{
  "version": 3,
  "sources": ["../../../node_modules/@rails/actioncable/src/adapters.js", "../../../node_modules/@rails/actioncable/src/logger.js", "../../../node_modules/@rails/actioncable/src/connection_monitor.js", "../../../node_modules/@rails/actioncable/src/internal.js", "../../../node_modules/@rails/actioncable/src/connection.js", "../../../node_modules/@rails/actioncable/src/subscription.js", "../../../node_modules/@rails/actioncable/src/subscription_guarantor.js", "../../../node_modules/@rails/actioncable/src/subscriptions.js", "../../../node_modules/@rails/actioncable/src/consumer.js", "../../../node_modules/@rails/actioncable/src/index.js", "../../../node_modules/@castleio/castle-js/dist/castle.js", "../../../node_modules/rrweb-snapshot/dist/rrweb-snapshot.js", "../../../node_modules/rrdom/dist/rrdom.js", "../../../node_modules/utils/dist/utils.js", "../../../node_modules/rrweb/src/utils.ts", "../../../node_modules/types/dist/types.js", "../../../node_modules/rrweb/src/record/mutation.ts", "../../../node_modules/rrweb/src/record/error-handler.ts", "../../../node_modules/rrweb/src/record/observer.ts", "../../../node_modules/rrweb/src/record/cross-origin-iframe-mirror.ts", "../../../node_modules/rrweb/src/record/iframe-manager.ts", "../../../node_modules/rrweb/src/record/shadow-dom-manager.ts", "../../../node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js", "../../../node_modules/rrweb/src/record/observers/canvas/serialize-args.ts", "../../../node_modules/rrweb/src/record/observers/canvas/2d.ts", "../../../node_modules/rrweb/src/record/observers/canvas/canvas.ts", "../../../node_modules/rrweb/src/record/observers/canvas/webgl.ts", "../../../node_modules/rrweb/src/record/observers/canvas/canvas-manager.ts", "../../../node_modules/rrweb/src/record/stylesheet-manager.ts", "../../../node_modules/rrweb/src/record/processed-node-manager.ts", "../../../node_modules/rrweb/src/record/index.ts", "../../../node_modules/mitt/dist/mitt.mjs", "../../../node_modules/rrweb/src/replay/smoothscroll.ts", "../../../node_modules/rrweb/src/replay/timer.ts", "../../../node_modules/@xstate/fsm/es/index.js", "../../../node_modules/rrweb/src/replay/machine.ts", "../../../node_modules/rrweb/src/replay/styles/inject-style.ts", "../../../node_modules/rrweb/src/replay/canvas/deserialize-args.ts", "../../../node_modules/rrweb/src/replay/canvas/webgl.ts", "../../../node_modules/rrweb/src/replay/canvas/2d.ts", "../../../node_modules/rrweb/src/replay/canvas/index.ts", "../../../node_modules/rrweb/src/replay/media/index.ts", "../../../node_modules/rrweb/src/replay/dialog/index.ts", "../../../node_modules/rrweb/src/replay/index.ts", "../../../node_modules/rrweb/src/index.ts", "../../../node_modules/@openpanel/web/dist/replay-V6FXES7X.js", "../../../node_modules/color-name/index.js", "../../../node_modules/color-convert/conversions.js", "../../../node_modules/color-convert/route.js", "../../../node_modules/color-convert/index.js", "../../../node_modules/bootstrap/js/src/dom/data.js", "../../../node_modules/bootstrap/js/src/util/index.js", "../../../node_modules/bootstrap/js/src/dom/event-handler.js", "../../../node_modules/bootstrap/js/src/dom/manipulator.js", "../../../node_modules/bootstrap/js/src/util/config.js", "../../../node_modules/bootstrap/js/src/base-component.js", "../../../node_modules/bootstrap/js/src/dom/selector-engine.js", "../../../node_modules/bootstrap/js/src/util/component-functions.js", "../../../node_modules/bootstrap/js/src/alert.js", "../../../node_modules/bootstrap/js/src/button.js", "../../../node_modules/bootstrap/js/src/util/swipe.js", "../../../node_modules/bootstrap/js/src/carousel.js", "../../../node_modules/bootstrap/js/src/collapse.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/enums.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getNodeName.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getWindow.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/instanceOf.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/applyStyles.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/getBasePlacement.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/math.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/userAgent.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/contains.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/isTableElement.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getParentNode.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/within.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/mergePaddingObject.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/getFreshSideObject.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/expandToHashMap.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/arrow.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/getVariation.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/computeStyles.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/eventListeners.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/getOppositePlacement.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/rectToClientRect.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/computeOffsets.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/detectOverflow.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/flip.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/hide.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/offset.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/popperOffsets.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/modifiers/preventOverflow.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/getAltAxis.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/orderModifiers.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/createPopper.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/debounce.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/utils/mergeByName.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/popper-lite.js", "../../../node_modules/bootstrap/node_modules/@popperjs/core/lib/popper.js", "../../../node_modules/bootstrap/js/src/dropdown.js", "../../../node_modules/bootstrap/js/src/util/backdrop.js", "../../../node_modules/bootstrap/js/src/util/focustrap.js", "../../../node_modules/bootstrap/js/src/util/scrollbar.js", "../../../node_modules/bootstrap/js/src/modal.js", "../../../node_modules/bootstrap/js/src/offcanvas.js", "../../../node_modules/bootstrap/js/src/util/sanitizer.js", "../../../node_modules/bootstrap/js/src/util/template-factory.js", "../../../node_modules/bootstrap/js/src/tooltip.js", "../../../node_modules/bootstrap/js/src/popover.js", "../../../node_modules/bootstrap/js/src/scrollspy.js", "../../../node_modules/bootstrap/js/src/tab.js", "../../../node_modules/bootstrap/js/src/toast.js", "../../../node_modules/bootstrap/js/index.umd.js", "../../../node_modules/@erwinstone/bs-select/dist/bs-select.js", "../../../node_modules/es-errors/type.js", "../../../node_modules/object-inspect/index.js", "../../../node_modules/side-channel-list/index.js", "../../../node_modules/es-object-atoms/index.js", "../../../node_modules/es-errors/index.js", "../../../node_modules/es-errors/eval.js", "../../../node_modules/es-errors/range.js", "../../../node_modules/es-errors/ref.js", "../../../node_modules/es-errors/syntax.js", "../../../node_modules/es-errors/uri.js", "../../../node_modules/math-intrinsics/abs.js", "../../../node_modules/math-intrinsics/floor.js", "../../../node_modules/math-intrinsics/max.js", "../../../node_modules/math-intrinsics/min.js", "../../../node_modules/math-intrinsics/pow.js", "../../../node_modules/math-intrinsics/round.js", "../../../node_modules/math-intrinsics/isNaN.js", "../../../node_modules/math-intrinsics/sign.js", "../../../node_modules/gopd/gOPD.js", "../../../node_modules/gopd/index.js", "../../../node_modules/es-define-property/index.js", "../../../node_modules/has-symbols/shams.js", "../../../node_modules/has-symbols/index.js", "../../../node_modules/get-proto/Reflect.getPrototypeOf.js", "../../../node_modules/get-proto/Object.getPrototypeOf.js", "../../../node_modules/function-bind/implementation.js", "../../../node_modules/function-bind/index.js", "../../../node_modules/call-bind-apply-helpers/functionCall.js", "../../../node_modules/call-bind-apply-helpers/functionApply.js", "../../../node_modules/call-bind-apply-helpers/reflectApply.js", "../../../node_modules/call-bind-apply-helpers/actualApply.js", "../../../node_modules/call-bind-apply-helpers/index.js", "../../../node_modules/dunder-proto/get.js", "../../../node_modules/get-proto/index.js", "../../../node_modules/hasown/index.js", "../../../node_modules/get-intrinsic/index.js", "../../../node_modules/call-bound/index.js", "../../../node_modules/side-channel-map/index.js", "../../../node_modules/side-channel-weakmap/index.js", "../../../node_modules/side-channel/index.js", "../../../node_modules/qs/lib/formats.js", "../../../node_modules/qs/lib/utils.js", "../../../node_modules/qs/lib/stringify.js", "../../../node_modules/qs/lib/parse.js", "../../../node_modules/qs/lib/index.js", "../../../node_modules/filepond/dist/filepond.js", "../../../node_modules/filepond-plugin-file-validate-size/dist/filepond-plugin-file-validate-size.js", "../../../node_modules/filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.js", "../../../node_modules/filepond-plugin-file-poster/dist/filepond-plugin-file-poster.js", "../../../node_modules/@sentry/browser/build/npm/esm/index.js", "../../../node_modules/@sentry/core/src/debug-build.ts", "../../../node_modules/@sentry/core/src/utils-hoist/version.ts", "../../../node_modules/@sentry/core/src/utils-hoist/worldwide.ts", "../../../node_modules/@sentry/core/src/utils-hoist/debug-build.ts", "../../../node_modules/@sentry/core/src/utils-hoist/logger.ts", "../../../node_modules/@sentry/core/src/utils-hoist/stacktrace.ts", "../../../node_modules/@sentry/core/src/utils-hoist/instrument/handlers.ts", "../../../node_modules/@sentry/core/src/utils-hoist/instrument/globalError.ts", "../../../node_modules/@sentry/core/src/utils-hoist/instrument/globalUnhandledRejection.ts", "../../../node_modules/@sentry/core/src/carrier.ts", "../../../node_modules/@sentry/core/src/utils-hoist/is.ts", "../../../node_modules/@sentry/core/src/utils-hoist/browser.ts", "../../../node_modules/@sentry/core/src/utils-hoist/string.ts", "../../../node_modules/@sentry/core/src/utils-hoist/object.ts", "../../../node_modules/@sentry/core/src/utils-hoist/time.ts", "../../../node_modules/@sentry/core/src/utils-hoist/misc.ts", "../../../node_modules/@sentry/core/src/utils-hoist/syncpromise.ts", "../../../node_modules/@sentry/core/src/session.ts", "../../../node_modules/@sentry/core/src/utils-hoist/propagationContext.ts", "../../../node_modules/@sentry/core/src/utils/merge.ts", "../../../node_modules/@sentry/core/src/utils/spanOnScope.ts", "../../../node_modules/@sentry/core/src/scope.ts", "../../../node_modules/@sentry/core/src/defaultScopes.ts", "../../../node_modules/@sentry/core/src/asyncContext/stackStrategy.ts", "../../../node_modules/@sentry/core/src/asyncContext/index.ts", "../../../node_modules/@sentry/core/src/currentScopes.ts", "../../../node_modules/@sentry/core/src/metrics/metric-summary.ts", "../../../node_modules/@sentry/core/src/semanticAttributes.ts", "../../../node_modules/@sentry/core/src/tracing/spanstatus.ts", "../../../node_modules/@sentry/core/src/utils-hoist/baggage.ts", "../../../node_modules/@sentry/core/src/utils-hoist/tracing.ts", "../../../node_modules/@sentry/core/src/utils/spanUtils.ts", "../../../node_modules/@sentry/core/src/tracing/errors.ts", "../../../node_modules/@sentry/core/src/tracing/utils.ts", "../../../node_modules/@sentry/core/src/tracing/hubextensions.ts", "../../../node_modules/@sentry/core/src/utils/hasTracingEnabled.ts", "../../../node_modules/@sentry/core/src/tracing/sentryNonRecordingSpan.ts", "../../../node_modules/@sentry/core/src/utils/handleCallbackErrors.ts", "../../../node_modules/@sentry/core/src/constants.ts", "../../../node_modules/@sentry/core/src/tracing/dynamicSamplingContext.ts", "../../../node_modules/@sentry/core/src/tracing/logSpans.ts", "../../../node_modules/@sentry/core/src/utils/parseSampleRate.ts", "../../../node_modules/@sentry/core/src/tracing/sampling.ts", "../../../node_modules/@sentry/core/src/utils-hoist/dsn.ts", "../../../node_modules/@sentry/core/src/utils-hoist/memo.ts", "../../../node_modules/@sentry/core/src/utils-hoist/normalize.ts", "../../../node_modules/@sentry/core/src/utils-hoist/envelope.ts", "../../../node_modules/@sentry/core/src/envelope.ts", "../../../node_modules/@sentry/core/src/tracing/measurement.ts", "../../../node_modules/@sentry/core/src/tracing/sentrySpan.ts", "../../../node_modules/@sentry/core/src/tracing/trace.ts", "../../../node_modules/@sentry/core/src/tracing/idleSpan.ts", "../../../node_modules/@sentry/core/src/eventProcessors.ts", "../../../node_modules/@sentry/core/src/utils-hoist/debug-ids.ts", "../../../node_modules/@sentry/core/src/utils/applyScopeDataToEvent.ts", "../../../node_modules/@sentry/core/src/utils/prepareEvent.ts", "../../../node_modules/@sentry/core/src/exports.ts", "../../../node_modules/@sentry/core/src/api.ts", "../../../node_modules/@sentry/core/src/integration.ts", "../../../node_modules/@sentry/core/src/utils-hoist/clientreport.ts", "../../../node_modules/@sentry/core/src/utils-hoist/error.ts", "../../../node_modules/@sentry/core/src/baseclient.ts", "../../../node_modules/@sentry/core/src/sdk.ts", "../../../node_modules/@sentry/core/src/utils-hoist/promisebuffer.ts", "../../../node_modules/@sentry/core/src/utils-hoist/ratelimit.ts", "../../../node_modules/@sentry/core/src/transports/base.ts", "../../../node_modules/@sentry/core/src/transports/offline.ts", "../../../node_modules/@sentry/core/src/transports/multiplexed.ts", "../../../node_modules/@sentry/core/src/utils/isSentryRequestUrl.ts", "../../../node_modules/@sentry/core/src/utils/parameterize.ts", "../../../node_modules/@sentry/core/src/utils/sdkMetadata.ts", "../../../node_modules/@sentry/core/src/utils/traceData.ts", "../../../node_modules/@sentry/core/src/breadcrumbs.ts", "../../../node_modules/@sentry/core/src/integrations/functiontostring.ts", "../../../node_modules/@sentry/core/src/integrations/inboundfilters.ts", "../../../node_modules/@sentry/core/src/utils-hoist/aggregate-errors.ts", "../../../node_modules/@sentry/core/src/metadata.ts", "../../../node_modules/@sentry/core/src/integrations/metadata.ts", "../../../node_modules/@sentry/core/src/utils-hoist/url.ts", "../../../node_modules/@sentry/core/src/utils-hoist/instrument/console.ts", "../../../node_modules/@sentry/core/src/utils-hoist/severity.ts", "../../../node_modules/@sentry/core/src/integrations/captureconsole.ts", "../../../node_modules/@sentry/core/src/integrations/debug.ts", "../../../node_modules/@sentry/core/src/integrations/dedupe.ts", "../../../node_modules/@sentry/core/src/integrations/extraerrordata.ts", "../../../node_modules/@sentry/core/src/utils-hoist/path.ts", "../../../node_modules/@sentry/core/src/integrations/rewriteframes.ts", "../../../node_modules/@sentry/core/src/integrations/sessiontiming.ts", "../../../node_modules/@sentry/core/src/integrations/zoderrors.ts", "../../../node_modules/@sentry/core/src/integrations/third-party-errors-filter.ts", "../../../node_modules/@sentry/core/src/metrics/constants.ts", "../../../node_modules/@sentry/core/src/metrics/exports.ts", "../../../node_modules/@sentry/core/src/metrics/utils.ts", "../../../node_modules/@sentry/core/src/metrics/envelope.ts", "../../../node_modules/@sentry/core/src/metrics/instance.ts", "../../../node_modules/@sentry/core/src/metrics/browser-aggregator.ts", "../../../node_modules/@sentry/core/src/fetch.ts", "../../../node_modules/@sentry/core/src/feedback.ts", "../../../node_modules/@sentry/core/src/getCurrentHubShim.ts", "../../../node_modules/@sentry/core/src/utils-hoist/breadcrumb-log-level.ts", "../../../node_modules/@sentry/core/src/utils-hoist/supports.ts", "../../../node_modules/@sentry/core/src/utils-hoist/instrument/fetch.ts", "../../../node_modules/@sentry/core/src/utils-hoist/env.ts", "../../../node_modules/@sentry/core/src/utils-hoist/node.ts", "../../../node_modules/@sentry/core/src/utils-hoist/isBrowser.ts", "../../../node_modules/@sentry/core/src/utils-hoist/vendor/supportsHistory.ts", "../../../node_modules/@sentry/core/src/utils-hoist/buildPolyfills/_nullishCoalesce.ts", "../../../node_modules/@sentry/core/src/utils-hoist/buildPolyfills/_optionalChain.ts", "../../../node_modules/@sentry/browser/src/helpers.ts", "../../../node_modules/@sentry/browser/src/debug-build.ts", "../../../node_modules/@sentry/browser/src/eventbuilder.ts", "../../../node_modules/@sentry/browser/src/userfeedback.ts", "../../../node_modules/@sentry/browser/src/client.ts", "../../../node_modules/@sentry-internal/browser-utils/src/debug-build.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/bindReporter.ts", "../../../node_modules/@sentry-internal/browser-utils/src/types.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/generateUniqueID.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/getActivationStart.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/initMetric.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/observe.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/onHidden.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/runOnce.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/whenActivated.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/onFCP.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getCLS.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getFID.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/interactions.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/lib/whenIdle.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getINP.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/getLCP.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/web-vitals/onTTFB.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/instrument.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/utils.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/cls.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/browserMetrics.ts", "../../../node_modules/@sentry-internal/browser-utils/src/instrument/dom.ts", "../../../node_modules/@sentry-internal/browser-utils/src/instrument/history.ts", "../../../node_modules/@sentry-internal/browser-utils/src/getNativeImplementation.ts", "../../../node_modules/@sentry-internal/browser-utils/src/instrument/xhr.ts", "../../../node_modules/@sentry-internal/browser-utils/src/metrics/inp.ts", "../../../node_modules/@sentry/browser/src/transports/fetch.ts", "../../../node_modules/@sentry/browser/src/stack-parsers.ts", "../../../node_modules/@sentry/browser/src/integrations/breadcrumbs.ts", "../../../node_modules/@sentry/browser/src/integrations/browserapierrors.ts", "../../../node_modules/@sentry/browser/src/integrations/browsersession.ts", "../../../node_modules/@sentry/browser/src/integrations/globalhandlers.ts", "../../../node_modules/@sentry/browser/src/integrations/httpcontext.ts", "../../../node_modules/@sentry/browser/src/integrations/linkederrors.ts", "../../../node_modules/@sentry/browser/src/sdk.ts", "../../../node_modules/@sentry/browser/src/utils/lazyLoadIntegration.ts", "../../../node_modules/@sentry/browser/src/integrations/reportingobserver.ts", "../../../node_modules/@sentry/browser/src/integrations/httpclient.ts", "../../../node_modules/@sentry/browser/src/integrations/contextlines.ts", "../../../node_modules/@sentry-internal/replay/src/constants.ts", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb-snapshot/es/rrweb-snapshot.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/utils.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/types/dist/rrweb-types.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrdom/es/rrdom.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/mutation.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/error-handler.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/observer.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/cross-origin-iframe-mirror.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/iframe-manager.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/shadow-dom-manager.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/observers/canvas/canvas-manager.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/stylesheet-manager.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/processed-node-manager.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/index.js", "../../../node_modules/@sentry-internal/replay/src/types/rrweb.ts", "../../../node_modules/@sentry-internal/replay/src/util/timestamp.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/addBreadcrumbEvent.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/domUtils.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/onWindowOpen.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleClick.ts", "../../../node_modules/@sentry-internal/replay/src/util/createBreadcrumb.ts", "../../../node_modules/node_modules/@sentry-internal/rrweb-snapshot/es/rrweb-snapshot.js", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/getAttributesToRecord.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleDom.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleKeyboardEvent.ts", "../../../node_modules/@sentry-internal/replay/src/util/createPerformanceEntries.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/performanceObserver.ts", "../../../node_modules/@sentry-internal/replay/src/debug-build.ts", "../../../node_modules/@sentry-internal/replay-worker/build/esm/worker.ts", "../../../node_modules/@sentry-internal/replay-worker/build/esm/index.js", "../../../node_modules/@sentry-internal/replay/src/util/logger.ts", "../../../node_modules/@sentry-internal/replay/src/eventBuffer/error.ts", "../../../node_modules/@sentry-internal/replay/src/eventBuffer/EventBufferArray.ts", "../../../node_modules/@sentry-internal/replay/src/eventBuffer/WorkerHandler.ts", "../../../node_modules/@sentry-internal/replay/src/eventBuffer/EventBufferCompressionWorker.ts", "../../../node_modules/@sentry-internal/replay/src/eventBuffer/EventBufferProxy.ts", "../../../node_modules/@sentry-internal/replay/src/eventBuffer/index.ts", "../../../node_modules/@sentry-internal/replay/src/util/hasSessionStorage.ts", "../../../node_modules/@sentry-internal/replay/src/session/clearSession.ts", "../../../node_modules/@sentry-internal/replay/src/util/isSampled.ts", "../../../node_modules/@sentry-internal/replay/src/session/Session.ts", "../../../node_modules/@sentry-internal/replay/src/session/saveSession.ts", "../../../node_modules/@sentry-internal/replay/src/session/createSession.ts", "../../../node_modules/@sentry-internal/replay/src/session/fetchSession.ts", "../../../node_modules/@sentry-internal/replay/src/util/isExpired.ts", "../../../node_modules/@sentry-internal/replay/src/util/isSessionExpired.ts", "../../../node_modules/@sentry-internal/replay/src/session/shouldRefreshSession.ts", "../../../node_modules/@sentry-internal/replay/src/session/loadOrCreateSession.ts", "../../../node_modules/@sentry-internal/replay/src/util/addEvent.ts", "../../../node_modules/@sentry-internal/replay/src/util/eventUtils.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleAfterSendEvent.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleBeforeSendEvent.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleBreadcrumbs.ts", "../../../node_modules/@sentry-internal/replay/src/util/isRrwebError.ts", "../../../node_modules/@sentry-internal/replay/src/util/resetReplayIdOnDynamicSamplingContext.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/addFeedbackBreadcrumb.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/shouldSampleForBufferEvent.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleGlobalEvent.ts", "../../../node_modules/@sentry-internal/replay/src/util/createPerformanceSpans.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleHistory.ts", "../../../node_modules/@sentry-internal/replay/src/util/shouldFilterRequest.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/addNetworkBreadcrumb.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/networkUtils.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/fetchUtils.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/util/xhrUtils.ts", "../../../node_modules/@sentry-internal/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts", "../../../node_modules/@sentry-internal/replay/src/util/addGlobalListeners.ts", "../../../node_modules/@sentry-internal/replay/src/util/addMemoryEntry.ts", "../../../node_modules/@sentry-internal/replay/src/util/debounce.ts", "../../../node_modules/@sentry-internal/replay/src/util/getRecordingSamplingOptions.ts", "../../../node_modules/@sentry-internal/replay/src/util/handleRecordingEmit.ts", "../../../node_modules/@sentry-internal/replay/src/util/createReplayEnvelope.ts", "../../../node_modules/@sentry-internal/replay/src/util/prepareRecordingData.ts", "../../../node_modules/@sentry-internal/replay/src/util/prepareReplayEvent.ts", "../../../node_modules/@sentry-internal/replay/src/util/sendReplayRequest.ts", "../../../node_modules/@sentry-internal/replay/src/util/sendReplay.ts", "../../../node_modules/@sentry-internal/replay/src/util/throttle.ts", "../../../node_modules/@sentry-internal/replay/src/replay.ts", "../../../node_modules/@sentry-internal/replay/src/util/getPrivacyOptions.ts", "../../../node_modules/@sentry-internal/replay/src/util/maskAttribute.ts", "../../../node_modules/@sentry-internal/replay/src/integration.ts", "../../../node_modules/@sentry-internal/replay/src/util/getReplay.ts", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb-snapshot/es/rrweb-snapshot.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/utils.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/types/dist/rrweb-types.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/error-handler.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/ext/base64-arraybuffer/dist/base64-arraybuffer.es5.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/observers/canvas/serialize-args.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/observers/canvas/2d.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/observers/canvas/canvas.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/observers/canvas/webgl.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb-worker/es/rrweb-worker/image-bitmap-data-url-worker.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb-worker/es/rrweb-worker/index.js", "../../../node_modules/node_modules/@sentry-internal/rrweb/es/rrweb/packages/rrweb/src/record/observers/canvas/canvas-manager.js", "../../../node_modules/@sentry-internal/replay-canvas/src/canvas.ts", "../../../node_modules/@sentry-internal/feedback/src/constants/index.ts", "../../../node_modules/@sentry-internal/feedback/src/core/sendFeedback.ts", "../../../node_modules/@sentry-internal/feedback/src/util/debug-build.ts", "../../../node_modules/@sentry-internal/feedback/src/util/isScreenshotSupported.ts", "../../../node_modules/@sentry-internal/feedback/src/util/mergeOptions.ts", "../../../node_modules/@sentry-internal/feedback/src/core/components/Actor.css.ts", "../../../node_modules/@sentry-internal/feedback/src/util/setAttributesNS.ts", "../../../node_modules/@sentry-internal/feedback/src/core/components/FeedbackIcon.ts", "../../../node_modules/@sentry-internal/feedback/src/core/components/Actor.ts", "../../../node_modules/@sentry-internal/feedback/src/core/createMainStyles.ts", "../../../node_modules/@sentry-internal/feedback/src/core/integration.ts", "../../../node_modules/@sentry-internal/feedback/src/core/getFeedback.ts", "../../../node_modules/node_modules/preact/dist/preact.mjs", "../../../node_modules/node_modules/preact/hooks/dist/hooks.mjs", "../../../node_modules/@sentry-internal/feedback/src/modal/components/SentryLogo.ts", "../../../node_modules/@sentry-internal/feedback/src/modal/components/DialogHeader.tsx", "../../../node_modules/@sentry-internal/feedback/src/util/validate.ts", "../../../node_modules/@sentry-internal/feedback/src/modal/components/Form.tsx", "../../../node_modules/@sentry-internal/feedback/src/modal/components/SuccessIcon.ts", "../../../node_modules/@sentry-internal/feedback/src/modal/components/Dialog.tsx", "../../../node_modules/@sentry-internal/feedback/src/modal/components/Dialog.css.ts", "../../../node_modules/@sentry-internal/feedback/src/modal/integration.tsx", "../../../node_modules/@sentry-internal/feedback/src/screenshot/components/CropCorner.tsx", "../../../node_modules/@sentry-internal/feedback/src/screenshot/components/ScreenshotInput.css.ts", "../../../node_modules/@sentry-internal/feedback/src/screenshot/components/useTakeScreenshot.tsx", "../../../node_modules/@sentry-internal/feedback/src/screenshot/components/ScreenshotEditor.tsx", "../../../node_modules/@sentry-internal/feedback/src/screenshot/integration.ts", "../../../node_modules/@sentry/browser/src/feedbackAsync.ts", "../../../node_modules/@sentry/browser/src/feedbackSync.ts", "../../../node_modules/@sentry/browser/src/metrics.ts", "../../../node_modules/@sentry/browser/src/tracing/request.ts", "../../../node_modules/@sentry/browser/src/tracing/backgroundtab.ts", "../../../node_modules/@sentry/browser/src/tracing/browserTracingIntegration.ts", "../../../node_modules/@sentry/browser/src/transports/offline.ts", "../../../node_modules/@sentry/browser/src/profiling/utils.ts", "../../../node_modules/@sentry/browser/src/profiling/startProfileForSpan.ts", "../../../node_modules/@sentry/browser/src/profiling/integration.ts", "../../../node_modules/@sentry/browser/src/integrations/spotlight.ts", "../../../node_modules/@sentry/browser/src/utils/featureFlags.ts", "../../../node_modules/@sentry/browser/src/integrations/featureFlags/featureFlagsIntegration.ts", "../../../node_modules/@sentry/browser/src/integrations/featureFlags/launchdarkly/integration.ts", "../../../node_modules/@sentry/browser/src/integrations/featureFlags/openfeature/integration.ts", "../../../node_modules/@sentry/browser/src/integrations/featureFlags/unleash/integration.ts", "../../../node_modules/@sentry/browser/src/integrations/featureFlags/statsig/integration.ts", "../../javascript/utils/sentry.js", "../../../node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/snakeize.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable_stream_source_element.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/fetch_requests.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/index.js", "../../javascript/utils/fetch.js", "../../javascript/utils/castle.js", "../../../node_modules/@openpanel/sdk/dist/index.js", "../../../node_modules/@openpanel/web/dist/index.js", "../../javascript/utils/openpanel.js", "../../javascript/utils/tracker.js", "../../javascript/utils/adhunter.js", "../../../node_modules/lodash-es/_freeGlobal.js", "../../../node_modules/lodash-es/_root.js", "../../../node_modules/lodash-es/_Symbol.js", "../../../node_modules/lodash-es/_getRawTag.js", "../../../node_modules/lodash-es/_objectToString.js", "../../../node_modules/lodash-es/_baseGetTag.js", "../../../node_modules/lodash-es/isObjectLike.js", "../../../node_modules/lodash-es/isSymbol.js", "../../../node_modules/lodash-es/_arrayMap.js", "../../../node_modules/lodash-es/isArray.js", "../../../node_modules/lodash-es/_baseToString.js", "../../../node_modules/lodash-es/_trimmedEndIndex.js", "../../../node_modules/lodash-es/_baseTrim.js", "../../../node_modules/lodash-es/isObject.js", "../../../node_modules/lodash-es/toNumber.js", "../../../node_modules/lodash-es/identity.js", "../../../node_modules/lodash-es/isFunction.js", "../../../node_modules/lodash-es/_coreJsData.js", "../../../node_modules/lodash-es/_isMasked.js", "../../../node_modules/lodash-es/_toSource.js", "../../../node_modules/lodash-es/_baseIsNative.js", "../../../node_modules/lodash-es/_getValue.js", "../../../node_modules/lodash-es/_getNative.js", "../../../node_modules/lodash-es/_WeakMap.js", "../../../node_modules/lodash-es/_baseCreate.js", "../../../node_modules/lodash-es/_apply.js", "../../../node_modules/lodash-es/_copyArray.js", "../../../node_modules/lodash-es/_shortOut.js", "../../../node_modules/lodash-es/constant.js", "../../../node_modules/lodash-es/_defineProperty.js", "../../../node_modules/lodash-es/_baseSetToString.js", "../../../node_modules/lodash-es/_setToString.js", "../../../node_modules/lodash-es/_arrayEach.js", "../../../node_modules/lodash-es/_isIndex.js", "../../../node_modules/lodash-es/_baseAssignValue.js", "../../../node_modules/lodash-es/eq.js", "../../../node_modules/lodash-es/_assignValue.js", "../../../node_modules/lodash-es/_copyObject.js", "../../../node_modules/lodash-es/_overRest.js", "../../../node_modules/lodash-es/_baseRest.js", "../../../node_modules/lodash-es/isLength.js", "../../../node_modules/lodash-es/isArrayLike.js", "../../../node_modules/lodash-es/_isIterateeCall.js", "../../../node_modules/lodash-es/_createAssigner.js", "../../../node_modules/lodash-es/_isPrototype.js", "../../../node_modules/lodash-es/_baseTimes.js", "../../../node_modules/lodash-es/_baseIsArguments.js", "../../../node_modules/lodash-es/isArguments.js", "../../../node_modules/lodash-es/stubFalse.js", "../../../node_modules/lodash-es/isBuffer.js", "../../../node_modules/lodash-es/_baseIsTypedArray.js", "../../../node_modules/lodash-es/_baseUnary.js", "../../../node_modules/lodash-es/_nodeUtil.js", "../../../node_modules/lodash-es/isTypedArray.js", "../../../node_modules/lodash-es/_arrayLikeKeys.js", "../../../node_modules/lodash-es/_overArg.js", "../../../node_modules/lodash-es/_nativeKeys.js", "../../../node_modules/lodash-es/_baseKeys.js", "../../../node_modules/lodash-es/keys.js", "../../../node_modules/lodash-es/_nativeKeysIn.js", "../../../node_modules/lodash-es/_baseKeysIn.js", "../../../node_modules/lodash-es/keysIn.js", "../../../node_modules/lodash-es/assignIn.js", "../../../node_modules/lodash-es/_isKey.js", "../../../node_modules/lodash-es/_nativeCreate.js", "../../../node_modules/lodash-es/_hashClear.js", "../../../node_modules/lodash-es/_hashDelete.js", "../../../node_modules/lodash-es/_hashGet.js", "../../../node_modules/lodash-es/_hashHas.js", "../../../node_modules/lodash-es/_hashSet.js", "../../../node_modules/lodash-es/_Hash.js", "../../../node_modules/lodash-es/_listCacheClear.js", "../../../node_modules/lodash-es/_assocIndexOf.js", "../../../node_modules/lodash-es/_listCacheDelete.js", "../../../node_modules/lodash-es/_listCacheGet.js", "../../../node_modules/lodash-es/_listCacheHas.js", "../../../node_modules/lodash-es/_listCacheSet.js", "../../../node_modules/lodash-es/_ListCache.js", "../../../node_modules/lodash-es/_Map.js", "../../../node_modules/lodash-es/_mapCacheClear.js", "../../../node_modules/lodash-es/_isKeyable.js", "../../../node_modules/lodash-es/_getMapData.js", "../../../node_modules/lodash-es/_mapCacheDelete.js", "../../../node_modules/lodash-es/_mapCacheGet.js", "../../../node_modules/lodash-es/_mapCacheHas.js", "../../../node_modules/lodash-es/_mapCacheSet.js", "../../../node_modules/lodash-es/_MapCache.js", "../../../node_modules/lodash-es/memoize.js", "../../../node_modules/lodash-es/_memoizeCapped.js", "../../../node_modules/lodash-es/_stringToPath.js", "../../../node_modules/lodash-es/toString.js", "../../../node_modules/lodash-es/_castPath.js", "../../../node_modules/lodash-es/_toKey.js", "../../../node_modules/lodash-es/_baseGet.js", "../../../node_modules/lodash-es/get.js", "../../../node_modules/lodash-es/_arrayPush.js", "../../../node_modules/lodash-es/_getPrototype.js", "../../../node_modules/lodash-es/isPlainObject.js", "../../../node_modules/lodash-es/_baseSlice.js", "../../../node_modules/lodash-es/_castSlice.js", "../../../node_modules/lodash-es/_hasUnicode.js", "../../../node_modules/lodash-es/_asciiToArray.js", "../../../node_modules/lodash-es/_unicodeToArray.js", "../../../node_modules/lodash-es/_stringToArray.js", "../../../node_modules/lodash-es/_createCaseFirst.js", "../../../node_modules/lodash-es/upperFirst.js", "../../../node_modules/lodash-es/_stackClear.js", "../../../node_modules/lodash-es/_stackDelete.js", "../../../node_modules/lodash-es/_stackGet.js", "../../../node_modules/lodash-es/_stackHas.js", "../../../node_modules/lodash-es/_stackSet.js", "../../../node_modules/lodash-es/_Stack.js", "../../../node_modules/lodash-es/_baseAssign.js", "../../../node_modules/lodash-es/_baseAssignIn.js", "../../../node_modules/lodash-es/_cloneBuffer.js", "../../../node_modules/lodash-es/_arrayFilter.js", "../../../node_modules/lodash-es/stubArray.js", "../../../node_modules/lodash-es/_getSymbols.js", "../../../node_modules/lodash-es/_copySymbols.js", "../../../node_modules/lodash-es/_getSymbolsIn.js", "../../../node_modules/lodash-es/_copySymbolsIn.js", "../../../node_modules/lodash-es/_baseGetAllKeys.js", "../../../node_modules/lodash-es/_getAllKeys.js", "../../../node_modules/lodash-es/_getAllKeysIn.js", "../../../node_modules/lodash-es/_DataView.js", "../../../node_modules/lodash-es/_Promise.js", "../../../node_modules/lodash-es/_Set.js", "../../../node_modules/lodash-es/_getTag.js", "../../../node_modules/lodash-es/_initCloneArray.js", "../../../node_modules/lodash-es/_Uint8Array.js", "../../../node_modules/lodash-es/_cloneArrayBuffer.js", "../../../node_modules/lodash-es/_cloneDataView.js", "../../../node_modules/lodash-es/_cloneRegExp.js", "../../../node_modules/lodash-es/_cloneSymbol.js", "../../../node_modules/lodash-es/_cloneTypedArray.js", "../../../node_modules/lodash-es/_initCloneByTag.js", "../../../node_modules/lodash-es/_initCloneObject.js", "../../../node_modules/lodash-es/_baseIsMap.js", "../../../node_modules/lodash-es/isMap.js", "../../../node_modules/lodash-es/_baseIsSet.js", "../../../node_modules/lodash-es/isSet.js", "../../../node_modules/lodash-es/_baseClone.js", "../../../node_modules/lodash-es/clone.js", "../../../node_modules/lodash-es/cloneDeep.js", "../../../node_modules/lodash-es/cloneDeepWith.js", "../../../node_modules/lodash-es/_setCacheAdd.js", "../../../node_modules/lodash-es/_setCacheHas.js", "../../../node_modules/lodash-es/_SetCache.js", "../../../node_modules/lodash-es/_arraySome.js", "../../../node_modules/lodash-es/_cacheHas.js", "../../../node_modules/lodash-es/_equalArrays.js", "../../../node_modules/lodash-es/_mapToArray.js", "../../../node_modules/lodash-es/_setToArray.js", "../../../node_modules/lodash-es/_equalByTag.js", "../../../node_modules/lodash-es/_equalObjects.js", "../../../node_modules/lodash-es/_baseIsEqualDeep.js", "../../../node_modules/lodash-es/_baseIsEqual.js", "../../../node_modules/lodash-es/_baseIsMatch.js", "../../../node_modules/lodash-es/_isStrictComparable.js", "../../../node_modules/lodash-es/_getMatchData.js", "../../../node_modules/lodash-es/_matchesStrictComparable.js", "../../../node_modules/lodash-es/_baseMatches.js", "../../../node_modules/lodash-es/_baseHasIn.js", "../../../node_modules/lodash-es/_hasPath.js", "../../../node_modules/lodash-es/hasIn.js", "../../../node_modules/lodash-es/_baseMatchesProperty.js", "../../../node_modules/lodash-es/_baseProperty.js", "../../../node_modules/lodash-es/_basePropertyDeep.js", "../../../node_modules/lodash-es/property.js", "../../../node_modules/lodash-es/_baseIteratee.js", "../../../node_modules/lodash-es/_createBaseFor.js", "../../../node_modules/lodash-es/_baseFor.js", "../../../node_modules/lodash-es/_baseForOwn.js", "../../../node_modules/lodash-es/_createBaseEach.js", "../../../node_modules/lodash-es/_baseEach.js", "../../../node_modules/lodash-es/now.js", "../../../node_modules/lodash-es/debounce.js", "../../../node_modules/lodash-es/_assignMergeValue.js", "../../../node_modules/lodash-es/isArrayLikeObject.js", "../../../node_modules/lodash-es/_safeGet.js", "../../../node_modules/lodash-es/toPlainObject.js", "../../../node_modules/lodash-es/_baseMergeDeep.js", "../../../node_modules/lodash-es/_baseMerge.js", "../../../node_modules/lodash-es/last.js", "../../../node_modules/lodash-es/_baseMap.js", "../../../node_modules/lodash-es/map.js", "../../../node_modules/lodash-es/isString.js", "../../../node_modules/lodash-es/_parent.js", "../../../node_modules/lodash-es/isElement.js", "../../../node_modules/lodash-es/isEqual.js", "../../../node_modules/lodash-es/isEqualWith.js", "../../../node_modules/lodash-es/mapValues.js", "../../../node_modules/lodash-es/merge.js", "../../../node_modules/lodash-es/_baseUnset.js", "../../../node_modules/lodash-es/_baseSet.js", "../../../node_modules/lodash-es/set.js", "../../../node_modules/lodash-es/throttle.js", "../../../node_modules/lodash-es/unset.js", "../../../node_modules/@ckeditor/ckeditor5-utils/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/global.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/env.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/fastdiff.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/diff.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/difftochanges.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/mix.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/spy.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/eventinfo.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/uid.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/priorities.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/inserttopriorityarray.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/ckeditorerror.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/version.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/emittermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/observablemixin.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/elementreplacer.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/abortabledebounce.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/count.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/comparearrays.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/isiterable.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/createelement.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/config.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isnode.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/iswindow.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/emittermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/findclosestscrollableancestor.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getancestors.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getdatafromelement.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getborderwidths.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getrangefrommouseevent.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/istext.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isrange.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/getpositionedancestor.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/rect.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/resizeobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/setdatainelement.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/tounit.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/indexof.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/insertat.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/iscomment.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isvalidattributename.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/isvisible.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/position.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/remove.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/dom/scroll.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/keyboard.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/language.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/toarray.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/translation-service.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/locale.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/collection.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/first.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/focustracker.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/keystrokehandler.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/objecttomap.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/tomap.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/wait.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/retry.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/splicearray.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/delay.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/verifylicense.ts", "../../../node_modules/@ckeditor/ckeditor5-utils/src/unicode.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/placeholder.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/typecheckable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/node.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/text.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/textproxy.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/matcher.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/stylesmap.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/element.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/containerelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/editableelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/rooteditableelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/treewalker.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/position.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/range.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/selection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/documentselection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/bubblingeventinfo.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/bubblingemittermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/document.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/attributeelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/emptyelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/uielement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/rawelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/documentfragment.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/downcastwriter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/filler.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/renderer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/domconverter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/observer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventdata.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/keyobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/fakeselectionobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mutationobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/focusobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/selectionobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/compositionobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/datatransfer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/inputobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/arrowkeysobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/tabobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/view.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/typecheckable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/node.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/nodelist.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/text.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/textproxy.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/element.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/treewalker.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/position.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/range.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/mapper.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/modelconsumable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/downcastdispatcher.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/selection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/liverange.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/documentselection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/conversionhelpers.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/downcasthelpers.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/autoparagraphing.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/upcasthelpers.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/selection-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/controller/editingcontroller.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/viewconsumable.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/schema.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/upcastdispatcher.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/basichtmlwriter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/controller/datacontroller.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/conversion/conversion.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dataprocessor/xmldataprocessor.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/operation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/moveoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/insertoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/splitoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/mergeoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/markeroperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/attributeoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/nooperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/renameoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/rootattributeoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/rootoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/operationfactory.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/transform.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/liveposition.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/batch.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/differ.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/history.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/rootelement.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/document.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/markercollection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/operation/detachoperation.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/documentfragment.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/writer.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/deletecontent.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/getselectedcontent.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/insertcontent.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/insertobject.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/utils/modifyselection.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/model/model.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/clickobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/upcastwriter.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/background.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/border.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/margin.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/view/styles/padding.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dev-utils/view.ts", "../../../node_modules/@ckeditor/ckeditor5-engine/src/dev-utils/model.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/watchdog.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/utils/getsubnodes.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/utils/areconnectedthroughproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/editorwatchdog.ts", "../../../node_modules/@ckeditor/ckeditor5-watchdog/src/contextwatchdog.ts", "../../../node_modules/@ckeditor/ckeditor5-core/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-core/src/plugin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/command.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/multicommand.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/plugincollection.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/context.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/contextplugin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/commandcollection.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/accessibility.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/editor.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/attachtoform.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/dataapimixin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/editor/utils/securesourceelement.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/pendingactions.ts", "../../../node_modules/@ckeditor/ckeditor5-core/src/index.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-upload/src/filereader.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/src/filerepository.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/src/adapters/base64uploadadapter.ts", "../../../node_modules/@ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter.ts", "../../../node_modules/color-parse/index.mjs", "../../../node_modules/@ckeditor/ckeditor5-ui/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-ui/src/viewcollection.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/template.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/view.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/clickoutsidehandler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/injectcsstransitiondisabler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/csstransitiondisablermixin.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/submithandler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/addkeyboardhandlingforgrid.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/icon/iconview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/buttonlabelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/buttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/formheader/formheaderview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/focuscycler.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/draggableviewmixin.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialogactionsview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialogcontentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialogview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dialog/dialog.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/listitembuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistitembuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/label/labelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/accessibilityhelp/accessibilityhelpcontentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/accessibilityhelp/accessibilityhelp.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/bodycollection.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/switchbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/button/filedialogbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/collapsible/collapsibleview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorgrid/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorgrid/colortileview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorgrid/colorgridview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorpicker/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/labeledfield/labeledfieldview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/input/inputbase.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/input/inputview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/inputtext/inputtextview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/inputnumber/inputnumberview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/textarea/textareaview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownpanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/dropdownview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/button/dropdownbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenulistitembuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenubuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listitemview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listseparatorview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listitemgroupview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/list/listview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenulistview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenulistitemview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenubehaviors.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/balloonpanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenunestedmenupanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenunestedmenuview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/menu/dropdownmenurootlistview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarseparatorview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarlinebreakview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/bindings/preventdefault.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/normalizetoolbarconfig.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/toolbarview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/dropdown/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/labeledfield/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorpicker/colorpickerview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/documentcolorcollection.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/colorgridsfragmentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/colorpickerfragmentview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/colorselector/colorselectorview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/componentfactory.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/tooltipmanager.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/poweredby.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/arialiveannouncer.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistitemview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/editorui.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/editoruiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editorui/boxed/boxededitoruiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editableui/editableuiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/editableui/inline/inlineeditableuiview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/iframe/iframeview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/filtergroupanditemnames.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/notification/notification.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/model.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/panel/sticky/stickypanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/text/searchtextqueryview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/searchinfoview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/searchresultsview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/search/text/searchtextview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/autocomplete/autocompleteview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/highlightedtext/highlightedtextview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/highlightedtext/buttonlabelwithhighlightview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/highlightedtext/labelwithhighlightview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/spinner/spinnerview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/balloon/balloontoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/block/blockbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/toolbar/block/blocktoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenubuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenupanelview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenuview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarmenulistitemfiledialogbuttonview.ts", "../../../node_modules/@ckeditor/ckeditor5-ui/src/menubar/menubarview.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/math.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/convert.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/compare.ts", "../../../node_modules/vanilla-colorful/src/lib/utils/dom.ts", "../../../node_modules/vanilla-colorful/src/lib/components/slider.ts", "../../../node_modules/vanilla-colorful/src/lib/components/hue.ts", "../../../node_modules/vanilla-colorful/src/lib/components/saturation.ts", "../../../node_modules/vanilla-colorful/src/lib/styles/color-picker.ts", "../../../node_modules/vanilla-colorful/src/lib/styles/hue.ts", "../../../node_modules/vanilla-colorful/src/lib/styles/saturation.ts", "../../../node_modules/vanilla-colorful/src/lib/components/color-picker.ts", "../../../node_modules/vanilla-colorful/src/lib/entrypoints/hex.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/changebuffer.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/inserttextcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/inserttextobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/input.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/deletecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/deleteobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/delete.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/typing.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/getlasttextline.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/textwatcher.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/twostepcaretmovement.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/texttransformation.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/findattributerange.ts", "../../../node_modules/@ckeditor/ckeditor5-typing/src/utils/inlinehighlight.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/code.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.ts", "../../../node_modules/@ckeditor/ckeditor5-basic-styles/src/underline.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-enter/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/entercommand.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/enterobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/enter.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/shiftentercommand.ts", "../../../node_modules/@ckeditor/ckeditor5-enter/src/shiftenter.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.ts", "../../../node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-widget/src/highlightstack.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgettypearound/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgettypearound/widgettypearound.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/verticalnavigation.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widget.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgettoolbarrepository.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize/resizerstate.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize/sizeview.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize/resizer.ts", "../../../node_modules/@ckeditor/ckeditor5-widget/src/widgetresize.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardmarkersutils.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/lineview.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/dragdroptarget.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropblocktoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.ts", "../../../node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.ts", "../../../node_modules/@ckeditor/ckeditor5-editor-classic/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-editor-classic/src/classiceditorui.ts", "../../../node_modules/@ckeditor/ckeditor5-editor-classic/src/classiceditoruiview.ts", "../../../node_modules/@ckeditor/ckeditor5-editor-classic/src/classiceditor.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectallcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectallediting.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectallui.ts", "../../../node_modules/@ckeditor/ckeditor5-select-all/src/selectall.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-undo/src/basecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undocommand.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/redocommand.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undoediting.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undoui.ts", "../../../node_modules/@ckeditor/ckeditor5-undo/src/undo.ts", "../../../node_modules/@ckeditor/ckeditor5-essentials/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-essentials/src/essentials.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/paragraphcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/insertparagraphcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/paragraph.ts", "../../../node_modules/@ckeditor/ckeditor5-paragraph/src/paragraphbuttonui.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingediting.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingui.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/heading.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/headingbuttonsui.ts", "../../../node_modules/@ckeditor/ckeditor5-heading/src/title.ts", "../../../node_modules/@ckeditor/ckeditor5-image/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageutils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/autoimage.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/ui/textalternativeformview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/ui/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative/imagetextalternativeui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetextalternative.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageloadobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/insertimagecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/replaceimagesourcecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagesizeattributes.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imagetypecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageplaceholder.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageblockediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/ui/imageinsertformview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/imageinsertui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageblock.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image/imageinlineediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinline.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/image.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionutils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/toggleimagecaptioncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption/imagecaptionui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagecaption.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadprogress.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/uploadimagecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload/imageuploadediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageupload.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/ui/imageinserturlview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert/imageinsertviaurlui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsertviaurl.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageinsert.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/resizeimagecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imageresizeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imageresizebuttons.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imageresizehandles.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/tryparsedimensionwithunit.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/getselectedimageeditornodes.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/getselectedimagewidthinunits.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/ui/imagecustomresizeformview.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/utils/getselectedimagepossibleresizerange.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize/imagecustomresizeui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imageresize.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestyleediting.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle/imagestyleui.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagestyle.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/imagetoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-image/src/pictureediting.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentediting.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentui.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indent.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentblockcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentcommandbehavior/indentusingoffset.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentcommandbehavior/indentusingclasses.ts", "../../../node_modules/@ckeditor/ckeditor5-indent/src/indentblock.ts", "../../../node_modules/@ckeditor/ckeditor5-link/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-link/src/utils/automaticdecorators.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/unlinkcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/utils/manualdecorator.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkediting.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/ui/linkformview.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/ui/linkactionsview.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkui.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/autolink.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/link.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkimageediting.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkimageui.ts", "../../../node_modules/@ckeditor/ckeditor5-link/src/linkimage.ts", "../../../node_modules/@ckeditor/ckeditor5-list/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/listwalker.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/model.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listindentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listmergecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listsplitcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/view.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils/postfixers.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/listui.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/liststartcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/utils/style.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/liststylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listreversedcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listpropertiesutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/utils/config.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listpropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/ui/listpropertiesview.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties/listpropertiesui.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/listproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/checktodolistcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/todocheckboxchangeobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/todolistediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist/todolistui.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/todolist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacylistcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacyindentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacyutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacylistutils.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacyconverters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist/legacylistediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacyliststylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacylistreversedcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacyliststartcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties/legacylistpropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacylistproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist/legacychecktodolistcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist/legacytodolistconverters.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist/legacytodolistediting.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/legacytodolist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/list/adjacentlistssupport.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/documentlist.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/documentlistproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-list/src/tododocumentlist.ts", "../../../node_modules/marked/lib/marked.esm.js", "../../../node_modules/turndown/lib/turndown.browser.es.js", "../../../node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.js", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/markdown2html/markdown2html.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/html2markdown/html2markdown.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/gfmdataprocessor.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/markdown.ts", "../../../node_modules/@ckeditor/ckeditor5-markdown-gfm/src/pastefrommarkdownexperimental.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaregistry.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedediting.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/automediaembed.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/ui/mediaformview.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedui.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembed.ts", "../../../node_modules/@ckeditor/ckeditor5-media-embed/src/mediaembedtoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mentioncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mentionediting.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/ui/mentionsview.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/ui/domwrapperview.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/ui/mentionlistitemview.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mentionui.ts", "../../../node_modules/@ckeditor/ckeditor5-mention/src/mention.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/list.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/image.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removemsattributes.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/normalizers/mswordnormalizer.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removeboldwrapper.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/br.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/normalizers/googledocsnormalizer.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removexmlns.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removegooglesheetstag.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removeinvalidtablewidth.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/removestyleblock.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/normalizers/googlesheetsnormalizer.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/space.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/filters/parse.ts", "../../../node_modules/@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformatui.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformatcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformatediting.ts", "../../../node_modules/@ckeditor/ckeditor5-remove-format/src/removeformat.ts", "../../../node_modules/@ckeditor/ckeditor5-table/dist/index.js", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/tableproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/common.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/upcasttable.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablewalker.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/downcast.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/inserttablecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/insertrowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/insertcolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/splitcellcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/structure.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/mergecellcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/removerowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/removecolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/setheaderrowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/setheadercolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/constants.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableutils.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/mergecellscommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/selectrowcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/commands/selectcolumncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-layout-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-cell-paragraph-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-headings-refresh-handler.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-cell-refresh-handler.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/ui/inserttableview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableselection.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableclipboard.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablekeyboard.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablemouse/mouseeventsobserver.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablemouse.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/table.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/plaintableoutput.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/ui/widget.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tabletoolbar.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/ui/colorinputview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/ui/table-properties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/ui/formrowview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/ui/tablecellpropertiesview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/ui/contextualballoon.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/utils/table-properties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/tablecellpropertiesui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellpropertycommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellwidth/commands/tablecellwidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellwidth/tablecellwidthediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellpaddingcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellheightcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellbackgroundcolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellverticalalignmentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellborderstylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellbordercolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/commands/tablecellborderwidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties/tablecellpropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecellproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablepropertycommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablebackgroundcolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablebordercolorcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tableborderstylecommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tableborderwidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablewidthcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tableheightcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/commands/tablealignmentcommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/tablepropertiesediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/ui/tablepropertiesview.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties/tablepropertiesui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tableproperties.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/converters/table-caption-post-fixer.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/utils.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/toggletablecaptioncommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/tablecaptionediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption/tablecaptionui.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecaption.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/tablewidthscommand.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/converters.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize/tablecolumnresizeediting.ts", "../../../node_modules/@ckeditor/ckeditor5-table/src/tablecolumnresize.ts", "../../../node_modules/ckeditor5/dist/translations/de.js", "../../javascript/utils/ckeditor5.js", "../../../node_modules/@hotwired/stimulus/dist/stimulus.js", "../../javascript/controllers/application.js", "../../javascript/controllers/app_controller.js", "../../javascript/controllers/color_scheme_controller.js", "../../javascript/controllers/auth_controller.js", "../../javascript/controllers/dropdown_controller.js", "../../javascript/controllers/advanced_search_controller.js", "../../javascript/controllers/cookies_controller.js", "../../javascript/controllers/favorites_controller.js", "../../javascript/controllers/item_controller.js", "../../javascript/controllers/listing_controller.js", "../../javascript/controllers/auction_controller.js", "../../javascript/controllers/messages_controller.js", "../../javascript/controllers/message_form_controller.js", "../../javascript/controllers/mini_collapse_controller.js", "../../javascript/controllers/listing_manager_controller.js", "../../javascript/controllers/report_controller.js", "../../javascript/controllers/review_controller.js", "../../javascript/controllers/review_form_controller.js", "../../javascript/controllers/rich_content_controller.js", "../../javascript/utils/autocomplete.js", "../../javascript/controllers/search_autocomplete_controller.js", "../../javascript/controllers/search_controller.js", "../../../node_modules/js-base64/base64.mjs", "../../javascript/controllers/toasts_controller.js", "../../javascript/controllers/tabs_controller.js", "../../javascript/controllers/sell_switch_controller.js", "../../javascript/controllers/countdown_controller.js", "../../javascript/controllers/feedback_controller.js", "../../javascript/controllers/maps_loader_controller.js", "../../javascript/controllers/animated_counter_controller.js", "../../javascript/controllers/accordion_controller.js", "../../javascript/controllers/item_gallery.js", "../../javascript/controllers/modal_controller.js", "../../javascript/controllers/secure_form_controller.js", "../../javascript/controllers/interest_cloud_controller.js", "../../javascript/controllers/chart_controller.js", "../../javascript/controllers/aorb_controler.js", "../../javascript/controllers/csv_dl_controller.js", "../../javascript/controllers/category_calibers_controller.js", "../../javascript/controllers/classified_optimiser_controller.js", "../../javascript/controllers/simple_editor_controller.js", "../../javascript/controllers/picture_manager_controller.js", "../../../node_modules/@pqina/filepond-plugin-image-editor/dist/FilePondPluginImageEditor.js", "../../../node_modules/filepond/locale/de-de.js", "../../../node_modules/filepond/locale/en-en.js", "../../../node_modules/filepond/locale/es-es.js", "../../../node_modules/filepond/locale/fr-fr.js", "../../../node_modules/filepond/locale/it-it.js", "../../../node_modules/filepond/locale/nl-nl.js", "../../../node_modules/filepond/locale/pl-pl.js", "../../javascript/i18n/filepond_labels.js", "../../../node_modules/@pqina/pintura/locale/de_DE/core/de_DE.js", "../../../node_modules/@pqina/pintura/locale/de_DE/crop/de_DE.js", "../../../node_modules/@pqina/pintura/locale/de_DE/annotate/de_DE.js", "../../../node_modules/@pqina/pintura/locale/de_DE/redact/de_DE.js", "../../../node_modules/@pqina/pintura/locale/en_GB/core/en_GB.js", "../../../node_modules/@pqina/pintura/locale/en_GB/crop/en_GB.js", "../../../node_modules/@pqina/pintura/locale/en_GB/annotate/en_GB.js", "../../../node_modules/@pqina/pintura/locale/en_GB/redact/en_GB.js", "../../../node_modules/@pqina/pintura/locale/es_ES/core/es_ES.js", "../../../node_modules/@pqina/pintura/locale/es_ES/crop/es_ES.js", "../../../node_modules/@pqina/pintura/locale/es_ES/annotate/es_ES.js", "../../../node_modules/@pqina/pintura/locale/es_ES/redact/es_ES.js", "../../../node_modules/@pqina/pintura/locale/fr_FR/core/fr_FR.js", "../../../node_modules/@pqina/pintura/locale/fr_FR/crop/fr_FR.js", "../../../node_modules/@pqina/pintura/locale/fr_FR/annotate/fr_FR.js", "../../../node_modules/@pqina/pintura/locale/fr_FR/redact/fr_FR.js", "../../../node_modules/@pqina/pintura/locale/it_IT/core/it_IT.js", "../../../node_modules/@pqina/pintura/locale/it_IT/crop/it_IT.js", "../../../node_modules/@pqina/pintura/locale/it_IT/annotate/it_IT.js", "../../../node_modules/@pqina/pintura/locale/it_IT/redact/it_IT.js", "../../../node_modules/@pqina/pintura/locale/nl_NL/core/nl_NL.js", "../../../node_modules/@pqina/pintura/locale/nl_NL/crop/nl_NL.js", "../../../node_modules/@pqina/pintura/locale/nl_NL/annotate/nl_NL.js", "../../../node_modules/@pqina/pintura/locale/nl_NL/redact/nl_NL.js", "../../javascript/i18n/pintura_locale.js", "../../../node_modules/@pqina/pintura/pintura.js", "../../javascript/controllers/purchase_controller.js", "../../javascript/controllers/auction_sold_controller.js", "../../javascript/controllers/auction_table_controller.js", "../../javascript/controllers/cloudflare_turnstile_controller.js", "../../javascript/controllers/header_banner_controller.js", "../../javascript/controllers/locale_banner_controller.js", "../../javascript/controllers/locale_switcher_controller.js", "../../javascript/controllers/place_controller.js", "../../javascript/controllers/screen_blocker_controller.js", "../../javascript/controllers/dynamic_dropdown_controller.js", "../../javascript/controllers/invoice_manager_controller.js", "../../javascript/controllers/advent_calendar_controller.js", "../../javascript/controllers/form_manager_controller.js", "../../javascript/controllers/index.js", "../../javascript/application.js"],
  "sourcesContent": ["export default {\n  logger: typeof console !== \"undefined\" ? console : undefined,\n  WebSocket: typeof WebSocket !== \"undefined\" ? WebSocket : undefined,\n}\n", "import adapters from \"./adapters\"\n\n// The logger is disabled by default. You can enable it with:\n//\n//   ActionCable.logger.enabled = true\n//\n//   Example:\n//\n//   import * as ActionCable from '@rails/actioncable'\n//\n//   ActionCable.logger.enabled = true\n//   ActionCable.logger.log('Connection Established.')\n//\n\nexport default {\n  log(...messages) {\n    if (this.enabled) {\n      messages.push(Date.now())\n      adapters.logger.log(\"[ActionCable]\", ...messages)\n    }\n  },\n}\n", "import logger from \"./logger\"\n\n// Responsible for ensuring the cable connection is in good health by validating the heartbeat pings sent from the server, and attempting\n// revival reconnections if things go astray. Internal class, not intended for direct user manipulation.\n\nconst now = () => new Date().getTime()\n\nconst secondsSince = time => (now() - time) / 1000\n\nclass ConnectionMonitor {\n  constructor(connection) {\n    this.visibilityDidChange = this.visibilityDidChange.bind(this)\n    this.connection = connection\n    this.reconnectAttempts = 0\n  }\n\n  start() {\n    if (!this.isRunning()) {\n      this.startedAt = now()\n      delete this.stoppedAt\n      this.startPolling()\n      addEventListener(\"visibilitychange\", this.visibilityDidChange)\n      logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`)\n    }\n  }\n\n  stop() {\n    if (this.isRunning()) {\n      this.stoppedAt = now()\n      this.stopPolling()\n      removeEventListener(\"visibilitychange\", this.visibilityDidChange)\n      logger.log(\"ConnectionMonitor stopped\")\n    }\n  }\n\n  isRunning() {\n    return this.startedAt && !this.stoppedAt\n  }\n\n  recordMessage() {\n    this.pingedAt = now()\n  }\n\n  recordConnect() {\n    this.reconnectAttempts = 0\n    delete this.disconnectedAt\n    logger.log(\"ConnectionMonitor recorded connect\")\n  }\n\n  recordDisconnect() {\n    this.disconnectedAt = now()\n    logger.log(\"ConnectionMonitor recorded disconnect\")\n  }\n\n  // Private\n\n  startPolling() {\n    this.stopPolling()\n    this.poll()\n  }\n\n  stopPolling() {\n    clearTimeout(this.pollTimeout)\n  }\n\n  poll() {\n    this.pollTimeout = setTimeout(() => {\n      this.reconnectIfStale()\n      this.poll()\n    }\n    , this.getPollInterval())\n  }\n\n  getPollInterval() {\n    const { staleThreshold, reconnectionBackoffRate } = this.constructor\n    const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10))\n    const jitterMax = this.reconnectAttempts === 0 ? 1.0 : reconnectionBackoffRate\n    const jitter = jitterMax * Math.random()\n    return staleThreshold * 1000 * backoff * (1 + jitter)\n  }\n\n  reconnectIfStale() {\n    if (this.connectionIsStale()) {\n      logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`)\n      this.reconnectAttempts++\n      if (this.disconnectedRecently()) {\n        logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`)\n      } else {\n        logger.log(\"ConnectionMonitor reopening\")\n        this.connection.reopen()\n      }\n    }\n  }\n\n  get refreshedAt() {\n    return this.pingedAt ? this.pingedAt : this.startedAt\n  }\n\n  connectionIsStale() {\n    return secondsSince(this.refreshedAt) > this.constructor.staleThreshold\n  }\n\n  disconnectedRecently() {\n    return this.disconnectedAt && (secondsSince(this.disconnectedAt) < this.constructor.staleThreshold)\n  }\n\n  visibilityDidChange() {\n    if (document.visibilityState === \"visible\") {\n      setTimeout(() => {\n        if (this.connectionIsStale() || !this.connection.isOpen()) {\n          logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`)\n          this.connection.reopen()\n        }\n      }\n      , 200)\n    }\n  }\n\n}\n\nConnectionMonitor.staleThreshold = 6 // Server::Connections::BEAT_INTERVAL * 2 (missed two pings)\nConnectionMonitor.reconnectionBackoffRate = 0.15\n\nexport default ConnectionMonitor\n", "export default {\n  \"message_types\": {\n    \"welcome\": \"welcome\",\n    \"disconnect\": \"disconnect\",\n    \"ping\": \"ping\",\n    \"confirmation\": \"confirm_subscription\",\n    \"rejection\": \"reject_subscription\"\n  },\n  \"disconnect_reasons\": {\n    \"unauthorized\": \"unauthorized\",\n    \"invalid_request\": \"invalid_request\",\n    \"server_restart\": \"server_restart\",\n    \"remote\": \"remote\"\n  },\n  \"default_mount_path\": \"/cable\",\n  \"protocols\": [\n    \"actioncable-v1-json\",\n    \"actioncable-unsupported\"\n  ]\n}\n", "import adapters from \"./adapters\"\nimport ConnectionMonitor from \"./connection_monitor\"\nimport INTERNAL from \"./internal\"\nimport logger from \"./logger\"\n\n// Encapsulate the cable connection held by the consumer. This is an internal class not intended for direct user manipulation.\n\nconst {message_types, protocols} = INTERNAL\nconst supportedProtocols = protocols.slice(0, protocols.length - 1)\n\nconst indexOf = [].indexOf\n\nclass Connection {\n  constructor(consumer) {\n    this.open = this.open.bind(this)\n    this.consumer = consumer\n    this.subscriptions = this.consumer.subscriptions\n    this.monitor = new ConnectionMonitor(this)\n    this.disconnected = true\n  }\n\n  send(data) {\n    if (this.isOpen()) {\n      this.webSocket.send(JSON.stringify(data))\n      return true\n    } else {\n      return false\n    }\n  }\n\n  open() {\n    if (this.isActive()) {\n      logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`)\n      return false\n    } else {\n      const socketProtocols = [...protocols, ...this.consumer.subprotocols || []]\n      logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`)\n      if (this.webSocket) { this.uninstallEventHandlers() }\n      this.webSocket = new adapters.WebSocket(this.consumer.url, socketProtocols)\n      this.installEventHandlers()\n      this.monitor.start()\n      return true\n    }\n  }\n\n  close({allowReconnect} = {allowReconnect: true}) {\n    if (!allowReconnect) { this.monitor.stop() }\n    // Avoid closing websockets in a \"connecting\" state due to Safari 15.1+ bug. See: https://github.com/rails/rails/issues/43835#issuecomment-1002288478\n    if (this.isOpen()) {\n      return this.webSocket.close()\n    }\n  }\n\n  reopen() {\n    logger.log(`Reopening WebSocket, current state is ${this.getState()}`)\n    if (this.isActive()) {\n      try {\n        return this.close()\n      } catch (error) {\n        logger.log(\"Failed to reopen WebSocket\", error)\n      }\n      finally {\n        logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`)\n        setTimeout(this.open, this.constructor.reopenDelay)\n      }\n    } else {\n      return this.open()\n    }\n  }\n\n  getProtocol() {\n    if (this.webSocket) {\n      return this.webSocket.protocol\n    }\n  }\n\n  isOpen() {\n    return this.isState(\"open\")\n  }\n\n  isActive() {\n    return this.isState(\"open\", \"connecting\")\n  }\n\n  triedToReconnect() {\n    return this.monitor.reconnectAttempts > 0\n  }\n\n  // Private\n\n  isProtocolSupported() {\n    return indexOf.call(supportedProtocols, this.getProtocol()) >= 0\n  }\n\n  isState(...states) {\n    return indexOf.call(states, this.getState()) >= 0\n  }\n\n  getState() {\n    if (this.webSocket) {\n      for (let state in adapters.WebSocket) {\n        if (adapters.WebSocket[state] === this.webSocket.readyState) {\n          return state.toLowerCase()\n        }\n      }\n    }\n    return null\n  }\n\n  installEventHandlers() {\n    for (let eventName in this.events) {\n      const handler = this.events[eventName].bind(this)\n      this.webSocket[`on${eventName}`] = handler\n    }\n  }\n\n  uninstallEventHandlers() {\n    for (let eventName in this.events) {\n      this.webSocket[`on${eventName}`] = function() {}\n    }\n  }\n\n}\n\nConnection.reopenDelay = 500\n\nConnection.prototype.events = {\n  message(event) {\n    if (!this.isProtocolSupported()) { return }\n    const {identifier, message, reason, reconnect, type} = JSON.parse(event.data)\n    this.monitor.recordMessage()\n    switch (type) {\n      case message_types.welcome:\n        if (this.triedToReconnect()) {\n          this.reconnectAttempted = true\n        }\n        this.monitor.recordConnect()\n        return this.subscriptions.reload()\n      case message_types.disconnect:\n        logger.log(`Disconnecting. Reason: ${reason}`)\n        return this.close({allowReconnect: reconnect})\n      case message_types.ping:\n        return null\n      case message_types.confirmation:\n        this.subscriptions.confirmSubscription(identifier)\n        if (this.reconnectAttempted) {\n          this.reconnectAttempted = false\n          return this.subscriptions.notify(identifier, \"connected\", {reconnected: true})\n        } else {\n          return this.subscriptions.notify(identifier, \"connected\", {reconnected: false})\n        }\n      case message_types.rejection:\n        return this.subscriptions.reject(identifier)\n      default:\n        return this.subscriptions.notify(identifier, \"received\", message)\n    }\n  },\n\n  open() {\n    logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`)\n    this.disconnected = false\n    if (!this.isProtocolSupported()) {\n      logger.log(\"Protocol is unsupported. Stopping monitor and disconnecting.\")\n      return this.close({allowReconnect: false})\n    }\n  },\n\n  close(event) {\n    logger.log(\"WebSocket onclose event\")\n    if (this.disconnected) { return }\n    this.disconnected = true\n    this.monitor.recordDisconnect()\n    return this.subscriptions.notifyAll(\"disconnected\", {willAttemptReconnect: this.monitor.isRunning()})\n  },\n\n  error() {\n    logger.log(\"WebSocket onerror event\")\n  }\n}\n\nexport default Connection\n", "// A new subscription is created through the ActionCable.Subscriptions instance available on the consumer.\n// It provides a number of callbacks and a method for calling remote procedure calls on the corresponding\n// Channel instance on the server side.\n//\n// An example demonstrates the basic functionality:\n//\n//   App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\", {\n//     connected() {\n//       // Called once the subscription has been successfully completed\n//     },\n//\n//     disconnected({ willAttemptReconnect: boolean }) {\n//       // Called when the client has disconnected with the server.\n//       // The object will have an `willAttemptReconnect` property which\n//       // says whether the client has the intention of attempting\n//       // to reconnect.\n//     },\n//\n//     appear() {\n//       this.perform('appear', {appearing_on: this.appearingOn()})\n//     },\n//\n//     away() {\n//       this.perform('away')\n//     },\n//\n//     appearingOn() {\n//       $('main').data('appearing-on')\n//     }\n//   })\n//\n// The methods #appear and #away forward their intent to the remote AppearanceChannel instance on the server\n// by calling the `perform` method with the first parameter being the action (which maps to AppearanceChannel#appear/away).\n// The second parameter is a hash that'll get JSON encoded and made available on the server in the data parameter.\n//\n// This is how the server component would look:\n//\n//   class AppearanceChannel < ApplicationActionCable::Channel\n//     def subscribed\n//       current_user.appear\n//     end\n//\n//     def unsubscribed\n//       current_user.disappear\n//     end\n//\n//     def appear(data)\n//       current_user.appear on: data['appearing_on']\n//     end\n//\n//     def away\n//       current_user.away\n//     end\n//   end\n//\n// The \"AppearanceChannel\" name is automatically mapped between the client-side subscription creation and the server-side Ruby class name.\n// The AppearanceChannel#appear/away public methods are exposed automatically to client-side invocation through the perform method.\n\nconst extend = function(object, properties) {\n  if (properties != null) {\n    for (let key in properties) {\n      const value = properties[key]\n      object[key] = value\n    }\n  }\n  return object\n}\n\nexport default class Subscription {\n  constructor(consumer, params = {}, mixin) {\n    this.consumer = consumer\n    this.identifier = JSON.stringify(params)\n    extend(this, mixin)\n  }\n\n  // Perform a channel action with the optional data passed as an attribute\n  perform(action, data = {}) {\n    data.action = action\n    return this.send(data)\n  }\n\n  send(data) {\n    return this.consumer.send({command: \"message\", identifier: this.identifier, data: JSON.stringify(data)})\n  }\n\n  unsubscribe() {\n    return this.consumer.subscriptions.remove(this)\n  }\n}\n", "import logger from \"./logger\"\n\n// Responsible for ensuring channel subscribe command is confirmed, retrying until confirmation is received.\n// Internal class, not intended for direct user manipulation.\n\nclass SubscriptionGuarantor {\n  constructor(subscriptions) {\n    this.subscriptions = subscriptions\n    this.pendingSubscriptions = []\n  }\n\n  guarantee(subscription) {\n    if(this.pendingSubscriptions.indexOf(subscription) == -1){ \n      logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`)\n      this.pendingSubscriptions.push(subscription) \n    }\n    else {\n      logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`)\n    }\n    this.startGuaranteeing()\n  }\n\n  forget(subscription) {\n    logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`)\n    this.pendingSubscriptions = (this.pendingSubscriptions.filter((s) => s !== subscription))\n  }\n\n  startGuaranteeing() {\n    this.stopGuaranteeing()\n    this.retrySubscribing()\n  }\n  \n  stopGuaranteeing() {\n    clearTimeout(this.retryTimeout)\n  }\n\n  retrySubscribing() {\n    this.retryTimeout = setTimeout(() => {\n      if (this.subscriptions && typeof(this.subscriptions.subscribe) === \"function\") {\n        this.pendingSubscriptions.map((subscription) => {\n          logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`)\n          this.subscriptions.subscribe(subscription)\n        })\n      }\n    }\n    , 500)\n  }\n}\n\nexport default SubscriptionGuarantor", "import logger from \"./logger\"\nimport Subscription from \"./subscription\"\nimport SubscriptionGuarantor from \"./subscription_guarantor\"\n\n// Collection class for creating (and internally managing) channel subscriptions.\n// The only method intended to be triggered by the user is ActionCable.Subscriptions#create,\n// and it should be called through the consumer like so:\n//\n//   App = {}\n//   App.cable = ActionCable.createConsumer(\"ws://example.com/accounts/1\")\n//   App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\")\n//\n// For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.\n\nexport default class Subscriptions {\n  constructor(consumer) {\n    this.consumer = consumer\n    this.guarantor = new SubscriptionGuarantor(this)\n    this.subscriptions = []\n  }\n\n  create(channelName, mixin) {\n    const channel = channelName\n    const params = typeof channel === \"object\" ? channel : {channel}\n    const subscription = new Subscription(this.consumer, params, mixin)\n    return this.add(subscription)\n  }\n\n  // Private\n\n  add(subscription) {\n    this.subscriptions.push(subscription)\n    this.consumer.ensureActiveConnection()\n    this.notify(subscription, \"initialized\")\n    this.subscribe(subscription)\n    return subscription\n  }\n\n  remove(subscription) {\n    this.forget(subscription)\n    if (!this.findAll(subscription.identifier).length) {\n      this.sendCommand(subscription, \"unsubscribe\")\n    }\n    return subscription\n  }\n\n  reject(identifier) {\n    return this.findAll(identifier).map((subscription) => {\n      this.forget(subscription)\n      this.notify(subscription, \"rejected\")\n      return subscription\n    })\n  }\n\n  forget(subscription) {\n    this.guarantor.forget(subscription)\n    this.subscriptions = (this.subscriptions.filter((s) => s !== subscription))\n    return subscription\n  }\n\n  findAll(identifier) {\n    return this.subscriptions.filter((s) => s.identifier === identifier)\n  }\n\n  reload() {\n    return this.subscriptions.map((subscription) =>\n      this.subscribe(subscription))\n  }\n\n  notifyAll(callbackName, ...args) {\n    return this.subscriptions.map((subscription) =>\n      this.notify(subscription, callbackName, ...args))\n  }\n\n  notify(subscription, callbackName, ...args) {\n    let subscriptions\n    if (typeof subscription === \"string\") {\n      subscriptions = this.findAll(subscription)\n    } else {\n      subscriptions = [subscription]\n    }\n\n    return subscriptions.map((subscription) =>\n      (typeof subscription[callbackName] === \"function\" ? subscription[callbackName](...args) : undefined))\n  }\n\n  subscribe(subscription) {\n    if (this.sendCommand(subscription, \"subscribe\")) {\n      this.guarantor.guarantee(subscription)\n    }\n  }\n\n  confirmSubscription(identifier) {\n    logger.log(`Subscription confirmed ${identifier}`)\n    this.findAll(identifier).map((subscription) =>\n      this.guarantor.forget(subscription))\n  }\n\n  sendCommand(subscription, command) {\n    const {identifier} = subscription\n    return this.consumer.send({command, identifier})\n  }\n}\n", "import Connection from \"./connection\"\nimport Subscriptions from \"./subscriptions\"\n\n// The ActionCable.Consumer establishes the connection to a server-side Ruby Connection object. Once established,\n// the ActionCable.ConnectionMonitor will ensure that its properly maintained through heartbeats and checking for stale updates.\n// The Consumer instance is also the gateway to establishing subscriptions to desired channels through the #createSubscription\n// method.\n//\n// The following example shows how this can be set up:\n//\n//   App = {}\n//   App.cable = ActionCable.createConsumer(\"ws://example.com/accounts/1\")\n//   App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\")\n//\n// For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.\n//\n// When a consumer is created, it automatically connects with the server.\n//\n// To disconnect from the server, call\n//\n//   App.cable.disconnect()\n//\n// and to restart the connection:\n//\n//   App.cable.connect()\n//\n// Any channel subscriptions which existed prior to disconnecting will\n// automatically resubscribe.\n\nexport default class Consumer {\n  constructor(url) {\n    this._url = url\n    this.subscriptions = new Subscriptions(this)\n    this.connection = new Connection(this)\n    this.subprotocols = []\n  }\n\n  get url() {\n    return createWebSocketURL(this._url)\n  }\n\n  send(data) {\n    return this.connection.send(data)\n  }\n\n  connect() {\n    return this.connection.open()\n  }\n\n  disconnect() {\n    return this.connection.close({allowReconnect: false})\n  }\n\n  ensureActiveConnection() {\n    if (!this.connection.isActive()) {\n      return this.connection.open()\n    }\n  }\n\n  addSubProtocol(subprotocol) {\n    this.subprotocols = [...this.subprotocols, subprotocol]\n  }\n}\n\nexport function createWebSocketURL(url) {\n  if (typeof url === \"function\") {\n    url = url()\n  }\n\n  if (url && !/^wss?:/i.test(url)) {\n    const a = document.createElement(\"a\")\n    a.href = url\n    // Fix populating Location properties in IE. Otherwise, protocol will be blank.\n    a.href = a.href // eslint-disable-line\n    a.protocol = a.protocol.replace(\"http\", \"ws\")\n    return a.href\n  } else {\n    return url\n  }\n}\n", "import adapters from \"./adapters\"\nimport Connection from \"./connection\"\nimport ConnectionMonitor from \"./connection_monitor\"\nimport Consumer, { createWebSocketURL } from \"./consumer\"\nimport INTERNAL from \"./internal\"\nimport logger from \"./logger\"\nimport Subscription from \"./subscription\"\nimport SubscriptionGuarantor from \"./subscription_guarantor\"\nimport Subscriptions from \"./subscriptions\"\n\nexport {\n  Connection,\n  ConnectionMonitor,\n  Consumer,\n  INTERNAL,\n  Subscription,\n  Subscriptions,\n  SubscriptionGuarantor,\n  adapters,\n  createWebSocketURL,\n  logger,\n}\n\nexport function createConsumer(url = getConfig(\"url\") || INTERNAL.default_mount_path) {\n  return new Consumer(url)\n}\n\nexport function getConfig(name) {\n  const element = document.head.querySelector(`meta[name='action-cable-${name}']`)\n  if (element) {\n    return element.getAttribute(\"content\")\n  }\n}\n", "(function(n,t){\"object\"===typeof exports&&\"undefined\"!==typeof module?t(exports):\"function\"===typeof define&&define.amd?define([\"exports\"],t):(n=\"undefined\"!==typeof globalThis?globalThis:n||self,t(n[\"@castleio/castle-js\"]={}))})(this,function(R){var M={e:\"OaQ=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\",\nt:{0:{0:{0:{0:{0:{0:{0:{0:\"j\",1:\"d\"},1:\"0\"},1:{0:{0:\"Y\",1:\"Z\"},1:{0:{0:\"S\",1:\"w\"},1:{0:{0:\"m\",1:\".\"},1:{0:\"'\",1:{0:\"W\",1:\"H\"}}}}}},1:{0:\"7\",1:{0:\"F\",1:{0:\"x\",1:\"A\"}}}},1:{0:\"z\",1:{0:{0:\"5\",1:\"!\"},1:{0:{0:\"R\",1:\"4\"},1:\"G\"}}}},1:{0:\"b\",1:{0:\"t\",1:\"?\"}}},1:{0:\"r\",1:{0:{0:{0:\"u\",1:{0:\"2\",1:\"8\"}},1:\"q\"},1:\"a\"}}},1:{0:{0:{0:\",\",1:{0:{0:\"o\",1:{0:\"Q\",1:\"3\"}},1:{0:{0:\"k\",1:{0:\"E\",1:\"V\"}},1:{0:{0:\"C\",1:{0:\"U\",1:\"B\"}},1:\"9\"}}}},1:{0:\"n\",1:{0:\"y\",1:\"p\"}}},1:{0:{0:{0:{0:{0:{0:{0:\"J\",1:\"-\"},1:{0:{0:\"I\",1:{0:\"T\",\n1:\"L\"}},1:\"N\"}},1:\"l\"},1:\"s\"},1:{0:{0:\"P\",1:\"i\"},1:\"c\"}},1:{0:\"f\",1:{0:{0:\"1\",1:{0:\"6\",1:\"O\"}},1:\"h\"}}},1:{0:\"g\",1:{0:\"v\",1:\"e\"}}}}}},O={e:\"ysk=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\",\nt:{0:{0:{0:\"r\",1:{0:\"v\",1:\"a\"}},1:{0:{0:{0:{0:{0:{0:\"V\",1:\"(\"},1:\"j\"},1:\"-\"},1:{0:{0:{0:\")\",1:{0:\";\",1:\"{\"}},1:{0:{0:\"}\",1:{0:\"/\",1:{0:\"D\",1:\"W\"}}},1:\"S\"}},1:{0:\"F\",1:{0:\"E\",1:{0:{0:{0:\"&\",1:{0:\"M\",1:\" \"}},1:\"4\"},1:\"J\"}}}}},1:\"e\"},1:{0:\"b\",1:{0:{0:{0:{0:'\"',1:{0:\"=\",1:{0:\"d\",1:\"[\"}}},1:{0:{0:{0:\"]\",1:{0:{0:\"+\",1:{0:\"\\u00e5\",1:\"\\u00f6\"}},1:\"3\"}},1:\"H\"},1:\"Z\"}},1:\"u\"},1:\"p\"}}}},1:{0:{0:{0:\"g\",1:{0:\"q\",1:{0:\"o\",1:{0:{0:{0:\"1\",1:{0:\"6\",1:\"K\"}},1:\"#\"},1:\"k\"}}}},1:{0:\"?\",1:\"n\"}},1:{0:{0:{0:\"y\",1:{0:{0:\"x\",\n1:{0:\"O\",1:\"Y\"}},1:\"t\"}},1:{0:{0:\"!\",1:{0:{0:{0:{0:{0:\"7\",1:{0:{0:\"\\u00e4\",1:\">\"},1:\"5\"}},1:\"9\"},1:\"I\"},1:{0:\"U\",1:\"2\"}},1:\",\"}},1:\"f\"}},1:{0:{0:{0:{0:{0:{0:\"T\",1:\"w\"},1:{0:{0:\"m\",1:\"|\"},1:{0:{0:\"L\",1:\"'\"},1:{0:{0:\"8\",1:\"^\"},1:\"X\"}}}},1:{0:\"C\",1:\"G\"}},1:\"h\"},1:{0:{0:\"l\",1:\".\"},1:{0:\"i\",1:{0:\"N\",1:{0:\"0\",1:\"A\"}}}}},1:{0:{0:{0:\"_\",1:{0:\"Q\",1:\"R\"}},1:\"z\"},1:{0:{0:\"s\",1:{0:{0:\":\",1:\"B\"},1:\"P\"}},1:\"c\"}}}}}}};function I(n,t){var r=n.charCodeAt();return r>=65&&r<=90?String.fromCharCode((r-65+t)%26+65):r>=\n97&&r<=122?String.fromCharCode((r-97+t)%26+97):32===r?String.fromCharCode(r+1):33===r?String.fromCharCode(r-1):n}function k(n,t){for(var r=\"\",u=t%26,e=0;e<n.length;e++)r+=I(n.charAt(e),u);return r}function W(n,t){for(var r=\"\",u=t,e=0;e<n.length;e++)u=u[n.charAt(e)],\"string\"===typeof u&&(r+=u,u=t);return r}function q(n){var t,r=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",u=\"\",e=n.length;for(n=n.replace(/=+$/,\"\"),t=0;t<e;t+=4){var c=r.indexOf(n.charAt(t))<<18,i=r.indexOf(n.charAt(t+\n1))<<12,o=r.indexOf(n.charAt(t+2))<<6,f=r.indexOf(n.charAt(t+3)),c=c|i|(o<0?0:o)|(f<0?0:f);u+=String.fromCharCode(c>>16&255),o>=0&&(u+=String.fromCharCode(c>>8&255)),f>=0&&(u+=String.fromCharCode(255&c))}return u}function V(n){for(var t=\"\",r=q(n.substr(0,4)),r=r.charCodeAt(0)<<8|r.charCodeAt(1),u=q(n.substr(4)),e=0;e<u.length;e++){var c=u.charCodeAt(e).toString(2);while(c.length<8)c=\"0\"+c;t+=c}return t.slice(-r)}var z=W(V(M.e),M.t).split(\"?\");function i(n){return k(z[n],13).split(\",\")}var Z=W(V(O.e),\nO.t).split(\"?\");function vn(n){return k(Z[n],13)}var B=\"8\",N=\"46\",U=\"32\",A=\"13\",G=\"9\",Q=\"16\",J=\"18\",K=\"17\",Y=\"224\",$=\"37\",nn=\"38\",tn=\"39\",rn=\"40\",un=vn(0),en=vn(1),cn=vn(2),on=vn(3),fn=vn(4),an=vn(5),_n=vn(6),ln=vn(7),dn=vn(8),hn=vn(9),pn=vn(10),yn=[un,en,B,N],mn=yn.concat([cn,on,fn,U,A,G]),wn=vn(11),gn=vn(12),Hn=vn(13),xn=vn(14),bn=vn(15),Fn=vn(16),Tn=vn(17),jn=vn(18),Xn=vn(19),Pn=vn(20),Ln=vn(21),Cn=vn(22),Dn=\"[\".concat(Cn,\"]\"),En=vn(23),Sn=vn(24),Rn=vn(25),Mn=vn(26),On=vn(27),In=vn(28),kn=vn(29),\nM=vn(30),Wn=vn(31),qn=vn(32),Vn=vn(33),zn=vn(34),Zn=vn(35),Bn=vn(36),Nn=vn(37),Un=vn(38),An=Nn+\"s\",Gn=vn(39),Qn=vn(40),Jn=vn(41),Kn=vn(42),Yn=vn(43),$n=vn(44),nt=vn(45),tt=vn(46),rt=vn(47),ut=vn(48),et=vn(49),ct=vn(50),it=vn(51),ot=vn(52),ft=vn(53),at=vn(54),_t=vn(55),vt=vn(56),st=vn(57),lt=vn(58),dt=vn(59),ht=vn(60),pt=vn(61),yt=vn(62),mt=vn(63),wt=vn(64),gt=vn(65),O=vn(66),Ht=vn(67),n=vn(68),xt=vn(69),bt=vn(70),Ft=vn(71),Tt=vn(72),jt=vn(73),Xt=vn(74),Pt=vn(75),Lt=vn(76),Ct=vn(77),Dt=vn(78),Et=\"^\\\\$?\".concat(Dt,\n\"_[a-zA-Z0-9]\"),St=vn(79),Rt=vn(80),Mt=vn(81),Ot=vn(82),It=vn(83),kt=vn(84),Wt=vn(85),qt=vn(86),Vt=vn(87),zt=vn(88),Zt=vn(89),Bt=vn(90),Nt=vn(91),Ut=vn(92),At=vn(93),Gt=vn(94),m=0,w=void m,p=null,y=Object,Qt=255,g=[].join(),Jt=1535E6,Kt=function(){},Yt=[],$t=6,nr=[3478979992,1302732199,2717384055,3748418954],tr=1164413191,rr=3891440048,ur=2746598870,er=function(n){return s(n)&&n!==g},cr=function(n){return n===w},ir=function(n){return!cr(n)},s=function(n){return ir(n)&&n!==p},or=function(n){return n||\nw},fr=function(n){return n?1:0},H=function(n,t){return!!(s(n)&&\"hasOwnProperty\"in n)&&n.hasOwnProperty(t)},ar=function(n,t){return t in n&&!!n[t]},_r=function(n){return y[zn](n)},vr=function(n){return y[Zn](n)},sr=function(n,t){return y[Nn](n,t)},lr=function(){return H(y,zn)&&H(y,Zn)&&H(y,Nn)},dr=function(n){return n.constructor.name},e=function(n){try{return n()}catch(t){}},f=function(r){return{u:function(n){return f(n(r))},i:function(t){return function(n){return t(n),f(n)}(r)},o:function(){return r}}},\nDt=function(n,t){for(var r in t)H(t,r)&&(n[r]=t[r]);return n},hr=y.assign||Dt,d=function(n){return n.navigator},pr=function(n){return n.document},yr=function(n){return n.screen},mr=function(n){return n.location},wr=function(n){return pr(n).documentElement},gr=function(n){return pr(n).body},Hr=function(n){return n.innerWidth||0},xr=function(n){return n.innerHeight||0},br=function(n){return n.outerWidth||0},Fr=function(n){return n.outerHeight||0},Tr=function(n){return n[Vn]},jr=function(n){return n[qn]},\nXr=function(t){return f(Tr(t)).u(function(n){return n?n.height:xr(t)}).o()},Pr=function(n,t,r){return n.setAttribute(t,r)},Lr=function(n,t){if(n.getAttribute)return n.getAttribute(t)},Cr=function(n,t){n&&n.appendChild(t)},Dr=function(n,t){n&&n.removeChild(t)},Er=function(n,t){return pr(n).createElement(t)},Sr=function(n){n&&n.parentNode&&n.parentNode.removeChild(n)},Rr=function(n,t,r){n.style.setProperty(t,r,\"important\")},Mr=function(n){Rr(n,\"visibility\",\"hidden\"),Rr(n,\"display\",\"block\")},Or=function(n,\nt,r,u){var e=pr(n);try{e.cookie=\"\".concat(t,\"=\").concat(r,\";path=/;\").concat(u).concat(\"SameSite=Lax\")}catch(c){}},Ir=function(n,t){var r=pr(n);try{return(r.cookie.match(\"(^|; )\".concat(t,\"=([^;]*)\"))||0)[2]}catch(u){return null}},kr=function(n){return!isNaN(n-parseFloat(n))},Wr=function(n){var t=Number.isInteger;return s(t)?t(n):\"number\"===typeof n&&isFinite(n)&&~~n===n},qr=function(n){var t=Array.isArray;return Vr(t)?t(n):\"[object Array]\"===y.prototype.toString.call(n)},Vr=function(n){return\"function\"===\ntypeof n},zr=function(n){return\"object\"===typeof n},Zr=function(n){return zr(n)&&!qr(n)},Br=function(n){return\"string\"===typeof n},Nr=function(n){return typeof n===typeof w},Ur=function(n,t){var r=n instanceof Object?n:new Object(n),u=isFinite(r.length)?~~r.length:0,e=0;if(t===undefined){do if(e in r&&r[e]===undefined)return e;while(++e<u)}else{do if(r[e]===t)return e;while(++e<u)}return-1},Ar=function(n){if(qr(n)&&n.length)return n.join(\",\")},Gr=function(n){n.splice(0,n.length)},Qr=function(n,t){for(var r=\n[],u=0,e=n;u<e.length;u++){var c=e[u];t(c)&&r.push(c)}return r},Jr=function(n,t){for(var r=0,u=n;r<u.length;r++){var e=u[r];if(t(e))return!0}return!1},Kr=function(n,t){for(var r in n)if(s(n[r])&&Zr(n[r])&&H(n[r],t))return!0;return!1},Yr=function(n){return Qr(n,function(n){return n})},$r=function(n,t){for(var r=[],u=0,e=n;u<e.length;u++){var c=e[u];r.push(t(c))}return r},nu=function(n,t){for(var r=0,u=0,e=n;u<e.length;u++){var c=e[u];t(c,r++)}},tu=function(n){if(\"values\"in y)return y.values(n);var t,\nr=[];for(t in n)H(n,t)&&r.push(n[t]);return r},ru=function(n){if(\"keys\"in y)return y.keys(n);var t,r=[];for(t in n)H(n,t)&&r.push(t);return r},uu=function(n,t,r){for(var u=r,e=0,c=0,i=n;c<i.length;c++){var o=i[c],u=t(u,o,e);e++}return u},eu=function(n,t){for(var r=Array(n),u=r.length-1;u>=0;u--)r[u]=t(u);return r},cu=function(n,t){return n||t?t?n?n.concat(t):t:n:[]},iu=function(n){return n?[].concat(n):[]},ou=function(n){if(y(n)!==n)return{};for(var t in n)er(n[t])||delete n[t];return n},fu=function(n,\nt){return!!n&&Ur(n,t)>=0},au=function(n){var r={\"boolean\":{},number:{},string:{}},u=[];return Qr(n,function(n){var t=typeof n;return t in r?!H(r[t],n)&&(r[t][n]=!0):!fu(u,n)&&(u.push(n),!0)})},l=function(n,t){for(var r=0;r<n.length;r++)if(n[r]===t)return!0;return!1},_u=function(n,t){var r=0;while(r<n.length)n[r]===t?n.splice(r,1):r++;return n},vu=function(n){for(var t=n.length,r=new Array(t),u=0;u<t;u++)r[u]=n[t-1-u];return r},su=function(n){for(var t=[],r=0;r<n.length;r++)qr(n[r])?nu(n[r],function(n){return t.push(n)}):\nt.push(n[r]);return t},lu=function(n){return $r(n,function(n){return!!n})},du=function(n){return uu(n,function(n,t,r){return er(t)&&(n[t]=r),n},{})},Dt=function(n,t){return du(n.split(t||\",\"))},hu=function(n){return n.toLowerCase()},pu=function(n){return n.toUpperCase()},yu=function(n){return n.length},mu=vn(95),wu=function(n,t){return n[mu](t)},gu=function(n){return pu(wu(n,m))+n.slice(1)},Hu=function(n,t){return n+gu(t)},xu=function(n,t){return n+\".\"+t},bu=function(n){return n.replace(/[\\x00-\\x08\\x0E-\\x1F\\x7F-\\x9F]/g,\ng)},Fu=function(n){return n.replace(/\\s/g,\" \")},Tu=function(n){return n.replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g,\" \")},ju=function(n){return Fu(bu(Tu(n+g)))},Xu=function(n){return n.replace(/^\\s+|\\s+$/g,\"\")},Pu=function(n){return Br(n)&&1===yu(n)&&n===pu(n)&&n!==hu(n)},Lu=function(n){return n.toString()},x=function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];var e=function(n,t){return n+t},c=function(n,t,r){var u;return t===r?n[t]:(u=~~((t+r)/2),e(c(n,t,u),c(n,u+1,r)))};return c(n,\n0,n.length-1)},Cu=function(n,t){return n.indexOf(t)>-1},Du=function(n){return JSON.stringify(n)},Eu=function(n){return JSON.parse(n)},Su=vn(96),Ru=vn(97),Mu=vn(98),Ou=vn(99),Iu=vn(100),ku=vn(101),Wu=vn(102),qu=vn(103),Vu=vn(104),zu=vn(105),Zu=vn(106),Bu=vn(107),Nu=vn(108),Uu=vn(109),Au=function(){return Math},Gu=function(n){return Au()[Su](n)},Qu=function(n){return Au()[Ou](n)},Ju=function(n){return Au()[Iu](n)},Ku=function(n,t){return Au()[ku](n,t)},Yu=function(n,t){return Au()[Mu](n,t)},$u=function(n,\nt){return Au()[qu](n,t)},ne=function(){return Au()[Wu]},te=function(n,t){return ne()(n,t)},re=function(){return Au()[Vu]},ue=function(n){return Au()[Uu](n)},ee=function(){return Au()[Nu]},ce=function(n){return Au()[zu](n)},ie=function(n){return Au()[Zu](n)},oe=function(n,t){return Au()[Bu](n,t)},fe=function(n,t){var r;return void 0===t&&(t=2),s(n)&&isFinite(n)?(r=Yu(10,t),Gu(n*r)/r):p},ae=function(n,t){return t!==m?n/t:p},_e=function(){return Au()[Ru]()},ve=function(n){return _e()*n|m},se=function(n,\nt){return Ju(n-t)},le=function(n){return s(n)?n>m?1:n<m?-1:m:m},c=function(n){var u=\"\".concat(Du(n)),t=uu(u.split(g),function(n,t,r){return Ku(31,n)+u.charCodeAt(r)|0},2166136261);return(\"0000000\"+(t>>>0).toString(16)).substr(-8)},b=function(n){var t=(n&Qt).toString(16);return(\"0\"+t).slice(-2)},de=function(n){for(var t=g,r=0;r<n.length;r++)t+=(15&n.charCodeAt(r)).toString(16);return t},he=function(n){for(var t=[],r=0;r<n.length;r++)t.push(n.charCodeAt(r)&Qt);return t},pe=function(n){return uu(he(n),\nfunction(n,t){return x(n,b(t))},g)},ye=function(n){var t=(3&n).toString(2);return(\"0\"+t).slice(-2)},me=function(n){return(15&n).toString(16)},we=function(n,t){var r=$u(Yu(2,8*t)-1,n),u=g,e=2*t;while(r>0)u=b(r)+u,r>>>=8;if(e)while(u.length<e)u=x(\"0\",u);return u},ge=function(n){return uu(n.match(/.{2}/g)||[],function(n,t){return x(n,String.fromCharCode(parseInt(t,16)&Qt))},g)},He=function(n){return $r(n.match(/.{2}/g)||[],function(n){return parseInt(n,16)&Qt})},xe=function(n){return uu(n,function(n,\nt){return x(n,b(t))},g)},be=function(n,t){for(var r=0,u=t&&n.length>t?n.slice(0,t):n,e=u.length,c=e-1;c>=0;c--)r|=(u[c]?1:0)<<e-c-1;return t&&e<t&&(r<<=t-e),r},Fe=function(n){for(var t=[],r=0;r<n.length;r++){var u=n[r]>>>0;t.push(255&u,u>>8&255,u>>16&255,u>>24&255)}return t},Te=function(n){for(var t=[],r=0;r<Qu(n.length/4);r++)t.push(((n[4*r]||0)|(n[4*r+1]||0)<<8|(n[4*r+2]||0)<<16|(n[4*r+3]||0)<<24)>>>0);return t},je=function(n){for(var t=0,r=0;r<n.length;r++)t^=n.charCodeAt(r);return 255&t},Xe=function(n,\nu){var e=0;return uu(n.split(g),function(n,t){var r=parseInt(t,16)^parseInt(wu(u,e),16);return e=(e+1)%u.length,x(n,r.toString(16))},g)},Pe=4,Le=3,Ce=function(n){var t=2,r=m,u=m;if(0===n)return{s:m,m:m,e:m};n<m&&(r=1,n=-n);while(n>=t)n/=t,u++;while(n<1)n*=t,u--;return{s:r,m:n,e:u}},De=function(n,t){var r=~~n,r=n-r,u=m;if(r>0){var e=1,c=r;while(!(0===c||e>t)){c*=2;var i=~~c;u|=i<<t-e,c-=i,e++}}return u},Ee=function(n,t){return n/Yu(2,t)+1},Se=function(n,t){var r=(1<<t)-1;return $u(n,r)},Re=function(){function n(n,\nt){this.exp=n,this.man=t,this.a=(1<<n)-1,this.b=(1<<t)-1}return n.prototype.e=function(n){var t=Ce(n),r=Se(t.e,this.exp),t=De(t.m,this.man);return r<<this.man|t},n.prototype.d=function(n){var t=n>>this.man&this.a,r=n&this.b;return Ee(r,this.man)*Yu(2,t)},n}(),Me=new Re(Pe,Le),Oe=new Re(Pe-2,Le+1),Ie=Yu(2,16),ke=function(n){var t;return kr(n)?(t=te(n,0),t<=15?64|Oe.e(t+1):128|Me.e($u(t,Ie)-14)):0},We=function(n){return uu(n,function(n,t){return x(n,b(ke(t)))},g)},qe=function(n){return f(~~(n/1E3-Jt)).u(function(n){return te($u(n,\n268435455),0)}).u(function(n){return xe([n>>24,n>>16,n>>8,n])}).o()},Ve=function(n){return we(n%1E3,2)},ze=function(n){return Be(me(ve(16)),n)},Ze=function(t,r){return f(me(ve(16))).u(function(n){return x(Be(n,t),Be(n,r))}).o()},Be=function(n,t){return Xe(t.slice(1),n)+n},Ne=vn(110),Ue=vn(111),Ae=vn(112),Ge=vn(113),Qe=vn(114),Je=function(n,t,r,u){Ye(n)?n[Ne](t,r,!u):$e(n)&&n[Ue](\"\".concat(Qe).concat(t),r)},Ke=function(n,t,r,u){Ye(n)?n[Ge](t,r,!u):$e(n)&&n[Ae](\"\".concat(Qe).concat(t),r)},Ye=function(n){return!!n[Ne]},\n$e=function(n){return!!n[Ue]},nc=vn(115),tc=function(n,t,r,u){try{var e=n[nc];e||u(),e.setItem(t,r),e.getItem(t)!==r&&(e.removeItem(t),u())}catch(c){u()}},rc=function(n,t){try{var r=n[nc];return r?r.getItem(t):p}catch(u){return p}},uc=function(n,t){try{var r=n[nc];if(r)return r.removeItem(t)}catch(u){}},ec=vn(183),cc=vn(116),ic=\"warn\",oc=vn(330),fc=function(n,t,r){ac(n,t,ec+r)},ac=function(n,t,r){var u;H(n,cc)&&(u=n[cc],H(u,t))&&u[t](r)},_c=4294967296,vc=function(){var u=4022871197,n=function(n){n=\nn.toString();for(var t=0;t<n.length;t++){u+=n.charCodeAt(t);var r=.02519603282416938*u;u=r>>>0,r-=u,r*=u,u=r>>>0,r-=u,u+=r*_c}return 2.3283064365386963E-10*(u>>>0)};return n},sc=function(n){for(var t=0,r=0,u=0,e=1,c=vc(),t=c(\" \"),r=c(\" \"),u=c(\" \"),i=0;i<n.length;i++)t-=c(n[i]),t<0&&(t+=1),r-=c(n[i]),r<0&&(r+=1),u-=c(n[i]),u<0&&(u+=1);return null,function(){var n=2091639*t+2.3283064365386963E-10*e;return t=r,r=u,u=n-(e=0|n)}},lc=function(n){return n()*_c},dc=function(n,t){var r=n.length;return Array.prototype.unshift.apply(n,\nArray.prototype.splice.call(n,t%r,r)),n},hc=function(n,t){return dc(n.split(g),t).join(g)},pc=function(n,t,r,u){return Xe(n,hc(t.slice(0,r),parseInt(u,16)))},yc=function(n,t){for(var r,u,e=0,c=[],i=0;i<n.length;i++){if(r=[],u=n.charCodeAt(i),u<128?r.push(u):u<2048?r.push(192|u>>6,128|63&u):u<55296||u>=57344?r.push(224|u>>12,128|u>>6&63,128|63&u):(i++,u=65536+((1023&u)<<10|1023&n.charCodeAt(i)),r.push(240|u>>18,128|u>>12&63,128|u>>6&63,128|63&u)),t&&!(e+r.length<=t))break;e+=r.length,c.push.apply(c,\nr)}return c},mc=[2650800128,3633152,2489],wc=function(n){return(n[0]>>>m)+(n[1]>>>m)+(n[2]>>>m)};function gc(n,t){var r=Te(n),u=r.length-1;if(!(u<1)){var e,c,i=0,o=r[u],f=r[0],a=~~(6+52/(u+1));while(a-- >0){for(i=i+wc(mc)>>>0,e=i>>>2&3,c=0;c<u;c++)f=r[c+1],o=r[c]=r[c]+((o>>>5^f<<2)+(f>>>3^o<<4)^(i^f)+(t[3&c^e]^o))>>>0;f=r[0],o=r[u]=r[u]+((o>>>5^f<<2)+(f>>>3^o<<4)^(i^f)+(t[3&c^e]^o))>>>0}}return r}var Hc,xc,bc,Fc,Tc,jc,Xc,Pc,Lc,Cc,Dc,Ec,Sc,Rc,Mc,Oc,Ic,kc,Wc,qc,Vc,zc,Zc,Bc,Nc,Uc,Ac,Gc,Qc,Jc,Kc,Yc,$c,\nni,ti,ri,ui,ei,ci,ii,oi,fi,ai,_i,vi,si,li,di,hi,pi,yi,mi=function(n){var t=m;while(n!=m)n>>=8,t++;return t},wi=function(n,r){return f(yc(ju(n),r?Qt-4:Qt)).u(function(n){var t=r?Fe(gc(n,cu(r,nr).concat([tr]))):n;return x(b(t.length),xe(t))}).o()},gi=function(n,t,r){var u=yc(ju(n),t&&r?r-4:r),u=t?Fe(gc(u,cu(t,nr).concat([tr]))):u,e=mi(u.length);return e>$t?b(m):x(b(e),we(u.length,e),xe(u))},Hi=function(){return new Date},Pe=function(n){return(new Date(n,1,1,m,m,1)).toUTCString()},xi=function(n){return new Date(n)},\nbi=Date.now||function(){return Hi().getTime()},Fi=function(n){var t=Hi();return t.setSeconds(t.getSeconds()+n),t.toUTCString()},Ti={},ji=function(){return Ti._=bi()},Xi=function(){return Ti._},Pi=\"0-9a-f\",Li=vn(117),Ci=vn(118),Di=vn(119),Ei=vn(120),Si=function(n){return we(lc(n),4)},Ri=function(){var n=sc([_e(),bi(),_e(),_e()]);return x(Si(n),Si(n),Si(n),Si(n))},Mi=function(n){var t=new Uint32Array(4);return n[Di][Li](t),$r(t,function(n){return we(n,4)}).join(g).split(g)},Oi=function(n){return n[Di][Ci]().replace(/-/g,\ng)},Ii=function(n){var t;if(n[Di]){if(n[Di][Ei]&&n[Di][Ci])return Oi(n);n[Di][Li]&&(t=Mi(n))}return t=t||Ri().split(g),t[12]=\"4\",t[16]=me(3&parseInt(t[16],16)|8),t.join(g)},ki=function(n){return!!n&&(new RegExp(\"^[\".concat(Pi,\"]{8}[\").concat(Pi,\"]{4}[0-5][\").concat(Pi,\"]{3}[89ab][\").concat(Pi,\"]{3}[\").concat(Pi,\"]{12}$\"))).test(n)},Wi=vn(121),qi=vn(122),Vi=vn(123),zi=vn(124),Zi=vn(125),Bi=vn(126),Ni=vn(127),Ui=vn(128),Ai=vn(129),Gi=vn(130),Qi=vn(131),Ji=vn(132),Ki=vn(133),Yi=vn(134),$i=vn(135),no=\nvn(136),to=vn(137),ro=vn(138),uo=vn(139),eo=vn(140),co=vn(141),io=vn(142),oo=vn(143),fo=vn(144),ao=vn(145),_o=vn(146),vo=vn(147),so=vn(148),lo=vn(149),ho=vn(150),po=vn(151),yo=vn(152),mo=vn(153),wo=vn(154),go=vn(155),Ho=vn(156),xo=vn(157),bo=vn(158),Fo=vn(159),To=vn(160),jo=vn(161),Xo=vn(162),Po=vn(163),Lo=vn(164),Co=vn(165),Le=vn(166),Re=vn(167),Do=\"\".concat(Co,\" \").concat(Le,\".\"),Eo=\"\".concat(Re,\", \").concat(Le,\".\"),So=vn(168),Ro=vn(169),Mo=vn(170),Oo=vn(171),Io=vn(172),ko=vn(173),Wo=vn(174),qo=\nvn(175),Vo=function(n){return d(n)[Vi]},zo=function(n){return d(n)[zi]},Zo=function(n){return d(n)[Ni]},Bo=function(n){return d(n)[Zi]},No=function(n){return d(n)[Bi]},Uo=function(n){var t=d(n);return t[Ui]||t[Hu(\"user\",Ui)]||t[Hu(\"browser\",Ui)]||t[Hu(\"system\",Ui)]},Ao=function(n){var t=yr(n);return s(t[uo])?t[uo]:t[eo]},Go=function(n){return yr(n).width||0},Qo=function(n){return yr(n).height||0},Jo=function(n){return yr(n).availWidth||0},Ko=function(n){return yr(n).availHeight||0},Yo=function(n){return or(d(n)[Ai])},\n$o=function(n){return or(d(n)[qi])},nf=function(n){return d(n)[Gi]},tf=function(n){return $r(nf(n),function(n){return n&&n.type})},rf=function(n){return d(n).userAgentData},uf=function(n){return d(n)[to]},ef=function(n){return d(n)[ho]},cf=function(n){return $r(uf(n),function(n){return n.name+n.description+n.length+n.filename})},of=function(n){var t=d(n);if(Vr(t[Qi])&&t[Qi]())return!0},ff=function(n){return\"1\"===n||\"0\"!==n&&p},af=function(n){var t=d(n);return no in t?ff(t[no]):no in n?ff(n[no]):Hu(\"ms\",\nno)in t?ff(t[Hu(\"ms\",no)]):void 0},_f=function(n){return d(n)[Ji]},vf=function(n){return d(n)[Ki]},sf=function(n){return d(n)[Yi]},lf=function(n){return d(n)[hu(Kn)]},df=function(n){return d(n)[$i]},hf=function(n){return d(n)[ro]},pf=function(n){return d(n)[co]},yf=function(n){return pr(n)[io]},mf=function(n){return n[po]},wf=function(n){return n[yo]},gf=function(n){return d(n)[Ho]},Hf=function(n){return n[xo]},xf=function(n){return n[mo]},bf=function(){var n=Hi();return n.setTime(0),n.setMonth(n.getMonth()+\n2),n.toLocaleString()},Ff=function(n){try{return Intl.DateTimeFormat()[vo]()}catch(t){}},Tf=function(n){var t=Ff();if(t)return t[so]},jf=function(n){var t=Ff();if(t)return t[lo]},Xf=function(n){return d(n)[Ui+\"s\"]||[]},Pf=function(n){return Ar(Xf(n))},Lf=function(n){return ar(n,oo)},Cf=function(n){return ar(n,fo)},Df=function(n){return ar(n,_o)||ar(n,ao)},Ef=0,Sf=1,Rf=2,Mf=3,Of=4,If=5,kf=6,Wf=7,qf=8,Vf=9,zf=10,Zf=11,Bf=12,Nf=13,Uf=14,Re=vn(176),Le=\",\",Af=Re.split(Le),Gf=0,Qf=1,Jf=2,Kf=3,Yf=4,$f=5,\nna=6,Le=7,ta=[{v:Gf},{v:Gf},{v:Qf,l:!0},{v:Qf,l:!0},{v:Qf,l:!0},{v:Jf,l:!0},{v:Jf,l:!0},{v:Jf,l:!0},{h:!0,v:Qf},{h:!0,v:Jf},{v:Kf,p:!0},{v:Yf,p:!0},{v:$f,p:!0},{v:na,p:!0},{v:Le,p:!0}],ra=500,Re=1E3,ua=200,ea=1E3,ca=1E3,Le=13,ia=function(){Hc=eu(Af.length,function(n){return m})},oa=function(n){return Hc[n]++},fa=function(n){return Hc[n]},aa=function(){return fa(If)>m||fa(kf)>m||fa(Wf)>m},_a=function(n,t){3===n.g&&(n.H[2]=n.H[1]),n.H[1]=n.H[0],n.H[0]=t},va=function(n,t,r,u,e){return void 0===e&&(e=\n1),{F:n,T:r,j:u,X:t,H:Array(e),g:e,P:m}},sa=function(n,t){var r;n.T&&!n.T(n,t)||n.X&&Ur(n.X,t.L)<m||(_a(n,t),n.j&&!n.j(n))||(r=n.F,r&&!r.apply(p,n.H))||n.P++},la=function(n,t){return!n||!t},da=function(n,t,r){return!n||!t||!r},ha=function(n,t){return n.C-t.C===0},pa=function(n,t){if(0!==n||0!==t)return ce(Yu(n,2)+Yu(t,2))},ya=function(n,t){return se(n.C,t.C)},ma=function(n,t){var r,u;if(n.D!==p&&n.S!==p&&t.D!==p&&t.S!==p)return r=n.D-t.D,u=n.S-t.S,pa(r,u)},wa=function(n,t,r){if(!da(n,t,r)){var u=\nr.D-t.D,e=r.S-t.S,c=n.D-t.D,i=n.S-t.S,o=u*c+e*i,u=pa(u,e),e=pa(c,i);if(u&&e&&u>2&&e>2){c=fe(o/(u*e),10);if(s(c))return i=ie(c),180*i/re()}}},ga=function(n,t,r){var u,e,c,i,o;if(!da(n,t,r)&&n.D!==p&&n.S!==p&&n.R!==p&&t.D!==p&&t.S!==p&&t.R!==p)return o=r.D-t.D,u=r.S-t.S,e=n.D-t.D,c=n.S-t.S,i=se(o*c,e*u),o=pa(o-e,u-c),o?i/o:0},Ha=function(n,t){var r,u;if(!la(n,t)&&!ha(n,t)&&ma(n,t))return r=t.D-n.D,u=t.S-n.S,180*oe(u,r)/re()+180},xa=function(n,t){if(!la(n,t))return ma(n,t)},ba=function(n,t){if(!la(n,\nt)&&n.D!==p&&n.S!==p&&n.R!==p&&t.D!==p&&t.S!==p&&t.R!==p)return Ju(10*n.D)+Ju(10*n.S)+Ju(10*n.R)},Fa=function(n,t){if(!la(n,t))return ya(n,t)},Ta=function(n,t){return la(n,t)||n.M!==t.M?void 0:ya(n,t)},ja=function(n,t){return la(n,t)||n.M===t.M?void 0:ya(n,t)},Xa=function(n){return Ur(yn,n.M)>=m},Pa=function(n){return!1===n.O},La=function(n,t){return n!==t&&le(n)+le(t)===m},Ca=function(n,t){return!la(n,t)&&n.I!==p&&n.k!==p&&t.I!==p&&t.k!==p&&(La(n.I,t.I)||La(n.k,t.k))},Da=function(n,t){return!la(n,\nt)&&n.W!==p&&n.q!==p&&(n.W<=m||n.W>=n.q)},Ea=0,Sa=1,Ra=2,Ma=0,Oa=1,Ia=2,ka=3,Wa=4,qa=5,Va=function(){xc=eu(5,function(n){return p})},za=function(n,t){return xc[n]=t},Za=function(n){return xc[n]},Ba=function(n){return n.V===m||1==n.V&&n.L===kf},Na=function(n){var t;return!!n.Z||(t=Za(Ia),!t)||n.C-t.C>ra},Ua=function(n,t){return!!t.V&&t.V>1},Aa=function(n){return!!n.H[1]&&!!n.X&&n.H[0].L===n.X[1]&&n.H[1].L===n.X[0]},Ga=function(n){return!!n.H[1]&&n.H[1].L===kf&&n.H[0].L!=kf},Qa=function(n){return!!n.H[1]&&\nn.H[0].L===kf&&n.H[1].L!=kf},Ja=function(n){return!!n.H[1]&&n.H[1].B==Ea&&n.H[0].B==Sa},Ka=function(n){return!!n.H[1]&&n.H[1].B==Sa&&n.H[0].B==Ra},Ya=function(n){return!!n.H[1]&&n.H[1].B==Ra&&n.H[0].B==Ra},$a=function(n){return!!n.H[1]&&n.H[1].B==Ea&&n.H[0].B==Ea},n0=function(){bc=va(Xa,[Sf]),Tc=va(Ca),Fc=va(Da),Xc=va(p,[kf],Ua),jc=va(p),Pc=va(Pa),ia()},t0=.5,r0=function(n){var t=ve(n.length-2)+1;n.splice(t,1)},u0=function(n,t){var r;return n.length?(r=s(t)?t:t0,r=(n.length-1)*r,Wr(r)?n[r]:(r=~~r,\nr+1<=n.length?(n[r]+n[r+1])/2:n[r])):p},e0=function(n,t){n.push(t);var r=n.length-1,u=n[r];while(r>0&&u<n[r-1])n[r]=n[r-1],--r;n[r]=u},c0=function(n){return{N:[],U:s(n)?n:ua}},i0=function(n){if(n.N.length<2)return p;var t=o0(n,t0);if(t==p)return p;for(var r=[],u=0,e=n.N;u<e.length;u++){var c=e[u];e0(r,se(c,t))}return u0(r,t0)},o0=function(n,t){return u0(n.N,t)},f0=function(n,t){var r=n.N;r.length>=n.U&&r0(r),e0(r,t)},a0=function(n,t){var r={A:p,G:c0(t),P:m,J:m,K:m,Y:w,$:w};return n&&(r.nn=c0(t)),\nr},_0=function(n,t){var r,u;n.P++,n.J+=t,f0(n.G,t),s(n.A)?(r=se(t,n.A),n.K+=r,n.nn&&(u=n.A+t,f0(n.nn,u==m?m:r/n.A+t)),t>n.$&&(n.$=t),t<n.Y&&(n.Y=t)):n.Y=n.$=t,n.A=t},t=function(n,t,r,u,e,c,i,o){return void 0===c&&(c=2),{F:n,T:u,j:e,X:r,H:Array(c),tn:t,rn:0,g:c,un:a0(i,o)}},a=function(n,t){var r;n.X&&Ur(n.X,t.L)<m||n.T&&!n.T(t)||(n.tn&&!n.rn&&(n.rn=1),_a(n,t),n.j&&!n.j(n))||(n.tn&&n.tn.apply(p,n.H)?(n.rn++,void 0):(r=n.F.apply(p,n.H),kr(r)&&_0(n.un,r)))},v0=function(n){n.H=Array(n.g),n.un=a0(!!n.un.nn,\nn.un.G.U),n.rn=0},s0=function(r){return function(n,t){if(n&&t)return n.C-t.C>r}},l0=function(n,t){var r;if(n&&t)return Ur(mn,n.M)>=m||Ur(mn,t.M)>m||(r=Za(Oa),!!(r&&r.C>t.C))||void 0},d0=s0(ra),h0=s0(Re),p0=l0,y0=function(){Lc=t(Fa,d0),Cc=t(Ha,d0),Ec=t(Fa,d0),Sc=t(Ha,d0),Rc=t(xa,d0),Dc=t(xa,d0,p,p,p,2,!0,ea),ti=a0(!1,ea),ri=a0(!1,ea),ui=a0(!1,ea),ei=a0(!1,ea),ci=a0(!1,ea),ii=a0(!1,ea),oi=a0(!1,ea),fi=t(xa,p,p,p,p,2,!0,ea),ai=t(Fa,p,p,p,p,2,!0,ea),Mc=t(Fa,p,[Of,Mf],p,Aa),Oc=t(ja,h0,[Sf,Ef],p,Aa),Ic=\nt(Ta,h0,[Sf,Ef],p,Aa),qc=t(Fa,p0,[Sf]),Vc=t(Fa,p0,[Ef]),kc=t(Fa,p0,[Sf,Ef],p,Aa),Wc=t(Fa,p0,[Ef,Sf],p,Aa),Gc=t(Fa,p,[kf,If,Wf],Ba,Qa),Qc=t(Fa,p,[kf,If,Wf],Ba,Ga),zc=t(ba),Zc=t(Fa,p,[Rf]),Nc=t(wa,p,p,p,p,3,!1,ea),Uc=t(wa,d0,p,p,p,3,!1,ea),Ac=t(ga,p,p,p,p,3,!1,ea),Bc=t(Fa,p,[Rf,Sf],p,Aa),Jc=t(ja,p,[Sf],p,$a),Kc=t(ja,p,[Sf],p,Ja),Yc=t(ja,p,[Sf],p,Ka),$c=t(ja,p,[Sf],p,Ya),ni=t(Fa,p,p,p,p,2,!0,ca)},m0=function(n){return n.P>1?fe(ae(n.K,n.P-1)):p},w0=function(n){return fe(ae(n.J,n.P))},g0=function(n){return fe(o0(n.G))},\nH0=function(n){return n.nn&&fe(o0(n.nn))},x0=function(n){return fe(i0(n.G))},b0=function(n){return n.nn&&fe(i0(n.nn))},F0=function(n){return fe(n.$)},T0=function(n){return fe(n.Y)},j0=function(n){return fe(n.J)},X0={en:m,cn:!1},P0=function(n){X0.en=Xr(n),X0.on=jr(n)},L0=function(n){var t,r,u;Na(n)&&(a(Ac,n),r=x0(fi.un),kr(r)&&_0(ti,r),t=g0(fi.un),kr(t)&&_0(ri,t),u=b0(fi.un),kr(u)&&_0(ui,r),u=H0(fi.un),kr(u)&&_0(ei,t),r=j0(fi.un),kr(r)&&_0(ci,r),u=j0(ai.un),kr(u)&&_0(ii,u),kr(r)&&kr(u)&&u>0&&_0(oi,\nr/u),v0(fi),v0(ai))},C0=function(n,t,r,u){var e=t.L;if(kr(e)){var c,i=r[e],o=Za(ka);switch(a(ni,t),sa(Pc,t),i.v){case Gf:s(t.M)?(a(Oc,t),a(Ic,t),a(Bc,t),a(kc,t),a(qc,t),a(Vc,t),a(Wc,t),a(Jc,t),a(Kc,t),a(Yc,t),a($c,t),sa(bc,t)):sa(jc,t);break;case Kf:a(zc,t);break;case na:f(Xr(n)).i(function(n){n<.7*X0.en&&za(qa,t),X0.en=n}).o();break;case Yf:sa(Tc,t);break;case $f:sa(Fc,t);break;case Jf:i.h?(a(Ec,t),a(Sc,t),a(Rc,t)):(a(Gc,t),a(Qc,t),sa(Xc,t));break;case Qf:i.h&&(a(Lc,t),a(Cc,t),a(Dc,t),a(Nc,t),a(Uc,\nt),L0(t),a(fi,t),a(ai,t)),r[e].l&&(a(Mc,t),a(Zc,t),a(Bc,t))}u&&u.rEv(t),i.v!=Gf&&za(Oa,t),o&&kr(o.L)&&o.Z&&(c=r[o.L],c.v==Qf)&&c.h&&L0(o),i.v==Qf&&i.h&&(za(Ia,t),Za(Ma)||(za(Ma,t),a(Ac,t))),i.h&&t.O&&(Za(Wa)||za(Wa,t)),za(ka,t)}},D0=/[a-zA-Z]/,E0=/\\d/,S0=function(n){return!s(n)||n.length>1?Ra:D0.test(n)?Ea:E0.test(n)?Sa:Ra},R0=vn(177),M0=vn(178),O0=function(n){return Ur(Af,n&&n.type)},I0=function(n,t){var r,u;t&&(r=t.clientX,u=t.clientY),n.D=s(r)?r:p,n.S=s(r)?u:p},k0=function(n,t){var r,u,e,c;t&&\n(r=t.pageX,u=t.pageY,e=t.screenX,c=t.screenY),n.fn=s(r)?r:p,n.an=s(u)?u:p,n._n=s(e)?e:p,n.vn=s(c)?c:p},W0=function(t,n,r,u){var e=O0(n),c={L:e,C:r,O:n.isTrusted};switch(ta[e].v){case Qf:I0(c,n),k0(c,n),c.M=n.button;break;case Gf:c.sn=s(n.keyCode)?n.keyCode:n.which,c.ln=n.code,c.M=s(c.ln)?c.ln:s(c.sn)?c.sn+g:p,c.dn=s(n.key)?n.key:s(c.sn)?String.fromCharCode(c.sn):p,c.B=S0(c.dn);break;case $f:c.W=t.scrollY,f(wr(t)).u(function(n){return s(n)?n.scrollHeight-xr(t):p}).i(function(n){return c.q=n}).o();\nbreak;case Yf:c.I=n.deltaX,c.k=n.deltaY;break;case Jf:var i=n[R0];s(i)&&(o=i[0],I0(c,o),k0(c,o),c.V=i.length);break;case Kf:var o=n[M0];o?(c.D=o.alpha,c.S=o.beta,c.R=o.gamma):c.D=c.S=c.R=p}u&&u.pEv(c,n);e=Za(ka);return e&&e.L!=c.L&&(e.Z=!0),c},q0=function(t){if(typeof ResizeObserver!=typeof w)try{var n=new ResizeObserver(function(n){jr(t)!=X0.on&&(X0.on=jr(t),X0.cn=!0)});n.observe(wr(t))}catch(sn){}},V0=function(n,t,r){return r[t].p?n:pr(n)},z0=function(n,t,r,u,e){var c=Z0(n,t,u,e);c.L>=m&&oa(c.L)},\nZ0=function(n,t,r,u){var e=W0(n,t,bi(),u);return C0(n,e,r,u),e},Re=vn(179),s0=vn(180),l0=vn(181),B0=vn(182),N0=[Re,s0,l0],U0=!1,A0=function(n,t,r,u,e){t.query({name:n}).then(function(n){var t=n.state;U0||t===B0&&(U0=!0,Je(r,u,e))})[\"catch\"](Kt)},G0=function(n,t,r,u){for(var e=lf(n),c=r.length-1;c>=0;c--){var i=V0(n,c,u);if(c===zf&&e&&e.query)for(var o=N0.length-1;o>=0;o--)A0(N0[o],e,i,r[c],t);else Je(i,r[c],t)}},Q0=function(t,r,u,e){_i=function(n){return z0(t,n,r,u,e)},P0(t),q0(t),G0(t,_i,r,u)},J0=\n10,K0=function(){var n;return fa(zf)>J0&&(null!==(n=m0(zc.un))&&void 0!==n?n:m)>J0},Y0=function(){var n=Za(Wa);return!!n&&n.D===m&&n.S===m},$0=function(){var n=Za(Wa);return!!(n&&kr(n.fn)&&kr(n.an))&&n.fn===n._n&&n.an===n.vn},n1=function(n){return[Oc.un.P>m,aa(),fa(Rf)>m,jc.P>m,K0(),bc.P>m,Xc.P>m,Y0(),$0(),fa(Bf)>m,fa(Uf)>m,fa(Zf)>m,fa(Nf)>m,X0.cn,!!Za(qa)]},t1=function(){var n=aa(),n=n?Lc:Ec,t=g0(Jc.un),r=x0(Jc.un);return[m0(Cc.un),m0(Sc.un),w0(Ic.un),w0(Vc.un),w0(Mc.un),m0(n.un),g0(Zc.un),x0(Zc.un),\ng0(Mc.un),x0(Mc.un),g0(Bc.un),x0(Bc.un),g0(qc.un),x0(qc.un),g0(Vc.un),x0(Vc.un),g0(kc.un),x0(kc.un),g0(Wc.un),x0(Wc.un),g0(Nc.un),x0(Nc.un),g0(Uc.un),x0(Uc.un),g0(Ac.un),x0(Ac.un),T0(Ac.un),F0(Ac.un),g0(Qc.un),x0(Qc.un),g0(Gc.un),x0(Gc.un),se(g0(Kc.un),t),se(x0(Kc.un),r),se(g0(Yc.un),t),se(x0(Yc.un),r),se(g0($c.un),t),se(x0($c.un),r),g0(ri),x0(ti),g0(ei),x0(ui),H0(Dc.un),b0(Dc.un),g0(ii),x0(ii),g0(ci),x0(ci),g0(oi),x0(oi),j0(Dc.un),g0(ni.un),x0(ni.un)]},Re=8,r1=Re-1,s0=Le,u1=Yu(2,r1),e1=Yu(2,Re)-\n1,l0=s0-r1,Le=e1-u1,c1=Le/l0,i1=function(n){return n<u1?n:$u(e1,~~((ue(n)*ee()-r1)*c1+u1))},o1=function(){return[i1(fa(qf)),i1(fa(Ef)),i1(fa(Rf)),i1(fa(kf)),i1(fa(Sf)),i1(fa(Vf)),i1(se(fa(Of),fa(Mf))),i1(ci.P>1?ci.P-1:m),i1(Tc.P),i1(Pc.P),i1(Fc.P)]},f1=4866,a1=0,_1=\"X-Castle-Request-Token\",v1=\"castle_request_token\",s1=\"__cid\",Re=\"__cuid\",l1=\"__ctst\",d1=Array(1024).join(\"x\"),s0=vn(183),h1=s0+\"missing or wrong publishableKey\",p1=s0+\"missing user or event data\",y1=s0+\"missing configuration\",Le=3456E4,\nm1=(Pe(1970),500),w1=100,g1=b(12),H1=6,l0=vn(184),x1={hn:!1,pn:!0,yn:l0,mn:1E3,wn:{gn:Re,Hn:Le},xn:!0},b1=function(t){return f(W1().bn.slice(3)).u(function(n){return t?pe(n):n}).o()},F1=function(n){n&&(x1.wn.gn=n)},T1=function(n){x1.Fn=n},j1=function(n){x1.Tn=n},X1=function(n){x1.jn=n},P1=function(n){n&&(n.name&&(x1.wn.gn=n.name),Wr(n.expireIn))&&(x1.wn.Hn=n.expireIn)},L1=function(n){x1.pn=n},C1=function(n){x1.hn=n},D1=function(n){n&&(x1.yn=n)},E1=function(n){kr(n)&&(x1.mn=n)},S1=function(n){s(n)&&\n(x1.xn=n)},R1=function(n){s(n)&&(x1.Xn=n)},M1=function(n){s(n)&&(x1.Pn=n)},O1=function(n){x1.Ln=n},I1=function(n){s(n)&&(x1.Cn=n)},k1=function(n){s(n)&&(x1.Dn=n)},W1=function(){return x1},q1=function(n){if(!er(n)||35!==n.length||\"pk_\"!==n.slice(0,3))throw h1;x1.bn=n},V1=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\",z1=function(n,t){if(n.btoa)return n.btoa(t);for(var r=V1,u=\"\",e=0,c=void 0,i=0,o=r;t.charAt(0|i)||(o=\"=\",i%1);u+=o.charAt(63&e>>8-i%1*8)){if(c=t.charCodeAt(i+=3/4),\nc>255)return null;e=e<<8|c}return u},Z1=function(n,t){var r=z1(n,t);return null==r?null:r.replace(/\\+/g,\"-\").replace(/\\//g,\"_\").replace(/=+$/,\"\")},B1=function(n,t){var r,u=3&n.length,e=n.length-u,c=t,i=3432918353,o=461845907,f=0,a=0;while(f<e)a=255&n.charCodeAt(f)|(255&n.charCodeAt(++f))<<8|(255&n.charCodeAt(++f))<<16|(255&n.charCodeAt(++f))<<24,++f,a=(65535&a)*i+(((a>>>16)*i&65535)<<16)&4294967295,a=a<<15|a>>>17,a=(65535&a)*o+(((a>>>16)*o&65535)<<16)&4294967295,c^=a,c=c<<13|c>>>19,r=5*(65535&c)+\n((5*(c>>>16)&65535)<<16)&4294967295,c=(65535&r)+27492+(((r>>>16)+58964&65535)<<16);switch(a=0,u){case 3:a^=(255&n.charCodeAt(f+2))<<16;case 2:a^=(255&n.charCodeAt(f+1))<<8;case 1:a^=255&n.charCodeAt(f),a=(65535&a)*i+(((a>>>16)*i&65535)<<16)&4294967295,a=a<<15|a>>>17,a=(65535&a)*o+(((a>>>16)*o&65535)<<16)&4294967295,c^=a}return c^=n.length,c^=c>>>16,c=2246822507*(65535&c)+((2246822507*(c>>>16)&65535)<<16)&4294967295,c^=c>>>13,c=3266489909*(65535&c)+((3266489909*(c>>>16)&65535)<<16)&4294967295,c^=c>>>\n16,c>>>0},N1=function(n){for(var t=$r(n,function(n){return fr(n)}),r=\"\",u=24,e=0;e<t.length;e+=u){var c=t.slice(e,e+u),i=be(c,w),c=c.length===u?3:Qu(c.length/8);r+=we(i,c)}return x(b(n.length),r)},U1=vn(185),A1=function(n){return d(n)[U1]},G1=vn(186),s0=vn(187),Pe=vn(188),Q1=G1+\"s\",J1=new RegExp(s0),K1=function(n){var t=$r(n[Q1]||[],function(n){return n[G1]}),t=Qr(t,function(n){return!/Not/.test(n)});if(t.length)return Ar(t.length>1?Qr(t,function(n){return!J1.test(n)}):t)},Y1=[s0,\"\".concat(Co,\" \").concat(gu(oo)),\ngu(ao),gu(fo),Pe],$1=vn(189),n_=function(n){return n[$1]?n[$1].toString().length:0},t_=function(){try{var n=[].constructor;try{return(-1).toFixed(-1),0}catch(t){return yu(t.message)+yu((n+g).split(n.name).join(g))}}catch(t){return null}},r_=function(){return cr(vi)&&(vi=t_()),vi},u_=80,e_=58,c_=77,i_=39,o_=function(){return r_()===u_},f_=function(){return r_()===e_},a_=function(){return r_()===c_},__=function(n){return n_(n)===i_},v_=vn(190),s_=vn(191),l_=vn(192),d_=vn(193),h_=vn(194),p_=vn(195),\ny_=vn(196),m_=vn(197),w_=vn(198),g_=vn(199),H_=vn(200),x_=vn(201),b_=256,F_=vn(202),T_=2*re(),j_=[[\"#f0f\",50,50],[\"#0ff\",100,50],[\"#f70\",75,100]],X_=function(n){return Er(n,s_)},P_=function(n,t,r){return new n[F_](t,r)},L_=function(n){var t;try{F_ in n&&(t=P_(n,b_,b_))}catch(sn){}finally{t=t||X_(n)}return t},C_=function(n){return!(!n||!n.getContext)},D_=function(n){return C_(n)&&!!(\"toDataURL\"in n)},E_=function(n){try{return n.getContext(w_+m_)}catch(sn){}},S_=function(n){var t,r=L_(n);if(C_(r))return r=\nr.getContext(m_)||E_(r),f_()?r.getParameter(r.RENDERER):(t=r&&r.getExtension(g_),t?r.getParameter(t.UNMASKED_RENDERER_WEBGL):void 0)},R_=function(n){var t=n.toDataURL();if(t)return B1(t).toString(16)},_=function(n,t){n.fillStyle=t},M_=function(n,t,r,u,e){n.fillRect(t,r,u,e)},O_=function(n,t,r,u){n.fillText(t,r,u)},I_=function(n,t){n.font=t},k_=function(n,t,r){n.width=t,n.height=r},W_=function(n){n.beginPath()},q_=function(n){n.closePath()},V_=function(n,t,r,u,e){n.arc(75,75,75,0,T_,!0)},z_=function(n,\nt){t?n.fill(t):n.fill()},Z_=function(n,t,r,u){void 0===u&&(u={});var e=n.getContext(y_,u);return k_(n,t,r),e},B_=function(n,t){k_(n,500,100);var r=v_+String.fromCharCode(55357,56836);return t.textBaseline=H_,_(t,\"#f60\"),M_(t,125,1,62,20),_(t,\"#069\"),I_(t,l_),O_(t,r,2,20),_(t,h_),I_(t,d_),O_(t,r,4,22),R_(n)},N_=function(n,t){k_(n,400,200),t.globalCompositeOperation=x_;for(var r=0,u=j_;r<u.length;r++){var e=u[r],c=e[0];e[1],e[2],_(t,c),W_(t),V_(t),q_(t),z_(t,w)}return _(t,\"#70f\"),V_(t),V_(t),z_(t,p_),\nR_(n)},U_=function(n){var t=X_(n),r=D_(t)?t.getContext(y_):w;if(r)return{En:B_(t,r),Sn:N_(t,r)}},A_=8,G_=255,Q_={willReadFrequently:!0,desynchronized:!0},J_=function(){return ve(Qt+1)},K_=function(n,t){n.clearRect(0,0,t,t)},Y_=function(n){for(var t=[],r=0;r<A_;r++)for(var u=0;u<A_;u++){var e=\"\".concat(J_(),\", \").concat(J_(),\", \").concat(J_(),\", \").concat(G_);_(n,\"rgba(\".concat(e,\")\")),M_(n,r,u,1,1),t.push(e)}return t},$_=function(n){for(var t=[],r=0;r<A_;r++)for(var u=0;u<A_;u++){var e=(n.getImageData(r,\nu,1,1)||{}).data,c=e[0],i=e[1],o=e[2],e=e[3],c=\"\".concat(c,\", \").concat(i,\", \").concat(o,\", \").concat(e);t.push(c)}return t},nv=function(n){var t=L_(n);if(C_(t)){t=Z_(t,A_,A_,Q_);if(t){var r=Y_(t),u=$_(t);K_(t,A_);for(var e=0;e<r.length;e++)if(r[e]!=u[e])return!0}}return!1},tv=vn(203),rv=vn(204),uv=function(n){var t=yr(n);return s(t[tv])&&s(t[rv])&&t[tv]>t[rv]?ae(t[tv],t[rv]):s(jr(n))?jr(n):1},ev=\"hasAttribute\",cv=\"attributes\",iv=function(n,t){return n[ev]?n[ev](t):!(!n[cv][t]||!n[cv][t].specified)},\nov=[O,Ht,n],fv=function(n){return Ur(n,!0)>-1},av=function(n){return!!n[\"__\".concat(wt)]},_v=function(n){return fv([ov[0]in n,ov[1]in n,ov[2]in n])},vv=function(n){return d(n)[mt]},sv=function(n){var t,r=new RegExp(Et);for(t in n)if(r.test(t))return!0},lv=function(n){var t=pr(n),r=wr(n);return!(!sv(n)&&!sv(t))||fv([mt in n,\"_\".concat(jt)in n,ct in n,\"_\".concat(Tt)in n,\"__\".concat(mt,\"_\").concat(bt)in t,\"__\".concat(lt,\"_\").concat(ht)in t,\"__\".concat(mt,\"_\").concat(ht)in t,\"__\".concat(Tt,\"_\").concat(ht)in\nt,\"__fx\".concat(lt,\"_\").concat(ht)in t,\"__\".concat(lt,\"_\").concat(Ct)in t,\"__\".concat(mt,\"_\").concat(Ct)in t,\"__\".concat(Tt,\"_\").concat(Ct)in t,\"__fx\".concat(lt,\"_\").concat(Ct)in t,\"__\".concat(mt,\"_\").concat(bt)in t,\"__\".concat(mt,\"_\").concat(Ft)in t,iv(r,Tt),iv(r,mt),iv(r,lt)])},dv=function(n){return!!n.external&&Vr(n.external.toString)&&Cu(n.external.toString(),Xt)},hv=function(n){return!(!n[vt]&&!n[\"\".concat(vt,\"Controller\")])},pv=function(n){return!!n.spawn},yv=function(n){return!!n.emit},mv=\nfunction(n){return!!n.Buffer},wv=function(n){var t=new RegExp(yt);return t.test(Bo(n))||t.test(No(n))},gv=vn(205),Hv=vn(206),xv=vn(207),bv=function(n){var t,r=d(n),u=pr(n),e=0;s(r[gv])?e=r[gv]:(c=r[\"ms\".concat(gv)],s(r[c])&&(e=r[c]));try{u.createEvent(Hv),t=!0}catch(i){t=!1}var c=\"on\".concat(xv)in n;return{Rn:e,Mn:t,On:c}},Fv=Ln+Wn,Tv=Pn+Wn,jv=0,Xv=1,Pv=2,Lv=vn(208),Cv=vn(209),Dv=vn(210),Ev=function(n,t,r){return Vr(n.matchMedia)&&r!=n.matchMedia(t).matches},Sv=function(n,e){var t=d(n),c=[];try{var r,\nu=Bo(n),i=Cu(u,Dv)||f_(),o=i&&Cu(u,Wo),f=t[Cv];f&&f[Lv]&&!o?(r=function(n){var t=f[Lv]();t&&t.then?t.then(n,function(){return e(c)}):e(c)},c=[!1,!1,!1],r(function(n){if(n)for(var t=0,r=n;t<r.length;t++){var u=r[t],u=u.kind;u!==Tv&&u!==Pn||(c[jv]=!0),u===Tv&&(c[Xv]=!0),u!==Fv&&u!==Ln||(c[Pv]=!0)}e(c)})):e(c)}catch(a){e(c)}},Rv=vn(211),Mv=function(){return Hi()[Rv]()},Ov=vn(212),Iv=function(){var n=Hi(),t=(n.setDate(1),n.setMonth(0),n[Rv]());return n.setMonth(6),se(t,n[Rv]())},kv=function(n){return f(xf(n)).u(function(n){if(n&&\nn[Ov])return f(n[Ov]+n.now()).u(function(n){return Gu(n)}).u(function(n){return Qu(Ju(n-bi())/1E3)}).o()}).o()},Wv=function(n){var t=[];if(!lr())return t;var r=d(n),u=r;do{for(var e=0,c=_r(u);e<c.length;e++){var i=c[e];t.push(i)}u=vr(u)}while(u);for(var o,f=[],a=0,_=t;a<_.length;a++){var i=_[a],v=sr(vr(r),i);s(v)?ir(v.value)?o=v.value.toString():ir(v.get)&&(o=v.get.toString()):o=g,f.push(\"\".concat(i,\"~~~\").concat(o))}return f},qv=vn(213),Vv=vn(214),zv=vn(215),Zv=function(n,t){switch(n[zv](t.replace(\"'\",\n'\"'))){case qv:return 2;case Vv:return 1;case g:return 0;default:return 3}},Bv=function(n,t){return Zv(n,\"\".concat(Pn,\"/\").concat(t))},Nv=function(n,t){return Zv(n,\"\".concat(Ln,\"/\").concat(t))},l0=vn(216),Re=vn(217),Le=vn(218),s0=vn(219),Uv=\"\".concat(l0,\"; \").concat(s0,'=\"').concat(Le,'\"'),Av=vn(220),Gv=\"\".concat(Re,\"; \").concat(s0,\"=1\"),Qv=vn(221),Jv=vn(222),Kv=function(n){var t=Er(n,Pn);return[Bv(t,Jv),Bv(t,Qv),Bv(t,Gv),Bv(t,Av),Bv(t,Uv)]},Pe=vn(223),O=vn(224),Ht=vn(225),n=vn(226),Le=vn(227),Yv=\n\"\".concat(l0,\"; \").concat(s0,'=\"').concat(Pe,'\"'),$v=\"\".concat(n,\"; \").concat(s0,'=\"').concat(O,'\"'),n2=\"\".concat(Le,\"; \").concat(s0,'=\"').concat(Ht,'\"'),t2=function(n){var t=Er(n,Ln);return[Nv(t,n2),Nv(t,$v),Nv(t,Yv)]},r2=function(n){try{return t2(n).concat(Kv(n))}catch(sn){return[]}},u2=function(n){var t=W1();t.Fn&&t.Fn(n)},v=function(n){try{return n()}catch(t){u2(t)}},e2=function(){si++,e2()},c2=function(){si=0;try{e2()}catch(n){return{In:si,kn:n.message,Wn:n.name,qn:n.stack?n.stack.toString().length:\nm}}return{In:m,kn:g,Wn:g,qn:m}},i2=function(){var n;try{return n.b,\"\"}catch(t){return t.message}},o2=function(){try{throw\"\";}catch(n){try{return n.toSource(),!0}catch(t){}}return!1},f2=vn(228),a2=\"\".concat(f2,\".\"),_2=vn(229),v2=vn(230),s2=vn(231),l2=vn(232),d2=vn(233),h2=vn(234),p2=\"Internal\".concat(h2),y2=\"Range\".concat(h2),m2=1,w2=2,g2=3,H2=4,h=5,x2=6,F=7,b2=function(n,t){return b((31&n)<<3|7&t)},F2=function(t,r,u,e){return f(b2(t,r)).u(function(n){switch(r){case x2:return x(n,b(Gu(10*u)));case g2:return x(n,\nb(u));case h:return x(n,u<=127?b(u):we(1<<15|32767&u,2));case H2:return x(n,wi(u,[t].concat(e)));case F:return x(n,u);default:return n}}).o()},T2=0,j2=1,X2=2,P2=3,L2=4,C2=5,D2=6,E2=7,S2=8,R2=9,M2=10,O2=11,I2=12,k2=13,W2=14,q2=15,V2=16,z2=17,Z2=18,B2=19,N2=20,U2=21,A2=22,G2=23,Q2=24,J2=25,K2=26,Y2=27,$2=28,ns=29,ts=30,rs=31,us=0,es=1,cs=2,is=5,os=6,fs=10,as=11,_s=12,vs=13,ss=14,ls=15,ds=16,hs=17,ps=18,ys=19,ms=20,ws=21,gs=22,Hs=23,xs=24,bs=25,Fs=26,Ts=27,js=28,Xs=29,Ps=30,Ls=0,Cs=1,Ds=2,Es=3,Ss=4,\nRs=5,Ms=6,Os=7,Is=8,ks=9,Ws=10,qs=11,Vs=12,zs=13,Zs=14,Bs=15,Ns=16,Us=17,As=18,Gs=19,Qs=20,Js=21,Ks=22,Ys=23,$s=24,n4=25,t4=26,r4=27,u4=28,e4=29,c4=30,i4=0,o4=1,f4=2,a4=3,_4=4,v4=5,s4=6,l4=7,d4=8,h4=9,p4=10,y4=11,m4=12,w4=13,g4=14,H4=15,x4=16,b4=17,F4={xn:!1,hn:!1,Vn:!1,zn:!1},T4=function(n){var t=W1();F4.xn=t.xn,F4.hn=t.hn,j4(n)},j4=function(n){F4.Vn=!!n[nc];var t=function(){F4.Vn&&(F4.zn=!0)};tc(n,l1,d1,t),uc(n,l1)},X4=function(){return F4},P4=vn(235),L4=function(n,t,r){try{var u;n?P4 in n?(u=n[P4](t),\nu.then(function(n){return r(n)},function(){return r(null)})):r(null):(r(null),void 0)}catch(sn){r(null)}},C4=vn(236),D4=vn(237),E4=vn(238),S4=vn(239),R4=vn(240),M4=vn(241),O4=vn(242),I4=On,k4=vn(243),W4=vn(244),q4=vn(245),V4=vn(246),z4=vn(247),Z4=vn(248),B4=vn(249),N4=vn(250),U4=vn(251),A4=vn(252),G4=vn(253),Q4=vn(254),J4=vn(255),K4=vn(256),Y4=vn(257),$4=vn(258),n5=vn(259),t5=vn(260),r5=vn(261),Re=function(n){return n},u5=xu(Yn,On),e5=xu(Kn,M),c5=xu(\"CSSStyleDeclaration\",Re(vn(424))),i5=vn(262),o5=\n!1,f5=!1,a5=function(n){return new Proxy(n,{})},_5={},v5=xu(B4,U4),s5=function(n){return!(new RegExp(v5)).test(n)},l5=function(n){return!(new RegExp(I4)).test(n)},d5=vn(263),h5=vn(264),p5=vn(265),y5=function(n,t){if(n[d5])try{var r=n[d5][\"version\"],u=r?n[d5][r].defaultCurrentScope:n[d5].hub;if(u)return Kr(u.getClient(),t)}catch(e){}},m5=function(n){return s(n[h5])},w5=function(n,t){var r=qr(t)?t:[t];if(o5){if(n==u5)return[];r=Qr(r,function(n){return l5(n)})}return f5&&n==c5?[]:r},g5=function(n){return n?\nQr(n,function(n){return s5(n)}).length:m},T=function(n){return\"failed \"+n},H5=function(n){e(function(){var n=z5(A5()).Zn;_5=function(){var u=n.Bn();return uu(ru(u),function(n,t,r){return n[t]=g5(u[t]),n},{})}()})},l0=function(){var u={};return{Nn:function(){return u},Un:function(n,t){var r=qr(t)?t:[t];if(u[n])return u[n]=cu(u[n],r);u[n]=r}}},x5=l0(),b5=x5.Un,F5=Ri(),T5=function(n){return dr(n)==Xn},j5=function(n){var t=n.An,r=n.Gn,u=n.Qn;try{throw li=t(),Error();}catch(e){return!T5(e)||!!r&&r(e)}finally{u&&\nu()}},X5=function(n){try{return li=n(),!1}catch(t){return!0}},P5=function(n){var t={};return t[\"\".concat(hu(Yn),\" \").concat(n,\"() { \").concat(Dn,\" }\")]=!0,t[\"\".concat(hu(Yn),\" get \").concat(n,\"() { \").concat(Dn,\" }\")]=!0,t[\"\".concat(hu(Yn),\" () { \").concat(Dn,\" }\")]=!0,t[\"\".concat(hu(Yn),\" \").concat(n,\"() {\").concat(\"\\n\",\"    \").concat(Dn).concat(\"\\n\",\"}\")]=!0,t[\"\".concat(hu(Yn),\" get \").concat(n,\"() {\").concat(\"\\n\",\"    \").concat(Dn).concat(\"\\n\",\"}\")]=!0,t[\"\".concat(hu(Yn),\" () {\").concat(\"\\n\",\"    \").concat(Dn).concat(\"\\n\",\n\"}\")]=!0,t},L5=function(n,t,r){return void 0===r&&(r=1),0===r?t.test(n.message):t.test(n.stack.split(\"\\n\")[1])},Pe=\"at \".concat(Yn,\"\\\\.\").concat(On,\" \"),C5=new RegExp(Pe),n=\"at Object\\\\.\".concat(On),D5=new RegExp(n),O=vn(266),Le=\"at (\".concat(Yn,\"\\\\.)?\\\\[\").concat(O,\"\\\\]\"),E5=new RegExp(Le),s0=vn(267),Ht=\"at (\".concat(s0,\"\\\\.)?\\\\[\").concat(O,\"\\\\]\"),S5=new RegExp(Ht),M=vn(268),R5=new RegExp(M),M5=/\\s(.+)\\]/,O5=/get\\s/,I5=/^(screen|navigator)$/i,k5=vn(269),W5=vn(270),q5=function(n,apFn,t,r,u){var e,\nc,i,o,f,a,_,v,s=n.self,l=En in s,d=o_(),h=f_();return Vr(apFn)?(c=apFn.name.replace(O5,g),v=null===r||void 0===r?void 0:r.name,i=vr(apFn),e={},e[T(C4)]=!!r&&j5({An:function(){return r.prototype[c]}}),e[T(D4)]=!!r&&I5.test(v)&&!!(sr(s[hu(v)],c)||l&&s[En][Nn](s[hu(v)],c)),e[T(E4)]=j5({An:function(){li=new apFn;var n=apFn.call(t);Zr(n)&&Vr(n.then)&&n[\"catch\"](function(n){})}}),e[T(S4)]=j5({An:function(){li=new apFn;var n=apFn.apply(t);Zr(n)&&Vr(n.then)&&n[\"catch\"](function(n){})}}),e[T(R4)]=j5({An:function(){return new apFn}}),\ne[T(O4)]=j5({An:function(){return y[Bn](apFn,p).toString()},Qn:function(){return y[Bn](apFn,i)}}),e[T(I4)]=!P5(c)[n[Yn][Sn].toString.call(apFn)]||!P5(On)[n[Yn][Sn].toString.call(apFn.toString)],e[T(k4)]=Sn in apFn,e[T(W4)]=!!(sr(apFn,Rn)||n[En][Nn](apFn,Rn)||sr(apFn,Mn)||n[En][Nn](apFn,Mn)||sr(apFn,Sn)||n[En][Nn](apFn,Sn)||sr(apFn,On)||n[En][Nn](apFn,On)),e[T(q4)]=!!(H(apFn,Rn)||H(apFn,Mn)||H(apFn,Sn)||H(apFn,On)),e[T(V4)]=ru(y[An](apFn)).sort().toString()!=W5,e[T(z4)]=_r(apFn).sort().toString()!=\nW5,e[T(Z4)]=l&&s[En].ownKeys(apFn).sort().toString()!=W5,e[T(B4)]=j5({An:function(){return y.create(apFn).toString()},Gn:function(n){return d&&!L5(n,C5)}})||j5({An:function(){return y.create(a5(apFn)).toString()},Gn:function(n){return d&&!L5(n,D5)}}),e[T(N4)]=j5({An:function(){li=apFn.arguments,li=apFn.caller},Gn:function(n){return h&&!L5(n,R5,0)}}),e[T(U4)]=j5({An:function(){li=apFn.toString.arguments,li=apFn.toString.caller},Gn:function(n){return h&&!L5(n,R5,0)}}),e[T(A4)]=j5({An:function(){return y[Bn](apFn,\ny.create(apFn)).toString()},Qn:function(){return y[Bn](apFn,i)}}),_=e,v=c==On||!!u[u5]||!!u[e5],v&&(o=a5(apFn),f=a5(apFn),a=a5(apFn),_=hr(_,(e={},e[T(G4)]=!j5({An:function(){apFn.__proto__=proxy,apFn++},Qn:function(){return y[Bn](apFn,i)}}),e[T(Q4)]=!j5({An:function(){return y[Bn](o,y.create(o)).toString()},Qn:function(){return y[Bn](o,i)}}),e[T(J4)]=!j5({An:function(){f.__proto__=f,f++},Qn:function(){return y[Bn](f,i)}}),e[T(K4)]=l&&j5({An:function(){throw li=s[En][Bn](apFn,y.create(apFn)),li=F5 in\napFn,new TypeError;},Qn:function(){return y[Bn](apFn,i)}}),e[T(Y4)]=l&&!j5({An:function(){s[En][Bn](a,y.create(a)),li=F5 in a},Qn:function(){return y[Bn](a,i)}}),e[T($4)]=d&&(j5({An:function(){li=apFn instanceof apFn},Gn:function(n){return!L5(n,E5)}})||j5({An:function(){var n=a5(apFn);li=n instanceof n},Gn:function(n){return!L5(n,S5)}})),e[T(n5)]=d&&l&&X5(function(){y[Un](apFn,g,{configurable:!0}).toString(),s[En].deleteProperty(apFn,g)}),e))),v=Qr(ru(_),function(n){return!!_[n]}),{acc:li,count:v.length,\nlist:v}):{count:0,list:[]}},V5=function(n){var a=n,u=function(n){return typeof n!=typeof w&&!!n},_={},v=function(n,t){var r=w5(n,t);r.length&&(b5(n,r),_[n]=r)};return{Bn:function(){return _},Jn:function(n,t){var c,i=t?t.Kn:undefined,o=t?t.Yn:undefined;try{if(c=n(),!u(c))return}catch(f){return}var r=c.prototype||c,r=au(_r(r).concat(ru(r)));nu(r.sort(),function(n){var t=n==k5||i&&!fu(i,n)||fu(o,n);if(!t){t=\"\".concat(c.name||(M5.test(c)?null===(t=M5.exec(c))||void 0===t?void 0:t[1]:w),\".\").concat(n);\ntry{var r=c.prototype||c,u=void 0;try{var apFn=r[n];if(Vr(apFn))return u=q5(a,r[n],r,p,_),u.count?v(t,u.list):void 0;if(\"name\"!=n&&\"length\"!=n&&n[0]!==pu(n[0]))return v(t,T(t5))}catch(f){}var e=sr(r,n).get,u=q5(a,e,r,c,_);if(u.count)return v(t,u.list)}catch(f){return v(t,r5)}}})}}},z5=function(n){var t=V5(n),r=t.Jn,r=(r(function(){return Function},{Kn:i(0),Yn:i(1)}),r(function(){return AnalyserNode}),r(function(){return AudioBuffer},{Kn:i(2)}),r(function(){return BiquadFilterNode},{Kn:i(3)}),r(function(){return CanvasRenderingContext2D},\n{Kn:i(4)}),r(function(){return CSSStyleDeclaration},{Kn:i(5)}),r(function(){return CSS2Properties},{Kn:i(5)}),r(function(){return Date},{Kn:i(6)}),r(function(){return GPU},{Kn:i(7)}),r(function(){return GPUAdapter},{Kn:i(8)}),r(function(){return Intl.DateTimeFormat},{Kn:i(9)}),r(function(){return Document},{Kn:i(10),Yn:i(11)}),r(function(){return DOMRect}),r(function(){return DOMRectReadOnly}),r(function(){return Element},{Kn:i(12)}),r(function(){return FontFace},{Kn:i(13)}),r(function(){return HTMLCanvasElement}),\nr(function(){return HTMLElement},{Kn:i(14),Yn:i(15)}),r(function(){return HTMLIFrameElement},{Kn:i(16)}),r(function(){return IntersectionObserverEntry},{Kn:i(17)}),r(function(){return Math},{Kn:i(18)}),r(function(){return MediaDevices},{Kn:i(19)}),r(function(){return Navigator},{Kn:i(20)}),r(function(){return Node},{Kn:i(21)}),r(function(){return OffscreenCanvas},{Kn:i(22)}),r(function(){return OffscreenCanvasRenderingContext2D},{Kn:i(23)}),r(function(){return Permissions},{Kn:i(24)}),r(function(){return Range},\n{Kn:i(25)}),r(function(){return Intl.RelativeTimeFormat},{Kn:i(26)}),r(function(){return Screen}),r(function(){return n[Qn]},{Kn:i(27)}),r(function(){return String},{Kn:i(28)}),r(function(){return StorageManager},{Kn:i(29)}),r(function(){return SVGRect}),r(function(){return SVGRectElement},{Kn:i(30)}),r(function(){return SVGTextContentElement},{Kn:i(31)}),r(function(){return TextMetrics}),r(function(){return WebGLRenderingContext},{Kn:i(32)}),r(function(){return WebGL2RenderingContext},{Kn:i(32)}),\nt.Bn());return{Zn:t,$n:r}},Z5=function(){var r=x5.Nn(),n=uu(ru(r),function(n,t){return n+r[t].length},0);return{data:r,total:n}},B5=function(n,t){try{var r,u,e,c,i,o,f,a;return o_()?(r=Er(n,jn),r.appendChild(Er(n,bn)),u=Er(n,jn),Pr(u,\"id\",Ri()),t?Pr(u,Tn,Bt):Pr(u,Fn,zt),Cr(u,r),Cr(gr(n),u),e=iu(u.childNodes)[0],c=iu(e.childNodes)[0],c&&(i=(c||{}).contentWindow,i)?(o=Er(i,jn),o.innerHTML=r,Cr(gr(i),o),f=iu(o.childNodes)[0],a=iu(f.childNodes)[0],a.contentWindow):p):n}catch(_){return n}},N5=function(n,\nt,r){var u=n.self,e={nt:u};if(t)return e;try{var c=u.length,i=new DocumentFragment,o=Er(n,jn),f=Ri(),a=(Pr(o,\"id\",f),Cr(i,o),Er(n,jn)),_=(r?Pr(a,Tn,Bt):Pr(a,Fn,zt),Cr(a,Er(n,bn)),Cr(o,a),Cr(gr(n),i),u[c]),v=B5(_,r);return{nt:v||u,tt:o}}catch(s){return e}},U5=function(){return di},A5=function(){return hi},G5=function(n){n[Qn]&&n[Qn][i5]()},Q5=function(n){o5=!(!y5(n,\"\".concat(Yn,\"ToString\"))&&!m5(n)),f5=!!y5(n,p5)},J5=function(n,t,r,u){var e=N5(n,r,u),c=e.nt,e=e.tt;hi=c,di=e,H5()},K5=function(){Sr(U5())},\nY5=vn(271),$5=vn(272),n3=vn(273),t3=function(n,t){return n[Y5]&&Vr(n[Y5].supports)&&n[Y5].supports(t)},r3=function(n){return t3(n,et)},u3=function(n){var t=lf(n);return!(!t||!t.query)},e3=function(t,r){return lf(t).query({name:Jn.toLowerCase()+\"s\"}).then(function(n){r(n.state==In&&c3(t))})[\"catch\"](function(){return r(!1)})},c3=function(n){return Jn in n&&n[Jn].permission===_t},i3=function(n,t,r,u){if(!o_()||r)return!1;var e=t;try{if(t||(e=Er(n,jn),Cr(gr(n),e)),!e)return!1;if(!n.getComputedStyle)return!1;\nu?Pr(e,Tn,n3):Pr(e,Fn,$5);var c=n.getComputedStyle(e).backgroundColor;return c===\"\".concat(xt,\"(255, \").concat(m,\", \").concat(m,\")\")}finally{t||Dr(gr(n),e)}},o3=function(n){return Ev(n,ot,!1)},f3=function(n,t){return L4(n,[],function(n){t(s(n)?n[Vi]===g:null)})},a3=function(n){var t=d(n);return gt in t&&!1===t[gt]},_3=function(n){return Hr(n)===Go(n)&&Fr(n)===Qo(n)||Tr(n)&&~~Tr(n).width===Go(n)&&~~Tr(n).height===Qo(n)},v3=function(){return!!_5[xu($n,mt)]},s3=function(n){var t=d(n);return o_()&&t3(n,\nrt)&&(!(Pt in t)||!(it in t))},l3=vn(274),d3=vn(275),h3=function(n){return o_()&&e(function(){return p3(n)})||{}},p3=function(n){var t=pt in n[l3].prototype,r=t3(n,ut),u=at in n,e=ft in n,c=n[d3]&&st in(n[d3].prototype||{});return{rt:r&&!u,ut:t&&!e,et:!c}},r=function(n){return n},y3=$r([Bi,qi,no,Ai,Ui,Ui+\"s\",co,Vi,Zi,zi,to,Gi,gv],function(n){return xu($n,n)}),m3=$r([r(vn(425)),r(vn(426)),r(vn(427)),r(vn(428)),r(vn(139)),r(vn(140))],function(n){return xu(r(vn(429)),n)}),w3=[xu(\"Date\",Rv),xu(\"Intl.RelativeTimeFormat\",\nvo),xu(\"Intl.DateTimeFormat\",vo)],Re=[xu(\"String\",r(vn(430)))],g3=$r([r(vn(280)),r(vn(431)),r(vn(432))],function(n){return xu(r(vn(433)),n)}).concat(Re).concat([xu(\"CSSStyleDeclaration\",r(vn(424))),xu(\"CSS2Properties\",r(vn(424)))]),l0=$r([r(vn(434)),r(vn(435))],function(n){return xu(r(vn(436)),n)}),H3=l0.concat([]),x3=(nu([r(vn(437)),r(vn(438)),r(vn(439))],function(n){H3.push(xu(r(vn(440)),n)),H3.push(xu(r(vn(441)),n))}),$r([r(vn(442)),r(vn(443)),r(vn(444)),r(vn(445)),r(vn(446)),r(vn(447)),r(vn(425))],\nfunction(n){return xu(r(vn(448)),n)})),b3=$r([r(vn(449)),r(vn(450)),r(vn(451)),r(vn(452))],function(n){return xu(r(vn(453)),n)}).concat(x3).concat(l0).concat(Re),F3=$r([r(vn(454)),r(vn(455))],function(n){return xu(r(vn(456)),n)}),T3=function(n){return Qr(n,function(n){return _5[n]}).length},j3=function(){return $r([y3,m3,w3,g3,H3,b3,x3,F3],function(n){return T3(n)})},X3=function(n){var t=jr(n),r=yr(n),t=f_()&&1!=t;if(!t)return t=Ev(n,\"(\".concat(Wi,\"-width:\").concat(r.width).concat(kn,\") and (\").concat(Wi,\n\"-height:\").concat(r.height).concat(kn,\")\"),!0),!!t},P3=function(n){var t=jr(n),t=Ev(n,\"(resolution:\".concat(t,\"dp\").concat(kn,\")\"),!0);if(!a_())return!!t},L3=function(n){var t=yr(n),r=!(t.width-t.availWidth||t.height-t.availHeight);return t.width>800&&r},C3=function(n,t){var u=!1,r=(nu(n,function(n){try{var t=\"MimeType\"==y[Zn](n[0]).constructor.name;t||(u=!0)}catch(r){u=!0}}),Qr(_r(t),function(n){return isNaN(+n)})),e=$r(n,function(n){return su(tu(n))}),e=$r(e,function(n){return n&&n.type});return nu(e,\nfunction(n){fu(r,n)||_u(r,n)}),nu(n,function(n){var t=$r(tu(n),function(n){return n&&n.type});nu(t,function(n){fu(r,n)||(u=!0)})}),u},D3=function(n){try{var t=Er(n,bn);return t.srcdoc=Ii(n),!!t.contentWindow}catch(r){return!0}},E3=function(n){var t=-50;return l(ru(n).slice(t),oo)&&l(_r(n).slice(t),oo)},S3=function(n){if(!(Lf(n)&&Gn in n[oo]))return!1;try{var t=n[oo][Gn];return Sn in t.sendMessage||Sn in t.connect||(new t.sendMessage,new t.connect),!0}catch(r){return dr(r)!=Xn}},R3=function(){return!!_5[u5]},\nM3=vn(276),O3=vn(277),I3=function(n){var t=d(n),r=gu(fo),u=\"is\".concat(r),r=Cf(t)&&dr(vr(t[fo]))==r&&Lu(t[fo][u])==\"function \".concat(u,\"() { \").concat(Dn,\" }\");return r},k3=function(n){return o_()&&M3 in Array.prototype&&!ar(n,O3)},W3=function(n){return k3(n)&&ef(n)===p},q3=function(n){var t=z5(n).$n;pi=Eu(Du(t))},V3=function(n){return pi[n]},z3=function(n){var t,r;return pi[n]&&(t=Eu(Du(pi[n])),r=[T(C4),T(D4),T(E4),T(S4),T(R4)],r=$r(r,function(n){return Ur(t,n)}),r=ne().apply(p,r)+1,a_()||t.splice(r,\n0,T(M4)),t)},o=function(n,t){return V3(xu(n,t))},j=function(n,t){return z3(xu(n,t))},Z3=vn(278),B3=function(){var n=ru(pi).length,t={ct:{it:i(33),ot:i(33),ft:i(34)},_t:{it:i(35),ot:i(35),vt:i(36),st:i(36),lt:i(36),dt:i(37),ht:i(37)},yt:{it:i(38),ot:i(38),wt:i(38),lt:i(39),dt:i(40),ht:i(39)},gt:{wt:i(36),Ht:i(36),xt:i(36),bt:i(36),Ft:i(36),Tt:i(36),jt:i(36),Xt:i(36),Pt:i(36)},Lt:{ht:i(41),dt:i(41),lt:i(41),Ct:i(41),Dt:i(41),Et:i(41),St:i(41),Rt:i(41),Mt:i(41),Ot:i(42),It:i(42),kt:i(42),Wt:i(42),qt:i(42),\nVt:i(42),zt:i(42)},Zt:{lt:i(43),ht:i(43)},Bt:{Ot:i(44),qt:i(44),Vt:i(44)},Nt:{it:i(45),ot:i(45),wt:i(45),Ht:i(45),xt:i(45),Ft:i(45),Tt:i(45),jt:i(45),Xt:i(45),Pt:i(45),Ot:i(42)},Ut:{it:i(46),ot:i(47),vt:i(46),st:i(46),wt:i(46),Ht:i(46),xt:i(46),bt:i(46),Ft:i(46),Tt:i(46),jt:i(46),Xt:i(46),Pt:i(46),ft:i(48),ht:i(48),dt:i(48),lt:i(46),Ot:i(49)}},r={At:c(o(vn(457),vn(458))),Gt:c(o(vn(457),vn(459))),Qt:c(o(vn(460),vn(461))),Jt:c(o(vn(460),vn(462))),Kt:c(o(vn(463),vn(464))),Yt:c(o(vn(463),vn(465))),$t:c(o(vn(463),\nvn(466))),nr:c(o(vn(463),vn(467))),tr:c(o(vn(463),vn(468))),rr:c(o(vn(463),vn(469))),ur:c(o(vn(470),vn(471))),er:c(o(vn(470),vn(472))),cr:c(o(vn(470),vn(473))),ir:c(o(vn(436),vn(435))),ar:c(o(vn(436),vn(434))),_r:c(o(vn(436),vn(474))),vr:c(o(vn(453),vn(451))),sr:c(o(vn(475),vn(476))),lr:c(o(vn(475),vn(477))),dr:c(o(vn(475),vn(478))),hr:c(o(vn(475),vn(479))),pr:c(o(vn(456),vn(455))),yr:c(o(vn(456),vn(454))),mr:c(o(vn(44),vn(129))),wr:c(o(vn(429),vn(428))),gr:c(o(vn(429),vn(480))),Hr:c(o(vn(429),vn(481))),\nbr:c(o(vn(429),vn(427))),Fr:c(o(vn(429),vn(139))),Tr:c(o(vn(429),vn(140)))},u={At:c(j(vn(457),vn(458))),Gt:c(j(vn(457),vn(459))),Qt:c(j(vn(460),vn(461))),Jt:c(j(vn(460),vn(462))),Kt:c(j(vn(463),vn(464))),Yt:c(j(vn(463),vn(465))),$t:c(j(vn(463),vn(466))),nr:c(j(vn(463),vn(467))),tr:c(j(vn(463),vn(468))),rr:c(j(vn(463),vn(469))),ur:c(j(vn(470),vn(471))),er:c(j(vn(470),vn(472))),cr:c(j(vn(470),vn(473))),ir:c(j(vn(436),vn(435))),ar:c(j(vn(436),vn(434))),_r:c(j(vn(436),vn(474))),vr:c(j(vn(453),vn(451))),\nsr:c(j(vn(475),vn(476))),lr:c(j(vn(475),vn(477))),dr:c(j(vn(475),vn(478))),hr:c(j(vn(475),vn(479))),pr:c(j(vn(456),vn(455))),yr:c(j(vn(456),vn(454))),mr:c(j(vn(44),vn(129))),wr:c(j(vn(429),vn(428))),gr:c(j(vn(429),vn(480))),Hr:c(j(vn(429),vn(481))),br:c(j(vn(429),vn(427))),Fr:c(j(vn(429),vn(139))),Tr:c(j(vn(429),vn(140)))},e=function(n,t,r,u){var e=n.ct,c=n._t,i=n.yt,o=n.gt,f=n.Lt,a=n.Zt,_=n.Bt,v=n.Nt,s=n.Ut;if(u)return l(c.it,r.At)&&l(c.ot,r.Gt)&&l(c.vt,r.Qt)&&l(c.st,r.Jt)&&l(c.ht,r.ar)&&l(c.dt,\nr._r)&&l(c.lt,r.vr)?St:u>=3&&l(i.it,t.At)&&l(i.ot,t.Gt)&&l(i.wt,t.Kt)&&l(i.ht,t.ar)&&l(i.dt,t._r)&&l(i.lt,t.vr)?Rt:l(o.wt,r.Kt)&&l(o.Ht,r.Yt)&&l(o.xt,r.$t)&&l(o.bt,r.nr)&&l(o.Ft,r.tr)&&l(o.Tt,r.rr)&&l(o.jt,r.ur)&&l(o.Xt,r.er)&&l(o.Pt,r.cr)?Mt:u>=7&&l(f.ht,t.ar)&&l(f.dt,t._r)&&l(f.lt,t.vr)&&l(f.Ct,t.sr)&&l(f.Dt,t.lr)&&l(f.Et,t.dr)&&l(f.St,t.hr)&&l(f.Rt,t.pr)&&l(f.Mt,t.yr)&&l(f.Ot,t.mr)&&l(f.It,t.wr)&&l(f.kt,t.gr)&&l(f.Wt,t.Hr)&&l(f.qt,t.br)&&l(f.Vt,t.Fr)&&l(f.zt,t.Tr)?Ot:u>=2&&l(a.lt,r.vr)&&l(a.ht,\nr.ar)?It:u>=3&&l(_.Ot,t.mr)&&l(_.qt,t.br)&&l(_.Vt,t.Fr)?kt:u>=2&&l(e.it,t.At)&&l(e.ot,t.At)&&l(e.ft,t.ir)&&t.mr==Z3?Wt:u>=14&&l(v.it,t.At)&&l(v.ot,t.At)&&l(v.wt,t.Kt)&&l(v.Ht,t.Yt)&&l(v.xt,t.$t)&&l(v.Ft,t.tr)&&l(v.Tt,t.rr)&&l(v.jt,t.ur)&&l(v.Xt,t.er)&&l(v.Pt,t.cr)&&l(v.Ot,t.mr)?qt:u>=15&&l(s.it,t.At)&&l(s.ot,t.Gt)&&l(s.vt,t.Qt)&&l(s.st,t.Jt)&&l(s.wt,t.Kt)&&l(s.Ht,t.Yt)&&l(s.xt,t.$t)&&l(s.bt,t.nr)&&l(s.Ft,t.tr)&&l(s.Tt,t.rr)&&l(s.jt,t.ur)&&l(s.Xt,t.er)&&l(s.it,t.At)&&l(s.Pt,t.cr)&&l(s.ft,t.ir)&&l(s.ht,\nt.ar)&&l(s.dt,t._r)&&l(s.lt,t.vr)&&l(s.Ot,t.mr)?Vt:void 0};return e(t,r,u,n)},Pe=function(n,t,r,u){return{jr:m,Xr:!1,Pr:!1,Lr:t,Cr:r,Dr:u,Er:n}},N3=function(n){n.Pr=!0},U3=function(n){N3(n),n.Lr&&n.Lr()},A3=function(n){n.Dr&&n.Dr()},G3=function(n){n.Cr&&n.Cr()},Q3=function(n,t,r){n.jr=n.jr-1,t&&t(r),n.Xr&&(n.jr===m?((n.Pr?G3:U3)(n),A3(n)):n.Pr&&G3(n))},J3=function(t,n,r,u,e){t.jr=t.jr+(e&&e.Sr||1);var c=function(n){Q3(t,u,n)};n.apply(p,r.concat([c]))},K3=function(n){n.Pr||U3(n)},Y3=function(n,t){n.Xr||\n(t(),n.Xr=!0,n.jr===m||n.Er===m?(U3(n),A3(n)):setTimeout(function(){return K3(n)},n.Er))},$3=!1,nl=[],tl=function(n){var t=0,r=nl[t++];while(r)r(n),r=nl[t++];Gr(nl)},rl=function(n){$3||($3=!0,tl(n))},ul=vn(279),el=vn(280),cl=function(r){var u=pr(r);yi=function(n){var t=$e(r)?n||r.event:n;(t&&t.type!==ul||u.readyState===gn)&&(Ye(r)&&Ke(u,wn,yi),Ke(u,ul,yi),Ke(r,el,yi),rl(r))},Ye(r)&&Je(u,wn,yi),Je(u,ul,yi),Je(r,el,yi),(u.readyState===gn||u.readyState===Hn&&!Cu(Bo(r),xn))&&rl(r)},il=function(n,t){$3?\nt(n):nl.push(t)},ol=vn(281),fl=function(r){var n=[e(function(){var n=vn(282);return!(!r.Promise||!r.Promise[n])}),e(function(){var n=vn(283);return H(Element.prototype,n)}),e(function(){var n=vn(284);return H(Element.prototype,n)}),e(function(){var n=vn(285);return H(Intl,n)}),e(function(){var n=vn(286);return H(Element.prototype,n)}),e(function(){return!(!r.Promise||!H(r.Promise,\"any\"))}),e(function(){var n=vn(287);return H(Intl,n)}),e(function(){var n=vn(288);return H(Array.prototype,n)}),e(function(){var n=\nvn(289);return H(y,n)}),e(function(){var n=vn(290);return H(WebAssembly,n)}),e(function(){var n=vn(291);return H(Array.prototype,n)}),e(function(){var n=vn(292);return H(Intl,n)}),e(function(){var n=vn(293);return!(!pr(r)[n]&&null!==pr(r)[n])}),e(function(){var n=vn(294);return H(Element.prototype,n)}),e(function(){var n=vn(295);return H(Element.prototype,n)}),e(function(){var n=vn(296);return H(AudioContext.prototype,n)}),e(function(){var n=vn(297);return H(String.prototype,n)}),e(function(){var n=\nvn(298);return H(ArrayBuffer.prototype,n)}),e(function(){return H(AbortSignal,\"any\")}),e(function(){var n=vn(299);return H(y,n)}),e(function(){var n=vn(300);return!(!r.Promise||!H(r.Promise,n))}),e(function(){var n=vn(301);return!!pr(r)[n]}),e(function(){var n=vn(302);return H(Array,n)}),e(function(){var n=vn(303);return n in r}),e(function(){var n=vn(304);return H(Element.prototype,n)}),e(function(){var n=vn(305);return n in r}),e(function(){var n,t=vn(306);return H(null===(n=r.GPUAdapter)||void 0===\nn?void 0:n.prototype,t)}),e(function(){var n=vn(307);return!!pr(r)[n]}),e(function(){var n=vn(308);return H(Intl,n)}),e(function(){var n,t=vn(309);return H(null===(n=r.SerialPort)||void 0===n?void 0:n.prototype,t)}),e(function(){var n,t=vn(310);return H(null===(n=r.GPUCanvasContext)||void 0===n?void 0:n.prototype,t)}),e(function(){var n=vn(311);return H(Request.prototype,n)}),e(function(){return!Nr(r[oo])}),e(function(){var n=vn(312);return!Nr(pr(r)[n])}),e(function(){return!Nr(rf(r))}),e(function(){return!Nr(A1(r))}),\ne(function(){return!Nr(gf(r))}),e(function(){var n=vn(313);return n in r}),e(function(){var n=vn(314);return!Nr(pr(r)[n])}),e(function(){var n=vn(315);return l(y[zn](r),n)}),e(function(){var n=vn(316);return!Nr(r[n])}),e(function(){var n=vn(317);return!Nr(r[n])}),e(function(){var n=vn(318);return!Nr(d(r)[n])}),e(function(){var n=vn(319);return!Nr(r[n])}),e(function(){return!Nr(d(r)[fo])}),e(function(){return Zr(d(r)[fo])&&Vr(d(r)[fo].isBrave)})];return n},al=function(n){var t=X_(n);if(D_(t)){var r,\nu=Z_(t,80,60);if(u)return r=[\"\\ud804\\udc13\\ud804\\udc37\",\"\\u1019\\u103c\\u1014\\u103a\\u1019\\u102c\\u1005\\u102c\",\"\\u0f56\\u0f7c\\u0f51\\u0f0b\\u0f61\\u0f72\\u0f42\"],I_(u,\"170px Arial\"),u.textAlign=\"center\",u.textBaseline=\"middle\",O_(u,r[0],0,30),O_(u,r[1],40,30),O_(u,r[2],60,30),t.toDataURL().length}},_l=function(t,n){var r=0;return nu(tu(n),function(n){Jr(n,function(n){return vl(t,n)})&&r++}),r},vl=function(n,t){var r=\"mmmmmmmmmmlli\",u=\"100px\",e=[Ut,At,Gt],c=X_(n);if(C_(c)){for(var i=Z_(c,300,150),o={},f=0;f<\ne.length;f++)I_(i,\"\".concat(u,\" \").concat(e[f])),o[e[f]]=i.measureText(r).width;I_(i,\"\".concat(u,\" \").concat(t,\", \").concat(Ut));var c=i.measureText(r).width,a=(I_(i,\"\".concat(u,\" \").concat(t,\", \").concat(At)),i.measureText(r).width),_=(I_(i,\"\".concat(u,\" \").concat(t,\", \").concat(Gt)),i.measureText(r).width);return c!==o[Ut]||a!==o[At]||_!==o[Gt]}},sl=function(n,t,r){n[t]=r||[t]},n=function(n){return n},ll={},dl={},hl={},pl=(nu([[n(vn(482)),[n(vn(482)),n(vn(483))]],[n(vn(484))],[n(vn(485)),[n(vn(486)),\nn(vn(487)),n(vn(488))]],[n(vn(489)),[n(vn(490)),n(vn(491)),n(vn(492)),n(vn(493))]],[n(vn(494))],[n(vn(495))],[n(vn(496)),[n(vn(497)),n(vn(498)),n(vn(499))]],[n(vn(500))],[n(vn(501)),[n(vn(502)),n(vn(503))]],[n(vn(504)),[n(vn(505)),n(vn(506)),n(vn(507))]],[n(vn(494))],[n(vn(495))],[n(vn(508))]],function(n){return sl(ll,n[0],n[1])}),nu([n(vn(509)),n(vn(510)),n(vn(511)),n(vn(512)),n(vn(513)),n(vn(514)),n(vn(515)),n(vn(516)),n(vn(517)),n(vn(518)),n(vn(519)),n(vn(520)),n(vn(521)),n(vn(522)),n(vn(523)),\nn(vn(524))],function(n){return sl(dl,n)}),nu([n(vn(525)),n(vn(526)),n(vn(527)),n(vn(528)),n(vn(529)),n(vn(530)),n(vn(531)),n(vn(532)),n(vn(533)),n(vn(534)),n(vn(535)),n(vn(536)),n(vn(537))],function(n){return sl(hl,n)}),f_()?sl(ll,n(vn(538)),[n(vn(541))]):(sl(ll,n(vn(538)),[n(vn(539)),n(vn(540)),n(vn(541))]),sl(hl,n(vn(542))),sl(hl,n(vn(543)))),function(n){try{var t=_l(n,ll),r=_l(n,hl),u=_l(n,dl),e=al(n);return{Rr:t,Mr:r,Or:u,Ir:e}}catch(sn){return{}}}),yl=function(n,t){if(!o_())return!1;var r=Er(n,\nbn),u=(t?Pr(r,Tn,Nt):Pr(r,Fn,Zt),Pr(r,\"sandbox\",\"allow-scripts\"),Cr(gr(n),r),!1);try{d(r.contentWindow),u=!0}catch(e){u=!1}finally{r.remove()}return u},ml=function(n){var t=xf(n);if(t&&Vr(t.getEntriesByType)){t=t.getEntriesByType(\"navigation\")[0];if(t)return{kr:t.redirectEnd-t.redirectStart,Wr:t.domainLookupEnd-t.domainLookupStart,qr:t.connectEnd-t.connectStart,Vr:t.secureConnectionStart>0?t.connectEnd-t.secureConnectionStart:0,zr:t.responseEnd-t.responseStart,Zr:t.fetchStart>0?t.responseEnd-t.fetchStart:\n0,Br:t.requestStart>0?t.responseEnd-t.requestStart:0,Nr:t.startTime>0?t.responseEnd-t.startTime:0,Ur:t.duration}}},wl=function(n){return[n.kr,n.Wr,n.qr,n.Vr,n.zr,n.Zr,n.Br,n.Nr,n.Ur]},gl=function(n){var t={Ar:!1,Gr:!1,Qr:!1,Jr:!1,Kr:null};try{t.Ar=!Cu(HTMLCanvasElement.prototype.toDataURL.toString(),Cn)}catch(sn){}try{t.Gr=!Cu(CanvasRenderingContext2D.prototype.getImageData.toString(),Cn)}catch(r){}try{CanvasRenderingContext2D.prototype.getImageData.apply(undefined,[0,0,1,1])}catch(u){t.Kr=u.message}if(o_()){try{t.Qr=\n!0,y[Bn](HTMLCanvasElement.prototype.toDataURL,HTMLCanvasElement.prototype.toDataURL)}catch(u){Cu(u.message,\"Cyclic\")&&(t.Qr=!1)}try{t.Jr=!0,y[Bn](CanvasRenderingContext2D.prototype.getImageData,CanvasRenderingContext2D.prototype.getImageData)}catch(u){Cu(u.message,\"Cyclic\")&&(t.Jr=!1)}}return t},Hl=function(){var n,t,r=62,u=new Array(r);while(r--)u[r]=String.fromCharCode(r+(r<10?48:r<36?55:61)),n=ve(r+1),t=u[r],u[r]=u[n],u[n]=t;return u.join(\"\")},xl=function(n){var t=X_(n);if(D_(t)){var r=Z_(t,200,\n200);if(r){_(r,\"rgba(0, 127, 255, 1)\");for(var u=[0,127,255,255],e=(M_(r,0,0,t.width,t.height),r.getImageData(0,0,t.width,t.height).data),c=0;c<e.length;c+=1)if(e[c]!==u[c%4])return!1;return!0}}},bl=function(n){var t=X_(n);if(C_(t)){t=Z_(t,800,15);if(t){for(var r=Hl(),u=(O_(t,r,20,10),Qu(t.measureText(r).width)),e=t.getImageData(0,0,u,15).data,t=X_(n),t=Z_(t,800,15),c=(t.fillText(r+\" \"+r,20,10),t.getImageData(0,0,u,15).data),i=0,o=0;o<e.length;o++)i+=Ju(e[o]-c[o]);return i}}},Fl=function(n,u){var e=\nX_(n);if(D_(e)){var c=Z_(e,10,10);if(c){for(var i=0,t=c.createImageData(e.width,e.height),r=0;r<t.data.length;r+=4){var o=ve(256),f=ve(256),a=ve(256);i+=o+f+a,t.data[r]=o,t.data[r+1]=f,t.data[r+2]=a,t.data[r+3]=255}c.putImageData(t,0,0);var _=new Image;_.onload=function(){c.drawImage(_,0,0);for(var n=c.getImageData(0,0,e.width,e.height),t=0,r=0;r<n.data.length;r+=4)t+=n.data[r]+n.data[r+1]+n.data[r+2];u(Ju(t-i))},_.src=e.toDataURL()}}},Tl=function(n,u){var e=X_(n);if(D_(e)){var t=Z_(e,200,200);if(t){_(t,\n\"#FF0000\"),M_(t,10,10,50,50),_(t,\"#00FF00\"),M_(t,70,10,50,50),_(t,\"#0000FF\"),M_(t,130,10,50,50),_(t,\"#FFFF00\"),M_(t,40,70,50,50),_(t,\"#FF00FF\"),M_(t,100,70,50,50),I_(t,\"16px Arial\"),_(t,\"#000000\"),O_(t,\"Hello Canvas\",20,150),I_(t,\"20px Times New Roman\"),_(t,\"#444444\"),O_(t,\"Testing\",100,150),t.beginPath(),t.strokeStyle=\"#008000\",t.moveTo(20,180),t.bezierCurveTo(20,100,100,100,100,180),t.stroke(),t.beginPath(),t.strokeStyle=\"#800000\",t.moveTo(100,180),t.bezierCurveTo(100,160,180,160,180,180),t.stroke();\nfor(var r=X_(n),c=Z_(r,e.width,e.height),i=new Image,o=(i.src=e.toDataURL(),t.getImageData(0,0,e.width,e.height)),f=(i.onload=function(){if(c){c.drawImage(i,0,0);for(var n=c.getImageData(0,0,e.width,e.height),t=0,r=0;r<o.data.length;r++)o.data[r]!==n.data[r]&&(t+=Ju(o.data[r]-n.data[r]));u(t)}else u(w),void 0},[]),a=0;a<o.data.length;a++)f.push(o.data[a].toString())}}},jl=function(n){if(F_ in n){var t=X_(n);if(D_(t)){var r=Z_(t,200,50);if(r){_(r,\"#FF0000\"),M_(r,10,10,50,50),_(r,\"#00FF00\"),M_(r,70,\n10,50,50),_(r,\"#0000FF\"),M_(r,130,10,50,50),_(r,\"#FFFF00\"),M_(r,40,70,50,50),_(r,\"#FF00FF\"),M_(r,100,70,50,50),_(r,\"rgba(125, 200, 0, 0.77)\"),I_(r,\"bold 120px Arial\"),O_(r,\"Hello Canvas\",-10,55),I_(r,\"20px Times New Roman\"),_(r,\"#444444\"),O_(r,\"Testing\",60,20);r=P_(n,200,50);if(C_(r)){var u=r.getContext(y_);if(u){_(u,\"#FF0000\"),M_(u,10,10,50,50),_(u,\"#00FF00\"),M_(u,70,10,50,50),_(u,\"#0000FF\"),M_(u,130,10,50,50),_(u,\"#FFFF00\"),M_(u,40,70,50,50),_(u,\"#FF00FF\"),M_(u,100,70,50,50),_(u,\"rgba(125, 200, 0, 0.77)\"),\nI_(u,\"bold 120px Arial\"),O_(u,\"Hello Canvas\",-10,55),I_(u,\"20px Times New Roman\"),_(u,\"#444444\"),O_(u,\"Testing\",60,20);var u=X_(n),e=Z_(u,200,50);if(e)return e.drawImage(r,0,0),u.toDataURL()===t.toDataURL()}}}}}},Xl=function(n,t,r){return Qr(n,function(n){return Cu(n[r||\"src\"],t)}).length>0},Pl=function(n){var t={Yr:!1,$r:!1,nu:!1,tu:!1,ru:!1,uu:!1,eu:!1,cu:!1,iu:!1,ou:!1,fu:!1,au:!1,_u:!1,vu:!1,su:!1,lu:!1,du:!1,hu:!1,pu:!1,yu:!1,mu:!1,wu:!1,gu:!1,Hu:!1,xu:!1,bu:!1,Fu:!1,Tu:!1,ju:!1,Xu:!1,Pu:!1,\nLu:!1,Cu:!1,Du:!1,Eu:!1,Su:!1,Ru:!1,Mu:!1,Ou:!1,Iu:!1,ku:!1,Wu:!1,qu:!1},r=vn(320),u=vn(321),e=vn(322),c=vn(323),i=vn(324),o=vn(325),f=vn(326),a=vn(327),_=vn(328),v=vn(329),s=vn(330),l=vn(331),d=vn(332),h=vn(333),p=vn(334),y=vn(335),m=vn(336),w=vn(337),g=vn(338),H=vn(339),x=vn(340),b=vn(341),F=vn(342),T=vn(343),j=vn(344),X=vn(345),P=vn(346),O=vn(347),I=vn(348),k=vn(349),W=vn(350),q=vn(351),V=vn(352),z=vn(353),Z=vn(354),B=vn(355),N=vn(356),U=vn(357),A=vn(358),G=vn(359),Q=vn(360),J=vn(361),K=vn(362),\nY=vn(363),$=vn(364),nn=vn(365),tn=vn(366),rn=vn(367),un=vn(368),en=vn(369),cn=vn(370),on=vn(371),fn=vn(372);try{var L=pr(n),C=gr(n),D=n[nc],E=n.sessionStorage,S=(t.Yr=iv(C,r),t.Ru=iv(C,u),t.$r=!(!n.ethereum||!n.ethereum.isMetaMask),L.querySelectorAll(on)),an=(t.nu=Xl(S,e),t.tu=Xl(S,c),t.yu=Xl(S,i),L.querySelectorAll(bn));t.ru=Xl(an,o),t.uu=!!L.querySelector(f),t.eu=!!L.querySelector(a),t.cu=!!L.getElementById(_),t.iu=null!==Lr(C,v);try{t.ou=!(!D||!D[s]||0!==D[s].indexOf(l)),t.vu=!(!E||!Br(E[d])),\nt.Fu=!!(D&&D[h]&&Cu(D[h],p)),t.ju=!(!E||!Br(E[y]))}catch(sn){}t.fu=!!L.getElementById(m),t.au=w in n&&Cu(n.handler.toString(),g),t._u=H in n,t.su=!!n.querySelector('[ext-id=\"'.concat(x,'\"]')),t.lu=b in n&&F in n&&T in n,t.du=!!n.querySelector(j),t.hu=X in n||P in n,t.pu=!!L.getElementById(O),t.mu=I in n&&k in n,t.wu=L.querySelectorAll(W).length>1,t.gu=!!L.getElementById(q)||!!L.getElementById(V),t.Hu=!!L.querySelector(z),t.xu=!!L.querySelector(Z),t.bu=!!L.getElementById(B),t.Tu=!!L.querySelector(N),\nt.Xu=!!L.getElementById(U),t.Pu=!!L.querySelector(\".at-theme-light > .at-base.notranslate\");var R=L.querySelector(A),_n=(R&&(t.Lu=iv(R,G),t.ku=iv(R,Q)),t.Cu=!!L.getElementById(J),t.Du=!!L.querySelector(K),t.Eu=Y in n&&$ in n.ietab,t.Su=!!L.getElementById(nn),t.Mu=!!L.getElementById(tn),t.Ou=!!L.getElementById(rn),t.Iu=!!L.getElementById(un),t.Wu=fu(C.classList,en),n.querySelectorAll(\"link\"));t.qu=Xl(_n,cn,fn)}catch(M){}return t},Ll=function(n){return[n.Yr,n.$r,n.nu,n.tu,n.ru,n.uu,n.eu,n.cu,n.iu,n.ou,\nn.fu,n.au,n._u,n.vu,n.su,n.lu,n.du,n.hu,n.pu,n.yu,n.mu,n.wu,n.gu,n.Hu,n.xu,n.bu,n.Fu,n.Tu,n.ju,n.Xu,n.Pu,n.Lu,n.Cu,n.Du,n.Eu,n.Su,n.Ru,n.Mu,n.Ou,n.Iu,n.ku,n.Wu,n.qu]},Cl=vn(373),Dl=vn(374),El=vn(375),Sl=vn(376),Rl=function(n){var t,r={Vu:Cl in n,zu:Dl in n,Zu:[]};for(t in n){var u=w;try{var e=y[Nn](n,t),u=e&&Vr(e.get)}catch(sn){}!u&&Vr(n[t])&&Vr(n[t].toString)&&(Cu(n[t].toString(),El)?(r.Bu=!0,r.Zu.push(t)):Cu(n[t].toString(),Sl)&&(r.Nu=!0,r.Zu.push(t)))}return r},Ml=vn(377),Ol=function(n){var u=\nxf(n);return new n.Promise(function(t){var r=u.now();d(n).gpu.requestAdapter(1255).then(function(n){})[\"catch\"](function(n){t(u.now()-r)})})},Il=vn(378),kl=function(n,s){try{var l;Ml in d(n)?(l=xf(n),Ol(n).then(function(_){var v=l.now();d(n).gpu.requestAdapter().then(function(n){if(n){for(var t=ru(y[Zn](n.limits)),r=(_u(t,Il),[]),u=0,e=t;u<e.length;u++){var c=e[u];r.push(c+n.limits[c])}for(var i=r.join(\",\"),o=0,f=0;f<i.length;f++){var a=i.charCodeAt(f),o=(o<<5)-o+a;o|=0}t=_>0?(l.now()-v)/_:0;s({Uu:n.info.vendor,\nAu:n.info.architecture,Gu:n.features.size,Qu:n.isFallbackAdapter,Ju:o.toString(),Ku:fe(t,3)})}else s(w),void 0})[\"catch\"](function(n){s(w)})})):(s(w),void 0)}catch(t){s(w)}},Wl=function(n,i){try{var t=d(n).keyboard;t&&t.getLayoutMap?t.getLayoutMap().then(function(n){for(var r=[],t=(n.forEach(function(n,t){r.push(\"\".concat(n,\",\").concat(t))}),r.join(\" \")),u=0,e=0;e<t.length;e++){var c=t.charCodeAt(e),u=(u<<5)-u+c;u|=0}i({Yu:u.toString(),$u:n.size})})[\"catch\"](function(n){i(w)}):i(w)}catch(r){i(w)}},\nql=[Mo,Oo,qo,Wo,ko],Vl=function(n){if(n.length){for(var t={ne:i(50),te:i(51),re:i(52),ue:i(53)},t=[{ee:Mo,ce:new RegExp(t.ne.join(\"|\"),\"i\")},{ee:Oo,ce:new RegExp(t.te.join(\"|\"),\"i\")},{ee:qo,ce:new RegExp(t.re.join(\"|\"),\"i\")},{ee:Wo,ce:new RegExp(t.ue.join(\"|\"),\"i\")}],r=function(t){if(Jr(n,function(n){return t.ce.test(n.name)}))return{value:t.ee}},u=0,e=t;u<e.length;u++){var c=e[u],c=r(c);if(\"object\"===typeof c)return c.value}return ko}},zl=function(n,t,r){var u=speechSynthesis.getVoices(),e=u&&u.find&&\nu.find(function(n){return n[\"default\"]}),c={};e&&(c.ie=e.lang.split(\"-\")[0]),c.oe=u.length,c.fe=Qr(u,function(n){return n.localService}).length,c.ae=Qr(u,function(n){return Cu(n.name,Co)}).length,c.ee=Vl(u),r(c)};function Zl(n,t){var r=n[Qn];r||t(w);try{zl(n,r,t),r.onvoiceschanged=function(){return zl(n,r,t)}}catch(sn){t(w)}}var Bl=function(n,t){var u,r,e=xf(n);Nr(n.Promise)||!e?(t(w),void 0):(u=!1,r=new n.Promise(function(t){var r=e.now();requestAnimationFrame(function(){var n;u||(u=!0,n=e.now()-\nr,t(n))})}),r.then(function(n){t(n|m)})[\"catch\"](function(){t(w)}))},Nl=function(n){if(!Nr(n.HTMLCanvasElement)){var t=X_(n);if(D_(t)){var r,e=Z_(t,720,16);if(e)return I_(e,\"8px \".concat(At)),r=[\"\\ud83d\\ude00\",\"\\ud83d\\ude01\",\"\\ud83d\\ude02\",\"\\ud83d\\ude03\",\"\\ud83d\\ude04\",\"\\ud83d\\ude05\",\"\\ud83d\\ude06\",\"\\ud83d\\ude07\",\"\\ud83d\\ude09\",\"\\ud83d\\ude0a\",\"\\ud83d\\ude0b\",\"\\ud83d\\ude0c\",\"\\ud83d\\ude0d\",\"\\ud83d\\ude0e\",\"\\ud83d\\ude0f\",\"\\ud83d\\ude10\",\"\\ud83d\\ude42\",\"\\ud83d\\ude43\",\"\\ud83e\\udd23\",\"\\ud83e\\udd29\",\"\\ud83e\\udd70\",\n\"\\ud83d\\ude0f\",\"\\ud83d\\ude09\",\"\\ud83d\\ude07\",\"\\ud83e\\udd81\",\"\\ud83d\\udc36\",\"\\ud83d\\udc2f\",\"\\ud83e\\udd8a\",\"\\ud83d\\udc1d\",\"\\ud83d\\udc30\",\"\\ud83d\\udc2d\",\"\\ud83d\\udc38\",\"\\ud83e\\udd85\",\"\\ud83d\\udc3c\",\"\\ud83d\\udc1f\",\"\\ud83c\\udf44\",\"\\ud83c\\udf32\",\"\\ud83c\\udf33\",\"\\ud83c\\udf34\",\"\\ud83c\\udf35\",\"\\ud83c\\udf55\",\"\\ud83c\\udf54\",\"\\ud83c\\udf5f\",\"\\ud83c\\udf70\",\"\\ud83e\\udd5e\",\"\\ud83c\\udf53\",\"\\ud83c\\udf4c\",\"\\ud83c\\udf4e\",\"\\ud83c\\udf49\",\"\\ud83c\\udf4a\",\"\\ud83c\\udf82\",\"\\ud83c\\udf68\",\"\\ud83e\\udd5b\",\"\\ud83e\\udd6d\",\"\\ud83e\\uddc0\",\n\"\\ud83c\\udf7a\",\"\\ud83c\\udfc0\",\"\\ud83c\\udfc8\",\"\\ud83c\\udfca\",\"\\ud83c\\udfb3\",\"\\ud83c\\udfd3\",\"\\ud83c\\udff8\",\"\\ud83e\\udd3a\",\"\\ud83c\\udfb2\",\"\\ud83c\\udfc6\",\"\\ud83d\\udef8\",\"\\ud83e\\udd4a\",\"\\ud83c\\udfa3\",\"\\ud83c\\udfd2\",\"\\ud83d\\udcf1\",\"\\ud83d\\udcf2\",\"\\ud83d\\udcbb\",\"\\ud83c\\udfa5\",\"\\ud83d\\udcb0\",\"\\ud83d\\udce6\",\"\\ud83d\\udcb3\"],f_()||r.push(\"\\u26bd\",\"\\ud83c\\udfaf\",\"\\ud83c\\udfb1\",\"\\ud83c\\udfe0\",\"\\ud83d\\udef0\",\"\\ud83d\\udcfa\",\"\\ud83d\\ude80\",\"\\ud83d\\udee0\",\"\\ud83d\\udeeb\",\"\\ud83c\\udfa7\",\"\\ud83d\\udd79\",\"\\ud83d\\udca1\"),\nnu(r,function(n,t){var r=8*(t+1),u=8;O_(e,n,r,u)}),R_(t)}}},Ul=function(n){var t=xf(n);if(t&&t.memory&&t.memory.jsHeapSizeLimit)return t=t.memory,{_e:t.jsHeapSizeLimit,ve:t.totalJSHeapSize}},Al=function(n){return[n._e,n.ve]};function Gl(n,t,r,u,e,c){O_(n,t,r,u);var i=n.getImageData(e,c,1,1);return[i.data[0],i.data[1],i.data[2],i.data[3]]}function Ql(n,t,r){var u=X_(n);if(C_(u)){var e=Z_(u,96,96,{willReadFrequently:r});if(e){I_(e,\"94px \".concat(At)),_(e,\"#000\");for(var c=0;c<t;c++)Gl(e,\"\\ud83d\\uddfa\\ufe0f\",\n-1,96,Math.floor(80*_e()),Math.floor(80*_e()))}}}var Jl,sn,Kl,Yl,$l,n6,t6=function(n){var t,r,u=xf(n);if(u&&Vr(u.now)&&!Nr(n.HTMLCanvasElement))return Ql(n,3,!0),t=u.now(),Ql(n,7,!0),t=u.now()-t,r=u.now(),Ql(n,7,!1),u=u.now()-r,r=0!==u&&0!==t?u/t:0,fe(r,3)},r6=function(n,t,r,u){if(t||!(\"getComputedStyle\"in n))return p;var e=Er(n,jn);try{var c=Er(n,Fn),i=\"@media (device-\".concat(r,\": \").concat(u,\"px) {\\n        body {\\n          --device-\").concat(r,\": \").concat(u,\";\\n        }\\n      }\"),o=(c.textContent=\ni,Cr(e,c),Cr(gr(n),e),n.getComputedStyle(gr(n))),f=Xu(o.getPropertyValue(\"--device-\".concat(r)))}catch(sn){}finally{Dr(gr(n),e)}return f?parseInt(f):p},u6=function(n,t){var r,u=yr(n),e=Go(n),c=Qo(n),i={};i.se=!!u.isExtended,i.le=Jo(n)>e||Ko(n)>c,i.de=wr(n).clientWidth>e||wr(n).clientHeight>c,i.he=Hr(n)>e||xr(n)>c,i.pe=br(n)>e,i.ye=!(r6(n,t,\"width\",e)===e&&r6(n,t,\"height\",c)===c);for(var o=56;o<2E3;o++)if(Ev(n,\"(max-resolution: \"+o+\"dpi)\",!1)){r=o;break}return i.me=r!==96*jr(n),i.we=pr(n).fullscreenElement!==\np,i},e6=function(n){var t=yr(n),t=t.orientation;if(t)return{ge:t.type,He:t.angle}},c6=function(n,t){var r=Er(n,jn),u=(t?Pr(r,Tn,Bt):Pr(r,Fn,zt),gr(n)),e=(Cr(u,r),{xe:r.offsetWidth-r.clientWidth,be:r.offsetHeight-r.clientHeight});return Dr(u,r),e},i6=function(n){return(new RegExp(yt)).test(n.ua)},o6=function(n){return(new RegExp(Lt)).test(n.r)},f6=function(n,t){return!(!n.ua||!t)&&n.ua!==t},a6=function(n,t){return!(!n.p||!t)&&n.p!==t},_6=function(n,t){return!(!n.hc||!t)&&n.hc!==t},v6=function(n,t){return!(!n.l||\n!t)&&n.l!==t},s6=function(n,t){return!(!n.ls||!t)&&Du(n.ls)!==Du(t)},l6=function(n,t){return!(!n.v||!t)&&n.r!==t},d6=function(n,t){return!(!n.dm||!t)&&n.dm!==t},h6=function(n,t,r){var u,e;try{e=n(),e&&(e.onmessage=function(n){!t.Fe&&n.data&&n.data.keep||(clearTimeout(u),e&&e.terminate()),n.data&&!n.data.e?r({Te:n.data}):r({je:!0})},e.postMessage(g),u=setTimeout(function(){e&&e.terminate(),r({Er:!0})},t.Er))}catch(c){u2(c),clearTimeout(u),e&&e.terminate(),r({je:!0})}},p6=function(n,t){if(\"https:\"==\nmr(n).protocol&&n.Symbol)return new n.Worker(t)},y6=vn(379),m6=function(n){var t=new Blob([n],{type:\"application/\".concat(y6)}),t=URL.createObjectURL(t);return new Worker(t)},w6=vn(380),g6=1024*1024,H6=vn(381),x6=vn(382),b6=function(c,i){var o=Ii(c);try{var n=mf(c).open(o,1);n.onupgradeneeded=function(n){var t=n.target&&n.target.result?n.target.result:w;try{t[H6](l1,{autoIncrement:!0}).put(new Blob),i(!1)}catch(e){var r,u=e;return e instanceof Error&&(u=e.message||e),Br(u)?(r=(new RegExp(w6)).test(u),\ni(r)):i(!1)}finally{t.close(),mf(c)[x6](o)}}}catch(t){return i(!1)}},F6=function(n,t){var r=wf(n),u=n[nc];try{r(p,p,p,p)}catch(e){return t(!0)}try{u.setItem(l1,\"1\"),u.removeItem(l1)}catch(e){return t(!0)}t(!1)},T6=function(n,t){(d(n)[gv]!==w?b6:F6)(n,t)},j6=function(n){return xf(n)!==w&&xf(n)[wo]!==w&&xf(n)[wo][go]!==w?xf(n)[wo][go]:1073741824},X6=vn(383),P6=function(e,c){gf(e)[X6](function(n,t){var r=Gu(t/g6),u=2*Gu(j6(e)/g6);c(r<u)},function(n){c(!1)})},L6=function(n,t){var r=Hf(n),u=function(){t(!1)},\ne=function(){t(!0)};r(0,1,u,e)},C6=function(n,t){(n.Promise!==w&&n.Promise.allSettled!==w?P6:L6)(n,t)},D6=function(n,t){t(cr(df(n)))},E6=function(n,t){t(cr(mf(n)))},S6=function(n,t){try{return a_()?T6(n,t):o_()?C6(n,t):f_()?D6(n,t):__(n)?E6(n,t):(t(!1),void 0)}catch(r){t(!1)}},R6=\"^\\\\s*([a-z-]*)(.*)$\",M6=\"([.:#][\\\\w-]+|\\\\[.+?\\\\])\",O6='^\\\\[([\\\\w-]+)([~|^$*]?=(\"([^\"]*)\"|([\\\\w-]+)))?(\\\\s+[is])?\\\\]$',I6=function(n){for(var t,r=(new RegExp(R6,\"i\")).exec(n),u=r[1]||undefined,e=new RegExp(M6,\"gi\");;){var c=\ne.exec(r[2]);if(!c)break;var i=c[0];switch(i[0]){case \".\":return[u,Tn,i.slice(1)];case \"#\":return[u,\"id\",i.slice(1)];case \"[\":var o=(new RegExp(O6)).exec(i);if(o)return[u,o[1],null!==(t=null!==(t=o[4])&&void 0!==t?t:o[5])&&void 0!==t?t:g]}}return[u,undefined,undefined]},k6=function(n,t){var r=I6(t),u=r[0],e=r[1],r=r[2],u=Er(n,null!==u&&void 0!==u?u:jn);return e&&r&&Pr(u,e,r),u},u=function(n){return n},W6=function(){return[[u(vn(544)),u(vn(545)),u(vn(546))],[u(vn(547)),u(vn(548)),u(vn(549))],[u(vn(550)),\nu(vn(551)),u(vn(552))],[u(vn(553)),u(vn(554)),u(vn(555))],[u(vn(556)),u(vn(557)),u(vn(558))],[u(vn(559)),u(vn(560)),u(vn(561))],[u(vn(562))],[u(vn(563)),u(vn(564)),u(vn(565))],[u(vn(566))],[u(vn(567)),u(vn(568)),u(vn(569))],[u(vn(570)),u(vn(571)),u(vn(572))],[u(vn(573)),u(vn(574)),u(vn(575))],[u(vn(576)),u(vn(577)),u(vn(578))],[u(vn(579)),u(vn(580)),u(vn(581))],[u(vn(582)),u(vn(583)),u(vn(584))],[u(vn(585)),u(vn(586)),u(vn(587))],[u(vn(588)),u(vn(589)),u(vn(590))],[u(vn(591)),u(vn(592)),u(vn(593))],\n[u(vn(594)),u(vn(595)),u(vn(596))],[u(vn(597)),u(vn(598)),u(vn(599))],[u(vn(600)),u(vn(601)),u(vn(602))],[u(vn(603)),u(vn(604)),u(vn(605))],[u(vn(606)),u(vn(607)),u(vn(608))],[u(vn(609)),u(vn(610)),u(vn(611))],[u(vn(612)),u(vn(613)),u(vn(614))],[u(vn(615)),u(vn(616))],[u(vn(617))],[u(vn(618)),u(vn(619)),u(vn(620))],[u(vn(621))],[u(vn(622)),u(vn(623)),u(vn(624))],[u(vn(625)),u(vn(626)),u(vn(627))],[u(vn(628)),u(vn(629)),u(vn(630))],[u(vn(631)),u(vn(632)),u(vn(633))],[u(vn(634)),u(vn(635)),u(vn(636))],\n[u(vn(637))],[u(vn(638)),u(vn(639)),u(vn(640))],[u(vn(641)),u(vn(642)),u(vn(643))],[u(vn(644)),u(vn(645))],[u(vn(646)),u(vn(647)),u(vn(648))],[u(vn(649)),u(vn(650)),u(vn(651))],[u(vn(652)),u(vn(653)),u(vn(654))],[u(vn(655)),u(vn(656)),u(vn(657))]]},q6=function(n,t){try{var r=W6(),u=uu(r,function(n,t){return n.concat(t)},[]);Z6(n,u,function(n){t(V6(r,n))})}catch(e){t(undefined)}},V6=function(n,t){for(var r,u=0;u<n.length;u++)z6(n[u],t)&&(r=r||[],r.push(u));return r},z6=function(n,t){for(var r=0,u=\nn;r<u.length;r++){var e=u[r];if(t[e])return!0}return!1},Z6=function(n,t,r){for(var u=Er(n,jn),e=(Mr(u),new Array(t.length)),c=0;c<t.length;++c){var i=k6(n,t[c]),o=Er(n,jn);Mr(o),Cr(o,i),Cr(u,i),e[c]=i}Cr(gr(n),u);var f={};setTimeout(function(){try{for(var n=0;n<t.length;++n)e[n].offsetParent||(f[t[n]]=!0)}finally{Sr(u)}r(f)},0)},B6={email:!1,hidden:!1,password:!1,tel:!1,text:!1},N6=vn(384),U6=vn(385),A6=vn(386),G6=function(n){if(n.target&&n.target.value&&n.target.type&&n.target.type in B6&&!(U6!==\nn.inputType&&\"data\"in n&&N6!==n.animationName))return!0},Q6=function(){return B6},J6=function(n,t){G6(n)&&(B6[n.target.type]=!0,t(n))},K6=function(n,t){var r=pr(n),u=function(n){return e(function(){return J6(n,t)})};Je(r,A6,u),Je(r,Wn,u)},Y6=vn(387),$6=function(n){var t,r=!1;return o_()&&(t=new Error,y[Un](t,Y6,{get:function(){return r=!0,g}}),ac(n,oc,t)),r},nd=function(n){return Ev(n,dt,!1)},Le=300,X=0,P=1,L=2,td=3,rd={},ud=(rd[X]={},rd[P]={},rd[L]={},rd[td]={},{}),ed=Pe(Le),cd=function(n,t,r,u){Jl=\nu,Y3(ed,function(){ed.Lr=t,ed.Cr=r,ch(n)})},C=function(n,t,r,u){return Jl&&Jl(n,t,r,u),r},D=function(n,t,r,u){s(u)&&(rd[n][t]=F2(t,r,u,[Xi()>>>0])),r!=F&&C(n,t,u)},id=function(n,t,r,u){r?rd[n][t]=F2(t,w2):u&&!1===r&&(rd[n][t]=F2(t,m2)),C(n,t,r)},od=function(n,t){return uu([n,t],function(n,t,r){return x(n,we(65535&t,2))},g)},fd=function(n,t,r){var u,e;r&&r.length&&(u=B1(r.sort().join(g)),e=x(b(r.length),we(u,4)),e=F2(t,F,e),rd[n][t]=e),r&&C(n,t,r,u)},ad=function(n){var t=j3(),r=$r(t,function(n){return me(n)}).join(g),\nu=F2(n,F,r);rd[P][n]=u,C(P,n,t,r)},_d=function(n,t,r){s(r)&&(rd[n][t]=r>25.5?F2(t,h,Gu(r)):F2(t,x2,r),C(n,t,r))},vd=function(n,t,r,u){var e;C(n,t,r),s(r)&&(e=Ur(u,r),rd[n][t]=e>=m?F2(t,g2,e):F2(t,H2,r,[Xi()>>>0]))},sd=function(n,t){var r=32767&n,u=65535&t;return r===u?we(32768|r,2):x(we(r,2),we(u,2))},ld=function(n,t){var r=Hr(n),u=br(n),e=xr(n),c=Fr(n),i=sd(r,u),o=sd(e,c);D(L,t,F,x(i,o)),C(L,t,[r,u,e,c])},dd=function(n,t){var r=yr(n);D(L,t,F,od(r.availLeft,r.availTop)),C(L,t,[r.availLeft,r.availTop])},\nhd=function(n,t,r){var u=v(function(){return c6(n,r)});u&&(D(L,t,F,od(u.xe,u.be)),C(L,t,[u.xe,u.be]))},pd=function(n,t){var r=Go(n),u=Jo(n),e=Qo(n),c=Ko(n),u=sd(r,u),i=sd(e,c);D(X,t,F,x(u,i)),C(X,t,[r,c,e,c])},yd=function(n){return we(Gu(1E3*n),6)},md=function(n){var t=b(n.length);return nu(n,function(n){t+=yd(n)}),t},wd=function(n,t){var r=br(n)-Hr(n),u=Fr(n)-xr(n);D(P,t,F,od(r,u)),C(P,t,[r,u])},gd=function(n,t){var r=bv(t),u=parseInt(\"\".concat(fr(r.Mn)).concat(fr(r.On)),2),r=b((63&r.Rn)<<2|u);D(X,\nn,F,r),C(X,n,u)},Hd=function(n){var t=Mv(),r=Iv(),u=x(b(t/15),b(r/15));D(X,n,F,u),C(X,n,[t,r])},xd=function(n,t){var r;t.length&&(r=[t[Pv],t[Xv],t[jv]],D(X,n,F,N1(r)),C(X,n,lu(r)))},bd=function(n,t){var r;t&&t.length&&(r=we(parseInt($r(t,ye).join(g),2),2),D(X,rs,F,r),C(X,n,t))},Fd=function(n,t){var r=[o2(),yf(n),Df(n),pf(n),vv(n),Lf(n),df(n),lf(n),sf(n),A1(n),vf(n),_f(n)];D(X,t,F,N1(r)),C(X,t,lu(r))},Td=function(n,t){var r=[av(n),_v(n),lv(n),dv(n),pv(n),hv(n),yv(n),mv(n)];D(X,t,F,N1(r)),C(X,t,lu(r))},\njd=function(n,t){var r=h3(n),r=(Q5(n),[v(function(){return nd(n)}),!f5&&!Za(Wa)&&v(function(){return $6(n)}),E3(n),S3(n),r.rt,r.ut,r.et,wv(n),c3(n),v(function(){return o3(n)}),a3(n),_3(n),s3(n),v(function(){return r3(n)}),vv(n)==w]);D(P,t,F,N1(r)),C(P,t,lu(r))},Xd=vn(388),Pd=vn(389),s0=vn(390),Ld=vn(391),Cd=vn(392),Dd=vn(393),Ed=\"\".concat(Ro,\" \").concat(Xd,\"v8l\"),Sd=vn(394),Rd=\"\".concat(Ro,\" \").concat(Xd,\"v81\"),Md=\"\".concat(Ro,\" \").concat(s0,\"64\"),Od=\"\".concat(Ro,\" \").concat(Pd,\"_64\"),Id=\"\".concat(Ro,\n\" \").concat(Xd,\"v7l\"),kd=vn(395),Wd=vn(396),qd=vn(397),Vd=vn(398),zd=vn(399),Zd=vn(400),Bd=vn(401),Nd=vn(402),Ud=vn(403),Ad=vn(404),Gd=vn(405),Qd=vn(406),Jd=vn(407),O=vn(408),Ht=vn(409),M=vn(410),l0=vn(411),Re=vn(412),n=vn(413),Le=vn(414),Pe=vn(415),Kd=function(n){return n.slice(2)},Yd=function(n){return x(Kd(n),\"-\",n.slice(2,4))},$d=[\"\".concat(O,\"/\").concat(M),\"\".concat(O,\"/\").concat(l0),\"\".concat(O,\"/\").concat(Re),\"\".concat(O,\"/\").concat(n),\"\".concat(O,\"/\").concat(Le),\"\".concat(Ht,\"/\").concat(Pe)],\nnh=[\"\".concat(Yd(kd),\",\").concat(Kd(kd)),\"\".concat(Yd(kd)),\"\".concat(Yd(Vd),\",\").concat(Kd(Vd),\",\").concat(Yd(kd),\",\").concat(Kd(kd)),\"\".concat(Yd(Wd),\",\").concat(Kd(Wd)),\"\".concat(Yd(Nd),\",\").concat(Kd(Nd))],th={Xe:i(54),Pe:i(55),Le:i(56),Ce:i(57)},rh=\"20181001000000\",uh=[\"20030107\",\"20100101\"],eh=vn(416),ch=function(u){var e,c=W1(),n=(vd(X,T2,Vo(u),[Ld,Cd,Dd,Ed,Sd,Rd,Md,Od,Id]),vd(X,j2,zo(u),[Do,Eo]),vd(X,X2,Uo(u),[Yd(kd),Yd(Wd),Yd(qd),Yd(Vd),Yd(zd),Yd(Zd),Yd(Bd),hu(Yd(kd)),hu(Yd(zd)),Yd(Nd),Yd(Ud),\nYd(Ad),Yd(Gd),Yd(Qd),Yd(Jd)]),_d(X,P2,$o(u)),pd(u,L2),D(X,C2,h,Ao(u)),D(X,D2,h,Yo(u)),_d(X,E2,uv(u)),Hd(S2),fd(X,R2,v(function(){return tf(u)})),fd(X,M2,v(function(){return cf(u)})),Fd(u,O2),ah(X,I2,Bo(u),512),f(fl(u)).i(function(n){D(L,Os,F,N1(vu(n))),C(L,Os,n)}),f(v(function(){return pl(u)})).i(function(n){n&&(D(L,Is,h,n.Rr),D(L,ks,h,n.Mr),D(L,Ws,h,n.Or),D(L,qs,h,n.Ir))}),f(v(function(){return ml(u)})).i(function(n){n&&f(wl(n)).i(function(n){D(L,Vs,F,md(n)),C(L,Vs,$r(n,function(n){return fe(n,3)}))})}),\nid(L,zs,v(function(){return yl(u,c.Dn)}),!0),id(td,y4,v(function(){return xl(u)})),D(td,H4,h,v(function(){return bl(u)})),J3(ed,Fl,[u],function(n){D(td,g4,h,n)}),J3(ed,Tl,[u],function(n){D(td,w4,h,n)}),f(v(function(){return jl(u)})).i(function(n){id(td,m4,n,!0)}),f(v(function(){return gl(u)})).i(function(n){var t;n&&(t=[n.Jr,n.Qr,n.Gr,n.Ar],D(L,Zs,F,N1(t)),C(L,Zs,t),vd(L,Bs,n.Kr,th.Xe))}),f(v(function(){return Ul(u)})).i(function(n){n&&f(Al(n)).i(function(n){D(L,Ns,F,md(n)),C(L,Ns,n)})}),f(v(function(){return u6(u,\nc.Dn)})).i(function(n){var t;n&&(t=[n.we,n.me,n.se,n.ye,n.pe,n.he,n.de,n.le],D(L,Us,F,N1(t)),C(L,Us,t))}),f(v(function(){return e6(u)})).i(function(n){n&&(vd(L,Qs,n.ge,th.Pe),D(L,Js,h,n.He))}),ld(u,As),dd(u,Gs),hd(u,Ks,c.Dn),f(v(function(){return t6(u)})).i(function(n){n&&(D(L,Ys,F,yd(n)),C(L,Ys,n))}),ih(),J3(ed,Zl,[u],function(n){n&&(D(L,$s,H2,n.ie),D(L,n4,h,n.oe),D(L,t4,h,n.fe),D(L,r4,h,n.ae),vd(L,u4,n.ee,ql))}),J3(ed,kl,[u],function(n){n&&(vd(td,o4,n.Uu,th.Ce),vd(td,f4,n.Au,th.Le),D(td,a4,h,n.Gu),\nid(td,_4,n.Qu,!0),D(td,v4,H2,n.Ju),D(td,s4,F,yd(n.Ku)),C(td,s4,n.Ku))}),J3(ed,Wl,[u],function(n){n&&(D(L,c4,H2,n.Yu),D(td,i4,h,n.$u))}),J3(ed,Bl,[u],function(n){n&&D(L,e4,h,n)}),v(function(){return U_(u)})),i=(n&&(D(X,k2,H2,n.En),D(X,Z2,H2,n.Sn)),v(function(){return S_(u)})),n=(D(X,B2,H2,i),id(X,q2,af(u),!0),id(X,V2,v(function(){return of(u)})),vd(X,z2,Zo(u),uh),D(X,N2,H2,bf()),D(X,A2,h,n_(u)),vd(X,G2,hf(u),[rh]),c2()),o=(D(X,Q2,h,n.In),vd(X,J2,n.kn,[f2,a2,_2]),vd(X,K2,n.Wn,[p2,y2,h2]),D(X,Y2,h,n.qn),\ngd($2,u),vd(X,ns,i2(),[v2,s2,l2,d2]),fd(X,ts,Wv(u)),bd(rs,r2(u)),J3(ed,Sv,[u],function(n){xd(W2,n)}),D(P,us,g2,a1),vd(P,es,Tf(),$d),vd(P,cs,Pf(u),nh),D(P,gs,H2,jf()),fh(fs),u3(u)&&J3(ed,e3,[u],function(n){id(P,ls,n)}),id(P,as,I3(u)),oh(u),D(P,_s,h,r_()),D(L,Es,h,v(function(){return kv(u)})),W3(u)),n=(o&&D(P,is,H2,fo),D(L,Ss,h,v(function(){return xi(Xi())[eh]()})),D(td,p4,H2,v(function(){return Nl(u)})),D(L,Rs,H2,mr(u).hostname),G5(u),il(u,function(n){try{f(v(function(){return Rl(n)})).i(function(n){var t;\nn&&(t=[n.zu,n.Vu,n.Nu,n.Bu],D(td,x4,F,N1(t)),C(td,x4,t),D(td,b4,H2,n.Zu.join(\",\")))});var t,r=pr(n),u=(Q5(n),v(function(){return q3(n)}),J5(n,r,c.Cn,c.Dn),Z5()),e=(D(P,os,h,u.total),ad(ws),o||(t=v(function(){return B3()}),D(P,is,H2,t)),[o5,f5,v(function(){return nv(n)}),v(function(){return L3(n)}),v(function(){return P3(n)}),v(function(){return X3(n)}),v(function(){return C3(uf(n),nf(n))}),D3(n),v(function(){return i3(n,U5(),c.Cn,c.Dn)}),v3(),R3()]);D(P,vs,F,N1(e)),C(P,vs,lu(e)),f(Pl(n)).i(function(n){var t=\nLl(n),t=(D(td,l4,F,N1(vu(t))),C(td,l4,t),Yr(t).length);D(td,d4,h,t),id(td,h4,n.mu)})}finally{K5()}J3(ed,q6,[n],function(n){fd(P,ys,n)})}),c.Xn?[function(){return p6(u,c.Xn)},{Er:1200,Fe:!1}]:[function(){return m6(ol)},{Er:1E3,Fe:!1}]);J3(ed,h6,n,function(n){var t,r;n.Te?\"p\"in n.Te?(r=n.Te,r=[l6(r,i),s6(r,Xf(u)),v6(r,Uo(u)),d6(r,$o(u)),_6(r,Yo(u)),a6(r,Vo(u)),f6(r,Bo(u)),o6(r),i6(r)],D(P,ds,F,N1(r)),C(P,ds,lu(r))):\"he\"in n.Te&&(t=n.Te.he,r=[bo,To,jo,Fo,Xo,Po],r=!!t&&Qr(r,function(n){return t[n]===\ng}).length===r.length,id(P,Fs,r,!0),t)&&(vd(P,js,t[bo],[Xd,Pd]),D(P,Xs,H2,t[To]),D(P,Ps,H2,t[Po]),r=[\"64\"===t[Fo],\"32\"===t[Fo],t[Xo],t[Lo]],D(P,Ts,F,N1(r)),C(P,Ts,lu(r)),vd(L,Ls,t[Vi],[Wo,So,Mo,Ro,Oo,Io]),D(L,Cs,H2,t[jo]),r=K1(t),vd(L,Ds,r,Y1)):(r=lu([n.je,n.Er]),D(P,Hs,F,N1(r)),C(P,Hs,r))},{Sr:2}),o_()&&c.Pn&&(e=200,h6(function(){return p6(u,c.Pn)},{Er:e,Fe:!0},function(n){var t,r;n.Te?(r=n.Te,s(r.t)&&(t=Qu(r.t))):n.Er&&(t=e),D(P,bs,h,t)})),J3(ed,S6,[u],function(n){id(P,ps,n,!0)}),K6(u,function(n){var t=\nlu(tu(Q6()));D(P,ms,F,N1(t)),C(P,ms,t)})},ih=function(){ah(L,Ms,Du(ud),2048)},oh=function(n){var t=rf(n);t&&J3(ed,f3,[t],function(n){id(P,ss,n,!0)})},fh=function(n){var t=tu(X4());D(P,n,F,N1(t)),C(P,n,t)},ah=function(n,t,r,u){s(r)&&(D(n,t,F,gi(r,[t,Xi()>>>0],u)),C(n,t,r))},_h=function(){return tu(rd[X])},vh=function(){return tu(rd[P])},sh=function(){return tu(rd[L])},lh=function(){return tu(rd[td])},dh=!1,hh=function(n){dh||(Td(n,U2),jd(n,hs),wd(n,xs),dh=!0)},ph=function(n){return!n.De||!!n.Se.Ee||\n!!n.Se.Re},yh=function(n){return!!n.De&&n.Se.Ee},mh=function(n){return!!n.De&&n.Se.Re},wh=function(n){return n.Me==nt},gh=function(n,t){return!n||t.Oe!=n.Oe||t.De!=n.De},Hh=function(n,t){return!!n&&t.Ie!=n.Ie},xh=function(n){return n.key||String.fromCharCode(n.charCode||n.keyCode)},bh=function(n){switch(xh(n)){case ln:case hn:case dn:case pn:case Q:case K:case J:case Y:return!0;default:return!1}},Fh=function(n,t){return t.nodeName?hu(t.nodeName):t===n?nt:t===pr(n)?tt:void 0},Th=function(n){return n.target||\nn.srcElement},jh=function(n){var t={};switch(n+\"\"){case B:case un:t.ke=!0;break;case N:case en:t.We=!0;break;case U:case cn:t.qe=!0;break;case A:case on:t.Ee=!0;break;case G:case fn:t.Re=!0;break;case $:case nn:case tn:case rn:case an+\"Left\":case an+\"Up\":case an+\"Right\":case an+\"Down\":t.Ve=!0}return t},Xh=function(n){return Pu(xh(n))},Ph=function(n){var t={};return n.altKey&&(t.ze=!0),n.metaKey&&(t.Ze=!0),n.ctrlKey&&(t.Be=!0),n.shiftKey&&(t.Ne=!0),n.getModifierState&&n.getModifierState(_n)&&(t.Ue=\n!0),t},Lh=function(n,t){var r,u={};return t&&(r=t.name||t.id,r)&&(u.Oe=je(ju(r))),u},Ch=function(n,t){var r,u=Lh(n,t);return t&&(u.Me=Fh(n,t),r=t.type,Br(r))&&(u.De=hu(r)),u},Dh=function(n,t){return Ch(n,Th(t))},s0=function(n,t){return Lh(n,Th(t))},Eh=/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/,Sh=/(\\+\\d{1,3}\\s?)?(\\(\\d{3}\\)|\\d{3})[\\s.-]?\\d{3}[\\s.-]?\\d{4}|^\\+[1-9]\\d{1,14}$/,Rh=/\\b(?!000|666|9\\d{2})([0-8]\\d{2}|7([0-6]\\d|7[012]))([-]?)\\d{2}\\3(?!0000)\\d{4}\\b/,Mh=/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\\d{3})\\d{11})$/,\nM=function(n,t){var r,u,e=Dh(n,t);return t.clipboardData&&t.clipboardData.getData&&(r=t.clipboardData.getData(\"text/plain\"),u={},u.Ae=Eh.test(r),u.Ge=Sh.test(r),u.Qe=Rh.test(r),u.Je=Mh.test(r),e.Se=u),e},l0=function(n,t){var r=Dh(n,t),u=Ph(t),u=hr(u,jh(t.code||t.keyCode||t.which));return Xh(t)&&(u.Ke=!0),r.Se=u,r},Re=0,n=1,O=2,Le=3,Ht=4,Pe=5,Oh=6,Ih=7,kh=8,Wh=9,qh=10,Vh=11,zh=12,Zh=13,Bh=14,Nh=15,Uh=16,Ah=17,Gh=18,Qh=19,Jh=20,Kh=21,Yh=22,$h=23,n7=24,t7=25,r7=26,u7=27,e7=511,c7=63,E=63,i7=E,o7=c7,\nS={Ye:[],$e:m,nc:w,tc:m,rc:!1},f7=(E={},E[n]={uc:s0,ec:i(58)},E[O]={uc:s0,ec:i(59)},E[Le]={uc:M,ec:i(60)},E[Ht]={ec:i(61)},E[kh]={ec:i(62)},E[Wh]={uc:Dh,ec:i(63)},E[qh]={ec:i(64)},E[Vh]={ec:i(65)},E[zh]={ec:i(66)},E[Re]={uc:Dh,ec:i(67)},E[Zh]={uc:Dh,ec:i(68)},E[Bh]={uc:Dh,ec:i(69)},E[$h]={cc:function(n,t){return yh(t)||mh(t)},uc:l0,ec:i(70)},E[Oh]={uc:Dh,ic:!0,ec:i(71),cc:function(n,t){return wh(t)}},E[Pe]={uc:Dh,ic:!0,ec:i(72),cc:function(n,t){return wh(t)}},E[Ih]={uc:Dh,ec:i(73)},E[Nh]={ic:!0,ec:i(74)},\nE[Uh]={ic:!0,ec:i(75)},E[Ah]={ic:!0,ec:i(76)},E[Gh]={cc:function(n,t){return!!G6(n)},uc:s0,ec:i(77)},E[Qh]={cc:function(n,t){return!ph(t)},uc:l0,ec:i(70)},E[Kh]={ec:i(78),oc:10},E[Jh]={ec:i(79),oc:10},E[n7]={cc:function(n,t,r){return pr(r).hidden},ec:i(80)},E[t7]={cc:function(n,t,r){return f(\"html\"===Fh(r,Th(n))).i(function(){S.rc=!0}).o()},ec:i(81)},E[r7]={cc:function(n,t,r){return f(S.rc&&\"html\"===Fh(r,Th(n))).i(function(){S.rc=!1}).o()},ec:i(82)},E[u7]={oc:1,ic:!0,ec:i(83)},E),a7=1E3,_7=function(n){var t;\nS.$e=0,(null===(t=S.nc)||void 0===t?void 0:t.Ie)===n.Ie&&(S.$e=S.tc)},v7=function(n){var t;S.$e++,(null===(t=S.nc)||void 0===t?void 0:t.Ie)===n.Ie&&S.tc++},s7=function(n){return S.nc?S.fc&&S.fc.Ie===S.nc.Ie?n.ac-S.fc.ac:n.ac-S.nc.ac:0},l7=function(n){var t=s7(n);t>a7&&S.Ye.push({Ie:Yh,ac:n.ac,Se:{_c:t}}),S.Ye.push(n),S.nc=n,S.tc=S.$e},d7=function(n){(gh(S.fc,n)||Hh(S.fc,n))&&_7(n),v7(n),1===S.$e?l7(n):S.nc.Se=hr(S.nc.Se,n.Se)},h7=function(n,t){Hh(S.fc,n)&&_7(n),v7(n),S.$e===t.oc&&l7(n)},p7=function(n){_7(n),\nl7(n)},y7=function(n,t,r,u){try{var e,c;bh(r)||(e=f7[t],c={Ie:t,ac:r.timeStamp},e.uc&&(c=hr(c,e.uc(n,r))),e.cc&&!e.cc(r,c,n))||(t==Qh?d7(c):t==Kh||t==Jh||t==u7?h7(c,e):p7(c),S.fc=c)}catch(i){u&&u(i)}},m7=function(){return S.Ye},w7=function(u,e){var c=pr(u);nu(ru(f7),function(t){var n=f7[t],r=n.ic?u:c;nu(n.ec,function(n){Je(r,n,function(n){y7(u,t,n,e)})})})},c7=function(n){var t=m,r=n.Se;return r&&(r.Ae&&(t|=1),r.Ge&&(t|=2),r.Je&&(t|=4),r.Qe)&&(t|=8),[t]},n=function(n){var t=m,r=n.Se;return r&&(r.Ee&&\n(t|=1),r.Re)&&(t|=2),[t]},O=function(n){var t=m,r=m,u=n.Se;return u&&(u.Be&&(t|=1),u.ze&&(t|=2),u.Ne&&(t|=4),u.Ze&&(t|=8),u.Ue&&(t|=16),u.Ke&&(t|=32),u.ke&&(r|=1),u.We&&(r|=2),u.qe&&(r|=4),u.Ve)&&(r|=8),[t,r]},M=function(n){var t;return n.Se?(t=~~(n.Se._c/1E3),[t>Qt?Qt:t]):[m]},g7=(sn={},sn[Le]=c7,sn[$h]=n,sn[Qh]=O,sn[Yh]=M,sn),Ht=vn(417),kh=vn(418),H7=Dt(Ht),x7=Dt(kh),b7=function(t,n,r){return cr(n)?r:f(hu(n)).u(function(n){return n in t?t[n]:r}).o()},F7=function(r){var n=r.Ie,t=g7[n],u=!!t,e=!!r.Me,\nc=e&&!!r.De,i=e&&s(r.Oe);return u&&(n|=64),e&&(n|=128),f([n]).i(function(n){var t;e&&(t=b7(x7,r.Me,i7),t=63&t,c&&(t|=64),i&&(t|=128),n.push(t),c)&&(t=b7(H7,r.De,o7),n.push(t))}).u(function(n){return u?cu(n,t(r)):n}).i(function(n){i&&n.push(255&r.Oe)}).u(function(n){return xe(n)}).o()},T7=0,j7=function(n){return n.splice(0,n.length-e7),b(T7)+we(n.length,2)+$r(n,function(n){return F7(n)}).join(\"\")},X7=[0,4,7,8],P7=function(n){return we(n<<12|f1,2)},L7=function(n,t,r,u){return f(2).u(function(n){return H1<<\n20|n<<16|65535&be(t,16)}).u(function(n){return x(we(n,3),We(r),xe(u),b(u.length))}).o()},C7=function(n,t){return we((2047&n)<<5|31&t,2)},D7=202116108,E7=function(u){return uu(u,function(n,t,r){return n.push(C7(X7[r],u[r].length)),cu(n,u[r])},[]).join(g)},S7=function(u,e){return f(f(bi()).i(function(n){return hh(u)}).u(function(n){return Ze(qe(n),Ve(n))}).i(function(n){return Kl=b(ve(Qt+1))}).o()).u(function(n){return[n,j7(m7())]}).u(function(n){var t=n[0],r=n[1];return x(f(Xi()).u(function(n){return Ze(qe(n),\nVe(n))}).o(),P7(X7.length),b1(!0),e,pc(x(t,pc(x(E7([_h(),vh(),sh(),lh()]),we(r.length/2,2),r,L7(u,n1(),t1(),o1()),b(255)),t,4,wu(t,3))),e,8,wu(e,9)))}).u(function(n){return f(He(n)).u(function(n){return[n.length,Fe(gc(n,[tr,rr,D7,ur]))]}).u(function(n){return x(g1,b(n[1].length-n[0]),xe(n[1]))}).o()}).u(function(n){return Z1(u,ge(x(Kl,Xe(x(n,b(n.length)),Kl))))}).o()},R7=function(){return Yl},M7=function(n){n&&/\\S+\\.\\S{2,}$/.test(n)&&(Yl=n)},O7={},I7=!1,k7=!1,W7=[],q7=function(n,t,r,u){tc(n,t,r,u||\nKt)},V7=function(n,t,r,u,e){var c=0,i=R7()||mr(n).hostname,o=i.split(\".\"),f=1===o.length;while(c<o.length-1||f){var a=o.slice(-1-++c).join(\".\"),a=a?\"domain=\".concat(a,\";\"):g;Or(n,t,r,\"expires=\".concat(u,\";\").concat(a)),f=!1}},z7=function(n,t,r){var u=W1(),u=\"\".concat(Fi(u.wn.Hn));V7(n,t,r,u)},Z7=function(n,t){return rc(n,t)||Ir(n,t)},B7=function(n){var t=W1(),t=Z7(n,t.wn.gn);ki(t)||(t=Ii(n)),J7(n,{vc:t}),I7=!0},N7=function(){return k7},U7=function(n,t){W7.push(t)},A7=function(n){var t=W1();if(!t.bn)throw h1;\nif(I7){k7=!0;for(var r=W7.length,u=0;u<r;u++){n8(n);var e=G7().sc;W7[u](e)}}},G7=function(){return O7[s1]},Q7=function(n){O7[s1]=n},J7=function(n,t){Q7(t);var r=W1();r.hn?q7(n,r.wn.gn,t.vc,function(){return z7(n,r.wn.gn,t.vc)}):(z7(n,r.wn.gn,t.vc),q7(n,r.wn.gn,t.vc))},K7=function(n){return G7()||$7(n,Ii(n))},Y7=function(n){return I7?K7(n).sc:w},$7=function(n,t){var r=W1().bn?S7(n,t):g;return f({vc:t,sc:r}).i(function(n){return Q7(n)}).o()},n8=function(t){return f(G7()).u(function(n){return n?$7(t,\nn.vc):w}).o()},t8=function(n){Q0(n,Af,ta)},r8=function(n){var r,u=\"pending\",e=[],t=function(){while(e.length)c(e.shift())},c=function(n){if(\"pending\"===u)e.push(n),void 0;else try{\"fulfilled\"===u?n.resolve(n.onFulfilled?n.onFulfilled(r):r):\"rejected\"===u&&n.resolve(n.onRejected?n.onRejected(r):r)}catch(t){n.reject(t)}},i=function(n){\"pending\"!==u||(u=\"fulfilled\",r=n,t())},o=function(n){\"pending\"!==u||(u=\"rejected\",r=n,t())},f=function(n,t){var r=r8(function(n,t){});return c({onFulfilled:n,onRejected:t,\nresolve:r.resolve,reject:r.reject}),r},a=function(n){return f(undefined,n)},_=function(t){return f(function(n){return t&&t(),n},function(n){throw t&&t(),n;})};try{n(i,o)}catch(v){o(v)}return{then:f,\"catch\":a,\"finally\":_,resolve:i,reject:o}},u8=function(r){return r8(function(n,t){return n(r)})},e8=vn(419),c8=vn(420),i8=\"name\",o8=function(n,t){if(typeof FormData==typeof w)return{};for(var r=new FormData(t),u={},e=0,c=t.querySelectorAll(\"[\".concat(e8,\"]\"));e<c.length;e++){var i=c[e],o=Lr(i,e8),i=Lr(i,\ni8),i=r.get(i);s(i)&&(u[o]=g+i)}return{name:Lr(t,c8),values:u}},Wh=function(u,e,c){var i=undefined,o=null;return function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];var r=function(){if(o=null,!c)return i=u.apply(null,n),i};return null!=o&&clearTimeout(o),c?i=u.apply(null,n):o=setTimeout(r,e),i}},f8=\"POST\",a8=\"withCredentials\",_8=4,qh=300,v8=function(){try{var n;if(typeof XMLHttpRequest!==typeof w)return n=new XMLHttpRequest,a8 in n?n:void 0}catch(t){}},s8=function(n,t,r){if(r.lc&&\n(clearTimeout(r.lc),r.lc=w),cr(r.dc))for(var u=n.length,e=0;e<u;e++)n[e](t);r.dc=t},l8=function(n,t){n.send(t)},d8=Wh(l8,qh),h8=vn(421),p8=vn(422),y8=function(n,t,r,u,e,c){var i,o,f=v8();return f&&f.setRequestHeader?(f.open(f8,t,!0),i={dc:w,lc:w},o=[],f.setRequestHeader(\"Content-Type\",\"application/\".concat(p8)),f.setRequestHeader(h8,r),f.onreadystatechange=function(){var n;f.readyState===_8&&(n=f.status,s8(o,n>=200&&n<400,i))},u(function(n){i.lc=setTimeout(function(){s8(o,p,i),f.abort()},c),e(f,Du(n))}),\nr8(function(n,t){i.dc!==w?n(i.dc):o.push(n)})):u8(!1)},m8=0,w8=1,g8=2,H8=4,x8=5,b8=3,F8=function(n){return Br(n)?n:Du(n)},T8=function(n,t,r,u,e,c){return j8(t,r,u,e,e,c)+we(n.length,b8)+pe(n)},j8=function(n,t,r,u,e,c){for(var i=[],o=c?gi:wi,f=m;f<r.length;f++){var a=r[f],_=Ur(u,a)>=m,v=Ur(e,a)>=m,s=H(t,a)&&er(t[a]);if(s||_){var l=void 0;if(_){_=s?t[a]:v?{}:w;if(cr(_))continue;for(var d=ou(_),s=ru(d).slice(m,Qt),l=b(s.length),h=0,p=s;h<p.length;h++){var y=p[h];l+=wi(F8(y),w),l+=wi(F8(d[y]),w)}}else l=\no(F8(t[a]),w);i.push(b(f)+l)}}return x(b(n),b(i.length),i.join(g))},X8=\"id\",P8=\"email\",L8=\"phone\",C8=\"registered_at\",D8=\"traits\",E8=\"signature\",S8=\"address\",R8=\"name\",M8=function(n){return j8(m8,n,[X8,P8,L8,C8,D8,E8,R8,S8],[D8,S8],Yt,!1)},O8=vn(423),I8=function(n){return j8(H8,n,[O8],Yt,Yt,!0)},k8=3,W8=function(t,r,u,n){var e=b(ve(Qt+1)),c=ze(qe(bi()));return f(n).u(function(n){return x(u,b(n.length),n.join(g))}).u(function(n){return pc(x(n,b(n.length&Qt)),c,4,wu(c,3))}).u(function(n){return pc(x(c,\nn),de(r.slice(3)),8,de(r[12]))}).u(function(n){return Xe(x(b((15&k8)<<4),n),e)}).u(function(n){return Z1(t,ge(x(e,n)))}).o()},q8=\"url\",V8=\"name\",z8=\"referrer\",Z8=function(n,t,r,u){return W8(n,t,u.userJwt?I8({jwt:u.userJwt}):M8(u.user),[T8(r,w8,u,[V8,q8,z8],Yt,!1)])},B8=function(u,n,e){var c,i,o,t,f=W1();if(f.bn)return s(e)&&(s(e.user)||s(e.userJwt))?(c=H(e,q8)?e[q8]:mr(u).href,i=H(e,V8)?e[V8]:pr(u).title||c,o=H(e,z8)?e[z8]:pr(u).referrer,t=function(r){return n.then(function(n){var t=Z8(u,f.bn,n,{user:e.user,\nuserJwt:e.userJwt,name:i,url:c,referrer:o});r({data:t})})},y8(u,f.yn,f.bn,t,d8,f.mn)):(f.pn&&fc(u,ic,p1),u8(!1));throw h1;},N8=\"name\",U8=\"values\",A8=function(n,t,r,u){return W8(n,t,u.userJwt?I8({jwt:u.userJwt}):M8(u.user),[T8(r,g8,u,[N8,U8],[U8],!1)])},G8=0,Q8=300,J8=function(u,n,e){var t,r,c=W1();if(c.bn)return s(e)&&(s(e.user)||s(e.userJwt))&&s(e.name)?(t=bi(),t-G8<Q8?u8(!1):(r=function(r){return n.then(function(n){var t=A8(u,c.bn,n,e);r({data:t})})},G8=t,y8(u,c.yn,c.bn,r,l8,c.mn))):(c.pn&&fc(u,\nic,p1),u8(!1));throw h1;},K8=\"name\",Y8=\"properties\",$8=function(n){return n.userJwt?I8({jwt:n.userJwt}):M8(n.user)},n9=function(n,t){return T8(n,x8,t,[K8,Y8],[Y8],!1)},t9=function(n,t,r,u){return W8(n,t,$8(u),[n9(r,u)])},r9={},u9=function(n){$l=n},e9=function(n){var t=r9[n];return t.hc&&(t=t.hc-bi(),t>0)?t:0},c9=function(r,u){return function(n){var t=r9[r],t=(t.yc=t.H.splice(0,w1),$r(t.yc,function(n){return n9(n.sc,n.mc)})),t=W8($l,u,r,t);n({data:t})}},i9=function(r){var t=r9[r];if(t.wc)return r8(function(t,\nn){setTimeout(function(){i9(r).then(function(n){t(n)})},m1)});if(t.gc)return u8(t.Hc);t.wc=!0,t.gc=!1,t.Hc=w;var n=W1();return y8($l,n.yn,n.bn,c9(r,n.bn),l8,n.mn).then(function(n){return t.wc=!1,t.gc=!0,t.Hc=n,n})},o9=function(u){var e=r9[u],c=e9(u);return 0===c&&(e.hc=bi()+m1),r8(function(t,n){var r=function(){i9(u).then(function(n){e.yc.pop(),0===e.yc.length&&(e.gc=!1,e.Hc=w,e.wc=!1),t(n)})};0===c?r():setTimeout(function(){r()},c)})},f9=function(n){r9[n.xc]||(r9[n.xc]={H:[],yc:[],hc:0});var t=r9[n.xc];\nreturn t.H.push({mc:n.mc,sc:n.sc}),o9(n.xc)},a9=function(n){return!s(n)||!(s(n.user)||s(n.userJwt))||!s(n.name)},_9=function(u,e,c){var r,n,i=W1();if(i.bn)return a9(c)?(i.pn&&fc(u,ic,p1),u8(!1)):i.xn?(r={then:function(t,n){return e.then(function(n){f9({xc:$8(c),mc:c,sc:n}).then(function(n){return t(n)})}),r}},r):(n=function(r){return e.then(function(n){var t=t9(u,i.bn,n,c);r({data:t})})},y8(u,i.yn,i.bn,n,l8,i.mn));throw h1;},v9=function(n,t){for(var r=W1(),u=r.Ln||v1,e=0,c=t.childNodes;e<c.length;e++){var i=\nc[e];if(Lr(i,\"name\")===u)return i}r=Er(n,\"input\");return Pr(r,\"type\",\"hidden\"),Pr(r,\"name\",u),Cr(t,r),r},s9=function(n){return typeof n.submit!==typeof w&&Vr(n.submit)?n.submit():typeof HTMLFormElement!==typeof w&&HTMLFormElement.prototype&&Vr(HTMLFormElement.prototype.submit)?HTMLFormElement.prototype.submit.call(n):void 0},l9=function(o){var f={createRequestToken:function(){return r8(function(n,t){N7()?(n8(o),n(Y7(o))):U7(o,n)})},page:function(n){return B8(o,f.createRequestToken(),n)},form:function(n){return J8(o,\nf.createRequestToken(),n)},custom:function(n){return _9(o,f.createRequestToken(),n)},formEventOnSubmit:function(n,t,r,u){if(!n.preventDefault)return!u||(u(n,null),void 0);n.preventDefault();var e=n.target||n.srcElement,c=function(t){r&&r.injectToken?f.injectTokenOnSubmit(n,function(n){return u?u(n,t):s9(e)}):u?u(n,t):s9(e)},i=hr(Br(t)?{userJwt:t}:{user:t||{}},o8(o,e));f.form(i).then(c)},injectTokenOnSubmit:function(t,r){t.preventDefault?t.preventDefault():t.returnValue=!1;var u=t.target||t.srcElement;\nf.createRequestToken().then(function(n){Pr(v9(o,u),\"value\",n),r?r(t):s9(u)})}};return f},d9=function(){if(n6)return n6;throw y1;},h9=function(n){n6=l9(n)},p9=\"submit\",y9=\"form\",m9=\"action\",w9=function(n,t){try{var r;return!!n&&(r=Br(n)?n:n.toString(),!Cu(r,\"://\")||(r.split(\"/\")[2]+\"\").split(\":\")[0]===mr(t).hostname)}catch(sn){return!1}},g9=function(n){try{var t;n.dataset&&n.dataset._cstlForm||(n.dataset._cstlForm=\"true\",t=Lr(n,m9),t&&Je(n,p9,function(n){return d9().injectTokenOnSubmit(n)},!0))}catch(sn){}},\nH9=function(n){var t=pr(n).getElementsByTagName(y9);nu(t,function(n,t){g9(n)})},x9=function(n){var t;typeof MutationObserver!==typeof w&&(t=new MutationObserver(function(n){nu(n,function(n){var t=n.addedNodes;nu(t,function(n){try{var t;1!==n.nodeType||(hu(n.tagName)===y9?g9(n):(t=n.getElementsByTagName&&n.getElementsByTagName(y9),t&&t.length&&nu(t,function(n){g9(n)})))}catch(sn){}})})}),t.observe(gr(n),{childList:!0,subtree:!0}))},b9=function(e){var c,i;typeof XMLHttpRequest===typeof w||(c=XMLHttpRequest.prototype.open,\ni=XMLHttpRequest.prototype.send,XMLHttpRequest.prototype.open=function(n,t,r,u,e){try{this._cstl_url=t}finally{return c.apply(this,arguments)}},XMLHttpRequest.prototype.send=function(t){var r=this,n=arguments;try{var u=r._cstl_url;return w9(u,e)?d9().createRequestToken().then(function(n){r.setRequestHeader(_1,n),i.call(r,t)}):i.apply(r,n)}catch(sn){return i.apply(r,n)}})},F9=function(i){var o;Vr(i.fetch)&&(o=i.fetch,i.fetch=function(u,e){try{e=e||{};var n=Br(u),t=zr(u)&&\"url\"in u,r=n?u:t?u.url:null;\nreturn w9(r,i)?d9().createRequestToken().then(function(n){var t;try{e.headers&&\"set\"in e.headers?e.headers.set(_1,n):e.headers=hr(e.headers||{},(t={},t[_1]=n,t))}catch(r){}return o(u,e)})[\"catch\"](function(n){return o(u,e)}):o(u,e)}catch(c){return o(u,e)}})},T9=!0,j9=w,Vh=function(n,t){return d9().injectTokenOnSubmit(n,t)},zh=function(){return d9().createRequestToken()},X9=function(r){cl(r),T4(r),ji(),nu([h9,u9],function(n,t){return n(r)}),nu([Va,y0,n0],function(n,t){return n()}),t8(r),cd(r,function(){B7(r),\nA7(r)},function(){return n8(r)}),v(function(){return w7(r,u2)}),il(r,function(n){var t=W1();t.Tn&&(H9(n),x9(n)),t.jn&&(b9(n),F9(n))}),T9=!1},Re=function(n){var t,r=n||{};if(H(r,nt)&&(t=r.window),t||typeof window!==typeof w&&(t=window),!t)throw y1;if(H(r,\"storageNamespace\")&&F1(r.storageNamespace),H(r,\"storage\")&&P1(r.storage),H(r,\"autoInjectTokenOnSubmit\")&&j1(!!r.autoInjectTokenOnSubmit),H(r,\"autoInjectTokenOnRequest\")&&X1(!!r.autoInjectTokenOnRequest),H(r,\"avoidCookies\")&&C1(!!r.avoidCookies),H(r,\n\"cookieDomain\")&&M7(r.cookieDomain),H(r,\"eFn\")&&T1(r.eFn),H(r,\"wUrl\")&&R1(r.wUrl),H(r,\"dwUrl\")&&M1(r.dwUrl),H(r,\"formTokenInputName\")&&O1(r.formTokenInputName),H(r,\"dCss\")&&I1(r.dCss),H(r,\"eCss\")&&k1(r.eCss),H(r,\"pk\")&&q1(r.pk),H(r,\"apiUrl\")&&D1(r.apiUrl),H(r,\"timeout\")&&E1(r.timeout),H(r,\"verbose\")&&L1(!!r.verbose),H(r,\"throttling\")&&S1(r.throttling),T9){if(!W1().bn)throw h1;X9(t)}return j9},Zh=function(n,t,r,u){return d9().formEventOnSubmit(n,t,r,u)},Bh=function(n){return d9().page(n)},Oh=function(n){return d9().form(n)},\nPe=function(n){return d9().custom(n)},j9={formEventOnSubmit:Zh,page:Bh,form:Oh,custom:Pe,configure:Re,createRequestToken:zh,injectTokenOnSubmit:Vh};R.configure=Re,R.createRequestToken=zh,R.custom=Pe,R.form=Oh,R.formEventOnSubmit=Zh,R.injectTokenOnSubmit=Vh,R.page=Bh});\n", "var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar NodeType = /* @__PURE__ */ ((NodeType2) => {\n  NodeType2[NodeType2[\"Document\"] = 0] = \"Document\";\n  NodeType2[NodeType2[\"DocumentType\"] = 1] = \"DocumentType\";\n  NodeType2[NodeType2[\"Element\"] = 2] = \"Element\";\n  NodeType2[NodeType2[\"Text\"] = 3] = \"Text\";\n  NodeType2[NodeType2[\"CDATA\"] = 4] = \"CDATA\";\n  NodeType2[NodeType2[\"Comment\"] = 5] = \"Comment\";\n  return NodeType2;\n})(NodeType || {});\nconst testableAccessors = {\n  Node: [\n    \"childNodes\",\n    \"parentNode\",\n    \"parentElement\",\n    \"textContent\",\n    \"ownerDocument\"\n  ],\n  ShadowRoot: [\"host\", \"styleSheets\"],\n  Element: [\"shadowRoot\", \"querySelector\", \"querySelectorAll\"],\n  MutationObserver: []\n};\nconst testableMethods = {\n  Node: [\"contains\", \"getRootNode\"],\n  ShadowRoot: [\"getSelection\"],\n  Element: [],\n  MutationObserver: [\"constructor\"]\n};\nconst untaintedBasePrototype = {};\nconst isAngularZonePresent = () => {\n  return !!globalThis.Zone;\n};\nfunction getUntaintedPrototype(key) {\n  if (untaintedBasePrototype[key])\n    return untaintedBasePrototype[key];\n  const defaultObj = globalThis[key];\n  const defaultPrototype = defaultObj.prototype;\n  const accessorNames = key in testableAccessors ? testableAccessors[key] : void 0;\n  const isUntaintedAccessors = Boolean(\n    accessorNames && // @ts-expect-error 2345\n    accessorNames.every(\n      (accessor) => {\n        var _a, _b;\n        return Boolean(\n          (_b = (_a = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a.get) == null ? void 0 : _b.toString().includes(\"[native code]\")\n        );\n      }\n    )\n  );\n  const methodNames = key in testableMethods ? testableMethods[key] : void 0;\n  const isUntaintedMethods = Boolean(\n    methodNames && methodNames.every(\n      // @ts-expect-error 2345\n      (method) => {\n        var _a;\n        return typeof defaultPrototype[method] === \"function\" && ((_a = defaultPrototype[method]) == null ? void 0 : _a.toString().includes(\"[native code]\"));\n      }\n    )\n  );\n  if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n    untaintedBasePrototype[key] = defaultObj.prototype;\n    return defaultObj.prototype;\n  }\n  try {\n    const iframeEl = document.createElement(\"iframe\");\n    document.body.appendChild(iframeEl);\n    const win = iframeEl.contentWindow;\n    if (!win) return defaultObj.prototype;\n    const untaintedObject = win[key].prototype;\n    document.body.removeChild(iframeEl);\n    if (!untaintedObject) return defaultPrototype;\n    return untaintedBasePrototype[key] = untaintedObject;\n  } catch {\n    return defaultPrototype;\n  }\n}\nconst untaintedAccessorCache = {};\nfunction getUntaintedAccessor(key, instance, accessor) {\n  var _a;\n  const cacheKey = `${key}.${String(accessor)}`;\n  if (untaintedAccessorCache[cacheKey])\n    return untaintedAccessorCache[cacheKey].call(\n      instance\n    );\n  const untaintedPrototype = getUntaintedPrototype(key);\n  const untaintedAccessor = (_a = Object.getOwnPropertyDescriptor(\n    untaintedPrototype,\n    accessor\n  )) == null ? void 0 : _a.get;\n  if (!untaintedAccessor) return instance[accessor];\n  untaintedAccessorCache[cacheKey] = untaintedAccessor;\n  return untaintedAccessor.call(instance);\n}\nconst untaintedMethodCache = {};\nfunction getUntaintedMethod(key, instance, method) {\n  const cacheKey = `${key}.${String(method)}`;\n  if (untaintedMethodCache[cacheKey])\n    return untaintedMethodCache[cacheKey].bind(\n      instance\n    );\n  const untaintedPrototype = getUntaintedPrototype(key);\n  const untaintedMethod = untaintedPrototype[method];\n  if (typeof untaintedMethod !== \"function\") return instance[method];\n  untaintedMethodCache[cacheKey] = untaintedMethod;\n  return untaintedMethod.bind(instance);\n}\nfunction ownerDocument(n) {\n  return getUntaintedAccessor(\"Node\", n, \"ownerDocument\");\n}\nfunction childNodes(n) {\n  return getUntaintedAccessor(\"Node\", n, \"childNodes\");\n}\nfunction parentNode(n) {\n  return getUntaintedAccessor(\"Node\", n, \"parentNode\");\n}\nfunction parentElement(n) {\n  return getUntaintedAccessor(\"Node\", n, \"parentElement\");\n}\nfunction textContent(n) {\n  return getUntaintedAccessor(\"Node\", n, \"textContent\");\n}\nfunction contains(n, other) {\n  return getUntaintedMethod(\"Node\", n, \"contains\")(other);\n}\nfunction getRootNode(n) {\n  return getUntaintedMethod(\"Node\", n, \"getRootNode\")();\n}\nfunction host(n) {\n  if (!n || !(\"host\" in n)) return null;\n  return getUntaintedAccessor(\"ShadowRoot\", n, \"host\");\n}\nfunction styleSheets(n) {\n  return n.styleSheets;\n}\nfunction shadowRoot(n) {\n  if (!n || !(\"shadowRoot\" in n)) return null;\n  return getUntaintedAccessor(\"Element\", n, \"shadowRoot\");\n}\nfunction querySelector(n, selectors) {\n  return getUntaintedAccessor(\"Element\", n, \"querySelector\")(selectors);\n}\nfunction querySelectorAll(n, selectors) {\n  return getUntaintedAccessor(\"Element\", n, \"querySelectorAll\")(selectors);\n}\nfunction mutationObserverCtor() {\n  return getUntaintedPrototype(\"MutationObserver\").constructor;\n}\nfunction patch(source, name, replacement) {\n  try {\n    if (!(name in source)) {\n      return () => {\n      };\n    }\n    const original = source[name];\n    const wrapped = replacement(original);\n    if (typeof wrapped === \"function\") {\n      wrapped.prototype = wrapped.prototype || {};\n      Object.defineProperties(wrapped, {\n        __rrweb_original__: {\n          enumerable: false,\n          value: original\n        }\n      });\n    }\n    source[name] = wrapped;\n    return () => {\n      source[name] = original;\n    };\n  } catch {\n    return () => {\n    };\n  }\n}\nconst index = {\n  ownerDocument,\n  childNodes,\n  parentNode,\n  parentElement,\n  textContent,\n  contains,\n  getRootNode,\n  host,\n  styleSheets,\n  shadowRoot,\n  querySelector,\n  querySelectorAll,\n  mutationObserver: mutationObserverCtor,\n  patch\n};\nfunction isElement(n) {\n  return n.nodeType === n.ELEMENT_NODE;\n}\nfunction isShadowRoot(n) {\n  const hostEl = (\n    // anchor and textarea elements also have a `host` property\n    // but only shadow roots have a `mode` property\n    n && \"host\" in n && \"mode\" in n && index.host(n) || null\n  );\n  return Boolean(\n    hostEl && \"shadowRoot\" in hostEl && index.shadowRoot(hostEl) === n\n  );\n}\nfunction isNativeShadowDom(shadowRoot2) {\n  return Object.prototype.toString.call(shadowRoot2) === \"[object ShadowRoot]\";\n}\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\n  if (cssText.includes(\" background-clip: text;\") && !cssText.includes(\" -webkit-background-clip: text;\")) {\n    cssText = cssText.replace(\n      /\\sbackground-clip:\\s*text;/g,\n      \" -webkit-background-clip: text; background-clip: text;\"\n    );\n  }\n  return cssText;\n}\nfunction escapeImportStatement(rule2) {\n  const { cssText } = rule2;\n  if (cssText.split('\"').length < 3) return cssText;\n  const statement = [\"@import\", `url(${JSON.stringify(rule2.href)})`];\n  if (rule2.layerName === \"\") {\n    statement.push(`layer`);\n  } else if (rule2.layerName) {\n    statement.push(`layer(${rule2.layerName})`);\n  }\n  if (rule2.supportsText) {\n    statement.push(`supports(${rule2.supportsText})`);\n  }\n  if (rule2.media.length) {\n    statement.push(rule2.media.mediaText);\n  }\n  return statement.join(\" \") + \";\";\n}\nfunction stringifyStylesheet(s) {\n  try {\n    const rules = s.rules || s.cssRules;\n    if (!rules) {\n      return null;\n    }\n    let sheetHref = s.href;\n    if (!sheetHref && s.ownerNode) {\n      sheetHref = s.ownerNode.baseURI;\n    }\n    const stringifiedRules = Array.from(\n      rules,\n      (rule2) => stringifyRule(rule2, sheetHref)\n    ).join(\"\");\n    return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);\n  } catch (error) {\n    return null;\n  }\n}\nfunction stringifyRule(rule2, sheetHref) {\n  if (isCSSImportRule(rule2)) {\n    let importStringified;\n    try {\n      importStringified = // for same-origin stylesheets,\n      // we can access the imported stylesheet rules directly\n      stringifyStylesheet(rule2.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement\n      escapeImportStatement(rule2);\n    } catch (error) {\n      importStringified = rule2.cssText;\n    }\n    if (rule2.styleSheet.href) {\n      return absolutifyURLs(importStringified, rule2.styleSheet.href);\n    }\n    return importStringified;\n  } else {\n    let ruleStringified = rule2.cssText;\n    if (isCSSStyleRule(rule2) && rule2.selectorText.includes(\":\")) {\n      ruleStringified = fixSafariColons(ruleStringified);\n    }\n    if (sheetHref) {\n      return absolutifyURLs(ruleStringified, sheetHref);\n    }\n    return ruleStringified;\n  }\n}\nfunction fixSafariColons(cssStringified) {\n  const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\n  return cssStringified.replace(regex, \"$1\\\\$2\");\n}\nfunction isCSSImportRule(rule2) {\n  return \"styleSheet\" in rule2;\n}\nfunction isCSSStyleRule(rule2) {\n  return \"selectorText\" in rule2;\n}\nclass Mirror {\n  constructor() {\n    __publicField(this, \"idNodeMap\", /* @__PURE__ */ new Map());\n    __publicField(this, \"nodeMetaMap\", /* @__PURE__ */ new WeakMap());\n  }\n  getId(n) {\n    var _a;\n    if (!n) return -1;\n    const id = (_a = this.getMeta(n)) == null ? void 0 : _a.id;\n    return id ?? -1;\n  }\n  getNode(id) {\n    return this.idNodeMap.get(id) || null;\n  }\n  getIds() {\n    return Array.from(this.idNodeMap.keys());\n  }\n  getMeta(n) {\n    return this.nodeMetaMap.get(n) || null;\n  }\n  // removes the node from idNodeMap\n  // doesn't remove the node from nodeMetaMap\n  removeNodeFromMap(n) {\n    const id = this.getId(n);\n    this.idNodeMap.delete(id);\n    if (n.childNodes) {\n      n.childNodes.forEach(\n        (childNode) => this.removeNodeFromMap(childNode)\n      );\n    }\n  }\n  has(id) {\n    return this.idNodeMap.has(id);\n  }\n  hasNode(node2) {\n    return this.nodeMetaMap.has(node2);\n  }\n  add(n, meta) {\n    const id = meta.id;\n    this.idNodeMap.set(id, n);\n    this.nodeMetaMap.set(n, meta);\n  }\n  replace(id, n) {\n    const oldNode = this.getNode(id);\n    if (oldNode) {\n      const meta = this.nodeMetaMap.get(oldNode);\n      if (meta) this.nodeMetaMap.set(n, meta);\n    }\n    this.idNodeMap.set(id, n);\n  }\n  reset() {\n    this.idNodeMap = /* @__PURE__ */ new Map();\n    this.nodeMetaMap = /* @__PURE__ */ new WeakMap();\n  }\n}\nfunction createMirror() {\n  return new Mirror();\n}\nfunction maskInputValue({\n  element,\n  maskInputOptions,\n  tagName,\n  type,\n  value,\n  maskInputFn\n}) {\n  let text = value || \"\";\n  const actualType = type && toLowerCase(type);\n  if (maskInputOptions[tagName.toLowerCase()] || actualType && maskInputOptions[actualType]) {\n    if (maskInputFn) {\n      text = maskInputFn(text, element);\n    } else {\n      text = \"*\".repeat(text.length);\n    }\n  }\n  return text;\n}\nfunction toLowerCase(str) {\n  return str.toLowerCase();\n}\nconst ORIGINAL_ATTRIBUTE_NAME = \"__rrweb_original__\";\nfunction is2DCanvasBlank(canvas) {\n  const ctx = canvas.getContext(\"2d\");\n  if (!ctx) return true;\n  const chunkSize = 50;\n  for (let x2 = 0; x2 < canvas.width; x2 += chunkSize) {\n    for (let y = 0; y < canvas.height; y += chunkSize) {\n      const getImageData = ctx.getImageData;\n      const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData ? getImageData[ORIGINAL_ATTRIBUTE_NAME] : getImageData;\n      const pixelBuffer = new Uint32Array(\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n        originalGetImageData.call(\n          ctx,\n          x2,\n          y,\n          Math.min(chunkSize, canvas.width - x2),\n          Math.min(chunkSize, canvas.height - y)\n        ).data.buffer\n      );\n      if (pixelBuffer.some((pixel) => pixel !== 0)) return false;\n    }\n  }\n  return true;\n}\nfunction isNodeMetaEqual(a, b) {\n  if (!a || !b || a.type !== b.type) return false;\n  if (a.type === NodeType.Document)\n    return a.compatMode === b.compatMode;\n  else if (a.type === NodeType.DocumentType)\n    return a.name === b.name && a.publicId === b.publicId && a.systemId === b.systemId;\n  else if (a.type === NodeType.Comment || a.type === NodeType.Text || a.type === NodeType.CDATA)\n    return a.textContent === b.textContent;\n  else if (a.type === NodeType.Element)\n    return a.tagName === b.tagName && JSON.stringify(a.attributes) === JSON.stringify(b.attributes) && a.isSVG === b.isSVG && a.needBlock === b.needBlock;\n  return false;\n}\nfunction getInputType(element) {\n  const type = element.type;\n  return element.hasAttribute(\"data-rr-is-password\") ? \"password\" : type ? (\n    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n    toLowerCase(type)\n  ) : null;\n}\nfunction extractFileExtension(path, baseURL) {\n  let url;\n  try {\n    url = new URL(path, baseURL ?? window.location.href);\n  } catch (err) {\n    return null;\n  }\n  const regex = /\\.([0-9a-z]+)(?:$)/i;\n  const match = url.pathname.match(regex);\n  return (match == null ? void 0 : match[1]) ?? null;\n}\nfunction extractOrigin(url) {\n  let origin = \"\";\n  if (url.indexOf(\"//\") > -1) {\n    origin = url.split(\"/\").slice(0, 3).join(\"/\");\n  } else {\n    origin = url.split(\"/\")[0];\n  }\n  origin = origin.split(\"?\")[0];\n  return origin;\n}\nconst URL_IN_CSS_REF = /url\\((?:(')([^']*)'|(\")(.*?)\"|([^)]*))\\)/gm;\nconst URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\\/\\//i;\nconst URL_WWW_MATCH = /^www\\..*/i;\nconst DATA_URI = /^(data:)([^,]*),(.*)/i;\nfunction absolutifyURLs(cssText, href) {\n  return (cssText || \"\").replace(\n    URL_IN_CSS_REF,\n    (origin, quote1, path1, quote2, path2, path3) => {\n      const filePath = path1 || path2 || path3;\n      const maybeQuote = quote1 || quote2 || \"\";\n      if (!filePath) {\n        return origin;\n      }\n      if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {\n        return `url(${maybeQuote}${filePath}${maybeQuote})`;\n      }\n      if (DATA_URI.test(filePath)) {\n        return `url(${maybeQuote}${filePath}${maybeQuote})`;\n      }\n      if (filePath[0] === \"/\") {\n        return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;\n      }\n      const stack = href.split(\"/\");\n      const parts = filePath.split(\"/\");\n      stack.pop();\n      for (const part of parts) {\n        if (part === \".\") {\n          continue;\n        } else if (part === \"..\") {\n          stack.pop();\n        } else {\n          stack.push(part);\n        }\n      }\n      return `url(${maybeQuote}${stack.join(\"/\")}${maybeQuote})`;\n    }\n  );\n}\nfunction normalizeCssString(cssText, _testNoPxNorm = false) {\n  if (_testNoPxNorm) {\n    return cssText.replace(/(\\/\\*[^*]*\\*\\/)|[\\s;]/g, \"\");\n  } else {\n    return cssText.replace(/(\\/\\*[^*]*\\*\\/)|[\\s;]/g, \"\").replace(/0px/g, \"0\");\n  }\n}\nfunction splitCssText(cssText, style, _testNoPxNorm = false) {\n  const childNodes2 = Array.from(style.childNodes);\n  const splits = [];\n  let iterCount = 0;\n  if (childNodes2.length > 1 && cssText && typeof cssText === \"string\") {\n    let cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);\n    const normFactor = cssTextNorm.length / cssText.length;\n    for (let i = 1; i < childNodes2.length; i++) {\n      if (childNodes2[i].textContent && typeof childNodes2[i].textContent === \"string\") {\n        const textContentNorm = normalizeCssString(\n          childNodes2[i].textContent,\n          _testNoPxNorm\n        );\n        const jLimit = 100;\n        let j = 3;\n        for (; j < textContentNorm.length; j++) {\n          if (\n            // keep consuming css identifiers (to get a decent chunk more quickly)\n            textContentNorm[j].match(/[a-zA-Z0-9]/) || // substring needs to be unique to this section\n            textContentNorm.indexOf(textContentNorm.substring(0, j), 1) !== -1\n          ) {\n            continue;\n          }\n          break;\n        }\n        for (; j < textContentNorm.length; j++) {\n          let startSubstring = textContentNorm.substring(0, j);\n          let cssNormSplits = cssTextNorm.split(startSubstring);\n          let splitNorm = -1;\n          if (cssNormSplits.length === 2) {\n            splitNorm = cssNormSplits[0].length;\n          } else if (cssNormSplits.length > 2 && cssNormSplits[0] === \"\" && childNodes2[i - 1].textContent !== \"\") {\n            splitNorm = cssTextNorm.indexOf(startSubstring, 1);\n          } else if (cssNormSplits.length === 1) {\n            startSubstring = startSubstring.substring(\n              0,\n              startSubstring.length - 1\n            );\n            cssNormSplits = cssTextNorm.split(startSubstring);\n            if (cssNormSplits.length <= 1) {\n              splits.push(cssText);\n              return splits;\n            }\n            j = jLimit + 1;\n          } else if (j === textContentNorm.length - 1) {\n            splitNorm = cssTextNorm.indexOf(startSubstring);\n          }\n          if (cssNormSplits.length >= 2 && j > jLimit) {\n            const prevTextContent = childNodes2[i - 1].textContent;\n            if (prevTextContent && typeof prevTextContent === \"string\") {\n              const prevMinLength = normalizeCssString(prevTextContent).length;\n              splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);\n            }\n            if (splitNorm === -1) {\n              splitNorm = cssNormSplits[0].length;\n            }\n          }\n          if (splitNorm !== -1) {\n            let k = Math.floor(splitNorm / normFactor);\n            for (; k > 0 && k < cssText.length; ) {\n              iterCount += 1;\n              if (iterCount > 50 * childNodes2.length) {\n                splits.push(cssText);\n                return splits;\n              }\n              const normPart = normalizeCssString(\n                cssText.substring(0, k),\n                _testNoPxNorm\n              );\n              if (normPart.length === splitNorm) {\n                splits.push(cssText.substring(0, k));\n                cssText = cssText.substring(k);\n                cssTextNorm = cssTextNorm.substring(splitNorm);\n                break;\n              } else if (normPart.length < splitNorm) {\n                k += Math.max(\n                  1,\n                  Math.floor((splitNorm - normPart.length) / normFactor)\n                );\n              } else {\n                k -= Math.max(\n                  1,\n                  Math.floor((normPart.length - splitNorm) * normFactor)\n                );\n              }\n            }\n            break;\n          }\n        }\n      }\n    }\n  }\n  splits.push(cssText);\n  return splits;\n}\nfunction markCssSplits(cssText, style) {\n  return splitCssText(cssText, style).join(\"/* rr_split */\");\n}\nlet _id = 1;\nconst tagNameRegex = new RegExp(\"[^a-z0-9-_:]\");\nconst IGNORED_NODE = -2;\nfunction genId() {\n  return _id++;\n}\nfunction getValidTagName(element) {\n  if (element instanceof HTMLFormElement) {\n    return \"form\";\n  }\n  const processedTagName = toLowerCase(element.tagName);\n  if (tagNameRegex.test(processedTagName)) {\n    return \"div\";\n  }\n  return processedTagName;\n}\nlet canvasService;\nlet canvasCtx;\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\n  if (attributeValue.trim() === \"\") {\n    return attributeValue;\n  }\n  let pos = 0;\n  function collectCharacters(regEx) {\n    let chars;\n    const match = regEx.exec(attributeValue.substring(pos));\n    if (match) {\n      chars = match[0];\n      pos += chars.length;\n      return chars;\n    }\n    return \"\";\n  }\n  const output = [];\n  while (true) {\n    collectCharacters(SRCSET_COMMAS_OR_SPACES);\n    if (pos >= attributeValue.length) {\n      break;\n    }\n    let url = collectCharacters(SRCSET_NOT_SPACES);\n    if (url.slice(-1) === \",\") {\n      url = absoluteToDoc(doc, url.substring(0, url.length - 1));\n      output.push(url);\n    } else {\n      let descriptorsStr = \"\";\n      url = absoluteToDoc(doc, url);\n      let inParens = false;\n      while (true) {\n        const c = attributeValue.charAt(pos);\n        if (c === \"\") {\n          output.push((url + descriptorsStr).trim());\n          break;\n        } else if (!inParens) {\n          if (c === \",\") {\n            pos += 1;\n            output.push((url + descriptorsStr).trim());\n            break;\n          } else if (c === \"(\") {\n            inParens = true;\n          }\n        } else {\n          if (c === \")\") {\n            inParens = false;\n          }\n        }\n        descriptorsStr += c;\n        pos += 1;\n      }\n    }\n  }\n  return output.join(\", \");\n}\nconst cachedDocument = /* @__PURE__ */ new WeakMap();\nfunction absoluteToDoc(doc, attributeValue) {\n  if (!attributeValue || attributeValue.trim() === \"\") {\n    return attributeValue;\n  }\n  return getHref(doc, attributeValue);\n}\nfunction isSVGElement(el) {\n  return Boolean(el.tagName === \"svg\" || el.ownerSVGElement);\n}\nfunction getHref(doc, customHref) {\n  let a = cachedDocument.get(doc);\n  if (!a) {\n    a = doc.createElement(\"a\");\n    cachedDocument.set(doc, a);\n  }\n  if (!customHref) {\n    customHref = \"\";\n  } else if (customHref.startsWith(\"blob:\") || customHref.startsWith(\"data:\")) {\n    return customHref;\n  }\n  a.setAttribute(\"href\", customHref);\n  return a.href;\n}\nfunction transformAttribute(doc, tagName, name, value) {\n  if (!value) {\n    return value;\n  }\n  if (name === \"src\" || name === \"href\" && !(tagName === \"use\" && value[0] === \"#\")) {\n    return absoluteToDoc(doc, value);\n  } else if (name === \"xlink:href\" && value[0] !== \"#\") {\n    return absoluteToDoc(doc, value);\n  } else if (name === \"background\" && [\"table\", \"td\", \"th\"].includes(tagName)) {\n    return absoluteToDoc(doc, value);\n  } else if (name === \"srcset\") {\n    return getAbsoluteSrcsetString(doc, value);\n  } else if (name === \"style\") {\n    return absolutifyURLs(value, getHref(doc));\n  } else if (tagName === \"object\" && name === \"data\") {\n    return absoluteToDoc(doc, value);\n  }\n  return value;\n}\nfunction ignoreAttribute(tagName, name, _value) {\n  return [\"video\", \"audio\"].includes(tagName) && name === \"autoplay\";\n}\nfunction _isBlockedElement(element, blockClass, blockSelector) {\n  try {\n    if (typeof blockClass === \"string\") {\n      if (element.classList.contains(blockClass)) {\n        return true;\n      }\n    } else {\n      for (let eIndex = element.classList.length; eIndex--; ) {\n        const className = element.classList[eIndex];\n        if (blockClass.test(className)) {\n          return true;\n        }\n      }\n    }\n    if (blockSelector) {\n      return element.matches(blockSelector);\n    }\n  } catch (e) {\n  }\n  return false;\n}\nfunction classMatchesRegex(node2, regex, checkAncestors) {\n  if (!node2) return false;\n  if (node2.nodeType !== node2.ELEMENT_NODE) {\n    if (!checkAncestors) return false;\n    return classMatchesRegex(index.parentNode(node2), regex, checkAncestors);\n  }\n  for (let eIndex = node2.classList.length; eIndex--; ) {\n    const className = node2.classList[eIndex];\n    if (regex.test(className)) {\n      return true;\n    }\n  }\n  if (!checkAncestors) return false;\n  return classMatchesRegex(index.parentNode(node2), regex, checkAncestors);\n}\nfunction needMaskingText(node2, maskTextClass, maskTextSelector, checkAncestors) {\n  let el;\n  if (isElement(node2)) {\n    el = node2;\n    if (!index.childNodes(el).length) {\n      return false;\n    }\n  } else if (index.parentElement(node2) === null) {\n    return false;\n  } else {\n    el = index.parentElement(node2);\n  }\n  try {\n    if (typeof maskTextClass === \"string\") {\n      if (checkAncestors) {\n        if (el.closest(`.${maskTextClass}`)) return true;\n      } else {\n        if (el.classList.contains(maskTextClass)) return true;\n      }\n    } else {\n      if (classMatchesRegex(el, maskTextClass, checkAncestors)) return true;\n    }\n    if (maskTextSelector) {\n      if (checkAncestors) {\n        if (el.closest(maskTextSelector)) return true;\n      } else {\n        if (el.matches(maskTextSelector)) return true;\n      }\n    }\n  } catch (e) {\n  }\n  return false;\n}\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\n  const win = iframeEl.contentWindow;\n  if (!win) {\n    return;\n  }\n  let fired = false;\n  let readyState;\n  try {\n    readyState = win.document.readyState;\n  } catch (error) {\n    return;\n  }\n  if (readyState !== \"complete\") {\n    const timer = setTimeout(() => {\n      if (!fired) {\n        listener();\n        fired = true;\n      }\n    }, iframeLoadTimeout);\n    iframeEl.addEventListener(\"load\", () => {\n      clearTimeout(timer);\n      fired = true;\n      listener();\n    });\n    return;\n  }\n  const blankUrl = \"about:blank\";\n  if (win.location.href !== blankUrl || iframeEl.src === blankUrl || iframeEl.src === \"\") {\n    setTimeout(listener, 0);\n    return iframeEl.addEventListener(\"load\", listener);\n  }\n  iframeEl.addEventListener(\"load\", listener);\n}\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\n  let fired = false;\n  let styleSheetLoaded;\n  try {\n    styleSheetLoaded = link.sheet;\n  } catch (error) {\n    return;\n  }\n  if (styleSheetLoaded) return;\n  const timer = setTimeout(() => {\n    if (!fired) {\n      listener();\n      fired = true;\n    }\n  }, styleSheetLoadTimeout);\n  link.addEventListener(\"load\", () => {\n    clearTimeout(timer);\n    fired = true;\n    listener();\n  });\n}\nfunction serializeNode(n, options) {\n  const {\n    doc,\n    mirror,\n    blockClass,\n    blockSelector,\n    needsMask,\n    inlineStylesheet,\n    maskInputOptions = {},\n    maskTextFn,\n    maskInputFn,\n    dataURLOptions = {},\n    inlineImages,\n    recordCanvas,\n    keepIframeSrcFn,\n    newlyAddedElement = false,\n    cssCaptured = false\n  } = options;\n  const rootId = getRootId(doc, mirror);\n  switch (n.nodeType) {\n    case n.DOCUMENT_NODE:\n      if (n.compatMode !== \"CSS1Compat\") {\n        return {\n          type: NodeType.Document,\n          childNodes: [],\n          compatMode: n.compatMode\n          // probably \"BackCompat\"\n        };\n      } else {\n        return {\n          type: NodeType.Document,\n          childNodes: []\n        };\n      }\n    case n.DOCUMENT_TYPE_NODE:\n      return {\n        type: NodeType.DocumentType,\n        name: n.name,\n        publicId: n.publicId,\n        systemId: n.systemId,\n        rootId\n      };\n    case n.ELEMENT_NODE:\n      return serializeElementNode(n, {\n        doc,\n        blockClass,\n        blockSelector,\n        inlineStylesheet,\n        maskInputOptions,\n        maskInputFn,\n        dataURLOptions,\n        inlineImages,\n        recordCanvas,\n        keepIframeSrcFn,\n        newlyAddedElement,\n        rootId\n      });\n    case n.TEXT_NODE:\n      return serializeTextNode(n, {\n        doc,\n        needsMask,\n        maskTextFn,\n        rootId,\n        cssCaptured\n      });\n    case n.CDATA_SECTION_NODE:\n      return {\n        type: NodeType.CDATA,\n        textContent: \"\",\n        rootId\n      };\n    case n.COMMENT_NODE:\n      return {\n        type: NodeType.Comment,\n        textContent: index.textContent(n) || \"\",\n        rootId\n      };\n    default:\n      return false;\n  }\n}\nfunction getRootId(doc, mirror) {\n  if (!mirror.hasNode(doc)) return void 0;\n  const docId = mirror.getId(doc);\n  return docId === 1 ? void 0 : docId;\n}\nfunction serializeTextNode(n, options) {\n  const { needsMask, maskTextFn, rootId, cssCaptured } = options;\n  const parent = index.parentNode(n);\n  const parentTagName = parent && parent.tagName;\n  let textContent2 = \"\";\n  const isStyle = parentTagName === \"STYLE\" ? true : void 0;\n  const isScript = parentTagName === \"SCRIPT\" ? true : void 0;\n  if (isScript) {\n    textContent2 = \"SCRIPT_PLACEHOLDER\";\n  } else if (!cssCaptured) {\n    textContent2 = index.textContent(n);\n    if (isStyle && textContent2) {\n      textContent2 = absolutifyURLs(textContent2, getHref(options.doc));\n    }\n  }\n  if (!isStyle && !isScript && textContent2 && needsMask) {\n    textContent2 = maskTextFn ? maskTextFn(textContent2, index.parentElement(n)) : textContent2.replace(/[\\S]/g, \"*\");\n  }\n  return {\n    type: NodeType.Text,\n    textContent: textContent2 || \"\",\n    rootId\n  };\n}\nfunction serializeElementNode(n, options) {\n  const {\n    doc,\n    blockClass,\n    blockSelector,\n    inlineStylesheet,\n    maskInputOptions = {},\n    maskInputFn,\n    dataURLOptions = {},\n    inlineImages,\n    recordCanvas,\n    keepIframeSrcFn,\n    newlyAddedElement = false,\n    rootId\n  } = options;\n  const needBlock = _isBlockedElement(n, blockClass, blockSelector);\n  const tagName = getValidTagName(n);\n  let attributes = {};\n  const len = n.attributes.length;\n  for (let i = 0; i < len; i++) {\n    const attr = n.attributes[i];\n    if (!ignoreAttribute(tagName, attr.name, attr.value)) {\n      attributes[attr.name] = transformAttribute(\n        doc,\n        tagName,\n        toLowerCase(attr.name),\n        attr.value\n      );\n    }\n  }\n  if (tagName === \"link\" && inlineStylesheet) {\n    const stylesheet = Array.from(doc.styleSheets).find((s) => {\n      return s.href === n.href;\n    });\n    let cssText = null;\n    if (stylesheet) {\n      cssText = stringifyStylesheet(stylesheet);\n    }\n    if (cssText) {\n      delete attributes.rel;\n      delete attributes.href;\n      attributes._cssText = cssText;\n    }\n  }\n  if (tagName === \"style\" && n.sheet) {\n    let cssText = stringifyStylesheet(\n      n.sheet\n    );\n    if (cssText) {\n      if (n.childNodes.length > 1) {\n        cssText = markCssSplits(cssText, n);\n      }\n      attributes._cssText = cssText;\n    }\n  }\n  if ([\"input\", \"textarea\", \"select\"].includes(tagName)) {\n    const value = n.value;\n    const checked = n.checked;\n    if (attributes.type !== \"radio\" && attributes.type !== \"checkbox\" && attributes.type !== \"submit\" && attributes.type !== \"button\" && value) {\n      attributes.value = maskInputValue({\n        element: n,\n        type: getInputType(n),\n        tagName,\n        value,\n        maskInputOptions,\n        maskInputFn\n      });\n    } else if (checked) {\n      attributes.checked = checked;\n    }\n  }\n  if (tagName === \"option\") {\n    if (n.selected && !maskInputOptions[\"select\"]) {\n      attributes.selected = true;\n    } else {\n      delete attributes.selected;\n    }\n  }\n  if (tagName === \"dialog\" && n.open) {\n    attributes.rr_open_mode = n.matches(\"dialog:modal\") ? \"modal\" : \"non-modal\";\n  }\n  if (tagName === \"canvas\" && recordCanvas) {\n    if (n.__context === \"2d\") {\n      if (!is2DCanvasBlank(n)) {\n        attributes.rr_dataURL = n.toDataURL(\n          dataURLOptions.type,\n          dataURLOptions.quality\n        );\n      }\n    } else if (!(\"__context\" in n)) {\n      const canvasDataURL = n.toDataURL(\n        dataURLOptions.type,\n        dataURLOptions.quality\n      );\n      const blankCanvas = doc.createElement(\"canvas\");\n      blankCanvas.width = n.width;\n      blankCanvas.height = n.height;\n      const blankCanvasDataURL = blankCanvas.toDataURL(\n        dataURLOptions.type,\n        dataURLOptions.quality\n      );\n      if (canvasDataURL !== blankCanvasDataURL) {\n        attributes.rr_dataURL = canvasDataURL;\n      }\n    }\n  }\n  if (tagName === \"img\" && inlineImages) {\n    if (!canvasService) {\n      canvasService = doc.createElement(\"canvas\");\n      canvasCtx = canvasService.getContext(\"2d\");\n    }\n    const image = n;\n    const imageSrc = image.currentSrc || image.getAttribute(\"src\") || \"<unknown-src>\";\n    const priorCrossOrigin = image.crossOrigin;\n    const recordInlineImage = () => {\n      image.removeEventListener(\"load\", recordInlineImage);\n      try {\n        canvasService.width = image.naturalWidth;\n        canvasService.height = image.naturalHeight;\n        canvasCtx.drawImage(image, 0, 0);\n        attributes.rr_dataURL = canvasService.toDataURL(\n          dataURLOptions.type,\n          dataURLOptions.quality\n        );\n      } catch (err) {\n        if (image.crossOrigin !== \"anonymous\") {\n          image.crossOrigin = \"anonymous\";\n          if (image.complete && image.naturalWidth !== 0)\n            recordInlineImage();\n          else image.addEventListener(\"load\", recordInlineImage);\n          return;\n        } else {\n          console.warn(\n            `Cannot inline img src=${imageSrc}! Error: ${err}`\n          );\n        }\n      }\n      if (image.crossOrigin === \"anonymous\") {\n        priorCrossOrigin ? attributes.crossOrigin = priorCrossOrigin : image.removeAttribute(\"crossorigin\");\n      }\n    };\n    if (image.complete && image.naturalWidth !== 0) recordInlineImage();\n    else image.addEventListener(\"load\", recordInlineImage);\n  }\n  if ([\"audio\", \"video\"].includes(tagName)) {\n    const mediaAttributes = attributes;\n    mediaAttributes.rr_mediaState = n.paused ? \"paused\" : \"played\";\n    mediaAttributes.rr_mediaCurrentTime = n.currentTime;\n    mediaAttributes.rr_mediaPlaybackRate = n.playbackRate;\n    mediaAttributes.rr_mediaMuted = n.muted;\n    mediaAttributes.rr_mediaLoop = n.loop;\n    mediaAttributes.rr_mediaVolume = n.volume;\n  }\n  if (!newlyAddedElement) {\n    if (n.scrollLeft) {\n      attributes.rr_scrollLeft = n.scrollLeft;\n    }\n    if (n.scrollTop) {\n      attributes.rr_scrollTop = n.scrollTop;\n    }\n  }\n  if (needBlock) {\n    const { width, height } = n.getBoundingClientRect();\n    attributes = {\n      class: attributes.class,\n      rr_width: `${width}px`,\n      rr_height: `${height}px`\n    };\n  }\n  if (tagName === \"iframe\" && !keepIframeSrcFn(attributes.src)) {\n    if (!n.contentDocument) {\n      attributes.rr_src = attributes.src;\n    }\n    delete attributes.src;\n  }\n  let isCustomElement;\n  try {\n    if (customElements.get(tagName)) isCustomElement = true;\n  } catch (e) {\n  }\n  return {\n    type: NodeType.Element,\n    tagName,\n    attributes,\n    childNodes: [],\n    isSVG: isSVGElement(n) || void 0,\n    needBlock,\n    rootId,\n    isCustom: isCustomElement\n  };\n}\nfunction lowerIfExists(maybeAttr) {\n  if (maybeAttr === void 0 || maybeAttr === null) {\n    return \"\";\n  } else {\n    return maybeAttr.toLowerCase();\n  }\n}\nfunction slimDOMDefaults(_slimDOMOptions) {\n  if (_slimDOMOptions === true || _slimDOMOptions === \"all\") {\n    return {\n      script: true,\n      comment: true,\n      headFavicon: true,\n      headWhitespace: true,\n      headMetaSocial: true,\n      headMetaRobots: true,\n      headMetaHttpEquiv: true,\n      headMetaVerification: true,\n      // the following are off for slimDOMOptions === true,\n      // as they destroy some (hidden) info:\n      headMetaAuthorship: _slimDOMOptions === \"all\",\n      headMetaDescKeywords: _slimDOMOptions === \"all\",\n      headTitleMutations: _slimDOMOptions === \"all\"\n    };\n  } else if (_slimDOMOptions) {\n    return _slimDOMOptions;\n  }\n  return {};\n}\nfunction slimDOMExcluded(sn, slimDOMOptions) {\n  if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\n    return true;\n  } else if (sn.type === NodeType.Element) {\n    if (slimDOMOptions.script && // script tag\n    (sn.tagName === \"script\" || // (module)preload link\n    sn.tagName === \"link\" && (sn.attributes.rel === \"preload\" && sn.attributes.as === \"script\" || sn.attributes.rel === \"modulepreload\") || // prefetch link\n    sn.tagName === \"link\" && sn.attributes.rel === \"prefetch\" && typeof sn.attributes.href === \"string\" && extractFileExtension(sn.attributes.href) === \"js\")) {\n      return true;\n    } else if (slimDOMOptions.headFavicon && (sn.tagName === \"link\" && sn.attributes.rel === \"shortcut icon\" || sn.tagName === \"meta\" && (lowerIfExists(sn.attributes.name).match(\n      /^msapplication-tile(image|color)$/\n    ) || lowerIfExists(sn.attributes.name) === \"application-name\" || lowerIfExists(sn.attributes.rel) === \"icon\" || lowerIfExists(sn.attributes.rel) === \"apple-touch-icon\" || lowerIfExists(sn.attributes.rel) === \"shortcut icon\"))) {\n      return true;\n    } else if (sn.tagName === \"meta\") {\n      if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\n        return true;\n      } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)\n      lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === \"pinterest\")) {\n        return true;\n      } else if (slimDOMOptions.headMetaRobots && (lowerIfExists(sn.attributes.name) === \"robots\" || lowerIfExists(sn.attributes.name) === \"googlebot\" || lowerIfExists(sn.attributes.name) === \"bingbot\")) {\n        return true;\n      } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes[\"http-equiv\"] !== void 0) {\n        return true;\n      } else if (slimDOMOptions.headMetaAuthorship && (lowerIfExists(sn.attributes.name) === \"author\" || lowerIfExists(sn.attributes.name) === \"generator\" || lowerIfExists(sn.attributes.name) === \"framework\" || lowerIfExists(sn.attributes.name) === \"publisher\" || lowerIfExists(sn.attributes.name) === \"progid\" || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {\n        return true;\n      } else if (slimDOMOptions.headMetaVerification && (lowerIfExists(sn.attributes.name) === \"google-site-verification\" || lowerIfExists(sn.attributes.name) === \"yandex-verification\" || lowerIfExists(sn.attributes.name) === \"csrf-token\" || lowerIfExists(sn.attributes.name) === \"p:domain_verify\" || lowerIfExists(sn.attributes.name) === \"verify-v1\" || lowerIfExists(sn.attributes.name) === \"verification\" || lowerIfExists(sn.attributes.name) === \"shopify-checkout-api-token\")) {\n        return true;\n      }\n    }\n  }\n  return false;\n}\nfunction serializeNodeWithId(n, options) {\n  const {\n    doc,\n    mirror,\n    blockClass,\n    blockSelector,\n    maskTextClass,\n    maskTextSelector,\n    skipChild = false,\n    inlineStylesheet = true,\n    maskInputOptions = {},\n    maskTextFn,\n    maskInputFn,\n    slimDOMOptions,\n    dataURLOptions = {},\n    inlineImages = false,\n    recordCanvas = false,\n    onSerialize,\n    onIframeLoad,\n    iframeLoadTimeout = 5e3,\n    onStylesheetLoad,\n    stylesheetLoadTimeout = 5e3,\n    keepIframeSrcFn = () => false,\n    newlyAddedElement = false,\n    cssCaptured = false\n  } = options;\n  let { needsMask } = options;\n  let { preserveWhiteSpace = true } = options;\n  if (!needsMask) {\n    const checkAncestors = needsMask === void 0;\n    needsMask = needMaskingText(\n      n,\n      maskTextClass,\n      maskTextSelector,\n      checkAncestors\n    );\n  }\n  const _serializedNode = serializeNode(n, {\n    doc,\n    mirror,\n    blockClass,\n    blockSelector,\n    needsMask,\n    inlineStylesheet,\n    maskInputOptions,\n    maskTextFn,\n    maskInputFn,\n    dataURLOptions,\n    inlineImages,\n    recordCanvas,\n    keepIframeSrcFn,\n    newlyAddedElement,\n    cssCaptured\n  });\n  if (!_serializedNode) {\n    console.warn(n, \"not serialized\");\n    return null;\n  }\n  let id;\n  if (mirror.hasNode(n)) {\n    id = mirror.getId(n);\n  } else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType.Text && !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, \"\").length) {\n    id = IGNORED_NODE;\n  } else {\n    id = genId();\n  }\n  const serializedNode = Object.assign(_serializedNode, { id });\n  mirror.add(n, serializedNode);\n  if (id === IGNORED_NODE) {\n    return null;\n  }\n  if (onSerialize) {\n    onSerialize(n);\n  }\n  let recordChild = !skipChild;\n  if (serializedNode.type === NodeType.Element) {\n    recordChild = recordChild && !serializedNode.needBlock;\n    delete serializedNode.needBlock;\n    const shadowRootEl = index.shadowRoot(n);\n    if (shadowRootEl && isNativeShadowDom(shadowRootEl))\n      serializedNode.isShadowHost = true;\n  }\n  if ((serializedNode.type === NodeType.Document || serializedNode.type === NodeType.Element) && recordChild) {\n    if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType.Element && serializedNode.tagName === \"head\") {\n      preserveWhiteSpace = false;\n    }\n    const bypassOptions = {\n      doc,\n      mirror,\n      blockClass,\n      blockSelector,\n      needsMask,\n      maskTextClass,\n      maskTextSelector,\n      skipChild,\n      inlineStylesheet,\n      maskInputOptions,\n      maskTextFn,\n      maskInputFn,\n      slimDOMOptions,\n      dataURLOptions,\n      inlineImages,\n      recordCanvas,\n      preserveWhiteSpace,\n      onSerialize,\n      onIframeLoad,\n      iframeLoadTimeout,\n      onStylesheetLoad,\n      stylesheetLoadTimeout,\n      keepIframeSrcFn,\n      cssCaptured: false\n    };\n    if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"textarea\" && serializedNode.attributes.value !== void 0) ;\n    else {\n      if (serializedNode.type === NodeType.Element && serializedNode.attributes._cssText !== void 0 && typeof serializedNode.attributes._cssText === \"string\") {\n        bypassOptions.cssCaptured = true;\n      }\n      for (const childN of Array.from(index.childNodes(n))) {\n        const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n        if (serializedChildNode) {\n          serializedNode.childNodes.push(serializedChildNode);\n        }\n      }\n    }\n    let shadowRootEl = null;\n    if (isElement(n) && (shadowRootEl = index.shadowRoot(n))) {\n      for (const childN of Array.from(index.childNodes(shadowRootEl))) {\n        const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n        if (serializedChildNode) {\n          isNativeShadowDom(shadowRootEl) && (serializedChildNode.isShadow = true);\n          serializedNode.childNodes.push(serializedChildNode);\n        }\n      }\n    }\n  }\n  const parent = index.parentNode(n);\n  if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {\n    serializedNode.isShadow = true;\n  }\n  if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"iframe\") {\n    onceIframeLoaded(\n      n,\n      () => {\n        const iframeDoc = n.contentDocument;\n        if (iframeDoc && onIframeLoad) {\n          const serializedIframeNode = serializeNodeWithId(iframeDoc, {\n            doc: iframeDoc,\n            mirror,\n            blockClass,\n            blockSelector,\n            needsMask,\n            maskTextClass,\n            maskTextSelector,\n            skipChild: false,\n            inlineStylesheet,\n            maskInputOptions,\n            maskTextFn,\n            maskInputFn,\n            slimDOMOptions,\n            dataURLOptions,\n            inlineImages,\n            recordCanvas,\n            preserveWhiteSpace,\n            onSerialize,\n            onIframeLoad,\n            iframeLoadTimeout,\n            onStylesheetLoad,\n            stylesheetLoadTimeout,\n            keepIframeSrcFn\n          });\n          if (serializedIframeNode) {\n            onIframeLoad(\n              n,\n              serializedIframeNode\n            );\n          }\n        }\n      },\n      iframeLoadTimeout\n    );\n  }\n  if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"link\" && typeof serializedNode.attributes.rel === \"string\" && (serializedNode.attributes.rel === \"stylesheet\" || serializedNode.attributes.rel === \"preload\" && typeof serializedNode.attributes.href === \"string\" && extractFileExtension(serializedNode.attributes.href) === \"css\")) {\n    onceStylesheetLoaded(\n      n,\n      () => {\n        if (onStylesheetLoad) {\n          const serializedLinkNode = serializeNodeWithId(n, {\n            doc,\n            mirror,\n            blockClass,\n            blockSelector,\n            needsMask,\n            maskTextClass,\n            maskTextSelector,\n            skipChild: false,\n            inlineStylesheet,\n            maskInputOptions,\n            maskTextFn,\n            maskInputFn,\n            slimDOMOptions,\n            dataURLOptions,\n            inlineImages,\n            recordCanvas,\n            preserveWhiteSpace,\n            onSerialize,\n            onIframeLoad,\n            iframeLoadTimeout,\n            onStylesheetLoad,\n            stylesheetLoadTimeout,\n            keepIframeSrcFn\n          });\n          if (serializedLinkNode) {\n            onStylesheetLoad(\n              n,\n              serializedLinkNode\n            );\n          }\n        }\n      },\n      stylesheetLoadTimeout\n    );\n  }\n  return serializedNode;\n}\nfunction snapshot(n, options) {\n  const {\n    mirror = new Mirror(),\n    blockClass = \"rr-block\",\n    blockSelector = null,\n    maskTextClass = \"rr-mask\",\n    maskTextSelector = null,\n    inlineStylesheet = true,\n    inlineImages = false,\n    recordCanvas = false,\n    maskAllInputs = false,\n    maskTextFn,\n    maskInputFn,\n    slimDOM = false,\n    dataURLOptions,\n    preserveWhiteSpace,\n    onSerialize,\n    onIframeLoad,\n    iframeLoadTimeout,\n    onStylesheetLoad,\n    stylesheetLoadTimeout,\n    keepIframeSrcFn = () => false\n  } = options || {};\n  const maskInputOptions = maskAllInputs === true ? {\n    color: true,\n    date: true,\n    \"datetime-local\": true,\n    email: true,\n    month: true,\n    number: true,\n    range: true,\n    search: true,\n    tel: true,\n    text: true,\n    time: true,\n    url: true,\n    week: true,\n    textarea: true,\n    select: true,\n    password: true\n  } : maskAllInputs === false ? {\n    password: true\n  } : maskAllInputs;\n  const slimDOMOptions = slimDOMDefaults(slimDOM);\n  return serializeNodeWithId(n, {\n    doc: n,\n    mirror,\n    blockClass,\n    blockSelector,\n    maskTextClass,\n    maskTextSelector,\n    skipChild: false,\n    inlineStylesheet,\n    maskInputOptions,\n    maskTextFn,\n    maskInputFn,\n    slimDOMOptions,\n    dataURLOptions,\n    inlineImages,\n    recordCanvas,\n    preserveWhiteSpace,\n    onSerialize,\n    onIframeLoad,\n    iframeLoadTimeout,\n    onStylesheetLoad,\n    stylesheetLoadTimeout,\n    keepIframeSrcFn,\n    newlyAddedElement: false\n  });\n}\nfunction visitSnapshot(node2, onVisit) {\n  function walk(current) {\n    onVisit(current);\n    if (current.type === NodeType.Document || current.type === NodeType.Element) {\n      current.childNodes.forEach(walk);\n    }\n  }\n  walk(node2);\n}\nfunction cleanupSnapshot() {\n  _id = 1;\n}\nconst MEDIA_SELECTOR = /(max|min)-device-(width|height)/;\nconst MEDIA_SELECTOR_GLOBAL = new RegExp(MEDIA_SELECTOR.source, \"g\");\nconst mediaSelectorPlugin = {\n  postcssPlugin: \"postcss-custom-selectors\",\n  prepare() {\n    return {\n      postcssPlugin: \"postcss-custom-selectors\",\n      AtRule: function(atrule) {\n        if (atrule.params.match(MEDIA_SELECTOR_GLOBAL)) {\n          atrule.params = atrule.params.replace(MEDIA_SELECTOR_GLOBAL, \"$1-$2\");\n        }\n      }\n    };\n  }\n};\nconst pseudoClassPlugin = {\n  postcssPlugin: \"postcss-hover-classes\",\n  prepare: function() {\n    const fixed = [];\n    return {\n      Rule: function(rule2) {\n        if (fixed.indexOf(rule2) !== -1) {\n          return;\n        }\n        fixed.push(rule2);\n        rule2.selectors.forEach(function(selector) {\n          if (selector.includes(\":hover\")) {\n            rule2.selector += \",\\n\" + selector.replace(/:hover/g, \".\\\\:hover\");\n          }\n        });\n      }\n    };\n  }\n};\nfunction getDefaultExportFromCjs(x2) {\n  return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, \"default\") ? x2[\"default\"] : x2;\n}\nfunction getAugmentedNamespace(n) {\n  if (n.__esModule) return n;\n  var f = n.default;\n  if (typeof f == \"function\") {\n    var a = function a2() {\n      if (this instanceof a2) {\n        return Reflect.construct(f, arguments, this.constructor);\n      }\n      return f.apply(this, arguments);\n    };\n    a.prototype = f.prototype;\n  } else a = {};\n  Object.defineProperty(a, \"__esModule\", { value: true });\n  Object.keys(n).forEach(function(k) {\n    var d = Object.getOwnPropertyDescriptor(n, k);\n    Object.defineProperty(a, k, d.get ? d : {\n      enumerable: true,\n      get: function() {\n        return n[k];\n      }\n    });\n  });\n  return a;\n}\nvar picocolors_browser = { exports: {} };\nvar x = String;\nvar create = function() {\n  return { isColorSupported: false, reset: x, bold: x, dim: x, italic: x, underline: x, inverse: x, hidden: x, strikethrough: x, black: x, red: x, green: x, yellow: x, blue: x, magenta: x, cyan: x, white: x, gray: x, bgBlack: x, bgRed: x, bgGreen: x, bgYellow: x, bgBlue: x, bgMagenta: x, bgCyan: x, bgWhite: x };\n};\npicocolors_browser.exports = create();\npicocolors_browser.exports.createColors = create;\nvar picocolors_browserExports = picocolors_browser.exports;\nconst __viteBrowserExternal = {};\nconst __viteBrowserExternal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n  __proto__: null,\n  default: __viteBrowserExternal\n}, Symbol.toStringTag, { value: \"Module\" }));\nconst require$$2 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1);\nlet pico = picocolors_browserExports;\nlet terminalHighlight$1 = require$$2;\nlet CssSyntaxError$3 = class CssSyntaxError extends Error {\n  constructor(message, line, column, source, file, plugin2) {\n    super(message);\n    this.name = \"CssSyntaxError\";\n    this.reason = message;\n    if (file) {\n      this.file = file;\n    }\n    if (source) {\n      this.source = source;\n    }\n    if (plugin2) {\n      this.plugin = plugin2;\n    }\n    if (typeof line !== \"undefined\" && typeof column !== \"undefined\") {\n      if (typeof line === \"number\") {\n        this.line = line;\n        this.column = column;\n      } else {\n        this.line = line.line;\n        this.column = line.column;\n        this.endLine = column.line;\n        this.endColumn = column.column;\n      }\n    }\n    this.setMessage();\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, CssSyntaxError);\n    }\n  }\n  setMessage() {\n    this.message = this.plugin ? this.plugin + \": \" : \"\";\n    this.message += this.file ? this.file : \"<css input>\";\n    if (typeof this.line !== \"undefined\") {\n      this.message += \":\" + this.line + \":\" + this.column;\n    }\n    this.message += \": \" + this.reason;\n  }\n  showSourceCode(color) {\n    if (!this.source) return \"\";\n    let css = this.source;\n    if (color == null) color = pico.isColorSupported;\n    if (terminalHighlight$1) {\n      if (color) css = terminalHighlight$1(css);\n    }\n    let lines = css.split(/\\r?\\n/);\n    let start = Math.max(this.line - 3, 0);\n    let end = Math.min(this.line + 2, lines.length);\n    let maxWidth = String(end).length;\n    let mark, aside;\n    if (color) {\n      let { bold, gray, red } = pico.createColors(true);\n      mark = (text) => bold(red(text));\n      aside = (text) => gray(text);\n    } else {\n      mark = aside = (str) => str;\n    }\n    return lines.slice(start, end).map((line, index2) => {\n      let number = start + 1 + index2;\n      let gutter = \" \" + (\" \" + number).slice(-maxWidth) + \" | \";\n      if (number === this.line) {\n        let spacing = aside(gutter.replace(/\\d/g, \" \")) + line.slice(0, this.column - 1).replace(/[^\\t]/g, \" \");\n        return mark(\">\") + aside(gutter) + line + \"\\n \" + spacing + mark(\"^\");\n      }\n      return \" \" + aside(gutter) + line;\n    }).join(\"\\n\");\n  }\n  toString() {\n    let code = this.showSourceCode();\n    if (code) {\n      code = \"\\n\\n\" + code + \"\\n\";\n    }\n    return this.name + \": \" + this.message + code;\n  }\n};\nvar cssSyntaxError = CssSyntaxError$3;\nCssSyntaxError$3.default = CssSyntaxError$3;\nvar symbols = {};\nsymbols.isClean = Symbol(\"isClean\");\nsymbols.my = Symbol(\"my\");\nconst DEFAULT_RAW = {\n  after: \"\\n\",\n  beforeClose: \"\\n\",\n  beforeComment: \"\\n\",\n  beforeDecl: \"\\n\",\n  beforeOpen: \" \",\n  beforeRule: \"\\n\",\n  colon: \": \",\n  commentLeft: \" \",\n  commentRight: \" \",\n  emptyBody: \"\",\n  indent: \"    \",\n  semicolon: false\n};\nfunction capitalize(str) {\n  return str[0].toUpperCase() + str.slice(1);\n}\nlet Stringifier$2 = class Stringifier {\n  constructor(builder) {\n    this.builder = builder;\n  }\n  atrule(node2, semicolon) {\n    let name = \"@\" + node2.name;\n    let params = node2.params ? this.rawValue(node2, \"params\") : \"\";\n    if (typeof node2.raws.afterName !== \"undefined\") {\n      name += node2.raws.afterName;\n    } else if (params) {\n      name += \" \";\n    }\n    if (node2.nodes) {\n      this.block(node2, name + params);\n    } else {\n      let end = (node2.raws.between || \"\") + (semicolon ? \";\" : \"\");\n      this.builder(name + params + end, node2);\n    }\n  }\n  beforeAfter(node2, detect) {\n    let value;\n    if (node2.type === \"decl\") {\n      value = this.raw(node2, null, \"beforeDecl\");\n    } else if (node2.type === \"comment\") {\n      value = this.raw(node2, null, \"beforeComment\");\n    } else if (detect === \"before\") {\n      value = this.raw(node2, null, \"beforeRule\");\n    } else {\n      value = this.raw(node2, null, \"beforeClose\");\n    }\n    let buf = node2.parent;\n    let depth = 0;\n    while (buf && buf.type !== \"root\") {\n      depth += 1;\n      buf = buf.parent;\n    }\n    if (value.includes(\"\\n\")) {\n      let indent = this.raw(node2, null, \"indent\");\n      if (indent.length) {\n        for (let step = 0; step < depth; step++) value += indent;\n      }\n    }\n    return value;\n  }\n  block(node2, start) {\n    let between = this.raw(node2, \"between\", \"beforeOpen\");\n    this.builder(start + between + \"{\", node2, \"start\");\n    let after;\n    if (node2.nodes && node2.nodes.length) {\n      this.body(node2);\n      after = this.raw(node2, \"after\");\n    } else {\n      after = this.raw(node2, \"after\", \"emptyBody\");\n    }\n    if (after) this.builder(after);\n    this.builder(\"}\", node2, \"end\");\n  }\n  body(node2) {\n    let last = node2.nodes.length - 1;\n    while (last > 0) {\n      if (node2.nodes[last].type !== \"comment\") break;\n      last -= 1;\n    }\n    let semicolon = this.raw(node2, \"semicolon\");\n    for (let i = 0; i < node2.nodes.length; i++) {\n      let child = node2.nodes[i];\n      let before = this.raw(child, \"before\");\n      if (before) this.builder(before);\n      this.stringify(child, last !== i || semicolon);\n    }\n  }\n  comment(node2) {\n    let left = this.raw(node2, \"left\", \"commentLeft\");\n    let right = this.raw(node2, \"right\", \"commentRight\");\n    this.builder(\"/*\" + left + node2.text + right + \"*/\", node2);\n  }\n  decl(node2, semicolon) {\n    let between = this.raw(node2, \"between\", \"colon\");\n    let string = node2.prop + between + this.rawValue(node2, \"value\");\n    if (node2.important) {\n      string += node2.raws.important || \" !important\";\n    }\n    if (semicolon) string += \";\";\n    this.builder(string, node2);\n  }\n  document(node2) {\n    this.body(node2);\n  }\n  raw(node2, own, detect) {\n    let value;\n    if (!detect) detect = own;\n    if (own) {\n      value = node2.raws[own];\n      if (typeof value !== \"undefined\") return value;\n    }\n    let parent = node2.parent;\n    if (detect === \"before\") {\n      if (!parent || parent.type === \"root\" && parent.first === node2) {\n        return \"\";\n      }\n      if (parent && parent.type === \"document\") {\n        return \"\";\n      }\n    }\n    if (!parent) return DEFAULT_RAW[detect];\n    let root2 = node2.root();\n    if (!root2.rawCache) root2.rawCache = {};\n    if (typeof root2.rawCache[detect] !== \"undefined\") {\n      return root2.rawCache[detect];\n    }\n    if (detect === \"before\" || detect === \"after\") {\n      return this.beforeAfter(node2, detect);\n    } else {\n      let method = \"raw\" + capitalize(detect);\n      if (this[method]) {\n        value = this[method](root2, node2);\n      } else {\n        root2.walk((i) => {\n          value = i.raws[own];\n          if (typeof value !== \"undefined\") return false;\n        });\n      }\n    }\n    if (typeof value === \"undefined\") value = DEFAULT_RAW[detect];\n    root2.rawCache[detect] = value;\n    return value;\n  }\n  rawBeforeClose(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && i.nodes.length > 0) {\n        if (typeof i.raws.after !== \"undefined\") {\n          value = i.raws.after;\n          if (value.includes(\"\\n\")) {\n            value = value.replace(/[^\\n]+$/, \"\");\n          }\n          return false;\n        }\n      }\n    });\n    if (value) value = value.replace(/\\S/g, \"\");\n    return value;\n  }\n  rawBeforeComment(root2, node2) {\n    let value;\n    root2.walkComments((i) => {\n      if (typeof i.raws.before !== \"undefined\") {\n        value = i.raws.before;\n        if (value.includes(\"\\n\")) {\n          value = value.replace(/[^\\n]+$/, \"\");\n        }\n        return false;\n      }\n    });\n    if (typeof value === \"undefined\") {\n      value = this.raw(node2, null, \"beforeDecl\");\n    } else if (value) {\n      value = value.replace(/\\S/g, \"\");\n    }\n    return value;\n  }\n  rawBeforeDecl(root2, node2) {\n    let value;\n    root2.walkDecls((i) => {\n      if (typeof i.raws.before !== \"undefined\") {\n        value = i.raws.before;\n        if (value.includes(\"\\n\")) {\n          value = value.replace(/[^\\n]+$/, \"\");\n        }\n        return false;\n      }\n    });\n    if (typeof value === \"undefined\") {\n      value = this.raw(node2, null, \"beforeRule\");\n    } else if (value) {\n      value = value.replace(/\\S/g, \"\");\n    }\n    return value;\n  }\n  rawBeforeOpen(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.type !== \"decl\") {\n        value = i.raws.between;\n        if (typeof value !== \"undefined\") return false;\n      }\n    });\n    return value;\n  }\n  rawBeforeRule(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && (i.parent !== root2 || root2.first !== i)) {\n        if (typeof i.raws.before !== \"undefined\") {\n          value = i.raws.before;\n          if (value.includes(\"\\n\")) {\n            value = value.replace(/[^\\n]+$/, \"\");\n          }\n          return false;\n        }\n      }\n    });\n    if (value) value = value.replace(/\\S/g, \"\");\n    return value;\n  }\n  rawColon(root2) {\n    let value;\n    root2.walkDecls((i) => {\n      if (typeof i.raws.between !== \"undefined\") {\n        value = i.raws.between.replace(/[^\\s:]/g, \"\");\n        return false;\n      }\n    });\n    return value;\n  }\n  rawEmptyBody(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && i.nodes.length === 0) {\n        value = i.raws.after;\n        if (typeof value !== \"undefined\") return false;\n      }\n    });\n    return value;\n  }\n  rawIndent(root2) {\n    if (root2.raws.indent) return root2.raws.indent;\n    let value;\n    root2.walk((i) => {\n      let p = i.parent;\n      if (p && p !== root2 && p.parent && p.parent === root2) {\n        if (typeof i.raws.before !== \"undefined\") {\n          let parts = i.raws.before.split(\"\\n\");\n          value = parts[parts.length - 1];\n          value = value.replace(/\\S/g, \"\");\n          return false;\n        }\n      }\n    });\n    return value;\n  }\n  rawSemicolon(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && i.nodes.length && i.last.type === \"decl\") {\n        value = i.raws.semicolon;\n        if (typeof value !== \"undefined\") return false;\n      }\n    });\n    return value;\n  }\n  rawValue(node2, prop) {\n    let value = node2[prop];\n    let raw = node2.raws[prop];\n    if (raw && raw.value === value) {\n      return raw.raw;\n    }\n    return value;\n  }\n  root(node2) {\n    this.body(node2);\n    if (node2.raws.after) this.builder(node2.raws.after);\n  }\n  rule(node2) {\n    this.block(node2, this.rawValue(node2, \"selector\"));\n    if (node2.raws.ownSemicolon) {\n      this.builder(node2.raws.ownSemicolon, node2, \"end\");\n    }\n  }\n  stringify(node2, semicolon) {\n    if (!this[node2.type]) {\n      throw new Error(\n        \"Unknown AST node type \" + node2.type + \". Maybe you need to change PostCSS stringifier.\"\n      );\n    }\n    this[node2.type](node2, semicolon);\n  }\n};\nvar stringifier = Stringifier$2;\nStringifier$2.default = Stringifier$2;\nlet Stringifier$1 = stringifier;\nfunction stringify$4(node2, builder) {\n  let str = new Stringifier$1(builder);\n  str.stringify(node2);\n}\nvar stringify_1 = stringify$4;\nstringify$4.default = stringify$4;\nlet { isClean: isClean$2, my: my$2 } = symbols;\nlet CssSyntaxError$2 = cssSyntaxError;\nlet Stringifier2 = stringifier;\nlet stringify$3 = stringify_1;\nfunction cloneNode(obj, parent) {\n  let cloned = new obj.constructor();\n  for (let i in obj) {\n    if (!Object.prototype.hasOwnProperty.call(obj, i)) {\n      continue;\n    }\n    if (i === \"proxyCache\") continue;\n    let value = obj[i];\n    let type = typeof value;\n    if (i === \"parent\" && type === \"object\") {\n      if (parent) cloned[i] = parent;\n    } else if (i === \"source\") {\n      cloned[i] = value;\n    } else if (Array.isArray(value)) {\n      cloned[i] = value.map((j) => cloneNode(j, cloned));\n    } else {\n      if (type === \"object\" && value !== null) value = cloneNode(value);\n      cloned[i] = value;\n    }\n  }\n  return cloned;\n}\nlet Node$4 = class Node {\n  constructor(defaults = {}) {\n    this.raws = {};\n    this[isClean$2] = false;\n    this[my$2] = true;\n    for (let name in defaults) {\n      if (name === \"nodes\") {\n        this.nodes = [];\n        for (let node2 of defaults[name]) {\n          if (typeof node2.clone === \"function\") {\n            this.append(node2.clone());\n          } else {\n            this.append(node2);\n          }\n        }\n      } else {\n        this[name] = defaults[name];\n      }\n    }\n  }\n  addToError(error) {\n    error.postcssNode = this;\n    if (error.stack && this.source && /\\n\\s{4}at /.test(error.stack)) {\n      let s = this.source;\n      error.stack = error.stack.replace(\n        /\\n\\s{4}at /,\n        `$&${s.input.from}:${s.start.line}:${s.start.column}$&`\n      );\n    }\n    return error;\n  }\n  after(add) {\n    this.parent.insertAfter(this, add);\n    return this;\n  }\n  assign(overrides = {}) {\n    for (let name in overrides) {\n      this[name] = overrides[name];\n    }\n    return this;\n  }\n  before(add) {\n    this.parent.insertBefore(this, add);\n    return this;\n  }\n  cleanRaws(keepBetween) {\n    delete this.raws.before;\n    delete this.raws.after;\n    if (!keepBetween) delete this.raws.between;\n  }\n  clone(overrides = {}) {\n    let cloned = cloneNode(this);\n    for (let name in overrides) {\n      cloned[name] = overrides[name];\n    }\n    return cloned;\n  }\n  cloneAfter(overrides = {}) {\n    let cloned = this.clone(overrides);\n    this.parent.insertAfter(this, cloned);\n    return cloned;\n  }\n  cloneBefore(overrides = {}) {\n    let cloned = this.clone(overrides);\n    this.parent.insertBefore(this, cloned);\n    return cloned;\n  }\n  error(message, opts = {}) {\n    if (this.source) {\n      let { end, start } = this.rangeBy(opts);\n      return this.source.input.error(\n        message,\n        { column: start.column, line: start.line },\n        { column: end.column, line: end.line },\n        opts\n      );\n    }\n    return new CssSyntaxError$2(message);\n  }\n  getProxyProcessor() {\n    return {\n      get(node2, prop) {\n        if (prop === \"proxyOf\") {\n          return node2;\n        } else if (prop === \"root\") {\n          return () => node2.root().toProxy();\n        } else {\n          return node2[prop];\n        }\n      },\n      set(node2, prop, value) {\n        if (node2[prop] === value) return true;\n        node2[prop] = value;\n        if (prop === \"prop\" || prop === \"value\" || prop === \"name\" || prop === \"params\" || prop === \"important\" || /* c8 ignore next */\n        prop === \"text\") {\n          node2.markDirty();\n        }\n        return true;\n      }\n    };\n  }\n  markDirty() {\n    if (this[isClean$2]) {\n      this[isClean$2] = false;\n      let next = this;\n      while (next = next.parent) {\n        next[isClean$2] = false;\n      }\n    }\n  }\n  next() {\n    if (!this.parent) return void 0;\n    let index2 = this.parent.index(this);\n    return this.parent.nodes[index2 + 1];\n  }\n  positionBy(opts, stringRepresentation) {\n    let pos = this.source.start;\n    if (opts.index) {\n      pos = this.positionInside(opts.index, stringRepresentation);\n    } else if (opts.word) {\n      stringRepresentation = this.toString();\n      let index2 = stringRepresentation.indexOf(opts.word);\n      if (index2 !== -1) pos = this.positionInside(index2, stringRepresentation);\n    }\n    return pos;\n  }\n  positionInside(index2, stringRepresentation) {\n    let string = stringRepresentation || this.toString();\n    let column = this.source.start.column;\n    let line = this.source.start.line;\n    for (let i = 0; i < index2; i++) {\n      if (string[i] === \"\\n\") {\n        column = 1;\n        line += 1;\n      } else {\n        column += 1;\n      }\n    }\n    return { column, line };\n  }\n  prev() {\n    if (!this.parent) return void 0;\n    let index2 = this.parent.index(this);\n    return this.parent.nodes[index2 - 1];\n  }\n  rangeBy(opts) {\n    let start = {\n      column: this.source.start.column,\n      line: this.source.start.line\n    };\n    let end = this.source.end ? {\n      column: this.source.end.column + 1,\n      line: this.source.end.line\n    } : {\n      column: start.column + 1,\n      line: start.line\n    };\n    if (opts.word) {\n      let stringRepresentation = this.toString();\n      let index2 = stringRepresentation.indexOf(opts.word);\n      if (index2 !== -1) {\n        start = this.positionInside(index2, stringRepresentation);\n        end = this.positionInside(index2 + opts.word.length, stringRepresentation);\n      }\n    } else {\n      if (opts.start) {\n        start = {\n          column: opts.start.column,\n          line: opts.start.line\n        };\n      } else if (opts.index) {\n        start = this.positionInside(opts.index);\n      }\n      if (opts.end) {\n        end = {\n          column: opts.end.column,\n          line: opts.end.line\n        };\n      } else if (typeof opts.endIndex === \"number\") {\n        end = this.positionInside(opts.endIndex);\n      } else if (opts.index) {\n        end = this.positionInside(opts.index + 1);\n      }\n    }\n    if (end.line < start.line || end.line === start.line && end.column <= start.column) {\n      end = { column: start.column + 1, line: start.line };\n    }\n    return { end, start };\n  }\n  raw(prop, defaultType) {\n    let str = new Stringifier2();\n    return str.raw(this, prop, defaultType);\n  }\n  remove() {\n    if (this.parent) {\n      this.parent.removeChild(this);\n    }\n    this.parent = void 0;\n    return this;\n  }\n  replaceWith(...nodes) {\n    if (this.parent) {\n      let bookmark = this;\n      let foundSelf = false;\n      for (let node2 of nodes) {\n        if (node2 === this) {\n          foundSelf = true;\n        } else if (foundSelf) {\n          this.parent.insertAfter(bookmark, node2);\n          bookmark = node2;\n        } else {\n          this.parent.insertBefore(bookmark, node2);\n        }\n      }\n      if (!foundSelf) {\n        this.remove();\n      }\n    }\n    return this;\n  }\n  root() {\n    let result2 = this;\n    while (result2.parent && result2.parent.type !== \"document\") {\n      result2 = result2.parent;\n    }\n    return result2;\n  }\n  toJSON(_, inputs) {\n    let fixed = {};\n    let emitInputs = inputs == null;\n    inputs = inputs || /* @__PURE__ */ new Map();\n    let inputsNextIndex = 0;\n    for (let name in this) {\n      if (!Object.prototype.hasOwnProperty.call(this, name)) {\n        continue;\n      }\n      if (name === \"parent\" || name === \"proxyCache\") continue;\n      let value = this[name];\n      if (Array.isArray(value)) {\n        fixed[name] = value.map((i) => {\n          if (typeof i === \"object\" && i.toJSON) {\n            return i.toJSON(null, inputs);\n          } else {\n            return i;\n          }\n        });\n      } else if (typeof value === \"object\" && value.toJSON) {\n        fixed[name] = value.toJSON(null, inputs);\n      } else if (name === \"source\") {\n        let inputId = inputs.get(value.input);\n        if (inputId == null) {\n          inputId = inputsNextIndex;\n          inputs.set(value.input, inputsNextIndex);\n          inputsNextIndex++;\n        }\n        fixed[name] = {\n          end: value.end,\n          inputId,\n          start: value.start\n        };\n      } else {\n        fixed[name] = value;\n      }\n    }\n    if (emitInputs) {\n      fixed.inputs = [...inputs.keys()].map((input2) => input2.toJSON());\n    }\n    return fixed;\n  }\n  toProxy() {\n    if (!this.proxyCache) {\n      this.proxyCache = new Proxy(this, this.getProxyProcessor());\n    }\n    return this.proxyCache;\n  }\n  toString(stringifier2 = stringify$3) {\n    if (stringifier2.stringify) stringifier2 = stringifier2.stringify;\n    let result2 = \"\";\n    stringifier2(this, (i) => {\n      result2 += i;\n    });\n    return result2;\n  }\n  warn(result2, text, opts) {\n    let data = { node: this };\n    for (let i in opts) data[i] = opts[i];\n    return result2.warn(text, data);\n  }\n  get proxyOf() {\n    return this;\n  }\n};\nvar node = Node$4;\nNode$4.default = Node$4;\nlet Node$3 = node;\nlet Declaration$4 = class Declaration extends Node$3 {\n  constructor(defaults) {\n    if (defaults && typeof defaults.value !== \"undefined\" && typeof defaults.value !== \"string\") {\n      defaults = { ...defaults, value: String(defaults.value) };\n    }\n    super(defaults);\n    this.type = \"decl\";\n  }\n  get variable() {\n    return this.prop.startsWith(\"--\") || this.prop[0] === \"$\";\n  }\n};\nvar declaration = Declaration$4;\nDeclaration$4.default = Declaration$4;\nlet urlAlphabet = \"useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict\";\nlet customAlphabet = (alphabet, defaultSize = 21) => {\n  return (size = defaultSize) => {\n    let id = \"\";\n    let i = size;\n    while (i--) {\n      id += alphabet[Math.random() * alphabet.length | 0];\n    }\n    return id;\n  };\n};\nlet nanoid$1 = (size = 21) => {\n  let id = \"\";\n  let i = size;\n  while (i--) {\n    id += urlAlphabet[Math.random() * 64 | 0];\n  }\n  return id;\n};\nvar nonSecure = { nanoid: nanoid$1, customAlphabet };\nlet { SourceMapConsumer: SourceMapConsumer$2, SourceMapGenerator: SourceMapGenerator$2 } = require$$2;\nlet { existsSync, readFileSync } = require$$2;\nlet { dirname: dirname$1, join } = require$$2;\nfunction fromBase64(str) {\n  if (Buffer) {\n    return Buffer.from(str, \"base64\").toString();\n  } else {\n    return window.atob(str);\n  }\n}\nlet PreviousMap$2 = class PreviousMap {\n  constructor(css, opts) {\n    if (opts.map === false) return;\n    this.loadAnnotation(css);\n    this.inline = this.startWith(this.annotation, \"data:\");\n    let prev = opts.map ? opts.map.prev : void 0;\n    let text = this.loadMap(opts.from, prev);\n    if (!this.mapFile && opts.from) {\n      this.mapFile = opts.from;\n    }\n    if (this.mapFile) this.root = dirname$1(this.mapFile);\n    if (text) this.text = text;\n  }\n  consumer() {\n    if (!this.consumerCache) {\n      this.consumerCache = new SourceMapConsumer$2(this.text);\n    }\n    return this.consumerCache;\n  }\n  decodeInline(text) {\n    let baseCharsetUri = /^data:application\\/json;charset=utf-?8;base64,/;\n    let baseUri = /^data:application\\/json;base64,/;\n    let charsetUri = /^data:application\\/json;charset=utf-?8,/;\n    let uri = /^data:application\\/json,/;\n    if (charsetUri.test(text) || uri.test(text)) {\n      return decodeURIComponent(text.substr(RegExp.lastMatch.length));\n    }\n    if (baseCharsetUri.test(text) || baseUri.test(text)) {\n      return fromBase64(text.substr(RegExp.lastMatch.length));\n    }\n    let encoding = text.match(/data:application\\/json;([^,]+),/)[1];\n    throw new Error(\"Unsupported source map encoding \" + encoding);\n  }\n  getAnnotationURL(sourceMapString) {\n    return sourceMapString.replace(/^\\/\\*\\s*# sourceMappingURL=/, \"\").trim();\n  }\n  isMap(map) {\n    if (typeof map !== \"object\") return false;\n    return typeof map.mappings === \"string\" || typeof map._mappings === \"string\" || Array.isArray(map.sections);\n  }\n  loadAnnotation(css) {\n    let comments = css.match(/\\/\\*\\s*# sourceMappingURL=/gm);\n    if (!comments) return;\n    let start = css.lastIndexOf(comments.pop());\n    let end = css.indexOf(\"*/\", start);\n    if (start > -1 && end > -1) {\n      this.annotation = this.getAnnotationURL(css.substring(start, end));\n    }\n  }\n  loadFile(path) {\n    this.root = dirname$1(path);\n    if (existsSync(path)) {\n      this.mapFile = path;\n      return readFileSync(path, \"utf-8\").toString().trim();\n    }\n  }\n  loadMap(file, prev) {\n    if (prev === false) return false;\n    if (prev) {\n      if (typeof prev === \"string\") {\n        return prev;\n      } else if (typeof prev === \"function\") {\n        let prevPath = prev(file);\n        if (prevPath) {\n          let map = this.loadFile(prevPath);\n          if (!map) {\n            throw new Error(\n              \"Unable to load previous source map: \" + prevPath.toString()\n            );\n          }\n          return map;\n        }\n      } else if (prev instanceof SourceMapConsumer$2) {\n        return SourceMapGenerator$2.fromSourceMap(prev).toString();\n      } else if (prev instanceof SourceMapGenerator$2) {\n        return prev.toString();\n      } else if (this.isMap(prev)) {\n        return JSON.stringify(prev);\n      } else {\n        throw new Error(\n          \"Unsupported previous source map format: \" + prev.toString()\n        );\n      }\n    } else if (this.inline) {\n      return this.decodeInline(this.annotation);\n    } else if (this.annotation) {\n      let map = this.annotation;\n      if (file) map = join(dirname$1(file), map);\n      return this.loadFile(map);\n    }\n  }\n  startWith(string, start) {\n    if (!string) return false;\n    return string.substr(0, start.length) === start;\n  }\n  withContent() {\n    return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0);\n  }\n};\nvar previousMap = PreviousMap$2;\nPreviousMap$2.default = PreviousMap$2;\nlet { SourceMapConsumer: SourceMapConsumer$1, SourceMapGenerator: SourceMapGenerator$1 } = require$$2;\nlet { fileURLToPath, pathToFileURL: pathToFileURL$1 } = require$$2;\nlet { isAbsolute, resolve: resolve$1 } = require$$2;\nlet { nanoid } = nonSecure;\nlet terminalHighlight = require$$2;\nlet CssSyntaxError$1 = cssSyntaxError;\nlet PreviousMap$1 = previousMap;\nlet fromOffsetCache = Symbol(\"fromOffsetCache\");\nlet sourceMapAvailable$1 = Boolean(SourceMapConsumer$1 && SourceMapGenerator$1);\nlet pathAvailable$1 = Boolean(resolve$1 && isAbsolute);\nlet Input$4 = class Input {\n  constructor(css, opts = {}) {\n    if (css === null || typeof css === \"undefined\" || typeof css === \"object\" && !css.toString) {\n      throw new Error(`PostCSS received ${css} instead of CSS string`);\n    }\n    this.css = css.toString();\n    if (this.css[0] === \"\\uFEFF\" || this.css[0] === \"￾\") {\n      this.hasBOM = true;\n      this.css = this.css.slice(1);\n    } else {\n      this.hasBOM = false;\n    }\n    if (opts.from) {\n      if (!pathAvailable$1 || /^\\w+:\\/\\//.test(opts.from) || isAbsolute(opts.from)) {\n        this.file = opts.from;\n      } else {\n        this.file = resolve$1(opts.from);\n      }\n    }\n    if (pathAvailable$1 && sourceMapAvailable$1) {\n      let map = new PreviousMap$1(this.css, opts);\n      if (map.text) {\n        this.map = map;\n        let file = map.consumer().file;\n        if (!this.file && file) this.file = this.mapResolve(file);\n      }\n    }\n    if (!this.file) {\n      this.id = \"<input css \" + nanoid(6) + \">\";\n    }\n    if (this.map) this.map.file = this.from;\n  }\n  error(message, line, column, opts = {}) {\n    let result2, endLine, endColumn;\n    if (line && typeof line === \"object\") {\n      let start = line;\n      let end = column;\n      if (typeof start.offset === \"number\") {\n        let pos = this.fromOffset(start.offset);\n        line = pos.line;\n        column = pos.col;\n      } else {\n        line = start.line;\n        column = start.column;\n      }\n      if (typeof end.offset === \"number\") {\n        let pos = this.fromOffset(end.offset);\n        endLine = pos.line;\n        endColumn = pos.col;\n      } else {\n        endLine = end.line;\n        endColumn = end.column;\n      }\n    } else if (!column) {\n      let pos = this.fromOffset(line);\n      line = pos.line;\n      column = pos.col;\n    }\n    let origin = this.origin(line, column, endLine, endColumn);\n    if (origin) {\n      result2 = new CssSyntaxError$1(\n        message,\n        origin.endLine === void 0 ? origin.line : { column: origin.column, line: origin.line },\n        origin.endLine === void 0 ? origin.column : { column: origin.endColumn, line: origin.endLine },\n        origin.source,\n        origin.file,\n        opts.plugin\n      );\n    } else {\n      result2 = new CssSyntaxError$1(\n        message,\n        endLine === void 0 ? line : { column, line },\n        endLine === void 0 ? column : { column: endColumn, line: endLine },\n        this.css,\n        this.file,\n        opts.plugin\n      );\n    }\n    result2.input = { column, endColumn, endLine, line, source: this.css };\n    if (this.file) {\n      if (pathToFileURL$1) {\n        result2.input.url = pathToFileURL$1(this.file).toString();\n      }\n      result2.input.file = this.file;\n    }\n    return result2;\n  }\n  fromOffset(offset) {\n    let lastLine, lineToIndex;\n    if (!this[fromOffsetCache]) {\n      let lines = this.css.split(\"\\n\");\n      lineToIndex = new Array(lines.length);\n      let prevIndex = 0;\n      for (let i = 0, l = lines.length; i < l; i++) {\n        lineToIndex[i] = prevIndex;\n        prevIndex += lines[i].length + 1;\n      }\n      this[fromOffsetCache] = lineToIndex;\n    } else {\n      lineToIndex = this[fromOffsetCache];\n    }\n    lastLine = lineToIndex[lineToIndex.length - 1];\n    let min = 0;\n    if (offset >= lastLine) {\n      min = lineToIndex.length - 1;\n    } else {\n      let max = lineToIndex.length - 2;\n      let mid;\n      while (min < max) {\n        mid = min + (max - min >> 1);\n        if (offset < lineToIndex[mid]) {\n          max = mid - 1;\n        } else if (offset >= lineToIndex[mid + 1]) {\n          min = mid + 1;\n        } else {\n          min = mid;\n          break;\n        }\n      }\n    }\n    return {\n      col: offset - lineToIndex[min] + 1,\n      line: min + 1\n    };\n  }\n  mapResolve(file) {\n    if (/^\\w+:\\/\\//.test(file)) {\n      return file;\n    }\n    return resolve$1(this.map.consumer().sourceRoot || this.map.root || \".\", file);\n  }\n  origin(line, column, endLine, endColumn) {\n    if (!this.map) return false;\n    let consumer = this.map.consumer();\n    let from = consumer.originalPositionFor({ column, line });\n    if (!from.source) return false;\n    let to;\n    if (typeof endLine === \"number\") {\n      to = consumer.originalPositionFor({ column: endColumn, line: endLine });\n    }\n    let fromUrl;\n    if (isAbsolute(from.source)) {\n      fromUrl = pathToFileURL$1(from.source);\n    } else {\n      fromUrl = new URL(\n        from.source,\n        this.map.consumer().sourceRoot || pathToFileURL$1(this.map.mapFile)\n      );\n    }\n    let result2 = {\n      column: from.column,\n      endColumn: to && to.column,\n      endLine: to && to.line,\n      line: from.line,\n      url: fromUrl.toString()\n    };\n    if (fromUrl.protocol === \"file:\") {\n      if (fileURLToPath) {\n        result2.file = fileURLToPath(fromUrl);\n      } else {\n        throw new Error(`file: protocol is not available in this PostCSS build`);\n      }\n    }\n    let source = consumer.sourceContentFor(from.source);\n    if (source) result2.source = source;\n    return result2;\n  }\n  toJSON() {\n    let json = {};\n    for (let name of [\"hasBOM\", \"css\", \"file\", \"id\"]) {\n      if (this[name] != null) {\n        json[name] = this[name];\n      }\n    }\n    if (this.map) {\n      json.map = { ...this.map };\n      if (json.map.consumerCache) {\n        json.map.consumerCache = void 0;\n      }\n    }\n    return json;\n  }\n  get from() {\n    return this.file || this.id;\n  }\n};\nvar input = Input$4;\nInput$4.default = Input$4;\nif (terminalHighlight && terminalHighlight.registerInput) {\n  terminalHighlight.registerInput(Input$4);\n}\nlet { SourceMapConsumer, SourceMapGenerator } = require$$2;\nlet { dirname, relative, resolve, sep } = require$$2;\nlet { pathToFileURL } = require$$2;\nlet Input$3 = input;\nlet sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);\nlet pathAvailable = Boolean(dirname && resolve && relative && sep);\nlet MapGenerator$2 = class MapGenerator {\n  constructor(stringify2, root2, opts, cssString) {\n    this.stringify = stringify2;\n    this.mapOpts = opts.map || {};\n    this.root = root2;\n    this.opts = opts;\n    this.css = cssString;\n    this.originalCSS = cssString;\n    this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute;\n    this.memoizedFileURLs = /* @__PURE__ */ new Map();\n    this.memoizedPaths = /* @__PURE__ */ new Map();\n    this.memoizedURLs = /* @__PURE__ */ new Map();\n  }\n  addAnnotation() {\n    let content;\n    if (this.isInline()) {\n      content = \"data:application/json;base64,\" + this.toBase64(this.map.toString());\n    } else if (typeof this.mapOpts.annotation === \"string\") {\n      content = this.mapOpts.annotation;\n    } else if (typeof this.mapOpts.annotation === \"function\") {\n      content = this.mapOpts.annotation(this.opts.to, this.root);\n    } else {\n      content = this.outputFile() + \".map\";\n    }\n    let eol = \"\\n\";\n    if (this.css.includes(\"\\r\\n\")) eol = \"\\r\\n\";\n    this.css += eol + \"/*# sourceMappingURL=\" + content + \" */\";\n  }\n  applyPrevMaps() {\n    for (let prev of this.previous()) {\n      let from = this.toUrl(this.path(prev.file));\n      let root2 = prev.root || dirname(prev.file);\n      let map;\n      if (this.mapOpts.sourcesContent === false) {\n        map = new SourceMapConsumer(prev.text);\n        if (map.sourcesContent) {\n          map.sourcesContent = null;\n        }\n      } else {\n        map = prev.consumer();\n      }\n      this.map.applySourceMap(map, from, this.toUrl(this.path(root2)));\n    }\n  }\n  clearAnnotation() {\n    if (this.mapOpts.annotation === false) return;\n    if (this.root) {\n      let node2;\n      for (let i = this.root.nodes.length - 1; i >= 0; i--) {\n        node2 = this.root.nodes[i];\n        if (node2.type !== \"comment\") continue;\n        if (node2.text.indexOf(\"# sourceMappingURL=\") === 0) {\n          this.root.removeChild(i);\n        }\n      }\n    } else if (this.css) {\n      this.css = this.css.replace(/\\n*?\\/\\*#[\\S\\s]*?\\*\\/$/gm, \"\");\n    }\n  }\n  generate() {\n    this.clearAnnotation();\n    if (pathAvailable && sourceMapAvailable && this.isMap()) {\n      return this.generateMap();\n    } else {\n      let result2 = \"\";\n      this.stringify(this.root, (i) => {\n        result2 += i;\n      });\n      return [result2];\n    }\n  }\n  generateMap() {\n    if (this.root) {\n      this.generateString();\n    } else if (this.previous().length === 1) {\n      let prev = this.previous()[0].consumer();\n      prev.file = this.outputFile();\n      this.map = SourceMapGenerator.fromSourceMap(prev, {\n        ignoreInvalidMapping: true\n      });\n    } else {\n      this.map = new SourceMapGenerator({\n        file: this.outputFile(),\n        ignoreInvalidMapping: true\n      });\n      this.map.addMapping({\n        generated: { column: 0, line: 1 },\n        original: { column: 0, line: 1 },\n        source: this.opts.from ? this.toUrl(this.path(this.opts.from)) : \"<no source>\"\n      });\n    }\n    if (this.isSourcesContent()) this.setSourcesContent();\n    if (this.root && this.previous().length > 0) this.applyPrevMaps();\n    if (this.isAnnotation()) this.addAnnotation();\n    if (this.isInline()) {\n      return [this.css];\n    } else {\n      return [this.css, this.map];\n    }\n  }\n  generateString() {\n    this.css = \"\";\n    this.map = new SourceMapGenerator({\n      file: this.outputFile(),\n      ignoreInvalidMapping: true\n    });\n    let line = 1;\n    let column = 1;\n    let noSource = \"<no source>\";\n    let mapping = {\n      generated: { column: 0, line: 0 },\n      original: { column: 0, line: 0 },\n      source: \"\"\n    };\n    let lines, last;\n    this.stringify(this.root, (str, node2, type) => {\n      this.css += str;\n      if (node2 && type !== \"end\") {\n        mapping.generated.line = line;\n        mapping.generated.column = column - 1;\n        if (node2.source && node2.source.start) {\n          mapping.source = this.sourcePath(node2);\n          mapping.original.line = node2.source.start.line;\n          mapping.original.column = node2.source.start.column - 1;\n          this.map.addMapping(mapping);\n        } else {\n          mapping.source = noSource;\n          mapping.original.line = 1;\n          mapping.original.column = 0;\n          this.map.addMapping(mapping);\n        }\n      }\n      lines = str.match(/\\n/g);\n      if (lines) {\n        line += lines.length;\n        last = str.lastIndexOf(\"\\n\");\n        column = str.length - last;\n      } else {\n        column += str.length;\n      }\n      if (node2 && type !== \"start\") {\n        let p = node2.parent || { raws: {} };\n        let childless = node2.type === \"decl\" || node2.type === \"atrule\" && !node2.nodes;\n        if (!childless || node2 !== p.last || p.raws.semicolon) {\n          if (node2.source && node2.source.end) {\n            mapping.source = this.sourcePath(node2);\n            mapping.original.line = node2.source.end.line;\n            mapping.original.column = node2.source.end.column - 1;\n            mapping.generated.line = line;\n            mapping.generated.column = column - 2;\n            this.map.addMapping(mapping);\n          } else {\n            mapping.source = noSource;\n            mapping.original.line = 1;\n            mapping.original.column = 0;\n            mapping.generated.line = line;\n            mapping.generated.column = column - 1;\n            this.map.addMapping(mapping);\n          }\n        }\n      }\n    });\n  }\n  isAnnotation() {\n    if (this.isInline()) {\n      return true;\n    }\n    if (typeof this.mapOpts.annotation !== \"undefined\") {\n      return this.mapOpts.annotation;\n    }\n    if (this.previous().length) {\n      return this.previous().some((i) => i.annotation);\n    }\n    return true;\n  }\n  isInline() {\n    if (typeof this.mapOpts.inline !== \"undefined\") {\n      return this.mapOpts.inline;\n    }\n    let annotation = this.mapOpts.annotation;\n    if (typeof annotation !== \"undefined\" && annotation !== true) {\n      return false;\n    }\n    if (this.previous().length) {\n      return this.previous().some((i) => i.inline);\n    }\n    return true;\n  }\n  isMap() {\n    if (typeof this.opts.map !== \"undefined\") {\n      return !!this.opts.map;\n    }\n    return this.previous().length > 0;\n  }\n  isSourcesContent() {\n    if (typeof this.mapOpts.sourcesContent !== \"undefined\") {\n      return this.mapOpts.sourcesContent;\n    }\n    if (this.previous().length) {\n      return this.previous().some((i) => i.withContent());\n    }\n    return true;\n  }\n  outputFile() {\n    if (this.opts.to) {\n      return this.path(this.opts.to);\n    } else if (this.opts.from) {\n      return this.path(this.opts.from);\n    } else {\n      return \"to.css\";\n    }\n  }\n  path(file) {\n    if (this.mapOpts.absolute) return file;\n    if (file.charCodeAt(0) === 60) return file;\n    if (/^\\w+:\\/\\//.test(file)) return file;\n    let cached = this.memoizedPaths.get(file);\n    if (cached) return cached;\n    let from = this.opts.to ? dirname(this.opts.to) : \".\";\n    if (typeof this.mapOpts.annotation === \"string\") {\n      from = dirname(resolve(from, this.mapOpts.annotation));\n    }\n    let path = relative(from, file);\n    this.memoizedPaths.set(file, path);\n    return path;\n  }\n  previous() {\n    if (!this.previousMaps) {\n      this.previousMaps = [];\n      if (this.root) {\n        this.root.walk((node2) => {\n          if (node2.source && node2.source.input.map) {\n            let map = node2.source.input.map;\n            if (!this.previousMaps.includes(map)) {\n              this.previousMaps.push(map);\n            }\n          }\n        });\n      } else {\n        let input2 = new Input$3(this.originalCSS, this.opts);\n        if (input2.map) this.previousMaps.push(input2.map);\n      }\n    }\n    return this.previousMaps;\n  }\n  setSourcesContent() {\n    let already = {};\n    if (this.root) {\n      this.root.walk((node2) => {\n        if (node2.source) {\n          let from = node2.source.input.from;\n          if (from && !already[from]) {\n            already[from] = true;\n            let fromUrl = this.usesFileUrls ? this.toFileUrl(from) : this.toUrl(this.path(from));\n            this.map.setSourceContent(fromUrl, node2.source.input.css);\n          }\n        }\n      });\n    } else if (this.css) {\n      let from = this.opts.from ? this.toUrl(this.path(this.opts.from)) : \"<no source>\";\n      this.map.setSourceContent(from, this.css);\n    }\n  }\n  sourcePath(node2) {\n    if (this.mapOpts.from) {\n      return this.toUrl(this.mapOpts.from);\n    } else if (this.usesFileUrls) {\n      return this.toFileUrl(node2.source.input.from);\n    } else {\n      return this.toUrl(this.path(node2.source.input.from));\n    }\n  }\n  toBase64(str) {\n    if (Buffer) {\n      return Buffer.from(str).toString(\"base64\");\n    } else {\n      return window.btoa(unescape(encodeURIComponent(str)));\n    }\n  }\n  toFileUrl(path) {\n    let cached = this.memoizedFileURLs.get(path);\n    if (cached) return cached;\n    if (pathToFileURL) {\n      let fileURL = pathToFileURL(path).toString();\n      this.memoizedFileURLs.set(path, fileURL);\n      return fileURL;\n    } else {\n      throw new Error(\n        \"`map.absolute` option is not available in this PostCSS build\"\n      );\n    }\n  }\n  toUrl(path) {\n    let cached = this.memoizedURLs.get(path);\n    if (cached) return cached;\n    if (sep === \"\\\\\") {\n      path = path.replace(/\\\\/g, \"/\");\n    }\n    let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent);\n    this.memoizedURLs.set(path, url);\n    return url;\n  }\n};\nvar mapGenerator = MapGenerator$2;\nlet Node$2 = node;\nlet Comment$4 = class Comment extends Node$2 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"comment\";\n  }\n};\nvar comment = Comment$4;\nComment$4.default = Comment$4;\nlet { isClean: isClean$1, my: my$1 } = symbols;\nlet Declaration$3 = declaration;\nlet Comment$3 = comment;\nlet Node$1 = node;\nlet parse$4, Rule$4, AtRule$4, Root$6;\nfunction cleanSource(nodes) {\n  return nodes.map((i) => {\n    if (i.nodes) i.nodes = cleanSource(i.nodes);\n    delete i.source;\n    return i;\n  });\n}\nfunction markDirtyUp(node2) {\n  node2[isClean$1] = false;\n  if (node2.proxyOf.nodes) {\n    for (let i of node2.proxyOf.nodes) {\n      markDirtyUp(i);\n    }\n  }\n}\nlet Container$7 = class Container extends Node$1 {\n  append(...children) {\n    for (let child of children) {\n      let nodes = this.normalize(child, this.last);\n      for (let node2 of nodes) this.proxyOf.nodes.push(node2);\n    }\n    this.markDirty();\n    return this;\n  }\n  cleanRaws(keepBetween) {\n    super.cleanRaws(keepBetween);\n    if (this.nodes) {\n      for (let node2 of this.nodes) node2.cleanRaws(keepBetween);\n    }\n  }\n  each(callback) {\n    if (!this.proxyOf.nodes) return void 0;\n    let iterator = this.getIterator();\n    let index2, result2;\n    while (this.indexes[iterator] < this.proxyOf.nodes.length) {\n      index2 = this.indexes[iterator];\n      result2 = callback(this.proxyOf.nodes[index2], index2);\n      if (result2 === false) break;\n      this.indexes[iterator] += 1;\n    }\n    delete this.indexes[iterator];\n    return result2;\n  }\n  every(condition) {\n    return this.nodes.every(condition);\n  }\n  getIterator() {\n    if (!this.lastEach) this.lastEach = 0;\n    if (!this.indexes) this.indexes = {};\n    this.lastEach += 1;\n    let iterator = this.lastEach;\n    this.indexes[iterator] = 0;\n    return iterator;\n  }\n  getProxyProcessor() {\n    return {\n      get(node2, prop) {\n        if (prop === \"proxyOf\") {\n          return node2;\n        } else if (!node2[prop]) {\n          return node2[prop];\n        } else if (prop === \"each\" || typeof prop === \"string\" && prop.startsWith(\"walk\")) {\n          return (...args) => {\n            return node2[prop](\n              ...args.map((i) => {\n                if (typeof i === \"function\") {\n                  return (child, index2) => i(child.toProxy(), index2);\n                } else {\n                  return i;\n                }\n              })\n            );\n          };\n        } else if (prop === \"every\" || prop === \"some\") {\n          return (cb) => {\n            return node2[prop](\n              (child, ...other) => cb(child.toProxy(), ...other)\n            );\n          };\n        } else if (prop === \"root\") {\n          return () => node2.root().toProxy();\n        } else if (prop === \"nodes\") {\n          return node2.nodes.map((i) => i.toProxy());\n        } else if (prop === \"first\" || prop === \"last\") {\n          return node2[prop].toProxy();\n        } else {\n          return node2[prop];\n        }\n      },\n      set(node2, prop, value) {\n        if (node2[prop] === value) return true;\n        node2[prop] = value;\n        if (prop === \"name\" || prop === \"params\" || prop === \"selector\") {\n          node2.markDirty();\n        }\n        return true;\n      }\n    };\n  }\n  index(child) {\n    if (typeof child === \"number\") return child;\n    if (child.proxyOf) child = child.proxyOf;\n    return this.proxyOf.nodes.indexOf(child);\n  }\n  insertAfter(exist, add) {\n    let existIndex = this.index(exist);\n    let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse();\n    existIndex = this.index(exist);\n    for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node2);\n    let index2;\n    for (let id in this.indexes) {\n      index2 = this.indexes[id];\n      if (existIndex < index2) {\n        this.indexes[id] = index2 + nodes.length;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  insertBefore(exist, add) {\n    let existIndex = this.index(exist);\n    let type = existIndex === 0 ? \"prepend\" : false;\n    let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse();\n    existIndex = this.index(exist);\n    for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex, 0, node2);\n    let index2;\n    for (let id in this.indexes) {\n      index2 = this.indexes[id];\n      if (existIndex <= index2) {\n        this.indexes[id] = index2 + nodes.length;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  normalize(nodes, sample) {\n    if (typeof nodes === \"string\") {\n      nodes = cleanSource(parse$4(nodes).nodes);\n    } else if (typeof nodes === \"undefined\") {\n      nodes = [];\n    } else if (Array.isArray(nodes)) {\n      nodes = nodes.slice(0);\n      for (let i of nodes) {\n        if (i.parent) i.parent.removeChild(i, \"ignore\");\n      }\n    } else if (nodes.type === \"root\" && this.type !== \"document\") {\n      nodes = nodes.nodes.slice(0);\n      for (let i of nodes) {\n        if (i.parent) i.parent.removeChild(i, \"ignore\");\n      }\n    } else if (nodes.type) {\n      nodes = [nodes];\n    } else if (nodes.prop) {\n      if (typeof nodes.value === \"undefined\") {\n        throw new Error(\"Value field is missed in node creation\");\n      } else if (typeof nodes.value !== \"string\") {\n        nodes.value = String(nodes.value);\n      }\n      nodes = [new Declaration$3(nodes)];\n    } else if (nodes.selector) {\n      nodes = [new Rule$4(nodes)];\n    } else if (nodes.name) {\n      nodes = [new AtRule$4(nodes)];\n    } else if (nodes.text) {\n      nodes = [new Comment$3(nodes)];\n    } else {\n      throw new Error(\"Unknown node type in node creation\");\n    }\n    let processed = nodes.map((i) => {\n      if (!i[my$1]) Container.rebuild(i);\n      i = i.proxyOf;\n      if (i.parent) i.parent.removeChild(i);\n      if (i[isClean$1]) markDirtyUp(i);\n      if (typeof i.raws.before === \"undefined\") {\n        if (sample && typeof sample.raws.before !== \"undefined\") {\n          i.raws.before = sample.raws.before.replace(/\\S/g, \"\");\n        }\n      }\n      i.parent = this.proxyOf;\n      return i;\n    });\n    return processed;\n  }\n  prepend(...children) {\n    children = children.reverse();\n    for (let child of children) {\n      let nodes = this.normalize(child, this.first, \"prepend\").reverse();\n      for (let node2 of nodes) this.proxyOf.nodes.unshift(node2);\n      for (let id in this.indexes) {\n        this.indexes[id] = this.indexes[id] + nodes.length;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  push(child) {\n    child.parent = this;\n    this.proxyOf.nodes.push(child);\n    return this;\n  }\n  removeAll() {\n    for (let node2 of this.proxyOf.nodes) node2.parent = void 0;\n    this.proxyOf.nodes = [];\n    this.markDirty();\n    return this;\n  }\n  removeChild(child) {\n    child = this.index(child);\n    this.proxyOf.nodes[child].parent = void 0;\n    this.proxyOf.nodes.splice(child, 1);\n    let index2;\n    for (let id in this.indexes) {\n      index2 = this.indexes[id];\n      if (index2 >= child) {\n        this.indexes[id] = index2 - 1;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  replaceValues(pattern, opts, callback) {\n    if (!callback) {\n      callback = opts;\n      opts = {};\n    }\n    this.walkDecls((decl) => {\n      if (opts.props && !opts.props.includes(decl.prop)) return;\n      if (opts.fast && !decl.value.includes(opts.fast)) return;\n      decl.value = decl.value.replace(pattern, callback);\n    });\n    this.markDirty();\n    return this;\n  }\n  some(condition) {\n    return this.nodes.some(condition);\n  }\n  walk(callback) {\n    return this.each((child, i) => {\n      let result2;\n      try {\n        result2 = callback(child, i);\n      } catch (e) {\n        throw child.addToError(e);\n      }\n      if (result2 !== false && child.walk) {\n        result2 = child.walk(callback);\n      }\n      return result2;\n    });\n  }\n  walkAtRules(name, callback) {\n    if (!callback) {\n      callback = name;\n      return this.walk((child, i) => {\n        if (child.type === \"atrule\") {\n          return callback(child, i);\n        }\n      });\n    }\n    if (name instanceof RegExp) {\n      return this.walk((child, i) => {\n        if (child.type === \"atrule\" && name.test(child.name)) {\n          return callback(child, i);\n        }\n      });\n    }\n    return this.walk((child, i) => {\n      if (child.type === \"atrule\" && child.name === name) {\n        return callback(child, i);\n      }\n    });\n  }\n  walkComments(callback) {\n    return this.walk((child, i) => {\n      if (child.type === \"comment\") {\n        return callback(child, i);\n      }\n    });\n  }\n  walkDecls(prop, callback) {\n    if (!callback) {\n      callback = prop;\n      return this.walk((child, i) => {\n        if (child.type === \"decl\") {\n          return callback(child, i);\n        }\n      });\n    }\n    if (prop instanceof RegExp) {\n      return this.walk((child, i) => {\n        if (child.type === \"decl\" && prop.test(child.prop)) {\n          return callback(child, i);\n        }\n      });\n    }\n    return this.walk((child, i) => {\n      if (child.type === \"decl\" && child.prop === prop) {\n        return callback(child, i);\n      }\n    });\n  }\n  walkRules(selector, callback) {\n    if (!callback) {\n      callback = selector;\n      return this.walk((child, i) => {\n        if (child.type === \"rule\") {\n          return callback(child, i);\n        }\n      });\n    }\n    if (selector instanceof RegExp) {\n      return this.walk((child, i) => {\n        if (child.type === \"rule\" && selector.test(child.selector)) {\n          return callback(child, i);\n        }\n      });\n    }\n    return this.walk((child, i) => {\n      if (child.type === \"rule\" && child.selector === selector) {\n        return callback(child, i);\n      }\n    });\n  }\n  get first() {\n    if (!this.proxyOf.nodes) return void 0;\n    return this.proxyOf.nodes[0];\n  }\n  get last() {\n    if (!this.proxyOf.nodes) return void 0;\n    return this.proxyOf.nodes[this.proxyOf.nodes.length - 1];\n  }\n};\nContainer$7.registerParse = (dependant) => {\n  parse$4 = dependant;\n};\nContainer$7.registerRule = (dependant) => {\n  Rule$4 = dependant;\n};\nContainer$7.registerAtRule = (dependant) => {\n  AtRule$4 = dependant;\n};\nContainer$7.registerRoot = (dependant) => {\n  Root$6 = dependant;\n};\nvar container = Container$7;\nContainer$7.default = Container$7;\nContainer$7.rebuild = (node2) => {\n  if (node2.type === \"atrule\") {\n    Object.setPrototypeOf(node2, AtRule$4.prototype);\n  } else if (node2.type === \"rule\") {\n    Object.setPrototypeOf(node2, Rule$4.prototype);\n  } else if (node2.type === \"decl\") {\n    Object.setPrototypeOf(node2, Declaration$3.prototype);\n  } else if (node2.type === \"comment\") {\n    Object.setPrototypeOf(node2, Comment$3.prototype);\n  } else if (node2.type === \"root\") {\n    Object.setPrototypeOf(node2, Root$6.prototype);\n  }\n  node2[my$1] = true;\n  if (node2.nodes) {\n    node2.nodes.forEach((child) => {\n      Container$7.rebuild(child);\n    });\n  }\n};\nlet Container$6 = container;\nlet LazyResult$4, Processor$3;\nlet Document$3 = class Document extends Container$6 {\n  constructor(defaults) {\n    super({ type: \"document\", ...defaults });\n    if (!this.nodes) {\n      this.nodes = [];\n    }\n  }\n  toResult(opts = {}) {\n    let lazy = new LazyResult$4(new Processor$3(), this, opts);\n    return lazy.stringify();\n  }\n};\nDocument$3.registerLazyResult = (dependant) => {\n  LazyResult$4 = dependant;\n};\nDocument$3.registerProcessor = (dependant) => {\n  Processor$3 = dependant;\n};\nvar document$1 = Document$3;\nDocument$3.default = Document$3;\nlet printed = {};\nvar warnOnce$2 = function warnOnce(message) {\n  if (printed[message]) return;\n  printed[message] = true;\n  if (typeof console !== \"undefined\" && console.warn) {\n    console.warn(message);\n  }\n};\nlet Warning$2 = class Warning {\n  constructor(text, opts = {}) {\n    this.type = \"warning\";\n    this.text = text;\n    if (opts.node && opts.node.source) {\n      let range = opts.node.rangeBy(opts);\n      this.line = range.start.line;\n      this.column = range.start.column;\n      this.endLine = range.end.line;\n      this.endColumn = range.end.column;\n    }\n    for (let opt in opts) this[opt] = opts[opt];\n  }\n  toString() {\n    if (this.node) {\n      return this.node.error(this.text, {\n        index: this.index,\n        plugin: this.plugin,\n        word: this.word\n      }).message;\n    }\n    if (this.plugin) {\n      return this.plugin + \": \" + this.text;\n    }\n    return this.text;\n  }\n};\nvar warning = Warning$2;\nWarning$2.default = Warning$2;\nlet Warning$1 = warning;\nlet Result$3 = class Result {\n  constructor(processor2, root2, opts) {\n    this.processor = processor2;\n    this.messages = [];\n    this.root = root2;\n    this.opts = opts;\n    this.css = void 0;\n    this.map = void 0;\n  }\n  toString() {\n    return this.css;\n  }\n  warn(text, opts = {}) {\n    if (!opts.plugin) {\n      if (this.lastPlugin && this.lastPlugin.postcssPlugin) {\n        opts.plugin = this.lastPlugin.postcssPlugin;\n      }\n    }\n    let warning2 = new Warning$1(text, opts);\n    this.messages.push(warning2);\n    return warning2;\n  }\n  warnings() {\n    return this.messages.filter((i) => i.type === \"warning\");\n  }\n  get content() {\n    return this.css;\n  }\n};\nvar result = Result$3;\nResult$3.default = Result$3;\nconst SINGLE_QUOTE = \"'\".charCodeAt(0);\nconst DOUBLE_QUOTE = '\"'.charCodeAt(0);\nconst BACKSLASH = \"\\\\\".charCodeAt(0);\nconst SLASH = \"/\".charCodeAt(0);\nconst NEWLINE = \"\\n\".charCodeAt(0);\nconst SPACE = \" \".charCodeAt(0);\nconst FEED = \"\\f\".charCodeAt(0);\nconst TAB = \"\t\".charCodeAt(0);\nconst CR = \"\\r\".charCodeAt(0);\nconst OPEN_SQUARE = \"[\".charCodeAt(0);\nconst CLOSE_SQUARE = \"]\".charCodeAt(0);\nconst OPEN_PARENTHESES = \"(\".charCodeAt(0);\nconst CLOSE_PARENTHESES = \")\".charCodeAt(0);\nconst OPEN_CURLY = \"{\".charCodeAt(0);\nconst CLOSE_CURLY = \"}\".charCodeAt(0);\nconst SEMICOLON = \";\".charCodeAt(0);\nconst ASTERISK = \"*\".charCodeAt(0);\nconst COLON = \":\".charCodeAt(0);\nconst AT = \"@\".charCodeAt(0);\nconst RE_AT_END = /[\\t\\n\\f\\r \"#'()/;[\\\\\\]{}]/g;\nconst RE_WORD_END = /[\\t\\n\\f\\r !\"#'():;@[\\\\\\]{}]|\\/(?=\\*)/g;\nconst RE_BAD_BRACKET = /.[\\r\\n\"'(/\\\\]/;\nconst RE_HEX_ESCAPE = /[\\da-f]/i;\nvar tokenize = function tokenizer(input2, options = {}) {\n  let css = input2.css.valueOf();\n  let ignore = options.ignoreErrors;\n  let code, next, quote, content, escape;\n  let escaped, escapePos, prev, n, currentToken;\n  let length = css.length;\n  let pos = 0;\n  let buffer = [];\n  let returned = [];\n  function position() {\n    return pos;\n  }\n  function unclosed(what) {\n    throw input2.error(\"Unclosed \" + what, pos);\n  }\n  function endOfFile() {\n    return returned.length === 0 && pos >= length;\n  }\n  function nextToken(opts) {\n    if (returned.length) return returned.pop();\n    if (pos >= length) return;\n    let ignoreUnclosed = opts ? opts.ignoreUnclosed : false;\n    code = css.charCodeAt(pos);\n    switch (code) {\n      case NEWLINE:\n      case SPACE:\n      case TAB:\n      case CR:\n      case FEED: {\n        next = pos;\n        do {\n          next += 1;\n          code = css.charCodeAt(next);\n        } while (code === SPACE || code === NEWLINE || code === TAB || code === CR || code === FEED);\n        currentToken = [\"space\", css.slice(pos, next)];\n        pos = next - 1;\n        break;\n      }\n      case OPEN_SQUARE:\n      case CLOSE_SQUARE:\n      case OPEN_CURLY:\n      case CLOSE_CURLY:\n      case COLON:\n      case SEMICOLON:\n      case CLOSE_PARENTHESES: {\n        let controlChar = String.fromCharCode(code);\n        currentToken = [controlChar, controlChar, pos];\n        break;\n      }\n      case OPEN_PARENTHESES: {\n        prev = buffer.length ? buffer.pop()[1] : \"\";\n        n = css.charCodeAt(pos + 1);\n        if (prev === \"url\" && n !== SINGLE_QUOTE && n !== DOUBLE_QUOTE && n !== SPACE && n !== NEWLINE && n !== TAB && n !== FEED && n !== CR) {\n          next = pos;\n          do {\n            escaped = false;\n            next = css.indexOf(\")\", next + 1);\n            if (next === -1) {\n              if (ignore || ignoreUnclosed) {\n                next = pos;\n                break;\n              } else {\n                unclosed(\"bracket\");\n              }\n            }\n            escapePos = next;\n            while (css.charCodeAt(escapePos - 1) === BACKSLASH) {\n              escapePos -= 1;\n              escaped = !escaped;\n            }\n          } while (escaped);\n          currentToken = [\"brackets\", css.slice(pos, next + 1), pos, next];\n          pos = next;\n        } else {\n          next = css.indexOf(\")\", pos + 1);\n          content = css.slice(pos, next + 1);\n          if (next === -1 || RE_BAD_BRACKET.test(content)) {\n            currentToken = [\"(\", \"(\", pos];\n          } else {\n            currentToken = [\"brackets\", content, pos, next];\n            pos = next;\n          }\n        }\n        break;\n      }\n      case SINGLE_QUOTE:\n      case DOUBLE_QUOTE: {\n        quote = code === SINGLE_QUOTE ? \"'\" : '\"';\n        next = pos;\n        do {\n          escaped = false;\n          next = css.indexOf(quote, next + 1);\n          if (next === -1) {\n            if (ignore || ignoreUnclosed) {\n              next = pos + 1;\n              break;\n            } else {\n              unclosed(\"string\");\n            }\n          }\n          escapePos = next;\n          while (css.charCodeAt(escapePos - 1) === BACKSLASH) {\n            escapePos -= 1;\n            escaped = !escaped;\n          }\n        } while (escaped);\n        currentToken = [\"string\", css.slice(pos, next + 1), pos, next];\n        pos = next;\n        break;\n      }\n      case AT: {\n        RE_AT_END.lastIndex = pos + 1;\n        RE_AT_END.test(css);\n        if (RE_AT_END.lastIndex === 0) {\n          next = css.length - 1;\n        } else {\n          next = RE_AT_END.lastIndex - 2;\n        }\n        currentToken = [\"at-word\", css.slice(pos, next + 1), pos, next];\n        pos = next;\n        break;\n      }\n      case BACKSLASH: {\n        next = pos;\n        escape = true;\n        while (css.charCodeAt(next + 1) === BACKSLASH) {\n          next += 1;\n          escape = !escape;\n        }\n        code = css.charCodeAt(next + 1);\n        if (escape && code !== SLASH && code !== SPACE && code !== NEWLINE && code !== TAB && code !== CR && code !== FEED) {\n          next += 1;\n          if (RE_HEX_ESCAPE.test(css.charAt(next))) {\n            while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) {\n              next += 1;\n            }\n            if (css.charCodeAt(next + 1) === SPACE) {\n              next += 1;\n            }\n          }\n        }\n        currentToken = [\"word\", css.slice(pos, next + 1), pos, next];\n        pos = next;\n        break;\n      }\n      default: {\n        if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) {\n          next = css.indexOf(\"*/\", pos + 2) + 1;\n          if (next === 0) {\n            if (ignore || ignoreUnclosed) {\n              next = css.length;\n            } else {\n              unclosed(\"comment\");\n            }\n          }\n          currentToken = [\"comment\", css.slice(pos, next + 1), pos, next];\n          pos = next;\n        } else {\n          RE_WORD_END.lastIndex = pos + 1;\n          RE_WORD_END.test(css);\n          if (RE_WORD_END.lastIndex === 0) {\n            next = css.length - 1;\n          } else {\n            next = RE_WORD_END.lastIndex - 2;\n          }\n          currentToken = [\"word\", css.slice(pos, next + 1), pos, next];\n          buffer.push(currentToken);\n          pos = next;\n        }\n        break;\n      }\n    }\n    pos++;\n    return currentToken;\n  }\n  function back(token) {\n    returned.push(token);\n  }\n  return {\n    back,\n    endOfFile,\n    nextToken,\n    position\n  };\n};\nlet Container$5 = container;\nlet AtRule$3 = class AtRule extends Container$5 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"atrule\";\n  }\n  append(...children) {\n    if (!this.proxyOf.nodes) this.nodes = [];\n    return super.append(...children);\n  }\n  prepend(...children) {\n    if (!this.proxyOf.nodes) this.nodes = [];\n    return super.prepend(...children);\n  }\n};\nvar atRule = AtRule$3;\nAtRule$3.default = AtRule$3;\nContainer$5.registerAtRule(AtRule$3);\nlet Container$4 = container;\nlet LazyResult$3, Processor$2;\nlet Root$5 = class Root extends Container$4 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"root\";\n    if (!this.nodes) this.nodes = [];\n  }\n  normalize(child, sample, type) {\n    let nodes = super.normalize(child);\n    if (sample) {\n      if (type === \"prepend\") {\n        if (this.nodes.length > 1) {\n          sample.raws.before = this.nodes[1].raws.before;\n        } else {\n          delete sample.raws.before;\n        }\n      } else if (this.first !== sample) {\n        for (let node2 of nodes) {\n          node2.raws.before = sample.raws.before;\n        }\n      }\n    }\n    return nodes;\n  }\n  removeChild(child, ignore) {\n    let index2 = this.index(child);\n    if (!ignore && index2 === 0 && this.nodes.length > 1) {\n      this.nodes[1].raws.before = this.nodes[index2].raws.before;\n    }\n    return super.removeChild(child);\n  }\n  toResult(opts = {}) {\n    let lazy = new LazyResult$3(new Processor$2(), this, opts);\n    return lazy.stringify();\n  }\n};\nRoot$5.registerLazyResult = (dependant) => {\n  LazyResult$3 = dependant;\n};\nRoot$5.registerProcessor = (dependant) => {\n  Processor$2 = dependant;\n};\nvar root = Root$5;\nRoot$5.default = Root$5;\nContainer$4.registerRoot(Root$5);\nlet list$2 = {\n  comma(string) {\n    return list$2.split(string, [\",\"], true);\n  },\n  space(string) {\n    let spaces = [\" \", \"\\n\", \"\t\"];\n    return list$2.split(string, spaces);\n  },\n  split(string, separators, last) {\n    let array = [];\n    let current = \"\";\n    let split = false;\n    let func = 0;\n    let inQuote = false;\n    let prevQuote = \"\";\n    let escape = false;\n    for (let letter of string) {\n      if (escape) {\n        escape = false;\n      } else if (letter === \"\\\\\") {\n        escape = true;\n      } else if (inQuote) {\n        if (letter === prevQuote) {\n          inQuote = false;\n        }\n      } else if (letter === '\"' || letter === \"'\") {\n        inQuote = true;\n        prevQuote = letter;\n      } else if (letter === \"(\") {\n        func += 1;\n      } else if (letter === \")\") {\n        if (func > 0) func -= 1;\n      } else if (func === 0) {\n        if (separators.includes(letter)) split = true;\n      }\n      if (split) {\n        if (current !== \"\") array.push(current.trim());\n        current = \"\";\n        split = false;\n      } else {\n        current += letter;\n      }\n    }\n    if (last || current !== \"\") array.push(current.trim());\n    return array;\n  }\n};\nvar list_1 = list$2;\nlist$2.default = list$2;\nlet Container$3 = container;\nlet list$1 = list_1;\nlet Rule$3 = class Rule extends Container$3 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"rule\";\n    if (!this.nodes) this.nodes = [];\n  }\n  get selectors() {\n    return list$1.comma(this.selector);\n  }\n  set selectors(values) {\n    let match = this.selector ? this.selector.match(/,\\s*/) : null;\n    let sep2 = match ? match[0] : \",\" + this.raw(\"between\", \"beforeOpen\");\n    this.selector = values.join(sep2);\n  }\n};\nvar rule = Rule$3;\nRule$3.default = Rule$3;\nContainer$3.registerRule(Rule$3);\nlet Declaration$2 = declaration;\nlet tokenizer2 = tokenize;\nlet Comment$2 = comment;\nlet AtRule$2 = atRule;\nlet Root$4 = root;\nlet Rule$2 = rule;\nconst SAFE_COMMENT_NEIGHBOR = {\n  empty: true,\n  space: true\n};\nfunction findLastWithPosition(tokens) {\n  for (let i = tokens.length - 1; i >= 0; i--) {\n    let token = tokens[i];\n    let pos = token[3] || token[2];\n    if (pos) return pos;\n  }\n}\nlet Parser$1 = class Parser {\n  constructor(input2) {\n    this.input = input2;\n    this.root = new Root$4();\n    this.current = this.root;\n    this.spaces = \"\";\n    this.semicolon = false;\n    this.createTokenizer();\n    this.root.source = { input: input2, start: { column: 1, line: 1, offset: 0 } };\n  }\n  atrule(token) {\n    let node2 = new AtRule$2();\n    node2.name = token[1].slice(1);\n    if (node2.name === \"\") {\n      this.unnamedAtrule(node2, token);\n    }\n    this.init(node2, token[2]);\n    let type;\n    let prev;\n    let shift;\n    let last = false;\n    let open = false;\n    let params = [];\n    let brackets = [];\n    while (!this.tokenizer.endOfFile()) {\n      token = this.tokenizer.nextToken();\n      type = token[0];\n      if (type === \"(\" || type === \"[\") {\n        brackets.push(type === \"(\" ? \")\" : \"]\");\n      } else if (type === \"{\" && brackets.length > 0) {\n        brackets.push(\"}\");\n      } else if (type === brackets[brackets.length - 1]) {\n        brackets.pop();\n      }\n      if (brackets.length === 0) {\n        if (type === \";\") {\n          node2.source.end = this.getPosition(token[2]);\n          node2.source.end.offset++;\n          this.semicolon = true;\n          break;\n        } else if (type === \"{\") {\n          open = true;\n          break;\n        } else if (type === \"}\") {\n          if (params.length > 0) {\n            shift = params.length - 1;\n            prev = params[shift];\n            while (prev && prev[0] === \"space\") {\n              prev = params[--shift];\n            }\n            if (prev) {\n              node2.source.end = this.getPosition(prev[3] || prev[2]);\n              node2.source.end.offset++;\n            }\n          }\n          this.end(token);\n          break;\n        } else {\n          params.push(token);\n        }\n      } else {\n        params.push(token);\n      }\n      if (this.tokenizer.endOfFile()) {\n        last = true;\n        break;\n      }\n    }\n    node2.raws.between = this.spacesAndCommentsFromEnd(params);\n    if (params.length) {\n      node2.raws.afterName = this.spacesAndCommentsFromStart(params);\n      this.raw(node2, \"params\", params);\n      if (last) {\n        token = params[params.length - 1];\n        node2.source.end = this.getPosition(token[3] || token[2]);\n        node2.source.end.offset++;\n        this.spaces = node2.raws.between;\n        node2.raws.between = \"\";\n      }\n    } else {\n      node2.raws.afterName = \"\";\n      node2.params = \"\";\n    }\n    if (open) {\n      node2.nodes = [];\n      this.current = node2;\n    }\n  }\n  checkMissedSemicolon(tokens) {\n    let colon = this.colon(tokens);\n    if (colon === false) return;\n    let founded = 0;\n    let token;\n    for (let j = colon - 1; j >= 0; j--) {\n      token = tokens[j];\n      if (token[0] !== \"space\") {\n        founded += 1;\n        if (founded === 2) break;\n      }\n    }\n    throw this.input.error(\n      \"Missed semicolon\",\n      token[0] === \"word\" ? token[3] + 1 : token[2]\n    );\n  }\n  colon(tokens) {\n    let brackets = 0;\n    let token, type, prev;\n    for (let [i, element] of tokens.entries()) {\n      token = element;\n      type = token[0];\n      if (type === \"(\") {\n        brackets += 1;\n      }\n      if (type === \")\") {\n        brackets -= 1;\n      }\n      if (brackets === 0 && type === \":\") {\n        if (!prev) {\n          this.doubleColon(token);\n        } else if (prev[0] === \"word\" && prev[1] === \"progid\") {\n          continue;\n        } else {\n          return i;\n        }\n      }\n      prev = token;\n    }\n    return false;\n  }\n  comment(token) {\n    let node2 = new Comment$2();\n    this.init(node2, token[2]);\n    node2.source.end = this.getPosition(token[3] || token[2]);\n    node2.source.end.offset++;\n    let text = token[1].slice(2, -2);\n    if (/^\\s*$/.test(text)) {\n      node2.text = \"\";\n      node2.raws.left = text;\n      node2.raws.right = \"\";\n    } else {\n      let match = text.match(/^(\\s*)([^]*\\S)(\\s*)$/);\n      node2.text = match[2];\n      node2.raws.left = match[1];\n      node2.raws.right = match[3];\n    }\n  }\n  createTokenizer() {\n    this.tokenizer = tokenizer2(this.input);\n  }\n  decl(tokens, customProperty) {\n    let node2 = new Declaration$2();\n    this.init(node2, tokens[0][2]);\n    let last = tokens[tokens.length - 1];\n    if (last[0] === \";\") {\n      this.semicolon = true;\n      tokens.pop();\n    }\n    node2.source.end = this.getPosition(\n      last[3] || last[2] || findLastWithPosition(tokens)\n    );\n    node2.source.end.offset++;\n    while (tokens[0][0] !== \"word\") {\n      if (tokens.length === 1) this.unknownWord(tokens);\n      node2.raws.before += tokens.shift()[1];\n    }\n    node2.source.start = this.getPosition(tokens[0][2]);\n    node2.prop = \"\";\n    while (tokens.length) {\n      let type = tokens[0][0];\n      if (type === \":\" || type === \"space\" || type === \"comment\") {\n        break;\n      }\n      node2.prop += tokens.shift()[1];\n    }\n    node2.raws.between = \"\";\n    let token;\n    while (tokens.length) {\n      token = tokens.shift();\n      if (token[0] === \":\") {\n        node2.raws.between += token[1];\n        break;\n      } else {\n        if (token[0] === \"word\" && /\\w/.test(token[1])) {\n          this.unknownWord([token]);\n        }\n        node2.raws.between += token[1];\n      }\n    }\n    if (node2.prop[0] === \"_\" || node2.prop[0] === \"*\") {\n      node2.raws.before += node2.prop[0];\n      node2.prop = node2.prop.slice(1);\n    }\n    let firstSpaces = [];\n    let next;\n    while (tokens.length) {\n      next = tokens[0][0];\n      if (next !== \"space\" && next !== \"comment\") break;\n      firstSpaces.push(tokens.shift());\n    }\n    this.precheckMissedSemicolon(tokens);\n    for (let i = tokens.length - 1; i >= 0; i--) {\n      token = tokens[i];\n      if (token[1].toLowerCase() === \"!important\") {\n        node2.important = true;\n        let string = this.stringFrom(tokens, i);\n        string = this.spacesFromEnd(tokens) + string;\n        if (string !== \" !important\") node2.raws.important = string;\n        break;\n      } else if (token[1].toLowerCase() === \"important\") {\n        let cache = tokens.slice(0);\n        let str = \"\";\n        for (let j = i; j > 0; j--) {\n          let type = cache[j][0];\n          if (str.trim().indexOf(\"!\") === 0 && type !== \"space\") {\n            break;\n          }\n          str = cache.pop()[1] + str;\n        }\n        if (str.trim().indexOf(\"!\") === 0) {\n          node2.important = true;\n          node2.raws.important = str;\n          tokens = cache;\n        }\n      }\n      if (token[0] !== \"space\" && token[0] !== \"comment\") {\n        break;\n      }\n    }\n    let hasWord = tokens.some((i) => i[0] !== \"space\" && i[0] !== \"comment\");\n    if (hasWord) {\n      node2.raws.between += firstSpaces.map((i) => i[1]).join(\"\");\n      firstSpaces = [];\n    }\n    this.raw(node2, \"value\", firstSpaces.concat(tokens), customProperty);\n    if (node2.value.includes(\":\") && !customProperty) {\n      this.checkMissedSemicolon(tokens);\n    }\n  }\n  doubleColon(token) {\n    throw this.input.error(\n      \"Double colon\",\n      { offset: token[2] },\n      { offset: token[2] + token[1].length }\n    );\n  }\n  emptyRule(token) {\n    let node2 = new Rule$2();\n    this.init(node2, token[2]);\n    node2.selector = \"\";\n    node2.raws.between = \"\";\n    this.current = node2;\n  }\n  end(token) {\n    if (this.current.nodes && this.current.nodes.length) {\n      this.current.raws.semicolon = this.semicolon;\n    }\n    this.semicolon = false;\n    this.current.raws.after = (this.current.raws.after || \"\") + this.spaces;\n    this.spaces = \"\";\n    if (this.current.parent) {\n      this.current.source.end = this.getPosition(token[2]);\n      this.current.source.end.offset++;\n      this.current = this.current.parent;\n    } else {\n      this.unexpectedClose(token);\n    }\n  }\n  endFile() {\n    if (this.current.parent) this.unclosedBlock();\n    if (this.current.nodes && this.current.nodes.length) {\n      this.current.raws.semicolon = this.semicolon;\n    }\n    this.current.raws.after = (this.current.raws.after || \"\") + this.spaces;\n    this.root.source.end = this.getPosition(this.tokenizer.position());\n  }\n  freeSemicolon(token) {\n    this.spaces += token[1];\n    if (this.current.nodes) {\n      let prev = this.current.nodes[this.current.nodes.length - 1];\n      if (prev && prev.type === \"rule\" && !prev.raws.ownSemicolon) {\n        prev.raws.ownSemicolon = this.spaces;\n        this.spaces = \"\";\n      }\n    }\n  }\n  // Helpers\n  getPosition(offset) {\n    let pos = this.input.fromOffset(offset);\n    return {\n      column: pos.col,\n      line: pos.line,\n      offset\n    };\n  }\n  init(node2, offset) {\n    this.current.push(node2);\n    node2.source = {\n      input: this.input,\n      start: this.getPosition(offset)\n    };\n    node2.raws.before = this.spaces;\n    this.spaces = \"\";\n    if (node2.type !== \"comment\") this.semicolon = false;\n  }\n  other(start) {\n    let end = false;\n    let type = null;\n    let colon = false;\n    let bracket = null;\n    let brackets = [];\n    let customProperty = start[1].startsWith(\"--\");\n    let tokens = [];\n    let token = start;\n    while (token) {\n      type = token[0];\n      tokens.push(token);\n      if (type === \"(\" || type === \"[\") {\n        if (!bracket) bracket = token;\n        brackets.push(type === \"(\" ? \")\" : \"]\");\n      } else if (customProperty && colon && type === \"{\") {\n        if (!bracket) bracket = token;\n        brackets.push(\"}\");\n      } else if (brackets.length === 0) {\n        if (type === \";\") {\n          if (colon) {\n            this.decl(tokens, customProperty);\n            return;\n          } else {\n            break;\n          }\n        } else if (type === \"{\") {\n          this.rule(tokens);\n          return;\n        } else if (type === \"}\") {\n          this.tokenizer.back(tokens.pop());\n          end = true;\n          break;\n        } else if (type === \":\") {\n          colon = true;\n        }\n      } else if (type === brackets[brackets.length - 1]) {\n        brackets.pop();\n        if (brackets.length === 0) bracket = null;\n      }\n      token = this.tokenizer.nextToken();\n    }\n    if (this.tokenizer.endOfFile()) end = true;\n    if (brackets.length > 0) this.unclosedBracket(bracket);\n    if (end && colon) {\n      if (!customProperty) {\n        while (tokens.length) {\n          token = tokens[tokens.length - 1][0];\n          if (token !== \"space\" && token !== \"comment\") break;\n          this.tokenizer.back(tokens.pop());\n        }\n      }\n      this.decl(tokens, customProperty);\n    } else {\n      this.unknownWord(tokens);\n    }\n  }\n  parse() {\n    let token;\n    while (!this.tokenizer.endOfFile()) {\n      token = this.tokenizer.nextToken();\n      switch (token[0]) {\n        case \"space\":\n          this.spaces += token[1];\n          break;\n        case \";\":\n          this.freeSemicolon(token);\n          break;\n        case \"}\":\n          this.end(token);\n          break;\n        case \"comment\":\n          this.comment(token);\n          break;\n        case \"at-word\":\n          this.atrule(token);\n          break;\n        case \"{\":\n          this.emptyRule(token);\n          break;\n        default:\n          this.other(token);\n          break;\n      }\n    }\n    this.endFile();\n  }\n  precheckMissedSemicolon() {\n  }\n  raw(node2, prop, tokens, customProperty) {\n    let token, type;\n    let length = tokens.length;\n    let value = \"\";\n    let clean = true;\n    let next, prev;\n    for (let i = 0; i < length; i += 1) {\n      token = tokens[i];\n      type = token[0];\n      if (type === \"space\" && i === length - 1 && !customProperty) {\n        clean = false;\n      } else if (type === \"comment\") {\n        prev = tokens[i - 1] ? tokens[i - 1][0] : \"empty\";\n        next = tokens[i + 1] ? tokens[i + 1][0] : \"empty\";\n        if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) {\n          if (value.slice(-1) === \",\") {\n            clean = false;\n          } else {\n            value += token[1];\n          }\n        } else {\n          clean = false;\n        }\n      } else {\n        value += token[1];\n      }\n    }\n    if (!clean) {\n      let raw = tokens.reduce((all, i) => all + i[1], \"\");\n      node2.raws[prop] = { raw, value };\n    }\n    node2[prop] = value;\n  }\n  rule(tokens) {\n    tokens.pop();\n    let node2 = new Rule$2();\n    this.init(node2, tokens[0][2]);\n    node2.raws.between = this.spacesAndCommentsFromEnd(tokens);\n    this.raw(node2, \"selector\", tokens);\n    this.current = node2;\n  }\n  spacesAndCommentsFromEnd(tokens) {\n    let lastTokenType;\n    let spaces = \"\";\n    while (tokens.length) {\n      lastTokenType = tokens[tokens.length - 1][0];\n      if (lastTokenType !== \"space\" && lastTokenType !== \"comment\") break;\n      spaces = tokens.pop()[1] + spaces;\n    }\n    return spaces;\n  }\n  // Errors\n  spacesAndCommentsFromStart(tokens) {\n    let next;\n    let spaces = \"\";\n    while (tokens.length) {\n      next = tokens[0][0];\n      if (next !== \"space\" && next !== \"comment\") break;\n      spaces += tokens.shift()[1];\n    }\n    return spaces;\n  }\n  spacesFromEnd(tokens) {\n    let lastTokenType;\n    let spaces = \"\";\n    while (tokens.length) {\n      lastTokenType = tokens[tokens.length - 1][0];\n      if (lastTokenType !== \"space\") break;\n      spaces = tokens.pop()[1] + spaces;\n    }\n    return spaces;\n  }\n  stringFrom(tokens, from) {\n    let result2 = \"\";\n    for (let i = from; i < tokens.length; i++) {\n      result2 += tokens[i][1];\n    }\n    tokens.splice(from, tokens.length - from);\n    return result2;\n  }\n  unclosedBlock() {\n    let pos = this.current.source.start;\n    throw this.input.error(\"Unclosed block\", pos.line, pos.column);\n  }\n  unclosedBracket(bracket) {\n    throw this.input.error(\n      \"Unclosed bracket\",\n      { offset: bracket[2] },\n      { offset: bracket[2] + 1 }\n    );\n  }\n  unexpectedClose(token) {\n    throw this.input.error(\n      \"Unexpected }\",\n      { offset: token[2] },\n      { offset: token[2] + 1 }\n    );\n  }\n  unknownWord(tokens) {\n    throw this.input.error(\n      \"Unknown word\",\n      { offset: tokens[0][2] },\n      { offset: tokens[0][2] + tokens[0][1].length }\n    );\n  }\n  unnamedAtrule(node2, token) {\n    throw this.input.error(\n      \"At-rule without name\",\n      { offset: token[2] },\n      { offset: token[2] + token[1].length }\n    );\n  }\n};\nvar parser = Parser$1;\nlet Container$2 = container;\nlet Parser2 = parser;\nlet Input$2 = input;\nfunction parse$3(css, opts) {\n  let input2 = new Input$2(css, opts);\n  let parser2 = new Parser2(input2);\n  try {\n    parser2.parse();\n  } catch (e) {\n    if (process.env.NODE_ENV !== \"production\") {\n      if (e.name === \"CssSyntaxError\" && opts && opts.from) {\n        if (/\\.scss$/i.test(opts.from)) {\n          e.message += \"\\nYou tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser\";\n        } else if (/\\.sass/i.test(opts.from)) {\n          e.message += \"\\nYou tried to parse Sass with the standard CSS parser; try again with the postcss-sass parser\";\n        } else if (/\\.less$/i.test(opts.from)) {\n          e.message += \"\\nYou tried to parse Less with the standard CSS parser; try again with the postcss-less parser\";\n        }\n      }\n    }\n    throw e;\n  }\n  return parser2.root;\n}\nvar parse_1 = parse$3;\nparse$3.default = parse$3;\nContainer$2.registerParse(parse$3);\nlet { isClean, my } = symbols;\nlet MapGenerator$1 = mapGenerator;\nlet stringify$2 = stringify_1;\nlet Container$1 = container;\nlet Document$2 = document$1;\nlet warnOnce$1 = warnOnce$2;\nlet Result$2 = result;\nlet parse$2 = parse_1;\nlet Root$3 = root;\nconst TYPE_TO_CLASS_NAME = {\n  atrule: \"AtRule\",\n  comment: \"Comment\",\n  decl: \"Declaration\",\n  document: \"Document\",\n  root: \"Root\",\n  rule: \"Rule\"\n};\nconst PLUGIN_PROPS = {\n  AtRule: true,\n  AtRuleExit: true,\n  Comment: true,\n  CommentExit: true,\n  Declaration: true,\n  DeclarationExit: true,\n  Document: true,\n  DocumentExit: true,\n  Once: true,\n  OnceExit: true,\n  postcssPlugin: true,\n  prepare: true,\n  Root: true,\n  RootExit: true,\n  Rule: true,\n  RuleExit: true\n};\nconst NOT_VISITORS = {\n  Once: true,\n  postcssPlugin: true,\n  prepare: true\n};\nconst CHILDREN = 0;\nfunction isPromise(obj) {\n  return typeof obj === \"object\" && typeof obj.then === \"function\";\n}\nfunction getEvents(node2) {\n  let key = false;\n  let type = TYPE_TO_CLASS_NAME[node2.type];\n  if (node2.type === \"decl\") {\n    key = node2.prop.toLowerCase();\n  } else if (node2.type === \"atrule\") {\n    key = node2.name.toLowerCase();\n  }\n  if (key && node2.append) {\n    return [\n      type,\n      type + \"-\" + key,\n      CHILDREN,\n      type + \"Exit\",\n      type + \"Exit-\" + key\n    ];\n  } else if (key) {\n    return [type, type + \"-\" + key, type + \"Exit\", type + \"Exit-\" + key];\n  } else if (node2.append) {\n    return [type, CHILDREN, type + \"Exit\"];\n  } else {\n    return [type, type + \"Exit\"];\n  }\n}\nfunction toStack(node2) {\n  let events;\n  if (node2.type === \"document\") {\n    events = [\"Document\", CHILDREN, \"DocumentExit\"];\n  } else if (node2.type === \"root\") {\n    events = [\"Root\", CHILDREN, \"RootExit\"];\n  } else {\n    events = getEvents(node2);\n  }\n  return {\n    eventIndex: 0,\n    events,\n    iterator: 0,\n    node: node2,\n    visitorIndex: 0,\n    visitors: []\n  };\n}\nfunction cleanMarks(node2) {\n  node2[isClean] = false;\n  if (node2.nodes) node2.nodes.forEach((i) => cleanMarks(i));\n  return node2;\n}\nlet postcss$2 = {};\nlet LazyResult$2 = class LazyResult {\n  constructor(processor2, css, opts) {\n    this.stringified = false;\n    this.processed = false;\n    let root2;\n    if (typeof css === \"object\" && css !== null && (css.type === \"root\" || css.type === \"document\")) {\n      root2 = cleanMarks(css);\n    } else if (css instanceof LazyResult || css instanceof Result$2) {\n      root2 = cleanMarks(css.root);\n      if (css.map) {\n        if (typeof opts.map === \"undefined\") opts.map = {};\n        if (!opts.map.inline) opts.map.inline = false;\n        opts.map.prev = css.map;\n      }\n    } else {\n      let parser2 = parse$2;\n      if (opts.syntax) parser2 = opts.syntax.parse;\n      if (opts.parser) parser2 = opts.parser;\n      if (parser2.parse) parser2 = parser2.parse;\n      try {\n        root2 = parser2(css, opts);\n      } catch (error) {\n        this.processed = true;\n        this.error = error;\n      }\n      if (root2 && !root2[my]) {\n        Container$1.rebuild(root2);\n      }\n    }\n    this.result = new Result$2(processor2, root2, opts);\n    this.helpers = { ...postcss$2, postcss: postcss$2, result: this.result };\n    this.plugins = this.processor.plugins.map((plugin2) => {\n      if (typeof plugin2 === \"object\" && plugin2.prepare) {\n        return { ...plugin2, ...plugin2.prepare(this.result) };\n      } else {\n        return plugin2;\n      }\n    });\n  }\n  async() {\n    if (this.error) return Promise.reject(this.error);\n    if (this.processed) return Promise.resolve(this.result);\n    if (!this.processing) {\n      this.processing = this.runAsync();\n    }\n    return this.processing;\n  }\n  catch(onRejected) {\n    return this.async().catch(onRejected);\n  }\n  finally(onFinally) {\n    return this.async().then(onFinally, onFinally);\n  }\n  getAsyncError() {\n    throw new Error(\"Use process(css).then(cb) to work with async plugins\");\n  }\n  handleError(error, node2) {\n    let plugin2 = this.result.lastPlugin;\n    try {\n      if (node2) node2.addToError(error);\n      this.error = error;\n      if (error.name === \"CssSyntaxError\" && !error.plugin) {\n        error.plugin = plugin2.postcssPlugin;\n        error.setMessage();\n      } else if (plugin2.postcssVersion) {\n        if (process.env.NODE_ENV !== \"production\") {\n          let pluginName = plugin2.postcssPlugin;\n          let pluginVer = plugin2.postcssVersion;\n          let runtimeVer = this.result.processor.version;\n          let a = pluginVer.split(\".\");\n          let b = runtimeVer.split(\".\");\n          if (a[0] !== b[0] || parseInt(a[1]) > parseInt(b[1])) {\n            console.error(\n              \"Unknown error from PostCSS plugin. Your current PostCSS version is \" + runtimeVer + \", but \" + pluginName + \" uses \" + pluginVer + \". Perhaps this is the source of the error below.\"\n            );\n          }\n        }\n      }\n    } catch (err) {\n      if (console && console.error) console.error(err);\n    }\n    return error;\n  }\n  prepareVisitors() {\n    this.listeners = {};\n    let add = (plugin2, type, cb) => {\n      if (!this.listeners[type]) this.listeners[type] = [];\n      this.listeners[type].push([plugin2, cb]);\n    };\n    for (let plugin2 of this.plugins) {\n      if (typeof plugin2 === \"object\") {\n        for (let event in plugin2) {\n          if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) {\n            throw new Error(\n              `Unknown event ${event} in ${plugin2.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`\n            );\n          }\n          if (!NOT_VISITORS[event]) {\n            if (typeof plugin2[event] === \"object\") {\n              for (let filter in plugin2[event]) {\n                if (filter === \"*\") {\n                  add(plugin2, event, plugin2[event][filter]);\n                } else {\n                  add(\n                    plugin2,\n                    event + \"-\" + filter.toLowerCase(),\n                    plugin2[event][filter]\n                  );\n                }\n              }\n            } else if (typeof plugin2[event] === \"function\") {\n              add(plugin2, event, plugin2[event]);\n            }\n          }\n        }\n      }\n    }\n    this.hasListener = Object.keys(this.listeners).length > 0;\n  }\n  async runAsync() {\n    this.plugin = 0;\n    for (let i = 0; i < this.plugins.length; i++) {\n      let plugin2 = this.plugins[i];\n      let promise = this.runOnRoot(plugin2);\n      if (isPromise(promise)) {\n        try {\n          await promise;\n        } catch (error) {\n          throw this.handleError(error);\n        }\n      }\n    }\n    this.prepareVisitors();\n    if (this.hasListener) {\n      let root2 = this.result.root;\n      while (!root2[isClean]) {\n        root2[isClean] = true;\n        let stack = [toStack(root2)];\n        while (stack.length > 0) {\n          let promise = this.visitTick(stack);\n          if (isPromise(promise)) {\n            try {\n              await promise;\n            } catch (e) {\n              let node2 = stack[stack.length - 1].node;\n              throw this.handleError(e, node2);\n            }\n          }\n        }\n      }\n      if (this.listeners.OnceExit) {\n        for (let [plugin2, visitor] of this.listeners.OnceExit) {\n          this.result.lastPlugin = plugin2;\n          try {\n            if (root2.type === \"document\") {\n              let roots = root2.nodes.map(\n                (subRoot) => visitor(subRoot, this.helpers)\n              );\n              await Promise.all(roots);\n            } else {\n              await visitor(root2, this.helpers);\n            }\n          } catch (e) {\n            throw this.handleError(e);\n          }\n        }\n      }\n    }\n    this.processed = true;\n    return this.stringify();\n  }\n  runOnRoot(plugin2) {\n    this.result.lastPlugin = plugin2;\n    try {\n      if (typeof plugin2 === \"object\" && plugin2.Once) {\n        if (this.result.root.type === \"document\") {\n          let roots = this.result.root.nodes.map(\n            (root2) => plugin2.Once(root2, this.helpers)\n          );\n          if (isPromise(roots[0])) {\n            return Promise.all(roots);\n          }\n          return roots;\n        }\n        return plugin2.Once(this.result.root, this.helpers);\n      } else if (typeof plugin2 === \"function\") {\n        return plugin2(this.result.root, this.result);\n      }\n    } catch (error) {\n      throw this.handleError(error);\n    }\n  }\n  stringify() {\n    if (this.error) throw this.error;\n    if (this.stringified) return this.result;\n    this.stringified = true;\n    this.sync();\n    let opts = this.result.opts;\n    let str = stringify$2;\n    if (opts.syntax) str = opts.syntax.stringify;\n    if (opts.stringifier) str = opts.stringifier;\n    if (str.stringify) str = str.stringify;\n    let map = new MapGenerator$1(str, this.result.root, this.result.opts);\n    let data = map.generate();\n    this.result.css = data[0];\n    this.result.map = data[1];\n    return this.result;\n  }\n  sync() {\n    if (this.error) throw this.error;\n    if (this.processed) return this.result;\n    this.processed = true;\n    if (this.processing) {\n      throw this.getAsyncError();\n    }\n    for (let plugin2 of this.plugins) {\n      let promise = this.runOnRoot(plugin2);\n      if (isPromise(promise)) {\n        throw this.getAsyncError();\n      }\n    }\n    this.prepareVisitors();\n    if (this.hasListener) {\n      let root2 = this.result.root;\n      while (!root2[isClean]) {\n        root2[isClean] = true;\n        this.walkSync(root2);\n      }\n      if (this.listeners.OnceExit) {\n        if (root2.type === \"document\") {\n          for (let subRoot of root2.nodes) {\n            this.visitSync(this.listeners.OnceExit, subRoot);\n          }\n        } else {\n          this.visitSync(this.listeners.OnceExit, root2);\n        }\n      }\n    }\n    return this.result;\n  }\n  then(onFulfilled, onRejected) {\n    if (process.env.NODE_ENV !== \"production\") {\n      if (!(\"from\" in this.opts)) {\n        warnOnce$1(\n          \"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning.\"\n        );\n      }\n    }\n    return this.async().then(onFulfilled, onRejected);\n  }\n  toString() {\n    return this.css;\n  }\n  visitSync(visitors, node2) {\n    for (let [plugin2, visitor] of visitors) {\n      this.result.lastPlugin = plugin2;\n      let promise;\n      try {\n        promise = visitor(node2, this.helpers);\n      } catch (e) {\n        throw this.handleError(e, node2.proxyOf);\n      }\n      if (node2.type !== \"root\" && node2.type !== \"document\" && !node2.parent) {\n        return true;\n      }\n      if (isPromise(promise)) {\n        throw this.getAsyncError();\n      }\n    }\n  }\n  visitTick(stack) {\n    let visit2 = stack[stack.length - 1];\n    let { node: node2, visitors } = visit2;\n    if (node2.type !== \"root\" && node2.type !== \"document\" && !node2.parent) {\n      stack.pop();\n      return;\n    }\n    if (visitors.length > 0 && visit2.visitorIndex < visitors.length) {\n      let [plugin2, visitor] = visitors[visit2.visitorIndex];\n      visit2.visitorIndex += 1;\n      if (visit2.visitorIndex === visitors.length) {\n        visit2.visitors = [];\n        visit2.visitorIndex = 0;\n      }\n      this.result.lastPlugin = plugin2;\n      try {\n        return visitor(node2.toProxy(), this.helpers);\n      } catch (e) {\n        throw this.handleError(e, node2);\n      }\n    }\n    if (visit2.iterator !== 0) {\n      let iterator = visit2.iterator;\n      let child;\n      while (child = node2.nodes[node2.indexes[iterator]]) {\n        node2.indexes[iterator] += 1;\n        if (!child[isClean]) {\n          child[isClean] = true;\n          stack.push(toStack(child));\n          return;\n        }\n      }\n      visit2.iterator = 0;\n      delete node2.indexes[iterator];\n    }\n    let events = visit2.events;\n    while (visit2.eventIndex < events.length) {\n      let event = events[visit2.eventIndex];\n      visit2.eventIndex += 1;\n      if (event === CHILDREN) {\n        if (node2.nodes && node2.nodes.length) {\n          node2[isClean] = true;\n          visit2.iterator = node2.getIterator();\n        }\n        return;\n      } else if (this.listeners[event]) {\n        visit2.visitors = this.listeners[event];\n        return;\n      }\n    }\n    stack.pop();\n  }\n  walkSync(node2) {\n    node2[isClean] = true;\n    let events = getEvents(node2);\n    for (let event of events) {\n      if (event === CHILDREN) {\n        if (node2.nodes) {\n          node2.each((child) => {\n            if (!child[isClean]) this.walkSync(child);\n          });\n        }\n      } else {\n        let visitors = this.listeners[event];\n        if (visitors) {\n          if (this.visitSync(visitors, node2.toProxy())) return;\n        }\n      }\n    }\n  }\n  warnings() {\n    return this.sync().warnings();\n  }\n  get content() {\n    return this.stringify().content;\n  }\n  get css() {\n    return this.stringify().css;\n  }\n  get map() {\n    return this.stringify().map;\n  }\n  get messages() {\n    return this.sync().messages;\n  }\n  get opts() {\n    return this.result.opts;\n  }\n  get processor() {\n    return this.result.processor;\n  }\n  get root() {\n    return this.sync().root;\n  }\n  get [Symbol.toStringTag]() {\n    return \"LazyResult\";\n  }\n};\nLazyResult$2.registerPostcss = (dependant) => {\n  postcss$2 = dependant;\n};\nvar lazyResult = LazyResult$2;\nLazyResult$2.default = LazyResult$2;\nRoot$3.registerLazyResult(LazyResult$2);\nDocument$2.registerLazyResult(LazyResult$2);\nlet MapGenerator2 = mapGenerator;\nlet stringify$1 = stringify_1;\nlet warnOnce2 = warnOnce$2;\nlet parse$1 = parse_1;\nconst Result$1 = result;\nlet NoWorkResult$1 = class NoWorkResult {\n  constructor(processor2, css, opts) {\n    css = css.toString();\n    this.stringified = false;\n    this._processor = processor2;\n    this._css = css;\n    this._opts = opts;\n    this._map = void 0;\n    let root2;\n    let str = stringify$1;\n    this.result = new Result$1(this._processor, root2, this._opts);\n    this.result.css = css;\n    let self = this;\n    Object.defineProperty(this.result, \"root\", {\n      get() {\n        return self.root;\n      }\n    });\n    let map = new MapGenerator2(str, root2, this._opts, css);\n    if (map.isMap()) {\n      let [generatedCSS, generatedMap] = map.generate();\n      if (generatedCSS) {\n        this.result.css = generatedCSS;\n      }\n      if (generatedMap) {\n        this.result.map = generatedMap;\n      }\n    } else {\n      map.clearAnnotation();\n      this.result.css = map.css;\n    }\n  }\n  async() {\n    if (this.error) return Promise.reject(this.error);\n    return Promise.resolve(this.result);\n  }\n  catch(onRejected) {\n    return this.async().catch(onRejected);\n  }\n  finally(onFinally) {\n    return this.async().then(onFinally, onFinally);\n  }\n  sync() {\n    if (this.error) throw this.error;\n    return this.result;\n  }\n  then(onFulfilled, onRejected) {\n    if (process.env.NODE_ENV !== \"production\") {\n      if (!(\"from\" in this._opts)) {\n        warnOnce2(\n          \"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning.\"\n        );\n      }\n    }\n    return this.async().then(onFulfilled, onRejected);\n  }\n  toString() {\n    return this._css;\n  }\n  warnings() {\n    return [];\n  }\n  get content() {\n    return this.result.css;\n  }\n  get css() {\n    return this.result.css;\n  }\n  get map() {\n    return this.result.map;\n  }\n  get messages() {\n    return [];\n  }\n  get opts() {\n    return this.result.opts;\n  }\n  get processor() {\n    return this.result.processor;\n  }\n  get root() {\n    if (this._root) {\n      return this._root;\n    }\n    let root2;\n    let parser2 = parse$1;\n    try {\n      root2 = parser2(this._css, this._opts);\n    } catch (error) {\n      this.error = error;\n    }\n    if (this.error) {\n      throw this.error;\n    } else {\n      this._root = root2;\n      return root2;\n    }\n  }\n  get [Symbol.toStringTag]() {\n    return \"NoWorkResult\";\n  }\n};\nvar noWorkResult = NoWorkResult$1;\nNoWorkResult$1.default = NoWorkResult$1;\nlet NoWorkResult2 = noWorkResult;\nlet LazyResult$1 = lazyResult;\nlet Document$1 = document$1;\nlet Root$2 = root;\nlet Processor$1 = class Processor {\n  constructor(plugins = []) {\n    this.version = \"8.4.38\";\n    this.plugins = this.normalize(plugins);\n  }\n  normalize(plugins) {\n    let normalized = [];\n    for (let i of plugins) {\n      if (i.postcss === true) {\n        i = i();\n      } else if (i.postcss) {\n        i = i.postcss;\n      }\n      if (typeof i === \"object\" && Array.isArray(i.plugins)) {\n        normalized = normalized.concat(i.plugins);\n      } else if (typeof i === \"object\" && i.postcssPlugin) {\n        normalized.push(i);\n      } else if (typeof i === \"function\") {\n        normalized.push(i);\n      } else if (typeof i === \"object\" && (i.parse || i.stringify)) {\n        if (process.env.NODE_ENV !== \"production\") {\n          throw new Error(\n            \"PostCSS syntaxes cannot be used as plugins. Instead, please use one of the syntax/parser/stringifier options as outlined in your PostCSS runner documentation.\"\n          );\n        }\n      } else {\n        throw new Error(i + \" is not a PostCSS plugin\");\n      }\n    }\n    return normalized;\n  }\n  process(css, opts = {}) {\n    if (!this.plugins.length && !opts.parser && !opts.stringifier && !opts.syntax) {\n      return new NoWorkResult2(this, css, opts);\n    } else {\n      return new LazyResult$1(this, css, opts);\n    }\n  }\n  use(plugin2) {\n    this.plugins = this.plugins.concat(this.normalize([plugin2]));\n    return this;\n  }\n};\nvar processor = Processor$1;\nProcessor$1.default = Processor$1;\nRoot$2.registerProcessor(Processor$1);\nDocument$1.registerProcessor(Processor$1);\nlet Declaration$1 = declaration;\nlet PreviousMap2 = previousMap;\nlet Comment$1 = comment;\nlet AtRule$1 = atRule;\nlet Input$1 = input;\nlet Root$1 = root;\nlet Rule$1 = rule;\nfunction fromJSON$1(json, inputs) {\n  if (Array.isArray(json)) return json.map((n) => fromJSON$1(n));\n  let { inputs: ownInputs, ...defaults } = json;\n  if (ownInputs) {\n    inputs = [];\n    for (let input2 of ownInputs) {\n      let inputHydrated = { ...input2, __proto__: Input$1.prototype };\n      if (inputHydrated.map) {\n        inputHydrated.map = {\n          ...inputHydrated.map,\n          __proto__: PreviousMap2.prototype\n        };\n      }\n      inputs.push(inputHydrated);\n    }\n  }\n  if (defaults.nodes) {\n    defaults.nodes = json.nodes.map((n) => fromJSON$1(n, inputs));\n  }\n  if (defaults.source) {\n    let { inputId, ...source } = defaults.source;\n    defaults.source = source;\n    if (inputId != null) {\n      defaults.source.input = inputs[inputId];\n    }\n  }\n  if (defaults.type === \"root\") {\n    return new Root$1(defaults);\n  } else if (defaults.type === \"decl\") {\n    return new Declaration$1(defaults);\n  } else if (defaults.type === \"rule\") {\n    return new Rule$1(defaults);\n  } else if (defaults.type === \"comment\") {\n    return new Comment$1(defaults);\n  } else if (defaults.type === \"atrule\") {\n    return new AtRule$1(defaults);\n  } else {\n    throw new Error(\"Unknown node type: \" + json.type);\n  }\n}\nvar fromJSON_1 = fromJSON$1;\nfromJSON$1.default = fromJSON$1;\nlet CssSyntaxError2 = cssSyntaxError;\nlet Declaration2 = declaration;\nlet LazyResult2 = lazyResult;\nlet Container2 = container;\nlet Processor2 = processor;\nlet stringify = stringify_1;\nlet fromJSON = fromJSON_1;\nlet Document2 = document$1;\nlet Warning2 = warning;\nlet Comment2 = comment;\nlet AtRule2 = atRule;\nlet Result2 = result;\nlet Input2 = input;\nlet parse = parse_1;\nlet list = list_1;\nlet Rule2 = rule;\nlet Root2 = root;\nlet Node2 = node;\nfunction postcss(...plugins) {\n  if (plugins.length === 1 && Array.isArray(plugins[0])) {\n    plugins = plugins[0];\n  }\n  return new Processor2(plugins);\n}\npostcss.plugin = function plugin(name, initializer) {\n  let warningPrinted = false;\n  function creator(...args) {\n    if (console && console.warn && !warningPrinted) {\n      warningPrinted = true;\n      console.warn(\n        name + \": postcss.plugin was deprecated. Migration guide:\\nhttps://evilmartians.com/chronicles/postcss-8-plugin-migration\"\n      );\n      if (process.env.LANG && process.env.LANG.startsWith(\"cn\")) {\n        console.warn(\n          name + \": 里面 postcss.plugin 被弃用. 迁移指南:\\nhttps://www.w3ctech.com/topic/2226\"\n        );\n      }\n    }\n    let transformer = initializer(...args);\n    transformer.postcssPlugin = name;\n    transformer.postcssVersion = new Processor2().version;\n    return transformer;\n  }\n  let cache;\n  Object.defineProperty(creator, \"postcss\", {\n    get() {\n      if (!cache) cache = creator();\n      return cache;\n    }\n  });\n  creator.process = function(css, processOpts, pluginOpts) {\n    return postcss([creator(pluginOpts)]).process(css, processOpts);\n  };\n  return creator;\n};\npostcss.stringify = stringify;\npostcss.parse = parse;\npostcss.fromJSON = fromJSON;\npostcss.list = list;\npostcss.comment = (defaults) => new Comment2(defaults);\npostcss.atRule = (defaults) => new AtRule2(defaults);\npostcss.decl = (defaults) => new Declaration2(defaults);\npostcss.rule = (defaults) => new Rule2(defaults);\npostcss.root = (defaults) => new Root2(defaults);\npostcss.document = (defaults) => new Document2(defaults);\npostcss.CssSyntaxError = CssSyntaxError2;\npostcss.Declaration = Declaration2;\npostcss.Container = Container2;\npostcss.Processor = Processor2;\npostcss.Document = Document2;\npostcss.Comment = Comment2;\npostcss.Warning = Warning2;\npostcss.AtRule = AtRule2;\npostcss.Result = Result2;\npostcss.Input = Input2;\npostcss.Rule = Rule2;\npostcss.Root = Root2;\npostcss.Node = Node2;\nLazyResult2.registerPostcss(postcss);\nvar postcss_1 = postcss;\npostcss.default = postcss;\nconst postcss$1 = /* @__PURE__ */ getDefaultExportFromCjs(postcss_1);\npostcss$1.stringify;\npostcss$1.fromJSON;\npostcss$1.plugin;\npostcss$1.parse;\npostcss$1.list;\npostcss$1.document;\npostcss$1.comment;\npostcss$1.atRule;\npostcss$1.rule;\npostcss$1.decl;\npostcss$1.root;\npostcss$1.CssSyntaxError;\npostcss$1.Declaration;\npostcss$1.Container;\npostcss$1.Processor;\npostcss$1.Document;\npostcss$1.Comment;\npostcss$1.Warning;\npostcss$1.AtRule;\npostcss$1.Result;\npostcss$1.Input;\npostcss$1.Rule;\npostcss$1.Root;\npostcss$1.Node;\nconst tagMap = {\n  script: \"noscript\",\n  // camel case svg element tag names\n  altglyph: \"altGlyph\",\n  altglyphdef: \"altGlyphDef\",\n  altglyphitem: \"altGlyphItem\",\n  animatecolor: \"animateColor\",\n  animatemotion: \"animateMotion\",\n  animatetransform: \"animateTransform\",\n  clippath: \"clipPath\",\n  feblend: \"feBlend\",\n  fecolormatrix: \"feColorMatrix\",\n  fecomponenttransfer: \"feComponentTransfer\",\n  fecomposite: \"feComposite\",\n  feconvolvematrix: \"feConvolveMatrix\",\n  fediffuselighting: \"feDiffuseLighting\",\n  fedisplacementmap: \"feDisplacementMap\",\n  fedistantlight: \"feDistantLight\",\n  fedropshadow: \"feDropShadow\",\n  feflood: \"feFlood\",\n  fefunca: \"feFuncA\",\n  fefuncb: \"feFuncB\",\n  fefuncg: \"feFuncG\",\n  fefuncr: \"feFuncR\",\n  fegaussianblur: \"feGaussianBlur\",\n  feimage: \"feImage\",\n  femerge: \"feMerge\",\n  femergenode: \"feMergeNode\",\n  femorphology: \"feMorphology\",\n  feoffset: \"feOffset\",\n  fepointlight: \"fePointLight\",\n  fespecularlighting: \"feSpecularLighting\",\n  fespotlight: \"feSpotLight\",\n  fetile: \"feTile\",\n  feturbulence: \"feTurbulence\",\n  foreignobject: \"foreignObject\",\n  glyphref: \"glyphRef\",\n  lineargradient: \"linearGradient\",\n  radialgradient: \"radialGradient\"\n};\nfunction getTagName(n) {\n  let tagName = tagMap[n.tagName] ? tagMap[n.tagName] : n.tagName;\n  if (tagName === \"link\" && n.attributes._cssText) {\n    tagName = \"style\";\n  }\n  return tagName;\n}\nfunction adaptCssForReplay(cssText, cache) {\n  const cachedStyle = cache == null ? void 0 : cache.stylesWithHoverClass.get(cssText);\n  if (cachedStyle) return cachedStyle;\n  let result2 = cssText;\n  try {\n    const ast = postcss$1([\n      mediaSelectorPlugin,\n      pseudoClassPlugin\n    ]).process(cssText);\n    result2 = ast.css;\n  } catch (error) {\n    console.warn(\"Failed to adapt css for replay\", error);\n  }\n  cache == null ? void 0 : cache.stylesWithHoverClass.set(cssText, result2);\n  return result2;\n}\nfunction createCache() {\n  const stylesWithHoverClass = /* @__PURE__ */ new Map();\n  return {\n    stylesWithHoverClass\n  };\n}\nfunction applyCssSplits(n, cssText, hackCss, cache) {\n  const childTextNodes = [];\n  for (const scn of n.childNodes) {\n    if (scn.type === NodeType.Text) {\n      childTextNodes.push(scn);\n    }\n  }\n  const cssTextSplits = cssText.split(\"/* rr_split */\");\n  while (cssTextSplits.length > 1 && cssTextSplits.length > childTextNodes.length) {\n    cssTextSplits.splice(-2, 2, cssTextSplits.slice(-2).join(\"\"));\n  }\n  let adaptedCss = \"\";\n  if (hackCss) {\n    adaptedCss = adaptCssForReplay(cssTextSplits.join(\"\"), cache);\n  }\n  let startIndex = 0;\n  for (let i = 0; i < childTextNodes.length; i++) {\n    if (i === cssTextSplits.length) {\n      break;\n    }\n    const childTextNode = childTextNodes[i];\n    if (!hackCss) {\n      childTextNode.textContent = cssTextSplits[i];\n    } else if (i < cssTextSplits.length - 1) {\n      let endIndex = startIndex;\n      let endSearch = cssTextSplits[i + 1].length;\n      endSearch = Math.min(endSearch, 30);\n      let found = false;\n      for (; endSearch > 2; endSearch--) {\n        const searchBit = cssTextSplits[i + 1].substring(0, endSearch);\n        const searchIndex = adaptedCss.substring(startIndex).indexOf(searchBit);\n        found = searchIndex !== -1;\n        if (found) {\n          endIndex += searchIndex;\n          break;\n        }\n      }\n      if (!found) {\n        endIndex += cssTextSplits[i].length;\n      }\n      childTextNode.textContent = adaptedCss.substring(startIndex, endIndex);\n      startIndex = endIndex;\n    } else {\n      childTextNode.textContent = adaptedCss.substring(startIndex);\n    }\n  }\n}\nfunction buildStyleNode(n, styleEl, cssText, options) {\n  const { doc, hackCss, cache } = options;\n  if (n.childNodes.length) {\n    applyCssSplits(n, cssText, hackCss, cache);\n  } else {\n    if (hackCss) {\n      cssText = adaptCssForReplay(cssText, cache);\n    }\n    styleEl.appendChild(doc.createTextNode(cssText));\n  }\n}\nfunction buildNode(n, options) {\n  var _a;\n  const { doc, hackCss, cache } = options;\n  switch (n.type) {\n    case NodeType.Document:\n      return doc.implementation.createDocument(null, \"\", null);\n    case NodeType.DocumentType:\n      return doc.implementation.createDocumentType(\n        n.name || \"html\",\n        n.publicId,\n        n.systemId\n      );\n    case NodeType.Element: {\n      const tagName = getTagName(n);\n      let node2;\n      if (n.isSVG) {\n        node2 = doc.createElementNS(\"http://www.w3.org/2000/svg\", tagName);\n      } else {\n        if (\n          // If the tag name is a custom element name\n          n.isCustom && // If the browser supports custom elements\n          ((_a = doc.defaultView) == null ? void 0 : _a.customElements) && // If the custom element hasn't been defined yet\n          !doc.defaultView.customElements.get(n.tagName)\n        )\n          doc.defaultView.customElements.define(\n            n.tagName,\n            class extends doc.defaultView.HTMLElement {\n            }\n          );\n        node2 = doc.createElement(tagName);\n      }\n      const specialAttributes = {};\n      for (const name in n.attributes) {\n        if (!Object.prototype.hasOwnProperty.call(n.attributes, name)) {\n          continue;\n        }\n        let value = n.attributes[name];\n        if (tagName === \"option\" && name === \"selected\" && value === false) {\n          continue;\n        }\n        if (value === null) {\n          continue;\n        }\n        if (value === true) value = \"\";\n        if (name.startsWith(\"rr_\")) {\n          specialAttributes[name] = value;\n          continue;\n        }\n        if (typeof value !== \"string\") ;\n        else if (tagName === \"style\" && name === \"_cssText\") {\n          buildStyleNode(n, node2, value, options);\n          continue;\n        } else if (tagName === \"textarea\" && name === \"value\") {\n          node2.appendChild(doc.createTextNode(value));\n          n.childNodes = [];\n          continue;\n        }\n        try {\n          if (n.isSVG && name === \"xlink:href\") {\n            node2.setAttributeNS(\n              \"http://www.w3.org/1999/xlink\",\n              name,\n              value.toString()\n            );\n          } else if (name === \"onload\" || name === \"onclick\" || name.substring(0, 7) === \"onmouse\") {\n            node2.setAttribute(\"_\" + name, value.toString());\n          } else if (tagName === \"meta\" && n.attributes[\"http-equiv\"] === \"Content-Security-Policy\" && name === \"content\") {\n            node2.setAttribute(\"csp-content\", value.toString());\n            continue;\n          } else if (tagName === \"link\" && (n.attributes.rel === \"preload\" && n.attributes.as === \"script\" || n.attributes.rel === \"modulepreload\")) {\n          } else if (tagName === \"link\" && n.attributes.rel === \"prefetch\" && typeof n.attributes.href === \"string\" && extractFileExtension(n.attributes.href) === \"js\") {\n          } else if (tagName === \"img\" && n.attributes.srcset && n.attributes.rr_dataURL) {\n            node2.setAttribute(\n              \"rrweb-original-srcset\",\n              n.attributes.srcset\n            );\n          } else {\n            node2.setAttribute(name, value.toString());\n          }\n        } catch (error) {\n        }\n      }\n      for (const name in specialAttributes) {\n        const value = specialAttributes[name];\n        if (tagName === \"canvas\" && name === \"rr_dataURL\") {\n          const image = doc.createElement(\"img\");\n          image.onload = () => {\n            const ctx = node2.getContext(\"2d\");\n            if (ctx) {\n              ctx.drawImage(image, 0, 0, image.width, image.height);\n            }\n          };\n          image.src = value.toString();\n          if (node2.RRNodeType)\n            node2.rr_dataURL = value.toString();\n        } else if (tagName === \"img\" && name === \"rr_dataURL\") {\n          const image = node2;\n          if (!image.currentSrc.startsWith(\"data:\")) {\n            image.setAttribute(\n              \"rrweb-original-src\",\n              n.attributes.src\n            );\n            image.src = value.toString();\n          }\n        }\n        if (name === \"rr_width\") {\n          node2.style.setProperty(\"width\", value.toString());\n        } else if (name === \"rr_height\") {\n          node2.style.setProperty(\"height\", value.toString());\n        } else if (name === \"rr_mediaCurrentTime\" && typeof value === \"number\") {\n          node2.currentTime = value;\n        } else if (name === \"rr_mediaState\") {\n          switch (value) {\n            case \"played\":\n              node2.play().catch((e) => console.warn(\"media playback error\", e));\n              break;\n            case \"paused\":\n              node2.pause();\n              break;\n          }\n        } else if (name === \"rr_mediaPlaybackRate\" && typeof value === \"number\") {\n          node2.playbackRate = value;\n        } else if (name === \"rr_mediaMuted\" && typeof value === \"boolean\") {\n          node2.muted = value;\n        } else if (name === \"rr_mediaLoop\" && typeof value === \"boolean\") {\n          node2.loop = value;\n        } else if (name === \"rr_mediaVolume\" && typeof value === \"number\") {\n          node2.volume = value;\n        } else if (name === \"rr_open_mode\") {\n          node2.setAttribute(\n            \"rr_open_mode\",\n            value\n          );\n        }\n      }\n      if (n.isShadowHost) {\n        if (!node2.shadowRoot) {\n          node2.attachShadow({ mode: \"open\" });\n        } else {\n          while (node2.shadowRoot.firstChild) {\n            node2.shadowRoot.removeChild(node2.shadowRoot.firstChild);\n          }\n        }\n      }\n      return node2;\n    }\n    case NodeType.Text:\n      if (n.isStyle && hackCss) {\n        return doc.createTextNode(adaptCssForReplay(n.textContent, cache));\n      }\n      return doc.createTextNode(n.textContent);\n    case NodeType.CDATA:\n      return doc.createCDATASection(n.textContent);\n    case NodeType.Comment:\n      return doc.createComment(n.textContent);\n    default:\n      return null;\n  }\n}\nfunction buildNodeWithSN(n, options) {\n  const {\n    doc,\n    mirror,\n    skipChild = false,\n    hackCss = true,\n    afterAppend,\n    cache\n  } = options;\n  if (mirror.has(n.id)) {\n    const nodeInMirror = mirror.getNode(n.id);\n    const meta = mirror.getMeta(nodeInMirror);\n    if (isNodeMetaEqual(meta, n)) return mirror.getNode(n.id);\n  }\n  let node2 = buildNode(n, { doc, hackCss, cache });\n  if (!node2) {\n    return null;\n  }\n  if (n.rootId && mirror.getNode(n.rootId) !== doc) {\n    mirror.replace(n.rootId, doc);\n  }\n  if (n.type === NodeType.Document) {\n    doc.close();\n    doc.open();\n    if (n.compatMode === \"BackCompat\" && n.childNodes && n.childNodes[0].type !== NodeType.DocumentType) {\n      if (n.childNodes[0].type === NodeType.Element && \"xmlns\" in n.childNodes[0].attributes && n.childNodes[0].attributes.xmlns === \"http://www.w3.org/1999/xhtml\") {\n        doc.write(\n          '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\">'\n        );\n      } else {\n        doc.write(\n          '<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\">'\n        );\n      }\n    }\n    node2 = doc;\n  }\n  mirror.add(node2, n);\n  if ((n.type === NodeType.Document || n.type === NodeType.Element) && !skipChild) {\n    for (const childN of n.childNodes) {\n      const childNode = buildNodeWithSN(childN, {\n        doc,\n        mirror,\n        skipChild: false,\n        hackCss,\n        afterAppend,\n        cache\n      });\n      if (!childNode) {\n        console.warn(\"Failed to rebuild\", childN);\n        continue;\n      }\n      if (childN.isShadow && isElement(node2) && node2.shadowRoot) {\n        node2.shadowRoot.appendChild(childNode);\n      } else if (n.type === NodeType.Document && childN.type == NodeType.Element) {\n        const htmlElement = childNode;\n        let body = null;\n        htmlElement.childNodes.forEach((child) => {\n          if (child.nodeName === \"BODY\") body = child;\n        });\n        if (body) {\n          htmlElement.removeChild(body);\n          node2.appendChild(childNode);\n          htmlElement.appendChild(body);\n        } else {\n          node2.appendChild(childNode);\n        }\n      } else {\n        node2.appendChild(childNode);\n      }\n      if (afterAppend) {\n        afterAppend(childNode, childN.id);\n      }\n    }\n  }\n  return node2;\n}\nfunction visit(mirror, onVisit) {\n  function walk(node2) {\n    onVisit(node2);\n  }\n  for (const id of mirror.getIds()) {\n    if (mirror.has(id)) {\n      walk(mirror.getNode(id));\n    }\n  }\n}\nfunction handleScroll(node2, mirror) {\n  const n = mirror.getMeta(node2);\n  if ((n == null ? void 0 : n.type) !== NodeType.Element) {\n    return;\n  }\n  const el = node2;\n  for (const name in n.attributes) {\n    if (!(Object.prototype.hasOwnProperty.call(n.attributes, name) && name.startsWith(\"rr_\"))) {\n      continue;\n    }\n    const value = n.attributes[name];\n    if (name === \"rr_scrollLeft\") {\n      el.scrollLeft = value;\n    }\n    if (name === \"rr_scrollTop\") {\n      el.scrollTop = value;\n    }\n  }\n}\nfunction rebuild(n, options) {\n  const {\n    doc,\n    onVisit,\n    hackCss = true,\n    afterAppend,\n    cache,\n    mirror = new Mirror()\n  } = options;\n  const node2 = buildNodeWithSN(n, {\n    doc,\n    mirror,\n    skipChild: false,\n    hackCss,\n    afterAppend,\n    cache\n  });\n  visit(mirror, (visitedNode) => {\n    if (onVisit) {\n      onVisit(visitedNode);\n    }\n    handleScroll(visitedNode, mirror);\n  });\n  return node2;\n}\nexport {\n  IGNORED_NODE,\n  Mirror,\n  absolutifyURLs,\n  adaptCssForReplay,\n  buildNodeWithSN,\n  classMatchesRegex,\n  cleanupSnapshot,\n  createCache,\n  createMirror,\n  escapeImportStatement,\n  extractFileExtension,\n  fixSafariColons,\n  genId,\n  getInputType,\n  ignoreAttribute,\n  is2DCanvasBlank,\n  isCSSImportRule,\n  isCSSStyleRule,\n  isElement,\n  isNativeShadowDom,\n  isNodeMetaEqual,\n  isShadowRoot,\n  markCssSplits,\n  maskInputValue,\n  needMaskingText,\n  normalizeCssString,\n  rebuild,\n  serializeNodeWithId,\n  slimDOMDefaults,\n  snapshot,\n  splitCssText,\n  stringifyRule,\n  stringifyStylesheet,\n  toLowerCase,\n  transformAttribute,\n  visitSnapshot\n};\n//# sourceMappingURL=rrweb-snapshot.js.map\n", "var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar __defProp2 = Object.defineProperty;\nvar __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nlet Mirror$1 = class Mirror {\n  constructor() {\n    __publicField2(this, \"idNodeMap\", /* @__PURE__ */ new Map());\n    __publicField2(this, \"nodeMetaMap\", /* @__PURE__ */ new WeakMap());\n  }\n  getId(n) {\n    var _a;\n    if (!n) return -1;\n    const id = (_a = this.getMeta(n)) == null ? void 0 : _a.id;\n    return id ?? -1;\n  }\n  getNode(id) {\n    return this.idNodeMap.get(id) || null;\n  }\n  getIds() {\n    return Array.from(this.idNodeMap.keys());\n  }\n  getMeta(n) {\n    return this.nodeMetaMap.get(n) || null;\n  }\n  // removes the node from idNodeMap\n  // doesn't remove the node from nodeMetaMap\n  removeNodeFromMap(n) {\n    const id = this.getId(n);\n    this.idNodeMap.delete(id);\n    if (n.childNodes) {\n      n.childNodes.forEach(\n        (childNode) => this.removeNodeFromMap(childNode)\n      );\n    }\n  }\n  has(id) {\n    return this.idNodeMap.has(id);\n  }\n  hasNode(node2) {\n    return this.nodeMetaMap.has(node2);\n  }\n  add(n, meta) {\n    const id = meta.id;\n    this.idNodeMap.set(id, n);\n    this.nodeMetaMap.set(n, meta);\n  }\n  replace(id, n) {\n    const oldNode = this.getNode(id);\n    if (oldNode) {\n      const meta = this.nodeMetaMap.get(oldNode);\n      if (meta) this.nodeMetaMap.set(n, meta);\n    }\n    this.idNodeMap.set(id, n);\n  }\n  reset() {\n    this.idNodeMap = /* @__PURE__ */ new Map();\n    this.nodeMetaMap = /* @__PURE__ */ new WeakMap();\n  }\n};\nfunction createMirror$1() {\n  return new Mirror$1();\n}\nfunction getDefaultExportFromCjs(x2) {\n  return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, \"default\") ? x2[\"default\"] : x2;\n}\nfunction getAugmentedNamespace(n) {\n  if (n.__esModule) return n;\n  var f = n.default;\n  if (typeof f == \"function\") {\n    var a = function a2() {\n      if (this instanceof a2) {\n        return Reflect.construct(f, arguments, this.constructor);\n      }\n      return f.apply(this, arguments);\n    };\n    a.prototype = f.prototype;\n  } else a = {};\n  Object.defineProperty(a, \"__esModule\", { value: true });\n  Object.keys(n).forEach(function(k) {\n    var d = Object.getOwnPropertyDescriptor(n, k);\n    Object.defineProperty(a, k, d.get ? d : {\n      enumerable: true,\n      get: function() {\n        return n[k];\n      }\n    });\n  });\n  return a;\n}\nvar picocolors_browser = { exports: {} };\nvar x = String;\nvar create = function() {\n  return { isColorSupported: false, reset: x, bold: x, dim: x, italic: x, underline: x, inverse: x, hidden: x, strikethrough: x, black: x, red: x, green: x, yellow: x, blue: x, magenta: x, cyan: x, white: x, gray: x, bgBlack: x, bgRed: x, bgGreen: x, bgYellow: x, bgBlue: x, bgMagenta: x, bgCyan: x, bgWhite: x };\n};\npicocolors_browser.exports = create();\npicocolors_browser.exports.createColors = create;\nvar picocolors_browserExports = picocolors_browser.exports;\nconst __viteBrowserExternal = {};\nconst __viteBrowserExternal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n  __proto__: null,\n  default: __viteBrowserExternal\n}, Symbol.toStringTag, { value: \"Module\" }));\nconst require$$2 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1);\nlet pico = picocolors_browserExports;\nlet terminalHighlight$1 = require$$2;\nlet CssSyntaxError$3 = class CssSyntaxError extends Error {\n  constructor(message, line, column, source, file, plugin2) {\n    super(message);\n    this.name = \"CssSyntaxError\";\n    this.reason = message;\n    if (file) {\n      this.file = file;\n    }\n    if (source) {\n      this.source = source;\n    }\n    if (plugin2) {\n      this.plugin = plugin2;\n    }\n    if (typeof line !== \"undefined\" && typeof column !== \"undefined\") {\n      if (typeof line === \"number\") {\n        this.line = line;\n        this.column = column;\n      } else {\n        this.line = line.line;\n        this.column = line.column;\n        this.endLine = column.line;\n        this.endColumn = column.column;\n      }\n    }\n    this.setMessage();\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, CssSyntaxError);\n    }\n  }\n  setMessage() {\n    this.message = this.plugin ? this.plugin + \": \" : \"\";\n    this.message += this.file ? this.file : \"<css input>\";\n    if (typeof this.line !== \"undefined\") {\n      this.message += \":\" + this.line + \":\" + this.column;\n    }\n    this.message += \": \" + this.reason;\n  }\n  showSourceCode(color) {\n    if (!this.source) return \"\";\n    let css = this.source;\n    if (color == null) color = pico.isColorSupported;\n    if (terminalHighlight$1) {\n      if (color) css = terminalHighlight$1(css);\n    }\n    let lines = css.split(/\\r?\\n/);\n    let start = Math.max(this.line - 3, 0);\n    let end = Math.min(this.line + 2, lines.length);\n    let maxWidth = String(end).length;\n    let mark, aside;\n    if (color) {\n      let { bold, gray, red } = pico.createColors(true);\n      mark = (text) => bold(red(text));\n      aside = (text) => gray(text);\n    } else {\n      mark = aside = (str) => str;\n    }\n    return lines.slice(start, end).map((line, index2) => {\n      let number = start + 1 + index2;\n      let gutter = \" \" + (\" \" + number).slice(-maxWidth) + \" | \";\n      if (number === this.line) {\n        let spacing = aside(gutter.replace(/\\d/g, \" \")) + line.slice(0, this.column - 1).replace(/[^\\t]/g, \" \");\n        return mark(\">\") + aside(gutter) + line + \"\\n \" + spacing + mark(\"^\");\n      }\n      return \" \" + aside(gutter) + line;\n    }).join(\"\\n\");\n  }\n  toString() {\n    let code = this.showSourceCode();\n    if (code) {\n      code = \"\\n\\n\" + code + \"\\n\";\n    }\n    return this.name + \": \" + this.message + code;\n  }\n};\nvar cssSyntaxError = CssSyntaxError$3;\nCssSyntaxError$3.default = CssSyntaxError$3;\nvar symbols = {};\nsymbols.isClean = Symbol(\"isClean\");\nsymbols.my = Symbol(\"my\");\nconst DEFAULT_RAW = {\n  after: \"\\n\",\n  beforeClose: \"\\n\",\n  beforeComment: \"\\n\",\n  beforeDecl: \"\\n\",\n  beforeOpen: \" \",\n  beforeRule: \"\\n\",\n  colon: \": \",\n  commentLeft: \" \",\n  commentRight: \" \",\n  emptyBody: \"\",\n  indent: \"    \",\n  semicolon: false\n};\nfunction capitalize(str) {\n  return str[0].toUpperCase() + str.slice(1);\n}\nlet Stringifier$2 = class Stringifier {\n  constructor(builder) {\n    this.builder = builder;\n  }\n  atrule(node2, semicolon) {\n    let name = \"@\" + node2.name;\n    let params = node2.params ? this.rawValue(node2, \"params\") : \"\";\n    if (typeof node2.raws.afterName !== \"undefined\") {\n      name += node2.raws.afterName;\n    } else if (params) {\n      name += \" \";\n    }\n    if (node2.nodes) {\n      this.block(node2, name + params);\n    } else {\n      let end = (node2.raws.between || \"\") + (semicolon ? \";\" : \"\");\n      this.builder(name + params + end, node2);\n    }\n  }\n  beforeAfter(node2, detect) {\n    let value;\n    if (node2.type === \"decl\") {\n      value = this.raw(node2, null, \"beforeDecl\");\n    } else if (node2.type === \"comment\") {\n      value = this.raw(node2, null, \"beforeComment\");\n    } else if (detect === \"before\") {\n      value = this.raw(node2, null, \"beforeRule\");\n    } else {\n      value = this.raw(node2, null, \"beforeClose\");\n    }\n    let buf = node2.parent;\n    let depth = 0;\n    while (buf && buf.type !== \"root\") {\n      depth += 1;\n      buf = buf.parent;\n    }\n    if (value.includes(\"\\n\")) {\n      let indent = this.raw(node2, null, \"indent\");\n      if (indent.length) {\n        for (let step = 0; step < depth; step++) value += indent;\n      }\n    }\n    return value;\n  }\n  block(node2, start) {\n    let between = this.raw(node2, \"between\", \"beforeOpen\");\n    this.builder(start + between + \"{\", node2, \"start\");\n    let after;\n    if (node2.nodes && node2.nodes.length) {\n      this.body(node2);\n      after = this.raw(node2, \"after\");\n    } else {\n      after = this.raw(node2, \"after\", \"emptyBody\");\n    }\n    if (after) this.builder(after);\n    this.builder(\"}\", node2, \"end\");\n  }\n  body(node2) {\n    let last = node2.nodes.length - 1;\n    while (last > 0) {\n      if (node2.nodes[last].type !== \"comment\") break;\n      last -= 1;\n    }\n    let semicolon = this.raw(node2, \"semicolon\");\n    for (let i = 0; i < node2.nodes.length; i++) {\n      let child = node2.nodes[i];\n      let before = this.raw(child, \"before\");\n      if (before) this.builder(before);\n      this.stringify(child, last !== i || semicolon);\n    }\n  }\n  comment(node2) {\n    let left = this.raw(node2, \"left\", \"commentLeft\");\n    let right = this.raw(node2, \"right\", \"commentRight\");\n    this.builder(\"/*\" + left + node2.text + right + \"*/\", node2);\n  }\n  decl(node2, semicolon) {\n    let between = this.raw(node2, \"between\", \"colon\");\n    let string = node2.prop + between + this.rawValue(node2, \"value\");\n    if (node2.important) {\n      string += node2.raws.important || \" !important\";\n    }\n    if (semicolon) string += \";\";\n    this.builder(string, node2);\n  }\n  document(node2) {\n    this.body(node2);\n  }\n  raw(node2, own, detect) {\n    let value;\n    if (!detect) detect = own;\n    if (own) {\n      value = node2.raws[own];\n      if (typeof value !== \"undefined\") return value;\n    }\n    let parent = node2.parent;\n    if (detect === \"before\") {\n      if (!parent || parent.type === \"root\" && parent.first === node2) {\n        return \"\";\n      }\n      if (parent && parent.type === \"document\") {\n        return \"\";\n      }\n    }\n    if (!parent) return DEFAULT_RAW[detect];\n    let root2 = node2.root();\n    if (!root2.rawCache) root2.rawCache = {};\n    if (typeof root2.rawCache[detect] !== \"undefined\") {\n      return root2.rawCache[detect];\n    }\n    if (detect === \"before\" || detect === \"after\") {\n      return this.beforeAfter(node2, detect);\n    } else {\n      let method = \"raw\" + capitalize(detect);\n      if (this[method]) {\n        value = this[method](root2, node2);\n      } else {\n        root2.walk((i) => {\n          value = i.raws[own];\n          if (typeof value !== \"undefined\") return false;\n        });\n      }\n    }\n    if (typeof value === \"undefined\") value = DEFAULT_RAW[detect];\n    root2.rawCache[detect] = value;\n    return value;\n  }\n  rawBeforeClose(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && i.nodes.length > 0) {\n        if (typeof i.raws.after !== \"undefined\") {\n          value = i.raws.after;\n          if (value.includes(\"\\n\")) {\n            value = value.replace(/[^\\n]+$/, \"\");\n          }\n          return false;\n        }\n      }\n    });\n    if (value) value = value.replace(/\\S/g, \"\");\n    return value;\n  }\n  rawBeforeComment(root2, node2) {\n    let value;\n    root2.walkComments((i) => {\n      if (typeof i.raws.before !== \"undefined\") {\n        value = i.raws.before;\n        if (value.includes(\"\\n\")) {\n          value = value.replace(/[^\\n]+$/, \"\");\n        }\n        return false;\n      }\n    });\n    if (typeof value === \"undefined\") {\n      value = this.raw(node2, null, \"beforeDecl\");\n    } else if (value) {\n      value = value.replace(/\\S/g, \"\");\n    }\n    return value;\n  }\n  rawBeforeDecl(root2, node2) {\n    let value;\n    root2.walkDecls((i) => {\n      if (typeof i.raws.before !== \"undefined\") {\n        value = i.raws.before;\n        if (value.includes(\"\\n\")) {\n          value = value.replace(/[^\\n]+$/, \"\");\n        }\n        return false;\n      }\n    });\n    if (typeof value === \"undefined\") {\n      value = this.raw(node2, null, \"beforeRule\");\n    } else if (value) {\n      value = value.replace(/\\S/g, \"\");\n    }\n    return value;\n  }\n  rawBeforeOpen(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.type !== \"decl\") {\n        value = i.raws.between;\n        if (typeof value !== \"undefined\") return false;\n      }\n    });\n    return value;\n  }\n  rawBeforeRule(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && (i.parent !== root2 || root2.first !== i)) {\n        if (typeof i.raws.before !== \"undefined\") {\n          value = i.raws.before;\n          if (value.includes(\"\\n\")) {\n            value = value.replace(/[^\\n]+$/, \"\");\n          }\n          return false;\n        }\n      }\n    });\n    if (value) value = value.replace(/\\S/g, \"\");\n    return value;\n  }\n  rawColon(root2) {\n    let value;\n    root2.walkDecls((i) => {\n      if (typeof i.raws.between !== \"undefined\") {\n        value = i.raws.between.replace(/[^\\s:]/g, \"\");\n        return false;\n      }\n    });\n    return value;\n  }\n  rawEmptyBody(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && i.nodes.length === 0) {\n        value = i.raws.after;\n        if (typeof value !== \"undefined\") return false;\n      }\n    });\n    return value;\n  }\n  rawIndent(root2) {\n    if (root2.raws.indent) return root2.raws.indent;\n    let value;\n    root2.walk((i) => {\n      let p = i.parent;\n      if (p && p !== root2 && p.parent && p.parent === root2) {\n        if (typeof i.raws.before !== \"undefined\") {\n          let parts = i.raws.before.split(\"\\n\");\n          value = parts[parts.length - 1];\n          value = value.replace(/\\S/g, \"\");\n          return false;\n        }\n      }\n    });\n    return value;\n  }\n  rawSemicolon(root2) {\n    let value;\n    root2.walk((i) => {\n      if (i.nodes && i.nodes.length && i.last.type === \"decl\") {\n        value = i.raws.semicolon;\n        if (typeof value !== \"undefined\") return false;\n      }\n    });\n    return value;\n  }\n  rawValue(node2, prop) {\n    let value = node2[prop];\n    let raw = node2.raws[prop];\n    if (raw && raw.value === value) {\n      return raw.raw;\n    }\n    return value;\n  }\n  root(node2) {\n    this.body(node2);\n    if (node2.raws.after) this.builder(node2.raws.after);\n  }\n  rule(node2) {\n    this.block(node2, this.rawValue(node2, \"selector\"));\n    if (node2.raws.ownSemicolon) {\n      this.builder(node2.raws.ownSemicolon, node2, \"end\");\n    }\n  }\n  stringify(node2, semicolon) {\n    if (!this[node2.type]) {\n      throw new Error(\n        \"Unknown AST node type \" + node2.type + \". Maybe you need to change PostCSS stringifier.\"\n      );\n    }\n    this[node2.type](node2, semicolon);\n  }\n};\nvar stringifier = Stringifier$2;\nStringifier$2.default = Stringifier$2;\nlet Stringifier$1 = stringifier;\nfunction stringify$4(node2, builder) {\n  let str = new Stringifier$1(builder);\n  str.stringify(node2);\n}\nvar stringify_1 = stringify$4;\nstringify$4.default = stringify$4;\nlet { isClean: isClean$2, my: my$2 } = symbols;\nlet CssSyntaxError$2 = cssSyntaxError;\nlet Stringifier2 = stringifier;\nlet stringify$3 = stringify_1;\nfunction cloneNode(obj, parent) {\n  let cloned = new obj.constructor();\n  for (let i in obj) {\n    if (!Object.prototype.hasOwnProperty.call(obj, i)) {\n      continue;\n    }\n    if (i === \"proxyCache\") continue;\n    let value = obj[i];\n    let type = typeof value;\n    if (i === \"parent\" && type === \"object\") {\n      if (parent) cloned[i] = parent;\n    } else if (i === \"source\") {\n      cloned[i] = value;\n    } else if (Array.isArray(value)) {\n      cloned[i] = value.map((j) => cloneNode(j, cloned));\n    } else {\n      if (type === \"object\" && value !== null) value = cloneNode(value);\n      cloned[i] = value;\n    }\n  }\n  return cloned;\n}\nlet Node$4 = class Node {\n  constructor(defaults = {}) {\n    this.raws = {};\n    this[isClean$2] = false;\n    this[my$2] = true;\n    for (let name in defaults) {\n      if (name === \"nodes\") {\n        this.nodes = [];\n        for (let node2 of defaults[name]) {\n          if (typeof node2.clone === \"function\") {\n            this.append(node2.clone());\n          } else {\n            this.append(node2);\n          }\n        }\n      } else {\n        this[name] = defaults[name];\n      }\n    }\n  }\n  addToError(error) {\n    error.postcssNode = this;\n    if (error.stack && this.source && /\\n\\s{4}at /.test(error.stack)) {\n      let s = this.source;\n      error.stack = error.stack.replace(\n        /\\n\\s{4}at /,\n        `$&${s.input.from}:${s.start.line}:${s.start.column}$&`\n      );\n    }\n    return error;\n  }\n  after(add) {\n    this.parent.insertAfter(this, add);\n    return this;\n  }\n  assign(overrides = {}) {\n    for (let name in overrides) {\n      this[name] = overrides[name];\n    }\n    return this;\n  }\n  before(add) {\n    this.parent.insertBefore(this, add);\n    return this;\n  }\n  cleanRaws(keepBetween) {\n    delete this.raws.before;\n    delete this.raws.after;\n    if (!keepBetween) delete this.raws.between;\n  }\n  clone(overrides = {}) {\n    let cloned = cloneNode(this);\n    for (let name in overrides) {\n      cloned[name] = overrides[name];\n    }\n    return cloned;\n  }\n  cloneAfter(overrides = {}) {\n    let cloned = this.clone(overrides);\n    this.parent.insertAfter(this, cloned);\n    return cloned;\n  }\n  cloneBefore(overrides = {}) {\n    let cloned = this.clone(overrides);\n    this.parent.insertBefore(this, cloned);\n    return cloned;\n  }\n  error(message, opts = {}) {\n    if (this.source) {\n      let { end, start } = this.rangeBy(opts);\n      return this.source.input.error(\n        message,\n        { column: start.column, line: start.line },\n        { column: end.column, line: end.line },\n        opts\n      );\n    }\n    return new CssSyntaxError$2(message);\n  }\n  getProxyProcessor() {\n    return {\n      get(node2, prop) {\n        if (prop === \"proxyOf\") {\n          return node2;\n        } else if (prop === \"root\") {\n          return () => node2.root().toProxy();\n        } else {\n          return node2[prop];\n        }\n      },\n      set(node2, prop, value) {\n        if (node2[prop] === value) return true;\n        node2[prop] = value;\n        if (prop === \"prop\" || prop === \"value\" || prop === \"name\" || prop === \"params\" || prop === \"important\" || /* c8 ignore next */\n        prop === \"text\") {\n          node2.markDirty();\n        }\n        return true;\n      }\n    };\n  }\n  markDirty() {\n    if (this[isClean$2]) {\n      this[isClean$2] = false;\n      let next = this;\n      while (next = next.parent) {\n        next[isClean$2] = false;\n      }\n    }\n  }\n  next() {\n    if (!this.parent) return void 0;\n    let index2 = this.parent.index(this);\n    return this.parent.nodes[index2 + 1];\n  }\n  positionBy(opts, stringRepresentation) {\n    let pos = this.source.start;\n    if (opts.index) {\n      pos = this.positionInside(opts.index, stringRepresentation);\n    } else if (opts.word) {\n      stringRepresentation = this.toString();\n      let index2 = stringRepresentation.indexOf(opts.word);\n      if (index2 !== -1) pos = this.positionInside(index2, stringRepresentation);\n    }\n    return pos;\n  }\n  positionInside(index2, stringRepresentation) {\n    let string = stringRepresentation || this.toString();\n    let column = this.source.start.column;\n    let line = this.source.start.line;\n    for (let i = 0; i < index2; i++) {\n      if (string[i] === \"\\n\") {\n        column = 1;\n        line += 1;\n      } else {\n        column += 1;\n      }\n    }\n    return { column, line };\n  }\n  prev() {\n    if (!this.parent) return void 0;\n    let index2 = this.parent.index(this);\n    return this.parent.nodes[index2 - 1];\n  }\n  rangeBy(opts) {\n    let start = {\n      column: this.source.start.column,\n      line: this.source.start.line\n    };\n    let end = this.source.end ? {\n      column: this.source.end.column + 1,\n      line: this.source.end.line\n    } : {\n      column: start.column + 1,\n      line: start.line\n    };\n    if (opts.word) {\n      let stringRepresentation = this.toString();\n      let index2 = stringRepresentation.indexOf(opts.word);\n      if (index2 !== -1) {\n        start = this.positionInside(index2, stringRepresentation);\n        end = this.positionInside(index2 + opts.word.length, stringRepresentation);\n      }\n    } else {\n      if (opts.start) {\n        start = {\n          column: opts.start.column,\n          line: opts.start.line\n        };\n      } else if (opts.index) {\n        start = this.positionInside(opts.index);\n      }\n      if (opts.end) {\n        end = {\n          column: opts.end.column,\n          line: opts.end.line\n        };\n      } else if (typeof opts.endIndex === \"number\") {\n        end = this.positionInside(opts.endIndex);\n      } else if (opts.index) {\n        end = this.positionInside(opts.index + 1);\n      }\n    }\n    if (end.line < start.line || end.line === start.line && end.column <= start.column) {\n      end = { column: start.column + 1, line: start.line };\n    }\n    return { end, start };\n  }\n  raw(prop, defaultType) {\n    let str = new Stringifier2();\n    return str.raw(this, prop, defaultType);\n  }\n  remove() {\n    if (this.parent) {\n      this.parent.removeChild(this);\n    }\n    this.parent = void 0;\n    return this;\n  }\n  replaceWith(...nodes) {\n    if (this.parent) {\n      let bookmark = this;\n      let foundSelf = false;\n      for (let node2 of nodes) {\n        if (node2 === this) {\n          foundSelf = true;\n        } else if (foundSelf) {\n          this.parent.insertAfter(bookmark, node2);\n          bookmark = node2;\n        } else {\n          this.parent.insertBefore(bookmark, node2);\n        }\n      }\n      if (!foundSelf) {\n        this.remove();\n      }\n    }\n    return this;\n  }\n  root() {\n    let result2 = this;\n    while (result2.parent && result2.parent.type !== \"document\") {\n      result2 = result2.parent;\n    }\n    return result2;\n  }\n  toJSON(_, inputs) {\n    let fixed = {};\n    let emitInputs = inputs == null;\n    inputs = inputs || /* @__PURE__ */ new Map();\n    let inputsNextIndex = 0;\n    for (let name in this) {\n      if (!Object.prototype.hasOwnProperty.call(this, name)) {\n        continue;\n      }\n      if (name === \"parent\" || name === \"proxyCache\") continue;\n      let value = this[name];\n      if (Array.isArray(value)) {\n        fixed[name] = value.map((i) => {\n          if (typeof i === \"object\" && i.toJSON) {\n            return i.toJSON(null, inputs);\n          } else {\n            return i;\n          }\n        });\n      } else if (typeof value === \"object\" && value.toJSON) {\n        fixed[name] = value.toJSON(null, inputs);\n      } else if (name === \"source\") {\n        let inputId = inputs.get(value.input);\n        if (inputId == null) {\n          inputId = inputsNextIndex;\n          inputs.set(value.input, inputsNextIndex);\n          inputsNextIndex++;\n        }\n        fixed[name] = {\n          end: value.end,\n          inputId,\n          start: value.start\n        };\n      } else {\n        fixed[name] = value;\n      }\n    }\n    if (emitInputs) {\n      fixed.inputs = [...inputs.keys()].map((input2) => input2.toJSON());\n    }\n    return fixed;\n  }\n  toProxy() {\n    if (!this.proxyCache) {\n      this.proxyCache = new Proxy(this, this.getProxyProcessor());\n    }\n    return this.proxyCache;\n  }\n  toString(stringifier2 = stringify$3) {\n    if (stringifier2.stringify) stringifier2 = stringifier2.stringify;\n    let result2 = \"\";\n    stringifier2(this, (i) => {\n      result2 += i;\n    });\n    return result2;\n  }\n  warn(result2, text, opts) {\n    let data = { node: this };\n    for (let i in opts) data[i] = opts[i];\n    return result2.warn(text, data);\n  }\n  get proxyOf() {\n    return this;\n  }\n};\nvar node = Node$4;\nNode$4.default = Node$4;\nlet Node$3 = node;\nlet Declaration$4 = class Declaration extends Node$3 {\n  constructor(defaults) {\n    if (defaults && typeof defaults.value !== \"undefined\" && typeof defaults.value !== \"string\") {\n      defaults = { ...defaults, value: String(defaults.value) };\n    }\n    super(defaults);\n    this.type = \"decl\";\n  }\n  get variable() {\n    return this.prop.startsWith(\"--\") || this.prop[0] === \"$\";\n  }\n};\nvar declaration = Declaration$4;\nDeclaration$4.default = Declaration$4;\nlet urlAlphabet = \"useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict\";\nlet customAlphabet = (alphabet, defaultSize = 21) => {\n  return (size = defaultSize) => {\n    let id = \"\";\n    let i = size;\n    while (i--) {\n      id += alphabet[Math.random() * alphabet.length | 0];\n    }\n    return id;\n  };\n};\nlet nanoid$1 = (size = 21) => {\n  let id = \"\";\n  let i = size;\n  while (i--) {\n    id += urlAlphabet[Math.random() * 64 | 0];\n  }\n  return id;\n};\nvar nonSecure = { nanoid: nanoid$1, customAlphabet };\nlet { SourceMapConsumer: SourceMapConsumer$2, SourceMapGenerator: SourceMapGenerator$2 } = require$$2;\nlet { existsSync, readFileSync } = require$$2;\nlet { dirname: dirname$1, join } = require$$2;\nfunction fromBase64(str) {\n  if (Buffer) {\n    return Buffer.from(str, \"base64\").toString();\n  } else {\n    return window.atob(str);\n  }\n}\nlet PreviousMap$2 = class PreviousMap {\n  constructor(css, opts) {\n    if (opts.map === false) return;\n    this.loadAnnotation(css);\n    this.inline = this.startWith(this.annotation, \"data:\");\n    let prev = opts.map ? opts.map.prev : void 0;\n    let text = this.loadMap(opts.from, prev);\n    if (!this.mapFile && opts.from) {\n      this.mapFile = opts.from;\n    }\n    if (this.mapFile) this.root = dirname$1(this.mapFile);\n    if (text) this.text = text;\n  }\n  consumer() {\n    if (!this.consumerCache) {\n      this.consumerCache = new SourceMapConsumer$2(this.text);\n    }\n    return this.consumerCache;\n  }\n  decodeInline(text) {\n    let baseCharsetUri = /^data:application\\/json;charset=utf-?8;base64,/;\n    let baseUri = /^data:application\\/json;base64,/;\n    let charsetUri = /^data:application\\/json;charset=utf-?8,/;\n    let uri = /^data:application\\/json,/;\n    if (charsetUri.test(text) || uri.test(text)) {\n      return decodeURIComponent(text.substr(RegExp.lastMatch.length));\n    }\n    if (baseCharsetUri.test(text) || baseUri.test(text)) {\n      return fromBase64(text.substr(RegExp.lastMatch.length));\n    }\n    let encoding = text.match(/data:application\\/json;([^,]+),/)[1];\n    throw new Error(\"Unsupported source map encoding \" + encoding);\n  }\n  getAnnotationURL(sourceMapString) {\n    return sourceMapString.replace(/^\\/\\*\\s*# sourceMappingURL=/, \"\").trim();\n  }\n  isMap(map) {\n    if (typeof map !== \"object\") return false;\n    return typeof map.mappings === \"string\" || typeof map._mappings === \"string\" || Array.isArray(map.sections);\n  }\n  loadAnnotation(css) {\n    let comments = css.match(/\\/\\*\\s*# sourceMappingURL=/gm);\n    if (!comments) return;\n    let start = css.lastIndexOf(comments.pop());\n    let end = css.indexOf(\"*/\", start);\n    if (start > -1 && end > -1) {\n      this.annotation = this.getAnnotationURL(css.substring(start, end));\n    }\n  }\n  loadFile(path) {\n    this.root = dirname$1(path);\n    if (existsSync(path)) {\n      this.mapFile = path;\n      return readFileSync(path, \"utf-8\").toString().trim();\n    }\n  }\n  loadMap(file, prev) {\n    if (prev === false) return false;\n    if (prev) {\n      if (typeof prev === \"string\") {\n        return prev;\n      } else if (typeof prev === \"function\") {\n        let prevPath = prev(file);\n        if (prevPath) {\n          let map = this.loadFile(prevPath);\n          if (!map) {\n            throw new Error(\n              \"Unable to load previous source map: \" + prevPath.toString()\n            );\n          }\n          return map;\n        }\n      } else if (prev instanceof SourceMapConsumer$2) {\n        return SourceMapGenerator$2.fromSourceMap(prev).toString();\n      } else if (prev instanceof SourceMapGenerator$2) {\n        return prev.toString();\n      } else if (this.isMap(prev)) {\n        return JSON.stringify(prev);\n      } else {\n        throw new Error(\n          \"Unsupported previous source map format: \" + prev.toString()\n        );\n      }\n    } else if (this.inline) {\n      return this.decodeInline(this.annotation);\n    } else if (this.annotation) {\n      let map = this.annotation;\n      if (file) map = join(dirname$1(file), map);\n      return this.loadFile(map);\n    }\n  }\n  startWith(string, start) {\n    if (!string) return false;\n    return string.substr(0, start.length) === start;\n  }\n  withContent() {\n    return !!(this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0);\n  }\n};\nvar previousMap = PreviousMap$2;\nPreviousMap$2.default = PreviousMap$2;\nlet { SourceMapConsumer: SourceMapConsumer$1, SourceMapGenerator: SourceMapGenerator$1 } = require$$2;\nlet { fileURLToPath, pathToFileURL: pathToFileURL$1 } = require$$2;\nlet { isAbsolute, resolve: resolve$1 } = require$$2;\nlet { nanoid } = nonSecure;\nlet terminalHighlight = require$$2;\nlet CssSyntaxError$1 = cssSyntaxError;\nlet PreviousMap$1 = previousMap;\nlet fromOffsetCache = Symbol(\"fromOffsetCache\");\nlet sourceMapAvailable$1 = Boolean(SourceMapConsumer$1 && SourceMapGenerator$1);\nlet pathAvailable$1 = Boolean(resolve$1 && isAbsolute);\nlet Input$4 = class Input {\n  constructor(css, opts = {}) {\n    if (css === null || typeof css === \"undefined\" || typeof css === \"object\" && !css.toString) {\n      throw new Error(`PostCSS received ${css} instead of CSS string`);\n    }\n    this.css = css.toString();\n    if (this.css[0] === \"\\uFEFF\" || this.css[0] === \"￾\") {\n      this.hasBOM = true;\n      this.css = this.css.slice(1);\n    } else {\n      this.hasBOM = false;\n    }\n    if (opts.from) {\n      if (!pathAvailable$1 || /^\\w+:\\/\\//.test(opts.from) || isAbsolute(opts.from)) {\n        this.file = opts.from;\n      } else {\n        this.file = resolve$1(opts.from);\n      }\n    }\n    if (pathAvailable$1 && sourceMapAvailable$1) {\n      let map = new PreviousMap$1(this.css, opts);\n      if (map.text) {\n        this.map = map;\n        let file = map.consumer().file;\n        if (!this.file && file) this.file = this.mapResolve(file);\n      }\n    }\n    if (!this.file) {\n      this.id = \"<input css \" + nanoid(6) + \">\";\n    }\n    if (this.map) this.map.file = this.from;\n  }\n  error(message, line, column, opts = {}) {\n    let result2, endLine, endColumn;\n    if (line && typeof line === \"object\") {\n      let start = line;\n      let end = column;\n      if (typeof start.offset === \"number\") {\n        let pos = this.fromOffset(start.offset);\n        line = pos.line;\n        column = pos.col;\n      } else {\n        line = start.line;\n        column = start.column;\n      }\n      if (typeof end.offset === \"number\") {\n        let pos = this.fromOffset(end.offset);\n        endLine = pos.line;\n        endColumn = pos.col;\n      } else {\n        endLine = end.line;\n        endColumn = end.column;\n      }\n    } else if (!column) {\n      let pos = this.fromOffset(line);\n      line = pos.line;\n      column = pos.col;\n    }\n    let origin = this.origin(line, column, endLine, endColumn);\n    if (origin) {\n      result2 = new CssSyntaxError$1(\n        message,\n        origin.endLine === void 0 ? origin.line : { column: origin.column, line: origin.line },\n        origin.endLine === void 0 ? origin.column : { column: origin.endColumn, line: origin.endLine },\n        origin.source,\n        origin.file,\n        opts.plugin\n      );\n    } else {\n      result2 = new CssSyntaxError$1(\n        message,\n        endLine === void 0 ? line : { column, line },\n        endLine === void 0 ? column : { column: endColumn, line: endLine },\n        this.css,\n        this.file,\n        opts.plugin\n      );\n    }\n    result2.input = { column, endColumn, endLine, line, source: this.css };\n    if (this.file) {\n      if (pathToFileURL$1) {\n        result2.input.url = pathToFileURL$1(this.file).toString();\n      }\n      result2.input.file = this.file;\n    }\n    return result2;\n  }\n  fromOffset(offset) {\n    let lastLine, lineToIndex;\n    if (!this[fromOffsetCache]) {\n      let lines = this.css.split(\"\\n\");\n      lineToIndex = new Array(lines.length);\n      let prevIndex = 0;\n      for (let i = 0, l = lines.length; i < l; i++) {\n        lineToIndex[i] = prevIndex;\n        prevIndex += lines[i].length + 1;\n      }\n      this[fromOffsetCache] = lineToIndex;\n    } else {\n      lineToIndex = this[fromOffsetCache];\n    }\n    lastLine = lineToIndex[lineToIndex.length - 1];\n    let min = 0;\n    if (offset >= lastLine) {\n      min = lineToIndex.length - 1;\n    } else {\n      let max = lineToIndex.length - 2;\n      let mid;\n      while (min < max) {\n        mid = min + (max - min >> 1);\n        if (offset < lineToIndex[mid]) {\n          max = mid - 1;\n        } else if (offset >= lineToIndex[mid + 1]) {\n          min = mid + 1;\n        } else {\n          min = mid;\n          break;\n        }\n      }\n    }\n    return {\n      col: offset - lineToIndex[min] + 1,\n      line: min + 1\n    };\n  }\n  mapResolve(file) {\n    if (/^\\w+:\\/\\//.test(file)) {\n      return file;\n    }\n    return resolve$1(this.map.consumer().sourceRoot || this.map.root || \".\", file);\n  }\n  origin(line, column, endLine, endColumn) {\n    if (!this.map) return false;\n    let consumer = this.map.consumer();\n    let from = consumer.originalPositionFor({ column, line });\n    if (!from.source) return false;\n    let to;\n    if (typeof endLine === \"number\") {\n      to = consumer.originalPositionFor({ column: endColumn, line: endLine });\n    }\n    let fromUrl;\n    if (isAbsolute(from.source)) {\n      fromUrl = pathToFileURL$1(from.source);\n    } else {\n      fromUrl = new URL(\n        from.source,\n        this.map.consumer().sourceRoot || pathToFileURL$1(this.map.mapFile)\n      );\n    }\n    let result2 = {\n      column: from.column,\n      endColumn: to && to.column,\n      endLine: to && to.line,\n      line: from.line,\n      url: fromUrl.toString()\n    };\n    if (fromUrl.protocol === \"file:\") {\n      if (fileURLToPath) {\n        result2.file = fileURLToPath(fromUrl);\n      } else {\n        throw new Error(`file: protocol is not available in this PostCSS build`);\n      }\n    }\n    let source = consumer.sourceContentFor(from.source);\n    if (source) result2.source = source;\n    return result2;\n  }\n  toJSON() {\n    let json = {};\n    for (let name of [\"hasBOM\", \"css\", \"file\", \"id\"]) {\n      if (this[name] != null) {\n        json[name] = this[name];\n      }\n    }\n    if (this.map) {\n      json.map = { ...this.map };\n      if (json.map.consumerCache) {\n        json.map.consumerCache = void 0;\n      }\n    }\n    return json;\n  }\n  get from() {\n    return this.file || this.id;\n  }\n};\nvar input = Input$4;\nInput$4.default = Input$4;\nif (terminalHighlight && terminalHighlight.registerInput) {\n  terminalHighlight.registerInput(Input$4);\n}\nlet { SourceMapConsumer, SourceMapGenerator } = require$$2;\nlet { dirname, relative, resolve, sep } = require$$2;\nlet { pathToFileURL } = require$$2;\nlet Input$3 = input;\nlet sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator);\nlet pathAvailable = Boolean(dirname && resolve && relative && sep);\nlet MapGenerator$2 = class MapGenerator {\n  constructor(stringify2, root2, opts, cssString) {\n    this.stringify = stringify2;\n    this.mapOpts = opts.map || {};\n    this.root = root2;\n    this.opts = opts;\n    this.css = cssString;\n    this.originalCSS = cssString;\n    this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute;\n    this.memoizedFileURLs = /* @__PURE__ */ new Map();\n    this.memoizedPaths = /* @__PURE__ */ new Map();\n    this.memoizedURLs = /* @__PURE__ */ new Map();\n  }\n  addAnnotation() {\n    let content;\n    if (this.isInline()) {\n      content = \"data:application/json;base64,\" + this.toBase64(this.map.toString());\n    } else if (typeof this.mapOpts.annotation === \"string\") {\n      content = this.mapOpts.annotation;\n    } else if (typeof this.mapOpts.annotation === \"function\") {\n      content = this.mapOpts.annotation(this.opts.to, this.root);\n    } else {\n      content = this.outputFile() + \".map\";\n    }\n    let eol = \"\\n\";\n    if (this.css.includes(\"\\r\\n\")) eol = \"\\r\\n\";\n    this.css += eol + \"/*# sourceMappingURL=\" + content + \" */\";\n  }\n  applyPrevMaps() {\n    for (let prev of this.previous()) {\n      let from = this.toUrl(this.path(prev.file));\n      let root2 = prev.root || dirname(prev.file);\n      let map;\n      if (this.mapOpts.sourcesContent === false) {\n        map = new SourceMapConsumer(prev.text);\n        if (map.sourcesContent) {\n          map.sourcesContent = null;\n        }\n      } else {\n        map = prev.consumer();\n      }\n      this.map.applySourceMap(map, from, this.toUrl(this.path(root2)));\n    }\n  }\n  clearAnnotation() {\n    if (this.mapOpts.annotation === false) return;\n    if (this.root) {\n      let node2;\n      for (let i = this.root.nodes.length - 1; i >= 0; i--) {\n        node2 = this.root.nodes[i];\n        if (node2.type !== \"comment\") continue;\n        if (node2.text.indexOf(\"# sourceMappingURL=\") === 0) {\n          this.root.removeChild(i);\n        }\n      }\n    } else if (this.css) {\n      this.css = this.css.replace(/\\n*?\\/\\*#[\\S\\s]*?\\*\\/$/gm, \"\");\n    }\n  }\n  generate() {\n    this.clearAnnotation();\n    if (pathAvailable && sourceMapAvailable && this.isMap()) {\n      return this.generateMap();\n    } else {\n      let result2 = \"\";\n      this.stringify(this.root, (i) => {\n        result2 += i;\n      });\n      return [result2];\n    }\n  }\n  generateMap() {\n    if (this.root) {\n      this.generateString();\n    } else if (this.previous().length === 1) {\n      let prev = this.previous()[0].consumer();\n      prev.file = this.outputFile();\n      this.map = SourceMapGenerator.fromSourceMap(prev, {\n        ignoreInvalidMapping: true\n      });\n    } else {\n      this.map = new SourceMapGenerator({\n        file: this.outputFile(),\n        ignoreInvalidMapping: true\n      });\n      this.map.addMapping({\n        generated: { column: 0, line: 1 },\n        original: { column: 0, line: 1 },\n        source: this.opts.from ? this.toUrl(this.path(this.opts.from)) : \"<no source>\"\n      });\n    }\n    if (this.isSourcesContent()) this.setSourcesContent();\n    if (this.root && this.previous().length > 0) this.applyPrevMaps();\n    if (this.isAnnotation()) this.addAnnotation();\n    if (this.isInline()) {\n      return [this.css];\n    } else {\n      return [this.css, this.map];\n    }\n  }\n  generateString() {\n    this.css = \"\";\n    this.map = new SourceMapGenerator({\n      file: this.outputFile(),\n      ignoreInvalidMapping: true\n    });\n    let line = 1;\n    let column = 1;\n    let noSource = \"<no source>\";\n    let mapping = {\n      generated: { column: 0, line: 0 },\n      original: { column: 0, line: 0 },\n      source: \"\"\n    };\n    let lines, last;\n    this.stringify(this.root, (str, node2, type) => {\n      this.css += str;\n      if (node2 && type !== \"end\") {\n        mapping.generated.line = line;\n        mapping.generated.column = column - 1;\n        if (node2.source && node2.source.start) {\n          mapping.source = this.sourcePath(node2);\n          mapping.original.line = node2.source.start.line;\n          mapping.original.column = node2.source.start.column - 1;\n          this.map.addMapping(mapping);\n        } else {\n          mapping.source = noSource;\n          mapping.original.line = 1;\n          mapping.original.column = 0;\n          this.map.addMapping(mapping);\n        }\n      }\n      lines = str.match(/\\n/g);\n      if (lines) {\n        line += lines.length;\n        last = str.lastIndexOf(\"\\n\");\n        column = str.length - last;\n      } else {\n        column += str.length;\n      }\n      if (node2 && type !== \"start\") {\n        let p = node2.parent || { raws: {} };\n        let childless = node2.type === \"decl\" || node2.type === \"atrule\" && !node2.nodes;\n        if (!childless || node2 !== p.last || p.raws.semicolon) {\n          if (node2.source && node2.source.end) {\n            mapping.source = this.sourcePath(node2);\n            mapping.original.line = node2.source.end.line;\n            mapping.original.column = node2.source.end.column - 1;\n            mapping.generated.line = line;\n            mapping.generated.column = column - 2;\n            this.map.addMapping(mapping);\n          } else {\n            mapping.source = noSource;\n            mapping.original.line = 1;\n            mapping.original.column = 0;\n            mapping.generated.line = line;\n            mapping.generated.column = column - 1;\n            this.map.addMapping(mapping);\n          }\n        }\n      }\n    });\n  }\n  isAnnotation() {\n    if (this.isInline()) {\n      return true;\n    }\n    if (typeof this.mapOpts.annotation !== \"undefined\") {\n      return this.mapOpts.annotation;\n    }\n    if (this.previous().length) {\n      return this.previous().some((i) => i.annotation);\n    }\n    return true;\n  }\n  isInline() {\n    if (typeof this.mapOpts.inline !== \"undefined\") {\n      return this.mapOpts.inline;\n    }\n    let annotation = this.mapOpts.annotation;\n    if (typeof annotation !== \"undefined\" && annotation !== true) {\n      return false;\n    }\n    if (this.previous().length) {\n      return this.previous().some((i) => i.inline);\n    }\n    return true;\n  }\n  isMap() {\n    if (typeof this.opts.map !== \"undefined\") {\n      return !!this.opts.map;\n    }\n    return this.previous().length > 0;\n  }\n  isSourcesContent() {\n    if (typeof this.mapOpts.sourcesContent !== \"undefined\") {\n      return this.mapOpts.sourcesContent;\n    }\n    if (this.previous().length) {\n      return this.previous().some((i) => i.withContent());\n    }\n    return true;\n  }\n  outputFile() {\n    if (this.opts.to) {\n      return this.path(this.opts.to);\n    } else if (this.opts.from) {\n      return this.path(this.opts.from);\n    } else {\n      return \"to.css\";\n    }\n  }\n  path(file) {\n    if (this.mapOpts.absolute) return file;\n    if (file.charCodeAt(0) === 60) return file;\n    if (/^\\w+:\\/\\//.test(file)) return file;\n    let cached = this.memoizedPaths.get(file);\n    if (cached) return cached;\n    let from = this.opts.to ? dirname(this.opts.to) : \".\";\n    if (typeof this.mapOpts.annotation === \"string\") {\n      from = dirname(resolve(from, this.mapOpts.annotation));\n    }\n    let path = relative(from, file);\n    this.memoizedPaths.set(file, path);\n    return path;\n  }\n  previous() {\n    if (!this.previousMaps) {\n      this.previousMaps = [];\n      if (this.root) {\n        this.root.walk((node2) => {\n          if (node2.source && node2.source.input.map) {\n            let map = node2.source.input.map;\n            if (!this.previousMaps.includes(map)) {\n              this.previousMaps.push(map);\n            }\n          }\n        });\n      } else {\n        let input2 = new Input$3(this.originalCSS, this.opts);\n        if (input2.map) this.previousMaps.push(input2.map);\n      }\n    }\n    return this.previousMaps;\n  }\n  setSourcesContent() {\n    let already = {};\n    if (this.root) {\n      this.root.walk((node2) => {\n        if (node2.source) {\n          let from = node2.source.input.from;\n          if (from && !already[from]) {\n            already[from] = true;\n            let fromUrl = this.usesFileUrls ? this.toFileUrl(from) : this.toUrl(this.path(from));\n            this.map.setSourceContent(fromUrl, node2.source.input.css);\n          }\n        }\n      });\n    } else if (this.css) {\n      let from = this.opts.from ? this.toUrl(this.path(this.opts.from)) : \"<no source>\";\n      this.map.setSourceContent(from, this.css);\n    }\n  }\n  sourcePath(node2) {\n    if (this.mapOpts.from) {\n      return this.toUrl(this.mapOpts.from);\n    } else if (this.usesFileUrls) {\n      return this.toFileUrl(node2.source.input.from);\n    } else {\n      return this.toUrl(this.path(node2.source.input.from));\n    }\n  }\n  toBase64(str) {\n    if (Buffer) {\n      return Buffer.from(str).toString(\"base64\");\n    } else {\n      return window.btoa(unescape(encodeURIComponent(str)));\n    }\n  }\n  toFileUrl(path) {\n    let cached = this.memoizedFileURLs.get(path);\n    if (cached) return cached;\n    if (pathToFileURL) {\n      let fileURL = pathToFileURL(path).toString();\n      this.memoizedFileURLs.set(path, fileURL);\n      return fileURL;\n    } else {\n      throw new Error(\n        \"`map.absolute` option is not available in this PostCSS build\"\n      );\n    }\n  }\n  toUrl(path) {\n    let cached = this.memoizedURLs.get(path);\n    if (cached) return cached;\n    if (sep === \"\\\\\") {\n      path = path.replace(/\\\\/g, \"/\");\n    }\n    let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent);\n    this.memoizedURLs.set(path, url);\n    return url;\n  }\n};\nvar mapGenerator = MapGenerator$2;\nlet Node$2 = node;\nlet Comment$4 = class Comment extends Node$2 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"comment\";\n  }\n};\nvar comment = Comment$4;\nComment$4.default = Comment$4;\nlet { isClean: isClean$1, my: my$1 } = symbols;\nlet Declaration$3 = declaration;\nlet Comment$3 = comment;\nlet Node$1 = node;\nlet parse$4, Rule$4, AtRule$4, Root$6;\nfunction cleanSource(nodes) {\n  return nodes.map((i) => {\n    if (i.nodes) i.nodes = cleanSource(i.nodes);\n    delete i.source;\n    return i;\n  });\n}\nfunction markDirtyUp(node2) {\n  node2[isClean$1] = false;\n  if (node2.proxyOf.nodes) {\n    for (let i of node2.proxyOf.nodes) {\n      markDirtyUp(i);\n    }\n  }\n}\nlet Container$7 = class Container extends Node$1 {\n  append(...children) {\n    for (let child of children) {\n      let nodes = this.normalize(child, this.last);\n      for (let node2 of nodes) this.proxyOf.nodes.push(node2);\n    }\n    this.markDirty();\n    return this;\n  }\n  cleanRaws(keepBetween) {\n    super.cleanRaws(keepBetween);\n    if (this.nodes) {\n      for (let node2 of this.nodes) node2.cleanRaws(keepBetween);\n    }\n  }\n  each(callback) {\n    if (!this.proxyOf.nodes) return void 0;\n    let iterator = this.getIterator();\n    let index2, result2;\n    while (this.indexes[iterator] < this.proxyOf.nodes.length) {\n      index2 = this.indexes[iterator];\n      result2 = callback(this.proxyOf.nodes[index2], index2);\n      if (result2 === false) break;\n      this.indexes[iterator] += 1;\n    }\n    delete this.indexes[iterator];\n    return result2;\n  }\n  every(condition) {\n    return this.nodes.every(condition);\n  }\n  getIterator() {\n    if (!this.lastEach) this.lastEach = 0;\n    if (!this.indexes) this.indexes = {};\n    this.lastEach += 1;\n    let iterator = this.lastEach;\n    this.indexes[iterator] = 0;\n    return iterator;\n  }\n  getProxyProcessor() {\n    return {\n      get(node2, prop) {\n        if (prop === \"proxyOf\") {\n          return node2;\n        } else if (!node2[prop]) {\n          return node2[prop];\n        } else if (prop === \"each\" || typeof prop === \"string\" && prop.startsWith(\"walk\")) {\n          return (...args) => {\n            return node2[prop](\n              ...args.map((i) => {\n                if (typeof i === \"function\") {\n                  return (child, index2) => i(child.toProxy(), index2);\n                } else {\n                  return i;\n                }\n              })\n            );\n          };\n        } else if (prop === \"every\" || prop === \"some\") {\n          return (cb) => {\n            return node2[prop](\n              (child, ...other) => cb(child.toProxy(), ...other)\n            );\n          };\n        } else if (prop === \"root\") {\n          return () => node2.root().toProxy();\n        } else if (prop === \"nodes\") {\n          return node2.nodes.map((i) => i.toProxy());\n        } else if (prop === \"first\" || prop === \"last\") {\n          return node2[prop].toProxy();\n        } else {\n          return node2[prop];\n        }\n      },\n      set(node2, prop, value) {\n        if (node2[prop] === value) return true;\n        node2[prop] = value;\n        if (prop === \"name\" || prop === \"params\" || prop === \"selector\") {\n          node2.markDirty();\n        }\n        return true;\n      }\n    };\n  }\n  index(child) {\n    if (typeof child === \"number\") return child;\n    if (child.proxyOf) child = child.proxyOf;\n    return this.proxyOf.nodes.indexOf(child);\n  }\n  insertAfter(exist, add) {\n    let existIndex = this.index(exist);\n    let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse();\n    existIndex = this.index(exist);\n    for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node2);\n    let index2;\n    for (let id in this.indexes) {\n      index2 = this.indexes[id];\n      if (existIndex < index2) {\n        this.indexes[id] = index2 + nodes.length;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  insertBefore(exist, add) {\n    let existIndex = this.index(exist);\n    let type = existIndex === 0 ? \"prepend\" : false;\n    let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse();\n    existIndex = this.index(exist);\n    for (let node2 of nodes) this.proxyOf.nodes.splice(existIndex, 0, node2);\n    let index2;\n    for (let id in this.indexes) {\n      index2 = this.indexes[id];\n      if (existIndex <= index2) {\n        this.indexes[id] = index2 + nodes.length;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  normalize(nodes, sample) {\n    if (typeof nodes === \"string\") {\n      nodes = cleanSource(parse$4(nodes).nodes);\n    } else if (typeof nodes === \"undefined\") {\n      nodes = [];\n    } else if (Array.isArray(nodes)) {\n      nodes = nodes.slice(0);\n      for (let i of nodes) {\n        if (i.parent) i.parent.removeChild(i, \"ignore\");\n      }\n    } else if (nodes.type === \"root\" && this.type !== \"document\") {\n      nodes = nodes.nodes.slice(0);\n      for (let i of nodes) {\n        if (i.parent) i.parent.removeChild(i, \"ignore\");\n      }\n    } else if (nodes.type) {\n      nodes = [nodes];\n    } else if (nodes.prop) {\n      if (typeof nodes.value === \"undefined\") {\n        throw new Error(\"Value field is missed in node creation\");\n      } else if (typeof nodes.value !== \"string\") {\n        nodes.value = String(nodes.value);\n      }\n      nodes = [new Declaration$3(nodes)];\n    } else if (nodes.selector) {\n      nodes = [new Rule$4(nodes)];\n    } else if (nodes.name) {\n      nodes = [new AtRule$4(nodes)];\n    } else if (nodes.text) {\n      nodes = [new Comment$3(nodes)];\n    } else {\n      throw new Error(\"Unknown node type in node creation\");\n    }\n    let processed = nodes.map((i) => {\n      if (!i[my$1]) Container.rebuild(i);\n      i = i.proxyOf;\n      if (i.parent) i.parent.removeChild(i);\n      if (i[isClean$1]) markDirtyUp(i);\n      if (typeof i.raws.before === \"undefined\") {\n        if (sample && typeof sample.raws.before !== \"undefined\") {\n          i.raws.before = sample.raws.before.replace(/\\S/g, \"\");\n        }\n      }\n      i.parent = this.proxyOf;\n      return i;\n    });\n    return processed;\n  }\n  prepend(...children) {\n    children = children.reverse();\n    for (let child of children) {\n      let nodes = this.normalize(child, this.first, \"prepend\").reverse();\n      for (let node2 of nodes) this.proxyOf.nodes.unshift(node2);\n      for (let id in this.indexes) {\n        this.indexes[id] = this.indexes[id] + nodes.length;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  push(child) {\n    child.parent = this;\n    this.proxyOf.nodes.push(child);\n    return this;\n  }\n  removeAll() {\n    for (let node2 of this.proxyOf.nodes) node2.parent = void 0;\n    this.proxyOf.nodes = [];\n    this.markDirty();\n    return this;\n  }\n  removeChild(child) {\n    child = this.index(child);\n    this.proxyOf.nodes[child].parent = void 0;\n    this.proxyOf.nodes.splice(child, 1);\n    let index2;\n    for (let id in this.indexes) {\n      index2 = this.indexes[id];\n      if (index2 >= child) {\n        this.indexes[id] = index2 - 1;\n      }\n    }\n    this.markDirty();\n    return this;\n  }\n  replaceValues(pattern, opts, callback) {\n    if (!callback) {\n      callback = opts;\n      opts = {};\n    }\n    this.walkDecls((decl) => {\n      if (opts.props && !opts.props.includes(decl.prop)) return;\n      if (opts.fast && !decl.value.includes(opts.fast)) return;\n      decl.value = decl.value.replace(pattern, callback);\n    });\n    this.markDirty();\n    return this;\n  }\n  some(condition) {\n    return this.nodes.some(condition);\n  }\n  walk(callback) {\n    return this.each((child, i) => {\n      let result2;\n      try {\n        result2 = callback(child, i);\n      } catch (e) {\n        throw child.addToError(e);\n      }\n      if (result2 !== false && child.walk) {\n        result2 = child.walk(callback);\n      }\n      return result2;\n    });\n  }\n  walkAtRules(name, callback) {\n    if (!callback) {\n      callback = name;\n      return this.walk((child, i) => {\n        if (child.type === \"atrule\") {\n          return callback(child, i);\n        }\n      });\n    }\n    if (name instanceof RegExp) {\n      return this.walk((child, i) => {\n        if (child.type === \"atrule\" && name.test(child.name)) {\n          return callback(child, i);\n        }\n      });\n    }\n    return this.walk((child, i) => {\n      if (child.type === \"atrule\" && child.name === name) {\n        return callback(child, i);\n      }\n    });\n  }\n  walkComments(callback) {\n    return this.walk((child, i) => {\n      if (child.type === \"comment\") {\n        return callback(child, i);\n      }\n    });\n  }\n  walkDecls(prop, callback) {\n    if (!callback) {\n      callback = prop;\n      return this.walk((child, i) => {\n        if (child.type === \"decl\") {\n          return callback(child, i);\n        }\n      });\n    }\n    if (prop instanceof RegExp) {\n      return this.walk((child, i) => {\n        if (child.type === \"decl\" && prop.test(child.prop)) {\n          return callback(child, i);\n        }\n      });\n    }\n    return this.walk((child, i) => {\n      if (child.type === \"decl\" && child.prop === prop) {\n        return callback(child, i);\n      }\n    });\n  }\n  walkRules(selector, callback) {\n    if (!callback) {\n      callback = selector;\n      return this.walk((child, i) => {\n        if (child.type === \"rule\") {\n          return callback(child, i);\n        }\n      });\n    }\n    if (selector instanceof RegExp) {\n      return this.walk((child, i) => {\n        if (child.type === \"rule\" && selector.test(child.selector)) {\n          return callback(child, i);\n        }\n      });\n    }\n    return this.walk((child, i) => {\n      if (child.type === \"rule\" && child.selector === selector) {\n        return callback(child, i);\n      }\n    });\n  }\n  get first() {\n    if (!this.proxyOf.nodes) return void 0;\n    return this.proxyOf.nodes[0];\n  }\n  get last() {\n    if (!this.proxyOf.nodes) return void 0;\n    return this.proxyOf.nodes[this.proxyOf.nodes.length - 1];\n  }\n};\nContainer$7.registerParse = (dependant) => {\n  parse$4 = dependant;\n};\nContainer$7.registerRule = (dependant) => {\n  Rule$4 = dependant;\n};\nContainer$7.registerAtRule = (dependant) => {\n  AtRule$4 = dependant;\n};\nContainer$7.registerRoot = (dependant) => {\n  Root$6 = dependant;\n};\nvar container = Container$7;\nContainer$7.default = Container$7;\nContainer$7.rebuild = (node2) => {\n  if (node2.type === \"atrule\") {\n    Object.setPrototypeOf(node2, AtRule$4.prototype);\n  } else if (node2.type === \"rule\") {\n    Object.setPrototypeOf(node2, Rule$4.prototype);\n  } else if (node2.type === \"decl\") {\n    Object.setPrototypeOf(node2, Declaration$3.prototype);\n  } else if (node2.type === \"comment\") {\n    Object.setPrototypeOf(node2, Comment$3.prototype);\n  } else if (node2.type === \"root\") {\n    Object.setPrototypeOf(node2, Root$6.prototype);\n  }\n  node2[my$1] = true;\n  if (node2.nodes) {\n    node2.nodes.forEach((child) => {\n      Container$7.rebuild(child);\n    });\n  }\n};\nlet Container$6 = container;\nlet LazyResult$4, Processor$3;\nlet Document$3 = class Document2 extends Container$6 {\n  constructor(defaults) {\n    super({ type: \"document\", ...defaults });\n    if (!this.nodes) {\n      this.nodes = [];\n    }\n  }\n  toResult(opts = {}) {\n    let lazy = new LazyResult$4(new Processor$3(), this, opts);\n    return lazy.stringify();\n  }\n};\nDocument$3.registerLazyResult = (dependant) => {\n  LazyResult$4 = dependant;\n};\nDocument$3.registerProcessor = (dependant) => {\n  Processor$3 = dependant;\n};\nvar document$1 = Document$3;\nDocument$3.default = Document$3;\nlet printed = {};\nvar warnOnce$2 = function warnOnce(message) {\n  if (printed[message]) return;\n  printed[message] = true;\n  if (typeof console !== \"undefined\" && console.warn) {\n    console.warn(message);\n  }\n};\nlet Warning$2 = class Warning {\n  constructor(text, opts = {}) {\n    this.type = \"warning\";\n    this.text = text;\n    if (opts.node && opts.node.source) {\n      let range = opts.node.rangeBy(opts);\n      this.line = range.start.line;\n      this.column = range.start.column;\n      this.endLine = range.end.line;\n      this.endColumn = range.end.column;\n    }\n    for (let opt in opts) this[opt] = opts[opt];\n  }\n  toString() {\n    if (this.node) {\n      return this.node.error(this.text, {\n        index: this.index,\n        plugin: this.plugin,\n        word: this.word\n      }).message;\n    }\n    if (this.plugin) {\n      return this.plugin + \": \" + this.text;\n    }\n    return this.text;\n  }\n};\nvar warning = Warning$2;\nWarning$2.default = Warning$2;\nlet Warning$1 = warning;\nlet Result$3 = class Result {\n  constructor(processor2, root2, opts) {\n    this.processor = processor2;\n    this.messages = [];\n    this.root = root2;\n    this.opts = opts;\n    this.css = void 0;\n    this.map = void 0;\n  }\n  toString() {\n    return this.css;\n  }\n  warn(text, opts = {}) {\n    if (!opts.plugin) {\n      if (this.lastPlugin && this.lastPlugin.postcssPlugin) {\n        opts.plugin = this.lastPlugin.postcssPlugin;\n      }\n    }\n    let warning2 = new Warning$1(text, opts);\n    this.messages.push(warning2);\n    return warning2;\n  }\n  warnings() {\n    return this.messages.filter((i) => i.type === \"warning\");\n  }\n  get content() {\n    return this.css;\n  }\n};\nvar result = Result$3;\nResult$3.default = Result$3;\nconst SINGLE_QUOTE = \"'\".charCodeAt(0);\nconst DOUBLE_QUOTE = '\"'.charCodeAt(0);\nconst BACKSLASH = \"\\\\\".charCodeAt(0);\nconst SLASH = \"/\".charCodeAt(0);\nconst NEWLINE = \"\\n\".charCodeAt(0);\nconst SPACE = \" \".charCodeAt(0);\nconst FEED = \"\\f\".charCodeAt(0);\nconst TAB = \"\t\".charCodeAt(0);\nconst CR = \"\\r\".charCodeAt(0);\nconst OPEN_SQUARE = \"[\".charCodeAt(0);\nconst CLOSE_SQUARE = \"]\".charCodeAt(0);\nconst OPEN_PARENTHESES = \"(\".charCodeAt(0);\nconst CLOSE_PARENTHESES = \")\".charCodeAt(0);\nconst OPEN_CURLY = \"{\".charCodeAt(0);\nconst CLOSE_CURLY = \"}\".charCodeAt(0);\nconst SEMICOLON = \";\".charCodeAt(0);\nconst ASTERISK = \"*\".charCodeAt(0);\nconst COLON = \":\".charCodeAt(0);\nconst AT = \"@\".charCodeAt(0);\nconst RE_AT_END = /[\\t\\n\\f\\r \"#'()/;[\\\\\\]{}]/g;\nconst RE_WORD_END = /[\\t\\n\\f\\r !\"#'():;@[\\\\\\]{}]|\\/(?=\\*)/g;\nconst RE_BAD_BRACKET = /.[\\r\\n\"'(/\\\\]/;\nconst RE_HEX_ESCAPE = /[\\da-f]/i;\nvar tokenize = function tokenizer(input2, options = {}) {\n  let css = input2.css.valueOf();\n  let ignore = options.ignoreErrors;\n  let code, next, quote, content, escape;\n  let escaped, escapePos, prev, n, currentToken;\n  let length = css.length;\n  let pos = 0;\n  let buffer = [];\n  let returned = [];\n  function position() {\n    return pos;\n  }\n  function unclosed(what) {\n    throw input2.error(\"Unclosed \" + what, pos);\n  }\n  function endOfFile() {\n    return returned.length === 0 && pos >= length;\n  }\n  function nextToken(opts) {\n    if (returned.length) return returned.pop();\n    if (pos >= length) return;\n    let ignoreUnclosed = opts ? opts.ignoreUnclosed : false;\n    code = css.charCodeAt(pos);\n    switch (code) {\n      case NEWLINE:\n      case SPACE:\n      case TAB:\n      case CR:\n      case FEED: {\n        next = pos;\n        do {\n          next += 1;\n          code = css.charCodeAt(next);\n        } while (code === SPACE || code === NEWLINE || code === TAB || code === CR || code === FEED);\n        currentToken = [\"space\", css.slice(pos, next)];\n        pos = next - 1;\n        break;\n      }\n      case OPEN_SQUARE:\n      case CLOSE_SQUARE:\n      case OPEN_CURLY:\n      case CLOSE_CURLY:\n      case COLON:\n      case SEMICOLON:\n      case CLOSE_PARENTHESES: {\n        let controlChar = String.fromCharCode(code);\n        currentToken = [controlChar, controlChar, pos];\n        break;\n      }\n      case OPEN_PARENTHESES: {\n        prev = buffer.length ? buffer.pop()[1] : \"\";\n        n = css.charCodeAt(pos + 1);\n        if (prev === \"url\" && n !== SINGLE_QUOTE && n !== DOUBLE_QUOTE && n !== SPACE && n !== NEWLINE && n !== TAB && n !== FEED && n !== CR) {\n          next = pos;\n          do {\n            escaped = false;\n            next = css.indexOf(\")\", next + 1);\n            if (next === -1) {\n              if (ignore || ignoreUnclosed) {\n                next = pos;\n                break;\n              } else {\n                unclosed(\"bracket\");\n              }\n            }\n            escapePos = next;\n            while (css.charCodeAt(escapePos - 1) === BACKSLASH) {\n              escapePos -= 1;\n              escaped = !escaped;\n            }\n          } while (escaped);\n          currentToken = [\"brackets\", css.slice(pos, next + 1), pos, next];\n          pos = next;\n        } else {\n          next = css.indexOf(\")\", pos + 1);\n          content = css.slice(pos, next + 1);\n          if (next === -1 || RE_BAD_BRACKET.test(content)) {\n            currentToken = [\"(\", \"(\", pos];\n          } else {\n            currentToken = [\"brackets\", content, pos, next];\n            pos = next;\n          }\n        }\n        break;\n      }\n      case SINGLE_QUOTE:\n      case DOUBLE_QUOTE: {\n        quote = code === SINGLE_QUOTE ? \"'\" : '\"';\n        next = pos;\n        do {\n          escaped = false;\n          next = css.indexOf(quote, next + 1);\n          if (next === -1) {\n            if (ignore || ignoreUnclosed) {\n              next = pos + 1;\n              break;\n            } else {\n              unclosed(\"string\");\n            }\n          }\n          escapePos = next;\n          while (css.charCodeAt(escapePos - 1) === BACKSLASH) {\n            escapePos -= 1;\n            escaped = !escaped;\n          }\n        } while (escaped);\n        currentToken = [\"string\", css.slice(pos, next + 1), pos, next];\n        pos = next;\n        break;\n      }\n      case AT: {\n        RE_AT_END.lastIndex = pos + 1;\n        RE_AT_END.test(css);\n        if (RE_AT_END.lastIndex === 0) {\n          next = css.length - 1;\n        } else {\n          next = RE_AT_END.lastIndex - 2;\n        }\n        currentToken = [\"at-word\", css.slice(pos, next + 1), pos, next];\n        pos = next;\n        break;\n      }\n      case BACKSLASH: {\n        next = pos;\n        escape = true;\n        while (css.charCodeAt(next + 1) === BACKSLASH) {\n          next += 1;\n          escape = !escape;\n        }\n        code = css.charCodeAt(next + 1);\n        if (escape && code !== SLASH && code !== SPACE && code !== NEWLINE && code !== TAB && code !== CR && code !== FEED) {\n          next += 1;\n          if (RE_HEX_ESCAPE.test(css.charAt(next))) {\n            while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) {\n              next += 1;\n            }\n            if (css.charCodeAt(next + 1) === SPACE) {\n              next += 1;\n            }\n          }\n        }\n        currentToken = [\"word\", css.slice(pos, next + 1), pos, next];\n        pos = next;\n        break;\n      }\n      default: {\n        if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) {\n          next = css.indexOf(\"*/\", pos + 2) + 1;\n          if (next === 0) {\n            if (ignore || ignoreUnclosed) {\n              next = css.length;\n            } else {\n              unclosed(\"comment\");\n            }\n          }\n          currentToken = [\"comment\", css.slice(pos, next + 1), pos, next];\n          pos = next;\n        } else {\n          RE_WORD_END.lastIndex = pos + 1;\n          RE_WORD_END.test(css);\n          if (RE_WORD_END.lastIndex === 0) {\n            next = css.length - 1;\n          } else {\n            next = RE_WORD_END.lastIndex - 2;\n          }\n          currentToken = [\"word\", css.slice(pos, next + 1), pos, next];\n          buffer.push(currentToken);\n          pos = next;\n        }\n        break;\n      }\n    }\n    pos++;\n    return currentToken;\n  }\n  function back(token) {\n    returned.push(token);\n  }\n  return {\n    back,\n    endOfFile,\n    nextToken,\n    position\n  };\n};\nlet Container$5 = container;\nlet AtRule$3 = class AtRule extends Container$5 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"atrule\";\n  }\n  append(...children) {\n    if (!this.proxyOf.nodes) this.nodes = [];\n    return super.append(...children);\n  }\n  prepend(...children) {\n    if (!this.proxyOf.nodes) this.nodes = [];\n    return super.prepend(...children);\n  }\n};\nvar atRule = AtRule$3;\nAtRule$3.default = AtRule$3;\nContainer$5.registerAtRule(AtRule$3);\nlet Container$4 = container;\nlet LazyResult$3, Processor$2;\nlet Root$5 = class Root extends Container$4 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"root\";\n    if (!this.nodes) this.nodes = [];\n  }\n  normalize(child, sample, type) {\n    let nodes = super.normalize(child);\n    if (sample) {\n      if (type === \"prepend\") {\n        if (this.nodes.length > 1) {\n          sample.raws.before = this.nodes[1].raws.before;\n        } else {\n          delete sample.raws.before;\n        }\n      } else if (this.first !== sample) {\n        for (let node2 of nodes) {\n          node2.raws.before = sample.raws.before;\n        }\n      }\n    }\n    return nodes;\n  }\n  removeChild(child, ignore) {\n    let index2 = this.index(child);\n    if (!ignore && index2 === 0 && this.nodes.length > 1) {\n      this.nodes[1].raws.before = this.nodes[index2].raws.before;\n    }\n    return super.removeChild(child);\n  }\n  toResult(opts = {}) {\n    let lazy = new LazyResult$3(new Processor$2(), this, opts);\n    return lazy.stringify();\n  }\n};\nRoot$5.registerLazyResult = (dependant) => {\n  LazyResult$3 = dependant;\n};\nRoot$5.registerProcessor = (dependant) => {\n  Processor$2 = dependant;\n};\nvar root = Root$5;\nRoot$5.default = Root$5;\nContainer$4.registerRoot(Root$5);\nlet list$2 = {\n  comma(string) {\n    return list$2.split(string, [\",\"], true);\n  },\n  space(string) {\n    let spaces = [\" \", \"\\n\", \"\t\"];\n    return list$2.split(string, spaces);\n  },\n  split(string, separators, last) {\n    let array = [];\n    let current = \"\";\n    let split = false;\n    let func = 0;\n    let inQuote = false;\n    let prevQuote = \"\";\n    let escape = false;\n    for (let letter of string) {\n      if (escape) {\n        escape = false;\n      } else if (letter === \"\\\\\") {\n        escape = true;\n      } else if (inQuote) {\n        if (letter === prevQuote) {\n          inQuote = false;\n        }\n      } else if (letter === '\"' || letter === \"'\") {\n        inQuote = true;\n        prevQuote = letter;\n      } else if (letter === \"(\") {\n        func += 1;\n      } else if (letter === \")\") {\n        if (func > 0) func -= 1;\n      } else if (func === 0) {\n        if (separators.includes(letter)) split = true;\n      }\n      if (split) {\n        if (current !== \"\") array.push(current.trim());\n        current = \"\";\n        split = false;\n      } else {\n        current += letter;\n      }\n    }\n    if (last || current !== \"\") array.push(current.trim());\n    return array;\n  }\n};\nvar list_1 = list$2;\nlist$2.default = list$2;\nlet Container$3 = container;\nlet list$1 = list_1;\nlet Rule$3 = class Rule extends Container$3 {\n  constructor(defaults) {\n    super(defaults);\n    this.type = \"rule\";\n    if (!this.nodes) this.nodes = [];\n  }\n  get selectors() {\n    return list$1.comma(this.selector);\n  }\n  set selectors(values) {\n    let match = this.selector ? this.selector.match(/,\\s*/) : null;\n    let sep2 = match ? match[0] : \",\" + this.raw(\"between\", \"beforeOpen\");\n    this.selector = values.join(sep2);\n  }\n};\nvar rule = Rule$3;\nRule$3.default = Rule$3;\nContainer$3.registerRule(Rule$3);\nlet Declaration$2 = declaration;\nlet tokenizer2 = tokenize;\nlet Comment$2 = comment;\nlet AtRule$2 = atRule;\nlet Root$4 = root;\nlet Rule$2 = rule;\nconst SAFE_COMMENT_NEIGHBOR = {\n  empty: true,\n  space: true\n};\nfunction findLastWithPosition(tokens) {\n  for (let i = tokens.length - 1; i >= 0; i--) {\n    let token = tokens[i];\n    let pos = token[3] || token[2];\n    if (pos) return pos;\n  }\n}\nlet Parser$1 = class Parser {\n  constructor(input2) {\n    this.input = input2;\n    this.root = new Root$4();\n    this.current = this.root;\n    this.spaces = \"\";\n    this.semicolon = false;\n    this.createTokenizer();\n    this.root.source = { input: input2, start: { column: 1, line: 1, offset: 0 } };\n  }\n  atrule(token) {\n    let node2 = new AtRule$2();\n    node2.name = token[1].slice(1);\n    if (node2.name === \"\") {\n      this.unnamedAtrule(node2, token);\n    }\n    this.init(node2, token[2]);\n    let type;\n    let prev;\n    let shift;\n    let last = false;\n    let open = false;\n    let params = [];\n    let brackets = [];\n    while (!this.tokenizer.endOfFile()) {\n      token = this.tokenizer.nextToken();\n      type = token[0];\n      if (type === \"(\" || type === \"[\") {\n        brackets.push(type === \"(\" ? \")\" : \"]\");\n      } else if (type === \"{\" && brackets.length > 0) {\n        brackets.push(\"}\");\n      } else if (type === brackets[brackets.length - 1]) {\n        brackets.pop();\n      }\n      if (brackets.length === 0) {\n        if (type === \";\") {\n          node2.source.end = this.getPosition(token[2]);\n          node2.source.end.offset++;\n          this.semicolon = true;\n          break;\n        } else if (type === \"{\") {\n          open = true;\n          break;\n        } else if (type === \"}\") {\n          if (params.length > 0) {\n            shift = params.length - 1;\n            prev = params[shift];\n            while (prev && prev[0] === \"space\") {\n              prev = params[--shift];\n            }\n            if (prev) {\n              node2.source.end = this.getPosition(prev[3] || prev[2]);\n              node2.source.end.offset++;\n            }\n          }\n          this.end(token);\n          break;\n        } else {\n          params.push(token);\n        }\n      } else {\n        params.push(token);\n      }\n      if (this.tokenizer.endOfFile()) {\n        last = true;\n        break;\n      }\n    }\n    node2.raws.between = this.spacesAndCommentsFromEnd(params);\n    if (params.length) {\n      node2.raws.afterName = this.spacesAndCommentsFromStart(params);\n      this.raw(node2, \"params\", params);\n      if (last) {\n        token = params[params.length - 1];\n        node2.source.end = this.getPosition(token[3] || token[2]);\n        node2.source.end.offset++;\n        this.spaces = node2.raws.between;\n        node2.raws.between = \"\";\n      }\n    } else {\n      node2.raws.afterName = \"\";\n      node2.params = \"\";\n    }\n    if (open) {\n      node2.nodes = [];\n      this.current = node2;\n    }\n  }\n  checkMissedSemicolon(tokens) {\n    let colon = this.colon(tokens);\n    if (colon === false) return;\n    let founded = 0;\n    let token;\n    for (let j = colon - 1; j >= 0; j--) {\n      token = tokens[j];\n      if (token[0] !== \"space\") {\n        founded += 1;\n        if (founded === 2) break;\n      }\n    }\n    throw this.input.error(\n      \"Missed semicolon\",\n      token[0] === \"word\" ? token[3] + 1 : token[2]\n    );\n  }\n  colon(tokens) {\n    let brackets = 0;\n    let token, type, prev;\n    for (let [i, element] of tokens.entries()) {\n      token = element;\n      type = token[0];\n      if (type === \"(\") {\n        brackets += 1;\n      }\n      if (type === \")\") {\n        brackets -= 1;\n      }\n      if (brackets === 0 && type === \":\") {\n        if (!prev) {\n          this.doubleColon(token);\n        } else if (prev[0] === \"word\" && prev[1] === \"progid\") {\n          continue;\n        } else {\n          return i;\n        }\n      }\n      prev = token;\n    }\n    return false;\n  }\n  comment(token) {\n    let node2 = new Comment$2();\n    this.init(node2, token[2]);\n    node2.source.end = this.getPosition(token[3] || token[2]);\n    node2.source.end.offset++;\n    let text = token[1].slice(2, -2);\n    if (/^\\s*$/.test(text)) {\n      node2.text = \"\";\n      node2.raws.left = text;\n      node2.raws.right = \"\";\n    } else {\n      let match = text.match(/^(\\s*)([^]*\\S)(\\s*)$/);\n      node2.text = match[2];\n      node2.raws.left = match[1];\n      node2.raws.right = match[3];\n    }\n  }\n  createTokenizer() {\n    this.tokenizer = tokenizer2(this.input);\n  }\n  decl(tokens, customProperty) {\n    let node2 = new Declaration$2();\n    this.init(node2, tokens[0][2]);\n    let last = tokens[tokens.length - 1];\n    if (last[0] === \";\") {\n      this.semicolon = true;\n      tokens.pop();\n    }\n    node2.source.end = this.getPosition(\n      last[3] || last[2] || findLastWithPosition(tokens)\n    );\n    node2.source.end.offset++;\n    while (tokens[0][0] !== \"word\") {\n      if (tokens.length === 1) this.unknownWord(tokens);\n      node2.raws.before += tokens.shift()[1];\n    }\n    node2.source.start = this.getPosition(tokens[0][2]);\n    node2.prop = \"\";\n    while (tokens.length) {\n      let type = tokens[0][0];\n      if (type === \":\" || type === \"space\" || type === \"comment\") {\n        break;\n      }\n      node2.prop += tokens.shift()[1];\n    }\n    node2.raws.between = \"\";\n    let token;\n    while (tokens.length) {\n      token = tokens.shift();\n      if (token[0] === \":\") {\n        node2.raws.between += token[1];\n        break;\n      } else {\n        if (token[0] === \"word\" && /\\w/.test(token[1])) {\n          this.unknownWord([token]);\n        }\n        node2.raws.between += token[1];\n      }\n    }\n    if (node2.prop[0] === \"_\" || node2.prop[0] === \"*\") {\n      node2.raws.before += node2.prop[0];\n      node2.prop = node2.prop.slice(1);\n    }\n    let firstSpaces = [];\n    let next;\n    while (tokens.length) {\n      next = tokens[0][0];\n      if (next !== \"space\" && next !== \"comment\") break;\n      firstSpaces.push(tokens.shift());\n    }\n    this.precheckMissedSemicolon(tokens);\n    for (let i = tokens.length - 1; i >= 0; i--) {\n      token = tokens[i];\n      if (token[1].toLowerCase() === \"!important\") {\n        node2.important = true;\n        let string = this.stringFrom(tokens, i);\n        string = this.spacesFromEnd(tokens) + string;\n        if (string !== \" !important\") node2.raws.important = string;\n        break;\n      } else if (token[1].toLowerCase() === \"important\") {\n        let cache = tokens.slice(0);\n        let str = \"\";\n        for (let j = i; j > 0; j--) {\n          let type = cache[j][0];\n          if (str.trim().indexOf(\"!\") === 0 && type !== \"space\") {\n            break;\n          }\n          str = cache.pop()[1] + str;\n        }\n        if (str.trim().indexOf(\"!\") === 0) {\n          node2.important = true;\n          node2.raws.important = str;\n          tokens = cache;\n        }\n      }\n      if (token[0] !== \"space\" && token[0] !== \"comment\") {\n        break;\n      }\n    }\n    let hasWord = tokens.some((i) => i[0] !== \"space\" && i[0] !== \"comment\");\n    if (hasWord) {\n      node2.raws.between += firstSpaces.map((i) => i[1]).join(\"\");\n      firstSpaces = [];\n    }\n    this.raw(node2, \"value\", firstSpaces.concat(tokens), customProperty);\n    if (node2.value.includes(\":\") && !customProperty) {\n      this.checkMissedSemicolon(tokens);\n    }\n  }\n  doubleColon(token) {\n    throw this.input.error(\n      \"Double colon\",\n      { offset: token[2] },\n      { offset: token[2] + token[1].length }\n    );\n  }\n  emptyRule(token) {\n    let node2 = new Rule$2();\n    this.init(node2, token[2]);\n    node2.selector = \"\";\n    node2.raws.between = \"\";\n    this.current = node2;\n  }\n  end(token) {\n    if (this.current.nodes && this.current.nodes.length) {\n      this.current.raws.semicolon = this.semicolon;\n    }\n    this.semicolon = false;\n    this.current.raws.after = (this.current.raws.after || \"\") + this.spaces;\n    this.spaces = \"\";\n    if (this.current.parent) {\n      this.current.source.end = this.getPosition(token[2]);\n      this.current.source.end.offset++;\n      this.current = this.current.parent;\n    } else {\n      this.unexpectedClose(token);\n    }\n  }\n  endFile() {\n    if (this.current.parent) this.unclosedBlock();\n    if (this.current.nodes && this.current.nodes.length) {\n      this.current.raws.semicolon = this.semicolon;\n    }\n    this.current.raws.after = (this.current.raws.after || \"\") + this.spaces;\n    this.root.source.end = this.getPosition(this.tokenizer.position());\n  }\n  freeSemicolon(token) {\n    this.spaces += token[1];\n    if (this.current.nodes) {\n      let prev = this.current.nodes[this.current.nodes.length - 1];\n      if (prev && prev.type === \"rule\" && !prev.raws.ownSemicolon) {\n        prev.raws.ownSemicolon = this.spaces;\n        this.spaces = \"\";\n      }\n    }\n  }\n  // Helpers\n  getPosition(offset) {\n    let pos = this.input.fromOffset(offset);\n    return {\n      column: pos.col,\n      line: pos.line,\n      offset\n    };\n  }\n  init(node2, offset) {\n    this.current.push(node2);\n    node2.source = {\n      input: this.input,\n      start: this.getPosition(offset)\n    };\n    node2.raws.before = this.spaces;\n    this.spaces = \"\";\n    if (node2.type !== \"comment\") this.semicolon = false;\n  }\n  other(start) {\n    let end = false;\n    let type = null;\n    let colon = false;\n    let bracket = null;\n    let brackets = [];\n    let customProperty = start[1].startsWith(\"--\");\n    let tokens = [];\n    let token = start;\n    while (token) {\n      type = token[0];\n      tokens.push(token);\n      if (type === \"(\" || type === \"[\") {\n        if (!bracket) bracket = token;\n        brackets.push(type === \"(\" ? \")\" : \"]\");\n      } else if (customProperty && colon && type === \"{\") {\n        if (!bracket) bracket = token;\n        brackets.push(\"}\");\n      } else if (brackets.length === 0) {\n        if (type === \";\") {\n          if (colon) {\n            this.decl(tokens, customProperty);\n            return;\n          } else {\n            break;\n          }\n        } else if (type === \"{\") {\n          this.rule(tokens);\n          return;\n        } else if (type === \"}\") {\n          this.tokenizer.back(tokens.pop());\n          end = true;\n          break;\n        } else if (type === \":\") {\n          colon = true;\n        }\n      } else if (type === brackets[brackets.length - 1]) {\n        brackets.pop();\n        if (brackets.length === 0) bracket = null;\n      }\n      token = this.tokenizer.nextToken();\n    }\n    if (this.tokenizer.endOfFile()) end = true;\n    if (brackets.length > 0) this.unclosedBracket(bracket);\n    if (end && colon) {\n      if (!customProperty) {\n        while (tokens.length) {\n          token = tokens[tokens.length - 1][0];\n          if (token !== \"space\" && token !== \"comment\") break;\n          this.tokenizer.back(tokens.pop());\n        }\n      }\n      this.decl(tokens, customProperty);\n    } else {\n      this.unknownWord(tokens);\n    }\n  }\n  parse() {\n    let token;\n    while (!this.tokenizer.endOfFile()) {\n      token = this.tokenizer.nextToken();\n      switch (token[0]) {\n        case \"space\":\n          this.spaces += token[1];\n          break;\n        case \";\":\n          this.freeSemicolon(token);\n          break;\n        case \"}\":\n          this.end(token);\n          break;\n        case \"comment\":\n          this.comment(token);\n          break;\n        case \"at-word\":\n          this.atrule(token);\n          break;\n        case \"{\":\n          this.emptyRule(token);\n          break;\n        default:\n          this.other(token);\n          break;\n      }\n    }\n    this.endFile();\n  }\n  precheckMissedSemicolon() {\n  }\n  raw(node2, prop, tokens, customProperty) {\n    let token, type;\n    let length = tokens.length;\n    let value = \"\";\n    let clean = true;\n    let next, prev;\n    for (let i = 0; i < length; i += 1) {\n      token = tokens[i];\n      type = token[0];\n      if (type === \"space\" && i === length - 1 && !customProperty) {\n        clean = false;\n      } else if (type === \"comment\") {\n        prev = tokens[i - 1] ? tokens[i - 1][0] : \"empty\";\n        next = tokens[i + 1] ? tokens[i + 1][0] : \"empty\";\n        if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) {\n          if (value.slice(-1) === \",\") {\n            clean = false;\n          } else {\n            value += token[1];\n          }\n        } else {\n          clean = false;\n        }\n      } else {\n        value += token[1];\n      }\n    }\n    if (!clean) {\n      let raw = tokens.reduce((all, i) => all + i[1], \"\");\n      node2.raws[prop] = { raw, value };\n    }\n    node2[prop] = value;\n  }\n  rule(tokens) {\n    tokens.pop();\n    let node2 = new Rule$2();\n    this.init(node2, tokens[0][2]);\n    node2.raws.between = this.spacesAndCommentsFromEnd(tokens);\n    this.raw(node2, \"selector\", tokens);\n    this.current = node2;\n  }\n  spacesAndCommentsFromEnd(tokens) {\n    let lastTokenType;\n    let spaces = \"\";\n    while (tokens.length) {\n      lastTokenType = tokens[tokens.length - 1][0];\n      if (lastTokenType !== \"space\" && lastTokenType !== \"comment\") break;\n      spaces = tokens.pop()[1] + spaces;\n    }\n    return spaces;\n  }\n  // Errors\n  spacesAndCommentsFromStart(tokens) {\n    let next;\n    let spaces = \"\";\n    while (tokens.length) {\n      next = tokens[0][0];\n      if (next !== \"space\" && next !== \"comment\") break;\n      spaces += tokens.shift()[1];\n    }\n    return spaces;\n  }\n  spacesFromEnd(tokens) {\n    let lastTokenType;\n    let spaces = \"\";\n    while (tokens.length) {\n      lastTokenType = tokens[tokens.length - 1][0];\n      if (lastTokenType !== \"space\") break;\n      spaces = tokens.pop()[1] + spaces;\n    }\n    return spaces;\n  }\n  stringFrom(tokens, from) {\n    let result2 = \"\";\n    for (let i = from; i < tokens.length; i++) {\n      result2 += tokens[i][1];\n    }\n    tokens.splice(from, tokens.length - from);\n    return result2;\n  }\n  unclosedBlock() {\n    let pos = this.current.source.start;\n    throw this.input.error(\"Unclosed block\", pos.line, pos.column);\n  }\n  unclosedBracket(bracket) {\n    throw this.input.error(\n      \"Unclosed bracket\",\n      { offset: bracket[2] },\n      { offset: bracket[2] + 1 }\n    );\n  }\n  unexpectedClose(token) {\n    throw this.input.error(\n      \"Unexpected }\",\n      { offset: token[2] },\n      { offset: token[2] + 1 }\n    );\n  }\n  unknownWord(tokens) {\n    throw this.input.error(\n      \"Unknown word\",\n      { offset: tokens[0][2] },\n      { offset: tokens[0][2] + tokens[0][1].length }\n    );\n  }\n  unnamedAtrule(node2, token) {\n    throw this.input.error(\n      \"At-rule without name\",\n      { offset: token[2] },\n      { offset: token[2] + token[1].length }\n    );\n  }\n};\nvar parser = Parser$1;\nlet Container$2 = container;\nlet Parser2 = parser;\nlet Input$2 = input;\nfunction parse$3(css, opts) {\n  let input2 = new Input$2(css, opts);\n  let parser2 = new Parser2(input2);\n  try {\n    parser2.parse();\n  } catch (e) {\n    if (process.env.NODE_ENV !== \"production\") {\n      if (e.name === \"CssSyntaxError\" && opts && opts.from) {\n        if (/\\.scss$/i.test(opts.from)) {\n          e.message += \"\\nYou tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser\";\n        } else if (/\\.sass/i.test(opts.from)) {\n          e.message += \"\\nYou tried to parse Sass with the standard CSS parser; try again with the postcss-sass parser\";\n        } else if (/\\.less$/i.test(opts.from)) {\n          e.message += \"\\nYou tried to parse Less with the standard CSS parser; try again with the postcss-less parser\";\n        }\n      }\n    }\n    throw e;\n  }\n  return parser2.root;\n}\nvar parse_1 = parse$3;\nparse$3.default = parse$3;\nContainer$2.registerParse(parse$3);\nlet { isClean, my } = symbols;\nlet MapGenerator$1 = mapGenerator;\nlet stringify$2 = stringify_1;\nlet Container$1 = container;\nlet Document$2 = document$1;\nlet warnOnce$1 = warnOnce$2;\nlet Result$2 = result;\nlet parse$2 = parse_1;\nlet Root$3 = root;\nconst TYPE_TO_CLASS_NAME = {\n  atrule: \"AtRule\",\n  comment: \"Comment\",\n  decl: \"Declaration\",\n  document: \"Document\",\n  root: \"Root\",\n  rule: \"Rule\"\n};\nconst PLUGIN_PROPS = {\n  AtRule: true,\n  AtRuleExit: true,\n  Comment: true,\n  CommentExit: true,\n  Declaration: true,\n  DeclarationExit: true,\n  Document: true,\n  DocumentExit: true,\n  Once: true,\n  OnceExit: true,\n  postcssPlugin: true,\n  prepare: true,\n  Root: true,\n  RootExit: true,\n  Rule: true,\n  RuleExit: true\n};\nconst NOT_VISITORS = {\n  Once: true,\n  postcssPlugin: true,\n  prepare: true\n};\nconst CHILDREN = 0;\nfunction isPromise(obj) {\n  return typeof obj === \"object\" && typeof obj.then === \"function\";\n}\nfunction getEvents(node2) {\n  let key = false;\n  let type = TYPE_TO_CLASS_NAME[node2.type];\n  if (node2.type === \"decl\") {\n    key = node2.prop.toLowerCase();\n  } else if (node2.type === \"atrule\") {\n    key = node2.name.toLowerCase();\n  }\n  if (key && node2.append) {\n    return [\n      type,\n      type + \"-\" + key,\n      CHILDREN,\n      type + \"Exit\",\n      type + \"Exit-\" + key\n    ];\n  } else if (key) {\n    return [type, type + \"-\" + key, type + \"Exit\", type + \"Exit-\" + key];\n  } else if (node2.append) {\n    return [type, CHILDREN, type + \"Exit\"];\n  } else {\n    return [type, type + \"Exit\"];\n  }\n}\nfunction toStack(node2) {\n  let events;\n  if (node2.type === \"document\") {\n    events = [\"Document\", CHILDREN, \"DocumentExit\"];\n  } else if (node2.type === \"root\") {\n    events = [\"Root\", CHILDREN, \"RootExit\"];\n  } else {\n    events = getEvents(node2);\n  }\n  return {\n    eventIndex: 0,\n    events,\n    iterator: 0,\n    node: node2,\n    visitorIndex: 0,\n    visitors: []\n  };\n}\nfunction cleanMarks(node2) {\n  node2[isClean] = false;\n  if (node2.nodes) node2.nodes.forEach((i) => cleanMarks(i));\n  return node2;\n}\nlet postcss$2 = {};\nlet LazyResult$2 = class LazyResult {\n  constructor(processor2, css, opts) {\n    this.stringified = false;\n    this.processed = false;\n    let root2;\n    if (typeof css === \"object\" && css !== null && (css.type === \"root\" || css.type === \"document\")) {\n      root2 = cleanMarks(css);\n    } else if (css instanceof LazyResult || css instanceof Result$2) {\n      root2 = cleanMarks(css.root);\n      if (css.map) {\n        if (typeof opts.map === \"undefined\") opts.map = {};\n        if (!opts.map.inline) opts.map.inline = false;\n        opts.map.prev = css.map;\n      }\n    } else {\n      let parser2 = parse$2;\n      if (opts.syntax) parser2 = opts.syntax.parse;\n      if (opts.parser) parser2 = opts.parser;\n      if (parser2.parse) parser2 = parser2.parse;\n      try {\n        root2 = parser2(css, opts);\n      } catch (error) {\n        this.processed = true;\n        this.error = error;\n      }\n      if (root2 && !root2[my]) {\n        Container$1.rebuild(root2);\n      }\n    }\n    this.result = new Result$2(processor2, root2, opts);\n    this.helpers = { ...postcss$2, postcss: postcss$2, result: this.result };\n    this.plugins = this.processor.plugins.map((plugin2) => {\n      if (typeof plugin2 === \"object\" && plugin2.prepare) {\n        return { ...plugin2, ...plugin2.prepare(this.result) };\n      } else {\n        return plugin2;\n      }\n    });\n  }\n  async() {\n    if (this.error) return Promise.reject(this.error);\n    if (this.processed) return Promise.resolve(this.result);\n    if (!this.processing) {\n      this.processing = this.runAsync();\n    }\n    return this.processing;\n  }\n  catch(onRejected) {\n    return this.async().catch(onRejected);\n  }\n  finally(onFinally) {\n    return this.async().then(onFinally, onFinally);\n  }\n  getAsyncError() {\n    throw new Error(\"Use process(css).then(cb) to work with async plugins\");\n  }\n  handleError(error, node2) {\n    let plugin2 = this.result.lastPlugin;\n    try {\n      if (node2) node2.addToError(error);\n      this.error = error;\n      if (error.name === \"CssSyntaxError\" && !error.plugin) {\n        error.plugin = plugin2.postcssPlugin;\n        error.setMessage();\n      } else if (plugin2.postcssVersion) {\n        if (process.env.NODE_ENV !== \"production\") {\n          let pluginName = plugin2.postcssPlugin;\n          let pluginVer = plugin2.postcssVersion;\n          let runtimeVer = this.result.processor.version;\n          let a = pluginVer.split(\".\");\n          let b = runtimeVer.split(\".\");\n          if (a[0] !== b[0] || parseInt(a[1]) > parseInt(b[1])) {\n            console.error(\n              \"Unknown error from PostCSS plugin. Your current PostCSS version is \" + runtimeVer + \", but \" + pluginName + \" uses \" + pluginVer + \". Perhaps this is the source of the error below.\"\n            );\n          }\n        }\n      }\n    } catch (err) {\n      if (console && console.error) console.error(err);\n    }\n    return error;\n  }\n  prepareVisitors() {\n    this.listeners = {};\n    let add = (plugin2, type, cb) => {\n      if (!this.listeners[type]) this.listeners[type] = [];\n      this.listeners[type].push([plugin2, cb]);\n    };\n    for (let plugin2 of this.plugins) {\n      if (typeof plugin2 === \"object\") {\n        for (let event in plugin2) {\n          if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) {\n            throw new Error(\n              `Unknown event ${event} in ${plugin2.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`\n            );\n          }\n          if (!NOT_VISITORS[event]) {\n            if (typeof plugin2[event] === \"object\") {\n              for (let filter in plugin2[event]) {\n                if (filter === \"*\") {\n                  add(plugin2, event, plugin2[event][filter]);\n                } else {\n                  add(\n                    plugin2,\n                    event + \"-\" + filter.toLowerCase(),\n                    plugin2[event][filter]\n                  );\n                }\n              }\n            } else if (typeof plugin2[event] === \"function\") {\n              add(plugin2, event, plugin2[event]);\n            }\n          }\n        }\n      }\n    }\n    this.hasListener = Object.keys(this.listeners).length > 0;\n  }\n  async runAsync() {\n    this.plugin = 0;\n    for (let i = 0; i < this.plugins.length; i++) {\n      let plugin2 = this.plugins[i];\n      let promise = this.runOnRoot(plugin2);\n      if (isPromise(promise)) {\n        try {\n          await promise;\n        } catch (error) {\n          throw this.handleError(error);\n        }\n      }\n    }\n    this.prepareVisitors();\n    if (this.hasListener) {\n      let root2 = this.result.root;\n      while (!root2[isClean]) {\n        root2[isClean] = true;\n        let stack = [toStack(root2)];\n        while (stack.length > 0) {\n          let promise = this.visitTick(stack);\n          if (isPromise(promise)) {\n            try {\n              await promise;\n            } catch (e) {\n              let node2 = stack[stack.length - 1].node;\n              throw this.handleError(e, node2);\n            }\n          }\n        }\n      }\n      if (this.listeners.OnceExit) {\n        for (let [plugin2, visitor] of this.listeners.OnceExit) {\n          this.result.lastPlugin = plugin2;\n          try {\n            if (root2.type === \"document\") {\n              let roots = root2.nodes.map(\n                (subRoot) => visitor(subRoot, this.helpers)\n              );\n              await Promise.all(roots);\n            } else {\n              await visitor(root2, this.helpers);\n            }\n          } catch (e) {\n            throw this.handleError(e);\n          }\n        }\n      }\n    }\n    this.processed = true;\n    return this.stringify();\n  }\n  runOnRoot(plugin2) {\n    this.result.lastPlugin = plugin2;\n    try {\n      if (typeof plugin2 === \"object\" && plugin2.Once) {\n        if (this.result.root.type === \"document\") {\n          let roots = this.result.root.nodes.map(\n            (root2) => plugin2.Once(root2, this.helpers)\n          );\n          if (isPromise(roots[0])) {\n            return Promise.all(roots);\n          }\n          return roots;\n        }\n        return plugin2.Once(this.result.root, this.helpers);\n      } else if (typeof plugin2 === \"function\") {\n        return plugin2(this.result.root, this.result);\n      }\n    } catch (error) {\n      throw this.handleError(error);\n    }\n  }\n  stringify() {\n    if (this.error) throw this.error;\n    if (this.stringified) return this.result;\n    this.stringified = true;\n    this.sync();\n    let opts = this.result.opts;\n    let str = stringify$2;\n    if (opts.syntax) str = opts.syntax.stringify;\n    if (opts.stringifier) str = opts.stringifier;\n    if (str.stringify) str = str.stringify;\n    let map = new MapGenerator$1(str, this.result.root, this.result.opts);\n    let data = map.generate();\n    this.result.css = data[0];\n    this.result.map = data[1];\n    return this.result;\n  }\n  sync() {\n    if (this.error) throw this.error;\n    if (this.processed) return this.result;\n    this.processed = true;\n    if (this.processing) {\n      throw this.getAsyncError();\n    }\n    for (let plugin2 of this.plugins) {\n      let promise = this.runOnRoot(plugin2);\n      if (isPromise(promise)) {\n        throw this.getAsyncError();\n      }\n    }\n    this.prepareVisitors();\n    if (this.hasListener) {\n      let root2 = this.result.root;\n      while (!root2[isClean]) {\n        root2[isClean] = true;\n        this.walkSync(root2);\n      }\n      if (this.listeners.OnceExit) {\n        if (root2.type === \"document\") {\n          for (let subRoot of root2.nodes) {\n            this.visitSync(this.listeners.OnceExit, subRoot);\n          }\n        } else {\n          this.visitSync(this.listeners.OnceExit, root2);\n        }\n      }\n    }\n    return this.result;\n  }\n  then(onFulfilled, onRejected) {\n    if (process.env.NODE_ENV !== \"production\") {\n      if (!(\"from\" in this.opts)) {\n        warnOnce$1(\n          \"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning.\"\n        );\n      }\n    }\n    return this.async().then(onFulfilled, onRejected);\n  }\n  toString() {\n    return this.css;\n  }\n  visitSync(visitors, node2) {\n    for (let [plugin2, visitor] of visitors) {\n      this.result.lastPlugin = plugin2;\n      let promise;\n      try {\n        promise = visitor(node2, this.helpers);\n      } catch (e) {\n        throw this.handleError(e, node2.proxyOf);\n      }\n      if (node2.type !== \"root\" && node2.type !== \"document\" && !node2.parent) {\n        return true;\n      }\n      if (isPromise(promise)) {\n        throw this.getAsyncError();\n      }\n    }\n  }\n  visitTick(stack) {\n    let visit2 = stack[stack.length - 1];\n    let { node: node2, visitors } = visit2;\n    if (node2.type !== \"root\" && node2.type !== \"document\" && !node2.parent) {\n      stack.pop();\n      return;\n    }\n    if (visitors.length > 0 && visit2.visitorIndex < visitors.length) {\n      let [plugin2, visitor] = visitors[visit2.visitorIndex];\n      visit2.visitorIndex += 1;\n      if (visit2.visitorIndex === visitors.length) {\n        visit2.visitors = [];\n        visit2.visitorIndex = 0;\n      }\n      this.result.lastPlugin = plugin2;\n      try {\n        return visitor(node2.toProxy(), this.helpers);\n      } catch (e) {\n        throw this.handleError(e, node2);\n      }\n    }\n    if (visit2.iterator !== 0) {\n      let iterator = visit2.iterator;\n      let child;\n      while (child = node2.nodes[node2.indexes[iterator]]) {\n        node2.indexes[iterator] += 1;\n        if (!child[isClean]) {\n          child[isClean] = true;\n          stack.push(toStack(child));\n          return;\n        }\n      }\n      visit2.iterator = 0;\n      delete node2.indexes[iterator];\n    }\n    let events = visit2.events;\n    while (visit2.eventIndex < events.length) {\n      let event = events[visit2.eventIndex];\n      visit2.eventIndex += 1;\n      if (event === CHILDREN) {\n        if (node2.nodes && node2.nodes.length) {\n          node2[isClean] = true;\n          visit2.iterator = node2.getIterator();\n        }\n        return;\n      } else if (this.listeners[event]) {\n        visit2.visitors = this.listeners[event];\n        return;\n      }\n    }\n    stack.pop();\n  }\n  walkSync(node2) {\n    node2[isClean] = true;\n    let events = getEvents(node2);\n    for (let event of events) {\n      if (event === CHILDREN) {\n        if (node2.nodes) {\n          node2.each((child) => {\n            if (!child[isClean]) this.walkSync(child);\n          });\n        }\n      } else {\n        let visitors = this.listeners[event];\n        if (visitors) {\n          if (this.visitSync(visitors, node2.toProxy())) return;\n        }\n      }\n    }\n  }\n  warnings() {\n    return this.sync().warnings();\n  }\n  get content() {\n    return this.stringify().content;\n  }\n  get css() {\n    return this.stringify().css;\n  }\n  get map() {\n    return this.stringify().map;\n  }\n  get messages() {\n    return this.sync().messages;\n  }\n  get opts() {\n    return this.result.opts;\n  }\n  get processor() {\n    return this.result.processor;\n  }\n  get root() {\n    return this.sync().root;\n  }\n  get [Symbol.toStringTag]() {\n    return \"LazyResult\";\n  }\n};\nLazyResult$2.registerPostcss = (dependant) => {\n  postcss$2 = dependant;\n};\nvar lazyResult = LazyResult$2;\nLazyResult$2.default = LazyResult$2;\nRoot$3.registerLazyResult(LazyResult$2);\nDocument$2.registerLazyResult(LazyResult$2);\nlet MapGenerator2 = mapGenerator;\nlet stringify$1 = stringify_1;\nlet warnOnce2 = warnOnce$2;\nlet parse$1 = parse_1;\nconst Result$1 = result;\nlet NoWorkResult$1 = class NoWorkResult {\n  constructor(processor2, css, opts) {\n    css = css.toString();\n    this.stringified = false;\n    this._processor = processor2;\n    this._css = css;\n    this._opts = opts;\n    this._map = void 0;\n    let root2;\n    let str = stringify$1;\n    this.result = new Result$1(this._processor, root2, this._opts);\n    this.result.css = css;\n    let self = this;\n    Object.defineProperty(this.result, \"root\", {\n      get() {\n        return self.root;\n      }\n    });\n    let map = new MapGenerator2(str, root2, this._opts, css);\n    if (map.isMap()) {\n      let [generatedCSS, generatedMap] = map.generate();\n      if (generatedCSS) {\n        this.result.css = generatedCSS;\n      }\n      if (generatedMap) {\n        this.result.map = generatedMap;\n      }\n    } else {\n      map.clearAnnotation();\n      this.result.css = map.css;\n    }\n  }\n  async() {\n    if (this.error) return Promise.reject(this.error);\n    return Promise.resolve(this.result);\n  }\n  catch(onRejected) {\n    return this.async().catch(onRejected);\n  }\n  finally(onFinally) {\n    return this.async().then(onFinally, onFinally);\n  }\n  sync() {\n    if (this.error) throw this.error;\n    return this.result;\n  }\n  then(onFulfilled, onRejected) {\n    if (process.env.NODE_ENV !== \"production\") {\n      if (!(\"from\" in this._opts)) {\n        warnOnce2(\n          \"Without `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning.\"\n        );\n      }\n    }\n    return this.async().then(onFulfilled, onRejected);\n  }\n  toString() {\n    return this._css;\n  }\n  warnings() {\n    return [];\n  }\n  get content() {\n    return this.result.css;\n  }\n  get css() {\n    return this.result.css;\n  }\n  get map() {\n    return this.result.map;\n  }\n  get messages() {\n    return [];\n  }\n  get opts() {\n    return this.result.opts;\n  }\n  get processor() {\n    return this.result.processor;\n  }\n  get root() {\n    if (this._root) {\n      return this._root;\n    }\n    let root2;\n    let parser2 = parse$1;\n    try {\n      root2 = parser2(this._css, this._opts);\n    } catch (error) {\n      this.error = error;\n    }\n    if (this.error) {\n      throw this.error;\n    } else {\n      this._root = root2;\n      return root2;\n    }\n  }\n  get [Symbol.toStringTag]() {\n    return \"NoWorkResult\";\n  }\n};\nvar noWorkResult = NoWorkResult$1;\nNoWorkResult$1.default = NoWorkResult$1;\nlet NoWorkResult2 = noWorkResult;\nlet LazyResult$1 = lazyResult;\nlet Document$1 = document$1;\nlet Root$2 = root;\nlet Processor$1 = class Processor {\n  constructor(plugins = []) {\n    this.version = \"8.4.38\";\n    this.plugins = this.normalize(plugins);\n  }\n  normalize(plugins) {\n    let normalized = [];\n    for (let i of plugins) {\n      if (i.postcss === true) {\n        i = i();\n      } else if (i.postcss) {\n        i = i.postcss;\n      }\n      if (typeof i === \"object\" && Array.isArray(i.plugins)) {\n        normalized = normalized.concat(i.plugins);\n      } else if (typeof i === \"object\" && i.postcssPlugin) {\n        normalized.push(i);\n      } else if (typeof i === \"function\") {\n        normalized.push(i);\n      } else if (typeof i === \"object\" && (i.parse || i.stringify)) {\n        if (process.env.NODE_ENV !== \"production\") {\n          throw new Error(\n            \"PostCSS syntaxes cannot be used as plugins. Instead, please use one of the syntax/parser/stringifier options as outlined in your PostCSS runner documentation.\"\n          );\n        }\n      } else {\n        throw new Error(i + \" is not a PostCSS plugin\");\n      }\n    }\n    return normalized;\n  }\n  process(css, opts = {}) {\n    if (!this.plugins.length && !opts.parser && !opts.stringifier && !opts.syntax) {\n      return new NoWorkResult2(this, css, opts);\n    } else {\n      return new LazyResult$1(this, css, opts);\n    }\n  }\n  use(plugin2) {\n    this.plugins = this.plugins.concat(this.normalize([plugin2]));\n    return this;\n  }\n};\nvar processor = Processor$1;\nProcessor$1.default = Processor$1;\nRoot$2.registerProcessor(Processor$1);\nDocument$1.registerProcessor(Processor$1);\nlet Declaration$1 = declaration;\nlet PreviousMap2 = previousMap;\nlet Comment$1 = comment;\nlet AtRule$1 = atRule;\nlet Input$1 = input;\nlet Root$1 = root;\nlet Rule$1 = rule;\nfunction fromJSON$1(json, inputs) {\n  if (Array.isArray(json)) return json.map((n) => fromJSON$1(n));\n  let { inputs: ownInputs, ...defaults } = json;\n  if (ownInputs) {\n    inputs = [];\n    for (let input2 of ownInputs) {\n      let inputHydrated = { ...input2, __proto__: Input$1.prototype };\n      if (inputHydrated.map) {\n        inputHydrated.map = {\n          ...inputHydrated.map,\n          __proto__: PreviousMap2.prototype\n        };\n      }\n      inputs.push(inputHydrated);\n    }\n  }\n  if (defaults.nodes) {\n    defaults.nodes = json.nodes.map((n) => fromJSON$1(n, inputs));\n  }\n  if (defaults.source) {\n    let { inputId, ...source } = defaults.source;\n    defaults.source = source;\n    if (inputId != null) {\n      defaults.source.input = inputs[inputId];\n    }\n  }\n  if (defaults.type === \"root\") {\n    return new Root$1(defaults);\n  } else if (defaults.type === \"decl\") {\n    return new Declaration$1(defaults);\n  } else if (defaults.type === \"rule\") {\n    return new Rule$1(defaults);\n  } else if (defaults.type === \"comment\") {\n    return new Comment$1(defaults);\n  } else if (defaults.type === \"atrule\") {\n    return new AtRule$1(defaults);\n  } else {\n    throw new Error(\"Unknown node type: \" + json.type);\n  }\n}\nvar fromJSON_1 = fromJSON$1;\nfromJSON$1.default = fromJSON$1;\nlet CssSyntaxError2 = cssSyntaxError;\nlet Declaration2 = declaration;\nlet LazyResult2 = lazyResult;\nlet Container2 = container;\nlet Processor2 = processor;\nlet stringify = stringify_1;\nlet fromJSON = fromJSON_1;\nlet Document22 = document$1;\nlet Warning2 = warning;\nlet Comment2 = comment;\nlet AtRule2 = atRule;\nlet Result2 = result;\nlet Input2 = input;\nlet parse = parse_1;\nlet list = list_1;\nlet Rule2 = rule;\nlet Root2 = root;\nlet Node2 = node;\nfunction postcss(...plugins) {\n  if (plugins.length === 1 && Array.isArray(plugins[0])) {\n    plugins = plugins[0];\n  }\n  return new Processor2(plugins);\n}\npostcss.plugin = function plugin(name, initializer) {\n  let warningPrinted = false;\n  function creator(...args) {\n    if (console && console.warn && !warningPrinted) {\n      warningPrinted = true;\n      console.warn(\n        name + \": postcss.plugin was deprecated. Migration guide:\\nhttps://evilmartians.com/chronicles/postcss-8-plugin-migration\"\n      );\n      if (process.env.LANG && process.env.LANG.startsWith(\"cn\")) {\n        console.warn(\n          name + \": 里面 postcss.plugin 被弃用. 迁移指南:\\nhttps://www.w3ctech.com/topic/2226\"\n        );\n      }\n    }\n    let transformer = initializer(...args);\n    transformer.postcssPlugin = name;\n    transformer.postcssVersion = new Processor2().version;\n    return transformer;\n  }\n  let cache;\n  Object.defineProperty(creator, \"postcss\", {\n    get() {\n      if (!cache) cache = creator();\n      return cache;\n    }\n  });\n  creator.process = function(css, processOpts, pluginOpts) {\n    return postcss([creator(pluginOpts)]).process(css, processOpts);\n  };\n  return creator;\n};\npostcss.stringify = stringify;\npostcss.parse = parse;\npostcss.fromJSON = fromJSON;\npostcss.list = list;\npostcss.comment = (defaults) => new Comment2(defaults);\npostcss.atRule = (defaults) => new AtRule2(defaults);\npostcss.decl = (defaults) => new Declaration2(defaults);\npostcss.rule = (defaults) => new Rule2(defaults);\npostcss.root = (defaults) => new Root2(defaults);\npostcss.document = (defaults) => new Document22(defaults);\npostcss.CssSyntaxError = CssSyntaxError2;\npostcss.Declaration = Declaration2;\npostcss.Container = Container2;\npostcss.Processor = Processor2;\npostcss.Document = Document22;\npostcss.Comment = Comment2;\npostcss.Warning = Warning2;\npostcss.AtRule = AtRule2;\npostcss.Result = Result2;\npostcss.Input = Input2;\npostcss.Rule = Rule2;\npostcss.Root = Root2;\npostcss.Node = Node2;\nLazyResult2.registerPostcss(postcss);\nvar postcss_1 = postcss;\npostcss.default = postcss;\nconst postcss$1 = /* @__PURE__ */ getDefaultExportFromCjs(postcss_1);\npostcss$1.stringify;\npostcss$1.fromJSON;\npostcss$1.plugin;\npostcss$1.parse;\npostcss$1.list;\npostcss$1.document;\npostcss$1.comment;\npostcss$1.atRule;\npostcss$1.rule;\npostcss$1.decl;\npostcss$1.root;\npostcss$1.CssSyntaxError;\npostcss$1.Declaration;\npostcss$1.Container;\npostcss$1.Processor;\npostcss$1.Document;\npostcss$1.Comment;\npostcss$1.Warning;\npostcss$1.AtRule;\npostcss$1.Result;\npostcss$1.Input;\npostcss$1.Rule;\npostcss$1.Root;\npostcss$1.Node;\nvar NodeType$1 = /* @__PURE__ */ ((NodeType2) => {\n  NodeType2[NodeType2[\"Document\"] = 0] = \"Document\";\n  NodeType2[NodeType2[\"DocumentType\"] = 1] = \"DocumentType\";\n  NodeType2[NodeType2[\"Element\"] = 2] = \"Element\";\n  NodeType2[NodeType2[\"Text\"] = 3] = \"Text\";\n  NodeType2[NodeType2[\"CDATA\"] = 4] = \"CDATA\";\n  NodeType2[NodeType2[\"Comment\"] = 5] = \"Comment\";\n  return NodeType2;\n})(NodeType$1 || {});\nfunction parseCSSText(cssText) {\n  const res = {};\n  const listDelimiter = /;(?![^(]*\\))/g;\n  const propertyDelimiter = /:(.+)/;\n  const comment2 = /\\/\\*.*?\\*\\//g;\n  cssText.replace(comment2, \"\").split(listDelimiter).forEach(function(item) {\n    if (item) {\n      const tmp = item.split(propertyDelimiter);\n      tmp.length > 1 && (res[camelize(tmp[0].trim())] = tmp[1].trim());\n    }\n  });\n  return res;\n}\nfunction toCSSText(style) {\n  const properties = [];\n  for (const name in style) {\n    const value = style[name];\n    if (typeof value !== \"string\") continue;\n    const normalizedName = hyphenate(name);\n    properties.push(`${normalizedName}: ${value};`);\n  }\n  return properties.join(\" \");\n}\nconst camelizeRE = /-([a-z])/g;\nconst CUSTOM_PROPERTY_REGEX = /^--[a-zA-Z0-9-]+$/;\nconst camelize = (str) => {\n  if (CUSTOM_PROPERTY_REGEX.test(str)) return str;\n  return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : \"\");\n};\nconst hyphenateRE = /\\B([A-Z])/g;\nconst hyphenate = (str) => {\n  return str.replace(hyphenateRE, \"-$1\").toLowerCase();\n};\nclass BaseRRNode {\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any\n  constructor(..._args) {\n    __publicField(this, \"parentElement\", null);\n    __publicField(this, \"parentNode\", null);\n    __publicField(this, \"ownerDocument\");\n    __publicField(this, \"firstChild\", null);\n    __publicField(this, \"lastChild\", null);\n    __publicField(this, \"previousSibling\", null);\n    __publicField(this, \"nextSibling\", null);\n    __publicField(this, \"ELEMENT_NODE\", 1);\n    __publicField(this, \"TEXT_NODE\", 3);\n    // corresponding nodeType value of standard HTML Node\n    __publicField(this, \"nodeType\");\n    __publicField(this, \"nodeName\");\n    __publicField(this, \"RRNodeType\");\n  }\n  get childNodes() {\n    const childNodes = [];\n    let childIterator = this.firstChild;\n    while (childIterator) {\n      childNodes.push(childIterator);\n      childIterator = childIterator.nextSibling;\n    }\n    return childNodes;\n  }\n  contains(node2) {\n    if (!(node2 instanceof BaseRRNode)) return false;\n    else if (node2.ownerDocument !== this.ownerDocument) return false;\n    else if (node2 === this) return true;\n    while (node2.parentNode) {\n      if (node2.parentNode === this) return true;\n      node2 = node2.parentNode;\n    }\n    return false;\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  appendChild(_newChild) {\n    throw new Error(\n      `RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`\n    );\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  insertBefore(_newChild, _refChild) {\n    throw new Error(\n      `RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`\n    );\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  removeChild(_node) {\n    throw new Error(\n      `RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`\n    );\n  }\n  toString() {\n    return \"RRNode\";\n  }\n}\nclass BaseRRDocument extends BaseRRNode {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  constructor(...args) {\n    super(args);\n    __publicField(this, \"nodeType\", 9);\n    __publicField(this, \"nodeName\", \"#document\");\n    __publicField(this, \"compatMode\", \"CSS1Compat\");\n    __publicField(this, \"RRNodeType\", NodeType$1.Document);\n    __publicField(this, \"textContent\", null);\n    this.ownerDocument = this;\n  }\n  get documentElement() {\n    return this.childNodes.find(\n      (node2) => node2.RRNodeType === NodeType$1.Element && node2.tagName === \"HTML\"\n    ) || null;\n  }\n  get body() {\n    var _a;\n    return ((_a = this.documentElement) == null ? void 0 : _a.childNodes.find(\n      (node2) => node2.RRNodeType === NodeType$1.Element && node2.tagName === \"BODY\"\n    )) || null;\n  }\n  get head() {\n    var _a;\n    return ((_a = this.documentElement) == null ? void 0 : _a.childNodes.find(\n      (node2) => node2.RRNodeType === NodeType$1.Element && node2.tagName === \"HEAD\"\n    )) || null;\n  }\n  get implementation() {\n    return this;\n  }\n  get firstElementChild() {\n    return this.documentElement;\n  }\n  appendChild(newChild) {\n    const nodeType = newChild.RRNodeType;\n    if (nodeType === NodeType$1.Element || nodeType === NodeType$1.DocumentType) {\n      if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {\n        throw new Error(\n          `RRDomException: Failed to execute 'appendChild' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? \"RRElement\" : \"RRDoctype\"} on RRDocument allowed.`\n        );\n      }\n    }\n    const child = appendChild(this, newChild);\n    child.parentElement = null;\n    return child;\n  }\n  insertBefore(newChild, refChild) {\n    const nodeType = newChild.RRNodeType;\n    if (nodeType === NodeType$1.Element || nodeType === NodeType$1.DocumentType) {\n      if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {\n        throw new Error(\n          `RRDomException: Failed to execute 'insertBefore' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? \"RRElement\" : \"RRDoctype\"} on RRDocument allowed.`\n        );\n      }\n    }\n    const child = insertBefore(this, newChild, refChild);\n    child.parentElement = null;\n    return child;\n  }\n  removeChild(node2) {\n    return removeChild(this, node2);\n  }\n  open() {\n    this.firstChild = null;\n    this.lastChild = null;\n  }\n  close() {\n  }\n  /**\n   * Adhoc implementation for setting xhtml namespace in rebuilt.ts (rrweb-snapshot).\n   * There are two lines used this function:\n   * 1. doc.write('\\<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\"\\>')\n   * 2. doc.write('\\<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\"\\>')\n   */\n  write(content) {\n    let publicId;\n    if (content === '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\">')\n      publicId = \"-//W3C//DTD XHTML 1.0 Transitional//EN\";\n    else if (content === '<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\">')\n      publicId = \"-//W3C//DTD HTML 4.0 Transitional//EN\";\n    if (publicId) {\n      const doctype = this.createDocumentType(\"html\", publicId, \"\");\n      this.open();\n      this.appendChild(doctype);\n    }\n  }\n  createDocument(_namespace, _qualifiedName, _doctype) {\n    return new BaseRRDocument();\n  }\n  createDocumentType(qualifiedName, publicId, systemId) {\n    const doctype = new BaseRRDocumentType(qualifiedName, publicId, systemId);\n    doctype.ownerDocument = this;\n    return doctype;\n  }\n  createElement(tagName) {\n    const element = new BaseRRElement(tagName);\n    element.ownerDocument = this;\n    return element;\n  }\n  createElementNS(_namespaceURI, qualifiedName) {\n    return this.createElement(qualifiedName);\n  }\n  createTextNode(data) {\n    const text = new BaseRRText(data);\n    text.ownerDocument = this;\n    return text;\n  }\n  createComment(data) {\n    const comment2 = new BaseRRComment(data);\n    comment2.ownerDocument = this;\n    return comment2;\n  }\n  createCDATASection(data) {\n    const CDATASection = new BaseRRCDATASection(data);\n    CDATASection.ownerDocument = this;\n    return CDATASection;\n  }\n  toString() {\n    return \"RRDocument\";\n  }\n}\nclass BaseRRDocumentType extends BaseRRNode {\n  constructor(qualifiedName, publicId, systemId) {\n    super();\n    __publicField(this, \"nodeType\", 10);\n    __publicField(this, \"RRNodeType\", NodeType$1.DocumentType);\n    __publicField(this, \"name\");\n    __publicField(this, \"publicId\");\n    __publicField(this, \"systemId\");\n    __publicField(this, \"textContent\", null);\n    this.name = qualifiedName;\n    this.publicId = publicId;\n    this.systemId = systemId;\n    this.nodeName = qualifiedName;\n  }\n  toString() {\n    return \"RRDocumentType\";\n  }\n}\nclass BaseRRElement extends BaseRRNode {\n  constructor(tagName) {\n    super();\n    __publicField(this, \"nodeType\", 1);\n    __publicField(this, \"RRNodeType\", NodeType$1.Element);\n    __publicField(this, \"tagName\");\n    __publicField(this, \"attributes\", {});\n    __publicField(this, \"shadowRoot\", null);\n    __publicField(this, \"scrollLeft\");\n    __publicField(this, \"scrollTop\");\n    this.tagName = tagName.toUpperCase();\n    this.nodeName = tagName.toUpperCase();\n  }\n  get textContent() {\n    let result2 = \"\";\n    this.childNodes.forEach((node2) => result2 += node2.textContent);\n    return result2;\n  }\n  set textContent(textContent) {\n    this.firstChild = null;\n    this.lastChild = null;\n    this.appendChild(this.ownerDocument.createTextNode(textContent));\n  }\n  get classList() {\n    return new ClassList(\n      this.attributes.class,\n      (newClassName) => {\n        this.attributes.class = newClassName;\n      }\n    );\n  }\n  get id() {\n    return this.attributes.id || \"\";\n  }\n  get className() {\n    return this.attributes.class || \"\";\n  }\n  get style() {\n    const style = this.attributes.style ? parseCSSText(this.attributes.style) : {};\n    const hyphenateRE2 = /\\B([A-Z])/g;\n    style.setProperty = (name, value, priority) => {\n      if (hyphenateRE2.test(name)) return;\n      const normalizedName = camelize(name);\n      if (!value) delete style[normalizedName];\n      else style[normalizedName] = value;\n      if (priority === \"important\") style[normalizedName] += \" !important\";\n      this.attributes.style = toCSSText(style);\n    };\n    style.removeProperty = (name) => {\n      if (hyphenateRE2.test(name)) return \"\";\n      const normalizedName = camelize(name);\n      const value = style[normalizedName] || \"\";\n      delete style[normalizedName];\n      this.attributes.style = toCSSText(style);\n      return value;\n    };\n    return style;\n  }\n  getAttribute(name) {\n    if (this.attributes[name] === void 0) return null;\n    return this.attributes[name];\n  }\n  setAttribute(name, attribute) {\n    this.attributes[name] = attribute;\n  }\n  setAttributeNS(_namespace, qualifiedName, value) {\n    this.setAttribute(qualifiedName, value);\n  }\n  removeAttribute(name) {\n    delete this.attributes[name];\n  }\n  appendChild(newChild) {\n    return appendChild(this, newChild);\n  }\n  insertBefore(newChild, refChild) {\n    return insertBefore(this, newChild, refChild);\n  }\n  removeChild(node2) {\n    return removeChild(this, node2);\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  attachShadow(_init) {\n    const shadowRoot = this.ownerDocument.createElement(\"SHADOWROOT\");\n    this.shadowRoot = shadowRoot;\n    return shadowRoot;\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  dispatchEvent(_event) {\n    return true;\n  }\n  toString() {\n    let attributeString = \"\";\n    for (const attribute in this.attributes) {\n      attributeString += `${attribute}=\"${this.attributes[attribute]}\" `;\n    }\n    return `${this.tagName} ${attributeString}`;\n  }\n}\nclass BaseRRMediaElement extends BaseRRElement {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"currentTime\");\n    __publicField(this, \"volume\");\n    __publicField(this, \"paused\");\n    __publicField(this, \"muted\");\n    __publicField(this, \"playbackRate\");\n    __publicField(this, \"loop\");\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  attachShadow(_init) {\n    throw new Error(\n      `RRDomException: Failed to execute 'attachShadow' on 'RRElement': This RRElement does not support attachShadow`\n    );\n  }\n  play() {\n    this.paused = false;\n  }\n  pause() {\n    this.paused = true;\n  }\n}\nclass BaseRRDialogElement extends BaseRRElement {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"tagName\", \"DIALOG\");\n    __publicField(this, \"nodeName\", \"DIALOG\");\n  }\n  get isModal() {\n    return this.getAttribute(\"rr_open_mode\") === \"modal\";\n  }\n  get open() {\n    return this.getAttribute(\"open\") !== null;\n  }\n  close() {\n    this.removeAttribute(\"open\");\n    this.removeAttribute(\"rr_open_mode\");\n  }\n  show() {\n    this.setAttribute(\"open\", \"\");\n    this.setAttribute(\"rr_open_mode\", \"non-modal\");\n  }\n  showModal() {\n    this.setAttribute(\"open\", \"\");\n    this.setAttribute(\"rr_open_mode\", \"modal\");\n  }\n}\nclass BaseRRText extends BaseRRNode {\n  constructor(data) {\n    super();\n    __publicField(this, \"nodeType\", 3);\n    __publicField(this, \"nodeName\", \"#text\");\n    __publicField(this, \"RRNodeType\", NodeType$1.Text);\n    __publicField(this, \"data\");\n    this.data = data;\n  }\n  get textContent() {\n    return this.data;\n  }\n  set textContent(textContent) {\n    this.data = textContent;\n  }\n  toString() {\n    return `RRText text=${JSON.stringify(this.data)}`;\n  }\n}\nclass BaseRRComment extends BaseRRNode {\n  constructor(data) {\n    super();\n    __publicField(this, \"nodeType\", 8);\n    __publicField(this, \"nodeName\", \"#comment\");\n    __publicField(this, \"RRNodeType\", NodeType$1.Comment);\n    __publicField(this, \"data\");\n    this.data = data;\n  }\n  get textContent() {\n    return this.data;\n  }\n  set textContent(textContent) {\n    this.data = textContent;\n  }\n  toString() {\n    return `RRComment text=${JSON.stringify(this.data)}`;\n  }\n}\nclass BaseRRCDATASection extends BaseRRNode {\n  constructor(data) {\n    super();\n    __publicField(this, \"nodeName\", \"#cdata-section\");\n    __publicField(this, \"nodeType\", 4);\n    __publicField(this, \"RRNodeType\", NodeType$1.CDATA);\n    __publicField(this, \"data\");\n    this.data = data;\n  }\n  get textContent() {\n    return this.data;\n  }\n  set textContent(textContent) {\n    this.data = textContent;\n  }\n  toString() {\n    return `RRCDATASection data=${JSON.stringify(this.data)}`;\n  }\n}\nclass ClassList {\n  constructor(classText, onChange) {\n    __publicField(this, \"onChange\");\n    __publicField(this, \"classes\", []);\n    __publicField(this, \"add\", (...classNames) => {\n      for (const item of classNames) {\n        const className = String(item);\n        if (this.classes.indexOf(className) >= 0) continue;\n        this.classes.push(className);\n      }\n      this.onChange && this.onChange(this.classes.join(\" \"));\n    });\n    __publicField(this, \"remove\", (...classNames) => {\n      this.classes = this.classes.filter(\n        (item) => classNames.indexOf(item) === -1\n      );\n      this.onChange && this.onChange(this.classes.join(\" \"));\n    });\n    if (classText) {\n      const classes = classText.trim().split(/\\s+/);\n      this.classes.push(...classes);\n    }\n    this.onChange = onChange;\n  }\n}\nfunction appendChild(parent, newChild) {\n  if (newChild.parentNode) newChild.parentNode.removeChild(newChild);\n  if (parent.lastChild) {\n    parent.lastChild.nextSibling = newChild;\n    newChild.previousSibling = parent.lastChild;\n  } else {\n    parent.firstChild = newChild;\n    newChild.previousSibling = null;\n  }\n  parent.lastChild = newChild;\n  newChild.nextSibling = null;\n  newChild.parentNode = parent;\n  newChild.parentElement = parent;\n  newChild.ownerDocument = parent.ownerDocument;\n  return newChild;\n}\nfunction insertBefore(parent, newChild, refChild) {\n  if (!refChild) return appendChild(parent, newChild);\n  if (refChild.parentNode !== parent)\n    throw new Error(\n      \"Failed to execute 'insertBefore' on 'RRNode': The RRNode before which the new node is to be inserted is not a child of this RRNode.\"\n    );\n  if (newChild === refChild) return newChild;\n  if (newChild.parentNode) newChild.parentNode.removeChild(newChild);\n  newChild.previousSibling = refChild.previousSibling;\n  refChild.previousSibling = newChild;\n  newChild.nextSibling = refChild;\n  if (newChild.previousSibling) newChild.previousSibling.nextSibling = newChild;\n  else parent.firstChild = newChild;\n  newChild.parentElement = parent;\n  newChild.parentNode = parent;\n  newChild.ownerDocument = parent.ownerDocument;\n  return newChild;\n}\nfunction removeChild(parent, child) {\n  if (child.parentNode !== parent)\n    throw new Error(\n      \"Failed to execute 'removeChild' on 'RRNode': The RRNode to be removed is not a child of this RRNode.\"\n    );\n  if (child.previousSibling)\n    child.previousSibling.nextSibling = child.nextSibling;\n  else parent.firstChild = child.nextSibling;\n  if (child.nextSibling)\n    child.nextSibling.previousSibling = child.previousSibling;\n  else parent.lastChild = child.previousSibling;\n  child.previousSibling = null;\n  child.nextSibling = null;\n  child.parentElement = null;\n  child.parentNode = null;\n  return child;\n}\nvar NodeType = /* @__PURE__ */ ((NodeType2) => {\n  NodeType2[NodeType2[\"PLACEHOLDER\"] = 0] = \"PLACEHOLDER\";\n  NodeType2[NodeType2[\"ELEMENT_NODE\"] = 1] = \"ELEMENT_NODE\";\n  NodeType2[NodeType2[\"ATTRIBUTE_NODE\"] = 2] = \"ATTRIBUTE_NODE\";\n  NodeType2[NodeType2[\"TEXT_NODE\"] = 3] = \"TEXT_NODE\";\n  NodeType2[NodeType2[\"CDATA_SECTION_NODE\"] = 4] = \"CDATA_SECTION_NODE\";\n  NodeType2[NodeType2[\"ENTITY_REFERENCE_NODE\"] = 5] = \"ENTITY_REFERENCE_NODE\";\n  NodeType2[NodeType2[\"ENTITY_NODE\"] = 6] = \"ENTITY_NODE\";\n  NodeType2[NodeType2[\"PROCESSING_INSTRUCTION_NODE\"] = 7] = \"PROCESSING_INSTRUCTION_NODE\";\n  NodeType2[NodeType2[\"COMMENT_NODE\"] = 8] = \"COMMENT_NODE\";\n  NodeType2[NodeType2[\"DOCUMENT_NODE\"] = 9] = \"DOCUMENT_NODE\";\n  NodeType2[NodeType2[\"DOCUMENT_TYPE_NODE\"] = 10] = \"DOCUMENT_TYPE_NODE\";\n  NodeType2[NodeType2[\"DOCUMENT_FRAGMENT_NODE\"] = 11] = \"DOCUMENT_FRAGMENT_NODE\";\n  return NodeType2;\n})(NodeType || {});\nconst NAMESPACES = {\n  svg: \"http://www.w3.org/2000/svg\",\n  \"xlink:href\": \"http://www.w3.org/1999/xlink\",\n  xmlns: \"http://www.w3.org/2000/xmlns/\"\n};\nconst SVGTagMap = {\n  altglyph: \"altGlyph\",\n  altglyphdef: \"altGlyphDef\",\n  altglyphitem: \"altGlyphItem\",\n  animatecolor: \"animateColor\",\n  animatemotion: \"animateMotion\",\n  animatetransform: \"animateTransform\",\n  clippath: \"clipPath\",\n  feblend: \"feBlend\",\n  fecolormatrix: \"feColorMatrix\",\n  fecomponenttransfer: \"feComponentTransfer\",\n  fecomposite: \"feComposite\",\n  feconvolvematrix: \"feConvolveMatrix\",\n  fediffuselighting: \"feDiffuseLighting\",\n  fedisplacementmap: \"feDisplacementMap\",\n  fedistantlight: \"feDistantLight\",\n  fedropshadow: \"feDropShadow\",\n  feflood: \"feFlood\",\n  fefunca: \"feFuncA\",\n  fefuncb: \"feFuncB\",\n  fefuncg: \"feFuncG\",\n  fefuncr: \"feFuncR\",\n  fegaussianblur: \"feGaussianBlur\",\n  feimage: \"feImage\",\n  femerge: \"feMerge\",\n  femergenode: \"feMergeNode\",\n  femorphology: \"feMorphology\",\n  feoffset: \"feOffset\",\n  fepointlight: \"fePointLight\",\n  fespecularlighting: \"feSpecularLighting\",\n  fespotlight: \"feSpotLight\",\n  fetile: \"feTile\",\n  feturbulence: \"feTurbulence\",\n  foreignobject: \"foreignObject\",\n  glyphref: \"glyphRef\",\n  lineargradient: \"linearGradient\",\n  radialgradient: \"radialGradient\"\n};\nlet createdNodeSet = null;\nfunction diff(oldTree, newTree, replayer, rrnodeMirror = newTree.mirror || newTree.ownerDocument.mirror) {\n  oldTree = diffBeforeUpdatingChildren(\n    oldTree,\n    newTree,\n    replayer,\n    rrnodeMirror\n  );\n  diffChildren(oldTree, newTree, replayer, rrnodeMirror);\n  diffAfterUpdatingChildren(oldTree, newTree, replayer);\n}\nfunction diffBeforeUpdatingChildren(oldTree, newTree, replayer, rrnodeMirror) {\n  var _a;\n  if (replayer.afterAppend && !createdNodeSet) {\n    createdNodeSet = /* @__PURE__ */ new WeakSet();\n    setTimeout(() => {\n      createdNodeSet = null;\n    }, 0);\n  }\n  if (!sameNodeType(oldTree, newTree)) {\n    const calibratedOldTree = createOrGetNode(\n      newTree,\n      replayer.mirror,\n      rrnodeMirror\n    );\n    (_a = oldTree.parentNode) == null ? void 0 : _a.replaceChild(calibratedOldTree, oldTree);\n    oldTree = calibratedOldTree;\n  }\n  switch (newTree.RRNodeType) {\n    case NodeType$1.Document: {\n      if (!nodeMatching(oldTree, newTree, replayer.mirror, rrnodeMirror)) {\n        const newMeta = rrnodeMirror.getMeta(newTree);\n        if (newMeta) {\n          replayer.mirror.removeNodeFromMap(oldTree);\n          oldTree.close();\n          oldTree.open();\n          replayer.mirror.add(oldTree, newMeta);\n          createdNodeSet == null ? void 0 : createdNodeSet.add(oldTree);\n        }\n      }\n      break;\n    }\n    case NodeType$1.Element: {\n      const oldElement = oldTree;\n      const newRRElement = newTree;\n      switch (newRRElement.tagName) {\n        case \"IFRAME\": {\n          const oldContentDocument = oldTree.contentDocument;\n          if (!oldContentDocument) break;\n          diff(\n            oldContentDocument,\n            newTree.contentDocument,\n            replayer,\n            rrnodeMirror\n          );\n          break;\n        }\n      }\n      if (newRRElement.shadowRoot) {\n        if (!oldElement.shadowRoot) oldElement.attachShadow({ mode: \"open\" });\n        diffChildren(\n          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n          oldElement.shadowRoot,\n          newRRElement.shadowRoot,\n          replayer,\n          rrnodeMirror\n        );\n      }\n      diffProps(oldElement, newRRElement, rrnodeMirror);\n      break;\n    }\n  }\n  return oldTree;\n}\nfunction diffAfterUpdatingChildren(oldTree, newTree, replayer) {\n  var _a;\n  switch (newTree.RRNodeType) {\n    case NodeType$1.Document: {\n      const scrollData = newTree.scrollData;\n      scrollData && replayer.applyScroll(scrollData, true);\n      break;\n    }\n    case NodeType$1.Element: {\n      const oldElement = oldTree;\n      const newRRElement = newTree;\n      newRRElement.scrollData && replayer.applyScroll(newRRElement.scrollData, true);\n      newRRElement.inputData && replayer.applyInput(newRRElement.inputData);\n      switch (newRRElement.tagName) {\n        case \"AUDIO\":\n        case \"VIDEO\": {\n          const oldMediaElement = oldTree;\n          const newMediaRRElement = newRRElement;\n          if (newMediaRRElement.paused !== void 0)\n            newMediaRRElement.paused ? void oldMediaElement.pause() : void oldMediaElement.play();\n          if (newMediaRRElement.muted !== void 0)\n            oldMediaElement.muted = newMediaRRElement.muted;\n          if (newMediaRRElement.volume !== void 0)\n            oldMediaElement.volume = newMediaRRElement.volume;\n          if (newMediaRRElement.currentTime !== void 0)\n            oldMediaElement.currentTime = newMediaRRElement.currentTime;\n          if (newMediaRRElement.playbackRate !== void 0)\n            oldMediaElement.playbackRate = newMediaRRElement.playbackRate;\n          if (newMediaRRElement.loop !== void 0)\n            oldMediaElement.loop = newMediaRRElement.loop;\n          break;\n        }\n        case \"CANVAS\": {\n          const rrCanvasElement = newTree;\n          if (rrCanvasElement.rr_dataURL !== null) {\n            const image = document.createElement(\"img\");\n            image.onload = () => {\n              const ctx = oldElement.getContext(\"2d\");\n              if (ctx) {\n                ctx.drawImage(image, 0, 0, image.width, image.height);\n              }\n            };\n            image.src = rrCanvasElement.rr_dataURL;\n          }\n          rrCanvasElement.canvasMutations.forEach(\n            (canvasMutation) => replayer.applyCanvas(\n              canvasMutation.event,\n              canvasMutation.mutation,\n              oldTree\n            )\n          );\n          break;\n        }\n        case \"STYLE\": {\n          const styleSheet = oldElement.sheet;\n          styleSheet && newTree.rules.forEach(\n            (data) => replayer.applyStyleSheetMutation(data, styleSheet)\n          );\n          break;\n        }\n        case \"DIALOG\": {\n          const dialog = oldElement;\n          const rrDialog = newRRElement;\n          const wasOpen = dialog.open;\n          const wasModal = dialog.matches(\"dialog:modal\");\n          const shouldBeOpen = rrDialog.open;\n          const shouldBeModal = rrDialog.isModal;\n          const modalChanged = wasModal !== shouldBeModal;\n          const openChanged = wasOpen !== shouldBeOpen;\n          if (modalChanged || wasOpen && openChanged) dialog.close();\n          if (shouldBeOpen && (openChanged || modalChanged)) {\n            try {\n              if (shouldBeModal) dialog.showModal();\n              else dialog.show();\n            } catch (e) {\n              console.warn(e);\n            }\n          }\n          break;\n        }\n      }\n      break;\n    }\n    case NodeType$1.Text:\n    case NodeType$1.Comment:\n    case NodeType$1.CDATA: {\n      if (oldTree.textContent !== newTree.data)\n        oldTree.textContent = newTree.data;\n      break;\n    }\n  }\n  if (createdNodeSet == null ? void 0 : createdNodeSet.has(oldTree)) {\n    createdNodeSet.delete(oldTree);\n    (_a = replayer.afterAppend) == null ? void 0 : _a.call(replayer, oldTree, replayer.mirror.getId(oldTree));\n  }\n}\nfunction diffProps(oldTree, newTree, rrnodeMirror) {\n  const oldAttributes = oldTree.attributes;\n  const newAttributes = newTree.attributes;\n  for (const name in newAttributes) {\n    const newValue = newAttributes[name];\n    const sn = rrnodeMirror.getMeta(newTree);\n    if ((sn == null ? void 0 : sn.isSVG) && NAMESPACES[name])\n      oldTree.setAttributeNS(NAMESPACES[name], name, newValue);\n    else if (newTree.tagName === \"CANVAS\" && name === \"rr_dataURL\") {\n      const image = document.createElement(\"img\");\n      image.src = newValue;\n      image.onload = () => {\n        const ctx = oldTree.getContext(\"2d\");\n        if (ctx) {\n          ctx.drawImage(image, 0, 0, image.width, image.height);\n        }\n      };\n    } else if (newTree.tagName === \"IFRAME\" && name === \"srcdoc\") continue;\n    else {\n      try {\n        oldTree.setAttribute(name, newValue);\n      } catch (err) {\n        console.warn(err);\n      }\n    }\n  }\n  for (const { name } of Array.from(oldAttributes))\n    if (!(name in newAttributes)) oldTree.removeAttribute(name);\n  newTree.scrollLeft && (oldTree.scrollLeft = newTree.scrollLeft);\n  newTree.scrollTop && (oldTree.scrollTop = newTree.scrollTop);\n}\nfunction diffChildren(oldTree, newTree, replayer, rrnodeMirror) {\n  const oldChildren = Array.from(oldTree.childNodes);\n  const newChildren = newTree.childNodes;\n  if (oldChildren.length === 0 && newChildren.length === 0) return;\n  let oldStartIndex = 0, oldEndIndex = oldChildren.length - 1, newStartIndex = 0, newEndIndex = newChildren.length - 1;\n  let oldStartNode = oldChildren[oldStartIndex], oldEndNode = oldChildren[oldEndIndex], newStartNode = newChildren[newStartIndex], newEndNode = newChildren[newEndIndex];\n  let oldIdToIndex = void 0, indexInOld = void 0;\n  while (oldStartIndex <= oldEndIndex && newStartIndex <= newEndIndex) {\n    if (oldStartNode === void 0) {\n      oldStartNode = oldChildren[++oldStartIndex];\n    } else if (oldEndNode === void 0) {\n      oldEndNode = oldChildren[--oldEndIndex];\n    } else if (\n      // same first node?\n      nodeMatching(oldStartNode, newStartNode, replayer.mirror, rrnodeMirror)\n    ) {\n      oldStartNode = oldChildren[++oldStartIndex];\n      newStartNode = newChildren[++newStartIndex];\n    } else if (\n      // same last node?\n      nodeMatching(oldEndNode, newEndNode, replayer.mirror, rrnodeMirror)\n    ) {\n      oldEndNode = oldChildren[--oldEndIndex];\n      newEndNode = newChildren[--newEndIndex];\n    } else if (\n      // is the first old node the same as the last new node?\n      nodeMatching(oldStartNode, newEndNode, replayer.mirror, rrnodeMirror)\n    ) {\n      try {\n        oldTree.insertBefore(oldStartNode, oldEndNode.nextSibling);\n      } catch (e) {\n        console.warn(e);\n      }\n      oldStartNode = oldChildren[++oldStartIndex];\n      newEndNode = newChildren[--newEndIndex];\n    } else if (\n      // is the last old node the same as the first new node?\n      nodeMatching(oldEndNode, newStartNode, replayer.mirror, rrnodeMirror)\n    ) {\n      try {\n        oldTree.insertBefore(oldEndNode, oldStartNode);\n      } catch (e) {\n        console.warn(e);\n      }\n      oldEndNode = oldChildren[--oldEndIndex];\n      newStartNode = newChildren[++newStartIndex];\n    } else {\n      if (!oldIdToIndex) {\n        oldIdToIndex = {};\n        for (let i = oldStartIndex; i <= oldEndIndex; i++) {\n          const oldChild2 = oldChildren[i];\n          if (oldChild2 && replayer.mirror.hasNode(oldChild2))\n            oldIdToIndex[replayer.mirror.getId(oldChild2)] = i;\n        }\n      }\n      indexInOld = oldIdToIndex[rrnodeMirror.getId(newStartNode)];\n      const nodeToMove = oldChildren[indexInOld];\n      if (indexInOld !== void 0 && nodeToMove && nodeMatching(nodeToMove, newStartNode, replayer.mirror, rrnodeMirror)) {\n        try {\n          oldTree.insertBefore(nodeToMove, oldStartNode);\n        } catch (e) {\n          console.warn(e);\n        }\n        oldChildren[indexInOld] = void 0;\n      } else {\n        const newNode = createOrGetNode(\n          newStartNode,\n          replayer.mirror,\n          rrnodeMirror\n        );\n        if (oldTree.nodeName === \"#document\" && oldStartNode && /**\n        * Special case 1: one document isn't allowed to have two doctype nodes at the same time, so we need to remove the old one first before inserting the new one.\n        * How this case happens: A parent document in the old tree already has a doctype node with an id e.g. #1. A new full snapshot rebuilds the replayer with a new doctype node with another id #2. According to the algorithm, the new doctype node will be inserted before the old one, which is not allowed by the Document standard.\n        */\n        (newNode.nodeType === newNode.DOCUMENT_TYPE_NODE && oldStartNode.nodeType === oldStartNode.DOCUMENT_TYPE_NODE || /**\n        * Special case 2: one document isn't allowed to have two HTMLElements at the same time, so we need to remove the old one first before inserting the new one.\n        * How this case happens: A mounted iframe element has an automatically created HTML element. We should delete it before inserting a serialized one. Otherwise, an error 'Only one element on document allowed' will be thrown.\n        */\n        newNode.nodeType === newNode.ELEMENT_NODE && oldStartNode.nodeType === oldStartNode.ELEMENT_NODE)) {\n          oldTree.removeChild(oldStartNode);\n          replayer.mirror.removeNodeFromMap(oldStartNode);\n          oldStartNode = oldChildren[++oldStartIndex];\n        }\n        try {\n          oldTree.insertBefore(newNode, oldStartNode || null);\n        } catch (e) {\n          console.warn(e);\n        }\n      }\n      newStartNode = newChildren[++newStartIndex];\n    }\n  }\n  if (oldStartIndex > oldEndIndex) {\n    const referenceRRNode = newChildren[newEndIndex + 1];\n    let referenceNode = null;\n    if (referenceRRNode)\n      referenceNode = replayer.mirror.getNode(\n        rrnodeMirror.getId(referenceRRNode)\n      );\n    for (; newStartIndex <= newEndIndex; ++newStartIndex) {\n      const newNode = createOrGetNode(\n        newChildren[newStartIndex],\n        replayer.mirror,\n        rrnodeMirror\n      );\n      try {\n        oldTree.insertBefore(newNode, referenceNode);\n      } catch (e) {\n        console.warn(e);\n      }\n    }\n  } else if (newStartIndex > newEndIndex) {\n    for (; oldStartIndex <= oldEndIndex; oldStartIndex++) {\n      const node2 = oldChildren[oldStartIndex];\n      if (!node2 || node2.parentNode !== oldTree) continue;\n      try {\n        oldTree.removeChild(node2);\n        replayer.mirror.removeNodeFromMap(node2);\n      } catch (e) {\n        console.warn(e);\n      }\n    }\n  }\n  let oldChild = oldTree.firstChild;\n  let newChild = newTree.firstChild;\n  while (oldChild !== null && newChild !== null) {\n    diff(oldChild, newChild, replayer, rrnodeMirror);\n    oldChild = oldChild.nextSibling;\n    newChild = newChild.nextSibling;\n  }\n}\nfunction createOrGetNode(rrNode, domMirror, rrnodeMirror) {\n  const nodeId = rrnodeMirror.getId(rrNode);\n  const sn = rrnodeMirror.getMeta(rrNode);\n  let node2 = null;\n  if (nodeId > -1) node2 = domMirror.getNode(nodeId);\n  if (node2 !== null && sameNodeType(node2, rrNode)) return node2;\n  switch (rrNode.RRNodeType) {\n    case NodeType$1.Document:\n      node2 = new Document();\n      break;\n    case NodeType$1.DocumentType:\n      node2 = document.implementation.createDocumentType(\n        rrNode.name,\n        rrNode.publicId,\n        rrNode.systemId\n      );\n      break;\n    case NodeType$1.Element: {\n      let tagName = rrNode.tagName.toLowerCase();\n      tagName = SVGTagMap[tagName] || tagName;\n      if (sn && \"isSVG\" in sn && (sn == null ? void 0 : sn.isSVG)) {\n        node2 = document.createElementNS(NAMESPACES[\"svg\"], tagName);\n      } else node2 = document.createElement(rrNode.tagName);\n      break;\n    }\n    case NodeType$1.Text:\n      node2 = document.createTextNode(rrNode.data);\n      break;\n    case NodeType$1.Comment:\n      node2 = document.createComment(rrNode.data);\n      break;\n    case NodeType$1.CDATA:\n      node2 = document.createCDATASection(rrNode.data);\n      break;\n  }\n  if (sn) domMirror.add(node2, { ...sn });\n  try {\n    createdNodeSet == null ? void 0 : createdNodeSet.add(node2);\n  } catch (e) {\n  }\n  return node2;\n}\nfunction sameNodeType(node1, node2) {\n  if (node1.nodeType !== node2.nodeType) return false;\n  return node1.nodeType !== node1.ELEMENT_NODE || node1.tagName.toUpperCase() === node2.tagName;\n}\nfunction nodeMatching(node1, node2, domMirror, rrdomMirror) {\n  const node1Id = domMirror.getId(node1);\n  const node2Id = rrdomMirror.getId(node2);\n  if (node1Id === -1 || node1Id !== node2Id) return false;\n  return sameNodeType(node1, node2);\n}\nclass RRDocument extends BaseRRDocument {\n  constructor(mirror) {\n    super();\n    __publicField(this, \"UNSERIALIZED_STARTING_ID\", -2);\n    // In the rrweb replayer, there are some unserialized nodes like the element that stores the injected style rules.\n    // These unserialized nodes may interfere the execution of the diff algorithm.\n    // The id of serialized node is larger than 0. So this value less than 0 is used as id for these unserialized nodes.\n    __publicField(this, \"_unserializedId\", this.UNSERIALIZED_STARTING_ID);\n    __publicField(this, \"mirror\", createMirror());\n    __publicField(this, \"scrollData\", null);\n    if (mirror) {\n      this.mirror = mirror;\n    }\n  }\n  /**\n   * Every time the id is used, it will minus 1 automatically to avoid collisions.\n   */\n  get unserializedId() {\n    return this._unserializedId--;\n  }\n  createDocument(_namespace, _qualifiedName, _doctype) {\n    return new RRDocument();\n  }\n  createDocumentType(qualifiedName, publicId, systemId) {\n    const documentTypeNode = new RRDocumentType(\n      qualifiedName,\n      publicId,\n      systemId\n    );\n    documentTypeNode.ownerDocument = this;\n    return documentTypeNode;\n  }\n  createElement(tagName) {\n    const upperTagName = tagName.toUpperCase();\n    let element;\n    switch (upperTagName) {\n      case \"AUDIO\":\n      case \"VIDEO\":\n        element = new RRMediaElement(upperTagName);\n        break;\n      case \"IFRAME\":\n        element = new RRIFrameElement(upperTagName, this.mirror);\n        break;\n      case \"CANVAS\":\n        element = new RRCanvasElement(upperTagName);\n        break;\n      case \"STYLE\":\n        element = new RRStyleElement(upperTagName);\n        break;\n      case \"DIALOG\":\n        element = new RRDialogElement(upperTagName);\n        break;\n      default:\n        element = new RRElement(upperTagName);\n        break;\n    }\n    element.ownerDocument = this;\n    return element;\n  }\n  createComment(data) {\n    const commentNode = new RRComment(data);\n    commentNode.ownerDocument = this;\n    return commentNode;\n  }\n  createCDATASection(data) {\n    const sectionNode = new RRCDATASection(data);\n    sectionNode.ownerDocument = this;\n    return sectionNode;\n  }\n  createTextNode(data) {\n    const textNode = new RRText(data);\n    textNode.ownerDocument = this;\n    return textNode;\n  }\n  destroyTree() {\n    this.firstChild = null;\n    this.lastChild = null;\n    this.mirror.reset();\n  }\n  open() {\n    super.open();\n    this._unserializedId = this.UNSERIALIZED_STARTING_ID;\n  }\n}\nconst RRDocumentType = BaseRRDocumentType;\nclass RRElement extends BaseRRElement {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"inputData\", null);\n    __publicField(this, \"scrollData\", null);\n  }\n}\nclass RRMediaElement extends BaseRRMediaElement {\n}\nclass RRDialogElement extends BaseRRDialogElement {\n}\nclass RRCanvasElement extends RRElement {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"rr_dataURL\", null);\n    __publicField(this, \"canvasMutations\", []);\n  }\n  /**\n   * This is a dummy implementation to distinguish RRCanvasElement from real HTMLCanvasElement.\n   */\n  getContext() {\n    return null;\n  }\n}\nclass RRStyleElement extends RRElement {\n  constructor() {\n    super(...arguments);\n    __publicField(this, \"rules\", []);\n  }\n}\nclass RRIFrameElement extends RRElement {\n  constructor(upperTagName, mirror) {\n    super(upperTagName);\n    __publicField(this, \"contentDocument\", new RRDocument());\n    this.contentDocument.mirror = mirror;\n  }\n}\nconst RRText = BaseRRText;\nconst RRComment = BaseRRComment;\nconst RRCDATASection = BaseRRCDATASection;\nfunction getValidTagName(element) {\n  if (element instanceof HTMLFormElement) {\n    return \"FORM\";\n  }\n  return element.tagName.toUpperCase();\n}\nfunction buildFromNode(node2, rrdom, domMirror, parentRRNode) {\n  let rrNode;\n  switch (node2.nodeType) {\n    case NodeType.DOCUMENT_NODE:\n      if (parentRRNode && parentRRNode.nodeName === \"IFRAME\")\n        rrNode = parentRRNode.contentDocument;\n      else {\n        rrNode = rrdom;\n        rrNode.compatMode = node2.compatMode;\n      }\n      break;\n    case NodeType.DOCUMENT_TYPE_NODE: {\n      const documentType = node2;\n      rrNode = rrdom.createDocumentType(\n        documentType.name,\n        documentType.publicId,\n        documentType.systemId\n      );\n      break;\n    }\n    case NodeType.ELEMENT_NODE: {\n      const elementNode = node2;\n      const tagName = getValidTagName(elementNode);\n      rrNode = rrdom.createElement(tagName);\n      const rrElement = rrNode;\n      for (const { name, value } of Array.from(elementNode.attributes)) {\n        rrElement.attributes[name] = value;\n      }\n      elementNode.scrollLeft && (rrElement.scrollLeft = elementNode.scrollLeft);\n      elementNode.scrollTop && (rrElement.scrollTop = elementNode.scrollTop);\n      break;\n    }\n    case NodeType.TEXT_NODE:\n      rrNode = rrdom.createTextNode(node2.textContent || \"\");\n      break;\n    case NodeType.CDATA_SECTION_NODE:\n      rrNode = rrdom.createCDATASection(node2.data);\n      break;\n    case NodeType.COMMENT_NODE:\n      rrNode = rrdom.createComment(node2.textContent || \"\");\n      break;\n    case NodeType.DOCUMENT_FRAGMENT_NODE:\n      rrNode = parentRRNode.attachShadow({ mode: \"open\" });\n      break;\n    default:\n      return null;\n  }\n  let sn = domMirror.getMeta(node2);\n  if (rrdom instanceof RRDocument) {\n    if (!sn) {\n      sn = getDefaultSN(rrNode, rrdom.unserializedId);\n      domMirror.add(node2, sn);\n    }\n    rrdom.mirror.add(rrNode, { ...sn });\n  }\n  return rrNode;\n}\nfunction buildFromDom(dom, domMirror = createMirror$1(), rrdom = new RRDocument()) {\n  function walk2(node2, parentRRNode) {\n    const rrNode = buildFromNode(node2, rrdom, domMirror, parentRRNode);\n    if (rrNode === null) return;\n    if (\n      // if the parentRRNode isn't a RRIFrameElement\n      (parentRRNode == null ? void 0 : parentRRNode.nodeName) !== \"IFRAME\" && // if node isn't a shadow root\n      node2.nodeType !== NodeType.DOCUMENT_FRAGMENT_NODE\n    ) {\n      parentRRNode == null ? void 0 : parentRRNode.appendChild(rrNode);\n      rrNode.parentNode = parentRRNode;\n      rrNode.parentElement = parentRRNode;\n    }\n    if (node2.nodeName === \"IFRAME\") {\n      const iframeDoc = node2.contentDocument;\n      iframeDoc && walk2(iframeDoc, rrNode);\n    } else if (node2.nodeType === NodeType.DOCUMENT_NODE || node2.nodeType === NodeType.ELEMENT_NODE || node2.nodeType === NodeType.DOCUMENT_FRAGMENT_NODE) {\n      if (node2.nodeType === NodeType.ELEMENT_NODE && node2.shadowRoot)\n        walk2(node2.shadowRoot, rrNode);\n      node2.childNodes.forEach((childNode) => walk2(childNode, rrNode));\n    }\n  }\n  walk2(dom, null);\n  return rrdom;\n}\nfunction createMirror() {\n  return new Mirror2();\n}\nclass Mirror2 {\n  constructor() {\n    __publicField(this, \"idNodeMap\", /* @__PURE__ */ new Map());\n    __publicField(this, \"nodeMetaMap\", /* @__PURE__ */ new WeakMap());\n  }\n  getId(n) {\n    var _a;\n    if (!n) return -1;\n    const id = (_a = this.getMeta(n)) == null ? void 0 : _a.id;\n    return id ?? -1;\n  }\n  getNode(id) {\n    return this.idNodeMap.get(id) || null;\n  }\n  getIds() {\n    return Array.from(this.idNodeMap.keys());\n  }\n  getMeta(n) {\n    return this.nodeMetaMap.get(n) || null;\n  }\n  // removes the node from idNodeMap\n  // doesn't remove the node from nodeMetaMap\n  removeNodeFromMap(n) {\n    const id = this.getId(n);\n    this.idNodeMap.delete(id);\n    if (n.childNodes) {\n      n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));\n    }\n  }\n  has(id) {\n    return this.idNodeMap.has(id);\n  }\n  hasNode(node2) {\n    return this.nodeMetaMap.has(node2);\n  }\n  add(n, meta) {\n    const id = meta.id;\n    this.idNodeMap.set(id, n);\n    this.nodeMetaMap.set(n, meta);\n  }\n  replace(id, n) {\n    const oldNode = this.getNode(id);\n    if (oldNode) {\n      const meta = this.nodeMetaMap.get(oldNode);\n      if (meta) this.nodeMetaMap.set(n, meta);\n    }\n    this.idNodeMap.set(id, n);\n  }\n  reset() {\n    this.idNodeMap = /* @__PURE__ */ new Map();\n    this.nodeMetaMap = /* @__PURE__ */ new WeakMap();\n  }\n}\nfunction getDefaultSN(node2, id) {\n  switch (node2.RRNodeType) {\n    case NodeType$1.Document:\n      return {\n        id,\n        type: node2.RRNodeType,\n        childNodes: []\n      };\n    case NodeType$1.DocumentType: {\n      const doctype = node2;\n      return {\n        id,\n        type: node2.RRNodeType,\n        name: doctype.name,\n        publicId: doctype.publicId,\n        systemId: doctype.systemId\n      };\n    }\n    case NodeType$1.Element:\n      return {\n        id,\n        type: node2.RRNodeType,\n        tagName: node2.tagName.toLowerCase(),\n        // In rrweb data, all tagNames are lowercase.\n        attributes: {},\n        childNodes: []\n      };\n    case NodeType$1.Text:\n      return {\n        id,\n        type: node2.RRNodeType,\n        textContent: node2.textContent || \"\"\n      };\n    case NodeType$1.Comment:\n      return {\n        id,\n        type: node2.RRNodeType,\n        textContent: node2.textContent || \"\"\n      };\n    case NodeType$1.CDATA:\n      return {\n        id,\n        type: node2.RRNodeType,\n        textContent: \"\"\n      };\n  }\n}\nfunction printRRDom(rootNode, mirror) {\n  return walk(rootNode, mirror, \"\");\n}\nfunction walk(node2, mirror, blankSpace) {\n  let printText = `${blankSpace}${mirror.getId(node2)} ${node2.toString()}\n`;\n  if (node2.RRNodeType === NodeType$1.Element) {\n    const element = node2;\n    if (element.shadowRoot)\n      printText += walk(element.shadowRoot, mirror, blankSpace + \"  \");\n  }\n  for (const child of node2.childNodes)\n    printText += walk(child, mirror, blankSpace + \"  \");\n  if (node2.nodeName === \"IFRAME\")\n    printText += walk(\n      node2.contentDocument,\n      mirror,\n      blankSpace + \"  \"\n    );\n  return printText;\n}\nexport {\n  BaseRRCDATASection,\n  BaseRRComment,\n  BaseRRDialogElement,\n  BaseRRDocument,\n  BaseRRDocumentType,\n  BaseRRElement,\n  BaseRRMediaElement,\n  BaseRRNode,\n  BaseRRText,\n  ClassList,\n  Mirror2 as Mirror,\n  NodeType,\n  RRCDATASection,\n  RRCanvasElement,\n  RRComment,\n  RRDialogElement,\n  RRDocument,\n  RRDocumentType,\n  RRElement,\n  RRIFrameElement,\n  RRMediaElement,\n  BaseRRNode as RRNode,\n  RRStyleElement,\n  RRText,\n  buildFromDom,\n  buildFromNode,\n  createMirror,\n  createOrGetNode,\n  diff,\n  getDefaultSN,\n  printRRDom\n};\n//# sourceMappingURL=rrdom.js.map\n", "const testableAccessors = {\n  Node: [\n    \"childNodes\",\n    \"parentNode\",\n    \"parentElement\",\n    \"textContent\",\n    \"ownerDocument\"\n  ],\n  ShadowRoot: [\"host\", \"styleSheets\"],\n  Element: [\"shadowRoot\", \"querySelector\", \"querySelectorAll\"],\n  MutationObserver: []\n};\nconst testableMethods = {\n  Node: [\"contains\", \"getRootNode\"],\n  ShadowRoot: [\"getSelection\"],\n  Element: [],\n  MutationObserver: [\"constructor\"]\n};\nconst untaintedBasePrototype = {};\nconst isAngularZonePresent = () => {\n  return !!globalThis.Zone;\n};\nfunction getUntaintedPrototype(key) {\n  if (untaintedBasePrototype[key])\n    return untaintedBasePrototype[key];\n  const defaultObj = globalThis[key];\n  const defaultPrototype = defaultObj.prototype;\n  const accessorNames = key in testableAccessors ? testableAccessors[key] : void 0;\n  const isUntaintedAccessors = Boolean(\n    accessorNames && // @ts-expect-error 2345\n    accessorNames.every(\n      (accessor) => {\n        var _a, _b;\n        return Boolean(\n          (_b = (_a = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a.get) == null ? void 0 : _b.toString().includes(\"[native code]\")\n        );\n      }\n    )\n  );\n  const methodNames = key in testableMethods ? testableMethods[key] : void 0;\n  const isUntaintedMethods = Boolean(\n    methodNames && methodNames.every(\n      // @ts-expect-error 2345\n      (method) => {\n        var _a;\n        return typeof defaultPrototype[method] === \"function\" && ((_a = defaultPrototype[method]) == null ? void 0 : _a.toString().includes(\"[native code]\"));\n      }\n    )\n  );\n  if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n    untaintedBasePrototype[key] = defaultObj.prototype;\n    return defaultObj.prototype;\n  }\n  try {\n    const iframeEl = document.createElement(\"iframe\");\n    document.body.appendChild(iframeEl);\n    const win = iframeEl.contentWindow;\n    if (!win) return defaultObj.prototype;\n    const untaintedObject = win[key].prototype;\n    document.body.removeChild(iframeEl);\n    if (!untaintedObject) return defaultPrototype;\n    return untaintedBasePrototype[key] = untaintedObject;\n  } catch {\n    return defaultPrototype;\n  }\n}\nconst untaintedAccessorCache = {};\nfunction getUntaintedAccessor(key, instance, accessor) {\n  var _a;\n  const cacheKey = `${key}.${String(accessor)}`;\n  if (untaintedAccessorCache[cacheKey])\n    return untaintedAccessorCache[cacheKey].call(\n      instance\n    );\n  const untaintedPrototype = getUntaintedPrototype(key);\n  const untaintedAccessor = (_a = Object.getOwnPropertyDescriptor(\n    untaintedPrototype,\n    accessor\n  )) == null ? void 0 : _a.get;\n  if (!untaintedAccessor) return instance[accessor];\n  untaintedAccessorCache[cacheKey] = untaintedAccessor;\n  return untaintedAccessor.call(instance);\n}\nconst untaintedMethodCache = {};\nfunction getUntaintedMethod(key, instance, method) {\n  const cacheKey = `${key}.${String(method)}`;\n  if (untaintedMethodCache[cacheKey])\n    return untaintedMethodCache[cacheKey].bind(\n      instance\n    );\n  const untaintedPrototype = getUntaintedPrototype(key);\n  const untaintedMethod = untaintedPrototype[method];\n  if (typeof untaintedMethod !== \"function\") return instance[method];\n  untaintedMethodCache[cacheKey] = untaintedMethod;\n  return untaintedMethod.bind(instance);\n}\nfunction ownerDocument(n) {\n  return getUntaintedAccessor(\"Node\", n, \"ownerDocument\");\n}\nfunction childNodes(n) {\n  return getUntaintedAccessor(\"Node\", n, \"childNodes\");\n}\nfunction parentNode(n) {\n  return getUntaintedAccessor(\"Node\", n, \"parentNode\");\n}\nfunction parentElement(n) {\n  return getUntaintedAccessor(\"Node\", n, \"parentElement\");\n}\nfunction textContent(n) {\n  return getUntaintedAccessor(\"Node\", n, \"textContent\");\n}\nfunction contains(n, other) {\n  return getUntaintedMethod(\"Node\", n, \"contains\")(other);\n}\nfunction getRootNode(n) {\n  return getUntaintedMethod(\"Node\", n, \"getRootNode\")();\n}\nfunction host(n) {\n  if (!n || !(\"host\" in n)) return null;\n  return getUntaintedAccessor(\"ShadowRoot\", n, \"host\");\n}\nfunction styleSheets(n) {\n  return n.styleSheets;\n}\nfunction shadowRoot(n) {\n  if (!n || !(\"shadowRoot\" in n)) return null;\n  return getUntaintedAccessor(\"Element\", n, \"shadowRoot\");\n}\nfunction querySelector(n, selectors) {\n  return getUntaintedAccessor(\"Element\", n, \"querySelector\")(selectors);\n}\nfunction querySelectorAll(n, selectors) {\n  return getUntaintedAccessor(\"Element\", n, \"querySelectorAll\")(selectors);\n}\nfunction mutationObserverCtor() {\n  return getUntaintedPrototype(\"MutationObserver\").constructor;\n}\nfunction patch(source, name, replacement) {\n  try {\n    if (!(name in source)) {\n      return () => {\n      };\n    }\n    const original = source[name];\n    const wrapped = replacement(original);\n    if (typeof wrapped === \"function\") {\n      wrapped.prototype = wrapped.prototype || {};\n      Object.defineProperties(wrapped, {\n        __rrweb_original__: {\n          enumerable: false,\n          value: original\n        }\n      });\n    }\n    source[name] = wrapped;\n    return () => {\n      source[name] = original;\n    };\n  } catch {\n    return () => {\n    };\n  }\n}\nconst index = {\n  ownerDocument,\n  childNodes,\n  parentNode,\n  parentElement,\n  textContent,\n  contains,\n  getRootNode,\n  host,\n  styleSheets,\n  shadowRoot,\n  querySelector,\n  querySelectorAll,\n  mutationObserver: mutationObserverCtor,\n  patch\n};\nexport {\n  childNodes,\n  contains,\n  index as default,\n  getRootNode,\n  getUntaintedAccessor,\n  getUntaintedMethod,\n  getUntaintedPrototype,\n  host,\n  isAngularZonePresent,\n  mutationObserverCtor,\n  ownerDocument,\n  parentElement,\n  parentNode,\n  patch,\n  querySelector,\n  querySelectorAll,\n  shadowRoot,\n  styleSheets,\n  textContent\n};\n//# sourceMappingURL=utils.js.map\n", "import type {\n  throttleOptions,\n  listenerHandler,\n  hookResetter,\n  blockClass,\n  addedNodeMutation,\n  DocumentDimension,\n  IWindow,\n  DeprecatedMirror,\n  textMutation,\n  IMirror,\n} from '@rrweb/types';\nimport type { Mirror, SlimDOMOptions } from 'rrweb-snapshot';\nimport { isShadowRoot, IGNORED_NODE, classMatchesRegex } from 'rrweb-snapshot';\nimport { RRNode, RRIFrameElement, BaseRRNode } from 'rrdom';\nimport dom from '@rrweb/utils';\n\nexport function on(\n  type: string,\n  fn: EventListenerOrEventListenerObject,\n  target: Document | IWindow = document,\n): listenerHandler {\n  const options = { capture: true, passive: true };\n  target.addEventListener(type, fn, options);\n  return () => target.removeEventListener(type, fn, options);\n}\n\n// https://github.com/rrweb-io/rrweb/pull/407\nconst DEPARTED_MIRROR_ACCESS_WARNING =\n  'Please stop import mirror directly. Instead of that,' +\n  '\\r\\n' +\n  'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +\n  '\\r\\n' +\n  'or you can use record.mirror to access the mirror instance during recording.';\n/** @deprecated */\nexport let _mirror: DeprecatedMirror = {\n  map: {},\n  getId() {\n    console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n    return -1;\n  },\n  getNode() {\n    console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n    return null;\n  },\n  removeNodeFromMap() {\n    console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n  },\n  has() {\n    console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n    return false;\n  },\n  reset() {\n    console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n  },\n};\nif (typeof window !== 'undefined' && window.Proxy && window.Reflect) {\n  _mirror = new Proxy(_mirror, {\n    get(target, prop, receiver) {\n      if (prop === 'map') {\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n      }\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n      return Reflect.get(target, prop, receiver);\n    },\n  });\n}\n\n// copy from underscore and modified\nexport function throttle<T>(\n  func: (arg: T) => void,\n  wait: number,\n  options: throttleOptions = {},\n) {\n  let timeout: ReturnType<typeof setTimeout> | null = null;\n  let previous = 0;\n  return function (...args: T[]) {\n    const now = Date.now();\n    if (!previous && options.leading === false) {\n      previous = now;\n    }\n    const remaining = wait - (now - previous);\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-this-alias\n    const context = this;\n    if (remaining <= 0 || remaining > wait) {\n      if (timeout) {\n        clearTimeout(timeout);\n        timeout = null;\n      }\n      previous = now;\n      func.apply(context, args);\n    } else if (!timeout && options.trailing !== false) {\n      timeout = setTimeout(() => {\n        previous = options.leading === false ? 0 : Date.now();\n        timeout = null;\n        func.apply(context, args);\n      }, remaining);\n    }\n  };\n}\n\nexport function hookSetter<T>(\n  target: T,\n  key: string | number | symbol,\n  d: PropertyDescriptor,\n  isRevoked?: boolean,\n  win = window,\n): hookResetter {\n  const original = win.Object.getOwnPropertyDescriptor(target, key);\n  win.Object.defineProperty(\n    target,\n    key,\n    isRevoked\n      ? d\n      : {\n          set(value) {\n            // put hooked setter into event loop to avoid of set latency\n            setTimeout(() => {\n              d.set!.call(this, value);\n            }, 0);\n            if (original && original.set) {\n              original.set.call(this, value);\n            }\n          },\n        },\n  );\n  return () => hookSetter(target, key, original || {}, true);\n}\n\n// guard against old third party libraries which redefine Date.now\nlet nowTimestamp = Date.now;\n\nif (!(/*@__PURE__*/ /[1-9][0-9]{12}/.test(Date.now().toString()))) {\n  // they have already redefined it! use a fallback\n  nowTimestamp = () => new Date().getTime();\n}\nexport { nowTimestamp };\n\nexport function getWindowScroll(win: Window) {\n  const doc = win.document;\n  return {\n    left: doc.scrollingElement\n      ? doc.scrollingElement.scrollLeft\n      : win.pageXOffset !== undefined\n      ? win.pageXOffset\n      : doc.documentElement.scrollLeft ||\n        (doc?.body && dom.parentElement(doc.body)?.scrollLeft) ||\n        doc?.body?.scrollLeft ||\n        0,\n    top: doc.scrollingElement\n      ? doc.scrollingElement.scrollTop\n      : win.pageYOffset !== undefined\n      ? win.pageYOffset\n      : doc?.documentElement.scrollTop ||\n        (doc?.body && dom.parentElement(doc.body)?.scrollTop) ||\n        doc?.body?.scrollTop ||\n        0,\n  };\n}\n\nexport function getWindowHeight(): number {\n  return (\n    window.innerHeight ||\n    (document.documentElement && document.documentElement.clientHeight) ||\n    (document.body && document.body.clientHeight)\n  );\n}\n\nexport function getWindowWidth(): number {\n  return (\n    window.innerWidth ||\n    (document.documentElement && document.documentElement.clientWidth) ||\n    (document.body && document.body.clientWidth)\n  );\n}\n\n/**\n * Returns the given node as an HTMLElement if it is one, otherwise the parent node as an HTMLElement\n * @param node - node to check\n * @returns HTMLElement or null\n */\n\nexport function closestElementOfNode(node: Node | null): HTMLElement | null {\n  if (!node) {\n    return null;\n  }\n  const el: HTMLElement | null =\n    node.nodeType === node.ELEMENT_NODE\n      ? (node as HTMLElement)\n      : dom.parentElement(node);\n  return el;\n}\n\n/**\n * Checks if the given element set to be blocked by rrweb\n * @param node - node to check\n * @param blockClass - class name to check\n * @param blockSelector - css selectors to check\n * @param checkAncestors - whether to search through parent nodes for the block class\n * @returns true/false if the node was blocked or not\n */\nexport function isBlocked(\n  node: Node | null,\n  blockClass: blockClass,\n  blockSelector: string | null,\n  checkAncestors: boolean,\n): boolean {\n  if (!node) {\n    return false;\n  }\n  const el = closestElementOfNode(node);\n\n  if (!el) {\n    return false;\n  }\n\n  try {\n    if (typeof blockClass === 'string') {\n      if (el.classList.contains(blockClass)) return true;\n      if (checkAncestors && el.closest('.' + blockClass) !== null) return true;\n    } else {\n      if (classMatchesRegex(el, blockClass, checkAncestors)) return true;\n    }\n  } catch (e) {\n    // e\n  }\n  if (blockSelector) {\n    if (el.matches(blockSelector)) return true;\n    if (checkAncestors && el.closest(blockSelector) !== null) return true;\n  }\n  return false;\n}\n\nexport function isSerialized(n: Node, mirror: Mirror): boolean {\n  return mirror.getId(n) !== -1;\n}\n\nexport function isIgnored(\n  n: Node,\n  mirror: Mirror,\n  slimDOMOptions: SlimDOMOptions,\n): boolean {\n  if ((n as Element).tagName === 'TITLE' && slimDOMOptions.headTitleMutations) {\n    // we do this check here but not in rrweb-snapshot\n    // to block mutations/animations on the title.\n    // the headTitleMutations option isn't intended to block recording of the initial value\n    return true;\n  }\n  // The main part of the slimDOM check happens in\n  // rrweb-snapshot::serializeNodeWithId\n  return mirror.getId(n) === IGNORED_NODE;\n}\n\nexport function isAncestorRemoved(target: Node, mirror: Mirror): boolean {\n  if (isShadowRoot(target)) {\n    return false;\n  }\n  const id = mirror.getId(target);\n  if (!mirror.has(id)) {\n    return true;\n  }\n  const parent = dom.parentNode(target);\n  if (parent && parent.nodeType === target.DOCUMENT_NODE) {\n    return false;\n  }\n  // if the root is not document, it means the node is not in the DOM tree anymore\n  if (!parent) {\n    return true;\n  }\n  return isAncestorRemoved(parent, mirror);\n}\n\nexport function legacy_isTouchEvent(\n  event: MouseEvent | TouchEvent | PointerEvent,\n): event is TouchEvent {\n  return Boolean((event as TouchEvent).changedTouches);\n}\n\nexport function polyfill(win = window) {\n  if ('NodeList' in win && !win.NodeList.prototype.forEach) {\n    // eslint-disable-next-line @typescript-eslint/unbound-method\n    win.NodeList.prototype.forEach = Array.prototype\n      .forEach as unknown as NodeList['forEach'];\n  }\n\n  if ('DOMTokenList' in win && !win.DOMTokenList.prototype.forEach) {\n    // eslint-disable-next-line @typescript-eslint/unbound-method\n    win.DOMTokenList.prototype.forEach = Array.prototype\n      .forEach as unknown as DOMTokenList['forEach'];\n  }\n}\n\ntype ResolveTree = {\n  value: addedNodeMutation;\n  children: ResolveTree[];\n  parent: ResolveTree | null;\n};\n\nexport function queueToResolveTrees(queue: addedNodeMutation[]): ResolveTree[] {\n  const queueNodeMap: Record<number, ResolveTree> = {};\n  const putIntoMap = (\n    m: addedNodeMutation,\n    parent: ResolveTree | null,\n  ): ResolveTree => {\n    const nodeInTree: ResolveTree = {\n      value: m,\n      parent,\n      children: [],\n    };\n    queueNodeMap[m.node.id] = nodeInTree;\n    return nodeInTree;\n  };\n\n  const queueNodeTrees: ResolveTree[] = [];\n  for (const mutation of queue) {\n    const { nextId, parentId } = mutation;\n    if (nextId && nextId in queueNodeMap) {\n      const nextInTree = queueNodeMap[nextId];\n      if (nextInTree.parent) {\n        const idx = nextInTree.parent.children.indexOf(nextInTree);\n        nextInTree.parent.children.splice(\n          idx,\n          0,\n          putIntoMap(mutation, nextInTree.parent),\n        );\n      } else {\n        const idx = queueNodeTrees.indexOf(nextInTree);\n        queueNodeTrees.splice(idx, 0, putIntoMap(mutation, null));\n      }\n      continue;\n    }\n    if (parentId in queueNodeMap) {\n      const parentInTree = queueNodeMap[parentId];\n      parentInTree.children.push(putIntoMap(mutation, parentInTree));\n      continue;\n    }\n    queueNodeTrees.push(putIntoMap(mutation, null));\n  }\n\n  return queueNodeTrees;\n}\n\nexport function iterateResolveTree(\n  tree: ResolveTree,\n  cb: (mutation: addedNodeMutation) => unknown,\n) {\n  cb(tree.value);\n  /**\n   * The resolve tree was designed to reflect the DOM layout,\n   * but we need append next sibling first, so we do a reverse\n   * loop here.\n   */\n  for (let i = tree.children.length - 1; i >= 0; i--) {\n    iterateResolveTree(tree.children[i], cb);\n  }\n}\n\nexport type AppendedIframe = {\n  mutationInQueue: addedNodeMutation;\n  builtNode: HTMLIFrameElement | RRIFrameElement;\n};\n\nexport function isSerializedIframe<TNode extends Node | RRNode>(\n  n: TNode,\n  mirror: IMirror<TNode>,\n): boolean {\n  return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));\n}\n\nexport function isSerializedStylesheet<TNode extends Node | RRNode>(\n  n: TNode,\n  mirror: IMirror<TNode>,\n): boolean {\n  return Boolean(\n    n.nodeName === 'LINK' &&\n      n.nodeType === n.ELEMENT_NODE &&\n      (n as HTMLElement).getAttribute &&\n      (n as HTMLElement).getAttribute('rel') === 'stylesheet' &&\n      mirror.getMeta(n),\n  );\n}\n\nexport function getBaseDimension(\n  node: Node,\n  rootIframe: Node,\n): DocumentDimension {\n  const frameElement = node.ownerDocument?.defaultView?.frameElement;\n  if (!frameElement || frameElement === rootIframe) {\n    return {\n      x: 0,\n      y: 0,\n      relativeScale: 1,\n      absoluteScale: 1,\n    };\n  }\n\n  const frameDimension = frameElement.getBoundingClientRect();\n  const frameBaseDimension = getBaseDimension(frameElement, rootIframe);\n  // the iframe element may have a scale transform\n  const relativeScale = frameDimension.height / frameElement.clientHeight;\n  return {\n    x:\n      frameDimension.x * frameBaseDimension.relativeScale +\n      frameBaseDimension.x,\n    y:\n      frameDimension.y * frameBaseDimension.relativeScale +\n      frameBaseDimension.y,\n    relativeScale,\n    absoluteScale: frameBaseDimension.absoluteScale * relativeScale,\n  };\n}\n\nexport function hasShadowRoot<T extends Node | RRNode>(\n  n: T,\n): n is T & { shadowRoot: ShadowRoot } {\n  if (!n) return false;\n  if (n instanceof BaseRRNode && 'shadowRoot' in n) {\n    return Boolean(n.shadowRoot);\n  }\n  return Boolean(dom.shadowRoot(n as unknown as Element));\n}\n\nexport function getNestedRule(\n  rules: CSSRuleList,\n  position: number[],\n): CSSGroupingRule {\n  const rule = rules[position[0]] as CSSGroupingRule;\n  if (position.length === 1) {\n    return rule;\n  } else {\n    return getNestedRule(\n      (rule.cssRules[position[1]] as CSSGroupingRule).cssRules,\n      position.slice(2),\n    );\n  }\n}\n\nexport function getPositionsAndIndex(nestedIndex: number[]) {\n  const positions = [...nestedIndex];\n  const index = positions.pop();\n  return { positions, index };\n}\n\n/**\n * Returns the latest mutation in the queue for each node.\n * @param mutations - mutations The text mutations to filter.\n * @returns The filtered text mutations.\n */\nexport function uniqueTextMutations(mutations: textMutation[]): textMutation[] {\n  const idSet = new Set<number>();\n  const uniqueMutations: textMutation[] = [];\n\n  for (let i = mutations.length; i--; ) {\n    const mutation = mutations[i];\n    if (!idSet.has(mutation.id)) {\n      uniqueMutations.push(mutation);\n      idSet.add(mutation.id);\n    }\n  }\n\n  return uniqueMutations;\n}\n\nexport class StyleSheetMirror {\n  private id = 1;\n  private styleIDMap = new WeakMap<CSSStyleSheet, number>();\n  private idStyleMap = new Map<number, CSSStyleSheet>();\n\n  getId(stylesheet: CSSStyleSheet): number {\n    return this.styleIDMap.get(stylesheet) ?? -1;\n  }\n\n  has(stylesheet: CSSStyleSheet): boolean {\n    return this.styleIDMap.has(stylesheet);\n  }\n\n  /**\n   * @returns If the stylesheet is in the mirror, returns the id of the stylesheet. If not, return the new assigned id.\n   */\n  add(stylesheet: CSSStyleSheet, id?: number): number {\n    if (this.has(stylesheet)) return this.getId(stylesheet);\n    let newId: number;\n    if (id === undefined) {\n      newId = this.id++;\n    } else newId = id;\n    this.styleIDMap.set(stylesheet, newId);\n    this.idStyleMap.set(newId, stylesheet);\n    return newId;\n  }\n\n  getStyle(id: number): CSSStyleSheet | null {\n    return this.idStyleMap.get(id) || null;\n  }\n\n  reset(): void {\n    this.styleIDMap = new WeakMap();\n    this.idStyleMap = new Map();\n    this.id = 1;\n  }\n\n  generateId(): number {\n    return this.id++;\n  }\n}\n\n/**\n * Get the direct shadow host of a node in shadow dom. Returns null if it is not in a shadow dom.\n */\nexport function getShadowHost(n: Node): Element | null {\n  let shadowHost: Element | null = null;\n  if (\n    'getRootNode' in n &&\n    dom.getRootNode(n)?.nodeType === Node.DOCUMENT_FRAGMENT_NODE &&\n    dom.host(dom.getRootNode(n) as ShadowRoot)\n  )\n    shadowHost = dom.host(dom.getRootNode(n) as ShadowRoot);\n  return shadowHost;\n}\n\n/**\n * Get the root shadow host of a node in nested shadow doms. Returns the node itself if it is not in a shadow dom.\n */\nexport function getRootShadowHost(n: Node): Node {\n  let rootShadowHost: Node = n;\n\n  let shadowHost: Element | null;\n  // If n is in a nested shadow dom.\n  while ((shadowHost = getShadowHost(rootShadowHost)))\n    rootShadowHost = shadowHost;\n\n  return rootShadowHost;\n}\n\nexport function shadowHostInDom(n: Node): boolean {\n  const doc = dom.ownerDocument(n);\n  if (!doc) return false;\n  const shadowHost = getRootShadowHost(n);\n  return dom.contains(doc, shadowHost);\n}\n\nexport function inDom(n: Node): boolean {\n  const doc = dom.ownerDocument(n);\n  if (!doc) return false;\n  return dom.contains(doc, n) || shadowHostInDom(n);\n}\n", "var EventType = /* @__PURE__ */ ((EventType2) => {\n  EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n  EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n  EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n  EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n  EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n  EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n  EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n  return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n  IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n  IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n  IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n  IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n  IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n  IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n  IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n  IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n  IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n  IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n  IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n  IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n  IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n  IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n  IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n  IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n  IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n  return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n  MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n  MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n  MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n  MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n  MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n  MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n  MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n  MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n  MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n  MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n  MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n  return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n  PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n  PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n  PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n  return PointerTypes2;\n})(PointerTypes || {});\nvar CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {\n  CanvasContext2[CanvasContext2[\"2D\"] = 0] = \"2D\";\n  CanvasContext2[CanvasContext2[\"WebGL\"] = 1] = \"WebGL\";\n  CanvasContext2[CanvasContext2[\"WebGL2\"] = 2] = \"WebGL2\";\n  return CanvasContext2;\n})(CanvasContext || {});\nvar MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {\n  MediaInteractions2[MediaInteractions2[\"Play\"] = 0] = \"Play\";\n  MediaInteractions2[MediaInteractions2[\"Pause\"] = 1] = \"Pause\";\n  MediaInteractions2[MediaInteractions2[\"Seeked\"] = 2] = \"Seeked\";\n  MediaInteractions2[MediaInteractions2[\"VolumeChange\"] = 3] = \"VolumeChange\";\n  MediaInteractions2[MediaInteractions2[\"RateChange\"] = 4] = \"RateChange\";\n  return MediaInteractions2;\n})(MediaInteractions || {});\nvar ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {\n  ReplayerEvents2[\"Start\"] = \"start\";\n  ReplayerEvents2[\"Pause\"] = \"pause\";\n  ReplayerEvents2[\"Resume\"] = \"resume\";\n  ReplayerEvents2[\"Resize\"] = \"resize\";\n  ReplayerEvents2[\"Finish\"] = \"finish\";\n  ReplayerEvents2[\"FullsnapshotRebuilded\"] = \"fullsnapshot-rebuilded\";\n  ReplayerEvents2[\"LoadStylesheetStart\"] = \"load-stylesheet-start\";\n  ReplayerEvents2[\"LoadStylesheetEnd\"] = \"load-stylesheet-end\";\n  ReplayerEvents2[\"SkipStart\"] = \"skip-start\";\n  ReplayerEvents2[\"SkipEnd\"] = \"skip-end\";\n  ReplayerEvents2[\"MouseInteraction\"] = \"mouse-interaction\";\n  ReplayerEvents2[\"EventCast\"] = \"event-cast\";\n  ReplayerEvents2[\"CustomEvent\"] = \"custom-event\";\n  ReplayerEvents2[\"Flush\"] = \"flush\";\n  ReplayerEvents2[\"StateChange\"] = \"state-change\";\n  ReplayerEvents2[\"PlayBack\"] = \"play-back\";\n  ReplayerEvents2[\"Destroy\"] = \"destroy\";\n  return ReplayerEvents2;\n})(ReplayerEvents || {});\nvar NodeType = /* @__PURE__ */ ((NodeType2) => {\n  NodeType2[NodeType2[\"Document\"] = 0] = \"Document\";\n  NodeType2[NodeType2[\"DocumentType\"] = 1] = \"DocumentType\";\n  NodeType2[NodeType2[\"Element\"] = 2] = \"Element\";\n  NodeType2[NodeType2[\"Text\"] = 3] = \"Text\";\n  NodeType2[NodeType2[\"CDATA\"] = 4] = \"CDATA\";\n  NodeType2[NodeType2[\"Comment\"] = 5] = \"Comment\";\n  return NodeType2;\n})(NodeType || {});\nexport {\n  CanvasContext,\n  EventType,\n  IncrementalSource,\n  MediaInteractions,\n  MouseInteractions,\n  NodeType,\n  PointerTypes,\n  ReplayerEvents\n};\n//# sourceMappingURL=types.js.map\n", "import {\n  serializeNodeWithId,\n  transformAttribute,\n  IGNORED_NODE,\n  ignoreAttribute,\n  isShadowRoot,\n  needMaskingText,\n  maskInputValue,\n  Mirror,\n  isNativeShadowDom,\n  getInputType,\n  toLowerCase,\n} from 'rrweb-snapshot';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport type {\n  mutationRecord,\n  textCursor,\n  attributeCursor,\n  removedNodeMutation,\n  addedNodeMutation,\n  Optional,\n} from '@rrweb/types';\nimport {\n  isBlocked,\n  isAncestorRemoved,\n  isIgnored,\n  isSerialized,\n  hasShadowRoot,\n  isSerializedIframe,\n  isSerializedStylesheet,\n  inDom,\n  getShadowHost,\n  closestElementOfNode,\n} from '../utils';\nimport dom from '@rrweb/utils';\n\ntype DoubleLinkedListNode = {\n  previous: DoubleLinkedListNode | null;\n  next: DoubleLinkedListNode | null;\n  value: NodeInLinkedList;\n};\ntype NodeInLinkedList = Node & {\n  __ln: DoubleLinkedListNode;\n};\n\nfunction isNodeInLinkedList(n: Node | NodeInLinkedList): n is NodeInLinkedList {\n  return '__ln' in n;\n}\n\nclass DoubleLinkedList {\n  public length = 0;\n  public head: DoubleLinkedListNode | null = null;\n  public tail: DoubleLinkedListNode | null = null;\n\n  public get(position: number) {\n    if (position >= this.length) {\n      throw new Error('Position outside of list range');\n    }\n\n    let current = this.head;\n    for (let index = 0; index < position; index++) {\n      current = current?.next || null;\n    }\n    return current;\n  }\n\n  public addNode(n: Node) {\n    const node: DoubleLinkedListNode = {\n      value: n as NodeInLinkedList,\n      previous: null,\n      next: null,\n    };\n    (n as NodeInLinkedList).__ln = node;\n    if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {\n      const current = n.previousSibling.__ln.next;\n      node.next = current;\n      node.previous = n.previousSibling.__ln;\n      n.previousSibling.__ln.next = node;\n      if (current) {\n        current.previous = node;\n      }\n    } else if (\n      n.nextSibling &&\n      isNodeInLinkedList(n.nextSibling) &&\n      n.nextSibling.__ln.previous\n    ) {\n      const current = n.nextSibling.__ln.previous;\n      node.previous = current;\n      node.next = n.nextSibling.__ln;\n      n.nextSibling.__ln.previous = node;\n      if (current) {\n        current.next = node;\n      }\n    } else {\n      if (this.head) {\n        this.head.previous = node;\n      }\n      node.next = this.head;\n      this.head = node;\n    }\n    if (node.next === null) {\n      this.tail = node;\n    }\n    this.length++;\n  }\n\n  public removeNode(n: NodeInLinkedList) {\n    const current = n.__ln;\n    if (!this.head) {\n      return;\n    }\n\n    if (!current.previous) {\n      this.head = current.next;\n      if (this.head) {\n        this.head.previous = null;\n      } else {\n        this.tail = null;\n      }\n    } else {\n      current.previous.next = current.next;\n      if (current.next) {\n        current.next.previous = current.previous;\n      } else {\n        this.tail = current.previous;\n      }\n    }\n    if (n.__ln) {\n      delete (n as Optional<NodeInLinkedList, '__ln'>).__ln;\n    }\n    this.length--;\n  }\n}\n\nconst moveKey = (id: number, parentId: number) => `${id}@${parentId}`;\n\n/**\n * controls behaviour of a MutationObserver\n */\nexport default class MutationBuffer {\n  private frozen = false;\n  private locked = false;\n\n  private texts: textCursor[] = [];\n  private attributes: attributeCursor[] = [];\n  private attributeMap = new WeakMap<Node, attributeCursor>();\n  private removes: removedNodeMutation[] = [];\n  private mapRemoves: Node[] = [];\n\n  private movedMap: Record<string, true> = {};\n\n  /**\n   * the browser MutationObserver emits multiple mutations after\n   * a delay for performance reasons, making tracing added nodes hard\n   * in our `processMutations` callback function.\n   * For example, if we append an element el_1 into body, and then append\n   * another element el_2 into el_1, these two mutations may be passed to the\n   * callback function together when the two operations were done.\n   * Generally we need to trace child nodes of newly added nodes, but in this\n   * case if we count el_2 as el_1's child node in the first mutation record,\n   * then we will count el_2 again in the second mutation record which was\n   * duplicated.\n   * To avoid of duplicate counting added nodes, we use a Set to store\n   * added nodes and its child nodes during iterate mutation records. Then\n   * collect added nodes from the Set which have no duplicate copy. But\n   * this also causes newly added nodes will not be serialized with id ASAP,\n   * which means all the id related calculation should be lazy too.\n   */\n  private addedSet = new Set<Node>();\n  private movedSet = new Set<Node>();\n  private droppedSet = new Set<Node>();\n  private removesSubTreeCache = new Set<Node>();\n\n  private mutationCb: observerParam['mutationCb'];\n  private blockClass: observerParam['blockClass'];\n  private blockSelector: observerParam['blockSelector'];\n  private maskTextClass: observerParam['maskTextClass'];\n  private maskTextSelector: observerParam['maskTextSelector'];\n  private inlineStylesheet: observerParam['inlineStylesheet'];\n  private maskInputOptions: observerParam['maskInputOptions'];\n  private maskTextFn: observerParam['maskTextFn'];\n  private maskInputFn: observerParam['maskInputFn'];\n  private keepIframeSrcFn: observerParam['keepIframeSrcFn'];\n  private recordCanvas: observerParam['recordCanvas'];\n  private inlineImages: observerParam['inlineImages'];\n  private slimDOMOptions: observerParam['slimDOMOptions'];\n  private dataURLOptions: observerParam['dataURLOptions'];\n  private doc: observerParam['doc'];\n  private mirror: observerParam['mirror'];\n  private iframeManager: observerParam['iframeManager'];\n  private stylesheetManager: observerParam['stylesheetManager'];\n  private shadowDomManager: observerParam['shadowDomManager'];\n  private canvasManager: observerParam['canvasManager'];\n  private processedNodeManager: observerParam['processedNodeManager'];\n  private unattachedDoc: HTMLDocument;\n\n  public init(options: MutationBufferParam) {\n    (\n      [\n        'mutationCb',\n        'blockClass',\n        'blockSelector',\n        'maskTextClass',\n        'maskTextSelector',\n        'inlineStylesheet',\n        'maskInputOptions',\n        'maskTextFn',\n        'maskInputFn',\n        'keepIframeSrcFn',\n        'recordCanvas',\n        'inlineImages',\n        'slimDOMOptions',\n        'dataURLOptions',\n        'doc',\n        'mirror',\n        'iframeManager',\n        'stylesheetManager',\n        'shadowDomManager',\n        'canvasManager',\n        'processedNodeManager',\n      ] as const\n    ).forEach((key) => {\n      // just a type trick, the runtime result is correct\n      this[key] = options[key] as never;\n    });\n  }\n\n  public freeze() {\n    this.frozen = true;\n    this.canvasManager.freeze();\n  }\n\n  public unfreeze() {\n    this.frozen = false;\n    this.canvasManager.unfreeze();\n    this.emit();\n  }\n\n  public isFrozen() {\n    return this.frozen;\n  }\n\n  public lock() {\n    this.locked = true;\n    this.canvasManager.lock();\n  }\n\n  public unlock() {\n    this.locked = false;\n    this.canvasManager.unlock();\n    this.emit();\n  }\n\n  public reset() {\n    this.shadowDomManager.reset();\n    this.canvasManager.reset();\n  }\n\n  public processMutations = (mutations: mutationRecord[]) => {\n    mutations.forEach(this.processMutation); // adds mutations to the buffer\n    this.emit(); // clears buffer if not locked/frozen\n  };\n\n  public emit = () => {\n    if (this.frozen || this.locked) {\n      return;\n    }\n\n    // delay any modification of the mirror until this function\n    // so that the mirror for takeFullSnapshot doesn't get mutated while it's event is being processed\n\n    const adds: addedNodeMutation[] = [];\n    const addedIds = new Set<number>();\n\n    /**\n     * Sometimes child node may be pushed before its newly added\n     * parent, so we init a queue to store these nodes.\n     */\n    const addList = new DoubleLinkedList();\n    const getNextId = (n: Node): number | null => {\n      let ns: Node | null = n;\n      let nextId: number | null = IGNORED_NODE; // slimDOM: ignored\n      while (nextId === IGNORED_NODE) {\n        ns = ns && ns.nextSibling;\n        nextId = ns && this.mirror.getId(ns);\n      }\n      return nextId;\n    };\n    const pushAdd = (n: Node) => {\n      const parent = dom.parentNode(n);\n      if (!parent || !inDom(n)) {\n        return;\n      }\n      let cssCaptured = false;\n      if (n.nodeType === Node.TEXT_NODE) {\n        const parentTag = (parent as Element).tagName;\n        if (parentTag === 'TEXTAREA') {\n          // genTextAreaValueMutation already called via parent\n          return;\n        } else if (parentTag === 'STYLE' && this.addedSet.has(parent)) {\n          // css content will be recorded via parent's _cssText attribute when\n          // mutation adds entire <style> element\n          cssCaptured = true;\n        }\n      }\n\n      const parentId = isShadowRoot(parent)\n        ? this.mirror.getId(getShadowHost(n))\n        : this.mirror.getId(parent);\n\n      const nextId = getNextId(n);\n      if (parentId === -1 || nextId === -1) {\n        return addList.addNode(n);\n      }\n      const sn = serializeNodeWithId(n, {\n        doc: this.doc,\n        mirror: this.mirror,\n        blockClass: this.blockClass,\n        blockSelector: this.blockSelector,\n        maskTextClass: this.maskTextClass,\n        maskTextSelector: this.maskTextSelector,\n        skipChild: true,\n        newlyAddedElement: true,\n        inlineStylesheet: this.inlineStylesheet,\n        maskInputOptions: this.maskInputOptions,\n        maskTextFn: this.maskTextFn,\n        maskInputFn: this.maskInputFn,\n        slimDOMOptions: this.slimDOMOptions,\n        dataURLOptions: this.dataURLOptions,\n        recordCanvas: this.recordCanvas,\n        inlineImages: this.inlineImages,\n        onSerialize: (currentN) => {\n          if (isSerializedIframe(currentN, this.mirror)) {\n            this.iframeManager.addIframe(currentN as HTMLIFrameElement);\n          }\n          if (isSerializedStylesheet(currentN, this.mirror)) {\n            this.stylesheetManager.trackLinkElement(\n              currentN as HTMLLinkElement,\n            );\n          }\n          if (hasShadowRoot(n)) {\n            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n            this.shadowDomManager.addShadowRoot(dom.shadowRoot(n)!, this.doc);\n          }\n        },\n        onIframeLoad: (iframe, childSn) => {\n          this.iframeManager.attachIframe(iframe, childSn);\n          this.shadowDomManager.observeAttachShadow(iframe);\n        },\n        onStylesheetLoad: (link, childSn) => {\n          this.stylesheetManager.attachLinkElement(link, childSn);\n        },\n        cssCaptured,\n      });\n      if (sn) {\n        adds.push({\n          parentId,\n          nextId,\n          node: sn,\n        });\n        addedIds.add(sn.id);\n      }\n    };\n\n    while (this.mapRemoves.length) {\n      this.mirror.removeNodeFromMap(this.mapRemoves.shift()!);\n    }\n\n    for (const n of this.movedSet) {\n      if (\n        isParentRemoved(this.removesSubTreeCache, n, this.mirror) &&\n        !this.movedSet.has(dom.parentNode(n)!)\n      ) {\n        continue;\n      }\n      pushAdd(n);\n    }\n\n    for (const n of this.addedSet) {\n      if (\n        !isAncestorInSet(this.droppedSet, n) &&\n        !isParentRemoved(this.removesSubTreeCache, n, this.mirror)\n      ) {\n        pushAdd(n);\n      } else if (isAncestorInSet(this.movedSet, n)) {\n        pushAdd(n);\n      } else {\n        this.droppedSet.add(n);\n      }\n    }\n\n    let candidate: DoubleLinkedListNode | null = null;\n    while (addList.length) {\n      let node: DoubleLinkedListNode | null = null;\n      if (candidate) {\n        const parentId = this.mirror.getId(dom.parentNode(candidate.value));\n        const nextId = getNextId(candidate.value);\n        if (parentId !== -1 && nextId !== -1) {\n          node = candidate;\n        }\n      }\n      if (!node) {\n        let tailNode = addList.tail;\n        while (tailNode) {\n          const _node = tailNode;\n          tailNode = tailNode.previous;\n          // ensure _node is defined before attempting to find value\n          if (_node) {\n            const parentId = this.mirror.getId(dom.parentNode(_node.value));\n            const nextId = getNextId(_node.value);\n\n            if (nextId === -1) continue;\n            // nextId !== -1 && parentId !== -1\n            else if (parentId !== -1) {\n              node = _node;\n              break;\n            }\n            // nextId !== -1 && parentId === -1 This branch can happen if the node is the child of shadow root\n            else {\n              const unhandledNode = _node.value;\n              const parent = dom.parentNode(unhandledNode);\n              // If the node is the direct child of a shadow root, we treat the shadow host as its parent node.\n              if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n                const shadowHost = dom.host(parent as ShadowRoot);\n                const parentId = this.mirror.getId(shadowHost);\n                if (parentId !== -1) {\n                  node = _node;\n                  break;\n                }\n              }\n            }\n          }\n        }\n      }\n      if (!node) {\n        /**\n         * If all nodes in queue could not find a serialized parent,\n         * it may be a bug or corner case. We need to escape the\n         * dead while loop at once.\n         */\n        while (addList.head) {\n          addList.removeNode(addList.head.value);\n        }\n        break;\n      }\n      candidate = node.previous;\n      addList.removeNode(node.value);\n      pushAdd(node.value);\n    }\n\n    const payload = {\n      texts: this.texts\n        .map((text) => {\n          const n = text.node;\n          const parent = dom.parentNode(n);\n          if (parent && (parent as Element).tagName === 'TEXTAREA') {\n            // the node is being ignored as it isn't in the mirror, so shift mutation to attributes on parent textarea\n            this.genTextAreaValueMutation(parent as HTMLTextAreaElement);\n          }\n          return {\n            id: this.mirror.getId(n),\n            value: text.value,\n          };\n        })\n        // no need to include them on added elements, as they have just been serialized with up to date attribubtes\n        .filter((text) => !addedIds.has(text.id))\n        // text mutation's id was not in the mirror map means the target node has been removed\n        .filter((text) => this.mirror.has(text.id)),\n      attributes: this.attributes\n        .map((attribute) => {\n          const { attributes } = attribute;\n          if (typeof attributes.style === 'string') {\n            const diffAsStr = JSON.stringify(attribute.styleDiff);\n            const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);\n            // check if the style diff is actually shorter than the regular string based mutation\n            // (which was the whole point of #464 'compact style mutation').\n            if (diffAsStr.length < attributes.style.length) {\n              // also: CSSOM fails badly when var() is present on shorthand properties, so only proceed with\n              // the compact style mutation if these have all been accounted for\n              if (\n                (diffAsStr + unchangedAsStr).split('var(').length ===\n                attributes.style.split('var(').length\n              ) {\n                attributes.style = attribute.styleDiff;\n              }\n            }\n          }\n          return {\n            id: this.mirror.getId(attribute.node),\n            attributes: attributes,\n          };\n        })\n        // no need to include them on added elements, as they have just been serialized with up to date attribubtes\n        .filter((attribute) => !addedIds.has(attribute.id))\n        // attribute mutation's id was not in the mirror map means the target node has been removed\n        .filter((attribute) => this.mirror.has(attribute.id)),\n      removes: this.removes,\n      adds,\n    };\n    // payload may be empty if the mutations happened in some blocked elements\n    if (\n      !payload.texts.length &&\n      !payload.attributes.length &&\n      !payload.removes.length &&\n      !payload.adds.length\n    ) {\n      return;\n    }\n\n    // reset\n    this.texts = [];\n    this.attributes = [];\n    this.attributeMap = new WeakMap<Node, attributeCursor>();\n    this.removes = [];\n    this.addedSet = new Set<Node>();\n    this.movedSet = new Set<Node>();\n    this.droppedSet = new Set<Node>();\n    this.removesSubTreeCache = new Set<Node>();\n    this.movedMap = {};\n\n    this.mutationCb(payload);\n  };\n\n  private genTextAreaValueMutation = (textarea: HTMLTextAreaElement) => {\n    let item = this.attributeMap.get(textarea);\n    if (!item) {\n      item = {\n        node: textarea,\n        attributes: {},\n        styleDiff: {},\n        _unchangedStyles: {},\n      };\n      this.attributes.push(item);\n      this.attributeMap.set(textarea, item);\n    }\n    const value = Array.from(\n      dom.childNodes(textarea),\n      (cn) => dom.textContent(cn) || '',\n    ).join('');\n    item.attributes.value = maskInputValue({\n      element: textarea,\n      maskInputOptions: this.maskInputOptions,\n      tagName: textarea.tagName,\n      type: getInputType(textarea),\n      value,\n      maskInputFn: this.maskInputFn,\n    });\n  };\n\n  private processMutation = (m: mutationRecord) => {\n    if (isIgnored(m.target, this.mirror, this.slimDOMOptions)) {\n      return;\n    }\n    switch (m.type) {\n      case 'characterData': {\n        const value = dom.textContent(m.target);\n\n        if (\n          !isBlocked(m.target, this.blockClass, this.blockSelector, false) &&\n          value !== m.oldValue\n        ) {\n          this.texts.push({\n            value:\n              needMaskingText(\n                m.target,\n                this.maskTextClass,\n                this.maskTextSelector,\n                true, // checkAncestors\n              ) && value\n                ? this.maskTextFn\n                  ? this.maskTextFn(value, closestElementOfNode(m.target))\n                  : value.replace(/[\\S]/g, '*')\n                : value,\n            node: m.target,\n          });\n        }\n        break;\n      }\n      case 'attributes': {\n        const target = m.target as HTMLElement;\n        let attributeName = m.attributeName as string;\n        let value = (m.target as HTMLElement).getAttribute(attributeName);\n\n        if (attributeName === 'value') {\n          const type = getInputType(target);\n\n          value = maskInputValue({\n            element: target,\n            maskInputOptions: this.maskInputOptions,\n            tagName: target.tagName,\n            type,\n            value,\n            maskInputFn: this.maskInputFn,\n          });\n        }\n        if (\n          isBlocked(m.target, this.blockClass, this.blockSelector, false) ||\n          value === m.oldValue\n        ) {\n          return;\n        }\n\n        let item = this.attributeMap.get(m.target);\n        if (\n          target.tagName === 'IFRAME' &&\n          attributeName === 'src' &&\n          !this.keepIframeSrcFn(value as string)\n        ) {\n          if (!(target as HTMLIFrameElement).contentDocument) {\n            // we can't record it directly as we can't see into it\n            // preserve the src attribute so a decision can be taken at replay time\n            attributeName = 'rr_src';\n          } else {\n            return;\n          }\n        }\n        if (!item) {\n          item = {\n            node: m.target,\n            attributes: {},\n            styleDiff: {},\n            _unchangedStyles: {},\n          };\n          this.attributes.push(item);\n          this.attributeMap.set(m.target, item);\n        }\n\n        // Keep this property on inputs that used to be password inputs\n        // This is used to ensure we do not unmask value when using e.g. a \"Show password\" type button\n        if (\n          attributeName === 'type' &&\n          target.tagName === 'INPUT' &&\n          (m.oldValue || '').toLowerCase() === 'password'\n        ) {\n          target.setAttribute('data-rr-is-password', 'true');\n        }\n\n        if (!ignoreAttribute(target.tagName, attributeName, value)) {\n          // overwrite attribute if the mutations was triggered in same time\n          item.attributes[attributeName] = transformAttribute(\n            this.doc,\n            toLowerCase(target.tagName),\n            toLowerCase(attributeName),\n            value,\n          );\n          if (attributeName === 'style') {\n            if (!this.unattachedDoc) {\n              try {\n                // avoid upsetting original document from a Content Security point of view\n                this.unattachedDoc =\n                  document.implementation.createHTMLDocument();\n              } catch (e) {\n                // fallback to more direct method\n                this.unattachedDoc = this.doc;\n              }\n            }\n            const old = this.unattachedDoc.createElement('span');\n            if (m.oldValue) {\n              old.setAttribute('style', m.oldValue);\n            }\n            for (const pname of Array.from(target.style)) {\n              const newValue = target.style.getPropertyValue(pname);\n              const newPriority = target.style.getPropertyPriority(pname);\n              if (\n                newValue !== old.style.getPropertyValue(pname) ||\n                newPriority !== old.style.getPropertyPriority(pname)\n              ) {\n                if (newPriority === '') {\n                  item.styleDiff[pname] = newValue;\n                } else {\n                  item.styleDiff[pname] = [newValue, newPriority];\n                }\n              } else {\n                // for checking\n                item._unchangedStyles[pname] = [newValue, newPriority];\n              }\n            }\n            for (const pname of Array.from(old.style)) {\n              if (target.style.getPropertyValue(pname) === '') {\n                // \"if not set, returns the empty string\"\n                item.styleDiff[pname] = false; // delete\n              }\n            }\n          } else if (attributeName === 'open' && target.tagName === 'DIALOG') {\n            if (target.matches('dialog:modal')) {\n              item.attributes['rr_open_mode'] = 'modal';\n            } else {\n              item.attributes['rr_open_mode'] = 'non-modal';\n            }\n          }\n        }\n        break;\n      }\n      case 'childList': {\n        /**\n         * Parent is blocked, ignore all child mutations\n         */\n        if (isBlocked(m.target, this.blockClass, this.blockSelector, true))\n          return;\n\n        if ((m.target as Element).tagName === 'TEXTAREA') {\n          // children would be ignored in genAdds as they aren't in the mirror\n          this.genTextAreaValueMutation(m.target as HTMLTextAreaElement);\n          return; // any removedNodes won't have been in mirror either\n        }\n\n        m.addedNodes.forEach((n) => this.genAdds(n, m.target));\n        m.removedNodes.forEach((n) => {\n          const nodeId = this.mirror.getId(n);\n          const parentId = isShadowRoot(m.target)\n            ? this.mirror.getId(dom.host(m.target))\n            : this.mirror.getId(m.target);\n          if (\n            isBlocked(m.target, this.blockClass, this.blockSelector, false) ||\n            isIgnored(n, this.mirror, this.slimDOMOptions) ||\n            !isSerialized(n, this.mirror)\n          ) {\n            return;\n          }\n          // removed node has not been serialized yet, just remove it from the Set\n          if (this.addedSet.has(n)) {\n            deepDelete(this.addedSet, n);\n            this.droppedSet.add(n);\n          } else if (this.addedSet.has(m.target) && nodeId === -1) {\n            /**\n             * If target was newly added and removed child node was\n             * not serialized, it means the child node has been removed\n             * before callback fired, so we can ignore it because\n             * newly added node will be serialized without child nodes.\n             * TODO: verify this\n             */\n          } else if (isAncestorRemoved(m.target, this.mirror)) {\n            /**\n             * If parent id was not in the mirror map any more, it\n             * means the parent node has already been removed. So\n             * the node is also removed which we do not need to track\n             * and replay.\n             */\n          } else if (\n            this.movedSet.has(n) &&\n            this.movedMap[moveKey(nodeId, parentId)]\n          ) {\n            deepDelete(this.movedSet, n);\n          } else {\n            this.removes.push({\n              parentId,\n              id: nodeId,\n              isShadow:\n                isShadowRoot(m.target) && isNativeShadowDom(m.target)\n                  ? true\n                  : undefined,\n            });\n            processRemoves(n, this.removesSubTreeCache);\n          }\n          this.mapRemoves.push(n);\n        });\n        break;\n      }\n      default:\n        break;\n    }\n  };\n\n  /**\n   * Make sure you check if `n`'s parent is blocked before calling this function\n   * */\n  private genAdds = (n: Node, target?: Node) => {\n    // this node was already recorded in other buffer, ignore it\n    if (this.processedNodeManager.inOtherBuffer(n, this)) return;\n\n    // if n is added to set, there is no need to travel it and its' children again\n    if (this.addedSet.has(n) || this.movedSet.has(n)) return;\n\n    if (this.mirror.hasNode(n)) {\n      if (isIgnored(n, this.mirror, this.slimDOMOptions)) {\n        return;\n      }\n      this.movedSet.add(n);\n      let targetId: number | null = null;\n      if (target && this.mirror.hasNode(target)) {\n        targetId = this.mirror.getId(target);\n      }\n      if (targetId && targetId !== -1) {\n        this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;\n      }\n    } else {\n      this.addedSet.add(n);\n      this.droppedSet.delete(n);\n    }\n\n    // if this node is blocked `serializeNode` will turn it into a placeholder element\n    // but we have to remove it's children otherwise they will be added as placeholders too\n    if (!isBlocked(n, this.blockClass, this.blockSelector, false)) {\n      dom.childNodes(n).forEach((childN) => this.genAdds(childN));\n      if (hasShadowRoot(n)) {\n        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n        dom.childNodes(dom.shadowRoot(n)!).forEach((childN) => {\n          this.processedNodeManager.add(childN, this);\n          this.genAdds(childN, n);\n        });\n      }\n    }\n  };\n}\n\n/**\n * Some utils to handle the mutation observer DOM records.\n * It should be more clear to extend the native data structure\n * like Set and Map, but currently Typescript does not support\n * that.\n */\nfunction deepDelete(addsSet: Set<Node>, n: Node) {\n  addsSet.delete(n);\n  dom.childNodes(n).forEach((childN) => deepDelete(addsSet, childN));\n}\n\nfunction processRemoves(n: Node, cache: Set<Node>) {\n  const queue = [n];\n\n  while (queue.length) {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const next = queue.pop()!;\n    if (cache.has(next)) continue;\n    cache.add(next);\n    dom.childNodes(next).forEach((n) => queue.push(n));\n  }\n\n  return;\n}\n\nfunction isParentRemoved(removes: Set<Node>, n: Node, mirror: Mirror): boolean {\n  if (removes.size === 0) return false;\n  return _isParentRemoved(removes, n, mirror);\n}\n\nfunction _isParentRemoved(\n  removes: Set<Node>,\n  n: Node,\n  _mirror: Mirror,\n): boolean {\n  const node: ParentNode | null = dom.parentNode(n);\n  if (!node) return false;\n  return removes.has(node);\n}\n\nfunction isAncestorInSet(set: Set<Node>, n: Node): boolean {\n  if (set.size === 0) return false;\n  return _isAncestorInSet(set, n);\n}\n\nfunction _isAncestorInSet(set: Set<Node>, n: Node): boolean {\n  const parent = dom.parentNode(n);\n  if (!parent) {\n    return false;\n  }\n  if (set.has(parent)) {\n    return true;\n  }\n  return _isAncestorInSet(set, parent);\n}\n", "import type { ErrorHandler } from '../types';\n\ntype Callback = (...args: unknown[]) => unknown;\n\nlet errorHandler: ErrorHandler | undefined;\n\nexport function registerErrorHandler(handler: ErrorHandler | undefined) {\n  errorHandler = handler;\n}\n\nexport function unregisterErrorHandler() {\n  errorHandler = undefined;\n}\n\n/**\n * Wrap callbacks in a wrapper that allows to pass errors to a configured `errorHandler` method.\n */\nexport const callbackWrapper = <T extends Callback>(cb: T): T => {\n  if (!errorHandler) {\n    return cb;\n  }\n\n  const rrwebWrapped = ((...rest: unknown[]) => {\n    try {\n      return cb(...rest);\n    } catch (error) {\n      if (errorHandler && errorHandler(error) === true) {\n        return;\n      }\n\n      throw error;\n    }\n  }) as unknown as T;\n\n  return rrwebWrapped;\n};\n", "import {\n  type MaskInputOptions,\n  maskInputValue,\n  Mirror,\n  getInputType,\n  toLowerCase,\n} from 'rrweb-snapshot';\nimport type { FontFaceSet } from 'css-font-loading-module';\nimport {\n  throttle,\n  on,\n  hookSetter,\n  getWindowScroll,\n  getWindowHeight,\n  getWindowWidth,\n  isBlocked,\n  legacy_isTouchEvent,\n  StyleSheetMirror,\n  nowTimestamp,\n} from '../utils';\nimport { patch } from '@rrweb/utils';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport {\n  IncrementalSource,\n  MouseInteractions,\n  PointerTypes,\n  MediaInteractions,\n} from '@rrweb/types';\nimport type {\n  mutationCallBack,\n  mousemoveCallBack,\n  mousePosition,\n  mouseInteractionCallBack,\n  listenerHandler,\n  scrollCallback,\n  styleSheetRuleCallback,\n  viewportResizeCallback,\n  inputValue,\n  inputCallback,\n  hookResetter,\n  hooksParam,\n  Arguments,\n  mediaInteractionCallback,\n  canvasMutationCallback,\n  fontCallback,\n  fontParam,\n  styleDeclarationCallback,\n  IWindow,\n  SelectionRange,\n  selectionCallback,\n  customElementCallback,\n} from '@rrweb/types';\nimport MutationBuffer from './mutation';\nimport { callbackWrapper } from './error-handler';\nimport dom, { mutationObserverCtor } from '@rrweb/utils';\n\nexport const mutationBuffers: MutationBuffer[] = [];\n\n// Event.path is non-standard and used in some older browsers\ntype NonStandardEvent = Omit<Event, 'composedPath'> & {\n  path: EventTarget[];\n};\n\nfunction getEventTarget(event: Event | NonStandardEvent): EventTarget | null {\n  try {\n    if ('composedPath' in event) {\n      const path = event.composedPath();\n      if (path.length) {\n        return path[0];\n      }\n    } else if ('path' in event && event.path.length) {\n      return event.path[0];\n    }\n  } catch {\n    // fallback to `event.target` below\n  }\n\n  return event && event.target;\n}\n\nexport function initMutationObserver(\n  options: MutationBufferParam,\n  rootEl: Node,\n): MutationObserver {\n  const mutationBuffer = new MutationBuffer();\n  mutationBuffers.push(mutationBuffer);\n  // see mutation.ts for details\n  mutationBuffer.init(options);\n  const observer = new (mutationObserverCtor() as new (\n    callback: MutationCallback,\n  ) => MutationObserver)(\n    callbackWrapper(mutationBuffer.processMutations.bind(mutationBuffer)),\n  );\n  observer.observe(rootEl, {\n    attributes: true,\n    attributeOldValue: true,\n    characterData: true,\n    characterDataOldValue: true,\n    childList: true,\n    subtree: true,\n  });\n  return observer;\n}\n\nfunction initMoveObserver({\n  mousemoveCb,\n  sampling,\n  doc,\n  mirror,\n}: observerParam): listenerHandler {\n  if (sampling.mousemove === false) {\n    return () => {\n      //\n    };\n  }\n\n  const threshold =\n    typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;\n  const callbackThreshold =\n    typeof sampling.mousemoveCallback === 'number'\n      ? sampling.mousemoveCallback\n      : 500;\n\n  let positions: mousePosition[] = [];\n  let timeBaseline: number | null;\n  const wrappedCb = throttle(\n    callbackWrapper(\n      (\n        source:\n          | IncrementalSource.MouseMove\n          | IncrementalSource.TouchMove\n          | IncrementalSource.Drag,\n      ) => {\n        const totalOffset = Date.now() - timeBaseline!;\n        mousemoveCb(\n          positions.map((p) => {\n            p.timeOffset -= totalOffset;\n            return p;\n          }),\n          source,\n        );\n        positions = [];\n        timeBaseline = null;\n      },\n    ),\n    callbackThreshold,\n  );\n  const updatePosition = callbackWrapper(\n    throttle<MouseEvent | TouchEvent | DragEvent>(\n      callbackWrapper((evt) => {\n        const target = getEventTarget(evt);\n        // 'legacy' here as we could switch to https://developer.mozilla.org/en-US/docs/Web/API/Element/pointermove_event\n        const { clientX, clientY } = legacy_isTouchEvent(evt)\n          ? evt.changedTouches[0]\n          : evt;\n        if (!timeBaseline) {\n          timeBaseline = nowTimestamp();\n        }\n        positions.push({\n          x: clientX,\n          y: clientY,\n          id: mirror.getId(target as Node),\n          timeOffset: nowTimestamp() - timeBaseline,\n        });\n        // it is possible DragEvent is undefined even on devices\n        // that support event 'drag'\n        wrappedCb(\n          typeof DragEvent !== 'undefined' && evt instanceof DragEvent\n            ? IncrementalSource.Drag\n            : evt instanceof MouseEvent\n            ? IncrementalSource.MouseMove\n            : IncrementalSource.TouchMove,\n        );\n      }),\n      threshold,\n      {\n        trailing: false,\n      },\n    ),\n  );\n  const handlers = [\n    on('mousemove', updatePosition, doc),\n    on('touchmove', updatePosition, doc),\n    on('drag', updatePosition, doc),\n  ];\n  return callbackWrapper(() => {\n    handlers.forEach((h) => h());\n  });\n}\n\nfunction initMouseInteractionObserver({\n  mouseInteractionCb,\n  doc,\n  mirror,\n  blockClass,\n  blockSelector,\n  sampling,\n}: observerParam): listenerHandler {\n  if (sampling.mouseInteraction === false) {\n    return () => {\n      //\n    };\n  }\n  const disableMap: Record<string, boolean | undefined> =\n    sampling.mouseInteraction === true ||\n    sampling.mouseInteraction === undefined\n      ? {}\n      : sampling.mouseInteraction;\n\n  const handlers: listenerHandler[] = [];\n  let currentPointerType: PointerTypes | null = null;\n  const getHandler = (eventKey: keyof typeof MouseInteractions) => {\n    return (event: MouseEvent | TouchEvent | PointerEvent) => {\n      const target = getEventTarget(event) as Node;\n      if (isBlocked(target, blockClass, blockSelector, true)) {\n        return;\n      }\n      let pointerType: PointerTypes | null = null;\n      let thisEventKey = eventKey;\n      if ('pointerType' in event) {\n        switch (event.pointerType) {\n          case 'mouse':\n            pointerType = PointerTypes.Mouse;\n            break;\n          case 'touch':\n            pointerType = PointerTypes.Touch;\n            break;\n          case 'pen':\n            pointerType = PointerTypes.Pen;\n            break;\n        }\n        if (pointerType === PointerTypes.Touch) {\n          if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {\n            // we are actually listening on 'pointerdown'\n            thisEventKey = 'TouchStart';\n          } else if (\n            MouseInteractions[eventKey] === MouseInteractions.MouseUp\n          ) {\n            // we are actually listening on 'pointerup'\n            thisEventKey = 'TouchEnd';\n          }\n        } else if (pointerType === PointerTypes.Pen) {\n          // TODO: these will get incorrectly emitted as MouseDown/MouseUp\n        }\n      } else if (legacy_isTouchEvent(event)) {\n        pointerType = PointerTypes.Touch;\n      }\n      if (pointerType !== null) {\n        currentPointerType = pointerType;\n        if (\n          (thisEventKey.startsWith('Touch') &&\n            pointerType === PointerTypes.Touch) ||\n          (thisEventKey.startsWith('Mouse') &&\n            pointerType === PointerTypes.Mouse)\n        ) {\n          // don't output redundant info\n          pointerType = null;\n        }\n      } else if (MouseInteractions[eventKey] === MouseInteractions.Click) {\n        pointerType = currentPointerType;\n        currentPointerType = null; // cleanup as we've used it\n      }\n      const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;\n      if (!e) {\n        return;\n      }\n      const id = mirror.getId(target);\n      const { clientX, clientY } = e;\n      callbackWrapper(mouseInteractionCb)({\n        type: MouseInteractions[thisEventKey],\n        id,\n        x: clientX,\n        y: clientY,\n        ...(pointerType !== null && { pointerType }),\n      });\n    };\n  };\n  Object.keys(MouseInteractions)\n    .filter(\n      (key) =>\n        Number.isNaN(Number(key)) &&\n        !key.endsWith('_Departed') &&\n        disableMap[key] !== false,\n    )\n    .forEach((eventKey: keyof typeof MouseInteractions) => {\n      let eventName = toLowerCase(eventKey);\n      const handler = getHandler(eventKey);\n      if (window.PointerEvent) {\n        switch (MouseInteractions[eventKey]) {\n          case MouseInteractions.MouseDown:\n          case MouseInteractions.MouseUp:\n            eventName = eventName.replace(\n              'mouse',\n              'pointer',\n            ) as unknown as typeof eventName;\n            break;\n          case MouseInteractions.TouchStart:\n          case MouseInteractions.TouchEnd:\n            // these are handled by pointerdown/pointerup\n            return;\n        }\n      }\n      handlers.push(on(eventName, handler, doc));\n    });\n  return callbackWrapper(() => {\n    handlers.forEach((h) => h());\n  });\n}\n\nexport function initScrollObserver({\n  scrollCb,\n  doc,\n  mirror,\n  blockClass,\n  blockSelector,\n  sampling,\n}: Pick<\n  observerParam,\n  'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'blockSelector' | 'sampling'\n>): listenerHandler {\n  const updatePosition = callbackWrapper(\n    throttle<UIEvent>(\n      callbackWrapper((evt) => {\n        const target = getEventTarget(evt);\n        if (\n          !target ||\n          isBlocked(target as Node, blockClass, blockSelector, true)\n        ) {\n          return;\n        }\n        const id = mirror.getId(target as Node);\n        if (target === doc && doc.defaultView) {\n          const scrollLeftTop = getWindowScroll(doc.defaultView);\n          scrollCb({\n            id,\n            x: scrollLeftTop.left,\n            y: scrollLeftTop.top,\n          });\n        } else {\n          scrollCb({\n            id,\n            x: (target as HTMLElement).scrollLeft,\n            y: (target as HTMLElement).scrollTop,\n          });\n        }\n      }),\n      sampling.scroll || 100,\n    ),\n  );\n  return on('scroll', updatePosition, doc);\n}\n\nfunction initViewportResizeObserver(\n  { viewportResizeCb }: observerParam,\n  { win }: { win: IWindow },\n): listenerHandler {\n  let lastH = -1;\n  let lastW = -1;\n  const updateDimension = callbackWrapper(\n    throttle(\n      callbackWrapper(() => {\n        const height = getWindowHeight();\n        const width = getWindowWidth();\n        if (lastH !== height || lastW !== width) {\n          viewportResizeCb({\n            width: Number(width),\n            height: Number(height),\n          });\n          lastH = height;\n          lastW = width;\n        }\n      }),\n      200,\n    ),\n  );\n  return on('resize', updateDimension, win);\n}\n\nexport const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];\nconst lastInputValueMap: WeakMap<EventTarget, inputValue> = new WeakMap();\nfunction initInputObserver({\n  inputCb,\n  doc,\n  mirror,\n  blockClass,\n  blockSelector,\n  ignoreClass,\n  ignoreSelector,\n  maskInputOptions,\n  maskInputFn,\n  sampling,\n  userTriggeredOnInput,\n}: observerParam): listenerHandler {\n  function eventHandler(event: Event) {\n    let target = getEventTarget(event) as HTMLElement | null;\n    const userTriggered = event.isTrusted;\n    const tagName = target && target.tagName;\n\n    /**\n     * If a site changes the value 'selected' of an option element, the value of its parent element, usually a select element, will be changed as well.\n     * We can treat this change as a value change of the select element the current target belongs to.\n     */\n    if (target && tagName === 'OPTION') {\n      target = dom.parentElement(target);\n    }\n    if (\n      !target ||\n      !tagName ||\n      INPUT_TAGS.indexOf(tagName) < 0 ||\n      isBlocked(target as Node, blockClass, blockSelector, true)\n    ) {\n      return;\n    }\n\n    if (\n      target.classList.contains(ignoreClass) ||\n      (ignoreSelector && target.matches(ignoreSelector))\n    ) {\n      return;\n    }\n    let text = (target as HTMLInputElement).value;\n    let isChecked = false;\n    const type: Lowercase<string> = getInputType(target) || '';\n\n    if (type === 'radio' || type === 'checkbox') {\n      isChecked = (target as HTMLInputElement).checked;\n    } else if (\n      maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||\n      maskInputOptions[type as keyof MaskInputOptions]\n    ) {\n      text = maskInputValue({\n        element: target,\n        maskInputOptions,\n        tagName,\n        type,\n        value: text,\n        maskInputFn,\n      });\n    }\n    cbWithDedup(\n      target,\n      userTriggeredOnInput\n        ? { text, isChecked, userTriggered }\n        : { text, isChecked },\n    );\n    // if a radio was checked\n    // the other radios with the same name attribute will be unchecked.\n    const name: string | undefined = (target as HTMLInputElement).name;\n    if (type === 'radio' && name && isChecked) {\n      doc\n        .querySelectorAll(`input[type=\"radio\"][name=\"${name}\"]`)\n        .forEach((el) => {\n          if (el !== target) {\n            const text = (el as HTMLInputElement).value;\n            cbWithDedup(\n              el,\n              userTriggeredOnInput\n                ? { text, isChecked: !isChecked, userTriggered: false }\n                : { text, isChecked: !isChecked },\n            );\n          }\n        });\n    }\n  }\n  function cbWithDedup(target: EventTarget, v: inputValue) {\n    const lastInputValue = lastInputValueMap.get(target);\n    if (\n      !lastInputValue ||\n      lastInputValue.text !== v.text ||\n      lastInputValue.isChecked !== v.isChecked\n    ) {\n      lastInputValueMap.set(target, v);\n      const id = mirror.getId(target as Node);\n      callbackWrapper(inputCb)({\n        ...v,\n        id,\n      });\n    }\n  }\n  const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];\n  const handlers: Array<listenerHandler | hookResetter> = events.map(\n    (eventName) => on(eventName, callbackWrapper(eventHandler), doc),\n  );\n  const currentWindow = doc.defaultView;\n  if (!currentWindow) {\n    return () => {\n      handlers.forEach((h) => h());\n    };\n  }\n  const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(\n    currentWindow.HTMLInputElement.prototype,\n    'value',\n  );\n  const hookProperties: Array<[HTMLElement, string]> = [\n    [currentWindow.HTMLInputElement.prototype, 'value'],\n    [currentWindow.HTMLInputElement.prototype, 'checked'],\n    [currentWindow.HTMLSelectElement.prototype, 'value'],\n    [currentWindow.HTMLTextAreaElement.prototype, 'value'],\n    // Some UI library use selectedIndex to set select value\n    [currentWindow.HTMLSelectElement.prototype, 'selectedIndex'],\n    [currentWindow.HTMLOptionElement.prototype, 'selected'],\n  ];\n  if (propertyDescriptor && propertyDescriptor.set) {\n    handlers.push(\n      ...hookProperties.map((p) =>\n        hookSetter<HTMLElement>(\n          p[0],\n          p[1],\n          {\n            set() {\n              // mock to a normal event\n              callbackWrapper(eventHandler)({\n                target: this as EventTarget,\n                isTrusted: false, // userTriggered to false as this could well be programmatic\n              } as Event);\n            },\n          },\n          false,\n          currentWindow,\n        ),\n      ),\n    );\n  }\n  return callbackWrapper(() => {\n    handlers.forEach((h) => h());\n  });\n}\n\ntype GroupingCSSRule =\n  | CSSGroupingRule\n  | CSSMediaRule\n  | CSSSupportsRule\n  | CSSConditionRule;\ntype GroupingCSSRuleTypes =\n  | typeof CSSGroupingRule\n  | typeof CSSMediaRule\n  | typeof CSSSupportsRule\n  | typeof CSSConditionRule;\n\nfunction getNestedCSSRulePositions(rule: CSSRule): number[] {\n  const positions: number[] = [];\n  function recurse(childRule: CSSRule, pos: number[]) {\n    if (\n      (hasNestedCSSRule('CSSGroupingRule') &&\n        childRule.parentRule instanceof CSSGroupingRule) ||\n      (hasNestedCSSRule('CSSMediaRule') &&\n        childRule.parentRule instanceof CSSMediaRule) ||\n      (hasNestedCSSRule('CSSSupportsRule') &&\n        childRule.parentRule instanceof CSSSupportsRule) ||\n      (hasNestedCSSRule('CSSConditionRule') &&\n        childRule.parentRule instanceof CSSConditionRule)\n    ) {\n      const rules = Array.from(\n        (childRule.parentRule as GroupingCSSRule).cssRules,\n      );\n      const index = rules.indexOf(childRule);\n      pos.unshift(index);\n    } else if (childRule.parentStyleSheet) {\n      const rules = Array.from(childRule.parentStyleSheet.cssRules);\n      const index = rules.indexOf(childRule);\n      pos.unshift(index);\n    }\n    return pos;\n  }\n  return recurse(rule, positions);\n}\n\n/**\n * For StyleSheets in Element, this function retrieves id of its host element.\n * For adopted StyleSheets, this function retrieves its styleId from a styleMirror.\n */\nfunction getIdAndStyleId(\n  sheet: CSSStyleSheet | undefined | null,\n  mirror: Mirror,\n  styleMirror: StyleSheetMirror,\n): {\n  styleId?: number;\n  id?: number;\n} {\n  let id, styleId;\n  if (!sheet) return {};\n  if (sheet.ownerNode) id = mirror.getId(sheet.ownerNode as Node);\n  else styleId = styleMirror.getId(sheet);\n  return {\n    styleId,\n    id,\n  };\n}\n\nfunction initStyleSheetObserver(\n  { styleSheetRuleCb, mirror, stylesheetManager }: observerParam,\n  { win }: { win: IWindow },\n): listenerHandler {\n  if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {\n    // If, for whatever reason, CSSStyleSheet is not available, we skip the observation of stylesheets.\n    return () => {\n      // Do nothing\n    };\n  }\n\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  const insertRule = win.CSSStyleSheet.prototype.insertRule;\n  win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {\n    apply: callbackWrapper(\n      (\n        target: typeof insertRule,\n        thisArg: CSSStyleSheet,\n        argumentsList: [string, number | undefined],\n      ) => {\n        const [rule, index] = argumentsList;\n\n        const { id, styleId } = getIdAndStyleId(\n          thisArg,\n          mirror,\n          stylesheetManager.styleMirror,\n        );\n\n        if ((id && id !== -1) || (styleId && styleId !== -1)) {\n          styleSheetRuleCb({\n            id,\n            styleId,\n            adds: [{ rule, index }],\n          });\n        }\n        return target.apply(thisArg, argumentsList);\n      },\n    ),\n  });\n\n  // Support for deprecated addRule method\n  win.CSSStyleSheet.prototype.addRule = function (\n    this: CSSStyleSheet,\n    selector: string,\n    styleBlock: string,\n    index: number = this.cssRules.length,\n  ) {\n    const rule = `${selector} { ${styleBlock} }`;\n    return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule, index]);\n  };\n\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n  win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {\n    apply: callbackWrapper(\n      (\n        target: typeof deleteRule,\n        thisArg: CSSStyleSheet,\n        argumentsList: [number],\n      ) => {\n        const [index] = argumentsList;\n\n        const { id, styleId } = getIdAndStyleId(\n          thisArg,\n          mirror,\n          stylesheetManager.styleMirror,\n        );\n\n        if ((id && id !== -1) || (styleId && styleId !== -1)) {\n          styleSheetRuleCb({\n            id,\n            styleId,\n            removes: [{ index }],\n          });\n        }\n        return target.apply(thisArg, argumentsList);\n      },\n    ),\n  });\n\n  // Support for deprecated removeRule method\n  win.CSSStyleSheet.prototype.removeRule = function (\n    this: CSSStyleSheet,\n    index: number,\n  ) {\n    return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index]);\n  };\n\n  let replace: (text: string) => Promise<CSSStyleSheet>;\n\n  if (win.CSSStyleSheet.prototype.replace) {\n    // eslint-disable-next-line @typescript-eslint/unbound-method\n    replace = win.CSSStyleSheet.prototype.replace;\n    win.CSSStyleSheet.prototype.replace = new Proxy(replace, {\n      apply: callbackWrapper(\n        (\n          target: typeof replace,\n          thisArg: CSSStyleSheet,\n          argumentsList: [string],\n        ) => {\n          const [text] = argumentsList;\n\n          const { id, styleId } = getIdAndStyleId(\n            thisArg,\n            mirror,\n            stylesheetManager.styleMirror,\n          );\n\n          if ((id && id !== -1) || (styleId && styleId !== -1)) {\n            styleSheetRuleCb({\n              id,\n              styleId,\n              replace: text,\n            });\n          }\n          return target.apply(thisArg, argumentsList);\n        },\n      ),\n    });\n  }\n\n  let replaceSync: (text: string) => void;\n  if (win.CSSStyleSheet.prototype.replaceSync) {\n    // eslint-disable-next-line @typescript-eslint/unbound-method\n    replaceSync = win.CSSStyleSheet.prototype.replaceSync;\n    win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {\n      apply: callbackWrapper(\n        (\n          target: typeof replaceSync,\n          thisArg: CSSStyleSheet,\n          argumentsList: [string],\n        ) => {\n          const [text] = argumentsList;\n\n          const { id, styleId } = getIdAndStyleId(\n            thisArg,\n            mirror,\n            stylesheetManager.styleMirror,\n          );\n\n          if ((id && id !== -1) || (styleId && styleId !== -1)) {\n            styleSheetRuleCb({\n              id,\n              styleId,\n              replaceSync: text,\n            });\n          }\n          return target.apply(thisArg, argumentsList);\n        },\n      ),\n    });\n  }\n\n  const supportedNestedCSSRuleTypes: {\n    [key: string]: GroupingCSSRuleTypes;\n  } = {};\n  if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {\n    supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;\n  } else {\n    // Some browsers (Safari) don't support CSSGroupingRule\n    // https://caniuse.com/?search=cssgroupingrule\n    // fall back to monkey patching classes that would have inherited from CSSGroupingRule\n\n    if (canMonkeyPatchNestedCSSRule('CSSMediaRule')) {\n      supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;\n    }\n    if (canMonkeyPatchNestedCSSRule('CSSConditionRule')) {\n      supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;\n    }\n    if (canMonkeyPatchNestedCSSRule('CSSSupportsRule')) {\n      supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;\n    }\n  }\n\n  const unmodifiedFunctions: {\n    [key: string]: {\n      insertRule: (rule: string, index?: number) => number;\n      deleteRule: (index: number) => void;\n    };\n  } = {};\n\n  Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n    unmodifiedFunctions[typeKey] = {\n      // eslint-disable-next-line @typescript-eslint/unbound-method\n      insertRule: type.prototype.insertRule,\n      // eslint-disable-next-line @typescript-eslint/unbound-method\n      deleteRule: type.prototype.deleteRule,\n    };\n\n    type.prototype.insertRule = new Proxy(\n      unmodifiedFunctions[typeKey].insertRule,\n      {\n        apply: callbackWrapper(\n          (\n            target: typeof insertRule,\n            thisArg: CSSRule,\n            argumentsList: [string, number | undefined],\n          ) => {\n            const [rule, index] = argumentsList;\n\n            const { id, styleId } = getIdAndStyleId(\n              thisArg.parentStyleSheet,\n              mirror,\n              stylesheetManager.styleMirror,\n            );\n\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\n              styleSheetRuleCb({\n                id,\n                styleId,\n                adds: [\n                  {\n                    rule,\n                    index: [\n                      ...getNestedCSSRulePositions(thisArg),\n                      index || 0, // defaults to 0\n                    ],\n                  },\n                ],\n              });\n            }\n            return target.apply(thisArg, argumentsList);\n          },\n        ),\n      },\n    );\n\n    type.prototype.deleteRule = new Proxy(\n      unmodifiedFunctions[typeKey].deleteRule,\n      {\n        apply: callbackWrapper(\n          (\n            target: typeof deleteRule,\n            thisArg: CSSRule,\n            argumentsList: [number],\n          ) => {\n            const [index] = argumentsList;\n\n            const { id, styleId } = getIdAndStyleId(\n              thisArg.parentStyleSheet,\n              mirror,\n              stylesheetManager.styleMirror,\n            );\n\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\n              styleSheetRuleCb({\n                id,\n                styleId,\n                removes: [\n                  { index: [...getNestedCSSRulePositions(thisArg), index] },\n                ],\n              });\n            }\n            return target.apply(thisArg, argumentsList);\n          },\n        ),\n      },\n    );\n  });\n\n  return callbackWrapper(() => {\n    win.CSSStyleSheet.prototype.insertRule = insertRule;\n    win.CSSStyleSheet.prototype.deleteRule = deleteRule;\n    replace && (win.CSSStyleSheet.prototype.replace = replace);\n    replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);\n    Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n      type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;\n      type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;\n    });\n  });\n}\n\nexport function initAdoptedStyleSheetObserver(\n  {\n    mirror,\n    stylesheetManager,\n  }: Pick<observerParam, 'mirror' | 'stylesheetManager'>,\n  host: Document | ShadowRoot,\n): listenerHandler {\n  let hostId: number | null = null;\n  // host of adoptedStyleSheets is outermost document or IFrame's document\n  if (host.nodeName === '#document') hostId = mirror.getId(host);\n  // The host is a ShadowRoot.\n  else hostId = mirror.getId(dom.host(host as ShadowRoot));\n\n  const patchTarget =\n    host.nodeName === '#document'\n      ? (host as Document).defaultView?.Document\n      : host.ownerDocument?.defaultView?.ShadowRoot;\n  const originalPropertyDescriptor = patchTarget?.prototype\n    ? Object.getOwnPropertyDescriptor(\n        patchTarget?.prototype,\n        'adoptedStyleSheets',\n      )\n    : undefined;\n  if (\n    hostId === null ||\n    hostId === -1 ||\n    !patchTarget ||\n    !originalPropertyDescriptor\n  )\n    return () => {\n      //\n    };\n\n  // Patch adoptedStyleSheets by overriding the original one.\n  Object.defineProperty(host, 'adoptedStyleSheets', {\n    configurable: originalPropertyDescriptor.configurable,\n    enumerable: originalPropertyDescriptor.enumerable,\n    get(): CSSStyleSheet[] {\n      return originalPropertyDescriptor.get?.call(this) as CSSStyleSheet[];\n    },\n    set(sheets: CSSStyleSheet[]) {\n      const result = originalPropertyDescriptor.set?.call(this, sheets);\n      if (hostId !== null && hostId !== -1) {\n        try {\n          stylesheetManager.adoptStyleSheets(sheets, hostId);\n        } catch (e) {\n          // for safety\n        }\n      }\n      return result;\n    },\n  });\n\n  return callbackWrapper(() => {\n    Object.defineProperty(host, 'adoptedStyleSheets', {\n      configurable: originalPropertyDescriptor.configurable,\n      enumerable: originalPropertyDescriptor.enumerable,\n      // eslint-disable-next-line @typescript-eslint/unbound-method\n      get: originalPropertyDescriptor.get,\n      // eslint-disable-next-line @typescript-eslint/unbound-method\n      set: originalPropertyDescriptor.set,\n    });\n  });\n}\n\nfunction initStyleDeclarationObserver(\n  {\n    styleDeclarationCb,\n    mirror,\n    ignoreCSSAttributes,\n    stylesheetManager,\n  }: observerParam,\n  { win }: { win: IWindow },\n): listenerHandler {\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n  win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {\n    apply: callbackWrapper(\n      (\n        target: typeof setProperty,\n        thisArg: CSSStyleDeclaration,\n        argumentsList: [string, string, string],\n      ) => {\n        const [property, value, priority] = argumentsList;\n\n        // ignore this mutation if we do not care about this css attribute\n        if (ignoreCSSAttributes.has(property)) {\n          return setProperty.apply(thisArg, [property, value, priority]);\n        }\n        const { id, styleId } = getIdAndStyleId(\n          thisArg.parentRule?.parentStyleSheet,\n          mirror,\n          stylesheetManager.styleMirror,\n        );\n        if ((id && id !== -1) || (styleId && styleId !== -1)) {\n          styleDeclarationCb({\n            id,\n            styleId,\n            set: {\n              property,\n              value,\n              priority,\n            },\n            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n            index: getNestedCSSRulePositions(thisArg.parentRule!),\n          });\n        }\n        return target.apply(thisArg, argumentsList);\n      },\n    ),\n  });\n\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n  win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {\n    apply: callbackWrapper(\n      (\n        target: typeof removeProperty,\n        thisArg: CSSStyleDeclaration,\n        argumentsList: [string],\n      ) => {\n        const [property] = argumentsList;\n\n        // ignore this mutation if we do not care about this css attribute\n        if (ignoreCSSAttributes.has(property)) {\n          return removeProperty.apply(thisArg, [property]);\n        }\n        const { id, styleId } = getIdAndStyleId(\n          thisArg.parentRule?.parentStyleSheet,\n          mirror,\n          stylesheetManager.styleMirror,\n        );\n        if ((id && id !== -1) || (styleId && styleId !== -1)) {\n          styleDeclarationCb({\n            id,\n            styleId,\n            remove: {\n              property,\n            },\n            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n            index: getNestedCSSRulePositions(thisArg.parentRule!),\n          });\n        }\n        return target.apply(thisArg, argumentsList);\n      },\n    ),\n  });\n\n  return callbackWrapper(() => {\n    win.CSSStyleDeclaration.prototype.setProperty = setProperty;\n    win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\n  });\n}\n\nfunction initMediaInteractionObserver({\n  mediaInteractionCb,\n  blockClass,\n  blockSelector,\n  mirror,\n  sampling,\n  doc,\n}: observerParam): listenerHandler {\n  const handler = callbackWrapper((type: MediaInteractions) =>\n    throttle(\n      callbackWrapper((event: Event) => {\n        const target = getEventTarget(event);\n        if (\n          !target ||\n          isBlocked(target as Node, blockClass, blockSelector, true)\n        ) {\n          return;\n        }\n        const { currentTime, volume, muted, playbackRate, loop } =\n          target as HTMLMediaElement;\n        mediaInteractionCb({\n          type,\n          id: mirror.getId(target as Node),\n          currentTime,\n          volume,\n          muted,\n          playbackRate,\n          loop,\n        });\n      }),\n      sampling.media || 500,\n    ),\n  );\n  const handlers = [\n    on('play', handler(MediaInteractions.Play), doc),\n    on('pause', handler(MediaInteractions.Pause), doc),\n    on('seeked', handler(MediaInteractions.Seeked), doc),\n    on('volumechange', handler(MediaInteractions.VolumeChange), doc),\n    on('ratechange', handler(MediaInteractions.RateChange), doc),\n  ];\n  return callbackWrapper(() => {\n    handlers.forEach((h) => h());\n  });\n}\n\nfunction initFontObserver({ fontCb, doc }: observerParam): listenerHandler {\n  const win = doc.defaultView as IWindow;\n  if (!win) {\n    return () => {\n      //\n    };\n  }\n\n  const handlers: listenerHandler[] = [];\n\n  const fontMap = new WeakMap<FontFace, fontParam>();\n\n  const originalFontFace = win.FontFace;\n  win.FontFace = function FontFace(\n    family: string,\n    source: string | ArrayBufferLike,\n    descriptors?: FontFaceDescriptors,\n  ) {\n    const fontFace = new originalFontFace(family, source, descriptors);\n    fontMap.set(fontFace, {\n      family,\n      buffer: typeof source !== 'string',\n      descriptors,\n      fontSource:\n        typeof source === 'string'\n          ? source\n          : JSON.stringify(Array.from(new Uint8Array(source))),\n    });\n    return fontFace;\n  } as unknown as typeof FontFace;\n\n  const restoreHandler = patch(\n    doc.fonts,\n    'add',\n    function (original: (font: FontFace) => void) {\n      return function (this: FontFaceSet, fontFace: FontFace) {\n        setTimeout(\n          callbackWrapper(() => {\n            const p = fontMap.get(fontFace);\n            if (p) {\n              fontCb(p);\n              fontMap.delete(fontFace);\n            }\n          }),\n          0,\n        );\n        return original.apply(this, [fontFace]);\n      };\n    },\n  );\n\n  handlers.push(() => {\n    win.FontFace = originalFontFace;\n  });\n  handlers.push(restoreHandler);\n\n  return callbackWrapper(() => {\n    handlers.forEach((h) => h());\n  });\n}\n\nfunction initSelectionObserver(param: observerParam): listenerHandler {\n  const { doc, mirror, blockClass, blockSelector, selectionCb } = param;\n  let collapsed = true;\n\n  const updateSelection = callbackWrapper(() => {\n    const selection = doc.getSelection();\n\n    if (!selection || (collapsed && selection?.isCollapsed)) return;\n\n    collapsed = selection.isCollapsed || false;\n\n    const ranges: SelectionRange[] = [];\n    const count = selection.rangeCount || 0;\n\n    for (let i = 0; i < count; i++) {\n      const range = selection.getRangeAt(i);\n\n      const { startContainer, startOffset, endContainer, endOffset } = range;\n\n      const blocked =\n        isBlocked(startContainer, blockClass, blockSelector, true) ||\n        isBlocked(endContainer, blockClass, blockSelector, true);\n\n      if (blocked) continue;\n\n      ranges.push({\n        start: mirror.getId(startContainer),\n        startOffset,\n        end: mirror.getId(endContainer),\n        endOffset,\n      });\n    }\n\n    selectionCb({ ranges });\n  });\n\n  updateSelection();\n\n  return on('selectionchange', updateSelection);\n}\n\nfunction initCustomElementObserver({\n  doc,\n  customElementCb,\n}: observerParam): listenerHandler {\n  const win = doc.defaultView as IWindow;\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  if (!win || !win.customElements) return () => {};\n  const restoreHandler = patch(\n    win.customElements,\n    'define',\n    function (\n      original: (\n        name: string,\n        constructor: CustomElementConstructor,\n        options?: ElementDefinitionOptions,\n      ) => void,\n    ) {\n      return function (\n        name: string,\n        constructor: CustomElementConstructor,\n        options?: ElementDefinitionOptions,\n      ) {\n        try {\n          customElementCb({\n            define: {\n              name,\n            },\n          });\n        } catch (e) {\n          console.warn(`Custom element callback failed for ${name}`);\n        }\n        return original.apply(this, [name, constructor, options]);\n      };\n    },\n  );\n  return restoreHandler;\n}\n\nfunction mergeHooks(o: observerParam, hooks: hooksParam) {\n  const {\n    mutationCb,\n    mousemoveCb,\n    mouseInteractionCb,\n    scrollCb,\n    viewportResizeCb,\n    inputCb,\n    mediaInteractionCb,\n    styleSheetRuleCb,\n    styleDeclarationCb,\n    canvasMutationCb,\n    fontCb,\n    selectionCb,\n    customElementCb,\n  } = o;\n  o.mutationCb = (...p: Arguments<mutationCallBack>) => {\n    if (hooks.mutation) {\n      hooks.mutation(...p);\n    }\n    mutationCb(...p);\n  };\n  o.mousemoveCb = (...p: Arguments<mousemoveCallBack>) => {\n    if (hooks.mousemove) {\n      hooks.mousemove(...p);\n    }\n    mousemoveCb(...p);\n  };\n  o.mouseInteractionCb = (...p: Arguments<mouseInteractionCallBack>) => {\n    if (hooks.mouseInteraction) {\n      hooks.mouseInteraction(...p);\n    }\n    mouseInteractionCb(...p);\n  };\n  o.scrollCb = (...p: Arguments<scrollCallback>) => {\n    if (hooks.scroll) {\n      hooks.scroll(...p);\n    }\n    scrollCb(...p);\n  };\n  o.viewportResizeCb = (...p: Arguments<viewportResizeCallback>) => {\n    if (hooks.viewportResize) {\n      hooks.viewportResize(...p);\n    }\n    viewportResizeCb(...p);\n  };\n  o.inputCb = (...p: Arguments<inputCallback>) => {\n    if (hooks.input) {\n      hooks.input(...p);\n    }\n    inputCb(...p);\n  };\n  o.mediaInteractionCb = (...p: Arguments<mediaInteractionCallback>) => {\n    if (hooks.mediaInteaction) {\n      hooks.mediaInteaction(...p);\n    }\n    mediaInteractionCb(...p);\n  };\n  o.styleSheetRuleCb = (...p: Arguments<styleSheetRuleCallback>) => {\n    if (hooks.styleSheetRule) {\n      hooks.styleSheetRule(...p);\n    }\n    styleSheetRuleCb(...p);\n  };\n  o.styleDeclarationCb = (...p: Arguments<styleDeclarationCallback>) => {\n    if (hooks.styleDeclaration) {\n      hooks.styleDeclaration(...p);\n    }\n    styleDeclarationCb(...p);\n  };\n  o.canvasMutationCb = (...p: Arguments<canvasMutationCallback>) => {\n    if (hooks.canvasMutation) {\n      hooks.canvasMutation(...p);\n    }\n    canvasMutationCb(...p);\n  };\n  o.fontCb = (...p: Arguments<fontCallback>) => {\n    if (hooks.font) {\n      hooks.font(...p);\n    }\n    fontCb(...p);\n  };\n  o.selectionCb = (...p: Arguments<selectionCallback>) => {\n    if (hooks.selection) {\n      hooks.selection(...p);\n    }\n    selectionCb(...p);\n  };\n  o.customElementCb = (...c: Arguments<customElementCallback>) => {\n    if (hooks.customElement) {\n      hooks.customElement(...c);\n    }\n    customElementCb(...c);\n  };\n}\n\nexport function initObservers(\n  o: observerParam,\n  hooks: hooksParam = {},\n): listenerHandler {\n  const currentWindow = o.doc.defaultView; // basically document.window\n  if (!currentWindow) {\n    return () => {\n      //\n    };\n  }\n\n  mergeHooks(o, hooks);\n  let mutationObserver: MutationObserver | undefined;\n  if (o.recordDOM) {\n    mutationObserver = initMutationObserver(o, o.doc);\n  }\n  const mousemoveHandler = initMoveObserver(o);\n  const mouseInteractionHandler = initMouseInteractionObserver(o);\n  const scrollHandler = initScrollObserver(o);\n  const viewportResizeHandler = initViewportResizeObserver(o, {\n    win: currentWindow,\n  });\n  const inputHandler = initInputObserver(o);\n  const mediaInteractionHandler = initMediaInteractionObserver(o);\n\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  let styleSheetObserver = () => {};\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  let adoptedStyleSheetObserver = () => {};\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  let styleDeclarationObserver = () => {};\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  let fontObserver = () => {};\n  if (o.recordDOM) {\n    styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });\n    adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);\n    styleDeclarationObserver = initStyleDeclarationObserver(o, {\n      win: currentWindow,\n    });\n    if (o.collectFonts) {\n      fontObserver = initFontObserver(o);\n    }\n  }\n  const selectionObserver = initSelectionObserver(o);\n  const customElementObserver = initCustomElementObserver(o);\n\n  // plugins\n  const pluginHandlers: listenerHandler[] = [];\n  for (const plugin of o.plugins) {\n    pluginHandlers.push(\n      plugin.observer(plugin.callback, currentWindow, plugin.options),\n    );\n  }\n\n  return callbackWrapper(() => {\n    mutationBuffers.forEach((b) => b.reset());\n    mutationObserver?.disconnect();\n    mousemoveHandler();\n    mouseInteractionHandler();\n    scrollHandler();\n    viewportResizeHandler();\n    inputHandler();\n    mediaInteractionHandler();\n    styleSheetObserver();\n    adoptedStyleSheetObserver();\n    styleDeclarationObserver();\n    fontObserver();\n    selectionObserver();\n    customElementObserver();\n    pluginHandlers.forEach((h) => h());\n  });\n}\n\ntype CSSGroupingProp =\n  | 'CSSGroupingRule'\n  | 'CSSMediaRule'\n  | 'CSSSupportsRule'\n  | 'CSSConditionRule';\n\nfunction hasNestedCSSRule(prop: CSSGroupingProp): boolean {\n  return typeof window[prop] !== 'undefined';\n}\n\nfunction canMonkeyPatchNestedCSSRule(prop: CSSGroupingProp): boolean {\n  return Boolean(\n    typeof window[prop] !== 'undefined' &&\n      // Note: Generally, this check _shouldn't_ be necessary\n      // However, in some scenarios (e.g. jsdom) this can sometimes fail, so we check for it here\n      window[prop].prototype &&\n      'insertRule' in window[prop].prototype &&\n      'deleteRule' in window[prop].prototype,\n  );\n}\n", "import type { ICrossOriginIframeMirror } from '@rrweb/types';\nexport default class CrossOriginIframeMirror\n  implements ICrossOriginIframeMirror\n{\n  private iframeIdToRemoteIdMap: WeakMap<\n    HTMLIFrameElement,\n    Map<number, number>\n  > = new WeakMap();\n  private iframeRemoteIdToIdMap: WeakMap<\n    HTMLIFrameElement,\n    Map<number, number>\n  > = new WeakMap();\n\n  constructor(private generateIdFn: () => number) {}\n\n  getId(\n    iframe: HTMLIFrameElement,\n    remoteId: number,\n    idToRemoteMap?: Map<number, number>,\n    remoteToIdMap?: Map<number, number>,\n  ): number {\n    const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);\n    const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);\n\n    let id = idToRemoteIdMap.get(remoteId);\n    if (!id) {\n      id = this.generateIdFn();\n      idToRemoteIdMap.set(remoteId, id);\n      remoteIdToIdMap.set(id, remoteId);\n    }\n    return id;\n  }\n\n  getIds(iframe: HTMLIFrameElement, remoteId: number[]): number[] {\n    const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);\n    const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n    return remoteId.map((id) =>\n      this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap),\n    );\n  }\n\n  getRemoteId(\n    iframe: HTMLIFrameElement,\n    id: number,\n    map?: Map<number, number>,\n  ): number {\n    const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);\n\n    if (typeof id !== 'number') return id;\n\n    const remoteId = remoteIdToIdMap.get(id);\n    if (!remoteId) return -1;\n    return remoteId;\n  }\n\n  getRemoteIds(iframe: HTMLIFrameElement, ids: number[]): number[] {\n    const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n\n    return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));\n  }\n\n  reset(iframe?: HTMLIFrameElement) {\n    if (!iframe) {\n      this.iframeIdToRemoteIdMap = new WeakMap();\n      this.iframeRemoteIdToIdMap = new WeakMap();\n      return;\n    }\n    this.iframeIdToRemoteIdMap.delete(iframe);\n    this.iframeRemoteIdToIdMap.delete(iframe);\n  }\n\n  private getIdToRemoteIdMap(iframe: HTMLIFrameElement) {\n    let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);\n    if (!idToRemoteIdMap) {\n      idToRemoteIdMap = new Map();\n      this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);\n    }\n    return idToRemoteIdMap;\n  }\n\n  private getRemoteIdToIdMap(iframe: HTMLIFrameElement) {\n    let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);\n    if (!remoteIdToIdMap) {\n      remoteIdToIdMap = new Map();\n      this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);\n    }\n    return remoteIdToIdMap;\n  }\n}\n", "import type { Mirror } from 'rrweb-snapshot';\nimport { genId } from 'rrweb-snapshot';\nimport type { CrossOriginIframeMessageEvent } from '../types';\nimport CrossOriginIframeMirror from './cross-origin-iframe-mirror';\nimport { EventType, NodeType, IncrementalSource } from '@rrweb/types';\nimport type {\n  eventWithTime,\n  eventWithoutTime,\n  serializedNodeWithId,\n  mutationCallBack,\n} from '@rrweb/types';\nimport type { StylesheetManager } from './stylesheet-manager';\n\nexport class IframeManager {\n  private iframes: WeakMap<HTMLIFrameElement, true> = new WeakMap();\n  private crossOriginIframeMap: WeakMap<MessageEventSource, HTMLIFrameElement> =\n    new WeakMap();\n  public crossOriginIframeMirror = new CrossOriginIframeMirror(genId);\n  public crossOriginIframeStyleMirror: CrossOriginIframeMirror;\n  public crossOriginIframeRootIdMap: WeakMap<HTMLIFrameElement, number> =\n    new WeakMap();\n  private mirror: Mirror;\n  private mutationCb: mutationCallBack;\n  private wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;\n  private loadListener?: (iframeEl: HTMLIFrameElement) => unknown;\n  private stylesheetManager: StylesheetManager;\n  private recordCrossOriginIframes: boolean;\n\n  constructor(options: {\n    mirror: Mirror;\n    mutationCb: mutationCallBack;\n    stylesheetManager: StylesheetManager;\n    recordCrossOriginIframes: boolean;\n    wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;\n  }) {\n    this.mutationCb = options.mutationCb;\n    this.wrappedEmit = options.wrappedEmit;\n    this.stylesheetManager = options.stylesheetManager;\n    this.recordCrossOriginIframes = options.recordCrossOriginIframes;\n    this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(\n      this.stylesheetManager.styleMirror.generateId.bind(\n        this.stylesheetManager.styleMirror,\n      ),\n    );\n    this.mirror = options.mirror;\n    if (this.recordCrossOriginIframes) {\n      window.addEventListener('message', this.handleMessage.bind(this));\n    }\n  }\n\n  public addIframe(iframeEl: HTMLIFrameElement) {\n    this.iframes.set(iframeEl, true);\n    if (iframeEl.contentWindow)\n      this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);\n  }\n\n  public addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown) {\n    this.loadListener = cb;\n  }\n\n  public attachIframe(\n    iframeEl: HTMLIFrameElement,\n    childSn: serializedNodeWithId,\n  ) {\n    this.mutationCb({\n      adds: [\n        {\n          parentId: this.mirror.getId(iframeEl),\n          nextId: null,\n          node: childSn,\n        },\n      ],\n      removes: [],\n      texts: [],\n      attributes: [],\n      isAttachIframe: true,\n    });\n\n    // Receive messages (events) coming from cross-origin iframes that are nested in this same-origin iframe.\n    if (this.recordCrossOriginIframes)\n      iframeEl.contentWindow?.addEventListener(\n        'message',\n        this.handleMessage.bind(this),\n      );\n\n    this.loadListener?.(iframeEl);\n\n    if (\n      iframeEl.contentDocument &&\n      iframeEl.contentDocument.adoptedStyleSheets &&\n      iframeEl.contentDocument.adoptedStyleSheets.length > 0\n    )\n      this.stylesheetManager.adoptStyleSheets(\n        iframeEl.contentDocument.adoptedStyleSheets,\n        this.mirror.getId(iframeEl.contentDocument),\n      );\n  }\n  private handleMessage(message: MessageEvent | CrossOriginIframeMessageEvent) {\n    const crossOriginMessageEvent = message as CrossOriginIframeMessageEvent;\n    if (\n      crossOriginMessageEvent.data.type !== 'rrweb' ||\n      // To filter out the rrweb messages which are forwarded by some sites.\n      crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin\n    )\n      return;\n\n    const iframeSourceWindow = message.source;\n    if (!iframeSourceWindow) return;\n\n    const iframeEl = this.crossOriginIframeMap.get(message.source);\n    if (!iframeEl) return;\n\n    const transformedEvent = this.transformCrossOriginEvent(\n      iframeEl,\n      crossOriginMessageEvent.data.event,\n    );\n\n    if (transformedEvent)\n      this.wrappedEmit(\n        transformedEvent,\n        crossOriginMessageEvent.data.isCheckout,\n      );\n  }\n\n  private transformCrossOriginEvent(\n    iframeEl: HTMLIFrameElement,\n    e: eventWithTime,\n  ): eventWithTime | false {\n    switch (e.type) {\n      case EventType.FullSnapshot: {\n        this.crossOriginIframeMirror.reset(iframeEl);\n        this.crossOriginIframeStyleMirror.reset(iframeEl);\n        /**\n         * Replaces the original id of the iframe with a new set of unique ids\n         */\n        this.replaceIdOnNode(e.data.node, iframeEl);\n        const rootId = e.data.node.id;\n        this.crossOriginIframeRootIdMap.set(iframeEl, rootId);\n        this.patchRootIdOnNode(e.data.node, rootId);\n        return {\n          timestamp: e.timestamp,\n          type: EventType.IncrementalSnapshot,\n          data: {\n            source: IncrementalSource.Mutation,\n            adds: [\n              {\n                parentId: this.mirror.getId(iframeEl),\n                nextId: null,\n                node: e.data.node,\n              },\n            ],\n            removes: [],\n            texts: [],\n            attributes: [],\n            isAttachIframe: true,\n          },\n        };\n      }\n      case EventType.Meta:\n      case EventType.Load:\n      case EventType.DomContentLoaded: {\n        return false;\n      }\n      case EventType.Plugin: {\n        return e;\n      }\n      case EventType.Custom: {\n        this.replaceIds(\n          e.data.payload as {\n            id?: unknown;\n            parentId?: unknown;\n            previousId?: unknown;\n            nextId?: unknown;\n          },\n          iframeEl,\n          ['id', 'parentId', 'previousId', 'nextId'],\n        );\n        return e;\n      }\n      case EventType.IncrementalSnapshot: {\n        switch (e.data.source) {\n          case IncrementalSource.Mutation: {\n            e.data.adds.forEach((n) => {\n              this.replaceIds(n, iframeEl, [\n                'parentId',\n                'nextId',\n                'previousId',\n              ]);\n              this.replaceIdOnNode(n.node, iframeEl);\n              const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);\n              rootId && this.patchRootIdOnNode(n.node, rootId);\n            });\n            e.data.removes.forEach((n) => {\n              this.replaceIds(n, iframeEl, ['parentId', 'id']);\n            });\n            e.data.attributes.forEach((n) => {\n              this.replaceIds(n, iframeEl, ['id']);\n            });\n            e.data.texts.forEach((n) => {\n              this.replaceIds(n, iframeEl, ['id']);\n            });\n            return e;\n          }\n          case IncrementalSource.Drag:\n          case IncrementalSource.TouchMove:\n          case IncrementalSource.MouseMove: {\n            e.data.positions.forEach((p) => {\n              this.replaceIds(p, iframeEl, ['id']);\n            });\n            return e;\n          }\n          case IncrementalSource.ViewportResize: {\n            // can safely ignore these events\n            return false;\n          }\n          case IncrementalSource.MediaInteraction:\n          case IncrementalSource.MouseInteraction:\n          case IncrementalSource.Scroll:\n          case IncrementalSource.CanvasMutation:\n          case IncrementalSource.Input: {\n            this.replaceIds(e.data, iframeEl, ['id']);\n            return e;\n          }\n          case IncrementalSource.StyleSheetRule:\n          case IncrementalSource.StyleDeclaration: {\n            this.replaceIds(e.data, iframeEl, ['id']);\n            this.replaceStyleIds(e.data, iframeEl, ['styleId']);\n            return e;\n          }\n          case IncrementalSource.Font: {\n            // fine as-is no modification needed\n            return e;\n          }\n          case IncrementalSource.Selection: {\n            e.data.ranges.forEach((range) => {\n              this.replaceIds(range, iframeEl, ['start', 'end']);\n            });\n            return e;\n          }\n          case IncrementalSource.AdoptedStyleSheet: {\n            this.replaceIds(e.data, iframeEl, ['id']);\n            this.replaceStyleIds(e.data, iframeEl, ['styleIds']);\n            e.data.styles?.forEach((style) => {\n              this.replaceStyleIds(style, iframeEl, ['styleId']);\n            });\n            return e;\n          }\n        }\n      }\n    }\n    return false;\n  }\n\n  private replace<T extends Record<string, unknown>>(\n    iframeMirror: CrossOriginIframeMirror,\n    obj: T,\n    iframeEl: HTMLIFrameElement,\n    keys: Array<keyof T>,\n  ): T {\n    for (const key of keys) {\n      if (!Array.isArray(obj[key]) && typeof obj[key] !== 'number') continue;\n      if (Array.isArray(obj[key])) {\n        obj[key] = iframeMirror.getIds(\n          iframeEl,\n          obj[key] as number[],\n        ) as T[keyof T];\n      } else {\n        (obj[key] as number) = iframeMirror.getId(iframeEl, obj[key] as number);\n      }\n    }\n\n    return obj;\n  }\n\n  private replaceIds<T extends Record<string, unknown>>(\n    obj: T,\n    iframeEl: HTMLIFrameElement,\n    keys: Array<keyof T>,\n  ): T {\n    return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);\n  }\n\n  private replaceStyleIds<T extends Record<string, unknown>>(\n    obj: T,\n    iframeEl: HTMLIFrameElement,\n    keys: Array<keyof T>,\n  ): T {\n    return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);\n  }\n\n  private replaceIdOnNode(\n    node: serializedNodeWithId,\n    iframeEl: HTMLIFrameElement,\n  ) {\n    this.replaceIds(node, iframeEl, ['id', 'rootId']);\n    if ('childNodes' in node) {\n      node.childNodes.forEach((child) => {\n        this.replaceIdOnNode(child, iframeEl);\n      });\n    }\n  }\n\n  private patchRootIdOnNode(node: serializedNodeWithId, rootId: number) {\n    if (node.type !== NodeType.Document && !node.rootId) node.rootId = rootId;\n    if ('childNodes' in node) {\n      node.childNodes.forEach((child) => {\n        this.patchRootIdOnNode(child, rootId);\n      });\n    }\n  }\n}\n", "import type { MutationBufferParam } from '../types';\nimport type {\n  mutationCallBack,\n  scrollCallback,\n  SamplingStrategy,\n} from '@rrweb/types';\nimport {\n  initMutationObserver,\n  initScrollObserver,\n  initAdoptedStyleSheetObserver,\n} from './observer';\nimport { inDom } from '../utils';\nimport type { Mirror } from 'rrweb-snapshot';\nimport { isNativeShadowDom } from 'rrweb-snapshot';\nimport dom, { patch } from '@rrweb/utils';\n\ntype BypassOptions = Omit<\n  MutationBufferParam,\n  'doc' | 'mutationCb' | 'mirror' | 'shadowDomManager'\n> & {\n  sampling: SamplingStrategy;\n};\n\nexport class ShadowDomManager {\n  private shadowDoms = new WeakSet<ShadowRoot>();\n  private mutationCb: mutationCallBack;\n  private scrollCb: scrollCallback;\n  private bypassOptions: BypassOptions;\n  private mirror: Mirror;\n  private restoreHandlers: (() => void)[] = [];\n\n  constructor(options: {\n    mutationCb: mutationCallBack;\n    scrollCb: scrollCallback;\n    bypassOptions: BypassOptions;\n    mirror: Mirror;\n  }) {\n    this.mutationCb = options.mutationCb;\n    this.scrollCb = options.scrollCb;\n    this.bypassOptions = options.bypassOptions;\n    this.mirror = options.mirror;\n\n    this.init();\n  }\n\n  public init() {\n    this.reset();\n    // Patch 'attachShadow' to observe newly added shadow doms.\n    this.patchAttachShadow(Element, document);\n  }\n\n  public addShadowRoot(shadowRoot: ShadowRoot, doc: Document) {\n    if (!isNativeShadowDom(shadowRoot)) return;\n    if (this.shadowDoms.has(shadowRoot)) return;\n    this.shadowDoms.add(shadowRoot);\n    const observer = initMutationObserver(\n      {\n        ...this.bypassOptions,\n        doc,\n        mutationCb: this.mutationCb,\n        mirror: this.mirror,\n        shadowDomManager: this,\n      },\n      shadowRoot,\n    );\n    this.restoreHandlers.push(() => observer.disconnect());\n    this.restoreHandlers.push(\n      initScrollObserver({\n        ...this.bypassOptions,\n        scrollCb: this.scrollCb,\n        // https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813\n        // scroll is not allowed to pass the boundary, so we need to listen the shadow document\n        doc: shadowRoot as unknown as Document,\n        mirror: this.mirror,\n      }),\n    );\n    // Defer this to avoid adoptedStyleSheet events being created before the full snapshot is created or attachShadow action is recorded.\n    setTimeout(() => {\n      if (\n        shadowRoot.adoptedStyleSheets &&\n        shadowRoot.adoptedStyleSheets.length > 0\n      )\n        this.bypassOptions.stylesheetManager.adoptStyleSheets(\n          shadowRoot.adoptedStyleSheets,\n          this.mirror.getId(dom.host(shadowRoot)),\n        );\n      this.restoreHandlers.push(\n        initAdoptedStyleSheetObserver(\n          {\n            mirror: this.mirror,\n            stylesheetManager: this.bypassOptions.stylesheetManager,\n          },\n          shadowRoot,\n        ),\n      );\n    }, 0);\n  }\n\n  /**\n   * Monkey patch 'attachShadow' of an IFrameElement to observe newly added shadow doms.\n   */\n  public observeAttachShadow(iframeElement: HTMLIFrameElement) {\n    if (!iframeElement.contentWindow || !iframeElement.contentDocument) return;\n\n    this.patchAttachShadow(\n      (\n        iframeElement.contentWindow as Window & {\n          Element: { prototype: Element };\n        }\n      ).Element,\n      iframeElement.contentDocument,\n    );\n  }\n\n  /**\n   * Patch 'attachShadow' to observe newly added shadow doms.\n   */\n  private patchAttachShadow(\n    element: {\n      prototype: Element;\n    },\n    doc: Document,\n  ) {\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    const manager = this;\n    this.restoreHandlers.push(\n      patch(\n        element.prototype,\n        'attachShadow',\n        function (original: (init: ShadowRootInit) => ShadowRoot) {\n          return function (this: Element, option: ShadowRootInit) {\n            const sRoot = original.call(this, option);\n            // For the shadow dom elements in the document, monitor their dom mutations.\n            // For shadow dom elements that aren't in the document yet,\n            // we start monitoring them once their shadow dom host is appended to the document.\n            const shadowRootEl = dom.shadowRoot(this);\n            if (shadowRootEl && inDom(this))\n              manager.addShadowRoot(shadowRootEl, doc);\n            return sRoot;\n          };\n        },\n      ),\n    );\n  }\n\n  public reset() {\n    this.restoreHandlers.forEach((handler) => {\n      try {\n        handler();\n      } catch (e) {\n        //\n      }\n    });\n    this.restoreHandlers = [];\n    this.shadowDoms = new WeakSet();\n  }\n}\n", "/*\n * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n    lookup[chars.charCodeAt(i)] = i;\n}\nvar encode = function (arraybuffer) {\n    var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';\n    for (i = 0; i < len; i += 3) {\n        base64 += chars[bytes[i] >> 2];\n        base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n        base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n        base64 += chars[bytes[i + 2] & 63];\n    }\n    if (len % 3 === 2) {\n        base64 = base64.substring(0, base64.length - 1) + '=';\n    }\n    else if (len % 3 === 1) {\n        base64 = base64.substring(0, base64.length - 2) + '==';\n    }\n    return base64;\n};\nvar decode = function (base64) {\n    var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n    if (base64[base64.length - 1] === '=') {\n        bufferLength--;\n        if (base64[base64.length - 2] === '=') {\n            bufferLength--;\n        }\n    }\n    var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);\n    for (i = 0; i < len; i += 4) {\n        encoded1 = lookup[base64.charCodeAt(i)];\n        encoded2 = lookup[base64.charCodeAt(i + 1)];\n        encoded3 = lookup[base64.charCodeAt(i + 2)];\n        encoded4 = lookup[base64.charCodeAt(i + 3)];\n        bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n        bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n        bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n    }\n    return arraybuffer;\n};\n\nexport { decode, encode };\n//# sourceMappingURL=base64-arraybuffer.es5.js.map\n", "import { encode } from 'base64-arraybuffer';\nimport type { IWindow, CanvasArg } from '@rrweb/types';\n\n// TODO: unify with `replay/webgl.ts`\ntype CanvasVarMap = Map<string, unknown[]>;\nconst canvasVarMap: Map<RenderingContext, CanvasVarMap> = new Map();\nexport function variableListFor(ctx: RenderingContext, ctor: string) {\n  let contextMap = canvasVarMap.get(ctx);\n  if (!contextMap) {\n    contextMap = new Map();\n    canvasVarMap.set(ctx, contextMap);\n  }\n  if (!contextMap.has(ctor)) {\n    contextMap.set(ctor, []);\n  }\n  return contextMap.get(ctor) as unknown[];\n}\n\nexport const saveWebGLVar = (\n  value: unknown,\n  win: IWindow,\n  ctx: RenderingContext,\n): number | void => {\n  if (\n    !value ||\n    !(isInstanceOfWebGLObject(value, win) || typeof value === 'object')\n  )\n    return;\n\n  const name = value.constructor.name;\n  const list = variableListFor(ctx, name);\n  let index = list.indexOf(value);\n\n  if (index === -1) {\n    index = list.length;\n    list.push(value);\n  }\n  return index;\n};\n\n// from webgl-recorder: https://github.com/evanw/webgl-recorder/blob/bef0e65596e981ee382126587e2dcbe0fc7748e2/webgl-recorder.js#L50-L77\nexport function serializeArg(\n  value: unknown,\n  win: IWindow,\n  ctx: RenderingContext,\n): CanvasArg {\n  if (value instanceof Array) {\n    return value.map((arg) => serializeArg(arg, win, ctx));\n  } else if (value === null) {\n    return value;\n  } else if (\n    value instanceof Float32Array ||\n    value instanceof Float64Array ||\n    value instanceof Int32Array ||\n    value instanceof Uint32Array ||\n    value instanceof Uint8Array ||\n    value instanceof Uint16Array ||\n    value instanceof Int16Array ||\n    value instanceof Int8Array ||\n    value instanceof Uint8ClampedArray\n  ) {\n    const name = value.constructor.name;\n    return {\n      rr_type: name,\n      args: [Object.values(value)],\n    };\n  } else if (\n    // SharedArrayBuffer disabled on most browsers due to spectre.\n    // More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/SharedArrayBuffer\n    // value instanceof SharedArrayBuffer ||\n    value instanceof ArrayBuffer\n  ) {\n    const name = value.constructor.name as 'ArrayBuffer';\n    const base64 = encode(value);\n\n    return {\n      rr_type: name,\n      base64,\n    };\n  } else if (value instanceof DataView) {\n    const name = value.constructor.name;\n    return {\n      rr_type: name,\n      args: [\n        serializeArg(value.buffer, win, ctx),\n        value.byteOffset,\n        value.byteLength,\n      ],\n    };\n  } else if (value instanceof HTMLImageElement) {\n    const name = value.constructor.name;\n    const { src } = value;\n    return {\n      rr_type: name,\n      src,\n    };\n  } else if (value instanceof HTMLCanvasElement) {\n    const name = 'HTMLImageElement';\n    // TODO: move `toDataURL` to web worker if possible\n    const src = value.toDataURL(); // heavy on large canvas\n    return {\n      rr_type: name,\n      src,\n    };\n  } else if (value instanceof ImageData) {\n    const name = value.constructor.name;\n    return {\n      rr_type: name,\n      args: [serializeArg(value.data, win, ctx), value.width, value.height],\n    };\n    // } else if (value instanceof Blob) {\n    //   const name = value.constructor.name;\n    //   return {\n    //     rr_type: name,\n    //     data: [serializeArg(await value.arrayBuffer(), win, ctx)],\n    //     type: value.type,\n    //   };\n  } else if (isInstanceOfWebGLObject(value, win) || typeof value === 'object') {\n    const name = value.constructor.name;\n    const index = saveWebGLVar(value, win, ctx) as number;\n\n    return {\n      rr_type: name,\n      index: index,\n    };\n  }\n\n  return value as unknown as CanvasArg;\n}\n\nexport const serializeArgs = (\n  args: Array<unknown>,\n  win: IWindow,\n  ctx: RenderingContext,\n) => {\n  return args.map((arg) => serializeArg(arg, win, ctx));\n};\n\nexport const isInstanceOfWebGLObject = (\n  value: unknown,\n  win: IWindow,\n): value is\n  | WebGLActiveInfo\n  | WebGLBuffer\n  | WebGLFramebuffer\n  | WebGLProgram\n  | WebGLRenderbuffer\n  | WebGLShader\n  | WebGLShaderPrecisionFormat\n  | WebGLTexture\n  | WebGLUniformLocation\n  | WebGLVertexArrayObject => {\n  const webGLConstructorNames: string[] = [\n    'WebGLActiveInfo',\n    'WebGLBuffer',\n    'WebGLFramebuffer',\n    'WebGLProgram',\n    'WebGLRenderbuffer',\n    'WebGLShader',\n    'WebGLShaderPrecisionFormat',\n    'WebGLTexture',\n    'WebGLUniformLocation',\n    'WebGLVertexArrayObject',\n    // In old Chrome versions, value won't be an instanceof WebGLVertexArrayObject.\n    'WebGLVertexArrayObjectOES',\n  ];\n  const supportedWebGLConstructorNames = webGLConstructorNames.filter(\n    (name: string) => typeof win[name as keyof Window] === 'function',\n  );\n  return Boolean(\n    supportedWebGLConstructorNames.find(\n      (name: string) => value instanceof win[name as keyof Window],\n    ),\n  );\n};\n", "import {\n  type blockClass,\n  CanvasContext,\n  type canvasManagerMutationCallback,\n  type IWindow,\n  type listenerHandler,\n} from '@rrweb/types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/utils';\nimport { serializeArgs } from './serialize-args';\n\nexport default function initCanvas2DMutationObserver(\n  cb: canvasManagerMutationCallback,\n  win: IWindow,\n  blockClass: blockClass,\n  blockSelector: string | null,\n): listenerHandler {\n  const handlers: listenerHandler[] = [];\n  const props2D = Object.getOwnPropertyNames(\n    win.CanvasRenderingContext2D.prototype,\n  );\n  for (const prop of props2D) {\n    try {\n      if (\n        typeof win.CanvasRenderingContext2D.prototype[\n          prop as keyof CanvasRenderingContext2D\n        ] !== 'function'\n      ) {\n        continue;\n      }\n      const restoreHandler = patch(\n        win.CanvasRenderingContext2D.prototype,\n        prop,\n        function (\n          original: (\n            this: CanvasRenderingContext2D,\n            ...args: unknown[]\n          ) => void,\n        ) {\n          return function (\n            this: CanvasRenderingContext2D,\n            ...args: Array<unknown>\n          ) {\n            if (!isBlocked(this.canvas, blockClass, blockSelector, true)) {\n              // Using setTimeout as toDataURL can be heavy\n              // and we'd rather not block the main thread\n              setTimeout(() => {\n                const recordArgs = serializeArgs(args, win, this);\n                cb(this.canvas, {\n                  type: CanvasContext['2D'],\n                  property: prop,\n                  args: recordArgs,\n                });\n              }, 0);\n            }\n            return original.apply(this, args);\n          };\n        },\n      );\n      handlers.push(restoreHandler);\n    } catch {\n      const hookHandler = hookSetter<CanvasRenderingContext2D>(\n        win.CanvasRenderingContext2D.prototype,\n        prop,\n        {\n          set(v) {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n            cb(this.canvas, {\n              type: CanvasContext['2D'],\n              property: prop,\n              args: [v],\n              setter: true,\n            });\n          },\n        },\n      );\n      handlers.push(hookHandler);\n    }\n  }\n  return () => {\n    handlers.forEach((h) => h());\n  };\n}\n", "import type { ICanvas } from 'rrweb-snapshot';\nimport type { blockClass, IWindow, listenerHandler } from '@rrweb/types';\nimport { isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/utils';\n\nfunction getNormalizedContextName(contextType: string) {\n  return contextType === 'experimental-webgl' ? 'webgl' : contextType;\n}\n\nexport default function initCanvasContextObserver(\n  win: IWindow,\n  blockClass: blockClass,\n  blockSelector: string | null,\n  setPreserveDrawingBufferToTrue: boolean,\n): listenerHandler {\n  const handlers: listenerHandler[] = [];\n  try {\n    const restoreHandler = patch(\n      win.HTMLCanvasElement.prototype,\n      'getContext',\n      function (\n        original: (\n          this: ICanvas | HTMLCanvasElement,\n          contextType: string,\n          ...args: Array<unknown>\n        ) => void,\n      ) {\n        return function (\n          this: ICanvas | HTMLCanvasElement,\n          contextType: string,\n          ...args: Array<unknown>\n        ) {\n          if (!isBlocked(this, blockClass, blockSelector, true)) {\n            const ctxName = getNormalizedContextName(contextType);\n            if (!('__context' in this)) (this as ICanvas).__context = ctxName;\n\n            if (\n              setPreserveDrawingBufferToTrue &&\n              ['webgl', 'webgl2'].includes(ctxName)\n            ) {\n              if (args[0] && typeof args[0] === 'object') {\n                const contextAttributes = args[0] as WebGLContextAttributes;\n                if (!contextAttributes.preserveDrawingBuffer) {\n                  contextAttributes.preserveDrawingBuffer = true;\n                }\n              } else {\n                args.splice(0, 1, {\n                  preserveDrawingBuffer: true,\n                });\n              }\n            }\n          }\n          return original.apply(this, [contextType, ...args]);\n        };\n      },\n    );\n    handlers.push(restoreHandler);\n  } catch {\n    console.error('failed to patch HTMLCanvasElement.prototype.getContext');\n  }\n  return () => {\n    handlers.forEach((h) => h());\n  };\n}\n", "import {\n  type blockClass,\n  CanvasContext,\n  type canvasManagerMutationCallback,\n  type canvasMutationWithType,\n  type IWindow,\n  type listenerHandler,\n} from '@rrweb/types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/utils';\nimport { saveWebGLVar, serializeArgs } from './serialize-args';\n\nfunction patchGLPrototype(\n  prototype: WebGLRenderingContext | WebGL2RenderingContext,\n  type: CanvasContext,\n  cb: canvasManagerMutationCallback,\n  blockClass: blockClass,\n  blockSelector: string | null,\n  win: IWindow,\n): listenerHandler[] {\n  const handlers: listenerHandler[] = [];\n\n  const props = Object.getOwnPropertyNames(prototype);\n\n  for (const prop of props) {\n    if (\n      //prop.startsWith('get') ||  // e.g. getProgramParameter, but too risky\n      [\n        'isContextLost',\n        'canvas',\n        'drawingBufferWidth',\n        'drawingBufferHeight',\n      ].includes(prop)\n    ) {\n      // skip read only propery/functions\n      continue;\n    }\n    try {\n      if (typeof prototype[prop as keyof typeof prototype] !== 'function') {\n        continue;\n      }\n      const restoreHandler = patch(\n        prototype,\n        prop,\n        function (\n          original: (this: typeof prototype, ...args: Array<unknown>) => void,\n        ) {\n          return function (this: typeof prototype, ...args: Array<unknown>) {\n            const result = original.apply(this, args);\n            saveWebGLVar(result, win, this);\n            if (\n              'tagName' in this.canvas &&\n              !isBlocked(this.canvas, blockClass, blockSelector, true)\n            ) {\n              const recordArgs = serializeArgs(args, win, this);\n              const mutation: canvasMutationWithType = {\n                type,\n                property: prop,\n                args: recordArgs,\n              };\n              // TODO: this could potentially also be an OffscreenCanvas as well as HTMLCanvasElement\n              cb(this.canvas, mutation);\n            }\n\n            return result;\n          };\n        },\n      );\n      handlers.push(restoreHandler);\n    } catch {\n      const hookHandler = hookSetter<typeof prototype>(prototype, prop, {\n        set(v) {\n          // TODO: this could potentially also be an OffscreenCanvas as well as HTMLCanvasElement\n          // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n          cb(this.canvas as HTMLCanvasElement, {\n            type,\n            property: prop,\n            args: [v],\n            setter: true,\n          });\n        },\n      });\n      handlers.push(hookHandler);\n    }\n  }\n\n  return handlers;\n}\n\nexport default function initCanvasWebGLMutationObserver(\n  cb: canvasManagerMutationCallback,\n  win: IWindow,\n  blockClass: blockClass,\n  blockSelector: string | null,\n): listenerHandler {\n  const handlers: listenerHandler[] = [];\n\n  handlers.push(\n    ...patchGLPrototype(\n      win.WebGLRenderingContext.prototype,\n      CanvasContext.WebGL,\n      cb,\n      blockClass,\n      blockSelector,\n      win,\n    ),\n  );\n\n  if (typeof win.WebGL2RenderingContext !== 'undefined') {\n    handlers.push(\n      ...patchGLPrototype(\n        win.WebGL2RenderingContext.prototype,\n        CanvasContext.WebGL2,\n        cb,\n        blockClass,\n        blockSelector,\n        win,\n      ),\n    );\n  }\n\n  return () => {\n    handlers.forEach((h) => h());\n  };\n}\n", "import type { ICanvas, Mirror } from 'rrweb-snapshot';\nimport type {\n  blockClass,\n  canvasManagerMutationCallback,\n  canvasMutationCallback,\n  canvasMutationCommand,\n  canvasMutationWithType,\n  IWindow,\n  listenerHandler,\n  CanvasArg,\n  DataURLOptions,\n} from '@rrweb/types';\nimport { isBlocked } from '../../../utils';\nimport { CanvasContext } from '@rrweb/types';\nimport initCanvas2DMutationObserver from './2d';\nimport initCanvasContextObserver from './canvas';\nimport initCanvasWebGLMutationObserver from './webgl';\nimport ImageBitmapDataURLWorker from '../../workers/image-bitmap-data-url-worker?worker&inline';\nimport type { ImageBitmapDataURLRequestWorker } from '../../workers/image-bitmap-data-url-worker';\n\nexport type RafStamps = { latestId: number; invokeId: number | null };\n\ntype pendingCanvasMutationsMap = Map<\n  HTMLCanvasElement,\n  canvasMutationWithType[]\n>;\n\nexport class CanvasManager {\n  private pendingCanvasMutations: pendingCanvasMutationsMap = new Map();\n  private rafStamps: RafStamps = { latestId: 0, invokeId: null };\n  private mirror: Mirror;\n\n  private mutationCb: canvasMutationCallback;\n  private resetObservers?: listenerHandler;\n  private frozen = false;\n  private locked = false;\n\n  public reset() {\n    this.pendingCanvasMutations.clear();\n    this.resetObservers && this.resetObservers();\n  }\n\n  public freeze() {\n    this.frozen = true;\n  }\n\n  public unfreeze() {\n    this.frozen = false;\n  }\n\n  public lock() {\n    this.locked = true;\n  }\n\n  public unlock() {\n    this.locked = false;\n  }\n\n  constructor(options: {\n    recordCanvas: boolean;\n    mutationCb: canvasMutationCallback;\n    win: IWindow;\n    blockClass: blockClass;\n    blockSelector: string | null;\n    mirror: Mirror;\n    sampling?: 'all' | number;\n    dataURLOptions: DataURLOptions;\n  }) {\n    const {\n      sampling = 'all',\n      win,\n      blockClass,\n      blockSelector,\n      recordCanvas,\n      dataURLOptions,\n    } = options;\n    this.mutationCb = options.mutationCb;\n    this.mirror = options.mirror;\n\n    if (recordCanvas && sampling === 'all')\n      this.initCanvasMutationObserver(win, blockClass, blockSelector);\n    if (recordCanvas && typeof sampling === 'number')\n      this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {\n        dataURLOptions,\n      });\n  }\n\n  private processMutation: canvasManagerMutationCallback = (\n    target,\n    mutation,\n  ) => {\n    const newFrame =\n      this.rafStamps.invokeId &&\n      this.rafStamps.latestId !== this.rafStamps.invokeId;\n    if (newFrame || !this.rafStamps.invokeId)\n      this.rafStamps.invokeId = this.rafStamps.latestId;\n\n    if (!this.pendingCanvasMutations.has(target)) {\n      this.pendingCanvasMutations.set(target, []);\n    }\n\n    this.pendingCanvasMutations.get(target)!.push(mutation);\n  };\n\n  private initCanvasFPSObserver(\n    fps: number,\n    win: IWindow,\n    blockClass: blockClass,\n    blockSelector: string | null,\n    options: {\n      dataURLOptions: DataURLOptions;\n    },\n  ) {\n    const canvasContextReset = initCanvasContextObserver(\n      win,\n      blockClass,\n      blockSelector,\n      true,\n    );\n    const snapshotInProgressMap: Map<number, boolean> = new Map();\n    const worker =\n      new ImageBitmapDataURLWorker() as ImageBitmapDataURLRequestWorker;\n    worker.onmessage = (e) => {\n      const { id } = e.data;\n      snapshotInProgressMap.set(id, false);\n\n      if (!('base64' in e.data)) return;\n\n      const { base64, type, width, height } = e.data;\n      this.mutationCb({\n        id,\n        type: CanvasContext['2D'],\n        commands: [\n          {\n            property: 'clearRect', // wipe canvas\n            args: [0, 0, width, height],\n          },\n          {\n            property: 'drawImage', // draws (semi-transparent) image\n            args: [\n              {\n                rr_type: 'ImageBitmap',\n                args: [\n                  {\n                    rr_type: 'Blob',\n                    data: [{ rr_type: 'ArrayBuffer', base64 }],\n                    type,\n                  },\n                ],\n              } as CanvasArg,\n              0,\n              0,\n            ],\n          },\n        ],\n      });\n    };\n\n    const timeBetweenSnapshots = 1000 / fps;\n    let lastSnapshotTime = 0;\n    let rafId: number;\n\n    const getCanvas = (): HTMLCanvasElement[] => {\n      const matchedCanvas: HTMLCanvasElement[] = [];\n      win.document.querySelectorAll('canvas').forEach((canvas) => {\n        if (!isBlocked(canvas, blockClass, blockSelector, true)) {\n          matchedCanvas.push(canvas);\n        }\n      });\n      return matchedCanvas;\n    };\n\n    const takeCanvasSnapshots = (timestamp: DOMHighResTimeStamp) => {\n      if (\n        lastSnapshotTime &&\n        timestamp - lastSnapshotTime < timeBetweenSnapshots\n      ) {\n        rafId = requestAnimationFrame(takeCanvasSnapshots);\n        return;\n      }\n      lastSnapshotTime = timestamp;\n\n      getCanvas()\n        // eslint-disable-next-line @typescript-eslint/no-misused-promises\n        .forEach(async (canvas: HTMLCanvasElement) => {\n          const id = this.mirror.getId(canvas);\n          if (snapshotInProgressMap.get(id)) return;\n\n          // The browser throws if the canvas is 0 in size\n          // Uncaught (in promise) DOMException: Failed to execute 'createImageBitmap' on 'Window': The source image width is 0.\n          // Assuming the same happens with height\n          if (canvas.width === 0 || canvas.height === 0) return;\n\n          snapshotInProgressMap.set(id, true);\n          if (['webgl', 'webgl2'].includes((canvas as ICanvas).__context)) {\n            // if the canvas hasn't been modified recently,\n            // its contents won't be in memory and `createImageBitmap`\n            // will return a transparent imageBitmap\n\n            const context = canvas.getContext((canvas as ICanvas).__context) as\n              | WebGLRenderingContext\n              | WebGL2RenderingContext\n              | null;\n            if (\n              context?.getContextAttributes()?.preserveDrawingBuffer === false\n            ) {\n              // Hack to load canvas back into memory so `createImageBitmap` can grab it's contents.\n              // Context: https://twitter.com/Juice10/status/1499775271758704643\n              // Preferably we set `preserveDrawingBuffer` to true, but that's not always possible,\n              // especially when canvas is loaded before rrweb.\n              // This hack can wipe the background color of the canvas in the (unlikely) event that\n              // the canvas background was changed but clear was not called directly afterwards.\n              // Example of this hack having negative side effect: https://visgl.github.io/react-map-gl/examples/layers\n              context.clear(context.COLOR_BUFFER_BIT);\n            }\n          }\n          const bitmap = await createImageBitmap(canvas);\n          worker.postMessage(\n            {\n              id,\n              bitmap,\n              width: canvas.width,\n              height: canvas.height,\n              dataURLOptions: options.dataURLOptions,\n            },\n            [bitmap],\n          );\n        });\n      rafId = requestAnimationFrame(takeCanvasSnapshots);\n    };\n\n    rafId = requestAnimationFrame(takeCanvasSnapshots);\n\n    this.resetObservers = () => {\n      canvasContextReset();\n      cancelAnimationFrame(rafId);\n    };\n  }\n\n  private initCanvasMutationObserver(\n    win: IWindow,\n    blockClass: blockClass,\n    blockSelector: string | null,\n  ): void {\n    this.startRAFTimestamping();\n    this.startPendingCanvasMutationFlusher();\n\n    const canvasContextReset = initCanvasContextObserver(\n      win,\n      blockClass,\n      blockSelector,\n      false,\n    );\n    const canvas2DReset = initCanvas2DMutationObserver(\n      this.processMutation.bind(this),\n      win,\n      blockClass,\n      blockSelector,\n    );\n\n    const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(\n      this.processMutation.bind(this),\n      win,\n      blockClass,\n      blockSelector,\n    );\n\n    this.resetObservers = () => {\n      canvasContextReset();\n      canvas2DReset();\n      canvasWebGL1and2Reset();\n    };\n  }\n\n  private startPendingCanvasMutationFlusher() {\n    requestAnimationFrame(() => this.flushPendingCanvasMutations());\n  }\n\n  private startRAFTimestamping() {\n    const setLatestRAFTimestamp = (timestamp: DOMHighResTimeStamp) => {\n      this.rafStamps.latestId = timestamp;\n      requestAnimationFrame(setLatestRAFTimestamp);\n    };\n    requestAnimationFrame(setLatestRAFTimestamp);\n  }\n\n  flushPendingCanvasMutations() {\n    this.pendingCanvasMutations.forEach(\n      (_values: canvasMutationCommand[], canvas: HTMLCanvasElement) => {\n        const id = this.mirror.getId(canvas);\n        this.flushPendingCanvasMutationFor(canvas, id);\n      },\n    );\n    requestAnimationFrame(() => this.flushPendingCanvasMutations());\n  }\n\n  flushPendingCanvasMutationFor(canvas: HTMLCanvasElement, id: number) {\n    if (this.frozen || this.locked) {\n      return;\n    }\n\n    const valuesWithType = this.pendingCanvasMutations.get(canvas);\n    if (!valuesWithType || id === -1) return;\n\n    const values = valuesWithType.map((value) => {\n      const { type, ...rest } = value;\n      return rest;\n    });\n    const { type } = valuesWithType[0];\n\n    this.mutationCb({ id, type, commands: values });\n\n    this.pendingCanvasMutations.delete(canvas);\n  }\n}\n", "import { stringifyRule } from 'rrweb-snapshot';\nimport type {\n  elementNode,\n  serializedNodeWithId,\n  adoptedStyleSheetCallback,\n  adoptedStyleSheetParam,\n  attributeMutation,\n  mutationCallBack,\n} from '@rrweb/types';\nimport { StyleSheetMirror } from '../utils';\n\nexport class StylesheetManager {\n  private trackedLinkElements: WeakSet<HTMLLinkElement> = new WeakSet();\n  private mutationCb: mutationCallBack;\n  private adoptedStyleSheetCb: adoptedStyleSheetCallback;\n  public styleMirror = new StyleSheetMirror();\n\n  constructor(options: {\n    mutationCb: mutationCallBack;\n    adoptedStyleSheetCb: adoptedStyleSheetCallback;\n  }) {\n    this.mutationCb = options.mutationCb;\n    this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;\n  }\n\n  public attachLinkElement(\n    linkEl: HTMLLinkElement,\n    childSn: serializedNodeWithId,\n  ) {\n    if ('_cssText' in (childSn as elementNode).attributes)\n      this.mutationCb({\n        adds: [],\n        removes: [],\n        texts: [],\n        attributes: [\n          {\n            id: childSn.id,\n            attributes: (childSn as elementNode)\n              .attributes as attributeMutation['attributes'],\n          },\n        ],\n      });\n\n    this.trackLinkElement(linkEl);\n  }\n\n  public trackLinkElement(linkEl: HTMLLinkElement) {\n    if (this.trackedLinkElements.has(linkEl)) return;\n\n    this.trackedLinkElements.add(linkEl);\n    this.trackStylesheetInLinkElement(linkEl);\n  }\n\n  public adoptStyleSheets(\n    sheets: CSSStyleSheet[] | readonly CSSStyleSheet[],\n    hostId: number,\n  ) {\n    if (sheets.length === 0) return;\n    const adoptedStyleSheetData: adoptedStyleSheetParam = {\n      id: hostId,\n      styleIds: [] as number[],\n    };\n    const styles: NonNullable<adoptedStyleSheetParam['styles']> = [];\n    for (const sheet of sheets) {\n      let styleId;\n      if (!this.styleMirror.has(sheet)) {\n        styleId = this.styleMirror.add(sheet);\n        styles.push({\n          styleId,\n          rules: Array.from(sheet.rules || CSSRule, (r, index) => ({\n            rule: stringifyRule(r, sheet.href),\n            index,\n          })),\n        });\n      } else styleId = this.styleMirror.getId(sheet);\n      adoptedStyleSheetData.styleIds.push(styleId);\n    }\n    if (styles.length > 0) adoptedStyleSheetData.styles = styles;\n    this.adoptedStyleSheetCb(adoptedStyleSheetData);\n  }\n\n  public reset() {\n    this.styleMirror.reset();\n    this.trackedLinkElements = new WeakSet();\n  }\n\n  // TODO: take snapshot on stylesheet reload by applying event listener\n  private trackStylesheetInLinkElement(_linkEl: HTMLLinkElement) {\n    // linkEl.addEventListener('load', () => {\n    //   // re-loaded, maybe take another snapshot?\n    // });\n  }\n}\n", "import type MutationBuffer from './mutation';\n\n/**\n * Keeps a log of nodes that could show up in multiple mutation buffer but shouldn't be handled twice.\n */\nexport default class ProcessedNodeManager {\n  private nodeMap: WeakMap<Node, Set<MutationBuffer>> = new WeakMap();\n\n  private active = false;\n\n  public inOtherBuffer(node: Node, thisBuffer: MutationBuffer) {\n    const buffers = this.nodeMap.get(node);\n    return (\n      buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer)\n    );\n  }\n\n  public add(node: Node, buffer: MutationBuffer) {\n    if (!this.active) {\n      this.active = true;\n      requestAnimationFrame(() => {\n        this.nodeMap = new WeakMap();\n        this.active = false;\n      });\n    }\n    this.nodeMap.set(node, (this.nodeMap.get(node) || new Set()).add(buffer));\n  }\n\n  public destroy() {\n    // cleanup no longer needed\n  }\n}\n", "import {\n  snapshot,\n  slimDOMDefaults,\n  type MaskInputOptions,\n  createMirror,\n} from 'rrweb-snapshot';\nimport { initObservers, mutationBuffers } from './observer';\nimport {\n  on,\n  getWindowWidth,\n  getWindowHeight,\n  getWindowScroll,\n  polyfill,\n  hasShadowRoot,\n  isSerializedIframe,\n  isSerializedStylesheet,\n  nowTimestamp,\n} from '../utils';\nimport type { recordOptions } from '../types';\nimport {\n  EventType,\n  type eventWithoutTime,\n  type eventWithTime,\n  IncrementalSource,\n  type listenerHandler,\n  type mutationCallbackParam,\n  type scrollCallback,\n  type canvasMutationParam,\n  type adoptedStyleSheetParam,\n} from '@rrweb/types';\nimport type { CrossOriginIframeMessageEventContent } from '../types';\nimport { IframeManager } from './iframe-manager';\nimport { ShadowDomManager } from './shadow-dom-manager';\nimport { CanvasManager } from './observers/canvas/canvas-manager';\nimport { StylesheetManager } from './stylesheet-manager';\nimport ProcessedNodeManager from './processed-node-manager';\nimport {\n  callbackWrapper,\n  registerErrorHandler,\n  unregisterErrorHandler,\n} from './error-handler';\nimport dom from '@rrweb/utils';\n\nlet wrappedEmit!: (e: eventWithoutTime, isCheckout?: boolean) => void;\n\nlet takeFullSnapshot!: (isCheckout?: boolean) => void;\nlet canvasManager!: CanvasManager;\nlet recording = false;\n\n// Multiple tools (i.e. MooTools, Prototype.js) override Array.from and drop support for the 2nd parameter\n// Try to pull a clean implementation from a newly created iframe\ntry {\n  if (Array.from([1], (x) => x * 2)[0] !== 2) {\n    const cleanFrame = document.createElement('iframe');\n    document.body.appendChild(cleanFrame);\n    // eslint-disable-next-line @typescript-eslint/unbound-method -- Array.from is static and doesn't rely on binding\n    Array.from = cleanFrame.contentWindow?.Array.from || Array.from;\n    document.body.removeChild(cleanFrame);\n  }\n} catch (err) {\n  console.debug('Unable to override Array.from', err);\n}\n\nconst mirror = createMirror();\nfunction record<T = eventWithTime>(\n  options: recordOptions<T> = {},\n): listenerHandler | undefined {\n  const {\n    emit,\n    checkoutEveryNms,\n    checkoutEveryNth,\n    blockClass = 'rr-block',\n    blockSelector = null,\n    ignoreClass = 'rr-ignore',\n    ignoreSelector = null,\n    maskTextClass = 'rr-mask',\n    maskTextSelector = null,\n    inlineStylesheet = true,\n    maskAllInputs,\n    maskInputOptions: _maskInputOptions,\n    slimDOMOptions: _slimDOMOptions,\n    maskInputFn,\n    maskTextFn,\n    hooks,\n    packFn,\n    sampling = {},\n    dataURLOptions = {},\n    mousemoveWait,\n    recordDOM = true,\n    recordCanvas = false,\n    recordCrossOriginIframes = false,\n    recordAfter = options.recordAfter === 'DOMContentLoaded'\n      ? options.recordAfter\n      : 'load',\n    userTriggeredOnInput = false,\n    collectFonts = false,\n    inlineImages = false,\n    plugins,\n    keepIframeSrcFn = () => false,\n    ignoreCSSAttributes = new Set([]),\n    errorHandler,\n  } = options;\n\n  registerErrorHandler(errorHandler);\n\n  const inEmittingFrame = recordCrossOriginIframes\n    ? window.parent === window\n    : true;\n\n  let passEmitsToParent = false;\n  if (!inEmittingFrame) {\n    try {\n      // throws if parent is cross-origin\n      if (window.parent.document) {\n        passEmitsToParent = false; // if parent is same origin we collect iframe events from the parent\n      }\n    } catch (e) {\n      passEmitsToParent = true;\n    }\n  }\n\n  // runtime checks for user options\n  if (inEmittingFrame && !emit) {\n    throw new Error('emit function is required');\n  }\n  if (!inEmittingFrame && !passEmitsToParent) {\n    return () => {\n      /* no-op since in this case we don't need to record anything from this frame in particular */\n    };\n  }\n  // move departed options to new options\n  if (mousemoveWait !== undefined && sampling.mousemove === undefined) {\n    sampling.mousemove = mousemoveWait;\n  }\n\n  // reset mirror in case `record` this was called earlier\n  mirror.reset();\n\n  const maskInputOptions: MaskInputOptions =\n    maskAllInputs === true\n      ? {\n          color: true,\n          date: true,\n          'datetime-local': true,\n          email: true,\n          month: true,\n          number: true,\n          range: true,\n          search: true,\n          tel: true,\n          text: true,\n          time: true,\n          url: true,\n          week: true,\n          textarea: true,\n          select: true,\n          password: true,\n        }\n      : _maskInputOptions !== undefined\n      ? _maskInputOptions\n      : { password: true };\n\n  const slimDOMOptions = slimDOMDefaults(_slimDOMOptions);\n\n  polyfill();\n\n  let lastFullSnapshotEvent: eventWithTime;\n  let incrementalSnapshotCount = 0;\n\n  const eventProcessor = (e: eventWithTime): T => {\n    for (const plugin of plugins || []) {\n      if (plugin.eventProcessor) {\n        e = plugin.eventProcessor(e);\n      }\n    }\n    if (\n      packFn &&\n      // Disable packing events which will be emitted to parent frames.\n      !passEmitsToParent\n    ) {\n      e = packFn(e) as unknown as eventWithTime;\n    }\n    return e as unknown as T;\n  };\n  wrappedEmit = (r: eventWithoutTime, isCheckout?: boolean) => {\n    const e = r as eventWithTime;\n    e.timestamp = nowTimestamp();\n    if (\n      mutationBuffers[0]?.isFrozen() &&\n      e.type !== EventType.FullSnapshot &&\n      !(\n        e.type === EventType.IncrementalSnapshot &&\n        e.data.source === IncrementalSource.Mutation\n      )\n    ) {\n      // we've got a user initiated event so first we need to apply\n      // all DOM changes that have been buffering during paused state\n      mutationBuffers.forEach((buf) => buf.unfreeze());\n    }\n\n    if (inEmittingFrame) {\n      emit?.(eventProcessor(e), isCheckout);\n    } else if (passEmitsToParent) {\n      const message: CrossOriginIframeMessageEventContent<T> = {\n        type: 'rrweb',\n        event: eventProcessor(e),\n        origin: window.location.origin,\n        isCheckout,\n      };\n      window.parent.postMessage(message, '*');\n    }\n\n    if (e.type === EventType.FullSnapshot) {\n      lastFullSnapshotEvent = e;\n      incrementalSnapshotCount = 0;\n    } else if (e.type === EventType.IncrementalSnapshot) {\n      // attach iframe should be considered as full snapshot\n      if (\n        e.data.source === IncrementalSource.Mutation &&\n        e.data.isAttachIframe\n      ) {\n        return;\n      }\n\n      incrementalSnapshotCount++;\n      const exceedCount =\n        checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;\n      const exceedTime =\n        checkoutEveryNms &&\n        e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;\n      if (exceedCount || exceedTime) {\n        takeFullSnapshot(true);\n      }\n    }\n  };\n\n  const wrappedMutationEmit = (m: mutationCallbackParam) => {\n    wrappedEmit({\n      type: EventType.IncrementalSnapshot,\n      data: {\n        source: IncrementalSource.Mutation,\n        ...m,\n      },\n    });\n  };\n  const wrappedScrollEmit: scrollCallback = (p) =>\n    wrappedEmit({\n      type: EventType.IncrementalSnapshot,\n      data: {\n        source: IncrementalSource.Scroll,\n        ...p,\n      },\n    });\n  const wrappedCanvasMutationEmit = (p: canvasMutationParam) =>\n    wrappedEmit({\n      type: EventType.IncrementalSnapshot,\n      data: {\n        source: IncrementalSource.CanvasMutation,\n        ...p,\n      },\n    });\n\n  const wrappedAdoptedStyleSheetEmit = (a: adoptedStyleSheetParam) =>\n    wrappedEmit({\n      type: EventType.IncrementalSnapshot,\n      data: {\n        source: IncrementalSource.AdoptedStyleSheet,\n        ...a,\n      },\n    });\n\n  const stylesheetManager = new StylesheetManager({\n    mutationCb: wrappedMutationEmit,\n    adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit,\n  });\n\n  const iframeManager = new IframeManager({\n    mirror,\n    mutationCb: wrappedMutationEmit,\n    stylesheetManager: stylesheetManager,\n    recordCrossOriginIframes,\n    wrappedEmit,\n  });\n\n  /**\n   * Exposes mirror to the plugins\n   */\n  for (const plugin of plugins || []) {\n    if (plugin.getMirror)\n      plugin.getMirror({\n        nodeMirror: mirror,\n        crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,\n        crossOriginIframeStyleMirror:\n          iframeManager.crossOriginIframeStyleMirror,\n      });\n  }\n\n  const processedNodeManager = new ProcessedNodeManager();\n\n  canvasManager = new CanvasManager({\n    recordCanvas,\n    mutationCb: wrappedCanvasMutationEmit,\n    win: window,\n    blockClass,\n    blockSelector,\n    mirror,\n    sampling: sampling.canvas,\n    dataURLOptions,\n  });\n\n  const shadowDomManager = new ShadowDomManager({\n    mutationCb: wrappedMutationEmit,\n    scrollCb: wrappedScrollEmit,\n    bypassOptions: {\n      blockClass,\n      blockSelector,\n      maskTextClass,\n      maskTextSelector,\n      inlineStylesheet,\n      maskInputOptions,\n      dataURLOptions,\n      maskTextFn,\n      maskInputFn,\n      recordCanvas,\n      inlineImages,\n      sampling,\n      slimDOMOptions,\n      iframeManager,\n      stylesheetManager,\n      canvasManager,\n      keepIframeSrcFn,\n      processedNodeManager,\n    },\n    mirror,\n  });\n\n  takeFullSnapshot = (isCheckout = false) => {\n    if (!recordDOM) {\n      return;\n    }\n    wrappedEmit(\n      {\n        type: EventType.Meta,\n        data: {\n          href: window.location.href,\n          width: getWindowWidth(),\n          height: getWindowHeight(),\n        },\n      },\n      isCheckout,\n    );\n\n    // When we take a full snapshot, old tracked StyleSheets need to be removed.\n    stylesheetManager.reset();\n\n    shadowDomManager.init();\n\n    mutationBuffers.forEach((buf) => buf.lock()); // don't allow any mirror modifications during snapshotting\n    const node = snapshot(document, {\n      mirror,\n      blockClass,\n      blockSelector,\n      maskTextClass,\n      maskTextSelector,\n      inlineStylesheet,\n      maskAllInputs: maskInputOptions,\n      maskTextFn,\n      maskInputFn,\n      slimDOM: slimDOMOptions,\n      dataURLOptions,\n      recordCanvas,\n      inlineImages,\n      onSerialize: (n) => {\n        if (isSerializedIframe(n, mirror)) {\n          iframeManager.addIframe(n as HTMLIFrameElement);\n        }\n        if (isSerializedStylesheet(n, mirror)) {\n          stylesheetManager.trackLinkElement(n as HTMLLinkElement);\n        }\n        if (hasShadowRoot(n)) {\n          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n          shadowDomManager.addShadowRoot(dom.shadowRoot(n as Node)!, document);\n        }\n      },\n      onIframeLoad: (iframe, childSn) => {\n        iframeManager.attachIframe(iframe, childSn);\n        shadowDomManager.observeAttachShadow(iframe);\n      },\n      onStylesheetLoad: (linkEl, childSn) => {\n        stylesheetManager.attachLinkElement(linkEl, childSn);\n      },\n      keepIframeSrcFn,\n    });\n\n    if (!node) {\n      return console.warn('Failed to snapshot the document');\n    }\n\n    wrappedEmit(\n      {\n        type: EventType.FullSnapshot,\n        data: {\n          node,\n          initialOffset: getWindowScroll(window),\n        },\n      },\n      isCheckout,\n    );\n    mutationBuffers.forEach((buf) => buf.unlock()); // generate & emit any mutations that happened during snapshotting, as can now apply against the newly built mirror\n\n    // Some old browsers don't support adoptedStyleSheets.\n    if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)\n      stylesheetManager.adoptStyleSheets(\n        document.adoptedStyleSheets,\n        mirror.getId(document),\n      );\n  };\n\n  try {\n    const handlers: listenerHandler[] = [];\n\n    const observe = (doc: Document) => {\n      return callbackWrapper(initObservers)(\n        {\n          mutationCb: wrappedMutationEmit,\n          mousemoveCb: (positions, source) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source,\n                positions,\n              },\n            }),\n          mouseInteractionCb: (d) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.MouseInteraction,\n                ...d,\n              },\n            }),\n          scrollCb: wrappedScrollEmit,\n          viewportResizeCb: (d) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.ViewportResize,\n                ...d,\n              },\n            }),\n          inputCb: (v) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.Input,\n                ...v,\n              },\n            }),\n          mediaInteractionCb: (p) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.MediaInteraction,\n                ...p,\n              },\n            }),\n          styleSheetRuleCb: (r) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.StyleSheetRule,\n                ...r,\n              },\n            }),\n          styleDeclarationCb: (r) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.StyleDeclaration,\n                ...r,\n              },\n            }),\n          canvasMutationCb: wrappedCanvasMutationEmit,\n          fontCb: (p) =>\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.Font,\n                ...p,\n              },\n            }),\n          selectionCb: (p) => {\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.Selection,\n                ...p,\n              },\n            });\n          },\n          customElementCb: (c) => {\n            wrappedEmit({\n              type: EventType.IncrementalSnapshot,\n              data: {\n                source: IncrementalSource.CustomElement,\n                ...c,\n              },\n            });\n          },\n          blockClass,\n          ignoreClass,\n          ignoreSelector,\n          maskTextClass,\n          maskTextSelector,\n          maskInputOptions,\n          inlineStylesheet,\n          sampling,\n          recordDOM,\n          recordCanvas,\n          inlineImages,\n          userTriggeredOnInput,\n          collectFonts,\n          doc,\n          maskInputFn,\n          maskTextFn,\n          keepIframeSrcFn,\n          blockSelector,\n          slimDOMOptions,\n          dataURLOptions,\n          mirror,\n          iframeManager,\n          stylesheetManager,\n          shadowDomManager,\n          processedNodeManager,\n          canvasManager,\n          ignoreCSSAttributes,\n          plugins:\n            plugins\n              ?.filter((p) => p.observer)\n              ?.map((p) => ({\n                observer: p.observer!,\n                options: p.options,\n                callback: (payload: object) =>\n                  wrappedEmit({\n                    type: EventType.Plugin,\n                    data: {\n                      plugin: p.name,\n                      payload,\n                    },\n                  }),\n              })) || [],\n        },\n        hooks,\n      );\n    };\n\n    iframeManager.addLoadListener((iframeEl) => {\n      try {\n        handlers.push(observe(iframeEl.contentDocument!));\n      } catch (error) {\n        // TODO: handle internal error\n        console.warn(error);\n      }\n    });\n\n    const init = () => {\n      takeFullSnapshot();\n      handlers.push(observe(document));\n      recording = true;\n    };\n    if (['interactive', 'complete'].includes(document.readyState)) {\n      init();\n    } else {\n      handlers.push(\n        on('DOMContentLoaded', () => {\n          wrappedEmit({\n            type: EventType.DomContentLoaded,\n            data: {},\n          });\n          if (recordAfter === 'DOMContentLoaded') init();\n        }),\n      );\n      handlers.push(\n        on(\n          'load',\n          () => {\n            wrappedEmit({\n              type: EventType.Load,\n              data: {},\n            });\n            if (recordAfter === 'load') init();\n          },\n          window,\n        ),\n      );\n    }\n    return () => {\n      handlers.forEach((handler) => {\n        try {\n          handler();\n        } catch (error) {\n          const msg = String(error).toLowerCase();\n          /**\n           * https://github.com/rrweb-io/rrweb/pull/1695\n           * This error can occur in a known scenario:\n           * If an iframe is initially same-origin and observed, but later its \n           location is changed in an opaque way to a cross-origin URL (perhaps within the iframe via its `document.location` or a redirect) \n           * attempting to execute the handler in the stop record function will \n           throw a \"cannot access cross-origin frame\" error.\n           * This error is expected and can be safely ignored.\n           */\n          if (!msg.includes('cross-origin')) {\n            console.warn(error);\n          }\n        }\n      });\n      processedNodeManager.destroy();\n      recording = false;\n      unregisterErrorHandler();\n    };\n  } catch (error) {\n    // TODO: handle internal error\n    console.warn(error);\n  }\n}\n\nrecord.addCustomEvent = <T>(tag: string, payload: T) => {\n  if (!recording) {\n    throw new Error('please add custom event after start recording');\n  }\n  wrappedEmit({\n    type: EventType.Custom,\n    data: {\n      tag,\n      payload,\n    },\n  });\n};\n\nrecord.freezePage = () => {\n  mutationBuffers.forEach((buf) => buf.freeze());\n};\n\nrecord.takeFullSnapshot = (isCheckout?: boolean) => {\n  if (!recording) {\n    throw new Error('please take full snapshot after start recording');\n  }\n  takeFullSnapshot(isCheckout);\n};\n\nrecord.mirror = mirror;\n\nexport default record;\n", "export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n", "/**\n * A fork version of https://github.com/iamdustan/smoothscroll\n * Add support of customize target window and document\n */\n\n/* eslint-disable */\n// @ts-nocheck\nexport function polyfill(w: Window = window, d = document) {\n  // return if scroll behavior is supported and polyfill is not forced\n  if (\n    'scrollBehavior' in d.documentElement.style &&\n    w.__forceSmoothScrollPolyfill__ !== true\n  ) {\n    return;\n  }\n\n  // globals\n  const Element = w.HTMLElement || w.Element;\n  const SCROLL_TIME = 468;\n\n  // object gathering original scroll methods\n  const original = {\n    scroll: w.scroll || w.scrollTo,\n    scrollBy: w.scrollBy,\n    elementScroll: Element.prototype.scroll || scrollElement,\n    scrollIntoView: Element.prototype.scrollIntoView,\n  };\n\n  // define timing method\n  const now =\n    w.performance && w.performance.now\n      ? w.performance.now.bind(w.performance)\n      : Date.now;\n\n  /**\n   * indicates if a the current browser is made by Microsoft\n   * @method isMicrosoftBrowser\n   * @param {String} userAgent\n   * @returns {Boolean}\n   */\n  function isMicrosoftBrowser(userAgent) {\n    const userAgentPatterns = ['MSIE ', 'Trident/', 'Edge/'];\n\n    return new RegExp(userAgentPatterns.join('|')).test(userAgent);\n  }\n\n  /*\n   * IE has rounding bug rounding down clientHeight and clientWidth and\n   * rounding up scrollHeight and scrollWidth causing false positives\n   * on hasScrollableSpace\n   */\n  const ROUNDING_TOLERANCE = isMicrosoftBrowser(w.navigator.userAgent) ? 1 : 0;\n\n  /**\n   * changes scroll position inside an element\n   * @method scrollElement\n   * @param {Number} x\n   * @param {Number} y\n   * @returns {undefined}\n   */\n  function scrollElement(x, y) {\n    this.scrollLeft = x;\n    this.scrollTop = y;\n  }\n\n  /**\n   * returns result of applying ease math function to a number\n   * @method ease\n   * @param {Number} k\n   * @returns {Number}\n   */\n  function ease(k) {\n    return 0.5 * (1 - Math.cos(Math.PI * k));\n  }\n\n  /**\n   * indicates if a smooth behavior should be applied\n   * @method shouldBailOut\n   * @param {Number|Object} firstArg\n   * @returns {Boolean}\n   */\n  function shouldBailOut(firstArg) {\n    if (\n      firstArg === null ||\n      typeof firstArg !== 'object' ||\n      firstArg.behavior === undefined ||\n      firstArg.behavior === 'auto' ||\n      firstArg.behavior === 'instant'\n    ) {\n      // first argument is not an object/null\n      // or behavior is auto, instant or undefined\n      return true;\n    }\n\n    if (typeof firstArg === 'object' && firstArg.behavior === 'smooth') {\n      // first argument is an object and behavior is smooth\n      return false;\n    }\n\n    // throw error when behavior is not supported\n    throw new TypeError(\n      'behavior member of ScrollOptions ' +\n        firstArg.behavior +\n        ' is not a valid value for enumeration ScrollBehavior.',\n    );\n  }\n\n  /**\n   * indicates if an element has scrollable space in the provided axis\n   * @method hasScrollableSpace\n   * @param {Node} el\n   * @param {String} axis\n   * @returns {Boolean}\n   */\n  function hasScrollableSpace(el, axis) {\n    if (axis === 'Y') {\n      return el.clientHeight + ROUNDING_TOLERANCE < el.scrollHeight;\n    }\n\n    if (axis === 'X') {\n      return el.clientWidth + ROUNDING_TOLERANCE < el.scrollWidth;\n    }\n  }\n\n  /**\n   * indicates if an element has a scrollable overflow property in the axis\n   * @method canOverflow\n   * @param {Node} el\n   * @param {String} axis\n   * @returns {Boolean}\n   */\n  function canOverflow(el, axis) {\n    const overflowValue = w.getComputedStyle(el, null)['overflow' + axis];\n\n    return overflowValue === 'auto' || overflowValue === 'scroll';\n  }\n\n  /**\n   * indicates if an element can be scrolled in either axis\n   * @method isScrollable\n   * @param {Node} el\n   * @param {String} axis\n   * @returns {Boolean}\n   */\n  function isScrollable(el) {\n    const isScrollableY = hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y');\n    const isScrollableX = hasScrollableSpace(el, 'X') && canOverflow(el, 'X');\n\n    return isScrollableY || isScrollableX;\n  }\n\n  /**\n   * finds scrollable parent of an element\n   * @method findScrollableParent\n   * @param {Node} el\n   * @returns {Node} el\n   */\n  function findScrollableParent(el) {\n    while (el !== d.body && isScrollable(el) === false) {\n      el = el.parentNode || el.host;\n    }\n\n    return el;\n  }\n\n  /**\n   * self invoked function that, given a context, steps through scrolling\n   * @method step\n   * @param {Object} context\n   * @returns {undefined}\n   */\n  function step(context) {\n    const time = now();\n    let value;\n    let currentX;\n    let currentY;\n    let elapsed = (time - context.startTime) / SCROLL_TIME;\n\n    // avoid elapsed times higher than one\n    elapsed = elapsed > 1 ? 1 : elapsed;\n\n    // apply easing to elapsed time\n    value = ease(elapsed);\n\n    currentX = context.startX + (context.x - context.startX) * value;\n    currentY = context.startY + (context.y - context.startY) * value;\n\n    context.method.call(context.scrollable, currentX, currentY);\n\n    // scroll more if we have not reached our destination\n    if (currentX !== context.x || currentY !== context.y) {\n      w.requestAnimationFrame(step.bind(w, context));\n    }\n  }\n\n  /**\n   * scrolls window or element with a smooth behavior\n   * @method smoothScroll\n   * @param {Object|Node} el\n   * @param {Number} x\n   * @param {Number} y\n   * @returns {undefined}\n   */\n  function smoothScroll(el, x, y) {\n    let scrollable;\n    let startX;\n    let startY;\n    let method;\n    const startTime = now();\n\n    // define scroll context\n    if (el === d.body) {\n      scrollable = w;\n      startX = w.scrollX || w.pageXOffset;\n      startY = w.scrollY || w.pageYOffset;\n      method = original.scroll;\n    } else {\n      scrollable = el;\n      startX = el.scrollLeft;\n      startY = el.scrollTop;\n      method = scrollElement;\n    }\n\n    // scroll looping over a frame\n    step({\n      scrollable: scrollable,\n      method: method,\n      startTime: startTime,\n      startX: startX,\n      startY: startY,\n      x: x,\n      y: y,\n    });\n  }\n\n  // ORIGINAL METHODS OVERRIDES\n  // w.scroll and w.scrollTo\n  w.scroll = w.scrollTo = function () {\n    // avoid action when no arguments are passed\n    if (arguments[0] === undefined) {\n      return;\n    }\n\n    // avoid smooth behavior if not required\n    if (shouldBailOut(arguments[0]) === true) {\n      original.scroll.call(\n        w,\n        arguments[0].left !== undefined\n          ? arguments[0].left\n          : typeof arguments[0] !== 'object'\n          ? arguments[0]\n          : w.scrollX || w.pageXOffset,\n        // use top prop, second argument if present or fallback to scrollY\n        arguments[0].top !== undefined\n          ? arguments[0].top\n          : arguments[1] !== undefined\n          ? arguments[1]\n          : w.scrollY || w.pageYOffset,\n      );\n\n      return;\n    }\n\n    // LET THE SMOOTHNESS BEGIN!\n    smoothScroll.call(\n      w,\n      d.body,\n      arguments[0].left !== undefined\n        ? ~~arguments[0].left\n        : w.scrollX || w.pageXOffset,\n      arguments[0].top !== undefined\n        ? ~~arguments[0].top\n        : w.scrollY || w.pageYOffset,\n    );\n  };\n\n  // w.scrollBy\n  w.scrollBy = function () {\n    // avoid action when no arguments are passed\n    if (arguments[0] === undefined) {\n      return;\n    }\n\n    // avoid smooth behavior if not required\n    if (shouldBailOut(arguments[0])) {\n      original.scrollBy.call(\n        w,\n        arguments[0].left !== undefined\n          ? arguments[0].left\n          : typeof arguments[0] !== 'object'\n          ? arguments[0]\n          : 0,\n        arguments[0].top !== undefined\n          ? arguments[0].top\n          : arguments[1] !== undefined\n          ? arguments[1]\n          : 0,\n      );\n\n      return;\n    }\n\n    // LET THE SMOOTHNESS BEGIN!\n    smoothScroll.call(\n      w,\n      d.body,\n      ~~arguments[0].left + (w.scrollX || w.pageXOffset),\n      ~~arguments[0].top + (w.scrollY || w.pageYOffset),\n    );\n  };\n\n  // Element.prototype.scroll and Element.prototype.scrollTo\n  Element.prototype.scroll = Element.prototype.scrollTo = function () {\n    // avoid action when no arguments are passed\n    if (arguments[0] === undefined) {\n      return;\n    }\n\n    // avoid smooth behavior if not required\n    if (shouldBailOut(arguments[0]) === true) {\n      // if one number is passed, throw error to match Firefox implementation\n      if (typeof arguments[0] === 'number' && arguments[1] === undefined) {\n        throw new SyntaxError('Value could not be converted');\n      }\n\n      original.elementScroll.call(\n        this,\n        // use left prop, first number argument or fallback to scrollLeft\n        arguments[0].left !== undefined\n          ? ~~arguments[0].left\n          : typeof arguments[0] !== 'object'\n          ? ~~arguments[0]\n          : this.scrollLeft,\n        // use top prop, second argument or fallback to scrollTop\n        arguments[0].top !== undefined\n          ? ~~arguments[0].top\n          : arguments[1] !== undefined\n          ? ~~arguments[1]\n          : this.scrollTop,\n      );\n\n      return;\n    }\n\n    const left = arguments[0].left;\n    const top = arguments[0].top;\n\n    // LET THE SMOOTHNESS BEGIN!\n    smoothScroll.call(\n      this,\n      this,\n      typeof left === 'undefined' ? this.scrollLeft : ~~left,\n      typeof top === 'undefined' ? this.scrollTop : ~~top,\n    );\n  };\n\n  // Element.prototype.scrollBy\n  Element.prototype.scrollBy = function () {\n    // avoid action when no arguments are passed\n    if (arguments[0] === undefined) {\n      return;\n    }\n\n    // avoid smooth behavior if not required\n    if (shouldBailOut(arguments[0]) === true) {\n      original.elementScroll.call(\n        this,\n        arguments[0].left !== undefined\n          ? ~~arguments[0].left + this.scrollLeft\n          : ~~arguments[0] + this.scrollLeft,\n        arguments[0].top !== undefined\n          ? ~~arguments[0].top + this.scrollTop\n          : ~~arguments[1] + this.scrollTop,\n      );\n\n      return;\n    }\n\n    this.scroll({\n      left: ~~arguments[0].left + this.scrollLeft,\n      top: ~~arguments[0].top + this.scrollTop,\n      behavior: arguments[0].behavior,\n    });\n  };\n\n  // Element.prototype.scrollIntoView\n  Element.prototype.scrollIntoView = function () {\n    // avoid smooth behavior if not required\n    if (shouldBailOut(arguments[0]) === true) {\n      original.scrollIntoView.call(\n        this,\n        arguments[0] === undefined ? true : arguments[0],\n      );\n\n      return;\n    }\n\n    // LET THE SMOOTHNESS BEGIN!\n    const scrollableParent = findScrollableParent(this);\n    const parentRects = scrollableParent.getBoundingClientRect();\n    const clientRects = this.getBoundingClientRect();\n\n    if (scrollableParent !== d.body) {\n      // reveal element inside parent\n      smoothScroll.call(\n        this,\n        scrollableParent,\n        scrollableParent.scrollLeft + clientRects.left - parentRects.left,\n        scrollableParent.scrollTop + clientRects.top - parentRects.top,\n      );\n\n      // reveal parent in viewport unless is fixed\n      if (w.getComputedStyle(scrollableParent).position !== 'fixed') {\n        w.scrollBy({\n          left: parentRects.left,\n          top: parentRects.top,\n          behavior: 'smooth',\n        });\n      }\n    } else {\n      // reveal element in viewport\n      w.scrollBy({\n        left: clientRects.left,\n        top: clientRects.top,\n        behavior: 'smooth',\n      });\n    }\n  };\n}\n", "import {\n  type actionWithDelay,\n  type eventWithTime,\n  EventType,\n  IncrementalSource,\n} from '@rrweb/types';\n\nexport class Timer {\n  public timeOffset = 0;\n  public speed: number;\n\n  private actions: actionWithDelay[];\n  private raf: number | true | null = null;\n  private lastTimestamp: number;\n\n  constructor(\n    actions: actionWithDelay[] = [],\n    config: {\n      speed: number;\n    },\n  ) {\n    this.actions = actions;\n    this.speed = config.speed;\n  }\n  /**\n   * Add an action, possibly after the timer starts.\n   */\n  public addAction(action: actionWithDelay) {\n    const rafWasActive = this.raf === true;\n    if (\n      !this.actions.length ||\n      this.actions[this.actions.length - 1].delay <= action.delay\n    ) {\n      // 'fast track'\n      this.actions.push(action);\n    } else {\n      // binary search - events can arrive out of order in a realtime context\n      const index = this.findActionIndex(action);\n      this.actions.splice(index, 0, action);\n    }\n    if (rafWasActive) {\n      this.raf = requestAnimationFrame(this.rafCheck.bind(this));\n    }\n  }\n\n  public start() {\n    this.timeOffset = 0;\n    this.lastTimestamp = performance.now();\n    this.raf = requestAnimationFrame(this.rafCheck.bind(this));\n  }\n\n  private rafCheck() {\n    const time = performance.now();\n    this.timeOffset += (time - this.lastTimestamp) * this.speed;\n    this.lastTimestamp = time;\n    while (this.actions.length) {\n      const action = this.actions[0];\n\n      if (this.timeOffset >= action.delay) {\n        this.actions.shift();\n        action.doAction();\n      } else {\n        break;\n      }\n    }\n    if (this.actions.length > 0) {\n      this.raf = requestAnimationFrame(this.rafCheck.bind(this));\n    } else {\n      this.raf = true; // was active\n    }\n  }\n\n  public clear() {\n    if (this.raf) {\n      if (this.raf !== true) {\n        cancelAnimationFrame(this.raf);\n      }\n      this.raf = null;\n    }\n    this.actions.length = 0;\n  }\n\n  public setSpeed(speed: number) {\n    this.speed = speed;\n  }\n\n  public isActive() {\n    return this.raf !== null;\n  }\n\n  private findActionIndex(action: actionWithDelay): number {\n    let start = 0;\n    let end = this.actions.length - 1;\n    while (start <= end) {\n      const mid = Math.floor((start + end) / 2);\n      if (this.actions[mid].delay < action.delay) {\n        start = mid + 1;\n      } else if (this.actions[mid].delay > action.delay) {\n        end = mid - 1;\n      } else {\n        // already an action with same delay (timestamp)\n        // the plus one will splice the new one after the existing one\n        return mid + 1;\n      }\n    }\n    return start;\n  }\n}\n\n// TODO: add speed to mouse move timestamp calculation\nexport function addDelay(event: eventWithTime, baselineTime: number): number {\n  // Mouse move events was recorded in a throttle function,\n  // so we need to find the real timestamp by traverse the time offsets.\n  if (\n    event.type === EventType.IncrementalSnapshot &&\n    event.data.source === IncrementalSource.MouseMove &&\n    event.data.positions &&\n    event.data.positions.length\n  ) {\n    const firstOffset = event.data.positions[0].timeOffset;\n    // timeOffset is a negative offset to event.timestamp\n    const firstTimestamp = event.timestamp + firstOffset;\n    event.delay = firstTimestamp - baselineTime;\n    return firstTimestamp - baselineTime;\n  }\n\n  event.delay = event.timestamp - baselineTime;\n  return event.delay;\n}\n", "/*! *****************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\nfunction t(t,n){var e=\"function\"==typeof Symbol&&t[Symbol.iterator];if(!e)return t;var r,o,i=e.call(t),a=[];try{for(;(void 0===n||n-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(t){o={error:t}}finally{try{r&&!r.done&&(e=i.return)&&e.call(i)}finally{if(o)throw o.error}}return a}var n;!function(t){t[t.NotStarted=0]=\"NotStarted\",t[t.Running=1]=\"Running\",t[t.Stopped=2]=\"Stopped\"}(n||(n={}));var e={type:\"xstate.init\"};function r(t){return void 0===t?[]:[].concat(t)}function o(t){return{type:\"xstate.assign\",assignment:t}}function i(t,n){return\"string\"==typeof(t=\"string\"==typeof t&&n&&n[t]?n[t]:t)?{type:t}:\"function\"==typeof t?{type:t.name,exec:t}:t}function a(t){return function(n){return t===n}}function u(t){return\"string\"==typeof t?{type:t}:t}function c(t,n){return{value:t,context:n,actions:[],changed:!1,matches:a(t)}}function f(t,n,e){var r=n,o=!1;return[t.filter((function(t){if(\"xstate.assign\"===t.type){o=!0;var n=Object.assign({},r);return\"function\"==typeof t.assignment?n=t.assignment(r,e):Object.keys(t.assignment).forEach((function(o){n[o]=\"function\"==typeof t.assignment[o]?t.assignment[o](r,e):t.assignment[o]})),r=n,!1}return!0})),r,o]}function s(n,o){void 0===o&&(o={});var s=t(f(r(n.states[n.initial].entry).map((function(t){return i(t,o.actions)})),n.context,e),2),l=s[0],v=s[1],y={config:n,_options:o,initialState:{value:n.initial,actions:l,context:v,matches:a(n.initial)},transition:function(e,o){var s,l,v=\"string\"==typeof e?{value:e,context:n.context}:e,p=v.value,g=v.context,d=u(o),x=n.states[p];if(x.on){var m=r(x.on[d.type]);try{for(var h=function(t){var n=\"function\"==typeof Symbol&&Symbol.iterator,e=n&&t[n],r=0;if(e)return e.call(t);if(t&&\"number\"==typeof t.length)return{next:function(){return t&&r>=t.length&&(t=void 0),{value:t&&t[r++],done:!t}}};throw new TypeError(n?\"Object is not iterable.\":\"Symbol.iterator is not defined.\")}(m),b=h.next();!b.done;b=h.next()){var S=b.value;if(void 0===S)return c(p,g);var w=\"string\"==typeof S?{target:S}:S,j=w.target,E=w.actions,R=void 0===E?[]:E,N=w.cond,O=void 0===N?function(){return!0}:N,_=void 0===j,k=null!=j?j:p,T=n.states[k];if(O(g,d)){var q=t(f((_?r(R):[].concat(x.exit,R,T.entry).filter((function(t){return t}))).map((function(t){return i(t,y._options.actions)})),g,d),3),z=q[0],A=q[1],B=q[2],C=null!=j?j:p;return{value:C,context:A,actions:z,changed:j!==p||z.length>0||B,matches:a(C)}}}}catch(t){s={error:t}}finally{try{b&&!b.done&&(l=h.return)&&l.call(h)}finally{if(s)throw s.error}}}return c(p,g)}};return y}var l=function(t,n){return t.actions.forEach((function(e){var r=e.exec;return r&&r(t.context,n)}))};function v(t){var r=t.initialState,o=n.NotStarted,i=new Set,c={_machine:t,send:function(e){o===n.Running&&(r=t.transition(r,e),l(r,u(e)),i.forEach((function(t){return t(r)})))},subscribe:function(t){return i.add(t),t(r),{unsubscribe:function(){return i.delete(t)}}},start:function(i){if(i){var u=\"object\"==typeof i?i:{context:t.config.context,value:i};r={value:u.value,actions:[],context:u.context,matches:a(u.value)}}return o=n.Running,l(r,e),c},stop:function(){return o=n.Stopped,i.clear(),c},get state(){return r},get status(){return o}};return c}export{n as InterpreterStatus,o as assign,s as createMachine,v as interpret};\n", "import {\n  createMachine,\n  interpret,\n  assign,\n  type StateMachine,\n} from '@xstate/fsm';\nimport type { playerConfig } from '../types';\nimport {\n  type eventWithTime,\n  ReplayerEvents,\n  EventType,\n  type Emitter,\n  IncrementalSource,\n} from '@rrweb/types';\nimport { Timer, addDelay } from './timer';\n\nexport type PlayerContext = {\n  events: eventWithTime[];\n  timer: Timer;\n  timeOffset: number;\n  baselineTime: number;\n  lastPlayedEvent: eventWithTime | null;\n};\nexport type PlayerEvent =\n  | {\n      type: 'PLAY';\n      payload: {\n        timeOffset: number;\n      };\n    }\n  | {\n      type: 'CAST_EVENT';\n      payload: {\n        event: eventWithTime;\n      };\n    }\n  | { type: 'PAUSE' }\n  | { type: 'TO_LIVE'; payload: { baselineTime?: number } }\n  | {\n      type: 'ADD_EVENT';\n      payload: {\n        event: eventWithTime;\n      };\n    }\n  | {\n      type: 'END';\n    };\nexport type PlayerState =\n  | {\n      value: 'playing';\n      context: PlayerContext;\n    }\n  | {\n      value: 'paused';\n      context: PlayerContext;\n    }\n  | {\n      value: 'live';\n      context: PlayerContext;\n    };\n\n/**\n * If the array have multiple meta and fullsnapshot events,\n * return the events from last meta to the end.\n */\nexport function discardPriorSnapshots(\n  events: eventWithTime[],\n  baselineTime: number,\n): eventWithTime[] {\n  for (let idx = events.length - 1; idx >= 0; idx--) {\n    const event = events[idx];\n    if (event.type === EventType.Meta) {\n      if (event.timestamp <= baselineTime) {\n        return events.slice(idx);\n      }\n    }\n  }\n  return events;\n}\n\ntype PlayerAssets = {\n  emitter: Emitter;\n  applyEventsSynchronously(events: Array<eventWithTime>): void;\n  getCastFn(event: eventWithTime, isSync: boolean): () => void;\n};\nexport function createPlayerService(\n  context: PlayerContext,\n  { getCastFn, applyEventsSynchronously, emitter }: PlayerAssets,\n) {\n  const playerMachine = createMachine<PlayerContext, PlayerEvent, PlayerState>(\n    {\n      id: 'player',\n      context,\n      initial: 'paused',\n      states: {\n        playing: {\n          on: {\n            PAUSE: {\n              target: 'paused',\n              actions: ['pause'],\n            },\n            CAST_EVENT: {\n              target: 'playing',\n              actions: 'castEvent',\n            },\n            END: {\n              target: 'paused',\n              actions: ['resetLastPlayedEvent', 'pause'],\n            },\n            ADD_EVENT: {\n              target: 'playing',\n              actions: ['addEvent'],\n            },\n          },\n        },\n        paused: {\n          on: {\n            PLAY: {\n              target: 'playing',\n              actions: ['recordTimeOffset', 'play'],\n            },\n            CAST_EVENT: {\n              target: 'paused',\n              actions: 'castEvent',\n            },\n            TO_LIVE: {\n              target: 'live',\n              actions: ['startLive'],\n            },\n            ADD_EVENT: {\n              target: 'paused',\n              actions: ['addEvent'],\n            },\n          },\n        },\n        live: {\n          on: {\n            ADD_EVENT: {\n              target: 'live',\n              actions: ['addEvent'],\n            },\n            CAST_EVENT: {\n              target: 'live',\n              actions: ['castEvent'],\n            },\n          },\n        },\n      },\n    },\n    {\n      actions: {\n        castEvent: assign({\n          lastPlayedEvent: (ctx, event) => {\n            if (event.type === 'CAST_EVENT') {\n              return event.payload.event;\n            }\n            return ctx.lastPlayedEvent;\n          },\n        }),\n        recordTimeOffset: assign((ctx, event) => {\n          let timeOffset = ctx.timeOffset;\n          if ('payload' in event && 'timeOffset' in event.payload) {\n            timeOffset = event.payload.timeOffset;\n          }\n          return {\n            ...ctx,\n            timeOffset,\n            baselineTime: ctx.events[0].timestamp + timeOffset,\n          };\n        }),\n        play(ctx) {\n          const { timer, events, baselineTime, lastPlayedEvent } = ctx;\n          timer.clear();\n\n          for (const event of events) {\n            // TODO: improve this API\n            addDelay(event, baselineTime);\n          }\n          const neededEvents = discardPriorSnapshots(events, baselineTime);\n\n          let lastPlayedTimestamp = lastPlayedEvent?.timestamp;\n          if (\n            lastPlayedEvent?.type === EventType.IncrementalSnapshot &&\n            lastPlayedEvent.data.source === IncrementalSource.MouseMove\n          ) {\n            lastPlayedTimestamp =\n              lastPlayedEvent.timestamp +\n              lastPlayedEvent.data.positions[0]?.timeOffset;\n          }\n          if (baselineTime < (lastPlayedTimestamp || 0)) {\n            emitter.emit(ReplayerEvents.PlayBack);\n          }\n\n          const syncEvents = new Array<eventWithTime>();\n          for (const event of neededEvents) {\n            if (\n              lastPlayedTimestamp &&\n              lastPlayedTimestamp < baselineTime &&\n              (event.timestamp <= lastPlayedTimestamp ||\n                event === lastPlayedEvent)\n            ) {\n              continue;\n            }\n            if (event.timestamp < baselineTime) {\n              syncEvents.push(event);\n            } else {\n              const castFn = getCastFn(event, false);\n              timer.addAction({\n                doAction: () => {\n                  castFn();\n                },\n                delay: event.delay!,\n              });\n            }\n          }\n          applyEventsSynchronously(syncEvents);\n          emitter.emit(ReplayerEvents.Flush);\n          timer.start();\n        },\n        pause(ctx) {\n          ctx.timer.clear();\n        },\n        resetLastPlayedEvent: assign((ctx) => {\n          return {\n            ...ctx,\n            lastPlayedEvent: null,\n          };\n        }),\n        startLive: assign({\n          baselineTime: (ctx, event) => {\n            ctx.timer.start();\n            if (event.type === 'TO_LIVE' && event.payload.baselineTime) {\n              return event.payload.baselineTime;\n            }\n            return Date.now();\n          },\n        }),\n        addEvent: assign((ctx, machineEvent) => {\n          const { baselineTime, timer, events } = ctx;\n          if (machineEvent.type === 'ADD_EVENT') {\n            const { event } = machineEvent.payload;\n            addDelay(event, baselineTime);\n\n            let end = events.length - 1;\n            if (!events[end] || events[end].timestamp <= event.timestamp) {\n              // fast track\n              events.push(event);\n            } else {\n              let insertionIndex = -1;\n              let start = 0;\n              while (start <= end) {\n                const mid = Math.floor((start + end) / 2);\n                if (events[mid].timestamp <= event.timestamp) {\n                  start = mid + 1;\n                } else {\n                  end = mid - 1;\n                }\n              }\n              if (insertionIndex === -1) {\n                insertionIndex = start;\n              }\n              events.splice(insertionIndex, 0, event);\n            }\n\n            const isSync = event.timestamp < baselineTime;\n            const castFn = getCastFn(event, isSync);\n            if (isSync) {\n              castFn();\n            } else if (timer.isActive()) {\n              timer.addAction({\n                doAction: () => {\n                  castFn();\n                },\n                delay: event.delay!,\n              });\n            }\n          }\n          return { ...ctx, events };\n        }),\n      },\n    },\n  );\n  return interpret(playerMachine);\n}\n\nexport type SpeedContext = {\n  normalSpeed: playerConfig['speed'];\n  timer: Timer;\n};\n\nexport type SpeedEvent =\n  | {\n      type: 'FAST_FORWARD';\n      payload: { speed: playerConfig['speed'] };\n    }\n  | {\n      type: 'BACK_TO_NORMAL';\n    }\n  | {\n      type: 'SET_SPEED';\n      payload: { speed: playerConfig['speed'] };\n    };\n\nexport type SpeedState =\n  | {\n      value: 'normal';\n      context: SpeedContext;\n    }\n  | {\n      value: 'skipping';\n      context: SpeedContext;\n    };\n\nexport function createSpeedService(context: SpeedContext) {\n  const speedMachine = createMachine<SpeedContext, SpeedEvent, SpeedState>(\n    {\n      id: 'speed',\n      context,\n      initial: 'normal',\n      states: {\n        normal: {\n          on: {\n            FAST_FORWARD: {\n              target: 'skipping',\n              actions: ['recordSpeed', 'setSpeed'],\n            },\n            SET_SPEED: {\n              target: 'normal',\n              actions: ['setSpeed'],\n            },\n          },\n        },\n        skipping: {\n          on: {\n            BACK_TO_NORMAL: {\n              target: 'normal',\n              actions: ['restoreSpeed'],\n            },\n            SET_SPEED: {\n              target: 'normal',\n              actions: ['setSpeed'],\n            },\n          },\n        },\n      },\n    },\n    {\n      actions: {\n        setSpeed: (ctx, event) => {\n          if ('payload' in event) {\n            ctx.timer.setSpeed(event.payload.speed);\n          }\n        },\n        recordSpeed: assign({\n          normalSpeed: (ctx) => ctx.timer.speed,\n        }),\n        restoreSpeed: (ctx) => {\n          ctx.timer.setSpeed(ctx.normalSpeed);\n        },\n      },\n    },\n  );\n\n  return interpret(speedMachine);\n}\n\nexport type PlayerMachineState = StateMachine.State<\n  PlayerContext,\n  PlayerEvent,\n  PlayerState\n>;\n\nexport type SpeedMachineState = StateMachine.State<\n  SpeedContext,\n  SpeedEvent,\n  SpeedState\n>;\n", "const rules: (blockClass: string) => string[] = (blockClass: string) => [\n  `.${blockClass} { background: currentColor }`,\n  'noscript { display: none !important; }',\n];\n\nexport default rules;\n", "import { decode } from 'base64-arraybuffer';\nimport type { Replayer } from '../';\nimport type { CanvasArg, SerializedCanvasArg } from '@rrweb/types';\n\n// TODO: add ability to wipe this list\ntype GLVarMap = Map<string, any[]>;\nconst webGLVarMap: Map<\n  CanvasRenderingContext2D | WebGLRenderingContext | WebGL2RenderingContext,\n  GLVarMap\n> = new Map();\nexport function variableListFor(\n  ctx:\n    | CanvasRenderingContext2D\n    | WebGLRenderingContext\n    | WebGL2RenderingContext,\n  ctor: string,\n) {\n  let contextMap = webGLVarMap.get(ctx);\n  if (!contextMap) {\n    contextMap = new Map();\n    webGLVarMap.set(ctx, contextMap);\n  }\n  if (!contextMap.has(ctor)) {\n    contextMap.set(ctor, []);\n  }\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n  return contextMap.get(ctor) as any[];\n}\n\nexport function isSerializedArg(arg: unknown): arg is SerializedCanvasArg {\n  return Boolean(arg && typeof arg === 'object' && 'rr_type' in arg);\n}\n\nexport function deserializeArg(\n  imageMap: Replayer['imageMap'],\n  ctx:\n    | CanvasRenderingContext2D\n    | WebGLRenderingContext\n    | WebGL2RenderingContext\n    | null,\n  preload?: {\n    isUnchanged: boolean;\n  },\n): (arg: CanvasArg) => Promise<any> {\n  return async (arg: CanvasArg): Promise<any> => {\n    if (arg && typeof arg === 'object' && 'rr_type' in arg) {\n      if (preload) preload.isUnchanged = false;\n      if (arg.rr_type === 'ImageBitmap' && 'args' in arg) {\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n        const args = await deserializeArg(imageMap, ctx, preload)(arg.args);\n        // eslint-disable-next-line prefer-spread\n        return await createImageBitmap.apply(null, args);\n      } else if ('index' in arg) {\n        if (preload || ctx === null) return arg; // we are preloading, ctx is unknown\n        const { rr_type: name, index } = arg;\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n        return variableListFor(ctx, name)[index];\n      } else if ('args' in arg) {\n        const { rr_type: name, args } = arg;\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n        const ctor = window[name as keyof Window];\n\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call\n        return new ctor(\n          ...(await Promise.all(\n            args.map(deserializeArg(imageMap, ctx, preload)),\n          )),\n        );\n      } else if ('base64' in arg) {\n        return decode(arg.base64);\n      } else if ('src' in arg) {\n        const image = imageMap.get(arg.src);\n        if (image) {\n          return image;\n        } else {\n          const image = new Image();\n          image.src = arg.src;\n          imageMap.set(arg.src, image);\n          return image;\n        }\n      } else if ('data' in arg && arg.rr_type === 'Blob') {\n        const blobContents = await Promise.all(\n          arg.data.map(deserializeArg(imageMap, ctx, preload)),\n        );\n        const blob = new Blob(blobContents, {\n          type: arg.type,\n        });\n        return blob;\n      }\n    } else if (Array.isArray(arg)) {\n      const result = await Promise.all(\n        arg.map(deserializeArg(imageMap, ctx, preload)),\n      );\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n      return result;\n    }\n    return arg;\n  };\n}\n", "import type { Replayer } from '../';\nimport { CanvasContext, type canvasMutationCommand } from '@rrweb/types';\nimport { deserializeArg, variableListFor } from './deserialize-args';\n\nfunction getContext(\n  target: HTMLCanvasElement,\n  type: CanvasContext,\n): WebGLRenderingContext | WebGL2RenderingContext | null {\n  // Note to whomever is going to implement support for `contextAttributes`:\n  // if `preserveDrawingBuffer` is set to true,\n  // you might have to do `ctx.flush()` before every webgl canvas event\n  try {\n    if (type === CanvasContext.WebGL) {\n      return (\n        target.getContext('webgl')! || target.getContext('experimental-webgl')\n      );\n    }\n    return target.getContext('webgl2')!;\n  } catch (e) {\n    return null;\n  }\n}\n\nconst WebGLVariableConstructorsNames = [\n  'WebGLActiveInfo',\n  'WebGLBuffer',\n  'WebGLFramebuffer',\n  'WebGLProgram',\n  'WebGLRenderbuffer',\n  'WebGLShader',\n  'WebGLShaderPrecisionFormat',\n  'WebGLTexture',\n  'WebGLUniformLocation',\n  'WebGLVertexArrayObject',\n];\n\nfunction saveToWebGLVarMap(\n  ctx: WebGLRenderingContext | WebGL2RenderingContext,\n  result: any,\n) {\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n  if (!result?.constructor) return; // probably null or undefined\n\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n  const { name } = result.constructor;\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n  if (!WebGLVariableConstructorsNames.includes(name)) return; // not a WebGL variable\n\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n  const variables = variableListFor(ctx, name);\n  if (!variables.includes(result)) variables.push(result);\n}\n\nexport default async function webglMutation({\n  mutation,\n  target,\n  type,\n  imageMap,\n  errorHandler,\n}: {\n  mutation: canvasMutationCommand;\n  target: HTMLCanvasElement;\n  type: CanvasContext;\n  imageMap: Replayer['imageMap'];\n  errorHandler: Replayer['warnCanvasMutationFailed'];\n}): Promise<void> {\n  try {\n    const ctx = getContext(target, type);\n    if (!ctx) return;\n\n    // NOTE: if `preserveDrawingBuffer` is set to true,\n    // we must flush the buffers on every new canvas event\n    // if (mutation.newFrame) ctx.flush();\n\n    if (mutation.setter) {\n      // skip some read-only type checks\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n      (ctx as any)[mutation.property] = mutation.args[0];\n      return;\n    }\n    const original = ctx[\n      mutation.property as Exclude<keyof typeof ctx, 'canvas'>\n    ] as (\n      ctx: WebGLRenderingContext | WebGL2RenderingContext,\n      args: unknown[],\n    ) => void;\n\n    const args = await Promise.all(\n      mutation.args.map(deserializeArg(imageMap, ctx)),\n    );\n    const result = original.apply(ctx, args);\n    saveToWebGLVarMap(ctx, result);\n\n    // Slows down replay considerably, only use for debugging\n    const debugMode = false;\n    if (debugMode) {\n      if (mutation.property === 'compileShader') {\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n        if (!ctx.getShaderParameter(args[0], ctx.COMPILE_STATUS))\n          console.warn(\n            'something went wrong in replay',\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n            ctx.getShaderInfoLog(args[0]),\n          );\n      } else if (mutation.property === 'linkProgram') {\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n        ctx.validateProgram(args[0]);\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n        if (!ctx.getProgramParameter(args[0], ctx.LINK_STATUS))\n          console.warn(\n            'something went wrong in replay',\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n            ctx.getProgramInfoLog(args[0]),\n          );\n      }\n      const webglError = ctx.getError();\n      if (webglError !== ctx.NO_ERROR) {\n        console.warn(\n          'WEBGL ERROR',\n          webglError,\n          'on command:',\n          mutation.property,\n          // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n          ...args,\n        );\n      }\n    }\n  } catch (error) {\n    errorHandler(mutation, error);\n  }\n}\n", "import type { Replayer } from '../';\nimport type { canvasMutationCommand } from '@rrweb/types';\nimport { deserializeArg } from './deserialize-args';\n\nexport default async function canvasMutation({\n  event,\n  mutations,\n  target,\n  imageMap,\n  errorHandler,\n}: {\n  event: Parameters<Replayer['applyIncremental']>[0];\n  mutations: canvasMutationCommand[];\n  target: HTMLCanvasElement;\n  imageMap: Replayer['imageMap'];\n  errorHandler: Replayer['warnCanvasMutationFailed'];\n}): Promise<void> {\n  const ctx = target.getContext('2d');\n\n  if (!ctx) {\n    errorHandler(mutations[0], new Error('Canvas context is null'));\n    return;\n  }\n\n  // step 1, deserialize args, they may be async\n  const mutationArgsPromises = mutations.map(\n    async (mutation: canvasMutationCommand): Promise<unknown[]> => {\n      return Promise.all(mutation.args.map(deserializeArg(imageMap, ctx)));\n    },\n  );\n  const args = await Promise.all(mutationArgsPromises);\n  // step 2 apply all mutations\n  args.forEach((args, index) => {\n    const mutation = mutations[index];\n    try {\n      if (mutation.setter) {\n        // skip some read-only type checks\n        (ctx as unknown as Record<string, unknown>)[mutation.property] =\n          mutation.args[0];\n        return;\n      }\n      const original = ctx[\n        mutation.property as Exclude<keyof typeof ctx, 'canvas'>\n      ] as (ctx: CanvasRenderingContext2D, args: unknown[]) => void;\n\n      /**\n       * We have serialized the image source into base64 string during recording,\n       * which has been preloaded before replay.\n       * So we can get call drawImage SYNCHRONOUSLY which avoid some fragile cast.\n       */\n      if (\n        mutation.property === 'drawImage' &&\n        typeof mutation.args[0] === 'string'\n      ) {\n        imageMap.get(event);\n        original.apply(ctx, mutation.args);\n      } else {\n        original.apply(ctx, args);\n      }\n    } catch (error) {\n      errorHandler(mutation, error);\n    }\n\n    return;\n  });\n}\n", "import type { Replayer } from '..';\nimport {\n  CanvasContext,\n  type canvasMutationCommand,\n  type canvasMutationData,\n  type canvasMutationParam,\n} from '@rrweb/types';\nimport webglMutation from './webgl';\nimport canvas2DMutation from './2d';\n\nexport default async function canvasMutation({\n  event,\n  mutation,\n  target,\n  imageMap,\n  canvasEventMap,\n  errorHandler,\n}: {\n  event: Parameters<Replayer['applyIncremental']>[0];\n  mutation: canvasMutationData;\n  target: HTMLCanvasElement;\n  imageMap: Replayer['imageMap'];\n  canvasEventMap: Replayer['canvasEventMap'];\n  errorHandler: Replayer['warnCanvasMutationFailed'];\n}): Promise<void> {\n  try {\n    const precomputedMutation: canvasMutationParam =\n      canvasEventMap.get(event) || mutation;\n\n    const commands: canvasMutationCommand[] =\n      'commands' in precomputedMutation\n        ? precomputedMutation.commands\n        : [precomputedMutation];\n\n    if ([CanvasContext.WebGL, CanvasContext.WebGL2].includes(mutation.type)) {\n      for (let i = 0; i < commands.length; i++) {\n        const command = commands[i];\n        await webglMutation({\n          mutation: command,\n          type: mutation.type,\n          target,\n          imageMap,\n          errorHandler,\n        });\n      }\n      return;\n    }\n    // default is '2d' for backwards compatibility (rrweb below 1.1.x)\n    await canvas2DMutation({\n      event,\n      mutations: commands,\n      target,\n      imageMap,\n      errorHandler,\n    });\n  } catch (error) {\n    errorHandler(mutation, error);\n  }\n}\n", "import type { Emitter } from '@rrweb/types';\nimport { MediaInteractions, ReplayerEvents } from '@rrweb/types';\nimport type { RRMediaElement } from 'rrdom';\nimport type { createPlayerService, createSpeedService } from '../machine';\nimport type { Mirror } from 'rrweb-snapshot';\nimport type { mediaInteractionData, mediaAttributes } from '@rrweb/types';\n\ntype MediaState = {\n  isPlaying: boolean;\n  currentTimeAtLastInteraction: number;\n  lastInteractionTimeOffset: number;\n  playbackRate: number;\n  loop: boolean;\n  volume: number;\n  muted: boolean;\n};\n\nexport class MediaManager {\n  private mediaMap: Map<HTMLMediaElement | RRMediaElement, MediaState> =\n    new Map();\n  private warn: (...args: Parameters<typeof console.warn>) => void;\n  private service: ReturnType<typeof createPlayerService>;\n  private speedService: ReturnType<typeof createSpeedService>;\n  private emitter: Emitter;\n  private getCurrentTime: () => number;\n  private metadataCallbackMap: WeakMap<\n    HTMLMediaElement | RRMediaElement,\n    () => void\n  > = new Map();\n\n  constructor(options: {\n    warn: (...args: Parameters<typeof console.warn>) => void;\n    service: ReturnType<typeof createPlayerService>;\n    speedService: ReturnType<typeof createSpeedService>;\n    getCurrentTime: () => number;\n    emitter: Emitter;\n  }) {\n    this.warn = options.warn;\n    this.service = options.service;\n    this.speedService = options.speedService;\n    this.emitter = options.emitter;\n    this.getCurrentTime = options.getCurrentTime;\n\n    this.emitter.on(ReplayerEvents.Start, this.start.bind(this));\n    this.emitter.on(ReplayerEvents.SkipStart, this.start.bind(this));\n    this.emitter.on(ReplayerEvents.Pause, this.pause.bind(this));\n    this.emitter.on(ReplayerEvents.Finish, this.pause.bind(this));\n    this.speedService.subscribe(() => {\n      this.syncAllMediaElements();\n    });\n  }\n\n  private syncAllMediaElements(options = { pause: false }) {\n    this.mediaMap.forEach((_mediaState, target) => {\n      this.syncTargetWithState(target);\n      if (options.pause) {\n        target.pause();\n      }\n    });\n  }\n\n  private start() {\n    this.syncAllMediaElements();\n  }\n\n  private pause() {\n    this.syncAllMediaElements({ pause: true });\n  }\n\n  private seekTo({\n    time,\n    target,\n    mediaState,\n  }: {\n    time: number;\n    target: HTMLMediaElement | RRMediaElement;\n    mediaState: MediaState;\n  }) {\n    if (mediaState.isPlaying) {\n      const differenceBetweenCurrentTimeAndMediaMutationTimestamp =\n        time - mediaState.lastInteractionTimeOffset;\n      const mediaPlaybackOffset =\n        (differenceBetweenCurrentTimeAndMediaMutationTimestamp / 1000) *\n        mediaState.playbackRate;\n\n      const duration = 'duration' in target && target.duration;\n\n      // Video hasn't loaded yet, wait for metadata\n      if (Number.isNaN(duration)) {\n        this.waitForMetadata(target);\n        return;\n      }\n\n      let seekToTime =\n        mediaState.currentTimeAtLastInteraction + mediaPlaybackOffset;\n\n      if (\n        target.loop &&\n        // RRMediaElement doesn't have a duration property\n        duration !== false\n      ) {\n        seekToTime = seekToTime % duration;\n      }\n\n      target.currentTime = seekToTime;\n    } else {\n      target.pause();\n      target.currentTime = mediaState.currentTimeAtLastInteraction;\n    }\n  }\n\n  private waitForMetadata(target: HTMLMediaElement | RRMediaElement) {\n    if (this.metadataCallbackMap.has(target)) return;\n    if (!('addEventListener' in target)) return;\n\n    const onLoadedMetadata = () => {\n      this.metadataCallbackMap.delete(target);\n      const mediaState = this.mediaMap.get(target);\n      if (!mediaState) return;\n      this.seekTo({\n        time: this.getCurrentTime(),\n        target,\n        mediaState,\n      });\n    };\n\n    this.metadataCallbackMap.set(target, onLoadedMetadata);\n    target.addEventListener('loadedmetadata', onLoadedMetadata, {\n      once: true,\n    });\n  }\n\n  private getMediaStateFromMutation({\n    target,\n    timeOffset,\n    mutation,\n  }: {\n    target: HTMLMediaElement | RRMediaElement;\n    timeOffset: number;\n    mutation: mediaInteractionData;\n  }): MediaState {\n    const lastState = this.mediaMap.get(target);\n    const { type, playbackRate, currentTime, muted, volume, loop } = mutation;\n\n    const isPlaying =\n      type === MediaInteractions.Play ||\n      (type !== MediaInteractions.Pause &&\n        (lastState?.isPlaying || target.getAttribute('autoplay') !== null));\n\n    const mediaState: MediaState = {\n      isPlaying,\n      currentTimeAtLastInteraction:\n        currentTime ?? lastState?.currentTimeAtLastInteraction ?? 0,\n      lastInteractionTimeOffset: timeOffset,\n      playbackRate: playbackRate ?? lastState?.playbackRate ?? 1,\n      volume: volume ?? lastState?.volume ?? 1,\n      muted: muted ?? lastState?.muted ?? target.getAttribute('muted') === null,\n      loop: loop ?? lastState?.loop ?? target.getAttribute('loop') === null,\n    };\n\n    return mediaState;\n  }\n\n  private syncTargetWithState(target: HTMLMediaElement | RRMediaElement) {\n    const mediaState = this.mediaMap.get(target);\n    if (!mediaState) return;\n    const { muted, loop, volume, isPlaying } = mediaState;\n    const playerIsPaused = this.service.state.matches('paused');\n    const playbackRate =\n      mediaState.playbackRate * this.speedService.state.context.timer.speed;\n\n    try {\n      this.seekTo({\n        time: this.getCurrentTime(),\n        target,\n        mediaState,\n      });\n\n      if (target.volume !== volume) {\n        target.volume = volume;\n      }\n      target.muted = muted;\n      target.loop = loop;\n\n      if (target.playbackRate !== playbackRate) {\n        // Avoid setting playbackRate when it's already the same\n        // Safari drops frames whenever playbackRate is set, even if it's the same\n        target.playbackRate = playbackRate;\n      }\n\n      if (isPlaying && !playerIsPaused) {\n        // remove listener for 'canplay' event because play() is async and returns a promise\n        // i.e. media will eventually start to play when data is loaded\n        // 'canplay' event fires even when currentTime attribute changes which may lead to\n        // unexpected behavior\n        void target.play();\n      } else {\n        target.pause();\n      }\n    } catch (error) {\n      this.warn(\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions\n        `Failed to replay media interactions: ${error.message || error}`,\n      );\n    }\n  }\n\n  public addMediaElements(node: Node, timeOffset: number, mirror: Mirror) {\n    if (!['AUDIO', 'VIDEO'].includes(node.nodeName)) return;\n    const target = node as HTMLMediaElement;\n    const serializedNode = mirror.getMeta(target);\n    if (!serializedNode || !('attributes' in serializedNode)) return;\n    const playerIsPaused = this.service.state.matches('paused');\n    const mediaAttributes = serializedNode.attributes as\n      | mediaAttributes\n      | Record<string, never>;\n\n    let isPlaying = false;\n    if (mediaAttributes.rr_mediaState) {\n      isPlaying = mediaAttributes.rr_mediaState === 'played';\n    } else {\n      isPlaying = target.getAttribute('autoplay') !== null;\n    }\n    if (isPlaying && playerIsPaused) target.pause();\n\n    let playbackRate = 1;\n    if (typeof mediaAttributes.rr_mediaPlaybackRate === 'number') {\n      playbackRate = mediaAttributes.rr_mediaPlaybackRate;\n    }\n\n    let muted = false;\n    if (typeof mediaAttributes.rr_mediaMuted === 'boolean') {\n      muted = mediaAttributes.rr_mediaMuted;\n    } else {\n      muted = target.getAttribute('muted') !== null;\n    }\n\n    let loop = false;\n    if (typeof mediaAttributes.rr_mediaLoop === 'boolean') {\n      loop = mediaAttributes.rr_mediaLoop;\n    } else {\n      loop = target.getAttribute('loop') !== null;\n    }\n\n    let volume = 1;\n    if (typeof mediaAttributes.rr_mediaVolume === 'number') {\n      volume = mediaAttributes.rr_mediaVolume;\n    }\n\n    let currentTimeAtLastInteraction = 0;\n    if (typeof mediaAttributes.rr_mediaCurrentTime === 'number') {\n      currentTimeAtLastInteraction = mediaAttributes.rr_mediaCurrentTime;\n    }\n\n    this.mediaMap.set(target, {\n      isPlaying,\n      currentTimeAtLastInteraction,\n      lastInteractionTimeOffset: timeOffset,\n      playbackRate,\n      volume,\n      muted,\n      loop,\n    });\n    this.syncTargetWithState(target);\n  }\n\n  public mediaMutation({\n    target,\n    timeOffset,\n    mutation,\n  }: {\n    target: HTMLMediaElement | RRMediaElement;\n    timeOffset: number;\n    mutation: mediaInteractionData;\n  }) {\n    this.mediaMap.set(\n      target,\n      this.getMediaStateFromMutation({\n        target,\n        timeOffset,\n        mutation,\n      }),\n    );\n\n    this.syncTargetWithState(target);\n  }\n\n  public isSupportedMediaElement(node: Node): node is HTMLMediaElement {\n    return ['AUDIO', 'VIDEO'].includes(node.nodeName);\n  }\n\n  public reset() {\n    this.mediaMap.clear();\n  }\n}\n", "import type { attributeMutation } from '@rrweb/types';\nimport { RRNode } from 'rrdom';\n\n/**\n * Checks if the dialog is a top level dialog and applies the dialog to the top level\n * @param node - potential dialog element to apply top level `showModal()` to, or other node (which will be ignored)\n * @param attributeMutation - the attribute mutation used to change the dialog (optional)\n * @returns void\n */\nexport function applyDialogToTopLevel(\n  node: HTMLDialogElement | Node | RRNode,\n  attributeMutation?: attributeMutation,\n): void {\n  if (node.nodeName !== 'DIALOG' || node instanceof RRNode) return;\n  const dialog = node as HTMLDialogElement;\n  const oldIsOpen = dialog.open;\n  const oldIsModalState = oldIsOpen && dialog.matches('dialog:modal');\n  const rrOpenMode = dialog.getAttribute('rr_open_mode');\n\n  const newIsOpen =\n    typeof attributeMutation?.attributes.open === 'string' ||\n    typeof dialog.getAttribute('open') === 'string';\n  const newIsModalState = rrOpenMode === 'modal';\n  const newIsNonModalState = rrOpenMode === 'non-modal';\n\n  const modalStateChanged =\n    (oldIsModalState && newIsNonModalState) ||\n    (!oldIsModalState && newIsModalState);\n\n  if (oldIsOpen && !modalStateChanged) return;\n  // complain if dialog is not attached to the dom\n  if (!dialog.isConnected) {\n    console.warn('dialog is not attached to the dom', dialog);\n    return;\n  }\n\n  if (oldIsOpen) dialog.close();\n  if (!newIsOpen) return;\n\n  if (newIsModalState) dialog.showModal();\n  else dialog.show();\n}\n\n/**\n * Check if the dialog is a top level dialog and removes the dialog from the top level if necessary\n * @param node - potential dialog element to remove from top level, or other node (which will be ignored)\n * @param attributeMutation - the attribute mutation used to change the dialog\n * @returns void\n */\nexport function removeDialogFromTopLevel(\n  node: HTMLDialogElement | Node | RRNode,\n  attributeMutation: attributeMutation,\n): void {\n  if (node.nodeName !== 'DIALOG' || node instanceof RRNode) return;\n  const dialog = node as HTMLDialogElement;\n\n  // complain if dialog is not attached to the dom\n  if (!dialog.isConnected) {\n    console.warn('dialog is not attached to the dom', dialog);\n    return;\n  }\n\n  if (attributeMutation.attributes.open === null) {\n    dialog.removeAttribute('open');\n    dialog.removeAttribute('rr_open_mode');\n  }\n}\n", "import {\n  rebuild,\n  adaptCssForReplay,\n  buildNodeWithSN,\n  type BuildCache,\n  createCache,\n  Mirror,\n  createMirror,\n  toLowerCase,\n} from 'rrweb-snapshot';\nimport {\n  RRDocument,\n  createOrGetNode,\n  buildFromNode,\n  buildFromDom,\n  diff,\n  getDefaultSN,\n} from 'rrdom';\nimport type {\n  RRNode,\n  RRElement,\n  RRStyleElement,\n  RRIFrameElement,\n  RRMediaElement,\n  RRCanvasElement,\n  ReplayerHandler,\n  Mirror as RRDOMMirror,\n} from 'rrdom';\nimport * as mittProxy from 'mitt';\nimport { polyfill as smoothscrollPolyfill } from './smoothscroll';\nimport { Timer } from './timer';\nimport {\n  createPlayerService,\n  createSpeedService,\n  type PlayerMachineState,\n  type SpeedMachineState,\n} from './machine';\nimport type { playerConfig, missingNodeMap } from '../types';\nimport {\n  NodeType,\n  EventType,\n  IncrementalSource,\n  MouseInteractions,\n  ReplayerEvents,\n} from '@rrweb/types';\nimport type {\n  attributes,\n  fullSnapshotEvent,\n  eventWithTime,\n  playerMetaData,\n  viewportResizeDimension,\n  addedNodeMutation,\n  incrementalSnapshotEvent,\n  incrementalData,\n  Handler,\n  Emitter,\n  metaEvent,\n  mutationData,\n  scrollData,\n  inputData,\n  canvasMutationData,\n  styleValueWithPriority,\n  mouseMovePos,\n  IWindow,\n  canvasMutationCommand,\n  canvasMutationParam,\n  canvasEventWithTime,\n  selectionData,\n  styleSheetRuleData,\n  styleDeclarationData,\n  adoptedStyleSheetData,\n  serializedElementNodeWithId,\n} from '@rrweb/types';\nimport {\n  polyfill,\n  queueToResolveTrees,\n  iterateResolveTree,\n  type AppendedIframe,\n  getBaseDimension,\n  hasShadowRoot,\n  isSerializedIframe,\n  getNestedRule,\n  getPositionsAndIndex,\n  uniqueTextMutations,\n  StyleSheetMirror,\n} from '../utils';\nimport getInjectStyleRules from './styles/inject-style';\nimport './styles/style.css';\nimport canvasMutation from './canvas';\nimport { deserializeArg } from './canvas/deserialize-args';\nimport { MediaManager } from './media';\nimport { applyDialogToTopLevel, removeDialogFromTopLevel } from './dialog';\n\nconst SKIP_TIME_INTERVAL = 5 * 1000;\n\n// https://github.com/rollup/rollup/issues/1267#issuecomment-296395734\nconst mitt = mittProxy.default || mittProxy;\n\nconst REPLAY_CONSOLE_PREFIX = '[replayer]';\n\nconst defaultMouseTailConfig = {\n  duration: 500,\n  lineCap: 'round',\n  lineWidth: 3,\n  strokeStyle: 'red',\n} as const;\n\nfunction indicatesTouchDevice(e: eventWithTime) {\n  return (\n    e.type == EventType.IncrementalSnapshot &&\n    (e.data.source == IncrementalSource.TouchMove ||\n      (e.data.source == IncrementalSource.MouseInteraction &&\n        e.data.type == MouseInteractions.TouchStart))\n  );\n}\n\nexport class Replayer {\n  public wrapper: HTMLDivElement;\n  public iframe: HTMLIFrameElement;\n\n  public service: ReturnType<typeof createPlayerService>;\n  public speedService: ReturnType<typeof createSpeedService>;\n  public get timer() {\n    return this.service.state.context.timer;\n  }\n\n  public config: playerConfig;\n\n  // In the fast-forward process, if the virtual-dom optimization is used, this flag value is true.\n  public usingVirtualDom = false;\n  public virtualDom: RRDocument = new RRDocument();\n\n  private mouse: HTMLDivElement;\n  private mouseTail: HTMLCanvasElement | null = null;\n  private tailPositions: Array<{ x: number; y: number }> = [];\n\n  private emitter: Emitter = mitt();\n\n  private nextUserInteractionEvent: eventWithTime | null;\n\n  private legacy_missingNodeRetryMap: missingNodeMap = {};\n\n  // The replayer uses the cache to speed up replay and scrubbing.\n  private cache: BuildCache = createCache();\n\n  private imageMap: Map<eventWithTime | string, HTMLImageElement> = new Map();\n  private canvasEventMap: Map<eventWithTime, canvasMutationParam> = new Map();\n\n  private mirror: Mirror = createMirror();\n\n  // Used to track StyleSheetObjects adopted on multiple document hosts.\n  private styleMirror: StyleSheetMirror = new StyleSheetMirror();\n\n  // Used to track video & audio elements, and keep them in sync with general playback.\n  private mediaManager: MediaManager;\n\n  private firstFullSnapshot: eventWithTime | true | null = null;\n\n  private newDocumentQueue: addedNodeMutation[] = [];\n\n  private mousePos: mouseMovePos | null = null;\n  private touchActive: boolean | null = null;\n  private lastMouseDownEvent: [Node, Event] | null = null;\n\n  // Keep the rootNode of the last hovered element. So  when hovering a new element, we can remove the last hovered element's :hover style.\n  private lastHoveredRootNode: Document | ShadowRoot;\n\n  // In the fast-forward mode, only the last selection data needs to be applied.\n  private lastSelectionData: selectionData | null = null;\n\n  // In the fast-forward mode using VirtualDom optimization, all stylesheetRule, and styleDeclaration events on constructed StyleSheets will be delayed to get applied until the flush stage.\n  private constructedStyleMutations: (\n    | styleSheetRuleData\n    | styleDeclarationData\n  )[] = [];\n\n  // Similar to the reason for constructedStyleMutations.\n  private adoptedStyleSheets: adoptedStyleSheetData[] = [];\n\n  constructor(\n    events: Array<eventWithTime | string>,\n    config?: Partial<playerConfig>,\n  ) {\n    if (!config?.liveMode && events.length < 2) {\n      throw new Error('Replayer need at least 2 events.');\n    }\n    const defaultConfig: playerConfig = {\n      speed: 1,\n      maxSpeed: 360,\n      root: document.body,\n      loadTimeout: 0,\n      skipInactive: false,\n      inactivePeriodThreshold: 10 * 1000,\n      showWarning: true,\n      showDebug: false,\n      blockClass: 'rr-block',\n      liveMode: false,\n      insertStyleRules: [],\n      triggerFocus: true,\n      UNSAFE_replayCanvas: false,\n      pauseAnimation: true,\n      mouseTail: defaultMouseTailConfig,\n      useVirtualDom: true, // Virtual-dom optimization is enabled by default.\n      logger: console,\n    };\n    this.config = Object.assign({}, defaultConfig, config);\n\n    this.handleResize = this.handleResize.bind(this);\n    this.getCastFn = this.getCastFn.bind(this);\n    this.applyEventsSynchronously = this.applyEventsSynchronously.bind(this);\n    this.emitter.on(ReplayerEvents.Resize, this.handleResize as Handler);\n\n    this.setupDom();\n\n    /**\n     * Exposes mirror to the plugins\n     */\n    for (const plugin of this.config.plugins || []) {\n      if (plugin.getMirror) plugin.getMirror({ nodeMirror: this.mirror });\n    }\n\n    this.emitter.on(ReplayerEvents.Flush, () => {\n      if (this.usingVirtualDom) {\n        const replayerHandler: ReplayerHandler = {\n          mirror: this.mirror,\n          applyCanvas: (\n            canvasEvent: canvasEventWithTime,\n            canvasMutationData: canvasMutationData,\n            target: HTMLCanvasElement,\n          ) => {\n            void canvasMutation({\n              event: canvasEvent,\n              mutation: canvasMutationData,\n              target,\n              imageMap: this.imageMap,\n              canvasEventMap: this.canvasEventMap,\n              errorHandler: this.warnCanvasMutationFailed.bind(this),\n            });\n          },\n          applyInput: this.applyInput.bind(this),\n          applyScroll: this.applyScroll.bind(this),\n          applyStyleSheetMutation: (\n            data: styleDeclarationData | styleSheetRuleData,\n            styleSheet: CSSStyleSheet,\n          ) => {\n            if (data.source === IncrementalSource.StyleSheetRule)\n              this.applyStyleSheetRule(data, styleSheet);\n            else if (data.source === IncrementalSource.StyleDeclaration)\n              this.applyStyleDeclaration(data, styleSheet);\n          },\n          afterAppend: (node: Node, id: number) => {\n            for (const plugin of this.config.plugins || []) {\n              if (plugin.onBuild) plugin.onBuild(node, { id, replayer: this });\n            }\n          },\n        };\n        if (this.iframe.contentDocument)\n          try {\n            diff(\n              this.iframe.contentDocument,\n              this.virtualDom,\n              replayerHandler,\n              this.virtualDom.mirror,\n            );\n          } catch (e) {\n            console.warn(e);\n          }\n\n        this.virtualDom.destroyTree();\n        this.usingVirtualDom = false;\n\n        // If these legacy missing nodes haven't been resolved, they should be converted to real Nodes.\n        if (Object.keys(this.legacy_missingNodeRetryMap).length) {\n          for (const key in this.legacy_missingNodeRetryMap) {\n            try {\n              const value = this.legacy_missingNodeRetryMap[key];\n              const realNode = createOrGetNode(\n                value.node as RRNode,\n                this.mirror,\n                this.virtualDom.mirror,\n              );\n              diff(\n                realNode,\n                value.node as RRNode,\n                replayerHandler,\n                this.virtualDom.mirror,\n              );\n              value.node = realNode;\n            } catch (error) {\n              this.warn(error);\n            }\n          }\n        }\n\n        this.constructedStyleMutations.forEach((data) => {\n          this.applyStyleSheetMutation(data);\n        });\n        this.constructedStyleMutations = [];\n\n        this.adoptedStyleSheets.forEach((data) => {\n          this.applyAdoptedStyleSheet(data);\n        });\n        this.adoptedStyleSheets = [];\n      }\n\n      if (this.mousePos) {\n        this.moveAndHover(\n          this.mousePos.x,\n          this.mousePos.y,\n          this.mousePos.id,\n          true,\n          this.mousePos.debugData,\n        );\n        this.mousePos = null;\n      }\n\n      if (this.touchActive === true) {\n        this.mouse.classList.add('touch-active');\n      } else if (this.touchActive === false) {\n        this.mouse.classList.remove('touch-active');\n      }\n      this.touchActive = null;\n\n      if (this.lastMouseDownEvent) {\n        const [target, event] = this.lastMouseDownEvent;\n        target.dispatchEvent(event);\n      }\n      this.lastMouseDownEvent = null;\n\n      if (this.lastSelectionData) {\n        this.applySelection(this.lastSelectionData);\n        this.lastSelectionData = null;\n      }\n    });\n    this.emitter.on(ReplayerEvents.PlayBack, () => {\n      this.firstFullSnapshot = null;\n      this.mirror.reset();\n      this.styleMirror.reset();\n      this.mediaManager.reset();\n    });\n\n    const timer = new Timer([], {\n      speed: this.config.speed,\n    });\n    this.service = createPlayerService(\n      {\n        events: events\n          .map((e) => {\n            if (config && config.unpackFn) {\n              return config.unpackFn(e as string);\n            }\n            return e as eventWithTime;\n          })\n          .sort((a1, a2) => a1.timestamp - a2.timestamp),\n        timer,\n        timeOffset: 0,\n        baselineTime: 0,\n        lastPlayedEvent: null,\n      },\n      {\n        getCastFn: this.getCastFn,\n        applyEventsSynchronously: this.applyEventsSynchronously,\n        emitter: this.emitter,\n      },\n    );\n    this.service.start();\n    this.service.subscribe((state) => {\n      this.emitter.emit(ReplayerEvents.StateChange, {\n        player: state,\n      });\n    });\n    this.speedService = createSpeedService({\n      normalSpeed: -1,\n      timer,\n    });\n    this.speedService.start();\n    this.speedService.subscribe((state) => {\n      this.emitter.emit(ReplayerEvents.StateChange, {\n        speed: state,\n      });\n    });\n    this.mediaManager = new MediaManager({\n      warn: this.warn.bind(this),\n      service: this.service,\n      speedService: this.speedService,\n      emitter: this.emitter,\n      getCurrentTime: this.getCurrentTime.bind(this),\n    });\n\n    // rebuild first full snapshot as the poster of the player\n    // maybe we can cache it for performance optimization\n    const firstMeta = this.service.state.context.events.find(\n      (e) => e.type === EventType.Meta,\n    );\n    const firstFullsnapshot = this.service.state.context.events.find(\n      (e) => e.type === EventType.FullSnapshot,\n    );\n    if (firstMeta) {\n      const { width, height } = firstMeta.data as metaEvent['data'];\n      setTimeout(() => {\n        this.emitter.emit(ReplayerEvents.Resize, {\n          width,\n          height,\n        });\n      }, 0);\n    }\n    if (firstFullsnapshot) {\n      setTimeout(() => {\n        // when something has been played, there is no need to rebuild poster\n        if (this.firstFullSnapshot) {\n          // true if any other fullSnapshot has been executed by Timer already\n          return;\n        }\n        this.firstFullSnapshot = firstFullsnapshot;\n        this.rebuildFullSnapshot(\n          firstFullsnapshot as fullSnapshotEvent & { timestamp: number },\n        );\n        this.iframe.contentWindow?.scrollTo(\n          (firstFullsnapshot as fullSnapshotEvent).data.initialOffset,\n        );\n      }, 1);\n    }\n    if (this.service.state.context.events.find(indicatesTouchDevice)) {\n      this.mouse.classList.add('touch-device');\n    }\n  }\n\n  public on(event: string, handler: Handler) {\n    this.emitter.on(event, handler);\n    return this;\n  }\n\n  public off(event: string, handler: Handler) {\n    this.emitter.off(event, handler);\n    return this;\n  }\n\n  public setConfig(config: Partial<playerConfig>) {\n    Object.keys(config).forEach((key) => {\n      const newConfigValue = config[key as keyof playerConfig];\n      (this.config as Record<keyof playerConfig, typeof newConfigValue>)[\n        key as keyof playerConfig\n      ] = config[key as keyof playerConfig];\n    });\n    if (!this.config.skipInactive) {\n      this.backToNormal();\n    }\n    if (typeof config.speed !== 'undefined') {\n      this.speedService.send({\n        type: 'SET_SPEED',\n        payload: {\n          speed: config.speed,\n        },\n      });\n    }\n    if (typeof config.mouseTail !== 'undefined') {\n      if (config.mouseTail === false) {\n        if (this.mouseTail) {\n          this.mouseTail.style.display = 'none';\n        }\n      } else {\n        if (!this.mouseTail) {\n          this.mouseTail = document.createElement('canvas');\n          this.mouseTail.width = Number.parseFloat(this.iframe.width);\n          this.mouseTail.height = Number.parseFloat(this.iframe.height);\n          this.mouseTail.classList.add('replayer-mouse-tail');\n          this.wrapper.insertBefore(this.mouseTail, this.iframe);\n        }\n        this.mouseTail.style.display = 'inherit';\n      }\n    }\n  }\n\n  public getMetaData(): playerMetaData {\n    const firstEvent = this.service.state.context.events[0];\n    const lastEvent =\n      this.service.state.context.events[\n        this.service.state.context.events.length - 1\n      ];\n    return {\n      startTime: firstEvent.timestamp,\n      endTime: lastEvent.timestamp,\n      totalTime: lastEvent.timestamp - firstEvent.timestamp,\n    };\n  }\n\n  /**\n   * Get the actual time offset the player is at now compared to the first event.\n   */\n  public getCurrentTime(): number {\n    return this.timer.timeOffset + this.getTimeOffset();\n  }\n\n  /**\n   * Get the time offset the player is at now compared to the first event, but without regard for the timer.\n   */\n  public getTimeOffset(): number {\n    const { baselineTime, events } = this.service.state.context;\n    return baselineTime - events[0].timestamp;\n  }\n\n  public getMirror(): Mirror {\n    return this.mirror;\n  }\n\n  /**\n   * This API was designed to be used as play at any time offset.\n   * Since we minimized the data collected from recorder, we do not\n   * have the ability of undo an event.\n   * So the implementation of play at any time offset will always iterate\n   * all of the events, cast event before the offset synchronously\n   * and cast event after the offset asynchronously with timer.\n   * @param timeOffset - number\n   */\n  public play(timeOffset = 0) {\n    if (this.service.state.matches('paused')) {\n      this.service.send({ type: 'PLAY', payload: { timeOffset } });\n    } else {\n      this.service.send({ type: 'PAUSE' });\n      this.service.send({ type: 'PLAY', payload: { timeOffset } });\n    }\n    this.iframe.contentDocument\n      ?.getElementsByTagName('html')[0]\n      ?.classList.remove('rrweb-paused');\n    this.emitter.emit(ReplayerEvents.Start);\n  }\n\n  public pause(timeOffset?: number) {\n    if (timeOffset === undefined && this.service.state.matches('playing')) {\n      this.service.send({ type: 'PAUSE' });\n    }\n    if (typeof timeOffset === 'number') {\n      this.play(timeOffset);\n      this.service.send({ type: 'PAUSE' });\n    }\n    this.iframe.contentDocument\n      ?.getElementsByTagName('html')[0]\n      ?.classList.add('rrweb-paused');\n    this.emitter.emit(ReplayerEvents.Pause);\n  }\n\n  public resume(timeOffset = 0) {\n    this.warn(\n      `The 'resume' was deprecated in 1.0. Please use 'play' method which has the same interface.`,\n    );\n    this.play(timeOffset);\n    this.emitter.emit(ReplayerEvents.Resume);\n  }\n\n  /**\n   * Totally destroy this replayer and please be careful that this operation is irreversible.\n   * Memory occupation can be released by removing all references to this replayer.\n   */\n  public destroy() {\n    this.pause();\n    this.mirror.reset();\n    this.styleMirror.reset();\n    this.mediaManager.reset();\n    this.config.root.removeChild(this.wrapper);\n    this.emitter.emit(ReplayerEvents.Destroy);\n  }\n\n  public startLive(baselineTime?: number) {\n    this.service.send({ type: 'TO_LIVE', payload: { baselineTime } });\n  }\n\n  public addEvent(rawEvent: eventWithTime | string) {\n    const event = this.config.unpackFn\n      ? this.config.unpackFn(rawEvent as string)\n      : (rawEvent as eventWithTime);\n    if (indicatesTouchDevice(event)) {\n      this.mouse.classList.add('touch-device');\n    }\n    void Promise.resolve().then(() =>\n      this.service.send({ type: 'ADD_EVENT', payload: { event } }),\n    );\n  }\n\n  public enableInteract() {\n    this.iframe.setAttribute('scrolling', 'auto');\n    this.iframe.style.pointerEvents = 'auto';\n  }\n\n  public disableInteract() {\n    this.iframe.setAttribute('scrolling', 'no');\n    this.iframe.style.pointerEvents = 'none';\n  }\n\n  /**\n   * Empties the replayer's cache and reclaims memory.\n   * The replayer will use this cache to speed up the playback.\n   */\n  public resetCache() {\n    this.cache = createCache();\n  }\n\n  private setupDom() {\n    this.wrapper = document.createElement('div');\n    this.wrapper.classList.add('replayer-wrapper');\n    this.config.root.appendChild(this.wrapper);\n\n    this.mouse = document.createElement('div');\n    this.mouse.classList.add('replayer-mouse');\n    this.wrapper.appendChild(this.mouse);\n\n    if (this.config.mouseTail !== false) {\n      this.mouseTail = document.createElement('canvas');\n      this.mouseTail.classList.add('replayer-mouse-tail');\n      this.mouseTail.style.display = 'inherit';\n      this.wrapper.appendChild(this.mouseTail);\n    }\n\n    this.iframe = document.createElement('iframe');\n    const attributes = ['allow-same-origin'];\n    if (this.config.UNSAFE_replayCanvas) {\n      attributes.push('allow-scripts');\n    }\n    // hide iframe before first meta event\n    this.iframe.style.display = 'none';\n    this.iframe.setAttribute('sandbox', attributes.join(' '));\n    this.disableInteract();\n    this.wrapper.appendChild(this.iframe);\n    if (this.iframe.contentWindow && this.iframe.contentDocument) {\n      smoothscrollPolyfill(\n        this.iframe.contentWindow,\n        this.iframe.contentDocument,\n      );\n\n      polyfill(this.iframe.contentWindow as IWindow);\n    }\n  }\n\n  private handleResize = (dimension: viewportResizeDimension) => {\n    this.iframe.style.display = 'inherit';\n    for (const el of [this.mouseTail, this.iframe]) {\n      if (!el) {\n        continue;\n      }\n      el.setAttribute('width', String(dimension.width));\n      el.setAttribute('height', String(dimension.height));\n    }\n  };\n\n  private applyEventsSynchronously = (events: Array<eventWithTime>) => {\n    for (const event of events) {\n      switch (event.type) {\n        case EventType.DomContentLoaded:\n        case EventType.Load:\n        case EventType.Custom:\n          continue;\n        case EventType.FullSnapshot:\n        case EventType.Meta:\n        case EventType.Plugin:\n        case EventType.IncrementalSnapshot:\n          break;\n        default:\n          break;\n      }\n      const castFn = this.getCastFn(event, true);\n      castFn();\n    }\n  };\n\n  private getCastFn = (event: eventWithTime, isSync = false) => {\n    let castFn: undefined | (() => void);\n    switch (event.type) {\n      case EventType.DomContentLoaded:\n      case EventType.Load:\n        break;\n      case EventType.Custom:\n        castFn = () => {\n          /**\n           * emit custom-event and pass the event object.\n           *\n           * This will add more value to the custom event and allows the client to react for custom-event.\n           */\n          this.emitter.emit(ReplayerEvents.CustomEvent, event);\n        };\n        break;\n      case EventType.Meta:\n        castFn = () =>\n          this.emitter.emit(ReplayerEvents.Resize, {\n            width: event.data.width,\n            height: event.data.height,\n          });\n        break;\n      case EventType.FullSnapshot:\n        castFn = () => {\n          if (this.firstFullSnapshot) {\n            if (this.firstFullSnapshot === event) {\n              // we've already built this exact FullSnapshot when the player was mounted, and haven't built any other FullSnapshot since\n              this.firstFullSnapshot = true; // forget as we might need to re-execute this FullSnapshot later e.g. to rebuild after scrubbing\n              return;\n            }\n          } else {\n            // Timer (requestAnimationFrame) can be faster than setTimeout(..., 1)\n            this.firstFullSnapshot = true;\n          }\n          this.mediaManager.reset();\n          this.styleMirror.reset();\n          this.rebuildFullSnapshot(event, isSync);\n          this.iframe.contentWindow?.scrollTo(event.data.initialOffset);\n        };\n        break;\n      case EventType.IncrementalSnapshot:\n        castFn = () => {\n          this.applyIncremental(event, isSync);\n          if (isSync) {\n            // do not check skip in sync\n            return;\n          }\n          if (event === this.nextUserInteractionEvent) {\n            this.nextUserInteractionEvent = null;\n            this.backToNormal();\n          }\n          if (this.config.skipInactive && !this.nextUserInteractionEvent) {\n            for (const _event of this.service.state.context.events) {\n              if (_event.timestamp <= event.timestamp) {\n                continue;\n              }\n              if (this.isUserInteraction(_event)) {\n                if (\n                  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n                  _event.delay! - event.delay! >\n                  this.config.inactivePeriodThreshold *\n                    this.speedService.state.context.timer.speed\n                ) {\n                  this.nextUserInteractionEvent = _event;\n                }\n                break;\n              }\n            }\n            if (this.nextUserInteractionEvent) {\n              const skipTime =\n                // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n                this.nextUserInteractionEvent.delay! - event.delay!;\n              const payload = {\n                speed: Math.min(\n                  Math.round(skipTime / SKIP_TIME_INTERVAL),\n                  this.config.maxSpeed,\n                ),\n              };\n              this.speedService.send({ type: 'FAST_FORWARD', payload });\n              this.emitter.emit(ReplayerEvents.SkipStart, payload);\n            }\n          }\n        };\n        break;\n      default:\n    }\n    const wrappedCastFn = () => {\n      if (castFn) {\n        castFn();\n      }\n\n      for (const plugin of this.config.plugins || []) {\n        if (plugin.handler) plugin.handler(event, isSync, { replayer: this });\n      }\n\n      this.service.send({ type: 'CAST_EVENT', payload: { event } });\n\n      // events are kept sorted by timestamp, check if this is the last event\n      const lastIndex = this.service.state.context.events.length - 1;\n      if (\n        !this.config.liveMode &&\n        event === this.service.state.context.events[lastIndex]\n      ) {\n        const finish = () => {\n          if (lastIndex < this.service.state.context.events.length - 1) {\n            // more events have been added since the setTimeout\n            return;\n          }\n          this.backToNormal();\n          this.service.send('END');\n          this.emitter.emit(ReplayerEvents.Finish);\n        };\n        let finishBuffer = 50; // allow for checking whether new events aren't just about to be loaded in\n        if (\n          event.type === EventType.IncrementalSnapshot &&\n          event.data.source === IncrementalSource.MouseMove &&\n          event.data.positions.length\n        ) {\n          // extend finish event if the last event is a mouse move so that the timer isn't stopped by the service before checking the last event\n          finishBuffer += Math.max(0, -event.data.positions[0].timeOffset);\n        }\n        setTimeout(finish, finishBuffer);\n      }\n\n      this.emitter.emit(ReplayerEvents.EventCast, event);\n    };\n    return wrappedCastFn;\n  };\n\n  private rebuildFullSnapshot(\n    event: fullSnapshotEvent & { timestamp: number },\n    isSync = false,\n  ) {\n    if (!this.iframe.contentDocument) {\n      return this.warn('Looks like your replayer has been destroyed.');\n    }\n    if (Object.keys(this.legacy_missingNodeRetryMap).length) {\n      this.warn(\n        'Found unresolved missing node map',\n        this.legacy_missingNodeRetryMap,\n      );\n    }\n    this.legacy_missingNodeRetryMap = {};\n    const collectedIframes: AppendedIframe[] = [];\n    const collectedDialogs = new Set<HTMLDialogElement>();\n    const afterAppend = (builtNode: Node, id: number) => {\n      if (builtNode.nodeName === 'DIALOG')\n        collectedDialogs.add(builtNode as HTMLDialogElement);\n      this.collectIframeAndAttachDocument(collectedIframes, builtNode);\n      if (this.mediaManager.isSupportedMediaElement(builtNode)) {\n        const { events } = this.service.state.context;\n        this.mediaManager.addMediaElements(\n          builtNode,\n          event.timestamp - events[0].timestamp,\n          this.mirror,\n        );\n      }\n      for (const plugin of this.config.plugins || []) {\n        if (plugin.onBuild)\n          plugin.onBuild(builtNode, {\n            id,\n            replayer: this,\n          });\n      }\n    };\n\n    /**\n     * Normally rebuilding full snapshot should not be under virtual dom environment.\n     * But if the order of data events has some issues, it might be possible.\n     * Adding this check to avoid any potential issues.\n     */\n    if (this.usingVirtualDom) {\n      this.virtualDom.destroyTree();\n      this.usingVirtualDom = false;\n    }\n\n    this.mirror.reset();\n    rebuild(event.data.node, {\n      doc: this.iframe.contentDocument,\n      afterAppend,\n      cache: this.cache,\n      mirror: this.mirror,\n    });\n    afterAppend(this.iframe.contentDocument, event.data.node.id);\n\n    for (const { mutationInQueue, builtNode } of collectedIframes) {\n      this.attachDocumentToIframe(mutationInQueue, builtNode);\n      this.newDocumentQueue = this.newDocumentQueue.filter(\n        (m) => m !== mutationInQueue,\n      );\n    }\n    const { documentElement, head } = this.iframe.contentDocument;\n    this.insertStyleRules(documentElement, head);\n    collectedDialogs.forEach((d) => applyDialogToTopLevel(d));\n    if (!this.service.state.matches('playing')) {\n      this.iframe.contentDocument\n        .getElementsByTagName('html')[0]\n        .classList.add('rrweb-paused');\n    }\n    this.emitter.emit(ReplayerEvents.FullsnapshotRebuilded, event);\n    if (!isSync) {\n      this.waitForStylesheetLoad();\n    }\n    if (this.config.UNSAFE_replayCanvas) {\n      void this.preloadAllImages();\n    }\n  }\n\n  private insertStyleRules(\n    documentElement: HTMLElement | RRElement,\n    head: HTMLHeadElement | RRElement,\n  ) {\n    const injectStylesRules = getInjectStyleRules(\n      this.config.blockClass,\n    ).concat(this.config.insertStyleRules);\n    if (this.config.pauseAnimation) {\n      injectStylesRules.push(\n        'html.rrweb-paused *, html.rrweb-paused *:before, html.rrweb-paused *:after { animation-play-state: paused !important; }',\n      );\n    }\n    if (!injectStylesRules.length) {\n      return;\n    }\n    if (this.usingVirtualDom) {\n      const styleEl = this.virtualDom.createElement('style');\n      this.virtualDom.mirror.add(\n        styleEl,\n        getDefaultSN(styleEl, this.virtualDom.unserializedId),\n      );\n      (documentElement as RRElement).insertBefore(styleEl, head as RRElement);\n      styleEl.rules.push({\n        source: IncrementalSource.StyleSheetRule,\n        adds: injectStylesRules.map((cssText, index) => ({\n          rule: cssText,\n          index,\n        })),\n      });\n    } else {\n      const styleEl = document.createElement('style');\n      (documentElement as HTMLElement).insertBefore(\n        styleEl,\n        head as HTMLHeadElement,\n      );\n      for (let idx = 0; idx < injectStylesRules.length; idx++) {\n        styleEl.sheet?.insertRule(injectStylesRules[idx], idx);\n      }\n    }\n  }\n\n  private attachDocumentToIframe(\n    mutation: addedNodeMutation,\n    iframeEl: HTMLIFrameElement | RRIFrameElement,\n  ) {\n    const mirror: RRDOMMirror | Mirror = this.usingVirtualDom\n      ? this.virtualDom.mirror\n      : this.mirror;\n    type TNode = typeof mirror extends Mirror ? Node : RRNode;\n    type TMirror = typeof mirror extends Mirror ? Mirror : RRDOMMirror;\n\n    const collectedIframes: AppendedIframe[] = [];\n    const collectedDialogs = new Set<HTMLDialogElement>();\n    const afterAppend = (builtNode: Node, id: number) => {\n      if (builtNode.nodeName === 'DIALOG')\n        collectedDialogs.add(builtNode as HTMLDialogElement);\n      this.collectIframeAndAttachDocument(collectedIframes, builtNode);\n      const sn = (mirror as TMirror).getMeta(builtNode as unknown as TNode);\n      if (\n        sn?.type === NodeType.Element &&\n        sn?.tagName.toUpperCase() === 'HTML'\n      ) {\n        const { documentElement, head } = iframeEl.contentDocument!;\n        this.insertStyleRules(\n          documentElement as HTMLElement | RRElement,\n          head as HTMLElement | RRElement,\n        );\n      }\n\n      // Skip the plugin onBuild callback in the virtual dom mode\n      if (this.usingVirtualDom) return;\n      for (const plugin of this.config.plugins || []) {\n        if (plugin.onBuild)\n          plugin.onBuild(builtNode, {\n            id,\n            replayer: this,\n          });\n      }\n    };\n\n    buildNodeWithSN(mutation.node, {\n      doc: iframeEl.contentDocument! as Document,\n      mirror: mirror as Mirror,\n      hackCss: true,\n      skipChild: false,\n      afterAppend,\n      cache: this.cache,\n    });\n    afterAppend(iframeEl.contentDocument! as Document, mutation.node.id);\n\n    for (const { mutationInQueue, builtNode } of collectedIframes) {\n      this.attachDocumentToIframe(mutationInQueue, builtNode);\n      this.newDocumentQueue = this.newDocumentQueue.filter(\n        (m) => m !== mutationInQueue,\n      );\n    }\n\n    collectedDialogs.forEach((d) => applyDialogToTopLevel(d));\n  }\n\n  private collectIframeAndAttachDocument(\n    collected: AppendedIframe[],\n    builtNode: Node,\n  ) {\n    if (isSerializedIframe(builtNode, this.mirror)) {\n      const mutationInQueue = this.newDocumentQueue.find(\n        (m) => m.parentId === this.mirror.getId(builtNode),\n      );\n      if (mutationInQueue) {\n        collected.push({\n          mutationInQueue,\n          builtNode: builtNode as HTMLIFrameElement,\n        });\n      }\n    }\n  }\n\n  /**\n   * pause when loading style sheet, resume when loaded all timeout exceed\n   */\n  private waitForStylesheetLoad() {\n    const head = this.iframe.contentDocument?.head;\n    if (head) {\n      const unloadSheets: Set<HTMLLinkElement> = new Set();\n      let timer: ReturnType<typeof setTimeout> | -1;\n      let beforeLoadState = this.service.state;\n      const stateHandler = () => {\n        beforeLoadState = this.service.state;\n      };\n      this.emitter.on(ReplayerEvents.Start, stateHandler);\n      this.emitter.on(ReplayerEvents.Pause, stateHandler);\n      const unsubscribe = () => {\n        this.emitter.off(ReplayerEvents.Start, stateHandler);\n        this.emitter.off(ReplayerEvents.Pause, stateHandler);\n      };\n      head\n        .querySelectorAll('link[rel=\"stylesheet\"]')\n        .forEach((css: HTMLLinkElement) => {\n          if (!css.sheet) {\n            unloadSheets.add(css);\n            css.addEventListener('load', () => {\n              unloadSheets.delete(css);\n              // all loaded and timer not released yet\n              if (unloadSheets.size === 0 && timer !== -1) {\n                if (beforeLoadState.matches('playing')) {\n                  this.play(this.getCurrentTime());\n                }\n                this.emitter.emit(ReplayerEvents.LoadStylesheetEnd);\n                if (timer) {\n                  clearTimeout(timer);\n                }\n                unsubscribe();\n              }\n            });\n          }\n        });\n\n      if (unloadSheets.size > 0) {\n        // find some unload sheets after iterate\n        this.service.send({ type: 'PAUSE' });\n        this.emitter.emit(ReplayerEvents.LoadStylesheetStart);\n        timer = setTimeout(() => {\n          if (beforeLoadState.matches('playing')) {\n            this.play(this.getCurrentTime());\n          }\n          // mark timer was called\n          timer = -1;\n          unsubscribe();\n        }, this.config.loadTimeout);\n      }\n    }\n  }\n\n  /**\n   * pause when there are some canvas drawImage args need to be loaded\n   */\n  private async preloadAllImages(): Promise<void[]> {\n    const promises: Promise<void>[] = [];\n    for (const event of this.service.state.context.events) {\n      if (\n        event.type === EventType.IncrementalSnapshot &&\n        event.data.source === IncrementalSource.CanvasMutation\n      ) {\n        promises.push(\n          this.deserializeAndPreloadCanvasEvents(event.data, event),\n        );\n        const commands =\n          'commands' in event.data ? event.data.commands : [event.data];\n        commands.forEach((c) => {\n          this.preloadImages(c, event);\n        });\n      }\n    }\n    return Promise.all(promises);\n  }\n\n  private preloadImages(data: canvasMutationCommand, event: eventWithTime) {\n    if (\n      data.property === 'drawImage' &&\n      typeof data.args[0] === 'string' &&\n      !this.imageMap.has(event)\n    ) {\n      const canvas = document.createElement('canvas');\n      const ctx = canvas.getContext('2d');\n      const imgd = ctx?.createImageData(canvas.width, canvas.height);\n      ctx?.putImageData(imgd!, 0, 0);\n    }\n  }\n  private async deserializeAndPreloadCanvasEvents(\n    data: canvasMutationData,\n    event: eventWithTime,\n  ) {\n    if (!this.canvasEventMap.has(event)) {\n      const status = {\n        isUnchanged: true,\n      };\n      if ('commands' in data) {\n        const commands = await Promise.all(\n          data.commands.map(async (c) => {\n            const args = await Promise.all(\n              c.args.map(deserializeArg(this.imageMap, null, status)),\n            );\n            return { ...c, args };\n          }),\n        );\n        if (status.isUnchanged === false)\n          this.canvasEventMap.set(event, { ...data, commands });\n      } else {\n        const args = await Promise.all(\n          data.args.map(deserializeArg(this.imageMap, null, status)),\n        );\n        if (status.isUnchanged === false)\n          this.canvasEventMap.set(event, { ...data, args });\n      }\n    }\n  }\n\n  private applyIncremental(\n    e: incrementalSnapshotEvent & { timestamp: number; delay?: number },\n    isSync: boolean,\n  ) {\n    const { data: d } = e;\n    switch (d.source) {\n      case IncrementalSource.Mutation: {\n        try {\n          this.applyMutation(d, isSync);\n        } catch (error) {\n          // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/restrict-template-expressions\n          this.warn(`Exception in mutation ${error.message || error}`, d);\n        }\n        break;\n      }\n      case IncrementalSource.Drag:\n      case IncrementalSource.TouchMove:\n      case IncrementalSource.MouseMove:\n        if (isSync) {\n          const lastPosition = d.positions[d.positions.length - 1];\n          this.mousePos = {\n            x: lastPosition.x,\n            y: lastPosition.y,\n            id: lastPosition.id,\n            debugData: d,\n          };\n        } else {\n          d.positions.forEach((p) => {\n            const action = {\n              doAction: () => {\n                this.moveAndHover(p.x, p.y, p.id, isSync, d);\n              },\n              delay:\n                p.timeOffset +\n                e.timestamp -\n                this.service.state.context.baselineTime,\n            };\n            this.timer.addAction(action);\n          });\n          // add a dummy action to keep timer alive\n          this.timer.addAction({\n            doAction() {\n              //\n            },\n            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n            delay: e.delay! - d.positions[0]?.timeOffset,\n          });\n        }\n        break;\n      case IncrementalSource.MouseInteraction: {\n        /**\n         * Same as the situation of missing input target.\n         */\n        if (d.id === -1) {\n          break;\n        }\n        const event = new Event(toLowerCase(MouseInteractions[d.type]));\n        const target = this.mirror.getNode(d.id);\n        if (!target) {\n          return this.debugNodeNotFound(d, d.id);\n        }\n        this.emitter.emit(ReplayerEvents.MouseInteraction, {\n          type: d.type,\n          target,\n        });\n        const { triggerFocus } = this.config;\n        switch (d.type) {\n          case MouseInteractions.Blur:\n            if ('blur' in (target as HTMLElement)) {\n              (target as HTMLElement).blur();\n            }\n            break;\n          case MouseInteractions.Focus:\n            if (triggerFocus && (target as HTMLElement).focus) {\n              (target as HTMLElement).focus({\n                preventScroll: true,\n              });\n            }\n            break;\n          case MouseInteractions.Click:\n          case MouseInteractions.TouchStart:\n          case MouseInteractions.TouchEnd:\n          case MouseInteractions.MouseDown:\n          case MouseInteractions.MouseUp:\n            if (isSync) {\n              if (d.type === MouseInteractions.TouchStart) {\n                this.touchActive = true;\n              } else if (d.type === MouseInteractions.TouchEnd) {\n                this.touchActive = false;\n              }\n              if (d.type === MouseInteractions.MouseDown) {\n                this.lastMouseDownEvent = [target, event];\n              } else if (d.type === MouseInteractions.MouseUp) {\n                this.lastMouseDownEvent = null;\n              }\n              this.mousePos = {\n                x: d.x || 0,\n                y: d.y || 0,\n                id: d.id,\n                debugData: d,\n              };\n            } else {\n              if (d.type === MouseInteractions.TouchStart) {\n                // don't draw a trail as user has lifted finger and is placing at a new point\n                this.tailPositions.length = 0;\n              }\n              this.moveAndHover(d.x || 0, d.y || 0, d.id, isSync, d);\n              if (d.type === MouseInteractions.Click) {\n                /*\n                 * don't want target.click() here as could trigger an iframe navigation\n                 * instead any effects of the click should already be covered by mutations\n                 */\n                /*\n                 * removal and addition of .active class (along with void line to trigger repaint)\n                 * triggers the 'click' css animation in styles/style.css\n                 */\n                this.mouse.classList.remove('active');\n                void this.mouse.offsetWidth;\n                this.mouse.classList.add('active');\n              } else if (d.type === MouseInteractions.TouchStart) {\n                void this.mouse.offsetWidth; // needed for the position update of moveAndHover to apply without the .touch-active transition\n                this.mouse.classList.add('touch-active');\n              } else if (d.type === MouseInteractions.TouchEnd) {\n                this.mouse.classList.remove('touch-active');\n              } else {\n                // for MouseDown & MouseUp also invoke default behavior\n                target.dispatchEvent(event);\n              }\n            }\n            break;\n          case MouseInteractions.TouchCancel:\n            if (isSync) {\n              this.touchActive = false;\n            } else {\n              this.mouse.classList.remove('touch-active');\n            }\n            break;\n          default:\n            target.dispatchEvent(event);\n        }\n        break;\n      }\n      case IncrementalSource.Scroll: {\n        /**\n         * Same as the situation of missing input target.\n         */\n        if (d.id === -1) {\n          break;\n        }\n        if (this.usingVirtualDom) {\n          const target = this.virtualDom.mirror.getNode(d.id) as RRElement;\n          if (!target) {\n            return this.debugNodeNotFound(d, d.id);\n          }\n          target.scrollData = d;\n          break;\n        }\n        // Use isSync rather than this.usingVirtualDom because not every fast-forward process uses virtual dom optimization.\n        this.applyScroll(d, isSync);\n        break;\n      }\n      case IncrementalSource.ViewportResize:\n        this.emitter.emit(ReplayerEvents.Resize, {\n          width: d.width,\n          height: d.height,\n        });\n        break;\n      case IncrementalSource.Input: {\n        /**\n         * Input event on an unserialized node usually means the event\n         * was synchrony triggered programmatically after the node was\n         * created. This means there was not an user observable interaction\n         * and we do not need to replay it.\n         */\n        if (d.id === -1) {\n          break;\n        }\n        if (this.usingVirtualDom) {\n          const target = this.virtualDom.mirror.getNode(d.id) as RRElement;\n          if (!target) {\n            return this.debugNodeNotFound(d, d.id);\n          }\n          target.inputData = d;\n          break;\n        }\n        this.applyInput(d);\n        break;\n      }\n      case IncrementalSource.MediaInteraction: {\n        const target = this.usingVirtualDom\n          ? this.virtualDom.mirror.getNode(d.id)\n          : this.mirror.getNode(d.id);\n        if (!target) {\n          return this.debugNodeNotFound(d, d.id);\n        }\n        const mediaEl = target as HTMLMediaElement | RRMediaElement;\n        const { events } = this.service.state.context;\n\n        this.mediaManager.mediaMutation({\n          target: mediaEl,\n          timeOffset: e.timestamp - events[0].timestamp,\n          mutation: d,\n        });\n\n        break;\n      }\n      case IncrementalSource.StyleSheetRule:\n      case IncrementalSource.StyleDeclaration: {\n        if (this.usingVirtualDom) {\n          if (d.styleId) this.constructedStyleMutations.push(d);\n          else if (d.id)\n            (\n              this.virtualDom.mirror.getNode(d.id) as RRStyleElement | null\n            )?.rules.push(d);\n        } else this.applyStyleSheetMutation(d);\n        break;\n      }\n      case IncrementalSource.CanvasMutation: {\n        if (!this.config.UNSAFE_replayCanvas) {\n          return;\n        }\n        if (this.usingVirtualDom) {\n          const target = this.virtualDom.mirror.getNode(\n            d.id,\n          ) as RRCanvasElement;\n          if (!target) {\n            return this.debugNodeNotFound(d, d.id);\n          }\n          target.canvasMutations.push({\n            event: e as canvasEventWithTime,\n            mutation: d,\n          });\n        } else {\n          const target = this.mirror.getNode(d.id);\n          if (!target) {\n            return this.debugNodeNotFound(d, d.id);\n          }\n          void canvasMutation({\n            event: e,\n            mutation: d,\n            target: target as HTMLCanvasElement,\n            imageMap: this.imageMap,\n            canvasEventMap: this.canvasEventMap,\n            errorHandler: this.warnCanvasMutationFailed.bind(this),\n          });\n        }\n        break;\n      }\n      case IncrementalSource.Font: {\n        try {\n          const fontFace = new FontFace(\n            d.family,\n            d.buffer\n              ? new Uint8Array(JSON.parse(d.fontSource) as Iterable<number>)\n              : d.fontSource,\n            d.descriptors,\n          );\n          this.iframe.contentDocument?.fonts.add(fontFace);\n        } catch (error) {\n          this.warn(error);\n        }\n        break;\n      }\n      case IncrementalSource.Selection: {\n        if (isSync) {\n          this.lastSelectionData = d;\n          break;\n        }\n        this.applySelection(d);\n        break;\n      }\n      case IncrementalSource.AdoptedStyleSheet: {\n        if (this.usingVirtualDom) this.adoptedStyleSheets.push(d);\n        else this.applyAdoptedStyleSheet(d);\n        break;\n      }\n      default:\n    }\n  }\n\n  /**\n   * Apply the mutation to the virtual dom or the real dom.\n   * @param d - The mutation data.\n   * @param isSync - Whether the mutation should be applied synchronously (while fast-forwarding).\n   */\n  private applyMutation(d: mutationData, isSync: boolean) {\n    // Only apply virtual dom optimization if the fast-forward process has node mutation. Because the cost of creating a virtual dom tree and executing the diff algorithm is usually higher than directly applying other kind of events.\n    if (this.config.useVirtualDom && !this.usingVirtualDom && isSync) {\n      this.usingVirtualDom = true;\n      buildFromDom(this.iframe.contentDocument!, this.mirror, this.virtualDom);\n      // If these legacy missing nodes haven't been resolved, they should be converted to virtual nodes.\n      if (Object.keys(this.legacy_missingNodeRetryMap).length) {\n        for (const key in this.legacy_missingNodeRetryMap) {\n          try {\n            const value = this.legacy_missingNodeRetryMap[key];\n            const virtualNode = buildFromNode(\n              value.node as Node,\n              this.virtualDom,\n              this.mirror,\n            );\n            if (virtualNode) value.node = virtualNode;\n          } catch (error) {\n            this.warn(error);\n          }\n        }\n      }\n    }\n    const mirror = this.usingVirtualDom ? this.virtualDom.mirror : this.mirror;\n    type TNode = typeof mirror extends Mirror ? Node : RRNode;\n\n    d.removes = d.removes.filter((mutation) => {\n      // warn of absence from mirror before we start applying each removal\n      // as earlier removals could remove a tree that includes a later removal\n      if (!mirror.getNode(mutation.id)) {\n        this.warnNodeNotFound(d, mutation.id);\n        return false;\n      }\n      return true;\n    });\n    d.removes.forEach((mutation) => {\n      const target = mirror.getNode(mutation.id);\n      if (!target) {\n        // no need to warn here, an ancestor may have already been removed\n        return;\n      }\n      let parent: Node | null | ShadowRoot | RRNode = mirror.getNode(\n        mutation.parentId,\n      );\n      if (!parent) {\n        return this.warnNodeNotFound(d, mutation.parentId);\n      }\n      if (mutation.isShadow && hasShadowRoot(parent as Node)) {\n        parent = (parent as Element | RRElement).shadowRoot;\n      }\n      // target may be removed with its parents before\n      mirror.removeNodeFromMap(target as Node & RRNode);\n      if (parent)\n        try {\n          parent.removeChild(target as Node & RRNode);\n          /**\n           * https://github.com/rrweb-io/rrweb/pull/887\n           * Remove any virtual style rules for stylesheets if a child text node is removed.\n           */\n          if (\n            this.usingVirtualDom &&\n            target.nodeName === '#text' &&\n            parent.nodeName === 'STYLE' &&\n            (parent as RRStyleElement).rules?.length > 0\n          )\n            (parent as RRStyleElement).rules = [];\n        } catch (error) {\n          if (error instanceof DOMException) {\n            this.warn(\n              'parent could not remove child in mutation',\n              parent,\n              target,\n              d,\n            );\n          } else {\n            throw error;\n          }\n        }\n    });\n\n    const legacy_missingNodeMap: missingNodeMap = {\n      ...this.legacy_missingNodeRetryMap,\n    };\n    const queue: addedNodeMutation[] = [];\n\n    // next not present at this moment\n    const nextNotInDOM = (mutation: addedNodeMutation) => {\n      let next: TNode | null = null;\n      if (mutation.nextId) {\n        next = mirror.getNode(mutation.nextId) as TNode | null;\n      }\n      // next not present at this moment\n      if (\n        mutation.nextId !== null &&\n        mutation.nextId !== undefined &&\n        mutation.nextId !== -1 &&\n        !next\n      ) {\n        return true;\n      }\n      return false;\n    };\n\n    const appendNode = (mutation: addedNodeMutation) => {\n      if (!this.iframe.contentDocument) {\n        return this.warn('Looks like your replayer has been destroyed.');\n      }\n      let parent: Node | null | ShadowRoot | RRNode = mirror.getNode(\n        mutation.parentId,\n      );\n      if (!parent) {\n        if (mutation.node.type === NodeType.Document) {\n          // is newly added document, maybe the document node of an iframe\n          return this.newDocumentQueue.push(mutation);\n        }\n        return queue.push(mutation);\n      }\n\n      if (mutation.node.isShadow) {\n        // If the parent is attached a shadow dom after it's created, it won't have a shadow root.\n        if (!hasShadowRoot(parent)) {\n          (parent as Element | RRElement).attachShadow({ mode: 'open' });\n          parent = (parent as Element | RRElement).shadowRoot! as Node | RRNode;\n        } else parent = parent.shadowRoot as Node | RRNode;\n      }\n\n      let previous: Node | RRNode | null = null;\n      let next: Node | RRNode | null = null;\n      if (mutation.previousId) {\n        previous = mirror.getNode(mutation.previousId);\n      }\n      if (mutation.nextId) {\n        next = mirror.getNode(mutation.nextId);\n      }\n      if (nextNotInDOM(mutation)) {\n        return queue.push(mutation);\n      }\n\n      if (mutation.node.rootId && !mirror.getNode(mutation.node.rootId)) {\n        return;\n      }\n\n      const targetDoc = mutation.node.rootId\n        ? mirror.getNode(mutation.node.rootId)\n        : this.usingVirtualDom\n        ? this.virtualDom\n        : this.iframe.contentDocument;\n      if (isSerializedIframe<typeof parent>(parent, mirror)) {\n        this.attachDocumentToIframe(\n          mutation,\n          parent as HTMLIFrameElement | RRIFrameElement,\n        );\n        return;\n      }\n      const afterAppend = (node: Node | RRNode, id: number) => {\n        // Skip the plugin onBuild callback for virtual dom\n        if (this.usingVirtualDom) return;\n        applyDialogToTopLevel(node);\n        for (const plugin of this.config.plugins || []) {\n          if (plugin.onBuild) plugin.onBuild(node, { id, replayer: this });\n        }\n      };\n\n      const target = buildNodeWithSN(mutation.node, {\n        doc: targetDoc as Document, // can be Document or RRDocument\n        mirror: mirror as Mirror, // can be this.mirror or virtualDom.mirror\n        skipChild: true,\n        hackCss: true,\n        cache: this.cache,\n        /**\n         * caveat: `afterAppend` only gets called on child nodes of target\n         * we have to call it again below when this target was added to the DOM\n         */\n        afterAppend,\n      }) as Node | RRNode;\n\n      // legacy data, we should not have -1 siblings any more\n      if (mutation.previousId === -1 || mutation.nextId === -1) {\n        legacy_missingNodeMap[mutation.node.id] = {\n          node: target,\n          mutation,\n        };\n        return;\n      }\n\n      // Typescripts type system is not smart enough\n      // to understand what is going on with the types below\n      type TNode = typeof mirror extends Mirror ? Node : RRNode;\n      type TMirror = typeof mirror extends Mirror ? Mirror : RRDOMMirror;\n\n      const parentSn = (mirror as TMirror).getMeta(parent as TNode);\n      if (\n        parentSn &&\n        parentSn.type === NodeType.Element &&\n        mutation.node.type === NodeType.Text\n      ) {\n        const prospectiveSiblings = Array.isArray(parent.childNodes)\n          ? parent.childNodes\n          : Array.from(parent.childNodes);\n        if (parentSn.tagName === 'textarea') {\n          // This should be redundant now as we are either recording the value or the childNode, and not both\n          // keeping around for backwards compatibility with old bad double data, see\n\n          // https://github.com/rrweb-io/rrweb/issues/745\n          // parent is textarea, will only keep one child node as the value\n          for (const c of prospectiveSiblings) {\n            if (c.nodeType === parent.TEXT_NODE) {\n              parent.removeChild(c as Node & RRNode);\n            }\n          }\n        } else if (\n          parentSn.tagName === 'style' &&\n          prospectiveSiblings.length === 1\n        ) {\n          // https://github.com/rrweb-io/rrweb/pull/1417\n          /**\n           * If both _cssText and textContent are present for a style element due to some existing bugs, the element was ending up with two child text nodes\n           * We need to remove the textNode created by _cssText as it doesn't have an id in the mirror, and thus cannot be further mutated.\n           */\n          for (const cssText of prospectiveSiblings as (Node & RRNode)[]) {\n            if (\n              cssText.nodeType === parent.TEXT_NODE &&\n              !mirror.hasNode(cssText)\n            ) {\n              target.textContent = cssText.textContent;\n              parent.removeChild(cssText);\n            }\n          }\n        }\n      } else if (parentSn?.type === NodeType.Document) {\n        /**\n         * Sometimes the document object is changed or reopened and the MutationObserver is disconnected, so the removal of child elements can't be detected and recorded.\n         * After the change of document, we may get another mutation which adds a new doctype or a HTML element, while the old one still exists in the dom.\n         * So, we need to remove the old one first to avoid collision.\n         */\n        const parentDoc = parent as Document | RRDocument;\n        /**\n         * To detect the exist of the old doctype before adding a new doctype.\n         * We need to remove the old doctype before adding the new one. Otherwise, code will throw \"mutation Failed to execute 'insertBefore' on 'Node': Only one doctype on document allowed\".\n         */\n        if (\n          mutation.node.type === NodeType.DocumentType &&\n          parentDoc.childNodes[0]?.nodeType === Node.DOCUMENT_TYPE_NODE\n        )\n          parentDoc.removeChild(parentDoc.childNodes[0] as Node & RRNode);\n        /**\n         * To detect the exist of the old HTML element before adding a new HTML element.\n         * The reason is similar to the above. One document only allows exactly one DocType and one HTML Element.\n         */\n        if (target.nodeName === 'HTML' && parentDoc.documentElement)\n          parentDoc.removeChild(\n            parentDoc.documentElement as HTMLElement & RRNode,\n          );\n      }\n\n      if (previous && previous.nextSibling && previous.nextSibling.parentNode) {\n        (parent as TNode).insertBefore(\n          target as TNode,\n          previous.nextSibling as TNode,\n        );\n      } else if (next && next.parentNode) {\n        // making sure the parent contains the reference nodes\n        // before we insert target before next.\n        (parent as TNode).contains(next as TNode)\n          ? (parent as TNode).insertBefore(target as TNode, next as TNode)\n          : (parent as TNode).insertBefore(target as TNode, null);\n      } else {\n        (parent as TNode).appendChild(target as TNode);\n      }\n      /**\n       * target was added, execute plugin hooks\n       */\n      afterAppend(target, mutation.node.id);\n\n      /**\n       * https://github.com/rrweb-io/rrweb/pull/887\n       * Remove any virtual style rules for stylesheets if a new text node is appended.\n       */\n      if (\n        this.usingVirtualDom &&\n        target.nodeName === '#text' &&\n        parent.nodeName === 'STYLE' &&\n        (parent as RRStyleElement).rules?.length > 0\n      )\n        (parent as RRStyleElement).rules = [];\n\n      if (isSerializedIframe(target, this.mirror)) {\n        const targetId = this.mirror.getId(target as HTMLIFrameElement);\n        const mutationInQueue = this.newDocumentQueue.find(\n          (m) => m.parentId === targetId,\n        );\n        if (mutationInQueue) {\n          this.attachDocumentToIframe(\n            mutationInQueue,\n            target as HTMLIFrameElement,\n          );\n          this.newDocumentQueue = this.newDocumentQueue.filter(\n            (m) => m !== mutationInQueue,\n          );\n        }\n      }\n\n      if (mutation.previousId || mutation.nextId) {\n        this.legacy_resolveMissingNode(\n          legacy_missingNodeMap,\n          parent,\n          target,\n          mutation,\n        );\n      }\n    };\n\n    d.adds.forEach((mutation) => {\n      appendNode(mutation);\n    });\n\n    const startTime = Date.now();\n    while (queue.length) {\n      // transform queue to resolve tree\n      const resolveTrees = queueToResolveTrees(queue);\n      queue.length = 0;\n      if (Date.now() - startTime > 500) {\n        this.warn(\n          'Timeout in the loop, please check the resolve tree data:',\n          resolveTrees,\n        );\n        break;\n      }\n      for (const tree of resolveTrees) {\n        const parent = mirror.getNode(tree.value.parentId);\n        if (!parent) {\n          this.debug(\n            'Drop resolve tree since there is no parent for the root node.',\n            tree,\n          );\n        } else {\n          iterateResolveTree(tree, (mutation) => {\n            appendNode(mutation);\n          });\n        }\n      }\n    }\n\n    if (Object.keys(legacy_missingNodeMap).length) {\n      Object.assign(this.legacy_missingNodeRetryMap, legacy_missingNodeMap);\n    }\n\n    uniqueTextMutations(d.texts).forEach((mutation) => {\n      const target = mirror.getNode(mutation.id);\n      if (!target) {\n        if (d.removes.find((r) => r.id === mutation.id)) {\n          // no need to warn, element was already removed\n          return;\n        }\n        return this.warnNodeNotFound(d, mutation.id);\n      }\n\n      const parentEl = target.parentElement as Element | RRElement;\n      if (mutation.value && parentEl && parentEl.tagName === 'STYLE') {\n        // assumes hackCss: true (which isn't currently configurable from rrweb)\n        target.textContent = adaptCssForReplay(mutation.value, this.cache);\n      } else {\n        target.textContent = mutation.value;\n      }\n\n      /**\n       * https://github.com/rrweb-io/rrweb/pull/865\n       * Remove any virtual style rules for stylesheets whose contents are replaced.\n       */\n      if (this.usingVirtualDom) {\n        const parent = target.parentNode as RRStyleElement;\n        if (parent?.rules?.length > 0) parent.rules = [];\n      }\n    });\n    d.attributes.forEach((mutation) => {\n      const target = mirror.getNode(mutation.id);\n      if (!target) {\n        if (d.removes.find((r) => r.id === mutation.id)) {\n          // no need to warn, element was already removed\n          return;\n        }\n        return this.warnNodeNotFound(d, mutation.id);\n      }\n      for (const attributeName in mutation.attributes) {\n        if (typeof attributeName === 'string') {\n          const value = mutation.attributes[attributeName];\n          if (value === null) {\n            (target as Element | RRElement).removeAttribute(attributeName);\n            if (attributeName === 'open')\n              removeDialogFromTopLevel(target, mutation);\n          } else if (typeof value === 'string') {\n            try {\n              // When building snapshot, some link styles haven't loaded. Then they are loaded, they will be inlined as incremental mutation change of attribute. We need to replace the old elements whose styles aren't inlined.\n              if (\n                attributeName === '_cssText' &&\n                (target.nodeName === 'LINK' || target.nodeName === 'STYLE')\n              ) {\n                try {\n                  const newSn = mirror.getMeta(\n                    target as Node & RRNode,\n                  ) as serializedElementNodeWithId;\n                  const newNode = buildNodeWithSN(\n                    {\n                      ...newSn,\n                      attributes: {\n                        ...newSn.attributes,\n                        ...(mutation.attributes as attributes),\n                      },\n                    },\n                    {\n                      doc: target.ownerDocument as Document, // can be Document or RRDocument\n                      mirror: mirror as Mirror,\n                      skipChild: true,\n                      hackCss: true,\n                      cache: this.cache,\n                    },\n                  );\n                  // Update mirror meta's attributes\n                  Object.assign(\n                    newSn.attributes,\n                    mutation.attributes as attributes,\n                  );\n                  const siblingNode = target.nextSibling;\n                  const parentNode = target.parentNode;\n                  if (newNode && parentNode) {\n                    parentNode.removeChild(target as Node & RRNode);\n                    parentNode.insertBefore(\n                      newNode as Node & RRNode,\n                      siblingNode as (Node & RRNode) | null,\n                    );\n                    mirror.replace(mutation.id, newNode as Node & RRNode);\n                    break;\n                  }\n                } catch (e) {\n                  // for safe\n                }\n              }\n              if (attributeName === 'value' && target.nodeName === 'TEXTAREA') {\n                // this may or may not have an effect on the value property (which is what is displayed)\n                // depending on whether the textarea has been modified by the user yet\n                // TODO: replaceChildNodes is not available in RRDom\n                const textarea = target as TNode;\n                textarea.childNodes.forEach((c) =>\n                  textarea.removeChild(c as TNode),\n                );\n                const tn = target.ownerDocument?.createTextNode(value);\n                if (tn) {\n                  textarea.appendChild(tn as TNode);\n                }\n              } else {\n                (target as Element | RRElement).setAttribute(\n                  attributeName,\n                  value,\n                );\n              }\n\n              if (\n                attributeName === 'rr_open_mode' &&\n                target.nodeName === 'DIALOG'\n              ) {\n                applyDialogToTopLevel(target, mutation);\n              }\n            } catch (error) {\n              this.warn(\n                'An error occurred may due to the checkout feature.',\n                error,\n              );\n            }\n          } else if (attributeName === 'style') {\n            const styleValues = value;\n            const targetEl = target as HTMLElement | RRElement;\n            for (const s in styleValues) {\n              if (styleValues[s] === false) {\n                targetEl.style.removeProperty(s);\n              } else if (styleValues[s] instanceof Array) {\n                const svp = styleValues[s] as styleValueWithPriority;\n                targetEl.style.setProperty(s, svp[0], svp[1]);\n              } else {\n                const svs = styleValues[s] as string;\n                targetEl.style.setProperty(s, svs);\n              }\n            }\n          }\n        }\n      }\n    });\n  }\n\n  /**\n   * Apply the scroll data on real elements.\n   * If the replayer is in sync mode, smooth scroll behavior should be disabled.\n   * @param d - the scroll data\n   * @param isSync - whether the replayer is in sync mode(fast-forward)\n   */\n  private applyScroll(d: scrollData, isSync: boolean) {\n    const target = this.mirror.getNode(d.id);\n    if (!target) {\n      return this.debugNodeNotFound(d, d.id);\n    }\n    const sn = this.mirror.getMeta(target);\n    if (target === this.iframe.contentDocument) {\n      this.iframe.contentWindow?.scrollTo({\n        top: d.y,\n        left: d.x,\n        behavior: isSync ? 'auto' : 'smooth',\n      });\n    } else if (sn?.type === NodeType.Document) {\n      // nest iframe content document\n      (target as Document).defaultView?.scrollTo({\n        top: d.y,\n        left: d.x,\n        behavior: isSync ? 'auto' : 'smooth',\n      });\n    } else {\n      try {\n        (target as Element).scrollTo({\n          top: d.y,\n          left: d.x,\n          behavior: isSync ? 'auto' : 'smooth',\n        });\n      } catch (error) {\n        /**\n         * Seldomly we may found scroll target was removed before\n         * its last scroll event.\n         */\n      }\n    }\n  }\n\n  private applyInput(d: inputData) {\n    const target = this.mirror.getNode(d.id);\n    if (!target) {\n      return this.debugNodeNotFound(d, d.id);\n    }\n    try {\n      (target as HTMLInputElement).checked = d.isChecked;\n      (target as HTMLInputElement).value = d.text;\n    } catch (error) {\n      // for safe\n    }\n  }\n\n  private applySelection(d: selectionData) {\n    try {\n      const selectionSet = new Set<Selection>();\n      const ranges = d.ranges.map(({ start, startOffset, end, endOffset }) => {\n        const startContainer = this.mirror.getNode(start);\n        const endContainer = this.mirror.getNode(end);\n\n        if (!startContainer || !endContainer) return;\n\n        const result = new Range();\n\n        result.setStart(startContainer, startOffset);\n        result.setEnd(endContainer, endOffset);\n        const doc = startContainer.ownerDocument;\n        const selection = doc?.getSelection();\n        selection && selectionSet.add(selection);\n\n        return {\n          range: result,\n          selection,\n        };\n      });\n\n      selectionSet.forEach((s) => s.removeAllRanges());\n\n      ranges.forEach((r) => r && r.selection?.addRange(r.range));\n    } catch (error) {\n      // for safe\n    }\n  }\n\n  private applyStyleSheetMutation(\n    data: styleDeclarationData | styleSheetRuleData,\n  ) {\n    let styleSheet: CSSStyleSheet | null = null;\n    if (data.styleId) styleSheet = this.styleMirror.getStyle(data.styleId);\n    else if (data.id)\n      styleSheet =\n        (this.mirror.getNode(data.id) as HTMLStyleElement)?.sheet || null;\n    if (!styleSheet) return;\n    if (data.source === IncrementalSource.StyleSheetRule)\n      this.applyStyleSheetRule(data, styleSheet);\n    else if (data.source === IncrementalSource.StyleDeclaration)\n      this.applyStyleDeclaration(data, styleSheet);\n  }\n\n  private applyStyleSheetRule(\n    data: styleSheetRuleData,\n    styleSheet: CSSStyleSheet,\n  ) {\n    data.adds?.forEach(({ rule, index: nestedIndex }) => {\n      try {\n        if (Array.isArray(nestedIndex)) {\n          const { positions, index } = getPositionsAndIndex(nestedIndex);\n          const nestedRule = getNestedRule(styleSheet.cssRules, positions);\n          nestedRule.insertRule(rule, index);\n        } else {\n          const index =\n            nestedIndex === undefined\n              ? undefined\n              : Math.min(nestedIndex, styleSheet.cssRules.length);\n          styleSheet?.insertRule(rule, index);\n        }\n      } catch (e) {\n        /**\n         * sometimes we may capture rules with browser prefix\n         * insert rule with prefixs in other browsers may cause Error\n         */\n        /**\n         * accessing styleSheet rules may cause SecurityError\n         * for specific access control settings\n         */\n      }\n    });\n\n    data.removes?.forEach(({ index: nestedIndex }) => {\n      try {\n        if (Array.isArray(nestedIndex)) {\n          const { positions, index } = getPositionsAndIndex(nestedIndex);\n          const nestedRule = getNestedRule(styleSheet.cssRules, positions);\n          nestedRule.deleteRule(index || 0);\n        } else {\n          styleSheet?.deleteRule(nestedIndex);\n        }\n      } catch (e) {\n        /**\n         * same as insertRule\n         */\n      }\n    });\n\n    if (data.replace)\n      try {\n        void styleSheet.replace?.(data.replace);\n      } catch (e) {\n        // for safety\n      }\n\n    if (data.replaceSync)\n      try {\n        styleSheet.replaceSync?.(data.replaceSync);\n      } catch (e) {\n        // for safety\n      }\n  }\n\n  private applyStyleDeclaration(\n    data: styleDeclarationData,\n    styleSheet: CSSStyleSheet,\n  ) {\n    if (data.set) {\n      const rule = getNestedRule(\n        styleSheet.rules,\n        data.index,\n      ) as unknown as CSSStyleRule;\n      rule.style.setProperty(\n        data.set.property,\n        data.set.value,\n        data.set.priority,\n      );\n    }\n\n    if (data.remove) {\n      const rule = getNestedRule(\n        styleSheet.rules,\n        data.index,\n      ) as unknown as CSSStyleRule;\n      rule.style.removeProperty(data.remove.property);\n    }\n  }\n\n  private applyAdoptedStyleSheet(data: adoptedStyleSheetData) {\n    const targetHost = this.mirror.getNode(data.id);\n    if (!targetHost) return;\n    // Create StyleSheet objects which will be adopted after.\n    data.styles?.forEach((style) => {\n      let newStyleSheet: CSSStyleSheet | null = null;\n      /**\n       * Constructed StyleSheet can't share across multiple documents.\n       * The replayer has to get the correct host window to recreate a StyleSheetObject.\n       */\n      let hostWindow: IWindow | null = null;\n      if (hasShadowRoot(targetHost))\n        hostWindow = targetHost.ownerDocument?.defaultView || null;\n      else if (targetHost.nodeName === '#document')\n        hostWindow = (targetHost as Document).defaultView;\n\n      if (!hostWindow) return;\n      try {\n        newStyleSheet = new hostWindow.CSSStyleSheet();\n        this.styleMirror.add(newStyleSheet, style.styleId);\n        // To reuse the code of applying stylesheet rules\n        this.applyStyleSheetRule(\n          {\n            source: IncrementalSource.StyleSheetRule,\n            adds: style.rules,\n          },\n          newStyleSheet,\n        );\n      } catch (e) {\n        // In case some browsers don't support constructing StyleSheet.\n      }\n    });\n\n    const MAX_RETRY_TIME = 10;\n    let count = 0;\n    const adoptStyleSheets = (targetHost: Node, styleIds: number[]) => {\n      const stylesToAdopt = styleIds\n        .map((styleId) => this.styleMirror.getStyle(styleId))\n        .filter((style) => style !== null) as CSSStyleSheet[];\n      if (hasShadowRoot(targetHost))\n        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n        (targetHost as HTMLElement).shadowRoot!.adoptedStyleSheets =\n          stylesToAdopt;\n      else if (targetHost.nodeName === '#document')\n        (targetHost as Document).adoptedStyleSheets = stylesToAdopt;\n\n      /**\n       * In the live mode where events are transferred over network without strict order guarantee, some newer events are applied before some old events and adopted stylesheets may haven't been created.\n       * This retry mechanism can help resolve this situation.\n       */\n      if (stylesToAdopt.length !== styleIds.length && count < MAX_RETRY_TIME) {\n        setTimeout(\n          () => adoptStyleSheets(targetHost, styleIds),\n          0 + 100 * count,\n        );\n        count++;\n      }\n    };\n    adoptStyleSheets(targetHost, data.styleIds);\n  }\n\n  private legacy_resolveMissingNode(\n    map: missingNodeMap,\n    parent: Node | RRNode,\n    target: Node | RRNode,\n    targetMutation: addedNodeMutation,\n  ) {\n    const { previousId, nextId } = targetMutation;\n    const previousInMap = previousId && map[previousId];\n    const nextInMap = nextId && map[nextId];\n    if (previousInMap) {\n      const { node, mutation } = previousInMap;\n      parent.insertBefore(node as Node & RRNode, target as Node & RRNode);\n      delete map[mutation.node.id];\n      delete this.legacy_missingNodeRetryMap[mutation.node.id];\n      if (mutation.previousId || mutation.nextId) {\n        this.legacy_resolveMissingNode(map, parent, node, mutation);\n      }\n    }\n    if (nextInMap) {\n      const { node, mutation } = nextInMap;\n      parent.insertBefore(\n        node as Node & RRNode,\n        target.nextSibling as Node & RRNode,\n      );\n      delete map[mutation.node.id];\n      delete this.legacy_missingNodeRetryMap[mutation.node.id];\n      if (mutation.previousId || mutation.nextId) {\n        this.legacy_resolveMissingNode(map, parent, node, mutation);\n      }\n    }\n  }\n\n  private moveAndHover(\n    x: number,\n    y: number,\n    id: number,\n    isSync: boolean,\n    debugData: incrementalData,\n  ) {\n    const target = this.mirror.getNode(id);\n    if (!target) {\n      return this.debugNodeNotFound(debugData, id);\n    }\n\n    const base = getBaseDimension(target, this.iframe);\n    const _x = x * base.absoluteScale + base.x;\n    const _y = y * base.absoluteScale + base.y;\n\n    this.mouse.style.left = `${_x}px`;\n    this.mouse.style.top = `${_y}px`;\n    if (!isSync) {\n      this.drawMouseTail({ x: _x, y: _y });\n    }\n    this.hoverElements(target as Element);\n  }\n\n  private drawMouseTail(position: { x: number; y: number }) {\n    if (!this.mouseTail) {\n      return;\n    }\n\n    const { lineCap, lineWidth, strokeStyle, duration } =\n      this.config.mouseTail === true\n        ? defaultMouseTailConfig\n        : Object.assign({}, defaultMouseTailConfig, this.config.mouseTail);\n\n    const draw = () => {\n      if (!this.mouseTail) {\n        return;\n      }\n      const ctx = this.mouseTail.getContext('2d');\n      if (!ctx || !this.tailPositions.length) {\n        return;\n      }\n      ctx.clearRect(0, 0, this.mouseTail.width, this.mouseTail.height);\n      ctx.beginPath();\n      ctx.lineWidth = lineWidth;\n      ctx.lineCap = lineCap;\n      ctx.strokeStyle = strokeStyle;\n      ctx.moveTo(this.tailPositions[0].x, this.tailPositions[0].y);\n      this.tailPositions.forEach((p) => ctx.lineTo(p.x, p.y));\n      ctx.stroke();\n    };\n\n    this.tailPositions.push(position);\n    draw();\n    setTimeout(() => {\n      this.tailPositions = this.tailPositions.filter((p) => p !== position);\n      draw();\n    }, duration / this.speedService.state.context.timer.speed);\n  }\n\n  private hoverElements(el: Element) {\n    (this.lastHoveredRootNode || this.iframe.contentDocument)\n      ?.querySelectorAll('.\\\\:hover')\n      .forEach((hoveredEl) => {\n        hoveredEl.classList.remove(':hover');\n      });\n    this.lastHoveredRootNode = el.getRootNode() as Document | ShadowRoot;\n    let currentEl: Element | null = el;\n    while (currentEl) {\n      if (currentEl.classList) {\n        currentEl.classList.add(':hover');\n      }\n      currentEl = currentEl.parentElement;\n    }\n  }\n\n  private isUserInteraction(event: eventWithTime): boolean {\n    if (event.type !== EventType.IncrementalSnapshot) {\n      return false;\n    }\n    return (\n      event.data.source > IncrementalSource.Mutation &&\n      event.data.source <= IncrementalSource.Input\n    );\n  }\n\n  private backToNormal() {\n    this.nextUserInteractionEvent = null;\n    if (this.speedService.state.matches('normal')) {\n      return;\n    }\n    this.speedService.send({ type: 'BACK_TO_NORMAL' });\n    this.emitter.emit(ReplayerEvents.SkipEnd, {\n      speed: this.speedService.state.context.normalSpeed,\n    });\n  }\n\n  private warnNodeNotFound(d: incrementalData, id: number) {\n    this.warn(`Node with id '${id}' not found. `, d);\n  }\n\n  private warnCanvasMutationFailed(\n    d: canvasMutationData | canvasMutationCommand,\n    error: unknown,\n  ) {\n    this.warn(`Has error on canvas update`, error, 'canvas mutation:', d);\n  }\n\n  private debugNodeNotFound(d: incrementalData, id: number) {\n    /**\n     * There maybe some valid scenes of node not being found.\n     * Because DOM events are macrotask and MutationObserver callback\n     * is microtask, so events fired on a removed DOM may emit\n     * snapshots in the reverse order.\n     */\n    this.debug(`Node with id '${id}' not found. `, d);\n  }\n\n  private warn(...args: Parameters<typeof console.warn>) {\n    if (!this.config.showWarning) {\n      return;\n    }\n    this.config.logger.warn(REPLAY_CONSOLE_PREFIX, ...args);\n  }\n\n  private debug(...args: Parameters<typeof console.log>) {\n    if (!this.config.showDebug) {\n      return;\n    }\n    this.config.logger.log(REPLAY_CONSOLE_PREFIX, ...args);\n  }\n}\n\nexport { type PlayerMachineState, type SpeedMachineState, type playerConfig };\n", "import record from './record';\nimport {\n  Replayer,\n  type playerConfig,\n  type PlayerMachineState,\n  type SpeedMachineState,\n} from './replay';\nimport canvasMutation from './replay/canvas';\nimport { _mirror } from './utils';\nimport * as utils from './utils';\n\nexport {\n  EventType,\n  IncrementalSource,\n  MouseInteractions,\n  ReplayerEvents,\n  type eventWithTime,\n} from '@rrweb/types';\n\n// exports style.css from replay\nimport './replay/styles/style.css';\n\nexport type { recordOptions, ReplayPlugin } from './types';\n\nconst { addCustomEvent } = record;\nconst { freezePage } = record;\nconst { takeFullSnapshot } = record;\n\nexport {\n  record,\n  addCustomEvent,\n  freezePage,\n  takeFullSnapshot,\n  Replayer,\n  type playerConfig,\n  type PlayerMachineState,\n  type SpeedMachineState,\n  canvasMutation,\n  _mirror as mirror,\n  utils,\n};\n", "import{record as C}from\"rrweb\";var s=null;function I(o,f){if(typeof document>\"u\"||typeof window>\"u\")return;s&&s();let v=o.maxEventsPerChunk??200,i=o.flushIntervalMs??1e4,k=o.maxPayloadBytes??1048576,e=[],d=0,r=null;function l(t){if(e.length===0)return;let n=JSON.stringify(e);if(new TextEncoder().encode(n).length>k){if(e.length>1){let a=Math.floor(e.length/2),y=e.slice(0,a),R=e.slice(a),_=t&&y.some(T=>T.type===2);e=y,l(_),e=R,l(!1);return}e=[];return}let x=e[0].timestamp,S=e[e.length-1].timestamp;try{f({chunk_index:d,events_count:e.length,is_full_snapshot:t,started_at:new Date(x).toISOString(),ended_at:new Date(S).toISOString(),payload:n}),d+=1,e=[]}catch(a){throw console.error(\"[ReplayRecorder] sendChunk failed\",a),a}}function g(t){let n=t||e.some(m=>m.type===2);e.length>=v?l(n):t&&e.length>0&&l(!0)}let c=o.maskAllText!==!1,u=o.unmaskTextSelector,b=C({emit(t,n){e.push(t),g(!!n)},checkoutEveryNms:i,maskAllInputs:o.maskAllInputs??!0,maskTextSelector:c?\"*\":\"[data-openpanel-replay-mask]\",maskTextFn:c&&u?(t,n)=>n?.closest(u)?t:t.replace(/\\S/g,\"*\"):void 0,blockSelector:o.blockSelector??\"[data-openpanel-replay-block]\",blockClass:o.blockClass,ignoreSelector:o.ignoreSelector});r=setInterval(()=>{if(e.length>0){let t=e.some(n=>n.type===2);l(t)}},i);function p(){if(document.visibilityState===\"hidden\"&&e.length>0){let t=e.some(n=>n.type===2);l(t)}}function h(){if(e.length>0){let t=e.some(n=>n.type===2);l(t)}}document.addEventListener(\"visibilitychange\",p),window.addEventListener(\"pagehide\",h),s=()=>{if(e.length>0){let t=e.some(n=>n.type===2);l(t)}r&&(clearInterval(r),r=null),document.removeEventListener(\"visibilitychange\",p),window.removeEventListener(\"pagehide\",h),b?.(),s=null}}function w(){s&&s()}export{I as startReplayRecorder,w as stopReplayRecorder};\n", "'use strict'\r\n\r\nmodule.exports = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\r\n", "/* MIT license */\n/* eslint-disable no-mixed-operators */\nconst cssKeywords = require('color-name');\n\n// NOTE: conversions should only return primitive values (i.e. arrays, or\n//       values that give correct `typeof` results).\n//       do not use box values types (i.e. Number(), String(), etc.)\n\nconst reverseKeywords = {};\nfor (const key of Object.keys(cssKeywords)) {\n\treverseKeywords[cssKeywords[key]] = key;\n}\n\nconst convert = {\n\trgb: {channels: 3, labels: 'rgb'},\n\thsl: {channels: 3, labels: 'hsl'},\n\thsv: {channels: 3, labels: 'hsv'},\n\thwb: {channels: 3, labels: 'hwb'},\n\tcmyk: {channels: 4, labels: 'cmyk'},\n\txyz: {channels: 3, labels: 'xyz'},\n\tlab: {channels: 3, labels: 'lab'},\n\tlch: {channels: 3, labels: 'lch'},\n\thex: {channels: 1, labels: ['hex']},\n\tkeyword: {channels: 1, labels: ['keyword']},\n\tansi16: {channels: 1, labels: ['ansi16']},\n\tansi256: {channels: 1, labels: ['ansi256']},\n\thcg: {channels: 3, labels: ['h', 'c', 'g']},\n\tapple: {channels: 3, labels: ['r16', 'g16', 'b16']},\n\tgray: {channels: 1, labels: ['gray']}\n};\n\nmodule.exports = convert;\n\n// Hide .channels and .labels properties\nfor (const model of Object.keys(convert)) {\n\tif (!('channels' in convert[model])) {\n\t\tthrow new Error('missing channels property: ' + model);\n\t}\n\n\tif (!('labels' in convert[model])) {\n\t\tthrow new Error('missing channel labels property: ' + model);\n\t}\n\n\tif (convert[model].labels.length !== convert[model].channels) {\n\t\tthrow new Error('channel and label counts mismatch: ' + model);\n\t}\n\n\tconst {channels, labels} = convert[model];\n\tdelete convert[model].channels;\n\tdelete convert[model].labels;\n\tObject.defineProperty(convert[model], 'channels', {value: channels});\n\tObject.defineProperty(convert[model], 'labels', {value: labels});\n}\n\nconvert.rgb.hsl = function (rgb) {\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\tconst min = Math.min(r, g, b);\n\tconst max = Math.max(r, g, b);\n\tconst delta = max - min;\n\tlet h;\n\tlet s;\n\n\tif (max === min) {\n\t\th = 0;\n\t} else if (r === max) {\n\t\th = (g - b) / delta;\n\t} else if (g === max) {\n\t\th = 2 + (b - r) / delta;\n\t} else if (b === max) {\n\t\th = 4 + (r - g) / delta;\n\t}\n\n\th = Math.min(h * 60, 360);\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tconst l = (min + max) / 2;\n\n\tif (max === min) {\n\t\ts = 0;\n\t} else if (l <= 0.5) {\n\t\ts = delta / (max + min);\n\t} else {\n\t\ts = delta / (2 - max - min);\n\t}\n\n\treturn [h, s * 100, l * 100];\n};\n\nconvert.rgb.hsv = function (rgb) {\n\tlet rdif;\n\tlet gdif;\n\tlet bdif;\n\tlet h;\n\tlet s;\n\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\tconst v = Math.max(r, g, b);\n\tconst diff = v - Math.min(r, g, b);\n\tconst diffc = function (c) {\n\t\treturn (v - c) / 6 / diff + 1 / 2;\n\t};\n\n\tif (diff === 0) {\n\t\th = 0;\n\t\ts = 0;\n\t} else {\n\t\ts = diff / v;\n\t\trdif = diffc(r);\n\t\tgdif = diffc(g);\n\t\tbdif = diffc(b);\n\n\t\tif (r === v) {\n\t\t\th = bdif - gdif;\n\t\t} else if (g === v) {\n\t\t\th = (1 / 3) + rdif - bdif;\n\t\t} else if (b === v) {\n\t\t\th = (2 / 3) + gdif - rdif;\n\t\t}\n\n\t\tif (h < 0) {\n\t\t\th += 1;\n\t\t} else if (h > 1) {\n\t\t\th -= 1;\n\t\t}\n\t}\n\n\treturn [\n\t\th * 360,\n\t\ts * 100,\n\t\tv * 100\n\t];\n};\n\nconvert.rgb.hwb = function (rgb) {\n\tconst r = rgb[0];\n\tconst g = rgb[1];\n\tlet b = rgb[2];\n\tconst h = convert.rgb.hsl(rgb)[0];\n\tconst w = 1 / 255 * Math.min(r, Math.min(g, b));\n\n\tb = 1 - 1 / 255 * Math.max(r, Math.max(g, b));\n\n\treturn [h, w * 100, b * 100];\n};\n\nconvert.rgb.cmyk = function (rgb) {\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\n\tconst k = Math.min(1 - r, 1 - g, 1 - b);\n\tconst c = (1 - r - k) / (1 - k) || 0;\n\tconst m = (1 - g - k) / (1 - k) || 0;\n\tconst y = (1 - b - k) / (1 - k) || 0;\n\n\treturn [c * 100, m * 100, y * 100, k * 100];\n};\n\nfunction comparativeDistance(x, y) {\n\t/*\n\t\tSee https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance\n\t*/\n\treturn (\n\t\t((x[0] - y[0]) ** 2) +\n\t\t((x[1] - y[1]) ** 2) +\n\t\t((x[2] - y[2]) ** 2)\n\t);\n}\n\nconvert.rgb.keyword = function (rgb) {\n\tconst reversed = reverseKeywords[rgb];\n\tif (reversed) {\n\t\treturn reversed;\n\t}\n\n\tlet currentClosestDistance = Infinity;\n\tlet currentClosestKeyword;\n\n\tfor (const keyword of Object.keys(cssKeywords)) {\n\t\tconst value = cssKeywords[keyword];\n\n\t\t// Compute comparative distance\n\t\tconst distance = comparativeDistance(rgb, value);\n\n\t\t// Check if its less, if so set as closest\n\t\tif (distance < currentClosestDistance) {\n\t\t\tcurrentClosestDistance = distance;\n\t\t\tcurrentClosestKeyword = keyword;\n\t\t}\n\t}\n\n\treturn currentClosestKeyword;\n};\n\nconvert.keyword.rgb = function (keyword) {\n\treturn cssKeywords[keyword];\n};\n\nconvert.rgb.xyz = function (rgb) {\n\tlet r = rgb[0] / 255;\n\tlet g = rgb[1] / 255;\n\tlet b = rgb[2] / 255;\n\n\t// Assume sRGB\n\tr = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92);\n\tg = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92);\n\tb = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92);\n\n\tconst x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\n\tconst y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\n\tconst z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\n\n\treturn [x * 100, y * 100, z * 100];\n};\n\nconvert.rgb.lab = function (rgb) {\n\tconst xyz = convert.rgb.xyz(rgb);\n\tlet x = xyz[0];\n\tlet y = xyz[1];\n\tlet z = xyz[2];\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);\n\n\tconst l = (116 * y) - 16;\n\tconst a = 500 * (x - y);\n\tconst b = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.hsl.rgb = function (hsl) {\n\tconst h = hsl[0] / 360;\n\tconst s = hsl[1] / 100;\n\tconst l = hsl[2] / 100;\n\tlet t2;\n\tlet t3;\n\tlet val;\n\n\tif (s === 0) {\n\t\tval = l * 255;\n\t\treturn [val, val, val];\n\t}\n\n\tif (l < 0.5) {\n\t\tt2 = l * (1 + s);\n\t} else {\n\t\tt2 = l + s - l * s;\n\t}\n\n\tconst t1 = 2 * l - t2;\n\n\tconst rgb = [0, 0, 0];\n\tfor (let i = 0; i < 3; i++) {\n\t\tt3 = h + 1 / 3 * -(i - 1);\n\t\tif (t3 < 0) {\n\t\t\tt3++;\n\t\t}\n\n\t\tif (t3 > 1) {\n\t\t\tt3--;\n\t\t}\n\n\t\tif (6 * t3 < 1) {\n\t\t\tval = t1 + (t2 - t1) * 6 * t3;\n\t\t} else if (2 * t3 < 1) {\n\t\t\tval = t2;\n\t\t} else if (3 * t3 < 2) {\n\t\t\tval = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n\t\t} else {\n\t\t\tval = t1;\n\t\t}\n\n\t\trgb[i] = val * 255;\n\t}\n\n\treturn rgb;\n};\n\nconvert.hsl.hsv = function (hsl) {\n\tconst h = hsl[0];\n\tlet s = hsl[1] / 100;\n\tlet l = hsl[2] / 100;\n\tlet smin = s;\n\tconst lmin = Math.max(l, 0.01);\n\n\tl *= 2;\n\ts *= (l <= 1) ? l : 2 - l;\n\tsmin *= lmin <= 1 ? lmin : 2 - lmin;\n\tconst v = (l + s) / 2;\n\tconst sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);\n\n\treturn [h, sv * 100, v * 100];\n};\n\nconvert.hsv.rgb = function (hsv) {\n\tconst h = hsv[0] / 60;\n\tconst s = hsv[1] / 100;\n\tlet v = hsv[2] / 100;\n\tconst hi = Math.floor(h) % 6;\n\n\tconst f = h - Math.floor(h);\n\tconst p = 255 * v * (1 - s);\n\tconst q = 255 * v * (1 - (s * f));\n\tconst t = 255 * v * (1 - (s * (1 - f)));\n\tv *= 255;\n\n\tswitch (hi) {\n\t\tcase 0:\n\t\t\treturn [v, t, p];\n\t\tcase 1:\n\t\t\treturn [q, v, p];\n\t\tcase 2:\n\t\t\treturn [p, v, t];\n\t\tcase 3:\n\t\t\treturn [p, q, v];\n\t\tcase 4:\n\t\t\treturn [t, p, v];\n\t\tcase 5:\n\t\t\treturn [v, p, q];\n\t}\n};\n\nconvert.hsv.hsl = function (hsv) {\n\tconst h = hsv[0];\n\tconst s = hsv[1] / 100;\n\tconst v = hsv[2] / 100;\n\tconst vmin = Math.max(v, 0.01);\n\tlet sl;\n\tlet l;\n\n\tl = (2 - s) * v;\n\tconst lmin = (2 - s) * vmin;\n\tsl = s * vmin;\n\tsl /= (lmin <= 1) ? lmin : 2 - lmin;\n\tsl = sl || 0;\n\tl /= 2;\n\n\treturn [h, sl * 100, l * 100];\n};\n\n// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\nconvert.hwb.rgb = function (hwb) {\n\tconst h = hwb[0] / 360;\n\tlet wh = hwb[1] / 100;\n\tlet bl = hwb[2] / 100;\n\tconst ratio = wh + bl;\n\tlet f;\n\n\t// Wh + bl cant be > 1\n\tif (ratio > 1) {\n\t\twh /= ratio;\n\t\tbl /= ratio;\n\t}\n\n\tconst i = Math.floor(6 * h);\n\tconst v = 1 - bl;\n\tf = 6 * h - i;\n\n\tif ((i & 0x01) !== 0) {\n\t\tf = 1 - f;\n\t}\n\n\tconst n = wh + f * (v - wh); // Linear interpolation\n\n\tlet r;\n\tlet g;\n\tlet b;\n\t/* eslint-disable max-statements-per-line,no-multi-spaces */\n\tswitch (i) {\n\t\tdefault:\n\t\tcase 6:\n\t\tcase 0: r = v;  g = n;  b = wh; break;\n\t\tcase 1: r = n;  g = v;  b = wh; break;\n\t\tcase 2: r = wh; g = v;  b = n; break;\n\t\tcase 3: r = wh; g = n;  b = v; break;\n\t\tcase 4: r = n;  g = wh; b = v; break;\n\t\tcase 5: r = v;  g = wh; b = n; break;\n\t}\n\t/* eslint-enable max-statements-per-line,no-multi-spaces */\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.cmyk.rgb = function (cmyk) {\n\tconst c = cmyk[0] / 100;\n\tconst m = cmyk[1] / 100;\n\tconst y = cmyk[2] / 100;\n\tconst k = cmyk[3] / 100;\n\n\tconst r = 1 - Math.min(1, c * (1 - k) + k);\n\tconst g = 1 - Math.min(1, m * (1 - k) + k);\n\tconst b = 1 - Math.min(1, y * (1 - k) + k);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.rgb = function (xyz) {\n\tconst x = xyz[0] / 100;\n\tconst y = xyz[1] / 100;\n\tconst z = xyz[2] / 100;\n\tlet r;\n\tlet g;\n\tlet b;\n\n\tr = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n\tg = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n\tb = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n\t// Assume sRGB\n\tr = r > 0.0031308\n\t\t? ((1.055 * (r ** (1.0 / 2.4))) - 0.055)\n\t\t: r * 12.92;\n\n\tg = g > 0.0031308\n\t\t? ((1.055 * (g ** (1.0 / 2.4))) - 0.055)\n\t\t: g * 12.92;\n\n\tb = b > 0.0031308\n\t\t? ((1.055 * (b ** (1.0 / 2.4))) - 0.055)\n\t\t: b * 12.92;\n\n\tr = Math.min(Math.max(0, r), 1);\n\tg = Math.min(Math.max(0, g), 1);\n\tb = Math.min(Math.max(0, b), 1);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.lab = function (xyz) {\n\tlet x = xyz[0];\n\tlet y = xyz[1];\n\tlet z = xyz[2];\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);\n\n\tconst l = (116 * y) - 16;\n\tconst a = 500 * (x - y);\n\tconst b = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.lab.xyz = function (lab) {\n\tconst l = lab[0];\n\tconst a = lab[1];\n\tconst b = lab[2];\n\tlet x;\n\tlet y;\n\tlet z;\n\n\ty = (l + 16) / 116;\n\tx = a / 500 + y;\n\tz = y - b / 200;\n\n\tconst y2 = y ** 3;\n\tconst x2 = x ** 3;\n\tconst z2 = z ** 3;\n\ty = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;\n\tx = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;\n\tz = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;\n\n\tx *= 95.047;\n\ty *= 100;\n\tz *= 108.883;\n\n\treturn [x, y, z];\n};\n\nconvert.lab.lch = function (lab) {\n\tconst l = lab[0];\n\tconst a = lab[1];\n\tconst b = lab[2];\n\tlet h;\n\n\tconst hr = Math.atan2(b, a);\n\th = hr * 360 / 2 / Math.PI;\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tconst c = Math.sqrt(a * a + b * b);\n\n\treturn [l, c, h];\n};\n\nconvert.lch.lab = function (lch) {\n\tconst l = lch[0];\n\tconst c = lch[1];\n\tconst h = lch[2];\n\n\tconst hr = h / 360 * 2 * Math.PI;\n\tconst a = c * Math.cos(hr);\n\tconst b = c * Math.sin(hr);\n\n\treturn [l, a, b];\n};\n\nconvert.rgb.ansi16 = function (args, saturation = null) {\n\tconst [r, g, b] = args;\n\tlet value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization\n\n\tvalue = Math.round(value / 50);\n\n\tif (value === 0) {\n\t\treturn 30;\n\t}\n\n\tlet ansi = 30\n\t\t+ ((Math.round(b / 255) << 2)\n\t\t| (Math.round(g / 255) << 1)\n\t\t| Math.round(r / 255));\n\n\tif (value === 2) {\n\t\tansi += 60;\n\t}\n\n\treturn ansi;\n};\n\nconvert.hsv.ansi16 = function (args) {\n\t// Optimization here; we already know the value and don't need to get\n\t// it converted for us.\n\treturn convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);\n};\n\nconvert.rgb.ansi256 = function (args) {\n\tconst r = args[0];\n\tconst g = args[1];\n\tconst b = args[2];\n\n\t// We use the extended greyscale palette here, with the exception of\n\t// black and white. normal palette only has 4 greyscale shades.\n\tif (r === g && g === b) {\n\t\tif (r < 8) {\n\t\t\treturn 16;\n\t\t}\n\n\t\tif (r > 248) {\n\t\t\treturn 231;\n\t\t}\n\n\t\treturn Math.round(((r - 8) / 247) * 24) + 232;\n\t}\n\n\tconst ansi = 16\n\t\t+ (36 * Math.round(r / 255 * 5))\n\t\t+ (6 * Math.round(g / 255 * 5))\n\t\t+ Math.round(b / 255 * 5);\n\n\treturn ansi;\n};\n\nconvert.ansi16.rgb = function (args) {\n\tlet color = args % 10;\n\n\t// Handle greyscale\n\tif (color === 0 || color === 7) {\n\t\tif (args > 50) {\n\t\t\tcolor += 3.5;\n\t\t}\n\n\t\tcolor = color / 10.5 * 255;\n\n\t\treturn [color, color, color];\n\t}\n\n\tconst mult = (~~(args > 50) + 1) * 0.5;\n\tconst r = ((color & 1) * mult) * 255;\n\tconst g = (((color >> 1) & 1) * mult) * 255;\n\tconst b = (((color >> 2) & 1) * mult) * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.ansi256.rgb = function (args) {\n\t// Handle greyscale\n\tif (args >= 232) {\n\t\tconst c = (args - 232) * 10 + 8;\n\t\treturn [c, c, c];\n\t}\n\n\targs -= 16;\n\n\tlet rem;\n\tconst r = Math.floor(args / 36) / 5 * 255;\n\tconst g = Math.floor((rem = args % 36) / 6) / 5 * 255;\n\tconst b = (rem % 6) / 5 * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hex = function (args) {\n\tconst integer = ((Math.round(args[0]) & 0xFF) << 16)\n\t\t+ ((Math.round(args[1]) & 0xFF) << 8)\n\t\t+ (Math.round(args[2]) & 0xFF);\n\n\tconst string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.hex.rgb = function (args) {\n\tconst match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);\n\tif (!match) {\n\t\treturn [0, 0, 0];\n\t}\n\n\tlet colorString = match[0];\n\n\tif (match[0].length === 3) {\n\t\tcolorString = colorString.split('').map(char => {\n\t\t\treturn char + char;\n\t\t}).join('');\n\t}\n\n\tconst integer = parseInt(colorString, 16);\n\tconst r = (integer >> 16) & 0xFF;\n\tconst g = (integer >> 8) & 0xFF;\n\tconst b = integer & 0xFF;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hcg = function (rgb) {\n\tconst r = rgb[0] / 255;\n\tconst g = rgb[1] / 255;\n\tconst b = rgb[2] / 255;\n\tconst max = Math.max(Math.max(r, g), b);\n\tconst min = Math.min(Math.min(r, g), b);\n\tconst chroma = (max - min);\n\tlet grayscale;\n\tlet hue;\n\n\tif (chroma < 1) {\n\t\tgrayscale = min / (1 - chroma);\n\t} else {\n\t\tgrayscale = 0;\n\t}\n\n\tif (chroma <= 0) {\n\t\thue = 0;\n\t} else\n\tif (max === r) {\n\t\thue = ((g - b) / chroma) % 6;\n\t} else\n\tif (max === g) {\n\t\thue = 2 + (b - r) / chroma;\n\t} else {\n\t\thue = 4 + (r - g) / chroma;\n\t}\n\n\thue /= 6;\n\thue %= 1;\n\n\treturn [hue * 360, chroma * 100, grayscale * 100];\n};\n\nconvert.hsl.hcg = function (hsl) {\n\tconst s = hsl[1] / 100;\n\tconst l = hsl[2] / 100;\n\n\tconst c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l));\n\n\tlet f = 0;\n\tif (c < 1.0) {\n\t\tf = (l - 0.5 * c) / (1.0 - c);\n\t}\n\n\treturn [hsl[0], c * 100, f * 100];\n};\n\nconvert.hsv.hcg = function (hsv) {\n\tconst s = hsv[1] / 100;\n\tconst v = hsv[2] / 100;\n\n\tconst c = s * v;\n\tlet f = 0;\n\n\tif (c < 1.0) {\n\t\tf = (v - c) / (1 - c);\n\t}\n\n\treturn [hsv[0], c * 100, f * 100];\n};\n\nconvert.hcg.rgb = function (hcg) {\n\tconst h = hcg[0] / 360;\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\n\tif (c === 0.0) {\n\t\treturn [g * 255, g * 255, g * 255];\n\t}\n\n\tconst pure = [0, 0, 0];\n\tconst hi = (h % 1) * 6;\n\tconst v = hi % 1;\n\tconst w = 1 - v;\n\tlet mg = 0;\n\n\t/* eslint-disable max-statements-per-line */\n\tswitch (Math.floor(hi)) {\n\t\tcase 0:\n\t\t\tpure[0] = 1; pure[1] = v; pure[2] = 0; break;\n\t\tcase 1:\n\t\t\tpure[0] = w; pure[1] = 1; pure[2] = 0; break;\n\t\tcase 2:\n\t\t\tpure[0] = 0; pure[1] = 1; pure[2] = v; break;\n\t\tcase 3:\n\t\t\tpure[0] = 0; pure[1] = w; pure[2] = 1; break;\n\t\tcase 4:\n\t\t\tpure[0] = v; pure[1] = 0; pure[2] = 1; break;\n\t\tdefault:\n\t\t\tpure[0] = 1; pure[1] = 0; pure[2] = w;\n\t}\n\t/* eslint-enable max-statements-per-line */\n\n\tmg = (1.0 - c) * g;\n\n\treturn [\n\t\t(c * pure[0] + mg) * 255,\n\t\t(c * pure[1] + mg) * 255,\n\t\t(c * pure[2] + mg) * 255\n\t];\n};\n\nconvert.hcg.hsv = function (hcg) {\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\n\tconst v = c + g * (1.0 - c);\n\tlet f = 0;\n\n\tif (v > 0.0) {\n\t\tf = c / v;\n\t}\n\n\treturn [hcg[0], f * 100, v * 100];\n};\n\nconvert.hcg.hsl = function (hcg) {\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\n\tconst l = g * (1.0 - c) + 0.5 * c;\n\tlet s = 0;\n\n\tif (l > 0.0 && l < 0.5) {\n\t\ts = c / (2 * l);\n\t} else\n\tif (l >= 0.5 && l < 1.0) {\n\t\ts = c / (2 * (1 - l));\n\t}\n\n\treturn [hcg[0], s * 100, l * 100];\n};\n\nconvert.hcg.hwb = function (hcg) {\n\tconst c = hcg[1] / 100;\n\tconst g = hcg[2] / 100;\n\tconst v = c + g * (1.0 - c);\n\treturn [hcg[0], (v - c) * 100, (1 - v) * 100];\n};\n\nconvert.hwb.hcg = function (hwb) {\n\tconst w = hwb[1] / 100;\n\tconst b = hwb[2] / 100;\n\tconst v = 1 - b;\n\tconst c = v - w;\n\tlet g = 0;\n\n\tif (c < 1) {\n\t\tg = (v - c) / (1 - c);\n\t}\n\n\treturn [hwb[0], c * 100, g * 100];\n};\n\nconvert.apple.rgb = function (apple) {\n\treturn [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];\n};\n\nconvert.rgb.apple = function (rgb) {\n\treturn [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];\n};\n\nconvert.gray.rgb = function (args) {\n\treturn [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];\n};\n\nconvert.gray.hsl = function (args) {\n\treturn [0, 0, args[0]];\n};\n\nconvert.gray.hsv = convert.gray.hsl;\n\nconvert.gray.hwb = function (gray) {\n\treturn [0, 100, gray[0]];\n};\n\nconvert.gray.cmyk = function (gray) {\n\treturn [0, 0, 0, gray[0]];\n};\n\nconvert.gray.lab = function (gray) {\n\treturn [gray[0], 0, 0];\n};\n\nconvert.gray.hex = function (gray) {\n\tconst val = Math.round(gray[0] / 100 * 255) & 0xFF;\n\tconst integer = (val << 16) + (val << 8) + val;\n\n\tconst string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.rgb.gray = function (rgb) {\n\tconst val = (rgb[0] + rgb[1] + rgb[2]) / 3;\n\treturn [val / 255 * 100];\n};\n", "const conversions = require('./conversions');\n\n/*\n\tThis function routes a model to all other models.\n\n\tall functions that are routed have a property `.conversion` attached\n\tto the returned synthetic function. This property is an array\n\tof strings, each with the steps in between the 'from' and 'to'\n\tcolor models (inclusive).\n\n\tconversions that are not possible simply are not included.\n*/\n\nfunction buildGraph() {\n\tconst graph = {};\n\t// https://jsperf.com/object-keys-vs-for-in-with-closure/3\n\tconst models = Object.keys(conversions);\n\n\tfor (let len = models.length, i = 0; i < len; i++) {\n\t\tgraph[models[i]] = {\n\t\t\t// http://jsperf.com/1-vs-infinity\n\t\t\t// micro-opt, but this is simple.\n\t\t\tdistance: -1,\n\t\t\tparent: null\n\t\t};\n\t}\n\n\treturn graph;\n}\n\n// https://en.wikipedia.org/wiki/Breadth-first_search\nfunction deriveBFS(fromModel) {\n\tconst graph = buildGraph();\n\tconst queue = [fromModel]; // Unshift -> queue -> pop\n\n\tgraph[fromModel].distance = 0;\n\n\twhile (queue.length) {\n\t\tconst current = queue.pop();\n\t\tconst adjacents = Object.keys(conversions[current]);\n\n\t\tfor (let len = adjacents.length, i = 0; i < len; i++) {\n\t\t\tconst adjacent = adjacents[i];\n\t\t\tconst node = graph[adjacent];\n\n\t\t\tif (node.distance === -1) {\n\t\t\t\tnode.distance = graph[current].distance + 1;\n\t\t\t\tnode.parent = current;\n\t\t\t\tqueue.unshift(adjacent);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn graph;\n}\n\nfunction link(from, to) {\n\treturn function (args) {\n\t\treturn to(from(args));\n\t};\n}\n\nfunction wrapConversion(toModel, graph) {\n\tconst path = [graph[toModel].parent, toModel];\n\tlet fn = conversions[graph[toModel].parent][toModel];\n\n\tlet cur = graph[toModel].parent;\n\twhile (graph[cur].parent) {\n\t\tpath.unshift(graph[cur].parent);\n\t\tfn = link(conversions[graph[cur].parent][cur], fn);\n\t\tcur = graph[cur].parent;\n\t}\n\n\tfn.conversion = path;\n\treturn fn;\n}\n\nmodule.exports = function (fromModel) {\n\tconst graph = deriveBFS(fromModel);\n\tconst conversion = {};\n\n\tconst models = Object.keys(graph);\n\tfor (let len = models.length, i = 0; i < len; i++) {\n\t\tconst toModel = models[i];\n\t\tconst node = graph[toModel];\n\n\t\tif (node.parent === null) {\n\t\t\t// No possible conversion, or this node is the source model.\n\t\t\tcontinue;\n\t\t}\n\n\t\tconversion[toModel] = wrapConversion(toModel, graph);\n\t}\n\n\treturn conversion;\n};\n\n", "const conversions = require('./conversions');\nconst route = require('./route');\n\nconst convert = {};\n\nconst models = Object.keys(conversions);\n\nfunction wrapRaw(fn) {\n\tconst wrappedFn = function (...args) {\n\t\tconst arg0 = args[0];\n\t\tif (arg0 === undefined || arg0 === null) {\n\t\t\treturn arg0;\n\t\t}\n\n\t\tif (arg0.length > 1) {\n\t\t\targs = arg0;\n\t\t}\n\n\t\treturn fn(args);\n\t};\n\n\t// Preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nfunction wrapRounded(fn) {\n\tconst wrappedFn = function (...args) {\n\t\tconst arg0 = args[0];\n\n\t\tif (arg0 === undefined || arg0 === null) {\n\t\t\treturn arg0;\n\t\t}\n\n\t\tif (arg0.length > 1) {\n\t\t\targs = arg0;\n\t\t}\n\n\t\tconst result = fn(args);\n\n\t\t// We're assuming the result is an array here.\n\t\t// see notice in conversions.js; don't use box types\n\t\t// in conversion functions.\n\t\tif (typeof result === 'object') {\n\t\t\tfor (let len = result.length, i = 0; i < len; i++) {\n\t\t\t\tresult[i] = Math.round(result[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t// Preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nmodels.forEach(fromModel => {\n\tconvert[fromModel] = {};\n\n\tObject.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});\n\tObject.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});\n\n\tconst routes = route(fromModel);\n\tconst routeModels = Object.keys(routes);\n\n\trouteModels.forEach(toModel => {\n\t\tconst fn = routes[toModel];\n\n\t\tconvert[fromModel][toModel] = wrapRounded(fn);\n\t\tconvert[fromModel][toModel].raw = wrapRaw(fn);\n\t});\n});\n\nmodule.exports = convert;\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n  set(element, key, instance) {\n    if (!elementMap.has(element)) {\n      elementMap.set(element, new Map())\n    }\n\n    const instanceMap = elementMap.get(element)\n\n    // make it clear we only want one instance per element\n    // can be removed later when multiple key/instances are fine to be used\n    if (!instanceMap.has(key) && instanceMap.size !== 0) {\n      // eslint-disable-next-line no-console\n      console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n      return\n    }\n\n    instanceMap.set(key, instance)\n  },\n\n  get(element, key) {\n    if (elementMap.has(element)) {\n      return elementMap.get(element).get(key) || null\n    }\n\n    return null\n  },\n\n  remove(element, key) {\n    if (!elementMap.has(element)) {\n      return\n    }\n\n    const instanceMap = elementMap.get(element)\n\n    instanceMap.delete(key)\n\n    // free up element references if there are no instances left for an element\n    if (instanceMap.size === 0) {\n      elementMap.delete(element)\n    }\n  }\n}\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1_000_000\nconst MILLISECONDS_MULTIPLIER = 1000\nconst TRANSITION_END = 'transitionend'\n\n/**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\nconst parseSelector = selector => {\n  if (selector && window.CSS && window.CSS.escape) {\n    // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n    selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`)\n  }\n\n  return selector\n}\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n  if (object === null || object === undefined) {\n    return `${object}`\n  }\n\n  return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n  do {\n    prefix += Math.floor(Math.random() * MAX_UID)\n  } while (document.getElementById(prefix))\n\n  return prefix\n}\n\nconst getTransitionDurationFromElement = element => {\n  if (!element) {\n    return 0\n  }\n\n  // Get transition-duration of the element\n  let { transitionDuration, transitionDelay } = window.getComputedStyle(element)\n\n  const floatTransitionDuration = Number.parseFloat(transitionDuration)\n  const floatTransitionDelay = Number.parseFloat(transitionDelay)\n\n  // Return 0 if element or transition duration is not found\n  if (!floatTransitionDuration && !floatTransitionDelay) {\n    return 0\n  }\n\n  // If multiple durations are defined, take the first\n  transitionDuration = transitionDuration.split(',')[0]\n  transitionDelay = transitionDelay.split(',')[0]\n\n  return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n}\n\nconst triggerTransitionEnd = element => {\n  element.dispatchEvent(new Event(TRANSITION_END))\n}\n\nconst isElement = object => {\n  if (!object || typeof object !== 'object') {\n    return false\n  }\n\n  if (typeof object.jquery !== 'undefined') {\n    object = object[0]\n  }\n\n  return typeof object.nodeType !== 'undefined'\n}\n\nconst getElement = object => {\n  // it's a jQuery object or a node element\n  if (isElement(object)) {\n    return object.jquery ? object[0] : object\n  }\n\n  if (typeof object === 'string' && object.length > 0) {\n    return document.querySelector(parseSelector(object))\n  }\n\n  return null\n}\n\nconst isVisible = element => {\n  if (!isElement(element) || element.getClientRects().length === 0) {\n    return false\n  }\n\n  const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'\n  // Handle `details` element as its content may falsie appear visible when it is closed\n  const closedDetails = element.closest('details:not([open])')\n\n  if (!closedDetails) {\n    return elementIsVisible\n  }\n\n  if (closedDetails !== element) {\n    const summary = element.closest('summary')\n    if (summary && summary.parentNode !== closedDetails) {\n      return false\n    }\n\n    if (summary === null) {\n      return false\n    }\n  }\n\n  return elementIsVisible\n}\n\nconst isDisabled = element => {\n  if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n    return true\n  }\n\n  if (element.classList.contains('disabled')) {\n    return true\n  }\n\n  if (typeof element.disabled !== 'undefined') {\n    return element.disabled\n  }\n\n  return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'\n}\n\nconst findShadowRoot = element => {\n  if (!document.documentElement.attachShadow) {\n    return null\n  }\n\n  // Can find the shadow root otherwise it'll return the document\n  if (typeof element.getRootNode === 'function') {\n    const root = element.getRootNode()\n    return root instanceof ShadowRoot ? root : null\n  }\n\n  if (element instanceof ShadowRoot) {\n    return element\n  }\n\n  // when we don't find a shadow root\n  if (!element.parentNode) {\n    return null\n  }\n\n  return findShadowRoot(element.parentNode)\n}\n\nconst noop = () => {}\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n  element.offsetHeight // eslint-disable-line no-unused-expressions\n}\n\nconst getjQuery = () => {\n  if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n    return window.jQuery\n  }\n\n  return null\n}\n\nconst DOMContentLoadedCallbacks = []\n\nconst onDOMContentLoaded = callback => {\n  if (document.readyState === 'loading') {\n    // add listener on the first call when the document is in loading state\n    if (!DOMContentLoadedCallbacks.length) {\n      document.addEventListener('DOMContentLoaded', () => {\n        for (const callback of DOMContentLoadedCallbacks) {\n          callback()\n        }\n      })\n    }\n\n    DOMContentLoadedCallbacks.push(callback)\n  } else {\n    callback()\n  }\n}\n\nconst isRTL = () => document.documentElement.dir === 'rtl'\n\nconst defineJQueryPlugin = plugin => {\n  onDOMContentLoaded(() => {\n    const $ = getjQuery()\n    /* istanbul ignore if */\n    if ($) {\n      const name = plugin.NAME\n      const JQUERY_NO_CONFLICT = $.fn[name]\n      $.fn[name] = plugin.jQueryInterface\n      $.fn[name].Constructor = plugin\n      $.fn[name].noConflict = () => {\n        $.fn[name] = JQUERY_NO_CONFLICT\n        return plugin.jQueryInterface\n      }\n    }\n  })\n}\n\nconst execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n  return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue\n}\n\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n  if (!waitForTransition) {\n    execute(callback)\n    return\n  }\n\n  const durationPadding = 5\n  const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding\n\n  let called = false\n\n  const handler = ({ target }) => {\n    if (target !== transitionElement) {\n      return\n    }\n\n    called = true\n    transitionElement.removeEventListener(TRANSITION_END, handler)\n    execute(callback)\n  }\n\n  transitionElement.addEventListener(TRANSITION_END, handler)\n  setTimeout(() => {\n    if (!called) {\n      triggerTransitionEnd(transitionElement)\n    }\n  }, emulatedDuration)\n}\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list    The list of elements\n * @param activeElement   The active element\n * @param shouldGetNext   Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n  const listLength = list.length\n  let index = list.indexOf(activeElement)\n\n  // if the element does not exist in the list return an element\n  // depending on the direction and if cycle is allowed\n  if (index === -1) {\n    return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]\n  }\n\n  index += shouldGetNext ? 1 : -1\n\n  if (isCycleAllowed) {\n    index = (index + listLength) % listLength\n  }\n\n  return list[Math.max(0, Math.min(index, listLength - 1))]\n}\n\nexport {\n  defineJQueryPlugin,\n  execute,\n  executeAfterTransition,\n  findShadowRoot,\n  getElement,\n  getjQuery,\n  getNextActiveElement,\n  getTransitionDurationFromElement,\n  getUID,\n  isDisabled,\n  isElement,\n  isRTL,\n  isVisible,\n  noop,\n  onDOMContentLoaded,\n  parseSelector,\n  reflow,\n  triggerTransitionEnd,\n  toType\n}\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { getjQuery } from '../util/index.js'\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/\nconst stripNameRegex = /\\..*/\nconst stripUidRegex = /::\\d+$/\nconst eventRegistry = {} // Events storage\nlet uidEvent = 1\nconst customEvents = {\n  mouseenter: 'mouseover',\n  mouseleave: 'mouseout'\n}\n\nconst nativeEvents = new Set([\n  'click',\n  'dblclick',\n  'mouseup',\n  'mousedown',\n  'contextmenu',\n  'mousewheel',\n  'DOMMouseScroll',\n  'mouseover',\n  'mouseout',\n  'mousemove',\n  'selectstart',\n  'selectend',\n  'keydown',\n  'keypress',\n  'keyup',\n  'orientationchange',\n  'touchstart',\n  'touchmove',\n  'touchend',\n  'touchcancel',\n  'pointerdown',\n  'pointermove',\n  'pointerup',\n  'pointerleave',\n  'pointercancel',\n  'gesturestart',\n  'gesturechange',\n  'gestureend',\n  'focus',\n  'blur',\n  'change',\n  'reset',\n  'select',\n  'submit',\n  'focusin',\n  'focusout',\n  'load',\n  'unload',\n  'beforeunload',\n  'resize',\n  'move',\n  'DOMContentLoaded',\n  'readystatechange',\n  'error',\n  'abort',\n  'scroll'\n])\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n  return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++\n}\n\nfunction getElementEvents(element) {\n  const uid = makeEventUid(element)\n\n  element.uidEvent = uid\n  eventRegistry[uid] = eventRegistry[uid] || {}\n\n  return eventRegistry[uid]\n}\n\nfunction bootstrapHandler(element, fn) {\n  return function handler(event) {\n    hydrateObj(event, { delegateTarget: element })\n\n    if (handler.oneOff) {\n      EventHandler.off(element, event.type, fn)\n    }\n\n    return fn.apply(element, [event])\n  }\n}\n\nfunction bootstrapDelegationHandler(element, selector, fn) {\n  return function handler(event) {\n    const domElements = element.querySelectorAll(selector)\n\n    for (let { target } = event; target && target !== this; target = target.parentNode) {\n      for (const domElement of domElements) {\n        if (domElement !== target) {\n          continue\n        }\n\n        hydrateObj(event, { delegateTarget: target })\n\n        if (handler.oneOff) {\n          EventHandler.off(element, event.type, selector, fn)\n        }\n\n        return fn.apply(target, [event])\n      }\n    }\n  }\n}\n\nfunction findHandler(events, callable, delegationSelector = null) {\n  return Object.values(events)\n    .find(event => event.callable === callable && event.delegationSelector === delegationSelector)\n}\n\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n  const isDelegated = typeof handler === 'string'\n  // TODO: tooltip passes `false` instead of selector, so we need to check\n  const callable = isDelegated ? delegationFunction : (handler || delegationFunction)\n  let typeEvent = getTypeEvent(originalTypeEvent)\n\n  if (!nativeEvents.has(typeEvent)) {\n    typeEvent = originalTypeEvent\n  }\n\n  return [isDelegated, callable, typeEvent]\n}\n\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n  if (typeof originalTypeEvent !== 'string' || !element) {\n    return\n  }\n\n  let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n\n  // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n  // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n  if (originalTypeEvent in customEvents) {\n    const wrapFunction = fn => {\n      return function (event) {\n        if (!event.relatedTarget || (event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget))) {\n          return fn.call(this, event)\n        }\n      }\n    }\n\n    callable = wrapFunction(callable)\n  }\n\n  const events = getElementEvents(element)\n  const handlers = events[typeEvent] || (events[typeEvent] = {})\n  const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null)\n\n  if (previousFunction) {\n    previousFunction.oneOff = previousFunction.oneOff && oneOff\n\n    return\n  }\n\n  const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''))\n  const fn = isDelegated ?\n    bootstrapDelegationHandler(element, handler, callable) :\n    bootstrapHandler(element, callable)\n\n  fn.delegationSelector = isDelegated ? handler : null\n  fn.callable = callable\n  fn.oneOff = oneOff\n  fn.uidEvent = uid\n  handlers[uid] = fn\n\n  element.addEventListener(typeEvent, fn, isDelegated)\n}\n\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n  const fn = findHandler(events[typeEvent], handler, delegationSelector)\n\n  if (!fn) {\n    return\n  }\n\n  element.removeEventListener(typeEvent, fn, Boolean(delegationSelector))\n  delete events[typeEvent][fn.uidEvent]\n}\n\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n  const storeElementEvent = events[typeEvent] || {}\n\n  for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n    if (handlerKey.includes(namespace)) {\n      removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n    }\n  }\n}\n\nfunction getTypeEvent(event) {\n  // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n  event = event.replace(stripNameRegex, '')\n  return customEvents[event] || event\n}\n\nconst EventHandler = {\n  on(element, event, handler, delegationFunction) {\n    addHandler(element, event, handler, delegationFunction, false)\n  },\n\n  one(element, event, handler, delegationFunction) {\n    addHandler(element, event, handler, delegationFunction, true)\n  },\n\n  off(element, originalTypeEvent, handler, delegationFunction) {\n    if (typeof originalTypeEvent !== 'string' || !element) {\n      return\n    }\n\n    const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n    const inNamespace = typeEvent !== originalTypeEvent\n    const events = getElementEvents(element)\n    const storeElementEvent = events[typeEvent] || {}\n    const isNamespace = originalTypeEvent.startsWith('.')\n\n    if (typeof callable !== 'undefined') {\n      // Simplest case: handler is passed, remove that listener ONLY.\n      if (!Object.keys(storeElementEvent).length) {\n        return\n      }\n\n      removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null)\n      return\n    }\n\n    if (isNamespace) {\n      for (const elementEvent of Object.keys(events)) {\n        removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1))\n      }\n    }\n\n    for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n      const handlerKey = keyHandlers.replace(stripUidRegex, '')\n\n      if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n        removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n      }\n    }\n  },\n\n  trigger(element, event, args) {\n    if (typeof event !== 'string' || !element) {\n      return null\n    }\n\n    const $ = getjQuery()\n    const typeEvent = getTypeEvent(event)\n    const inNamespace = event !== typeEvent\n\n    let jQueryEvent = null\n    let bubbles = true\n    let nativeDispatch = true\n    let defaultPrevented = false\n\n    if (inNamespace && $) {\n      jQueryEvent = $.Event(event, args)\n\n      $(element).trigger(jQueryEvent)\n      bubbles = !jQueryEvent.isPropagationStopped()\n      nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()\n      defaultPrevented = jQueryEvent.isDefaultPrevented()\n    }\n\n    const evt = hydrateObj(new Event(event, { bubbles, cancelable: true }), args)\n\n    if (defaultPrevented) {\n      evt.preventDefault()\n    }\n\n    if (nativeDispatch) {\n      element.dispatchEvent(evt)\n    }\n\n    if (evt.defaultPrevented && jQueryEvent) {\n      jQueryEvent.preventDefault()\n    }\n\n    return evt\n  }\n}\n\nfunction hydrateObj(obj, meta = {}) {\n  for (const [key, value] of Object.entries(meta)) {\n    try {\n      obj[key] = value\n    } catch {\n      Object.defineProperty(obj, key, {\n        configurable: true,\n        get() {\n          return value\n        }\n      })\n    }\n  }\n\n  return obj\n}\n\nexport default EventHandler\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n  if (value === 'true') {\n    return true\n  }\n\n  if (value === 'false') {\n    return false\n  }\n\n  if (value === Number(value).toString()) {\n    return Number(value)\n  }\n\n  if (value === '' || value === 'null') {\n    return null\n  }\n\n  if (typeof value !== 'string') {\n    return value\n  }\n\n  try {\n    return JSON.parse(decodeURIComponent(value))\n  } catch {\n    return value\n  }\n}\n\nfunction normalizeDataKey(key) {\n  return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n  setDataAttribute(element, key, value) {\n    element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n  },\n\n  removeDataAttribute(element, key) {\n    element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n  },\n\n  getDataAttributes(element) {\n    if (!element) {\n      return {}\n    }\n\n    const attributes = {}\n    const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))\n\n    for (const key of bsKeys) {\n      let pureKey = key.replace(/^bs/, '')\n      pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1)\n      attributes[pureKey] = normalizeData(element.dataset[key])\n    }\n\n    return attributes\n  },\n\n  getDataAttribute(element, key) {\n    return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n  }\n}\n\nexport default Manipulator\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Manipulator from '../dom/manipulator.js'\nimport { isElement, toType } from './index.js'\n\n/**\n * Class definition\n */\n\nclass Config {\n  // Getters\n  static get Default() {\n    return {}\n  }\n\n  static get DefaultType() {\n    return {}\n  }\n\n  static get NAME() {\n    throw new Error('You have to implement the static method \"NAME\", for each component!')\n  }\n\n  _getConfig(config) {\n    config = this._mergeConfigObj(config)\n    config = this._configAfterMerge(config)\n    this._typeCheckConfig(config)\n    return config\n  }\n\n  _configAfterMerge(config) {\n    return config\n  }\n\n  _mergeConfigObj(config, element) {\n    const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {} // try to parse\n\n    return {\n      ...this.constructor.Default,\n      ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n      ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n      ...(typeof config === 'object' ? config : {})\n    }\n  }\n\n  _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n    for (const [property, expectedTypes] of Object.entries(configTypes)) {\n      const value = config[property]\n      const valueType = isElement(value) ? 'element' : toType(value)\n\n      if (!new RegExp(expectedTypes).test(valueType)) {\n        throw new TypeError(\n          `${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`\n        )\n      }\n    }\n  }\n}\n\nexport default Config\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.8'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n  constructor(element, config) {\n    super()\n\n    element = getElement(element)\n    if (!element) {\n      return\n    }\n\n    this._element = element\n    this._config = this._getConfig(config)\n\n    Data.set(this._element, this.constructor.DATA_KEY, this)\n  }\n\n  // Public\n  dispose() {\n    Data.remove(this._element, this.constructor.DATA_KEY)\n    EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n    for (const propertyName of Object.getOwnPropertyNames(this)) {\n      this[propertyName] = null\n    }\n  }\n\n  // Private\n  _queueCallback(callback, element, isAnimated = true) {\n    executeAfterTransition(callback, element, isAnimated)\n  }\n\n  _getConfig(config) {\n    config = this._mergeConfigObj(config, this._element)\n    config = this._configAfterMerge(config)\n    this._typeCheckConfig(config)\n    return config\n  }\n\n  // Static\n  static getInstance(element) {\n    return Data.get(getElement(element), this.DATA_KEY)\n  }\n\n  static getOrCreateInstance(element, config = {}) {\n    return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n  }\n\n  static get VERSION() {\n    return VERSION\n  }\n\n  static get DATA_KEY() {\n    return `bs.${this.NAME}`\n  }\n\n  static get EVENT_KEY() {\n    return `.${this.DATA_KEY}`\n  }\n\n  static eventName(name) {\n    return `${name}${this.EVENT_KEY}`\n  }\n}\n\nexport default BaseComponent\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { isDisabled, isVisible, parseSelector } from '../util/index.js'\n\nconst getSelector = element => {\n  let selector = element.getAttribute('data-bs-target')\n\n  if (!selector || selector === '#') {\n    let hrefAttribute = element.getAttribute('href')\n\n    // The only valid content that could double as a selector are IDs or classes,\n    // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n    // `document.querySelector` will rightfully complain it is invalid.\n    // See https://github.com/twbs/bootstrap/issues/32273\n    if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {\n      return null\n    }\n\n    // Just in case some CMS puts out a full URL with the anchor appended\n    if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n      hrefAttribute = `#${hrefAttribute.split('#')[1]}`\n    }\n\n    selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null\n  }\n\n  return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null\n}\n\nconst SelectorEngine = {\n  find(selector, element = document.documentElement) {\n    return [].concat(...Element.prototype.querySelectorAll.call(element, selector))\n  },\n\n  findOne(selector, element = document.documentElement) {\n    return Element.prototype.querySelector.call(element, selector)\n  },\n\n  children(element, selector) {\n    return [].concat(...element.children).filter(child => child.matches(selector))\n  },\n\n  parents(element, selector) {\n    const parents = []\n    let ancestor = element.parentNode.closest(selector)\n\n    while (ancestor) {\n      parents.push(ancestor)\n      ancestor = ancestor.parentNode.closest(selector)\n    }\n\n    return parents\n  },\n\n  prev(element, selector) {\n    let previous = element.previousElementSibling\n\n    while (previous) {\n      if (previous.matches(selector)) {\n        return [previous]\n      }\n\n      previous = previous.previousElementSibling\n    }\n\n    return []\n  },\n  // TODO: this is now unused; remove later along with prev()\n  next(element, selector) {\n    let next = element.nextElementSibling\n\n    while (next) {\n      if (next.matches(selector)) {\n        return [next]\n      }\n\n      next = next.nextElementSibling\n    }\n\n    return []\n  },\n\n  focusableChildren(element) {\n    const focusables = [\n      'a',\n      'button',\n      'input',\n      'textarea',\n      'select',\n      'details',\n      '[tabindex]',\n      '[contenteditable=\"true\"]'\n    ].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',')\n\n    return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el))\n  },\n\n  getSelectorFromElement(element) {\n    const selector = getSelector(element)\n\n    if (selector) {\n      return SelectorEngine.findOne(selector) ? selector : null\n    }\n\n    return null\n  },\n\n  getElementFromSelector(element) {\n    const selector = getSelector(element)\n\n    return selector ? SelectorEngine.findOne(selector) : null\n  },\n\n  getMultipleElementsFromSelector(element) {\n    const selector = getSelector(element)\n\n    return selector ? SelectorEngine.find(selector) : []\n  }\n}\n\nexport default SelectorEngine\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport { isDisabled } from './index.js'\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n  const clickEvent = `click.dismiss${component.EVENT_KEY}`\n  const name = component.NAME\n\n  EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault()\n    }\n\n    if (isDisabled(this)) {\n      return\n    }\n\n    const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`)\n    const instance = component.getOrCreateInstance(target)\n\n    // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n    instance[method]()\n  })\n}\n\nexport {\n  enableDismissTrigger\n}\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n  // Getters\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  close() {\n    const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n    if (closeEvent.defaultPrevented) {\n      return\n    }\n\n    this._element.classList.remove(CLASS_NAME_SHOW)\n\n    const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n    this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n  }\n\n  // Private\n  _destroyElement() {\n    this._element.remove()\n    EventHandler.trigger(this._element, EVENT_CLOSED)\n    this.dispose()\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Alert.getOrCreateInstance(this)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config](this)\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert)\n\nexport default Alert\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n  // Getters\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  toggle() {\n    // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n    this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Button.getOrCreateInstance(this)\n\n      if (config === 'toggle') {\n        data[config]()\n      }\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n  event.preventDefault()\n\n  const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n  const data = Button.getOrCreateInstance(button)\n\n  data.toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button)\n\nexport default Button\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport Config from './config.js'\nimport { execute } from './index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'swipe'\nconst EVENT_KEY = '.bs.swipe'\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst POINTER_TYPE_TOUCH = 'touch'\nconst POINTER_TYPE_PEN = 'pen'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n  endCallback: null,\n  leftCallback: null,\n  rightCallback: null\n}\n\nconst DefaultType = {\n  endCallback: '(function|null)',\n  leftCallback: '(function|null)',\n  rightCallback: '(function|null)'\n}\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n  constructor(element, config) {\n    super()\n    this._element = element\n\n    if (!element || !Swipe.isSupported()) {\n      return\n    }\n\n    this._config = this._getConfig(config)\n    this._deltaX = 0\n    this._supportPointerEvents = Boolean(window.PointerEvent)\n    this._initEvents()\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  dispose() {\n    EventHandler.off(this._element, EVENT_KEY)\n  }\n\n  // Private\n  _start(event) {\n    if (!this._supportPointerEvents) {\n      this._deltaX = event.touches[0].clientX\n\n      return\n    }\n\n    if (this._eventIsPointerPenTouch(event)) {\n      this._deltaX = event.clientX\n    }\n  }\n\n  _end(event) {\n    if (this._eventIsPointerPenTouch(event)) {\n      this._deltaX = event.clientX - this._deltaX\n    }\n\n    this._handleSwipe()\n    execute(this._config.endCallback)\n  }\n\n  _move(event) {\n    this._deltaX = event.touches && event.touches.length > 1 ?\n      0 :\n      event.touches[0].clientX - this._deltaX\n  }\n\n  _handleSwipe() {\n    const absDeltaX = Math.abs(this._deltaX)\n\n    if (absDeltaX <= SWIPE_THRESHOLD) {\n      return\n    }\n\n    const direction = absDeltaX / this._deltaX\n\n    this._deltaX = 0\n\n    if (!direction) {\n      return\n    }\n\n    execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback)\n  }\n\n  _initEvents() {\n    if (this._supportPointerEvents) {\n      EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event))\n      EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event))\n\n      this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n    } else {\n      EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event))\n      EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event))\n      EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event))\n    }\n  }\n\n  _eventIsPointerPenTouch(event) {\n    return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)\n  }\n\n  // Static\n  static isSupported() {\n    return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n  }\n}\n\nexport default Swipe\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n  defineJQueryPlugin,\n  getNextActiveElement,\n  isRTL,\n  isVisible,\n  reflow,\n  triggerTransitionEnd\n} from './util/index.js'\nimport Swipe from './util/swipe.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'carousel'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ARROW_LEFT_KEY = 'ArrowLeft'\nconst ARROW_RIGHT_KEY = 'ArrowRight'\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next'\nconst ORDER_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_END = 'carousel-item-end'\nconst CLASS_NAME_START = 'carousel-item-start'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]'\n\nconst KEY_TO_DIRECTION = {\n  [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n  [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n}\n\nconst Default = {\n  interval: 5000,\n  keyboard: true,\n  pause: 'hover',\n  ride: false,\n  touch: true,\n  wrap: true\n}\n\nconst DefaultType = {\n  interval: '(number|boolean)', // TODO:v6 remove boolean support\n  keyboard: 'boolean',\n  pause: '(string|boolean)',\n  ride: '(boolean|string)',\n  touch: 'boolean',\n  wrap: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    this._interval = null\n    this._activeElement = null\n    this._isSliding = false\n    this.touchTimeout = null\n    this._swipeHelper = null\n\n    this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)\n    this._addEventListeners()\n\n    if (this._config.ride === CLASS_NAME_CAROUSEL) {\n      this.cycle()\n    }\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  next() {\n    this._slide(ORDER_NEXT)\n  }\n\n  nextWhenVisible() {\n    // FIXME TODO use `document.visibilityState`\n    // Don't call next when the page isn't visible\n    // or the carousel or its parent isn't visible\n    if (!document.hidden && isVisible(this._element)) {\n      this.next()\n    }\n  }\n\n  prev() {\n    this._slide(ORDER_PREV)\n  }\n\n  pause() {\n    if (this._isSliding) {\n      triggerTransitionEnd(this._element)\n    }\n\n    this._clearInterval()\n  }\n\n  cycle() {\n    this._clearInterval()\n    this._updateInterval()\n\n    this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval)\n  }\n\n  _maybeEnableCycle() {\n    if (!this._config.ride) {\n      return\n    }\n\n    if (this._isSliding) {\n      EventHandler.one(this._element, EVENT_SLID, () => this.cycle())\n      return\n    }\n\n    this.cycle()\n  }\n\n  to(index) {\n    const items = this._getItems()\n    if (index > items.length - 1 || index < 0) {\n      return\n    }\n\n    if (this._isSliding) {\n      EventHandler.one(this._element, EVENT_SLID, () => this.to(index))\n      return\n    }\n\n    const activeIndex = this._getItemIndex(this._getActive())\n    if (activeIndex === index) {\n      return\n    }\n\n    const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV\n\n    this._slide(order, items[index])\n  }\n\n  dispose() {\n    if (this._swipeHelper) {\n      this._swipeHelper.dispose()\n    }\n\n    super.dispose()\n  }\n\n  // Private\n  _configAfterMerge(config) {\n    config.defaultInterval = config.interval\n    return config\n  }\n\n  _addEventListeners() {\n    if (this._config.keyboard) {\n      EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))\n    }\n\n    if (this._config.pause === 'hover') {\n      EventHandler.on(this._element, EVENT_MOUSEENTER, () => this.pause())\n      EventHandler.on(this._element, EVENT_MOUSELEAVE, () => this._maybeEnableCycle())\n    }\n\n    if (this._config.touch && Swipe.isSupported()) {\n      this._addTouchEventListeners()\n    }\n  }\n\n  _addTouchEventListeners() {\n    for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n      EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault())\n    }\n\n    const endCallBack = () => {\n      if (this._config.pause !== 'hover') {\n        return\n      }\n\n      // If it's a touch-enabled device, mouseenter/leave are fired as\n      // part of the mouse compatibility events on first tap - the carousel\n      // would stop cycling until user tapped out of it;\n      // here, we listen for touchend, explicitly pause the carousel\n      // (as if it's the second time we tap on it, mouseenter compat event\n      // is NOT fired) and after a timeout (to allow for mouse compatibility\n      // events to fire) we explicitly restart cycling\n\n      this.pause()\n      if (this.touchTimeout) {\n        clearTimeout(this.touchTimeout)\n      }\n\n      this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n    }\n\n    const swipeConfig = {\n      leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n      rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n      endCallback: endCallBack\n    }\n\n    this._swipeHelper = new Swipe(this._element, swipeConfig)\n  }\n\n  _keydown(event) {\n    if (/input|textarea/i.test(event.target.tagName)) {\n      return\n    }\n\n    const direction = KEY_TO_DIRECTION[event.key]\n    if (direction) {\n      event.preventDefault()\n      this._slide(this._directionToOrder(direction))\n    }\n  }\n\n  _getItemIndex(element) {\n    return this._getItems().indexOf(element)\n  }\n\n  _setActiveIndicatorElement(index) {\n    if (!this._indicatorsElement) {\n      return\n    }\n\n    const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement)\n\n    activeIndicator.classList.remove(CLASS_NAME_ACTIVE)\n    activeIndicator.removeAttribute('aria-current')\n\n    const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement)\n\n    if (newActiveIndicator) {\n      newActiveIndicator.classList.add(CLASS_NAME_ACTIVE)\n      newActiveIndicator.setAttribute('aria-current', 'true')\n    }\n  }\n\n  _updateInterval() {\n    const element = this._activeElement || this._getActive()\n\n    if (!element) {\n      return\n    }\n\n    const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10)\n\n    this._config.interval = elementInterval || this._config.defaultInterval\n  }\n\n  _slide(order, element = null) {\n    if (this._isSliding) {\n      return\n    }\n\n    const activeElement = this._getActive()\n    const isNext = order === ORDER_NEXT\n    const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap)\n\n    if (nextElement === activeElement) {\n      return\n    }\n\n    const nextElementIndex = this._getItemIndex(nextElement)\n\n    const triggerEvent = eventName => {\n      return EventHandler.trigger(this._element, eventName, {\n        relatedTarget: nextElement,\n        direction: this._orderToDirection(order),\n        from: this._getItemIndex(activeElement),\n        to: nextElementIndex\n      })\n    }\n\n    const slideEvent = triggerEvent(EVENT_SLIDE)\n\n    if (slideEvent.defaultPrevented) {\n      return\n    }\n\n    if (!activeElement || !nextElement) {\n      // Some weirdness is happening, so we bail\n      // TODO: change tests that use empty divs to avoid this check\n      return\n    }\n\n    const isCycling = Boolean(this._interval)\n    this.pause()\n\n    this._isSliding = true\n\n    this._setActiveIndicatorElement(nextElementIndex)\n    this._activeElement = nextElement\n\n    const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END\n    const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV\n\n    nextElement.classList.add(orderClassName)\n\n    reflow(nextElement)\n\n    activeElement.classList.add(directionalClassName)\n    nextElement.classList.add(directionalClassName)\n\n    const completeCallBack = () => {\n      nextElement.classList.remove(directionalClassName, orderClassName)\n      nextElement.classList.add(CLASS_NAME_ACTIVE)\n\n      activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName)\n\n      this._isSliding = false\n\n      triggerEvent(EVENT_SLID)\n    }\n\n    this._queueCallback(completeCallBack, activeElement, this._isAnimated())\n\n    if (isCycling) {\n      this.cycle()\n    }\n  }\n\n  _isAnimated() {\n    return this._element.classList.contains(CLASS_NAME_SLIDE)\n  }\n\n  _getActive() {\n    return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)\n  }\n\n  _getItems() {\n    return SelectorEngine.find(SELECTOR_ITEM, this._element)\n  }\n\n  _clearInterval() {\n    if (this._interval) {\n      clearInterval(this._interval)\n      this._interval = null\n    }\n  }\n\n  _directionToOrder(direction) {\n    if (isRTL()) {\n      return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT\n    }\n\n    return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV\n  }\n\n  _orderToDirection(order) {\n    if (isRTL()) {\n      return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT\n    }\n\n    return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Carousel.getOrCreateInstance(this, config)\n\n      if (typeof config === 'number') {\n        data.to(config)\n        return\n      }\n\n      if (typeof config === 'string') {\n        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n          throw new TypeError(`No method named \"${config}\"`)\n        }\n\n        data[config]()\n      }\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) {\n  const target = SelectorEngine.getElementFromSelector(this)\n\n  if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n    return\n  }\n\n  event.preventDefault()\n\n  const carousel = Carousel.getOrCreateInstance(target)\n  const slideIndex = this.getAttribute('data-bs-slide-to')\n\n  if (slideIndex) {\n    carousel.to(slideIndex)\n    carousel._maybeEnableCycle()\n    return\n  }\n\n  if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n    carousel.next()\n    carousel._maybeEnableCycle()\n    return\n  }\n\n  carousel.prev()\n  carousel._maybeEnableCycle()\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n  const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE)\n\n  for (const carousel of carousels) {\n    Carousel.getOrCreateInstance(carousel)\n  }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel)\n\nexport default Carousel\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n  defineJQueryPlugin,\n  getElement,\n  reflow\n} from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'collapse'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal'\n\nconst WIDTH = 'width'\nconst HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"collapse\"]'\n\nconst Default = {\n  parent: null,\n  toggle: true\n}\n\nconst DefaultType = {\n  parent: '(null|element)',\n  toggle: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    this._isTransitioning = false\n    this._triggerArray = []\n\n    const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)\n\n    for (const elem of toggleList) {\n      const selector = SelectorEngine.getSelectorFromElement(elem)\n      const filterElement = SelectorEngine.find(selector)\n        .filter(foundElement => foundElement === this._element)\n\n      if (selector !== null && filterElement.length) {\n        this._triggerArray.push(elem)\n      }\n    }\n\n    this._initializeChildren()\n\n    if (!this._config.parent) {\n      this._addAriaAndCollapsedClass(this._triggerArray, this._isShown())\n    }\n\n    if (this._config.toggle) {\n      this.toggle()\n    }\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  toggle() {\n    if (this._isShown()) {\n      this.hide()\n    } else {\n      this.show()\n    }\n  }\n\n  show() {\n    if (this._isTransitioning || this._isShown()) {\n      return\n    }\n\n    let activeChildren = []\n\n    // find active children\n    if (this._config.parent) {\n      activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES)\n        .filter(element => element !== this._element)\n        .map(element => Collapse.getOrCreateInstance(element, { toggle: false }))\n    }\n\n    if (activeChildren.length && activeChildren[0]._isTransitioning) {\n      return\n    }\n\n    const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)\n    if (startEvent.defaultPrevented) {\n      return\n    }\n\n    for (const activeInstance of activeChildren) {\n      activeInstance.hide()\n    }\n\n    const dimension = this._getDimension()\n\n    this._element.classList.remove(CLASS_NAME_COLLAPSE)\n    this._element.classList.add(CLASS_NAME_COLLAPSING)\n\n    this._element.style[dimension] = 0\n\n    this._addAriaAndCollapsedClass(this._triggerArray, true)\n    this._isTransitioning = true\n\n    const complete = () => {\n      this._isTransitioning = false\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSING)\n      this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n      this._element.style[dimension] = ''\n\n      EventHandler.trigger(this._element, EVENT_SHOWN)\n    }\n\n    const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n    const scrollSize = `scroll${capitalizedDimension}`\n\n    this._queueCallback(complete, this._element, true)\n    this._element.style[dimension] = `${this._element[scrollSize]}px`\n  }\n\n  hide() {\n    if (this._isTransitioning || !this._isShown()) {\n      return\n    }\n\n    const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n    if (startEvent.defaultPrevented) {\n      return\n    }\n\n    const dimension = this._getDimension()\n\n    this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n    reflow(this._element)\n\n    this._element.classList.add(CLASS_NAME_COLLAPSING)\n    this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n    for (const trigger of this._triggerArray) {\n      const element = SelectorEngine.getElementFromSelector(trigger)\n\n      if (element && !this._isShown(element)) {\n        this._addAriaAndCollapsedClass([trigger], false)\n      }\n    }\n\n    this._isTransitioning = true\n\n    const complete = () => {\n      this._isTransitioning = false\n      this._element.classList.remove(CLASS_NAME_COLLAPSING)\n      this._element.classList.add(CLASS_NAME_COLLAPSE)\n      EventHandler.trigger(this._element, EVENT_HIDDEN)\n    }\n\n    this._element.style[dimension] = ''\n\n    this._queueCallback(complete, this._element, true)\n  }\n\n  // Private\n  _isShown(element = this._element) {\n    return element.classList.contains(CLASS_NAME_SHOW)\n  }\n\n  _configAfterMerge(config) {\n    config.toggle = Boolean(config.toggle) // Coerce string values\n    config.parent = getElement(config.parent)\n    return config\n  }\n\n  _getDimension() {\n    return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT\n  }\n\n  _initializeChildren() {\n    if (!this._config.parent) {\n      return\n    }\n\n    const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE)\n\n    for (const element of children) {\n      const selected = SelectorEngine.getElementFromSelector(element)\n\n      if (selected) {\n        this._addAriaAndCollapsedClass([element], this._isShown(selected))\n      }\n    }\n  }\n\n  _getFirstLevelChildren(selector) {\n    const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent)\n    // remove children if greater depth\n    return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element))\n  }\n\n  _addAriaAndCollapsedClass(triggerArray, isOpen) {\n    if (!triggerArray.length) {\n      return\n    }\n\n    for (const element of triggerArray) {\n      element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen)\n      element.setAttribute('aria-expanded', isOpen)\n    }\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    const _config = {}\n    if (typeof config === 'string' && /show|hide/.test(config)) {\n      _config.toggle = false\n    }\n\n    return this.each(function () {\n      const data = Collapse.getOrCreateInstance(this, _config)\n\n      if (typeof config === 'string') {\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`)\n        }\n\n        data[config]()\n      }\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n  // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n  if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {\n    event.preventDefault()\n  }\n\n  for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n    Collapse.getOrCreateInstance(element, { toggle: false }).toggle()\n  }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse)\n\nexport default Collapse\n", "export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n  return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n  return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];", "export default function getNodeName(element) {\n  return element ? (element.nodeName || '').toLowerCase() : null;\n}", "export default function getWindow(node) {\n  if (node == null) {\n    return window;\n  }\n\n  if (node.toString() !== '[object Window]') {\n    var ownerDocument = node.ownerDocument;\n    return ownerDocument ? ownerDocument.defaultView || window : window;\n  }\n\n  return node;\n}", "import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n  var OwnElement = getWindow(node).Element;\n  return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n  var OwnElement = getWindow(node).HTMLElement;\n  return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n  // IE 11 has no ShadowRoot\n  if (typeof ShadowRoot === 'undefined') {\n    return false;\n  }\n\n  var OwnElement = getWindow(node).ShadowRoot;\n  return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };", "import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n  var state = _ref.state;\n  Object.keys(state.elements).forEach(function (name) {\n    var style = state.styles[name] || {};\n    var attributes = state.attributes[name] || {};\n    var element = state.elements[name]; // arrow is optional + virtual elements\n\n    if (!isHTMLElement(element) || !getNodeName(element)) {\n      return;\n    } // Flow doesn't support to extend this property, but it's the most\n    // effective way to apply styles to an HTMLElement\n    // $FlowFixMe[cannot-write]\n\n\n    Object.assign(element.style, style);\n    Object.keys(attributes).forEach(function (name) {\n      var value = attributes[name];\n\n      if (value === false) {\n        element.removeAttribute(name);\n      } else {\n        element.setAttribute(name, value === true ? '' : value);\n      }\n    });\n  });\n}\n\nfunction effect(_ref2) {\n  var state = _ref2.state;\n  var initialStyles = {\n    popper: {\n      position: state.options.strategy,\n      left: '0',\n      top: '0',\n      margin: '0'\n    },\n    arrow: {\n      position: 'absolute'\n    },\n    reference: {}\n  };\n  Object.assign(state.elements.popper.style, initialStyles.popper);\n  state.styles = initialStyles;\n\n  if (state.elements.arrow) {\n    Object.assign(state.elements.arrow.style, initialStyles.arrow);\n  }\n\n  return function () {\n    Object.keys(state.elements).forEach(function (name) {\n      var element = state.elements[name];\n      var attributes = state.attributes[name] || {};\n      var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n      var style = styleProperties.reduce(function (style, property) {\n        style[property] = '';\n        return style;\n      }, {}); // arrow is optional + virtual elements\n\n      if (!isHTMLElement(element) || !getNodeName(element)) {\n        return;\n      }\n\n      Object.assign(element.style, style);\n      Object.keys(attributes).forEach(function (attribute) {\n        element.removeAttribute(attribute);\n      });\n    });\n  };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'applyStyles',\n  enabled: true,\n  phase: 'write',\n  fn: applyStyles,\n  effect: effect,\n  requires: ['computeStyles']\n};", "import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n  return placement.split('-')[0];\n}", "export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;", "export default function getUAString() {\n  var uaData = navigator.userAgentData;\n\n  if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {\n    return uaData.brands.map(function (item) {\n      return item.brand + \"/\" + item.version;\n    }).join(' ');\n  }\n\n  return navigator.userAgent;\n}", "import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n  return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}", "import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n  if (includeScale === void 0) {\n    includeScale = false;\n  }\n\n  if (isFixedStrategy === void 0) {\n    isFixedStrategy = false;\n  }\n\n  var clientRect = element.getBoundingClientRect();\n  var scaleX = 1;\n  var scaleY = 1;\n\n  if (includeScale && isHTMLElement(element)) {\n    scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n    scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n  }\n\n  var _ref = isElement(element) ? getWindow(element) : window,\n      visualViewport = _ref.visualViewport;\n\n  var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n  var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n  var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n  var width = clientRect.width / scaleX;\n  var height = clientRect.height / scaleY;\n  return {\n    width: width,\n    height: height,\n    top: y,\n    right: x + width,\n    bottom: y + height,\n    left: x,\n    x: x,\n    y: y\n  };\n}", "import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n  var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n  // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n  var width = element.offsetWidth;\n  var height = element.offsetHeight;\n\n  if (Math.abs(clientRect.width - width) <= 1) {\n    width = clientRect.width;\n  }\n\n  if (Math.abs(clientRect.height - height) <= 1) {\n    height = clientRect.height;\n  }\n\n  return {\n    x: element.offsetLeft,\n    y: element.offsetTop,\n    width: width,\n    height: height\n  };\n}", "import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n  var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n  if (parent.contains(child)) {\n    return true;\n  } // then fallback to custom implementation with Shadow DOM support\n  else if (rootNode && isShadowRoot(rootNode)) {\n      var next = child;\n\n      do {\n        if (next && parent.isSameNode(next)) {\n          return true;\n        } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n        next = next.parentNode || next.host;\n      } while (next);\n    } // Give up, the result is false\n\n\n  return false;\n}", "import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n  return getWindow(element).getComputedStyle(element);\n}", "import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n  return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}", "import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n  // $FlowFixMe[incompatible-return]: assume body is always available\n  return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n  element.document) || window.document).documentElement;\n}", "import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n  if (getNodeName(element) === 'html') {\n    return element;\n  }\n\n  return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n    // $FlowFixMe[incompatible-return]\n    // $FlowFixMe[prop-missing]\n    element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n    element.parentNode || ( // DOM Element detected\n    isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n    // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n    getDocumentElement(element) // fallback\n\n  );\n}", "import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n  if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n  getComputedStyle(element).position === 'fixed') {\n    return null;\n  }\n\n  return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n  var isFirefox = /firefox/i.test(getUAString());\n  var isIE = /Trident/i.test(getUAString());\n\n  if (isIE && isHTMLElement(element)) {\n    // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n    var elementCss = getComputedStyle(element);\n\n    if (elementCss.position === 'fixed') {\n      return null;\n    }\n  }\n\n  var currentNode = getParentNode(element);\n\n  if (isShadowRoot(currentNode)) {\n    currentNode = currentNode.host;\n  }\n\n  while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n    var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n    // create a containing block.\n    // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n    if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n      return currentNode;\n    } else {\n      currentNode = currentNode.parentNode;\n    }\n  }\n\n  return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n  var window = getWindow(element);\n  var offsetParent = getTrueOffsetParent(element);\n\n  while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n    offsetParent = getTrueOffsetParent(offsetParent);\n  }\n\n  if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n    return window;\n  }\n\n  return offsetParent || getContainingBlock(element) || window;\n}", "export default function getMainAxisFromPlacement(placement) {\n  return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}", "import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n  return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n  var v = within(min, value, max);\n  return v > max ? max : v;\n}", "import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n  return Object.assign({}, getFreshSideObject(), paddingObject);\n}", "export default function getFreshSideObject() {\n  return {\n    top: 0,\n    right: 0,\n    bottom: 0,\n    left: 0\n  };\n}", "export default function expandToHashMap(value, keys) {\n  return keys.reduce(function (hashMap, key) {\n    hashMap[key] = value;\n    return hashMap;\n  }, {});\n}", "import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n  padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n    placement: state.placement\n  })) : padding;\n  return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n  var _state$modifiersData$;\n\n  var state = _ref.state,\n      name = _ref.name,\n      options = _ref.options;\n  var arrowElement = state.elements.arrow;\n  var popperOffsets = state.modifiersData.popperOffsets;\n  var basePlacement = getBasePlacement(state.placement);\n  var axis = getMainAxisFromPlacement(basePlacement);\n  var isVertical = [left, right].indexOf(basePlacement) >= 0;\n  var len = isVertical ? 'height' : 'width';\n\n  if (!arrowElement || !popperOffsets) {\n    return;\n  }\n\n  var paddingObject = toPaddingObject(options.padding, state);\n  var arrowRect = getLayoutRect(arrowElement);\n  var minProp = axis === 'y' ? top : left;\n  var maxProp = axis === 'y' ? bottom : right;\n  var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n  var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n  var arrowOffsetParent = getOffsetParent(arrowElement);\n  var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n  var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n  // outside of the popper bounds\n\n  var min = paddingObject[minProp];\n  var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n  var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n  var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n  var axisProp = axis;\n  state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n  var state = _ref2.state,\n      options = _ref2.options;\n  var _options$element = options.element,\n      arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n  if (arrowElement == null) {\n    return;\n  } // CSS selector\n\n\n  if (typeof arrowElement === 'string') {\n    arrowElement = state.elements.popper.querySelector(arrowElement);\n\n    if (!arrowElement) {\n      return;\n    }\n  }\n\n  if (!contains(state.elements.popper, arrowElement)) {\n    return;\n  }\n\n  state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'arrow',\n  enabled: true,\n  phase: 'main',\n  fn: arrow,\n  effect: effect,\n  requires: ['popperOffsets'],\n  requiresIfExists: ['preventOverflow']\n};", "export default function getVariation(placement) {\n  return placement.split('-')[1];\n}", "import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n  top: 'auto',\n  right: 'auto',\n  bottom: 'auto',\n  left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref, win) {\n  var x = _ref.x,\n      y = _ref.y;\n  var dpr = win.devicePixelRatio || 1;\n  return {\n    x: round(x * dpr) / dpr || 0,\n    y: round(y * dpr) / dpr || 0\n  };\n}\n\nexport function mapToStyles(_ref2) {\n  var _Object$assign2;\n\n  var popper = _ref2.popper,\n      popperRect = _ref2.popperRect,\n      placement = _ref2.placement,\n      variation = _ref2.variation,\n      offsets = _ref2.offsets,\n      position = _ref2.position,\n      gpuAcceleration = _ref2.gpuAcceleration,\n      adaptive = _ref2.adaptive,\n      roundOffsets = _ref2.roundOffsets,\n      isFixed = _ref2.isFixed;\n  var _offsets$x = offsets.x,\n      x = _offsets$x === void 0 ? 0 : _offsets$x,\n      _offsets$y = offsets.y,\n      y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n  var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n    x: x,\n    y: y\n  }) : {\n    x: x,\n    y: y\n  };\n\n  x = _ref3.x;\n  y = _ref3.y;\n  var hasX = offsets.hasOwnProperty('x');\n  var hasY = offsets.hasOwnProperty('y');\n  var sideX = left;\n  var sideY = top;\n  var win = window;\n\n  if (adaptive) {\n    var offsetParent = getOffsetParent(popper);\n    var heightProp = 'clientHeight';\n    var widthProp = 'clientWidth';\n\n    if (offsetParent === getWindow(popper)) {\n      offsetParent = getDocumentElement(popper);\n\n      if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n        heightProp = 'scrollHeight';\n        widthProp = 'scrollWidth';\n      }\n    } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n    offsetParent = offsetParent;\n\n    if (placement === top || (placement === left || placement === right) && variation === end) {\n      sideY = bottom;\n      var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n      offsetParent[heightProp];\n      y -= offsetY - popperRect.height;\n      y *= gpuAcceleration ? 1 : -1;\n    }\n\n    if (placement === left || (placement === top || placement === bottom) && variation === end) {\n      sideX = right;\n      var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n      offsetParent[widthProp];\n      x -= offsetX - popperRect.width;\n      x *= gpuAcceleration ? 1 : -1;\n    }\n  }\n\n  var commonStyles = Object.assign({\n    position: position\n  }, adaptive && unsetSides);\n\n  var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n    x: x,\n    y: y\n  }, getWindow(popper)) : {\n    x: x,\n    y: y\n  };\n\n  x = _ref4.x;\n  y = _ref4.y;\n\n  if (gpuAcceleration) {\n    var _Object$assign;\n\n    return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n  }\n\n  return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n  var state = _ref5.state,\n      options = _ref5.options;\n  var _options$gpuAccelerat = options.gpuAcceleration,\n      gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n      _options$adaptive = options.adaptive,\n      adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n      _options$roundOffsets = options.roundOffsets,\n      roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n  var commonStyles = {\n    placement: getBasePlacement(state.placement),\n    variation: getVariation(state.placement),\n    popper: state.elements.popper,\n    popperRect: state.rects.popper,\n    gpuAcceleration: gpuAcceleration,\n    isFixed: state.options.strategy === 'fixed'\n  };\n\n  if (state.modifiersData.popperOffsets != null) {\n    state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n      offsets: state.modifiersData.popperOffsets,\n      position: state.options.strategy,\n      adaptive: adaptive,\n      roundOffsets: roundOffsets\n    })));\n  }\n\n  if (state.modifiersData.arrow != null) {\n    state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n      offsets: state.modifiersData.arrow,\n      position: 'absolute',\n      adaptive: false,\n      roundOffsets: roundOffsets\n    })));\n  }\n\n  state.attributes.popper = Object.assign({}, state.attributes.popper, {\n    'data-popper-placement': state.placement\n  });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'computeStyles',\n  enabled: true,\n  phase: 'beforeWrite',\n  fn: computeStyles,\n  data: {}\n};", "import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n  passive: true\n};\n\nfunction effect(_ref) {\n  var state = _ref.state,\n      instance = _ref.instance,\n      options = _ref.options;\n  var _options$scroll = options.scroll,\n      scroll = _options$scroll === void 0 ? true : _options$scroll,\n      _options$resize = options.resize,\n      resize = _options$resize === void 0 ? true : _options$resize;\n  var window = getWindow(state.elements.popper);\n  var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n  if (scroll) {\n    scrollParents.forEach(function (scrollParent) {\n      scrollParent.addEventListener('scroll', instance.update, passive);\n    });\n  }\n\n  if (resize) {\n    window.addEventListener('resize', instance.update, passive);\n  }\n\n  return function () {\n    if (scroll) {\n      scrollParents.forEach(function (scrollParent) {\n        scrollParent.removeEventListener('scroll', instance.update, passive);\n      });\n    }\n\n    if (resize) {\n      window.removeEventListener('resize', instance.update, passive);\n    }\n  };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'eventListeners',\n  enabled: true,\n  phase: 'write',\n  fn: function fn() {},\n  effect: effect,\n  data: {}\n};", "var hash = {\n  left: 'right',\n  right: 'left',\n  bottom: 'top',\n  top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n  return placement.replace(/left|right|bottom|top/g, function (matched) {\n    return hash[matched];\n  });\n}", "var hash = {\n  start: 'end',\n  end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n  return placement.replace(/start|end/g, function (matched) {\n    return hash[matched];\n  });\n}", "import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n  var win = getWindow(node);\n  var scrollLeft = win.pageXOffset;\n  var scrollTop = win.pageYOffset;\n  return {\n    scrollLeft: scrollLeft,\n    scrollTop: scrollTop\n  };\n}", "import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n  // If <html> has a CSS width greater than the viewport, then this will be\n  // incorrect for RTL.\n  // Popper 1 is broken in this case and never had a bug report so let's assume\n  // it's not an issue. I don't think anyone ever specifies width on <html>\n  // anyway.\n  // Browsers where the left scrollbar doesn't cause an issue report `0` for\n  // this (e.g. Edge 2019, IE11, Safari)\n  return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}", "import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n  // Firefox wants us to check `-x` and `-y` variations as well\n  var _getComputedStyle = getComputedStyle(element),\n      overflow = _getComputedStyle.overflow,\n      overflowX = _getComputedStyle.overflowX,\n      overflowY = _getComputedStyle.overflowY;\n\n  return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}", "import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n  if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n    // $FlowFixMe[incompatible-return]: assume body is always available\n    return node.ownerDocument.body;\n  }\n\n  if (isHTMLElement(node) && isScrollParent(node)) {\n    return node;\n  }\n\n  return getScrollParent(getParentNode(node));\n}", "import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n  var _element$ownerDocumen;\n\n  if (list === void 0) {\n    list = [];\n  }\n\n  var scrollParent = getScrollParent(element);\n  var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n  var win = getWindow(scrollParent);\n  var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n  var updatedList = list.concat(target);\n  return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n  updatedList.concat(listScrollParents(getParentNode(target)));\n}", "export default function rectToClientRect(rect) {\n  return Object.assign({}, rect, {\n    left: rect.x,\n    top: rect.y,\n    right: rect.x + rect.width,\n    bottom: rect.y + rect.height\n  });\n}", "import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n  var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n  rect.top = rect.top + element.clientTop;\n  rect.left = rect.left + element.clientLeft;\n  rect.bottom = rect.top + element.clientHeight;\n  rect.right = rect.left + element.clientWidth;\n  rect.width = element.clientWidth;\n  rect.height = element.clientHeight;\n  rect.x = rect.left;\n  rect.y = rect.top;\n  return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n  return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n  var clippingParents = listScrollParents(getParentNode(element));\n  var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n  var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n  if (!isElement(clipperElement)) {\n    return [];\n  } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n  return clippingParents.filter(function (clippingParent) {\n    return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n  });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n  var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n  var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n  var firstClippingParent = clippingParents[0];\n  var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n    var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n    accRect.top = max(rect.top, accRect.top);\n    accRect.right = min(rect.right, accRect.right);\n    accRect.bottom = min(rect.bottom, accRect.bottom);\n    accRect.left = max(rect.left, accRect.left);\n    return accRect;\n  }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n  clippingRect.width = clippingRect.right - clippingRect.left;\n  clippingRect.height = clippingRect.bottom - clippingRect.top;\n  clippingRect.x = clippingRect.left;\n  clippingRect.y = clippingRect.top;\n  return clippingRect;\n}", "import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n  var win = getWindow(element);\n  var html = getDocumentElement(element);\n  var visualViewport = win.visualViewport;\n  var width = html.clientWidth;\n  var height = html.clientHeight;\n  var x = 0;\n  var y = 0;\n\n  if (visualViewport) {\n    width = visualViewport.width;\n    height = visualViewport.height;\n    var layoutViewport = isLayoutViewport();\n\n    if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n      x = visualViewport.offsetLeft;\n      y = visualViewport.offsetTop;\n    }\n  }\n\n  return {\n    width: width,\n    height: height,\n    x: x + getWindowScrollBarX(element),\n    y: y\n  };\n}", "import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `<html>` and `<body>` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n  var _element$ownerDocumen;\n\n  var html = getDocumentElement(element);\n  var winScroll = getWindowScroll(element);\n  var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n  var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n  var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n  var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n  var y = -winScroll.scrollTop;\n\n  if (getComputedStyle(body || html).direction === 'rtl') {\n    x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n  }\n\n  return {\n    width: width,\n    height: height,\n    x: x,\n    y: y\n  };\n}", "import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n  var reference = _ref.reference,\n      element = _ref.element,\n      placement = _ref.placement;\n  var basePlacement = placement ? getBasePlacement(placement) : null;\n  var variation = placement ? getVariation(placement) : null;\n  var commonX = reference.x + reference.width / 2 - element.width / 2;\n  var commonY = reference.y + reference.height / 2 - element.height / 2;\n  var offsets;\n\n  switch (basePlacement) {\n    case top:\n      offsets = {\n        x: commonX,\n        y: reference.y - element.height\n      };\n      break;\n\n    case bottom:\n      offsets = {\n        x: commonX,\n        y: reference.y + reference.height\n      };\n      break;\n\n    case right:\n      offsets = {\n        x: reference.x + reference.width,\n        y: commonY\n      };\n      break;\n\n    case left:\n      offsets = {\n        x: reference.x - element.width,\n        y: commonY\n      };\n      break;\n\n    default:\n      offsets = {\n        x: reference.x,\n        y: reference.y\n      };\n  }\n\n  var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n  if (mainAxis != null) {\n    var len = mainAxis === 'y' ? 'height' : 'width';\n\n    switch (variation) {\n      case start:\n        offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n        break;\n\n      case end:\n        offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n        break;\n\n      default:\n    }\n  }\n\n  return offsets;\n}", "import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n  if (options === void 0) {\n    options = {};\n  }\n\n  var _options = options,\n      _options$placement = _options.placement,\n      placement = _options$placement === void 0 ? state.placement : _options$placement,\n      _options$strategy = _options.strategy,\n      strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n      _options$boundary = _options.boundary,\n      boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n      _options$rootBoundary = _options.rootBoundary,\n      rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n      _options$elementConte = _options.elementContext,\n      elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n      _options$altBoundary = _options.altBoundary,\n      altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n      _options$padding = _options.padding,\n      padding = _options$padding === void 0 ? 0 : _options$padding;\n  var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n  var altContext = elementContext === popper ? reference : popper;\n  var popperRect = state.rects.popper;\n  var element = state.elements[altBoundary ? altContext : elementContext];\n  var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n  var referenceClientRect = getBoundingClientRect(state.elements.reference);\n  var popperOffsets = computeOffsets({\n    reference: referenceClientRect,\n    element: popperRect,\n    strategy: 'absolute',\n    placement: placement\n  });\n  var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n  var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n  // 0 or negative = within the clipping rect\n\n  var overflowOffsets = {\n    top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n    bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n    left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n    right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n  };\n  var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n  if (elementContext === popper && offsetData) {\n    var offset = offsetData[placement];\n    Object.keys(overflowOffsets).forEach(function (key) {\n      var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n      var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n      overflowOffsets[key] += offset[axis] * multiply;\n    });\n  }\n\n  return overflowOffsets;\n}", "import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n  if (options === void 0) {\n    options = {};\n  }\n\n  var _options = options,\n      placement = _options.placement,\n      boundary = _options.boundary,\n      rootBoundary = _options.rootBoundary,\n      padding = _options.padding,\n      flipVariations = _options.flipVariations,\n      _options$allowedAutoP = _options.allowedAutoPlacements,\n      allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n  var variation = getVariation(placement);\n  var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n    return getVariation(placement) === variation;\n  }) : basePlacements;\n  var allowedPlacements = placements.filter(function (placement) {\n    return allowedAutoPlacements.indexOf(placement) >= 0;\n  });\n\n  if (allowedPlacements.length === 0) {\n    allowedPlacements = placements;\n  } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n  var overflows = allowedPlacements.reduce(function (acc, placement) {\n    acc[placement] = detectOverflow(state, {\n      placement: placement,\n      boundary: boundary,\n      rootBoundary: rootBoundary,\n      padding: padding\n    })[getBasePlacement(placement)];\n    return acc;\n  }, {});\n  return Object.keys(overflows).sort(function (a, b) {\n    return overflows[a] - overflows[b];\n  });\n}", "import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n  if (getBasePlacement(placement) === auto) {\n    return [];\n  }\n\n  var oppositePlacement = getOppositePlacement(placement);\n  return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n  var state = _ref.state,\n      options = _ref.options,\n      name = _ref.name;\n\n  if (state.modifiersData[name]._skip) {\n    return;\n  }\n\n  var _options$mainAxis = options.mainAxis,\n      checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n      _options$altAxis = options.altAxis,\n      checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n      specifiedFallbackPlacements = options.fallbackPlacements,\n      padding = options.padding,\n      boundary = options.boundary,\n      rootBoundary = options.rootBoundary,\n      altBoundary = options.altBoundary,\n      _options$flipVariatio = options.flipVariations,\n      flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n      allowedAutoPlacements = options.allowedAutoPlacements;\n  var preferredPlacement = state.options.placement;\n  var basePlacement = getBasePlacement(preferredPlacement);\n  var isBasePlacement = basePlacement === preferredPlacement;\n  var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n  var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n    return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n      placement: placement,\n      boundary: boundary,\n      rootBoundary: rootBoundary,\n      padding: padding,\n      flipVariations: flipVariations,\n      allowedAutoPlacements: allowedAutoPlacements\n    }) : placement);\n  }, []);\n  var referenceRect = state.rects.reference;\n  var popperRect = state.rects.popper;\n  var checksMap = new Map();\n  var makeFallbackChecks = true;\n  var firstFittingPlacement = placements[0];\n\n  for (var i = 0; i < placements.length; i++) {\n    var placement = placements[i];\n\n    var _basePlacement = getBasePlacement(placement);\n\n    var isStartVariation = getVariation(placement) === start;\n    var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n    var len = isVertical ? 'width' : 'height';\n    var overflow = detectOverflow(state, {\n      placement: placement,\n      boundary: boundary,\n      rootBoundary: rootBoundary,\n      altBoundary: altBoundary,\n      padding: padding\n    });\n    var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n    if (referenceRect[len] > popperRect[len]) {\n      mainVariationSide = getOppositePlacement(mainVariationSide);\n    }\n\n    var altVariationSide = getOppositePlacement(mainVariationSide);\n    var checks = [];\n\n    if (checkMainAxis) {\n      checks.push(overflow[_basePlacement] <= 0);\n    }\n\n    if (checkAltAxis) {\n      checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n    }\n\n    if (checks.every(function (check) {\n      return check;\n    })) {\n      firstFittingPlacement = placement;\n      makeFallbackChecks = false;\n      break;\n    }\n\n    checksMap.set(placement, checks);\n  }\n\n  if (makeFallbackChecks) {\n    // `2` may be desired in some cases – research later\n    var numberOfChecks = flipVariations ? 3 : 1;\n\n    var _loop = function _loop(_i) {\n      var fittingPlacement = placements.find(function (placement) {\n        var checks = checksMap.get(placement);\n\n        if (checks) {\n          return checks.slice(0, _i).every(function (check) {\n            return check;\n          });\n        }\n      });\n\n      if (fittingPlacement) {\n        firstFittingPlacement = fittingPlacement;\n        return \"break\";\n      }\n    };\n\n    for (var _i = numberOfChecks; _i > 0; _i--) {\n      var _ret = _loop(_i);\n\n      if (_ret === \"break\") break;\n    }\n  }\n\n  if (state.placement !== firstFittingPlacement) {\n    state.modifiersData[name]._skip = true;\n    state.placement = firstFittingPlacement;\n    state.reset = true;\n  }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'flip',\n  enabled: true,\n  phase: 'main',\n  fn: flip,\n  requiresIfExists: ['offset'],\n  data: {\n    _skip: false\n  }\n};", "import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n  if (preventedOffsets === void 0) {\n    preventedOffsets = {\n      x: 0,\n      y: 0\n    };\n  }\n\n  return {\n    top: overflow.top - rect.height - preventedOffsets.y,\n    right: overflow.right - rect.width + preventedOffsets.x,\n    bottom: overflow.bottom - rect.height + preventedOffsets.y,\n    left: overflow.left - rect.width - preventedOffsets.x\n  };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n  return [top, right, bottom, left].some(function (side) {\n    return overflow[side] >= 0;\n  });\n}\n\nfunction hide(_ref) {\n  var state = _ref.state,\n      name = _ref.name;\n  var referenceRect = state.rects.reference;\n  var popperRect = state.rects.popper;\n  var preventedOffsets = state.modifiersData.preventOverflow;\n  var referenceOverflow = detectOverflow(state, {\n    elementContext: 'reference'\n  });\n  var popperAltOverflow = detectOverflow(state, {\n    altBoundary: true\n  });\n  var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n  var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n  var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n  var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n  state.modifiersData[name] = {\n    referenceClippingOffsets: referenceClippingOffsets,\n    popperEscapeOffsets: popperEscapeOffsets,\n    isReferenceHidden: isReferenceHidden,\n    hasPopperEscaped: hasPopperEscaped\n  };\n  state.attributes.popper = Object.assign({}, state.attributes.popper, {\n    'data-popper-reference-hidden': isReferenceHidden,\n    'data-popper-escaped': hasPopperEscaped\n  });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'hide',\n  enabled: true,\n  phase: 'main',\n  requiresIfExists: ['preventOverflow'],\n  fn: hide\n};", "import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n  var basePlacement = getBasePlacement(placement);\n  var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n  var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n    placement: placement\n  })) : offset,\n      skidding = _ref[0],\n      distance = _ref[1];\n\n  skidding = skidding || 0;\n  distance = (distance || 0) * invertDistance;\n  return [left, right].indexOf(basePlacement) >= 0 ? {\n    x: distance,\n    y: skidding\n  } : {\n    x: skidding,\n    y: distance\n  };\n}\n\nfunction offset(_ref2) {\n  var state = _ref2.state,\n      options = _ref2.options,\n      name = _ref2.name;\n  var _options$offset = options.offset,\n      offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n  var data = placements.reduce(function (acc, placement) {\n    acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n    return acc;\n  }, {});\n  var _data$state$placement = data[state.placement],\n      x = _data$state$placement.x,\n      y = _data$state$placement.y;\n\n  if (state.modifiersData.popperOffsets != null) {\n    state.modifiersData.popperOffsets.x += x;\n    state.modifiersData.popperOffsets.y += y;\n  }\n\n  state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'offset',\n  enabled: true,\n  phase: 'main',\n  requires: ['popperOffsets'],\n  fn: offset\n};", "import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n  var state = _ref.state,\n      name = _ref.name;\n  // Offsets are the actual position the popper needs to have to be\n  // properly positioned near its reference element\n  // This is the most basic placement, and will be adjusted by\n  // the modifiers in the next step\n  state.modifiersData[name] = computeOffsets({\n    reference: state.rects.reference,\n    element: state.rects.popper,\n    strategy: 'absolute',\n    placement: state.placement\n  });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'popperOffsets',\n  enabled: true,\n  phase: 'read',\n  fn: popperOffsets,\n  data: {}\n};", "import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n  var state = _ref.state,\n      options = _ref.options,\n      name = _ref.name;\n  var _options$mainAxis = options.mainAxis,\n      checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n      _options$altAxis = options.altAxis,\n      checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n      boundary = options.boundary,\n      rootBoundary = options.rootBoundary,\n      altBoundary = options.altBoundary,\n      padding = options.padding,\n      _options$tether = options.tether,\n      tether = _options$tether === void 0 ? true : _options$tether,\n      _options$tetherOffset = options.tetherOffset,\n      tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n  var overflow = detectOverflow(state, {\n    boundary: boundary,\n    rootBoundary: rootBoundary,\n    padding: padding,\n    altBoundary: altBoundary\n  });\n  var basePlacement = getBasePlacement(state.placement);\n  var variation = getVariation(state.placement);\n  var isBasePlacement = !variation;\n  var mainAxis = getMainAxisFromPlacement(basePlacement);\n  var altAxis = getAltAxis(mainAxis);\n  var popperOffsets = state.modifiersData.popperOffsets;\n  var referenceRect = state.rects.reference;\n  var popperRect = state.rects.popper;\n  var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n    placement: state.placement\n  })) : tetherOffset;\n  var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n    mainAxis: tetherOffsetValue,\n    altAxis: tetherOffsetValue\n  } : Object.assign({\n    mainAxis: 0,\n    altAxis: 0\n  }, tetherOffsetValue);\n  var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n  var data = {\n    x: 0,\n    y: 0\n  };\n\n  if (!popperOffsets) {\n    return;\n  }\n\n  if (checkMainAxis) {\n    var _offsetModifierState$;\n\n    var mainSide = mainAxis === 'y' ? top : left;\n    var altSide = mainAxis === 'y' ? bottom : right;\n    var len = mainAxis === 'y' ? 'height' : 'width';\n    var offset = popperOffsets[mainAxis];\n    var min = offset + overflow[mainSide];\n    var max = offset - overflow[altSide];\n    var additive = tether ? -popperRect[len] / 2 : 0;\n    var minLen = variation === start ? referenceRect[len] : popperRect[len];\n    var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n    // outside the reference bounds\n\n    var arrowElement = state.elements.arrow;\n    var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n      width: 0,\n      height: 0\n    };\n    var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n    var arrowPaddingMin = arrowPaddingObject[mainSide];\n    var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n    // to include its full size in the calculation. If the reference is small\n    // and near the edge of a boundary, the popper can overflow even if the\n    // reference is not overflowing as well (e.g. virtual elements with no\n    // width or height)\n\n    var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n    var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n    var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n    var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n    var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n    var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n    var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n    var tetherMax = offset + maxOffset - offsetModifierValue;\n    var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n    popperOffsets[mainAxis] = preventedOffset;\n    data[mainAxis] = preventedOffset - offset;\n  }\n\n  if (checkAltAxis) {\n    var _offsetModifierState$2;\n\n    var _mainSide = mainAxis === 'x' ? top : left;\n\n    var _altSide = mainAxis === 'x' ? bottom : right;\n\n    var _offset = popperOffsets[altAxis];\n\n    var _len = altAxis === 'y' ? 'height' : 'width';\n\n    var _min = _offset + overflow[_mainSide];\n\n    var _max = _offset - overflow[_altSide];\n\n    var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n    var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n    var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n    var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n    var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n    popperOffsets[altAxis] = _preventedOffset;\n    data[altAxis] = _preventedOffset - _offset;\n  }\n\n  state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n  name: 'preventOverflow',\n  enabled: true,\n  phase: 'main',\n  fn: preventOverflow,\n  requiresIfExists: ['offset']\n};", "export default function getAltAxis(axis) {\n  return axis === 'x' ? 'y' : 'x';\n}", "import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n  var rect = element.getBoundingClientRect();\n  var scaleX = round(rect.width) / element.offsetWidth || 1;\n  var scaleY = round(rect.height) / element.offsetHeight || 1;\n  return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n  if (isFixed === void 0) {\n    isFixed = false;\n  }\n\n  var isOffsetParentAnElement = isHTMLElement(offsetParent);\n  var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n  var documentElement = getDocumentElement(offsetParent);\n  var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n  var scroll = {\n    scrollLeft: 0,\n    scrollTop: 0\n  };\n  var offsets = {\n    x: 0,\n    y: 0\n  };\n\n  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n    if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n    isScrollParent(documentElement)) {\n      scroll = getNodeScroll(offsetParent);\n    }\n\n    if (isHTMLElement(offsetParent)) {\n      offsets = getBoundingClientRect(offsetParent, true);\n      offsets.x += offsetParent.clientLeft;\n      offsets.y += offsetParent.clientTop;\n    } else if (documentElement) {\n      offsets.x = getWindowScrollBarX(documentElement);\n    }\n  }\n\n  return {\n    x: rect.left + scroll.scrollLeft - offsets.x,\n    y: rect.top + scroll.scrollTop - offsets.y,\n    width: rect.width,\n    height: rect.height\n  };\n}", "import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n  if (node === getWindow(node) || !isHTMLElement(node)) {\n    return getWindowScroll(node);\n  } else {\n    return getHTMLElementScroll(node);\n  }\n}", "export default function getHTMLElementScroll(element) {\n  return {\n    scrollLeft: element.scrollLeft,\n    scrollTop: element.scrollTop\n  };\n}", "import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n  var map = new Map();\n  var visited = new Set();\n  var result = [];\n  modifiers.forEach(function (modifier) {\n    map.set(modifier.name, modifier);\n  }); // On visiting object, check for its dependencies and visit them recursively\n\n  function sort(modifier) {\n    visited.add(modifier.name);\n    var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n    requires.forEach(function (dep) {\n      if (!visited.has(dep)) {\n        var depModifier = map.get(dep);\n\n        if (depModifier) {\n          sort(depModifier);\n        }\n      }\n    });\n    result.push(modifier);\n  }\n\n  modifiers.forEach(function (modifier) {\n    if (!visited.has(modifier.name)) {\n      // check for visited object\n      sort(modifier);\n    }\n  });\n  return result;\n}\n\nexport default function orderModifiers(modifiers) {\n  // order based on dependencies\n  var orderedModifiers = order(modifiers); // order based on phase\n\n  return modifierPhases.reduce(function (acc, phase) {\n    return acc.concat(orderedModifiers.filter(function (modifier) {\n      return modifier.phase === phase;\n    }));\n  }, []);\n}", "import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nvar DEFAULT_OPTIONS = {\n  placement: 'bottom',\n  modifiers: [],\n  strategy: 'absolute'\n};\n\nfunction areValidElements() {\n  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n    args[_key] = arguments[_key];\n  }\n\n  return !args.some(function (element) {\n    return !(element && typeof element.getBoundingClientRect === 'function');\n  });\n}\n\nexport function popperGenerator(generatorOptions) {\n  if (generatorOptions === void 0) {\n    generatorOptions = {};\n  }\n\n  var _generatorOptions = generatorOptions,\n      _generatorOptions$def = _generatorOptions.defaultModifiers,\n      defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n      _generatorOptions$def2 = _generatorOptions.defaultOptions,\n      defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n  return function createPopper(reference, popper, options) {\n    if (options === void 0) {\n      options = defaultOptions;\n    }\n\n    var state = {\n      placement: 'bottom',\n      orderedModifiers: [],\n      options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n      modifiersData: {},\n      elements: {\n        reference: reference,\n        popper: popper\n      },\n      attributes: {},\n      styles: {}\n    };\n    var effectCleanupFns = [];\n    var isDestroyed = false;\n    var instance = {\n      state: state,\n      setOptions: function setOptions(setOptionsAction) {\n        var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n        cleanupModifierEffects();\n        state.options = Object.assign({}, defaultOptions, state.options, options);\n        state.scrollParents = {\n          reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n          popper: listScrollParents(popper)\n        }; // Orders the modifiers based on their dependencies and `phase`\n        // properties\n\n        var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n        state.orderedModifiers = orderedModifiers.filter(function (m) {\n          return m.enabled;\n        });\n        runModifierEffects();\n        return instance.update();\n      },\n      // Sync update – it will always be executed, even if not necessary. This\n      // is useful for low frequency updates where sync behavior simplifies the\n      // logic.\n      // For high frequency updates (e.g. `resize` and `scroll` events), always\n      // prefer the async Popper#update method\n      forceUpdate: function forceUpdate() {\n        if (isDestroyed) {\n          return;\n        }\n\n        var _state$elements = state.elements,\n            reference = _state$elements.reference,\n            popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n        // anymore\n\n        if (!areValidElements(reference, popper)) {\n          return;\n        } // Store the reference and popper rects to be read by modifiers\n\n\n        state.rects = {\n          reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n          popper: getLayoutRect(popper)\n        }; // Modifiers have the ability to reset the current update cycle. The\n        // most common use case for this is the `flip` modifier changing the\n        // placement, which then needs to re-run all the modifiers, because the\n        // logic was previously ran for the previous placement and is therefore\n        // stale/incorrect\n\n        state.reset = false;\n        state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n        // is filled with the initial data specified by the modifier. This means\n        // it doesn't persist and is fresh on each update.\n        // To ensure persistent data, use `${name}#persistent`\n\n        state.orderedModifiers.forEach(function (modifier) {\n          return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n        });\n\n        for (var index = 0; index < state.orderedModifiers.length; index++) {\n          if (state.reset === true) {\n            state.reset = false;\n            index = -1;\n            continue;\n          }\n\n          var _state$orderedModifie = state.orderedModifiers[index],\n              fn = _state$orderedModifie.fn,\n              _state$orderedModifie2 = _state$orderedModifie.options,\n              _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n              name = _state$orderedModifie.name;\n\n          if (typeof fn === 'function') {\n            state = fn({\n              state: state,\n              options: _options,\n              name: name,\n              instance: instance\n            }) || state;\n          }\n        }\n      },\n      // Async and optimistically optimized update – it will not be executed if\n      // not necessary (debounced to run at most once-per-tick)\n      update: debounce(function () {\n        return new Promise(function (resolve) {\n          instance.forceUpdate();\n          resolve(state);\n        });\n      }),\n      destroy: function destroy() {\n        cleanupModifierEffects();\n        isDestroyed = true;\n      }\n    };\n\n    if (!areValidElements(reference, popper)) {\n      return instance;\n    }\n\n    instance.setOptions(options).then(function (state) {\n      if (!isDestroyed && options.onFirstUpdate) {\n        options.onFirstUpdate(state);\n      }\n    }); // Modifiers have the ability to execute arbitrary code before the first\n    // update cycle runs. They will be executed in the same order as the update\n    // cycle. This is useful when a modifier adds some persistent data that\n    // other modifiers need to use, but the modifier is run after the dependent\n    // one.\n\n    function runModifierEffects() {\n      state.orderedModifiers.forEach(function (_ref) {\n        var name = _ref.name,\n            _ref$options = _ref.options,\n            options = _ref$options === void 0 ? {} : _ref$options,\n            effect = _ref.effect;\n\n        if (typeof effect === 'function') {\n          var cleanupFn = effect({\n            state: state,\n            name: name,\n            instance: instance,\n            options: options\n          });\n\n          var noopFn = function noopFn() {};\n\n          effectCleanupFns.push(cleanupFn || noopFn);\n        }\n      });\n    }\n\n    function cleanupModifierEffects() {\n      effectCleanupFns.forEach(function (fn) {\n        return fn();\n      });\n      effectCleanupFns = [];\n    }\n\n    return instance;\n  };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };", "export default function debounce(fn) {\n  var pending;\n  return function () {\n    if (!pending) {\n      pending = new Promise(function (resolve) {\n        Promise.resolve().then(function () {\n          pending = undefined;\n          resolve(fn());\n        });\n      });\n    }\n\n    return pending;\n  };\n}", "export default function mergeByName(modifiers) {\n  var merged = modifiers.reduce(function (merged, current) {\n    var existing = merged[current.name];\n    merged[current.name] = existing ? Object.assign({}, existing, current, {\n      options: Object.assign({}, existing.options, current.options),\n      data: Object.assign({}, existing.data, current.data)\n    }) : current;\n    return merged;\n  }, {}); // IE11 does not support Object.values\n\n  return Object.keys(merged).map(function (key) {\n    return merged[key];\n  });\n}", "import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n  defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };", "import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n  defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";", "/**\n * --------------------------------------------------------------------------\n * Bootstrap dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n  defineJQueryPlugin,\n  execute,\n  getElement,\n  getNextActiveElement,\n  isDisabled,\n  isElement,\n  isRTL,\n  isVisible,\n  noop\n} from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'dropdown'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ESCAPE_KEY = 'Escape'\nconst TAB_KEY = 'Tab'\nconst ARROW_UP_KEY = 'ArrowUp'\nconst ARROW_DOWN_KEY = 'ArrowDown'\nconst RIGHT_MOUSE_BUTTON = 2 // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPEND = 'dropend'\nconst CLASS_NAME_DROPSTART = 'dropstart'\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center'\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)'\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR = '.navbar'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'\nconst PLACEMENT_TOPCENTER = 'top'\nconst PLACEMENT_BOTTOMCENTER = 'bottom'\n\nconst Default = {\n  autoClose: true,\n  boundary: 'clippingParents',\n  display: 'dynamic',\n  offset: [0, 2],\n  popperConfig: null,\n  reference: 'toggle'\n}\n\nconst DefaultType = {\n  autoClose: '(boolean|string)',\n  boundary: '(string|element)',\n  display: 'string',\n  offset: '(array|string|function)',\n  popperConfig: '(null|object|function)',\n  reference: '(string|element|object)'\n}\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    this._popper = null\n    this._parent = this._element.parentNode // dropdown wrapper\n    // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n    this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] ||\n      SelectorEngine.prev(this._element, SELECTOR_MENU)[0] ||\n      SelectorEngine.findOne(SELECTOR_MENU, this._parent)\n    this._inNavbar = this._detectNavbar()\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  toggle() {\n    return this._isShown() ? this.hide() : this.show()\n  }\n\n  show() {\n    if (isDisabled(this._element) || this._isShown()) {\n      return\n    }\n\n    const relatedTarget = {\n      relatedTarget: this._element\n    }\n\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, relatedTarget)\n\n    if (showEvent.defaultPrevented) {\n      return\n    }\n\n    this._createPopper()\n\n    // If this is a touch-enabled device we add extra\n    // empty mouseover listeners to the body's immediate children;\n    // only needed because of broken event delegation on iOS\n    // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n    if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n      for (const element of [].concat(...document.body.children)) {\n        EventHandler.on(element, 'mouseover', noop)\n      }\n    }\n\n    this._element.focus()\n    this._element.setAttribute('aria-expanded', true)\n\n    this._menu.classList.add(CLASS_NAME_SHOW)\n    this._element.classList.add(CLASS_NAME_SHOW)\n    EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget)\n  }\n\n  hide() {\n    if (isDisabled(this._element) || !this._isShown()) {\n      return\n    }\n\n    const relatedTarget = {\n      relatedTarget: this._element\n    }\n\n    this._completeHide(relatedTarget)\n  }\n\n  dispose() {\n    if (this._popper) {\n      this._popper.destroy()\n    }\n\n    super.dispose()\n  }\n\n  update() {\n    this._inNavbar = this._detectNavbar()\n    if (this._popper) {\n      this._popper.update()\n    }\n  }\n\n  // Private\n  _completeHide(relatedTarget) {\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget)\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    // If this is a touch-enabled device we remove the extra\n    // empty mouseover listeners we added for iOS support\n    if ('ontouchstart' in document.documentElement) {\n      for (const element of [].concat(...document.body.children)) {\n        EventHandler.off(element, 'mouseover', noop)\n      }\n    }\n\n    if (this._popper) {\n      this._popper.destroy()\n    }\n\n    this._menu.classList.remove(CLASS_NAME_SHOW)\n    this._element.classList.remove(CLASS_NAME_SHOW)\n    this._element.setAttribute('aria-expanded', 'false')\n    Manipulator.removeDataAttribute(this._menu, 'popper')\n    EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)\n  }\n\n  _getConfig(config) {\n    config = super._getConfig(config)\n\n    if (typeof config.reference === 'object' && !isElement(config.reference) &&\n      typeof config.reference.getBoundingClientRect !== 'function'\n    ) {\n      // Popper virtual elements require a getBoundingClientRect method\n      throw new TypeError(`${NAME.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`)\n    }\n\n    return config\n  }\n\n  _createPopper() {\n    if (typeof Popper === 'undefined') {\n      throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org/docs/v2/)')\n    }\n\n    let referenceElement = this._element\n\n    if (this._config.reference === 'parent') {\n      referenceElement = this._parent\n    } else if (isElement(this._config.reference)) {\n      referenceElement = getElement(this._config.reference)\n    } else if (typeof this._config.reference === 'object') {\n      referenceElement = this._config.reference\n    }\n\n    const popperConfig = this._getPopperConfig()\n    this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig)\n  }\n\n  _isShown() {\n    return this._menu.classList.contains(CLASS_NAME_SHOW)\n  }\n\n  _getPlacement() {\n    const parentDropdown = this._parent\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n      return PLACEMENT_RIGHT\n    }\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n      return PLACEMENT_LEFT\n    }\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n      return PLACEMENT_TOPCENTER\n    }\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n      return PLACEMENT_BOTTOMCENTER\n    }\n\n    // We need to trim the value because custom properties can also include spaces\n    const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n      return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP\n    }\n\n    return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM\n  }\n\n  _detectNavbar() {\n    return this._element.closest(SELECTOR_NAVBAR) !== null\n  }\n\n  _getOffset() {\n    const { offset } = this._config\n\n    if (typeof offset === 'string') {\n      return offset.split(',').map(value => Number.parseInt(value, 10))\n    }\n\n    if (typeof offset === 'function') {\n      return popperData => offset(popperData, this._element)\n    }\n\n    return offset\n  }\n\n  _getPopperConfig() {\n    const defaultBsPopperConfig = {\n      placement: this._getPlacement(),\n      modifiers: [{\n        name: 'preventOverflow',\n        options: {\n          boundary: this._config.boundary\n        }\n      },\n      {\n        name: 'offset',\n        options: {\n          offset: this._getOffset()\n        }\n      }]\n    }\n\n    // Disable Popper if we have a static display or Dropdown is in Navbar\n    if (this._inNavbar || this._config.display === 'static') {\n      Manipulator.setDataAttribute(this._menu, 'popper', 'static') // TODO: v6 remove\n      defaultBsPopperConfig.modifiers = [{\n        name: 'applyStyles',\n        enabled: false\n      }]\n    }\n\n    return {\n      ...defaultBsPopperConfig,\n      ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])\n    }\n  }\n\n  _selectMenuItem({ key, target }) {\n    const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element))\n\n    if (!items.length) {\n      return\n    }\n\n    // if target isn't included in items (e.g. when expanding the dropdown)\n    // allow cycling to get the last item in case key equals ARROW_UP_KEY\n    getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus()\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Dropdown.getOrCreateInstance(this, config)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (typeof data[config] === 'undefined') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config]()\n    })\n  }\n\n  static clearMenus(event) {\n    if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) {\n      return\n    }\n\n    const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN)\n\n    for (const toggle of openToggles) {\n      const context = Dropdown.getInstance(toggle)\n      if (!context || context._config.autoClose === false) {\n        continue\n      }\n\n      const composedPath = event.composedPath()\n      const isMenuTarget = composedPath.includes(context._menu)\n      if (\n        composedPath.includes(context._element) ||\n        (context._config.autoClose === 'inside' && !isMenuTarget) ||\n        (context._config.autoClose === 'outside' && isMenuTarget)\n      ) {\n        continue\n      }\n\n      // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n      if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n        continue\n      }\n\n      const relatedTarget = { relatedTarget: context._element }\n\n      if (event.type === 'click') {\n        relatedTarget.clickEvent = event\n      }\n\n      context._completeHide(relatedTarget)\n    }\n  }\n\n  static dataApiKeydownHandler(event) {\n    // If not an UP | DOWN | ESCAPE key => not a dropdown command\n    // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n    const isInput = /input|textarea/i.test(event.target.tagName)\n    const isEscapeEvent = event.key === ESCAPE_KEY\n    const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)\n\n    if (!isUpOrDownEvent && !isEscapeEvent) {\n      return\n    }\n\n    if (isInput && !isEscapeEvent) {\n      return\n    }\n\n    event.preventDefault()\n\n    // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n    const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ?\n      this :\n      (SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0] ||\n        SelectorEngine.next(this, SELECTOR_DATA_TOGGLE)[0] ||\n        SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode))\n\n    const instance = Dropdown.getOrCreateInstance(getToggleButton)\n\n    if (isUpOrDownEvent) {\n      event.stopPropagation()\n      instance.show()\n      instance._selectMenuItem(event)\n      return\n    }\n\n    if (instance._isShown()) { // else is escape and we check if it is shown\n      event.stopPropagation()\n      instance.hide()\n      getToggleButton.focus()\n    }\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n  event.preventDefault()\n  Dropdown.getOrCreateInstance(this).toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown)\n\nexport default Dropdown\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport Config from './config.js'\nimport {\n  execute, executeAfterTransition, getElement, reflow\n} from './index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'backdrop'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`\n\nconst Default = {\n  className: 'modal-backdrop',\n  clickCallback: null,\n  isAnimated: false,\n  isVisible: true, // if false, we use the backdrop helper without adding any element to the dom\n  rootElement: 'body' // give the choice to place backdrop under different elements\n}\n\nconst DefaultType = {\n  className: 'string',\n  clickCallback: '(function|null)',\n  isAnimated: 'boolean',\n  isVisible: 'boolean',\n  rootElement: '(element|string)'\n}\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n  constructor(config) {\n    super()\n    this._config = this._getConfig(config)\n    this._isAppended = false\n    this._element = null\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  show(callback) {\n    if (!this._config.isVisible) {\n      execute(callback)\n      return\n    }\n\n    this._append()\n\n    const element = this._getElement()\n    if (this._config.isAnimated) {\n      reflow(element)\n    }\n\n    element.classList.add(CLASS_NAME_SHOW)\n\n    this._emulateAnimation(() => {\n      execute(callback)\n    })\n  }\n\n  hide(callback) {\n    if (!this._config.isVisible) {\n      execute(callback)\n      return\n    }\n\n    this._getElement().classList.remove(CLASS_NAME_SHOW)\n\n    this._emulateAnimation(() => {\n      this.dispose()\n      execute(callback)\n    })\n  }\n\n  dispose() {\n    if (!this._isAppended) {\n      return\n    }\n\n    EventHandler.off(this._element, EVENT_MOUSEDOWN)\n\n    this._element.remove()\n    this._isAppended = false\n  }\n\n  // Private\n  _getElement() {\n    if (!this._element) {\n      const backdrop = document.createElement('div')\n      backdrop.className = this._config.className\n      if (this._config.isAnimated) {\n        backdrop.classList.add(CLASS_NAME_FADE)\n      }\n\n      this._element = backdrop\n    }\n\n    return this._element\n  }\n\n  _configAfterMerge(config) {\n    // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n    config.rootElement = getElement(config.rootElement)\n    return config\n  }\n\n  _append() {\n    if (this._isAppended) {\n      return\n    }\n\n    const element = this._getElement()\n    this._config.rootElement.append(element)\n\n    EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n      execute(this._config.clickCallback)\n    })\n\n    this._isAppended = true\n  }\n\n  _emulateAnimation(callback) {\n    executeAfterTransition(callback, this._getElement(), this._config.isAnimated)\n  }\n}\n\nexport default Backdrop\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n  autofocus: true,\n  trapElement: null // The element to trap focus inside of\n}\n\nconst DefaultType = {\n  autofocus: 'boolean',\n  trapElement: 'element'\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n  constructor(config) {\n    super()\n    this._config = this._getConfig(config)\n    this._isActive = false\n    this._lastTabNavDirection = null\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  activate() {\n    if (this._isActive) {\n      return\n    }\n\n    if (this._config.autofocus) {\n      this._config.trapElement.focus()\n    }\n\n    EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop\n    EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))\n    EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))\n\n    this._isActive = true\n  }\n\n  deactivate() {\n    if (!this._isActive) {\n      return\n    }\n\n    this._isActive = false\n    EventHandler.off(document, EVENT_KEY)\n  }\n\n  // Private\n  _handleFocusin(event) {\n    const { trapElement } = this._config\n\n    if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n      return\n    }\n\n    const elements = SelectorEngine.focusableChildren(trapElement)\n\n    if (elements.length === 0) {\n      trapElement.focus()\n    } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n      elements[elements.length - 1].focus()\n    } else {\n      elements[0].focus()\n    }\n  }\n\n  _handleKeydown(event) {\n    if (event.key !== TAB_KEY) {\n      return\n    }\n\n    this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD\n  }\n}\n\nexport default FocusTrap\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Manipulator from '../dom/manipulator.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport { isElement } from './index.js'\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\nconst PROPERTY_PADDING = 'padding-right'\nconst PROPERTY_MARGIN = 'margin-right'\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n  constructor() {\n    this._element = document.body\n  }\n\n  // Public\n  getWidth() {\n    // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n    const documentWidth = document.documentElement.clientWidth\n    return Math.abs(window.innerWidth - documentWidth)\n  }\n\n  hide() {\n    const width = this.getWidth()\n    this._disableOverFlow()\n    // give padding to element to balance the hidden scrollbar width\n    this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n    // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n    this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n    this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width)\n  }\n\n  reset() {\n    this._resetElementAttributes(this._element, 'overflow')\n    this._resetElementAttributes(this._element, PROPERTY_PADDING)\n    this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING)\n    this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN)\n  }\n\n  isOverflowing() {\n    return this.getWidth() > 0\n  }\n\n  // Private\n  _disableOverFlow() {\n    this._saveInitialAttribute(this._element, 'overflow')\n    this._element.style.overflow = 'hidden'\n  }\n\n  _setElementAttributes(selector, styleProperty, callback) {\n    const scrollbarWidth = this.getWidth()\n    const manipulationCallBack = element => {\n      if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n        return\n      }\n\n      this._saveInitialAttribute(element, styleProperty)\n      const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty)\n      element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`)\n    }\n\n    this._applyManipulationCallback(selector, manipulationCallBack)\n  }\n\n  _saveInitialAttribute(element, styleProperty) {\n    const actualValue = element.style.getPropertyValue(styleProperty)\n    if (actualValue) {\n      Manipulator.setDataAttribute(element, styleProperty, actualValue)\n    }\n  }\n\n  _resetElementAttributes(selector, styleProperty) {\n    const manipulationCallBack = element => {\n      const value = Manipulator.getDataAttribute(element, styleProperty)\n      // We only want to remove the property if the value is `null`; the value can also be zero\n      if (value === null) {\n        element.style.removeProperty(styleProperty)\n        return\n      }\n\n      Manipulator.removeDataAttribute(element, styleProperty)\n      element.style.setProperty(styleProperty, value)\n    }\n\n    this._applyManipulationCallback(selector, manipulationCallBack)\n  }\n\n  _applyManipulationCallback(selector, callBack) {\n    if (isElement(selector)) {\n      callBack(selector)\n      return\n    }\n\n    for (const sel of SelectorEngine.find(selector, this._element)) {\n      callBack(sel)\n    }\n  }\n}\n\nexport default ScrollBarHelper\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport Backdrop from './util/backdrop.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport FocusTrap from './util/focustrap.js'\nimport {\n  defineJQueryPlugin, isRTL, isVisible, reflow\n} from './util/index.js'\nimport ScrollBarHelper from './util/scrollbar.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'modal'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst ESCAPE_KEY = 'Escape'\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst OPEN_SELECTOR = '.modal.show'\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"modal\"]'\n\nconst Default = {\n  backdrop: true,\n  focus: true,\n  keyboard: true\n}\n\nconst DefaultType = {\n  backdrop: '(boolean|string)',\n  focus: 'boolean',\n  keyboard: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)\n    this._backdrop = this._initializeBackDrop()\n    this._focustrap = this._initializeFocusTrap()\n    this._isShown = false\n    this._isTransitioning = false\n    this._scrollBar = new ScrollBarHelper()\n\n    this._addEventListeners()\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  toggle(relatedTarget) {\n    return this._isShown ? this.hide() : this.show(relatedTarget)\n  }\n\n  show(relatedTarget) {\n    if (this._isShown || this._isTransitioning) {\n      return\n    }\n\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {\n      relatedTarget\n    })\n\n    if (showEvent.defaultPrevented) {\n      return\n    }\n\n    this._isShown = true\n    this._isTransitioning = true\n\n    this._scrollBar.hide()\n\n    document.body.classList.add(CLASS_NAME_OPEN)\n\n    this._adjustDialog()\n\n    this._backdrop.show(() => this._showElement(relatedTarget))\n  }\n\n  hide() {\n    if (!this._isShown || this._isTransitioning) {\n      return\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    this._isShown = false\n    this._isTransitioning = true\n    this._focustrap.deactivate()\n\n    this._element.classList.remove(CLASS_NAME_SHOW)\n\n    this._queueCallback(() => this._hideModal(), this._element, this._isAnimated())\n  }\n\n  dispose() {\n    EventHandler.off(window, EVENT_KEY)\n    EventHandler.off(this._dialog, EVENT_KEY)\n\n    this._backdrop.dispose()\n    this._focustrap.deactivate()\n\n    super.dispose()\n  }\n\n  handleUpdate() {\n    this._adjustDialog()\n  }\n\n  // Private\n  _initializeBackDrop() {\n    return new Backdrop({\n      isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,\n      isAnimated: this._isAnimated()\n    })\n  }\n\n  _initializeFocusTrap() {\n    return new FocusTrap({\n      trapElement: this._element\n    })\n  }\n\n  _showElement(relatedTarget) {\n    // try to append dynamic modal\n    if (!document.body.contains(this._element)) {\n      document.body.append(this._element)\n    }\n\n    this._element.style.display = 'block'\n    this._element.removeAttribute('aria-hidden')\n    this._element.setAttribute('aria-modal', true)\n    this._element.setAttribute('role', 'dialog')\n    this._element.scrollTop = 0\n\n    const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)\n    if (modalBody) {\n      modalBody.scrollTop = 0\n    }\n\n    reflow(this._element)\n\n    this._element.classList.add(CLASS_NAME_SHOW)\n\n    const transitionComplete = () => {\n      if (this._config.focus) {\n        this._focustrap.activate()\n      }\n\n      this._isTransitioning = false\n      EventHandler.trigger(this._element, EVENT_SHOWN, {\n        relatedTarget\n      })\n    }\n\n    this._queueCallback(transitionComplete, this._dialog, this._isAnimated())\n  }\n\n  _addEventListeners() {\n    EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n      if (event.key !== ESCAPE_KEY) {\n        return\n      }\n\n      if (this._config.keyboard) {\n        this.hide()\n        return\n      }\n\n      this._triggerBackdropTransition()\n    })\n\n    EventHandler.on(window, EVENT_RESIZE, () => {\n      if (this._isShown && !this._isTransitioning) {\n        this._adjustDialog()\n      }\n    })\n\n    EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n      // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n      EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n        if (this._element !== event.target || this._element !== event2.target) {\n          return\n        }\n\n        if (this._config.backdrop === 'static') {\n          this._triggerBackdropTransition()\n          return\n        }\n\n        if (this._config.backdrop) {\n          this.hide()\n        }\n      })\n    })\n  }\n\n  _hideModal() {\n    this._element.style.display = 'none'\n    this._element.setAttribute('aria-hidden', true)\n    this._element.removeAttribute('aria-modal')\n    this._element.removeAttribute('role')\n    this._isTransitioning = false\n\n    this._backdrop.hide(() => {\n      document.body.classList.remove(CLASS_NAME_OPEN)\n      this._resetAdjustments()\n      this._scrollBar.reset()\n      EventHandler.trigger(this._element, EVENT_HIDDEN)\n    })\n  }\n\n  _isAnimated() {\n    return this._element.classList.contains(CLASS_NAME_FADE)\n  }\n\n  _triggerBackdropTransition() {\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n    const initialOverflowY = this._element.style.overflowY\n    // return if the following background transition hasn't yet completed\n    if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n      return\n    }\n\n    if (!isModalOverflowing) {\n      this._element.style.overflowY = 'hidden'\n    }\n\n    this._element.classList.add(CLASS_NAME_STATIC)\n    this._queueCallback(() => {\n      this._element.classList.remove(CLASS_NAME_STATIC)\n      this._queueCallback(() => {\n        this._element.style.overflowY = initialOverflowY\n      }, this._dialog)\n    }, this._dialog)\n\n    this._element.focus()\n  }\n\n  /**\n   * The following methods are used to handle overflowing modals\n   */\n\n  _adjustDialog() {\n    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n    const scrollbarWidth = this._scrollBar.getWidth()\n    const isBodyOverflowing = scrollbarWidth > 0\n\n    if (isBodyOverflowing && !isModalOverflowing) {\n      const property = isRTL() ? 'paddingLeft' : 'paddingRight'\n      this._element.style[property] = `${scrollbarWidth}px`\n    }\n\n    if (!isBodyOverflowing && isModalOverflowing) {\n      const property = isRTL() ? 'paddingRight' : 'paddingLeft'\n      this._element.style[property] = `${scrollbarWidth}px`\n    }\n  }\n\n  _resetAdjustments() {\n    this._element.style.paddingLeft = ''\n    this._element.style.paddingRight = ''\n  }\n\n  // Static\n  static jQueryInterface(config, relatedTarget) {\n    return this.each(function () {\n      const data = Modal.getOrCreateInstance(this, config)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (typeof data[config] === 'undefined') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config](relatedTarget)\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n  const target = SelectorEngine.getElementFromSelector(this)\n\n  if (['A', 'AREA'].includes(this.tagName)) {\n    event.preventDefault()\n  }\n\n  EventHandler.one(target, EVENT_SHOW, showEvent => {\n    if (showEvent.defaultPrevented) {\n      // only register focus restorer if modal will actually get shown\n      return\n    }\n\n    EventHandler.one(target, EVENT_HIDDEN, () => {\n      if (isVisible(this)) {\n        this.focus()\n      }\n    })\n  })\n\n  // avoid conflict when clicking modal toggler while another one is open\n  const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n  if (alreadyOpen) {\n    Modal.getInstance(alreadyOpen).hide()\n  }\n\n  const data = Modal.getOrCreateInstance(target)\n\n  data.toggle(this)\n})\n\nenableDismissTrigger(Modal)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal)\n\nexport default Modal\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport Backdrop from './util/backdrop.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport FocusTrap from './util/focustrap.js'\nimport {\n  defineJQueryPlugin,\n  isDisabled,\n  isVisible\n} from './util/index.js'\nimport ScrollBarHelper from './util/scrollbar.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'offcanvas'\nconst DATA_KEY = 'bs.offcanvas'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst ESCAPE_KEY = 'Escape'\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\nconst CLASS_NAME_HIDING = 'hiding'\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop'\nconst OPEN_SELECTOR = '.offcanvas.show'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"offcanvas\"]'\n\nconst Default = {\n  backdrop: true,\n  keyboard: true,\n  scroll: false\n}\n\nconst DefaultType = {\n  backdrop: '(boolean|string)',\n  keyboard: 'boolean',\n  scroll: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    this._isShown = false\n    this._backdrop = this._initializeBackDrop()\n    this._focustrap = this._initializeFocusTrap()\n    this._addEventListeners()\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  toggle(relatedTarget) {\n    return this._isShown ? this.hide() : this.show(relatedTarget)\n  }\n\n  show(relatedTarget) {\n    if (this._isShown) {\n      return\n    }\n\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, { relatedTarget })\n\n    if (showEvent.defaultPrevented) {\n      return\n    }\n\n    this._isShown = true\n    this._backdrop.show()\n\n    if (!this._config.scroll) {\n      new ScrollBarHelper().hide()\n    }\n\n    this._element.setAttribute('aria-modal', true)\n    this._element.setAttribute('role', 'dialog')\n    this._element.classList.add(CLASS_NAME_SHOWING)\n\n    const completeCallBack = () => {\n      if (!this._config.scroll || this._config.backdrop) {\n        this._focustrap.activate()\n      }\n\n      this._element.classList.add(CLASS_NAME_SHOW)\n      this._element.classList.remove(CLASS_NAME_SHOWING)\n      EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget })\n    }\n\n    this._queueCallback(completeCallBack, this._element, true)\n  }\n\n  hide() {\n    if (!this._isShown) {\n      return\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    this._focustrap.deactivate()\n    this._element.blur()\n    this._isShown = false\n    this._element.classList.add(CLASS_NAME_HIDING)\n    this._backdrop.hide()\n\n    const completeCallback = () => {\n      this._element.classList.remove(CLASS_NAME_SHOW, CLASS_NAME_HIDING)\n      this._element.removeAttribute('aria-modal')\n      this._element.removeAttribute('role')\n\n      if (!this._config.scroll) {\n        new ScrollBarHelper().reset()\n      }\n\n      EventHandler.trigger(this._element, EVENT_HIDDEN)\n    }\n\n    this._queueCallback(completeCallback, this._element, true)\n  }\n\n  dispose() {\n    this._backdrop.dispose()\n    this._focustrap.deactivate()\n    super.dispose()\n  }\n\n  // Private\n  _initializeBackDrop() {\n    const clickCallback = () => {\n      if (this._config.backdrop === 'static') {\n        EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n        return\n      }\n\n      this.hide()\n    }\n\n    // 'static' option will be translated to true, and booleans will keep their value\n    const isVisible = Boolean(this._config.backdrop)\n\n    return new Backdrop({\n      className: CLASS_NAME_BACKDROP,\n      isVisible,\n      isAnimated: true,\n      rootElement: this._element.parentNode,\n      clickCallback: isVisible ? clickCallback : null\n    })\n  }\n\n  _initializeFocusTrap() {\n    return new FocusTrap({\n      trapElement: this._element\n    })\n  }\n\n  _addEventListeners() {\n    EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n      if (event.key !== ESCAPE_KEY) {\n        return\n      }\n\n      if (this._config.keyboard) {\n        this.hide()\n        return\n      }\n\n      EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n    })\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Offcanvas.getOrCreateInstance(this, config)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config](this)\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n  const target = SelectorEngine.getElementFromSelector(this)\n\n  if (['A', 'AREA'].includes(this.tagName)) {\n    event.preventDefault()\n  }\n\n  if (isDisabled(this)) {\n    return\n  }\n\n  EventHandler.one(target, EVENT_HIDDEN, () => {\n    // focus on trigger when it is closed\n    if (isVisible(this)) {\n      this.focus()\n    }\n  })\n\n  // avoid conflict when clicking a toggler of an offcanvas, while another is open\n  const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n  if (alreadyOpen && alreadyOpen !== target) {\n    Offcanvas.getInstance(alreadyOpen).hide()\n  }\n\n  const data = Offcanvas.getOrCreateInstance(target)\n  data.toggle(this)\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n  for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n    Offcanvas.getOrCreateInstance(selector).show()\n  }\n})\n\nEventHandler.on(window, EVENT_RESIZE, () => {\n  for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n    if (getComputedStyle(element).position !== 'fixed') {\n      Offcanvas.getOrCreateInstance(element).hide()\n    }\n  }\n})\n\nenableDismissTrigger(Offcanvas)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas)\n\nexport default Offcanvas\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// js-docs-start allow-list\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\nexport const DefaultAllowlist = {\n  // Global attributes allowed on any supplied element below.\n  '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n  a: ['target', 'href', 'title', 'rel'],\n  area: [],\n  b: [],\n  br: [],\n  col: [],\n  code: [],\n  dd: [],\n  div: [],\n  dl: [],\n  dt: [],\n  em: [],\n  hr: [],\n  h1: [],\n  h2: [],\n  h3: [],\n  h4: [],\n  h5: [],\n  h6: [],\n  i: [],\n  img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n  li: [],\n  ol: [],\n  p: [],\n  pre: [],\n  s: [],\n  small: [],\n  span: [],\n  sub: [],\n  sup: [],\n  strong: [],\n  u: [],\n  ul: []\n}\n// js-docs-end allow-list\n\nconst uriAttributes = new Set([\n  'background',\n  'cite',\n  'href',\n  'itemtype',\n  'longdesc',\n  'poster',\n  'src',\n  'xlink:href'\n])\n\n/**\n * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation\n * contexts.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38\n */\nconst SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i\n\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n  const attributeName = attribute.nodeName.toLowerCase()\n\n  if (allowedAttributeList.includes(attributeName)) {\n    if (uriAttributes.has(attributeName)) {\n      return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue))\n    }\n\n    return true\n  }\n\n  // Check if a regular expression validates the attribute.\n  return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)\n    .some(regex => regex.test(attributeName))\n}\n\nexport function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n  if (!unsafeHtml.length) {\n    return unsafeHtml\n  }\n\n  if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n    return sanitizeFunction(unsafeHtml)\n  }\n\n  const domParser = new window.DOMParser()\n  const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n  const elements = [].concat(...createdDocument.body.querySelectorAll('*'))\n\n  for (const element of elements) {\n    const elementName = element.nodeName.toLowerCase()\n\n    if (!Object.keys(allowList).includes(elementName)) {\n      element.remove()\n      continue\n    }\n\n    const attributeList = [].concat(...element.attributes)\n    const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || [])\n\n    for (const attribute of attributeList) {\n      if (!allowedAttribute(attribute, allowedAttributes)) {\n        element.removeAttribute(attribute.nodeName)\n      }\n    }\n  }\n\n  return createdDocument.body.innerHTML\n}\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\nimport { DefaultAllowlist, sanitizeHtml } from './sanitizer.js'\nimport { execute, getElement, isElement } from './index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'TemplateFactory'\n\nconst Default = {\n  allowList: DefaultAllowlist,\n  content: {}, // { selector : text ,  selector2 : text2 , }\n  extraClass: '',\n  html: false,\n  sanitize: true,\n  sanitizeFn: null,\n  template: '<div></div>'\n}\n\nconst DefaultType = {\n  allowList: 'object',\n  content: 'object',\n  extraClass: '(string|function)',\n  html: 'boolean',\n  sanitize: 'boolean',\n  sanitizeFn: '(null|function)',\n  template: 'string'\n}\n\nconst DefaultContentType = {\n  entry: '(string|element|function|null)',\n  selector: '(string|element)'\n}\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n  constructor(config) {\n    super()\n    this._config = this._getConfig(config)\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  getContent() {\n    return Object.values(this._config.content)\n      .map(config => this._resolvePossibleFunction(config))\n      .filter(Boolean)\n  }\n\n  hasContent() {\n    return this.getContent().length > 0\n  }\n\n  changeContent(content) {\n    this._checkContent(content)\n    this._config.content = { ...this._config.content, ...content }\n    return this\n  }\n\n  toHtml() {\n    const templateWrapper = document.createElement('div')\n    templateWrapper.innerHTML = this._maybeSanitize(this._config.template)\n\n    for (const [selector, text] of Object.entries(this._config.content)) {\n      this._setContent(templateWrapper, text, selector)\n    }\n\n    const template = templateWrapper.children[0]\n    const extraClass = this._resolvePossibleFunction(this._config.extraClass)\n\n    if (extraClass) {\n      template.classList.add(...extraClass.split(' '))\n    }\n\n    return template\n  }\n\n  // Private\n  _typeCheckConfig(config) {\n    super._typeCheckConfig(config)\n    this._checkContent(config.content)\n  }\n\n  _checkContent(arg) {\n    for (const [selector, content] of Object.entries(arg)) {\n      super._typeCheckConfig({ selector, entry: content }, DefaultContentType)\n    }\n  }\n\n  _setContent(template, content, selector) {\n    const templateElement = SelectorEngine.findOne(selector, template)\n\n    if (!templateElement) {\n      return\n    }\n\n    content = this._resolvePossibleFunction(content)\n\n    if (!content) {\n      templateElement.remove()\n      return\n    }\n\n    if (isElement(content)) {\n      this._putElementInTemplate(getElement(content), templateElement)\n      return\n    }\n\n    if (this._config.html) {\n      templateElement.innerHTML = this._maybeSanitize(content)\n      return\n    }\n\n    templateElement.textContent = content\n  }\n\n  _maybeSanitize(arg) {\n    return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg\n  }\n\n  _resolvePossibleFunction(arg) {\n    return execute(arg, [undefined, this])\n  }\n\n  _putElementInTemplate(element, templateElement) {\n    if (this._config.html) {\n      templateElement.innerHTML = ''\n      templateElement.append(element)\n      return\n    }\n\n    templateElement.textContent = element.textContent\n  }\n}\n\nexport default TemplateFactory\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport {\n  defineJQueryPlugin, execute, findShadowRoot, getElement, getUID, isRTL, noop\n} from './util/index.js'\nimport { DefaultAllowlist } from './util/sanitizer.js'\nimport TemplateFactory from './util/template-factory.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'tooltip'\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn'])\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_MODAL = 'modal'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`\n\nconst EVENT_MODAL_HIDE = 'hide.bs.modal'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\nconst EVENT_HIDE = 'hide'\nconst EVENT_HIDDEN = 'hidden'\nconst EVENT_SHOW = 'show'\nconst EVENT_SHOWN = 'shown'\nconst EVENT_INSERTED = 'inserted'\nconst EVENT_CLICK = 'click'\nconst EVENT_FOCUSIN = 'focusin'\nconst EVENT_FOCUSOUT = 'focusout'\nconst EVENT_MOUSEENTER = 'mouseenter'\nconst EVENT_MOUSELEAVE = 'mouseleave'\n\nconst AttachmentMap = {\n  AUTO: 'auto',\n  TOP: 'top',\n  RIGHT: isRTL() ? 'left' : 'right',\n  BOTTOM: 'bottom',\n  LEFT: isRTL() ? 'right' : 'left'\n}\n\nconst Default = {\n  allowList: DefaultAllowlist,\n  animation: true,\n  boundary: 'clippingParents',\n  container: false,\n  customClass: '',\n  delay: 0,\n  fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n  html: false,\n  offset: [0, 6],\n  placement: 'top',\n  popperConfig: null,\n  sanitize: true,\n  sanitizeFn: null,\n  selector: false,\n  template: '<div class=\"tooltip\" role=\"tooltip\">' +\n            '<div class=\"tooltip-arrow\"></div>' +\n            '<div class=\"tooltip-inner\"></div>' +\n            '</div>',\n  title: '',\n  trigger: 'hover focus'\n}\n\nconst DefaultType = {\n  allowList: 'object',\n  animation: 'boolean',\n  boundary: '(string|element)',\n  container: '(string|element|boolean)',\n  customClass: '(string|function)',\n  delay: '(number|object)',\n  fallbackPlacements: 'array',\n  html: 'boolean',\n  offset: '(array|string|function)',\n  placement: '(string|function)',\n  popperConfig: '(null|object|function)',\n  sanitize: 'boolean',\n  sanitizeFn: '(null|function)',\n  selector: '(string|boolean)',\n  template: 'string',\n  title: '(string|element|function)',\n  trigger: 'string'\n}\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n  constructor(element, config) {\n    if (typeof Popper === 'undefined') {\n      throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org/docs/v2/)')\n    }\n\n    super(element, config)\n\n    // Private\n    this._isEnabled = true\n    this._timeout = 0\n    this._isHovered = null\n    this._activeTrigger = {}\n    this._popper = null\n    this._templateFactory = null\n    this._newContent = null\n\n    // Protected\n    this.tip = null\n\n    this._setListeners()\n\n    if (!this._config.selector) {\n      this._fixTitle()\n    }\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  enable() {\n    this._isEnabled = true\n  }\n\n  disable() {\n    this._isEnabled = false\n  }\n\n  toggleEnabled() {\n    this._isEnabled = !this._isEnabled\n  }\n\n  toggle() {\n    if (!this._isEnabled) {\n      return\n    }\n\n    if (this._isShown()) {\n      this._leave()\n      return\n    }\n\n    this._enter()\n  }\n\n  dispose() {\n    clearTimeout(this._timeout)\n\n    EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n\n    if (this._element.getAttribute('data-bs-original-title')) {\n      this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'))\n    }\n\n    this._disposePopper()\n    super.dispose()\n  }\n\n  show() {\n    if (this._element.style.display === 'none') {\n      throw new Error('Please use show on visible elements')\n    }\n\n    if (!(this._isWithContent() && this._isEnabled)) {\n      return\n    }\n\n    const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW))\n    const shadowRoot = findShadowRoot(this._element)\n    const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element)\n\n    if (showEvent.defaultPrevented || !isInTheDom) {\n      return\n    }\n\n    // TODO: v6 remove this or make it optional\n    this._disposePopper()\n\n    const tip = this._getTipElement()\n\n    this._element.setAttribute('aria-describedby', tip.getAttribute('id'))\n\n    const { container } = this._config\n\n    if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n      container.append(tip)\n      EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED))\n    }\n\n    this._popper = this._createPopper(tip)\n\n    tip.classList.add(CLASS_NAME_SHOW)\n\n    // If this is a touch-enabled device we add extra\n    // empty mouseover listeners to the body's immediate children;\n    // only needed because of broken event delegation on iOS\n    // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n    if ('ontouchstart' in document.documentElement) {\n      for (const element of [].concat(...document.body.children)) {\n        EventHandler.on(element, 'mouseover', noop)\n      }\n    }\n\n    const complete = () => {\n      EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN))\n\n      if (this._isHovered === false) {\n        this._leave()\n      }\n\n      this._isHovered = false\n    }\n\n    this._queueCallback(complete, this.tip, this._isAnimated())\n  }\n\n  hide() {\n    if (!this._isShown()) {\n      return\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE))\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    const tip = this._getTipElement()\n    tip.classList.remove(CLASS_NAME_SHOW)\n\n    // If this is a touch-enabled device we remove the extra\n    // empty mouseover listeners we added for iOS support\n    if ('ontouchstart' in document.documentElement) {\n      for (const element of [].concat(...document.body.children)) {\n        EventHandler.off(element, 'mouseover', noop)\n      }\n    }\n\n    this._activeTrigger[TRIGGER_CLICK] = false\n    this._activeTrigger[TRIGGER_FOCUS] = false\n    this._activeTrigger[TRIGGER_HOVER] = false\n    this._isHovered = null // it is a trick to support manual triggering\n\n    const complete = () => {\n      if (this._isWithActiveTrigger()) {\n        return\n      }\n\n      if (!this._isHovered) {\n        this._disposePopper()\n      }\n\n      this._element.removeAttribute('aria-describedby')\n      EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN))\n    }\n\n    this._queueCallback(complete, this.tip, this._isAnimated())\n  }\n\n  update() {\n    if (this._popper) {\n      this._popper.update()\n    }\n  }\n\n  // Protected\n  _isWithContent() {\n    return Boolean(this._getTitle())\n  }\n\n  _getTipElement() {\n    if (!this.tip) {\n      this.tip = this._createTipElement(this._newContent || this._getContentForTemplate())\n    }\n\n    return this.tip\n  }\n\n  _createTipElement(content) {\n    const tip = this._getTemplateFactory(content).toHtml()\n\n    // TODO: remove this check in v6\n    if (!tip) {\n      return null\n    }\n\n    tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW)\n    // TODO: v6 the following can be achieved with CSS only\n    tip.classList.add(`bs-${this.constructor.NAME}-auto`)\n\n    const tipId = getUID(this.constructor.NAME).toString()\n\n    tip.setAttribute('id', tipId)\n\n    if (this._isAnimated()) {\n      tip.classList.add(CLASS_NAME_FADE)\n    }\n\n    return tip\n  }\n\n  setContent(content) {\n    this._newContent = content\n    if (this._isShown()) {\n      this._disposePopper()\n      this.show()\n    }\n  }\n\n  _getTemplateFactory(content) {\n    if (this._templateFactory) {\n      this._templateFactory.changeContent(content)\n    } else {\n      this._templateFactory = new TemplateFactory({\n        ...this._config,\n        // the `content` var has to be after `this._config`\n        // to override config.content in case of popover\n        content,\n        extraClass: this._resolvePossibleFunction(this._config.customClass)\n      })\n    }\n\n    return this._templateFactory\n  }\n\n  _getContentForTemplate() {\n    return {\n      [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n    }\n  }\n\n  _getTitle() {\n    return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title')\n  }\n\n  // Private\n  _initializeOnDelegatedTarget(event) {\n    return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())\n  }\n\n  _isAnimated() {\n    return this._config.animation || (this.tip && this.tip.classList.contains(CLASS_NAME_FADE))\n  }\n\n  _isShown() {\n    return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW)\n  }\n\n  _createPopper(tip) {\n    const placement = execute(this._config.placement, [this, tip, this._element])\n    const attachment = AttachmentMap[placement.toUpperCase()]\n    return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))\n  }\n\n  _getOffset() {\n    const { offset } = this._config\n\n    if (typeof offset === 'string') {\n      return offset.split(',').map(value => Number.parseInt(value, 10))\n    }\n\n    if (typeof offset === 'function') {\n      return popperData => offset(popperData, this._element)\n    }\n\n    return offset\n  }\n\n  _resolvePossibleFunction(arg) {\n    return execute(arg, [this._element, this._element])\n  }\n\n  _getPopperConfig(attachment) {\n    const defaultBsPopperConfig = {\n      placement: attachment,\n      modifiers: [\n        {\n          name: 'flip',\n          options: {\n            fallbackPlacements: this._config.fallbackPlacements\n          }\n        },\n        {\n          name: 'offset',\n          options: {\n            offset: this._getOffset()\n          }\n        },\n        {\n          name: 'preventOverflow',\n          options: {\n            boundary: this._config.boundary\n          }\n        },\n        {\n          name: 'arrow',\n          options: {\n            element: `.${this.constructor.NAME}-arrow`\n          }\n        },\n        {\n          name: 'preSetPlacement',\n          enabled: true,\n          phase: 'beforeMain',\n          fn: data => {\n            // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n            // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n            this._getTipElement().setAttribute('data-popper-placement', data.state.placement)\n          }\n        }\n      ]\n    }\n\n    return {\n      ...defaultBsPopperConfig,\n      ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])\n    }\n  }\n\n  _setListeners() {\n    const triggers = this._config.trigger.split(' ')\n\n    for (const trigger of triggers) {\n      if (trigger === 'click') {\n        EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {\n          const context = this._initializeOnDelegatedTarget(event)\n          context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK])\n          context.toggle()\n        })\n      } else if (trigger !== TRIGGER_MANUAL) {\n        const eventIn = trigger === TRIGGER_HOVER ?\n          this.constructor.eventName(EVENT_MOUSEENTER) :\n          this.constructor.eventName(EVENT_FOCUSIN)\n        const eventOut = trigger === TRIGGER_HOVER ?\n          this.constructor.eventName(EVENT_MOUSELEAVE) :\n          this.constructor.eventName(EVENT_FOCUSOUT)\n\n        EventHandler.on(this._element, eventIn, this._config.selector, event => {\n          const context = this._initializeOnDelegatedTarget(event)\n          context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true\n          context._enter()\n        })\n        EventHandler.on(this._element, eventOut, this._config.selector, event => {\n          const context = this._initializeOnDelegatedTarget(event)\n          context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =\n            context._element.contains(event.relatedTarget)\n\n          context._leave()\n        })\n      }\n    }\n\n    this._hideModalHandler = () => {\n      if (this._element) {\n        this.hide()\n      }\n    }\n\n    EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n  }\n\n  _fixTitle() {\n    const title = this._element.getAttribute('title')\n\n    if (!title) {\n      return\n    }\n\n    if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n      this._element.setAttribute('aria-label', title)\n    }\n\n    this._element.setAttribute('data-bs-original-title', title) // DO NOT USE IT. Is only for backwards compatibility\n    this._element.removeAttribute('title')\n  }\n\n  _enter() {\n    if (this._isShown() || this._isHovered) {\n      this._isHovered = true\n      return\n    }\n\n    this._isHovered = true\n\n    this._setTimeout(() => {\n      if (this._isHovered) {\n        this.show()\n      }\n    }, this._config.delay.show)\n  }\n\n  _leave() {\n    if (this._isWithActiveTrigger()) {\n      return\n    }\n\n    this._isHovered = false\n\n    this._setTimeout(() => {\n      if (!this._isHovered) {\n        this.hide()\n      }\n    }, this._config.delay.hide)\n  }\n\n  _setTimeout(handler, timeout) {\n    clearTimeout(this._timeout)\n    this._timeout = setTimeout(handler, timeout)\n  }\n\n  _isWithActiveTrigger() {\n    return Object.values(this._activeTrigger).includes(true)\n  }\n\n  _getConfig(config) {\n    const dataAttributes = Manipulator.getDataAttributes(this._element)\n\n    for (const dataAttribute of Object.keys(dataAttributes)) {\n      if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n        delete dataAttributes[dataAttribute]\n      }\n    }\n\n    config = {\n      ...dataAttributes,\n      ...(typeof config === 'object' && config ? config : {})\n    }\n    config = this._mergeConfigObj(config)\n    config = this._configAfterMerge(config)\n    this._typeCheckConfig(config)\n    return config\n  }\n\n  _configAfterMerge(config) {\n    config.container = config.container === false ? document.body : getElement(config.container)\n\n    if (typeof config.delay === 'number') {\n      config.delay = {\n        show: config.delay,\n        hide: config.delay\n      }\n    }\n\n    if (typeof config.title === 'number') {\n      config.title = config.title.toString()\n    }\n\n    if (typeof config.content === 'number') {\n      config.content = config.content.toString()\n    }\n\n    return config\n  }\n\n  _getDelegateConfig() {\n    const config = {}\n\n    for (const [key, value] of Object.entries(this._config)) {\n      if (this.constructor.Default[key] !== value) {\n        config[key] = value\n      }\n    }\n\n    config.selector = false\n    config.trigger = 'manual'\n\n    // In the future can be replaced with:\n    // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n    // `Object.fromEntries(keysWithDifferentValues)`\n    return config\n  }\n\n  _disposePopper() {\n    if (this._popper) {\n      this._popper.destroy()\n      this._popper = null\n    }\n\n    if (this.tip) {\n      this.tip.remove()\n      this.tip = null\n    }\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Tooltip.getOrCreateInstance(this, config)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (typeof data[config] === 'undefined') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config]()\n    })\n  }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip)\n\nexport default Tooltip\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Tooltip from './tooltip.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'popover'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Default = {\n  ...Tooltip.Default,\n  content: '',\n  offset: [0, 8],\n  placement: 'right',\n  template: '<div class=\"popover\" role=\"tooltip\">' +\n    '<div class=\"popover-arrow\"></div>' +\n    '<h3 class=\"popover-header\"></h3>' +\n    '<div class=\"popover-body\"></div>' +\n    '</div>',\n  trigger: 'click'\n}\n\nconst DefaultType = {\n  ...Tooltip.DefaultType,\n  content: '(null|string|element|function)'\n}\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Overrides\n  _isWithContent() {\n    return this._getTitle() || this._getContent()\n  }\n\n  // Private\n  _getContentForTemplate() {\n    return {\n      [SELECTOR_TITLE]: this._getTitle(),\n      [SELECTOR_CONTENT]: this._getContent()\n    }\n  }\n\n  _getContent() {\n    return this._resolvePossibleFunction(this._config.content)\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Popover.getOrCreateInstance(this, config)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (typeof data[config] === 'undefined') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config]()\n    })\n  }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover)\n\nexport default Popover\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport {\n  defineJQueryPlugin, getElement, isDisabled, isVisible\n} from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'scrollspy'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]'\nconst SELECTOR_TARGET_LINKS = '[href]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst Default = {\n  offset: null, // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n  rootMargin: '0px 0px -25%',\n  smoothScroll: false,\n  target: null,\n  threshold: [0.1, 0.5, 1]\n}\n\nconst DefaultType = {\n  offset: '(number|null)', // TODO v6 @deprecated, keep it for backwards compatibility reasons\n  rootMargin: 'string',\n  smoothScroll: 'boolean',\n  target: 'element',\n  threshold: 'array'\n}\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    // this._element is the observablesContainer and config.target the menu links wrapper\n    this._targetLinks = new Map()\n    this._observableSections = new Map()\n    this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element\n    this._activeTarget = null\n    this._observer = null\n    this._previousScrollData = {\n      visibleEntryTop: 0,\n      parentScrollTop: 0\n    }\n    this.refresh() // initialize\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  refresh() {\n    this._initializeTargetsAndObservables()\n    this._maybeEnableSmoothScroll()\n\n    if (this._observer) {\n      this._observer.disconnect()\n    } else {\n      this._observer = this._getNewObserver()\n    }\n\n    for (const section of this._observableSections.values()) {\n      this._observer.observe(section)\n    }\n  }\n\n  dispose() {\n    this._observer.disconnect()\n    super.dispose()\n  }\n\n  // Private\n  _configAfterMerge(config) {\n    // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n    config.target = getElement(config.target) || document.body\n\n    // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n    config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin\n\n    if (typeof config.threshold === 'string') {\n      config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value))\n    }\n\n    return config\n  }\n\n  _maybeEnableSmoothScroll() {\n    if (!this._config.smoothScroll) {\n      return\n    }\n\n    // unregister any previous listeners\n    EventHandler.off(this._config.target, EVENT_CLICK)\n\n    EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n      const observableSection = this._observableSections.get(event.target.hash)\n      if (observableSection) {\n        event.preventDefault()\n        const root = this._rootElement || window\n        const height = observableSection.offsetTop - this._element.offsetTop\n        if (root.scrollTo) {\n          root.scrollTo({ top: height, behavior: 'smooth' })\n          return\n        }\n\n        // Chrome 60 doesn't support `scrollTo`\n        root.scrollTop = height\n      }\n    })\n  }\n\n  _getNewObserver() {\n    const options = {\n      root: this._rootElement,\n      threshold: this._config.threshold,\n      rootMargin: this._config.rootMargin\n    }\n\n    return new IntersectionObserver(entries => this._observerCallback(entries), options)\n  }\n\n  // The logic of selection\n  _observerCallback(entries) {\n    const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`)\n    const activate = entry => {\n      this._previousScrollData.visibleEntryTop = entry.target.offsetTop\n      this._process(targetElement(entry))\n    }\n\n    const parentScrollTop = (this._rootElement || document.documentElement).scrollTop\n    const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop\n    this._previousScrollData.parentScrollTop = parentScrollTop\n\n    for (const entry of entries) {\n      if (!entry.isIntersecting) {\n        this._activeTarget = null\n        this._clearActiveClass(targetElement(entry))\n\n        continue\n      }\n\n      const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop\n      // if we are scrolling down, pick the bigger offsetTop\n      if (userScrollsDown && entryIsLowerThanPrevious) {\n        activate(entry)\n        // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n        if (!parentScrollTop) {\n          return\n        }\n\n        continue\n      }\n\n      // if we are scrolling up, pick the smallest offsetTop\n      if (!userScrollsDown && !entryIsLowerThanPrevious) {\n        activate(entry)\n      }\n    }\n  }\n\n  _initializeTargetsAndObservables() {\n    this._targetLinks = new Map()\n    this._observableSections = new Map()\n\n    const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target)\n\n    for (const anchor of targetLinks) {\n      // ensure that the anchor has an id and is not disabled\n      if (!anchor.hash || isDisabled(anchor)) {\n        continue\n      }\n\n      const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element)\n\n      // ensure that the observableSection exists & is visible\n      if (isVisible(observableSection)) {\n        this._targetLinks.set(decodeURI(anchor.hash), anchor)\n        this._observableSections.set(anchor.hash, observableSection)\n      }\n    }\n  }\n\n  _process(target) {\n    if (this._activeTarget === target) {\n      return\n    }\n\n    this._clearActiveClass(this._config.target)\n    this._activeTarget = target\n    target.classList.add(CLASS_NAME_ACTIVE)\n    this._activateParents(target)\n\n    EventHandler.trigger(this._element, EVENT_ACTIVATE, { relatedTarget: target })\n  }\n\n  _activateParents(target) {\n    // Activate dropdown parents\n    if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n      SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN))\n        .classList.add(CLASS_NAME_ACTIVE)\n      return\n    }\n\n    for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n      // Set triggered links parents as active\n      // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n      for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {\n        item.classList.add(CLASS_NAME_ACTIVE)\n      }\n    }\n  }\n\n  _clearActiveClass(parent) {\n    parent.classList.remove(CLASS_NAME_ACTIVE)\n\n    const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent)\n    for (const node of activeNodes) {\n      node.classList.remove(CLASS_NAME_ACTIVE)\n    }\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = ScrollSpy.getOrCreateInstance(this, config)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config]()\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n  for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {\n    ScrollSpy.getOrCreateInstance(spy)\n  }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(ScrollSpy)\n\nexport default ScrollSpy\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport { defineJQueryPlugin, getNextActiveElement, isDisabled } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'tab'\nconst DATA_KEY = 'bs.tab'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}`\n\nconst ARROW_LEFT_KEY = 'ArrowLeft'\nconst ARROW_RIGHT_KEY = 'ArrowRight'\nconst ARROW_UP_KEY = 'ArrowUp'\nconst ARROW_DOWN_KEY = 'ArrowDown'\nconst HOME_KEY = 'Home'\nconst END_KEY = 'End'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_DROPDOWN = 'dropdown'\n\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\nconst SELECTOR_DROPDOWN_MENU = '.dropdown-menu'\nconst NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`\n\nconst SELECTOR_TAB_PANEL = '.list-group, .nav, [role=\"tablist\"]'\nconst SELECTOR_OUTER = '.nav-item, .list-group-item'\nconst SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role=\"tab\"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"tab\"], [data-bs-toggle=\"pill\"], [data-bs-toggle=\"list\"]' // TODO: could only be `tab` in v6\nconst SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`\n\nconst SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle=\"tab\"], .${CLASS_NAME_ACTIVE}[data-bs-toggle=\"pill\"], .${CLASS_NAME_ACTIVE}[data-bs-toggle=\"list\"]`\n\n/**\n * Class definition\n */\n\nclass Tab extends BaseComponent {\n  constructor(element) {\n    super(element)\n    this._parent = this._element.closest(SELECTOR_TAB_PANEL)\n\n    if (!this._parent) {\n      return\n      // TODO: should throw exception in v6\n      // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)\n    }\n\n    // Set up initial aria attributes\n    this._setInitialAttributes(this._parent, this._getChildren())\n\n    EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))\n  }\n\n  // Getters\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  show() { // Shows this elem and deactivate the active sibling if exists\n    const innerElem = this._element\n    if (this._elemIsActive(innerElem)) {\n      return\n    }\n\n    // Search for active tab on same parent to deactivate it\n    const active = this._getActiveElem()\n\n    const hideEvent = active ?\n      EventHandler.trigger(active, EVENT_HIDE, { relatedTarget: innerElem }) :\n      null\n\n    const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW, { relatedTarget: active })\n\n    if (showEvent.defaultPrevented || (hideEvent && hideEvent.defaultPrevented)) {\n      return\n    }\n\n    this._deactivate(active, innerElem)\n    this._activate(innerElem, active)\n  }\n\n  // Private\n  _activate(element, relatedElem) {\n    if (!element) {\n      return\n    }\n\n    element.classList.add(CLASS_NAME_ACTIVE)\n\n    this._activate(SelectorEngine.getElementFromSelector(element)) // Search and activate/show the proper section\n\n    const complete = () => {\n      if (element.getAttribute('role') !== 'tab') {\n        element.classList.add(CLASS_NAME_SHOW)\n        return\n      }\n\n      element.removeAttribute('tabindex')\n      element.setAttribute('aria-selected', true)\n      this._toggleDropDown(element, true)\n      EventHandler.trigger(element, EVENT_SHOWN, {\n        relatedTarget: relatedElem\n      })\n    }\n\n    this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE))\n  }\n\n  _deactivate(element, relatedElem) {\n    if (!element) {\n      return\n    }\n\n    element.classList.remove(CLASS_NAME_ACTIVE)\n    element.blur()\n\n    this._deactivate(SelectorEngine.getElementFromSelector(element)) // Search and deactivate the shown section too\n\n    const complete = () => {\n      if (element.getAttribute('role') !== 'tab') {\n        element.classList.remove(CLASS_NAME_SHOW)\n        return\n      }\n\n      element.setAttribute('aria-selected', false)\n      element.setAttribute('tabindex', '-1')\n      this._toggleDropDown(element, false)\n      EventHandler.trigger(element, EVENT_HIDDEN, { relatedTarget: relatedElem })\n    }\n\n    this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE))\n  }\n\n  _keydown(event) {\n    if (!([ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key))) {\n      return\n    }\n\n    event.stopPropagation()// stopPropagation/preventDefault both added to support up/down keys without scrolling the page\n    event.preventDefault()\n\n    const children = this._getChildren().filter(element => !isDisabled(element))\n    let nextActiveElement\n\n    if ([HOME_KEY, END_KEY].includes(event.key)) {\n      nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1]\n    } else {\n      const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key)\n      nextActiveElement = getNextActiveElement(children, event.target, isNext, true)\n    }\n\n    if (nextActiveElement) {\n      nextActiveElement.focus({ preventScroll: true })\n      Tab.getOrCreateInstance(nextActiveElement).show()\n    }\n  }\n\n  _getChildren() { // collection of inner elements\n    return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent)\n  }\n\n  _getActiveElem() {\n    return this._getChildren().find(child => this._elemIsActive(child)) || null\n  }\n\n  _setInitialAttributes(parent, children) {\n    this._setAttributeIfNotExists(parent, 'role', 'tablist')\n\n    for (const child of children) {\n      this._setInitialAttributesOnChild(child)\n    }\n  }\n\n  _setInitialAttributesOnChild(child) {\n    child = this._getInnerElement(child)\n    const isActive = this._elemIsActive(child)\n    const outerElem = this._getOuterElement(child)\n    child.setAttribute('aria-selected', isActive)\n\n    if (outerElem !== child) {\n      this._setAttributeIfNotExists(outerElem, 'role', 'presentation')\n    }\n\n    if (!isActive) {\n      child.setAttribute('tabindex', '-1')\n    }\n\n    this._setAttributeIfNotExists(child, 'role', 'tab')\n\n    // set attributes to the related panel too\n    this._setInitialAttributesOnTargetPanel(child)\n  }\n\n  _setInitialAttributesOnTargetPanel(child) {\n    const target = SelectorEngine.getElementFromSelector(child)\n\n    if (!target) {\n      return\n    }\n\n    this._setAttributeIfNotExists(target, 'role', 'tabpanel')\n\n    if (child.id) {\n      this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`)\n    }\n  }\n\n  _toggleDropDown(element, open) {\n    const outerElem = this._getOuterElement(element)\n    if (!outerElem.classList.contains(CLASS_DROPDOWN)) {\n      return\n    }\n\n    const toggle = (selector, className) => {\n      const element = SelectorEngine.findOne(selector, outerElem)\n      if (element) {\n        element.classList.toggle(className, open)\n      }\n    }\n\n    toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE)\n    toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW)\n    outerElem.setAttribute('aria-expanded', open)\n  }\n\n  _setAttributeIfNotExists(element, attribute, value) {\n    if (!element.hasAttribute(attribute)) {\n      element.setAttribute(attribute, value)\n    }\n  }\n\n  _elemIsActive(elem) {\n    return elem.classList.contains(CLASS_NAME_ACTIVE)\n  }\n\n  // Try to get the inner element (usually the .nav-link)\n  _getInnerElement(elem) {\n    return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem)\n  }\n\n  // Try to get the outer element (usually the .nav-item)\n  _getOuterElement(elem) {\n    return elem.closest(SELECTOR_OUTER) || elem\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Tab.getOrCreateInstance(this)\n\n      if (typeof config !== 'string') {\n        return\n      }\n\n      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n        throw new TypeError(`No method named \"${config}\"`)\n      }\n\n      data[config]()\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n  if (['A', 'AREA'].includes(this.tagName)) {\n    event.preventDefault()\n  }\n\n  if (isDisabled(this)) {\n    return\n  }\n\n  Tab.getOrCreateInstance(this).show()\n})\n\n/**\n * Initialize on focus\n */\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n  for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {\n    Tab.getOrCreateInstance(element)\n  }\n})\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tab)\n\nexport default Tab\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport { defineJQueryPlugin, reflow } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'toast'\nconst DATA_KEY = 'bs.toast'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`\nconst EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_FOCUSOUT = `focusout${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_HIDE = 'hide' // @deprecated - kept here only for backwards compatibility\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\n\nconst DefaultType = {\n  animation: 'boolean',\n  autohide: 'boolean',\n  delay: 'number'\n}\n\nconst Default = {\n  animation: true,\n  autohide: true,\n  delay: 5000\n}\n\n/**\n * Class definition\n */\n\nclass Toast extends BaseComponent {\n  constructor(element, config) {\n    super(element, config)\n\n    this._timeout = null\n    this._hasMouseInteraction = false\n    this._hasKeyboardInteraction = false\n    this._setListeners()\n  }\n\n  // Getters\n  static get Default() {\n    return Default\n  }\n\n  static get DefaultType() {\n    return DefaultType\n  }\n\n  static get NAME() {\n    return NAME\n  }\n\n  // Public\n  show() {\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW)\n\n    if (showEvent.defaultPrevented) {\n      return\n    }\n\n    this._clearTimeout()\n\n    if (this._config.animation) {\n      this._element.classList.add(CLASS_NAME_FADE)\n    }\n\n    const complete = () => {\n      this._element.classList.remove(CLASS_NAME_SHOWING)\n      EventHandler.trigger(this._element, EVENT_SHOWN)\n\n      this._maybeScheduleHide()\n    }\n\n    this._element.classList.remove(CLASS_NAME_HIDE) // @deprecated\n    reflow(this._element)\n    this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING)\n\n    this._queueCallback(complete, this._element, this._config.animation)\n  }\n\n  hide() {\n    if (!this.isShown()) {\n      return\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n    if (hideEvent.defaultPrevented) {\n      return\n    }\n\n    const complete = () => {\n      this._element.classList.add(CLASS_NAME_HIDE) // @deprecated\n      this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW)\n      EventHandler.trigger(this._element, EVENT_HIDDEN)\n    }\n\n    this._element.classList.add(CLASS_NAME_SHOWING)\n    this._queueCallback(complete, this._element, this._config.animation)\n  }\n\n  dispose() {\n    this._clearTimeout()\n\n    if (this.isShown()) {\n      this._element.classList.remove(CLASS_NAME_SHOW)\n    }\n\n    super.dispose()\n  }\n\n  isShown() {\n    return this._element.classList.contains(CLASS_NAME_SHOW)\n  }\n\n  // Private\n  _maybeScheduleHide() {\n    if (!this._config.autohide) {\n      return\n    }\n\n    if (this._hasMouseInteraction || this._hasKeyboardInteraction) {\n      return\n    }\n\n    this._timeout = setTimeout(() => {\n      this.hide()\n    }, this._config.delay)\n  }\n\n  _onInteraction(event, isInteracting) {\n    switch (event.type) {\n      case 'mouseover':\n      case 'mouseout': {\n        this._hasMouseInteraction = isInteracting\n        break\n      }\n\n      case 'focusin':\n      case 'focusout': {\n        this._hasKeyboardInteraction = isInteracting\n        break\n      }\n\n      default: {\n        break\n      }\n    }\n\n    if (isInteracting) {\n      this._clearTimeout()\n      return\n    }\n\n    const nextElement = event.relatedTarget\n    if (this._element === nextElement || this._element.contains(nextElement)) {\n      return\n    }\n\n    this._maybeScheduleHide()\n  }\n\n  _setListeners() {\n    EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true))\n    EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false))\n    EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true))\n    EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false))\n  }\n\n  _clearTimeout() {\n    clearTimeout(this._timeout)\n    this._timeout = null\n  }\n\n  // Static\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Toast.getOrCreateInstance(this, config)\n\n      if (typeof config === 'string') {\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`)\n        }\n\n        data[config](this)\n      }\n    })\n  }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Toast)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Toast)\n\nexport default Toast\n", "/**\n * --------------------------------------------------------------------------\n * Bootstrap index.umd.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Alert from './src/alert.js'\nimport Button from './src/button.js'\nimport Carousel from './src/carousel.js'\nimport Collapse from './src/collapse.js'\nimport Dropdown from './src/dropdown.js'\nimport Modal from './src/modal.js'\nimport Offcanvas from './src/offcanvas.js'\nimport Popover from './src/popover.js'\nimport ScrollSpy from './src/scrollspy.js'\nimport Tab from './src/tab.js'\nimport Toast from './src/toast.js'\nimport Tooltip from './src/tooltip.js'\n\nexport default {\n  Alert,\n  Button,\n  Carousel,\n  Collapse,\n  Dropdown,\n  Modal,\n  Offcanvas,\n  Popover,\n  ScrollSpy,\n  Tab,\n  Toast,\n  Tooltip\n}\n", "/*!\n* @erwinstone/bs-select v1.0.2 (https://bs-select.vercel.app/)\n* Copyright 2024 erwinstone\n* Licensed under MIT (https://github.com/erwinstone/bs-select/blob/master/LICENSE)\n*/\n(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Bss = factory());\n})(this, (function () { 'use strict';\n\n\tclass Bss {\n\t  #classWrapper = \"bss-wrapper\";\n\t  #classItem = \"dropdown-item\";\n\t  #classItems = \"bss-items\";\n\t  #classClear = \"bss-clear\";\n\t  #classHeader = \"dropdown-header\";\n\t  #classHidden = \"d-none\";\n\t  #classNoResults = \"bss-no-results\";\n\t  #classTagRemove = \"bss-tag-remove\";\n\t  #target;\n\t  #search;\n\t  #create;\n\t  #clear;\n\t  #maxHeight;\n\t  #labels;\n\t  #autoClose;\n\t  #dropdown;\n\t  #dropdownToggle;\n\t  #searchInput;\n\t  #clearBtn;\n\t  #noResults;\n\t  #isMultiple;\n\t  #isDisabled;\n\t  constructor(selectElement, options) {\n\t    this.#target = selectElement;\n\t    this.#search = options?.search ?? selectElement.dataset.bssSearch !== void 0;\n\t    this.#create = options?.create ?? selectElement.dataset.bssCreate !== void 0;\n\t    this.#clear = options?.clear ?? selectElement.dataset.bssClear !== void 0;\n\t    this.#maxHeight = options?.maxHeight || selectElement.dataset.bssMaxHeight || \"25rem\";\n\t    this.#labels = { placeholder: \"\", search: \"Search\", noResults: \"No results found\", clear: \"Clear selection\", addElement: 'Press Enter to add \"<b>%{value}</b>\"' };\n\t    this.#labels = options?.labels ? { ...this.#labels, ...options.labels } : this.#labels;\n\t    this.#autoClose = (this.#target.dataset.bssAutoClose || options?.autoClose) ?? \"true\";\n\t    this.#createDropdown();\n\t    this.#updateDropdown();\n\t    this.#registerEvents();\n\t  }\n\t  #createDropdown() {\n\t    if (this.#target.nextElementSibling && this.#target.nextElementSibling.classList && this.#target.nextElementSibling.classList.contains(this.#classWrapper)) {\n\t      this.#target.nextElementSibling.remove();\n\t    }\n\t    const template = `\n\t\t<div class=\"dropdown ${this.#classWrapper}\">\n\t\t\t<button type=\"button\" data-bs-toggle=\"dropdown\" data-bs-auto-close=\"${this.#autoClose}\" aria-expanded=\"false\"></button>\n\t\t\t<div class=\"dropdown-menu\" style=\"max-height:${this.#maxHeight}\">\n\t\t\t\t<div class=\"d-flex flex-column\">\n\t\t\t\t\t<div class=\"bss-search-wrapper\">\n\t\t\t\t\t\t<input type=\"text\" class=\"form-control\" placeholder=\"${this.#target.dataset.bssSearchLabel || this.#labels.search}\" onkeydown=\"return event.key !== 'Enter'\">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"${this.#classItems}\"></div>\n\t\t\t\t\t<div class=\"${this.#classNoResults} ${this.#classItem} text-wrap ${this.#classHidden}\">${this.#target.dataset.bssNoResultsLabel || this.#labels.noResults}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<button class=\"btn ${this.#classClear}\" tabindex=\"-1\" type=\"button\" title=\"${this.#target.dataset.bssClearLabel || this.#labels.clear}\">\n\t\t\t\t<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 14 14\" fill=\"none\">\n\t\t\t\t\t<path d=\"M13 1L0.999999 13\" stroke-width=\"2\" stroke=\"currentColor\"></path>\n\t\t\t\t\t<path d=\"M1 1L13 13\" stroke-width=\"2\" stroke=\"currentColor\"></path>\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t</div>\n\t\t`;\n\t    this.#target.insertAdjacentHTML(\"afterend\", template);\n\t    this.#target.style.display = \"none\";\n\t    const dropdown = this.#target.nextElementSibling;\n\t    if (dropdown instanceof HTMLDivElement)\n\t      this.#dropdown = dropdown;\n\t    this.#dropdownToggle = dropdown.querySelector('[data-bs-toggle=\"dropdown\"]');\n\t    this.#searchInput = dropdown.querySelector(\"input\");\n\t    this.#clearBtn = dropdown.querySelector(`.${this.#classClear}`);\n\t    this.#isMultiple = this.#target.multiple;\n\t    this.#isDisabled = this.#target.disabled;\n\t    this.#noResults = dropdown.querySelector(`.${this.#classNoResults}`);\n\t    this.#dropdownToggle.className = this.#target.className;\n\t    this.#dropdownToggle.disabled = this.#isDisabled;\n\t    this.#target.classList.contains(\"form-select-sm\") && this.#searchInput.classList.add(\"form-control-sm\");\n\t    this.#target.classList.contains(\"form-select-lg\") && this.#searchInput.classList.add(\"form-control-lg\");\n\t    if (!this.#clear)\n\t      this.#clearBtn.remove();\n\t    if (!this.#search) {\n\t      this.#searchInput.parentElement.remove();\n\t      this.#noResults.remove();\n\t    }\n\t  }\n\t  #updateDropdown() {\n\t    this.#dropdownToggle.innerHTML = this.#dropdownToggleInner();\n\t    const items = this.#dropdown.querySelector(`.${this.#classItems}`);\n\t    items.innerHTML = \"\";\n\t    this.#itemsInner().forEach((i) => items.appendChild(i));\n\t    if (this.#target.value !== \"\" && this.#hasPlaceholder()) {\n\t      this.#dropdownToggle.setAttribute(\"data-show-clear\", \"true\");\n\t    } else {\n\t      this.#dropdownToggle.removeAttribute(\"data-show-clear\");\n\t    }\n\t    if (!this.#isDisabled) {\n\t      this.#dropdown.querySelectorAll(`.${this.#classTagRemove}`).forEach((i) => {\n\t        i.addEventListener(\"click\", () => {\n\t          this.#dropdownToggle.click();\n\t          this.removeValue(i.getAttribute(\"data-bs-value\"));\n\t        });\n\t      });\n\t    }\n\t    this.#searchInput.value = \"\";\n\t    this.#search && this.#noResults.classList.add(this.#classHidden);\n\t  }\n\t  #registerEvents() {\n\t    this.#dropdownToggle.addEventListener(\"shown.bs.dropdown\", () => {\n\t      if (this.#search) {\n\t        this.#searchInput.focus();\n\t      } else {\n\t        const active = this.#dropdown.querySelector(`.${this.#classItem}.active`);\n\t        if (active && active instanceof HTMLButtonElement)\n\t          active.focus();\n\t      }\n\t    });\n\t    this.#searchInput.addEventListener(\"keyup\", (e) => {\n\t      const value = this.#searchInput.value.trim();\n\t      const items = this.#dropdown.querySelectorAll(`button.${this.#classItem}`);\n\t      let found = 0;\n\t      items.forEach((i) => {\n\t        i.classList.add(this.#classHidden);\n\t        if (i.innerHTML.toLowerCase().indexOf(value.toLowerCase()) > -1) {\n\t          i.classList.remove(this.#classHidden);\n\t          found++;\n\t        }\n\t      });\n\t      this.#dropdown.querySelectorAll(`.${this.#classHeader}`).forEach((i) => {\n\t        i.querySelectorAll(`button:not(.${this.#classHidden})`).length ? i.classList.remove(this.#classHidden) : i.classList.add(this.#classHidden);\n\t      });\n\t      if (found) {\n\t        this.#noResults.classList.add(this.#classHidden);\n\t      } else {\n\t        this.#noResults.classList.remove(this.#classHidden);\n\t        if (this.#create) {\n\t          this.#noResults.innerHTML = (this.#target.dataset.bssAddElement || this.#labels.addElement).replace(\"%{value}\", value);\n\t          if (e.key === \"Enter\") {\n\t            let opt = document.createElement(\"option\");\n\t            opt.value = value;\n\t            opt.selected = true;\n\t            opt.textContent = value;\n\t            this.#target.add(opt);\n\t            this.#dropdownToggle.click();\n\t            this.#change();\n\t          }\n\t        }\n\t      }\n\t    });\n\t    this.#clearBtn.addEventListener(\"click\", () => this.clear());\n\t    this.#target.addEventListener(\"change\", () => this.#updateDropdown());\n\t  }\n\t  enable() {\n\t    this.#isDisabled = false;\n\t    this.#dropdownToggle.disabled = false;\n\t  }\n\t  disable() {\n\t    this.#isDisabled = true;\n\t    this.#dropdownToggle.disabled = true;\n\t  }\n\t  clear() {\n\t    Array.from(this.#target.options).forEach((i) => i.selected = false);\n\t    this.#hasPlaceholder() && (this.#target.value = \"\");\n\t    this.#updateDropdown();\n\t  }\n\t  setValue(value) {\n\t    this.#setSelectedOption(value, true);\n\t    this.#setSelectedOption(\"\", false);\n\t    this.#change();\n\t  }\n\t  removeValue(value) {\n\t    this.#setSelectedOption(value, false);\n\t    this.#change();\n\t  }\n\t  getValue() {\n\t    return this.#isMultiple ? Array.from(this.#target.selectedOptions).map((i) => i.value) : this.#target.value;\n\t  }\n\t  #setSelectedOption(value, selected) {\n\t    Array.from(this.#target.options).forEach((i) => i.value === value && (i.selected = selected));\n\t  }\n\t  #change() {\n\t    this.#target.dispatchEvent(new Event(\"change\"));\n\t  }\n\t  #dropdownToggleInner() {\n\t    this.#target.options;\n\t    const selected = Array.from(this.#target.selectedOptions);\n\t    if (selected.length < 1 && this.#isMultiple && this.#hasPlaceholder()) {\n\t      const opt = document.createElement(\"option\");\n\t      opt.hidden = true;\n\t      opt.textContent = this.#target.dataset.bssPlaceholder || this.#labels.placeholder;\n\t      selected.push(opt);\n\t    }\n\t    return selected.map((i) => {\n\t      return i.hidden ? this.#placeholder(i.innerHTML) : this.#isMultiple ? this.#tag(i) : i.innerHTML;\n\t    }).join(\"\");\n\t  }\n\t  #itemsInner() {\n\t    const items = [];\n\t    this.#target.querySelectorAll(\":scope>*\").forEach((opt) => {\n\t      if (opt instanceof HTMLOptionElement) {\n\t        !opt.hidden && items.push(this.#item(opt));\n\t      }\n\t      if (opt instanceof HTMLOptGroupElement) {\n\t        const header = document.createElement(\"div\");\n\t        header.classList.add(this.#classHeader);\n\t        header.innerHTML = `<span>${opt.label}</span>`;\n\t        opt.querySelectorAll(\"option\").forEach((i) => header.appendChild(this.#item(i)));\n\t        items.push(header);\n\t      }\n\t    });\n\t    return items;\n\t  }\n\t  #placeholder(value) {\n\t    return `<span class=\"bss-placeholder\">${value}</span>`;\n\t  }\n\t  #tag(option) {\n\t    return `<div class=\"bss-tag\"><svg data-bs-value=\"${option.value}\" class=\"${this.#classTagRemove}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M0 0h24v24H0z\" fill=\"none\"></path><path d=\"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z\"></path></svg>\n\t\t${option.innerHTML}</div>`;\n\t  }\n\t  #item(option) {\n\t    let button = document.createElement(\"button\");\n\t    button.type = \"button\";\n\t    button.disabled = option.selected && this.#isMultiple || option.disabled;\n\t    button.innerHTML = option.innerHTML;\n\t    button.classList.add(this.#classItem);\n\t    option.selected && button.classList.add(\"active\");\n\t    button.addEventListener(\"click\", () => this.setValue(option.value));\n\t    return button;\n\t  }\n\t  #hasPlaceholder() {\n\t    return (this.#target.dataset.bssPlaceholder || this.#labels.placeholder) !== \"\";\n\t  }\n\t}\n\n\treturn Bss;\n\n}));\n", "'use strict';\n\n/** @type {import('./type')} */\nmodule.exports = TypeError;\n", "var hasMap = typeof Map === 'function' && Map.prototype;\nvar mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;\nvar mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;\nvar mapForEach = hasMap && Map.prototype.forEach;\nvar hasSet = typeof Set === 'function' && Set.prototype;\nvar setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;\nvar setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;\nvar setForEach = hasSet && Set.prototype.forEach;\nvar hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;\nvar weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;\nvar hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;\nvar weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;\nvar hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;\nvar weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;\nvar booleanValueOf = Boolean.prototype.valueOf;\nvar objectToString = Object.prototype.toString;\nvar functionToString = Function.prototype.toString;\nvar $match = String.prototype.match;\nvar $slice = String.prototype.slice;\nvar $replace = String.prototype.replace;\nvar $toUpperCase = String.prototype.toUpperCase;\nvar $toLowerCase = String.prototype.toLowerCase;\nvar $test = RegExp.prototype.test;\nvar $concat = Array.prototype.concat;\nvar $join = Array.prototype.join;\nvar $arrSlice = Array.prototype.slice;\nvar $floor = Math.floor;\nvar bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;\nvar gOPS = Object.getOwnPropertySymbols;\nvar symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;\nvar hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';\n// ie, `has-tostringtag/shams\nvar toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')\n    ? Symbol.toStringTag\n    : null;\nvar isEnumerable = Object.prototype.propertyIsEnumerable;\n\nvar gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (\n    [].__proto__ === Array.prototype // eslint-disable-line no-proto\n        ? function (O) {\n            return O.__proto__; // eslint-disable-line no-proto\n        }\n        : null\n);\n\nfunction addNumericSeparator(num, str) {\n    if (\n        num === Infinity\n        || num === -Infinity\n        || num !== num\n        || (num && num > -1000 && num < 1000)\n        || $test.call(/e/, str)\n    ) {\n        return str;\n    }\n    var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;\n    if (typeof num === 'number') {\n        var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)\n        if (int !== num) {\n            var intStr = String(int);\n            var dec = $slice.call(str, intStr.length + 1);\n            return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');\n        }\n    }\n    return $replace.call(str, sepRegex, '$&_');\n}\n\nvar utilInspect = require('./util.inspect');\nvar inspectCustom = utilInspect.custom;\nvar inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null;\n\nvar quotes = {\n    __proto__: null,\n    'double': '\"',\n    single: \"'\"\n};\nvar quoteREs = {\n    __proto__: null,\n    'double': /([\"\\\\])/g,\n    single: /(['\\\\])/g\n};\n\nmodule.exports = function inspect_(obj, options, depth, seen) {\n    var opts = options || {};\n\n    if (has(opts, 'quoteStyle') && !has(quotes, opts.quoteStyle)) {\n        throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');\n    }\n    if (\n        has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'\n            ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity\n            : opts.maxStringLength !== null\n        )\n    ) {\n        throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');\n    }\n    var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;\n    if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {\n        throw new TypeError('option \"customInspect\", if provided, must be `true`, `false`, or `\\'symbol\\'`');\n    }\n\n    if (\n        has(opts, 'indent')\n        && opts.indent !== null\n        && opts.indent !== '\\t'\n        && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)\n    ) {\n        throw new TypeError('option \"indent\" must be \"\\\\t\", an integer > 0, or `null`');\n    }\n    if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {\n        throw new TypeError('option \"numericSeparator\", if provided, must be `true` or `false`');\n    }\n    var numericSeparator = opts.numericSeparator;\n\n    if (typeof obj === 'undefined') {\n        return 'undefined';\n    }\n    if (obj === null) {\n        return 'null';\n    }\n    if (typeof obj === 'boolean') {\n        return obj ? 'true' : 'false';\n    }\n\n    if (typeof obj === 'string') {\n        return inspectString(obj, opts);\n    }\n    if (typeof obj === 'number') {\n        if (obj === 0) {\n            return Infinity / obj > 0 ? '0' : '-0';\n        }\n        var str = String(obj);\n        return numericSeparator ? addNumericSeparator(obj, str) : str;\n    }\n    if (typeof obj === 'bigint') {\n        var bigIntStr = String(obj) + 'n';\n        return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;\n    }\n\n    var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;\n    if (typeof depth === 'undefined') { depth = 0; }\n    if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {\n        return isArray(obj) ? '[Array]' : '[Object]';\n    }\n\n    var indent = getIndent(opts, depth);\n\n    if (typeof seen === 'undefined') {\n        seen = [];\n    } else if (indexOf(seen, obj) >= 0) {\n        return '[Circular]';\n    }\n\n    function inspect(value, from, noIndent) {\n        if (from) {\n            seen = $arrSlice.call(seen);\n            seen.push(from);\n        }\n        if (noIndent) {\n            var newOpts = {\n                depth: opts.depth\n            };\n            if (has(opts, 'quoteStyle')) {\n                newOpts.quoteStyle = opts.quoteStyle;\n            }\n            return inspect_(value, newOpts, depth + 1, seen);\n        }\n        return inspect_(value, opts, depth + 1, seen);\n    }\n\n    if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable\n        var name = nameOf(obj);\n        var keys = arrObjKeys(obj, inspect);\n        return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');\n    }\n    if (isSymbol(obj)) {\n        var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\\(.*\\))_[^)]*$/, '$1') : symToString.call(obj);\n        return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;\n    }\n    if (isElement(obj)) {\n        var s = '<' + $toLowerCase.call(String(obj.nodeName));\n        var attrs = obj.attributes || [];\n        for (var i = 0; i < attrs.length; i++) {\n            s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);\n        }\n        s += '>';\n        if (obj.childNodes && obj.childNodes.length) { s += '...'; }\n        s += '</' + $toLowerCase.call(String(obj.nodeName)) + '>';\n        return s;\n    }\n    if (isArray(obj)) {\n        if (obj.length === 0) { return '[]'; }\n        var xs = arrObjKeys(obj, inspect);\n        if (indent && !singleLineValues(xs)) {\n            return '[' + indentedJoin(xs, indent) + ']';\n        }\n        return '[ ' + $join.call(xs, ', ') + ' ]';\n    }\n    if (isError(obj)) {\n        var parts = arrObjKeys(obj, inspect);\n        if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) {\n            return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';\n        }\n        if (parts.length === 0) { return '[' + String(obj) + ']'; }\n        return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';\n    }\n    if (typeof obj === 'object' && customInspect) {\n        if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) {\n            return utilInspect(obj, { depth: maxDepth - depth });\n        } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {\n            return obj.inspect();\n        }\n    }\n    if (isMap(obj)) {\n        var mapParts = [];\n        if (mapForEach) {\n            mapForEach.call(obj, function (value, key) {\n                mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));\n            });\n        }\n        return collectionOf('Map', mapSize.call(obj), mapParts, indent);\n    }\n    if (isSet(obj)) {\n        var setParts = [];\n        if (setForEach) {\n            setForEach.call(obj, function (value) {\n                setParts.push(inspect(value, obj));\n            });\n        }\n        return collectionOf('Set', setSize.call(obj), setParts, indent);\n    }\n    if (isWeakMap(obj)) {\n        return weakCollectionOf('WeakMap');\n    }\n    if (isWeakSet(obj)) {\n        return weakCollectionOf('WeakSet');\n    }\n    if (isWeakRef(obj)) {\n        return weakCollectionOf('WeakRef');\n    }\n    if (isNumber(obj)) {\n        return markBoxed(inspect(Number(obj)));\n    }\n    if (isBigInt(obj)) {\n        return markBoxed(inspect(bigIntValueOf.call(obj)));\n    }\n    if (isBoolean(obj)) {\n        return markBoxed(booleanValueOf.call(obj));\n    }\n    if (isString(obj)) {\n        return markBoxed(inspect(String(obj)));\n    }\n    // note: in IE 8, sometimes `global !== window` but both are the prototypes of each other\n    /* eslint-env browser */\n    if (typeof window !== 'undefined' && obj === window) {\n        return '{ [object Window] }';\n    }\n    if (\n        (typeof globalThis !== 'undefined' && obj === globalThis)\n        || (typeof global !== 'undefined' && obj === global)\n    ) {\n        return '{ [object globalThis] }';\n    }\n    if (!isDate(obj) && !isRegExp(obj)) {\n        var ys = arrObjKeys(obj, inspect);\n        var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;\n        var protoTag = obj instanceof Object ? '' : 'null prototype';\n        var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';\n        var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';\n        var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');\n        if (ys.length === 0) { return tag + '{}'; }\n        if (indent) {\n            return tag + '{' + indentedJoin(ys, indent) + '}';\n        }\n        return tag + '{ ' + $join.call(ys, ', ') + ' }';\n    }\n    return String(obj);\n};\n\nfunction wrapQuotes(s, defaultStyle, opts) {\n    var style = opts.quoteStyle || defaultStyle;\n    var quoteChar = quotes[style];\n    return quoteChar + s + quoteChar;\n}\n\nfunction quote(s) {\n    return $replace.call(String(s), /\"/g, '&quot;');\n}\n\nfunction canTrustToString(obj) {\n    return !toStringTag || !(typeof obj === 'object' && (toStringTag in obj || typeof obj[toStringTag] !== 'undefined'));\n}\nfunction isArray(obj) { return toStr(obj) === '[object Array]' && canTrustToString(obj); }\nfunction isDate(obj) { return toStr(obj) === '[object Date]' && canTrustToString(obj); }\nfunction isRegExp(obj) { return toStr(obj) === '[object RegExp]' && canTrustToString(obj); }\nfunction isError(obj) { return toStr(obj) === '[object Error]' && canTrustToString(obj); }\nfunction isString(obj) { return toStr(obj) === '[object String]' && canTrustToString(obj); }\nfunction isNumber(obj) { return toStr(obj) === '[object Number]' && canTrustToString(obj); }\nfunction isBoolean(obj) { return toStr(obj) === '[object Boolean]' && canTrustToString(obj); }\n\n// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives\nfunction isSymbol(obj) {\n    if (hasShammedSymbols) {\n        return obj && typeof obj === 'object' && obj instanceof Symbol;\n    }\n    if (typeof obj === 'symbol') {\n        return true;\n    }\n    if (!obj || typeof obj !== 'object' || !symToString) {\n        return false;\n    }\n    try {\n        symToString.call(obj);\n        return true;\n    } catch (e) {}\n    return false;\n}\n\nfunction isBigInt(obj) {\n    if (!obj || typeof obj !== 'object' || !bigIntValueOf) {\n        return false;\n    }\n    try {\n        bigIntValueOf.call(obj);\n        return true;\n    } catch (e) {}\n    return false;\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };\nfunction has(obj, key) {\n    return hasOwn.call(obj, key);\n}\n\nfunction toStr(obj) {\n    return objectToString.call(obj);\n}\n\nfunction nameOf(f) {\n    if (f.name) { return f.name; }\n    var m = $match.call(functionToString.call(f), /^function\\s*([\\w$]+)/);\n    if (m) { return m[1]; }\n    return null;\n}\n\nfunction indexOf(xs, x) {\n    if (xs.indexOf) { return xs.indexOf(x); }\n    for (var i = 0, l = xs.length; i < l; i++) {\n        if (xs[i] === x) { return i; }\n    }\n    return -1;\n}\n\nfunction isMap(x) {\n    if (!mapSize || !x || typeof x !== 'object') {\n        return false;\n    }\n    try {\n        mapSize.call(x);\n        try {\n            setSize.call(x);\n        } catch (s) {\n            return true;\n        }\n        return x instanceof Map; // core-js workaround, pre-v2.5.0\n    } catch (e) {}\n    return false;\n}\n\nfunction isWeakMap(x) {\n    if (!weakMapHas || !x || typeof x !== 'object') {\n        return false;\n    }\n    try {\n        weakMapHas.call(x, weakMapHas);\n        try {\n            weakSetHas.call(x, weakSetHas);\n        } catch (s) {\n            return true;\n        }\n        return x instanceof WeakMap; // core-js workaround, pre-v2.5.0\n    } catch (e) {}\n    return false;\n}\n\nfunction isWeakRef(x) {\n    if (!weakRefDeref || !x || typeof x !== 'object') {\n        return false;\n    }\n    try {\n        weakRefDeref.call(x);\n        return true;\n    } catch (e) {}\n    return false;\n}\n\nfunction isSet(x) {\n    if (!setSize || !x || typeof x !== 'object') {\n        return false;\n    }\n    try {\n        setSize.call(x);\n        try {\n            mapSize.call(x);\n        } catch (m) {\n            return true;\n        }\n        return x instanceof Set; // core-js workaround, pre-v2.5.0\n    } catch (e) {}\n    return false;\n}\n\nfunction isWeakSet(x) {\n    if (!weakSetHas || !x || typeof x !== 'object') {\n        return false;\n    }\n    try {\n        weakSetHas.call(x, weakSetHas);\n        try {\n            weakMapHas.call(x, weakMapHas);\n        } catch (s) {\n            return true;\n        }\n        return x instanceof WeakSet; // core-js workaround, pre-v2.5.0\n    } catch (e) {}\n    return false;\n}\n\nfunction isElement(x) {\n    if (!x || typeof x !== 'object') { return false; }\n    if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {\n        return true;\n    }\n    return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';\n}\n\nfunction inspectString(str, opts) {\n    if (str.length > opts.maxStringLength) {\n        var remaining = str.length - opts.maxStringLength;\n        var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');\n        return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;\n    }\n    var quoteRE = quoteREs[opts.quoteStyle || 'single'];\n    quoteRE.lastIndex = 0;\n    // eslint-disable-next-line no-control-regex\n    var s = $replace.call($replace.call(str, quoteRE, '\\\\$1'), /[\\x00-\\x1f]/g, lowbyte);\n    return wrapQuotes(s, 'single', opts);\n}\n\nfunction lowbyte(c) {\n    var n = c.charCodeAt(0);\n    var x = {\n        8: 'b',\n        9: 't',\n        10: 'n',\n        12: 'f',\n        13: 'r'\n    }[n];\n    if (x) { return '\\\\' + x; }\n    return '\\\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));\n}\n\nfunction markBoxed(str) {\n    return 'Object(' + str + ')';\n}\n\nfunction weakCollectionOf(type) {\n    return type + ' { ? }';\n}\n\nfunction collectionOf(type, size, entries, indent) {\n    var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');\n    return type + ' (' + size + ') {' + joinedEntries + '}';\n}\n\nfunction singleLineValues(xs) {\n    for (var i = 0; i < xs.length; i++) {\n        if (indexOf(xs[i], '\\n') >= 0) {\n            return false;\n        }\n    }\n    return true;\n}\n\nfunction getIndent(opts, depth) {\n    var baseIndent;\n    if (opts.indent === '\\t') {\n        baseIndent = '\\t';\n    } else if (typeof opts.indent === 'number' && opts.indent > 0) {\n        baseIndent = $join.call(Array(opts.indent + 1), ' ');\n    } else {\n        return null;\n    }\n    return {\n        base: baseIndent,\n        prev: $join.call(Array(depth + 1), baseIndent)\n    };\n}\n\nfunction indentedJoin(xs, indent) {\n    if (xs.length === 0) { return ''; }\n    var lineJoiner = '\\n' + indent.prev + indent.base;\n    return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\\n' + indent.prev;\n}\n\nfunction arrObjKeys(obj, inspect) {\n    var isArr = isArray(obj);\n    var xs = [];\n    if (isArr) {\n        xs.length = obj.length;\n        for (var i = 0; i < obj.length; i++) {\n            xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';\n        }\n    }\n    var syms = typeof gOPS === 'function' ? gOPS(obj) : [];\n    var symMap;\n    if (hasShammedSymbols) {\n        symMap = {};\n        for (var k = 0; k < syms.length; k++) {\n            symMap['$' + syms[k]] = syms[k];\n        }\n    }\n\n    for (var key in obj) { // eslint-disable-line no-restricted-syntax\n        if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n        if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue\n        if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {\n            // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section\n            continue; // eslint-disable-line no-restricted-syntax, no-continue\n        } else if ($test.call(/[^\\w$]/, key)) {\n            xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));\n        } else {\n            xs.push(key + ': ' + inspect(obj[key], obj));\n        }\n    }\n    if (typeof gOPS === 'function') {\n        for (var j = 0; j < syms.length; j++) {\n            if (isEnumerable.call(obj, syms[j])) {\n                xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));\n            }\n        }\n    }\n    return xs;\n}\n", "'use strict';\n\nvar inspect = require('object-inspect');\n\nvar $TypeError = require('es-errors/type');\n\n/*\n* This function traverses the list returning the node corresponding to the given key.\n*\n* That node is also moved to the head of the list, so that if it's accessed again we don't need to traverse the whole list.\n* By doing so, all the recently used nodes can be accessed relatively quickly.\n*/\n/** @type {import('./list.d.ts').listGetNode} */\n// eslint-disable-next-line consistent-return\nvar listGetNode = function (list, key, isDelete) {\n\t/** @type {typeof list | NonNullable<(typeof list)['next']>} */\n\tvar prev = list;\n\t/** @type {(typeof list)['next']} */\n\tvar curr;\n\t// eslint-disable-next-line eqeqeq\n\tfor (; (curr = prev.next) != null; prev = curr) {\n\t\tif (curr.key === key) {\n\t\t\tprev.next = curr.next;\n\t\t\tif (!isDelete) {\n\t\t\t\t// eslint-disable-next-line no-extra-parens\n\t\t\t\tcurr.next = /** @type {NonNullable<typeof list.next>} */ (list.next);\n\t\t\t\tlist.next = curr; // eslint-disable-line no-param-reassign\n\t\t\t}\n\t\t\treturn curr;\n\t\t}\n\t}\n};\n\n/** @type {import('./list.d.ts').listGet} */\nvar listGet = function (objects, key) {\n\tif (!objects) {\n\t\treturn void undefined;\n\t}\n\tvar node = listGetNode(objects, key);\n\treturn node && node.value;\n};\n/** @type {import('./list.d.ts').listSet} */\nvar listSet = function (objects, key, value) {\n\tvar node = listGetNode(objects, key);\n\tif (node) {\n\t\tnode.value = value;\n\t} else {\n\t\t// Prepend the new node to the beginning of the list\n\t\tobjects.next = /** @type {import('./list.d.ts').ListNode<typeof value, typeof key>} */ ({ // eslint-disable-line no-param-reassign, no-extra-parens\n\t\t\tkey: key,\n\t\t\tnext: objects.next,\n\t\t\tvalue: value\n\t\t});\n\t}\n};\n/** @type {import('./list.d.ts').listHas} */\nvar listHas = function (objects, key) {\n\tif (!objects) {\n\t\treturn false;\n\t}\n\treturn !!listGetNode(objects, key);\n};\n/** @type {import('./list.d.ts').listDelete} */\n// eslint-disable-next-line consistent-return\nvar listDelete = function (objects, key) {\n\tif (objects) {\n\t\treturn listGetNode(objects, key, true);\n\t}\n};\n\n/** @type {import('.')} */\nmodule.exports = function getSideChannelList() {\n\t/** @typedef {ReturnType<typeof getSideChannelList>} Channel */\n\t/** @typedef {Parameters<Channel['get']>[0]} K */\n\t/** @typedef {Parameters<Channel['set']>[1]} V */\n\n\t/** @type {import('./list.d.ts').RootNode<V, K> | undefined} */ var $o;\n\n\t/** @type {Channel} */\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\t'delete': function (key) {\n\t\t\tvar deletedNode = listDelete($o, key);\n\t\t\tif (deletedNode && $o && !$o.next) {\n\t\t\t\t$o = void undefined;\n\t\t\t}\n\t\t\treturn !!deletedNode;\n\t\t},\n\t\tget: function (key) {\n\t\t\treturn listGet($o, key);\n\t\t},\n\t\thas: function (key) {\n\t\t\treturn listHas($o, key);\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif (!$o) {\n\t\t\t\t// Initialize the linked list as an empty node, so that we don't have to special-case handling of the first node: we can always refer to it as (previous node).next, instead of something like (list).head\n\t\t\t\t$o = {\n\t\t\t\t\tnext: void undefined\n\t\t\t\t};\n\t\t\t}\n\t\t\t// eslint-disable-next-line no-extra-parens\n\t\t\tlistSet(/** @type {NonNullable<typeof $o>} */ ($o), key, value);\n\t\t}\n\t};\n\treturn channel;\n};\n", "'use strict';\n\n/** @type {import('.')} */\nmodule.exports = Object;\n", "'use strict';\n\n/** @type {import('.')} */\nmodule.exports = Error;\n", "'use strict';\n\n/** @type {import('./eval')} */\nmodule.exports = EvalError;\n", "'use strict';\n\n/** @type {import('./range')} */\nmodule.exports = RangeError;\n", "'use strict';\n\n/** @type {import('./ref')} */\nmodule.exports = ReferenceError;\n", "'use strict';\n\n/** @type {import('./syntax')} */\nmodule.exports = SyntaxError;\n", "'use strict';\n\n/** @type {import('./uri')} */\nmodule.exports = URIError;\n", "'use strict';\n\n/** @type {import('./abs')} */\nmodule.exports = Math.abs;\n", "'use strict';\n\n/** @type {import('./floor')} */\nmodule.exports = Math.floor;\n", "'use strict';\n\n/** @type {import('./max')} */\nmodule.exports = Math.max;\n", "'use strict';\n\n/** @type {import('./min')} */\nmodule.exports = Math.min;\n", "'use strict';\n\n/** @type {import('./pow')} */\nmodule.exports = Math.pow;\n", "'use strict';\n\n/** @type {import('./round')} */\nmodule.exports = Math.round;\n", "'use strict';\n\n/** @type {import('./isNaN')} */\nmodule.exports = Number.isNaN || function isNaN(a) {\n\treturn a !== a;\n};\n", "'use strict';\n\nvar $isNaN = require('./isNaN');\n\n/** @type {import('./sign')} */\nmodule.exports = function sign(number) {\n\tif ($isNaN(number) || number === 0) {\n\t\treturn number;\n\t}\n\treturn number < 0 ? -1 : +1;\n};\n", "'use strict';\n\n/** @type {import('./gOPD')} */\nmodule.exports = Object.getOwnPropertyDescriptor;\n", "'use strict';\n\n/** @type {import('.')} */\nvar $gOPD = require('./gOPD');\n\nif ($gOPD) {\n\ttry {\n\t\t$gOPD([], 'length');\n\t} catch (e) {\n\t\t// IE 8 has a broken gOPD\n\t\t$gOPD = null;\n\t}\n}\n\nmodule.exports = $gOPD;\n", "'use strict';\n\n/** @type {import('.')} */\nvar $defineProperty = Object.defineProperty || false;\nif ($defineProperty) {\n\ttry {\n\t\t$defineProperty({}, 'a', { value: 1 });\n\t} catch (e) {\n\t\t// IE 8 has a broken defineProperty\n\t\t$defineProperty = false;\n\t}\n}\n\nmodule.exports = $defineProperty;\n", "'use strict';\n\n/** @type {import('./shams')} */\n/* eslint complexity: [2, 18], max-statements: [2, 33] */\nmodule.exports = function hasSymbols() {\n\tif (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }\n\tif (typeof Symbol.iterator === 'symbol') { return true; }\n\n\t/** @type {{ [k in symbol]?: unknown }} */\n\tvar obj = {};\n\tvar sym = Symbol('test');\n\tvar symObj = Object(sym);\n\tif (typeof sym === 'string') { return false; }\n\n\tif (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }\n\tif (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }\n\n\t// temp disabled per https://github.com/ljharb/object.assign/issues/17\n\t// if (sym instanceof Symbol) { return false; }\n\t// temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4\n\t// if (!(symObj instanceof Symbol)) { return false; }\n\n\t// if (typeof Symbol.prototype.toString !== 'function') { return false; }\n\t// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }\n\n\tvar symVal = 42;\n\tobj[sym] = symVal;\n\tfor (var _ in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop\n\tif (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }\n\n\tif (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }\n\n\tvar syms = Object.getOwnPropertySymbols(obj);\n\tif (syms.length !== 1 || syms[0] !== sym) { return false; }\n\n\tif (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }\n\n\tif (typeof Object.getOwnPropertyDescriptor === 'function') {\n\t\t// eslint-disable-next-line no-extra-parens\n\t\tvar descriptor = /** @type {PropertyDescriptor} */ (Object.getOwnPropertyDescriptor(obj, sym));\n\t\tif (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }\n\t}\n\n\treturn true;\n};\n", "'use strict';\n\nvar origSymbol = typeof Symbol !== 'undefined' && Symbol;\nvar hasSymbolSham = require('./shams');\n\n/** @type {import('.')} */\nmodule.exports = function hasNativeSymbols() {\n\tif (typeof origSymbol !== 'function') { return false; }\n\tif (typeof Symbol !== 'function') { return false; }\n\tif (typeof origSymbol('foo') !== 'symbol') { return false; }\n\tif (typeof Symbol('bar') !== 'symbol') { return false; }\n\n\treturn hasSymbolSham();\n};\n", "'use strict';\n\n/** @type {import('./Reflect.getPrototypeOf')} */\nmodule.exports = (typeof Reflect !== 'undefined' && Reflect.getPrototypeOf) || null;\n", "'use strict';\n\nvar $Object = require('es-object-atoms');\n\n/** @type {import('./Object.getPrototypeOf')} */\nmodule.exports = $Object.getPrototypeOf || null;\n", "'use strict';\n\n/* eslint no-invalid-this: 1 */\n\nvar ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';\nvar toStr = Object.prototype.toString;\nvar max = Math.max;\nvar funcType = '[object Function]';\n\nvar concatty = function concatty(a, b) {\n    var arr = [];\n\n    for (var i = 0; i < a.length; i += 1) {\n        arr[i] = a[i];\n    }\n    for (var j = 0; j < b.length; j += 1) {\n        arr[j + a.length] = b[j];\n    }\n\n    return arr;\n};\n\nvar slicy = function slicy(arrLike, offset) {\n    var arr = [];\n    for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) {\n        arr[j] = arrLike[i];\n    }\n    return arr;\n};\n\nvar joiny = function (arr, joiner) {\n    var str = '';\n    for (var i = 0; i < arr.length; i += 1) {\n        str += arr[i];\n        if (i + 1 < arr.length) {\n            str += joiner;\n        }\n    }\n    return str;\n};\n\nmodule.exports = function bind(that) {\n    var target = this;\n    if (typeof target !== 'function' || toStr.apply(target) !== funcType) {\n        throw new TypeError(ERROR_MESSAGE + target);\n    }\n    var args = slicy(arguments, 1);\n\n    var bound;\n    var binder = function () {\n        if (this instanceof bound) {\n            var result = target.apply(\n                this,\n                concatty(args, arguments)\n            );\n            if (Object(result) === result) {\n                return result;\n            }\n            return this;\n        }\n        return target.apply(\n            that,\n            concatty(args, arguments)\n        );\n\n    };\n\n    var boundLength = max(0, target.length - args.length);\n    var boundArgs = [];\n    for (var i = 0; i < boundLength; i++) {\n        boundArgs[i] = '$' + i;\n    }\n\n    bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder);\n\n    if (target.prototype) {\n        var Empty = function Empty() {};\n        Empty.prototype = target.prototype;\n        bound.prototype = new Empty();\n        Empty.prototype = null;\n    }\n\n    return bound;\n};\n", "'use strict';\n\nvar implementation = require('./implementation');\n\nmodule.exports = Function.prototype.bind || implementation;\n", "'use strict';\n\n/** @type {import('./functionCall')} */\nmodule.exports = Function.prototype.call;\n", "'use strict';\n\n/** @type {import('./functionApply')} */\nmodule.exports = Function.prototype.apply;\n", "'use strict';\n\n/** @type {import('./reflectApply')} */\nmodule.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply;\n", "'use strict';\n\nvar bind = require('function-bind');\n\nvar $apply = require('./functionApply');\nvar $call = require('./functionCall');\nvar $reflectApply = require('./reflectApply');\n\n/** @type {import('./actualApply')} */\nmodule.exports = $reflectApply || bind.call($call, $apply);\n", "'use strict';\n\nvar bind = require('function-bind');\nvar $TypeError = require('es-errors/type');\n\nvar $call = require('./functionCall');\nvar $actualApply = require('./actualApply');\n\n/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */\nmodule.exports = function callBindBasic(args) {\n\tif (args.length < 1 || typeof args[0] !== 'function') {\n\t\tthrow new $TypeError('a function is required');\n\t}\n\treturn $actualApply(bind, $call, args);\n};\n", "'use strict';\n\nvar callBind = require('call-bind-apply-helpers');\nvar gOPD = require('gopd');\n\nvar hasProtoAccessor;\ntry {\n\t// eslint-disable-next-line no-extra-parens, no-proto\n\thasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */ ([]).__proto__ === Array.prototype;\n} catch (e) {\n\tif (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') {\n\t\tthrow e;\n\t}\n}\n\n// eslint-disable-next-line no-extra-parens\nvar desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__'));\n\nvar $Object = Object;\nvar $getPrototypeOf = $Object.getPrototypeOf;\n\n/** @type {import('./get')} */\nmodule.exports = desc && typeof desc.get === 'function'\n\t? callBind([desc.get])\n\t: typeof $getPrototypeOf === 'function'\n\t\t? /** @type {import('./get')} */ function getDunder(value) {\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\treturn $getPrototypeOf(value == null ? value : $Object(value));\n\t\t}\n\t\t: false;\n", "'use strict';\n\nvar reflectGetProto = require('./Reflect.getPrototypeOf');\nvar originalGetProto = require('./Object.getPrototypeOf');\n\nvar getDunderProto = require('dunder-proto/get');\n\n/** @type {import('.')} */\nmodule.exports = reflectGetProto\n\t? function getProto(O) {\n\t\t// @ts-expect-error TS can't narrow inside a closure, for some reason\n\t\treturn reflectGetProto(O);\n\t}\n\t: originalGetProto\n\t\t? function getProto(O) {\n\t\t\tif (!O || (typeof O !== 'object' && typeof O !== 'function')) {\n\t\t\t\tthrow new TypeError('getProto: not an object');\n\t\t\t}\n\t\t\t// @ts-expect-error TS can't narrow inside a closure, for some reason\n\t\t\treturn originalGetProto(O);\n\t\t}\n\t\t: getDunderProto\n\t\t\t? function getProto(O) {\n\t\t\t\t// @ts-expect-error TS can't narrow inside a closure, for some reason\n\t\t\t\treturn getDunderProto(O);\n\t\t\t}\n\t\t\t: null;\n", "'use strict';\n\nvar call = Function.prototype.call;\nvar $hasOwn = Object.prototype.hasOwnProperty;\nvar bind = require('function-bind');\n\n/** @type {import('.')} */\nmodule.exports = bind.call(call, $hasOwn);\n", "'use strict';\n\nvar undefined;\n\nvar $Object = require('es-object-atoms');\n\nvar $Error = require('es-errors');\nvar $EvalError = require('es-errors/eval');\nvar $RangeError = require('es-errors/range');\nvar $ReferenceError = require('es-errors/ref');\nvar $SyntaxError = require('es-errors/syntax');\nvar $TypeError = require('es-errors/type');\nvar $URIError = require('es-errors/uri');\n\nvar abs = require('math-intrinsics/abs');\nvar floor = require('math-intrinsics/floor');\nvar max = require('math-intrinsics/max');\nvar min = require('math-intrinsics/min');\nvar pow = require('math-intrinsics/pow');\nvar round = require('math-intrinsics/round');\nvar sign = require('math-intrinsics/sign');\n\nvar $Function = Function;\n\n// eslint-disable-next-line consistent-return\nvar getEvalledConstructor = function (expressionSyntax) {\n\ttry {\n\t\treturn $Function('\"use strict\"; return (' + expressionSyntax + ').constructor;')();\n\t} catch (e) {}\n};\n\nvar $gOPD = require('gopd');\nvar $defineProperty = require('es-define-property');\n\nvar throwTypeError = function () {\n\tthrow new $TypeError();\n};\nvar ThrowTypeError = $gOPD\n\t? (function () {\n\t\ttry {\n\t\t\t// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties\n\t\t\targuments.callee; // IE 8 does not throw here\n\t\t\treturn throwTypeError;\n\t\t} catch (calleeThrows) {\n\t\t\ttry {\n\t\t\t\t// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')\n\t\t\t\treturn $gOPD(arguments, 'callee').get;\n\t\t\t} catch (gOPDthrows) {\n\t\t\t\treturn throwTypeError;\n\t\t\t}\n\t\t}\n\t}())\n\t: throwTypeError;\n\nvar hasSymbols = require('has-symbols')();\n\nvar getProto = require('get-proto');\nvar $ObjectGPO = require('get-proto/Object.getPrototypeOf');\nvar $ReflectGPO = require('get-proto/Reflect.getPrototypeOf');\n\nvar $apply = require('call-bind-apply-helpers/functionApply');\nvar $call = require('call-bind-apply-helpers/functionCall');\n\nvar needsEval = {};\n\nvar TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);\n\nvar INTRINSICS = {\n\t__proto__: null,\n\t'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,\n\t'%Array%': Array,\n\t'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,\n\t'%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,\n\t'%AsyncFromSyncIteratorPrototype%': undefined,\n\t'%AsyncFunction%': needsEval,\n\t'%AsyncGenerator%': needsEval,\n\t'%AsyncGeneratorFunction%': needsEval,\n\t'%AsyncIteratorPrototype%': needsEval,\n\t'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,\n\t'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,\n\t'%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,\n\t'%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,\n\t'%Boolean%': Boolean,\n\t'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,\n\t'%Date%': Date,\n\t'%decodeURI%': decodeURI,\n\t'%decodeURIComponent%': decodeURIComponent,\n\t'%encodeURI%': encodeURI,\n\t'%encodeURIComponent%': encodeURIComponent,\n\t'%Error%': $Error,\n\t'%eval%': eval, // eslint-disable-line no-eval\n\t'%EvalError%': $EvalError,\n\t'%Float16Array%': typeof Float16Array === 'undefined' ? undefined : Float16Array,\n\t'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,\n\t'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,\n\t'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,\n\t'%Function%': $Function,\n\t'%GeneratorFunction%': needsEval,\n\t'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,\n\t'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,\n\t'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,\n\t'%isFinite%': isFinite,\n\t'%isNaN%': isNaN,\n\t'%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,\n\t'%JSON%': typeof JSON === 'object' ? JSON : undefined,\n\t'%Map%': typeof Map === 'undefined' ? undefined : Map,\n\t'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),\n\t'%Math%': Math,\n\t'%Number%': Number,\n\t'%Object%': $Object,\n\t'%Object.getOwnPropertyDescriptor%': $gOPD,\n\t'%parseFloat%': parseFloat,\n\t'%parseInt%': parseInt,\n\t'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,\n\t'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,\n\t'%RangeError%': $RangeError,\n\t'%ReferenceError%': $ReferenceError,\n\t'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,\n\t'%RegExp%': RegExp,\n\t'%Set%': typeof Set === 'undefined' ? undefined : Set,\n\t'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),\n\t'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,\n\t'%String%': String,\n\t'%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,\n\t'%Symbol%': hasSymbols ? Symbol : undefined,\n\t'%SyntaxError%': $SyntaxError,\n\t'%ThrowTypeError%': ThrowTypeError,\n\t'%TypedArray%': TypedArray,\n\t'%TypeError%': $TypeError,\n\t'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,\n\t'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,\n\t'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,\n\t'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,\n\t'%URIError%': $URIError,\n\t'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,\n\t'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,\n\t'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet,\n\n\t'%Function.prototype.call%': $call,\n\t'%Function.prototype.apply%': $apply,\n\t'%Object.defineProperty%': $defineProperty,\n\t'%Object.getPrototypeOf%': $ObjectGPO,\n\t'%Math.abs%': abs,\n\t'%Math.floor%': floor,\n\t'%Math.max%': max,\n\t'%Math.min%': min,\n\t'%Math.pow%': pow,\n\t'%Math.round%': round,\n\t'%Math.sign%': sign,\n\t'%Reflect.getPrototypeOf%': $ReflectGPO\n};\n\nif (getProto) {\n\ttry {\n\t\tnull.error; // eslint-disable-line no-unused-expressions\n\t} catch (e) {\n\t\t// https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229\n\t\tvar errorProto = getProto(getProto(e));\n\t\tINTRINSICS['%Error.prototype%'] = errorProto;\n\t}\n}\n\nvar doEval = function doEval(name) {\n\tvar value;\n\tif (name === '%AsyncFunction%') {\n\t\tvalue = getEvalledConstructor('async function () {}');\n\t} else if (name === '%GeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('function* () {}');\n\t} else if (name === '%AsyncGeneratorFunction%') {\n\t\tvalue = getEvalledConstructor('async function* () {}');\n\t} else if (name === '%AsyncGenerator%') {\n\t\tvar fn = doEval('%AsyncGeneratorFunction%');\n\t\tif (fn) {\n\t\t\tvalue = fn.prototype;\n\t\t}\n\t} else if (name === '%AsyncIteratorPrototype%') {\n\t\tvar gen = doEval('%AsyncGenerator%');\n\t\tif (gen && getProto) {\n\t\t\tvalue = getProto(gen.prototype);\n\t\t}\n\t}\n\n\tINTRINSICS[name] = value;\n\n\treturn value;\n};\n\nvar LEGACY_ALIASES = {\n\t__proto__: null,\n\t'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],\n\t'%ArrayPrototype%': ['Array', 'prototype'],\n\t'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],\n\t'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],\n\t'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],\n\t'%ArrayProto_values%': ['Array', 'prototype', 'values'],\n\t'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],\n\t'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],\n\t'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],\n\t'%BooleanPrototype%': ['Boolean', 'prototype'],\n\t'%DataViewPrototype%': ['DataView', 'prototype'],\n\t'%DatePrototype%': ['Date', 'prototype'],\n\t'%ErrorPrototype%': ['Error', 'prototype'],\n\t'%EvalErrorPrototype%': ['EvalError', 'prototype'],\n\t'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],\n\t'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],\n\t'%FunctionPrototype%': ['Function', 'prototype'],\n\t'%Generator%': ['GeneratorFunction', 'prototype'],\n\t'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],\n\t'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],\n\t'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],\n\t'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],\n\t'%JSONParse%': ['JSON', 'parse'],\n\t'%JSONStringify%': ['JSON', 'stringify'],\n\t'%MapPrototype%': ['Map', 'prototype'],\n\t'%NumberPrototype%': ['Number', 'prototype'],\n\t'%ObjectPrototype%': ['Object', 'prototype'],\n\t'%ObjProto_toString%': ['Object', 'prototype', 'toString'],\n\t'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],\n\t'%PromisePrototype%': ['Promise', 'prototype'],\n\t'%PromiseProto_then%': ['Promise', 'prototype', 'then'],\n\t'%Promise_all%': ['Promise', 'all'],\n\t'%Promise_reject%': ['Promise', 'reject'],\n\t'%Promise_resolve%': ['Promise', 'resolve'],\n\t'%RangeErrorPrototype%': ['RangeError', 'prototype'],\n\t'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],\n\t'%RegExpPrototype%': ['RegExp', 'prototype'],\n\t'%SetPrototype%': ['Set', 'prototype'],\n\t'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],\n\t'%StringPrototype%': ['String', 'prototype'],\n\t'%SymbolPrototype%': ['Symbol', 'prototype'],\n\t'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],\n\t'%TypedArrayPrototype%': ['TypedArray', 'prototype'],\n\t'%TypeErrorPrototype%': ['TypeError', 'prototype'],\n\t'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],\n\t'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],\n\t'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],\n\t'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],\n\t'%URIErrorPrototype%': ['URIError', 'prototype'],\n\t'%WeakMapPrototype%': ['WeakMap', 'prototype'],\n\t'%WeakSetPrototype%': ['WeakSet', 'prototype']\n};\n\nvar bind = require('function-bind');\nvar hasOwn = require('hasown');\nvar $concat = bind.call($call, Array.prototype.concat);\nvar $spliceApply = bind.call($apply, Array.prototype.splice);\nvar $replace = bind.call($call, String.prototype.replace);\nvar $strSlice = bind.call($call, String.prototype.slice);\nvar $exec = bind.call($call, RegExp.prototype.exec);\n\n/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */\nvar rePropName = /[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g;\nvar reEscapeChar = /\\\\(\\\\)?/g; /** Used to match backslashes in property paths. */\nvar stringToPath = function stringToPath(string) {\n\tvar first = $strSlice(string, 0, 1);\n\tvar last = $strSlice(string, -1);\n\tif (first === '%' && last !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected closing `%`');\n\t} else if (last === '%' && first !== '%') {\n\t\tthrow new $SyntaxError('invalid intrinsic syntax, expected opening `%`');\n\t}\n\tvar result = [];\n\t$replace(string, rePropName, function (match, number, quote, subString) {\n\t\tresult[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;\n\t});\n\treturn result;\n};\n/* end adaptation */\n\nvar getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {\n\tvar intrinsicName = name;\n\tvar alias;\n\tif (hasOwn(LEGACY_ALIASES, intrinsicName)) {\n\t\talias = LEGACY_ALIASES[intrinsicName];\n\t\tintrinsicName = '%' + alias[0] + '%';\n\t}\n\n\tif (hasOwn(INTRINSICS, intrinsicName)) {\n\t\tvar value = INTRINSICS[intrinsicName];\n\t\tif (value === needsEval) {\n\t\t\tvalue = doEval(intrinsicName);\n\t\t}\n\t\tif (typeof value === 'undefined' && !allowMissing) {\n\t\t\tthrow new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');\n\t\t}\n\n\t\treturn {\n\t\t\talias: alias,\n\t\t\tname: intrinsicName,\n\t\t\tvalue: value\n\t\t};\n\t}\n\n\tthrow new $SyntaxError('intrinsic ' + name + ' does not exist!');\n};\n\nmodule.exports = function GetIntrinsic(name, allowMissing) {\n\tif (typeof name !== 'string' || name.length === 0) {\n\t\tthrow new $TypeError('intrinsic name must be a non-empty string');\n\t}\n\tif (arguments.length > 1 && typeof allowMissing !== 'boolean') {\n\t\tthrow new $TypeError('\"allowMissing\" argument must be a boolean');\n\t}\n\n\tif ($exec(/^%?[^%]*%?$/, name) === null) {\n\t\tthrow new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');\n\t}\n\tvar parts = stringToPath(name);\n\tvar intrinsicBaseName = parts.length > 0 ? parts[0] : '';\n\n\tvar intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);\n\tvar intrinsicRealName = intrinsic.name;\n\tvar value = intrinsic.value;\n\tvar skipFurtherCaching = false;\n\n\tvar alias = intrinsic.alias;\n\tif (alias) {\n\t\tintrinsicBaseName = alias[0];\n\t\t$spliceApply(parts, $concat([0, 1], alias));\n\t}\n\n\tfor (var i = 1, isOwn = true; i < parts.length; i += 1) {\n\t\tvar part = parts[i];\n\t\tvar first = $strSlice(part, 0, 1);\n\t\tvar last = $strSlice(part, -1);\n\t\tif (\n\t\t\t(\n\t\t\t\t(first === '\"' || first === \"'\" || first === '`')\n\t\t\t\t|| (last === '\"' || last === \"'\" || last === '`')\n\t\t\t)\n\t\t\t&& first !== last\n\t\t) {\n\t\t\tthrow new $SyntaxError('property names with quotes must have matching quotes');\n\t\t}\n\t\tif (part === 'constructor' || !isOwn) {\n\t\t\tskipFurtherCaching = true;\n\t\t}\n\n\t\tintrinsicBaseName += '.' + part;\n\t\tintrinsicRealName = '%' + intrinsicBaseName + '%';\n\n\t\tif (hasOwn(INTRINSICS, intrinsicRealName)) {\n\t\t\tvalue = INTRINSICS[intrinsicRealName];\n\t\t} else if (value != null) {\n\t\t\tif (!(part in value)) {\n\t\t\t\tif (!allowMissing) {\n\t\t\t\t\tthrow new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');\n\t\t\t\t}\n\t\t\t\treturn void undefined;\n\t\t\t}\n\t\t\tif ($gOPD && (i + 1) >= parts.length) {\n\t\t\t\tvar desc = $gOPD(value, part);\n\t\t\t\tisOwn = !!desc;\n\n\t\t\t\t// By convention, when a data property is converted to an accessor\n\t\t\t\t// property to emulate a data property that does not suffer from\n\t\t\t\t// the override mistake, that accessor's getter is marked with\n\t\t\t\t// an `originalValue` property. Here, when we detect this, we\n\t\t\t\t// uphold the illusion by pretending to see that original data\n\t\t\t\t// property, i.e., returning the value rather than the getter\n\t\t\t\t// itself.\n\t\t\t\tif (isOwn && 'get' in desc && !('originalValue' in desc.get)) {\n\t\t\t\t\tvalue = desc.get;\n\t\t\t\t} else {\n\t\t\t\t\tvalue = value[part];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisOwn = hasOwn(value, part);\n\t\t\t\tvalue = value[part];\n\t\t\t}\n\n\t\t\tif (isOwn && !skipFurtherCaching) {\n\t\t\t\tINTRINSICS[intrinsicRealName] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn value;\n};\n", "'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\n\nvar callBindBasic = require('call-bind-apply-helpers');\n\n/** @type {(thisArg: string, searchString: string, position?: number) => number} */\nvar $indexOf = callBindBasic([GetIntrinsic('%String.prototype.indexOf%')]);\n\n/** @type {import('.')} */\nmodule.exports = function callBoundIntrinsic(name, allowMissing) {\n\t/* eslint no-extra-parens: 0 */\n\n\tvar intrinsic = /** @type {(this: unknown, ...args: unknown[]) => unknown} */ (GetIntrinsic(name, !!allowMissing));\n\tif (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {\n\t\treturn callBindBasic(/** @type {const} */ ([intrinsic]));\n\t}\n\treturn intrinsic;\n};\n", "'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\nvar callBound = require('call-bound');\nvar inspect = require('object-inspect');\n\nvar $TypeError = require('es-errors/type');\nvar $Map = GetIntrinsic('%Map%', true);\n\n/** @type {<K, V>(thisArg: Map<K, V>, key: K) => V} */\nvar $mapGet = callBound('Map.prototype.get', true);\n/** @type {<K, V>(thisArg: Map<K, V>, key: K, value: V) => void} */\nvar $mapSet = callBound('Map.prototype.set', true);\n/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */\nvar $mapHas = callBound('Map.prototype.has', true);\n/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */\nvar $mapDelete = callBound('Map.prototype.delete', true);\n/** @type {<K, V>(thisArg: Map<K, V>) => number} */\nvar $mapSize = callBound('Map.prototype.size', true);\n\n/** @type {import('.')} */\nmodule.exports = !!$Map && /** @type {Exclude<import('.'), false>} */ function getSideChannelMap() {\n\t/** @typedef {ReturnType<typeof getSideChannelMap>} Channel */\n\t/** @typedef {Parameters<Channel['get']>[0]} K */\n\t/** @typedef {Parameters<Channel['set']>[1]} V */\n\n\t/** @type {Map<K, V> | undefined} */ var $m;\n\n\t/** @type {Channel} */\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t}\n\t\t},\n\t\t'delete': function (key) {\n\t\t\tif ($m) {\n\t\t\t\tvar result = $mapDelete($m, key);\n\t\t\t\tif ($mapSize($m) === 0) {\n\t\t\t\t\t$m = void undefined;\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget: function (key) { // eslint-disable-line consistent-return\n\t\t\tif ($m) {\n\t\t\t\treturn $mapGet($m, key);\n\t\t\t}\n\t\t},\n\t\thas: function (key) {\n\t\t\tif ($m) {\n\t\t\t\treturn $mapHas($m, key);\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif (!$m) {\n\t\t\t\t// @ts-expect-error TS can't handle narrowing a variable inside a closure\n\t\t\t\t$m = new $Map();\n\t\t\t}\n\t\t\t$mapSet($m, key, value);\n\t\t}\n\t};\n\n\t// @ts-expect-error TODO: figure out why TS is erroring here\n\treturn channel;\n};\n", "'use strict';\n\nvar GetIntrinsic = require('get-intrinsic');\nvar callBound = require('call-bound');\nvar inspect = require('object-inspect');\nvar getSideChannelMap = require('side-channel-map');\n\nvar $TypeError = require('es-errors/type');\nvar $WeakMap = GetIntrinsic('%WeakMap%', true);\n\n/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => V} */\nvar $weakMapGet = callBound('WeakMap.prototype.get', true);\n/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K, value: V) => void} */\nvar $weakMapSet = callBound('WeakMap.prototype.set', true);\n/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */\nvar $weakMapHas = callBound('WeakMap.prototype.has', true);\n/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */\nvar $weakMapDelete = callBound('WeakMap.prototype.delete', true);\n\n/** @type {import('.')} */\nmodule.exports = $WeakMap\n\t? /** @type {Exclude<import('.'), false>} */ function getSideChannelWeakMap() {\n\t\t/** @typedef {ReturnType<typeof getSideChannelWeakMap>} Channel */\n\t\t/** @typedef {Parameters<Channel['get']>[0]} K */\n\t\t/** @typedef {Parameters<Channel['set']>[1]} V */\n\n\t\t/** @type {WeakMap<K & object, V> | undefined} */ var $wm;\n\t\t/** @type {Channel | undefined} */ var $m;\n\n\t\t/** @type {Channel} */\n\t\tvar channel = {\n\t\t\tassert: function (key) {\n\t\t\t\tif (!channel.has(key)) {\n\t\t\t\t\tthrow new $TypeError('Side channel does not contain ' + inspect(key));\n\t\t\t\t}\n\t\t\t},\n\t\t\t'delete': function (key) {\n\t\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\t\tif ($wm) {\n\t\t\t\t\t\treturn $weakMapDelete($wm, key);\n\t\t\t\t\t}\n\t\t\t\t} else if (getSideChannelMap) {\n\t\t\t\t\tif ($m) {\n\t\t\t\t\t\treturn $m['delete'](key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tget: function (key) {\n\t\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\t\tif ($wm) {\n\t\t\t\t\t\treturn $weakMapGet($wm, key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn $m && $m.get(key);\n\t\t\t},\n\t\t\thas: function (key) {\n\t\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\t\tif ($wm) {\n\t\t\t\t\t\treturn $weakMapHas($wm, key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn !!$m && $m.has(key);\n\t\t\t},\n\t\t\tset: function (key, value) {\n\t\t\t\tif ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {\n\t\t\t\t\tif (!$wm) {\n\t\t\t\t\t\t$wm = new $WeakMap();\n\t\t\t\t\t}\n\t\t\t\t\t$weakMapSet($wm, key, value);\n\t\t\t\t} else if (getSideChannelMap) {\n\t\t\t\t\tif (!$m) {\n\t\t\t\t\t\t$m = getSideChannelMap();\n\t\t\t\t\t}\n\t\t\t\t\t// eslint-disable-next-line no-extra-parens\n\t\t\t\t\t/** @type {NonNullable<typeof $m>} */ ($m).set(key, value);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// @ts-expect-error TODO: figure out why this is erroring\n\t\treturn channel;\n\t}\n\t: getSideChannelMap;\n", "'use strict';\n\nvar $TypeError = require('es-errors/type');\nvar inspect = require('object-inspect');\nvar getSideChannelList = require('side-channel-list');\nvar getSideChannelMap = require('side-channel-map');\nvar getSideChannelWeakMap = require('side-channel-weakmap');\n\nvar makeChannel = getSideChannelWeakMap || getSideChannelMap || getSideChannelList;\n\n/** @type {import('.')} */\nmodule.exports = function getSideChannel() {\n\t/** @typedef {ReturnType<typeof getSideChannel>} Channel */\n\n\t/** @type {Channel | undefined} */ var $channelData;\n\n\t/** @type {Channel} */\n\tvar channel = {\n\t\tassert: function (key) {\n\t\t\tif (!channel.has(key)) {\n\t\t\t\tvar keyDesc = key && Object(key) === key\n\t\t\t\t\t? 'the given object key'\n\t\t\t\t\t: inspect(key);\n\t\t\t\tthrow new $TypeError('Side channel does not contain ' + keyDesc);\n\t\t\t}\n\t\t},\n\t\t'delete': function (key) {\n\t\t\treturn !!$channelData && $channelData['delete'](key);\n\t\t},\n\t\tget: function (key) {\n\t\t\treturn $channelData && $channelData.get(key);\n\t\t},\n\t\thas: function (key) {\n\t\t\treturn !!$channelData && $channelData.has(key);\n\t\t},\n\t\tset: function (key, value) {\n\t\t\tif (!$channelData) {\n\t\t\t\t$channelData = makeChannel();\n\t\t\t}\n\n\t\t\t$channelData.set(key, value);\n\t\t}\n\t};\n\n\treturn channel;\n};\n", "'use strict';\n\nvar replace = String.prototype.replace;\nvar percentTwenties = /%20/g;\n\nvar Format = {\n    RFC1738: 'RFC1738',\n    RFC3986: 'RFC3986'\n};\n\nmodule.exports = {\n    'default': Format.RFC3986,\n    formatters: {\n        RFC1738: function (value) {\n            return replace.call(value, percentTwenties, '+');\n        },\n        RFC3986: function (value) {\n            return String(value);\n        }\n    },\n    RFC1738: Format.RFC1738,\n    RFC3986: Format.RFC3986\n};\n", "'use strict';\n\nvar formats = require('./formats');\nvar getSideChannel = require('side-channel');\nvar defineProperty = require('es-define-property');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\n// Track objects created from arrayLimit overflow using side-channel\n// Stores the current max numeric index for O(1) lookup\nvar overflowChannel = getSideChannel();\n\nvar markOverflow = function markOverflow(obj, maxIndex) {\n    overflowChannel.set(obj, maxIndex);\n    return obj;\n};\n\nvar isOverflow = function isOverflow(obj) {\n    return overflowChannel.has(obj);\n};\n\nvar getMaxIndex = function getMaxIndex(obj) {\n    return overflowChannel.get(obj);\n};\n\nvar setMaxIndex = function setMaxIndex(obj, maxIndex) {\n    overflowChannel.set(obj, maxIndex);\n};\n\nvar hexTable = (function () {\n    var array = [];\n    for (var i = 0; i < 256; ++i) {\n        array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();\n    }\n\n    return array;\n}());\n\nvar compactQueue = function compactQueue(queue) {\n    while (queue.length > 1) {\n        var item = queue.pop();\n        var obj = item.obj[item.prop];\n\n        if (isArray(obj)) {\n            var compacted = [];\n\n            for (var j = 0; j < obj.length; ++j) {\n                if (typeof obj[j] !== 'undefined') {\n                    compacted[compacted.length] = obj[j];\n                }\n            }\n\n            item.obj[item.prop] = compacted;\n        }\n    }\n};\n\nvar arrayToObject = function arrayToObject(source, options) {\n    var obj = options && options.plainObjects ? { __proto__: null } : {};\n    for (var i = 0; i < source.length; ++i) {\n        if (typeof source[i] !== 'undefined') {\n            obj[i] = source[i];\n        }\n    }\n\n    return obj;\n};\n\nvar setProperty = function setProperty(obj, key, value) {\n    if (key === '__proto__' && defineProperty) {\n        defineProperty(obj, key, {\n            configurable: true,\n            enumerable: true,\n            value: value,\n            writable: true\n        });\n    } else {\n        obj[key] = value;\n    }\n};\n\nvar merge = function merge(target, source, options) {\n    /* eslint no-param-reassign: 0 */\n    if (!source) {\n        return target;\n    }\n\n    if (typeof source !== 'object' && typeof source !== 'function') {\n        if (isArray(target)) {\n            var nextIndex = target.length;\n            if (options && typeof options.arrayLimit === 'number' && nextIndex >= options.arrayLimit) {\n                if (options.throwOnLimitExceeded) {\n                    throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n                }\n                return markOverflow(arrayToObject(target.concat(source), options), nextIndex);\n            }\n            target[nextIndex] = source;\n        } else if (target && typeof target === 'object') {\n            if (isOverflow(target)) {\n                // Add at next numeric index for overflow objects\n                var newIndex = getMaxIndex(target) + 1;\n                target[newIndex] = source;\n                setMaxIndex(target, newIndex);\n            } else if (options && options.strictMerge) {\n                return [target, source];\n            } else if (\n                (options && (options.plainObjects || options.allowPrototypes))\n                || !has.call(Object.prototype, source)\n            ) {\n                target[source] = true;\n            }\n        } else {\n            return [target, source];\n        }\n\n        return target;\n    }\n\n    if (!target || typeof target !== 'object') {\n        if (isOverflow(source)) {\n            // Create new object with target at 0, source values shifted by 1\n            var sourceKeys = Object.keys(source);\n            var result = options && options.plainObjects\n                ? { __proto__: null, 0: target }\n                : { 0: target };\n            for (var m = 0; m < sourceKeys.length; m++) {\n                var oldKey = parseInt(sourceKeys[m], 10);\n                result[oldKey + 1] = source[sourceKeys[m]];\n            }\n            return markOverflow(result, getMaxIndex(source) + 1);\n        }\n        var combined = [target].concat(source);\n        if (options && typeof options.arrayLimit === 'number' && combined.length > options.arrayLimit) {\n            if (options.throwOnLimitExceeded) {\n                throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n            }\n            return markOverflow(arrayToObject(combined, options), combined.length - 1);\n        }\n        return combined;\n    }\n\n    var mergeTarget = target;\n    if (isArray(target) && !isArray(source)) {\n        mergeTarget = arrayToObject(target, options);\n    }\n\n    if (isArray(target) && isArray(source)) {\n        source.forEach(function (item, i) {\n            if (has.call(target, i)) {\n                var targetItem = target[i];\n                if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {\n                    target[i] = merge(targetItem, item, options);\n                } else {\n                    target[target.length] = item;\n                }\n            } else {\n                target[i] = item;\n            }\n        });\n        if (options && typeof options.arrayLimit === 'number' && target.length > options.arrayLimit) {\n            if (options.throwOnLimitExceeded) {\n                throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n            }\n            return markOverflow(arrayToObject(target, options), target.length - 1);\n        }\n        return target;\n    }\n\n    return Object.keys(source).reduce(function (acc, key) {\n        var value = source[key];\n\n        if (has.call(acc, key)) {\n            setProperty(acc, key, merge(acc[key], value, options));\n        } else {\n            setProperty(acc, key, value);\n        }\n\n        if (isOverflow(source) && !isOverflow(acc)) {\n            markOverflow(acc, getMaxIndex(source));\n        }\n        if (isOverflow(acc)) {\n            var keyNum = parseInt(key, 10);\n            if (String(keyNum) === key && keyNum >= 0 && keyNum > getMaxIndex(acc)) {\n                setMaxIndex(acc, keyNum);\n            }\n        }\n\n        return acc;\n    }, mergeTarget);\n};\n\nvar assign = function assignSingleSource(target, source) {\n    return Object.keys(source).reduce(function (acc, key) {\n        setProperty(acc, key, source[key]);\n        return acc;\n    }, target);\n};\n\nvar decode = function (str, defaultDecoder, charset) {\n    var strWithoutPlus = str.replace(/\\+/g, ' ');\n    if (charset === 'iso-8859-1') {\n        // unescape never throws, no try...catch needed:\n        return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);\n    }\n    // utf-8\n    try {\n        return decodeURIComponent(strWithoutPlus);\n    } catch (e) {\n        return strWithoutPlus;\n    }\n};\n\nvar limit = 1024;\n\n/* eslint operator-linebreak: [2, \"before\"] */\n\nvar encode = function encode(str, defaultEncoder, charset, kind, format) {\n    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.\n    // It has been adapted here for stricter adherence to RFC 3986\n    if (str.length === 0) {\n        return str;\n    }\n\n    var string = str;\n    if (typeof str === 'symbol') {\n        string = Symbol.prototype.toString.call(str);\n    } else if (typeof str !== 'string') {\n        string = String(str);\n    }\n\n    if (charset === 'iso-8859-1') {\n        return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {\n            return '%26%23' + parseInt($0.slice(2), 16) + '%3B';\n        });\n    }\n\n    var out = '';\n    for (var j = 0; j < string.length; j += limit) {\n        var segment = string.length >= limit ? string.slice(j, j + limit) : string;\n        if (j + limit < string.length) {\n            var last = segment.charCodeAt(segment.length - 1);\n            if (last >= 0xD800 && last <= 0xDBFF) {\n                segment = segment.slice(0, -1);\n                j -= 1;\n            }\n        }\n        var arr = [];\n\n        for (var i = 0; i < segment.length; ++i) {\n            var c = segment.charCodeAt(i);\n            if (\n                c === 0x2D // -\n                || c === 0x2E // .\n                || c === 0x5F // _\n                || c === 0x7E // ~\n                || (c >= 0x30 && c <= 0x39) // 0-9\n                || (c >= 0x41 && c <= 0x5A) // a-z\n                || (c >= 0x61 && c <= 0x7A) // A-Z\n                || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )\n            ) {\n                arr[arr.length] = segment.charAt(i);\n                continue;\n            }\n\n            if (c < 0x80) {\n                arr[arr.length] = hexTable[c];\n                continue;\n            }\n\n            if (c < 0x800) {\n                arr[arr.length] = hexTable[0xC0 | (c >> 6)]\n                    + hexTable[0x80 | (c & 0x3F)];\n                continue;\n            }\n\n            if (c < 0xD800 || c >= 0xE000) {\n                arr[arr.length] = hexTable[0xE0 | (c >> 12)]\n                    + hexTable[0x80 | ((c >> 6) & 0x3F)]\n                    + hexTable[0x80 | (c & 0x3F)];\n                continue;\n            }\n\n            i += 1;\n            c = 0x10000 + (((c & 0x3FF) << 10) | (segment.charCodeAt(i) & 0x3FF));\n\n            arr[arr.length] = hexTable[0xF0 | (c >> 18)]\n                + hexTable[0x80 | ((c >> 12) & 0x3F)]\n                + hexTable[0x80 | ((c >> 6) & 0x3F)]\n                + hexTable[0x80 | (c & 0x3F)];\n        }\n\n        out += arr.join('');\n    }\n\n    return out;\n};\n\nvar compact = function compact(value) {\n    var queue = [{ obj: { o: value }, prop: 'o' }];\n    var refs = getSideChannel();\n\n    for (var i = 0; i < queue.length; ++i) {\n        var item = queue[i];\n        var obj = item.obj[item.prop];\n\n        var keys = Object.keys(obj);\n        for (var j = 0; j < keys.length; ++j) {\n            var key = keys[j];\n            var val = obj[key];\n            if (typeof val === 'object' && val !== null && !refs.has(val)) {\n                queue[queue.length] = { obj: obj, prop: key };\n                refs.set(val, true);\n            }\n        }\n    }\n\n    compactQueue(queue);\n\n    return value;\n};\n\nvar isRegExp = function isRegExp(obj) {\n    return Object.prototype.toString.call(obj) === '[object RegExp]';\n};\n\nvar isBuffer = function isBuffer(obj) {\n    if (!obj || typeof obj !== 'object') {\n        return false;\n    }\n\n    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));\n};\n\nvar combine = function combine(a, b, arrayLimit, plainObjects, throwOnLimitExceeded) {\n    // If 'a' is already an overflow object, add to it\n    if (isOverflow(a)) {\n        if (throwOnLimitExceeded) {\n            throw new RangeError('Array limit exceeded. Only ' + arrayLimit + ' element' + (arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n        }\n        var newIndex = getMaxIndex(a) + 1;\n        a[newIndex] = b;\n        setMaxIndex(a, newIndex);\n        return a;\n    }\n\n    var result = [].concat(a, b);\n    if (result.length > arrayLimit) {\n        if (throwOnLimitExceeded) {\n            throw new RangeError('Array limit exceeded. Only ' + arrayLimit + ' element' + (arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n        }\n        return markOverflow(arrayToObject(result, { plainObjects: plainObjects }), result.length - 1);\n    }\n    return result;\n};\n\nvar maybeMap = function maybeMap(val, fn) {\n    if (isArray(val)) {\n        var mapped = [];\n        for (var i = 0; i < val.length; i += 1) {\n            mapped[mapped.length] = fn(val[i]);\n        }\n        return mapped;\n    }\n    return fn(val);\n};\n\nmodule.exports = {\n    arrayToObject: arrayToObject,\n    assign: assign,\n    combine: combine,\n    compact: compact,\n    decode: decode,\n    encode: encode,\n    isBuffer: isBuffer,\n    isOverflow: isOverflow,\n    isRegExp: isRegExp,\n    markOverflow: markOverflow,\n    maybeMap: maybeMap,\n    merge: merge\n};\n", "'use strict';\n\nvar getSideChannel = require('side-channel');\nvar utils = require('./utils');\nvar formats = require('./formats');\nvar has = Object.prototype.hasOwnProperty;\n\nvar arrayPrefixGenerators = {\n    brackets: function brackets(prefix) {\n        return prefix + '[]';\n    },\n    comma: 'comma',\n    indices: function indices(prefix, key) {\n        return prefix + '[' + key + ']';\n    },\n    repeat: function repeat(prefix) {\n        return prefix;\n    }\n};\n\nvar isArray = Array.isArray;\nvar push = Array.prototype.push;\nvar pushToArray = function (arr, valueOrArray) {\n    push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);\n};\n\nvar toISO = Date.prototype.toISOString;\n\nvar defaultFormat = formats['default'];\nvar defaults = {\n    addQueryPrefix: false,\n    allowDots: false,\n    allowEmptyArrays: false,\n    arrayFormat: 'indices',\n    charset: 'utf-8',\n    charsetSentinel: false,\n    commaRoundTrip: false,\n    delimiter: '&',\n    encode: true,\n    encodeDotInKeys: false,\n    encoder: utils.encode,\n    encodeValuesOnly: false,\n    filter: void undefined,\n    format: defaultFormat,\n    formatter: formats.formatters[defaultFormat],\n    // deprecated\n    indices: false,\n    serializeDate: function serializeDate(date) {\n        return toISO.call(date);\n    },\n    skipNulls: false,\n    strictNullHandling: false\n};\n\nvar isNonNullishPrimitive = function isNonNullishPrimitive(v) {\n    return typeof v === 'string'\n        || typeof v === 'number'\n        || typeof v === 'boolean'\n        || typeof v === 'symbol'\n        || typeof v === 'bigint';\n};\n\nvar sentinel = {};\n\nvar stringify = function stringify(\n    object,\n    prefix,\n    generateArrayPrefix,\n    commaRoundTrip,\n    allowEmptyArrays,\n    strictNullHandling,\n    skipNulls,\n    encodeDotInKeys,\n    encoder,\n    filter,\n    sort,\n    allowDots,\n    serializeDate,\n    format,\n    formatter,\n    encodeValuesOnly,\n    charset,\n    sideChannel\n) {\n    var obj = object;\n\n    var tmpSc = sideChannel;\n    var step = 0;\n    var findFlag = false;\n    while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {\n        // Where object last appeared in the ref tree\n        var pos = tmpSc.get(object);\n        step += 1;\n        if (typeof pos !== 'undefined') {\n            if (pos === step) {\n                throw new RangeError('Cyclic object value');\n            } else {\n                findFlag = true; // Break while\n            }\n        }\n        if (typeof tmpSc.get(sentinel) === 'undefined') {\n            step = 0;\n        }\n    }\n\n    if (typeof filter === 'function') {\n        obj = filter(prefix, obj);\n    } else if (obj instanceof Date) {\n        obj = serializeDate(obj);\n    } else if (generateArrayPrefix === 'comma' && isArray(obj)) {\n        obj = utils.maybeMap(obj, function (value) {\n            if (value instanceof Date) {\n                return serializeDate(value);\n            }\n            return value;\n        });\n    }\n\n    if (obj === null) {\n        if (strictNullHandling) {\n            return formatter(encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix);\n        }\n\n        obj = '';\n    }\n\n    if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {\n        if (encoder) {\n            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);\n            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];\n        }\n        return [formatter(prefix) + '=' + formatter(String(obj))];\n    }\n\n    var values = [];\n\n    if (typeof obj === 'undefined') {\n        return values;\n    }\n\n    var objKeys;\n    if (generateArrayPrefix === 'comma' && isArray(obj)) {\n        // we need to join elements in\n        if (encodeValuesOnly && encoder) {\n            obj = utils.maybeMap(obj, function (v) {\n                return v == null ? v : encoder(v);\n            });\n        }\n        objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];\n    } else if (isArray(filter)) {\n        objKeys = filter;\n    } else {\n        var keys = Object.keys(obj);\n        objKeys = sort ? keys.sort(sort) : keys;\n    }\n\n    var encodedPrefix = encodeDotInKeys ? String(prefix).replace(/\\./g, '%2E') : String(prefix);\n\n    var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + '[]' : encodedPrefix;\n\n    if (allowEmptyArrays && isArray(obj) && obj.length === 0) {\n        return adjustedPrefix + '[]';\n    }\n\n    for (var j = 0; j < objKeys.length; ++j) {\n        var key = objKeys[j];\n        var value = typeof key === 'object' && key && typeof key.value !== 'undefined'\n            ? key.value\n            : obj[key];\n\n        if (skipNulls && value === null) {\n            continue;\n        }\n\n        var encodedKey = allowDots && encodeDotInKeys ? String(key).replace(/\\./g, '%2E') : String(key);\n        var keyPrefix = isArray(obj)\n            ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, encodedKey) : adjustedPrefix\n            : adjustedPrefix + (allowDots ? '.' + encodedKey : '[' + encodedKey + ']');\n\n        sideChannel.set(object, step);\n        var valueSideChannel = getSideChannel();\n        valueSideChannel.set(sentinel, sideChannel);\n        pushToArray(values, stringify(\n            value,\n            keyPrefix,\n            generateArrayPrefix,\n            commaRoundTrip,\n            allowEmptyArrays,\n            strictNullHandling,\n            skipNulls,\n            encodeDotInKeys,\n            generateArrayPrefix === 'comma' && encodeValuesOnly && isArray(obj) ? null : encoder,\n            filter,\n            sort,\n            allowDots,\n            serializeDate,\n            format,\n            formatter,\n            encodeValuesOnly,\n            charset,\n            valueSideChannel\n        ));\n    }\n\n    return values;\n};\n\nvar normalizeStringifyOptions = function normalizeStringifyOptions(opts) {\n    if (!opts) {\n        return defaults;\n    }\n\n    if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {\n        throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided');\n    }\n\n    if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') {\n        throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided');\n    }\n\n    if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {\n        throw new TypeError('Encoder has to be a function.');\n    }\n\n    var charset = opts.charset || defaults.charset;\n    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {\n        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');\n    }\n\n    var format = formats['default'];\n    if (typeof opts.format !== 'undefined') {\n        if (!has.call(formats.formatters, opts.format)) {\n            throw new TypeError('Unknown format option provided.');\n        }\n        format = opts.format;\n    }\n    var formatter = formats.formatters[format];\n\n    var filter = defaults.filter;\n    if (typeof opts.filter === 'function' || isArray(opts.filter)) {\n        filter = opts.filter;\n    }\n\n    var arrayFormat;\n    if (opts.arrayFormat in arrayPrefixGenerators) {\n        arrayFormat = opts.arrayFormat;\n    } else if ('indices' in opts) {\n        arrayFormat = opts.indices ? 'indices' : 'repeat';\n    } else {\n        arrayFormat = defaults.arrayFormat;\n    }\n\n    if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') {\n        throw new TypeError('`commaRoundTrip` must be a boolean, or absent');\n    }\n\n    var allowDots = typeof opts.allowDots === 'undefined' ? opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;\n\n    return {\n        addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,\n        allowDots: allowDots,\n        allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,\n        arrayFormat: arrayFormat,\n        charset: charset,\n        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,\n        commaRoundTrip: !!opts.commaRoundTrip,\n        delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,\n        encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,\n        encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys,\n        encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,\n        encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,\n        filter: filter,\n        format: format,\n        formatter: formatter,\n        serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,\n        skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,\n        sort: typeof opts.sort === 'function' ? opts.sort : null,\n        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling\n    };\n};\n\nmodule.exports = function (object, opts) {\n    var obj = object;\n    var options = normalizeStringifyOptions(opts);\n\n    var objKeys;\n    var filter;\n\n    if (typeof options.filter === 'function') {\n        filter = options.filter;\n        obj = filter('', obj);\n    } else if (isArray(options.filter)) {\n        filter = options.filter;\n        objKeys = filter;\n    }\n\n    var keys = [];\n\n    if (typeof obj !== 'object' || obj === null) {\n        return '';\n    }\n\n    var generateArrayPrefix = arrayPrefixGenerators[options.arrayFormat];\n    var commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip;\n\n    if (!objKeys) {\n        objKeys = Object.keys(obj);\n    }\n\n    if (options.sort) {\n        objKeys.sort(options.sort);\n    }\n\n    var sideChannel = getSideChannel();\n    for (var i = 0; i < objKeys.length; ++i) {\n        var key = objKeys[i];\n\n        if (typeof key === 'undefined' || key === null) {\n            continue;\n        }\n\n        var value = obj[key];\n\n        if (options.skipNulls && value === null) {\n            continue;\n        }\n        pushToArray(keys, stringify(\n            value,\n            key,\n            generateArrayPrefix,\n            commaRoundTrip,\n            options.allowEmptyArrays,\n            options.strictNullHandling,\n            options.skipNulls,\n            options.encodeDotInKeys,\n            options.encode ? options.encoder : null,\n            options.filter,\n            options.sort,\n            options.allowDots,\n            options.serializeDate,\n            options.format,\n            options.formatter,\n            options.encodeValuesOnly,\n            options.charset,\n            sideChannel\n        ));\n    }\n\n    var joined = keys.join(options.delimiter);\n    var prefix = options.addQueryPrefix === true ? '?' : '';\n\n    if (options.charsetSentinel) {\n        if (options.charset === 'iso-8859-1') {\n            // encodeURIComponent('&#10003;'), the \"numeric entity\" representation of a checkmark\n            prefix += 'utf8=%26%2310003%3B' + options.delimiter;\n        } else {\n            // encodeURIComponent('\u2713')\n            prefix += 'utf8=%E2%9C%93' + options.delimiter;\n        }\n    }\n\n    return joined.length > 0 ? prefix + joined : '';\n};\n", "'use strict';\n\nvar utils = require('./utils');\n\nvar has = Object.prototype.hasOwnProperty;\nvar isArray = Array.isArray;\n\nvar defaults = {\n    allowDots: false,\n    allowEmptyArrays: false,\n    allowPrototypes: false,\n    allowSparse: false,\n    arrayLimit: 20,\n    charset: 'utf-8',\n    charsetSentinel: false,\n    comma: false,\n    decodeDotInKeys: false,\n    decoder: utils.decode,\n    delimiter: '&',\n    depth: 5,\n    duplicates: 'combine',\n    ignoreQueryPrefix: false,\n    interpretNumericEntities: false,\n    parameterLimit: 1000,\n    parseArrays: true,\n    plainObjects: false,\n    strictDepth: false,\n    strictMerge: true,\n    strictNullHandling: false,\n    throwOnLimitExceeded: false\n};\n\nvar interpretNumericEntities = function (str) {\n    return str.replace(/&#(\\d+);/g, function ($0, numberStr) {\n        return String.fromCharCode(parseInt(numberStr, 10));\n    });\n};\n\nvar parseArrayValue = function (val, options, currentArrayLength, isFlatArrayValue) {\n    if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {\n        if (isFlatArrayValue && options.throwOnLimitExceeded) {\n            var commaCount = 0;\n            var commaIndex = val.indexOf(',');\n            while (commaIndex > -1) {\n                commaCount += 1;\n                if (commaCount >= options.arrayLimit) {\n                    throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n                }\n                commaIndex = val.indexOf(',', commaIndex + 1);\n            }\n        }\n        return val.split(',');\n    }\n\n    if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) {\n        throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n    }\n\n    return val;\n};\n\n// This is what browsers will submit when the \u2713 character occurs in an\n// application/x-www-form-urlencoded body and the encoding of the page containing\n// the form is iso-8859-1, or when the submitted form has an accept-charset\n// attribute of iso-8859-1. Presumably also with other charsets that do not contain\n// the \u2713 character, such as us-ascii.\nvar isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')\n\n// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.\nvar charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('\u2713')\n\nvar parseValues = function parseQueryStringValues(str, options) {\n    var obj = { __proto__: null };\n\n    var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\\?/, '') : str;\n    cleanStr = cleanStr.replace(/%5B/gi, '[').replace(/%5D/gi, ']');\n\n    var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;\n    var parts = cleanStr.split(\n        options.delimiter,\n        options.throwOnLimitExceeded && typeof limit !== 'undefined' ? limit + 1 : limit\n    );\n\n    if (options.throwOnLimitExceeded && typeof limit !== 'undefined' && parts.length > limit) {\n        throw new RangeError('Parameter limit exceeded. Only ' + limit + ' parameter' + (limit === 1 ? '' : 's') + ' allowed.');\n    }\n\n    var skipIndex = -1; // Keep track of where the utf8 sentinel was found\n    var i;\n\n    var charset = options.charset;\n    if (options.charsetSentinel) {\n        for (i = 0; i < parts.length; ++i) {\n            if (parts[i].indexOf('utf8=') === 0) {\n                if (parts[i] === charsetSentinel) {\n                    charset = 'utf-8';\n                } else if (parts[i] === isoSentinel) {\n                    charset = 'iso-8859-1';\n                }\n                skipIndex = i;\n                i = parts.length; // The eslint settings do not allow break;\n            }\n        }\n    }\n\n    for (i = 0; i < parts.length; ++i) {\n        if (i === skipIndex) {\n            continue;\n        }\n        var part = parts[i];\n\n        var bracketEqualsPos = part.indexOf(']=');\n        var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;\n\n        var key;\n        var val;\n        if (pos === -1) {\n            key = options.decoder(part, defaults.decoder, charset, 'key');\n            val = options.strictNullHandling ? null : '';\n        } else {\n            key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');\n\n            if (key !== null) {\n                val = utils.maybeMap(\n                    parseArrayValue(\n                        part.slice(pos + 1),\n                        options,\n                        isArray(obj[key]) ? obj[key].length : 0,\n                        part.indexOf('[]=') === -1\n                    ),\n                    function (encodedVal) {\n                        return options.decoder(encodedVal, defaults.decoder, charset, 'value');\n                    }\n                );\n            }\n        }\n\n        if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {\n            val = interpretNumericEntities(String(val));\n        }\n\n        if (part.indexOf('[]=') > -1) {\n            val = isArray(val) ? [val] : val;\n        }\n\n        if (options.comma && isArray(val) && val.length > options.arrayLimit) {\n            val = utils.combine([], val, options.arrayLimit, options.plainObjects, options.throwOnLimitExceeded);\n        }\n\n        if (key !== null) {\n            var existing = has.call(obj, key);\n            if (existing && (options.duplicates === 'combine' || part.indexOf('[]=') > -1)) {\n                obj[key] = utils.combine(\n                    obj[key],\n                    val,\n                    options.arrayLimit,\n                    options.plainObjects,\n                    options.throwOnLimitExceeded\n                );\n            } else if (!existing || options.duplicates === 'last') {\n                obj[key] = val;\n            }\n        }\n    }\n\n    return obj;\n};\n\nvar parseObject = function (chain, val, options, valuesParsed) {\n    var currentArrayLength = 0;\n    if (chain.length > 0 && chain[chain.length - 1] === '[]') {\n        var parentKey = chain.slice(0, -1).join('');\n        currentArrayLength = Array.isArray(val) && val[parentKey] ? val[parentKey].length : 0;\n    }\n\n    var leaf = valuesParsed ? val : parseArrayValue(val, options, currentArrayLength);\n\n    for (var i = chain.length - 1; i >= 0; --i) {\n        var obj;\n        var root = chain[i];\n\n        if (root === '[]' && options.parseArrays) {\n            if (utils.isOverflow(leaf)) {\n                // leaf is already an overflow object, preserve it\n                obj = leaf;\n            } else {\n                obj = options.allowEmptyArrays && (leaf === '' || (options.strictNullHandling && leaf === null))\n                    ? []\n                    : utils.combine(\n                        [],\n                        leaf,\n                        options.arrayLimit,\n                        options.plainObjects,\n                        options.throwOnLimitExceeded\n                    );\n            }\n        } else {\n            obj = options.plainObjects ? { __proto__: null } : {};\n            var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;\n            var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, '.') : cleanRoot;\n            var index = parseInt(decodedRoot, 10);\n            var isValidArrayIndex = !isNaN(index)\n                && root !== decodedRoot\n                && String(index) === decodedRoot\n                && index >= 0\n                && options.parseArrays;\n            if (!options.parseArrays && decodedRoot === '') {\n                obj = { 0: leaf };\n            } else if (isValidArrayIndex && index < options.arrayLimit) {\n                obj = [];\n                obj[index] = leaf;\n            } else if (isValidArrayIndex && options.throwOnLimitExceeded) {\n                throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');\n            } else if (isValidArrayIndex) {\n                obj[index] = leaf;\n                utils.markOverflow(obj, index);\n            } else if (decodedRoot !== '__proto__') {\n                obj[decodedRoot] = leaf;\n            }\n        }\n\n        leaf = obj;\n    }\n\n    return leaf;\n};\n\n// Split a key like \"a[b][c[]]\" into ['a', '[b]', '[c[]]'] while preserving\n// qs parse semantics for depth/prototype guards.\nvar splitKeyIntoSegments = function splitKeyIntoSegments(originalKey, options) {\n    var key = options.allowDots ? originalKey.replace(/\\.([^.[]+)/g, '[$1]') : originalKey;\n\n    // depth <= 0 keeps the whole key as one segment\n    if (options.depth <= 0) {\n        if (!options.plainObjects && has.call(Object.prototype, key)) {\n            if (!options.allowPrototypes) {\n                return;\n            }\n        }\n\n        return [key];\n    }\n\n    var segments = [];\n\n    // parent before the first '[' (may be empty if key starts with '[')\n    var first = key.indexOf('[');\n    var parent = first >= 0 ? key.slice(0, first) : key;\n    if (parent) {\n        if (!options.plainObjects && has.call(Object.prototype, parent)) {\n            if (!options.allowPrototypes) {\n                return;\n            }\n        }\n\n        segments[segments.length] = parent;\n    }\n\n    var n = key.length;\n    var open = first;\n    var collected = 0;\n\n    while (open >= 0 && collected < options.depth) {\n        var level = 1;\n        var i = open + 1;\n        var close = -1;\n\n        // balance nested '[' and ']' inside this bracket group using a nesting level counter\n        while (i < n && close < 0) {\n            var cu = key.charCodeAt(i);\n            if (cu === 0x5B) { // '['\n                level += 1;\n            } else if (cu === 0x5D) { // ']'\n                level -= 1;\n                if (level === 0) {\n                    close = i; // found matching close; loop will exit by condition\n                }\n            }\n            i += 1;\n        }\n\n        if (close < 0) {\n            // Unterminated group: wrap the raw remainder in one bracket pair so it stays\n            // a single literal segment (e.g. \"[[]b\" -> \"[[]b]\"); we do not infer missing ']'.\n            segments[segments.length] = '[' + key.slice(open) + ']';\n            return segments;\n        }\n\n        var seg = key.slice(open, close + 1);\n        // prototype guard for the content of this group\n        var content = seg.slice(1, -1);\n        if (!options.plainObjects && has.call(Object.prototype, content) && !options.allowPrototypes) {\n            return;\n        }\n\n        segments[segments.length] = seg;\n        collected += 1;\n\n        // find the next '[' after this balanced group\n        open = key.indexOf('[', close + 1);\n    }\n\n    if (open >= 0) {\n        if (options.strictDepth === true) {\n            throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true');\n        }\n\n        segments[segments.length] = '[' + key.slice(open) + ']';\n    }\n\n    return segments;\n};\n\nvar parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {\n    if (!givenKey) {\n        return;\n    }\n\n    var keys = splitKeyIntoSegments(givenKey, options);\n\n    if (!keys) {\n        return;\n    }\n\n    return parseObject(keys, val, options, valuesParsed);\n};\n\nvar normalizeParseOptions = function normalizeParseOptions(opts) {\n    if (!opts) {\n        return defaults;\n    }\n\n    if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {\n        throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided');\n    }\n\n    if (typeof opts.decodeDotInKeys !== 'undefined' && typeof opts.decodeDotInKeys !== 'boolean') {\n        throw new TypeError('`decodeDotInKeys` option can only be `true` or `false`, when provided');\n    }\n\n    if (opts.decoder !== null && typeof opts.decoder !== 'undefined' && typeof opts.decoder !== 'function') {\n        throw new TypeError('Decoder has to be a function.');\n    }\n\n    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {\n        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');\n    }\n\n    if (typeof opts.throwOnLimitExceeded !== 'undefined' && typeof opts.throwOnLimitExceeded !== 'boolean') {\n        throw new TypeError('`throwOnLimitExceeded` option must be a boolean');\n    }\n\n    var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;\n\n    var duplicates = typeof opts.duplicates === 'undefined' ? defaults.duplicates : opts.duplicates;\n\n    if (duplicates !== 'combine' && duplicates !== 'first' && duplicates !== 'last') {\n        throw new TypeError('The duplicates option must be either combine, first, or last');\n    }\n\n    var allowDots = typeof opts.allowDots === 'undefined' ? opts.decodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;\n\n    return {\n        allowDots: allowDots,\n        allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,\n        allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,\n        allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,\n        arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,\n        charset: charset,\n        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,\n        comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,\n        decodeDotInKeys: typeof opts.decodeDotInKeys === 'boolean' ? opts.decodeDotInKeys : defaults.decodeDotInKeys,\n        decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,\n        delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,\n        // eslint-disable-next-line no-implicit-coercion, no-extra-parens\n        depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,\n        duplicates: duplicates,\n        ignoreQueryPrefix: opts.ignoreQueryPrefix === true,\n        interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,\n        parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,\n        parseArrays: opts.parseArrays !== false,\n        plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,\n        strictDepth: typeof opts.strictDepth === 'boolean' ? !!opts.strictDepth : defaults.strictDepth,\n        strictMerge: typeof opts.strictMerge === 'boolean' ? !!opts.strictMerge : defaults.strictMerge,\n        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling,\n        throwOnLimitExceeded: typeof opts.throwOnLimitExceeded === 'boolean' ? opts.throwOnLimitExceeded : false\n    };\n};\n\nmodule.exports = function (str, opts) {\n    var options = normalizeParseOptions(opts);\n\n    if (str === '' || str === null || typeof str === 'undefined') {\n        return options.plainObjects ? { __proto__: null } : {};\n    }\n\n    var tempObj = typeof str === 'string' ? parseValues(str, options) : str;\n    var obj = options.plainObjects ? { __proto__: null } : {};\n\n    // Iterate over the keys and setup the new object\n\n    var keys = Object.keys(tempObj);\n    for (var i = 0; i < keys.length; ++i) {\n        var key = keys[i];\n        var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');\n        obj = utils.merge(obj, newObj, options);\n    }\n\n    if (options.allowSparse === true) {\n        return obj;\n    }\n\n    return utils.compact(obj);\n};\n", "'use strict';\n\nvar stringify = require('./stringify');\nvar parse = require('./parse');\nvar formats = require('./formats');\n\nmodule.exports = {\n    formats: formats,\n    parse: parse,\n    stringify: stringify\n};\n", "/*!\n * FilePond 4.32.12\n * Licensed under MIT, https://opensource.org/licenses/MIT/\n * Please visit https://pqina.nl/filepond/ for details.\n */\n\n/* eslint-disable */\n\n(function(global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined'\n        ? factory(exports)\n        : typeof define === 'function' && define.amd\n        ? define(['exports'], factory)\n        : ((global = global || self), factory((global.FilePond = {})));\n})(this, function(exports) {\n    'use strict';\n\n    var isNode = function isNode(value) {\n        return value instanceof HTMLElement;\n    };\n\n    var createStore = function createStore(initialState) {\n        var queries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n        var actions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n        // internal state\n        var state = Object.assign({}, initialState);\n\n        // contains all actions for next frame, is clear when actions are requested\n        var actionQueue = [];\n        var dispatchQueue = [];\n\n        // returns a duplicate of the current state\n        var getState = function getState() {\n            return Object.assign({}, state);\n        };\n\n        // returns a duplicate of the actions array and clears the actions array\n        var processActionQueue = function processActionQueue() {\n            // create copy of actions queue\n            var queue = [].concat(actionQueue);\n\n            // clear actions queue (we don't want no double actions)\n            actionQueue.length = 0;\n\n            return queue;\n        };\n\n        // processes actions that might block the main UI thread\n        var processDispatchQueue = function processDispatchQueue() {\n            // create copy of actions queue\n            var queue = [].concat(dispatchQueue);\n\n            // clear actions queue (we don't want no double actions)\n            dispatchQueue.length = 0;\n\n            // now dispatch these actions\n            queue.forEach(function(_ref) {\n                var type = _ref.type,\n                    data = _ref.data;\n                dispatch(type, data);\n            });\n        };\n\n        // adds a new action, calls its handler and\n        var dispatch = function dispatch(type, data, isBlocking) {\n            // is blocking action (should never block if document is hidden)\n            if (isBlocking && !document.hidden) {\n                dispatchQueue.push({ type: type, data: data });\n                return;\n            }\n\n            // if this action has a handler, handle the action\n            if (actionHandlers[type]) {\n                actionHandlers[type](data);\n            }\n\n            // now add action\n            actionQueue.push({\n                type: type,\n                data: data,\n            });\n        };\n\n        var query = function query(str) {\n            var _queryHandles;\n            for (\n                var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1;\n                _key < _len;\n                _key++\n            ) {\n                args[_key - 1] = arguments[_key];\n            }\n            return queryHandles[str]\n                ? (_queryHandles = queryHandles)[str].apply(_queryHandles, args)\n                : null;\n        };\n\n        var api = {\n            getState: getState,\n            processActionQueue: processActionQueue,\n            processDispatchQueue: processDispatchQueue,\n            dispatch: dispatch,\n            query: query,\n        };\n\n        var queryHandles = {};\n        queries.forEach(function(query) {\n            queryHandles = Object.assign({}, query(state), {}, queryHandles);\n        });\n\n        var actionHandlers = {};\n        actions.forEach(function(action) {\n            actionHandlers = Object.assign({}, action(dispatch, query, state), {}, actionHandlers);\n        });\n\n        return api;\n    };\n\n    var defineProperty = function defineProperty(obj, property, definition) {\n        if (typeof definition === 'function') {\n            obj[property] = definition;\n            return;\n        }\n        Object.defineProperty(obj, property, Object.assign({}, definition));\n    };\n\n    var forin = function forin(obj, cb) {\n        for (var key in obj) {\n            if (!obj.hasOwnProperty(key)) {\n                continue;\n            }\n\n            cb(key, obj[key]);\n        }\n    };\n\n    var createObject = function createObject(definition) {\n        var obj = {};\n        forin(definition, function(property) {\n            defineProperty(obj, property, definition[property]);\n        });\n        return obj;\n    };\n\n    var attr = function attr(node, name) {\n        var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n        if (value === null) {\n            return node.getAttribute(name) || node.hasAttribute(name);\n        }\n        node.setAttribute(name, value);\n    };\n\n    var ns = 'http://www.w3.org/2000/svg';\n    var svgElements = ['svg', 'path']; // only svg elements used\n\n    var isSVGElement = function isSVGElement(tag) {\n        return svgElements.includes(tag);\n    };\n\n    var createElement = function createElement(tag, className) {\n        var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n        if (typeof className === 'object') {\n            attributes = className;\n            className = null;\n        }\n        var element = isSVGElement(tag)\n            ? document.createElementNS(ns, tag)\n            : document.createElement(tag);\n        if (className) {\n            if (isSVGElement(tag)) {\n                attr(element, 'class', className);\n            } else {\n                element.className = className;\n            }\n        }\n        forin(attributes, function(name, value) {\n            attr(element, name, value);\n        });\n        return element;\n    };\n\n    var appendChild = function appendChild(parent) {\n        return function(child, index) {\n            if (typeof index !== 'undefined' && parent.children[index]) {\n                parent.insertBefore(child, parent.children[index]);\n            } else {\n                parent.appendChild(child);\n            }\n        };\n    };\n\n    var appendChildView = function appendChildView(parent, childViews) {\n        return function(view, index) {\n            if (typeof index !== 'undefined') {\n                childViews.splice(index, 0, view);\n            } else {\n                childViews.push(view);\n            }\n\n            return view;\n        };\n    };\n\n    var removeChildView = function removeChildView(parent, childViews) {\n        return function(view) {\n            // remove from child views\n            childViews.splice(childViews.indexOf(view), 1);\n\n            // remove the element\n            if (view.element.parentNode) {\n                parent.removeChild(view.element);\n            }\n\n            return view;\n        };\n    };\n\n    var IS_BROWSER = (function() {\n        return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n    })();\n    var isBrowser = function isBrowser() {\n        return IS_BROWSER;\n    };\n\n    var testElement = isBrowser() ? createElement('svg') : {};\n    var getChildCount =\n        'children' in testElement\n            ? function(el) {\n                  return el.children.length;\n              }\n            : function(el) {\n                  return el.childNodes.length;\n              };\n\n    var getViewRect = function getViewRect(elementRect, childViews, offset, scale) {\n        var left = offset[0] || elementRect.left;\n        var top = offset[1] || elementRect.top;\n        var right = left + elementRect.width;\n        var bottom = top + elementRect.height * (scale[1] || 1);\n\n        var rect = {\n            // the rectangle of the element itself\n            element: Object.assign({}, elementRect),\n\n            // the rectangle of the element expanded to contain its children, does not include any margins\n            inner: {\n                left: elementRect.left,\n                top: elementRect.top,\n                right: elementRect.right,\n                bottom: elementRect.bottom,\n            },\n\n            // the rectangle of the element expanded to contain its children including own margin and child margins\n            // margins will be added after we've recalculated the size\n            outer: {\n                left: left,\n                top: top,\n                right: right,\n                bottom: bottom,\n            },\n        };\n\n        // expand rect to fit all child rectangles\n        childViews\n            .filter(function(childView) {\n                return !childView.isRectIgnored();\n            })\n            .map(function(childView) {\n                return childView.rect;\n            })\n            .forEach(function(childViewRect) {\n                expandRect(rect.inner, Object.assign({}, childViewRect.inner));\n                expandRect(rect.outer, Object.assign({}, childViewRect.outer));\n            });\n\n        // calculate inner width and height\n        calculateRectSize(rect.inner);\n\n        // append additional margin (top and left margins are included in top and left automatically)\n        rect.outer.bottom += rect.element.marginBottom;\n        rect.outer.right += rect.element.marginRight;\n\n        // calculate outer width and height\n        calculateRectSize(rect.outer);\n\n        return rect;\n    };\n\n    var expandRect = function expandRect(parent, child) {\n        // adjust for parent offset\n        child.top += parent.top;\n        child.right += parent.left;\n        child.bottom += parent.top;\n        child.left += parent.left;\n\n        if (child.bottom > parent.bottom) {\n            parent.bottom = child.bottom;\n        }\n\n        if (child.right > parent.right) {\n            parent.right = child.right;\n        }\n    };\n\n    var calculateRectSize = function calculateRectSize(rect) {\n        rect.width = rect.right - rect.left;\n        rect.height = rect.bottom - rect.top;\n    };\n\n    var isNumber = function isNumber(value) {\n        return typeof value === 'number';\n    };\n\n    /**\n     * Determines if position is at destination\n     * @param position\n     * @param destination\n     * @param velocity\n     * @param errorMargin\n     * @returns {boolean}\n     */\n    var thereYet = function thereYet(position, destination, velocity) {\n        var errorMargin = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0.001;\n        return Math.abs(position - destination) < errorMargin && Math.abs(velocity) < errorMargin;\n    };\n\n    /**\n     * Spring animation\n     */\n    var spring =\n        // default options\n        function spring() // method definition\n        {\n            var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n                _ref$stiffness = _ref.stiffness,\n                stiffness = _ref$stiffness === void 0 ? 0.5 : _ref$stiffness,\n                _ref$damping = _ref.damping,\n                damping = _ref$damping === void 0 ? 0.75 : _ref$damping,\n                _ref$mass = _ref.mass,\n                mass = _ref$mass === void 0 ? 10 : _ref$mass;\n            var target = null;\n            var position = null;\n            var velocity = 0;\n            var resting = false;\n\n            // updates spring state\n            var interpolate = function interpolate(ts, skipToEndState) {\n                // in rest, don't animate\n                if (resting) return;\n\n                // need at least a target or position to do springy things\n                if (!(isNumber(target) && isNumber(position))) {\n                    resting = true;\n                    velocity = 0;\n                    return;\n                }\n\n                // calculate spring force\n                var f = -(position - target) * stiffness;\n\n                // update velocity by adding force based on mass\n                velocity += f / mass;\n\n                // update position by adding velocity\n                position += velocity;\n\n                // slow down based on amount of damping\n                velocity *= damping;\n\n                // we've arrived if we're near target and our velocity is near zero\n                if (thereYet(position, target, velocity) || skipToEndState) {\n                    position = target;\n                    velocity = 0;\n                    resting = true;\n\n                    // we done\n                    api.onupdate(position);\n                    api.oncomplete(position);\n                } else {\n                    // progress update\n                    api.onupdate(position);\n                }\n            };\n\n            /**\n             * Set new target value\n             * @param value\n             */\n            var setTarget = function setTarget(value) {\n                // if currently has no position, set target and position to this value\n                if (isNumber(value) && !isNumber(position)) {\n                    position = value;\n                }\n\n                // next target value will not be animated to\n                if (target === null) {\n                    target = value;\n                    position = value;\n                }\n\n                // let start moving to target\n                target = value;\n\n                // already at target\n                if (position === target || typeof target === 'undefined') {\n                    // now resting as target is current position, stop moving\n                    resting = true;\n                    velocity = 0;\n\n                    // done!\n                    api.onupdate(position);\n                    api.oncomplete(position);\n\n                    return;\n                }\n\n                resting = false;\n            };\n\n            // need 'api' to call onupdate callback\n            var api = createObject({\n                interpolate: interpolate,\n                target: {\n                    set: setTarget,\n                    get: function get() {\n                        return target;\n                    },\n                },\n\n                resting: {\n                    get: function get() {\n                        return resting;\n                    },\n                },\n\n                onupdate: function onupdate(value) {},\n                oncomplete: function oncomplete(value) {},\n            });\n\n            return api;\n        };\n\n    var easeLinear = function easeLinear(t) {\n        return t;\n    };\n    var easeInOutQuad = function easeInOutQuad(t) {\n        return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n    };\n\n    var tween =\n        // default values\n        function tween() // method definition\n        {\n            var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n                _ref$duration = _ref.duration,\n                duration = _ref$duration === void 0 ? 500 : _ref$duration,\n                _ref$easing = _ref.easing,\n                easing = _ref$easing === void 0 ? easeInOutQuad : _ref$easing,\n                _ref$delay = _ref.delay,\n                delay = _ref$delay === void 0 ? 0 : _ref$delay;\n            var start = null;\n            var t;\n            var p;\n            var resting = true;\n            var reverse = false;\n            var target = null;\n\n            var interpolate = function interpolate(ts, skipToEndState) {\n                if (resting || target === null) return;\n\n                if (start === null) {\n                    start = ts;\n                }\n\n                if (ts - start < delay) return;\n\n                t = ts - start - delay;\n\n                if (t >= duration || skipToEndState) {\n                    t = 1;\n                    p = reverse ? 0 : 1;\n                    api.onupdate(p * target);\n                    api.oncomplete(p * target);\n                    resting = true;\n                } else {\n                    p = t / duration;\n                    api.onupdate((t >= 0 ? easing(reverse ? 1 - p : p) : 0) * target);\n                }\n            };\n\n            // need 'api' to call onupdate callback\n            var api = createObject({\n                interpolate: interpolate,\n                target: {\n                    get: function get() {\n                        return reverse ? 0 : target;\n                    },\n                    set: function set(value) {\n                        // is initial value\n                        if (target === null) {\n                            target = value;\n                            api.onupdate(value);\n                            api.oncomplete(value);\n                            return;\n                        }\n\n                        // want to tween to a smaller value and have a current value\n                        if (value < target) {\n                            target = 1;\n                            reverse = true;\n                        } else {\n                            // not tweening to a smaller value\n                            reverse = false;\n                            target = value;\n                        }\n\n                        // let's go!\n                        resting = false;\n                        start = null;\n                    },\n                },\n\n                resting: {\n                    get: function get() {\n                        return resting;\n                    },\n                },\n\n                onupdate: function onupdate(value) {},\n                oncomplete: function oncomplete(value) {},\n            });\n\n            return api;\n        };\n\n    var animator = {\n        spring: spring,\n        tween: tween,\n    };\n\n    /*\n                       { type: 'spring', stiffness: .5, damping: .75, mass: 10 };\n                       { translation: { type: 'spring', ... }, ... }\n                       { translation: { x: { type: 'spring', ... } } }\n                      */\n    var createAnimator = function createAnimator(definition, category, property) {\n        // default is single definition\n        // we check if transform is set, if so, we check if property is set\n        var def =\n            definition[category] && typeof definition[category][property] === 'object'\n                ? definition[category][property]\n                : definition[category] || definition;\n\n        var type = typeof def === 'string' ? def : def.type;\n        var props = typeof def === 'object' ? Object.assign({}, def) : {};\n\n        return animator[type] ? animator[type](props) : null;\n    };\n\n    var addGetSet = function addGetSet(keys, obj, props) {\n        var overwrite = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n        obj = Array.isArray(obj) ? obj : [obj];\n        obj.forEach(function(o) {\n            keys.forEach(function(key) {\n                var name = key;\n                var getter = function getter() {\n                    return props[key];\n                };\n                var setter = function setter(value) {\n                    return (props[key] = value);\n                };\n\n                if (typeof key === 'object') {\n                    name = key.key;\n                    getter = key.getter || getter;\n                    setter = key.setter || setter;\n                }\n\n                if (o[name] && !overwrite) {\n                    return;\n                }\n\n                o[name] = {\n                    get: getter,\n                    set: setter,\n                };\n            });\n        });\n    };\n\n    // add to state,\n    // add getters and setters to internal and external api (if not set)\n    // setup animators\n\n    var animations = function animations(_ref) {\n        var mixinConfig = _ref.mixinConfig,\n            viewProps = _ref.viewProps,\n            viewInternalAPI = _ref.viewInternalAPI,\n            viewExternalAPI = _ref.viewExternalAPI;\n        // initial properties\n        var initialProps = Object.assign({}, viewProps);\n\n        // list of all active animations\n        var animations = [];\n\n        // setup animators\n        forin(mixinConfig, function(property, animation) {\n            var animator = createAnimator(animation);\n            if (!animator) {\n                return;\n            }\n\n            // when the animator updates, update the view state value\n            animator.onupdate = function(value) {\n                viewProps[property] = value;\n            };\n\n            // set animator target\n            animator.target = initialProps[property];\n\n            // when value is set, set the animator target value\n            var prop = {\n                key: property,\n                setter: function setter(value) {\n                    // if already at target, we done!\n                    if (animator.target === value) {\n                        return;\n                    }\n\n                    animator.target = value;\n                },\n                getter: function getter() {\n                    return viewProps[property];\n                },\n            };\n\n            // add getters and setters\n            addGetSet([prop], [viewInternalAPI, viewExternalAPI], viewProps, true);\n\n            // add it to the list for easy updating from the _write method\n            animations.push(animator);\n        });\n\n        // expose internal write api\n        return {\n            write: function write(ts) {\n                var skipToEndState = document.hidden;\n                var resting = true;\n                animations.forEach(function(animation) {\n                    if (!animation.resting) resting = false;\n                    animation.interpolate(ts, skipToEndState);\n                });\n                return resting;\n            },\n            destroy: function destroy() {},\n        };\n    };\n\n    var addEvent = function addEvent(element) {\n        return function(type, fn) {\n            element.addEventListener(type, fn);\n        };\n    };\n\n    var removeEvent = function removeEvent(element) {\n        return function(type, fn) {\n            element.removeEventListener(type, fn);\n        };\n    };\n\n    // mixin\n    var listeners = function listeners(_ref) {\n        var mixinConfig = _ref.mixinConfig,\n            viewProps = _ref.viewProps,\n            viewInternalAPI = _ref.viewInternalAPI,\n            viewExternalAPI = _ref.viewExternalAPI,\n            viewState = _ref.viewState,\n            view = _ref.view;\n        var events = [];\n\n        var add = addEvent(view.element);\n        var remove = removeEvent(view.element);\n\n        viewExternalAPI.on = function(type, fn) {\n            events.push({\n                type: type,\n                fn: fn,\n            });\n\n            add(type, fn);\n        };\n\n        viewExternalAPI.off = function(type, fn) {\n            events.splice(\n                events.findIndex(function(event) {\n                    return event.type === type && event.fn === fn;\n                }),\n                1\n            );\n\n            remove(type, fn);\n        };\n\n        return {\n            write: function write() {\n                // not busy\n                return true;\n            },\n            destroy: function destroy() {\n                events.forEach(function(event) {\n                    remove(event.type, event.fn);\n                });\n            },\n        };\n    };\n\n    // add to external api and link to props\n\n    var apis = function apis(_ref) {\n        var mixinConfig = _ref.mixinConfig,\n            viewProps = _ref.viewProps,\n            viewExternalAPI = _ref.viewExternalAPI;\n        addGetSet(mixinConfig, viewExternalAPI, viewProps);\n    };\n\n    var isDefined = function isDefined(value) {\n        return value != null;\n    };\n\n    // add to state,\n    // add getters and setters to internal and external api (if not set)\n    // set initial state based on props in viewProps\n    // apply as transforms each frame\n\n    var defaults = {\n        opacity: 1,\n        scaleX: 1,\n        scaleY: 1,\n        translateX: 0,\n        translateY: 0,\n        rotateX: 0,\n        rotateY: 0,\n        rotateZ: 0,\n        originX: 0,\n        originY: 0,\n    };\n\n    var styles = function styles(_ref) {\n        var mixinConfig = _ref.mixinConfig,\n            viewProps = _ref.viewProps,\n            viewInternalAPI = _ref.viewInternalAPI,\n            viewExternalAPI = _ref.viewExternalAPI,\n            view = _ref.view;\n        // initial props\n        var initialProps = Object.assign({}, viewProps);\n\n        // current props\n        var currentProps = {};\n\n        // we will add those properties to the external API and link them to the viewState\n        addGetSet(mixinConfig, [viewInternalAPI, viewExternalAPI], viewProps);\n\n        // override rect on internal and external rect getter so it takes in account transforms\n        var getOffset = function getOffset() {\n            return [viewProps['translateX'] || 0, viewProps['translateY'] || 0];\n        };\n\n        var getScale = function getScale() {\n            return [viewProps['scaleX'] || 0, viewProps['scaleY'] || 0];\n        };\n        var getRect = function getRect() {\n            return view.rect\n                ? getViewRect(view.rect, view.childViews, getOffset(), getScale())\n                : null;\n        };\n        viewInternalAPI.rect = { get: getRect };\n        viewExternalAPI.rect = { get: getRect };\n\n        // apply view props\n        mixinConfig.forEach(function(key) {\n            viewProps[key] =\n                typeof initialProps[key] === 'undefined' ? defaults[key] : initialProps[key];\n        });\n\n        // expose api\n        return {\n            write: function write() {\n                // see if props have changed\n                if (!propsHaveChanged(currentProps, viewProps)) {\n                    return;\n                }\n\n                // moves element to correct position on screen\n                applyStyles(view.element, viewProps);\n\n                // store new transforms\n                Object.assign(currentProps, Object.assign({}, viewProps));\n\n                // no longer busy\n                return true;\n            },\n            destroy: function destroy() {},\n        };\n    };\n\n    var propsHaveChanged = function propsHaveChanged(currentProps, newProps) {\n        // different amount of keys\n        if (Object.keys(currentProps).length !== Object.keys(newProps).length) {\n            return true;\n        }\n\n        // lets analyze the individual props\n        for (var prop in newProps) {\n            if (newProps[prop] !== currentProps[prop]) {\n                return true;\n            }\n        }\n\n        return false;\n    };\n\n    var applyStyles = function applyStyles(element, _ref2) {\n        var opacity = _ref2.opacity,\n            perspective = _ref2.perspective,\n            translateX = _ref2.translateX,\n            translateY = _ref2.translateY,\n            scaleX = _ref2.scaleX,\n            scaleY = _ref2.scaleY,\n            rotateX = _ref2.rotateX,\n            rotateY = _ref2.rotateY,\n            rotateZ = _ref2.rotateZ,\n            originX = _ref2.originX,\n            originY = _ref2.originY,\n            width = _ref2.width,\n            height = _ref2.height;\n\n        var transforms = '';\n        var styles = '';\n\n        // handle transform origin\n        if (isDefined(originX) || isDefined(originY)) {\n            styles += 'transform-origin: ' + (originX || 0) + 'px ' + (originY || 0) + 'px;';\n        }\n\n        // transform order is relevant\n        // 0. perspective\n        if (isDefined(perspective)) {\n            transforms += 'perspective(' + perspective + 'px) ';\n        }\n\n        // 1. translate\n        if (isDefined(translateX) || isDefined(translateY)) {\n            transforms +=\n                'translate3d(' + (translateX || 0) + 'px, ' + (translateY || 0) + 'px, 0) ';\n        }\n\n        // 2. scale\n        if (isDefined(scaleX) || isDefined(scaleY)) {\n            transforms +=\n                'scale3d(' +\n                (isDefined(scaleX) ? scaleX : 1) +\n                ', ' +\n                (isDefined(scaleY) ? scaleY : 1) +\n                ', 1) ';\n        }\n\n        // 3. rotate\n        if (isDefined(rotateZ)) {\n            transforms += 'rotateZ(' + rotateZ + 'rad) ';\n        }\n\n        if (isDefined(rotateX)) {\n            transforms += 'rotateX(' + rotateX + 'rad) ';\n        }\n\n        if (isDefined(rotateY)) {\n            transforms += 'rotateY(' + rotateY + 'rad) ';\n        }\n\n        // add transforms\n        if (transforms.length) {\n            styles += 'transform:' + transforms + ';';\n        }\n\n        // add opacity\n        if (isDefined(opacity)) {\n            styles += 'opacity:' + opacity + ';';\n\n            // if we reach zero, we make the element inaccessible\n            if (opacity === 0) {\n                styles += 'visibility:hidden;';\n            }\n\n            // if we're below 100% opacity this element can't be clicked\n            if (opacity < 1) {\n                styles += 'pointer-events:none;';\n            }\n        }\n\n        // add height\n        if (isDefined(height)) {\n            styles += 'height:' + height + 'px;';\n        }\n\n        // add width\n        if (isDefined(width)) {\n            styles += 'width:' + width + 'px;';\n        }\n\n        // apply styles\n        var elementCurrentStyle = element.elementCurrentStyle || '';\n\n        // if new styles does not match current styles, lets update!\n        if (styles.length !== elementCurrentStyle.length || styles !== elementCurrentStyle) {\n            element.style.cssText = styles;\n            // store current styles so we can compare them to new styles later on\n            // _not_ getting the style value is faster\n            element.elementCurrentStyle = styles;\n        }\n    };\n\n    var Mixins = {\n        styles: styles,\n        listeners: listeners,\n        animations: animations,\n        apis: apis,\n    };\n\n    var updateRect = function updateRect() {\n        var rect = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n        var element = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n        var style = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        if (!element.layoutCalculated) {\n            rect.paddingTop = parseInt(style.paddingTop, 10) || 0;\n            rect.marginTop = parseInt(style.marginTop, 10) || 0;\n            rect.marginRight = parseInt(style.marginRight, 10) || 0;\n            rect.marginBottom = parseInt(style.marginBottom, 10) || 0;\n            rect.marginLeft = parseInt(style.marginLeft, 10) || 0;\n            element.layoutCalculated = true;\n        }\n\n        rect.left = element.offsetLeft || 0;\n        rect.top = element.offsetTop || 0;\n        rect.width = element.offsetWidth || 0;\n        rect.height = element.offsetHeight || 0;\n\n        rect.right = rect.left + rect.width;\n        rect.bottom = rect.top + rect.height;\n\n        rect.scrollTop = element.scrollTop;\n\n        rect.hidden = element.offsetParent === null;\n\n        return rect;\n    };\n\n    var createView =\n        // default view definition\n        function createView() {\n            var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n                _ref$tag = _ref.tag,\n                tag = _ref$tag === void 0 ? 'div' : _ref$tag,\n                _ref$name = _ref.name,\n                name = _ref$name === void 0 ? null : _ref$name,\n                _ref$attributes = _ref.attributes,\n                attributes = _ref$attributes === void 0 ? {} : _ref$attributes,\n                _ref$read = _ref.read,\n                read = _ref$read === void 0 ? function() {} : _ref$read,\n                _ref$write = _ref.write,\n                write = _ref$write === void 0 ? function() {} : _ref$write,\n                _ref$create = _ref.create,\n                create = _ref$create === void 0 ? function() {} : _ref$create,\n                _ref$destroy = _ref.destroy,\n                destroy = _ref$destroy === void 0 ? function() {} : _ref$destroy,\n                _ref$filterFrameActio = _ref.filterFrameActionsForChild,\n                filterFrameActionsForChild =\n                    _ref$filterFrameActio === void 0\n                        ? function(child, actions) {\n                              return actions;\n                          }\n                        : _ref$filterFrameActio,\n                _ref$didCreateView = _ref.didCreateView,\n                didCreateView = _ref$didCreateView === void 0 ? function() {} : _ref$didCreateView,\n                _ref$didWriteView = _ref.didWriteView,\n                didWriteView = _ref$didWriteView === void 0 ? function() {} : _ref$didWriteView,\n                _ref$ignoreRect = _ref.ignoreRect,\n                ignoreRect = _ref$ignoreRect === void 0 ? false : _ref$ignoreRect,\n                _ref$ignoreRectUpdate = _ref.ignoreRectUpdate,\n                ignoreRectUpdate = _ref$ignoreRectUpdate === void 0 ? false : _ref$ignoreRectUpdate,\n                _ref$mixins = _ref.mixins,\n                mixins = _ref$mixins === void 0 ? [] : _ref$mixins;\n            return function(\n                // each view requires reference to store\n                store\n            ) {\n                var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n                // root element should not be changed\n                var element = createElement(tag, 'filepond--' + name, attributes);\n\n                // style reference should also not be changed\n                var style = window.getComputedStyle(element, null);\n\n                // element rectangle\n                var rect = updateRect();\n                var frameRect = null;\n\n                // rest state\n                var isResting = false;\n\n                // pretty self explanatory\n                var childViews = [];\n\n                // loaded mixins\n                var activeMixins = [];\n\n                // references to created children\n                var ref = {};\n\n                // state used for each instance\n                var state = {};\n\n                // list of writers that will be called to update this view\n                var writers = [\n                    write, // default writer\n                ];\n\n                var readers = [\n                    read, // default reader\n                ];\n\n                var destroyers = [\n                    destroy, // default destroy\n                ];\n\n                // core view methods\n                var getElement = function getElement() {\n                    return element;\n                };\n                var getChildViews = function getChildViews() {\n                    return childViews.concat();\n                };\n                var getReference = function getReference() {\n                    return ref;\n                };\n                var createChildView = function createChildView(store) {\n                    return function(view, props) {\n                        return view(store, props);\n                    };\n                };\n                var getRect = function getRect() {\n                    if (frameRect) {\n                        return frameRect;\n                    }\n                    frameRect = getViewRect(rect, childViews, [0, 0], [1, 1]);\n                    return frameRect;\n                };\n                var getStyle = function getStyle() {\n                    return style;\n                };\n\n                /**\n                 * Read data from DOM\n                 * @private\n                 */\n                var _read = function _read() {\n                    frameRect = null;\n\n                    // read child views\n                    childViews.forEach(function(child) {\n                        return child._read();\n                    });\n\n                    var shouldUpdate = !(ignoreRectUpdate && rect.width && rect.height);\n                    if (shouldUpdate) {\n                        updateRect(rect, element, style);\n                    }\n\n                    // readers\n                    var api = { root: internalAPI, props: props, rect: rect };\n                    readers.forEach(function(reader) {\n                        return reader(api);\n                    });\n                };\n\n                /**\n                 * Write data to DOM\n                 * @private\n                 */\n                var _write = function _write(ts, frameActions, shouldOptimize) {\n                    // if no actions, we assume that the view is resting\n                    var resting = frameActions.length === 0;\n\n                    // writers\n                    writers.forEach(function(writer) {\n                        var writerResting = writer({\n                            props: props,\n                            root: internalAPI,\n                            actions: frameActions,\n                            timestamp: ts,\n                            shouldOptimize: shouldOptimize,\n                        });\n\n                        if (writerResting === false) {\n                            resting = false;\n                        }\n                    });\n\n                    // run mixins\n                    activeMixins.forEach(function(mixin) {\n                        // if one of the mixins is still busy after write operation, we are not resting\n                        var mixinResting = mixin.write(ts);\n                        if (mixinResting === false) {\n                            resting = false;\n                        }\n                    });\n\n                    // updates child views that are currently attached to the DOM\n                    childViews\n                        .filter(function(child) {\n                            return !!child.element.parentNode;\n                        })\n                        .forEach(function(child) {\n                            // if a child view is not resting, we are not resting\n                            var childResting = child._write(\n                                ts,\n                                filterFrameActionsForChild(child, frameActions),\n                                shouldOptimize\n                            );\n\n                            if (!childResting) {\n                                resting = false;\n                            }\n                        });\n\n                    // append new elements to DOM and update those\n                    childViews\n                        //.filter(child => !child.element.parentNode)\n                        .forEach(function(child, index) {\n                            // skip\n                            if (child.element.parentNode) {\n                                return;\n                            }\n\n                            // append to DOM\n                            internalAPI.appendChild(child.element, index);\n\n                            // call read (need to know the size of these elements)\n                            child._read();\n\n                            // re-call write\n                            child._write(\n                                ts,\n                                filterFrameActionsForChild(child, frameActions),\n                                shouldOptimize\n                            );\n\n                            // we just added somthing to the dom, no rest\n                            resting = false;\n                        });\n\n                    // update resting state\n                    isResting = resting;\n\n                    didWriteView({\n                        props: props,\n                        root: internalAPI,\n                        actions: frameActions,\n                        timestamp: ts,\n                    });\n\n                    // let parent know if we are resting\n                    return resting;\n                };\n\n                var _destroy = function _destroy() {\n                    activeMixins.forEach(function(mixin) {\n                        return mixin.destroy();\n                    });\n                    destroyers.forEach(function(destroyer) {\n                        destroyer({ root: internalAPI, props: props });\n                    });\n                    childViews.forEach(function(child) {\n                        return child._destroy();\n                    });\n                };\n\n                // sharedAPI\n                var sharedAPIDefinition = {\n                    element: {\n                        get: getElement,\n                    },\n\n                    style: {\n                        get: getStyle,\n                    },\n\n                    childViews: {\n                        get: getChildViews,\n                    },\n                };\n\n                // private API definition\n                var internalAPIDefinition = Object.assign({}, sharedAPIDefinition, {\n                    rect: {\n                        get: getRect,\n                    },\n\n                    // access to custom children references\n                    ref: {\n                        get: getReference,\n                    },\n\n                    // dom modifiers\n                    is: function is(needle) {\n                        return name === needle;\n                    },\n                    appendChild: appendChild(element),\n                    createChildView: createChildView(store),\n                    linkView: function linkView(view) {\n                        childViews.push(view);\n                        return view;\n                    },\n                    unlinkView: function unlinkView(view) {\n                        childViews.splice(childViews.indexOf(view), 1);\n                    },\n                    appendChildView: appendChildView(element, childViews),\n                    removeChildView: removeChildView(element, childViews),\n                    registerWriter: function registerWriter(writer) {\n                        return writers.push(writer);\n                    },\n                    registerReader: function registerReader(reader) {\n                        return readers.push(reader);\n                    },\n                    registerDestroyer: function registerDestroyer(destroyer) {\n                        return destroyers.push(destroyer);\n                    },\n                    invalidateLayout: function invalidateLayout() {\n                        return (element.layoutCalculated = false);\n                    },\n\n                    // access to data store\n                    dispatch: store.dispatch,\n                    query: store.query,\n                });\n\n                // public view API methods\n                var externalAPIDefinition = {\n                    element: {\n                        get: getElement,\n                    },\n\n                    childViews: {\n                        get: getChildViews,\n                    },\n\n                    rect: {\n                        get: getRect,\n                    },\n\n                    resting: {\n                        get: function get() {\n                            return isResting;\n                        },\n                    },\n\n                    isRectIgnored: function isRectIgnored() {\n                        return ignoreRect;\n                    },\n                    _read: _read,\n                    _write: _write,\n                    _destroy: _destroy,\n                };\n\n                // mixin API methods\n                var mixinAPIDefinition = Object.assign({}, sharedAPIDefinition, {\n                    rect: {\n                        get: function get() {\n                            return rect;\n                        },\n                    },\n                });\n\n                // add mixin functionality\n                Object.keys(mixins)\n                    .sort(function(a, b) {\n                        // move styles to the back of the mixin list (so adjustments of other mixins are applied to the props correctly)\n                        if (a === 'styles') {\n                            return 1;\n                        } else if (b === 'styles') {\n                            return -1;\n                        }\n                        return 0;\n                    })\n                    .forEach(function(key) {\n                        var mixinAPI = Mixins[key]({\n                            mixinConfig: mixins[key],\n                            viewProps: props,\n                            viewState: state,\n                            viewInternalAPI: internalAPIDefinition,\n                            viewExternalAPI: externalAPIDefinition,\n                            view: createObject(mixinAPIDefinition),\n                        });\n\n                        if (mixinAPI) {\n                            activeMixins.push(mixinAPI);\n                        }\n                    });\n\n                // construct private api\n                var internalAPI = createObject(internalAPIDefinition);\n\n                // create the view\n                create({\n                    root: internalAPI,\n                    props: props,\n                });\n\n                // append created child views to root node\n                var childCount = getChildCount(element); // need to know the current child count so appending happens in correct order\n                childViews.forEach(function(child, index) {\n                    internalAPI.appendChild(child.element, childCount + index);\n                });\n\n                // call did create\n                didCreateView(internalAPI);\n\n                // expose public api\n                return createObject(externalAPIDefinition);\n            };\n        };\n\n    var createPainter = function createPainter(read, write) {\n        var fps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 60;\n\n        var name = '__framePainter';\n\n        // set global painter\n        if (window[name]) {\n            window[name].readers.push(read);\n            window[name].writers.push(write);\n            return;\n        }\n\n        window[name] = {\n            readers: [read],\n            writers: [write],\n        };\n\n        var painter = window[name];\n\n        var interval = 1000 / fps;\n        var last = null;\n        var id = null;\n        var requestTick = null;\n        var cancelTick = null;\n\n        var setTimerType = function setTimerType() {\n            if (document.hidden) {\n                requestTick = function requestTick() {\n                    return window.setTimeout(function() {\n                        return tick(performance.now());\n                    }, interval);\n                };\n                cancelTick = function cancelTick() {\n                    return window.clearTimeout(id);\n                };\n            } else {\n                requestTick = function requestTick() {\n                    return window.requestAnimationFrame(tick);\n                };\n                cancelTick = function cancelTick() {\n                    return window.cancelAnimationFrame(id);\n                };\n            }\n        };\n\n        document.addEventListener('visibilitychange', function() {\n            if (cancelTick) cancelTick();\n            setTimerType();\n            tick(performance.now());\n        });\n\n        var tick = function tick(ts) {\n            // queue next tick\n            id = requestTick(tick);\n\n            // limit fps\n            if (!last) {\n                last = ts;\n            }\n\n            var delta = ts - last;\n\n            if (delta <= interval) {\n                // skip frame\n                return;\n            }\n\n            // align next frame\n            last = ts - (delta % interval);\n\n            // update view\n            painter.readers.forEach(function(read) {\n                return read();\n            });\n            painter.writers.forEach(function(write) {\n                return write(ts);\n            });\n        };\n\n        setTimerType();\n        tick(performance.now());\n\n        return {\n            pause: function pause() {\n                cancelTick(id);\n            },\n        };\n    };\n\n    var createRoute = function createRoute(routes, fn) {\n        return function(_ref) {\n            var root = _ref.root,\n                props = _ref.props,\n                _ref$actions = _ref.actions,\n                actions = _ref$actions === void 0 ? [] : _ref$actions,\n                timestamp = _ref.timestamp,\n                shouldOptimize = _ref.shouldOptimize;\n            actions\n                .filter(function(action) {\n                    return routes[action.type];\n                })\n                .forEach(function(action) {\n                    return routes[action.type]({\n                        root: root,\n                        props: props,\n                        action: action.data,\n                        timestamp: timestamp,\n                        shouldOptimize: shouldOptimize,\n                    });\n                });\n\n            if (fn) {\n                fn({\n                    root: root,\n                    props: props,\n                    actions: actions,\n                    timestamp: timestamp,\n                    shouldOptimize: shouldOptimize,\n                });\n            }\n        };\n    };\n\n    var insertBefore = function insertBefore(newNode, referenceNode) {\n        return referenceNode.parentNode.insertBefore(newNode, referenceNode);\n    };\n\n    var insertAfter = function insertAfter(newNode, referenceNode) {\n        return referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);\n    };\n\n    var isArray = function isArray(value) {\n        return Array.isArray(value);\n    };\n\n    var isEmpty = function isEmpty(value) {\n        return value == null;\n    };\n\n    var trim = function trim(str) {\n        return str.trim();\n    };\n\n    var toString = function toString(value) {\n        return '' + value;\n    };\n\n    var toArray = function toArray(value) {\n        var splitter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ',';\n        if (isEmpty(value)) {\n            return [];\n        }\n        if (isArray(value)) {\n            return value;\n        }\n        return toString(value)\n            .split(splitter)\n            .map(trim)\n            .filter(function(str) {\n                return str.length;\n            });\n    };\n\n    var isBoolean = function isBoolean(value) {\n        return typeof value === 'boolean';\n    };\n\n    var toBoolean = function toBoolean(value) {\n        return isBoolean(value) ? value : value === 'true';\n    };\n\n    var isString = function isString(value) {\n        return typeof value === 'string';\n    };\n\n    var toNumber = function toNumber(value) {\n        return isNumber(value)\n            ? value\n            : isString(value)\n            ? toString(value).replace(/[a-z]+/gi, '')\n            : 0;\n    };\n\n    var toInt = function toInt(value) {\n        return parseInt(toNumber(value), 10);\n    };\n\n    var toFloat = function toFloat(value) {\n        return parseFloat(toNumber(value));\n    };\n\n    var isInt = function isInt(value) {\n        return isNumber(value) && isFinite(value) && Math.floor(value) === value;\n    };\n\n    var toBytes = function toBytes(value) {\n        var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;\n        // is in bytes\n        if (isInt(value)) {\n            return value;\n        }\n\n        // is natural file size\n        var naturalFileSize = toString(value).trim();\n\n        // if is value in megabytes\n        if (/MB$/i.test(naturalFileSize)) {\n            naturalFileSize = naturalFileSize.replace(/MB$i/, '').trim();\n            return toInt(naturalFileSize) * base * base;\n        }\n\n        // if is value in kilobytes\n        if (/KB/i.test(naturalFileSize)) {\n            naturalFileSize = naturalFileSize.replace(/KB$i/, '').trim();\n            return toInt(naturalFileSize) * base;\n        }\n\n        return toInt(naturalFileSize);\n    };\n\n    var isFunction = function isFunction(value) {\n        return typeof value === 'function';\n    };\n\n    var toFunctionReference = function toFunctionReference(string) {\n        var ref = self;\n        var levels = string.split('.');\n        var level = null;\n        while ((level = levels.shift())) {\n            ref = ref[level];\n            if (!ref) {\n                return null;\n            }\n        }\n        return ref;\n    };\n\n    var methods = {\n        process: 'POST',\n        patch: 'PATCH',\n        revert: 'DELETE',\n        fetch: 'GET',\n        restore: 'GET',\n        load: 'GET',\n    };\n\n    var createServerAPI = function createServerAPI(outline) {\n        var api = {};\n\n        api.url = isString(outline) ? outline : outline.url || '';\n        api.timeout = outline.timeout ? parseInt(outline.timeout, 10) : 0;\n        api.headers = outline.headers ? outline.headers : {};\n\n        forin(methods, function(key) {\n            api[key] = createAction(key, outline[key], methods[key], api.timeout, api.headers);\n        });\n\n        // remove process if no url or process on outline\n        api.process = outline.process || isString(outline) || outline.url ? api.process : null;\n\n        // special treatment for remove\n        api.remove = outline.remove || null;\n\n        // remove generic headers from api object\n        delete api.headers;\n\n        return api;\n    };\n\n    var createAction = function createAction(name, outline, method, timeout, headers) {\n        // is explicitely set to null so disable\n        if (outline === null) {\n            return null;\n        }\n\n        // if is custom function, done! Dev handles everything.\n        if (typeof outline === 'function') {\n            return outline;\n        }\n\n        // build action object\n        var action = {\n            url: method === 'GET' || method === 'PATCH' ? '?' + name + '=' : '',\n            method: method,\n            headers: headers,\n            withCredentials: false,\n            timeout: timeout,\n            onload: null,\n            ondata: null,\n            onerror: null,\n        };\n\n        // is a single url\n        if (isString(outline)) {\n            action.url = outline;\n            return action;\n        }\n\n        // overwrite\n        Object.assign(action, outline);\n\n        // see if should reformat headers;\n        if (isString(action.headers)) {\n            var parts = action.headers.split(/:(.+)/);\n            action.headers = {\n                header: parts[0],\n                value: parts[1],\n            };\n        }\n\n        // if is bool withCredentials\n        action.withCredentials = toBoolean(action.withCredentials);\n\n        return action;\n    };\n\n    var toServerAPI = function toServerAPI(value) {\n        return createServerAPI(value);\n    };\n\n    var isNull = function isNull(value) {\n        return value === null;\n    };\n\n    var isObject = function isObject(value) {\n        return typeof value === 'object' && value !== null;\n    };\n\n    var isAPI = function isAPI(value) {\n        return (\n            isObject(value) &&\n            isString(value.url) &&\n            isObject(value.process) &&\n            isObject(value.revert) &&\n            isObject(value.restore) &&\n            isObject(value.fetch)\n        );\n    };\n\n    var getType = function getType(value) {\n        if (isArray(value)) {\n            return 'array';\n        }\n\n        if (isNull(value)) {\n            return 'null';\n        }\n\n        if (isInt(value)) {\n            return 'int';\n        }\n\n        if (/^[0-9]+ ?(?:GB|MB|KB)$/gi.test(value)) {\n            return 'bytes';\n        }\n\n        if (isAPI(value)) {\n            return 'api';\n        }\n\n        return typeof value;\n    };\n\n    var replaceSingleQuotes = function replaceSingleQuotes(str) {\n        return str\n            .replace(/{\\s*'/g, '{\"')\n            .replace(/'\\s*}/g, '\"}')\n            .replace(/'\\s*:/g, '\":')\n            .replace(/:\\s*'/g, ':\"')\n            .replace(/,\\s*'/g, ',\"')\n            .replace(/'\\s*,/g, '\",');\n    };\n\n    var conversionTable = {\n        array: toArray,\n        boolean: toBoolean,\n        int: function int(value) {\n            return getType(value) === 'bytes' ? toBytes(value) : toInt(value);\n        },\n        number: toFloat,\n        float: toFloat,\n        bytes: toBytes,\n        string: function string(value) {\n            return isFunction(value) ? value : toString(value);\n        },\n        function: function _function(value) {\n            return toFunctionReference(value);\n        },\n        serverapi: toServerAPI,\n        object: function object(value) {\n            try {\n                return JSON.parse(replaceSingleQuotes(value));\n            } catch (e) {\n                return null;\n            }\n        },\n    };\n\n    var convertTo = function convertTo(value, type) {\n        return conversionTable[type](value);\n    };\n\n    var getValueByType = function getValueByType(newValue, defaultValue, valueType) {\n        // can always assign default value\n        if (newValue === defaultValue) {\n            return newValue;\n        }\n\n        // get the type of the new value\n        var newValueType = getType(newValue);\n\n        // is valid type?\n        if (newValueType !== valueType) {\n            // is string input, let's attempt to convert\n            var convertedValue = convertTo(newValue, valueType);\n\n            // what is the type now\n            newValueType = getType(convertedValue);\n\n            // no valid conversions found\n            if (convertedValue === null) {\n                throw 'Trying to assign value with incorrect type to \"' +\n                    option +\n                    '\", allowed type: \"' +\n                    valueType +\n                    '\"';\n            } else {\n                newValue = convertedValue;\n            }\n        }\n\n        // assign new value\n        return newValue;\n    };\n\n    var createOption = function createOption(defaultValue, valueType) {\n        var currentValue = defaultValue;\n        return {\n            enumerable: true,\n            get: function get() {\n                return currentValue;\n            },\n            set: function set(newValue) {\n                currentValue = getValueByType(newValue, defaultValue, valueType);\n            },\n        };\n    };\n\n    var createOptions = function createOptions(options) {\n        var obj = {};\n        forin(options, function(prop) {\n            var optionDefinition = options[prop];\n            obj[prop] = createOption(optionDefinition[0], optionDefinition[1]);\n        });\n        return createObject(obj);\n    };\n\n    var createInitialState = function createInitialState(options) {\n        return {\n            // model\n            items: [],\n\n            // timeout used for calling update items\n            listUpdateTimeout: null,\n\n            // timeout used for stacking metadata updates\n            itemUpdateTimeout: null,\n\n            // queue of items waiting to be processed\n            processingQueue: [],\n\n            // options\n            options: createOptions(options),\n        };\n    };\n\n    var fromCamels = function fromCamels(string) {\n        var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '-';\n        return string\n            .split(/(?=[A-Z])/)\n            .map(function(part) {\n                return part.toLowerCase();\n            })\n            .join(separator);\n    };\n\n    var createOptionAPI = function createOptionAPI(store, options) {\n        var obj = {};\n        forin(options, function(key) {\n            obj[key] = {\n                get: function get() {\n                    return store.getState().options[key];\n                },\n                set: function set(value) {\n                    store.dispatch('SET_' + fromCamels(key, '_').toUpperCase(), {\n                        value: value,\n                    });\n                },\n            };\n        });\n        return obj;\n    };\n\n    var createOptionActions = function createOptionActions(options) {\n        return function(dispatch, query, state) {\n            var obj = {};\n            forin(options, function(key) {\n                var name = fromCamels(key, '_').toUpperCase();\n\n                obj['SET_' + name] = function(action) {\n                    try {\n                        state.options[key] = action.value;\n                    } catch (e) {} // nope, failed\n\n                    // we successfully set the value of this option\n                    dispatch('DID_SET_' + name, { value: state.options[key] });\n                };\n            });\n            return obj;\n        };\n    };\n\n    var createOptionQueries = function createOptionQueries(options) {\n        return function(state) {\n            var obj = {};\n            forin(options, function(key) {\n                obj['GET_' + fromCamels(key, '_').toUpperCase()] = function(action) {\n                    return state.options[key];\n                };\n            });\n            return obj;\n        };\n    };\n\n    var InteractionMethod = {\n        API: 1,\n        DROP: 2,\n        BROWSE: 3,\n        PASTE: 4,\n        NONE: 5,\n    };\n\n    var getUniqueId = function getUniqueId() {\n        return Math.random()\n            .toString(36)\n            .substring(2, 11);\n    };\n\n    function _typeof(obj) {\n        if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {\n            _typeof = function(obj) {\n                return typeof obj;\n            };\n        } else {\n            _typeof = function(obj) {\n                return obj &&\n                    typeof Symbol === 'function' &&\n                    obj.constructor === Symbol &&\n                    obj !== Symbol.prototype\n                    ? 'symbol'\n                    : typeof obj;\n            };\n        }\n\n        return _typeof(obj);\n    }\n\n    var REACT_ELEMENT_TYPE;\n\n    function _jsx(type, props, key, children) {\n        if (!REACT_ELEMENT_TYPE) {\n            REACT_ELEMENT_TYPE =\n                (typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element')) ||\n                0xeac7;\n        }\n\n        var defaultProps = type && type.defaultProps;\n        var childrenLength = arguments.length - 3;\n\n        if (!props && childrenLength !== 0) {\n            props = {\n                children: void 0,\n            };\n        }\n\n        if (props && defaultProps) {\n            for (var propName in defaultProps) {\n                if (props[propName] === void 0) {\n                    props[propName] = defaultProps[propName];\n                }\n            }\n        } else if (!props) {\n            props = defaultProps || {};\n        }\n\n        if (childrenLength === 1) {\n            props.children = children;\n        } else if (childrenLength > 1) {\n            var childArray = new Array(childrenLength);\n\n            for (var i = 0; i < childrenLength; i++) {\n                childArray[i] = arguments[i + 3];\n            }\n\n            props.children = childArray;\n        }\n\n        return {\n            $$typeof: REACT_ELEMENT_TYPE,\n            type: type,\n            key: key === undefined ? null : '' + key,\n            ref: null,\n            props: props,\n            _owner: null,\n        };\n    }\n\n    function _asyncIterator(iterable) {\n        var method;\n\n        if (typeof Symbol !== 'undefined') {\n            if (Symbol.asyncIterator) {\n                method = iterable[Symbol.asyncIterator];\n                if (method != null) return method.call(iterable);\n            }\n\n            if (Symbol.iterator) {\n                method = iterable[Symbol.iterator];\n                if (method != null) return method.call(iterable);\n            }\n        }\n\n        throw new TypeError('Object is not async iterable');\n    }\n\n    function _AwaitValue(value) {\n        this.wrapped = value;\n    }\n\n    function _AsyncGenerator(gen) {\n        var front, back;\n\n        function send(key, arg) {\n            return new Promise(function(resolve, reject) {\n                var request = {\n                    key: key,\n                    arg: arg,\n                    resolve: resolve,\n                    reject: reject,\n                    next: null,\n                };\n\n                if (back) {\n                    back = back.next = request;\n                } else {\n                    front = back = request;\n                    resume(key, arg);\n                }\n            });\n        }\n\n        function resume(key, arg) {\n            try {\n                var result = gen[key](arg);\n                var value = result.value;\n                var wrappedAwait = value instanceof _AwaitValue;\n                Promise.resolve(wrappedAwait ? value.wrapped : value).then(\n                    function(arg) {\n                        if (wrappedAwait) {\n                            resume('next', arg);\n                            return;\n                        }\n\n                        settle(result.done ? 'return' : 'normal', arg);\n                    },\n                    function(err) {\n                        resume('throw', err);\n                    }\n                );\n            } catch (err) {\n                settle('throw', err);\n            }\n        }\n\n        function settle(type, value) {\n            switch (type) {\n                case 'return':\n                    front.resolve({\n                        value: value,\n                        done: true,\n                    });\n                    break;\n\n                case 'throw':\n                    front.reject(value);\n                    break;\n\n                default:\n                    front.resolve({\n                        value: value,\n                        done: false,\n                    });\n                    break;\n            }\n\n            front = front.next;\n\n            if (front) {\n                resume(front.key, front.arg);\n            } else {\n                back = null;\n            }\n        }\n\n        this._invoke = send;\n\n        if (typeof gen.return !== 'function') {\n            this.return = undefined;\n        }\n    }\n\n    if (typeof Symbol === 'function' && Symbol.asyncIterator) {\n        _AsyncGenerator.prototype[Symbol.asyncIterator] = function() {\n            return this;\n        };\n    }\n\n    _AsyncGenerator.prototype.next = function(arg) {\n        return this._invoke('next', arg);\n    };\n\n    _AsyncGenerator.prototype.throw = function(arg) {\n        return this._invoke('throw', arg);\n    };\n\n    _AsyncGenerator.prototype.return = function(arg) {\n        return this._invoke('return', arg);\n    };\n\n    function _wrapAsyncGenerator(fn) {\n        return function() {\n            return new _AsyncGenerator(fn.apply(this, arguments));\n        };\n    }\n\n    function _awaitAsyncGenerator(value) {\n        return new _AwaitValue(value);\n    }\n\n    function _asyncGeneratorDelegate(inner, awaitWrap) {\n        var iter = {},\n            waiting = false;\n\n        function pump(key, value) {\n            waiting = true;\n            value = new Promise(function(resolve) {\n                resolve(inner[key](value));\n            });\n            return {\n                done: false,\n                value: awaitWrap(value),\n            };\n        }\n\n        if (typeof Symbol === 'function' && Symbol.iterator) {\n            iter[Symbol.iterator] = function() {\n                return this;\n            };\n        }\n\n        iter.next = function(value) {\n            if (waiting) {\n                waiting = false;\n                return value;\n            }\n\n            return pump('next', value);\n        };\n\n        if (typeof inner.throw === 'function') {\n            iter.throw = function(value) {\n                if (waiting) {\n                    waiting = false;\n                    throw value;\n                }\n\n                return pump('throw', value);\n            };\n        }\n\n        if (typeof inner.return === 'function') {\n            iter.return = function(value) {\n                return pump('return', value);\n            };\n        }\n\n        return iter;\n    }\n\n    function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n        try {\n            var info = gen[key](arg);\n            var value = info.value;\n        } catch (error) {\n            reject(error);\n            return;\n        }\n\n        if (info.done) {\n            resolve(value);\n        } else {\n            Promise.resolve(value).then(_next, _throw);\n        }\n    }\n\n    function _asyncToGenerator(fn) {\n        return function() {\n            var self = this,\n                args = arguments;\n            return new Promise(function(resolve, reject) {\n                var gen = fn.apply(self, args);\n\n                function _next(value) {\n                    asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value);\n                }\n\n                function _throw(err) {\n                    asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err);\n                }\n\n                _next(undefined);\n            });\n        };\n    }\n\n    function _classCallCheck(instance, Constructor) {\n        if (!(instance instanceof Constructor)) {\n            throw new TypeError('Cannot call a class as a function');\n        }\n    }\n\n    function _defineProperties(target, props) {\n        for (var i = 0; i < props.length; i++) {\n            var descriptor = props[i];\n            descriptor.enumerable = descriptor.enumerable || false;\n            descriptor.configurable = true;\n            if ('value' in descriptor) descriptor.writable = true;\n            Object.defineProperty(target, descriptor.key, descriptor);\n        }\n    }\n\n    function _createClass(Constructor, protoProps, staticProps) {\n        if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n        if (staticProps) _defineProperties(Constructor, staticProps);\n        return Constructor;\n    }\n\n    function _defineEnumerableProperties(obj, descs) {\n        for (var key in descs) {\n            var desc = descs[key];\n            desc.configurable = desc.enumerable = true;\n            if ('value' in desc) desc.writable = true;\n            Object.defineProperty(obj, key, desc);\n        }\n\n        if (Object.getOwnPropertySymbols) {\n            var objectSymbols = Object.getOwnPropertySymbols(descs);\n\n            for (var i = 0; i < objectSymbols.length; i++) {\n                var sym = objectSymbols[i];\n                var desc = descs[sym];\n                desc.configurable = desc.enumerable = true;\n                if ('value' in desc) desc.writable = true;\n                Object.defineProperty(obj, sym, desc);\n            }\n        }\n\n        return obj;\n    }\n\n    function _defaults(obj, defaults) {\n        var keys = Object.getOwnPropertyNames(defaults);\n\n        for (var i = 0; i < keys.length; i++) {\n            var key = keys[i];\n            var value = Object.getOwnPropertyDescriptor(defaults, key);\n\n            if (value && value.configurable && obj[key] === undefined) {\n                Object.defineProperty(obj, key, value);\n            }\n        }\n\n        return obj;\n    }\n\n    function _defineProperty(obj, key, value) {\n        if (key in obj) {\n            Object.defineProperty(obj, key, {\n                value: value,\n                enumerable: true,\n                configurable: true,\n                writable: true,\n            });\n        } else {\n            obj[key] = value;\n        }\n\n        return obj;\n    }\n\n    function _extends() {\n        _extends =\n            Object.assign ||\n            function(target) {\n                for (var i = 1; i < arguments.length; i++) {\n                    var source = arguments[i];\n\n                    for (var key in source) {\n                        if (Object.prototype.hasOwnProperty.call(source, key)) {\n                            target[key] = source[key];\n                        }\n                    }\n                }\n\n                return target;\n            };\n\n        return _extends.apply(this, arguments);\n    }\n\n    function _objectSpread(target) {\n        for (var i = 1; i < arguments.length; i++) {\n            var source = arguments[i] != null ? arguments[i] : {};\n            var ownKeys = Object.keys(source);\n\n            if (typeof Object.getOwnPropertySymbols === 'function') {\n                ownKeys = ownKeys.concat(\n                    Object.getOwnPropertySymbols(source).filter(function(sym) {\n                        return Object.getOwnPropertyDescriptor(source, sym).enumerable;\n                    })\n                );\n            }\n\n            ownKeys.forEach(function(key) {\n                _defineProperty(target, key, source[key]);\n            });\n        }\n\n        return target;\n    }\n\n    function ownKeys(object, enumerableOnly) {\n        var keys = Object.keys(object);\n\n        if (Object.getOwnPropertySymbols) {\n            var symbols = Object.getOwnPropertySymbols(object);\n            if (enumerableOnly)\n                symbols = symbols.filter(function(sym) {\n                    return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n                });\n            keys.push.apply(keys, symbols);\n        }\n\n        return keys;\n    }\n\n    function _objectSpread2(target) {\n        for (var i = 1; i < arguments.length; i++) {\n            var source = arguments[i] != null ? arguments[i] : {};\n\n            if (i % 2) {\n                ownKeys(source, true).forEach(function(key) {\n                    _defineProperty(target, key, source[key]);\n                });\n            } else if (Object.getOwnPropertyDescriptors) {\n                Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n            } else {\n                ownKeys(source).forEach(function(key) {\n                    Object.defineProperty(\n                        target,\n                        key,\n                        Object.getOwnPropertyDescriptor(source, key)\n                    );\n                });\n            }\n        }\n\n        return target;\n    }\n\n    function _inherits(subClass, superClass) {\n        if (typeof superClass !== 'function' && superClass !== null) {\n            throw new TypeError('Super expression must either be null or a function');\n        }\n\n        subClass.prototype = Object.create(superClass && superClass.prototype, {\n            constructor: {\n                value: subClass,\n                writable: true,\n                configurable: true,\n            },\n        });\n        if (superClass) _setPrototypeOf(subClass, superClass);\n    }\n\n    function _inheritsLoose(subClass, superClass) {\n        subClass.prototype = Object.create(superClass.prototype);\n        subClass.prototype.constructor = subClass;\n        subClass.__proto__ = superClass;\n    }\n\n    function _getPrototypeOf(o) {\n        _getPrototypeOf = Object.setPrototypeOf\n            ? Object.getPrototypeOf\n            : function _getPrototypeOf(o) {\n                  return o.__proto__ || Object.getPrototypeOf(o);\n              };\n        return _getPrototypeOf(o);\n    }\n\n    function _setPrototypeOf(o, p) {\n        _setPrototypeOf =\n            Object.setPrototypeOf ||\n            function _setPrototypeOf(o, p) {\n                o.__proto__ = p;\n                return o;\n            };\n\n        return _setPrototypeOf(o, p);\n    }\n\n    function isNativeReflectConstruct() {\n        if (typeof Reflect === 'undefined' || !Reflect.construct) return false;\n        if (Reflect.construct.sham) return false;\n        if (typeof Proxy === 'function') return true;\n\n        try {\n            Date.prototype.toString.call(Reflect.construct(Date, [], function() {}));\n            return true;\n        } catch (e) {\n            return false;\n        }\n    }\n\n    function _construct(Parent, args, Class) {\n        if (isNativeReflectConstruct()) {\n            _construct = Reflect.construct;\n        } else {\n            _construct = function _construct(Parent, args, Class) {\n                var a = [null];\n                a.push.apply(a, args);\n                var Constructor = Function.bind.apply(Parent, a);\n                var instance = new Constructor();\n                if (Class) _setPrototypeOf(instance, Class.prototype);\n                return instance;\n            };\n        }\n\n        return _construct.apply(null, arguments);\n    }\n\n    function _isNativeFunction(fn) {\n        return Function.toString.call(fn).indexOf('[native code]') !== -1;\n    }\n\n    function _wrapNativeSuper(Class) {\n        var _cache = typeof Map === 'function' ? new Map() : undefined;\n\n        _wrapNativeSuper = function _wrapNativeSuper(Class) {\n            if (Class === null || !_isNativeFunction(Class)) return Class;\n\n            if (typeof Class !== 'function') {\n                throw new TypeError('Super expression must either be null or a function');\n            }\n\n            if (typeof _cache !== 'undefined') {\n                if (_cache.has(Class)) return _cache.get(Class);\n\n                _cache.set(Class, Wrapper);\n            }\n\n            function Wrapper() {\n                return _construct(Class, arguments, _getPrototypeOf(this).constructor);\n            }\n\n            Wrapper.prototype = Object.create(Class.prototype, {\n                constructor: {\n                    value: Wrapper,\n                    enumerable: false,\n                    writable: true,\n                    configurable: true,\n                },\n            });\n            return _setPrototypeOf(Wrapper, Class);\n        };\n\n        return _wrapNativeSuper(Class);\n    }\n\n    function _instanceof(left, right) {\n        if (right != null && typeof Symbol !== 'undefined' && right[Symbol.hasInstance]) {\n            return !!right[Symbol.hasInstance](left);\n        } else {\n            return left instanceof right;\n        }\n    }\n\n    function _interopRequireDefault(obj) {\n        return obj && obj.__esModule\n            ? obj\n            : {\n                  default: obj,\n              };\n    }\n\n    function _interopRequireWildcard(obj) {\n        if (obj && obj.__esModule) {\n            return obj;\n        } else {\n            var newObj = {};\n\n            if (obj != null) {\n                for (var key in obj) {\n                    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n                        var desc =\n                            Object.defineProperty && Object.getOwnPropertyDescriptor\n                                ? Object.getOwnPropertyDescriptor(obj, key)\n                                : {};\n\n                        if (desc.get || desc.set) {\n                            Object.defineProperty(newObj, key, desc);\n                        } else {\n                            newObj[key] = obj[key];\n                        }\n                    }\n                }\n            }\n\n            newObj.default = obj;\n            return newObj;\n        }\n    }\n\n    function _newArrowCheck(innerThis, boundThis) {\n        if (innerThis !== boundThis) {\n            throw new TypeError('Cannot instantiate an arrow function');\n        }\n    }\n\n    function _objectDestructuringEmpty(obj) {\n        if (obj == null) throw new TypeError('Cannot destructure undefined');\n    }\n\n    function _objectWithoutPropertiesLoose(source, excluded) {\n        if (source == null) return {};\n        var target = {};\n        var sourceKeys = Object.keys(source);\n        var key, i;\n\n        for (i = 0; i < sourceKeys.length; i++) {\n            key = sourceKeys[i];\n            if (excluded.indexOf(key) >= 0) continue;\n            target[key] = source[key];\n        }\n\n        return target;\n    }\n\n    function _objectWithoutProperties(source, excluded) {\n        if (source == null) return {};\n\n        var target = _objectWithoutPropertiesLoose(source, excluded);\n\n        var key, i;\n\n        if (Object.getOwnPropertySymbols) {\n            var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n\n            for (i = 0; i < sourceSymbolKeys.length; i++) {\n                key = sourceSymbolKeys[i];\n                if (excluded.indexOf(key) >= 0) continue;\n                if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n                target[key] = source[key];\n            }\n        }\n\n        return target;\n    }\n\n    function _assertThisInitialized(self) {\n        if (self === void 0) {\n            throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n        }\n\n        return self;\n    }\n\n    function _possibleConstructorReturn(self, call) {\n        if (call && (typeof call === 'object' || typeof call === 'function')) {\n            return call;\n        }\n\n        return _assertThisInitialized(self);\n    }\n\n    function _superPropBase(object, property) {\n        while (!Object.prototype.hasOwnProperty.call(object, property)) {\n            object = _getPrototypeOf(object);\n            if (object === null) break;\n        }\n\n        return object;\n    }\n\n    function _get(target, property, receiver) {\n        if (typeof Reflect !== 'undefined' && Reflect.get) {\n            _get = Reflect.get;\n        } else {\n            _get = function _get(target, property, receiver) {\n                var base = _superPropBase(target, property);\n\n                if (!base) return;\n                var desc = Object.getOwnPropertyDescriptor(base, property);\n\n                if (desc.get) {\n                    return desc.get.call(receiver);\n                }\n\n                return desc.value;\n            };\n        }\n\n        return _get(target, property, receiver || target);\n    }\n\n    function set(target, property, value, receiver) {\n        if (typeof Reflect !== 'undefined' && Reflect.set) {\n            set = Reflect.set;\n        } else {\n            set = function set(target, property, value, receiver) {\n                var base = _superPropBase(target, property);\n\n                var desc;\n\n                if (base) {\n                    desc = Object.getOwnPropertyDescriptor(base, property);\n\n                    if (desc.set) {\n                        desc.set.call(receiver, value);\n                        return true;\n                    } else if (!desc.writable) {\n                        return false;\n                    }\n                }\n\n                desc = Object.getOwnPropertyDescriptor(receiver, property);\n\n                if (desc) {\n                    if (!desc.writable) {\n                        return false;\n                    }\n\n                    desc.value = value;\n                    Object.defineProperty(receiver, property, desc);\n                } else {\n                    _defineProperty(receiver, property, value);\n                }\n\n                return true;\n            };\n        }\n\n        return set(target, property, value, receiver);\n    }\n\n    function _set(target, property, value, receiver, isStrict) {\n        var s = set(target, property, value, receiver || target);\n\n        if (!s && isStrict) {\n            throw new Error('failed to set property');\n        }\n\n        return value;\n    }\n\n    function _taggedTemplateLiteral(strings, raw) {\n        if (!raw) {\n            raw = strings.slice(0);\n        }\n\n        return Object.freeze(\n            Object.defineProperties(strings, {\n                raw: {\n                    value: Object.freeze(raw),\n                },\n            })\n        );\n    }\n\n    function _taggedTemplateLiteralLoose(strings, raw) {\n        if (!raw) {\n            raw = strings.slice(0);\n        }\n\n        strings.raw = raw;\n        return strings;\n    }\n\n    function _temporalRef(val, name) {\n        if (val === _temporalUndefined) {\n            throw new ReferenceError(name + ' is not defined - temporal dead zone');\n        } else {\n            return val;\n        }\n    }\n\n    function _readOnlyError(name) {\n        throw new Error('\"' + name + '\" is read-only');\n    }\n\n    function _classNameTDZError(name) {\n        throw new Error('Class \"' + name + '\" cannot be referenced in computed property keys.');\n    }\n\n    var _temporalUndefined = {};\n\n    function _slicedToArray(arr, i) {\n        return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();\n    }\n\n    function _slicedToArrayLoose(arr, i) {\n        return _arrayWithHoles(arr) || _iterableToArrayLimitLoose(arr, i) || _nonIterableRest();\n    }\n\n    function _toArray(arr) {\n        return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest();\n    }\n\n    function _toConsumableArray(arr) {\n        return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n    }\n\n    function _arrayWithoutHoles(arr) {\n        if (Array.isArray(arr)) {\n            for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n            return arr2;\n        }\n    }\n\n    function _arrayWithHoles(arr) {\n        if (Array.isArray(arr)) return arr;\n    }\n\n    function _iterableToArray(iter) {\n        if (\n            Symbol.iterator in Object(iter) ||\n            Object.prototype.toString.call(iter) === '[object Arguments]'\n        )\n            return Array.from(iter);\n    }\n\n    function _iterableToArrayLimit(arr, i) {\n        var _arr = [];\n        var _n = true;\n        var _d = false;\n        var _e = undefined;\n\n        try {\n            for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {\n                _arr.push(_s.value);\n\n                if (i && _arr.length === i) break;\n            }\n        } catch (err) {\n            _d = true;\n            _e = err;\n        } finally {\n            try {\n                if (!_n && _i['return'] != null) _i['return']();\n            } finally {\n                if (_d) throw _e;\n            }\n        }\n\n        return _arr;\n    }\n\n    function _iterableToArrayLimitLoose(arr, i) {\n        var _arr = [];\n\n        for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done; ) {\n            _arr.push(_step.value);\n\n            if (i && _arr.length === i) break;\n        }\n\n        return _arr;\n    }\n\n    function _nonIterableSpread() {\n        throw new TypeError('Invalid attempt to spread non-iterable instance');\n    }\n\n    function _nonIterableRest() {\n        throw new TypeError('Invalid attempt to destructure non-iterable instance');\n    }\n\n    function _skipFirstGeneratorNext(fn) {\n        return function() {\n            var it = fn.apply(this, arguments);\n            it.next();\n            return it;\n        };\n    }\n\n    function _toPrimitive(input, hint) {\n        if (typeof input !== 'object' || input === null) return input;\n        var prim = input[Symbol.toPrimitive];\n\n        if (prim !== undefined) {\n            var res = prim.call(input, hint || 'default');\n            if (typeof res !== 'object') return res;\n            throw new TypeError('@@toPrimitive must return a primitive value.');\n        }\n\n        return (hint === 'string' ? String : Number)(input);\n    }\n\n    function _toPropertyKey(arg) {\n        var key = _toPrimitive(arg, 'string');\n\n        return typeof key === 'symbol' ? key : String(key);\n    }\n\n    function _initializerWarningHelper(descriptor, context) {\n        throw new Error(\n            'Decorating class property failed. Please ensure that ' +\n                'proposal-class-properties is enabled and set to use loose mode. ' +\n                'To use proposal-class-properties in spec mode with decorators, wait for ' +\n                'the next major version of decorators in stage 2.'\n        );\n    }\n\n    function _initializerDefineProperty(target, property, descriptor, context) {\n        if (!descriptor) return;\n        Object.defineProperty(target, property, {\n            enumerable: descriptor.enumerable,\n            configurable: descriptor.configurable,\n            writable: descriptor.writable,\n            value: descriptor.initializer ? descriptor.initializer.call(context) : void 0,\n        });\n    }\n\n    function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {\n        var desc = {};\n        Object.keys(descriptor).forEach(function(key) {\n            desc[key] = descriptor[key];\n        });\n        desc.enumerable = !!desc.enumerable;\n        desc.configurable = !!desc.configurable;\n\n        if ('value' in desc || desc.initializer) {\n            desc.writable = true;\n        }\n\n        desc = decorators\n            .slice()\n            .reverse()\n            .reduce(function(desc, decorator) {\n                return decorator(target, property, desc) || desc;\n            }, desc);\n\n        if (context && desc.initializer !== void 0) {\n            desc.value = desc.initializer ? desc.initializer.call(context) : void 0;\n            desc.initializer = undefined;\n        }\n\n        if (desc.initializer === void 0) {\n            Object.defineProperty(target, property, desc);\n            desc = null;\n        }\n\n        return desc;\n    }\n\n    var id = 0;\n\n    function _classPrivateFieldLooseKey(name) {\n        return '__private_' + id++ + '_' + name;\n    }\n\n    function _classPrivateFieldLooseBase(receiver, privateKey) {\n        if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) {\n            throw new TypeError('attempted to use private field on non-instance');\n        }\n\n        return receiver;\n    }\n\n    function _classPrivateFieldGet(receiver, privateMap) {\n        var descriptor = privateMap.get(receiver);\n\n        if (!descriptor) {\n            throw new TypeError('attempted to get private field on non-instance');\n        }\n\n        if (descriptor.get) {\n            return descriptor.get.call(receiver);\n        }\n\n        return descriptor.value;\n    }\n\n    function _classPrivateFieldSet(receiver, privateMap, value) {\n        var descriptor = privateMap.get(receiver);\n\n        if (!descriptor) {\n            throw new TypeError('attempted to set private field on non-instance');\n        }\n\n        if (descriptor.set) {\n            descriptor.set.call(receiver, value);\n        } else {\n            if (!descriptor.writable) {\n                throw new TypeError('attempted to set read only private field');\n            }\n\n            descriptor.value = value;\n        }\n\n        return value;\n    }\n\n    function _classPrivateFieldDestructureSet(receiver, privateMap) {\n        if (!privateMap.has(receiver)) {\n            throw new TypeError('attempted to set private field on non-instance');\n        }\n\n        var descriptor = privateMap.get(receiver);\n\n        if (descriptor.set) {\n            if (!('__destrObj' in descriptor)) {\n                descriptor.__destrObj = {\n                    set value(v) {\n                        descriptor.set.call(receiver, v);\n                    },\n                };\n            }\n\n            return descriptor.__destrObj;\n        } else {\n            if (!descriptor.writable) {\n                throw new TypeError('attempted to set read only private field');\n            }\n\n            return descriptor;\n        }\n    }\n\n    function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {\n        if (receiver !== classConstructor) {\n            throw new TypeError('Private static access of wrong provenance');\n        }\n\n        return descriptor.value;\n    }\n\n    function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) {\n        if (receiver !== classConstructor) {\n            throw new TypeError('Private static access of wrong provenance');\n        }\n\n        if (!descriptor.writable) {\n            throw new TypeError('attempted to set read only private field');\n        }\n\n        descriptor.value = value;\n        return value;\n    }\n\n    function _classStaticPrivateMethodGet(receiver, classConstructor, method) {\n        if (receiver !== classConstructor) {\n            throw new TypeError('Private static access of wrong provenance');\n        }\n\n        return method;\n    }\n\n    function _classStaticPrivateMethodSet() {\n        throw new TypeError('attempted to set read only static private field');\n    }\n\n    function _decorate(decorators, factory, superClass, mixins) {\n        var api = _getDecoratorsApi();\n\n        if (mixins) {\n            for (var i = 0; i < mixins.length; i++) {\n                api = mixins[i](api);\n            }\n        }\n\n        var r = factory(function initialize(O) {\n            api.initializeInstanceElements(O, decorated.elements);\n        }, superClass);\n        var decorated = api.decorateClass(\n            _coalesceClassElements(r.d.map(_createElementDescriptor)),\n            decorators\n        );\n        api.initializeClassElements(r.F, decorated.elements);\n        return api.runClassFinishers(r.F, decorated.finishers);\n    }\n\n    function _getDecoratorsApi() {\n        _getDecoratorsApi = function() {\n            return api;\n        };\n\n        var api = {\n            elementsDefinitionOrder: [['method'], ['field']],\n            initializeInstanceElements: function(O, elements) {\n                ['method', 'field'].forEach(function(kind) {\n                    elements.forEach(function(element) {\n                        if (element.kind === kind && element.placement === 'own') {\n                            this.defineClassElement(O, element);\n                        }\n                    }, this);\n                }, this);\n            },\n            initializeClassElements: function(F, elements) {\n                var proto = F.prototype;\n                ['method', 'field'].forEach(function(kind) {\n                    elements.forEach(function(element) {\n                        var placement = element.placement;\n\n                        if (\n                            element.kind === kind &&\n                            (placement === 'static' || placement === 'prototype')\n                        ) {\n                            var receiver = placement === 'static' ? F : proto;\n                            this.defineClassElement(receiver, element);\n                        }\n                    }, this);\n                }, this);\n            },\n            defineClassElement: function(receiver, element) {\n                var descriptor = element.descriptor;\n\n                if (element.kind === 'field') {\n                    var initializer = element.initializer;\n                    descriptor = {\n                        enumerable: descriptor.enumerable,\n                        writable: descriptor.writable,\n                        configurable: descriptor.configurable,\n                        value: initializer === void 0 ? void 0 : initializer.call(receiver),\n                    };\n                }\n\n                Object.defineProperty(receiver, element.key, descriptor);\n            },\n            decorateClass: function(elements, decorators) {\n                var newElements = [];\n                var finishers = [];\n                var placements = {\n                    static: [],\n                    prototype: [],\n                    own: [],\n                };\n                elements.forEach(function(element) {\n                    this.addElementPlacement(element, placements);\n                }, this);\n                elements.forEach(function(element) {\n                    if (!_hasDecorators(element)) return newElements.push(element);\n                    var elementFinishersExtras = this.decorateElement(element, placements);\n                    newElements.push(elementFinishersExtras.element);\n                    newElements.push.apply(newElements, elementFinishersExtras.extras);\n                    finishers.push.apply(finishers, elementFinishersExtras.finishers);\n                }, this);\n\n                if (!decorators) {\n                    return {\n                        elements: newElements,\n                        finishers: finishers,\n                    };\n                }\n\n                var result = this.decorateConstructor(newElements, decorators);\n                finishers.push.apply(finishers, result.finishers);\n                result.finishers = finishers;\n                return result;\n            },\n            addElementPlacement: function(element, placements, silent) {\n                var keys = placements[element.placement];\n\n                if (!silent && keys.indexOf(element.key) !== -1) {\n                    throw new TypeError('Duplicated element (' + element.key + ')');\n                }\n\n                keys.push(element.key);\n            },\n            decorateElement: function(element, placements) {\n                var extras = [];\n                var finishers = [];\n\n                for (var decorators = element.decorators, i = decorators.length - 1; i >= 0; i--) {\n                    var keys = placements[element.placement];\n                    keys.splice(keys.indexOf(element.key), 1);\n                    var elementObject = this.fromElementDescriptor(element);\n                    var elementFinisherExtras = this.toElementFinisherExtras(\n                        (0, decorators[i])(elementObject) || elementObject\n                    );\n                    element = elementFinisherExtras.element;\n                    this.addElementPlacement(element, placements);\n\n                    if (elementFinisherExtras.finisher) {\n                        finishers.push(elementFinisherExtras.finisher);\n                    }\n\n                    var newExtras = elementFinisherExtras.extras;\n\n                    if (newExtras) {\n                        for (var j = 0; j < newExtras.length; j++) {\n                            this.addElementPlacement(newExtras[j], placements);\n                        }\n\n                        extras.push.apply(extras, newExtras);\n                    }\n                }\n\n                return {\n                    element: element,\n                    finishers: finishers,\n                    extras: extras,\n                };\n            },\n            decorateConstructor: function(elements, decorators) {\n                var finishers = [];\n\n                for (var i = decorators.length - 1; i >= 0; i--) {\n                    var obj = this.fromClassDescriptor(elements);\n                    var elementsAndFinisher = this.toClassDescriptor(\n                        (0, decorators[i])(obj) || obj\n                    );\n\n                    if (elementsAndFinisher.finisher !== undefined) {\n                        finishers.push(elementsAndFinisher.finisher);\n                    }\n\n                    if (elementsAndFinisher.elements !== undefined) {\n                        elements = elementsAndFinisher.elements;\n\n                        for (var j = 0; j < elements.length - 1; j++) {\n                            for (var k = j + 1; k < elements.length; k++) {\n                                if (\n                                    elements[j].key === elements[k].key &&\n                                    elements[j].placement === elements[k].placement\n                                ) {\n                                    throw new TypeError(\n                                        'Duplicated element (' + elements[j].key + ')'\n                                    );\n                                }\n                            }\n                        }\n                    }\n                }\n\n                return {\n                    elements: elements,\n                    finishers: finishers,\n                };\n            },\n            fromElementDescriptor: function(element) {\n                var obj = {\n                    kind: element.kind,\n                    key: element.key,\n                    placement: element.placement,\n                    descriptor: element.descriptor,\n                };\n                var desc = {\n                    value: 'Descriptor',\n                    configurable: true,\n                };\n                Object.defineProperty(obj, Symbol.toStringTag, desc);\n                if (element.kind === 'field') obj.initializer = element.initializer;\n                return obj;\n            },\n            toElementDescriptors: function(elementObjects) {\n                if (elementObjects === undefined) return;\n                return _toArray(elementObjects).map(function(elementObject) {\n                    var element = this.toElementDescriptor(elementObject);\n                    this.disallowProperty(elementObject, 'finisher', 'An element descriptor');\n                    this.disallowProperty(elementObject, 'extras', 'An element descriptor');\n                    return element;\n                }, this);\n            },\n            toElementDescriptor: function(elementObject) {\n                var kind = String(elementObject.kind);\n\n                if (kind !== 'method' && kind !== 'field') {\n                    throw new TypeError(\n                        'An element descriptor\\'s .kind property must be either \"method\" or' +\n                            ' \"field\", but a decorator created an element descriptor with' +\n                            ' .kind \"' +\n                            kind +\n                            '\"'\n                    );\n                }\n\n                var key = _toPropertyKey(elementObject.key);\n\n                var placement = String(elementObject.placement);\n\n                if (placement !== 'static' && placement !== 'prototype' && placement !== 'own') {\n                    throw new TypeError(\n                        'An element descriptor\\'s .placement property must be one of \"static\",' +\n                            ' \"prototype\" or \"own\", but a decorator created an element descriptor' +\n                            ' with .placement \"' +\n                            placement +\n                            '\"'\n                    );\n                }\n\n                var descriptor = elementObject.descriptor;\n                this.disallowProperty(elementObject, 'elements', 'An element descriptor');\n                var element = {\n                    kind: kind,\n                    key: key,\n                    placement: placement,\n                    descriptor: Object.assign({}, descriptor),\n                };\n\n                if (kind !== 'field') {\n                    this.disallowProperty(elementObject, 'initializer', 'A method descriptor');\n                } else {\n                    this.disallowProperty(\n                        descriptor,\n                        'get',\n                        'The property descriptor of a field descriptor'\n                    );\n                    this.disallowProperty(\n                        descriptor,\n                        'set',\n                        'The property descriptor of a field descriptor'\n                    );\n                    this.disallowProperty(\n                        descriptor,\n                        'value',\n                        'The property descriptor of a field descriptor'\n                    );\n                    element.initializer = elementObject.initializer;\n                }\n\n                return element;\n            },\n            toElementFinisherExtras: function(elementObject) {\n                var element = this.toElementDescriptor(elementObject);\n\n                var finisher = _optionalCallableProperty(elementObject, 'finisher');\n\n                var extras = this.toElementDescriptors(elementObject.extras);\n                return {\n                    element: element,\n                    finisher: finisher,\n                    extras: extras,\n                };\n            },\n            fromClassDescriptor: function(elements) {\n                var obj = {\n                    kind: 'class',\n                    elements: elements.map(this.fromElementDescriptor, this),\n                };\n                var desc = {\n                    value: 'Descriptor',\n                    configurable: true,\n                };\n                Object.defineProperty(obj, Symbol.toStringTag, desc);\n                return obj;\n            },\n            toClassDescriptor: function(obj) {\n                var kind = String(obj.kind);\n\n                if (kind !== 'class') {\n                    throw new TypeError(\n                        'A class descriptor\\'s .kind property must be \"class\", but a decorator' +\n                            ' created a class descriptor with .kind \"' +\n                            kind +\n                            '\"'\n                    );\n                }\n\n                this.disallowProperty(obj, 'key', 'A class descriptor');\n                this.disallowProperty(obj, 'placement', 'A class descriptor');\n                this.disallowProperty(obj, 'descriptor', 'A class descriptor');\n                this.disallowProperty(obj, 'initializer', 'A class descriptor');\n                this.disallowProperty(obj, 'extras', 'A class descriptor');\n\n                var finisher = _optionalCallableProperty(obj, 'finisher');\n\n                var elements = this.toElementDescriptors(obj.elements);\n                return {\n                    elements: elements,\n                    finisher: finisher,\n                };\n            },\n            runClassFinishers: function(constructor, finishers) {\n                for (var i = 0; i < finishers.length; i++) {\n                    var newConstructor = (0, finishers[i])(constructor);\n\n                    if (newConstructor !== undefined) {\n                        if (typeof newConstructor !== 'function') {\n                            throw new TypeError('Finishers must return a constructor.');\n                        }\n\n                        constructor = newConstructor;\n                    }\n                }\n\n                return constructor;\n            },\n            disallowProperty: function(obj, name, objectType) {\n                if (obj[name] !== undefined) {\n                    throw new TypeError(objectType + \" can't have a .\" + name + ' property.');\n                }\n            },\n        };\n        return api;\n    }\n\n    function _createElementDescriptor(def) {\n        var key = _toPropertyKey(def.key);\n\n        var descriptor;\n\n        if (def.kind === 'method') {\n            descriptor = {\n                value: def.value,\n                writable: true,\n                configurable: true,\n                enumerable: false,\n            };\n        } else if (def.kind === 'get') {\n            descriptor = {\n                get: def.value,\n                configurable: true,\n                enumerable: false,\n            };\n        } else if (def.kind === 'set') {\n            descriptor = {\n                set: def.value,\n                configurable: true,\n                enumerable: false,\n            };\n        } else if (def.kind === 'field') {\n            descriptor = {\n                configurable: true,\n                writable: true,\n                enumerable: true,\n            };\n        }\n\n        var element = {\n            kind: def.kind === 'field' ? 'field' : 'method',\n            key: key,\n            placement: def.static ? 'static' : def.kind === 'field' ? 'own' : 'prototype',\n            descriptor: descriptor,\n        };\n        if (def.decorators) element.decorators = def.decorators;\n        if (def.kind === 'field') element.initializer = def.value;\n        return element;\n    }\n\n    function _coalesceGetterSetter(element, other) {\n        if (element.descriptor.get !== undefined) {\n            other.descriptor.get = element.descriptor.get;\n        } else {\n            other.descriptor.set = element.descriptor.set;\n        }\n    }\n\n    function _coalesceClassElements(elements) {\n        var newElements = [];\n\n        var isSameElement = function(other) {\n            return (\n                other.kind === 'method' &&\n                other.key === element.key &&\n                other.placement === element.placement\n            );\n        };\n\n        for (var i = 0; i < elements.length; i++) {\n            var element = elements[i];\n            var other;\n\n            if (element.kind === 'method' && (other = newElements.find(isSameElement))) {\n                if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) {\n                    if (_hasDecorators(element) || _hasDecorators(other)) {\n                        throw new ReferenceError(\n                            'Duplicated methods (' + element.key + \") can't be decorated.\"\n                        );\n                    }\n\n                    other.descriptor = element.descriptor;\n                } else {\n                    if (_hasDecorators(element)) {\n                        if (_hasDecorators(other)) {\n                            throw new ReferenceError(\n                                \"Decorators can't be placed on different accessors with for \" +\n                                    'the same property (' +\n                                    element.key +\n                                    ').'\n                            );\n                        }\n\n                        other.decorators = element.decorators;\n                    }\n\n                    _coalesceGetterSetter(element, other);\n                }\n            } else {\n                newElements.push(element);\n            }\n        }\n\n        return newElements;\n    }\n\n    function _hasDecorators(element) {\n        return element.decorators && element.decorators.length;\n    }\n\n    function _isDataDescriptor(desc) {\n        return desc !== undefined && !(desc.value === undefined && desc.writable === undefined);\n    }\n\n    function _optionalCallableProperty(obj, name) {\n        var value = obj[name];\n\n        if (value !== undefined && typeof value !== 'function') {\n            throw new TypeError(\"Expected '\" + name + \"' to be a function\");\n        }\n\n        return value;\n    }\n\n    function _classPrivateMethodGet(receiver, privateSet, fn) {\n        if (!privateSet.has(receiver)) {\n            throw new TypeError('attempted to get private field on non-instance');\n        }\n\n        return fn;\n    }\n\n    function _classPrivateMethodSet() {\n        throw new TypeError('attempted to reassign private method');\n    }\n\n    function _wrapRegExp(re, groups) {\n        _wrapRegExp = function(re, groups) {\n            return new BabelRegExp(re, groups);\n        };\n\n        var _RegExp = _wrapNativeSuper(RegExp);\n\n        var _super = RegExp.prototype;\n\n        var _groups = new WeakMap();\n\n        function BabelRegExp(re, groups) {\n            var _this = _RegExp.call(this, re);\n\n            _groups.set(_this, groups);\n\n            return _this;\n        }\n\n        _inherits(BabelRegExp, _RegExp);\n\n        BabelRegExp.prototype.exec = function(str) {\n            var result = _super.exec.call(this, str);\n\n            if (result) result.groups = buildGroups(result, this);\n            return result;\n        };\n\n        BabelRegExp.prototype[Symbol.replace] = function(str, substitution) {\n            if (typeof substitution === 'string') {\n                var groups = _groups.get(this);\n\n                return _super[Symbol.replace].call(\n                    this,\n                    str,\n                    substitution.replace(/\\$<([^>]+)>/g, function(_, name) {\n                        return '$' + groups[name];\n                    })\n                );\n            } else if (typeof substitution === 'function') {\n                var _this = this;\n\n                return _super[Symbol.replace].call(this, str, function() {\n                    var args = [];\n                    args.push.apply(args, arguments);\n\n                    if (typeof args[args.length - 1] !== 'object') {\n                        args.push(buildGroups(args, _this));\n                    }\n\n                    return substitution.apply(this, args);\n                });\n            } else {\n                return _super[Symbol.replace].call(this, str, substitution);\n            }\n        };\n\n        function buildGroups(result, re) {\n            var g = _groups.get(re);\n\n            return Object.keys(g).reduce(function(groups, name) {\n                groups[name] = result[g[name]];\n                return groups;\n            }, Object.create(null));\n        }\n\n        return _wrapRegExp.apply(this, arguments);\n    }\n\n    var arrayRemove = function arrayRemove(arr, index) {\n        return arr.splice(index, 1);\n    };\n\n    var run = function run(cb, sync) {\n        if (sync) {\n            cb();\n        } else if (document.hidden) {\n            Promise.resolve(1).then(cb);\n        } else {\n            setTimeout(cb, 0);\n        }\n    };\n\n    var on = function on() {\n        var listeners = [];\n        var off = function off(event, cb) {\n            arrayRemove(\n                listeners,\n                listeners.findIndex(function(listener) {\n                    return listener.event === event && (listener.cb === cb || !cb);\n                })\n            );\n        };\n        var _fire = function fire(event, args, sync) {\n            listeners\n                .filter(function(listener) {\n                    return listener.event === event;\n                })\n                .map(function(listener) {\n                    return listener.cb;\n                })\n                .forEach(function(cb) {\n                    return run(function() {\n                        return cb.apply(void 0, _toConsumableArray(args));\n                    }, sync);\n                });\n        };\n        return {\n            fireSync: function fireSync(event) {\n                for (\n                    var _len = arguments.length,\n                        args = new Array(_len > 1 ? _len - 1 : 0),\n                        _key = 1;\n                    _key < _len;\n                    _key++\n                ) {\n                    args[_key - 1] = arguments[_key];\n                }\n                _fire(event, args, true);\n            },\n            fire: function fire(event) {\n                for (\n                    var _len2 = arguments.length,\n                        args = new Array(_len2 > 1 ? _len2 - 1 : 0),\n                        _key2 = 1;\n                    _key2 < _len2;\n                    _key2++\n                ) {\n                    args[_key2 - 1] = arguments[_key2];\n                }\n                _fire(event, args, false);\n            },\n            on: function on(event, cb) {\n                listeners.push({ event: event, cb: cb });\n            },\n            onOnce: function onOnce(event, _cb) {\n                listeners.push({\n                    event: event,\n                    cb: function cb() {\n                        off(event, _cb);\n                        _cb.apply(void 0, arguments);\n                    },\n                });\n            },\n            off: off,\n        };\n    };\n\n    var copyObjectPropertiesToObject = function copyObjectPropertiesToObject(\n        src,\n        target,\n        excluded\n    ) {\n        Object.getOwnPropertyNames(src)\n            .filter(function(property) {\n                return !excluded.includes(property);\n            })\n            .forEach(function(key) {\n                return Object.defineProperty(\n                    target,\n                    key,\n                    Object.getOwnPropertyDescriptor(src, key)\n                );\n            });\n    };\n\n    var PRIVATE = [\n        'fire',\n        'process',\n        'revert',\n        'load',\n        'on',\n        'off',\n        'onOnce',\n        'retryLoad',\n        'extend',\n        'archive',\n        'archived',\n        'release',\n        'released',\n        'requestProcessing',\n        'freeze',\n    ];\n\n    var createItemAPI = function createItemAPI(item) {\n        var api = {};\n        copyObjectPropertiesToObject(item, api, PRIVATE);\n        return api;\n    };\n\n    var removeReleasedItems = function removeReleasedItems(items) {\n        items.forEach(function(item, index) {\n            if (item.released) {\n                arrayRemove(items, index);\n            }\n        });\n    };\n\n    var ItemStatus = {\n        INIT: 1,\n        IDLE: 2,\n        PROCESSING_QUEUED: 9,\n        PROCESSING: 3,\n        PROCESSING_COMPLETE: 5,\n        PROCESSING_ERROR: 6,\n        PROCESSING_REVERT_ERROR: 10,\n        LOADING: 7,\n        LOAD_ERROR: 8,\n    };\n\n    var FileOrigin = {\n        INPUT: 1,\n        LIMBO: 2,\n        LOCAL: 3,\n    };\n\n    var getNonNumeric = function getNonNumeric(str) {\n        return /[^0-9]+/.exec(str);\n    };\n\n    var getDecimalSeparator = function getDecimalSeparator() {\n        return getNonNumeric((1.1).toLocaleString())[0];\n    };\n\n    var getThousandsSeparator = function getThousandsSeparator() {\n        // Added for browsers that do not return the thousands separator (happend on native browser Android 4.4.4)\n        // We check against the normal toString output and if they're the same return a comma when decimal separator is a dot\n        var decimalSeparator = getDecimalSeparator();\n        var thousandsStringWithSeparator = (1000.0).toLocaleString();\n        var thousandsStringWithoutSeparator = (1000.0).toString();\n        if (thousandsStringWithSeparator !== thousandsStringWithoutSeparator) {\n            return getNonNumeric(thousandsStringWithSeparator)[0];\n        }\n        return decimalSeparator === '.' ? ',' : '.';\n    };\n\n    var Type = {\n        BOOLEAN: 'boolean',\n        INT: 'int',\n        NUMBER: 'number',\n        STRING: 'string',\n        ARRAY: 'array',\n        OBJECT: 'object',\n        FUNCTION: 'function',\n        ACTION: 'action',\n        SERVER_API: 'serverapi',\n        REGEX: 'regex',\n    };\n\n    // all registered filters\n    var filters = [];\n\n    // loops over matching filters and passes options to each filter, returning the mapped results\n    var applyFilterChain = function applyFilterChain(key, value, utils) {\n        return new Promise(function(resolve, reject) {\n            // find matching filters for this key\n            var matchingFilters = filters\n                .filter(function(f) {\n                    return f.key === key;\n                })\n                .map(function(f) {\n                    return f.cb;\n                });\n\n            // resolve now\n            if (matchingFilters.length === 0) {\n                resolve(value);\n                return;\n            }\n\n            // first filter to kick things of\n            var initialFilter = matchingFilters.shift();\n\n            // chain filters\n            matchingFilters\n                .reduce(\n                    // loop over promises passing value to next promise\n                    function(current, next) {\n                        return current.then(function(value) {\n                            return next(value, utils);\n                        });\n                    },\n\n                    // call initial filter, will return a promise\n                    initialFilter(value, utils)\n\n                    // all executed\n                )\n                .then(function(value) {\n                    return resolve(value);\n                })\n                .catch(function(error) {\n                    return reject(error);\n                });\n        });\n    };\n\n    var applyFilters = function applyFilters(key, value, utils) {\n        return filters\n            .filter(function(f) {\n                return f.key === key;\n            })\n            .map(function(f) {\n                return f.cb(value, utils);\n            });\n    };\n\n    // adds a new filter to the list\n    var addFilter = function addFilter(key, cb) {\n        return filters.push({ key: key, cb: cb });\n    };\n\n    var extendDefaultOptions = function extendDefaultOptions(additionalOptions) {\n        return Object.assign(defaultOptions, additionalOptions);\n    };\n\n    var getOptions = function getOptions() {\n        return Object.assign({}, defaultOptions);\n    };\n\n    var setOptions = function setOptions(opts) {\n        forin(opts, function(key, value) {\n            // key does not exist, so this option cannot be set\n            if (!defaultOptions[key]) {\n                return;\n            }\n            defaultOptions[key][0] = getValueByType(\n                value,\n                defaultOptions[key][0],\n                defaultOptions[key][1]\n            );\n        });\n    };\n\n    // default options on app\n    var defaultOptions = {\n        // the id to add to the root element\n        id: [null, Type.STRING],\n\n        // input field name to use\n        name: ['filepond', Type.STRING],\n\n        // disable the field\n        disabled: [false, Type.BOOLEAN],\n\n        // classname to put on wrapper\n        className: [null, Type.STRING],\n\n        // is the field required\n        required: [false, Type.BOOLEAN],\n\n        // Allow media capture when value is set\n        captureMethod: [null, Type.STRING],\n        // - \"camera\", \"microphone\" or \"camcorder\",\n        // - Does not work with multiple on apple devices\n        // - If set, acceptedFileTypes must be made to match with media wildcard \"image/*\", \"audio/*\" or \"video/*\"\n\n        // sync `acceptedFileTypes` property with `accept` attribute\n        allowSyncAcceptAttribute: [true, Type.BOOLEAN],\n\n        // Feature toggles\n        allowDrop: [true, Type.BOOLEAN], // Allow dropping of files\n        allowBrowse: [true, Type.BOOLEAN], // Allow browsing the file system\n        allowPaste: [true, Type.BOOLEAN], // Allow pasting files\n        allowMultiple: [false, Type.BOOLEAN], // Allow multiple files (disabled by default, as multiple attribute is also required on input to allow multiple)\n        allowReplace: [true, Type.BOOLEAN], // Allow dropping a file on other file to replace it (only works when multiple is set to false)\n        allowRevert: [true, Type.BOOLEAN], // Allows user to revert file upload\n        allowRemove: [true, Type.BOOLEAN], // Allow user to remove a file\n        allowProcess: [true, Type.BOOLEAN], // Allows user to process a file, when set to false, this removes the file upload button\n        allowReorder: [false, Type.BOOLEAN], // Allow reordering of files\n        allowDirectoriesOnly: [false, Type.BOOLEAN], // Allow only selecting directories with browse (no support for filtering dnd at this point)\n\n        // Try store file if `server` not set\n        storeAsFile: [false, Type.BOOLEAN],\n\n        // Revert mode\n        forceRevert: [false, Type.BOOLEAN], // Set to 'force' to require the file to be reverted before removal\n\n        // Input requirements\n        maxFiles: [null, Type.INT], // Max number of files\n        checkValidity: [false, Type.BOOLEAN], // Enables custom validity messages\n\n        // Where to put file\n        itemInsertLocationFreedom: [true, Type.BOOLEAN], // Set to false to always add items to begin or end of list\n        itemInsertLocation: ['before', Type.STRING], // Default index in list to add items that have been dropped at the top of the list\n        itemInsertInterval: [75, Type.INT],\n\n        // Drag 'n Drop related\n        dropOnPage: [false, Type.BOOLEAN], // Allow dropping of files anywhere on page (prevents browser from opening file if dropped outside of Up)\n        dropOnElement: [true, Type.BOOLEAN], // Drop needs to happen on element (set to false to also load drops outside of Up)\n        dropValidation: [false, Type.BOOLEAN], // Enable or disable validating files on drop\n        ignoredFiles: [['.ds_store', 'thumbs.db', 'desktop.ini'], Type.ARRAY],\n\n        // Upload related\n        instantUpload: [true, Type.BOOLEAN], // Should upload files immediately on drop\n        maxParallelUploads: [2, Type.INT], // Maximum files to upload in parallel\n        allowMinimumUploadDuration: [true, Type.BOOLEAN], // if true uploads take at least 750 ms, this ensures the user sees the upload progress giving trust the upload actually happened\n\n        // Chunks\n        chunkUploads: [false, Type.BOOLEAN], // Enable chunked uploads\n        chunkForce: [false, Type.BOOLEAN], // Force use of chunk uploads even for files smaller than chunk size\n        chunkSize: [5000000, Type.INT], // Size of chunks (5MB default)\n        chunkRetryDelays: [[500, 1000, 3000], Type.ARRAY], // Amount of times to retry upload of a chunk when it fails\n\n        // The server api end points to use for uploading (see docs)\n        server: [null, Type.SERVER_API],\n\n        // File size calculations, can set to 1024, this is only used for display, properties use file size base 1000\n        fileSizeBase: [1000, Type.INT],\n\n        // Labels and status messages\n        labelFileSizeBytes: ['bytes', Type.STRING],\n        labelFileSizeKilobytes: ['KB', Type.STRING],\n        labelFileSizeMegabytes: ['MB', Type.STRING],\n        labelFileSizeGigabytes: ['GB', Type.STRING],\n\n        labelDecimalSeparator: [getDecimalSeparator(), Type.STRING], // Default is locale separator\n        labelThousandsSeparator: [getThousandsSeparator(), Type.STRING], // Default is locale separator\n\n        labelIdle: [\n            'Drag & Drop your files or <span class=\"filepond--label-action\">Browse</span>',\n            Type.STRING,\n        ],\n\n        labelInvalidField: ['Field contains invalid files', Type.STRING],\n        labelFileWaitingForSize: ['Waiting for size', Type.STRING],\n        labelFileSizeNotAvailable: ['Size not available', Type.STRING],\n        labelFileCountSingular: ['file in list', Type.STRING],\n        labelFileCountPlural: ['files in list', Type.STRING],\n        labelFileLoading: ['Loading', Type.STRING],\n        labelFileAdded: ['Added', Type.STRING], // assistive only\n        labelFileLoadError: ['Error during load', Type.STRING],\n        labelFileRemoved: ['Removed', Type.STRING], // assistive only\n        labelFileRemoveError: ['Error during remove', Type.STRING],\n        labelFileProcessing: ['Uploading', Type.STRING],\n        labelFileProcessingComplete: ['Upload complete', Type.STRING],\n        labelFileProcessingAborted: ['Upload cancelled', Type.STRING],\n        labelFileProcessingError: ['Error during upload', Type.STRING],\n        labelFileProcessingRevertError: ['Error during revert', Type.STRING],\n\n        labelTapToCancel: ['tap to cancel', Type.STRING],\n        labelTapToRetry: ['tap to retry', Type.STRING],\n        labelTapToUndo: ['tap to undo', Type.STRING],\n\n        labelButtonRemoveItem: ['Remove', Type.STRING],\n        labelButtonAbortItemLoad: ['Abort', Type.STRING],\n        labelButtonRetryItemLoad: ['Retry', Type.STRING],\n        labelButtonAbortItemProcessing: ['Cancel', Type.STRING],\n        labelButtonUndoItemProcessing: ['Undo', Type.STRING],\n        labelButtonRetryItemProcessing: ['Retry', Type.STRING],\n        labelButtonProcessItem: ['Upload', Type.STRING],\n\n        // make sure width and height plus viewpox are even numbers so icons are nicely centered\n        iconRemove: [\n            '<svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M11.586 13l-2.293 2.293a1 1 0 0 0 1.414 1.414L13 14.414l2.293 2.293a1 1 0 0 0 1.414-1.414L14.414 13l2.293-2.293a1 1 0 0 0-1.414-1.414L13 11.586l-2.293-2.293a1 1 0 0 0-1.414 1.414L11.586 13z\" fill=\"currentColor\" fill-rule=\"nonzero\"/></svg>',\n            Type.STRING,\n        ],\n\n        iconProcess: [\n            '<svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M14 10.414v3.585a1 1 0 0 1-2 0v-3.585l-1.293 1.293a1 1 0 0 1-1.414-1.415l3-3a1 1 0 0 1 1.414 0l3 3a1 1 0 0 1-1.414 1.415L14 10.414zM9 18a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2H9z\" fill=\"currentColor\" fill-rule=\"evenodd\"/></svg>',\n            Type.STRING,\n        ],\n\n        iconRetry: [\n            '<svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.81 9.185l-.038.02A4.997 4.997 0 0 0 8 13.683a5 5 0 0 0 5 5 5 5 0 0 0 5-5 1 1 0 0 1 2 0A7 7 0 1 1 9.722 7.496l-.842-.21a.999.999 0 1 1 .484-1.94l3.23.806c.535.133.86.675.73 1.21l-.804 3.233a.997.997 0 0 1-1.21.73.997.997 0 0 1-.73-1.21l.23-.928v-.002z\" fill=\"currentColor\" fill-rule=\"nonzero\"/></svg>',\n            Type.STRING,\n        ],\n\n        iconUndo: [\n            '<svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.185 10.81l.02-.038A4.997 4.997 0 0 1 13.683 8a5 5 0 0 1 5 5 5 5 0 0 1-5 5 1 1 0 0 0 0 2A7 7 0 1 0 7.496 9.722l-.21-.842a.999.999 0 1 0-1.94.484l.806 3.23c.133.535.675.86 1.21.73l3.233-.803a.997.997 0 0 0 .73-1.21.997.997 0 0 0-1.21-.73l-.928.23-.002-.001z\" fill=\"currentColor\" fill-rule=\"nonzero\"/></svg>',\n            Type.STRING,\n        ],\n\n        iconDone: [\n            '<svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18.293 9.293a1 1 0 0 1 1.414 1.414l-7.002 7a1 1 0 0 1-1.414 0l-3.998-4a1 1 0 1 1 1.414-1.414L12 15.586l6.294-6.293z\" fill=\"currentColor\" fill-rule=\"nonzero\"/></svg>',\n            Type.STRING,\n        ],\n\n        // event handlers\n        oninit: [null, Type.FUNCTION],\n        onwarning: [null, Type.FUNCTION],\n        onerror: [null, Type.FUNCTION],\n        onactivatefile: [null, Type.FUNCTION],\n        oninitfile: [null, Type.FUNCTION],\n        onaddfilestart: [null, Type.FUNCTION],\n        onaddfileprogress: [null, Type.FUNCTION],\n        onaddfile: [null, Type.FUNCTION],\n        onprocessfilestart: [null, Type.FUNCTION],\n        onprocessfileprogress: [null, Type.FUNCTION],\n        onprocessfileabort: [null, Type.FUNCTION],\n        onprocessfilerevert: [null, Type.FUNCTION],\n        onprocessfile: [null, Type.FUNCTION],\n        onprocessfiles: [null, Type.FUNCTION],\n        onremovefile: [null, Type.FUNCTION],\n        onpreparefile: [null, Type.FUNCTION],\n        onupdatefiles: [null, Type.FUNCTION],\n        onreorderfiles: [null, Type.FUNCTION],\n\n        // hooks\n        beforeDropFile: [null, Type.FUNCTION],\n        beforeAddFile: [null, Type.FUNCTION],\n        beforeRemoveFile: [null, Type.FUNCTION],\n        beforePrepareFile: [null, Type.FUNCTION],\n\n        // styles\n        stylePanelLayout: [null, Type.STRING], // null 'integrated', 'compact', 'circle'\n        stylePanelAspectRatio: [null, Type.STRING], // null or '3:2' or 1\n        styleItemPanelAspectRatio: [null, Type.STRING],\n        styleButtonRemoveItemPosition: ['left', Type.STRING],\n        styleButtonProcessItemPosition: ['right', Type.STRING],\n        styleLoadIndicatorPosition: ['right', Type.STRING],\n        styleProgressIndicatorPosition: ['right', Type.STRING],\n        styleButtonRemoveItemAlign: [false, Type.BOOLEAN],\n\n        // custom initial files array\n        files: [[], Type.ARRAY],\n\n        // show support by displaying credits\n        credits: [['https://filepond.com', 'Powered by FilePond'], Type.ARRAY],\n    };\n\n    var getItemByQuery = function getItemByQuery(items, query) {\n        // just return first index\n        if (isEmpty(query)) {\n            return items[0] || null;\n        }\n\n        // query is index\n        if (isInt(query)) {\n            return items[query] || null;\n        }\n\n        // if query is item, get the id\n        if (typeof query === 'object') {\n            query = query.id;\n        }\n\n        // assume query is a string and return item by id\n        return (\n            items.find(function(item) {\n                return item.id === query;\n            }) || null\n        );\n    };\n\n    var getNumericAspectRatioFromString = function getNumericAspectRatioFromString(aspectRatio) {\n        if (isEmpty(aspectRatio)) {\n            return aspectRatio;\n        }\n        if (/:/.test(aspectRatio)) {\n            var parts = aspectRatio.split(':');\n            return parts[1] / parts[0];\n        }\n        return parseFloat(aspectRatio);\n    };\n\n    var getActiveItems = function getActiveItems(items) {\n        return items.filter(function(item) {\n            return !item.archived;\n        });\n    };\n\n    var Status = {\n        EMPTY: 0,\n        IDLE: 1, // waiting\n        ERROR: 2, // a file is in error state\n        BUSY: 3, // busy processing or loading\n        READY: 4, // all files uploaded\n    };\n\n    var res = null;\n    var canUpdateFileInput = function canUpdateFileInput() {\n        if (res === null) {\n            try {\n                var dataTransfer = new DataTransfer();\n                dataTransfer.items.add(new File(['hello world'], 'This_Works.txt'));\n                var el = document.createElement('input');\n                el.setAttribute('type', 'file');\n                el.files = dataTransfer.files;\n                res = el.files.length === 1;\n            } catch (err) {\n                res = false;\n            }\n        }\n        return res;\n    };\n\n    var ITEM_ERROR = [\n        ItemStatus.LOAD_ERROR,\n        ItemStatus.PROCESSING_ERROR,\n        ItemStatus.PROCESSING_REVERT_ERROR,\n    ];\n\n    var ITEM_BUSY = [\n        ItemStatus.LOADING,\n        ItemStatus.PROCESSING,\n        ItemStatus.PROCESSING_QUEUED,\n        ItemStatus.INIT,\n    ];\n\n    var ITEM_READY = [ItemStatus.PROCESSING_COMPLETE];\n\n    var isItemInErrorState = function isItemInErrorState(item) {\n        return ITEM_ERROR.includes(item.status);\n    };\n    var isItemInBusyState = function isItemInBusyState(item) {\n        return ITEM_BUSY.includes(item.status);\n    };\n    var isItemInReadyState = function isItemInReadyState(item) {\n        return ITEM_READY.includes(item.status);\n    };\n\n    var isAsync = function isAsync(state) {\n        return (\n            isObject(state.options.server) &&\n            (isObject(state.options.server.process) || isFunction(state.options.server.process))\n        );\n    };\n\n    var queries = function queries(state) {\n        return {\n            GET_STATUS: function GET_STATUS() {\n                var items = getActiveItems(state.items);\n                var EMPTY = Status.EMPTY,\n                    ERROR = Status.ERROR,\n                    BUSY = Status.BUSY,\n                    IDLE = Status.IDLE,\n                    READY = Status.READY;\n\n                if (items.length === 0) return EMPTY;\n\n                if (items.some(isItemInErrorState)) return ERROR;\n\n                if (items.some(isItemInBusyState)) return BUSY;\n\n                if (items.some(isItemInReadyState)) return READY;\n\n                return IDLE;\n            },\n\n            GET_ITEM: function GET_ITEM(query) {\n                return getItemByQuery(state.items, query);\n            },\n\n            GET_ACTIVE_ITEM: function GET_ACTIVE_ITEM(query) {\n                return getItemByQuery(getActiveItems(state.items), query);\n            },\n\n            GET_ACTIVE_ITEMS: function GET_ACTIVE_ITEMS() {\n                return getActiveItems(state.items);\n            },\n\n            GET_ITEMS: function GET_ITEMS() {\n                return state.items;\n            },\n\n            GET_ITEM_NAME: function GET_ITEM_NAME(query) {\n                var item = getItemByQuery(state.items, query);\n                return item ? item.filename : null;\n            },\n\n            GET_ITEM_SIZE: function GET_ITEM_SIZE(query) {\n                var item = getItemByQuery(state.items, query);\n                return item ? item.fileSize : null;\n            },\n\n            GET_STYLES: function GET_STYLES() {\n                return Object.keys(state.options)\n                    .filter(function(key) {\n                        return /^style/.test(key);\n                    })\n                    .map(function(option) {\n                        return {\n                            name: option,\n                            value: state.options[option],\n                        };\n                    });\n            },\n\n            GET_PANEL_ASPECT_RATIO: function GET_PANEL_ASPECT_RATIO() {\n                var isShapeCircle = /circle/.test(state.options.stylePanelLayout);\n                var aspectRatio = isShapeCircle\n                    ? 1\n                    : getNumericAspectRatioFromString(state.options.stylePanelAspectRatio);\n                return aspectRatio;\n            },\n\n            GET_ITEM_PANEL_ASPECT_RATIO: function GET_ITEM_PANEL_ASPECT_RATIO() {\n                return state.options.styleItemPanelAspectRatio;\n            },\n\n            GET_ITEMS_BY_STATUS: function GET_ITEMS_BY_STATUS(status) {\n                return getActiveItems(state.items).filter(function(item) {\n                    return item.status === status;\n                });\n            },\n\n            GET_TOTAL_ITEMS: function GET_TOTAL_ITEMS() {\n                return getActiveItems(state.items).length;\n            },\n\n            SHOULD_UPDATE_FILE_INPUT: function SHOULD_UPDATE_FILE_INPUT() {\n                return state.options.storeAsFile && canUpdateFileInput() && !isAsync(state);\n            },\n\n            IS_ASYNC: function IS_ASYNC() {\n                return isAsync(state);\n            },\n\n            GET_FILE_SIZE_LABELS: function GET_FILE_SIZE_LABELS(query) {\n                return {\n                    labelBytes: query('GET_LABEL_FILE_SIZE_BYTES') || undefined,\n                    labelKilobytes: query('GET_LABEL_FILE_SIZE_KILOBYTES') || undefined,\n                    labelMegabytes: query('GET_LABEL_FILE_SIZE_MEGABYTES') || undefined,\n                    labelGigabytes: query('GET_LABEL_FILE_SIZE_GIGABYTES') || undefined,\n                };\n            },\n        };\n    };\n\n    var hasRoomForItem = function hasRoomForItem(state) {\n        var count = getActiveItems(state.items).length;\n\n        // if cannot have multiple items, to add one item it should currently not contain items\n        if (!state.options.allowMultiple) {\n            return count === 0;\n        }\n\n        // if allows multiple items, we check if a max item count has been set, if not, there's no limit\n        var maxFileCount = state.options.maxFiles;\n        if (maxFileCount === null) {\n            return true;\n        }\n\n        // we check if the current count is smaller than the max count, if so, another file can still be added\n        if (count < maxFileCount) {\n            return true;\n        }\n\n        // no more room for another file\n        return false;\n    };\n\n    var limit = function limit(value, min, max) {\n        return Math.max(Math.min(max, value), min);\n    };\n\n    var arrayInsert = function arrayInsert(arr, index, item) {\n        return arr.splice(index, 0, item);\n    };\n\n    var insertItem = function insertItem(items, item, index) {\n        if (isEmpty(item)) {\n            return null;\n        }\n\n        // if index is undefined, append\n        if (typeof index === 'undefined') {\n            items.push(item);\n            return item;\n        }\n\n        // limit the index to the size of the items array\n        index = limit(index, 0, items.length);\n\n        // add item to array\n        arrayInsert(items, index, item);\n\n        // expose\n        return item;\n    };\n\n    var isBase64DataURI = function isBase64DataURI(str) {\n        return /^\\s*data:([a-z]+\\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\\-._~:@\\/?%\\s]*)\\s*$/i.test(\n            str\n        );\n    };\n\n    var getFilenameFromURL = function getFilenameFromURL(url) {\n        return ('' + url)\n            .split('/')\n            .pop()\n            .split('?')\n            .shift();\n    };\n\n    var getExtensionFromFilename = function getExtensionFromFilename(name) {\n        return name.split('.').pop();\n    };\n\n    var guesstimateExtension = function guesstimateExtension(type) {\n        // if no extension supplied, exit here\n        if (typeof type !== 'string') {\n            return '';\n        }\n\n        // get subtype\n        var subtype = type.split('/').pop();\n\n        // is svg subtype\n        if (/svg/.test(subtype)) {\n            return 'svg';\n        }\n\n        if (/zip|compressed/.test(subtype)) {\n            return 'zip';\n        }\n\n        if (/plain/.test(subtype)) {\n            return 'txt';\n        }\n\n        if (/msword/.test(subtype)) {\n            return 'doc';\n        }\n\n        // if is valid subtype\n        if (/[a-z]+/.test(subtype)) {\n            // always use jpg extension\n            if (subtype === 'jpeg') {\n                return 'jpg';\n            }\n\n            // return subtype\n            return subtype;\n        }\n\n        return '';\n    };\n\n    var leftPad = function leftPad(value) {\n        var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';\n        return (padding + value).slice(-padding.length);\n    };\n\n    var getDateString = function getDateString() {\n        var date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Date();\n        return (\n            date.getFullYear() +\n            '-' +\n            leftPad(date.getMonth() + 1, '00') +\n            '-' +\n            leftPad(date.getDate(), '00') +\n            '_' +\n            leftPad(date.getHours(), '00') +\n            '-' +\n            leftPad(date.getMinutes(), '00') +\n            '-' +\n            leftPad(date.getSeconds(), '00')\n        );\n    };\n\n    var getFileFromBlob = function getFileFromBlob(blob, filename) {\n        var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n        var extension = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n        var file =\n            typeof type === 'string'\n                ? blob.slice(0, blob.size, type)\n                : blob.slice(0, blob.size, blob.type);\n        file.lastModifiedDate = new Date();\n\n        // copy relative path\n        if (blob._relativePath) file._relativePath = blob._relativePath;\n\n        // if blob has name property, use as filename if no filename supplied\n        if (!isString(filename)) {\n            filename = getDateString();\n        }\n\n        // if filename supplied but no extension and filename has extension\n        if (filename && extension === null && getExtensionFromFilename(filename)) {\n            file.name = filename;\n        } else {\n            extension = extension || guesstimateExtension(file.type);\n            file.name = filename + (extension ? '.' + extension : '');\n        }\n\n        return file;\n    };\n\n    var getBlobBuilder = function getBlobBuilder() {\n        return (window.BlobBuilder =\n            window.BlobBuilder ||\n            window.WebKitBlobBuilder ||\n            window.MozBlobBuilder ||\n            window.MSBlobBuilder);\n    };\n\n    var createBlob = function createBlob(arrayBuffer, mimeType) {\n        var BB = getBlobBuilder();\n\n        if (BB) {\n            var bb = new BB();\n            bb.append(arrayBuffer);\n            return bb.getBlob(mimeType);\n        }\n\n        return new Blob([arrayBuffer], {\n            type: mimeType,\n        });\n    };\n\n    var getBlobFromByteStringWithMimeType = function getBlobFromByteStringWithMimeType(\n        byteString,\n        mimeType\n    ) {\n        var ab = new ArrayBuffer(byteString.length);\n        var ia = new Uint8Array(ab);\n\n        for (var i = 0; i < byteString.length; i++) {\n            ia[i] = byteString.charCodeAt(i);\n        }\n\n        return createBlob(ab, mimeType);\n    };\n\n    var getMimeTypeFromBase64DataURI = function getMimeTypeFromBase64DataURI(dataURI) {\n        return (/^data:(.+);/.exec(dataURI) || [])[1] || null;\n    };\n\n    var getBase64DataFromBase64DataURI = function getBase64DataFromBase64DataURI(dataURI) {\n        // get data part of string (remove data:image/jpeg...,)\n        var data = dataURI.split(',')[1];\n\n        // remove any whitespace as that causes InvalidCharacterError in IE\n        return data.replace(/\\s/g, '');\n    };\n\n    var getByteStringFromBase64DataURI = function getByteStringFromBase64DataURI(dataURI) {\n        return atob(getBase64DataFromBase64DataURI(dataURI));\n    };\n\n    var getBlobFromBase64DataURI = function getBlobFromBase64DataURI(dataURI) {\n        var mimeType = getMimeTypeFromBase64DataURI(dataURI);\n        var byteString = getByteStringFromBase64DataURI(dataURI);\n\n        return getBlobFromByteStringWithMimeType(byteString, mimeType);\n    };\n\n    var getFileFromBase64DataURI = function getFileFromBase64DataURI(dataURI, filename, extension) {\n        return getFileFromBlob(getBlobFromBase64DataURI(dataURI), filename, null, extension);\n    };\n\n    var getFileNameFromHeader = function getFileNameFromHeader(header) {\n        // test if is content disposition header, if not exit\n        if (!/^content-disposition:/i.test(header)) return null;\n\n        // get filename parts\n        var matches = header\n            .split(/filename=|filename\\*=.+''/)\n            .splice(1)\n            .map(function(name) {\n                return name.trim().replace(/^[\"']|[;\"']{0,2}$/g, '');\n            })\n            .filter(function(name) {\n                return name.length;\n            });\n\n        return matches.length ? decodeURI(matches[matches.length - 1]) : null;\n    };\n\n    var getFileSizeFromHeader = function getFileSizeFromHeader(header) {\n        if (/content-length:/i.test(header)) {\n            var size = header.match(/[0-9]+/)[0];\n            return size ? parseInt(size, 10) : null;\n        }\n        return null;\n    };\n\n    var getTranfserIdFromHeader = function getTranfserIdFromHeader(header) {\n        if (/x-content-transfer-id:/i.test(header)) {\n            var id = (header.split(':')[1] || '').trim();\n            return id || null;\n        }\n        return null;\n    };\n\n    var getFileInfoFromHeaders = function getFileInfoFromHeaders(headers) {\n        var info = {\n            source: null,\n            name: null,\n            size: null,\n        };\n\n        var rows = headers.split('\\n');\n        var _iteratorNormalCompletion = true;\n        var _didIteratorError = false;\n        var _iteratorError = undefined;\n        try {\n            for (\n                var _iterator = rows[Symbol.iterator](), _step;\n                !(_iteratorNormalCompletion = (_step = _iterator.next()).done);\n                _iteratorNormalCompletion = true\n            ) {\n                var header = _step.value;\n\n                var name = getFileNameFromHeader(header);\n                if (name) {\n                    info.name = name;\n                    continue;\n                }\n\n                var size = getFileSizeFromHeader(header);\n                if (size) {\n                    info.size = size;\n                    continue;\n                }\n\n                var source = getTranfserIdFromHeader(header);\n                if (source) {\n                    info.source = source;\n                    continue;\n                }\n            }\n        } catch (err) {\n            _didIteratorError = true;\n            _iteratorError = err;\n        } finally {\n            try {\n                if (!_iteratorNormalCompletion && _iterator.return != null) {\n                    _iterator.return();\n                }\n            } finally {\n                if (_didIteratorError) {\n                    throw _iteratorError;\n                }\n            }\n        }\n\n        return info;\n    };\n\n    var createFileLoader = function createFileLoader(fetchFn) {\n        var state = {\n            source: null,\n            complete: false,\n            progress: 0,\n            size: null,\n            timestamp: null,\n            duration: 0,\n            request: null,\n        };\n\n        var getProgress = function getProgress() {\n            return state.progress;\n        };\n        var abort = function abort() {\n            if (state.request && state.request.abort) {\n                state.request.abort();\n            }\n        };\n\n        // load source\n        var load = function load() {\n            // get quick reference\n            var source = state.source;\n\n            api.fire('init', source);\n\n            // Load Files\n            if (source instanceof File) {\n                api.fire('load', source);\n            } else if (source instanceof Blob) {\n                // Load blobs, set default name to current date\n                api.fire('load', getFileFromBlob(source, source.name));\n            } else if (isBase64DataURI(source)) {\n                // Load base 64, set default name to current date\n                api.fire('load', getFileFromBase64DataURI(source));\n            } else {\n                // Deal as if is external URL, let's load it!\n                loadURL(source);\n            }\n        };\n\n        // loads a url\n        var loadURL = function loadURL(url) {\n            // is remote url and no fetch method supplied\n            if (!fetchFn) {\n                api.fire('error', {\n                    type: 'error',\n                    body: \"Can't load URL\",\n                    code: 400,\n                });\n\n                return;\n            }\n\n            // set request start\n            state.timestamp = Date.now();\n\n            // load file\n            state.request = fetchFn(\n                url,\n                function(response) {\n                    // update duration\n                    state.duration = Date.now() - state.timestamp;\n\n                    // done!\n                    state.complete = true;\n\n                    // turn blob response into a file\n                    if (response instanceof Blob) {\n                        response = getFileFromBlob(\n                            response,\n                            response.name || getFilenameFromURL(url)\n                        );\n                    }\n\n                    api.fire(\n                        'load',\n                        // if has received blob, we go with blob, if no response, we return null\n                        response instanceof Blob ? response : response ? response.body : null\n                    );\n                },\n                function(error) {\n                    api.fire(\n                        'error',\n                        typeof error === 'string'\n                            ? {\n                                  type: 'error',\n                                  code: 0,\n                                  body: error,\n                              }\n                            : error\n                    );\n                },\n                function(computable, current, total) {\n                    // collected some meta data already\n                    if (total) {\n                        state.size = total;\n                    }\n\n                    // update duration\n                    state.duration = Date.now() - state.timestamp;\n\n                    // if we can't compute progress, we're not going to fire progress events\n                    if (!computable) {\n                        state.progress = null;\n                        return;\n                    }\n\n                    // update progress percentage\n                    state.progress = current / total;\n\n                    // expose\n                    api.fire('progress', state.progress);\n                },\n                function() {\n                    api.fire('abort');\n                },\n                function(response) {\n                    var fileinfo = getFileInfoFromHeaders(\n                        typeof response === 'string' ? response : response.headers\n                    );\n                    api.fire('meta', {\n                        size: state.size || fileinfo.size,\n                        filename: fileinfo.name,\n                        source: fileinfo.source,\n                    });\n                }\n            );\n        };\n\n        var api = Object.assign({}, on(), {\n            setSource: function setSource(source) {\n                return (state.source = source);\n            },\n            getProgress: getProgress, // file load progress\n            abort: abort, // abort file load\n            load: load, // start load\n        });\n\n        return api;\n    };\n\n    var isGet = function isGet(method) {\n        return /GET|HEAD/.test(method);\n    };\n\n    var sendRequest = function sendRequest(data, url, options) {\n        var api = {\n            onheaders: function onheaders() {},\n            onprogress: function onprogress() {},\n            onload: function onload() {},\n            ontimeout: function ontimeout() {},\n            onerror: function onerror() {},\n            onabort: function onabort() {},\n            abort: function abort() {\n                aborted = true;\n                xhr.abort();\n            },\n        };\n\n        // timeout identifier, only used when timeout is defined\n        var aborted = false;\n        var headersReceived = false;\n\n        // set default options\n        options = Object.assign(\n            {\n                method: 'POST',\n                headers: {},\n                withCredentials: false,\n            },\n            options\n        );\n\n        // encode url\n        url = encodeURI(url);\n\n        // if method is GET, add any received data to url\n\n        if (isGet(options.method) && data) {\n            url =\n                '' +\n                url +\n                encodeURIComponent(typeof data === 'string' ? data : JSON.stringify(data));\n        }\n\n        // create request\n        var xhr = new XMLHttpRequest();\n\n        // progress of load\n        var process = isGet(options.method) ? xhr : xhr.upload;\n        process.onprogress = function(e) {\n            // no progress event when aborted ( onprogress is called once after abort() )\n            if (aborted) {\n                return;\n            }\n\n            api.onprogress(e.lengthComputable, e.loaded, e.total);\n        };\n\n        // tries to get header info to the app as fast as possible\n        xhr.onreadystatechange = function() {\n            // not interesting in these states ('unsent' and 'openend' as they don't give us any additional info)\n            if (xhr.readyState < 2) {\n                return;\n            }\n\n            // no server response\n            if (xhr.readyState === 4 && xhr.status === 0) {\n                return;\n            }\n\n            if (headersReceived) {\n                return;\n            }\n\n            headersReceived = true;\n\n            // we've probably received some useful data in response headers\n            api.onheaders(xhr);\n        };\n\n        // load successful\n        xhr.onload = function() {\n            // is classified as valid response\n            if (xhr.status >= 200 && xhr.status < 300) {\n                api.onload(xhr);\n            } else {\n                api.onerror(xhr);\n            }\n        };\n\n        // error during load\n        xhr.onerror = function() {\n            return api.onerror(xhr);\n        };\n\n        // request aborted\n        xhr.onabort = function() {\n            aborted = true;\n            api.onabort();\n        };\n\n        // request timeout\n        xhr.ontimeout = function() {\n            return api.ontimeout(xhr);\n        };\n\n        // open up open up!\n        xhr.open(options.method, url, true);\n\n        // set timeout if defined (do it after open so IE11 plays ball)\n        if (isInt(options.timeout)) {\n            xhr.timeout = options.timeout;\n        }\n\n        // add headers\n        Object.keys(options.headers).forEach(function(key) {\n            var value = unescape(encodeURIComponent(options.headers[key]));\n            xhr.setRequestHeader(key, value);\n        });\n\n        // set type of response\n        if (options.responseType) {\n            xhr.responseType = options.responseType;\n        }\n\n        // set credentials\n        if (options.withCredentials) {\n            xhr.withCredentials = true;\n        }\n\n        // let's send our data\n        xhr.send(data);\n\n        return api;\n    };\n\n    var createResponse = function createResponse(type, code, body, headers) {\n        return {\n            type: type,\n            code: code,\n            body: body,\n            headers: headers,\n        };\n    };\n\n    var createTimeoutResponse = function createTimeoutResponse(cb) {\n        return function(xhr) {\n            cb(createResponse('error', 0, 'Timeout', xhr.getAllResponseHeaders()));\n        };\n    };\n\n    var hasQS = function hasQS(str) {\n        return /\\?/.test(str);\n    };\n    var buildURL = function buildURL() {\n        var url = '';\n        for (var _len = arguments.length, parts = new Array(_len), _key = 0; _key < _len; _key++) {\n            parts[_key] = arguments[_key];\n        }\n        parts.forEach(function(part) {\n            url += hasQS(url) && hasQS(part) ? part.replace(/\\?/, '&') : part;\n        });\n        return url;\n    };\n\n    var createFetchFunction = function createFetchFunction() {\n        var apiUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n        var action = arguments.length > 1 ? arguments[1] : undefined;\n        // custom handler (should also handle file, load, error, progress and abort)\n        if (typeof action === 'function') {\n            return action;\n        }\n\n        // no action supplied\n        if (!action || !isString(action.url)) {\n            return null;\n        }\n\n        // set onload hanlder\n        var onload =\n            action.onload ||\n            function(res) {\n                return res;\n            };\n        var onerror =\n            action.onerror ||\n            function(res) {\n                return null;\n            };\n\n        // internal handler\n        return function(url, load, error, progress, abort, headers) {\n            // do local or remote request based on if the url is external\n            var request = sendRequest(\n                url,\n                buildURL(apiUrl, action.url),\n                Object.assign({}, action, {\n                    responseType: 'blob',\n                })\n            );\n\n            request.onload = function(xhr) {\n                // get headers\n                var headers = xhr.getAllResponseHeaders();\n\n                // get filename\n                var filename = getFileInfoFromHeaders(headers).name || getFilenameFromURL(url);\n\n                // create response\n                load(\n                    createResponse(\n                        'load',\n                        xhr.status,\n                        action.method === 'HEAD'\n                            ? null\n                            : getFileFromBlob(onload(xhr.response), filename),\n                        headers\n                    )\n                );\n            };\n\n            request.onerror = function(xhr) {\n                error(\n                    createResponse(\n                        'error',\n                        xhr.status,\n                        onerror(xhr.response) || xhr.statusText,\n                        xhr.getAllResponseHeaders()\n                    )\n                );\n            };\n\n            request.onheaders = function(xhr) {\n                headers(createResponse('headers', xhr.status, null, xhr.getAllResponseHeaders()));\n            };\n\n            request.ontimeout = createTimeoutResponse(error);\n            request.onprogress = progress;\n            request.onabort = abort;\n\n            // should return request\n            return request;\n        };\n    };\n\n    var ChunkStatus = {\n        QUEUED: 0,\n        COMPLETE: 1,\n        PROCESSING: 2,\n        ERROR: 3,\n        WAITING: 4,\n    };\n\n    /*\n                                                       function signature:\n                                                         (file, metadata, load, error, progress, abort, transfer, options) => {\n                                                           return {\n                                                           abort:() => {}\n                                                         }\n                                                       }\n                                                       */\n\n    // apiUrl, action, name, file, metadata, load, error, progress, abort, transfer, options\n    var processFileChunked = function processFileChunked(\n        apiUrl,\n        action,\n        name,\n        file,\n        metadata,\n        load,\n        error,\n        progress,\n        abort,\n        transfer,\n        options\n    ) {\n        // all chunks\n        var chunks = [];\n        var chunkTransferId = options.chunkTransferId,\n            chunkServer = options.chunkServer,\n            chunkSize = options.chunkSize,\n            chunkRetryDelays = options.chunkRetryDelays;\n\n        // default state\n        var state = {\n            serverId: chunkTransferId,\n            aborted: false,\n        };\n\n        // set onload handlers\n        var ondata =\n            action.ondata ||\n            function(fd) {\n                return fd;\n            };\n        var onload =\n            action.onload ||\n            function(xhr, method) {\n                return method === 'HEAD' ? xhr.getResponseHeader('Upload-Offset') : xhr.response;\n            };\n        var onerror =\n            action.onerror ||\n            function(res) {\n                return null;\n            };\n\n        // create server hook\n        var requestTransferId = function requestTransferId(cb) {\n            var formData = new FormData();\n\n            // add metadata under same name\n            if (isObject(metadata)) formData.append(name, JSON.stringify(metadata));\n\n            var headers =\n                typeof action.headers === 'function'\n                    ? action.headers(file, metadata)\n                    : Object.assign(\n                          {},\n\n                          action.headers,\n                          {\n                              'Upload-Length': file.size,\n                          }\n                      );\n\n            var requestParams = Object.assign({}, action, {\n                headers: headers,\n            });\n\n            // send request object\n            var request = sendRequest(\n                ondata(formData),\n                buildURL(apiUrl, action.url),\n                requestParams\n            );\n\n            request.onload = function(xhr) {\n                return cb(onload(xhr, requestParams.method));\n            };\n\n            request.onerror = function(xhr) {\n                return error(\n                    createResponse(\n                        'error',\n                        xhr.status,\n                        onerror(xhr.response) || xhr.statusText,\n                        xhr.getAllResponseHeaders()\n                    )\n                );\n            };\n\n            request.ontimeout = createTimeoutResponse(error);\n        };\n\n        var requestTransferOffset = function requestTransferOffset(cb) {\n            var requestUrl = buildURL(apiUrl, chunkServer.url, state.serverId);\n\n            var headers =\n                typeof action.headers === 'function'\n                    ? action.headers(state.serverId)\n                    : Object.assign(\n                          {},\n\n                          action.headers\n                      );\n\n            var requestParams = {\n                headers: headers,\n                method: 'HEAD',\n            };\n\n            var request = sendRequest(null, requestUrl, requestParams);\n\n            request.onload = function(xhr) {\n                return cb(onload(xhr, requestParams.method));\n            };\n\n            request.onerror = function(xhr) {\n                return error(\n                    createResponse(\n                        'error',\n                        xhr.status,\n                        onerror(xhr.response) || xhr.statusText,\n                        xhr.getAllResponseHeaders()\n                    )\n                );\n            };\n\n            request.ontimeout = createTimeoutResponse(error);\n        };\n\n        // create chunks\n        var lastChunkIndex = Math.floor(file.size / chunkSize);\n        for (var i = 0; i <= lastChunkIndex; i++) {\n            var offset = i * chunkSize;\n            var data = file.slice(offset, offset + chunkSize, 'application/offset+octet-stream');\n            chunks[i] = {\n                index: i,\n                size: data.size,\n                offset: offset,\n                data: data,\n                file: file,\n                progress: 0,\n                retries: _toConsumableArray(chunkRetryDelays),\n                status: ChunkStatus.QUEUED,\n                error: null,\n                request: null,\n                timeout: null,\n            };\n        }\n\n        var completeProcessingChunks = function completeProcessingChunks() {\n            return load(state.serverId);\n        };\n\n        var canProcessChunk = function canProcessChunk(chunk) {\n            return chunk.status === ChunkStatus.QUEUED || chunk.status === ChunkStatus.ERROR;\n        };\n\n        var processChunk = function processChunk(chunk) {\n            // processing is paused, wait here\n            if (state.aborted) return;\n\n            // get next chunk to process\n            chunk = chunk || chunks.find(canProcessChunk);\n\n            // no more chunks to process\n            if (!chunk) {\n                // all done?\n                if (\n                    chunks.every(function(chunk) {\n                        return chunk.status === ChunkStatus.COMPLETE;\n                    })\n                ) {\n                    completeProcessingChunks();\n                }\n\n                // no chunk to handle\n                return;\n            }\n\n            // now processing this chunk\n            chunk.status = ChunkStatus.PROCESSING;\n            chunk.progress = null;\n\n            // allow parsing of formdata\n            var ondata =\n                chunkServer.ondata ||\n                function(fd) {\n                    return fd;\n                };\n            var onerror =\n                chunkServer.onerror ||\n                function(res) {\n                    return null;\n                };\n            var onload = chunkServer.onload || function() {};\n\n            // send request object\n            var requestUrl = buildURL(apiUrl, chunkServer.url, state.serverId);\n\n            var headers =\n                typeof chunkServer.headers === 'function'\n                    ? chunkServer.headers(chunk)\n                    : Object.assign(\n                          {},\n\n                          chunkServer.headers,\n                          {\n                              'Content-Type': 'application/offset+octet-stream',\n                              'Upload-Offset': chunk.offset,\n                              'Upload-Length': file.size,\n                              'Upload-Name': file.name,\n                          }\n                      );\n\n            var request = (chunk.request = sendRequest(\n                ondata(chunk.data),\n                requestUrl,\n                Object.assign({}, chunkServer, {\n                    headers: headers,\n                })\n            ));\n\n            request.onload = function(xhr) {\n                // allow hooking into request result\n                onload(xhr, chunk.index, chunks.length);\n\n                // done!\n                chunk.status = ChunkStatus.COMPLETE;\n\n                // remove request reference\n                chunk.request = null;\n\n                // start processing more chunks\n                processChunks();\n            };\n\n            request.onprogress = function(lengthComputable, loaded, total) {\n                chunk.progress = lengthComputable ? loaded : null;\n                updateTotalProgress();\n            };\n\n            request.onerror = function(xhr) {\n                chunk.status = ChunkStatus.ERROR;\n                chunk.request = null;\n                chunk.error = onerror(xhr.response) || xhr.statusText;\n                if (!retryProcessChunk(chunk)) {\n                    error(\n                        createResponse(\n                            'error',\n                            xhr.status,\n                            onerror(xhr.response) || xhr.statusText,\n                            xhr.getAllResponseHeaders()\n                        )\n                    );\n                }\n            };\n\n            request.ontimeout = function(xhr) {\n                chunk.status = ChunkStatus.ERROR;\n                chunk.request = null;\n                if (!retryProcessChunk(chunk)) {\n                    createTimeoutResponse(error)(xhr);\n                }\n            };\n\n            request.onabort = function() {\n                chunk.status = ChunkStatus.QUEUED;\n                chunk.request = null;\n                abort();\n            };\n        };\n\n        var retryProcessChunk = function retryProcessChunk(chunk) {\n            // no more retries left\n            if (chunk.retries.length === 0) return false;\n\n            // new retry\n            chunk.status = ChunkStatus.WAITING;\n            clearTimeout(chunk.timeout);\n            chunk.timeout = setTimeout(function() {\n                processChunk(chunk);\n            }, chunk.retries.shift());\n\n            // we're going to retry\n            return true;\n        };\n\n        var updateTotalProgress = function updateTotalProgress() {\n            // calculate total progress fraction\n            var totalBytesTransfered = chunks.reduce(function(p, chunk) {\n                if (p === null || chunk.progress === null) return null;\n                return p + chunk.progress;\n            }, 0);\n\n            // can't compute progress\n            if (totalBytesTransfered === null) return progress(false, 0, 0);\n\n            // calculate progress values\n            var totalSize = chunks.reduce(function(total, chunk) {\n                return total + chunk.size;\n            }, 0);\n\n            // can update progress indicator\n            progress(true, totalBytesTransfered, totalSize);\n        };\n\n        // process new chunks\n        var processChunks = function processChunks() {\n            var totalProcessing = chunks.filter(function(chunk) {\n                return chunk.status === ChunkStatus.PROCESSING;\n            }).length;\n            if (totalProcessing >= 1) return;\n            processChunk();\n        };\n\n        var abortChunks = function abortChunks() {\n            chunks.forEach(function(chunk) {\n                clearTimeout(chunk.timeout);\n                if (chunk.request) {\n                    chunk.request.abort();\n                }\n            });\n        };\n\n        // let's go!\n        if (!state.serverId) {\n            requestTransferId(function(serverId) {\n                // stop here if aborted, might have happened in between request and callback\n                if (state.aborted) return;\n\n                // pass back to item so we can use it if something goes wrong\n                transfer(serverId);\n\n                // store internally\n                state.serverId = serverId;\n                processChunks();\n            });\n        } else {\n            requestTransferOffset(function(offset) {\n                // stop here if aborted, might have happened in between request and callback\n                if (state.aborted) return;\n\n                // mark chunks with lower offset as complete\n                chunks\n                    .filter(function(chunk) {\n                        return chunk.offset < offset;\n                    })\n                    .forEach(function(chunk) {\n                        chunk.status = ChunkStatus.COMPLETE;\n                        chunk.progress = chunk.size;\n                    });\n\n                // continue processing\n                processChunks();\n            });\n        }\n\n        return {\n            abort: function abort() {\n                state.aborted = true;\n                abortChunks();\n            },\n        };\n    };\n\n    /*\n                                                               function signature:\n                                                                 (file, metadata, load, error, progress, abort) => {\n                                                                   return {\n                                                                   abort:() => {}\n                                                                 }\n                                                               }\n                                                               */\n    var createFileProcessorFunction = function createFileProcessorFunction(\n        apiUrl,\n        action,\n        name,\n        options\n    ) {\n        return function(file, metadata, load, error, progress, abort, transfer) {\n            // no file received\n            if (!file) return;\n\n            // if was passed a file, and we can chunk it, exit here\n            var canChunkUpload = options.chunkUploads;\n            var shouldChunkUpload = canChunkUpload && file.size > options.chunkSize;\n            var willChunkUpload = canChunkUpload && (shouldChunkUpload || options.chunkForce);\n            if (file instanceof Blob && willChunkUpload)\n                return processFileChunked(\n                    apiUrl,\n                    action,\n                    name,\n                    file,\n                    metadata,\n                    load,\n                    error,\n                    progress,\n                    abort,\n                    transfer,\n                    options\n                );\n\n            // set handlers\n            var ondata =\n                action.ondata ||\n                function(fd) {\n                    return fd;\n                };\n            var onload =\n                action.onload ||\n                function(res) {\n                    return res;\n                };\n            var onerror =\n                action.onerror ||\n                function(res) {\n                    return null;\n                };\n\n            var headers =\n                typeof action.headers === 'function'\n                    ? action.headers(file, metadata) || {}\n                    : Object.assign(\n                          {},\n\n                          action.headers\n                      );\n\n            var requestParams = Object.assign({}, action, {\n                headers: headers,\n            });\n\n            // create formdata object\n            var formData = new FormData();\n\n            // add metadata under same name\n            if (isObject(metadata)) {\n                formData.append(name, JSON.stringify(metadata));\n            }\n\n            // Turn into an array of objects so no matter what the input, we can handle it the same way\n            (file instanceof Blob ? [{ name: null, file: file }] : file).forEach(function(item) {\n                formData.append(\n                    name,\n                    item.file,\n                    item.name === null ? item.file.name : '' + item.name + item.file.name\n                );\n            });\n\n            // send request object\n            var request = sendRequest(\n                ondata(formData),\n                buildURL(apiUrl, action.url),\n                requestParams\n            );\n            request.onload = function(xhr) {\n                load(\n                    createResponse(\n                        'load',\n                        xhr.status,\n                        onload(xhr.response),\n                        xhr.getAllResponseHeaders()\n                    )\n                );\n            };\n\n            request.onerror = function(xhr) {\n                error(\n                    createResponse(\n                        'error',\n                        xhr.status,\n                        onerror(xhr.response) || xhr.statusText,\n                        xhr.getAllResponseHeaders()\n                    )\n                );\n            };\n\n            request.ontimeout = createTimeoutResponse(error);\n            request.onprogress = progress;\n            request.onabort = abort;\n\n            // should return request\n            return request;\n        };\n    };\n\n    var createProcessorFunction = function createProcessorFunction() {\n        var apiUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n        var action = arguments.length > 1 ? arguments[1] : undefined;\n        var name = arguments.length > 2 ? arguments[2] : undefined;\n        var options = arguments.length > 3 ? arguments[3] : undefined;\n\n        // custom handler (should also handle file, load, error, progress and abort)\n        if (typeof action === 'function')\n            return function() {\n                for (\n                    var _len = arguments.length, params = new Array(_len), _key = 0;\n                    _key < _len;\n                    _key++\n                ) {\n                    params[_key] = arguments[_key];\n                }\n                return action.apply(void 0, [name].concat(params, [options]));\n            };\n\n        // no action supplied\n        if (!action || !isString(action.url)) return null;\n\n        // internal handler\n        return createFileProcessorFunction(apiUrl, action, name, options);\n    };\n\n    /*\n                                                      function signature:\n                                                      (uniqueFileId, load, error) => { }\n                                                      */\n    var createRevertFunction = function createRevertFunction() {\n        var apiUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n        var action = arguments.length > 1 ? arguments[1] : undefined;\n        // is custom implementation\n        if (typeof action === 'function') {\n            return action;\n        }\n\n        // no action supplied, return stub function, interface will work, but file won't be removed\n        if (!action || !isString(action.url)) {\n            return function(uniqueFileId, load) {\n                return load();\n            };\n        }\n\n        // set onload hanlder\n        var onload =\n            action.onload ||\n            function(res) {\n                return res;\n            };\n        var onerror =\n            action.onerror ||\n            function(res) {\n                return null;\n            };\n\n        // internal implementation\n        return function(uniqueFileId, load, error) {\n            var request = sendRequest(\n                uniqueFileId,\n                apiUrl + action.url,\n                action // contains method, headers and withCredentials properties\n            );\n            request.onload = function(xhr) {\n                load(\n                    createResponse(\n                        'load',\n                        xhr.status,\n                        onload(xhr.response),\n                        xhr.getAllResponseHeaders()\n                    )\n                );\n            };\n\n            request.onerror = function(xhr) {\n                error(\n                    createResponse(\n                        'error',\n                        xhr.status,\n                        onerror(xhr.response) || xhr.statusText,\n                        xhr.getAllResponseHeaders()\n                    )\n                );\n            };\n\n            request.ontimeout = createTimeoutResponse(error);\n\n            return request;\n        };\n    };\n\n    var getRandomNumber = function getRandomNumber() {\n        var min = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;\n        var max = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n        return min + Math.random() * (max - min);\n    };\n\n    var createPerceivedPerformanceUpdater = function createPerceivedPerformanceUpdater(cb) {\n        var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;\n        var offset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;\n        var tickMin = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 25;\n        var tickMax = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 250;\n        var timeout = null;\n        var start = Date.now();\n\n        var tick = function tick() {\n            var runtime = Date.now() - start;\n            var delay = getRandomNumber(tickMin, tickMax);\n\n            if (runtime + delay > duration) {\n                delay = runtime + delay - duration;\n            }\n\n            var progress = runtime / duration;\n            if (progress >= 1 || document.hidden) {\n                cb(1);\n                return;\n            }\n\n            cb(progress);\n\n            timeout = setTimeout(tick, delay);\n        };\n\n        if (duration > 0) tick();\n\n        return {\n            clear: function clear() {\n                clearTimeout(timeout);\n            },\n        };\n    };\n\n    var createFileProcessor = function createFileProcessor(processFn, options) {\n        var state = {\n            complete: false,\n            perceivedProgress: 0,\n            perceivedPerformanceUpdater: null,\n            progress: null,\n            timestamp: null,\n            perceivedDuration: 0,\n            duration: 0,\n            request: null,\n            response: null,\n        };\n        var allowMinimumUploadDuration = options.allowMinimumUploadDuration;\n\n        var process = function process(file, metadata) {\n            var progressFn = function progressFn() {\n                // we've not yet started the real download, stop here\n                // the request might not go through, for instance, there might be some server trouble\n                // if state.progress is null, the server does not allow computing progress and we show the spinner instead\n                if (state.duration === 0 || state.progress === null) return;\n\n                // as we're now processing, fire the progress event\n                api.fire('progress', api.getProgress());\n            };\n\n            var completeFn = function completeFn() {\n                state.complete = true;\n                api.fire('load-perceived', state.response.body);\n            };\n\n            // let's start processing\n            api.fire('start');\n\n            // set request start\n            state.timestamp = Date.now();\n\n            // create perceived performance progress indicator\n            state.perceivedPerformanceUpdater = createPerceivedPerformanceUpdater(\n                function(progress) {\n                    state.perceivedProgress = progress;\n                    state.perceivedDuration = Date.now() - state.timestamp;\n\n                    progressFn();\n\n                    // if fake progress is done, and a response has been received,\n                    // and we've not yet called the complete method\n                    if (state.response && state.perceivedProgress === 1 && !state.complete) {\n                        // we done!\n                        completeFn();\n                    }\n                },\n                // random delay as in a list of files you start noticing\n                // files uploading at the exact same speed\n                allowMinimumUploadDuration ? getRandomNumber(750, 1500) : 0\n            );\n\n            // remember request so we can abort it later\n            state.request = processFn(\n                // the file to process\n                file,\n\n                // the metadata to send along\n                metadata,\n\n                // callbacks (load, error, progress, abort, transfer)\n                // load expects the body to be a server id if\n                // you want to make use of revert\n                function(response) {\n                    // we put the response in state so we can access\n                    // it outside of this method\n                    state.response = isObject(response)\n                        ? response\n                        : {\n                              type: 'load',\n                              code: 200,\n                              body: '' + response,\n                              headers: {},\n                          };\n\n                    // update duration\n                    state.duration = Date.now() - state.timestamp;\n\n                    // force progress to 1 as we're now done\n                    state.progress = 1;\n\n                    // actual load is done let's share results\n                    api.fire('load', state.response.body);\n\n                    // we are really done\n                    // if perceived progress is 1 ( wait for perceived progress to complete )\n                    // or if server does not support progress ( null )\n                    if (\n                        !allowMinimumUploadDuration ||\n                        (allowMinimumUploadDuration && state.perceivedProgress === 1)\n                    ) {\n                        completeFn();\n                    }\n                },\n\n                // error is expected to be an object with type, code, body\n                function(error) {\n                    // cancel updater\n                    state.perceivedPerformanceUpdater.clear();\n\n                    // update others about this error\n                    api.fire(\n                        'error',\n                        isObject(error)\n                            ? error\n                            : {\n                                  type: 'error',\n                                  code: 0,\n                                  body: '' + error,\n                              }\n                    );\n                },\n\n                // actual processing progress\n                function(computable, current, total) {\n                    // update actual duration\n                    state.duration = Date.now() - state.timestamp;\n\n                    // update actual progress\n                    state.progress = computable ? current / total : null;\n\n                    progressFn();\n                },\n\n                // abort does not expect a value\n                function() {\n                    // stop updater\n                    state.perceivedPerformanceUpdater.clear();\n\n                    // fire the abort event so we can switch visuals\n                    api.fire('abort', state.response ? state.response.body : null);\n                },\n\n                // register the id for this transfer\n                function(transferId) {\n                    api.fire('transfer', transferId);\n                }\n            );\n        };\n\n        var abort = function abort() {\n            // no request running, can't abort\n            if (!state.request) return;\n\n            // stop updater\n            state.perceivedPerformanceUpdater.clear();\n\n            // abort actual request\n            if (state.request.abort) state.request.abort();\n\n            // if has response object, we've completed the request\n            state.complete = true;\n        };\n\n        var reset = function reset() {\n            abort();\n            state.complete = false;\n            state.perceivedProgress = 0;\n            state.progress = 0;\n            state.timestamp = null;\n            state.perceivedDuration = 0;\n            state.duration = 0;\n            state.request = null;\n            state.response = null;\n        };\n\n        var getProgress = allowMinimumUploadDuration\n            ? function() {\n                  return state.progress ? Math.min(state.progress, state.perceivedProgress) : null;\n              }\n            : function() {\n                  return state.progress || null;\n              };\n\n        var getDuration = allowMinimumUploadDuration\n            ? function() {\n                  return Math.min(state.duration, state.perceivedDuration);\n              }\n            : function() {\n                  return state.duration;\n              };\n\n        var api = Object.assign({}, on(), {\n            process: process, // start processing file\n            abort: abort, // abort active process request\n            getProgress: getProgress,\n            getDuration: getDuration,\n            reset: reset,\n        });\n\n        return api;\n    };\n\n    var getFilenameWithoutExtension = function getFilenameWithoutExtension(name) {\n        return name.substring(0, name.lastIndexOf('.')) || name;\n    };\n\n    var createFileStub = function createFileStub(source) {\n        var data = [source.name, source.size, source.type];\n\n        // is blob or base64, then we need to set the name\n        if (source instanceof Blob || isBase64DataURI(source)) {\n            data[0] = source.name || getDateString();\n        } else if (isBase64DataURI(source)) {\n            // if is base64 data uri we need to determine the average size and type\n            data[1] = source.length;\n            data[2] = getMimeTypeFromBase64DataURI(source);\n        } else if (isString(source)) {\n            // url\n            data[0] = getFilenameFromURL(source);\n            data[1] = 0;\n            data[2] = 'application/octet-stream';\n        }\n\n        return {\n            name: data[0],\n            size: data[1],\n            type: data[2],\n        };\n    };\n\n    var isFile = function isFile(value) {\n        return !!(value instanceof File || (value instanceof Blob && value.name));\n    };\n\n    var deepCloneObject = function deepCloneObject(src) {\n        if (!isObject(src)) return src;\n        var target = isArray(src) ? [] : {};\n        for (var key in src) {\n            if (!src.hasOwnProperty(key)) continue;\n            var v = src[key];\n            target[key] = v && isObject(v) ? deepCloneObject(v) : v;\n        }\n        return target;\n    };\n\n    var createItem = function createItem() {\n        var origin = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n        var serverFileReference =\n            arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n        var file = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n        // unique id for this item, is used to identify the item across views\n        var id = getUniqueId();\n\n        /**\n         * Internal item state\n         */\n        var state = {\n            // is archived\n            archived: false,\n\n            // if is frozen, no longer fires events\n            frozen: false,\n\n            // removed from view\n            released: false,\n\n            // original source\n            source: null,\n\n            // file model reference\n            file: file,\n\n            // id of file on server\n            serverFileReference: serverFileReference,\n\n            // id of file transfer on server\n            transferId: null,\n\n            // is aborted\n            processingAborted: false,\n\n            // current item status\n            status: serverFileReference ? ItemStatus.PROCESSING_COMPLETE : ItemStatus.INIT,\n\n            // active processes\n            activeLoader: null,\n            activeProcessor: null,\n        };\n\n        // callback used when abort processing is called to link back to the resolve method\n        var abortProcessingRequestComplete = null;\n\n        /**\n         * Externally added item metadata\n         */\n        var metadata = {};\n\n        // item data\n        var setStatus = function setStatus(status) {\n            return (state.status = status);\n        };\n\n        // fire event unless the item has been archived\n        var fire = function fire(event) {\n            if (state.released || state.frozen) return;\n            for (\n                var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1;\n                _key < _len;\n                _key++\n            ) {\n                params[_key - 1] = arguments[_key];\n            }\n            api.fire.apply(api, [event].concat(params));\n        };\n\n        // file data\n        var getFileExtension = function getFileExtension() {\n            return getExtensionFromFilename(state.file.name);\n        };\n        var getFileType = function getFileType() {\n            return state.file.type;\n        };\n        var getFileSize = function getFileSize() {\n            return state.file.size;\n        };\n        var getFile = function getFile() {\n            return state.file;\n        };\n\n        //\n        // logic to load a file\n        //\n        var load = function load(source, loader, onload) {\n            // remember the original item source\n            state.source = source;\n\n            // source is known\n            api.fireSync('init');\n\n            // file stub is already there\n            if (state.file) {\n                api.fireSync('load-skip');\n                return;\n            }\n\n            // set a stub file object while loading the actual data\n            state.file = createFileStub(source);\n\n            // starts loading\n            loader.on('init', function() {\n                fire('load-init');\n            });\n\n            // we'eve received a size indication, let's update the stub\n            loader.on('meta', function(meta) {\n                // set size of file stub\n                state.file.size = meta.size;\n\n                // set name of file stub\n                state.file.filename = meta.filename;\n\n                // if has received source, we done\n                if (meta.source) {\n                    origin = FileOrigin.LIMBO;\n                    state.serverFileReference = meta.source;\n                    state.status = ItemStatus.PROCESSING_COMPLETE;\n                }\n\n                // size has been updated\n                fire('load-meta');\n            });\n\n            // the file is now loading we need to update the progress indicators\n            loader.on('progress', function(progress) {\n                setStatus(ItemStatus.LOADING);\n\n                fire('load-progress', progress);\n            });\n\n            // an error was thrown while loading the file, we need to switch to error state\n            loader.on('error', function(error) {\n                setStatus(ItemStatus.LOAD_ERROR);\n\n                fire('load-request-error', error);\n            });\n\n            // user or another process aborted the file load (cannot retry)\n            loader.on('abort', function() {\n                setStatus(ItemStatus.INIT);\n                fire('load-abort');\n            });\n\n            // done loading\n            loader.on('load', function(file) {\n                // as we've now loaded the file the loader is no longer required\n                state.activeLoader = null;\n\n                // called when file has loaded succesfully\n                var success = function success(result) {\n                    // set (possibly) transformed file\n                    state.file = isFile(result) ? result : state.file;\n\n                    // file received\n                    if (origin === FileOrigin.LIMBO && state.serverFileReference) {\n                        setStatus(ItemStatus.PROCESSING_COMPLETE);\n                    } else {\n                        setStatus(ItemStatus.IDLE);\n                    }\n\n                    fire('load');\n                };\n\n                var error = function error(result) {\n                    // set original file\n                    state.file = file;\n                    fire('load-meta');\n\n                    setStatus(ItemStatus.LOAD_ERROR);\n                    fire('load-file-error', result);\n                };\n\n                // if we already have a server file reference, we don't need to call the onload method\n                if (state.serverFileReference) {\n                    success(file);\n                    return;\n                }\n\n                // no server id, let's give this file the full treatment\n                onload(file, success, error);\n            });\n\n            // set loader source data\n            loader.setSource(source);\n\n            // set as active loader\n            state.activeLoader = loader;\n\n            // load the source data\n            loader.load();\n        };\n\n        var retryLoad = function retryLoad() {\n            if (!state.activeLoader) {\n                return;\n            }\n            state.activeLoader.load();\n        };\n\n        var abortLoad = function abortLoad() {\n            if (state.activeLoader) {\n                state.activeLoader.abort();\n                return;\n            }\n            setStatus(ItemStatus.INIT);\n            fire('load-abort');\n        };\n\n        //\n        // logic to process a file\n        //\n        var process = function process(processor, onprocess) {\n            // processing was aborted\n            if (state.processingAborted) {\n                state.processingAborted = false;\n                return;\n            }\n\n            // now processing\n            setStatus(ItemStatus.PROCESSING);\n\n            // reset abort callback\n            abortProcessingRequestComplete = null;\n\n            // if no file loaded we'll wait for the load event\n            if (!(state.file instanceof Blob)) {\n                api.on('load', function() {\n                    process(processor, onprocess);\n                });\n                return;\n            }\n\n            // setup processor\n            processor.on('load', function(serverFileReference) {\n                // need this id to be able to revert the upload\n                state.transferId = null;\n                state.serverFileReference = serverFileReference;\n            });\n\n            // register transfer id\n            processor.on('transfer', function(transferId) {\n                // need this id to be able to revert the upload\n                state.transferId = transferId;\n            });\n\n            processor.on('load-perceived', function(serverFileReference) {\n                // no longer required\n                state.activeProcessor = null;\n\n                // need this id to be able to rever the upload\n                state.transferId = null;\n                state.serverFileReference = serverFileReference;\n\n                setStatus(ItemStatus.PROCESSING_COMPLETE);\n                fire('process-complete', serverFileReference);\n            });\n\n            processor.on('start', function() {\n                fire('process-start');\n            });\n\n            processor.on('error', function(error) {\n                state.activeProcessor = null;\n                setStatus(ItemStatus.PROCESSING_ERROR);\n                fire('process-error', error);\n            });\n\n            processor.on('abort', function(serverFileReference) {\n                state.activeProcessor = null;\n\n                // if file was uploaded but processing was cancelled during perceived processor time store file reference\n                state.serverFileReference = serverFileReference;\n\n                setStatus(ItemStatus.IDLE);\n                fire('process-abort');\n\n                // has timeout so doesn't interfere with remove action\n                if (abortProcessingRequestComplete) {\n                    abortProcessingRequestComplete();\n                }\n            });\n\n            processor.on('progress', function(progress) {\n                fire('process-progress', progress);\n            });\n\n            // when successfully transformed\n            var success = function success(file) {\n                // if was archived in the mean time, don't process\n                if (state.archived) return;\n\n                // process file!\n                processor.process(file, Object.assign({}, metadata));\n            };\n\n            // something went wrong during transform phase\n            var error = console.error;\n\n            // start processing the file\n            onprocess(state.file, success, error);\n\n            // set as active processor\n            state.activeProcessor = processor;\n        };\n\n        var requestProcessing = function requestProcessing() {\n            state.processingAborted = false;\n            setStatus(ItemStatus.PROCESSING_QUEUED);\n        };\n\n        var abortProcessing = function abortProcessing() {\n            return new Promise(function(resolve) {\n                if (!state.activeProcessor) {\n                    state.processingAborted = true;\n\n                    setStatus(ItemStatus.IDLE);\n                    fire('process-abort');\n\n                    resolve();\n                    return;\n                }\n\n                abortProcessingRequestComplete = function abortProcessingRequestComplete() {\n                    resolve();\n                };\n\n                state.activeProcessor.abort();\n            });\n        };\n\n        //\n        // logic to revert a processed file\n        //\n        var revert = function revert(revertFileUpload, forceRevert) {\n            return new Promise(function(resolve, reject) {\n                // a completed upload will have a serverFileReference, a failed chunked upload where\n                // getting a serverId succeeded but >=0 chunks have been uploaded will have transferId set\n                var serverTransferId =\n                    state.serverFileReference !== null\n                        ? state.serverFileReference\n                        : state.transferId;\n\n                // cannot revert without a server id for this process\n                if (serverTransferId === null) {\n                    resolve();\n                    return;\n                }\n\n                // revert the upload (fire and forget)\n                revertFileUpload(\n                    serverTransferId,\n                    function() {\n                        // reset file server id and transfer id as now it's not available on the server\n                        state.serverFileReference = null;\n                        state.transferId = null;\n                        resolve();\n                    },\n                    function(error) {\n                        // don't set error state when reverting is optional, it will always resolve\n                        if (!forceRevert) {\n                            resolve();\n                            return;\n                        }\n\n                        // oh no errors\n                        setStatus(ItemStatus.PROCESSING_REVERT_ERROR);\n                        fire('process-revert-error');\n                        reject(error);\n                    }\n                );\n\n                // fire event\n                setStatus(ItemStatus.IDLE);\n                fire('process-revert');\n            });\n        };\n\n        // exposed methods\n        var _setMetadata = function setMetadata(key, value, silent) {\n            var keys = key.split('.');\n            var root = keys[0];\n            var last = keys.pop();\n            var data = metadata;\n            keys.forEach(function(key) {\n                return (data = data[key]);\n            });\n\n            // compare old value against new value, if they're the same, we're not updating\n            if (JSON.stringify(data[last]) === JSON.stringify(value)) return;\n\n            // update value\n            data[last] = value;\n\n            // fire update\n            fire('metadata-update', {\n                key: root,\n                value: metadata[root],\n                silent: silent,\n            });\n        };\n\n        var getMetadata = function getMetadata(key) {\n            return deepCloneObject(key ? metadata[key] : metadata);\n        };\n\n        var api = Object.assign(\n            {\n                id: {\n                    get: function get() {\n                        return id;\n                    },\n                },\n                origin: {\n                    get: function get() {\n                        return origin;\n                    },\n                    set: function set(value) {\n                        return (origin = value);\n                    },\n                },\n                serverId: {\n                    get: function get() {\n                        return state.serverFileReference;\n                    },\n                },\n                transferId: {\n                    get: function get() {\n                        return state.transferId;\n                    },\n                },\n                status: {\n                    get: function get() {\n                        return state.status;\n                    },\n                },\n                filename: {\n                    get: function get() {\n                        return state.file.name;\n                    },\n                },\n                filenameWithoutExtension: {\n                    get: function get() {\n                        return getFilenameWithoutExtension(state.file.name);\n                    },\n                },\n                fileExtension: { get: getFileExtension },\n                fileType: { get: getFileType },\n                fileSize: { get: getFileSize },\n                file: { get: getFile },\n                relativePath: {\n                    get: function get() {\n                        return state.file._relativePath;\n                    },\n                },\n\n                source: {\n                    get: function get() {\n                        return state.source;\n                    },\n                },\n\n                getMetadata: getMetadata,\n                setMetadata: function setMetadata(key, value, silent) {\n                    if (isObject(key)) {\n                        var data = key;\n                        Object.keys(data).forEach(function(key) {\n                            _setMetadata(key, data[key], value);\n                        });\n                        return key;\n                    }\n                    _setMetadata(key, value, silent);\n                    return value;\n                },\n\n                extend: function extend(name, handler) {\n                    return (itemAPI[name] = handler);\n                },\n\n                abortLoad: abortLoad,\n                retryLoad: retryLoad,\n                requestProcessing: requestProcessing,\n                abortProcessing: abortProcessing,\n\n                load: load,\n                process: process,\n                revert: revert,\n            },\n\n            on(),\n            {\n                freeze: function freeze() {\n                    return (state.frozen = true);\n                },\n\n                release: function release() {\n                    return (state.released = true);\n                },\n                released: {\n                    get: function get() {\n                        return state.released;\n                    },\n                },\n\n                archive: function archive() {\n                    return (state.archived = true);\n                },\n                archived: {\n                    get: function get() {\n                        return state.archived;\n                    },\n                },\n\n                // replace source and file object\n                setFile: function setFile(file) {\n                    return (state.file = file);\n                },\n            }\n        );\n\n        // create it here instead of returning it instantly so we can extend it later\n        var itemAPI = createObject(api);\n\n        return itemAPI;\n    };\n\n    var getItemIndexByQuery = function getItemIndexByQuery(items, query) {\n        // just return first index\n        if (isEmpty(query)) {\n            return 0;\n        }\n\n        // invalid queries\n        if (!isString(query)) {\n            return -1;\n        }\n\n        // return item by id (or -1 if not found)\n        return items.findIndex(function(item) {\n            return item.id === query;\n        });\n    };\n\n    var getItemById = function getItemById(items, itemId) {\n        var index = getItemIndexByQuery(items, itemId);\n        if (index < 0) {\n            return;\n        }\n        return items[index] || null;\n    };\n\n    var fetchBlob = function fetchBlob(url, load, error, progress, abort, headers) {\n        var request = sendRequest(null, url, {\n            method: 'GET',\n            responseType: 'blob',\n        });\n\n        request.onload = function(xhr) {\n            // get headers\n            var headers = xhr.getAllResponseHeaders();\n\n            // get filename\n            var filename = getFileInfoFromHeaders(headers).name || getFilenameFromURL(url);\n\n            // create response\n            load(\n                createResponse('load', xhr.status, getFileFromBlob(xhr.response, filename), headers)\n            );\n        };\n\n        request.onerror = function(xhr) {\n            error(createResponse('error', xhr.status, xhr.statusText, xhr.getAllResponseHeaders()));\n        };\n\n        request.onheaders = function(xhr) {\n            headers(createResponse('headers', xhr.status, null, xhr.getAllResponseHeaders()));\n        };\n\n        request.ontimeout = createTimeoutResponse(error);\n        request.onprogress = progress;\n        request.onabort = abort;\n\n        // should return request\n        return request;\n    };\n\n    var getDomainFromURL = function getDomainFromURL(url) {\n        if (url.indexOf('//') === 0) {\n            url = location.protocol + url;\n        }\n        return url\n            .toLowerCase()\n            .replace('blob:', '')\n            .replace(/([a-z])?:\\/\\//, '$1')\n            .split('/')[0];\n    };\n\n    var isExternalURL = function isExternalURL(url) {\n        return (\n            (url.indexOf(':') > -1 || url.indexOf('//') > -1) &&\n            getDomainFromURL(location.href) !== getDomainFromURL(url)\n        );\n    };\n\n    var dynamicLabel = function dynamicLabel(label) {\n        return function() {\n            return isFunction(label) ? label.apply(void 0, arguments) : label;\n        };\n    };\n\n    var isMockItem = function isMockItem(item) {\n        return !isFile(item.file);\n    };\n\n    var listUpdated = function listUpdated(dispatch, state) {\n        clearTimeout(state.listUpdateTimeout);\n        state.listUpdateTimeout = setTimeout(function() {\n            dispatch('DID_UPDATE_ITEMS', { items: getActiveItems(state.items) });\n        }, 0);\n    };\n\n    var optionalPromise = function optionalPromise(fn) {\n        for (\n            var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1;\n            _key < _len;\n            _key++\n        ) {\n            params[_key - 1] = arguments[_key];\n        }\n        return new Promise(function(resolve) {\n            if (!fn) {\n                return resolve(true);\n            }\n\n            var result = fn.apply(void 0, params);\n\n            if (result == null) {\n                return resolve(true);\n            }\n\n            if (typeof result === 'boolean') {\n                return resolve(result);\n            }\n\n            if (typeof result.then === 'function') {\n                result.then(resolve);\n            }\n        });\n    };\n\n    var sortItems = function sortItems(state, compare) {\n        state.items.sort(function(a, b) {\n            return compare(createItemAPI(a), createItemAPI(b));\n        });\n    };\n\n    // returns item based on state\n    var getItemByQueryFromState = function getItemByQueryFromState(state, itemHandler) {\n        return function() {\n            var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n            var query = _ref.query,\n                _ref$success = _ref.success,\n                success = _ref$success === void 0 ? function() {} : _ref$success,\n                _ref$failure = _ref.failure,\n                failure = _ref$failure === void 0 ? function() {} : _ref$failure,\n                options = _objectWithoutProperties(_ref, ['query', 'success', 'failure']);\n            var item = getItemByQuery(state.items, query);\n            if (!item) {\n                failure({\n                    error: createResponse('error', 0, 'Item not found'),\n                    file: null,\n                });\n\n                return;\n            }\n            itemHandler(item, success, failure, options || {});\n        };\n    };\n\n    var actions = function actions(dispatch, query, state) {\n        return {\n            /**\n             * Aborts all ongoing processes\n             */\n            ABORT_ALL: function ABORT_ALL() {\n                getActiveItems(state.items).forEach(function(item) {\n                    item.freeze();\n                    item.abortLoad();\n                    item.abortProcessing();\n                });\n            },\n\n            /**\n             * Sets initial files\n             */\n            DID_SET_FILES: function DID_SET_FILES(_ref2) {\n                var _ref2$value = _ref2.value,\n                    value = _ref2$value === void 0 ? [] : _ref2$value;\n                // map values to file objects\n                var files = value.map(function(file) {\n                    return {\n                        source: file.source ? file.source : file,\n                        options: file.options,\n                    };\n                });\n\n                // loop over files, if file is in list, leave it be, if not, remove\n                // test if items should be moved\n                var activeItems = getActiveItems(state.items);\n\n                activeItems.forEach(function(item) {\n                    // if item not is in new value, remove\n                    if (\n                        !files.find(function(file) {\n                            return file.source === item.source || file.source === item.file;\n                        })\n                    ) {\n                        dispatch('REMOVE_ITEM', { query: item, remove: false });\n                    }\n                });\n\n                // add new files\n                activeItems = getActiveItems(state.items);\n                files.forEach(function(file, index) {\n                    // if file is already in list\n                    if (\n                        activeItems.find(function(item) {\n                            return item.source === file.source || item.file === file.source;\n                        })\n                    )\n                        return;\n\n                    // not in list, add\n                    dispatch(\n                        'ADD_ITEM',\n                        Object.assign({}, file, {\n                            interactionMethod: InteractionMethod.NONE,\n                            index: index,\n                        })\n                    );\n                });\n            },\n\n            DID_UPDATE_ITEM_METADATA: function DID_UPDATE_ITEM_METADATA(_ref3) {\n                var id = _ref3.id,\n                    action = _ref3.action,\n                    change = _ref3.change;\n                // don't do anything\n                if (change.silent) return;\n\n                // if is called multiple times in close succession we combined all calls together to save resources\n                clearTimeout(state.itemUpdateTimeout);\n                state.itemUpdateTimeout = setTimeout(function() {\n                    var item = getItemById(state.items, id);\n\n                    // only revert and attempt to upload when we're uploading to a server\n                    if (!query('IS_ASYNC')) {\n                        // should we update the output data\n                        applyFilterChain('SHOULD_PREPARE_OUTPUT', false, {\n                            item: item,\n                            query: query,\n                            action: action,\n                            change: change,\n                        }).then(function(shouldPrepareOutput) {\n                            // plugins determined the output data should be prepared (or not), can be adjusted with beforePrepareOutput hook\n                            var beforePrepareFile = query('GET_BEFORE_PREPARE_FILE');\n                            if (beforePrepareFile)\n                                shouldPrepareOutput = beforePrepareFile(item, shouldPrepareOutput);\n\n                            if (!shouldPrepareOutput) return;\n\n                            dispatch(\n                                'REQUEST_PREPARE_OUTPUT',\n                                {\n                                    query: id,\n                                    item: item,\n                                    success: function success(file) {\n                                        dispatch('DID_PREPARE_OUTPUT', { id: id, file: file });\n                                    },\n                                },\n\n                                true\n                            );\n                        });\n\n                        return;\n                    }\n\n                    // if is local item we need to enable upload button so change can be propagated to server\n                    if (item.origin === FileOrigin.LOCAL) {\n                        dispatch('DID_LOAD_ITEM', {\n                            id: item.id,\n                            error: null,\n                            serverFileReference: item.source,\n                        });\n                    }\n\n                    // for async scenarios\n                    var upload = function upload() {\n                        // we push this forward a bit so the interface is updated correctly\n                        setTimeout(function() {\n                            dispatch('REQUEST_ITEM_PROCESSING', { query: id });\n                        }, 32);\n                    };\n\n                    var revert = function revert(doUpload) {\n                        item.revert(\n                            createRevertFunction(\n                                state.options.server.url,\n                                state.options.server.revert\n                            ),\n                            query('GET_FORCE_REVERT')\n                        )\n                            .then(doUpload ? upload : function() {})\n                            .catch(function() {});\n                    };\n\n                    var abort = function abort(doUpload) {\n                        item.abortProcessing().then(doUpload ? upload : function() {});\n                    };\n\n                    // if we should re-upload the file immediately\n                    if (item.status === ItemStatus.PROCESSING_COMPLETE) {\n                        return revert(state.options.instantUpload);\n                    }\n\n                    // if currently uploading, cancel upload\n                    if (item.status === ItemStatus.PROCESSING) {\n                        return abort(state.options.instantUpload);\n                    }\n\n                    if (state.options.instantUpload) {\n                        upload();\n                    }\n                }, 0);\n            },\n\n            MOVE_ITEM: function MOVE_ITEM(_ref4) {\n                var query = _ref4.query,\n                    index = _ref4.index;\n                var item = getItemByQuery(state.items, query);\n                if (!item) return;\n                var currentIndex = state.items.indexOf(item);\n                index = limit(index, 0, state.items.length - 1);\n                if (currentIndex === index) return;\n                state.items.splice(index, 0, state.items.splice(currentIndex, 1)[0]);\n            },\n\n            SORT: function SORT(_ref5) {\n                var compare = _ref5.compare;\n                sortItems(state, compare);\n                dispatch('DID_SORT_ITEMS', {\n                    items: query('GET_ACTIVE_ITEMS'),\n                });\n            },\n\n            ADD_ITEMS: function ADD_ITEMS(_ref6) {\n                var items = _ref6.items,\n                    index = _ref6.index,\n                    interactionMethod = _ref6.interactionMethod,\n                    _ref6$success = _ref6.success,\n                    success = _ref6$success === void 0 ? function() {} : _ref6$success,\n                    _ref6$failure = _ref6.failure,\n                    failure = _ref6$failure === void 0 ? function() {} : _ref6$failure;\n                var currentIndex = index;\n\n                if (index === -1 || typeof index === 'undefined') {\n                    var insertLocation = query('GET_ITEM_INSERT_LOCATION');\n                    var totalItems = query('GET_TOTAL_ITEMS');\n                    currentIndex = insertLocation === 'before' ? 0 : totalItems;\n                }\n\n                var ignoredFiles = query('GET_IGNORED_FILES');\n                var isValidFile = function isValidFile(source) {\n                    return isFile(source)\n                        ? !ignoredFiles.includes(source.name.toLowerCase())\n                        : !isEmpty(source);\n                };\n                var validItems = items.filter(isValidFile);\n\n                var promises = validItems.map(function(source) {\n                    return new Promise(function(resolve, reject) {\n                        dispatch('ADD_ITEM', {\n                            interactionMethod: interactionMethod,\n                            source: source.source || source,\n                            success: resolve,\n                            failure: reject,\n                            index: currentIndex++,\n                            options: source.options || {},\n                        });\n                    });\n                });\n\n                Promise.all(promises)\n                    .then(success)\n                    .catch(failure);\n            },\n\n            /**\n             * @param source\n             * @param index\n             * @param interactionMethod\n             */\n            ADD_ITEM: function ADD_ITEM(_ref7) {\n                var source = _ref7.source,\n                    _ref7$index = _ref7.index,\n                    index = _ref7$index === void 0 ? -1 : _ref7$index,\n                    interactionMethod = _ref7.interactionMethod,\n                    _ref7$success = _ref7.success,\n                    success = _ref7$success === void 0 ? function() {} : _ref7$success,\n                    _ref7$failure = _ref7.failure,\n                    failure = _ref7$failure === void 0 ? function() {} : _ref7$failure,\n                    _ref7$options = _ref7.options,\n                    options = _ref7$options === void 0 ? {} : _ref7$options;\n                // if no source supplied\n                if (isEmpty(source)) {\n                    failure({\n                        error: createResponse('error', 0, 'No source'),\n                        file: null,\n                    });\n\n                    return;\n                }\n\n                // filter out invalid file items, used to filter dropped directory contents\n                if (\n                    isFile(source) &&\n                    state.options.ignoredFiles.includes(source.name.toLowerCase())\n                ) {\n                    // fail silently\n                    return;\n                }\n\n                // test if there's still room in the list of files\n                if (!hasRoomForItem(state)) {\n                    // if multiple allowed, we can't replace\n                    // or if only a single item is allowed but we're not allowed to replace it we exit\n                    if (\n                        state.options.allowMultiple ||\n                        (!state.options.allowMultiple && !state.options.allowReplace)\n                    ) {\n                        var error = createResponse('warning', 0, 'Max files');\n\n                        dispatch('DID_THROW_MAX_FILES', {\n                            source: source,\n                            error: error,\n                        });\n\n                        failure({ error: error, file: null });\n\n                        return;\n                    }\n\n                    // let's replace the item\n                    // id of first item we're about to remove\n                    var _item = getActiveItems(state.items)[0];\n\n                    // if has been processed remove it from the server as well\n                    if (\n                        _item.status === ItemStatus.PROCESSING_COMPLETE ||\n                        _item.status === ItemStatus.PROCESSING_REVERT_ERROR\n                    ) {\n                        var forceRevert = query('GET_FORCE_REVERT');\n                        _item\n                            .revert(\n                                createRevertFunction(\n                                    state.options.server.url,\n                                    state.options.server.revert\n                                ),\n                                forceRevert\n                            )\n                            .then(function() {\n                                if (!forceRevert) return;\n\n                                // try to add now\n                                dispatch('ADD_ITEM', {\n                                    source: source,\n                                    index: index,\n                                    interactionMethod: interactionMethod,\n                                    success: success,\n                                    failure: failure,\n                                    options: options,\n                                });\n                            })\n                            .catch(function() {}); // no need to handle this catch state for now\n\n                        if (forceRevert) return;\n                    }\n\n                    // remove first item as it will be replaced by this item\n                    dispatch('REMOVE_ITEM', { query: _item.id });\n                }\n\n                // where did the file originate\n                var origin =\n                    options.type === 'local'\n                        ? FileOrigin.LOCAL\n                        : options.type === 'limbo'\n                        ? FileOrigin.LIMBO\n                        : FileOrigin.INPUT;\n\n                // create a new blank item\n                var item = createItem(\n                    // where did this file come from\n                    origin,\n\n                    // an input file never has a server file reference\n                    origin === FileOrigin.INPUT ? null : source,\n\n                    // file mock data, if defined\n                    options.file\n                );\n\n                // set initial meta data\n                Object.keys(options.metadata || {}).forEach(function(key) {\n                    item.setMetadata(key, options.metadata[key]);\n                });\n\n                // created the item, let plugins add methods\n                applyFilters('DID_CREATE_ITEM', item, { query: query, dispatch: dispatch });\n\n                // where to insert new items\n                var itemInsertLocation = query('GET_ITEM_INSERT_LOCATION');\n\n                // adjust index if is not allowed to pick location\n                if (!state.options.itemInsertLocationFreedom) {\n                    index = itemInsertLocation === 'before' ? -1 : state.items.length;\n                }\n\n                // add item to list\n                insertItem(state.items, item, index);\n\n                // sort items in list\n                if (isFunction(itemInsertLocation) && source) {\n                    sortItems(state, itemInsertLocation);\n                }\n\n                // get a quick reference to the item id\n                var id = item.id;\n\n                // observe item events\n                item.on('init', function() {\n                    dispatch('DID_INIT_ITEM', { id: id });\n                });\n\n                item.on('load-init', function() {\n                    dispatch('DID_START_ITEM_LOAD', { id: id });\n                });\n\n                item.on('load-meta', function() {\n                    dispatch('DID_UPDATE_ITEM_META', { id: id });\n                });\n\n                item.on('load-progress', function(progress) {\n                    dispatch('DID_UPDATE_ITEM_LOAD_PROGRESS', { id: id, progress: progress });\n                });\n\n                item.on('load-request-error', function(error) {\n                    var mainStatus = dynamicLabel(state.options.labelFileLoadError)(error);\n\n                    // is client error, no way to recover\n                    if (error.code >= 400 && error.code < 500) {\n                        dispatch('DID_THROW_ITEM_INVALID', {\n                            id: id,\n                            error: error,\n                            status: {\n                                main: mainStatus,\n                                sub: error.code + ' (' + error.body + ')',\n                            },\n                        });\n\n                        // reject the file so can be dealt with through API\n                        failure({ error: error, file: createItemAPI(item) });\n                        return;\n                    }\n\n                    // is possible server error, so might be possible to retry\n                    dispatch('DID_THROW_ITEM_LOAD_ERROR', {\n                        id: id,\n                        error: error,\n                        status: {\n                            main: mainStatus,\n                            sub: state.options.labelTapToRetry,\n                        },\n                    });\n                });\n\n                item.on('load-file-error', function(error) {\n                    dispatch('DID_THROW_ITEM_INVALID', {\n                        id: id,\n                        error: error.status,\n                        status: error.status,\n                    });\n\n                    failure({ error: error.status, file: createItemAPI(item) });\n                });\n\n                item.on('load-abort', function() {\n                    dispatch('REMOVE_ITEM', { query: id });\n                });\n\n                item.on('load-skip', function() {\n                    item.on('metadata-update', function(change) {\n                        if (!isFile(item.file)) return;\n                        dispatch('DID_UPDATE_ITEM_METADATA', { id: id, change: change });\n                    });\n\n                    dispatch('COMPLETE_LOAD_ITEM', {\n                        query: id,\n                        item: item,\n                        data: {\n                            source: source,\n                            success: success,\n                        },\n                    });\n                });\n\n                item.on('load', function() {\n                    var handleAdd = function handleAdd(shouldAdd) {\n                        // no should not add this file\n                        if (!shouldAdd) {\n                            dispatch('REMOVE_ITEM', {\n                                query: id,\n                            });\n\n                            return;\n                        }\n\n                        // now interested in metadata updates\n                        item.on('metadata-update', function(change) {\n                            dispatch('DID_UPDATE_ITEM_METADATA', { id: id, change: change });\n                        });\n\n                        // let plugins decide if the output data should be prepared at this point\n                        // means we'll do this and wait for idle state\n                        applyFilterChain('SHOULD_PREPARE_OUTPUT', false, {\n                            item: item,\n                            query: query,\n                        }).then(function(shouldPrepareOutput) {\n                            // plugins determined the output data should be prepared (or not), can be adjusted with beforePrepareOutput hook\n                            var beforePrepareFile = query('GET_BEFORE_PREPARE_FILE');\n                            if (beforePrepareFile)\n                                shouldPrepareOutput = beforePrepareFile(item, shouldPrepareOutput);\n\n                            var loadComplete = function loadComplete() {\n                                dispatch('COMPLETE_LOAD_ITEM', {\n                                    query: id,\n                                    item: item,\n                                    data: {\n                                        source: source,\n                                        success: success,\n                                    },\n                                });\n\n                                listUpdated(dispatch, state);\n                            };\n\n                            // exit\n                            if (shouldPrepareOutput) {\n                                // wait for idle state and then run PREPARE_OUTPUT\n                                dispatch(\n                                    'REQUEST_PREPARE_OUTPUT',\n                                    {\n                                        query: id,\n                                        item: item,\n                                        success: function success(file) {\n                                            dispatch('DID_PREPARE_OUTPUT', { id: id, file: file });\n                                            loadComplete();\n                                        },\n                                    },\n\n                                    true\n                                );\n\n                                return;\n                            }\n\n                            loadComplete();\n                        });\n                    };\n\n                    // item loaded, allow plugins to\n                    // - read data (quickly)\n                    // - add metadata\n                    applyFilterChain('DID_LOAD_ITEM', item, { query: query, dispatch: dispatch })\n                        .then(function() {\n                            optionalPromise(query('GET_BEFORE_ADD_FILE'), createItemAPI(item)).then(\n                                handleAdd\n                            );\n                        })\n                        .catch(function(e) {\n                            if (!e || !e.error || !e.status) return handleAdd(false);\n                            dispatch('DID_THROW_ITEM_INVALID', {\n                                id: id,\n                                error: e.error,\n                                status: e.status,\n                            });\n                        });\n                });\n\n                item.on('process-start', function() {\n                    dispatch('DID_START_ITEM_PROCESSING', { id: id });\n                });\n\n                item.on('process-progress', function(progress) {\n                    dispatch('DID_UPDATE_ITEM_PROCESS_PROGRESS', { id: id, progress: progress });\n                });\n\n                item.on('process-error', function(error) {\n                    dispatch('DID_THROW_ITEM_PROCESSING_ERROR', {\n                        id: id,\n                        error: error,\n                        status: {\n                            main: dynamicLabel(state.options.labelFileProcessingError)(error),\n                            sub: state.options.labelTapToRetry,\n                        },\n                    });\n                });\n\n                item.on('process-revert-error', function(error) {\n                    dispatch('DID_THROW_ITEM_PROCESSING_REVERT_ERROR', {\n                        id: id,\n                        error: error,\n                        status: {\n                            main: dynamicLabel(state.options.labelFileProcessingRevertError)(error),\n                            sub: state.options.labelTapToRetry,\n                        },\n                    });\n                });\n\n                item.on('process-complete', function(serverFileReference) {\n                    dispatch('DID_COMPLETE_ITEM_PROCESSING', {\n                        id: id,\n                        error: null,\n                        serverFileReference: serverFileReference,\n                    });\n\n                    dispatch('DID_DEFINE_VALUE', { id: id, value: serverFileReference });\n                });\n\n                item.on('process-abort', function() {\n                    dispatch('DID_ABORT_ITEM_PROCESSING', { id: id });\n                });\n\n                item.on('process-revert', function() {\n                    dispatch('DID_REVERT_ITEM_PROCESSING', { id: id });\n                    dispatch('DID_DEFINE_VALUE', { id: id, value: null });\n                });\n\n                // let view know the item has been inserted\n                dispatch('DID_ADD_ITEM', {\n                    id: id,\n                    index: index,\n                    interactionMethod: interactionMethod,\n                });\n\n                listUpdated(dispatch, state);\n\n                // start loading the source\n                var _ref8 = state.options.server || {},\n                    url = _ref8.url,\n                    load = _ref8.load,\n                    restore = _ref8.restore,\n                    fetch = _ref8.fetch;\n\n                item.load(\n                    source,\n\n                    // this creates a function that loads the file based on the type of file (string, base64, blob, file) and location of file (local, remote, limbo)\n                    createFileLoader(\n                        origin === FileOrigin.INPUT\n                            ? // input, if is remote, see if should use custom fetch, else use default fetchBlob\n                              isString(source) && isExternalURL(source)\n                                ? fetch\n                                    ? createFetchFunction(url, fetch)\n                                    : fetchBlob // remote url\n                                : fetchBlob // try to fetch url\n                            : // limbo or local\n                            origin === FileOrigin.LIMBO\n                            ? createFetchFunction(url, restore) // limbo\n                            : createFetchFunction(url, load) // local\n                    ),\n\n                    // called when the file is loaded so it can be piped through the filters\n                    function(file, success, error) {\n                        // let's process the file\n                        applyFilterChain('LOAD_FILE', file, { query: query })\n                            .then(success)\n                            .catch(error);\n                    }\n                );\n            },\n\n            REQUEST_PREPARE_OUTPUT: function REQUEST_PREPARE_OUTPUT(_ref9) {\n                var item = _ref9.item,\n                    success = _ref9.success,\n                    _ref9$failure = _ref9.failure,\n                    failure = _ref9$failure === void 0 ? function() {} : _ref9$failure;\n                // error response if item archived\n                var err = {\n                    error: createResponse('error', 0, 'Item not found'),\n                    file: null,\n                };\n\n                // don't handle archived items, an item could have been archived (load aborted) while waiting to be prepared\n                if (item.archived) return failure(err);\n\n                // allow plugins to alter the file data\n                applyFilterChain('PREPARE_OUTPUT', item.file, { query: query, item: item }).then(\n                    function(result) {\n                        applyFilterChain('COMPLETE_PREPARE_OUTPUT', result, {\n                            query: query,\n                            item: item,\n                        }).then(function(result) {\n                            // don't handle archived items, an item could have been archived (load aborted) while being prepared\n                            if (item.archived) return failure(err);\n\n                            // we done!\n                            success(result);\n                        });\n                    }\n                );\n            },\n\n            COMPLETE_LOAD_ITEM: function COMPLETE_LOAD_ITEM(_ref10) {\n                var item = _ref10.item,\n                    data = _ref10.data;\n                var success = data.success,\n                    source = data.source;\n\n                // sort items in list\n                var itemInsertLocation = query('GET_ITEM_INSERT_LOCATION');\n                if (isFunction(itemInsertLocation) && source) {\n                    sortItems(state, itemInsertLocation);\n                }\n\n                // let interface know the item has loaded\n                dispatch('DID_LOAD_ITEM', {\n                    id: item.id,\n                    error: null,\n                    serverFileReference: item.origin === FileOrigin.INPUT ? null : source,\n                });\n\n                // item has been successfully loaded and added to the\n                // list of items so can now be safely returned for use\n                success(createItemAPI(item));\n\n                // if this is a local server file we need to show a different state\n                if (item.origin === FileOrigin.LOCAL) {\n                    dispatch('DID_LOAD_LOCAL_ITEM', { id: item.id });\n                    return;\n                }\n\n                // if is a temp server file we prevent async upload call here (as the file is already on the server)\n                if (item.origin === FileOrigin.LIMBO) {\n                    dispatch('DID_COMPLETE_ITEM_PROCESSING', {\n                        id: item.id,\n                        error: null,\n                        serverFileReference: source,\n                    });\n\n                    dispatch('DID_DEFINE_VALUE', {\n                        id: item.id,\n                        value: item.serverId || source,\n                    });\n\n                    return;\n                }\n\n                // id we are allowed to upload the file immediately, lets do it\n                if (query('IS_ASYNC') && state.options.instantUpload) {\n                    dispatch('REQUEST_ITEM_PROCESSING', { query: item.id });\n                }\n            },\n\n            RETRY_ITEM_LOAD: getItemByQueryFromState(state, function(item) {\n                // try loading the source one more time\n                item.retryLoad();\n            }),\n\n            REQUEST_ITEM_PREPARE: getItemByQueryFromState(state, function(item, _success, failure) {\n                dispatch(\n                    'REQUEST_PREPARE_OUTPUT',\n                    {\n                        query: item.id,\n                        item: item,\n                        success: function success(file) {\n                            dispatch('DID_PREPARE_OUTPUT', { id: item.id, file: file });\n                            _success({\n                                file: item,\n                                output: file,\n                            });\n                        },\n                        failure: failure,\n                    },\n\n                    true\n                );\n            }),\n\n            REQUEST_ITEM_PROCESSING: getItemByQueryFromState(state, function(\n                item,\n                success,\n                failure\n            ) {\n                // cannot be queued (or is already queued)\n                var itemCanBeQueuedForProcessing =\n                    // waiting for something\n                    item.status === ItemStatus.IDLE ||\n                    // processing went wrong earlier\n                    item.status === ItemStatus.PROCESSING_ERROR;\n\n                // not ready to be processed\n                if (!itemCanBeQueuedForProcessing) {\n                    var processNow = function processNow() {\n                        return dispatch('REQUEST_ITEM_PROCESSING', {\n                            query: item,\n                            success: success,\n                            failure: failure,\n                        });\n                    };\n\n                    var process = function process() {\n                        return document.hidden ? processNow() : setTimeout(processNow, 32);\n                    };\n\n                    // if already done processing or tried to revert but didn't work, try again\n                    if (\n                        item.status === ItemStatus.PROCESSING_COMPLETE ||\n                        item.status === ItemStatus.PROCESSING_REVERT_ERROR\n                    ) {\n                        item.revert(\n                            createRevertFunction(\n                                state.options.server.url,\n                                state.options.server.revert\n                            ),\n                            query('GET_FORCE_REVERT')\n                        )\n                            .then(process)\n                            .catch(function() {}); // don't continue with processing if something went wrong\n                    } else if (item.status === ItemStatus.PROCESSING) {\n                        item.abortProcessing().then(process);\n                    }\n\n                    return;\n                }\n\n                // already queued for processing\n                if (item.status === ItemStatus.PROCESSING_QUEUED) return;\n\n                item.requestProcessing();\n\n                dispatch('DID_REQUEST_ITEM_PROCESSING', { id: item.id });\n\n                dispatch('PROCESS_ITEM', { query: item, success: success, failure: failure }, true);\n            }),\n\n            PROCESS_ITEM: getItemByQueryFromState(state, function(item, success, failure) {\n                var maxParallelUploads = query('GET_MAX_PARALLEL_UPLOADS');\n                var totalCurrentUploads = query('GET_ITEMS_BY_STATUS', ItemStatus.PROCESSING)\n                    .length;\n\n                // queue and wait till queue is freed up\n                if (totalCurrentUploads === maxParallelUploads) {\n                    // queue for later processing\n                    state.processingQueue.push({\n                        id: item.id,\n                        success: success,\n                        failure: failure,\n                    });\n\n                    // stop it!\n                    return;\n                }\n\n                // if was not queued or is already processing exit here\n                if (item.status === ItemStatus.PROCESSING) return;\n\n                var processNext = function processNext() {\n                    // process queueud items\n                    var queueEntry = state.processingQueue.shift();\n\n                    // no items left\n                    if (!queueEntry) return;\n\n                    // get item reference\n                    var id = queueEntry.id,\n                        success = queueEntry.success,\n                        failure = queueEntry.failure;\n                    var itemReference = getItemByQuery(state.items, id);\n\n                    // if item was archived while in queue, jump to next\n                    if (!itemReference || itemReference.archived) {\n                        processNext();\n                        return;\n                    }\n\n                    // process queued item\n                    dispatch(\n                        'PROCESS_ITEM',\n                        { query: id, success: success, failure: failure },\n                        true\n                    );\n                };\n\n                // we done function\n                item.onOnce('process-complete', function() {\n                    success(createItemAPI(item));\n                    processNext();\n\n                    // if origin is local, and we're instant uploading, trigger remove of original\n                    // as revert will remove file from list\n                    var server = state.options.server;\n                    var instantUpload = state.options.instantUpload;\n                    if (\n                        instantUpload &&\n                        item.origin === FileOrigin.LOCAL &&\n                        isFunction(server.remove)\n                    ) {\n                        var noop = function noop() {};\n                        item.origin = FileOrigin.LIMBO;\n                        state.options.server.remove(item.source, noop, noop);\n                    }\n\n                    // All items processed? No errors?\n                    var allItemsProcessed =\n                        query('GET_ITEMS_BY_STATUS', ItemStatus.PROCESSING_COMPLETE).length ===\n                        state.items.length;\n                    if (allItemsProcessed) {\n                        dispatch('DID_COMPLETE_ITEM_PROCESSING_ALL');\n                    }\n                });\n\n                // we error function\n                item.onOnce('process-error', function(error) {\n                    failure({ error: error, file: createItemAPI(item) });\n                    processNext();\n                });\n\n                // abort function\n                item.onOnce('process-abort', function() {\n                    processNext();\n                });\n\n                // start file processing\n                var options = state.options;\n                item.process(\n                    createFileProcessor(\n                        createProcessorFunction(\n                            options.server.url,\n                            options.server.process,\n                            options.name,\n                            {\n                                chunkTransferId: item.transferId,\n                                chunkServer: options.server.patch,\n                                chunkUploads: options.chunkUploads,\n                                chunkForce: options.chunkForce,\n                                chunkSize: options.chunkSize,\n                                chunkRetryDelays: options.chunkRetryDelays,\n                            }\n                        ),\n\n                        {\n                            allowMinimumUploadDuration: query('GET_ALLOW_MINIMUM_UPLOAD_DURATION'),\n                        }\n                    ),\n\n                    // called when the file is about to be processed so it can be piped through the transform filters\n                    function(file, success, error) {\n                        // allow plugins to alter the file data\n                        applyFilterChain('PREPARE_OUTPUT', file, { query: query, item: item })\n                            .then(function(file) {\n                                dispatch('DID_PREPARE_OUTPUT', { id: item.id, file: file });\n\n                                success(file);\n                            })\n                            .catch(error);\n                    }\n                );\n            }),\n\n            RETRY_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n                dispatch('REQUEST_ITEM_PROCESSING', { query: item });\n            }),\n\n            REQUEST_REMOVE_ITEM: getItemByQueryFromState(state, function(item) {\n                optionalPromise(query('GET_BEFORE_REMOVE_FILE'), createItemAPI(item)).then(function(\n                    shouldRemove\n                ) {\n                    if (!shouldRemove) {\n                        return;\n                    }\n                    dispatch('REMOVE_ITEM', { query: item });\n                });\n            }),\n\n            RELEASE_ITEM: getItemByQueryFromState(state, function(item) {\n                item.release();\n            }),\n\n            REMOVE_ITEM: getItemByQueryFromState(state, function(item, success, failure, options) {\n                var removeFromView = function removeFromView() {\n                    // get id reference\n                    var id = item.id;\n\n                    // archive the item, this does not remove it from the list\n                    getItemById(state.items, id).archive();\n\n                    // tell the view the item has been removed\n                    dispatch('DID_REMOVE_ITEM', { error: null, id: id, item: item });\n\n                    // now the list has been modified\n                    listUpdated(dispatch, state);\n\n                    // correctly removed\n                    success(createItemAPI(item));\n                };\n\n                // if this is a local file and the `server.remove` function has been configured,\n                // send source there so dev can remove file from server\n                var server = state.options.server;\n                if (\n                    item.origin === FileOrigin.LOCAL &&\n                    server &&\n                    isFunction(server.remove) &&\n                    options.remove !== false\n                ) {\n                    dispatch('DID_START_ITEM_REMOVE', { id: item.id });\n\n                    server.remove(\n                        item.source,\n                        function() {\n                            return removeFromView();\n                        },\n                        function(status) {\n                            dispatch('DID_THROW_ITEM_REMOVE_ERROR', {\n                                id: item.id,\n                                error: createResponse('error', 0, status, null),\n                                status: {\n                                    main: dynamicLabel(state.options.labelFileRemoveError)(status),\n                                    sub: state.options.labelTapToRetry,\n                                },\n                            });\n                        }\n                    );\n                } else {\n                    // if is requesting revert and can revert need to call revert handler (not calling request_ because that would also trigger beforeRemoveHook)\n                    if (\n                        (options.revert &&\n                            item.origin !== FileOrigin.LOCAL &&\n                            item.serverId !== null) ||\n                        // if chunked uploads are enabled and we're uploading in chunks for this specific file\n                        // or if the file isn't big enough for chunked uploads but chunkForce is set then call\n                        // revert before removing from the view...\n                        (state.options.chunkUploads && item.file.size > state.options.chunkSize) ||\n                        (state.options.chunkUploads && state.options.chunkForce)\n                    ) {\n                        item.revert(\n                            createRevertFunction(\n                                state.options.server.url,\n                                state.options.server.revert\n                            ),\n                            query('GET_FORCE_REVERT')\n                        );\n                    }\n\n                    // can now safely remove from view\n                    removeFromView();\n                }\n            }),\n\n            ABORT_ITEM_LOAD: getItemByQueryFromState(state, function(item) {\n                item.abortLoad();\n            }),\n\n            ABORT_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n                // test if is already processed\n                if (item.serverId) {\n                    dispatch('REVERT_ITEM_PROCESSING', { id: item.id });\n                    return;\n                }\n\n                // abort\n                item.abortProcessing().then(function() {\n                    var shouldRemove = state.options.instantUpload;\n                    if (shouldRemove) {\n                        dispatch('REMOVE_ITEM', { query: item.id });\n                    }\n                });\n            }),\n\n            REQUEST_REVERT_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n                // not instant uploading, revert immediately\n                if (!state.options.instantUpload) {\n                    dispatch('REVERT_ITEM_PROCESSING', { query: item });\n                    return;\n                }\n\n                // if we're instant uploading the file will also be removed if we revert,\n                // so if a before remove file hook is defined we need to run it now\n                var handleRevert = function handleRevert(shouldRevert) {\n                    if (!shouldRevert) return;\n                    dispatch('REVERT_ITEM_PROCESSING', { query: item });\n                };\n\n                var fn = query('GET_BEFORE_REMOVE_FILE');\n                if (!fn) {\n                    return handleRevert(true);\n                }\n\n                var requestRemoveResult = fn(createItemAPI(item));\n                if (requestRemoveResult == null) {\n                    // undefined or null\n                    return handleRevert(true);\n                }\n\n                if (typeof requestRemoveResult === 'boolean') {\n                    return handleRevert(requestRemoveResult);\n                }\n\n                if (typeof requestRemoveResult.then === 'function') {\n                    requestRemoveResult.then(handleRevert);\n                }\n            }),\n\n            REVERT_ITEM_PROCESSING: getItemByQueryFromState(state, function(item) {\n                item.revert(\n                    createRevertFunction(state.options.server.url, state.options.server.revert),\n                    query('GET_FORCE_REVERT')\n                )\n                    .then(function() {\n                        var shouldRemove = state.options.instantUpload || isMockItem(item);\n                        if (shouldRemove) {\n                            dispatch('REMOVE_ITEM', { query: item.id });\n                        }\n                    })\n                    .catch(function() {});\n            }),\n\n            SET_OPTIONS: function SET_OPTIONS(_ref11) {\n                var options = _ref11.options;\n                // get all keys passed\n                var optionKeys = Object.keys(options);\n\n                // get prioritized keyed to include (remove once not in options object)\n                var prioritizedOptionKeys = PrioritizedOptions.filter(function(key) {\n                    return optionKeys.includes(key);\n                });\n\n                // order the keys, prioritized first, then rest\n                var orderedOptionKeys = [].concat(\n                    _toConsumableArray(prioritizedOptionKeys),\n                    _toConsumableArray(\n                        Object.keys(options).filter(function(key) {\n                            return !prioritizedOptionKeys.includes(key);\n                        })\n                    )\n                );\n\n                // dispatch set event for each option\n                orderedOptionKeys.forEach(function(key) {\n                    dispatch('SET_' + fromCamels(key, '_').toUpperCase(), {\n                        value: options[key],\n                    });\n                });\n            },\n        };\n    };\n\n    var PrioritizedOptions = ['server'];\n\n    var formatFilename = function formatFilename(name) {\n        return name;\n    };\n\n    var createElement$1 = function createElement(tagName) {\n        return document.createElement(tagName);\n    };\n\n    var text = function text(node, value) {\n        var textNode = node.childNodes[0];\n        if (!textNode) {\n            textNode = document.createTextNode(value);\n            node.appendChild(textNode);\n        } else if (value !== textNode.nodeValue) {\n            textNode.nodeValue = value;\n        }\n    };\n\n    var polarToCartesian = function polarToCartesian(centerX, centerY, radius, angleInDegrees) {\n        var angleInRadians = (((angleInDegrees % 360) - 90) * Math.PI) / 180.0;\n        return {\n            x: centerX + radius * Math.cos(angleInRadians),\n            y: centerY + radius * Math.sin(angleInRadians),\n        };\n    };\n\n    var describeArc = function describeArc(x, y, radius, startAngle, endAngle, arcSweep) {\n        var start = polarToCartesian(x, y, radius, endAngle);\n        var end = polarToCartesian(x, y, radius, startAngle);\n        return ['M', start.x, start.y, 'A', radius, radius, 0, arcSweep, 0, end.x, end.y].join(' ');\n    };\n\n    var percentageArc = function percentageArc(x, y, radius, from, to) {\n        var arcSweep = 1;\n        if (to > from && to - from <= 0.5) {\n            arcSweep = 0;\n        }\n        if (from > to && from - to >= 0.5) {\n            arcSweep = 0;\n        }\n        return describeArc(\n            x,\n            y,\n            radius,\n            Math.min(0.9999, from) * 360,\n            Math.min(0.9999, to) * 360,\n            arcSweep\n        );\n    };\n\n    var create = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        // start at 0\n        props.spin = false;\n        props.progress = 0;\n        props.opacity = 0;\n\n        // svg\n        var svg = createElement('svg');\n        root.ref.path = createElement('path', {\n            'stroke-width': 2,\n            'stroke-linecap': 'round',\n        });\n\n        svg.appendChild(root.ref.path);\n\n        root.ref.svg = svg;\n\n        root.appendChild(svg);\n    };\n\n    var write = function write(_ref2) {\n        var root = _ref2.root,\n            props = _ref2.props;\n        if (props.opacity === 0) {\n            return;\n        }\n\n        if (props.align) {\n            root.element.dataset.align = props.align;\n        }\n\n        // get width of stroke\n        var ringStrokeWidth = parseInt(attr(root.ref.path, 'stroke-width'), 10);\n\n        // calculate size of ring\n        var size = root.rect.element.width * 0.5;\n\n        // ring state\n        var ringFrom = 0;\n        var ringTo = 0;\n\n        // now in busy mode\n        if (props.spin) {\n            ringFrom = 0;\n            ringTo = 0.5;\n        } else {\n            ringFrom = 0;\n            ringTo = props.progress;\n        }\n\n        // get arc path\n        var coordinates = percentageArc(size, size, size - ringStrokeWidth, ringFrom, ringTo);\n\n        // update progress bar\n        attr(root.ref.path, 'd', coordinates);\n\n        // hide while contains 0 value\n        attr(root.ref.path, 'stroke-opacity', props.spin || props.progress > 0 ? 1 : 0);\n    };\n\n    var progressIndicator = createView({\n        tag: 'div',\n        name: 'progress-indicator',\n        ignoreRectUpdate: true,\n        ignoreRect: true,\n        create: create,\n        write: write,\n        mixins: {\n            apis: ['progress', 'spin', 'align'],\n            styles: ['opacity'],\n            animations: {\n                opacity: { type: 'tween', duration: 500 },\n                progress: {\n                    type: 'spring',\n                    stiffness: 0.95,\n                    damping: 0.65,\n                    mass: 10,\n                },\n            },\n        },\n    });\n\n    var create$1 = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        root.element.innerHTML = (props.icon || '') + ('<span>' + props.label + '</span>');\n\n        props.isDisabled = false;\n    };\n\n    var write$1 = function write(_ref2) {\n        var root = _ref2.root,\n            props = _ref2.props;\n        var isDisabled = props.isDisabled;\n        var shouldDisable = root.query('GET_DISABLED') || props.opacity === 0;\n\n        if (shouldDisable && !isDisabled) {\n            props.isDisabled = true;\n            attr(root.element, 'disabled', 'disabled');\n        } else if (!shouldDisable && isDisabled) {\n            props.isDisabled = false;\n            root.element.removeAttribute('disabled');\n        }\n    };\n\n    var fileActionButton = createView({\n        tag: 'button',\n        attributes: {\n            type: 'button',\n        },\n\n        ignoreRect: true,\n        ignoreRectUpdate: true,\n        name: 'file-action-button',\n        mixins: {\n            apis: ['label'],\n            styles: ['translateX', 'translateY', 'scaleX', 'scaleY', 'opacity'],\n            animations: {\n                scaleX: 'spring',\n                scaleY: 'spring',\n                translateX: 'spring',\n                translateY: 'spring',\n                opacity: { type: 'tween', duration: 250 },\n            },\n\n            listeners: true,\n        },\n\n        create: create$1,\n        write: write$1,\n    });\n\n    var toNaturalFileSize = function toNaturalFileSize(bytes) {\n        var decimalSeparator =\n            arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '.';\n        var base = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;\n        var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n        var _options$labelBytes = options.labelBytes,\n            labelBytes = _options$labelBytes === void 0 ? 'bytes' : _options$labelBytes,\n            _options$labelKilobyt = options.labelKilobytes,\n            labelKilobytes = _options$labelKilobyt === void 0 ? 'KB' : _options$labelKilobyt,\n            _options$labelMegabyt = options.labelMegabytes,\n            labelMegabytes = _options$labelMegabyt === void 0 ? 'MB' : _options$labelMegabyt,\n            _options$labelGigabyt = options.labelGigabytes,\n            labelGigabytes = _options$labelGigabyt === void 0 ? 'GB' : _options$labelGigabyt;\n\n        // no negative byte sizes\n        bytes = Math.round(Math.abs(bytes));\n\n        var KB = base;\n        var MB = base * base;\n        var GB = base * base * base;\n\n        // just bytes\n        if (bytes < KB) {\n            return bytes + ' ' + labelBytes;\n        }\n\n        // kilobytes\n        if (bytes < MB) {\n            return Math.floor(bytes / KB) + ' ' + labelKilobytes;\n        }\n\n        // megabytes\n        if (bytes < GB) {\n            return removeDecimalsWhenZero(bytes / MB, 1, decimalSeparator) + ' ' + labelMegabytes;\n        }\n\n        // gigabytes\n        return removeDecimalsWhenZero(bytes / GB, 2, decimalSeparator) + ' ' + labelGigabytes;\n    };\n\n    var removeDecimalsWhenZero = function removeDecimalsWhenZero(value, decimalCount, separator) {\n        return value\n            .toFixed(decimalCount)\n            .split('.')\n            .filter(function(part) {\n                return part !== '0';\n            })\n            .join(separator);\n    };\n\n    var create$2 = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        // filename\n        var fileName = createElement$1('span');\n        fileName.className = 'filepond--file-info-main';\n        // hide for screenreaders\n        // the file is contained in a fieldset with legend that contains the filename\n        // no need to read it twice\n        attr(fileName, 'aria-hidden', 'true');\n        root.appendChild(fileName);\n        root.ref.fileName = fileName;\n\n        // filesize\n        var fileSize = createElement$1('span');\n        fileSize.className = 'filepond--file-info-sub';\n        root.appendChild(fileSize);\n        root.ref.fileSize = fileSize;\n\n        // set initial values\n        text(fileSize, root.query('GET_LABEL_FILE_WAITING_FOR_SIZE'));\n        text(fileName, formatFilename(root.query('GET_ITEM_NAME', props.id)));\n    };\n\n    var updateFile = function updateFile(_ref2) {\n        var root = _ref2.root,\n            props = _ref2.props;\n        text(\n            root.ref.fileSize,\n            toNaturalFileSize(\n                root.query('GET_ITEM_SIZE', props.id),\n                '.',\n                root.query('GET_FILE_SIZE_BASE'),\n                root.query('GET_FILE_SIZE_LABELS', root.query)\n            )\n        );\n\n        text(root.ref.fileName, formatFilename(root.query('GET_ITEM_NAME', props.id)));\n    };\n\n    var updateFileSizeOnError = function updateFileSizeOnError(_ref3) {\n        var root = _ref3.root,\n            props = _ref3.props;\n        // if size is available don't fallback to unknown size message\n        if (isInt(root.query('GET_ITEM_SIZE', props.id))) {\n            updateFile({ root: root, props: props });\n            return;\n        }\n\n        text(root.ref.fileSize, root.query('GET_LABEL_FILE_SIZE_NOT_AVAILABLE'));\n    };\n\n    var fileInfo = createView({\n        name: 'file-info',\n        ignoreRect: true,\n        ignoreRectUpdate: true,\n        write: createRoute({\n            DID_LOAD_ITEM: updateFile,\n            DID_UPDATE_ITEM_META: updateFile,\n            DID_THROW_ITEM_LOAD_ERROR: updateFileSizeOnError,\n            DID_THROW_ITEM_INVALID: updateFileSizeOnError,\n        }),\n\n        didCreateView: function didCreateView(root) {\n            applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n        },\n        create: create$2,\n        mixins: {\n            styles: ['translateX', 'translateY'],\n            animations: {\n                translateX: 'spring',\n                translateY: 'spring',\n            },\n        },\n    });\n\n    var toPercentage = function toPercentage(value) {\n        return Math.round(value * 100);\n    };\n\n    var create$3 = function create(_ref) {\n        var root = _ref.root;\n\n        // main status\n        var main = createElement$1('span');\n        main.className = 'filepond--file-status-main';\n        root.appendChild(main);\n        root.ref.main = main;\n\n        // sub status\n        var sub = createElement$1('span');\n        sub.className = 'filepond--file-status-sub';\n        root.appendChild(sub);\n        root.ref.sub = sub;\n\n        didSetItemLoadProgress({ root: root, action: { progress: null } });\n    };\n\n    var didSetItemLoadProgress = function didSetItemLoadProgress(_ref2) {\n        var root = _ref2.root,\n            action = _ref2.action;\n        var title =\n            action.progress === null\n                ? root.query('GET_LABEL_FILE_LOADING')\n                : root.query('GET_LABEL_FILE_LOADING') + ' ' + toPercentage(action.progress) + '%';\n\n        text(root.ref.main, title);\n        text(root.ref.sub, root.query('GET_LABEL_TAP_TO_CANCEL'));\n    };\n\n    var didSetItemProcessProgress = function didSetItemProcessProgress(_ref3) {\n        var root = _ref3.root,\n            action = _ref3.action;\n        var title =\n            action.progress === null\n                ? root.query('GET_LABEL_FILE_PROCESSING')\n                : root.query('GET_LABEL_FILE_PROCESSING') +\n                  ' ' +\n                  toPercentage(action.progress) +\n                  '%';\n\n        text(root.ref.main, title);\n        text(root.ref.sub, root.query('GET_LABEL_TAP_TO_CANCEL'));\n    };\n\n    var didRequestItemProcessing = function didRequestItemProcessing(_ref4) {\n        var root = _ref4.root;\n        text(root.ref.main, root.query('GET_LABEL_FILE_PROCESSING'));\n        text(root.ref.sub, root.query('GET_LABEL_TAP_TO_CANCEL'));\n    };\n\n    var didAbortItemProcessing = function didAbortItemProcessing(_ref5) {\n        var root = _ref5.root;\n        text(root.ref.main, root.query('GET_LABEL_FILE_PROCESSING_ABORTED'));\n        text(root.ref.sub, root.query('GET_LABEL_TAP_TO_RETRY'));\n    };\n\n    var didCompleteItemProcessing = function didCompleteItemProcessing(_ref6) {\n        var root = _ref6.root;\n        text(root.ref.main, root.query('GET_LABEL_FILE_PROCESSING_COMPLETE'));\n        text(root.ref.sub, root.query('GET_LABEL_TAP_TO_UNDO'));\n    };\n\n    var clear = function clear(_ref7) {\n        var root = _ref7.root;\n        text(root.ref.main, '');\n        text(root.ref.sub, '');\n    };\n\n    var error = function error(_ref8) {\n        var root = _ref8.root,\n            action = _ref8.action;\n        text(root.ref.main, action.status.main);\n        text(root.ref.sub, action.status.sub);\n    };\n\n    var fileStatus = createView({\n        name: 'file-status',\n        ignoreRect: true,\n        ignoreRectUpdate: true,\n        write: createRoute({\n            DID_LOAD_ITEM: clear,\n            DID_REVERT_ITEM_PROCESSING: clear,\n            DID_REQUEST_ITEM_PROCESSING: didRequestItemProcessing,\n            DID_ABORT_ITEM_PROCESSING: didAbortItemProcessing,\n            DID_COMPLETE_ITEM_PROCESSING: didCompleteItemProcessing,\n            DID_UPDATE_ITEM_PROCESS_PROGRESS: didSetItemProcessProgress,\n            DID_UPDATE_ITEM_LOAD_PROGRESS: didSetItemLoadProgress,\n            DID_THROW_ITEM_LOAD_ERROR: error,\n            DID_THROW_ITEM_INVALID: error,\n            DID_THROW_ITEM_PROCESSING_ERROR: error,\n            DID_THROW_ITEM_PROCESSING_REVERT_ERROR: error,\n            DID_THROW_ITEM_REMOVE_ERROR: error,\n        }),\n\n        didCreateView: function didCreateView(root) {\n            applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n        },\n        create: create$3,\n        mixins: {\n            styles: ['translateX', 'translateY', 'opacity'],\n            animations: {\n                opacity: { type: 'tween', duration: 250 },\n                translateX: 'spring',\n                translateY: 'spring',\n            },\n        },\n    });\n\n    /**\n     * Button definitions for the file view\n     */\n\n    var Buttons = {\n        AbortItemLoad: {\n            label: 'GET_LABEL_BUTTON_ABORT_ITEM_LOAD',\n            action: 'ABORT_ITEM_LOAD',\n            className: 'filepond--action-abort-item-load',\n            align: 'LOAD_INDICATOR_POSITION', // right\n        },\n        RetryItemLoad: {\n            label: 'GET_LABEL_BUTTON_RETRY_ITEM_LOAD',\n            action: 'RETRY_ITEM_LOAD',\n            icon: 'GET_ICON_RETRY',\n            className: 'filepond--action-retry-item-load',\n            align: 'BUTTON_PROCESS_ITEM_POSITION', // right\n        },\n        RemoveItem: {\n            label: 'GET_LABEL_BUTTON_REMOVE_ITEM',\n            action: 'REQUEST_REMOVE_ITEM',\n            icon: 'GET_ICON_REMOVE',\n            className: 'filepond--action-remove-item',\n            align: 'BUTTON_REMOVE_ITEM_POSITION', // left\n        },\n        ProcessItem: {\n            label: 'GET_LABEL_BUTTON_PROCESS_ITEM',\n            action: 'REQUEST_ITEM_PROCESSING',\n            icon: 'GET_ICON_PROCESS',\n            className: 'filepond--action-process-item',\n            align: 'BUTTON_PROCESS_ITEM_POSITION', // right\n        },\n        AbortItemProcessing: {\n            label: 'GET_LABEL_BUTTON_ABORT_ITEM_PROCESSING',\n            action: 'ABORT_ITEM_PROCESSING',\n            className: 'filepond--action-abort-item-processing',\n            align: 'BUTTON_PROCESS_ITEM_POSITION', // right\n        },\n        RetryItemProcessing: {\n            label: 'GET_LABEL_BUTTON_RETRY_ITEM_PROCESSING',\n            action: 'RETRY_ITEM_PROCESSING',\n            icon: 'GET_ICON_RETRY',\n            className: 'filepond--action-retry-item-processing',\n            align: 'BUTTON_PROCESS_ITEM_POSITION', // right\n        },\n        RevertItemProcessing: {\n            label: 'GET_LABEL_BUTTON_UNDO_ITEM_PROCESSING',\n            action: 'REQUEST_REVERT_ITEM_PROCESSING',\n            icon: 'GET_ICON_UNDO',\n            className: 'filepond--action-revert-item-processing',\n            align: 'BUTTON_PROCESS_ITEM_POSITION', // right\n        },\n    };\n\n    // make a list of buttons, we can then remove buttons from this list if they're disabled\n    var ButtonKeys = [];\n    forin(Buttons, function(key) {\n        ButtonKeys.push(key);\n    });\n\n    var calculateFileInfoOffset = function calculateFileInfoOffset(root) {\n        if (getRemoveIndicatorAligment(root) === 'right') return 0;\n        var buttonRect = root.ref.buttonRemoveItem.rect.element;\n        return buttonRect.hidden ? null : buttonRect.width + buttonRect.left;\n    };\n\n    var calculateButtonWidth = function calculateButtonWidth(root) {\n        var buttonRect = root.ref.buttonAbortItemLoad.rect.element;\n        return buttonRect.width;\n    };\n\n    // Force on full pixels so text stays crips\n    var calculateFileVerticalCenterOffset = function calculateFileVerticalCenterOffset(root) {\n        return Math.floor(root.ref.buttonRemoveItem.rect.element.height / 4);\n    };\n    var calculateFileHorizontalCenterOffset = function calculateFileHorizontalCenterOffset(root) {\n        return Math.floor(root.ref.buttonRemoveItem.rect.element.left / 2);\n    };\n\n    var getLoadIndicatorAlignment = function getLoadIndicatorAlignment(root) {\n        return root.query('GET_STYLE_LOAD_INDICATOR_POSITION');\n    };\n    var getProcessIndicatorAlignment = function getProcessIndicatorAlignment(root) {\n        return root.query('GET_STYLE_PROGRESS_INDICATOR_POSITION');\n    };\n    var getRemoveIndicatorAligment = function getRemoveIndicatorAligment(root) {\n        return root.query('GET_STYLE_BUTTON_REMOVE_ITEM_POSITION');\n    };\n\n    var DefaultStyle = {\n        buttonAbortItemLoad: { opacity: 0 },\n        buttonRetryItemLoad: { opacity: 0 },\n        buttonRemoveItem: { opacity: 0 },\n        buttonProcessItem: { opacity: 0 },\n        buttonAbortItemProcessing: { opacity: 0 },\n        buttonRetryItemProcessing: { opacity: 0 },\n        buttonRevertItemProcessing: { opacity: 0 },\n        loadProgressIndicator: { opacity: 0, align: getLoadIndicatorAlignment },\n        processProgressIndicator: { opacity: 0, align: getProcessIndicatorAlignment },\n        processingCompleteIndicator: { opacity: 0, scaleX: 0.75, scaleY: 0.75 },\n        info: { translateX: 0, translateY: 0, opacity: 0 },\n        status: { translateX: 0, translateY: 0, opacity: 0 },\n    };\n\n    var IdleStyle = {\n        buttonRemoveItem: { opacity: 1 },\n        buttonProcessItem: { opacity: 1 },\n        info: { translateX: calculateFileInfoOffset },\n        status: { translateX: calculateFileInfoOffset },\n    };\n\n    var ProcessingStyle = {\n        buttonAbortItemProcessing: { opacity: 1 },\n        processProgressIndicator: { opacity: 1 },\n        status: { opacity: 1 },\n    };\n\n    var StyleMap = {\n        DID_THROW_ITEM_INVALID: {\n            buttonRemoveItem: { opacity: 1 },\n            info: { translateX: calculateFileInfoOffset },\n            status: { translateX: calculateFileInfoOffset, opacity: 1 },\n        },\n\n        DID_START_ITEM_LOAD: {\n            buttonAbortItemLoad: { opacity: 1 },\n            loadProgressIndicator: { opacity: 1 },\n            status: { opacity: 1 },\n        },\n\n        DID_THROW_ITEM_LOAD_ERROR: {\n            buttonRetryItemLoad: { opacity: 1 },\n            buttonRemoveItem: { opacity: 1 },\n            info: { translateX: calculateFileInfoOffset },\n            status: { opacity: 1 },\n        },\n\n        DID_START_ITEM_REMOVE: {\n            processProgressIndicator: { opacity: 1, align: getRemoveIndicatorAligment },\n            info: { translateX: calculateFileInfoOffset },\n            status: { opacity: 0 },\n        },\n\n        DID_THROW_ITEM_REMOVE_ERROR: {\n            processProgressIndicator: { opacity: 0, align: getRemoveIndicatorAligment },\n            buttonRemoveItem: { opacity: 1 },\n            info: { translateX: calculateFileInfoOffset },\n            status: { opacity: 1, translateX: calculateFileInfoOffset },\n        },\n\n        DID_LOAD_ITEM: IdleStyle,\n        DID_LOAD_LOCAL_ITEM: {\n            buttonRemoveItem: { opacity: 1 },\n            info: { translateX: calculateFileInfoOffset },\n            status: { translateX: calculateFileInfoOffset },\n        },\n\n        DID_START_ITEM_PROCESSING: ProcessingStyle,\n        DID_REQUEST_ITEM_PROCESSING: ProcessingStyle,\n        DID_UPDATE_ITEM_PROCESS_PROGRESS: ProcessingStyle,\n        DID_COMPLETE_ITEM_PROCESSING: {\n            buttonRevertItemProcessing: { opacity: 1 },\n            info: { opacity: 1 },\n            status: { opacity: 1 },\n        },\n\n        DID_THROW_ITEM_PROCESSING_ERROR: {\n            buttonRemoveItem: { opacity: 1 },\n            buttonRetryItemProcessing: { opacity: 1 },\n            status: { opacity: 1 },\n            info: { translateX: calculateFileInfoOffset },\n        },\n\n        DID_THROW_ITEM_PROCESSING_REVERT_ERROR: {\n            buttonRevertItemProcessing: { opacity: 1 },\n            status: { opacity: 1 },\n            info: { opacity: 1 },\n        },\n\n        DID_ABORT_ITEM_PROCESSING: {\n            buttonRemoveItem: { opacity: 1 },\n            buttonProcessItem: { opacity: 1 },\n            info: { translateX: calculateFileInfoOffset },\n            status: { opacity: 1 },\n        },\n\n        DID_REVERT_ITEM_PROCESSING: IdleStyle,\n    };\n\n    // complete indicator view\n    var processingCompleteIndicatorView = createView({\n        create: function create(_ref) {\n            var root = _ref.root;\n            root.element.innerHTML = root.query('GET_ICON_DONE');\n        },\n        name: 'processing-complete-indicator',\n        ignoreRect: true,\n        mixins: {\n            styles: ['scaleX', 'scaleY', 'opacity'],\n            animations: {\n                scaleX: 'spring',\n                scaleY: 'spring',\n                opacity: { type: 'tween', duration: 250 },\n            },\n        },\n    });\n\n    /**\n     * Creates the file view\n     */\n    var create$4 = function create(_ref2) {\n        var root = _ref2.root,\n            props = _ref2.props;\n        // copy Buttons object\n        var LocalButtons = Object.keys(Buttons).reduce(function(prev, curr) {\n            prev[curr] = Object.assign({}, Buttons[curr]);\n            return prev;\n        }, {});\n        var id = props.id;\n\n        // allow reverting upload\n        var allowRevert = root.query('GET_ALLOW_REVERT');\n\n        // allow remove file\n        var allowRemove = root.query('GET_ALLOW_REMOVE');\n\n        // allow processing upload\n        var allowProcess = root.query('GET_ALLOW_PROCESS');\n\n        // is instant uploading, need this to determine the icon of the undo button\n        var instantUpload = root.query('GET_INSTANT_UPLOAD');\n\n        // is async set up\n        var isAsync = root.query('IS_ASYNC');\n\n        // should align remove item buttons\n        var alignRemoveItemButton = root.query('GET_STYLE_BUTTON_REMOVE_ITEM_ALIGN');\n\n        // enabled buttons array\n        var buttonFilter;\n        if (isAsync) {\n            if (allowProcess && !allowRevert) {\n                // only remove revert button\n                buttonFilter = function buttonFilter(key) {\n                    return !/RevertItemProcessing/.test(key);\n                };\n            } else if (!allowProcess && allowRevert) {\n                // only remove process button\n                buttonFilter = function buttonFilter(key) {\n                    return !/ProcessItem|RetryItemProcessing|AbortItemProcessing/.test(key);\n                };\n            } else if (!allowProcess && !allowRevert) {\n                // remove all process buttons\n                buttonFilter = function buttonFilter(key) {\n                    return !/Process/.test(key);\n                };\n            }\n        } else {\n            // no process controls available\n            buttonFilter = function buttonFilter(key) {\n                return !/Process/.test(key);\n            };\n        }\n\n        var enabledButtons = buttonFilter ? ButtonKeys.filter(buttonFilter) : ButtonKeys.concat();\n\n        // update icon and label for revert button when instant uploading\n        if (instantUpload && allowRevert) {\n            LocalButtons['RevertItemProcessing'].label = 'GET_LABEL_BUTTON_REMOVE_ITEM';\n            LocalButtons['RevertItemProcessing'].icon = 'GET_ICON_REMOVE';\n        }\n\n        // remove last button (revert) if not allowed\n        if (isAsync && !allowRevert) {\n            var map = StyleMap['DID_COMPLETE_ITEM_PROCESSING'];\n            map.info.translateX = calculateFileHorizontalCenterOffset;\n            map.info.translateY = calculateFileVerticalCenterOffset;\n            map.status.translateY = calculateFileVerticalCenterOffset;\n            map.processingCompleteIndicator = { opacity: 1, scaleX: 1, scaleY: 1 };\n        }\n\n        // should align center\n        if (isAsync && !allowProcess) {\n            [\n                'DID_START_ITEM_PROCESSING',\n                'DID_REQUEST_ITEM_PROCESSING',\n                'DID_UPDATE_ITEM_PROCESS_PROGRESS',\n                'DID_THROW_ITEM_PROCESSING_ERROR',\n            ].forEach(function(key) {\n                StyleMap[key].status.translateY = calculateFileVerticalCenterOffset;\n            });\n            StyleMap['DID_THROW_ITEM_PROCESSING_ERROR'].status.translateX = calculateButtonWidth;\n        }\n\n        // move remove button to right\n        if (alignRemoveItemButton && allowRevert) {\n            LocalButtons['RevertItemProcessing'].align = 'BUTTON_REMOVE_ITEM_POSITION';\n            var _map = StyleMap['DID_COMPLETE_ITEM_PROCESSING'];\n            _map.info.translateX = calculateFileInfoOffset;\n            _map.status.translateY = calculateFileVerticalCenterOffset;\n            _map.processingCompleteIndicator = { opacity: 1, scaleX: 1, scaleY: 1 };\n        }\n\n        // show/hide RemoveItem button\n        if (!allowRemove) {\n            LocalButtons['RemoveItem'].disabled = true;\n        }\n\n        // create the button views\n        forin(LocalButtons, function(key, definition) {\n            // create button\n            var buttonView = root.createChildView(fileActionButton, {\n                label: root.query(definition.label),\n                icon: root.query(definition.icon),\n                opacity: 0,\n            });\n\n            // should be appended?\n            if (enabledButtons.includes(key)) {\n                root.appendChildView(buttonView);\n            }\n\n            // toggle\n            if (definition.disabled) {\n                buttonView.element.setAttribute('disabled', 'disabled');\n                buttonView.element.setAttribute('hidden', 'hidden');\n            }\n\n            // add position attribute\n            buttonView.element.dataset.align = root.query('GET_STYLE_' + definition.align);\n\n            // add class\n            buttonView.element.classList.add(definition.className);\n\n            // handle interactions\n            buttonView.on('click', function(e) {\n                e.stopPropagation();\n                if (definition.disabled) return;\n                root.dispatch(definition.action, { query: id });\n            });\n\n            // set reference\n            root.ref['button' + key] = buttonView;\n        });\n\n        // checkmark\n        root.ref.processingCompleteIndicator = root.appendChildView(\n            root.createChildView(processingCompleteIndicatorView)\n        );\n\n        root.ref.processingCompleteIndicator.element.dataset.align = root.query(\n            'GET_STYLE_BUTTON_PROCESS_ITEM_POSITION'\n        );\n\n        // create file info view\n        root.ref.info = root.appendChildView(root.createChildView(fileInfo, { id: id }));\n\n        // create file status view\n        root.ref.status = root.appendChildView(root.createChildView(fileStatus, { id: id }));\n\n        // add progress indicators\n        var loadIndicatorView = root.appendChildView(\n            root.createChildView(progressIndicator, {\n                opacity: 0,\n                align: root.query('GET_STYLE_LOAD_INDICATOR_POSITION'),\n            })\n        );\n\n        loadIndicatorView.element.classList.add('filepond--load-indicator');\n        root.ref.loadProgressIndicator = loadIndicatorView;\n\n        var progressIndicatorView = root.appendChildView(\n            root.createChildView(progressIndicator, {\n                opacity: 0,\n                align: root.query('GET_STYLE_PROGRESS_INDICATOR_POSITION'),\n            })\n        );\n\n        progressIndicatorView.element.classList.add('filepond--process-indicator');\n        root.ref.processProgressIndicator = progressIndicatorView;\n\n        // current active styles\n        root.ref.activeStyles = [];\n    };\n\n    var write$2 = function write(_ref3) {\n        var root = _ref3.root,\n            actions = _ref3.actions,\n            props = _ref3.props;\n        // route actions\n        route({ root: root, actions: actions, props: props });\n\n        // select last state change action\n        var action = actions\n            .concat()\n            .filter(function(action) {\n                return /^DID_/.test(action.type);\n            })\n            .reverse()\n            .find(function(action) {\n                return StyleMap[action.type];\n            });\n\n        // a new action happened, let's get the matching styles\n        if (action) {\n            // define new active styles\n            root.ref.activeStyles = [];\n\n            var stylesToApply = StyleMap[action.type];\n            forin(DefaultStyle, function(name, defaultStyles) {\n                // get reference to control\n                var control = root.ref[name];\n\n                // loop over all styles for this control\n                forin(defaultStyles, function(key, defaultValue) {\n                    var value =\n                        stylesToApply[name] && typeof stylesToApply[name][key] !== 'undefined'\n                            ? stylesToApply[name][key]\n                            : defaultValue;\n                    root.ref.activeStyles.push({ control: control, key: key, value: value });\n                });\n            });\n        }\n\n        // apply active styles to element\n        root.ref.activeStyles.forEach(function(_ref4) {\n            var control = _ref4.control,\n                key = _ref4.key,\n                value = _ref4.value;\n            control[key] = typeof value === 'function' ? value(root) : value;\n        });\n    };\n\n    var route = createRoute({\n        DID_SET_LABEL_BUTTON_ABORT_ITEM_PROCESSING: function DID_SET_LABEL_BUTTON_ABORT_ITEM_PROCESSING(\n            _ref5\n        ) {\n            var root = _ref5.root,\n                action = _ref5.action;\n            root.ref.buttonAbortItemProcessing.label = action.value;\n        },\n        DID_SET_LABEL_BUTTON_ABORT_ITEM_LOAD: function DID_SET_LABEL_BUTTON_ABORT_ITEM_LOAD(_ref6) {\n            var root = _ref6.root,\n                action = _ref6.action;\n            root.ref.buttonAbortItemLoad.label = action.value;\n        },\n        DID_SET_LABEL_BUTTON_ABORT_ITEM_REMOVAL: function DID_SET_LABEL_BUTTON_ABORT_ITEM_REMOVAL(\n            _ref7\n        ) {\n            var root = _ref7.root,\n                action = _ref7.action;\n            root.ref.buttonAbortItemRemoval.label = action.value;\n        },\n        DID_REQUEST_ITEM_PROCESSING: function DID_REQUEST_ITEM_PROCESSING(_ref8) {\n            var root = _ref8.root;\n            root.ref.processProgressIndicator.spin = true;\n            root.ref.processProgressIndicator.progress = 0;\n        },\n        DID_START_ITEM_LOAD: function DID_START_ITEM_LOAD(_ref9) {\n            var root = _ref9.root;\n            root.ref.loadProgressIndicator.spin = true;\n            root.ref.loadProgressIndicator.progress = 0;\n        },\n        DID_START_ITEM_REMOVE: function DID_START_ITEM_REMOVE(_ref10) {\n            var root = _ref10.root;\n            root.ref.processProgressIndicator.spin = true;\n            root.ref.processProgressIndicator.progress = 0;\n        },\n        DID_UPDATE_ITEM_LOAD_PROGRESS: function DID_UPDATE_ITEM_LOAD_PROGRESS(_ref11) {\n            var root = _ref11.root,\n                action = _ref11.action;\n            root.ref.loadProgressIndicator.spin = false;\n            root.ref.loadProgressIndicator.progress = action.progress;\n        },\n        DID_UPDATE_ITEM_PROCESS_PROGRESS: function DID_UPDATE_ITEM_PROCESS_PROGRESS(_ref12) {\n            var root = _ref12.root,\n                action = _ref12.action;\n            root.ref.processProgressIndicator.spin = false;\n            root.ref.processProgressIndicator.progress = action.progress;\n        },\n    });\n\n    var file = createView({\n        create: create$4,\n        write: write$2,\n        didCreateView: function didCreateView(root) {\n            applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n        },\n        name: 'file',\n    });\n\n    /**\n     * Creates the file view\n     */\n    var create$5 = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n\n        // filename\n        root.ref.fileName = createElement$1('legend');\n        root.appendChild(root.ref.fileName);\n\n        // file appended\n        root.ref.file = root.appendChildView(root.createChildView(file, { id: props.id }));\n\n        // data has moved to data.js\n        root.ref.data = false;\n    };\n\n    /**\n     * Data storage\n     */\n    var didLoadItem = function didLoadItem(_ref2) {\n        var root = _ref2.root,\n            props = _ref2.props;\n        // updates the legend of the fieldset so screenreaders can better group buttons\n        text(root.ref.fileName, formatFilename(root.query('GET_ITEM_NAME', props.id)));\n    };\n\n    var fileWrapper = createView({\n        create: create$5,\n        ignoreRect: true,\n        write: createRoute({\n            DID_LOAD_ITEM: didLoadItem,\n        }),\n\n        didCreateView: function didCreateView(root) {\n            applyFilters('CREATE_VIEW', Object.assign({}, root, { view: root }));\n        },\n        tag: 'fieldset',\n        name: 'file-wrapper',\n    });\n\n    var PANEL_SPRING_PROPS = { type: 'spring', damping: 0.6, mass: 7 };\n\n    var create$6 = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        [\n            {\n                name: 'top',\n            },\n\n            {\n                name: 'center',\n                props: {\n                    translateY: null,\n                    scaleY: null,\n                },\n\n                mixins: {\n                    animations: {\n                        scaleY: PANEL_SPRING_PROPS,\n                    },\n\n                    styles: ['translateY', 'scaleY'],\n                },\n            },\n\n            {\n                name: 'bottom',\n                props: {\n                    translateY: null,\n                },\n\n                mixins: {\n                    animations: {\n                        translateY: PANEL_SPRING_PROPS,\n                    },\n\n                    styles: ['translateY'],\n                },\n            },\n        ].forEach(function(section) {\n            createSection(root, section, props.name);\n        });\n\n        root.element.classList.add('filepond--' + props.name);\n\n        root.ref.scalable = null;\n    };\n\n    var createSection = function createSection(root, section, className) {\n        var viewConstructor = createView({\n            name: 'panel-' + section.name + ' filepond--' + className,\n            mixins: section.mixins,\n            ignoreRectUpdate: true,\n        });\n\n        var view = root.createChildView(viewConstructor, section.props);\n\n        root.ref[section.name] = root.appendChildView(view);\n    };\n\n    var write$3 = function write(_ref2) {\n        var root = _ref2.root,\n            props = _ref2.props;\n\n        // update scalable state\n        if (root.ref.scalable === null || props.scalable !== root.ref.scalable) {\n            root.ref.scalable = isBoolean(props.scalable) ? props.scalable : true;\n            root.element.dataset.scalable = root.ref.scalable;\n        }\n\n        // no height, can't set\n        if (!props.height) return;\n\n        // get child rects\n        var topRect = root.ref.top.rect.element;\n        var bottomRect = root.ref.bottom.rect.element;\n\n        // make sure height never is smaller than bottom and top seciton heights combined (will probably never happen, but who knows)\n        var height = Math.max(topRect.height + bottomRect.height, props.height);\n\n        // offset center part\n        root.ref.center.translateY = topRect.height;\n\n        // scale center part\n        // use math ceil to prevent transparent lines because of rounding errors\n        root.ref.center.scaleY = (height - topRect.height - bottomRect.height) / 100;\n\n        // offset bottom part\n        root.ref.bottom.translateY = height - bottomRect.height;\n    };\n\n    var panel = createView({\n        name: 'panel',\n        read: function read(_ref3) {\n            var root = _ref3.root,\n                props = _ref3.props;\n            return (props.heightCurrent = root.ref.bottom.translateY);\n        },\n        write: write$3,\n        create: create$6,\n        ignoreRect: true,\n        mixins: {\n            apis: ['height', 'heightCurrent', 'scalable'],\n        },\n    });\n\n    var createDragHelper = function createDragHelper(items) {\n        var itemIds = items.map(function(item) {\n            return item.id;\n        });\n        var prevIndex = undefined;\n        return {\n            setIndex: function setIndex(index) {\n                prevIndex = index;\n            },\n            getIndex: function getIndex() {\n                return prevIndex;\n            },\n            getItemIndex: function getItemIndex(item) {\n                return itemIds.indexOf(item.id);\n            },\n        };\n    };\n\n    var ITEM_TRANSLATE_SPRING = {\n        type: 'spring',\n        stiffness: 0.75,\n        damping: 0.45,\n        mass: 10,\n    };\n\n    var ITEM_SCALE_SPRING = 'spring';\n\n    var StateMap = {\n        DID_START_ITEM_LOAD: 'busy',\n        DID_UPDATE_ITEM_LOAD_PROGRESS: 'loading',\n        DID_THROW_ITEM_INVALID: 'load-invalid',\n        DID_THROW_ITEM_LOAD_ERROR: 'load-error',\n        DID_LOAD_ITEM: 'idle',\n        DID_THROW_ITEM_REMOVE_ERROR: 'remove-error',\n        DID_START_ITEM_REMOVE: 'busy',\n        DID_START_ITEM_PROCESSING: 'busy processing',\n        DID_REQUEST_ITEM_PROCESSING: 'busy processing',\n        DID_UPDATE_ITEM_PROCESS_PROGRESS: 'processing',\n        DID_COMPLETE_ITEM_PROCESSING: 'processing-complete',\n        DID_THROW_ITEM_PROCESSING_ERROR: 'processing-error',\n        DID_THROW_ITEM_PROCESSING_REVERT_ERROR: 'processing-revert-error',\n        DID_ABORT_ITEM_PROCESSING: 'cancelled',\n        DID_REVERT_ITEM_PROCESSING: 'idle',\n    };\n\n    /**\n     * Creates the file view\n     */\n    var create$7 = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        // select\n        root.ref.handleClick = function(e) {\n            return root.dispatch('DID_ACTIVATE_ITEM', { id: props.id });\n        };\n\n        // set id\n        root.element.id = 'filepond--item-' + props.id;\n        root.element.addEventListener('click', root.ref.handleClick);\n\n        // file view\n        root.ref.container = root.appendChildView(\n            root.createChildView(fileWrapper, { id: props.id })\n        );\n\n        // file panel\n        root.ref.panel = root.appendChildView(root.createChildView(panel, { name: 'item-panel' }));\n\n        // default start height\n        root.ref.panel.height = null;\n\n        // by default not marked for removal\n        props.markedForRemoval = false;\n\n        // if not allowed to reorder file items, exit here\n        if (!root.query('GET_ALLOW_REORDER')) return;\n\n        // set to idle so shows grab cursor\n        root.element.dataset.dragState = 'idle';\n\n        var grab = function grab(e) {\n            if (!e.isPrimary) return;\n\n            var removedActivateListener = false;\n\n            var origin = {\n                x: e.pageX,\n                y: e.pageY,\n            };\n\n            props.dragOrigin = {\n                x: root.translateX,\n                y: root.translateY,\n            };\n\n            props.dragCenter = {\n                x: e.offsetX,\n                y: e.offsetY,\n            };\n\n            var dragState = createDragHelper(root.query('GET_ACTIVE_ITEMS'));\n\n            root.dispatch('DID_GRAB_ITEM', { id: props.id, dragState: dragState });\n\n            var drag = function drag(e) {\n                if (!e.isPrimary) return;\n\n                e.stopPropagation();\n                e.preventDefault();\n\n                props.dragOffset = {\n                    x: e.pageX - origin.x,\n                    y: e.pageY - origin.y,\n                };\n\n                // if dragged stop listening to clicks, will re-add when done dragging\n                var dist =\n                    props.dragOffset.x * props.dragOffset.x +\n                    props.dragOffset.y * props.dragOffset.y;\n                if (dist > 16 && !removedActivateListener) {\n                    removedActivateListener = true;\n                    root.element.removeEventListener('click', root.ref.handleClick);\n                }\n\n                root.dispatch('DID_DRAG_ITEM', { id: props.id, dragState: dragState });\n            };\n\n            var drop = function drop(e) {\n                if (!e.isPrimary) return;\n\n                props.dragOffset = {\n                    x: e.pageX - origin.x,\n                    y: e.pageY - origin.y,\n                };\n\n                reset();\n            };\n\n            var cancel = function cancel() {\n                reset();\n            };\n\n            var reset = function reset() {\n                document.removeEventListener('pointercancel', cancel);\n                document.removeEventListener('pointermove', drag);\n                document.removeEventListener('pointerup', drop);\n\n                root.dispatch('DID_DROP_ITEM', { id: props.id, dragState: dragState });\n\n                // start listening to clicks again\n                if (removedActivateListener) {\n                    setTimeout(function() {\n                        return root.element.addEventListener('click', root.ref.handleClick);\n                    }, 0);\n                }\n            };\n\n            document.addEventListener('pointercancel', cancel);\n            document.addEventListener('pointermove', drag);\n            document.addEventListener('pointerup', drop);\n        };\n\n        root.element.addEventListener('pointerdown', grab);\n    };\n\n    var route$1 = createRoute({\n        DID_UPDATE_PANEL_HEIGHT: function DID_UPDATE_PANEL_HEIGHT(_ref2) {\n            var root = _ref2.root,\n                action = _ref2.action;\n            root.height = action.height;\n        },\n    });\n\n    var write$4 = createRoute(\n        {\n            DID_GRAB_ITEM: function DID_GRAB_ITEM(_ref3) {\n                var root = _ref3.root,\n                    props = _ref3.props;\n                props.dragOrigin = {\n                    x: root.translateX,\n                    y: root.translateY,\n                };\n            },\n            DID_DRAG_ITEM: function DID_DRAG_ITEM(_ref4) {\n                var root = _ref4.root;\n                root.element.dataset.dragState = 'drag';\n            },\n            DID_DROP_ITEM: function DID_DROP_ITEM(_ref5) {\n                var root = _ref5.root,\n                    props = _ref5.props;\n                props.dragOffset = null;\n                props.dragOrigin = null;\n                root.element.dataset.dragState = 'drop';\n            },\n        },\n\n        function(_ref6) {\n            var root = _ref6.root,\n                actions = _ref6.actions,\n                props = _ref6.props,\n                shouldOptimize = _ref6.shouldOptimize;\n            if (root.element.dataset.dragState === 'drop') {\n                if (root.scaleX <= 1) {\n                    root.element.dataset.dragState = 'idle';\n                }\n            }\n\n            // select last state change action\n            var action = actions\n                .concat()\n                .filter(function(action) {\n                    return /^DID_/.test(action.type);\n                })\n                .reverse()\n                .find(function(action) {\n                    return StateMap[action.type];\n                });\n\n            // no need to set same state twice\n            if (action && action.type !== props.currentState) {\n                // set current state\n                props.currentState = action.type;\n\n                // set state\n                root.element.dataset.filepondItemState = StateMap[props.currentState] || '';\n            }\n\n            // route actions\n            var aspectRatio =\n                root.query('GET_ITEM_PANEL_ASPECT_RATIO') || root.query('GET_PANEL_ASPECT_RATIO');\n            if (!aspectRatio) {\n                route$1({ root: root, actions: actions, props: props });\n                if (!root.height && root.ref.container.rect.element.height > 0) {\n                    root.height = root.ref.container.rect.element.height;\n                }\n            } else if (!shouldOptimize) {\n                root.height = root.rect.element.width * aspectRatio;\n            }\n\n            // sync panel height with item height\n            if (shouldOptimize) {\n                root.ref.panel.height = null;\n            }\n\n            root.ref.panel.height = root.height;\n        }\n    );\n\n    var item = createView({\n        create: create$7,\n        write: write$4,\n        destroy: function destroy(_ref7) {\n            var root = _ref7.root,\n                props = _ref7.props;\n            root.element.removeEventListener('click', root.ref.handleClick);\n            root.dispatch('RELEASE_ITEM', { query: props.id });\n        },\n        tag: 'li',\n        name: 'item',\n        mixins: {\n            apis: [\n                'id',\n                'interactionMethod',\n                'markedForRemoval',\n                'spawnDate',\n                'dragCenter',\n                'dragOrigin',\n                'dragOffset',\n            ],\n\n            styles: ['translateX', 'translateY', 'scaleX', 'scaleY', 'opacity', 'height'],\n            animations: {\n                scaleX: ITEM_SCALE_SPRING,\n                scaleY: ITEM_SCALE_SPRING,\n                translateX: ITEM_TRANSLATE_SPRING,\n                translateY: ITEM_TRANSLATE_SPRING,\n                opacity: { type: 'tween', duration: 150 },\n            },\n        },\n    });\n\n    var getItemsPerRow = function(horizontalSpace, itemWidth) {\n        // add one pixel leeway, when using percentages for item width total items can be 1.99 per row\n\n        return Math.max(1, Math.floor((horizontalSpace + 1) / itemWidth));\n    };\n\n    var getItemIndexByPosition = function getItemIndexByPosition(view, children, positionInView) {\n        if (!positionInView) return;\n\n        var horizontalSpace = view.rect.element.width;\n        // const children = view.childViews;\n        var l = children.length;\n        var last = null;\n\n        // -1, don't move items to accomodate (either add to top or bottom)\n        if (l === 0 || positionInView.top < children[0].rect.element.top) return -1;\n\n        // let's get the item width\n        var item = children[0];\n        var itemRect = item.rect.element;\n        var itemHorizontalMargin = itemRect.marginLeft + itemRect.marginRight;\n        var itemWidth = itemRect.width + itemHorizontalMargin;\n        var itemsPerRow = getItemsPerRow(horizontalSpace, itemWidth);\n\n        // stack\n        if (itemsPerRow === 1) {\n            for (var index = 0; index < l; index++) {\n                var child = children[index];\n                var childMid = child.rect.outer.top + child.rect.element.height * 0.5;\n                if (positionInView.top < childMid) {\n                    return index;\n                }\n            }\n            return l;\n        }\n\n        // grid\n        var itemVerticalMargin = itemRect.marginTop + itemRect.marginBottom;\n        var itemHeight = itemRect.height + itemVerticalMargin;\n        for (var _index = 0; _index < l; _index++) {\n            var indexX = _index % itemsPerRow;\n            var indexY = Math.floor(_index / itemsPerRow);\n\n            var offsetX = indexX * itemWidth;\n            var offsetY = indexY * itemHeight;\n\n            var itemTop = offsetY - itemRect.marginTop;\n            var itemRight = offsetX + itemWidth;\n            var itemBottom = offsetY + itemHeight + itemRect.marginBottom;\n\n            if (positionInView.top < itemBottom && positionInView.top > itemTop) {\n                if (positionInView.left < itemRight) {\n                    return _index;\n                } else if (_index !== l - 1) {\n                    last = _index;\n                } else {\n                    last = null;\n                }\n            }\n        }\n\n        if (last !== null) {\n            return last;\n        }\n\n        return l;\n    };\n\n    var dropAreaDimensions = {\n        height: 0,\n        width: 0,\n        get getHeight() {\n            return this.height;\n        },\n        set setHeight(val) {\n            if (this.height === 0 || val === 0) this.height = val;\n        },\n        get getWidth() {\n            return this.width;\n        },\n        set setWidth(val) {\n            if (this.width === 0 || val === 0) this.width = val;\n        },\n        setDimensions: function setDimensions(height, width) {\n            if (this.height === 0 || height === 0) this.height = height;\n            if (this.width === 0 || width === 0) this.width = width;\n        },\n    };\n\n    var create$8 = function create(_ref) {\n        var root = _ref.root;\n        // need to set role to list as otherwise it won't be read as a list by VoiceOver\n        attr(root.element, 'role', 'list');\n\n        root.ref.lastItemSpanwDate = Date.now();\n    };\n\n    /**\n     * Inserts a new item\n     * @param root\n     * @param action\n     */\n    var addItemView = function addItemView(_ref2) {\n        var root = _ref2.root,\n            action = _ref2.action;\n        var id = action.id,\n            index = action.index,\n            interactionMethod = action.interactionMethod;\n\n        root.ref.addIndex = index;\n\n        var now = Date.now();\n        var spawnDate = now;\n        var opacity = 1;\n\n        if (interactionMethod !== InteractionMethod.NONE) {\n            opacity = 0;\n            var cooldown = root.query('GET_ITEM_INSERT_INTERVAL');\n            var dist = now - root.ref.lastItemSpanwDate;\n            spawnDate = dist < cooldown ? now + (cooldown - dist) : now;\n        }\n\n        root.ref.lastItemSpanwDate = spawnDate;\n\n        root.appendChildView(\n            root.createChildView(\n                // view type\n                item,\n\n                // props\n                {\n                    spawnDate: spawnDate,\n                    id: id,\n                    opacity: opacity,\n                    interactionMethod: interactionMethod,\n                }\n            ),\n\n            index\n        );\n    };\n\n    var moveItem = function moveItem(item, x, y) {\n        var vx = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;\n        var vy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;\n        // set to null to remove animation while dragging\n        if (item.dragOffset) {\n            item.translateX = null;\n            item.translateY = null;\n            item.translateX = item.dragOrigin.x + item.dragOffset.x;\n            item.translateY = item.dragOrigin.y + item.dragOffset.y;\n            item.scaleX = 1.025;\n            item.scaleY = 1.025;\n        } else {\n            item.translateX = x;\n            item.translateY = y;\n\n            if (Date.now() > item.spawnDate) {\n                // reveal element\n                if (item.opacity === 0) {\n                    introItemView(item, x, y, vx, vy);\n                }\n\n                // make sure is default scale every frame\n                item.scaleX = 1;\n                item.scaleY = 1;\n                item.opacity = 1;\n            }\n        }\n    };\n\n    var introItemView = function introItemView(item, x, y, vx, vy) {\n        if (item.interactionMethod === InteractionMethod.NONE) {\n            item.translateX = null;\n            item.translateX = x;\n            item.translateY = null;\n            item.translateY = y;\n        } else if (item.interactionMethod === InteractionMethod.DROP) {\n            item.translateX = null;\n            item.translateX = x - vx * 20;\n\n            item.translateY = null;\n            item.translateY = y - vy * 10;\n\n            item.scaleX = 0.8;\n            item.scaleY = 0.8;\n        } else if (item.interactionMethod === InteractionMethod.BROWSE) {\n            item.translateY = null;\n            item.translateY = y - 30;\n        } else if (item.interactionMethod === InteractionMethod.API) {\n            item.translateX = null;\n            item.translateX = x - 30;\n            item.translateY = null;\n        }\n    };\n\n    /**\n     * Removes an existing item\n     * @param root\n     * @param action\n     */\n    var removeItemView = function removeItemView(_ref3) {\n        var root = _ref3.root,\n            action = _ref3.action;\n        var id = action.id;\n\n        // get the view matching the given id\n        var view = root.childViews.find(function(child) {\n            return child.id === id;\n        });\n\n        // if no view found, exit\n        if (!view) {\n            return;\n        }\n\n        // animate view out of view\n        view.scaleX = 0.9;\n        view.scaleY = 0.9;\n        view.opacity = 0;\n\n        // mark for removal\n        view.markedForRemoval = true;\n    };\n\n    var getItemHeight = function getItemHeight(child) {\n        return (\n            child.rect.element.height +\n            child.rect.element.marginBottom +\n            child.rect.element.marginTop\n        );\n    };\n    var getItemWidth = function getItemWidth(child) {\n        return (\n            child.rect.element.width +\n            child.rect.element.marginLeft * 0.5 +\n            child.rect.element.marginRight * 0.5\n        );\n    };\n\n    var dragItem = function dragItem(_ref4) {\n        var root = _ref4.root,\n            action = _ref4.action;\n        var id = action.id,\n            dragState = action.dragState;\n\n        // reference to item\n        var item = root.query('GET_ITEM', { id: id });\n\n        // get the view matching the given id\n        var view = root.childViews.find(function(child) {\n            return child.id === id;\n        });\n\n        var numItems = root.childViews.length;\n        var oldIndex = dragState.getItemIndex(item);\n\n        // if no view found, exit\n        if (!view) return;\n\n        var dragPosition = {\n            x: view.dragOrigin.x + view.dragOffset.x + view.dragCenter.x,\n            y: view.dragOrigin.y + view.dragOffset.y + view.dragCenter.y,\n        };\n\n        // get drag area dimensions\n        var dragHeight = getItemHeight(view);\n        var dragWidth = getItemWidth(view);\n\n        // get rows and columns (There will always be at least one row and one column if a file is present)\n        var cols = Math.floor(root.rect.outer.width / dragWidth);\n        if (cols > numItems) cols = numItems;\n\n        // rows are used to find when we have left the preview area bounding box\n        var rows = Math.floor(numItems / cols + 1);\n\n        dropAreaDimensions.setHeight = dragHeight * rows;\n        dropAreaDimensions.setWidth = dragWidth * cols;\n\n        // get new index of dragged item\n        var location = {\n            y: Math.floor(dragPosition.y / dragHeight),\n            x: Math.floor(dragPosition.x / dragWidth),\n            getGridIndex: function getGridIndex() {\n                if (\n                    dragPosition.y > dropAreaDimensions.getHeight ||\n                    dragPosition.y < 0 ||\n                    dragPosition.x > dropAreaDimensions.getWidth ||\n                    dragPosition.x < 0\n                )\n                    return oldIndex;\n                return this.y * cols + this.x;\n            },\n            getColIndex: function getColIndex() {\n                var items = root.query('GET_ACTIVE_ITEMS');\n                var visibleChildren = root.childViews.filter(function(child) {\n                    return child.rect.element.height;\n                });\n                var children = items.map(function(item) {\n                    return visibleChildren.find(function(childView) {\n                        return childView.id === item.id;\n                    });\n                });\n\n                var currentIndex = children.findIndex(function(child) {\n                    return child === view;\n                });\n                var dragHeight = getItemHeight(view);\n                var l = children.length;\n                var idx = l;\n                var childHeight = 0;\n                var childBottom = 0;\n                var childTop = 0;\n                for (var i = 0; i < l; i++) {\n                    childHeight = getItemHeight(children[i]);\n                    childTop = childBottom;\n                    childBottom = childTop + childHeight;\n                    if (dragPosition.y < childBottom) {\n                        if (currentIndex > i) {\n                            if (dragPosition.y < childTop + dragHeight) {\n                                idx = i;\n                                break;\n                            }\n                            continue;\n                        }\n                        idx = i;\n                        break;\n                    }\n                }\n                return idx;\n            },\n        };\n\n        // get new index\n        var index = cols > 1 ? location.getGridIndex() : location.getColIndex();\n        root.dispatch('MOVE_ITEM', { query: view, index: index });\n\n        // if the index of the item changed, dispatch reorder action\n        var currentIndex = dragState.getIndex();\n\n        if (currentIndex === undefined || currentIndex !== index) {\n            dragState.setIndex(index);\n\n            if (currentIndex === undefined) return;\n\n            root.dispatch('DID_REORDER_ITEMS', {\n                items: root.query('GET_ACTIVE_ITEMS'),\n                origin: oldIndex,\n                target: index,\n            });\n        }\n    };\n\n    /**\n     * Setup action routes\n     */\n    var route$2 = createRoute({\n        DID_ADD_ITEM: addItemView,\n        DID_REMOVE_ITEM: removeItemView,\n        DID_DRAG_ITEM: dragItem,\n    });\n\n    /**\n     * Write to view\n     * @param root\n     * @param actions\n     * @param props\n     */\n    var write$5 = function write(_ref5) {\n        var root = _ref5.root,\n            props = _ref5.props,\n            actions = _ref5.actions,\n            shouldOptimize = _ref5.shouldOptimize;\n        // route actions\n        route$2({ root: root, props: props, actions: actions });\n        var dragCoordinates = props.dragCoordinates;\n\n        // available space on horizontal axis\n        var horizontalSpace = root.rect.element.width;\n\n        // only draw children that have dimensions\n        var visibleChildren = root.childViews.filter(function(child) {\n            return child.rect.element.height;\n        });\n\n        // sort based on current active items\n        var children = root\n            .query('GET_ACTIVE_ITEMS')\n            .map(function(item) {\n                return visibleChildren.find(function(child) {\n                    return child.id === item.id;\n                });\n            })\n            .filter(function(item) {\n                return item;\n            });\n\n        // get index\n        var dragIndex = dragCoordinates\n            ? getItemIndexByPosition(root, children, dragCoordinates)\n            : null;\n\n        // add index is used to reserve the dropped/added item index till the actual item is rendered\n        var addIndex = root.ref.addIndex || null;\n\n        // add index no longer needed till possibly next draw\n        root.ref.addIndex = null;\n\n        var dragIndexOffset = 0;\n        var removeIndexOffset = 0;\n        var addIndexOffset = 0;\n\n        if (children.length === 0) return;\n\n        var childRect = children[0].rect.element;\n        var itemVerticalMargin = childRect.marginTop + childRect.marginBottom;\n        var itemHorizontalMargin = childRect.marginLeft + childRect.marginRight;\n        var itemWidth = childRect.width + itemHorizontalMargin;\n        var itemHeight = childRect.height + itemVerticalMargin;\n        var itemsPerRow = getItemsPerRow(horizontalSpace, itemWidth);\n\n        // stack\n        if (itemsPerRow === 1) {\n            var offsetY = 0;\n            var dragOffset = 0;\n\n            children.forEach(function(child, index) {\n                if (dragIndex) {\n                    var dist = index - dragIndex;\n                    if (dist === -2) {\n                        dragOffset = -itemVerticalMargin * 0.25;\n                    } else if (dist === -1) {\n                        dragOffset = -itemVerticalMargin * 0.75;\n                    } else if (dist === 0) {\n                        dragOffset = itemVerticalMargin * 0.75;\n                    } else if (dist === 1) {\n                        dragOffset = itemVerticalMargin * 0.25;\n                    } else {\n                        dragOffset = 0;\n                    }\n                }\n\n                if (shouldOptimize) {\n                    child.translateX = null;\n                    child.translateY = null;\n                }\n\n                if (!child.markedForRemoval) {\n                    moveItem(child, 0, offsetY + dragOffset);\n                }\n\n                var itemHeight = child.rect.element.height + itemVerticalMargin;\n\n                var visualHeight = itemHeight * (child.markedForRemoval ? child.opacity : 1);\n\n                offsetY += visualHeight;\n            });\n        }\n        // grid\n        else {\n            var prevX = 0;\n            var prevY = 0;\n\n            children.forEach(function(child, index) {\n                if (index === dragIndex) {\n                    dragIndexOffset = 1;\n                }\n\n                if (index === addIndex) {\n                    addIndexOffset += 1;\n                }\n\n                if (child.markedForRemoval && child.opacity < 0.5) {\n                    removeIndexOffset -= 1;\n                }\n\n                var visualIndex = index + addIndexOffset + dragIndexOffset + removeIndexOffset;\n\n                var indexX = visualIndex % itemsPerRow;\n                var indexY = Math.floor(visualIndex / itemsPerRow);\n\n                var offsetX = indexX * itemWidth;\n                var offsetY = indexY * itemHeight;\n\n                var vectorX = Math.sign(offsetX - prevX);\n                var vectorY = Math.sign(offsetY - prevY);\n\n                prevX = offsetX;\n                prevY = offsetY;\n\n                if (child.markedForRemoval) return;\n\n                if (shouldOptimize) {\n                    child.translateX = null;\n                    child.translateY = null;\n                }\n\n                moveItem(child, offsetX, offsetY, vectorX, vectorY);\n            });\n        }\n    };\n\n    /**\n     * Filters actions that are meant specifically for a certain child of the list\n     * @param child\n     * @param actions\n     */\n    var filterSetItemActions = function filterSetItemActions(child, actions) {\n        return actions.filter(function(action) {\n            // if action has an id, filter out actions that don't have this child id\n            if (action.data && action.data.id) {\n                return child.id === action.data.id;\n            }\n\n            // allow all other actions\n            return true;\n        });\n    };\n\n    var list = createView({\n        create: create$8,\n        write: write$5,\n        tag: 'ul',\n        name: 'list',\n        didWriteView: function didWriteView(_ref6) {\n            var root = _ref6.root;\n            root.childViews\n                .filter(function(view) {\n                    return view.markedForRemoval && view.opacity === 0 && view.resting;\n                })\n                .forEach(function(view) {\n                    view._destroy();\n                    root.removeChildView(view);\n                });\n        },\n        filterFrameActionsForChild: filterSetItemActions,\n        mixins: {\n            apis: ['dragCoordinates'],\n        },\n    });\n\n    var create$9 = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        root.ref.list = root.appendChildView(root.createChildView(list));\n        props.dragCoordinates = null;\n        props.overflowing = false;\n    };\n\n    var storeDragCoordinates = function storeDragCoordinates(_ref2) {\n        var root = _ref2.root,\n            props = _ref2.props,\n            action = _ref2.action;\n        if (!root.query('GET_ITEM_INSERT_LOCATION_FREEDOM')) return;\n        props.dragCoordinates = {\n            left: action.position.scopeLeft - root.ref.list.rect.element.left,\n            top:\n                action.position.scopeTop -\n                (root.rect.outer.top + root.rect.element.marginTop + root.rect.element.scrollTop),\n        };\n    };\n\n    var clearDragCoordinates = function clearDragCoordinates(_ref3) {\n        var props = _ref3.props;\n        props.dragCoordinates = null;\n    };\n\n    var route$3 = createRoute({\n        DID_DRAG: storeDragCoordinates,\n        DID_END_DRAG: clearDragCoordinates,\n    });\n\n    var write$6 = function write(_ref4) {\n        var root = _ref4.root,\n            props = _ref4.props,\n            actions = _ref4.actions;\n\n        // route actions\n        route$3({ root: root, props: props, actions: actions });\n\n        // current drag position\n        root.ref.list.dragCoordinates = props.dragCoordinates;\n\n        // if currently overflowing but no longer received overflow\n        if (props.overflowing && !props.overflow) {\n            props.overflowing = false;\n\n            // reset overflow state\n            root.element.dataset.state = '';\n            root.height = null;\n        }\n\n        // if is not overflowing currently but does receive overflow value\n        if (props.overflow) {\n            var newHeight = Math.round(props.overflow);\n            if (newHeight !== root.height) {\n                props.overflowing = true;\n                root.element.dataset.state = 'overflow';\n                root.height = newHeight;\n            }\n        }\n    };\n\n    var listScroller = createView({\n        create: create$9,\n        write: write$6,\n        name: 'list-scroller',\n        mixins: {\n            apis: ['overflow', 'dragCoordinates'],\n            styles: ['height', 'translateY'],\n            animations: {\n                translateY: 'spring',\n            },\n        },\n    });\n\n    var attrToggle = function attrToggle(element, name, state) {\n        var enabledValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';\n        if (state) {\n            attr(element, name, enabledValue);\n        } else {\n            element.removeAttribute(name);\n        }\n    };\n\n    var resetFileInput = function resetFileInput(input) {\n        // no value, no need to reset\n        if (!input || input.value === '') {\n            return;\n        }\n\n        try {\n            // for modern browsers\n            input.value = '';\n        } catch (err) {}\n\n        // for IE10\n        if (input.value) {\n            // quickly append input to temp form and reset form\n            var form = createElement$1('form');\n            var parentNode = input.parentNode;\n            var ref = input.nextSibling;\n            form.appendChild(input);\n            form.reset();\n\n            // re-inject input where it originally was\n            if (ref) {\n                parentNode.insertBefore(input, ref);\n            } else {\n                parentNode.appendChild(input);\n            }\n        }\n    };\n\n    var create$a = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        // set id so can be referenced from outside labels\n        root.element.id = 'filepond--browser-' + props.id;\n\n        // set name of element (is removed when a value is set)\n        attr(root.element, 'name', root.query('GET_NAME'));\n\n        // we have to link this element to the status element\n        attr(root.element, 'aria-controls', 'filepond--assistant-' + props.id);\n\n        // set label, we use labelled by as otherwise the screenreader does not read the \"browse\" text in the label (as it has tabindex: 0)\n        attr(root.element, 'aria-labelledby', 'filepond--drop-label-' + props.id);\n\n        // set configurable props\n        setAcceptedFileTypes({\n            root: root,\n            action: { value: root.query('GET_ACCEPTED_FILE_TYPES') },\n        });\n        toggleAllowMultiple({ root: root, action: { value: root.query('GET_ALLOW_MULTIPLE') } });\n        toggleDirectoryFilter({\n            root: root,\n            action: { value: root.query('GET_ALLOW_DIRECTORIES_ONLY') },\n        });\n        toggleDisabled({ root: root });\n        toggleRequired({ root: root, action: { value: root.query('GET_REQUIRED') } });\n        setCaptureMethod({ root: root, action: { value: root.query('GET_CAPTURE_METHOD') } });\n\n        // handle changes to the input field\n        root.ref.handleChange = function(e) {\n            if (!root.element.value) {\n                return;\n            }\n\n            // extract files and move value of webkitRelativePath path to _relativePath\n            var files = Array.from(root.element.files).map(function(file) {\n                file._relativePath = file.webkitRelativePath;\n                return file;\n            });\n\n            // we add a little delay so the OS file select window can move out of the way before we add our file\n            setTimeout(function() {\n                // load files\n                props.onload(files);\n\n                // reset input, it's just for exposing a method to drop files, should not retain any state\n                resetFileInput(root.element);\n            }, 250);\n        };\n\n        root.element.addEventListener('change', root.ref.handleChange);\n    };\n\n    var setAcceptedFileTypes = function setAcceptedFileTypes(_ref2) {\n        var root = _ref2.root,\n            action = _ref2.action;\n        if (!root.query('GET_ALLOW_SYNC_ACCEPT_ATTRIBUTE')) return;\n        attrToggle(\n            root.element,\n            'accept',\n            !!action.value,\n            action.value ? action.value.join(',') : ''\n        );\n    };\n\n    var toggleAllowMultiple = function toggleAllowMultiple(_ref3) {\n        var root = _ref3.root,\n            action = _ref3.action;\n        attrToggle(root.element, 'multiple', action.value);\n    };\n\n    var toggleDirectoryFilter = function toggleDirectoryFilter(_ref4) {\n        var root = _ref4.root,\n            action = _ref4.action;\n        attrToggle(root.element, 'webkitdirectory', action.value);\n    };\n\n    var toggleDisabled = function toggleDisabled(_ref5) {\n        var root = _ref5.root;\n        var isDisabled = root.query('GET_DISABLED');\n        var doesAllowBrowse = root.query('GET_ALLOW_BROWSE');\n        var disableField = isDisabled || !doesAllowBrowse;\n        attrToggle(root.element, 'disabled', disableField);\n    };\n\n    var toggleRequired = function toggleRequired(_ref6) {\n        var root = _ref6.root,\n            action = _ref6.action;\n        // want to remove required, always possible\n        if (!action.value) {\n            attrToggle(root.element, 'required', false);\n        }\n        // if want to make required, only possible when zero items\n        else if (root.query('GET_TOTAL_ITEMS') === 0) {\n            attrToggle(root.element, 'required', true);\n        }\n    };\n\n    var setCaptureMethod = function setCaptureMethod(_ref7) {\n        var root = _ref7.root,\n            action = _ref7.action;\n        attrToggle(\n            root.element,\n            'capture',\n            !!action.value,\n            action.value === true ? '' : action.value\n        );\n    };\n\n    var updateRequiredStatus = function updateRequiredStatus(_ref8) {\n        var root = _ref8.root;\n        var element = root.element;\n        // always remove the required attribute when more than zero items\n        if (root.query('GET_TOTAL_ITEMS') > 0) {\n            attrToggle(element, 'required', false);\n            attrToggle(element, 'name', false);\n\n            // still has items\n            var activeItems = root.query('GET_ACTIVE_ITEMS');\n            var hasInvalidField = false;\n            for (var i = 0; i < activeItems.length; i++) {\n                if (activeItems[i].status === ItemStatus.LOAD_ERROR) {\n                    hasInvalidField = true;\n                }\n            }\n            // set validity status\n            root.element.setCustomValidity(\n                hasInvalidField ? root.query('GET_LABEL_INVALID_FIELD') : ''\n            );\n        } else {\n            // add name attribute\n            attrToggle(element, 'name', true, root.query('GET_NAME'));\n\n            // remove any validation messages\n            var shouldCheckValidity = root.query('GET_CHECK_VALIDITY');\n            if (shouldCheckValidity) {\n                element.setCustomValidity('');\n            }\n\n            // we only add required if the field has been deemed required\n            if (root.query('GET_REQUIRED')) {\n                attrToggle(element, 'required', true);\n            }\n        }\n    };\n\n    var updateFieldValidityStatus = function updateFieldValidityStatus(_ref9) {\n        var root = _ref9.root;\n        var shouldCheckValidity = root.query('GET_CHECK_VALIDITY');\n        if (!shouldCheckValidity) return;\n        root.element.setCustomValidity(root.query('GET_LABEL_INVALID_FIELD'));\n    };\n\n    var browser = createView({\n        tag: 'input',\n        name: 'browser',\n        ignoreRect: true,\n        ignoreRectUpdate: true,\n        attributes: {\n            type: 'file',\n        },\n\n        create: create$a,\n        destroy: function destroy(_ref10) {\n            var root = _ref10.root;\n            root.element.removeEventListener('change', root.ref.handleChange);\n        },\n        write: createRoute({\n            DID_LOAD_ITEM: updateRequiredStatus,\n            DID_REMOVE_ITEM: updateRequiredStatus,\n            DID_THROW_ITEM_INVALID: updateFieldValidityStatus,\n\n            DID_SET_DISABLED: toggleDisabled,\n            DID_SET_ALLOW_BROWSE: toggleDisabled,\n            DID_SET_ALLOW_DIRECTORIES_ONLY: toggleDirectoryFilter,\n            DID_SET_ALLOW_MULTIPLE: toggleAllowMultiple,\n            DID_SET_ACCEPTED_FILE_TYPES: setAcceptedFileTypes,\n            DID_SET_CAPTURE_METHOD: setCaptureMethod,\n            DID_SET_REQUIRED: toggleRequired,\n        }),\n    });\n\n    var Key = {\n        ENTER: 13,\n        SPACE: 32,\n    };\n\n    var create$b = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        // create the label and link it to the file browser\n        var label = createElement$1('label');\n        attr(label, 'for', 'filepond--browser-' + props.id);\n\n        // use for labeling file input (aria-labelledby on file input)\n        attr(label, 'id', 'filepond--drop-label-' + props.id);\n\n        // handle keys\n        root.ref.handleKeyDown = function(e) {\n            var isActivationKey = e.keyCode === Key.ENTER || e.keyCode === Key.SPACE;\n            if (!isActivationKey) return;\n            // stops from triggering the element a second time\n            e.preventDefault();\n\n            // click link (will then in turn activate file input)\n            root.ref.label.click();\n        };\n\n        root.ref.handleClick = function(e) {\n            var isLabelClick = e.target === label || label.contains(e.target);\n\n            // don't want to click twice\n            if (isLabelClick) return;\n\n            // click link (will then in turn activate file input)\n            root.ref.label.click();\n        };\n\n        // attach events\n        label.addEventListener('keydown', root.ref.handleKeyDown);\n        root.element.addEventListener('click', root.ref.handleClick);\n\n        // update\n        updateLabelValue(label, props.caption);\n\n        // add!\n        root.appendChild(label);\n        root.ref.label = label;\n    };\n\n    var updateLabelValue = function updateLabelValue(label, value) {\n        label.innerHTML = value;\n        var clickable = label.querySelector('.filepond--label-action');\n        if (clickable) {\n            attr(clickable, 'tabindex', '0');\n        }\n        return value;\n    };\n\n    var dropLabel = createView({\n        name: 'drop-label',\n        ignoreRect: true,\n        create: create$b,\n        destroy: function destroy(_ref2) {\n            var root = _ref2.root;\n            root.ref.label.addEventListener('keydown', root.ref.handleKeyDown);\n            root.element.removeEventListener('click', root.ref.handleClick);\n        },\n        write: createRoute({\n            DID_SET_LABEL_IDLE: function DID_SET_LABEL_IDLE(_ref3) {\n                var root = _ref3.root,\n                    action = _ref3.action;\n                updateLabelValue(root.ref.label, action.value);\n            },\n        }),\n\n        mixins: {\n            styles: ['opacity', 'translateX', 'translateY'],\n            animations: {\n                opacity: { type: 'tween', duration: 150 },\n                translateX: 'spring',\n                translateY: 'spring',\n            },\n        },\n    });\n\n    var blob = createView({\n        name: 'drip-blob',\n        ignoreRect: true,\n        mixins: {\n            styles: ['translateX', 'translateY', 'scaleX', 'scaleY', 'opacity'],\n            animations: {\n                scaleX: 'spring',\n                scaleY: 'spring',\n                translateX: 'spring',\n                translateY: 'spring',\n                opacity: { type: 'tween', duration: 250 },\n            },\n        },\n    });\n\n    var addBlob = function addBlob(_ref) {\n        var root = _ref.root;\n        var centerX = root.rect.element.width * 0.5;\n        var centerY = root.rect.element.height * 0.5;\n\n        root.ref.blob = root.appendChildView(\n            root.createChildView(blob, {\n                opacity: 0,\n                scaleX: 2.5,\n                scaleY: 2.5,\n                translateX: centerX,\n                translateY: centerY,\n            })\n        );\n    };\n\n    var moveBlob = function moveBlob(_ref2) {\n        var root = _ref2.root,\n            action = _ref2.action;\n        if (!root.ref.blob) {\n            addBlob({ root: root });\n            return;\n        }\n\n        root.ref.blob.translateX = action.position.scopeLeft;\n        root.ref.blob.translateY = action.position.scopeTop;\n        root.ref.blob.scaleX = 1;\n        root.ref.blob.scaleY = 1;\n        root.ref.blob.opacity = 1;\n    };\n\n    var hideBlob = function hideBlob(_ref3) {\n        var root = _ref3.root;\n        if (!root.ref.blob) {\n            return;\n        }\n        root.ref.blob.opacity = 0;\n    };\n\n    var explodeBlob = function explodeBlob(_ref4) {\n        var root = _ref4.root;\n        if (!root.ref.blob) {\n            return;\n        }\n        root.ref.blob.scaleX = 2.5;\n        root.ref.blob.scaleY = 2.5;\n        root.ref.blob.opacity = 0;\n    };\n\n    var write$7 = function write(_ref5) {\n        var root = _ref5.root,\n            props = _ref5.props,\n            actions = _ref5.actions;\n        route$4({ root: root, props: props, actions: actions });\n        var blob = root.ref.blob;\n\n        if (actions.length === 0 && blob && blob.opacity === 0) {\n            root.removeChildView(blob);\n            root.ref.blob = null;\n        }\n    };\n\n    var route$4 = createRoute({\n        DID_DRAG: moveBlob,\n        DID_DROP: explodeBlob,\n        DID_END_DRAG: hideBlob,\n    });\n\n    var drip = createView({\n        ignoreRect: true,\n        ignoreRectUpdate: true,\n        name: 'drip',\n        write: write$7,\n    });\n\n    var setInputFiles = function setInputFiles(element, files) {\n        try {\n            // Create a DataTransfer instance and add a newly created file\n            var dataTransfer = new DataTransfer();\n            files.forEach(function(file) {\n                if (file instanceof File) {\n                    dataTransfer.items.add(file);\n                } else {\n                    dataTransfer.items.add(\n                        new File([file], file.name, {\n                            type: file.type,\n                        })\n                    );\n                }\n            });\n\n            // Assign the DataTransfer files list to the file input\n            element.files = dataTransfer.files;\n        } catch (err) {\n            return false;\n        }\n        return true;\n    };\n\n    var create$c = function create(_ref) {\n        var root = _ref.root;\n        root.ref.fields = {};\n        var legend = document.createElement('legend');\n        legend.textContent = 'Files';\n        root.element.appendChild(legend);\n    };\n\n    var getField = function getField(root, id) {\n        return root.ref.fields[id];\n    };\n\n    var syncFieldPositionsWithItems = function syncFieldPositionsWithItems(root) {\n        root.query('GET_ACTIVE_ITEMS').forEach(function(item) {\n            if (!root.ref.fields[item.id]) return;\n            root.element.appendChild(root.ref.fields[item.id]);\n        });\n    };\n\n    var didReorderItems = function didReorderItems(_ref2) {\n        var root = _ref2.root;\n        return syncFieldPositionsWithItems(root);\n    };\n\n    var didAddItem = function didAddItem(_ref3) {\n        var root = _ref3.root,\n            action = _ref3.action;\n        var fileItem = root.query('GET_ITEM', action.id);\n        var isLocalFile = fileItem.origin === FileOrigin.LOCAL;\n        var shouldUseFileInput = !isLocalFile && root.query('SHOULD_UPDATE_FILE_INPUT');\n        var dataContainer = createElement$1('input');\n        dataContainer.type = shouldUseFileInput ? 'file' : 'hidden';\n        dataContainer.name = root.query('GET_NAME');\n        root.ref.fields[action.id] = dataContainer;\n        syncFieldPositionsWithItems(root);\n    };\n\n    var didLoadItem$1 = function didLoadItem(_ref4) {\n        var root = _ref4.root,\n            action = _ref4.action;\n        var field = getField(root, action.id);\n        if (!field) return;\n\n        // store server ref in hidden input\n        if (action.serverFileReference !== null) field.value = action.serverFileReference;\n\n        // store file item in file input\n        if (!root.query('SHOULD_UPDATE_FILE_INPUT')) return;\n\n        var fileItem = root.query('GET_ITEM', action.id);\n        setInputFiles(field, [fileItem.file]);\n    };\n\n    var didPrepareOutput = function didPrepareOutput(_ref5) {\n        var root = _ref5.root,\n            action = _ref5.action;\n        // this timeout pushes the handler after 'load'\n        if (!root.query('SHOULD_UPDATE_FILE_INPUT')) return;\n        setTimeout(function() {\n            var field = getField(root, action.id);\n            if (!field) return;\n            setInputFiles(field, [action.file]);\n        }, 0);\n    };\n\n    var didSetDisabled = function didSetDisabled(_ref6) {\n        var root = _ref6.root;\n        root.element.disabled = root.query('GET_DISABLED');\n    };\n\n    var didRemoveItem = function didRemoveItem(_ref7) {\n        var root = _ref7.root,\n            action = _ref7.action;\n        var field = getField(root, action.id);\n        if (!field) return;\n        if (field.parentNode) field.parentNode.removeChild(field);\n        delete root.ref.fields[action.id];\n    };\n\n    // only runs for server files. will refuse to update the value if the field\n    // is a file field\n    var didDefineValue = function didDefineValue(_ref8) {\n        var root = _ref8.root,\n            action = _ref8.action;\n        var field = getField(root, action.id);\n        if (!field) return;\n        if (action.value === null) {\n            // clear field value\n            field.removeAttribute('value');\n        } else {\n            // set field value\n            if (field.type != 'file') {\n                field.value = action.value;\n            }\n        }\n        syncFieldPositionsWithItems(root);\n    };\n\n    var write$8 = createRoute({\n        DID_SET_DISABLED: didSetDisabled,\n        DID_ADD_ITEM: didAddItem,\n        DID_LOAD_ITEM: didLoadItem$1,\n        DID_REMOVE_ITEM: didRemoveItem,\n        DID_DEFINE_VALUE: didDefineValue,\n        DID_PREPARE_OUTPUT: didPrepareOutput,\n        DID_REORDER_ITEMS: didReorderItems,\n        DID_SORT_ITEMS: didReorderItems,\n    });\n\n    var data = createView({\n        tag: 'fieldset',\n        name: 'data',\n        create: create$c,\n        write: write$8,\n        ignoreRect: true,\n    });\n\n    var getRootNode = function getRootNode(element) {\n        return 'getRootNode' in element ? element.getRootNode() : document;\n    };\n\n    var images = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'tiff'];\n    var text$1 = ['css', 'csv', 'html', 'txt'];\n    var map = {\n        zip: 'zip|compressed',\n        epub: 'application/epub+zip',\n    };\n\n    var guesstimateMimeType = function guesstimateMimeType() {\n        var extension = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n        extension = extension.toLowerCase();\n        if (images.includes(extension)) {\n            return (\n                'image/' +\n                (extension === 'jpg' ? 'jpeg' : extension === 'svg' ? 'svg+xml' : extension)\n            );\n        }\n        if (text$1.includes(extension)) {\n            return 'text/' + extension;\n        }\n\n        return map[extension] || '';\n    };\n\n    var requestDataTransferItems = function requestDataTransferItems(dataTransfer) {\n        return new Promise(function(resolve, reject) {\n            // try to get links from transfer, if found we'll exit immediately (unless a file is in the dataTransfer as well, this is because Firefox could represent the file as a URL and a file object at the same time)\n            var links = getLinks(dataTransfer);\n            if (links.length && !hasFiles(dataTransfer)) {\n                return resolve(links);\n            }\n            // try to get files from the transfer\n            getFiles(dataTransfer).then(resolve);\n        });\n    };\n\n    /**\n     * Test if datatransfer has files\n     */\n    var hasFiles = function hasFiles(dataTransfer) {\n        if (dataTransfer.files) return dataTransfer.files.length > 0;\n        return false;\n    };\n\n    /**\n     * Extracts files from a DataTransfer object\n     */\n    var getFiles = function getFiles(dataTransfer) {\n        return new Promise(function(resolve, reject) {\n            // get the transfer items as promises\n            var promisedFiles = (dataTransfer.items ? Array.from(dataTransfer.items) : [])\n                // only keep file system items (files and directories)\n                .filter(function(item) {\n                    return isFileSystemItem(item);\n                })\n\n                // map each item to promise\n                .map(function(item) {\n                    return getFilesFromItem(item);\n                });\n\n            // if is empty, see if we can extract some info from the files property as a fallback\n            if (!promisedFiles.length) {\n                // TODO: test for directories (should not be allowed)\n                // Use FileReader, problem is that the files property gets lost in the process\n                resolve(dataTransfer.files ? Array.from(dataTransfer.files) : []);\n                return;\n            }\n\n            // done!\n            Promise.all(promisedFiles)\n                .then(function(returnedFileGroups) {\n                    // flatten groups\n                    var files = [];\n                    returnedFileGroups.forEach(function(group) {\n                        files.push.apply(files, group);\n                    });\n\n                    // done (filter out empty files)!\n                    resolve(\n                        files\n                            .filter(function(file) {\n                                return file;\n                            })\n                            .map(function(file) {\n                                if (!file._relativePath)\n                                    file._relativePath = file.webkitRelativePath;\n                                return file;\n                            })\n                    );\n                })\n                .catch(console.error);\n        });\n    };\n\n    var isFileSystemItem = function isFileSystemItem(item) {\n        if (isEntry(item)) {\n            var entry = getAsEntry(item);\n            if (entry) {\n                return entry.isFile || entry.isDirectory;\n            }\n        }\n        return item.kind === 'file';\n    };\n\n    var getFilesFromItem = function getFilesFromItem(item) {\n        return new Promise(function(resolve, reject) {\n            if (isDirectoryEntry(item)) {\n                getFilesInDirectory(getAsEntry(item))\n                    .then(resolve)\n                    .catch(reject);\n                return;\n            }\n\n            resolve([item.getAsFile()]);\n        });\n    };\n\n    var getFilesInDirectory = function getFilesInDirectory(entry) {\n        return new Promise(function(resolve, reject) {\n            var files = [];\n\n            // the total entries to read\n            var dirCounter = 0;\n            var fileCounter = 0;\n\n            var resolveIfDone = function resolveIfDone() {\n                if (fileCounter === 0 && dirCounter === 0) {\n                    resolve(files);\n                }\n            };\n\n            // the recursive function\n            var readEntries = function readEntries(dirEntry) {\n                dirCounter++;\n\n                var directoryReader = dirEntry.createReader();\n\n                // directories are returned in batches, we need to process all batches before we're done\n                var readBatch = function readBatch() {\n                    directoryReader.readEntries(function(entries) {\n                        if (entries.length === 0) {\n                            dirCounter--;\n                            resolveIfDone();\n                            return;\n                        }\n\n                        entries.forEach(function(entry) {\n                            // recursively read more directories\n                            if (entry.isDirectory) {\n                                readEntries(entry);\n                            } else {\n                                // read as file\n                                fileCounter++;\n\n                                entry.file(function(file) {\n                                    var correctedFile = correctMissingFileType(file);\n                                    if (entry.fullPath)\n                                        correctedFile._relativePath = entry.fullPath;\n                                    files.push(correctedFile);\n                                    fileCounter--;\n                                    resolveIfDone();\n                                });\n                            }\n                        });\n\n                        // try to get next batch of files\n                        readBatch();\n                    }, reject);\n                };\n\n                // read first batch of files\n                readBatch();\n            };\n\n            // go!\n            readEntries(entry);\n        });\n    };\n\n    var correctMissingFileType = function correctMissingFileType(file) {\n        if (file.type.length) return file;\n        var date = file.lastModifiedDate;\n        var name = file.name;\n        var type = guesstimateMimeType(getExtensionFromFilename(file.name));\n        if (!type.length) return file;\n        file = file.slice(0, file.size, type);\n        file.name = name;\n        file.lastModifiedDate = date;\n        return file;\n    };\n\n    var isDirectoryEntry = function isDirectoryEntry(item) {\n        return isEntry(item) && (getAsEntry(item) || {}).isDirectory;\n    };\n\n    var isEntry = function isEntry(item) {\n        return 'webkitGetAsEntry' in item;\n    };\n\n    var getAsEntry = function getAsEntry(item) {\n        return item.webkitGetAsEntry();\n    };\n\n    /**\n     * Extracts links from a DataTransfer object\n     */\n    var getLinks = function getLinks(dataTransfer) {\n        var links = [];\n        try {\n            // look in meta data property\n            links = getLinksFromTransferMetaData(dataTransfer);\n            if (links.length) {\n                return links;\n            }\n            links = getLinksFromTransferURLData(dataTransfer);\n        } catch (e) {\n            // nope nope nope (probably IE trouble)\n        }\n        return links;\n    };\n\n    var getLinksFromTransferURLData = function getLinksFromTransferURLData(dataTransfer) {\n        var data = dataTransfer.getData('url');\n        if (typeof data === 'string' && data.length) {\n            return [data];\n        }\n        return [];\n    };\n\n    var getLinksFromTransferMetaData = function getLinksFromTransferMetaData(dataTransfer) {\n        var data = dataTransfer.getData('text/html');\n        if (typeof data === 'string' && data.length) {\n            var matches = data.match(/src\\s*=\\s*\"(.+?)\"/);\n            if (matches) {\n                return [matches[1]];\n            }\n        }\n        return [];\n    };\n\n    var dragNDropObservers = [];\n\n    var eventPosition = function eventPosition(e) {\n        return {\n            pageLeft: e.pageX,\n            pageTop: e.pageY,\n            scopeLeft: e.offsetX || e.layerX,\n            scopeTop: e.offsetY || e.layerY,\n        };\n    };\n\n    var createDragNDropClient = function createDragNDropClient(\n        element,\n        scopeToObserve,\n        filterElement\n    ) {\n        var observer = getDragNDropObserver(scopeToObserve);\n\n        var client = {\n            element: element,\n            filterElement: filterElement,\n            state: null,\n            ondrop: function ondrop() {},\n            onenter: function onenter() {},\n            ondrag: function ondrag() {},\n            onexit: function onexit() {},\n            onload: function onload() {},\n            allowdrop: function allowdrop() {},\n        };\n\n        client.destroy = observer.addListener(client);\n\n        return client;\n    };\n\n    var getDragNDropObserver = function getDragNDropObserver(element) {\n        // see if already exists, if so, return\n        var observer = dragNDropObservers.find(function(item) {\n            return item.element === element;\n        });\n        if (observer) {\n            return observer;\n        }\n\n        // create new observer, does not yet exist for this element\n        var newObserver = createDragNDropObserver(element);\n        dragNDropObservers.push(newObserver);\n        return newObserver;\n    };\n\n    var createDragNDropObserver = function createDragNDropObserver(element) {\n        var clients = [];\n\n        var routes = {\n            dragenter: dragenter,\n            dragover: dragover,\n            dragleave: dragleave,\n            drop: drop,\n        };\n\n        var handlers = {};\n\n        forin(routes, function(event, createHandler) {\n            handlers[event] = createHandler(element, clients);\n            element.addEventListener(event, handlers[event], false);\n        });\n\n        var observer = {\n            element: element,\n            addListener: function addListener(client) {\n                // add as client\n                clients.push(client);\n\n                // return removeListener function\n                return function() {\n                    // remove client\n                    clients.splice(clients.indexOf(client), 1);\n\n                    // if no more clients, clean up observer\n                    if (clients.length === 0) {\n                        dragNDropObservers.splice(dragNDropObservers.indexOf(observer), 1);\n\n                        forin(routes, function(event) {\n                            element.removeEventListener(event, handlers[event], false);\n                        });\n                    }\n                };\n            },\n        };\n\n        return observer;\n    };\n\n    var elementFromPoint = function elementFromPoint(root, point) {\n        if (!('elementFromPoint' in root)) {\n            root = document;\n        }\n        return root.elementFromPoint(point.x, point.y);\n    };\n\n    var isEventTarget = function isEventTarget(e, target) {\n        // get root\n        var root = getRootNode(target);\n\n        // get element at position\n        // if root is not actual shadow DOM and does not have elementFromPoint method, use the one on document\n        var elementAtPosition = elementFromPoint(root, {\n            x: e.pageX - window.pageXOffset,\n            y: e.pageY - window.pageYOffset,\n        });\n\n        // test if target is the element or if one of its children is\n        return elementAtPosition === target || target.contains(elementAtPosition);\n    };\n\n    var initialTarget = null;\n\n    var setDropEffect = function setDropEffect(dataTransfer, effect) {\n        // is in try catch as IE11 will throw error if not\n        try {\n            dataTransfer.dropEffect = effect;\n        } catch (e) {}\n    };\n\n    var dragenter = function dragenter(root, clients) {\n        return function(e) {\n            e.preventDefault();\n\n            initialTarget = e.target;\n\n            clients.forEach(function(client) {\n                var element = client.element,\n                    onenter = client.onenter;\n\n                if (isEventTarget(e, element)) {\n                    client.state = 'enter';\n\n                    // fire enter event\n                    onenter(eventPosition(e));\n                }\n            });\n        };\n    };\n\n    var dragover = function dragover(root, clients) {\n        return function(e) {\n            e.preventDefault();\n\n            var dataTransfer = e.dataTransfer;\n\n            requestDataTransferItems(dataTransfer).then(function(items) {\n                var overDropTarget = false;\n\n                clients.some(function(client) {\n                    var filterElement = client.filterElement,\n                        element = client.element,\n                        onenter = client.onenter,\n                        onexit = client.onexit,\n                        ondrag = client.ondrag,\n                        allowdrop = client.allowdrop;\n\n                    // by default we can drop\n                    setDropEffect(dataTransfer, 'copy');\n\n                    // allow transfer of these items\n                    var allowsTransfer = allowdrop(items);\n\n                    // only used when can be dropped on page\n                    if (!allowsTransfer) {\n                        setDropEffect(dataTransfer, 'none');\n                        return;\n                    }\n\n                    // targetting this client\n                    if (isEventTarget(e, element)) {\n                        overDropTarget = true;\n\n                        // had no previous state, means we are entering this client\n                        if (client.state === null) {\n                            client.state = 'enter';\n                            onenter(eventPosition(e));\n                            return;\n                        }\n\n                        // now over element (no matter if it allows the drop or not)\n                        client.state = 'over';\n\n                        // needs to allow transfer\n                        if (filterElement && !allowsTransfer) {\n                            setDropEffect(dataTransfer, 'none');\n                            return;\n                        }\n\n                        // dragging\n                        ondrag(eventPosition(e));\n                    } else {\n                        // should be over an element to drop\n                        if (filterElement && !overDropTarget) {\n                            setDropEffect(dataTransfer, 'none');\n                        }\n\n                        // might have just left this client?\n                        if (client.state) {\n                            client.state = null;\n                            onexit(eventPosition(e));\n                        }\n                    }\n                });\n            });\n        };\n    };\n\n    var drop = function drop(root, clients) {\n        return function(e) {\n            e.preventDefault();\n\n            var dataTransfer = e.dataTransfer;\n\n            requestDataTransferItems(dataTransfer).then(function(items) {\n                clients.forEach(function(client) {\n                    var filterElement = client.filterElement,\n                        element = client.element,\n                        ondrop = client.ondrop,\n                        onexit = client.onexit,\n                        allowdrop = client.allowdrop;\n\n                    client.state = null;\n\n                    // if we're filtering on element we need to be over the element to drop\n                    if (filterElement && !isEventTarget(e, element)) return;\n\n                    // no transfer for this client\n                    if (!allowdrop(items)) return onexit(eventPosition(e));\n\n                    // we can drop these items on this client\n                    ondrop(eventPosition(e), items);\n                });\n            });\n        };\n    };\n\n    var dragleave = function dragleave(root, clients) {\n        return function(e) {\n            if (initialTarget !== e.target) {\n                return;\n            }\n\n            clients.forEach(function(client) {\n                var onexit = client.onexit;\n\n                client.state = null;\n\n                onexit(eventPosition(e));\n            });\n        };\n    };\n\n    var createHopper = function createHopper(scope, validateItems, options) {\n        // is now hopper scope\n        scope.classList.add('filepond--hopper');\n\n        // shortcuts\n        var catchesDropsOnPage = options.catchesDropsOnPage,\n            requiresDropOnElement = options.requiresDropOnElement,\n            _options$filterItems = options.filterItems,\n            filterItems =\n                _options$filterItems === void 0\n                    ? function(items) {\n                          return items;\n                      }\n                    : _options$filterItems;\n\n        // create a dnd client\n        var client = createDragNDropClient(\n            scope,\n            catchesDropsOnPage ? document.documentElement : scope,\n            requiresDropOnElement\n        );\n\n        // current client state\n        var lastState = '';\n        var currentState = '';\n\n        // determines if a file may be dropped\n        client.allowdrop = function(items) {\n            // TODO: if we can, throw error to indicate the items cannot by dropped\n\n            return validateItems(filterItems(items));\n        };\n\n        client.ondrop = function(position, items) {\n            var filteredItems = filterItems(items);\n\n            if (!validateItems(filteredItems)) {\n                api.ondragend(position);\n                return;\n            }\n\n            currentState = 'drag-drop';\n\n            api.onload(filteredItems, position);\n        };\n\n        client.ondrag = function(position) {\n            api.ondrag(position);\n        };\n\n        client.onenter = function(position) {\n            currentState = 'drag-over';\n\n            api.ondragstart(position);\n        };\n\n        client.onexit = function(position) {\n            currentState = 'drag-exit';\n\n            api.ondragend(position);\n        };\n\n        var api = {\n            updateHopperState: function updateHopperState() {\n                if (lastState !== currentState) {\n                    scope.dataset.hopperState = currentState;\n                    lastState = currentState;\n                }\n            },\n            onload: function onload() {},\n            ondragstart: function ondragstart() {},\n            ondrag: function ondrag() {},\n            ondragend: function ondragend() {},\n            destroy: function destroy() {\n                // destroy client\n                client.destroy();\n            },\n        };\n\n        return api;\n    };\n\n    var listening = false;\n    var listeners$1 = [];\n\n    var handlePaste = function handlePaste(e) {\n        // if is pasting in input or textarea and the target is outside of a filepond scope, ignore\n        var activeEl = document.activeElement;\n        var isActiveElementEditable =\n            activeEl &&\n            (/textarea|input/i.test(activeEl.nodeName) ||\n                activeEl.getAttribute('contenteditable') === 'true' ||\n                activeEl.getAttribute('contenteditable') === '');\n\n        if (isActiveElementEditable) {\n            // test textarea or input is contained in filepond root\n            var inScope = false;\n            var element = activeEl;\n            while (element !== document.body) {\n                if (element.classList.contains('filepond--root')) {\n                    inScope = true;\n                    break;\n                }\n                element = element.parentNode;\n            }\n\n            if (!inScope) return;\n        }\n\n        requestDataTransferItems(e.clipboardData).then(function(files) {\n            // no files received\n            if (!files.length) {\n                return;\n            }\n\n            // notify listeners of received files\n            listeners$1.forEach(function(listener) {\n                return listener(files);\n            });\n        });\n    };\n\n    var listen = function listen(cb) {\n        // can't add twice\n        if (listeners$1.includes(cb)) {\n            return;\n        }\n\n        // add initial listener\n        listeners$1.push(cb);\n\n        // setup paste listener for entire page\n        if (listening) {\n            return;\n        }\n\n        listening = true;\n        document.addEventListener('paste', handlePaste);\n    };\n\n    var unlisten = function unlisten(listener) {\n        arrayRemove(listeners$1, listeners$1.indexOf(listener));\n\n        // clean up\n        if (listeners$1.length === 0) {\n            document.removeEventListener('paste', handlePaste);\n            listening = false;\n        }\n    };\n\n    var createPaster = function createPaster() {\n        var cb = function cb(files) {\n            api.onload(files);\n        };\n\n        var api = {\n            destroy: function destroy() {\n                unlisten(cb);\n            },\n            onload: function onload() {},\n        };\n\n        listen(cb);\n\n        return api;\n    };\n\n    /**\n     * Creates the file view\n     */\n    var create$d = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        root.element.id = 'filepond--assistant-' + props.id;\n        attr(root.element, 'role', 'alert');\n        attr(root.element, 'aria-live', 'polite');\n        attr(root.element, 'aria-relevant', 'additions');\n    };\n\n    var addFilesNotificationTimeout = null;\n    var notificationClearTimeout = null;\n\n    var filenames = [];\n\n    var assist = function assist(root, message) {\n        root.element.textContent = message;\n    };\n\n    var clear$1 = function clear(root) {\n        root.element.textContent = '';\n    };\n\n    var listModified = function listModified(root, filename, label) {\n        var total = root.query('GET_TOTAL_ITEMS');\n        assist(\n            root,\n            label +\n                ' ' +\n                filename +\n                ', ' +\n                total +\n                ' ' +\n                (total === 1\n                    ? root.query('GET_LABEL_FILE_COUNT_SINGULAR')\n                    : root.query('GET_LABEL_FILE_COUNT_PLURAL'))\n        );\n\n        // clear group after set amount of time so the status is not read twice\n        clearTimeout(notificationClearTimeout);\n        notificationClearTimeout = setTimeout(function() {\n            clear$1(root);\n        }, 1500);\n    };\n\n    var isUsingFilePond = function isUsingFilePond(root) {\n        return root.element.parentNode.contains(document.activeElement);\n    };\n\n    var itemAdded = function itemAdded(_ref2) {\n        var root = _ref2.root,\n            action = _ref2.action;\n        if (!isUsingFilePond(root)) {\n            return;\n        }\n\n        root.element.textContent = '';\n        var item = root.query('GET_ITEM', action.id);\n        filenames.push(item.filename);\n\n        clearTimeout(addFilesNotificationTimeout);\n        addFilesNotificationTimeout = setTimeout(function() {\n            listModified(root, filenames.join(', '), root.query('GET_LABEL_FILE_ADDED'));\n            filenames.length = 0;\n        }, 750);\n    };\n\n    var itemRemoved = function itemRemoved(_ref3) {\n        var root = _ref3.root,\n            action = _ref3.action;\n        if (!isUsingFilePond(root)) {\n            return;\n        }\n\n        var item = action.item;\n        listModified(root, item.filename, root.query('GET_LABEL_FILE_REMOVED'));\n    };\n\n    var itemProcessed = function itemProcessed(_ref4) {\n        var root = _ref4.root,\n            action = _ref4.action;\n        // will also notify the user when FilePond is not being used, as the user might be occupied with other activities while uploading a file\n\n        var item = root.query('GET_ITEM', action.id);\n        var filename = item.filename;\n        var label = root.query('GET_LABEL_FILE_PROCESSING_COMPLETE');\n\n        assist(root, filename + ' ' + label);\n    };\n\n    var itemProcessedUndo = function itemProcessedUndo(_ref5) {\n        var root = _ref5.root,\n            action = _ref5.action;\n        var item = root.query('GET_ITEM', action.id);\n        var filename = item.filename;\n        var label = root.query('GET_LABEL_FILE_PROCESSING_ABORTED');\n\n        assist(root, filename + ' ' + label);\n    };\n\n    var itemError = function itemError(_ref6) {\n        var root = _ref6.root,\n            action = _ref6.action;\n        var item = root.query('GET_ITEM', action.id);\n        var filename = item.filename;\n\n        // will also notify the user when FilePond is not being used, as the user might be occupied with other activities while uploading a file\n\n        assist(root, action.status.main + ' ' + filename + ' ' + action.status.sub);\n    };\n\n    var assistant = createView({\n        create: create$d,\n        ignoreRect: true,\n        ignoreRectUpdate: true,\n        write: createRoute({\n            DID_LOAD_ITEM: itemAdded,\n            DID_REMOVE_ITEM: itemRemoved,\n            DID_COMPLETE_ITEM_PROCESSING: itemProcessed,\n\n            DID_ABORT_ITEM_PROCESSING: itemProcessedUndo,\n            DID_REVERT_ITEM_PROCESSING: itemProcessedUndo,\n\n            DID_THROW_ITEM_REMOVE_ERROR: itemError,\n            DID_THROW_ITEM_LOAD_ERROR: itemError,\n            DID_THROW_ITEM_INVALID: itemError,\n            DID_THROW_ITEM_PROCESSING_ERROR: itemError,\n        }),\n\n        tag: 'span',\n        name: 'assistant',\n    });\n\n    var toCamels = function toCamels(string) {\n        var separator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '-';\n        return string.replace(new RegExp(separator + '.', 'g'), function(sub) {\n            return sub.charAt(1).toUpperCase();\n        });\n    };\n\n    var debounce = function debounce(func) {\n        var interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 16;\n        var immidiateOnly =\n            arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n        var last = Date.now();\n        var timeout = null;\n\n        return function() {\n            for (\n                var _len = arguments.length, args = new Array(_len), _key = 0;\n                _key < _len;\n                _key++\n            ) {\n                args[_key] = arguments[_key];\n            }\n            clearTimeout(timeout);\n\n            var dist = Date.now() - last;\n\n            var fn = function fn() {\n                last = Date.now();\n                func.apply(void 0, args);\n            };\n\n            if (dist < interval) {\n                // we need to delay by the difference between interval and dist\n                // for example: if distance is 10 ms and interval is 16 ms,\n                // we need to wait an additional 6ms before calling the function)\n                if (!immidiateOnly) {\n                    timeout = setTimeout(fn, interval - dist);\n                }\n            } else {\n                // go!\n                fn();\n            }\n        };\n    };\n\n    var MAX_FILES_LIMIT = 1000000;\n\n    var prevent = function prevent(e) {\n        return e.preventDefault();\n    };\n\n    var create$e = function create(_ref) {\n        var root = _ref.root,\n            props = _ref.props;\n        // Add id\n        var id = root.query('GET_ID');\n        if (id) {\n            root.element.id = id;\n        }\n\n        // Add className\n        var className = root.query('GET_CLASS_NAME');\n        if (className) {\n            className\n                .split(' ')\n                .filter(function(name) {\n                    return name.length;\n                })\n                .forEach(function(name) {\n                    root.element.classList.add(name);\n                });\n        }\n\n        // Field label\n        root.ref.label = root.appendChildView(\n            root.createChildView(\n                dropLabel,\n                Object.assign({}, props, {\n                    translateY: null,\n                    caption: root.query('GET_LABEL_IDLE'),\n                })\n            )\n        );\n\n        // List of items\n        root.ref.list = root.appendChildView(\n            root.createChildView(listScroller, { translateY: null })\n        );\n\n        // Background panel\n        root.ref.panel = root.appendChildView(root.createChildView(panel, { name: 'panel-root' }));\n\n        // Assistant notifies assistive tech when content changes\n        root.ref.assistant = root.appendChildView(\n            root.createChildView(assistant, Object.assign({}, props))\n        );\n\n        // Data\n        root.ref.data = root.appendChildView(root.createChildView(data, Object.assign({}, props)));\n\n        // Measure (tests if fixed height was set)\n        // DOCTYPE needs to be set for this to work\n        root.ref.measure = createElement$1('div');\n        root.ref.measure.style.height = '100%';\n        root.element.appendChild(root.ref.measure);\n\n        // information on the root height or fixed height status\n        root.ref.bounds = null;\n\n        // apply initial style properties\n        root.query('GET_STYLES')\n            .filter(function(style) {\n                return !isEmpty(style.value);\n            })\n            .map(function(_ref2) {\n                var name = _ref2.name,\n                    value = _ref2.value;\n                root.element.dataset[name] = value;\n            });\n\n        // determine if width changed\n        root.ref.widthPrevious = null;\n        root.ref.widthUpdated = debounce(function() {\n            root.ref.updateHistory = [];\n            root.dispatch('DID_RESIZE_ROOT');\n        }, 250);\n\n        // history of updates\n        root.ref.previousAspectRatio = null;\n        root.ref.updateHistory = [];\n\n        // prevent scrolling and zooming on iOS (only if supports pointer events, for then we can enable reorder)\n        var canHover = window.matchMedia('(pointer: fine) and (hover: hover)').matches;\n        var hasPointerEvents = 'PointerEvent' in window;\n        if (root.query('GET_ALLOW_REORDER') && hasPointerEvents && !canHover) {\n            root.element.addEventListener('touchmove', prevent, { passive: false });\n            root.element.addEventListener('gesturestart', prevent);\n        }\n\n        // add credits\n        var credits = root.query('GET_CREDITS');\n        var hasCredits = credits.length === 2;\n        if (hasCredits) {\n            var frag = document.createElement('a');\n            frag.className = 'filepond--credits';\n            frag.href = credits[0];\n            frag.tabIndex = -1;\n            frag.target = '_blank';\n            frag.rel = 'noopener noreferrer nofollow';\n            frag.textContent = credits[1];\n            root.element.appendChild(frag);\n            root.ref.credits = frag;\n        }\n    };\n\n    var write$9 = function write(_ref3) {\n        var root = _ref3.root,\n            props = _ref3.props,\n            actions = _ref3.actions;\n        // route actions\n        route$5({ root: root, props: props, actions: actions });\n\n        // apply style properties\n        actions\n            .filter(function(action) {\n                return /^DID_SET_STYLE_/.test(action.type);\n            })\n            .filter(function(action) {\n                return !isEmpty(action.data.value);\n            })\n            .map(function(_ref4) {\n                var type = _ref4.type,\n                    data = _ref4.data;\n                var name = toCamels(type.substring(8).toLowerCase(), '_');\n                root.element.dataset[name] = data.value;\n                root.invalidateLayout();\n            });\n\n        if (root.rect.element.hidden) return;\n\n        if (root.rect.element.width !== root.ref.widthPrevious) {\n            root.ref.widthPrevious = root.rect.element.width;\n            root.ref.widthUpdated();\n        }\n\n        // get box bounds, we do this only once\n        var bounds = root.ref.bounds;\n        if (!bounds) {\n            bounds = root.ref.bounds = calculateRootBoundingBoxHeight(root);\n\n            // destroy measure element\n            root.element.removeChild(root.ref.measure);\n            root.ref.measure = null;\n        }\n\n        // get quick references to various high level parts of the upload tool\n        var _root$ref = root.ref,\n            hopper = _root$ref.hopper,\n            label = _root$ref.label,\n            list = _root$ref.list,\n            panel = _root$ref.panel;\n\n        // sets correct state to hopper scope\n        if (hopper) {\n            hopper.updateHopperState();\n        }\n\n        // bool to indicate if we're full or not\n        var aspectRatio = root.query('GET_PANEL_ASPECT_RATIO');\n        var isMultiItem = root.query('GET_ALLOW_MULTIPLE');\n        var totalItems = root.query('GET_TOTAL_ITEMS');\n        var maxItems = isMultiItem ? root.query('GET_MAX_FILES') || MAX_FILES_LIMIT : 1;\n        var atMaxCapacity = totalItems === maxItems;\n\n        // action used to add item\n        var addAction = actions.find(function(action) {\n            return action.type === 'DID_ADD_ITEM';\n        });\n\n        // if reached max capacity and we've just reached it\n        if (atMaxCapacity && addAction) {\n            // get interaction type\n            var interactionMethod = addAction.data.interactionMethod;\n\n            // hide label\n            label.opacity = 0;\n\n            if (isMultiItem) {\n                label.translateY = -40;\n            } else {\n                if (interactionMethod === InteractionMethod.API) {\n                    label.translateX = 40;\n                } else if (interactionMethod === InteractionMethod.BROWSE) {\n                    label.translateY = 40;\n                } else {\n                    label.translateY = 30;\n                }\n            }\n        } else if (!atMaxCapacity) {\n            label.opacity = 1;\n            label.translateX = 0;\n            label.translateY = 0;\n        }\n\n        var listItemMargin = calculateListItemMargin(root);\n\n        var listHeight = calculateListHeight(root);\n\n        var labelHeight = label.rect.element.height;\n        var currentLabelHeight = !isMultiItem || atMaxCapacity ? 0 : labelHeight;\n\n        var listMarginTop = atMaxCapacity ? list.rect.element.marginTop : 0;\n        var listMarginBottom = totalItems === 0 ? 0 : list.rect.element.marginBottom;\n\n        var visualHeight =\n            currentLabelHeight + listMarginTop + listHeight.visual + listMarginBottom;\n        var boundsHeight =\n            currentLabelHeight + listMarginTop + listHeight.bounds + listMarginBottom;\n\n        // link list to label bottom position\n        list.translateY =\n            Math.max(0, currentLabelHeight - list.rect.element.marginTop) - listItemMargin.top;\n\n        if (aspectRatio) {\n            // fixed aspect ratio\n\n            // calculate height based on width\n            var width = root.rect.element.width;\n            var height = width * aspectRatio;\n\n            // clear history if aspect ratio has changed\n            if (aspectRatio !== root.ref.previousAspectRatio) {\n                root.ref.previousAspectRatio = aspectRatio;\n                root.ref.updateHistory = [];\n            }\n\n            // remember this width\n            var history = root.ref.updateHistory;\n            history.push(width);\n\n            var MAX_BOUNCES = 2;\n            if (history.length > MAX_BOUNCES * 2) {\n                var l = history.length;\n                var bottom = l - 10;\n                var bounces = 0;\n                for (var i = l; i >= bottom; i--) {\n                    if (history[i] === history[i - 2]) {\n                        bounces++;\n                    }\n\n                    if (bounces >= MAX_BOUNCES) {\n                        // dont adjust height\n                        return;\n                    }\n                }\n            }\n\n            // fix height of panel so it adheres to aspect ratio\n            panel.scalable = false;\n            panel.height = height;\n\n            // available height for list\n            var listAvailableHeight =\n                // the height of the panel minus the label height\n                height -\n                currentLabelHeight -\n                // the room we leave open between the end of the list and the panel bottom\n                (listMarginBottom - listItemMargin.bottom) -\n                // if we're full we need to leave some room between the top of the panel and the list\n                (atMaxCapacity ? listMarginTop : 0);\n\n            if (listHeight.visual > listAvailableHeight) {\n                list.overflow = listAvailableHeight;\n            } else {\n                list.overflow = null;\n            }\n\n            // set container bounds (so pushes siblings downwards)\n            root.height = height;\n        } else if (bounds.fixedHeight) {\n            // fixed height\n\n            // fix height of panel\n            panel.scalable = false;\n\n            // available height for list\n            var _listAvailableHeight =\n                // the height of the panel minus the label height\n                bounds.fixedHeight -\n                currentLabelHeight -\n                // the room we leave open between the end of the list and the panel bottom\n                (listMarginBottom - listItemMargin.bottom) -\n                // if we're full we need to leave some room between the top of the panel and the list\n                (atMaxCapacity ? listMarginTop : 0);\n\n            // set list height\n            if (listHeight.visual > _listAvailableHeight) {\n                list.overflow = _listAvailableHeight;\n            } else {\n                list.overflow = null;\n            }\n\n            // no need to set container bounds as these are handles by CSS fixed height\n        } else if (bounds.cappedHeight) {\n            // max-height\n\n            // not a fixed height panel\n            var isCappedHeight = visualHeight >= bounds.cappedHeight;\n            var panelHeight = Math.min(bounds.cappedHeight, visualHeight);\n            panel.scalable = true;\n            panel.height = isCappedHeight\n                ? panelHeight\n                : panelHeight - listItemMargin.top - listItemMargin.bottom;\n\n            // available height for list\n            var _listAvailableHeight2 =\n                // the height of the panel minus the label height\n                panelHeight -\n                currentLabelHeight -\n                // the room we leave open between the end of the list and the panel bottom\n                (listMarginBottom - listItemMargin.bottom) -\n                // if we're full we need to leave some room between the top of the panel and the list\n                (atMaxCapacity ? listMarginTop : 0);\n\n            // set list height (if is overflowing)\n            if (visualHeight > bounds.cappedHeight && listHeight.visual > _listAvailableHeight2) {\n                list.overflow = _listAvailableHeight2;\n            } else {\n                list.overflow = null;\n            }\n\n            // set container bounds (so pushes siblings downwards)\n            root.height = Math.min(\n                bounds.cappedHeight,\n                boundsHeight - listItemMargin.top - listItemMargin.bottom\n            );\n        } else {\n            // flexible height\n\n            // not a fixed height panel\n            var itemMargin = totalItems > 0 ? listItemMargin.top + listItemMargin.bottom : 0;\n            panel.scalable = true;\n            panel.height = Math.max(labelHeight, visualHeight - itemMargin);\n\n            // set container bounds (so pushes siblings downwards)\n            root.height = Math.max(labelHeight, boundsHeight - itemMargin);\n        }\n\n        // move credits to bottom\n        if (root.ref.credits && panel.heightCurrent)\n            root.ref.credits.style.transform = 'translateY(' + panel.heightCurrent + 'px)';\n    };\n\n    var calculateListItemMargin = function calculateListItemMargin(root) {\n        var item = root.ref.list.childViews[0].childViews[0];\n        return item\n            ? {\n                  top: item.rect.element.marginTop,\n                  bottom: item.rect.element.marginBottom,\n              }\n            : {\n                  top: 0,\n                  bottom: 0,\n              };\n    };\n\n    var calculateListHeight = function calculateListHeight(root) {\n        var visual = 0;\n        var bounds = 0;\n\n        // get file list reference\n        var scrollList = root.ref.list;\n        var itemList = scrollList.childViews[0];\n        var visibleChildren = itemList.childViews.filter(function(child) {\n            return child.rect.element.height;\n        });\n        var children = root\n            .query('GET_ACTIVE_ITEMS')\n            .map(function(item) {\n                return visibleChildren.find(function(child) {\n                    return child.id === item.id;\n                });\n            })\n            .filter(function(item) {\n                return item;\n            });\n\n        // no children, done!\n        if (children.length === 0) return { visual: visual, bounds: bounds };\n\n        var horizontalSpace = itemList.rect.element.width;\n        var dragIndex = getItemIndexByPosition(itemList, children, scrollList.dragCoordinates);\n\n        var childRect = children[0].rect.element;\n\n        var itemVerticalMargin = childRect.marginTop + childRect.marginBottom;\n        var itemHorizontalMargin = childRect.marginLeft + childRect.marginRight;\n\n        var itemWidth = childRect.width + itemHorizontalMargin;\n        var itemHeight = childRect.height + itemVerticalMargin;\n\n        var newItem = typeof dragIndex !== 'undefined' && dragIndex >= 0 ? 1 : 0;\n        var removedItem = children.find(function(child) {\n            return child.markedForRemoval && child.opacity < 0.45;\n        })\n            ? -1\n            : 0;\n        var verticalItemCount = children.length + newItem + removedItem;\n        var itemsPerRow = getItemsPerRow(horizontalSpace, itemWidth);\n\n        // stack\n        if (itemsPerRow === 1) {\n            children.forEach(function(item) {\n                var height = item.rect.element.height + itemVerticalMargin;\n                bounds += height;\n                visual += height * item.opacity;\n            });\n        }\n        // grid\n        else {\n            bounds = Math.ceil(verticalItemCount / itemsPerRow) * itemHeight;\n            visual = bounds;\n        }\n\n        return { visual: visual, bounds: bounds };\n    };\n\n    var calculateRootBoundingBoxHeight = function calculateRootBoundingBoxHeight(root) {\n        var height = root.ref.measureHeight || null;\n        var cappedHeight = parseInt(root.style.maxHeight, 10) || null;\n        var fixedHeight = height === 0 ? null : height;\n\n        return {\n            cappedHeight: cappedHeight,\n            fixedHeight: fixedHeight,\n        };\n    };\n\n    var exceedsMaxFiles = function exceedsMaxFiles(root, items) {\n        var allowReplace = root.query('GET_ALLOW_REPLACE');\n        var allowMultiple = root.query('GET_ALLOW_MULTIPLE');\n        var totalItems = root.query('GET_TOTAL_ITEMS');\n        var maxItems = root.query('GET_MAX_FILES');\n\n        // total amount of items being dragged\n        var totalBrowseItems = items.length;\n\n        // if does not allow multiple items and dragging more than one item\n        if (!allowMultiple && totalBrowseItems > 1) {\n            root.dispatch('DID_THROW_MAX_FILES', {\n                source: items,\n                error: createResponse('warning', 0, 'Max files'),\n            });\n\n            return true;\n        }\n\n        // limit max items to one if not allowed to drop multiple items\n        maxItems = allowMultiple ? maxItems : 1;\n\n        if (!allowMultiple && allowReplace) {\n            // There is only one item, so there is room to replace or add an item\n            return false;\n        }\n\n        // no more room?\n        var hasMaxItems = isInt(maxItems);\n        if (hasMaxItems && totalItems + totalBrowseItems > maxItems) {\n            root.dispatch('DID_THROW_MAX_FILES', {\n                source: items,\n                error: createResponse('warning', 0, 'Max files'),\n            });\n\n            return true;\n        }\n\n        return false;\n    };\n\n    var getDragIndex = function getDragIndex(list, children, position) {\n        var itemList = list.childViews[0];\n        return getItemIndexByPosition(itemList, children, {\n            left: position.scopeLeft - itemList.rect.element.left,\n            top:\n                position.scopeTop -\n                (list.rect.outer.top + list.rect.element.marginTop + list.rect.element.scrollTop),\n        });\n    };\n\n    /**\n     * Enable or disable file drop functionality\n     */\n    var toggleDrop = function toggleDrop(root) {\n        var isAllowed = root.query('GET_ALLOW_DROP');\n        var isDisabled = root.query('GET_DISABLED');\n        var enabled = isAllowed && !isDisabled;\n        if (enabled && !root.ref.hopper) {\n            var hopper = createHopper(\n                root.element,\n                function(items) {\n                    // allow quick validation of dropped items\n                    var beforeDropFile =\n                        root.query('GET_BEFORE_DROP_FILE') ||\n                        function() {\n                            return true;\n                        };\n\n                    // all items should be validated by all filters as valid\n                    var dropValidation = root.query('GET_DROP_VALIDATION');\n                    return dropValidation\n                        ? items.every(function(item) {\n                              return (\n                                  applyFilters('ALLOW_HOPPER_ITEM', item, {\n                                      query: root.query,\n                                  }).every(function(result) {\n                                      return result === true;\n                                  }) && beforeDropFile(item)\n                              );\n                          })\n                        : true;\n                },\n                {\n                    filterItems: function filterItems(items) {\n                        var ignoredFiles = root.query('GET_IGNORED_FILES');\n                        return items.filter(function(item) {\n                            if (isFile(item)) {\n                                return !ignoredFiles.includes(item.name.toLowerCase());\n                            }\n                            return true;\n                        });\n                    },\n                    catchesDropsOnPage: root.query('GET_DROP_ON_PAGE'),\n                    requiresDropOnElement: root.query('GET_DROP_ON_ELEMENT'),\n                }\n            );\n\n            hopper.onload = function(items, position) {\n                // get item children elements and sort based on list sort\n                var list = root.ref.list.childViews[0];\n                var visibleChildren = list.childViews.filter(function(child) {\n                    return child.rect.element.height;\n                });\n                var children = root\n                    .query('GET_ACTIVE_ITEMS')\n                    .map(function(item) {\n                        return visibleChildren.find(function(child) {\n                            return child.id === item.id;\n                        });\n                    })\n                    .filter(function(item) {\n                        return item;\n                    });\n\n                applyFilterChain('ADD_ITEMS', items, { dispatch: root.dispatch }).then(function(\n                    queue\n                ) {\n                    // these files don't fit so stop here\n                    if (exceedsMaxFiles(root, queue)) return false;\n\n                    // go\n                    root.dispatch('ADD_ITEMS', {\n                        items: queue,\n                        index: getDragIndex(root.ref.list, children, position),\n                        interactionMethod: InteractionMethod.DROP,\n                    });\n                });\n\n                root.dispatch('DID_DROP', { position: position });\n\n                root.dispatch('DID_END_DRAG', { position: position });\n            };\n\n            hopper.ondragstart = function(position) {\n                root.dispatch('DID_START_DRAG', { position: position });\n            };\n\n            hopper.ondrag = debounce(function(position) {\n                root.dispatch('DID_DRAG', { position: position });\n            });\n\n            hopper.ondragend = function(position) {\n                root.dispatch('DID_END_DRAG', { position: position });\n            };\n\n            root.ref.hopper = hopper;\n\n            root.ref.drip = root.appendChildView(root.createChildView(drip));\n        } else if (!enabled && root.ref.hopper) {\n            root.ref.hopper.destroy();\n            root.ref.hopper = null;\n            root.removeChildView(root.ref.drip);\n        }\n    };\n\n    /**\n     * Enable or disable browse functionality\n     */\n    var toggleBrowse = function toggleBrowse(root, props) {\n        var isAllowed = root.query('GET_ALLOW_BROWSE');\n        var isDisabled = root.query('GET_DISABLED');\n        var enabled = isAllowed && !isDisabled;\n        if (enabled && !root.ref.browser) {\n            root.ref.browser = root.appendChildView(\n                root.createChildView(\n                    browser,\n                    Object.assign({}, props, {\n                        onload: function onload(items) {\n                            applyFilterChain('ADD_ITEMS', items, {\n                                dispatch: root.dispatch,\n                            }).then(function(queue) {\n                                // these files don't fit so stop here\n                                if (exceedsMaxFiles(root, queue)) return false;\n\n                                // add items!\n                                root.dispatch('ADD_ITEMS', {\n                                    items: queue,\n                                    index: -1,\n                                    interactionMethod: InteractionMethod.BROWSE,\n                                });\n                            });\n                        },\n                    })\n                ),\n\n                0\n            );\n        } else if (!enabled && root.ref.browser) {\n            root.removeChildView(root.ref.browser);\n            root.ref.browser = null;\n        }\n    };\n\n    /**\n     * Enable or disable paste functionality\n     */\n    var togglePaste = function togglePaste(root) {\n        var isAllowed = root.query('GET_ALLOW_PASTE');\n        var isDisabled = root.query('GET_DISABLED');\n        var enabled = isAllowed && !isDisabled;\n        if (enabled && !root.ref.paster) {\n            root.ref.paster = createPaster();\n            root.ref.paster.onload = function(items) {\n                applyFilterChain('ADD_ITEMS', items, { dispatch: root.dispatch }).then(function(\n                    queue\n                ) {\n                    // these files don't fit so stop here\n                    if (exceedsMaxFiles(root, queue)) return false;\n\n                    // add items!\n                    root.dispatch('ADD_ITEMS', {\n                        items: queue,\n                        index: -1,\n                        interactionMethod: InteractionMethod.PASTE,\n                    });\n                });\n            };\n        } else if (!enabled && root.ref.paster) {\n            root.ref.paster.destroy();\n            root.ref.paster = null;\n        }\n    };\n\n    /**\n     * Route actions\n     */\n    var route$5 = createRoute({\n        DID_SET_ALLOW_BROWSE: function DID_SET_ALLOW_BROWSE(_ref5) {\n            var root = _ref5.root,\n                props = _ref5.props;\n            toggleBrowse(root, props);\n        },\n        DID_SET_ALLOW_DROP: function DID_SET_ALLOW_DROP(_ref6) {\n            var root = _ref6.root;\n            toggleDrop(root);\n        },\n        DID_SET_ALLOW_PASTE: function DID_SET_ALLOW_PASTE(_ref7) {\n            var root = _ref7.root;\n            togglePaste(root);\n        },\n        DID_SET_DISABLED: function DID_SET_DISABLED(_ref8) {\n            var root = _ref8.root,\n                props = _ref8.props;\n            toggleDrop(root);\n            togglePaste(root);\n            toggleBrowse(root, props);\n            var isDisabled = root.query('GET_DISABLED');\n            if (isDisabled) {\n                root.element.dataset.disabled = 'disabled';\n            } else {\n                // delete root.element.dataset.disabled; <= this does not work on iOS 10\n                root.element.removeAttribute('data-disabled');\n            }\n        },\n    });\n\n    var root = createView({\n        name: 'root',\n        read: function read(_ref9) {\n            var root = _ref9.root;\n            if (root.ref.measure) {\n                root.ref.measureHeight = root.ref.measure.offsetHeight;\n            }\n        },\n        create: create$e,\n        write: write$9,\n        destroy: function destroy(_ref10) {\n            var root = _ref10.root;\n            if (root.ref.paster) {\n                root.ref.paster.destroy();\n            }\n            if (root.ref.hopper) {\n                root.ref.hopper.destroy();\n            }\n            root.element.removeEventListener('touchmove', prevent);\n            root.element.removeEventListener('gesturestart', prevent);\n        },\n        mixins: {\n            styles: ['height'],\n        },\n    });\n\n    // creates the app\n    var createApp = function createApp() {\n        var initialOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n        // let element\n        var originalElement = null;\n\n        // get default options\n        var defaultOptions = getOptions();\n\n        // create the data store, this will contain all our app info\n        var store = createStore(\n            // initial state (should be serializable)\n            createInitialState(defaultOptions),\n\n            // queries\n            [queries, createOptionQueries(defaultOptions)],\n\n            // action handlers\n            [actions, createOptionActions(defaultOptions)]\n        );\n\n        // set initial options\n        store.dispatch('SET_OPTIONS', { options: initialOptions });\n\n        // kick thread if visibility changes\n        var visibilityHandler = function visibilityHandler() {\n            if (document.hidden) return;\n            store.dispatch('KICK');\n        };\n        document.addEventListener('visibilitychange', visibilityHandler);\n\n        // re-render on window resize start and finish\n        var resizeDoneTimer = null;\n        var isResizing = false;\n        var isResizingHorizontally = false;\n        var initialWindowWidth = null;\n        var currentWindowWidth = null;\n        var resizeHandler = function resizeHandler() {\n            if (!isResizing) {\n                isResizing = true;\n            }\n            clearTimeout(resizeDoneTimer);\n            resizeDoneTimer = setTimeout(function() {\n                isResizing = false;\n                initialWindowWidth = null;\n                currentWindowWidth = null;\n                if (isResizingHorizontally) {\n                    isResizingHorizontally = false;\n                    store.dispatch('DID_STOP_RESIZE');\n                }\n            }, 500);\n        };\n        window.addEventListener('resize', resizeHandler);\n\n        // render initial view\n        var view = root(store, { id: getUniqueId() });\n\n        //\n        // PRIVATE API -------------------------------------------------------------------------------------\n        //\n        var isResting = false;\n        var isHidden = false;\n\n        var readWriteApi = {\n            // necessary for update loop\n\n            /**\n             * Reads from dom (never call manually)\n             * @private\n             */\n            _read: function _read() {\n                // test if we're resizing horizontally\n                // TODO: see if we can optimize this by measuring root rect\n                if (isResizing) {\n                    currentWindowWidth = window.innerWidth;\n                    if (!initialWindowWidth) {\n                        initialWindowWidth = currentWindowWidth;\n                    }\n\n                    if (!isResizingHorizontally && currentWindowWidth !== initialWindowWidth) {\n                        store.dispatch('DID_START_RESIZE');\n                        isResizingHorizontally = true;\n                    }\n                }\n\n                if (isHidden && isResting) {\n                    // test if is no longer hidden\n                    isResting = view.element.offsetParent === null;\n                }\n\n                // if resting, no need to read as numbers will still all be correct\n                if (isResting) return;\n\n                // read view data\n                view._read();\n\n                // if is hidden we need to know so we exit rest mode when revealed\n                isHidden = view.rect.element.hidden;\n            },\n\n            /**\n             * Writes to dom (never call manually)\n             * @private\n             */\n            _write: function _write(ts) {\n                // get all actions from store\n                var actions = store\n                    .processActionQueue()\n\n                    // filter out set actions (these will automatically trigger DID_SET)\n                    .filter(function(action) {\n                        return !/^SET_/.test(action.type);\n                    });\n\n                // if was idling and no actions stop here\n                if (isResting && !actions.length) return;\n\n                // some actions might trigger events\n                routeActionsToEvents(actions);\n\n                // update the view\n                isResting = view._write(ts, actions, isResizingHorizontally);\n\n                // will clean up all archived items\n                removeReleasedItems(store.query('GET_ITEMS'));\n\n                // now idling\n                if (isResting) {\n                    store.processDispatchQueue();\n                }\n            },\n        };\n\n        //\n        // EXPOSE EVENTS -------------------------------------------------------------------------------------\n        //\n        var createEvent = function createEvent(name) {\n            return function(data) {\n                // create default event\n                var event = {\n                    type: name,\n                };\n\n                // no data to add\n                if (!data) {\n                    return event;\n                }\n\n                // copy relevant props\n                if (data.hasOwnProperty('error')) {\n                    event.error = data.error ? Object.assign({}, data.error) : null;\n                }\n\n                if (data.status) {\n                    event.status = Object.assign({}, data.status);\n                }\n\n                if (data.file) {\n                    event.output = data.file;\n                }\n\n                // only source is available, else add item if possible\n                if (data.source) {\n                    event.file = data.source;\n                } else if (data.item || data.id) {\n                    var item = data.item ? data.item : store.query('GET_ITEM', data.id);\n                    event.file = item ? createItemAPI(item) : null;\n                }\n\n                // map all items in a possible items array\n                if (data.items) {\n                    event.items = data.items.map(createItemAPI);\n                }\n\n                // if this is a progress event add the progress amount\n                if (/progress/.test(name)) {\n                    event.progress = data.progress;\n                }\n\n                // copy relevant props\n                if (data.hasOwnProperty('origin') && data.hasOwnProperty('target')) {\n                    event.origin = data.origin;\n                    event.target = data.target;\n                }\n\n                return event;\n            };\n        };\n\n        var eventRoutes = {\n            DID_DESTROY: createEvent('destroy'),\n\n            DID_INIT: createEvent('init'),\n\n            DID_THROW_MAX_FILES: createEvent('warning'),\n\n            DID_INIT_ITEM: createEvent('initfile'),\n            DID_START_ITEM_LOAD: createEvent('addfilestart'),\n            DID_UPDATE_ITEM_LOAD_PROGRESS: createEvent('addfileprogress'),\n            DID_LOAD_ITEM: createEvent('addfile'),\n\n            DID_THROW_ITEM_INVALID: [createEvent('error'), createEvent('addfile')],\n\n            DID_THROW_ITEM_LOAD_ERROR: [createEvent('error'), createEvent('addfile')],\n\n            DID_THROW_ITEM_REMOVE_ERROR: [createEvent('error'), createEvent('removefile')],\n\n            DID_PREPARE_OUTPUT: createEvent('preparefile'),\n\n            DID_START_ITEM_PROCESSING: createEvent('processfilestart'),\n            DID_UPDATE_ITEM_PROCESS_PROGRESS: createEvent('processfileprogress'),\n            DID_ABORT_ITEM_PROCESSING: createEvent('processfileabort'),\n            DID_COMPLETE_ITEM_PROCESSING: createEvent('processfile'),\n            DID_COMPLETE_ITEM_PROCESSING_ALL: createEvent('processfiles'),\n            DID_REVERT_ITEM_PROCESSING: createEvent('processfilerevert'),\n\n            DID_THROW_ITEM_PROCESSING_ERROR: [createEvent('error'), createEvent('processfile')],\n\n            DID_REMOVE_ITEM: createEvent('removefile'),\n\n            DID_UPDATE_ITEMS: createEvent('updatefiles'),\n\n            DID_ACTIVATE_ITEM: createEvent('activatefile'),\n\n            DID_REORDER_ITEMS: createEvent('reorderfiles'),\n        };\n\n        var exposeEvent = function exposeEvent(event) {\n            // create event object to be dispatched\n            var detail = Object.assign({ pond: exports }, event);\n            delete detail.type;\n            view.element.dispatchEvent(\n                new CustomEvent('FilePond:' + event.type, {\n                    // event info\n                    detail: detail,\n\n                    // event behaviour\n                    bubbles: true,\n                    cancelable: true,\n                    composed: true, // triggers listeners outside of shadow root\n                })\n            );\n\n            // event object to params used for `on()` event handlers and callbacks `oninit()`\n            var params = [];\n\n            // if is possible error event, make it the first param\n            if (event.hasOwnProperty('error')) {\n                params.push(event.error);\n            }\n\n            // file is always section\n            if (event.hasOwnProperty('file')) {\n                params.push(event.file);\n            }\n\n            // append other props\n            var filtered = ['type', 'error', 'file'];\n            Object.keys(event)\n                .filter(function(key) {\n                    return !filtered.includes(key);\n                })\n                .forEach(function(key) {\n                    return params.push(event[key]);\n                });\n\n            // on(type, () => { })\n            exports.fire.apply(exports, [event.type].concat(params));\n\n            // oninit = () => {}\n            var handler = store.query('GET_ON' + event.type.toUpperCase());\n            if (handler) {\n                handler.apply(void 0, params);\n            }\n        };\n\n        var routeActionsToEvents = function routeActionsToEvents(actions) {\n            if (!actions.length) return;\n            actions\n                .filter(function(action) {\n                    return eventRoutes[action.type];\n                })\n                .forEach(function(action) {\n                    var routes = eventRoutes[action.type];\n                    (Array.isArray(routes) ? routes : [routes]).forEach(function(route) {\n                        // this isn't fantastic, but because of the stacking of settimeouts plugins can handle the did_load before the did_init\n                        if (action.type === 'DID_INIT_ITEM') {\n                            exposeEvent(route(action.data));\n                        } else {\n                            setTimeout(function() {\n                                exposeEvent(route(action.data));\n                            }, 0);\n                        }\n                    });\n                });\n        };\n\n        //\n        // PUBLIC API -------------------------------------------------------------------------------------\n        //\n        var setOptions = function setOptions(options) {\n            return store.dispatch('SET_OPTIONS', { options: options });\n        };\n\n        var getFile = function getFile(query) {\n            return store.query('GET_ACTIVE_ITEM', query);\n        };\n\n        var prepareFile = function prepareFile(query) {\n            return new Promise(function(resolve, reject) {\n                store.dispatch('REQUEST_ITEM_PREPARE', {\n                    query: query,\n                    success: function success(item) {\n                        resolve(item);\n                    },\n                    failure: function failure(error) {\n                        reject(error);\n                    },\n                });\n            });\n        };\n\n        var addFile = function addFile(source) {\n            var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n            return new Promise(function(resolve, reject) {\n                addFiles([{ source: source, options: options }], { index: options.index })\n                    .then(function(items) {\n                        return resolve(items && items[0]);\n                    })\n                    .catch(reject);\n            });\n        };\n\n        var isFilePondFile = function isFilePondFile(obj) {\n            return obj.file && obj.id;\n        };\n\n        var removeFile = function removeFile(query, options) {\n            // if only passed options\n            if (typeof query === 'object' && !isFilePondFile(query) && !options) {\n                options = query;\n                query = undefined;\n            }\n\n            // request item removal\n            store.dispatch('REMOVE_ITEM', Object.assign({}, options, { query: query }));\n\n            // see if item has been removed\n            return store.query('GET_ACTIVE_ITEM', query) === null;\n        };\n\n        var addFiles = function addFiles() {\n            for (\n                var _len = arguments.length, args = new Array(_len), _key = 0;\n                _key < _len;\n                _key++\n            ) {\n                args[_key] = arguments[_key];\n            }\n            return new Promise(function(resolve, reject) {\n                var sources = [];\n                var options = {};\n\n                // user passed a sources array\n                if (isArray(args[0])) {\n                    sources.push.apply(sources, args[0]);\n                    Object.assign(options, args[1] || {});\n                } else {\n                    // user passed sources as arguments, last one might be options object\n                    var lastArgument = args[args.length - 1];\n                    if (typeof lastArgument === 'object' && !(lastArgument instanceof Blob)) {\n                        Object.assign(options, args.pop());\n                    }\n\n                    // add rest to sources\n                    sources.push.apply(sources, args);\n                }\n\n                store.dispatch('ADD_ITEMS', {\n                    items: sources,\n                    index: options.index,\n                    interactionMethod: InteractionMethod.API,\n                    success: resolve,\n                    failure: reject,\n                });\n            });\n        };\n\n        var getFiles = function getFiles() {\n            return store.query('GET_ACTIVE_ITEMS');\n        };\n\n        var processFile = function processFile(query) {\n            return new Promise(function(resolve, reject) {\n                store.dispatch('REQUEST_ITEM_PROCESSING', {\n                    query: query,\n                    success: function success(item) {\n                        resolve(item);\n                    },\n                    failure: function failure(error) {\n                        reject(error);\n                    },\n                });\n            });\n        };\n\n        var prepareFiles = function prepareFiles() {\n            for (\n                var _len2 = arguments.length, args = new Array(_len2), _key2 = 0;\n                _key2 < _len2;\n                _key2++\n            ) {\n                args[_key2] = arguments[_key2];\n            }\n            var queries = Array.isArray(args[0]) ? args[0] : args;\n            var items = queries.length ? queries : getFiles();\n            return Promise.all(items.map(prepareFile));\n        };\n\n        var processFiles = function processFiles() {\n            for (\n                var _len3 = arguments.length, args = new Array(_len3), _key3 = 0;\n                _key3 < _len3;\n                _key3++\n            ) {\n                args[_key3] = arguments[_key3];\n            }\n            var queries = Array.isArray(args[0]) ? args[0] : args;\n            if (!queries.length) {\n                var files = getFiles().filter(function(item) {\n                    return (\n                        !(item.status === ItemStatus.IDLE && item.origin === FileOrigin.LOCAL) &&\n                        item.status !== ItemStatus.PROCESSING &&\n                        item.status !== ItemStatus.PROCESSING_COMPLETE &&\n                        item.status !== ItemStatus.PROCESSING_REVERT_ERROR\n                    );\n                });\n\n                return Promise.all(files.map(processFile));\n            }\n            return Promise.all(queries.map(processFile));\n        };\n\n        var removeFiles = function removeFiles() {\n            for (\n                var _len4 = arguments.length, args = new Array(_len4), _key4 = 0;\n                _key4 < _len4;\n                _key4++\n            ) {\n                args[_key4] = arguments[_key4];\n            }\n\n            var queries = Array.isArray(args[0]) ? args[0] : args;\n\n            var options;\n            if (typeof queries[queries.length - 1] === 'object') {\n                options = queries.pop();\n            } else if (Array.isArray(args[0])) {\n                options = args[1];\n            }\n\n            var files = getFiles();\n\n            if (!queries.length)\n                return Promise.all(\n                    files.map(function(file) {\n                        return removeFile(file, options);\n                    })\n                );\n\n            // when removing by index the indexes shift after each file removal so we need to convert indexes to ids\n            var mappedQueries = queries\n                .map(function(query) {\n                    return isNumber(query) ? (files[query] ? files[query].id : null) : query;\n                })\n                .filter(function(query) {\n                    return query;\n                });\n\n            return mappedQueries.map(function(q) {\n                return removeFile(q, options);\n            });\n        };\n\n        var exports = Object.assign(\n            {},\n\n            on(),\n            {},\n\n            readWriteApi,\n            {},\n\n            createOptionAPI(store, defaultOptions),\n            {\n                /**\n                 * Override options defined in options object\n                 * @param options\n                 */\n                setOptions: setOptions,\n\n                /**\n                 * Load the given file\n                 * @param source - the source of the file (either a File, base64 data uri or url)\n                 * @param options - object, { index: 0 }\n                 */\n                addFile: addFile,\n\n                /**\n                 * Load the given files\n                 * @param sources - the sources of the files to load\n                 * @param options - object, { index: 0 }\n                 */\n                addFiles: addFiles,\n\n                /**\n                 * Returns the file objects matching the given query\n                 * @param query { string, number, null }\n                 */\n                getFile: getFile,\n\n                /**\n                 * Upload file with given name\n                 * @param query { string, number, null  }\n                 */\n                processFile: processFile,\n\n                /**\n                 * Request prepare output for file with given name\n                 * @param query { string, number, null  }\n                 */\n                prepareFile: prepareFile,\n\n                /**\n                 * Removes a file by its name\n                 * @param query { string, number, null  }\n                 */\n                removeFile: removeFile,\n\n                /**\n                 * Moves a file to a new location in the files list\n                 */\n                moveFile: function moveFile(query, index) {\n                    return store.dispatch('MOVE_ITEM', { query: query, index: index });\n                },\n\n                /**\n                 * Returns all files (wrapped in public api)\n                 */\n                getFiles: getFiles,\n\n                /**\n                 * Starts uploading all files\n                 */\n                processFiles: processFiles,\n\n                /**\n                 * Clears all files from the files list\n                 */\n                removeFiles: removeFiles,\n\n                /**\n                 * Starts preparing output of all files\n                 */\n                prepareFiles: prepareFiles,\n\n                /**\n                 * Sort list of files\n                 */\n                sort: function sort(compare) {\n                    return store.dispatch('SORT', { compare: compare });\n                },\n\n                /**\n                 * Browse the file system for a file\n                 */\n                browse: function browse() {\n                    // needs to be trigger directly as user action needs to be traceable (is not traceable in requestAnimationFrame)\n                    var input = view.element.querySelector('input[type=file]');\n                    if (input) {\n                        input.click();\n                    }\n                },\n\n                /**\n                 * Destroys the app\n                 */\n                destroy: function destroy() {\n                    // request destruction\n                    exports.fire('destroy', view.element);\n\n                    // stop active processes (file uploads, fetches, stuff like that)\n                    // loop over items and depending on states call abort for ongoing processes\n                    store.dispatch('ABORT_ALL');\n\n                    // destroy view\n                    view._destroy();\n\n                    // stop listening to resize\n                    window.removeEventListener('resize', resizeHandler);\n\n                    // stop listening to the visiblitychange event\n                    document.removeEventListener('visibilitychange', visibilityHandler);\n\n                    // dispatch destroy\n                    store.dispatch('DID_DESTROY');\n                },\n\n                /**\n                 * Inserts the plugin before the target element\n                 */\n                insertBefore: function insertBefore$1(element) {\n                    return insertBefore(view.element, element);\n                },\n\n                /**\n                 * Inserts the plugin after the target element\n                 */\n                insertAfter: function insertAfter$1(element) {\n                    return insertAfter(view.element, element);\n                },\n\n                /**\n                 * Appends the plugin to the target element\n                 */\n                appendTo: function appendTo(element) {\n                    return element.appendChild(view.element);\n                },\n\n                /**\n                 * Replaces an element with the app\n                 */\n                replaceElement: function replaceElement(element) {\n                    // insert the app before the element\n                    insertBefore(view.element, element);\n\n                    // remove the original element\n                    element.parentNode.removeChild(element);\n\n                    // remember original element\n                    originalElement = element;\n                },\n\n                /**\n                 * Restores the original element\n                 */\n                restoreElement: function restoreElement() {\n                    if (!originalElement) {\n                        return; // no element to restore\n                    }\n\n                    // restore original element\n                    insertAfter(originalElement, view.element);\n\n                    // remove our element\n                    view.element.parentNode.removeChild(view.element);\n\n                    // remove reference\n                    originalElement = null;\n                },\n\n                /**\n                 * Returns true if the app root is attached to given element\n                 * @param element\n                 */\n                isAttachedTo: function isAttachedTo(element) {\n                    return view.element === element || originalElement === element;\n                },\n\n                /**\n                 * Returns the root element\n                 */\n                element: {\n                    get: function get() {\n                        return view.element;\n                    },\n                },\n\n                /**\n                 * Returns the current pond status\n                 */\n                status: {\n                    get: function get() {\n                        return store.query('GET_STATUS');\n                    },\n                },\n            }\n        );\n\n        // Done!\n        store.dispatch('DID_INIT');\n\n        // create actual api object\n        return createObject(exports);\n    };\n\n    var createAppObject = function createAppObject() {\n        var customOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n        // default options\n        var defaultOptions = {};\n        forin(getOptions(), function(key, value) {\n            defaultOptions[key] = value[0];\n        });\n\n        // set app options\n        var app = createApp(\n            Object.assign(\n                {},\n\n                defaultOptions,\n                {},\n\n                customOptions\n            )\n        );\n\n        // return the plugin instance\n        return app;\n    };\n\n    var lowerCaseFirstLetter = function lowerCaseFirstLetter(string) {\n        return string.charAt(0).toLowerCase() + string.slice(1);\n    };\n\n    var attributeNameToPropertyName = function attributeNameToPropertyName(attributeName) {\n        return toCamels(attributeName.replace(/^data-/, ''));\n    };\n\n    var mapObject = function mapObject(object, propertyMap) {\n        // remove unwanted\n        forin(propertyMap, function(selector, mapping) {\n            forin(object, function(property, value) {\n                // create regexp shortcut\n                var selectorRegExp = new RegExp(selector);\n\n                // tests if\n                var matches = selectorRegExp.test(property);\n\n                // no match, skip\n                if (!matches) {\n                    return;\n                }\n\n                // if there's a mapping, the original property is always removed\n                delete object[property];\n\n                // should only remove, we done!\n                if (mapping === false) {\n                    return;\n                }\n\n                // move value to new property\n                if (isString(mapping)) {\n                    object[mapping] = value;\n                    return;\n                }\n\n                // move to group\n                var group = mapping.group;\n                if (isObject(mapping) && !object[group]) {\n                    object[group] = {};\n                }\n\n                object[group][lowerCaseFirstLetter(property.replace(selectorRegExp, ''))] = value;\n            });\n\n            // do submapping\n            if (mapping.mapping) {\n                mapObject(object[mapping.group], mapping.mapping);\n            }\n        });\n    };\n\n    var getAttributesAsObject = function getAttributesAsObject(node) {\n        var attributeMapping =\n            arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n        // turn attributes into object\n        var attributes = [];\n        forin(node.attributes, function(index) {\n            attributes.push(node.attributes[index]);\n        });\n\n        var output = attributes\n            .filter(function(attribute) {\n                return attribute.name;\n            })\n            .reduce(function(obj, attribute) {\n                var value = attr(node, attribute.name);\n\n                obj[attributeNameToPropertyName(attribute.name)] =\n                    value === attribute.name ? true : value;\n                return obj;\n            }, {});\n\n        // do mapping of object properties\n        mapObject(output, attributeMapping);\n\n        return output;\n    };\n\n    var createAppAtElement = function createAppAtElement(element) {\n        var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n        // how attributes of the input element are mapped to the options for the plugin\n        var attributeMapping = {\n            // translate to other name\n            '^class$': 'className',\n            '^multiple$': 'allowMultiple',\n            '^capture$': 'captureMethod',\n            '^webkitdirectory$': 'allowDirectoriesOnly',\n\n            // group under single property\n            '^server': {\n                group: 'server',\n                mapping: {\n                    '^process': {\n                        group: 'process',\n                    },\n\n                    '^revert': {\n                        group: 'revert',\n                    },\n\n                    '^fetch': {\n                        group: 'fetch',\n                    },\n\n                    '^restore': {\n                        group: 'restore',\n                    },\n\n                    '^load': {\n                        group: 'load',\n                    },\n                },\n            },\n\n            // don't include in object\n            '^type$': false,\n            '^files$': false,\n        };\n\n        // add additional option translators\n        applyFilters('SET_ATTRIBUTE_TO_OPTION_MAP', attributeMapping);\n\n        // create final options object by setting options object and then overriding options supplied on element\n        var mergedOptions = Object.assign({}, options);\n\n        var attributeOptions = getAttributesAsObject(\n            element.nodeName === 'FIELDSET' ? element.querySelector('input[type=file]') : element,\n            attributeMapping\n        );\n\n        // merge with options object\n        Object.keys(attributeOptions).forEach(function(key) {\n            if (isObject(attributeOptions[key])) {\n                if (!isObject(mergedOptions[key])) {\n                    mergedOptions[key] = {};\n                }\n                Object.assign(mergedOptions[key], attributeOptions[key]);\n            } else {\n                mergedOptions[key] = attributeOptions[key];\n            }\n        });\n\n        // if parent is a fieldset, get files from parent by selecting all input fields that are not file upload fields\n        // these will then be automatically set to the initial files\n        mergedOptions.files = (options.files || []).concat(\n            Array.from(element.querySelectorAll('input:not([type=file])')).map(function(input) {\n                return {\n                    source: input.value,\n                    options: {\n                        type: input.dataset.type,\n                    },\n                };\n            })\n        );\n\n        // build plugin\n        var app = createAppObject(mergedOptions);\n\n        // add already selected files\n        if (element.files) {\n            Array.from(element.files).forEach(function(file) {\n                app.addFile(file);\n            });\n        }\n\n        // replace the target element\n        app.replaceElement(element);\n\n        // expose\n        return app;\n    };\n\n    // if an element is passed, we create the instance at that element, if not, we just create an up object\n    var createApp$1 = function createApp() {\n        return isNode(arguments.length <= 0 ? undefined : arguments[0])\n            ? createAppAtElement.apply(void 0, arguments)\n            : createAppObject.apply(void 0, arguments);\n    };\n\n    var PRIVATE_METHODS = ['fire', '_read', '_write'];\n\n    var createAppAPI = function createAppAPI(app) {\n        var api = {};\n\n        copyObjectPropertiesToObject(app, api, PRIVATE_METHODS);\n\n        return api;\n    };\n\n    /**\n     * Replaces placeholders in given string with replacements\n     * @param string - \"Foo {bar}\"\"\n     * @param replacements - { \"bar\": 10 }\n     */\n    var replaceInString = function replaceInString(string, replacements) {\n        return string.replace(/(?:{([a-zA-Z]+)})/g, function(match, group) {\n            return replacements[group];\n        });\n    };\n\n    var createWorker = function createWorker(fn) {\n        var workerBlob = new Blob(['(', fn.toString(), ')()'], {\n            type: 'application/javascript',\n        });\n\n        var workerURL = URL.createObjectURL(workerBlob);\n        var worker = new Worker(workerURL);\n\n        return {\n            transfer: function transfer(message, cb) {},\n            post: function post(message, cb, transferList) {\n                var id = getUniqueId();\n\n                worker.onmessage = function(e) {\n                    if (e.data.id === id) {\n                        cb(e.data.message);\n                    }\n                };\n\n                worker.postMessage(\n                    {\n                        id: id,\n                        message: message,\n                    },\n\n                    transferList\n                );\n            },\n            terminate: function terminate() {\n                worker.terminate();\n                URL.revokeObjectURL(workerURL);\n            },\n        };\n    };\n\n    var loadImage = function loadImage(url) {\n        return new Promise(function(resolve, reject) {\n            var img = new Image();\n            img.onload = function() {\n                resolve(img);\n            };\n            img.onerror = function(e) {\n                reject(e);\n            };\n            img.src = url;\n        });\n    };\n\n    var renameFile = function renameFile(file, name) {\n        var renamedFile = file.slice(0, file.size, file.type);\n        renamedFile.lastModifiedDate = file.lastModifiedDate;\n        renamedFile.name = name;\n        return renamedFile;\n    };\n\n    var copyFile = function copyFile(file) {\n        return renameFile(file, file.name);\n    };\n\n    // already registered plugins (can't register twice)\n    var registeredPlugins = [];\n\n    // pass utils to plugin\n    var createAppPlugin = function createAppPlugin(plugin) {\n        // already registered\n        if (registeredPlugins.includes(plugin)) {\n            return;\n        }\n\n        // remember this plugin\n        registeredPlugins.push(plugin);\n\n        // setup!\n        var pluginOutline = plugin({\n            addFilter: addFilter,\n            utils: {\n                Type: Type,\n                forin: forin,\n                isString: isString,\n                isFile: isFile,\n                toNaturalFileSize: toNaturalFileSize,\n                replaceInString: replaceInString,\n                getExtensionFromFilename: getExtensionFromFilename,\n                getFilenameWithoutExtension: getFilenameWithoutExtension,\n                guesstimateMimeType: guesstimateMimeType,\n                getFileFromBlob: getFileFromBlob,\n                getFilenameFromURL: getFilenameFromURL,\n                createRoute: createRoute,\n                createWorker: createWorker,\n                createView: createView,\n                createItemAPI: createItemAPI,\n                loadImage: loadImage,\n                copyFile: copyFile,\n                renameFile: renameFile,\n                createBlob: createBlob,\n                applyFilterChain: applyFilterChain,\n                text: text,\n                getNumericAspectRatioFromString: getNumericAspectRatioFromString,\n            },\n\n            views: {\n                fileActionButton: fileActionButton,\n            },\n        });\n\n        // add plugin options to default options\n        extendDefaultOptions(pluginOutline.options);\n    };\n\n    // feature detection used by supported() method\n    var isOperaMini = function isOperaMini() {\n        return Object.prototype.toString.call(window.operamini) === '[object OperaMini]';\n    };\n    var hasPromises = function hasPromises() {\n        return 'Promise' in window;\n    };\n    var hasBlobSlice = function hasBlobSlice() {\n        return 'slice' in Blob.prototype;\n    };\n    var hasCreateObjectURL = function hasCreateObjectURL() {\n        return 'URL' in window && 'createObjectURL' in window.URL;\n    };\n    var hasVisibility = function hasVisibility() {\n        return 'visibilityState' in document;\n    };\n    var hasTiming = function hasTiming() {\n        return 'performance' in window;\n    }; // iOS 8.x\n    var hasCSSSupports = function hasCSSSupports() {\n        return 'supports' in (window.CSS || {});\n    }; // use to detect Safari 9+\n    var isIE11 = function isIE11() {\n        return /MSIE|Trident/.test(window.navigator.userAgent);\n    };\n\n    var supported = (function() {\n        // Runs immediately and then remembers result for subsequent calls\n        var isSupported =\n            // Has to be a browser\n            isBrowser() &&\n            // Can't run on Opera Mini due to lack of everything\n            !isOperaMini() &&\n            // Require these APIs to feature detect a modern browser\n            hasVisibility() &&\n            hasPromises() &&\n            hasBlobSlice() &&\n            hasCreateObjectURL() &&\n            hasTiming() &&\n            // doesn't need CSSSupports but is a good way to detect Safari 9+ (we do want to support IE11 though)\n            (hasCSSSupports() || isIE11());\n\n        return function() {\n            return isSupported;\n        };\n    })();\n\n    /**\n     * Plugin internal state (over all instances)\n     */\n    var state = {\n        // active app instances, used to redraw the apps and to find the later\n        apps: [],\n    };\n\n    // plugin name\n    var name = 'filepond';\n\n    /**\n     * Public Plugin methods\n     */\n    var fn = function fn() {};\n    exports.Status = {};\n    exports.FileStatus = {};\n    exports.FileOrigin = {};\n    exports.OptionTypes = {};\n    exports.create = fn;\n    exports.destroy = fn;\n    exports.parse = fn;\n    exports.find = fn;\n    exports.registerPlugin = fn;\n    exports.getOptions = fn;\n    exports.setOptions = fn;\n\n    // if not supported, no API\n    if (supported()) {\n        // start painter and fire load event\n        createPainter(\n            function() {\n                state.apps.forEach(function(app) {\n                    return app._read();\n                });\n            },\n            function(ts) {\n                state.apps.forEach(function(app) {\n                    return app._write(ts);\n                });\n            }\n        );\n\n        // fire loaded event so we know when FilePond is available\n        var dispatch = function dispatch() {\n            // let others know we have area ready\n            document.dispatchEvent(\n                new CustomEvent('FilePond:loaded', {\n                    detail: {\n                        supported: supported,\n                        create: exports.create,\n                        destroy: exports.destroy,\n                        parse: exports.parse,\n                        find: exports.find,\n                        registerPlugin: exports.registerPlugin,\n                        setOptions: exports.setOptions,\n                    },\n                })\n            );\n\n            // clean up event\n            document.removeEventListener('DOMContentLoaded', dispatch);\n        };\n\n        if (document.readyState !== 'loading') {\n            // move to back of execution queue, FilePond should have been exported by then\n            setTimeout(function() {\n                return dispatch();\n            }, 0);\n        } else {\n            document.addEventListener('DOMContentLoaded', dispatch);\n        }\n\n        // updates the OptionTypes object based on the current options\n        var updateOptionTypes = function updateOptionTypes() {\n            return forin(getOptions(), function(key, value) {\n                exports.OptionTypes[key] = value[1];\n            });\n        };\n\n        exports.Status = Object.assign({}, Status);\n        exports.FileOrigin = Object.assign({}, FileOrigin);\n        exports.FileStatus = Object.assign({}, ItemStatus);\n\n        exports.OptionTypes = {};\n        updateOptionTypes();\n\n        // create method, creates apps and adds them to the app array\n        exports.create = function create() {\n            var app = createApp$1.apply(void 0, arguments);\n            app.on('destroy', exports.destroy);\n            state.apps.push(app);\n            return createAppAPI(app);\n        };\n\n        // destroys apps and removes them from the app array\n        exports.destroy = function destroy(hook) {\n            // returns true if the app was destroyed successfully\n            var indexToRemove = state.apps.findIndex(function(app) {\n                return app.isAttachedTo(hook);\n            });\n            if (indexToRemove >= 0) {\n                // remove from apps\n                var app = state.apps.splice(indexToRemove, 1)[0];\n\n                // restore original dom element\n                app.restoreElement();\n\n                return true;\n            }\n\n            return false;\n        };\n\n        // parses the given context for plugins (does not include the context element itself)\n        exports.parse = function parse(context) {\n            // get all possible hooks\n            var matchedHooks = Array.from(context.querySelectorAll('.' + name));\n\n            // filter out already active hooks\n            var newHooks = matchedHooks.filter(function(newHook) {\n                return !state.apps.find(function(app) {\n                    return app.isAttachedTo(newHook);\n                });\n            });\n\n            // create new instance for each hook\n            return newHooks.map(function(hook) {\n                return exports.create(hook);\n            });\n        };\n\n        // returns an app based on the given element hook\n        exports.find = function find(hook) {\n            var app = state.apps.find(function(app) {\n                return app.isAttachedTo(hook);\n            });\n            if (!app) {\n                return null;\n            }\n            return createAppAPI(app);\n        };\n\n        // adds a plugin extension\n        exports.registerPlugin = function registerPlugin() {\n            for (\n                var _len = arguments.length, plugins = new Array(_len), _key = 0;\n                _key < _len;\n                _key++\n            ) {\n                plugins[_key] = arguments[_key];\n            }\n\n            // register plugins\n            plugins.forEach(createAppPlugin);\n\n            // update OptionTypes, each plugin might have extended the default options\n            updateOptionTypes();\n        };\n\n        exports.getOptions = function getOptions$1() {\n            var opts = {};\n            forin(getOptions(), function(key, value) {\n                opts[key] = value[0];\n            });\n            return opts;\n        };\n\n        exports.setOptions = function setOptions$1(opts) {\n            if (isObject(opts)) {\n                // update existing plugins\n                state.apps.forEach(function(app) {\n                    app.setOptions(opts);\n                });\n\n                // override defaults\n                setOptions(opts);\n            }\n\n            // return new options\n            return exports.getOptions();\n        };\n    }\n\n    exports.supported = supported;\n\n    Object.defineProperty(exports, '__esModule', { value: true });\n});\n", "/*!\n * FilePondPluginFileValidateSize 2.2.8\n * Licensed under MIT, https://opensource.org/licenses/MIT/\n * Please visit https://pqina.nl/filepond/ for details.\n */\n\n/* eslint-disable */\n\n(function(global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined'\n        ? (module.exports = factory())\n        : typeof define === 'function' && define.amd\n        ? define(factory)\n        : ((global = global || self), (global.FilePondPluginFileValidateSize = factory()));\n})(this, function() {\n    'use strict';\n\n    var plugin = function plugin(_ref) {\n        var addFilter = _ref.addFilter,\n            utils = _ref.utils;\n        // get quick reference to Type utils\n        var Type = utils.Type,\n            replaceInString = utils.replaceInString,\n            toNaturalFileSize = utils.toNaturalFileSize;\n\n        // filtering if an item is allowed in hopper\n        addFilter('ALLOW_HOPPER_ITEM', function(file, _ref2) {\n            var query = _ref2.query;\n            if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) {\n                return true;\n            }\n\n            var sizeMax = query('GET_MAX_FILE_SIZE');\n            if (sizeMax !== null && file.size > sizeMax) {\n                return false;\n            }\n\n            var sizeMin = query('GET_MIN_FILE_SIZE');\n            if (sizeMin !== null && file.size < sizeMin) {\n                return false;\n            }\n\n            return true;\n        });\n\n        // called for each file that is loaded\n        // right before it is set to the item state\n        // should return a promise\n        addFilter('LOAD_FILE', function(file, _ref3) {\n            var query = _ref3.query;\n            return new Promise(function(resolve, reject) {\n                // if not allowed, all fine, exit\n                if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) {\n                    return resolve(file);\n                }\n\n                // check if file should be filtered\n                var fileFilter = query('GET_FILE_VALIDATE_SIZE_FILTER');\n                if (fileFilter && !fileFilter(file)) {\n                    return resolve(file);\n                }\n\n                // reject or resolve based on file size\n                var sizeMax = query('GET_MAX_FILE_SIZE');\n                if (sizeMax !== null && file.size > sizeMax) {\n                    reject({\n                        status: {\n                            main: query('GET_LABEL_MAX_FILE_SIZE_EXCEEDED'),\n                            sub: replaceInString(query('GET_LABEL_MAX_FILE_SIZE'), {\n                                filesize: toNaturalFileSize(\n                                    sizeMax,\n                                    '.',\n                                    query('GET_FILE_SIZE_BASE'),\n                                    query('GET_FILE_SIZE_LABELS', query)\n                                ),\n                            }),\n                        },\n                    });\n\n                    return;\n                }\n\n                // reject or resolve based on file size\n                var sizeMin = query('GET_MIN_FILE_SIZE');\n                if (sizeMin !== null && file.size < sizeMin) {\n                    reject({\n                        status: {\n                            main: query('GET_LABEL_MIN_FILE_SIZE_EXCEEDED'),\n                            sub: replaceInString(query('GET_LABEL_MIN_FILE_SIZE'), {\n                                filesize: toNaturalFileSize(\n                                    sizeMin,\n                                    '.',\n                                    query('GET_FILE_SIZE_BASE'),\n                                    query('GET_FILE_SIZE_LABELS', query)\n                                ),\n                            }),\n                        },\n                    });\n\n                    return;\n                }\n\n                // returns the current option value\n                var totalSizeMax = query('GET_MAX_TOTAL_FILE_SIZE');\n                if (totalSizeMax !== null) {\n                    // get the current total file size\n                    var currentTotalSize = query('GET_ACTIVE_ITEMS').reduce(function(total, item) {\n                        return total + item.fileSize;\n                    }, 0);\n\n                    // get the size of the new file\n                    if (currentTotalSize > totalSizeMax) {\n                        reject({\n                            status: {\n                                main: query('GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED'),\n                                sub: replaceInString(query('GET_LABEL_MAX_TOTAL_FILE_SIZE'), {\n                                    filesize: toNaturalFileSize(\n                                        totalSizeMax,\n                                        '.',\n                                        query('GET_FILE_SIZE_BASE'),\n                                        query('GET_FILE_SIZE_LABELS', query)\n                                    ),\n                                }),\n                            },\n                        });\n\n                        return;\n                    }\n                }\n\n                // file is fine, let's pass it back\n                resolve(file);\n            });\n        });\n\n        return {\n            options: {\n                // Enable or disable file type validation\n                allowFileSizeValidation: [true, Type.BOOLEAN],\n\n                // Max individual file size in bytes\n                maxFileSize: [null, Type.INT],\n\n                // Min individual file size in bytes\n                minFileSize: [null, Type.INT],\n\n                // Max total file size in bytes\n                maxTotalFileSize: [null, Type.INT],\n\n                // Filter the files that need to be validated for size\n                fileValidateSizeFilter: [null, Type.FUNCTION],\n\n                // error labels\n                labelMinFileSizeExceeded: ['File is too small', Type.STRING],\n                labelMinFileSize: ['Minimum file size is {filesize}', Type.STRING],\n\n                labelMaxFileSizeExceeded: ['File is too large', Type.STRING],\n                labelMaxFileSize: ['Maximum file size is {filesize}', Type.STRING],\n\n                labelMaxTotalFileSizeExceeded: ['Maximum total size exceeded', Type.STRING],\n                labelMaxTotalFileSize: ['Maximum total file size is {filesize}', Type.STRING],\n            },\n        };\n    };\n\n    // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags\n    var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n    if (isBrowser) {\n        document.dispatchEvent(new CustomEvent('FilePond:pluginloaded', { detail: plugin }));\n    }\n\n    return plugin;\n});\n", "/*!\n * FilePondPluginFileValidateType 1.2.9\n * Licensed under MIT, https://opensource.org/licenses/MIT/\n * Please visit https://pqina.nl/filepond/ for details.\n */\n\n/* eslint-disable */\n\n(function(global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined'\n        ? (module.exports = factory())\n        : typeof define === 'function' && define.amd\n        ? define(factory)\n        : ((global = global || self), (global.FilePondPluginFileValidateType = factory()));\n})(this, function() {\n    'use strict';\n\n    var plugin = function plugin(_ref) {\n        var addFilter = _ref.addFilter,\n            utils = _ref.utils;\n        // get quick reference to Type utils\n        var Type = utils.Type,\n            isString = utils.isString,\n            replaceInString = utils.replaceInString,\n            guesstimateMimeType = utils.guesstimateMimeType,\n            getExtensionFromFilename = utils.getExtensionFromFilename,\n            getFilenameFromURL = utils.getFilenameFromURL;\n\n        var mimeTypeMatchesWildCard = function mimeTypeMatchesWildCard(mimeType, wildcard) {\n            var mimeTypeGroup = (/^[^/]+/.exec(mimeType) || []).pop(); // image/png -> image\n            var wildcardGroup = wildcard.slice(0, -2); // image/* -> image\n            return mimeTypeGroup === wildcardGroup;\n        };\n\n        var isValidMimeType = function isValidMimeType(acceptedTypes, userInputType) {\n            return acceptedTypes.some(function(acceptedType) {\n                // accepted is wildcard mime type\n                if (/\\*$/.test(acceptedType)) {\n                    return mimeTypeMatchesWildCard(userInputType, acceptedType);\n                }\n\n                // is normal mime type\n                return acceptedType === userInputType;\n            });\n        };\n\n        var getItemType = function getItemType(item) {\n            // if the item is a url we guess the mime type by the extension\n            var type = '';\n            if (isString(item)) {\n                var filename = getFilenameFromURL(item);\n                var extension = getExtensionFromFilename(filename);\n                if (extension) {\n                    type = guesstimateMimeType(extension);\n                }\n            } else {\n                type = item.type;\n            }\n\n            return type;\n        };\n\n        var validateFile = function validateFile(item, acceptedFileTypes, typeDetector) {\n            // no types defined, everything is allowed \\o/\n            if (acceptedFileTypes.length === 0) {\n                return true;\n            }\n\n            // gets the item type\n            var type = getItemType(item);\n\n            // no type detector, test now\n            if (!typeDetector) {\n                return isValidMimeType(acceptedFileTypes, type);\n            }\n\n            // use type detector\n            return new Promise(function(resolve, reject) {\n                typeDetector(item, type)\n                    .then(function(detectedType) {\n                        if (isValidMimeType(acceptedFileTypes, detectedType)) {\n                            resolve();\n                        } else {\n                            reject();\n                        }\n                    })\n                    .catch(reject);\n            });\n        };\n\n        var applyMimeTypeMap = function applyMimeTypeMap(map) {\n            return function(acceptedFileType) {\n                return map[acceptedFileType] === null\n                    ? false\n                    : map[acceptedFileType] || acceptedFileType;\n            };\n        };\n\n        // setup attribute mapping for accept\n        addFilter('SET_ATTRIBUTE_TO_OPTION_MAP', function(map) {\n            return Object.assign(map, {\n                accept: 'acceptedFileTypes',\n            });\n        });\n\n        // filtering if an item is allowed in hopper\n        addFilter('ALLOW_HOPPER_ITEM', function(file, _ref2) {\n            var query = _ref2.query;\n            // if we are not doing file type validation exit\n            if (!query('GET_ALLOW_FILE_TYPE_VALIDATION')) {\n                return true;\n            }\n\n            // we validate the file against the accepted file types\n            return validateFile(file, query('GET_ACCEPTED_FILE_TYPES'));\n        });\n\n        // called for each file that is loaded\n        // right before it is set to the item state\n        // should return a promise\n        addFilter('LOAD_FILE', function(file, _ref3) {\n            var query = _ref3.query;\n            return new Promise(function(resolve, reject) {\n                if (!query('GET_ALLOW_FILE_TYPE_VALIDATION')) {\n                    resolve(file);\n                    return;\n                }\n\n                var acceptedFileTypes = query('GET_ACCEPTED_FILE_TYPES');\n\n                // custom type detector method\n                var typeDetector = query('GET_FILE_VALIDATE_TYPE_DETECT_TYPE');\n\n                // if invalid, exit here\n                var validationResult = validateFile(file, acceptedFileTypes, typeDetector);\n\n                var handleRejection = function handleRejection() {\n                    var acceptedFileTypesMapped = acceptedFileTypes\n                        .map(\n                            applyMimeTypeMap(\n                                query('GET_FILE_VALIDATE_TYPE_LABEL_EXPECTED_TYPES_MAP')\n                            )\n                        )\n                        .filter(function(label) {\n                            return label !== false;\n                        });\n\n                    var acceptedFileTypesMappedUnique = acceptedFileTypesMapped.filter(function(\n                        item,\n                        index\n                    ) {\n                        return acceptedFileTypesMapped.indexOf(item) === index;\n                    });\n\n                    reject({\n                        status: {\n                            main: query('GET_LABEL_FILE_TYPE_NOT_ALLOWED'),\n                            sub: replaceInString(\n                                query('GET_FILE_VALIDATE_TYPE_LABEL_EXPECTED_TYPES'),\n                                {\n                                    allTypes: acceptedFileTypesMappedUnique.join(', '),\n                                    allButLastType: acceptedFileTypesMappedUnique\n                                        .slice(0, -1)\n                                        .join(', '),\n                                    lastType:\n                                        acceptedFileTypesMappedUnique[\n                                            acceptedFileTypesMappedUnique.length - 1\n                                        ],\n                                }\n                            ),\n                        },\n                    });\n                };\n\n                // has returned new filename immidiately\n                if (typeof validationResult === 'boolean') {\n                    if (!validationResult) {\n                        return handleRejection();\n                    }\n                    return resolve(file);\n                }\n\n                // is promise\n                validationResult\n                    .then(function() {\n                        resolve(file);\n                    })\n                    .catch(handleRejection);\n            });\n        });\n\n        // expose plugin\n        return {\n            // default options\n            options: {\n                // Enable or disable file type validation\n                allowFileTypeValidation: [true, Type.BOOLEAN],\n\n                // What file types to accept\n                acceptedFileTypes: [[], Type.ARRAY],\n                // - must be comma separated\n                // - mime types: image/png, image/jpeg, image/gif\n                // - extensions: .png, .jpg, .jpeg ( not enabled yet )\n                // - wildcards: image/*\n\n                // label to show when a type is not allowed\n                labelFileTypeNotAllowed: ['File is of invalid type', Type.STRING],\n\n                // nicer label\n                fileValidateTypeLabelExpectedTypes: [\n                    'Expects {allButLastType} or {lastType}',\n                    Type.STRING,\n                ],\n\n                // map mime types to extensions\n                fileValidateTypeLabelExpectedTypesMap: [{}, Type.OBJECT],\n\n                // Custom function to detect type of file\n                fileValidateTypeDetectType: [null, Type.FUNCTION],\n            },\n        };\n    };\n\n    // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags\n    var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n    if (isBrowser) {\n        document.dispatchEvent(new CustomEvent('FilePond:pluginloaded', { detail: plugin }));\n    }\n\n    return plugin;\n});\n", "/*!\n * FilePondPluginFilePoster 2.5.2\n * Licensed under MIT, https://opensource.org/licenses/MIT/\n * Please visit https://pqina.nl/filepond/ for details.\n */\n\n/* eslint-disable */\n\n(function(global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined'\n    ? (module.exports = factory())\n    : typeof define === 'function' && define.amd\n    ? define(factory)\n    : ((global = global || self),\n      (global.FilePondPluginFilePoster = factory()));\n})(this, function() {\n  'use strict';\n\n  var IMAGE_SCALE_SPRING_PROPS = {\n    type: 'spring',\n    stiffness: 0.5,\n    damping: 0.45,\n    mass: 10\n  };\n\n  var createPosterView = function createPosterView(_) {\n    return _.utils.createView({\n      name: 'file-poster',\n      tag: 'div',\n      ignoreRect: true,\n      create: function create(_ref) {\n        var root = _ref.root;\n        root.ref.image = document.createElement('img');\n        root.element.appendChild(root.ref.image);\n      },\n      write: _.utils.createRoute({\n        DID_FILE_POSTER_LOAD: function DID_FILE_POSTER_LOAD(_ref2) {\n          var root = _ref2.root,\n            props = _ref2.props;\n          var id = props.id;\n\n          // get item\n          var item = root.query('GET_ITEM', { id: props.id });\n          if (!item) return;\n\n          // get poster\n          var poster = item.getMetadata('poster');\n          root.ref.image.src = poster;\n\n          // let others know of our fabulous achievement (so the image can be faded in)\n          root.dispatch('DID_FILE_POSTER_DRAW', { id: id });\n        }\n      }),\n\n      mixins: {\n        styles: ['scaleX', 'scaleY', 'opacity'],\n        animations: {\n          scaleX: IMAGE_SCALE_SPRING_PROPS,\n          scaleY: IMAGE_SCALE_SPRING_PROPS,\n          opacity: { type: 'tween', duration: 750 }\n        }\n      }\n    });\n  };\n\n  var applyTemplate = function applyTemplate(source, target) {\n    // copy width and height\n    target.width = source.width;\n    target.height = source.height;\n\n    // draw the template\n    var ctx = target.getContext('2d');\n    ctx.drawImage(source, 0, 0);\n  };\n\n  var createPosterOverlayView = function createPosterOverlayView(fpAPI) {\n    return fpAPI.utils.createView({\n      name: 'file-poster-overlay',\n      tag: 'canvas',\n      ignoreRect: true,\n      create: function create(_ref) {\n        var root = _ref.root,\n          props = _ref.props;\n        applyTemplate(props.template, root.element);\n      },\n      mixins: {\n        styles: ['opacity'],\n        animations: {\n          opacity: { type: 'spring', mass: 25 }\n        }\n      }\n    });\n  };\n\n  var getImageSize = function getImageSize(url, cb) {\n    var image = new Image();\n    image.onload = function() {\n      var width = image.naturalWidth;\n      var height = image.naturalHeight;\n      image = null;\n      cb(width, height);\n    };\n    image.src = url;\n  };\n\n  var easeInOutSine = function easeInOutSine(t) {\n    return -0.5 * (Math.cos(Math.PI * t) - 1);\n  };\n\n  var addGradientSteps = function addGradientSteps(gradient, color) {\n    var alpha =\n      arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n    var easeFn =\n      arguments.length > 3 && arguments[3] !== undefined\n        ? arguments[3]\n        : easeInOutSine;\n    var steps =\n      arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 10;\n    var offset =\n      arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;\n    var range = 1 - offset;\n    var rgb = color.join(',');\n    for (var i = 0; i <= steps; i++) {\n      var p = i / steps;\n      var stop = offset + range * p;\n      gradient.addColorStop(\n        stop,\n        'rgba('.concat(rgb, ', ').concat(easeFn(p) * alpha, ')')\n      );\n    }\n  };\n\n  var MAX_WIDTH = 10;\n  var MAX_HEIGHT = 10;\n\n  var calculateAverageColor = function calculateAverageColor(image) {\n    var scalar = Math.min(MAX_WIDTH / image.width, MAX_HEIGHT / image.height);\n\n    var canvas = document.createElement('canvas');\n    var ctx = canvas.getContext('2d');\n    var width = (canvas.width = Math.ceil(image.width * scalar));\n    var height = (canvas.height = Math.ceil(image.height * scalar));\n    ctx.drawImage(image, 0, 0, width, height);\n    var data = null;\n    try {\n      data = ctx.getImageData(0, 0, width, height).data;\n    } catch (e) {\n      return null;\n    }\n    var l = data.length;\n\n    var r = 0;\n    var g = 0;\n    var b = 0;\n    var i = 0;\n\n    for (; i < l; i += 4) {\n      r += data[i] * data[i];\n      g += data[i + 1] * data[i + 1];\n      b += data[i + 2] * data[i + 2];\n    }\n\n    r = averageColor(r, l);\n    g = averageColor(g, l);\n    b = averageColor(b, l);\n\n    return { r: r, g: g, b: b };\n  };\n\n  var averageColor = function averageColor(c, l) {\n    return Math.floor(Math.sqrt(c / (l / 4)));\n  };\n\n  var drawTemplate = function drawTemplate(\n    canvas,\n    width,\n    height,\n    color,\n    alphaTarget\n  ) {\n    canvas.width = width;\n    canvas.height = height;\n    var ctx = canvas.getContext('2d');\n\n    var horizontalCenter = width * 0.5;\n\n    var grad = ctx.createRadialGradient(\n      horizontalCenter,\n      height + 110,\n      height - 100,\n      horizontalCenter,\n      height + 110,\n      height + 100\n    );\n\n    addGradientSteps(grad, color, alphaTarget, undefined, 8, 0.4);\n\n    ctx.save();\n    ctx.translate(-width * 0.5, 0);\n    ctx.scale(2, 1);\n    ctx.fillStyle = grad;\n    ctx.fillRect(0, 0, width, height);\n    ctx.restore();\n  };\n\n  var hasNavigator = typeof navigator !== 'undefined';\n  var hasDocument = typeof document !== 'undefined';\n\n  var width = 500;\n  var height = 200;\n\n  var overlayTemplateShadow =\n    hasNavigator && hasDocument && document.createElement('canvas');\n  var overlayTemplateError =\n    hasNavigator && hasDocument && document.createElement('canvas');\n  var overlayTemplateSuccess =\n    hasNavigator && hasDocument && document.createElement('canvas');\n\n  var itemShadowColor = [40, 40, 40];\n  var itemErrorColor = [196, 78, 71];\n  var itemSuccessColor = [54, 151, 99];\n\n  if (hasNavigator && hasDocument) {\n    drawTemplate(overlayTemplateShadow, width, height, itemShadowColor, 0.85);\n    drawTemplate(overlayTemplateError, width, height, itemErrorColor, 1);\n    drawTemplate(overlayTemplateSuccess, width, height, itemSuccessColor, 1);\n  }\n\n  var loadImage = function loadImage(url, crossOriginValue) {\n    return new Promise(function(resolve, reject) {\n      var img = new Image();\n      if (typeof crossOrigin === 'string') {\n        img.crossOrigin = crossOriginValue;\n      }\n      img.onload = function() {\n        resolve(img);\n      };\n      img.onerror = function(e) {\n        reject(e);\n      };\n      img.src = url;\n    });\n  };\n\n  var createPosterWrapperView = function createPosterWrapperView(_) {\n    // create overlay view\n    var overlay = createPosterOverlayView(_);\n\n    /**\n     * Write handler for when preview container has been created\n     */\n    var didCreatePreviewContainer = function didCreatePreviewContainer(_ref) {\n      var root = _ref.root,\n        props = _ref.props;\n      var id = props.id;\n\n      // we need to get the file data to determine the eventual image size\n      var item = root.query('GET_ITEM', id);\n      if (!item) return;\n\n      // get url to file\n      var fileURL = item.getMetadata('poster');\n\n      // image is now ready\n      var previewImageLoaded = function previewImageLoaded(data) {\n        // calculate average image color, is in try catch to circumvent any cors errors\n        var averageColor = root.query(\n          'GET_FILE_POSTER_CALCULATE_AVERAGE_IMAGE_COLOR'\n        )\n          ? calculateAverageColor(data)\n          : null;\n        item.setMetadata('color', averageColor, true);\n\n        // the preview is now ready to be drawn\n        root.dispatch('DID_FILE_POSTER_LOAD', {\n          id: id,\n          data: data\n        });\n      };\n\n      // determine image size of this item\n      getImageSize(fileURL, function(width, height) {\n        // we can now scale the panel to the final size\n        root.dispatch('DID_FILE_POSTER_CALCULATE_SIZE', {\n          id: id,\n          width: width,\n          height: height\n        });\n\n        // create fallback preview\n        loadImage(\n          fileURL,\n          root.query('GET_FILE_POSTER_CROSS_ORIGIN_ATTRIBUTE_VALUE')\n        ).then(previewImageLoaded);\n      });\n    };\n\n    /**\n     * Write handler for when the preview has been loaded\n     */\n    var didLoadPreview = function didLoadPreview(_ref2) {\n      var root = _ref2.root;\n      root.ref.overlayShadow.opacity = 1;\n    };\n\n    /**\n     * Write handler for when the preview image is ready to be animated\n     */\n    var didDrawPreview = function didDrawPreview(_ref3) {\n      var root = _ref3.root;\n      var image = root.ref.image;\n\n      // reveal image\n      image.scaleX = 1.0;\n      image.scaleY = 1.0;\n      image.opacity = 1;\n    };\n\n    /**\n     * Write handler for when the preview has been loaded\n     */\n    var restoreOverlay = function restoreOverlay(_ref4) {\n      var root = _ref4.root;\n      root.ref.overlayShadow.opacity = 1;\n      root.ref.overlayError.opacity = 0;\n      root.ref.overlaySuccess.opacity = 0;\n    };\n\n    var didThrowError = function didThrowError(_ref5) {\n      var root = _ref5.root;\n      root.ref.overlayShadow.opacity = 0.25;\n      root.ref.overlayError.opacity = 1;\n    };\n\n    var didCompleteProcessing = function didCompleteProcessing(_ref6) {\n      var root = _ref6.root;\n      root.ref.overlayShadow.opacity = 0.25;\n      root.ref.overlaySuccess.opacity = 1;\n    };\n\n    /**\n     * Constructor\n     */\n    var create = function create(_ref7) {\n      var root = _ref7.root,\n        props = _ref7.props;\n      // test if colors aren't default item overlay colors\n      var itemShadowColorProp = root.query(\n        'GET_FILE_POSTER_ITEM_OVERLAY_SHADOW_COLOR'\n      );\n\n      var itemErrorColorProp = root.query(\n        'GET_FILE_POSTER_ITEM_OVERLAY_ERROR_COLOR'\n      );\n\n      var itemSuccessColorProp = root.query(\n        'GET_FILE_POSTER_ITEM_OVERLAY_SUCCESS_COLOR'\n      );\n\n      if (itemShadowColorProp && itemShadowColorProp !== itemShadowColor) {\n        itemShadowColor = itemShadowColorProp;\n        drawTemplate(\n          overlayTemplateShadow,\n          width,\n          height,\n          itemShadowColor,\n          0.85\n        );\n      }\n      if (itemErrorColorProp && itemErrorColorProp !== itemErrorColor) {\n        itemErrorColor = itemErrorColorProp;\n        drawTemplate(overlayTemplateError, width, height, itemErrorColor, 1);\n      }\n      if (itemSuccessColorProp && itemSuccessColorProp !== itemSuccessColor) {\n        itemSuccessColor = itemSuccessColorProp;\n        drawTemplate(\n          overlayTemplateSuccess,\n          width,\n          height,\n          itemSuccessColor,\n          1\n        );\n      }\n\n      // image view\n      var image = createPosterView(_);\n\n      // append image presenter\n      root.ref.image = root.appendChildView(\n        root.createChildView(image, {\n          id: props.id,\n          scaleX: 1.25,\n          scaleY: 1.25,\n          opacity: 0\n        })\n      );\n\n      // image overlays\n      root.ref.overlayShadow = root.appendChildView(\n        root.createChildView(overlay, {\n          template: overlayTemplateShadow,\n          opacity: 0\n        })\n      );\n\n      root.ref.overlaySuccess = root.appendChildView(\n        root.createChildView(overlay, {\n          template: overlayTemplateSuccess,\n          opacity: 0\n        })\n      );\n\n      root.ref.overlayError = root.appendChildView(\n        root.createChildView(overlay, {\n          template: overlayTemplateError,\n          opacity: 0\n        })\n      );\n    };\n\n    return _.utils.createView({\n      name: 'file-poster-wrapper',\n      create: create,\n      write: _.utils.createRoute({\n        // image preview stated\n        DID_FILE_POSTER_LOAD: didLoadPreview,\n        DID_FILE_POSTER_DRAW: didDrawPreview,\n        DID_FILE_POSTER_CONTAINER_CREATE: didCreatePreviewContainer,\n\n        // file states\n        DID_THROW_ITEM_LOAD_ERROR: didThrowError,\n        DID_THROW_ITEM_PROCESSING_ERROR: didThrowError,\n        DID_THROW_ITEM_INVALID: didThrowError,\n        DID_COMPLETE_ITEM_PROCESSING: didCompleteProcessing,\n        DID_START_ITEM_PROCESSING: restoreOverlay,\n        DID_REVERT_ITEM_PROCESSING: restoreOverlay\n      })\n    });\n  };\n\n  /**\n   * File Poster Plugin\n   */\n  var plugin = function plugin(fpAPI) {\n    var addFilter = fpAPI.addFilter,\n      utils = fpAPI.utils;\n    var Type = utils.Type,\n      createRoute = utils.createRoute;\n\n    // filePosterView\n    var filePosterView = createPosterWrapperView(fpAPI);\n\n    // called for each view that is created right after the 'create' method\n    addFilter('CREATE_VIEW', function(viewAPI) {\n      // get reference to created view\n      var is = viewAPI.is,\n        view = viewAPI.view,\n        query = viewAPI.query;\n\n      // only hook up to item view and only if is enabled for this cropper\n      if (!is('file') || !query('GET_ALLOW_FILE_POSTER')) return;\n\n      // create the file poster plugin, but only do so if the item is an image\n      var didLoadItem = function didLoadItem(_ref) {\n        var root = _ref.root,\n          props = _ref.props;\n        updateItemPoster(root, props);\n      };\n\n      var didUpdateItemMetadata = function didUpdateItemMetadata(_ref2) {\n        var root = _ref2.root,\n          props = _ref2.props,\n          action = _ref2.action;\n        if (!/poster/.test(action.change.key)) return;\n        updateItemPoster(root, props);\n      };\n\n      var updateItemPoster = function updateItemPoster(root, props) {\n        var id = props.id;\n        var item = query('GET_ITEM', id);\n\n        // item could theoretically have been removed in the mean time\n        if (!item || !item.getMetadata('poster') || item.archived) return;\n\n        // don't update if is the same poster\n        if (root.ref.previousPoster === item.getMetadata('poster')) return;\n        root.ref.previousPoster = item.getMetadata('poster');\n\n        // test if is filtered\n        if (!query('GET_FILE_POSTER_FILTER_ITEM')(item)) return;\n\n        if (root.ref.filePoster) {\n          view.removeChildView(root.ref.filePoster);\n        }\n\n        // set preview view\n        root.ref.filePoster = view.appendChildView(\n          view.createChildView(filePosterView, { id: id })\n        );\n\n        // now ready\n        root.dispatch('DID_FILE_POSTER_CONTAINER_CREATE', { id: id });\n      };\n\n      var didCalculatePreviewSize = function didCalculatePreviewSize(_ref3) {\n        var root = _ref3.root,\n          action = _ref3.action;\n        // no poster set\n        if (!root.ref.filePoster) return;\n\n        // remember dimensions\n        root.ref.imageWidth = action.width;\n        root.ref.imageHeight = action.height;\n\n        root.ref.shouldUpdatePanelHeight = true;\n\n        root.dispatch('KICK');\n      };\n\n      var getPosterHeight = function getPosterHeight(_ref4) {\n        var root = _ref4.root;\n        var fixedPosterHeight = root.query('GET_FILE_POSTER_HEIGHT');\n\n        // if fixed height: return fixed immediately\n        if (fixedPosterHeight) {\n          return fixedPosterHeight;\n        }\n\n        var minPosterHeight = root.query('GET_FILE_POSTER_MIN_HEIGHT');\n        var maxPosterHeight = root.query('GET_FILE_POSTER_MAX_HEIGHT');\n\n        // if natural height is smaller than minHeight: return min height\n        if (minPosterHeight && root.ref.imageHeight < minPosterHeight) {\n          return minPosterHeight;\n        }\n\n        var height =\n          root.rect.element.width *\n          (root.ref.imageHeight / root.ref.imageWidth);\n\n        if (minPosterHeight && height < minPosterHeight) {\n          return minPosterHeight;\n        }\n        if (maxPosterHeight && height > maxPosterHeight) {\n          return maxPosterHeight;\n        }\n\n        return height;\n      };\n\n      // start writing\n      view.registerWriter(\n        createRoute(\n          {\n            DID_LOAD_ITEM: didLoadItem,\n            DID_FILE_POSTER_CALCULATE_SIZE: didCalculatePreviewSize,\n            DID_UPDATE_ITEM_METADATA: didUpdateItemMetadata\n          },\n\n          function(_ref5) {\n            var root = _ref5.root,\n              props = _ref5.props;\n            // don't run without poster\n            if (!root.ref.filePoster) return;\n\n            // don't do anything while hidden\n            if (root.rect.element.hidden) return;\n\n            // should we redraw\n            if (root.ref.shouldUpdatePanelHeight) {\n              // time to resize the parent panel\n              root.dispatch('DID_UPDATE_PANEL_HEIGHT', {\n                id: props.id,\n                height: getPosterHeight({ root: root })\n              });\n\n              // done!\n              root.ref.shouldUpdatePanelHeight = false;\n            }\n          }\n        )\n      );\n    });\n\n    // expose plugin\n    return {\n      options: {\n        // Enable or disable file poster\n        allowFilePoster: [true, Type.BOOLEAN],\n\n        // Fixed preview height\n        filePosterHeight: [null, Type.INT],\n\n        // Min image height\n        filePosterMinHeight: [null, Type.INT],\n\n        // Max image height\n        filePosterMaxHeight: [null, Type.INT],\n\n        // filters file items to determine which are shown as poster\n        filePosterFilterItem: [\n          function() {\n            return true;\n          },\n          Type.FUNCTION\n        ],\n\n        // Enables or disables reading average image color\n        filePosterCalculateAverageImageColor: [false, Type.BOOLEAN],\n\n        // Allows setting the value of the CORS attribute (null is don't set attribute)\n        filePosterCrossOriginAttributeValue: ['Anonymous', Type.STRING],\n\n        // Colors used for item overlay gradient\n        filePosterItemOverlayShadowColor: [null, Type.ARRAY],\n        filePosterItemOverlayErrorColor: [null, Type.ARRAY],\n        filePosterItemOverlaySuccessColor: [null, Type.ARRAY]\n      }\n    };\n  };\n\n  // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags\n  var isBrowser =\n    typeof window !== 'undefined' && typeof window.document !== 'undefined';\n  if (isBrowser) {\n    document.dispatchEvent(\n      new CustomEvent('FilePond:pluginloaded', { detail: plugin })\n    );\n  }\n\n  return plugin;\n});\n", "export { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, addBreadcrumb, addEventProcessor, addIntegration, addTracingExtensions, captureConsoleIntegration, captureEvent, captureException, captureFeedback, captureMessage, captureSession, close, continueTrace, createTransport, debugIntegration, dedupeIntegration, endSession, extraErrorDataIntegration, flush, functionToStringIntegration, getActiveSpan, getClient, getCurrentHub, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, getSpanDescendants, getSpanStatusFromHttpCode, inboundFiltersIntegration, isInitialized, lastEventId, makeMultiplexedTransport, moduleMetadataIntegration, parameterize, registerSpanErrorInstrumentation, rewriteFramesIntegration, sessionTimingIntegration, setContext, setCurrentClient, setExtra, setExtras, setHttpStatus, setMeasurement, setTag, setTags, setUser, spanToBaggageHeader, spanToJSON, spanToTraceHeader, startInactiveSpan, startNewTrace, startSession, startSpan, startSpanManual, suppressTracing, thirdPartyErrorFilterIntegration, updateSpanName, withActiveSpan, withIsolationScope, withScope, zodErrorsIntegration } from '@sentry/core';\nexport { WINDOW } from './helpers.js';\nexport { BrowserClient } from './client.js';\nexport { makeFetchTransport } from './transports/fetch.js';\nexport { chromeStackLineParser, defaultStackLineParsers, defaultStackParser, geckoStackLineParser, opera10StackLineParser, opera11StackLineParser, winjsStackLineParser } from './stack-parsers.js';\nexport { eventFromException, eventFromMessage, exceptionFromError } from './eventbuilder.js';\nexport { createUserFeedbackEnvelope } from './userfeedback.js';\nexport { captureUserFeedback, forceLoad, getDefaultIntegrations, init, onLoad, showReportDialog } from './sdk.js';\nexport { breadcrumbsIntegration } from './integrations/breadcrumbs.js';\nexport { globalHandlersIntegration } from './integrations/globalhandlers.js';\nexport { httpContextIntegration } from './integrations/httpcontext.js';\nexport { linkedErrorsIntegration } from './integrations/linkederrors.js';\nexport { browserApiErrorsIntegration } from './integrations/browserapierrors.js';\nexport { lazyLoadIntegration } from './utils/lazyLoadIntegration.js';\nexport { reportingObserverIntegration } from './integrations/reportingobserver.js';\nexport { httpClientIntegration } from './integrations/httpclient.js';\nexport { contextLinesIntegration } from './integrations/contextlines.js';\nexport { getReplay, replayIntegration } from '@sentry-internal/replay';\nexport { replayCanvasIntegration } from '@sentry-internal/replay-canvas';\nexport { feedbackAsyncIntegration } from './feedbackAsync.js';\nexport { feedbackSyncIntegration as feedbackIntegration, feedbackSyncIntegration } from './feedbackSync.js';\nexport { getFeedback, sendFeedback } from '@sentry-internal/feedback';\nexport { metrics } from './metrics.js';\nexport { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './tracing/request.js';\nexport { browserTracingIntegration, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan } from './tracing/browserTracingIntegration.js';\nexport { makeBrowserOfflineTransport } from './transports/offline.js';\nexport { browserProfilingIntegration } from './profiling/integration.js';\nexport { spotlightBrowserIntegration } from './integrations/spotlight.js';\nexport { browserSessionIntegration } from './integrations/browsersession.js';\nexport { featureFlagsIntegration } from './integrations/featureFlags/featureFlagsIntegration.js';\nexport { buildLaunchDarklyFlagUsedHandler, launchDarklyIntegration } from './integrations/featureFlags/launchdarkly/integration.js';\nexport { OpenFeatureIntegrationHook, openFeatureIntegration } from './integrations/featureFlags/openfeature/integration.js';\nexport { unleashIntegration } from './integrations/featureFlags/unleash/integration.js';\nexport { statsigIntegration } from './integrations/featureFlags/statsig/integration.js';\n//# sourceMappingURL=index.js.map\n", "declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n", "// This is a magic string replaced by rollup\ndeclare const __SENTRY_SDK_VERSION__: string;\n\nexport const SDK_VERSION = typeof __SENTRY_SDK_VERSION__ === 'string' ? __SENTRY_SDK_VERSION__ : '0.0.0-unknown.0';\n", "/**\n * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,\n * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.\n *\n * Note: This file was originally called `global.ts`, but was changed to unblock users which might be doing\n * string replaces with bundlers like Vite for `global` (would break imports that rely on importing from utils/src/global).\n *\n * Why worldwide?\n *\n * Why not?\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Client, MetricsAggregator, Scope } from '../types-hoist';\n\nimport type { SdkSource } from './env';\nimport type { logger } from './logger';\nimport { SDK_VERSION } from './version';\n\ninterface SentryCarrier {\n  acs?: any;\n  stack?: any;\n\n  globalScope?: Scope;\n  defaultIsolationScope?: Scope;\n  defaultCurrentScope?: Scope;\n  globalMetricsAggregators?: WeakMap<Client, MetricsAggregator> | undefined;\n  logger?: typeof logger;\n\n  /** Overwrites TextEncoder used in `@sentry/core`, need for `react-native@0.73` and older */\n  encodePolyfill?: (input: string) => Uint8Array;\n  /** Overwrites TextDecoder used in `@sentry/core`, need for `react-native@0.73` and older */\n  decodePolyfill?: (input: Uint8Array) => string;\n}\n\n// TODO(v9): Clean up or remove this type\ntype BackwardsCompatibleSentryCarrier = SentryCarrier & {\n  // pre-v7 hub (replaced by .stack)\n  hub: any;\n  integrations?: any[];\n  logger: any;\n  extensions?: {\n    /** Extension methods for the hub, which are bound to the current Hub instance */\n    // eslint-disable-next-line @typescript-eslint/ban-types\n    [key: string]: Function;\n  };\n};\n\n/** Internal global with common properties and Sentry extensions  */\nexport type InternalGlobal = {\n  navigator?: { userAgent?: string; maxTouchPoints?: number };\n  console: Console;\n  PerformanceObserver?: any;\n  Sentry?: any;\n  onerror?: {\n    (event: object | string, source?: string, lineno?: number, colno?: number, error?: Error): any;\n    __SENTRY_INSTRUMENTED__?: true;\n  };\n  onunhandledrejection?: {\n    (event: unknown): boolean;\n    __SENTRY_INSTRUMENTED__?: true;\n  };\n  SENTRY_ENVIRONMENT?: string;\n  SENTRY_DSN?: string;\n  SENTRY_RELEASE?: {\n    id?: string;\n  };\n  SENTRY_SDK_SOURCE?: SdkSource;\n  /**\n   * Debug IDs are indirectly injected by Sentry CLI or bundler plugins to directly reference a particular source map\n   * for resolving of a source file. The injected code will place an entry into the record for each loaded bundle/JS\n   * file.\n   */\n  _sentryDebugIds?: Record<string, string>;\n  __SENTRY__: Record<Exclude<string, 'version'>, SentryCarrier> & {\n    version?: string;\n  } & BackwardsCompatibleSentryCarrier;\n  /**\n   * Raw module metadata that is injected by bundler plugins.\n   *\n   * Keys are `error.stack` strings, values are the metadata.\n   */\n  _sentryModuleMetadata?: Record<string, any>;\n  _sentryEsmLoaderHookRegistered?: boolean;\n};\n\n/** Get's the global object for the current JavaScript runtime */\nexport const GLOBAL_OBJ = globalThis as unknown as InternalGlobal;\n\n/**\n * Returns a global singleton contained in the global `__SENTRY__[]` object.\n *\n * If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory\n * function and added to the `__SENTRY__` object.\n *\n * @param name name of the global singleton on __SENTRY__\n * @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`\n * @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value\n * @returns the singleton\n */\nexport function getGlobalSingleton<T>(name: keyof SentryCarrier, creator: () => T, obj?: unknown): T {\n  const gbl = (obj || GLOBAL_OBJ) as InternalGlobal;\n  const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});\n  const versionedCarrier = (__SENTRY__[SDK_VERSION] = __SENTRY__[SDK_VERSION] || {});\n  return versionedCarrier[name] || (versionedCarrier[name] = creator());\n}\n", "declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n", "import type { ConsoleLevel } from '../types-hoist';\n\nimport { DEBUG_BUILD } from './debug-build';\nimport { GLOBAL_OBJ, getGlobalSingleton } from './worldwide';\n\n/** Prefix for logging strings */\nconst PREFIX = 'Sentry Logger ';\n\nexport const CONSOLE_LEVELS: readonly ConsoleLevel[] = [\n  'debug',\n  'info',\n  'warn',\n  'error',\n  'log',\n  'assert',\n  'trace',\n] as const;\n\ntype LoggerMethod = (...args: unknown[]) => void;\ntype LoggerConsoleMethods = Record<ConsoleLevel, LoggerMethod>;\n\n/** This may be mutated by the console instrumentation. */\nexport const originalConsoleMethods: {\n  [key in ConsoleLevel]?: (...args: unknown[]) => void;\n} = {};\n\n/** JSDoc */\nexport interface Logger extends LoggerConsoleMethods {\n  disable(): void;\n  enable(): void;\n  isEnabled(): boolean;\n}\n\n/**\n * Temporarily disable sentry console instrumentations.\n *\n * @param callback The function to run against the original `console` messages\n * @returns The results of the callback\n */\nexport function consoleSandbox<T>(callback: () => T): T {\n  if (!('console' in GLOBAL_OBJ)) {\n    return callback();\n  }\n\n  const console = GLOBAL_OBJ.console as Console;\n  const wrappedFuncs: Partial<LoggerConsoleMethods> = {};\n\n  const wrappedLevels = Object.keys(originalConsoleMethods) as ConsoleLevel[];\n\n  // Restore all wrapped console methods\n  wrappedLevels.forEach(level => {\n    const originalConsoleMethod = originalConsoleMethods[level] as LoggerMethod;\n    wrappedFuncs[level] = console[level] as LoggerMethod | undefined;\n    console[level] = originalConsoleMethod;\n  });\n\n  try {\n    return callback();\n  } finally {\n    // Revert restoration to wrapped state\n    wrappedLevels.forEach(level => {\n      console[level] = wrappedFuncs[level] as LoggerMethod;\n    });\n  }\n}\n\nfunction makeLogger(): Logger {\n  let enabled = false;\n  const logger: Partial<Logger> = {\n    enable: () => {\n      enabled = true;\n    },\n    disable: () => {\n      enabled = false;\n    },\n    isEnabled: () => enabled,\n  };\n\n  if (DEBUG_BUILD) {\n    CONSOLE_LEVELS.forEach(name => {\n      logger[name] = (...args: Parameters<(typeof GLOBAL_OBJ.console)[typeof name]>) => {\n        if (enabled) {\n          consoleSandbox(() => {\n            GLOBAL_OBJ.console[name](`${PREFIX}[${name}]:`, ...args);\n          });\n        }\n      };\n    });\n  } else {\n    CONSOLE_LEVELS.forEach(name => {\n      logger[name] = () => undefined;\n    });\n  }\n\n  return logger as Logger;\n}\n\n/**\n * This is a logger singleton which either logs things or no-ops if logging is not enabled.\n * The logger is a singleton on the carrier, to ensure that a consistent logger is used throughout the SDK.\n */\nexport const logger = getGlobalSingleton('logger', makeLogger);\n", "import type { Event, StackFrame, StackLineParser, StackParser } from '../types-hoist';\n\nconst STACKTRACE_FRAME_LIMIT = 50;\nexport const UNKNOWN_FUNCTION = '?';\n// Used to sanitize webpack (error: *) wrapped stack errors\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STRIP_FRAME_REGEXP = /captureMessage|captureException/;\n\n/**\n * Creates a stack parser with the supplied line parsers\n *\n * StackFrames are returned in the correct order for Sentry Exception\n * frames and with Sentry SDK internal frames removed from the top and bottom\n *\n */\nexport function createStackParser(...parsers: StackLineParser[]): StackParser {\n  const sortedParsers = parsers.sort((a, b) => a[0] - b[0]).map(p => p[1]);\n\n  return (stack: string, skipFirstLines: number = 0, framesToPop: number = 0): StackFrame[] => {\n    const frames: StackFrame[] = [];\n    const lines = stack.split('\\n');\n\n    for (let i = skipFirstLines; i < lines.length; i++) {\n      const line = lines[i] as string;\n      // Ignore lines over 1kb as they are unlikely to be stack frames.\n      // Many of the regular expressions use backtracking which results in run time that increases exponentially with\n      // input size. Huge strings can result in hangs/Denial of Service:\n      // https://github.com/getsentry/sentry-javascript/issues/2286\n      if (line.length > 1024) {\n        continue;\n      }\n\n      // https://github.com/getsentry/sentry-javascript/issues/5459\n      // Remove webpack (error: *) wrappers\n      const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n\n      // https://github.com/getsentry/sentry-javascript/issues/7813\n      // Skip Error: lines\n      if (cleanedLine.match(/\\S*Error: /)) {\n        continue;\n      }\n\n      for (const parser of sortedParsers) {\n        const frame = parser(cleanedLine);\n\n        if (frame) {\n          frames.push(frame);\n          break;\n        }\n      }\n\n      if (frames.length >= STACKTRACE_FRAME_LIMIT + framesToPop) {\n        break;\n      }\n    }\n\n    return stripSentryFramesAndReverse(frames.slice(framesToPop));\n  };\n}\n\n/**\n * Gets a stack parser implementation from Options.stackParser\n * @see Options\n *\n * If options contains an array of line parsers, it is converted into a parser\n */\nexport function stackParserFromStackParserOptions(stackParser: StackParser | StackLineParser[]): StackParser {\n  if (Array.isArray(stackParser)) {\n    return createStackParser(...stackParser);\n  }\n  return stackParser;\n}\n\n/**\n * Removes Sentry frames from the top and bottom of the stack if present and enforces a limit of max number of frames.\n * Assumes stack input is ordered from top to bottom and returns the reverse representation so call site of the\n * function that caused the crash is the last frame in the array.\n * @hidden\n */\nexport function stripSentryFramesAndReverse(stack: ReadonlyArray<StackFrame>): StackFrame[] {\n  if (!stack.length) {\n    return [];\n  }\n\n  const localStack = Array.from(stack);\n\n  // If stack starts with one of our API calls, remove it (starts, meaning it's the top of the stack - aka last call)\n  if (/sentryWrapped/.test(getLastStackFrame(localStack).function || '')) {\n    localStack.pop();\n  }\n\n  // Reversing in the middle of the procedure allows us to just pop the values off the stack\n  localStack.reverse();\n\n  // If stack ends with one of our internal API calls, remove it (ends, meaning it's the bottom of the stack - aka top-most call)\n  if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n    localStack.pop();\n\n    // When using synthetic events, we will have a 2 levels deep stack, as `new Error('Sentry syntheticException')`\n    // is produced within the hub itself, making it:\n    //\n    //   Sentry.captureException()\n    //   getCurrentHub().captureException()\n    //\n    // instead of just the top `Sentry` call itself.\n    // This forces us to possibly strip an additional frame in the exact same was as above.\n    if (STRIP_FRAME_REGEXP.test(getLastStackFrame(localStack).function || '')) {\n      localStack.pop();\n    }\n  }\n\n  return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map(frame => ({\n    ...frame,\n    filename: frame.filename || getLastStackFrame(localStack).filename,\n    function: frame.function || UNKNOWN_FUNCTION,\n  }));\n}\n\nfunction getLastStackFrame(arr: StackFrame[]): StackFrame {\n  return arr[arr.length - 1] || {};\n}\n\nconst defaultFunctionName = '<anonymous>';\n\n/**\n * Safely extract function name from itself\n */\nexport function getFunctionName(fn: unknown): string {\n  try {\n    if (!fn || typeof fn !== 'function') {\n      return defaultFunctionName;\n    }\n    return fn.name || defaultFunctionName;\n  } catch (e) {\n    // Just accessing custom props in some Selenium environments\n    // can cause a \"Permission denied\" exception (see raven-js#495).\n    return defaultFunctionName;\n  }\n}\n\n/**\n * Get's stack frames from an event without needing to check for undefined properties.\n */\nexport function getFramesFromEvent(event: Event): StackFrame[] | undefined {\n  const exception = event.exception;\n\n  if (exception) {\n    const frames: StackFrame[] = [];\n    try {\n      // @ts-expect-error Object could be undefined\n      exception.values.forEach(value => {\n        // @ts-expect-error Value could be undefined\n        if (value.stacktrace.frames) {\n          // @ts-expect-error Value could be undefined\n          frames.push(...value.stacktrace.frames);\n        }\n      });\n      return frames;\n    } catch (_oO) {\n      return undefined;\n    }\n  }\n  return undefined;\n}\n", "import { DEBUG_BUILD } from '../debug-build';\nimport { logger } from '../logger';\nimport { getFunctionName } from '../stacktrace';\n\nexport type InstrumentHandlerType =\n  | 'console'\n  | 'dom'\n  | 'fetch'\n  | 'fetch-body-resolved'\n  | 'history'\n  | 'xhr'\n  | 'error'\n  | 'unhandledrejection';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type InstrumentHandlerCallback = (data: any) => void;\n\n// We keep the handlers globally\nconst handlers: { [key in InstrumentHandlerType]?: InstrumentHandlerCallback[] } = {};\nconst instrumented: { [key in InstrumentHandlerType]?: boolean } = {};\n\n/** Add a handler function. */\nexport function addHandler(type: InstrumentHandlerType, handler: InstrumentHandlerCallback): void {\n  handlers[type] = handlers[type] || [];\n  (handlers[type] as InstrumentHandlerCallback[]).push(handler);\n}\n\n/**\n * Reset all instrumentation handlers.\n * This can be used by tests to ensure we have a clean slate of instrumentation handlers.\n */\nexport function resetInstrumentationHandlers(): void {\n  Object.keys(handlers).forEach(key => {\n    handlers[key as InstrumentHandlerType] = undefined;\n  });\n}\n\n/** Maybe run an instrumentation function, unless it was already called. */\nexport function maybeInstrument(type: InstrumentHandlerType, instrumentFn: () => void): void {\n  if (!instrumented[type]) {\n    instrumented[type] = true;\n    try {\n      instrumentFn();\n    } catch (e) {\n      DEBUG_BUILD && logger.error(`Error while instrumenting ${type}`, e);\n    }\n  }\n}\n\n/** Trigger handlers for a given instrumentation type. */\nexport function triggerHandlers(type: InstrumentHandlerType, data: unknown): void {\n  const typeHandlers = type && handlers[type];\n  if (!typeHandlers) {\n    return;\n  }\n\n  for (const handler of typeHandlers) {\n    try {\n      handler(data);\n    } catch (e) {\n      DEBUG_BUILD &&\n        logger.error(\n          `Error while triggering instrumentation handler.\\nType: ${type}\\nName: ${getFunctionName(handler)}\\nError:`,\n          e,\n        );\n    }\n  }\n}\n", "import type { HandlerDataError } from '../../types-hoist';\n\nimport { GLOBAL_OBJ } from '../worldwide';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers';\n\nlet _oldOnErrorHandler: (typeof GLOBAL_OBJ)['onerror'] | null = null;\n\n/**\n * Add an instrumentation handler for when an error is captured by the global error handler.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addGlobalErrorInstrumentationHandler(handler: (data: HandlerDataError) => void): void {\n  const type = 'error';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentError);\n}\n\nfunction instrumentError(): void {\n  _oldOnErrorHandler = GLOBAL_OBJ.onerror;\n\n  // Note: The reason we are doing window.onerror instead of window.addEventListener('error')\n  // is that we are using this handler in the Loader Script, to handle buffered errors consistently\n  GLOBAL_OBJ.onerror = function (\n    msg: string | object,\n    url?: string,\n    line?: number,\n    column?: number,\n    error?: Error,\n  ): boolean {\n    const handlerData: HandlerDataError = {\n      column,\n      error,\n      line,\n      msg,\n      url,\n    };\n    triggerHandlers('error', handlerData);\n\n    if (_oldOnErrorHandler) {\n      // eslint-disable-next-line prefer-rest-params\n      return _oldOnErrorHandler.apply(this, arguments);\n    }\n\n    return false;\n  };\n\n  GLOBAL_OBJ.onerror.__SENTRY_INSTRUMENTED__ = true;\n}\n", "import type { HandlerDataUnhandledRejection } from '../../types-hoist';\nimport { GLOBAL_OBJ } from '../worldwide';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers';\n\nlet _oldOnUnhandledRejectionHandler: (typeof GLOBAL_OBJ)['onunhandledrejection'] | null = null;\n\n/**\n * Add an instrumentation handler for when an unhandled promise rejection is captured.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addGlobalUnhandledRejectionInstrumentationHandler(\n  handler: (data: HandlerDataUnhandledRejection) => void,\n): void {\n  const type = 'unhandledrejection';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentUnhandledRejection);\n}\n\nfunction instrumentUnhandledRejection(): void {\n  _oldOnUnhandledRejectionHandler = GLOBAL_OBJ.onunhandledrejection;\n\n  // Note: The reason we are doing window.onunhandledrejection instead of window.addEventListener('unhandledrejection')\n  // is that we are using this handler in the Loader Script, to handle buffered rejections consistently\n  GLOBAL_OBJ.onunhandledrejection = function (e: unknown): boolean {\n    const handlerData: HandlerDataUnhandledRejection = e;\n    triggerHandlers('unhandledrejection', handlerData);\n\n    if (_oldOnUnhandledRejectionHandler) {\n      // eslint-disable-next-line prefer-rest-params\n      return _oldOnUnhandledRejectionHandler.apply(this, arguments);\n    }\n\n    return true;\n  };\n\n  GLOBAL_OBJ.onunhandledrejection.__SENTRY_INSTRUMENTED__ = true;\n}\n", "import type { AsyncContextStack } from './asyncContext/stackStrategy';\nimport type { AsyncContextStrategy } from './asyncContext/types';\nimport type { Client, Integration, MetricsAggregator, Scope } from './types-hoist';\nimport { SDK_VERSION } from './utils-hoist/version';\nimport { GLOBAL_OBJ } from './utils-hoist/worldwide';\n\n/**\n * An object that contains globally accessible properties and maintains a scope stack.\n * @hidden\n */\nexport interface Carrier {\n  __SENTRY__?: VersionedCarrier;\n}\n\ntype VersionedCarrier = {\n  version?: string;\n} & Record<Exclude<string, 'version'>, SentryCarrier>;\n\ninterface SentryCarrier {\n  acs?: AsyncContextStrategy;\n  stack?: AsyncContextStack;\n\n  globalScope?: Scope;\n  defaultIsolationScope?: Scope;\n  defaultCurrentScope?: Scope;\n  globalMetricsAggregators?: WeakMap<Client, MetricsAggregator> | undefined;\n\n  // TODO(v9): Remove these properties - they are no longer used and were left over in v8\n  integrations?: Integration[];\n  extensions?: {\n    // eslint-disable-next-line @typescript-eslint/ban-types\n    [key: string]: Function;\n  };\n}\n\n/**\n * Returns the global shim registry.\n *\n * FIXME: This function is problematic, because despite always returning a valid Carrier,\n * it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check\n * at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.\n **/\nexport function getMainCarrier(): Carrier {\n  // This ensures a Sentry carrier exists\n  getSentryCarrier(GLOBAL_OBJ);\n  return GLOBAL_OBJ;\n}\n\n/** Will either get the existing sentry carrier, or create a new one. */\nexport function getSentryCarrier(carrier: Carrier): SentryCarrier {\n  const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});\n\n  // For now: First SDK that sets the .version property wins\n  __SENTRY__.version = __SENTRY__.version || SDK_VERSION;\n\n  // Intentionally populating and returning the version of \"this\" SDK instance\n  // rather than what's set in .version so that \"this\" SDK always gets its carrier\n  return (__SENTRY__[SDK_VERSION] = __SENTRY__[SDK_VERSION] || {});\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { ParameterizedString, PolymorphicEvent, Primitive } from '../types-hoist';\n\n// eslint-disable-next-line @typescript-eslint/unbound-method\nconst objectToString = Object.prototype.toString;\n\n/**\n * Checks whether given value's type is one of a few Error or Error-like\n * {@link isError}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isError(wat: unknown): wat is Error {\n  switch (objectToString.call(wat)) {\n    case '[object Error]':\n    case '[object Exception]':\n    case '[object DOMException]':\n    case '[object WebAssembly.Exception]':\n      return true;\n    default:\n      return isInstanceOf(wat, Error);\n  }\n}\n/**\n * Checks whether given value is an instance of the given built-in class.\n *\n * @param wat The value to be checked\n * @param className\n * @returns A boolean representing the result.\n */\nfunction isBuiltin(wat: unknown, className: string): boolean {\n  return objectToString.call(wat) === `[object ${className}]`;\n}\n\n/**\n * Checks whether given value's type is ErrorEvent\n * {@link isErrorEvent}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isErrorEvent(wat: unknown): boolean {\n  return isBuiltin(wat, 'ErrorEvent');\n}\n\n/**\n * Checks whether given value's type is DOMError\n * {@link isDOMError}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isDOMError(wat: unknown): boolean {\n  return isBuiltin(wat, 'DOMError');\n}\n\n/**\n * Checks whether given value's type is DOMException\n * {@link isDOMException}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isDOMException(wat: unknown): boolean {\n  return isBuiltin(wat, 'DOMException');\n}\n\n/**\n * Checks whether given value's type is a string\n * {@link isString}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isString(wat: unknown): wat is string {\n  return isBuiltin(wat, 'String');\n}\n\n/**\n * Checks whether given string is parameterized\n * {@link isParameterizedString}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isParameterizedString(wat: unknown): wat is ParameterizedString {\n  return (\n    typeof wat === 'object' &&\n    wat !== null &&\n    '__sentry_template_string__' in wat &&\n    '__sentry_template_values__' in wat\n  );\n}\n\n/**\n * Checks whether given value is a primitive (undefined, null, number, boolean, string, bigint, symbol)\n * {@link isPrimitive}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isPrimitive(wat: unknown): wat is Primitive {\n  return wat === null || isParameterizedString(wat) || (typeof wat !== 'object' && typeof wat !== 'function');\n}\n\n/**\n * Checks whether given value's type is an object literal, or a class instance.\n * {@link isPlainObject}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isPlainObject(wat: unknown): wat is Record<string, unknown> {\n  return isBuiltin(wat, 'Object');\n}\n\n/**\n * Checks whether given value's type is an Event instance\n * {@link isEvent}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isEvent(wat: unknown): wat is PolymorphicEvent {\n  return typeof Event !== 'undefined' && isInstanceOf(wat, Event);\n}\n\n/**\n * Checks whether given value's type is an Element instance\n * {@link isElement}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isElement(wat: unknown): boolean {\n  return typeof Element !== 'undefined' && isInstanceOf(wat, Element);\n}\n\n/**\n * Checks whether given value's type is an regexp\n * {@link isRegExp}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isRegExp(wat: unknown): wat is RegExp {\n  return isBuiltin(wat, 'RegExp');\n}\n\n/**\n * Checks whether given value has a then function.\n * @param wat A value to be checked.\n */\nexport function isThenable(wat: any): wat is PromiseLike<any> {\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n  return Boolean(wat && wat.then && typeof wat.then === 'function');\n}\n\n/**\n * Checks whether given value's type is a SyntheticEvent\n * {@link isSyntheticEvent}.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isSyntheticEvent(wat: unknown): boolean {\n  return isPlainObject(wat) && 'nativeEvent' in wat && 'preventDefault' in wat && 'stopPropagation' in wat;\n}\n\n/**\n * Checks whether given value's type is an instance of provided constructor.\n * {@link isInstanceOf}.\n *\n * @param wat A value to be checked.\n * @param base A constructor to be used in a check.\n * @returns A boolean representing the result.\n */\nexport function isInstanceOf(wat: any, base: any): boolean {\n  try {\n    return wat instanceof base;\n  } catch (_e) {\n    return false;\n  }\n}\n\ninterface VueViewModel {\n  // Vue3\n  __isVue?: boolean;\n  // Vue2\n  _isVue?: boolean;\n}\n/**\n * Checks whether given value's type is a Vue ViewModel.\n *\n * @param wat A value to be checked.\n * @returns A boolean representing the result.\n */\nexport function isVueViewModel(wat: unknown): boolean {\n  // Not using Object.prototype.toString because in Vue 3 it would read the instance's Symbol(Symbol.toStringTag) property.\n  return !!(typeof wat === 'object' && wat !== null && ((wat as VueViewModel).__isVue || (wat as VueViewModel)._isVue));\n}\n", "import { isString } from './is';\nimport { GLOBAL_OBJ } from './worldwide';\n\nconst WINDOW = GLOBAL_OBJ as unknown as Window;\n\nconst DEFAULT_MAX_STRING_LENGTH = 80;\n\ntype SimpleNode = {\n  parentNode: SimpleNode;\n} | null;\n\n/**\n * Given a child DOM element, returns a query-selector statement describing that\n * and its ancestors\n * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]\n * @returns generated DOM path\n */\nexport function htmlTreeAsString(\n  elem: unknown,\n  options: string[] | { keyAttrs?: string[]; maxStringLength?: number } = {},\n): string {\n  if (!elem) {\n    return '<unknown>';\n  }\n\n  // try/catch both:\n  // - accessing event.target (see getsentry/raven-js#838, #768)\n  // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly\n  // - can throw an exception in some circumstances.\n  try {\n    let currentElem = elem as SimpleNode;\n    const MAX_TRAVERSE_HEIGHT = 5;\n    const out = [];\n    let height = 0;\n    let len = 0;\n    const separator = ' > ';\n    const sepLength = separator.length;\n    let nextStr;\n    const keyAttrs = Array.isArray(options) ? options : options.keyAttrs;\n    const maxStringLength = (!Array.isArray(options) && options.maxStringLength) || DEFAULT_MAX_STRING_LENGTH;\n\n    while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) {\n      nextStr = _htmlElementAsString(currentElem, keyAttrs);\n      // bail out if\n      // - nextStr is the 'html' element\n      // - the length of the string that would be created exceeds maxStringLength\n      //   (ignore this limit if we are on the first iteration)\n      if (nextStr === 'html' || (height > 1 && len + out.length * sepLength + nextStr.length >= maxStringLength)) {\n        break;\n      }\n\n      out.push(nextStr);\n\n      len += nextStr.length;\n      currentElem = currentElem.parentNode;\n    }\n\n    return out.reverse().join(separator);\n  } catch (_oO) {\n    return '<unknown>';\n  }\n}\n\n/**\n * Returns a simple, query-selector representation of a DOM element\n * e.g. [HTMLElement] => input#foo.btn[name=baz]\n * @returns generated DOM path\n */\nfunction _htmlElementAsString(el: unknown, keyAttrs?: string[]): string {\n  const elem = el as {\n    tagName?: string;\n    id?: string;\n    className?: string;\n    getAttribute(key: string): string;\n  };\n\n  const out = [];\n\n  if (!elem || !elem.tagName) {\n    return '';\n  }\n\n  // @ts-expect-error WINDOW has HTMLElement\n  if (WINDOW.HTMLElement) {\n    // If using the component name annotation plugin, this value may be available on the DOM node\n    if (elem instanceof HTMLElement && elem.dataset) {\n      if (elem.dataset['sentryComponent']) {\n        return elem.dataset['sentryComponent'];\n      }\n      if (elem.dataset['sentryElement']) {\n        return elem.dataset['sentryElement'];\n      }\n    }\n  }\n\n  out.push(elem.tagName.toLowerCase());\n\n  // Pairs of attribute keys defined in `serializeAttribute` and their values on element.\n  const keyAttrPairs =\n    keyAttrs && keyAttrs.length\n      ? keyAttrs.filter(keyAttr => elem.getAttribute(keyAttr)).map(keyAttr => [keyAttr, elem.getAttribute(keyAttr)])\n      : null;\n\n  if (keyAttrPairs && keyAttrPairs.length) {\n    keyAttrPairs.forEach(keyAttrPair => {\n      out.push(`[${keyAttrPair[0]}=\"${keyAttrPair[1]}\"]`);\n    });\n  } else {\n    if (elem.id) {\n      out.push(`#${elem.id}`);\n    }\n\n    const className = elem.className;\n    if (className && isString(className)) {\n      const classes = className.split(/\\s+/);\n      for (const c of classes) {\n        out.push(`.${c}`);\n      }\n    }\n  }\n  const allowedAttrs = ['aria-label', 'type', 'name', 'title', 'alt'];\n  for (const k of allowedAttrs) {\n    const attr = elem.getAttribute(k);\n    if (attr) {\n      out.push(`[${k}=\"${attr}\"]`);\n    }\n  }\n\n  return out.join('');\n}\n\n/**\n * A safe form of location.href\n */\nexport function getLocationHref(): string {\n  try {\n    return WINDOW.document.location.href;\n  } catch (oO) {\n    return '';\n  }\n}\n\n/**\n * Gets a DOM element by using document.querySelector.\n *\n * This wrapper will first check for the existence of the function before\n * actually calling it so that we don't have to take care of this check,\n * every time we want to access the DOM.\n *\n * Reason: DOM/querySelector is not available in all environments.\n *\n * We have to cast to any because utils can be consumed by a variety of environments,\n * and we don't want to break TS users. If you know what element will be selected by\n * `document.querySelector`, specify it as part of the generic call. For example,\n * `const element = getDomElement<Element>('selector');`\n *\n * @param selector the selector string passed on to document.querySelector\n *\n * @deprecated This method is deprecated and will be removed in the next major version.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getDomElement<E = any>(selector: string): E | null {\n  if (WINDOW.document && WINDOW.document.querySelector) {\n    return WINDOW.document.querySelector(selector) as unknown as E;\n  }\n  return null;\n}\n\n/**\n * Given a DOM element, traverses up the tree until it finds the first ancestor node\n * that has the `data-sentry-component` or `data-sentry-element` attribute with `data-sentry-component` taking\n * precedence. This attribute is added at build-time by projects that have the component name annotation plugin installed.\n *\n * @returns a string representation of the component for the provided DOM element, or `null` if not found\n */\nexport function getComponentName(elem: unknown): string | null {\n  // @ts-expect-error WINDOW has HTMLElement\n  if (!WINDOW.HTMLElement) {\n    return null;\n  }\n\n  let currentElem = elem as SimpleNode;\n  const MAX_TRAVERSE_HEIGHT = 5;\n  for (let i = 0; i < MAX_TRAVERSE_HEIGHT; i++) {\n    if (!currentElem) {\n      return null;\n    }\n\n    if (currentElem instanceof HTMLElement) {\n      if (currentElem.dataset['sentryComponent']) {\n        return currentElem.dataset['sentryComponent'];\n      }\n      if (currentElem.dataset['sentryElement']) {\n        return currentElem.dataset['sentryElement'];\n      }\n    }\n\n    currentElem = currentElem.parentNode;\n  }\n\n  return null;\n}\n", "import { isRegExp, isString, isVueViewModel } from './is';\n\nexport { escapeStringForRegex } from './vendor/escapeStringForRegex';\n\n/**\n * Truncates given string to the maximum characters count\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string (0 = unlimited)\n * @returns string Encoded\n */\nexport function truncate(str: string, max: number = 0): string {\n  if (typeof str !== 'string' || max === 0) {\n    return str;\n  }\n  return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\n\n/**\n * This is basically just `trim_line` from\n * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string\n * @returns string Encoded\n */\nexport function snipLine(line: string, colno: number): string {\n  let newLine = line;\n  const lineLength = newLine.length;\n  if (lineLength <= 150) {\n    return newLine;\n  }\n  if (colno > lineLength) {\n    // eslint-disable-next-line no-param-reassign\n    colno = lineLength;\n  }\n\n  let start = Math.max(colno - 60, 0);\n  if (start < 5) {\n    start = 0;\n  }\n\n  let end = Math.min(start + 140, lineLength);\n  if (end > lineLength - 5) {\n    end = lineLength;\n  }\n  if (end === lineLength) {\n    start = Math.max(end - 140, 0);\n  }\n\n  newLine = newLine.slice(start, end);\n  if (start > 0) {\n    newLine = `'{snip} ${newLine}`;\n  }\n  if (end < lineLength) {\n    newLine += ' {snip}';\n  }\n\n  return newLine;\n}\n\n/**\n * Join values in array\n * @param input array of values to be joined together\n * @param delimiter string to be placed in-between values\n * @returns Joined values\n */\nexport function safeJoin(input: unknown[], delimiter?: string): string {\n  if (!Array.isArray(input)) {\n    return '';\n  }\n\n  const output = [];\n  // eslint-disable-next-line @typescript-eslint/prefer-for-of\n  for (let i = 0; i < input.length; i++) {\n    const value = input[i];\n    try {\n      // This is a hack to fix a Vue3-specific bug that causes an infinite loop of\n      // console warnings. This happens when a Vue template is rendered with\n      // an undeclared variable, which we try to stringify, ultimately causing\n      // Vue to issue another warning which repeats indefinitely.\n      // see: https://github.com/getsentry/sentry-javascript/pull/8981\n      if (isVueViewModel(value)) {\n        output.push('[VueViewModel]');\n      } else {\n        output.push(String(value));\n      }\n    } catch (e) {\n      output.push('[value cannot be serialized]');\n    }\n  }\n\n  return output.join(delimiter);\n}\n\n/**\n * Checks if the given value matches a regex or string\n *\n * @param value The string to test\n * @param pattern Either a regex or a string against which `value` will be matched\n * @param requireExactStringMatch If true, `value` must match `pattern` exactly. If false, `value` will match\n * `pattern` if it contains `pattern`. Only applies to string-type patterns.\n */\nexport function isMatchingPattern(\n  value: string,\n  pattern: RegExp | string,\n  requireExactStringMatch: boolean = false,\n): boolean {\n  if (!isString(value)) {\n    return false;\n  }\n\n  if (isRegExp(pattern)) {\n    return pattern.test(value);\n  }\n  if (isString(pattern)) {\n    return requireExactStringMatch ? value === pattern : value.includes(pattern);\n  }\n\n  return false;\n}\n\n/**\n * Test the given string against an array of strings and regexes. By default, string matching is done on a\n * substring-inclusion basis rather than a strict equality basis\n *\n * @param testString The string to test\n * @param patterns The patterns against which to test the string\n * @param requireExactStringMatch If true, `testString` must match one of the given string patterns exactly in order to\n * count. If false, `testString` will match a string pattern if it contains that pattern.\n * @returns\n */\nexport function stringMatchesSomePattern(\n  testString: string,\n  patterns: Array<string | RegExp> = [],\n  requireExactStringMatch: boolean = false,\n): boolean {\n  return patterns.some(pattern => isMatchingPattern(testString, pattern, requireExactStringMatch));\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { WrappedFunction } from '../types-hoist';\n\nimport { htmlTreeAsString } from './browser';\nimport { DEBUG_BUILD } from './debug-build';\nimport { isElement, isError, isEvent, isInstanceOf, isPlainObject, isPrimitive } from './is';\nimport { logger } from './logger';\nimport { truncate } from './string';\n\n/**\n * Replace a method in an object with a wrapped version of itself.\n *\n * @param source An object that contains a method to be wrapped.\n * @param name The name of the method to be wrapped.\n * @param replacementFactory A higher-order function that takes the original version of the given method and returns a\n * wrapped version. Note: The function returned by `replacementFactory` needs to be a non-arrow function, in order to\n * preserve the correct value of `this`, and the original method must be called using `origMethod.call(this, <other\n * args>)` or `origMethod.apply(this, [<other args>])` (rather than being called directly), again to preserve `this`.\n * @returns void\n */\nexport function fill(source: { [key: string]: any }, name: string, replacementFactory: (...args: any[]) => any): void {\n  if (!(name in source)) {\n    return;\n  }\n\n  const original = source[name] as () => any;\n  const wrapped = replacementFactory(original) as WrappedFunction;\n\n  // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n  // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n  if (typeof wrapped === 'function') {\n    markFunctionWrapped(wrapped, original);\n  }\n\n  try {\n    source[name] = wrapped;\n  } catch {\n    DEBUG_BUILD && logger.log(`Failed to replace method \"${name}\" in object`, source);\n  }\n}\n\n/**\n * Defines a non-enumerable property on the given object.\n *\n * @param obj The object on which to set the property\n * @param name The name of the property to be set\n * @param value The value to which to set the property\n */\nexport function addNonEnumerableProperty(obj: object, name: string, value: unknown): void {\n  try {\n    Object.defineProperty(obj, name, {\n      // enumerable: false, // the default, so we can save on bundle size by not explicitly setting it\n      value: value,\n      writable: true,\n      configurable: true,\n    });\n  } catch (o_O) {\n    DEBUG_BUILD && logger.log(`Failed to add non-enumerable property \"${name}\" to object`, obj);\n  }\n}\n\n/**\n * Remembers the original function on the wrapped function and\n * patches up the prototype.\n *\n * @param wrapped the wrapper function\n * @param original the original function that gets wrapped\n */\nexport function markFunctionWrapped(wrapped: WrappedFunction, original: WrappedFunction): void {\n  try {\n    const proto = original.prototype || {};\n    wrapped.prototype = original.prototype = proto;\n    addNonEnumerableProperty(wrapped, '__sentry_original__', original);\n  } catch (o_O) {} // eslint-disable-line no-empty\n}\n\n/**\n * This extracts the original function if available.  See\n * `markFunctionWrapped` for more information.\n *\n * @param func the function to unwrap\n * @returns the unwrapped version of the function if available.\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function getOriginalFunction<T extends Function>(func: WrappedFunction<T>): T | undefined {\n  return func.__sentry_original__;\n}\n\n/**\n * Encodes given object into url-friendly format\n *\n * @param object An object that contains serializable values\n * @returns string Encoded\n *\n * @deprecated This function is deprecated and will be removed in the next major version of the SDK.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function urlEncode(object: { [key: string]: any }): string {\n  return Object.entries(object)\n    .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n    .join('&');\n}\n\n/**\n * Transforms any `Error` or `Event` into a plain object with all of their enumerable properties, and some of their\n * non-enumerable properties attached.\n *\n * @param value Initial source that we have to transform in order for it to be usable by the serializer\n * @returns An Event or Error turned into an object - or the value argument itself, when value is neither an Event nor\n *  an Error.\n */\nexport function convertToPlainObject<V>(value: V):\n  | {\n      [ownProps: string]: unknown;\n      type: string;\n      target: string;\n      currentTarget: string;\n      detail?: unknown;\n    }\n  | {\n      [ownProps: string]: unknown;\n      message: string;\n      name: string;\n      stack?: string;\n    }\n  | V {\n  if (isError(value)) {\n    return {\n      message: value.message,\n      name: value.name,\n      stack: value.stack,\n      ...getOwnProperties(value),\n    };\n  } else if (isEvent(value)) {\n    const newObj: {\n      [ownProps: string]: unknown;\n      type: string;\n      target: string;\n      currentTarget: string;\n      detail?: unknown;\n    } = {\n      type: value.type,\n      target: serializeEventTarget(value.target),\n      currentTarget: serializeEventTarget(value.currentTarget),\n      ...getOwnProperties(value),\n    };\n\n    if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) {\n      newObj.detail = value.detail;\n    }\n\n    return newObj;\n  } else {\n    return value;\n  }\n}\n\n/** Creates a string representation of the target of an `Event` object */\nfunction serializeEventTarget(target: unknown): string {\n  try {\n    return isElement(target) ? htmlTreeAsString(target) : Object.prototype.toString.call(target);\n  } catch (_oO) {\n    return '<unknown>';\n  }\n}\n\n/** Filters out all but an object's own properties */\nfunction getOwnProperties(obj: unknown): { [key: string]: unknown } {\n  if (typeof obj === 'object' && obj !== null) {\n    const extractedProps: { [key: string]: unknown } = {};\n    for (const property in obj) {\n      if (Object.prototype.hasOwnProperty.call(obj, property)) {\n        extractedProps[property] = (obj as Record<string, unknown>)[property];\n      }\n    }\n    return extractedProps;\n  } else {\n    return {};\n  }\n}\n\n/**\n * Given any captured exception, extract its keys and create a sorted\n * and truncated list that will be used inside the event message.\n * eg. `Non-error exception captured with keys: foo, bar, baz`\n */\nexport function extractExceptionKeysForMessage(exception: Record<string, unknown>, maxLength: number = 40): string {\n  const keys = Object.keys(convertToPlainObject(exception));\n  keys.sort();\n\n  const firstKey = keys[0];\n\n  if (!firstKey) {\n    return '[object has no keys]';\n  }\n\n  if (firstKey.length >= maxLength) {\n    return truncate(firstKey, maxLength);\n  }\n\n  for (let includedKeys = keys.length; includedKeys > 0; includedKeys--) {\n    const serialized = keys.slice(0, includedKeys).join(', ');\n    if (serialized.length > maxLength) {\n      continue;\n    }\n    if (includedKeys === keys.length) {\n      return serialized;\n    }\n    return truncate(serialized, maxLength);\n  }\n\n  return '';\n}\n\n/**\n * Given any object, return a new object having removed all fields whose value was `undefined`.\n * Works recursively on objects and arrays.\n *\n * Attention: This function keeps circular references in the returned object.\n */\nexport function dropUndefinedKeys<T>(inputValue: T): T {\n  // This map keeps track of what already visited nodes map to.\n  // Our Set - based memoBuilder doesn't work here because we want to the output object to have the same circular\n  // references as the input object.\n  const memoizationMap = new Map<unknown, unknown>();\n\n  // This function just proxies `_dropUndefinedKeys` to keep the `memoBuilder` out of this function's API\n  return _dropUndefinedKeys(inputValue, memoizationMap);\n}\n\nfunction _dropUndefinedKeys<T>(inputValue: T, memoizationMap: Map<unknown, unknown>): T {\n  if (isPojo(inputValue)) {\n    // If this node has already been visited due to a circular reference, return the object it was mapped to in the new object\n    const memoVal = memoizationMap.get(inputValue);\n    if (memoVal !== undefined) {\n      return memoVal as T;\n    }\n\n    const returnValue: { [key: string]: unknown } = {};\n    // Store the mapping of this value in case we visit it again, in case of circular data\n    memoizationMap.set(inputValue, returnValue);\n\n    for (const key of Object.getOwnPropertyNames(inputValue)) {\n      if (typeof inputValue[key] !== 'undefined') {\n        returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap);\n      }\n    }\n\n    return returnValue as T;\n  }\n\n  if (Array.isArray(inputValue)) {\n    // If this node has already been visited due to a circular reference, return the array it was mapped to in the new object\n    const memoVal = memoizationMap.get(inputValue);\n    if (memoVal !== undefined) {\n      return memoVal as T;\n    }\n\n    const returnValue: unknown[] = [];\n    // Store the mapping of this value in case we visit it again, in case of circular data\n    memoizationMap.set(inputValue, returnValue);\n\n    inputValue.forEach((item: unknown) => {\n      returnValue.push(_dropUndefinedKeys(item, memoizationMap));\n    });\n\n    return returnValue as unknown as T;\n  }\n\n  return inputValue;\n}\n\nfunction isPojo(input: unknown): input is Record<string, unknown> {\n  if (!isPlainObject(input)) {\n    return false;\n  }\n\n  try {\n    const name = (Object.getPrototypeOf(input) as { constructor: { name: string } }).constructor.name;\n    return !name || name === 'Object';\n  } catch {\n    return true;\n  }\n}\n\n/**\n * Ensure that something is an object.\n *\n * Turns `undefined` and `null` into `String`s and all other primitives into instances of their respective wrapper\n * classes (String, Boolean, Number, etc.). Acts as the identity function on non-primitives.\n *\n * @param wat The subject of the objectification\n * @returns A version of `wat` which can safely be used with `Object` class methods\n */\nexport function objectify(wat: unknown): typeof Object {\n  let objectified;\n  switch (true) {\n    // this will catch both undefined and null\n    case wat == undefined:\n      objectified = new String(wat);\n      break;\n\n    // Though symbols and bigints do have wrapper classes (`Symbol` and `BigInt`, respectively), for whatever reason\n    // those classes don't have constructors which can be used with the `new` keyword. We therefore need to cast each as\n    // an object in order to wrap it.\n    case typeof wat === 'symbol' || typeof wat === 'bigint':\n      objectified = Object(wat);\n      break;\n\n    // this will catch the remaining primitives: `String`, `Number`, and `Boolean`\n    case isPrimitive(wat):\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n      objectified = new (wat as any).constructor(wat);\n      break;\n\n    // by process of elimination, at this point we know that `wat` must already be an object\n    default:\n      objectified = wat;\n      break;\n  }\n  return objectified;\n}\n", "import { GLOBAL_OBJ } from './worldwide';\n\nconst ONE_SECOND_IN_MS = 1000;\n\n/**\n * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}\n * for accessing a high-resolution monotonic clock.\n */\ninterface Performance {\n  /**\n   * The millisecond timestamp at which measurement began, measured in Unix time.\n   */\n  timeOrigin: number;\n  /**\n   * Returns the current millisecond timestamp, where 0 represents the start of measurement.\n   */\n  now(): number;\n}\n\n/**\n * Returns a timestamp in seconds since the UNIX epoch using the Date API.\n *\n * TODO(v8): Return type should be rounded.\n */\nexport function dateTimestampInSeconds(): number {\n  return Date.now() / ONE_SECOND_IN_MS;\n}\n\n/**\n * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not\n * support the API.\n *\n * Wrapping the native API works around differences in behavior from different browsers.\n */\nfunction createUnixTimestampInSecondsFunc(): () => number {\n  const { performance } = GLOBAL_OBJ as typeof GLOBAL_OBJ & { performance?: Performance };\n  if (!performance || !performance.now) {\n    return dateTimestampInSeconds;\n  }\n\n  // Some browser and environments don't have a timeOrigin, so we fallback to\n  // using Date.now() to compute the starting time.\n  const approxStartingTimeOrigin = Date.now() - performance.now();\n  const timeOrigin = performance.timeOrigin == undefined ? approxStartingTimeOrigin : performance.timeOrigin;\n\n  // performance.now() is a monotonic clock, which means it starts at 0 when the process begins. To get the current\n  // wall clock time (actual UNIX timestamp), we need to add the starting time origin and the current time elapsed.\n  //\n  // TODO: This does not account for the case where the monotonic clock that powers performance.now() drifts from the\n  // wall clock time, which causes the returned timestamp to be inaccurate. We should investigate how to detect and\n  // correct for this.\n  // See: https://github.com/getsentry/sentry-javascript/issues/2590\n  // See: https://github.com/mdn/content/issues/4713\n  // See: https://dev.to/noamr/when-a-millisecond-is-not-a-millisecond-3h6\n  return () => {\n    return (timeOrigin + performance.now()) / ONE_SECOND_IN_MS;\n  };\n}\n\n/**\n * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the\n * availability of the Performance API.\n *\n * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is\n * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The\n * skew can grow to arbitrary amounts like days, weeks or months.\n * See https://github.com/getsentry/sentry-javascript/issues/2590.\n */\nexport const timestampInSeconds = createUnixTimestampInSecondsFunc();\n\n/**\n * Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only.\n *\n * @deprecated This variable will be removed in the next major version.\n */\nexport let _browserPerformanceTimeOriginMode: string;\n\n/**\n * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the\n * performance API is available.\n */\nexport const browserPerformanceTimeOrigin = ((): number | undefined => {\n  // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or\n  // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin\n  // data as reliable if they are within a reasonable threshold of the current time.\n\n  const { performance } = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n  if (!performance || !performance.now) {\n    // eslint-disable-next-line deprecation/deprecation\n    _browserPerformanceTimeOriginMode = 'none';\n    return undefined;\n  }\n\n  const threshold = 3600 * 1000;\n  const performanceNow = performance.now();\n  const dateNow = Date.now();\n\n  // if timeOrigin isn't available set delta to threshold so it isn't used\n  const timeOriginDelta = performance.timeOrigin\n    ? Math.abs(performance.timeOrigin + performanceNow - dateNow)\n    : threshold;\n  const timeOriginIsReliable = timeOriginDelta < threshold;\n\n  // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin\n  // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.\n  // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always\n  // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the\n  // Date API.\n  // eslint-disable-next-line deprecation/deprecation\n  const navigationStart = performance.timing && performance.timing.navigationStart;\n  const hasNavigationStart = typeof navigationStart === 'number';\n  // if navigationStart isn't available set delta to threshold so it isn't used\n  const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;\n  const navigationStartIsReliable = navigationStartDelta < threshold;\n\n  if (timeOriginIsReliable || navigationStartIsReliable) {\n    // Use the more reliable time origin\n    if (timeOriginDelta <= navigationStartDelta) {\n      // eslint-disable-next-line deprecation/deprecation\n      _browserPerformanceTimeOriginMode = 'timeOrigin';\n      return performance.timeOrigin;\n    } else {\n      // eslint-disable-next-line deprecation/deprecation\n      _browserPerformanceTimeOriginMode = 'navigationStart';\n      return navigationStart;\n    }\n  }\n\n  // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date.\n  // eslint-disable-next-line deprecation/deprecation\n  _browserPerformanceTimeOriginMode = 'dateNow';\n  return dateNow;\n})();\n", "import type { Event, Exception, Mechanism, StackFrame } from '../types-hoist';\n\nimport { addNonEnumerableProperty } from './object';\nimport { snipLine } from './string';\nimport { GLOBAL_OBJ } from './worldwide';\n\ninterface CryptoInternal {\n  getRandomValues(array: Uint8Array): Uint8Array;\n  randomUUID?(): string;\n}\n\n/** An interface for common properties on global */\ninterface CryptoGlobal {\n  msCrypto?: CryptoInternal;\n  crypto?: CryptoInternal;\n}\n\n/**\n * UUID4 generator\n *\n * @returns string Generated UUID4.\n */\nexport function uuid4(): string {\n  const gbl = GLOBAL_OBJ as typeof GLOBAL_OBJ & CryptoGlobal;\n  const crypto = gbl.crypto || gbl.msCrypto;\n\n  let getRandomByte = (): number => Math.random() * 16;\n  try {\n    if (crypto && crypto.randomUUID) {\n      return crypto.randomUUID().replace(/-/g, '');\n    }\n    if (crypto && crypto.getRandomValues) {\n      getRandomByte = () => {\n        // crypto.getRandomValues might return undefined instead of the typed array\n        // in old Chromium versions (e.g. 23.0.1235.0 (151422))\n        // However, `typedArray` is still filled in-place.\n        // @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#typedarray\n        const typedArray = new Uint8Array(1);\n        crypto.getRandomValues(typedArray);\n        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n        return typedArray[0]!;\n      };\n    }\n  } catch (_) {\n    // some runtimes can crash invoking crypto\n    // https://github.com/getsentry/sentry-javascript/issues/8935\n  }\n\n  // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523\n  // Concatenating the following numbers as strings results in '10000000100040008000100000000000'\n  return (([1e7] as unknown as string) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, c =>\n    // eslint-disable-next-line no-bitwise\n    ((c as unknown as number) ^ ((getRandomByte() & 15) >> ((c as unknown as number) / 4))).toString(16),\n  );\n}\n\nfunction getFirstException(event: Event): Exception | undefined {\n  return event.exception && event.exception.values ? event.exception.values[0] : undefined;\n}\n\n/**\n * Extracts either message or type+value from an event that can be used for user-facing logs\n * @returns event's description\n */\nexport function getEventDescription(event: Event): string {\n  const { message, event_id: eventId } = event;\n  if (message) {\n    return message;\n  }\n\n  const firstException = getFirstException(event);\n  if (firstException) {\n    if (firstException.type && firstException.value) {\n      return `${firstException.type}: ${firstException.value}`;\n    }\n    return firstException.type || firstException.value || eventId || '<unknown>';\n  }\n  return eventId || '<unknown>';\n}\n\n/**\n * Adds exception values, type and value to an synthetic Exception.\n * @param event The event to modify.\n * @param value Value of the exception.\n * @param type Type of the exception.\n * @hidden\n */\nexport function addExceptionTypeValue(event: Event, value?: string, type?: string): void {\n  const exception = (event.exception = event.exception || {});\n  const values = (exception.values = exception.values || []);\n  const firstException = (values[0] = values[0] || {});\n  if (!firstException.value) {\n    firstException.value = value || '';\n  }\n  if (!firstException.type) {\n    firstException.type = type || 'Error';\n  }\n}\n\n/**\n * Adds exception mechanism data to a given event. Uses defaults if the second parameter is not passed.\n *\n * @param event The event to modify.\n * @param newMechanism Mechanism data to add to the event.\n * @hidden\n */\nexport function addExceptionMechanism(event: Event, newMechanism?: Partial<Mechanism>): void {\n  const firstException = getFirstException(event);\n  if (!firstException) {\n    return;\n  }\n\n  const defaultMechanism = { type: 'generic', handled: true };\n  const currentMechanism = firstException.mechanism;\n  firstException.mechanism = { ...defaultMechanism, ...currentMechanism, ...newMechanism };\n\n  if (newMechanism && 'data' in newMechanism) {\n    const mergedData = { ...(currentMechanism && currentMechanism.data), ...newMechanism.data };\n    firstException.mechanism.data = mergedData;\n  }\n}\n\n// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string\nconst SEMVER_REGEXP =\n  /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\n/**\n * Represents Semantic Versioning object\n */\ninterface SemVer {\n  major?: number;\n  minor?: number;\n  patch?: number;\n  prerelease?: string;\n  buildmetadata?: string;\n}\n\nfunction _parseInt(input: string | undefined): number {\n  return parseInt(input || '', 10);\n}\n\n/**\n * Parses input into a SemVer interface\n * @param input string representation of a semver version\n */\nexport function parseSemver(input: string): SemVer {\n  const match = input.match(SEMVER_REGEXP) || [];\n  const major = _parseInt(match[1]);\n  const minor = _parseInt(match[2]);\n  const patch = _parseInt(match[3]);\n  return {\n    buildmetadata: match[5],\n    major: isNaN(major) ? undefined : major,\n    minor: isNaN(minor) ? undefined : minor,\n    patch: isNaN(patch) ? undefined : patch,\n    prerelease: match[4],\n  };\n}\n\n/**\n * This function adds context (pre/post/line) lines to the provided frame\n *\n * @param lines string[] containing all lines\n * @param frame StackFrame that will be mutated\n * @param linesOfContext number of context lines we want to add pre/post\n */\nexport function addContextToFrame(lines: string[], frame: StackFrame, linesOfContext: number = 5): void {\n  // When there is no line number in the frame, attaching context is nonsensical and will even break grouping\n  if (frame.lineno === undefined) {\n    return;\n  }\n\n  const maxLines = lines.length;\n  const sourceLine = Math.max(Math.min(maxLines - 1, frame.lineno - 1), 0);\n\n  frame.pre_context = lines\n    .slice(Math.max(0, sourceLine - linesOfContext), sourceLine)\n    .map((line: string) => snipLine(line, 0));\n\n  // We guard here to ensure this is not larger than the existing number of lines\n  const lineIndex = Math.min(maxLines - 1, sourceLine);\n\n  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n  frame.context_line = snipLine(lines[lineIndex]!, frame.colno || 0);\n\n  frame.post_context = lines\n    .slice(Math.min(sourceLine + 1, maxLines), sourceLine + 1 + linesOfContext)\n    .map((line: string) => snipLine(line, 0));\n}\n\n/**\n * Checks whether or not we've already captured the given exception (note: not an identical exception - the very object\n * in question), and marks it captured if not.\n *\n * This is useful because it's possible for an error to get captured by more than one mechanism. After we intercept and\n * record an error, we rethrow it (assuming we've intercepted it before it's reached the top-level global handlers), so\n * that we don't interfere with whatever effects the error might have had were the SDK not there. At that point, because\n * the error has been rethrown, it's possible for it to bubble up to some other code we've instrumented. If it's not\n * caught after that, it will bubble all the way up to the global handlers (which of course we also instrument). This\n * function helps us ensure that even if we encounter the same error more than once, we only record it the first time we\n * see it.\n *\n * Note: It will ignore primitives (always return `false` and not mark them as seen), as properties can't be set on\n * them. {@link: Object.objectify} can be used on exceptions to convert any that are primitives into their equivalent\n * object wrapper forms so that this check will always work. However, because we need to flag the exact object which\n * will get rethrown, and because that rethrowing happens outside of the event processing pipeline, the objectification\n * must be done before the exception captured.\n *\n * @param A thrown exception to check or flag as having been seen\n * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen)\n */\nexport function checkOrSetAlreadyCaught(exception: unknown): boolean {\n  if (isAlreadyCaptured(exception)) {\n    return true;\n  }\n\n  try {\n    // set it this way rather than by assignment so that it's not ennumerable and therefore isn't recorded by the\n    // `ExtraErrorData` integration\n    addNonEnumerableProperty(exception as { [key: string]: unknown }, '__sentry_captured__', true);\n  } catch (err) {\n    // `exception` is a primitive, so we can't mark it seen\n  }\n\n  return false;\n}\n\nfunction isAlreadyCaptured(exception: unknown): boolean | void {\n  try {\n    return (exception as { __sentry_captured__?: boolean }).__sentry_captured__;\n  } catch {} // eslint-disable-line no-empty\n}\n\n/**\n * Checks whether the given input is already an array, and if it isn't, wraps it in one.\n *\n * @param maybeArray Input to turn into an array, if necessary\n * @returns The input, if already an array, or an array with the input as the only element, if not\n *\n * @deprecated This function has been deprecated and will not be replaced.\n */\nexport function arrayify<T = unknown>(maybeArray: T | T[]): T[] {\n  return Array.isArray(maybeArray) ? maybeArray : [maybeArray];\n}\n", "/* eslint-disable @typescript-eslint/explicit-function-return-type */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { isThenable } from './is';\n\n/** SyncPromise internal states */\nconst enum States {\n  /** Pending */\n  PENDING = 0,\n  /** Resolved / OK */\n  RESOLVED = 1,\n  /** Rejected / Error */\n  REJECTED = 2,\n}\n\n// Overloads so we can call resolvedSyncPromise without arguments and generic argument\nexport function resolvedSyncPromise(): PromiseLike<void>;\nexport function resolvedSyncPromise<T>(value: T | PromiseLike<T>): PromiseLike<T>;\n\n/**\n * Creates a resolved sync promise.\n *\n * @param value the value to resolve the promise with\n * @returns the resolved sync promise\n */\nexport function resolvedSyncPromise<T>(value?: T | PromiseLike<T>): PromiseLike<T> {\n  return new SyncPromise(resolve => {\n    resolve(value);\n  });\n}\n\n/**\n * Creates a rejected sync promise.\n *\n * @param value the value to reject the promise with\n * @returns the rejected sync promise\n */\nexport function rejectedSyncPromise<T = never>(reason?: any): PromiseLike<T> {\n  return new SyncPromise((_, reject) => {\n    reject(reason);\n  });\n}\n\n/**\n * Thenable class that behaves like a Promise and follows it's interface\n * but is not async internally\n */\nclass SyncPromise<T> implements PromiseLike<T> {\n  private _state: States;\n  private _handlers: Array<[boolean, (value: T) => void, (reason: any) => any]>;\n  private _value: any;\n\n  public constructor(\n    executor: (resolve: (value?: T | PromiseLike<T> | null) => void, reject: (reason?: any) => void) => void,\n  ) {\n    this._state = States.PENDING;\n    this._handlers = [];\n\n    try {\n      executor(this._resolve, this._reject);\n    } catch (e) {\n      this._reject(e);\n    }\n  }\n\n  /** JSDoc */\n  public then<TResult1 = T, TResult2 = never>(\n    onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n    onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n  ): PromiseLike<TResult1 | TResult2> {\n    return new SyncPromise((resolve, reject) => {\n      this._handlers.push([\n        false,\n        result => {\n          if (!onfulfilled) {\n            // TODO: ¯\\_(ツ)_/¯\n            // TODO: FIXME\n            resolve(result as any);\n          } else {\n            try {\n              resolve(onfulfilled(result));\n            } catch (e) {\n              reject(e);\n            }\n          }\n        },\n        reason => {\n          if (!onrejected) {\n            reject(reason);\n          } else {\n            try {\n              resolve(onrejected(reason));\n            } catch (e) {\n              reject(e);\n            }\n          }\n        },\n      ]);\n      this._executeHandlers();\n    });\n  }\n\n  /** JSDoc */\n  public catch<TResult = never>(\n    onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,\n  ): PromiseLike<T | TResult> {\n    return this.then(val => val, onrejected);\n  }\n\n  /** JSDoc */\n  public finally<TResult>(onfinally?: (() => void) | null): PromiseLike<TResult> {\n    return new SyncPromise<TResult>((resolve, reject) => {\n      let val: TResult | any;\n      let isRejected: boolean;\n\n      return this.then(\n        value => {\n          isRejected = false;\n          val = value;\n          if (onfinally) {\n            onfinally();\n          }\n        },\n        reason => {\n          isRejected = true;\n          val = reason;\n          if (onfinally) {\n            onfinally();\n          }\n        },\n      ).then(() => {\n        if (isRejected) {\n          reject(val);\n          return;\n        }\n\n        resolve(val as unknown as any);\n      });\n    });\n  }\n\n  /** JSDoc */\n  private readonly _resolve = (value?: T | PromiseLike<T> | null) => {\n    this._setResult(States.RESOLVED, value);\n  };\n\n  /** JSDoc */\n  private readonly _reject = (reason?: any) => {\n    this._setResult(States.REJECTED, reason);\n  };\n\n  /** JSDoc */\n  private readonly _setResult = (state: States, value?: T | PromiseLike<T> | any) => {\n    if (this._state !== States.PENDING) {\n      return;\n    }\n\n    if (isThenable(value)) {\n      void (value as PromiseLike<T>).then(this._resolve, this._reject);\n      return;\n    }\n\n    this._state = state;\n    this._value = value;\n\n    this._executeHandlers();\n  };\n\n  /** JSDoc */\n  private readonly _executeHandlers = () => {\n    if (this._state === States.PENDING) {\n      return;\n    }\n\n    const cachedHandlers = this._handlers.slice();\n    this._handlers = [];\n\n    cachedHandlers.forEach(handler => {\n      if (handler[0]) {\n        return;\n      }\n\n      if (this._state === States.RESOLVED) {\n        handler[1](this._value as unknown as any);\n      }\n\n      if (this._state === States.REJECTED) {\n        handler[2](this._value);\n      }\n\n      handler[0] = true;\n    });\n  };\n}\n\nexport { SyncPromise };\n", "import type { SerializedSession, Session, SessionContext, SessionStatus } from './types-hoist';\nimport { dropUndefinedKeys, timestampInSeconds, uuid4 } from './utils-hoist';\n\n/**\n * Creates a new `Session` object by setting certain default parameters. If optional @param context\n * is passed, the passed properties are applied to the session object.\n *\n * @param context (optional) additional properties to be applied to the returned session object\n *\n * @returns a new `Session` object\n */\nexport function makeSession(context?: Omit<SessionContext, 'started' | 'status'>): Session {\n  // Both timestamp and started are in seconds since the UNIX epoch.\n  const startingTime = timestampInSeconds();\n\n  const session: Session = {\n    sid: uuid4(),\n    init: true,\n    timestamp: startingTime,\n    started: startingTime,\n    duration: 0,\n    status: 'ok',\n    errors: 0,\n    ignoreDuration: false,\n    toJSON: () => sessionToJSON(session),\n  };\n\n  if (context) {\n    updateSession(session, context);\n  }\n\n  return session;\n}\n\n/**\n * Updates a session object with the properties passed in the context.\n *\n * Note that this function mutates the passed object and returns void.\n * (Had to do this instead of returning a new and updated session because closing and sending a session\n * makes an update to the session after it was passed to the sending logic.\n * @see BaseClient.captureSession )\n *\n * @param session the `Session` to update\n * @param context the `SessionContext` holding the properties that should be updated in @param session\n */\n// eslint-disable-next-line complexity\nexport function updateSession(session: Session, context: SessionContext = {}): void {\n  if (context.user) {\n    if (!session.ipAddress && context.user.ip_address) {\n      session.ipAddress = context.user.ip_address;\n    }\n\n    if (!session.did && !context.did) {\n      session.did = context.user.id || context.user.email || context.user.username;\n    }\n  }\n\n  session.timestamp = context.timestamp || timestampInSeconds();\n\n  if (context.abnormal_mechanism) {\n    session.abnormal_mechanism = context.abnormal_mechanism;\n  }\n\n  if (context.ignoreDuration) {\n    session.ignoreDuration = context.ignoreDuration;\n  }\n  if (context.sid) {\n    // Good enough uuid validation. — Kamil\n    session.sid = context.sid.length === 32 ? context.sid : uuid4();\n  }\n  if (context.init !== undefined) {\n    session.init = context.init;\n  }\n  if (!session.did && context.did) {\n    session.did = `${context.did}`;\n  }\n  if (typeof context.started === 'number') {\n    session.started = context.started;\n  }\n  if (session.ignoreDuration) {\n    session.duration = undefined;\n  } else if (typeof context.duration === 'number') {\n    session.duration = context.duration;\n  } else {\n    const duration = session.timestamp - session.started;\n    session.duration = duration >= 0 ? duration : 0;\n  }\n  if (context.release) {\n    session.release = context.release;\n  }\n  if (context.environment) {\n    session.environment = context.environment;\n  }\n  if (!session.ipAddress && context.ipAddress) {\n    session.ipAddress = context.ipAddress;\n  }\n  if (!session.userAgent && context.userAgent) {\n    session.userAgent = context.userAgent;\n  }\n  if (typeof context.errors === 'number') {\n    session.errors = context.errors;\n  }\n  if (context.status) {\n    session.status = context.status;\n  }\n}\n\n/**\n * Closes a session by setting its status and updating the session object with it.\n * Internally calls `updateSession` to update the passed session object.\n *\n * Note that this function mutates the passed session (@see updateSession for explanation).\n *\n * @param session the `Session` object to be closed\n * @param status the `SessionStatus` with which the session was closed. If you don't pass a status,\n *               this function will keep the previously set status, unless it was `'ok'` in which case\n *               it is changed to `'exited'`.\n */\nexport function closeSession(session: Session, status?: Exclude<SessionStatus, 'ok'>): void {\n  let context = {};\n  if (status) {\n    context = { status };\n  } else if (session.status === 'ok') {\n    context = { status: 'exited' };\n  }\n\n  updateSession(session, context);\n}\n\n/**\n * Serializes a passed session object to a JSON object with a slightly different structure.\n * This is necessary because the Sentry backend requires a slightly different schema of a session\n * than the one the JS SDKs use internally.\n *\n * @param session the session to be converted\n *\n * @returns a JSON object of the passed session\n */\nfunction sessionToJSON(session: Session): SerializedSession {\n  return dropUndefinedKeys({\n    sid: `${session.sid}`,\n    init: session.init,\n    // Make sure that sec is converted to ms for date constructor\n    started: new Date(session.started * 1000).toISOString(),\n    timestamp: new Date(session.timestamp * 1000).toISOString(),\n    status: session.status,\n    errors: session.errors,\n    did: typeof session.did === 'number' || typeof session.did === 'string' ? `${session.did}` : undefined,\n    duration: session.duration,\n    abnormal_mechanism: session.abnormal_mechanism,\n    attrs: {\n      release: session.release,\n      environment: session.environment,\n      ip_address: session.ipAddress,\n      user_agent: session.userAgent,\n    },\n  });\n}\n", "import type { PropagationContext } from '../types-hoist';\nimport { uuid4 } from './misc';\n\n/**\n * Returns a new minimal propagation context.\n *\n * @deprecated Use `generateTraceId` and `generateSpanId` instead.\n */\nexport function generatePropagationContext(): PropagationContext {\n  return {\n    traceId: generateTraceId(),\n    spanId: generateSpanId(),\n  };\n}\n\n/**\n * Generate a random, valid trace ID.\n */\nexport function generateTraceId(): string {\n  return uuid4();\n}\n\n/**\n * Generate a random, valid span ID.\n */\nexport function generateSpanId(): string {\n  return uuid4().substring(16);\n}\n", "/**\n * Shallow merge two objects.\n * Does not mutate the passed in objects.\n * Undefined/empty values in the merge object will overwrite existing values.\n *\n * By default, this merges 2 levels deep.\n */\nexport function merge<T>(initialObj: T, mergeObj: T, levels = 2): T {\n  // If the merge value is not an object, or we have no merge levels left,\n  // we just set the value to the merge value\n  if (!mergeObj || typeof mergeObj !== 'object' || levels <= 0) {\n    return mergeObj;\n  }\n\n  // If the merge object is an empty object, and the initial object is not undefined, we return the initial object\n  if (initialObj && mergeObj && Object.keys(mergeObj).length === 0) {\n    return initialObj;\n  }\n\n  // Clone object\n  const output = { ...initialObj };\n\n  // Merge values into output, resursively\n  for (const key in mergeObj) {\n    if (Object.prototype.hasOwnProperty.call(mergeObj, key)) {\n      output[key] = merge(output[key], mergeObj[key], levels - 1);\n    }\n  }\n\n  return output;\n}\n", "import type { Scope, Span } from '../types-hoist';\nimport { addNonEnumerableProperty } from '../utils-hoist/object';\n\nconst SCOPE_SPAN_FIELD = '_sentrySpan';\n\ntype ScopeWithMaybeSpan = Scope & {\n  [SCOPE_SPAN_FIELD]?: Span;\n};\n\n/**\n * Set the active span for a given scope.\n * NOTE: This should NOT be used directly, but is only used internally by the trace methods.\n */\nexport function _setSpanForScope(scope: Scope, span: Span | undefined): void {\n  if (span) {\n    addNonEnumerableProperty(scope as ScopeWithMaybeSpan, SCOPE_SPAN_FIELD, span);\n  } else {\n    // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n    delete (scope as ScopeWithMaybeSpan)[SCOPE_SPAN_FIELD];\n  }\n}\n\n/**\n * Get the active span for a given scope.\n * NOTE: This should NOT be used directly, but is only used internally by the trace methods.\n */\nexport function _getSpanForScope(scope: ScopeWithMaybeSpan): Span | undefined {\n  return scope[SCOPE_SPAN_FIELD];\n}\n", "/* eslint-disable max-lines */\nimport type {\n  Attachment,\n  Breadcrumb,\n  CaptureContext,\n  Client,\n  Context,\n  Contexts,\n  Event,\n  EventHint,\n  EventProcessor,\n  Extra,\n  Extras,\n  Primitive,\n  PropagationContext,\n  RequestSession,\n  Scope as ScopeInterface,\n  ScopeContext,\n  ScopeData,\n  Session,\n  SeverityLevel,\n  User,\n} from './types-hoist';\n\nimport { updateSession } from './session';\nimport { isPlainObject } from './utils-hoist/is';\nimport { logger } from './utils-hoist/logger';\nimport { uuid4 } from './utils-hoist/misc';\nimport { generateSpanId, generateTraceId } from './utils-hoist/propagationContext';\nimport { dateTimestampInSeconds } from './utils-hoist/time';\nimport { merge } from './utils/merge';\nimport { _getSpanForScope, _setSpanForScope } from './utils/spanOnScope';\n\n/**\n * Default value for maximum number of breadcrumbs added to an event.\n */\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\n/**\n * Holds additional event information.\n */\nclass ScopeClass implements ScopeInterface {\n  /** Flag if notifying is happening. */\n  protected _notifyingListeners: boolean;\n\n  /** Callback for client to receive scope changes. */\n  protected _scopeListeners: Array<(scope: Scope) => void>;\n\n  /** Callback list that will be called during event processing. */\n  protected _eventProcessors: EventProcessor[];\n\n  /** Array of breadcrumbs. */\n  protected _breadcrumbs: Breadcrumb[];\n\n  /** User */\n  protected _user: User;\n\n  /** Tags */\n  protected _tags: { [key: string]: Primitive };\n\n  /** Extra */\n  protected _extra: Extras;\n\n  /** Contexts */\n  protected _contexts: Contexts;\n\n  /** Attachments */\n  protected _attachments: Attachment[];\n\n  /** Propagation Context for distributed tracing */\n  protected _propagationContext: PropagationContext;\n\n  /**\n   * A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get\n   * sent to Sentry\n   */\n  protected _sdkProcessingMetadata: { [key: string]: unknown };\n\n  /** Fingerprint */\n  protected _fingerprint?: string[];\n\n  /** Severity */\n  protected _level?: SeverityLevel;\n\n  /**\n   * Transaction Name\n   *\n   * IMPORTANT: The transaction name on the scope has nothing to do with root spans/transaction objects.\n   * It's purpose is to assign a transaction to the scope that's added to non-transaction events.\n   */\n  protected _transactionName?: string;\n\n  /** Session */\n  protected _session?: Session;\n\n  /** Request Mode Session Status */\n  // eslint-disable-next-line deprecation/deprecation\n  protected _requestSession?: RequestSession;\n\n  /** The client on this scope */\n  protected _client?: Client;\n\n  /** Contains the last event id of a captured event.  */\n  protected _lastEventId?: string;\n\n  // NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method.\n\n  public constructor() {\n    this._notifyingListeners = false;\n    this._scopeListeners = [];\n    this._eventProcessors = [];\n    this._breadcrumbs = [];\n    this._attachments = [];\n    this._user = {};\n    this._tags = {};\n    this._extra = {};\n    this._contexts = {};\n    this._sdkProcessingMetadata = {};\n    this._propagationContext = {\n      traceId: generateTraceId(),\n      spanId: generateSpanId(),\n    };\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public clone(): ScopeClass {\n    const newScope = new ScopeClass();\n    newScope._breadcrumbs = [...this._breadcrumbs];\n    newScope._tags = { ...this._tags };\n    newScope._extra = { ...this._extra };\n    newScope._contexts = { ...this._contexts };\n    if (this._contexts.flags) {\n      // We need to copy the `values` array so insertions on a cloned scope\n      // won't affect the original array.\n      newScope._contexts.flags = {\n        values: [...this._contexts.flags.values],\n      };\n    }\n\n    newScope._user = this._user;\n    newScope._level = this._level;\n    newScope._session = this._session;\n    newScope._transactionName = this._transactionName;\n    newScope._fingerprint = this._fingerprint;\n    newScope._eventProcessors = [...this._eventProcessors];\n    newScope._requestSession = this._requestSession;\n    newScope._attachments = [...this._attachments];\n    newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata };\n    newScope._propagationContext = { ...this._propagationContext };\n    newScope._client = this._client;\n    newScope._lastEventId = this._lastEventId;\n\n    _setSpanForScope(newScope, _getSpanForScope(this));\n\n    return newScope;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setClient(client: Client | undefined): void {\n    this._client = client;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setLastEventId(lastEventId: string | undefined): void {\n    this._lastEventId = lastEventId;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getClient<C extends Client>(): C | undefined {\n    return this._client as C | undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public lastEventId(): string | undefined {\n    return this._lastEventId;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public addScopeListener(callback: (scope: Scope) => void): void {\n    this._scopeListeners.push(callback);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public addEventProcessor(callback: EventProcessor): this {\n    this._eventProcessors.push(callback);\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setUser(user: User | null): this {\n    // If null is passed we want to unset everything, but still define keys,\n    // so that later down in the pipeline any existing values are cleared.\n    this._user = user || {\n      email: undefined,\n      id: undefined,\n      ip_address: undefined,\n      username: undefined,\n    };\n\n    if (this._session) {\n      updateSession(this._session, { user });\n    }\n\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getUser(): User | undefined {\n    return this._user;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  // eslint-disable-next-line deprecation/deprecation\n  public getRequestSession(): RequestSession | undefined {\n    return this._requestSession;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  // eslint-disable-next-line deprecation/deprecation\n  public setRequestSession(requestSession?: RequestSession): this {\n    this._requestSession = requestSession;\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setTags(tags: { [key: string]: Primitive }): this {\n    this._tags = {\n      ...this._tags,\n      ...tags,\n    };\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setTag(key: string, value: Primitive): this {\n    this._tags = { ...this._tags, [key]: value };\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setExtras(extras: Extras): this {\n    this._extra = {\n      ...this._extra,\n      ...extras,\n    };\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setExtra(key: string, extra: Extra): this {\n    this._extra = { ...this._extra, [key]: extra };\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setFingerprint(fingerprint: string[]): this {\n    this._fingerprint = fingerprint;\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setLevel(level: SeverityLevel): this {\n    this._level = level;\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * Sets the transaction name on the scope so that the name of e.g. taken server route or\n   * the page location is attached to future events.\n   *\n   * IMPORTANT: Calling this function does NOT change the name of the currently active\n   * root span. If you want to change the name of the active root span, use\n   * `Sentry.updateSpanName(rootSpan, 'new name')` instead.\n   *\n   * By default, the SDK updates the scope's transaction name automatically on sensible\n   * occasions, such as a page navigation or when handling a new request on the server.\n   */\n  public setTransactionName(name?: string): this {\n    this._transactionName = name;\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setContext(key: string, context: Context | null): this {\n    if (context === null) {\n      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n      delete this._contexts[key];\n    } else {\n      this._contexts[key] = context;\n    }\n\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setSession(session?: Session): this {\n    if (!session) {\n      delete this._session;\n    } else {\n      this._session = session;\n    }\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getSession(): Session | undefined {\n    return this._session;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public update(captureContext?: CaptureContext): this {\n    if (!captureContext) {\n      return this;\n    }\n\n    const scopeToMerge = typeof captureContext === 'function' ? captureContext(this) : captureContext;\n\n    const [scopeInstance, requestSession] =\n      scopeToMerge instanceof Scope\n        ? // eslint-disable-next-line deprecation/deprecation\n          [scopeToMerge.getScopeData(), scopeToMerge.getRequestSession()]\n        : isPlainObject(scopeToMerge)\n          ? [captureContext as ScopeContext, (captureContext as ScopeContext).requestSession]\n          : [];\n\n    const { tags, extra, user, contexts, level, fingerprint = [], propagationContext } = scopeInstance || {};\n\n    this._tags = { ...this._tags, ...tags };\n    this._extra = { ...this._extra, ...extra };\n    this._contexts = { ...this._contexts, ...contexts };\n\n    if (user && Object.keys(user).length) {\n      this._user = user;\n    }\n\n    if (level) {\n      this._level = level;\n    }\n\n    if (fingerprint.length) {\n      this._fingerprint = fingerprint;\n    }\n\n    if (propagationContext) {\n      this._propagationContext = propagationContext;\n    }\n\n    if (requestSession) {\n      this._requestSession = requestSession;\n    }\n\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public clear(): this {\n    // client is not cleared here on purpose!\n    this._breadcrumbs = [];\n    this._tags = {};\n    this._extra = {};\n    this._user = {};\n    this._contexts = {};\n    this._level = undefined;\n    this._transactionName = undefined;\n    this._fingerprint = undefined;\n    this._requestSession = undefined;\n    this._session = undefined;\n    _setSpanForScope(this, undefined);\n    this._attachments = [];\n    this.setPropagationContext({ traceId: generateTraceId() });\n\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public addBreadcrumb(breadcrumb: Breadcrumb, maxBreadcrumbs?: number): this {\n    const maxCrumbs = typeof maxBreadcrumbs === 'number' ? maxBreadcrumbs : DEFAULT_MAX_BREADCRUMBS;\n\n    // No data has been changed, so don't notify scope listeners\n    if (maxCrumbs <= 0) {\n      return this;\n    }\n\n    const mergedBreadcrumb = {\n      timestamp: dateTimestampInSeconds(),\n      ...breadcrumb,\n    };\n\n    this._breadcrumbs.push(mergedBreadcrumb);\n    if (this._breadcrumbs.length > maxCrumbs) {\n      this._breadcrumbs = this._breadcrumbs.slice(-maxCrumbs);\n      if (this._client) {\n        this._client.recordDroppedEvent('buffer_overflow', 'log_item');\n      }\n    }\n\n    this._notifyScopeListeners();\n\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getLastBreadcrumb(): Breadcrumb | undefined {\n    return this._breadcrumbs[this._breadcrumbs.length - 1];\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public clearBreadcrumbs(): this {\n    this._breadcrumbs = [];\n    this._notifyScopeListeners();\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public addAttachment(attachment: Attachment): this {\n    this._attachments.push(attachment);\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public clearAttachments(): this {\n    this._attachments = [];\n    return this;\n  }\n\n  /** @inheritDoc */\n  public getScopeData(): ScopeData {\n    return {\n      breadcrumbs: this._breadcrumbs,\n      attachments: this._attachments,\n      contexts: this._contexts,\n      tags: this._tags,\n      extra: this._extra,\n      user: this._user,\n      level: this._level,\n      fingerprint: this._fingerprint || [],\n      eventProcessors: this._eventProcessors,\n      propagationContext: this._propagationContext,\n      sdkProcessingMetadata: this._sdkProcessingMetadata,\n      transactionName: this._transactionName,\n      span: _getSpanForScope(this),\n    };\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setSDKProcessingMetadata(newData: { [key: string]: unknown }): this {\n    this._sdkProcessingMetadata = merge(this._sdkProcessingMetadata, newData, 2);\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setPropagationContext(\n    context: Omit<PropagationContext, 'spanId'> & Partial<Pick<PropagationContext, 'spanId'>>,\n  ): this {\n    this._propagationContext = {\n      // eslint-disable-next-line deprecation/deprecation\n      spanId: generateSpanId(),\n      ...context,\n    };\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getPropagationContext(): PropagationContext {\n    return this._propagationContext;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public captureException(exception: unknown, hint?: EventHint): string {\n    const eventId = hint && hint.event_id ? hint.event_id : uuid4();\n\n    if (!this._client) {\n      logger.warn('No client configured on scope - will not capture exception!');\n      return eventId;\n    }\n\n    const syntheticException = new Error('Sentry syntheticException');\n\n    this._client.captureException(\n      exception,\n      {\n        originalException: exception,\n        syntheticException,\n        ...hint,\n        event_id: eventId,\n      },\n      this,\n    );\n\n    return eventId;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public captureMessage(message: string, level?: SeverityLevel, hint?: EventHint): string {\n    const eventId = hint && hint.event_id ? hint.event_id : uuid4();\n\n    if (!this._client) {\n      logger.warn('No client configured on scope - will not capture message!');\n      return eventId;\n    }\n\n    const syntheticException = new Error(message);\n\n    this._client.captureMessage(\n      message,\n      level,\n      {\n        originalException: message,\n        syntheticException,\n        ...hint,\n        event_id: eventId,\n      },\n      this,\n    );\n\n    return eventId;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public captureEvent(event: Event, hint?: EventHint): string {\n    const eventId = hint && hint.event_id ? hint.event_id : uuid4();\n\n    if (!this._client) {\n      logger.warn('No client configured on scope - will not capture event!');\n      return eventId;\n    }\n\n    this._client.captureEvent(event, { ...hint, event_id: eventId }, this);\n\n    return eventId;\n  }\n\n  /**\n   * This will be called on every set call.\n   */\n  protected _notifyScopeListeners(): void {\n    // We need this check for this._notifyingListeners to be able to work on scope during updates\n    // If this check is not here we'll produce endless recursion when something is done with the scope\n    // during the callback.\n    if (!this._notifyingListeners) {\n      this._notifyingListeners = true;\n      this._scopeListeners.forEach(callback => {\n        callback(this);\n      });\n      this._notifyingListeners = false;\n    }\n  }\n}\n\n/**\n * Holds additional event information.\n */\nexport const Scope = ScopeClass;\n\n/**\n * Holds additional event information.\n */\nexport type Scope = ScopeInterface;\n", "import { Scope as ScopeClass } from './scope';\nimport type { Scope } from './types-hoist';\nimport { getGlobalSingleton } from './utils-hoist/worldwide';\n\n/** Get the default current scope. */\nexport function getDefaultCurrentScope(): Scope {\n  return getGlobalSingleton('defaultCurrentScope', () => new ScopeClass());\n}\n\n/** Get the default isolation scope. */\nexport function getDefaultIsolationScope(): Scope {\n  return getGlobalSingleton('defaultIsolationScope', () => new ScopeClass());\n}\n", "import { getDefaultCurrentScope, getDefaultIsolationScope } from '../defaultScopes';\nimport { Scope } from '../scope';\nimport type { Client, Scope as ScopeInterface } from '../types-hoist';\nimport { isThenable } from '../utils-hoist/is';\nimport { getMainCarrier, getSentryCarrier } from './../carrier';\nimport type { AsyncContextStrategy } from './types';\n\ninterface Layer {\n  client?: Client;\n  scope: ScopeInterface;\n}\n\n/**\n * This is an object that holds a stack of scopes.\n */\nexport class AsyncContextStack {\n  private readonly _stack: [Layer, ...Layer[]];\n  private _isolationScope: ScopeInterface;\n\n  public constructor(scope?: ScopeInterface, isolationScope?: ScopeInterface) {\n    let assignedScope;\n    if (!scope) {\n      assignedScope = new Scope();\n    } else {\n      assignedScope = scope;\n    }\n\n    let assignedIsolationScope;\n    if (!isolationScope) {\n      assignedIsolationScope = new Scope();\n    } else {\n      assignedIsolationScope = isolationScope;\n    }\n\n    // scope stack for domains or the process\n    this._stack = [{ scope: assignedScope }];\n    this._isolationScope = assignedIsolationScope;\n  }\n\n  /**\n   * Fork a scope for the stack.\n   */\n  public withScope<T>(callback: (scope: ScopeInterface) => T): T {\n    const scope = this._pushScope();\n\n    let maybePromiseResult: T;\n    try {\n      maybePromiseResult = callback(scope);\n    } catch (e) {\n      this._popScope();\n      throw e;\n    }\n\n    if (isThenable(maybePromiseResult)) {\n      // @ts-expect-error - isThenable returns the wrong type\n      return maybePromiseResult.then(\n        res => {\n          this._popScope();\n          return res;\n        },\n        e => {\n          this._popScope();\n          throw e;\n        },\n      );\n    }\n\n    this._popScope();\n    return maybePromiseResult;\n  }\n\n  /**\n   * Get the client of the stack.\n   */\n  public getClient<C extends Client>(): C | undefined {\n    return this.getStackTop().client as C;\n  }\n\n  /**\n   * Returns the scope of the top stack.\n   */\n  public getScope(): ScopeInterface {\n    return this.getStackTop().scope;\n  }\n\n  /**\n   * Get the isolation scope for the stack.\n   */\n  public getIsolationScope(): ScopeInterface {\n    return this._isolationScope;\n  }\n\n  /**\n   * Returns the topmost scope layer in the order domain > local > process.\n   */\n  public getStackTop(): Layer {\n    return this._stack[this._stack.length - 1] as Layer;\n  }\n\n  /**\n   * Push a scope to the stack.\n   */\n  private _pushScope(): ScopeInterface {\n    // We want to clone the content of prev scope\n    const scope = this.getScope().clone();\n    this._stack.push({\n      client: this.getClient(),\n      scope,\n    });\n    return scope;\n  }\n\n  /**\n   * Pop a scope from the stack.\n   */\n  private _popScope(): boolean {\n    if (this._stack.length <= 1) return false;\n    return !!this._stack.pop();\n  }\n}\n\n/**\n * Get the global async context stack.\n * This will be removed during the v8 cycle and is only here to make migration easier.\n */\nfunction getAsyncContextStack(): AsyncContextStack {\n  const registry = getMainCarrier();\n  const sentry = getSentryCarrier(registry);\n\n  return (sentry.stack = sentry.stack || new AsyncContextStack(getDefaultCurrentScope(), getDefaultIsolationScope()));\n}\n\nfunction withScope<T>(callback: (scope: ScopeInterface) => T): T {\n  return getAsyncContextStack().withScope(callback);\n}\n\nfunction withSetScope<T>(scope: ScopeInterface, callback: (scope: ScopeInterface) => T): T {\n  const stack = getAsyncContextStack() as AsyncContextStack;\n  return stack.withScope(() => {\n    stack.getStackTop().scope = scope;\n    return callback(scope);\n  });\n}\n\nfunction withIsolationScope<T>(callback: (isolationScope: ScopeInterface) => T): T {\n  return getAsyncContextStack().withScope(() => {\n    return callback(getAsyncContextStack().getIsolationScope());\n  });\n}\n\n/**\n * Get the stack-based async context strategy.\n */\nexport function getStackAsyncContextStrategy(): AsyncContextStrategy {\n  return {\n    withIsolationScope,\n    withScope,\n    withSetScope,\n    withSetIsolationScope: <T>(_isolationScope: ScopeInterface, callback: (isolationScope: ScopeInterface) => T) => {\n      return withIsolationScope(callback);\n    },\n    getCurrentScope: () => getAsyncContextStack().getScope(),\n    getIsolationScope: () => getAsyncContextStack().getIsolationScope(),\n  };\n}\n", "import type { Carrier } from './../carrier';\nimport { getMainCarrier, getSentryCarrier } from './../carrier';\nimport { getStackAsyncContextStrategy } from './stackStrategy';\nimport type { AsyncContextStrategy } from './types';\n\n/**\n * @private Private API with no semver guarantees!\n *\n * Sets the global async context strategy\n */\nexport function setAsyncContextStrategy(strategy: AsyncContextStrategy | undefined): void {\n  // Get main carrier (global for every environment)\n  const registry = getMainCarrier();\n  const sentry = getSentryCarrier(registry);\n  sentry.acs = strategy;\n}\n\n/**\n * Get the current async context strategy.\n * If none has been setup, the default will be used.\n */\nexport function getAsyncContextStrategy(carrier: Carrier): AsyncContextStrategy {\n  const sentry = getSentryCarrier(carrier);\n\n  if (sentry.acs) {\n    return sentry.acs;\n  }\n\n  // Otherwise, use the default one (stack)\n  return getStackAsyncContextStrategy();\n}\n", "import { getAsyncContextStrategy } from './asyncContext';\nimport { getMainCarrier } from './carrier';\nimport { Scope as ScopeClass } from './scope';\nimport type { Client, Scope, TraceContext } from './types-hoist';\nimport { dropUndefinedKeys } from './utils-hoist/object';\nimport { getGlobalSingleton } from './utils-hoist/worldwide';\n\n/**\n * Get the currently active scope.\n */\nexport function getCurrentScope(): Scope {\n  const carrier = getMainCarrier();\n  const acs = getAsyncContextStrategy(carrier);\n  return acs.getCurrentScope();\n}\n\n/**\n * Get the currently active isolation scope.\n * The isolation scope is active for the current execution context.\n */\nexport function getIsolationScope(): Scope {\n  const carrier = getMainCarrier();\n  const acs = getAsyncContextStrategy(carrier);\n  return acs.getIsolationScope();\n}\n\n/**\n * Get the global scope.\n * This scope is applied to _all_ events.\n */\nexport function getGlobalScope(): Scope {\n  return getGlobalSingleton('globalScope', () => new ScopeClass());\n}\n\n/**\n * Creates a new scope with and executes the given operation within.\n * The scope is automatically removed once the operation\n * finishes or throws.\n */\nexport function withScope<T>(callback: (scope: Scope) => T): T;\n/**\n * Set the given scope as the active scope in the callback.\n */\nexport function withScope<T>(scope: Scope | undefined, callback: (scope: Scope) => T): T;\n/**\n * Either creates a new active scope, or sets the given scope as active scope in the given callback.\n */\nexport function withScope<T>(\n  ...rest: [callback: (scope: Scope) => T] | [scope: Scope | undefined, callback: (scope: Scope) => T]\n): T {\n  const carrier = getMainCarrier();\n  const acs = getAsyncContextStrategy(carrier);\n\n  // If a scope is defined, we want to make this the active scope instead of the default one\n  if (rest.length === 2) {\n    const [scope, callback] = rest;\n\n    if (!scope) {\n      return acs.withScope(callback);\n    }\n\n    return acs.withSetScope(scope, callback);\n  }\n\n  return acs.withScope(rest[0]);\n}\n\n/**\n * Attempts to fork the current isolation scope and the current scope based on the current async context strategy. If no\n * async context strategy is set, the isolation scope and the current scope will not be forked (this is currently the\n * case, for example, in the browser).\n *\n * Usage of this function in environments without async context strategy is discouraged and may lead to unexpected behaviour.\n *\n * This function is intended for Sentry SDK and SDK integration development. It is not recommended to be used in \"normal\"\n * applications directly because it comes with pitfalls. Use at your own risk!\n */\nexport function withIsolationScope<T>(callback: (isolationScope: Scope) => T): T;\n/**\n * Set the provided isolation scope as active in the given callback. If no\n * async context strategy is set, the isolation scope and the current scope will not be forked (this is currently the\n * case, for example, in the browser).\n *\n * Usage of this function in environments without async context strategy is discouraged and may lead to unexpected behaviour.\n *\n * This function is intended for Sentry SDK and SDK integration development. It is not recommended to be used in \"normal\"\n * applications directly because it comes with pitfalls. Use at your own risk!\n *\n * If you pass in `undefined` as a scope, it will fork a new isolation scope, the same as if no scope is passed.\n */\nexport function withIsolationScope<T>(isolationScope: Scope | undefined, callback: (isolationScope: Scope) => T): T;\n/**\n * Either creates a new active isolation scope, or sets the given isolation scope as active scope in the given callback.\n */\nexport function withIsolationScope<T>(\n  ...rest:\n    | [callback: (isolationScope: Scope) => T]\n    | [isolationScope: Scope | undefined, callback: (isolationScope: Scope) => T]\n): T {\n  const carrier = getMainCarrier();\n  const acs = getAsyncContextStrategy(carrier);\n\n  // If a scope is defined, we want to make this the active scope instead of the default one\n  if (rest.length === 2) {\n    const [isolationScope, callback] = rest;\n\n    if (!isolationScope) {\n      return acs.withIsolationScope(callback);\n    }\n\n    return acs.withSetIsolationScope(isolationScope, callback);\n  }\n\n  return acs.withIsolationScope(rest[0]);\n}\n\n/**\n * Get the currently active client.\n */\nexport function getClient<C extends Client>(): C | undefined {\n  return getCurrentScope().getClient<C>();\n}\n\n/**\n * Get a trace context for the given scope.\n */\nexport function getTraceContextFromScope(scope: Scope): TraceContext {\n  const propagationContext = scope.getPropagationContext();\n\n  // TODO(v9): Use generateSpanId() instead of spanId\n  // eslint-disable-next-line deprecation/deprecation\n  const { traceId, spanId, parentSpanId } = propagationContext;\n\n  const traceContext: TraceContext = dropUndefinedKeys({\n    trace_id: traceId,\n    span_id: spanId,\n    parent_span_id: parentSpanId,\n  });\n\n  return traceContext;\n}\n", "import type { MeasurementUnit, Span } from '../types-hoist';\nimport type { MetricSummary } from '../types-hoist';\nimport type { Primitive } from '../types-hoist';\nimport { dropUndefinedKeys } from '../utils-hoist/object';\nimport type { MetricType } from './types';\n\n/**\n * key: bucketKey\n * value: [exportKey, MetricSummary]\n */\ntype MetricSummaryStorage = Map<string, [string, MetricSummary]>;\n\nconst METRICS_SPAN_FIELD = '_sentryMetrics';\n\ntype SpanWithPotentialMetrics = Span & {\n  [METRICS_SPAN_FIELD]?: MetricSummaryStorage;\n};\n\n/**\n * Fetches the metric summary if it exists for the passed span\n */\nexport function getMetricSummaryJsonForSpan(span: Span): Record<string, Array<MetricSummary>> | undefined {\n  const storage = (span as SpanWithPotentialMetrics)[METRICS_SPAN_FIELD];\n\n  if (!storage) {\n    return undefined;\n  }\n  const output: Record<string, Array<MetricSummary>> = {};\n\n  for (const [, [exportKey, summary]] of storage) {\n    const arr = output[exportKey] || (output[exportKey] = []);\n    arr.push(dropUndefinedKeys(summary));\n  }\n\n  return output;\n}\n\n/**\n * Updates the metric summary on a span.\n */\nexport function updateMetricSummaryOnSpan(\n  span: Span,\n  metricType: MetricType,\n  sanitizedName: string,\n  value: number,\n  unit: MeasurementUnit,\n  tags: Record<string, Primitive>,\n  bucketKey: string,\n): void {\n  const existingStorage = (span as SpanWithPotentialMetrics)[METRICS_SPAN_FIELD];\n  const storage =\n    existingStorage ||\n    ((span as SpanWithPotentialMetrics)[METRICS_SPAN_FIELD] = new Map<string, [string, MetricSummary]>());\n\n  const exportKey = `${metricType}:${sanitizedName}@${unit}`;\n  const bucketItem = storage.get(bucketKey);\n\n  if (bucketItem) {\n    const [, summary] = bucketItem;\n    storage.set(bucketKey, [\n      exportKey,\n      {\n        min: Math.min(summary.min, value),\n        max: Math.max(summary.max, value),\n        count: (summary.count += 1),\n        sum: (summary.sum += value),\n        tags: summary.tags,\n      },\n    ]);\n  } else {\n    storage.set(bucketKey, [\n      exportKey,\n      {\n        min: value,\n        max: value,\n        count: 1,\n        sum: value,\n        tags,\n      },\n    ]);\n  }\n}\n", "/**\n * Use this attribute to represent the source of a span.\n * Should be one of: custom, url, route, view, component, task, unknown\n *\n */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_SOURCE = 'sentry.source';\n\n/**\n * Use this attribute to represent the sample rate used for a span.\n */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE = 'sentry.sample_rate';\n\n/**\n * Use this attribute to represent the operation of a span.\n */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_OP = 'sentry.op';\n\n/**\n * Use this attribute to represent the origin of a span.\n */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN = 'sentry.origin';\n\n/** The reason why an idle span finished. */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON = 'sentry.idle_span_finish_reason';\n\n/** The unit of a measurement, which may be stored as a TimedEvent. */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT = 'sentry.measurement_unit';\n\n/** The value of a measurement, which may be stored as a TimedEvent. */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE = 'sentry.measurement_value';\n\n/**\n * A custom span name set by users guaranteed to be taken over any automatically\n * inferred name. This attribute is removed before the span is sent.\n *\n * @internal only meant for internal SDK usage\n * @hidden\n */\nexport const SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME = 'sentry.custom_span_name';\n\n/**\n * The id of the profile that this span occurred in.\n */\nexport const SEMANTIC_ATTRIBUTE_PROFILE_ID = 'sentry.profile_id';\n\nexport const SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME = 'sentry.exclusive_time';\n\nexport const SEMANTIC_ATTRIBUTE_CACHE_HIT = 'cache.hit';\n\nexport const SEMANTIC_ATTRIBUTE_CACHE_KEY = 'cache.key';\n\nexport const SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE = 'cache.item_size';\n\n/** TODO: Remove these once we update to latest semantic conventions */\nexport const SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD = 'http.request.method';\nexport const SEMANTIC_ATTRIBUTE_URL_FULL = 'url.full';\n", "import type { Span, SpanStatus } from '../types-hoist';\n\nexport const SPAN_STATUS_UNSET = 0;\nexport const SPAN_STATUS_OK = 1;\nexport const SPAN_STATUS_ERROR = 2;\n\n/**\n * Converts a HTTP status code into a sentry status with a message.\n *\n * @param httpStatus The HTTP response status code.\n * @returns The span status or unknown_error.\n */\n// https://develop.sentry.dev/sdk/event-payloads/span/\nexport function getSpanStatusFromHttpCode(httpStatus: number): SpanStatus {\n  if (httpStatus < 400 && httpStatus >= 100) {\n    return { code: SPAN_STATUS_OK };\n  }\n\n  if (httpStatus >= 400 && httpStatus < 500) {\n    switch (httpStatus) {\n      case 401:\n        return { code: SPAN_STATUS_ERROR, message: 'unauthenticated' };\n      case 403:\n        return { code: SPAN_STATUS_ERROR, message: 'permission_denied' };\n      case 404:\n        return { code: SPAN_STATUS_ERROR, message: 'not_found' };\n      case 409:\n        return { code: SPAN_STATUS_ERROR, message: 'already_exists' };\n      case 413:\n        return { code: SPAN_STATUS_ERROR, message: 'failed_precondition' };\n      case 429:\n        return { code: SPAN_STATUS_ERROR, message: 'resource_exhausted' };\n      case 499:\n        return { code: SPAN_STATUS_ERROR, message: 'cancelled' };\n      default:\n        return { code: SPAN_STATUS_ERROR, message: 'invalid_argument' };\n    }\n  }\n\n  if (httpStatus >= 500 && httpStatus < 600) {\n    switch (httpStatus) {\n      case 501:\n        return { code: SPAN_STATUS_ERROR, message: 'unimplemented' };\n      case 503:\n        return { code: SPAN_STATUS_ERROR, message: 'unavailable' };\n      case 504:\n        return { code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' };\n      default:\n        return { code: SPAN_STATUS_ERROR, message: 'internal_error' };\n    }\n  }\n\n  return { code: SPAN_STATUS_ERROR, message: 'unknown_error' };\n}\n\n/**\n * Sets the Http status attributes on the current span based on the http code.\n * Additionally, the span's status is updated, depending on the http code.\n */\nexport function setHttpStatus(span: Span, httpStatus: number): void {\n  span.setAttribute('http.response.status_code', httpStatus);\n\n  const spanStatus = getSpanStatusFromHttpCode(httpStatus);\n  if (spanStatus.message !== 'unknown_error') {\n    span.setStatus(spanStatus);\n  }\n}\n", "import type { DynamicSamplingContext } from '../types-hoist';\n\nimport { DEBUG_BUILD } from './debug-build';\nimport { isString } from './is';\nimport { logger } from './logger';\n\n/**\n * @deprecated Use a `\"baggage\"` string directly\n */\nexport const BAGGAGE_HEADER_NAME = 'baggage';\n\nexport const SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-';\n\nexport const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;\n\n/**\n * Max length of a serialized baggage string\n *\n * https://www.w3.org/TR/baggage/#limits\n */\nexport const MAX_BAGGAGE_STRING_LENGTH = 8192;\n\n/**\n * Takes a baggage header and turns it into Dynamic Sampling Context, by extracting all the \"sentry-\" prefixed values\n * from it.\n *\n * @param baggageHeader A very bread definition of a baggage header as it might appear in various frameworks.\n * @returns The Dynamic Sampling Context that was found on `baggageHeader`, if there was any, `undefined` otherwise.\n */\nexport function baggageHeaderToDynamicSamplingContext(\n  // Very liberal definition of what any incoming header might look like\n  baggageHeader: string | string[] | number | null | undefined | boolean,\n): Partial<DynamicSamplingContext> | undefined {\n  const baggageObject = parseBaggageHeader(baggageHeader);\n\n  if (!baggageObject) {\n    return undefined;\n  }\n\n  // Read all \"sentry-\" prefixed values out of the baggage object and put it onto a dynamic sampling context object.\n  const dynamicSamplingContext = Object.entries(baggageObject).reduce<Record<string, string>>((acc, [key, value]) => {\n    if (key.match(SENTRY_BAGGAGE_KEY_PREFIX_REGEX)) {\n      const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);\n      acc[nonPrefixedKey] = value;\n    }\n    return acc;\n  }, {});\n\n  // Only return a dynamic sampling context object if there are keys in it.\n  // A keyless object means there were no sentry values on the header, which means that there is no DSC.\n  if (Object.keys(dynamicSamplingContext).length > 0) {\n    return dynamicSamplingContext as Partial<DynamicSamplingContext>;\n  } else {\n    return undefined;\n  }\n}\n\n/**\n * Turns a Dynamic Sampling Object into a baggage header by prefixing all the keys on the object with \"sentry-\".\n *\n * @param dynamicSamplingContext The Dynamic Sampling Context to turn into a header. For convenience and compatibility\n * with the `getDynamicSamplingContext` method on the Transaction class ,this argument can also be `undefined`. If it is\n * `undefined` the function will return `undefined`.\n * @returns a baggage header, created from `dynamicSamplingContext`, or `undefined` either if `dynamicSamplingContext`\n * was `undefined`, or if `dynamicSamplingContext` didn't contain any values.\n */\nexport function dynamicSamplingContextToSentryBaggageHeader(\n  // this also takes undefined for convenience and bundle size in other places\n  dynamicSamplingContext?: Partial<DynamicSamplingContext>,\n): string | undefined {\n  if (!dynamicSamplingContext) {\n    return undefined;\n  }\n\n  // Prefix all DSC keys with \"sentry-\" and put them into a new object\n  const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce<Record<string, string>>(\n    (acc, [dscKey, dscValue]) => {\n      if (dscValue) {\n        acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;\n      }\n      return acc;\n    },\n    {},\n  );\n\n  return objectToBaggageHeader(sentryPrefixedDSC);\n}\n\n/**\n * Take a baggage header and parse it into an object.\n */\nexport function parseBaggageHeader(\n  baggageHeader: string | string[] | number | null | undefined | boolean,\n): Record<string, string> | undefined {\n  if (!baggageHeader || (!isString(baggageHeader) && !Array.isArray(baggageHeader))) {\n    return undefined;\n  }\n\n  if (Array.isArray(baggageHeader)) {\n    // Combine all baggage headers into one object containing the baggage values so we can later read the Sentry-DSC-values from it\n    return baggageHeader.reduce<Record<string, string>>((acc, curr) => {\n      const currBaggageObject = baggageHeaderToObject(curr);\n      Object.entries(currBaggageObject).forEach(([key, value]) => {\n        acc[key] = value;\n      });\n      return acc;\n    }, {});\n  }\n\n  return baggageHeaderToObject(baggageHeader);\n}\n\n/**\n * Will parse a baggage header, which is a simple key-value map, into a flat object.\n *\n * @param baggageHeader The baggage header to parse.\n * @returns a flat object containing all the key-value pairs from `baggageHeader`.\n */\nfunction baggageHeaderToObject(baggageHeader: string): Record<string, string> {\n  return baggageHeader\n    .split(',')\n    .map(baggageEntry => baggageEntry.split('=').map(keyOrValue => decodeURIComponent(keyOrValue.trim())))\n    .reduce<Record<string, string>>((acc, [key, value]) => {\n      if (key && value) {\n        acc[key] = value;\n      }\n      return acc;\n    }, {});\n}\n\n/**\n * Turns a flat object (key-value pairs) into a baggage header, which is also just key-value pairs.\n *\n * @param object The object to turn into a baggage header.\n * @returns a baggage header string, or `undefined` if the object didn't have any values, since an empty baggage header\n * is not spec compliant.\n */\nfunction objectToBaggageHeader(object: Record<string, string>): string | undefined {\n  if (Object.keys(object).length === 0) {\n    // An empty baggage header is not spec compliant: We return undefined.\n    return undefined;\n  }\n\n  return Object.entries(object).reduce((baggageHeader, [objectKey, objectValue], currentIndex) => {\n    const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`;\n    const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`;\n    if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) {\n      DEBUG_BUILD &&\n        logger.warn(\n          `Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`,\n        );\n      return baggageHeader;\n    } else {\n      return newBaggageHeader;\n    }\n  }, '');\n}\n", "import type { PropagationContext, TraceparentData } from '../types-hoist';\n\nimport { baggageHeaderToDynamicSamplingContext } from './baggage';\nimport { generateSpanId, generateTraceId } from './propagationContext';\n\n// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here\nexport const TRACEPARENT_REGEXP = new RegExp(\n  '^[ \\\\t]*' + // whitespace\n    '([0-9a-f]{32})?' + // trace_id\n    '-?([0-9a-f]{16})?' + // span_id\n    '-?([01])?' + // sampled\n    '[ \\\\t]*$', // whitespace\n);\n\n/**\n * Extract transaction context data from a `sentry-trace` header.\n *\n * @param traceparent Traceparent string\n *\n * @returns Object containing data from the header, or undefined if traceparent string is malformed\n */\nexport function extractTraceparentData(traceparent?: string): TraceparentData | undefined {\n  if (!traceparent) {\n    return undefined;\n  }\n\n  const matches = traceparent.match(TRACEPARENT_REGEXP);\n  if (!matches) {\n    return undefined;\n  }\n\n  let parentSampled: boolean | undefined;\n  if (matches[3] === '1') {\n    parentSampled = true;\n  } else if (matches[3] === '0') {\n    parentSampled = false;\n  }\n\n  return {\n    traceId: matches[1],\n    parentSampled,\n    parentSpanId: matches[2],\n  };\n}\n\n/**\n * Create a propagation context from incoming headers or\n * creates a minimal new one if the headers are undefined.\n */\nexport function propagationContextFromHeaders(\n  sentryTrace: string | undefined,\n  baggage: string | number | boolean | string[] | null | undefined,\n): PropagationContext {\n  const traceparentData = extractTraceparentData(sentryTrace);\n  const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggage);\n\n  if (!traceparentData || !traceparentData.traceId) {\n    return { traceId: generateTraceId(), spanId: generateSpanId() };\n  }\n\n  const { traceId, parentSpanId, parentSampled } = traceparentData;\n\n  const virtualSpanId = generateSpanId();\n\n  return {\n    traceId,\n    parentSpanId,\n    spanId: virtualSpanId,\n    sampled: parentSampled,\n    dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it\n  };\n}\n\n/**\n * Create sentry-trace header from span context values.\n */\nexport function generateSentryTraceHeader(\n  traceId: string = generateTraceId(),\n  spanId: string = generateSpanId(),\n  sampled?: boolean,\n): string {\n  let sampledString = '';\n  if (sampled !== undefined) {\n    sampledString = sampled ? '-1' : '-0';\n  }\n  return `${traceId}-${spanId}${sampledString}`;\n}\n", "import { getAsyncContextStrategy } from '../asyncContext';\nimport { getMainCarrier } from '../carrier';\nimport { getCurrentScope } from '../currentScopes';\nimport { getMetricSummaryJsonForSpan, updateMetricSummaryOnSpan } from '../metrics/metric-summary';\nimport type { MetricType } from '../metrics/types';\nimport {\n  SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n  SEMANTIC_ATTRIBUTE_SENTRY_OP,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '../semanticAttributes';\nimport type { SentrySpan } from '../tracing/sentrySpan';\nimport { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus';\nimport type {\n  MeasurementUnit,\n  Primitive,\n  Span,\n  SpanAttributes,\n  SpanJSON,\n  SpanOrigin,\n  SpanStatus,\n  SpanTimeInput,\n  TraceContext,\n} from '../types-hoist';\nimport { consoleSandbox } from '../utils-hoist/logger';\nimport { addNonEnumerableProperty, dropUndefinedKeys } from '../utils-hoist/object';\nimport { generateSpanId } from '../utils-hoist/propagationContext';\nimport { timestampInSeconds } from '../utils-hoist/time';\nimport { generateSentryTraceHeader } from '../utils-hoist/tracing';\nimport { _getSpanForScope } from './spanOnScope';\n\n// These are aligned with OpenTelemetry trace flags\nexport const TRACE_FLAG_NONE = 0x0;\nexport const TRACE_FLAG_SAMPLED = 0x1;\n\n// todo(v9): Remove this once we've stopped dropping spans via `beforeSendSpan`\nlet hasShownSpanDropWarning = false;\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in an event.\n * By default, this will only include trace_id, span_id & parent_span_id.\n * If `includeAllData` is true, it will also include data, op, status & origin.\n */\nexport function spanToTransactionTraceContext(span: Span): TraceContext {\n  const { spanId: span_id, traceId: trace_id } = span.spanContext();\n  const { data, op, parent_span_id, status, origin } = spanToJSON(span);\n\n  return dropUndefinedKeys({\n    parent_span_id,\n    span_id,\n    trace_id,\n    data,\n    op,\n    status,\n    origin,\n  });\n}\n\n/**\n * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event.\n */\nexport function spanToTraceContext(span: Span): TraceContext {\n  const { spanId, traceId: trace_id, isRemote } = span.spanContext();\n\n  // If the span is remote, we use a random/virtual span as span_id to the trace context,\n  // and the remote span as parent_span_id\n  const parent_span_id = isRemote ? spanId : spanToJSON(span).parent_span_id;\n  const span_id = isRemote ? generateSpanId() : spanId;\n\n  return dropUndefinedKeys({\n    parent_span_id,\n    span_id,\n    trace_id,\n  });\n}\n\n/**\n * Convert a Span to a Sentry trace header.\n */\nexport function spanToTraceHeader(span: Span): string {\n  const { traceId, spanId } = span.spanContext();\n  const sampled = spanIsSampled(span);\n  return generateSentryTraceHeader(traceId, spanId, sampled);\n}\n\n/**\n * Convert a span time input into a timestamp in seconds.\n */\nexport function spanTimeInputToSeconds(input: SpanTimeInput | undefined): number {\n  if (typeof input === 'number') {\n    return ensureTimestampInSeconds(input);\n  }\n\n  if (Array.isArray(input)) {\n    // See {@link HrTime} for the array-based time format\n    return input[0] + input[1] / 1e9;\n  }\n\n  if (input instanceof Date) {\n    return ensureTimestampInSeconds(input.getTime());\n  }\n\n  return timestampInSeconds();\n}\n\n/**\n * Converts a timestamp to second, if it was in milliseconds, or keeps it as second.\n */\nfunction ensureTimestampInSeconds(timestamp: number): number {\n  const isMs = timestamp > 9999999999;\n  return isMs ? timestamp / 1000 : timestamp;\n}\n\n/**\n * Convert a span to a JSON representation.\n */\n// Note: Because of this, we currently have a circular type dependency (which we opted out of in package.json).\n// This is not avoidable as we need `spanToJSON` in `spanUtils.ts`, which in turn is needed by `span.ts` for backwards compatibility.\n// And `spanToJSON` needs the Span class from `span.ts` to check here.\nexport function spanToJSON(span: Span): Partial<SpanJSON> {\n  if (spanIsSentrySpan(span)) {\n    return span.getSpanJSON();\n  }\n\n  try {\n    const { spanId: span_id, traceId: trace_id } = span.spanContext();\n\n    // Handle a span from @opentelemetry/sdk-base-trace's `Span` class\n    if (spanIsOpenTelemetrySdkTraceBaseSpan(span)) {\n      const { attributes, startTime, name, endTime, parentSpanId, status } = span;\n\n      return dropUndefinedKeys({\n        span_id,\n        trace_id,\n        data: attributes,\n        description: name,\n        parent_span_id: parentSpanId,\n        start_timestamp: spanTimeInputToSeconds(startTime),\n        // This is [0,0] by default in OTEL, in which case we want to interpret this as no end time\n        timestamp: spanTimeInputToSeconds(endTime) || undefined,\n        status: getStatusMessage(status),\n        op: attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n        origin: attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] as SpanOrigin | undefined,\n        _metrics_summary: getMetricSummaryJsonForSpan(span),\n      });\n    }\n\n    // Finally, at least we have `spanContext()`....\n    return {\n      span_id,\n      trace_id,\n    };\n  } catch {\n    return {};\n  }\n}\n\nfunction spanIsOpenTelemetrySdkTraceBaseSpan(span: Span): span is OpenTelemetrySdkTraceBaseSpan {\n  const castSpan = span as OpenTelemetrySdkTraceBaseSpan;\n  return !!castSpan.attributes && !!castSpan.startTime && !!castSpan.name && !!castSpan.endTime && !!castSpan.status;\n}\n\n/** Exported only for tests. */\nexport interface OpenTelemetrySdkTraceBaseSpan extends Span {\n  attributes: SpanAttributes;\n  startTime: SpanTimeInput;\n  name: string;\n  status: SpanStatus;\n  endTime: SpanTimeInput;\n  parentSpanId?: string;\n}\n\n/**\n * Sadly, due to circular dependency checks we cannot actually import the Span class here and check for instanceof.\n * :( So instead we approximate this by checking if it has the `getSpanJSON` method.\n */\nfunction spanIsSentrySpan(span: Span): span is SentrySpan {\n  return typeof (span as SentrySpan).getSpanJSON === 'function';\n}\n\n/**\n * Returns true if a span is sampled.\n * In most cases, you should just use `span.isRecording()` instead.\n * However, this has a slightly different semantic, as it also returns false if the span is finished.\n * So in the case where this distinction is important, use this method.\n */\nexport function spanIsSampled(span: Span): boolean {\n  // We align our trace flags with the ones OpenTelemetry use\n  // So we also check for sampled the same way they do.\n  const { traceFlags } = span.spanContext();\n  return traceFlags === TRACE_FLAG_SAMPLED;\n}\n\n/** Get the status message to use for a JSON representation of a span. */\nexport function getStatusMessage(status: SpanStatus | undefined): string | undefined {\n  if (!status || status.code === SPAN_STATUS_UNSET) {\n    return undefined;\n  }\n\n  if (status.code === SPAN_STATUS_OK) {\n    return 'ok';\n  }\n\n  return status.message || 'unknown_error';\n}\n\nconst CHILD_SPANS_FIELD = '_sentryChildSpans';\nconst ROOT_SPAN_FIELD = '_sentryRootSpan';\n\ntype SpanWithPotentialChildren = Span & {\n  [CHILD_SPANS_FIELD]?: Set<Span>;\n  [ROOT_SPAN_FIELD]?: Span;\n};\n\n/**\n * Adds an opaque child span reference to a span.\n */\nexport function addChildSpanToSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n  // We store the root span reference on the child span\n  // We need this for `getRootSpan()` to work\n  const rootSpan = span[ROOT_SPAN_FIELD] || span;\n  addNonEnumerableProperty(childSpan as SpanWithPotentialChildren, ROOT_SPAN_FIELD, rootSpan);\n\n  // We store a list of child spans on the parent span\n  // We need this for `getSpanDescendants()` to work\n  if (span[CHILD_SPANS_FIELD]) {\n    span[CHILD_SPANS_FIELD].add(childSpan);\n  } else {\n    addNonEnumerableProperty(span, CHILD_SPANS_FIELD, new Set([childSpan]));\n  }\n}\n\n/** This is only used internally by Idle Spans. */\nexport function removeChildSpanFromSpan(span: SpanWithPotentialChildren, childSpan: Span): void {\n  if (span[CHILD_SPANS_FIELD]) {\n    span[CHILD_SPANS_FIELD].delete(childSpan);\n  }\n}\n\n/**\n * Returns an array of the given span and all of its descendants.\n */\nexport function getSpanDescendants(span: SpanWithPotentialChildren): Span[] {\n  const resultSet = new Set<Span>();\n\n  function addSpanChildren(span: SpanWithPotentialChildren): void {\n    // This exit condition is required to not infinitely loop in case of a circular dependency.\n    if (resultSet.has(span)) {\n      return;\n      // We want to ignore unsampled spans (e.g. non recording spans)\n    } else if (spanIsSampled(span)) {\n      resultSet.add(span);\n      const childSpans = span[CHILD_SPANS_FIELD] ? Array.from(span[CHILD_SPANS_FIELD]) : [];\n      for (const childSpan of childSpans) {\n        addSpanChildren(childSpan);\n      }\n    }\n  }\n\n  addSpanChildren(span);\n\n  return Array.from(resultSet);\n}\n\n/**\n * Returns the root span of a given span.\n */\nexport function getRootSpan(span: SpanWithPotentialChildren): Span {\n  return span[ROOT_SPAN_FIELD] || span;\n}\n\n/**\n * Returns the currently active span.\n */\nexport function getActiveSpan(): Span | undefined {\n  const carrier = getMainCarrier();\n  const acs = getAsyncContextStrategy(carrier);\n  if (acs.getActiveSpan) {\n    return acs.getActiveSpan();\n  }\n\n  return _getSpanForScope(getCurrentScope());\n}\n\n/**\n * Updates the metric summary on the currently active span\n */\nexport function updateMetricSummaryOnActiveSpan(\n  metricType: MetricType,\n  sanitizedName: string,\n  value: number,\n  unit: MeasurementUnit,\n  tags: Record<string, Primitive>,\n  bucketKey: string,\n): void {\n  const span = getActiveSpan();\n  if (span) {\n    updateMetricSummaryOnSpan(span, metricType, sanitizedName, value, unit, tags, bucketKey);\n  }\n}\n\n/**\n * Logs a warning once if `beforeSendSpan` is used to drop spans.\n *\n * todo(v9): Remove this once we've stopped dropping spans via `beforeSendSpan`.\n */\nexport function showSpanDropWarning(): void {\n  if (!hasShownSpanDropWarning) {\n    consoleSandbox(() => {\n      // eslint-disable-next-line no-console\n      console.warn(\n        '[Sentry] Deprecation warning: Returning null from `beforeSendSpan` will be disallowed from SDK version 9.0.0 onwards. The callback will only support mutating spans. To drop certain spans, configure the respective integrations directly.',\n      );\n    });\n    hasShownSpanDropWarning = true;\n  }\n}\n\n/**\n * Updates the name of the given span and ensures that the span name is not\n * overwritten by the Sentry SDK.\n *\n * Use this function instead of `span.updateName()` if you want to make sure that\n * your name is kept. For some spans, for example root `http.server` spans the\n * Sentry SDK would otherwise overwrite the span name with a high-quality name\n * it infers when the span ends.\n *\n * Use this function in server code or when your span is started on the server\n * and on the client (browser). If you only update a span name on the client,\n * you can also use `span.updateName()` the SDK does not overwrite the name.\n *\n * @param span - The span to update the name of.\n * @param name - The name to set on the span.\n */\nexport function updateSpanName(span: Span, name: string): void {\n  span.updateName(name);\n  span.setAttributes({\n    [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n    [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: name,\n  });\n}\n", "import { DEBUG_BUILD } from '../debug-build';\nimport { addGlobalErrorInstrumentationHandler } from '../utils-hoist/instrument/globalError';\nimport { addGlobalUnhandledRejectionInstrumentationHandler } from '../utils-hoist/instrument/globalUnhandledRejection';\nimport { logger } from '../utils-hoist/logger';\nimport { getActiveSpan, getRootSpan } from '../utils/spanUtils';\nimport { SPAN_STATUS_ERROR } from './spanstatus';\n\nlet errorsInstrumented = false;\n\n/**  Only exposed for testing */\nexport function _resetErrorsInstrumented(): void {\n  errorsInstrumented = false;\n}\n\n/**\n * Ensure that global errors automatically set the active span status.\n */\nexport function registerSpanErrorInstrumentation(): void {\n  if (errorsInstrumented) {\n    return;\n  }\n\n  errorsInstrumented = true;\n  addGlobalErrorInstrumentationHandler(errorCallback);\n  addGlobalUnhandledRejectionInstrumentationHandler(errorCallback);\n}\n\n/**\n * If an error or unhandled promise occurs, we mark the active root span as failed\n */\nfunction errorCallback(): void {\n  const activeSpan = getActiveSpan();\n  const rootSpan = activeSpan && getRootSpan(activeSpan);\n  if (rootSpan) {\n    const message = 'internal_error';\n    DEBUG_BUILD && logger.log(`[Tracing] Root span: ${message} -> Global error occurred`);\n    rootSpan.setStatus({ code: SPAN_STATUS_ERROR, message });\n  }\n}\n\n// The function name will be lost when bundling but we need to be able to identify this listener later to maintain the\n// node.js default exit behaviour\nerrorCallback.tag = 'sentry_tracingErrorCallback';\n", "import type { Span } from '../types-hoist';\nimport type { Scope } from '../types-hoist';\nimport { addNonEnumerableProperty } from '../utils-hoist/object';\n\nconst SCOPE_ON_START_SPAN_FIELD = '_sentryScope';\nconst ISOLATION_SCOPE_ON_START_SPAN_FIELD = '_sentryIsolationScope';\n\ntype SpanWithScopes = Span & {\n  [SCOPE_ON_START_SPAN_FIELD]?: Scope;\n  [ISOLATION_SCOPE_ON_START_SPAN_FIELD]?: Scope;\n};\n\n/** Store the scope & isolation scope for a span, which can the be used when it is finished. */\nexport function setCapturedScopesOnSpan(span: Span | undefined, scope: Scope, isolationScope: Scope): void {\n  if (span) {\n    addNonEnumerableProperty(span, ISOLATION_SCOPE_ON_START_SPAN_FIELD, isolationScope);\n    addNonEnumerableProperty(span, SCOPE_ON_START_SPAN_FIELD, scope);\n  }\n}\n\n/**\n * Grabs the scope and isolation scope off a span that were active when the span was started.\n */\nexport function getCapturedScopesOnSpan(span: Span): { scope?: Scope; isolationScope?: Scope } {\n  return {\n    scope: (span as SpanWithScopes)[SCOPE_ON_START_SPAN_FIELD],\n    isolationScope: (span as SpanWithScopes)[ISOLATION_SCOPE_ON_START_SPAN_FIELD],\n  };\n}\n", "import { registerSpanErrorInstrumentation } from './errors';\n\n/**\n * @deprecated Use `registerSpanErrorInstrumentation()` instead. In v9, this function will be removed. Note that you don't need to call this in Node-based SDKs or when using `browserTracingIntegration`.\n */\nexport function addTracingExtensions(): void {\n  registerSpanErrorInstrumentation();\n}\n", "import { getClient } from '../currentScopes';\nimport type { Options } from '../types-hoist';\n\n// Treeshakable guard to remove all code related to tracing\ndeclare const __SENTRY_TRACING__: boolean | undefined;\n\n/**\n * Determines if tracing is currently enabled.\n *\n * Tracing is enabled when at least one of `tracesSampleRate` and `tracesSampler` is defined in the SDK config.\n */\nexport function hasTracingEnabled(\n  maybeOptions?: Pick<Options, 'tracesSampleRate' | 'tracesSampler' | 'enableTracing'> | undefined,\n): boolean {\n  if (typeof __SENTRY_TRACING__ === 'boolean' && !__SENTRY_TRACING__) {\n    return false;\n  }\n\n  const client = getClient();\n  const options = maybeOptions || (client && client.getOptions());\n  // eslint-disable-next-line deprecation/deprecation\n  return !!options && (options.enableTracing || 'tracesSampleRate' in options || 'tracesSampler' in options);\n}\n", "import type {\n  SentrySpanArguments,\n  Span,\n  SpanAttributeValue,\n  SpanAttributes,\n  SpanContextData,\n  SpanStatus,\n  SpanTimeInput,\n} from '../types-hoist';\nimport { generateSpanId, generateTraceId } from '../utils-hoist/propagationContext';\nimport { TRACE_FLAG_NONE } from '../utils/spanUtils';\n\n/**\n * A Sentry Span that is non-recording, meaning it will not be sent to Sentry.\n */\nexport class SentryNonRecordingSpan implements Span {\n  private _traceId: string;\n  private _spanId: string;\n\n  public constructor(spanContext: SentrySpanArguments = {}) {\n    this._traceId = spanContext.traceId || generateTraceId();\n    this._spanId = spanContext.spanId || generateSpanId();\n  }\n\n  /** @inheritdoc */\n  public spanContext(): SpanContextData {\n    return {\n      spanId: this._spanId,\n      traceId: this._traceId,\n      traceFlags: TRACE_FLAG_NONE,\n    };\n  }\n\n  /** @inheritdoc */\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  public end(_timestamp?: SpanTimeInput): void {}\n\n  /** @inheritdoc */\n  public setAttribute(_key: string, _value: SpanAttributeValue | undefined): this {\n    return this;\n  }\n\n  /** @inheritdoc */\n  public setAttributes(_values: SpanAttributes): this {\n    return this;\n  }\n\n  /** @inheritdoc */\n  public setStatus(_status: SpanStatus): this {\n    return this;\n  }\n\n  /** @inheritdoc */\n  public updateName(_name: string): this {\n    return this;\n  }\n\n  /** @inheritdoc */\n  public isRecording(): boolean {\n    return false;\n  }\n\n  /** @inheritdoc */\n  public addEvent(\n    _name: string,\n    _attributesOrStartTime?: SpanAttributes | SpanTimeInput,\n    _startTime?: SpanTimeInput,\n  ): this {\n    return this;\n  }\n\n  /**\n   * This should generally not be used,\n   * but we need it for being compliant with the OTEL Span interface.\n   *\n   * @hidden\n   * @internal\n   */\n  public addLink(_link: unknown): this {\n    return this;\n  }\n\n  /**\n   * This should generally not be used,\n   * but we need it for being compliant with the OTEL Span interface.\n   *\n   * @hidden\n   * @internal\n   */\n  public addLinks(_links: unknown[]): this {\n    return this;\n  }\n\n  /**\n   * This should generally not be used,\n   * but we need it for being compliant with the OTEL Span interface.\n   *\n   * @hidden\n   * @internal\n   */\n  public recordException(_exception: unknown, _time?: number | undefined): void {\n    // noop\n  }\n}\n", "import { isThenable } from '../utils-hoist/is';\n\n/**\n * Wrap a callback function with error handling.\n * If an error is thrown, it will be passed to the `onError` callback and re-thrown.\n *\n * If the return value of the function is a promise, it will be handled with `maybeHandlePromiseRejection`.\n *\n * If an `onFinally` callback is provided, this will be called when the callback has finished\n * - so if it returns a promise, once the promise resolved/rejected,\n * else once the callback has finished executing.\n * The `onFinally` callback will _always_ be called, no matter if an error was thrown or not.\n */\nexport function handleCallbackErrors<\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Fn extends () => any,\n>(\n  fn: Fn,\n  onError: (error: unknown) => void,\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\n  onFinally: () => void = () => {},\n): ReturnType<Fn> {\n  let maybePromiseResult: ReturnType<Fn>;\n  try {\n    maybePromiseResult = fn();\n  } catch (e) {\n    onError(e);\n    onFinally();\n    throw e;\n  }\n\n  return maybeHandlePromiseRejection(maybePromiseResult, onError, onFinally);\n}\n\n/**\n * Maybe handle a promise rejection.\n * This expects to be given a value that _may_ be a promise, or any other value.\n * If it is a promise, and it rejects, it will call the `onError` callback.\n * Other than this, it will generally return the given value as-is.\n */\nfunction maybeHandlePromiseRejection<MaybePromise>(\n  value: MaybePromise,\n  onError: (error: unknown) => void,\n  onFinally: () => void,\n): MaybePromise {\n  if (isThenable(value)) {\n    // @ts-expect-error - the isThenable check returns the \"wrong\" type here\n    return value.then(\n      res => {\n        onFinally();\n        return res;\n      },\n      e => {\n        onError(e);\n        onFinally();\n        throw e;\n      },\n    );\n  }\n\n  onFinally();\n  return value;\n}\n", "export const DEFAULT_ENVIRONMENT = 'production';\n", "import type { Client, DynamicSamplingContext, Scope, Span } from '../types-hoist';\n\nimport { DEFAULT_ENVIRONMENT } from '../constants';\nimport { getClient } from '../currentScopes';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes';\nimport {\n  baggageHeaderToDynamicSamplingContext,\n  dynamicSamplingContextToSentryBaggageHeader,\n} from '../utils-hoist/baggage';\nimport { addNonEnumerableProperty, dropUndefinedKeys } from '../utils-hoist/object';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled';\nimport { getRootSpan, spanIsSampled, spanToJSON } from '../utils/spanUtils';\n\n/**\n * If you change this value, also update the terser plugin config to\n * avoid minification of the object property!\n */\nconst FROZEN_DSC_FIELD = '_frozenDsc';\n\ntype SpanWithMaybeDsc = Span & {\n  [FROZEN_DSC_FIELD]?: Partial<DynamicSamplingContext> | undefined;\n};\n\n/**\n * Freeze the given DSC on the given span.\n */\nexport function freezeDscOnSpan(span: Span, dsc: Partial<DynamicSamplingContext>): void {\n  const spanWithMaybeDsc = span as SpanWithMaybeDsc;\n  addNonEnumerableProperty(spanWithMaybeDsc, FROZEN_DSC_FIELD, dsc);\n}\n\n/**\n * Creates a dynamic sampling context from a client.\n *\n * Dispatches the `createDsc` lifecycle hook as a side effect.\n */\nexport function getDynamicSamplingContextFromClient(trace_id: string, client: Client): DynamicSamplingContext {\n  const options = client.getOptions();\n\n  const { publicKey: public_key } = client.getDsn() || {};\n\n  const dsc = dropUndefinedKeys({\n    environment: options.environment || DEFAULT_ENVIRONMENT,\n    release: options.release,\n    public_key,\n    trace_id,\n  }) as DynamicSamplingContext;\n\n  client.emit('createDsc', dsc);\n\n  return dsc;\n}\n\n/**\n * Get the dynamic sampling context for the currently active scopes.\n */\nexport function getDynamicSamplingContextFromScope(client: Client, scope: Scope): Partial<DynamicSamplingContext> {\n  const propagationContext = scope.getPropagationContext();\n  return propagationContext.dsc || getDynamicSamplingContextFromClient(propagationContext.traceId, client);\n}\n\n/**\n * Creates a dynamic sampling context from a span (and client and scope)\n *\n * @param span the span from which a few values like the root span name and sample rate are extracted.\n *\n * @returns a dynamic sampling context\n */\nexport function getDynamicSamplingContextFromSpan(span: Span): Readonly<Partial<DynamicSamplingContext>> {\n  const client = getClient();\n  if (!client) {\n    return {};\n  }\n\n  const rootSpan = getRootSpan(span);\n\n  // For core implementation, we freeze the DSC onto the span as a non-enumerable property\n  const frozenDsc = (rootSpan as SpanWithMaybeDsc)[FROZEN_DSC_FIELD];\n  if (frozenDsc) {\n    return frozenDsc;\n  }\n\n  // For OpenTelemetry, we freeze the DSC on the trace state\n  const traceState = rootSpan.spanContext().traceState;\n  const traceStateDsc = traceState && traceState.get('sentry.dsc');\n\n  // If the span has a DSC, we want it to take precedence\n  const dscOnTraceState = traceStateDsc && baggageHeaderToDynamicSamplingContext(traceStateDsc);\n\n  if (dscOnTraceState) {\n    return dscOnTraceState;\n  }\n\n  // Else, we generate it from the span\n  const dsc = getDynamicSamplingContextFromClient(span.spanContext().traceId, client);\n  const jsonSpan = spanToJSON(rootSpan);\n  const attributes = jsonSpan.data || {};\n  const maybeSampleRate = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE];\n\n  if (maybeSampleRate != null) {\n    dsc.sample_rate = `${maybeSampleRate}`;\n  }\n\n  // We don't want to have a transaction name in the DSC if the source is \"url\" because URLs might contain PII\n  const source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n\n  // after JSON conversion, txn.name becomes jsonSpan.description\n  const name = jsonSpan.description;\n  if (source !== 'url' && name) {\n    dsc.transaction = name;\n  }\n\n  // How can we even land here with hasTracingEnabled() returning false?\n  // Otel creates a Non-recording span in Tracing Without Performance mode when handling incoming requests\n  // So we end up with an active span that is not sampled (neither positively nor negatively)\n  if (hasTracingEnabled()) {\n    dsc.sampled = String(spanIsSampled(rootSpan));\n  }\n\n  client.emit('createDsc', dsc, rootSpan);\n\n  return dsc;\n}\n\n/**\n * Convert a Span to a baggage header.\n */\nexport function spanToBaggageHeader(span: Span): string | undefined {\n  const dsc = getDynamicSamplingContextFromSpan(span);\n  return dynamicSamplingContextToSentryBaggageHeader(dsc);\n}\n", "import { DEBUG_BUILD } from '../debug-build';\nimport type { Span } from '../types-hoist';\nimport { logger } from '../utils-hoist/logger';\nimport { getRootSpan, spanIsSampled, spanToJSON } from '../utils/spanUtils';\n\n/**\n * Print a log message for a started span.\n */\nexport function logSpanStart(span: Span): void {\n  if (!DEBUG_BUILD) return;\n\n  const { description = '< unknown name >', op = '< unknown op >', parent_span_id: parentSpanId } = spanToJSON(span);\n  const { spanId } = span.spanContext();\n\n  const sampled = spanIsSampled(span);\n  const rootSpan = getRootSpan(span);\n  const isRootSpan = rootSpan === span;\n\n  const header = `[Tracing] Starting ${sampled ? 'sampled' : 'unsampled'} ${isRootSpan ? 'root ' : ''}span`;\n\n  const infoParts: string[] = [`op: ${op}`, `name: ${description}`, `ID: ${spanId}`];\n\n  if (parentSpanId) {\n    infoParts.push(`parent ID: ${parentSpanId}`);\n  }\n\n  if (!isRootSpan) {\n    const { op, description } = spanToJSON(rootSpan);\n    infoParts.push(`root ID: ${rootSpan.spanContext().spanId}`);\n    if (op) {\n      infoParts.push(`root op: ${op}`);\n    }\n    if (description) {\n      infoParts.push(`root description: ${description}`);\n    }\n  }\n\n  logger.log(`${header}\n  ${infoParts.join('\\n  ')}`);\n}\n\n/**\n * Print a log message for an ended span.\n */\nexport function logSpanEnd(span: Span): void {\n  if (!DEBUG_BUILD) return;\n\n  const { description = '< unknown name >', op = '< unknown op >' } = spanToJSON(span);\n  const { spanId } = span.spanContext();\n  const rootSpan = getRootSpan(span);\n  const isRootSpan = rootSpan === span;\n\n  const msg = `[Tracing] Finishing \"${op}\" ${isRootSpan ? 'root ' : ''}span \"${description}\" with ID ${spanId}`;\n  logger.log(msg);\n}\n", "import { DEBUG_BUILD } from '../debug-build';\nimport { logger } from '../utils-hoist/logger';\n\n/**\n * Parse a sample rate from a given value.\n * This will either return a boolean or number sample rate, if the sample rate is valid (between 0 and 1).\n * If a string is passed, we try to convert it to a number.\n *\n * Any invalid sample rate will return `undefined`.\n */\nexport function parseSampleRate(sampleRate: unknown): number | undefined {\n  if (typeof sampleRate === 'boolean') {\n    return Number(sampleRate);\n  }\n\n  const rate = typeof sampleRate === 'string' ? parseFloat(sampleRate) : sampleRate;\n  if (typeof rate !== 'number' || isNaN(rate) || rate < 0 || rate > 1) {\n    DEBUG_BUILD &&\n      logger.warn(\n        `[Tracing] Given sample rate is invalid. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(\n          sampleRate,\n        )} of type ${JSON.stringify(typeof sampleRate)}.`,\n      );\n    return undefined;\n  }\n\n  return rate;\n}\n", "import type { Options, RequestEventData, SamplingContext } from '../types-hoist';\n\nimport { getIsolationScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { logger } from '../utils-hoist/logger';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled';\nimport { parseSampleRate } from '../utils/parseSampleRate';\n\n/**\n * Makes a sampling decision for the given options.\n *\n * Called every time a root span is created. Only root spans which emerge with a `sampled` value of `true` will be\n * sent to Sentry.\n */\nexport function sampleSpan(\n  options: Pick<Options, 'tracesSampleRate' | 'tracesSampler' | 'enableTracing'>,\n  samplingContext: SamplingContext,\n): [sampled: boolean, sampleRate?: number] {\n  // nothing to do if tracing is not enabled\n  if (!hasTracingEnabled(options)) {\n    return [false];\n  }\n\n  // Casting this from unknown, as the type of `sdkProcessingMetadata` is only changed in v9 and `normalizedRequest` is set in SentryHttpInstrumentation\n  const normalizedRequest = getIsolationScope().getScopeData().sdkProcessingMetadata\n    .normalizedRequest as RequestEventData;\n\n  const enhancedSamplingContext = {\n    ...samplingContext,\n    normalizedRequest: samplingContext.normalizedRequest || normalizedRequest,\n  };\n\n  // we would have bailed already if neither `tracesSampler` nor `tracesSampleRate` nor `enableTracing` were defined, so one of these should\n  // work; prefer the hook if so\n  let sampleRate;\n  if (typeof options.tracesSampler === 'function') {\n    sampleRate = options.tracesSampler(enhancedSamplingContext);\n  } else if (enhancedSamplingContext.parentSampled !== undefined) {\n    sampleRate = enhancedSamplingContext.parentSampled;\n  } else if (typeof options.tracesSampleRate !== 'undefined') {\n    sampleRate = options.tracesSampleRate;\n  } else {\n    // When `enableTracing === true`, we use a sample rate of 100%\n    sampleRate = 1;\n  }\n\n  // Since this is coming from the user (or from a function provided by the user), who knows what we might get.\n  // (The only valid values are booleans or numbers between 0 and 1.)\n  const parsedSampleRate = parseSampleRate(sampleRate);\n\n  if (parsedSampleRate === undefined) {\n    DEBUG_BUILD && logger.warn('[Tracing] Discarding transaction because of invalid sample rate.');\n    return [false];\n  }\n\n  // if the function returned 0 (or false), or if `tracesSampleRate` is 0, it's a sign the transaction should be dropped\n  if (!parsedSampleRate) {\n    DEBUG_BUILD &&\n      logger.log(\n        `[Tracing] Discarding transaction because ${\n          typeof options.tracesSampler === 'function'\n            ? 'tracesSampler returned 0 or false'\n            : 'a negative sampling decision was inherited or tracesSampleRate is set to 0'\n        }`,\n      );\n    return [false, parsedSampleRate];\n  }\n\n  // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is\n  // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.\n  const shouldSample = Math.random() < parsedSampleRate;\n\n  // if we're not going to keep it, we're done\n  if (!shouldSample) {\n    DEBUG_BUILD &&\n      logger.log(\n        `[Tracing] Discarding transaction because it's not included in the random sample (sampling rate = ${Number(\n          sampleRate,\n        )})`,\n      );\n    return [false, parsedSampleRate];\n  }\n\n  return [true, parsedSampleRate];\n}\n", "import type { DsnComponents, DsnLike, DsnProtocol } from '../types-hoist';\n\nimport { DEBUG_BUILD } from './debug-build';\nimport { consoleSandbox, logger } from './logger';\n\n/** Regular expression used to parse a Dsn. */\nconst DSN_REGEX = /^(?:(\\w+):)\\/\\/(?:(\\w+)(?::(\\w+)?)?@)([\\w.-]+)(?::(\\d+))?\\/(.+)/;\n\nfunction isValidProtocol(protocol?: string): protocol is DsnProtocol {\n  return protocol === 'http' || protocol === 'https';\n}\n\n/**\n * Renders the string representation of this Dsn.\n *\n * By default, this will render the public representation without the password\n * component. To get the deprecated private representation, set `withPassword`\n * to true.\n *\n * @param withPassword When set to true, the password will be included.\n */\nexport function dsnToString(dsn: DsnComponents, withPassword: boolean = false): string {\n  const { host, path, pass, port, projectId, protocol, publicKey } = dsn;\n  return (\n    `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +\n    `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`\n  );\n}\n\n/**\n * Parses a Dsn from a given string.\n *\n * @param str A Dsn as string\n * @returns Dsn as DsnComponents or undefined if @param str is not a valid DSN string\n */\nexport function dsnFromString(str: string): DsnComponents | undefined {\n  const match = DSN_REGEX.exec(str);\n\n  if (!match) {\n    // This should be logged to the console\n    consoleSandbox(() => {\n      // eslint-disable-next-line no-console\n      console.error(`Invalid Sentry Dsn: ${str}`);\n    });\n    return undefined;\n  }\n\n  const [protocol, publicKey, pass = '', host = '', port = '', lastPath = ''] = match.slice(1);\n  let path = '';\n  let projectId = lastPath;\n\n  const split = projectId.split('/');\n  if (split.length > 1) {\n    path = split.slice(0, -1).join('/');\n    projectId = split.pop() as string;\n  }\n\n  if (projectId) {\n    const projectMatch = projectId.match(/^\\d+/);\n    if (projectMatch) {\n      projectId = projectMatch[0];\n    }\n  }\n\n  return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol as DsnProtocol, publicKey });\n}\n\nfunction dsnFromComponents(components: DsnComponents): DsnComponents {\n  return {\n    protocol: components.protocol,\n    publicKey: components.publicKey || '',\n    pass: components.pass || '',\n    host: components.host,\n    port: components.port || '',\n    path: components.path || '',\n    projectId: components.projectId,\n  };\n}\n\nfunction validateDsn(dsn: DsnComponents): boolean {\n  if (!DEBUG_BUILD) {\n    return true;\n  }\n\n  const { port, projectId, protocol } = dsn;\n\n  const requiredComponents: ReadonlyArray<keyof DsnComponents> = ['protocol', 'publicKey', 'host', 'projectId'];\n  const hasMissingRequiredComponent = requiredComponents.find(component => {\n    if (!dsn[component]) {\n      logger.error(`Invalid Sentry Dsn: ${component} missing`);\n      return true;\n    }\n    return false;\n  });\n\n  if (hasMissingRequiredComponent) {\n    return false;\n  }\n\n  if (!projectId.match(/^\\d+$/)) {\n    logger.error(`Invalid Sentry Dsn: Invalid projectId ${projectId}`);\n    return false;\n  }\n\n  if (!isValidProtocol(protocol)) {\n    logger.error(`Invalid Sentry Dsn: Invalid protocol ${protocol}`);\n    return false;\n  }\n\n  if (port && isNaN(parseInt(port, 10))) {\n    logger.error(`Invalid Sentry Dsn: Invalid port ${port}`);\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Creates a valid Sentry Dsn object, identifying a Sentry instance and project.\n * @returns a valid DsnComponents object or `undefined` if @param from is an invalid DSN source\n */\nexport function makeDsn(from: DsnLike): DsnComponents | undefined {\n  const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);\n  if (!components || !validateDsn(components)) {\n    return undefined;\n  }\n  return components;\n}\n", "/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport type MemoFunc = [\n  // memoize\n  (obj: any) => boolean,\n  // unmemoize\n  (obj: any) => void,\n];\n\n/**\n * Helper to decycle json objects\n *\n * @deprecated This function is deprecated and will be removed in the next major version.\n */\n// TODO(v9): Move this function into normalize() directly\nexport function memoBuilder(): MemoFunc {\n  const hasWeakSet = typeof WeakSet === 'function';\n  const inner: any = hasWeakSet ? new WeakSet() : [];\n  function memoize(obj: any): boolean {\n    if (hasWeakSet) {\n      if (inner.has(obj)) {\n        return true;\n      }\n      inner.add(obj);\n      return false;\n    }\n    // eslint-disable-next-line @typescript-eslint/prefer-for-of\n    for (let i = 0; i < inner.length; i++) {\n      const value = inner[i];\n      if (value === obj) {\n        return true;\n      }\n    }\n    inner.push(obj);\n    return false;\n  }\n\n  function unmemoize(obj: any): void {\n    if (hasWeakSet) {\n      inner.delete(obj);\n    } else {\n      for (let i = 0; i < inner.length; i++) {\n        if (inner[i] === obj) {\n          inner.splice(i, 1);\n          break;\n        }\n      }\n    }\n  }\n  return [memoize, unmemoize];\n}\n", "import type { Primitive } from '../types-hoist';\n\nimport { isSyntheticEvent, isVueViewModel } from './is';\nimport type { MemoFunc } from './memo';\nimport { memoBuilder } from './memo';\nimport { convertToPlainObject } from './object';\nimport { getFunctionName } from './stacktrace';\n\ntype Prototype = { constructor: (...args: unknown[]) => unknown };\n// This is a hack to placate TS, relying on the fact that technically, arrays are objects with integer keys. Normally we\n// think of those keys as actual numbers, but `arr['0']` turns out to work just as well as `arr[0]`, and doing it this\n// way lets us use a single type in the places where behave as if we are only dealing with objects, even if some of them\n// might be arrays.\ntype ObjOrArray<T> = { [key: string]: T };\n\n/**\n * Recursively normalizes the given object.\n *\n * - Creates a copy to prevent original input mutation\n * - Skips non-enumerable properties\n * - When stringifying, calls `toJSON` if implemented\n * - Removes circular references\n * - Translates non-serializable values (`undefined`/`NaN`/functions) to serializable format\n * - Translates known global objects/classes to a string representations\n * - Takes care of `Error` object serialization\n * - Optionally limits depth of final output\n * - Optionally limits number of properties/elements included in any single object/array\n *\n * @param input The object to be normalized.\n * @param depth The max depth to which to normalize the object. (Anything deeper stringified whole.)\n * @param maxProperties The max number of elements or properties to be included in any single array or\n * object in the normalized output.\n * @returns A normalized version of the object, or `\"**non-serializable**\"` if any errors are thrown during normalization.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function normalize(input: unknown, depth: number = 100, maxProperties: number = +Infinity): any {\n  try {\n    // since we're at the outermost level, we don't provide a key\n    return visit('', input, depth, maxProperties);\n  } catch (err) {\n    return { ERROR: `**non-serializable** (${err})` };\n  }\n}\n\n/** JSDoc */\nexport function normalizeToSize<T>(\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  object: { [key: string]: any },\n  // Default Node.js REPL depth\n  depth: number = 3,\n  // 100kB, as 200kB is max payload size, so half sounds reasonable\n  maxSize: number = 100 * 1024,\n): T {\n  const normalized = normalize(object, depth);\n\n  if (jsonSize(normalized) > maxSize) {\n    return normalizeToSize(object, depth - 1, maxSize);\n  }\n\n  return normalized as T;\n}\n\n/**\n * Visits a node to perform normalization on it\n *\n * @param key The key corresponding to the given node\n * @param value The node to be visited\n * @param depth Optional number indicating the maximum recursion depth\n * @param maxProperties Optional maximum number of properties/elements included in any single object/array\n * @param memo Optional Memo class handling decycling\n */\nfunction visit(\n  key: string,\n  value: unknown,\n  depth: number = +Infinity,\n  maxProperties: number = +Infinity,\n  // eslint-disable-next-line deprecation/deprecation\n  memo: MemoFunc = memoBuilder(),\n): Primitive | ObjOrArray<unknown> {\n  const [memoize, unmemoize] = memo;\n\n  // Get the simple cases out of the way first\n  if (\n    value == null || // this matches null and undefined -> eqeq not eqeqeq\n    ['boolean', 'string'].includes(typeof value) ||\n    (typeof value === 'number' && Number.isFinite(value))\n  ) {\n    return value as Primitive;\n  }\n\n  const stringified = stringifyValue(key, value);\n\n  // Anything we could potentially dig into more (objects or arrays) will have come back as `\"[object XXXX]\"`.\n  // Everything else will have already been serialized, so if we don't see that pattern, we're done.\n  if (!stringified.startsWith('[object ')) {\n    return stringified;\n  }\n\n  // From here on, we can assert that `value` is either an object or an array.\n\n  // Do not normalize objects that we know have already been normalized. As a general rule, the\n  // \"__sentry_skip_normalization__\" property should only be used sparingly and only should only be set on objects that\n  // have already been normalized.\n  if ((value as ObjOrArray<unknown>)['__sentry_skip_normalization__']) {\n    return value as ObjOrArray<unknown>;\n  }\n\n  // We can set `__sentry_override_normalization_depth__` on an object to ensure that from there\n  // We keep a certain amount of depth.\n  // This should be used sparingly, e.g. we use it for the redux integration to ensure we get a certain amount of state.\n  const remainingDepth =\n    typeof (value as ObjOrArray<unknown>)['__sentry_override_normalization_depth__'] === 'number'\n      ? ((value as ObjOrArray<unknown>)['__sentry_override_normalization_depth__'] as number)\n      : depth;\n\n  // We're also done if we've reached the max depth\n  if (remainingDepth === 0) {\n    // At this point we know `serialized` is a string of the form `\"[object XXXX]\"`. Clean it up so it's just `\"[XXXX]\"`.\n    return stringified.replace('object ', '');\n  }\n\n  // If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.\n  if (memoize(value)) {\n    return '[Circular ~]';\n  }\n\n  // If the value has a `toJSON` method, we call it to extract more information\n  const valueWithToJSON = value as unknown & { toJSON?: () => unknown };\n  if (valueWithToJSON && typeof valueWithToJSON.toJSON === 'function') {\n    try {\n      const jsonValue = valueWithToJSON.toJSON();\n      // We need to normalize the return value of `.toJSON()` in case it has circular references\n      return visit('', jsonValue, remainingDepth - 1, maxProperties, memo);\n    } catch (err) {\n      // pass (The built-in `toJSON` failed, but we can still try to do it ourselves)\n    }\n  }\n\n  // At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse\n  // because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each\n  // property/entry, and keep track of the number of items we add to it.\n  const normalized = (Array.isArray(value) ? [] : {}) as ObjOrArray<unknown>;\n  let numAdded = 0;\n\n  // Before we begin, convert`Error` and`Event` instances into plain objects, since some of each of their relevant\n  // properties are non-enumerable and otherwise would get missed.\n  const visitable = convertToPlainObject(value as ObjOrArray<unknown>);\n\n  for (const visitKey in visitable) {\n    // Avoid iterating over fields in the prototype if they've somehow been exposed to enumeration.\n    if (!Object.prototype.hasOwnProperty.call(visitable, visitKey)) {\n      continue;\n    }\n\n    if (numAdded >= maxProperties) {\n      normalized[visitKey] = '[MaxProperties ~]';\n      break;\n    }\n\n    // Recursively visit all the child nodes\n    const visitValue = visitable[visitKey];\n    normalized[visitKey] = visit(visitKey, visitValue, remainingDepth - 1, maxProperties, memo);\n\n    numAdded++;\n  }\n\n  // Once we've visited all the branches, remove the parent from memo storage\n  unmemoize(value);\n\n  // Return accumulated values\n  return normalized;\n}\n\n/* eslint-disable complexity */\n/**\n * Stringify the given value. Handles various known special values and types.\n *\n * Not meant to be used on simple primitives which already have a string representation, as it will, for example, turn\n * the number 1231 into \"[Object Number]\", nor on `null`, as it will throw.\n *\n * @param value The value to stringify\n * @returns A stringified representation of the given value\n */\nfunction stringifyValue(\n  key: unknown,\n  // this type is a tiny bit of a cheat, since this function does handle NaN (which is technically a number), but for\n  // our internal use, it'll do\n  value: Exclude<unknown, string | number | boolean | null>,\n): string {\n  try {\n    if (key === 'domain' && value && typeof value === 'object' && (value as { _events: unknown })._events) {\n      return '[Domain]';\n    }\n\n    if (key === 'domainEmitter') {\n      return '[DomainEmitter]';\n    }\n\n    // It's safe to use `global`, `window`, and `document` here in this manner, as we are asserting using `typeof` first\n    // which won't throw if they are not present.\n\n    if (typeof global !== 'undefined' && value === global) {\n      return '[Global]';\n    }\n\n    // eslint-disable-next-line no-restricted-globals\n    if (typeof window !== 'undefined' && value === window) {\n      return '[Window]';\n    }\n\n    // eslint-disable-next-line no-restricted-globals\n    if (typeof document !== 'undefined' && value === document) {\n      return '[Document]';\n    }\n\n    if (isVueViewModel(value)) {\n      return '[VueViewModel]';\n    }\n\n    // React's SyntheticEvent thingy\n    if (isSyntheticEvent(value)) {\n      return '[SyntheticEvent]';\n    }\n\n    if (typeof value === 'number' && !Number.isFinite(value)) {\n      return `[${value}]`;\n    }\n\n    if (typeof value === 'function') {\n      return `[Function: ${getFunctionName(value)}]`;\n    }\n\n    if (typeof value === 'symbol') {\n      return `[${String(value)}]`;\n    }\n\n    // stringified BigInts are indistinguishable from regular numbers, so we need to label them to avoid confusion\n    if (typeof value === 'bigint') {\n      return `[BigInt: ${String(value)}]`;\n    }\n\n    // Now that we've knocked out all the special cases and the primitives, all we have left are objects. Simply casting\n    // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as\n    // `\"[object Object]\"`. If we instead look at the constructor's name (which is the same as the name of the class),\n    // we can make sure that only plain objects come out that way.\n    const objName = getConstructorName(value);\n\n    // Handle HTML Elements\n    if (/^HTML(\\w*)Element$/.test(objName)) {\n      return `[HTMLElement: ${objName}]`;\n    }\n\n    return `[object ${objName}]`;\n  } catch (err) {\n    return `**non-serializable** (${err})`;\n  }\n}\n/* eslint-enable complexity */\n\nfunction getConstructorName(value: unknown): string {\n  const prototype: Prototype | null = Object.getPrototypeOf(value);\n\n  return prototype ? prototype.constructor.name : 'null prototype';\n}\n\n/** Calculates bytes size of input string */\nfunction utf8Length(value: string): number {\n  // eslint-disable-next-line no-bitwise\n  return ~-encodeURI(value).split(/%..|./).length;\n}\n\n/** Calculates bytes size of input object */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction jsonSize(value: any): number {\n  return utf8Length(JSON.stringify(value));\n}\n\n/**\n * Normalizes URLs in exceptions and stacktraces to a base path so Sentry can fingerprint\n * across platforms and working directory.\n *\n * @param url The URL to be normalized.\n * @param basePath The application base path.\n * @returns The normalized URL.\n */\nexport function normalizeUrlToBase(url: string, basePath: string): string {\n  const escapedBase = basePath\n    // Backslash to forward\n    .replace(/\\\\/g, '/')\n    // Escape RegExp special characters\n    .replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');\n\n  let newUrl = url;\n  try {\n    newUrl = decodeURI(url);\n  } catch (_Oo) {\n    // Sometime this breaks\n  }\n  return (\n    newUrl\n      .replace(/\\\\/g, '/')\n      .replace(/webpack:\\/?/g, '') // Remove intermediate base path\n      // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor\n      .replace(new RegExp(`(file://)?/*${escapedBase}/*`, 'ig'), 'app:///')\n  );\n}\n", "import type {\n  Attachment,\n  AttachmentItem,\n  BaseEnvelopeHeaders,\n  BaseEnvelopeItemHeaders,\n  DataCategory,\n  DsnComponents,\n  Envelope,\n  EnvelopeItemType,\n  Event,\n  EventEnvelopeHeaders,\n  SdkInfo,\n  SdkMetadata,\n  SpanItem,\n  SpanJSON,\n} from '../types-hoist';\n\nimport { dsnToString } from './dsn';\nimport { normalize } from './normalize';\nimport { dropUndefinedKeys } from './object';\nimport { GLOBAL_OBJ } from './worldwide';\n\n/**\n * Creates an envelope.\n * Make sure to always explicitly provide the generic to this function\n * so that the envelope types resolve correctly.\n */\nexport function createEnvelope<E extends Envelope>(headers: E[0], items: E[1] = []): E {\n  return [headers, items] as E;\n}\n\n/**\n * Add an item to an envelope.\n * Make sure to always explicitly provide the generic to this function\n * so that the envelope types resolve correctly.\n */\nexport function addItemToEnvelope<E extends Envelope>(envelope: E, newItem: E[1][number]): E {\n  const [headers, items] = envelope;\n  return [headers, [...items, newItem]] as unknown as E;\n}\n\n/**\n * Convenience function to loop through the items and item types of an envelope.\n * (This function was mostly created because working with envelope types is painful at the moment)\n *\n * If the callback returns true, the rest of the items will be skipped.\n */\nexport function forEachEnvelopeItem<E extends Envelope>(\n  envelope: Envelope,\n  callback: (envelopeItem: E[1][number], envelopeItemType: E[1][number][0]['type']) => boolean | void,\n): boolean {\n  const envelopeItems = envelope[1];\n\n  for (const envelopeItem of envelopeItems) {\n    const envelopeItemType = envelopeItem[0].type;\n    const result = callback(envelopeItem, envelopeItemType);\n\n    if (result) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Returns true if the envelope contains any of the given envelope item types\n */\nexport function envelopeContainsItemType(envelope: Envelope, types: EnvelopeItemType[]): boolean {\n  return forEachEnvelopeItem(envelope, (_, type) => types.includes(type));\n}\n\n/**\n * Encode a string to UTF8 array.\n */\nfunction encodeUTF8(input: string): Uint8Array {\n  return GLOBAL_OBJ.__SENTRY__ && GLOBAL_OBJ.__SENTRY__.encodePolyfill\n    ? GLOBAL_OBJ.__SENTRY__.encodePolyfill(input)\n    : new TextEncoder().encode(input);\n}\n\n/**\n * Decode a UTF8 array to string.\n */\nfunction decodeUTF8(input: Uint8Array): string {\n  return GLOBAL_OBJ.__SENTRY__ && GLOBAL_OBJ.__SENTRY__.decodePolyfill\n    ? GLOBAL_OBJ.__SENTRY__.decodePolyfill(input)\n    : new TextDecoder().decode(input);\n}\n\n/**\n * Serializes an envelope.\n */\nexport function serializeEnvelope(envelope: Envelope): string | Uint8Array {\n  const [envHeaders, items] = envelope;\n\n  // Initially we construct our envelope as a string and only convert to binary chunks if we encounter binary data\n  let parts: string | Uint8Array[] = JSON.stringify(envHeaders);\n\n  function append(next: string | Uint8Array): void {\n    if (typeof parts === 'string') {\n      parts = typeof next === 'string' ? parts + next : [encodeUTF8(parts), next];\n    } else {\n      parts.push(typeof next === 'string' ? encodeUTF8(next) : next);\n    }\n  }\n\n  for (const item of items) {\n    const [itemHeaders, payload] = item;\n\n    append(`\\n${JSON.stringify(itemHeaders)}\\n`);\n\n    if (typeof payload === 'string' || payload instanceof Uint8Array) {\n      append(payload);\n    } else {\n      let stringifiedPayload: string;\n      try {\n        stringifiedPayload = JSON.stringify(payload);\n      } catch (e) {\n        // In case, despite all our efforts to keep `payload` circular-dependency-free, `JSON.stringify()` still\n        // fails, we try again after normalizing it again with infinite normalization depth. This of course has a\n        // performance impact but in this case a performance hit is better than throwing.\n        stringifiedPayload = JSON.stringify(normalize(payload));\n      }\n      append(stringifiedPayload);\n    }\n  }\n\n  return typeof parts === 'string' ? parts : concatBuffers(parts);\n}\n\nfunction concatBuffers(buffers: Uint8Array[]): Uint8Array {\n  const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0);\n\n  const merged = new Uint8Array(totalLength);\n  let offset = 0;\n  for (const buffer of buffers) {\n    merged.set(buffer, offset);\n    offset += buffer.length;\n  }\n\n  return merged;\n}\n\n/**\n * Parses an envelope\n */\nexport function parseEnvelope(env: string | Uint8Array): Envelope {\n  let buffer = typeof env === 'string' ? encodeUTF8(env) : env;\n\n  function readBinary(length: number): Uint8Array {\n    const bin = buffer.subarray(0, length);\n    // Replace the buffer with the remaining data excluding trailing newline\n    buffer = buffer.subarray(length + 1);\n    return bin;\n  }\n\n  function readJson<T>(): T {\n    let i = buffer.indexOf(0xa);\n    // If we couldn't find a newline, we must have found the end of the buffer\n    if (i < 0) {\n      i = buffer.length;\n    }\n\n    return JSON.parse(decodeUTF8(readBinary(i))) as T;\n  }\n\n  const envelopeHeader = readJson<BaseEnvelopeHeaders>();\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const items: [any, any][] = [];\n\n  while (buffer.length) {\n    const itemHeader = readJson<BaseEnvelopeItemHeaders>();\n    const binaryLength = typeof itemHeader.length === 'number' ? itemHeader.length : undefined;\n\n    items.push([itemHeader, binaryLength ? readBinary(binaryLength) : readJson()]);\n  }\n\n  return [envelopeHeader, items];\n}\n\n/**\n * Creates envelope item for a single span\n */\nexport function createSpanEnvelopeItem(spanJson: Partial<SpanJSON>): SpanItem {\n  const spanHeaders: SpanItem[0] = {\n    type: 'span',\n  };\n\n  return [spanHeaders, spanJson];\n}\n\n/**\n * Creates attachment envelope items\n */\nexport function createAttachmentEnvelopeItem(attachment: Attachment): AttachmentItem {\n  const buffer = typeof attachment.data === 'string' ? encodeUTF8(attachment.data) : attachment.data;\n\n  return [\n    dropUndefinedKeys({\n      type: 'attachment',\n      length: buffer.length,\n      filename: attachment.filename,\n      content_type: attachment.contentType,\n      attachment_type: attachment.attachmentType,\n    }),\n    buffer,\n  ];\n}\n\nconst ITEM_TYPE_TO_DATA_CATEGORY_MAP: Record<EnvelopeItemType, DataCategory> = {\n  session: 'session',\n  sessions: 'session',\n  attachment: 'attachment',\n  transaction: 'transaction',\n  event: 'error',\n  client_report: 'internal',\n  user_report: 'default',\n  profile: 'profile',\n  profile_chunk: 'profile',\n  replay_event: 'replay',\n  replay_recording: 'replay',\n  check_in: 'monitor',\n  feedback: 'feedback',\n  span: 'span',\n  statsd: 'metric_bucket',\n  raw_security: 'security',\n};\n\n/**\n * Maps the type of an envelope item to a data category.\n */\nexport function envelopeItemTypeToDataCategory(type: EnvelopeItemType): DataCategory {\n  return ITEM_TYPE_TO_DATA_CATEGORY_MAP[type];\n}\n\n/** Extracts the minimal SDK info from the metadata or an events */\nexport function getSdkMetadataForEnvelopeHeader(metadataOrEvent?: SdkMetadata | Event): SdkInfo | undefined {\n  if (!metadataOrEvent || !metadataOrEvent.sdk) {\n    return;\n  }\n  const { name, version } = metadataOrEvent.sdk;\n  return { name, version };\n}\n\n/**\n * Creates event envelope headers, based on event, sdk info and tunnel\n * Note: This function was extracted from the core package to make it available in Replay\n */\nexport function createEventEnvelopeHeaders(\n  event: Event,\n  sdkInfo: SdkInfo | undefined,\n  tunnel: string | undefined,\n  dsn?: DsnComponents,\n): EventEnvelopeHeaders {\n  const dynamicSamplingContext = event.sdkProcessingMetadata && event.sdkProcessingMetadata.dynamicSamplingContext;\n  return {\n    event_id: event.event_id as string,\n    sent_at: new Date().toISOString(),\n    ...(sdkInfo && { sdk: sdkInfo }),\n    ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n    ...(dynamicSamplingContext && {\n      trace: dropUndefinedKeys({ ...dynamicSamplingContext }),\n    }),\n  };\n}\n", "import { getDynamicSamplingContextFromSpan } from './tracing/dynamicSamplingContext';\nimport type { SentrySpan } from './tracing/sentrySpan';\nimport type {\n  Client,\n  DsnComponents,\n  DynamicSamplingContext,\n  Event,\n  EventEnvelope,\n  EventItem,\n  LegacyCSPReport,\n  RawSecurityEnvelope,\n  RawSecurityItem,\n  SdkInfo,\n  SdkMetadata,\n  Session,\n  SessionAggregates,\n  SessionEnvelope,\n  SessionItem,\n  SpanEnvelope,\n  SpanItem,\n  SpanJSON,\n} from './types-hoist';\nimport { dsnToString } from './utils-hoist/dsn';\nimport {\n  createEnvelope,\n  createEventEnvelopeHeaders,\n  createSpanEnvelopeItem,\n  getSdkMetadataForEnvelopeHeader,\n} from './utils-hoist/envelope';\nimport { uuid4 } from './utils-hoist/misc';\nimport { showSpanDropWarning, spanToJSON } from './utils/spanUtils';\n\n/**\n * Apply SdkInfo (name, version, packages, integrations) to the corresponding event key.\n * Merge with existing data if any.\n **/\nfunction enhanceEventWithSdkInfo(event: Event, sdkInfo?: SdkInfo): Event {\n  if (!sdkInfo) {\n    return event;\n  }\n  event.sdk = event.sdk || {};\n  event.sdk.name = event.sdk.name || sdkInfo.name;\n  event.sdk.version = event.sdk.version || sdkInfo.version;\n  event.sdk.integrations = [...(event.sdk.integrations || []), ...(sdkInfo.integrations || [])];\n  event.sdk.packages = [...(event.sdk.packages || []), ...(sdkInfo.packages || [])];\n  return event;\n}\n\n/** Creates an envelope from a Session */\nexport function createSessionEnvelope(\n  session: Session | SessionAggregates,\n  dsn?: DsnComponents,\n  metadata?: SdkMetadata,\n  tunnel?: string,\n): SessionEnvelope {\n  const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);\n  const envelopeHeaders = {\n    sent_at: new Date().toISOString(),\n    ...(sdkInfo && { sdk: sdkInfo }),\n    ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n  };\n\n  const envelopeItem: SessionItem =\n    'aggregates' in session ? [{ type: 'sessions' }, session] : [{ type: 'session' }, session.toJSON()];\n\n  return createEnvelope<SessionEnvelope>(envelopeHeaders, [envelopeItem]);\n}\n\n/**\n * Create an Envelope from an event.\n */\nexport function createEventEnvelope(\n  event: Event,\n  dsn?: DsnComponents,\n  metadata?: SdkMetadata,\n  tunnel?: string,\n): EventEnvelope {\n  const sdkInfo = getSdkMetadataForEnvelopeHeader(metadata);\n\n  /*\n    Note: Due to TS, event.type may be `replay_event`, theoretically.\n    In practice, we never call `createEventEnvelope` with `replay_event` type,\n    and we'd have to adjust a looot of types to make this work properly.\n    We want to avoid casting this around, as that could lead to bugs (e.g. when we add another type)\n    So the safe choice is to really guard against the replay_event type here.\n  */\n  const eventType = event.type && event.type !== 'replay_event' ? event.type : 'event';\n\n  enhanceEventWithSdkInfo(event, metadata && metadata.sdk);\n\n  const envelopeHeaders = createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn);\n\n  // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to\n  // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may\n  // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid\n  // of this `delete`, lest we miss putting it back in the next time the property is in use.)\n  delete event.sdkProcessingMetadata;\n\n  const eventItem: EventItem = [{ type: eventType }, event];\n  return createEnvelope<EventEnvelope>(envelopeHeaders, [eventItem]);\n}\n\n/**\n * Create envelope from Span item.\n *\n * Takes an optional client and runs spans through `beforeSendSpan` if available.\n */\nexport function createSpanEnvelope(spans: [SentrySpan, ...SentrySpan[]], client?: Client): SpanEnvelope {\n  function dscHasRequiredProps(dsc: Partial<DynamicSamplingContext>): dsc is DynamicSamplingContext {\n    return !!dsc.trace_id && !!dsc.public_key;\n  }\n\n  // For the moment we'll obtain the DSC from the first span in the array\n  // This might need to be changed if we permit sending multiple spans from\n  // different segments in one envelope\n  const dsc = getDynamicSamplingContextFromSpan(spans[0]);\n\n  const dsn = client && client.getDsn();\n  const tunnel = client && client.getOptions().tunnel;\n\n  const headers: SpanEnvelope[0] = {\n    sent_at: new Date().toISOString(),\n    ...(dscHasRequiredProps(dsc) && { trace: dsc }),\n    ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n  };\n\n  const beforeSendSpan = client && client.getOptions().beforeSendSpan;\n  const convertToSpanJSON = beforeSendSpan\n    ? (span: SentrySpan) => {\n        const spanJson = beforeSendSpan(spanToJSON(span) as SpanJSON);\n        if (!spanJson) {\n          showSpanDropWarning();\n        }\n        return spanJson;\n      }\n    : (span: SentrySpan) => spanToJSON(span);\n\n  const items: SpanItem[] = [];\n  for (const span of spans) {\n    const spanJson = convertToSpanJSON(span);\n    if (spanJson) {\n      items.push(createSpanEnvelopeItem(spanJson));\n    }\n  }\n\n  return createEnvelope<SpanEnvelope>(headers, items);\n}\n\n/**\n * Create an Envelope from a CSP report.\n */\nexport function createRawSecurityEnvelope(\n  report: LegacyCSPReport,\n  dsn: DsnComponents,\n  tunnel?: string,\n  release?: string,\n  environment?: string,\n): RawSecurityEnvelope {\n  const envelopeHeaders = {\n    event_id: uuid4(),\n    ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }),\n  };\n\n  const eventItem: RawSecurityItem = [\n    { type: 'raw_security', sentry_release: release, sentry_environment: environment },\n    report,\n  ];\n\n  return createEnvelope<RawSecurityEnvelope>(envelopeHeaders, [eventItem]);\n}\n", "import { DEBUG_BUILD } from '../debug-build';\nimport {\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n} from '../semanticAttributes';\nimport type { MeasurementUnit, Measurements, TimedEvent } from '../types-hoist';\nimport { logger } from '../utils-hoist/logger';\nimport { getActiveSpan, getRootSpan } from '../utils/spanUtils';\n\n/**\n * Adds a measurement to the active transaction on the current global scope. You can optionally pass in a different span\n * as the 4th parameter.\n */\nexport function setMeasurement(name: string, value: number, unit: MeasurementUnit, activeSpan = getActiveSpan()): void {\n  const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n  if (rootSpan) {\n    DEBUG_BUILD && logger.log(`[Measurement] Setting measurement on root span: ${name} = ${value} ${unit}`);\n    rootSpan.addEvent(name, {\n      [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: value,\n      [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: unit as string,\n    });\n  }\n}\n\n/**\n * Convert timed events to measurements.\n */\nexport function timedEventsToMeasurements(events: TimedEvent[]): Measurements | undefined {\n  if (!events || events.length === 0) {\n    return undefined;\n  }\n\n  const measurements: Measurements = {};\n  events.forEach(event => {\n    const attributes = event.attributes || {};\n    const unit = attributes[SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT] as MeasurementUnit | undefined;\n    const value = attributes[SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE] as number | undefined;\n\n    if (typeof unit === 'string' && typeof value === 'number') {\n      measurements[event.name] = { value, unit };\n    }\n  });\n\n  return measurements;\n}\n", "import { getClient, getCurrentScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { createSpanEnvelope } from '../envelope';\nimport { getMetricSummaryJsonForSpan } from '../metrics/metric-summary';\nimport {\n  SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME,\n  SEMANTIC_ATTRIBUTE_PROFILE_ID,\n  SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n  SEMANTIC_ATTRIBUTE_SENTRY_OP,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '../semanticAttributes';\nimport type {\n  SentrySpanArguments,\n  Span,\n  SpanAttributeValue,\n  SpanAttributes,\n  SpanContextData,\n  SpanEnvelope,\n  SpanJSON,\n  SpanOrigin,\n  SpanStatus,\n  SpanTimeInput,\n  TimedEvent,\n  TransactionEvent,\n  TransactionSource,\n} from '../types-hoist';\nimport { logger } from '../utils-hoist/logger';\nimport { dropUndefinedKeys } from '../utils-hoist/object';\nimport { generateSpanId, generateTraceId } from '../utils-hoist/propagationContext';\nimport { timestampInSeconds } from '../utils-hoist/time';\nimport {\n  TRACE_FLAG_NONE,\n  TRACE_FLAG_SAMPLED,\n  getRootSpan,\n  getSpanDescendants,\n  getStatusMessage,\n  spanTimeInputToSeconds,\n  spanToJSON,\n  spanToTransactionTraceContext,\n} from '../utils/spanUtils';\nimport { getDynamicSamplingContextFromSpan } from './dynamicSamplingContext';\nimport { logSpanEnd } from './logSpans';\nimport { timedEventsToMeasurements } from './measurement';\nimport { getCapturedScopesOnSpan } from './utils';\n\nconst MAX_SPAN_COUNT = 1000;\n\n/**\n * Span contains all data about a span\n */\nexport class SentrySpan implements Span {\n  protected _traceId: string;\n  protected _spanId: string;\n  protected _parentSpanId?: string | undefined;\n  protected _sampled: boolean | undefined;\n  protected _name?: string | undefined;\n  protected _attributes: SpanAttributes;\n  /** Epoch timestamp in seconds when the span started. */\n  protected _startTime: number;\n  /** Epoch timestamp in seconds when the span ended. */\n  protected _endTime?: number | undefined;\n  /** Internal keeper of the status */\n  protected _status?: SpanStatus;\n  /** The timed events added to this span. */\n  protected _events: TimedEvent[];\n\n  /** if true, treat span as a standalone span (not part of a transaction) */\n  private _isStandaloneSpan?: boolean;\n\n  /**\n   * You should never call the constructor manually, always use `Sentry.startSpan()`\n   * or other span methods.\n   * @internal\n   * @hideconstructor\n   * @hidden\n   */\n  public constructor(spanContext: SentrySpanArguments = {}) {\n    this._traceId = spanContext.traceId || generateTraceId();\n    this._spanId = spanContext.spanId || generateSpanId();\n    this._startTime = spanContext.startTimestamp || timestampInSeconds();\n\n    this._attributes = {};\n    this.setAttributes({\n      [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual',\n      [SEMANTIC_ATTRIBUTE_SENTRY_OP]: spanContext.op,\n      ...spanContext.attributes,\n    });\n\n    this._name = spanContext.name;\n\n    if (spanContext.parentSpanId) {\n      this._parentSpanId = spanContext.parentSpanId;\n    }\n    // We want to include booleans as well here\n    if ('sampled' in spanContext) {\n      this._sampled = spanContext.sampled;\n    }\n    if (spanContext.endTimestamp) {\n      this._endTime = spanContext.endTimestamp;\n    }\n\n    this._events = [];\n\n    this._isStandaloneSpan = spanContext.isStandalone;\n\n    // If the span is already ended, ensure we finalize the span immediately\n    if (this._endTime) {\n      this._onSpanEnded();\n    }\n  }\n\n  /**\n   * This should generally not be used,\n   * but it is needed for being compliant with the OTEL Span interface.\n   *\n   * @hidden\n   * @internal\n   */\n  public addLink(_link: unknown): this {\n    return this;\n  }\n\n  /**\n   * This should generally not be used,\n   * but it is needed for being compliant with the OTEL Span interface.\n   *\n   * @hidden\n   * @internal\n   */\n  public addLinks(_links: unknown[]): this {\n    return this;\n  }\n\n  /**\n   * This should generally not be used,\n   * but it is needed for being compliant with the OTEL Span interface.\n   *\n   * @hidden\n   * @internal\n   */\n  public recordException(_exception: unknown, _time?: number | undefined): void {\n    // noop\n  }\n\n  /** @inheritdoc */\n  public spanContext(): SpanContextData {\n    const { _spanId: spanId, _traceId: traceId, _sampled: sampled } = this;\n    return {\n      spanId,\n      traceId,\n      traceFlags: sampled ? TRACE_FLAG_SAMPLED : TRACE_FLAG_NONE,\n    };\n  }\n\n  /** @inheritdoc */\n  public setAttribute(key: string, value: SpanAttributeValue | undefined): this {\n    if (value === undefined) {\n      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n      delete this._attributes[key];\n    } else {\n      this._attributes[key] = value;\n    }\n\n    return this;\n  }\n\n  /** @inheritdoc */\n  public setAttributes(attributes: SpanAttributes): this {\n    Object.keys(attributes).forEach(key => this.setAttribute(key, attributes[key]));\n    return this;\n  }\n\n  /**\n   * This should generally not be used,\n   * but we need it for browser tracing where we want to adjust the start time afterwards.\n   * USE THIS WITH CAUTION!\n   *\n   * @hidden\n   * @internal\n   */\n  public updateStartTime(timeInput: SpanTimeInput): void {\n    this._startTime = spanTimeInputToSeconds(timeInput);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public setStatus(value: SpanStatus): this {\n    this._status = value;\n    return this;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public updateName(name: string): this {\n    this._name = name;\n    this.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'custom');\n    return this;\n  }\n\n  /** @inheritdoc */\n  public end(endTimestamp?: SpanTimeInput): void {\n    // If already ended, skip\n    if (this._endTime) {\n      return;\n    }\n\n    this._endTime = spanTimeInputToSeconds(endTimestamp);\n    logSpanEnd(this);\n\n    this._onSpanEnded();\n  }\n\n  /**\n   * Get JSON representation of this span.\n   *\n   * @hidden\n   * @internal This method is purely for internal purposes and should not be used outside\n   * of SDK code. If you need to get a JSON representation of a span,\n   * use `spanToJSON(span)` instead.\n   */\n  public getSpanJSON(): SpanJSON {\n    return dropUndefinedKeys({\n      data: this._attributes,\n      description: this._name,\n      op: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP],\n      parent_span_id: this._parentSpanId,\n      span_id: this._spanId,\n      start_timestamp: this._startTime,\n      status: getStatusMessage(this._status),\n      timestamp: this._endTime,\n      trace_id: this._traceId,\n      origin: this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] as SpanOrigin | undefined,\n      _metrics_summary: getMetricSummaryJsonForSpan(this),\n      profile_id: this._attributes[SEMANTIC_ATTRIBUTE_PROFILE_ID] as string | undefined,\n      exclusive_time: this._attributes[SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME] as number | undefined,\n      measurements: timedEventsToMeasurements(this._events),\n      is_segment: (this._isStandaloneSpan && getRootSpan(this) === this) || undefined,\n      segment_id: this._isStandaloneSpan ? getRootSpan(this).spanContext().spanId : undefined,\n    });\n  }\n\n  /** @inheritdoc */\n  public isRecording(): boolean {\n    return !this._endTime && !!this._sampled;\n  }\n\n  /**\n   * @inheritdoc\n   */\n  public addEvent(\n    name: string,\n    attributesOrStartTime?: SpanAttributes | SpanTimeInput,\n    startTime?: SpanTimeInput,\n  ): this {\n    DEBUG_BUILD && logger.log('[Tracing] Adding an event to span:', name);\n\n    const time = isSpanTimeInput(attributesOrStartTime) ? attributesOrStartTime : startTime || timestampInSeconds();\n    const attributes = isSpanTimeInput(attributesOrStartTime) ? {} : attributesOrStartTime || {};\n\n    const event: TimedEvent = {\n      name,\n      time: spanTimeInputToSeconds(time),\n      attributes,\n    };\n\n    this._events.push(event);\n\n    return this;\n  }\n\n  /**\n   * This method should generally not be used,\n   * but for now we need a way to publicly check if the `_isStandaloneSpan` flag is set.\n   * USE THIS WITH CAUTION!\n   * @internal\n   * @hidden\n   * @experimental\n   */\n  public isStandaloneSpan(): boolean {\n    return !!this._isStandaloneSpan;\n  }\n\n  /** Emit `spanEnd` when the span is ended. */\n  private _onSpanEnded(): void {\n    const client = getClient();\n    if (client) {\n      client.emit('spanEnd', this);\n    }\n\n    // A segment span is basically the root span of a local span tree.\n    // So for now, this is either what we previously refer to as the root span,\n    // or a standalone span.\n    const isSegmentSpan = this._isStandaloneSpan || this === getRootSpan(this);\n\n    if (!isSegmentSpan) {\n      return;\n    }\n\n    // if this is a standalone span, we send it immediately\n    if (this._isStandaloneSpan) {\n      if (this._sampled) {\n        sendSpanEnvelope(createSpanEnvelope([this], client));\n      } else {\n        DEBUG_BUILD &&\n          logger.log('[Tracing] Discarding standalone span because its trace was not chosen to be sampled.');\n        if (client) {\n          client.recordDroppedEvent('sample_rate', 'span');\n        }\n      }\n      return;\n    }\n\n    const transactionEvent = this._convertSpanToTransaction();\n    if (transactionEvent) {\n      const scope = getCapturedScopesOnSpan(this).scope || getCurrentScope();\n      scope.captureEvent(transactionEvent);\n    }\n  }\n\n  /**\n   * Finish the transaction & prepare the event to send to Sentry.\n   */\n  private _convertSpanToTransaction(): TransactionEvent | undefined {\n    // We can only convert finished spans\n    if (!isFullFinishedSpan(spanToJSON(this))) {\n      return undefined;\n    }\n\n    if (!this._name) {\n      DEBUG_BUILD && logger.warn('Transaction has no name, falling back to `<unlabeled transaction>`.');\n      this._name = '<unlabeled transaction>';\n    }\n\n    const { scope: capturedSpanScope, isolationScope: capturedSpanIsolationScope } = getCapturedScopesOnSpan(this);\n    const scope = capturedSpanScope || getCurrentScope();\n    const client = scope.getClient() || getClient();\n\n    if (this._sampled !== true) {\n      // At this point if `sampled !== true` we want to discard the transaction.\n      DEBUG_BUILD && logger.log('[Tracing] Discarding transaction because its trace was not chosen to be sampled.');\n\n      if (client) {\n        client.recordDroppedEvent('sample_rate', 'transaction');\n      }\n\n      return undefined;\n    }\n\n    // The transaction span itself as well as any potential standalone spans should be filtered out\n    const finishedSpans = getSpanDescendants(this).filter(span => span !== this && !isStandaloneSpan(span));\n\n    const spans = finishedSpans.map(span => spanToJSON(span)).filter(isFullFinishedSpan);\n\n    const source = this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] as TransactionSource | undefined;\n\n    // remove internal root span attributes we don't need to send.\n    /* eslint-disable @typescript-eslint/no-dynamic-delete */\n    delete this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n    spans.forEach(span => {\n      span.data && delete span.data[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME];\n    });\n    // eslint-enabled-next-line @typescript-eslint/no-dynamic-delete\n\n    const transaction: TransactionEvent = {\n      contexts: {\n        trace: spanToTransactionTraceContext(this),\n      },\n      spans:\n        // spans.sort() mutates the array, but `spans` is already a copy so we can safely do this here\n        // we do not use spans anymore after this point\n        spans.length > MAX_SPAN_COUNT\n          ? spans.sort((a, b) => a.start_timestamp - b.start_timestamp).slice(0, MAX_SPAN_COUNT)\n          : spans,\n      start_timestamp: this._startTime,\n      timestamp: this._endTime,\n      transaction: this._name,\n      type: 'transaction',\n      sdkProcessingMetadata: {\n        capturedSpanScope,\n        capturedSpanIsolationScope,\n        ...dropUndefinedKeys({\n          dynamicSamplingContext: getDynamicSamplingContextFromSpan(this),\n        }),\n      },\n      _metrics_summary: getMetricSummaryJsonForSpan(this),\n      ...(source && {\n        transaction_info: {\n          source,\n        },\n      }),\n    };\n\n    const measurements = timedEventsToMeasurements(this._events);\n    const hasMeasurements = measurements && Object.keys(measurements).length;\n\n    if (hasMeasurements) {\n      DEBUG_BUILD &&\n        logger.log(\n          '[Measurements] Adding measurements to transaction event',\n          JSON.stringify(measurements, undefined, 2),\n        );\n      transaction.measurements = measurements;\n    }\n\n    return transaction;\n  }\n}\n\nfunction isSpanTimeInput(value: undefined | SpanAttributes | SpanTimeInput): value is SpanTimeInput {\n  return (value && typeof value === 'number') || value instanceof Date || Array.isArray(value);\n}\n\n// We want to filter out any incomplete SpanJSON objects\nfunction isFullFinishedSpan(input: Partial<SpanJSON>): input is SpanJSON {\n  return !!input.start_timestamp && !!input.timestamp && !!input.span_id && !!input.trace_id;\n}\n\n/** `SentrySpan`s can be sent as a standalone span rather than belonging to a transaction */\nfunction isStandaloneSpan(span: Span): boolean {\n  return span instanceof SentrySpan && span.isStandaloneSpan();\n}\n\n/**\n * Sends a `SpanEnvelope`.\n *\n * Note: If the envelope's spans are dropped, e.g. via `beforeSendSpan`,\n * the envelope will not be sent either.\n */\nfunction sendSpanEnvelope(envelope: SpanEnvelope): void {\n  const client = getClient();\n  if (!client) {\n    return;\n  }\n\n  const spanItems = envelope[1];\n  if (!spanItems || spanItems.length === 0) {\n    client.recordDroppedEvent('before_send', 'span');\n    return;\n  }\n\n  // sendEnvelope should not throw\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  client.sendEnvelope(envelope);\n}\n", "/* eslint-disable max-lines */\n\nimport type { AsyncContextStrategy } from '../asyncContext/types';\nimport { getMainCarrier } from '../carrier';\nimport type { ClientOptions, Scope, SentrySpanArguments, Span, SpanTimeInput, StartSpanOptions } from '../types-hoist';\n\nimport { getClient, getCurrentScope, getIsolationScope, withScope } from '../currentScopes';\n\nimport { getAsyncContextStrategy } from '../asyncContext';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '../semanticAttributes';\nimport { logger } from '../utils-hoist/logger';\nimport { generateTraceId } from '../utils-hoist/propagationContext';\nimport { propagationContextFromHeaders } from '../utils-hoist/tracing';\nimport { handleCallbackErrors } from '../utils/handleCallbackErrors';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled';\nimport { _getSpanForScope, _setSpanForScope } from '../utils/spanOnScope';\nimport { addChildSpanToSpan, getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../utils/spanUtils';\nimport { freezeDscOnSpan, getDynamicSamplingContextFromSpan } from './dynamicSamplingContext';\nimport { logSpanStart } from './logSpans';\nimport { sampleSpan } from './sampling';\nimport { SentryNonRecordingSpan } from './sentryNonRecordingSpan';\nimport { SentrySpan } from './sentrySpan';\nimport { SPAN_STATUS_ERROR } from './spanstatus';\nimport { setCapturedScopesOnSpan } from './utils';\n\nconst SUPPRESS_TRACING_KEY = '__SENTRY_SUPPRESS_TRACING__';\n\n/**\n * Wraps a function with a transaction/span and finishes the span after the function is done.\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * If you want to create a span that is not set as active, use {@link startInactiveSpan}.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startSpan<T>(options: StartSpanOptions, callback: (span: Span) => T): T {\n  const acs = getAcs();\n  if (acs.startSpan) {\n    return acs.startSpan(options, callback);\n  }\n\n  const spanArguments = parseSentrySpanArguments(options);\n  const { forceTransaction, parentSpan: customParentSpan } = options;\n\n  return withScope(options.scope, () => {\n    // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n    const wrapper = getActiveSpanWrapper<T>(customParentSpan);\n\n    return wrapper(() => {\n      const scope = getCurrentScope();\n      const parentSpan = getParentSpan(scope);\n\n      const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n      const activeSpan = shouldSkipSpan\n        ? new SentryNonRecordingSpan()\n        : createChildOrRootSpan({\n            parentSpan,\n            spanArguments,\n            forceTransaction,\n            scope,\n          });\n\n      _setSpanForScope(scope, activeSpan);\n\n      return handleCallbackErrors(\n        () => callback(activeSpan),\n        () => {\n          // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n          const { status } = spanToJSON(activeSpan);\n          if (activeSpan.isRecording() && (!status || status === 'ok')) {\n            activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n          }\n        },\n        () => activeSpan.end(),\n      );\n    });\n  });\n}\n\n/**\n * Similar to `Sentry.startSpan`. Wraps a function with a transaction/span, but does not finish the span\n * after the function is done automatically. You'll have to call `span.end()` manually.\n *\n * The created span is the active span and will be used as parent by other spans created inside the function\n * and can be accessed via `Sentry.getActiveSpan()`, as long as the function is executed while the scope is active.\n *\n * You'll always get a span passed to the callback,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startSpanManual<T>(options: StartSpanOptions, callback: (span: Span, finish: () => void) => T): T {\n  const acs = getAcs();\n  if (acs.startSpanManual) {\n    return acs.startSpanManual(options, callback);\n  }\n\n  const spanArguments = parseSentrySpanArguments(options);\n  const { forceTransaction, parentSpan: customParentSpan } = options;\n\n  return withScope(options.scope, () => {\n    // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n    const wrapper = getActiveSpanWrapper<T>(customParentSpan);\n\n    return wrapper(() => {\n      const scope = getCurrentScope();\n      const parentSpan = getParentSpan(scope);\n\n      const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n      const activeSpan = shouldSkipSpan\n        ? new SentryNonRecordingSpan()\n        : createChildOrRootSpan({\n            parentSpan,\n            spanArguments,\n            forceTransaction,\n            scope,\n          });\n\n      _setSpanForScope(scope, activeSpan);\n\n      function finishAndSetSpan(): void {\n        activeSpan.end();\n      }\n\n      return handleCallbackErrors(\n        () => callback(activeSpan, finishAndSetSpan),\n        () => {\n          // Only update the span status if it hasn't been changed yet, and the span is not yet finished\n          const { status } = spanToJSON(activeSpan);\n          if (activeSpan.isRecording() && (!status || status === 'ok')) {\n            activeSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n          }\n        },\n      );\n    });\n  });\n}\n\n/**\n * Creates a span. This span is not set as active, so will not get automatic instrumentation spans\n * as children or be able to be accessed via `Sentry.getActiveSpan()`.\n *\n * If you want to create a span that is set as active, use {@link startSpan}.\n *\n * This function will always return a span,\n * it may just be a non-recording span if the span is not sampled or if tracing is disabled.\n */\nexport function startInactiveSpan(options: StartSpanOptions): Span {\n  const acs = getAcs();\n  if (acs.startInactiveSpan) {\n    return acs.startInactiveSpan(options);\n  }\n\n  const spanArguments = parseSentrySpanArguments(options);\n  const { forceTransaction, parentSpan: customParentSpan } = options;\n\n  // If `options.scope` is defined, we use this as as a wrapper,\n  // If `options.parentSpan` is defined, we want to wrap the callback in `withActiveSpan`\n  const wrapper = options.scope\n    ? (callback: () => Span) => withScope(options.scope, callback)\n    : customParentSpan !== undefined\n      ? (callback: () => Span) => withActiveSpan(customParentSpan, callback)\n      : (callback: () => Span) => callback();\n\n  return wrapper(() => {\n    const scope = getCurrentScope();\n    const parentSpan = getParentSpan(scope);\n\n    const shouldSkipSpan = options.onlyIfParent && !parentSpan;\n\n    if (shouldSkipSpan) {\n      return new SentryNonRecordingSpan();\n    }\n\n    return createChildOrRootSpan({\n      parentSpan,\n      spanArguments,\n      forceTransaction,\n      scope,\n    });\n  });\n}\n\n/**\n * Continue a trace from `sentry-trace` and `baggage` values.\n * These values can be obtained from incoming request headers, or in the browser from `<meta name=\"sentry-trace\">`\n * and `<meta name=\"baggage\">` HTML tags.\n *\n * Spans started with `startSpan`, `startSpanManual` and `startInactiveSpan`, within the callback will automatically\n * be attached to the incoming trace.\n */\nexport const continueTrace = <V>(\n  options: {\n    sentryTrace: Parameters<typeof propagationContextFromHeaders>[0];\n    baggage: Parameters<typeof propagationContextFromHeaders>[1];\n  },\n  callback: () => V,\n): V => {\n  const carrier = getMainCarrier();\n  const acs = getAsyncContextStrategy(carrier);\n  if (acs.continueTrace) {\n    return acs.continueTrace(options, callback);\n  }\n\n  const { sentryTrace, baggage } = options;\n\n  return withScope(scope => {\n    const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n    scope.setPropagationContext(propagationContext);\n    return callback();\n  });\n};\n\n/**\n * Forks the current scope and sets the provided span as active span in the context of the provided callback. Can be\n * passed `null` to start an entirely new span tree.\n *\n * @param span Spans started in the context of the provided callback will be children of this span. If `null` is passed,\n * spans started within the callback will not be attached to a parent span.\n * @param callback Execution context in which the provided span will be active. Is passed the newly forked scope.\n * @returns the value returned from the provided callback function.\n */\nexport function withActiveSpan<T>(span: Span | null, callback: (scope: Scope) => T): T {\n  const acs = getAcs();\n  if (acs.withActiveSpan) {\n    return acs.withActiveSpan(span, callback);\n  }\n\n  return withScope(scope => {\n    _setSpanForScope(scope, span || undefined);\n    return callback(scope);\n  });\n}\n\n/** Suppress tracing in the given callback, ensuring no spans are generated inside of it. */\nexport function suppressTracing<T>(callback: () => T): T {\n  const acs = getAcs();\n\n  if (acs.suppressTracing) {\n    return acs.suppressTracing(callback);\n  }\n\n  return withScope(scope => {\n    scope.setSDKProcessingMetadata({ [SUPPRESS_TRACING_KEY]: true });\n    return callback();\n  });\n}\n\n/**\n * Starts a new trace for the duration of the provided callback. Spans started within the\n * callback will be part of the new trace instead of a potentially previously started trace.\n *\n * Important: Only use this function if you want to override the default trace lifetime and\n * propagation mechanism of the SDK for the duration and scope of the provided callback.\n * The newly created trace will also be the root of a new distributed trace, for example if\n * you make http requests within the callback.\n * This function might be useful if the operation you want to instrument should not be part\n * of a potentially ongoing trace.\n *\n * Default behavior:\n * - Server-side: A new trace is started for each incoming request.\n * - Browser: A new trace is started for each page our route. Navigating to a new route\n *            or page will automatically create a new trace.\n */\nexport function startNewTrace<T>(callback: () => T): T {\n  return withScope(scope => {\n    scope.setPropagationContext({ traceId: generateTraceId() });\n    DEBUG_BUILD && logger.info(`Starting a new trace with id ${scope.getPropagationContext().traceId}`);\n    return withActiveSpan(null, callback);\n  });\n}\n\nfunction createChildOrRootSpan({\n  parentSpan,\n  spanArguments,\n  forceTransaction,\n  scope,\n}: {\n  parentSpan: SentrySpan | undefined;\n  spanArguments: SentrySpanArguments;\n  forceTransaction?: boolean;\n  scope: Scope;\n}): Span {\n  if (!hasTracingEnabled()) {\n    return new SentryNonRecordingSpan();\n  }\n\n  const isolationScope = getIsolationScope();\n\n  let span: Span;\n  if (parentSpan && !forceTransaction) {\n    span = _startChildSpan(parentSpan, scope, spanArguments);\n    addChildSpanToSpan(parentSpan, span);\n  } else if (parentSpan) {\n    // If we forced a transaction but have a parent span, make sure to continue from the parent span, not the scope\n    const dsc = getDynamicSamplingContextFromSpan(parentSpan);\n    const { traceId, spanId: parentSpanId } = parentSpan.spanContext();\n    const parentSampled = spanIsSampled(parentSpan);\n\n    span = _startRootSpan(\n      {\n        traceId,\n        parentSpanId,\n        ...spanArguments,\n      },\n      scope,\n      parentSampled,\n    );\n\n    freezeDscOnSpan(span, dsc);\n  } else {\n    const {\n      traceId,\n      dsc,\n      parentSpanId,\n      sampled: parentSampled,\n    } = {\n      ...isolationScope.getPropagationContext(),\n      ...scope.getPropagationContext(),\n    };\n\n    span = _startRootSpan(\n      {\n        traceId,\n        parentSpanId,\n        ...spanArguments,\n      },\n      scope,\n      parentSampled,\n    );\n\n    if (dsc) {\n      freezeDscOnSpan(span, dsc);\n    }\n  }\n\n  logSpanStart(span);\n\n  setCapturedScopesOnSpan(span, scope, isolationScope);\n\n  return span;\n}\n\n/**\n * This converts StartSpanOptions to SentrySpanArguments.\n * For the most part (for now) we accept the same options,\n * but some of them need to be transformed.\n */\nfunction parseSentrySpanArguments(options: StartSpanOptions): SentrySpanArguments {\n  const exp = options.experimental || {};\n  const initialCtx: SentrySpanArguments = {\n    isStandalone: exp.standalone,\n    ...options,\n  };\n\n  if (options.startTime) {\n    const ctx: SentrySpanArguments & { startTime?: SpanTimeInput } = { ...initialCtx };\n    ctx.startTimestamp = spanTimeInputToSeconds(options.startTime);\n    delete ctx.startTime;\n    return ctx;\n  }\n\n  return initialCtx;\n}\n\nfunction getAcs(): AsyncContextStrategy {\n  const carrier = getMainCarrier();\n  return getAsyncContextStrategy(carrier);\n}\n\nfunction _startRootSpan(spanArguments: SentrySpanArguments, scope: Scope, parentSampled?: boolean): SentrySpan {\n  const client = getClient();\n  const options: Partial<ClientOptions> = (client && client.getOptions()) || {};\n\n  const { name = '', attributes } = spanArguments;\n  const [sampled, sampleRate] = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY]\n    ? [false]\n    : sampleSpan(options, {\n        name,\n        parentSampled,\n        attributes,\n        transactionContext: {\n          name,\n          parentSampled,\n        },\n      });\n\n  const rootSpan = new SentrySpan({\n    ...spanArguments,\n    attributes: {\n      [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom',\n      ...spanArguments.attributes,\n    },\n    sampled,\n  });\n  if (sampleRate !== undefined) {\n    rootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, sampleRate);\n  }\n\n  if (client) {\n    client.emit('spanStart', rootSpan);\n  }\n\n  return rootSpan;\n}\n\n/**\n * Creates a new `Span` while setting the current `Span.id` as `parentSpanId`.\n * This inherits the sampling decision from the parent span.\n */\nfunction _startChildSpan(parentSpan: Span, scope: Scope, spanArguments: SentrySpanArguments): Span {\n  const { spanId, traceId } = parentSpan.spanContext();\n  const sampled = scope.getScopeData().sdkProcessingMetadata[SUPPRESS_TRACING_KEY] ? false : spanIsSampled(parentSpan);\n\n  const childSpan = sampled\n    ? new SentrySpan({\n        ...spanArguments,\n        parentSpanId: spanId,\n        traceId,\n        sampled,\n      })\n    : new SentryNonRecordingSpan({ traceId });\n\n  addChildSpanToSpan(parentSpan, childSpan);\n\n  const client = getClient();\n  if (client) {\n    client.emit('spanStart', childSpan);\n    // If it has an endTimestamp, it's already ended\n    if (spanArguments.endTimestamp) {\n      client.emit('spanEnd', childSpan);\n    }\n  }\n\n  return childSpan;\n}\n\nfunction getParentSpan(scope: Scope): SentrySpan | undefined {\n  const span = _getSpanForScope(scope) as SentrySpan | undefined;\n\n  if (!span) {\n    return undefined;\n  }\n\n  const client = getClient();\n  const options: Partial<ClientOptions> = client ? client.getOptions() : {};\n  if (options.parentSpanIsAlwaysRootSpan) {\n    return getRootSpan(span) as SentrySpan;\n  }\n\n  return span;\n}\n\nfunction getActiveSpanWrapper<T>(parentSpan: Span | undefined | null): (callback: () => T) => T {\n  return parentSpan !== undefined\n    ? (callback: () => T) => {\n        return withActiveSpan(parentSpan, callback);\n      }\n    : (callback: () => T) => callback();\n}\n", "import { getClient, getCurrentScope } from '../currentScopes';\nimport type { Span, SpanAttributes, StartSpanOptions } from '../types-hoist';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON } from '../semanticAttributes';\nimport { logger } from '../utils-hoist/logger';\nimport { timestampInSeconds } from '../utils-hoist/time';\nimport { hasTracingEnabled } from '../utils/hasTracingEnabled';\nimport { _setSpanForScope } from '../utils/spanOnScope';\nimport {\n  getActiveSpan,\n  getSpanDescendants,\n  removeChildSpanFromSpan,\n  spanTimeInputToSeconds,\n  spanToJSON,\n} from '../utils/spanUtils';\nimport { SentryNonRecordingSpan } from './sentryNonRecordingSpan';\nimport { SPAN_STATUS_ERROR } from './spanstatus';\nimport { startInactiveSpan } from './trace';\n\nexport const TRACING_DEFAULTS = {\n  idleTimeout: 1_000,\n  finalTimeout: 30_000,\n  childSpanTimeout: 15_000,\n};\n\nconst FINISH_REASON_HEARTBEAT_FAILED = 'heartbeatFailed';\nconst FINISH_REASON_IDLE_TIMEOUT = 'idleTimeout';\nconst FINISH_REASON_FINAL_TIMEOUT = 'finalTimeout';\nconst FINISH_REASON_EXTERNAL_FINISH = 'externalFinish';\nconst FINISH_REASON_CANCELLED = 'cancelled';\n\n// unused\nconst FINISH_REASON_DOCUMENT_HIDDEN = 'documentHidden';\n\n// unused in this file, but used in BrowserTracing\nconst FINISH_REASON_INTERRUPTED = 'interactionInterrupted';\n\ntype IdleSpanFinishReason =\n  | typeof FINISH_REASON_CANCELLED\n  | typeof FINISH_REASON_DOCUMENT_HIDDEN\n  | typeof FINISH_REASON_EXTERNAL_FINISH\n  | typeof FINISH_REASON_FINAL_TIMEOUT\n  | typeof FINISH_REASON_HEARTBEAT_FAILED\n  | typeof FINISH_REASON_IDLE_TIMEOUT\n  | typeof FINISH_REASON_INTERRUPTED;\n\ninterface IdleSpanOptions {\n  /**\n   * The time that has to pass without any span being created.\n   * If this time is exceeded, the idle span will finish.\n   */\n  idleTimeout: number;\n  /**\n   * The max. time an idle span may run.\n   * If this time is exceeded, the idle span will finish no matter what.\n   */\n  finalTimeout: number;\n  /**\n   * The max. time a child span may run.\n   * If the time since the last span was started exceeds this time, the idle span will finish.\n   */\n  childSpanTimeout?: number;\n  /**\n   * When set to `true`, will disable the idle timeout and child timeout\n   * until the `idleSpanEnableAutoFinish` hook is emitted for the idle span.\n   * The final timeout mechanism will not be affected by this option,\n   * meaning the idle span will definitely be finished when the final timeout is\n   * reached, no matter what this option is configured to.\n   *\n   * Defaults to `false`.\n   */\n  disableAutoFinish?: boolean;\n  /** Allows to configure a hook that is called when the idle span is ended, before it is processed. */\n  beforeSpanEnd?: (span: Span) => void;\n}\n\n/**\n * An idle span is a span that automatically finishes. It does this by tracking child spans as activities.\n * An idle span is always the active span.\n */\nexport function startIdleSpan(startSpanOptions: StartSpanOptions, options: Partial<IdleSpanOptions> = {}): Span {\n  // Activities store a list of active spans\n  const activities = new Map<string, boolean>();\n\n  // We should not use heartbeat if we finished a span\n  let _finished = false;\n\n  // Timer that tracks idleTimeout\n  let _idleTimeoutID: ReturnType<typeof setTimeout> | undefined;\n\n  // Timer that tracks maxSpanTime for child spans\n  let _childSpanTimeoutID: ReturnType<typeof setTimeout> | undefined;\n\n  // The reason why the span was finished\n  let _finishReason: IdleSpanFinishReason = FINISH_REASON_EXTERNAL_FINISH;\n\n  let _autoFinishAllowed: boolean = !options.disableAutoFinish;\n\n  const _cleanupHooks: (() => void)[] = [];\n\n  const {\n    idleTimeout = TRACING_DEFAULTS.idleTimeout,\n    finalTimeout = TRACING_DEFAULTS.finalTimeout,\n    childSpanTimeout = TRACING_DEFAULTS.childSpanTimeout,\n    beforeSpanEnd,\n  } = options;\n\n  const client = getClient();\n\n  if (!client || !hasTracingEnabled()) {\n    return new SentryNonRecordingSpan();\n  }\n\n  const scope = getCurrentScope();\n  const previousActiveSpan = getActiveSpan();\n  const span = _startIdleSpan(startSpanOptions);\n\n  // We patch span.end to ensure we can run some things before the span is ended\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  span.end = new Proxy(span.end, {\n    apply(target, thisArg, args: Parameters<Span['end']>) {\n      if (beforeSpanEnd) {\n        beforeSpanEnd(span);\n      }\n\n      // Just ensuring that this keeps working, even if we ever have more arguments here\n      const [definedEndTimestamp, ...rest] = args;\n      const timestamp = definedEndTimestamp || timestampInSeconds();\n      const spanEndTimestamp = spanTimeInputToSeconds(timestamp);\n\n      // Ensure we end with the last span timestamp, if possible\n      const spans = getSpanDescendants(span).filter(child => child !== span);\n\n      // If we have no spans, we just end, nothing else to do here\n      if (!spans.length) {\n        onIdleSpanEnded(spanEndTimestamp);\n        return Reflect.apply(target, thisArg, [spanEndTimestamp, ...rest]);\n      }\n\n      const childEndTimestamps = spans\n        .map(span => spanToJSON(span).timestamp)\n        .filter(timestamp => !!timestamp) as number[];\n      const latestSpanEndTimestamp = childEndTimestamps.length ? Math.max(...childEndTimestamps) : undefined;\n\n      // In reality this should always exist here, but type-wise it may be undefined...\n      const spanStartTimestamp = spanToJSON(span).start_timestamp;\n\n      // The final endTimestamp should:\n      // * Never be before the span start timestamp\n      // * Be the latestSpanEndTimestamp, if there is one, and it is smaller than the passed span end timestamp\n      // * Otherwise be the passed end timestamp\n      // Final timestamp can never be after finalTimeout\n      const endTimestamp = Math.min(\n        spanStartTimestamp ? spanStartTimestamp + finalTimeout / 1000 : Infinity,\n        Math.max(spanStartTimestamp || -Infinity, Math.min(spanEndTimestamp, latestSpanEndTimestamp || Infinity)),\n      );\n\n      onIdleSpanEnded(endTimestamp);\n      return Reflect.apply(target, thisArg, [endTimestamp, ...rest]);\n    },\n  });\n\n  /**\n   * Cancels the existing idle timeout, if there is one.\n   */\n  function _cancelIdleTimeout(): void {\n    if (_idleTimeoutID) {\n      clearTimeout(_idleTimeoutID);\n      _idleTimeoutID = undefined;\n    }\n  }\n\n  /**\n   * Cancels the existing child span timeout, if there is one.\n   */\n  function _cancelChildSpanTimeout(): void {\n    if (_childSpanTimeoutID) {\n      clearTimeout(_childSpanTimeoutID);\n      _childSpanTimeoutID = undefined;\n    }\n  }\n\n  /**\n   * Restarts idle timeout, if there is no running idle timeout it will start one.\n   */\n  function _restartIdleTimeout(endTimestamp?: number): void {\n    _cancelIdleTimeout();\n    _idleTimeoutID = setTimeout(() => {\n      if (!_finished && activities.size === 0 && _autoFinishAllowed) {\n        _finishReason = FINISH_REASON_IDLE_TIMEOUT;\n        span.end(endTimestamp);\n      }\n    }, idleTimeout);\n  }\n\n  /**\n   * Restarts child span timeout, if there is none running it will start one.\n   */\n  function _restartChildSpanTimeout(endTimestamp?: number): void {\n    _cancelChildSpanTimeout();\n    _idleTimeoutID = setTimeout(() => {\n      if (!_finished && _autoFinishAllowed) {\n        _finishReason = FINISH_REASON_HEARTBEAT_FAILED;\n        span.end(endTimestamp);\n      }\n    }, childSpanTimeout);\n  }\n\n  /**\n   * Start tracking a specific activity.\n   * @param spanId The span id that represents the activity\n   */\n  function _pushActivity(spanId: string): void {\n    _cancelIdleTimeout();\n    activities.set(spanId, true);\n\n    const endTimestamp = timestampInSeconds();\n    // We need to add the timeout here to have the real endtimestamp of the idle span\n    // Remember timestampInSeconds is in seconds, timeout is in ms\n    _restartChildSpanTimeout(endTimestamp + childSpanTimeout / 1000);\n  }\n\n  /**\n   * Remove an activity from usage\n   * @param spanId The span id that represents the activity\n   */\n  function _popActivity(spanId: string): void {\n    if (activities.has(spanId)) {\n      activities.delete(spanId);\n    }\n\n    if (activities.size === 0) {\n      const endTimestamp = timestampInSeconds();\n      // We need to add the timeout here to have the real endtimestamp of the idle span\n      // Remember timestampInSeconds is in seconds, timeout is in ms\n      _restartIdleTimeout(endTimestamp + idleTimeout / 1000);\n      _cancelChildSpanTimeout();\n    }\n  }\n\n  function onIdleSpanEnded(endTimestamp: number): void {\n    _finished = true;\n    activities.clear();\n\n    _cleanupHooks.forEach(cleanup => cleanup());\n\n    _setSpanForScope(scope, previousActiveSpan);\n\n    const spanJSON = spanToJSON(span);\n\n    const { start_timestamp: startTimestamp } = spanJSON;\n    // This should never happen, but to make TS happy...\n    if (!startTimestamp) {\n      return;\n    }\n\n    const attributes: SpanAttributes = spanJSON.data || {};\n    if (!attributes[SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON]) {\n      span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, _finishReason);\n    }\n\n    logger.log(`[Tracing] Idle span \"${spanJSON.op}\" finished`);\n\n    const childSpans = getSpanDescendants(span).filter(child => child !== span);\n\n    let discardedSpans = 0;\n    childSpans.forEach(childSpan => {\n      // We cancel all pending spans with status \"cancelled\" to indicate the idle span was finished early\n      if (childSpan.isRecording()) {\n        childSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'cancelled' });\n        childSpan.end(endTimestamp);\n        DEBUG_BUILD &&\n          logger.log('[Tracing] Cancelling span since span ended early', JSON.stringify(childSpan, undefined, 2));\n      }\n\n      const childSpanJSON = spanToJSON(childSpan);\n      const { timestamp: childEndTimestamp = 0, start_timestamp: childStartTimestamp = 0 } = childSpanJSON;\n\n      const spanStartedBeforeIdleSpanEnd = childStartTimestamp <= endTimestamp;\n\n      // Add a delta with idle timeout so that we prevent false positives\n      const timeoutWithMarginOfError = (finalTimeout + idleTimeout) / 1000;\n      const spanEndedBeforeFinalTimeout = childEndTimestamp - childStartTimestamp <= timeoutWithMarginOfError;\n\n      if (DEBUG_BUILD) {\n        const stringifiedSpan = JSON.stringify(childSpan, undefined, 2);\n        if (!spanStartedBeforeIdleSpanEnd) {\n          logger.log('[Tracing] Discarding span since it happened after idle span was finished', stringifiedSpan);\n        } else if (!spanEndedBeforeFinalTimeout) {\n          logger.log('[Tracing] Discarding span since it finished after idle span final timeout', stringifiedSpan);\n        }\n      }\n\n      if (!spanEndedBeforeFinalTimeout || !spanStartedBeforeIdleSpanEnd) {\n        removeChildSpanFromSpan(span, childSpan);\n        discardedSpans++;\n      }\n    });\n\n    if (discardedSpans > 0) {\n      span.setAttribute('sentry.idle_span_discarded_spans', discardedSpans);\n    }\n  }\n\n  _cleanupHooks.push(\n    client.on('spanStart', startedSpan => {\n      // If we already finished the idle span,\n      // or if this is the idle span itself being started,\n      // or if the started span has already been closed,\n      // we don't care about it for activity\n      if (_finished || startedSpan === span || !!spanToJSON(startedSpan).timestamp) {\n        return;\n      }\n\n      const allSpans = getSpanDescendants(span);\n\n      // If the span that was just started is a child of the idle span, we should track it\n      if (allSpans.includes(startedSpan)) {\n        _pushActivity(startedSpan.spanContext().spanId);\n      }\n    }),\n  );\n\n  _cleanupHooks.push(\n    client.on('spanEnd', endedSpan => {\n      if (_finished) {\n        return;\n      }\n\n      _popActivity(endedSpan.spanContext().spanId);\n    }),\n  );\n\n  _cleanupHooks.push(\n    client.on('idleSpanEnableAutoFinish', spanToAllowAutoFinish => {\n      if (spanToAllowAutoFinish === span) {\n        _autoFinishAllowed = true;\n        _restartIdleTimeout();\n\n        if (activities.size) {\n          _restartChildSpanTimeout();\n        }\n      }\n    }),\n  );\n\n  // We only start the initial idle timeout if we are not delaying the auto finish\n  if (!options.disableAutoFinish) {\n    _restartIdleTimeout();\n  }\n\n  setTimeout(() => {\n    if (!_finished) {\n      span.setStatus({ code: SPAN_STATUS_ERROR, message: 'deadline_exceeded' });\n      _finishReason = FINISH_REASON_FINAL_TIMEOUT;\n      span.end();\n    }\n  }, finalTimeout);\n\n  return span;\n}\n\nfunction _startIdleSpan(options: StartSpanOptions): Span {\n  const span = startInactiveSpan(options);\n\n  _setSpanForScope(getCurrentScope(), span);\n\n  DEBUG_BUILD && logger.log('[Tracing] Started span is an idle span');\n\n  return span;\n}\n", "import { DEBUG_BUILD } from './debug-build';\nimport type { Event, EventHint, EventProcessor } from './types-hoist';\nimport { isThenable } from './utils-hoist/is';\nimport { logger } from './utils-hoist/logger';\nimport { SyncPromise } from './utils-hoist/syncpromise';\n\n/**\n * Process an array of event processors, returning the processed event (or `null` if the event was dropped).\n */\nexport function notifyEventProcessors(\n  processors: EventProcessor[],\n  event: Event | null,\n  hint: EventHint,\n  index: number = 0,\n): PromiseLike<Event | null> {\n  return new SyncPromise<Event | null>((resolve, reject) => {\n    const processor = processors[index];\n    if (event === null || typeof processor !== 'function') {\n      resolve(event);\n    } else {\n      const result = processor({ ...event }, hint) as Event | null;\n\n      DEBUG_BUILD && processor.id && result === null && logger.log(`Event processor \"${processor.id}\" dropped event`);\n\n      if (isThenable(result)) {\n        void result\n          .then(final => notifyEventProcessors(processors, final, hint, index + 1).then(resolve))\n          .then(null, reject);\n      } else {\n        void notifyEventProcessors(processors, result, hint, index + 1)\n          .then(resolve)\n          .then(null, reject);\n      }\n    }\n  });\n}\n", "import type { DebugImage, StackParser } from '../types-hoist';\nimport { GLOBAL_OBJ } from './worldwide';\n\ntype StackString = string;\ntype CachedResult = [string, string];\n\nlet parsedStackResults: Record<StackString, CachedResult> | undefined;\nlet lastKeysCount: number | undefined;\nlet cachedFilenameDebugIds: Record<string, string> | undefined;\n\n/**\n * Returns a map of filenames to debug identifiers.\n */\nexport function getFilenameToDebugIdMap(stackParser: StackParser): Record<string, string> {\n  const debugIdMap = GLOBAL_OBJ._sentryDebugIds;\n  if (!debugIdMap) {\n    return {};\n  }\n\n  const debugIdKeys = Object.keys(debugIdMap);\n\n  // If the count of registered globals hasn't changed since the last call, we\n  // can just return the cached result.\n  if (cachedFilenameDebugIds && debugIdKeys.length === lastKeysCount) {\n    return cachedFilenameDebugIds;\n  }\n\n  lastKeysCount = debugIdKeys.length;\n\n  // Build a map of filename -> debug_id.\n  cachedFilenameDebugIds = debugIdKeys.reduce<Record<string, string>>((acc, stackKey) => {\n    if (!parsedStackResults) {\n      parsedStackResults = {};\n    }\n\n    const result = parsedStackResults[stackKey];\n\n    if (result) {\n      acc[result[0]] = result[1];\n    } else {\n      const parsedStack = stackParser(stackKey);\n\n      for (let i = parsedStack.length - 1; i >= 0; i--) {\n        const stackFrame = parsedStack[i];\n        const filename = stackFrame && stackFrame.filename;\n        const debugId = debugIdMap[stackKey];\n\n        if (filename && debugId) {\n          acc[filename] = debugId;\n          parsedStackResults[stackKey] = [filename, debugId];\n          break;\n        }\n      }\n    }\n\n    return acc;\n  }, {});\n\n  return cachedFilenameDebugIds;\n}\n\n/**\n * Returns a list of debug images for the given resources.\n */\nexport function getDebugImagesForResources(\n  stackParser: StackParser,\n  resource_paths: ReadonlyArray<string>,\n): DebugImage[] {\n  const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser);\n\n  if (!filenameDebugIdMap) {\n    return [];\n  }\n\n  const images: DebugImage[] = [];\n  for (const path of resource_paths) {\n    if (path && filenameDebugIdMap[path]) {\n      images.push({\n        type: 'sourcemap',\n        code_file: path,\n        debug_id: filenameDebugIdMap[path] as string,\n      });\n    }\n  }\n\n  return images;\n}\n", "import { getDynamicSamplingContextFromSpan } from '../tracing/dynamicSamplingContext';\nimport type { Breadcrumb, Event, ScopeData, Span } from '../types-hoist';\nimport { dropUndefinedKeys } from '../utils-hoist/object';\nimport { merge } from './merge';\nimport { getRootSpan, spanToJSON, spanToTraceContext } from './spanUtils';\n\n/**\n * Applies data from the scope to the event and runs all event processors on it.\n */\nexport function applyScopeDataToEvent(event: Event, data: ScopeData): void {\n  const { fingerprint, span, breadcrumbs, sdkProcessingMetadata } = data;\n\n  // Apply general data\n  applyDataToEvent(event, data);\n\n  // We want to set the trace context for normal events only if there isn't already\n  // a trace context on the event. There is a product feature in place where we link\n  // errors with transaction and it relies on that.\n  if (span) {\n    applySpanToEvent(event, span);\n  }\n\n  applyFingerprintToEvent(event, fingerprint);\n  applyBreadcrumbsToEvent(event, breadcrumbs);\n  applySdkMetadataToEvent(event, sdkProcessingMetadata);\n}\n\n/** Merge data of two scopes together. */\nexport function mergeScopeData(data: ScopeData, mergeData: ScopeData): void {\n  const {\n    extra,\n    tags,\n    user,\n    contexts,\n    level,\n    sdkProcessingMetadata,\n    breadcrumbs,\n    fingerprint,\n    eventProcessors,\n    attachments,\n    propagationContext,\n    transactionName,\n    span,\n  } = mergeData;\n\n  mergeAndOverwriteScopeData(data, 'extra', extra);\n  mergeAndOverwriteScopeData(data, 'tags', tags);\n  mergeAndOverwriteScopeData(data, 'user', user);\n  mergeAndOverwriteScopeData(data, 'contexts', contexts);\n\n  data.sdkProcessingMetadata = merge(data.sdkProcessingMetadata, sdkProcessingMetadata, 2);\n\n  if (level) {\n    data.level = level;\n  }\n\n  if (transactionName) {\n    data.transactionName = transactionName;\n  }\n\n  if (span) {\n    data.span = span;\n  }\n\n  if (breadcrumbs.length) {\n    data.breadcrumbs = [...data.breadcrumbs, ...breadcrumbs];\n  }\n\n  if (fingerprint.length) {\n    data.fingerprint = [...data.fingerprint, ...fingerprint];\n  }\n\n  if (eventProcessors.length) {\n    data.eventProcessors = [...data.eventProcessors, ...eventProcessors];\n  }\n\n  if (attachments.length) {\n    data.attachments = [...data.attachments, ...attachments];\n  }\n\n  data.propagationContext = { ...data.propagationContext, ...propagationContext };\n}\n\n/**\n * Merges certain scope data. Undefined values will overwrite any existing values.\n * Exported only for tests.\n */\nexport function mergeAndOverwriteScopeData<\n  Prop extends 'extra' | 'tags' | 'user' | 'contexts' | 'sdkProcessingMetadata',\n  Data extends ScopeData,\n>(data: Data, prop: Prop, mergeVal: Data[Prop]): void {\n  data[prop] = merge(data[prop], mergeVal, 1);\n}\n\n/** Exported only for tests */\nexport function mergeArray<Prop extends 'breadcrumbs' | 'fingerprint'>(\n  event: Event,\n  prop: Prop,\n  mergeVal: ScopeData[Prop],\n): void {\n  const prevVal = event[prop];\n  // If we are not merging any new values,\n  // we only need to proceed if there was an empty array before (as we want to replace it with undefined)\n  if (!mergeVal.length && (!prevVal || prevVal.length)) {\n    return;\n  }\n\n  const merged = [...(prevVal || []), ...mergeVal] as ScopeData[Prop];\n  event[prop] = merged.length ? merged : undefined;\n}\n\nfunction applyDataToEvent(event: Event, data: ScopeData): void {\n  const { extra, tags, user, contexts, level, transactionName } = data;\n\n  const cleanedExtra = dropUndefinedKeys(extra);\n  if (cleanedExtra && Object.keys(cleanedExtra).length) {\n    event.extra = { ...cleanedExtra, ...event.extra };\n  }\n\n  const cleanedTags = dropUndefinedKeys(tags);\n  if (cleanedTags && Object.keys(cleanedTags).length) {\n    event.tags = { ...cleanedTags, ...event.tags };\n  }\n\n  const cleanedUser = dropUndefinedKeys(user);\n  if (cleanedUser && Object.keys(cleanedUser).length) {\n    event.user = { ...cleanedUser, ...event.user };\n  }\n\n  const cleanedContexts = dropUndefinedKeys(contexts);\n  if (cleanedContexts && Object.keys(cleanedContexts).length) {\n    event.contexts = { ...cleanedContexts, ...event.contexts };\n  }\n\n  if (level) {\n    event.level = level;\n  }\n\n  // transaction events get their `transaction` from the root span name\n  if (transactionName && event.type !== 'transaction') {\n    event.transaction = transactionName;\n  }\n}\n\nfunction applyBreadcrumbsToEvent(event: Event, breadcrumbs: Breadcrumb[]): void {\n  const mergedBreadcrumbs = [...(event.breadcrumbs || []), ...breadcrumbs];\n  event.breadcrumbs = mergedBreadcrumbs.length ? mergedBreadcrumbs : undefined;\n}\n\nfunction applySdkMetadataToEvent(event: Event, sdkProcessingMetadata: ScopeData['sdkProcessingMetadata']): void {\n  event.sdkProcessingMetadata = {\n    ...event.sdkProcessingMetadata,\n    ...sdkProcessingMetadata,\n  };\n}\n\nfunction applySpanToEvent(event: Event, span: Span): void {\n  event.contexts = {\n    trace: spanToTraceContext(span),\n    ...event.contexts,\n  };\n\n  event.sdkProcessingMetadata = {\n    dynamicSamplingContext: getDynamicSamplingContextFromSpan(span),\n    ...event.sdkProcessingMetadata,\n  };\n\n  const rootSpan = getRootSpan(span);\n  const transactionName = spanToJSON(rootSpan).description;\n  if (transactionName && !event.transaction && event.type === 'transaction') {\n    event.transaction = transactionName;\n  }\n}\n\n/**\n * Applies fingerprint from the scope to the event if there's one,\n * uses message if there's one instead or get rid of empty fingerprint\n */\nfunction applyFingerprintToEvent(event: Event, fingerprint: ScopeData['fingerprint'] | undefined): void {\n  // Make sure it's an array first and we actually have something in place\n  event.fingerprint = event.fingerprint\n    ? Array.isArray(event.fingerprint)\n      ? event.fingerprint\n      : [event.fingerprint]\n    : [];\n\n  // If we have something on the scope, then merge it with event\n  if (fingerprint) {\n    event.fingerprint = event.fingerprint.concat(fingerprint);\n  }\n\n  // If we have no data at all, remove empty array default\n  if (event.fingerprint && !event.fingerprint.length) {\n    delete event.fingerprint;\n  }\n}\n", "import type {\n  CaptureContext,\n  Client,\n  ClientOptions,\n  Event,\n  EventHint,\n  Scope as ScopeInterface,\n  ScopeContext,\n  StackParser,\n} from '../types-hoist';\n\nimport { DEFAULT_ENVIRONMENT } from '../constants';\nimport { getGlobalScope } from '../currentScopes';\nimport { notifyEventProcessors } from '../eventProcessors';\nimport { Scope } from '../scope';\nimport { getFilenameToDebugIdMap } from '../utils-hoist/debug-ids';\nimport { addExceptionMechanism, uuid4 } from '../utils-hoist/misc';\nimport { normalize } from '../utils-hoist/normalize';\nimport { truncate } from '../utils-hoist/string';\nimport { dateTimestampInSeconds } from '../utils-hoist/time';\nimport { applyScopeDataToEvent, mergeScopeData } from './applyScopeDataToEvent';\n\n/**\n * This type makes sure that we get either a CaptureContext, OR an EventHint.\n * It does not allow mixing them, which could lead to unexpected outcomes, e.g. this is disallowed:\n * { user: { id: '123' }, mechanism: { handled: false } }\n */\nexport type ExclusiveEventHintOrCaptureContext =\n  | (CaptureContext & Partial<{ [key in keyof EventHint]: never }>)\n  | (EventHint & Partial<{ [key in keyof ScopeContext]: never }>);\n\n/**\n * Adds common information to events.\n *\n * The information includes release and environment from `options`,\n * breadcrumbs and context (extra, tags and user) from the scope.\n *\n * Information that is already present in the event is never overwritten. For\n * nested objects, such as the context, keys are merged.\n *\n * @param event The original event.\n * @param hint May contain additional information about the original exception.\n * @param scope A scope containing event metadata.\n * @returns A new event with more information.\n * @hidden\n */\nexport function prepareEvent(\n  options: ClientOptions,\n  event: Event,\n  hint: EventHint,\n  scope?: ScopeInterface,\n  client?: Client,\n  isolationScope?: ScopeInterface,\n): PromiseLike<Event | null> {\n  const { normalizeDepth = 3, normalizeMaxBreadth = 1_000 } = options;\n  const prepared: Event = {\n    ...event,\n    event_id: event.event_id || hint.event_id || uuid4(),\n    timestamp: event.timestamp || dateTimestampInSeconds(),\n  };\n  const integrations = hint.integrations || options.integrations.map(i => i.name);\n\n  applyClientOptions(prepared, options);\n  applyIntegrationsMetadata(prepared, integrations);\n\n  if (client) {\n    client.emit('applyFrameMetadata', event);\n  }\n\n  // Only put debug IDs onto frames for error events.\n  if (event.type === undefined) {\n    applyDebugIds(prepared, options.stackParser);\n  }\n\n  // If we have scope given to us, use it as the base for further modifications.\n  // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.\n  const finalScope = getFinalScope(scope, hint.captureContext);\n\n  if (hint.mechanism) {\n    addExceptionMechanism(prepared, hint.mechanism);\n  }\n\n  const clientEventProcessors = client ? client.getEventProcessors() : [];\n\n  // This should be the last thing called, since we want that\n  // {@link Scope.addEventProcessor} gets the finished prepared event.\n  // Merge scope data together\n  const data = getGlobalScope().getScopeData();\n\n  if (isolationScope) {\n    const isolationData = isolationScope.getScopeData();\n    mergeScopeData(data, isolationData);\n  }\n\n  if (finalScope) {\n    const finalScopeData = finalScope.getScopeData();\n    mergeScopeData(data, finalScopeData);\n  }\n\n  const attachments = [...(hint.attachments || []), ...data.attachments];\n  if (attachments.length) {\n    hint.attachments = attachments;\n  }\n\n  applyScopeDataToEvent(prepared, data);\n\n  const eventProcessors = [\n    ...clientEventProcessors,\n    // Run scope event processors _after_ all other processors\n    ...data.eventProcessors,\n  ];\n\n  const result = notifyEventProcessors(eventProcessors, prepared, hint);\n\n  return result.then(evt => {\n    if (evt) {\n      // We apply the debug_meta field only after all event processors have ran, so that if any event processors modified\n      // file names (e.g.the RewriteFrames integration) the filename -> debug ID relationship isn't destroyed.\n      // This should not cause any PII issues, since we're only moving data that is already on the event and not adding\n      // any new data\n      applyDebugMeta(evt);\n    }\n\n    if (typeof normalizeDepth === 'number' && normalizeDepth > 0) {\n      return normalizeEvent(evt, normalizeDepth, normalizeMaxBreadth);\n    }\n    return evt;\n  });\n}\n\n/**\n * Enhances event using the client configuration.\n * It takes care of all \"static\" values like environment, release and `dist`,\n * as well as truncating overly long values.\n *\n * Only exported for tests.\n *\n * @param event event instance to be enhanced\n */\nexport function applyClientOptions(event: Event, options: ClientOptions): void {\n  const { environment, release, dist, maxValueLength = 250 } = options;\n\n  // empty strings do not make sense for environment, release, and dist\n  // so we handle them the same as if they were not provided\n  event.environment = event.environment || environment || DEFAULT_ENVIRONMENT;\n\n  if (!event.release && release) {\n    event.release = release;\n  }\n\n  if (!event.dist && dist) {\n    event.dist = dist;\n  }\n\n  if (event.message) {\n    event.message = truncate(event.message, maxValueLength);\n  }\n\n  const exception = event.exception && event.exception.values && event.exception.values[0];\n  if (exception && exception.value) {\n    exception.value = truncate(exception.value, maxValueLength);\n  }\n\n  const request = event.request;\n  if (request && request.url) {\n    request.url = truncate(request.url, maxValueLength);\n  }\n}\n\n/**\n * Puts debug IDs into the stack frames of an error event.\n */\nexport function applyDebugIds(event: Event, stackParser: StackParser): void {\n  // Build a map of filename -> debug_id\n  const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser);\n\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    event!.exception!.values!.forEach(exception => {\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      exception.stacktrace!.frames!.forEach(frame => {\n        if (filenameDebugIdMap && frame.filename) {\n          frame.debug_id = filenameDebugIdMap[frame.filename];\n        }\n      });\n    });\n  } catch (e) {\n    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.\n  }\n}\n\n/**\n * Moves debug IDs from the stack frames of an error event into the debug_meta field.\n */\nexport function applyDebugMeta(event: Event): void {\n  // Extract debug IDs and filenames from the stack frames on the event.\n  const filenameDebugIdMap: Record<string, string> = {};\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    event.exception!.values!.forEach(exception => {\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      exception.stacktrace!.frames!.forEach(frame => {\n        if (frame.debug_id) {\n          if (frame.abs_path) {\n            filenameDebugIdMap[frame.abs_path] = frame.debug_id;\n          } else if (frame.filename) {\n            filenameDebugIdMap[frame.filename] = frame.debug_id;\n          }\n          delete frame.debug_id;\n        }\n      });\n    });\n  } catch (e) {\n    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.\n  }\n\n  if (Object.keys(filenameDebugIdMap).length === 0) {\n    return;\n  }\n\n  // Fill debug_meta information\n  event.debug_meta = event.debug_meta || {};\n  event.debug_meta.images = event.debug_meta.images || [];\n  const images = event.debug_meta.images;\n  Object.entries(filenameDebugIdMap).forEach(([filename, debug_id]) => {\n    images.push({\n      type: 'sourcemap',\n      code_file: filename,\n      debug_id,\n    });\n  });\n}\n\n/**\n * This function adds all used integrations to the SDK info in the event.\n * @param event The event that will be filled with all integrations.\n */\nfunction applyIntegrationsMetadata(event: Event, integrationNames: string[]): void {\n  if (integrationNames.length > 0) {\n    event.sdk = event.sdk || {};\n    event.sdk.integrations = [...(event.sdk.integrations || []), ...integrationNames];\n  }\n}\n\n/**\n * Applies `normalize` function on necessary `Event` attributes to make them safe for serialization.\n * Normalized keys:\n * - `breadcrumbs.data`\n * - `user`\n * - `contexts`\n * - `extra`\n * @param event Event\n * @returns Normalized event\n */\nfunction normalizeEvent(event: Event | null, depth: number, maxBreadth: number): Event | null {\n  if (!event) {\n    return null;\n  }\n\n  const normalized: Event = {\n    ...event,\n    ...(event.breadcrumbs && {\n      breadcrumbs: event.breadcrumbs.map(b => ({\n        ...b,\n        ...(b.data && {\n          data: normalize(b.data, depth, maxBreadth),\n        }),\n      })),\n    }),\n    ...(event.user && {\n      user: normalize(event.user, depth, maxBreadth),\n    }),\n    ...(event.contexts && {\n      contexts: normalize(event.contexts, depth, maxBreadth),\n    }),\n    ...(event.extra && {\n      extra: normalize(event.extra, depth, maxBreadth),\n    }),\n  };\n\n  // event.contexts.trace stores information about a Transaction. Similarly,\n  // event.spans[] stores information about child Spans. Given that a\n  // Transaction is conceptually a Span, normalization should apply to both\n  // Transactions and Spans consistently.\n  // For now the decision is to skip normalization of Transactions and Spans,\n  // so this block overwrites the normalized event to add back the original\n  // Transaction information prior to normalization.\n  if (event.contexts && event.contexts.trace && normalized.contexts) {\n    normalized.contexts.trace = event.contexts.trace;\n\n    // event.contexts.trace.data may contain circular/dangerous data so we need to normalize it\n    if (event.contexts.trace.data) {\n      normalized.contexts.trace.data = normalize(event.contexts.trace.data, depth, maxBreadth);\n    }\n  }\n\n  // event.spans[].data may contain circular/dangerous data so we need to normalize it\n  if (event.spans) {\n    normalized.spans = event.spans.map(span => {\n      return {\n        ...span,\n        ...(span.data && {\n          data: normalize(span.data, depth, maxBreadth),\n        }),\n      };\n    });\n  }\n\n  // event.contexts.flags (FeatureFlagContext) stores context for our feature\n  // flag integrations. It has a greater nesting depth than our other typed\n  // Contexts, so we re-normalize with a fixed depth of 3 here. We do not want\n  // to skip this in case of conflicting, user-provided context.\n  if (event.contexts && event.contexts.flags && normalized.contexts) {\n    normalized.contexts.flags = normalize(event.contexts.flags, 3, maxBreadth);\n  }\n\n  return normalized;\n}\n\nfunction getFinalScope(\n  scope: ScopeInterface | undefined,\n  captureContext: CaptureContext | undefined,\n): ScopeInterface | undefined {\n  if (!captureContext) {\n    return scope;\n  }\n\n  const finalScope = scope ? scope.clone() : new Scope();\n  finalScope.update(captureContext);\n  return finalScope;\n}\n\n/**\n * Parse either an `EventHint` directly, or convert a `CaptureContext` to an `EventHint`.\n * This is used to allow to update method signatures that used to accept a `CaptureContext` but should now accept an `EventHint`.\n */\nexport function parseEventHintOrCaptureContext(\n  hint: ExclusiveEventHintOrCaptureContext | undefined,\n): EventHint | undefined {\n  if (!hint) {\n    return undefined;\n  }\n\n  // If you pass a Scope or `() => Scope` as CaptureContext, we just return this as captureContext\n  if (hintIsScopeOrFunction(hint)) {\n    return { captureContext: hint };\n  }\n\n  if (hintIsScopeContext(hint)) {\n    return {\n      captureContext: hint,\n    };\n  }\n\n  return hint;\n}\n\nfunction hintIsScopeOrFunction(\n  hint: CaptureContext | EventHint,\n): hint is ScopeInterface | ((scope: ScopeInterface) => ScopeInterface) {\n  return hint instanceof Scope || typeof hint === 'function';\n}\n\ntype ScopeContextProperty = keyof ScopeContext;\nconst captureContextKeys: readonly ScopeContextProperty[] = [\n  'user',\n  'level',\n  'extra',\n  'contexts',\n  'tags',\n  'fingerprint',\n  'requestSession',\n  'propagationContext',\n] as const;\n\nfunction hintIsScopeContext(hint: Partial<ScopeContext> | EventHint): hint is Partial<ScopeContext> {\n  return Object.keys(hint).some(key => captureContextKeys.includes(key as ScopeContextProperty));\n}\n", "import type {\n  CaptureContext,\n  CheckIn,\n  Event,\n  EventHint,\n  EventProcessor,\n  Extra,\n  Extras,\n  FinishedCheckIn,\n  MonitorConfig,\n  Primitive,\n  Session,\n  SessionContext,\n  SeverityLevel,\n  User,\n} from './types-hoist';\n\nimport { DEFAULT_ENVIRONMENT } from './constants';\nimport { getClient, getCurrentScope, getIsolationScope, withIsolationScope } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport { closeSession, makeSession, updateSession } from './session';\nimport { isThenable } from './utils-hoist/is';\nimport { logger } from './utils-hoist/logger';\nimport { uuid4 } from './utils-hoist/misc';\nimport { timestampInSeconds } from './utils-hoist/time';\nimport { GLOBAL_OBJ } from './utils-hoist/worldwide';\nimport type { ExclusiveEventHintOrCaptureContext } from './utils/prepareEvent';\nimport { parseEventHintOrCaptureContext } from './utils/prepareEvent';\n\n/**\n * Captures an exception event and sends it to Sentry.\n *\n * @param exception The exception to capture.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured Sentry event.\n */\nexport function captureException(exception: unknown, hint?: ExclusiveEventHintOrCaptureContext): string {\n  return getCurrentScope().captureException(exception, parseEventHintOrCaptureContext(hint));\n}\n\n/**\n * Captures a message event and sends it to Sentry.\n *\n * @param message The message to send to Sentry.\n * @param captureContext Define the level of the message or pass in additional data to attach to the message.\n * @returns the id of the captured message.\n */\nexport function captureMessage(message: string, captureContext?: CaptureContext | SeverityLevel): string {\n  // This is necessary to provide explicit scopes upgrade, without changing the original\n  // arity of the `captureMessage(message, level)` method.\n  const level = typeof captureContext === 'string' ? captureContext : undefined;\n  const context = typeof captureContext !== 'string' ? { captureContext } : undefined;\n  return getCurrentScope().captureMessage(message, level, context);\n}\n\n/**\n * Captures a manually created event and sends it to Sentry.\n *\n * @param event The event to send to Sentry.\n * @param hint Optional additional data to attach to the Sentry event.\n * @returns the id of the captured event.\n */\nexport function captureEvent(event: Event, hint?: EventHint): string {\n  return getCurrentScope().captureEvent(event, hint);\n}\n\n/**\n * Sets context data with the given name.\n * @param name of the context\n * @param context Any kind of data. This data will be normalized.\n */\nexport function setContext(name: string, context: { [key: string]: unknown } | null): void {\n  getIsolationScope().setContext(name, context);\n}\n\n/**\n * Set an object that will be merged sent as extra data with the event.\n * @param extras Extras object to merge into current context.\n */\nexport function setExtras(extras: Extras): void {\n  getIsolationScope().setExtras(extras);\n}\n\n/**\n * Set key:value that will be sent as extra data with the event.\n * @param key String of extra\n * @param extra Any kind of data. This data will be normalized.\n */\nexport function setExtra(key: string, extra: Extra): void {\n  getIsolationScope().setExtra(key, extra);\n}\n\n/**\n * Set an object that will be merged sent as tags data with the event.\n * @param tags Tags context object to merge into current context.\n */\nexport function setTags(tags: { [key: string]: Primitive }): void {\n  getIsolationScope().setTags(tags);\n}\n\n/**\n * Set key:value that will be sent as tags data with the event.\n *\n * Can also be used to unset a tag, by passing `undefined`.\n *\n * @param key String key of tag\n * @param value Value of tag\n */\nexport function setTag(key: string, value: Primitive): void {\n  getIsolationScope().setTag(key, value);\n}\n\n/**\n * Updates user context information for future events.\n *\n * @param user User context object to be set in the current context. Pass `null` to unset the user.\n */\nexport function setUser(user: User | null): void {\n  getIsolationScope().setUser(user);\n}\n\n/**\n * The last error event id of the isolation scope.\n *\n * Warning: This function really returns the last recorded error event id on the current\n * isolation scope. If you call this function after handling a certain error and another error\n * is captured in between, the last one is returned instead of the one you might expect.\n * Also, ids of events that were never sent to Sentry (for example because\n * they were dropped in `beforeSend`) could be returned.\n *\n * @returns The last event id of the isolation scope.\n */\nexport function lastEventId(): string | undefined {\n  return getIsolationScope().lastEventId();\n}\n\n/**\n * Create a cron monitor check in and send it to Sentry.\n *\n * @param checkIn An object that describes a check in.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nexport function captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorConfig): string {\n  const scope = getCurrentScope();\n  const client = getClient();\n  if (!client) {\n    DEBUG_BUILD && logger.warn('Cannot capture check-in. No client defined.');\n  } else if (!client.captureCheckIn) {\n    DEBUG_BUILD && logger.warn('Cannot capture check-in. Client does not support sending check-ins.');\n  } else {\n    return client.captureCheckIn(checkIn, upsertMonitorConfig, scope);\n  }\n\n  return uuid4();\n}\n\n/**\n * Wraps a callback with a cron monitor check in. The check in will be sent to Sentry when the callback finishes.\n *\n * @param monitorSlug The distinct slug of the monitor.\n * @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want\n * to create a monitor automatically when sending a check in.\n */\nexport function withMonitor<T>(\n  monitorSlug: CheckIn['monitorSlug'],\n  callback: () => T,\n  upsertMonitorConfig?: MonitorConfig,\n): T {\n  const checkInId = captureCheckIn({ monitorSlug, status: 'in_progress' }, upsertMonitorConfig);\n  const now = timestampInSeconds();\n\n  function finishCheckIn(status: FinishedCheckIn['status']): void {\n    captureCheckIn({ monitorSlug, status, checkInId, duration: timestampInSeconds() - now });\n  }\n\n  return withIsolationScope(() => {\n    let maybePromiseResult: T;\n    try {\n      maybePromiseResult = callback();\n    } catch (e) {\n      finishCheckIn('error');\n      throw e;\n    }\n\n    if (isThenable(maybePromiseResult)) {\n      Promise.resolve(maybePromiseResult).then(\n        () => {\n          finishCheckIn('ok');\n        },\n        e => {\n          finishCheckIn('error');\n          throw e;\n        },\n      );\n    } else {\n      finishCheckIn('ok');\n    }\n\n    return maybePromiseResult;\n  });\n}\n\n/**\n * Call `flush()` on the current client, if there is one. See {@link Client.flush}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue. Omitting this parameter will cause\n * the client to wait until all events are sent before resolving the promise.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nexport async function flush(timeout?: number): Promise<boolean> {\n  const client = getClient();\n  if (client) {\n    return client.flush(timeout);\n  }\n  DEBUG_BUILD && logger.warn('Cannot flush events. No client defined.');\n  return Promise.resolve(false);\n}\n\n/**\n * Call `close()` on the current client, if there is one. See {@link Client.close}.\n *\n * @param timeout Maximum time in ms the client should wait to flush its event queue before shutting down. Omitting this\n * parameter will cause the client to wait until all events are sent before disabling itself.\n * @returns A promise which resolves to `true` if the queue successfully drains before the timeout, or `false` if it\n * doesn't (or if there's no client defined).\n */\nexport async function close(timeout?: number): Promise<boolean> {\n  const client = getClient();\n  if (client) {\n    return client.close(timeout);\n  }\n  DEBUG_BUILD && logger.warn('Cannot flush events and disable SDK. No client defined.');\n  return Promise.resolve(false);\n}\n\n/**\n * Returns true if Sentry has been properly initialized.\n */\nexport function isInitialized(): boolean {\n  return !!getClient();\n}\n\n/** If the SDK is initialized & enabled. */\nexport function isEnabled(): boolean {\n  const client = getClient();\n  return !!client && client.getOptions().enabled !== false && !!client.getTransport();\n}\n\n/**\n * Add an event processor.\n * This will be added to the current isolation scope, ensuring any event that is processed in the current execution\n * context will have the processor applied.\n */\nexport function addEventProcessor(callback: EventProcessor): void {\n  getIsolationScope().addEventProcessor(callback);\n}\n\n/**\n * Start a session on the current isolation scope.\n *\n * @param context (optional) additional properties to be applied to the returned session object\n *\n * @returns the new active session\n */\nexport function startSession(context?: SessionContext): Session {\n  const client = getClient();\n  const isolationScope = getIsolationScope();\n  const currentScope = getCurrentScope();\n\n  const { release, environment = DEFAULT_ENVIRONMENT } = (client && client.getOptions()) || {};\n\n  // Will fetch userAgent if called from browser sdk\n  const { userAgent } = GLOBAL_OBJ.navigator || {};\n\n  const session = makeSession({\n    release,\n    environment,\n    user: currentScope.getUser() || isolationScope.getUser(),\n    ...(userAgent && { userAgent }),\n    ...context,\n  });\n\n  // End existing session if there's one\n  const currentSession = isolationScope.getSession();\n  if (currentSession && currentSession.status === 'ok') {\n    updateSession(currentSession, { status: 'exited' });\n  }\n\n  endSession();\n\n  // Afterwards we set the new session on the scope\n  isolationScope.setSession(session);\n\n  // TODO (v8): Remove this and only use the isolation scope(?).\n  // For v7 though, we can't \"soft-break\" people using getCurrentHub().getScope().setSession()\n  currentScope.setSession(session);\n\n  return session;\n}\n\n/**\n * End the session on the current isolation scope.\n */\nexport function endSession(): void {\n  const isolationScope = getIsolationScope();\n  const currentScope = getCurrentScope();\n\n  const session = currentScope.getSession() || isolationScope.getSession();\n  if (session) {\n    closeSession(session);\n  }\n  _sendSessionUpdate();\n\n  // the session is over; take it off of the scope\n  isolationScope.setSession();\n\n  // TODO (v8): Remove this and only use the isolation scope(?).\n  // For v7 though, we can't \"soft-break\" people using getCurrentHub().getScope().setSession()\n  currentScope.setSession();\n}\n\n/**\n * Sends the current Session on the scope\n */\nfunction _sendSessionUpdate(): void {\n  const isolationScope = getIsolationScope();\n  const currentScope = getCurrentScope();\n  const client = getClient();\n  // TODO (v8): Remove currentScope and only use the isolation scope(?).\n  // For v7 though, we can't \"soft-break\" people using getCurrentHub().getScope().setSession()\n  const session = currentScope.getSession() || isolationScope.getSession();\n  if (session && client) {\n    client.captureSession(session);\n  }\n}\n\n/**\n * Sends the current session on the scope to Sentry\n *\n * @param end If set the session will be marked as exited and removed from the scope.\n *            Defaults to `false`.\n */\nexport function captureSession(end: boolean = false): void {\n  // both send the update and pull the session from the scope\n  if (end) {\n    endSession();\n    return;\n  }\n\n  // only send the update\n  _sendSessionUpdate();\n}\n", "import type { DsnComponents, DsnLike, SdkInfo } from './types-hoist';\nimport { dsnToString, makeDsn } from './utils-hoist/dsn';\n\nconst SENTRY_API_VERSION = '7';\n\n/** Returns the prefix to construct Sentry ingestion API endpoints. */\nfunction getBaseApiEndpoint(dsn: DsnComponents): string {\n  const protocol = dsn.protocol ? `${dsn.protocol}:` : '';\n  const port = dsn.port ? `:${dsn.port}` : '';\n  return `${protocol}//${dsn.host}${port}${dsn.path ? `/${dsn.path}` : ''}/api/`;\n}\n\n/** Returns the ingest API endpoint for target. */\nfunction _getIngestEndpoint(dsn: DsnComponents): string {\n  return `${getBaseApiEndpoint(dsn)}${dsn.projectId}/envelope/`;\n}\n\n/** Returns a URL-encoded string with auth config suitable for a query string. */\nfunction _encodedAuth(dsn: DsnComponents, sdkInfo: SdkInfo | undefined): string {\n  const params: Record<string, string> = {\n    sentry_version: SENTRY_API_VERSION,\n  };\n\n  if (dsn.publicKey) {\n    // We send only the minimum set of required information. See\n    // https://github.com/getsentry/sentry-javascript/issues/2572.\n    params.sentry_key = dsn.publicKey;\n  }\n\n  if (sdkInfo) {\n    params.sentry_client = `${sdkInfo.name}/${sdkInfo.version}`;\n  }\n\n  return new URLSearchParams(params).toString();\n}\n\n/**\n * Returns the envelope endpoint URL with auth in the query string.\n *\n * Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.\n */\nexport function getEnvelopeEndpointWithUrlEncodedAuth(dsn: DsnComponents, tunnel?: string, sdkInfo?: SdkInfo): string {\n  return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, sdkInfo)}`;\n}\n\n/** Returns the url to the report dialog endpoint. */\nexport function getReportDialogEndpoint(\n  dsnLike: DsnLike,\n  dialogOptions: {\n    // TODO(v9): Change this to  [key: string]: unknown;\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    [key: string]: any;\n    user?: { name?: string; email?: string };\n  },\n): string {\n  const dsn = makeDsn(dsnLike);\n  if (!dsn) {\n    return '';\n  }\n\n  const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;\n\n  let encodedOptions = `dsn=${dsnToString(dsn)}`;\n  for (const key in dialogOptions) {\n    if (key === 'dsn') {\n      continue;\n    }\n\n    if (key === 'onClose') {\n      continue;\n    }\n\n    if (key === 'user') {\n      const user = dialogOptions.user;\n      if (!user) {\n        continue;\n      }\n      if (user.name) {\n        encodedOptions += `&name=${encodeURIComponent(user.name)}`;\n      }\n      if (user.email) {\n        encodedOptions += `&email=${encodeURIComponent(user.email)}`;\n      }\n    } else {\n      encodedOptions += `&${encodeURIComponent(key)}=${encodeURIComponent(dialogOptions[key] as string)}`;\n    }\n  }\n\n  return `${endpoint}?${encodedOptions}`;\n}\n", "import { getClient } from './currentScopes';\nimport type { Client, Event, EventHint, Integration, IntegrationFn, Options } from './types-hoist';\n\nimport { DEBUG_BUILD } from './debug-build';\nimport { logger } from './utils-hoist/logger';\n\nexport const installedIntegrations: string[] = [];\n\n/** Map of integrations assigned to a client */\nexport type IntegrationIndex = {\n  [key: string]: Integration;\n};\n\ntype IntegrationWithDefaultInstance = Integration & { isDefaultInstance?: true };\n\n/**\n * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to\n * preserve the order of integrations in the array.\n *\n * @private\n */\nfunction filterDuplicates(integrations: Integration[]): Integration[] {\n  const integrationsByName: { [key: string]: Integration } = {};\n\n  integrations.forEach((currentInstance: IntegrationWithDefaultInstance) => {\n    const { name } = currentInstance;\n\n    const existingInstance: IntegrationWithDefaultInstance | undefined = integrationsByName[name];\n\n    // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a\n    // default instance to overwrite an existing user instance\n    if (existingInstance && !existingInstance.isDefaultInstance && currentInstance.isDefaultInstance) {\n      return;\n    }\n\n    integrationsByName[name] = currentInstance;\n  });\n\n  return Object.values(integrationsByName);\n}\n\n/** Gets integrations to install */\nexport function getIntegrationsToSetup(options: Pick<Options, 'defaultIntegrations' | 'integrations'>): Integration[] {\n  const defaultIntegrations = options.defaultIntegrations || [];\n  const userIntegrations = options.integrations;\n\n  // We flag default instances, so that later we can tell them apart from any user-created instances of the same class\n  defaultIntegrations.forEach((integration: IntegrationWithDefaultInstance) => {\n    integration.isDefaultInstance = true;\n  });\n\n  let integrations: Integration[];\n\n  if (Array.isArray(userIntegrations)) {\n    integrations = [...defaultIntegrations, ...userIntegrations];\n  } else if (typeof userIntegrations === 'function') {\n    const resolvedUserIntegrations = userIntegrations(defaultIntegrations);\n    integrations = Array.isArray(resolvedUserIntegrations) ? resolvedUserIntegrations : [resolvedUserIntegrations];\n  } else {\n    integrations = defaultIntegrations;\n  }\n\n  const finalIntegrations = filterDuplicates(integrations);\n\n  // The `Debug` integration prints copies of the `event` and `hint` which will be passed to `beforeSend` or\n  // `beforeSendTransaction`. It therefore has to run after all other integrations, so that the changes of all event\n  // processors will be reflected in the printed values. For lack of a more elegant way to guarantee that, we therefore\n  // locate it and, assuming it exists, pop it out of its current spot and shove it onto the end of the array.\n  const debugIndex = finalIntegrations.findIndex(integration => integration.name === 'Debug');\n  if (debugIndex > -1) {\n    const [debugInstance] = finalIntegrations.splice(debugIndex, 1) as [Integration];\n    finalIntegrations.push(debugInstance);\n  }\n\n  return finalIntegrations;\n}\n\n/**\n * Given a list of integration instances this installs them all. When `withDefaults` is set to `true` then all default\n * integrations are added unless they were already provided before.\n * @param integrations array of integration instances\n * @param withDefault should enable default integrations\n */\nexport function setupIntegrations(client: Client, integrations: Integration[]): IntegrationIndex {\n  const integrationIndex: IntegrationIndex = {};\n\n  integrations.forEach(integration => {\n    // guard against empty provided integrations\n    if (integration) {\n      setupIntegration(client, integration, integrationIndex);\n    }\n  });\n\n  return integrationIndex;\n}\n\n/**\n * Execute the `afterAllSetup` hooks of the given integrations.\n */\nexport function afterSetupIntegrations(client: Client, integrations: Integration[]): void {\n  for (const integration of integrations) {\n    // guard against empty provided integrations\n    if (integration && integration.afterAllSetup) {\n      integration.afterAllSetup(client);\n    }\n  }\n}\n\n/** Setup a single integration.  */\nexport function setupIntegration(client: Client, integration: Integration, integrationIndex: IntegrationIndex): void {\n  if (integrationIndex[integration.name]) {\n    DEBUG_BUILD && logger.log(`Integration skipped because it was already installed: ${integration.name}`);\n    return;\n  }\n  integrationIndex[integration.name] = integration;\n\n  // `setupOnce` is only called the first time\n  if (installedIntegrations.indexOf(integration.name) === -1 && typeof integration.setupOnce === 'function') {\n    integration.setupOnce();\n    installedIntegrations.push(integration.name);\n  }\n\n  // `setup` is run for each client\n  if (integration.setup && typeof integration.setup === 'function') {\n    integration.setup(client);\n  }\n\n  if (typeof integration.preprocessEvent === 'function') {\n    const callback = integration.preprocessEvent.bind(integration) as typeof integration.preprocessEvent;\n    client.on('preprocessEvent', (event, hint) => callback(event, hint, client));\n  }\n\n  if (typeof integration.processEvent === 'function') {\n    const callback = integration.processEvent.bind(integration) as typeof integration.processEvent;\n\n    const processor = Object.assign((event: Event, hint: EventHint) => callback(event, hint, client), {\n      id: integration.name,\n    });\n\n    client.addEventProcessor(processor);\n  }\n\n  DEBUG_BUILD && logger.log(`Integration installed: ${integration.name}`);\n}\n\n/** Add an integration to the current scope's client. */\nexport function addIntegration(integration: Integration): void {\n  const client = getClient();\n\n  if (!client) {\n    DEBUG_BUILD && logger.warn(`Cannot add integration \"${integration.name}\" because no SDK Client is available.`);\n    return;\n  }\n\n  client.addIntegration(integration);\n}\n\n/**\n * Define an integration function that can be used to create an integration instance.\n * Note that this by design hides the implementation details of the integration, as they are considered internal.\n */\nexport function defineIntegration<Fn extends IntegrationFn>(fn: Fn): (...args: Parameters<Fn>) => Integration {\n  return fn;\n}\n", "import type { ClientReport, ClientReportEnvelope, ClientReportItem } from '../types-hoist';\n\nimport { createEnvelope } from './envelope';\nimport { dateTimestampInSeconds } from './time';\n\n/**\n * Creates client report envelope\n * @param discarded_events An array of discard events\n * @param dsn A DSN that can be set on the header. Optional.\n */\nexport function createClientReportEnvelope(\n  discarded_events: ClientReport['discarded_events'],\n  dsn?: string,\n  timestamp?: number,\n): ClientReportEnvelope {\n  const clientReportItem: ClientReportItem = [\n    { type: 'client_report' },\n    {\n      timestamp: timestamp || dateTimestampInSeconds(),\n      discarded_events,\n    },\n  ];\n  return createEnvelope<ClientReportEnvelope>(dsn ? { dsn } : {}, [clientReportItem]);\n}\n", "import type { ConsoleLevel } from '../types-hoist';\n\n/** An error emitted by Sentry SDKs and related utilities. */\nexport class SentryError extends Error {\n  public logLevel: ConsoleLevel;\n\n  public constructor(\n    public message: string,\n    logLevel: ConsoleLevel = 'warn',\n  ) {\n    super(message);\n\n    this.logLevel = logLevel;\n  }\n}\n", "/* eslint-disable max-lines */\nimport type {\n  Breadcrumb,\n  BreadcrumbHint,\n  Client,\n  ClientOptions,\n  DataCategory,\n  DsnComponents,\n  DynamicSamplingContext,\n  Envelope,\n  ErrorEvent,\n  Event,\n  EventDropReason,\n  EventHint,\n  EventProcessor,\n  FeedbackEvent,\n  Integration,\n  Outcome,\n  ParameterizedString,\n  SdkMetadata,\n  Session,\n  SessionAggregates,\n  SeverityLevel,\n  Span,\n  SpanAttributes,\n  SpanContextData,\n  SpanJSON,\n  StartSpanOptions,\n  TransactionEvent,\n  Transport,\n  TransportMakeRequestResponse,\n} from './types-hoist';\n\nimport { getEnvelopeEndpointWithUrlEncodedAuth } from './api';\nimport { getCurrentScope, getIsolationScope, getTraceContextFromScope } from './currentScopes';\nimport { DEBUG_BUILD } from './debug-build';\nimport { createEventEnvelope, createSessionEnvelope } from './envelope';\nimport type { IntegrationIndex } from './integration';\nimport { afterSetupIntegrations } from './integration';\nimport { setupIntegration, setupIntegrations } from './integration';\nimport type { Scope } from './scope';\nimport { updateSession } from './session';\nimport { getDynamicSamplingContextFromScope } from './tracing/dynamicSamplingContext';\nimport { createClientReportEnvelope } from './utils-hoist/clientreport';\nimport { dsnToString, makeDsn } from './utils-hoist/dsn';\nimport { addItemToEnvelope, createAttachmentEnvelopeItem } from './utils-hoist/envelope';\nimport { SentryError } from './utils-hoist/error';\nimport { isParameterizedString, isPlainObject, isPrimitive, isThenable } from './utils-hoist/is';\nimport { consoleSandbox, logger } from './utils-hoist/logger';\nimport { checkOrSetAlreadyCaught, uuid4 } from './utils-hoist/misc';\nimport { SyncPromise, rejectedSyncPromise, resolvedSyncPromise } from './utils-hoist/syncpromise';\nimport { parseSampleRate } from './utils/parseSampleRate';\nimport { prepareEvent } from './utils/prepareEvent';\nimport { showSpanDropWarning } from './utils/spanUtils';\n\nconst ALREADY_SEEN_ERROR = \"Not capturing exception because it's already been captured.\";\n\n/**\n * Base implementation for all JavaScript SDK clients.\n *\n * Call the constructor with the corresponding options\n * specific to the client subclass. To access these options later, use\n * {@link Client.getOptions}.\n *\n * If a Dsn is specified in the options, it will be parsed and stored. Use\n * {@link Client.getDsn} to retrieve the Dsn at any moment. In case the Dsn is\n * invalid, the constructor will throw a {@link SentryException}. Note that\n * without a valid Dsn, the SDK will not send any events to Sentry.\n *\n * Before sending an event, it is passed through\n * {@link BaseClient._prepareEvent} to add SDK information and scope data\n * (breadcrumbs and context). To add more custom information, override this\n * method and extend the resulting prepared event.\n *\n * To issue automatically created events (e.g. via instrumentation), use\n * {@link Client.captureEvent}. It will prepare the event and pass it through\n * the callback lifecycle. To issue auto-breadcrumbs, use\n * {@link Client.addBreadcrumb}.\n *\n * @example\n * class NodeClient extends BaseClient<NodeOptions> {\n *   public constructor(options: NodeOptions) {\n *     super(options);\n *   }\n *\n *   // ...\n * }\n */\nexport abstract class BaseClient<O extends ClientOptions> implements Client<O> {\n  /** Options passed to the SDK. */\n  protected readonly _options: O;\n\n  /** The client Dsn, if specified in options. Without this Dsn, the SDK will be disabled. */\n  protected readonly _dsn?: DsnComponents;\n\n  protected readonly _transport?: Transport;\n\n  /** Array of set up integrations. */\n  protected _integrations: IntegrationIndex;\n\n  /** Number of calls being processed */\n  protected _numProcessing: number;\n\n  protected _eventProcessors: EventProcessor[];\n\n  /** Holds flushable  */\n  private _outcomes: { [key: string]: number };\n\n  // eslint-disable-next-line @typescript-eslint/ban-types\n  private _hooks: Record<string, Function[]>;\n\n  /**\n   * Initializes this client instance.\n   *\n   * @param options Options for the client.\n   */\n  protected constructor(options: O) {\n    this._options = options;\n    this._integrations = {};\n    this._numProcessing = 0;\n    this._outcomes = {};\n    this._hooks = {};\n    this._eventProcessors = [];\n\n    if (options.dsn) {\n      this._dsn = makeDsn(options.dsn);\n    } else {\n      DEBUG_BUILD && logger.warn('No DSN provided, client will not send events.');\n    }\n\n    if (this._dsn) {\n      const url = getEnvelopeEndpointWithUrlEncodedAuth(\n        this._dsn,\n        options.tunnel,\n        options._metadata ? options._metadata.sdk : undefined,\n      );\n      this._transport = options.transport({\n        tunnel: this._options.tunnel,\n        recordDroppedEvent: this.recordDroppedEvent.bind(this),\n        ...options.transportOptions,\n        url,\n      });\n    }\n\n    // TODO(v9): Remove this deprecation warning\n    const tracingOptions = ['enableTracing', 'tracesSampleRate', 'tracesSampler'] as const;\n    const undefinedOption = tracingOptions.find(option => option in options && options[option] == undefined);\n    if (undefinedOption) {\n      consoleSandbox(() => {\n        // eslint-disable-next-line no-console\n        console.warn(\n          `[Sentry] Deprecation warning: \\`${undefinedOption}\\` is set to undefined, which leads to tracing being enabled. In v9, a value of \\`undefined\\` will result in tracing being disabled.`,\n        );\n      });\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public captureException(exception: unknown, hint?: EventHint, scope?: Scope): string {\n    const eventId = uuid4();\n\n    // ensure we haven't captured this very object before\n    if (checkOrSetAlreadyCaught(exception)) {\n      DEBUG_BUILD && logger.log(ALREADY_SEEN_ERROR);\n      return eventId;\n    }\n\n    const hintWithEventId = {\n      event_id: eventId,\n      ...hint,\n    };\n\n    this._process(\n      this.eventFromException(exception, hintWithEventId).then(event =>\n        this._captureEvent(event, hintWithEventId, scope),\n      ),\n    );\n\n    return hintWithEventId.event_id;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public captureMessage(\n    message: ParameterizedString,\n    level?: SeverityLevel,\n    hint?: EventHint,\n    currentScope?: Scope,\n  ): string {\n    const hintWithEventId = {\n      event_id: uuid4(),\n      ...hint,\n    };\n\n    const eventMessage = isParameterizedString(message) ? message : String(message);\n\n    const promisedEvent = isPrimitive(message)\n      ? this.eventFromMessage(eventMessage, level, hintWithEventId)\n      : this.eventFromException(message, hintWithEventId);\n\n    this._process(promisedEvent.then(event => this._captureEvent(event, hintWithEventId, currentScope)));\n\n    return hintWithEventId.event_id;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public captureEvent(event: Event, hint?: EventHint, currentScope?: Scope): string {\n    const eventId = uuid4();\n\n    // ensure we haven't captured this very object before\n    if (hint && hint.originalException && checkOrSetAlreadyCaught(hint.originalException)) {\n      DEBUG_BUILD && logger.log(ALREADY_SEEN_ERROR);\n      return eventId;\n    }\n\n    const hintWithEventId = {\n      event_id: eventId,\n      ...hint,\n    };\n\n    const sdkProcessingMetadata = event.sdkProcessingMetadata || {};\n    const capturedSpanScope: Scope | undefined = sdkProcessingMetadata.capturedSpanScope;\n\n    this._process(this._captureEvent(event, hintWithEventId, capturedSpanScope || currentScope));\n\n    return hintWithEventId.event_id;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public captureSession(session: Session): void {\n    if (!(typeof session.release === 'string')) {\n      DEBUG_BUILD && logger.warn('Discarded session because of missing or non-string release');\n    } else {\n      this.sendSession(session);\n      // After sending, we set init false to indicate it's not the first occurrence\n      updateSession(session, { init: false });\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getDsn(): DsnComponents | undefined {\n    return this._dsn;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getOptions(): O {\n    return this._options;\n  }\n\n  /**\n   * @see SdkMetadata\n   *\n   * @return The metadata of the SDK\n   */\n  public getSdkMetadata(): SdkMetadata | undefined {\n    return this._options._metadata;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public getTransport(): Transport | undefined {\n    return this._transport;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public flush(timeout?: number): PromiseLike<boolean> {\n    const transport = this._transport;\n    if (transport) {\n      this.emit('flush');\n      return this._isClientDoneProcessing(timeout).then(clientFinished => {\n        return transport.flush(timeout).then(transportFlushed => clientFinished && transportFlushed);\n      });\n    } else {\n      return resolvedSyncPromise(true);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public close(timeout?: number): PromiseLike<boolean> {\n    return this.flush(timeout).then(result => {\n      this.getOptions().enabled = false;\n      this.emit('close');\n      return result;\n    });\n  }\n\n  /** Get all installed event processors. */\n  public getEventProcessors(): EventProcessor[] {\n    return this._eventProcessors;\n  }\n\n  /** @inheritDoc */\n  public addEventProcessor(eventProcessor: EventProcessor): void {\n    this._eventProcessors.push(eventProcessor);\n  }\n\n  /** @inheritdoc */\n  public init(): void {\n    if (\n      this._isEnabled() ||\n      // Force integrations to be setup even if no DSN was set when we have\n      // Spotlight enabled. This is particularly important for browser as we\n      // don't support the `spotlight` option there and rely on the users\n      // adding the `spotlightBrowserIntegration()` to their integrations which\n      // wouldn't get initialized with the check below when there's no DSN set.\n      this._options.integrations.some(({ name }) => name.startsWith('Spotlight'))\n    ) {\n      this._setupIntegrations();\n    }\n  }\n\n  /**\n   * Gets an installed integration by its name.\n   *\n   * @returns The installed integration or `undefined` if no integration with that `name` was installed.\n   */\n  public getIntegrationByName<T extends Integration = Integration>(integrationName: string): T | undefined {\n    return this._integrations[integrationName] as T | undefined;\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public addIntegration(integration: Integration): void {\n    const isAlreadyInstalled = this._integrations[integration.name];\n\n    // This hook takes care of only installing if not already installed\n    setupIntegration(this, integration, this._integrations);\n    // Here we need to check manually to make sure to not run this multiple times\n    if (!isAlreadyInstalled) {\n      afterSetupIntegrations(this, [integration]);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public sendEvent(event: Event, hint: EventHint = {}): void {\n    this.emit('beforeSendEvent', event, hint);\n\n    let env = createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel);\n\n    for (const attachment of hint.attachments || []) {\n      env = addItemToEnvelope(env, createAttachmentEnvelopeItem(attachment));\n    }\n\n    const promise = this.sendEnvelope(env);\n    if (promise) {\n      promise.then(sendResponse => this.emit('afterSendEvent', event, sendResponse), null);\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public sendSession(session: Session | SessionAggregates): void {\n    const env = createSessionEnvelope(session, this._dsn, this._options._metadata, this._options.tunnel);\n\n    // sendEnvelope should not throw\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.sendEnvelope(env);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public recordDroppedEvent(reason: EventDropReason, category: DataCategory, eventOrCount?: Event | number): void {\n    if (this._options.sendClientReports) {\n      // TODO v9: We do not need the `event` passed as third argument anymore, and can possibly remove this overload\n      // If event is passed as third argument, we assume this is a count of 1\n      const count = typeof eventOrCount === 'number' ? eventOrCount : 1;\n\n      // We want to track each category (error, transaction, session, replay_event) separately\n      // but still keep the distinction between different type of outcomes.\n      // We could use nested maps, but it's much easier to read and type this way.\n      // A correct type for map-based implementation if we want to go that route\n      // would be `Partial<Record<SentryRequestType, Partial<Record<Outcome, number>>>>`\n      // With typescript 4.1 we could even use template literal types\n      const key = `${reason}:${category}`;\n      DEBUG_BUILD && logger.log(`Recording outcome: \"${key}\"${count > 1 ? ` (${count} times)` : ''}`);\n      this._outcomes[key] = (this._outcomes[key] || 0) + count;\n    }\n  }\n\n  // Keep on() & emit() signatures in sync with types' client.ts interface\n  /* eslint-disable @typescript-eslint/unified-signatures */\n\n  /** @inheritdoc */\n  public on(hook: 'spanStart', callback: (span: Span) => void): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'spanEnd', callback: (span: Span) => void): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'idleSpanEnableAutoFinish', callback: (span: Span) => void): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'beforeEnvelope', callback: (envelope: Envelope) => void): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'beforeSendEvent', callback: (event: Event, hint?: EventHint) => void): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'preprocessEvent', callback: (event: Event, hint?: EventHint) => void): () => void;\n\n  /** @inheritdoc */\n  public on(\n    hook: 'afterSendEvent',\n    callback: (event: Event, sendResponse: TransportMakeRequestResponse) => void,\n  ): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'beforeAddBreadcrumb', callback: (breadcrumb: Breadcrumb, hint?: BreadcrumbHint) => void): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'createDsc', callback: (dsc: DynamicSamplingContext, rootSpan?: Span) => void): () => void;\n\n  /** @inheritdoc */\n  public on(\n    hook: 'beforeSendFeedback',\n    callback: (feedback: FeedbackEvent, options?: { includeReplay: boolean }) => void,\n  ): () => void;\n\n  /** @inheritdoc */\n  public on(\n    hook: 'beforeSampling',\n    callback: (\n      samplingData: {\n        spanAttributes: SpanAttributes;\n        spanName: string;\n        parentSampled?: boolean;\n        parentContext?: SpanContextData;\n      },\n      samplingDecision: { decision: boolean },\n    ) => void,\n  ): void;\n\n  /** @inheritdoc */\n  public on(\n    hook: 'startPageLoadSpan',\n    callback: (\n      options: StartSpanOptions,\n      traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },\n    ) => void,\n  ): () => void;\n\n  /** @inheritdoc */\n  public on(hook: 'startNavigationSpan', callback: (options: StartSpanOptions) => void): () => void;\n\n  public on(hook: 'flush', callback: () => void): () => void;\n\n  public on(hook: 'close', callback: () => void): () => void;\n\n  public on(hook: 'applyFrameMetadata', callback: (event: Event) => void): () => void;\n\n  /** @inheritdoc */\n  public on(hook: string, callback: unknown): () => void {\n    const hooks = (this._hooks[hook] = this._hooks[hook] || []);\n\n    // @ts-expect-error We assume the types are correct\n    hooks.push(callback);\n\n    // This function returns a callback execution handler that, when invoked,\n    // deregisters a callback. This is crucial for managing instances where callbacks\n    // need to be unregistered to prevent self-referencing in callback closures,\n    // ensuring proper garbage collection.\n    return () => {\n      // @ts-expect-error We assume the types are correct\n      const cbIndex = hooks.indexOf(callback);\n      if (cbIndex > -1) {\n        hooks.splice(cbIndex, 1);\n      }\n    };\n  }\n\n  /** @inheritdoc */\n  public emit(\n    hook: 'beforeSampling',\n    samplingData: {\n      spanAttributes: SpanAttributes;\n      spanName: string;\n      parentSampled?: boolean;\n      parentContext?: SpanContextData;\n    },\n    samplingDecision: { decision: boolean },\n  ): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'spanStart', span: Span): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'spanEnd', span: Span): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'idleSpanEnableAutoFinish', span: Span): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'beforeEnvelope', envelope: Envelope): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'beforeSendEvent', event: Event, hint?: EventHint): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'preprocessEvent', event: Event, hint?: EventHint): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'afterSendEvent', event: Event, sendResponse: TransportMakeRequestResponse): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'beforeAddBreadcrumb', breadcrumb: Breadcrumb, hint?: BreadcrumbHint): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'createDsc', dsc: DynamicSamplingContext, rootSpan?: Span): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'beforeSendFeedback', feedback: FeedbackEvent, options?: { includeReplay: boolean }): void;\n\n  /** @inheritdoc */\n  public emit(\n    hook: 'startPageLoadSpan',\n    options: StartSpanOptions,\n    traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },\n  ): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'startNavigationSpan', options: StartSpanOptions): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'flush'): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'close'): void;\n\n  /** @inheritdoc */\n  public emit(hook: 'applyFrameMetadata', event: Event): void;\n\n  /** @inheritdoc */\n  public emit(hook: string, ...rest: unknown[]): void {\n    const callbacks = this._hooks[hook];\n    if (callbacks) {\n      callbacks.forEach(callback => callback(...rest));\n    }\n  }\n\n  /**\n   * @inheritdoc\n   */\n  public sendEnvelope(envelope: Envelope): PromiseLike<TransportMakeRequestResponse> {\n    this.emit('beforeEnvelope', envelope);\n\n    if (this._isEnabled() && this._transport) {\n      return this._transport.send(envelope).then(null, reason => {\n        DEBUG_BUILD && logger.error('Error while sending envelope:', reason);\n        return reason;\n      });\n    }\n\n    DEBUG_BUILD && logger.error('Transport disabled');\n\n    return resolvedSyncPromise({});\n  }\n\n  /* eslint-enable @typescript-eslint/unified-signatures */\n\n  /** Setup integrations for this client. */\n  protected _setupIntegrations(): void {\n    const { integrations } = this._options;\n    this._integrations = setupIntegrations(this, integrations);\n    afterSetupIntegrations(this, integrations);\n  }\n\n  /** Updates existing session based on the provided event */\n  protected _updateSessionFromEvent(session: Session, event: Event): void {\n    let crashed = event.level === 'fatal';\n    let errored = false;\n    const exceptions = event.exception && event.exception.values;\n\n    if (exceptions) {\n      errored = true;\n\n      for (const ex of exceptions) {\n        const mechanism = ex.mechanism;\n        if (mechanism && mechanism.handled === false) {\n          crashed = true;\n          break;\n        }\n      }\n    }\n\n    // A session is updated and that session update is sent in only one of the two following scenarios:\n    // 1. Session with non terminal status and 0 errors + an error occurred -> Will set error count to 1 and send update\n    // 2. Session with non terminal status and 1 error + a crash occurred -> Will set status crashed and send update\n    const sessionNonTerminal = session.status === 'ok';\n    const shouldUpdateAndSend = (sessionNonTerminal && session.errors === 0) || (sessionNonTerminal && crashed);\n\n    if (shouldUpdateAndSend) {\n      updateSession(session, {\n        ...(crashed && { status: 'crashed' }),\n        errors: session.errors || Number(errored || crashed),\n      });\n      this.captureSession(session);\n    }\n  }\n\n  /**\n   * Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying\n   * \"no\" (resolving to `false`) in order to give the client a chance to potentially finish first.\n   *\n   * @param timeout The time, in ms, after which to resolve to `false` if the client is still busy. Passing `0` (or not\n   * passing anything) will make the promise wait as long as it takes for processing to finish before resolving to\n   * `true`.\n   * @returns A promise which will resolve to `true` if processing is already done or finishes before the timeout, and\n   * `false` otherwise\n   */\n  protected _isClientDoneProcessing(timeout?: number): PromiseLike<boolean> {\n    return new SyncPromise(resolve => {\n      let ticked: number = 0;\n      const tick: number = 1;\n\n      const interval = setInterval(() => {\n        if (this._numProcessing == 0) {\n          clearInterval(interval);\n          resolve(true);\n        } else {\n          ticked += tick;\n          if (timeout && ticked >= timeout) {\n            clearInterval(interval);\n            resolve(false);\n          }\n        }\n      }, tick);\n    });\n  }\n\n  /** Determines whether this SDK is enabled and a transport is present. */\n  protected _isEnabled(): boolean {\n    return this.getOptions().enabled !== false && this._transport !== undefined;\n  }\n\n  /**\n   * Adds common information to events.\n   *\n   * The information includes release and environment from `options`,\n   * breadcrumbs and context (extra, tags and user) from the scope.\n   *\n   * Information that is already present in the event is never overwritten. For\n   * nested objects, such as the context, keys are merged.\n   *\n   * @param event The original event.\n   * @param hint May contain additional information about the original exception.\n   * @param currentScope A scope containing event metadata.\n   * @returns A new event with more information.\n   */\n  protected _prepareEvent(\n    event: Event,\n    hint: EventHint,\n    currentScope = getCurrentScope(),\n    isolationScope = getIsolationScope(),\n  ): PromiseLike<Event | null> {\n    const options = this.getOptions();\n    const integrations = Object.keys(this._integrations);\n    if (!hint.integrations && integrations.length > 0) {\n      hint.integrations = integrations;\n    }\n\n    this.emit('preprocessEvent', event, hint);\n\n    if (!event.type) {\n      isolationScope.setLastEventId(event.event_id || hint.event_id);\n    }\n\n    return prepareEvent(options, event, hint, currentScope, this, isolationScope).then(evt => {\n      if (evt === null) {\n        return evt;\n      }\n\n      evt.contexts = {\n        trace: getTraceContextFromScope(currentScope),\n        ...evt.contexts,\n      };\n\n      const dynamicSamplingContext = getDynamicSamplingContextFromScope(this, currentScope);\n\n      evt.sdkProcessingMetadata = {\n        dynamicSamplingContext,\n        ...evt.sdkProcessingMetadata,\n      };\n\n      return evt;\n    });\n  }\n\n  /**\n   * Processes the event and logs an error in case of rejection\n   * @param event\n   * @param hint\n   * @param scope\n   */\n  protected _captureEvent(event: Event, hint: EventHint = {}, scope?: Scope): PromiseLike<string | undefined> {\n    return this._processEvent(event, hint, scope).then(\n      finalEvent => {\n        return finalEvent.event_id;\n      },\n      reason => {\n        if (DEBUG_BUILD) {\n          // If something's gone wrong, log the error as a warning. If it's just us having used a `SentryError` for\n          // control flow, log just the message (no stack) as a log-level log.\n          if (reason instanceof SentryError && reason.logLevel === 'log') {\n            logger.log(reason.message);\n          } else {\n            logger.warn(reason);\n          }\n        }\n        return undefined;\n      },\n    );\n  }\n\n  /**\n   * Processes an event (either error or message) and sends it to Sentry.\n   *\n   * This also adds breadcrumbs and context information to the event. However,\n   * platform specific meta data (such as the User's IP address) must be added\n   * by the SDK implementor.\n   *\n   *\n   * @param event The event to send to Sentry.\n   * @param hint May contain additional information about the original exception.\n   * @param currentScope A scope containing event metadata.\n   * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send.\n   */\n  protected _processEvent(event: Event, hint: EventHint, currentScope?: Scope): PromiseLike<Event> {\n    const options = this.getOptions();\n    const { sampleRate } = options;\n\n    const isTransaction = isTransactionEvent(event);\n    const isError = isErrorEvent(event);\n    const eventType = event.type || 'error';\n    const beforeSendLabel = `before send for type \\`${eventType}\\``;\n\n    // 1.0 === 100% events are sent\n    // 0.0 === 0% events are sent\n    // Sampling for transaction happens somewhere else\n    const parsedSampleRate = typeof sampleRate === 'undefined' ? undefined : parseSampleRate(sampleRate);\n    if (isError && typeof parsedSampleRate === 'number' && Math.random() > parsedSampleRate) {\n      this.recordDroppedEvent('sample_rate', 'error', event);\n      return rejectedSyncPromise(\n        new SentryError(\n          `Discarding event because it's not included in the random sample (sampling rate = ${sampleRate})`,\n          'log',\n        ),\n      );\n    }\n\n    const dataCategory: DataCategory = eventType === 'replay_event' ? 'replay' : eventType;\n\n    const sdkProcessingMetadata = event.sdkProcessingMetadata || {};\n    const capturedSpanIsolationScope: Scope | undefined = sdkProcessingMetadata.capturedSpanIsolationScope;\n\n    return this._prepareEvent(event, hint, currentScope, capturedSpanIsolationScope)\n      .then(prepared => {\n        if (prepared === null) {\n          this.recordDroppedEvent('event_processor', dataCategory, event);\n          throw new SentryError('An event processor returned `null`, will not send event.', 'log');\n        }\n\n        const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true;\n        if (isInternalException) {\n          return prepared;\n        }\n\n        const result = processBeforeSend(this, options, prepared, hint);\n        return _validateBeforeSendResult(result, beforeSendLabel);\n      })\n      .then(processedEvent => {\n        if (processedEvent === null) {\n          this.recordDroppedEvent('before_send', dataCategory, event);\n          if (isTransaction) {\n            const spans = event.spans || [];\n            // the transaction itself counts as one span, plus all the child spans that are added\n            const spanCount = 1 + spans.length;\n            this.recordDroppedEvent('before_send', 'span', spanCount);\n          }\n          throw new SentryError(`${beforeSendLabel} returned \\`null\\`, will not send event.`, 'log');\n        }\n\n        const session = currentScope && currentScope.getSession();\n        if (!isTransaction && session) {\n          this._updateSessionFromEvent(session, processedEvent);\n        }\n\n        if (isTransaction) {\n          const spanCountBefore =\n            (processedEvent.sdkProcessingMetadata && processedEvent.sdkProcessingMetadata.spanCountBeforeProcessing) ||\n            0;\n          const spanCountAfter = processedEvent.spans ? processedEvent.spans.length : 0;\n\n          const droppedSpanCount = spanCountBefore - spanCountAfter;\n          if (droppedSpanCount > 0) {\n            this.recordDroppedEvent('before_send', 'span', droppedSpanCount);\n          }\n        }\n\n        // None of the Sentry built event processor will update transaction name,\n        // so if the transaction name has been changed by an event processor, we know\n        // it has to come from custom event processor added by a user\n        const transactionInfo = processedEvent.transaction_info;\n        if (isTransaction && transactionInfo && processedEvent.transaction !== event.transaction) {\n          const source = 'custom';\n          processedEvent.transaction_info = {\n            ...transactionInfo,\n            source,\n          };\n        }\n\n        this.sendEvent(processedEvent, hint);\n        return processedEvent;\n      })\n      .then(null, reason => {\n        if (reason instanceof SentryError) {\n          throw reason;\n        }\n\n        this.captureException(reason, {\n          data: {\n            __sentry__: true,\n          },\n          originalException: reason,\n        });\n        throw new SentryError(\n          `Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\\nReason: ${reason}`,\n        );\n      });\n  }\n\n  /**\n   * Occupies the client with processing and event\n   */\n  protected _process<T>(promise: PromiseLike<T>): void {\n    this._numProcessing++;\n    void promise.then(\n      value => {\n        this._numProcessing--;\n        return value;\n      },\n      reason => {\n        this._numProcessing--;\n        return reason;\n      },\n    );\n  }\n\n  /**\n   * Clears outcomes on this client and returns them.\n   */\n  protected _clearOutcomes(): Outcome[] {\n    const outcomes = this._outcomes;\n    this._outcomes = {};\n    return Object.entries(outcomes).map(([key, quantity]) => {\n      const [reason, category] = key.split(':') as [EventDropReason, DataCategory];\n      return {\n        reason,\n        category,\n        quantity,\n      };\n    });\n  }\n\n  /**\n   * Sends client reports as an envelope.\n   */\n  protected _flushOutcomes(): void {\n    DEBUG_BUILD && logger.log('Flushing outcomes...');\n\n    const outcomes = this._clearOutcomes();\n\n    if (outcomes.length === 0) {\n      DEBUG_BUILD && logger.log('No outcomes to send');\n      return;\n    }\n\n    // This is really the only place where we want to check for a DSN and only send outcomes then\n    if (!this._dsn) {\n      DEBUG_BUILD && logger.log('No dsn provided, will not send outcomes');\n      return;\n    }\n\n    DEBUG_BUILD && logger.log('Sending outcomes:', outcomes);\n\n    const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn));\n\n    // sendEnvelope should not throw\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.sendEnvelope(envelope);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public abstract eventFromException(_exception: unknown, _hint?: EventHint): PromiseLike<Event>;\n\n  /**\n   * @inheritDoc\n   */\n  public abstract eventFromMessage(\n    _message: ParameterizedString,\n    _level?: SeverityLevel,\n    _hint?: EventHint,\n  ): PromiseLike<Event>;\n}\n\n/**\n * Verifies that return value of configured `beforeSend` or `beforeSendTransaction` is of expected type, and returns the value if so.\n */\nfunction _validateBeforeSendResult(\n  beforeSendResult: PromiseLike<Event | null> | Event | null,\n  beforeSendLabel: string,\n): PromiseLike<Event | null> | Event | null {\n  const invalidValueError = `${beforeSendLabel} must return \\`null\\` or a valid event.`;\n  if (isThenable(beforeSendResult)) {\n    return beforeSendResult.then(\n      event => {\n        if (!isPlainObject(event) && event !== null) {\n          throw new SentryError(invalidValueError);\n        }\n        return event;\n      },\n      e => {\n        throw new SentryError(`${beforeSendLabel} rejected with ${e}`);\n      },\n    );\n  } else if (!isPlainObject(beforeSendResult) && beforeSendResult !== null) {\n    throw new SentryError(invalidValueError);\n  }\n  return beforeSendResult;\n}\n\n/**\n * Process the matching `beforeSendXXX` callback.\n */\nfunction processBeforeSend(\n  client: Client,\n  options: ClientOptions,\n  event: Event,\n  hint: EventHint,\n): PromiseLike<Event | null> | Event | null {\n  const { beforeSend, beforeSendTransaction, beforeSendSpan } = options;\n\n  if (isErrorEvent(event) && beforeSend) {\n    return beforeSend(event, hint);\n  }\n\n  if (isTransactionEvent(event)) {\n    if (event.spans && beforeSendSpan) {\n      const processedSpans: SpanJSON[] = [];\n      for (const span of event.spans) {\n        const processedSpan = beforeSendSpan(span);\n        if (processedSpan) {\n          processedSpans.push(processedSpan);\n        } else {\n          showSpanDropWarning();\n          client.recordDroppedEvent('before_send', 'span');\n        }\n      }\n      event.spans = processedSpans;\n    }\n\n    if (beforeSendTransaction) {\n      if (event.spans) {\n        // We store the # of spans before processing in SDK metadata,\n        // so we can compare it afterwards to determine how many spans were dropped\n        const spanCountBefore = event.spans.length;\n        event.sdkProcessingMetadata = {\n          ...event.sdkProcessingMetadata,\n          spanCountBeforeProcessing: spanCountBefore,\n        };\n      }\n      return beforeSendTransaction(event, hint);\n    }\n  }\n\n  return event;\n}\n\nfunction isErrorEvent(event: Event): event is ErrorEvent {\n  return event.type === undefined;\n}\n\nfunction isTransactionEvent(event: Event): event is TransactionEvent {\n  return event.type === 'transaction';\n}\n", "import { getCurrentScope } from './currentScopes';\nimport type { Client, ClientOptions } from './types-hoist';\n\nimport { DEBUG_BUILD } from './debug-build';\nimport { consoleSandbox, logger } from './utils-hoist/logger';\n\n/** A class object that can instantiate Client objects. */\nexport type ClientClass<F extends Client, O extends ClientOptions> = new (options: O) => F;\n\n/**\n * Internal function to create a new SDK client instance. The client is\n * installed and then bound to the current scope.\n *\n * @param clientClass The client class to instantiate.\n * @param options Options to pass to the client.\n */\nexport function initAndBind<F extends Client, O extends ClientOptions>(\n  clientClass: ClientClass<F, O>,\n  options: O,\n): Client {\n  if (options.debug === true) {\n    if (DEBUG_BUILD) {\n      logger.enable();\n    } else {\n      // use `console.warn` rather than `logger.warn` since by non-debug bundles have all `logger.x` statements stripped\n      consoleSandbox(() => {\n        // eslint-disable-next-line no-console\n        console.warn('[Sentry] Cannot initialize SDK with `debug` option using a non-debug bundle.');\n      });\n    }\n  }\n  const scope = getCurrentScope();\n  scope.update(options.initialScope);\n\n  const client = new clientClass(options);\n  setCurrentClient(client);\n  client.init();\n  return client;\n}\n\n/**\n * Make the given client the current client.\n */\nexport function setCurrentClient(client: Client): void {\n  getCurrentScope().setClient(client);\n}\n", "import { SentryError } from './error';\nimport { SyncPromise, rejectedSyncPromise, resolvedSyncPromise } from './syncpromise';\n\nexport interface PromiseBuffer<T> {\n  // exposes the internal array so tests can assert on the state of it.\n  // XXX: this really should not be public api.\n  $: Array<PromiseLike<T>>;\n  add(taskProducer: () => PromiseLike<T>): PromiseLike<T>;\n  drain(timeout?: number): PromiseLike<boolean>;\n}\n\n/**\n * Creates an new PromiseBuffer object with the specified limit\n * @param limit max number of promises that can be stored in the buffer\n */\nexport function makePromiseBuffer<T>(limit?: number): PromiseBuffer<T> {\n  const buffer: Array<PromiseLike<T>> = [];\n\n  function isReady(): boolean {\n    return limit === undefined || buffer.length < limit;\n  }\n\n  /**\n   * Remove a promise from the queue.\n   *\n   * @param task Can be any PromiseLike<T>\n   * @returns Removed promise.\n   */\n  function remove(task: PromiseLike<T>): PromiseLike<T | void> {\n    return buffer.splice(buffer.indexOf(task), 1)[0] || Promise.resolve(undefined);\n  }\n\n  /**\n   * Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.\n   *\n   * @param taskProducer A function producing any PromiseLike<T>; In previous versions this used to be `task:\n   *        PromiseLike<T>`, but under that model, Promises were instantly created on the call-site and their executor\n   *        functions therefore ran immediately. Thus, even if the buffer was full, the action still happened. By\n   *        requiring the promise to be wrapped in a function, we can defer promise creation until after the buffer\n   *        limit check.\n   * @returns The original promise.\n   */\n  function add(taskProducer: () => PromiseLike<T>): PromiseLike<T> {\n    if (!isReady()) {\n      return rejectedSyncPromise(new SentryError('Not adding Promise because buffer limit was reached.'));\n    }\n\n    // start the task and add its promise to the queue\n    const task = taskProducer();\n    if (buffer.indexOf(task) === -1) {\n      buffer.push(task);\n    }\n    void task\n      .then(() => remove(task))\n      // Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`\n      // rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't\n      // have promises, so TS has to polyfill when down-compiling.)\n      .then(null, () =>\n        remove(task).then(null, () => {\n          // We have to add another catch here because `remove()` starts a new promise chain.\n        }),\n      );\n    return task;\n  }\n\n  /**\n   * Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.\n   *\n   * @param timeout The time, in ms, after which to resolve to `false` if the queue is still non-empty. Passing `0` (or\n   * not passing anything) will make the promise wait as long as it takes for the queue to drain before resolving to\n   * `true`.\n   * @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and\n   * `false` otherwise\n   */\n  function drain(timeout?: number): PromiseLike<boolean> {\n    return new SyncPromise<boolean>((resolve, reject) => {\n      let counter = buffer.length;\n\n      if (!counter) {\n        return resolve(true);\n      }\n\n      // wait for `timeout` ms and then resolve to `false` (if not cancelled first)\n      const capturedSetTimeout = setTimeout(() => {\n        if (timeout && timeout > 0) {\n          resolve(false);\n        }\n      }, timeout);\n\n      // if all promises resolve in time, cancel the timer and resolve to `true`\n      buffer.forEach(item => {\n        void resolvedSyncPromise(item).then(() => {\n          if (!--counter) {\n            clearTimeout(capturedSetTimeout);\n            resolve(true);\n          }\n        }, reject);\n      });\n    });\n  }\n\n  return {\n    $: buffer,\n    add,\n    drain,\n  };\n}\n", "import type { DataCategory, TransportMakeRequestResponse } from '../types-hoist';\n\n// Intentionally keeping the key broad, as we don't know for sure what rate limit headers get returned from backend\nexport type RateLimits = Record<string, number>;\n\nexport const DEFAULT_RETRY_AFTER = 60 * 1000; // 60 seconds\n\n/**\n * Extracts Retry-After value from the request header or returns default value\n * @param header string representation of 'Retry-After' header\n * @param now current unix timestamp\n *\n */\nexport function parseRetryAfterHeader(header: string, now: number = Date.now()): number {\n  const headerDelay = parseInt(`${header}`, 10);\n  if (!isNaN(headerDelay)) {\n    return headerDelay * 1000;\n  }\n\n  const headerDate = Date.parse(`${header}`);\n  if (!isNaN(headerDate)) {\n    return headerDate - now;\n  }\n\n  return DEFAULT_RETRY_AFTER;\n}\n\n/**\n * Gets the time that the given category is disabled until for rate limiting.\n * In case no category-specific limit is set but a general rate limit across all categories is active,\n * that time is returned.\n *\n * @return the time in ms that the category is disabled until or 0 if there's no active rate limit.\n */\nexport function disabledUntil(limits: RateLimits, dataCategory: DataCategory): number {\n  return limits[dataCategory] || limits.all || 0;\n}\n\n/**\n * Checks if a category is rate limited\n */\nexport function isRateLimited(limits: RateLimits, dataCategory: DataCategory, now: number = Date.now()): boolean {\n  return disabledUntil(limits, dataCategory) > now;\n}\n\n/**\n * Update ratelimits from incoming headers.\n *\n * @return the updated RateLimits object.\n */\nexport function updateRateLimits(\n  limits: RateLimits,\n  { statusCode, headers }: TransportMakeRequestResponse,\n  now: number = Date.now(),\n): RateLimits {\n  const updatedRateLimits: RateLimits = {\n    ...limits,\n  };\n\n  // \"The name is case-insensitive.\"\n  // https://developer.mozilla.org/en-US/docs/Web/API/Headers/get\n  const rateLimitHeader = headers && headers['x-sentry-rate-limits'];\n  const retryAfterHeader = headers && headers['retry-after'];\n\n  if (rateLimitHeader) {\n    /**\n     * rate limit headers are of the form\n     *     <header>,<header>,..\n     * where each <header> is of the form\n     *     <retry_after>: <categories>: <scope>: <reason_code>: <namespaces>\n     * where\n     *     <retry_after> is a delay in seconds\n     *     <categories> is the event type(s) (error, transaction, etc) being rate limited and is of the form\n     *         <category>;<category>;...\n     *     <scope> is what's being limited (org, project, or key) - ignored by SDK\n     *     <reason_code> is an arbitrary string like \"org_quota\" - ignored by SDK\n     *     <namespaces> Semicolon-separated list of metric namespace identifiers. Defines which namespace(s) will be affected.\n     *         Only present if rate limit applies to the metric_bucket data category.\n     */\n    for (const limit of rateLimitHeader.trim().split(',')) {\n      const [retryAfter, categories, , , namespaces] = limit.split(':', 5) as [string, ...string[]];\n      const headerDelay = parseInt(retryAfter, 10);\n      const delay = (!isNaN(headerDelay) ? headerDelay : 60) * 1000; // 60sec default\n      if (!categories) {\n        updatedRateLimits.all = now + delay;\n      } else {\n        for (const category of categories.split(';')) {\n          if (category === 'metric_bucket') {\n            // namespaces will be present when category === 'metric_bucket'\n            if (!namespaces || namespaces.split(';').includes('custom')) {\n              updatedRateLimits[category] = now + delay;\n            }\n          } else {\n            updatedRateLimits[category] = now + delay;\n          }\n        }\n      }\n    }\n  } else if (retryAfterHeader) {\n    updatedRateLimits.all = now + parseRetryAfterHeader(retryAfterHeader, now);\n  } else if (statusCode === 429) {\n    updatedRateLimits.all = now + 60 * 1000;\n  }\n\n  return updatedRateLimits;\n}\n", "import type {\n  Envelope,\n  EnvelopeItem,\n  EnvelopeItemType,\n  Event,\n  EventDropReason,\n  EventItem,\n  InternalBaseTransportOptions,\n  Transport,\n  TransportMakeRequestResponse,\n  TransportRequestExecutor,\n} from '../types-hoist';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport {\n  createEnvelope,\n  envelopeItemTypeToDataCategory,\n  forEachEnvelopeItem,\n  serializeEnvelope,\n} from '../utils-hoist/envelope';\nimport { SentryError } from '../utils-hoist/error';\nimport { logger } from '../utils-hoist/logger';\nimport { type PromiseBuffer, makePromiseBuffer } from '../utils-hoist/promisebuffer';\nimport { type RateLimits, isRateLimited, updateRateLimits } from '../utils-hoist/ratelimit';\nimport { resolvedSyncPromise } from '../utils-hoist/syncpromise';\n\nexport const DEFAULT_TRANSPORT_BUFFER_SIZE = 64;\n\n/**\n * Creates an instance of a Sentry `Transport`\n *\n * @param options\n * @param makeRequest\n */\nexport function createTransport(\n  options: InternalBaseTransportOptions,\n  makeRequest: TransportRequestExecutor,\n  buffer: PromiseBuffer<TransportMakeRequestResponse> = makePromiseBuffer(\n    options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE,\n  ),\n): Transport {\n  let rateLimits: RateLimits = {};\n  const flush = (timeout?: number): PromiseLike<boolean> => buffer.drain(timeout);\n\n  function send(envelope: Envelope): PromiseLike<TransportMakeRequestResponse> {\n    const filteredEnvelopeItems: EnvelopeItem[] = [];\n\n    // Drop rate limited items from envelope\n    forEachEnvelopeItem(envelope, (item, type) => {\n      const dataCategory = envelopeItemTypeToDataCategory(type);\n      if (isRateLimited(rateLimits, dataCategory)) {\n        const event: Event | undefined = getEventForEnvelopeItem(item, type);\n        options.recordDroppedEvent('ratelimit_backoff', dataCategory, event);\n      } else {\n        filteredEnvelopeItems.push(item);\n      }\n    });\n\n    // Skip sending if envelope is empty after filtering out rate limited events\n    if (filteredEnvelopeItems.length === 0) {\n      return resolvedSyncPromise({});\n    }\n\n    const filteredEnvelope: Envelope = createEnvelope(envelope[0], filteredEnvelopeItems as (typeof envelope)[1]);\n\n    // Creates client report for each item in an envelope\n    const recordEnvelopeLoss = (reason: EventDropReason): void => {\n      forEachEnvelopeItem(filteredEnvelope, (item, type) => {\n        const event: Event | undefined = getEventForEnvelopeItem(item, type);\n        options.recordDroppedEvent(reason, envelopeItemTypeToDataCategory(type), event);\n      });\n    };\n\n    const requestTask = (): PromiseLike<TransportMakeRequestResponse> =>\n      makeRequest({ body: serializeEnvelope(filteredEnvelope) }).then(\n        response => {\n          // We don't want to throw on NOK responses, but we want to at least log them\n          if (response.statusCode !== undefined && (response.statusCode < 200 || response.statusCode >= 300)) {\n            DEBUG_BUILD && logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`);\n          }\n\n          rateLimits = updateRateLimits(rateLimits, response);\n          return response;\n        },\n        error => {\n          recordEnvelopeLoss('network_error');\n          throw error;\n        },\n      );\n\n    return buffer.add(requestTask).then(\n      result => result,\n      error => {\n        if (error instanceof SentryError) {\n          DEBUG_BUILD && logger.error('Skipped sending event because buffer is full.');\n          recordEnvelopeLoss('queue_overflow');\n          return resolvedSyncPromise({});\n        } else {\n          throw error;\n        }\n      },\n    );\n  }\n\n  return {\n    send,\n    flush,\n  };\n}\n\nfunction getEventForEnvelopeItem(item: Envelope[1][number], type: EnvelopeItemType): Event | undefined {\n  if (type !== 'event' && type !== 'transaction') {\n    return undefined;\n  }\n\n  return Array.isArray(item) ? (item as EventItem)[1] : undefined;\n}\n", "import type { Envelope, InternalBaseTransportOptions, Transport, TransportMakeRequestResponse } from '../types-hoist';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { envelopeContainsItemType } from '../utils-hoist/envelope';\nimport { logger } from '../utils-hoist/logger';\nimport { parseRetryAfterHeader } from '../utils-hoist/ratelimit';\n\nexport const MIN_DELAY = 100; // 100 ms\nexport const START_DELAY = 5_000; // 5 seconds\nconst MAX_DELAY = 3.6e6; // 1 hour\n\nexport interface OfflineStore {\n  push(env: Envelope): Promise<void>;\n  unshift(env: Envelope): Promise<void>;\n  shift(): Promise<Envelope | undefined>;\n}\n\nexport type CreateOfflineStore = (options: OfflineTransportOptions) => OfflineStore;\n\nexport interface OfflineTransportOptions extends InternalBaseTransportOptions {\n  /**\n   * A function that creates the offline store instance.\n   */\n  createStore?: CreateOfflineStore;\n\n  /**\n   * Flush the offline store shortly after startup.\n   *\n   * Defaults: false\n   */\n  flushAtStartup?: boolean;\n\n  /**\n   * Called before an event is stored.\n   *\n   * Return false to drop the envelope rather than store it.\n   *\n   * @param envelope The envelope that failed to send.\n   * @param error The error that occurred.\n   * @param retryDelay The current retry delay in milliseconds.\n   */\n  shouldStore?: (envelope: Envelope, error: Error, retryDelay: number) => boolean | Promise<boolean>;\n}\n\ntype Timer = number | { unref?: () => void };\n\n/**\n * Wraps a transport and stores and retries events when they fail to send.\n *\n * @param createTransport The transport to wrap.\n */\nexport function makeOfflineTransport<TO>(\n  createTransport: (options: TO) => Transport,\n): (options: TO & OfflineTransportOptions) => Transport {\n  function log(...args: unknown[]): void {\n    DEBUG_BUILD && logger.info('[Offline]:', ...args);\n  }\n\n  return options => {\n    const transport = createTransport(options);\n\n    if (!options.createStore) {\n      throw new Error('No `createStore` function was provided');\n    }\n\n    const store = options.createStore(options);\n\n    let retryDelay = START_DELAY;\n    let flushTimer: Timer | undefined;\n\n    function shouldQueue(env: Envelope, error: Error, retryDelay: number): boolean | Promise<boolean> {\n      // We want to drop client reports because they can be generated when we retry sending events while offline.\n      if (envelopeContainsItemType(env, ['client_report'])) {\n        return false;\n      }\n\n      if (options.shouldStore) {\n        return options.shouldStore(env, error, retryDelay);\n      }\n\n      return true;\n    }\n\n    function flushIn(delay: number): void {\n      if (flushTimer) {\n        clearTimeout(flushTimer as ReturnType<typeof setTimeout>);\n      }\n\n      flushTimer = setTimeout(async () => {\n        flushTimer = undefined;\n\n        const found = await store.shift();\n        if (found) {\n          log('Attempting to send previously queued event');\n\n          // We should to update the sent_at timestamp to the current time.\n          found[0].sent_at = new Date().toISOString();\n\n          void send(found, true).catch(e => {\n            log('Failed to retry sending', e);\n          });\n        }\n      }, delay) as Timer;\n\n      // We need to unref the timer in node.js, otherwise the node process never exit.\n      if (typeof flushTimer !== 'number' && flushTimer.unref) {\n        flushTimer.unref();\n      }\n    }\n\n    function flushWithBackOff(): void {\n      if (flushTimer) {\n        return;\n      }\n\n      flushIn(retryDelay);\n\n      retryDelay = Math.min(retryDelay * 2, MAX_DELAY);\n    }\n\n    async function send(envelope: Envelope, isRetry: boolean = false): Promise<TransportMakeRequestResponse> {\n      // We queue all replay envelopes to avoid multiple replay envelopes being sent at the same time. If one fails, we\n      // need to retry them in order.\n      if (!isRetry && envelopeContainsItemType(envelope, ['replay_event', 'replay_recording'])) {\n        await store.push(envelope);\n        flushIn(MIN_DELAY);\n        return {};\n      }\n\n      try {\n        const result = await transport.send(envelope);\n\n        let delay = MIN_DELAY;\n\n        if (result) {\n          // If there's a retry-after header, use that as the next delay.\n          if (result.headers && result.headers['retry-after']) {\n            delay = parseRetryAfterHeader(result.headers['retry-after']);\n          } else if (result.headers && result.headers['x-sentry-rate-limits']) {\n            delay = 60_000; // 60 seconds\n          } // If we have a server error, return now so we don't flush the queue.\n          else if ((result.statusCode || 0) >= 400) {\n            return result;\n          }\n        }\n\n        flushIn(delay);\n        retryDelay = START_DELAY;\n        return result;\n      } catch (e) {\n        if (await shouldQueue(envelope, e as Error, retryDelay)) {\n          // If this envelope was a retry, we want to add it to the front of the queue so it's retried again first.\n          if (isRetry) {\n            await store.unshift(envelope);\n          } else {\n            await store.push(envelope);\n          }\n          flushWithBackOff();\n          log('Error sending. Event queued.', e as Error);\n          return {};\n        } else {\n          throw e;\n        }\n      }\n    }\n\n    if (options.flushAtStartup) {\n      flushWithBackOff();\n    }\n\n    return {\n      send,\n      flush: timeout => {\n        // If there's no timeout, we should attempt to flush the offline queue.\n        if (timeout === undefined) {\n          retryDelay = START_DELAY;\n          flushIn(MIN_DELAY);\n        }\n\n        return transport.flush(timeout);\n      },\n    };\n  };\n}\n", "import type {\n  BaseTransportOptions,\n  Envelope,\n  EnvelopeItemType,\n  Event,\n  EventItem,\n  Transport,\n  TransportMakeRequestResponse,\n} from '../types-hoist';\n\nimport { getEnvelopeEndpointWithUrlEncodedAuth } from '../api';\nimport { dsnFromString } from '../utils-hoist/dsn';\nimport { createEnvelope, forEachEnvelopeItem } from '../utils-hoist/envelope';\n\ninterface MatchParam {\n  /** The envelope to be sent */\n  envelope: Envelope;\n  /**\n   * A function that returns an event from the envelope if one exists. You can optionally pass an array of envelope item\n   * types to filter by - only envelopes matching the given types will be multiplexed.\n   * Allowed values are: 'event', 'transaction', 'profile', 'replay_event'\n   *\n   * @param types Defaults to ['event']\n   */\n  getEvent(types?: EnvelopeItemType[]): Event | undefined;\n}\n\ntype RouteTo = { dsn: string; release: string };\ntype Matcher = (param: MatchParam) => (string | RouteTo)[];\n\n/**\n * Gets an event from an envelope.\n *\n * This is only exported for use in the tests\n */\nexport function eventFromEnvelope(env: Envelope, types: EnvelopeItemType[]): Event | undefined {\n  let event: Event | undefined;\n\n  forEachEnvelopeItem(env, (item, type) => {\n    if (types.includes(type)) {\n      event = Array.isArray(item) ? (item as EventItem)[1] : undefined;\n    }\n    // bail out if we found an event\n    return !!event;\n  });\n\n  return event;\n}\n\n/**\n * Creates a transport that overrides the release on all events.\n */\nfunction makeOverrideReleaseTransport<TO extends BaseTransportOptions>(\n  createTransport: (options: TO) => Transport,\n  release: string,\n): (options: TO) => Transport {\n  return options => {\n    const transport = createTransport(options);\n\n    return {\n      ...transport,\n      send: async (envelope: Envelope): Promise<TransportMakeRequestResponse> => {\n        const event = eventFromEnvelope(envelope, ['event', 'transaction', 'profile', 'replay_event']);\n\n        if (event) {\n          event.release = release;\n        }\n        return transport.send(envelope);\n      },\n    };\n  };\n}\n\n/** Overrides the DSN in the envelope header  */\nfunction overrideDsn(envelope: Envelope, dsn: string): Envelope {\n  return createEnvelope(\n    dsn\n      ? {\n          ...envelope[0],\n          dsn,\n        }\n      : envelope[0],\n    envelope[1],\n  );\n}\n\n/**\n * Creates a transport that can send events to different DSNs depending on the envelope contents.\n */\nexport function makeMultiplexedTransport<TO extends BaseTransportOptions>(\n  createTransport: (options: TO) => Transport,\n  matcher: Matcher,\n): (options: TO) => Transport {\n  return options => {\n    const fallbackTransport = createTransport(options);\n    const otherTransports: Map<string, Transport> = new Map();\n\n    function getTransport(dsn: string, release: string | undefined): [string, Transport] | undefined {\n      // We create a transport for every unique dsn/release combination as there may be code from multiple releases in\n      // use at the same time\n      const key = release ? `${dsn}:${release}` : dsn;\n\n      let transport = otherTransports.get(key);\n\n      if (!transport) {\n        const validatedDsn = dsnFromString(dsn);\n        if (!validatedDsn) {\n          return undefined;\n        }\n        const url = getEnvelopeEndpointWithUrlEncodedAuth(validatedDsn, options.tunnel);\n\n        transport = release\n          ? makeOverrideReleaseTransport(createTransport, release)({ ...options, url })\n          : createTransport({ ...options, url });\n\n        otherTransports.set(key, transport);\n      }\n\n      return [dsn, transport];\n    }\n\n    async function send(envelope: Envelope): Promise<TransportMakeRequestResponse> {\n      function getEvent(types?: EnvelopeItemType[]): Event | undefined {\n        const eventTypes: EnvelopeItemType[] = types && types.length ? types : ['event'];\n        return eventFromEnvelope(envelope, eventTypes);\n      }\n\n      const transports = matcher({ envelope, getEvent })\n        .map(result => {\n          if (typeof result === 'string') {\n            return getTransport(result, undefined);\n          } else {\n            return getTransport(result.dsn, result.release);\n          }\n        })\n        .filter((t): t is [string, Transport] => !!t);\n\n      // If we have no transports to send to, use the fallback transport\n      // Don't override the DSN in the header for the fallback transport. '' is falsy\n      const transportsWithFallback: [string, Transport][] = transports.length ? transports : [['', fallbackTransport]];\n\n      const results = (await Promise.all(\n        transportsWithFallback.map(([dsn, transport]) => transport.send(overrideDsn(envelope, dsn))),\n      )) as [TransportMakeRequestResponse, ...TransportMakeRequestResponse[]];\n\n      return results[0];\n    }\n\n    async function flush(timeout: number | undefined): Promise<boolean> {\n      const allTransports = [...otherTransports.values(), fallbackTransport];\n      const results = await Promise.all(allTransports.map(transport => transport.flush(timeout)));\n      return results.every(r => r);\n    }\n\n    return {\n      send,\n      flush,\n    };\n  };\n}\n", "import type { Client, DsnComponents } from '../types-hoist';\n\n/**\n * Checks whether given url points to Sentry server\n *\n * @param url url to verify\n */\nexport function isSentryRequestUrl(url: string, client: Client | undefined): boolean {\n  const dsn = client && client.getDsn();\n  const tunnel = client && client.getOptions().tunnel;\n  return checkDsn(url, dsn) || checkTunnel(url, tunnel);\n}\n\nfunction checkTunnel(url: string, tunnel: string | undefined): boolean {\n  if (!tunnel) {\n    return false;\n  }\n\n  return removeTrailingSlash(url) === removeTrailingSlash(tunnel);\n}\n\nfunction checkDsn(url: string, dsn: DsnComponents | undefined): boolean {\n  return dsn ? url.includes(dsn.host) : false;\n}\n\nfunction removeTrailingSlash(str: string): string {\n  return str[str.length - 1] === '/' ? str.slice(0, -1) : str;\n}\n", "import type { ParameterizedString } from '../types-hoist';\n\n/**\n * Tagged template function which returns parameterized representation of the message\n * For example: parameterize`This is a log statement with ${x} and ${y} params`, would return:\n * \"__sentry_template_string__\": 'This is a log statement with %s and %s params',\n * \"__sentry_template_values__\": ['first', 'second']\n * @param strings An array of string values splitted between expressions\n * @param values Expressions extracted from template string\n * @returns String with template information in __sentry_template_string__ and __sentry_template_values__ properties\n */\nexport function parameterize(strings: TemplateStringsArray, ...values: string[]): ParameterizedString {\n  const formatted = new String(String.raw(strings, ...values)) as ParameterizedString;\n  formatted.__sentry_template_string__ = strings.join('\\x00').replace(/%/g, '%%').replace(/\\0/g, '%s');\n  formatted.__sentry_template_values__ = values;\n  return formatted;\n}\n", "import type { Options } from '../types-hoist';\nimport { SDK_VERSION } from '../utils-hoist/version';\n\n/**\n * A builder for the SDK metadata in the options for the SDK initialization.\n *\n * Note: This function is identical to `buildMetadata` in Remix and NextJS and SvelteKit.\n * We don't extract it for bundle size reasons.\n * @see https://github.com/getsentry/sentry-javascript/pull/7404\n * @see https://github.com/getsentry/sentry-javascript/pull/4196\n *\n * If you make changes to this function consider updating the others as well.\n *\n * @param options SDK options object that gets mutated\n * @param names list of package names\n */\nexport function applySdkMetadata(options: Options, name: string, names = [name], source = 'npm'): void {\n  const metadata = options._metadata || {};\n\n  if (!metadata.sdk) {\n    metadata.sdk = {\n      name: `sentry.javascript.${name}`,\n      packages: names.map(name => ({\n        name: `${source}:@sentry/${name}`,\n        version: SDK_VERSION,\n      })),\n      version: SDK_VERSION,\n    };\n  }\n\n  options._metadata = metadata;\n}\n", "import { getAsyncContextStrategy } from '../asyncContext';\nimport { getMainCarrier } from '../carrier';\nimport { getClient, getCurrentScope } from '../currentScopes';\nimport { isEnabled } from '../exports';\nimport { getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan } from '../tracing';\nimport type { Scope, SerializedTraceData, Span } from '../types-hoist';\nimport { dynamicSamplingContextToSentryBaggageHeader } from '../utils-hoist/baggage';\nimport { logger } from '../utils-hoist/logger';\nimport { TRACEPARENT_REGEXP, generateSentryTraceHeader } from '../utils-hoist/tracing';\nimport { getActiveSpan, spanToTraceHeader } from './spanUtils';\n\n/**\n * Extracts trace propagation data from the current span or from the client's scope (via transaction or propagation\n * context) and serializes it to `sentry-trace` and `baggage` values to strings. These values can be used to propagate\n * a trace via our tracing Http headers or Html `<meta>` tags.\n *\n * This function also applies some validation to the generated sentry-trace and baggage values to ensure that\n * only valid strings are returned.\n *\n * @returns an object with the tracing data values. The object keys are the name of the tracing key to be used as header\n * or meta tag name.\n */\nexport function getTraceData(options: { span?: Span } = {}): SerializedTraceData {\n  const client = getClient();\n  if (!isEnabled() || !client) {\n    return {};\n  }\n\n  const carrier = getMainCarrier();\n  const acs = getAsyncContextStrategy(carrier);\n  if (acs.getTraceData) {\n    return acs.getTraceData(options);\n  }\n\n  const scope = getCurrentScope();\n  const span = options.span || getActiveSpan();\n  const sentryTrace = span ? spanToTraceHeader(span) : scopeToTraceHeader(scope);\n  const dsc = span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromScope(client, scope);\n  const baggage = dynamicSamplingContextToSentryBaggageHeader(dsc);\n\n  const isValidSentryTraceHeader = TRACEPARENT_REGEXP.test(sentryTrace);\n  if (!isValidSentryTraceHeader) {\n    logger.warn('Invalid sentry-trace data. Cannot generate trace data');\n    return {};\n  }\n\n  return {\n    'sentry-trace': sentryTrace,\n    baggage,\n  };\n}\n\n/**\n * Get a sentry-trace header value for the given scope.\n */\nfunction scopeToTraceHeader(scope: Scope): string {\n  // TODO(v9): Use generateSpanId() instead of spanId\n  // eslint-disable-next-line deprecation/deprecation\n  const { traceId, sampled, spanId } = scope.getPropagationContext();\n  return generateSentryTraceHeader(traceId, spanId, sampled);\n}\n", "import { getClient, getIsolationScope } from './currentScopes';\nimport type { Breadcrumb, BreadcrumbHint } from './types-hoist';\nimport { consoleSandbox } from './utils-hoist/logger';\nimport { dateTimestampInSeconds } from './utils-hoist/time';\n\n/**\n * Default maximum number of breadcrumbs added to an event. Can be overwritten\n * with {@link Options.maxBreadcrumbs}.\n */\nconst DEFAULT_BREADCRUMBS = 100;\n\n/**\n * Records a new breadcrumb which will be attached to future events.\n *\n * Breadcrumbs will be added to subsequent events to provide more context on\n * user's actions prior to an error or crash.\n */\nexport function addBreadcrumb(breadcrumb: Breadcrumb, hint?: BreadcrumbHint): void {\n  const client = getClient();\n  const isolationScope = getIsolationScope();\n\n  if (!client) return;\n\n  const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } = client.getOptions();\n\n  if (maxBreadcrumbs <= 0) return;\n\n  const timestamp = dateTimestampInSeconds();\n  const mergedBreadcrumb = { timestamp, ...breadcrumb };\n  const finalBreadcrumb = beforeBreadcrumb\n    ? (consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) as Breadcrumb | null)\n    : mergedBreadcrumb;\n\n  if (finalBreadcrumb === null) return;\n\n  if (client.emit) {\n    client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);\n  }\n\n  isolationScope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);\n}\n", "import { getClient } from '../currentScopes';\nimport { defineIntegration } from '../integration';\nimport type { Client, IntegrationFn, WrappedFunction } from '../types-hoist';\nimport { getOriginalFunction } from '../utils-hoist/object';\n\nlet originalFunctionToString: () => void;\n\nconst INTEGRATION_NAME = 'FunctionToString';\n\nconst SETUP_CLIENTS = new WeakMap<Client, boolean>();\n\nconst _functionToStringIntegration = (() => {\n  return {\n    name: INTEGRATION_NAME,\n    setupOnce() {\n      // eslint-disable-next-line @typescript-eslint/unbound-method\n      originalFunctionToString = Function.prototype.toString;\n\n      // intrinsics (like Function.prototype) might be immutable in some environments\n      // e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal)\n      try {\n        Function.prototype.toString = function (this: WrappedFunction, ...args: unknown[]): string {\n          const originalFunction = getOriginalFunction(this);\n          const context =\n            SETUP_CLIENTS.has(getClient() as Client) && originalFunction !== undefined ? originalFunction : this;\n          return originalFunctionToString.apply(context, args);\n        };\n      } catch {\n        // ignore errors here, just don't patch this\n      }\n    },\n    setup(client) {\n      SETUP_CLIENTS.set(client, true);\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Patch toString calls to return proper name for wrapped functions.\n *\n * ```js\n * Sentry.init({\n *   integrations: [\n *     functionToStringIntegration(),\n *   ],\n * });\n * ```\n */\nexport const functionToStringIntegration = defineIntegration(_functionToStringIntegration);\n", "import type { Event, IntegrationFn, StackFrame } from '../types-hoist';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { defineIntegration } from '../integration';\nimport { logger } from '../utils-hoist/logger';\nimport { getEventDescription } from '../utils-hoist/misc';\nimport { stringMatchesSomePattern } from '../utils-hoist/string';\n\n// \"Script error.\" is hard coded into browsers for errors that it can't read.\n// this is the result of a script being pulled in from an external domain and CORS.\nconst DEFAULT_IGNORE_ERRORS = [\n  /^Script error\\.?$/,\n  /^Javascript error: Script error\\.? on line 0$/,\n  /^ResizeObserver loop completed with undelivered notifications.$/, // The browser logs this when a ResizeObserver handler takes a bit longer. Usually this is not an actual issue though. It indicates slowness.\n  /^Cannot redefine property: googletag$/, // This is thrown when google tag manager is used in combination with an ad blocker\n  /^Can't find variable: gmo$/, // Error from Google Search App https://issuetracker.google.com/issues/396043331\n  \"undefined is not an object (evaluating 'a.L')\", // Random error that happens but not actionable or noticeable to end-users.\n  'can\\'t redefine non-configurable property \"solana\"', // Probably a browser extension or custom browser (Brave) throwing this error\n  \"vv().getRestrictions is not a function. (In 'vv().getRestrictions(1,a)', 'vv().getRestrictions' is undefined)\", // Error thrown by GTM, seemingly not affecting end-users\n  \"Can't find variable: _AutofillCallbackHandler\", // Unactionable error in instagram webview https://developers.facebook.com/community/threads/320013549791141/\n  /^Non-Error promise rejection captured with value: Object Not Found Matching Id:\\d+, MethodName:simulateEvent, ParamCount:\\d+$/, // unactionable error from CEFSharp, a .NET library that embeds chromium in .NET apps\n  /^Java exception was raised during method invocation$/, // error from Facebook Mobile browser (https://github.com/getsentry/sentry-javascript/issues/15065)\n];\n\n/** Options for the InboundFilters integration */\nexport interface InboundFiltersOptions {\n  allowUrls: Array<string | RegExp>;\n  denyUrls: Array<string | RegExp>;\n  ignoreErrors: Array<string | RegExp>;\n  ignoreTransactions: Array<string | RegExp>;\n  ignoreInternal: boolean;\n  disableErrorDefaults: boolean;\n}\n\nconst INTEGRATION_NAME = 'InboundFilters';\nconst _inboundFiltersIntegration = ((options: Partial<InboundFiltersOptions> = {}) => {\n  return {\n    name: INTEGRATION_NAME,\n    processEvent(event, _hint, client) {\n      const clientOptions = client.getOptions();\n      const mergedOptions = _mergeOptions(options, clientOptions);\n      return _shouldDropEvent(event, mergedOptions) ? null : event;\n    },\n  };\n}) satisfies IntegrationFn;\n\nexport const inboundFiltersIntegration = defineIntegration(_inboundFiltersIntegration);\n\nfunction _mergeOptions(\n  internalOptions: Partial<InboundFiltersOptions> = {},\n  clientOptions: Partial<InboundFiltersOptions> = {},\n): Partial<InboundFiltersOptions> {\n  return {\n    allowUrls: [...(internalOptions.allowUrls || []), ...(clientOptions.allowUrls || [])],\n    denyUrls: [...(internalOptions.denyUrls || []), ...(clientOptions.denyUrls || [])],\n    ignoreErrors: [\n      ...(internalOptions.ignoreErrors || []),\n      ...(clientOptions.ignoreErrors || []),\n      ...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS),\n    ],\n    ignoreTransactions: [...(internalOptions.ignoreTransactions || []), ...(clientOptions.ignoreTransactions || [])],\n    ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true,\n  };\n}\n\nfunction _shouldDropEvent(event: Event, options: Partial<InboundFiltersOptions>): boolean {\n  if (options.ignoreInternal && _isSentryError(event)) {\n    DEBUG_BUILD &&\n      logger.warn(`Event dropped due to being internal Sentry Error.\\nEvent: ${getEventDescription(event)}`);\n    return true;\n  }\n  if (_isIgnoredError(event, options.ignoreErrors)) {\n    DEBUG_BUILD &&\n      logger.warn(\n        `Event dropped due to being matched by \\`ignoreErrors\\` option.\\nEvent: ${getEventDescription(event)}`,\n      );\n    return true;\n  }\n  if (_isUselessError(event)) {\n    DEBUG_BUILD &&\n      logger.warn(\n        `Event dropped due to not having an error message, error type or stacktrace.\\nEvent: ${getEventDescription(\n          event,\n        )}`,\n      );\n    return true;\n  }\n  if (_isIgnoredTransaction(event, options.ignoreTransactions)) {\n    DEBUG_BUILD &&\n      logger.warn(\n        `Event dropped due to being matched by \\`ignoreTransactions\\` option.\\nEvent: ${getEventDescription(event)}`,\n      );\n    return true;\n  }\n  if (_isDeniedUrl(event, options.denyUrls)) {\n    DEBUG_BUILD &&\n      logger.warn(\n        `Event dropped due to being matched by \\`denyUrls\\` option.\\nEvent: ${getEventDescription(\n          event,\n        )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n      );\n    return true;\n  }\n  if (!_isAllowedUrl(event, options.allowUrls)) {\n    DEBUG_BUILD &&\n      logger.warn(\n        `Event dropped due to not being matched by \\`allowUrls\\` option.\\nEvent: ${getEventDescription(\n          event,\n        )}.\\nUrl: ${_getEventFilterUrl(event)}`,\n      );\n    return true;\n  }\n  return false;\n}\n\nfunction _isIgnoredError(event: Event, ignoreErrors?: Array<string | RegExp>): boolean {\n  // If event.type, this is not an error\n  if (event.type || !ignoreErrors || !ignoreErrors.length) {\n    return false;\n  }\n\n  return _getPossibleEventMessages(event).some(message => stringMatchesSomePattern(message, ignoreErrors));\n}\n\nfunction _isIgnoredTransaction(event: Event, ignoreTransactions?: Array<string | RegExp>): boolean {\n  if (event.type !== 'transaction' || !ignoreTransactions || !ignoreTransactions.length) {\n    return false;\n  }\n\n  const name = event.transaction;\n  return name ? stringMatchesSomePattern(name, ignoreTransactions) : false;\n}\n\nfunction _isDeniedUrl(event: Event, denyUrls?: Array<string | RegExp>): boolean {\n  // TODO: Use Glob instead?\n  if (!denyUrls || !denyUrls.length) {\n    return false;\n  }\n  const url = _getEventFilterUrl(event);\n  return !url ? false : stringMatchesSomePattern(url, denyUrls);\n}\n\nfunction _isAllowedUrl(event: Event, allowUrls?: Array<string | RegExp>): boolean {\n  // TODO: Use Glob instead?\n  if (!allowUrls || !allowUrls.length) {\n    return true;\n  }\n  const url = _getEventFilterUrl(event);\n  return !url ? true : stringMatchesSomePattern(url, allowUrls);\n}\n\nfunction _getPossibleEventMessages(event: Event): string[] {\n  const possibleMessages: string[] = [];\n\n  if (event.message) {\n    possibleMessages.push(event.message);\n  }\n\n  let lastException;\n  try {\n    // @ts-expect-error Try catching to save bundle size\n    lastException = event.exception.values[event.exception.values.length - 1];\n  } catch (e) {\n    // try catching to save bundle size checking existence of variables\n  }\n\n  if (lastException) {\n    if (lastException.value) {\n      possibleMessages.push(lastException.value);\n      if (lastException.type) {\n        possibleMessages.push(`${lastException.type}: ${lastException.value}`);\n      }\n    }\n  }\n\n  return possibleMessages;\n}\n\nfunction _isSentryError(event: Event): boolean {\n  try {\n    // @ts-expect-error can't be a sentry error if undefined\n    return event.exception.values[0].type === 'SentryError';\n  } catch (e) {\n    // ignore\n  }\n  return false;\n}\n\nfunction _getLastValidUrl(frames: StackFrame[] = []): string | null {\n  for (let i = frames.length - 1; i >= 0; i--) {\n    const frame = frames[i];\n\n    if (frame && frame.filename !== '<anonymous>' && frame.filename !== '[native code]') {\n      return frame.filename || null;\n    }\n  }\n\n  return null;\n}\n\nfunction _getEventFilterUrl(event: Event): string | null {\n  try {\n    let frames;\n    try {\n      // @ts-expect-error we only care about frames if the whole thing here is defined\n      frames = event.exception.values[0].stacktrace.frames;\n    } catch (e) {\n      // ignore\n    }\n    return frames ? _getLastValidUrl(frames) : null;\n  } catch (oO) {\n    DEBUG_BUILD && logger.error(`Cannot extract url for event ${getEventDescription(event)}`);\n    return null;\n  }\n}\n\nfunction _isUselessError(event: Event): boolean {\n  if (event.type) {\n    // event is not an error\n    return false;\n  }\n\n  // We only want to consider events for dropping that actually have recorded exception values.\n  if (!event.exception || !event.exception.values || event.exception.values.length === 0) {\n    return false;\n  }\n\n  return (\n    // No top-level message\n    !event.message &&\n    // There are no exception values that have a stacktrace, a non-generic-Error type or value\n    !event.exception.values.some(value => value.stacktrace || (value.type && value.type !== 'Error') || value.value)\n  );\n}\n", "import type { Event, EventHint, Exception, ExtendedError, StackParser } from '../types-hoist';\n\nimport { isInstanceOf } from './is';\nimport { truncate } from './string';\n\n/**\n * Creates exceptions inside `event.exception.values` for errors that are nested on properties based on the `key` parameter.\n */\nexport function applyAggregateErrorsToEvent(\n  exceptionFromErrorImplementation: (stackParser: StackParser, ex: Error) => Exception,\n  parser: StackParser,\n  maxValueLimit: number = 250,\n  key: string,\n  limit: number,\n  event: Event,\n  hint?: EventHint,\n): void {\n  if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {\n    return;\n  }\n\n  // Generally speaking the last item in `event.exception.values` is the exception originating from the original Error\n  const originalException: Exception | undefined =\n    event.exception.values.length > 0 ? event.exception.values[event.exception.values.length - 1] : undefined;\n\n  // We only create exception grouping if there is an exception in the event.\n  if (originalException) {\n    event.exception.values = truncateAggregateExceptions(\n      aggregateExceptionsFromError(\n        exceptionFromErrorImplementation,\n        parser,\n        limit,\n        hint.originalException as ExtendedError,\n        key,\n        event.exception.values,\n        originalException,\n        0,\n      ),\n      maxValueLimit,\n    );\n  }\n}\n\nfunction aggregateExceptionsFromError(\n  exceptionFromErrorImplementation: (stackParser: StackParser, ex: Error) => Exception,\n  parser: StackParser,\n  limit: number,\n  error: ExtendedError,\n  key: string,\n  prevExceptions: Exception[],\n  exception: Exception,\n  exceptionId: number,\n): Exception[] {\n  if (prevExceptions.length >= limit + 1) {\n    return prevExceptions;\n  }\n\n  let newExceptions = [...prevExceptions];\n\n  // Recursively call this function in order to walk down a chain of errors\n  if (isInstanceOf(error[key], Error)) {\n    applyExceptionGroupFieldsForParentException(exception, exceptionId);\n    const newException = exceptionFromErrorImplementation(parser, error[key]);\n    const newExceptionId = newExceptions.length;\n    applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId);\n    newExceptions = aggregateExceptionsFromError(\n      exceptionFromErrorImplementation,\n      parser,\n      limit,\n      error[key],\n      key,\n      [newException, ...newExceptions],\n      newException,\n      newExceptionId,\n    );\n  }\n\n  // This will create exception grouping for AggregateErrors\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError\n  if (Array.isArray(error.errors)) {\n    error.errors.forEach((childError, i) => {\n      if (isInstanceOf(childError, Error)) {\n        applyExceptionGroupFieldsForParentException(exception, exceptionId);\n        const newException = exceptionFromErrorImplementation(parser, childError);\n        const newExceptionId = newExceptions.length;\n        applyExceptionGroupFieldsForChildException(newException, `errors[${i}]`, newExceptionId, exceptionId);\n        newExceptions = aggregateExceptionsFromError(\n          exceptionFromErrorImplementation,\n          parser,\n          limit,\n          childError,\n          key,\n          [newException, ...newExceptions],\n          newException,\n          newExceptionId,\n        );\n      }\n    });\n  }\n\n  return newExceptions;\n}\n\nfunction applyExceptionGroupFieldsForParentException(exception: Exception, exceptionId: number): void {\n  // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.\n  exception.mechanism = exception.mechanism || { type: 'generic', handled: true };\n\n  exception.mechanism = {\n    ...exception.mechanism,\n    ...(exception.type === 'AggregateError' && { is_exception_group: true }),\n    exception_id: exceptionId,\n  };\n}\n\nfunction applyExceptionGroupFieldsForChildException(\n  exception: Exception,\n  source: string,\n  exceptionId: number,\n  parentId: number | undefined,\n): void {\n  // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.\n  exception.mechanism = exception.mechanism || { type: 'generic', handled: true };\n\n  exception.mechanism = {\n    ...exception.mechanism,\n    type: 'chained',\n    source,\n    exception_id: exceptionId,\n    parent_id: parentId,\n  };\n}\n\n/**\n * Truncate the message (exception.value) of all exceptions in the event.\n * Because this event processor is ran after `applyClientOptions`,\n * we need to truncate the message of the added exceptions here.\n */\nfunction truncateAggregateExceptions(exceptions: Exception[], maxValueLength: number): Exception[] {\n  return exceptions.map(exception => {\n    if (exception.value) {\n      exception.value = truncate(exception.value, maxValueLength);\n    }\n    return exception;\n  });\n}\n", "import type { Event, StackParser } from './types-hoist';\nimport { GLOBAL_OBJ } from './utils-hoist/worldwide';\n\n/** Keys are source filename/url, values are metadata objects. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst filenameMetadataMap = new Map<string, any>();\n/** Set of stack strings that have already been parsed. */\nconst parsedStacks = new Set<string>();\n\nfunction ensureMetadataStacksAreParsed(parser: StackParser): void {\n  if (!GLOBAL_OBJ._sentryModuleMetadata) {\n    return;\n  }\n\n  for (const stack of Object.keys(GLOBAL_OBJ._sentryModuleMetadata)) {\n    const metadata = GLOBAL_OBJ._sentryModuleMetadata[stack];\n\n    if (parsedStacks.has(stack)) {\n      continue;\n    }\n\n    // Ensure this stack doesn't get parsed again\n    parsedStacks.add(stack);\n\n    const frames = parser(stack);\n\n    // Go through the frames starting from the top of the stack and find the first one with a filename\n    for (const frame of frames.reverse()) {\n      if (frame.filename) {\n        // Save the metadata for this filename\n        filenameMetadataMap.set(frame.filename, metadata);\n        break;\n      }\n    }\n  }\n}\n\n/**\n * Retrieve metadata for a specific JavaScript file URL.\n *\n * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getMetadataForUrl(parser: StackParser, filename: string): any | undefined {\n  ensureMetadataStacksAreParsed(parser);\n  return filenameMetadataMap.get(filename);\n}\n\n/**\n * Adds metadata to stack frames.\n *\n * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option.\n */\nexport function addMetadataToStackFrames(parser: StackParser, event: Event): void {\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    event.exception!.values!.forEach(exception => {\n      if (!exception.stacktrace) {\n        return;\n      }\n\n      for (const frame of exception.stacktrace.frames || []) {\n        if (!frame.filename || frame.module_metadata) {\n          continue;\n        }\n\n        const metadata = getMetadataForUrl(parser, frame.filename);\n\n        if (metadata) {\n          frame.module_metadata = metadata;\n        }\n      }\n    });\n  } catch (_) {\n    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.\n  }\n}\n\n/**\n * Strips metadata from stack frames.\n */\nexport function stripMetadataFromStackFrames(event: Event): void {\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    event.exception!.values!.forEach(exception => {\n      if (!exception.stacktrace) {\n        return;\n      }\n\n      for (const frame of exception.stacktrace.frames || []) {\n        delete frame.module_metadata;\n      }\n    });\n  } catch (_) {\n    // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.\n  }\n}\n", "import { defineIntegration } from '../integration';\nimport type { EventItem } from '../types-hoist';\n\nimport { addMetadataToStackFrames, stripMetadataFromStackFrames } from '../metadata';\nimport { forEachEnvelopeItem } from '../utils-hoist/envelope';\n\n/**\n * Adds module metadata to stack frames.\n *\n * Metadata can be injected by the Sentry bundler plugins using the `moduleMetadata` config option.\n *\n * When this integration is added, the metadata passed to the bundler plugin is added to the stack frames of all events\n * under the `module_metadata` property. This can be used to help in tagging or routing of events from different teams\n * our sources\n */\nexport const moduleMetadataIntegration = defineIntegration(() => {\n  return {\n    name: 'ModuleMetadata',\n    setup(client) {\n      // We need to strip metadata from stack frames before sending them to Sentry since these are client side only.\n      client.on('beforeEnvelope', envelope => {\n        forEachEnvelopeItem(envelope, (item, type) => {\n          if (type === 'event') {\n            const event = Array.isArray(item) ? (item as EventItem)[1] : undefined;\n\n            if (event) {\n              stripMetadataFromStackFrames(event);\n              item[1] = event;\n            }\n          }\n        });\n      });\n\n      client.on('applyFrameMetadata', event => {\n        // Only apply stack frame metadata to error events\n        if (event.type) {\n          return;\n        }\n\n        const stackParser = client.getOptions().stackParser;\n        addMetadataToStackFrames(stackParser, event);\n      });\n    },\n  };\n});\n", "type PartialURL = {\n  host?: string;\n  path?: string;\n  protocol?: string;\n  relative?: string;\n  search?: string;\n  hash?: string;\n};\n\n/**\n * Parses string form of URL into an object\n * // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B\n * // intentionally using regex and not <a/> href parsing trick because React Native and other\n * // environments where DOM might not be available\n * @returns parsed URL object\n */\nexport function parseUrl(url: string): PartialURL {\n  if (!url) {\n    return {};\n  }\n\n  const match = url.match(/^(([^:/?#]+):)?(\\/\\/([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$/);\n\n  if (!match) {\n    return {};\n  }\n\n  // coerce to undefined values to empty string so we don't get 'undefined'\n  const query = match[6] || '';\n  const fragment = match[8] || '';\n  return {\n    host: match[4],\n    path: match[5],\n    protocol: match[2],\n    search: query,\n    hash: fragment,\n    relative: match[5] + query + fragment, // everything minus origin\n  };\n}\n\n/**\n * Strip the query string and fragment off of a given URL or path (if present)\n *\n * @param urlPath Full URL or path, including possible query string and/or fragment\n * @returns URL or path without query string or fragment\n */\nexport function stripUrlQueryAndFragment(urlPath: string): string {\n  return (urlPath.split(/[?#]/, 1) as [string, ...string[]])[0];\n}\n\n/**\n * Returns number of URL segments of a passed string URL.\n *\n * @deprecated This function will be removed in the next major version.\n */\n// TODO(v9): Hoist this function into the places where we use it. (as it stands only react router v6 instrumentation)\nexport function getNumberOfUrlSegments(url: string): number {\n  // split at '/' or at '\\/' to split regex urls correctly\n  return url.split(/\\\\?\\//).filter(s => s.length > 0 && s !== ',').length;\n}\n\n/**\n * Takes a URL object and returns a sanitized string which is safe to use as span name\n * see: https://develop.sentry.dev/sdk/data-handling/#structuring-data\n */\nexport function getSanitizedUrlString(url: PartialURL): string {\n  const { protocol, host, path } = url;\n\n  const filteredHost =\n    (host &&\n      host\n        // Always filter out authority\n        .replace(/^.*@/, '[filtered]:[filtered]@')\n        // Don't show standard :80 (http) and :443 (https) ports to reduce the noise\n        // TODO: Use new URL global if it exists\n        .replace(/(:80)$/, '')\n        .replace(/(:443)$/, '')) ||\n    '';\n\n  return `${protocol ? `${protocol}://` : ''}${filteredHost}${path}`;\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/ban-types */\nimport type { ConsoleLevel, HandlerDataConsole } from '../../types-hoist';\n\nimport { CONSOLE_LEVELS, originalConsoleMethods } from '../logger';\nimport { fill } from '../object';\nimport { GLOBAL_OBJ } from '../worldwide';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers';\n\n/**\n * Add an instrumentation handler for when a console.xxx method is called.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addConsoleInstrumentationHandler(handler: (data: HandlerDataConsole) => void): void {\n  const type = 'console';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentConsole);\n}\n\nfunction instrumentConsole(): void {\n  if (!('console' in GLOBAL_OBJ)) {\n    return;\n  }\n\n  CONSOLE_LEVELS.forEach(function (level: ConsoleLevel): void {\n    if (!(level in GLOBAL_OBJ.console)) {\n      return;\n    }\n\n    fill(GLOBAL_OBJ.console, level, function (originalConsoleMethod: () => any): Function {\n      originalConsoleMethods[level] = originalConsoleMethod;\n\n      return function (...args: any[]): void {\n        const handlerData: HandlerDataConsole = { args, level };\n        triggerHandlers('console', handlerData);\n\n        const log = originalConsoleMethods[level];\n        log && log.apply(GLOBAL_OBJ.console, args);\n      };\n    });\n  });\n}\n", "import type { SeverityLevel } from '../types-hoist';\n\n/**\n * @deprecated This variable has been deprecated and will be removed in the next major version.\n */\nexport const validSeverityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'];\n\n/**\n * Converts a string-based level into a `SeverityLevel`, normalizing it along the way.\n *\n * @param level String representation of desired `SeverityLevel`.\n * @returns The `SeverityLevel` corresponding to the given string, or 'log' if the string isn't a valid level.\n */\nexport function severityLevelFromString(level: SeverityLevel | string): SeverityLevel {\n  return (\n    level === 'warn' ? 'warning' : ['fatal', 'error', 'warning', 'log', 'info', 'debug'].includes(level) ? level : 'log'\n  ) as SeverityLevel;\n}\n", "import { getClient, withScope } from '../currentScopes';\nimport { captureException, captureMessage } from '../exports';\nimport { defineIntegration } from '../integration';\nimport type { CaptureContext, IntegrationFn } from '../types-hoist';\nimport { addConsoleInstrumentationHandler } from '../utils-hoist/instrument/console';\nimport { CONSOLE_LEVELS } from '../utils-hoist/logger';\nimport { addExceptionMechanism } from '../utils-hoist/misc';\nimport { severityLevelFromString } from '../utils-hoist/severity';\nimport { safeJoin } from '../utils-hoist/string';\nimport { GLOBAL_OBJ } from '../utils-hoist/worldwide';\n\ninterface CaptureConsoleOptions {\n  levels?: string[];\n\n  // TODO(v9): Flip default value to `true` and adjust JSDoc!\n  /**\n   * By default, Sentry will mark captured console messages as unhandled.\n   * Set this to `true` if you want to mark them as handled instead.\n   *\n   * Note: in v9 of the SDK, this option will default to `true`, meaning the default behavior will change to mark console messages as handled.\n   * @default false\n   */\n  handled?: boolean;\n}\n\nconst INTEGRATION_NAME = 'CaptureConsole';\n\nconst _captureConsoleIntegration = ((options: CaptureConsoleOptions = {}) => {\n  const levels = options.levels || CONSOLE_LEVELS;\n  // TODO(v9): Flip default value to `true`\n  const handled = !!options.handled;\n\n  return {\n    name: INTEGRATION_NAME,\n    setup(client) {\n      if (!('console' in GLOBAL_OBJ)) {\n        return;\n      }\n\n      addConsoleInstrumentationHandler(({ args, level }) => {\n        if (getClient() !== client || !levels.includes(level)) {\n          return;\n        }\n\n        consoleHandler(args, level, handled);\n      });\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Send Console API calls as Sentry Events.\n */\nexport const captureConsoleIntegration = defineIntegration(_captureConsoleIntegration);\n\nfunction consoleHandler(args: unknown[], level: string, handled: boolean): void {\n  const captureContext: CaptureContext = {\n    level: severityLevelFromString(level),\n    extra: {\n      arguments: args,\n    },\n  };\n\n  withScope(scope => {\n    scope.addEventProcessor(event => {\n      event.logger = 'console';\n\n      addExceptionMechanism(event, {\n        handled,\n        type: 'console',\n      });\n\n      return event;\n    });\n\n    if (level === 'assert') {\n      if (!args[0]) {\n        const message = `Assertion failed: ${safeJoin(args.slice(1), ' ') || 'console.assert'}`;\n        scope.setExtra('arguments', args.slice(1));\n        captureMessage(message, captureContext);\n      }\n      return;\n    }\n\n    const error = args.find(arg => arg instanceof Error);\n    if (error) {\n      captureException(error, captureContext);\n      return;\n    }\n\n    const message = safeJoin(args, ' ');\n    captureMessage(message, captureContext);\n  });\n}\n", "import { defineIntegration } from '../integration';\nimport type { Event, EventHint, IntegrationFn } from '../types-hoist';\nimport { consoleSandbox } from '../utils-hoist/logger';\n\nconst INTEGRATION_NAME = 'Debug';\n\ninterface DebugOptions {\n  /** Controls whether console output created by this integration should be stringified. Default: `false` */\n  stringify?: boolean;\n  /** Controls whether a debugger should be launched before an event is sent. Default: `false` */\n  debugger?: boolean;\n}\n\nconst _debugIntegration = ((options: DebugOptions = {}) => {\n  const _options = {\n    debugger: false,\n    stringify: false,\n    ...options,\n  };\n\n  return {\n    name: INTEGRATION_NAME,\n    setup(client) {\n      client.on('beforeSendEvent', (event: Event, hint?: EventHint) => {\n        if (_options.debugger) {\n          // eslint-disable-next-line no-debugger\n          debugger;\n        }\n\n        /* eslint-disable no-console */\n        consoleSandbox(() => {\n          if (_options.stringify) {\n            console.log(JSON.stringify(event, null, 2));\n            if (hint && Object.keys(hint).length) {\n              console.log(JSON.stringify(hint, null, 2));\n            }\n          } else {\n            console.log(event);\n            if (hint && Object.keys(hint).length) {\n              console.log(hint);\n            }\n          }\n        });\n        /* eslint-enable no-console */\n      });\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Integration to debug sent Sentry events.\n * This integration should not be used in production.\n *\n * @deprecated This integration is deprecated and will be removed in the next major version of the SDK.\n * To log outgoing events, use [Hook Options](https://docs.sentry.io/platforms/javascript/configuration/options/#hooks) (`beforeSend`, `beforeSendTransaction`, ...).\n */\nexport const debugIntegration = defineIntegration(_debugIntegration);\n", "import { defineIntegration } from '../integration';\nimport type { Event, Exception, IntegrationFn, StackFrame } from '../types-hoist';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { logger } from '../utils-hoist/logger';\nimport { getFramesFromEvent } from '../utils-hoist/stacktrace';\n\nconst INTEGRATION_NAME = 'Dedupe';\n\nconst _dedupeIntegration = (() => {\n  let previousEvent: Event | undefined;\n\n  return {\n    name: INTEGRATION_NAME,\n    processEvent(currentEvent) {\n      // We want to ignore any non-error type events, e.g. transactions or replays\n      // These should never be deduped, and also not be compared against as _previousEvent.\n      if (currentEvent.type) {\n        return currentEvent;\n      }\n\n      // Juuust in case something goes wrong\n      try {\n        if (_shouldDropEvent(currentEvent, previousEvent)) {\n          DEBUG_BUILD && logger.warn('Event dropped due to being a duplicate of previously captured event.');\n          return null;\n        }\n      } catch (_oO) {} // eslint-disable-line no-empty\n\n      return (previousEvent = currentEvent);\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Deduplication filter.\n */\nexport const dedupeIntegration = defineIntegration(_dedupeIntegration);\n\n/** only exported for tests. */\nexport function _shouldDropEvent(currentEvent: Event, previousEvent?: Event): boolean {\n  if (!previousEvent) {\n    return false;\n  }\n\n  if (_isSameMessageEvent(currentEvent, previousEvent)) {\n    return true;\n  }\n\n  if (_isSameExceptionEvent(currentEvent, previousEvent)) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction _isSameMessageEvent(currentEvent: Event, previousEvent: Event): boolean {\n  const currentMessage = currentEvent.message;\n  const previousMessage = previousEvent.message;\n\n  // If neither event has a message property, they were both exceptions, so bail out\n  if (!currentMessage && !previousMessage) {\n    return false;\n  }\n\n  // If only one event has a stacktrace, but not the other one, they are not the same\n  if ((currentMessage && !previousMessage) || (!currentMessage && previousMessage)) {\n    return false;\n  }\n\n  if (currentMessage !== previousMessage) {\n    return false;\n  }\n\n  if (!_isSameFingerprint(currentEvent, previousEvent)) {\n    return false;\n  }\n\n  if (!_isSameStacktrace(currentEvent, previousEvent)) {\n    return false;\n  }\n\n  return true;\n}\n\nfunction _isSameExceptionEvent(currentEvent: Event, previousEvent: Event): boolean {\n  const previousException = _getExceptionFromEvent(previousEvent);\n  const currentException = _getExceptionFromEvent(currentEvent);\n\n  if (!previousException || !currentException) {\n    return false;\n  }\n\n  if (previousException.type !== currentException.type || previousException.value !== currentException.value) {\n    return false;\n  }\n\n  if (!_isSameFingerprint(currentEvent, previousEvent)) {\n    return false;\n  }\n\n  if (!_isSameStacktrace(currentEvent, previousEvent)) {\n    return false;\n  }\n\n  return true;\n}\n\nfunction _isSameStacktrace(currentEvent: Event, previousEvent: Event): boolean {\n  let currentFrames = getFramesFromEvent(currentEvent);\n  let previousFrames = getFramesFromEvent(previousEvent);\n\n  // If neither event has a stacktrace, they are assumed to be the same\n  if (!currentFrames && !previousFrames) {\n    return true;\n  }\n\n  // If only one event has a stacktrace, but not the other one, they are not the same\n  if ((currentFrames && !previousFrames) || (!currentFrames && previousFrames)) {\n    return false;\n  }\n\n  currentFrames = currentFrames as StackFrame[];\n  previousFrames = previousFrames as StackFrame[];\n\n  // If number of frames differ, they are not the same\n  if (previousFrames.length !== currentFrames.length) {\n    return false;\n  }\n\n  // Otherwise, compare the two\n  for (let i = 0; i < previousFrames.length; i++) {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const frameA = previousFrames[i]!;\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const frameB = currentFrames[i]!;\n\n    if (\n      frameA.filename !== frameB.filename ||\n      frameA.lineno !== frameB.lineno ||\n      frameA.colno !== frameB.colno ||\n      frameA.function !== frameB.function\n    ) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\nfunction _isSameFingerprint(currentEvent: Event, previousEvent: Event): boolean {\n  let currentFingerprint = currentEvent.fingerprint;\n  let previousFingerprint = previousEvent.fingerprint;\n\n  // If neither event has a fingerprint, they are assumed to be the same\n  if (!currentFingerprint && !previousFingerprint) {\n    return true;\n  }\n\n  // If only one event has a fingerprint, but not the other one, they are not the same\n  if ((currentFingerprint && !previousFingerprint) || (!currentFingerprint && previousFingerprint)) {\n    return false;\n  }\n\n  currentFingerprint = currentFingerprint as string[];\n  previousFingerprint = previousFingerprint as string[];\n\n  // Otherwise, compare the two\n  try {\n    return !!(currentFingerprint.join('') === previousFingerprint.join(''));\n  } catch (_oO) {\n    return false;\n  }\n}\n\nfunction _getExceptionFromEvent(event: Event): Exception | undefined {\n  return event.exception && event.exception.values && event.exception.values[0];\n}\n", "import { defineIntegration } from '../integration';\nimport type { Contexts, Event, EventHint, ExtendedError, IntegrationFn } from '../types-hoist';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { isError, isPlainObject } from '../utils-hoist/is';\nimport { logger } from '../utils-hoist/logger';\nimport { normalize } from '../utils-hoist/normalize';\nimport { addNonEnumerableProperty } from '../utils-hoist/object';\nimport { truncate } from '../utils-hoist/string';\n\nconst INTEGRATION_NAME = 'ExtraErrorData';\n\ninterface ExtraErrorDataOptions {\n  /**\n   * The object depth up to which to capture data on error objects.\n   */\n  depth: number;\n\n  /**\n   * Whether to capture error causes. Defaults to true.\n   *\n   * More information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause\n   */\n  captureErrorCause: boolean;\n}\n\n/**\n * Extract additional data for from original exceptions.\n */\nconst _extraErrorDataIntegration = ((options: Partial<ExtraErrorDataOptions> = {}) => {\n  const { depth = 3, captureErrorCause = true } = options;\n  return {\n    name: INTEGRATION_NAME,\n    processEvent(event, hint, client) {\n      const { maxValueLength = 250 } = client.getOptions();\n      return _enhanceEventWithErrorData(event, hint, depth, captureErrorCause, maxValueLength);\n    },\n  };\n}) satisfies IntegrationFn;\n\nexport const extraErrorDataIntegration = defineIntegration(_extraErrorDataIntegration);\n\nfunction _enhanceEventWithErrorData(\n  event: Event,\n  hint: EventHint = {},\n  depth: number,\n  captureErrorCause: boolean,\n  maxValueLength: number,\n): Event {\n  if (!hint.originalException || !isError(hint.originalException)) {\n    return event;\n  }\n  const exceptionName = (hint.originalException as ExtendedError).name || hint.originalException.constructor.name;\n\n  const errorData = _extractErrorData(hint.originalException as ExtendedError, captureErrorCause, maxValueLength);\n\n  if (errorData) {\n    const contexts: Contexts = {\n      ...event.contexts,\n    };\n\n    const normalizedErrorData = normalize(errorData, depth);\n\n    if (isPlainObject(normalizedErrorData)) {\n      // We mark the error data as \"already normalized\" here, because we don't want other normalization procedures to\n      // potentially truncate the data we just already normalized, with a certain depth setting.\n      addNonEnumerableProperty(normalizedErrorData, '__sentry_skip_normalization__', true);\n      contexts[exceptionName] = normalizedErrorData;\n    }\n\n    return {\n      ...event,\n      contexts,\n    };\n  }\n\n  return event;\n}\n\n/**\n * Extract extra information from the Error object\n */\nfunction _extractErrorData(\n  error: ExtendedError,\n  captureErrorCause: boolean,\n  maxValueLength: number,\n): Record<string, unknown> | null {\n  // We are trying to enhance already existing event, so no harm done if it won't succeed\n  try {\n    const nativeKeys = [\n      'name',\n      'message',\n      'stack',\n      'line',\n      'column',\n      'fileName',\n      'lineNumber',\n      'columnNumber',\n      'toJSON',\n    ];\n\n    const extraErrorInfo: Record<string, unknown> = {};\n\n    // We want only enumerable properties, thus `getOwnPropertyNames` is redundant here, as we filter keys anyway.\n    for (const key of Object.keys(error)) {\n      if (nativeKeys.indexOf(key) !== -1) {\n        continue;\n      }\n      const value = error[key];\n      extraErrorInfo[key] = isError(value) || typeof value === 'string' ? truncate(`${value}`, maxValueLength) : value;\n    }\n\n    // Error.cause is a standard property that is non enumerable, we therefore need to access it separately.\n    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause\n    if (captureErrorCause && error.cause !== undefined) {\n      extraErrorInfo.cause = isError(error.cause) ? error.cause.toString() : error.cause;\n    }\n\n    // Check if someone attached `toJSON` method to grab even more properties (eg. axios is doing that)\n    if (typeof error.toJSON === 'function') {\n      const serializedError = error.toJSON() as Record<string, unknown>;\n\n      for (const key of Object.keys(serializedError)) {\n        const value = serializedError[key];\n        extraErrorInfo[key] = isError(value) ? value.toString() : value;\n      }\n    }\n\n    return extraErrorInfo;\n  } catch (oO) {\n    DEBUG_BUILD && logger.error('Unable to extract extra data from the Error object:', oO);\n  }\n\n  return null;\n}\n", "// Slightly modified (no IE8 support, ES6) and transcribed to TypeScript\n// https://github.com/calvinmetcalf/rollup-plugin-node-builtins/blob/63ab8aacd013767445ca299e468d9a60a95328d7/src/es6/path.js\n//\n// Copyright Joyent, Inc.and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n/** JSDoc */\nfunction normalizeArray(parts: string[], allowAboveRoot?: boolean): string[] {\n  // if the path tries to go above the root, `up` ends up > 0\n  let up = 0;\n  for (let i = parts.length - 1; i >= 0; i--) {\n    const last = parts[i];\n    if (last === '.') {\n      parts.splice(i, 1);\n    } else if (last === '..') {\n      parts.splice(i, 1);\n      up++;\n    } else if (up) {\n      parts.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (allowAboveRoot) {\n    for (; up--; up) {\n      parts.unshift('..');\n    }\n  }\n\n  return parts;\n}\n\n// Split a filename into [root, dir, basename, ext], unix version\n// 'root' is just a slash, or nothing.\nconst splitPathRe = /^(\\S+:\\\\|\\/?)([\\s\\S]*?)((?:\\.{1,2}|[^/\\\\]+?|)(\\.[^./\\\\]*|))(?:[/\\\\]*)$/;\n/** JSDoc */\nfunction splitPath(filename: string): string[] {\n  // Truncate files names greater than 1024 characters to avoid regex dos\n  // https://github.com/getsentry/sentry-javascript/pull/8737#discussion_r1285719172\n  const truncated = filename.length > 1024 ? `<truncated>${filename.slice(-1024)}` : filename;\n  const parts = splitPathRe.exec(truncated);\n  return parts ? parts.slice(1) : [];\n}\n\n// path.resolve([from ...], to)\n// posix version\n/** JSDoc */\nexport function resolve(...args: string[]): string {\n  let resolvedPath = '';\n  let resolvedAbsolute = false;\n\n  for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n    const path = i >= 0 ? args[i] : '/';\n\n    // Skip empty entries\n    if (!path) {\n      continue;\n    }\n\n    resolvedPath = `${path}/${resolvedPath}`;\n    resolvedAbsolute = path.charAt(0) === '/';\n  }\n\n  // At this point the path should be resolved to a full absolute path, but\n  // handle relative paths to be safe (might happen when process.cwd() fails)\n\n  // Normalize the path\n  resolvedPath = normalizeArray(\n    resolvedPath.split('/').filter(p => !!p),\n    !resolvedAbsolute,\n  ).join('/');\n\n  return (resolvedAbsolute ? '/' : '') + resolvedPath || '.';\n}\n\n/** JSDoc */\nfunction trim(arr: string[]): string[] {\n  let start = 0;\n  for (; start < arr.length; start++) {\n    if (arr[start] !== '') {\n      break;\n    }\n  }\n\n  let end = arr.length - 1;\n  for (; end >= 0; end--) {\n    if (arr[end] !== '') {\n      break;\n    }\n  }\n\n  if (start > end) {\n    return [];\n  }\n  return arr.slice(start, end - start + 1);\n}\n\n// path.relative(from, to)\n// posix version\n/** JSDoc */\nexport function relative(from: string, to: string): string {\n  /* eslint-disable no-param-reassign */\n  from = resolve(from).slice(1);\n  to = resolve(to).slice(1);\n  /* eslint-enable no-param-reassign */\n\n  const fromParts = trim(from.split('/'));\n  const toParts = trim(to.split('/'));\n\n  const length = Math.min(fromParts.length, toParts.length);\n  let samePartsLength = length;\n  for (let i = 0; i < length; i++) {\n    if (fromParts[i] !== toParts[i]) {\n      samePartsLength = i;\n      break;\n    }\n  }\n\n  let outputParts = [];\n  for (let i = samePartsLength; i < fromParts.length; i++) {\n    outputParts.push('..');\n  }\n\n  outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n  return outputParts.join('/');\n}\n\n// path.normalize(path)\n// posix version\n/** JSDoc */\nexport function normalizePath(path: string): string {\n  const isPathAbsolute = isAbsolute(path);\n  const trailingSlash = path.slice(-1) === '/';\n\n  // Normalize the path\n  let normalizedPath = normalizeArray(\n    path.split('/').filter(p => !!p),\n    !isPathAbsolute,\n  ).join('/');\n\n  if (!normalizedPath && !isPathAbsolute) {\n    normalizedPath = '.';\n  }\n  if (normalizedPath && trailingSlash) {\n    normalizedPath += '/';\n  }\n\n  return (isPathAbsolute ? '/' : '') + normalizedPath;\n}\n\n// posix version\n/** JSDoc */\nexport function isAbsolute(path: string): boolean {\n  return path.charAt(0) === '/';\n}\n\n// posix version\n/** JSDoc */\nexport function join(...args: string[]): string {\n  return normalizePath(args.join('/'));\n}\n\n/** JSDoc */\nexport function dirname(path: string): string {\n  const result = splitPath(path);\n  const root = result[0] || '';\n  let dir = result[1];\n\n  if (!root && !dir) {\n    // No dirname whatsoever\n    return '.';\n  }\n\n  if (dir) {\n    // It has a dirname, strip trailing slash\n    dir = dir.slice(0, dir.length - 1);\n  }\n\n  return root + dir;\n}\n\n/** JSDoc */\nexport function basename(path: string, ext?: string): string {\n  let f = splitPath(path)[2] || '';\n  if (ext && f.slice(ext.length * -1) === ext) {\n    f = f.slice(0, f.length - ext.length);\n  }\n  return f;\n}\n", "import { defineIntegration } from '../integration';\nimport type { Event, StackFrame, Stacktrace } from '../types-hoist';\nimport { basename, relative } from '../utils-hoist/path';\nimport { GLOBAL_OBJ } from '../utils-hoist/worldwide';\n\ntype StackFrameIteratee = (frame: StackFrame) => StackFrame;\n\nconst INTEGRATION_NAME = 'RewriteFrames';\n\ninterface RewriteFramesOptions {\n  /**\n   * Root path (the beginning of the path) that will be stripped from the frames' filename.\n   *\n   * This option has slightly different behaviour in the browser and on servers:\n   * - In the browser, the value you provide in `root` will be stripped from the beginning stack frames' paths (if the path started with the value).\n   * - On the server, the root value will only replace the beginning of stack frame filepaths, when the path is absolute. If no `root` value is provided and the path is absolute, the frame will be reduced to only the filename and the provided `prefix` option.\n   *\n   * Browser example:\n   * - Original frame: `'http://example.com/my/path/static/asset.js'`\n   * - `root: 'http://example.com/my/path'`\n   * - `assetPrefix: 'app://'`\n   * - Resulting frame: `'app:///static/asset.js'`\n   *\n   * Server example:\n   * - Original frame: `'/User/local/my/path/static/asset.js'`\n   * - `root: '/User/local/my/path'`\n   * - `assetPrefix: 'app://'`\n   * - Resulting frame: `'app:///static/asset.js'`\n   */\n  root?: string;\n\n  /**\n   * A custom prefix that stack frames will be prepended with.\n   *\n   * Default: `'app://'`\n   *\n   * This option has slightly different behaviour in the browser and on servers:\n   * - In the browser, the value you provide in `prefix` will prefix the resulting filename when the value you provided in `root` was applied. Effectively replacing whatever `root` matched in the beginning of the frame with `prefix`.\n   * - On the server, the prefix is applied to all stackframes with absolute paths. On Windows, the drive identifier (e.g. \"C://\") is replaced with the prefix.\n   */\n  prefix?: string;\n\n  /**\n   * Defines an iterator that is used to iterate through all of the stack frames for modification before being sent to Sentry.\n   * Setting this option will effectively disable both the `root` and the `prefix` options.\n   */\n  iteratee?: StackFrameIteratee;\n}\n\n/**\n * Rewrite event frames paths.\n */\nexport const rewriteFramesIntegration = defineIntegration((options: RewriteFramesOptions = {}) => {\n  const root = options.root;\n  const prefix = options.prefix || 'app:///';\n\n  const isBrowser = 'window' in GLOBAL_OBJ && GLOBAL_OBJ.window !== undefined;\n\n  const iteratee: StackFrameIteratee = options.iteratee || generateIteratee({ isBrowser, root, prefix });\n\n  /** Process an exception event. */\n  function _processExceptionsEvent(event: Event): Event {\n    try {\n      return {\n        ...event,\n        exception: {\n          ...event.exception,\n          // The check for this is performed inside `process` call itself, safe to skip here\n          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n          values: event.exception!.values!.map(value => ({\n            ...value,\n            ...(value.stacktrace && { stacktrace: _processStacktrace(value.stacktrace) }),\n          })),\n        },\n      };\n    } catch (_oO) {\n      return event;\n    }\n  }\n\n  /** Process a stack trace. */\n  function _processStacktrace(stacktrace?: Stacktrace): Stacktrace {\n    return {\n      ...stacktrace,\n      frames: stacktrace && stacktrace.frames && stacktrace.frames.map(f => iteratee(f)),\n    };\n  }\n\n  return {\n    name: INTEGRATION_NAME,\n    processEvent(originalEvent) {\n      let processedEvent = originalEvent;\n\n      if (originalEvent.exception && Array.isArray(originalEvent.exception.values)) {\n        processedEvent = _processExceptionsEvent(processedEvent);\n      }\n\n      return processedEvent;\n    },\n  };\n});\n\n/**\n * Exported only for tests.\n */\nexport function generateIteratee({\n  isBrowser,\n  root,\n  prefix,\n}: {\n  isBrowser: boolean;\n  root?: string;\n  prefix: string;\n}): StackFrameIteratee {\n  return (frame: StackFrame) => {\n    if (!frame.filename) {\n      return frame;\n    }\n\n    // Determine if this is a Windows frame by checking for a Windows-style prefix such as `C:\\`\n    const isWindowsFrame =\n      /^[a-zA-Z]:\\\\/.test(frame.filename) ||\n      // or the presence of a backslash without a forward slash (which are not allowed on Windows)\n      (frame.filename.includes('\\\\') && !frame.filename.includes('/'));\n\n    // Check if the frame filename begins with `/`\n    const startsWithSlash = /^\\//.test(frame.filename);\n\n    if (isBrowser) {\n      if (root) {\n        const oldFilename = frame.filename;\n        if (oldFilename.indexOf(root) === 0) {\n          frame.filename = oldFilename.replace(root, prefix);\n        }\n      }\n    } else {\n      if (isWindowsFrame || startsWithSlash) {\n        const filename = isWindowsFrame\n          ? frame.filename\n              .replace(/^[a-zA-Z]:/, '') // remove Windows-style prefix\n              .replace(/\\\\/g, '/') // replace all `\\\\` instances with `/`\n          : frame.filename;\n        const base = root ? relative(root, filename) : basename(filename);\n        frame.filename = `${prefix}${base}`;\n      }\n    }\n\n    return frame;\n  };\n}\n", "import { defineIntegration } from '../integration';\nimport type { IntegrationFn } from '../types-hoist';\nimport { timestampInSeconds } from '../utils-hoist/time';\n\nconst INTEGRATION_NAME = 'SessionTiming';\n\nconst _sessionTimingIntegration = (() => {\n  const startTime = timestampInSeconds() * 1000;\n\n  return {\n    name: INTEGRATION_NAME,\n    processEvent(event) {\n      const now = timestampInSeconds() * 1000;\n\n      return {\n        ...event,\n        extra: {\n          ...event.extra,\n          ['session:start']: startTime,\n          ['session:duration']: now - startTime,\n          ['session:end']: now,\n        },\n      };\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * This function adds duration since the sessionTimingIntegration was initialized\n * till the time event was sent.\n *\n * @deprecated This integration is deprecated and will be removed in the next major version of the SDK.\n * To capture session durations alongside events, use [Context](https://docs.sentry.io/platforms/javascript/enriching-events/context/) (`Sentry.setContext()`).\n */\nexport const sessionTimingIntegration = defineIntegration(_sessionTimingIntegration);\n", "import { defineIntegration } from '../integration';\nimport type { Event, EventHint, IntegrationFn } from '../types-hoist';\nimport { isError } from '../utils-hoist/is';\nimport { truncate } from '../utils-hoist/string';\n\ninterface ZodErrorsOptions {\n  key?: string;\n  /**\n   * Limits the number of Zod errors inlined in each Sentry event.\n   *\n   * @default 10\n   */\n  limit?: number;\n  /**\n   * Save full list of Zod issues as an attachment in Sentry\n   *\n   * @default false\n   */\n  saveZodIssuesAsAttachment?: boolean;\n}\n\nconst DEFAULT_LIMIT = 10;\nconst INTEGRATION_NAME = 'ZodErrors';\n\n/**\n * Simplified ZodIssue type definition\n */\ninterface ZodIssue {\n  path: (string | number)[];\n  message?: string;\n  expected?: unknown;\n  received?: unknown;\n  unionErrors?: unknown[];\n  keys?: unknown[];\n  invalid_literal?: unknown;\n}\n\ninterface ZodError extends Error {\n  issues: ZodIssue[];\n}\n\nfunction originalExceptionIsZodError(originalException: unknown): originalException is ZodError {\n  return (\n    isError(originalException) &&\n    originalException.name === 'ZodError' &&\n    Array.isArray((originalException as ZodError).issues)\n  );\n}\n\ntype SingleLevelZodIssue<T extends ZodIssue> = {\n  [P in keyof T]: T[P] extends string | number | undefined\n    ? T[P]\n    : T[P] extends unknown[]\n      ? string | undefined\n      : unknown;\n};\n\n/**\n * Formats child objects or arrays to a string\n * that is preserved when sent to Sentry.\n *\n * Without this, we end up with something like this in Sentry:\n *\n * [\n *  [Object],\n *  [Object],\n *  [Object],\n *  [Object]\n * ]\n */\nexport function flattenIssue(issue: ZodIssue): SingleLevelZodIssue<ZodIssue> {\n  return {\n    ...issue,\n    path: 'path' in issue && Array.isArray(issue.path) ? issue.path.join('.') : undefined,\n    keys: 'keys' in issue ? JSON.stringify(issue.keys) : undefined,\n    unionErrors: 'unionErrors' in issue ? JSON.stringify(issue.unionErrors) : undefined,\n  };\n}\n\n/**\n * Takes ZodError issue path array and returns a flattened version as a string.\n * This makes it easier to display paths within a Sentry error message.\n *\n * Array indexes are normalized to reduce duplicate entries\n *\n * @param path ZodError issue path\n * @returns flattened path\n *\n * @example\n * flattenIssuePath([0, 'foo', 1, 'bar']) // -> '<array>.foo.<array>.bar'\n */\nexport function flattenIssuePath(path: Array<string | number>): string {\n  return path\n    .map(p => {\n      if (typeof p === 'number') {\n        return '<array>';\n      } else {\n        return p;\n      }\n    })\n    .join('.');\n}\n\n/**\n * Zod error message is a stringified version of ZodError.issues\n * This doesn't display well in the Sentry UI. Replace it with something shorter.\n */\nexport function formatIssueMessage(zodError: ZodError): string {\n  const errorKeyMap = new Set<string | number | symbol>();\n  for (const iss of zodError.issues) {\n    const issuePath = flattenIssuePath(iss.path);\n    if (issuePath.length > 0) {\n      errorKeyMap.add(issuePath);\n    }\n  }\n\n  const errorKeys = Array.from(errorKeyMap);\n  if (errorKeys.length === 0) {\n    // If there are no keys, then we're likely validating the root\n    // variable rather than a key within an object. This attempts\n    // to extract what type it was that failed to validate.\n    // For example, z.string().parse(123) would return \"string\" here.\n    let rootExpectedType = 'variable';\n    if (zodError.issues.length > 0) {\n      const iss = zodError.issues[0];\n      if (iss !== undefined && 'expected' in iss && typeof iss.expected === 'string') {\n        rootExpectedType = iss.expected;\n      }\n    }\n    return `Failed to validate ${rootExpectedType}`;\n  }\n  return `Failed to validate keys: ${truncate(errorKeys.join(', '), 100)}`;\n}\n\n/**\n * Applies ZodError issues to an event extra and replaces the error message\n */\nexport function applyZodErrorsToEvent(\n  limit: number,\n  saveZodIssuesAsAttachment: boolean = false,\n  event: Event,\n  hint: EventHint,\n): Event {\n  if (\n    !event.exception ||\n    !event.exception.values ||\n    !hint ||\n    !hint.originalException ||\n    !originalExceptionIsZodError(hint.originalException) ||\n    hint.originalException.issues.length === 0\n  ) {\n    return event;\n  }\n\n  try {\n    const issuesToFlatten = saveZodIssuesAsAttachment\n      ? hint.originalException.issues\n      : hint.originalException.issues.slice(0, limit);\n    const flattenedIssues = issuesToFlatten.map(flattenIssue);\n\n    if (saveZodIssuesAsAttachment) {\n      // Sometimes having the full error details can be helpful.\n      // Attachments have much higher limits, so we can include the full list of issues.\n      if (!Array.isArray(hint.attachments)) {\n        hint.attachments = [];\n      }\n      hint.attachments.push({\n        filename: 'zod_issues.json',\n        data: JSON.stringify({\n          issues: flattenedIssues,\n        }),\n      });\n    }\n\n    return {\n      ...event,\n      exception: {\n        ...event.exception,\n        values: [\n          {\n            ...event.exception.values[0],\n            value: formatIssueMessage(hint.originalException),\n          },\n          ...event.exception.values.slice(1),\n        ],\n      },\n      extra: {\n        ...event.extra,\n        'zoderror.issues': flattenedIssues.slice(0, limit),\n      },\n    };\n  } catch (e) {\n    // Hopefully we never throw errors here, but record it\n    // with the event just in case.\n    return {\n      ...event,\n      extra: {\n        ...event.extra,\n        'zoderrors sentry integration parse error': {\n          message: 'an exception was thrown while processing ZodError within applyZodErrorsToEvent()',\n          error: e instanceof Error ? `${e.name}: ${e.message}\\n${e.stack}` : 'unknown',\n        },\n      },\n    };\n  }\n}\n\nconst _zodErrorsIntegration = ((options: ZodErrorsOptions = {}) => {\n  const limit = typeof options.limit === 'undefined' ? DEFAULT_LIMIT : options.limit;\n\n  return {\n    name: INTEGRATION_NAME,\n    processEvent(originalEvent, hint): Event {\n      const processedEvent = applyZodErrorsToEvent(limit, options.saveZodIssuesAsAttachment, originalEvent, hint);\n      return processedEvent;\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Sentry integration to process Zod errors, making them easier to work with in Sentry.\n */\nexport const zodErrorsIntegration = defineIntegration(_zodErrorsIntegration);\n", "import { defineIntegration } from '../integration';\nimport { addMetadataToStackFrames, stripMetadataFromStackFrames } from '../metadata';\nimport type { Event, EventItem } from '../types-hoist';\nimport { forEachEnvelopeItem } from '../utils-hoist/envelope';\nimport { getFramesFromEvent } from '../utils-hoist/stacktrace';\n\ninterface Options {\n  /**\n   * Keys that have been provided in the Sentry bundler plugin via the the `applicationKey` option, identifying your bundles.\n   *\n   * - Webpack plugin: https://www.npmjs.com/package/@sentry/webpack-plugin#applicationkey\n   * - Vite plugin: https://www.npmjs.com/package/@sentry/vite-plugin#applicationkey\n   * - Esbuild plugin: https://www.npmjs.com/package/@sentry/esbuild-plugin#applicationkey\n   * - Rollup plugin: https://www.npmjs.com/package/@sentry/rollup-plugin#applicationkey\n   */\n  filterKeys: string[];\n\n  /**\n   * Defines how the integration should behave. \"Third-Party Stack Frames\" are stack frames that did not come from files marked with a matching bundle key.\n   *\n   * You can define the behaviour with one of 4 modes:\n   * - `drop-error-if-contains-third-party-frames`: Drop error events that contain at least one third-party stack frame.\n   * - `drop-error-if-exclusively-contains-third-party-frames`: Drop error events that exclusively contain third-party stack frames.\n   * - `apply-tag-if-contains-third-party-frames`: Keep all error events, but apply a `third_party_code: true` tag in case the error contains at least one third-party stack frame.\n   * - `apply-tag-if-exclusively-contains-third-party-frames`: Keep all error events, but apply a `third_party_code: true` tag in case the error contains exclusively third-party stack frames.\n   *\n   * If you chose the mode to only apply tags, the tags can then be used in Sentry to filter your issue stream by entering `!third_party_code:True` in the search bar.\n   */\n  behaviour:\n    | 'drop-error-if-contains-third-party-frames'\n    | 'drop-error-if-exclusively-contains-third-party-frames'\n    | 'apply-tag-if-contains-third-party-frames'\n    | 'apply-tag-if-exclusively-contains-third-party-frames';\n}\n\n/**\n * This integration allows you to filter out, or tag error events that do not come from user code marked with a bundle key via the Sentry bundler plugins.\n */\nexport const thirdPartyErrorFilterIntegration = defineIntegration((options: Options) => {\n  return {\n    name: 'ThirdPartyErrorsFilter',\n    setup(client) {\n      // We need to strip metadata from stack frames before sending them to Sentry since these are client side only.\n      // TODO(lforst): Move this cleanup logic into a more central place in the SDK.\n      client.on('beforeEnvelope', envelope => {\n        forEachEnvelopeItem(envelope, (item, type) => {\n          if (type === 'event') {\n            const event = Array.isArray(item) ? (item as EventItem)[1] : undefined;\n\n            if (event) {\n              stripMetadataFromStackFrames(event);\n              item[1] = event;\n            }\n          }\n        });\n      });\n\n      client.on('applyFrameMetadata', event => {\n        // Only apply stack frame metadata to error events\n        if (event.type) {\n          return;\n        }\n\n        const stackParser = client.getOptions().stackParser;\n        addMetadataToStackFrames(stackParser, event);\n      });\n    },\n\n    processEvent(event) {\n      const frameKeys = getBundleKeysForAllFramesWithFilenames(event);\n\n      if (frameKeys) {\n        const arrayMethod =\n          options.behaviour === 'drop-error-if-contains-third-party-frames' ||\n          options.behaviour === 'apply-tag-if-contains-third-party-frames'\n            ? 'some'\n            : 'every';\n\n        const behaviourApplies = frameKeys[arrayMethod](keys => !keys.some(key => options.filterKeys.includes(key)));\n\n        if (behaviourApplies) {\n          const shouldDrop =\n            options.behaviour === 'drop-error-if-contains-third-party-frames' ||\n            options.behaviour === 'drop-error-if-exclusively-contains-third-party-frames';\n          if (shouldDrop) {\n            return null;\n          } else {\n            event.tags = {\n              ...event.tags,\n              third_party_code: true,\n            };\n          }\n        }\n      }\n\n      return event;\n    },\n  };\n});\n\nfunction getBundleKeysForAllFramesWithFilenames(event: Event): string[][] | undefined {\n  const frames = getFramesFromEvent(event);\n\n  if (!frames) {\n    return undefined;\n  }\n\n  return (\n    frames\n      // Exclude frames without a filename since these are likely native code or built-ins\n      .filter(frame => !!frame.filename)\n      .map(frame => {\n        if (frame.module_metadata) {\n          return Object.keys(frame.module_metadata)\n            .filter(key => key.startsWith(BUNDLER_PLUGIN_APP_KEY_PREFIX))\n            .map(key => key.slice(BUNDLER_PLUGIN_APP_KEY_PREFIX.length));\n        }\n        return [];\n      })\n  );\n}\n\nconst BUNDLER_PLUGIN_APP_KEY_PREFIX = '_sentryBundlerPluginAppKey:';\n", "export const COUNTER_METRIC_TYPE = 'c' as const;\nexport const GAUGE_METRIC_TYPE = 'g' as const;\nexport const SET_METRIC_TYPE = 's' as const;\nexport const DISTRIBUTION_METRIC_TYPE = 'd' as const;\n\n/**\n * This does not match spec in https://develop.sentry.dev/sdk/metrics\n * but was chosen to optimize for the most common case in browser environments.\n */\nexport const DEFAULT_BROWSER_FLUSH_INTERVAL = 5000;\n\n/**\n * SDKs are required to bucket into 10 second intervals (rollup in seconds)\n * which is the current lower bound of metric accuracy.\n */\nexport const DEFAULT_FLUSH_INTERVAL = 10000;\n\n/**\n * The maximum number of metrics that should be stored in memory.\n */\nexport const MAX_WEIGHT = 10000;\n", "import { getClient } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { startSpanManual } from '../tracing';\nimport type { Client, DurationUnit, MetricData, MetricsAggregator as MetricsAggregatorInterface } from '../types-hoist';\nimport { logger } from '../utils-hoist/logger';\nimport { timestampInSeconds } from '../utils-hoist/time';\nimport { getGlobalSingleton } from '../utils-hoist/worldwide';\nimport { handleCallbackErrors } from '../utils/handleCallbackErrors';\nimport { getActiveSpan, getRootSpan, spanToJSON } from '../utils/spanUtils';\nimport { COUNTER_METRIC_TYPE, DISTRIBUTION_METRIC_TYPE, GAUGE_METRIC_TYPE, SET_METRIC_TYPE } from './constants';\nimport type { MetricType } from './types';\n\ntype MetricsAggregatorConstructor = {\n  new (client: Client): MetricsAggregatorInterface;\n};\n\n/**\n * Gets the metrics aggregator for a given client.\n * @param client The client for which to get the metrics aggregator.\n * @param Aggregator Optional metrics aggregator class to use to create an aggregator if one does not exist.\n */\nfunction getMetricsAggregatorForClient(\n  client: Client,\n  Aggregator: MetricsAggregatorConstructor,\n): MetricsAggregatorInterface {\n  const globalMetricsAggregators = getGlobalSingleton<WeakMap<Client, MetricsAggregatorInterface>>(\n    'globalMetricsAggregators',\n    () => new WeakMap(),\n  );\n\n  const aggregator = globalMetricsAggregators.get(client);\n  if (aggregator) {\n    return aggregator;\n  }\n\n  const newAggregator = new Aggregator(client);\n  client.on('flush', () => newAggregator.flush());\n  client.on('close', () => newAggregator.close());\n  globalMetricsAggregators.set(client, newAggregator);\n\n  return newAggregator;\n}\n\nfunction addToMetricsAggregator(\n  Aggregator: MetricsAggregatorConstructor,\n  metricType: MetricType,\n  name: string,\n  value: number | string,\n  data: MetricData | undefined = {},\n): void {\n  const client = data.client || getClient<Client>();\n\n  if (!client) {\n    return;\n  }\n\n  const span = getActiveSpan();\n  const rootSpan = span ? getRootSpan(span) : undefined;\n  const transactionName = rootSpan && spanToJSON(rootSpan).description;\n\n  const { unit, tags, timestamp } = data;\n  const { release, environment } = client.getOptions();\n  const metricTags: Record<string, string> = {};\n  if (release) {\n    metricTags.release = release;\n  }\n  if (environment) {\n    metricTags.environment = environment;\n  }\n  if (transactionName) {\n    metricTags.transaction = transactionName;\n  }\n\n  DEBUG_BUILD && logger.log(`Adding value of ${value} to ${metricType} metric ${name}`);\n\n  const aggregator = getMetricsAggregatorForClient(client, Aggregator);\n  aggregator.add(metricType, name, value, unit, { ...metricTags, ...tags }, timestamp);\n}\n\n/**\n * Adds a value to a counter metric\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction increment(aggregator: MetricsAggregatorConstructor, name: string, value: number = 1, data?: MetricData): void {\n  addToMetricsAggregator(aggregator, COUNTER_METRIC_TYPE, name, ensureNumber(value), data);\n}\n\n/**\n * Adds a value to a distribution metric\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction distribution(aggregator: MetricsAggregatorConstructor, name: string, value: number, data?: MetricData): void {\n  addToMetricsAggregator(aggregator, DISTRIBUTION_METRIC_TYPE, name, ensureNumber(value), data);\n}\n\n/**\n * Adds a timing metric.\n * The metric is added as a distribution metric.\n *\n * You can either directly capture a numeric `value`, or wrap a callback function in `timing`.\n * In the latter case, the duration of the callback execution will be captured as a span & a metric.\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction timing<T = void>(\n  aggregator: MetricsAggregatorConstructor,\n  name: string,\n  value: number | (() => T),\n  unit: DurationUnit = 'second',\n  data?: Omit<MetricData, 'unit'>,\n): T | void {\n  // callback form\n  if (typeof value === 'function') {\n    const startTime = timestampInSeconds();\n\n    return startSpanManual(\n      {\n        op: 'metrics.timing',\n        name,\n        startTime,\n        onlyIfParent: true,\n      },\n      span => {\n        return handleCallbackErrors(\n          () => value(),\n          () => {\n            // no special error handling necessary\n          },\n          () => {\n            const endTime = timestampInSeconds();\n            const timeDiff = endTime - startTime;\n            // eslint-disable-next-line deprecation/deprecation\n            distribution(aggregator, name, timeDiff, { ...data, unit: 'second' });\n            span.end(endTime);\n          },\n        );\n      },\n    );\n  }\n\n  // value form\n  // eslint-disable-next-line deprecation/deprecation\n  distribution(aggregator, name, value, { ...data, unit });\n}\n\n/**\n * Adds a value to a set metric. Value must be a string or integer.\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction set(aggregator: MetricsAggregatorConstructor, name: string, value: number | string, data?: MetricData): void {\n  addToMetricsAggregator(aggregator, SET_METRIC_TYPE, name, value, data);\n}\n\n/**\n * Adds a value to a gauge metric\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction gauge(aggregator: MetricsAggregatorConstructor, name: string, value: number, data?: MetricData): void {\n  addToMetricsAggregator(aggregator, GAUGE_METRIC_TYPE, name, ensureNumber(value), data);\n}\n\n/**\n * The metrics API is used to capture custom metrics in Sentry.\n *\n * @deprecated The Sentry metrics beta has ended. This export will be removed in a future release.\n */\nexport const metrics = {\n  increment,\n  distribution,\n  set,\n  gauge,\n  timing,\n  /**\n   * @ignore This is for internal use only.\n   */\n  getMetricsAggregatorForClient,\n};\n\n// Although this is typed to be a number, we try to handle strings as well here\nfunction ensureNumber(number: number | string): number {\n  return typeof number === 'string' ? parseInt(number) : number;\n}\n", "import type { MeasurementUnit, MetricBucketItem, Primitive } from '../types-hoist';\nimport { dropUndefinedKeys } from '../utils-hoist/object';\nimport type { MetricType } from './types';\n\n/**\n * Generate bucket key from metric properties.\n */\nexport function getBucketKey(\n  metricType: MetricType,\n  name: string,\n  unit: MeasurementUnit,\n  tags: Record<string, string>,\n): string {\n  const stringifiedTags = Object.entries(dropUndefinedKeys(tags)).sort((a, b) => a[0].localeCompare(b[0]));\n  return `${metricType}${name}${unit}${stringifiedTags}`;\n}\n\n/* eslint-disable no-bitwise */\n/**\n * Simple hash function for strings.\n */\nexport function simpleHash(s: string): number {\n  let rv = 0;\n  for (let i = 0; i < s.length; i++) {\n    const c = s.charCodeAt(i);\n    rv = (rv << 5) - rv + c;\n    rv &= rv;\n  }\n  return rv >>> 0;\n}\n/* eslint-enable no-bitwise */\n\n/**\n * Serialize metrics buckets into a string based on statsd format.\n *\n * Example of format:\n * metric.name@second:1:1.2|d|#a:value,b:anothervalue|T12345677\n * Segments:\n * name: metric.name\n * unit: second\n * value: [1, 1.2]\n * type of metric: d (distribution)\n * tags: { a: value, b: anothervalue }\n * timestamp: 12345677\n */\nexport function serializeMetricBuckets(metricBucketItems: MetricBucketItem[]): string {\n  let out = '';\n  for (const item of metricBucketItems) {\n    const tagEntries = Object.entries(item.tags);\n    const maybeTags = tagEntries.length > 0 ? `|#${tagEntries.map(([key, value]) => `${key}:${value}`).join(',')}` : '';\n    out += `${item.name}@${item.unit}:${item.metric}|${item.metricType}${maybeTags}|T${item.timestamp}\\n`;\n  }\n  return out;\n}\n\n/**\n * Sanitizes units\n *\n * These Regex's are straight from the normalisation docs:\n * https://develop.sentry.dev/sdk/metrics/#normalization\n */\nexport function sanitizeUnit(unit: string): string {\n  return unit.replace(/[^\\w]+/gi, '_');\n}\n\n/**\n * Sanitizes metric keys\n *\n * These Regex's are straight from the normalisation docs:\n * https://develop.sentry.dev/sdk/metrics/#normalization\n */\nexport function sanitizeMetricKey(key: string): string {\n  return key.replace(/[^\\w\\-.]+/gi, '_');\n}\n\n/**\n * Sanitizes metric keys\n *\n * These Regex's are straight from the normalisation docs:\n * https://develop.sentry.dev/sdk/metrics/#normalization\n */\nfunction sanitizeTagKey(key: string): string {\n  return key.replace(/[^\\w\\-./]+/gi, '');\n}\n\n/**\n * These Regex's are straight from the normalisation docs:\n * https://develop.sentry.dev/sdk/metrics/#normalization\n */\nconst tagValueReplacements: [string, string][] = [\n  ['\\n', '\\\\n'],\n  ['\\r', '\\\\r'],\n  ['\\t', '\\\\t'],\n  ['\\\\', '\\\\\\\\'],\n  ['|', '\\\\u{7c}'],\n  [',', '\\\\u{2c}'],\n];\n\nfunction getCharOrReplacement(input: string): string {\n  for (const [search, replacement] of tagValueReplacements) {\n    if (input === search) {\n      return replacement;\n    }\n  }\n\n  return input;\n}\n\nfunction sanitizeTagValue(value: string): string {\n  return [...value].reduce((acc, char) => acc + getCharOrReplacement(char), '');\n}\n\n/**\n * Sanitizes tags.\n */\nexport function sanitizeTags(unsanitizedTags: Record<string, Primitive>): Record<string, string> {\n  const tags: Record<string, string> = {};\n  for (const key in unsanitizedTags) {\n    if (Object.prototype.hasOwnProperty.call(unsanitizedTags, key)) {\n      const sanitizedKey = sanitizeTagKey(key);\n      tags[sanitizedKey] = sanitizeTagValue(String(unsanitizedTags[key]));\n    }\n  }\n  return tags;\n}\n", "import type { Client, DsnComponents, MetricBucketItem, SdkMetadata, StatsdEnvelope, StatsdItem } from '../types-hoist';\nimport { dsnToString } from '../utils-hoist/dsn';\nimport { createEnvelope } from '../utils-hoist/envelope';\nimport { logger } from '../utils-hoist/logger';\nimport { serializeMetricBuckets } from './utils';\n\n/**\n * Captures aggregated metrics to the supplied client.\n */\nexport function captureAggregateMetrics(client: Client, metricBucketItems: Array<MetricBucketItem>): void {\n  logger.log(`Flushing aggregated metrics, number of metrics: ${metricBucketItems.length}`);\n  const dsn = client.getDsn();\n  const metadata = client.getSdkMetadata();\n  const tunnel = client.getOptions().tunnel;\n\n  const metricsEnvelope = createMetricEnvelope(metricBucketItems, dsn, metadata, tunnel);\n\n  // sendEnvelope should not throw\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  client.sendEnvelope(metricsEnvelope);\n}\n\n/**\n * Create envelope from a metric aggregate.\n */\nexport function createMetricEnvelope(\n  metricBucketItems: Array<MetricBucketItem>,\n  dsn?: DsnComponents,\n  metadata?: SdkMetadata,\n  tunnel?: string,\n): StatsdEnvelope {\n  const headers: StatsdEnvelope[0] = {\n    sent_at: new Date().toISOString(),\n  };\n\n  if (metadata && metadata.sdk) {\n    headers.sdk = {\n      name: metadata.sdk.name,\n      version: metadata.sdk.version,\n    };\n  }\n\n  if (!!tunnel && dsn) {\n    headers.dsn = dsnToString(dsn);\n  }\n\n  const item = createMetricEnvelopeItem(metricBucketItems);\n  return createEnvelope<StatsdEnvelope>(headers, [item]);\n}\n\nfunction createMetricEnvelopeItem(metricBucketItems: MetricBucketItem[]): StatsdItem {\n  const payload = serializeMetricBuckets(metricBucketItems);\n  const metricHeaders: StatsdItem[0] = {\n    type: 'statsd',\n    length: payload.length,\n  };\n  return [metricHeaders, payload];\n}\n", "import type { MetricInstance } from '../types-hoist';\nimport { COUNTER_METRIC_TYPE, DISTRIBUTION_METRIC_TYPE, GAUGE_METRIC_TYPE, SET_METRIC_TYPE } from './constants';\nimport { simpleHash } from './utils';\n\n/**\n * A metric instance representing a counter.\n */\nexport class CounterMetric implements MetricInstance {\n  public constructor(private _value: number) {}\n\n  /** @inheritDoc */\n  public get weight(): number {\n    return 1;\n  }\n\n  /** @inheritdoc */\n  public add(value: number): void {\n    this._value += value;\n  }\n\n  /** @inheritdoc */\n  public toString(): string {\n    return `${this._value}`;\n  }\n}\n\n/**\n * A metric instance representing a gauge.\n */\nexport class GaugeMetric implements MetricInstance {\n  private _last: number;\n  private _min: number;\n  private _max: number;\n  private _sum: number;\n  private _count: number;\n\n  public constructor(value: number) {\n    this._last = value;\n    this._min = value;\n    this._max = value;\n    this._sum = value;\n    this._count = 1;\n  }\n\n  /** @inheritDoc */\n  public get weight(): number {\n    return 5;\n  }\n\n  /** @inheritdoc */\n  public add(value: number): void {\n    this._last = value;\n    if (value < this._min) {\n      this._min = value;\n    }\n    if (value > this._max) {\n      this._max = value;\n    }\n    this._sum += value;\n    this._count++;\n  }\n\n  /** @inheritdoc */\n  public toString(): string {\n    return `${this._last}:${this._min}:${this._max}:${this._sum}:${this._count}`;\n  }\n}\n\n/**\n * A metric instance representing a distribution.\n */\nexport class DistributionMetric implements MetricInstance {\n  private _value: number[];\n\n  public constructor(first: number) {\n    this._value = [first];\n  }\n\n  /** @inheritDoc */\n  public get weight(): number {\n    return this._value.length;\n  }\n\n  /** @inheritdoc */\n  public add(value: number): void {\n    this._value.push(value);\n  }\n\n  /** @inheritdoc */\n  public toString(): string {\n    return this._value.join(':');\n  }\n}\n\n/**\n * A metric instance representing a set.\n */\nexport class SetMetric implements MetricInstance {\n  private _value: Set<number | string>;\n\n  public constructor(public first: number | string) {\n    this._value = new Set([first]);\n  }\n\n  /** @inheritDoc */\n  public get weight(): number {\n    return this._value.size;\n  }\n\n  /** @inheritdoc */\n  public add(value: number | string): void {\n    this._value.add(value);\n  }\n\n  /** @inheritdoc */\n  public toString(): string {\n    return Array.from(this._value)\n      .map(val => (typeof val === 'string' ? simpleHash(val) : val))\n      .join(':');\n  }\n}\n\nexport const METRIC_MAP = {\n  [COUNTER_METRIC_TYPE]: CounterMetric,\n  [GAUGE_METRIC_TYPE]: GaugeMetric,\n  [DISTRIBUTION_METRIC_TYPE]: DistributionMetric,\n  [SET_METRIC_TYPE]: SetMetric,\n};\n", "import type { Client, MeasurementUnit, MetricsAggregator, Primitive } from '../types-hoist';\nimport { timestampInSeconds } from '../utils-hoist/time';\nimport { updateMetricSummaryOnActiveSpan } from '../utils/spanUtils';\nimport { DEFAULT_BROWSER_FLUSH_INTERVAL, SET_METRIC_TYPE } from './constants';\nimport { captureAggregateMetrics } from './envelope';\nimport { METRIC_MAP } from './instance';\nimport type { MetricBucket, MetricType } from './types';\nimport { getBucketKey, sanitizeMetricKey, sanitizeTags, sanitizeUnit } from './utils';\n\n/**\n * A simple metrics aggregator that aggregates metrics in memory and flushes them periodically.\n * Default flush interval is 5 seconds.\n *\n * @experimental This API is experimental and might change in the future.\n */\nexport class BrowserMetricsAggregator implements MetricsAggregator {\n  // TODO(@anonrig): Use FinalizationRegistry to have a proper way of flushing the buckets\n  // when the aggregator is garbage collected.\n  // Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry\n  private _buckets: MetricBucket;\n  private readonly _interval: ReturnType<typeof setInterval>;\n\n  public constructor(private readonly _client: Client) {\n    this._buckets = new Map();\n    this._interval = setInterval(() => this.flush(), DEFAULT_BROWSER_FLUSH_INTERVAL);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public add(\n    metricType: MetricType,\n    unsanitizedName: string,\n    value: number | string,\n    unsanitizedUnit: MeasurementUnit | undefined = 'none',\n    unsanitizedTags: Record<string, Primitive> | undefined = {},\n    maybeFloatTimestamp: number | undefined = timestampInSeconds(),\n  ): void {\n    const timestamp = Math.floor(maybeFloatTimestamp);\n    const name = sanitizeMetricKey(unsanitizedName);\n    const tags = sanitizeTags(unsanitizedTags);\n    const unit = sanitizeUnit(unsanitizedUnit as string);\n\n    const bucketKey = getBucketKey(metricType, name, unit, tags);\n\n    let bucketItem = this._buckets.get(bucketKey);\n    // If this is a set metric, we need to calculate the delta from the previous weight.\n    const previousWeight = bucketItem && metricType === SET_METRIC_TYPE ? bucketItem.metric.weight : 0;\n\n    if (bucketItem) {\n      bucketItem.metric.add(value);\n      // TODO(abhi): Do we need this check?\n      if (bucketItem.timestamp < timestamp) {\n        bucketItem.timestamp = timestamp;\n      }\n    } else {\n      bucketItem = {\n        // @ts-expect-error we don't need to narrow down the type of value here, saves bundle size.\n        metric: new METRIC_MAP[metricType](value),\n        timestamp,\n        metricType,\n        name,\n        unit,\n        tags,\n      };\n      this._buckets.set(bucketKey, bucketItem);\n    }\n\n    // If value is a string, it's a set metric so calculate the delta from the previous weight.\n    const val = typeof value === 'string' ? bucketItem.metric.weight - previousWeight : value;\n    updateMetricSummaryOnActiveSpan(metricType, name, val, unit, unsanitizedTags, bucketKey);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public flush(): void {\n    // short circuit if buckets are empty.\n    if (this._buckets.size === 0) {\n      return;\n    }\n\n    const metricBuckets = Array.from(this._buckets.values());\n    captureAggregateMetrics(this._client, metricBuckets);\n\n    this._buckets.clear();\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public close(): void {\n    clearInterval(this._interval);\n    this.flush();\n  }\n}\n", "import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from './semanticAttributes';\nimport { SPAN_STATUS_ERROR, setHttpStatus, startInactiveSpan } from './tracing';\nimport { SentryNonRecordingSpan } from './tracing/sentryNonRecordingSpan';\nimport type { Client, HandlerDataFetch, Scope, Span, SpanOrigin } from './types-hoist';\nimport { SENTRY_BAGGAGE_KEY_PREFIX } from './utils-hoist/baggage';\nimport { isInstanceOf } from './utils-hoist/is';\nimport { parseUrl } from './utils-hoist/url';\nimport { hasTracingEnabled } from './utils/hasTracingEnabled';\nimport { getActiveSpan } from './utils/spanUtils';\nimport { getTraceData } from './utils/traceData';\n\ntype PolymorphicRequestHeaders =\n  | Record<string, string | undefined>\n  | Array<[string, string]>\n  // the below is not precisely the Header type used in Request, but it'll pass duck-typing\n  | {\n      append: (key: string, value: string) => void;\n      get: (key: string) => string | null | undefined;\n    };\n\n/**\n * Create and track fetch request spans for usage in combination with `addFetchInstrumentationHandler`.\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function instrumentFetchRequest(\n  handlerData: HandlerDataFetch,\n  shouldCreateSpan: (url: string) => boolean,\n  shouldAttachHeaders: (url: string) => boolean,\n  spans: Record<string, Span>,\n  spanOrigin: SpanOrigin = 'auto.http.browser',\n): Span | undefined {\n  if (!handlerData.fetchData) {\n    return undefined;\n  }\n\n  const shouldCreateSpanResult = hasTracingEnabled() && shouldCreateSpan(handlerData.fetchData.url);\n\n  if (handlerData.endTimestamp && shouldCreateSpanResult) {\n    const spanId = handlerData.fetchData.__span;\n    if (!spanId) return;\n\n    const span = spans[spanId];\n    if (span) {\n      endSpan(span, handlerData);\n\n      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n      delete spans[spanId];\n    }\n    return undefined;\n  }\n\n  const { method, url } = handlerData.fetchData;\n\n  const fullUrl = getFullURL(url);\n  const host = fullUrl ? parseUrl(fullUrl).host : undefined;\n\n  const hasParent = !!getActiveSpan();\n\n  const span =\n    shouldCreateSpanResult && hasParent\n      ? startInactiveSpan({\n          name: `${method} ${url}`,\n          attributes: {\n            url,\n            type: 'fetch',\n            'http.method': method,\n            'http.url': fullUrl,\n            'server.address': host,\n            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: spanOrigin,\n            [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n          },\n        })\n      : new SentryNonRecordingSpan();\n\n  handlerData.fetchData.__span = span.spanContext().spanId;\n  spans[span.spanContext().spanId] = span;\n\n  if (shouldAttachHeaders(handlerData.fetchData.url)) {\n    const request: string | Request = handlerData.args[0];\n\n    const options: { [key: string]: unknown } = handlerData.args[1] || {};\n\n    const headers = _addTracingHeadersToFetchRequest(\n      request,\n      options,\n      // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction),\n      // we do not want to use the span as base for the trace headers,\n      // which means that the headers will be generated from the scope and the sampling decision is deferred\n      hasTracingEnabled() && hasParent ? span : undefined,\n    );\n    if (headers) {\n      // Ensure this is actually set, if no options have been passed previously\n      handlerData.args[1] = options;\n      options.headers = headers;\n    }\n  }\n\n  return span;\n}\n\n/**\n * Adds sentry-trace and baggage headers to the various forms of fetch headers.\n */\nfunction _addTracingHeadersToFetchRequest(\n  request: string | Request,\n  fetchOptionsObj: {\n    headers?:\n      | {\n          [key: string]: string[] | string | undefined;\n        }\n      | PolymorphicRequestHeaders;\n  },\n  span?: Span,\n): PolymorphicRequestHeaders | undefined {\n  const traceHeaders = getTraceData({ span });\n  const sentryTrace = traceHeaders['sentry-trace'];\n  const baggage = traceHeaders.baggage;\n\n  // Nothing to do, when we return undefined here, the original headers will be used\n  if (!sentryTrace) {\n    return undefined;\n  }\n\n  const headers = fetchOptionsObj.headers || (isRequest(request) ? request.headers : undefined);\n\n  if (!headers) {\n    return { ...traceHeaders };\n  } else if (isHeaders(headers)) {\n    const newHeaders = new Headers(headers);\n    newHeaders.set('sentry-trace', sentryTrace);\n\n    if (baggage) {\n      const prevBaggageHeader = newHeaders.get('baggage');\n      if (prevBaggageHeader) {\n        const prevHeaderStrippedFromSentryBaggage = stripBaggageHeaderOfSentryBaggageValues(prevBaggageHeader);\n        newHeaders.set(\n          'baggage',\n          // If there are non-sentry entries (i.e. if the stripped string is non-empty/truthy) combine the stripped header and sentry baggage header\n          // otherwise just set the sentry baggage header\n          prevHeaderStrippedFromSentryBaggage ? `${prevHeaderStrippedFromSentryBaggage},${baggage}` : baggage,\n        );\n      } else {\n        newHeaders.set('baggage', baggage);\n      }\n    }\n\n    return newHeaders;\n  } else if (Array.isArray(headers)) {\n    const newHeaders = [\n      ...headers\n        // Remove any existing sentry-trace headers\n        .filter(header => {\n          return !(Array.isArray(header) && header[0] === 'sentry-trace');\n        })\n        // Get rid of previous sentry baggage values in baggage header\n        .map(header => {\n          if (Array.isArray(header) && header[0] === 'baggage' && typeof header[1] === 'string') {\n            const [headerName, headerValue, ...rest] = header;\n            return [headerName, stripBaggageHeaderOfSentryBaggageValues(headerValue), ...rest];\n          } else {\n            return header;\n          }\n        }),\n      // Attach the new sentry-trace header\n      ['sentry-trace', sentryTrace],\n    ];\n\n    if (baggage) {\n      // If there are multiple entries with the same key, the browser will merge the values into a single request header.\n      // Its therefore safe to simply push a \"baggage\" entry, even though there might already be another baggage header.\n      newHeaders.push(['baggage', baggage]);\n    }\n\n    return newHeaders as PolymorphicRequestHeaders;\n  } else {\n    const existingBaggageHeader = 'baggage' in headers ? headers.baggage : undefined;\n    let newBaggageHeaders: string[] = [];\n\n    if (Array.isArray(existingBaggageHeader)) {\n      newBaggageHeaders = existingBaggageHeader\n        .map(headerItem =>\n          typeof headerItem === 'string' ? stripBaggageHeaderOfSentryBaggageValues(headerItem) : headerItem,\n        )\n        .filter(headerItem => headerItem === '');\n    } else if (existingBaggageHeader) {\n      newBaggageHeaders.push(stripBaggageHeaderOfSentryBaggageValues(existingBaggageHeader));\n    }\n\n    if (baggage) {\n      newBaggageHeaders.push(baggage);\n    }\n\n    return {\n      ...(headers as Exclude<typeof headers, Headers>),\n      'sentry-trace': sentryTrace,\n      baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined,\n    };\n  }\n}\n\n/**\n * Adds sentry-trace and baggage headers to the various forms of fetch headers.\n *\n * @deprecated This function will not be exported anymore in v9.\n */\nexport function addTracingHeadersToFetchRequest(\n  request: string | unknown,\n  _client: Client | undefined,\n  _scope: Scope | undefined,\n  fetchOptionsObj: {\n    headers?:\n      | {\n          [key: string]: string[] | string | undefined;\n        }\n      | PolymorphicRequestHeaders;\n  },\n  span?: Span,\n): PolymorphicRequestHeaders | undefined {\n  return _addTracingHeadersToFetchRequest(request as Request, fetchOptionsObj, span);\n}\n\nfunction getFullURL(url: string): string | undefined {\n  try {\n    const parsed = new URL(url);\n    return parsed.href;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction endSpan(span: Span, handlerData: HandlerDataFetch): void {\n  if (handlerData.response) {\n    setHttpStatus(span, handlerData.response.status);\n\n    const contentLength =\n      handlerData.response && handlerData.response.headers && handlerData.response.headers.get('content-length');\n\n    if (contentLength) {\n      const contentLengthNum = parseInt(contentLength);\n      if (contentLengthNum > 0) {\n        span.setAttribute('http.response_content_length', contentLengthNum);\n      }\n    }\n  } else if (handlerData.error) {\n    span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n  }\n  span.end();\n}\n\nfunction stripBaggageHeaderOfSentryBaggageValues(baggageHeader: string): string {\n  return (\n    baggageHeader\n      .split(',')\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      .filter(baggageEntry => !baggageEntry.split('=')[0]!.startsWith(SENTRY_BAGGAGE_KEY_PREFIX))\n      .join(',')\n  );\n}\n\nfunction isRequest(request: unknown): request is Request {\n  return typeof Request !== 'undefined' && isInstanceOf(request, Request);\n}\n\nfunction isHeaders(headers: unknown): headers is Headers {\n  return typeof Headers !== 'undefined' && isInstanceOf(headers, Headers);\n}\n", "import { getClient, getCurrentScope } from './currentScopes';\nimport type { EventHint, FeedbackEvent, SendFeedbackParams } from './types-hoist';\nimport { dropUndefinedKeys } from './utils-hoist/object';\n\n/**\n * Send user feedback to Sentry.\n */\nexport function captureFeedback(\n  params: SendFeedbackParams,\n  hint: EventHint & { includeReplay?: boolean } = {},\n  scope = getCurrentScope(),\n): string {\n  const { message, name, email, url, source, associatedEventId, tags } = params;\n\n  const feedbackEvent: FeedbackEvent = {\n    contexts: {\n      feedback: dropUndefinedKeys({\n        contact_email: email,\n        name,\n        message,\n        url,\n        source,\n        associated_event_id: associatedEventId,\n      }),\n    },\n    type: 'feedback',\n    level: 'info',\n    tags,\n  };\n\n  const client = (scope && scope.getClient()) || getClient();\n\n  if (client) {\n    client.emit('beforeSendFeedback', feedbackEvent, hint);\n  }\n\n  const eventId = scope.captureEvent(feedbackEvent, hint);\n\n  return eventId;\n}\n", "import { addBreadcrumb } from './breadcrumbs';\nimport { getClient, getCurrentScope, getIsolationScope, withScope } from './currentScopes';\nimport {\n  captureEvent,\n  endSession,\n  setContext,\n  setExtra,\n  setExtras,\n  setTag,\n  setTags,\n  setUser,\n  startSession,\n} from './exports';\nimport type { Client, EventHint, Hub, Integration, IntegrationClass, SeverityLevel } from './types-hoist';\n\n/**\n * This is for legacy reasons, and returns a proxy object instead of a hub to be used.\n *\n * @deprecated Use the methods directly from the top level Sentry API (e.g. `Sentry.withScope`)\n * For more information see our migration guide for\n * [replacing `getCurrentHub` and `Hub`](https://github.com/getsentry/sentry-javascript/blob/develop/MIGRATION.md#deprecate-hub)\n * usage\n */\n// eslint-disable-next-line deprecation/deprecation\nexport function getCurrentHubShim(): Hub {\n  return {\n    bindClient(client: Client): void {\n      const scope = getCurrentScope();\n      scope.setClient(client);\n    },\n\n    withScope,\n    getClient: <C extends Client>() => getClient() as C | undefined,\n    getScope: getCurrentScope,\n    getIsolationScope,\n    captureException: (exception: unknown, hint?: EventHint) => {\n      return getCurrentScope().captureException(exception, hint);\n    },\n    captureMessage: (message: string, level?: SeverityLevel, hint?: EventHint) => {\n      return getCurrentScope().captureMessage(message, level, hint);\n    },\n    captureEvent,\n    addBreadcrumb,\n    setUser,\n    setTags,\n    setTag,\n    setExtra,\n    setExtras,\n    setContext,\n\n    getIntegration<T extends Integration>(integration: IntegrationClass<T>): T | null {\n      const client = getClient();\n      return (client && client.getIntegrationByName<T>(integration.id)) || null;\n    },\n\n    startSession,\n    endSession,\n    captureSession(end?: boolean): void {\n      // both send the update and pull the session from the scope\n      if (end) {\n        return endSession();\n      }\n\n      // only send the update\n      _sendSessionUpdate();\n    },\n  };\n}\n\n/**\n * Returns the default hub instance.\n *\n * If a hub is already registered in the global carrier but this module\n * contains a more recent version, it replaces the registered version.\n * Otherwise, the currently registered hub will be returned.\n *\n * @deprecated Use the respective replacement method directly instead.\n */\n// eslint-disable-next-line deprecation/deprecation\nexport const getCurrentHub = getCurrentHubShim;\n\n/**\n * Sends the current Session on the scope\n */\nfunction _sendSessionUpdate(): void {\n  const scope = getCurrentScope();\n  const client = getClient();\n\n  const session = scope.getSession();\n  if (client && session) {\n    client.captureSession(session);\n  }\n}\n", "import type { SeverityLevel } from '../types-hoist';\n\n/**\n * Determine a breadcrumb's log level (only `warning` or `error`) based on an HTTP status code.\n */\nexport function getBreadcrumbLogLevelFromHttpStatusCode(statusCode: number | undefined): SeverityLevel | undefined {\n  // NOTE: undefined defaults to 'info' in Sentry\n  if (statusCode === undefined) {\n    return undefined;\n  } else if (statusCode >= 400 && statusCode < 500) {\n    return 'warning';\n  } else if (statusCode >= 500) {\n    return 'error';\n  } else {\n    return undefined;\n  }\n}\n", "import { DEBUG_BUILD } from './debug-build';\nimport { logger } from './logger';\nimport { GLOBAL_OBJ } from './worldwide';\n\nconst WINDOW = GLOBAL_OBJ as unknown as Window;\n\ndeclare const EdgeRuntime: string | undefined;\n\nexport { supportsHistory } from './vendor/supportsHistory';\n\n/**\n * Tells whether current environment supports ErrorEvent objects\n * {@link supportsErrorEvent}.\n *\n * @returns Answer to the given question.\n */\nexport function supportsErrorEvent(): boolean {\n  try {\n    new ErrorEvent('');\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\n/**\n * Tells whether current environment supports DOMError objects\n * {@link supportsDOMError}.\n *\n * @returns Answer to the given question.\n */\nexport function supportsDOMError(): boolean {\n  try {\n    // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError':\n    // 1 argument required, but only 0 present.\n    // @ts-expect-error It really needs 1 argument, not 0.\n    new DOMError('');\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\n/**\n * Tells whether current environment supports DOMException objects\n * {@link supportsDOMException}.\n *\n * @returns Answer to the given question.\n */\nexport function supportsDOMException(): boolean {\n  try {\n    new DOMException('');\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\n/**\n * Tells whether current environment supports Fetch API\n * {@link supportsFetch}.\n *\n * @returns Answer to the given question.\n */\nexport function supportsFetch(): boolean {\n  if (!('fetch' in WINDOW)) {\n    return false;\n  }\n\n  try {\n    new Headers();\n    new Request('http://www.example.com');\n    new Response();\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\n/**\n * isNative checks if the given function is a native implementation\n */\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function isNativeFunction(func: Function): boolean {\n  return func && /^function\\s+\\w+\\(\\)\\s+\\{\\s+\\[native code\\]\\s+\\}$/.test(func.toString());\n}\n\n/**\n * Tells whether current environment supports Fetch API natively\n * {@link supportsNativeFetch}.\n *\n * @returns true if `window.fetch` is natively implemented, false otherwise\n */\nexport function supportsNativeFetch(): boolean {\n  if (typeof EdgeRuntime === 'string') {\n    return true;\n  }\n\n  if (!supportsFetch()) {\n    return false;\n  }\n\n  // Fast path to avoid DOM I/O\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  if (isNativeFunction(WINDOW.fetch)) {\n    return true;\n  }\n\n  // window.fetch is implemented, but is polyfilled or already wrapped (e.g: by a chrome extension)\n  // so create a \"pure\" iframe to see if that has native fetch\n  let result = false;\n  const doc = WINDOW.document;\n  // eslint-disable-next-line deprecation/deprecation\n  if (doc && typeof (doc.createElement as unknown) === 'function') {\n    try {\n      const sandbox = doc.createElement('iframe');\n      sandbox.hidden = true;\n      doc.head.appendChild(sandbox);\n      if (sandbox.contentWindow && sandbox.contentWindow.fetch) {\n        // eslint-disable-next-line @typescript-eslint/unbound-method\n        result = isNativeFunction(sandbox.contentWindow.fetch);\n      }\n      doc.head.removeChild(sandbox);\n    } catch (err) {\n      DEBUG_BUILD &&\n        logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', err);\n    }\n  }\n\n  return result;\n}\n\n/**\n * Tells whether current environment supports ReportingObserver API\n * {@link supportsReportingObserver}.\n *\n * @returns Answer to the given question.\n */\nexport function supportsReportingObserver(): boolean {\n  return 'ReportingObserver' in WINDOW;\n}\n\n/**\n * Tells whether current environment supports Referrer Policy API\n * {@link supportsReferrerPolicy}.\n *\n * @returns Answer to the given question.\n */\nexport function supportsReferrerPolicy(): boolean {\n  // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default'\n  // (see https://caniuse.com/#feat=referrer-policy),\n  // it doesn't. And it throws an exception instead of ignoring this parameter...\n  // REF: https://github.com/getsentry/raven-js/issues/1233\n\n  if (!supportsFetch()) {\n    return false;\n  }\n\n  try {\n    new Request('_', {\n      referrerPolicy: 'origin' as ReferrerPolicy,\n    });\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { HandlerDataFetch } from '../../types-hoist';\n\nimport { isError } from '../is';\nimport { addNonEnumerableProperty, fill } from '../object';\nimport { supportsNativeFetch } from '../supports';\nimport { timestampInSeconds } from '../time';\nimport { GLOBAL_OBJ } from '../worldwide';\nimport { addHandler, maybeInstrument, triggerHandlers } from './handlers';\n\ntype FetchResource = string | { toString(): string } | { url: string };\n\n/**\n * Add an instrumentation handler for when a fetch request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addFetchInstrumentationHandler(\n  handler: (data: HandlerDataFetch) => void,\n  skipNativeFetchCheck?: boolean,\n): void {\n  const type = 'fetch';\n  addHandler(type, handler);\n  maybeInstrument(type, () => instrumentFetch(undefined, skipNativeFetchCheck));\n}\n\n/**\n * Add an instrumentation handler for long-lived fetch requests, like consuming server-sent events (SSE) via fetch.\n * The handler will resolve the request body and emit the actual `endTimestamp`, so that the\n * span can be updated accordingly.\n *\n * Only used internally\n * @hidden\n */\nexport function addFetchEndInstrumentationHandler(handler: (data: HandlerDataFetch) => void): void {\n  const type = 'fetch-body-resolved';\n  addHandler(type, handler);\n  maybeInstrument(type, () => instrumentFetch(streamHandler));\n}\n\nfunction instrumentFetch(onFetchResolved?: (response: Response) => void, skipNativeFetchCheck: boolean = false): void {\n  if (skipNativeFetchCheck && !supportsNativeFetch()) {\n    return;\n  }\n\n  fill(GLOBAL_OBJ, 'fetch', function (originalFetch: () => void): () => void {\n    return function (...args: any[]): void {\n      // We capture the error right here and not in the Promise error callback because Safari (and probably other\n      // browsers too) will wipe the stack trace up to this point, only leaving us with this file which is useless.\n\n      // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n      //       it means the error, that was caused by your fetch call did not\n      //       have a stack trace, so the SDK backfilled the stack trace so\n      //       you can see which fetch call failed.\n      const virtualError = new Error();\n\n      const { method, url } = parseFetchArgs(args);\n      const handlerData: HandlerDataFetch = {\n        args,\n        fetchData: {\n          method,\n          url,\n        },\n        startTimestamp: timestampInSeconds() * 1000,\n        // // Adding the error to be able to fingerprint the failed fetch event in HttpClient instrumentation\n        virtualError,\n      };\n\n      // if there is no callback, fetch is instrumented directly\n      if (!onFetchResolved) {\n        triggerHandlers('fetch', {\n          ...handlerData,\n        });\n      }\n\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n      return originalFetch.apply(GLOBAL_OBJ, args).then(\n        async (response: Response) => {\n          if (onFetchResolved) {\n            onFetchResolved(response);\n          } else {\n            triggerHandlers('fetch', {\n              ...handlerData,\n              endTimestamp: timestampInSeconds() * 1000,\n              response,\n            });\n          }\n\n          return response;\n        },\n        (error: Error) => {\n          triggerHandlers('fetch', {\n            ...handlerData,\n            endTimestamp: timestampInSeconds() * 1000,\n            error,\n          });\n\n          if (isError(error) && error.stack === undefined) {\n            // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n            //       it means the error, that was caused by your fetch call did not\n            //       have a stack trace, so the SDK backfilled the stack trace so\n            //       you can see which fetch call failed.\n            error.stack = virtualError.stack;\n            addNonEnumerableProperty(error, 'framesToPop', 1);\n          }\n\n          // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n          //       it means the sentry.javascript SDK caught an error invoking your application code.\n          //       This is expected behavior and NOT indicative of a bug with sentry.javascript.\n          throw error;\n        },\n      );\n    };\n  });\n}\n\nasync function resolveResponse(res: Response | undefined, onFinishedResolving: () => void): Promise<void> {\n  if (res && res.body) {\n    const body = res.body;\n    const responseReader = body.getReader();\n\n    // Define a maximum duration after which we just cancel\n    const maxFetchDurationTimeout = setTimeout(\n      () => {\n        body.cancel().then(null, () => {\n          // noop\n        });\n      },\n      90 * 1000, // 90s\n    );\n\n    let readingActive = true;\n    while (readingActive) {\n      let chunkTimeout;\n      try {\n        // abort reading if read op takes more than 5s\n        chunkTimeout = setTimeout(() => {\n          body.cancel().then(null, () => {\n            // noop on error\n          });\n        }, 5000);\n\n        // This .read() call will reject/throw when we abort due to timeouts through `body.cancel()`\n        const { done } = await responseReader.read();\n\n        clearTimeout(chunkTimeout);\n\n        if (done) {\n          onFinishedResolving();\n          readingActive = false;\n        }\n      } catch (error) {\n        readingActive = false;\n      } finally {\n        clearTimeout(chunkTimeout);\n      }\n    }\n\n    clearTimeout(maxFetchDurationTimeout);\n\n    responseReader.releaseLock();\n    body.cancel().then(null, () => {\n      // noop on error\n    });\n  }\n}\n\nfunction streamHandler(response: Response): void {\n  // clone response for awaiting stream\n  let clonedResponseForResolving: Response;\n  try {\n    clonedResponseForResolving = response.clone();\n  } catch {\n    return;\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  resolveResponse(clonedResponseForResolving, () => {\n    triggerHandlers('fetch-body-resolved', {\n      endTimestamp: timestampInSeconds() * 1000,\n      response,\n    });\n  });\n}\n\nfunction hasProp<T extends string>(obj: unknown, prop: T): obj is Record<string, string> {\n  return !!obj && typeof obj === 'object' && !!(obj as Record<string, string>)[prop];\n}\n\nfunction getUrlFromResource(resource: FetchResource): string {\n  if (typeof resource === 'string') {\n    return resource;\n  }\n\n  if (!resource) {\n    return '';\n  }\n\n  if (hasProp(resource, 'url')) {\n    return resource.url;\n  }\n\n  if (resource.toString) {\n    return resource.toString();\n  }\n\n  return '';\n}\n\n/**\n * Parses the fetch arguments to find the used Http method and the url of the request.\n * Exported for tests only.\n */\nexport function parseFetchArgs(fetchArgs: unknown[]): { method: string; url: string } {\n  if (fetchArgs.length === 0) {\n    return { method: 'GET', url: '' };\n  }\n\n  if (fetchArgs.length === 2) {\n    const [url, options] = fetchArgs as [FetchResource, object];\n\n    return {\n      url: getUrlFromResource(url),\n      method: hasProp(options, 'method') ? String(options.method).toUpperCase() : 'GET',\n    };\n  }\n\n  const arg = fetchArgs[0];\n  return {\n    url: getUrlFromResource(arg as FetchResource),\n    method: hasProp(arg, 'method') ? String(arg.method).toUpperCase() : 'GET',\n  };\n}\n", "/*\n * This module exists for optimizations in the build process through rollup and terser.  We define some global\n * constants, which can be overridden during build. By guarding certain pieces of code with functions that return these\n * constants, we can control whether or not they appear in the final bundle. (Any code guarded by a false condition will\n * never run, and will hence be dropped during treeshaking.) The two primary uses for this are stripping out calls to\n * `logger` and preventing node-related code from appearing in browser bundles.\n *\n * Attention:\n * This file should not be used to define constants/flags that are intended to be used for tree-shaking conducted by\n * users. These flags should live in their respective packages, as we identified user tooling (specifically webpack)\n * having issues tree-shaking these constants across package boundaries.\n * An example for this is the __SENTRY_DEBUG__ constant. It is declared in each package individually because we want\n * users to be able to shake away expressions that it guards.\n */\n\ndeclare const __SENTRY_BROWSER_BUNDLE__: boolean | undefined;\n\nexport type SdkSource = 'npm' | 'cdn' | 'loader';\n\n/**\n * Figures out if we're building a browser bundle.\n *\n * @returns true if this is a browser bundle build.\n */\nexport function isBrowserBundle(): boolean {\n  return typeof __SENTRY_BROWSER_BUNDLE__ !== 'undefined' && !!__SENTRY_BROWSER_BUNDLE__;\n}\n\n/**\n * Get source of SDK.\n */\nexport function getSDKSource(): SdkSource {\n  // This comment is used to identify this line in the CDN bundle build step and replace this with \"return 'cdn';\"\n  /* __SENTRY_SDK_SOURCE__ */ return 'npm';\n}\n", "/**\n * NOTE: In order to avoid circular dependencies, if you add a function to this module and it needs to print something,\n * you must either a) use `console.log` rather than the logger, or b) put your function elsewhere.\n */\n\nimport { isBrowserBundle } from './env';\n\n/**\n * Checks whether we're in the Node.js or Browser environment\n *\n * @returns Answer to given question\n */\nexport function isNodeEnv(): boolean {\n  // explicitly check for browser bundles as those can be optimized statically\n  // by terser/rollup.\n  return (\n    !isBrowserBundle() &&\n    Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'\n  );\n}\n\n/**\n * Requires a module which is protected against bundler minification.\n *\n * @param request The module path to resolve\n * @deprecated This function will be removed in the next major version.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function dynamicRequire(mod: any, request: string): any {\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n  return mod.require(request);\n}\n\n/**\n * Helper for dynamically loading module that should work with linked dependencies.\n * The problem is that we _should_ be using `require(require.resolve(moduleName, { paths: [cwd()] }))`\n * However it's _not possible_ to do that with Webpack, as it has to know all the dependencies during\n * build time. `require.resolve` is also not available in any other way, so we cannot create,\n * a fake helper like we do with `dynamicRequire`.\n *\n * We always prefer to use local package, thus the value is not returned early from each `try/catch` block.\n * That is to mimic the behavior of `require.resolve` exactly.\n *\n * @param moduleName module name to require\n * @param existingModule module to use for requiring\n * @returns possibly required module\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function loadModule<T>(moduleName: string, existingModule: any = module): T | undefined {\n  let mod: T | undefined;\n\n  try {\n    // eslint-disable-next-line deprecation/deprecation\n    mod = dynamicRequire(existingModule, moduleName);\n  } catch (e) {\n    // no-empty\n  }\n\n  if (!mod) {\n    try {\n      // eslint-disable-next-line deprecation/deprecation\n      const { cwd } = dynamicRequire(existingModule, 'process');\n      // eslint-disable-next-line deprecation/deprecation\n      mod = dynamicRequire(existingModule, `${cwd()}/node_modules/${moduleName}`) as T;\n    } catch (e) {\n      // no-empty\n    }\n  }\n\n  return mod;\n}\n", "import { isNodeEnv } from './node';\nimport { GLOBAL_OBJ } from './worldwide';\n\n/**\n * Returns true if we are in the browser.\n */\nexport function isBrowser(): boolean {\n  // eslint-disable-next-line no-restricted-globals\n  return typeof window !== 'undefined' && (!isNodeEnv() || isElectronNodeRenderer());\n}\n\ntype ElectronProcess = { type?: string };\n\n// Electron renderers with nodeIntegration enabled are detected as Node.js so we specifically test for them\nfunction isElectronNodeRenderer(): boolean {\n  const process = (GLOBAL_OBJ as typeof GLOBAL_OBJ & { process?: ElectronProcess }).process;\n  return !!process && process.type === 'renderer';\n}\n", "// Based on https://github.com/angular/angular.js/pull/13945/files\n// The MIT License\n\n// Copyright (c) 2010-2016 Google, Inc. http://angularjs.org\n\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nimport { GLOBAL_OBJ } from '../worldwide';\n\nconst WINDOW = GLOBAL_OBJ as unknown as Window;\n\n/**\n * Tells whether current environment supports History API\n * {@link supportsHistory}.\n *\n * @returns Answer to the given question.\n */\nexport function supportsHistory(): boolean {\n  // NOTE: in Chrome App environment, touching history.pushState, *even inside\n  //       a try/catch block*, will cause Chrome to output an error to console.error\n  // borrowed from: https://github.com/angular/angular.js/pull/13945/files\n  // TODO(v9): Remove this custom check, it is pretty old and likely not needed anymore\n  const chromeVar = (WINDOW as { chrome?: { app?: { runtime?: unknown } } }).chrome;\n  const isChromePackagedApp = chromeVar && chromeVar.app && chromeVar.app.runtime;\n  const hasHistoryApi = 'history' in WINDOW && !!WINDOW.history.pushState && !!WINDOW.history.replaceState;\n\n  return !isChromePackagedApp && hasHistoryApi;\n}\n", "// https://github.com/alangpierce/sucrase/tree/265887868966917f3b924ce38dfad01fbab1329f\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2012-2018 various contributors (see AUTHORS)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Polyfill for the nullish coalescing operator (`??`).\n *\n * Note that the RHS is wrapped in a function so that if it's a computed value, that evaluation won't happen unless the\n * LHS evaluates to a nullish value, to mimic the operator's short-circuiting behavior.\n *\n * Adapted from Sucrase (https://github.com/alangpierce/sucrase)\n *\n * @param lhs The value of the expression to the left of the `??`\n * @param rhsFn A function returning the value of the expression to the right of the `??`\n * @returns The LHS value, unless it's `null` or `undefined`, in which case, the RHS value\n */\nexport function _nullishCoalesce(lhs: unknown, rhsFn: () => unknown): unknown {\n  // by checking for loose equality to `null`, we catch both `null` and `undefined`\n  return lhs != null ? lhs : rhsFn();\n}\n\n// Sucrase version:\n// function _nullishCoalesce(lhs, rhsFn) {\n//   if (lhs != null) {\n//     return lhs;\n//   } else {\n//     return rhsFn();\n//   }\n// }\n", "// https://github.com/alangpierce/sucrase/tree/265887868966917f3b924ce38dfad01fbab1329f\n//\n// The MIT License (MIT)\n//\n// Copyright (c) 2012-2018 various contributors (see AUTHORS)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport type { GenericFunction } from './types';\n\n/**\n * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,\n * descriptors, and functions.\n *\n * Adapted from Sucrase (https://github.com/alangpierce/sucrase)\n * See https://github.com/alangpierce/sucrase/blob/265887868966917f3b924ce38dfad01fbab1329f/src/transformers/OptionalChainingNullishTransformer.ts#L15\n *\n * @param ops Array result of expression conversion\n * @returns The value of the expression\n */\nexport function _optionalChain(ops: unknown[]): unknown {\n  let lastAccessLHS: unknown = undefined;\n  let value = ops[0];\n  let i = 1;\n  while (i < ops.length) {\n    const op = ops[i] as string;\n    const fn = ops[i + 1] as (intermediateValue: unknown) => unknown;\n    i += 2;\n    // by checking for loose equality to `null`, we catch both `null` and `undefined`\n    if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {\n      // really we're meaning to return `undefined` as an actual value here, but it saves bytes not to write it\n      return;\n    }\n    if (op === 'access' || op === 'optionalAccess') {\n      lastAccessLHS = value;\n      value = fn(value);\n    } else if (op === 'call' || op === 'optionalCall') {\n      value = fn((...args: unknown[]) => (value as GenericFunction).call(lastAccessLHS, ...args));\n      lastAccessLHS = undefined;\n    }\n  }\n  return value;\n}\n\n// Sucrase version\n// function _optionalChain(ops) {\n//   let lastAccessLHS = undefined;\n//   let value = ops[0];\n//   let i = 1;\n//   while (i < ops.length) {\n//     const op = ops[i];\n//     const fn = ops[i + 1];\n//     i += 2;\n//     if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {\n//       return undefined;\n//     }\n//     if (op === 'access' || op === 'optionalAccess') {\n//       lastAccessLHS = value;\n//       value = fn(value);\n//     } else if (op === 'call' || op === 'optionalCall') {\n//       value = fn((...args) => value.call(lastAccessLHS, ...args));\n//       lastAccessLHS = undefined;\n//     }\n//   }\n//   return value;\n// }\n", "import type { Mechanism, WrappedFunction } from '@sentry/core';\nimport {\n  GLOBAL_OBJ,\n  addExceptionMechanism,\n  addExceptionTypeValue,\n  addNonEnumerableProperty,\n  captureException,\n  getOriginalFunction,\n  markFunctionWrapped,\n  withScope,\n} from '@sentry/core';\n\nexport const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nlet ignoreOnError: number = 0;\n\n/**\n * @hidden\n */\nexport function shouldIgnoreOnError(): boolean {\n  return ignoreOnError > 0;\n}\n\n/**\n * @hidden\n */\nexport function ignoreNextOnError(): void {\n  // onerror should trigger before setTimeout\n  ignoreOnError++;\n  setTimeout(() => {\n    ignoreOnError--;\n  });\n}\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype WrappableFunction = Function;\n\nexport function wrap<T extends WrappableFunction>(\n  fn: T,\n  options?: {\n    mechanism?: Mechanism;\n  },\n): WrappedFunction<T>;\nexport function wrap<NonFunction>(\n  fn: NonFunction,\n  options?: {\n    mechanism?: Mechanism;\n  },\n): NonFunction;\n/**\n * Instruments the given function and sends an event to Sentry every time the\n * function throws an exception.\n *\n * @param fn A function to wrap. It is generally safe to pass an unbound function, because the returned wrapper always\n * has a correct `this` context.\n * @returns The wrapped function.\n * @hidden\n */\nexport function wrap<T extends WrappableFunction, NonFunction>(\n  fn: T | NonFunction,\n  options: {\n    mechanism?: Mechanism;\n  } = {},\n): NonFunction | WrappedFunction<T> {\n  // for future readers what this does is wrap a function and then create\n  // a bi-directional wrapping between them.\n  //\n  // example: wrapped = wrap(original);\n  //  original.__sentry_wrapped__ -> wrapped\n  //  wrapped.__sentry_original__ -> original\n\n  function isFunction(fn: T | NonFunction): fn is T {\n    return typeof fn === 'function';\n  }\n\n  if (!isFunction(fn)) {\n    return fn;\n  }\n\n  try {\n    // if we're dealing with a function that was previously wrapped, return\n    // the original wrapper.\n    const wrapper = (fn as WrappedFunction<T>).__sentry_wrapped__;\n    if (wrapper) {\n      if (typeof wrapper === 'function') {\n        return wrapper;\n      } else {\n        // If we find that the `__sentry_wrapped__` function is not a function at the time of accessing it, it means\n        // that something messed with it. In that case we want to return the originally passed function.\n        return fn;\n      }\n    }\n\n    // We don't wanna wrap it twice\n    if (getOriginalFunction(fn)) {\n      return fn;\n    }\n  } catch (e) {\n    // Just accessing custom props in some Selenium environments\n    // can cause a \"Permission denied\" exception (see raven-js#495).\n    // Bail on wrapping and return the function as-is (defers to window.onerror).\n    return fn;\n  }\n\n  // Wrap the function itself\n  // It is important that `sentryWrapped` is not an arrow function to preserve the context of `this`\n  const sentryWrapped = function (this: unknown, ...args: unknown[]): unknown {\n    try {\n      // Also wrap arguments that are themselves functions\n      const wrappedArguments = args.map(arg => wrap(arg, options));\n\n      // Attempt to invoke user-land function\n      // NOTE: If you are a Sentry user, and you are seeing this stack frame, it\n      //       means the sentry.javascript SDK caught an error invoking your application code. This\n      //       is expected behavior and NOT indicative of a bug with sentry.javascript.\n      return fn.apply(this, wrappedArguments);\n    } catch (ex) {\n      ignoreNextOnError();\n\n      withScope(scope => {\n        scope.addEventProcessor(event => {\n          if (options.mechanism) {\n            addExceptionTypeValue(event, undefined, undefined);\n            addExceptionMechanism(event, options.mechanism);\n          }\n\n          event.extra = {\n            ...event.extra,\n            arguments: args,\n          };\n\n          return event;\n        });\n\n        captureException(ex);\n      });\n\n      throw ex;\n    }\n  } as unknown as WrappedFunction<T>;\n\n  // Wrap the wrapped function in a proxy, to ensure any other properties of the original function remain available\n  try {\n    for (const property in fn) {\n      if (Object.prototype.hasOwnProperty.call(fn, property)) {\n        sentryWrapped[property as keyof T] = fn[property as keyof T];\n      }\n    }\n  } catch {\n    // Accessing some objects may throw\n    // ref: https://github.com/getsentry/sentry-javascript/issues/1168\n  }\n\n  // Signal that this function has been wrapped/filled already\n  // for both debugging and to prevent it to being wrapped/filled twice\n  markFunctionWrapped(sentryWrapped, fn);\n\n  addNonEnumerableProperty(fn, '__sentry_wrapped__', sentryWrapped);\n\n  // Restore original function name (not all browsers allow that)\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name')!;\n    if (descriptor.configurable) {\n      Object.defineProperty(sentryWrapped, 'name', {\n        get(): string {\n          return fn.name;\n        },\n      });\n    }\n  } catch {\n    // This may throw if e.g. the descriptor does not exist, or a browser does not allow redefining `name`.\n    // to save some bytes we simply try-catch this\n  }\n\n  return sentryWrapped;\n}\n", "declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n", "import type {\n  Event,\n  EventHint,\n  Exception,\n  ParameterizedString,\n  SeverityLevel,\n  StackFrame,\n  StackParser,\n} from '@sentry/core';\nimport {\n  addExceptionMechanism,\n  addExceptionTypeValue,\n  extractExceptionKeysForMessage,\n  getClient,\n  isDOMError,\n  isDOMException,\n  isError,\n  isErrorEvent,\n  isEvent,\n  isParameterizedString,\n  isPlainObject,\n  normalizeToSize,\n  resolvedSyncPromise,\n} from '@sentry/core';\n\ntype Prototype = { constructor: (...args: unknown[]) => unknown };\n\n/**\n * This function creates an exception from a JavaScript Error\n */\nexport function exceptionFromError(stackParser: StackParser, ex: Error): Exception {\n  // Get the frames first since Opera can lose the stack if we touch anything else first\n  const frames = parseStackFrames(stackParser, ex);\n\n  const exception: Exception = {\n    type: extractType(ex),\n    value: extractMessage(ex),\n  };\n\n  if (frames.length) {\n    exception.stacktrace = { frames };\n  }\n\n  if (exception.type === undefined && exception.value === '') {\n    exception.value = 'Unrecoverable error caught';\n  }\n\n  return exception;\n}\n\nfunction eventFromPlainObject(\n  stackParser: StackParser,\n  exception: Record<string, unknown>,\n  syntheticException?: Error,\n  isUnhandledRejection?: boolean,\n): Event {\n  const client = getClient();\n  const normalizeDepth = client && client.getOptions().normalizeDepth;\n\n  // If we can, we extract an exception from the object properties\n  const errorFromProp = getErrorPropertyFromObject(exception);\n\n  const extra = {\n    __serialized__: normalizeToSize(exception, normalizeDepth),\n  };\n\n  if (errorFromProp) {\n    return {\n      exception: {\n        values: [exceptionFromError(stackParser, errorFromProp)],\n      },\n      extra,\n    };\n  }\n\n  const event = {\n    exception: {\n      values: [\n        {\n          type: isEvent(exception) ? exception.constructor.name : isUnhandledRejection ? 'UnhandledRejection' : 'Error',\n          value: getNonErrorObjectExceptionValue(exception, { isUnhandledRejection }),\n        } as Exception,\n      ],\n    },\n    extra,\n  } satisfies Event;\n\n  if (syntheticException) {\n    const frames = parseStackFrames(stackParser, syntheticException);\n    if (frames.length) {\n      // event.exception.values[0] has been set above\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      event.exception.values[0]!.stacktrace = { frames };\n    }\n  }\n\n  return event;\n}\n\nfunction eventFromError(stackParser: StackParser, ex: Error): Event {\n  return {\n    exception: {\n      values: [exceptionFromError(stackParser, ex)],\n    },\n  };\n}\n\n/** Parses stack frames from an error */\nfunction parseStackFrames(\n  stackParser: StackParser,\n  ex: Error & { framesToPop?: number; stacktrace?: string },\n): StackFrame[] {\n  // Access and store the stacktrace property before doing ANYTHING\n  // else to it because Opera is not very good at providing it\n  // reliably in other circumstances.\n  const stacktrace = ex.stacktrace || ex.stack || '';\n\n  const skipLines = getSkipFirstStackStringLines(ex);\n  const framesToPop = getPopFirstTopFrames(ex);\n\n  try {\n    return stackParser(stacktrace, skipLines, framesToPop);\n  } catch (e) {\n    // no-empty\n  }\n\n  return [];\n}\n\n// Based on our own mapping pattern - https://github.com/getsentry/sentry/blob/9f08305e09866c8bd6d0c24f5b0aabdd7dd6c59c/src/sentry/lang/javascript/errormapping.py#L83-L108\nconst reactMinifiedRegexp = /Minified React error #\\d+;/i;\n\n/**\n * Certain known React errors contain links that would be falsely\n * parsed as frames. This function check for these errors and\n * returns number of the stack string lines to skip.\n */\nfunction getSkipFirstStackStringLines(ex: Error): number {\n  if (ex && reactMinifiedRegexp.test(ex.message)) {\n    return 1;\n  }\n\n  return 0;\n}\n\n/**\n * If error has `framesToPop` property, it means that the\n * creator tells us the first x frames will be useless\n * and should be discarded. Typically error from wrapper function\n * which don't point to the actual location in the developer's code.\n *\n * Example: https://github.com/zertosh/invariant/blob/master/invariant.js#L46\n */\nfunction getPopFirstTopFrames(ex: Error & { framesToPop?: unknown }): number {\n  if (typeof ex.framesToPop === 'number') {\n    return ex.framesToPop;\n  }\n\n  return 0;\n}\n\n// https://developer.mozilla.org/en-US/docs/WebAssembly/JavaScript_interface/Exception\n// @ts-expect-error - WebAssembly.Exception is a valid class\nfunction isWebAssemblyException(exception: unknown): exception is WebAssembly.Exception {\n  // Check for support\n  // @ts-expect-error - WebAssembly.Exception is a valid class\n  if (typeof WebAssembly !== 'undefined' && typeof WebAssembly.Exception !== 'undefined') {\n    // @ts-expect-error - WebAssembly.Exception is a valid class\n    return exception instanceof WebAssembly.Exception;\n  } else {\n    return false;\n  }\n}\n\n/**\n * Extracts from errors what we use as the exception `type` in error events.\n *\n * Usually, this is the `name` property on Error objects but WASM errors need to be treated differently.\n */\nexport function extractType(ex: Error & { message: { error?: Error } }): string | undefined {\n  const name = ex && ex.name;\n\n  // The name for WebAssembly.Exception Errors needs to be extracted differently.\n  // Context: https://github.com/getsentry/sentry-javascript/issues/13787\n  if (!name && isWebAssemblyException(ex)) {\n    // Emscripten sets array[type, message] to the \"message\" property on the WebAssembly.Exception object\n    const hasTypeInMessage = ex.message && Array.isArray(ex.message) && ex.message.length == 2;\n    return hasTypeInMessage ? ex.message[0] : 'WebAssembly.Exception';\n  }\n\n  return name;\n}\n\n/**\n * There are cases where stacktrace.message is an Event object\n * https://github.com/getsentry/sentry-javascript/issues/1949\n * In this specific case we try to extract stacktrace.message.error.message\n */\nexport function extractMessage(ex: Error & { message: { error?: Error } }): string {\n  const message = ex && ex.message;\n\n  if (!message) {\n    return 'No error message';\n  }\n\n  if (message.error && typeof message.error.message === 'string') {\n    return message.error.message;\n  }\n\n  // Emscripten sets array[type, message] to the \"message\" property on the WebAssembly.Exception object\n  if (isWebAssemblyException(ex) && Array.isArray(ex.message) && ex.message.length == 2) {\n    return ex.message[1];\n  }\n\n  return message;\n}\n\n/**\n * Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.\n * @hidden\n */\nexport function eventFromException(\n  stackParser: StackParser,\n  exception: unknown,\n  hint?: EventHint,\n  attachStacktrace?: boolean,\n): PromiseLike<Event> {\n  const syntheticException = (hint && hint.syntheticException) || undefined;\n  const event = eventFromUnknownInput(stackParser, exception, syntheticException, attachStacktrace);\n  addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }\n  event.level = 'error';\n  if (hint && hint.event_id) {\n    event.event_id = hint.event_id;\n  }\n  return resolvedSyncPromise(event);\n}\n\n/**\n * Builds and Event from a Message\n * @hidden\n */\nexport function eventFromMessage(\n  stackParser: StackParser,\n  message: ParameterizedString,\n  level: SeverityLevel = 'info',\n  hint?: EventHint,\n  attachStacktrace?: boolean,\n): PromiseLike<Event> {\n  const syntheticException = (hint && hint.syntheticException) || undefined;\n  const event = eventFromString(stackParser, message, syntheticException, attachStacktrace);\n  event.level = level;\n  if (hint && hint.event_id) {\n    event.event_id = hint.event_id;\n  }\n  return resolvedSyncPromise(event);\n}\n\n/**\n * @hidden\n */\nexport function eventFromUnknownInput(\n  stackParser: StackParser,\n  exception: unknown,\n  syntheticException?: Error,\n  attachStacktrace?: boolean,\n  isUnhandledRejection?: boolean,\n): Event {\n  let event: Event;\n\n  if (isErrorEvent(exception as ErrorEvent) && (exception as ErrorEvent).error) {\n    // If it is an ErrorEvent with `error` property, extract it to get actual Error\n    const errorEvent = exception as ErrorEvent;\n    return eventFromError(stackParser, errorEvent.error as Error);\n  }\n\n  // If it is a `DOMError` (which is a legacy API, but still supported in some browsers) then we just extract the name\n  // and message, as it doesn't provide anything else. According to the spec, all `DOMExceptions` should also be\n  // `Error`s, but that's not the case in IE11, so in that case we treat it the same as we do a `DOMError`.\n  //\n  // https://developer.mozilla.org/en-US/docs/Web/API/DOMError\n  // https://developer.mozilla.org/en-US/docs/Web/API/DOMException\n  // https://webidl.spec.whatwg.org/#es-DOMException-specialness\n  if (isDOMError(exception) || isDOMException(exception as DOMException)) {\n    const domException = exception as DOMException;\n\n    if ('stack' in (exception as Error)) {\n      event = eventFromError(stackParser, exception as Error);\n    } else {\n      const name = domException.name || (isDOMError(domException) ? 'DOMError' : 'DOMException');\n      const message = domException.message ? `${name}: ${domException.message}` : name;\n      event = eventFromString(stackParser, message, syntheticException, attachStacktrace);\n      addExceptionTypeValue(event, message);\n    }\n    if ('code' in domException) {\n      // eslint-disable-next-line deprecation/deprecation\n      event.tags = { ...event.tags, 'DOMException.code': `${domException.code}` };\n    }\n\n    return event;\n  }\n  if (isError(exception)) {\n    // we have a real Error object, do nothing\n    return eventFromError(stackParser, exception);\n  }\n  if (isPlainObject(exception) || isEvent(exception)) {\n    // If it's a plain object or an instance of `Event` (the built-in JS kind, not this SDK's `Event` type), serialize\n    // it manually. This will allow us to group events based on top-level keys which is much better than creating a new\n    // group on any key/value change.\n    const objectException = exception as Record<string, unknown>;\n    event = eventFromPlainObject(stackParser, objectException, syntheticException, isUnhandledRejection);\n    addExceptionMechanism(event, {\n      synthetic: true,\n    });\n    return event;\n  }\n\n  // If none of previous checks were valid, then it means that it's not:\n  // - an instance of DOMError\n  // - an instance of DOMException\n  // - an instance of Event\n  // - an instance of Error\n  // - a valid ErrorEvent (one with an error property)\n  // - a plain Object\n  //\n  // So bail out and capture it as a simple message:\n  event = eventFromString(stackParser, exception as string, syntheticException, attachStacktrace);\n  addExceptionTypeValue(event, `${exception}`, undefined);\n  addExceptionMechanism(event, {\n    synthetic: true,\n  });\n\n  return event;\n}\n\nfunction eventFromString(\n  stackParser: StackParser,\n  message: ParameterizedString,\n  syntheticException?: Error,\n  attachStacktrace?: boolean,\n): Event {\n  const event: Event = {};\n\n  if (attachStacktrace && syntheticException) {\n    const frames = parseStackFrames(stackParser, syntheticException);\n    if (frames.length) {\n      event.exception = {\n        values: [{ value: message, stacktrace: { frames } }],\n      };\n    }\n    addExceptionMechanism(event, { synthetic: true });\n  }\n\n  if (isParameterizedString(message)) {\n    const { __sentry_template_string__, __sentry_template_values__ } = message;\n\n    event.logentry = {\n      message: __sentry_template_string__,\n      params: __sentry_template_values__,\n    };\n    return event;\n  }\n\n  event.message = message;\n  return event;\n}\n\nfunction getNonErrorObjectExceptionValue(\n  exception: Record<string, unknown>,\n  { isUnhandledRejection }: { isUnhandledRejection?: boolean },\n): string {\n  const keys = extractExceptionKeysForMessage(exception);\n  const captureType = isUnhandledRejection ? 'promise rejection' : 'exception';\n\n  // Some ErrorEvent instances do not have an `error` property, which is why they are not handled before\n  // We still want to try to get a decent message for these cases\n  if (isErrorEvent(exception)) {\n    return `Event \\`ErrorEvent\\` captured as ${captureType} with message \\`${exception.message}\\``;\n  }\n\n  if (isEvent(exception)) {\n    const className = getObjectClassName(exception);\n    return `Event \\`${className}\\` (type=${exception.type}) captured as ${captureType}`;\n  }\n\n  return `Object captured as ${captureType} with keys: ${keys}`;\n}\n\nfunction getObjectClassName(obj: unknown): string | undefined | void {\n  try {\n    const prototype: Prototype | null = Object.getPrototypeOf(obj);\n    return prototype ? prototype.constructor.name : undefined;\n  } catch (e) {\n    // ignore errors here\n  }\n}\n\n/** If a plain object has a property that is an `Error`, return this error. */\nfunction getErrorPropertyFromObject(obj: Record<string, unknown>): Error | undefined {\n  for (const prop in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n      const value = obj[prop];\n      if (value instanceof Error) {\n        return value;\n      }\n    }\n  }\n\n  return undefined;\n}\n", "import { createEnvelope, dsnToString } from '@sentry/core';\nimport type { DsnComponents, EventEnvelope, SdkMetadata, UserFeedback, UserFeedbackItem } from '@sentry/core';\n\n/**\n * Creates an envelope from a user feedback.\n */\nexport function createUserFeedbackEnvelope(\n  feedback: UserFeedback,\n  {\n    metadata,\n    tunnel,\n    dsn,\n  }: {\n    metadata: SdkMetadata | undefined;\n    tunnel: string | undefined;\n    dsn: DsnComponents | undefined;\n  },\n): EventEnvelope {\n  const headers: EventEnvelope[0] = {\n    event_id: feedback.event_id,\n    sent_at: new Date().toISOString(),\n    ...(metadata &&\n      metadata.sdk && {\n        sdk: {\n          name: metadata.sdk.name,\n          version: metadata.sdk.version,\n        },\n      }),\n    ...(!!tunnel && !!dsn && { dsn: dsnToString(dsn) }),\n  };\n  const item = createUserFeedbackEnvelopeItem(feedback);\n\n  return createEnvelope(headers, [item]);\n}\n\nfunction createUserFeedbackEnvelopeItem(feedback: UserFeedback): UserFeedbackItem {\n  const feedbackHeaders: UserFeedbackItem[0] = {\n    type: 'user_report',\n  };\n  return [feedbackHeaders, feedback];\n}\n", "import type {\n  BrowserClientProfilingOptions,\n  BrowserClientReplayOptions,\n  ClientOptions,\n  Event,\n  EventHint,\n  Options,\n  ParameterizedString,\n  Scope,\n  SeverityLevel,\n  UserFeedback,\n} from '@sentry/core';\nimport { BaseClient, applySdkMetadata, getSDKSource, logger } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport { WINDOW } from './helpers';\nimport type { BrowserTransportOptions } from './transports/types';\nimport { createUserFeedbackEnvelope } from './userfeedback';\n\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/core Options for more information.\n */\nexport type BrowserOptions = Options<BrowserTransportOptions> &\n  BrowserClientReplayOptions &\n  BrowserClientProfilingOptions & {\n    /**\n     * Important: Only set this option if you know what you are doing!\n     *\n     * By default, the SDK will check if `Sentry.init` is called in a browser extension.\n     * In case it is, it will stop initialization and log a warning\n     * because browser extensions require a different Sentry initialization process:\n     * https://docs.sentry.io/platforms/javascript/best-practices/shared-environments/\n     *\n     * Setting up the SDK in a browser extension with global error monitoring is not recommended\n     * and will likely flood you with errors from other web sites or extensions. This can heavily\n     * impact your quota and cause interference with your and other Sentry SDKs in shared environments.\n     *\n     * If this check wrongfully flags your setup as a browser extension, you can set this\n     * option to `true` to skip the check.\n     *\n     * @default false\n     */\n    skipBrowserExtensionCheck?: boolean;\n  };\n\n/**\n * Configuration options for the Sentry Browser SDK Client class\n * @see BrowserClient for more information.\n */\nexport type BrowserClientOptions = ClientOptions<BrowserTransportOptions> &\n  BrowserClientReplayOptions &\n  BrowserClientProfilingOptions & {\n    /** If configured, this URL will be used as base URL for lazy loading integration. */\n    cdnBaseUrl?: string;\n  };\n\n/**\n * The Sentry Browser SDK Client.\n *\n * @see BrowserOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class BrowserClient extends BaseClient<BrowserClientOptions> {\n  /**\n   * Creates a new Browser SDK instance.\n   *\n   * @param options Configuration options for this SDK.\n   */\n  public constructor(options: BrowserClientOptions) {\n    const opts = {\n      // We default this to true, as it is the safer scenario\n      parentSpanIsAlwaysRootSpan: true,\n      ...options,\n    };\n    const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();\n    applySdkMetadata(opts, 'browser', ['browser'], sdkSource);\n\n    super(opts);\n\n    if (opts.sendClientReports && WINDOW.document) {\n      WINDOW.document.addEventListener('visibilitychange', () => {\n        if (WINDOW.document.visibilityState === 'hidden') {\n          this._flushOutcomes();\n        }\n      });\n    }\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n    return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  public eventFromMessage(\n    message: ParameterizedString,\n    level: SeverityLevel = 'info',\n    hint?: EventHint,\n  ): PromiseLike<Event> {\n    return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);\n  }\n\n  /**\n   * Sends user feedback to Sentry.\n   *\n   * @deprecated Use `captureFeedback` instead.\n   */\n  public captureUserFeedback(feedback: UserFeedback): void {\n    if (!this._isEnabled()) {\n      DEBUG_BUILD && logger.warn('SDK not enabled, will not capture user feedback.');\n      return;\n    }\n\n    const envelope = createUserFeedbackEnvelope(feedback, {\n      metadata: this.getSdkMetadata(),\n      dsn: this.getDsn(),\n      tunnel: this.getOptions().tunnel,\n    });\n\n    // sendEnvelope should not throw\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.sendEnvelope(envelope);\n  }\n\n  /**\n   * @inheritDoc\n   */\n  protected _prepareEvent(event: Event, hint: EventHint, scope?: Scope): PromiseLike<Event | null> {\n    event.platform = event.platform || 'javascript';\n    return super._prepareEvent(event, hint, scope);\n  }\n}\n", "declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { MetricRatingThresholds, MetricType } from '../types';\n\nconst getRating = (value: number, thresholds: MetricRatingThresholds): MetricType['rating'] => {\n  if (value > thresholds[1]) {\n    return 'poor';\n  }\n  if (value > thresholds[0]) {\n    return 'needs-improvement';\n  }\n  return 'good';\n};\n\nexport const bindReporter = <MetricName extends MetricType['name']>(\n  callback: (metric: Extract<MetricType, { name: MetricName }>) => void,\n  metric: Extract<MetricType, { name: MetricName }>,\n  thresholds: MetricRatingThresholds,\n  reportAllChanges?: boolean,\n) => {\n  let prevValue: number;\n  let delta: number;\n  return (forceReport?: boolean) => {\n    if (metric.value >= 0) {\n      if (forceReport || reportAllChanges) {\n        delta = metric.value - (prevValue || 0);\n\n        // Report the metric if there's a non-zero delta or if no previous\n        // value exists (which can happen in the case of the document becoming\n        // hidden when the metric value is 0).\n        // See: https://github.com/GoogleChrome/web-vitals/issues/14\n        if (delta || prevValue === undefined) {\n          prevValue = metric.value;\n          metric.delta = delta;\n          metric.rating = getRating(metric.value, thresholds);\n          callback(metric);\n        }\n      }\n    }\n  };\n};\n", "import { GLOBAL_OBJ } from '@sentry/core';\n\nexport const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ &\n  // document is not available in all browser environments (webworkers). We make it optional so you have to explicitly check for it\n  Omit<Window, 'document'> &\n  Partial<Pick<Window, 'document'>>;\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Performantly generate a unique, 30-char string by combining a version\n * number, the current timestamp with a 13-digit number integer.\n * @return {string}\n */\nexport const generateUniqueID = () => {\n  return `v4-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;\n};\n", "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\n// sentry-specific change:\n// add optional param to not check for responseStart (see comment below)\nexport const getNavigationEntry = (checkResponseStart = true): PerformanceNavigationTiming | void => {\n  const navigationEntry =\n    WINDOW.performance && WINDOW.performance.getEntriesByType && WINDOW.performance.getEntriesByType('navigation')[0];\n  // Check to ensure the `responseStart` property is present and valid.\n  // In some cases no value is reported by the browser (for\n  // privacy/security reasons), and in other cases (bugs) the value is\n  // negative or is larger than the current page time. Ignore these cases:\n  // https://github.com/GoogleChrome/web-vitals/issues/137\n  // https://github.com/GoogleChrome/web-vitals/issues/162\n  // https://github.com/GoogleChrome/web-vitals/issues/275\n  if (\n    // sentry-specific change:\n    // We don't want to check for responseStart for our own use of `getNavigationEntry`\n    !checkResponseStart ||\n    (navigationEntry && navigationEntry.responseStart > 0 && navigationEntry.responseStart < performance.now())\n  ) {\n    return navigationEntry;\n  }\n};\n", "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getNavigationEntry } from './getNavigationEntry';\n\nexport const getActivationStart = (): number => {\n  const navEntry = getNavigationEntry();\n  return (navEntry && navEntry.activationStart) || 0;\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\nimport type { MetricType } from '../types';\nimport { generateUniqueID } from './generateUniqueID';\nimport { getActivationStart } from './getActivationStart';\nimport { getNavigationEntry } from './getNavigationEntry';\n\nexport const initMetric = <MetricName extends MetricType['name']>(name: MetricName, value?: number) => {\n  const navEntry = getNavigationEntry();\n  let navigationType: MetricType['navigationType'] = 'navigate';\n\n  if (navEntry) {\n    if ((WINDOW.document && WINDOW.document.prerendering) || getActivationStart() > 0) {\n      navigationType = 'prerender';\n    } else if (WINDOW.document && WINDOW.document.wasDiscarded) {\n      navigationType = 'restore';\n    } else if (navEntry.type) {\n      navigationType = navEntry.type.replace(/_/g, '-') as MetricType['navigationType'];\n    }\n  }\n\n  // Use `entries` type specific for the metric.\n  const entries: Extract<MetricType, { name: MetricName }>['entries'] = [];\n\n  return {\n    name,\n    value: typeof value === 'undefined' ? -1 : value,\n    rating: 'good' as const, // If needed, will be updated when reported. `const` to keep the type from widening to `string`.\n    delta: 0,\n    entries,\n    id: generateUniqueID(),\n    navigationType,\n  };\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ninterface PerformanceEntryMap {\n  event: PerformanceEventTiming[];\n  'first-input': PerformanceEventTiming[];\n  'layout-shift': LayoutShift[];\n  'largest-contentful-paint': LargestContentfulPaint[];\n  'long-animation-frame': PerformanceLongAnimationFrameTiming[];\n  paint: PerformancePaintTiming[];\n  navigation: PerformanceNavigationTiming[];\n  resource: PerformanceResourceTiming[];\n  // Sentry-specific change:\n  // We add longtask as a supported entry type as we use this in\n  // our `instrumentPerformanceObserver` function also observes 'longtask'\n  // entries.\n  longtask: PerformanceEntry[];\n}\n\n/**\n * Takes a performance entry type and a callback function, and creates a\n * `PerformanceObserver` instance that will observe the specified entry type\n * with buffering enabled and call the callback _for each entry_.\n *\n * This function also feature-detects entry support and wraps the logic in a\n * try/catch to avoid errors in unsupporting browsers.\n */\nexport const observe = <K extends keyof PerformanceEntryMap>(\n  type: K,\n  callback: (entries: PerformanceEntryMap[K]) => void,\n  opts?: PerformanceObserverInit,\n): PerformanceObserver | undefined => {\n  try {\n    if (PerformanceObserver.supportedEntryTypes.includes(type)) {\n      const po = new PerformanceObserver(list => {\n        // Delay by a microtask to workaround a bug in Safari where the\n        // callback is invoked immediately, rather than in a separate task.\n        // See: https://github.com/GoogleChrome/web-vitals/issues/277\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        Promise.resolve().then(() => {\n          callback(list.getEntries() as PerformanceEntryMap[K]);\n        });\n      });\n      po.observe(\n        Object.assign(\n          {\n            type,\n            buffered: true,\n          },\n          opts || {},\n        ) as PerformanceObserverInit,\n      );\n      return po;\n    }\n  } catch (e) {\n    // Do nothing.\n  }\n  return;\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\nexport interface OnHiddenCallback {\n  (event: Event): void;\n}\n\n// Sentry-specific change:\n// This function's logic was NOT updated to web-vitals 4.2.4 but we continue\n// to use the web-vitals 3.5.2 due to us having stricter browser support.\n// PR with context that made the changes: https://github.com/GoogleChrome/web-vitals/pull/442/files#r1530492402\n// The PR removed listening to the `pagehide` event, in favour of only listening to `visibilitychange` event.\n// This is \"more correct\" but some browsers we still support (Safari 12.1-14.0) don't fully support `visibilitychange`\n// or have known bugs w.r.t the `visibilitychange` event.\n// TODO (v9): If we decide to drop support for Safari 12.1-14.0, we can use the logic from web-vitals 4.2.4\n// In this case, we also need to update the integration tests that currently trigger the `pagehide` event to\n// simulate the page being hidden.\nexport const onHidden = (cb: OnHiddenCallback) => {\n  const onHiddenOrPageHide = (event: Event) => {\n    if (event.type === 'pagehide' || (WINDOW.document && WINDOW.document.visibilityState === 'hidden')) {\n      cb(event);\n    }\n  };\n\n  if (WINDOW.document) {\n    addEventListener('visibilitychange', onHiddenOrPageHide, true);\n    // Some browsers have buggy implementations of visibilitychange,\n    // so we use pagehide in addition, just to be safe.\n    addEventListener('pagehide', onHiddenOrPageHide, true);\n  }\n};\n", "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const runOnce = (cb: () => void) => {\n  let called = false;\n  return () => {\n    if (!called) {\n      cb();\n      called = true;\n    }\n  };\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\nlet firstHiddenTime = -1;\n\nconst initHiddenTime = () => {\n  // If the document is hidden when this code runs, assume it was always\n  // hidden and the page was loaded in the background, with the one exception\n  // that visibility state is always 'hidden' during prerendering, so we have\n  // to ignore that case until prerendering finishes (see: `prerenderingchange`\n  // event logic below).\n  return WINDOW.document!.visibilityState === 'hidden' && !WINDOW.document!.prerendering ? 0 : Infinity;\n};\n\nconst onVisibilityUpdate = (event: Event) => {\n  // If the document is 'hidden' and no previous hidden timestamp has been\n  // set, update it based on the current event data.\n  if (WINDOW.document!.visibilityState === 'hidden' && firstHiddenTime > -1) {\n    // If the event is a 'visibilitychange' event, it means the page was\n    // visible prior to this change, so the event timestamp is the first\n    // hidden time.\n    // However, if the event is not a 'visibilitychange' event, then it must\n    // be a 'prerenderingchange' event, and the fact that the document is\n    // still 'hidden' from the above check means the tab was activated\n    // in a background state and so has always been hidden.\n    firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0;\n\n    // Remove all listeners now that a `firstHiddenTime` value has been set.\n    removeChangeListeners();\n  }\n};\n\nconst addChangeListeners = () => {\n  addEventListener('visibilitychange', onVisibilityUpdate, true);\n  // IMPORTANT: when a page is prerendering, its `visibilityState` is\n  // 'hidden', so in order to account for cases where this module checks for\n  // visibility during prerendering, an additional check after prerendering\n  // completes is also required.\n  addEventListener('prerenderingchange', onVisibilityUpdate, true);\n};\n\nconst removeChangeListeners = () => {\n  removeEventListener('visibilitychange', onVisibilityUpdate, true);\n  removeEventListener('prerenderingchange', onVisibilityUpdate, true);\n};\n\nexport const getVisibilityWatcher = () => {\n  if (WINDOW.document && firstHiddenTime < 0) {\n    // If the document is hidden when this code runs, assume it was hidden\n    // since navigation start. This isn't a perfect heuristic, but it's the\n    // best we can do until an API is available to support querying past\n    // visibilityState.\n    firstHiddenTime = initHiddenTime();\n    addChangeListeners();\n  }\n  return {\n    get firstHiddenTime() {\n      return firstHiddenTime;\n    },\n  };\n};\n", "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\n\nexport const whenActivated = (callback: () => void) => {\n  if (WINDOW.document && WINDOW.document.prerendering) {\n    addEventListener('prerenderingchange', () => callback(), true);\n  } else {\n    callback();\n  }\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { whenActivated } from './lib/whenActivated';\nimport type { FCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */\nexport const FCPThresholds: MetricRatingThresholds = [1800, 3000];\n\n/**\n * Calculates the [FCP](https://web.dev/articles/fcp) value for the current page and\n * calls the `callback` function once the value is ready, along with the\n * relevant `paint` performance entry used to determine the value. The reported\n * value is a `DOMHighResTimeStamp`.\n */\nexport const onFCP = (onReport: (metric: FCPMetric) => void, opts: ReportOpts = {}) => {\n  whenActivated(() => {\n    const visibilityWatcher = getVisibilityWatcher();\n    const metric = initMetric('FCP');\n    let report: ReturnType<typeof bindReporter>;\n\n    const handleEntries = (entries: FCPMetric['entries']) => {\n      entries.forEach(entry => {\n        if (entry.name === 'first-contentful-paint') {\n          po!.disconnect();\n\n          // Only report if the page wasn't hidden prior to the first paint.\n          if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n            // The activationStart reference is used because FCP should be\n            // relative to page activation rather than navigation start if the\n            // page was prerendered. But in cases where `activationStart` occurs\n            // after the FCP, this time should be clamped at 0.\n            metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n            metric.entries.push(entry);\n            report(true);\n          }\n        }\n      });\n    };\n\n    const po = observe('paint', handleEntries);\n\n    if (po) {\n      report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges);\n    }\n  });\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { runOnce } from './lib/runOnce';\nimport { onFCP } from './onFCP';\nimport type { CLSMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */\nexport const CLSThresholds: MetricRatingThresholds = [0.1, 0.25];\n\n/**\n * Calculates the [CLS](https://web.dev/articles/cls) value for the current page and\n * calls the `callback` function once the value is ready to be reported, along\n * with all `layout-shift` performance entries that were used in the metric\n * value calculation. The reported value is a `double` (corresponding to a\n * [layout shift score](https://web.dev/articles/cls#layout_shift_score)).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** CLS should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nexport const onCLS = (onReport: (metric: CLSMetric) => void, opts: ReportOpts = {}) => {\n  // Start monitoring FCP so we can only report CLS if FCP is also reported.\n  // Note: this is done to match the current behavior of CrUX.\n  onFCP(\n    runOnce(() => {\n      const metric = initMetric('CLS', 0);\n      let report: ReturnType<typeof bindReporter>;\n\n      let sessionValue = 0;\n      let sessionEntries: LayoutShift[] = [];\n\n      const handleEntries = (entries: LayoutShift[]) => {\n        entries.forEach(entry => {\n          // Only count layout shifts without recent user input.\n          if (!entry.hadRecentInput) {\n            const firstSessionEntry = sessionEntries[0];\n            const lastSessionEntry = sessionEntries[sessionEntries.length - 1];\n\n            // If the entry occurred less than 1 second after the previous entry\n            // and less than 5 seconds after the first entry in the session,\n            // include the entry in the current session. Otherwise, start a new\n            // session.\n            if (\n              sessionValue &&\n              firstSessionEntry &&\n              lastSessionEntry &&\n              entry.startTime - lastSessionEntry.startTime < 1000 &&\n              entry.startTime - firstSessionEntry.startTime < 5000\n            ) {\n              sessionValue += entry.value;\n              sessionEntries.push(entry);\n            } else {\n              sessionValue = entry.value;\n              sessionEntries = [entry];\n            }\n          }\n        });\n\n        // If the current session value is larger than the current CLS value,\n        // update CLS and the entries contributing to it.\n        if (sessionValue > metric.value) {\n          metric.value = sessionValue;\n          metric.entries = sessionEntries;\n          report();\n        }\n      };\n\n      const po = observe('layout-shift', handleEntries);\n      if (po) {\n        report = bindReporter(onReport, metric, CLSThresholds, opts.reportAllChanges);\n\n        onHidden(() => {\n          handleEntries(po.takeRecords() as CLSMetric['entries']);\n          report(true);\n        });\n\n        // Queue a task to report (if nothing else triggers a report first).\n        // This allows CLS to be reported as soon as FCP fires when\n        // `reportAllChanges` is true.\n        setTimeout(report, 0);\n      }\n    }),\n  );\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport type { FIDMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */\nexport const FIDThresholds: MetricRatingThresholds = [100, 300];\n\n/**\n * Calculates the [FID](https://web.dev/articles/fid) value for the current page and\n * calls the `callback` function once the value is ready, along with the\n * relevant `first-input` performance entry used to determine the value. The\n * reported value is a `DOMHighResTimeStamp`.\n *\n * _**Important:** since FID is only reported after the user interacts with the\n * page, it's possible that it will not be reported for some page loads._\n */\nexport const onFID = (onReport: (metric: FIDMetric) => void, opts: ReportOpts = {}) => {\n  whenActivated(() => {\n    const visibilityWatcher = getVisibilityWatcher();\n    const metric = initMetric('FID');\n    // eslint-disable-next-line prefer-const\n    let report: ReturnType<typeof bindReporter>;\n\n    const handleEntry = (entry: PerformanceEventTiming): void => {\n      // Only report if the page wasn't hidden prior to the first input.\n      if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n        metric.value = entry.processingStart - entry.startTime;\n        metric.entries.push(entry);\n        report(true);\n      }\n    };\n\n    const handleEntries = (entries: FIDMetric['entries']) => {\n      (entries as PerformanceEventTiming[]).forEach(handleEntry);\n    };\n\n    const po = observe('first-input', handleEntries);\n\n    report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges);\n\n    if (po) {\n      onHidden(\n        runOnce(() => {\n          handleEntries(po.takeRecords() as FIDMetric['entries']);\n          po.disconnect();\n        }),\n      );\n    }\n  });\n};\n", "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { observe } from '../observe';\n\ndeclare global {\n  interface Performance {\n    interactionCount: number;\n  }\n}\n\nlet interactionCountEstimate = 0;\nlet minKnownInteractionId = Infinity;\nlet maxKnownInteractionId = 0;\n\nconst updateEstimate = (entries: PerformanceEventTiming[]) => {\n  entries.forEach(e => {\n    if (e.interactionId) {\n      minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId);\n      maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId);\n\n      interactionCountEstimate = maxKnownInteractionId ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1 : 0;\n    }\n  });\n};\n\nlet po: PerformanceObserver | undefined;\n\n/**\n * Returns the `interactionCount` value using the native API (if available)\n * or the polyfill estimate in this module.\n */\nexport const getInteractionCount = (): number => {\n  return po ? interactionCountEstimate : performance.interactionCount || 0;\n};\n\n/**\n * Feature detects native support or initializes the polyfill if needed.\n */\nexport const initInteractionCountPolyfill = (): void => {\n  if ('interactionCount' in performance || po) return;\n\n  po = observe('event', updateEstimate, {\n    type: 'event',\n    buffered: true,\n    durationThreshold: 0,\n  } as PerformanceObserverInit);\n};\n", "/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInteractionCount } from './polyfills/interactionCountPolyfill';\n\ninterface Interaction {\n  id: number;\n  latency: number;\n  entries: PerformanceEventTiming[];\n}\n\ninterface EntryPreProcessingHook {\n  (entry: PerformanceEventTiming): void;\n}\n\n// A list of longest interactions on the page (by latency) sorted so the\n// longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER long.\nexport const longestInteractionList: Interaction[] = [];\n\n// A mapping of longest interactions by their interaction ID.\n// This is used for faster lookup.\nexport const longestInteractionMap: Map<number, Interaction> = new Map();\n\n// The default `durationThreshold` used across this library for observing\n// `event` entries via PerformanceObserver.\nexport const DEFAULT_DURATION_THRESHOLD = 40;\n\n// Used to store the interaction count after a bfcache restore, since p98\n// interaction latencies should only consider the current navigation.\nlet prevInteractionCount = 0;\n\n/**\n * Returns the interaction count since the last bfcache restore (or for the\n * full page lifecycle if there were no bfcache restores).\n */\nconst getInteractionCountForNavigation = () => {\n  return getInteractionCount() - prevInteractionCount;\n};\n\nexport const resetInteractions = () => {\n  prevInteractionCount = getInteractionCount();\n  longestInteractionList.length = 0;\n  longestInteractionMap.clear();\n};\n\n/**\n * Returns the estimated p98 longest interaction based on the stored\n * interaction candidates and the interaction count for the current page.\n */\nexport const estimateP98LongestInteraction = () => {\n  const candidateInteractionIndex = Math.min(\n    longestInteractionList.length - 1,\n    Math.floor(getInteractionCountForNavigation() / 50),\n  );\n\n  return longestInteractionList[candidateInteractionIndex];\n};\n\n// To prevent unnecessary memory usage on pages with lots of interactions,\n// store at most 10 of the longest interactions to consider as INP candidates.\nconst MAX_INTERACTIONS_TO_CONSIDER = 10;\n\n/**\n * A list of callback functions to run before each entry is processed.\n * Exposing this list allows the attribution build to hook into the\n * entry processing pipeline.\n */\nexport const entryPreProcessingCallbacks: EntryPreProcessingHook[] = [];\n\n/**\n * Takes a performance entry and adds it to the list of worst interactions\n * if its duration is long enough to make it among the worst. If the\n * entry is part of an existing interaction, it is merged and the latency\n * and entries list is updated as needed.\n */\nexport const processInteractionEntry = (entry: PerformanceEventTiming) => {\n  entryPreProcessingCallbacks.forEach(cb => cb(entry));\n\n  // Skip further processing for entries that cannot be INP candidates.\n  if (!(entry.interactionId || entry.entryType === 'first-input')) return;\n\n  // The least-long of the 10 longest interactions.\n  const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];\n\n  const existingInteraction = longestInteractionMap.get(entry.interactionId!);\n\n  // Only process the entry if it's possibly one of the ten longest,\n  // or if it's part of an existing interaction.\n  if (\n    existingInteraction ||\n    longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||\n    (minLongestInteraction && entry.duration > minLongestInteraction.latency)\n  ) {\n    // If the interaction already exists, update it. Otherwise create one.\n    if (existingInteraction) {\n      // If the new entry has a longer duration, replace the old entries,\n      // otherwise add to the array.\n      if (entry.duration > existingInteraction.latency) {\n        existingInteraction.entries = [entry];\n        existingInteraction.latency = entry.duration;\n      } else if (\n        entry.duration === existingInteraction.latency &&\n        entry.startTime === (existingInteraction.entries[0] && existingInteraction.entries[0].startTime)\n      ) {\n        existingInteraction.entries.push(entry);\n      }\n    } else {\n      const interaction = {\n        id: entry.interactionId!,\n        latency: entry.duration,\n        entries: [entry],\n      };\n      longestInteractionMap.set(interaction.id, interaction);\n      longestInteractionList.push(interaction);\n    }\n\n    // Sort the entries by latency (descending) and keep only the top ten.\n    longestInteractionList.sort((a, b) => b.latency - a.latency);\n    if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) {\n      longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i => longestInteractionMap.delete(i.id));\n    }\n  }\n};\n", "/*\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../../types';\nimport { onHidden } from './onHidden';\nimport { runOnce } from './runOnce';\n\n/**\n * Runs the passed callback during the next idle period, or immediately\n * if the browser's visibility state is (or becomes) hidden.\n */\nexport const whenIdle = (cb: () => void): number => {\n  const rIC = WINDOW.requestIdleCallback || WINDOW.setTimeout;\n\n  let handle = -1;\n  // eslint-disable-next-line no-param-reassign\n  cb = runOnce(cb) as () => void;\n  // If the document is hidden, run the callback immediately, otherwise\n  // race an idle callback with the next `visibilitychange` event.\n  if (WINDOW.document && WINDOW.document.visibilityState === 'hidden') {\n    cb();\n  } else {\n    handle = rIC(cb);\n    onHidden(cb);\n  }\n  return handle;\n};\n", "/*\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../types';\nimport { bindReporter } from './lib/bindReporter';\nimport { initMetric } from './lib/initMetric';\nimport { DEFAULT_DURATION_THRESHOLD, estimateP98LongestInteraction, processInteractionEntry } from './lib/interactions';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdle } from './lib/whenIdle';\n\nimport type { INPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */\nexport const INPThresholds: MetricRatingThresholds = [200, 500];\n\n/**\n * Calculates the [INP](https://web.dev/articles/inp) value for the current\n * page and calls the `callback` function once the value is ready, along with\n * the `event` performance entries reported for that interaction. The reported\n * value is a `DOMHighResTimeStamp`.\n *\n * A custom `durationThreshold` configuration option can optionally be passed to\n * control what `event-timing` entries are considered for INP reporting. The\n * default threshold is `40`, which means INP scores of less than 40 are\n * reported as 0. Note that this will not affect your 75th percentile INP value\n * unless that value is also less than 40 (well below the recommended\n * [good](https://web.dev/articles/inp#what_is_a_good_inp_score) threshold).\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called as soon as the value is initially\n * determined as well as any time the value changes throughout the page\n * lifespan.\n *\n * _**Important:** INP should be continually monitored for changes throughout\n * the entire lifespan of a page—including if the user returns to the page after\n * it's been hidden/backgrounded. However, since browsers often [will not fire\n * additional callbacks once the user has backgrounded a\n * page](https://developer.chrome.com/blog/page-lifecycle-api/#advice-hidden),\n * `callback` is always called when the page's visibility state changes to\n * hidden. As a result, the `callback` function might be called multiple times\n * during the same page load._\n */\nexport const onINP = (onReport: (metric: INPMetric) => void, opts: ReportOpts = {}) => {\n  // Return if the browser doesn't support all APIs needed to measure INP.\n  if (!('PerformanceEventTiming' in WINDOW && 'interactionId' in PerformanceEventTiming.prototype)) {\n    return;\n  }\n\n  whenActivated(() => {\n    // TODO(philipwalton): remove once the polyfill is no longer needed.\n    initInteractionCountPolyfill();\n\n    const metric = initMetric('INP');\n    // eslint-disable-next-line prefer-const\n    let report: ReturnType<typeof bindReporter>;\n\n    const handleEntries = (entries: INPMetric['entries']) => {\n      // Queue the `handleEntries()` callback in the next idle task.\n      // This is needed to increase the chances that all event entries that\n      // occurred between the user interaction and the next paint\n      // have been dispatched. Note: there is currently an experiment\n      // running in Chrome (EventTimingKeypressAndCompositionInteractionId)\n      // 123+ that if rolled out fully may make this no longer necessary.\n      whenIdle(() => {\n        entries.forEach(processInteractionEntry);\n\n        const inp = estimateP98LongestInteraction();\n\n        if (inp && inp.latency !== metric.value) {\n          metric.value = inp.latency;\n          metric.entries = inp.entries;\n          report();\n        }\n      });\n    };\n\n    const po = observe('event', handleEntries, {\n      // Event Timing entries have their durations rounded to the nearest 8ms,\n      // so a duration of 40ms would be any event that spans 2.5 or more frames\n      // at 60Hz. This threshold is chosen to strike a balance between usefulness\n      // and performance. Running this callback for any interaction that spans\n      // just one or two frames is likely not worth the insight that could be\n      // gained.\n      durationThreshold: opts.durationThreshold != null ? opts.durationThreshold : DEFAULT_DURATION_THRESHOLD,\n    });\n\n    report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges);\n\n    if (po) {\n      // Also observe entries of type `first-input`. This is useful in cases\n      // where the first interaction is less than the `durationThreshold`.\n      po.observe({ type: 'first-input', buffered: true });\n\n      onHidden(() => {\n        handleEntries(po.takeRecords() as INPMetric['entries']);\n        report(true);\n      });\n    }\n  });\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../types';\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { initMetric } from './lib/initMetric';\nimport { observe } from './lib/observe';\nimport { onHidden } from './lib/onHidden';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdle } from './lib/whenIdle';\nimport type { LCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nexport const LCPThresholds: MetricRatingThresholds = [2500, 4000];\n\nconst reportedMetricIDs: Record<string, boolean> = {};\n\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nexport const onLCP = (onReport: (metric: LCPMetric) => void, opts: ReportOpts = {}) => {\n  whenActivated(() => {\n    const visibilityWatcher = getVisibilityWatcher();\n    const metric = initMetric('LCP');\n    let report: ReturnType<typeof bindReporter>;\n\n    const handleEntries = (entries: LCPMetric['entries']) => {\n      // If reportAllChanges is set then call this function for each entry,\n      // otherwise only consider the last one.\n      if (!opts.reportAllChanges) {\n        // eslint-disable-next-line no-param-reassign\n        entries = entries.slice(-1);\n      }\n\n      entries.forEach(entry => {\n        // Only report if the page wasn't hidden prior to LCP.\n        if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n          // The startTime attribute returns the value of the renderTime if it is\n          // not 0, and the value of the loadTime otherwise. The activationStart\n          // reference is used because LCP should be relative to page activation\n          // rather than navigation start if the page was pre-rendered. But in cases\n          // where `activationStart` occurs after the LCP, this time should be\n          // clamped at 0.\n          metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n          metric.entries = [entry];\n          report();\n        }\n      });\n    };\n\n    const po = observe('largest-contentful-paint', handleEntries);\n\n    if (po) {\n      report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n\n      const stopListening = runOnce(() => {\n        if (!reportedMetricIDs[metric.id]) {\n          handleEntries(po.takeRecords() as LCPMetric['entries']);\n          po.disconnect();\n          reportedMetricIDs[metric.id] = true;\n          report(true);\n        }\n      });\n\n      // Stop listening after input. Note: while scrolling is an input that\n      // stops LCP observation, it's unreliable since it can be programmatically\n      // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75\n      ['keydown', 'click'].forEach(type => {\n        // Wrap in a setTimeout so the callback is run in a separate task\n        // to avoid extending the keyboard/click handler to reduce INP impact\n        // https://github.com/GoogleChrome/web-vitals/issues/383\n        if (WINDOW.document) {\n          addEventListener(type, () => whenIdle(stopListening as () => void), {\n            once: true,\n            capture: true,\n          });\n        }\n      });\n\n      onHidden(stopListening);\n    }\n  });\n};\n", "/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { WINDOW } from '../../types';\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getNavigationEntry } from './lib/getNavigationEntry';\nimport { initMetric } from './lib/initMetric';\nimport { whenActivated } from './lib/whenActivated';\nimport type { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types';\n\n/** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */\nexport const TTFBThresholds: MetricRatingThresholds = [800, 1800];\n\n/**\n * Runs in the next task after the page is done loading and/or prerendering.\n * @param callback\n */\nconst whenReady = (callback: () => void) => {\n  if (WINDOW.document && WINDOW.document.prerendering) {\n    whenActivated(() => whenReady(callback));\n  } else if (WINDOW.document && WINDOW.document.readyState !== 'complete') {\n    addEventListener('load', () => whenReady(callback), true);\n  } else {\n    // Queue a task so the callback runs after `loadEventEnd`.\n    setTimeout(callback, 0);\n  }\n};\n\n/**\n * Calculates the [TTFB](https://web.dev/articles/ttfb) value for the\n * current page and calls the `callback` function once the page has loaded,\n * along with the relevant `navigation` performance entry used to determine the\n * value. The reported value is a `DOMHighResTimeStamp`.\n *\n * Note, this function waits until after the page is loaded to call `callback`\n * in order to ensure all properties of the `navigation` entry are populated.\n * This is useful if you want to report on other metrics exposed by the\n * [Navigation Timing API](https://w3c.github.io/navigation-timing/). For\n * example, the TTFB metric starts from the page's [time\n * origin](https://www.w3.org/TR/hr-time-2/#sec-time-origin), which means it\n * includes time spent on DNS lookup, connection negotiation, network latency,\n * and server processing time.\n */\nexport const onTTFB = (onReport: (metric: TTFBMetric) => void, opts: ReportOpts = {}) => {\n  const metric = initMetric('TTFB');\n  const report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges);\n\n  whenReady(() => {\n    const navigationEntry = getNavigationEntry();\n\n    if (navigationEntry) {\n      // The activationStart reference is used because TTFB should be\n      // relative to page activation rather than navigation start if the\n      // page was prerendered. But in cases where `activationStart` occurs\n      // after the first byte is received, this time should be clamped at 0.\n      metric.value = Math.max(navigationEntry.responseStart - getActivationStart(), 0);\n\n      metric.entries = [navigationEntry];\n      report(true);\n    }\n  });\n};\n", "import { getFunctionName, logger } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { onCLS } from './web-vitals/getCLS';\nimport { onFID } from './web-vitals/getFID';\nimport { onINP } from './web-vitals/getINP';\nimport { onLCP } from './web-vitals/getLCP';\nimport { observe } from './web-vitals/lib/observe';\nimport { onTTFB } from './web-vitals/onTTFB';\n\ntype InstrumentHandlerTypePerformanceObserver =\n  | 'longtask'\n  | 'event'\n  | 'navigation'\n  | 'paint'\n  | 'resource'\n  | 'first-input';\n\ntype InstrumentHandlerTypeMetric = 'cls' | 'lcp' | 'fid' | 'ttfb' | 'inp';\n\n// We provide this here manually instead of relying on a global, as this is not available in non-browser environements\n// And we do not want to expose such types\ninterface PerformanceEntry {\n  readonly duration: number;\n  readonly entryType: string;\n  readonly name: string;\n  readonly startTime: number;\n  toJSON(): Record<string, unknown>;\n}\ninterface PerformanceEventTiming extends PerformanceEntry {\n  processingStart: number;\n  processingEnd: number;\n  duration: number;\n  cancelable?: boolean;\n  target?: unknown | null;\n  interactionId?: number;\n}\n\ninterface PerformanceScriptTiming extends PerformanceEntry {\n  sourceURL: string;\n  sourceFunctionName: string;\n  sourceCharPosition: number;\n  invoker: string;\n  invokerType: string;\n}\nexport interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {\n  scripts: PerformanceScriptTiming[];\n}\n\ninterface Metric {\n  /**\n   * The name of the metric (in acronym form).\n   */\n  name: 'CLS' | 'FCP' | 'FID' | 'INP' | 'LCP' | 'TTFB';\n\n  /**\n   * The current value of the metric.\n   */\n  value: number;\n\n  /**\n   * The rating as to whether the metric value is within the \"good\",\n   * \"needs improvement\", or \"poor\" thresholds of the metric.\n   */\n  rating: 'good' | 'needs-improvement' | 'poor';\n\n  /**\n   * The delta between the current value and the last-reported value.\n   * On the first report, `delta` and `value` will always be the same.\n   */\n  delta: number;\n\n  /**\n   * A unique ID representing this particular metric instance. This ID can\n   * be used by an analytics tool to dedupe multiple values sent for the same\n   * metric instance, or to group multiple deltas together and calculate a\n   * total. It can also be used to differentiate multiple different metric\n   * instances sent from the same page, which can happen if the page is\n   * restored from the back/forward cache (in that case new metrics object\n   * get created).\n   */\n  id: string;\n\n  /**\n   * Any performance entries relevant to the metric value calculation.\n   * The array may also be empty if the metric value was not based on any\n   * entries (e.g. a CLS value of 0 given no layout shifts).\n   */\n  entries: PerformanceEntry[];\n\n  /**\n   * The type of navigation\n   *\n   * Navigation Timing API (or `undefined` if the browser doesn't\n   * support that API). For pages that are restored from the bfcache, this\n   * value will be 'back-forward-cache'.\n   */\n  navigationType: 'navigate' | 'reload' | 'back-forward' | 'back-forward-cache' | 'prerender' | 'restore';\n}\n\ntype InstrumentHandlerType = InstrumentHandlerTypeMetric | InstrumentHandlerTypePerformanceObserver;\n\ntype StopListening = undefined | void | (() => void);\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InstrumentHandlerCallback = (data: any) => void;\n\ntype CleanupHandlerCallback = () => void;\n\nconst handlers: { [key in InstrumentHandlerType]?: InstrumentHandlerCallback[] } = {};\nconst instrumented: { [key in InstrumentHandlerType]?: boolean } = {};\n\nlet _previousCls: Metric | undefined;\nlet _previousFid: Metric | undefined;\nlet _previousLcp: Metric | undefined;\nlet _previousTtfb: Metric | undefined;\nlet _previousInp: Metric | undefined;\n\n/**\n * Add a callback that will be triggered when a CLS metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n *\n * Pass `stopOnCallback = true` to stop listening for CLS when the cleanup callback is called.\n * This will lead to the CLS being finalized and frozen.\n */\nexport function addClsInstrumentationHandler(\n  callback: (data: { metric: Metric }) => void,\n  stopOnCallback = false,\n): CleanupHandlerCallback {\n  return addMetricObserver('cls', callback, instrumentCls, _previousCls, stopOnCallback);\n}\n\n/**\n * Add a callback that will be triggered when a LCP metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n *\n * Pass `stopOnCallback = true` to stop listening for LCP when the cleanup callback is called.\n * This will lead to the LCP being finalized and frozen.\n */\nexport function addLcpInstrumentationHandler(\n  callback: (data: { metric: Metric }) => void,\n  stopOnCallback = false,\n): CleanupHandlerCallback {\n  return addMetricObserver('lcp', callback, instrumentLcp, _previousLcp, stopOnCallback);\n}\n\n/**\n * Add a callback that will be triggered when a FID metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nexport function addFidInstrumentationHandler(callback: (data: { metric: Metric }) => void): CleanupHandlerCallback {\n  return addMetricObserver('fid', callback, instrumentFid, _previousFid);\n}\n\n/**\n * Add a callback that will be triggered when a FID metric is available.\n */\nexport function addTtfbInstrumentationHandler(callback: (data: { metric: Metric }) => void): CleanupHandlerCallback {\n  return addMetricObserver('ttfb', callback, instrumentTtfb, _previousTtfb);\n}\n\n/**\n * Add a callback that will be triggered when a INP metric is available.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nexport function addInpInstrumentationHandler(\n  callback: (data: { metric: Omit<Metric, 'entries'> & { entries: PerformanceEventTiming[] } }) => void,\n): CleanupHandlerCallback {\n  return addMetricObserver('inp', callback, instrumentInp, _previousInp);\n}\n\nexport function addPerformanceInstrumentationHandler(\n  type: 'event',\n  callback: (data: { entries: ((PerformanceEntry & { target?: unknown | null }) | PerformanceEventTiming)[] }) => void,\n): CleanupHandlerCallback;\nexport function addPerformanceInstrumentationHandler(\n  type: InstrumentHandlerTypePerformanceObserver,\n  callback: (data: { entries: PerformanceEntry[] }) => void,\n): CleanupHandlerCallback;\n\n/**\n * Add a callback that will be triggered when a performance observer is triggered,\n * and receives the entries of the observer.\n * Returns a cleanup callback which can be called to remove the instrumentation handler.\n */\nexport function addPerformanceInstrumentationHandler(\n  type: InstrumentHandlerTypePerformanceObserver,\n  callback: (data: { entries: PerformanceEntry[] }) => void,\n): CleanupHandlerCallback {\n  addHandler(type, callback);\n\n  if (!instrumented[type]) {\n    instrumentPerformanceObserver(type);\n    instrumented[type] = true;\n  }\n\n  return getCleanupCallback(type, callback);\n}\n\n/** Trigger all handlers of a given type. */\nfunction triggerHandlers(type: InstrumentHandlerType, data: unknown): void {\n  const typeHandlers = handlers[type];\n\n  if (!typeHandlers || !typeHandlers.length) {\n    return;\n  }\n\n  for (const handler of typeHandlers) {\n    try {\n      handler(data);\n    } catch (e) {\n      DEBUG_BUILD &&\n        logger.error(\n          `Error while triggering instrumentation handler.\\nType: ${type}\\nName: ${getFunctionName(handler)}\\nError:`,\n          e,\n        );\n    }\n  }\n}\n\nfunction instrumentCls(): StopListening {\n  return onCLS(\n    metric => {\n      triggerHandlers('cls', {\n        metric,\n      });\n      _previousCls = metric;\n    },\n    // We want the callback to be called whenever the CLS value updates.\n    // By default, the callback is only called when the tab goes to the background.\n    { reportAllChanges: true },\n  );\n}\n\nfunction instrumentFid(): void {\n  return onFID(metric => {\n    triggerHandlers('fid', {\n      metric,\n    });\n    _previousFid = metric;\n  });\n}\n\nfunction instrumentLcp(): StopListening {\n  return onLCP(\n    metric => {\n      triggerHandlers('lcp', {\n        metric,\n      });\n      _previousLcp = metric;\n    },\n    // We want the callback to be called whenever the LCP value updates.\n    // By default, the callback is only called when the tab goes to the background.\n    { reportAllChanges: true },\n  );\n}\n\nfunction instrumentTtfb(): StopListening {\n  return onTTFB(metric => {\n    triggerHandlers('ttfb', {\n      metric,\n    });\n    _previousTtfb = metric;\n  });\n}\n\nfunction instrumentInp(): void {\n  return onINP(metric => {\n    triggerHandlers('inp', {\n      metric,\n    });\n    _previousInp = metric;\n  });\n}\n\nfunction addMetricObserver(\n  type: InstrumentHandlerTypeMetric,\n  callback: InstrumentHandlerCallback,\n  instrumentFn: () => StopListening,\n  previousValue: Metric | undefined,\n  stopOnCallback = false,\n): CleanupHandlerCallback {\n  addHandler(type, callback);\n\n  let stopListening: StopListening | undefined;\n\n  if (!instrumented[type]) {\n    stopListening = instrumentFn();\n    instrumented[type] = true;\n  }\n\n  if (previousValue) {\n    callback({ metric: previousValue });\n  }\n\n  return getCleanupCallback(type, callback, stopOnCallback ? stopListening : undefined);\n}\n\nfunction instrumentPerformanceObserver(type: InstrumentHandlerTypePerformanceObserver): void {\n  const options: PerformanceObserverInit = {};\n\n  // Special per-type options we want to use\n  if (type === 'event') {\n    options.durationThreshold = 0;\n  }\n\n  observe(\n    type,\n    entries => {\n      triggerHandlers(type, { entries });\n    },\n    options,\n  );\n}\n\nfunction addHandler(type: InstrumentHandlerType, handler: InstrumentHandlerCallback): void {\n  handlers[type] = handlers[type] || [];\n  (handlers[type] as InstrumentHandlerCallback[]).push(handler);\n}\n\n// Get a callback which can be called to remove the instrumentation handler\nfunction getCleanupCallback(\n  type: InstrumentHandlerType,\n  callback: InstrumentHandlerCallback,\n  stopListening: StopListening,\n): CleanupHandlerCallback {\n  return () => {\n    if (stopListening) {\n      stopListening();\n    }\n\n    const typeHandlers = handlers[type];\n\n    if (!typeHandlers) {\n      return;\n    }\n\n    const index = typeHandlers.indexOf(callback);\n    if (index !== -1) {\n      typeHandlers.splice(index, 1);\n    }\n  };\n}\n\n/**\n * Check if a PerformanceEntry is a PerformanceEventTiming by checking for the `duration` property.\n */\nexport function isPerformanceEventTiming(entry: PerformanceEntry): entry is PerformanceEventTiming {\n  return 'duration' in entry;\n}\n", "import type { Integration, SentrySpan, Span, SpanAttributes, SpanTimeInput, StartSpanOptions } from '@sentry/core';\nimport { getClient, getCurrentScope, spanToJSON, startInactiveSpan, withActiveSpan } from '@sentry/core';\nimport { WINDOW } from '../types';\n\n/**\n * Checks if a given value is a valid measurement value.\n */\nexport function isMeasurementValue(value: unknown): value is number {\n  return typeof value === 'number' && isFinite(value);\n}\n\n/**\n * Helper function to start child on transactions. This function will make sure that the transaction will\n * use the start timestamp of the created child span if it is earlier than the transactions actual\n * start timestamp.\n */\nexport function startAndEndSpan(\n  parentSpan: Span,\n  startTimeInSeconds: number,\n  endTime: SpanTimeInput,\n  { ...ctx }: StartSpanOptions,\n): Span | undefined {\n  const parentStartTime = spanToJSON(parentSpan).start_timestamp;\n  if (parentStartTime && parentStartTime > startTimeInSeconds) {\n    // We can only do this for SentrySpans...\n    if (typeof (parentSpan as Partial<SentrySpan>).updateStartTime === 'function') {\n      (parentSpan as SentrySpan).updateStartTime(startTimeInSeconds);\n    }\n  }\n\n  // The return value only exists for tests\n  return withActiveSpan(parentSpan, () => {\n    const span = startInactiveSpan({\n      startTime: startTimeInSeconds,\n      ...ctx,\n    });\n\n    if (span) {\n      span.end(endTime);\n    }\n\n    return span;\n  });\n}\n\ninterface StandaloneWebVitalSpanOptions {\n  name: string;\n  transaction?: string;\n  attributes: SpanAttributes;\n  startTime: number;\n}\n\n/**\n * Starts an inactive, standalone span used to send web vital values to Sentry.\n * DO NOT use this for arbitrary spans, as these spans require special handling\n * during ingestion to extract metrics.\n *\n * This function adds a bunch of attributes and data to the span that's shared\n * by all web vital standalone spans. However, you need to take care of adding\n * the actual web vital value as an event to the span. Also, you need to assign\n * a transaction name and some other values that are specific to the web vital.\n *\n * Ultimately, you also need to take care of ending the span to send it off.\n *\n * @param options\n *\n * @returns an inactive, standalone and NOT YET ended span\n */\nexport function startStandaloneWebVitalSpan(options: StandaloneWebVitalSpanOptions): Span | undefined {\n  const client = getClient();\n  if (!client) {\n    return;\n  }\n\n  const { name, transaction, attributes: passedAttributes, startTime } = options;\n\n  const { release, environment } = client.getOptions();\n  // We need to get the replay, user, and activeTransaction from the current scope\n  // so that we can associate replay id, profile id, and a user display to the span\n  const replay = client.getIntegrationByName<Integration & { getReplayId: () => string }>('Replay');\n  const replayId = replay && replay.getReplayId();\n\n  const scope = getCurrentScope();\n\n  const user = scope.getUser();\n  const userDisplay = user !== undefined ? user.email || user.id || user.ip_address : undefined;\n\n  let profileId: string | undefined;\n  try {\n    // @ts-expect-error skip optional chaining to save bundle size with try catch\n    profileId = scope.getScopeData().contexts.profile.profile_id;\n  } catch {\n    // do nothing\n  }\n\n  const attributes: SpanAttributes = {\n    release,\n    environment,\n\n    user: userDisplay || undefined,\n    profile_id: profileId || undefined,\n    replay_id: replayId || undefined,\n\n    transaction,\n\n    // Web vital score calculation relies on the user agent to account for different\n    // browsers setting different thresholds for what is considered a good/meh/bad value.\n    // For example: Chrome vs. Chrome Mobile\n    'user_agent.original': WINDOW.navigator && WINDOW.navigator.userAgent,\n\n    ...passedAttributes,\n  };\n\n  return startInactiveSpan({\n    name,\n    attributes,\n    startTime,\n    experimental: {\n      standalone: true,\n    },\n  });\n}\n\n/** Get the browser performance API. */\nexport function getBrowserPerformanceAPI(): Performance | undefined {\n  // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n  return WINDOW && WINDOW.addEventListener && WINDOW.performance;\n}\n\n/**\n * Converts from milliseconds to seconds\n * @param time time in ms\n */\nexport function msToSec(time: number): number {\n  return time / 1000;\n}\n\n/**\n * Converts ALPN protocol ids to name and version.\n *\n * (https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)\n * @param nextHopProtocol PerformanceResourceTiming.nextHopProtocol\n */\nexport function extractNetworkProtocol(nextHopProtocol: string): { name: string; version: string } {\n  let name = 'unknown';\n  let version = 'unknown';\n  let _name = '';\n  for (const char of nextHopProtocol) {\n    // http/1.1 etc.\n    if (char === '/') {\n      [name, version] = nextHopProtocol.split('/') as [string, string];\n      break;\n    }\n    // h2, h3 etc.\n    if (!isNaN(Number(char))) {\n      name = _name === 'h' ? 'http' : _name;\n      version = nextHopProtocol.split(_name)[1] as string;\n      break;\n    }\n    _name += char;\n  }\n  if (_name === nextHopProtocol) {\n    // webrtc, ftp, etc.\n    name = _name;\n  }\n  return { name, version };\n}\n", "import {\n  SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n  SEMANTIC_ATTRIBUTE_SENTRY_OP,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  getActiveSpan,\n  getClient,\n  getCurrentScope,\n  getRootSpan,\n  spanToJSON,\n} from '@sentry/core';\nimport { browserPerformanceTimeOrigin, dropUndefinedKeys, htmlTreeAsString, logger } from '@sentry/core';\nimport type { SpanAttributes } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { addClsInstrumentationHandler } from './instrument';\nimport { msToSec, startStandaloneWebVitalSpan } from './utils';\nimport { onHidden } from './web-vitals/lib/onHidden';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value once\n *\n * - the page visibility is hidden\n * - a navigation span is started (to stop CLS measurement for SPA soft navigations)\n *\n * Once either of these events triggers, the CLS value is sent as a standalone span and we stop\n * measuring CLS.\n */\nexport function trackClsAsStandaloneSpan(): void {\n  let standaloneCLsValue = 0;\n  let standaloneClsEntry: LayoutShift | undefined;\n  let pageloadSpanId: string | undefined;\n\n  if (!supportsLayoutShift()) {\n    return;\n  }\n\n  let sentSpan = false;\n  function _collectClsOnce() {\n    if (sentSpan) {\n      return;\n    }\n    sentSpan = true;\n    if (pageloadSpanId) {\n      sendStandaloneClsSpan(standaloneCLsValue, standaloneClsEntry, pageloadSpanId);\n    }\n    cleanupClsHandler();\n  }\n\n  const cleanupClsHandler = addClsInstrumentationHandler(({ metric }) => {\n    const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n    if (!entry) {\n      return;\n    }\n    standaloneCLsValue = metric.value;\n    standaloneClsEntry = entry;\n  }, true);\n\n  // use pagehide event from web-vitals\n  onHidden(() => {\n    _collectClsOnce();\n  });\n\n  // Since the call chain of this function is synchronous and evaluates before the SDK client is created,\n  // we need to wait with subscribing to a client hook until the client is created. Therefore, we defer\n  // to the next tick after the SDK setup.\n  setTimeout(() => {\n    const client = getClient();\n\n    if (!client) {\n      return;\n    }\n\n    const unsubscribeStartNavigation = client.on('startNavigationSpan', () => {\n      _collectClsOnce();\n      unsubscribeStartNavigation && unsubscribeStartNavigation();\n    });\n\n    const activeSpan = getActiveSpan();\n    const rootSpan = activeSpan && getRootSpan(activeSpan);\n    const spanJSON = rootSpan && spanToJSON(rootSpan);\n    if (spanJSON && spanJSON.op === 'pageload') {\n      pageloadSpanId = rootSpan.spanContext().spanId;\n    }\n  }, 0);\n}\n\nfunction sendStandaloneClsSpan(clsValue: number, entry: LayoutShift | undefined, pageloadSpanId: string) {\n  DEBUG_BUILD && logger.log(`Sending CLS span (${clsValue})`);\n\n  const startTime = msToSec((browserPerformanceTimeOrigin || 0) + ((entry && entry.startTime) || 0));\n  const routeName = getCurrentScope().getScopeData().transactionName;\n\n  const name = entry ? htmlTreeAsString(entry.sources[0] && entry.sources[0].node) : 'Layout shift';\n\n  const attributes: SpanAttributes = dropUndefinedKeys({\n    [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.cls',\n    [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'ui.webvital.cls',\n    [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: (entry && entry.duration) || 0,\n    // attach the pageload span id to the CLS span so that we can link them in the UI\n    'sentry.pageload.span_id': pageloadSpanId,\n  });\n\n  const span = startStandaloneWebVitalSpan({\n    name,\n    transaction: routeName,\n    attributes,\n    startTime,\n  });\n\n  if (span) {\n    span.addEvent('cls', {\n      [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: '',\n      [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: clsValue,\n    });\n\n    // LayoutShift performance entries always have a duration of 0, so we don't need to add `entry.duration` here\n    // see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/duration\n    span.end(startTime);\n  }\n}\n\nfunction supportsLayoutShift(): boolean {\n  try {\n    return PerformanceObserver.supportedEntryTypes.includes('layout-shift');\n  } catch {\n    return false;\n  }\n}\n", "/* eslint-disable max-lines */\nimport type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  browserPerformanceTimeOrigin,\n  getActiveSpan,\n  getComponentName,\n  htmlTreeAsString,\n  parseUrl,\n  setMeasurement,\n  spanToJSON,\n} from '@sentry/core';\nimport { WINDOW } from '../types';\nimport { trackClsAsStandaloneSpan } from './cls';\nimport {\n  type PerformanceLongAnimationFrameTiming,\n  addClsInstrumentationHandler,\n  addFidInstrumentationHandler,\n  addLcpInstrumentationHandler,\n  addPerformanceInstrumentationHandler,\n  addTtfbInstrumentationHandler,\n} from './instrument';\nimport {\n  extractNetworkProtocol,\n  getBrowserPerformanceAPI,\n  isMeasurementValue,\n  msToSec,\n  startAndEndSpan,\n} from './utils';\nimport { getActivationStart } from './web-vitals/lib/getActivationStart';\nimport { getNavigationEntry } from './web-vitals/lib/getNavigationEntry';\nimport { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher';\n\ninterface NavigatorNetworkInformation {\n  readonly connection?: NetworkInformation;\n}\n\n// http://wicg.github.io/netinfo/#connection-types\ntype ConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'mixed' | 'none' | 'other' | 'unknown' | 'wifi' | 'wimax';\n\n// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum\ntype EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';\n\n// http://wicg.github.io/netinfo/#dom-megabit\ntype Megabit = number;\n// http://wicg.github.io/netinfo/#dom-millisecond\ntype Millisecond = number;\n\n// http://wicg.github.io/netinfo/#networkinformation-interface\ninterface NetworkInformation extends EventTarget {\n  // http://wicg.github.io/netinfo/#type-attribute\n  readonly type?: ConnectionType;\n  // http://wicg.github.io/netinfo/#effectivetype-attribute\n  readonly effectiveType?: EffectiveConnectionType;\n  // http://wicg.github.io/netinfo/#downlinkmax-attribute\n  readonly downlinkMax?: Megabit;\n  // http://wicg.github.io/netinfo/#downlink-attribute\n  readonly downlink?: Megabit;\n  // http://wicg.github.io/netinfo/#rtt-attribute\n  readonly rtt?: Millisecond;\n  // http://wicg.github.io/netinfo/#savedata-attribute\n  readonly saveData?: boolean;\n  // http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection\n  onchange?: EventListener;\n}\n\n// https://w3c.github.io/device-memory/#sec-device-memory-js-api\ninterface NavigatorDeviceMemory {\n  readonly deviceMemory?: number;\n}\n\nconst MAX_INT_AS_BYTES = 2147483647;\n\nlet _performanceCursor: number = 0;\n\nlet _measurements: Measurements = {};\nlet _lcpEntry: LargestContentfulPaint | undefined;\nlet _clsEntry: LayoutShift | undefined;\n\ninterface StartTrackingWebVitalsOptions {\n  recordClsStandaloneSpans: boolean;\n}\n\n/**\n * Start tracking web vitals.\n * The callback returned by this function can be used to stop tracking & ensure all measurements are final & captured.\n *\n * @returns A function that forces web vitals collection\n */\nexport function startTrackingWebVitals({ recordClsStandaloneSpans }: StartTrackingWebVitalsOptions): () => void {\n  const performance = getBrowserPerformanceAPI();\n  if (performance && browserPerformanceTimeOrigin) {\n    // @ts-expect-error we want to make sure all of these are available, even if TS is sure they are\n    if (performance.mark) {\n      WINDOW.performance.mark('sentry-tracing-init');\n    }\n    const fidCleanupCallback = _trackFID();\n    const lcpCleanupCallback = _trackLCP();\n    const ttfbCleanupCallback = _trackTtfb();\n    const clsCleanupCallback = recordClsStandaloneSpans ? trackClsAsStandaloneSpan() : _trackCLS();\n\n    return (): void => {\n      fidCleanupCallback();\n      lcpCleanupCallback();\n      ttfbCleanupCallback();\n      clsCleanupCallback && clsCleanupCallback();\n    };\n  }\n\n  return () => undefined;\n}\n\n/**\n * Start tracking long tasks.\n */\nexport function startTrackingLongTasks(): void {\n  addPerformanceInstrumentationHandler('longtask', ({ entries }) => {\n    const parent = getActiveSpan();\n    if (!parent) {\n      return;\n    }\n\n    const { op: parentOp, start_timestamp: parentStartTimestamp } = spanToJSON(parent);\n\n    for (const entry of entries) {\n      const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n      const duration = msToSec(entry.duration);\n\n      if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n        // Skip adding a span if the long task started before the navigation started.\n        // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n        // time, potentially skewing the duration of the actual navigation as reported via our\n        // routing instrumentations\n        continue;\n      }\n\n      startAndEndSpan(parent, startTime, startTime + duration, {\n        name: 'Main UI thread blocked',\n        op: 'ui.long-task',\n        attributes: {\n          [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n        },\n      });\n    }\n  });\n}\n\n/**\n * Start tracking long animation frames.\n */\nexport function startTrackingLongAnimationFrames(): void {\n  // NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so\n  // we directly observe `long-animation-frame` events instead of through the web-vitals\n  // `observe` helper function.\n  const observer = new PerformanceObserver(list => {\n    const parent = getActiveSpan();\n    if (!parent) {\n      return;\n    }\n    for (const entry of list.getEntries() as PerformanceLongAnimationFrameTiming[]) {\n      if (!entry.scripts[0]) {\n        continue;\n      }\n\n      const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n\n      const { start_timestamp: parentStartTimestamp, op: parentOp } = spanToJSON(parent);\n\n      if (parentOp === 'navigation' && parentStartTimestamp && startTime < parentStartTimestamp) {\n        // Skip adding the span if the long animation frame started before the navigation started.\n        // `startAndEndSpan` will otherwise adjust the parent's start time to the span's start\n        // time, potentially skewing the duration of the actual navigation as reported via our\n        // routing instrumentations\n        continue;\n      }\n\n      const duration = msToSec(entry.duration);\n\n      const attributes: SpanAttributes = {\n        [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n      };\n\n      const initialScript = entry.scripts[0];\n      const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;\n      attributes['browser.script.invoker'] = invoker;\n      attributes['browser.script.invoker_type'] = invokerType;\n      if (sourceURL) {\n        attributes['code.filepath'] = sourceURL;\n      }\n      if (sourceFunctionName) {\n        attributes['code.function'] = sourceFunctionName;\n      }\n      if (sourceCharPosition !== -1) {\n        attributes['browser.script.source_char_position'] = sourceCharPosition;\n      }\n\n      startAndEndSpan(parent, startTime, startTime + duration, {\n        name: 'Main UI thread blocked',\n        op: 'ui.long-animation-frame',\n        attributes,\n      });\n    }\n  });\n\n  observer.observe({ type: 'long-animation-frame', buffered: true });\n}\n\n/**\n * Start tracking interaction events.\n */\nexport function startTrackingInteractions(): void {\n  addPerformanceInstrumentationHandler('event', ({ entries }) => {\n    const parent = getActiveSpan();\n    if (!parent) {\n      return;\n    }\n    for (const entry of entries) {\n      if (entry.name === 'click') {\n        const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n        const duration = msToSec(entry.duration);\n\n        const spanOptions: StartSpanOptions & Required<Pick<StartSpanOptions, 'attributes'>> = {\n          name: htmlTreeAsString(entry.target),\n          op: `ui.interaction.${entry.name}`,\n          startTime: startTime,\n          attributes: {\n            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n          },\n        };\n\n        const componentName = getComponentName(entry.target);\n        if (componentName) {\n          spanOptions.attributes['ui.component_name'] = componentName;\n        }\n\n        startAndEndSpan(parent, startTime, startTime + duration, spanOptions);\n      }\n    }\n  });\n}\n\nexport { registerInpInteractionListener, startTrackingINP } from './inp';\n\n/**\n * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry\n * to the `_measurements` object which ultimately is applied to the pageload span's measurements.\n */\nfunction _trackCLS(): () => void {\n  return addClsInstrumentationHandler(({ metric }) => {\n    const entry = metric.entries[metric.entries.length - 1] as LayoutShift | undefined;\n    if (!entry) {\n      return;\n    }\n    _measurements['cls'] = { value: metric.value, unit: '' };\n    _clsEntry = entry;\n  }, true);\n}\n\n/** Starts tracking the Largest Contentful Paint on the current page. */\nfunction _trackLCP(): () => void {\n  return addLcpInstrumentationHandler(({ metric }) => {\n    const entry = metric.entries[metric.entries.length - 1];\n    if (!entry) {\n      return;\n    }\n\n    _measurements['lcp'] = { value: metric.value, unit: 'millisecond' };\n    _lcpEntry = entry as LargestContentfulPaint;\n  }, true);\n}\n\n/** Starts tracking the First Input Delay on the current page. */\nfunction _trackFID(): () => void {\n  return addFidInstrumentationHandler(({ metric }) => {\n    const entry = metric.entries[metric.entries.length - 1];\n    if (!entry) {\n      return;\n    }\n\n    const timeOrigin = msToSec(browserPerformanceTimeOrigin as number);\n    const startTime = msToSec(entry.startTime);\n    _measurements['fid'] = { value: metric.value, unit: 'millisecond' };\n    _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' };\n  });\n}\n\nfunction _trackTtfb(): () => void {\n  return addTtfbInstrumentationHandler(({ metric }) => {\n    const entry = metric.entries[metric.entries.length - 1];\n    if (!entry) {\n      return;\n    }\n\n    _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' };\n  });\n}\n\ninterface AddPerformanceEntriesOptions {\n  /**\n   * Flag to determine if CLS should be recorded as a measurement on the span or\n   * sent as a standalone span instead.\n   */\n  recordClsOnPageloadSpan: boolean;\n}\n\n/** Add performance related spans to a transaction */\nexport function addPerformanceEntries(span: Span, options: AddPerformanceEntriesOptions): void {\n  const performance = getBrowserPerformanceAPI();\n  if (!performance || !performance.getEntries || !browserPerformanceTimeOrigin) {\n    // Gatekeeper if performance API not available\n    return;\n  }\n\n  const timeOrigin = msToSec(browserPerformanceTimeOrigin);\n\n  const performanceEntries = performance.getEntries();\n\n  const { op, start_timestamp: transactionStartTime } = spanToJSON(span);\n\n  performanceEntries.slice(_performanceCursor).forEach(entry => {\n    const startTime = msToSec(entry.startTime);\n    const duration = msToSec(\n      // Inexplicably, Chrome sometimes emits a negative duration. We need to work around this.\n      // There is a SO post attempting to explain this, but it leaves one with open questions: https://stackoverflow.com/questions/23191918/peformance-getentries-and-negative-duration-display\n      // The way we clamp the value is probably not accurate, since we have observed this happen for things that may take a while to load, like for example the replay worker.\n      // TODO: Investigate why this happens and how to properly mitigate. For now, this is a workaround to prevent transactions being dropped due to negative duration spans.\n      Math.max(0, entry.duration),\n    );\n\n    if (op === 'navigation' && transactionStartTime && timeOrigin + startTime < transactionStartTime) {\n      return;\n    }\n\n    switch (entry.entryType) {\n      case 'navigation': {\n        _addNavigationSpans(span, entry as PerformanceNavigationTiming, timeOrigin);\n        break;\n      }\n      case 'mark':\n      case 'paint':\n      case 'measure': {\n        _addMeasureSpans(span, entry, startTime, duration, timeOrigin);\n\n        // capture web vitals\n        const firstHidden = getVisibilityWatcher();\n        // Only report if the page wasn't hidden prior to the web vital.\n        const shouldRecord = entry.startTime < firstHidden.firstHiddenTime;\n\n        if (entry.name === 'first-paint' && shouldRecord) {\n          _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' };\n        }\n        if (entry.name === 'first-contentful-paint' && shouldRecord) {\n          _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' };\n        }\n        break;\n      }\n      case 'resource': {\n        _addResourceSpans(span, entry as PerformanceResourceTiming, entry.name, startTime, duration, timeOrigin);\n        break;\n      }\n      // Ignore other entry types.\n    }\n  });\n\n  _performanceCursor = Math.max(performanceEntries.length - 1, 0);\n\n  _trackNavigator(span);\n\n  // Measurements are only available for pageload transactions\n  if (op === 'pageload') {\n    _addTtfbRequestTimeToMeasurements(_measurements);\n\n    const fidMark = _measurements['mark.fid'];\n    if (fidMark && _measurements['fid']) {\n      // create span for FID\n      startAndEndSpan(span, fidMark.value, fidMark.value + msToSec(_measurements['fid'].value), {\n        name: 'first input delay',\n        op: 'ui.action',\n        attributes: {\n          [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n        },\n      });\n\n      // Delete mark.fid as we don't want it to be part of final payload\n      delete _measurements['mark.fid'];\n    }\n\n    // If FCP is not recorded we should not record the cls value\n    // according to the new definition of CLS.\n    // TODO: Check if the first condition is still necessary: `onCLS` already only fires once `onFCP` was called.\n    if (!('fcp' in _measurements) || !options.recordClsOnPageloadSpan) {\n      delete _measurements.cls;\n    }\n\n    Object.entries(_measurements).forEach(([measurementName, measurement]) => {\n      setMeasurement(measurementName, measurement.value, measurement.unit);\n    });\n\n    // Set timeOrigin which denotes the timestamp which to base the LCP/FCP/FP/TTFB measurements on\n    span.setAttribute('performance.timeOrigin', timeOrigin);\n\n    // In prerendering scenarios, where a page might be prefetched and pre-rendered before the user clicks the link,\n    // the navigation starts earlier than when the user clicks it. Web Vitals should always be based on the\n    // user-perceived time, so they are not reported from the actual start of the navigation, but rather from the\n    // time where the user actively started the navigation, for example by clicking a link.\n    // This is user action is called \"activation\" and the time between navigation and activation is stored in\n    // the `activationStart` attribute of the \"navigation\" PerformanceEntry.\n    span.setAttribute('performance.activationStart', getActivationStart());\n\n    _setWebVitalAttributes(span);\n  }\n\n  _lcpEntry = undefined;\n  _clsEntry = undefined;\n  _measurements = {};\n}\n\n/**\n * Create measure related spans.\n * Exported only for tests.\n */\nexport function _addMeasureSpans(\n  span: Span,\n  entry: PerformanceEntry,\n  startTime: number,\n  duration: number,\n  timeOrigin: number,\n): void {\n  const navEntry = getNavigationEntry(false);\n  const requestTime = msToSec(navEntry ? navEntry.requestStart : 0);\n  // Because performance.measure accepts arbitrary timestamps it can produce\n  // spans that happen before the browser even makes a request for the page.\n  //\n  // An example of this is the automatically generated Next.js-before-hydration\n  // spans created by the Next.js framework.\n  //\n  // To prevent this we will pin the start timestamp to the request start time\n  // This does make duration inaccurate, so if this does happen, we will add\n  // an attribute to the span\n  const measureStartTimestamp = timeOrigin + Math.max(startTime, requestTime);\n  const startTimeStamp = timeOrigin + startTime;\n  const measureEndTimestamp = startTimeStamp + duration;\n\n  const attributes: SpanAttributes = {\n    [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n  };\n\n  if (measureStartTimestamp !== startTimeStamp) {\n    attributes['sentry.browser.measure_happened_before_request'] = true;\n    attributes['sentry.browser.measure_start_time'] = measureStartTimestamp;\n  }\n\n  // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process.\n  if (measureStartTimestamp <= measureEndTimestamp) {\n    startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, {\n      name: entry.name as string,\n      op: entry.entryType as string,\n      attributes,\n    });\n  }\n}\n\n/** Instrument navigation entries */\nfunction _addNavigationSpans(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n  (['unloadEvent', 'redirect', 'domContentLoadedEvent', 'loadEvent', 'connect'] as const).forEach(event => {\n    _addPerformanceNavigationTiming(span, entry, event, timeOrigin);\n  });\n  _addPerformanceNavigationTiming(span, entry, 'secureConnection', timeOrigin, 'TLS/SSL');\n  _addPerformanceNavigationTiming(span, entry, 'fetch', timeOrigin, 'cache');\n  _addPerformanceNavigationTiming(span, entry, 'domainLookup', timeOrigin, 'DNS');\n\n  _addRequest(span, entry, timeOrigin);\n}\n\ntype StartEventName =\n  | 'secureConnection'\n  | 'fetch'\n  | 'domainLookup'\n  | 'unloadEvent'\n  | 'redirect'\n  | 'connect'\n  | 'domContentLoadedEvent'\n  | 'loadEvent';\n\ntype EndEventName =\n  | 'connectEnd'\n  | 'domainLookupStart'\n  | 'domainLookupEnd'\n  | 'unloadEventEnd'\n  | 'redirectEnd'\n  | 'connectEnd'\n  | 'domContentLoadedEventEnd'\n  | 'loadEventEnd';\n\n/** Create performance navigation related spans */\nfunction _addPerformanceNavigationTiming(\n  span: Span,\n  entry: PerformanceNavigationTiming,\n  event: StartEventName,\n  timeOrigin: number,\n  name: string = event,\n): void {\n  const eventEnd = _getEndPropertyNameForNavigationTiming(event) satisfies keyof PerformanceNavigationTiming;\n  const end = entry[eventEnd];\n  const start = entry[`${event}Start`];\n  if (!start || !end) {\n    return;\n  }\n  startAndEndSpan(span, timeOrigin + msToSec(start), timeOrigin + msToSec(end), {\n    op: `browser.${name}`,\n    name: entry.name,\n    attributes: {\n      [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n    },\n  });\n}\n\nfunction _getEndPropertyNameForNavigationTiming(event: StartEventName): EndEventName {\n  if (event === 'secureConnection') {\n    return 'connectEnd';\n  }\n  if (event === 'fetch') {\n    return 'domainLookupStart';\n  }\n  return `${event}End`;\n}\n\n/** Create request and response related spans */\nfunction _addRequest(span: Span, entry: PerformanceNavigationTiming, timeOrigin: number): void {\n  const requestStartTimestamp = timeOrigin + msToSec(entry.requestStart as number);\n  const responseEndTimestamp = timeOrigin + msToSec(entry.responseEnd as number);\n  const responseStartTimestamp = timeOrigin + msToSec(entry.responseStart as number);\n  if (entry.responseEnd) {\n    // It is possible that we are collecting these metrics when the page hasn't finished loading yet, for example when the HTML slowly streams in.\n    // In this case, ie. when the document request hasn't finished yet, `entry.responseEnd` will be 0.\n    // In order not to produce faulty spans, where the end timestamp is before the start timestamp, we will only collect\n    // these spans when the responseEnd value is available. The backend (Relay) would drop the entire span if it contained faulty spans.\n    startAndEndSpan(span, requestStartTimestamp, responseEndTimestamp, {\n      op: 'browser.request',\n      name: entry.name,\n      attributes: {\n        [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n      },\n    });\n\n    startAndEndSpan(span, responseStartTimestamp, responseEndTimestamp, {\n      op: 'browser.response',\n      name: entry.name,\n      attributes: {\n        [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',\n      },\n    });\n  }\n}\n\n/**\n * Create resource-related spans.\n * Exported only for tests.\n */\nexport function _addResourceSpans(\n  span: Span,\n  entry: PerformanceResourceTiming,\n  resourceUrl: string,\n  startTime: number,\n  duration: number,\n  timeOrigin: number,\n): void {\n  // we already instrument based on fetch and xhr, so we don't need to\n  // duplicate spans here.\n  if (entry.initiatorType === 'xmlhttprequest' || entry.initiatorType === 'fetch') {\n    return;\n  }\n\n  const parsedUrl = parseUrl(resourceUrl);\n\n  const attributes: SpanAttributes = {\n    [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics',\n  };\n  setResourceEntrySizeData(attributes, entry, 'transferSize', 'http.response_transfer_size');\n  setResourceEntrySizeData(attributes, entry, 'encodedBodySize', 'http.response_content_length');\n  setResourceEntrySizeData(attributes, entry, 'decodedBodySize', 'http.decoded_response_content_length');\n\n  // `deliveryType` is experimental and does not exist everywhere\n  const deliveryType = (entry as { deliveryType?: 'cache' | 'navigational-prefetch' | '' }).deliveryType;\n  if (deliveryType != null) {\n    attributes['http.response_delivery_type'] = deliveryType;\n  }\n\n  // Types do not reflect this property yet\n  const renderBlockingStatus = (entry as { renderBlockingStatus?: 'render-blocking' | 'non-render-blocking' })\n    .renderBlockingStatus;\n  if (renderBlockingStatus) {\n    attributes['resource.render_blocking_status'] = renderBlockingStatus;\n  }\n\n  if (parsedUrl.protocol) {\n    attributes['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.\n  }\n\n  if (parsedUrl.host) {\n    attributes['server.address'] = parsedUrl.host;\n  }\n\n  attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);\n\n  const { name, version } = extractNetworkProtocol(entry.nextHopProtocol);\n  attributes['network.protocol.name'] = name;\n  attributes['network.protocol.version'] = version;\n\n  const startTimestamp = timeOrigin + startTime;\n  const endTimestamp = startTimestamp + duration;\n\n  startAndEndSpan(span, startTimestamp, endTimestamp, {\n    name: resourceUrl.replace(WINDOW.location.origin, ''),\n    op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',\n    attributes,\n  });\n}\n\n/**\n * Capture the information of the user agent.\n */\nfunction _trackNavigator(span: Span): void {\n  const navigator = WINDOW.navigator as null | (Navigator & NavigatorNetworkInformation & NavigatorDeviceMemory);\n  if (!navigator) {\n    return;\n  }\n\n  // track network connectivity\n  const connection = navigator.connection;\n  if (connection) {\n    if (connection.effectiveType) {\n      span.setAttribute('effectiveConnectionType', connection.effectiveType);\n    }\n\n    if (connection.type) {\n      span.setAttribute('connectionType', connection.type);\n    }\n\n    if (isMeasurementValue(connection.rtt)) {\n      _measurements['connection.rtt'] = { value: connection.rtt, unit: 'millisecond' };\n    }\n  }\n\n  if (isMeasurementValue(navigator.deviceMemory)) {\n    span.setAttribute('deviceMemory', `${navigator.deviceMemory} GB`);\n  }\n\n  if (isMeasurementValue(navigator.hardwareConcurrency)) {\n    span.setAttribute('hardwareConcurrency', String(navigator.hardwareConcurrency));\n  }\n}\n\n/** Add LCP / CLS data to span to allow debugging */\nfunction _setWebVitalAttributes(span: Span): void {\n  if (_lcpEntry) {\n    // Capture Properties of the LCP element that contributes to the LCP.\n\n    if (_lcpEntry.element) {\n      span.setAttribute('lcp.element', htmlTreeAsString(_lcpEntry.element));\n    }\n\n    if (_lcpEntry.id) {\n      span.setAttribute('lcp.id', _lcpEntry.id);\n    }\n\n    if (_lcpEntry.url) {\n      // Trim URL to the first 200 characters.\n      span.setAttribute('lcp.url', _lcpEntry.url.trim().slice(0, 200));\n    }\n\n    if (_lcpEntry.loadTime != null) {\n      // loadTime is the time of LCP that's related to receiving the LCP element response..\n      span.setAttribute('lcp.loadTime', _lcpEntry.loadTime);\n    }\n\n    if (_lcpEntry.renderTime != null) {\n      // renderTime is loadTime + rendering time\n      // it's 0 if the LCP element is loaded from a 3rd party origin that doesn't send the\n      // `Timing-Allow-Origin` header.\n      span.setAttribute('lcp.renderTime', _lcpEntry.renderTime);\n    }\n\n    span.setAttribute('lcp.size', _lcpEntry.size);\n  }\n\n  // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift\n  if (_clsEntry && _clsEntry.sources) {\n    _clsEntry.sources.forEach((source, index) =>\n      span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)),\n    );\n  }\n}\n\nfunction setResourceEntrySizeData(\n  attributes: SpanAttributes,\n  entry: PerformanceResourceTiming,\n  key: keyof Pick<PerformanceResourceTiming, 'transferSize' | 'encodedBodySize' | 'decodedBodySize'>,\n  dataKey: 'http.response_transfer_size' | 'http.response_content_length' | 'http.decoded_response_content_length',\n): void {\n  const entryVal = entry[key];\n  if (entryVal != null && entryVal < MAX_INT_AS_BYTES) {\n    attributes[dataKey] = entryVal;\n  }\n}\n\n/**\n * Add ttfb request time information to measurements.\n *\n * ttfb information is added via vendored web vitals library.\n */\nfunction _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void {\n  const navEntry = getNavigationEntry(false);\n  if (!navEntry) {\n    return;\n  }\n\n  const { responseStart, requestStart } = navEntry;\n\n  if (requestStart <= responseStart) {\n    _measurements['ttfb.requestTime'] = {\n      value: responseStart - requestStart,\n      unit: 'millisecond',\n    };\n  }\n}\n", "import type { HandlerDataDom } from '@sentry/core';\nimport { addHandler, addNonEnumerableProperty, fill, maybeInstrument, triggerHandlers, uuid4 } from '@sentry/core';\nimport { WINDOW } from '../types';\n\ntype SentryWrappedTarget = HTMLElement & { _sentryId?: string };\n\ntype AddEventListener = (\n  type: string,\n  listener: EventListenerOrEventListenerObject,\n  options?: boolean | AddEventListenerOptions,\n) => void;\ntype RemoveEventListener = (\n  type: string,\n  listener: EventListenerOrEventListenerObject,\n  options?: boolean | EventListenerOptions,\n) => void;\n\ntype InstrumentedElement = Element & {\n  __sentry_instrumentation_handlers__?: {\n    [key in 'click' | 'keypress']?: {\n      handler?: unknown;\n      /** The number of custom listeners attached to this element */\n      refCount: number;\n    };\n  };\n};\n\nconst DEBOUNCE_DURATION = 1000;\n\nlet debounceTimerID: number | undefined;\nlet lastCapturedEventType: string | undefined;\nlet lastCapturedEventTargetId: string | undefined;\n\n/**\n * Add an instrumentation handler for when a click or a keypress happens.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addClickKeypressInstrumentationHandler(handler: (data: HandlerDataDom) => void): void {\n  const type = 'dom';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentDOM);\n}\n\n/** Exported for tests only. */\nexport function instrumentDOM(): void {\n  if (!WINDOW.document) {\n    return;\n  }\n\n  // Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom\n  // handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before\n  // we instrument `addEventListener` so that we don't end up attaching this handler twice.\n  const triggerDOMHandler = triggerHandlers.bind(null, 'dom');\n  const globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true);\n  WINDOW.document.addEventListener('click', globalDOMEventHandler, false);\n  WINDOW.document.addEventListener('keypress', globalDOMEventHandler, false);\n\n  // After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled\n  // clicks & keypresses, by adding an event listener of our own to any element to which they add a listener. That\n  // way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler\n  // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still\n  // guaranteed to fire at least once.)\n  ['EventTarget', 'Node'].forEach((target: string) => {\n    const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;\n    const targetObj = globalObject[target];\n    const proto = targetObj && targetObj.prototype;\n\n    // eslint-disable-next-line no-prototype-builtins\n    if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {\n      return;\n    }\n\n    fill(proto, 'addEventListener', function (originalAddEventListener: AddEventListener): AddEventListener {\n      return function (this: InstrumentedElement, type, listener, options): AddEventListener {\n        if (type === 'click' || type == 'keypress') {\n          try {\n            const handlers = (this.__sentry_instrumentation_handlers__ =\n              this.__sentry_instrumentation_handlers__ || {});\n            const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 });\n\n            if (!handlerForType.handler) {\n              const handler = makeDOMEventHandler(triggerDOMHandler);\n              handlerForType.handler = handler;\n              originalAddEventListener.call(this, type, handler, options);\n            }\n\n            handlerForType.refCount++;\n          } catch (e) {\n            // Accessing dom properties is always fragile.\n            // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n          }\n        }\n\n        return originalAddEventListener.call(this, type, listener, options);\n      };\n    });\n\n    fill(\n      proto,\n      'removeEventListener',\n      function (originalRemoveEventListener: RemoveEventListener): RemoveEventListener {\n        return function (this: InstrumentedElement, type, listener, options): () => void {\n          if (type === 'click' || type == 'keypress') {\n            try {\n              const handlers = this.__sentry_instrumentation_handlers__ || {};\n              const handlerForType = handlers[type];\n\n              if (handlerForType) {\n                handlerForType.refCount--;\n                // If there are no longer any custom handlers of the current type on this element, we can remove ours, too.\n                if (handlerForType.refCount <= 0) {\n                  originalRemoveEventListener.call(this, type, handlerForType.handler, options);\n                  handlerForType.handler = undefined;\n                  delete handlers[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete\n                }\n\n                // If there are no longer any custom handlers of any type on this element, cleanup everything.\n                if (Object.keys(handlers).length === 0) {\n                  delete this.__sentry_instrumentation_handlers__;\n                }\n              }\n            } catch (e) {\n              // Accessing dom properties is always fragile.\n              // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n            }\n          }\n\n          return originalRemoveEventListener.call(this, type, listener, options);\n        };\n      },\n    );\n  });\n}\n\n/**\n * Check whether the event is similar to the last captured one. For example, two click events on the same button.\n */\nfunction isSimilarToLastCapturedEvent(event: Event): boolean {\n  // If both events have different type, then user definitely performed two separate actions. e.g. click + keypress.\n  if (event.type !== lastCapturedEventType) {\n    return false;\n  }\n\n  try {\n    // If both events have the same type, it's still possible that actions were performed on different targets.\n    // e.g. 2 clicks on different buttons.\n    if (!event.target || (event.target as SentryWrappedTarget)._sentryId !== lastCapturedEventTargetId) {\n      return false;\n    }\n  } catch (e) {\n    // just accessing `target` property can throw an exception in some rare circumstances\n    // see: https://github.com/getsentry/sentry-javascript/issues/838\n  }\n\n  // If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_\n  // to which an event listener was attached), we treat them as the same action, as we want to capture\n  // only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box.\n  return true;\n}\n\n/**\n * Decide whether an event should be captured.\n * @param event event to be captured\n */\nfunction shouldSkipDOMEvent(eventType: string, target: SentryWrappedTarget | null): boolean {\n  // We are only interested in filtering `keypress` events for now.\n  if (eventType !== 'keypress') {\n    return false;\n  }\n\n  if (!target || !target.tagName) {\n    return true;\n  }\n\n  // Only consider keypress events on actual input elements. This will disregard keypresses targeting body\n  // e.g.tabbing through elements, hotkeys, etc.\n  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Wraps addEventListener to capture UI breadcrumbs\n */\nfunction makeDOMEventHandler(\n  handler: (data: HandlerDataDom) => void,\n  globalListener: boolean = false,\n): (event: Event) => void {\n  return (event: Event & { _sentryCaptured?: true }): void => {\n    // It's possible this handler might trigger multiple times for the same\n    // event (e.g. event propagation through node ancestors).\n    // Ignore if we've already captured that event.\n    if (!event || event['_sentryCaptured']) {\n      return;\n    }\n\n    const target = getEventTarget(event);\n\n    // We always want to skip _some_ events.\n    if (shouldSkipDOMEvent(event.type, target)) {\n      return;\n    }\n\n    // Mark event as \"seen\"\n    addNonEnumerableProperty(event, '_sentryCaptured', true);\n\n    if (target && !target._sentryId) {\n      // Add UUID to event target so we can identify if\n      addNonEnumerableProperty(target, '_sentryId', uuid4());\n    }\n\n    const name = event.type === 'keypress' ? 'input' : event.type;\n\n    // If there is no last captured event, it means that we can safely capture the new event and store it for future comparisons.\n    // If there is a last captured event, see if the new event is different enough to treat it as a unique one.\n    // If that's the case, emit the previous event and store locally the newly-captured DOM event.\n    if (!isSimilarToLastCapturedEvent(event)) {\n      const handlerData: HandlerDataDom = { event, name, global: globalListener };\n      handler(handlerData);\n      lastCapturedEventType = event.type;\n      lastCapturedEventTargetId = target ? target._sentryId : undefined;\n    }\n\n    // Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together.\n    clearTimeout(debounceTimerID);\n    debounceTimerID = WINDOW.setTimeout(() => {\n      lastCapturedEventTargetId = undefined;\n      lastCapturedEventType = undefined;\n    }, DEBOUNCE_DURATION);\n  };\n}\n\nfunction getEventTarget(event: Event): SentryWrappedTarget | null {\n  try {\n    return event.target as SentryWrappedTarget | null;\n  } catch (e) {\n    // just accessing `target` property can throw an exception in some rare circumstances\n    // see: https://github.com/getsentry/sentry-javascript/issues/838\n    return null;\n  }\n}\n", "import { addHandler, fill, maybeInstrument, supportsHistory, triggerHandlers } from '@sentry/core';\nimport type { HandlerDataHistory } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nlet lastHref: string | undefined;\n\n/**\n * Add an instrumentation handler for when a fetch request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addHistoryInstrumentationHandler(handler: (data: HandlerDataHistory) => void): void {\n  const type = 'history';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentHistory);\n}\n\nfunction instrumentHistory(): void {\n  if (!supportsHistory()) {\n    return;\n  }\n\n  const oldOnPopState = WINDOW.onpopstate;\n  WINDOW.onpopstate = function (this: WindowEventHandlers, ...args: unknown[]) {\n    const to = WINDOW.location.href;\n    // keep track of the current URL state, as we always receive only the updated state\n    const from = lastHref;\n    lastHref = to;\n    const handlerData: HandlerDataHistory = { from, to };\n    triggerHandlers('history', handlerData);\n    if (oldOnPopState) {\n      // Apparently this can throw in Firefox when incorrectly implemented plugin is installed.\n      // https://github.com/getsentry/sentry-javascript/issues/3344\n      // https://github.com/bugsnag/bugsnag-js/issues/469\n      try {\n        return oldOnPopState.apply(this, args);\n      } catch (_oO) {\n        // no-empty\n      }\n    }\n  };\n\n  function historyReplacementFunction(originalHistoryFunction: () => void): () => void {\n    return function (this: History, ...args: unknown[]): void {\n      const url = args.length > 2 ? args[2] : undefined;\n      if (url) {\n        // coerce to string (this is what pushState does)\n        const from = lastHref;\n        const to = String(url);\n        // keep track of the current URL state, as we always receive only the updated state\n        lastHref = to;\n        const handlerData: HandlerDataHistory = { from, to };\n        triggerHandlers('history', handlerData);\n      }\n      return originalHistoryFunction.apply(this, args);\n    };\n  }\n\n  fill(WINDOW.history, 'pushState', historyReplacementFunction);\n  fill(WINDOW.history, 'replaceState', historyReplacementFunction);\n}\n", "import { isNativeFunction, logger } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\nimport { WINDOW } from './types';\n\n/**\n * We generally want to use window.fetch / window.setTimeout.\n * However, in some cases this may be wrapped (e.g. by Zone.js for Angular),\n * so we try to get an unpatched version of this from a sandboxed iframe.\n */\n\ninterface CacheableImplementations {\n  setTimeout: typeof WINDOW.setTimeout;\n  fetch: typeof WINDOW.fetch;\n}\n\nconst cachedImplementations: Partial<CacheableImplementations> = {};\n\n/**\n * Get the native implementation of a browser function.\n *\n * This can be used to ensure we get an unwrapped version of a function, in cases where a wrapped function can lead to problems.\n *\n * The following methods can be retrieved:\n * - `setTimeout`: This can be wrapped by e.g. Angular, causing change detection to be triggered.\n * - `fetch`: This can be wrapped by e.g. ad-blockers, causing an infinite loop when a request is blocked.\n */\nexport function getNativeImplementation<T extends keyof CacheableImplementations>(\n  name: T,\n): CacheableImplementations[T] {\n  const cached = cachedImplementations[name];\n  if (cached) {\n    return cached;\n  }\n\n  let impl = WINDOW[name] as CacheableImplementations[T];\n\n  // Fast path to avoid DOM I/O\n  if (isNativeFunction(impl)) {\n    return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]);\n  }\n\n  const document = WINDOW.document;\n  // eslint-disable-next-line deprecation/deprecation\n  if (document && typeof document.createElement === 'function') {\n    try {\n      const sandbox = document.createElement('iframe');\n      sandbox.hidden = true;\n      document.head.appendChild(sandbox);\n      const contentWindow = sandbox.contentWindow;\n      if (contentWindow && contentWindow[name]) {\n        impl = contentWindow[name] as CacheableImplementations[T];\n      }\n      document.head.removeChild(sandbox);\n    } catch (e) {\n      // Could not create sandbox iframe, just use window.xxx\n      DEBUG_BUILD && logger.warn(`Could not create sandbox iframe for ${name} check, bailing to window.${name}: `, e);\n    }\n  }\n\n  // Sanity check: This _should_ not happen, but if it does, we just skip caching...\n  // This can happen e.g. in tests where fetch may not be available in the env, or similar.\n  if (!impl) {\n    return impl;\n  }\n\n  return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]);\n}\n\n/** Clear a cached implementation. */\nexport function clearCachedImplementation(name: keyof CacheableImplementations): void {\n  cachedImplementations[name] = undefined;\n}\n\n/**\n * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers.\n * Whenever someone wraps the Fetch API and returns the wrong promise chain,\n * this chain becomes orphaned and there is no possible way to capture it's rejections\n * other than allowing it bubble up to this very handler. eg.\n *\n * const f = window.fetch;\n * window.fetch = function () {\n *   const p = f.apply(this, arguments);\n *\n *   p.then(function() {\n *     console.log('hi.');\n *   });\n *\n *   return p;\n * }\n *\n * `p.then(function () { ... })` is producing a completely separate promise chain,\n * however, what's returned is `p` - the result of original `fetch` call.\n *\n * This mean, that whenever we use the Fetch API to send our own requests, _and_\n * some ad-blocker blocks it, this orphaned chain will _always_ reject,\n * effectively causing another event to be captured.\n * This makes a whole process become an infinite loop, which we need to somehow\n * deal with, and break it in one way or another.\n *\n * To deal with this issue, we are making sure that we _always_ use the real\n * browser Fetch API, instead of relying on what `window.fetch` exposes.\n * The only downside to this would be missing our own requests as breadcrumbs,\n * but because we are already not doing this, it should be just fine.\n *\n * Possible failed fetch error messages per-browser:\n *\n * Chrome:  Failed to fetch\n * Edge:    Failed to Fetch\n * Firefox: NetworkError when attempting to fetch resource\n * Safari:  resource blocked by content blocker\n */\nexport function fetch(...rest: Parameters<typeof WINDOW.fetch>): ReturnType<typeof WINDOW.fetch> {\n  return getNativeImplementation('fetch')(...rest);\n}\n\n/**\n * Get an unwrapped `setTimeout` method.\n * This ensures that even if e.g. Angular wraps `setTimeout`, we get the native implementation,\n * avoiding triggering change detection.\n */\nexport function setTimeout(...rest: Parameters<typeof WINDOW.setTimeout>): ReturnType<typeof WINDOW.setTimeout> {\n  return getNativeImplementation('setTimeout')(...rest);\n}\n", "import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/core';\nimport { addHandler, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nexport const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';\n\ntype WindowWithXhr = Window & { XMLHttpRequest?: typeof XMLHttpRequest };\n\n/**\n * Add an instrumentation handler for when an XHR request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addXhrInstrumentationHandler(handler: (data: HandlerDataXhr) => void): void {\n  const type = 'xhr';\n  addHandler(type, handler);\n  maybeInstrument(type, instrumentXHR);\n}\n\n/** Exported only for tests. */\nexport function instrumentXHR(): void {\n  if (!(WINDOW as WindowWithXhr).XMLHttpRequest) {\n    return;\n  }\n\n  const xhrproto = XMLHttpRequest.prototype;\n\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  xhrproto.open = new Proxy(xhrproto.open, {\n    apply(originalOpen, xhrOpenThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest, xhrOpenArgArray) {\n      // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n      //       it means the error, that was caused by your XHR call did not\n      //       have a stack trace. If you are using HttpClient integration,\n      //       this is the expected behavior, as we are using this virtual error to capture\n      //       the location of your XHR call, and group your HttpClient events accordingly.\n      const virtualError = new Error();\n\n      const startTimestamp = timestampInSeconds() * 1000;\n\n      // open() should always be called with two or more arguments\n      // But to be on the safe side, we actually validate this and bail out if we don't have a method & url\n      const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : undefined;\n      const url = parseUrl(xhrOpenArgArray[1]);\n\n      if (!method || !url) {\n        return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n      }\n\n      xhrOpenThisArg[SENTRY_XHR_DATA_KEY] = {\n        method,\n        url,\n        request_headers: {},\n      };\n\n      // if Sentry key appears in URL, don't capture it as a request\n      if (method === 'POST' && url.match(/sentry_key/)) {\n        xhrOpenThisArg.__sentry_own_request__ = true;\n      }\n\n      const onreadystatechangeHandler: () => void = () => {\n        // For whatever reason, this is not the same instance here as from the outer method\n        const xhrInfo = xhrOpenThisArg[SENTRY_XHR_DATA_KEY];\n\n        if (!xhrInfo) {\n          return;\n        }\n\n        if (xhrOpenThisArg.readyState === 4) {\n          try {\n            // touching statusCode in some platforms throws\n            // an exception\n            xhrInfo.status_code = xhrOpenThisArg.status;\n          } catch (e) {\n            /* do nothing */\n          }\n\n          const handlerData: HandlerDataXhr = {\n            endTimestamp: timestampInSeconds() * 1000,\n            startTimestamp,\n            xhr: xhrOpenThisArg,\n            virtualError,\n          };\n          triggerHandlers('xhr', handlerData);\n        }\n      };\n\n      if ('onreadystatechange' in xhrOpenThisArg && typeof xhrOpenThisArg.onreadystatechange === 'function') {\n        xhrOpenThisArg.onreadystatechange = new Proxy(xhrOpenThisArg.onreadystatechange, {\n          apply(originalOnreadystatechange, onreadystatechangeThisArg, onreadystatechangeArgArray: unknown[]) {\n            onreadystatechangeHandler();\n            return originalOnreadystatechange.apply(onreadystatechangeThisArg, onreadystatechangeArgArray);\n          },\n        });\n      } else {\n        xhrOpenThisArg.addEventListener('readystatechange', onreadystatechangeHandler);\n      }\n\n      // Intercepting `setRequestHeader` to access the request headers of XHR instance.\n      // This will only work for user/library defined headers, not for the default/browser-assigned headers.\n      // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.\n      xhrOpenThisArg.setRequestHeader = new Proxy(xhrOpenThisArg.setRequestHeader, {\n        apply(\n          originalSetRequestHeader,\n          setRequestHeaderThisArg: SentryWrappedXMLHttpRequest,\n          setRequestHeaderArgArray: unknown[],\n        ) {\n          const [header, value] = setRequestHeaderArgArray;\n\n          const xhrInfo = setRequestHeaderThisArg[SENTRY_XHR_DATA_KEY];\n\n          if (xhrInfo && isString(header) && isString(value)) {\n            xhrInfo.request_headers[header.toLowerCase()] = value;\n          }\n\n          return originalSetRequestHeader.apply(setRequestHeaderThisArg, setRequestHeaderArgArray);\n        },\n      });\n\n      return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n    },\n  });\n\n  // eslint-disable-next-line @typescript-eslint/unbound-method\n  xhrproto.send = new Proxy(xhrproto.send, {\n    apply(originalSend, sendThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest, sendArgArray: unknown[]) {\n      const sentryXhrData = sendThisArg[SENTRY_XHR_DATA_KEY];\n\n      if (!sentryXhrData) {\n        return originalSend.apply(sendThisArg, sendArgArray);\n      }\n\n      if (sendArgArray[0] !== undefined) {\n        sentryXhrData.body = sendArgArray[0];\n      }\n\n      const handlerData: HandlerDataXhr = {\n        startTimestamp: timestampInSeconds() * 1000,\n        xhr: sendThisArg,\n      };\n      triggerHandlers('xhr', handlerData);\n\n      return originalSend.apply(sendThisArg, sendArgArray);\n    },\n  });\n}\n\nfunction parseUrl(url: string | unknown): string | undefined {\n  if (isString(url)) {\n    return url;\n  }\n\n  try {\n    // url can be a string or URL\n    // but since URL is not available in IE11, we do not check for it,\n    // but simply assume it is an URL and return `toString()` from it (which returns the full URL)\n    // If that fails, we just return undefined\n    return (url as URL).toString();\n  } catch {} // eslint-disable-line no-empty\n\n  return undefined;\n}\n", "import type { Span, SpanAttributes } from '@sentry/core';\nimport {\n  SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT,\n  SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE,\n  SEMANTIC_ATTRIBUTE_SENTRY_OP,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  browserPerformanceTimeOrigin,\n  dropUndefinedKeys,\n  getActiveSpan,\n  getCurrentScope,\n  getRootSpan,\n  htmlTreeAsString,\n  spanToJSON,\n} from '@sentry/core';\nimport {\n  addInpInstrumentationHandler,\n  addPerformanceInstrumentationHandler,\n  isPerformanceEventTiming,\n} from './instrument';\nimport { getBrowserPerformanceAPI, msToSec, startStandaloneWebVitalSpan } from './utils';\n\nconst LAST_INTERACTIONS: number[] = [];\nconst INTERACTIONS_SPAN_MAP = new Map<number, Span>();\n\n/**\n * Start tracking INP webvital events.\n */\nexport function startTrackingINP(): () => void {\n  const performance = getBrowserPerformanceAPI();\n  if (performance && browserPerformanceTimeOrigin) {\n    const inpCallback = _trackINP();\n\n    return (): void => {\n      inpCallback();\n    };\n  }\n\n  return () => undefined;\n}\n\nconst INP_ENTRY_MAP: Record<string, 'click' | 'hover' | 'drag' | 'press'> = {\n  click: 'click',\n  pointerdown: 'click',\n  pointerup: 'click',\n  mousedown: 'click',\n  mouseup: 'click',\n  touchstart: 'click',\n  touchend: 'click',\n  mouseover: 'hover',\n  mouseout: 'hover',\n  mouseenter: 'hover',\n  mouseleave: 'hover',\n  pointerover: 'hover',\n  pointerout: 'hover',\n  pointerenter: 'hover',\n  pointerleave: 'hover',\n  dragstart: 'drag',\n  dragend: 'drag',\n  drag: 'drag',\n  dragenter: 'drag',\n  dragleave: 'drag',\n  dragover: 'drag',\n  drop: 'drag',\n  keydown: 'press',\n  keyup: 'press',\n  keypress: 'press',\n  input: 'press',\n};\n\n/** Starts tracking the Interaction to Next Paint on the current page. */\nfunction _trackINP(): () => void {\n  return addInpInstrumentationHandler(({ metric }) => {\n    if (metric.value == undefined) {\n      return;\n    }\n\n    const entry = metric.entries.find(entry => entry.duration === metric.value && INP_ENTRY_MAP[entry.name]);\n\n    if (!entry) {\n      return;\n    }\n\n    const { interactionId } = entry;\n    const interactionType = INP_ENTRY_MAP[entry.name];\n\n    /** Build the INP span, create an envelope from the span, and then send the envelope */\n    const startTime = msToSec((browserPerformanceTimeOrigin as number) + entry.startTime);\n    const duration = msToSec(metric.value);\n    const activeSpan = getActiveSpan();\n    const rootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;\n\n    // We first try to lookup the span from our INTERACTIONS_SPAN_MAP,\n    // where we cache the route per interactionId\n    const cachedSpan = interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : undefined;\n\n    const spanToUse = cachedSpan || rootSpan;\n\n    // Else, we try to use the active span.\n    // Finally, we fall back to look at the transactionName on the scope\n    const routeName = spanToUse ? spanToJSON(spanToUse).description : getCurrentScope().getScopeData().transactionName;\n\n    const name = htmlTreeAsString(entry.target);\n    const attributes: SpanAttributes = dropUndefinedKeys({\n      [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser.inp',\n      [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `ui.interaction.${interactionType}`,\n      [SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME]: entry.duration,\n    });\n\n    const span = startStandaloneWebVitalSpan({\n      name,\n      transaction: routeName,\n      attributes,\n      startTime,\n    });\n\n    if (span) {\n      span.addEvent('inp', {\n        [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT]: 'millisecond',\n        [SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE]: metric.value,\n      });\n\n      span.end(startTime + duration);\n    }\n  });\n}\n\n/**\n * Register a listener to cache route information for INP interactions.\n * TODO(v9): `latestRoute` no longer needs to be passed in and will be removed in v9.\n */\nexport function registerInpInteractionListener(_latestRoute?: unknown): void {\n  const handleEntries = ({ entries }: { entries: PerformanceEntry[] }): void => {\n    const activeSpan = getActiveSpan();\n    const activeRootSpan = activeSpan && getRootSpan(activeSpan);\n\n    entries.forEach(entry => {\n      if (!isPerformanceEventTiming(entry) || !activeRootSpan) {\n        return;\n      }\n\n      const interactionId = entry.interactionId;\n      if (interactionId == null) {\n        return;\n      }\n\n      // If the interaction was already recorded before, nothing more to do\n      if (INTERACTIONS_SPAN_MAP.has(interactionId)) {\n        return;\n      }\n\n      // We keep max. 10 interactions in the list, then remove the oldest one & clean up\n      if (LAST_INTERACTIONS.length > 10) {\n        const last = LAST_INTERACTIONS.shift() as number;\n        INTERACTIONS_SPAN_MAP.delete(last);\n      }\n\n      // We add the interaction to the list of recorded interactions\n      // and store the span for this interaction\n      LAST_INTERACTIONS.push(interactionId);\n      INTERACTIONS_SPAN_MAP.set(interactionId, activeRootSpan);\n    });\n  };\n\n  addPerformanceInstrumentationHandler('event', handleEntries);\n  addPerformanceInstrumentationHandler('first-input', handleEntries);\n}\n", "import { clearCachedImplementation, getNativeImplementation } from '@sentry-internal/browser-utils';\nimport type { Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core';\nimport { createTransport, rejectedSyncPromise } from '@sentry/core';\nimport type { WINDOW } from '../helpers';\nimport type { BrowserTransportOptions } from './types';\n\n/**\n * Creates a Transport that uses the Fetch API to send events to Sentry.\n */\nexport function makeFetchTransport(\n  options: BrowserTransportOptions,\n  nativeFetch: typeof WINDOW.fetch | undefined = getNativeImplementation('fetch'),\n): Transport {\n  let pendingBodySize = 0;\n  let pendingCount = 0;\n\n  function makeRequest(request: TransportRequest): PromiseLike<TransportMakeRequestResponse> {\n    const requestSize = request.body.length;\n    pendingBodySize += requestSize;\n    pendingCount++;\n\n    const requestOptions: RequestInit = {\n      body: request.body,\n      method: 'POST',\n      referrerPolicy: 'origin',\n      headers: options.headers,\n      // Outgoing requests are usually cancelled when navigating to a different page, causing a \"TypeError: Failed to\n      // fetch\" error and sending a \"network_error\" client-outcome - in Chrome, the request status shows \"(cancelled)\".\n      // The `keepalive` flag keeps outgoing requests alive, even when switching pages. We want this since we're\n      // frequently sending events right before the user is switching pages (eg. when finishing navigation transactions).\n      // Gotchas:\n      // - `keepalive` isn't supported by Firefox\n      // - As per spec (https://fetch.spec.whatwg.org/#http-network-or-cache-fetch):\n      //   If the sum of contentLength and inflightKeepaliveBytes is greater than 64 kibibytes, then return a network error.\n      //   We will therefore only activate the flag when we're below that limit.\n      // There is also a limit of requests that can be open at the same time, so we also limit this to 15\n      // See https://github.com/getsentry/sentry-javascript/pull/7553 for details\n      keepalive: pendingBodySize <= 60_000 && pendingCount < 15,\n      ...options.fetchOptions,\n    };\n\n    if (!nativeFetch) {\n      clearCachedImplementation('fetch');\n      return rejectedSyncPromise('No fetch implementation available');\n    }\n\n    try {\n      // TODO: This may need a `suppressTracing` call in the future when we switch the browser SDK to OTEL\n      return nativeFetch(options.url, requestOptions).then(response => {\n        pendingBodySize -= requestSize;\n        pendingCount--;\n        return {\n          statusCode: response.status,\n          headers: {\n            'x-sentry-rate-limits': response.headers.get('X-Sentry-Rate-Limits'),\n            'retry-after': response.headers.get('Retry-After'),\n          },\n        };\n      });\n    } catch (e) {\n      clearCachedImplementation('fetch');\n      pendingBodySize -= requestSize;\n      pendingCount--;\n      return rejectedSyncPromise(e);\n    }\n  }\n\n  return createTransport(options, makeRequest);\n}\n", "// This was originally forked from https://github.com/csnover/TraceKit, and was largely\n// re - written as part of raven - js.\n//\n// This code was later copied to the JavaScript mono - repo and further modified and\n// refactored over the years.\n\n// Copyright (c) 2013 Onur Can Cakmak onur.cakmak@gmail.com and all TraceKit contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this\n// software and associated documentation files(the 'Software'), to deal in the Software\n// without restriction, including without limitation the rights to use, copy, modify,\n// merge, publish, distribute, sublicense, and / or sell copies of the Software, and to\n// permit persons to whom the Software is furnished to do so, subject to the following\n// conditions:\n//\n// The above copyright notice and this permission notice shall be included in all copies\n// or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n// PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\n// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE\n// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nimport { UNKNOWN_FUNCTION, createStackParser } from '@sentry/core';\nimport type { StackFrame, StackLineParser, StackLineParserFn } from '@sentry/core';\n\nconst OPERA10_PRIORITY = 10;\nconst OPERA11_PRIORITY = 20;\nconst CHROME_PRIORITY = 30;\nconst WINJS_PRIORITY = 40;\nconst GECKO_PRIORITY = 50;\n\nfunction createFrame(filename: string, func: string, lineno?: number, colno?: number): StackFrame {\n  const frame: StackFrame = {\n    filename,\n    function: func === '<anonymous>' ? UNKNOWN_FUNCTION : func,\n    in_app: true, // All browser frames are considered in_app\n  };\n\n  if (lineno !== undefined) {\n    frame.lineno = lineno;\n  }\n\n  if (colno !== undefined) {\n    frame.colno = colno;\n  }\n\n  return frame;\n}\n\n// This regex matches frames that have no function name (ie. are at the top level of a module).\n// For example \"at http://localhost:5000//script.js:1:126\"\n// Frames _with_ function names usually look as follows: \"at commitLayoutEffects (react-dom.development.js:23426:1)\"\nconst chromeRegexNoFnName = /^\\s*at (\\S+?)(?::(\\d+))(?::(\\d+))\\s*$/i;\n\n// This regex matches all the frames that have a function name.\nconst chromeRegex =\n  /^\\s*at (?:(.+?\\)(?: \\[.+\\])?|.*?) ?\\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\\/)?.*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\n\nconst chromeEvalRegex = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\n\n// Chromium based browsers: Chrome, Brave, new Opera, new Edge\n// We cannot call this variable `chrome` because it can conflict with global `chrome` variable in certain environments\n// See: https://github.com/getsentry/sentry-javascript/issues/6880\nconst chromeStackParserFn: StackLineParserFn = line => {\n  // If the stack line has no function name, we need to parse it differently\n  const noFnParts = chromeRegexNoFnName.exec(line) as null | [string, string, string, string];\n\n  if (noFnParts) {\n    const [, filename, line, col] = noFnParts;\n    return createFrame(filename, UNKNOWN_FUNCTION, +line, +col);\n  }\n\n  const parts = chromeRegex.exec(line) as null | [string, string, string, string, string];\n\n  if (parts) {\n    const isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line\n\n    if (isEval) {\n      const subMatch = chromeEvalRegex.exec(parts[2]) as null | [string, string, string, string];\n\n      if (subMatch) {\n        // throw out eval line/column and use top-most line/column number\n        parts[2] = subMatch[1]; // url\n        parts[3] = subMatch[2]; // line\n        parts[4] = subMatch[3]; // column\n      }\n    }\n\n    // Kamil: One more hack won't hurt us right? Understanding and adding more rules on top of these regexps right now\n    // would be way too time consuming. (TODO: Rewrite whole RegExp to be more readable)\n    const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);\n\n    return createFrame(filename, func, parts[3] ? +parts[3] : undefined, parts[4] ? +parts[4] : undefined);\n  }\n\n  return;\n};\n\nexport const chromeStackLineParser: StackLineParser = [CHROME_PRIORITY, chromeStackParserFn];\n\n// gecko regex: `(?:bundle|\\d+\\.js)`: `bundle` is for react native, `\\d+\\.js` also but specifically for ram bundles because it\n// generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js\n// We need this specific case for now because we want no other regex to match.\nconst geckoREgex =\n  /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)?((?:[-a-z]+)?:\\/.*?|\\[native code\\]|[^@]*(?:bundle|\\d+\\.js)|\\/[\\w\\-. /=]+)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nconst geckoEvalRegex = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\n\nconst gecko: StackLineParserFn = line => {\n  const parts = geckoREgex.exec(line) as null | [string, string, string, string, string, string];\n\n  if (parts) {\n    const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n    if (isEval) {\n      const subMatch = geckoEvalRegex.exec(parts[3]) as null | [string, string, string];\n\n      if (subMatch) {\n        // throw out eval line/column and use top-most line number\n        parts[1] = parts[1] || 'eval';\n        parts[3] = subMatch[1];\n        parts[4] = subMatch[2];\n        parts[5] = ''; // no column when eval\n      }\n    }\n\n    let filename = parts[3];\n    let func = parts[1] || UNKNOWN_FUNCTION;\n    [func, filename] = extractSafariExtensionDetails(func, filename);\n\n    return createFrame(filename, func, parts[4] ? +parts[4] : undefined, parts[5] ? +parts[5] : undefined);\n  }\n\n  return;\n};\n\nexport const geckoStackLineParser: StackLineParser = [GECKO_PRIORITY, gecko];\n\nconst winjsRegex = /^\\s*at (?:((?:\\[object object\\])?.+) )?\\(?((?:[-a-z]+):.*?):(\\d+)(?::(\\d+))?\\)?\\s*$/i;\n\nconst winjs: StackLineParserFn = line => {\n  const parts = winjsRegex.exec(line) as null | [string, string, string, string, string];\n\n  return parts\n    ? createFrame(parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined)\n    : undefined;\n};\n\nexport const winjsStackLineParser: StackLineParser = [WINJS_PRIORITY, winjs];\n\nconst opera10Regex = / line (\\d+).*script (?:in )?(\\S+)(?:: in function (\\S+))?$/i;\n\nconst opera10: StackLineParserFn = line => {\n  const parts = opera10Regex.exec(line) as null | [string, string, string, string];\n  return parts ? createFrame(parts[2], parts[3] || UNKNOWN_FUNCTION, +parts[1]) : undefined;\n};\n\nexport const opera10StackLineParser: StackLineParser = [OPERA10_PRIORITY, opera10];\n\nconst opera11Regex =\n  / line (\\d+), column (\\d+)\\s*(?:in (?:<anonymous function: ([^>]+)>|([^)]+))\\(.*\\))? in (.*):\\s*$/i;\n\nconst opera11: StackLineParserFn = line => {\n  const parts = opera11Regex.exec(line) as null | [string, string, string, string, string, string];\n  return parts ? createFrame(parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;\n};\n\nexport const opera11StackLineParser: StackLineParser = [OPERA11_PRIORITY, opera11];\n\nexport const defaultStackLineParsers = [chromeStackLineParser, geckoStackLineParser];\n\nexport const defaultStackParser = createStackParser(...defaultStackLineParsers);\n\n/**\n * Safari web extensions, starting version unknown, can produce \"frames-only\" stacktraces.\n * What it means, is that instead of format like:\n *\n * Error: wat\n *   at function@url:row:col\n *   at function@url:row:col\n *   at function@url:row:col\n *\n * it produces something like:\n *\n *   function@url:row:col\n *   function@url:row:col\n *   function@url:row:col\n *\n * Because of that, it won't be captured by `chrome` RegExp and will fall into `Gecko` branch.\n * This function is extracted so that we can use it in both places without duplicating the logic.\n * Unfortunately \"just\" changing RegExp is too complicated now and making it pass all tests\n * and fix this case seems like an impossible, or at least way too time-consuming task.\n */\nconst extractSafariExtensionDetails = (func: string, filename: string): [string, string] => {\n  const isSafariExtension = func.indexOf('safari-extension') !== -1;\n  const isSafariWebExtension = func.indexOf('safari-web-extension') !== -1;\n\n  return isSafariExtension || isSafariWebExtension\n    ? [\n        func.indexOf('@') !== -1 ? (func.split('@')[0] as string) : UNKNOWN_FUNCTION,\n        isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`,\n      ]\n    : [func, filename];\n};\n", "/* eslint-disable max-lines */\n\nimport {\n  SENTRY_XHR_DATA_KEY,\n  addClickKeypressInstrumentationHandler,\n  addHistoryInstrumentationHandler,\n  addXhrInstrumentationHandler,\n} from '@sentry-internal/browser-utils';\nimport type {\n  Breadcrumb,\n  Client,\n  Event as SentryEvent,\n  FetchBreadcrumbData,\n  FetchBreadcrumbHint,\n  HandlerDataConsole,\n  HandlerDataDom,\n  HandlerDataFetch,\n  HandlerDataHistory,\n  HandlerDataXhr,\n  IntegrationFn,\n  XhrBreadcrumbData,\n  XhrBreadcrumbHint,\n} from '@sentry/core';\nimport {\n  addBreadcrumb,\n  addConsoleInstrumentationHandler,\n  addFetchInstrumentationHandler,\n  defineIntegration,\n  getBreadcrumbLogLevelFromHttpStatusCode,\n  getClient,\n  getComponentName,\n  getEventDescription,\n  htmlTreeAsString,\n  logger,\n  parseUrl,\n  safeJoin,\n  severityLevelFromString,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\n\ninterface BreadcrumbsOptions {\n  console: boolean;\n  dom:\n    | boolean\n    | {\n        serializeAttribute?: string | string[];\n        maxStringLength?: number;\n      };\n  fetch: boolean;\n  history: boolean;\n  sentry: boolean;\n  xhr: boolean;\n}\n\n/** maxStringLength gets capped to prevent 100 breadcrumbs exceeding 1MB event payload size */\nconst MAX_ALLOWED_STRING_LENGTH = 1024;\n\nconst INTEGRATION_NAME = 'Breadcrumbs';\n\nconst _breadcrumbsIntegration = ((options: Partial<BreadcrumbsOptions> = {}) => {\n  const _options = {\n    console: true,\n    dom: true,\n    fetch: true,\n    history: true,\n    sentry: true,\n    xhr: true,\n    ...options,\n  };\n\n  return {\n    name: INTEGRATION_NAME,\n    setup(client) {\n      if (_options.console) {\n        addConsoleInstrumentationHandler(_getConsoleBreadcrumbHandler(client));\n      }\n      if (_options.dom) {\n        addClickKeypressInstrumentationHandler(_getDomBreadcrumbHandler(client, _options.dom));\n      }\n      if (_options.xhr) {\n        addXhrInstrumentationHandler(_getXhrBreadcrumbHandler(client));\n      }\n      if (_options.fetch) {\n        addFetchInstrumentationHandler(_getFetchBreadcrumbHandler(client));\n      }\n      if (_options.history) {\n        addHistoryInstrumentationHandler(_getHistoryBreadcrumbHandler(client));\n      }\n      if (_options.sentry) {\n        client.on('beforeSendEvent', _getSentryBreadcrumbHandler(client));\n      }\n    },\n  };\n}) satisfies IntegrationFn;\n\nexport const breadcrumbsIntegration = defineIntegration(_breadcrumbsIntegration);\n\n/**\n * Adds a breadcrumb for Sentry events or transactions if this option is enabled.\n */\nfunction _getSentryBreadcrumbHandler(client: Client): (event: SentryEvent) => void {\n  return function addSentryBreadcrumb(event: SentryEvent): void {\n    if (getClient() !== client) {\n      return;\n    }\n\n    addBreadcrumb(\n      {\n        category: `sentry.${event.type === 'transaction' ? 'transaction' : 'event'}`,\n        event_id: event.event_id,\n        level: event.level,\n        message: getEventDescription(event),\n      },\n      {\n        event,\n      },\n    );\n  };\n}\n\n/**\n * A HOC that creates a function that creates breadcrumbs from DOM API calls.\n * This is a HOC so that we get access to dom options in the closure.\n */\nfunction _getDomBreadcrumbHandler(\n  client: Client,\n  dom: BreadcrumbsOptions['dom'],\n): (handlerData: HandlerDataDom) => void {\n  return function _innerDomBreadcrumb(handlerData: HandlerDataDom): void {\n    if (getClient() !== client) {\n      return;\n    }\n\n    let target;\n    let componentName;\n    let keyAttrs = typeof dom === 'object' ? dom.serializeAttribute : undefined;\n\n    let maxStringLength =\n      typeof dom === 'object' && typeof dom.maxStringLength === 'number' ? dom.maxStringLength : undefined;\n    if (maxStringLength && maxStringLength > MAX_ALLOWED_STRING_LENGTH) {\n      DEBUG_BUILD &&\n        logger.warn(\n          `\\`dom.maxStringLength\\` cannot exceed ${MAX_ALLOWED_STRING_LENGTH}, but a value of ${maxStringLength} was configured. Sentry will use ${MAX_ALLOWED_STRING_LENGTH} instead.`,\n        );\n      maxStringLength = MAX_ALLOWED_STRING_LENGTH;\n    }\n\n    if (typeof keyAttrs === 'string') {\n      keyAttrs = [keyAttrs];\n    }\n\n    // Accessing event.target can throw (see getsentry/raven-js#838, #768)\n    try {\n      const event = handlerData.event as Event | Node;\n      const element = _isEvent(event) ? event.target : event;\n\n      target = htmlTreeAsString(element, { keyAttrs, maxStringLength });\n      componentName = getComponentName(element);\n    } catch (e) {\n      target = '<unknown>';\n    }\n\n    if (target.length === 0) {\n      return;\n    }\n\n    const breadcrumb: Breadcrumb = {\n      category: `ui.${handlerData.name}`,\n      message: target,\n    };\n\n    if (componentName) {\n      breadcrumb.data = { 'ui.component_name': componentName };\n    }\n\n    addBreadcrumb(breadcrumb, {\n      event: handlerData.event,\n      name: handlerData.name,\n      global: handlerData.global,\n    });\n  };\n}\n\n/**\n * Creates breadcrumbs from console API calls\n */\nfunction _getConsoleBreadcrumbHandler(client: Client): (handlerData: HandlerDataConsole) => void {\n  return function _consoleBreadcrumb(handlerData: HandlerDataConsole): void {\n    if (getClient() !== client) {\n      return;\n    }\n\n    const breadcrumb = {\n      category: 'console',\n      data: {\n        arguments: handlerData.args,\n        logger: 'console',\n      },\n      level: severityLevelFromString(handlerData.level),\n      message: safeJoin(handlerData.args, ' '),\n    };\n\n    if (handlerData.level === 'assert') {\n      if (handlerData.args[0] === false) {\n        breadcrumb.message = `Assertion failed: ${safeJoin(handlerData.args.slice(1), ' ') || 'console.assert'}`;\n        breadcrumb.data.arguments = handlerData.args.slice(1);\n      } else {\n        // Don't capture a breadcrumb for passed assertions\n        return;\n      }\n    }\n\n    addBreadcrumb(breadcrumb, {\n      input: handlerData.args,\n      level: handlerData.level,\n    });\n  };\n}\n\n/**\n * Creates breadcrumbs from XHR API calls\n */\nfunction _getXhrBreadcrumbHandler(client: Client): (handlerData: HandlerDataXhr) => void {\n  return function _xhrBreadcrumb(handlerData: HandlerDataXhr): void {\n    if (getClient() !== client) {\n      return;\n    }\n\n    const { startTimestamp, endTimestamp } = handlerData;\n\n    const sentryXhrData = handlerData.xhr[SENTRY_XHR_DATA_KEY];\n\n    // We only capture complete, non-sentry requests\n    if (!startTimestamp || !endTimestamp || !sentryXhrData) {\n      return;\n    }\n\n    const { method, url, status_code, body } = sentryXhrData;\n\n    const data: XhrBreadcrumbData = {\n      method,\n      url,\n      status_code,\n    };\n\n    const hint: XhrBreadcrumbHint = {\n      xhr: handlerData.xhr,\n      input: body,\n      startTimestamp,\n      endTimestamp,\n    };\n\n    const level = getBreadcrumbLogLevelFromHttpStatusCode(status_code);\n\n    addBreadcrumb(\n      {\n        category: 'xhr',\n        data,\n        type: 'http',\n        level,\n      },\n      hint,\n    );\n  };\n}\n\n/**\n * Creates breadcrumbs from fetch API calls\n */\nfunction _getFetchBreadcrumbHandler(client: Client): (handlerData: HandlerDataFetch) => void {\n  return function _fetchBreadcrumb(handlerData: HandlerDataFetch): void {\n    if (getClient() !== client) {\n      return;\n    }\n\n    const { startTimestamp, endTimestamp } = handlerData;\n\n    // We only capture complete fetch requests\n    if (!endTimestamp) {\n      return;\n    }\n\n    if (handlerData.fetchData.url.match(/sentry_key/) && handlerData.fetchData.method === 'POST') {\n      // We will not create breadcrumbs for fetch requests that contain `sentry_key` (internal sentry requests)\n      return;\n    }\n\n    if (handlerData.error) {\n      const data: FetchBreadcrumbData = handlerData.fetchData;\n      const hint: FetchBreadcrumbHint = {\n        data: handlerData.error,\n        input: handlerData.args,\n        startTimestamp,\n        endTimestamp,\n      };\n\n      addBreadcrumb(\n        {\n          category: 'fetch',\n          data,\n          level: 'error',\n          type: 'http',\n        },\n        hint,\n      );\n    } else {\n      const response = handlerData.response as Response | undefined;\n      const data: FetchBreadcrumbData = {\n        ...handlerData.fetchData,\n        status_code: response && response.status,\n      };\n      const hint: FetchBreadcrumbHint = {\n        input: handlerData.args,\n        response,\n        startTimestamp,\n        endTimestamp,\n      };\n      const level = getBreadcrumbLogLevelFromHttpStatusCode(data.status_code);\n\n      addBreadcrumb(\n        {\n          category: 'fetch',\n          data,\n          type: 'http',\n          level,\n        },\n        hint,\n      );\n    }\n  };\n}\n\n/**\n * Creates breadcrumbs from history API calls\n */\nfunction _getHistoryBreadcrumbHandler(client: Client): (handlerData: HandlerDataHistory) => void {\n  return function _historyBreadcrumb(handlerData: HandlerDataHistory): void {\n    if (getClient() !== client) {\n      return;\n    }\n\n    let from: string | undefined = handlerData.from;\n    let to: string | undefined = handlerData.to;\n    const parsedLoc = parseUrl(WINDOW.location.href);\n    let parsedFrom = from ? parseUrl(from) : undefined;\n    const parsedTo = parseUrl(to);\n\n    // Initial pushState doesn't provide `from` information\n    if (!parsedFrom || !parsedFrom.path) {\n      parsedFrom = parsedLoc;\n    }\n\n    // Use only the path component of the URL if the URL matches the current\n    // document (almost all the time when using pushState)\n    if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host) {\n      to = parsedTo.relative;\n    }\n    if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host) {\n      from = parsedFrom.relative;\n    }\n\n    addBreadcrumb({\n      category: 'navigation',\n      data: {\n        from,\n        to,\n      },\n    });\n  };\n}\n\nfunction _isEvent(event: unknown): event is Event {\n  return !!event && !!(event as Record<string, unknown>).target;\n}\n", "import type { IntegrationFn, WrappedFunction } from '@sentry/core';\nimport { defineIntegration, fill, getFunctionName, getOriginalFunction } from '@sentry/core';\n\nimport { WINDOW, wrap } from '../helpers';\n\nconst DEFAULT_EVENT_TARGET = [\n  'EventTarget',\n  'Window',\n  'Node',\n  'ApplicationCache',\n  'AudioTrackList',\n  'BroadcastChannel',\n  'ChannelMergerNode',\n  'CryptoOperation',\n  'EventSource',\n  'FileReader',\n  'HTMLUnknownElement',\n  'IDBDatabase',\n  'IDBRequest',\n  'IDBTransaction',\n  'KeyOperation',\n  'MediaController',\n  'MessagePort',\n  'ModalWindow',\n  'Notification',\n  'SVGElementInstance',\n  'Screen',\n  'SharedWorker',\n  'TextTrack',\n  'TextTrackCue',\n  'TextTrackList',\n  'WebSocket',\n  'WebSocketWorker',\n  'Worker',\n  'XMLHttpRequest',\n  'XMLHttpRequestEventTarget',\n  'XMLHttpRequestUpload',\n];\n\nconst INTEGRATION_NAME = 'BrowserApiErrors';\n\ntype XMLHttpRequestProp = 'onload' | 'onerror' | 'onprogress' | 'onreadystatechange';\n\ninterface BrowserApiErrorsOptions {\n  setTimeout: boolean;\n  setInterval: boolean;\n  requestAnimationFrame: boolean;\n  XMLHttpRequest: boolean;\n  eventTarget: boolean | string[];\n}\n\nconst _browserApiErrorsIntegration = ((options: Partial<BrowserApiErrorsOptions> = {}) => {\n  const _options = {\n    XMLHttpRequest: true,\n    eventTarget: true,\n    requestAnimationFrame: true,\n    setInterval: true,\n    setTimeout: true,\n    ...options,\n  };\n\n  return {\n    name: INTEGRATION_NAME,\n    // TODO: This currently only works for the first client this is setup\n    // We may want to adjust this to check for client etc.\n    setupOnce() {\n      if (_options.setTimeout) {\n        fill(WINDOW, 'setTimeout', _wrapTimeFunction);\n      }\n\n      if (_options.setInterval) {\n        fill(WINDOW, 'setInterval', _wrapTimeFunction);\n      }\n\n      if (_options.requestAnimationFrame) {\n        fill(WINDOW, 'requestAnimationFrame', _wrapRAF);\n      }\n\n      if (_options.XMLHttpRequest && 'XMLHttpRequest' in WINDOW) {\n        fill(XMLHttpRequest.prototype, 'send', _wrapXHR);\n      }\n\n      const eventTargetOption = _options.eventTarget;\n      if (eventTargetOption) {\n        const eventTarget = Array.isArray(eventTargetOption) ? eventTargetOption : DEFAULT_EVENT_TARGET;\n        eventTarget.forEach(_wrapEventTarget);\n      }\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Wrap timer functions and event targets to catch errors and provide better meta data.\n */\nexport const browserApiErrorsIntegration = defineIntegration(_browserApiErrorsIntegration);\n\nfunction _wrapTimeFunction(original: () => void): () => number {\n  return function (this: unknown, ...args: unknown[]): number {\n    const originalCallback = args[0];\n    args[0] = wrap(originalCallback, {\n      mechanism: {\n        data: { function: getFunctionName(original) },\n        handled: false,\n        type: 'instrument',\n      },\n    });\n    return original.apply(this, args);\n  };\n}\n\nfunction _wrapRAF(original: () => void): (callback: () => void) => unknown {\n  return function (this: unknown, callback: () => void): () => void {\n    return original.apply(this, [\n      wrap(callback, {\n        mechanism: {\n          data: {\n            function: 'requestAnimationFrame',\n            handler: getFunctionName(original),\n          },\n          handled: false,\n          type: 'instrument',\n        },\n      }),\n    ]);\n  };\n}\n\nfunction _wrapXHR(originalSend: () => void): () => void {\n  return function (this: XMLHttpRequest, ...args: unknown[]): void {\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    const xhr = this;\n    const xmlHttpRequestProps: XMLHttpRequestProp[] = ['onload', 'onerror', 'onprogress', 'onreadystatechange'];\n\n    xmlHttpRequestProps.forEach(prop => {\n      if (prop in xhr && typeof xhr[prop] === 'function') {\n        fill(xhr, prop, function (original) {\n          const wrapOptions = {\n            mechanism: {\n              data: {\n                function: prop,\n                handler: getFunctionName(original),\n              },\n              handled: false,\n              type: 'instrument',\n            },\n          };\n\n          // If Instrument integration has been called before BrowserApiErrors, get the name of original function\n          const originalFunction = getOriginalFunction(original);\n          if (originalFunction) {\n            wrapOptions.mechanism.data.handler = getFunctionName(originalFunction);\n          }\n\n          // Otherwise wrap directly\n          return wrap(original, wrapOptions);\n        });\n      }\n    });\n\n    return originalSend.apply(this, args);\n  };\n}\n\nfunction _wrapEventTarget(target: string): void {\n  const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;\n  const targetObj = globalObject[target];\n  const proto = targetObj && targetObj.prototype;\n\n  // eslint-disable-next-line no-prototype-builtins\n  if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {\n    return;\n  }\n\n  fill(proto, 'addEventListener', function (original: VoidFunction): (\n    ...args: Parameters<typeof WINDOW.addEventListener>\n  ) => ReturnType<typeof WINDOW.addEventListener> {\n    return function (this: unknown, eventName, fn, options): VoidFunction {\n      try {\n        if (isEventListenerObject(fn)) {\n          // ESlint disable explanation:\n          //  First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would\n          //  introduce a bug here, because bind returns a new function that doesn't have our\n          //  flags(like __sentry_original__) attached. `wrap` checks for those flags to avoid unnecessary wrapping.\n          //  Without those flags, every call to addEventListener wraps the function again, causing a memory leak.\n          // eslint-disable-next-line @typescript-eslint/unbound-method\n          fn.handleEvent = wrap(fn.handleEvent, {\n            mechanism: {\n              data: {\n                function: 'handleEvent',\n                handler: getFunctionName(fn),\n                target,\n              },\n              handled: false,\n              type: 'instrument',\n            },\n          });\n        }\n      } catch {\n        // can sometimes get 'Permission denied to access property \"handle Event'\n      }\n\n      return original.apply(this, [\n        eventName,\n        wrap(fn, {\n          mechanism: {\n            data: {\n              function: 'addEventListener',\n              handler: getFunctionName(fn),\n              target,\n            },\n            handled: false,\n            type: 'instrument',\n          },\n        }),\n        options,\n      ]);\n    };\n  });\n\n  fill(proto, 'removeEventListener', function (originalRemoveEventListener: VoidFunction): (\n    this: unknown,\n    ...args: Parameters<typeof WINDOW.removeEventListener>\n  ) => ReturnType<typeof WINDOW.removeEventListener> {\n    return function (this: unknown, eventName, fn, options): VoidFunction {\n      /**\n       * There are 2 possible scenarios here:\n       *\n       * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified\n       * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function\n       * as a pass-through, and call original `removeEventListener` with it.\n       *\n       * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using\n       * our wrapped version of `addEventListener`, which internally calls `wrap` helper.\n       * This helper \"wraps\" whole callback inside a try/catch statement, and attached appropriate metadata to it,\n       * in order for us to make a distinction between wrapped/non-wrapped functions possible.\n       * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.\n       *\n       * When someone adds a handler prior to initialization, and then do it again, but after,\n       * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible\n       * to get rid of the initial handler and it'd stick there forever.\n       */\n      try {\n        const originalEventHandler = (fn as WrappedFunction).__sentry_wrapped__;\n        if (originalEventHandler) {\n          originalRemoveEventListener.call(this, eventName, originalEventHandler, options);\n        }\n      } catch (e) {\n        // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments\n      }\n      return originalRemoveEventListener.call(this, eventName, fn, options);\n    };\n  });\n}\n\nfunction isEventListenerObject(obj: unknown): obj is EventListenerObject {\n  return typeof (obj as EventListenerObject).handleEvent === 'function';\n}\n", "import { addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils';\nimport { captureSession, defineIntegration, logger, startSession } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\n\n/**\n * When added, automatically creates sessions which allow you to track adoption and crashes (crash free rate) in your Releases in Sentry.\n * More information: https://docs.sentry.io/product/releases/health/\n *\n * Note: In order for session tracking to work, you need to set up Releases: https://docs.sentry.io/product/releases/\n */\nexport const browserSessionIntegration = defineIntegration(() => {\n  return {\n    name: 'BrowserSession',\n    setupOnce() {\n      if (typeof WINDOW.document === 'undefined') {\n        DEBUG_BUILD &&\n          logger.warn('Using the `browserSessionIntegration` in non-browser environments is not supported.');\n        return;\n      }\n\n      // The session duration for browser sessions does not track a meaningful\n      // concept that can be used as a metric.\n      // Automatically captured sessions are akin to page views, and thus we\n      // discard their duration.\n      startSession({ ignoreDuration: true });\n      captureSession();\n\n      // We want to create a session for every navigation as well\n      addHistoryInstrumentationHandler(({ from, to }) => {\n        // Don't create an additional session for the initial route or if the location did not change\n        if (from !== undefined && from !== to) {\n          startSession({ ignoreDuration: true });\n          captureSession();\n        }\n      });\n    },\n  };\n});\n", "import type { Client, Event, IntegrationFn, Primitive, StackParser } from '@sentry/core';\nimport {\n  UNKNOWN_FUNCTION,\n  addGlobalErrorInstrumentationHandler,\n  addGlobalUnhandledRejectionInstrumentationHandler,\n  captureEvent,\n  defineIntegration,\n  getClient,\n  getLocationHref,\n  isPrimitive,\n  isString,\n  logger,\n} from '@sentry/core';\n\nimport type { BrowserClient } from '../client';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { eventFromUnknownInput } from '../eventbuilder';\nimport { shouldIgnoreOnError } from '../helpers';\n\ntype GlobalHandlersIntegrationsOptionKeys = 'onerror' | 'onunhandledrejection';\n\ntype GlobalHandlersIntegrations = Record<GlobalHandlersIntegrationsOptionKeys, boolean>;\n\nconst INTEGRATION_NAME = 'GlobalHandlers';\n\nconst _globalHandlersIntegration = ((options: Partial<GlobalHandlersIntegrations> = {}) => {\n  const _options = {\n    onerror: true,\n    onunhandledrejection: true,\n    ...options,\n  };\n\n  return {\n    name: INTEGRATION_NAME,\n    setupOnce() {\n      Error.stackTraceLimit = 50;\n    },\n    setup(client) {\n      if (_options.onerror) {\n        _installGlobalOnErrorHandler(client);\n        globalHandlerLog('onerror');\n      }\n      if (_options.onunhandledrejection) {\n        _installGlobalOnUnhandledRejectionHandler(client);\n        globalHandlerLog('onunhandledrejection');\n      }\n    },\n  };\n}) satisfies IntegrationFn;\n\nexport const globalHandlersIntegration = defineIntegration(_globalHandlersIntegration);\n\nfunction _installGlobalOnErrorHandler(client: Client): void {\n  addGlobalErrorInstrumentationHandler(data => {\n    const { stackParser, attachStacktrace } = getOptions();\n\n    if (getClient() !== client || shouldIgnoreOnError()) {\n      return;\n    }\n\n    const { msg, url, line, column, error } = data;\n\n    const event = _enhanceEventWithInitialFrame(\n      eventFromUnknownInput(stackParser, error || msg, undefined, attachStacktrace, false),\n      url,\n      line,\n      column,\n    );\n\n    event.level = 'error';\n\n    captureEvent(event, {\n      originalException: error,\n      mechanism: {\n        handled: false,\n        type: 'onerror',\n      },\n    });\n  });\n}\n\nfunction _installGlobalOnUnhandledRejectionHandler(client: Client): void {\n  addGlobalUnhandledRejectionInstrumentationHandler(e => {\n    const { stackParser, attachStacktrace } = getOptions();\n\n    if (getClient() !== client || shouldIgnoreOnError()) {\n      return;\n    }\n\n    const error = _getUnhandledRejectionError(e as unknown);\n\n    const event = isPrimitive(error)\n      ? _eventFromRejectionWithPrimitive(error)\n      : eventFromUnknownInput(stackParser, error, undefined, attachStacktrace, true);\n\n    event.level = 'error';\n\n    captureEvent(event, {\n      originalException: error,\n      mechanism: {\n        handled: false,\n        type: 'onunhandledrejection',\n      },\n    });\n  });\n}\n\nfunction _getUnhandledRejectionError(error: unknown): unknown {\n  if (isPrimitive(error)) {\n    return error;\n  }\n\n  // dig the object of the rejection out of known event types\n  try {\n    type ErrorWithReason = { reason: unknown };\n    // PromiseRejectionEvents store the object of the rejection under 'reason'\n    // see https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent\n    if ('reason' in (error as ErrorWithReason)) {\n      return (error as ErrorWithReason).reason;\n    }\n\n    type CustomEventWithDetail = { detail: { reason: unknown } };\n    // something, somewhere, (likely a browser extension) effectively casts PromiseRejectionEvents\n    // to CustomEvents, moving the `promise` and `reason` attributes of the PRE into\n    // the CustomEvent's `detail` attribute, since they're not part of CustomEvent's spec\n    // see https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent and\n    // https://github.com/getsentry/sentry-javascript/issues/2380\n    if ('detail' in (error as CustomEventWithDetail) && 'reason' in (error as CustomEventWithDetail).detail) {\n      return (error as CustomEventWithDetail).detail.reason;\n    }\n  } catch {} // eslint-disable-line no-empty\n\n  return error;\n}\n\n/**\n * Create an event from a promise rejection where the `reason` is a primitive.\n *\n * @param reason: The `reason` property of the promise rejection\n * @returns An Event object with an appropriate `exception` value\n */\nfunction _eventFromRejectionWithPrimitive(reason: Primitive): Event {\n  return {\n    exception: {\n      values: [\n        {\n          type: 'UnhandledRejection',\n          // String() is needed because the Primitive type includes symbols (which can't be automatically stringified)\n          value: `Non-Error promise rejection captured with value: ${String(reason)}`,\n        },\n      ],\n    },\n  };\n}\n\nfunction _enhanceEventWithInitialFrame(\n  event: Event,\n  url: string | undefined,\n  line: number | undefined,\n  column: number | undefined,\n): Event {\n  // event.exception\n  const e = (event.exception = event.exception || {});\n  // event.exception.values\n  const ev = (e.values = e.values || []);\n  // event.exception.values[0]\n  const ev0 = (ev[0] = ev[0] || {});\n  // event.exception.values[0].stacktrace\n  const ev0s = (ev0.stacktrace = ev0.stacktrace || {});\n  // event.exception.values[0].stacktrace.frames\n  const ev0sf = (ev0s.frames = ev0s.frames || []);\n\n  const colno = column;\n  const lineno = line;\n  const filename = isString(url) && url.length > 0 ? url : getLocationHref();\n\n  // event.exception.values[0].stacktrace.frames\n  if (ev0sf.length === 0) {\n    ev0sf.push({\n      colno,\n      filename,\n      function: UNKNOWN_FUNCTION,\n      in_app: true,\n      lineno,\n    });\n  }\n\n  return event;\n}\n\nfunction globalHandlerLog(type: string): void {\n  DEBUG_BUILD && logger.log(`Global Handler attached: ${type}`);\n}\n\nfunction getOptions(): { stackParser: StackParser; attachStacktrace?: boolean } {\n  const client = getClient<BrowserClient>();\n  const options = (client && client.getOptions()) || {\n    stackParser: () => [],\n    attachStacktrace: false,\n  };\n  return options;\n}\n", "import { defineIntegration } from '@sentry/core';\nimport { WINDOW } from '../helpers';\n\n/**\n * Collects information about HTTP request headers and\n * attaches them to the event.\n */\nexport const httpContextIntegration = defineIntegration(() => {\n  return {\n    name: 'HttpContext',\n    preprocessEvent(event) {\n      // if none of the information we want exists, don't bother\n      if (!WINDOW.navigator && !WINDOW.location && !WINDOW.document) {\n        return;\n      }\n\n      // grab as much info as exists and add it to the event\n      const url = (event.request && event.request.url) || (WINDOW.location && WINDOW.location.href);\n      const { referrer } = WINDOW.document || {};\n      const { userAgent } = WINDOW.navigator || {};\n\n      const headers = {\n        ...(event.request && event.request.headers),\n        ...(referrer && { Referer: referrer }),\n        ...(userAgent && { 'User-Agent': userAgent }),\n      };\n      const request = { ...event.request, ...(url && { url }), headers };\n\n      event.request = request;\n    },\n  };\n});\n", "import type { IntegrationFn } from '@sentry/core';\nimport { applyAggregateErrorsToEvent, defineIntegration } from '@sentry/core';\nimport { exceptionFromError } from '../eventbuilder';\n\ninterface LinkedErrorsOptions {\n  key?: string;\n  limit?: number;\n}\n\nconst DEFAULT_KEY = 'cause';\nconst DEFAULT_LIMIT = 5;\n\nconst INTEGRATION_NAME = 'LinkedErrors';\n\nconst _linkedErrorsIntegration = ((options: LinkedErrorsOptions = {}) => {\n  const limit = options.limit || DEFAULT_LIMIT;\n  const key = options.key || DEFAULT_KEY;\n\n  return {\n    name: INTEGRATION_NAME,\n    preprocessEvent(event, hint, client) {\n      const options = client.getOptions();\n\n      applyAggregateErrorsToEvent(\n        // This differs from the LinkedErrors integration in core by using a different exceptionFromError function\n        exceptionFromError,\n        options.stackParser,\n        options.maxValueLength,\n        key,\n        limit,\n        event,\n        hint,\n      );\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Aggregrate linked errors in an event.\n */\nexport const linkedErrorsIntegration = defineIntegration(_linkedErrorsIntegration);\n", "import {\n  consoleSandbox,\n  dedupeIntegration,\n  functionToStringIntegration,\n  getClient,\n  getCurrentScope,\n  getIntegrationsToSetup,\n  getReportDialogEndpoint,\n  inboundFiltersIntegration,\n  initAndBind,\n  lastEventId,\n  logger,\n  stackParserFromStackParserOptions,\n  supportsFetch,\n} from '@sentry/core';\nimport type { Client, DsnLike, Integration, Options, UserFeedback } from '@sentry/core';\nimport type { BrowserClientOptions, BrowserOptions } from './client';\nimport { BrowserClient } from './client';\nimport { DEBUG_BUILD } from './debug-build';\nimport { WINDOW } from './helpers';\nimport { breadcrumbsIntegration } from './integrations/breadcrumbs';\nimport { browserApiErrorsIntegration } from './integrations/browserapierrors';\nimport { browserSessionIntegration } from './integrations/browsersession';\nimport { globalHandlersIntegration } from './integrations/globalhandlers';\nimport { httpContextIntegration } from './integrations/httpcontext';\nimport { linkedErrorsIntegration } from './integrations/linkederrors';\nimport { defaultStackParser } from './stack-parsers';\nimport { makeFetchTransport } from './transports/fetch';\n\n/** Get the default integrations for the browser SDK. */\nexport function getDefaultIntegrations(options: Options): Integration[] {\n  /**\n   * Note: Please make sure this stays in sync with Angular SDK, which re-exports\n   * `getDefaultIntegrations` but with an adjusted set of integrations.\n   */\n  const integrations = [\n    inboundFiltersIntegration(),\n    functionToStringIntegration(),\n    browserApiErrorsIntegration(),\n    breadcrumbsIntegration(),\n    globalHandlersIntegration(),\n    linkedErrorsIntegration(),\n    dedupeIntegration(),\n    httpContextIntegration(),\n  ];\n\n  // eslint-disable-next-line deprecation/deprecation\n  if (options.autoSessionTracking !== false) {\n    integrations.push(browserSessionIntegration());\n  }\n\n  return integrations;\n}\n\nfunction applyDefaultOptions(optionsArg: BrowserOptions = {}): BrowserOptions {\n  const defaultOptions: BrowserOptions = {\n    defaultIntegrations: getDefaultIntegrations(optionsArg),\n    release:\n      typeof __SENTRY_RELEASE__ === 'string' // This allows build tooling to find-and-replace __SENTRY_RELEASE__ to inject a release value\n        ? __SENTRY_RELEASE__\n        : WINDOW.SENTRY_RELEASE && WINDOW.SENTRY_RELEASE.id // This supports the variable that sentry-webpack-plugin injects\n          ? WINDOW.SENTRY_RELEASE.id\n          : undefined,\n    autoSessionTracking: true,\n    sendClientReports: true,\n  };\n\n  // TODO: Instead of dropping just `defaultIntegrations`, we should simply\n  // call `dropUndefinedKeys` on the entire `optionsArg`.\n  // However, for this to work we need to adjust the `hasTracingEnabled()` logic\n  // first as it differentiates between `undefined` and the key not being in the object.\n  if (optionsArg.defaultIntegrations == null) {\n    delete optionsArg.defaultIntegrations;\n  }\n\n  return { ...defaultOptions, ...optionsArg };\n}\n\ntype ExtensionProperties = {\n  chrome?: Runtime;\n  browser?: Runtime;\n  nw?: unknown;\n};\ntype Runtime = {\n  runtime?: {\n    id?: string;\n  };\n};\n\nfunction shouldShowBrowserExtensionError(): boolean {\n  const windowWithMaybeExtension =\n    typeof WINDOW.window !== 'undefined' && (WINDOW as typeof WINDOW & ExtensionProperties);\n  if (!windowWithMaybeExtension) {\n    // No need to show the error if we're not in a browser window environment (e.g. service workers)\n    return false;\n  }\n\n  const extensionKey = windowWithMaybeExtension.chrome ? 'chrome' : 'browser';\n  const extensionObject = windowWithMaybeExtension[extensionKey];\n\n  const runtimeId = extensionObject && extensionObject.runtime && extensionObject.runtime.id;\n  const href = (WINDOW.location && WINDOW.location.href) || '';\n\n  const extensionProtocols = ['chrome-extension:', 'moz-extension:', 'ms-browser-extension:', 'safari-web-extension:'];\n\n  // Running the SDK in a dedicated extension page and calling Sentry.init is fine; no risk of data leakage\n  const isDedicatedExtensionPage =\n    !!runtimeId && WINDOW === WINDOW.top && extensionProtocols.some(protocol => href.startsWith(`${protocol}//`));\n\n  // Running the SDK in NW.js, which appears like a browser extension but isn't, is also fine\n  // see: https://github.com/getsentry/sentry-javascript/issues/12668\n  const isNWjs = typeof windowWithMaybeExtension.nw !== 'undefined';\n\n  return !!runtimeId && !isDedicatedExtensionPage && !isNWjs;\n}\n\n/**\n * A magic string that build tooling can leverage in order to inject a release value into the SDK.\n */\ndeclare const __SENTRY_RELEASE__: string | undefined;\n\n/**\n * The Sentry Browser SDK Client.\n *\n * To use this SDK, call the {@link init} function as early as possible when\n * loading the web page. To set context information or send manual events, use\n * the provided methods.\n *\n * @example\n *\n * ```\n *\n * import { init } from '@sentry/browser';\n *\n * init({\n *   dsn: '__DSN__',\n *   // ...\n * });\n * ```\n *\n * @example\n * ```\n *\n * import { addBreadcrumb } from '@sentry/browser';\n * addBreadcrumb({\n *   message: 'My Breadcrumb',\n *   // ...\n * });\n * ```\n *\n * @example\n *\n * ```\n *\n * import * as Sentry from '@sentry/browser';\n * Sentry.captureMessage('Hello, world!');\n * Sentry.captureException(new Error('Good bye'));\n * Sentry.captureEvent({\n *   message: 'Manual',\n *   stacktrace: [\n *     // ...\n *   ],\n * });\n * ```\n *\n * @see {@link BrowserOptions} for documentation on configuration options.\n */\nexport function init(browserOptions: BrowserOptions = {}): Client | undefined {\n  const options = applyDefaultOptions(browserOptions);\n\n  if (!options.skipBrowserExtensionCheck && shouldShowBrowserExtensionError()) {\n    consoleSandbox(() => {\n      // eslint-disable-next-line no-console\n      console.error(\n        '[Sentry] You cannot run Sentry this way in a browser extension, check: https://docs.sentry.io/platforms/javascript/best-practices/browser-extensions/',\n      );\n    });\n    return;\n  }\n\n  if (DEBUG_BUILD) {\n    if (!supportsFetch()) {\n      logger.warn(\n        'No Fetch API detected. The Sentry SDK requires a Fetch API compatible environment to send events. Please add a Fetch API polyfill.',\n      );\n    }\n  }\n  const clientOptions: BrowserClientOptions = {\n    ...options,\n    stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),\n    integrations: getIntegrationsToSetup(options),\n    transport: options.transport || makeFetchTransport,\n  };\n\n  return initAndBind(BrowserClient, clientOptions);\n}\n\n/**\n * All properties the report dialog supports\n */\nexport interface ReportDialogOptions {\n  // TODO(v9): Change this to  [key: string]: unknkown;\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  [key: string]: any;\n  eventId?: string;\n  dsn?: DsnLike;\n  user?: {\n    email?: string;\n    name?: string;\n  };\n  lang?: string;\n  title?: string;\n  subtitle?: string;\n  subtitle2?: string;\n  labelName?: string;\n  labelEmail?: string;\n  labelComments?: string;\n  labelClose?: string;\n  labelSubmit?: string;\n  errorGeneric?: string;\n  errorFormEntry?: string;\n  successMessage?: string;\n  /** Callback after reportDialog showed up */\n  onLoad?(this: void): void;\n  /** Callback after reportDialog closed */\n  onClose?(this: void): void;\n}\n\n/**\n * Present the user with a report dialog.\n *\n * @param options Everything is optional, we try to fetch all info need from the global scope.\n */\nexport function showReportDialog(options: ReportDialogOptions = {}): void {\n  // doesn't work without a document (React Native)\n  if (!WINDOW.document) {\n    DEBUG_BUILD && logger.error('Global document not defined in showReportDialog call');\n    return;\n  }\n\n  const scope = getCurrentScope();\n  const client = scope.getClient();\n  const dsn = client && client.getDsn();\n\n  if (!dsn) {\n    DEBUG_BUILD && logger.error('DSN not configured for showReportDialog call');\n    return;\n  }\n\n  if (scope) {\n    options.user = {\n      ...scope.getUser(),\n      ...options.user,\n    };\n  }\n\n  if (!options.eventId) {\n    const eventId = lastEventId();\n    if (eventId) {\n      options.eventId = eventId;\n    }\n  }\n\n  const script = WINDOW.document.createElement('script');\n  script.async = true;\n  script.crossOrigin = 'anonymous';\n  script.src = getReportDialogEndpoint(dsn, options);\n\n  if (options.onLoad) {\n    script.onload = options.onLoad;\n  }\n\n  const { onClose } = options;\n  if (onClose) {\n    const reportDialogClosedMessageHandler = (event: MessageEvent): void => {\n      if (event.data === '__sentry_reportdialog_closed__') {\n        try {\n          onClose();\n        } finally {\n          WINDOW.removeEventListener('message', reportDialogClosedMessageHandler);\n        }\n      }\n    };\n    WINDOW.addEventListener('message', reportDialogClosedMessageHandler);\n  }\n\n  const injectionPoint = WINDOW.document.head || WINDOW.document.body;\n  if (injectionPoint) {\n    injectionPoint.appendChild(script);\n  } else {\n    DEBUG_BUILD && logger.error('Not injecting report dialog. No injection point found in HTML');\n  }\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function forceLoad(): void {\n  // Noop\n}\n\n/**\n * This function is here to be API compatible with the loader.\n * @hidden\n */\nexport function onLoad(callback: () => void): void {\n  callback();\n}\n\n/**\n * Captures user feedback and sends it to Sentry.\n *\n * @deprecated Use `captureFeedback` instead.\n */\nexport function captureUserFeedback(feedback: UserFeedback): void {\n  const client = getClient<BrowserClient>();\n  if (client) {\n    // eslint-disable-next-line deprecation/deprecation\n    client.captureUserFeedback(feedback);\n  }\n}\n", "import { SDK_VERSION, getClient } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport type { BrowserClient } from '../client';\nimport { WINDOW } from '../helpers';\n\n// This is a map of integration function method to bundle file name.\nconst LazyLoadableIntegrations = {\n  replayIntegration: 'replay',\n  replayCanvasIntegration: 'replay-canvas',\n  feedbackIntegration: 'feedback',\n  feedbackModalIntegration: 'feedback-modal',\n  feedbackScreenshotIntegration: 'feedback-screenshot',\n  captureConsoleIntegration: 'captureconsole',\n  contextLinesIntegration: 'contextlines',\n  linkedErrorsIntegration: 'linkederrors',\n  debugIntegration: 'debug',\n  dedupeIntegration: 'dedupe',\n  extraErrorDataIntegration: 'extraerrordata',\n  httpClientIntegration: 'httpclient',\n  reportingObserverIntegration: 'reportingobserver',\n  rewriteFramesIntegration: 'rewriteframes',\n  sessionTimingIntegration: 'sessiontiming',\n  browserProfilingIntegration: 'browserprofiling',\n  moduleMetadataIntegration: 'modulemetadata',\n} as const;\n\nconst WindowWithMaybeIntegration = WINDOW as {\n  Sentry?: Partial<Record<keyof typeof LazyLoadableIntegrations, IntegrationFn>>;\n};\n\n/**\n * Lazy load an integration from the CDN.\n * Rejects if the integration cannot be loaded.\n */\nexport async function lazyLoadIntegration(\n  name: keyof typeof LazyLoadableIntegrations,\n  scriptNonce?: string,\n): Promise<IntegrationFn> {\n  const bundle = LazyLoadableIntegrations[name];\n\n  // `window.Sentry` is only set when using a CDN bundle, but this method can also be used via the NPM package\n  const sentryOnWindow = (WindowWithMaybeIntegration.Sentry = WindowWithMaybeIntegration.Sentry || {});\n\n  if (!bundle) {\n    throw new Error(`Cannot lazy load integration: ${name}`);\n  }\n\n  // Bail if the integration already exists\n  const existing = sentryOnWindow[name];\n  // The `feedbackIntegration` is loaded by default in the CDN bundles,\n  // so we need to differentiate between the real integration and the shim.\n  // if only the shim exists, we still want to lazy load the real integration.\n  if (typeof existing === 'function' && !('_isShim' in existing)) {\n    return existing;\n  }\n\n  const url = getScriptURL(bundle);\n  const script = WINDOW.document.createElement('script');\n  script.src = url;\n  script.crossOrigin = 'anonymous';\n  script.referrerPolicy = 'origin';\n\n  if (scriptNonce) {\n    script.setAttribute('nonce', scriptNonce);\n  }\n\n  const waitForLoad = new Promise<void>((resolve, reject) => {\n    script.addEventListener('load', () => resolve());\n    script.addEventListener('error', reject);\n  });\n\n  const currentScript = WINDOW.document.currentScript;\n  const parent = WINDOW.document.body || WINDOW.document.head || (currentScript && currentScript.parentElement);\n\n  if (parent) {\n    parent.appendChild(script);\n  } else {\n    throw new Error(`Could not find parent element to insert lazy-loaded ${name} script`);\n  }\n\n  try {\n    await waitForLoad;\n  } catch {\n    throw new Error(`Error when loading integration: ${name}`);\n  }\n\n  const integrationFn = sentryOnWindow[name];\n\n  if (typeof integrationFn !== 'function') {\n    throw new Error(`Could not load integration: ${name}`);\n  }\n\n  return integrationFn;\n}\n\nfunction getScriptURL(bundle: string): string {\n  const client = getClient<BrowserClient>();\n  const options = client && client.getOptions();\n  const baseURL = (options && options.cdnBaseUrl) || 'https://browser.sentry-cdn.com';\n\n  return new URL(`/${SDK_VERSION}/${bundle}.min.js`, baseURL).toString();\n}\n", "import type { Client, IntegrationFn } from '@sentry/core';\nimport {\n  GLOBAL_OBJ,\n  captureMessage,\n  defineIntegration,\n  getClient,\n  supportsReportingObserver,\n  withScope,\n} from '@sentry/core';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst INTEGRATION_NAME = 'ReportingObserver';\n\ninterface Report {\n  [key: string]: unknown;\n  type: ReportTypes;\n  url: string;\n  body?: ReportBody;\n}\n\ntype ReportTypes = 'crash' | 'deprecation' | 'intervention';\n\ntype ReportBody = CrashReportBody | DeprecationReportBody | InterventionReportBody;\n\ninterface CrashReportBody {\n  [key: string]: unknown;\n  crashId: string;\n  reason?: string;\n}\n\ninterface DeprecationReportBody {\n  [key: string]: unknown;\n  id: string;\n  anticipatedRemoval?: Date;\n  message: string;\n  sourceFile?: string;\n  lineNumber?: number;\n  columnNumber?: number;\n}\n\ninterface InterventionReportBody {\n  [key: string]: unknown;\n  id: string;\n  message: string;\n  sourceFile?: string;\n  lineNumber?: number;\n  columnNumber?: number;\n}\n\ninterface ReportingObserverOptions {\n  types?: ReportTypes[];\n}\n\n/** This is experimental and the types are not included with TypeScript, sadly. */\ninterface ReportingObserverClass {\n  new (\n    handler: (reports: Report[]) => void,\n    options: { buffered?: boolean; types?: ReportTypes[] },\n  ): {\n    observe: () => void;\n  };\n}\n\nconst SETUP_CLIENTS = new WeakMap<Client, boolean>();\n\nconst _reportingObserverIntegration = ((options: ReportingObserverOptions = {}) => {\n  const types = options.types || ['crash', 'deprecation', 'intervention'];\n\n  /** Handler for the reporting observer. */\n  function handler(reports: Report[]): void {\n    if (!SETUP_CLIENTS.has(getClient() as Client)) {\n      return;\n    }\n\n    for (const report of reports) {\n      withScope(scope => {\n        scope.setExtra('url', report.url);\n\n        const label = `ReportingObserver [${report.type}]`;\n        let details = 'No details available';\n\n        if (report.body) {\n          // Object.keys doesn't work on ReportBody, as all properties are inherited\n          const plainBody: {\n            [key: string]: unknown;\n          } = {};\n\n          // eslint-disable-next-line guard-for-in\n          for (const prop in report.body) {\n            plainBody[prop] = report.body[prop];\n          }\n\n          scope.setExtra('body', plainBody);\n\n          if (report.type === 'crash') {\n            const body = report.body as CrashReportBody;\n            // A fancy way to create a message out of crashId OR reason OR both OR fallback\n            details = [body.crashId || '', body.reason || ''].join(' ').trim() || details;\n          } else {\n            const body = report.body as DeprecationReportBody | InterventionReportBody;\n            details = body.message || details;\n          }\n        }\n\n        captureMessage(`${label}: ${details}`);\n      });\n    }\n  }\n\n  return {\n    name: INTEGRATION_NAME,\n    setupOnce() {\n      if (!supportsReportingObserver()) {\n        return;\n      }\n\n      const observer = new (WINDOW as typeof WINDOW & { ReportingObserver: ReportingObserverClass }).ReportingObserver(\n        handler,\n        {\n          buffered: true,\n          types,\n        },\n      );\n\n      observer.observe();\n    },\n\n    setup(client): void {\n      SETUP_CLIENTS.set(client, true);\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Reporting API integration - https://w3c.github.io/reporting/\n */\nexport const reportingObserverIntegration = defineIntegration(_reportingObserverIntegration);\n", "import { SENTRY_XHR_DATA_KEY, addXhrInstrumentationHandler } from '@sentry-internal/browser-utils';\nimport type { Client, Event as SentryEvent, IntegrationFn, SentryWrappedXMLHttpRequest } from '@sentry/core';\nimport {\n  GLOBAL_OBJ,\n  addExceptionMechanism,\n  addFetchInstrumentationHandler,\n  captureEvent,\n  defineIntegration,\n  getClient,\n  isSentryRequestUrl,\n  logger,\n  supportsNativeFetch,\n} from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\n\nexport type HttpStatusCodeRange = [number, number] | number;\nexport type HttpRequestTarget = string | RegExp;\n\nconst INTEGRATION_NAME = 'HttpClient';\n\ninterface HttpClientOptions {\n  /**\n   * HTTP status codes that should be considered failed.\n   * This array can contain tuples of `[begin, end]` (both inclusive),\n   * single status codes, or a combinations of both\n   *\n   * Example: [[500, 505], 507]\n   * Default: [[500, 599]]\n   */\n  failedRequestStatusCodes: HttpStatusCodeRange[];\n\n  /**\n   * Targets to track for failed requests.\n   * This array can contain strings or regular expressions.\n   *\n   * Example: ['http://localhost', /api\\/.*\\/]\n   * Default: [/.*\\/]\n   */\n  failedRequestTargets: HttpRequestTarget[];\n}\n\nconst _httpClientIntegration = ((options: Partial<HttpClientOptions> = {}) => {\n  const _options: HttpClientOptions = {\n    failedRequestStatusCodes: [[500, 599]],\n    failedRequestTargets: [/.*/],\n    ...options,\n  };\n\n  return {\n    name: INTEGRATION_NAME,\n    setup(client): void {\n      _wrapFetch(client, _options);\n      _wrapXHR(client, _options);\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Create events for failed client side HTTP requests.\n */\nexport const httpClientIntegration = defineIntegration(_httpClientIntegration);\n\n/**\n * Interceptor function for fetch requests\n *\n * @param requestInfo The Fetch API request info\n * @param response The Fetch API response\n * @param requestInit The request init object\n */\nfunction _fetchResponseHandler(\n  options: HttpClientOptions,\n  requestInfo: RequestInfo,\n  response: Response,\n  requestInit?: RequestInit,\n  error?: unknown,\n): void {\n  if (_shouldCaptureResponse(options, response.status, response.url)) {\n    const request = _getRequest(requestInfo, requestInit);\n\n    let requestHeaders, responseHeaders, requestCookies, responseCookies;\n\n    if (_shouldSendDefaultPii()) {\n      [requestHeaders, requestCookies] = _parseCookieHeaders('Cookie', request);\n      [responseHeaders, responseCookies] = _parseCookieHeaders('Set-Cookie', response);\n    }\n\n    const event = _createEvent({\n      url: request.url,\n      method: request.method,\n      status: response.status,\n      requestHeaders,\n      responseHeaders,\n      requestCookies,\n      responseCookies,\n      error,\n    });\n\n    captureEvent(event);\n  }\n}\n\nfunction _parseCookieHeaders(\n  cookieHeader: string,\n  obj: Request | Response,\n): [Record<string, string>, Record<string, string> | undefined] {\n  const headers = _extractFetchHeaders(obj.headers);\n  let cookies;\n\n  try {\n    const cookieString = headers[cookieHeader] || headers[cookieHeader.toLowerCase()] || undefined;\n\n    if (cookieString) {\n      cookies = _parseCookieString(cookieString);\n    }\n  } catch {\n    // ignore it if parsing fails\n  }\n\n  return [headers, cookies];\n}\n\n/**\n * Interceptor function for XHR requests\n *\n * @param xhr The XHR request\n * @param method The HTTP method\n * @param headers The HTTP headers\n */\nfunction _xhrResponseHandler(\n  options: HttpClientOptions,\n  xhr: XMLHttpRequest,\n  method: string,\n  headers: Record<string, string>,\n  error?: unknown,\n): void {\n  if (_shouldCaptureResponse(options, xhr.status, xhr.responseURL)) {\n    let requestHeaders, responseCookies, responseHeaders;\n\n    if (_shouldSendDefaultPii()) {\n      try {\n        const cookieString = xhr.getResponseHeader('Set-Cookie') || xhr.getResponseHeader('set-cookie') || undefined;\n\n        if (cookieString) {\n          responseCookies = _parseCookieString(cookieString);\n        }\n      } catch {\n        // ignore it if parsing fails\n      }\n\n      try {\n        responseHeaders = _getXHRResponseHeaders(xhr);\n      } catch {\n        // ignore it if parsing fails\n      }\n\n      requestHeaders = headers;\n    }\n\n    const event = _createEvent({\n      url: xhr.responseURL,\n      method,\n      status: xhr.status,\n      requestHeaders,\n      // Can't access request cookies from XHR\n      responseHeaders,\n      responseCookies,\n      error,\n    });\n\n    captureEvent(event);\n  }\n}\n\n/**\n * Extracts response size from `Content-Length` header when possible\n *\n * @param headers\n * @returns The response size in bytes or undefined\n */\nfunction _getResponseSizeFromHeaders(headers?: Record<string, string>): number | undefined {\n  if (headers) {\n    const contentLength = headers['Content-Length'] || headers['content-length'];\n\n    if (contentLength) {\n      return parseInt(contentLength, 10);\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Creates an object containing cookies from the given cookie string\n *\n * @param cookieString The cookie string to parse\n * @returns The parsed cookies\n */\nfunction _parseCookieString(cookieString: string): Record<string, string> {\n  return cookieString.split('; ').reduce((acc: Record<string, string>, cookie: string) => {\n    const [key, value] = cookie.split('=');\n    if (key && value) {\n      acc[key] = value;\n    }\n    return acc;\n  }, {});\n}\n\n/**\n * Extracts the headers as an object from the given Fetch API request or response object\n *\n * @param headers The headers to extract\n * @returns The extracted headers as an object\n */\nfunction _extractFetchHeaders(headers: Headers): Record<string, string> {\n  const result: Record<string, string> = {};\n\n  headers.forEach((value, key) => {\n    result[key] = value;\n  });\n\n  return result;\n}\n\n/**\n * Extracts the response headers as an object from the given XHR object\n *\n * @param xhr The XHR object to extract the response headers from\n * @returns The response headers as an object\n */\nfunction _getXHRResponseHeaders(xhr: XMLHttpRequest): Record<string, string> {\n  const headers = xhr.getAllResponseHeaders();\n\n  if (!headers) {\n    return {};\n  }\n\n  return headers.split('\\r\\n').reduce((acc: Record<string, string>, line: string) => {\n    const [key, value] = line.split(': ');\n    if (key && value) {\n      acc[key] = value;\n    }\n    return acc;\n  }, {});\n}\n\n/**\n * Checks if the given target url is in the given list of targets\n *\n * @param target The target url to check\n * @returns true if the target url is in the given list of targets, false otherwise\n */\nfunction _isInGivenRequestTargets(\n  failedRequestTargets: HttpClientOptions['failedRequestTargets'],\n  target: string,\n): boolean {\n  return failedRequestTargets.some((givenRequestTarget: HttpRequestTarget) => {\n    if (typeof givenRequestTarget === 'string') {\n      return target.includes(givenRequestTarget);\n    }\n\n    return givenRequestTarget.test(target);\n  });\n}\n\n/**\n * Checks if the given status code is in the given range\n *\n * @param status The status code to check\n * @returns true if the status code is in the given range, false otherwise\n */\nfunction _isInGivenStatusRanges(\n  failedRequestStatusCodes: HttpClientOptions['failedRequestStatusCodes'],\n  status: number,\n): boolean {\n  return failedRequestStatusCodes.some((range: HttpStatusCodeRange) => {\n    if (typeof range === 'number') {\n      return range === status;\n    }\n\n    return status >= range[0] && status <= range[1];\n  });\n}\n\n/**\n * Wraps `fetch` function to capture request and response data\n */\nfunction _wrapFetch(client: Client, options: HttpClientOptions): void {\n  if (!supportsNativeFetch()) {\n    return;\n  }\n\n  addFetchInstrumentationHandler(handlerData => {\n    if (getClient() !== client) {\n      return;\n    }\n\n    const { response, args, error, virtualError } = handlerData;\n    const [requestInfo, requestInit] = args as [RequestInfo, RequestInit | undefined];\n\n    if (!response) {\n      return;\n    }\n\n    _fetchResponseHandler(options, requestInfo, response as Response, requestInit, error || virtualError);\n  }, false);\n}\n\n/**\n * Wraps XMLHttpRequest to capture request and response data\n */\nfunction _wrapXHR(client: Client, options: HttpClientOptions): void {\n  if (!('XMLHttpRequest' in GLOBAL_OBJ)) {\n    return;\n  }\n\n  addXhrInstrumentationHandler(handlerData => {\n    if (getClient() !== client) {\n      return;\n    }\n\n    const { error, virtualError } = handlerData;\n\n    const xhr = handlerData.xhr as SentryWrappedXMLHttpRequest & XMLHttpRequest;\n\n    const sentryXhrData = xhr[SENTRY_XHR_DATA_KEY];\n\n    if (!sentryXhrData) {\n      return;\n    }\n\n    const { method, request_headers: headers } = sentryXhrData;\n\n    try {\n      _xhrResponseHandler(options, xhr, method, headers, error || virtualError);\n    } catch (e) {\n      DEBUG_BUILD && logger.warn('Error while extracting response event form XHR response', e);\n    }\n  });\n}\n\n/**\n * Checks whether to capture given response as an event\n *\n * @param status response status code\n * @param url response url\n */\nfunction _shouldCaptureResponse(options: HttpClientOptions, status: number, url: string): boolean {\n  return (\n    _isInGivenStatusRanges(options.failedRequestStatusCodes, status) &&\n    _isInGivenRequestTargets(options.failedRequestTargets, url) &&\n    !isSentryRequestUrl(url, getClient())\n  );\n}\n\n/**\n * Creates a synthetic Sentry event from given response data\n *\n * @param data response data\n * @returns event\n */\nfunction _createEvent(data: {\n  url: string;\n  method: string;\n  status: number;\n  responseHeaders?: Record<string, string>;\n  responseCookies?: Record<string, string>;\n  requestHeaders?: Record<string, string>;\n  requestCookies?: Record<string, string>;\n  error?: unknown;\n}): SentryEvent {\n  const client = getClient();\n  const virtualStackTrace = client && data.error && data.error instanceof Error ? data.error.stack : undefined;\n  // Remove the first frame from the stack as it's the HttpClient call\n  const stack = virtualStackTrace && client ? client.getOptions().stackParser(virtualStackTrace, 0, 1) : undefined;\n  const message = `HTTP Client Error with status code: ${data.status}`;\n\n  const event: SentryEvent = {\n    message,\n    exception: {\n      values: [\n        {\n          type: 'Error',\n          value: message,\n          stacktrace: stack ? { frames: stack } : undefined,\n        },\n      ],\n    },\n    request: {\n      url: data.url,\n      method: data.method,\n      headers: data.requestHeaders,\n      cookies: data.requestCookies,\n    },\n    contexts: {\n      response: {\n        status_code: data.status,\n        headers: data.responseHeaders,\n        cookies: data.responseCookies,\n        body_size: _getResponseSizeFromHeaders(data.responseHeaders),\n      },\n    },\n  };\n\n  addExceptionMechanism(event, {\n    type: 'http.client',\n    handled: false,\n  });\n\n  return event;\n}\n\nfunction _getRequest(requestInfo: RequestInfo, requestInit?: RequestInit): Request {\n  if (!requestInit && requestInfo instanceof Request) {\n    return requestInfo;\n  }\n\n  // If both are set, we try to construct a new Request with the given arguments\n  // However, if e.g. the original request has a `body`, this will throw an error because it was already accessed\n  // In this case, as a fallback, we just use the original request - using both is rather an edge case\n  if (requestInfo instanceof Request && requestInfo.bodyUsed) {\n    return requestInfo;\n  }\n\n  return new Request(requestInfo, requestInit);\n}\n\nfunction _shouldSendDefaultPii(): boolean {\n  const client = getClient();\n  return client ? Boolean(client.getOptions().sendDefaultPii) : false;\n}\n", "import type { Event, IntegrationFn, StackFrame } from '@sentry/core';\nimport { GLOBAL_OBJ, addContextToFrame, defineIntegration, stripUrlQueryAndFragment } from '@sentry/core';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nconst DEFAULT_LINES_OF_CONTEXT = 7;\n\nconst INTEGRATION_NAME = 'ContextLines';\n\ninterface ContextLinesOptions {\n  /**\n   * Sets the number of context lines for each frame when loading a file.\n   * Defaults to 7.\n   *\n   * Set to 0 to disable loading and inclusion of source files.\n   **/\n  frameContextLines?: number;\n}\n\nconst _contextLinesIntegration = ((options: ContextLinesOptions = {}) => {\n  const contextLines = options.frameContextLines != null ? options.frameContextLines : DEFAULT_LINES_OF_CONTEXT;\n\n  return {\n    name: INTEGRATION_NAME,\n    processEvent(event) {\n      return addSourceContext(event, contextLines);\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Collects source context lines around the lines of stackframes pointing to JS embedded in\n * the current page's HTML.\n *\n * This integration DOES NOT work for stack frames pointing to JS files that are loaded by the browser.\n * For frames pointing to files, context lines are added during ingestion and symbolication\n * by attempting to download the JS files to the Sentry backend.\n *\n * Use this integration if you have inline JS code in HTML pages that can't be accessed\n * by our backend (e.g. due to a login-protected page).\n */\nexport const contextLinesIntegration = defineIntegration(_contextLinesIntegration);\n\n/**\n * Processes an event and adds context lines.\n */\nfunction addSourceContext(event: Event, contextLines: number): Event {\n  const doc = WINDOW.document;\n  const htmlFilename = WINDOW.location && stripUrlQueryAndFragment(WINDOW.location.href);\n  if (!doc || !htmlFilename) {\n    return event;\n  }\n\n  const exceptions = event.exception && event.exception.values;\n  if (!exceptions || !exceptions.length) {\n    return event;\n  }\n\n  const html = doc.documentElement.innerHTML;\n  if (!html) {\n    return event;\n  }\n\n  const htmlLines = ['<!DOCTYPE html>', '<html>', ...html.split('\\n'), '</html>'];\n\n  exceptions.forEach(exception => {\n    const stacktrace = exception.stacktrace;\n    if (stacktrace && stacktrace.frames) {\n      stacktrace.frames = stacktrace.frames.map(frame =>\n        applySourceContextToFrame(frame, htmlLines, htmlFilename, contextLines),\n      );\n    }\n  });\n\n  return event;\n}\n\n/**\n * Only exported for testing\n */\nexport function applySourceContextToFrame(\n  frame: StackFrame,\n  htmlLines: string[],\n  htmlFilename: string,\n  linesOfContext: number,\n): StackFrame {\n  if (frame.filename !== htmlFilename || !frame.lineno || !htmlLines.length) {\n    return frame;\n  }\n\n  addContextToFrame(htmlLines, frame, linesOfContext);\n\n  return frame;\n}\n", "import { GLOBAL_OBJ } from '@sentry/core';\n\n// exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`\n// prevents the browser package from being bundled in the CDN bundle, and avoids a\n// circular dependency between the browser and replay packages should `@sentry/browser` import\n// from `@sentry/replay` in the future\nexport const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\nexport const REPLAY_SESSION_KEY = 'sentryReplaySession';\nexport const REPLAY_EVENT_NAME = 'replay_event';\nexport const RECORDING_EVENT_NAME = 'replay_recording';\nexport const UNABLE_TO_SEND_REPLAY = 'Unable to send Replay';\n\n// The idle limit for a session after which recording is paused.\nexport const SESSION_IDLE_PAUSE_DURATION = 300_000; // 5 minutes in ms\n\n// The idle limit for a session after which the session expires.\nexport const SESSION_IDLE_EXPIRE_DURATION = 900_000; // 15 minutes in ms\n\n/** Default flush delays */\nexport const DEFAULT_FLUSH_MIN_DELAY = 5_000;\n// XXX: Temp fix for our debounce logic where `maxWait` would never occur if it\n// was the same as `wait`\nexport const DEFAULT_FLUSH_MAX_DELAY = 5_500;\n\n/* How long to wait for error checkouts */\nexport const BUFFER_CHECKOUT_TIME = 60_000;\n\nexport const RETRY_BASE_INTERVAL = 5000;\nexport const RETRY_MAX_COUNT = 3;\n\n/* The max (uncompressed) size in bytes of a network body. Any body larger than this will be truncated. */\nexport const NETWORK_BODY_MAX_SIZE = 150_000;\n\n/* The max size of a single console arg that is captured. Any arg larger than this will be truncated. */\nexport const CONSOLE_ARG_MAX_SIZE = 5_000;\n\n/* Min. time to wait before we consider something a slow click. */\nexport const SLOW_CLICK_THRESHOLD = 3_000;\n/* For scroll actions after a click, we only look for a very short time period to detect programmatic scrolling. */\nexport const SLOW_CLICK_SCROLL_TIMEOUT = 300;\n\n/** When encountering a total segment size exceeding this size, stop the replay (as we cannot properly ingest it). */\nexport const REPLAY_MAX_EVENT_BUFFER_SIZE = 20_000_000; // ~20MB\n\n/** Replays must be min. 5s long before we send them. */\nexport const MIN_REPLAY_DURATION = 4_999;\n/* The max. allowed value that the minReplayDuration can be set to. */\nexport const MIN_REPLAY_DURATION_LIMIT = 15_000;\n\n/** The max. length of a replay. */\nexport const MAX_REPLAY_DURATION = 3_600_000; // 60 minutes in ms;\n\n/** Default attributes to be ignored when `maskAllText` is enabled */\nexport const DEFAULT_IGNORED_ATTRIBUTES = ['title', 'placeholder'];\n", "var NodeType;\r\n(function (NodeType) {\r\n    NodeType[NodeType[\"Document\"] = 0] = \"Document\";\r\n    NodeType[NodeType[\"DocumentType\"] = 1] = \"DocumentType\";\r\n    NodeType[NodeType[\"Element\"] = 2] = \"Element\";\r\n    NodeType[NodeType[\"Text\"] = 3] = \"Text\";\r\n    NodeType[NodeType[\"CDATA\"] = 4] = \"CDATA\";\r\n    NodeType[NodeType[\"Comment\"] = 5] = \"Comment\";\r\n})(NodeType || (NodeType = {}));\n\nfunction isElement(n) {\r\n    return n.nodeType === n.ELEMENT_NODE;\r\n}\r\nfunction isShadowRoot(n) {\r\n    const host = n?.host;\r\n    return Boolean(host?.shadowRoot === n);\r\n}\r\nfunction isNativeShadowDom(shadowRoot) {\r\n    return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';\r\n}\r\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\r\n    if (cssText.includes(' background-clip: text;') &&\r\n        !cssText.includes(' -webkit-background-clip: text;')) {\r\n        cssText = cssText.replace(/\\sbackground-clip:\\s*text;/g, ' -webkit-background-clip: text; background-clip: text;');\r\n    }\r\n    return cssText;\r\n}\r\nfunction escapeImportStatement(rule) {\r\n    const { cssText } = rule;\r\n    if (cssText.split('\"').length < 3)\r\n        return cssText;\r\n    const statement = ['@import', `url(${JSON.stringify(rule.href)})`];\r\n    if (rule.layerName === '') {\r\n        statement.push(`layer`);\r\n    }\r\n    else if (rule.layerName) {\r\n        statement.push(`layer(${rule.layerName})`);\r\n    }\r\n    if (rule.supportsText) {\r\n        statement.push(`supports(${rule.supportsText})`);\r\n    }\r\n    if (rule.media.length) {\r\n        statement.push(rule.media.mediaText);\r\n    }\r\n    return statement.join(' ') + ';';\r\n}\r\nfunction stringifyStylesheet(s) {\r\n    try {\r\n        const rules = s.rules || s.cssRules;\r\n        return rules\r\n            ? fixBrowserCompatibilityIssuesInCSS(Array.from(rules, stringifyRule).join(''))\r\n            : null;\r\n    }\r\n    catch (error) {\r\n        return null;\r\n    }\r\n}\r\nfunction fixAllCssProperty(rule) {\r\n    let styles = '';\r\n    for (let i = 0; i < rule.style.length; i++) {\r\n        const styleDeclaration = rule.style;\r\n        const attribute = styleDeclaration[i];\r\n        const isImportant = styleDeclaration.getPropertyPriority(attribute);\r\n        styles += `${attribute}:${styleDeclaration.getPropertyValue(attribute)}${isImportant ? ` !important` : ''};`;\r\n    }\r\n    return `${rule.selectorText} { ${styles} }`;\r\n}\r\nfunction stringifyRule(rule) {\r\n    let importStringified;\r\n    if (isCSSImportRule(rule)) {\r\n        try {\r\n            importStringified =\r\n                stringifyStylesheet(rule.styleSheet) ||\r\n                    escapeImportStatement(rule);\r\n        }\r\n        catch (error) {\r\n        }\r\n    }\r\n    else if (isCSSStyleRule(rule)) {\r\n        let cssText = rule.cssText;\r\n        const needsSafariColonFix = rule.selectorText.includes(':');\r\n        const needsAllFix = typeof rule.style['all'] === 'string' && rule.style['all'];\r\n        if (needsAllFix) {\r\n            cssText = fixAllCssProperty(rule);\r\n        }\r\n        if (needsSafariColonFix) {\r\n            cssText = fixSafariColons(cssText);\r\n        }\r\n        if (needsSafariColonFix || needsAllFix) {\r\n            return cssText;\r\n        }\r\n    }\r\n    return importStringified || rule.cssText;\r\n}\r\nfunction fixSafariColons(cssStringified) {\r\n    const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\r\n    return cssStringified.replace(regex, '$1\\\\$2');\r\n}\r\nfunction isCSSImportRule(rule) {\r\n    return 'styleSheet' in rule;\r\n}\r\nfunction isCSSStyleRule(rule) {\r\n    return 'selectorText' in rule;\r\n}\r\nclass Mirror {\r\n    constructor() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n    getId(n) {\r\n        if (!n)\r\n            return -1;\r\n        const id = this.getMeta(n)?.id;\r\n        return id ?? -1;\r\n    }\r\n    getNode(id) {\r\n        return this.idNodeMap.get(id) || null;\r\n    }\r\n    getIds() {\r\n        return Array.from(this.idNodeMap.keys());\r\n    }\r\n    getMeta(n) {\r\n        return this.nodeMetaMap.get(n) || null;\r\n    }\r\n    removeNodeFromMap(n) {\r\n        const id = this.getId(n);\r\n        this.idNodeMap.delete(id);\r\n        if (n.childNodes) {\r\n            n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));\r\n        }\r\n    }\r\n    has(id) {\r\n        return this.idNodeMap.has(id);\r\n    }\r\n    hasNode(node) {\r\n        return this.nodeMetaMap.has(node);\r\n    }\r\n    add(n, meta) {\r\n        const id = meta.id;\r\n        this.idNodeMap.set(id, n);\r\n        this.nodeMetaMap.set(n, meta);\r\n    }\r\n    replace(id, n) {\r\n        const oldNode = this.getNode(id);\r\n        if (oldNode) {\r\n            const meta = this.nodeMetaMap.get(oldNode);\r\n            if (meta)\r\n                this.nodeMetaMap.set(n, meta);\r\n        }\r\n        this.idNodeMap.set(id, n);\r\n    }\r\n    reset() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n}\r\nfunction createMirror() {\r\n    return new Mirror();\r\n}\r\nfunction shouldMaskInput({ maskInputOptions, tagName, type, }) {\r\n    if (tagName === 'OPTION') {\r\n        tagName = 'SELECT';\r\n    }\r\n    return Boolean(maskInputOptions[tagName.toLowerCase()] ||\r\n        (type && maskInputOptions[type]) ||\r\n        type === 'password' ||\r\n        (tagName === 'INPUT' && !type && maskInputOptions['text']));\r\n}\r\nfunction maskInputValue({ isMasked, element, value, maskInputFn, }) {\r\n    let text = value || '';\r\n    if (!isMasked) {\r\n        return text;\r\n    }\r\n    if (maskInputFn) {\r\n        text = maskInputFn(text, element);\r\n    }\r\n    return '*'.repeat(text.length);\r\n}\r\nfunction toLowerCase(str) {\r\n    return str.toLowerCase();\r\n}\r\nfunction toUpperCase(str) {\r\n    return str.toUpperCase();\r\n}\r\nconst ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';\r\nfunction is2DCanvasBlank(canvas) {\r\n    const ctx = canvas.getContext('2d');\r\n    if (!ctx)\r\n        return true;\r\n    const chunkSize = 50;\r\n    for (let x = 0; x < canvas.width; x += chunkSize) {\r\n        for (let y = 0; y < canvas.height; y += chunkSize) {\r\n            const getImageData = ctx.getImageData;\r\n            const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData\r\n                ? getImageData[ORIGINAL_ATTRIBUTE_NAME]\r\n                : getImageData;\r\n            const pixelBuffer = new Uint32Array(originalGetImageData.call(ctx, x, y, Math.min(chunkSize, canvas.width - x), Math.min(chunkSize, canvas.height - y)).data.buffer);\r\n            if (pixelBuffer.some((pixel) => pixel !== 0))\r\n                return false;\r\n        }\r\n    }\r\n    return true;\r\n}\r\nfunction isNodeMetaEqual(a, b) {\r\n    if (!a || !b || a.type !== b.type)\r\n        return false;\r\n    if (a.type === NodeType.Document)\r\n        return a.compatMode === b.compatMode;\r\n    else if (a.type === NodeType.DocumentType)\r\n        return (a.name === b.name &&\r\n            a.publicId === b.publicId &&\r\n            a.systemId === b.systemId);\r\n    else if (a.type === NodeType.Comment ||\r\n        a.type === NodeType.Text ||\r\n        a.type === NodeType.CDATA)\r\n        return a.textContent === b.textContent;\r\n    else if (a.type === NodeType.Element)\r\n        return (a.tagName === b.tagName &&\r\n            JSON.stringify(a.attributes) ===\r\n                JSON.stringify(b.attributes) &&\r\n            a.isSVG === b.isSVG &&\r\n            a.needBlock === b.needBlock);\r\n    return false;\r\n}\r\nfunction getInputType(element) {\r\n    const type = element.type;\r\n    return element.hasAttribute('data-rr-is-password')\r\n        ? 'password'\r\n        : type\r\n            ?\r\n                toLowerCase(type)\r\n            : null;\r\n}\r\nfunction getInputValue(el, tagName, type) {\r\n    if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {\r\n        return el.getAttribute('value') || '';\r\n    }\r\n    return el.value;\r\n}\r\nfunction extractFileExtension(path, baseURL) {\r\n    let url;\r\n    try {\r\n        url = new URL(path, baseURL ?? window.location.href);\r\n    }\r\n    catch (err) {\r\n        return null;\r\n    }\r\n    const regex = /\\.([0-9a-z]+)(?:$)/i;\r\n    const match = url.pathname.match(regex);\r\n    return match?.[1] ?? null;\r\n}\r\nconst cachedImplementations = {};\r\nfunction getImplementation(name) {\r\n    const cached = cachedImplementations[name];\r\n    if (cached) {\r\n        return cached;\r\n    }\r\n    const document = window.document;\r\n    let impl = window[name];\r\n    if (document && typeof document.createElement === 'function') {\r\n        try {\r\n            const sandbox = document.createElement('iframe');\r\n            sandbox.hidden = true;\r\n            document.head.appendChild(sandbox);\r\n            const contentWindow = sandbox.contentWindow;\r\n            if (contentWindow && contentWindow[name]) {\r\n                impl =\r\n                    contentWindow[name];\r\n            }\r\n            document.head.removeChild(sandbox);\r\n        }\r\n        catch (e) {\r\n        }\r\n    }\r\n    return (cachedImplementations[name] = impl.bind(window));\r\n}\r\nfunction setTimeout(...rest) {\r\n    return getImplementation('setTimeout')(...rest);\r\n}\r\nfunction clearTimeout(...rest) {\r\n    return getImplementation('clearTimeout')(...rest);\r\n}\r\nfunction getIframeContentDocument(iframe) {\r\n    try {\r\n        return iframe.contentDocument;\r\n    }\r\n    catch (e) {\r\n    }\r\n}\n\nlet _id = 1;\r\nconst tagNameRegex = new RegExp('[^a-z0-9-_:]');\r\nconst IGNORED_NODE = -2;\r\nfunction genId() {\r\n    return _id++;\r\n}\r\nfunction getValidTagName(element) {\r\n    if (element instanceof HTMLFormElement) {\r\n        return 'form';\r\n    }\r\n    const processedTagName = toLowerCase(element.tagName);\r\n    if (tagNameRegex.test(processedTagName)) {\r\n        return 'div';\r\n    }\r\n    return processedTagName;\r\n}\r\nfunction extractOrigin(url) {\r\n    let origin = '';\r\n    if (url.indexOf('//') > -1) {\r\n        origin = url.split('/').slice(0, 3).join('/');\r\n    }\r\n    else {\r\n        origin = url.split('/')[0];\r\n    }\r\n    origin = origin.split('?')[0];\r\n    return origin;\r\n}\r\nlet canvasService;\r\nlet canvasCtx;\r\nconst URL_IN_CSS_REF = /url\\((?:(')([^']*)'|(\")(.*?)\"|([^)]*))\\)/gm;\r\nconst URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\\/\\//i;\r\nconst URL_WWW_MATCH = /^www\\..*/i;\r\nconst DATA_URI = /^(data:)([^,]*),(.*)/i;\r\nfunction absoluteToStylesheet(cssText, href) {\r\n    return (cssText || '').replace(URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => {\r\n        const filePath = path1 || path2 || path3;\r\n        const maybeQuote = quote1 || quote2 || '';\r\n        if (!filePath) {\r\n            return origin;\r\n        }\r\n        if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {\r\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\r\n        }\r\n        if (DATA_URI.test(filePath)) {\r\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\r\n        }\r\n        if (filePath[0] === '/') {\r\n            return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;\r\n        }\r\n        const stack = href.split('/');\r\n        const parts = filePath.split('/');\r\n        stack.pop();\r\n        for (const part of parts) {\r\n            if (part === '.') {\r\n                continue;\r\n            }\r\n            else if (part === '..') {\r\n                stack.pop();\r\n            }\r\n            else {\r\n                stack.push(part);\r\n            }\r\n        }\r\n        return `url(${maybeQuote}${stack.join('/')}${maybeQuote})`;\r\n    });\r\n}\r\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\r\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\r\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\r\n    if (attributeValue.trim() === '') {\r\n        return attributeValue;\r\n    }\r\n    let pos = 0;\r\n    function collectCharacters(regEx) {\r\n        let chars;\r\n        const match = regEx.exec(attributeValue.substring(pos));\r\n        if (match) {\r\n            chars = match[0];\r\n            pos += chars.length;\r\n            return chars;\r\n        }\r\n        return '';\r\n    }\r\n    const output = [];\r\n    while (true) {\r\n        collectCharacters(SRCSET_COMMAS_OR_SPACES);\r\n        if (pos >= attributeValue.length) {\r\n            break;\r\n        }\r\n        let url = collectCharacters(SRCSET_NOT_SPACES);\r\n        if (url.slice(-1) === ',') {\r\n            url = absoluteToDoc(doc, url.substring(0, url.length - 1));\r\n            output.push(url);\r\n        }\r\n        else {\r\n            let descriptorsStr = '';\r\n            url = absoluteToDoc(doc, url);\r\n            let inParens = false;\r\n            while (true) {\r\n                const c = attributeValue.charAt(pos);\r\n                if (c === '') {\r\n                    output.push((url + descriptorsStr).trim());\r\n                    break;\r\n                }\r\n                else if (!inParens) {\r\n                    if (c === ',') {\r\n                        pos += 1;\r\n                        output.push((url + descriptorsStr).trim());\r\n                        break;\r\n                    }\r\n                    else if (c === '(') {\r\n                        inParens = true;\r\n                    }\r\n                }\r\n                else {\r\n                    if (c === ')') {\r\n                        inParens = false;\r\n                    }\r\n                }\r\n                descriptorsStr += c;\r\n                pos += 1;\r\n            }\r\n        }\r\n    }\r\n    return output.join(', ');\r\n}\r\nconst cachedDocument = new WeakMap();\r\nfunction absoluteToDoc(doc, attributeValue) {\r\n    if (!attributeValue || attributeValue.trim() === '') {\r\n        return attributeValue;\r\n    }\r\n    return getHref(doc, attributeValue);\r\n}\r\nfunction isSVGElement(el) {\r\n    return Boolean(el.tagName === 'svg' || el.ownerSVGElement);\r\n}\r\nfunction getHref(doc, customHref) {\r\n    let a = cachedDocument.get(doc);\r\n    if (!a) {\r\n        a = doc.createElement('a');\r\n        cachedDocument.set(doc, a);\r\n    }\r\n    if (!customHref) {\r\n        customHref = '';\r\n    }\r\n    else if (customHref.startsWith('blob:') || customHref.startsWith('data:')) {\r\n        return customHref;\r\n    }\r\n    a.setAttribute('href', customHref);\r\n    return a.href;\r\n}\r\nfunction transformAttribute(doc, tagName, name, value, element, maskAttributeFn) {\r\n    if (!value) {\r\n        return value;\r\n    }\r\n    if (name === 'src' ||\r\n        (name === 'href' && !(tagName === 'use' && value[0] === '#'))) {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'xlink:href' && value[0] !== '#') {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'background' &&\r\n        (tagName === 'table' || tagName === 'td' || tagName === 'th')) {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'srcset') {\r\n        return getAbsoluteSrcsetString(doc, value);\r\n    }\r\n    else if (name === 'style') {\r\n        return absoluteToStylesheet(value, getHref(doc));\r\n    }\r\n    else if (tagName === 'object' && name === 'data') {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    if (typeof maskAttributeFn === 'function') {\r\n        return maskAttributeFn(name, value, element);\r\n    }\r\n    return value;\r\n}\r\nfunction ignoreAttribute(tagName, name, _value) {\r\n    return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';\r\n}\r\nfunction _isBlockedElement(element, blockClass, blockSelector, unblockSelector) {\r\n    try {\r\n        if (unblockSelector && element.matches(unblockSelector)) {\r\n            return false;\r\n        }\r\n        if (typeof blockClass === 'string') {\r\n            if (element.classList.contains(blockClass)) {\r\n                return true;\r\n            }\r\n        }\r\n        else {\r\n            for (let eIndex = element.classList.length; eIndex--;) {\r\n                const className = element.classList[eIndex];\r\n                if (blockClass.test(className)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        if (blockSelector) {\r\n            return element.matches(blockSelector);\r\n        }\r\n    }\r\n    catch (e) {\r\n    }\r\n    return false;\r\n}\r\nfunction elementClassMatchesRegex(el, regex) {\r\n    for (let eIndex = el.classList.length; eIndex--;) {\r\n        const className = el.classList[eIndex];\r\n        if (regex.test(className)) {\r\n            return true;\r\n        }\r\n    }\r\n    return false;\r\n}\r\nfunction distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {\r\n    if (!node)\r\n        return -1;\r\n    if (node.nodeType !== node.ELEMENT_NODE)\r\n        return -1;\r\n    if (distance > limit)\r\n        return -1;\r\n    if (matchPredicate(node))\r\n        return distance;\r\n    return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);\r\n}\r\nfunction createMatchPredicate(className, selector) {\r\n    return (node) => {\r\n        const el = node;\r\n        if (el === null)\r\n            return false;\r\n        try {\r\n            if (className) {\r\n                if (typeof className === 'string') {\r\n                    if (el.matches(`.${className}`))\r\n                        return true;\r\n                }\r\n                else if (elementClassMatchesRegex(el, className)) {\r\n                    return true;\r\n                }\r\n            }\r\n            if (selector && el.matches(selector))\r\n                return true;\r\n            return false;\r\n        }\r\n        catch {\r\n            return false;\r\n        }\r\n    };\r\n}\r\nfunction needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText) {\r\n    try {\r\n        const el = node.nodeType === node.ELEMENT_NODE\r\n            ? node\r\n            : node.parentElement;\r\n        if (el === null)\r\n            return false;\r\n        if (el.tagName === 'INPUT') {\r\n            const autocomplete = el.getAttribute('autocomplete');\r\n            const disallowedAutocompleteValues = [\r\n                'current-password',\r\n                'new-password',\r\n                'cc-number',\r\n                'cc-exp',\r\n                'cc-exp-month',\r\n                'cc-exp-year',\r\n                'cc-csc',\r\n            ];\r\n            if (disallowedAutocompleteValues.includes(autocomplete)) {\r\n                return true;\r\n            }\r\n        }\r\n        let maskDistance = -1;\r\n        let unmaskDistance = -1;\r\n        if (maskAllText) {\r\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector));\r\n            if (unmaskDistance < 0) {\r\n                return true;\r\n            }\r\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector), unmaskDistance >= 0 ? unmaskDistance : Infinity);\r\n        }\r\n        else {\r\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector));\r\n            if (maskDistance < 0) {\r\n                return false;\r\n            }\r\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector), maskDistance >= 0 ? maskDistance : Infinity);\r\n        }\r\n        return maskDistance >= 0\r\n            ? unmaskDistance >= 0\r\n                ? maskDistance <= unmaskDistance\r\n                : true\r\n            : unmaskDistance >= 0\r\n                ? false\r\n                : !!maskAllText;\r\n    }\r\n    catch (e) {\r\n    }\r\n    return !!maskAllText;\r\n}\r\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\r\n    const win = iframeEl.contentWindow;\r\n    if (!win) {\r\n        return;\r\n    }\r\n    let fired = false;\r\n    let readyState;\r\n    try {\r\n        readyState = win.document.readyState;\r\n    }\r\n    catch (error) {\r\n        return;\r\n    }\r\n    if (readyState !== 'complete') {\r\n        const timer = setTimeout(() => {\r\n            if (!fired) {\r\n                listener();\r\n                fired = true;\r\n            }\r\n        }, iframeLoadTimeout);\r\n        iframeEl.addEventListener('load', () => {\r\n            clearTimeout(timer);\r\n            fired = true;\r\n            listener();\r\n        });\r\n        return;\r\n    }\r\n    const blankUrl = 'about:blank';\r\n    if (win.location.href !== blankUrl ||\r\n        iframeEl.src === blankUrl ||\r\n        iframeEl.src === '') {\r\n        setTimeout(listener, 0);\r\n        return iframeEl.addEventListener('load', listener);\r\n    }\r\n    iframeEl.addEventListener('load', listener);\r\n}\r\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\r\n    let fired = false;\r\n    let styleSheetLoaded;\r\n    try {\r\n        styleSheetLoaded = link.sheet;\r\n    }\r\n    catch (error) {\r\n        return;\r\n    }\r\n    if (styleSheetLoaded)\r\n        return;\r\n    const timer = setTimeout(() => {\r\n        if (!fired) {\r\n            listener();\r\n            fired = true;\r\n        }\r\n    }, styleSheetLoadTimeout);\r\n    link.addEventListener('load', () => {\r\n        clearTimeout(timer);\r\n        fired = true;\r\n        listener();\r\n    });\r\n}\r\nfunction serializeNode(n, options) {\r\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskAttributeFn, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, } = options;\r\n    const rootId = getRootId(doc, mirror);\r\n    switch (n.nodeType) {\r\n        case n.DOCUMENT_NODE:\r\n            if (n.compatMode !== 'CSS1Compat') {\r\n                return {\r\n                    type: NodeType.Document,\r\n                    childNodes: [],\r\n                    compatMode: n.compatMode,\r\n                };\r\n            }\r\n            else {\r\n                return {\r\n                    type: NodeType.Document,\r\n                    childNodes: [],\r\n                };\r\n            }\r\n        case n.DOCUMENT_TYPE_NODE:\r\n            return {\r\n                type: NodeType.DocumentType,\r\n                name: n.name,\r\n                publicId: n.publicId,\r\n                systemId: n.systemId,\r\n                rootId,\r\n            };\r\n        case n.ELEMENT_NODE:\r\n            return serializeElementNode(n, {\r\n                doc,\r\n                blockClass,\r\n                blockSelector,\r\n                unblockSelector,\r\n                inlineStylesheet,\r\n                maskAttributeFn,\r\n                maskInputOptions,\r\n                maskInputFn,\r\n                dataURLOptions,\r\n                inlineImages,\r\n                recordCanvas,\r\n                keepIframeSrcFn,\r\n                newlyAddedElement,\r\n                rootId,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n            });\r\n        case n.TEXT_NODE:\r\n            return serializeTextNode(n, {\r\n                doc,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n                maskTextFn,\r\n                maskInputOptions,\r\n                maskInputFn,\r\n                rootId,\r\n            });\r\n        case n.CDATA_SECTION_NODE:\r\n            return {\r\n                type: NodeType.CDATA,\r\n                textContent: '',\r\n                rootId,\r\n            };\r\n        case n.COMMENT_NODE:\r\n            return {\r\n                type: NodeType.Comment,\r\n                textContent: n.textContent || '',\r\n                rootId,\r\n            };\r\n        default:\r\n            return false;\r\n    }\r\n}\r\nfunction getRootId(doc, mirror) {\r\n    if (!mirror.hasNode(doc))\r\n        return undefined;\r\n    const docId = mirror.getId(doc);\r\n    return docId === 1 ? undefined : docId;\r\n}\r\nfunction serializeTextNode(n, options) {\r\n    const { maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, maskTextFn, maskInputOptions, maskInputFn, rootId, } = options;\r\n    const parentTagName = n.parentNode && n.parentNode.tagName;\r\n    let textContent = n.textContent;\r\n    const isStyle = parentTagName === 'STYLE' ? true : undefined;\r\n    const isScript = parentTagName === 'SCRIPT' ? true : undefined;\r\n    const isTextarea = parentTagName === 'TEXTAREA' ? true : undefined;\r\n    if (isStyle && textContent) {\r\n        try {\r\n            if (n.nextSibling || n.previousSibling) {\r\n            }\r\n            else if (n.parentNode.sheet?.cssRules) {\r\n                textContent = stringifyStylesheet(n.parentNode.sheet);\r\n            }\r\n        }\r\n        catch (err) {\r\n            console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);\r\n        }\r\n        textContent = absoluteToStylesheet(textContent, getHref(options.doc));\r\n    }\r\n    if (isScript) {\r\n        textContent = 'SCRIPT_PLACEHOLDER';\r\n    }\r\n    const forceMask = needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText);\r\n    if (!isStyle && !isScript && !isTextarea && textContent && forceMask) {\r\n        textContent = maskTextFn\r\n            ? maskTextFn(textContent, n.parentElement)\r\n            : textContent.replace(/[\\S]/g, '*');\r\n    }\r\n    if (isTextarea && textContent && (maskInputOptions.textarea || forceMask)) {\r\n        textContent = maskInputFn\r\n            ? maskInputFn(textContent, n.parentNode)\r\n            : textContent.replace(/[\\S]/g, '*');\r\n    }\r\n    if (parentTagName === 'OPTION' && textContent) {\r\n        const isInputMasked = shouldMaskInput({\r\n            type: null,\r\n            tagName: parentTagName,\r\n            maskInputOptions,\r\n        });\r\n        textContent = maskInputValue({\r\n            isMasked: needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked),\r\n            element: n,\r\n            value: textContent,\r\n            maskInputFn,\r\n        });\r\n    }\r\n    return {\r\n        type: NodeType.Text,\r\n        textContent: textContent || '',\r\n        isStyle,\r\n        rootId,\r\n    };\r\n}\r\nfunction serializeElementNode(n, options) {\r\n    const { doc, blockClass, blockSelector, unblockSelector, inlineStylesheet, maskInputOptions = {}, maskAttributeFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, } = options;\r\n    const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);\r\n    const tagName = getValidTagName(n);\r\n    let attributes = {};\r\n    const len = n.attributes.length;\r\n    for (let i = 0; i < len; i++) {\r\n        const attr = n.attributes[i];\r\n        if (attr.name && !ignoreAttribute(tagName, attr.name, attr.value)) {\r\n            attributes[attr.name] = transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value, n, maskAttributeFn);\r\n        }\r\n    }\r\n    if (tagName === 'link' && inlineStylesheet) {\r\n        const stylesheet = Array.from(doc.styleSheets).find((s) => {\r\n            return s.href === n.href;\r\n        });\r\n        let cssText = null;\r\n        if (stylesheet) {\r\n            cssText = stringifyStylesheet(stylesheet);\r\n        }\r\n        if (cssText) {\r\n            attributes.rel = null;\r\n            attributes.href = null;\r\n            attributes.crossorigin = null;\r\n            attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);\r\n        }\r\n    }\r\n    if (tagName === 'style' &&\r\n        n.sheet &&\r\n        !(n.innerText || n.textContent || '').trim().length) {\r\n        const cssText = stringifyStylesheet(n.sheet);\r\n        if (cssText) {\r\n            attributes._cssText = absoluteToStylesheet(cssText, getHref(doc));\r\n        }\r\n    }\r\n    if (tagName === 'input' ||\r\n        tagName === 'textarea' ||\r\n        tagName === 'select' ||\r\n        tagName === 'option') {\r\n        const el = n;\r\n        const type = getInputType(el);\r\n        const value = getInputValue(el, toUpperCase(tagName), type);\r\n        const checked = el.checked;\r\n        if (type !== 'submit' && type !== 'button' && value) {\r\n            const forceMask = needMaskingText(el, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, shouldMaskInput({\r\n                type,\r\n                tagName: toUpperCase(tagName),\r\n                maskInputOptions,\r\n            }));\r\n            attributes.value = maskInputValue({\r\n                isMasked: forceMask,\r\n                element: el,\r\n                value,\r\n                maskInputFn,\r\n            });\r\n        }\r\n        if (checked) {\r\n            attributes.checked = checked;\r\n        }\r\n    }\r\n    if (tagName === 'option') {\r\n        if (n.selected && !maskInputOptions['select']) {\r\n            attributes.selected = true;\r\n        }\r\n        else {\r\n            delete attributes.selected;\r\n        }\r\n    }\r\n    if (tagName === 'canvas' && recordCanvas) {\r\n        if (n.__context === '2d') {\r\n            if (!is2DCanvasBlank(n)) {\r\n                attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            }\r\n        }\r\n        else if (!('__context' in n)) {\r\n            const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            const blankCanvas = doc.createElement('canvas');\r\n            blankCanvas.width = n.width;\r\n            blankCanvas.height = n.height;\r\n            const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            if (canvasDataURL !== blankCanvasDataURL) {\r\n                attributes.rr_dataURL = canvasDataURL;\r\n            }\r\n        }\r\n    }\r\n    if (tagName === 'img' && inlineImages) {\r\n        if (!canvasService) {\r\n            canvasService = doc.createElement('canvas');\r\n            canvasCtx = canvasService.getContext('2d');\r\n        }\r\n        const image = n;\r\n        const imageSrc = image.currentSrc || image.getAttribute('src') || '<unknown-src>';\r\n        const priorCrossOrigin = image.crossOrigin;\r\n        const recordInlineImage = () => {\r\n            image.removeEventListener('load', recordInlineImage);\r\n            try {\r\n                canvasService.width = image.naturalWidth;\r\n                canvasService.height = image.naturalHeight;\r\n                canvasCtx.drawImage(image, 0, 0);\r\n                attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            }\r\n            catch (err) {\r\n                if (image.crossOrigin !== 'anonymous') {\r\n                    image.crossOrigin = 'anonymous';\r\n                    if (image.complete && image.naturalWidth !== 0)\r\n                        recordInlineImage();\r\n                    else\r\n                        image.addEventListener('load', recordInlineImage);\r\n                    return;\r\n                }\r\n                else {\r\n                    console.warn(`Cannot inline img src=${imageSrc}! Error: ${err}`);\r\n                }\r\n            }\r\n            if (image.crossOrigin === 'anonymous') {\r\n                priorCrossOrigin\r\n                    ? (attributes.crossOrigin = priorCrossOrigin)\r\n                    : image.removeAttribute('crossorigin');\r\n            }\r\n        };\r\n        if (image.complete && image.naturalWidth !== 0)\r\n            recordInlineImage();\r\n        else\r\n            image.addEventListener('load', recordInlineImage);\r\n    }\r\n    if (tagName === 'audio' || tagName === 'video') {\r\n        attributes.rr_mediaState = n.paused\r\n            ? 'paused'\r\n            : 'played';\r\n        attributes.rr_mediaCurrentTime = n.currentTime;\r\n    }\r\n    if (!newlyAddedElement) {\r\n        if (n.scrollLeft) {\r\n            attributes.rr_scrollLeft = n.scrollLeft;\r\n        }\r\n        if (n.scrollTop) {\r\n            attributes.rr_scrollTop = n.scrollTop;\r\n        }\r\n    }\r\n    if (needBlock) {\r\n        const { width, height } = n.getBoundingClientRect();\r\n        attributes = {\r\n            class: attributes.class,\r\n            rr_width: `${width}px`,\r\n            rr_height: `${height}px`,\r\n        };\r\n    }\r\n    if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {\r\n        if (!needBlock && !getIframeContentDocument(n)) {\r\n            attributes.rr_src = attributes.src;\r\n        }\r\n        delete attributes.src;\r\n    }\r\n    let isCustomElement;\r\n    try {\r\n        if (customElements.get(tagName))\r\n            isCustomElement = true;\r\n    }\r\n    catch (e) {\r\n    }\r\n    return {\r\n        type: NodeType.Element,\r\n        tagName,\r\n        attributes,\r\n        childNodes: [],\r\n        isSVG: isSVGElement(n) || undefined,\r\n        needBlock,\r\n        rootId,\r\n        isCustom: isCustomElement,\r\n    };\r\n}\r\nfunction lowerIfExists(maybeAttr) {\r\n    if (maybeAttr === undefined || maybeAttr === null) {\r\n        return '';\r\n    }\r\n    else {\r\n        return maybeAttr.toLowerCase();\r\n    }\r\n}\r\nfunction slimDOMExcluded(sn, slimDOMOptions) {\r\n    if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\r\n        return true;\r\n    }\r\n    else if (sn.type === NodeType.Element) {\r\n        if (slimDOMOptions.script &&\r\n            (sn.tagName === 'script' ||\r\n                (sn.tagName === 'link' &&\r\n                    (sn.attributes.rel === 'preload' ||\r\n                        sn.attributes.rel === 'modulepreload')) ||\r\n                (sn.tagName === 'link' &&\r\n                    sn.attributes.rel === 'prefetch' &&\r\n                    typeof sn.attributes.href === 'string' &&\r\n                    extractFileExtension(sn.attributes.href) === 'js'))) {\r\n            return true;\r\n        }\r\n        else if (slimDOMOptions.headFavicon &&\r\n            ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||\r\n                (sn.tagName === 'meta' &&\r\n                    (lowerIfExists(sn.attributes.name).match(/^msapplication-tile(image|color)$/) ||\r\n                        lowerIfExists(sn.attributes.name) === 'application-name' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'icon' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'shortcut icon')))) {\r\n            return true;\r\n        }\r\n        else if (sn.tagName === 'meta') {\r\n            if (slimDOMOptions.headMetaDescKeywords &&\r\n                lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaSocial &&\r\n                (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) ||\r\n                    lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||\r\n                    lowerIfExists(sn.attributes.name) === 'pinterest')) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaRobots &&\r\n                (lowerIfExists(sn.attributes.name) === 'robots' ||\r\n                    lowerIfExists(sn.attributes.name) === 'googlebot' ||\r\n                    lowerIfExists(sn.attributes.name) === 'bingbot')) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaHttpEquiv &&\r\n                sn.attributes['http-equiv'] !== undefined) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaAuthorship &&\r\n                (lowerIfExists(sn.attributes.name) === 'author' ||\r\n                    lowerIfExists(sn.attributes.name) === 'generator' ||\r\n                    lowerIfExists(sn.attributes.name) === 'framework' ||\r\n                    lowerIfExists(sn.attributes.name) === 'publisher' ||\r\n                    lowerIfExists(sn.attributes.name) === 'progid' ||\r\n                    lowerIfExists(sn.attributes.property).match(/^article:/) ||\r\n                    lowerIfExists(sn.attributes.property).match(/^product:/))) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaVerification &&\r\n                (lowerIfExists(sn.attributes.name) === 'google-site-verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'yandex-verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'csrf-token' ||\r\n                    lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||\r\n                    lowerIfExists(sn.attributes.name) === 'verify-v1' ||\r\n                    lowerIfExists(sn.attributes.name) === 'verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')) {\r\n                return true;\r\n            }\r\n        }\r\n    }\r\n    return false;\r\n}\r\nfunction serializeNodeWithId(n, options) {\r\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, skipChild = false, inlineStylesheet = true, maskInputOptions = {}, maskAttributeFn, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5000, onStylesheetLoad, stylesheetLoadTimeout = 5000, keepIframeSrcFn = () => false, newlyAddedElement = false, } = options;\r\n    let { preserveWhiteSpace = true } = options;\r\n    const _serializedNode = serializeNode(n, {\r\n        doc,\r\n        mirror,\r\n        blockClass,\r\n        blockSelector,\r\n        maskAllText,\r\n        unblockSelector,\r\n        maskTextClass,\r\n        unmaskTextClass,\r\n        maskTextSelector,\r\n        unmaskTextSelector,\r\n        inlineStylesheet,\r\n        maskInputOptions,\r\n        maskAttributeFn,\r\n        maskTextFn,\r\n        maskInputFn,\r\n        dataURLOptions,\r\n        inlineImages,\r\n        recordCanvas,\r\n        keepIframeSrcFn,\r\n        newlyAddedElement,\r\n    });\r\n    if (!_serializedNode) {\r\n        console.warn(n, 'not serialized');\r\n        return null;\r\n    }\r\n    let id;\r\n    if (mirror.hasNode(n)) {\r\n        id = mirror.getId(n);\r\n    }\r\n    else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||\r\n        (!preserveWhiteSpace &&\r\n            _serializedNode.type === NodeType.Text &&\r\n            !_serializedNode.isStyle &&\r\n            !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, '').length)) {\r\n        id = IGNORED_NODE;\r\n    }\r\n    else {\r\n        id = genId();\r\n    }\r\n    const serializedNode = Object.assign(_serializedNode, { id });\r\n    mirror.add(n, serializedNode);\r\n    if (id === IGNORED_NODE) {\r\n        return null;\r\n    }\r\n    if (onSerialize) {\r\n        onSerialize(n);\r\n    }\r\n    let recordChild = !skipChild;\r\n    if (serializedNode.type === NodeType.Element) {\r\n        recordChild = recordChild && !serializedNode.needBlock;\r\n        delete serializedNode.needBlock;\r\n        const shadowRoot = n.shadowRoot;\r\n        if (shadowRoot && isNativeShadowDom(shadowRoot))\r\n            serializedNode.isShadowHost = true;\r\n    }\r\n    if ((serializedNode.type === NodeType.Document ||\r\n        serializedNode.type === NodeType.Element) &&\r\n        recordChild) {\r\n        if (slimDOMOptions.headWhitespace &&\r\n            serializedNode.type === NodeType.Element &&\r\n            serializedNode.tagName === 'head') {\r\n            preserveWhiteSpace = false;\r\n        }\r\n        const bypassOptions = {\r\n            doc,\r\n            mirror,\r\n            blockClass,\r\n            blockSelector,\r\n            maskAllText,\r\n            unblockSelector,\r\n            maskTextClass,\r\n            unmaskTextClass,\r\n            maskTextSelector,\r\n            unmaskTextSelector,\r\n            skipChild,\r\n            inlineStylesheet,\r\n            maskInputOptions,\r\n            maskAttributeFn,\r\n            maskTextFn,\r\n            maskInputFn,\r\n            slimDOMOptions,\r\n            dataURLOptions,\r\n            inlineImages,\r\n            recordCanvas,\r\n            preserveWhiteSpace,\r\n            onSerialize,\r\n            onIframeLoad,\r\n            iframeLoadTimeout,\r\n            onStylesheetLoad,\r\n            stylesheetLoadTimeout,\r\n            keepIframeSrcFn,\r\n        };\r\n        for (const childN of Array.from(n.childNodes)) {\r\n            const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\r\n            if (serializedChildNode) {\r\n                serializedNode.childNodes.push(serializedChildNode);\r\n            }\r\n        }\r\n        if (isElement(n) && n.shadowRoot) {\r\n            for (const childN of Array.from(n.shadowRoot.childNodes)) {\r\n                const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\r\n                if (serializedChildNode) {\r\n                    isNativeShadowDom(n.shadowRoot) &&\r\n                        (serializedChildNode.isShadow = true);\r\n                    serializedNode.childNodes.push(serializedChildNode);\r\n                }\r\n            }\r\n        }\r\n    }\r\n    if (n.parentNode &&\r\n        isShadowRoot(n.parentNode) &&\r\n        isNativeShadowDom(n.parentNode)) {\r\n        serializedNode.isShadow = true;\r\n    }\r\n    if (serializedNode.type === NodeType.Element &&\r\n        serializedNode.tagName === 'iframe') {\r\n        onceIframeLoaded(n, () => {\r\n            const iframeDoc = getIframeContentDocument(n);\r\n            if (iframeDoc && onIframeLoad) {\r\n                const serializedIframeNode = serializeNodeWithId(iframeDoc, {\r\n                    doc: iframeDoc,\r\n                    mirror,\r\n                    blockClass,\r\n                    blockSelector,\r\n                    unblockSelector,\r\n                    maskAllText,\r\n                    maskTextClass,\r\n                    unmaskTextClass,\r\n                    maskTextSelector,\r\n                    unmaskTextSelector,\r\n                    skipChild: false,\r\n                    inlineStylesheet,\r\n                    maskInputOptions,\r\n                    maskAttributeFn,\r\n                    maskTextFn,\r\n                    maskInputFn,\r\n                    slimDOMOptions,\r\n                    dataURLOptions,\r\n                    inlineImages,\r\n                    recordCanvas,\r\n                    preserveWhiteSpace,\r\n                    onSerialize,\r\n                    onIframeLoad,\r\n                    iframeLoadTimeout,\r\n                    onStylesheetLoad,\r\n                    stylesheetLoadTimeout,\r\n                    keepIframeSrcFn,\r\n                });\r\n                if (serializedIframeNode) {\r\n                    onIframeLoad(n, serializedIframeNode);\r\n                }\r\n            }\r\n        }, iframeLoadTimeout);\r\n    }\r\n    if (serializedNode.type === NodeType.Element &&\r\n        serializedNode.tagName === 'link' &&\r\n        typeof serializedNode.attributes.rel === 'string' &&\r\n        (serializedNode.attributes.rel === 'stylesheet' ||\r\n            (serializedNode.attributes.rel === 'preload' &&\r\n                typeof serializedNode.attributes.href === 'string' &&\r\n                extractFileExtension(serializedNode.attributes.href) === 'css'))) {\r\n        onceStylesheetLoaded(n, () => {\r\n            if (onStylesheetLoad) {\r\n                const serializedLinkNode = serializeNodeWithId(n, {\r\n                    doc,\r\n                    mirror,\r\n                    blockClass,\r\n                    blockSelector,\r\n                    unblockSelector,\r\n                    maskAllText,\r\n                    maskTextClass,\r\n                    unmaskTextClass,\r\n                    maskTextSelector,\r\n                    unmaskTextSelector,\r\n                    skipChild: false,\r\n                    inlineStylesheet,\r\n                    maskInputOptions,\r\n                    maskAttributeFn,\r\n                    maskTextFn,\r\n                    maskInputFn,\r\n                    slimDOMOptions,\r\n                    dataURLOptions,\r\n                    inlineImages,\r\n                    recordCanvas,\r\n                    preserveWhiteSpace,\r\n                    onSerialize,\r\n                    onIframeLoad,\r\n                    iframeLoadTimeout,\r\n                    onStylesheetLoad,\r\n                    stylesheetLoadTimeout,\r\n                    keepIframeSrcFn,\r\n                });\r\n                if (serializedLinkNode) {\r\n                    onStylesheetLoad(n, serializedLinkNode);\r\n                }\r\n            }\r\n        }, stylesheetLoadTimeout);\r\n    }\r\n    return serializedNode;\r\n}\r\nfunction snapshot(n, options) {\r\n    const { mirror = new Mirror(), blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskAllInputs = false, maskAttributeFn, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn = () => false, } = options || {};\r\n    const maskInputOptions = maskAllInputs === true\r\n        ? {\r\n            color: true,\r\n            date: true,\r\n            'datetime-local': true,\r\n            email: true,\r\n            month: true,\r\n            number: true,\r\n            range: true,\r\n            search: true,\r\n            tel: true,\r\n            text: true,\r\n            time: true,\r\n            url: true,\r\n            week: true,\r\n            textarea: true,\r\n            select: true,\r\n        }\r\n        : maskAllInputs === false\r\n            ? {}\r\n            : maskAllInputs;\r\n    const slimDOMOptions = slimDOM === true || slimDOM === 'all'\r\n        ?\r\n            {\r\n                script: true,\r\n                comment: true,\r\n                headFavicon: true,\r\n                headWhitespace: true,\r\n                headMetaDescKeywords: slimDOM === 'all',\r\n                headMetaSocial: true,\r\n                headMetaRobots: true,\r\n                headMetaHttpEquiv: true,\r\n                headMetaAuthorship: true,\r\n                headMetaVerification: true,\r\n            }\r\n        : slimDOM === false\r\n            ? {}\r\n            : slimDOM;\r\n    return serializeNodeWithId(n, {\r\n        doc: n,\r\n        mirror,\r\n        blockClass,\r\n        blockSelector,\r\n        unblockSelector,\r\n        maskAllText,\r\n        maskTextClass,\r\n        unmaskTextClass,\r\n        maskTextSelector,\r\n        unmaskTextSelector,\r\n        skipChild: false,\r\n        inlineStylesheet,\r\n        maskInputOptions,\r\n        maskAttributeFn,\r\n        maskTextFn,\r\n        maskInputFn,\r\n        slimDOMOptions,\r\n        dataURLOptions,\r\n        inlineImages,\r\n        recordCanvas,\r\n        preserveWhiteSpace,\r\n        onSerialize,\r\n        onIframeLoad,\r\n        iframeLoadTimeout,\r\n        onStylesheetLoad,\r\n        stylesheetLoadTimeout,\r\n        keepIframeSrcFn,\r\n        newlyAddedElement: false,\r\n    });\r\n}\r\n\nconst commentre = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g;\r\nfunction parse(css, options = {}) {\r\n    let lineno = 1;\r\n    let column = 1;\r\n    function updatePosition(str) {\r\n        const lines = str.match(/\\n/g);\r\n        if (lines) {\r\n            lineno += lines.length;\r\n        }\r\n        const i = str.lastIndexOf('\\n');\r\n        column = i === -1 ? column + str.length : str.length - i;\r\n    }\r\n    function position() {\r\n        const start = { line: lineno, column };\r\n        return (node) => {\r\n            node.position = new Position(start);\r\n            whitespace();\r\n            return node;\r\n        };\r\n    }\r\n    class Position {\r\n        constructor(start) {\r\n            this.start = start;\r\n            this.end = { line: lineno, column };\r\n            this.source = options.source;\r\n        }\r\n    }\r\n    Position.prototype.content = css;\r\n    const errorsList = [];\r\n    function error(msg) {\r\n        const err = new Error(`${options.source || ''}:${lineno}:${column}: ${msg}`);\r\n        err.reason = msg;\r\n        err.filename = options.source;\r\n        err.line = lineno;\r\n        err.column = column;\r\n        err.source = css;\r\n        if (options.silent) {\r\n            errorsList.push(err);\r\n        }\r\n        else {\r\n            throw err;\r\n        }\r\n    }\r\n    function stylesheet() {\r\n        const rulesList = rules();\r\n        return {\r\n            type: 'stylesheet',\r\n            stylesheet: {\r\n                source: options.source,\r\n                rules: rulesList,\r\n                parsingErrors: errorsList,\r\n            },\r\n        };\r\n    }\r\n    function open() {\r\n        return match(/^{\\s*/);\r\n    }\r\n    function close() {\r\n        return match(/^}/);\r\n    }\r\n    function rules() {\r\n        let node;\r\n        const rules = [];\r\n        whitespace();\r\n        comments(rules);\r\n        while (css.length && css.charAt(0) !== '}' && (node = atrule() || rule())) {\r\n            if (node) {\r\n                rules.push(node);\r\n                comments(rules);\r\n            }\r\n        }\r\n        return rules;\r\n    }\r\n    function match(re) {\r\n        const m = re.exec(css);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const str = m[0];\r\n        updatePosition(str);\r\n        css = css.slice(str.length);\r\n        return m;\r\n    }\r\n    function whitespace() {\r\n        match(/^\\s*/);\r\n    }\r\n    function comments(rules = []) {\r\n        let c;\r\n        while ((c = comment())) {\r\n            if (c) {\r\n                rules.push(c);\r\n            }\r\n            c = comment();\r\n        }\r\n        return rules;\r\n    }\r\n    function comment() {\r\n        const pos = position();\r\n        if ('/' !== css.charAt(0) || '*' !== css.charAt(1)) {\r\n            return;\r\n        }\r\n        let i = 2;\r\n        while ('' !== css.charAt(i) &&\r\n            ('*' !== css.charAt(i) || '/' !== css.charAt(i + 1))) {\r\n            ++i;\r\n        }\r\n        i += 2;\r\n        if ('' === css.charAt(i - 1)) {\r\n            return error('End of comment missing');\r\n        }\r\n        const str = css.slice(2, i - 2);\r\n        column += 2;\r\n        updatePosition(str);\r\n        css = css.slice(i);\r\n        column += 2;\r\n        return pos({\r\n            type: 'comment',\r\n            comment: str,\r\n        });\r\n    }\r\n    function selector() {\r\n        const m = match(/^([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const splitSelectors = trim(m[0])\r\n            .replace(/\\/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*\\/+/g, '')\r\n            .replace(/\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'/g, (m) => {\r\n            return m.replace(/,/g, '\\u200C');\r\n        })\r\n            .split(/\\s*(?![^(]*\\)),\\s*/);\r\n        if (splitSelectors.length <= 1) {\r\n            return splitSelectors.map((s) => {\r\n                return s.replace(/\\u200C/g, ',');\r\n            });\r\n        }\r\n        let i = 0;\r\n        let j = 0;\r\n        const len = splitSelectors.length;\r\n        const finalSelectors = [];\r\n        while (i < len) {\r\n            const openingParensCount = (splitSelectors[i].match(/\\(/g) || []).length;\r\n            const closingParensCount = (splitSelectors[i].match(/\\)/g) || []).length;\r\n            let unbalancedParens = openingParensCount - closingParensCount;\r\n            if (unbalancedParens >= 1) {\r\n                let foundClosingSelector = false;\r\n                j = i + 1;\r\n                while (j < len) {\r\n                    const nextOpeningParensCount = (splitSelectors[j].match(/\\(/g) || [])\r\n                        .length;\r\n                    const nextClosingParensCount = (splitSelectors[j].match(/\\)/g) || [])\r\n                        .length;\r\n                    const nextUnbalancedParens = nextClosingParensCount - nextOpeningParensCount;\r\n                    if (nextUnbalancedParens === unbalancedParens) {\r\n                        finalSelectors.push(splitSelectors.slice(i, j + 1).join(','));\r\n                        i = j + 1;\r\n                        foundClosingSelector = true;\r\n                        break;\r\n                    }\r\n                    j++;\r\n                    unbalancedParens -= nextUnbalancedParens;\r\n                }\r\n                if (foundClosingSelector) {\r\n                    continue;\r\n                }\r\n                splitSelectors\r\n                    .slice(i, len)\r\n                    .forEach((selector) => selector && finalSelectors.push(selector));\r\n                break;\r\n            }\r\n            splitSelectors[i] && finalSelectors.push(splitSelectors[i]);\r\n            i++;\r\n        }\r\n        return finalSelectors.map((s) => {\r\n            return s.replace(/\\u200C/g, ',');\r\n        });\r\n    }\r\n    function declaration() {\r\n        const pos = position();\r\n        const propMatch = match(/^(\\*?[-#\\/\\*\\\\\\w]+(\\[[0-9a-z_-]+\\])?)\\s*/);\r\n        if (!propMatch) {\r\n            return;\r\n        }\r\n        const prop = trim(propMatch[0]);\r\n        if (!match(/^:\\s*/)) {\r\n            return error(`property missing ':'`);\r\n        }\r\n        const val = match(/^((?:'(?:\\\\'|.)*?'|\"(?:\\\\\"|.)*?\"|\\([^\\)]*?\\)|[^};])+)/);\r\n        const ret = pos({\r\n            type: 'declaration',\r\n            property: prop.replace(commentre, ''),\r\n            value: val ? trim(val[0]).replace(commentre, '') : '',\r\n        });\r\n        match(/^[;\\s]*/);\r\n        return ret;\r\n    }\r\n    function declarations() {\r\n        const decls = [];\r\n        if (!open()) {\r\n            return error(`missing '{'`);\r\n        }\r\n        comments(decls);\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            if (decl !== false) {\r\n                decls.push(decl);\r\n                comments(decls);\r\n            }\r\n            decl = declaration();\r\n        }\r\n        if (!close()) {\r\n            return error(`missing '}'`);\r\n        }\r\n        return decls;\r\n    }\r\n    function keyframe() {\r\n        let m;\r\n        const vals = [];\r\n        const pos = position();\r\n        while ((m = match(/^((\\d+\\.\\d+|\\.\\d+|\\d+)%?|[a-z]+)\\s*/))) {\r\n            vals.push(m[1]);\r\n            match(/^,\\s*/);\r\n        }\r\n        if (!vals.length) {\r\n            return;\r\n        }\r\n        return pos({\r\n            type: 'keyframe',\r\n            values: vals,\r\n            declarations: declarations(),\r\n        });\r\n    }\r\n    function atkeyframes() {\r\n        const pos = position();\r\n        let m = match(/^@([-\\w]+)?keyframes\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const vendor = m[1];\r\n        m = match(/^([-\\w]+)\\s*/);\r\n        if (!m) {\r\n            return error('@keyframes missing name');\r\n        }\r\n        const name = m[1];\r\n        if (!open()) {\r\n            return error(`@keyframes missing '{'`);\r\n        }\r\n        let frame;\r\n        let frames = comments();\r\n        while ((frame = keyframe())) {\r\n            frames.push(frame);\r\n            frames = frames.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@keyframes missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'keyframes',\r\n            name,\r\n            vendor,\r\n            keyframes: frames,\r\n        });\r\n    }\r\n    function atsupports() {\r\n        const pos = position();\r\n        const m = match(/^@supports *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const supports = trim(m[1]);\r\n        if (!open()) {\r\n            return error(`@supports missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@supports missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'supports',\r\n            supports,\r\n            rules: style,\r\n        });\r\n    }\r\n    function athost() {\r\n        const pos = position();\r\n        const m = match(/^@host\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        if (!open()) {\r\n            return error(`@host missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@host missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'host',\r\n            rules: style,\r\n        });\r\n    }\r\n    function atmedia() {\r\n        const pos = position();\r\n        const m = match(/^@media *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const media = trim(m[1]);\r\n        if (!open()) {\r\n            return error(`@media missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@media missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'media',\r\n            media,\r\n            rules: style,\r\n        });\r\n    }\r\n    function atcustommedia() {\r\n        const pos = position();\r\n        const m = match(/^@custom-media\\s+(--[^\\s]+)\\s*([^{;]+);/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        return pos({\r\n            type: 'custom-media',\r\n            name: trim(m[1]),\r\n            media: trim(m[2]),\r\n        });\r\n    }\r\n    function atpage() {\r\n        const pos = position();\r\n        const m = match(/^@page */);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const sel = selector() || [];\r\n        if (!open()) {\r\n            return error(`@page missing '{'`);\r\n        }\r\n        let decls = comments();\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            decls.push(decl);\r\n            decls = decls.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@page missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'page',\r\n            selectors: sel,\r\n            declarations: decls,\r\n        });\r\n    }\r\n    function atdocument() {\r\n        const pos = position();\r\n        const m = match(/^@([-\\w]+)?document *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const vendor = trim(m[1]);\r\n        const doc = trim(m[2]);\r\n        if (!open()) {\r\n            return error(`@document missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@document missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'document',\r\n            document: doc,\r\n            vendor,\r\n            rules: style,\r\n        });\r\n    }\r\n    function atfontface() {\r\n        const pos = position();\r\n        const m = match(/^@font-face\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        if (!open()) {\r\n            return error(`@font-face missing '{'`);\r\n        }\r\n        let decls = comments();\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            decls.push(decl);\r\n            decls = decls.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@font-face missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'font-face',\r\n            declarations: decls,\r\n        });\r\n    }\r\n    const atimport = _compileAtrule('import');\r\n    const atcharset = _compileAtrule('charset');\r\n    const atnamespace = _compileAtrule('namespace');\r\n    function _compileAtrule(name) {\r\n        const re = new RegExp('^@' +\r\n            name +\r\n            '\\\\s*((?:' +\r\n            [\r\n                /[^\\\\]\"(?:\\\\\"|[^\"])*\"/.source,\r\n                /[^\\\\]'(?:\\\\'|[^'])*'/.source,\r\n                '[^;]',\r\n            ].join('|') +\r\n            ')+);');\r\n        return () => {\r\n            const pos = position();\r\n            const m = match(re);\r\n            if (!m) {\r\n                return;\r\n            }\r\n            const ret = { type: name };\r\n            ret[name] = m[1].trim();\r\n            return pos(ret);\r\n        };\r\n    }\r\n    function atrule() {\r\n        if (css[0] !== '@') {\r\n            return;\r\n        }\r\n        return (atkeyframes() ||\r\n            atmedia() ||\r\n            atcustommedia() ||\r\n            atsupports() ||\r\n            atimport() ||\r\n            atcharset() ||\r\n            atnamespace() ||\r\n            atdocument() ||\r\n            atpage() ||\r\n            athost() ||\r\n            atfontface());\r\n    }\r\n    function rule() {\r\n        const pos = position();\r\n        const sel = selector();\r\n        if (!sel) {\r\n            return error('selector missing');\r\n        }\r\n        comments();\r\n        return pos({\r\n            type: 'rule',\r\n            selectors: sel,\r\n            declarations: declarations(),\r\n        });\r\n    }\r\n    return addParent(stylesheet());\r\n}\r\nfunction trim(str) {\r\n    return str ? str.replace(/^\\s+|\\s+$/g, '') : '';\r\n}\r\nfunction addParent(obj, parent) {\r\n    const isNode = obj && typeof obj.type === 'string';\r\n    const childParent = isNode ? obj : parent;\r\n    for (const k of Object.keys(obj)) {\r\n        const value = obj[k];\r\n        if (Array.isArray(value)) {\r\n            value.forEach((v) => {\r\n                addParent(v, childParent);\r\n            });\r\n        }\r\n        else if (value && typeof value === 'object') {\r\n            addParent(value, childParent);\r\n        }\r\n    }\r\n    if (isNode) {\r\n        Object.defineProperty(obj, 'parent', {\r\n            configurable: true,\r\n            writable: true,\r\n            enumerable: false,\r\n            value: parent || null,\r\n        });\r\n    }\r\n    return obj;\r\n}\n\nconst tagMap = {\r\n    script: 'noscript',\r\n    altglyph: 'altGlyph',\r\n    altglyphdef: 'altGlyphDef',\r\n    altglyphitem: 'altGlyphItem',\r\n    animatecolor: 'animateColor',\r\n    animatemotion: 'animateMotion',\r\n    animatetransform: 'animateTransform',\r\n    clippath: 'clipPath',\r\n    feblend: 'feBlend',\r\n    fecolormatrix: 'feColorMatrix',\r\n    fecomponenttransfer: 'feComponentTransfer',\r\n    fecomposite: 'feComposite',\r\n    feconvolvematrix: 'feConvolveMatrix',\r\n    fediffuselighting: 'feDiffuseLighting',\r\n    fedisplacementmap: 'feDisplacementMap',\r\n    fedistantlight: 'feDistantLight',\r\n    fedropshadow: 'feDropShadow',\r\n    feflood: 'feFlood',\r\n    fefunca: 'feFuncA',\r\n    fefuncb: 'feFuncB',\r\n    fefuncg: 'feFuncG',\r\n    fefuncr: 'feFuncR',\r\n    fegaussianblur: 'feGaussianBlur',\r\n    feimage: 'feImage',\r\n    femerge: 'feMerge',\r\n    femergenode: 'feMergeNode',\r\n    femorphology: 'feMorphology',\r\n    feoffset: 'feOffset',\r\n    fepointlight: 'fePointLight',\r\n    fespecularlighting: 'feSpecularLighting',\r\n    fespotlight: 'feSpotLight',\r\n    fetile: 'feTile',\r\n    feturbulence: 'feTurbulence',\r\n    foreignobject: 'foreignObject',\r\n    glyphref: 'glyphRef',\r\n    lineargradient: 'linearGradient',\r\n    radialgradient: 'radialGradient',\r\n};\r\nfunction getTagName(n) {\r\n    let tagName = tagMap[n.tagName] ? tagMap[n.tagName] : n.tagName;\r\n    if (tagName === 'link' && n.attributes._cssText) {\r\n        tagName = 'style';\r\n    }\r\n    return tagName;\r\n}\r\nfunction escapeRegExp(str) {\r\n    return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\nconst HOVER_SELECTOR = /([^\\\\]):hover/;\r\nconst HOVER_SELECTOR_GLOBAL = new RegExp(HOVER_SELECTOR.source, 'g');\r\nfunction addHoverClass(cssText, cache) {\r\n    const cachedStyle = cache?.stylesWithHoverClass.get(cssText);\r\n    if (cachedStyle)\r\n        return cachedStyle;\r\n    if (cssText.length >= 1000000) {\r\n        return cssText;\r\n    }\r\n    const ast = parse(cssText, {\r\n        silent: true,\r\n    });\r\n    if (!ast.stylesheet) {\r\n        return cssText;\r\n    }\r\n    const selectors = [];\r\n    ast.stylesheet.rules.forEach((rule) => {\r\n        if ('selectors' in rule) {\r\n            (rule.selectors || []).forEach((selector) => {\r\n                if (HOVER_SELECTOR.test(selector)) {\r\n                    selectors.push(selector);\r\n                }\r\n            });\r\n        }\r\n    });\r\n    if (selectors.length === 0) {\r\n        return cssText;\r\n    }\r\n    const selectorMatcher = new RegExp(selectors\r\n        .filter((selector, index) => selectors.indexOf(selector) === index)\r\n        .sort((a, b) => b.length - a.length)\r\n        .map((selector) => {\r\n        return escapeRegExp(selector);\r\n    })\r\n        .join('|'), 'g');\r\n    const result = cssText.replace(selectorMatcher, (selector) => {\r\n        const newSelector = selector.replace(HOVER_SELECTOR_GLOBAL, '$1.\\\\:hover');\r\n        return `${selector}, ${newSelector}`;\r\n    });\r\n    cache?.stylesWithHoverClass.set(cssText, result);\r\n    return result;\r\n}\r\nfunction createCache() {\r\n    const stylesWithHoverClass = new Map();\r\n    return {\r\n        stylesWithHoverClass,\r\n    };\r\n}\r\nfunction buildNode(n, options) {\r\n    const { doc, hackCss, cache } = options;\r\n    switch (n.type) {\r\n        case NodeType.Document:\r\n            return doc.implementation.createDocument(null, '', null);\r\n        case NodeType.DocumentType:\r\n            return doc.implementation.createDocumentType(n.name || 'html', n.publicId, n.systemId);\r\n        case NodeType.Element: {\r\n            const tagName = getTagName(n);\r\n            let node;\r\n            if (n.isSVG) {\r\n                node = doc.createElementNS('http://www.w3.org/2000/svg', tagName);\r\n            }\r\n            else {\r\n                if (n.isCustom &&\r\n                    doc.defaultView?.customElements &&\r\n                    !doc.defaultView.customElements.get(n.tagName))\r\n                    doc.defaultView.customElements.define(n.tagName, class extends doc.defaultView.HTMLElement {\r\n                    });\r\n                node = doc.createElement(tagName);\r\n            }\r\n            const specialAttributes = {};\r\n            for (const name in n.attributes) {\r\n                if (!Object.prototype.hasOwnProperty.call(n.attributes, name)) {\r\n                    continue;\r\n                }\r\n                let value = n.attributes[name];\r\n                if (tagName === 'option' &&\r\n                    name === 'selected' &&\r\n                    value === false) {\r\n                    continue;\r\n                }\r\n                if (value === null) {\r\n                    continue;\r\n                }\r\n                if (value === true)\r\n                    value = '';\r\n                if (name.startsWith('rr_')) {\r\n                    specialAttributes[name] = value;\r\n                    continue;\r\n                }\r\n                const isTextarea = tagName === 'textarea' && name === 'value';\r\n                const isRemoteOrDynamicCss = tagName === 'style' && name === '_cssText';\r\n                if (isRemoteOrDynamicCss && hackCss && typeof value === 'string') {\r\n                    value = addHoverClass(value, cache);\r\n                }\r\n                if ((isTextarea || isRemoteOrDynamicCss) && typeof value === 'string') {\r\n                    const child = doc.createTextNode(value);\r\n                    for (const c of Array.from(node.childNodes)) {\r\n                        if (c.nodeType === node.TEXT_NODE) {\r\n                            node.removeChild(c);\r\n                        }\r\n                    }\r\n                    node.appendChild(child);\r\n                    continue;\r\n                }\r\n                try {\r\n                    if (n.isSVG && name === 'xlink:href') {\r\n                        node.setAttributeNS('http://www.w3.org/1999/xlink', name, value.toString());\r\n                    }\r\n                    else if (name === 'onload' ||\r\n                        name === 'onclick' ||\r\n                        name.substring(0, 7) === 'onmouse') {\r\n                        node.setAttribute('_' + name, value.toString());\r\n                    }\r\n                    else if (tagName === 'meta' &&\r\n                        n.attributes['http-equiv'] === 'Content-Security-Policy' &&\r\n                        name === 'content') {\r\n                        node.setAttribute('csp-content', value.toString());\r\n                        continue;\r\n                    }\r\n                    else if (tagName === 'link' &&\r\n                        (n.attributes.rel === 'preload' ||\r\n                            n.attributes.rel === 'modulepreload')) {\r\n                    }\r\n                    else if (tagName === 'link' &&\r\n                        n.attributes.rel === 'prefetch' &&\r\n                        typeof n.attributes.href === 'string' &&\r\n                        extractFileExtension(n.attributes.href) === 'js') {\r\n                    }\r\n                    else if (tagName === 'img' &&\r\n                        n.attributes.srcset &&\r\n                        n.attributes.rr_dataURL) {\r\n                        node.setAttribute('rrweb-original-srcset', n.attributes.srcset);\r\n                    }\r\n                    else {\r\n                        node.setAttribute(name, value.toString());\r\n                    }\r\n                }\r\n                catch (error) {\r\n                }\r\n            }\r\n            for (const name in specialAttributes) {\r\n                const value = specialAttributes[name];\r\n                if (tagName === 'canvas' && name === 'rr_dataURL') {\r\n                    const image = doc.createElement('img');\r\n                    image.onload = () => {\r\n                        const ctx = node.getContext('2d');\r\n                        if (ctx) {\r\n                            ctx.drawImage(image, 0, 0, image.width, image.height);\r\n                        }\r\n                    };\r\n                    image.src = value.toString();\r\n                    if (node.RRNodeType)\r\n                        node.rr_dataURL = value.toString();\r\n                }\r\n                else if (tagName === 'img' && name === 'rr_dataURL') {\r\n                    const image = node;\r\n                    if (!image.currentSrc.startsWith('data:')) {\r\n                        image.setAttribute('rrweb-original-src', n.attributes.src);\r\n                        image.src = value.toString();\r\n                    }\r\n                }\r\n                if (name === 'rr_width') {\r\n                    node.style.setProperty('width', value.toString());\r\n                }\r\n                else if (name === 'rr_height') {\r\n                    node.style.setProperty('height', value.toString());\r\n                }\r\n                else if (name === 'rr_mediaCurrentTime' &&\r\n                    typeof value === 'number') {\r\n                    node.currentTime = value;\r\n                }\r\n                else if (name === 'rr_mediaState') {\r\n                    switch (value) {\r\n                        case 'played':\r\n                            node\r\n                                .play()\r\n                                .catch((e) => console.warn('media playback error', e));\r\n                            break;\r\n                        case 'paused':\r\n                            node.pause();\r\n                            break;\r\n                    }\r\n                }\r\n            }\r\n            if (n.isShadowHost) {\r\n                if (!node.shadowRoot) {\r\n                    node.attachShadow({ mode: 'open' });\r\n                }\r\n                else {\r\n                    while (node.shadowRoot.firstChild) {\r\n                        node.shadowRoot.removeChild(node.shadowRoot.firstChild);\r\n                    }\r\n                }\r\n            }\r\n            return node;\r\n        }\r\n        case NodeType.Text:\r\n            return doc.createTextNode(n.isStyle && hackCss\r\n                ? addHoverClass(n.textContent, cache)\r\n                : n.textContent);\r\n        case NodeType.CDATA:\r\n            return doc.createCDATASection(n.textContent);\r\n        case NodeType.Comment:\r\n            return doc.createComment(n.textContent);\r\n        default:\r\n            return null;\r\n    }\r\n}\r\nfunction buildNodeWithSN(n, options) {\r\n    const { doc, mirror, skipChild = false, hackCss = true, afterAppend, cache, } = options;\r\n    if (mirror.has(n.id)) {\r\n        const nodeInMirror = mirror.getNode(n.id);\r\n        const meta = mirror.getMeta(nodeInMirror);\r\n        if (isNodeMetaEqual(meta, n))\r\n            return mirror.getNode(n.id);\r\n    }\r\n    let node = buildNode(n, { doc, hackCss, cache });\r\n    if (!node) {\r\n        return null;\r\n    }\r\n    if (n.rootId && mirror.getNode(n.rootId) !== doc) {\r\n        mirror.replace(n.rootId, doc);\r\n    }\r\n    if (n.type === NodeType.Document) {\r\n        doc.close();\r\n        doc.open();\r\n        if (n.compatMode === 'BackCompat' &&\r\n            n.childNodes &&\r\n            n.childNodes[0].type !== NodeType.DocumentType) {\r\n            if (n.childNodes[0].type === NodeType.Element &&\r\n                'xmlns' in n.childNodes[0].attributes &&\r\n                n.childNodes[0].attributes.xmlns === 'http://www.w3.org/1999/xhtml') {\r\n                doc.write('<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\">');\r\n            }\r\n            else {\r\n                doc.write('<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\">');\r\n            }\r\n        }\r\n        node = doc;\r\n    }\r\n    mirror.add(node, n);\r\n    if ((n.type === NodeType.Document || n.type === NodeType.Element) &&\r\n        !skipChild) {\r\n        for (const childN of n.childNodes) {\r\n            const childNode = buildNodeWithSN(childN, {\r\n                doc,\r\n                mirror,\r\n                skipChild: false,\r\n                hackCss,\r\n                afterAppend,\r\n                cache,\r\n            });\r\n            if (!childNode) {\r\n                console.warn('Failed to rebuild', childN);\r\n                continue;\r\n            }\r\n            if (childN.isShadow && isElement(node) && node.shadowRoot) {\r\n                node.shadowRoot.appendChild(childNode);\r\n            }\r\n            else if (n.type === NodeType.Document &&\r\n                childN.type == NodeType.Element) {\r\n                const htmlElement = childNode;\r\n                let body = null;\r\n                htmlElement.childNodes.forEach((child) => {\r\n                    if (child.nodeName === 'BODY')\r\n                        body = child;\r\n                });\r\n                if (body) {\r\n                    htmlElement.removeChild(body);\r\n                    node.appendChild(childNode);\r\n                    htmlElement.appendChild(body);\r\n                }\r\n                else {\r\n                    node.appendChild(childNode);\r\n                }\r\n            }\r\n            else {\r\n                node.appendChild(childNode);\r\n            }\r\n            if (afterAppend) {\r\n                afterAppend(childNode, childN.id);\r\n            }\r\n        }\r\n    }\r\n    return node;\r\n}\r\nfunction visit(mirror, onVisit) {\r\n    function walk(node) {\r\n        onVisit(node);\r\n    }\r\n    for (const id of mirror.getIds()) {\r\n        if (mirror.has(id)) {\r\n            walk(mirror.getNode(id));\r\n        }\r\n    }\r\n}\r\nfunction handleScroll(node, mirror) {\r\n    const n = mirror.getMeta(node);\r\n    if (n?.type !== NodeType.Element) {\r\n        return;\r\n    }\r\n    const el = node;\r\n    for (const name in n.attributes) {\r\n        if (!(Object.prototype.hasOwnProperty.call(n.attributes, name) &&\r\n            name.startsWith('rr_'))) {\r\n            continue;\r\n        }\r\n        const value = n.attributes[name];\r\n        if (name === 'rr_scrollLeft') {\r\n            el.scrollLeft = value;\r\n        }\r\n        if (name === 'rr_scrollTop') {\r\n            el.scrollTop = value;\r\n        }\r\n    }\r\n}\r\nfunction rebuild(n, options) {\r\n    const { doc, onVisit, hackCss = true, afterAppend, cache, mirror = new Mirror(), } = options;\r\n    const node = buildNodeWithSN(n, {\r\n        doc,\r\n        mirror,\r\n        skipChild: false,\r\n        hackCss,\r\n        afterAppend,\r\n        cache,\r\n    });\r\n    visit(mirror, (visitedNode) => {\r\n        if (onVisit) {\r\n            onVisit(visitedNode);\r\n        }\r\n        handleScroll(visitedNode, mirror);\r\n    });\r\n    return node;\r\n}\n\nexport { IGNORED_NODE, Mirror, NodeType, addHoverClass, buildNodeWithSN, clearTimeout, createCache, createMatchPredicate, createMirror, distanceToMatch, escapeImportStatement, extractFileExtension, fixAllCssProperty, fixSafariColons, genId, getIframeContentDocument, getInputType, getInputValue, ignoreAttribute, is2DCanvasBlank, isCSSImportRule, isCSSStyleRule, isElement, isNativeShadowDom, isNodeMetaEqual, isShadowRoot, maskInputValue, needMaskingText, rebuild, serializeNodeWithId, setTimeout, shouldMaskInput, snapshot, stringifyRule, stringifyStylesheet, toLowerCase, toUpperCase, transformAttribute };\n", "import { distanceToMatch, IGNORED_NODE, isShadowRoot, createMatchPredicate } from '../../rrweb-snapshot/es/rrweb-snapshot.js';\n\nfunction on(type, fn, target = document) {\r\n    const options = { capture: true, passive: true };\r\n    target.addEventListener(type, fn, options);\r\n    return () => target.removeEventListener(type, fn, options);\r\n}\r\nconst DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +\r\n    '\\r\\n' +\r\n    'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +\r\n    '\\r\\n' +\r\n    'or you can use record.mirror to access the mirror instance during recording.';\r\nlet _mirror = {\r\n    map: {},\r\n    getId() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n        return -1;\r\n    },\r\n    getNode() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n        return null;\r\n    },\r\n    removeNodeFromMap() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n    },\r\n    has() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n        return false;\r\n    },\r\n    reset() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n    },\r\n};\r\nif (typeof window !== 'undefined' && window.Proxy && window.Reflect) {\r\n    _mirror = new Proxy(_mirror, {\r\n        get(target, prop, receiver) {\r\n            if (prop === 'map') {\r\n                console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n            }\r\n            return Reflect.get(target, prop, receiver);\r\n        },\r\n    });\r\n}\r\nfunction throttle(func, wait, options = {}) {\r\n    let timeout = null;\r\n    let previous = 0;\r\n    return function (...args) {\r\n        const now = Date.now();\r\n        if (!previous && options.leading === false) {\r\n            previous = now;\r\n        }\r\n        const remaining = wait - (now - previous);\r\n        const context = this;\r\n        if (remaining <= 0 || remaining > wait) {\r\n            if (timeout) {\r\n                clearTimeout(timeout);\r\n                timeout = null;\r\n            }\r\n            previous = now;\r\n            func.apply(context, args);\r\n        }\r\n        else if (!timeout && options.trailing !== false) {\r\n            timeout = setTimeout(() => {\r\n                previous = options.leading === false ? 0 : Date.now();\r\n                timeout = null;\r\n                func.apply(context, args);\r\n            }, remaining);\r\n        }\r\n    };\r\n}\r\nfunction hookSetter(target, key, d, isRevoked, win = window) {\r\n    const original = win.Object.getOwnPropertyDescriptor(target, key);\r\n    win.Object.defineProperty(target, key, isRevoked\r\n        ? d\r\n        : {\r\n            set(value) {\r\n                setTimeout(() => {\r\n                    d.set.call(this, value);\r\n                }, 0);\r\n                if (original && original.set) {\r\n                    original.set.call(this, value);\r\n                }\r\n            },\r\n        });\r\n    return () => hookSetter(target, key, original || {}, true);\r\n}\r\nfunction patch(source, name, replacement) {\r\n    try {\r\n        if (!(name in source)) {\r\n            return () => {\r\n            };\r\n        }\r\n        const original = source[name];\r\n        const wrapped = replacement(original);\r\n        if (typeof wrapped === 'function') {\r\n            wrapped.prototype = wrapped.prototype || {};\r\n            Object.defineProperties(wrapped, {\r\n                __rrweb_original__: {\r\n                    enumerable: false,\r\n                    value: original,\r\n                },\r\n            });\r\n        }\r\n        source[name] = wrapped;\r\n        return () => {\r\n            source[name] = original;\r\n        };\r\n    }\r\n    catch {\r\n        return () => {\r\n        };\r\n    }\r\n}\r\nlet nowTimestamp = Date.now;\r\nif (!(/[1-9][0-9]{12}/.test(Date.now().toString()))) {\r\n    nowTimestamp = () => new Date().getTime();\r\n}\r\nfunction getWindowScroll(win) {\r\n    const doc = win.document;\r\n    return {\r\n        left: doc.scrollingElement\r\n            ? doc.scrollingElement.scrollLeft\r\n            : win.pageXOffset !== undefined\r\n                ? win.pageXOffset\r\n                : doc?.documentElement.scrollLeft ||\r\n                    doc?.body?.parentElement?.scrollLeft ||\r\n                    doc?.body?.scrollLeft ||\r\n                    0,\r\n        top: doc.scrollingElement\r\n            ? doc.scrollingElement.scrollTop\r\n            : win.pageYOffset !== undefined\r\n                ? win.pageYOffset\r\n                : doc?.documentElement.scrollTop ||\r\n                    doc?.body?.parentElement?.scrollTop ||\r\n                    doc?.body?.scrollTop ||\r\n                    0,\r\n    };\r\n}\r\nfunction getWindowHeight() {\r\n    return (window.innerHeight ||\r\n        (document.documentElement && document.documentElement.clientHeight) ||\r\n        (document.body && document.body.clientHeight));\r\n}\r\nfunction getWindowWidth() {\r\n    return (window.innerWidth ||\r\n        (document.documentElement && document.documentElement.clientWidth) ||\r\n        (document.body && document.body.clientWidth));\r\n}\r\nfunction closestElementOfNode(node) {\r\n    if (!node) {\r\n        return null;\r\n    }\r\n    const el = node.nodeType === node.ELEMENT_NODE\r\n        ? node\r\n        : node.parentElement;\r\n    return el;\r\n}\r\nfunction isBlocked(node, blockClass, blockSelector, unblockSelector, checkAncestors) {\r\n    if (!node) {\r\n        return false;\r\n    }\r\n    const el = closestElementOfNode(node);\r\n    if (!el) {\r\n        return false;\r\n    }\r\n    const blockedPredicate = createMatchPredicate(blockClass, blockSelector);\r\n    if (!checkAncestors) {\r\n        const isUnblocked = unblockSelector && el.matches(unblockSelector);\r\n        return blockedPredicate(el) && !isUnblocked;\r\n    }\r\n    const blockDistance = distanceToMatch(el, blockedPredicate);\r\n    let unblockDistance = -1;\r\n    if (blockDistance < 0) {\r\n        return false;\r\n    }\r\n    if (unblockSelector) {\r\n        unblockDistance = distanceToMatch(el, createMatchPredicate(null, unblockSelector));\r\n    }\r\n    if (blockDistance > -1 && unblockDistance < 0) {\r\n        return true;\r\n    }\r\n    return blockDistance < unblockDistance;\r\n}\r\nfunction isSerialized(n, mirror) {\r\n    return mirror.getId(n) !== -1;\r\n}\r\nfunction isIgnored(n, mirror) {\r\n    return mirror.getId(n) === IGNORED_NODE;\r\n}\r\nfunction isAncestorRemoved(target, mirror) {\r\n    if (isShadowRoot(target)) {\r\n        return false;\r\n    }\r\n    const id = mirror.getId(target);\r\n    if (!mirror.has(id)) {\r\n        return true;\r\n    }\r\n    if (target.parentNode &&\r\n        target.parentNode.nodeType === target.DOCUMENT_NODE) {\r\n        return false;\r\n    }\r\n    if (!target.parentNode) {\r\n        return true;\r\n    }\r\n    return isAncestorRemoved(target.parentNode, mirror);\r\n}\r\nfunction legacy_isTouchEvent(event) {\r\n    return Boolean(event.changedTouches);\r\n}\r\nfunction polyfill(win = window) {\r\n    if ('NodeList' in win && !win.NodeList.prototype.forEach) {\r\n        win.NodeList.prototype.forEach = Array.prototype\r\n            .forEach;\r\n    }\r\n    if ('DOMTokenList' in win && !win.DOMTokenList.prototype.forEach) {\r\n        win.DOMTokenList.prototype.forEach = Array.prototype\r\n            .forEach;\r\n    }\r\n    if (!Node.prototype.contains) {\r\n        Node.prototype.contains = (...args) => {\r\n            let node = args[0];\r\n            if (!(0 in args)) {\r\n                throw new TypeError('1 argument is required');\r\n            }\r\n            do {\r\n                if (this === node) {\r\n                    return true;\r\n                }\r\n            } while ((node = node && node.parentNode));\r\n            return false;\r\n        };\r\n    }\r\n}\r\nfunction queueToResolveTrees(queue) {\r\n    const queueNodeMap = {};\r\n    const putIntoMap = (m, parent) => {\r\n        const nodeInTree = {\r\n            value: m,\r\n            parent,\r\n            children: [],\r\n        };\r\n        queueNodeMap[m.node.id] = nodeInTree;\r\n        return nodeInTree;\r\n    };\r\n    const queueNodeTrees = [];\r\n    for (const mutation of queue) {\r\n        const { nextId, parentId } = mutation;\r\n        if (nextId && nextId in queueNodeMap) {\r\n            const nextInTree = queueNodeMap[nextId];\r\n            if (nextInTree.parent) {\r\n                const idx = nextInTree.parent.children.indexOf(nextInTree);\r\n                nextInTree.parent.children.splice(idx, 0, putIntoMap(mutation, nextInTree.parent));\r\n            }\r\n            else {\r\n                const idx = queueNodeTrees.indexOf(nextInTree);\r\n                queueNodeTrees.splice(idx, 0, putIntoMap(mutation, null));\r\n            }\r\n            continue;\r\n        }\r\n        if (parentId in queueNodeMap) {\r\n            const parentInTree = queueNodeMap[parentId];\r\n            parentInTree.children.push(putIntoMap(mutation, parentInTree));\r\n            continue;\r\n        }\r\n        queueNodeTrees.push(putIntoMap(mutation, null));\r\n    }\r\n    return queueNodeTrees;\r\n}\r\nfunction iterateResolveTree(tree, cb) {\r\n    cb(tree.value);\r\n    for (let i = tree.children.length - 1; i >= 0; i--) {\r\n        iterateResolveTree(tree.children[i], cb);\r\n    }\r\n}\r\nfunction isSerializedIframe(n, mirror) {\r\n    return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));\r\n}\r\nfunction isSerializedStylesheet(n, mirror) {\r\n    return Boolean(n.nodeName === 'LINK' &&\r\n        n.nodeType === n.ELEMENT_NODE &&\r\n        n.getAttribute &&\r\n        n.getAttribute('rel') === 'stylesheet' &&\r\n        mirror.getMeta(n));\r\n}\r\nfunction getBaseDimension(node, rootIframe) {\r\n    const frameElement = node.ownerDocument?.defaultView?.frameElement;\r\n    if (!frameElement || frameElement === rootIframe) {\r\n        return {\r\n            x: 0,\r\n            y: 0,\r\n            relativeScale: 1,\r\n            absoluteScale: 1,\r\n        };\r\n    }\r\n    const frameDimension = frameElement.getBoundingClientRect();\r\n    const frameBaseDimension = getBaseDimension(frameElement, rootIframe);\r\n    const relativeScale = frameDimension.height / frameElement.clientHeight;\r\n    return {\r\n        x: frameDimension.x * frameBaseDimension.relativeScale +\r\n            frameBaseDimension.x,\r\n        y: frameDimension.y * frameBaseDimension.relativeScale +\r\n            frameBaseDimension.y,\r\n        relativeScale,\r\n        absoluteScale: frameBaseDimension.absoluteScale * relativeScale,\r\n    };\r\n}\r\nfunction hasShadowRoot(n) {\r\n    return Boolean(n?.shadowRoot);\r\n}\r\nfunction getNestedRule(rules, position) {\r\n    const rule = rules[position[0]];\r\n    if (position.length === 1) {\r\n        return rule;\r\n    }\r\n    else {\r\n        return getNestedRule(rule.cssRules[position[1]].cssRules, position.slice(2));\r\n    }\r\n}\r\nfunction getPositionsAndIndex(nestedIndex) {\r\n    const positions = [...nestedIndex];\r\n    const index = positions.pop();\r\n    return { positions, index };\r\n}\r\nfunction uniqueTextMutations(mutations) {\r\n    const idSet = new Set();\r\n    const uniqueMutations = [];\r\n    for (let i = mutations.length; i--;) {\r\n        const mutation = mutations[i];\r\n        if (!idSet.has(mutation.id)) {\r\n            uniqueMutations.push(mutation);\r\n            idSet.add(mutation.id);\r\n        }\r\n    }\r\n    return uniqueMutations;\r\n}\r\nclass StyleSheetMirror {\r\n    constructor() {\r\n        this.id = 1;\r\n        this.styleIDMap = new WeakMap();\r\n        this.idStyleMap = new Map();\r\n    }\r\n    getId(stylesheet) {\r\n        return this.styleIDMap.get(stylesheet) ?? -1;\r\n    }\r\n    has(stylesheet) {\r\n        return this.styleIDMap.has(stylesheet);\r\n    }\r\n    add(stylesheet, id) {\r\n        if (this.has(stylesheet))\r\n            return this.getId(stylesheet);\r\n        let newId;\r\n        if (id === undefined) {\r\n            newId = this.id++;\r\n        }\r\n        else\r\n            newId = id;\r\n        this.styleIDMap.set(stylesheet, newId);\r\n        this.idStyleMap.set(newId, stylesheet);\r\n        return newId;\r\n    }\r\n    getStyle(id) {\r\n        return this.idStyleMap.get(id) || null;\r\n    }\r\n    reset() {\r\n        this.styleIDMap = new WeakMap();\r\n        this.idStyleMap = new Map();\r\n        this.id = 1;\r\n    }\r\n    generateId() {\r\n        return this.id++;\r\n    }\r\n}\r\nfunction getShadowHost(n) {\r\n    let shadowHost = null;\r\n    if (n.getRootNode?.()?.nodeType === Node.DOCUMENT_FRAGMENT_NODE &&\r\n        n.getRootNode().host)\r\n        shadowHost = n.getRootNode().host;\r\n    return shadowHost;\r\n}\r\nfunction getRootShadowHost(n) {\r\n    let rootShadowHost = n;\r\n    let shadowHost;\r\n    while ((shadowHost = getShadowHost(rootShadowHost)))\r\n        rootShadowHost = shadowHost;\r\n    return rootShadowHost;\r\n}\r\nfunction shadowHostInDom(n) {\r\n    const doc = n.ownerDocument;\r\n    if (!doc)\r\n        return false;\r\n    const shadowHost = getRootShadowHost(n);\r\n    return doc.contains(shadowHost);\r\n}\r\nfunction inDom(n) {\r\n    const doc = n.ownerDocument;\r\n    if (!doc)\r\n        return false;\r\n    return doc.contains(n) || shadowHostInDom(n);\r\n}\r\nconst cachedImplementations = {};\r\nfunction getImplementation(name) {\r\n    const cached = cachedImplementations[name];\r\n    if (cached) {\r\n        return cached;\r\n    }\r\n    const document = window.document;\r\n    let impl = window[name];\r\n    if (document && typeof document.createElement === 'function') {\r\n        try {\r\n            const sandbox = document.createElement('iframe');\r\n            sandbox.hidden = true;\r\n            document.head.appendChild(sandbox);\r\n            const contentWindow = sandbox.contentWindow;\r\n            if (contentWindow && contentWindow[name]) {\r\n                impl =\r\n                    contentWindow[name];\r\n            }\r\n            document.head.removeChild(sandbox);\r\n        }\r\n        catch (e) {\r\n        }\r\n    }\r\n    return (cachedImplementations[name] = impl.bind(window));\r\n}\r\nfunction onRequestAnimationFrame(...rest) {\r\n    return getImplementation('requestAnimationFrame')(...rest);\r\n}\r\nfunction setTimeout(...rest) {\r\n    return getImplementation('setTimeout')(...rest);\r\n}\r\nfunction clearTimeout(...rest) {\r\n    return getImplementation('clearTimeout')(...rest);\r\n}\n\nexport { StyleSheetMirror, _mirror, clearTimeout, closestElementOfNode, getBaseDimension, getNestedRule, getPositionsAndIndex, getRootShadowHost, getShadowHost, getWindowHeight, getWindowScroll, getWindowWidth, hasShadowRoot, hookSetter, inDom, isAncestorRemoved, isBlocked, isIgnored, isSerialized, isSerializedIframe, isSerializedStylesheet, iterateResolveTree, legacy_isTouchEvent, nowTimestamp, on, onRequestAnimationFrame, patch, polyfill, queueToResolveTrees, setTimeout, shadowHostInDom, throttle, uniqueTextMutations };\n", "var EventType = /* @__PURE__ */ ((EventType2) => {\n  EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n  EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n  EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n  EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n  EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n  EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n  EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n  return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n  IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n  IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n  IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n  IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n  IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n  IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n  IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n  IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n  IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n  IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n  IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n  IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n  IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n  IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n  IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n  IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n  IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n  return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n  MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n  MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n  MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n  MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n  MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n  MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n  MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n  MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n  MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n  MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n  MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n  return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n  PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n  PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n  PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n  return PointerTypes2;\n})(PointerTypes || {});\nvar CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {\n  CanvasContext2[CanvasContext2[\"2D\"] = 0] = \"2D\";\n  CanvasContext2[CanvasContext2[\"WebGL\"] = 1] = \"WebGL\";\n  CanvasContext2[CanvasContext2[\"WebGL2\"] = 2] = \"WebGL2\";\n  return CanvasContext2;\n})(CanvasContext || {});\nvar ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {\n  ReplayerEvents2[\"Start\"] = \"start\";\n  ReplayerEvents2[\"Pause\"] = \"pause\";\n  ReplayerEvents2[\"Resume\"] = \"resume\";\n  ReplayerEvents2[\"Resize\"] = \"resize\";\n  ReplayerEvents2[\"Finish\"] = \"finish\";\n  ReplayerEvents2[\"FullsnapshotRebuilded\"] = \"fullsnapshot-rebuilded\";\n  ReplayerEvents2[\"LoadStylesheetStart\"] = \"load-stylesheet-start\";\n  ReplayerEvents2[\"LoadStylesheetEnd\"] = \"load-stylesheet-end\";\n  ReplayerEvents2[\"SkipStart\"] = \"skip-start\";\n  ReplayerEvents2[\"SkipEnd\"] = \"skip-end\";\n  ReplayerEvents2[\"MouseInteraction\"] = \"mouse-interaction\";\n  ReplayerEvents2[\"EventCast\"] = \"event-cast\";\n  ReplayerEvents2[\"CustomEvent\"] = \"custom-event\";\n  ReplayerEvents2[\"Flush\"] = \"flush\";\n  ReplayerEvents2[\"StateChange\"] = \"state-change\";\n  ReplayerEvents2[\"PlayBack\"] = \"play-back\";\n  ReplayerEvents2[\"Destroy\"] = \"destroy\";\n  return ReplayerEvents2;\n})(ReplayerEvents || {});\n\nexport { CanvasContext, EventType, IncrementalSource, MouseInteractions, PointerTypes, ReplayerEvents };\n", "var NodeType$1;\r\n(function (NodeType) {\r\n    NodeType[NodeType[\"Document\"] = 0] = \"Document\";\r\n    NodeType[NodeType[\"DocumentType\"] = 1] = \"DocumentType\";\r\n    NodeType[NodeType[\"Element\"] = 2] = \"Element\";\r\n    NodeType[NodeType[\"Text\"] = 3] = \"Text\";\r\n    NodeType[NodeType[\"CDATA\"] = 4] = \"CDATA\";\r\n    NodeType[NodeType[\"Comment\"] = 5] = \"Comment\";\r\n})(NodeType$1 || (NodeType$1 = {}));\nclass Mirror$1 {\r\n    constructor() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n    getId(n) {\r\n        if (!n)\r\n            return -1;\r\n        const id = this.getMeta(n)?.id;\r\n        return id ?? -1;\r\n    }\r\n    getNode(id) {\r\n        return this.idNodeMap.get(id) || null;\r\n    }\r\n    getIds() {\r\n        return Array.from(this.idNodeMap.keys());\r\n    }\r\n    getMeta(n) {\r\n        return this.nodeMetaMap.get(n) || null;\r\n    }\r\n    removeNodeFromMap(n) {\r\n        const id = this.getId(n);\r\n        this.idNodeMap.delete(id);\r\n        if (n.childNodes) {\r\n            n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));\r\n        }\r\n    }\r\n    has(id) {\r\n        return this.idNodeMap.has(id);\r\n    }\r\n    hasNode(node) {\r\n        return this.nodeMetaMap.has(node);\r\n    }\r\n    add(n, meta) {\r\n        const id = meta.id;\r\n        this.idNodeMap.set(id, n);\r\n        this.nodeMetaMap.set(n, meta);\r\n    }\r\n    replace(id, n) {\r\n        const oldNode = this.getNode(id);\r\n        if (oldNode) {\r\n            const meta = this.nodeMetaMap.get(oldNode);\r\n            if (meta)\r\n                this.nodeMetaMap.set(n, meta);\r\n        }\r\n        this.idNodeMap.set(id, n);\r\n    }\r\n    reset() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n}\r\nfunction createMirror$1() {\r\n    return new Mirror$1();\r\n}\n\nfunction parseCSSText(cssText) {\r\n    const res = {};\r\n    const listDelimiter = /;(?![^(]*\\))/g;\r\n    const propertyDelimiter = /:(.+)/;\r\n    const comment = /\\/\\*.*?\\*\\//g;\r\n    cssText\r\n        .replace(comment, '')\r\n        .split(listDelimiter)\r\n        .forEach(function (item) {\r\n        if (item) {\r\n            const tmp = item.split(propertyDelimiter);\r\n            tmp.length > 1 && (res[camelize(tmp[0].trim())] = tmp[1].trim());\r\n        }\r\n    });\r\n    return res;\r\n}\r\nfunction toCSSText(style) {\r\n    const properties = [];\r\n    for (const name in style) {\r\n        const value = style[name];\r\n        if (typeof value !== 'string')\r\n            continue;\r\n        const normalizedName = hyphenate(name);\r\n        properties.push(`${normalizedName}: ${value};`);\r\n    }\r\n    return properties.join(' ');\r\n}\r\nconst camelizeRE = /-([a-z])/g;\r\nconst CUSTOM_PROPERTY_REGEX = /^--[a-zA-Z0-9-]+$/;\r\nconst camelize = (str) => {\r\n    if (CUSTOM_PROPERTY_REGEX.test(str))\r\n        return str;\r\n    return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));\r\n};\r\nconst hyphenateRE = /\\B([A-Z])/g;\r\nconst hyphenate = (str) => {\r\n    return str.replace(hyphenateRE, '-$1').toLowerCase();\r\n};\n\nclass BaseRRNode {\r\n    constructor(..._args) {\r\n        this.parentElement = null;\r\n        this.parentNode = null;\r\n        this.firstChild = null;\r\n        this.lastChild = null;\r\n        this.previousSibling = null;\r\n        this.nextSibling = null;\r\n        this.ELEMENT_NODE = NodeType.ELEMENT_NODE;\r\n        this.TEXT_NODE = NodeType.TEXT_NODE;\r\n    }\r\n    get childNodes() {\r\n        const childNodes = [];\r\n        let childIterator = this.firstChild;\r\n        while (childIterator) {\r\n            childNodes.push(childIterator);\r\n            childIterator = childIterator.nextSibling;\r\n        }\r\n        return childNodes;\r\n    }\r\n    contains(node) {\r\n        if (!(node instanceof BaseRRNode))\r\n            return false;\r\n        else if (node.ownerDocument !== this.ownerDocument)\r\n            return false;\r\n        else if (node === this)\r\n            return true;\r\n        while (node.parentNode) {\r\n            if (node.parentNode === this)\r\n                return true;\r\n            node = node.parentNode;\r\n        }\r\n        return false;\r\n    }\r\n    appendChild(_newChild) {\r\n        throw new Error(`RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`);\r\n    }\r\n    insertBefore(_newChild, _refChild) {\r\n        throw new Error(`RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`);\r\n    }\r\n    removeChild(_node) {\r\n        throw new Error(`RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`);\r\n    }\r\n    toString() {\r\n        return 'RRNode';\r\n    }\r\n}\r\nfunction BaseRRDocumentImpl(RRNodeClass) {\r\n    return class BaseRRDocument extends RRNodeClass {\r\n        constructor(...args) {\r\n            super(args);\r\n            this.nodeType = NodeType.DOCUMENT_NODE;\r\n            this.nodeName = '#document';\r\n            this.compatMode = 'CSS1Compat';\r\n            this.RRNodeType = NodeType$1.Document;\r\n            this.textContent = null;\r\n            this.ownerDocument = this;\r\n        }\r\n        get documentElement() {\r\n            return (this.childNodes.find((node) => node.RRNodeType === NodeType$1.Element &&\r\n                node.tagName === 'HTML') || null);\r\n        }\r\n        get body() {\r\n            return (this.documentElement?.childNodes.find((node) => node.RRNodeType === NodeType$1.Element &&\r\n                node.tagName === 'BODY') || null);\r\n        }\r\n        get head() {\r\n            return (this.documentElement?.childNodes.find((node) => node.RRNodeType === NodeType$1.Element &&\r\n                node.tagName === 'HEAD') || null);\r\n        }\r\n        get implementation() {\r\n            return this;\r\n        }\r\n        get firstElementChild() {\r\n            return this.documentElement;\r\n        }\r\n        appendChild(newChild) {\r\n            const nodeType = newChild.RRNodeType;\r\n            if (nodeType === NodeType$1.Element ||\r\n                nodeType === NodeType$1.DocumentType) {\r\n                if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {\r\n                    throw new Error(`RRDomException: Failed to execute 'appendChild' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? 'RRElement' : 'RRDoctype'} on RRDocument allowed.`);\r\n                }\r\n            }\r\n            const child = appendChild(this, newChild);\r\n            child.parentElement = null;\r\n            return child;\r\n        }\r\n        insertBefore(newChild, refChild) {\r\n            const nodeType = newChild.RRNodeType;\r\n            if (nodeType === NodeType$1.Element ||\r\n                nodeType === NodeType$1.DocumentType) {\r\n                if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {\r\n                    throw new Error(`RRDomException: Failed to execute 'insertBefore' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? 'RRElement' : 'RRDoctype'} on RRDocument allowed.`);\r\n                }\r\n            }\r\n            const child = insertBefore(this, newChild, refChild);\r\n            child.parentElement = null;\r\n            return child;\r\n        }\r\n        removeChild(node) {\r\n            return removeChild(this, node);\r\n        }\r\n        open() {\r\n            this.firstChild = null;\r\n            this.lastChild = null;\r\n        }\r\n        close() {\r\n        }\r\n        write(content) {\r\n            let publicId;\r\n            if (content ===\r\n                '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\">')\r\n                publicId = '-//W3C//DTD XHTML 1.0 Transitional//EN';\r\n            else if (content ===\r\n                '<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\">')\r\n                publicId = '-//W3C//DTD HTML 4.0 Transitional//EN';\r\n            if (publicId) {\r\n                const doctype = this.createDocumentType('html', publicId, '');\r\n                this.open();\r\n                this.appendChild(doctype);\r\n            }\r\n        }\r\n        createDocument(_namespace, _qualifiedName, _doctype) {\r\n            return new BaseRRDocument();\r\n        }\r\n        createDocumentType(qualifiedName, publicId, systemId) {\r\n            const doctype = new (BaseRRDocumentTypeImpl(BaseRRNode))(qualifiedName, publicId, systemId);\r\n            doctype.ownerDocument = this;\r\n            return doctype;\r\n        }\r\n        createElement(tagName) {\r\n            const element = new (BaseRRElementImpl(BaseRRNode))(tagName);\r\n            element.ownerDocument = this;\r\n            return element;\r\n        }\r\n        createElementNS(_namespaceURI, qualifiedName) {\r\n            return this.createElement(qualifiedName);\r\n        }\r\n        createTextNode(data) {\r\n            const text = new (BaseRRTextImpl(BaseRRNode))(data);\r\n            text.ownerDocument = this;\r\n            return text;\r\n        }\r\n        createComment(data) {\r\n            const comment = new (BaseRRCommentImpl(BaseRRNode))(data);\r\n            comment.ownerDocument = this;\r\n            return comment;\r\n        }\r\n        createCDATASection(data) {\r\n            const CDATASection = new (BaseRRCDATASectionImpl(BaseRRNode))(data);\r\n            CDATASection.ownerDocument = this;\r\n            return CDATASection;\r\n        }\r\n        toString() {\r\n            return 'RRDocument';\r\n        }\r\n    };\r\n}\r\nfunction BaseRRDocumentTypeImpl(RRNodeClass) {\r\n    return class BaseRRDocumentType extends RRNodeClass {\r\n        constructor(qualifiedName, publicId, systemId) {\r\n            super();\r\n            this.nodeType = NodeType.DOCUMENT_TYPE_NODE;\r\n            this.RRNodeType = NodeType$1.DocumentType;\r\n            this.name = qualifiedName;\r\n            this.publicId = publicId;\r\n            this.systemId = systemId;\r\n            this.nodeName = qualifiedName;\r\n            this.textContent = null;\r\n        }\r\n        toString() {\r\n            return 'RRDocumentType';\r\n        }\r\n    };\r\n}\r\nfunction BaseRRElementImpl(RRNodeClass) {\r\n    return class BaseRRElement extends RRNodeClass {\r\n        constructor(tagName) {\r\n            super();\r\n            this.nodeType = NodeType.ELEMENT_NODE;\r\n            this.RRNodeType = NodeType$1.Element;\r\n            this.attributes = {};\r\n            this.shadowRoot = null;\r\n            this.tagName = tagName.toUpperCase();\r\n            this.nodeName = tagName.toUpperCase();\r\n        }\r\n        get textContent() {\r\n            let result = '';\r\n            this.childNodes.forEach((node) => (result += node.textContent));\r\n            return result;\r\n        }\r\n        set textContent(textContent) {\r\n            this.firstChild = null;\r\n            this.lastChild = null;\r\n            this.appendChild(this.ownerDocument.createTextNode(textContent));\r\n        }\r\n        get classList() {\r\n            return new ClassList(this.attributes.class, (newClassName) => {\r\n                this.attributes.class = newClassName;\r\n            });\r\n        }\r\n        get id() {\r\n            return this.attributes.id || '';\r\n        }\r\n        get className() {\r\n            return this.attributes.class || '';\r\n        }\r\n        get style() {\r\n            const style = (this.attributes.style ? parseCSSText(this.attributes.style) : {});\r\n            const hyphenateRE = /\\B([A-Z])/g;\r\n            style.setProperty = (name, value, priority) => {\r\n                if (hyphenateRE.test(name))\r\n                    return;\r\n                const normalizedName = camelize(name);\r\n                if (!value)\r\n                    delete style[normalizedName];\r\n                else\r\n                    style[normalizedName] = value;\r\n                if (priority === 'important')\r\n                    style[normalizedName] += ' !important';\r\n                this.attributes.style = toCSSText(style);\r\n            };\r\n            style.removeProperty = (name) => {\r\n                if (hyphenateRE.test(name))\r\n                    return '';\r\n                const normalizedName = camelize(name);\r\n                const value = style[normalizedName] || '';\r\n                delete style[normalizedName];\r\n                this.attributes.style = toCSSText(style);\r\n                return value;\r\n            };\r\n            return style;\r\n        }\r\n        getAttribute(name) {\r\n            return this.attributes[name] || null;\r\n        }\r\n        setAttribute(name, attribute) {\r\n            this.attributes[name] = attribute;\r\n        }\r\n        setAttributeNS(_namespace, qualifiedName, value) {\r\n            this.setAttribute(qualifiedName, value);\r\n        }\r\n        removeAttribute(name) {\r\n            delete this.attributes[name];\r\n        }\r\n        appendChild(newChild) {\r\n            return appendChild(this, newChild);\r\n        }\r\n        insertBefore(newChild, refChild) {\r\n            return insertBefore(this, newChild, refChild);\r\n        }\r\n        removeChild(node) {\r\n            return removeChild(this, node);\r\n        }\r\n        attachShadow(_init) {\r\n            const shadowRoot = this.ownerDocument.createElement('SHADOWROOT');\r\n            this.shadowRoot = shadowRoot;\r\n            return shadowRoot;\r\n        }\r\n        dispatchEvent(_event) {\r\n            return true;\r\n        }\r\n        toString() {\r\n            let attributeString = '';\r\n            for (const attribute in this.attributes) {\r\n                attributeString += `${attribute}=\"${this.attributes[attribute]}\" `;\r\n            }\r\n            return `${this.tagName} ${attributeString}`;\r\n        }\r\n    };\r\n}\r\nfunction BaseRRMediaElementImpl(RRElementClass) {\r\n    return class BaseRRMediaElement extends RRElementClass {\r\n        attachShadow(_init) {\r\n            throw new Error(`RRDomException: Failed to execute 'attachShadow' on 'RRElement': This RRElement does not support attachShadow`);\r\n        }\r\n        play() {\r\n            this.paused = false;\r\n        }\r\n        pause() {\r\n            this.paused = true;\r\n        }\r\n    };\r\n}\r\nfunction BaseRRTextImpl(RRNodeClass) {\r\n    return class BaseRRText extends RRNodeClass {\r\n        constructor(data) {\r\n            super();\r\n            this.nodeType = NodeType.TEXT_NODE;\r\n            this.nodeName = '#text';\r\n            this.RRNodeType = NodeType$1.Text;\r\n            this.data = data;\r\n        }\r\n        get textContent() {\r\n            return this.data;\r\n        }\r\n        set textContent(textContent) {\r\n            this.data = textContent;\r\n        }\r\n        toString() {\r\n            return `RRText text=${JSON.stringify(this.data)}`;\r\n        }\r\n    };\r\n}\r\nfunction BaseRRCommentImpl(RRNodeClass) {\r\n    return class BaseRRComment extends RRNodeClass {\r\n        constructor(data) {\r\n            super();\r\n            this.nodeType = NodeType.COMMENT_NODE;\r\n            this.nodeName = '#comment';\r\n            this.RRNodeType = NodeType$1.Comment;\r\n            this.data = data;\r\n        }\r\n        get textContent() {\r\n            return this.data;\r\n        }\r\n        set textContent(textContent) {\r\n            this.data = textContent;\r\n        }\r\n        toString() {\r\n            return `RRComment text=${JSON.stringify(this.data)}`;\r\n        }\r\n    };\r\n}\r\nfunction BaseRRCDATASectionImpl(RRNodeClass) {\r\n    return class BaseRRCDATASection extends RRNodeClass {\r\n        constructor(data) {\r\n            super();\r\n            this.nodeName = '#cdata-section';\r\n            this.nodeType = NodeType.CDATA_SECTION_NODE;\r\n            this.RRNodeType = NodeType$1.CDATA;\r\n            this.data = data;\r\n        }\r\n        get textContent() {\r\n            return this.data;\r\n        }\r\n        set textContent(textContent) {\r\n            this.data = textContent;\r\n        }\r\n        toString() {\r\n            return `RRCDATASection data=${JSON.stringify(this.data)}`;\r\n        }\r\n    };\r\n}\r\nclass ClassList {\r\n    constructor(classText, onChange) {\r\n        this.classes = [];\r\n        this.add = (...classNames) => {\r\n            for (const item of classNames) {\r\n                const className = String(item);\r\n                if (this.classes.indexOf(className) >= 0)\r\n                    continue;\r\n                this.classes.push(className);\r\n            }\r\n            this.onChange && this.onChange(this.classes.join(' '));\r\n        };\r\n        this.remove = (...classNames) => {\r\n            this.classes = this.classes.filter((item) => classNames.indexOf(item) === -1);\r\n            this.onChange && this.onChange(this.classes.join(' '));\r\n        };\r\n        if (classText) {\r\n            const classes = classText.trim().split(/\\s+/);\r\n            this.classes.push(...classes);\r\n        }\r\n        this.onChange = onChange;\r\n    }\r\n}\r\nfunction appendChild(parent, newChild) {\r\n    if (newChild.parentNode)\r\n        newChild.parentNode.removeChild(newChild);\r\n    if (parent.lastChild) {\r\n        parent.lastChild.nextSibling = newChild;\r\n        newChild.previousSibling = parent.lastChild;\r\n    }\r\n    else {\r\n        parent.firstChild = newChild;\r\n        newChild.previousSibling = null;\r\n    }\r\n    parent.lastChild = newChild;\r\n    newChild.nextSibling = null;\r\n    newChild.parentNode = parent;\r\n    newChild.parentElement = parent;\r\n    newChild.ownerDocument = parent.ownerDocument;\r\n    return newChild;\r\n}\r\nfunction insertBefore(parent, newChild, refChild) {\r\n    if (!refChild)\r\n        return appendChild(parent, newChild);\r\n    if (refChild.parentNode !== parent)\r\n        throw new Error(\"Failed to execute 'insertBefore' on 'RRNode': The RRNode before which the new node is to be inserted is not a child of this RRNode.\");\r\n    if (newChild === refChild)\r\n        return newChild;\r\n    if (newChild.parentNode)\r\n        newChild.parentNode.removeChild(newChild);\r\n    newChild.previousSibling = refChild.previousSibling;\r\n    refChild.previousSibling = newChild;\r\n    newChild.nextSibling = refChild;\r\n    if (newChild.previousSibling)\r\n        newChild.previousSibling.nextSibling = newChild;\r\n    else\r\n        parent.firstChild = newChild;\r\n    newChild.parentElement = parent;\r\n    newChild.parentNode = parent;\r\n    newChild.ownerDocument = parent.ownerDocument;\r\n    return newChild;\r\n}\r\nfunction removeChild(parent, child) {\r\n    if (child.parentNode !== parent)\r\n        throw new Error(\"Failed to execute 'removeChild' on 'RRNode': The RRNode to be removed is not a child of this RRNode.\");\r\n    if (child.previousSibling)\r\n        child.previousSibling.nextSibling = child.nextSibling;\r\n    else\r\n        parent.firstChild = child.nextSibling;\r\n    if (child.nextSibling)\r\n        child.nextSibling.previousSibling = child.previousSibling;\r\n    else\r\n        parent.lastChild = child.previousSibling;\r\n    child.previousSibling = null;\r\n    child.nextSibling = null;\r\n    child.parentElement = null;\r\n    child.parentNode = null;\r\n    return child;\r\n}\r\nvar NodeType;\r\n(function (NodeType) {\r\n    NodeType[NodeType[\"PLACEHOLDER\"] = 0] = \"PLACEHOLDER\";\r\n    NodeType[NodeType[\"ELEMENT_NODE\"] = 1] = \"ELEMENT_NODE\";\r\n    NodeType[NodeType[\"ATTRIBUTE_NODE\"] = 2] = \"ATTRIBUTE_NODE\";\r\n    NodeType[NodeType[\"TEXT_NODE\"] = 3] = \"TEXT_NODE\";\r\n    NodeType[NodeType[\"CDATA_SECTION_NODE\"] = 4] = \"CDATA_SECTION_NODE\";\r\n    NodeType[NodeType[\"ENTITY_REFERENCE_NODE\"] = 5] = \"ENTITY_REFERENCE_NODE\";\r\n    NodeType[NodeType[\"ENTITY_NODE\"] = 6] = \"ENTITY_NODE\";\r\n    NodeType[NodeType[\"PROCESSING_INSTRUCTION_NODE\"] = 7] = \"PROCESSING_INSTRUCTION_NODE\";\r\n    NodeType[NodeType[\"COMMENT_NODE\"] = 8] = \"COMMENT_NODE\";\r\n    NodeType[NodeType[\"DOCUMENT_NODE\"] = 9] = \"DOCUMENT_NODE\";\r\n    NodeType[NodeType[\"DOCUMENT_TYPE_NODE\"] = 10] = \"DOCUMENT_TYPE_NODE\";\r\n    NodeType[NodeType[\"DOCUMENT_FRAGMENT_NODE\"] = 11] = \"DOCUMENT_FRAGMENT_NODE\";\r\n})(NodeType || (NodeType = {}));\n\nfunction getIFrameContentDocument(iframe) {\r\n    try {\r\n        return iframe.contentDocument;\r\n    }\r\n    catch (e) {\r\n    }\r\n}\r\nfunction getIFrameContentWindow(iframe) {\r\n    try {\r\n        return iframe.contentWindow;\r\n    }\r\n    catch (e) {\r\n    }\r\n}\n\nconst NAMESPACES = {\r\n    svg: 'http://www.w3.org/2000/svg',\r\n    'xlink:href': 'http://www.w3.org/1999/xlink',\r\n    xmlns: 'http://www.w3.org/2000/xmlns/',\r\n};\r\nconst SVGTagMap = {\r\n    altglyph: 'altGlyph',\r\n    altglyphdef: 'altGlyphDef',\r\n    altglyphitem: 'altGlyphItem',\r\n    animatecolor: 'animateColor',\r\n    animatemotion: 'animateMotion',\r\n    animatetransform: 'animateTransform',\r\n    clippath: 'clipPath',\r\n    feblend: 'feBlend',\r\n    fecolormatrix: 'feColorMatrix',\r\n    fecomponenttransfer: 'feComponentTransfer',\r\n    fecomposite: 'feComposite',\r\n    feconvolvematrix: 'feConvolveMatrix',\r\n    fediffuselighting: 'feDiffuseLighting',\r\n    fedisplacementmap: 'feDisplacementMap',\r\n    fedistantlight: 'feDistantLight',\r\n    fedropshadow: 'feDropShadow',\r\n    feflood: 'feFlood',\r\n    fefunca: 'feFuncA',\r\n    fefuncb: 'feFuncB',\r\n    fefuncg: 'feFuncG',\r\n    fefuncr: 'feFuncR',\r\n    fegaussianblur: 'feGaussianBlur',\r\n    feimage: 'feImage',\r\n    femerge: 'feMerge',\r\n    femergenode: 'feMergeNode',\r\n    femorphology: 'feMorphology',\r\n    feoffset: 'feOffset',\r\n    fepointlight: 'fePointLight',\r\n    fespecularlighting: 'feSpecularLighting',\r\n    fespotlight: 'feSpotLight',\r\n    fetile: 'feTile',\r\n    feturbulence: 'feTurbulence',\r\n    foreignobject: 'foreignObject',\r\n    glyphref: 'glyphRef',\r\n    lineargradient: 'linearGradient',\r\n    radialgradient: 'radialGradient',\r\n};\r\nlet createdNodeSet = null;\r\nfunction diff(oldTree, newTree, replayer, rrnodeMirror = newTree.mirror ||\r\n    newTree.ownerDocument.mirror) {\r\n    oldTree = diffBeforeUpdatingChildren(oldTree, newTree, replayer, rrnodeMirror);\r\n    diffChildren(oldTree, newTree, replayer, rrnodeMirror);\r\n    diffAfterUpdatingChildren(oldTree, newTree, replayer);\r\n}\r\nfunction diffBeforeUpdatingChildren(oldTree, newTree, replayer, rrnodeMirror) {\r\n    if (replayer.afterAppend && !createdNodeSet) {\r\n        createdNodeSet = new WeakSet();\r\n        setTimeout(() => {\r\n            createdNodeSet = null;\r\n        }, 0);\r\n    }\r\n    if (!sameNodeType(oldTree, newTree)) {\r\n        const calibratedOldTree = createOrGetNode(newTree, replayer.mirror, rrnodeMirror);\r\n        oldTree.parentNode?.replaceChild(calibratedOldTree, oldTree);\r\n        oldTree = calibratedOldTree;\r\n    }\r\n    switch (newTree.RRNodeType) {\r\n        case NodeType$1.Document: {\r\n            if (!nodeMatching(oldTree, newTree, replayer.mirror, rrnodeMirror)) {\r\n                const newMeta = rrnodeMirror.getMeta(newTree);\r\n                if (newMeta) {\r\n                    replayer.mirror.removeNodeFromMap(oldTree);\r\n                    oldTree.close();\r\n                    oldTree.open();\r\n                    replayer.mirror.add(oldTree, newMeta);\r\n                    createdNodeSet?.add(oldTree);\r\n                }\r\n            }\r\n            break;\r\n        }\r\n        case NodeType$1.Element: {\r\n            const oldElement = oldTree;\r\n            const newRRElement = newTree;\r\n            switch (newRRElement.tagName) {\r\n                case 'IFRAME': {\r\n                    const oldContentDocument = getIFrameContentDocument(oldTree);\r\n                    if (!oldContentDocument)\r\n                        break;\r\n                    diff(oldContentDocument, newTree.contentDocument, replayer, rrnodeMirror);\r\n                    break;\r\n                }\r\n            }\r\n            if (newRRElement.shadowRoot) {\r\n                if (!oldElement.shadowRoot)\r\n                    oldElement.attachShadow({ mode: 'open' });\r\n                diffChildren(oldElement.shadowRoot, newRRElement.shadowRoot, replayer, rrnodeMirror);\r\n            }\r\n            diffProps(oldElement, newRRElement, rrnodeMirror);\r\n            break;\r\n        }\r\n    }\r\n    return oldTree;\r\n}\r\nfunction diffAfterUpdatingChildren(oldTree, newTree, replayer) {\r\n    switch (newTree.RRNodeType) {\r\n        case NodeType$1.Document: {\r\n            const scrollData = newTree.scrollData;\r\n            scrollData && replayer.applyScroll(scrollData, true);\r\n            break;\r\n        }\r\n        case NodeType$1.Element: {\r\n            const oldElement = oldTree;\r\n            const newRRElement = newTree;\r\n            newRRElement.scrollData &&\r\n                replayer.applyScroll(newRRElement.scrollData, true);\r\n            newRRElement.inputData && replayer.applyInput(newRRElement.inputData);\r\n            switch (newRRElement.tagName) {\r\n                case 'AUDIO':\r\n                case 'VIDEO': {\r\n                    const oldMediaElement = oldTree;\r\n                    const newMediaRRElement = newRRElement;\r\n                    if (newMediaRRElement.paused !== undefined)\r\n                        newMediaRRElement.paused\r\n                            ? void oldMediaElement.pause()\r\n                            : void oldMediaElement.play();\r\n                    if (newMediaRRElement.muted !== undefined)\r\n                        oldMediaElement.muted = newMediaRRElement.muted;\r\n                    if (newMediaRRElement.volume !== undefined)\r\n                        oldMediaElement.volume = newMediaRRElement.volume;\r\n                    if (newMediaRRElement.currentTime !== undefined)\r\n                        oldMediaElement.currentTime = newMediaRRElement.currentTime;\r\n                    if (newMediaRRElement.playbackRate !== undefined)\r\n                        oldMediaElement.playbackRate = newMediaRRElement.playbackRate;\r\n                    break;\r\n                }\r\n                case 'CANVAS': {\r\n                    const rrCanvasElement = newTree;\r\n                    if (rrCanvasElement.rr_dataURL !== null) {\r\n                        const image = document.createElement('img');\r\n                        image.onload = () => {\r\n                            const ctx = oldElement.getContext('2d');\r\n                            if (ctx) {\r\n                                ctx.drawImage(image, 0, 0, image.width, image.height);\r\n                            }\r\n                        };\r\n                        image.src = rrCanvasElement.rr_dataURL;\r\n                    }\r\n                    rrCanvasElement.canvasMutations.forEach((canvasMutation) => replayer.applyCanvas(canvasMutation.event, canvasMutation.mutation, oldTree));\r\n                    break;\r\n                }\r\n                case 'STYLE': {\r\n                    const styleSheet = oldElement.sheet;\r\n                    styleSheet &&\r\n                        newTree.rules.forEach((data) => replayer.applyStyleSheetMutation(data, styleSheet));\r\n                    break;\r\n                }\r\n            }\r\n            break;\r\n        }\r\n        case NodeType$1.Text:\r\n        case NodeType$1.Comment:\r\n        case NodeType$1.CDATA: {\r\n            if (oldTree.textContent !==\r\n                newTree.data)\r\n                oldTree.textContent = newTree.data;\r\n            break;\r\n        }\r\n    }\r\n    if (createdNodeSet?.has(oldTree)) {\r\n        createdNodeSet.delete(oldTree);\r\n        replayer.afterAppend?.(oldTree, replayer.mirror.getId(oldTree));\r\n    }\r\n}\r\nfunction diffProps(oldTree, newTree, rrnodeMirror) {\r\n    const oldAttributes = oldTree.attributes;\r\n    const newAttributes = newTree.attributes;\r\n    for (const name in newAttributes) {\r\n        const newValue = newAttributes[name];\r\n        const sn = rrnodeMirror.getMeta(newTree);\r\n        if (sn?.isSVG && NAMESPACES[name])\r\n            oldTree.setAttributeNS(NAMESPACES[name], name, newValue);\r\n        else if (newTree.tagName === 'CANVAS' && name === 'rr_dataURL') {\r\n            const image = document.createElement('img');\r\n            image.src = newValue;\r\n            image.onload = () => {\r\n                const ctx = oldTree.getContext('2d');\r\n                if (ctx) {\r\n                    ctx.drawImage(image, 0, 0, image.width, image.height);\r\n                }\r\n            };\r\n        }\r\n        else if (newTree.tagName === 'IFRAME' && name === 'srcdoc')\r\n            continue;\r\n        else {\r\n            try {\r\n                oldTree.setAttribute(name, newValue);\r\n            }\r\n            catch (err) {\r\n                console.warn(err);\r\n            }\r\n        }\r\n    }\r\n    for (const { name } of Array.from(oldAttributes))\r\n        if (!(name in newAttributes))\r\n            oldTree.removeAttribute(name);\r\n    newTree.scrollLeft && (oldTree.scrollLeft = newTree.scrollLeft);\r\n    newTree.scrollTop && (oldTree.scrollTop = newTree.scrollTop);\r\n}\r\nfunction diffChildren(oldTree, newTree, replayer, rrnodeMirror) {\r\n    const oldChildren = Array.from(oldTree.childNodes);\r\n    const newChildren = newTree.childNodes;\r\n    if (oldChildren.length === 0 && newChildren.length === 0)\r\n        return;\r\n    let oldStartIndex = 0, oldEndIndex = oldChildren.length - 1, newStartIndex = 0, newEndIndex = newChildren.length - 1;\r\n    let oldStartNode = oldChildren[oldStartIndex], oldEndNode = oldChildren[oldEndIndex], newStartNode = newChildren[newStartIndex], newEndNode = newChildren[newEndIndex];\r\n    let oldIdToIndex = undefined, indexInOld = undefined;\r\n    while (oldStartIndex <= oldEndIndex && newStartIndex <= newEndIndex) {\r\n        if (oldStartNode === undefined) {\r\n            oldStartNode = oldChildren[++oldStartIndex];\r\n        }\r\n        else if (oldEndNode === undefined) {\r\n            oldEndNode = oldChildren[--oldEndIndex];\r\n        }\r\n        else if (nodeMatching(oldStartNode, newStartNode, replayer.mirror, rrnodeMirror)) {\r\n            oldStartNode = oldChildren[++oldStartIndex];\r\n            newStartNode = newChildren[++newStartIndex];\r\n        }\r\n        else if (nodeMatching(oldEndNode, newEndNode, replayer.mirror, rrnodeMirror)) {\r\n            oldEndNode = oldChildren[--oldEndIndex];\r\n            newEndNode = newChildren[--newEndIndex];\r\n        }\r\n        else if (nodeMatching(oldStartNode, newEndNode, replayer.mirror, rrnodeMirror)) {\r\n            try {\r\n                oldTree.insertBefore(oldStartNode, oldEndNode.nextSibling);\r\n            }\r\n            catch (e) {\r\n                console.warn(e);\r\n            }\r\n            oldStartNode = oldChildren[++oldStartIndex];\r\n            newEndNode = newChildren[--newEndIndex];\r\n        }\r\n        else if (nodeMatching(oldEndNode, newStartNode, replayer.mirror, rrnodeMirror)) {\r\n            try {\r\n                oldTree.insertBefore(oldEndNode, oldStartNode);\r\n            }\r\n            catch (e) {\r\n                console.warn(e);\r\n            }\r\n            oldEndNode = oldChildren[--oldEndIndex];\r\n            newStartNode = newChildren[++newStartIndex];\r\n        }\r\n        else {\r\n            if (!oldIdToIndex) {\r\n                oldIdToIndex = {};\r\n                for (let i = oldStartIndex; i <= oldEndIndex; i++) {\r\n                    const oldChild = oldChildren[i];\r\n                    if (oldChild && replayer.mirror.hasNode(oldChild))\r\n                        oldIdToIndex[replayer.mirror.getId(oldChild)] = i;\r\n                }\r\n            }\r\n            indexInOld = oldIdToIndex[rrnodeMirror.getId(newStartNode)];\r\n            const nodeToMove = oldChildren[indexInOld];\r\n            if (indexInOld !== undefined &&\r\n                nodeToMove &&\r\n                nodeMatching(nodeToMove, newStartNode, replayer.mirror, rrnodeMirror)) {\r\n                try {\r\n                    oldTree.insertBefore(nodeToMove, oldStartNode);\r\n                }\r\n                catch (e) {\r\n                    console.warn(e);\r\n                }\r\n                oldChildren[indexInOld] = undefined;\r\n            }\r\n            else {\r\n                const newNode = createOrGetNode(newStartNode, replayer.mirror, rrnodeMirror);\r\n                if (oldTree.nodeName === '#document' &&\r\n                    oldStartNode &&\r\n                    ((newNode.nodeType === newNode.DOCUMENT_TYPE_NODE &&\r\n                        oldStartNode.nodeType === oldStartNode.DOCUMENT_TYPE_NODE) ||\r\n                        (newNode.nodeType === newNode.ELEMENT_NODE &&\r\n                            oldStartNode.nodeType === oldStartNode.ELEMENT_NODE))) {\r\n                    oldTree.removeChild(oldStartNode);\r\n                    replayer.mirror.removeNodeFromMap(oldStartNode);\r\n                    oldStartNode = oldChildren[++oldStartIndex];\r\n                }\r\n                try {\r\n                    oldTree.insertBefore(newNode, oldStartNode || null);\r\n                }\r\n                catch (e) {\r\n                    console.warn(e);\r\n                }\r\n            }\r\n            newStartNode = newChildren[++newStartIndex];\r\n        }\r\n    }\r\n    if (oldStartIndex > oldEndIndex) {\r\n        const referenceRRNode = newChildren[newEndIndex + 1];\r\n        let referenceNode = null;\r\n        if (referenceRRNode)\r\n            referenceNode = replayer.mirror.getNode(rrnodeMirror.getId(referenceRRNode));\r\n        for (; newStartIndex <= newEndIndex; ++newStartIndex) {\r\n            const newNode = createOrGetNode(newChildren[newStartIndex], replayer.mirror, rrnodeMirror);\r\n            try {\r\n                oldTree.insertBefore(newNode, referenceNode);\r\n            }\r\n            catch (e) {\r\n                console.warn(e);\r\n            }\r\n        }\r\n    }\r\n    else if (newStartIndex > newEndIndex) {\r\n        for (; oldStartIndex <= oldEndIndex; oldStartIndex++) {\r\n            const node = oldChildren[oldStartIndex];\r\n            if (!node || node.parentNode !== oldTree)\r\n                continue;\r\n            try {\r\n                oldTree.removeChild(node);\r\n                replayer.mirror.removeNodeFromMap(node);\r\n            }\r\n            catch (e) {\r\n                console.warn(e);\r\n            }\r\n        }\r\n    }\r\n    let oldChild = oldTree.firstChild;\r\n    let newChild = newTree.firstChild;\r\n    while (oldChild !== null && newChild !== null) {\r\n        diff(oldChild, newChild, replayer, rrnodeMirror);\r\n        oldChild = oldChild.nextSibling;\r\n        newChild = newChild.nextSibling;\r\n    }\r\n}\r\nfunction createOrGetNode(rrNode, domMirror, rrnodeMirror) {\r\n    const nodeId = rrnodeMirror.getId(rrNode);\r\n    const sn = rrnodeMirror.getMeta(rrNode);\r\n    let node = null;\r\n    if (nodeId > -1)\r\n        node = domMirror.getNode(nodeId);\r\n    if (node !== null && sameNodeType(node, rrNode))\r\n        return node;\r\n    switch (rrNode.RRNodeType) {\r\n        case NodeType$1.Document:\r\n            node = new Document();\r\n            break;\r\n        case NodeType$1.DocumentType:\r\n            node = document.implementation.createDocumentType(rrNode.name, rrNode.publicId, rrNode.systemId);\r\n            break;\r\n        case NodeType$1.Element: {\r\n            let tagName = rrNode.tagName.toLowerCase();\r\n            tagName = SVGTagMap[tagName] || tagName;\r\n            if (sn && 'isSVG' in sn && sn?.isSVG) {\r\n                node = document.createElementNS(NAMESPACES['svg'], tagName);\r\n            }\r\n            else\r\n                node = document.createElement(rrNode.tagName);\r\n            break;\r\n        }\r\n        case NodeType$1.Text:\r\n            node = document.createTextNode(rrNode.data);\r\n            break;\r\n        case NodeType$1.Comment:\r\n            node = document.createComment(rrNode.data);\r\n            break;\r\n        case NodeType$1.CDATA:\r\n            node = document.createCDATASection(rrNode.data);\r\n            break;\r\n    }\r\n    if (sn)\r\n        domMirror.add(node, { ...sn });\r\n    try {\r\n        createdNodeSet?.add(node);\r\n    }\r\n    catch (e) {\r\n    }\r\n    return node;\r\n}\r\nfunction sameNodeType(node1, node2) {\r\n    if (node1.nodeType !== node2.nodeType)\r\n        return false;\r\n    return (node1.nodeType !== node1.ELEMENT_NODE ||\r\n        node1.tagName.toUpperCase() ===\r\n            node2.tagName);\r\n}\r\nfunction nodeMatching(node1, node2, domMirror, rrdomMirror) {\r\n    const node1Id = domMirror.getId(node1);\r\n    const node2Id = rrdomMirror.getId(node2);\r\n    if (node1Id === -1 || node1Id !== node2Id)\r\n        return false;\r\n    return sameNodeType(node1, node2);\r\n}\n\nclass RRDocument extends BaseRRDocumentImpl(BaseRRNode) {\r\n    get unserializedId() {\r\n        return this._unserializedId--;\r\n    }\r\n    constructor(mirror) {\r\n        super();\r\n        this.UNSERIALIZED_STARTING_ID = -2;\r\n        this._unserializedId = this.UNSERIALIZED_STARTING_ID;\r\n        this.mirror = createMirror();\r\n        this.scrollData = null;\r\n        if (mirror) {\r\n            this.mirror = mirror;\r\n        }\r\n    }\r\n    createDocument(_namespace, _qualifiedName, _doctype) {\r\n        return new RRDocument();\r\n    }\r\n    createDocumentType(qualifiedName, publicId, systemId) {\r\n        const documentTypeNode = new RRDocumentType(qualifiedName, publicId, systemId);\r\n        documentTypeNode.ownerDocument = this;\r\n        return documentTypeNode;\r\n    }\r\n    createElement(tagName) {\r\n        const upperTagName = tagName.toUpperCase();\r\n        let element;\r\n        switch (upperTagName) {\r\n            case 'AUDIO':\r\n            case 'VIDEO':\r\n                element = new RRMediaElement(upperTagName);\r\n                break;\r\n            case 'IFRAME':\r\n                element = new RRIFrameElement(upperTagName, this.mirror);\r\n                break;\r\n            case 'CANVAS':\r\n                element = new RRCanvasElement(upperTagName);\r\n                break;\r\n            case 'STYLE':\r\n                element = new RRStyleElement(upperTagName);\r\n                break;\r\n            default:\r\n                element = new RRElement(upperTagName);\r\n                break;\r\n        }\r\n        element.ownerDocument = this;\r\n        return element;\r\n    }\r\n    createComment(data) {\r\n        const commentNode = new RRComment(data);\r\n        commentNode.ownerDocument = this;\r\n        return commentNode;\r\n    }\r\n    createCDATASection(data) {\r\n        const sectionNode = new RRCDATASection(data);\r\n        sectionNode.ownerDocument = this;\r\n        return sectionNode;\r\n    }\r\n    createTextNode(data) {\r\n        const textNode = new RRText(data);\r\n        textNode.ownerDocument = this;\r\n        return textNode;\r\n    }\r\n    destroyTree() {\r\n        this.firstChild = null;\r\n        this.lastChild = null;\r\n        this.mirror.reset();\r\n    }\r\n    open() {\r\n        super.open();\r\n        this._unserializedId = this.UNSERIALIZED_STARTING_ID;\r\n    }\r\n}\r\nconst RRDocumentType = BaseRRDocumentTypeImpl(BaseRRNode);\r\nclass RRElement extends BaseRRElementImpl(BaseRRNode) {\r\n    constructor() {\r\n        super(...arguments);\r\n        this.inputData = null;\r\n        this.scrollData = null;\r\n    }\r\n}\r\nclass RRMediaElement extends BaseRRMediaElementImpl(RRElement) {\r\n}\r\nclass RRCanvasElement extends RRElement {\r\n    constructor() {\r\n        super(...arguments);\r\n        this.rr_dataURL = null;\r\n        this.canvasMutations = [];\r\n    }\r\n    getContext() {\r\n        return null;\r\n    }\r\n}\r\nclass RRStyleElement extends RRElement {\r\n    constructor() {\r\n        super(...arguments);\r\n        this.rules = [];\r\n    }\r\n}\r\nclass RRIFrameElement extends RRElement {\r\n    constructor(upperTagName, mirror) {\r\n        super(upperTagName);\r\n        this.contentDocument = new RRDocument();\r\n        this.contentDocument.mirror = mirror;\r\n    }\r\n}\r\nconst RRText = BaseRRTextImpl(BaseRRNode);\r\nconst RRComment = BaseRRCommentImpl(BaseRRNode);\r\nconst RRCDATASection = BaseRRCDATASectionImpl(BaseRRNode);\r\nfunction getValidTagName(element) {\r\n    if (element instanceof HTMLFormElement) {\r\n        return 'FORM';\r\n    }\r\n    return element.tagName.toUpperCase();\r\n}\r\nfunction buildFromNode(node, rrdom, domMirror, parentRRNode) {\r\n    let rrNode;\r\n    switch (node.nodeType) {\r\n        case NodeType.DOCUMENT_NODE:\r\n            if (parentRRNode && parentRRNode.nodeName === 'IFRAME')\r\n                rrNode = parentRRNode.contentDocument;\r\n            else {\r\n                rrNode = rrdom;\r\n                rrNode.compatMode = node.compatMode;\r\n            }\r\n            break;\r\n        case NodeType.DOCUMENT_TYPE_NODE: {\r\n            const documentType = node;\r\n            rrNode = rrdom.createDocumentType(documentType.name, documentType.publicId, documentType.systemId);\r\n            break;\r\n        }\r\n        case NodeType.ELEMENT_NODE: {\r\n            const elementNode = node;\r\n            const tagName = getValidTagName(elementNode);\r\n            rrNode = rrdom.createElement(tagName);\r\n            const rrElement = rrNode;\r\n            for (const { name, value } of Array.from(elementNode.attributes)) {\r\n                rrElement.attributes[name] = value;\r\n            }\r\n            elementNode.scrollLeft && (rrElement.scrollLeft = elementNode.scrollLeft);\r\n            elementNode.scrollTop && (rrElement.scrollTop = elementNode.scrollTop);\r\n            break;\r\n        }\r\n        case NodeType.TEXT_NODE:\r\n            rrNode = rrdom.createTextNode(node.textContent || '');\r\n            break;\r\n        case NodeType.CDATA_SECTION_NODE:\r\n            rrNode = rrdom.createCDATASection(node.data);\r\n            break;\r\n        case NodeType.COMMENT_NODE:\r\n            rrNode = rrdom.createComment(node.textContent || '');\r\n            break;\r\n        case NodeType.DOCUMENT_FRAGMENT_NODE:\r\n            rrNode = parentRRNode.attachShadow({ mode: 'open' });\r\n            break;\r\n        default:\r\n            return null;\r\n    }\r\n    let sn = domMirror.getMeta(node);\r\n    if (rrdom instanceof RRDocument) {\r\n        if (!sn) {\r\n            sn = getDefaultSN(rrNode, rrdom.unserializedId);\r\n            domMirror.add(node, sn);\r\n        }\r\n        rrdom.mirror.add(rrNode, { ...sn });\r\n    }\r\n    return rrNode;\r\n}\r\nfunction buildFromDom(dom, domMirror = createMirror$1(), rrdom = new RRDocument()) {\r\n    function walk(node, parentRRNode) {\r\n        const rrNode = buildFromNode(node, rrdom, domMirror, parentRRNode);\r\n        if (rrNode === null)\r\n            return;\r\n        if (parentRRNode?.nodeName !== 'IFRAME' &&\r\n            node.nodeType !== NodeType.DOCUMENT_FRAGMENT_NODE) {\r\n            parentRRNode?.appendChild(rrNode);\r\n            rrNode.parentNode = parentRRNode;\r\n            rrNode.parentElement = parentRRNode;\r\n        }\r\n        if (node.nodeName === 'IFRAME') {\r\n            const iframeDoc = getIFrameContentDocument(node);\r\n            iframeDoc && walk(iframeDoc, rrNode);\r\n        }\r\n        else if (node.nodeType === NodeType.DOCUMENT_NODE ||\r\n            node.nodeType === NodeType.ELEMENT_NODE ||\r\n            node.nodeType === NodeType.DOCUMENT_FRAGMENT_NODE) {\r\n            if (node.nodeType === NodeType.ELEMENT_NODE &&\r\n                node.shadowRoot)\r\n                walk(node.shadowRoot, rrNode);\r\n            node.childNodes.forEach((childNode) => walk(childNode, rrNode));\r\n        }\r\n    }\r\n    walk(dom, null);\r\n    return rrdom;\r\n}\r\nfunction createMirror() {\r\n    return new Mirror();\r\n}\r\nclass Mirror {\r\n    constructor() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n    getId(n) {\r\n        if (!n)\r\n            return -1;\r\n        const id = this.getMeta(n)?.id;\r\n        return id ?? -1;\r\n    }\r\n    getNode(id) {\r\n        return this.idNodeMap.get(id) || null;\r\n    }\r\n    getIds() {\r\n        return Array.from(this.idNodeMap.keys());\r\n    }\r\n    getMeta(n) {\r\n        return this.nodeMetaMap.get(n) || null;\r\n    }\r\n    removeNodeFromMap(n) {\r\n        const id = this.getId(n);\r\n        this.idNodeMap.delete(id);\r\n        if (n.childNodes) {\r\n            n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));\r\n        }\r\n    }\r\n    has(id) {\r\n        return this.idNodeMap.has(id);\r\n    }\r\n    hasNode(node) {\r\n        return this.nodeMetaMap.has(node);\r\n    }\r\n    add(n, meta) {\r\n        const id = meta.id;\r\n        this.idNodeMap.set(id, n);\r\n        this.nodeMetaMap.set(n, meta);\r\n    }\r\n    replace(id, n) {\r\n        const oldNode = this.getNode(id);\r\n        if (oldNode) {\r\n            const meta = this.nodeMetaMap.get(oldNode);\r\n            if (meta)\r\n                this.nodeMetaMap.set(n, meta);\r\n        }\r\n        this.idNodeMap.set(id, n);\r\n    }\r\n    reset() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n}\r\nfunction getDefaultSN(node, id) {\r\n    switch (node.RRNodeType) {\r\n        case NodeType$1.Document:\r\n            return {\r\n                id,\r\n                type: node.RRNodeType,\r\n                childNodes: [],\r\n            };\r\n        case NodeType$1.DocumentType: {\r\n            const doctype = node;\r\n            return {\r\n                id,\r\n                type: node.RRNodeType,\r\n                name: doctype.name,\r\n                publicId: doctype.publicId,\r\n                systemId: doctype.systemId,\r\n            };\r\n        }\r\n        case NodeType$1.Element:\r\n            return {\r\n                id,\r\n                type: node.RRNodeType,\r\n                tagName: node.tagName.toLowerCase(),\r\n                attributes: {},\r\n                childNodes: [],\r\n            };\r\n        case NodeType$1.Text:\r\n            return {\r\n                id,\r\n                type: node.RRNodeType,\r\n                textContent: node.textContent || '',\r\n            };\r\n        case NodeType$1.Comment:\r\n            return {\r\n                id,\r\n                type: node.RRNodeType,\r\n                textContent: node.textContent || '',\r\n            };\r\n        case NodeType$1.CDATA:\r\n            return {\r\n                id,\r\n                type: node.RRNodeType,\r\n                textContent: '',\r\n            };\r\n    }\r\n}\n\nexport { BaseRRCDATASectionImpl, BaseRRCommentImpl, BaseRRDocumentImpl, BaseRRDocumentTypeImpl, BaseRRElementImpl, BaseRRMediaElementImpl, BaseRRNode, BaseRRTextImpl, ClassList, Mirror, NodeType, RRCDATASection, RRCanvasElement, RRComment, RRDocument, RRDocumentType, RRElement, RRIFrameElement, RRMediaElement, BaseRRNode as RRNode, RRStyleElement, RRText, buildFromDom, buildFromNode, createMirror, createOrGetNode, diff, getDefaultSN, getIFrameContentDocument, getIFrameContentWindow };\n", "import { isShadowRoot, isNativeShadowDom, getInputType, getInputValue, shouldMaskInput, needMaskingText, maskInputValue, ignoreAttribute, transformAttribute, toLowerCase, IGNORED_NODE, serializeNodeWithId } from '../../../rrweb-snapshot/es/rrweb-snapshot.js';\nimport { isIgnored, isBlocked, isSerialized, isAncestorRemoved, closestElementOfNode, hasShadowRoot, inDom, getShadowHost, isSerializedIframe, isSerializedStylesheet } from '../utils.js';\nimport { getIFrameContentDocument } from '../../../rrdom/es/rrdom.js';\n\nfunction isNodeInLinkedList(n) {\r\n    return '__ln' in n;\r\n}\r\nclass DoubleLinkedList {\r\n    constructor() {\r\n        this.length = 0;\r\n        this.head = null;\r\n        this.tail = null;\r\n    }\r\n    get(position) {\r\n        if (position >= this.length) {\r\n            throw new Error('Position outside of list range');\r\n        }\r\n        let current = this.head;\r\n        for (let index = 0; index < position; index++) {\r\n            current = current?.next || null;\r\n        }\r\n        return current;\r\n    }\r\n    addNode(n) {\r\n        const node = {\r\n            value: n,\r\n            previous: null,\r\n            next: null,\r\n        };\r\n        n.__ln = node;\r\n        if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {\r\n            const current = n.previousSibling.__ln.next;\r\n            node.next = current;\r\n            node.previous = n.previousSibling.__ln;\r\n            n.previousSibling.__ln.next = node;\r\n            if (current) {\r\n                current.previous = node;\r\n            }\r\n        }\r\n        else if (n.nextSibling &&\r\n            isNodeInLinkedList(n.nextSibling) &&\r\n            n.nextSibling.__ln.previous) {\r\n            const current = n.nextSibling.__ln.previous;\r\n            node.previous = current;\r\n            node.next = n.nextSibling.__ln;\r\n            n.nextSibling.__ln.previous = node;\r\n            if (current) {\r\n                current.next = node;\r\n            }\r\n        }\r\n        else {\r\n            if (this.head) {\r\n                this.head.previous = node;\r\n            }\r\n            node.next = this.head;\r\n            this.head = node;\r\n        }\r\n        if (node.next === null) {\r\n            this.tail = node;\r\n        }\r\n        this.length++;\r\n    }\r\n    removeNode(n) {\r\n        const current = n.__ln;\r\n        if (!this.head) {\r\n            return;\r\n        }\r\n        if (!current.previous) {\r\n            this.head = current.next;\r\n            if (this.head) {\r\n                this.head.previous = null;\r\n            }\r\n            else {\r\n                this.tail = null;\r\n            }\r\n        }\r\n        else {\r\n            current.previous.next = current.next;\r\n            if (current.next) {\r\n                current.next.previous = current.previous;\r\n            }\r\n            else {\r\n                this.tail = current.previous;\r\n            }\r\n        }\r\n        if (n.__ln) {\r\n            delete n.__ln;\r\n        }\r\n        this.length--;\r\n    }\r\n}\r\nconst moveKey = (id, parentId) => `${id}@${parentId}`;\r\nclass MutationBuffer {\r\n    constructor() {\r\n        this.frozen = false;\r\n        this.locked = false;\r\n        this.texts = [];\r\n        this.attributes = [];\r\n        this.attributeMap = new WeakMap();\r\n        this.removes = [];\r\n        this.mapRemoves = [];\r\n        this.movedMap = {};\r\n        this.addedSet = new Set();\r\n        this.movedSet = new Set();\r\n        this.droppedSet = new Set();\r\n        this.processMutations = (mutations) => {\r\n            mutations.forEach(this.processMutation);\r\n            this.emit();\r\n        };\r\n        this.emit = () => {\r\n            if (this.frozen || this.locked) {\r\n                return;\r\n            }\r\n            const adds = [];\r\n            const addedIds = new Set();\r\n            const addList = new DoubleLinkedList();\r\n            const getNextId = (n) => {\r\n                let ns = n;\r\n                let nextId = IGNORED_NODE;\r\n                while (nextId === IGNORED_NODE) {\r\n                    ns = ns && ns.nextSibling;\r\n                    nextId = ns && this.mirror.getId(ns);\r\n                }\r\n                return nextId;\r\n            };\r\n            const pushAdd = (n) => {\r\n                if (!n.parentNode || !inDom(n)) {\r\n                    return;\r\n                }\r\n                const parentId = isShadowRoot(n.parentNode)\r\n                    ? this.mirror.getId(getShadowHost(n))\r\n                    : this.mirror.getId(n.parentNode);\r\n                const nextId = getNextId(n);\r\n                if (parentId === -1 || nextId === -1) {\r\n                    return addList.addNode(n);\r\n                }\r\n                const sn = serializeNodeWithId(n, {\r\n                    doc: this.doc,\r\n                    mirror: this.mirror,\r\n                    blockClass: this.blockClass,\r\n                    blockSelector: this.blockSelector,\r\n                    maskAllText: this.maskAllText,\r\n                    unblockSelector: this.unblockSelector,\r\n                    maskTextClass: this.maskTextClass,\r\n                    unmaskTextClass: this.unmaskTextClass,\r\n                    maskTextSelector: this.maskTextSelector,\r\n                    unmaskTextSelector: this.unmaskTextSelector,\r\n                    skipChild: true,\r\n                    newlyAddedElement: true,\r\n                    inlineStylesheet: this.inlineStylesheet,\r\n                    maskInputOptions: this.maskInputOptions,\r\n                    maskAttributeFn: this.maskAttributeFn,\r\n                    maskTextFn: this.maskTextFn,\r\n                    maskInputFn: this.maskInputFn,\r\n                    slimDOMOptions: this.slimDOMOptions,\r\n                    dataURLOptions: this.dataURLOptions,\r\n                    recordCanvas: this.recordCanvas,\r\n                    inlineImages: this.inlineImages,\r\n                    onSerialize: (currentN) => {\r\n                        if (isSerializedIframe(currentN, this.mirror) &&\r\n                            !isBlocked(currentN, this.blockClass, this.blockSelector, this.unblockSelector, false)) {\r\n                            this.iframeManager.addIframe(currentN);\r\n                        }\r\n                        if (isSerializedStylesheet(currentN, this.mirror)) {\r\n                            this.stylesheetManager.trackLinkElement(currentN);\r\n                        }\r\n                        if (hasShadowRoot(n)) {\r\n                            this.shadowDomManager.addShadowRoot(n.shadowRoot, this.doc);\r\n                        }\r\n                    },\r\n                    onIframeLoad: (iframe, childSn) => {\r\n                        if (isBlocked(iframe, this.blockClass, this.blockSelector, this.unblockSelector, false)) {\r\n                            return;\r\n                        }\r\n                        this.iframeManager.attachIframe(iframe, childSn);\r\n                        if (iframe.contentWindow) {\r\n                            this.canvasManager.addWindow(iframe.contentWindow);\r\n                        }\r\n                        this.shadowDomManager.observeAttachShadow(iframe);\r\n                    },\r\n                    onStylesheetLoad: (link, childSn) => {\r\n                        this.stylesheetManager.attachLinkElement(link, childSn);\r\n                    },\r\n                });\r\n                if (sn) {\r\n                    adds.push({\r\n                        parentId,\r\n                        nextId,\r\n                        node: sn,\r\n                    });\r\n                    addedIds.add(sn.id);\r\n                }\r\n            };\r\n            while (this.mapRemoves.length) {\r\n                this.mirror.removeNodeFromMap(this.mapRemoves.shift());\r\n            }\r\n            for (const n of this.movedSet) {\r\n                if (isParentRemoved(this.removes, n, this.mirror) &&\r\n                    !this.movedSet.has(n.parentNode)) {\r\n                    continue;\r\n                }\r\n                pushAdd(n);\r\n            }\r\n            for (const n of this.addedSet) {\r\n                if (!isAncestorInSet(this.droppedSet, n) &&\r\n                    !isParentRemoved(this.removes, n, this.mirror)) {\r\n                    pushAdd(n);\r\n                }\r\n                else if (isAncestorInSet(this.movedSet, n)) {\r\n                    pushAdd(n);\r\n                }\r\n                else {\r\n                    this.droppedSet.add(n);\r\n                }\r\n            }\r\n            let candidate = null;\r\n            while (addList.length) {\r\n                let node = null;\r\n                if (candidate) {\r\n                    const parentId = this.mirror.getId(candidate.value.parentNode);\r\n                    const nextId = getNextId(candidate.value);\r\n                    if (parentId !== -1 && nextId !== -1) {\r\n                        node = candidate;\r\n                    }\r\n                }\r\n                if (!node) {\r\n                    let tailNode = addList.tail;\r\n                    while (tailNode) {\r\n                        const _node = tailNode;\r\n                        tailNode = tailNode.previous;\r\n                        if (_node) {\r\n                            const parentId = this.mirror.getId(_node.value.parentNode);\r\n                            const nextId = getNextId(_node.value);\r\n                            if (nextId === -1)\r\n                                continue;\r\n                            else if (parentId !== -1) {\r\n                                node = _node;\r\n                                break;\r\n                            }\r\n                            else {\r\n                                const unhandledNode = _node.value;\r\n                                if (unhandledNode.parentNode &&\r\n                                    unhandledNode.parentNode.nodeType ===\r\n                                        Node.DOCUMENT_FRAGMENT_NODE) {\r\n                                    const shadowHost = unhandledNode.parentNode\r\n                                        .host;\r\n                                    const parentId = this.mirror.getId(shadowHost);\r\n                                    if (parentId !== -1) {\r\n                                        node = _node;\r\n                                        break;\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                if (!node) {\r\n                    while (addList.head) {\r\n                        addList.removeNode(addList.head.value);\r\n                    }\r\n                    break;\r\n                }\r\n                candidate = node.previous;\r\n                addList.removeNode(node.value);\r\n                pushAdd(node.value);\r\n            }\r\n            const payload = {\r\n                texts: this.texts\r\n                    .map((text) => ({\r\n                    id: this.mirror.getId(text.node),\r\n                    value: text.value,\r\n                }))\r\n                    .filter((text) => !addedIds.has(text.id))\r\n                    .filter((text) => this.mirror.has(text.id)),\r\n                attributes: this.attributes\r\n                    .map((attribute) => {\r\n                    const { attributes } = attribute;\r\n                    if (typeof attributes.style === 'string') {\r\n                        const diffAsStr = JSON.stringify(attribute.styleDiff);\r\n                        const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);\r\n                        if (diffAsStr.length < attributes.style.length) {\r\n                            if ((diffAsStr + unchangedAsStr).split('var(').length ===\r\n                                attributes.style.split('var(').length) {\r\n                                attributes.style = attribute.styleDiff;\r\n                            }\r\n                        }\r\n                    }\r\n                    return {\r\n                        id: this.mirror.getId(attribute.node),\r\n                        attributes: attributes,\r\n                    };\r\n                })\r\n                    .filter((attribute) => !addedIds.has(attribute.id))\r\n                    .filter((attribute) => this.mirror.has(attribute.id)),\r\n                removes: this.removes,\r\n                adds,\r\n            };\r\n            if (!payload.texts.length &&\r\n                !payload.attributes.length &&\r\n                !payload.removes.length &&\r\n                !payload.adds.length) {\r\n                return;\r\n            }\r\n            this.texts = [];\r\n            this.attributes = [];\r\n            this.attributeMap = new WeakMap();\r\n            this.removes = [];\r\n            this.addedSet = new Set();\r\n            this.movedSet = new Set();\r\n            this.droppedSet = new Set();\r\n            this.movedMap = {};\r\n            this.mutationCb(payload);\r\n        };\r\n        this.processMutation = (m) => {\r\n            if (isIgnored(m.target, this.mirror)) {\r\n                return;\r\n            }\r\n            switch (m.type) {\r\n                case 'characterData': {\r\n                    const value = m.target.textContent;\r\n                    if (!isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) &&\r\n                        value !== m.oldValue) {\r\n                        this.texts.push({\r\n                            value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, this.maskAllText) && value\r\n                                ? this.maskTextFn\r\n                                    ? this.maskTextFn(value, closestElementOfNode(m.target))\r\n                                    : value.replace(/[\\S]/g, '*')\r\n                                : value,\r\n                            node: m.target,\r\n                        });\r\n                    }\r\n                    break;\r\n                }\r\n                case 'attributes': {\r\n                    const target = m.target;\r\n                    let attributeName = m.attributeName;\r\n                    let value = m.target.getAttribute(attributeName);\r\n                    if (attributeName === 'value') {\r\n                        const type = getInputType(target);\r\n                        const tagName = target.tagName;\r\n                        value = getInputValue(target, tagName, type);\r\n                        const isInputMasked = shouldMaskInput({\r\n                            maskInputOptions: this.maskInputOptions,\r\n                            tagName,\r\n                            type,\r\n                        });\r\n                        const forceMask = needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, isInputMasked);\r\n                        value = maskInputValue({\r\n                            isMasked: forceMask,\r\n                            element: target,\r\n                            value,\r\n                            maskInputFn: this.maskInputFn,\r\n                        });\r\n                    }\r\n                    if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||\r\n                        value === m.oldValue) {\r\n                        return;\r\n                    }\r\n                    let item = this.attributeMap.get(m.target);\r\n                    if (target.tagName === 'IFRAME' &&\r\n                        attributeName === 'src' &&\r\n                        !this.keepIframeSrcFn(value)) {\r\n                        const iframeDoc = getIFrameContentDocument(target);\r\n                        if (!iframeDoc) {\r\n                            attributeName = 'rr_src';\r\n                        }\r\n                        else {\r\n                            return;\r\n                        }\r\n                    }\r\n                    if (!item) {\r\n                        item = {\r\n                            node: m.target,\r\n                            attributes: {},\r\n                            styleDiff: {},\r\n                            _unchangedStyles: {},\r\n                        };\r\n                        this.attributes.push(item);\r\n                        this.attributeMap.set(m.target, item);\r\n                    }\r\n                    if (attributeName === 'type' &&\r\n                        target.tagName === 'INPUT' &&\r\n                        (m.oldValue || '').toLowerCase() === 'password') {\r\n                        target.setAttribute('data-rr-is-password', 'true');\r\n                    }\r\n                    if (!ignoreAttribute(target.tagName, attributeName)) {\r\n                        item.attributes[attributeName] = transformAttribute(this.doc, toLowerCase(target.tagName), toLowerCase(attributeName), value, target, this.maskAttributeFn);\r\n                        if (attributeName === 'style') {\r\n                            if (!this.unattachedDoc) {\r\n                                try {\r\n                                    this.unattachedDoc =\r\n                                        document.implementation.createHTMLDocument();\r\n                                }\r\n                                catch (e) {\r\n                                    this.unattachedDoc = this.doc;\r\n                                }\r\n                            }\r\n                            const old = this.unattachedDoc.createElement('span');\r\n                            if (m.oldValue) {\r\n                                old.setAttribute('style', m.oldValue);\r\n                            }\r\n                            for (const pname of Array.from(target.style)) {\r\n                                const newValue = target.style.getPropertyValue(pname);\r\n                                const newPriority = target.style.getPropertyPriority(pname);\r\n                                if (newValue !== old.style.getPropertyValue(pname) ||\r\n                                    newPriority !== old.style.getPropertyPriority(pname)) {\r\n                                    if (newPriority === '') {\r\n                                        item.styleDiff[pname] = newValue;\r\n                                    }\r\n                                    else {\r\n                                        item.styleDiff[pname] = [newValue, newPriority];\r\n                                    }\r\n                                }\r\n                                else {\r\n                                    item._unchangedStyles[pname] = [newValue, newPriority];\r\n                                }\r\n                            }\r\n                            for (const pname of Array.from(old.style)) {\r\n                                if (target.style.getPropertyValue(pname) === '') {\r\n                                    item.styleDiff[pname] = false;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                    break;\r\n                }\r\n                case 'childList': {\r\n                    if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, true)) {\r\n                        return;\r\n                    }\r\n                    m.addedNodes.forEach((n) => this.genAdds(n, m.target));\r\n                    m.removedNodes.forEach((n) => {\r\n                        const nodeId = this.mirror.getId(n);\r\n                        const parentId = isShadowRoot(m.target)\r\n                            ? this.mirror.getId(m.target.host)\r\n                            : this.mirror.getId(m.target);\r\n                        if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||\r\n                            isIgnored(n, this.mirror) ||\r\n                            !isSerialized(n, this.mirror)) {\r\n                            return;\r\n                        }\r\n                        if (this.addedSet.has(n)) {\r\n                            deepDelete(this.addedSet, n);\r\n                            this.droppedSet.add(n);\r\n                        }\r\n                        else if (this.addedSet.has(m.target) && nodeId === -1) ;\r\n                        else if (isAncestorRemoved(m.target, this.mirror)) ;\r\n                        else if (this.movedSet.has(n) &&\r\n                            this.movedMap[moveKey(nodeId, parentId)]) {\r\n                            deepDelete(this.movedSet, n);\r\n                        }\r\n                        else {\r\n                            this.removes.push({\r\n                                parentId,\r\n                                id: nodeId,\r\n                                isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target)\r\n                                    ? true\r\n                                    : undefined,\r\n                            });\r\n                        }\r\n                        this.mapRemoves.push(n);\r\n                    });\r\n                    break;\r\n                }\r\n            }\r\n        };\r\n        this.genAdds = (n, target) => {\r\n            if (this.processedNodeManager.inOtherBuffer(n, this))\r\n                return;\r\n            if (this.addedSet.has(n) || this.movedSet.has(n))\r\n                return;\r\n            if (this.mirror.hasNode(n)) {\r\n                if (isIgnored(n, this.mirror)) {\r\n                    return;\r\n                }\r\n                this.movedSet.add(n);\r\n                let targetId = null;\r\n                if (target && this.mirror.hasNode(target)) {\r\n                    targetId = this.mirror.getId(target);\r\n                }\r\n                if (targetId && targetId !== -1) {\r\n                    this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;\r\n                }\r\n            }\r\n            else {\r\n                this.addedSet.add(n);\r\n                this.droppedSet.delete(n);\r\n            }\r\n            if (!isBlocked(n, this.blockClass, this.blockSelector, this.unblockSelector, false)) {\r\n                n.childNodes.forEach((childN) => this.genAdds(childN));\r\n                if (hasShadowRoot(n)) {\r\n                    n.shadowRoot.childNodes.forEach((childN) => {\r\n                        this.processedNodeManager.add(childN, this);\r\n                        this.genAdds(childN, n);\r\n                    });\r\n                }\r\n            }\r\n        };\r\n    }\r\n    init(options) {\r\n        [\r\n            'mutationCb',\r\n            'blockClass',\r\n            'blockSelector',\r\n            'unblockSelector',\r\n            'maskAllText',\r\n            'maskTextClass',\r\n            'unmaskTextClass',\r\n            'maskTextSelector',\r\n            'unmaskTextSelector',\r\n            'inlineStylesheet',\r\n            'maskInputOptions',\r\n            'maskAttributeFn',\r\n            'maskTextFn',\r\n            'maskInputFn',\r\n            'keepIframeSrcFn',\r\n            'recordCanvas',\r\n            'inlineImages',\r\n            'slimDOMOptions',\r\n            'dataURLOptions',\r\n            'doc',\r\n            'mirror',\r\n            'iframeManager',\r\n            'stylesheetManager',\r\n            'shadowDomManager',\r\n            'canvasManager',\r\n            'processedNodeManager',\r\n        ].forEach((key) => {\r\n            this[key] = options[key];\r\n        });\r\n    }\r\n    freeze() {\r\n        this.frozen = true;\r\n        this.canvasManager.freeze();\r\n    }\r\n    unfreeze() {\r\n        this.frozen = false;\r\n        this.canvasManager.unfreeze();\r\n        this.emit();\r\n    }\r\n    isFrozen() {\r\n        return this.frozen;\r\n    }\r\n    lock() {\r\n        this.locked = true;\r\n        this.canvasManager.lock();\r\n    }\r\n    unlock() {\r\n        this.locked = false;\r\n        this.canvasManager.unlock();\r\n        this.emit();\r\n    }\r\n    reset() {\r\n        this.shadowDomManager.reset();\r\n        this.canvasManager.reset();\r\n    }\r\n}\r\nfunction deepDelete(addsSet, n) {\r\n    addsSet.delete(n);\r\n    n.childNodes.forEach((childN) => deepDelete(addsSet, childN));\r\n}\r\nfunction isParentRemoved(removes, n, mirror) {\r\n    if (removes.length === 0)\r\n        return false;\r\n    return _isParentRemoved(removes, n, mirror);\r\n}\r\nfunction _isParentRemoved(removes, n, mirror) {\r\n    let node = n.parentNode;\r\n    while (node) {\r\n        const parentId = mirror.getId(node);\r\n        if (removes.some((r) => r.id === parentId)) {\r\n            return true;\r\n        }\r\n        node = node.parentNode;\r\n    }\r\n    return false;\r\n}\r\nfunction isAncestorInSet(set, n) {\r\n    if (set.size === 0)\r\n        return false;\r\n    return _isAncestorInSet(set, n);\r\n}\r\nfunction _isAncestorInSet(set, n) {\r\n    const { parentNode } = n;\r\n    if (!parentNode) {\r\n        return false;\r\n    }\r\n    if (set.has(parentNode)) {\r\n        return true;\r\n    }\r\n    return _isAncestorInSet(set, parentNode);\r\n}\n\nexport { MutationBuffer as default };\n", "let errorHandler;\r\nfunction registerErrorHandler(handler) {\r\n    errorHandler = handler;\r\n}\r\nfunction unregisterErrorHandler() {\r\n    errorHandler = undefined;\r\n}\r\nconst callbackWrapper = (cb) => {\r\n    if (!errorHandler) {\r\n        return cb;\r\n    }\r\n    const rrwebWrapped = ((...rest) => {\r\n        try {\r\n            return cb(...rest);\r\n        }\r\n        catch (error) {\r\n            if (errorHandler && errorHandler(error) === true) {\r\n                return () => {\r\n                };\r\n            }\r\n            throw error;\r\n        }\r\n    });\r\n    return rrwebWrapped;\r\n};\n\nexport { callbackWrapper, registerErrorHandler, unregisterErrorHandler };\n", "import { toLowerCase, toUpperCase, getInputType, getInputValue, shouldMaskInput, needMaskingText, maskInputValue } from '../../../rrweb-snapshot/es/rrweb-snapshot.js';\nimport { on, throttle, isBlocked, getWindowScroll, hookSetter, patch, setTimeout, legacy_isTouchEvent, nowTimestamp, getWindowHeight, getWindowWidth } from '../utils.js';\nimport { MouseInteractions, IncrementalSource, PointerTypes } from '../../../types/dist/rrweb-types.js';\nimport MutationBuffer from './mutation.js';\nimport { callbackWrapper } from './error-handler.js';\n\nconst mutationBuffers = [];\r\nfunction getEventTarget(event) {\r\n    try {\r\n        if ('composedPath' in event) {\r\n            const path = event.composedPath();\r\n            if (path.length) {\r\n                return path[0];\r\n            }\r\n        }\r\n        else if ('path' in event && event.path.length) {\r\n            return event.path[0];\r\n        }\r\n    }\r\n    catch {\r\n    }\r\n    return event && event.target;\r\n}\r\nfunction initMutationObserver(options, rootEl) {\r\n    const mutationBuffer = new MutationBuffer();\r\n    mutationBuffers.push(mutationBuffer);\r\n    mutationBuffer.init(options);\r\n    let mutationObserverCtor = window.MutationObserver ||\r\n        window.__rrMutationObserver;\r\n    const angularZoneSymbol = window?.Zone?.__symbol__?.('MutationObserver');\r\n    if (angularZoneSymbol &&\r\n        window[angularZoneSymbol]) {\r\n        mutationObserverCtor = window[angularZoneSymbol];\r\n    }\r\n    const observer = new mutationObserverCtor(callbackWrapper((mutations) => {\r\n        if (options.onMutation && options.onMutation(mutations) === false) {\r\n            return;\r\n        }\r\n        mutationBuffer.processMutations.bind(mutationBuffer)(mutations);\r\n    }));\r\n    observer.observe(rootEl, {\r\n        attributes: true,\r\n        attributeOldValue: true,\r\n        characterData: true,\r\n        characterDataOldValue: true,\r\n        childList: true,\r\n        subtree: true,\r\n    });\r\n    return observer;\r\n}\r\nfunction initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {\r\n    if (sampling.mousemove === false) {\r\n        return () => {\r\n        };\r\n    }\r\n    const threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;\r\n    const callbackThreshold = typeof sampling.mousemoveCallback === 'number'\r\n        ? sampling.mousemoveCallback\r\n        : 500;\r\n    let positions = [];\r\n    let timeBaseline;\r\n    const wrappedCb = throttle(callbackWrapper((source) => {\r\n        const totalOffset = Date.now() - timeBaseline;\r\n        mousemoveCb(positions.map((p) => {\r\n            p.timeOffset -= totalOffset;\r\n            return p;\r\n        }), source);\r\n        positions = [];\r\n        timeBaseline = null;\r\n    }), callbackThreshold);\r\n    const updatePosition = callbackWrapper(throttle(callbackWrapper((evt) => {\r\n        const target = getEventTarget(evt);\r\n        const { clientX, clientY } = legacy_isTouchEvent(evt)\r\n            ? evt.changedTouches[0]\r\n            : evt;\r\n        if (!timeBaseline) {\r\n            timeBaseline = nowTimestamp();\r\n        }\r\n        positions.push({\r\n            x: clientX,\r\n            y: clientY,\r\n            id: mirror.getId(target),\r\n            timeOffset: nowTimestamp() - timeBaseline,\r\n        });\r\n        wrappedCb(typeof DragEvent !== 'undefined' && evt instanceof DragEvent\r\n            ? IncrementalSource.Drag\r\n            : evt instanceof MouseEvent\r\n                ? IncrementalSource.MouseMove\r\n                : IncrementalSource.TouchMove);\r\n    }), threshold, {\r\n        trailing: false,\r\n    }));\r\n    const handlers = [\r\n        on('mousemove', updatePosition, doc),\r\n        on('touchmove', updatePosition, doc),\r\n        on('drag', updatePosition, doc),\r\n    ];\r\n    return callbackWrapper(() => {\r\n        handlers.forEach((h) => h());\r\n    });\r\n}\r\nfunction initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {\r\n    if (sampling.mouseInteraction === false) {\r\n        return () => {\r\n        };\r\n    }\r\n    const disableMap = sampling.mouseInteraction === true ||\r\n        sampling.mouseInteraction === undefined\r\n        ? {}\r\n        : sampling.mouseInteraction;\r\n    const handlers = [];\r\n    let currentPointerType = null;\r\n    const getHandler = (eventKey) => {\r\n        return (event) => {\r\n            const target = getEventTarget(event);\r\n            if (isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\r\n                return;\r\n            }\r\n            let pointerType = null;\r\n            let thisEventKey = eventKey;\r\n            if ('pointerType' in event) {\r\n                switch (event.pointerType) {\r\n                    case 'mouse':\r\n                        pointerType = PointerTypes.Mouse;\r\n                        break;\r\n                    case 'touch':\r\n                        pointerType = PointerTypes.Touch;\r\n                        break;\r\n                    case 'pen':\r\n                        pointerType = PointerTypes.Pen;\r\n                        break;\r\n                }\r\n                if (pointerType === PointerTypes.Touch) {\r\n                    if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {\r\n                        thisEventKey = 'TouchStart';\r\n                    }\r\n                    else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {\r\n                        thisEventKey = 'TouchEnd';\r\n                    }\r\n                }\r\n                else if (pointerType === PointerTypes.Pen) ;\r\n            }\r\n            else if (legacy_isTouchEvent(event)) {\r\n                pointerType = PointerTypes.Touch;\r\n            }\r\n            if (pointerType !== null) {\r\n                currentPointerType = pointerType;\r\n                if ((thisEventKey.startsWith('Touch') &&\r\n                    pointerType === PointerTypes.Touch) ||\r\n                    (thisEventKey.startsWith('Mouse') &&\r\n                        pointerType === PointerTypes.Mouse)) {\r\n                    pointerType = null;\r\n                }\r\n            }\r\n            else if (MouseInteractions[eventKey] === MouseInteractions.Click) {\r\n                pointerType = currentPointerType;\r\n                currentPointerType = null;\r\n            }\r\n            const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;\r\n            if (!e) {\r\n                return;\r\n            }\r\n            const id = mirror.getId(target);\r\n            const { clientX, clientY } = e;\r\n            callbackWrapper(mouseInteractionCb)({\r\n                type: MouseInteractions[thisEventKey],\r\n                id,\r\n                x: clientX,\r\n                y: clientY,\r\n                ...(pointerType !== null && { pointerType }),\r\n            });\r\n        };\r\n    };\r\n    Object.keys(MouseInteractions)\r\n        .filter((key) => Number.isNaN(Number(key)) &&\r\n        !key.endsWith('_Departed') &&\r\n        disableMap[key] !== false)\r\n        .forEach((eventKey) => {\r\n        let eventName = toLowerCase(eventKey);\r\n        const handler = getHandler(eventKey);\r\n        if (window.PointerEvent) {\r\n            switch (MouseInteractions[eventKey]) {\r\n                case MouseInteractions.MouseDown:\r\n                case MouseInteractions.MouseUp:\r\n                    eventName = eventName.replace('mouse', 'pointer');\r\n                    break;\r\n                case MouseInteractions.TouchStart:\r\n                case MouseInteractions.TouchEnd:\r\n                    return;\r\n            }\r\n        }\r\n        handlers.push(on(eventName, handler, doc));\r\n    });\r\n    return callbackWrapper(() => {\r\n        handlers.forEach((h) => h());\r\n    });\r\n}\r\nfunction initScrollObserver({ scrollCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {\r\n    const updatePosition = callbackWrapper(throttle(callbackWrapper((evt) => {\r\n        const target = getEventTarget(evt);\r\n        if (!target ||\r\n            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\r\n            return;\r\n        }\r\n        const id = mirror.getId(target);\r\n        if (target === doc && doc.defaultView) {\r\n            const scrollLeftTop = getWindowScroll(doc.defaultView);\r\n            scrollCb({\r\n                id,\r\n                x: scrollLeftTop.left,\r\n                y: scrollLeftTop.top,\r\n            });\r\n        }\r\n        else {\r\n            scrollCb({\r\n                id,\r\n                x: target.scrollLeft,\r\n                y: target.scrollTop,\r\n            });\r\n        }\r\n    }), sampling.scroll || 100));\r\n    return on('scroll', updatePosition, doc);\r\n}\r\nfunction initViewportResizeObserver({ viewportResizeCb }, { win }) {\r\n    let lastH = -1;\r\n    let lastW = -1;\r\n    const updateDimension = callbackWrapper(throttle(callbackWrapper(() => {\r\n        const height = getWindowHeight();\r\n        const width = getWindowWidth();\r\n        if (lastH !== height || lastW !== width) {\r\n            viewportResizeCb({\r\n                width: Number(width),\r\n                height: Number(height),\r\n            });\r\n            lastH = height;\r\n            lastW = width;\r\n        }\r\n    }), 200));\r\n    return on('resize', updateDimension, win);\r\n}\r\nconst INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];\r\nconst lastInputValueMap = new WeakMap();\r\nfunction initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, unblockSelector, ignoreClass, ignoreSelector, maskInputOptions, maskInputFn, sampling, userTriggeredOnInput, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, }) {\r\n    function eventHandler(event) {\r\n        let target = getEventTarget(event);\r\n        const userTriggered = event.isTrusted;\r\n        const tagName = target && toUpperCase(target.tagName);\r\n        if (tagName === 'OPTION')\r\n            target = target.parentElement;\r\n        if (!target ||\r\n            !tagName ||\r\n            INPUT_TAGS.indexOf(tagName) < 0 ||\r\n            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\r\n            return;\r\n        }\r\n        const el = target;\r\n        if (el.classList.contains(ignoreClass) ||\r\n            (ignoreSelector && el.matches(ignoreSelector))) {\r\n            return;\r\n        }\r\n        const type = getInputType(target);\r\n        let text = getInputValue(el, tagName, type);\r\n        let isChecked = false;\r\n        const isInputMasked = shouldMaskInput({\r\n            maskInputOptions,\r\n            tagName,\r\n            type,\r\n        });\r\n        const forceMask = needMaskingText(target, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked);\r\n        if (type === 'radio' || type === 'checkbox') {\r\n            isChecked = target.checked;\r\n        }\r\n        text = maskInputValue({\r\n            isMasked: forceMask,\r\n            element: target,\r\n            value: text,\r\n            maskInputFn,\r\n        });\r\n        cbWithDedup(target, userTriggeredOnInput\r\n            ? { text, isChecked, userTriggered }\r\n            : { text, isChecked });\r\n        const name = target.name;\r\n        if (type === 'radio' && name && isChecked) {\r\n            doc\r\n                .querySelectorAll(`input[type=\"radio\"][name=\"${name}\"]`)\r\n                .forEach((el) => {\r\n                if (el !== target) {\r\n                    const text = maskInputValue({\r\n                        isMasked: forceMask,\r\n                        element: el,\r\n                        value: getInputValue(el, tagName, type),\r\n                        maskInputFn,\r\n                    });\r\n                    cbWithDedup(el, userTriggeredOnInput\r\n                        ? { text, isChecked: !isChecked, userTriggered: false }\r\n                        : { text, isChecked: !isChecked });\r\n                }\r\n            });\r\n        }\r\n    }\r\n    function cbWithDedup(target, v) {\r\n        const lastInputValue = lastInputValueMap.get(target);\r\n        if (!lastInputValue ||\r\n            lastInputValue.text !== v.text ||\r\n            lastInputValue.isChecked !== v.isChecked) {\r\n            lastInputValueMap.set(target, v);\r\n            const id = mirror.getId(target);\r\n            callbackWrapper(inputCb)({\r\n                ...v,\r\n                id,\r\n            });\r\n        }\r\n    }\r\n    const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];\r\n    const handlers = events.map((eventName) => on(eventName, callbackWrapper(eventHandler), doc));\r\n    const currentWindow = doc.defaultView;\r\n    if (!currentWindow) {\r\n        return () => {\r\n            handlers.forEach((h) => h());\r\n        };\r\n    }\r\n    const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(currentWindow.HTMLInputElement.prototype, 'value');\r\n    const hookProperties = [\r\n        [currentWindow.HTMLInputElement.prototype, 'value'],\r\n        [currentWindow.HTMLInputElement.prototype, 'checked'],\r\n        [currentWindow.HTMLSelectElement.prototype, 'value'],\r\n        [currentWindow.HTMLTextAreaElement.prototype, 'value'],\r\n        [currentWindow.HTMLSelectElement.prototype, 'selectedIndex'],\r\n        [currentWindow.HTMLOptionElement.prototype, 'selected'],\r\n    ];\r\n    if (propertyDescriptor && propertyDescriptor.set) {\r\n        handlers.push(...hookProperties.map((p) => hookSetter(p[0], p[1], {\r\n            set() {\r\n                callbackWrapper(eventHandler)({\r\n                    target: this,\r\n                    isTrusted: false,\r\n                });\r\n            },\r\n        }, false, currentWindow)));\r\n    }\r\n    return callbackWrapper(() => {\r\n        handlers.forEach((h) => h());\r\n    });\r\n}\r\nfunction getNestedCSSRulePositions(rule) {\r\n    const positions = [];\r\n    function recurse(childRule, pos) {\r\n        if ((hasNestedCSSRule('CSSGroupingRule') &&\r\n            childRule.parentRule instanceof CSSGroupingRule) ||\r\n            (hasNestedCSSRule('CSSMediaRule') &&\r\n                childRule.parentRule instanceof CSSMediaRule) ||\r\n            (hasNestedCSSRule('CSSSupportsRule') &&\r\n                childRule.parentRule instanceof CSSSupportsRule) ||\r\n            (hasNestedCSSRule('CSSConditionRule') &&\r\n                childRule.parentRule instanceof CSSConditionRule)) {\r\n            const rules = Array.from(childRule.parentRule.cssRules);\r\n            const index = rules.indexOf(childRule);\r\n            pos.unshift(index);\r\n        }\r\n        else if (childRule.parentStyleSheet) {\r\n            const rules = Array.from(childRule.parentStyleSheet.cssRules);\r\n            const index = rules.indexOf(childRule);\r\n            pos.unshift(index);\r\n        }\r\n        return pos;\r\n    }\r\n    return recurse(rule, positions);\r\n}\r\nfunction getIdAndStyleId(sheet, mirror, styleMirror) {\r\n    let id, styleId;\r\n    if (!sheet)\r\n        return {};\r\n    if (sheet.ownerNode)\r\n        id = mirror.getId(sheet.ownerNode);\r\n    else\r\n        styleId = styleMirror.getId(sheet);\r\n    return {\r\n        styleId,\r\n        id,\r\n    };\r\n}\r\nfunction initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager }, { win }) {\r\n    if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {\r\n        return () => {\r\n        };\r\n    }\r\n    const insertRule = win.CSSStyleSheet.prototype.insertRule;\r\n    win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {\r\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n            const [rule, index] = argumentsList;\r\n            const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\r\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                styleSheetRuleCb({\r\n                    id,\r\n                    styleId,\r\n                    adds: [{ rule, index }],\r\n                });\r\n            }\r\n            return target.apply(thisArg, argumentsList);\r\n        }),\r\n    });\r\n    const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\r\n    win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {\r\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n            const [index] = argumentsList;\r\n            const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\r\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                styleSheetRuleCb({\r\n                    id,\r\n                    styleId,\r\n                    removes: [{ index }],\r\n                });\r\n            }\r\n            return target.apply(thisArg, argumentsList);\r\n        }),\r\n    });\r\n    let replace;\r\n    if (win.CSSStyleSheet.prototype.replace) {\r\n        replace = win.CSSStyleSheet.prototype.replace;\r\n        win.CSSStyleSheet.prototype.replace = new Proxy(replace, {\r\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n                const [text] = argumentsList;\r\n                const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\r\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                    styleSheetRuleCb({\r\n                        id,\r\n                        styleId,\r\n                        replace: text,\r\n                    });\r\n                }\r\n                return target.apply(thisArg, argumentsList);\r\n            }),\r\n        });\r\n    }\r\n    let replaceSync;\r\n    if (win.CSSStyleSheet.prototype.replaceSync) {\r\n        replaceSync = win.CSSStyleSheet.prototype.replaceSync;\r\n        win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {\r\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n                const [text] = argumentsList;\r\n                const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\r\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                    styleSheetRuleCb({\r\n                        id,\r\n                        styleId,\r\n                        replaceSync: text,\r\n                    });\r\n                }\r\n                return target.apply(thisArg, argumentsList);\r\n            }),\r\n        });\r\n    }\r\n    const supportedNestedCSSRuleTypes = {};\r\n    if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {\r\n        supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;\r\n    }\r\n    else {\r\n        if (canMonkeyPatchNestedCSSRule('CSSMediaRule')) {\r\n            supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;\r\n        }\r\n        if (canMonkeyPatchNestedCSSRule('CSSConditionRule')) {\r\n            supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;\r\n        }\r\n        if (canMonkeyPatchNestedCSSRule('CSSSupportsRule')) {\r\n            supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;\r\n        }\r\n    }\r\n    const unmodifiedFunctions = {};\r\n    Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\r\n        unmodifiedFunctions[typeKey] = {\r\n            insertRule: type.prototype.insertRule,\r\n            deleteRule: type.prototype.deleteRule,\r\n        };\r\n        type.prototype.insertRule = new Proxy(unmodifiedFunctions[typeKey].insertRule, {\r\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n                const [rule, index] = argumentsList;\r\n                const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);\r\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                    styleSheetRuleCb({\r\n                        id,\r\n                        styleId,\r\n                        adds: [\r\n                            {\r\n                                rule,\r\n                                index: [\r\n                                    ...getNestedCSSRulePositions(thisArg),\r\n                                    index || 0,\r\n                                ],\r\n                            },\r\n                        ],\r\n                    });\r\n                }\r\n                return target.apply(thisArg, argumentsList);\r\n            }),\r\n        });\r\n        type.prototype.deleteRule = new Proxy(unmodifiedFunctions[typeKey].deleteRule, {\r\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n                const [index] = argumentsList;\r\n                const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);\r\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                    styleSheetRuleCb({\r\n                        id,\r\n                        styleId,\r\n                        removes: [\r\n                            { index: [...getNestedCSSRulePositions(thisArg), index] },\r\n                        ],\r\n                    });\r\n                }\r\n                return target.apply(thisArg, argumentsList);\r\n            }),\r\n        });\r\n    });\r\n    return callbackWrapper(() => {\r\n        win.CSSStyleSheet.prototype.insertRule = insertRule;\r\n        win.CSSStyleSheet.prototype.deleteRule = deleteRule;\r\n        replace && (win.CSSStyleSheet.prototype.replace = replace);\r\n        replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);\r\n        Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\r\n            type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;\r\n            type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;\r\n        });\r\n    });\r\n}\r\nfunction initAdoptedStyleSheetObserver({ mirror, stylesheetManager, }, host) {\r\n    let hostId = null;\r\n    if (host.nodeName === '#document')\r\n        hostId = mirror.getId(host);\r\n    else\r\n        hostId = mirror.getId(host.host);\r\n    const patchTarget = host.nodeName === '#document'\r\n        ? host.defaultView?.Document\r\n        : host.ownerDocument?.defaultView?.ShadowRoot;\r\n    const originalPropertyDescriptor = patchTarget?.prototype\r\n        ? Object.getOwnPropertyDescriptor(patchTarget?.prototype, 'adoptedStyleSheets')\r\n        : undefined;\r\n    if (hostId === null ||\r\n        hostId === -1 ||\r\n        !patchTarget ||\r\n        !originalPropertyDescriptor)\r\n        return () => {\r\n        };\r\n    Object.defineProperty(host, 'adoptedStyleSheets', {\r\n        configurable: originalPropertyDescriptor.configurable,\r\n        enumerable: originalPropertyDescriptor.enumerable,\r\n        get() {\r\n            return originalPropertyDescriptor.get?.call(this);\r\n        },\r\n        set(sheets) {\r\n            const result = originalPropertyDescriptor.set?.call(this, sheets);\r\n            if (hostId !== null && hostId !== -1) {\r\n                try {\r\n                    stylesheetManager.adoptStyleSheets(sheets, hostId);\r\n                }\r\n                catch (e) {\r\n                }\r\n            }\r\n            return result;\r\n        },\r\n    });\r\n    return callbackWrapper(() => {\r\n        Object.defineProperty(host, 'adoptedStyleSheets', {\r\n            configurable: originalPropertyDescriptor.configurable,\r\n            enumerable: originalPropertyDescriptor.enumerable,\r\n            get: originalPropertyDescriptor.get,\r\n            set: originalPropertyDescriptor.set,\r\n        });\r\n    });\r\n}\r\nfunction initStyleDeclarationObserver({ styleDeclarationCb, mirror, ignoreCSSAttributes, stylesheetManager, }, { win }) {\r\n    const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\r\n    win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {\r\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n            const [property, value, priority] = argumentsList;\r\n            if (ignoreCSSAttributes.has(property)) {\r\n                return setProperty.apply(thisArg, [property, value, priority]);\r\n            }\r\n            const { id, styleId } = getIdAndStyleId(thisArg.parentRule?.parentStyleSheet, mirror, stylesheetManager.styleMirror);\r\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                styleDeclarationCb({\r\n                    id,\r\n                    styleId,\r\n                    set: {\r\n                        property,\r\n                        value,\r\n                        priority,\r\n                    },\r\n                    index: getNestedCSSRulePositions(thisArg.parentRule),\r\n                });\r\n            }\r\n            return target.apply(thisArg, argumentsList);\r\n        }),\r\n    });\r\n    const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\r\n    win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {\r\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\r\n            const [property] = argumentsList;\r\n            if (ignoreCSSAttributes.has(property)) {\r\n                return removeProperty.apply(thisArg, [property]);\r\n            }\r\n            const { id, styleId } = getIdAndStyleId(thisArg.parentRule?.parentStyleSheet, mirror, stylesheetManager.styleMirror);\r\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\r\n                styleDeclarationCb({\r\n                    id,\r\n                    styleId,\r\n                    remove: {\r\n                        property,\r\n                    },\r\n                    index: getNestedCSSRulePositions(thisArg.parentRule),\r\n                });\r\n            }\r\n            return target.apply(thisArg, argumentsList);\r\n        }),\r\n    });\r\n    return callbackWrapper(() => {\r\n        win.CSSStyleDeclaration.prototype.setProperty = setProperty;\r\n        win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\r\n    });\r\n}\r\nfunction initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSelector, unblockSelector, mirror, sampling, doc, }) {\r\n    const handler = callbackWrapper((type) => throttle(callbackWrapper((event) => {\r\n        const target = getEventTarget(event);\r\n        if (!target ||\r\n            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\r\n            return;\r\n        }\r\n        const { currentTime, volume, muted, playbackRate } = target;\r\n        mediaInteractionCb({\r\n            type,\r\n            id: mirror.getId(target),\r\n            currentTime,\r\n            volume,\r\n            muted,\r\n            playbackRate,\r\n        });\r\n    }), sampling.media || 500));\r\n    const handlers = [\r\n        on('play', handler(0), doc),\r\n        on('pause', handler(1), doc),\r\n        on('seeked', handler(2), doc),\r\n        on('volumechange', handler(3), doc),\r\n        on('ratechange', handler(4), doc),\r\n    ];\r\n    return callbackWrapper(() => {\r\n        handlers.forEach((h) => h());\r\n    });\r\n}\r\nfunction initFontObserver({ fontCb, doc }) {\r\n    const win = doc.defaultView;\r\n    if (!win) {\r\n        return () => {\r\n        };\r\n    }\r\n    const handlers = [];\r\n    const fontMap = new WeakMap();\r\n    const originalFontFace = win.FontFace;\r\n    win.FontFace = function FontFace(family, source, descriptors) {\r\n        const fontFace = new originalFontFace(family, source, descriptors);\r\n        fontMap.set(fontFace, {\r\n            family,\r\n            buffer: typeof source !== 'string',\r\n            descriptors,\r\n            fontSource: typeof source === 'string'\r\n                ? source\r\n                : JSON.stringify(Array.from(new Uint8Array(source))),\r\n        });\r\n        return fontFace;\r\n    };\r\n    const restoreHandler = patch(doc.fonts, 'add', function (original) {\r\n        return function (fontFace) {\r\n            setTimeout(callbackWrapper(() => {\r\n                const p = fontMap.get(fontFace);\r\n                if (p) {\r\n                    fontCb(p);\r\n                    fontMap.delete(fontFace);\r\n                }\r\n            }), 0);\r\n            return original.apply(this, [fontFace]);\r\n        };\r\n    });\r\n    handlers.push(() => {\r\n        win.FontFace = originalFontFace;\r\n    });\r\n    handlers.push(restoreHandler);\r\n    return callbackWrapper(() => {\r\n        handlers.forEach((h) => h());\r\n    });\r\n}\r\nfunction initSelectionObserver(param) {\r\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, selectionCb, } = param;\r\n    let collapsed = true;\r\n    const updateSelection = callbackWrapper(() => {\r\n        const selection = doc.getSelection();\r\n        if (!selection || (collapsed && selection?.isCollapsed))\r\n            return;\r\n        collapsed = selection.isCollapsed || false;\r\n        const ranges = [];\r\n        const count = selection.rangeCount || 0;\r\n        for (let i = 0; i < count; i++) {\r\n            const range = selection.getRangeAt(i);\r\n            const { startContainer, startOffset, endContainer, endOffset } = range;\r\n            const blocked = isBlocked(startContainer, blockClass, blockSelector, unblockSelector, true) ||\r\n                isBlocked(endContainer, blockClass, blockSelector, unblockSelector, true);\r\n            if (blocked)\r\n                continue;\r\n            ranges.push({\r\n                start: mirror.getId(startContainer),\r\n                startOffset,\r\n                end: mirror.getId(endContainer),\r\n                endOffset,\r\n            });\r\n        }\r\n        selectionCb({ ranges });\r\n    });\r\n    updateSelection();\r\n    return on('selectionchange', updateSelection);\r\n}\r\nfunction initCustomElementObserver({ doc, customElementCb, }) {\r\n    const win = doc.defaultView;\r\n    if (!win || !win.customElements)\r\n        return () => { };\r\n    const restoreHandler = patch(win.customElements, 'define', function (original) {\r\n        return function (name, constructor, options) {\r\n            try {\r\n                customElementCb({\r\n                    define: {\r\n                        name,\r\n                    },\r\n                });\r\n            }\r\n            catch (e) {\r\n            }\r\n            return original.apply(this, [name, constructor, options]);\r\n        };\r\n    });\r\n    return restoreHandler;\r\n}\r\nfunction initObservers(o, _hooks = {}) {\r\n    const currentWindow = o.doc.defaultView;\r\n    if (!currentWindow) {\r\n        return () => {\r\n        };\r\n    }\r\n    let mutationObserver;\r\n    if (o.recordDOM) {\r\n        mutationObserver = initMutationObserver(o, o.doc);\r\n    }\r\n    const mousemoveHandler = initMoveObserver(o);\r\n    const mouseInteractionHandler = initMouseInteractionObserver(o);\r\n    const scrollHandler = initScrollObserver(o);\r\n    const viewportResizeHandler = initViewportResizeObserver(o, {\r\n        win: currentWindow,\r\n    });\r\n    const inputHandler = initInputObserver(o);\r\n    const mediaInteractionHandler = initMediaInteractionObserver(o);\r\n    let styleSheetObserver = () => { };\r\n    let adoptedStyleSheetObserver = () => { };\r\n    let styleDeclarationObserver = () => { };\r\n    let fontObserver = () => { };\r\n    if (o.recordDOM) {\r\n        styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });\r\n        adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);\r\n        styleDeclarationObserver = initStyleDeclarationObserver(o, {\r\n            win: currentWindow,\r\n        });\r\n        if (o.collectFonts) {\r\n            fontObserver = initFontObserver(o);\r\n        }\r\n    }\r\n    const selectionObserver = initSelectionObserver(o);\r\n    const customElementObserver = initCustomElementObserver(o);\r\n    const pluginHandlers = [];\r\n    for (const plugin of o.plugins) {\r\n        pluginHandlers.push(plugin.observer(plugin.callback, currentWindow, plugin.options));\r\n    }\r\n    return callbackWrapper(() => {\r\n        mutationBuffers.forEach((b) => b.reset());\r\n        mutationObserver?.disconnect();\r\n        mousemoveHandler();\r\n        mouseInteractionHandler();\r\n        scrollHandler();\r\n        viewportResizeHandler();\r\n        inputHandler();\r\n        mediaInteractionHandler();\r\n        styleSheetObserver();\r\n        adoptedStyleSheetObserver();\r\n        styleDeclarationObserver();\r\n        fontObserver();\r\n        selectionObserver();\r\n        customElementObserver();\r\n        pluginHandlers.forEach((h) => h());\r\n    });\r\n}\r\nfunction hasNestedCSSRule(prop) {\r\n    return typeof window[prop] !== 'undefined';\r\n}\r\nfunction canMonkeyPatchNestedCSSRule(prop) {\r\n    return Boolean(typeof window[prop] !== 'undefined' &&\r\n        window[prop].prototype &&\r\n        'insertRule' in window[prop].prototype &&\r\n        'deleteRule' in window[prop].prototype);\r\n}\n\nexport { INPUT_TAGS, initAdoptedStyleSheetObserver, initMutationObserver, initObservers, initScrollObserver, mutationBuffers };\n", "class CrossOriginIframeMirror {\r\n    constructor(generateIdFn) {\r\n        this.generateIdFn = generateIdFn;\r\n        this.iframeIdToRemoteIdMap = new WeakMap();\r\n        this.iframeRemoteIdToIdMap = new WeakMap();\r\n    }\r\n    getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {\r\n        const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);\r\n        const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);\r\n        let id = idToRemoteIdMap.get(remoteId);\r\n        if (!id) {\r\n            id = this.generateIdFn();\r\n            idToRemoteIdMap.set(remoteId, id);\r\n            remoteIdToIdMap.set(id, remoteId);\r\n        }\r\n        return id;\r\n    }\r\n    getIds(iframe, remoteId) {\r\n        const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);\r\n        const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\r\n        return remoteId.map((id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap));\r\n    }\r\n    getRemoteId(iframe, id, map) {\r\n        const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);\r\n        if (typeof id !== 'number')\r\n            return id;\r\n        const remoteId = remoteIdToIdMap.get(id);\r\n        if (!remoteId)\r\n            return -1;\r\n        return remoteId;\r\n    }\r\n    getRemoteIds(iframe, ids) {\r\n        const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\r\n        return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));\r\n    }\r\n    reset(iframe) {\r\n        if (!iframe) {\r\n            this.iframeIdToRemoteIdMap = new WeakMap();\r\n            this.iframeRemoteIdToIdMap = new WeakMap();\r\n            return;\r\n        }\r\n        this.iframeIdToRemoteIdMap.delete(iframe);\r\n        this.iframeRemoteIdToIdMap.delete(iframe);\r\n    }\r\n    getIdToRemoteIdMap(iframe) {\r\n        let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);\r\n        if (!idToRemoteIdMap) {\r\n            idToRemoteIdMap = new Map();\r\n            this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);\r\n        }\r\n        return idToRemoteIdMap;\r\n    }\r\n    getRemoteIdToIdMap(iframe) {\r\n        let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);\r\n        if (!remoteIdToIdMap) {\r\n            remoteIdToIdMap = new Map();\r\n            this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);\r\n        }\r\n        return remoteIdToIdMap;\r\n    }\r\n}\n\nexport { CrossOriginIframeMirror as default };\n", "import { genId, NodeType } from '../../../rrweb-snapshot/es/rrweb-snapshot.js';\nimport CrossOriginIframeMirror from './cross-origin-iframe-mirror.js';\nimport { EventType, IncrementalSource } from '../../../types/dist/rrweb-types.js';\nimport { getIFrameContentDocument } from '../../../rrdom/es/rrdom.js';\n\nclass IframeManagerNoop {\r\n    constructor() {\r\n        this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);\r\n        this.crossOriginIframeRootIdMap = new WeakMap();\r\n    }\r\n    addIframe() {\r\n    }\r\n    addLoadListener() {\r\n    }\r\n    attachIframe() {\r\n    }\r\n}\r\nclass IframeManager {\r\n    constructor(options) {\r\n        this.iframes = new WeakMap();\r\n        this.crossOriginIframeMap = new WeakMap();\r\n        this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);\r\n        this.crossOriginIframeRootIdMap = new WeakMap();\r\n        this.mutationCb = options.mutationCb;\r\n        this.wrappedEmit = options.wrappedEmit;\r\n        this.stylesheetManager = options.stylesheetManager;\r\n        this.recordCrossOriginIframes = options.recordCrossOriginIframes;\r\n        this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(this.stylesheetManager.styleMirror.generateId.bind(this.stylesheetManager.styleMirror));\r\n        this.mirror = options.mirror;\r\n        if (this.recordCrossOriginIframes) {\r\n            window.addEventListener('message', this.handleMessage.bind(this));\r\n        }\r\n    }\r\n    addIframe(iframeEl) {\r\n        this.iframes.set(iframeEl, true);\r\n        if (iframeEl.contentWindow)\r\n            this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);\r\n    }\r\n    addLoadListener(cb) {\r\n        this.loadListener = cb;\r\n    }\r\n    attachIframe(iframeEl, childSn) {\r\n        this.mutationCb({\r\n            adds: [\r\n                {\r\n                    parentId: this.mirror.getId(iframeEl),\r\n                    nextId: null,\r\n                    node: childSn,\r\n                },\r\n            ],\r\n            removes: [],\r\n            texts: [],\r\n            attributes: [],\r\n            isAttachIframe: true,\r\n        });\r\n        this.loadListener?.(iframeEl);\r\n        const iframeDoc = getIFrameContentDocument(iframeEl);\r\n        if (iframeDoc &&\r\n            iframeDoc.adoptedStyleSheets &&\r\n            iframeDoc.adoptedStyleSheets.length > 0)\r\n            this.stylesheetManager.adoptStyleSheets(iframeDoc.adoptedStyleSheets, this.mirror.getId(iframeDoc));\r\n    }\r\n    handleMessage(message) {\r\n        const crossOriginMessageEvent = message;\r\n        if (crossOriginMessageEvent.data.type !== 'rrweb' ||\r\n            crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)\r\n            return;\r\n        const iframeSourceWindow = message.source;\r\n        if (!iframeSourceWindow)\r\n            return;\r\n        const iframeEl = this.crossOriginIframeMap.get(message.source);\r\n        if (!iframeEl)\r\n            return;\r\n        const transformedEvent = this.transformCrossOriginEvent(iframeEl, crossOriginMessageEvent.data.event);\r\n        if (transformedEvent)\r\n            this.wrappedEmit(transformedEvent, crossOriginMessageEvent.data.isCheckout);\r\n    }\r\n    transformCrossOriginEvent(iframeEl, e) {\r\n        switch (e.type) {\r\n            case EventType.FullSnapshot: {\r\n                this.crossOriginIframeMirror.reset(iframeEl);\r\n                this.crossOriginIframeStyleMirror.reset(iframeEl);\r\n                this.replaceIdOnNode(e.data.node, iframeEl);\r\n                const rootId = e.data.node.id;\r\n                this.crossOriginIframeRootIdMap.set(iframeEl, rootId);\r\n                this.patchRootIdOnNode(e.data.node, rootId);\r\n                return {\r\n                    timestamp: e.timestamp,\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.Mutation,\r\n                        adds: [\r\n                            {\r\n                                parentId: this.mirror.getId(iframeEl),\r\n                                nextId: null,\r\n                                node: e.data.node,\r\n                            },\r\n                        ],\r\n                        removes: [],\r\n                        texts: [],\r\n                        attributes: [],\r\n                        isAttachIframe: true,\r\n                    },\r\n                };\r\n            }\r\n            case EventType.Meta:\r\n            case EventType.Load:\r\n            case EventType.DomContentLoaded: {\r\n                return false;\r\n            }\r\n            case EventType.Plugin: {\r\n                return e;\r\n            }\r\n            case EventType.Custom: {\r\n                this.replaceIds(e.data.payload, iframeEl, ['id', 'parentId', 'previousId', 'nextId']);\r\n                return e;\r\n            }\r\n            case EventType.IncrementalSnapshot: {\r\n                switch (e.data.source) {\r\n                    case IncrementalSource.Mutation: {\r\n                        e.data.adds.forEach((n) => {\r\n                            this.replaceIds(n, iframeEl, [\r\n                                'parentId',\r\n                                'nextId',\r\n                                'previousId',\r\n                            ]);\r\n                            this.replaceIdOnNode(n.node, iframeEl);\r\n                            const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);\r\n                            rootId && this.patchRootIdOnNode(n.node, rootId);\r\n                        });\r\n                        e.data.removes.forEach((n) => {\r\n                            this.replaceIds(n, iframeEl, ['parentId', 'id']);\r\n                        });\r\n                        e.data.attributes.forEach((n) => {\r\n                            this.replaceIds(n, iframeEl, ['id']);\r\n                        });\r\n                        e.data.texts.forEach((n) => {\r\n                            this.replaceIds(n, iframeEl, ['id']);\r\n                        });\r\n                        return e;\r\n                    }\r\n                    case IncrementalSource.Drag:\r\n                    case IncrementalSource.TouchMove:\r\n                    case IncrementalSource.MouseMove: {\r\n                        e.data.positions.forEach((p) => {\r\n                            this.replaceIds(p, iframeEl, ['id']);\r\n                        });\r\n                        return e;\r\n                    }\r\n                    case IncrementalSource.ViewportResize: {\r\n                        return false;\r\n                    }\r\n                    case IncrementalSource.MediaInteraction:\r\n                    case IncrementalSource.MouseInteraction:\r\n                    case IncrementalSource.Scroll:\r\n                    case IncrementalSource.CanvasMutation:\r\n                    case IncrementalSource.Input: {\r\n                        this.replaceIds(e.data, iframeEl, ['id']);\r\n                        return e;\r\n                    }\r\n                    case IncrementalSource.StyleSheetRule:\r\n                    case IncrementalSource.StyleDeclaration: {\r\n                        this.replaceIds(e.data, iframeEl, ['id']);\r\n                        this.replaceStyleIds(e.data, iframeEl, ['styleId']);\r\n                        return e;\r\n                    }\r\n                    case IncrementalSource.Font: {\r\n                        return e;\r\n                    }\r\n                    case IncrementalSource.Selection: {\r\n                        e.data.ranges.forEach((range) => {\r\n                            this.replaceIds(range, iframeEl, ['start', 'end']);\r\n                        });\r\n                        return e;\r\n                    }\r\n                    case IncrementalSource.AdoptedStyleSheet: {\r\n                        this.replaceIds(e.data, iframeEl, ['id']);\r\n                        this.replaceStyleIds(e.data, iframeEl, ['styleIds']);\r\n                        e.data.styles?.forEach((style) => {\r\n                            this.replaceStyleIds(style, iframeEl, ['styleId']);\r\n                        });\r\n                        return e;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n    replace(iframeMirror, obj, iframeEl, keys) {\r\n        for (const key of keys) {\r\n            if (!Array.isArray(obj[key]) && typeof obj[key] !== 'number')\r\n                continue;\r\n            if (Array.isArray(obj[key])) {\r\n                obj[key] = iframeMirror.getIds(iframeEl, obj[key]);\r\n            }\r\n            else {\r\n                obj[key] = iframeMirror.getId(iframeEl, obj[key]);\r\n            }\r\n        }\r\n        return obj;\r\n    }\r\n    replaceIds(obj, iframeEl, keys) {\r\n        return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);\r\n    }\r\n    replaceStyleIds(obj, iframeEl, keys) {\r\n        return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);\r\n    }\r\n    replaceIdOnNode(node, iframeEl) {\r\n        this.replaceIds(node, iframeEl, ['id', 'rootId']);\r\n        if ('childNodes' in node) {\r\n            node.childNodes.forEach((child) => {\r\n                this.replaceIdOnNode(child, iframeEl);\r\n            });\r\n        }\r\n    }\r\n    patchRootIdOnNode(node, rootId) {\r\n        if (node.type !== NodeType.Document && !node.rootId)\r\n            node.rootId = rootId;\r\n        if ('childNodes' in node) {\r\n            node.childNodes.forEach((child) => {\r\n                this.patchRootIdOnNode(child, rootId);\r\n            });\r\n        }\r\n    }\r\n}\n\nexport { IframeManager, IframeManagerNoop };\n", "import { initMutationObserver, initScrollObserver, initAdoptedStyleSheetObserver } from './observer.js';\nimport { setTimeout, patch, inDom } from '../utils.js';\nimport { isNativeShadowDom } from '../../../rrweb-snapshot/es/rrweb-snapshot.js';\nimport { getIFrameContentDocument, getIFrameContentWindow } from '../../../rrdom/es/rrdom.js';\n\nclass ShadowDomManagerNoop {\r\n    init() {\r\n    }\r\n    addShadowRoot() {\r\n    }\r\n    observeAttachShadow() {\r\n    }\r\n    reset() {\r\n    }\r\n}\r\nclass ShadowDomManager {\r\n    constructor(options) {\r\n        this.shadowDoms = new WeakSet();\r\n        this.restoreHandlers = [];\r\n        this.mutationCb = options.mutationCb;\r\n        this.scrollCb = options.scrollCb;\r\n        this.bypassOptions = options.bypassOptions;\r\n        this.mirror = options.mirror;\r\n        this.init();\r\n    }\r\n    init() {\r\n        this.reset();\r\n        this.patchAttachShadow(Element, document);\r\n    }\r\n    addShadowRoot(shadowRoot, doc) {\r\n        if (!isNativeShadowDom(shadowRoot))\r\n            return;\r\n        if (this.shadowDoms.has(shadowRoot))\r\n            return;\r\n        this.shadowDoms.add(shadowRoot);\r\n        this.bypassOptions.canvasManager.addShadowRoot(shadowRoot);\r\n        const observer = initMutationObserver({\r\n            ...this.bypassOptions,\r\n            doc,\r\n            mutationCb: this.mutationCb,\r\n            mirror: this.mirror,\r\n            shadowDomManager: this,\r\n        }, shadowRoot);\r\n        this.restoreHandlers.push(() => observer.disconnect());\r\n        this.restoreHandlers.push(initScrollObserver({\r\n            ...this.bypassOptions,\r\n            scrollCb: this.scrollCb,\r\n            doc: shadowRoot,\r\n            mirror: this.mirror,\r\n        }));\r\n        setTimeout(() => {\r\n            if (shadowRoot.adoptedStyleSheets &&\r\n                shadowRoot.adoptedStyleSheets.length > 0)\r\n                this.bypassOptions.stylesheetManager.adoptStyleSheets(shadowRoot.adoptedStyleSheets, this.mirror.getId(shadowRoot.host));\r\n            this.restoreHandlers.push(initAdoptedStyleSheetObserver({\r\n                mirror: this.mirror,\r\n                stylesheetManager: this.bypassOptions.stylesheetManager,\r\n            }, shadowRoot));\r\n        }, 0);\r\n    }\r\n    observeAttachShadow(iframeElement) {\r\n        const iframeDoc = getIFrameContentDocument(iframeElement);\r\n        const iframeWindow = getIFrameContentWindow(iframeElement);\r\n        if (!iframeDoc || !iframeWindow)\r\n            return;\r\n        this.patchAttachShadow(iframeWindow.Element, iframeDoc);\r\n    }\r\n    patchAttachShadow(element, doc) {\r\n        const manager = this;\r\n        this.restoreHandlers.push(patch(element.prototype, 'attachShadow', function (original) {\r\n            return function (option) {\r\n                const shadowRoot = original.call(this, option);\r\n                if (this.shadowRoot && inDom(this))\r\n                    manager.addShadowRoot(this.shadowRoot, doc);\r\n                return shadowRoot;\r\n            };\r\n        }));\r\n    }\r\n    reset() {\r\n        this.restoreHandlers.forEach((handler) => {\r\n            try {\r\n                handler();\r\n            }\r\n            catch (e) {\r\n            }\r\n        });\r\n        this.restoreHandlers = [];\r\n        this.shadowDoms = new WeakSet();\r\n        this.bypassOptions.canvasManager.resetShadowRoots();\r\n    }\r\n}\n\nexport { ShadowDomManager, ShadowDomManagerNoop };\n", "import { onRequestAnimationFrame, isBlocked } from '../../../utils.js';\nimport { CanvasContext } from '../../../../../types/dist/rrweb-types.js';\nimport initCanvas2DMutationObserver from './2d.js';\nimport initCanvasContextObserver from './canvas.js';\nimport initCanvasWebGLMutationObserver from './webgl.js';\nimport { getImageBitmapDataUrlWorkerURL as t } from '../../../../../rrweb-worker/es/rrweb-worker/index.js';\nimport { callbackWrapper, registerErrorHandler } from '../../error-handler.js';\n\nclass CanvasManagerNoop {\r\n    reset() {\r\n    }\r\n    freeze() {\r\n    }\r\n    unfreeze() {\r\n    }\r\n    lock() {\r\n    }\r\n    unlock() {\r\n    }\r\n    snapshot() {\r\n    }\r\n    addWindow() {\r\n    }\r\n    addShadowRoot() {\r\n    }\r\n    resetShadowRoots() {\r\n    }\r\n}\r\nclass CanvasManager {\r\n    reset() {\r\n        this.pendingCanvasMutations.clear();\r\n        this.restoreHandlers.forEach((handler) => {\r\n            try {\r\n                handler();\r\n            }\r\n            catch (e) {\r\n            }\r\n        });\r\n        this.restoreHandlers = [];\r\n        this.windowsSet = new WeakSet();\r\n        this.windows = [];\r\n        this.shadowDoms = new Set();\r\n        this.worker?.terminate();\r\n        this.worker = null;\r\n        this.snapshotInProgressMap = new Map();\r\n    }\r\n    freeze() {\r\n        this.frozen = true;\r\n    }\r\n    unfreeze() {\r\n        this.frozen = false;\r\n    }\r\n    lock() {\r\n        this.locked = true;\r\n    }\r\n    unlock() {\r\n        this.locked = false;\r\n    }\r\n    constructor(options) {\r\n        this.pendingCanvasMutations = new Map();\r\n        this.rafStamps = { latestId: 0, invokeId: null };\r\n        this.shadowDoms = new Set();\r\n        this.windowsSet = new WeakSet();\r\n        this.windows = [];\r\n        this.restoreHandlers = [];\r\n        this.frozen = false;\r\n        this.locked = false;\r\n        this.snapshotInProgressMap = new Map();\r\n        this.worker = null;\r\n        this.processMutation = (target, mutation) => {\r\n            const newFrame = this.rafStamps.invokeId &&\r\n                this.rafStamps.latestId !== this.rafStamps.invokeId;\r\n            if (newFrame || !this.rafStamps.invokeId)\r\n                this.rafStamps.invokeId = this.rafStamps.latestId;\r\n            if (!this.pendingCanvasMutations.has(target)) {\r\n                this.pendingCanvasMutations.set(target, []);\r\n            }\r\n            this.pendingCanvasMutations.get(target).push(mutation);\r\n        };\r\n        const { sampling = 'all', win, blockClass, blockSelector, unblockSelector, maxCanvasSize, recordCanvas, dataURLOptions, errorHandler, } = options;\r\n        this.mutationCb = options.mutationCb;\r\n        this.mirror = options.mirror;\r\n        this.options = options;\r\n        if (errorHandler) {\r\n            registerErrorHandler(errorHandler);\r\n        }\r\n        if ((recordCanvas && typeof sampling === 'number') ||\r\n            options.enableManualSnapshot) {\r\n            this.worker = this.initFPSWorker();\r\n        }\r\n        this.addWindow(win);\r\n        if (options.enableManualSnapshot) {\r\n            return;\r\n        }\r\n        callbackWrapper(() => {\r\n            if (recordCanvas && sampling === 'all') {\r\n                this.startRAFTimestamping();\r\n                this.startPendingCanvasMutationFlusher();\r\n            }\r\n            if (recordCanvas && typeof sampling === 'number') {\r\n                this.initCanvasFPSObserver(sampling, blockClass, blockSelector, unblockSelector, maxCanvasSize, {\r\n                    dataURLOptions,\r\n                });\r\n            }\r\n        })();\r\n    }\r\n    addWindow(win) {\r\n        const { sampling = 'all', blockClass, blockSelector, unblockSelector, recordCanvas, enableManualSnapshot, } = this.options;\r\n        if (this.windowsSet.has(win))\r\n            return;\r\n        if (enableManualSnapshot) {\r\n            this.windowsSet.add(win);\r\n            this.windows.push(new WeakRef(win));\r\n            return;\r\n        }\r\n        callbackWrapper(() => {\r\n            if (recordCanvas && sampling === 'all') {\r\n                this.initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector);\r\n            }\r\n            if (recordCanvas && typeof sampling === 'number') {\r\n                const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, true);\r\n                this.restoreHandlers.push(() => {\r\n                    canvasContextReset();\r\n                });\r\n            }\r\n        })();\r\n        this.windowsSet.add(win);\r\n        this.windows.push(new WeakRef(win));\r\n    }\r\n    addShadowRoot(shadowRoot) {\r\n        this.shadowDoms.add(new WeakRef(shadowRoot));\r\n    }\r\n    resetShadowRoots() {\r\n        this.shadowDoms = new Set();\r\n    }\r\n    initFPSWorker() {\r\n        const worker = new Worker(t());\r\n        worker.onmessage = (e) => {\r\n            const data = e.data;\r\n            const { id } = data;\r\n            this.snapshotInProgressMap.set(id, false);\r\n            if (!('base64' in data))\r\n                return;\r\n            const { base64, type, width, height } = data;\r\n            this.mutationCb({\r\n                id,\r\n                type: CanvasContext['2D'],\r\n                commands: [\r\n                    {\r\n                        property: 'clearRect',\r\n                        args: [0, 0, width, height],\r\n                    },\r\n                    {\r\n                        property: 'drawImage',\r\n                        args: [\r\n                            {\r\n                                rr_type: 'ImageBitmap',\r\n                                args: [\r\n                                    {\r\n                                        rr_type: 'Blob',\r\n                                        data: [{ rr_type: 'ArrayBuffer', base64 }],\r\n                                        type,\r\n                                    },\r\n                                ],\r\n                            },\r\n                            0,\r\n                            0,\r\n                            width,\r\n                            height,\r\n                        ],\r\n                    },\r\n                ],\r\n            });\r\n        };\r\n        return worker;\r\n    }\r\n    initCanvasFPSObserver(fps, blockClass, blockSelector, unblockSelector, maxCanvasSize, options) {\r\n        const rafId = this.takeSnapshot(false, fps, blockClass, blockSelector, unblockSelector, maxCanvasSize, options.dataURLOptions);\r\n        this.restoreHandlers.push(() => {\r\n            cancelAnimationFrame(rafId);\r\n        });\r\n    }\r\n    initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector) {\r\n        const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, false);\r\n        const canvas2DReset = initCanvas2DMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector);\r\n        const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector, this.mirror);\r\n        this.restoreHandlers.push(() => {\r\n            canvasContextReset();\r\n            canvas2DReset();\r\n            canvasWebGL1and2Reset();\r\n        });\r\n    }\r\n    snapshot(canvasElement) {\r\n        const { options } = this;\r\n        const rafId = this.takeSnapshot(true, options.sampling === 'all' ? 2 : options.sampling || 2, options.blockClass, options.blockSelector, options.unblockSelector, options.maxCanvasSize, options.dataURLOptions, canvasElement);\r\n        this.restoreHandlers.push(() => {\r\n            cancelAnimationFrame(rafId);\r\n        });\r\n    }\r\n    takeSnapshot(isManualSnapshot, fps, blockClass, blockSelector, unblockSelector, maxCanvasSize, dataURLOptions, canvasElement) {\r\n        const timeBetweenSnapshots = 1000 / fps;\r\n        let lastSnapshotTime = 0;\r\n        let rafId;\r\n        const getCanvas = (canvasElement) => {\r\n            if (canvasElement) {\r\n                return [canvasElement];\r\n            }\r\n            const matchedCanvas = [];\r\n            const searchCanvas = (root) => {\r\n                root.querySelectorAll('canvas').forEach((canvas) => {\r\n                    if (!isBlocked(canvas, blockClass, blockSelector, unblockSelector, true)) {\r\n                        matchedCanvas.push(canvas);\r\n                    }\r\n                });\r\n            };\r\n            for (const item of this.windows) {\r\n                const window = item.deref();\r\n                if (window) {\r\n                    searchCanvas(window.document);\r\n                }\r\n            }\r\n            for (const item of this.shadowDoms) {\r\n                const shadowRoot = item.deref();\r\n                if (shadowRoot) {\r\n                    searchCanvas(shadowRoot);\r\n                }\r\n            }\r\n            return matchedCanvas;\r\n        };\r\n        const takeCanvasSnapshots = (timestamp) => {\r\n            if (!this.windows.length) {\r\n                return;\r\n            }\r\n            if (lastSnapshotTime &&\r\n                timestamp - lastSnapshotTime < timeBetweenSnapshots) {\r\n                rafId = onRequestAnimationFrame(takeCanvasSnapshots);\r\n                return;\r\n            }\r\n            lastSnapshotTime = timestamp;\r\n            getCanvas(canvasElement).forEach((canvas) => {\r\n                if (!this.mirror.hasNode(canvas)) {\r\n                    return;\r\n                }\r\n                const id = this.mirror.getId(canvas);\r\n                if (this.snapshotInProgressMap.get(id))\r\n                    return;\r\n                if (!canvas.width || !canvas.height)\r\n                    return;\r\n                this.snapshotInProgressMap.set(id, true);\r\n                if (!isManualSnapshot &&\r\n                    ['webgl', 'webgl2'].includes(canvas.__context)) {\r\n                    const context = canvas.getContext(canvas.__context);\r\n                    if (context?.getContextAttributes()?.preserveDrawingBuffer === false) {\r\n                        context.clear(context.COLOR_BUFFER_BIT);\r\n                    }\r\n                }\r\n                createImageBitmap(canvas)\r\n                    .then((bitmap) => {\r\n                    this.worker?.postMessage({\r\n                        id,\r\n                        bitmap,\r\n                        width: canvas.width,\r\n                        height: canvas.height,\r\n                        dataURLOptions,\r\n                        maxCanvasSize,\r\n                    }, [bitmap]);\r\n                })\r\n                    .catch((error) => {\r\n                    callbackWrapper(() => {\r\n                        throw error;\r\n                    })();\r\n                });\r\n            });\r\n            if (!isManualSnapshot) {\r\n                rafId = onRequestAnimationFrame(takeCanvasSnapshots);\r\n            }\r\n        };\r\n        rafId = onRequestAnimationFrame(takeCanvasSnapshots);\r\n        return rafId;\r\n    }\r\n    startPendingCanvasMutationFlusher() {\r\n        onRequestAnimationFrame(() => this.flushPendingCanvasMutations());\r\n    }\r\n    startRAFTimestamping() {\r\n        const setLatestRAFTimestamp = (timestamp) => {\r\n            this.rafStamps.latestId = timestamp;\r\n            onRequestAnimationFrame(setLatestRAFTimestamp);\r\n        };\r\n        onRequestAnimationFrame(setLatestRAFTimestamp);\r\n    }\r\n    flushPendingCanvasMutations() {\r\n        this.pendingCanvasMutations.forEach((values, canvas) => {\r\n            const id = this.mirror.getId(canvas);\r\n            this.flushPendingCanvasMutationFor(canvas, id);\r\n        });\r\n        onRequestAnimationFrame(() => this.flushPendingCanvasMutations());\r\n    }\r\n    flushPendingCanvasMutationFor(canvas, id) {\r\n        if (this.frozen || this.locked) {\r\n            return;\r\n        }\r\n        const valuesWithType = this.pendingCanvasMutations.get(canvas);\r\n        if (!valuesWithType || id === -1)\r\n            return;\r\n        const values = valuesWithType.map((value) => {\r\n            const { type, ...rest } = value;\r\n            return rest;\r\n        });\r\n        const { type } = valuesWithType[0];\r\n        this.mutationCb({ id, type, commands: values });\r\n        this.pendingCanvasMutations.delete(canvas);\r\n    }\r\n}\n\nexport { CanvasManager, CanvasManagerNoop };\n", "import { stringifyRule } from '../../../rrweb-snapshot/es/rrweb-snapshot.js';\nimport { StyleSheetMirror } from '../utils.js';\n\nclass StylesheetManager {\r\n    constructor(options) {\r\n        this.trackedLinkElements = new WeakSet();\r\n        this.styleMirror = new StyleSheetMirror();\r\n        this.mutationCb = options.mutationCb;\r\n        this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;\r\n    }\r\n    attachLinkElement(linkEl, childSn) {\r\n        if ('_cssText' in childSn.attributes)\r\n            this.mutationCb({\r\n                adds: [],\r\n                removes: [],\r\n                texts: [],\r\n                attributes: [\r\n                    {\r\n                        id: childSn.id,\r\n                        attributes: childSn\r\n                            .attributes,\r\n                    },\r\n                ],\r\n            });\r\n        this.trackLinkElement(linkEl);\r\n    }\r\n    trackLinkElement(linkEl) {\r\n        if (this.trackedLinkElements.has(linkEl))\r\n            return;\r\n        this.trackedLinkElements.add(linkEl);\r\n        this.trackStylesheetInLinkElement(linkEl);\r\n    }\r\n    adoptStyleSheets(sheets, hostId) {\r\n        if (sheets.length === 0)\r\n            return;\r\n        const adoptedStyleSheetData = {\r\n            id: hostId,\r\n            styleIds: [],\r\n        };\r\n        const styles = [];\r\n        for (const sheet of sheets) {\r\n            let styleId;\r\n            if (!this.styleMirror.has(sheet)) {\r\n                styleId = this.styleMirror.add(sheet);\r\n                styles.push({\r\n                    styleId,\r\n                    rules: Array.from(sheet.rules || CSSRule, (r, index) => ({\r\n                        rule: stringifyRule(r),\r\n                        index,\r\n                    })),\r\n                });\r\n            }\r\n            else\r\n                styleId = this.styleMirror.getId(sheet);\r\n            adoptedStyleSheetData.styleIds.push(styleId);\r\n        }\r\n        if (styles.length > 0)\r\n            adoptedStyleSheetData.styles = styles;\r\n        this.adoptedStyleSheetCb(adoptedStyleSheetData);\r\n    }\r\n    reset() {\r\n        this.styleMirror.reset();\r\n        this.trackedLinkElements = new WeakSet();\r\n    }\r\n    trackStylesheetInLinkElement(linkEl) {\r\n    }\r\n}\n\nexport { StylesheetManager };\n", "import { onRequestAnimationFrame } from '../utils.js';\n\nclass ProcessedNodeManager {\r\n    constructor() {\r\n        this.nodeMap = new WeakMap();\r\n        this.active = false;\r\n    }\r\n    inOtherBuffer(node, thisBuffer) {\r\n        const buffers = this.nodeMap.get(node);\r\n        return (buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer));\r\n    }\r\n    add(node, buffer) {\r\n        if (!this.active) {\r\n            this.active = true;\r\n            onRequestAnimationFrame(() => {\r\n                this.nodeMap = new WeakMap();\r\n                this.active = false;\r\n            });\r\n        }\r\n        this.nodeMap.set(node, (this.nodeMap.get(node) || new Set()).add(buffer));\r\n    }\r\n    destroy() {\r\n    }\r\n}\n\nexport { ProcessedNodeManager as default };\n", "import { createMirror, snapshot } from '../../../rrweb-snapshot/es/rrweb-snapshot.js';\nimport { initObservers, mutationBuffers } from './observer.js';\nimport { polyfill, on, nowTimestamp, getWindowWidth, getWindowHeight, getWindowScroll, isSerializedIframe, isSerializedStylesheet, hasShadowRoot } from '../utils.js';\nimport { EventType, IncrementalSource } from '../../../types/dist/rrweb-types.js';\nimport { IframeManagerNoop, IframeManager } from './iframe-manager.js';\nimport { ShadowDomManagerNoop, ShadowDomManager } from './shadow-dom-manager.js';\nimport { CanvasManagerNoop } from './observers/canvas/canvas-manager.js';\nexport { CanvasManager } from './observers/canvas/canvas-manager.js';\nimport { StylesheetManager } from './stylesheet-manager.js';\nimport ProcessedNodeManager from './processed-node-manager.js';\nimport { callbackWrapper, unregisterErrorHandler, registerErrorHandler } from './error-handler.js';\n\nlet wrappedEmit;\r\nlet _wrappedEmit;\r\nlet _takeFullSnapshot;\r\ntry {\r\n    if (Array.from([1], (x) => x * 2)[0] !== 2) {\r\n        const cleanFrame = document.createElement('iframe');\r\n        document.body.appendChild(cleanFrame);\r\n        Array.from = cleanFrame.contentWindow?.Array.from || Array.from;\r\n        document.body.removeChild(cleanFrame);\r\n    }\r\n}\r\ncatch (err) {\r\n    console.debug('Unable to override Array.from', err);\r\n}\r\nconst mirror = createMirror();\r\nfunction record(options = {}) {\r\n    const { emit, checkoutEveryNms, checkoutEveryNth, blockClass = 'rr-block', blockSelector = null, unblockSelector = null, ignoreClass = 'rr-ignore', ignoreSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, maskAllInputs, maskInputOptions: _maskInputOptions, slimDOMOptions: _slimDOMOptions, maskAttributeFn, maskInputFn, maskTextFn, maxCanvasSize = null, packFn, sampling = {}, dataURLOptions = {}, mousemoveWait, recordDOM = true, recordCanvas = false, recordCrossOriginIframes = false, recordAfter = options.recordAfter === 'DOMContentLoaded'\r\n        ? options.recordAfter\r\n        : 'load', userTriggeredOnInput = false, collectFonts = false, inlineImages = false, plugins, keepIframeSrcFn = () => false, ignoreCSSAttributes = new Set([]), errorHandler, onMutation, getCanvasManager, } = options;\r\n    registerErrorHandler(errorHandler);\r\n    const inEmittingFrame = recordCrossOriginIframes\r\n        ? window.parent === window\r\n        : true;\r\n    let passEmitsToParent = false;\r\n    if (!inEmittingFrame) {\r\n        try {\r\n            if (window.parent.document) {\r\n                passEmitsToParent = false;\r\n            }\r\n        }\r\n        catch (e) {\r\n            passEmitsToParent = true;\r\n        }\r\n    }\r\n    if (inEmittingFrame && !emit) {\r\n        throw new Error('emit function is required');\r\n    }\r\n    if (!inEmittingFrame && !passEmitsToParent) {\r\n        return () => {\r\n        };\r\n    }\r\n    if (mousemoveWait !== undefined && sampling.mousemove === undefined) {\r\n        sampling.mousemove = mousemoveWait;\r\n    }\r\n    mirror.reset();\r\n    const maskInputOptions = maskAllInputs === true\r\n        ? {\r\n            color: true,\r\n            date: true,\r\n            'datetime-local': true,\r\n            email: true,\r\n            month: true,\r\n            number: true,\r\n            range: true,\r\n            search: true,\r\n            tel: true,\r\n            text: true,\r\n            time: true,\r\n            url: true,\r\n            week: true,\r\n            textarea: true,\r\n            select: true,\r\n            radio: true,\r\n            checkbox: true,\r\n        }\r\n        : _maskInputOptions !== undefined\r\n            ? _maskInputOptions\r\n            : {};\r\n    const slimDOMOptions = _slimDOMOptions === true || _slimDOMOptions === 'all'\r\n        ? {\r\n            script: true,\r\n            comment: true,\r\n            headFavicon: true,\r\n            headWhitespace: true,\r\n            headMetaSocial: true,\r\n            headMetaRobots: true,\r\n            headMetaHttpEquiv: true,\r\n            headMetaVerification: true,\r\n            headMetaAuthorship: _slimDOMOptions === 'all',\r\n            headMetaDescKeywords: _slimDOMOptions === 'all',\r\n        }\r\n        : _slimDOMOptions\r\n            ? _slimDOMOptions\r\n            : {};\r\n    polyfill();\r\n    let lastFullSnapshotEvent;\r\n    let incrementalSnapshotCount = 0;\r\n    const eventProcessor = (e) => {\r\n        for (const plugin of plugins || []) {\r\n            if (plugin.eventProcessor) {\r\n                e = plugin.eventProcessor(e);\r\n            }\r\n        }\r\n        if (packFn &&\r\n            !passEmitsToParent) {\r\n            e = packFn(e);\r\n        }\r\n        return e;\r\n    };\r\n    wrappedEmit = (r, isCheckout) => {\r\n        const e = r;\r\n        e.timestamp = nowTimestamp();\r\n        if (mutationBuffers[0]?.isFrozen() &&\r\n            e.type !== EventType.FullSnapshot &&\r\n            !(e.type === EventType.IncrementalSnapshot &&\r\n                e.data.source === IncrementalSource.Mutation)) {\r\n            mutationBuffers.forEach((buf) => buf.unfreeze());\r\n        }\r\n        if (inEmittingFrame) {\r\n            emit?.(eventProcessor(e), isCheckout);\r\n        }\r\n        else if (passEmitsToParent) {\r\n            const message = {\r\n                type: 'rrweb',\r\n                event: eventProcessor(e),\r\n                origin: window.location.origin,\r\n                isCheckout,\r\n            };\r\n            window.parent.postMessage(message, '*');\r\n        }\r\n        if (e.type === EventType.FullSnapshot) {\r\n            lastFullSnapshotEvent = e;\r\n            incrementalSnapshotCount = 0;\r\n        }\r\n        else if (e.type === EventType.IncrementalSnapshot) {\r\n            if (e.data.source === IncrementalSource.Mutation &&\r\n                e.data.isAttachIframe) {\r\n                return;\r\n            }\r\n            incrementalSnapshotCount++;\r\n            const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;\r\n            const exceedTime = checkoutEveryNms &&\r\n                lastFullSnapshotEvent &&\r\n                e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;\r\n            if (exceedCount || exceedTime) {\r\n                takeFullSnapshot(true);\r\n            }\r\n        }\r\n    };\r\n    _wrappedEmit = wrappedEmit;\r\n    const wrappedMutationEmit = (m) => {\r\n        wrappedEmit({\r\n            type: EventType.IncrementalSnapshot,\r\n            data: {\r\n                source: IncrementalSource.Mutation,\r\n                ...m,\r\n            },\r\n        });\r\n    };\r\n    const wrappedScrollEmit = (p) => wrappedEmit({\r\n        type: EventType.IncrementalSnapshot,\r\n        data: {\r\n            source: IncrementalSource.Scroll,\r\n            ...p,\r\n        },\r\n    });\r\n    const wrappedCanvasMutationEmit = (p) => wrappedEmit({\r\n        type: EventType.IncrementalSnapshot,\r\n        data: {\r\n            source: IncrementalSource.CanvasMutation,\r\n            ...p,\r\n        },\r\n    });\r\n    const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit({\r\n        type: EventType.IncrementalSnapshot,\r\n        data: {\r\n            source: IncrementalSource.AdoptedStyleSheet,\r\n            ...a,\r\n        },\r\n    });\r\n    const stylesheetManager = new StylesheetManager({\r\n        mutationCb: wrappedMutationEmit,\r\n        adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit,\r\n    });\r\n    const iframeManager = typeof __RRWEB_EXCLUDE_IFRAME__ === 'boolean' && __RRWEB_EXCLUDE_IFRAME__\r\n        ? new IframeManagerNoop()\r\n        : new IframeManager({\r\n            mirror,\r\n            mutationCb: wrappedMutationEmit,\r\n            stylesheetManager: stylesheetManager,\r\n            recordCrossOriginIframes,\r\n            wrappedEmit,\r\n        });\r\n    for (const plugin of plugins || []) {\r\n        if (plugin.getMirror)\r\n            plugin.getMirror({\r\n                nodeMirror: mirror,\r\n                crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,\r\n                crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror,\r\n            });\r\n    }\r\n    const processedNodeManager = new ProcessedNodeManager();\r\n    const canvasManager = _getCanvasManager(getCanvasManager, {\r\n        mirror,\r\n        win: window,\r\n        mutationCb: (p) => wrappedEmit({\r\n            type: EventType.IncrementalSnapshot,\r\n            data: {\r\n                source: IncrementalSource.CanvasMutation,\r\n                ...p,\r\n            },\r\n        }),\r\n        recordCanvas,\r\n        blockClass,\r\n        blockSelector,\r\n        unblockSelector,\r\n        maxCanvasSize,\r\n        sampling: sampling['canvas'],\r\n        dataURLOptions,\r\n        errorHandler,\r\n    });\r\n    const shadowDomManager = typeof __RRWEB_EXCLUDE_SHADOW_DOM__ === 'boolean' &&\r\n        __RRWEB_EXCLUDE_SHADOW_DOM__\r\n        ? new ShadowDomManagerNoop()\r\n        : new ShadowDomManager({\r\n            mutationCb: wrappedMutationEmit,\r\n            scrollCb: wrappedScrollEmit,\r\n            bypassOptions: {\r\n                onMutation,\r\n                blockClass,\r\n                blockSelector,\r\n                unblockSelector,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n                inlineStylesheet,\r\n                maskInputOptions,\r\n                dataURLOptions,\r\n                maskAttributeFn,\r\n                maskTextFn,\r\n                maskInputFn,\r\n                recordCanvas,\r\n                inlineImages,\r\n                sampling,\r\n                slimDOMOptions,\r\n                iframeManager,\r\n                stylesheetManager,\r\n                canvasManager,\r\n                keepIframeSrcFn,\r\n                processedNodeManager,\r\n            },\r\n            mirror,\r\n        });\r\n    const takeFullSnapshot = (isCheckout = false) => {\r\n        if (!recordDOM) {\r\n            return;\r\n        }\r\n        wrappedEmit({\r\n            type: EventType.Meta,\r\n            data: {\r\n                href: window.location.href,\r\n                width: getWindowWidth(),\r\n                height: getWindowHeight(),\r\n            },\r\n        }, isCheckout);\r\n        stylesheetManager.reset();\r\n        shadowDomManager.init();\r\n        mutationBuffers.forEach((buf) => buf.lock());\r\n        const node = snapshot(document, {\r\n            mirror,\r\n            blockClass,\r\n            blockSelector,\r\n            unblockSelector,\r\n            maskAllText,\r\n            maskTextClass,\r\n            unmaskTextClass,\r\n            maskTextSelector,\r\n            unmaskTextSelector,\r\n            inlineStylesheet,\r\n            maskAllInputs: maskInputOptions,\r\n            maskAttributeFn,\r\n            maskInputFn,\r\n            maskTextFn,\r\n            slimDOM: slimDOMOptions,\r\n            dataURLOptions,\r\n            recordCanvas,\r\n            inlineImages,\r\n            onSerialize: (n) => {\r\n                if (isSerializedIframe(n, mirror)) {\r\n                    iframeManager.addIframe(n);\r\n                }\r\n                if (isSerializedStylesheet(n, mirror)) {\r\n                    stylesheetManager.trackLinkElement(n);\r\n                }\r\n                if (hasShadowRoot(n)) {\r\n                    shadowDomManager.addShadowRoot(n.shadowRoot, document);\r\n                }\r\n            },\r\n            onIframeLoad: (iframe, childSn) => {\r\n                iframeManager.attachIframe(iframe, childSn);\r\n                if (iframe.contentWindow) {\r\n                    canvasManager.addWindow(iframe.contentWindow);\r\n                }\r\n                shadowDomManager.observeAttachShadow(iframe);\r\n            },\r\n            onStylesheetLoad: (linkEl, childSn) => {\r\n                stylesheetManager.attachLinkElement(linkEl, childSn);\r\n            },\r\n            keepIframeSrcFn,\r\n        });\r\n        if (!node) {\r\n            return console.warn('Failed to snapshot the document');\r\n        }\r\n        wrappedEmit({\r\n            type: EventType.FullSnapshot,\r\n            data: {\r\n                node,\r\n                initialOffset: getWindowScroll(window),\r\n            },\r\n        });\r\n        mutationBuffers.forEach((buf) => buf.unlock());\r\n        if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)\r\n            stylesheetManager.adoptStyleSheets(document.adoptedStyleSheets, mirror.getId(document));\r\n    };\r\n    _takeFullSnapshot = takeFullSnapshot;\r\n    try {\r\n        const handlers = [];\r\n        const observe = (doc) => {\r\n            return callbackWrapper(initObservers)({\r\n                onMutation,\r\n                mutationCb: wrappedMutationEmit,\r\n                mousemoveCb: (positions, source) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source,\r\n                        positions,\r\n                    },\r\n                }),\r\n                mouseInteractionCb: (d) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.MouseInteraction,\r\n                        ...d,\r\n                    },\r\n                }),\r\n                scrollCb: wrappedScrollEmit,\r\n                viewportResizeCb: (d) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.ViewportResize,\r\n                        ...d,\r\n                    },\r\n                }),\r\n                inputCb: (v) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.Input,\r\n                        ...v,\r\n                    },\r\n                }),\r\n                mediaInteractionCb: (p) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.MediaInteraction,\r\n                        ...p,\r\n                    },\r\n                }),\r\n                styleSheetRuleCb: (r) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.StyleSheetRule,\r\n                        ...r,\r\n                    },\r\n                }),\r\n                styleDeclarationCb: (r) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.StyleDeclaration,\r\n                        ...r,\r\n                    },\r\n                }),\r\n                canvasMutationCb: wrappedCanvasMutationEmit,\r\n                fontCb: (p) => wrappedEmit({\r\n                    type: EventType.IncrementalSnapshot,\r\n                    data: {\r\n                        source: IncrementalSource.Font,\r\n                        ...p,\r\n                    },\r\n                }),\r\n                selectionCb: (p) => {\r\n                    wrappedEmit({\r\n                        type: EventType.IncrementalSnapshot,\r\n                        data: {\r\n                            source: IncrementalSource.Selection,\r\n                            ...p,\r\n                        },\r\n                    });\r\n                },\r\n                customElementCb: (c) => {\r\n                    wrappedEmit({\r\n                        type: EventType.IncrementalSnapshot,\r\n                        data: {\r\n                            source: IncrementalSource.CustomElement,\r\n                            ...c,\r\n                        },\r\n                    });\r\n                },\r\n                blockClass,\r\n                ignoreClass,\r\n                ignoreSelector,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n                maskInputOptions,\r\n                inlineStylesheet,\r\n                sampling,\r\n                recordDOM,\r\n                recordCanvas,\r\n                inlineImages,\r\n                userTriggeredOnInput,\r\n                collectFonts,\r\n                doc,\r\n                maskAttributeFn,\r\n                maskInputFn,\r\n                maskTextFn,\r\n                keepIframeSrcFn,\r\n                blockSelector,\r\n                unblockSelector,\r\n                slimDOMOptions,\r\n                dataURLOptions,\r\n                mirror,\r\n                iframeManager,\r\n                stylesheetManager,\r\n                shadowDomManager,\r\n                processedNodeManager,\r\n                canvasManager,\r\n                ignoreCSSAttributes,\r\n                plugins: plugins\r\n                    ?.filter((p) => p.observer)\r\n                    ?.map((p) => ({\r\n                    observer: p.observer,\r\n                    options: p.options,\r\n                    callback: (payload) => wrappedEmit({\r\n                        type: EventType.Plugin,\r\n                        data: {\r\n                            plugin: p.name,\r\n                            payload,\r\n                        },\r\n                    }),\r\n                })) || [],\r\n            }, {});\r\n        };\r\n        iframeManager.addLoadListener((iframeEl) => {\r\n            try {\r\n                handlers.push(observe(iframeEl.contentDocument));\r\n            }\r\n            catch (error) {\r\n                console.warn(error);\r\n            }\r\n        });\r\n        const init = () => {\r\n            takeFullSnapshot();\r\n            handlers.push(observe(document));\r\n        };\r\n        if (document.readyState === 'interactive' ||\r\n            document.readyState === 'complete') {\r\n            init();\r\n        }\r\n        else {\r\n            handlers.push(on('DOMContentLoaded', () => {\r\n                wrappedEmit({\r\n                    type: EventType.DomContentLoaded,\r\n                    data: {},\r\n                });\r\n                if (recordAfter === 'DOMContentLoaded')\r\n                    init();\r\n            }));\r\n            handlers.push(on('load', () => {\r\n                wrappedEmit({\r\n                    type: EventType.Load,\r\n                    data: {},\r\n                });\r\n                if (recordAfter === 'load')\r\n                    init();\r\n            }, window));\r\n        }\r\n        return () => {\r\n            handlers.forEach((h) => h());\r\n            processedNodeManager.destroy();\r\n            _takeFullSnapshot = undefined;\r\n            unregisterErrorHandler();\r\n        };\r\n    }\r\n    catch (error) {\r\n        console.warn(error);\r\n    }\r\n}\r\nfunction addCustomEvent(tag, payload) {\r\n    if (!_wrappedEmit) {\r\n        throw new Error('please add custom event after start recording');\r\n    }\r\n    wrappedEmit({\r\n        type: EventType.Custom,\r\n        data: {\r\n            tag,\r\n            payload,\r\n        },\r\n    });\r\n}\r\nfunction freezePage() {\r\n    mutationBuffers.forEach((buf) => buf.freeze());\r\n}\r\nfunction takeFullSnapshot(isCheckout) {\r\n    if (!_takeFullSnapshot) {\r\n        throw new Error('please take full snapshot after start recording');\r\n    }\r\n    _takeFullSnapshot(isCheckout);\r\n}\r\nrecord.mirror = mirror;\r\nrecord.takeFullSnapshot = takeFullSnapshot;\r\nfunction _getCanvasManager(getCanvasManagerFn, options) {\r\n    try {\r\n        return getCanvasManagerFn\r\n            ? getCanvasManagerFn(options)\r\n            : new CanvasManagerNoop();\r\n    }\r\n    catch {\r\n        console.warn('Unable to initialize CanvasManager');\r\n        return new CanvasManagerNoop();\r\n    }\r\n}\n\nexport { addCustomEvent, record as default, freezePage, takeFullSnapshot };\n", "type ClassOption = string | RegExp;\n\n/** Duplicate this from @sentry-internal/rrweb so we can export this as well. */\nexport const ReplayEventTypeDomContentLoaded = 0;\nexport const ReplayEventTypeLoad = 1;\nexport const ReplayEventTypeFullSnapshot = 2;\nexport const ReplayEventTypeIncrementalSnapshot = 3;\nexport const ReplayEventTypeMeta = 4;\nexport const ReplayEventTypeCustom = 5;\nexport const ReplayEventTypePlugin = 6;\n\nexport type ReplayEventType =\n  | typeof ReplayEventTypeDomContentLoaded\n  | typeof ReplayEventTypeLoad\n  | typeof ReplayEventTypeFullSnapshot\n  | typeof ReplayEventTypeIncrementalSnapshot\n  | typeof ReplayEventTypeMeta\n  | typeof ReplayEventTypeCustom\n  | typeof ReplayEventTypePlugin;\n\n/**\n * This is a partial copy of rrweb's eventWithTime type which only contains the properties\n * we specifically need in the SDK.\n */\nexport type ReplayEventWithTime = {\n  type: ReplayEventType;\n  data: unknown;\n  timestamp: number;\n  delay?: number;\n};\n\n/**\n * This is a partial copy of rrweb's recording options which only contains the properties\n * we specifically use in the SDK. Users can specify additional properties, hence we add the\n * Record<string, unknown> union type.\n */\nexport type RrwebRecordOptions = {\n  maskAllText?: boolean;\n  maskAllInputs?: boolean;\n  blockClass?: ClassOption;\n  ignoreClass?: string;\n  maskTextClass?: ClassOption;\n  maskTextSelector?: string;\n  blockSelector?: string;\n  maskInputOptions?: Record<string, boolean>;\n} & Record<string, unknown>;\n\nexport interface CanvasManagerInterface {\n  reset(): void;\n  freeze(): void;\n  unfreeze(): void;\n  lock(): void;\n  unlock(): void;\n  snapshot(): void;\n  addWindow(win: typeof globalThis & Window): void;\n  addShadowRoot(shadowRoot: ShadowRoot): void;\n  resetShadowRoots(): void;\n}\n\nexport interface CanvasManagerOptions {\n  recordCanvas: boolean;\n  enableManualSnapshot?: boolean;\n  blockClass: string | RegExp;\n  blockSelector: string | null;\n  unblockSelector: string | null;\n  sampling?: 'all' | number;\n  dataURLOptions: Partial<{\n    type: string;\n    quality: number;\n  }>;\n  mutationCb: (p: any) => void;\n  win: typeof globalThis & Window;\n  mirror: any;\n}\n", "/**\n * Converts a timestamp to ms, if it was in s, or keeps it as ms.\n */\nexport function timestampToMs(timestamp: number): number {\n  const isMs = timestamp > 9999999999;\n  return isMs ? timestamp : timestamp * 1000;\n}\n\n/**\n * Converts a timestamp to s, if it was in ms, or keeps it as s.\n */\nexport function timestampToS(timestamp: number): number {\n  const isMs = timestamp > 9999999999;\n  return isMs ? timestamp / 1000 : timestamp;\n}\n", "import { EventType } from '@sentry-internal/rrweb';\nimport { normalize } from '@sentry/core';\nimport type { Breadcrumb } from '@sentry/core';\n\nimport type { ReplayContainer } from '../../types';\n\n/**\n * Add a breadcrumb event to replay.\n */\nexport function addBreadcrumbEvent(replay: ReplayContainer, breadcrumb: Breadcrumb): void {\n  if (breadcrumb.category === 'sentry.transaction') {\n    return;\n  }\n\n  if (['ui.click', 'ui.input'].includes(breadcrumb.category as string)) {\n    replay.triggerUserActivity();\n  } else {\n    replay.checkAndHandleExpiredSession();\n  }\n\n  replay.addUpdate(() => {\n    // This should never reject\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    replay.throttledAddEvent({\n      type: EventType.Custom,\n      // TODO: We were converting from ms to seconds for breadcrumbs, spans,\n      // but maybe we should just keep them as milliseconds\n      timestamp: (breadcrumb.timestamp || 0) * 1000,\n      data: {\n        tag: 'breadcrumb',\n        // normalize to max. 10 depth and 1_000 properties per object\n        payload: normalize(breadcrumb, 10, 1_000),\n      },\n    });\n\n    // Do not flush after console log messages\n    return breadcrumb.category === 'console';\n  });\n}\n", "import type { INode } from '@sentry-internal/rrweb-snapshot';\n\nconst INTERACTIVE_SELECTOR = 'button,a';\n\n/** Get the closest interactive parent element, or else return the given element. */\nexport function getClosestInteractive(element: Element): Element {\n  const closestInteractive = element.closest(INTERACTIVE_SELECTOR);\n  return closestInteractive || element;\n}\n\n/**\n * For clicks, we check if the target is inside of a button or link\n * If so, we use this as the target instead\n * This is useful because if you click on the image in <button><img></button>,\n * The target will be the image, not the button, which we don't want here\n */\nexport function getClickTargetNode(event: Event | MouseEvent | Node): Node | INode | null {\n  const target = getTargetNode(event);\n\n  if (!target || !(target instanceof Element)) {\n    return target;\n  }\n\n  return getClosestInteractive(target);\n}\n\n/** Get the event target node. */\nexport function getTargetNode(event: Node | { target: EventTarget | null }): Node | INode | null {\n  if (isEventWithTarget(event)) {\n    return event.target as Node | null;\n  }\n\n  return event;\n}\n\nfunction isEventWithTarget(event: unknown): event is { target: EventTarget | null } {\n  return typeof event === 'object' && !!event && 'target' in event;\n}\n", "import { fill } from '@sentry/core';\n\nimport { WINDOW } from '../../constants';\n\ntype WindowOpenHandler = () => void;\n\nlet handlers: undefined | WindowOpenHandler[];\n\n/**\n * Register a handler to be called when `window.open()` is called.\n * Returns a cleanup function.\n */\nexport function onWindowOpen(cb: WindowOpenHandler): () => void {\n  // Ensure to only register this once\n  if (!handlers) {\n    handlers = [];\n    monkeyPatchWindowOpen();\n  }\n\n  handlers.push(cb);\n\n  return () => {\n    const pos = handlers ? handlers.indexOf(cb) : -1;\n    if (pos > -1) {\n      (handlers as WindowOpenHandler[]).splice(pos, 1);\n    }\n  };\n}\n\nfunction monkeyPatchWindowOpen(): void {\n  fill(WINDOW, 'open', function (originalWindowOpen: () => void): () => void {\n    return function (...args: unknown[]): void {\n      if (handlers) {\n        try {\n          handlers.forEach(handler => handler());\n        } catch (e) {\n          // ignore errors in here\n        }\n      }\n\n      return originalWindowOpen.apply(WINDOW, args);\n    };\n  });\n}\n", "import { setTimeout } from '@sentry-internal/browser-utils';\nimport { IncrementalSource, MouseInteractions, record } from '@sentry-internal/rrweb';\nimport type { Breadcrumb } from '@sentry/core';\n\nimport { WINDOW } from '../constants';\nimport type {\n  RecordingEvent,\n  ReplayClickDetector,\n  ReplayContainer,\n  ReplayMultiClickFrame,\n  ReplaySlowClickFrame,\n  SlowClickConfig,\n} from '../types';\nimport { ReplayEventTypeIncrementalSnapshot } from '../types';\nimport { timestampToS } from '../util/timestamp';\nimport { addBreadcrumbEvent } from './util/addBreadcrumbEvent';\nimport { getClosestInteractive } from './util/domUtils';\nimport { onWindowOpen } from './util/onWindowOpen';\n\ntype ClickBreadcrumb = Breadcrumb & {\n  timestamp: number;\n};\n\ninterface Click {\n  timestamp: number;\n  mutationAfter?: number;\n  scrollAfter?: number;\n  clickBreadcrumb: ClickBreadcrumb;\n  clickCount: number;\n  node: HTMLElement;\n}\n\ntype IncrementalRecordingEvent = RecordingEvent & {\n  type: typeof ReplayEventTypeIncrementalSnapshot;\n  data: { source: IncrementalSource };\n};\n\ntype IncrementalMouseInteractionRecordingEvent = IncrementalRecordingEvent & {\n  type: typeof ReplayEventTypeIncrementalSnapshot;\n  data: { type: MouseInteractions; id: number };\n};\n\n/** Any IncrementalSource for rrweb that we interpret as a kind of mutation. */\nconst IncrementalMutationSources = new Set([\n  IncrementalSource.Mutation,\n  IncrementalSource.StyleSheetRule,\n  IncrementalSource.StyleDeclaration,\n  IncrementalSource.AdoptedStyleSheet,\n  IncrementalSource.CanvasMutation,\n  IncrementalSource.Selection,\n  IncrementalSource.MediaInteraction,\n]);\n\n/** Handle a click. */\nexport function handleClick(clickDetector: ReplayClickDetector, clickBreadcrumb: Breadcrumb, node: HTMLElement): void {\n  clickDetector.handleClick(clickBreadcrumb, node);\n}\n\n/** A click detector class that can be used to detect slow or rage clicks on elements. */\nexport class ClickDetector implements ReplayClickDetector {\n  // protected for testing\n  protected _lastMutation: number;\n  protected _lastScroll: number;\n\n  private _clicks: Click[];\n  private _teardown: undefined | (() => void);\n\n  private _threshold: number;\n  private _scrollTimeout: number;\n  private _timeout: number;\n  private _ignoreSelector: string;\n\n  private _replay: ReplayContainer;\n  private _checkClickTimeout?: ReturnType<typeof setTimeout>;\n  private _addBreadcrumbEvent: typeof addBreadcrumbEvent;\n\n  public constructor(\n    replay: ReplayContainer,\n    slowClickConfig: SlowClickConfig,\n    // Just for easier testing\n    _addBreadcrumbEvent = addBreadcrumbEvent,\n  ) {\n    this._lastMutation = 0;\n    this._lastScroll = 0;\n    this._clicks = [];\n\n    // We want everything in s, but options are in ms\n    this._timeout = slowClickConfig.timeout / 1000;\n    this._threshold = slowClickConfig.threshold / 1000;\n    this._scrollTimeout = slowClickConfig.scrollTimeout / 1000;\n    this._replay = replay;\n    this._ignoreSelector = slowClickConfig.ignoreSelector;\n    this._addBreadcrumbEvent = _addBreadcrumbEvent;\n  }\n\n  /** Register click detection handlers on mutation or scroll. */\n  public addListeners(): void {\n    const cleanupWindowOpen = onWindowOpen(() => {\n      // Treat window.open as mutation\n      this._lastMutation = nowInSeconds();\n    });\n\n    this._teardown = () => {\n      cleanupWindowOpen();\n\n      this._clicks = [];\n      this._lastMutation = 0;\n      this._lastScroll = 0;\n    };\n  }\n\n  /** Clean up listeners. */\n  public removeListeners(): void {\n    if (this._teardown) {\n      this._teardown();\n    }\n\n    if (this._checkClickTimeout) {\n      clearTimeout(this._checkClickTimeout);\n    }\n  }\n\n  /** @inheritDoc */\n  public handleClick(breadcrumb: Breadcrumb, node: HTMLElement): void {\n    if (ignoreElement(node, this._ignoreSelector) || !isClickBreadcrumb(breadcrumb)) {\n      return;\n    }\n\n    const newClick: Click = {\n      timestamp: timestampToS(breadcrumb.timestamp),\n      clickBreadcrumb: breadcrumb,\n      // Set this to 0 so we know it originates from the click breadcrumb\n      clickCount: 0,\n      node,\n    };\n\n    // If there was a click in the last 1s on the same element, ignore it - only keep a single reference per second\n    if (\n      this._clicks.some(click => click.node === newClick.node && Math.abs(click.timestamp - newClick.timestamp) < 1)\n    ) {\n      return;\n    }\n\n    this._clicks.push(newClick);\n\n    // If this is the first new click, set a timeout to check for multi clicks\n    if (this._clicks.length === 1) {\n      this._scheduleCheckClicks();\n    }\n  }\n\n  /** @inheritDoc */\n  public registerMutation(timestamp = Date.now()): void {\n    this._lastMutation = timestampToS(timestamp);\n  }\n\n  /** @inheritDoc */\n  public registerScroll(timestamp = Date.now()): void {\n    this._lastScroll = timestampToS(timestamp);\n  }\n\n  /** @inheritDoc */\n  public registerClick(element: HTMLElement): void {\n    const node = getClosestInteractive(element);\n    this._handleMultiClick(node as HTMLElement);\n  }\n\n  /** Count multiple clicks on elements. */\n  private _handleMultiClick(node: HTMLElement): void {\n    this._getClicks(node).forEach(click => {\n      click.clickCount++;\n    });\n  }\n\n  /** Get all pending clicks for a given node. */\n  private _getClicks(node: HTMLElement): Click[] {\n    return this._clicks.filter(click => click.node === node);\n  }\n\n  /** Check the clicks that happened. */\n  private _checkClicks(): void {\n    const timedOutClicks: Click[] = [];\n\n    const now = nowInSeconds();\n\n    this._clicks.forEach(click => {\n      if (!click.mutationAfter && this._lastMutation) {\n        click.mutationAfter = click.timestamp <= this._lastMutation ? this._lastMutation - click.timestamp : undefined;\n      }\n      if (!click.scrollAfter && this._lastScroll) {\n        click.scrollAfter = click.timestamp <= this._lastScroll ? this._lastScroll - click.timestamp : undefined;\n      }\n\n      // All of these are in seconds!\n      if (click.timestamp + this._timeout <= now) {\n        timedOutClicks.push(click);\n      }\n    });\n\n    // Remove \"old\" clicks\n    for (const click of timedOutClicks) {\n      const pos = this._clicks.indexOf(click);\n\n      if (pos > -1) {\n        this._generateBreadcrumbs(click);\n        this._clicks.splice(pos, 1);\n      }\n    }\n\n    // Trigger new check, unless no clicks left\n    if (this._clicks.length) {\n      this._scheduleCheckClicks();\n    }\n  }\n\n  /** Generate matching breadcrumb(s) for the click. */\n  private _generateBreadcrumbs(click: Click): void {\n    const replay = this._replay;\n    const hadScroll = click.scrollAfter && click.scrollAfter <= this._scrollTimeout;\n    const hadMutation = click.mutationAfter && click.mutationAfter <= this._threshold;\n\n    const isSlowClick = !hadScroll && !hadMutation;\n    const { clickCount, clickBreadcrumb } = click;\n\n    // Slow click\n    if (isSlowClick) {\n      // If `mutationAfter` is set, it means a mutation happened after the threshold, but before the timeout\n      // If not, it means we just timed out without scroll & mutation\n      const timeAfterClickMs = Math.min(click.mutationAfter || this._timeout, this._timeout) * 1000;\n      const endReason = timeAfterClickMs < this._timeout * 1000 ? 'mutation' : 'timeout';\n\n      const breadcrumb: ReplaySlowClickFrame = {\n        type: 'default',\n        message: clickBreadcrumb.message,\n        timestamp: clickBreadcrumb.timestamp,\n        category: 'ui.slowClickDetected',\n        data: {\n          ...clickBreadcrumb.data,\n          url: WINDOW.location.href,\n          route: replay.getCurrentRoute(),\n          timeAfterClickMs,\n          endReason,\n          // If clickCount === 0, it means multiClick was not correctly captured here\n          // - we still want to send 1 in this case\n          clickCount: clickCount || 1,\n        },\n      };\n\n      this._addBreadcrumbEvent(replay, breadcrumb);\n      return;\n    }\n\n    // Multi click\n    if (clickCount > 1) {\n      const breadcrumb: ReplayMultiClickFrame = {\n        type: 'default',\n        message: clickBreadcrumb.message,\n        timestamp: clickBreadcrumb.timestamp,\n        category: 'ui.multiClick',\n        data: {\n          ...clickBreadcrumb.data,\n          url: WINDOW.location.href,\n          route: replay.getCurrentRoute(),\n          clickCount,\n          metric: true,\n        },\n      };\n\n      this._addBreadcrumbEvent(replay, breadcrumb);\n    }\n  }\n\n  /** Schedule to check current clicks. */\n  private _scheduleCheckClicks(): void {\n    if (this._checkClickTimeout) {\n      clearTimeout(this._checkClickTimeout);\n    }\n\n    this._checkClickTimeout = setTimeout(() => this._checkClicks(), 1000);\n  }\n}\n\nconst SLOW_CLICK_TAGS = ['A', 'BUTTON', 'INPUT'];\n\n/** exported for tests only */\nexport function ignoreElement(node: HTMLElement, ignoreSelector: string): boolean {\n  if (!SLOW_CLICK_TAGS.includes(node.tagName)) {\n    return true;\n  }\n\n  // If <input> tag, we only want to consider input[type='submit'] & input[type='button']\n  if (node.tagName === 'INPUT' && !['submit', 'button'].includes(node.getAttribute('type') || '')) {\n    return true;\n  }\n\n  // If <a> tag, detect special variants that may not lead to an action\n  // If target !== _self, we may open the link somewhere else, which would lead to no action\n  // Also, when downloading a file, we may not leave the page, but still not trigger an action\n  if (\n    node.tagName === 'A' &&\n    (node.hasAttribute('download') || (node.hasAttribute('target') && node.getAttribute('target') !== '_self'))\n  ) {\n    return true;\n  }\n\n  if (ignoreSelector && node.matches(ignoreSelector)) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction isClickBreadcrumb(breadcrumb: Breadcrumb): breadcrumb is ClickBreadcrumb {\n  return !!(breadcrumb.data && typeof breadcrumb.data.nodeId === 'number' && breadcrumb.timestamp);\n}\n\n// This is good enough for us, and is easier to test/mock than `timestampInSeconds`\nfunction nowInSeconds(): number {\n  return Date.now() / 1000;\n}\n\n/** Update the click detector based on a recording event of rrweb. */\nexport function updateClickDetectorForRecordingEvent(clickDetector: ReplayClickDetector, event: RecordingEvent): void {\n  try {\n    // note: We only consider incremental snapshots here\n    // This means that any full snapshot is ignored for mutation detection - the reason is that we simply cannot know if a mutation happened here.\n    // E.g. think that we are buffering, an error happens and we take a full snapshot because we switched to session mode -\n    // in this scenario, we would not know if a dead click happened because of the error, which is a key dead click scenario.\n    // Instead, by ignoring full snapshots, we have the risk that we generate a false positive\n    // (if a mutation _did_ happen but was \"swallowed\" by the full snapshot)\n    // But this should be more unlikely as we'd generally capture the incremental snapshot right away\n\n    if (!isIncrementalEvent(event)) {\n      return;\n    }\n\n    const { source } = event.data;\n    if (IncrementalMutationSources.has(source)) {\n      clickDetector.registerMutation(event.timestamp);\n    }\n\n    if (source === IncrementalSource.Scroll) {\n      clickDetector.registerScroll(event.timestamp);\n    }\n\n    if (isIncrementalMouseInteraction(event)) {\n      const { type, id } = event.data;\n      const node = record.mirror.getNode(id);\n\n      if (node instanceof HTMLElement && type === MouseInteractions.Click) {\n        clickDetector.registerClick(node);\n      }\n    }\n  } catch {\n    // ignore errors here, e.g. if accessing something that does not exist\n  }\n}\n\nfunction isIncrementalEvent(event: RecordingEvent): event is IncrementalRecordingEvent {\n  return event.type === ReplayEventTypeIncrementalSnapshot;\n}\n\nfunction isIncrementalMouseInteraction(\n  event: IncrementalRecordingEvent,\n): event is IncrementalMouseInteractionRecordingEvent {\n  return event.data.source === IncrementalSource.MouseInteraction;\n}\n", "import type { ReplayBreadcrumbFrame } from '../types/replayFrame';\n\n/**\n * Create a breadcrumb for a replay.\n */\nexport function createBreadcrumb(\n  breadcrumb: Omit<ReplayBreadcrumbFrame, 'timestamp' | 'type'> & Partial<Pick<ReplayBreadcrumbFrame, 'timestamp'>>,\n): ReplayBreadcrumbFrame {\n  return {\n    timestamp: Date.now() / 1000,\n    type: 'default',\n    ...breadcrumb,\n  };\n}\n", "var NodeType;\r\n(function (NodeType) {\r\n    NodeType[NodeType[\"Document\"] = 0] = \"Document\";\r\n    NodeType[NodeType[\"DocumentType\"] = 1] = \"DocumentType\";\r\n    NodeType[NodeType[\"Element\"] = 2] = \"Element\";\r\n    NodeType[NodeType[\"Text\"] = 3] = \"Text\";\r\n    NodeType[NodeType[\"CDATA\"] = 4] = \"CDATA\";\r\n    NodeType[NodeType[\"Comment\"] = 5] = \"Comment\";\r\n})(NodeType || (NodeType = {}));\n\nfunction isElement(n) {\r\n    return n.nodeType === n.ELEMENT_NODE;\r\n}\r\nfunction isShadowRoot(n) {\r\n    const host = n?.host;\r\n    return Boolean(host?.shadowRoot === n);\r\n}\r\nfunction isNativeShadowDom(shadowRoot) {\r\n    return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';\r\n}\r\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\r\n    if (cssText.includes(' background-clip: text;') &&\r\n        !cssText.includes(' -webkit-background-clip: text;')) {\r\n        cssText = cssText.replace(/\\sbackground-clip:\\s*text;/g, ' -webkit-background-clip: text; background-clip: text;');\r\n    }\r\n    return cssText;\r\n}\r\nfunction escapeImportStatement(rule) {\r\n    const { cssText } = rule;\r\n    if (cssText.split('\"').length < 3)\r\n        return cssText;\r\n    const statement = ['@import', `url(${JSON.stringify(rule.href)})`];\r\n    if (rule.layerName === '') {\r\n        statement.push(`layer`);\r\n    }\r\n    else if (rule.layerName) {\r\n        statement.push(`layer(${rule.layerName})`);\r\n    }\r\n    if (rule.supportsText) {\r\n        statement.push(`supports(${rule.supportsText})`);\r\n    }\r\n    if (rule.media.length) {\r\n        statement.push(rule.media.mediaText);\r\n    }\r\n    return statement.join(' ') + ';';\r\n}\r\nfunction stringifyStylesheet(s) {\r\n    try {\r\n        const rules = s.rules || s.cssRules;\r\n        return rules\r\n            ? fixBrowserCompatibilityIssuesInCSS(Array.from(rules, stringifyRule).join(''))\r\n            : null;\r\n    }\r\n    catch (error) {\r\n        return null;\r\n    }\r\n}\r\nfunction fixAllCssProperty(rule) {\r\n    let styles = '';\r\n    for (let i = 0; i < rule.style.length; i++) {\r\n        const styleDeclaration = rule.style;\r\n        const attribute = styleDeclaration[i];\r\n        const isImportant = styleDeclaration.getPropertyPriority(attribute);\r\n        styles += `${attribute}:${styleDeclaration.getPropertyValue(attribute)}${isImportant ? ` !important` : ''};`;\r\n    }\r\n    return `${rule.selectorText} { ${styles} }`;\r\n}\r\nfunction stringifyRule(rule) {\r\n    let importStringified;\r\n    if (isCSSImportRule(rule)) {\r\n        try {\r\n            importStringified =\r\n                stringifyStylesheet(rule.styleSheet) ||\r\n                    escapeImportStatement(rule);\r\n        }\r\n        catch (error) {\r\n        }\r\n    }\r\n    else if (isCSSStyleRule(rule)) {\r\n        let cssText = rule.cssText;\r\n        const needsSafariColonFix = rule.selectorText.includes(':');\r\n        const needsAllFix = typeof rule.style['all'] === 'string' && rule.style['all'];\r\n        if (needsAllFix) {\r\n            cssText = fixAllCssProperty(rule);\r\n        }\r\n        if (needsSafariColonFix) {\r\n            cssText = fixSafariColons(cssText);\r\n        }\r\n        if (needsSafariColonFix || needsAllFix) {\r\n            return cssText;\r\n        }\r\n    }\r\n    return importStringified || rule.cssText;\r\n}\r\nfunction fixSafariColons(cssStringified) {\r\n    const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\r\n    return cssStringified.replace(regex, '$1\\\\$2');\r\n}\r\nfunction isCSSImportRule(rule) {\r\n    return 'styleSheet' in rule;\r\n}\r\nfunction isCSSStyleRule(rule) {\r\n    return 'selectorText' in rule;\r\n}\r\nclass Mirror {\r\n    constructor() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n    getId(n) {\r\n        if (!n)\r\n            return -1;\r\n        const id = this.getMeta(n)?.id;\r\n        return id ?? -1;\r\n    }\r\n    getNode(id) {\r\n        return this.idNodeMap.get(id) || null;\r\n    }\r\n    getIds() {\r\n        return Array.from(this.idNodeMap.keys());\r\n    }\r\n    getMeta(n) {\r\n        return this.nodeMetaMap.get(n) || null;\r\n    }\r\n    removeNodeFromMap(n) {\r\n        const id = this.getId(n);\r\n        this.idNodeMap.delete(id);\r\n        if (n.childNodes) {\r\n            n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));\r\n        }\r\n    }\r\n    has(id) {\r\n        return this.idNodeMap.has(id);\r\n    }\r\n    hasNode(node) {\r\n        return this.nodeMetaMap.has(node);\r\n    }\r\n    add(n, meta) {\r\n        const id = meta.id;\r\n        this.idNodeMap.set(id, n);\r\n        this.nodeMetaMap.set(n, meta);\r\n    }\r\n    replace(id, n) {\r\n        const oldNode = this.getNode(id);\r\n        if (oldNode) {\r\n            const meta = this.nodeMetaMap.get(oldNode);\r\n            if (meta)\r\n                this.nodeMetaMap.set(n, meta);\r\n        }\r\n        this.idNodeMap.set(id, n);\r\n    }\r\n    reset() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n}\r\nfunction createMirror() {\r\n    return new Mirror();\r\n}\r\nfunction shouldMaskInput({ maskInputOptions, tagName, type, }) {\r\n    if (tagName === 'OPTION') {\r\n        tagName = 'SELECT';\r\n    }\r\n    return Boolean(maskInputOptions[tagName.toLowerCase()] ||\r\n        (type && maskInputOptions[type]) ||\r\n        type === 'password' ||\r\n        (tagName === 'INPUT' && !type && maskInputOptions['text']));\r\n}\r\nfunction maskInputValue({ isMasked, element, value, maskInputFn, }) {\r\n    let text = value || '';\r\n    if (!isMasked) {\r\n        return text;\r\n    }\r\n    if (maskInputFn) {\r\n        text = maskInputFn(text, element);\r\n    }\r\n    return '*'.repeat(text.length);\r\n}\r\nfunction toLowerCase(str) {\r\n    return str.toLowerCase();\r\n}\r\nfunction toUpperCase(str) {\r\n    return str.toUpperCase();\r\n}\r\nconst ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';\r\nfunction is2DCanvasBlank(canvas) {\r\n    const ctx = canvas.getContext('2d');\r\n    if (!ctx)\r\n        return true;\r\n    const chunkSize = 50;\r\n    for (let x = 0; x < canvas.width; x += chunkSize) {\r\n        for (let y = 0; y < canvas.height; y += chunkSize) {\r\n            const getImageData = ctx.getImageData;\r\n            const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData\r\n                ? getImageData[ORIGINAL_ATTRIBUTE_NAME]\r\n                : getImageData;\r\n            const pixelBuffer = new Uint32Array(originalGetImageData.call(ctx, x, y, Math.min(chunkSize, canvas.width - x), Math.min(chunkSize, canvas.height - y)).data.buffer);\r\n            if (pixelBuffer.some((pixel) => pixel !== 0))\r\n                return false;\r\n        }\r\n    }\r\n    return true;\r\n}\r\nfunction isNodeMetaEqual(a, b) {\r\n    if (!a || !b || a.type !== b.type)\r\n        return false;\r\n    if (a.type === NodeType.Document)\r\n        return a.compatMode === b.compatMode;\r\n    else if (a.type === NodeType.DocumentType)\r\n        return (a.name === b.name &&\r\n            a.publicId === b.publicId &&\r\n            a.systemId === b.systemId);\r\n    else if (a.type === NodeType.Comment ||\r\n        a.type === NodeType.Text ||\r\n        a.type === NodeType.CDATA)\r\n        return a.textContent === b.textContent;\r\n    else if (a.type === NodeType.Element)\r\n        return (a.tagName === b.tagName &&\r\n            JSON.stringify(a.attributes) ===\r\n                JSON.stringify(b.attributes) &&\r\n            a.isSVG === b.isSVG &&\r\n            a.needBlock === b.needBlock);\r\n    return false;\r\n}\r\nfunction getInputType(element) {\r\n    const type = element.type;\r\n    return element.hasAttribute('data-rr-is-password')\r\n        ? 'password'\r\n        : type\r\n            ?\r\n                toLowerCase(type)\r\n            : null;\r\n}\r\nfunction getInputValue(el, tagName, type) {\r\n    if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {\r\n        return el.getAttribute('value') || '';\r\n    }\r\n    return el.value;\r\n}\r\nfunction extractFileExtension(path, baseURL) {\r\n    let url;\r\n    try {\r\n        url = new URL(path, baseURL ?? window.location.href);\r\n    }\r\n    catch (err) {\r\n        return null;\r\n    }\r\n    const regex = /\\.([0-9a-z]+)(?:$)/i;\r\n    const match = url.pathname.match(regex);\r\n    return match?.[1] ?? null;\r\n}\r\nconst cachedImplementations = {};\r\nfunction getImplementation(name) {\r\n    const cached = cachedImplementations[name];\r\n    if (cached) {\r\n        return cached;\r\n    }\r\n    const document = window.document;\r\n    let impl = window[name];\r\n    if (document && typeof document.createElement === 'function') {\r\n        try {\r\n            const sandbox = document.createElement('iframe');\r\n            sandbox.hidden = true;\r\n            document.head.appendChild(sandbox);\r\n            const contentWindow = sandbox.contentWindow;\r\n            if (contentWindow && contentWindow[name]) {\r\n                impl =\r\n                    contentWindow[name];\r\n            }\r\n            document.head.removeChild(sandbox);\r\n        }\r\n        catch (e) {\r\n        }\r\n    }\r\n    return (cachedImplementations[name] = impl.bind(window));\r\n}\r\nfunction onRequestAnimationFrame(...rest) {\r\n    return getImplementation('requestAnimationFrame')(...rest);\r\n}\r\nfunction setTimeout(...rest) {\r\n    return getImplementation('setTimeout')(...rest);\r\n}\r\nfunction clearTimeout(...rest) {\r\n    return getImplementation('clearTimeout')(...rest);\r\n}\r\nfunction getIframeContentDocument(iframe) {\r\n    try {\r\n        return iframe.contentDocument;\r\n    }\r\n    catch (e) {\r\n    }\r\n}\n\nlet _id = 1;\r\nconst tagNameRegex = new RegExp('[^a-z0-9-_:]');\r\nconst IGNORED_NODE = -2;\r\nfunction genId() {\r\n    return _id++;\r\n}\r\nfunction getValidTagName(element) {\r\n    if (element instanceof HTMLFormElement) {\r\n        return 'form';\r\n    }\r\n    const processedTagName = toLowerCase(element.tagName);\r\n    if (tagNameRegex.test(processedTagName)) {\r\n        return 'div';\r\n    }\r\n    return processedTagName;\r\n}\r\nfunction extractOrigin(url) {\r\n    let origin = '';\r\n    if (url.indexOf('//') > -1) {\r\n        origin = url.split('/').slice(0, 3).join('/');\r\n    }\r\n    else {\r\n        origin = url.split('/')[0];\r\n    }\r\n    origin = origin.split('?')[0];\r\n    return origin;\r\n}\r\nlet canvasService;\r\nlet canvasCtx;\r\nconst URL_IN_CSS_REF = /url\\((?:(')([^']*)'|(\")(.*?)\"|([^)]*))\\)/gm;\r\nconst URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\\/\\//i;\r\nconst URL_WWW_MATCH = /^www\\..*/i;\r\nconst DATA_URI = /^(data:)([^,]*),(.*)/i;\r\nfunction absoluteToStylesheet(cssText, href) {\r\n    return (cssText || '').replace(URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => {\r\n        const filePath = path1 || path2 || path3;\r\n        const maybeQuote = quote1 || quote2 || '';\r\n        if (!filePath) {\r\n            return origin;\r\n        }\r\n        if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {\r\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\r\n        }\r\n        if (DATA_URI.test(filePath)) {\r\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\r\n        }\r\n        if (filePath[0] === '/') {\r\n            return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;\r\n        }\r\n        const stack = href.split('/');\r\n        const parts = filePath.split('/');\r\n        stack.pop();\r\n        for (const part of parts) {\r\n            if (part === '.') {\r\n                continue;\r\n            }\r\n            else if (part === '..') {\r\n                stack.pop();\r\n            }\r\n            else {\r\n                stack.push(part);\r\n            }\r\n        }\r\n        return `url(${maybeQuote}${stack.join('/')}${maybeQuote})`;\r\n    });\r\n}\r\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\r\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\r\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\r\n    if (attributeValue.trim() === '') {\r\n        return attributeValue;\r\n    }\r\n    let pos = 0;\r\n    function collectCharacters(regEx) {\r\n        let chars;\r\n        const match = regEx.exec(attributeValue.substring(pos));\r\n        if (match) {\r\n            chars = match[0];\r\n            pos += chars.length;\r\n            return chars;\r\n        }\r\n        return '';\r\n    }\r\n    const output = [];\r\n    while (true) {\r\n        collectCharacters(SRCSET_COMMAS_OR_SPACES);\r\n        if (pos >= attributeValue.length) {\r\n            break;\r\n        }\r\n        let url = collectCharacters(SRCSET_NOT_SPACES);\r\n        if (url.slice(-1) === ',') {\r\n            url = absoluteToDoc(doc, url.substring(0, url.length - 1));\r\n            output.push(url);\r\n        }\r\n        else {\r\n            let descriptorsStr = '';\r\n            url = absoluteToDoc(doc, url);\r\n            let inParens = false;\r\n            while (true) {\r\n                const c = attributeValue.charAt(pos);\r\n                if (c === '') {\r\n                    output.push((url + descriptorsStr).trim());\r\n                    break;\r\n                }\r\n                else if (!inParens) {\r\n                    if (c === ',') {\r\n                        pos += 1;\r\n                        output.push((url + descriptorsStr).trim());\r\n                        break;\r\n                    }\r\n                    else if (c === '(') {\r\n                        inParens = true;\r\n                    }\r\n                }\r\n                else {\r\n                    if (c === ')') {\r\n                        inParens = false;\r\n                    }\r\n                }\r\n                descriptorsStr += c;\r\n                pos += 1;\r\n            }\r\n        }\r\n    }\r\n    return output.join(', ');\r\n}\r\nconst cachedDocument = new WeakMap();\r\nfunction absoluteToDoc(doc, attributeValue) {\r\n    if (!attributeValue || attributeValue.trim() === '') {\r\n        return attributeValue;\r\n    }\r\n    return getHref(doc, attributeValue);\r\n}\r\nfunction isSVGElement(el) {\r\n    return Boolean(el.tagName === 'svg' || el.ownerSVGElement);\r\n}\r\nfunction getHref(doc, customHref) {\r\n    let a = cachedDocument.get(doc);\r\n    if (!a) {\r\n        a = doc.createElement('a');\r\n        cachedDocument.set(doc, a);\r\n    }\r\n    if (!customHref) {\r\n        customHref = '';\r\n    }\r\n    else if (customHref.startsWith('blob:') || customHref.startsWith('data:')) {\r\n        return customHref;\r\n    }\r\n    a.setAttribute('href', customHref);\r\n    return a.href;\r\n}\r\nfunction transformAttribute(doc, tagName, name, value, element, maskAttributeFn) {\r\n    if (!value) {\r\n        return value;\r\n    }\r\n    if (name === 'src' ||\r\n        (name === 'href' && !(tagName === 'use' && value[0] === '#'))) {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'xlink:href' && value[0] !== '#') {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'background' &&\r\n        (tagName === 'table' || tagName === 'td' || tagName === 'th')) {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'srcset') {\r\n        return getAbsoluteSrcsetString(doc, value);\r\n    }\r\n    else if (name === 'style') {\r\n        return absoluteToStylesheet(value, getHref(doc));\r\n    }\r\n    else if (tagName === 'object' && name === 'data') {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    if (typeof maskAttributeFn === 'function') {\r\n        return maskAttributeFn(name, value, element);\r\n    }\r\n    return value;\r\n}\r\nfunction ignoreAttribute(tagName, name, _value) {\r\n    return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';\r\n}\r\nfunction _isBlockedElement(element, blockClass, blockSelector, unblockSelector) {\r\n    try {\r\n        if (unblockSelector && element.matches(unblockSelector)) {\r\n            return false;\r\n        }\r\n        if (typeof blockClass === 'string') {\r\n            if (element.classList.contains(blockClass)) {\r\n                return true;\r\n            }\r\n        }\r\n        else {\r\n            for (let eIndex = element.classList.length; eIndex--;) {\r\n                const className = element.classList[eIndex];\r\n                if (blockClass.test(className)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        if (blockSelector) {\r\n            return element.matches(blockSelector);\r\n        }\r\n    }\r\n    catch (e) {\r\n    }\r\n    return false;\r\n}\r\nfunction elementClassMatchesRegex(el, regex) {\r\n    for (let eIndex = el.classList.length; eIndex--;) {\r\n        const className = el.classList[eIndex];\r\n        if (regex.test(className)) {\r\n            return true;\r\n        }\r\n    }\r\n    return false;\r\n}\r\nfunction classMatchesRegex(node, regex, checkAncestors) {\r\n    if (!node)\r\n        return false;\r\n    if (checkAncestors) {\r\n        return (distanceToMatch(node, (node) => elementClassMatchesRegex(node, regex)) >= 0);\r\n    }\r\n    else if (node.nodeType === node.ELEMENT_NODE) {\r\n        return elementClassMatchesRegex(node, regex);\r\n    }\r\n    return false;\r\n}\r\nfunction distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {\r\n    if (!node)\r\n        return -1;\r\n    if (node.nodeType !== node.ELEMENT_NODE)\r\n        return -1;\r\n    if (distance > limit)\r\n        return -1;\r\n    if (matchPredicate(node))\r\n        return distance;\r\n    return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);\r\n}\r\nfunction createMatchPredicate(className, selector) {\r\n    return (node) => {\r\n        const el = node;\r\n        if (el === null)\r\n            return false;\r\n        try {\r\n            if (className) {\r\n                if (typeof className === 'string') {\r\n                    if (el.matches(`.${className}`))\r\n                        return true;\r\n                }\r\n                else if (elementClassMatchesRegex(el, className)) {\r\n                    return true;\r\n                }\r\n            }\r\n            if (selector && el.matches(selector))\r\n                return true;\r\n            return false;\r\n        }\r\n        catch {\r\n            return false;\r\n        }\r\n    };\r\n}\r\nfunction needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText) {\r\n    try {\r\n        const el = node.nodeType === node.ELEMENT_NODE\r\n            ? node\r\n            : node.parentElement;\r\n        if (el === null)\r\n            return false;\r\n        if (el.tagName === 'INPUT') {\r\n            const autocomplete = el.getAttribute('autocomplete');\r\n            const disallowedAutocompleteValues = [\r\n                'current-password',\r\n                'new-password',\r\n                'cc-number',\r\n                'cc-exp',\r\n                'cc-exp-month',\r\n                'cc-exp-year',\r\n                'cc-csc',\r\n            ];\r\n            if (disallowedAutocompleteValues.includes(autocomplete)) {\r\n                return true;\r\n            }\r\n        }\r\n        let maskDistance = -1;\r\n        let unmaskDistance = -1;\r\n        if (maskAllText) {\r\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector));\r\n            if (unmaskDistance < 0) {\r\n                return true;\r\n            }\r\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector), unmaskDistance >= 0 ? unmaskDistance : Infinity);\r\n        }\r\n        else {\r\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector));\r\n            if (maskDistance < 0) {\r\n                return false;\r\n            }\r\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector), maskDistance >= 0 ? maskDistance : Infinity);\r\n        }\r\n        return maskDistance >= 0\r\n            ? unmaskDistance >= 0\r\n                ? maskDistance <= unmaskDistance\r\n                : true\r\n            : unmaskDistance >= 0\r\n                ? false\r\n                : !!maskAllText;\r\n    }\r\n    catch (e) {\r\n    }\r\n    return !!maskAllText;\r\n}\r\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\r\n    const win = iframeEl.contentWindow;\r\n    if (!win) {\r\n        return;\r\n    }\r\n    let fired = false;\r\n    let readyState;\r\n    try {\r\n        readyState = win.document.readyState;\r\n    }\r\n    catch (error) {\r\n        return;\r\n    }\r\n    if (readyState !== 'complete') {\r\n        const timer = setTimeout(() => {\r\n            if (!fired) {\r\n                listener();\r\n                fired = true;\r\n            }\r\n        }, iframeLoadTimeout);\r\n        iframeEl.addEventListener('load', () => {\r\n            clearTimeout(timer);\r\n            fired = true;\r\n            listener();\r\n        });\r\n        return;\r\n    }\r\n    const blankUrl = 'about:blank';\r\n    if (win.location.href !== blankUrl ||\r\n        iframeEl.src === blankUrl ||\r\n        iframeEl.src === '') {\r\n        setTimeout(listener, 0);\r\n        return iframeEl.addEventListener('load', listener);\r\n    }\r\n    iframeEl.addEventListener('load', listener);\r\n}\r\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\r\n    let fired = false;\r\n    let styleSheetLoaded;\r\n    try {\r\n        styleSheetLoaded = link.sheet;\r\n    }\r\n    catch (error) {\r\n        return;\r\n    }\r\n    if (styleSheetLoaded)\r\n        return;\r\n    const timer = setTimeout(() => {\r\n        if (!fired) {\r\n            listener();\r\n            fired = true;\r\n        }\r\n    }, styleSheetLoadTimeout);\r\n    link.addEventListener('load', () => {\r\n        clearTimeout(timer);\r\n        fired = true;\r\n        listener();\r\n    });\r\n}\r\nfunction serializeNode(n, options) {\r\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskAttributeFn, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, } = options;\r\n    const rootId = getRootId(doc, mirror);\r\n    switch (n.nodeType) {\r\n        case n.DOCUMENT_NODE:\r\n            if (n.compatMode !== 'CSS1Compat') {\r\n                return {\r\n                    type: NodeType.Document,\r\n                    childNodes: [],\r\n                    compatMode: n.compatMode,\r\n                };\r\n            }\r\n            else {\r\n                return {\r\n                    type: NodeType.Document,\r\n                    childNodes: [],\r\n                };\r\n            }\r\n        case n.DOCUMENT_TYPE_NODE:\r\n            return {\r\n                type: NodeType.DocumentType,\r\n                name: n.name,\r\n                publicId: n.publicId,\r\n                systemId: n.systemId,\r\n                rootId,\r\n            };\r\n        case n.ELEMENT_NODE:\r\n            return serializeElementNode(n, {\r\n                doc,\r\n                blockClass,\r\n                blockSelector,\r\n                unblockSelector,\r\n                inlineStylesheet,\r\n                maskAttributeFn,\r\n                maskInputOptions,\r\n                maskInputFn,\r\n                dataURLOptions,\r\n                inlineImages,\r\n                recordCanvas,\r\n                keepIframeSrcFn,\r\n                newlyAddedElement,\r\n                rootId,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n            });\r\n        case n.TEXT_NODE:\r\n            return serializeTextNode(n, {\r\n                doc,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n                maskTextFn,\r\n                maskInputOptions,\r\n                maskInputFn,\r\n                rootId,\r\n            });\r\n        case n.CDATA_SECTION_NODE:\r\n            return {\r\n                type: NodeType.CDATA,\r\n                textContent: '',\r\n                rootId,\r\n            };\r\n        case n.COMMENT_NODE:\r\n            return {\r\n                type: NodeType.Comment,\r\n                textContent: n.textContent || '',\r\n                rootId,\r\n            };\r\n        default:\r\n            return false;\r\n    }\r\n}\r\nfunction getRootId(doc, mirror) {\r\n    if (!mirror.hasNode(doc))\r\n        return undefined;\r\n    const docId = mirror.getId(doc);\r\n    return docId === 1 ? undefined : docId;\r\n}\r\nfunction serializeTextNode(n, options) {\r\n    const { maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, maskTextFn, maskInputOptions, maskInputFn, rootId, } = options;\r\n    const parentTagName = n.parentNode && n.parentNode.tagName;\r\n    let textContent = n.textContent;\r\n    const isStyle = parentTagName === 'STYLE' ? true : undefined;\r\n    const isScript = parentTagName === 'SCRIPT' ? true : undefined;\r\n    const isTextarea = parentTagName === 'TEXTAREA' ? true : undefined;\r\n    if (isStyle && textContent) {\r\n        try {\r\n            if (n.nextSibling || n.previousSibling) {\r\n            }\r\n            else if (n.parentNode.sheet?.cssRules) {\r\n                textContent = stringifyStylesheet(n.parentNode.sheet);\r\n            }\r\n        }\r\n        catch (err) {\r\n            console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);\r\n        }\r\n        textContent = absoluteToStylesheet(textContent, getHref(options.doc));\r\n    }\r\n    if (isScript) {\r\n        textContent = 'SCRIPT_PLACEHOLDER';\r\n    }\r\n    const forceMask = needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText);\r\n    if (!isStyle && !isScript && !isTextarea && textContent && forceMask) {\r\n        textContent = maskTextFn\r\n            ? maskTextFn(textContent, n.parentElement)\r\n            : textContent.replace(/[\\S]/g, '*');\r\n    }\r\n    if (isTextarea && textContent && (maskInputOptions.textarea || forceMask)) {\r\n        textContent = maskInputFn\r\n            ? maskInputFn(textContent, n.parentNode)\r\n            : textContent.replace(/[\\S]/g, '*');\r\n    }\r\n    if (parentTagName === 'OPTION' && textContent) {\r\n        const isInputMasked = shouldMaskInput({\r\n            type: null,\r\n            tagName: parentTagName,\r\n            maskInputOptions,\r\n        });\r\n        textContent = maskInputValue({\r\n            isMasked: needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked),\r\n            element: n,\r\n            value: textContent,\r\n            maskInputFn,\r\n        });\r\n    }\r\n    return {\r\n        type: NodeType.Text,\r\n        textContent: textContent || '',\r\n        isStyle,\r\n        rootId,\r\n    };\r\n}\r\nfunction serializeElementNode(n, options) {\r\n    const { doc, blockClass, blockSelector, unblockSelector, inlineStylesheet, maskInputOptions = {}, maskAttributeFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, } = options;\r\n    const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);\r\n    const tagName = getValidTagName(n);\r\n    let attributes = {};\r\n    const len = n.attributes.length;\r\n    for (let i = 0; i < len; i++) {\r\n        const attr = n.attributes[i];\r\n        if (attr.name && !ignoreAttribute(tagName, attr.name, attr.value)) {\r\n            attributes[attr.name] = transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value, n, maskAttributeFn);\r\n        }\r\n    }\r\n    if (tagName === 'link' && inlineStylesheet) {\r\n        const stylesheet = Array.from(doc.styleSheets).find((s) => {\r\n            return s.href === n.href;\r\n        });\r\n        let cssText = null;\r\n        if (stylesheet) {\r\n            cssText = stringifyStylesheet(stylesheet);\r\n        }\r\n        if (cssText) {\r\n            attributes.rel = null;\r\n            attributes.href = null;\r\n            attributes.crossorigin = null;\r\n            attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);\r\n        }\r\n    }\r\n    if (tagName === 'style' &&\r\n        n.sheet &&\r\n        !(n.innerText || n.textContent || '').trim().length) {\r\n        const cssText = stringifyStylesheet(n.sheet);\r\n        if (cssText) {\r\n            attributes._cssText = absoluteToStylesheet(cssText, getHref(doc));\r\n        }\r\n    }\r\n    if (tagName === 'input' ||\r\n        tagName === 'textarea' ||\r\n        tagName === 'select' ||\r\n        tagName === 'option') {\r\n        const el = n;\r\n        const type = getInputType(el);\r\n        const value = getInputValue(el, toUpperCase(tagName), type);\r\n        const checked = el.checked;\r\n        if (type !== 'submit' && type !== 'button' && value) {\r\n            const forceMask = needMaskingText(el, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, shouldMaskInput({\r\n                type,\r\n                tagName: toUpperCase(tagName),\r\n                maskInputOptions,\r\n            }));\r\n            attributes.value = maskInputValue({\r\n                isMasked: forceMask,\r\n                element: el,\r\n                value,\r\n                maskInputFn,\r\n            });\r\n        }\r\n        if (checked) {\r\n            attributes.checked = checked;\r\n        }\r\n    }\r\n    if (tagName === 'option') {\r\n        if (n.selected && !maskInputOptions['select']) {\r\n            attributes.selected = true;\r\n        }\r\n        else {\r\n            delete attributes.selected;\r\n        }\r\n    }\r\n    if (tagName === 'canvas' && recordCanvas) {\r\n        if (n.__context === '2d') {\r\n            if (!is2DCanvasBlank(n)) {\r\n                attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            }\r\n        }\r\n        else if (!('__context' in n)) {\r\n            const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            const blankCanvas = doc.createElement('canvas');\r\n            blankCanvas.width = n.width;\r\n            blankCanvas.height = n.height;\r\n            const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            if (canvasDataURL !== blankCanvasDataURL) {\r\n                attributes.rr_dataURL = canvasDataURL;\r\n            }\r\n        }\r\n    }\r\n    if (tagName === 'img' && inlineImages) {\r\n        if (!canvasService) {\r\n            canvasService = doc.createElement('canvas');\r\n            canvasCtx = canvasService.getContext('2d');\r\n        }\r\n        const image = n;\r\n        const imageSrc = image.currentSrc || image.getAttribute('src') || '<unknown-src>';\r\n        const priorCrossOrigin = image.crossOrigin;\r\n        const recordInlineImage = () => {\r\n            image.removeEventListener('load', recordInlineImage);\r\n            try {\r\n                canvasService.width = image.naturalWidth;\r\n                canvasService.height = image.naturalHeight;\r\n                canvasCtx.drawImage(image, 0, 0);\r\n                attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            }\r\n            catch (err) {\r\n                if (image.crossOrigin !== 'anonymous') {\r\n                    image.crossOrigin = 'anonymous';\r\n                    if (image.complete && image.naturalWidth !== 0)\r\n                        recordInlineImage();\r\n                    else\r\n                        image.addEventListener('load', recordInlineImage);\r\n                    return;\r\n                }\r\n                else {\r\n                    console.warn(`Cannot inline img src=${imageSrc}! Error: ${err}`);\r\n                }\r\n            }\r\n            if (image.crossOrigin === 'anonymous') {\r\n                priorCrossOrigin\r\n                    ? (attributes.crossOrigin = priorCrossOrigin)\r\n                    : image.removeAttribute('crossorigin');\r\n            }\r\n        };\r\n        if (image.complete && image.naturalWidth !== 0)\r\n            recordInlineImage();\r\n        else\r\n            image.addEventListener('load', recordInlineImage);\r\n    }\r\n    if (tagName === 'audio' || tagName === 'video') {\r\n        attributes.rr_mediaState = n.paused\r\n            ? 'paused'\r\n            : 'played';\r\n        attributes.rr_mediaCurrentTime = n.currentTime;\r\n    }\r\n    if (!newlyAddedElement) {\r\n        if (n.scrollLeft) {\r\n            attributes.rr_scrollLeft = n.scrollLeft;\r\n        }\r\n        if (n.scrollTop) {\r\n            attributes.rr_scrollTop = n.scrollTop;\r\n        }\r\n    }\r\n    if (needBlock) {\r\n        const { width, height } = n.getBoundingClientRect();\r\n        attributes = {\r\n            class: attributes.class,\r\n            rr_width: `${width}px`,\r\n            rr_height: `${height}px`,\r\n        };\r\n    }\r\n    if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {\r\n        if (!needBlock && !getIframeContentDocument(n)) {\r\n            attributes.rr_src = attributes.src;\r\n        }\r\n        delete attributes.src;\r\n    }\r\n    let isCustomElement;\r\n    try {\r\n        if (customElements.get(tagName))\r\n            isCustomElement = true;\r\n    }\r\n    catch (e) {\r\n    }\r\n    return {\r\n        type: NodeType.Element,\r\n        tagName,\r\n        attributes,\r\n        childNodes: [],\r\n        isSVG: isSVGElement(n) || undefined,\r\n        needBlock,\r\n        rootId,\r\n        isCustom: isCustomElement,\r\n    };\r\n}\r\nfunction lowerIfExists(maybeAttr) {\r\n    if (maybeAttr === undefined || maybeAttr === null) {\r\n        return '';\r\n    }\r\n    else {\r\n        return maybeAttr.toLowerCase();\r\n    }\r\n}\r\nfunction slimDOMExcluded(sn, slimDOMOptions) {\r\n    if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\r\n        return true;\r\n    }\r\n    else if (sn.type === NodeType.Element) {\r\n        if (slimDOMOptions.script &&\r\n            (sn.tagName === 'script' ||\r\n                (sn.tagName === 'link' &&\r\n                    (sn.attributes.rel === 'preload' ||\r\n                        sn.attributes.rel === 'modulepreload')) ||\r\n                (sn.tagName === 'link' &&\r\n                    sn.attributes.rel === 'prefetch' &&\r\n                    typeof sn.attributes.href === 'string' &&\r\n                    extractFileExtension(sn.attributes.href) === 'js'))) {\r\n            return true;\r\n        }\r\n        else if (slimDOMOptions.headFavicon &&\r\n            ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||\r\n                (sn.tagName === 'meta' &&\r\n                    (lowerIfExists(sn.attributes.name).match(/^msapplication-tile(image|color)$/) ||\r\n                        lowerIfExists(sn.attributes.name) === 'application-name' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'icon' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'shortcut icon')))) {\r\n            return true;\r\n        }\r\n        else if (sn.tagName === 'meta') {\r\n            if (slimDOMOptions.headMetaDescKeywords &&\r\n                lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaSocial &&\r\n                (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) ||\r\n                    lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||\r\n                    lowerIfExists(sn.attributes.name) === 'pinterest')) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaRobots &&\r\n                (lowerIfExists(sn.attributes.name) === 'robots' ||\r\n                    lowerIfExists(sn.attributes.name) === 'googlebot' ||\r\n                    lowerIfExists(sn.attributes.name) === 'bingbot')) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaHttpEquiv &&\r\n                sn.attributes['http-equiv'] !== undefined) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaAuthorship &&\r\n                (lowerIfExists(sn.attributes.name) === 'author' ||\r\n                    lowerIfExists(sn.attributes.name) === 'generator' ||\r\n                    lowerIfExists(sn.attributes.name) === 'framework' ||\r\n                    lowerIfExists(sn.attributes.name) === 'publisher' ||\r\n                    lowerIfExists(sn.attributes.name) === 'progid' ||\r\n                    lowerIfExists(sn.attributes.property).match(/^article:/) ||\r\n                    lowerIfExists(sn.attributes.property).match(/^product:/))) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaVerification &&\r\n                (lowerIfExists(sn.attributes.name) === 'google-site-verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'yandex-verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'csrf-token' ||\r\n                    lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||\r\n                    lowerIfExists(sn.attributes.name) === 'verify-v1' ||\r\n                    lowerIfExists(sn.attributes.name) === 'verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')) {\r\n                return true;\r\n            }\r\n        }\r\n    }\r\n    return false;\r\n}\r\nfunction serializeNodeWithId(n, options) {\r\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, skipChild = false, inlineStylesheet = true, maskInputOptions = {}, maskAttributeFn, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5000, onStylesheetLoad, stylesheetLoadTimeout = 5000, keepIframeSrcFn = () => false, newlyAddedElement = false, } = options;\r\n    let { preserveWhiteSpace = true } = options;\r\n    const _serializedNode = serializeNode(n, {\r\n        doc,\r\n        mirror,\r\n        blockClass,\r\n        blockSelector,\r\n        maskAllText,\r\n        unblockSelector,\r\n        maskTextClass,\r\n        unmaskTextClass,\r\n        maskTextSelector,\r\n        unmaskTextSelector,\r\n        inlineStylesheet,\r\n        maskInputOptions,\r\n        maskAttributeFn,\r\n        maskTextFn,\r\n        maskInputFn,\r\n        dataURLOptions,\r\n        inlineImages,\r\n        recordCanvas,\r\n        keepIframeSrcFn,\r\n        newlyAddedElement,\r\n    });\r\n    if (!_serializedNode) {\r\n        console.warn(n, 'not serialized');\r\n        return null;\r\n    }\r\n    let id;\r\n    if (mirror.hasNode(n)) {\r\n        id = mirror.getId(n);\r\n    }\r\n    else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||\r\n        (!preserveWhiteSpace &&\r\n            _serializedNode.type === NodeType.Text &&\r\n            !_serializedNode.isStyle &&\r\n            !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, '').length)) {\r\n        id = IGNORED_NODE;\r\n    }\r\n    else {\r\n        id = genId();\r\n    }\r\n    const serializedNode = Object.assign(_serializedNode, { id });\r\n    mirror.add(n, serializedNode);\r\n    if (id === IGNORED_NODE) {\r\n        return null;\r\n    }\r\n    if (onSerialize) {\r\n        onSerialize(n);\r\n    }\r\n    let recordChild = !skipChild;\r\n    if (serializedNode.type === NodeType.Element) {\r\n        recordChild = recordChild && !serializedNode.needBlock;\r\n        delete serializedNode.needBlock;\r\n        const shadowRoot = n.shadowRoot;\r\n        if (shadowRoot && isNativeShadowDom(shadowRoot))\r\n            serializedNode.isShadowHost = true;\r\n    }\r\n    if ((serializedNode.type === NodeType.Document ||\r\n        serializedNode.type === NodeType.Element) &&\r\n        recordChild) {\r\n        if (slimDOMOptions.headWhitespace &&\r\n            serializedNode.type === NodeType.Element &&\r\n            serializedNode.tagName === 'head') {\r\n            preserveWhiteSpace = false;\r\n        }\r\n        const bypassOptions = {\r\n            doc,\r\n            mirror,\r\n            blockClass,\r\n            blockSelector,\r\n            maskAllText,\r\n            unblockSelector,\r\n            maskTextClass,\r\n            unmaskTextClass,\r\n            maskTextSelector,\r\n            unmaskTextSelector,\r\n            skipChild,\r\n            inlineStylesheet,\r\n            maskInputOptions,\r\n            maskAttributeFn,\r\n            maskTextFn,\r\n            maskInputFn,\r\n            slimDOMOptions,\r\n            dataURLOptions,\r\n            inlineImages,\r\n            recordCanvas,\r\n            preserveWhiteSpace,\r\n            onSerialize,\r\n            onIframeLoad,\r\n            iframeLoadTimeout,\r\n            onStylesheetLoad,\r\n            stylesheetLoadTimeout,\r\n            keepIframeSrcFn,\r\n        };\r\n        for (const childN of Array.from(n.childNodes)) {\r\n            const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\r\n            if (serializedChildNode) {\r\n                serializedNode.childNodes.push(serializedChildNode);\r\n            }\r\n        }\r\n        if (isElement(n) && n.shadowRoot) {\r\n            for (const childN of Array.from(n.shadowRoot.childNodes)) {\r\n                const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\r\n                if (serializedChildNode) {\r\n                    isNativeShadowDom(n.shadowRoot) &&\r\n                        (serializedChildNode.isShadow = true);\r\n                    serializedNode.childNodes.push(serializedChildNode);\r\n                }\r\n            }\r\n        }\r\n    }\r\n    if (n.parentNode &&\r\n        isShadowRoot(n.parentNode) &&\r\n        isNativeShadowDom(n.parentNode)) {\r\n        serializedNode.isShadow = true;\r\n    }\r\n    if (serializedNode.type === NodeType.Element &&\r\n        serializedNode.tagName === 'iframe') {\r\n        onceIframeLoaded(n, () => {\r\n            const iframeDoc = getIframeContentDocument(n);\r\n            if (iframeDoc && onIframeLoad) {\r\n                const serializedIframeNode = serializeNodeWithId(iframeDoc, {\r\n                    doc: iframeDoc,\r\n                    mirror,\r\n                    blockClass,\r\n                    blockSelector,\r\n                    unblockSelector,\r\n                    maskAllText,\r\n                    maskTextClass,\r\n                    unmaskTextClass,\r\n                    maskTextSelector,\r\n                    unmaskTextSelector,\r\n                    skipChild: false,\r\n                    inlineStylesheet,\r\n                    maskInputOptions,\r\n                    maskAttributeFn,\r\n                    maskTextFn,\r\n                    maskInputFn,\r\n                    slimDOMOptions,\r\n                    dataURLOptions,\r\n                    inlineImages,\r\n                    recordCanvas,\r\n                    preserveWhiteSpace,\r\n                    onSerialize,\r\n                    onIframeLoad,\r\n                    iframeLoadTimeout,\r\n                    onStylesheetLoad,\r\n                    stylesheetLoadTimeout,\r\n                    keepIframeSrcFn,\r\n                });\r\n                if (serializedIframeNode) {\r\n                    onIframeLoad(n, serializedIframeNode);\r\n                }\r\n            }\r\n        }, iframeLoadTimeout);\r\n    }\r\n    if (serializedNode.type === NodeType.Element &&\r\n        serializedNode.tagName === 'link' &&\r\n        typeof serializedNode.attributes.rel === 'string' &&\r\n        (serializedNode.attributes.rel === 'stylesheet' ||\r\n            (serializedNode.attributes.rel === 'preload' &&\r\n                typeof serializedNode.attributes.href === 'string' &&\r\n                extractFileExtension(serializedNode.attributes.href) === 'css'))) {\r\n        onceStylesheetLoaded(n, () => {\r\n            if (onStylesheetLoad) {\r\n                const serializedLinkNode = serializeNodeWithId(n, {\r\n                    doc,\r\n                    mirror,\r\n                    blockClass,\r\n                    blockSelector,\r\n                    unblockSelector,\r\n                    maskAllText,\r\n                    maskTextClass,\r\n                    unmaskTextClass,\r\n                    maskTextSelector,\r\n                    unmaskTextSelector,\r\n                    skipChild: false,\r\n                    inlineStylesheet,\r\n                    maskInputOptions,\r\n                    maskAttributeFn,\r\n                    maskTextFn,\r\n                    maskInputFn,\r\n                    slimDOMOptions,\r\n                    dataURLOptions,\r\n                    inlineImages,\r\n                    recordCanvas,\r\n                    preserveWhiteSpace,\r\n                    onSerialize,\r\n                    onIframeLoad,\r\n                    iframeLoadTimeout,\r\n                    onStylesheetLoad,\r\n                    stylesheetLoadTimeout,\r\n                    keepIframeSrcFn,\r\n                });\r\n                if (serializedLinkNode) {\r\n                    onStylesheetLoad(n, serializedLinkNode);\r\n                }\r\n            }\r\n        }, stylesheetLoadTimeout);\r\n    }\r\n    return serializedNode;\r\n}\r\nfunction snapshot(n, options) {\r\n    const { mirror = new Mirror(), blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskAllInputs = false, maskAttributeFn, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn = () => false, } = options || {};\r\n    const maskInputOptions = maskAllInputs === true\r\n        ? {\r\n            color: true,\r\n            date: true,\r\n            'datetime-local': true,\r\n            email: true,\r\n            month: true,\r\n            number: true,\r\n            range: true,\r\n            search: true,\r\n            tel: true,\r\n            text: true,\r\n            time: true,\r\n            url: true,\r\n            week: true,\r\n            textarea: true,\r\n            select: true,\r\n        }\r\n        : maskAllInputs === false\r\n            ? {}\r\n            : maskAllInputs;\r\n    const slimDOMOptions = slimDOM === true || slimDOM === 'all'\r\n        ?\r\n            {\r\n                script: true,\r\n                comment: true,\r\n                headFavicon: true,\r\n                headWhitespace: true,\r\n                headMetaDescKeywords: slimDOM === 'all',\r\n                headMetaSocial: true,\r\n                headMetaRobots: true,\r\n                headMetaHttpEquiv: true,\r\n                headMetaAuthorship: true,\r\n                headMetaVerification: true,\r\n            }\r\n        : slimDOM === false\r\n            ? {}\r\n            : slimDOM;\r\n    return serializeNodeWithId(n, {\r\n        doc: n,\r\n        mirror,\r\n        blockClass,\r\n        blockSelector,\r\n        unblockSelector,\r\n        maskAllText,\r\n        maskTextClass,\r\n        unmaskTextClass,\r\n        maskTextSelector,\r\n        unmaskTextSelector,\r\n        skipChild: false,\r\n        inlineStylesheet,\r\n        maskInputOptions,\r\n        maskAttributeFn,\r\n        maskTextFn,\r\n        maskInputFn,\r\n        slimDOMOptions,\r\n        dataURLOptions,\r\n        inlineImages,\r\n        recordCanvas,\r\n        preserveWhiteSpace,\r\n        onSerialize,\r\n        onIframeLoad,\r\n        iframeLoadTimeout,\r\n        onStylesheetLoad,\r\n        stylesheetLoadTimeout,\r\n        keepIframeSrcFn,\r\n        newlyAddedElement: false,\r\n    });\r\n}\r\nfunction visitSnapshot(node, onVisit) {\r\n    function walk(current) {\r\n        onVisit(current);\r\n        if (current.type === NodeType.Document ||\r\n            current.type === NodeType.Element) {\r\n            current.childNodes.forEach(walk);\r\n        }\r\n    }\r\n    walk(node);\r\n}\r\nfunction cleanupSnapshot() {\r\n    _id = 1;\r\n}\n\nconst commentre = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g;\r\nfunction parse(css, options = {}) {\r\n    let lineno = 1;\r\n    let column = 1;\r\n    function updatePosition(str) {\r\n        const lines = str.match(/\\n/g);\r\n        if (lines) {\r\n            lineno += lines.length;\r\n        }\r\n        const i = str.lastIndexOf('\\n');\r\n        column = i === -1 ? column + str.length : str.length - i;\r\n    }\r\n    function position() {\r\n        const start = { line: lineno, column };\r\n        return (node) => {\r\n            node.position = new Position(start);\r\n            whitespace();\r\n            return node;\r\n        };\r\n    }\r\n    class Position {\r\n        constructor(start) {\r\n            this.start = start;\r\n            this.end = { line: lineno, column };\r\n            this.source = options.source;\r\n        }\r\n    }\r\n    Position.prototype.content = css;\r\n    const errorsList = [];\r\n    function error(msg) {\r\n        const err = new Error(`${options.source || ''}:${lineno}:${column}: ${msg}`);\r\n        err.reason = msg;\r\n        err.filename = options.source;\r\n        err.line = lineno;\r\n        err.column = column;\r\n        err.source = css;\r\n        if (options.silent) {\r\n            errorsList.push(err);\r\n        }\r\n        else {\r\n            throw err;\r\n        }\r\n    }\r\n    function stylesheet() {\r\n        const rulesList = rules();\r\n        return {\r\n            type: 'stylesheet',\r\n            stylesheet: {\r\n                source: options.source,\r\n                rules: rulesList,\r\n                parsingErrors: errorsList,\r\n            },\r\n        };\r\n    }\r\n    function open() {\r\n        return match(/^{\\s*/);\r\n    }\r\n    function close() {\r\n        return match(/^}/);\r\n    }\r\n    function rules() {\r\n        let node;\r\n        const rules = [];\r\n        whitespace();\r\n        comments(rules);\r\n        while (css.length && css.charAt(0) !== '}' && (node = atrule() || rule())) {\r\n            if (node) {\r\n                rules.push(node);\r\n                comments(rules);\r\n            }\r\n        }\r\n        return rules;\r\n    }\r\n    function match(re) {\r\n        const m = re.exec(css);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const str = m[0];\r\n        updatePosition(str);\r\n        css = css.slice(str.length);\r\n        return m;\r\n    }\r\n    function whitespace() {\r\n        match(/^\\s*/);\r\n    }\r\n    function comments(rules = []) {\r\n        let c;\r\n        while ((c = comment())) {\r\n            if (c) {\r\n                rules.push(c);\r\n            }\r\n            c = comment();\r\n        }\r\n        return rules;\r\n    }\r\n    function comment() {\r\n        const pos = position();\r\n        if ('/' !== css.charAt(0) || '*' !== css.charAt(1)) {\r\n            return;\r\n        }\r\n        let i = 2;\r\n        while ('' !== css.charAt(i) &&\r\n            ('*' !== css.charAt(i) || '/' !== css.charAt(i + 1))) {\r\n            ++i;\r\n        }\r\n        i += 2;\r\n        if ('' === css.charAt(i - 1)) {\r\n            return error('End of comment missing');\r\n        }\r\n        const str = css.slice(2, i - 2);\r\n        column += 2;\r\n        updatePosition(str);\r\n        css = css.slice(i);\r\n        column += 2;\r\n        return pos({\r\n            type: 'comment',\r\n            comment: str,\r\n        });\r\n    }\r\n    function selector() {\r\n        const m = match(/^([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const splitSelectors = trim(m[0])\r\n            .replace(/\\/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*\\/+/g, '')\r\n            .replace(/\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'/g, (m) => {\r\n            return m.replace(/,/g, '\\u200C');\r\n        })\r\n            .split(/\\s*(?![^(]*\\)),\\s*/);\r\n        if (splitSelectors.length <= 1) {\r\n            return splitSelectors.map((s) => {\r\n                return s.replace(/\\u200C/g, ',');\r\n            });\r\n        }\r\n        let i = 0;\r\n        let j = 0;\r\n        const len = splitSelectors.length;\r\n        const finalSelectors = [];\r\n        while (i < len) {\r\n            const openingParensCount = (splitSelectors[i].match(/\\(/g) || []).length;\r\n            const closingParensCount = (splitSelectors[i].match(/\\)/g) || []).length;\r\n            let unbalancedParens = openingParensCount - closingParensCount;\r\n            if (unbalancedParens >= 1) {\r\n                let foundClosingSelector = false;\r\n                j = i + 1;\r\n                while (j < len) {\r\n                    const nextOpeningParensCount = (splitSelectors[j].match(/\\(/g) || [])\r\n                        .length;\r\n                    const nextClosingParensCount = (splitSelectors[j].match(/\\)/g) || [])\r\n                        .length;\r\n                    const nextUnbalancedParens = nextClosingParensCount - nextOpeningParensCount;\r\n                    if (nextUnbalancedParens === unbalancedParens) {\r\n                        finalSelectors.push(splitSelectors.slice(i, j + 1).join(','));\r\n                        i = j + 1;\r\n                        foundClosingSelector = true;\r\n                        break;\r\n                    }\r\n                    j++;\r\n                    unbalancedParens -= nextUnbalancedParens;\r\n                }\r\n                if (foundClosingSelector) {\r\n                    continue;\r\n                }\r\n                splitSelectors\r\n                    .slice(i, len)\r\n                    .forEach((selector) => selector && finalSelectors.push(selector));\r\n                break;\r\n            }\r\n            splitSelectors[i] && finalSelectors.push(splitSelectors[i]);\r\n            i++;\r\n        }\r\n        return finalSelectors.map((s) => {\r\n            return s.replace(/\\u200C/g, ',');\r\n        });\r\n    }\r\n    function declaration() {\r\n        const pos = position();\r\n        const propMatch = match(/^(\\*?[-#\\/\\*\\\\\\w]+(\\[[0-9a-z_-]+\\])?)\\s*/);\r\n        if (!propMatch) {\r\n            return;\r\n        }\r\n        const prop = trim(propMatch[0]);\r\n        if (!match(/^:\\s*/)) {\r\n            return error(`property missing ':'`);\r\n        }\r\n        const val = match(/^((?:'(?:\\\\'|.)*?'|\"(?:\\\\\"|.)*?\"|\\([^\\)]*?\\)|[^};])+)/);\r\n        const ret = pos({\r\n            type: 'declaration',\r\n            property: prop.replace(commentre, ''),\r\n            value: val ? trim(val[0]).replace(commentre, '') : '',\r\n        });\r\n        match(/^[;\\s]*/);\r\n        return ret;\r\n    }\r\n    function declarations() {\r\n        const decls = [];\r\n        if (!open()) {\r\n            return error(`missing '{'`);\r\n        }\r\n        comments(decls);\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            if (decl !== false) {\r\n                decls.push(decl);\r\n                comments(decls);\r\n            }\r\n            decl = declaration();\r\n        }\r\n        if (!close()) {\r\n            return error(`missing '}'`);\r\n        }\r\n        return decls;\r\n    }\r\n    function keyframe() {\r\n        let m;\r\n        const vals = [];\r\n        const pos = position();\r\n        while ((m = match(/^((\\d+\\.\\d+|\\.\\d+|\\d+)%?|[a-z]+)\\s*/))) {\r\n            vals.push(m[1]);\r\n            match(/^,\\s*/);\r\n        }\r\n        if (!vals.length) {\r\n            return;\r\n        }\r\n        return pos({\r\n            type: 'keyframe',\r\n            values: vals,\r\n            declarations: declarations(),\r\n        });\r\n    }\r\n    function atkeyframes() {\r\n        const pos = position();\r\n        let m = match(/^@([-\\w]+)?keyframes\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const vendor = m[1];\r\n        m = match(/^([-\\w]+)\\s*/);\r\n        if (!m) {\r\n            return error('@keyframes missing name');\r\n        }\r\n        const name = m[1];\r\n        if (!open()) {\r\n            return error(`@keyframes missing '{'`);\r\n        }\r\n        let frame;\r\n        let frames = comments();\r\n        while ((frame = keyframe())) {\r\n            frames.push(frame);\r\n            frames = frames.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@keyframes missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'keyframes',\r\n            name,\r\n            vendor,\r\n            keyframes: frames,\r\n        });\r\n    }\r\n    function atsupports() {\r\n        const pos = position();\r\n        const m = match(/^@supports *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const supports = trim(m[1]);\r\n        if (!open()) {\r\n            return error(`@supports missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@supports missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'supports',\r\n            supports,\r\n            rules: style,\r\n        });\r\n    }\r\n    function athost() {\r\n        const pos = position();\r\n        const m = match(/^@host\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        if (!open()) {\r\n            return error(`@host missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@host missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'host',\r\n            rules: style,\r\n        });\r\n    }\r\n    function atmedia() {\r\n        const pos = position();\r\n        const m = match(/^@media *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const media = trim(m[1]);\r\n        if (!open()) {\r\n            return error(`@media missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@media missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'media',\r\n            media,\r\n            rules: style,\r\n        });\r\n    }\r\n    function atcustommedia() {\r\n        const pos = position();\r\n        const m = match(/^@custom-media\\s+(--[^\\s]+)\\s*([^{;]+);/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        return pos({\r\n            type: 'custom-media',\r\n            name: trim(m[1]),\r\n            media: trim(m[2]),\r\n        });\r\n    }\r\n    function atpage() {\r\n        const pos = position();\r\n        const m = match(/^@page */);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const sel = selector() || [];\r\n        if (!open()) {\r\n            return error(`@page missing '{'`);\r\n        }\r\n        let decls = comments();\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            decls.push(decl);\r\n            decls = decls.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@page missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'page',\r\n            selectors: sel,\r\n            declarations: decls,\r\n        });\r\n    }\r\n    function atdocument() {\r\n        const pos = position();\r\n        const m = match(/^@([-\\w]+)?document *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const vendor = trim(m[1]);\r\n        const doc = trim(m[2]);\r\n        if (!open()) {\r\n            return error(`@document missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@document missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'document',\r\n            document: doc,\r\n            vendor,\r\n            rules: style,\r\n        });\r\n    }\r\n    function atfontface() {\r\n        const pos = position();\r\n        const m = match(/^@font-face\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        if (!open()) {\r\n            return error(`@font-face missing '{'`);\r\n        }\r\n        let decls = comments();\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            decls.push(decl);\r\n            decls = decls.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@font-face missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'font-face',\r\n            declarations: decls,\r\n        });\r\n    }\r\n    const atimport = _compileAtrule('import');\r\n    const atcharset = _compileAtrule('charset');\r\n    const atnamespace = _compileAtrule('namespace');\r\n    function _compileAtrule(name) {\r\n        const re = new RegExp('^@' +\r\n            name +\r\n            '\\\\s*((?:' +\r\n            [\r\n                /[^\\\\]\"(?:\\\\\"|[^\"])*\"/.source,\r\n                /[^\\\\]'(?:\\\\'|[^'])*'/.source,\r\n                '[^;]',\r\n            ].join('|') +\r\n            ')+);');\r\n        return () => {\r\n            const pos = position();\r\n            const m = match(re);\r\n            if (!m) {\r\n                return;\r\n            }\r\n            const ret = { type: name };\r\n            ret[name] = m[1].trim();\r\n            return pos(ret);\r\n        };\r\n    }\r\n    function atrule() {\r\n        if (css[0] !== '@') {\r\n            return;\r\n        }\r\n        return (atkeyframes() ||\r\n            atmedia() ||\r\n            atcustommedia() ||\r\n            atsupports() ||\r\n            atimport() ||\r\n            atcharset() ||\r\n            atnamespace() ||\r\n            atdocument() ||\r\n            atpage() ||\r\n            athost() ||\r\n            atfontface());\r\n    }\r\n    function rule() {\r\n        const pos = position();\r\n        const sel = selector();\r\n        if (!sel) {\r\n            return error('selector missing');\r\n        }\r\n        comments();\r\n        return pos({\r\n            type: 'rule',\r\n            selectors: sel,\r\n            declarations: declarations(),\r\n        });\r\n    }\r\n    return addParent(stylesheet());\r\n}\r\nfunction trim(str) {\r\n    return str ? str.replace(/^\\s+|\\s+$/g, '') : '';\r\n}\r\nfunction addParent(obj, parent) {\r\n    const isNode = obj && typeof obj.type === 'string';\r\n    const childParent = isNode ? obj : parent;\r\n    for (const k of Object.keys(obj)) {\r\n        const value = obj[k];\r\n        if (Array.isArray(value)) {\r\n            value.forEach((v) => {\r\n                addParent(v, childParent);\r\n            });\r\n        }\r\n        else if (value && typeof value === 'object') {\r\n            addParent(value, childParent);\r\n        }\r\n    }\r\n    if (isNode) {\r\n        Object.defineProperty(obj, 'parent', {\r\n            configurable: true,\r\n            writable: true,\r\n            enumerable: false,\r\n            value: parent || null,\r\n        });\r\n    }\r\n    return obj;\r\n}\n\nconst tagMap = {\r\n    script: 'noscript',\r\n    altglyph: 'altGlyph',\r\n    altglyphdef: 'altGlyphDef',\r\n    altglyphitem: 'altGlyphItem',\r\n    animatecolor: 'animateColor',\r\n    animatemotion: 'animateMotion',\r\n    animatetransform: 'animateTransform',\r\n    clippath: 'clipPath',\r\n    feblend: 'feBlend',\r\n    fecolormatrix: 'feColorMatrix',\r\n    fecomponenttransfer: 'feComponentTransfer',\r\n    fecomposite: 'feComposite',\r\n    feconvolvematrix: 'feConvolveMatrix',\r\n    fediffuselighting: 'feDiffuseLighting',\r\n    fedisplacementmap: 'feDisplacementMap',\r\n    fedistantlight: 'feDistantLight',\r\n    fedropshadow: 'feDropShadow',\r\n    feflood: 'feFlood',\r\n    fefunca: 'feFuncA',\r\n    fefuncb: 'feFuncB',\r\n    fefuncg: 'feFuncG',\r\n    fefuncr: 'feFuncR',\r\n    fegaussianblur: 'feGaussianBlur',\r\n    feimage: 'feImage',\r\n    femerge: 'feMerge',\r\n    femergenode: 'feMergeNode',\r\n    femorphology: 'feMorphology',\r\n    feoffset: 'feOffset',\r\n    fepointlight: 'fePointLight',\r\n    fespecularlighting: 'feSpecularLighting',\r\n    fespotlight: 'feSpotLight',\r\n    fetile: 'feTile',\r\n    feturbulence: 'feTurbulence',\r\n    foreignobject: 'foreignObject',\r\n    glyphref: 'glyphRef',\r\n    lineargradient: 'linearGradient',\r\n    radialgradient: 'radialGradient',\r\n};\r\nfunction getTagName(n) {\r\n    let tagName = tagMap[n.tagName] ? tagMap[n.tagName] : n.tagName;\r\n    if (tagName === 'link' && n.attributes._cssText) {\r\n        tagName = 'style';\r\n    }\r\n    return tagName;\r\n}\r\nfunction escapeRegExp(str) {\r\n    return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\nconst HOVER_SELECTOR = /([^\\\\]):hover/;\r\nconst HOVER_SELECTOR_GLOBAL = new RegExp(HOVER_SELECTOR.source, 'g');\r\nfunction addHoverClass(cssText, cache) {\r\n    const cachedStyle = cache?.stylesWithHoverClass.get(cssText);\r\n    if (cachedStyle)\r\n        return cachedStyle;\r\n    if (cssText.length >= 1000000) {\r\n        return cssText;\r\n    }\r\n    const ast = parse(cssText, {\r\n        silent: true,\r\n    });\r\n    if (!ast.stylesheet) {\r\n        return cssText;\r\n    }\r\n    const selectors = [];\r\n    ast.stylesheet.rules.forEach((rule) => {\r\n        if ('selectors' in rule) {\r\n            (rule.selectors || []).forEach((selector) => {\r\n                if (HOVER_SELECTOR.test(selector)) {\r\n                    selectors.push(selector);\r\n                }\r\n            });\r\n        }\r\n    });\r\n    if (selectors.length === 0) {\r\n        return cssText;\r\n    }\r\n    const selectorMatcher = new RegExp(selectors\r\n        .filter((selector, index) => selectors.indexOf(selector) === index)\r\n        .sort((a, b) => b.length - a.length)\r\n        .map((selector) => {\r\n        return escapeRegExp(selector);\r\n    })\r\n        .join('|'), 'g');\r\n    const result = cssText.replace(selectorMatcher, (selector) => {\r\n        const newSelector = selector.replace(HOVER_SELECTOR_GLOBAL, '$1.\\\\:hover');\r\n        return `${selector}, ${newSelector}`;\r\n    });\r\n    cache?.stylesWithHoverClass.set(cssText, result);\r\n    return result;\r\n}\r\nfunction createCache() {\r\n    const stylesWithHoverClass = new Map();\r\n    return {\r\n        stylesWithHoverClass,\r\n    };\r\n}\r\nfunction buildNode(n, options) {\r\n    const { doc, hackCss, cache } = options;\r\n    switch (n.type) {\r\n        case NodeType.Document:\r\n            return doc.implementation.createDocument(null, '', null);\r\n        case NodeType.DocumentType:\r\n            return doc.implementation.createDocumentType(n.name || 'html', n.publicId, n.systemId);\r\n        case NodeType.Element: {\r\n            const tagName = getTagName(n);\r\n            let node;\r\n            if (n.isSVG) {\r\n                node = doc.createElementNS('http://www.w3.org/2000/svg', tagName);\r\n            }\r\n            else {\r\n                if (n.isCustom &&\r\n                    doc.defaultView?.customElements &&\r\n                    !doc.defaultView.customElements.get(n.tagName))\r\n                    doc.defaultView.customElements.define(n.tagName, class extends doc.defaultView.HTMLElement {\r\n                    });\r\n                node = doc.createElement(tagName);\r\n            }\r\n            const specialAttributes = {};\r\n            for (const name in n.attributes) {\r\n                if (!Object.prototype.hasOwnProperty.call(n.attributes, name)) {\r\n                    continue;\r\n                }\r\n                let value = n.attributes[name];\r\n                if (tagName === 'option' &&\r\n                    name === 'selected' &&\r\n                    value === false) {\r\n                    continue;\r\n                }\r\n                if (value === null) {\r\n                    continue;\r\n                }\r\n                if (value === true)\r\n                    value = '';\r\n                if (name.startsWith('rr_')) {\r\n                    specialAttributes[name] = value;\r\n                    continue;\r\n                }\r\n                const isTextarea = tagName === 'textarea' && name === 'value';\r\n                const isRemoteOrDynamicCss = tagName === 'style' && name === '_cssText';\r\n                if (isRemoteOrDynamicCss && hackCss && typeof value === 'string') {\r\n                    value = addHoverClass(value, cache);\r\n                }\r\n                if ((isTextarea || isRemoteOrDynamicCss) && typeof value === 'string') {\r\n                    const child = doc.createTextNode(value);\r\n                    for (const c of Array.from(node.childNodes)) {\r\n                        if (c.nodeType === node.TEXT_NODE) {\r\n                            node.removeChild(c);\r\n                        }\r\n                    }\r\n                    node.appendChild(child);\r\n                    continue;\r\n                }\r\n                try {\r\n                    if (n.isSVG && name === 'xlink:href') {\r\n                        node.setAttributeNS('http://www.w3.org/1999/xlink', name, value.toString());\r\n                    }\r\n                    else if (name === 'onload' ||\r\n                        name === 'onclick' ||\r\n                        name.substring(0, 7) === 'onmouse') {\r\n                        node.setAttribute('_' + name, value.toString());\r\n                    }\r\n                    else if (tagName === 'meta' &&\r\n                        n.attributes['http-equiv'] === 'Content-Security-Policy' &&\r\n                        name === 'content') {\r\n                        node.setAttribute('csp-content', value.toString());\r\n                        continue;\r\n                    }\r\n                    else if (tagName === 'link' &&\r\n                        (n.attributes.rel === 'preload' ||\r\n                            n.attributes.rel === 'modulepreload')) {\r\n                    }\r\n                    else if (tagName === 'link' &&\r\n                        n.attributes.rel === 'prefetch' &&\r\n                        typeof n.attributes.href === 'string' &&\r\n                        extractFileExtension(n.attributes.href) === 'js') {\r\n                    }\r\n                    else if (tagName === 'img' &&\r\n                        n.attributes.srcset &&\r\n                        n.attributes.rr_dataURL) {\r\n                        node.setAttribute('rrweb-original-srcset', n.attributes.srcset);\r\n                    }\r\n                    else {\r\n                        node.setAttribute(name, value.toString());\r\n                    }\r\n                }\r\n                catch (error) {\r\n                }\r\n            }\r\n            for (const name in specialAttributes) {\r\n                const value = specialAttributes[name];\r\n                if (tagName === 'canvas' && name === 'rr_dataURL') {\r\n                    const image = doc.createElement('img');\r\n                    image.onload = () => {\r\n                        const ctx = node.getContext('2d');\r\n                        if (ctx) {\r\n                            ctx.drawImage(image, 0, 0, image.width, image.height);\r\n                        }\r\n                    };\r\n                    image.src = value.toString();\r\n                    if (node.RRNodeType)\r\n                        node.rr_dataURL = value.toString();\r\n                }\r\n                else if (tagName === 'img' && name === 'rr_dataURL') {\r\n                    const image = node;\r\n                    if (!image.currentSrc.startsWith('data:')) {\r\n                        image.setAttribute('rrweb-original-src', n.attributes.src);\r\n                        image.src = value.toString();\r\n                    }\r\n                }\r\n                if (name === 'rr_width') {\r\n                    node.style.setProperty('width', value.toString());\r\n                }\r\n                else if (name === 'rr_height') {\r\n                    node.style.setProperty('height', value.toString());\r\n                }\r\n                else if (name === 'rr_mediaCurrentTime' &&\r\n                    typeof value === 'number') {\r\n                    node.currentTime = value;\r\n                }\r\n                else if (name === 'rr_mediaState') {\r\n                    switch (value) {\r\n                        case 'played':\r\n                            node\r\n                                .play()\r\n                                .catch((e) => console.warn('media playback error', e));\r\n                            break;\r\n                        case 'paused':\r\n                            node.pause();\r\n                            break;\r\n                    }\r\n                }\r\n            }\r\n            if (n.isShadowHost) {\r\n                if (!node.shadowRoot) {\r\n                    node.attachShadow({ mode: 'open' });\r\n                }\r\n                else {\r\n                    while (node.shadowRoot.firstChild) {\r\n                        node.shadowRoot.removeChild(node.shadowRoot.firstChild);\r\n                    }\r\n                }\r\n            }\r\n            return node;\r\n        }\r\n        case NodeType.Text:\r\n            return doc.createTextNode(n.isStyle && hackCss\r\n                ? addHoverClass(n.textContent, cache)\r\n                : n.textContent);\r\n        case NodeType.CDATA:\r\n            return doc.createCDATASection(n.textContent);\r\n        case NodeType.Comment:\r\n            return doc.createComment(n.textContent);\r\n        default:\r\n            return null;\r\n    }\r\n}\r\nfunction buildNodeWithSN(n, options) {\r\n    const { doc, mirror, skipChild = false, hackCss = true, afterAppend, cache, } = options;\r\n    if (mirror.has(n.id)) {\r\n        const nodeInMirror = mirror.getNode(n.id);\r\n        const meta = mirror.getMeta(nodeInMirror);\r\n        if (isNodeMetaEqual(meta, n))\r\n            return mirror.getNode(n.id);\r\n    }\r\n    let node = buildNode(n, { doc, hackCss, cache });\r\n    if (!node) {\r\n        return null;\r\n    }\r\n    if (n.rootId && mirror.getNode(n.rootId) !== doc) {\r\n        mirror.replace(n.rootId, doc);\r\n    }\r\n    if (n.type === NodeType.Document) {\r\n        doc.close();\r\n        doc.open();\r\n        if (n.compatMode === 'BackCompat' &&\r\n            n.childNodes &&\r\n            n.childNodes[0].type !== NodeType.DocumentType) {\r\n            if (n.childNodes[0].type === NodeType.Element &&\r\n                'xmlns' in n.childNodes[0].attributes &&\r\n                n.childNodes[0].attributes.xmlns === 'http://www.w3.org/1999/xhtml') {\r\n                doc.write('<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\">');\r\n            }\r\n            else {\r\n                doc.write('<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\">');\r\n            }\r\n        }\r\n        node = doc;\r\n    }\r\n    mirror.add(node, n);\r\n    if ((n.type === NodeType.Document || n.type === NodeType.Element) &&\r\n        !skipChild) {\r\n        for (const childN of n.childNodes) {\r\n            const childNode = buildNodeWithSN(childN, {\r\n                doc,\r\n                mirror,\r\n                skipChild: false,\r\n                hackCss,\r\n                afterAppend,\r\n                cache,\r\n            });\r\n            if (!childNode) {\r\n                console.warn('Failed to rebuild', childN);\r\n                continue;\r\n            }\r\n            if (childN.isShadow && isElement(node) && node.shadowRoot) {\r\n                node.shadowRoot.appendChild(childNode);\r\n            }\r\n            else if (n.type === NodeType.Document &&\r\n                childN.type == NodeType.Element) {\r\n                const htmlElement = childNode;\r\n                let body = null;\r\n                htmlElement.childNodes.forEach((child) => {\r\n                    if (child.nodeName === 'BODY')\r\n                        body = child;\r\n                });\r\n                if (body) {\r\n                    htmlElement.removeChild(body);\r\n                    node.appendChild(childNode);\r\n                    htmlElement.appendChild(body);\r\n                }\r\n                else {\r\n                    node.appendChild(childNode);\r\n                }\r\n            }\r\n            else {\r\n                node.appendChild(childNode);\r\n            }\r\n            if (afterAppend) {\r\n                afterAppend(childNode, childN.id);\r\n            }\r\n        }\r\n    }\r\n    return node;\r\n}\r\nfunction visit(mirror, onVisit) {\r\n    function walk(node) {\r\n        onVisit(node);\r\n    }\r\n    for (const id of mirror.getIds()) {\r\n        if (mirror.has(id)) {\r\n            walk(mirror.getNode(id));\r\n        }\r\n    }\r\n}\r\nfunction handleScroll(node, mirror) {\r\n    const n = mirror.getMeta(node);\r\n    if (n?.type !== NodeType.Element) {\r\n        return;\r\n    }\r\n    const el = node;\r\n    for (const name in n.attributes) {\r\n        if (!(Object.prototype.hasOwnProperty.call(n.attributes, name) &&\r\n            name.startsWith('rr_'))) {\r\n            continue;\r\n        }\r\n        const value = n.attributes[name];\r\n        if (name === 'rr_scrollLeft') {\r\n            el.scrollLeft = value;\r\n        }\r\n        if (name === 'rr_scrollTop') {\r\n            el.scrollTop = value;\r\n        }\r\n    }\r\n}\r\nfunction rebuild(n, options) {\r\n    const { doc, onVisit, hackCss = true, afterAppend, cache, mirror = new Mirror(), } = options;\r\n    const node = buildNodeWithSN(n, {\r\n        doc,\r\n        mirror,\r\n        skipChild: false,\r\n        hackCss,\r\n        afterAppend,\r\n        cache,\r\n    });\r\n    visit(mirror, (visitedNode) => {\r\n        if (onVisit) {\r\n            onVisit(visitedNode);\r\n        }\r\n        handleScroll(visitedNode, mirror);\r\n    });\r\n    return node;\r\n}\n\nexport { IGNORED_NODE, Mirror, NodeType, addHoverClass, buildNodeWithSN, classMatchesRegex, cleanupSnapshot, clearTimeout, createCache, createMatchPredicate, createMirror, distanceToMatch, escapeImportStatement, extractFileExtension, fixAllCssProperty, fixSafariColons, genId, getIframeContentDocument, getInputType, getInputValue, ignoreAttribute, is2DCanvasBlank, isCSSImportRule, isCSSStyleRule, isElement, isNativeShadowDom, isNodeMetaEqual, isShadowRoot, maskInputValue, needMaskingText, onRequestAnimationFrame, rebuild, serializeNodeWithId, setTimeout, shouldMaskInput, snapshot, stringifyRule, stringifyStylesheet, toLowerCase, toUpperCase, transformAttribute, visitSnapshot };\n", "// Note that these are the serialized attributes and not attributes directly on\n// the DOM Node. Attributes we are interested in:\nconst ATTRIBUTES_TO_RECORD = new Set([\n  'id',\n  'class',\n  'aria-label',\n  'role',\n  'name',\n  'alt',\n  'title',\n  'data-test-id',\n  'data-testid',\n  'disabled',\n  'aria-disabled',\n  'data-sentry-component',\n]);\n\n/**\n * Inclusion list of attributes that we want to record from the DOM element\n */\nexport function getAttributesToRecord(attributes: Record<string, unknown>): Record<string, unknown> {\n  const obj: Record<string, unknown> = {};\n  if (!attributes['data-sentry-component'] && attributes['data-sentry-element']) {\n    attributes['data-sentry-component'] = attributes['data-sentry-element'];\n  }\n  for (const key in attributes) {\n    if (ATTRIBUTES_TO_RECORD.has(key)) {\n      let normalizedKey = key;\n\n      if (key === 'data-testid' || key === 'data-test-id') {\n        normalizedKey = 'testId';\n      }\n\n      obj[normalizedKey] = attributes[key];\n    }\n  }\n\n  return obj;\n}\n", "import { record } from '@sentry-internal/rrweb';\nimport type { serializedElementNodeWithId, serializedNodeWithId } from '@sentry-internal/rrweb-snapshot';\nimport { NodeType } from '@sentry-internal/rrweb-snapshot';\nimport { htmlTreeAsString } from '@sentry/core';\nimport type { Breadcrumb, HandlerDataDom } from '@sentry/core';\n\nimport type { ReplayContainer } from '../types';\nimport { createBreadcrumb } from '../util/createBreadcrumb';\nimport { handleClick } from './handleClick';\nimport { addBreadcrumbEvent } from './util/addBreadcrumbEvent';\nimport { getClickTargetNode, getTargetNode } from './util/domUtils';\nimport { getAttributesToRecord } from './util/getAttributesToRecord';\n\nexport const handleDomListener: (replay: ReplayContainer) => (handlerData: HandlerDataDom) => void = (\n  replay: ReplayContainer,\n) => {\n  return (handlerData: HandlerDataDom): void => {\n    if (!replay.isEnabled()) {\n      return;\n    }\n\n    const result = handleDom(handlerData);\n\n    if (!result) {\n      return;\n    }\n\n    const isClick = handlerData.name === 'click';\n    const event = isClick ? (handlerData.event as PointerEvent) : undefined;\n    // Ignore clicks if ctrl/alt/meta/shift keys are held down as they alter behavior of clicks (e.g. open in new tab)\n    if (\n      isClick &&\n      replay.clickDetector &&\n      event &&\n      event.target &&\n      !event.altKey &&\n      !event.metaKey &&\n      !event.ctrlKey &&\n      !event.shiftKey\n    ) {\n      handleClick(\n        replay.clickDetector,\n        result as Breadcrumb & { timestamp: number; data: { nodeId: number } },\n        getClickTargetNode(handlerData.event as Event) as HTMLElement,\n      );\n    }\n\n    addBreadcrumbEvent(replay, result);\n  };\n};\n\n/** Get the base DOM breadcrumb. */\nexport function getBaseDomBreadcrumb(target: Node | null, message: string): Breadcrumb {\n  const nodeId = record.mirror.getId(target);\n  const node = nodeId && record.mirror.getNode(nodeId);\n  const meta = node && record.mirror.getMeta(node);\n  const element = meta && isElement(meta) ? meta : null;\n\n  return {\n    message,\n    data: element\n      ? {\n          nodeId,\n          node: {\n            id: nodeId,\n            tagName: element.tagName,\n            textContent: Array.from(element.childNodes)\n              .map((node: serializedNodeWithId) => node.type === NodeType.Text && node.textContent)\n              .filter(Boolean) // filter out empty values\n              .map(text => (text as string).trim())\n              .join(''),\n            attributes: getAttributesToRecord(element.attributes),\n          },\n        }\n      : {},\n  };\n}\n\n/**\n * An event handler to react to DOM events.\n * Exported for tests.\n */\nexport function handleDom(handlerData: HandlerDataDom): Breadcrumb | null {\n  const { target, message } = getDomTarget(handlerData);\n\n  return createBreadcrumb({\n    category: `ui.${handlerData.name}`,\n    ...getBaseDomBreadcrumb(target, message),\n  });\n}\n\nfunction getDomTarget(handlerData: HandlerDataDom): { target: Node | null; message: string } {\n  const isClick = handlerData.name === 'click';\n\n  let message: string | undefined;\n  let target: Node | null = null;\n\n  // Accessing event.target can throw (see getsentry/raven-js#838, #768)\n  try {\n    target = isClick ? getClickTargetNode(handlerData.event as Event) : getTargetNode(handlerData.event as Event);\n    message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';\n  } catch (e) {\n    message = '<unknown>';\n  }\n\n  return { target, message };\n}\n\nfunction isElement(node: serializedNodeWithId): node is serializedElementNodeWithId {\n  return node.type === NodeType.Element;\n}\n", "import { htmlTreeAsString } from '@sentry/core';\nimport type { Breadcrumb } from '@sentry/core';\n\nimport type { ReplayContainer } from '../types';\nimport { createBreadcrumb } from '../util/createBreadcrumb';\nimport { getBaseDomBreadcrumb } from './handleDom';\nimport { addBreadcrumbEvent } from './util/addBreadcrumbEvent';\n\n/** Handle keyboard events & create breadcrumbs. */\nexport function handleKeyboardEvent(replay: ReplayContainer, event: KeyboardEvent): void {\n  if (!replay.isEnabled()) {\n    return;\n  }\n\n  // Update user activity, but do not restart recording as it can create\n  // noisy/low-value replays (e.g. user comes back from idle, hits alt-tab, new\n  // session with a single \"keydown\" breadcrumb is created)\n  replay.updateUserActivity();\n\n  const breadcrumb = getKeyboardBreadcrumb(event);\n\n  if (!breadcrumb) {\n    return;\n  }\n\n  addBreadcrumbEvent(replay, breadcrumb);\n}\n\n/** exported only for tests */\nexport function getKeyboardBreadcrumb(event: KeyboardEvent): Breadcrumb | null {\n  const { metaKey, shiftKey, ctrlKey, altKey, key, target } = event;\n\n  // never capture for input fields\n  if (!target || isInputElement(target as HTMLElement) || !key) {\n    return null;\n  }\n\n  // Note: We do not consider shift here, as that means \"uppercase\"\n  const hasModifierKey = metaKey || ctrlKey || altKey;\n  const isCharacterKey = key.length === 1; // other keys like Escape, Tab, etc have a longer length\n\n  // Do not capture breadcrumb if only a word key is pressed\n  // This could leak e.g. user input\n  if (!hasModifierKey && isCharacterKey) {\n    return null;\n  }\n\n  const message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';\n  const baseBreadcrumb = getBaseDomBreadcrumb(target as Node, message);\n\n  return createBreadcrumb({\n    category: 'ui.keyDown',\n    message,\n    data: {\n      ...baseBreadcrumb.data,\n      metaKey,\n      shiftKey,\n      ctrlKey,\n      altKey,\n      key,\n    },\n  });\n}\n\nfunction isInputElement(target: HTMLElement): boolean {\n  return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;\n}\n", "import { record } from '@sentry-internal/rrweb';\nimport { browserPerformanceTimeOrigin } from '@sentry/core';\n\nimport { WINDOW } from '../constants';\nimport type {\n  AllPerformanceEntry,\n  AllPerformanceEntryData,\n  ExperimentalPerformanceResourceTiming,\n  NavigationData,\n  PaintData,\n  ReplayContainer,\n  ReplayPerformanceEntry,\n  ResourceData,\n  WebVitalData,\n} from '../types';\n\n// Map entryType -> function to normalize data for event\nconst ENTRY_TYPES: Record<\n  string,\n  (entry: AllPerformanceEntry) => null | ReplayPerformanceEntry<AllPerformanceEntryData>\n> = {\n  // @ts-expect-error TODO: entry type does not fit the create* functions entry type\n  resource: createResourceEntry,\n  paint: createPaintEntry,\n  // @ts-expect-error TODO: entry type does not fit the create* functions entry type\n  navigation: createNavigationEntry,\n};\n\nexport interface Metric {\n  /**\n   * The current value of the metric.\n   */\n  value: number;\n\n  /**\n   * The rating as to whether the metric value is within the \"good\",\n   * \"needs improvement\", or \"poor\" thresholds of the metric.\n   */\n  rating: 'good' | 'needs-improvement' | 'poor';\n\n  /**\n   * Any performance entries relevant to the metric value calculation.\n   * The array may also be empty if the metric value was not based on any\n   * entries (e.g. a CLS value of 0 given no layout shifts).\n   */\n  entries: PerformanceEntry[] | LayoutShift[];\n}\n\ninterface LayoutShift extends PerformanceEntry {\n  value: number;\n  sources: LayoutShiftAttribution[];\n  hadRecentInput: boolean;\n}\n\ninterface LayoutShiftAttribution {\n  node?: Node;\n  previousRect: DOMRectReadOnly;\n  currentRect: DOMRectReadOnly;\n}\n\n/**\n * Handler creater for web vitals\n */\nexport function webVitalHandler(\n  getter: (metric: Metric) => ReplayPerformanceEntry<AllPerformanceEntryData>,\n  replay: ReplayContainer,\n): (data: { metric: Metric }) => void {\n  return ({ metric }) => void replay.replayPerformanceEntries.push(getter(metric));\n}\n\n/**\n * Create replay performance entries from the browser performance entries.\n */\nexport function createPerformanceEntries(\n  entries: AllPerformanceEntry[],\n): ReplayPerformanceEntry<AllPerformanceEntryData>[] {\n  return entries.map(createPerformanceEntry).filter(Boolean) as ReplayPerformanceEntry<AllPerformanceEntryData>[];\n}\n\nfunction createPerformanceEntry(entry: AllPerformanceEntry): ReplayPerformanceEntry<AllPerformanceEntryData> | null {\n  const entryType = ENTRY_TYPES[entry.entryType];\n  if (!entryType) {\n    return null;\n  }\n\n  return entryType(entry);\n}\n\nfunction getAbsoluteTime(time: number): number {\n  // browserPerformanceTimeOrigin can be undefined if `performance` or\n  // `performance.now` doesn't exist, but this is already checked by this integration\n  return ((browserPerformanceTimeOrigin || WINDOW.performance.timeOrigin) + time) / 1000;\n}\n\nfunction createPaintEntry(entry: PerformancePaintTiming): ReplayPerformanceEntry<PaintData> {\n  const { duration, entryType, name, startTime } = entry;\n\n  const start = getAbsoluteTime(startTime);\n  return {\n    type: entryType,\n    name,\n    start,\n    end: start + duration,\n    data: undefined,\n  };\n}\n\nfunction createNavigationEntry(entry: PerformanceNavigationTiming): ReplayPerformanceEntry<NavigationData> | null {\n  const {\n    entryType,\n    name,\n    decodedBodySize,\n    duration,\n    domComplete,\n    encodedBodySize,\n    domContentLoadedEventStart,\n    domContentLoadedEventEnd,\n    domInteractive,\n    loadEventStart,\n    loadEventEnd,\n    redirectCount,\n    startTime,\n    transferSize,\n    type,\n  } = entry;\n\n  // Ignore entries with no duration, they do not seem to be useful and cause dupes\n  if (duration === 0) {\n    return null;\n  }\n\n  return {\n    type: `${entryType}.${type}`,\n    start: getAbsoluteTime(startTime),\n    end: getAbsoluteTime(domComplete),\n    name,\n    data: {\n      size: transferSize,\n      decodedBodySize,\n      encodedBodySize,\n      duration,\n      domInteractive,\n      domContentLoadedEventStart,\n      domContentLoadedEventEnd,\n      loadEventStart,\n      loadEventEnd,\n      domComplete,\n      redirectCount,\n    },\n  };\n}\n\nfunction createResourceEntry(\n  entry: ExperimentalPerformanceResourceTiming,\n): ReplayPerformanceEntry<ResourceData> | null {\n  const {\n    entryType,\n    initiatorType,\n    name,\n    responseEnd,\n    startTime,\n    decodedBodySize,\n    encodedBodySize,\n    responseStatus,\n    transferSize,\n  } = entry;\n\n  // Core SDK handles these\n  if (['fetch', 'xmlhttprequest'].includes(initiatorType)) {\n    return null;\n  }\n\n  return {\n    type: `${entryType}.${initiatorType}`,\n    start: getAbsoluteTime(startTime),\n    end: getAbsoluteTime(responseEnd),\n    name,\n    data: {\n      size: transferSize,\n      statusCode: responseStatus,\n      decodedBodySize,\n      encodedBodySize,\n    },\n  };\n}\n\n/**\n * Add a LCP event to the replay based on a LCP metric.\n */\nexport function getLargestContentfulPaint(metric: Metric): ReplayPerformanceEntry<WebVitalData> {\n  const lastEntry = metric.entries[metric.entries.length - 1] as (PerformanceEntry & { element?: Node }) | undefined;\n  const node = lastEntry && lastEntry.element ? [lastEntry.element] : undefined;\n  return getWebVital(metric, 'largest-contentful-paint', node);\n}\n\nfunction isLayoutShift(entry: PerformanceEntry): entry is LayoutShift {\n  return (entry as LayoutShift).sources !== undefined;\n}\n\n/**\n * Add a CLS event to the replay based on a CLS metric.\n */\nexport function getCumulativeLayoutShift(metric: Metric): ReplayPerformanceEntry<WebVitalData> {\n  const layoutShifts: WebVitalData['attributions'] = [];\n  const nodes: Node[] = [];\n  for (const entry of metric.entries) {\n    if (isLayoutShift(entry)) {\n      const nodeIds = [];\n      for (const source of entry.sources) {\n        if (source.node) {\n          nodes.push(source.node);\n          const nodeId = record.mirror.getId(source.node);\n          if (nodeId) {\n            nodeIds.push(nodeId);\n          }\n        }\n      }\n      layoutShifts.push({ value: entry.value, nodeIds: nodeIds.length ? nodeIds : undefined });\n    }\n  }\n\n  return getWebVital(metric, 'cumulative-layout-shift', nodes, layoutShifts);\n}\n\n/**\n * Add a FID event to the replay based on a FID metric.\n */\nexport function getFirstInputDelay(metric: Metric): ReplayPerformanceEntry<WebVitalData> {\n  const lastEntry = metric.entries[metric.entries.length - 1] as (PerformanceEntry & { target?: Node }) | undefined;\n  const node = lastEntry && lastEntry.target ? [lastEntry.target] : undefined;\n  return getWebVital(metric, 'first-input-delay', node);\n}\n\n/**\n * Add an INP event to the replay based on an INP metric.\n */\nexport function getInteractionToNextPaint(metric: Metric): ReplayPerformanceEntry<WebVitalData> {\n  const lastEntry = metric.entries[metric.entries.length - 1] as (PerformanceEntry & { target?: Node }) | undefined;\n  const node = lastEntry && lastEntry.target ? [lastEntry.target] : undefined;\n  return getWebVital(metric, 'interaction-to-next-paint', node);\n}\n\n/**\n * Add an web vital event to the replay based on the web vital metric.\n */\nfunction getWebVital(\n  metric: Metric,\n  name: string,\n  nodes: Node[] | undefined,\n  attributions?: WebVitalData['attributions'],\n): ReplayPerformanceEntry<WebVitalData> {\n  const value = metric.value;\n  const rating = metric.rating;\n\n  const end = getAbsoluteTime(value);\n\n  return {\n    type: 'web-vital',\n    name,\n    start: end,\n    end,\n    data: {\n      value,\n      size: value,\n      rating,\n      nodeIds: nodes ? nodes.map(node => record.mirror.getId(node)) : undefined,\n      attributions,\n    },\n  };\n}\n", "import {\n  addClsInstrumentationHandler,\n  addFidInstrumentationHandler,\n  addInpInstrumentationHandler,\n  addLcpInstrumentationHandler,\n  addPerformanceInstrumentationHandler,\n} from '@sentry-internal/browser-utils';\nimport type { ReplayContainer } from '../types';\nimport {\n  getCumulativeLayoutShift,\n  getFirstInputDelay,\n  getInteractionToNextPaint,\n  getLargestContentfulPaint,\n  webVitalHandler,\n} from '../util/createPerformanceEntries';\n\n/**\n * Sets up a PerformanceObserver to listen to all performance entry types.\n * Returns a callback to stop observing.\n */\nexport function setupPerformanceObserver(replay: ReplayContainer): () => void {\n  function addPerformanceEntry(entry: PerformanceEntry): void {\n    // It is possible for entries to come up multiple times\n    if (!replay.performanceEntries.includes(entry)) {\n      replay.performanceEntries.push(entry);\n    }\n  }\n\n  function onEntries({ entries }: { entries: PerformanceEntry[] }): void {\n    entries.forEach(addPerformanceEntry);\n  }\n\n  const clearCallbacks: (() => void)[] = [];\n\n  (['navigation', 'paint', 'resource'] as const).forEach(type => {\n    clearCallbacks.push(addPerformanceInstrumentationHandler(type, onEntries));\n  });\n\n  clearCallbacks.push(\n    addLcpInstrumentationHandler(webVitalHandler(getLargestContentfulPaint, replay)),\n    addClsInstrumentationHandler(webVitalHandler(getCumulativeLayoutShift, replay)),\n    addFidInstrumentationHandler(webVitalHandler(getFirstInputDelay, replay)),\n    addInpInstrumentationHandler(webVitalHandler(getInteractionToNextPaint, replay)),\n  );\n\n  // A callback to cleanup all handlers\n  return () => {\n    clearCallbacks.forEach(clearCallback => clearCallback());\n  };\n}\n", "declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n", "export default `var t=Uint8Array,n=Uint16Array,r=Int32Array,e=new t([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),i=new t([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),a=new t([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),s=function(t,e){for(var i=new n(31),a=0;a<31;++a)i[a]=e+=1<<t[a-1];var s=new r(i[30]);for(a=1;a<30;++a)for(var o=i[a];o<i[a+1];++o)s[o]=o-i[a]<<5|a;return{b:i,r:s}},o=s(e,2),f=o.b,h=o.r;f[28]=258,h[258]=28;for(var l=s(i,0).r,u=new n(32768),c=0;c<32768;++c){var v=(43690&c)>>1|(21845&c)<<1;v=(61680&(v=(52428&v)>>2|(13107&v)<<2))>>4|(3855&v)<<4,u[c]=((65280&v)>>8|(255&v)<<8)>>1}var d=function(t,r,e){for(var i=t.length,a=0,s=new n(r);a<i;++a)t[a]&&++s[t[a]-1];var o,f=new n(r);for(a=1;a<r;++a)f[a]=f[a-1]+s[a-1]<<1;if(e){o=new n(1<<r);var h=15-r;for(a=0;a<i;++a)if(t[a])for(var l=a<<4|t[a],c=r-t[a],v=f[t[a]-1]++<<c,d=v|(1<<c)-1;v<=d;++v)o[u[v]>>h]=l}else for(o=new n(i),a=0;a<i;++a)t[a]&&(o[a]=u[f[t[a]-1]++]>>15-t[a]);return o},g=new t(288);for(c=0;c<144;++c)g[c]=8;for(c=144;c<256;++c)g[c]=9;for(c=256;c<280;++c)g[c]=7;for(c=280;c<288;++c)g[c]=8;var w=new t(32);for(c=0;c<32;++c)w[c]=5;var p=d(g,9,0),y=d(w,5,0),m=function(t){return(t+7)/8|0},b=function(n,r,e){return(null==e||e>n.length)&&(e=n.length),new t(n.subarray(r,e))},M=[\"unexpected EOF\",\"invalid block type\",\"invalid length/literal\",\"invalid distance\",\"stream finished\",\"no stream handler\",,\"no callback\",\"invalid UTF-8 data\",\"extra field too long\",\"date not in range 1980-2099\",\"filename too long\",\"stream finishing\",\"invalid zip data\"],E=function(t,n,r){var e=new Error(n||M[t]);if(e.code=t,Error.captureStackTrace&&Error.captureStackTrace(e,E),!r)throw e;return e},z=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8},_=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8,t[e+2]|=r>>16},x=function(r,e){for(var i=[],a=0;a<r.length;++a)r[a]&&i.push({s:a,f:r[a]});var s=i.length,o=i.slice();if(!s)return{t:F,l:0};if(1==s){var f=new t(i[0].s+1);return f[i[0].s]=1,{t:f,l:1}}i.sort((function(t,n){return t.f-n.f})),i.push({s:-1,f:25001});var h=i[0],l=i[1],u=0,c=1,v=2;for(i[0]={s:-1,f:h.f+l.f,l:h,r:l};c!=s-1;)h=i[i[u].f<i[v].f?u++:v++],l=i[u!=c&&i[u].f<i[v].f?u++:v++],i[c++]={s:-1,f:h.f+l.f,l:h,r:l};var d=o[0].s;for(a=1;a<s;++a)o[a].s>d&&(d=o[a].s);var g=new n(d+1),w=A(i[c-1],g,0);if(w>e){a=0;var p=0,y=w-e,m=1<<y;for(o.sort((function(t,n){return g[n.s]-g[t.s]||t.f-n.f}));a<s;++a){var b=o[a].s;if(!(g[b]>e))break;p+=m-(1<<w-g[b]),g[b]=e}for(p>>=y;p>0;){var M=o[a].s;g[M]<e?p-=1<<e-g[M]++-1:++a}for(;a>=0&&p;--a){var E=o[a].s;g[E]==e&&(--g[E],++p)}w=e}return{t:new t(g),l:w}},A=function(t,n,r){return-1==t.s?Math.max(A(t.l,n,r+1),A(t.r,n,r+1)):n[t.s]=r},D=function(t){for(var r=t.length;r&&!t[--r];);for(var e=new n(++r),i=0,a=t[0],s=1,o=function(t){e[i++]=t},f=1;f<=r;++f)if(t[f]==a&&f!=r)++s;else{if(!a&&s>2){for(;s>138;s-=138)o(32754);s>2&&(o(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(o(a),--s;s>6;s-=6)o(8304);s>2&&(o(s-3<<5|8208),s=0)}for(;s--;)o(a);s=1,a=t[f]}return{c:e.subarray(0,i),n:r}},T=function(t,n){for(var r=0,e=0;e<n.length;++e)r+=t[e]*n[e];return r},k=function(t,n,r){var e=r.length,i=m(n+2);t[i]=255&e,t[i+1]=e>>8,t[i+2]=255^t[i],t[i+3]=255^t[i+1];for(var a=0;a<e;++a)t[i+a+4]=r[a];return 8*(i+4+e)},U=function(t,r,s,o,f,h,l,u,c,v,m){z(r,m++,s),++f[256];for(var b=x(f,15),M=b.t,E=b.l,A=x(h,15),U=A.t,C=A.l,F=D(M),I=F.c,S=F.n,L=D(U),O=L.c,j=L.n,q=new n(19),B=0;B<I.length;++B)++q[31&I[B]];for(B=0;B<O.length;++B)++q[31&O[B]];for(var G=x(q,7),H=G.t,J=G.l,K=19;K>4&&!H[a[K-1]];--K);var N,P,Q,R,V=v+5<<3,W=T(f,g)+T(h,w)+l,X=T(f,M)+T(h,U)+l+14+3*K+T(q,H)+2*q[16]+3*q[17]+7*q[18];if(c>=0&&V<=W&&V<=X)return k(r,m,t.subarray(c,c+v));if(z(r,m,1+(X<W)),m+=2,X<W){N=d(M,E,0),P=M,Q=d(U,C,0),R=U;var Y=d(H,J,0);z(r,m,S-257),z(r,m+5,j-1),z(r,m+10,K-4),m+=14;for(B=0;B<K;++B)z(r,m+3*B,H[a[B]]);m+=3*K;for(var Z=[I,O],$=0;$<2;++$){var tt=Z[$];for(B=0;B<tt.length;++B){var nt=31&tt[B];z(r,m,Y[nt]),m+=H[nt],nt>15&&(z(r,m,tt[B]>>5&127),m+=tt[B]>>12)}}}else N=p,P=g,Q=y,R=w;for(B=0;B<u;++B){var rt=o[B];if(rt>255){_(r,m,N[(nt=rt>>18&31)+257]),m+=P[nt+257],nt>7&&(z(r,m,rt>>23&31),m+=e[nt]);var et=31&rt;_(r,m,Q[et]),m+=R[et],et>3&&(_(r,m,rt>>5&8191),m+=i[et])}else _(r,m,N[rt]),m+=P[rt]}return _(r,m,N[256]),m+P[256]},C=new r([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),F=new t(0),I=function(){for(var t=new Int32Array(256),n=0;n<256;++n){for(var r=n,e=9;--e;)r=(1&r&&-306674912)^r>>>1;t[n]=r}return t}(),S=function(){var t=-1;return{p:function(n){for(var r=t,e=0;e<n.length;++e)r=I[255&r^n[e]]^r>>>8;t=r},d:function(){return~t}}},L=function(){var t=1,n=0;return{p:function(r){for(var e=t,i=n,a=0|r.length,s=0;s!=a;){for(var o=Math.min(s+2655,a);s<o;++s)i+=e+=r[s];e=(65535&e)+15*(e>>16),i=(65535&i)+15*(i>>16)}t=e,n=i},d:function(){return(255&(t%=65521))<<24|(65280&t)<<8|(255&(n%=65521))<<8|n>>8}}},O=function(a,s,o,f,u){if(!u&&(u={l:1},s.dictionary)){var c=s.dictionary.subarray(-32768),v=new t(c.length+a.length);v.set(c),v.set(a,c.length),a=v,u.w=c.length}return function(a,s,o,f,u,c){var v=c.z||a.length,d=new t(f+v+5*(1+Math.ceil(v/7e3))+u),g=d.subarray(f,d.length-u),w=c.l,p=7&(c.r||0);if(s){p&&(g[0]=c.r>>3);for(var y=C[s-1],M=y>>13,E=8191&y,z=(1<<o)-1,_=c.p||new n(32768),x=c.h||new n(z+1),A=Math.ceil(o/3),D=2*A,T=function(t){return(a[t]^a[t+1]<<A^a[t+2]<<D)&z},F=new r(25e3),I=new n(288),S=new n(32),L=0,O=0,j=c.i||0,q=0,B=c.w||0,G=0;j+2<v;++j){var H=T(j),J=32767&j,K=x[H];if(_[J]=K,x[H]=J,B<=j){var N=v-j;if((L>7e3||q>24576)&&(N>423||!w)){p=U(a,g,0,F,I,S,O,q,G,j-G,p),q=L=O=0,G=j;for(var P=0;P<286;++P)I[P]=0;for(P=0;P<30;++P)S[P]=0}var Q=2,R=0,V=E,W=J-K&32767;if(N>2&&H==T(j-W))for(var X=Math.min(M,N)-1,Y=Math.min(32767,j),Z=Math.min(258,N);W<=Y&&--V&&J!=K;){if(a[j+Q]==a[j+Q-W]){for(var $=0;$<Z&&a[j+$]==a[j+$-W];++$);if($>Q){if(Q=$,R=W,$>X)break;var tt=Math.min(W,$-2),nt=0;for(P=0;P<tt;++P){var rt=j-W+P&32767,et=rt-_[rt]&32767;et>nt&&(nt=et,K=rt)}}}W+=(J=K)-(K=_[J])&32767}if(R){F[q++]=268435456|h[Q]<<18|l[R];var it=31&h[Q],at=31&l[R];O+=e[it]+i[at],++I[257+it],++S[at],B=j+Q,++L}else F[q++]=a[j],++I[a[j]]}}for(j=Math.max(j,B);j<v;++j)F[q++]=a[j],++I[a[j]];p=U(a,g,w,F,I,S,O,q,G,j-G,p),w||(c.r=7&p|g[p/8|0]<<3,p-=7,c.h=x,c.p=_,c.i=j,c.w=B)}else{for(j=c.w||0;j<v+w;j+=65535){var st=j+65535;st>=v&&(g[p/8|0]=w,st=v),p=k(g,p+1,a.subarray(j,st))}c.i=v}return b(d,0,f+m(p)+u)}(a,null==s.level?6:s.level,null==s.mem?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(a.length)))):12+s.mem,o,f,u)},j=function(t,n,r){for(;r;++n)t[n]=r,r>>>=8},q=function(t,n){var r=n.filename;if(t[0]=31,t[1]=139,t[2]=8,t[8]=n.level<2?4:9==n.level?2:0,t[9]=3,0!=n.mtime&&j(t,4,Math.floor(new Date(n.mtime||Date.now())/1e3)),r){t[3]=8;for(var e=0;e<=r.length;++e)t[e+10]=r.charCodeAt(e)}},B=function(t){return 10+(t.filename?t.filename.length+1:0)},G=function(){function n(n,r){if(\"function\"==typeof n&&(r=n,n={}),this.ondata=r,this.o=n||{},this.s={l:0,i:32768,w:32768,z:32768},this.b=new t(98304),this.o.dictionary){var e=this.o.dictionary.subarray(-32768);this.b.set(e,32768-e.length),this.s.i=32768-e.length}}return n.prototype.p=function(t,n){this.ondata(O(t,this.o,0,0,this.s),n)},n.prototype.push=function(n,r){this.ondata||E(5),this.s.l&&E(4);var e=n.length+this.s.z;if(e>this.b.length){if(e>2*this.b.length-32768){var i=new t(-32768&e);i.set(this.b.subarray(0,this.s.z)),this.b=i}var a=this.b.length-this.s.z;a&&(this.b.set(n.subarray(0,a),this.s.z),this.s.z=this.b.length,this.p(this.b,!1)),this.b.set(this.b.subarray(-32768)),this.b.set(n.subarray(a),32768),this.s.z=n.length-a+32768,this.s.i=32766,this.s.w=32768}else this.b.set(n,this.s.z),this.s.z+=n.length;this.s.l=1&r,(this.s.z>this.s.w+8191||r)&&(this.p(this.b,r||!1),this.s.w=this.s.i,this.s.i-=2)},n}();var H=function(){function t(t,n){this.c=L(),this.v=1,G.call(this,t,n)}return t.prototype.push=function(t,n){this.c.p(t),G.prototype.push.call(this,t,n)},t.prototype.p=function(t,n){var r=O(t,this.o,this.v&&(this.o.dictionary?6:2),n&&4,this.s);this.v&&(function(t,n){var r=n.level,e=0==r?0:r<6?1:9==r?3:2;if(t[0]=120,t[1]=e<<6|(n.dictionary&&32),t[1]|=31-(t[0]<<8|t[1])%31,n.dictionary){var i=L();i.p(n.dictionary),j(t,2,i.d())}}(r,this.o),this.v=0),n&&j(r,r.length-4,this.c.d()),this.ondata(r,n)},t}(),J=\"undefined\"!=typeof TextEncoder&&new TextEncoder,K=\"undefined\"!=typeof TextDecoder&&new TextDecoder;try{K.decode(F,{stream:!0})}catch(t){}var N=function(){function t(t){this.ondata=t}return t.prototype.push=function(t,n){this.ondata||E(5),this.d&&E(4),this.ondata(P(t),this.d=n||!1)},t}();function P(n,r){if(J)return J.encode(n);for(var e=n.length,i=new t(n.length+(n.length>>1)),a=0,s=function(t){i[a++]=t},o=0;o<e;++o){if(a+5>i.length){var f=new t(a+8+(e-o<<1));f.set(i),i=f}var h=n.charCodeAt(o);h<128||r?s(h):h<2048?(s(192|h>>6),s(128|63&h)):h>55295&&h<57344?(s(240|(h=65536+(1047552&h)|1023&n.charCodeAt(++o))>>18),s(128|h>>12&63),s(128|h>>6&63),s(128|63&h)):(s(224|h>>12),s(128|h>>6&63),s(128|63&h))}return b(i,0,a)}function Q(t){return function(t,n){n||(n={});var r=S(),e=t.length;r.p(t);var i=O(t,n,B(n),8),a=i.length;return q(i,n),j(i,a-8,r.d()),j(i,a-4,e),i}(P(t))}const R=new class{constructor(){this._init()}clear(){this._init()}addEvent(t){if(!t)throw new Error(\"Adding invalid event\");const n=this._hasEvents?\",\":\"\";this.stream.push(n+t),this._hasEvents=!0}finish(){this.stream.push(\"]\",!0);const t=function(t){let n=0;for(const r of t)n+=r.length;const r=new Uint8Array(n);for(let n=0,e=0,i=t.length;n<i;n++){const i=t[n];r.set(i,e),e+=i.length}return r}(this._deflatedData);return this._init(),t}_init(){this._hasEvents=!1,this._deflatedData=[],this.deflate=new H,this.deflate.ondata=(t,n)=>{this._deflatedData.push(t)},this.stream=new N(((t,n)=>{this.deflate.push(t,n)})),this.stream.push(\"[\")}},V={clear:()=>{R.clear()},addEvent:t=>R.addEvent(t),finish:()=>R.finish(),compress:t=>Q(t)};addEventListener(\"message\",(function(t){const n=t.data.method,r=t.data.id,e=t.data.arg;if(n in V&&\"function\"==typeof V[n])try{const t=V[n](e);postMessage({id:r,method:n,success:!0,response:t})}catch(t){postMessage({id:r,method:n,success:!1,response:t.message}),console.error(t)}})),postMessage({id:void 0,method:\"init\",success:!0,response:void 0});`;\n", "import r from\"./worker\";function e(){const e=new Blob([r]);return URL.createObjectURL(e)}export{e as getWorkerURL};\n", "import type { ConsoleLevel, SeverityLevel } from '@sentry/core';\nimport { addBreadcrumb, captureException, logger as coreLogger, severityLevelFromString } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\n\ntype ReplayConsoleLevels = Extract<ConsoleLevel, 'info' | 'warn' | 'error' | 'log'>;\nconst CONSOLE_LEVELS: readonly ReplayConsoleLevels[] = ['info', 'warn', 'error', 'log'] as const;\nconst PREFIX = '[Replay] ';\n\ntype LoggerMethod = (...args: unknown[]) => void;\ntype LoggerConsoleMethods = Record<ReplayConsoleLevels, LoggerMethod>;\n\ninterface LoggerConfig {\n  captureExceptions: boolean;\n  traceInternals: boolean;\n}\n\ninterface ReplayLogger extends LoggerConsoleMethods {\n  /**\n   * Calls `logger.info` but saves breadcrumb in the next tick due to race\n   * conditions before replay is initialized.\n   */\n  infoTick: LoggerMethod;\n  /**\n   * Captures exceptions (`Error`) if \"capture internal exceptions\" is enabled\n   */\n  exception: LoggerMethod;\n  /**\n   * Configures the logger with additional debugging behavior\n   */\n  setConfig(config: LoggerConfig): void;\n}\n\nfunction _addBreadcrumb(message: unknown, level: SeverityLevel = 'info'): void {\n  addBreadcrumb(\n    {\n      category: 'console',\n      data: {\n        logger: 'replay',\n      },\n      level,\n      message: `${PREFIX}${message}`,\n    },\n    { level },\n  );\n}\n\nfunction makeReplayLogger(): ReplayLogger {\n  let _capture = false;\n  let _trace = false;\n\n  const _logger: Partial<ReplayLogger> = {\n    exception: () => undefined,\n    infoTick: () => undefined,\n    setConfig: (opts: LoggerConfig) => {\n      _capture = opts.captureExceptions;\n      _trace = opts.traceInternals;\n    },\n  };\n\n  if (DEBUG_BUILD) {\n    CONSOLE_LEVELS.forEach(name => {\n      _logger[name] = (...args: unknown[]) => {\n        coreLogger[name](PREFIX, ...args);\n        if (_trace) {\n          _addBreadcrumb(args.join(''), severityLevelFromString(name));\n        }\n      };\n    });\n\n    _logger.exception = (error: unknown, ...message: unknown[]) => {\n      if (message.length && _logger.error) {\n        _logger.error(...message);\n      }\n\n      coreLogger.error(PREFIX, error);\n\n      if (_capture) {\n        captureException(error);\n      } else if (_trace) {\n        // No need for a breadcrumb if `_capture` is enabled since it should be\n        // captured as an exception\n        _addBreadcrumb(error, 'error');\n      }\n    };\n\n    _logger.infoTick = (...args: unknown[]) => {\n      coreLogger.info(PREFIX, ...args);\n      if (_trace) {\n        // Wait a tick here to avoid race conditions for some initial logs\n        // which may be added before replay is initialized\n        setTimeout(() => _addBreadcrumb(args[0]), 0);\n      }\n    };\n  } else {\n    CONSOLE_LEVELS.forEach(name => {\n      _logger[name] = () => undefined;\n    });\n  }\n\n  return _logger as ReplayLogger;\n}\n\nexport const logger = makeReplayLogger();\n", "import { REPLAY_MAX_EVENT_BUFFER_SIZE } from '../constants';\n\n/** This error indicates that the event buffer size exceeded the limit.. */\nexport class EventBufferSizeExceededError extends Error {\n  public constructor() {\n    super(`Event buffer exceeded maximum size of ${REPLAY_MAX_EVENT_BUFFER_SIZE}.`);\n  }\n}\n", "import { REPLAY_MAX_EVENT_BUFFER_SIZE } from '../constants';\nimport type { AddEventResult, EventBuffer, EventBufferType, RecordingEvent } from '../types';\nimport { timestampToMs } from '../util/timestamp';\nimport { EventBufferSizeExceededError } from './error';\n\n/**\n * A basic event buffer that does not do any compression.\n * Used as fallback if the compression worker cannot be loaded or is disabled.\n */\nexport class EventBufferArray implements EventBuffer {\n  /** All the events that are buffered to be sent. */\n  public events: RecordingEvent[];\n\n  /** @inheritdoc */\n  public hasCheckout: boolean;\n\n  /** @inheritdoc */\n  public waitForCheckout: boolean;\n\n  private _totalSize: number;\n\n  public constructor() {\n    this.events = [];\n    this._totalSize = 0;\n    this.hasCheckout = false;\n    this.waitForCheckout = false;\n  }\n\n  /** @inheritdoc */\n  public get hasEvents(): boolean {\n    return this.events.length > 0;\n  }\n\n  /** @inheritdoc */\n  public get type(): EventBufferType {\n    return 'sync';\n  }\n\n  /** @inheritdoc */\n  public destroy(): void {\n    this.events = [];\n  }\n\n  /** @inheritdoc */\n  public async addEvent(event: RecordingEvent): Promise<AddEventResult> {\n    const eventSize = JSON.stringify(event).length;\n    this._totalSize += eventSize;\n    if (this._totalSize > REPLAY_MAX_EVENT_BUFFER_SIZE) {\n      throw new EventBufferSizeExceededError();\n    }\n\n    this.events.push(event);\n  }\n\n  /** @inheritdoc */\n  public finish(): Promise<string> {\n    return new Promise<string>(resolve => {\n      // Make a copy of the events array reference and immediately clear the\n      // events member so that we do not lose new events while uploading\n      // attachment.\n      const eventsRet = this.events;\n      this.clear();\n      resolve(JSON.stringify(eventsRet));\n    });\n  }\n\n  /** @inheritdoc */\n  public clear(): void {\n    this.events = [];\n    this._totalSize = 0;\n    this.hasCheckout = false;\n  }\n\n  /** @inheritdoc */\n  public getEarliestTimestamp(): number | null {\n    const timestamp = this.events.map(event => event.timestamp).sort()[0];\n\n    if (!timestamp) {\n      return null;\n    }\n\n    return timestampToMs(timestamp);\n  }\n}\n", "import { DEBUG_BUILD } from '../debug-build';\nimport type { WorkerRequest, WorkerResponse } from '../types';\nimport { logger } from '../util/logger';\n\n/**\n * Event buffer that uses a web worker to compress events.\n * Exported only for testing.\n */\nexport class WorkerHandler {\n  private _worker: Worker;\n  private _id: number;\n  private _ensureReadyPromise?: Promise<void>;\n\n  public constructor(worker: Worker) {\n    this._worker = worker;\n    this._id = 0;\n  }\n\n  /**\n   * Ensure the worker is ready (or not).\n   * This will either resolve when the worker is ready, or reject if an error occurred.\n   */\n  public ensureReady(): Promise<void> {\n    // Ensure we only check once\n    if (this._ensureReadyPromise) {\n      return this._ensureReadyPromise;\n    }\n\n    this._ensureReadyPromise = new Promise((resolve, reject) => {\n      this._worker.addEventListener(\n        'message',\n        ({ data }: MessageEvent) => {\n          if ((data as WorkerResponse).success) {\n            resolve();\n          } else {\n            reject();\n          }\n        },\n        { once: true },\n      );\n\n      this._worker.addEventListener(\n        'error',\n        error => {\n          reject(error);\n        },\n        { once: true },\n      );\n    });\n\n    return this._ensureReadyPromise;\n  }\n\n  /**\n   * Destroy the worker.\n   */\n  public destroy(): void {\n    DEBUG_BUILD && logger.info('Destroying compression worker');\n    this._worker.terminate();\n  }\n\n  /**\n   * Post message to worker and wait for response before resolving promise.\n   */\n  public postMessage<T>(method: WorkerRequest['method'], arg?: WorkerRequest['arg']): Promise<T> {\n    const id = this._getAndIncrementId();\n\n    return new Promise((resolve, reject) => {\n      const listener = ({ data }: MessageEvent): void => {\n        const response = data as WorkerResponse;\n        if (response.method !== method) {\n          return;\n        }\n\n        // There can be multiple listeners for a single method, the id ensures\n        // that the response matches the caller.\n        if (response.id !== id) {\n          return;\n        }\n\n        // At this point, we'll always want to remove listener regardless of result status\n        this._worker.removeEventListener('message', listener);\n\n        if (!response.success) {\n          // TODO: Do some error handling, not sure what\n          DEBUG_BUILD && logger.error('Error in compression worker: ', response.response);\n\n          reject(new Error('Error in compression worker'));\n          return;\n        }\n\n        resolve(response.response as T);\n      };\n\n      // Note: we can't use `once` option because it's possible it needs to\n      // listen to multiple messages\n      this._worker.addEventListener('message', listener);\n      this._worker.postMessage({ id, method, arg });\n    });\n  }\n\n  /** Get the current ID and increment it for the next call. */\n  private _getAndIncrementId(): number {\n    return this._id++;\n  }\n}\n", "import type { ReplayRecordingData } from '@sentry/core';\n\nimport { REPLAY_MAX_EVENT_BUFFER_SIZE } from '../constants';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { AddEventResult, EventBuffer, EventBufferType, RecordingEvent } from '../types';\nimport { logger } from '../util/logger';\nimport { timestampToMs } from '../util/timestamp';\nimport { WorkerHandler } from './WorkerHandler';\nimport { EventBufferSizeExceededError } from './error';\n\n/**\n * Event buffer that uses a web worker to compress events.\n * Exported only for testing.\n */\nexport class EventBufferCompressionWorker implements EventBuffer {\n  /** @inheritdoc */\n  public hasCheckout: boolean;\n\n  /** @inheritdoc */\n  public waitForCheckout: boolean;\n\n  private _worker: WorkerHandler;\n  private _earliestTimestamp: number | null;\n  private _totalSize;\n\n  public constructor(worker: Worker) {\n    this._worker = new WorkerHandler(worker);\n    this._earliestTimestamp = null;\n    this._totalSize = 0;\n    this.hasCheckout = false;\n    this.waitForCheckout = false;\n  }\n\n  /** @inheritdoc */\n  public get hasEvents(): boolean {\n    return !!this._earliestTimestamp;\n  }\n\n  /** @inheritdoc */\n  public get type(): EventBufferType {\n    return 'worker';\n  }\n\n  /**\n   * Ensure the worker is ready (or not).\n   * This will either resolve when the worker is ready, or reject if an error occurred.\n   */\n  public ensureReady(): Promise<void> {\n    return this._worker.ensureReady();\n  }\n\n  /**\n   * Destroy the event buffer.\n   */\n  public destroy(): void {\n    this._worker.destroy();\n  }\n\n  /**\n   * Add an event to the event buffer.\n   *\n   * Returns true if event was successfully received and processed by worker.\n   */\n  public addEvent(event: RecordingEvent): Promise<AddEventResult> {\n    const timestamp = timestampToMs(event.timestamp);\n    if (!this._earliestTimestamp || timestamp < this._earliestTimestamp) {\n      this._earliestTimestamp = timestamp;\n    }\n\n    const data = JSON.stringify(event);\n    this._totalSize += data.length;\n\n    if (this._totalSize > REPLAY_MAX_EVENT_BUFFER_SIZE) {\n      return Promise.reject(new EventBufferSizeExceededError());\n    }\n\n    return this._sendEventToWorker(data);\n  }\n\n  /**\n   * Finish the event buffer and return the compressed data.\n   */\n  public finish(): Promise<ReplayRecordingData> {\n    return this._finishRequest();\n  }\n\n  /** @inheritdoc */\n  public clear(): void {\n    this._earliestTimestamp = null;\n    this._totalSize = 0;\n    this.hasCheckout = false;\n\n    // We do not wait on this, as we assume the order of messages is consistent for the worker\n    this._worker.postMessage('clear').then(null, e => {\n      DEBUG_BUILD && logger.exception(e, 'Sending \"clear\" message to worker failed', e);\n    });\n  }\n\n  /** @inheritdoc */\n  public getEarliestTimestamp(): number | null {\n    return this._earliestTimestamp;\n  }\n\n  /**\n   * Send the event to the worker.\n   */\n  private _sendEventToWorker(data: string): Promise<AddEventResult> {\n    return this._worker.postMessage<void>('addEvent', data);\n  }\n\n  /**\n   * Finish the request and return the compressed data from the worker.\n   */\n  private async _finishRequest(): Promise<Uint8Array> {\n    const response = await this._worker.postMessage<Uint8Array>('finish');\n\n    this._earliestTimestamp = null;\n    this._totalSize = 0;\n\n    return response;\n  }\n}\n", "import type { ReplayRecordingData } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { AddEventResult, EventBuffer, EventBufferType, RecordingEvent } from '../types';\nimport { logger } from '../util/logger';\nimport { EventBufferArray } from './EventBufferArray';\nimport { EventBufferCompressionWorker } from './EventBufferCompressionWorker';\n\n/**\n * This proxy will try to use the compression worker, and fall back to use the simple buffer if an error occurs there.\n * This can happen e.g. if the worker cannot be loaded.\n * Exported only for testing.\n */\nexport class EventBufferProxy implements EventBuffer {\n  private _fallback: EventBufferArray;\n  private _compression: EventBufferCompressionWorker;\n  private _used: EventBuffer;\n  private _ensureWorkerIsLoadedPromise: Promise<void>;\n\n  public constructor(worker: Worker) {\n    this._fallback = new EventBufferArray();\n    this._compression = new EventBufferCompressionWorker(worker);\n    this._used = this._fallback;\n\n    this._ensureWorkerIsLoadedPromise = this._ensureWorkerIsLoaded();\n  }\n\n  /** @inheritdoc */\n  public get waitForCheckout(): boolean {\n    return this._used.waitForCheckout;\n  }\n\n  /** @inheritdoc */\n  public get type(): EventBufferType {\n    return this._used.type;\n  }\n\n  /** @inheritDoc */\n  public get hasEvents(): boolean {\n    return this._used.hasEvents;\n  }\n\n  /** @inheritdoc */\n  public get hasCheckout(): boolean {\n    return this._used.hasCheckout;\n  }\n  /** @inheritdoc */\n  public set hasCheckout(value: boolean) {\n    this._used.hasCheckout = value;\n  }\n\n  /** @inheritdoc */\n  // eslint-disable-next-line @typescript-eslint/adjacent-overload-signatures\n  public set waitForCheckout(value: boolean) {\n    this._used.waitForCheckout = value;\n  }\n\n  /** @inheritDoc */\n  public destroy(): void {\n    this._fallback.destroy();\n    this._compression.destroy();\n  }\n\n  /** @inheritdoc */\n  public clear(): void {\n    return this._used.clear();\n  }\n\n  /** @inheritdoc */\n  public getEarliestTimestamp(): number | null {\n    return this._used.getEarliestTimestamp();\n  }\n\n  /**\n   * Add an event to the event buffer.\n   *\n   * Returns true if event was successfully added.\n   */\n  public addEvent(event: RecordingEvent): Promise<AddEventResult> {\n    return this._used.addEvent(event);\n  }\n\n  /** @inheritDoc */\n  public async finish(): Promise<ReplayRecordingData> {\n    // Ensure the worker is loaded, so the sent event is compressed\n    await this.ensureWorkerIsLoaded();\n\n    return this._used.finish();\n  }\n\n  /** Ensure the worker has loaded. */\n  public ensureWorkerIsLoaded(): Promise<void> {\n    return this._ensureWorkerIsLoadedPromise;\n  }\n\n  /** Actually check if the worker has been loaded. */\n  private async _ensureWorkerIsLoaded(): Promise<void> {\n    try {\n      await this._compression.ensureReady();\n    } catch (error) {\n      // If the worker fails to load, we fall back to the simple buffer.\n      // Nothing more to do from our side here\n      DEBUG_BUILD && logger.exception(error, 'Failed to load the compression worker, falling back to simple buffer');\n      return;\n    }\n\n    // Now we need to switch over the array buffer to the compression worker\n    await this._switchToCompressionWorker();\n  }\n\n  /** Switch the used buffer to the compression worker. */\n  private async _switchToCompressionWorker(): Promise<void> {\n    const { events, hasCheckout, waitForCheckout } = this._fallback;\n\n    const addEventPromises: Promise<void>[] = [];\n    for (const event of events) {\n      addEventPromises.push(this._compression.addEvent(event));\n    }\n\n    this._compression.hasCheckout = hasCheckout;\n    this._compression.waitForCheckout = waitForCheckout;\n\n    // We switch over to the new buffer immediately - any further events will be added\n    // after the previously buffered ones\n    this._used = this._compression;\n\n    // Wait for original events to be re-added before resolving\n    try {\n      await Promise.all(addEventPromises);\n\n      // Can now clear fallback buffer as it's no longer necessary\n      this._fallback.clear();\n    } catch (error) {\n      DEBUG_BUILD && logger.exception(error, 'Failed to add events when switching buffers.');\n    }\n  }\n}\n", "import { getWorkerURL } from '@sentry-internal/replay-worker';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { EventBuffer } from '../types';\nimport { logger } from '../util/logger';\nimport { EventBufferArray } from './EventBufferArray';\nimport { EventBufferProxy } from './EventBufferProxy';\n\ninterface CreateEventBufferParams {\n  useCompression: boolean;\n  workerUrl?: string;\n}\n\n// Treeshakable guard to remove the code of the included compression worker\ndeclare const __SENTRY_EXCLUDE_REPLAY_WORKER__: boolean;\n\n/**\n * Create an event buffer for replays.\n */\nexport function createEventBuffer({\n  useCompression,\n  workerUrl: customWorkerUrl,\n}: CreateEventBufferParams): EventBuffer {\n  if (\n    useCompression &&\n    // eslint-disable-next-line no-restricted-globals\n    window.Worker\n  ) {\n    const worker = _loadWorker(customWorkerUrl);\n\n    if (worker) {\n      return worker;\n    }\n  }\n\n  DEBUG_BUILD && logger.info('Using simple buffer');\n  return new EventBufferArray();\n}\n\nfunction _loadWorker(customWorkerUrl?: string): EventBufferProxy | void {\n  try {\n    const workerUrl = customWorkerUrl || _getWorkerUrl();\n\n    if (!workerUrl) {\n      return;\n    }\n\n    DEBUG_BUILD && logger.info(`Using compression worker${customWorkerUrl ? ` from ${customWorkerUrl}` : ''}`);\n    const worker = new Worker(workerUrl);\n    return new EventBufferProxy(worker);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to create compression worker');\n    // Fall back to use simple event buffer array\n  }\n}\n\nfunction _getWorkerUrl(): string {\n  if (typeof __SENTRY_EXCLUDE_REPLAY_WORKER__ === 'undefined' || !__SENTRY_EXCLUDE_REPLAY_WORKER__) {\n    return getWorkerURL();\n  }\n\n  return '';\n}\n", "import { WINDOW } from '../constants';\n\n/** If sessionStorage is available. */\nexport function hasSessionStorage(): boolean {\n  try {\n    // This can throw, e.g. when being accessed in a sandboxed iframe\n    return 'sessionStorage' in WINDOW && !!WINDOW.sessionStorage;\n  } catch {\n    return false;\n  }\n}\n", "import { REPLAY_SESSION_KEY, WINDOW } from '../../src/constants';\nimport type { ReplayContainer } from '../../src/types';\nimport { hasSessionStorage } from '../util/hasSessionStorage';\n\n/**\n * Removes the session from Session Storage and unsets session in replay instance\n */\nexport function clearSession(replay: ReplayContainer): void {\n  deleteSession();\n  replay.session = undefined;\n}\n\n/**\n * Deletes a session from storage\n */\nfunction deleteSession(): void {\n  if (!hasSessionStorage()) {\n    return;\n  }\n\n  try {\n    WINDOW.sessionStorage.removeItem(REPLAY_SESSION_KEY);\n  } catch {\n    // Ignore potential SecurityError exceptions\n  }\n}\n", "/**\n * Given a sample rate, returns true if replay should be sampled.\n *\n * 1.0 = 100% sampling\n * 0.0 = 0% sampling\n */\nexport function isSampled(sampleRate?: number): boolean {\n  if (sampleRate === undefined) {\n    return false;\n  }\n\n  // Math.random() returns a number in range of 0 to 1 (inclusive of 0, but not 1)\n  return Math.random() < sampleRate;\n}\n", "import { uuid4 } from '@sentry/core';\n\nimport type { Sampled, Session } from '../types';\n\n/**\n * Get a session with defaults & applied sampling.\n */\nexport function makeSession(session: Partial<Session> & { sampled: Sampled }): Session {\n  const now = Date.now();\n  const id = session.id || uuid4();\n  // Note that this means we cannot set a started/lastActivity of `0`, but this should not be relevant outside of tests.\n  const started = session.started || now;\n  const lastActivity = session.lastActivity || now;\n  const segmentId = session.segmentId || 0;\n  const sampled = session.sampled;\n  const previousSessionId = session.previousSessionId;\n\n  return {\n    id,\n    started,\n    lastActivity,\n    segmentId,\n    sampled,\n    previousSessionId,\n  };\n}\n", "import { REPLAY_SESSION_KEY, WINDOW } from '../constants';\nimport type { Session } from '../types';\nimport { hasSessionStorage } from '../util/hasSessionStorage';\n\n/**\n * Save a session to session storage.\n */\nexport function saveSession(session: Session): void {\n  if (!hasSessionStorage()) {\n    return;\n  }\n\n  try {\n    WINDOW.sessionStorage.setItem(REPLAY_SESSION_KEY, JSON.stringify(session));\n  } catch {\n    // Ignore potential SecurityError exceptions\n  }\n}\n", "import type { Sampled, Session, SessionOptions } from '../types';\nimport { isSampled } from '../util/isSampled';\nimport { makeSession } from './Session';\nimport { saveSession } from './saveSession';\n\n/**\n * Get the sampled status for a session based on sample rates & current sampled status.\n */\nexport function getSessionSampleType(sessionSampleRate: number, allowBuffering: boolean): Sampled {\n  return isSampled(sessionSampleRate) ? 'session' : allowBuffering ? 'buffer' : false;\n}\n\n/**\n * Create a new session, which in its current implementation is a Sentry event\n * that all replays will be saved to as attachments. Currently, we only expect\n * one of these Sentry events per \"replay session\".\n */\nexport function createSession(\n  { sessionSampleRate, allowBuffering, stickySession = false }: SessionOptions,\n  { previousSessionId }: { previousSessionId?: string } = {},\n): Session {\n  const sampled = getSessionSampleType(sessionSampleRate, allowBuffering);\n  const session = makeSession({\n    sampled,\n    previousSessionId,\n  });\n\n  if (stickySession) {\n    saveSession(session);\n  }\n\n  return session;\n}\n", "import { REPLAY_SESSION_KEY, WINDOW } from '../constants';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Session } from '../types';\nimport { hasSessionStorage } from '../util/hasSessionStorage';\nimport { logger } from '../util/logger';\nimport { makeSession } from './Session';\n\n/**\n * Fetches a session from storage\n */\nexport function fetchSession(): Session | null {\n  if (!hasSessionStorage()) {\n    return null;\n  }\n\n  try {\n    // This can throw if cookies are disabled\n    const sessionStringFromStorage = WINDOW.sessionStorage.getItem(REPLAY_SESSION_KEY);\n\n    if (!sessionStringFromStorage) {\n      return null;\n    }\n\n    const sessionObj = JSON.parse(sessionStringFromStorage) as Session;\n\n    DEBUG_BUILD && logger.infoTick('Loading existing session');\n\n    return makeSession(sessionObj);\n  } catch {\n    return null;\n  }\n}\n", "/**\n * Given an initial timestamp and an expiry duration, checks to see if current\n * time should be considered as expired.\n */\nexport function isExpired(\n  initialTime: null | number,\n  expiry: undefined | number,\n  targetTime: number = +new Date(),\n): boolean {\n  // Always expired if < 0\n  if (initialTime === null || expiry === undefined || expiry < 0) {\n    return true;\n  }\n\n  // Never expires if == 0\n  if (expiry === 0) {\n    return false;\n  }\n\n  return initialTime + expiry <= targetTime;\n}\n", "import type { Session } from '../types';\nimport { isExpired } from './isExpired';\n\n/**\n * Checks to see if session is expired\n */\nexport function isSessionExpired(\n  session: Session,\n  {\n    maxReplayDuration,\n    sessionIdleExpire,\n    targetTime = Date.now(),\n  }: { maxReplayDuration: number; sessionIdleExpire: number; targetTime?: number },\n): boolean {\n  return (\n    // First, check that maximum session length has not been exceeded\n    isExpired(session.started, maxReplayDuration, targetTime) ||\n    // check that the idle timeout has not been exceeded (i.e. user has\n    // performed an action within the last `sessionIdleExpire` ms)\n    isExpired(session.lastActivity, sessionIdleExpire, targetTime)\n  );\n}\n", "import type { Session } from '../types';\nimport { isSessionExpired } from '../util/isSessionExpired';\n\n/** If the session should be refreshed or not. */\nexport function shouldRefreshSession(\n  session: Session,\n  { sessionIdleExpire, maxReplayDuration }: { sessionIdleExpire: number; maxReplayDuration: number },\n): boolean {\n  // If not expired, all good, just keep the session\n  if (!isSessionExpired(session, { sessionIdleExpire, maxReplayDuration })) {\n    return false;\n  }\n\n  // If we are buffering & haven't ever flushed yet, always continue\n  if (session.sampled === 'buffer' && session.segmentId === 0) {\n    return false;\n  }\n\n  return true;\n}\n", "import { DEBUG_BUILD } from '../debug-build';\nimport type { Session, SessionOptions } from '../types';\nimport { logger } from '../util/logger';\nimport { createSession } from './createSession';\nimport { fetchSession } from './fetchSession';\nimport { shouldRefreshSession } from './shouldRefreshSession';\n\n/**\n * Get or create a session, when initializing the replay.\n * Returns a session that may be unsampled.\n */\nexport function loadOrCreateSession(\n  {\n    sessionIdleExpire,\n    maxReplayDuration,\n    previousSessionId,\n  }: {\n    sessionIdleExpire: number;\n    maxReplayDuration: number;\n    previousSessionId?: string;\n  },\n  sessionOptions: SessionOptions,\n): Session {\n  const existingSession = sessionOptions.stickySession && fetchSession();\n\n  // No session exists yet, just create a new one\n  if (!existingSession) {\n    DEBUG_BUILD && logger.infoTick('Creating new session');\n    return createSession(sessionOptions, { previousSessionId });\n  }\n\n  if (!shouldRefreshSession(existingSession, { sessionIdleExpire, maxReplayDuration })) {\n    return existingSession;\n  }\n\n  DEBUG_BUILD && logger.infoTick('Session in sessionStorage is expired, creating new one...');\n  return createSession(sessionOptions, { previousSessionId: existingSession.id });\n}\n", "import { EventType } from '@sentry-internal/rrweb';\nimport { getClient } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { EventBufferSizeExceededError } from '../eventBuffer/error';\nimport type { AddEventResult, RecordingEvent, ReplayContainer, ReplayFrameEvent, ReplayPluginOptions } from '../types';\nimport { logger } from './logger';\nimport { timestampToMs } from './timestamp';\n\nfunction isCustomEvent(event: RecordingEvent): event is ReplayFrameEvent {\n  return event.type === EventType.Custom;\n}\n\n/**\n * Add an event to the event buffer.\n * In contrast to `addEvent`, this does not return a promise & does not wait for the adding of the event to succeed/fail.\n * Instead this returns `true` if we tried to add the event, else false.\n * It returns `false` e.g. if we are paused, disabled, or out of the max replay duration.\n *\n * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.\n */\nexport function addEventSync(replay: ReplayContainer, event: RecordingEvent, isCheckout?: boolean): boolean {\n  if (!shouldAddEvent(replay, event)) {\n    return false;\n  }\n\n  // This should never reject\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  _addEvent(replay, event, isCheckout);\n\n  return true;\n}\n\n/**\n * Add an event to the event buffer.\n * Resolves to `null` if no event was added, else to `void`.\n *\n * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.\n */\nexport function addEvent(\n  replay: ReplayContainer,\n  event: RecordingEvent,\n  isCheckout?: boolean,\n): Promise<AddEventResult | null> {\n  if (!shouldAddEvent(replay, event)) {\n    return Promise.resolve(null);\n  }\n\n  return _addEvent(replay, event, isCheckout);\n}\n\nasync function _addEvent(\n  replay: ReplayContainer,\n  event: RecordingEvent,\n  isCheckout?: boolean,\n): Promise<AddEventResult | null> {\n  const { eventBuffer } = replay;\n\n  if (!eventBuffer || (eventBuffer.waitForCheckout && !isCheckout)) {\n    return null;\n  }\n\n  const isBufferMode = replay.recordingMode === 'buffer';\n\n  try {\n    if (isCheckout && isBufferMode) {\n      eventBuffer.clear();\n    }\n\n    if (isCheckout) {\n      eventBuffer.hasCheckout = true;\n      eventBuffer.waitForCheckout = false;\n    }\n\n    const replayOptions = replay.getOptions();\n\n    const eventAfterPossibleCallback = maybeApplyCallback(event, replayOptions.beforeAddRecordingEvent);\n\n    if (!eventAfterPossibleCallback) {\n      return;\n    }\n\n    return await eventBuffer.addEvent(eventAfterPossibleCallback);\n  } catch (error) {\n    const isExceeded = error && error instanceof EventBufferSizeExceededError;\n    const reason = isExceeded ? 'addEventSizeExceeded' : 'addEvent';\n\n    if (isExceeded && isBufferMode) {\n      // Clear buffer and wait for next checkout\n      eventBuffer.clear();\n      eventBuffer.waitForCheckout = true;\n\n      return null;\n    }\n\n    replay.handleException(error);\n\n    await replay.stop({ reason });\n\n    const client = getClient();\n\n    if (client) {\n      client.recordDroppedEvent('internal_sdk_error', 'replay');\n    }\n  }\n}\n\n/** Exported only for tests. */\nexport function shouldAddEvent(replay: ReplayContainer, event: RecordingEvent): boolean {\n  if (!replay.eventBuffer || replay.isPaused() || !replay.isEnabled()) {\n    return false;\n  }\n\n  const timestampInMs = timestampToMs(event.timestamp);\n\n  // Throw out events that happen more than 5 minutes ago. This can happen if\n  // page has been left open and idle for a long period of time and user\n  // comes back to trigger a new session. The performance entries rely on\n  // `performance.timeOrigin`, which is when the page first opened.\n  if (timestampInMs + replay.timeouts.sessionIdlePause < Date.now()) {\n    return false;\n  }\n\n  // Throw out events that are +60min from the initial timestamp\n  if (timestampInMs > replay.getContext().initialTimestamp + replay.getOptions().maxReplayDuration) {\n    DEBUG_BUILD &&\n      logger.infoTick(`Skipping event with timestamp ${timestampInMs} because it is after maxReplayDuration`);\n    return false;\n  }\n\n  return true;\n}\n\nfunction maybeApplyCallback(\n  event: RecordingEvent,\n  callback: ReplayPluginOptions['beforeAddRecordingEvent'],\n): RecordingEvent | null | undefined {\n  try {\n    if (typeof callback === 'function' && isCustomEvent(event)) {\n      return callback(event);\n    }\n  } catch (error) {\n    DEBUG_BUILD &&\n      logger.exception(error, 'An error occurred in the `beforeAddRecordingEvent` callback, skipping the event...');\n    return null;\n  }\n\n  return event;\n}\n", "import type { ErrorEvent, Event, FeedbackEvent, ReplayEvent, TransactionEvent } from '@sentry/core';\n\n/** If the event is an error event */\nexport function isErrorEvent(event: Event): event is ErrorEvent {\n  return !event.type;\n}\n\n/** If the event is a transaction event */\nexport function isTransactionEvent(event: Event): event is TransactionEvent {\n  return event.type === 'transaction';\n}\n\n/** If the event is an replay event */\nexport function isReplayEvent(event: Event): event is ReplayEvent {\n  return event.type === 'replay_event';\n}\n\n/** If the event is a feedback event */\nexport function isFeedbackEvent(event: Event): event is FeedbackEvent {\n  return event.type === 'feedback';\n}\n", "import { setTimeout } from '@sentry-internal/browser-utils';\nimport type { ErrorEvent, Event, TransactionEvent, TransportMakeRequestResponse } from '@sentry/core';\n\nimport type { ReplayContainer } from '../types';\nimport { isErrorEvent, isTransactionEvent } from '../util/eventUtils';\n\ntype AfterSendEventCallback = (event: Event, sendResponse: TransportMakeRequestResponse) => void;\n\n/**\n * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.\n */\nexport function handleAfterSendEvent(replay: ReplayContainer): AfterSendEventCallback {\n  return (event: Event, sendResponse: TransportMakeRequestResponse) => {\n    if (!replay.isEnabled() || (!isErrorEvent(event) && !isTransactionEvent(event))) {\n      return;\n    }\n\n    const statusCode = sendResponse && sendResponse.statusCode;\n\n    // We only want to do stuff on successful error sending, otherwise you get error replays without errors attached\n    // If not using the base transport, we allow `undefined` response (as a custom transport may not implement this correctly yet)\n    // If we do use the base transport, we skip if we encountered an non-OK status code\n    if (!statusCode || statusCode < 200 || statusCode >= 300) {\n      return;\n    }\n\n    if (isTransactionEvent(event)) {\n      handleTransactionEvent(replay, event);\n      return;\n    }\n\n    handleErrorEvent(replay, event);\n  };\n}\n\nfunction handleTransactionEvent(replay: ReplayContainer, event: TransactionEvent): void {\n  const replayContext = replay.getContext();\n\n  // Collect traceIds in _context regardless of `recordingMode`\n  // In error mode, _context gets cleared on every checkout\n  // We limit to max. 100 transactions linked\n  if (event.contexts && event.contexts.trace && event.contexts.trace.trace_id && replayContext.traceIds.size < 100) {\n    replayContext.traceIds.add(event.contexts.trace.trace_id as string);\n  }\n}\n\nfunction handleErrorEvent(replay: ReplayContainer, event: ErrorEvent): void {\n  const replayContext = replay.getContext();\n\n  // Add error to list of errorIds of replay. This is ok to do even if not\n  // sampled because context will get reset at next checkout.\n  // XXX: There is also a race condition where it's possible to capture an\n  // error to Sentry before Replay SDK has loaded, but response returns after\n  // it was loaded, and this gets called.\n  // We limit to max. 100 errors linked\n  if (event.event_id && replayContext.errorIds.size < 100) {\n    replayContext.errorIds.add(event.event_id);\n  }\n\n  // If error event is tagged with replay id it means it was sampled (when in buffer mode)\n  // Need to be very careful that this does not cause an infinite loop\n  if (replay.recordingMode !== 'buffer' || !event.tags || !event.tags.replayId) {\n    return;\n  }\n\n  const { beforeErrorSampling } = replay.getOptions();\n  if (typeof beforeErrorSampling === 'function' && !beforeErrorSampling(event)) {\n    return;\n  }\n\n  setTimeout(async () => {\n    try {\n      // Capture current event buffer as new replay\n      await replay.sendBufferedReplayOrFlush();\n    } catch (err) {\n      replay.handleException(err);\n    }\n  });\n}\n", "import { getLocationHref } from '@sentry/core';\nimport type { ErrorEvent, Event } from '@sentry/core';\n\nimport type { ReplayContainer } from '../types';\nimport { createBreadcrumb } from '../util/createBreadcrumb';\nimport { isErrorEvent } from '../util/eventUtils';\nimport { addBreadcrumbEvent } from './util/addBreadcrumbEvent';\n\ntype BeforeSendEventCallback = (event: Event) => void;\n\n/**\n * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.\n */\nexport function handleBeforeSendEvent(replay: ReplayContainer): BeforeSendEventCallback {\n  return (event: Event) => {\n    if (!replay.isEnabled() || !isErrorEvent(event)) {\n      return;\n    }\n\n    handleHydrationError(replay, event);\n  };\n}\n\nfunction handleHydrationError(replay: ReplayContainer, event: ErrorEvent): void {\n  const exceptionValue =\n    event.exception && event.exception.values && event.exception.values[0] && event.exception.values[0].value;\n  if (typeof exceptionValue !== 'string') {\n    return;\n  }\n\n  if (\n    // Only matches errors in production builds of react-dom\n    // Example https://reactjs.org/docs/error-decoder.html?invariant=423\n    // With newer React versions, the messages changed to a different website https://react.dev/errors/418\n    exceptionValue.match(\n      /(reactjs\\.org\\/docs\\/error-decoder\\.html\\?invariant=|react\\.dev\\/errors\\/)(418|419|422|423|425)/,\n    ) ||\n    // Development builds of react-dom\n    // Error 1: Hydration failed because the initial UI does not match what was rendered on the server.\n    // Error 2: Text content does not match server-rendered HTML. Warning: Text content did not match.\n    exceptionValue.match(/(does not match server-rendered HTML|Hydration failed because)/i)\n  ) {\n    const breadcrumb = createBreadcrumb({\n      category: 'replay.hydrate-error',\n      data: {\n        url: getLocationHref(),\n      },\n    });\n    addBreadcrumbEvent(replay, breadcrumb);\n  }\n}\n", "import type { Breadcrumb } from '@sentry/core';\nimport { getClient, normalize } from '@sentry/core';\nimport { CONSOLE_ARG_MAX_SIZE } from '../constants';\nimport type { ReplayContainer } from '../types';\nimport type { ReplayFrame } from '../types/replayFrame';\nimport { createBreadcrumb } from '../util/createBreadcrumb';\nimport { addBreadcrumbEvent } from './util/addBreadcrumbEvent';\n\ntype BreadcrumbWithCategory = Required<Pick<Breadcrumb, 'category'>>;\n\n/**\n * Handle breadcrumbs that Sentry captures, and make sure to capture relevant breadcrumbs to Replay as well.\n */\nexport function handleBreadcrumbs(replay: ReplayContainer): void {\n  const client = getClient();\n\n  if (!client) {\n    return;\n  }\n\n  client.on('beforeAddBreadcrumb', breadcrumb => beforeAddBreadcrumb(replay, breadcrumb));\n}\n\nfunction beforeAddBreadcrumb(replay: ReplayContainer, breadcrumb: Breadcrumb): void {\n  if (!replay.isEnabled() || !isBreadcrumbWithCategory(breadcrumb)) {\n    return;\n  }\n\n  const result = normalizeBreadcrumb(breadcrumb);\n  if (result) {\n    addBreadcrumbEvent(replay, result);\n  }\n}\n\n/** Exported only for tests. */\nexport function normalizeBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb | null {\n  if (\n    !isBreadcrumbWithCategory(breadcrumb) ||\n    [\n      // fetch & xhr are handled separately,in handleNetworkBreadcrumbs\n      'fetch',\n      'xhr',\n      // These two are breadcrumbs for emitted sentry events, we don't care about them\n      'sentry.event',\n      'sentry.transaction',\n    ].includes(breadcrumb.category) ||\n    // We capture UI breadcrumbs separately\n    breadcrumb.category.startsWith('ui.')\n  ) {\n    return null;\n  }\n\n  if (breadcrumb.category === 'console') {\n    return normalizeConsoleBreadcrumb(breadcrumb);\n  }\n\n  return createBreadcrumb(breadcrumb);\n}\n\n/** exported for tests only */\nexport function normalizeConsoleBreadcrumb(\n  breadcrumb: Omit<Breadcrumb, 'category'> & BreadcrumbWithCategory,\n): ReplayFrame {\n  const args = breadcrumb.data && breadcrumb.data.arguments;\n\n  if (!Array.isArray(args) || args.length === 0) {\n    return createBreadcrumb(breadcrumb);\n  }\n\n  let isTruncated = false;\n\n  // Avoid giant args captures\n  const normalizedArgs = args.map(arg => {\n    if (!arg) {\n      return arg;\n    }\n    if (typeof arg === 'string') {\n      if (arg.length > CONSOLE_ARG_MAX_SIZE) {\n        isTruncated = true;\n        return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;\n      }\n\n      return arg;\n    }\n    if (typeof arg === 'object') {\n      try {\n        const normalizedArg = normalize(arg, 7);\n        const stringified = JSON.stringify(normalizedArg);\n        if (stringified.length > CONSOLE_ARG_MAX_SIZE) {\n          isTruncated = true;\n          // We use the pretty printed JSON string here as a base\n          return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;\n        }\n        return normalizedArg;\n      } catch {\n        // fall back to default\n      }\n    }\n\n    return arg;\n  });\n\n  return createBreadcrumb({\n    ...breadcrumb,\n    data: {\n      ...breadcrumb.data,\n      arguments: normalizedArgs,\n      ...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),\n    },\n  });\n}\n\nfunction isBreadcrumbWithCategory(breadcrumb: Breadcrumb): breadcrumb is BreadcrumbWithCategory {\n  return !!breadcrumb.category;\n}\n", "import type { Event, EventHint } from '@sentry/core';\n\n/**\n * Returns true if we think the given event is an error originating inside of rrweb.\n */\nexport function isRrwebError(event: Event, hint: EventHint): boolean {\n  if (event.type || !event.exception || !event.exception.values || !event.exception.values.length) {\n    return false;\n  }\n\n  // @ts-expect-error this may be set by rrweb when it finds errors\n  if (hint.originalException && hint.originalException.__rrweb__) {\n    return true;\n  }\n\n  return false;\n}\n", "import { getActiveSpan, getCurrentScope, getDynamicSamplingContextFromSpan } from '@sentry/core';\nimport type { DynamicSamplingContext } from '@sentry/core';\n\n/**\n * Reset the `replay_id` field on the DSC.\n */\nexport function resetReplayIdOnDynamicSamplingContext(): void {\n  // Reset DSC on the current scope, if there is one\n  const dsc = getCurrentScope().getPropagationContext().dsc;\n  if (dsc) {\n    delete dsc.replay_id;\n  }\n\n  // Clear it from frozen DSC on the active span\n  const activeSpan = getActiveSpan();\n  if (activeSpan) {\n    const dsc = getDynamicSamplingContextFromSpan(activeSpan);\n    delete (dsc as Partial<DynamicSamplingContext>).replay_id;\n  }\n}\n", "import { EventType } from '@sentry-internal/rrweb';\nimport type { FeedbackEvent } from '@sentry/core';\n\nimport type { ReplayBreadcrumbFrameEvent, ReplayContainer } from '../../types';\n\n/**\n * Add a feedback breadcrumb event to replay.\n */\nexport function addFeedbackBreadcrumb(replay: ReplayContainer, event: FeedbackEvent): void {\n  replay.triggerUserActivity();\n  replay.addUpdate(() => {\n    if (!event.timestamp) {\n      // Ignore events that don't have timestamps (this shouldn't happen, more of a typing issue)\n      // Return true here so that we don't flush\n      return true;\n    }\n\n    // This should never reject\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    replay.throttledAddEvent({\n      type: EventType.Custom,\n      timestamp: event.timestamp * 1000,\n      data: {\n        tag: 'breadcrumb',\n        payload: {\n          timestamp: event.timestamp,\n          type: 'default',\n          category: 'sentry.feedback',\n          data: {\n            feedbackId: event.event_id,\n          },\n        },\n      },\n    } as ReplayBreadcrumbFrameEvent);\n\n    return false;\n  });\n}\n", "import type { Event } from '@sentry/core';\n\nimport { UNABLE_TO_SEND_REPLAY } from '../../constants';\nimport type { ReplayContainer } from '../../types';\nimport { isSampled } from '../../util/isSampled';\n\n/**\n * Determine if event should be sampled (only applies in buffer mode).\n * When an event is captured by `handleGlobalEvent`, when in buffer mode\n * we determine if we want to sample the error or not.\n */\nexport function shouldSampleForBufferEvent(replay: ReplayContainer, event: Event): boolean {\n  if (replay.recordingMode !== 'buffer') {\n    return false;\n  }\n\n  // ignore this error because otherwise we could loop indefinitely with\n  // trying to capture replay and failing\n  if (event.message === UNABLE_TO_SEND_REPLAY) {\n    return false;\n  }\n\n  // Require the event to be an error event & to have an exception\n  if (!event.exception || event.type) {\n    return false;\n  }\n\n  return isSampled(replay.getOptions().errorSampleRate);\n}\n", "import type { Event, EventHint } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { ReplayContainer } from '../types';\nimport { isErrorEvent, isFeedbackEvent, isReplayEvent, isTransactionEvent } from '../util/eventUtils';\nimport { isRrwebError } from '../util/isRrwebError';\nimport { logger } from '../util/logger';\nimport { resetReplayIdOnDynamicSamplingContext } from '../util/resetReplayIdOnDynamicSamplingContext';\nimport { addFeedbackBreadcrumb } from './util/addFeedbackBreadcrumb';\nimport { shouldSampleForBufferEvent } from './util/shouldSampleForBufferEvent';\n\n/**\n * Returns a listener to be added to `addEventProcessor(listener)`.\n */\nexport function handleGlobalEventListener(replay: ReplayContainer): (event: Event, hint: EventHint) => Event | null {\n  return Object.assign(\n    (event: Event, hint: EventHint) => {\n      // Do nothing if replay has been disabled or paused\n      if (!replay.isEnabled() || replay.isPaused()) {\n        return event;\n      }\n\n      if (isReplayEvent(event)) {\n        // Replays have separate set of breadcrumbs, do not include breadcrumbs\n        // from core SDK\n        delete event.breadcrumbs;\n        return event;\n      }\n\n      // We only want to handle errors, transactions, and feedbacks, nothing else\n      if (!isErrorEvent(event) && !isTransactionEvent(event) && !isFeedbackEvent(event)) {\n        return event;\n      }\n\n      // Ensure we do not add replay_id if the session is expired\n      const isSessionActive = replay.checkAndHandleExpiredSession();\n      if (!isSessionActive) {\n        // prevent exceeding replay durations by removing the expired replayId from the DSC\n        resetReplayIdOnDynamicSamplingContext();\n        return event;\n      }\n\n      if (isFeedbackEvent(event)) {\n        // This should never reject\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        replay.flush();\n        event.contexts.feedback.replay_id = replay.getSessionId();\n        // Add a replay breadcrumb for this piece of feedback\n        addFeedbackBreadcrumb(replay, event);\n        return event;\n      }\n\n      // Unless `captureExceptions` is enabled, we want to ignore errors coming from rrweb\n      // As there can be a bunch of stuff going wrong in internals there, that we don't want to bubble up to users\n      if (isRrwebError(event, hint) && !replay.getOptions()._experiments.captureExceptions) {\n        DEBUG_BUILD && logger.log('Ignoring error from rrweb internals', event);\n        return null;\n      }\n\n      // When in buffer mode, we decide to sample here.\n      // Later, in `handleAfterSendEvent`, if the replayId is set, we know that we sampled\n      // And convert the buffer session to a full session\n      const isErrorEventSampled = shouldSampleForBufferEvent(replay, event);\n\n      // Tag errors if it has been sampled in buffer mode, or if it is session mode\n      // Only tag transactions if in session mode\n      const shouldTagReplayId = isErrorEventSampled || replay.recordingMode === 'session';\n\n      if (shouldTagReplayId) {\n        event.tags = { ...event.tags, replayId: replay.getSessionId() };\n      }\n\n      return event;\n    },\n    { id: 'Replay' },\n  );\n}\n", "import { EventType } from '@sentry-internal/rrweb';\n\nimport type { AddEventResult, AllEntryData, ReplayContainer, ReplayPerformanceEntry } from '../types';\n\n/**\n * Create a \"span\" for each performance entry.\n */\nexport function createPerformanceSpans(\n  replay: ReplayContainer,\n  entries: ReplayPerformanceEntry<AllEntryData>[],\n): Promise<AddEventResult | null>[] {\n  return entries.map(({ type, start, end, name, data }) => {\n    const response = replay.throttledAddEvent({\n      type: EventType.Custom,\n      timestamp: start,\n      data: {\n        tag: 'performanceSpan',\n        payload: {\n          op: type,\n          description: name,\n          startTimestamp: start,\n          endTimestamp: end,\n          data,\n        },\n      },\n    });\n\n    // If response is a string, it means its either THROTTLED or SKIPPED\n    return typeof response === 'string' ? Promise.resolve(null) : response;\n  });\n}\n", "import type { HandlerDataHistory } from '@sentry/core';\n\nimport type { HistoryData, ReplayContainer, ReplayPerformanceEntry } from '../types';\nimport { createPerformanceSpans } from '../util/createPerformanceSpans';\n\nfunction handleHistory(handlerData: HandlerDataHistory): ReplayPerformanceEntry<HistoryData> {\n  const { from, to } = handlerData;\n\n  const now = Date.now() / 1000;\n\n  return {\n    type: 'navigation.push',\n    start: now,\n    end: now,\n    name: to,\n    data: {\n      previous: from,\n    },\n  };\n}\n\n/**\n * Returns a listener to be added to `addHistoryInstrumentationHandler(listener)`.\n */\nexport function handleHistorySpanListener(replay: ReplayContainer): (handlerData: HandlerDataHistory) => void {\n  return (handlerData: HandlerDataHistory) => {\n    if (!replay.isEnabled()) {\n      return;\n    }\n\n    const result = handleHistory(handlerData);\n\n    if (result === null) {\n      return;\n    }\n\n    // Need to collect visited URLs\n    replay.getContext().urls.push(result.name);\n    replay.triggerUserActivity();\n\n    replay.addUpdate(() => {\n      createPerformanceSpans(replay, [result]);\n      // Returning false to flush\n      return false;\n    });\n  };\n}\n", "import { getClient, isSentryRequestUrl } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { ReplayContainer } from '../types';\n\n/**\n * Check whether a given request URL should be filtered out. This is so we\n * don't log Sentry ingest requests.\n */\nexport function shouldFilterRequest(replay: ReplayContainer, url: string): boolean {\n  // If we enabled the `traceInternals` experiment, we want to trace everything\n  if (DEBUG_BUILD && replay.getOptions()._experiments.traceInternals) {\n    return false;\n  }\n\n  return isSentryRequestUrl(url, getClient());\n}\n", "import type { NetworkRequestData, ReplayContainer, ReplayPerformanceEntry } from '../../types';\nimport { createPerformanceSpans } from '../../util/createPerformanceSpans';\nimport { shouldFilterRequest } from '../../util/shouldFilterRequest';\n\n/** Add a performance entry breadcrumb */\nexport function addNetworkBreadcrumb(\n  replay: ReplayContainer,\n  result: ReplayPerformanceEntry<NetworkRequestData> | null,\n): void {\n  if (!replay.isEnabled()) {\n    return;\n  }\n\n  if (result === null) {\n    return;\n  }\n\n  if (shouldFilterRequest(replay, result.name)) {\n    return;\n  }\n\n  replay.addUpdate(() => {\n    createPerformanceSpans(replay, [result]);\n    // Returning true will cause `addUpdate` to not flush\n    // We do not want network requests to cause a flush. This will prevent\n    // recurring/polling requests from keeping the replay session alive.\n    return true;\n  });\n}\n", "import { dropUndefinedKeys, stringMatchesSomePattern } from '@sentry/core';\n\nimport { NETWORK_BODY_MAX_SIZE, WINDOW } from '../../constants';\nimport { DEBUG_BUILD } from '../../debug-build';\nimport type {\n  NetworkBody,\n  NetworkMetaWarning,\n  NetworkRequestData,\n  ReplayNetworkRequestData,\n  ReplayNetworkRequestOrResponse,\n  ReplayPerformanceEntry,\n} from '../../types';\nimport { logger } from '../../util/logger';\n\n/** Get the size of a body. */\nexport function getBodySize(body: RequestInit['body']): number | undefined {\n  if (!body) {\n    return undefined;\n  }\n\n  const textEncoder = new TextEncoder();\n\n  try {\n    if (typeof body === 'string') {\n      return textEncoder.encode(body).length;\n    }\n\n    if (body instanceof URLSearchParams) {\n      return textEncoder.encode(body.toString()).length;\n    }\n\n    if (body instanceof FormData) {\n      const formDataStr = _serializeFormData(body);\n      return textEncoder.encode(formDataStr).length;\n    }\n\n    if (body instanceof Blob) {\n      return body.size;\n    }\n\n    if (body instanceof ArrayBuffer) {\n      return body.byteLength;\n    }\n\n    // Currently unhandled types: ArrayBufferView, ReadableStream\n  } catch {\n    // just return undefined\n  }\n\n  return undefined;\n}\n\n/** Convert a Content-Length header to number/undefined.  */\nexport function parseContentLengthHeader(header: string | null | undefined): number | undefined {\n  if (!header) {\n    return undefined;\n  }\n\n  const size = parseInt(header, 10);\n  return isNaN(size) ? undefined : size;\n}\n\n/** Get the string representation of a body. */\nexport function getBodyString(body: unknown): [string | undefined, NetworkMetaWarning?] {\n  try {\n    if (typeof body === 'string') {\n      return [body];\n    }\n\n    if (body instanceof URLSearchParams) {\n      return [body.toString()];\n    }\n\n    if (body instanceof FormData) {\n      return [_serializeFormData(body)];\n    }\n\n    if (!body) {\n      return [undefined];\n    }\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to serialize body', body);\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n\n  DEBUG_BUILD && logger.info('Skipping network body because of body type', body);\n\n  return [undefined, 'UNPARSEABLE_BODY_TYPE'];\n}\n\n/** Merge a warning into an existing network request/response. */\nexport function mergeWarning(\n  info: ReplayNetworkRequestOrResponse | undefined,\n  warning: NetworkMetaWarning,\n): ReplayNetworkRequestOrResponse {\n  if (!info) {\n    return {\n      headers: {},\n      size: undefined,\n      _meta: {\n        warnings: [warning],\n      },\n    };\n  }\n\n  const newMeta = { ...info._meta };\n  const existingWarnings = newMeta.warnings || [];\n  newMeta.warnings = [...existingWarnings, warning];\n\n  info._meta = newMeta;\n  return info;\n}\n\n/** Convert ReplayNetworkRequestData to a PerformanceEntry. */\nexport function makeNetworkReplayBreadcrumb(\n  type: string,\n  data: ReplayNetworkRequestData | null,\n): ReplayPerformanceEntry<NetworkRequestData> | null {\n  if (!data) {\n    return null;\n  }\n\n  const { startTimestamp, endTimestamp, url, method, statusCode, request, response } = data;\n\n  const result: ReplayPerformanceEntry<NetworkRequestData> = {\n    type,\n    start: startTimestamp / 1000,\n    end: endTimestamp / 1000,\n    name: url,\n    data: dropUndefinedKeys({\n      method,\n      statusCode,\n      request,\n      response,\n    }),\n  };\n\n  return result;\n}\n\n/** Build the request or response part of a replay network breadcrumb that was skipped. */\nexport function buildSkippedNetworkRequestOrResponse(bodySize: number | undefined): ReplayNetworkRequestOrResponse {\n  return {\n    headers: {},\n    size: bodySize,\n    _meta: {\n      warnings: ['URL_SKIPPED'],\n    },\n  };\n}\n\n/** Build the request or response part of a replay network breadcrumb. */\nexport function buildNetworkRequestOrResponse(\n  headers: Record<string, string>,\n  bodySize: number | undefined,\n  body: string | undefined,\n): ReplayNetworkRequestOrResponse | undefined {\n  if (!bodySize && Object.keys(headers).length === 0) {\n    return undefined;\n  }\n\n  if (!bodySize) {\n    return {\n      headers,\n    };\n  }\n\n  if (!body) {\n    return {\n      headers,\n      size: bodySize,\n    };\n  }\n\n  const info: ReplayNetworkRequestOrResponse = {\n    headers,\n    size: bodySize,\n  };\n\n  const { body: normalizedBody, warnings } = normalizeNetworkBody(body);\n  info.body = normalizedBody;\n  if (warnings && warnings.length > 0) {\n    info._meta = {\n      warnings,\n    };\n  }\n\n  return info;\n}\n\n/** Filter a set of headers */\nexport function getAllowedHeaders(headers: Record<string, string>, allowedHeaders: string[]): Record<string, string> {\n  return Object.entries(headers).reduce((filteredHeaders: Record<string, string>, [key, value]) => {\n    const normalizedKey = key.toLowerCase();\n    // Avoid putting empty strings into the headers\n    if (allowedHeaders.includes(normalizedKey) && headers[key]) {\n      filteredHeaders[normalizedKey] = value;\n    }\n    return filteredHeaders;\n  }, {});\n}\n\nfunction _serializeFormData(formData: FormData): string {\n  // This is a bit simplified, but gives us a decent estimate\n  // This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith&age=13'\n  // @ts-expect-error passing FormData to URLSearchParams actually works\n  return new URLSearchParams(formData).toString();\n}\n\nfunction normalizeNetworkBody(body: string | undefined): {\n  body: NetworkBody | undefined;\n  warnings?: NetworkMetaWarning[];\n} {\n  if (!body || typeof body !== 'string') {\n    return {\n      body,\n    };\n  }\n\n  const exceedsSizeLimit = body.length > NETWORK_BODY_MAX_SIZE;\n  const isProbablyJson = _strIsProbablyJson(body);\n\n  if (exceedsSizeLimit) {\n    const truncatedBody = body.slice(0, NETWORK_BODY_MAX_SIZE);\n\n    if (isProbablyJson) {\n      return {\n        body: truncatedBody,\n        warnings: ['MAYBE_JSON_TRUNCATED'],\n      };\n    }\n\n    return {\n      body: `${truncatedBody}…`,\n      warnings: ['TEXT_TRUNCATED'],\n    };\n  }\n\n  if (isProbablyJson) {\n    try {\n      const jsonBody = JSON.parse(body);\n      return {\n        body: jsonBody,\n      };\n    } catch {\n      // fall back to just send the body as string\n    }\n  }\n\n  return {\n    body,\n  };\n}\n\nfunction _strIsProbablyJson(str: string): boolean {\n  const first = str[0];\n  const last = str[str.length - 1];\n\n  // Simple check: If this does not start & end with {} or [], it's not JSON\n  return (first === '[' && last === ']') || (first === '{' && last === '}');\n}\n\n/** Match an URL against a list of strings/Regex. */\nexport function urlMatches(url: string, urls: (string | RegExp)[]): boolean {\n  const fullUrl = getFullUrl(url);\n\n  return stringMatchesSomePattern(fullUrl, urls);\n}\n\n/** exported for tests */\nexport function getFullUrl(url: string, baseURI = WINDOW.document.baseURI): string {\n  // Short circuit for common cases:\n  if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith(WINDOW.location.origin)) {\n    return url;\n  }\n  const fixedUrl = new URL(url, baseURI);\n\n  // If these do not match, we are not dealing with a relative URL, so just return it\n  if (fixedUrl.origin !== new URL(baseURI).origin) {\n    return url;\n  }\n\n  const fullUrl = fixedUrl.href;\n\n  // Remove trailing slashes, if they don't match the original URL\n  if (!url.endsWith('/') && fullUrl.endsWith('/')) {\n    return fullUrl.slice(0, -1);\n  }\n\n  return fullUrl;\n}\n", "import { setTimeout } from '@sentry-internal/browser-utils';\nimport type { Breadcrumb, FetchBreadcrumbData } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../../debug-build';\nimport type {\n  FetchHint,\n  NetworkMetaWarning,\n  ReplayContainer,\n  ReplayNetworkOptions,\n  ReplayNetworkRequestData,\n  ReplayNetworkRequestOrResponse,\n} from '../../types';\nimport { logger } from '../../util/logger';\nimport { addNetworkBreadcrumb } from './addNetworkBreadcrumb';\nimport {\n  buildNetworkRequestOrResponse,\n  buildSkippedNetworkRequestOrResponse,\n  getAllowedHeaders,\n  getBodySize,\n  getBodyString,\n  makeNetworkReplayBreadcrumb,\n  mergeWarning,\n  parseContentLengthHeader,\n  urlMatches,\n} from './networkUtils';\n\n/**\n * Capture a fetch breadcrumb to a replay.\n * This adds additional data (where appropriate).\n */\nexport async function captureFetchBreadcrumbToReplay(\n  breadcrumb: Breadcrumb & { data: FetchBreadcrumbData },\n  hint: Partial<FetchHint>,\n  options: ReplayNetworkOptions & {\n    replay: ReplayContainer;\n  },\n): Promise<void> {\n  try {\n    const data = await _prepareFetchData(breadcrumb, hint, options);\n\n    // Create a replay performance entry from this breadcrumb\n    const result = makeNetworkReplayBreadcrumb('resource.fetch', data);\n    addNetworkBreadcrumb(options.replay, result);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to capture fetch breadcrumb');\n  }\n}\n\n/**\n * Enrich a breadcrumb with additional data.\n * This has to be sync & mutate the given breadcrumb,\n * as the breadcrumb is afterwards consumed by other handlers.\n */\nexport function enrichFetchBreadcrumb(\n  breadcrumb: Breadcrumb & { data: FetchBreadcrumbData },\n  hint: Partial<FetchHint>,\n): void {\n  const { input, response } = hint;\n\n  const body = input ? _getFetchRequestArgBody(input) : undefined;\n  const reqSize = getBodySize(body);\n\n  const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;\n\n  if (reqSize !== undefined) {\n    breadcrumb.data.request_body_size = reqSize;\n  }\n  if (resSize !== undefined) {\n    breadcrumb.data.response_body_size = resSize;\n  }\n}\n\nasync function _prepareFetchData(\n  breadcrumb: Breadcrumb & { data: FetchBreadcrumbData },\n  hint: Partial<FetchHint>,\n  options: ReplayNetworkOptions,\n): Promise<ReplayNetworkRequestData> {\n  const now = Date.now();\n  const { startTimestamp = now, endTimestamp = now } = hint;\n\n  const {\n    url,\n    method,\n    status_code: statusCode = 0,\n    request_body_size: requestBodySize,\n    response_body_size: responseBodySize,\n  } = breadcrumb.data;\n\n  const captureDetails =\n    urlMatches(url, options.networkDetailAllowUrls) && !urlMatches(url, options.networkDetailDenyUrls);\n\n  const request = captureDetails\n    ? _getRequestInfo(options, hint.input, requestBodySize)\n    : buildSkippedNetworkRequestOrResponse(requestBodySize);\n  const response = await _getResponseInfo(captureDetails, options, hint.response, responseBodySize);\n\n  return {\n    startTimestamp,\n    endTimestamp,\n    url,\n    method,\n    statusCode,\n    request,\n    response,\n  };\n}\n\nfunction _getRequestInfo(\n  { networkCaptureBodies, networkRequestHeaders }: ReplayNetworkOptions,\n  input: FetchHint['input'] | undefined,\n  requestBodySize?: number,\n): ReplayNetworkRequestOrResponse | undefined {\n  const headers = input ? getRequestHeaders(input, networkRequestHeaders) : {};\n\n  if (!networkCaptureBodies) {\n    return buildNetworkRequestOrResponse(headers, requestBodySize, undefined);\n  }\n\n  // We only want to transmit string or string-like bodies\n  const requestBody = _getFetchRequestArgBody(input);\n  const [bodyStr, warning] = getBodyString(requestBody);\n  const data = buildNetworkRequestOrResponse(headers, requestBodySize, bodyStr);\n\n  if (warning) {\n    return mergeWarning(data, warning);\n  }\n\n  return data;\n}\n\n/** Exported only for tests. */\nexport async function _getResponseInfo(\n  captureDetails: boolean,\n  {\n    networkCaptureBodies,\n    networkResponseHeaders,\n  }: Pick<ReplayNetworkOptions, 'networkCaptureBodies' | 'networkResponseHeaders'>,\n  response: Response | undefined,\n  responseBodySize?: number,\n): Promise<ReplayNetworkRequestOrResponse | undefined> {\n  if (!captureDetails && responseBodySize !== undefined) {\n    return buildSkippedNetworkRequestOrResponse(responseBodySize);\n  }\n\n  const headers = response ? getAllHeaders(response.headers, networkResponseHeaders) : {};\n\n  if (!response || (!networkCaptureBodies && responseBodySize !== undefined)) {\n    return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);\n  }\n\n  const [bodyText, warning] = await _parseFetchResponseBody(response);\n  const result = getResponseData(bodyText, {\n    networkCaptureBodies,\n\n    responseBodySize,\n    captureDetails,\n    headers,\n  });\n\n  if (warning) {\n    return mergeWarning(result, warning);\n  }\n\n  return result;\n}\n\nfunction getResponseData(\n  bodyText: string | undefined,\n  {\n    networkCaptureBodies,\n    responseBodySize,\n    captureDetails,\n    headers,\n  }: {\n    captureDetails: boolean;\n    networkCaptureBodies: boolean;\n    responseBodySize: number | undefined;\n    headers: Record<string, string>;\n  },\n): ReplayNetworkRequestOrResponse | undefined {\n  try {\n    const size =\n      bodyText && bodyText.length && responseBodySize === undefined ? getBodySize(bodyText) : responseBodySize;\n\n    if (!captureDetails) {\n      return buildSkippedNetworkRequestOrResponse(size);\n    }\n\n    if (networkCaptureBodies) {\n      return buildNetworkRequestOrResponse(headers, size, bodyText);\n    }\n\n    return buildNetworkRequestOrResponse(headers, size, undefined);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to serialize response body');\n    // fallback\n    return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);\n  }\n}\n\nasync function _parseFetchResponseBody(response: Response): Promise<[string | undefined, NetworkMetaWarning?]> {\n  const res = _tryCloneResponse(response);\n\n  if (!res) {\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n\n  try {\n    const text = await _tryGetResponseText(res);\n    return [text];\n  } catch (error) {\n    if (error instanceof Error && error.message.indexOf('Timeout') > -1) {\n      DEBUG_BUILD && logger.warn('Parsing text body from response timed out');\n      return [undefined, 'BODY_PARSE_TIMEOUT'];\n    }\n\n    DEBUG_BUILD && logger.exception(error, 'Failed to get text body from response');\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n}\n\nfunction _getFetchRequestArgBody(fetchArgs: unknown[] = []): RequestInit['body'] | undefined {\n  // We only support getting the body from the fetch options\n  if (fetchArgs.length !== 2 || typeof fetchArgs[1] !== 'object') {\n    return undefined;\n  }\n\n  return (fetchArgs[1] as RequestInit).body;\n}\n\nfunction getAllHeaders(headers: Headers, allowedHeaders: string[]): Record<string, string> {\n  const allHeaders: Record<string, string> = {};\n\n  allowedHeaders.forEach(header => {\n    if (headers.get(header)) {\n      allHeaders[header] = headers.get(header) as string;\n    }\n  });\n\n  return allHeaders;\n}\n\nfunction getRequestHeaders(fetchArgs: unknown[], allowedHeaders: string[]): Record<string, string> {\n  if (fetchArgs.length === 1 && typeof fetchArgs[0] !== 'string') {\n    return getHeadersFromOptions(fetchArgs[0] as Request | RequestInit, allowedHeaders);\n  }\n\n  if (fetchArgs.length === 2) {\n    return getHeadersFromOptions(fetchArgs[1] as Request | RequestInit, allowedHeaders);\n  }\n\n  return {};\n}\n\nfunction getHeadersFromOptions(\n  input: Request | RequestInit | undefined,\n  allowedHeaders: string[],\n): Record<string, string> {\n  if (!input) {\n    return {};\n  }\n\n  const headers = input.headers;\n\n  if (!headers) {\n    return {};\n  }\n\n  if (headers instanceof Headers) {\n    return getAllHeaders(headers, allowedHeaders);\n  }\n\n  // We do not support this, as it is not really documented (anymore?)\n  if (Array.isArray(headers)) {\n    return {};\n  }\n\n  return getAllowedHeaders(headers, allowedHeaders);\n}\n\nfunction _tryCloneResponse(response: Response): Response | void {\n  try {\n    // We have to clone this, as the body can only be read once\n    return response.clone();\n  } catch (error) {\n    // this can throw if the response was already consumed before\n    DEBUG_BUILD && logger.exception(error, 'Failed to clone response body');\n  }\n}\n\n/**\n * Get the response body of a fetch request, or timeout after 500ms.\n * Fetch can return a streaming body, that may not resolve (or not for a long time).\n * If that happens, we rather abort after a short time than keep waiting for this.\n */\nfunction _tryGetResponseText(response: Response): Promise<string | undefined> {\n  return new Promise((resolve, reject) => {\n    const timeout = setTimeout(() => reject(new Error('Timeout while trying to read response body')), 500);\n\n    _getResponseText(response)\n      .then(\n        txt => resolve(txt),\n        reason => reject(reason),\n      )\n      .finally(() => clearTimeout(timeout));\n  });\n}\n\nasync function _getResponseText(response: Response): Promise<string> {\n  // Force this to be a promise, just to be safe\n  // eslint-disable-next-line no-return-await\n  return await response.text();\n}\n", "import { SENTRY_XHR_DATA_KEY } from '@sentry-internal/browser-utils';\nimport type { Breadcrumb, XhrBreadcrumbData } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../../debug-build';\nimport type {\n  NetworkMetaWarning,\n  ReplayContainer,\n  ReplayNetworkOptions,\n  ReplayNetworkRequestData,\n  XhrHint,\n} from '../../types';\nimport { logger } from '../../util/logger';\nimport { addNetworkBreadcrumb } from './addNetworkBreadcrumb';\nimport {\n  buildNetworkRequestOrResponse,\n  buildSkippedNetworkRequestOrResponse,\n  getAllowedHeaders,\n  getBodySize,\n  getBodyString,\n  makeNetworkReplayBreadcrumb,\n  mergeWarning,\n  parseContentLengthHeader,\n  urlMatches,\n} from './networkUtils';\n\n/**\n * Capture an XHR breadcrumb to a replay.\n * This adds additional data (where appropriate).\n */\nexport async function captureXhrBreadcrumbToReplay(\n  breadcrumb: Breadcrumb & { data: XhrBreadcrumbData },\n  hint: Partial<XhrHint>,\n  options: ReplayNetworkOptions & { replay: ReplayContainer },\n): Promise<void> {\n  try {\n    const data = _prepareXhrData(breadcrumb, hint, options);\n\n    // Create a replay performance entry from this breadcrumb\n    const result = makeNetworkReplayBreadcrumb('resource.xhr', data);\n    addNetworkBreadcrumb(options.replay, result);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to capture xhr breadcrumb');\n  }\n}\n\n/**\n * Enrich a breadcrumb with additional data.\n * This has to be sync & mutate the given breadcrumb,\n * as the breadcrumb is afterwards consumed by other handlers.\n */\nexport function enrichXhrBreadcrumb(\n  breadcrumb: Breadcrumb & { data: XhrBreadcrumbData },\n  hint: Partial<XhrHint>,\n): void {\n  const { xhr, input } = hint;\n\n  if (!xhr) {\n    return;\n  }\n\n  const reqSize = getBodySize(input);\n  const resSize = xhr.getResponseHeader('content-length')\n    ? parseContentLengthHeader(xhr.getResponseHeader('content-length'))\n    : _getBodySize(xhr.response, xhr.responseType);\n\n  if (reqSize !== undefined) {\n    breadcrumb.data.request_body_size = reqSize;\n  }\n  if (resSize !== undefined) {\n    breadcrumb.data.response_body_size = resSize;\n  }\n}\n\nfunction _prepareXhrData(\n  breadcrumb: Breadcrumb & { data: XhrBreadcrumbData },\n  hint: Partial<XhrHint>,\n  options: ReplayNetworkOptions,\n): ReplayNetworkRequestData | null {\n  const now = Date.now();\n  const { startTimestamp = now, endTimestamp = now, input, xhr } = hint;\n\n  const {\n    url,\n    method,\n    status_code: statusCode = 0,\n    request_body_size: requestBodySize,\n    response_body_size: responseBodySize,\n  } = breadcrumb.data;\n\n  if (!url) {\n    return null;\n  }\n\n  if (!xhr || !urlMatches(url, options.networkDetailAllowUrls) || urlMatches(url, options.networkDetailDenyUrls)) {\n    const request = buildSkippedNetworkRequestOrResponse(requestBodySize);\n    const response = buildSkippedNetworkRequestOrResponse(responseBodySize);\n    return {\n      startTimestamp,\n      endTimestamp,\n      url,\n      method,\n      statusCode,\n      request,\n      response,\n    };\n  }\n\n  const xhrInfo = xhr[SENTRY_XHR_DATA_KEY];\n  const networkRequestHeaders = xhrInfo\n    ? getAllowedHeaders(xhrInfo.request_headers, options.networkRequestHeaders)\n    : {};\n  const networkResponseHeaders = getAllowedHeaders(getResponseHeaders(xhr), options.networkResponseHeaders);\n\n  const [requestBody, requestWarning] = options.networkCaptureBodies ? getBodyString(input) : [undefined];\n  const [responseBody, responseWarning] = options.networkCaptureBodies ? _getXhrResponseBody(xhr) : [undefined];\n\n  const request = buildNetworkRequestOrResponse(networkRequestHeaders, requestBodySize, requestBody);\n  const response = buildNetworkRequestOrResponse(networkResponseHeaders, responseBodySize, responseBody);\n\n  return {\n    startTimestamp,\n    endTimestamp,\n    url,\n    method,\n    statusCode,\n    request: requestWarning ? mergeWarning(request, requestWarning) : request,\n    response: responseWarning ? mergeWarning(response, responseWarning) : response,\n  };\n}\n\nfunction getResponseHeaders(xhr: XMLHttpRequest): Record<string, string> {\n  const headers = xhr.getAllResponseHeaders();\n\n  if (!headers) {\n    return {};\n  }\n\n  return headers.split('\\r\\n').reduce((acc: Record<string, string>, line: string) => {\n    const [key, value] = line.split(': ') as [string, string | undefined];\n    if (value) {\n      acc[key.toLowerCase()] = value;\n    }\n    return acc;\n  }, {});\n}\n\nfunction _getXhrResponseBody(xhr: XMLHttpRequest): [string | undefined, NetworkMetaWarning?] {\n  // We collect errors that happen, but only log them if we can't get any response body\n  const errors: unknown[] = [];\n\n  try {\n    return [xhr.responseText];\n  } catch (e) {\n    errors.push(e);\n  }\n\n  // Try to manually parse the response body, if responseText fails\n  try {\n    return _parseXhrResponse(xhr.response, xhr.responseType);\n  } catch (e) {\n    errors.push(e);\n  }\n\n  DEBUG_BUILD && logger.warn('Failed to get xhr response body', ...errors);\n\n  return [undefined];\n}\n\n/**\n * Get the string representation of the XHR response.\n * Based on MDN, these are the possible types of the response:\n * string\n * ArrayBuffer\n * Blob\n * Document\n * POJO\n *\n * Exported only for tests.\n */\nexport function _parseXhrResponse(\n  body: XMLHttpRequest['response'],\n  responseType: XMLHttpRequest['responseType'],\n): [string | undefined, NetworkMetaWarning?] {\n  try {\n    if (typeof body === 'string') {\n      return [body];\n    }\n\n    if (body instanceof Document) {\n      return [body.body.outerHTML];\n    }\n\n    if (responseType === 'json' && body && typeof body === 'object') {\n      return [JSON.stringify(body)];\n    }\n\n    if (!body) {\n      return [undefined];\n    }\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to serialize body', body);\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n\n  DEBUG_BUILD && logger.info('Skipping network body because of body type', body);\n\n  return [undefined, 'UNPARSEABLE_BODY_TYPE'];\n}\n\nfunction _getBodySize(\n  body: XMLHttpRequest['response'],\n  responseType: XMLHttpRequest['responseType'],\n): number | undefined {\n  try {\n    const bodyStr = responseType === 'json' && body && typeof body === 'object' ? JSON.stringify(body) : body;\n    return getBodySize(bodyStr);\n  } catch {\n    return undefined;\n  }\n}\n", "import { getClient } from '@sentry/core';\nimport type { Breadcrumb, BreadcrumbHint, FetchBreadcrumbData, XhrBreadcrumbData } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { FetchHint, ReplayContainer, ReplayNetworkOptions, XhrHint } from '../types';\nimport { logger } from '../util/logger';\nimport { captureFetchBreadcrumbToReplay, enrichFetchBreadcrumb } from './util/fetchUtils';\nimport { captureXhrBreadcrumbToReplay, enrichXhrBreadcrumb } from './util/xhrUtils';\n\ninterface ExtendedNetworkBreadcrumbsOptions extends ReplayNetworkOptions {\n  replay: ReplayContainer;\n}\n\n/**\n * This method does two things:\n * - It enriches the regular XHR/fetch breadcrumbs with request/response size data\n * - It captures the XHR/fetch breadcrumbs to the replay\n *   (enriching it with further data that is _not_ added to the regular breadcrumbs)\n */\nexport function handleNetworkBreadcrumbs(replay: ReplayContainer): void {\n  const client = getClient();\n\n  try {\n    const {\n      networkDetailAllowUrls,\n      networkDetailDenyUrls,\n      networkCaptureBodies,\n      networkRequestHeaders,\n      networkResponseHeaders,\n    } = replay.getOptions();\n\n    const options: ExtendedNetworkBreadcrumbsOptions = {\n      replay,\n      networkDetailAllowUrls,\n      networkDetailDenyUrls,\n      networkCaptureBodies,\n      networkRequestHeaders,\n      networkResponseHeaders,\n    };\n\n    if (client) {\n      client.on('beforeAddBreadcrumb', (breadcrumb, hint) => beforeAddNetworkBreadcrumb(options, breadcrumb, hint));\n    }\n  } catch {\n    // Do nothing\n  }\n}\n\n/** just exported for tests */\nexport function beforeAddNetworkBreadcrumb(\n  options: ExtendedNetworkBreadcrumbsOptions,\n  breadcrumb: Breadcrumb,\n  hint?: BreadcrumbHint,\n): void {\n  if (!breadcrumb.data) {\n    return;\n  }\n\n  try {\n    if (_isXhrBreadcrumb(breadcrumb) && _isXhrHint(hint)) {\n      // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick\n      // Because the hook runs synchronously, and the breadcrumb is afterwards passed on\n      // So any async mutations to it will not be reflected in the final breadcrumb\n      enrichXhrBreadcrumb(breadcrumb, hint);\n\n      // This call should not reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      captureXhrBreadcrumbToReplay(breadcrumb, hint, options);\n    }\n\n    if (_isFetchBreadcrumb(breadcrumb) && _isFetchHint(hint)) {\n      // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick\n      // Because the hook runs synchronously, and the breadcrumb is afterwards passed on\n      // So any async mutations to it will not be reflected in the final breadcrumb\n      enrichFetchBreadcrumb(breadcrumb, hint);\n\n      // This call should not reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      captureFetchBreadcrumbToReplay(breadcrumb, hint, options);\n    }\n  } catch (e) {\n    DEBUG_BUILD && logger.exception(e, 'Error when enriching network breadcrumb');\n  }\n}\n\nfunction _isXhrBreadcrumb(breadcrumb: Breadcrumb): breadcrumb is Breadcrumb & { data: XhrBreadcrumbData } {\n  return breadcrumb.category === 'xhr';\n}\n\nfunction _isFetchBreadcrumb(breadcrumb: Breadcrumb): breadcrumb is Breadcrumb & { data: FetchBreadcrumbData } {\n  return breadcrumb.category === 'fetch';\n}\n\nfunction _isXhrHint(hint?: BreadcrumbHint): hint is XhrHint {\n  return hint && hint.xhr;\n}\n\nfunction _isFetchHint(hint?: BreadcrumbHint): hint is FetchHint {\n  return hint && hint.response;\n}\n", "import {\n  addClickKeypressInstrumentationHandler,\n  addHistoryInstrumentationHandler,\n} from '@sentry-internal/browser-utils';\nimport { addEventProcessor, getClient } from '@sentry/core';\nimport type { DynamicSamplingContext } from '@sentry/core';\n\nimport { handleAfterSendEvent } from '../coreHandlers/handleAfterSendEvent';\nimport { handleBeforeSendEvent } from '../coreHandlers/handleBeforeSendEvent';\nimport { handleBreadcrumbs } from '../coreHandlers/handleBreadcrumbs';\nimport { handleDomListener } from '../coreHandlers/handleDom';\nimport { handleGlobalEventListener } from '../coreHandlers/handleGlobalEvent';\nimport { handleHistorySpanListener } from '../coreHandlers/handleHistory';\nimport { handleNetworkBreadcrumbs } from '../coreHandlers/handleNetworkBreadcrumbs';\nimport type { ReplayContainer } from '../types';\n\n/**\n * Add global listeners that cannot be removed.\n */\nexport function addGlobalListeners(replay: ReplayContainer): void {\n  // Listeners from core SDK //\n  const client = getClient();\n\n  addClickKeypressInstrumentationHandler(handleDomListener(replay));\n  addHistoryInstrumentationHandler(handleHistorySpanListener(replay));\n  handleBreadcrumbs(replay);\n  handleNetworkBreadcrumbs(replay);\n\n  // Tag all (non replay) events that get sent to Sentry with the current\n  // replay ID so that we can reference them later in the UI\n  const eventProcessor = handleGlobalEventListener(replay);\n  addEventProcessor(eventProcessor);\n\n  // If a custom client has no hooks yet, we continue to use the \"old\" implementation\n  if (client) {\n    client.on('beforeSendEvent', handleBeforeSendEvent(replay));\n    client.on('afterSendEvent', handleAfterSendEvent(replay));\n    client.on('createDsc', (dsc: DynamicSamplingContext) => {\n      const replayId = replay.getSessionId();\n      // We do not want to set the DSC when in buffer mode, as that means the replay has not been sent (yet)\n      if (replayId && replay.isEnabled() && replay.recordingMode === 'session') {\n        // Ensure to check that the session is still active - it could have expired in the meanwhile\n        const isSessionActive = replay.checkAndHandleExpiredSession();\n        if (isSessionActive) {\n          dsc.replay_id = replayId;\n        }\n      }\n    });\n\n    client.on('spanStart', span => {\n      replay.lastActiveSpan = span;\n    });\n\n    // We may be missing the initial spanStart due to timing issues,\n    // so we capture it on finish again.\n    client.on('spanEnd', span => {\n      replay.lastActiveSpan = span;\n    });\n\n    // We want to flush replay\n    client.on('beforeSendFeedback', (feedbackEvent, options) => {\n      const replayId = replay.getSessionId();\n      if (options && options.includeReplay && replay.isEnabled() && replayId) {\n        // This should never reject\n        if (feedbackEvent.contexts && feedbackEvent.contexts.feedback) {\n          feedbackEvent.contexts.feedback.replay_id = replayId;\n        }\n      }\n    });\n  }\n}\n", "import { WINDOW } from '../constants';\nimport type { AddEventResult, MemoryData, ReplayContainer, ReplayPerformanceEntry } from '../types';\nimport { createPerformanceSpans } from './createPerformanceSpans';\n\ntype ReplayMemoryEntry = ReplayPerformanceEntry<MemoryData> & { data: { memory: MemoryInfo } };\n\ninterface MemoryInfo {\n  jsHeapSizeLimit: number;\n  totalJSHeapSize: number;\n  usedJSHeapSize: number;\n}\n\n/**\n * Create a \"span\" for the total amount of memory being used by JS objects\n * (including v8 internal objects).\n */\nexport async function addMemoryEntry(replay: ReplayContainer): Promise<Array<AddEventResult | null>> {\n  // window.performance.memory is a non-standard API and doesn't work on all browsers, so we try-catch this\n  try {\n    return Promise.all(\n      createPerformanceSpans(replay, [\n        // @ts-expect-error memory doesn't exist on type Performance as the API is non-standard (we check that it exists above)\n        createMemoryEntry(WINDOW.performance.memory),\n      ]),\n    );\n  } catch (error) {\n    // Do nothing\n    return [];\n  }\n}\n\nfunction createMemoryEntry(memoryEntry: MemoryInfo): ReplayMemoryEntry {\n  const { jsHeapSizeLimit, totalJSHeapSize, usedJSHeapSize } = memoryEntry;\n  // we don't want to use `getAbsoluteTime` because it adds the event time to the\n  // time origin, so we get the current timestamp instead\n  const time = Date.now() / 1000;\n  return {\n    type: 'memory',\n    name: 'memory',\n    start: time,\n    end: time,\n    data: {\n      memory: {\n        jsHeapSizeLimit,\n        totalJSHeapSize,\n        usedJSHeapSize,\n      },\n    },\n  };\n}\n", "import { setTimeout } from '@sentry-internal/browser-utils';\n\ntype DebouncedCallback = {\n  (): void | unknown;\n  flush: () => void | unknown;\n  cancel: () => void;\n};\ntype CallbackFunction = () => unknown;\ntype DebounceOptions = { maxWait?: number };\n\n/**\n * Heavily simplified debounce function based on lodash.debounce.\n *\n * This function takes a callback function (@param fun) and delays its invocation\n * by @param wait milliseconds. Optionally, a maxWait can be specified in @param options,\n * which ensures that the callback is invoked at least once after the specified max. wait time.\n *\n * @param func the function whose invocation is to be debounced\n * @param wait the minimum time until the function is invoked after it was called once\n * @param options the options object, which can contain the `maxWait` property\n *\n * @returns the debounced version of the function, which needs to be called at least once to start the\n *          debouncing process. Subsequent calls will reset the debouncing timer and, in case @paramfunc\n *          was already invoked in the meantime, return @param func's return value.\n *          The debounced function has two additional properties:\n *          - `flush`: Invokes the debounced function immediately and returns its return value\n *          - `cancel`: Cancels the debouncing process and resets the debouncing timer\n */\nexport function debounce(func: CallbackFunction, wait: number, options?: DebounceOptions): DebouncedCallback {\n  let callbackReturnValue: unknown;\n\n  let timerId: ReturnType<typeof setTimeout> | undefined;\n  let maxTimerId: ReturnType<typeof setTimeout> | undefined;\n\n  const maxWait = options && options.maxWait ? Math.max(options.maxWait, wait) : 0;\n\n  function invokeFunc(): unknown {\n    cancelTimers();\n    callbackReturnValue = func();\n    return callbackReturnValue;\n  }\n\n  function cancelTimers(): void {\n    timerId !== undefined && clearTimeout(timerId);\n    maxTimerId !== undefined && clearTimeout(maxTimerId);\n    timerId = maxTimerId = undefined;\n  }\n\n  function flush(): unknown {\n    if (timerId !== undefined || maxTimerId !== undefined) {\n      return invokeFunc();\n    }\n    return callbackReturnValue;\n  }\n\n  function debounced(): unknown {\n    if (timerId) {\n      clearTimeout(timerId);\n    }\n    timerId = setTimeout(invokeFunc, wait);\n\n    if (maxWait && maxTimerId === undefined) {\n      maxTimerId = setTimeout(invokeFunc, maxWait);\n    }\n\n    return callbackReturnValue;\n  }\n\n  debounced.cancel = cancelTimers;\n  debounced.flush = flush;\n  return debounced;\n}\n", "import { GLOBAL_OBJ } from '@sentry/core';\n\nconst NAVIGATOR = GLOBAL_OBJ.navigator;\n\n/**\n *  Disable sampling mousemove events on iOS browsers as this can cause blocking the main thread\n *  https://github.com/getsentry/sentry-javascript/issues/14534\n */\nexport function getRecordingSamplingOptions(): Partial<{ sampling: { mousemove: boolean } }> {\n  if (\n    /iPhone|iPad|iPod/i.test((NAVIGATOR && NAVIGATOR.userAgent) || '') ||\n    (/Macintosh/i.test((NAVIGATOR && NAVIGATOR.userAgent) || '') &&\n      NAVIGATOR &&\n      NAVIGATOR.maxTouchPoints &&\n      NAVIGATOR.maxTouchPoints > 1)\n  ) {\n    return {\n      sampling: {\n        mousemove: false,\n      },\n    };\n  }\n\n  return {};\n}\n", "import { EventType } from '@sentry-internal/rrweb';\n\nimport { updateClickDetectorForRecordingEvent } from '../coreHandlers/handleClick';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { saveSession } from '../session/saveSession';\nimport type { RecordingEvent, ReplayContainer, ReplayOptionFrameEvent } from '../types';\nimport { addEventSync } from './addEvent';\nimport { logger } from './logger';\n\ntype RecordingEmitCallback = (event: RecordingEvent, isCheckout?: boolean) => void;\n\n/**\n * Handler for recording events.\n *\n * Adds to event buffer, and has varying flushing behaviors if the event was a checkout.\n */\nexport function getHandleRecordingEmit(replay: ReplayContainer): RecordingEmitCallback {\n  let hadFirstEvent = false;\n\n  return (event: RecordingEvent, _isCheckout?: boolean) => {\n    // If this is false, it means session is expired, create and a new session and wait for checkout\n    if (!replay.checkAndHandleExpiredSession()) {\n      DEBUG_BUILD && logger.warn('Received replay event after session expired.');\n\n      return;\n    }\n\n    // `_isCheckout` is only set when the checkout is due to `checkoutEveryNms`\n    // We also want to treat the first event as a checkout, so we handle this specifically here\n    const isCheckout = _isCheckout || !hadFirstEvent;\n    hadFirstEvent = true;\n\n    if (replay.clickDetector) {\n      updateClickDetectorForRecordingEvent(replay.clickDetector, event);\n    }\n\n    // The handler returns `true` if we do not want to trigger debounced flush, `false` if we want to debounce flush.\n    replay.addUpdate(() => {\n      // The session is always started immediately on pageload/init, but for\n      // error-only replays, it should reflect the most recent checkout\n      // when an error occurs. Clear any state that happens before this current\n      // checkout. This needs to happen before `addEvent()` which updates state\n      // dependent on this reset.\n      if (replay.recordingMode === 'buffer' && isCheckout) {\n        replay.setInitialState();\n      }\n\n      // If the event is not added (e.g. due to being paused, disabled, or out of the max replay duration),\n      // Skip all further steps\n      if (!addEventSync(replay, event, isCheckout)) {\n        // Return true to skip scheduling a debounced flush\n        return true;\n      }\n\n      // Different behavior for full snapshots (type=2), ignore other event types\n      // See https://github.com/rrweb-io/rrweb/blob/d8f9290ca496712aa1e7d472549480c4e7876594/packages/rrweb/src/types.ts#L16\n      if (!isCheckout) {\n        return false;\n      }\n\n      const session = replay.session;\n\n      // Additionally, create a meta event that will capture certain SDK settings.\n      // In order to handle buffer mode, this needs to either be done when we\n      // receive checkout events or at flush time. We have an experimental mode\n      // to perform multiple checkouts a session (the idea is to improve\n      // seeking during playback), so also only include if segmentId is 0\n      // (handled in `addSettingsEvent`).\n      //\n      // `isCheckout` is always true, but want to be explicit that it should\n      // only be added for checkouts\n      addSettingsEvent(replay, isCheckout);\n\n      // When in buffer mode, make sure we adjust the session started date to the current earliest event of the buffer\n      // this should usually be the timestamp of the checkout event, but to be safe...\n      if (replay.recordingMode === 'buffer' && session && replay.eventBuffer) {\n        const earliestEvent = replay.eventBuffer.getEarliestTimestamp();\n        if (earliestEvent) {\n          DEBUG_BUILD &&\n            logger.info(`Updating session start time to earliest event in buffer to ${new Date(earliestEvent)}`);\n\n          session.started = earliestEvent;\n\n          if (replay.getOptions().stickySession) {\n            saveSession(session);\n          }\n        }\n      }\n\n      // If there is a previousSessionId after a full snapshot occurs, then\n      // the replay session was started due to session expiration. The new session\n      // is started before triggering a new checkout and contains the id\n      // of the previous session. Do not immediately flush in this case\n      // to avoid capturing only the checkout and instead the replay will\n      // be captured if they perform any follow-up actions.\n      if (session && session.previousSessionId) {\n        return true;\n      }\n\n      if (replay.recordingMode === 'session') {\n        // If the full snapshot is due to an initial load, we will not have\n        // a previous session ID. In this case, we want to buffer events\n        // for a set amount of time before flushing. This can help avoid\n        // capturing replays of users that immediately close the window.\n\n        // This should never reject\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        void replay.flush();\n      }\n\n      return true;\n    });\n  };\n}\n\n/**\n * Exported for tests\n */\nexport function createOptionsEvent(replay: ReplayContainer): ReplayOptionFrameEvent {\n  const options = replay.getOptions();\n  return {\n    type: EventType.Custom,\n    timestamp: Date.now(),\n    data: {\n      tag: 'options',\n      payload: {\n        shouldRecordCanvas: replay.isRecordingCanvas(),\n        sessionSampleRate: options.sessionSampleRate,\n        errorSampleRate: options.errorSampleRate,\n        useCompressionOption: options.useCompression,\n        blockAllMedia: options.blockAllMedia,\n        maskAllText: options.maskAllText,\n        maskAllInputs: options.maskAllInputs,\n        useCompression: replay.eventBuffer ? replay.eventBuffer.type === 'worker' : false,\n        networkDetailHasUrls: options.networkDetailAllowUrls.length > 0,\n        networkCaptureBodies: options.networkCaptureBodies,\n        networkRequestHasHeaders: options.networkRequestHeaders.length > 0,\n        networkResponseHasHeaders: options.networkResponseHeaders.length > 0,\n      },\n    },\n  };\n}\n\n/**\n * Add a \"meta\" event that contains a simplified view on current configuration\n * options. This should only be included on the first segment of a recording.\n */\nfunction addSettingsEvent(replay: ReplayContainer, isCheckout?: boolean): void {\n  // Only need to add this event when sending the first segment\n  if (!isCheckout || !replay.session || replay.session.segmentId !== 0) {\n    return;\n  }\n\n  addEventSync(replay, createOptionsEvent(replay), false);\n}\n", "import { createEnvelope, createEventEnvelopeHeaders, getSdkMetadataForEnvelopeHeader } from '@sentry/core';\nimport type { DsnComponents, ReplayEnvelope, ReplayEvent, ReplayRecordingData } from '@sentry/core';\n\n/**\n * Create a replay envelope ready to be sent.\n * This includes both the replay event, as well as the recording data.\n */\nexport function createReplayEnvelope(\n  replayEvent: ReplayEvent,\n  recordingData: ReplayRecordingData,\n  dsn: DsnComponents,\n  tunnel?: string,\n): ReplayEnvelope {\n  return createEnvelope<ReplayEnvelope>(\n    createEventEnvelopeHeaders(replayEvent, getSdkMetadataForEnvelopeHeader(replayEvent), tunnel, dsn),\n    [\n      [{ type: 'replay_event' }, replayEvent],\n      [\n        {\n          type: 'replay_recording',\n          // If string then we need to encode to UTF8, otherwise will have\n          // wrong size. TextEncoder has similar browser support to\n          // MutationObserver, although it does not accept IE11.\n          length:\n            typeof recordingData === 'string' ? new TextEncoder().encode(recordingData).length : recordingData.length,\n        },\n        recordingData,\n      ],\n    ],\n  );\n}\n", "import type { ReplayRecordingData } from '@sentry/core';\n\n/**\n * Prepare the recording data ready to be sent.\n */\nexport function prepareRecordingData({\n  recordingData,\n  headers,\n}: {\n  recordingData: ReplayRecordingData;\n  headers: Record<string, unknown>;\n}): ReplayRecordingData {\n  let payloadWithSequence;\n\n  // XXX: newline is needed to separate sequence id from events\n  const replayHeaders = `${JSON.stringify(headers)}\n`;\n\n  if (typeof recordingData === 'string') {\n    payloadWithSequence = `${replayHeaders}${recordingData}`;\n  } else {\n    const enc = new TextEncoder();\n    // XXX: newline is needed to separate sequence id from events\n    const sequence = enc.encode(replayHeaders);\n    // Merge the two Uint8Arrays\n    payloadWithSequence = new Uint8Array(sequence.length + recordingData.length);\n    payloadWithSequence.set(sequence);\n    payloadWithSequence.set(recordingData, sequence.length);\n  }\n\n  return payloadWithSequence;\n}\n", "import type { IntegrationIndex } from '@sentry/core';\nimport { getIsolationScope, prepareEvent } from '@sentry/core';\nimport type { Client, EventHint, ReplayEvent, Scope } from '@sentry/core';\n\n/**\n * Prepare a replay event & enrich it with the SDK metadata.\n */\nexport async function prepareReplayEvent({\n  client,\n  scope,\n  replayId: event_id,\n  event,\n}: {\n  client: Client & { _integrations?: IntegrationIndex };\n  scope: Scope;\n  replayId: string;\n  event: ReplayEvent;\n}): Promise<ReplayEvent | null> {\n  const integrations =\n    typeof client._integrations === 'object' && client._integrations !== null && !Array.isArray(client._integrations)\n      ? Object.keys(client._integrations)\n      : undefined;\n\n  const eventHint: EventHint = { event_id, integrations };\n\n  client.emit('preprocessEvent', event, eventHint);\n\n  const preparedEvent = (await prepareEvent(\n    client.getOptions(),\n    event,\n    eventHint,\n    scope,\n    client,\n    getIsolationScope(),\n  )) as ReplayEvent | null;\n\n  // If e.g. a global event processor returned null\n  if (!preparedEvent) {\n    return null;\n  }\n\n  // This normally happens in browser client \"_prepareEvent\"\n  // but since we do not use this private method from the client, but rather the plain import\n  // we need to do this manually.\n  preparedEvent.platform = preparedEvent.platform || 'javascript';\n\n  // extract the SDK name because `client._prepareEvent` doesn't add it to the event\n  const metadata = client.getSdkMetadata();\n  const { name, version } = (metadata && metadata.sdk) || {};\n\n  preparedEvent.sdk = {\n    ...preparedEvent.sdk,\n    name: name || 'sentry.javascript.unknown',\n    version: version || '0.0.0',\n  };\n\n  return preparedEvent;\n}\n", "import type { RateLimits, ReplayEvent, TransportMakeRequestResponse } from '@sentry/core';\nimport { getClient, getCurrentScope, isRateLimited, resolvedSyncPromise, updateRateLimits } from '@sentry/core';\nimport { REPLAY_EVENT_NAME, UNABLE_TO_SEND_REPLAY } from '../constants';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { SendReplayData } from '../types';\nimport { createReplayEnvelope } from './createReplayEnvelope';\nimport { logger } from './logger';\nimport { prepareRecordingData } from './prepareRecordingData';\nimport { prepareReplayEvent } from './prepareReplayEvent';\n\n/**\n * Send replay attachment using `fetch()`\n */\nexport async function sendReplayRequest({\n  recordingData,\n  replayId,\n  segmentId: segment_id,\n  eventContext,\n  timestamp,\n  session,\n}: SendReplayData): Promise<TransportMakeRequestResponse> {\n  const preparedRecordingData = prepareRecordingData({\n    recordingData,\n    headers: {\n      segment_id,\n    },\n  });\n\n  const { urls, errorIds, traceIds, initialTimestamp } = eventContext;\n\n  const client = getClient();\n  const scope = getCurrentScope();\n  const transport = client && client.getTransport();\n  const dsn = client && client.getDsn();\n\n  if (!client || !transport || !dsn || !session.sampled) {\n    return resolvedSyncPromise({});\n  }\n\n  const baseEvent: ReplayEvent = {\n    type: REPLAY_EVENT_NAME,\n    replay_start_timestamp: initialTimestamp / 1000,\n    timestamp: timestamp / 1000,\n    error_ids: errorIds,\n    trace_ids: traceIds,\n    urls,\n    replay_id: replayId,\n    segment_id,\n    replay_type: session.sampled,\n  };\n\n  const replayEvent = await prepareReplayEvent({ scope, client, replayId, event: baseEvent });\n\n  if (!replayEvent) {\n    // Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions\n    client.recordDroppedEvent('event_processor', 'replay', baseEvent);\n    DEBUG_BUILD && logger.info('An event processor returned `null`, will not send event.');\n    return resolvedSyncPromise({});\n  }\n\n  /*\n  For reference, the fully built event looks something like this:\n  {\n      \"type\": \"replay_event\",\n      \"timestamp\": 1670837008.634,\n      \"error_ids\": [\n          \"errorId\"\n      ],\n      \"trace_ids\": [\n          \"traceId\"\n      ],\n      \"urls\": [\n          \"https://example.com\"\n      ],\n      \"replay_id\": \"eventId\",\n      \"segment_id\": 3,\n      \"replay_type\": \"error\",\n      \"platform\": \"javascript\",\n      \"event_id\": \"eventId\",\n      \"environment\": \"production\",\n      \"sdk\": {\n          \"integrations\": [\n              \"BrowserTracing\",\n              \"Replay\"\n          ],\n          \"name\": \"sentry.javascript.browser\",\n          \"version\": \"7.25.0\"\n      },\n      \"sdkProcessingMetadata\": {},\n      \"contexts\": {\n      },\n  }\n  */\n\n  // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to\n  // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may\n  // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid\n  // of this `delete`, lest we miss putting it back in the next time the property is in use.)\n  delete replayEvent.sdkProcessingMetadata;\n\n  const envelope = createReplayEnvelope(replayEvent, preparedRecordingData, dsn, client.getOptions().tunnel);\n\n  let response: TransportMakeRequestResponse;\n\n  try {\n    response = await transport.send(envelope);\n  } catch (err) {\n    const error = new Error(UNABLE_TO_SEND_REPLAY);\n\n    try {\n      // In case browsers don't allow this property to be writable\n      // @ts-expect-error This needs lib es2022 and newer\n      error.cause = err;\n    } catch {\n      // nothing to do\n    }\n    throw error;\n  }\n\n  // If the status code is invalid, we want to immediately stop & not retry\n  if (typeof response.statusCode === 'number' && (response.statusCode < 200 || response.statusCode >= 300)) {\n    throw new TransportStatusCodeError(response.statusCode);\n  }\n\n  const rateLimits = updateRateLimits({}, response);\n  if (isRateLimited(rateLimits, 'replay')) {\n    throw new RateLimitError(rateLimits);\n  }\n\n  return response;\n}\n\n/**\n * This error indicates that the transport returned an invalid status code.\n */\nexport class TransportStatusCodeError extends Error {\n  public constructor(statusCode: number) {\n    super(`Transport returned status code ${statusCode}`);\n  }\n}\n\n/**\n * This error indicates that we hit a rate limit API error.\n */\nexport class RateLimitError extends Error {\n  public rateLimits: RateLimits;\n\n  public constructor(rateLimits: RateLimits) {\n    super('Rate limit hit');\n    this.rateLimits = rateLimits;\n  }\n}\n", "import { setTimeout } from '@sentry-internal/browser-utils';\nimport { setContext } from '@sentry/core';\n\nimport { RETRY_BASE_INTERVAL, RETRY_MAX_COUNT, UNABLE_TO_SEND_REPLAY } from '../constants';\nimport type { SendReplayData } from '../types';\nimport { RateLimitError, TransportStatusCodeError, sendReplayRequest } from './sendReplayRequest';\n\n/**\n * Finalize and send the current replay event to Sentry\n */\nexport async function sendReplay(\n  replayData: SendReplayData,\n  retryConfig = {\n    count: 0,\n    interval: RETRY_BASE_INTERVAL,\n  },\n): Promise<unknown> {\n  const { recordingData, onError } = replayData;\n\n  // short circuit if there's no events to upload (this shouldn't happen as _runFlush makes this check)\n  if (!recordingData.length) {\n    return;\n  }\n\n  try {\n    await sendReplayRequest(replayData);\n    return true;\n  } catch (err) {\n    if (err instanceof TransportStatusCodeError || err instanceof RateLimitError) {\n      throw err;\n    }\n\n    // Capture error for every failed replay\n    setContext('Replays', {\n      _retryCount: retryConfig.count,\n    });\n\n    if (onError) {\n      onError(err);\n    }\n\n    // If an error happened here, it's likely that uploading the attachment\n    // failed, we'll can retry with the same events payload\n    if (retryConfig.count >= RETRY_MAX_COUNT) {\n      const error = new Error(`${UNABLE_TO_SEND_REPLAY} - max retries exceeded`);\n\n      try {\n        // In case browsers don't allow this property to be writable\n        // @ts-expect-error This needs lib es2022 and newer\n        error.cause = err;\n      } catch {\n        // nothing to do\n      }\n\n      throw error;\n    }\n\n    // will retry in intervals of 5, 10, 30\n    retryConfig.interval *= ++retryConfig.count;\n\n    return new Promise((resolve, reject) => {\n      setTimeout(async () => {\n        try {\n          await sendReplay(replayData, retryConfig);\n          resolve(true);\n        } catch (err) {\n          reject(err);\n        }\n      }, retryConfig.interval);\n    });\n  }\n}\n", "export const THROTTLED = '__THROTTLED';\nexport const SKIPPED = '__SKIPPED';\n\n/**\n * Create a throttled function off a given function.\n * When calling the throttled function, it will call the original function only\n * if it hasn't been called more than `maxCount` times in the last `durationSeconds`.\n *\n * Returns `THROTTLED` if throttled for the first time, after that `SKIPPED`,\n * or else the return value of the original function.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function throttle<T extends (...rest: any[]) => any>(\n  fn: T,\n  maxCount: number,\n  durationSeconds: number,\n): (...rest: Parameters<T>) => ReturnType<T> | typeof THROTTLED | typeof SKIPPED {\n  const counter = new Map<number, number>();\n\n  const _cleanup = (now: number): void => {\n    const threshold = now - durationSeconds;\n    counter.forEach((_value, key) => {\n      if (key < threshold) {\n        counter.delete(key);\n      }\n    });\n  };\n\n  const _getTotalCount = (): number => {\n    return [...counter.values()].reduce((a, b) => a + b, 0);\n  };\n\n  let isThrottled = false;\n\n  return (...rest: Parameters<T>): ReturnType<T> | typeof THROTTLED | typeof SKIPPED => {\n    // Date in second-precision, which we use as basis for the throttling\n    const now = Math.floor(Date.now() / 1000);\n\n    // First, make sure to delete any old entries\n    _cleanup(now);\n\n    // If already over limit, do nothing\n    if (_getTotalCount() >= maxCount) {\n      const wasThrottled = isThrottled;\n      isThrottled = true;\n      return wasThrottled ? SKIPPED : THROTTLED;\n    }\n\n    isThrottled = false;\n    const count = counter.get(now) || 0;\n    counter.set(now, count + 1);\n\n    return fn(...rest);\n  };\n}\n", "/* eslint-disable max-lines */ // TODO: We might want to split this file up\nimport { EventType, record } from '@sentry-internal/rrweb';\nimport type { ReplayRecordingMode, Span } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, getClient, getRootSpan, spanToJSON } from '@sentry/core';\nimport {\n  BUFFER_CHECKOUT_TIME,\n  SESSION_IDLE_EXPIRE_DURATION,\n  SESSION_IDLE_PAUSE_DURATION,\n  SLOW_CLICK_SCROLL_TIMEOUT,\n  SLOW_CLICK_THRESHOLD,\n  WINDOW,\n} from './constants';\nimport { ClickDetector } from './coreHandlers/handleClick';\nimport { handleKeyboardEvent } from './coreHandlers/handleKeyboardEvent';\nimport { setupPerformanceObserver } from './coreHandlers/performanceObserver';\nimport { DEBUG_BUILD } from './debug-build';\nimport { createEventBuffer } from './eventBuffer';\nimport { clearSession } from './session/clearSession';\nimport { loadOrCreateSession } from './session/loadOrCreateSession';\nimport { saveSession } from './session/saveSession';\nimport { shouldRefreshSession } from './session/shouldRefreshSession';\nimport type {\n  AddEventResult,\n  AddUpdateCallback,\n  AllPerformanceEntry,\n  AllPerformanceEntryData,\n  EventBuffer,\n  InternalEventContext,\n  PopEventContext,\n  RecordingEvent,\n  RecordingOptions,\n  ReplayBreadcrumbFrame,\n  ReplayCanvasIntegrationOptions,\n  ReplayContainer as ReplayContainerInterface,\n  ReplayPerformanceEntry,\n  ReplayPluginOptions,\n  SendBufferedReplayOptions,\n  Session,\n  SlowClickConfig,\n  Timeouts,\n} from './types';\nimport { ReplayEventTypeCustom } from './types';\nimport { addEvent, addEventSync } from './util/addEvent';\nimport { addGlobalListeners } from './util/addGlobalListeners';\nimport { addMemoryEntry } from './util/addMemoryEntry';\nimport { createBreadcrumb } from './util/createBreadcrumb';\nimport { createPerformanceEntries } from './util/createPerformanceEntries';\nimport { createPerformanceSpans } from './util/createPerformanceSpans';\nimport { debounce } from './util/debounce';\nimport { getRecordingSamplingOptions } from './util/getRecordingSamplingOptions';\nimport { getHandleRecordingEmit } from './util/handleRecordingEmit';\nimport { isExpired } from './util/isExpired';\nimport { isSessionExpired } from './util/isSessionExpired';\nimport { logger } from './util/logger';\nimport { resetReplayIdOnDynamicSamplingContext } from './util/resetReplayIdOnDynamicSamplingContext';\nimport { sendReplay } from './util/sendReplay';\nimport { RateLimitError } from './util/sendReplayRequest';\nimport type { SKIPPED } from './util/throttle';\nimport { THROTTLED, throttle } from './util/throttle';\n\n/**\n * The main replay container class, which holds all the state and methods for recording and sending replays.\n */\nexport class ReplayContainer implements ReplayContainerInterface {\n  public eventBuffer: EventBuffer | null;\n\n  public performanceEntries: AllPerformanceEntry[];\n\n  public replayPerformanceEntries: ReplayPerformanceEntry<AllPerformanceEntryData>[];\n\n  public session: Session | undefined;\n\n  public clickDetector: ClickDetector | undefined;\n\n  /**\n   * Recording can happen in one of two modes:\n   *   - session: Record the whole session, sending it continuously\n   *   - buffer: Always keep the last 60s of recording, requires:\n   *     - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs\n   *     - or calling `flush()` to send the replay\n   */\n  public recordingMode: ReplayRecordingMode;\n\n  /**\n   * The current or last active span.\n   * This is only available when performance is enabled.\n   */\n  public lastActiveSpan?: Span;\n\n  /**\n   * These are here so we can overwrite them in tests etc.\n   * @hidden\n   */\n  public readonly timeouts: Timeouts;\n\n  /** The replay has to be manually started, because no sample rate (neither session or error) was provided. */\n  private _requiresManualStart: boolean;\n\n  private _throttledAddEvent: (\n    event: RecordingEvent,\n    isCheckout?: boolean,\n  ) => typeof THROTTLED | typeof SKIPPED | Promise<AddEventResult | null>;\n\n  /**\n   * Options to pass to `rrweb.record()`\n   */\n  private readonly _recordingOptions: RecordingOptions;\n\n  private readonly _options: ReplayPluginOptions;\n\n  private _performanceCleanupCallback?: () => void;\n\n  private _debouncedFlush: ReturnType<typeof debounce>;\n  private _flushLock: Promise<unknown> | undefined;\n\n  /**\n   * Timestamp of the last user activity. This lives across sessions.\n   */\n  private _lastActivity: number;\n\n  /**\n   * Is the integration currently active?\n   */\n  private _isEnabled: boolean;\n\n  /**\n   * Paused is a state where:\n   * - DOM Recording is not listening at all\n   * - Nothing will be added to event buffer (e.g. core SDK events)\n   */\n  private _isPaused: boolean;\n\n  /**\n   * Have we attached listeners to the core SDK?\n   * Note we have to track this as there is no way to remove instrumentation handlers.\n   */\n  private _hasInitializedCoreListeners: boolean;\n\n  /**\n   * Function to stop recording\n   */\n  private _stopRecording: ReturnType<typeof record> | undefined;\n\n  private _context: InternalEventContext;\n\n  /**\n   * Internal use for canvas recording options\n   */\n  private _canvas: ReplayCanvasIntegrationOptions | undefined;\n\n  public constructor({\n    options,\n    recordingOptions,\n  }: {\n    options: ReplayPluginOptions;\n    recordingOptions: RecordingOptions;\n  }) {\n    this.eventBuffer = null;\n    this.performanceEntries = [];\n    this.replayPerformanceEntries = [];\n    this.recordingMode = 'session';\n    this.timeouts = {\n      sessionIdlePause: SESSION_IDLE_PAUSE_DURATION,\n      sessionIdleExpire: SESSION_IDLE_EXPIRE_DURATION,\n    } as const;\n    this._lastActivity = Date.now();\n    this._isEnabled = false;\n    this._isPaused = false;\n    this._requiresManualStart = false;\n    this._hasInitializedCoreListeners = false;\n    this._context = {\n      errorIds: new Set(),\n      traceIds: new Set(),\n      urls: [],\n      initialTimestamp: Date.now(),\n      initialUrl: '',\n    };\n\n    this._recordingOptions = recordingOptions;\n    this._options = options;\n\n    this._debouncedFlush = debounce(() => this._flush(), this._options.flushMinDelay, {\n      maxWait: this._options.flushMaxDelay,\n    });\n\n    this._throttledAddEvent = throttle(\n      (event: RecordingEvent, isCheckout?: boolean) => addEvent(this, event, isCheckout),\n      // Max 300 events...\n      300,\n      // ... per 5s\n      5,\n    );\n\n    const { slowClickTimeout, slowClickIgnoreSelectors } = this.getOptions();\n\n    const slowClickConfig: SlowClickConfig | undefined = slowClickTimeout\n      ? {\n          threshold: Math.min(SLOW_CLICK_THRESHOLD, slowClickTimeout),\n          timeout: slowClickTimeout,\n          scrollTimeout: SLOW_CLICK_SCROLL_TIMEOUT,\n          ignoreSelector: slowClickIgnoreSelectors ? slowClickIgnoreSelectors.join(',') : '',\n        }\n      : undefined;\n\n    if (slowClickConfig) {\n      this.clickDetector = new ClickDetector(this, slowClickConfig);\n    }\n\n    // Configure replay logger w/ experimental options\n    if (DEBUG_BUILD) {\n      const experiments = options._experiments;\n      logger.setConfig({\n        captureExceptions: !!experiments.captureExceptions,\n        traceInternals: !!experiments.traceInternals,\n      });\n    }\n  }\n\n  /** Get the event context. */\n  public getContext(): InternalEventContext {\n    return this._context;\n  }\n\n  /** If recording is currently enabled. */\n  public isEnabled(): boolean {\n    return this._isEnabled;\n  }\n\n  /** If recording is currently paused. */\n  public isPaused(): boolean {\n    return this._isPaused;\n  }\n\n  /**\n   * Determine if canvas recording is enabled\n   */\n  public isRecordingCanvas(): boolean {\n    return Boolean(this._canvas);\n  }\n\n  /** Get the replay integration options. */\n  public getOptions(): ReplayPluginOptions {\n    return this._options;\n  }\n\n  /** A wrapper to conditionally capture exceptions. */\n  public handleException(error: unknown): void {\n    DEBUG_BUILD && logger.exception(error);\n    if (this._options.onError) {\n      this._options.onError(error);\n    }\n  }\n\n  /**\n   * Initializes the plugin based on sampling configuration. Should not be\n   * called outside of constructor.\n   */\n  public initializeSampling(previousSessionId?: string): void {\n    const { errorSampleRate, sessionSampleRate } = this._options;\n\n    // If neither sample rate is > 0, then do nothing - user will need to call one of\n    // `start()` or `startBuffering` themselves.\n    const requiresManualStart = errorSampleRate <= 0 && sessionSampleRate <= 0;\n\n    this._requiresManualStart = requiresManualStart;\n\n    if (requiresManualStart) {\n      return;\n    }\n\n    // Otherwise if there is _any_ sample rate set, try to load an existing\n    // session, or create a new one.\n    this._initializeSessionForSampling(previousSessionId);\n\n    if (!this.session) {\n      // This should not happen, something wrong has occurred\n      DEBUG_BUILD && logger.exception(new Error('Unable to initialize and create session'));\n      return;\n    }\n\n    if (this.session.sampled === false) {\n      // This should only occur if `errorSampleRate` is 0 and was unsampled for\n      // session-based replay. In this case there is nothing to do.\n      return;\n    }\n\n    // If segmentId > 0, it means we've previously already captured this session\n    // In this case, we still want to continue in `session` recording mode\n    this.recordingMode = this.session.sampled === 'buffer' && this.session.segmentId === 0 ? 'buffer' : 'session';\n\n    DEBUG_BUILD && logger.infoTick(`Starting replay in ${this.recordingMode} mode`);\n\n    this._initializeRecording();\n  }\n\n  /**\n   * Start a replay regardless of sampling rate. Calling this will always\n   * create a new session. Will log a message if replay is already in progress.\n   *\n   * Creates or loads a session, attaches listeners to varying events (DOM,\n   * _performanceObserver, Recording, Sentry SDK, etc)\n   */\n  public start(): void {\n    if (this._isEnabled && this.recordingMode === 'session') {\n      DEBUG_BUILD && logger.info('Recording is already in progress');\n      return;\n    }\n\n    if (this._isEnabled && this.recordingMode === 'buffer') {\n      DEBUG_BUILD && logger.info('Buffering is in progress, call `flush()` to save the replay');\n      return;\n    }\n\n    DEBUG_BUILD && logger.infoTick('Starting replay in session mode');\n\n    // Required as user activity is initially set in\n    // constructor, so if `start()` is called after\n    // session idle expiration, a replay will not be\n    // created due to an idle timeout.\n    this._updateUserActivity();\n\n    const session = loadOrCreateSession(\n      {\n        maxReplayDuration: this._options.maxReplayDuration,\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n      },\n      {\n        stickySession: this._options.stickySession,\n        // This is intentional: create a new session-based replay when calling `start()`\n        sessionSampleRate: 1,\n        allowBuffering: false,\n      },\n    );\n\n    this.session = session;\n\n    this._initializeRecording();\n  }\n\n  /**\n   * Start replay buffering. Buffers until `flush()` is called or, if\n   * `replaysOnErrorSampleRate` > 0, an error occurs.\n   */\n  public startBuffering(): void {\n    if (this._isEnabled) {\n      DEBUG_BUILD && logger.info('Buffering is in progress, call `flush()` to save the replay');\n      return;\n    }\n\n    DEBUG_BUILD && logger.infoTick('Starting replay in buffer mode');\n\n    const session = loadOrCreateSession(\n      {\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n        maxReplayDuration: this._options.maxReplayDuration,\n      },\n      {\n        stickySession: this._options.stickySession,\n        sessionSampleRate: 0,\n        allowBuffering: true,\n      },\n    );\n\n    this.session = session;\n\n    this.recordingMode = 'buffer';\n    this._initializeRecording();\n  }\n\n  /**\n   * Start recording.\n   *\n   * Note that this will cause a new DOM checkout\n   */\n  public startRecording(): void {\n    try {\n      const canvasOptions = this._canvas;\n\n      this._stopRecording = record({\n        ...this._recordingOptions,\n        // When running in error sampling mode, we need to overwrite `checkoutEveryNms`\n        // Without this, it would record forever, until an error happens, which we don't want\n        // instead, we'll always keep the last 60 seconds of replay before an error happened\n        ...(this.recordingMode === 'buffer'\n          ? { checkoutEveryNms: BUFFER_CHECKOUT_TIME }\n          : // Otherwise, use experimental option w/ min checkout time of 6 minutes\n            // This is to improve playback seeking as there could potentially be\n            // less mutations to process in the worse cases.\n            //\n            // checkout by \"N\" events is probably ideal, but means we have less\n            // control about the number of checkouts we make (which generally\n            // increases replay size)\n            this._options._experiments.continuousCheckout && {\n              // Minimum checkout time is 6 minutes\n              checkoutEveryNms: Math.max(360_000, this._options._experiments.continuousCheckout),\n            }),\n        emit: getHandleRecordingEmit(this),\n        ...getRecordingSamplingOptions(),\n        onMutation: this._onMutationHandler,\n        ...(canvasOptions\n          ? {\n              recordCanvas: canvasOptions.recordCanvas,\n              getCanvasManager: canvasOptions.getCanvasManager,\n              sampling: canvasOptions.sampling,\n              dataURLOptions: canvasOptions.dataURLOptions,\n            }\n          : {}),\n      });\n    } catch (err) {\n      this.handleException(err);\n    }\n  }\n\n  /**\n   * Stops the recording, if it was running.\n   *\n   * Returns true if it was previously stopped, or is now stopped,\n   * otherwise false.\n   */\n  public stopRecording(): boolean {\n    try {\n      if (this._stopRecording) {\n        this._stopRecording();\n        this._stopRecording = undefined;\n      }\n\n      return true;\n    } catch (err) {\n      this.handleException(err);\n      return false;\n    }\n  }\n\n  /**\n   * Currently, this needs to be manually called (e.g. for tests). Sentry SDK\n   * does not support a teardown\n   */\n  public async stop({ forceFlush = false, reason }: { forceFlush?: boolean; reason?: string } = {}): Promise<void> {\n    if (!this._isEnabled) {\n      return;\n    }\n\n    // We can't move `_isEnabled` after awaiting a flush, otherwise we can\n    // enter into an infinite loop when `stop()` is called while flushing.\n    this._isEnabled = false;\n\n    try {\n      DEBUG_BUILD && logger.info(`Stopping Replay${reason ? ` triggered by ${reason}` : ''}`);\n\n      resetReplayIdOnDynamicSamplingContext();\n\n      this._removeListeners();\n      this.stopRecording();\n\n      this._debouncedFlush.cancel();\n      // See comment above re: `_isEnabled`, we \"force\" a flush, ignoring the\n      // `_isEnabled` state of the plugin since it was disabled above.\n      if (forceFlush) {\n        await this._flush({ force: true });\n      }\n\n      // After flush, destroy event buffer\n      this.eventBuffer && this.eventBuffer.destroy();\n      this.eventBuffer = null;\n\n      // Clear session from session storage, note this means if a new session\n      // is started after, it will not have `previousSessionId`\n      clearSession(this);\n    } catch (err) {\n      this.handleException(err);\n    }\n  }\n\n  /**\n   * Pause some replay functionality. See comments for `_isPaused`.\n   * This differs from stop as this only stops DOM recording, it is\n   * not as thorough of a shutdown as `stop()`.\n   */\n  public pause(): void {\n    if (this._isPaused) {\n      return;\n    }\n\n    this._isPaused = true;\n    this.stopRecording();\n\n    DEBUG_BUILD && logger.info('Pausing replay');\n  }\n\n  /**\n   * Resumes recording, see notes for `pause().\n   *\n   * Note that calling `startRecording()` here will cause a\n   * new DOM checkout.`\n   */\n  public resume(): void {\n    if (!this._isPaused || !this._checkSession()) {\n      return;\n    }\n\n    this._isPaused = false;\n    this.startRecording();\n\n    DEBUG_BUILD && logger.info('Resuming replay');\n  }\n\n  /**\n   * If not in \"session\" recording mode, flush event buffer which will create a new replay.\n   * Unless `continueRecording` is false, the replay will continue to record and\n   * behave as a \"session\"-based replay.\n   *\n   * Otherwise, queue up a flush.\n   */\n  public async sendBufferedReplayOrFlush({ continueRecording = true }: SendBufferedReplayOptions = {}): Promise<void> {\n    if (this.recordingMode === 'session') {\n      return this.flushImmediate();\n    }\n\n    const activityTime = Date.now();\n\n    DEBUG_BUILD && logger.info('Converting buffer to session');\n\n    // Allow flush to complete before resuming as a session recording, otherwise\n    // the checkout from `startRecording` may be included in the payload.\n    // Prefer to keep the error replay as a separate (and smaller) segment\n    // than the session replay.\n    await this.flushImmediate();\n\n    const hasStoppedRecording = this.stopRecording();\n\n    if (!continueRecording || !hasStoppedRecording) {\n      return;\n    }\n\n    // To avoid race conditions where this is called multiple times, we check here again that we are still buffering\n    if ((this.recordingMode as ReplayRecordingMode) === 'session') {\n      return;\n    }\n\n    // Re-start recording in session-mode\n    this.recordingMode = 'session';\n\n    // Once this session ends, we do not want to refresh it\n    if (this.session) {\n      this._updateUserActivity(activityTime);\n      this._updateSessionActivity(activityTime);\n      this._maybeSaveSession();\n    }\n\n    this.startRecording();\n  }\n\n  /**\n   * We want to batch uploads of replay events. Save events only if\n   * `<flushMinDelay>` milliseconds have elapsed since the last event\n   * *OR* if `<flushMaxDelay>` milliseconds have elapsed.\n   *\n   * Accepts a callback to perform side-effects and returns true to stop batch\n   * processing and hand back control to caller.\n   */\n  public addUpdate(cb: AddUpdateCallback): void {\n    // We need to always run `cb` (e.g. in the case of `this.recordingMode == 'buffer'`)\n    const cbResult = cb();\n\n    // If this option is turned on then we will only want to call `flush`\n    // explicitly\n    if (this.recordingMode === 'buffer') {\n      return;\n    }\n\n    // If callback is true, we do not want to continue with flushing -- the\n    // caller will need to handle it.\n    if (cbResult === true) {\n      return;\n    }\n\n    // addUpdate is called quite frequently - use _debouncedFlush so that it\n    // respects the flush delays and does not flush immediately\n    this._debouncedFlush();\n  }\n\n  /**\n   * Updates the user activity timestamp and resumes recording. This should be\n   * called in an event handler for a user action that we consider as the user\n   * being \"active\" (e.g. a mouse click).\n   */\n  public triggerUserActivity(): void {\n    this._updateUserActivity();\n\n    // This case means that recording was once stopped due to inactivity.\n    // Ensure that recording is resumed.\n    if (!this._stopRecording) {\n      // Create a new session, otherwise when the user action is flushed, it\n      // will get rejected due to an expired session.\n      if (!this._checkSession()) {\n        return;\n      }\n\n      // Note: This will cause a new DOM checkout\n      this.resume();\n      return;\n    }\n\n    // Otherwise... recording was never suspended, continue as normalish\n    this.checkAndHandleExpiredSession();\n\n    this._updateSessionActivity();\n  }\n\n  /**\n   * Updates the user activity timestamp *without* resuming\n   * recording. Some user events (e.g. keydown) can be create\n   * low-value replays that only contain the keypress as a\n   * breadcrumb. Instead this would require other events to\n   * create a new replay after a session has expired.\n   */\n  public updateUserActivity(): void {\n    this._updateUserActivity();\n    this._updateSessionActivity();\n  }\n\n  /**\n   * Only flush if `this.recordingMode === 'session'`\n   */\n  public conditionalFlush(): Promise<void> {\n    if (this.recordingMode === 'buffer') {\n      return Promise.resolve();\n    }\n\n    return this.flushImmediate();\n  }\n\n  /**\n   * Flush using debounce flush\n   */\n  public flush(): Promise<void> {\n    return this._debouncedFlush() as Promise<void>;\n  }\n\n  /**\n   * Always flush via `_debouncedFlush` so that we do not have flushes triggered\n   * from calling both `flush` and `_debouncedFlush`. Otherwise, there could be\n   * cases of multiple flushes happening closely together.\n   */\n  public flushImmediate(): Promise<void> {\n    this._debouncedFlush();\n    // `.flush` is provided by the debounced function, analogously to lodash.debounce\n    return this._debouncedFlush.flush() as Promise<void>;\n  }\n\n  /**\n   * Cancels queued up flushes.\n   */\n  public cancelFlush(): void {\n    this._debouncedFlush.cancel();\n  }\n\n  /** Get the current session (=replay) ID */\n  public getSessionId(): string | undefined {\n    return this.session && this.session.id;\n  }\n\n  /**\n   * Checks if recording should be stopped due to user inactivity. Otherwise\n   * check if session is expired and create a new session if so. Triggers a new\n   * full snapshot on new session.\n   *\n   * Returns true if session is not expired, false otherwise.\n   * @hidden\n   */\n  public checkAndHandleExpiredSession(): boolean | void {\n    // Prevent starting a new session if the last user activity is older than\n    // SESSION_IDLE_PAUSE_DURATION. Otherwise non-user activity can trigger a new\n    // session+recording. This creates noisy replays that do not have much\n    // content in them.\n    if (\n      this._lastActivity &&\n      isExpired(this._lastActivity, this.timeouts.sessionIdlePause) &&\n      this.session &&\n      this.session.sampled === 'session'\n    ) {\n      // Pause recording only for session-based replays. Otherwise, resuming\n      // will create a new replay and will conflict with users who only choose\n      // to record error-based replays only. (e.g. the resumed replay will not\n      // contain a reference to an error)\n      this.pause();\n      return;\n    }\n\n    // --- There is recent user activity --- //\n    // This will create a new session if expired, based on expiry length\n    if (!this._checkSession()) {\n      // Check session handles the refreshing itself\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Capture some initial state that can change throughout the lifespan of the\n   * replay. This is required because otherwise they would be captured at the\n   * first flush.\n   */\n  public setInitialState(): void {\n    const urlPath = `${WINDOW.location.pathname}${WINDOW.location.hash}${WINDOW.location.search}`;\n    const url = `${WINDOW.location.origin}${urlPath}`;\n\n    this.performanceEntries = [];\n    this.replayPerformanceEntries = [];\n\n    // Reset _context as well\n    this._clearContext();\n\n    this._context.initialUrl = url;\n    this._context.initialTimestamp = Date.now();\n    this._context.urls.push(url);\n  }\n\n  /**\n   * Add a breadcrumb event, that may be throttled.\n   * If it was throttled, we add a custom breadcrumb to indicate that.\n   */\n  public throttledAddEvent(\n    event: RecordingEvent,\n    isCheckout?: boolean,\n  ): typeof THROTTLED | typeof SKIPPED | Promise<AddEventResult | null> {\n    const res = this._throttledAddEvent(event, isCheckout);\n\n    // If this is THROTTLED, it means we have throttled the event for the first time\n    // In this case, we want to add a breadcrumb indicating that something was skipped\n    if (res === THROTTLED) {\n      const breadcrumb = createBreadcrumb({\n        category: 'replay.throttled',\n      });\n\n      this.addUpdate(() => {\n        // Return `false` if the event _was_ added, as that means we schedule a flush\n        return !addEventSync(this, {\n          type: ReplayEventTypeCustom,\n          timestamp: breadcrumb.timestamp || 0,\n          data: {\n            tag: 'breadcrumb',\n            payload: breadcrumb,\n            metric: true,\n          },\n        });\n      });\n    }\n\n    return res;\n  }\n\n  /**\n   * This will get the parametrized route name of the current page.\n   * This is only available if performance is enabled, and if an instrumented router is used.\n   */\n  public getCurrentRoute(): string | undefined {\n    const lastActiveSpan = this.lastActiveSpan || getActiveSpan();\n    const lastRootSpan = lastActiveSpan && getRootSpan(lastActiveSpan);\n\n    const attributes = (lastRootSpan && spanToJSON(lastRootSpan).data) || {};\n    const source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n    if (!lastRootSpan || !source || !['route', 'custom'].includes(source)) {\n      return undefined;\n    }\n\n    return spanToJSON(lastRootSpan).description;\n  }\n\n  /**\n   * Initialize and start all listeners to varying events (DOM,\n   * Performance Observer, Recording, Sentry SDK, etc)\n   */\n  private _initializeRecording(): void {\n    this.setInitialState();\n\n    // this method is generally called on page load or manually - in both cases\n    // we should treat it as an activity\n    this._updateSessionActivity();\n\n    this.eventBuffer = createEventBuffer({\n      useCompression: this._options.useCompression,\n      workerUrl: this._options.workerUrl,\n    });\n\n    this._removeListeners();\n    this._addListeners();\n\n    // Need to set as enabled before we start recording, as `record()` can trigger a flush with a new checkout\n    this._isEnabled = true;\n    this._isPaused = false;\n\n    this.startRecording();\n  }\n\n  /**\n   * Loads (or refreshes) the current session.\n   */\n  private _initializeSessionForSampling(previousSessionId?: string): void {\n    // Whenever there is _any_ error sample rate, we always allow buffering\n    // Because we decide on sampling when an error occurs, we need to buffer at all times if sampling for errors\n    const allowBuffering = this._options.errorSampleRate > 0;\n\n    const session = loadOrCreateSession(\n      {\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n        maxReplayDuration: this._options.maxReplayDuration,\n        previousSessionId,\n      },\n      {\n        stickySession: this._options.stickySession,\n        sessionSampleRate: this._options.sessionSampleRate,\n        allowBuffering,\n      },\n    );\n\n    this.session = session;\n  }\n\n  /**\n   * Checks and potentially refreshes the current session.\n   * Returns false if session is not recorded.\n   */\n  private _checkSession(): boolean {\n    // If there is no session yet, we do not want to refresh anything\n    // This should generally not happen, but to be safe....\n    if (!this.session) {\n      return false;\n    }\n\n    const currentSession = this.session;\n\n    if (\n      shouldRefreshSession(currentSession, {\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n        maxReplayDuration: this._options.maxReplayDuration,\n      })\n    ) {\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this._refreshSession(currentSession);\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Refresh a session with a new one.\n   * This stops the current session (without forcing a flush, as that would never work since we are expired),\n   * and then does a new sampling based on the refreshed session.\n   */\n  private async _refreshSession(session: Session): Promise<void> {\n    if (!this._isEnabled) {\n      return;\n    }\n    await this.stop({ reason: 'refresh session' });\n    this.initializeSampling(session.id);\n  }\n\n  /**\n   * Adds listeners to record events for the replay\n   */\n  private _addListeners(): void {\n    try {\n      WINDOW.document.addEventListener('visibilitychange', this._handleVisibilityChange);\n      WINDOW.addEventListener('blur', this._handleWindowBlur);\n      WINDOW.addEventListener('focus', this._handleWindowFocus);\n      WINDOW.addEventListener('keydown', this._handleKeyboardEvent);\n\n      if (this.clickDetector) {\n        this.clickDetector.addListeners();\n      }\n\n      // There is no way to remove these listeners, so ensure they are only added once\n      if (!this._hasInitializedCoreListeners) {\n        addGlobalListeners(this);\n\n        this._hasInitializedCoreListeners = true;\n      }\n    } catch (err) {\n      this.handleException(err);\n    }\n\n    this._performanceCleanupCallback = setupPerformanceObserver(this);\n  }\n\n  /**\n   * Cleans up listeners that were created in `_addListeners`\n   */\n  private _removeListeners(): void {\n    try {\n      WINDOW.document.removeEventListener('visibilitychange', this._handleVisibilityChange);\n\n      WINDOW.removeEventListener('blur', this._handleWindowBlur);\n      WINDOW.removeEventListener('focus', this._handleWindowFocus);\n      WINDOW.removeEventListener('keydown', this._handleKeyboardEvent);\n\n      if (this.clickDetector) {\n        this.clickDetector.removeListeners();\n      }\n\n      if (this._performanceCleanupCallback) {\n        this._performanceCleanupCallback();\n      }\n    } catch (err) {\n      this.handleException(err);\n    }\n  }\n\n  /**\n   * Handle when visibility of the page content changes. Opening a new tab will\n   * cause the state to change to hidden because of content of current page will\n   * be hidden. Likewise, moving a different window to cover the contents of the\n   * page will also trigger a change to a hidden state.\n   */\n  private _handleVisibilityChange: () => void = () => {\n    if (WINDOW.document.visibilityState === 'visible') {\n      this._doChangeToForegroundTasks();\n    } else {\n      this._doChangeToBackgroundTasks();\n    }\n  };\n\n  /**\n   * Handle when page is blurred\n   */\n  private _handleWindowBlur: () => void = () => {\n    const breadcrumb = createBreadcrumb({\n      category: 'ui.blur',\n    });\n\n    // Do not count blur as a user action -- it's part of the process of them\n    // leaving the page\n    this._doChangeToBackgroundTasks(breadcrumb);\n  };\n\n  /**\n   * Handle when page is focused\n   */\n  private _handleWindowFocus: () => void = () => {\n    const breadcrumb = createBreadcrumb({\n      category: 'ui.focus',\n    });\n\n    // Do not count focus as a user action -- instead wait until they focus and\n    // interactive with page\n    this._doChangeToForegroundTasks(breadcrumb);\n  };\n\n  /** Ensure page remains active when a key is pressed. */\n  private _handleKeyboardEvent: (event: KeyboardEvent) => void = (event: KeyboardEvent) => {\n    handleKeyboardEvent(this, event);\n  };\n\n  /**\n   * Tasks to run when we consider a page to be hidden (via blurring and/or visibility)\n   */\n  private _doChangeToBackgroundTasks(breadcrumb?: ReplayBreadcrumbFrame): void {\n    if (!this.session) {\n      return;\n    }\n\n    const expired = isSessionExpired(this.session, {\n      maxReplayDuration: this._options.maxReplayDuration,\n      sessionIdleExpire: this.timeouts.sessionIdleExpire,\n    });\n\n    if (expired) {\n      return;\n    }\n\n    if (breadcrumb) {\n      this._createCustomBreadcrumb(breadcrumb);\n    }\n\n    // Send replay when the page/tab becomes hidden. There is no reason to send\n    // replay if it becomes visible, since no actions we care about were done\n    // while it was hidden\n    // This should never reject\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    void this.conditionalFlush();\n  }\n\n  /**\n   * Tasks to run when we consider a page to be visible (via focus and/or visibility)\n   */\n  private _doChangeToForegroundTasks(breadcrumb?: ReplayBreadcrumbFrame): void {\n    if (!this.session) {\n      return;\n    }\n\n    const isSessionActive = this.checkAndHandleExpiredSession();\n\n    if (!isSessionActive) {\n      // If the user has come back to the page within SESSION_IDLE_PAUSE_DURATION\n      // ms, we will re-use the existing session, otherwise create a new\n      // session\n      DEBUG_BUILD && logger.info('Document has become active, but session has expired');\n      return;\n    }\n\n    if (breadcrumb) {\n      this._createCustomBreadcrumb(breadcrumb);\n    }\n  }\n\n  /**\n   * Update user activity (across session lifespans)\n   */\n  private _updateUserActivity(_lastActivity: number = Date.now()): void {\n    this._lastActivity = _lastActivity;\n  }\n\n  /**\n   * Updates the session's last activity timestamp\n   */\n  private _updateSessionActivity(_lastActivity: number = Date.now()): void {\n    if (this.session) {\n      this.session.lastActivity = _lastActivity;\n      this._maybeSaveSession();\n    }\n  }\n\n  /**\n   * Helper to create (and buffer) a replay breadcrumb from a core SDK breadcrumb\n   */\n  private _createCustomBreadcrumb(breadcrumb: ReplayBreadcrumbFrame): void {\n    this.addUpdate(() => {\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.throttledAddEvent({\n        type: EventType.Custom,\n        timestamp: breadcrumb.timestamp || 0,\n        data: {\n          tag: 'breadcrumb',\n          payload: breadcrumb,\n        },\n      });\n    });\n  }\n\n  /**\n   * Observed performance events are added to `this.performanceEntries`. These\n   * are included in the replay event before it is finished and sent to Sentry.\n   */\n  private _addPerformanceEntries(): Promise<Array<AddEventResult | null>> {\n    let performanceEntries = createPerformanceEntries(this.performanceEntries).concat(this.replayPerformanceEntries);\n\n    this.performanceEntries = [];\n    this.replayPerformanceEntries = [];\n\n    // If we are manually starting, we want to ensure we only include performance entries\n    // that are after the initial timestamp\n    // The reason for this is that we may have performance entries from the page load, but may decide to start\n    // the replay later on, in which case we do not want to include these entries.\n    // without this, manually started replays can have events long before the actual replay recording starts,\n    // which messes with the timeline etc.\n    if (this._requiresManualStart) {\n      const initialTimestampInSeconds = this._context.initialTimestamp / 1000;\n      performanceEntries = performanceEntries.filter(entry => entry.start >= initialTimestampInSeconds);\n    }\n\n    return Promise.all(createPerformanceSpans(this, performanceEntries));\n  }\n\n  /**\n   * Clear _context\n   */\n  private _clearContext(): void {\n    // XXX: `initialTimestamp` and `initialUrl` do not get cleared\n    this._context.errorIds.clear();\n    this._context.traceIds.clear();\n    this._context.urls = [];\n  }\n\n  /** Update the initial timestamp based on the buffer content. */\n  private _updateInitialTimestampFromEventBuffer(): void {\n    const { session, eventBuffer } = this;\n    // If replay was started manually (=no sample rate was given),\n    // We do not want to back-port the initial timestamp\n    if (!session || !eventBuffer || this._requiresManualStart) {\n      return;\n    }\n\n    // we only ever update this on the initial segment\n    if (session.segmentId) {\n      return;\n    }\n\n    const earliestEvent = eventBuffer.getEarliestTimestamp();\n    if (earliestEvent && earliestEvent < this._context.initialTimestamp) {\n      this._context.initialTimestamp = earliestEvent;\n    }\n  }\n\n  /**\n   * Return and clear _context\n   */\n  private _popEventContext(): PopEventContext {\n    const _context = {\n      initialTimestamp: this._context.initialTimestamp,\n      initialUrl: this._context.initialUrl,\n      errorIds: Array.from(this._context.errorIds),\n      traceIds: Array.from(this._context.traceIds),\n      urls: this._context.urls,\n    };\n\n    this._clearContext();\n\n    return _context;\n  }\n\n  /**\n   * Flushes replay event buffer to Sentry.\n   *\n   * Performance events are only added right before flushing - this is\n   * due to the buffered performance observer events.\n   *\n   * Should never be called directly, only by `flush`\n   */\n  private async _runFlush(): Promise<void> {\n    const replayId = this.getSessionId();\n\n    if (!this.session || !this.eventBuffer || !replayId) {\n      DEBUG_BUILD && logger.error('No session or eventBuffer found to flush.');\n      return;\n    }\n\n    await this._addPerformanceEntries();\n\n    // Check eventBuffer again, as it could have been stopped in the meanwhile\n    if (!this.eventBuffer || !this.eventBuffer.hasEvents) {\n      return;\n    }\n\n    // Only attach memory event if eventBuffer is not empty\n    await addMemoryEntry(this);\n\n    // Check eventBuffer again, as it could have been stopped in the meanwhile\n    if (!this.eventBuffer) {\n      return;\n    }\n\n    // if this changed in the meanwhile, e.g. because the session was refreshed or similar, we abort here\n    if (replayId !== this.getSessionId()) {\n      return;\n    }\n\n    try {\n      // This uses the data from the eventBuffer, so we need to call this before `finish()\n      this._updateInitialTimestampFromEventBuffer();\n\n      const timestamp = Date.now();\n\n      // Check total duration again, to avoid sending outdated stuff\n      // We leave 30s wiggle room to accommodate late flushing etc.\n      // This _could_ happen when the browser is suspended during flushing, in which case we just want to stop\n      if (timestamp - this._context.initialTimestamp > this._options.maxReplayDuration + 30_000) {\n        throw new Error('Session is too long, not sending replay');\n      }\n\n      const eventContext = this._popEventContext();\n      // Always increment segmentId regardless of outcome of sending replay\n      const segmentId = this.session.segmentId++;\n      this._maybeSaveSession();\n\n      // Note this empties the event buffer regardless of outcome of sending replay\n      const recordingData = await this.eventBuffer.finish();\n\n      await sendReplay({\n        replayId,\n        recordingData,\n        segmentId,\n        eventContext,\n        session: this.session,\n        timestamp,\n        onError: err => this.handleException(err),\n      });\n    } catch (err) {\n      this.handleException(err);\n\n      // This means we retried 3 times and all of them failed,\n      // or we ran into a problem we don't want to retry, like rate limiting.\n      // In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.stop({ reason: 'sendReplay' });\n\n      const client = getClient();\n\n      if (client) {\n        const dropReason = err instanceof RateLimitError ? 'ratelimit_backoff' : 'send_error';\n        client.recordDroppedEvent(dropReason, 'replay');\n      }\n    }\n  }\n\n  /**\n   * Flush recording data to Sentry. Creates a lock so that only a single flush\n   * can be active at a time. Do not call this directly.\n   */\n  private _flush = async ({\n    force = false,\n  }: {\n    /**\n     * If true, flush while ignoring the `_isEnabled` state of\n     * Replay integration. (By default, flush is noop if integration\n     * is stopped).\n     */\n    force?: boolean;\n  } = {}): Promise<void> => {\n    if (!this._isEnabled && !force) {\n      // This can happen if e.g. the replay was stopped because of exceeding the retry limit\n      return;\n    }\n\n    if (!this.checkAndHandleExpiredSession()) {\n      DEBUG_BUILD && logger.error('Attempting to finish replay event after session expired.');\n      return;\n    }\n\n    if (!this.session) {\n      // should never happen, as we would have bailed out before\n      return;\n    }\n\n    const start = this.session.started;\n    const now = Date.now();\n    const duration = now - start;\n\n    // A flush is about to happen, cancel any queued flushes\n    this._debouncedFlush.cancel();\n\n    // If session is too short, or too long (allow some wiggle room over maxReplayDuration), do not send it\n    // This _should_ not happen, but it may happen if flush is triggered due to a page activity change or similar\n    const tooShort = duration < this._options.minReplayDuration;\n    const tooLong = duration > this._options.maxReplayDuration + 5_000;\n    if (tooShort || tooLong) {\n      DEBUG_BUILD &&\n        logger.info(\n          `Session duration (${Math.floor(duration / 1000)}s) is too ${\n            tooShort ? 'short' : 'long'\n          }, not sending replay.`,\n        );\n\n      if (tooShort) {\n        this._debouncedFlush();\n      }\n      return;\n    }\n\n    const eventBuffer = this.eventBuffer;\n    if (eventBuffer && this.session.segmentId === 0 && !eventBuffer.hasCheckout) {\n      DEBUG_BUILD && logger.info('Flushing initial segment without checkout.');\n      // TODO FN: Evaluate if we want to stop here, or remove this again?\n    }\n\n    const _flushInProgress = !!this._flushLock;\n\n    // this._flushLock acts as a lock so that future calls to `_flush()` will\n    // be blocked until current flush is finished (i.e. this promise resolves)\n    if (!this._flushLock) {\n      this._flushLock = this._runFlush();\n    }\n\n    try {\n      await this._flushLock;\n    } catch (err) {\n      this.handleException(err);\n    } finally {\n      this._flushLock = undefined;\n\n      if (_flushInProgress) {\n        // Wait for previous flush to finish, then call the debounced\n        // `_flush()`. It's possible there are other flush requests queued and\n        // waiting for it to resolve. We want to reduce all outstanding\n        // requests (as well as any new flush requests that occur within a\n        // second of the locked flush completing) into a single flush.\n        this._debouncedFlush();\n      }\n    }\n  };\n\n  /** Save the session, if it is sticky */\n  private _maybeSaveSession(): void {\n    if (this.session && this._options.stickySession) {\n      saveSession(this.session);\n    }\n  }\n\n  /** Handler for rrweb.record.onMutation */\n  private _onMutationHandler = (mutations: unknown[]): boolean => {\n    const count = mutations.length;\n\n    const mutationLimit = this._options.mutationLimit;\n    const mutationBreadcrumbLimit = this._options.mutationBreadcrumbLimit;\n    const overMutationLimit = mutationLimit && count > mutationLimit;\n\n    // Create a breadcrumb if a lot of mutations happen at the same time\n    // We can show this in the UI as an information with potential performance improvements\n    if (count > mutationBreadcrumbLimit || overMutationLimit) {\n      const breadcrumb = createBreadcrumb({\n        category: 'replay.mutations',\n        data: {\n          count,\n          limit: overMutationLimit,\n        },\n      });\n      this._createCustomBreadcrumb(breadcrumb);\n    }\n\n    // Stop replay if over the mutation limit\n    if (overMutationLimit) {\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.stop({ reason: 'mutationLimit', forceFlush: this.recordingMode === 'session' });\n      return false;\n    }\n\n    // `true` means we use the regular mutation handling by rrweb\n    return true;\n  };\n}\n", "import type { ReplayIntegrationPrivacyOptions } from '../types';\n\ntype GetPrivacyOptions = Required<Omit<ReplayIntegrationPrivacyOptions, 'maskFn'>>;\n\ninterface GetPrivacyReturn {\n  maskTextSelector: string;\n  unmaskTextSelector: string;\n  blockSelector: string;\n  unblockSelector: string;\n  ignoreSelector: string;\n\n  blockClass?: RegExp;\n  maskTextClass?: RegExp;\n}\n\nfunction getOption(selectors: string[], defaultSelectors: string[]): string {\n  return [\n    ...selectors,\n    // sentry defaults\n    ...defaultSelectors,\n  ].join(',');\n}\n\n/**\n * Returns privacy related configuration for use in rrweb\n */\nexport function getPrivacyOptions({ mask, unmask, block, unblock, ignore }: GetPrivacyOptions): GetPrivacyReturn {\n  const defaultBlockedElements = ['base', 'iframe[srcdoc]:not([src])'];\n\n  const maskSelector = getOption(mask, ['.sentry-mask', '[data-sentry-mask]']);\n  const unmaskSelector = getOption(unmask, []);\n\n  const options: GetPrivacyReturn = {\n    // We are making the decision to make text and input selectors the same\n    maskTextSelector: maskSelector,\n    unmaskTextSelector: unmaskSelector,\n\n    blockSelector: getOption(block, ['.sentry-block', '[data-sentry-block]', ...defaultBlockedElements]),\n    unblockSelector: getOption(unblock, []),\n    ignoreSelector: getOption(ignore, ['.sentry-ignore', '[data-sentry-ignore]', 'input[type=\"file\"]']),\n  };\n\n  return options;\n}\n", "import type { getPrivacyOptions } from './getPrivacyOptions';\n\ninterface MaskAttributeParams {\n  maskAttributes: string[];\n  maskAllText: boolean;\n  privacyOptions: ReturnType<typeof getPrivacyOptions>;\n  key: string;\n  value: string;\n  el: HTMLElement;\n}\n\n/**\n * Masks an attribute if necessary, otherwise return attribute value as-is.\n */\nexport function maskAttribute({\n  el,\n  key,\n  maskAttributes,\n  maskAllText,\n  privacyOptions,\n  value,\n}: MaskAttributeParams): string {\n  // We only mask attributes if `maskAllText` is true\n  if (!maskAllText) {\n    return value;\n  }\n\n  // unmaskTextSelector takes precedence\n  if (privacyOptions.unmaskTextSelector && el.matches(privacyOptions.unmaskTextSelector)) {\n    return value;\n  }\n\n  if (\n    maskAttributes.includes(key) ||\n    // Need to mask `value` attribute for `<input>` if it's a button-like\n    // type\n    (key === 'value' && el.tagName === 'INPUT' && ['submit', 'button'].includes(el.getAttribute('type') || ''))\n  ) {\n    return value.replace(/[\\S]/g, '*');\n  }\n\n  return value;\n}\n", "import type { BrowserClientReplayOptions, Client, Integration, IntegrationFn, ReplayRecordingMode } from '@sentry/core';\nimport { consoleSandbox, dropUndefinedKeys, isBrowser, parseSampleRate } from '@sentry/core';\nimport {\n  DEFAULT_FLUSH_MAX_DELAY,\n  DEFAULT_FLUSH_MIN_DELAY,\n  MAX_REPLAY_DURATION,\n  MIN_REPLAY_DURATION,\n  MIN_REPLAY_DURATION_LIMIT,\n} from './constants';\nimport { ReplayContainer } from './replay';\nimport type {\n  InitialReplayPluginOptions,\n  RecordingOptions,\n  ReplayCanvasIntegrationOptions,\n  ReplayConfiguration,\n  ReplayPluginOptions,\n  SendBufferedReplayOptions,\n} from './types';\nimport { getPrivacyOptions } from './util/getPrivacyOptions';\nimport { maskAttribute } from './util/maskAttribute';\n\nconst MEDIA_SELECTORS =\n  'img,image,svg,video,object,picture,embed,map,audio,link[rel=\"icon\"],link[rel=\"apple-touch-icon\"]';\n\nconst DEFAULT_NETWORK_HEADERS = ['content-length', 'content-type', 'accept'];\n\nlet _initialized = false;\n\n/**\n * Sentry integration for [Session Replay](https://sentry.io/for/session-replay/).\n *\n * See the [Replay documentation](https://docs.sentry.io/platforms/javascript/guides/session-replay/) for more information.\n *\n * @example\n *\n * ```\n * Sentry.init({\n *   dsn: '__DSN__',\n *   integrations: [Sentry.replayIntegration()],\n * });\n * ```\n */\nexport const replayIntegration = ((options?: ReplayConfiguration) => {\n  return new Replay(options);\n}) satisfies IntegrationFn;\n\n/**\n * Replay integration\n *\n * TODO: Rewrite this to be functional integration\n * Exported for tests.\n */\nexport class Replay implements Integration {\n  /**\n   * @inheritDoc\n   */\n  public static id: string = 'Replay';\n\n  /**\n   * @inheritDoc\n   */\n  public name: string;\n\n  /**\n   * Options to pass to `rrweb.record()`\n   */\n  private readonly _recordingOptions: RecordingOptions;\n\n  /**\n   * Initial options passed to the replay integration, merged with default values.\n   * Note: `sessionSampleRate` and `errorSampleRate` are not required here, as they\n   * can only be finally set when setupOnce() is called.\n   *\n   * @private\n   */\n  private readonly _initialOptions: InitialReplayPluginOptions;\n\n  private _replay?: ReplayContainer;\n\n  public constructor({\n    flushMinDelay = DEFAULT_FLUSH_MIN_DELAY,\n    flushMaxDelay = DEFAULT_FLUSH_MAX_DELAY,\n    minReplayDuration = MIN_REPLAY_DURATION,\n    maxReplayDuration = MAX_REPLAY_DURATION,\n    stickySession = true,\n    useCompression = true,\n    workerUrl,\n    _experiments = {},\n    maskAllText = true,\n    maskAllInputs = true,\n    blockAllMedia = true,\n\n    mutationBreadcrumbLimit = 750,\n    mutationLimit = 10_000,\n\n    slowClickTimeout = 7_000,\n    slowClickIgnoreSelectors = [],\n\n    networkDetailAllowUrls = [],\n    networkDetailDenyUrls = [],\n    networkCaptureBodies = true,\n    networkRequestHeaders = [],\n    networkResponseHeaders = [],\n\n    mask = [],\n    maskAttributes = ['title', 'placeholder'],\n    unmask = [],\n    block = [],\n    unblock = [],\n    ignore = [],\n    maskFn,\n\n    beforeAddRecordingEvent,\n    beforeErrorSampling,\n    onError,\n  }: ReplayConfiguration = {}) {\n    this.name = Replay.id;\n\n    const privacyOptions = getPrivacyOptions({\n      mask,\n      unmask,\n      block,\n      unblock,\n      ignore,\n    });\n\n    this._recordingOptions = {\n      maskAllInputs,\n      maskAllText,\n      maskInputOptions: { password: true },\n      maskTextFn: maskFn,\n      maskInputFn: maskFn,\n      maskAttributeFn: (key: string, value: string, el: HTMLElement): string =>\n        maskAttribute({\n          maskAttributes,\n          maskAllText,\n          privacyOptions,\n          key,\n          value,\n          el,\n        }),\n\n      ...privacyOptions,\n\n      // Our defaults\n      slimDOMOptions: 'all',\n      inlineStylesheet: true,\n      // Disable inline images as it will increase segment/replay size\n      inlineImages: false,\n      // collect fonts, but be aware that `sentry.io` needs to be an allowed\n      // origin for playback\n      collectFonts: true,\n      errorHandler: (err: Error & { __rrweb__?: boolean }) => {\n        try {\n          err.__rrweb__ = true;\n        } catch (error) {\n          // ignore errors here\n          // this can happen if the error is frozen or does not allow mutation for other reasons\n        }\n      },\n    };\n\n    this._initialOptions = {\n      flushMinDelay,\n      flushMaxDelay,\n      minReplayDuration: Math.min(minReplayDuration, MIN_REPLAY_DURATION_LIMIT),\n      maxReplayDuration: Math.min(maxReplayDuration, MAX_REPLAY_DURATION),\n      stickySession,\n      useCompression,\n      workerUrl,\n      blockAllMedia,\n      maskAllInputs,\n      maskAllText,\n      mutationBreadcrumbLimit,\n      mutationLimit,\n      slowClickTimeout,\n      slowClickIgnoreSelectors,\n      networkDetailAllowUrls,\n      networkDetailDenyUrls,\n      networkCaptureBodies,\n      networkRequestHeaders: _getMergedNetworkHeaders(networkRequestHeaders),\n      networkResponseHeaders: _getMergedNetworkHeaders(networkResponseHeaders),\n      beforeAddRecordingEvent,\n      beforeErrorSampling,\n      onError,\n\n      _experiments,\n    };\n\n    if (this._initialOptions.blockAllMedia) {\n      // `blockAllMedia` is a more user friendly option to configure blocking\n      // embedded media elements\n      this._recordingOptions.blockSelector = !this._recordingOptions.blockSelector\n        ? MEDIA_SELECTORS\n        : `${this._recordingOptions.blockSelector},${MEDIA_SELECTORS}`;\n    }\n\n    if (this._isInitialized && isBrowser()) {\n      throw new Error('Multiple Sentry Session Replay instances are not supported');\n    }\n\n    this._isInitialized = true;\n  }\n\n  /** If replay has already been initialized */\n  protected get _isInitialized(): boolean {\n    return _initialized;\n  }\n\n  /** Update _isInitialized */\n  protected set _isInitialized(value: boolean) {\n    _initialized = value;\n  }\n\n  /**\n   * Setup and initialize replay container\n   */\n  public afterAllSetup(client: Client): void {\n    if (!isBrowser() || this._replay) {\n      return;\n    }\n\n    this._setup(client);\n    this._initialize(client);\n  }\n\n  /**\n   * Start a replay regardless of sampling rate. Calling this will always\n   * create a new session. Will log a message if replay is already in progress.\n   *\n   * Creates or loads a session, attaches listeners to varying events (DOM,\n   * PerformanceObserver, Recording, Sentry SDK, etc)\n   */\n  public start(): void {\n    if (!this._replay) {\n      return;\n    }\n    this._replay.start();\n  }\n\n  /**\n   * Start replay buffering. Buffers until `flush()` is called or, if\n   * `replaysOnErrorSampleRate` > 0, until an error occurs.\n   */\n  public startBuffering(): void {\n    if (!this._replay) {\n      return;\n    }\n\n    this._replay.startBuffering();\n  }\n\n  /**\n   * Currently, this needs to be manually called (e.g. for tests). Sentry SDK\n   * does not support a teardown\n   */\n  public stop(): Promise<void> {\n    if (!this._replay) {\n      return Promise.resolve();\n    }\n\n    return this._replay.stop({ forceFlush: this._replay.recordingMode === 'session' });\n  }\n\n  /**\n   * If not in \"session\" recording mode, flush event buffer which will create a new replay.\n   * If replay is not enabled, a new session replay is started.\n   * Unless `continueRecording` is false, the replay will continue to record and\n   * behave as a \"session\"-based replay.\n   *\n   * Otherwise, queue up a flush.\n   */\n  public flush(options?: SendBufferedReplayOptions): Promise<void> {\n    if (!this._replay) {\n      return Promise.resolve();\n    }\n\n    // assuming a session should be recorded in this case\n    if (!this._replay.isEnabled()) {\n      this._replay.start();\n      return Promise.resolve();\n    }\n\n    return this._replay.sendBufferedReplayOrFlush(options);\n  }\n\n  /**\n   * Get the current session ID.\n   */\n  public getReplayId(): string | undefined {\n    if (!this._replay || !this._replay.isEnabled()) {\n      return;\n    }\n\n    return this._replay.getSessionId();\n  }\n\n  /**\n   * Get the current recording mode. This can be either `session` or `buffer`.\n   *\n   * `session`: Recording the whole session, sending it continuously\n   * `buffer`: Always keeping the last 60s of recording, requires:\n   *   - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs\n   *   - or calling `flush()` to send the replay\n   */\n  public getRecordingMode(): ReplayRecordingMode | undefined {\n    if (!this._replay || !this._replay.isEnabled()) {\n      return;\n    }\n\n    return this._replay.recordingMode;\n  }\n\n  /**\n   * Initializes replay.\n   */\n  protected _initialize(client: Client): void {\n    if (!this._replay) {\n      return;\n    }\n\n    this._maybeLoadFromReplayCanvasIntegration(client);\n    this._replay.initializeSampling();\n  }\n\n  /** Setup the integration. */\n  private _setup(client: Client): void {\n    // Client is not available in constructor, so we need to wait until setupOnce\n    const finalOptions = loadReplayOptionsFromClient(this._initialOptions, client);\n\n    this._replay = new ReplayContainer({\n      options: finalOptions,\n      recordingOptions: this._recordingOptions,\n    });\n  }\n\n  /** Get canvas options from ReplayCanvas integration, if it is also added. */\n  private _maybeLoadFromReplayCanvasIntegration(client: Client): void {\n    // To save bundle size, we skip checking for stuff here\n    // and instead just try-catch everything - as generally this should all be defined\n    /* eslint-disable @typescript-eslint/no-non-null-assertion */\n    try {\n      const canvasIntegration = client.getIntegrationByName('ReplayCanvas') as Integration & {\n        getOptions(): ReplayCanvasIntegrationOptions;\n      };\n      if (!canvasIntegration) {\n        return;\n      }\n\n      this._replay!['_canvas'] = canvasIntegration.getOptions();\n    } catch {\n      // ignore errors here\n    }\n    /* eslint-enable @typescript-eslint/no-non-null-assertion */\n  }\n}\n\n/** Parse Replay-related options from SDK options */\nfunction loadReplayOptionsFromClient(initialOptions: InitialReplayPluginOptions, client: Client): ReplayPluginOptions {\n  const opt = client.getOptions() as BrowserClientReplayOptions;\n\n  const finalOptions: ReplayPluginOptions = {\n    sessionSampleRate: 0,\n    errorSampleRate: 0,\n    ...dropUndefinedKeys(initialOptions),\n  };\n\n  const replaysSessionSampleRate = parseSampleRate(opt.replaysSessionSampleRate);\n  const replaysOnErrorSampleRate = parseSampleRate(opt.replaysOnErrorSampleRate);\n\n  if (replaysSessionSampleRate == null && replaysOnErrorSampleRate == null) {\n    consoleSandbox(() => {\n      // eslint-disable-next-line no-console\n      console.warn(\n        'Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.',\n      );\n    });\n  }\n\n  if (replaysSessionSampleRate != null) {\n    finalOptions.sessionSampleRate = replaysSessionSampleRate;\n  }\n\n  if (replaysOnErrorSampleRate != null) {\n    finalOptions.errorSampleRate = replaysOnErrorSampleRate;\n  }\n\n  return finalOptions;\n}\n\nfunction _getMergedNetworkHeaders(headers: string[]): string[] {\n  return [...DEFAULT_NETWORK_HEADERS, ...headers.map(header => header.toLowerCase())];\n}\n", "import { getClient } from '@sentry/core';\nimport type { replayIntegration } from '../integration';\n\n/**\n * This is a small utility to get a type-safe instance of the Replay integration.\n */\nexport function getReplay(): ReturnType<typeof replayIntegration> | undefined {\n  const client = getClient();\n  return client && client.getIntegrationByName<ReturnType<typeof replayIntegration>>('Replay');\n}\n", "var NodeType;\r\n(function (NodeType) {\r\n    NodeType[NodeType[\"Document\"] = 0] = \"Document\";\r\n    NodeType[NodeType[\"DocumentType\"] = 1] = \"DocumentType\";\r\n    NodeType[NodeType[\"Element\"] = 2] = \"Element\";\r\n    NodeType[NodeType[\"Text\"] = 3] = \"Text\";\r\n    NodeType[NodeType[\"CDATA\"] = 4] = \"CDATA\";\r\n    NodeType[NodeType[\"Comment\"] = 5] = \"Comment\";\r\n})(NodeType || (NodeType = {}));\n\nfunction isElement(n) {\r\n    return n.nodeType === n.ELEMENT_NODE;\r\n}\r\nfunction isShadowRoot(n) {\r\n    const host = n?.host;\r\n    return Boolean(host?.shadowRoot === n);\r\n}\r\nfunction isNativeShadowDom(shadowRoot) {\r\n    return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';\r\n}\r\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\r\n    if (cssText.includes(' background-clip: text;') &&\r\n        !cssText.includes(' -webkit-background-clip: text;')) {\r\n        cssText = cssText.replace(/\\sbackground-clip:\\s*text;/g, ' -webkit-background-clip: text; background-clip: text;');\r\n    }\r\n    return cssText;\r\n}\r\nfunction escapeImportStatement(rule) {\r\n    const { cssText } = rule;\r\n    if (cssText.split('\"').length < 3)\r\n        return cssText;\r\n    const statement = ['@import', `url(${JSON.stringify(rule.href)})`];\r\n    if (rule.layerName === '') {\r\n        statement.push(`layer`);\r\n    }\r\n    else if (rule.layerName) {\r\n        statement.push(`layer(${rule.layerName})`);\r\n    }\r\n    if (rule.supportsText) {\r\n        statement.push(`supports(${rule.supportsText})`);\r\n    }\r\n    if (rule.media.length) {\r\n        statement.push(rule.media.mediaText);\r\n    }\r\n    return statement.join(' ') + ';';\r\n}\r\nfunction stringifyStylesheet(s) {\r\n    try {\r\n        const rules = s.rules || s.cssRules;\r\n        return rules\r\n            ? fixBrowserCompatibilityIssuesInCSS(Array.from(rules, stringifyRule).join(''))\r\n            : null;\r\n    }\r\n    catch (error) {\r\n        return null;\r\n    }\r\n}\r\nfunction fixAllCssProperty(rule) {\r\n    let styles = '';\r\n    for (let i = 0; i < rule.style.length; i++) {\r\n        const styleDeclaration = rule.style;\r\n        const attribute = styleDeclaration[i];\r\n        const isImportant = styleDeclaration.getPropertyPriority(attribute);\r\n        styles += `${attribute}:${styleDeclaration.getPropertyValue(attribute)}${isImportant ? ` !important` : ''};`;\r\n    }\r\n    return `${rule.selectorText} { ${styles} }`;\r\n}\r\nfunction stringifyRule(rule) {\r\n    let importStringified;\r\n    if (isCSSImportRule(rule)) {\r\n        try {\r\n            importStringified =\r\n                stringifyStylesheet(rule.styleSheet) ||\r\n                    escapeImportStatement(rule);\r\n        }\r\n        catch (error) {\r\n        }\r\n    }\r\n    else if (isCSSStyleRule(rule)) {\r\n        let cssText = rule.cssText;\r\n        const needsSafariColonFix = rule.selectorText.includes(':');\r\n        const needsAllFix = typeof rule.style['all'] === 'string' && rule.style['all'];\r\n        if (needsAllFix) {\r\n            cssText = fixAllCssProperty(rule);\r\n        }\r\n        if (needsSafariColonFix) {\r\n            cssText = fixSafariColons(cssText);\r\n        }\r\n        if (needsSafariColonFix || needsAllFix) {\r\n            return cssText;\r\n        }\r\n    }\r\n    return importStringified || rule.cssText;\r\n}\r\nfunction fixSafariColons(cssStringified) {\r\n    const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\r\n    return cssStringified.replace(regex, '$1\\\\$2');\r\n}\r\nfunction isCSSImportRule(rule) {\r\n    return 'styleSheet' in rule;\r\n}\r\nfunction isCSSStyleRule(rule) {\r\n    return 'selectorText' in rule;\r\n}\r\nclass Mirror {\r\n    constructor() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n    getId(n) {\r\n        if (!n)\r\n            return -1;\r\n        const id = this.getMeta(n)?.id;\r\n        return id ?? -1;\r\n    }\r\n    getNode(id) {\r\n        return this.idNodeMap.get(id) || null;\r\n    }\r\n    getIds() {\r\n        return Array.from(this.idNodeMap.keys());\r\n    }\r\n    getMeta(n) {\r\n        return this.nodeMetaMap.get(n) || null;\r\n    }\r\n    removeNodeFromMap(n) {\r\n        const id = this.getId(n);\r\n        this.idNodeMap.delete(id);\r\n        if (n.childNodes) {\r\n            n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));\r\n        }\r\n    }\r\n    has(id) {\r\n        return this.idNodeMap.has(id);\r\n    }\r\n    hasNode(node) {\r\n        return this.nodeMetaMap.has(node);\r\n    }\r\n    add(n, meta) {\r\n        const id = meta.id;\r\n        this.idNodeMap.set(id, n);\r\n        this.nodeMetaMap.set(n, meta);\r\n    }\r\n    replace(id, n) {\r\n        const oldNode = this.getNode(id);\r\n        if (oldNode) {\r\n            const meta = this.nodeMetaMap.get(oldNode);\r\n            if (meta)\r\n                this.nodeMetaMap.set(n, meta);\r\n        }\r\n        this.idNodeMap.set(id, n);\r\n    }\r\n    reset() {\r\n        this.idNodeMap = new Map();\r\n        this.nodeMetaMap = new WeakMap();\r\n    }\r\n}\r\nfunction createMirror() {\r\n    return new Mirror();\r\n}\r\nfunction shouldMaskInput({ maskInputOptions, tagName, type, }) {\r\n    if (tagName === 'OPTION') {\r\n        tagName = 'SELECT';\r\n    }\r\n    return Boolean(maskInputOptions[tagName.toLowerCase()] ||\r\n        (type && maskInputOptions[type]) ||\r\n        type === 'password' ||\r\n        (tagName === 'INPUT' && !type && maskInputOptions['text']));\r\n}\r\nfunction maskInputValue({ isMasked, element, value, maskInputFn, }) {\r\n    let text = value || '';\r\n    if (!isMasked) {\r\n        return text;\r\n    }\r\n    if (maskInputFn) {\r\n        text = maskInputFn(text, element);\r\n    }\r\n    return '*'.repeat(text.length);\r\n}\r\nfunction toLowerCase(str) {\r\n    return str.toLowerCase();\r\n}\r\nfunction toUpperCase(str) {\r\n    return str.toUpperCase();\r\n}\r\nconst ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';\r\nfunction is2DCanvasBlank(canvas) {\r\n    const ctx = canvas.getContext('2d');\r\n    if (!ctx)\r\n        return true;\r\n    const chunkSize = 50;\r\n    for (let x = 0; x < canvas.width; x += chunkSize) {\r\n        for (let y = 0; y < canvas.height; y += chunkSize) {\r\n            const getImageData = ctx.getImageData;\r\n            const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData\r\n                ? getImageData[ORIGINAL_ATTRIBUTE_NAME]\r\n                : getImageData;\r\n            const pixelBuffer = new Uint32Array(originalGetImageData.call(ctx, x, y, Math.min(chunkSize, canvas.width - x), Math.min(chunkSize, canvas.height - y)).data.buffer);\r\n            if (pixelBuffer.some((pixel) => pixel !== 0))\r\n                return false;\r\n        }\r\n    }\r\n    return true;\r\n}\r\nfunction isNodeMetaEqual(a, b) {\r\n    if (!a || !b || a.type !== b.type)\r\n        return false;\r\n    if (a.type === NodeType.Document)\r\n        return a.compatMode === b.compatMode;\r\n    else if (a.type === NodeType.DocumentType)\r\n        return (a.name === b.name &&\r\n            a.publicId === b.publicId &&\r\n            a.systemId === b.systemId);\r\n    else if (a.type === NodeType.Comment ||\r\n        a.type === NodeType.Text ||\r\n        a.type === NodeType.CDATA)\r\n        return a.textContent === b.textContent;\r\n    else if (a.type === NodeType.Element)\r\n        return (a.tagName === b.tagName &&\r\n            JSON.stringify(a.attributes) ===\r\n                JSON.stringify(b.attributes) &&\r\n            a.isSVG === b.isSVG &&\r\n            a.needBlock === b.needBlock);\r\n    return false;\r\n}\r\nfunction getInputType(element) {\r\n    const type = element.type;\r\n    return element.hasAttribute('data-rr-is-password')\r\n        ? 'password'\r\n        : type\r\n            ?\r\n                toLowerCase(type)\r\n            : null;\r\n}\r\nfunction getInputValue(el, tagName, type) {\r\n    if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {\r\n        return el.getAttribute('value') || '';\r\n    }\r\n    return el.value;\r\n}\r\nfunction extractFileExtension(path, baseURL) {\r\n    let url;\r\n    try {\r\n        url = new URL(path, baseURL ?? window.location.href);\r\n    }\r\n    catch (err) {\r\n        return null;\r\n    }\r\n    const regex = /\\.([0-9a-z]+)(?:$)/i;\r\n    const match = url.pathname.match(regex);\r\n    return match?.[1] ?? null;\r\n}\r\nconst cachedImplementations = {};\r\nfunction getImplementation(name) {\r\n    const cached = cachedImplementations[name];\r\n    if (cached) {\r\n        return cached;\r\n    }\r\n    const document = window.document;\r\n    let impl = window[name];\r\n    if (document && typeof document.createElement === 'function') {\r\n        try {\r\n            const sandbox = document.createElement('iframe');\r\n            sandbox.hidden = true;\r\n            document.head.appendChild(sandbox);\r\n            const contentWindow = sandbox.contentWindow;\r\n            if (contentWindow && contentWindow[name]) {\r\n                impl =\r\n                    contentWindow[name];\r\n            }\r\n            document.head.removeChild(sandbox);\r\n        }\r\n        catch (e) {\r\n        }\r\n    }\r\n    return (cachedImplementations[name] = impl.bind(window));\r\n}\r\nfunction setTimeout(...rest) {\r\n    return getImplementation('setTimeout')(...rest);\r\n}\r\nfunction clearTimeout(...rest) {\r\n    return getImplementation('clearTimeout')(...rest);\r\n}\r\nfunction getIframeContentDocument(iframe) {\r\n    try {\r\n        return iframe.contentDocument;\r\n    }\r\n    catch (e) {\r\n    }\r\n}\n\nlet _id = 1;\r\nconst tagNameRegex = new RegExp('[^a-z0-9-_:]');\r\nconst IGNORED_NODE = -2;\r\nfunction genId() {\r\n    return _id++;\r\n}\r\nfunction getValidTagName(element) {\r\n    if (element instanceof HTMLFormElement) {\r\n        return 'form';\r\n    }\r\n    const processedTagName = toLowerCase(element.tagName);\r\n    if (tagNameRegex.test(processedTagName)) {\r\n        return 'div';\r\n    }\r\n    return processedTagName;\r\n}\r\nfunction extractOrigin(url) {\r\n    let origin = '';\r\n    if (url.indexOf('//') > -1) {\r\n        origin = url.split('/').slice(0, 3).join('/');\r\n    }\r\n    else {\r\n        origin = url.split('/')[0];\r\n    }\r\n    origin = origin.split('?')[0];\r\n    return origin;\r\n}\r\nlet canvasService;\r\nlet canvasCtx;\r\nconst URL_IN_CSS_REF = /url\\((?:(')([^']*)'|(\")(.*?)\"|([^)]*))\\)/gm;\r\nconst URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\\/\\//i;\r\nconst URL_WWW_MATCH = /^www\\..*/i;\r\nconst DATA_URI = /^(data:)([^,]*),(.*)/i;\r\nfunction absoluteToStylesheet(cssText, href) {\r\n    return (cssText || '').replace(URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => {\r\n        const filePath = path1 || path2 || path3;\r\n        const maybeQuote = quote1 || quote2 || '';\r\n        if (!filePath) {\r\n            return origin;\r\n        }\r\n        if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {\r\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\r\n        }\r\n        if (DATA_URI.test(filePath)) {\r\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\r\n        }\r\n        if (filePath[0] === '/') {\r\n            return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;\r\n        }\r\n        const stack = href.split('/');\r\n        const parts = filePath.split('/');\r\n        stack.pop();\r\n        for (const part of parts) {\r\n            if (part === '.') {\r\n                continue;\r\n            }\r\n            else if (part === '..') {\r\n                stack.pop();\r\n            }\r\n            else {\r\n                stack.push(part);\r\n            }\r\n        }\r\n        return `url(${maybeQuote}${stack.join('/')}${maybeQuote})`;\r\n    });\r\n}\r\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\r\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\r\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\r\n    if (attributeValue.trim() === '') {\r\n        return attributeValue;\r\n    }\r\n    let pos = 0;\r\n    function collectCharacters(regEx) {\r\n        let chars;\r\n        const match = regEx.exec(attributeValue.substring(pos));\r\n        if (match) {\r\n            chars = match[0];\r\n            pos += chars.length;\r\n            return chars;\r\n        }\r\n        return '';\r\n    }\r\n    const output = [];\r\n    while (true) {\r\n        collectCharacters(SRCSET_COMMAS_OR_SPACES);\r\n        if (pos >= attributeValue.length) {\r\n            break;\r\n        }\r\n        let url = collectCharacters(SRCSET_NOT_SPACES);\r\n        if (url.slice(-1) === ',') {\r\n            url = absoluteToDoc(doc, url.substring(0, url.length - 1));\r\n            output.push(url);\r\n        }\r\n        else {\r\n            let descriptorsStr = '';\r\n            url = absoluteToDoc(doc, url);\r\n            let inParens = false;\r\n            while (true) {\r\n                const c = attributeValue.charAt(pos);\r\n                if (c === '') {\r\n                    output.push((url + descriptorsStr).trim());\r\n                    break;\r\n                }\r\n                else if (!inParens) {\r\n                    if (c === ',') {\r\n                        pos += 1;\r\n                        output.push((url + descriptorsStr).trim());\r\n                        break;\r\n                    }\r\n                    else if (c === '(') {\r\n                        inParens = true;\r\n                    }\r\n                }\r\n                else {\r\n                    if (c === ')') {\r\n                        inParens = false;\r\n                    }\r\n                }\r\n                descriptorsStr += c;\r\n                pos += 1;\r\n            }\r\n        }\r\n    }\r\n    return output.join(', ');\r\n}\r\nconst cachedDocument = new WeakMap();\r\nfunction absoluteToDoc(doc, attributeValue) {\r\n    if (!attributeValue || attributeValue.trim() === '') {\r\n        return attributeValue;\r\n    }\r\n    return getHref(doc, attributeValue);\r\n}\r\nfunction isSVGElement(el) {\r\n    return Boolean(el.tagName === 'svg' || el.ownerSVGElement);\r\n}\r\nfunction getHref(doc, customHref) {\r\n    let a = cachedDocument.get(doc);\r\n    if (!a) {\r\n        a = doc.createElement('a');\r\n        cachedDocument.set(doc, a);\r\n    }\r\n    if (!customHref) {\r\n        customHref = '';\r\n    }\r\n    else if (customHref.startsWith('blob:') || customHref.startsWith('data:')) {\r\n        return customHref;\r\n    }\r\n    a.setAttribute('href', customHref);\r\n    return a.href;\r\n}\r\nfunction transformAttribute(doc, tagName, name, value, element, maskAttributeFn) {\r\n    if (!value) {\r\n        return value;\r\n    }\r\n    if (name === 'src' ||\r\n        (name === 'href' && !(tagName === 'use' && value[0] === '#'))) {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'xlink:href' && value[0] !== '#') {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'background' &&\r\n        (tagName === 'table' || tagName === 'td' || tagName === 'th')) {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    else if (name === 'srcset') {\r\n        return getAbsoluteSrcsetString(doc, value);\r\n    }\r\n    else if (name === 'style') {\r\n        return absoluteToStylesheet(value, getHref(doc));\r\n    }\r\n    else if (tagName === 'object' && name === 'data') {\r\n        return absoluteToDoc(doc, value);\r\n    }\r\n    if (typeof maskAttributeFn === 'function') {\r\n        return maskAttributeFn(name, value, element);\r\n    }\r\n    return value;\r\n}\r\nfunction ignoreAttribute(tagName, name, _value) {\r\n    return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';\r\n}\r\nfunction _isBlockedElement(element, blockClass, blockSelector, unblockSelector) {\r\n    try {\r\n        if (unblockSelector && element.matches(unblockSelector)) {\r\n            return false;\r\n        }\r\n        if (typeof blockClass === 'string') {\r\n            if (element.classList.contains(blockClass)) {\r\n                return true;\r\n            }\r\n        }\r\n        else {\r\n            for (let eIndex = element.classList.length; eIndex--;) {\r\n                const className = element.classList[eIndex];\r\n                if (blockClass.test(className)) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        if (blockSelector) {\r\n            return element.matches(blockSelector);\r\n        }\r\n    }\r\n    catch (e) {\r\n    }\r\n    return false;\r\n}\r\nfunction elementClassMatchesRegex(el, regex) {\r\n    for (let eIndex = el.classList.length; eIndex--;) {\r\n        const className = el.classList[eIndex];\r\n        if (regex.test(className)) {\r\n            return true;\r\n        }\r\n    }\r\n    return false;\r\n}\r\nfunction distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {\r\n    if (!node)\r\n        return -1;\r\n    if (node.nodeType !== node.ELEMENT_NODE)\r\n        return -1;\r\n    if (distance > limit)\r\n        return -1;\r\n    if (matchPredicate(node))\r\n        return distance;\r\n    return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);\r\n}\r\nfunction createMatchPredicate(className, selector) {\r\n    return (node) => {\r\n        const el = node;\r\n        if (el === null)\r\n            return false;\r\n        try {\r\n            if (className) {\r\n                if (typeof className === 'string') {\r\n                    if (el.matches(`.${className}`))\r\n                        return true;\r\n                }\r\n                else if (elementClassMatchesRegex(el, className)) {\r\n                    return true;\r\n                }\r\n            }\r\n            if (selector && el.matches(selector))\r\n                return true;\r\n            return false;\r\n        }\r\n        catch {\r\n            return false;\r\n        }\r\n    };\r\n}\r\nfunction needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText) {\r\n    try {\r\n        const el = node.nodeType === node.ELEMENT_NODE\r\n            ? node\r\n            : node.parentElement;\r\n        if (el === null)\r\n            return false;\r\n        if (el.tagName === 'INPUT') {\r\n            const autocomplete = el.getAttribute('autocomplete');\r\n            const disallowedAutocompleteValues = [\r\n                'current-password',\r\n                'new-password',\r\n                'cc-number',\r\n                'cc-exp',\r\n                'cc-exp-month',\r\n                'cc-exp-year',\r\n                'cc-csc',\r\n            ];\r\n            if (disallowedAutocompleteValues.includes(autocomplete)) {\r\n                return true;\r\n            }\r\n        }\r\n        let maskDistance = -1;\r\n        let unmaskDistance = -1;\r\n        if (maskAllText) {\r\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector));\r\n            if (unmaskDistance < 0) {\r\n                return true;\r\n            }\r\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector), unmaskDistance >= 0 ? unmaskDistance : Infinity);\r\n        }\r\n        else {\r\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector));\r\n            if (maskDistance < 0) {\r\n                return false;\r\n            }\r\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector), maskDistance >= 0 ? maskDistance : Infinity);\r\n        }\r\n        return maskDistance >= 0\r\n            ? unmaskDistance >= 0\r\n                ? maskDistance <= unmaskDistance\r\n                : true\r\n            : unmaskDistance >= 0\r\n                ? false\r\n                : !!maskAllText;\r\n    }\r\n    catch (e) {\r\n    }\r\n    return !!maskAllText;\r\n}\r\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\r\n    const win = iframeEl.contentWindow;\r\n    if (!win) {\r\n        return;\r\n    }\r\n    let fired = false;\r\n    let readyState;\r\n    try {\r\n        readyState = win.document.readyState;\r\n    }\r\n    catch (error) {\r\n        return;\r\n    }\r\n    if (readyState !== 'complete') {\r\n        const timer = setTimeout(() => {\r\n            if (!fired) {\r\n                listener();\r\n                fired = true;\r\n            }\r\n        }, iframeLoadTimeout);\r\n        iframeEl.addEventListener('load', () => {\r\n            clearTimeout(timer);\r\n            fired = true;\r\n            listener();\r\n        });\r\n        return;\r\n    }\r\n    const blankUrl = 'about:blank';\r\n    if (win.location.href !== blankUrl ||\r\n        iframeEl.src === blankUrl ||\r\n        iframeEl.src === '') {\r\n        setTimeout(listener, 0);\r\n        return iframeEl.addEventListener('load', listener);\r\n    }\r\n    iframeEl.addEventListener('load', listener);\r\n}\r\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\r\n    let fired = false;\r\n    let styleSheetLoaded;\r\n    try {\r\n        styleSheetLoaded = link.sheet;\r\n    }\r\n    catch (error) {\r\n        return;\r\n    }\r\n    if (styleSheetLoaded)\r\n        return;\r\n    const timer = setTimeout(() => {\r\n        if (!fired) {\r\n            listener();\r\n            fired = true;\r\n        }\r\n    }, styleSheetLoadTimeout);\r\n    link.addEventListener('load', () => {\r\n        clearTimeout(timer);\r\n        fired = true;\r\n        listener();\r\n    });\r\n}\r\nfunction serializeNode(n, options) {\r\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskAttributeFn, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, } = options;\r\n    const rootId = getRootId(doc, mirror);\r\n    switch (n.nodeType) {\r\n        case n.DOCUMENT_NODE:\r\n            if (n.compatMode !== 'CSS1Compat') {\r\n                return {\r\n                    type: NodeType.Document,\r\n                    childNodes: [],\r\n                    compatMode: n.compatMode,\r\n                };\r\n            }\r\n            else {\r\n                return {\r\n                    type: NodeType.Document,\r\n                    childNodes: [],\r\n                };\r\n            }\r\n        case n.DOCUMENT_TYPE_NODE:\r\n            return {\r\n                type: NodeType.DocumentType,\r\n                name: n.name,\r\n                publicId: n.publicId,\r\n                systemId: n.systemId,\r\n                rootId,\r\n            };\r\n        case n.ELEMENT_NODE:\r\n            return serializeElementNode(n, {\r\n                doc,\r\n                blockClass,\r\n                blockSelector,\r\n                unblockSelector,\r\n                inlineStylesheet,\r\n                maskAttributeFn,\r\n                maskInputOptions,\r\n                maskInputFn,\r\n                dataURLOptions,\r\n                inlineImages,\r\n                recordCanvas,\r\n                keepIframeSrcFn,\r\n                newlyAddedElement,\r\n                rootId,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n            });\r\n        case n.TEXT_NODE:\r\n            return serializeTextNode(n, {\r\n                doc,\r\n                maskAllText,\r\n                maskTextClass,\r\n                unmaskTextClass,\r\n                maskTextSelector,\r\n                unmaskTextSelector,\r\n                maskTextFn,\r\n                maskInputOptions,\r\n                maskInputFn,\r\n                rootId,\r\n            });\r\n        case n.CDATA_SECTION_NODE:\r\n            return {\r\n                type: NodeType.CDATA,\r\n                textContent: '',\r\n                rootId,\r\n            };\r\n        case n.COMMENT_NODE:\r\n            return {\r\n                type: NodeType.Comment,\r\n                textContent: n.textContent || '',\r\n                rootId,\r\n            };\r\n        default:\r\n            return false;\r\n    }\r\n}\r\nfunction getRootId(doc, mirror) {\r\n    if (!mirror.hasNode(doc))\r\n        return undefined;\r\n    const docId = mirror.getId(doc);\r\n    return docId === 1 ? undefined : docId;\r\n}\r\nfunction serializeTextNode(n, options) {\r\n    const { maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, maskTextFn, maskInputOptions, maskInputFn, rootId, } = options;\r\n    const parentTagName = n.parentNode && n.parentNode.tagName;\r\n    let textContent = n.textContent;\r\n    const isStyle = parentTagName === 'STYLE' ? true : undefined;\r\n    const isScript = parentTagName === 'SCRIPT' ? true : undefined;\r\n    const isTextarea = parentTagName === 'TEXTAREA' ? true : undefined;\r\n    if (isStyle && textContent) {\r\n        try {\r\n            if (n.nextSibling || n.previousSibling) {\r\n            }\r\n            else if (n.parentNode.sheet?.cssRules) {\r\n                textContent = stringifyStylesheet(n.parentNode.sheet);\r\n            }\r\n        }\r\n        catch (err) {\r\n            console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);\r\n        }\r\n        textContent = absoluteToStylesheet(textContent, getHref(options.doc));\r\n    }\r\n    if (isScript) {\r\n        textContent = 'SCRIPT_PLACEHOLDER';\r\n    }\r\n    const forceMask = needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText);\r\n    if (!isStyle && !isScript && !isTextarea && textContent && forceMask) {\r\n        textContent = maskTextFn\r\n            ? maskTextFn(textContent, n.parentElement)\r\n            : textContent.replace(/[\\S]/g, '*');\r\n    }\r\n    if (isTextarea && textContent && (maskInputOptions.textarea || forceMask)) {\r\n        textContent = maskInputFn\r\n            ? maskInputFn(textContent, n.parentNode)\r\n            : textContent.replace(/[\\S]/g, '*');\r\n    }\r\n    if (parentTagName === 'OPTION' && textContent) {\r\n        const isInputMasked = shouldMaskInput({\r\n            type: null,\r\n            tagName: parentTagName,\r\n            maskInputOptions,\r\n        });\r\n        textContent = maskInputValue({\r\n            isMasked: needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked),\r\n            element: n,\r\n            value: textContent,\r\n            maskInputFn,\r\n        });\r\n    }\r\n    return {\r\n        type: NodeType.Text,\r\n        textContent: textContent || '',\r\n        isStyle,\r\n        rootId,\r\n    };\r\n}\r\nfunction serializeElementNode(n, options) {\r\n    const { doc, blockClass, blockSelector, unblockSelector, inlineStylesheet, maskInputOptions = {}, maskAttributeFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, } = options;\r\n    const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);\r\n    const tagName = getValidTagName(n);\r\n    let attributes = {};\r\n    const len = n.attributes.length;\r\n    for (let i = 0; i < len; i++) {\r\n        const attr = n.attributes[i];\r\n        if (attr.name && !ignoreAttribute(tagName, attr.name, attr.value)) {\r\n            attributes[attr.name] = transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value, n, maskAttributeFn);\r\n        }\r\n    }\r\n    if (tagName === 'link' && inlineStylesheet) {\r\n        const stylesheet = Array.from(doc.styleSheets).find((s) => {\r\n            return s.href === n.href;\r\n        });\r\n        let cssText = null;\r\n        if (stylesheet) {\r\n            cssText = stringifyStylesheet(stylesheet);\r\n        }\r\n        if (cssText) {\r\n            attributes.rel = null;\r\n            attributes.href = null;\r\n            attributes.crossorigin = null;\r\n            attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);\r\n        }\r\n    }\r\n    if (tagName === 'style' &&\r\n        n.sheet &&\r\n        !(n.innerText || n.textContent || '').trim().length) {\r\n        const cssText = stringifyStylesheet(n.sheet);\r\n        if (cssText) {\r\n            attributes._cssText = absoluteToStylesheet(cssText, getHref(doc));\r\n        }\r\n    }\r\n    if (tagName === 'input' ||\r\n        tagName === 'textarea' ||\r\n        tagName === 'select' ||\r\n        tagName === 'option') {\r\n        const el = n;\r\n        const type = getInputType(el);\r\n        const value = getInputValue(el, toUpperCase(tagName), type);\r\n        const checked = el.checked;\r\n        if (type !== 'submit' && type !== 'button' && value) {\r\n            const forceMask = needMaskingText(el, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, shouldMaskInput({\r\n                type,\r\n                tagName: toUpperCase(tagName),\r\n                maskInputOptions,\r\n            }));\r\n            attributes.value = maskInputValue({\r\n                isMasked: forceMask,\r\n                element: el,\r\n                value,\r\n                maskInputFn,\r\n            });\r\n        }\r\n        if (checked) {\r\n            attributes.checked = checked;\r\n        }\r\n    }\r\n    if (tagName === 'option') {\r\n        if (n.selected && !maskInputOptions['select']) {\r\n            attributes.selected = true;\r\n        }\r\n        else {\r\n            delete attributes.selected;\r\n        }\r\n    }\r\n    if (tagName === 'canvas' && recordCanvas) {\r\n        if (n.__context === '2d') {\r\n            if (!is2DCanvasBlank(n)) {\r\n                attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            }\r\n        }\r\n        else if (!('__context' in n)) {\r\n            const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            const blankCanvas = doc.createElement('canvas');\r\n            blankCanvas.width = n.width;\r\n            blankCanvas.height = n.height;\r\n            const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            if (canvasDataURL !== blankCanvasDataURL) {\r\n                attributes.rr_dataURL = canvasDataURL;\r\n            }\r\n        }\r\n    }\r\n    if (tagName === 'img' && inlineImages) {\r\n        if (!canvasService) {\r\n            canvasService = doc.createElement('canvas');\r\n            canvasCtx = canvasService.getContext('2d');\r\n        }\r\n        const image = n;\r\n        const imageSrc = image.currentSrc || image.getAttribute('src') || '<unknown-src>';\r\n        const priorCrossOrigin = image.crossOrigin;\r\n        const recordInlineImage = () => {\r\n            image.removeEventListener('load', recordInlineImage);\r\n            try {\r\n                canvasService.width = image.naturalWidth;\r\n                canvasService.height = image.naturalHeight;\r\n                canvasCtx.drawImage(image, 0, 0);\r\n                attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);\r\n            }\r\n            catch (err) {\r\n                if (image.crossOrigin !== 'anonymous') {\r\n                    image.crossOrigin = 'anonymous';\r\n                    if (image.complete && image.naturalWidth !== 0)\r\n                        recordInlineImage();\r\n                    else\r\n                        image.addEventListener('load', recordInlineImage);\r\n                    return;\r\n                }\r\n                else {\r\n                    console.warn(`Cannot inline img src=${imageSrc}! Error: ${err}`);\r\n                }\r\n            }\r\n            if (image.crossOrigin === 'anonymous') {\r\n                priorCrossOrigin\r\n                    ? (attributes.crossOrigin = priorCrossOrigin)\r\n                    : image.removeAttribute('crossorigin');\r\n            }\r\n        };\r\n        if (image.complete && image.naturalWidth !== 0)\r\n            recordInlineImage();\r\n        else\r\n            image.addEventListener('load', recordInlineImage);\r\n    }\r\n    if (tagName === 'audio' || tagName === 'video') {\r\n        attributes.rr_mediaState = n.paused\r\n            ? 'paused'\r\n            : 'played';\r\n        attributes.rr_mediaCurrentTime = n.currentTime;\r\n    }\r\n    if (!newlyAddedElement) {\r\n        if (n.scrollLeft) {\r\n            attributes.rr_scrollLeft = n.scrollLeft;\r\n        }\r\n        if (n.scrollTop) {\r\n            attributes.rr_scrollTop = n.scrollTop;\r\n        }\r\n    }\r\n    if (needBlock) {\r\n        const { width, height } = n.getBoundingClientRect();\r\n        attributes = {\r\n            class: attributes.class,\r\n            rr_width: `${width}px`,\r\n            rr_height: `${height}px`,\r\n        };\r\n    }\r\n    if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {\r\n        if (!needBlock && !getIframeContentDocument(n)) {\r\n            attributes.rr_src = attributes.src;\r\n        }\r\n        delete attributes.src;\r\n    }\r\n    let isCustomElement;\r\n    try {\r\n        if (customElements.get(tagName))\r\n            isCustomElement = true;\r\n    }\r\n    catch (e) {\r\n    }\r\n    return {\r\n        type: NodeType.Element,\r\n        tagName,\r\n        attributes,\r\n        childNodes: [],\r\n        isSVG: isSVGElement(n) || undefined,\r\n        needBlock,\r\n        rootId,\r\n        isCustom: isCustomElement,\r\n    };\r\n}\r\nfunction lowerIfExists(maybeAttr) {\r\n    if (maybeAttr === undefined || maybeAttr === null) {\r\n        return '';\r\n    }\r\n    else {\r\n        return maybeAttr.toLowerCase();\r\n    }\r\n}\r\nfunction slimDOMExcluded(sn, slimDOMOptions) {\r\n    if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\r\n        return true;\r\n    }\r\n    else if (sn.type === NodeType.Element) {\r\n        if (slimDOMOptions.script &&\r\n            (sn.tagName === 'script' ||\r\n                (sn.tagName === 'link' &&\r\n                    (sn.attributes.rel === 'preload' ||\r\n                        sn.attributes.rel === 'modulepreload')) ||\r\n                (sn.tagName === 'link' &&\r\n                    sn.attributes.rel === 'prefetch' &&\r\n                    typeof sn.attributes.href === 'string' &&\r\n                    extractFileExtension(sn.attributes.href) === 'js'))) {\r\n            return true;\r\n        }\r\n        else if (slimDOMOptions.headFavicon &&\r\n            ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||\r\n                (sn.tagName === 'meta' &&\r\n                    (lowerIfExists(sn.attributes.name).match(/^msapplication-tile(image|color)$/) ||\r\n                        lowerIfExists(sn.attributes.name) === 'application-name' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'icon' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||\r\n                        lowerIfExists(sn.attributes.rel) === 'shortcut icon')))) {\r\n            return true;\r\n        }\r\n        else if (sn.tagName === 'meta') {\r\n            if (slimDOMOptions.headMetaDescKeywords &&\r\n                lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaSocial &&\r\n                (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) ||\r\n                    lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||\r\n                    lowerIfExists(sn.attributes.name) === 'pinterest')) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaRobots &&\r\n                (lowerIfExists(sn.attributes.name) === 'robots' ||\r\n                    lowerIfExists(sn.attributes.name) === 'googlebot' ||\r\n                    lowerIfExists(sn.attributes.name) === 'bingbot')) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaHttpEquiv &&\r\n                sn.attributes['http-equiv'] !== undefined) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaAuthorship &&\r\n                (lowerIfExists(sn.attributes.name) === 'author' ||\r\n                    lowerIfExists(sn.attributes.name) === 'generator' ||\r\n                    lowerIfExists(sn.attributes.name) === 'framework' ||\r\n                    lowerIfExists(sn.attributes.name) === 'publisher' ||\r\n                    lowerIfExists(sn.attributes.name) === 'progid' ||\r\n                    lowerIfExists(sn.attributes.property).match(/^article:/) ||\r\n                    lowerIfExists(sn.attributes.property).match(/^product:/))) {\r\n                return true;\r\n            }\r\n            else if (slimDOMOptions.headMetaVerification &&\r\n                (lowerIfExists(sn.attributes.name) === 'google-site-verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'yandex-verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'csrf-token' ||\r\n                    lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||\r\n                    lowerIfExists(sn.attributes.name) === 'verify-v1' ||\r\n                    lowerIfExists(sn.attributes.name) === 'verification' ||\r\n                    lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')) {\r\n                return true;\r\n            }\r\n        }\r\n    }\r\n    return false;\r\n}\r\nfunction serializeNodeWithId(n, options) {\r\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, skipChild = false, inlineStylesheet = true, maskInputOptions = {}, maskAttributeFn, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5000, onStylesheetLoad, stylesheetLoadTimeout = 5000, keepIframeSrcFn = () => false, newlyAddedElement = false, } = options;\r\n    let { preserveWhiteSpace = true } = options;\r\n    const _serializedNode = serializeNode(n, {\r\n        doc,\r\n        mirror,\r\n        blockClass,\r\n        blockSelector,\r\n        maskAllText,\r\n        unblockSelector,\r\n        maskTextClass,\r\n        unmaskTextClass,\r\n        maskTextSelector,\r\n        unmaskTextSelector,\r\n        inlineStylesheet,\r\n        maskInputOptions,\r\n        maskAttributeFn,\r\n        maskTextFn,\r\n        maskInputFn,\r\n        dataURLOptions,\r\n        inlineImages,\r\n        recordCanvas,\r\n        keepIframeSrcFn,\r\n        newlyAddedElement,\r\n    });\r\n    if (!_serializedNode) {\r\n        console.warn(n, 'not serialized');\r\n        return null;\r\n    }\r\n    let id;\r\n    if (mirror.hasNode(n)) {\r\n        id = mirror.getId(n);\r\n    }\r\n    else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||\r\n        (!preserveWhiteSpace &&\r\n            _serializedNode.type === NodeType.Text &&\r\n            !_serializedNode.isStyle &&\r\n            !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, '').length)) {\r\n        id = IGNORED_NODE;\r\n    }\r\n    else {\r\n        id = genId();\r\n    }\r\n    const serializedNode = Object.assign(_serializedNode, { id });\r\n    mirror.add(n, serializedNode);\r\n    if (id === IGNORED_NODE) {\r\n        return null;\r\n    }\r\n    if (onSerialize) {\r\n        onSerialize(n);\r\n    }\r\n    let recordChild = !skipChild;\r\n    if (serializedNode.type === NodeType.Element) {\r\n        recordChild = recordChild && !serializedNode.needBlock;\r\n        delete serializedNode.needBlock;\r\n        const shadowRoot = n.shadowRoot;\r\n        if (shadowRoot && isNativeShadowDom(shadowRoot))\r\n            serializedNode.isShadowHost = true;\r\n    }\r\n    if ((serializedNode.type === NodeType.Document ||\r\n        serializedNode.type === NodeType.Element) &&\r\n        recordChild) {\r\n        if (slimDOMOptions.headWhitespace &&\r\n            serializedNode.type === NodeType.Element &&\r\n            serializedNode.tagName === 'head') {\r\n            preserveWhiteSpace = false;\r\n        }\r\n        const bypassOptions = {\r\n            doc,\r\n            mirror,\r\n            blockClass,\r\n            blockSelector,\r\n            maskAllText,\r\n            unblockSelector,\r\n            maskTextClass,\r\n            unmaskTextClass,\r\n            maskTextSelector,\r\n            unmaskTextSelector,\r\n            skipChild,\r\n            inlineStylesheet,\r\n            maskInputOptions,\r\n            maskAttributeFn,\r\n            maskTextFn,\r\n            maskInputFn,\r\n            slimDOMOptions,\r\n            dataURLOptions,\r\n            inlineImages,\r\n            recordCanvas,\r\n            preserveWhiteSpace,\r\n            onSerialize,\r\n            onIframeLoad,\r\n            iframeLoadTimeout,\r\n            onStylesheetLoad,\r\n            stylesheetLoadTimeout,\r\n            keepIframeSrcFn,\r\n        };\r\n        for (const childN of Array.from(n.childNodes)) {\r\n            const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\r\n            if (serializedChildNode) {\r\n                serializedNode.childNodes.push(serializedChildNode);\r\n            }\r\n        }\r\n        if (isElement(n) && n.shadowRoot) {\r\n            for (const childN of Array.from(n.shadowRoot.childNodes)) {\r\n                const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\r\n                if (serializedChildNode) {\r\n                    isNativeShadowDom(n.shadowRoot) &&\r\n                        (serializedChildNode.isShadow = true);\r\n                    serializedNode.childNodes.push(serializedChildNode);\r\n                }\r\n            }\r\n        }\r\n    }\r\n    if (n.parentNode &&\r\n        isShadowRoot(n.parentNode) &&\r\n        isNativeShadowDom(n.parentNode)) {\r\n        serializedNode.isShadow = true;\r\n    }\r\n    if (serializedNode.type === NodeType.Element &&\r\n        serializedNode.tagName === 'iframe') {\r\n        onceIframeLoaded(n, () => {\r\n            const iframeDoc = getIframeContentDocument(n);\r\n            if (iframeDoc && onIframeLoad) {\r\n                const serializedIframeNode = serializeNodeWithId(iframeDoc, {\r\n                    doc: iframeDoc,\r\n                    mirror,\r\n                    blockClass,\r\n                    blockSelector,\r\n                    unblockSelector,\r\n                    maskAllText,\r\n                    maskTextClass,\r\n                    unmaskTextClass,\r\n                    maskTextSelector,\r\n                    unmaskTextSelector,\r\n                    skipChild: false,\r\n                    inlineStylesheet,\r\n                    maskInputOptions,\r\n                    maskAttributeFn,\r\n                    maskTextFn,\r\n                    maskInputFn,\r\n                    slimDOMOptions,\r\n                    dataURLOptions,\r\n                    inlineImages,\r\n                    recordCanvas,\r\n                    preserveWhiteSpace,\r\n                    onSerialize,\r\n                    onIframeLoad,\r\n                    iframeLoadTimeout,\r\n                    onStylesheetLoad,\r\n                    stylesheetLoadTimeout,\r\n                    keepIframeSrcFn,\r\n                });\r\n                if (serializedIframeNode) {\r\n                    onIframeLoad(n, serializedIframeNode);\r\n                }\r\n            }\r\n        }, iframeLoadTimeout);\r\n    }\r\n    if (serializedNode.type === NodeType.Element &&\r\n        serializedNode.tagName === 'link' &&\r\n        typeof serializedNode.attributes.rel === 'string' &&\r\n        (serializedNode.attributes.rel === 'stylesheet' ||\r\n            (serializedNode.attributes.rel === 'preload' &&\r\n                typeof serializedNode.attributes.href === 'string' &&\r\n                extractFileExtension(serializedNode.attributes.href) === 'css'))) {\r\n        onceStylesheetLoaded(n, () => {\r\n            if (onStylesheetLoad) {\r\n                const serializedLinkNode = serializeNodeWithId(n, {\r\n                    doc,\r\n                    mirror,\r\n                    blockClass,\r\n                    blockSelector,\r\n                    unblockSelector,\r\n                    maskAllText,\r\n                    maskTextClass,\r\n                    unmaskTextClass,\r\n                    maskTextSelector,\r\n                    unmaskTextSelector,\r\n                    skipChild: false,\r\n                    inlineStylesheet,\r\n                    maskInputOptions,\r\n                    maskAttributeFn,\r\n                    maskTextFn,\r\n                    maskInputFn,\r\n                    slimDOMOptions,\r\n                    dataURLOptions,\r\n                    inlineImages,\r\n                    recordCanvas,\r\n                    preserveWhiteSpace,\r\n                    onSerialize,\r\n                    onIframeLoad,\r\n                    iframeLoadTimeout,\r\n                    onStylesheetLoad,\r\n                    stylesheetLoadTimeout,\r\n                    keepIframeSrcFn,\r\n                });\r\n                if (serializedLinkNode) {\r\n                    onStylesheetLoad(n, serializedLinkNode);\r\n                }\r\n            }\r\n        }, stylesheetLoadTimeout);\r\n    }\r\n    return serializedNode;\r\n}\r\nfunction snapshot(n, options) {\r\n    const { mirror = new Mirror(), blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskAllInputs = false, maskAttributeFn, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn = () => false, } = options || {};\r\n    const maskInputOptions = maskAllInputs === true\r\n        ? {\r\n            color: true,\r\n            date: true,\r\n            'datetime-local': true,\r\n            email: true,\r\n            month: true,\r\n            number: true,\r\n            range: true,\r\n            search: true,\r\n            tel: true,\r\n            text: true,\r\n            time: true,\r\n            url: true,\r\n            week: true,\r\n            textarea: true,\r\n            select: true,\r\n        }\r\n        : maskAllInputs === false\r\n            ? {}\r\n            : maskAllInputs;\r\n    const slimDOMOptions = slimDOM === true || slimDOM === 'all'\r\n        ?\r\n            {\r\n                script: true,\r\n                comment: true,\r\n                headFavicon: true,\r\n                headWhitespace: true,\r\n                headMetaDescKeywords: slimDOM === 'all',\r\n                headMetaSocial: true,\r\n                headMetaRobots: true,\r\n                headMetaHttpEquiv: true,\r\n                headMetaAuthorship: true,\r\n                headMetaVerification: true,\r\n            }\r\n        : slimDOM === false\r\n            ? {}\r\n            : slimDOM;\r\n    return serializeNodeWithId(n, {\r\n        doc: n,\r\n        mirror,\r\n        blockClass,\r\n        blockSelector,\r\n        unblockSelector,\r\n        maskAllText,\r\n        maskTextClass,\r\n        unmaskTextClass,\r\n        maskTextSelector,\r\n        unmaskTextSelector,\r\n        skipChild: false,\r\n        inlineStylesheet,\r\n        maskInputOptions,\r\n        maskAttributeFn,\r\n        maskTextFn,\r\n        maskInputFn,\r\n        slimDOMOptions,\r\n        dataURLOptions,\r\n        inlineImages,\r\n        recordCanvas,\r\n        preserveWhiteSpace,\r\n        onSerialize,\r\n        onIframeLoad,\r\n        iframeLoadTimeout,\r\n        onStylesheetLoad,\r\n        stylesheetLoadTimeout,\r\n        keepIframeSrcFn,\r\n        newlyAddedElement: false,\r\n    });\r\n}\r\n\nconst commentre = /\\/\\*[^*]*\\*+([^/*][^*]*\\*+)*\\//g;\r\nfunction parse(css, options = {}) {\r\n    let lineno = 1;\r\n    let column = 1;\r\n    function updatePosition(str) {\r\n        const lines = str.match(/\\n/g);\r\n        if (lines) {\r\n            lineno += lines.length;\r\n        }\r\n        const i = str.lastIndexOf('\\n');\r\n        column = i === -1 ? column + str.length : str.length - i;\r\n    }\r\n    function position() {\r\n        const start = { line: lineno, column };\r\n        return (node) => {\r\n            node.position = new Position(start);\r\n            whitespace();\r\n            return node;\r\n        };\r\n    }\r\n    class Position {\r\n        constructor(start) {\r\n            this.start = start;\r\n            this.end = { line: lineno, column };\r\n            this.source = options.source;\r\n        }\r\n    }\r\n    Position.prototype.content = css;\r\n    const errorsList = [];\r\n    function error(msg) {\r\n        const err = new Error(`${options.source || ''}:${lineno}:${column}: ${msg}`);\r\n        err.reason = msg;\r\n        err.filename = options.source;\r\n        err.line = lineno;\r\n        err.column = column;\r\n        err.source = css;\r\n        if (options.silent) {\r\n            errorsList.push(err);\r\n        }\r\n        else {\r\n            throw err;\r\n        }\r\n    }\r\n    function stylesheet() {\r\n        const rulesList = rules();\r\n        return {\r\n            type: 'stylesheet',\r\n            stylesheet: {\r\n                source: options.source,\r\n                rules: rulesList,\r\n                parsingErrors: errorsList,\r\n            },\r\n        };\r\n    }\r\n    function open() {\r\n        return match(/^{\\s*/);\r\n    }\r\n    function close() {\r\n        return match(/^}/);\r\n    }\r\n    function rules() {\r\n        let node;\r\n        const rules = [];\r\n        whitespace();\r\n        comments(rules);\r\n        while (css.length && css.charAt(0) !== '}' && (node = atrule() || rule())) {\r\n            if (node) {\r\n                rules.push(node);\r\n                comments(rules);\r\n            }\r\n        }\r\n        return rules;\r\n    }\r\n    function match(re) {\r\n        const m = re.exec(css);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const str = m[0];\r\n        updatePosition(str);\r\n        css = css.slice(str.length);\r\n        return m;\r\n    }\r\n    function whitespace() {\r\n        match(/^\\s*/);\r\n    }\r\n    function comments(rules = []) {\r\n        let c;\r\n        while ((c = comment())) {\r\n            if (c) {\r\n                rules.push(c);\r\n            }\r\n            c = comment();\r\n        }\r\n        return rules;\r\n    }\r\n    function comment() {\r\n        const pos = position();\r\n        if ('/' !== css.charAt(0) || '*' !== css.charAt(1)) {\r\n            return;\r\n        }\r\n        let i = 2;\r\n        while ('' !== css.charAt(i) &&\r\n            ('*' !== css.charAt(i) || '/' !== css.charAt(i + 1))) {\r\n            ++i;\r\n        }\r\n        i += 2;\r\n        if ('' === css.charAt(i - 1)) {\r\n            return error('End of comment missing');\r\n        }\r\n        const str = css.slice(2, i - 2);\r\n        column += 2;\r\n        updatePosition(str);\r\n        css = css.slice(i);\r\n        column += 2;\r\n        return pos({\r\n            type: 'comment',\r\n            comment: str,\r\n        });\r\n    }\r\n    function selector() {\r\n        const m = match(/^([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const splitSelectors = trim(m[0])\r\n            .replace(/\\/\\*([^*]|[\\r\\n]|(\\*+([^*/]|[\\r\\n])))*\\*\\/+/g, '')\r\n            .replace(/\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'/g, (m) => {\r\n            return m.replace(/,/g, '\\u200C');\r\n        })\r\n            .split(/\\s*(?![^(]*\\)),\\s*/);\r\n        if (splitSelectors.length <= 1) {\r\n            return splitSelectors.map((s) => {\r\n                return s.replace(/\\u200C/g, ',');\r\n            });\r\n        }\r\n        let i = 0;\r\n        let j = 0;\r\n        const len = splitSelectors.length;\r\n        const finalSelectors = [];\r\n        while (i < len) {\r\n            const openingParensCount = (splitSelectors[i].match(/\\(/g) || []).length;\r\n            const closingParensCount = (splitSelectors[i].match(/\\)/g) || []).length;\r\n            let unbalancedParens = openingParensCount - closingParensCount;\r\n            if (unbalancedParens >= 1) {\r\n                let foundClosingSelector = false;\r\n                j = i + 1;\r\n                while (j < len) {\r\n                    const nextOpeningParensCount = (splitSelectors[j].match(/\\(/g) || [])\r\n                        .length;\r\n                    const nextClosingParensCount = (splitSelectors[j].match(/\\)/g) || [])\r\n                        .length;\r\n                    const nextUnbalancedParens = nextClosingParensCount - nextOpeningParensCount;\r\n                    if (nextUnbalancedParens === unbalancedParens) {\r\n                        finalSelectors.push(splitSelectors.slice(i, j + 1).join(','));\r\n                        i = j + 1;\r\n                        foundClosingSelector = true;\r\n                        break;\r\n                    }\r\n                    j++;\r\n                    unbalancedParens -= nextUnbalancedParens;\r\n                }\r\n                if (foundClosingSelector) {\r\n                    continue;\r\n                }\r\n                splitSelectors\r\n                    .slice(i, len)\r\n                    .forEach((selector) => selector && finalSelectors.push(selector));\r\n                break;\r\n            }\r\n            splitSelectors[i] && finalSelectors.push(splitSelectors[i]);\r\n            i++;\r\n        }\r\n        return finalSelectors.map((s) => {\r\n            return s.replace(/\\u200C/g, ',');\r\n        });\r\n    }\r\n    function declaration() {\r\n        const pos = position();\r\n        const propMatch = match(/^(\\*?[-#\\/\\*\\\\\\w]+(\\[[0-9a-z_-]+\\])?)\\s*/);\r\n        if (!propMatch) {\r\n            return;\r\n        }\r\n        const prop = trim(propMatch[0]);\r\n        if (!match(/^:\\s*/)) {\r\n            return error(`property missing ':'`);\r\n        }\r\n        const val = match(/^((?:'(?:\\\\'|.)*?'|\"(?:\\\\\"|.)*?\"|\\([^\\)]*?\\)|[^};])+)/);\r\n        const ret = pos({\r\n            type: 'declaration',\r\n            property: prop.replace(commentre, ''),\r\n            value: val ? trim(val[0]).replace(commentre, '') : '',\r\n        });\r\n        match(/^[;\\s]*/);\r\n        return ret;\r\n    }\r\n    function declarations() {\r\n        const decls = [];\r\n        if (!open()) {\r\n            return error(`missing '{'`);\r\n        }\r\n        comments(decls);\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            if (decl !== false) {\r\n                decls.push(decl);\r\n                comments(decls);\r\n            }\r\n            decl = declaration();\r\n        }\r\n        if (!close()) {\r\n            return error(`missing '}'`);\r\n        }\r\n        return decls;\r\n    }\r\n    function keyframe() {\r\n        let m;\r\n        const vals = [];\r\n        const pos = position();\r\n        while ((m = match(/^((\\d+\\.\\d+|\\.\\d+|\\d+)%?|[a-z]+)\\s*/))) {\r\n            vals.push(m[1]);\r\n            match(/^,\\s*/);\r\n        }\r\n        if (!vals.length) {\r\n            return;\r\n        }\r\n        return pos({\r\n            type: 'keyframe',\r\n            values: vals,\r\n            declarations: declarations(),\r\n        });\r\n    }\r\n    function atkeyframes() {\r\n        const pos = position();\r\n        let m = match(/^@([-\\w]+)?keyframes\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const vendor = m[1];\r\n        m = match(/^([-\\w]+)\\s*/);\r\n        if (!m) {\r\n            return error('@keyframes missing name');\r\n        }\r\n        const name = m[1];\r\n        if (!open()) {\r\n            return error(`@keyframes missing '{'`);\r\n        }\r\n        let frame;\r\n        let frames = comments();\r\n        while ((frame = keyframe())) {\r\n            frames.push(frame);\r\n            frames = frames.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@keyframes missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'keyframes',\r\n            name,\r\n            vendor,\r\n            keyframes: frames,\r\n        });\r\n    }\r\n    function atsupports() {\r\n        const pos = position();\r\n        const m = match(/^@supports *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const supports = trim(m[1]);\r\n        if (!open()) {\r\n            return error(`@supports missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@supports missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'supports',\r\n            supports,\r\n            rules: style,\r\n        });\r\n    }\r\n    function athost() {\r\n        const pos = position();\r\n        const m = match(/^@host\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        if (!open()) {\r\n            return error(`@host missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@host missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'host',\r\n            rules: style,\r\n        });\r\n    }\r\n    function atmedia() {\r\n        const pos = position();\r\n        const m = match(/^@media *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const media = trim(m[1]);\r\n        if (!open()) {\r\n            return error(`@media missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@media missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'media',\r\n            media,\r\n            rules: style,\r\n        });\r\n    }\r\n    function atcustommedia() {\r\n        const pos = position();\r\n        const m = match(/^@custom-media\\s+(--[^\\s]+)\\s*([^{;]+);/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        return pos({\r\n            type: 'custom-media',\r\n            name: trim(m[1]),\r\n            media: trim(m[2]),\r\n        });\r\n    }\r\n    function atpage() {\r\n        const pos = position();\r\n        const m = match(/^@page */);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const sel = selector() || [];\r\n        if (!open()) {\r\n            return error(`@page missing '{'`);\r\n        }\r\n        let decls = comments();\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            decls.push(decl);\r\n            decls = decls.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@page missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'page',\r\n            selectors: sel,\r\n            declarations: decls,\r\n        });\r\n    }\r\n    function atdocument() {\r\n        const pos = position();\r\n        const m = match(/^@([-\\w]+)?document *([^{]+)/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        const vendor = trim(m[1]);\r\n        const doc = trim(m[2]);\r\n        if (!open()) {\r\n            return error(`@document missing '{'`);\r\n        }\r\n        const style = comments().concat(rules());\r\n        if (!close()) {\r\n            return error(`@document missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'document',\r\n            document: doc,\r\n            vendor,\r\n            rules: style,\r\n        });\r\n    }\r\n    function atfontface() {\r\n        const pos = position();\r\n        const m = match(/^@font-face\\s*/);\r\n        if (!m) {\r\n            return;\r\n        }\r\n        if (!open()) {\r\n            return error(`@font-face missing '{'`);\r\n        }\r\n        let decls = comments();\r\n        let decl;\r\n        while ((decl = declaration())) {\r\n            decls.push(decl);\r\n            decls = decls.concat(comments());\r\n        }\r\n        if (!close()) {\r\n            return error(`@font-face missing '}'`);\r\n        }\r\n        return pos({\r\n            type: 'font-face',\r\n            declarations: decls,\r\n        });\r\n    }\r\n    const atimport = _compileAtrule('import');\r\n    const atcharset = _compileAtrule('charset');\r\n    const atnamespace = _compileAtrule('namespace');\r\n    function _compileAtrule(name) {\r\n        const re = new RegExp('^@' +\r\n            name +\r\n            '\\\\s*((?:' +\r\n            [\r\n                /[^\\\\]\"(?:\\\\\"|[^\"])*\"/.source,\r\n                /[^\\\\]'(?:\\\\'|[^'])*'/.source,\r\n                '[^;]',\r\n            ].join('|') +\r\n            ')+);');\r\n        return () => {\r\n            const pos = position();\r\n            const m = match(re);\r\n            if (!m) {\r\n                return;\r\n            }\r\n            const ret = { type: name };\r\n            ret[name] = m[1].trim();\r\n            return pos(ret);\r\n        };\r\n    }\r\n    function atrule() {\r\n        if (css[0] !== '@') {\r\n            return;\r\n        }\r\n        return (atkeyframes() ||\r\n            atmedia() ||\r\n            atcustommedia() ||\r\n            atsupports() ||\r\n            atimport() ||\r\n            atcharset() ||\r\n            atnamespace() ||\r\n            atdocument() ||\r\n            atpage() ||\r\n            athost() ||\r\n            atfontface());\r\n    }\r\n    function rule() {\r\n        const pos = position();\r\n        const sel = selector();\r\n        if (!sel) {\r\n            return error('selector missing');\r\n        }\r\n        comments();\r\n        return pos({\r\n            type: 'rule',\r\n            selectors: sel,\r\n            declarations: declarations(),\r\n        });\r\n    }\r\n    return addParent(stylesheet());\r\n}\r\nfunction trim(str) {\r\n    return str ? str.replace(/^\\s+|\\s+$/g, '') : '';\r\n}\r\nfunction addParent(obj, parent) {\r\n    const isNode = obj && typeof obj.type === 'string';\r\n    const childParent = isNode ? obj : parent;\r\n    for (const k of Object.keys(obj)) {\r\n        const value = obj[k];\r\n        if (Array.isArray(value)) {\r\n            value.forEach((v) => {\r\n                addParent(v, childParent);\r\n            });\r\n        }\r\n        else if (value && typeof value === 'object') {\r\n            addParent(value, childParent);\r\n        }\r\n    }\r\n    if (isNode) {\r\n        Object.defineProperty(obj, 'parent', {\r\n            configurable: true,\r\n            writable: true,\r\n            enumerable: false,\r\n            value: parent || null,\r\n        });\r\n    }\r\n    return obj;\r\n}\n\nconst tagMap = {\r\n    script: 'noscript',\r\n    altglyph: 'altGlyph',\r\n    altglyphdef: 'altGlyphDef',\r\n    altglyphitem: 'altGlyphItem',\r\n    animatecolor: 'animateColor',\r\n    animatemotion: 'animateMotion',\r\n    animatetransform: 'animateTransform',\r\n    clippath: 'clipPath',\r\n    feblend: 'feBlend',\r\n    fecolormatrix: 'feColorMatrix',\r\n    fecomponenttransfer: 'feComponentTransfer',\r\n    fecomposite: 'feComposite',\r\n    feconvolvematrix: 'feConvolveMatrix',\r\n    fediffuselighting: 'feDiffuseLighting',\r\n    fedisplacementmap: 'feDisplacementMap',\r\n    fedistantlight: 'feDistantLight',\r\n    fedropshadow: 'feDropShadow',\r\n    feflood: 'feFlood',\r\n    fefunca: 'feFuncA',\r\n    fefuncb: 'feFuncB',\r\n    fefuncg: 'feFuncG',\r\n    fefuncr: 'feFuncR',\r\n    fegaussianblur: 'feGaussianBlur',\r\n    feimage: 'feImage',\r\n    femerge: 'feMerge',\r\n    femergenode: 'feMergeNode',\r\n    femorphology: 'feMorphology',\r\n    feoffset: 'feOffset',\r\n    fepointlight: 'fePointLight',\r\n    fespecularlighting: 'feSpecularLighting',\r\n    fespotlight: 'feSpotLight',\r\n    fetile: 'feTile',\r\n    feturbulence: 'feTurbulence',\r\n    foreignobject: 'foreignObject',\r\n    glyphref: 'glyphRef',\r\n    lineargradient: 'linearGradient',\r\n    radialgradient: 'radialGradient',\r\n};\r\nfunction getTagName(n) {\r\n    let tagName = tagMap[n.tagName] ? tagMap[n.tagName] : n.tagName;\r\n    if (tagName === 'link' && n.attributes._cssText) {\r\n        tagName = 'style';\r\n    }\r\n    return tagName;\r\n}\r\nfunction escapeRegExp(str) {\r\n    return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\nconst HOVER_SELECTOR = /([^\\\\]):hover/;\r\nconst HOVER_SELECTOR_GLOBAL = new RegExp(HOVER_SELECTOR.source, 'g');\r\nfunction addHoverClass(cssText, cache) {\r\n    const cachedStyle = cache?.stylesWithHoverClass.get(cssText);\r\n    if (cachedStyle)\r\n        return cachedStyle;\r\n    if (cssText.length >= 1000000) {\r\n        return cssText;\r\n    }\r\n    const ast = parse(cssText, {\r\n        silent: true,\r\n    });\r\n    if (!ast.stylesheet) {\r\n        return cssText;\r\n    }\r\n    const selectors = [];\r\n    ast.stylesheet.rules.forEach((rule) => {\r\n        if ('selectors' in rule) {\r\n            (rule.selectors || []).forEach((selector) => {\r\n                if (HOVER_SELECTOR.test(selector)) {\r\n                    selectors.push(selector);\r\n                }\r\n            });\r\n        }\r\n    });\r\n    if (selectors.length === 0) {\r\n        return cssText;\r\n    }\r\n    const selectorMatcher = new RegExp(selectors\r\n        .filter((selector, index) => selectors.indexOf(selector) === index)\r\n        .sort((a, b) => b.length - a.length)\r\n        .map((selector) => {\r\n        return escapeRegExp(selector);\r\n    })\r\n        .join('|'), 'g');\r\n    const result = cssText.replace(selectorMatcher, (selector) => {\r\n        const newSelector = selector.replace(HOVER_SELECTOR_GLOBAL, '$1.\\\\:hover');\r\n        return `${selector}, ${newSelector}`;\r\n    });\r\n    cache?.stylesWithHoverClass.set(cssText, result);\r\n    return result;\r\n}\r\nfunction createCache() {\r\n    const stylesWithHoverClass = new Map();\r\n    return {\r\n        stylesWithHoverClass,\r\n    };\r\n}\r\nfunction buildNode(n, options) {\r\n    const { doc, hackCss, cache } = options;\r\n    switch (n.type) {\r\n        case NodeType.Document:\r\n            return doc.implementation.createDocument(null, '', null);\r\n        case NodeType.DocumentType:\r\n            return doc.implementation.createDocumentType(n.name || 'html', n.publicId, n.systemId);\r\n        case NodeType.Element: {\r\n            const tagName = getTagName(n);\r\n            let node;\r\n            if (n.isSVG) {\r\n                node = doc.createElementNS('http://www.w3.org/2000/svg', tagName);\r\n            }\r\n            else {\r\n                if (n.isCustom &&\r\n                    doc.defaultView?.customElements &&\r\n                    !doc.defaultView.customElements.get(n.tagName))\r\n                    doc.defaultView.customElements.define(n.tagName, class extends doc.defaultView.HTMLElement {\r\n                    });\r\n                node = doc.createElement(tagName);\r\n            }\r\n            const specialAttributes = {};\r\n            for (const name in n.attributes) {\r\n                if (!Object.prototype.hasOwnProperty.call(n.attributes, name)) {\r\n                    continue;\r\n                }\r\n                let value = n.attributes[name];\r\n                if (tagName === 'option' &&\r\n                    name === 'selected' &&\r\n                    value === false) {\r\n                    continue;\r\n                }\r\n                if (value === null) {\r\n                    continue;\r\n                }\r\n                if (value === true)\r\n                    value = '';\r\n                if (name.startsWith('rr_')) {\r\n                    specialAttributes[name] = value;\r\n                    continue;\r\n                }\r\n                const isTextarea = tagName === 'textarea' && name === 'value';\r\n                const isRemoteOrDynamicCss = tagName === 'style' && name === '_cssText';\r\n                if (isRemoteOrDynamicCss && hackCss && typeof value === 'string') {\r\n                    value = addHoverClass(value, cache);\r\n                }\r\n                if ((isTextarea || isRemoteOrDynamicCss) && typeof value === 'string') {\r\n                    const child = doc.createTextNode(value);\r\n                    for (const c of Array.from(node.childNodes)) {\r\n                        if (c.nodeType === node.TEXT_NODE) {\r\n                            node.removeChild(c);\r\n                        }\r\n                    }\r\n                    node.appendChild(child);\r\n                    continue;\r\n                }\r\n                try {\r\n                    if (n.isSVG && name === 'xlink:href') {\r\n                        node.setAttributeNS('http://www.w3.org/1999/xlink', name, value.toString());\r\n                    }\r\n                    else if (name === 'onload' ||\r\n                        name === 'onclick' ||\r\n                        name.substring(0, 7) === 'onmouse') {\r\n                        node.setAttribute('_' + name, value.toString());\r\n                    }\r\n                    else if (tagName === 'meta' &&\r\n                        n.attributes['http-equiv'] === 'Content-Security-Policy' &&\r\n                        name === 'content') {\r\n                        node.setAttribute('csp-content', value.toString());\r\n                        continue;\r\n                    }\r\n                    else if (tagName === 'link' &&\r\n                        (n.attributes.rel === 'preload' ||\r\n                            n.attributes.rel === 'modulepreload')) {\r\n                    }\r\n                    else if (tagName === 'link' &&\r\n                        n.attributes.rel === 'prefetch' &&\r\n                        typeof n.attributes.href === 'string' &&\r\n                        extractFileExtension(n.attributes.href) === 'js') {\r\n                    }\r\n                    else if (tagName === 'img' &&\r\n                        n.attributes.srcset &&\r\n                        n.attributes.rr_dataURL) {\r\n                        node.setAttribute('rrweb-original-srcset', n.attributes.srcset);\r\n                    }\r\n                    else {\r\n                        node.setAttribute(name, value.toString());\r\n                    }\r\n                }\r\n                catch (error) {\r\n                }\r\n            }\r\n            for (const name in specialAttributes) {\r\n                const value = specialAttributes[name];\r\n                if (tagName === 'canvas' && name === 'rr_dataURL') {\r\n                    const image = doc.createElement('img');\r\n                    image.onload = () => {\r\n                        const ctx = node.getContext('2d');\r\n                        if (ctx) {\r\n                            ctx.drawImage(image, 0, 0, image.width, image.height);\r\n                        }\r\n                    };\r\n                    image.src = value.toString();\r\n                    if (node.RRNodeType)\r\n                        node.rr_dataURL = value.toString();\r\n                }\r\n                else if (tagName === 'img' && name === 'rr_dataURL') {\r\n                    const image = node;\r\n                    if (!image.currentSrc.startsWith('data:')) {\r\n                        image.setAttribute('rrweb-original-src', n.attributes.src);\r\n                        image.src = value.toString();\r\n                    }\r\n                }\r\n                if (name === 'rr_width') {\r\n                    node.style.setProperty('width', value.toString());\r\n                }\r\n                else if (name === 'rr_height') {\r\n                    node.style.setProperty('height', value.toString());\r\n                }\r\n                else if (name === 'rr_mediaCurrentTime' &&\r\n                    typeof value === 'number') {\r\n                    node.currentTime = value;\r\n                }\r\n                else if (name === 'rr_mediaState') {\r\n                    switch (value) {\r\n                        case 'played':\r\n                            node\r\n                                .play()\r\n                                .catch((e) => console.warn('media playback error', e));\r\n                            break;\r\n                        case 'paused':\r\n                            node.pause();\r\n                            break;\r\n                    }\r\n                }\r\n            }\r\n            if (n.isShadowHost) {\r\n                if (!node.shadowRoot) {\r\n                    node.attachShadow({ mode: 'open' });\r\n                }\r\n                else {\r\n                    while (node.shadowRoot.firstChild) {\r\n                        node.shadowRoot.removeChild(node.shadowRoot.firstChild);\r\n                    }\r\n                }\r\n            }\r\n            return node;\r\n        }\r\n        case NodeType.Text:\r\n            return doc.createTextNode(n.isStyle && hackCss\r\n                ? addHoverClass(n.textContent, cache)\r\n                : n.textContent);\r\n        case NodeType.CDATA:\r\n            return doc.createCDATASection(n.textContent);\r\n        case NodeType.Comment:\r\n            return doc.createComment(n.textContent);\r\n        default:\r\n            return null;\r\n    }\r\n}\r\nfunction buildNodeWithSN(n, options) {\r\n    const { doc, mirror, skipChild = false, hackCss = true, afterAppend, cache, } = options;\r\n    if (mirror.has(n.id)) {\r\n        const nodeInMirror = mirror.getNode(n.id);\r\n        const meta = mirror.getMeta(nodeInMirror);\r\n        if (isNodeMetaEqual(meta, n))\r\n            return mirror.getNode(n.id);\r\n    }\r\n    let node = buildNode(n, { doc, hackCss, cache });\r\n    if (!node) {\r\n        return null;\r\n    }\r\n    if (n.rootId && mirror.getNode(n.rootId) !== doc) {\r\n        mirror.replace(n.rootId, doc);\r\n    }\r\n    if (n.type === NodeType.Document) {\r\n        doc.close();\r\n        doc.open();\r\n        if (n.compatMode === 'BackCompat' &&\r\n            n.childNodes &&\r\n            n.childNodes[0].type !== NodeType.DocumentType) {\r\n            if (n.childNodes[0].type === NodeType.Element &&\r\n                'xmlns' in n.childNodes[0].attributes &&\r\n                n.childNodes[0].attributes.xmlns === 'http://www.w3.org/1999/xhtml') {\r\n                doc.write('<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\">');\r\n            }\r\n            else {\r\n                doc.write('<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\">');\r\n            }\r\n        }\r\n        node = doc;\r\n    }\r\n    mirror.add(node, n);\r\n    if ((n.type === NodeType.Document || n.type === NodeType.Element) &&\r\n        !skipChild) {\r\n        for (const childN of n.childNodes) {\r\n            const childNode = buildNodeWithSN(childN, {\r\n                doc,\r\n                mirror,\r\n                skipChild: false,\r\n                hackCss,\r\n                afterAppend,\r\n                cache,\r\n            });\r\n            if (!childNode) {\r\n                console.warn('Failed to rebuild', childN);\r\n                continue;\r\n            }\r\n            if (childN.isShadow && isElement(node) && node.shadowRoot) {\r\n                node.shadowRoot.appendChild(childNode);\r\n            }\r\n            else if (n.type === NodeType.Document &&\r\n                childN.type == NodeType.Element) {\r\n                const htmlElement = childNode;\r\n                let body = null;\r\n                htmlElement.childNodes.forEach((child) => {\r\n                    if (child.nodeName === 'BODY')\r\n                        body = child;\r\n                });\r\n                if (body) {\r\n                    htmlElement.removeChild(body);\r\n                    node.appendChild(childNode);\r\n                    htmlElement.appendChild(body);\r\n                }\r\n                else {\r\n                    node.appendChild(childNode);\r\n                }\r\n            }\r\n            else {\r\n                node.appendChild(childNode);\r\n            }\r\n            if (afterAppend) {\r\n                afterAppend(childNode, childN.id);\r\n            }\r\n        }\r\n    }\r\n    return node;\r\n}\r\nfunction visit(mirror, onVisit) {\r\n    function walk(node) {\r\n        onVisit(node);\r\n    }\r\n    for (const id of mirror.getIds()) {\r\n        if (mirror.has(id)) {\r\n            walk(mirror.getNode(id));\r\n        }\r\n    }\r\n}\r\nfunction handleScroll(node, mirror) {\r\n    const n = mirror.getMeta(node);\r\n    if (n?.type !== NodeType.Element) {\r\n        return;\r\n    }\r\n    const el = node;\r\n    for (const name in n.attributes) {\r\n        if (!(Object.prototype.hasOwnProperty.call(n.attributes, name) &&\r\n            name.startsWith('rr_'))) {\r\n            continue;\r\n        }\r\n        const value = n.attributes[name];\r\n        if (name === 'rr_scrollLeft') {\r\n            el.scrollLeft = value;\r\n        }\r\n        if (name === 'rr_scrollTop') {\r\n            el.scrollTop = value;\r\n        }\r\n    }\r\n}\r\nfunction rebuild(n, options) {\r\n    const { doc, onVisit, hackCss = true, afterAppend, cache, mirror = new Mirror(), } = options;\r\n    const node = buildNodeWithSN(n, {\r\n        doc,\r\n        mirror,\r\n        skipChild: false,\r\n        hackCss,\r\n        afterAppend,\r\n        cache,\r\n    });\r\n    visit(mirror, (visitedNode) => {\r\n        if (onVisit) {\r\n            onVisit(visitedNode);\r\n        }\r\n        handleScroll(visitedNode, mirror);\r\n    });\r\n    return node;\r\n}\n\nexport { IGNORED_NODE, Mirror, NodeType, addHoverClass, buildNodeWithSN, clearTimeout, createCache, createMatchPredicate, createMirror, distanceToMatch, escapeImportStatement, extractFileExtension, fixAllCssProperty, fixSafariColons, genId, getIframeContentDocument, getInputType, getInputValue, ignoreAttribute, is2DCanvasBlank, isCSSImportRule, isCSSStyleRule, isElement, isNativeShadowDom, isNodeMetaEqual, isShadowRoot, maskInputValue, needMaskingText, rebuild, serializeNodeWithId, setTimeout, shouldMaskInput, snapshot, stringifyRule, stringifyStylesheet, toLowerCase, toUpperCase, transformAttribute };\n", "import { distanceToMatch, IGNORED_NODE, isShadowRoot, createMatchPredicate } from '../../rrweb-snapshot/es/rrweb-snapshot.js';\n\nfunction on(type, fn, target = document) {\r\n    const options = { capture: true, passive: true };\r\n    target.addEventListener(type, fn, options);\r\n    return () => target.removeEventListener(type, fn, options);\r\n}\r\nconst DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +\r\n    '\\r\\n' +\r\n    'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +\r\n    '\\r\\n' +\r\n    'or you can use record.mirror to access the mirror instance during recording.';\r\nlet _mirror = {\r\n    map: {},\r\n    getId() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n        return -1;\r\n    },\r\n    getNode() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n        return null;\r\n    },\r\n    removeNodeFromMap() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n    },\r\n    has() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n        return false;\r\n    },\r\n    reset() {\r\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n    },\r\n};\r\nif (typeof window !== 'undefined' && window.Proxy && window.Reflect) {\r\n    _mirror = new Proxy(_mirror, {\r\n        get(target, prop, receiver) {\r\n            if (prop === 'map') {\r\n                console.error(DEPARTED_MIRROR_ACCESS_WARNING);\r\n            }\r\n            return Reflect.get(target, prop, receiver);\r\n        },\r\n    });\r\n}\r\nfunction throttle(func, wait, options = {}) {\r\n    let timeout = null;\r\n    let previous = 0;\r\n    return function (...args) {\r\n        const now = Date.now();\r\n        if (!previous && options.leading === false) {\r\n            previous = now;\r\n        }\r\n        const remaining = wait - (now - previous);\r\n        const context = this;\r\n        if (remaining <= 0 || remaining > wait) {\r\n            if (timeout) {\r\n                clearTimeout(timeout);\r\n                timeout = null;\r\n            }\r\n            previous = now;\r\n            func.apply(context, args);\r\n        }\r\n        else if (!timeout && options.trailing !== false) {\r\n            timeout = setTimeout(() => {\r\n                previous = options.leading === false ? 0 : Date.now();\r\n                timeout = null;\r\n                func.apply(context, args);\r\n            }, remaining);\r\n        }\r\n    };\r\n}\r\nfunction hookSetter(target, key, d, isRevoked, win = window) {\r\n    const original = win.Object.getOwnPropertyDescriptor(target, key);\r\n    win.Object.defineProperty(target, key, isRevoked\r\n        ? d\r\n        : {\r\n            set(value) {\r\n                setTimeout(() => {\r\n                    d.set.call(this, value);\r\n                }, 0);\r\n                if (original && original.set) {\r\n                    original.set.call(this, value);\r\n                }\r\n            },\r\n        });\r\n    return () => hookSetter(target, key, original || {}, true);\r\n}\r\nfunction patch(source, name, replacement) {\r\n    try {\r\n        if (!(name in source)) {\r\n            return () => {\r\n            };\r\n        }\r\n        const original = source[name];\r\n        const wrapped = replacement(original);\r\n        if (typeof wrapped === 'function') {\r\n            wrapped.prototype = wrapped.prototype || {};\r\n            Object.defineProperties(wrapped, {\r\n                __rrweb_original__: {\r\n                    enumerable: false,\r\n                    value: original,\r\n                },\r\n            });\r\n        }\r\n        source[name] = wrapped;\r\n        return () => {\r\n            source[name] = original;\r\n        };\r\n    }\r\n    catch {\r\n        return () => {\r\n        };\r\n    }\r\n}\r\nlet nowTimestamp = Date.now;\r\nif (!(/[1-9][0-9]{12}/.test(Date.now().toString()))) {\r\n    nowTimestamp = () => new Date().getTime();\r\n}\r\nfunction getWindowScroll(win) {\r\n    const doc = win.document;\r\n    return {\r\n        left: doc.scrollingElement\r\n            ? doc.scrollingElement.scrollLeft\r\n            : win.pageXOffset !== undefined\r\n                ? win.pageXOffset\r\n                : doc?.documentElement.scrollLeft ||\r\n                    doc?.body?.parentElement?.scrollLeft ||\r\n                    doc?.body?.scrollLeft ||\r\n                    0,\r\n        top: doc.scrollingElement\r\n            ? doc.scrollingElement.scrollTop\r\n            : win.pageYOffset !== undefined\r\n                ? win.pageYOffset\r\n                : doc?.documentElement.scrollTop ||\r\n                    doc?.body?.parentElement?.scrollTop ||\r\n                    doc?.body?.scrollTop ||\r\n                    0,\r\n    };\r\n}\r\nfunction getWindowHeight() {\r\n    return (window.innerHeight ||\r\n        (document.documentElement && document.documentElement.clientHeight) ||\r\n        (document.body && document.body.clientHeight));\r\n}\r\nfunction getWindowWidth() {\r\n    return (window.innerWidth ||\r\n        (document.documentElement && document.documentElement.clientWidth) ||\r\n        (document.body && document.body.clientWidth));\r\n}\r\nfunction closestElementOfNode(node) {\r\n    if (!node) {\r\n        return null;\r\n    }\r\n    const el = node.nodeType === node.ELEMENT_NODE\r\n        ? node\r\n        : node.parentElement;\r\n    return el;\r\n}\r\nfunction isBlocked(node, blockClass, blockSelector, unblockSelector, checkAncestors) {\r\n    if (!node) {\r\n        return false;\r\n    }\r\n    const el = closestElementOfNode(node);\r\n    if (!el) {\r\n        return false;\r\n    }\r\n    const blockedPredicate = createMatchPredicate(blockClass, blockSelector);\r\n    if (!checkAncestors) {\r\n        const isUnblocked = unblockSelector && el.matches(unblockSelector);\r\n        return blockedPredicate(el) && !isUnblocked;\r\n    }\r\n    const blockDistance = distanceToMatch(el, blockedPredicate);\r\n    let unblockDistance = -1;\r\n    if (blockDistance < 0) {\r\n        return false;\r\n    }\r\n    if (unblockSelector) {\r\n        unblockDistance = distanceToMatch(el, createMatchPredicate(null, unblockSelector));\r\n    }\r\n    if (blockDistance > -1 && unblockDistance < 0) {\r\n        return true;\r\n    }\r\n    return blockDistance < unblockDistance;\r\n}\r\nfunction isSerialized(n, mirror) {\r\n    return mirror.getId(n) !== -1;\r\n}\r\nfunction isIgnored(n, mirror) {\r\n    return mirror.getId(n) === IGNORED_NODE;\r\n}\r\nfunction isAncestorRemoved(target, mirror) {\r\n    if (isShadowRoot(target)) {\r\n        return false;\r\n    }\r\n    const id = mirror.getId(target);\r\n    if (!mirror.has(id)) {\r\n        return true;\r\n    }\r\n    if (target.parentNode &&\r\n        target.parentNode.nodeType === target.DOCUMENT_NODE) {\r\n        return false;\r\n    }\r\n    if (!target.parentNode) {\r\n        return true;\r\n    }\r\n    return isAncestorRemoved(target.parentNode, mirror);\r\n}\r\nfunction legacy_isTouchEvent(event) {\r\n    return Boolean(event.changedTouches);\r\n}\r\nfunction polyfill(win = window) {\r\n    if ('NodeList' in win && !win.NodeList.prototype.forEach) {\r\n        win.NodeList.prototype.forEach = Array.prototype\r\n            .forEach;\r\n    }\r\n    if ('DOMTokenList' in win && !win.DOMTokenList.prototype.forEach) {\r\n        win.DOMTokenList.prototype.forEach = Array.prototype\r\n            .forEach;\r\n    }\r\n    if (!Node.prototype.contains) {\r\n        Node.prototype.contains = (...args) => {\r\n            let node = args[0];\r\n            if (!(0 in args)) {\r\n                throw new TypeError('1 argument is required');\r\n            }\r\n            do {\r\n                if (this === node) {\r\n                    return true;\r\n                }\r\n            } while ((node = node && node.parentNode));\r\n            return false;\r\n        };\r\n    }\r\n}\r\nfunction queueToResolveTrees(queue) {\r\n    const queueNodeMap = {};\r\n    const putIntoMap = (m, parent) => {\r\n        const nodeInTree = {\r\n            value: m,\r\n            parent,\r\n            children: [],\r\n        };\r\n        queueNodeMap[m.node.id] = nodeInTree;\r\n        return nodeInTree;\r\n    };\r\n    const queueNodeTrees = [];\r\n    for (const mutation of queue) {\r\n        const { nextId, parentId } = mutation;\r\n        if (nextId && nextId in queueNodeMap) {\r\n            const nextInTree = queueNodeMap[nextId];\r\n            if (nextInTree.parent) {\r\n                const idx = nextInTree.parent.children.indexOf(nextInTree);\r\n                nextInTree.parent.children.splice(idx, 0, putIntoMap(mutation, nextInTree.parent));\r\n            }\r\n            else {\r\n                const idx = queueNodeTrees.indexOf(nextInTree);\r\n                queueNodeTrees.splice(idx, 0, putIntoMap(mutation, null));\r\n            }\r\n            continue;\r\n        }\r\n        if (parentId in queueNodeMap) {\r\n            const parentInTree = queueNodeMap[parentId];\r\n            parentInTree.children.push(putIntoMap(mutation, parentInTree));\r\n            continue;\r\n        }\r\n        queueNodeTrees.push(putIntoMap(mutation, null));\r\n    }\r\n    return queueNodeTrees;\r\n}\r\nfunction iterateResolveTree(tree, cb) {\r\n    cb(tree.value);\r\n    for (let i = tree.children.length - 1; i >= 0; i--) {\r\n        iterateResolveTree(tree.children[i], cb);\r\n    }\r\n}\r\nfunction isSerializedIframe(n, mirror) {\r\n    return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));\r\n}\r\nfunction isSerializedStylesheet(n, mirror) {\r\n    return Boolean(n.nodeName === 'LINK' &&\r\n        n.nodeType === n.ELEMENT_NODE &&\r\n        n.getAttribute &&\r\n        n.getAttribute('rel') === 'stylesheet' &&\r\n        mirror.getMeta(n));\r\n}\r\nfunction getBaseDimension(node, rootIframe) {\r\n    const frameElement = node.ownerDocument?.defaultView?.frameElement;\r\n    if (!frameElement || frameElement === rootIframe) {\r\n        return {\r\n            x: 0,\r\n            y: 0,\r\n            relativeScale: 1,\r\n            absoluteScale: 1,\r\n        };\r\n    }\r\n    const frameDimension = frameElement.getBoundingClientRect();\r\n    const frameBaseDimension = getBaseDimension(frameElement, rootIframe);\r\n    const relativeScale = frameDimension.height / frameElement.clientHeight;\r\n    return {\r\n        x: frameDimension.x * frameBaseDimension.relativeScale +\r\n            frameBaseDimension.x,\r\n        y: frameDimension.y * frameBaseDimension.relativeScale +\r\n            frameBaseDimension.y,\r\n        relativeScale,\r\n        absoluteScale: frameBaseDimension.absoluteScale * relativeScale,\r\n    };\r\n}\r\nfunction hasShadowRoot(n) {\r\n    return Boolean(n?.shadowRoot);\r\n}\r\nfunction getNestedRule(rules, position) {\r\n    const rule = rules[position[0]];\r\n    if (position.length === 1) {\r\n        return rule;\r\n    }\r\n    else {\r\n        return getNestedRule(rule.cssRules[position[1]].cssRules, position.slice(2));\r\n    }\r\n}\r\nfunction getPositionsAndIndex(nestedIndex) {\r\n    const positions = [...nestedIndex];\r\n    const index = positions.pop();\r\n    return { positions, index };\r\n}\r\nfunction uniqueTextMutations(mutations) {\r\n    const idSet = new Set();\r\n    const uniqueMutations = [];\r\n    for (let i = mutations.length; i--;) {\r\n        const mutation = mutations[i];\r\n        if (!idSet.has(mutation.id)) {\r\n            uniqueMutations.push(mutation);\r\n            idSet.add(mutation.id);\r\n        }\r\n    }\r\n    return uniqueMutations;\r\n}\r\nclass StyleSheetMirror {\r\n    constructor() {\r\n        this.id = 1;\r\n        this.styleIDMap = new WeakMap();\r\n        this.idStyleMap = new Map();\r\n    }\r\n    getId(stylesheet) {\r\n        return this.styleIDMap.get(stylesheet) ?? -1;\r\n    }\r\n    has(stylesheet) {\r\n        return this.styleIDMap.has(stylesheet);\r\n    }\r\n    add(stylesheet, id) {\r\n        if (this.has(stylesheet))\r\n            return this.getId(stylesheet);\r\n        let newId;\r\n        if (id === undefined) {\r\n            newId = this.id++;\r\n        }\r\n        else\r\n            newId = id;\r\n        this.styleIDMap.set(stylesheet, newId);\r\n        this.idStyleMap.set(newId, stylesheet);\r\n        return newId;\r\n    }\r\n    getStyle(id) {\r\n        return this.idStyleMap.get(id) || null;\r\n    }\r\n    reset() {\r\n        this.styleIDMap = new WeakMap();\r\n        this.idStyleMap = new Map();\r\n        this.id = 1;\r\n    }\r\n    generateId() {\r\n        return this.id++;\r\n    }\r\n}\r\nfunction getShadowHost(n) {\r\n    let shadowHost = null;\r\n    if (n.getRootNode?.()?.nodeType === Node.DOCUMENT_FRAGMENT_NODE &&\r\n        n.getRootNode().host)\r\n        shadowHost = n.getRootNode().host;\r\n    return shadowHost;\r\n}\r\nfunction getRootShadowHost(n) {\r\n    let rootShadowHost = n;\r\n    let shadowHost;\r\n    while ((shadowHost = getShadowHost(rootShadowHost)))\r\n        rootShadowHost = shadowHost;\r\n    return rootShadowHost;\r\n}\r\nfunction shadowHostInDom(n) {\r\n    const doc = n.ownerDocument;\r\n    if (!doc)\r\n        return false;\r\n    const shadowHost = getRootShadowHost(n);\r\n    return doc.contains(shadowHost);\r\n}\r\nfunction inDom(n) {\r\n    const doc = n.ownerDocument;\r\n    if (!doc)\r\n        return false;\r\n    return doc.contains(n) || shadowHostInDom(n);\r\n}\r\nconst cachedImplementations = {};\r\nfunction getImplementation(name) {\r\n    const cached = cachedImplementations[name];\r\n    if (cached) {\r\n        return cached;\r\n    }\r\n    const document = window.document;\r\n    let impl = window[name];\r\n    if (document && typeof document.createElement === 'function') {\r\n        try {\r\n            const sandbox = document.createElement('iframe');\r\n            sandbox.hidden = true;\r\n            document.head.appendChild(sandbox);\r\n            const contentWindow = sandbox.contentWindow;\r\n            if (contentWindow && contentWindow[name]) {\r\n                impl =\r\n                    contentWindow[name];\r\n            }\r\n            document.head.removeChild(sandbox);\r\n        }\r\n        catch (e) {\r\n        }\r\n    }\r\n    return (cachedImplementations[name] = impl.bind(window));\r\n}\r\nfunction onRequestAnimationFrame(...rest) {\r\n    return getImplementation('requestAnimationFrame')(...rest);\r\n}\r\nfunction setTimeout(...rest) {\r\n    return getImplementation('setTimeout')(...rest);\r\n}\r\nfunction clearTimeout(...rest) {\r\n    return getImplementation('clearTimeout')(...rest);\r\n}\n\nexport { StyleSheetMirror, _mirror, clearTimeout, closestElementOfNode, getBaseDimension, getNestedRule, getPositionsAndIndex, getRootShadowHost, getShadowHost, getWindowHeight, getWindowScroll, getWindowWidth, hasShadowRoot, hookSetter, inDom, isAncestorRemoved, isBlocked, isIgnored, isSerialized, isSerializedIframe, isSerializedStylesheet, iterateResolveTree, legacy_isTouchEvent, nowTimestamp, on, onRequestAnimationFrame, patch, polyfill, queueToResolveTrees, setTimeout, shadowHostInDom, throttle, uniqueTextMutations };\n", "var EventType = /* @__PURE__ */ ((EventType2) => {\n  EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n  EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n  EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n  EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n  EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n  EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n  EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n  return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n  IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n  IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n  IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n  IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n  IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n  IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n  IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n  IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n  IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n  IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n  IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n  IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n  IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n  IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n  IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n  IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n  IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n  return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n  MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n  MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n  MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n  MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n  MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n  MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n  MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n  MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n  MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n  MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n  MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n  return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n  PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n  PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n  PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n  return PointerTypes2;\n})(PointerTypes || {});\nvar CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {\n  CanvasContext2[CanvasContext2[\"2D\"] = 0] = \"2D\";\n  CanvasContext2[CanvasContext2[\"WebGL\"] = 1] = \"WebGL\";\n  CanvasContext2[CanvasContext2[\"WebGL2\"] = 2] = \"WebGL2\";\n  return CanvasContext2;\n})(CanvasContext || {});\nvar ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {\n  ReplayerEvents2[\"Start\"] = \"start\";\n  ReplayerEvents2[\"Pause\"] = \"pause\";\n  ReplayerEvents2[\"Resume\"] = \"resume\";\n  ReplayerEvents2[\"Resize\"] = \"resize\";\n  ReplayerEvents2[\"Finish\"] = \"finish\";\n  ReplayerEvents2[\"FullsnapshotRebuilded\"] = \"fullsnapshot-rebuilded\";\n  ReplayerEvents2[\"LoadStylesheetStart\"] = \"load-stylesheet-start\";\n  ReplayerEvents2[\"LoadStylesheetEnd\"] = \"load-stylesheet-end\";\n  ReplayerEvents2[\"SkipStart\"] = \"skip-start\";\n  ReplayerEvents2[\"SkipEnd\"] = \"skip-end\";\n  ReplayerEvents2[\"MouseInteraction\"] = \"mouse-interaction\";\n  ReplayerEvents2[\"EventCast\"] = \"event-cast\";\n  ReplayerEvents2[\"CustomEvent\"] = \"custom-event\";\n  ReplayerEvents2[\"Flush\"] = \"flush\";\n  ReplayerEvents2[\"StateChange\"] = \"state-change\";\n  ReplayerEvents2[\"PlayBack\"] = \"play-back\";\n  ReplayerEvents2[\"Destroy\"] = \"destroy\";\n  return ReplayerEvents2;\n})(ReplayerEvents || {});\n\nexport { CanvasContext, EventType, IncrementalSource, MouseInteractions, PointerTypes, ReplayerEvents };\n", "let errorHandler;\r\nfunction registerErrorHandler(handler) {\r\n    errorHandler = handler;\r\n}\r\nfunction unregisterErrorHandler() {\r\n    errorHandler = undefined;\r\n}\r\nconst callbackWrapper = (cb) => {\r\n    if (!errorHandler) {\r\n        return cb;\r\n    }\r\n    const rrwebWrapped = ((...rest) => {\r\n        try {\r\n            return cb(...rest);\r\n        }\r\n        catch (error) {\r\n            if (errorHandler && errorHandler(error) === true) {\r\n                return () => {\r\n                };\r\n            }\r\n            throw error;\r\n        }\r\n    });\r\n    return rrwebWrapped;\r\n};\n\nexport { callbackWrapper, registerErrorHandler, unregisterErrorHandler };\n", "/*\n * base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n    lookup[chars.charCodeAt(i)] = i;\n}\nvar encode = function (arraybuffer) {\n    var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';\n    for (i = 0; i < len; i += 3) {\n        base64 += chars[bytes[i] >> 2];\n        base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n        base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n        base64 += chars[bytes[i + 2] & 63];\n    }\n    if (len % 3 === 2) {\n        base64 = base64.substring(0, base64.length - 1) + '=';\n    }\n    else if (len % 3 === 1) {\n        base64 = base64.substring(0, base64.length - 2) + '==';\n    }\n    return base64;\n};\nvar decode = function (base64) {\n    var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n    if (base64[base64.length - 1] === '=') {\n        bufferLength--;\n        if (base64[base64.length - 2] === '=') {\n            bufferLength--;\n        }\n    }\n    var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);\n    for (i = 0; i < len; i += 4) {\n        encoded1 = lookup[base64.charCodeAt(i)];\n        encoded2 = lookup[base64.charCodeAt(i + 1)];\n        encoded3 = lookup[base64.charCodeAt(i + 2)];\n        encoded4 = lookup[base64.charCodeAt(i + 3)];\n        bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n        bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n        bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n    }\n    return arraybuffer;\n};\n\nexport { decode, encode };\n", "import { encode } from './../../../../../../ext/base64-arraybuffer/dist/base64-arraybuffer.es5.js';\n\nconst canvasVarMap = new Map();\r\nfunction variableListFor(ctx, ctor) {\r\n    let contextMap = canvasVarMap.get(ctx);\r\n    if (!contextMap) {\r\n        contextMap = new Map();\r\n        canvasVarMap.set(ctx, contextMap);\r\n    }\r\n    if (!contextMap.has(ctor)) {\r\n        contextMap.set(ctor, []);\r\n    }\r\n    return contextMap.get(ctor);\r\n}\r\nconst saveWebGLVar = (value, win, ctx) => {\r\n    if (!value ||\r\n        !(isInstanceOfWebGLObject(value, win) || typeof value === 'object'))\r\n        return;\r\n    const name = value.constructor.name;\r\n    const list = variableListFor(ctx, name);\r\n    let index = list.indexOf(value);\r\n    if (index === -1) {\r\n        index = list.length;\r\n        list.push(value);\r\n    }\r\n    return index;\r\n};\r\nfunction serializeArg(value, win, ctx) {\r\n    if (value instanceof Array) {\r\n        return value.map((arg) => serializeArg(arg, win, ctx));\r\n    }\r\n    else if (value === null) {\r\n        return value;\r\n    }\r\n    else if (value instanceof Float32Array ||\r\n        value instanceof Float64Array ||\r\n        value instanceof Int32Array ||\r\n        value instanceof Uint32Array ||\r\n        value instanceof Uint8Array ||\r\n        value instanceof Uint16Array ||\r\n        value instanceof Int16Array ||\r\n        value instanceof Int8Array ||\r\n        value instanceof Uint8ClampedArray) {\r\n        const name = value.constructor.name;\r\n        return {\r\n            rr_type: name,\r\n            args: [Object.values(value)],\r\n        };\r\n    }\r\n    else if (value instanceof ArrayBuffer) {\r\n        const name = value.constructor.name;\r\n        const base64 = encode(value);\r\n        return {\r\n            rr_type: name,\r\n            base64,\r\n        };\r\n    }\r\n    else if (value instanceof DataView) {\r\n        const name = value.constructor.name;\r\n        return {\r\n            rr_type: name,\r\n            args: [\r\n                serializeArg(value.buffer, win, ctx),\r\n                value.byteOffset,\r\n                value.byteLength,\r\n            ],\r\n        };\r\n    }\r\n    else if (value instanceof HTMLImageElement) {\r\n        const name = value.constructor.name;\r\n        const { src } = value;\r\n        return {\r\n            rr_type: name,\r\n            src,\r\n        };\r\n    }\r\n    else if (value instanceof HTMLCanvasElement) {\r\n        const name = 'HTMLImageElement';\r\n        const src = value.toDataURL();\r\n        return {\r\n            rr_type: name,\r\n            src,\r\n        };\r\n    }\r\n    else if (value instanceof ImageData) {\r\n        const name = value.constructor.name;\r\n        return {\r\n            rr_type: name,\r\n            args: [serializeArg(value.data, win, ctx), value.width, value.height],\r\n        };\r\n    }\r\n    else if (isInstanceOfWebGLObject(value, win) || typeof value === 'object') {\r\n        const name = value.constructor.name;\r\n        const index = saveWebGLVar(value, win, ctx);\r\n        return {\r\n            rr_type: name,\r\n            index: index,\r\n        };\r\n    }\r\n    return value;\r\n}\r\nconst serializeArgs = (args, win, ctx) => {\r\n    return args.map((arg) => serializeArg(arg, win, ctx));\r\n};\r\nconst isInstanceOfWebGLObject = (value, win) => {\r\n    const webGLConstructorNames = [\r\n        'WebGLActiveInfo',\r\n        'WebGLBuffer',\r\n        'WebGLFramebuffer',\r\n        'WebGLProgram',\r\n        'WebGLRenderbuffer',\r\n        'WebGLShader',\r\n        'WebGLShaderPrecisionFormat',\r\n        'WebGLTexture',\r\n        'WebGLUniformLocation',\r\n        'WebGLVertexArrayObject',\r\n        'WebGLVertexArrayObjectOES',\r\n    ];\r\n    const supportedWebGLConstructorNames = webGLConstructorNames.filter((name) => typeof win[name] === 'function');\r\n    return Boolean(supportedWebGLConstructorNames.find((name) => value instanceof win[name]));\r\n};\n\nexport { isInstanceOfWebGLObject, saveWebGLVar, serializeArg, serializeArgs, variableListFor };\n", "import { CanvasContext } from '../../../../../types/dist/rrweb-types.js';\nimport { patch, isBlocked, setTimeout, hookSetter } from '../../../utils.js';\nimport { serializeArgs } from './serialize-args.js';\n\nfunction initCanvas2DMutationObserver(cb, win, blockClass, blockSelector, unblockSelector) {\r\n    const handlers = [];\r\n    const props2D = Object.getOwnPropertyNames(win.CanvasRenderingContext2D.prototype);\r\n    for (const prop of props2D) {\r\n        try {\r\n            if (typeof win.CanvasRenderingContext2D.prototype[prop] !== 'function') {\r\n                continue;\r\n            }\r\n            const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {\r\n                return function (...args) {\r\n                    if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {\r\n                        setTimeout(() => {\r\n                            const recordArgs = serializeArgs(args, win, this);\r\n                            cb(this.canvas, {\r\n                                type: CanvasContext['2D'],\r\n                                property: prop,\r\n                                args: recordArgs,\r\n                            });\r\n                        }, 0);\r\n                    }\r\n                    return original.apply(this, args);\r\n                };\r\n            });\r\n            handlers.push(restoreHandler);\r\n        }\r\n        catch {\r\n            const hookHandler = hookSetter(win.CanvasRenderingContext2D.prototype, prop, {\r\n                set(v) {\r\n                    cb(this.canvas, {\r\n                        type: CanvasContext['2D'],\r\n                        property: prop,\r\n                        args: [v],\r\n                        setter: true,\r\n                    });\r\n                },\r\n            });\r\n            handlers.push(hookHandler);\r\n        }\r\n    }\r\n    return () => {\r\n        handlers.forEach((h) => h());\r\n    };\r\n}\n\nexport { initCanvas2DMutationObserver as default };\n", "import { patch, isBlocked } from '../../../utils.js';\n\nfunction getNormalizedContextName(contextType) {\r\n    return contextType === 'experimental-webgl' ? 'webgl' : contextType;\r\n}\r\nfunction initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, setPreserveDrawingBufferToTrue) {\r\n    const handlers = [];\r\n    try {\r\n        const restoreHandler = patch(win.HTMLCanvasElement.prototype, 'getContext', function (original) {\r\n            return function (contextType, ...args) {\r\n                if (!isBlocked(this, blockClass, blockSelector, unblockSelector, true)) {\r\n                    const ctxName = getNormalizedContextName(contextType);\r\n                    if (!('__context' in this))\r\n                        this.__context = ctxName;\r\n                    if (setPreserveDrawingBufferToTrue &&\r\n                        ['webgl', 'webgl2'].includes(ctxName)) {\r\n                        if (args[0] && typeof args[0] === 'object') {\r\n                            const contextAttributes = args[0];\r\n                            if (!contextAttributes.preserveDrawingBuffer) {\r\n                                contextAttributes.preserveDrawingBuffer = true;\r\n                            }\r\n                        }\r\n                        else {\r\n                            args.splice(0, 1, {\r\n                                preserveDrawingBuffer: true,\r\n                            });\r\n                        }\r\n                    }\r\n                }\r\n                return original.apply(this, [contextType, ...args]);\r\n            };\r\n        });\r\n        handlers.push(restoreHandler);\r\n    }\r\n    catch {\r\n        console.error('failed to patch HTMLCanvasElement.prototype.getContext');\r\n    }\r\n    return () => {\r\n        handlers.forEach((h) => h());\r\n    };\r\n}\n\nexport { initCanvasContextObserver as default };\n", "import { CanvasContext } from '../../../../../types/dist/rrweb-types.js';\nimport { patch, isBlocked, hookSetter } from '../../../utils.js';\nimport { saveWebGLVar, serializeArgs } from './serialize-args.js';\n\nfunction patchGLPrototype(prototype, type, cb, blockClass, blockSelector, unblockSelector, mirror, win) {\r\n    const handlers = [];\r\n    const props = Object.getOwnPropertyNames(prototype);\r\n    for (const prop of props) {\r\n        if ([\r\n            'isContextLost',\r\n            'canvas',\r\n            'drawingBufferWidth',\r\n            'drawingBufferHeight',\r\n        ].includes(prop)) {\r\n            continue;\r\n        }\r\n        try {\r\n            if (typeof prototype[prop] !== 'function') {\r\n                continue;\r\n            }\r\n            const restoreHandler = patch(prototype, prop, function (original) {\r\n                return function (...args) {\r\n                    const result = original.apply(this, args);\r\n                    saveWebGLVar(result, win, this);\r\n                    if ('tagName' in this.canvas &&\r\n                        !isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {\r\n                        const recordArgs = serializeArgs(args, win, this);\r\n                        const mutation = {\r\n                            type,\r\n                            property: prop,\r\n                            args: recordArgs,\r\n                        };\r\n                        cb(this.canvas, mutation);\r\n                    }\r\n                    return result;\r\n                };\r\n            });\r\n            handlers.push(restoreHandler);\r\n        }\r\n        catch {\r\n            const hookHandler = hookSetter(prototype, prop, {\r\n                set(v) {\r\n                    cb(this.canvas, {\r\n                        type,\r\n                        property: prop,\r\n                        args: [v],\r\n                        setter: true,\r\n                    });\r\n                },\r\n            });\r\n            handlers.push(hookHandler);\r\n        }\r\n    }\r\n    return handlers;\r\n}\r\nfunction initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, unblockSelector, mirror) {\r\n    const handlers = [];\r\n    handlers.push(...patchGLPrototype(win.WebGLRenderingContext.prototype, CanvasContext.WebGL, cb, blockClass, blockSelector, unblockSelector, mirror, win));\r\n    if (typeof win.WebGL2RenderingContext !== 'undefined') {\r\n        handlers.push(...patchGLPrototype(win.WebGL2RenderingContext.prototype, CanvasContext.WebGL2, cb, blockClass, blockSelector, unblockSelector, mirror, win));\r\n    }\r\n    return () => {\r\n        handlers.forEach((h) => h());\r\n    };\r\n}\n\nexport { initCanvasWebGLMutationObserver as default };\n", "var r = `for(var e=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",t=\"undefined\"==typeof Uint8Array?[]:new Uint8Array(256),a=0;a<64;a++)t[e.charCodeAt(a)]=a;var n=function(t){var a,n=new Uint8Array(t),r=n.length,s=\"\";for(a=0;a<r;a+=3)s+=e[n[a]>>2],s+=e[(3&n[a])<<4|n[a+1]>>4],s+=e[(15&n[a+1])<<2|n[a+2]>>6],s+=e[63&n[a+2]];return r%3==2?s=s.substring(0,s.length-1)+\"=\":r%3==1&&(s=s.substring(0,s.length-2)+\"==\"),s};const r=new Map,s=new Map;const i=self;i.onmessage=async function(e){if(!(\"OffscreenCanvas\"in globalThis))return i.postMessage({id:e.data.id});{const{id:t,bitmap:a,width:o,height:f,maxCanvasSize:c,dataURLOptions:g}=e.data,u=async function(e,t,a){const r=e+\"-\"+t;if(\"OffscreenCanvas\"in globalThis){if(s.has(r))return s.get(r);const i=new OffscreenCanvas(e,t);i.getContext(\"2d\");const o=await i.convertToBlob(a),f=await o.arrayBuffer(),c=n(f);return s.set(r,c),c}return\"\"}(o,f,g),[h,d]=function(e,t,a){if(!a)return[e,t];const[n,r]=a;if(e<=n&&t<=r)return[e,t];let s=e,i=t;return s>n&&(i=Math.floor(n*t/e),s=n),i>r&&(s=Math.floor(r*e/t),i=r),[s,i]}(o,f,c),l=new OffscreenCanvas(h,d),w=l.getContext(\"bitmaprenderer\"),p=h===o&&d===f?a:await createImageBitmap(a,{resizeWidth:h,resizeHeight:d,resizeQuality:\"low\"});w.transferFromImageBitmap(p),a.close();const y=await l.convertToBlob(g),v=y.type,b=await y.arrayBuffer(),m=n(b);if(p.close(),!r.has(t)&&await u===m)return r.set(t,m),i.postMessage({id:t});if(r.get(t)===m)return i.postMessage({id:t});i.postMessage({id:t,type:v,base64:m,width:o,height:f}),r.set(t,m)}};`;\n\nexport { r as default };\n", "import r from './image-bitmap-data-url-worker.js';\n\nfunction t(){const t=new Blob([r]);return URL.createObjectURL(t)}\n\nexport { t as getImageBitmapDataUrlWorkerURL };\n", "import { onRequestAnimationFrame, isBlocked } from '../../../utils.js';\nimport { CanvasContext } from '../../../../../types/dist/rrweb-types.js';\nimport initCanvas2DMutationObserver from './2d.js';\nimport initCanvasContextObserver from './canvas.js';\nimport initCanvasWebGLMutationObserver from './webgl.js';\nimport { getImageBitmapDataUrlWorkerURL as t } from '../../../../../rrweb-worker/es/rrweb-worker/index.js';\nimport { callbackWrapper, registerErrorHandler } from '../../error-handler.js';\n\nclass CanvasManagerNoop {\r\n    reset() {\r\n    }\r\n    freeze() {\r\n    }\r\n    unfreeze() {\r\n    }\r\n    lock() {\r\n    }\r\n    unlock() {\r\n    }\r\n    snapshot() {\r\n    }\r\n    addWindow() {\r\n    }\r\n    addShadowRoot() {\r\n    }\r\n    resetShadowRoots() {\r\n    }\r\n}\r\nclass CanvasManager {\r\n    reset() {\r\n        this.pendingCanvasMutations.clear();\r\n        this.restoreHandlers.forEach((handler) => {\r\n            try {\r\n                handler();\r\n            }\r\n            catch (e) {\r\n            }\r\n        });\r\n        this.restoreHandlers = [];\r\n        this.windowsSet = new WeakSet();\r\n        this.windows = [];\r\n        this.shadowDoms = new Set();\r\n        this.worker?.terminate();\r\n        this.worker = null;\r\n        this.snapshotInProgressMap = new Map();\r\n    }\r\n    freeze() {\r\n        this.frozen = true;\r\n    }\r\n    unfreeze() {\r\n        this.frozen = false;\r\n    }\r\n    lock() {\r\n        this.locked = true;\r\n    }\r\n    unlock() {\r\n        this.locked = false;\r\n    }\r\n    constructor(options) {\r\n        this.pendingCanvasMutations = new Map();\r\n        this.rafStamps = { latestId: 0, invokeId: null };\r\n        this.shadowDoms = new Set();\r\n        this.windowsSet = new WeakSet();\r\n        this.windows = [];\r\n        this.restoreHandlers = [];\r\n        this.frozen = false;\r\n        this.locked = false;\r\n        this.snapshotInProgressMap = new Map();\r\n        this.worker = null;\r\n        this.processMutation = (target, mutation) => {\r\n            const newFrame = this.rafStamps.invokeId &&\r\n                this.rafStamps.latestId !== this.rafStamps.invokeId;\r\n            if (newFrame || !this.rafStamps.invokeId)\r\n                this.rafStamps.invokeId = this.rafStamps.latestId;\r\n            if (!this.pendingCanvasMutations.has(target)) {\r\n                this.pendingCanvasMutations.set(target, []);\r\n            }\r\n            this.pendingCanvasMutations.get(target).push(mutation);\r\n        };\r\n        const { sampling = 'all', win, blockClass, blockSelector, unblockSelector, maxCanvasSize, recordCanvas, dataURLOptions, errorHandler, } = options;\r\n        this.mutationCb = options.mutationCb;\r\n        this.mirror = options.mirror;\r\n        this.options = options;\r\n        if (errorHandler) {\r\n            registerErrorHandler(errorHandler);\r\n        }\r\n        if ((recordCanvas && typeof sampling === 'number') ||\r\n            options.enableManualSnapshot) {\r\n            this.worker = this.initFPSWorker();\r\n        }\r\n        this.addWindow(win);\r\n        if (options.enableManualSnapshot) {\r\n            return;\r\n        }\r\n        callbackWrapper(() => {\r\n            if (recordCanvas && sampling === 'all') {\r\n                this.startRAFTimestamping();\r\n                this.startPendingCanvasMutationFlusher();\r\n            }\r\n            if (recordCanvas && typeof sampling === 'number') {\r\n                this.initCanvasFPSObserver(sampling, blockClass, blockSelector, unblockSelector, maxCanvasSize, {\r\n                    dataURLOptions,\r\n                });\r\n            }\r\n        })();\r\n    }\r\n    addWindow(win) {\r\n        const { sampling = 'all', blockClass, blockSelector, unblockSelector, recordCanvas, enableManualSnapshot, } = this.options;\r\n        if (this.windowsSet.has(win))\r\n            return;\r\n        if (enableManualSnapshot) {\r\n            this.windowsSet.add(win);\r\n            this.windows.push(new WeakRef(win));\r\n            return;\r\n        }\r\n        callbackWrapper(() => {\r\n            if (recordCanvas && sampling === 'all') {\r\n                this.initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector);\r\n            }\r\n            if (recordCanvas && typeof sampling === 'number') {\r\n                const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, true);\r\n                this.restoreHandlers.push(() => {\r\n                    canvasContextReset();\r\n                });\r\n            }\r\n        })();\r\n        this.windowsSet.add(win);\r\n        this.windows.push(new WeakRef(win));\r\n    }\r\n    addShadowRoot(shadowRoot) {\r\n        this.shadowDoms.add(new WeakRef(shadowRoot));\r\n    }\r\n    resetShadowRoots() {\r\n        this.shadowDoms = new Set();\r\n    }\r\n    initFPSWorker() {\r\n        const worker = new Worker(t());\r\n        worker.onmessage = (e) => {\r\n            const data = e.data;\r\n            const { id } = data;\r\n            this.snapshotInProgressMap.set(id, false);\r\n            if (!('base64' in data))\r\n                return;\r\n            const { base64, type, width, height } = data;\r\n            this.mutationCb({\r\n                id,\r\n                type: CanvasContext['2D'],\r\n                commands: [\r\n                    {\r\n                        property: 'clearRect',\r\n                        args: [0, 0, width, height],\r\n                    },\r\n                    {\r\n                        property: 'drawImage',\r\n                        args: [\r\n                            {\r\n                                rr_type: 'ImageBitmap',\r\n                                args: [\r\n                                    {\r\n                                        rr_type: 'Blob',\r\n                                        data: [{ rr_type: 'ArrayBuffer', base64 }],\r\n                                        type,\r\n                                    },\r\n                                ],\r\n                            },\r\n                            0,\r\n                            0,\r\n                            width,\r\n                            height,\r\n                        ],\r\n                    },\r\n                ],\r\n            });\r\n        };\r\n        return worker;\r\n    }\r\n    initCanvasFPSObserver(fps, blockClass, blockSelector, unblockSelector, maxCanvasSize, options) {\r\n        const rafId = this.takeSnapshot(false, fps, blockClass, blockSelector, unblockSelector, maxCanvasSize, options.dataURLOptions);\r\n        this.restoreHandlers.push(() => {\r\n            cancelAnimationFrame(rafId);\r\n        });\r\n    }\r\n    initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector) {\r\n        const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, false);\r\n        const canvas2DReset = initCanvas2DMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector);\r\n        const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector, this.mirror);\r\n        this.restoreHandlers.push(() => {\r\n            canvasContextReset();\r\n            canvas2DReset();\r\n            canvasWebGL1and2Reset();\r\n        });\r\n    }\r\n    snapshot(canvasElement) {\r\n        const { options } = this;\r\n        const rafId = this.takeSnapshot(true, options.sampling === 'all' ? 2 : options.sampling || 2, options.blockClass, options.blockSelector, options.unblockSelector, options.maxCanvasSize, options.dataURLOptions, canvasElement);\r\n        this.restoreHandlers.push(() => {\r\n            cancelAnimationFrame(rafId);\r\n        });\r\n    }\r\n    takeSnapshot(isManualSnapshot, fps, blockClass, blockSelector, unblockSelector, maxCanvasSize, dataURLOptions, canvasElement) {\r\n        const timeBetweenSnapshots = 1000 / fps;\r\n        let lastSnapshotTime = 0;\r\n        let rafId;\r\n        const getCanvas = (canvasElement) => {\r\n            if (canvasElement) {\r\n                return [canvasElement];\r\n            }\r\n            const matchedCanvas = [];\r\n            const searchCanvas = (root) => {\r\n                root.querySelectorAll('canvas').forEach((canvas) => {\r\n                    if (!isBlocked(canvas, blockClass, blockSelector, unblockSelector, true)) {\r\n                        matchedCanvas.push(canvas);\r\n                    }\r\n                });\r\n            };\r\n            for (const item of this.windows) {\r\n                const window = item.deref();\r\n                if (window) {\r\n                    searchCanvas(window.document);\r\n                }\r\n            }\r\n            for (const item of this.shadowDoms) {\r\n                const shadowRoot = item.deref();\r\n                if (shadowRoot) {\r\n                    searchCanvas(shadowRoot);\r\n                }\r\n            }\r\n            return matchedCanvas;\r\n        };\r\n        const takeCanvasSnapshots = (timestamp) => {\r\n            if (!this.windows.length) {\r\n                return;\r\n            }\r\n            if (lastSnapshotTime &&\r\n                timestamp - lastSnapshotTime < timeBetweenSnapshots) {\r\n                rafId = onRequestAnimationFrame(takeCanvasSnapshots);\r\n                return;\r\n            }\r\n            lastSnapshotTime = timestamp;\r\n            getCanvas(canvasElement).forEach((canvas) => {\r\n                if (!this.mirror.hasNode(canvas)) {\r\n                    return;\r\n                }\r\n                const id = this.mirror.getId(canvas);\r\n                if (this.snapshotInProgressMap.get(id))\r\n                    return;\r\n                if (!canvas.width || !canvas.height)\r\n                    return;\r\n                this.snapshotInProgressMap.set(id, true);\r\n                if (!isManualSnapshot &&\r\n                    ['webgl', 'webgl2'].includes(canvas.__context)) {\r\n                    const context = canvas.getContext(canvas.__context);\r\n                    if (context?.getContextAttributes()?.preserveDrawingBuffer === false) {\r\n                        context.clear(context.COLOR_BUFFER_BIT);\r\n                    }\r\n                }\r\n                createImageBitmap(canvas)\r\n                    .then((bitmap) => {\r\n                    this.worker?.postMessage({\r\n                        id,\r\n                        bitmap,\r\n                        width: canvas.width,\r\n                        height: canvas.height,\r\n                        dataURLOptions,\r\n                        maxCanvasSize,\r\n                    }, [bitmap]);\r\n                })\r\n                    .catch((error) => {\r\n                    callbackWrapper(() => {\r\n                        throw error;\r\n                    })();\r\n                });\r\n            });\r\n            if (!isManualSnapshot) {\r\n                rafId = onRequestAnimationFrame(takeCanvasSnapshots);\r\n            }\r\n        };\r\n        rafId = onRequestAnimationFrame(takeCanvasSnapshots);\r\n        return rafId;\r\n    }\r\n    startPendingCanvasMutationFlusher() {\r\n        onRequestAnimationFrame(() => this.flushPendingCanvasMutations());\r\n    }\r\n    startRAFTimestamping() {\r\n        const setLatestRAFTimestamp = (timestamp) => {\r\n            this.rafStamps.latestId = timestamp;\r\n            onRequestAnimationFrame(setLatestRAFTimestamp);\r\n        };\r\n        onRequestAnimationFrame(setLatestRAFTimestamp);\r\n    }\r\n    flushPendingCanvasMutations() {\r\n        this.pendingCanvasMutations.forEach((values, canvas) => {\r\n            const id = this.mirror.getId(canvas);\r\n            this.flushPendingCanvasMutationFor(canvas, id);\r\n        });\r\n        onRequestAnimationFrame(() => this.flushPendingCanvasMutations());\r\n    }\r\n    flushPendingCanvasMutationFor(canvas, id) {\r\n        if (this.frozen || this.locked) {\r\n            return;\r\n        }\r\n        const valuesWithType = this.pendingCanvasMutations.get(canvas);\r\n        if (!valuesWithType || id === -1)\r\n            return;\r\n        const values = valuesWithType.map((value) => {\r\n            const { type, ...rest } = value;\r\n            return rest;\r\n        });\r\n        const { type } = valuesWithType[0];\r\n        this.mutationCb({ id, type, commands: values });\r\n        this.pendingCanvasMutations.delete(canvas);\r\n    }\r\n}\n\nexport { CanvasManager, CanvasManagerNoop };\n", "import type { CanvasManagerInterface, CanvasManagerOptions } from '@sentry-internal/replay';\nimport { CanvasManager } from '@sentry-internal/rrweb';\nimport { defineIntegration } from '@sentry/core';\nimport type { Integration, IntegrationFn } from '@sentry/core';\n\ninterface ReplayCanvasIntegration extends Integration {\n  snapshot: (canvasElement?: HTMLCanvasElement) => Promise<void>;\n}\n\ninterface ReplayCanvasOptions {\n  enableManualSnapshot?: boolean;\n  maxCanvasSize?: [width: number, height: number];\n  quality: 'low' | 'medium' | 'high';\n}\n\ntype GetCanvasManager = (options: CanvasManagerOptions) => CanvasManagerInterface;\nexport interface ReplayCanvasIntegrationOptions {\n  enableManualSnapshot?: boolean;\n  maxCanvasSize?: number;\n  recordCanvas: true;\n  getCanvasManager: GetCanvasManager;\n  sampling: {\n    canvas: number;\n  };\n  dataURLOptions: {\n    type: string;\n    quality: number;\n  };\n}\n\nconst CANVAS_QUALITY = {\n  low: {\n    sampling: {\n      canvas: 1,\n    },\n    dataURLOptions: {\n      type: 'image/webp',\n      quality: 0.25,\n    },\n  },\n  medium: {\n    sampling: {\n      canvas: 2,\n    },\n    dataURLOptions: {\n      type: 'image/webp',\n      quality: 0.4,\n    },\n  },\n  high: {\n    sampling: {\n      canvas: 4,\n    },\n    dataURLOptions: {\n      type: 'image/webp',\n      quality: 0.5,\n    },\n  },\n};\n\nconst INTEGRATION_NAME = 'ReplayCanvas';\nconst DEFAULT_MAX_CANVAS_SIZE = 1280;\n\n/** Exported only for type safe tests. */\nexport const _replayCanvasIntegration = ((options: Partial<ReplayCanvasOptions> = {}) => {\n  const [maxCanvasWidth, maxCanvasHeight] = options.maxCanvasSize || [];\n  const _canvasOptions = {\n    quality: options.quality || 'medium',\n    enableManualSnapshot: options.enableManualSnapshot,\n    maxCanvasSize: [\n      maxCanvasWidth ? Math.min(maxCanvasWidth, DEFAULT_MAX_CANVAS_SIZE) : DEFAULT_MAX_CANVAS_SIZE,\n      maxCanvasHeight ? Math.min(maxCanvasHeight, DEFAULT_MAX_CANVAS_SIZE) : DEFAULT_MAX_CANVAS_SIZE,\n    ] as [number, number],\n  };\n\n  let canvasManagerResolve: (value: CanvasManager) => void;\n  const _canvasManager: Promise<CanvasManager> = new Promise(resolve => (canvasManagerResolve = resolve));\n\n  return {\n    name: INTEGRATION_NAME,\n    getOptions(): ReplayCanvasIntegrationOptions {\n      const { quality, enableManualSnapshot, maxCanvasSize } = _canvasOptions;\n\n      return {\n        enableManualSnapshot,\n        recordCanvas: true,\n        getCanvasManager: (getCanvasManagerOptions: CanvasManagerOptions) => {\n          const manager = new CanvasManager({\n            ...getCanvasManagerOptions,\n            enableManualSnapshot,\n            maxCanvasSize,\n            errorHandler: (err: unknown) => {\n              try {\n                if (typeof err === 'object') {\n                  (err as Error & { __rrweb__?: boolean }).__rrweb__ = true;\n                }\n              } catch (error) {\n                // ignore errors here\n                // this can happen if the error is frozen or does not allow mutation for other reasons\n              }\n            },\n          });\n          canvasManagerResolve(manager);\n          return manager;\n        },\n        ...(CANVAS_QUALITY[quality || 'medium'] || CANVAS_QUALITY.medium),\n      };\n    },\n    async snapshot(canvasElement?: HTMLCanvasElement) {\n      const canvasManager = await _canvasManager;\n      canvasManager.snapshot(canvasElement);\n    },\n  };\n}) satisfies IntegrationFn<ReplayCanvasIntegration>;\n\n/**\n * Add this in addition to `replayIntegration()` to enable canvas recording.\n */\nexport const replayCanvasIntegration = defineIntegration(\n  _replayCanvasIntegration,\n) as IntegrationFn<ReplayCanvasIntegration>;\n", "import { GLOBAL_OBJ } from '@sentry/core';\n\n// exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`\n// prevents the browser package from being bundled in the CDN bundle, and avoids a\n// circular dependency between the browser and feedback packages\nexport const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\nexport const DOCUMENT = WINDOW.document;\nexport const NAVIGATOR = WINDOW.navigator;\n\nexport const TRIGGER_LABEL = 'Report a Bug';\nexport const CANCEL_BUTTON_LABEL = 'Cancel';\nexport const SUBMIT_BUTTON_LABEL = 'Send Bug Report';\nexport const CONFIRM_BUTTON_LABEL = 'Confirm';\nexport const FORM_TITLE = 'Report a Bug';\nexport const EMAIL_PLACEHOLDER = 'your.email@example.org';\nexport const EMAIL_LABEL = 'Email';\nexport const MESSAGE_PLACEHOLDER = \"What's the bug? What did you expect?\";\nexport const MESSAGE_LABEL = 'Description';\nexport const NAME_PLACEHOLDER = 'Your Name';\nexport const NAME_LABEL = 'Name';\nexport const SUCCESS_MESSAGE_TEXT = 'Thank you for your report!';\nexport const IS_REQUIRED_LABEL = '(required)';\nexport const ADD_SCREENSHOT_LABEL = 'Add a screenshot';\nexport const REMOVE_SCREENSHOT_LABEL = 'Remove screenshot';\n\nexport const FEEDBACK_WIDGET_SOURCE = 'widget';\nexport const FEEDBACK_API_SOURCE = 'api';\n\nexport const SUCCESS_MESSAGE_TIMEOUT = 5000;\n", "import type { Event, EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/core';\nimport { captureFeedback, getClient, getCurrentScope, getLocationHref } from '@sentry/core';\nimport { FEEDBACK_API_SOURCE } from '../constants';\n\n/**\n * Public API to send a Feedback item to Sentry\n */\nexport const sendFeedback: SendFeedback = (\n  params: SendFeedbackParams,\n  hint: EventHint & { includeReplay?: boolean } = { includeReplay: true },\n): Promise<string> => {\n  if (!params.message) {\n    throw new Error('Unable to submit feedback with empty message');\n  }\n\n  // We want to wait for the feedback to be sent (or not)\n  const client = getClient();\n\n  if (!client) {\n    throw new Error('No client setup, cannot send feedback.');\n  }\n\n  if (params.tags && Object.keys(params.tags).length) {\n    getCurrentScope().setTags(params.tags);\n  }\n  const eventId = captureFeedback(\n    {\n      source: FEEDBACK_API_SOURCE,\n      url: getLocationHref(),\n      ...params,\n    },\n    hint,\n  );\n\n  // We want to wait for the feedback to be sent (or not)\n  return new Promise<string>((resolve, reject) => {\n    // After 5s, we want to clear anyhow\n    const timeout = setTimeout(() => reject('Unable to determine if Feedback was correctly sent.'), 5_000);\n\n    const cleanup = client.on('afterSendEvent', (event: Event, response: TransportMakeRequestResponse) => {\n      if (event.event_id !== eventId) {\n        return;\n      }\n\n      clearTimeout(timeout);\n      cleanup();\n\n      // Require valid status codes, otherwise can assume feedback was not sent successfully\n      if (\n        response &&\n        typeof response.statusCode === 'number' &&\n        response.statusCode >= 200 &&\n        response.statusCode < 300\n      ) {\n        return resolve(eventId);\n      }\n\n      if (response && typeof response.statusCode === 'number' && response.statusCode === 0) {\n        return reject(\n          'Unable to send Feedback. This is because of network issues, or because you are using an ad-blocker.',\n        );\n      }\n\n      if (response && typeof response.statusCode === 'number' && response.statusCode === 403) {\n        return reject(\n          'Unable to send Feedback. This could be because this domain is not in your list of allowed domains.',\n        );\n      }\n\n      return reject(\n        'Unable to send Feedback. This could be because of network issues, or because you are using an ad-blocker',\n      );\n    });\n  });\n};\n\n/*\n * For reference, the fully built event looks something like this:\n * {\n *     \"type\": \"feedback\",\n *     \"event_id\": \"d2132d31b39445f1938d7e21b6bf0ec4\",\n *     \"timestamp\": 1597977777.6189718,\n *     \"dist\": \"1.12\",\n *     \"platform\": \"javascript\",\n *     \"environment\": \"production\",\n *     \"release\": 42,\n *     \"tags\": {\"transaction\": \"/organizations/:orgId/performance/:eventSlug/\"},\n *     \"sdk\": {\"name\": \"name\", \"version\": \"version\"},\n *     \"user\": {\n *         \"id\": \"123\",\n *         \"username\": \"user\",\n *         \"email\": \"user@site.com\",\n *         \"ip_address\": \"192.168.11.12\",\n *     },\n *     \"request\": {\n *         \"url\": None,\n *         \"headers\": {\n *             \"user-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15\"\n *         },\n *     },\n *     \"contexts\": {\n *         \"feedback\": {\n *             \"message\": \"test message\",\n *             \"contact_email\": \"test@example.com\",\n *             \"type\": \"feedback\",\n *         },\n *         \"trace\": {\n *             \"trace_id\": \"4C79F60C11214EB38604F4AE0781BFB2\",\n *             \"span_id\": \"FA90FDEAD5F74052\",\n *             \"type\": \"trace\",\n *         },\n *         \"replay\": {\n *             \"replay_id\": \"e2d42047b1c5431c8cba85ee2a8ab25d\",\n *         },\n *     },\n *   }\n */\n", "declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n", "import { NAVIGATOR } from '../constants';\n\n/**\n * Mobile browsers do not support `mediaDevices.getDisplayMedia` even though they have the api implemented\n * Instead they return things like `NotAllowedError` when called.\n *\n * It's simpler for us to browser sniff first, and avoid loading the integration if we can.\n *\n * https://stackoverflow.com/a/58879212\n * https://stackoverflow.com/a/3540295\n *\n * `mediaDevices.getDisplayMedia` is also only supported in secure contexts, and return a `mediaDevices is not supported` error, so we should also avoid loading the integration if we can.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia\n */\nexport function isScreenshotSupported(): boolean {\n  if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(NAVIGATOR.userAgent)) {\n    return false;\n  }\n  /**\n   * User agent on iPads show as Macintosh, so we need extra checks\n   *\n   * https://forums.developer.apple.com/forums/thread/119186\n   * https://stackoverflow.com/questions/60482650/how-to-detect-ipad-useragent-on-safari-browser\n   */\n  if (/Macintosh/i.test(NAVIGATOR.userAgent) && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 1) {\n    return false;\n  }\n  if (!isSecureContext) {\n    return false;\n  }\n  return true;\n}\n", "import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/core';\nimport type { OptionalFeedbackConfiguration } from '../core/types';\n\n/**\n * Quick and dirty deep merge for the Feedback integration options\n */\nexport function mergeOptions(\n  defaultOptions: FeedbackInternalOptions,\n  optionOverrides: OptionalFeedbackConfiguration,\n): FeedbackInternalOptions {\n  return {\n    ...defaultOptions,\n    ...optionOverrides,\n    tags: {\n      ...defaultOptions.tags,\n      ...optionOverrides.tags,\n    },\n    onFormOpen: () => {\n      optionOverrides.onFormOpen && optionOverrides.onFormOpen();\n      defaultOptions.onFormOpen && defaultOptions.onFormOpen();\n    },\n    onFormClose: () => {\n      optionOverrides.onFormClose && optionOverrides.onFormClose();\n      defaultOptions.onFormClose && defaultOptions.onFormClose();\n    },\n    onSubmitSuccess: (data: FeedbackFormData) => {\n      optionOverrides.onSubmitSuccess && optionOverrides.onSubmitSuccess(data);\n      defaultOptions.onSubmitSuccess && defaultOptions.onSubmitSuccess(data);\n    },\n    onSubmitError: (error: Error) => {\n      optionOverrides.onSubmitError && optionOverrides.onSubmitError(error);\n      defaultOptions.onSubmitError && defaultOptions.onSubmitError(error);\n    },\n    onFormSubmitted: () => {\n      optionOverrides.onFormSubmitted && optionOverrides.onFormSubmitted();\n      defaultOptions.onFormSubmitted && defaultOptions.onFormSubmitted();\n    },\n    themeDark: {\n      ...defaultOptions.themeDark,\n      ...optionOverrides.themeDark,\n    },\n    themeLight: {\n      ...defaultOptions.themeLight,\n      ...optionOverrides.themeLight,\n    },\n  };\n}\n", "import { DOCUMENT } from '../../constants';\n\n/**\n * Creates <style> element for widget actor (button that opens the dialog)\n */\nexport function createActorStyles(styleNonce?: string): HTMLStyleElement {\n  const style = DOCUMENT.createElement('style');\n  style.textContent = `\n.widget__actor {\n  position: fixed;\n  z-index: var(--z-index);\n  margin: var(--page-margin);\n  inset: var(--actor-inset);\n\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  padding: 16px;\n\n  font-family: inherit;\n  font-size: var(--font-size);\n  font-weight: 600;\n  line-height: 1.14em;\n  text-decoration: none;\n\n  background: var(--actor-background, var(--background));\n  border-radius: var(--actor-border-radius, 1.7em/50%);\n  border: var(--actor-border, var(--border));\n  box-shadow: var(--actor-box-shadow, var(--box-shadow));\n  color: var(--actor-color, var(--foreground));\n  fill: var(--actor-color, var(--foreground));\n  cursor: pointer;\n  opacity: 1;\n  transition: transform 0.2s ease-in-out;\n  transform: translate(0, 0) scale(1);\n}\n.widget__actor[aria-hidden=\"true\"] {\n  opacity: 0;\n  pointer-events: none;\n  visibility: hidden;\n  transform: translate(0, 16px) scale(0.98);\n}\n\n.widget__actor:hover {\n  background: var(--actor-hover-background, var(--background));\n  filter: var(--interactive-filter);\n}\n\n.widget__actor svg {\n  width: 1.14em;\n  height: 1.14em;\n}\n\n@media (max-width: 600px) {\n  .widget__actor span {\n    display: none;\n  }\n}\n`;\n\n  if (styleNonce) {\n    style.setAttribute('nonce', styleNonce);\n  }\n\n  return style;\n}\n", "/**\n * Helper function to set a dict of attributes on element (w/ specified namespace)\n */\nexport function setAttributesNS<T extends SVGElement>(el: T, attributes: Record<string, string>): T {\n  Object.entries(attributes).forEach(([key, val]) => {\n    el.setAttributeNS(null, key, val);\n  });\n  return el;\n}\n", "import { WINDOW } from '../../constants';\nimport { setAttributesNS } from '../../util/setAttributesNS';\n\nconst SIZE = 20;\nconst XMLNS = 'http://www.w3.org/2000/svg';\n\n/**\n * Feedback Icon\n */\nexport function FeedbackIcon(): SVGElement {\n  const createElementNS = <K extends keyof SVGElementTagNameMap>(tagName: K): SVGElementTagNameMap[K] =>\n    WINDOW.document.createElementNS(XMLNS, tagName);\n  const svg = setAttributesNS(createElementNS('svg'), {\n    width: `${SIZE}`,\n    height: `${SIZE}`,\n    viewBox: `0 0 ${SIZE} ${SIZE}`,\n    fill: 'var(--actor-color, var(--foreground))',\n  });\n\n  const g = setAttributesNS(createElementNS('g'), {\n    clipPath: 'url(#clip0_57_80)',\n  });\n\n  const path = setAttributesNS(createElementNS('path'), {\n    ['fill-rule']: 'evenodd',\n    ['clip-rule']: 'evenodd',\n    d: 'M15.6622 15H12.3997C12.2129 14.9959 12.031 14.9396 11.8747 14.8375L8.04965 12.2H7.49956V19.1C7.4875 19.3348 7.3888 19.5568 7.22256 19.723C7.05632 19.8892 6.83435 19.9879 6.59956 20H2.04956C1.80193 19.9968 1.56535 19.8969 1.39023 19.7218C1.21511 19.5467 1.1153 19.3101 1.11206 19.0625V12.2H0.949652C0.824431 12.2017 0.700142 12.1783 0.584123 12.1311C0.468104 12.084 0.362708 12.014 0.274155 11.9255C0.185602 11.8369 0.115689 11.7315 0.0685419 11.6155C0.0213952 11.4995 -0.00202913 11.3752 -0.00034808 11.25V3.75C-0.00900498 3.62067 0.0092504 3.49095 0.0532651 3.36904C0.0972798 3.24712 0.166097 3.13566 0.255372 3.04168C0.344646 2.94771 0.452437 2.87327 0.571937 2.82307C0.691437 2.77286 0.82005 2.74798 0.949652 2.75H8.04965L11.8747 0.1625C12.031 0.0603649 12.2129 0.00407221 12.3997 0H15.6622C15.9098 0.00323746 16.1464 0.103049 16.3215 0.278167C16.4966 0.453286 16.5964 0.689866 16.5997 0.9375V3.25269C17.3969 3.42959 18.1345 3.83026 18.7211 4.41679C19.5322 5.22788 19.9878 6.32796 19.9878 7.47502C19.9878 8.62209 19.5322 9.72217 18.7211 10.5333C18.1345 11.1198 17.3969 11.5205 16.5997 11.6974V14.0125C16.6047 14.1393 16.5842 14.2659 16.5395 14.3847C16.4948 14.5035 16.4268 14.6121 16.3394 14.7042C16.252 14.7962 16.147 14.8698 16.0307 14.9206C15.9144 14.9714 15.7891 14.9984 15.6622 15ZM1.89695 10.325H1.88715V4.625H8.33715C8.52423 4.62301 8.70666 4.56654 8.86215 4.4625L12.6872 1.875H14.7247V13.125H12.6872L8.86215 10.4875C8.70666 10.3835 8.52423 10.327 8.33715 10.325H2.20217C2.15205 10.3167 2.10102 10.3125 2.04956 10.3125C1.9981 10.3125 1.94708 10.3167 1.89695 10.325ZM2.98706 12.2V18.1625H5.66206V12.2H2.98706ZM16.5997 9.93612V5.01393C16.6536 5.02355 16.7072 5.03495 16.7605 5.04814C17.1202 5.13709 17.4556 5.30487 17.7425 5.53934C18.0293 5.77381 18.2605 6.06912 18.4192 6.40389C18.578 6.73866 18.6603 7.10452 18.6603 7.47502C18.6603 7.84552 18.578 8.21139 18.4192 8.54616C18.2605 8.88093 18.0293 9.17624 17.7425 9.41071C17.4556 9.64518 17.1202 9.81296 16.7605 9.90191C16.7072 9.91509 16.6536 9.9265 16.5997 9.93612Z',\n  });\n  svg.appendChild(g).appendChild(path);\n\n  const speakerDefs = createElementNS('defs');\n  const speakerClipPathDef = setAttributesNS(createElementNS('clipPath'), {\n    id: 'clip0_57_80',\n  });\n\n  const speakerRect = setAttributesNS(createElementNS('rect'), {\n    width: `${SIZE}`,\n    height: `${SIZE}`,\n    fill: 'white',\n  });\n\n  speakerClipPathDef.appendChild(speakerRect);\n  speakerDefs.appendChild(speakerClipPathDef);\n\n  svg.appendChild(speakerDefs).appendChild(speakerClipPathDef).appendChild(speakerRect);\n\n  return svg;\n}\n", "import { DOCUMENT, TRIGGER_LABEL } from '../../constants';\nimport { createActorStyles } from './Actor.css';\nimport { FeedbackIcon } from './FeedbackIcon';\n\nexport interface ActorProps {\n  triggerLabel: string;\n  triggerAriaLabel: string;\n  shadow: ShadowRoot;\n  styleNonce?: string;\n}\n\nexport interface ActorComponent {\n  el: HTMLElement;\n\n  appendToDom: () => void;\n\n  removeFromDom: () => void;\n\n  show: () => void;\n\n  hide: () => void;\n}\n\n/**\n * The sentry-provided button to open the feedback modal\n */\nexport function Actor({ triggerLabel, triggerAriaLabel, shadow, styleNonce }: ActorProps): ActorComponent {\n  const el = DOCUMENT.createElement('button');\n  el.type = 'button';\n  el.className = 'widget__actor';\n  el.ariaHidden = 'false';\n  el.ariaLabel = triggerAriaLabel || triggerLabel || TRIGGER_LABEL;\n  el.appendChild(FeedbackIcon());\n  if (triggerLabel) {\n    const label = DOCUMENT.createElement('span');\n    label.appendChild(DOCUMENT.createTextNode(triggerLabel));\n    el.appendChild(label);\n  }\n\n  const style = createActorStyles(styleNonce);\n\n  return {\n    el,\n    appendToDom(): void {\n      shadow.appendChild(style);\n      shadow.appendChild(el);\n    },\n    removeFromDom(): void {\n      shadow.removeChild(el);\n      shadow.removeChild(style);\n    },\n    show(): void {\n      el.ariaHidden = 'false';\n    },\n    hide(): void {\n      el.ariaHidden = 'true';\n    },\n  };\n}\n", "import type { FeedbackInternalOptions } from '@sentry/core';\nimport { DOCUMENT } from '../constants';\n\nconst PURPLE = 'rgba(88, 74, 192, 1)';\n\ninterface InternalTheme extends NonNullable<FeedbackInternalOptions['themeLight']> {\n  border: string;\n  interactiveFilter: string;\n}\n\nconst DEFAULT_LIGHT: InternalTheme = {\n  foreground: '#2b2233',\n  background: '#ffffff',\n  accentForeground: 'white',\n  accentBackground: PURPLE,\n  successColor: '#268d75',\n  errorColor: '#df3338',\n  border: '1.5px solid rgba(41, 35, 47, 0.13)',\n  boxShadow: '0px 4px 24px 0px rgba(43, 34, 51, 0.12)',\n  outline: '1px auto var(--accent-background)',\n  interactiveFilter: 'brightness(95%)',\n};\nconst DEFAULT_DARK: InternalTheme = {\n  foreground: '#ebe6ef',\n  background: '#29232f',\n  accentForeground: 'white',\n  accentBackground: PURPLE,\n  successColor: '#2da98c',\n  errorColor: '#f55459',\n  border: '1.5px solid rgba(235, 230, 239, 0.15)',\n  boxShadow: '0px 4px 24px 0px rgba(43, 34, 51, 0.12)',\n  outline: '1px auto var(--accent-background)',\n  interactiveFilter: 'brightness(150%)',\n};\n\nfunction getThemedCssVariables(theme: InternalTheme): string {\n  return `\n  --foreground: ${theme.foreground};\n  --background: ${theme.background};\n  --accent-foreground: ${theme.accentForeground};\n  --accent-background: ${theme.accentBackground};\n  --success-color: ${theme.successColor};\n  --error-color: ${theme.errorColor};\n  --border: ${theme.border};\n  --box-shadow: ${theme.boxShadow};\n  --outline: ${theme.outline};\n  --interactive-filter: ${theme.interactiveFilter};\n  `;\n}\n\n/**\n * Creates <style> element for widget actor (button that opens the dialog)\n */\nexport function createMainStyles({\n  colorScheme,\n  themeDark,\n  themeLight,\n  styleNonce,\n}: FeedbackInternalOptions): HTMLStyleElement {\n  const style = DOCUMENT.createElement('style');\n  style.textContent = `\n:host {\n  --font-family: system-ui, 'Helvetica Neue', Arial, sans-serif;\n  --font-size: 14px;\n  --z-index: 100000;\n\n  --page-margin: 16px;\n  --inset: auto 0 0 auto;\n  --actor-inset: var(--inset);\n\n  font-family: var(--font-family);\n  font-size: var(--font-size);\n\n  ${colorScheme !== 'system' ? 'color-scheme: only light;' : ''}\n\n  ${getThemedCssVariables(\n    colorScheme === 'dark' ? { ...DEFAULT_DARK, ...themeDark } : { ...DEFAULT_LIGHT, ...themeLight },\n  )}\n}\n\n${\n  colorScheme === 'system'\n    ? `\n@media (prefers-color-scheme: dark) {\n  :host {\n    ${getThemedCssVariables({ ...DEFAULT_DARK, ...themeDark })}\n  }\n}`\n    : ''\n}\n}\n`;\n\n  if (styleNonce) {\n    style.setAttribute('nonce', styleNonce);\n  }\n\n  return style;\n}\n", "import type {\n  FeedbackInternalOptions,\n  FeedbackModalIntegration,\n  FeedbackScreenshotIntegration,\n  Integration,\n  IntegrationFn,\n} from '@sentry/core';\nimport { addIntegration, isBrowser, logger } from '@sentry/core';\nimport {\n  ADD_SCREENSHOT_LABEL,\n  CANCEL_BUTTON_LABEL,\n  CONFIRM_BUTTON_LABEL,\n  DOCUMENT,\n  EMAIL_LABEL,\n  EMAIL_PLACEHOLDER,\n  FORM_TITLE,\n  IS_REQUIRED_LABEL,\n  MESSAGE_LABEL,\n  MESSAGE_PLACEHOLDER,\n  NAME_LABEL,\n  NAME_PLACEHOLDER,\n  REMOVE_SCREENSHOT_LABEL,\n  SUBMIT_BUTTON_LABEL,\n  SUCCESS_MESSAGE_TEXT,\n  TRIGGER_LABEL,\n} from '../constants';\nimport { DEBUG_BUILD } from '../util/debug-build';\nimport { isScreenshotSupported } from '../util/isScreenshotSupported';\nimport { mergeOptions } from '../util/mergeOptions';\nimport type { ActorComponent } from './components/Actor';\nimport { Actor } from './components/Actor';\nimport { createMainStyles } from './createMainStyles';\nimport { sendFeedback } from './sendFeedback';\nimport type { OptionalFeedbackConfiguration, OverrideFeedbackConfiguration } from './types';\n\ntype Unsubscribe = () => void;\n\n/**\n * Allow users to capture user feedback and send it to Sentry.\n */\n\ntype BuilderOptions =\n  | {\n      lazyLoadIntegration?: never;\n      getModalIntegration: () => IntegrationFn;\n      getScreenshotIntegration: () => IntegrationFn;\n    }\n  | {\n      // The type here should be `keyof typeof LazyLoadableIntegrations`, but that'll cause a cicrular\n      // dependency with @sentry/core\n      lazyLoadIntegration: (\n        name: 'feedbackModalIntegration' | 'feedbackScreenshotIntegration',\n        scriptNonce?: string,\n      ) => Promise<IntegrationFn>;\n      getModalIntegration?: never;\n      getScreenshotIntegration?: never;\n    };\n\nexport const buildFeedbackIntegration = ({\n  lazyLoadIntegration,\n  getModalIntegration,\n  getScreenshotIntegration,\n}: BuilderOptions): IntegrationFn<\n  Integration & {\n    attachTo(el: Element | string, optionOverrides?: OverrideFeedbackConfiguration): Unsubscribe;\n    createForm(\n      optionOverrides?: OverrideFeedbackConfiguration,\n    ): Promise<ReturnType<FeedbackModalIntegration['createDialog']>>;\n    createWidget(optionOverrides?: OverrideFeedbackConfiguration): ActorComponent;\n    remove(): void;\n  }\n> => {\n  const feedbackIntegration = (({\n    // FeedbackGeneralConfiguration\n    id = 'sentry-feedback',\n    autoInject = true,\n    showBranding = true,\n    isEmailRequired = false,\n    isNameRequired = false,\n    showEmail = true,\n    showName = true,\n    enableScreenshot = true,\n    useSentryUser = {\n      email: 'email',\n      name: 'username',\n    },\n    tags,\n    styleNonce,\n    scriptNonce,\n\n    // FeedbackThemeConfiguration\n    colorScheme = 'system',\n    themeLight = {},\n    themeDark = {},\n\n    // FeedbackTextConfiguration\n    addScreenshotButtonLabel = ADD_SCREENSHOT_LABEL,\n    cancelButtonLabel = CANCEL_BUTTON_LABEL,\n    confirmButtonLabel = CONFIRM_BUTTON_LABEL,\n    emailLabel = EMAIL_LABEL,\n    emailPlaceholder = EMAIL_PLACEHOLDER,\n    formTitle = FORM_TITLE,\n    isRequiredLabel = IS_REQUIRED_LABEL,\n    messageLabel = MESSAGE_LABEL,\n    messagePlaceholder = MESSAGE_PLACEHOLDER,\n    nameLabel = NAME_LABEL,\n    namePlaceholder = NAME_PLACEHOLDER,\n    removeScreenshotButtonLabel = REMOVE_SCREENSHOT_LABEL,\n    submitButtonLabel = SUBMIT_BUTTON_LABEL,\n    successMessageText = SUCCESS_MESSAGE_TEXT,\n    triggerLabel = TRIGGER_LABEL,\n    triggerAriaLabel = '',\n\n    // FeedbackCallbacks\n    onFormOpen,\n    onFormClose,\n    onSubmitSuccess,\n    onSubmitError,\n    onFormSubmitted,\n  }: OptionalFeedbackConfiguration = {}) => {\n    const _options = {\n      id,\n      autoInject,\n      showBranding,\n      isEmailRequired,\n      isNameRequired,\n      showEmail,\n      showName,\n      enableScreenshot,\n      useSentryUser,\n      tags,\n      styleNonce,\n      scriptNonce,\n\n      colorScheme,\n      themeDark,\n      themeLight,\n\n      triggerLabel,\n      triggerAriaLabel,\n      cancelButtonLabel,\n      submitButtonLabel,\n      confirmButtonLabel,\n      formTitle,\n      emailLabel,\n      emailPlaceholder,\n      messageLabel,\n      messagePlaceholder,\n      nameLabel,\n      namePlaceholder,\n      successMessageText,\n      isRequiredLabel,\n      addScreenshotButtonLabel,\n      removeScreenshotButtonLabel,\n\n      onFormClose,\n      onFormOpen,\n      onSubmitError,\n      onSubmitSuccess,\n      onFormSubmitted,\n    };\n\n    let _shadow: ShadowRoot | null = null;\n    let _subscriptions: Unsubscribe[] = [];\n\n    /**\n     * Get the shadow root where we will append css\n     */\n    const _createShadow = (options: FeedbackInternalOptions): ShadowRoot => {\n      if (!_shadow) {\n        const host = DOCUMENT.createElement('div');\n        host.id = String(options.id);\n        DOCUMENT.body.appendChild(host);\n\n        _shadow = host.attachShadow({ mode: 'open' });\n        _shadow.appendChild(createMainStyles(options));\n      }\n      return _shadow as ShadowRoot;\n    };\n\n    const _loadAndRenderDialog = async (\n      options: FeedbackInternalOptions,\n    ): Promise<ReturnType<FeedbackModalIntegration['createDialog']>> => {\n      const screenshotRequired = options.enableScreenshot && isScreenshotSupported();\n\n      let modalIntegration: FeedbackModalIntegration;\n      let screenshotIntegration: FeedbackScreenshotIntegration | undefined;\n\n      try {\n        const modalIntegrationFn = getModalIntegration\n          ? getModalIntegration()\n          : await lazyLoadIntegration('feedbackModalIntegration', scriptNonce);\n        modalIntegration = modalIntegrationFn() as FeedbackModalIntegration;\n        addIntegration(modalIntegration);\n      } catch {\n        DEBUG_BUILD &&\n          logger.error(\n            '[Feedback] Error when trying to load feedback integrations. Try using `feedbackSyncIntegration` in your `Sentry.init`.',\n          );\n        throw new Error('[Feedback] Missing feedback modal integration!');\n      }\n\n      try {\n        const screenshotIntegrationFn = screenshotRequired\n          ? getScreenshotIntegration\n            ? getScreenshotIntegration()\n            : await lazyLoadIntegration('feedbackScreenshotIntegration', scriptNonce)\n          : undefined;\n\n        if (screenshotIntegrationFn) {\n          screenshotIntegration = screenshotIntegrationFn() as FeedbackScreenshotIntegration;\n          addIntegration(screenshotIntegration);\n        }\n      } catch {\n        DEBUG_BUILD &&\n          logger.error('[Feedback] Missing feedback screenshot integration. Proceeding without screenshots.');\n      }\n\n      const dialog = modalIntegration.createDialog({\n        options: {\n          ...options,\n          onFormClose: () => {\n            dialog && dialog.close();\n            options.onFormClose && options.onFormClose();\n          },\n          onFormSubmitted: () => {\n            dialog && dialog.close();\n            options.onFormSubmitted && options.onFormSubmitted();\n          },\n        },\n        screenshotIntegration,\n        sendFeedback,\n        shadow: _createShadow(options),\n      });\n\n      return dialog;\n    };\n\n    const _attachTo = (el: Element | string, optionOverrides: OverrideFeedbackConfiguration = {}): Unsubscribe => {\n      const mergedOptions = mergeOptions(_options, optionOverrides);\n\n      const targetEl =\n        typeof el === 'string' ? DOCUMENT.querySelector(el) : typeof el.addEventListener === 'function' ? el : null;\n\n      if (!targetEl) {\n        DEBUG_BUILD && logger.error('[Feedback] Unable to attach to target element');\n        throw new Error('Unable to attach to target element');\n      }\n\n      let dialog: ReturnType<FeedbackModalIntegration['createDialog']> | null = null;\n      const handleClick = async (): Promise<void> => {\n        if (!dialog) {\n          dialog = await _loadAndRenderDialog({\n            ...mergedOptions,\n            onFormSubmitted: () => {\n              dialog && dialog.removeFromDom();\n              mergedOptions.onFormSubmitted && mergedOptions.onFormSubmitted();\n            },\n          });\n        }\n        dialog.appendToDom();\n        dialog.open();\n      };\n      targetEl.addEventListener('click', handleClick);\n      const unsubscribe = (): void => {\n        _subscriptions = _subscriptions.filter(sub => sub !== unsubscribe);\n        dialog && dialog.removeFromDom();\n        dialog = null;\n        targetEl.removeEventListener('click', handleClick);\n      };\n      _subscriptions.push(unsubscribe);\n      return unsubscribe;\n    };\n\n    const _createActor = (optionOverrides: OverrideFeedbackConfiguration = {}): ActorComponent => {\n      const mergedOptions = mergeOptions(_options, optionOverrides);\n      const shadow = _createShadow(mergedOptions);\n      const actor = Actor({\n        triggerLabel: mergedOptions.triggerLabel,\n        triggerAriaLabel: mergedOptions.triggerAriaLabel,\n        shadow,\n        styleNonce,\n      });\n      _attachTo(actor.el, {\n        ...mergedOptions,\n        onFormOpen() {\n          actor.hide();\n        },\n        onFormClose() {\n          actor.show();\n        },\n        onFormSubmitted() {\n          actor.show();\n        },\n      });\n      return actor;\n    };\n\n    return {\n      name: 'Feedback',\n      setupOnce() {\n        if (!isBrowser() || !_options.autoInject) {\n          return;\n        }\n\n        if (DOCUMENT.readyState === 'loading') {\n          DOCUMENT.addEventListener('DOMContentLoaded', () => _createActor().appendToDom());\n        } else {\n          _createActor().appendToDom();\n        }\n      },\n\n      /**\n       * Adds click listener to the element to open a feedback dialog\n       *\n       * The returned function can be used to remove the click listener\n       */\n      attachTo: _attachTo,\n\n      /**\n       * Creates a new widget which is composed of a Button which triggers a Dialog.\n       * Accepts partial options to override any options passed to constructor.\n       */\n      createWidget(optionOverrides: OverrideFeedbackConfiguration = {}): ActorComponent {\n        const actor = _createActor(mergeOptions(_options, optionOverrides));\n        actor.appendToDom();\n        return actor;\n      },\n\n      /**\n       * Creates a new Form which you can\n       * Accepts partial options to override any options passed to constructor.\n       */\n      async createForm(\n        optionOverrides: OverrideFeedbackConfiguration = {},\n      ): Promise<ReturnType<FeedbackModalIntegration['createDialog']>> {\n        return _loadAndRenderDialog(mergeOptions(_options, optionOverrides));\n      },\n\n      /**\n       * Removes the Feedback integration (including host, shadow DOM, and all widgets)\n       */\n      remove(): void {\n        if (_shadow) {\n          _shadow.parentElement && _shadow.parentElement.remove();\n          _shadow = null;\n        }\n        // Remove any lingering subscriptions\n        _subscriptions.forEach(sub => sub());\n        _subscriptions = [];\n      },\n    };\n  }) satisfies IntegrationFn;\n\n  return feedbackIntegration;\n};\n", "import { getClient } from '@sentry/core';\nimport type { buildFeedbackIntegration } from './integration';\n\ntype FeedbackIntegration = ReturnType<typeof buildFeedbackIntegration>;\n\n/**\n * This is a small utility to get a type-safe instance of the Feedback integration.\n */\nexport function getFeedback(): ReturnType<FeedbackIntegration> | undefined {\n  const client = getClient();\n  return client && client.getIntegrationByName<ReturnType<FeedbackIntegration>>('Feedback');\n}\n", "var n,l,u,t,i,o,r,f,e,c={},s=[],a=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,h=Array.isArray;function v(n,l){for(var u in l)n[u]=l[u];return n}function p(n){var l=n.parentNode;l&&l.removeChild(n)}function y(l,u,t){var i,o,r,f={};for(r in u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return d(l,f,i,o,null)}function d(n,t,i,o,r){var f={type:n,props:t,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,constructor:void 0,__v:null==r?++u:r,__i:-1,__u:0};return null==r&&null!=l.vnode&&l.vnode(f),f}function _(){return{current:null}}function g(n){return n.children}function b(n,l){this.props=n,this.context=l}function m(n,l){if(null==l)return n.__?m(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?m(n):null}function w(n,u,t){var i,o=n.__v,r=o.__e,f=n.__P;if(f)return(i=v({},o)).__v=o.__v+1,l.vnode&&l.vnode(i),M(f,i,o,n.__n,void 0!==f.ownerSVGElement,32&o.__u?[r]:null,u,null==r?m(o):r,!!(32&o.__u),t),i.__.__k[i.__i]=i,i.__d=void 0,i.__e!=r&&k(i),i}function k(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k(n)}}function x(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!C.__r++||o!==l.debounceRendering)&&((o=l.debounceRendering)||r)(C)}function C(){var n,u,t,o=[],r=[];for(i.sort(f);n=i.shift();)n.__d&&(t=i.length,u=w(n,o,r)||u,0===t||i.length>t?(j(o,u,r),r.length=o.length=0,u=void 0,i.sort(f)):u&&l.__c&&l.__c(u,s));u&&j(o,u,r),C.__r=0}function P(n,l,u,t,i,o,r,f,e,a,h){var v,p,y,d,_,g=t&&t.__k||s,b=l.length;for(u.__d=e,S(u,l,g),e=u.__d,v=0;v<b;v++)null!=(y=u.__k[v])&&\"boolean\"!=typeof y&&\"function\"!=typeof y&&(p=-1===y.__i?c:g[y.__i]||c,y.__i=v,M(n,y,p,i,o,r,f,e,a,h),d=y.__e,y.ref&&p.ref!=y.ref&&(p.ref&&N(p.ref,null,y),h.push(y.ref,y.__c||d,y)),null==_&&null!=d&&(_=d),65536&y.__u||p.__k===y.__k?e=$(y,e,n):\"function\"==typeof y.type&&void 0!==y.__d?e=y.__d:d&&(e=d.nextSibling),y.__d=void 0,y.__u&=-196609);u.__d=e,u.__e=_}function S(n,l,u){var t,i,o,r,f,e=l.length,c=u.length,s=c,a=0;for(n.__k=[],t=0;t<e;t++)null!=(i=n.__k[t]=null==(i=l[t])||\"boolean\"==typeof i||\"function\"==typeof i?null:\"string\"==typeof i||\"number\"==typeof i||\"bigint\"==typeof i||i.constructor==String?d(null,i,null,null,i):h(i)?d(g,{children:i},null,null,null):void 0===i.constructor&&i.__b>0?d(i.type,i.props,i.key,i.ref?i.ref:null,i.__v):i)?(i.__=n,i.__b=n.__b+1,f=I(i,u,r=t+a,s),i.__i=f,o=null,-1!==f&&(s--,(o=u[f])&&(o.__u|=131072)),null==o||null===o.__v?(-1==f&&a--,\"function\"!=typeof i.type&&(i.__u|=65536)):f!==r&&(f===r+1?a++:f>r?s>e-r?a+=f-r:a--:a=f<r&&f==r-1?f-r:0,f!==t+a&&(i.__u|=65536))):(o=u[t])&&null==o.key&&o.__e&&(o.__e==n.__d&&(n.__d=m(o)),O(o,o,!1),u[t]=null,s--);if(s)for(t=0;t<c;t++)null!=(o=u[t])&&0==(131072&o.__u)&&(o.__e==n.__d&&(n.__d=m(o)),O(o,o))}function $(n,l,u){var t,i;if(\"function\"==typeof n.type){for(t=n.__k,i=0;t&&i<t.length;i++)t[i]&&(t[i].__=n,l=$(t[i],l,u));return l}n.__e!=l&&(u.insertBefore(n.__e,l||null),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8===l.nodeType);return l}function H(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(h(n)?n.some(function(n){H(n,l)}):l.push(n)),l}function I(n,l,u,t){var i=n.key,o=n.type,r=u-1,f=u+1,e=l[u];if(null===e||e&&i==e.key&&o===e.type)return u;if(t>(null!=e&&0==(131072&e.__u)?1:0))for(;r>=0||f<l.length;){if(r>=0){if((e=l[r])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return r;r--}if(f<l.length){if((e=l[f])&&0==(131072&e.__u)&&i==e.key&&o===e.type)return f;f++}}return-1}function T(n,l,u){\"-\"===l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||a.test(l)?u:u+\"px\"}function A(n,l,u,t,i){var o;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof t&&(n.style.cssText=t=\"\"),t)for(l in t)u&&l in u||T(n.style,l,\"\");if(u)for(l in u)t&&u[l]===t[l]||T(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])o=l!==(l=l.replace(/(PointerCapture)$|Capture$/i,\"$1\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?t?u.u=t.u:(u.u=Date.now(),n.addEventListener(l,o?L:D,o)):n.removeEventListener(l,o?L:D,o);else{if(i)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!==l&&\"height\"!==l&&\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&\"rowSpan\"!==l&&\"colSpan\"!==l&&\"role\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&\"-\"!==l[4]?n.removeAttribute(l):n.setAttribute(l,u))}}function D(n){if(this.l){var u=this.l[n.type+!1];if(n.t){if(n.t<=u.u)return}else n.t=Date.now();return u(l.event?l.event(n):n)}}function L(n){if(this.l)return this.l[n.type+!0](l.event?l.event(n):n)}function M(n,u,t,i,o,r,f,e,c,s){var a,p,y,d,_,m,w,k,x,C,S,$,H,I,T,A=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),r=[e=u.__e=t.__e]),(a=l.__b)&&a(u);n:if(\"function\"==typeof A)try{if(k=u.props,x=(a=A.contextType)&&i[a.__c],C=a?x?x.props.value:a.__:i,t.__c?w=(p=u.__c=t.__c).__=p.__E:(\"prototype\"in A&&A.prototype.render?u.__c=p=new A(k,C):(u.__c=p=new b(k,C),p.constructor=A,p.render=q),x&&x.sub(p),p.props=k,p.state||(p.state={}),p.context=C,p.__n=i,y=p.__d=!0,p.__h=[],p._sb=[]),null==p.__s&&(p.__s=p.state),null!=A.getDerivedStateFromProps&&(p.__s==p.state&&(p.__s=v({},p.__s)),v(p.__s,A.getDerivedStateFromProps(k,p.__s))),d=p.props,_=p.state,p.__v=u,y)null==A.getDerivedStateFromProps&&null!=p.componentWillMount&&p.componentWillMount(),null!=p.componentDidMount&&p.__h.push(p.componentDidMount);else{if(null==A.getDerivedStateFromProps&&k!==d&&null!=p.componentWillReceiveProps&&p.componentWillReceiveProps(k,C),!p.__e&&(null!=p.shouldComponentUpdate&&!1===p.shouldComponentUpdate(k,p.__s,C)||u.__v===t.__v)){for(u.__v!==t.__v&&(p.props=k,p.state=p.__s,p.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.forEach(function(n){n&&(n.__=u)}),S=0;S<p._sb.length;S++)p.__h.push(p._sb[S]);p._sb=[],p.__h.length&&f.push(p);break n}null!=p.componentWillUpdate&&p.componentWillUpdate(k,p.__s,C),null!=p.componentDidUpdate&&p.__h.push(function(){p.componentDidUpdate(d,_,m)})}if(p.context=C,p.props=k,p.__P=n,p.__e=!1,$=l.__r,H=0,\"prototype\"in A&&A.prototype.render){for(p.state=p.__s,p.__d=!1,$&&$(u),a=p.render(p.props,p.state,p.context),I=0;I<p._sb.length;I++)p.__h.push(p._sb[I]);p._sb=[]}else do{p.__d=!1,$&&$(u),a=p.render(p.props,p.state,p.context),p.state=p.__s}while(p.__d&&++H<25);p.state=p.__s,null!=p.getChildContext&&(i=v(v({},i),p.getChildContext())),y||null==p.getSnapshotBeforeUpdate||(m=p.getSnapshotBeforeUpdate(d,_)),P(n,h(T=null!=a&&a.type===g&&null==a.key?a.props.children:a)?T:[T],u,t,i,o,r,f,e,c,s),p.base=u.__e,u.__u&=-161,p.__h.length&&f.push(p),w&&(p.__E=p.__=null)}catch(n){u.__v=null,c||null!=r?(u.__e=e,u.__u|=c?160:32,r[r.indexOf(e)]=null):(u.__e=t.__e,u.__k=t.__k),l.__e(n,u,t)}else null==r&&u.__v===t.__v?(u.__k=t.__k,u.__e=t.__e):u.__e=z(t.__e,u,t,i,o,r,f,c,s);(a=l.diffed)&&a(u)}function j(n,u,t){for(var i=0;i<t.length;i++)N(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function z(l,u,t,i,o,r,f,e,s){var a,v,y,d,_,g,b,w=t.props,k=u.props,x=u.type;if(\"svg\"===x&&(o=!0),null!=r)for(a=0;a<r.length;a++)if((_=r[a])&&\"setAttribute\"in _==!!x&&(x?_.localName===x:3===_.nodeType)){l=_,r[a]=null;break}if(null==l){if(null===x)return document.createTextNode(k);l=o?document.createElementNS(\"http://www.w3.org/2000/svg\",x):document.createElement(x,k.is&&k),r=null,e=!1}if(null===x)w===k||e&&l.data===k||(l.data=k);else{if(r=r&&n.call(l.childNodes),w=t.props||c,!e&&null!=r)for(w={},a=0;a<l.attributes.length;a++)w[(_=l.attributes[a]).name]=_.value;for(a in w)_=w[a],\"children\"==a||(\"dangerouslySetInnerHTML\"==a?y=_:\"key\"===a||a in k||A(l,a,null,_,o));for(a in k)_=k[a],\"children\"==a?d=_:\"dangerouslySetInnerHTML\"==a?v=_:\"value\"==a?g=_:\"checked\"==a?b=_:\"key\"===a||e&&\"function\"!=typeof _||w[a]===_||A(l,a,_,w[a],o);if(v)e||y&&(v.__html===y.__html||v.__html===l.innerHTML)||(l.innerHTML=v.__html),u.__k=[];else if(y&&(l.innerHTML=\"\"),P(l,h(d)?d:[d],u,t,i,o&&\"foreignObject\"!==x,r,f,r?r[0]:t.__k&&m(t,0),e,s),null!=r)for(a=r.length;a--;)null!=r[a]&&p(r[a]);e||(a=\"value\",void 0!==g&&(g!==l[a]||\"progress\"===x&&!g||\"option\"===x&&g!==w[a])&&A(l,a,g,w[a],!1),a=\"checked\",void 0!==b&&b!==l[a]&&A(l,a,b,w[a],!1))}return l}function N(n,u,t){try{\"function\"==typeof n?n(u):n.current=u}catch(n){l.__e(n,t)}}function O(n,u,t){var i,o;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!==n.__e||N(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null,n.__c=void 0}if(i=n.__k)for(o=0;o<i.length;o++)i[o]&&O(i[o],u,t||\"function\"!=typeof n.type);t||null==n.__e||p(n.__e),n.__=n.__e=n.__d=void 0}function q(n,l,u){return this.constructor(n,u)}function B(u,t,i){var o,r,f,e;l.__&&l.__(u,t),r=(o=\"function\"==typeof i)?null:i&&i.__k||t.__k,f=[],e=[],M(t,u=(!o&&i||t).__k=y(g,null,[u]),r||c,c,void 0!==t.ownerSVGElement,!o&&i?[i]:r?null:t.firstChild?n.call(t.childNodes):null,f,!o&&i?i:r?r.__e:t.firstChild,o,e),u.__d=void 0,j(f,u,e)}function E(n,l){B(n,l,E)}function F(l,u,t){var i,o,r,f,e=v({},l.props);for(r in l.type&&l.type.defaultProps&&(f=l.type.defaultProps),u)\"key\"==r?i=u[r]:\"ref\"==r?o=u[r]:e[r]=void 0===u[r]&&void 0!==f?f[r]:u[r];return arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),d(l.type,e,i||l.key,o||l.ref,null)}function G(n,l){var u={__c:l=\"__cC\"+e++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,t;return this.getChildContext||(u=[],(t={})[l]=this,this.getChildContext=function(){return t},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(function(n){n.__e=!0,x(n)})},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=s.slice,l={__e:function(n,l,u,t){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&null==n.constructor},b.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=v({},this.state),\"function\"==typeof n&&(n=n(v({},u),this.props)),n&&v(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),x(this))},b.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),x(this))},b.prototype.render=g,i=[],r=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,f=function(n,l){return n.__v.__b-l.__v.__b},C.__r=0,e=0;export{b as Component,g as Fragment,F as cloneElement,G as createContext,y as createElement,_ as createRef,y as h,E as hydrate,t as isValidElement,l as options,B as render,H as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n", "import{options as n}from\"preact\";var t,r,u,i,o=0,f=[],c=[],e=n,a=e.__b,v=e.__r,l=e.diffed,m=e.__c,s=e.unmount,d=e.__;function h(n,t){e.__h&&e.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({__V:c}),u.__[n]}function p(n){return o=1,y(D,n)}function y(n,u,i){var o=h(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return!!n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=!1;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),!(!i&&o.__c.props===n)&&(!c||c.call(this,n,t,r))};r.u=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function _(n,u){var i=h(t++,3);!e.__s&&C(i.__H,u)&&(i.__=n,i.i=u,r.__H.__h.push(i))}function A(n,u){var i=h(t++,4);!e.__s&&C(i.__H,u)&&(i.__=n,i.i=u,r.__h.push(i))}function F(n){return o=5,q(function(){return{current:n}},[])}function T(n,t,r){o=6,A(function(){return\"function\"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function q(n,r){var u=h(t++,7);return C(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function x(n,t){return o=8,q(function(){return n},t)}function P(n){var u=r.context[n.__c],i=h(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function V(n,t){e.useDebugValue&&e.useDebugValue(t?t(n):n)}function b(n){var u=h(t++,10),i=p();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function g(){var n=h(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function j(){for(var n;n=f.shift();)if(n.__P&&n.__H)try{n.__H.__h.forEach(z),n.__H.__h.forEach(B),n.__H.__h=[]}catch(t){n.__H.__h=[],e.__e(t,n.__v)}}e.__b=function(n){r=null,a&&a(n)},e.__=function(n,t){t.__k&&t.__k.__m&&(n.__m=t.__k.__m),d&&d(n,t)},e.__r=function(n){v&&v(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=c,n.__N=n.i=void 0})):(i.__h.forEach(z),i.__h.forEach(B),i.__h=[],t=0)),u=r},e.diffed=function(n){l&&l(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===e.requestAnimationFrame||((i=e.requestAnimationFrame)||w)(j)),t.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==c&&(n.__=n.__V),n.i=void 0,n.__V=c})),u=r=null},e.__c=function(n,t){t.some(function(n){try{n.__h.forEach(z),n.__h=n.__h.filter(function(n){return!n.__||B(n)})}catch(r){t.some(function(n){n.__h&&(n.__h=[])}),t=[],e.__e(r,n.__v)}}),m&&m(n,t)},e.unmount=function(n){s&&s(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{z(n)}catch(n){t=n}}),r.__H=void 0,t&&e.__e(t,r.__v))};var k=\"function\"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);k&&(t=requestAnimationFrame(r))}function z(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function B(n){var t=r;n.__c=n.__(),r=t}function C(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return\"function\"==typeof t?t(n):t}export{x as useCallback,P as useContext,V as useDebugValue,_ as useEffect,b as useErrorBoundary,g as useId,T as useImperativeHandle,A as useLayoutEffect,q as useMemo,y as useReducer,F as useRef,p as useState};\n//# sourceMappingURL=hooks.module.js.map\n", "import { DOCUMENT } from '../../constants';\nimport { setAttributesNS } from '../../util/setAttributesNS';\n\nconst XMLNS = 'http://www.w3.org/2000/svg';\n\n/**\n * Sentry Logo\n */\nexport function SentryLogo(): SVGElement {\n  const createElementNS = <K extends keyof SVGElementTagNameMap>(tagName: K): SVGElementTagNameMap[K] =>\n    DOCUMENT.createElementNS(XMLNS, tagName);\n  const svg = setAttributesNS(createElementNS('svg'), {\n    width: '32',\n    height: '30',\n    viewBox: '0 0 72 66',\n    fill: 'inherit',\n  });\n\n  const path = setAttributesNS(createElementNS('path'), {\n    transform: 'translate(11, 11)',\n    d: 'M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z',\n  });\n  svg.appendChild(path);\n\n  return svg;\n}\n", "import type { FeedbackInternalOptions } from '@sentry/core';\n// biome-ignore lint/nursery/noUnusedImports: reason\nimport { h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars\nimport type { VNode } from 'preact';\nimport { useMemo } from 'preact/hooks';\nimport { SentryLogo } from './SentryLogo';\n\nexport interface Props {\n  options: FeedbackInternalOptions;\n}\n\nexport function DialogHeader({ options }: Props): VNode {\n  const logoHtml = useMemo(() => ({ __html: SentryLogo().outerHTML }), []);\n\n  return (\n    <h2 class=\"dialog__header\">\n      <span class=\"dialog__title\">{options.formTitle}</span>\n      {options.showBranding ? (\n        <a\n          class=\"brand-link\"\n          target=\"_blank\"\n          href=\"https://sentry.io/welcome/\"\n          title=\"Powered by Sentry\"\n          rel=\"noopener noreferrer\"\n          dangerouslySetInnerHTML={logoHtml}\n        />\n      ) : null}\n    </h2>\n  );\n}\n", "import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/core';\n\nexport type Props = Pick<\n  FeedbackInternalOptions,\n  'emailLabel' | 'isEmailRequired' | 'isNameRequired' | 'messageLabel' | 'nameLabel'\n>;\n\n/**\n * Validate that a given feedback submission has the required fields\n */\nexport function getMissingFields(feedback: FeedbackFormData, props: Props): string[] {\n  const emptyFields = [];\n  if (props.isNameRequired && !feedback.name) {\n    emptyFields.push(props.nameLabel);\n  }\n  if (props.isEmailRequired && !feedback.email) {\n    emptyFields.push(props.emailLabel);\n  }\n  if (!feedback.message) {\n    emptyFields.push(props.messageLabel);\n  }\n\n  return emptyFields;\n}\n", "import { logger } from '@sentry/core';\nimport type {\n  FeedbackFormData,\n  FeedbackInternalOptions,\n  FeedbackScreenshotIntegration,\n  SendFeedback,\n} from '@sentry/core';\n// biome-ignore lint/nursery/noUnusedImports: reason\nimport { h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars\nimport type { JSX, VNode } from 'preact';\nimport { useCallback, useState } from 'preact/hooks';\nimport { FEEDBACK_WIDGET_SOURCE } from '../../constants';\nimport { DEBUG_BUILD } from '../../util/debug-build';\nimport { getMissingFields } from '../../util/validate';\n\nexport interface Props extends Pick<FeedbackInternalOptions, 'showEmail' | 'showName'> {\n  options: FeedbackInternalOptions;\n  defaultEmail: string;\n  defaultName: string;\n  onFormClose: () => void;\n  onSubmit: SendFeedback;\n  onSubmitSuccess: (data: FeedbackFormData) => void;\n  onSubmitError: (error: Error) => void;\n  screenshotInput: ReturnType<FeedbackScreenshotIntegration['createInput']> | undefined;\n}\n\nfunction retrieveStringValue(formData: FormData, key: string): string {\n  const value = formData.get(key);\n  if (typeof value === 'string') {\n    return value.trim();\n  }\n  return '';\n}\n\nexport function Form({\n  options,\n  defaultEmail,\n  defaultName,\n\n  onFormClose,\n  onSubmit,\n  onSubmitSuccess,\n  onSubmitError,\n  showEmail,\n  showName,\n  screenshotInput,\n}: Props): VNode {\n  const {\n    tags,\n    addScreenshotButtonLabel,\n    removeScreenshotButtonLabel,\n    cancelButtonLabel,\n    emailLabel,\n    emailPlaceholder,\n    isEmailRequired,\n    isNameRequired,\n    messageLabel,\n    messagePlaceholder,\n    nameLabel,\n    namePlaceholder,\n    submitButtonLabel,\n    isRequiredLabel,\n  } = options;\n  // TODO: set a ref on the form, and whenever an input changes call processForm() and setError()\n  const [error, setError] = useState<null | string>(null);\n\n  const [showScreenshotInput, setShowScreenshotInput] = useState(false);\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  const ScreenshotInputComponent: any = screenshotInput && screenshotInput.input;\n\n  const [screenshotError, setScreenshotError] = useState<null | Error>(null);\n  const onScreenshotError = useCallback((error: Error) => {\n    setScreenshotError(error);\n    setShowScreenshotInput(false);\n  }, []);\n\n  const hasAllRequiredFields = useCallback(\n    (data: FeedbackFormData) => {\n      const missingFields = getMissingFields(data, {\n        emailLabel,\n        isEmailRequired,\n        isNameRequired,\n        messageLabel,\n        nameLabel,\n      });\n\n      if (missingFields.length > 0) {\n        setError(`Please enter in the following required fields: ${missingFields.join(', ')}`);\n      } else {\n        setError(null);\n      }\n\n      return missingFields.length === 0;\n    },\n    [emailLabel, isEmailRequired, isNameRequired, messageLabel, nameLabel],\n  );\n\n  const handleSubmit = useCallback(\n    async (e: JSX.TargetedSubmitEvent<HTMLFormElement>) => {\n      try {\n        e.preventDefault();\n        if (!(e.target instanceof HTMLFormElement)) {\n          return;\n        }\n        const formData = new FormData(e.target);\n        const attachment = await (screenshotInput && showScreenshotInput ? screenshotInput.value() : undefined);\n\n        const data: FeedbackFormData = {\n          name: retrieveStringValue(formData, 'name'),\n          email: retrieveStringValue(formData, 'email'),\n          message: retrieveStringValue(formData, 'message'),\n          attachments: attachment ? [attachment] : undefined,\n        };\n\n        if (!hasAllRequiredFields(data)) {\n          return;\n        }\n\n        try {\n          await onSubmit(\n            {\n              name: data.name,\n              email: data.email,\n              message: data.message,\n              source: FEEDBACK_WIDGET_SOURCE,\n              tags,\n            },\n            { attachments: data.attachments },\n          );\n          onSubmitSuccess(data);\n        } catch (error) {\n          DEBUG_BUILD && logger.error(error);\n          setError(error as string);\n          onSubmitError(error as Error);\n        }\n      } catch {\n        // pass\n      }\n    },\n    [screenshotInput && showScreenshotInput, onSubmitSuccess, onSubmitError],\n  );\n\n  return (\n    <form class=\"form\" onSubmit={handleSubmit}>\n      {ScreenshotInputComponent && showScreenshotInput ? (\n        <ScreenshotInputComponent onError={onScreenshotError} />\n      ) : null}\n\n      <div class=\"form__right\" data-sentry-feedback={true}>\n        <div class=\"form__top\">\n          {error ? <div class=\"form__error-container\">{error}</div> : null}\n\n          {showName ? (\n            <label for=\"name\" class=\"form__label\">\n              <LabelText label={nameLabel} isRequiredLabel={isRequiredLabel} isRequired={isNameRequired} />\n              <input\n                class=\"form__input\"\n                defaultValue={defaultName}\n                id=\"name\"\n                name=\"name\"\n                placeholder={namePlaceholder}\n                required={isNameRequired}\n                type=\"text\"\n              />\n            </label>\n          ) : (\n            <input aria-hidden value={defaultName} name=\"name\" type=\"hidden\" />\n          )}\n\n          {showEmail ? (\n            <label for=\"email\" class=\"form__label\">\n              <LabelText label={emailLabel} isRequiredLabel={isRequiredLabel} isRequired={isEmailRequired} />\n              <input\n                class=\"form__input\"\n                defaultValue={defaultEmail}\n                id=\"email\"\n                name=\"email\"\n                placeholder={emailPlaceholder}\n                required={isEmailRequired}\n                type=\"email\"\n              ></input>\n            </label>\n          ) : (\n            <input aria-hidden value={defaultEmail} name=\"email\" type=\"hidden\" />\n          )}\n\n          <label for=\"message\" class=\"form__label\">\n            <LabelText label={messageLabel} isRequiredLabel={isRequiredLabel} isRequired />\n            <textarea\n              autoFocus\n              class=\"form__input form__input--textarea\"\n              id=\"message\"\n              name=\"message\"\n              placeholder={messagePlaceholder}\n              required={true}\n              rows={5}\n            />\n          </label>\n\n          {ScreenshotInputComponent ? (\n            <label for=\"screenshot\" class=\"form__label\">\n              <button\n                class=\"btn btn--default\"\n                type=\"button\"\n                onClick={() => {\n                  setScreenshotError(null);\n                  setShowScreenshotInput(prev => !prev);\n                }}\n              >\n                {showScreenshotInput ? removeScreenshotButtonLabel : addScreenshotButtonLabel}\n              </button>\n              {screenshotError ? <div class=\"form__error-container\">{screenshotError.message}</div> : null}\n            </label>\n          ) : null}\n        </div>\n        <div class=\"btn-group\">\n          <button class=\"btn btn--primary\" type=\"submit\">\n            {submitButtonLabel}\n          </button>\n          <button class=\"btn btn--default\" type=\"button\" onClick={onFormClose}>\n            {cancelButtonLabel}\n          </button>\n        </div>\n      </div>\n    </form>\n  );\n}\n\nfunction LabelText({\n  label,\n  isRequired,\n  isRequiredLabel,\n}: {\n  label: string;\n  isRequired: boolean;\n  isRequiredLabel: string;\n}): VNode {\n  return (\n    <span class=\"form__label__text\">\n      {label}\n      {isRequired && <span class=\"form__label__text--required\">{isRequiredLabel}</span>}\n    </span>\n  );\n}\n", "import { WINDOW } from '../../constants';\nimport { setAttributesNS } from '../../util/setAttributesNS';\n\nconst WIDTH = 16;\nconst HEIGHT = 17;\nconst XMLNS = 'http://www.w3.org/2000/svg';\n\n/**\n * Success Icon (checkmark)\n */\nexport function SuccessIcon(): SVGElement {\n  const createElementNS = <K extends keyof SVGElementTagNameMap>(tagName: K): SVGElementTagNameMap[K] =>\n    WINDOW.document.createElementNS(XMLNS, tagName);\n  const svg = setAttributesNS(createElementNS('svg'), {\n    width: `${WIDTH}`,\n    height: `${HEIGHT}`,\n    viewBox: `0 0 ${WIDTH} ${HEIGHT}`,\n    fill: 'inherit',\n  });\n\n  const g = setAttributesNS(createElementNS('g'), {\n    clipPath: 'url(#clip0_57_156)',\n  });\n\n  const path2 = setAttributesNS(createElementNS('path'), {\n    ['fill-rule']: 'evenodd',\n    ['clip-rule']: 'evenodd',\n    d: 'M3.55544 15.1518C4.87103 16.0308 6.41775 16.5 8 16.5C10.1217 16.5 12.1566 15.6571 13.6569 14.1569C15.1571 12.6566 16 10.6217 16 8.5C16 6.91775 15.5308 5.37103 14.6518 4.05544C13.7727 2.73985 12.5233 1.71447 11.0615 1.10897C9.59966 0.503466 7.99113 0.34504 6.43928 0.653721C4.88743 0.962403 3.46197 1.72433 2.34315 2.84315C1.22433 3.96197 0.462403 5.38743 0.153721 6.93928C-0.15496 8.49113 0.00346625 10.0997 0.608967 11.5615C1.21447 13.0233 2.23985 14.2727 3.55544 15.1518ZM4.40546 3.1204C5.46945 2.40946 6.72036 2.03 8 2.03C9.71595 2.03 11.3616 2.71166 12.575 3.92502C13.7883 5.13838 14.47 6.78405 14.47 8.5C14.47 9.77965 14.0905 11.0306 13.3796 12.0945C12.6687 13.1585 11.6582 13.9878 10.476 14.4775C9.29373 14.9672 7.99283 15.0953 6.73777 14.8457C5.48271 14.596 4.32987 13.9798 3.42502 13.075C2.52018 12.1701 1.90397 11.0173 1.65432 9.76224C1.40468 8.50718 1.5328 7.20628 2.0225 6.02404C2.5122 4.8418 3.34148 3.83133 4.40546 3.1204Z',\n  });\n  const path = setAttributesNS(createElementNS('path'), {\n    d: 'M6.68775 12.4297C6.78586 12.4745 6.89218 12.4984 7 12.5C7.11275 12.4955 7.22315 12.4664 7.32337 12.4145C7.4236 12.3627 7.51121 12.2894 7.58 12.2L12 5.63999C12.0848 5.47724 12.1071 5.28902 12.0625 5.11098C12.0178 4.93294 11.9095 4.77744 11.7579 4.67392C11.6064 4.57041 11.4221 4.52608 11.24 4.54931C11.0579 4.57254 10.8907 4.66173 10.77 4.79999L6.88 10.57L5.13 8.56999C5.06508 8.49566 4.98613 8.43488 4.89768 8.39111C4.80922 8.34735 4.713 8.32148 4.61453 8.31498C4.51605 8.30847 4.41727 8.32147 4.32382 8.35322C4.23038 8.38497 4.14413 8.43484 4.07 8.49999C3.92511 8.63217 3.83692 8.81523 3.82387 9.01092C3.81083 9.2066 3.87393 9.39976 4 9.54999L6.43 12.24C6.50187 12.3204 6.58964 12.385 6.68775 12.4297Z',\n  });\n\n  svg.appendChild(g).append(path, path2);\n\n  const speakerDefs = createElementNS('defs');\n  const speakerClipPathDef = setAttributesNS(createElementNS('clipPath'), {\n    id: 'clip0_57_156',\n  });\n\n  const speakerRect = setAttributesNS(createElementNS('rect'), {\n    width: `${WIDTH}`,\n    height: `${WIDTH}`,\n    fill: 'white',\n    transform: 'translate(0 0.5)',\n  });\n\n  speakerClipPathDef.appendChild(speakerRect);\n  speakerDefs.appendChild(speakerClipPathDef);\n\n  svg.appendChild(speakerDefs).appendChild(speakerClipPathDef).appendChild(speakerRect);\n\n  return svg;\n}\n", "import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/core';\n// biome-ignore lint/nursery/noUnusedImports: reason\nimport { Fragment, h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars\nimport type { VNode } from 'preact';\nimport { useCallback, useMemo, useState } from 'preact/hooks';\n\nimport { SUCCESS_MESSAGE_TIMEOUT } from '../../constants';\nimport { DialogHeader } from './DialogHeader';\nimport type { Props as HeaderProps } from './DialogHeader';\nimport type { Props as FormProps } from './Form';\nimport { Form } from './Form';\nimport { SuccessIcon } from './SuccessIcon';\n\ninterface Props extends HeaderProps, FormProps {\n  onFormSubmitted: () => void;\n  open: boolean;\n  options: FeedbackInternalOptions;\n}\n\nexport function Dialog({ open, onFormSubmitted, ...props }: Props): VNode {\n  const options = props.options;\n  const successIconHtml = useMemo(() => ({ __html: SuccessIcon().outerHTML }), []);\n\n  const [timeoutId, setTimeoutId] = useState<NodeJS.Timeout | null>(null);\n\n  const handleOnSuccessClick = useCallback(() => {\n    if (timeoutId) {\n      clearTimeout(timeoutId);\n      setTimeoutId(null);\n    }\n    onFormSubmitted();\n  }, [timeoutId]);\n\n  const onSubmitSuccess = useCallback(\n    (data: FeedbackFormData) => {\n      props.onSubmitSuccess(data);\n      setTimeoutId(\n        setTimeout(() => {\n          onFormSubmitted();\n          setTimeoutId(null);\n        }, SUCCESS_MESSAGE_TIMEOUT),\n      );\n    },\n    [onFormSubmitted],\n  );\n\n  return (\n    <Fragment>\n      {timeoutId ? (\n        <div class=\"success__position\" onClick={handleOnSuccessClick}>\n          <div class=\"success__content\">\n            {options.successMessageText}\n            <span class=\"success__icon\" dangerouslySetInnerHTML={successIconHtml} />\n          </div>\n        </div>\n      ) : (\n        <dialog class=\"dialog\" onClick={options.onFormClose} open={open}>\n          <div class=\"dialog__position\">\n            <div\n              class=\"dialog__content\"\n              onClick={e => {\n                // Stop event propagation so clicks on content modal do not propagate to dialog (which will close dialog)\n                e.stopPropagation();\n              }}\n            >\n              <DialogHeader options={options} />\n              <Form {...props} onSubmitSuccess={onSubmitSuccess} />\n            </div>\n          </div>\n        </dialog>\n      )}\n    </Fragment>\n  );\n}\n", "import { DOCUMENT } from '../../constants';\n\nconst DIALOG = `\n.dialog {\n  position: fixed;\n  z-index: var(--z-index);\n  margin: 0;\n  inset: 0;\n\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0;\n  height: 100vh;\n  width: 100vw;\n\n  color: var(--dialog-color, var(--foreground));\n  fill: var(--dialog-color, var(--foreground));\n  line-height: 1.75em;\n\n  background-color: rgba(0, 0, 0, 0.05);\n  border: none;\n  inset: 0;\n  opacity: 1;\n  transition: opacity 0.2s ease-in-out;\n}\n\n.dialog__position {\n  position: fixed;\n  z-index: var(--z-index);\n  inset: var(--dialog-inset);\n  padding: var(--page-margin);\n  display: flex;\n  max-height: calc(100vh - (2 * var(--page-margin)));\n}\n@media (max-width: 600px) {\n  .dialog__position {\n    inset: var(--page-margin);\n    padding: 0;\n  }\n}\n\n.dialog__position:has(.editor) {\n  inset: var(--page-margin);\n  padding: 0;\n}\n\n.dialog:not([open]) {\n  opacity: 0;\n  pointer-events: none;\n  visibility: hidden;\n}\n.dialog:not([open]) .dialog__content {\n  transform: translate(0, -16px) scale(0.98);\n}\n\n.dialog__content {\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  padding: var(--dialog-padding, 24px);\n  max-width: 100%;\n  width: 100%;\n  max-height: 100%;\n  overflow: auto;\n\n  background: var(--dialog-background, var(--background));\n  border-radius: var(--dialog-border-radius, 20px);\n  border: var(--dialog-border, var(--border));\n  box-shadow: var(--dialog-box-shadow, var(--box-shadow));\n  transform: translate(0, 0) scale(1);\n  transition: transform 0.2s ease-in-out;\n}\n\n`;\n\nconst DIALOG_HEADER = `\n.dialog__header {\n  display: flex;\n  gap: 4px;\n  justify-content: space-between;\n  font-weight: var(--dialog-header-weight, 600);\n  margin: 0;\n}\n.dialog__title {\n  align-self: center;\n  width: var(--form-width, 272px);\n}\n\n@media (max-width: 600px) {\n  .dialog__title {\n    width: auto;\n  }\n}\n\n.dialog__position:has(.editor) .dialog__title {\n  width: auto;\n}\n\n\n.brand-link {\n  display: inline-flex;\n}\n.brand-link:focus-visible {\n  outline: var(--outline);\n}\n`;\n\nconst FORM = `\n.form {\n  display: flex;\n  overflow: auto;\n  flex-direction: row;\n  gap: 16px;\n  flex: 1 0;\n}\n\n.form__right {\n  flex: 0 0 auto;\n  display: flex;\n  overflow: auto;\n  flex-direction: column;\n  justify-content: space-between;\n  gap: 20px;\n  width: var(--form-width, 100%);\n}\n\n.dialog__position:has(.editor) .form__right {\n  width: var(--form-width, 272px);\n}\n\n.form__top {\n  display: flex;\n  flex-direction: column;\n  gap: 8px;\n}\n\n.form__error-container {\n  color: var(--error-color);\n  fill: var(--error-color);\n}\n\n.form__label {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n  margin: 0px;\n}\n\n.form__label__text {\n  display: flex;\n  gap: 4px;\n  align-items: center;\n}\n\n.form__label__text--required {\n  font-size: 0.85em;\n}\n\n.form__input {\n  font-family: inherit;\n  line-height: inherit;\n  background: transparent;\n  box-sizing: border-box;\n  border: var(--input-border, var(--border));\n  border-radius: var(--input-border-radius, 6px);\n  color: var(--input-color, inherit);\n  fill: var(--input-color, inherit);\n  font-size: var(--input-font-size, inherit);\n  font-weight: var(--input-font-weight, 500);\n  padding: 6px 12px;\n}\n\n.form__input::placeholder {\n  opacity: 0.65;\n  color: var(--input-placeholder-color, inherit);\n  filter: var(--interactive-filter);\n}\n\n.form__input:focus-visible {\n  outline: var(--input-focus-outline, var(--outline));\n}\n\n.form__input--textarea {\n  font-family: inherit;\n  resize: vertical;\n}\n\n.error {\n  color: var(--error-color);\n  fill: var(--error-color);\n}\n`;\n\nconst BUTTON = `\n.btn-group {\n  display: grid;\n  gap: 8px;\n}\n\n.btn {\n  line-height: inherit;\n  border: var(--button-border, var(--border));\n  border-radius: var(--button-border-radius, 6px);\n  cursor: pointer;\n  font-family: inherit;\n  font-size: var(--button-font-size, inherit);\n  font-weight: var(--button-font-weight, 600);\n  padding: var(--button-padding, 6px 16px);\n}\n.btn[disabled] {\n  opacity: 0.6;\n  pointer-events: none;\n}\n\n.btn--primary {\n  color: var(--button-primary-color, var(--accent-foreground));\n  fill: var(--button-primary-color, var(--accent-foreground));\n  background: var(--button-primary-background, var(--accent-background));\n  border: var(--button-primary-border, var(--border));\n  border-radius: var(--button-primary-border-radius, 6px);\n  font-weight: var(--button-primary-font-weight, 500);\n}\n.btn--primary:hover {\n  color: var(--button-primary-hover-color, var(--accent-foreground));\n  fill: var(--button-primary-hover-color, var(--accent-foreground));\n  background: var(--button-primary-hover-background, var(--accent-background));\n  filter: var(--interactive-filter);\n}\n.btn--primary:focus-visible {\n  background: var(--button-primary-hover-background, var(--accent-background));\n  filter: var(--interactive-filter);\n  outline: var(--button-primary-focus-outline, var(--outline));\n}\n\n.btn--default {\n  color: var(--button-color, var(--foreground));\n  fill: var(--button-color, var(--foreground));\n  background: var(--button-background, var(--background));\n  border: var(--button-border, var(--border));\n  border-radius: var(--button-border-radius, 6px);\n  font-weight: var(--button-font-weight, 500);\n}\n.btn--default:hover {\n  color: var(--button-color, var(--foreground));\n  fill: var(--button-color, var(--foreground));\n  background: var(--button-hover-background, var(--background));\n  filter: var(--interactive-filter);\n}\n.btn--default:focus-visible {\n  background: var(--button-hover-background, var(--background));\n  filter: var(--interactive-filter);\n  outline: var(--button-focus-outline, var(--outline));\n}\n`;\n\nconst SUCCESS = `\n.success__position {\n  position: fixed;\n  inset: var(--dialog-inset);\n  padding: var(--page-margin);\n  z-index: var(--z-index);\n}\n.success__content {\n  background: var(--success-background, var(--background));\n  border: var(--success-border, var(--border));\n  border-radius: var(--success-border-radius, 1.7em/50%);\n  box-shadow: var(--success-box-shadow, var(--box-shadow));\n  font-weight: var(--success-font-weight, 600);\n  color: var(--success-color);\n  fill: var(--success-color);\n  padding: 12px 24px;\n  line-height: 1.75em;\n\n  display: grid;\n  align-items: center;\n  grid-auto-flow: column;\n  gap: 6px;\n  cursor: default;\n}\n\n.success__icon {\n  display: flex;\n}\n`;\n\n/**\n * Creates <style> element for widget dialog\n */\nexport function createDialogStyles(styleNonce?: string): HTMLStyleElement {\n  const style = DOCUMENT.createElement('style');\n\n  style.textContent = `\n:host {\n  --dialog-inset: var(--inset);\n}\n\n${DIALOG}\n${DIALOG_HEADER}\n${FORM}\n${BUTTON}\n${SUCCESS}\n`;\n\n  if (styleNonce) {\n    style.setAttribute('nonce', styleNonce);\n  }\n\n  return style;\n}\n", "import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';\nimport type { FeedbackFormData, FeedbackModalIntegration, IntegrationFn, User } from '@sentry/core';\nimport { h, render } from 'preact';\nimport * as hooks from 'preact/hooks';\nimport { DOCUMENT } from '../constants';\nimport { Dialog } from './components/Dialog';\nimport { createDialogStyles } from './components/Dialog.css';\n\nfunction getUser(): User | undefined {\n  const currentUser = getCurrentScope().getUser();\n  const isolationUser = getIsolationScope().getUser();\n  const globalUser = getGlobalScope().getUser();\n  if (currentUser && Object.keys(currentUser).length) {\n    return currentUser;\n  }\n  if (isolationUser && Object.keys(isolationUser).length) {\n    return isolationUser;\n  }\n  return globalUser;\n}\n\nexport const feedbackModalIntegration = ((): FeedbackModalIntegration => {\n  return {\n    name: 'FeedbackModal',\n    // eslint-disable-next-line @typescript-eslint/no-empty-function\n    setupOnce() {},\n    createDialog: ({ options, screenshotIntegration, sendFeedback, shadow }) => {\n      const shadowRoot = shadow as unknown as ShadowRoot;\n      const userKey = options.useSentryUser;\n      const user = getUser();\n\n      const el = DOCUMENT.createElement('div');\n      const style = createDialogStyles(options.styleNonce);\n\n      let originalOverflow = '';\n      const dialog: ReturnType<FeedbackModalIntegration['createDialog']> = {\n        get el() {\n          return el;\n        },\n        appendToDom(): void {\n          if (!shadowRoot.contains(style) && !shadowRoot.contains(el)) {\n            shadowRoot.appendChild(style);\n            shadowRoot.appendChild(el);\n          }\n        },\n        removeFromDom(): void {\n          shadowRoot.removeChild(el);\n          shadowRoot.removeChild(style);\n          DOCUMENT.body.style.overflow = originalOverflow;\n        },\n        open() {\n          renderContent(true);\n          options.onFormOpen && options.onFormOpen();\n          originalOverflow = DOCUMENT.body.style.overflow;\n          DOCUMENT.body.style.overflow = 'hidden';\n        },\n        close() {\n          renderContent(false);\n          DOCUMENT.body.style.overflow = originalOverflow;\n        },\n      };\n\n      const screenshotInput = screenshotIntegration && screenshotIntegration.createInput({ h, hooks, dialog, options });\n\n      const renderContent = (open: boolean): void => {\n        render(\n          <Dialog\n            options={options}\n            screenshotInput={screenshotInput}\n            showName={options.showName || options.isNameRequired}\n            showEmail={options.showEmail || options.isEmailRequired}\n            defaultName={(userKey && user && user[userKey.name]) || ''}\n            defaultEmail={(userKey && user && user[userKey.email]) || ''}\n            onFormClose={() => {\n              renderContent(false);\n              options.onFormClose && options.onFormClose();\n            }}\n            onSubmit={sendFeedback}\n            onSubmitSuccess={(data: FeedbackFormData) => {\n              renderContent(false);\n              options.onSubmitSuccess && options.onSubmitSuccess(data);\n            }}\n            onSubmitError={(error: Error) => {\n              options.onSubmitError && options.onSubmitError(error);\n            }}\n            onFormSubmitted={() => {\n              options.onFormSubmitted && options.onFormSubmitted();\n            }}\n            open={open}\n          />,\n          el,\n        );\n      };\n\n      return dialog;\n    },\n  };\n}) satisfies IntegrationFn;\n", "import type { VNode, h as hType } from 'preact';\n\ninterface FactoryParams {\n  h: typeof hType;\n}\n\nexport default function CropCornerFactory({\n  h, // eslint-disable-line @typescript-eslint/no-unused-vars\n}: FactoryParams) {\n  return function CropCorner({\n    top,\n    left,\n    corner,\n    onGrabButton,\n  }: {\n    top: number;\n    left: number;\n    corner: string;\n    onGrabButton: (e: Event, corner: string) => void;\n  }): VNode {\n    return (\n      <button\n        class={`editor__crop-corner editor__crop-corner--${corner} `}\n        style={{\n          top: top,\n          left: left,\n        }}\n        onMouseDown={e => {\n          e.preventDefault();\n          onGrabButton(e, corner);\n        }}\n        onClick={e => {\n          e.preventDefault();\n        }}\n      ></button>\n    );\n  };\n}\n", "import { DOCUMENT } from '../../constants';\n\n/**\n * Creates <style> element for widget dialog\n */\nexport function createScreenshotInputStyles(styleNonce?: string): HTMLStyleElement {\n  const style = DOCUMENT.createElement('style');\n\n  const surface200 = '#1A141F';\n  const gray100 = '#302735';\n\n  style.textContent = `\n.editor {\n  padding: 10px;\n  padding-top: 65px;\n  padding-bottom: 65px;\n  flex-grow: 1;\n\n  background-color: ${surface200};\n  background-image: repeating-linear-gradient(\n      -145deg,\n      transparent,\n      transparent 8px,\n      ${surface200} 8px,\n      ${surface200} 11px\n    ),\n    repeating-linear-gradient(\n      -45deg,\n      transparent,\n      transparent 15px,\n      ${gray100} 15px,\n      ${gray100} 16px\n    );\n}\n\n.editor__canvas-container {\n  width: 100%;\n  height: 100%;\n  position: relative;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n.editor__canvas-container canvas {\n  object-fit: contain;\n  position: relative;\n}\n\n.editor__crop-btn-group {\n  padding: 8px;\n  gap: 8px;\n  border-radius: var(--menu-border-radius, 6px);\n  background: var(--button-primary-background, var(--background));\n  width: 175px;\n  position: absolute;\n}\n\n.editor__crop-corner {\n  width: 30px;\n  height: 30px;\n  position: absolute;\n  background: none;\n  border: 3px solid #ffffff;\n}\n\n.editor__crop-corner--top-left {\n  cursor: nwse-resize;\n  border-right: none;\n  border-bottom: none;\n}\n.editor__crop-corner--top-right {\n  cursor: nesw-resize;\n  border-left: none;\n  border-bottom: none;\n}\n.editor__crop-corner--bottom-left {\n  cursor: nesw-resize;\n  border-right: none;\n  border-top: none;\n}\n.editor__crop-corner--bottom-right {\n  cursor: nwse-resize;\n  border-left: none;\n  border-top: none;\n}\n`;\n\n  if (styleNonce) {\n    style.setAttribute('nonce', styleNonce);\n  }\n\n  return style;\n}\n", "import type * as Hooks from 'preact/hooks';\nimport { DOCUMENT, NAVIGATOR, WINDOW } from '../../constants';\n\ninterface FactoryParams {\n  hooks: typeof Hooks;\n}\n\ninterface Props {\n  onBeforeScreenshot: () => void;\n  onScreenshot: (imageSource: HTMLVideoElement) => void;\n  onAfterScreenshot: () => void;\n  onError: (error: Error) => void;\n}\n\ntype UseTakeScreenshot = ({ onBeforeScreenshot, onScreenshot, onAfterScreenshot, onError }: Props) => void;\n\nexport function useTakeScreenshotFactory({ hooks }: FactoryParams): UseTakeScreenshot {\n  return function useTakeScreenshot({ onBeforeScreenshot, onScreenshot, onAfterScreenshot, onError }: Props) {\n    hooks.useEffect(() => {\n      const takeScreenshot = async (): Promise<void> => {\n        onBeforeScreenshot();\n        const stream = await NAVIGATOR.mediaDevices.getDisplayMedia({\n          video: {\n            width: WINDOW.innerWidth * WINDOW.devicePixelRatio,\n            height: WINDOW.innerHeight * WINDOW.devicePixelRatio,\n          },\n          audio: false,\n          // @ts-expect-error experimental flags: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#prefercurrenttab\n          monitorTypeSurfaces: 'exclude',\n          preferCurrentTab: true,\n          selfBrowserSurface: 'include',\n          surfaceSwitching: 'exclude',\n        });\n\n        const video = DOCUMENT.createElement('video');\n        await new Promise<void>((resolve, reject) => {\n          video.srcObject = stream;\n          video.onloadedmetadata = () => {\n            onScreenshot(video);\n            stream.getTracks().forEach(track => track.stop());\n            resolve();\n          };\n          video.play().catch(reject);\n        });\n        onAfterScreenshot();\n      };\n\n      takeScreenshot().catch(onError);\n    }, []);\n  };\n}\n", "/* eslint-disable max-lines */\nimport type { FeedbackInternalOptions, FeedbackModalIntegration } from '@sentry/core';\nimport type { ComponentType, VNode, h as hType } from 'preact';\n// biome-ignore lint/nursery/noUnusedImports: reason\nimport { h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars\nimport type * as Hooks from 'preact/hooks';\nimport { DOCUMENT, WINDOW } from '../../constants';\nimport CropCornerFactory from './CropCorner';\nimport { createScreenshotInputStyles } from './ScreenshotInput.css';\nimport { useTakeScreenshotFactory } from './useTakeScreenshot';\n\nconst CROP_BUTTON_SIZE = 30;\nconst CROP_BUTTON_BORDER = 3;\nconst CROP_BUTTON_OFFSET = CROP_BUTTON_SIZE + CROP_BUTTON_BORDER;\nconst DPI = WINDOW.devicePixelRatio;\n\ninterface FactoryParams {\n  h: typeof hType;\n  hooks: typeof Hooks;\n  imageBuffer: HTMLCanvasElement;\n  dialog: ReturnType<FeedbackModalIntegration['createDialog']>;\n  options: FeedbackInternalOptions;\n}\n\ninterface Props {\n  onError: (error: Error) => void;\n}\n\ninterface Box {\n  startX: number;\n  startY: number;\n  endX: number;\n  endY: number;\n}\n\ninterface Rect {\n  x: number;\n  y: number;\n  height: number;\n  width: number;\n}\n\nconst constructRect = (box: Box): Rect => {\n  return {\n    x: Math.min(box.startX, box.endX),\n    y: Math.min(box.startY, box.endY),\n    width: Math.abs(box.startX - box.endX),\n    height: Math.abs(box.startY - box.endY),\n  };\n};\n\nconst getContainedSize = (img: HTMLCanvasElement): Box => {\n  const imgClientHeight = img.clientHeight;\n  const imgClientWidth = img.clientWidth;\n  const ratio = img.width / img.height;\n  let width = imgClientHeight * ratio;\n  let height = imgClientHeight;\n  if (width > imgClientWidth) {\n    width = imgClientWidth;\n    height = imgClientWidth / ratio;\n  }\n  const x = (imgClientWidth - width) / 2;\n  const y = (imgClientHeight - height) / 2;\n  return { startX: x, startY: y, endX: width + x, endY: height + y };\n};\n\nexport function ScreenshotEditorFactory({\n  h,\n  hooks,\n  imageBuffer,\n  dialog,\n  options,\n}: FactoryParams): ComponentType<Props> {\n  const useTakeScreenshot = useTakeScreenshotFactory({ hooks });\n\n  return function ScreenshotEditor({ onError }: Props): VNode {\n    const styles = hooks.useMemo(() => ({ __html: createScreenshotInputStyles(options.styleNonce).innerText }), []);\n    const CropCorner = CropCornerFactory({ h });\n\n    const canvasContainerRef = hooks.useRef<HTMLDivElement>(null);\n    const cropContainerRef = hooks.useRef<HTMLDivElement>(null);\n    const croppingRef = hooks.useRef<HTMLCanvasElement>(null);\n    const [croppingRect, setCroppingRect] = hooks.useState<Box>({ startX: 0, startY: 0, endX: 0, endY: 0 });\n    const [confirmCrop, setConfirmCrop] = hooks.useState(false);\n    const [isResizing, setIsResizing] = hooks.useState(false);\n\n    hooks.useEffect(() => {\n      WINDOW.addEventListener('resize', resizeCropper, false);\n    }, []);\n\n    function resizeCropper(): void {\n      const cropper = croppingRef.current;\n      const imageDimensions = constructRect(getContainedSize(imageBuffer));\n      if (cropper) {\n        cropper.width = imageDimensions.width * DPI;\n        cropper.height = imageDimensions.height * DPI;\n        cropper.style.width = `${imageDimensions.width}px`;\n        cropper.style.height = `${imageDimensions.height}px`;\n        const ctx = cropper.getContext('2d');\n        if (ctx) {\n          ctx.scale(DPI, DPI);\n        }\n      }\n\n      const cropButton = cropContainerRef.current;\n      if (cropButton) {\n        cropButton.style.width = `${imageDimensions.width}px`;\n        cropButton.style.height = `${imageDimensions.height}px`;\n      }\n\n      setCroppingRect({ startX: 0, startY: 0, endX: imageDimensions.width, endY: imageDimensions.height });\n    }\n\n    hooks.useEffect(() => {\n      const cropper = croppingRef.current;\n      if (!cropper) {\n        return;\n      }\n\n      const ctx = cropper.getContext('2d');\n      if (!ctx) {\n        return;\n      }\n\n      const imageDimensions = constructRect(getContainedSize(imageBuffer));\n      const croppingBox = constructRect(croppingRect);\n      ctx.clearRect(0, 0, imageDimensions.width, imageDimensions.height);\n\n      // draw gray overlay around the selection\n      ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';\n      ctx.fillRect(0, 0, imageDimensions.width, imageDimensions.height);\n      ctx.clearRect(croppingBox.x, croppingBox.y, croppingBox.width, croppingBox.height);\n\n      // draw selection border\n      ctx.strokeStyle = '#ffffff';\n      ctx.lineWidth = 3;\n      ctx.strokeRect(croppingBox.x + 1, croppingBox.y + 1, croppingBox.width - 2, croppingBox.height - 2);\n      ctx.strokeStyle = '#000000';\n      ctx.lineWidth = 1;\n      ctx.strokeRect(croppingBox.x + 3, croppingBox.y + 3, croppingBox.width - 6, croppingBox.height - 6);\n    }, [croppingRect]);\n\n    function onGrabButton(e: Event, corner: string): void {\n      setConfirmCrop(false);\n      setIsResizing(true);\n      const handleMouseMove = makeHandleMouseMove(corner);\n      const handleMouseUp = (): void => {\n        DOCUMENT.removeEventListener('mousemove', handleMouseMove);\n        DOCUMENT.removeEventListener('mouseup', handleMouseUp);\n        setConfirmCrop(true);\n        setIsResizing(false);\n      };\n\n      DOCUMENT.addEventListener('mouseup', handleMouseUp);\n      DOCUMENT.addEventListener('mousemove', handleMouseMove);\n    }\n\n    const makeHandleMouseMove = hooks.useCallback((corner: string) => {\n      return function (e: MouseEvent) {\n        if (!croppingRef.current) {\n          return;\n        }\n        const cropCanvas = croppingRef.current;\n        const cropBoundingRect = cropCanvas.getBoundingClientRect();\n        const mouseX = e.clientX - cropBoundingRect.x;\n        const mouseY = e.clientY - cropBoundingRect.y;\n        switch (corner) {\n          case 'top-left':\n            setCroppingRect(prev => ({\n              ...prev,\n              startX: Math.min(Math.max(0, mouseX), prev.endX - CROP_BUTTON_OFFSET),\n              startY: Math.min(Math.max(0, mouseY), prev.endY - CROP_BUTTON_OFFSET),\n            }));\n            break;\n          case 'top-right':\n            setCroppingRect(prev => ({\n              ...prev,\n              endX: Math.max(Math.min(mouseX, cropCanvas.width / DPI), prev.startX + CROP_BUTTON_OFFSET),\n              startY: Math.min(Math.max(0, mouseY), prev.endY - CROP_BUTTON_OFFSET),\n            }));\n            break;\n          case 'bottom-left':\n            setCroppingRect(prev => ({\n              ...prev,\n              startX: Math.min(Math.max(0, mouseX), prev.endX - CROP_BUTTON_OFFSET),\n              endY: Math.max(Math.min(mouseY, cropCanvas.height / DPI), prev.startY + CROP_BUTTON_OFFSET),\n            }));\n            break;\n          case 'bottom-right':\n            setCroppingRect(prev => ({\n              ...prev,\n              endX: Math.max(Math.min(mouseX, cropCanvas.width / DPI), prev.startX + CROP_BUTTON_OFFSET),\n              endY: Math.max(Math.min(mouseY, cropCanvas.height / DPI), prev.startY + CROP_BUTTON_OFFSET),\n            }));\n            break;\n        }\n      };\n    }, []);\n\n    // DRAGGING FUNCTIONALITY.\n    const initialPositionRef = hooks.useRef({ initialX: 0, initialY: 0 });\n\n    function onDragStart(e: MouseEvent): void {\n      if (isResizing) return;\n\n      initialPositionRef.current = { initialX: e.clientX, initialY: e.clientY };\n\n      const handleMouseMove = (moveEvent: MouseEvent): void => {\n        const cropCanvas = croppingRef.current;\n        if (!cropCanvas) return;\n\n        const deltaX = moveEvent.clientX - initialPositionRef.current.initialX;\n        const deltaY = moveEvent.clientY - initialPositionRef.current.initialY;\n\n        setCroppingRect(prev => {\n          // Math.max stops it from going outside of the borders\n          const newStartX = Math.max(\n            0,\n            Math.min(prev.startX + deltaX, cropCanvas.width / DPI - (prev.endX - prev.startX)),\n          );\n          const newStartY = Math.max(\n            0,\n            Math.min(prev.startY + deltaY, cropCanvas.height / DPI - (prev.endY - prev.startY)),\n          );\n          // Don't want to change size, just position\n          const newEndX = newStartX + (prev.endX - prev.startX);\n          const newEndY = newStartY + (prev.endY - prev.startY);\n\n          initialPositionRef.current.initialX = moveEvent.clientX;\n          initialPositionRef.current.initialY = moveEvent.clientY;\n\n          return {\n            startX: newStartX,\n            startY: newStartY,\n            endX: newEndX,\n            endY: newEndY,\n          };\n        });\n      };\n\n      const handleMouseUp = (): void => {\n        DOCUMENT.removeEventListener('mousemove', handleMouseMove);\n        DOCUMENT.removeEventListener('mouseup', handleMouseUp);\n      };\n\n      DOCUMENT.addEventListener('mousemove', handleMouseMove);\n      DOCUMENT.addEventListener('mouseup', handleMouseUp);\n    }\n\n    function submit(): void {\n      const cutoutCanvas = DOCUMENT.createElement('canvas');\n      const imageBox = constructRect(getContainedSize(imageBuffer));\n      const croppingBox = constructRect(croppingRect);\n      cutoutCanvas.width = croppingBox.width * DPI;\n      cutoutCanvas.height = croppingBox.height * DPI;\n\n      const cutoutCtx = cutoutCanvas.getContext('2d');\n      if (cutoutCtx && imageBuffer) {\n        cutoutCtx.drawImage(\n          imageBuffer,\n          (croppingBox.x / imageBox.width) * imageBuffer.width,\n          (croppingBox.y / imageBox.height) * imageBuffer.height,\n          (croppingBox.width / imageBox.width) * imageBuffer.width,\n          (croppingBox.height / imageBox.height) * imageBuffer.height,\n          0,\n          0,\n          cutoutCanvas.width,\n          cutoutCanvas.height,\n        );\n      }\n\n      const ctx = imageBuffer.getContext('2d');\n      if (ctx) {\n        ctx.clearRect(0, 0, imageBuffer.width, imageBuffer.height);\n        imageBuffer.width = cutoutCanvas.width;\n        imageBuffer.height = cutoutCanvas.height;\n        imageBuffer.style.width = `${croppingBox.width}px`;\n        imageBuffer.style.height = `${croppingBox.height}px`;\n        ctx.drawImage(cutoutCanvas, 0, 0);\n        resizeCropper();\n      }\n    }\n\n    useTakeScreenshot({\n      onBeforeScreenshot: hooks.useCallback(() => {\n        (dialog.el as HTMLElement).style.display = 'none';\n      }, []),\n      onScreenshot: hooks.useCallback(\n        (imageSource: HTMLVideoElement) => {\n          const context = imageBuffer.getContext('2d');\n          if (!context) {\n            throw new Error('Could not get canvas context');\n          }\n          imageBuffer.width = imageSource.videoWidth;\n          imageBuffer.height = imageSource.videoHeight;\n          imageBuffer.style.width = '100%';\n          imageBuffer.style.height = '100%';\n          context.drawImage(imageSource, 0, 0);\n        },\n        [imageBuffer],\n      ),\n      onAfterScreenshot: hooks.useCallback(() => {\n        (dialog.el as HTMLElement).style.display = 'block';\n        const container = canvasContainerRef.current;\n        container && container.appendChild(imageBuffer);\n        resizeCropper();\n      }, []),\n      onError: hooks.useCallback(error => {\n        (dialog.el as HTMLElement).style.display = 'block';\n        onError(error);\n      }, []),\n    });\n\n    return (\n      <div class=\"editor\">\n        <style nonce={options.styleNonce} dangerouslySetInnerHTML={styles} />\n        <div class=\"editor__canvas-container\" ref={canvasContainerRef}>\n          <div class=\"editor__crop-container\" style={{ position: 'absolute', zIndex: 1 }} ref={cropContainerRef}>\n            <canvas\n              onMouseDown={onDragStart}\n              style={{ position: 'absolute', cursor: confirmCrop ? 'move' : 'auto' }}\n              ref={croppingRef}\n            ></canvas>\n            <CropCorner\n              left={croppingRect.startX - CROP_BUTTON_BORDER}\n              top={croppingRect.startY - CROP_BUTTON_BORDER}\n              onGrabButton={onGrabButton}\n              corner=\"top-left\"\n            ></CropCorner>\n            <CropCorner\n              left={croppingRect.endX - CROP_BUTTON_SIZE + CROP_BUTTON_BORDER}\n              top={croppingRect.startY - CROP_BUTTON_BORDER}\n              onGrabButton={onGrabButton}\n              corner=\"top-right\"\n            ></CropCorner>\n            <CropCorner\n              left={croppingRect.startX - CROP_BUTTON_BORDER}\n              top={croppingRect.endY - CROP_BUTTON_SIZE + CROP_BUTTON_BORDER}\n              onGrabButton={onGrabButton}\n              corner=\"bottom-left\"\n            ></CropCorner>\n            <CropCorner\n              left={croppingRect.endX - CROP_BUTTON_SIZE + CROP_BUTTON_BORDER}\n              top={croppingRect.endY - CROP_BUTTON_SIZE + CROP_BUTTON_BORDER}\n              onGrabButton={onGrabButton}\n              corner=\"bottom-right\"\n            ></CropCorner>\n            <div\n              style={{\n                left: Math.max(0, croppingRect.endX - 191),\n                top: Math.max(0, croppingRect.endY + 8),\n                display: confirmCrop ? 'flex' : 'none',\n              }}\n              class=\"editor__crop-btn-group\"\n            >\n              <button\n                onClick={e => {\n                  e.preventDefault();\n                  if (croppingRef.current) {\n                    setCroppingRect({\n                      startX: 0,\n                      startY: 0,\n                      endX: croppingRef.current.width / DPI,\n                      endY: croppingRef.current.height / DPI,\n                    });\n                  }\n                  setConfirmCrop(false);\n                }}\n                class=\"btn btn--default\"\n              >\n                {options.cancelButtonLabel}\n              </button>\n              <button\n                onClick={e => {\n                  e.preventDefault();\n                  submit();\n                  setConfirmCrop(false);\n                }}\n                class=\"btn btn--primary\"\n              >\n                {options.confirmButtonLabel}\n              </button>\n            </div>\n          </div>\n        </div>\n      </div>\n    );\n  };\n}\n", "import type { FeedbackScreenshotIntegration, IntegrationFn } from '@sentry/core';\nimport type { Attachment } from '@sentry/core';\nimport type { h as hType } from 'preact';\nimport type * as Hooks from 'preact/hooks';\nimport { DOCUMENT } from '../constants';\nimport { ScreenshotEditorFactory } from './components/ScreenshotEditor';\n\nexport const feedbackScreenshotIntegration = ((): FeedbackScreenshotIntegration => {\n  return {\n    name: 'FeedbackScreenshot',\n    // eslint-disable-next-line @typescript-eslint/no-empty-function\n    setupOnce() {},\n    createInput: ({ h, hooks, dialog, options }) => {\n      const imageBuffer = DOCUMENT.createElement('canvas');\n\n      return {\n        input: ScreenshotEditorFactory({\n          h: h as typeof hType,\n          hooks: hooks as typeof Hooks,\n          imageBuffer,\n          dialog,\n          options,\n        }) as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n\n        value: async () => {\n          const blob = await new Promise<Parameters<BlobCallback>[0]>(resolve => {\n            imageBuffer.toBlob(resolve, 'image/png');\n          });\n          if (blob) {\n            const data = new Uint8Array(await blob.arrayBuffer());\n            const attachment: Attachment = {\n              data,\n              filename: 'screenshot.png',\n              contentType: 'application/png',\n              // attachmentType?: string;\n            };\n            return attachment;\n          }\n          return undefined;\n        },\n      };\n    },\n  };\n}) satisfies IntegrationFn;\n", "import { buildFeedbackIntegration } from '@sentry-internal/feedback';\nimport { lazyLoadIntegration } from './utils/lazyLoadIntegration';\n\n/**\n * An integration to add user feedback to your application,\n * while loading most of the code lazily only when it's needed.\n */\nexport const feedbackAsyncIntegration = buildFeedbackIntegration({\n  lazyLoadIntegration,\n});\n", "import {\n  buildFeedbackIntegration,\n  feedbackModalIntegration,\n  feedbackScreenshotIntegration,\n} from '@sentry-internal/feedback';\n\n/** Add a widget to capture user feedback to your application. */\nexport const feedbackSyncIntegration = buildFeedbackIntegration({\n  getModalIntegration: () => feedbackModalIntegration,\n  getScreenshotIntegration: () => feedbackScreenshotIntegration,\n});\n", "import { BrowserMetricsAggregator, metrics as metricsCore } from '@sentry/core';\nimport type { DurationUnit, MetricData, Metrics } from '@sentry/core';\n\n/**\n * Adds a value to a counter metric\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction increment(name: string, value: number = 1, data?: MetricData): void {\n  // eslint-disable-next-line deprecation/deprecation\n  metricsCore.increment(BrowserMetricsAggregator, name, value, data);\n}\n\n/**\n * Adds a value to a distribution metric\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction distribution(name: string, value: number, data?: MetricData): void {\n  // eslint-disable-next-line deprecation/deprecation\n  metricsCore.distribution(BrowserMetricsAggregator, name, value, data);\n}\n\n/**\n * Adds a value to a set metric. Value must be a string or integer.\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction set(name: string, value: number | string, data?: MetricData): void {\n  // eslint-disable-next-line deprecation/deprecation\n  metricsCore.set(BrowserMetricsAggregator, name, value, data);\n}\n\n/**\n * Adds a value to a gauge metric\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction gauge(name: string, value: number, data?: MetricData): void {\n  // eslint-disable-next-line deprecation/deprecation\n  metricsCore.gauge(BrowserMetricsAggregator, name, value, data);\n}\n\n/**\n * Adds a timing metric.\n * The metric is added as a distribution metric.\n *\n * You can either directly capture a numeric `value`, or wrap a callback function in `timing`.\n * In the latter case, the duration of the callback execution will be captured as a span & a metric.\n *\n * @deprecated The Sentry metrics beta has ended. This method will be removed in a future release.\n */\nfunction timing(name: string, value: number, unit?: DurationUnit, data?: Omit<MetricData, 'unit'>): void;\nfunction timing<T>(name: string, callback: () => T, unit?: DurationUnit, data?: Omit<MetricData, 'unit'>): T;\nfunction timing<T = void>(\n  name: string,\n  value: number | (() => T),\n  unit: DurationUnit = 'second',\n  data?: Omit<MetricData, 'unit'>,\n): T | void {\n  // eslint-disable-next-line deprecation/deprecation\n  return metricsCore.timing(BrowserMetricsAggregator, name, value, unit, data);\n}\n\n/**\n * The metrics API is used to capture custom metrics in Sentry.\n *\n * @deprecated The Sentry metrics beta has ended. This export will be removed in a future release.\n */\nexport const metrics: Metrics = {\n  increment,\n  distribution,\n  set,\n  gauge,\n  timing,\n};\n", "import {\n  SENTRY_XHR_DATA_KEY,\n  addPerformanceInstrumentationHandler,\n  addXhrInstrumentationHandler,\n  extractNetworkProtocol,\n} from '@sentry-internal/browser-utils';\nimport type { Client, HandlerDataXhr, SentryWrappedXMLHttpRequest, Span } from '@sentry/core';\nimport {\n  SEMANTIC_ATTRIBUTE_SENTRY_OP,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  SentryNonRecordingSpan,\n  addFetchEndInstrumentationHandler,\n  addFetchInstrumentationHandler,\n  browserPerformanceTimeOrigin,\n  getActiveSpan,\n  getTraceData,\n  hasTracingEnabled,\n  instrumentFetchRequest,\n  parseUrl,\n  setHttpStatus,\n  spanToJSON,\n  startInactiveSpan,\n  stringMatchesSomePattern,\n} from '@sentry/core';\nimport { WINDOW } from '../helpers';\n\n/** Options for Request Instrumentation */\nexport interface RequestInstrumentationOptions {\n  /**\n   * List of strings and/or Regular Expressions used to determine which outgoing requests will have `sentry-trace` and `baggage`\n   * headers attached.\n   *\n   * **Default:** If this option is not provided, tracing headers will be attached to all outgoing requests.\n   * If you are using a browser SDK, by default, tracing headers will only be attached to outgoing requests to the same origin.\n   *\n   * **Disclaimer:** Carelessly setting this option in browser environments may result into CORS errors!\n   * Only attach tracing headers to requests to the same origin, or to requests to services you can control CORS headers of.\n   * Cross-origin requests, meaning requests to a different domain, for example a request to `https://api.example.com/` while you're on `https://example.com/`, take special care.\n   * If you are attaching headers to cross-origin requests, make sure the backend handling the request returns a `\"Access-Control-Allow-Headers: sentry-trace, baggage\"` header to ensure your requests aren't blocked.\n   *\n   * If you provide a `tracePropagationTargets` array, the entries you provide will be matched against the entire URL of the outgoing request.\n   * If you are using a browser SDK, the entries will also be matched against the pathname of the outgoing requests.\n   * This is so you can have matchers for relative requests, for example, `/^\\/api/` if you want to trace requests to your `/api` routes on the same domain.\n   *\n   * If any of the two match any of the provided values, tracing headers will be attached to the outgoing request.\n   * Both, the string values, and the RegExes you provide in the array will match if they partially match the URL or pathname.\n   *\n   * Examples:\n   * - `tracePropagationTargets: [/^\\/api/]` and request to `https://same-origin.com/api/posts`:\n   *   - Tracing headers will be attached because the request is sent to the same origin and the regex matches the pathname \"/api/posts\".\n   * - `tracePropagationTargets: [/^\\/api/]` and request to `https://different-origin.com/api/posts`:\n   *   - Tracing headers will not be attached because the pathname will only be compared when the request target lives on the same origin.\n   * - `tracePropagationTargets: [/^\\/api/, 'https://external-api.com']` and request to `https://external-api.com/v1/data`:\n   *   - Tracing headers will be attached because the request URL matches the string `'https://external-api.com'`.\n   */\n  tracePropagationTargets?: Array<string | RegExp>;\n\n  /**\n   * Flag to disable patching all together for fetch requests.\n   *\n   * Default: true\n   */\n  traceFetch: boolean;\n\n  /**\n   * Flag to disable patching all together for xhr requests.\n   *\n   * Default: true\n   */\n  traceXHR: boolean;\n\n  /**\n   * Flag to disable tracking of long-lived streams, like server-sent events (SSE) via fetch.\n   * Do not enable this in case you have live streams or very long running streams.\n   *\n   * Disabled by default since it can lead to issues with streams using the `cancel()` api\n   * (https://github.com/getsentry/sentry-javascript/issues/13950)\n   *\n   * Default: false\n   */\n  trackFetchStreamPerformance: boolean;\n\n  /**\n   * If true, Sentry will capture http timings and add them to the corresponding http spans.\n   *\n   * Default: true\n   */\n  enableHTTPTimings: boolean;\n\n  /**\n   * This function will be called before creating a span for a request with the given url.\n   * Return false if you don't want a span for the given url.\n   *\n   * Default: (url: string) => true\n   */\n  shouldCreateSpanForRequest?(this: void, url: string): boolean;\n}\n\nconst responseToSpanId = new WeakMap<object, string>();\nconst spanIdToEndTimestamp = new Map<string, number>();\n\nexport const defaultRequestInstrumentationOptions: RequestInstrumentationOptions = {\n  traceFetch: true,\n  traceXHR: true,\n  enableHTTPTimings: true,\n  trackFetchStreamPerformance: false,\n};\n\n/** Registers span creators for xhr and fetch requests  */\nexport function instrumentOutgoingRequests(client: Client, _options?: Partial<RequestInstrumentationOptions>): void {\n  const {\n    traceFetch,\n    traceXHR,\n    trackFetchStreamPerformance,\n    shouldCreateSpanForRequest,\n    enableHTTPTimings,\n    tracePropagationTargets,\n  } = {\n    traceFetch: defaultRequestInstrumentationOptions.traceFetch,\n    traceXHR: defaultRequestInstrumentationOptions.traceXHR,\n    trackFetchStreamPerformance: defaultRequestInstrumentationOptions.trackFetchStreamPerformance,\n    ..._options,\n  };\n\n  const shouldCreateSpan =\n    typeof shouldCreateSpanForRequest === 'function' ? shouldCreateSpanForRequest : (_: string) => true;\n\n  const shouldAttachHeadersWithTargets = (url: string): boolean => shouldAttachHeaders(url, tracePropagationTargets);\n\n  const spans: Record<string, Span> = {};\n\n  if (traceFetch) {\n    // Keeping track of http requests, whose body payloads resolved later than the initial resolved request\n    // e.g. streaming using server sent events (SSE)\n    client.addEventProcessor(event => {\n      if (event.type === 'transaction' && event.spans) {\n        event.spans.forEach(span => {\n          if (span.op === 'http.client') {\n            const updatedTimestamp = spanIdToEndTimestamp.get(span.span_id);\n            if (updatedTimestamp) {\n              span.timestamp = updatedTimestamp / 1000;\n              spanIdToEndTimestamp.delete(span.span_id);\n            }\n          }\n        });\n      }\n      return event;\n    });\n\n    if (trackFetchStreamPerformance) {\n      addFetchEndInstrumentationHandler(handlerData => {\n        if (handlerData.response) {\n          const span = responseToSpanId.get(handlerData.response);\n          if (span && handlerData.endTimestamp) {\n            spanIdToEndTimestamp.set(span, handlerData.endTimestamp);\n          }\n        }\n      });\n    }\n\n    addFetchInstrumentationHandler(handlerData => {\n      const createdSpan = instrumentFetchRequest(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans);\n\n      if (handlerData.response && handlerData.fetchData.__span) {\n        responseToSpanId.set(handlerData.response, handlerData.fetchData.__span);\n      }\n\n      // We cannot use `window.location` in the generic fetch instrumentation,\n      // but we need it for reliable `server.address` attribute.\n      // so we extend this in here\n      if (createdSpan) {\n        const fullUrl = getFullURL(handlerData.fetchData.url);\n        const host = fullUrl ? parseUrl(fullUrl).host : undefined;\n        createdSpan.setAttributes({\n          'http.url': fullUrl,\n          'server.address': host,\n        });\n      }\n\n      if (enableHTTPTimings && createdSpan) {\n        addHTTPTimings(createdSpan);\n      }\n    });\n  }\n\n  if (traceXHR) {\n    addXhrInstrumentationHandler(handlerData => {\n      const createdSpan = xhrCallback(handlerData, shouldCreateSpan, shouldAttachHeadersWithTargets, spans);\n      if (enableHTTPTimings && createdSpan) {\n        addHTTPTimings(createdSpan);\n      }\n    });\n  }\n}\n\nfunction isPerformanceResourceTiming(entry: PerformanceEntry): entry is PerformanceResourceTiming {\n  return (\n    entry.entryType === 'resource' &&\n    'initiatorType' in entry &&\n    typeof (entry as PerformanceResourceTiming).nextHopProtocol === 'string' &&\n    (entry.initiatorType === 'fetch' || entry.initiatorType === 'xmlhttprequest')\n  );\n}\n\n/**\n * Creates a temporary observer to listen to the next fetch/xhr resourcing timings,\n * so that when timings hit their per-browser limit they don't need to be removed.\n *\n * @param span A span that has yet to be finished, must contain `url` on data.\n */\nfunction addHTTPTimings(span: Span): void {\n  const { url } = spanToJSON(span).data || {};\n\n  if (!url || typeof url !== 'string') {\n    return;\n  }\n\n  const cleanup = addPerformanceInstrumentationHandler('resource', ({ entries }) => {\n    entries.forEach(entry => {\n      if (isPerformanceResourceTiming(entry) && entry.name.endsWith(url)) {\n        const spanData = resourceTimingEntryToSpanData(entry);\n        spanData.forEach(data => span.setAttribute(...data));\n        // In the next tick, clean this handler up\n        // We have to wait here because otherwise this cleans itself up before it is fully done\n        setTimeout(cleanup);\n      }\n    });\n  });\n}\n\nfunction getAbsoluteTime(time: number = 0): number {\n  return ((browserPerformanceTimeOrigin || performance.timeOrigin) + time) / 1000;\n}\n\nfunction resourceTimingEntryToSpanData(resourceTiming: PerformanceResourceTiming): [string, string | number][] {\n  const { name, version } = extractNetworkProtocol(resourceTiming.nextHopProtocol);\n\n  const timingSpanData: [string, string | number][] = [];\n\n  timingSpanData.push(['network.protocol.version', version], ['network.protocol.name', name]);\n\n  if (!browserPerformanceTimeOrigin) {\n    return timingSpanData;\n  }\n  return [\n    ...timingSpanData,\n    ['http.request.redirect_start', getAbsoluteTime(resourceTiming.redirectStart)],\n    ['http.request.fetch_start', getAbsoluteTime(resourceTiming.fetchStart)],\n    ['http.request.domain_lookup_start', getAbsoluteTime(resourceTiming.domainLookupStart)],\n    ['http.request.domain_lookup_end', getAbsoluteTime(resourceTiming.domainLookupEnd)],\n    ['http.request.connect_start', getAbsoluteTime(resourceTiming.connectStart)],\n    ['http.request.secure_connection_start', getAbsoluteTime(resourceTiming.secureConnectionStart)],\n    ['http.request.connection_end', getAbsoluteTime(resourceTiming.connectEnd)],\n    ['http.request.request_start', getAbsoluteTime(resourceTiming.requestStart)],\n    ['http.request.response_start', getAbsoluteTime(resourceTiming.responseStart)],\n    ['http.request.response_end', getAbsoluteTime(resourceTiming.responseEnd)],\n  ];\n}\n\n/**\n * A function that determines whether to attach tracing headers to a request.\n * We only export this function for testing purposes.\n */\nexport function shouldAttachHeaders(\n  targetUrl: string,\n  tracePropagationTargets: (string | RegExp)[] | undefined,\n): boolean {\n  // window.location.href not being defined is an edge case in the browser but we need to handle it.\n  // Potentially dangerous situations where it may not be defined: Browser Extensions, Web Workers, patching of the location obj\n  const href: string | undefined = WINDOW.location && WINDOW.location.href;\n\n  if (!href) {\n    // If there is no window.location.origin, we default to only attaching tracing headers to relative requests, i.e. ones that start with `/`\n    // BIG DISCLAIMER: Users can call URLs with a double slash (fetch(\"//example.com/api\")), this is a shorthand for \"send to the same protocol\",\n    // so we need a to exclude those requests, because they might be cross origin.\n    const isRelativeSameOriginRequest = !!targetUrl.match(/^\\/(?!\\/)/);\n    if (!tracePropagationTargets) {\n      return isRelativeSameOriginRequest;\n    } else {\n      return stringMatchesSomePattern(targetUrl, tracePropagationTargets);\n    }\n  } else {\n    let resolvedUrl;\n    let currentOrigin;\n\n    // URL parsing may fail, we default to not attaching trace headers in that case.\n    try {\n      resolvedUrl = new URL(targetUrl, href);\n      currentOrigin = new URL(href).origin;\n    } catch (e) {\n      return false;\n    }\n\n    const isSameOriginRequest = resolvedUrl.origin === currentOrigin;\n    if (!tracePropagationTargets) {\n      return isSameOriginRequest;\n    } else {\n      return (\n        stringMatchesSomePattern(resolvedUrl.toString(), tracePropagationTargets) ||\n        (isSameOriginRequest && stringMatchesSomePattern(resolvedUrl.pathname, tracePropagationTargets))\n      );\n    }\n  }\n}\n\n/**\n * Create and track xhr request spans\n *\n * @returns Span if a span was created, otherwise void.\n */\nexport function xhrCallback(\n  handlerData: HandlerDataXhr,\n  shouldCreateSpan: (url: string) => boolean,\n  shouldAttachHeaders: (url: string) => boolean,\n  spans: Record<string, Span>,\n): Span | undefined {\n  const xhr = handlerData.xhr;\n  const sentryXhrData = xhr && xhr[SENTRY_XHR_DATA_KEY];\n\n  if (!xhr || xhr.__sentry_own_request__ || !sentryXhrData) {\n    return undefined;\n  }\n\n  const shouldCreateSpanResult = hasTracingEnabled() && shouldCreateSpan(sentryXhrData.url);\n\n  // check first if the request has finished and is tracked by an existing span which should now end\n  if (handlerData.endTimestamp && shouldCreateSpanResult) {\n    const spanId = xhr.__sentry_xhr_span_id__;\n    if (!spanId) return;\n\n    const span = spans[spanId];\n    if (span && sentryXhrData.status_code !== undefined) {\n      setHttpStatus(span, sentryXhrData.status_code);\n      span.end();\n\n      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n      delete spans[spanId];\n    }\n    return undefined;\n  }\n\n  const fullUrl = getFullURL(sentryXhrData.url);\n  const host = fullUrl ? parseUrl(fullUrl).host : undefined;\n\n  const hasParent = !!getActiveSpan();\n\n  const span =\n    shouldCreateSpanResult && hasParent\n      ? startInactiveSpan({\n          name: `${sentryXhrData.method} ${sentryXhrData.url}`,\n          attributes: {\n            type: 'xhr',\n            'http.method': sentryXhrData.method,\n            'http.url': fullUrl,\n            url: sentryXhrData.url,\n            'server.address': host,\n            [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.browser',\n            [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client',\n          },\n        })\n      : new SentryNonRecordingSpan();\n\n  xhr.__sentry_xhr_span_id__ = span.spanContext().spanId;\n  spans[xhr.__sentry_xhr_span_id__] = span;\n\n  if (shouldAttachHeaders(sentryXhrData.url)) {\n    addTracingHeadersToXhrRequest(\n      xhr,\n      // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction),\n      // we do not want to use the span as base for the trace headers,\n      // which means that the headers will be generated from the scope and the sampling decision is deferred\n      hasTracingEnabled() && hasParent ? span : undefined,\n    );\n  }\n\n  return span;\n}\n\nfunction addTracingHeadersToXhrRequest(xhr: SentryWrappedXMLHttpRequest, span?: Span): void {\n  const { 'sentry-trace': sentryTrace, baggage } = getTraceData({ span });\n\n  if (sentryTrace) {\n    setHeaderOnXhr(xhr, sentryTrace, baggage);\n  }\n}\n\nfunction setHeaderOnXhr(\n  xhr: SentryWrappedXMLHttpRequest,\n  sentryTraceHeader: string,\n  sentryBaggageHeader: string | undefined,\n): void {\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    xhr.setRequestHeader!('sentry-trace', sentryTraceHeader);\n    if (sentryBaggageHeader) {\n      // From MDN: \"If this method is called several times with the same header, the values are merged into one single request header.\"\n      // We can therefore simply set a baggage header without checking what was there before\n      // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      xhr.setRequestHeader!('baggage', sentryBaggageHeader);\n    }\n  } catch (_) {\n    // Error: InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.\n  }\n}\n\nfunction getFullURL(url: string): string | undefined {\n  try {\n    // By adding a base URL to new URL(), this will also work for relative urls\n    // If `url` is a full URL, the base URL is ignored anyhow\n    const parsed = new URL(url, WINDOW.location.origin);\n    return parsed.href;\n  } catch {\n    return undefined;\n  }\n}\n", "import { SPAN_STATUS_ERROR, getActiveSpan, getRootSpan, logger, spanToJSON } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\n\n/**\n * Add a listener that cancels and finishes a transaction when the global\n * document is hidden.\n */\nexport function registerBackgroundTabDetection(): void {\n  if (WINDOW && WINDOW.document) {\n    WINDOW.document.addEventListener('visibilitychange', () => {\n      const activeSpan = getActiveSpan();\n      if (!activeSpan) {\n        return;\n      }\n\n      const rootSpan = getRootSpan(activeSpan);\n\n      if (WINDOW.document.hidden && rootSpan) {\n        const cancelledStatus = 'cancelled';\n\n        const { op, status } = spanToJSON(rootSpan);\n\n        if (DEBUG_BUILD) {\n          logger.log(`[Tracing] Transaction: ${cancelledStatus} -> since tab moved to the background, op: ${op}`);\n        }\n\n        // We should not set status if it is already set, this prevent important statuses like\n        // error or data loss from being overwritten on transaction.\n        if (!status) {\n          rootSpan.setStatus({ code: SPAN_STATUS_ERROR, message: cancelledStatus });\n        }\n\n        rootSpan.setAttribute('sentry.cancellation_reason', 'document.hidden');\n        rootSpan.end();\n      }\n    });\n  } else {\n    DEBUG_BUILD && logger.warn('[Tracing] Could not set up background tab detection due to lack of global document');\n  }\n}\n", "/* eslint-disable max-lines */\nimport {\n  addHistoryInstrumentationHandler,\n  addPerformanceEntries,\n  registerInpInteractionListener,\n  startTrackingINP,\n  startTrackingInteractions,\n  startTrackingLongAnimationFrames,\n  startTrackingLongTasks,\n  startTrackingWebVitals,\n} from '@sentry-internal/browser-utils';\nimport type { Client, IntegrationFn, Span, StartSpanOptions, TransactionSource } from '@sentry/core';\nimport {\n  GLOBAL_OBJ,\n  SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON,\n  SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n  SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n  TRACING_DEFAULTS,\n  browserPerformanceTimeOrigin,\n  generateTraceId,\n  getActiveSpan,\n  getClient,\n  getCurrentScope,\n  getDomElement,\n  getDynamicSamplingContextFromSpan,\n  getIsolationScope,\n  getRootSpan,\n  logger,\n  propagationContextFromHeaders,\n  registerSpanErrorInstrumentation,\n  spanIsSampled,\n  spanToJSON,\n  startIdleSpan,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport { registerBackgroundTabDetection } from './backgroundtab';\nimport { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './request';\n\nexport const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\ninterface RouteInfo {\n  name: string | undefined;\n  source: TransactionSource | undefined;\n}\n\n/** Options for Browser Tracing integration */\nexport interface BrowserTracingOptions {\n  /**\n   * The time that has to pass without any span being created.\n   * If this time is exceeded, the idle span will finish.\n   *\n   * Default: 1000 (ms)\n   */\n  idleTimeout: number;\n\n  /**\n   * The max. time an idle span may run.\n   * If this time is exceeded, the idle span will finish no matter what.\n   *\n   * Default: 30000 (ms)\n   */\n  finalTimeout: number;\n\n  /**\n   The max. time an idle span may run.\n   * If this time is exceeded, the idle span will finish no matter what.\n   *\n   * Default: 15000 (ms)\n   */\n  childSpanTimeout: number;\n\n  /**\n   * If a span should be created on page load.\n   * If this is set to `false`, this integration will not start the default page load span.\n   * Default: true\n   */\n  instrumentPageLoad: boolean;\n\n  /**\n   * If a span should be created on navigation (history change).\n   * If this is set to `false`, this integration will not start the default navigation spans.\n   * Default: true\n   */\n  instrumentNavigation: boolean;\n\n  /**\n   * Flag spans where tabs moved to background with \"cancelled\". Browser background tab timing is\n   * not suited towards doing precise measurements of operations. By default, we recommend that this option\n   * be enabled as background transactions can mess up your statistics in nondeterministic ways.\n   *\n   * Default: true\n   */\n  markBackgroundSpan: boolean;\n\n  /**\n   * If true, Sentry will capture long tasks and add them to the corresponding transaction.\n   *\n   * Default: true\n   */\n  enableLongTask: boolean;\n\n  /**\n   * If true, Sentry will capture long animation frames and add them to the corresponding transaction.\n   *\n   * Default: false\n   */\n  enableLongAnimationFrame: boolean;\n\n  /**\n   * If true, Sentry will capture first input delay and add it to the corresponding transaction.\n   *\n   * Default: true\n   */\n  enableInp: boolean;\n\n  /**\n   * Flag to disable patching all together for fetch requests.\n   *\n   * Default: true\n   */\n  traceFetch: boolean;\n\n  /**\n   * Flag to disable patching all together for xhr requests.\n   *\n   * Default: true\n   */\n  traceXHR: boolean;\n\n  /**\n   * Flag to disable tracking of long-lived streams, like server-sent events (SSE) via fetch.\n   * Do not enable this in case you have live streams or very long running streams.\n   *\n   * Default: false\n   */\n  trackFetchStreamPerformance: boolean;\n\n  /**\n   * If true, Sentry will capture http timings and add them to the corresponding http spans.\n   *\n   * Default: true\n   */\n  enableHTTPTimings: boolean;\n\n  /**\n   * _experiments allows the user to send options to define how this integration works.\n   *\n   * Default: undefined\n   */\n  _experiments: Partial<{\n    enableInteractions: boolean;\n    enableStandaloneClsSpans: boolean;\n  }>;\n\n  /**\n   * A callback which is called before a span for a pageload or navigation is started.\n   * It receives the options passed to `startSpan`, and expects to return an updated options object.\n   */\n  beforeStartSpan?: (options: StartSpanOptions) => StartSpanOptions;\n\n  /**\n   * This function will be called before creating a span for a request with the given url.\n   * Return false if you don't want a span for the given url.\n   *\n   * Default: (url: string) => true\n   */\n  shouldCreateSpanForRequest?(this: void, url: string): boolean;\n}\n\nconst DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = {\n  ...TRACING_DEFAULTS,\n  instrumentNavigation: true,\n  instrumentPageLoad: true,\n  markBackgroundSpan: true,\n  enableLongTask: true,\n  enableLongAnimationFrame: true,\n  enableInp: true,\n  _experiments: {},\n  ...defaultRequestInstrumentationOptions,\n};\n\n/**\n * The Browser Tracing integration automatically instruments browser pageload/navigation\n * actions as transactions, and captures requests, metrics and errors as spans.\n *\n * The integration can be configured with a variety of options, and can be extended to use\n * any routing library.\n *\n * We explicitly export the proper type here, as this has to be extended in some cases.\n */\nexport const browserTracingIntegration = ((_options: Partial<BrowserTracingOptions> = {}) => {\n  registerSpanErrorInstrumentation();\n\n  const {\n    enableInp,\n    enableLongTask,\n    enableLongAnimationFrame,\n    _experiments: { enableInteractions, enableStandaloneClsSpans },\n    beforeStartSpan,\n    idleTimeout,\n    finalTimeout,\n    childSpanTimeout,\n    markBackgroundSpan,\n    traceFetch,\n    traceXHR,\n    trackFetchStreamPerformance,\n    shouldCreateSpanForRequest,\n    enableHTTPTimings,\n    instrumentPageLoad,\n    instrumentNavigation,\n  } = {\n    ...DEFAULT_BROWSER_TRACING_OPTIONS,\n    ..._options,\n  };\n\n  const _collectWebVitals = startTrackingWebVitals({ recordClsStandaloneSpans: enableStandaloneClsSpans || false });\n\n  if (enableInp) {\n    startTrackingINP();\n  }\n\n  if (\n    enableLongAnimationFrame &&\n    GLOBAL_OBJ.PerformanceObserver &&\n    PerformanceObserver.supportedEntryTypes &&\n    PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')\n  ) {\n    startTrackingLongAnimationFrames();\n  } else if (enableLongTask) {\n    startTrackingLongTasks();\n  }\n\n  if (enableInteractions) {\n    startTrackingInteractions();\n  }\n\n  const latestRoute: RouteInfo = {\n    name: undefined,\n    source: undefined,\n  };\n\n  /** Create routing idle transaction. */\n  function _createRouteSpan(client: Client, startSpanOptions: StartSpanOptions): Span {\n    const isPageloadTransaction = startSpanOptions.op === 'pageload';\n\n    const finalStartSpanOptions: StartSpanOptions = beforeStartSpan\n      ? beforeStartSpan(startSpanOptions)\n      : startSpanOptions;\n\n    const attributes = finalStartSpanOptions.attributes || {};\n\n    // If `finalStartSpanOptions.name` is different than `startSpanOptions.name`\n    // it is because `beforeStartSpan` set a custom name. Therefore we set the source to 'custom'.\n    if (startSpanOptions.name !== finalStartSpanOptions.name) {\n      attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'custom';\n      finalStartSpanOptions.attributes = attributes;\n    }\n\n    latestRoute.name = finalStartSpanOptions.name;\n    latestRoute.source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n\n    const idleSpan = startIdleSpan(finalStartSpanOptions, {\n      idleTimeout,\n      finalTimeout,\n      childSpanTimeout,\n      // should wait for finish signal if it's a pageload transaction\n      disableAutoFinish: isPageloadTransaction,\n      beforeSpanEnd: span => {\n        _collectWebVitals();\n        addPerformanceEntries(span, { recordClsOnPageloadSpan: !enableStandaloneClsSpans });\n      },\n    });\n\n    function emitFinish(): void {\n      if (['interactive', 'complete'].includes(WINDOW.document.readyState)) {\n        client.emit('idleSpanEnableAutoFinish', idleSpan);\n      }\n    }\n\n    if (isPageloadTransaction && WINDOW.document) {\n      WINDOW.document.addEventListener('readystatechange', () => {\n        emitFinish();\n      });\n\n      emitFinish();\n    }\n\n    return idleSpan;\n  }\n\n  return {\n    name: BROWSER_TRACING_INTEGRATION_ID,\n    afterAllSetup(client) {\n      let activeSpan: Span | undefined;\n      let startingUrl: string | undefined = WINDOW.location && WINDOW.location.href;\n\n      function maybeEndActiveSpan(): void {\n        if (activeSpan && !spanToJSON(activeSpan).timestamp) {\n          DEBUG_BUILD && logger.log(`[Tracing] Finishing current active span with op: ${spanToJSON(activeSpan).op}`);\n          // If there's an open active span, we need to finish it before creating an new one.\n          activeSpan.end();\n        }\n      }\n\n      client.on('startNavigationSpan', startSpanOptions => {\n        if (getClient() !== client) {\n          return;\n        }\n\n        maybeEndActiveSpan();\n\n        activeSpan = _createRouteSpan(client, {\n          op: 'navigation',\n          ...startSpanOptions,\n        });\n      });\n\n      client.on('startPageLoadSpan', (startSpanOptions, traceOptions = {}) => {\n        if (getClient() !== client) {\n          return;\n        }\n        maybeEndActiveSpan();\n\n        const sentryTrace = traceOptions.sentryTrace || getMetaContent('sentry-trace');\n        const baggage = traceOptions.baggage || getMetaContent('baggage');\n\n        const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n        getCurrentScope().setPropagationContext(propagationContext);\n\n        activeSpan = _createRouteSpan(client, {\n          op: 'pageload',\n          ...startSpanOptions,\n        });\n      });\n\n      // A trace should to stay the consistent over the entire time span of one route.\n      // Therefore, when the initial pageload or navigation root span ends, we update the\n      // scope's propagation context to keep span-specific attributes like the `sampled` decision and\n      // the dynamic sampling context valid, even after the root span has ended.\n      // This ensures that the trace data is consistent for the entire duration of the route.\n      client.on('spanEnd', span => {\n        const op = spanToJSON(span).op;\n        if (span !== getRootSpan(span) || (op !== 'navigation' && op !== 'pageload')) {\n          return;\n        }\n\n        const scope = getCurrentScope();\n        const oldPropagationContext = scope.getPropagationContext();\n\n        scope.setPropagationContext({\n          ...oldPropagationContext,\n          sampled: oldPropagationContext.sampled !== undefined ? oldPropagationContext.sampled : spanIsSampled(span),\n          dsc: oldPropagationContext.dsc || getDynamicSamplingContextFromSpan(span),\n        });\n      });\n\n      if (WINDOW.location) {\n        if (instrumentPageLoad) {\n          startBrowserTracingPageLoadSpan(client, {\n            name: WINDOW.location.pathname,\n            // pageload should always start at timeOrigin (and needs to be in s, not ms)\n            startTime: browserPerformanceTimeOrigin ? browserPerformanceTimeOrigin / 1000 : undefined,\n            attributes: {\n              [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n              [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',\n            },\n          });\n        }\n\n        if (instrumentNavigation) {\n          addHistoryInstrumentationHandler(({ to, from }) => {\n            /**\n             * This early return is there to account for some cases where a navigation transaction starts right after\n             * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't\n             * create an uneccessary navigation transaction.\n             *\n             * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also\n             * only be caused in certain development environments where the usage of a hot module reloader is causing\n             * errors.\n             */\n            if (from === undefined && startingUrl && startingUrl.indexOf(to) !== -1) {\n              startingUrl = undefined;\n              return;\n            }\n\n            if (from !== to) {\n              startingUrl = undefined;\n              startBrowserTracingNavigationSpan(client, {\n                name: WINDOW.location.pathname,\n                attributes: {\n                  [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n                  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.browser',\n                },\n              });\n            }\n          });\n        }\n      }\n\n      if (markBackgroundSpan) {\n        registerBackgroundTabDetection();\n      }\n\n      if (enableInteractions) {\n        registerInteractionListener(idleTimeout, finalTimeout, childSpanTimeout, latestRoute);\n      }\n\n      if (enableInp) {\n        registerInpInteractionListener();\n      }\n\n      instrumentOutgoingRequests(client, {\n        traceFetch,\n        traceXHR,\n        trackFetchStreamPerformance,\n        tracePropagationTargets: client.getOptions().tracePropagationTargets,\n        shouldCreateSpanForRequest,\n        enableHTTPTimings,\n      });\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * Manually start a page load span.\n * This will only do something if a browser tracing integration integration has been setup.\n *\n * If you provide a custom `traceOptions` object, it will be used to continue the trace\n * instead of the default behavior, which is to look it up on the <meta> tags.\n */\nexport function startBrowserTracingPageLoadSpan(\n  client: Client,\n  spanOptions: StartSpanOptions,\n  traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },\n): Span | undefined {\n  client.emit('startPageLoadSpan', spanOptions, traceOptions);\n\n  getCurrentScope().setTransactionName(spanOptions.name);\n\n  const span = getActiveSpan();\n  const op = span && spanToJSON(span).op;\n  return op === 'pageload' ? span : undefined;\n}\n\n/**\n * Manually start a navigation span.\n * This will only do something if a browser tracing integration has been setup.\n */\nexport function startBrowserTracingNavigationSpan(client: Client, spanOptions: StartSpanOptions): Span | undefined {\n  getIsolationScope().setPropagationContext({ traceId: generateTraceId() });\n  getCurrentScope().setPropagationContext({ traceId: generateTraceId() });\n\n  client.emit('startNavigationSpan', spanOptions);\n\n  getCurrentScope().setTransactionName(spanOptions.name);\n\n  const span = getActiveSpan();\n  const op = span && spanToJSON(span).op;\n  return op === 'navigation' ? span : undefined;\n}\n\n/** Returns the value of a meta tag */\nexport function getMetaContent(metaName: string): string | undefined {\n  // Can't specify generic to `getDomElement` because tracing can be used\n  // in a variety of environments, have to disable `no-unsafe-member-access`\n  // as a result.\n  // eslint-disable-next-line deprecation/deprecation\n  const metaTag = getDomElement(`meta[name=${metaName}]`);\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n  return metaTag ? metaTag.getAttribute('content') : undefined;\n}\n\n/** Start listener for interaction transactions */\nfunction registerInteractionListener(\n  idleTimeout: BrowserTracingOptions['idleTimeout'],\n  finalTimeout: BrowserTracingOptions['finalTimeout'],\n  childSpanTimeout: BrowserTracingOptions['childSpanTimeout'],\n  latestRoute: RouteInfo,\n): void {\n  let inflightInteractionSpan: Span | undefined;\n  const registerInteractionTransaction = (): void => {\n    const op = 'ui.action.click';\n\n    const activeSpan = getActiveSpan();\n    const rootSpan = activeSpan && getRootSpan(activeSpan);\n    if (rootSpan) {\n      const currentRootSpanOp = spanToJSON(rootSpan).op;\n      if (['navigation', 'pageload'].includes(currentRootSpanOp as string)) {\n        DEBUG_BUILD &&\n          logger.warn(`[Tracing] Did not create ${op} span because a pageload or navigation span is in progress.`);\n        return undefined;\n      }\n    }\n\n    if (inflightInteractionSpan) {\n      inflightInteractionSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, 'interactionInterrupted');\n      inflightInteractionSpan.end();\n      inflightInteractionSpan = undefined;\n    }\n\n    if (!latestRoute.name) {\n      DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);\n      return undefined;\n    }\n\n    inflightInteractionSpan = startIdleSpan(\n      {\n        name: latestRoute.name,\n        op,\n        attributes: {\n          [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRoute.source || 'url',\n        },\n      },\n      {\n        idleTimeout,\n        finalTimeout,\n        childSpanTimeout,\n      },\n    );\n  };\n\n  if (WINDOW.document) {\n    addEventListener('click', registerInteractionTransaction, { once: false, capture: true });\n  }\n}\n", "import type { BaseTransportOptions, Envelope, OfflineStore, OfflineTransportOptions, Transport } from '@sentry/core';\nimport { makeOfflineTransport, parseEnvelope, serializeEnvelope } from '@sentry/core';\nimport { WINDOW } from '../helpers';\nimport { makeFetchTransport } from './fetch';\n\n// 'Store', 'promisifyRequest' and 'createStore' were originally copied from the 'idb-keyval' package before being\n// modified and simplified: https://github.com/jakearchibald/idb-keyval\n//\n// At commit: 0420a704fd6cbb4225429c536b1f61112d012fca\n// Original license:\n\n// Copyright 2016, Jake Archibald\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//   http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\ntype Store = <T>(callback: (store: IDBObjectStore) => T | PromiseLike<T>) => Promise<T>;\n\nfunction promisifyRequest<T = undefined>(request: IDBRequest<T> | IDBTransaction): Promise<T> {\n  return new Promise<T>((resolve, reject) => {\n    // @ts-expect-error - file size hacks\n    request.oncomplete = request.onsuccess = () => resolve(request.result);\n    // @ts-expect-error - file size hacks\n    request.onabort = request.onerror = () => reject(request.error);\n  });\n}\n\n/** Create or open an IndexedDb store */\nexport function createStore(dbName: string, storeName: string): Store {\n  const request = indexedDB.open(dbName);\n  request.onupgradeneeded = () => request.result.createObjectStore(storeName);\n  const dbp = promisifyRequest(request);\n\n  return callback => dbp.then(db => callback(db.transaction(storeName, 'readwrite').objectStore(storeName)));\n}\n\nfunction keys(store: IDBObjectStore): Promise<number[]> {\n  return promisifyRequest(store.getAllKeys() as IDBRequest<number[]>);\n}\n\n/** Insert into the end of the store */\nexport function push(store: Store, value: Uint8Array | string, maxQueueSize: number): Promise<void> {\n  return store(store => {\n    return keys(store).then(keys => {\n      if (keys.length >= maxQueueSize) {\n        return;\n      }\n\n      // We insert with an incremented key so that the entries are popped in order\n      store.put(value, Math.max(...keys, 0) + 1);\n      return promisifyRequest(store.transaction);\n    });\n  });\n}\n\n/** Insert into the front of the store */\nexport function unshift(store: Store, value: Uint8Array | string, maxQueueSize: number): Promise<void> {\n  return store(store => {\n    return keys(store).then(keys => {\n      if (keys.length >= maxQueueSize) {\n        return;\n      }\n\n      // We insert with an decremented key so that the entries are popped in order\n      store.put(value, Math.min(...keys, 0) - 1);\n      return promisifyRequest(store.transaction);\n    });\n  });\n}\n\n/** Pop the oldest value from the store */\nexport function shift(store: Store): Promise<Uint8Array | string | undefined> {\n  return store(store => {\n    return keys(store).then(keys => {\n      const firstKey = keys[0];\n      if (firstKey == null) {\n        return undefined;\n      }\n\n      return promisifyRequest(store.get(firstKey)).then(value => {\n        store.delete(firstKey);\n        return promisifyRequest(store.transaction).then(() => value);\n      });\n    });\n  });\n}\n\nexport interface BrowserOfflineTransportOptions extends Omit<OfflineTransportOptions, 'createStore'> {\n  /**\n   * Name of indexedDb database to store envelopes in\n   * Default: 'sentry-offline'\n   */\n  dbName?: string;\n  /**\n   * Name of indexedDb object store to store envelopes in\n   * Default: 'queue'\n   */\n  storeName?: string;\n  /**\n   * Maximum number of envelopes to store\n   * Default: 30\n   */\n  maxQueueSize?: number;\n}\n\nfunction createIndexedDbStore(options: BrowserOfflineTransportOptions): OfflineStore {\n  let store: Store | undefined;\n\n  // Lazily create the store only when it's needed\n  function getStore(): Store {\n    if (store == undefined) {\n      store = createStore(options.dbName || 'sentry-offline', options.storeName || 'queue');\n    }\n\n    return store;\n  }\n\n  return {\n    push: async (env: Envelope) => {\n      try {\n        const serialized = await serializeEnvelope(env);\n        await push(getStore(), serialized, options.maxQueueSize || 30);\n      } catch (_) {\n        //\n      }\n    },\n    unshift: async (env: Envelope) => {\n      try {\n        const serialized = await serializeEnvelope(env);\n        await unshift(getStore(), serialized, options.maxQueueSize || 30);\n      } catch (_) {\n        //\n      }\n    },\n    shift: async () => {\n      try {\n        const deserialized = await shift(getStore());\n        if (deserialized) {\n          return parseEnvelope(deserialized);\n        }\n      } catch (_) {\n        //\n      }\n\n      return undefined;\n    },\n  };\n}\n\nfunction makeIndexedDbOfflineTransport<T>(\n  createTransport: (options: T) => Transport,\n): (options: T & BrowserOfflineTransportOptions) => Transport {\n  return options => {\n    const transport = createTransport({ ...options, createStore: createIndexedDbStore });\n\n    WINDOW.addEventListener('online', async _ => {\n      await transport.flush();\n    });\n\n    return transport;\n  };\n}\n\n/**\n * Creates a transport that uses IndexedDb to store events when offline.\n */\nexport function makeBrowserOfflineTransport<T extends BaseTransportOptions>(\n  createTransport: (options: T) => Transport = makeFetchTransport,\n): (options: T & BrowserOfflineTransportOptions) => Transport {\n  return makeIndexedDbOfflineTransport<T>(makeOfflineTransport(createTransport));\n}\n", "/* eslint-disable max-lines */\nimport type { DebugImage, Envelope, Event, EventEnvelope, Profile, Span, ThreadCpuProfile } from '@sentry/core';\nimport {\n  DEFAULT_ENVIRONMENT,\n  browserPerformanceTimeOrigin,\n  forEachEnvelopeItem,\n  getClient,\n  getDebugImagesForResources,\n  logger,\n  spanToJSON,\n  timestampInSeconds,\n  uuid4,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport type { JSSelfProfile, JSSelfProfileStack, JSSelfProfiler, JSSelfProfilerConstructor } from './jsSelfProfiling';\n\nconst MS_TO_NS = 1e6;\n// Use 0 as main thread id which is identical to threadId in node:worker_threads\n// where main logs 0 and workers seem to log in increments of 1\nconst THREAD_ID_STRING = String(0);\nconst THREAD_NAME = 'main';\n\n// Machine properties (eval only once)\nlet OS_PLATFORM = '';\nlet OS_PLATFORM_VERSION = '';\nlet OS_ARCH = '';\nlet OS_BROWSER = (WINDOW.navigator && WINDOW.navigator.userAgent) || '';\nlet OS_MODEL = '';\nconst OS_LOCALE =\n  (WINDOW.navigator && WINDOW.navigator.language) ||\n  (WINDOW.navigator && WINDOW.navigator.languages && WINDOW.navigator.languages[0]) ||\n  '';\n\ntype UAData = {\n  platform?: string;\n  architecture?: string;\n  model?: string;\n  platformVersion?: string;\n  fullVersionList?: {\n    brand: string;\n    version: string;\n  }[];\n};\n\ninterface UserAgentData {\n  getHighEntropyValues: (keys: string[]) => Promise<UAData>;\n}\n\nfunction isUserAgentData(data: unknown): data is UserAgentData {\n  return typeof data === 'object' && data !== null && 'getHighEntropyValues' in data;\n}\n\n// @ts-expect-error userAgentData is not part of the navigator interface yet\nconst userAgentData = WINDOW.navigator && WINDOW.navigator.userAgentData;\n\nif (isUserAgentData(userAgentData)) {\n  userAgentData\n    .getHighEntropyValues(['architecture', 'model', 'platform', 'platformVersion', 'fullVersionList'])\n    .then((ua: UAData) => {\n      OS_PLATFORM = ua.platform || '';\n      OS_ARCH = ua.architecture || '';\n      OS_MODEL = ua.model || '';\n      OS_PLATFORM_VERSION = ua.platformVersion || '';\n\n      if (ua.fullVersionList && ua.fullVersionList.length > 0) {\n        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n        const firstUa = ua.fullVersionList[ua.fullVersionList.length - 1]!;\n        OS_BROWSER = `${firstUa.brand} ${firstUa.version}`;\n      }\n    })\n    .catch(e => void e);\n}\n\nfunction isProcessedJSSelfProfile(profile: ThreadCpuProfile | JSSelfProfile): profile is JSSelfProfile {\n  return !('thread_metadata' in profile);\n}\n\n// Enriches the profile with threadId of the current thread.\n// This is done in node as we seem to not be able to get the info from C native code.\n/**\n *\n */\nexport function enrichWithThreadInformation(profile: ThreadCpuProfile | JSSelfProfile): ThreadCpuProfile {\n  if (!isProcessedJSSelfProfile(profile)) {\n    return profile;\n  }\n\n  return convertJSSelfProfileToSampledFormat(profile);\n}\n\n// Profile is marked as optional because it is deleted from the metadata\n// by the integration before the event is processed by other integrations.\nexport interface ProfiledEvent extends Event {\n  sdkProcessingMetadata: {\n    profile?: JSSelfProfile;\n  };\n}\n\nfunction getTraceId(event: Event): string {\n  const traceId: unknown = event && event.contexts && event.contexts['trace'] && event.contexts['trace']['trace_id'];\n  // Log a warning if the profile has an invalid traceId (should be uuidv4).\n  // All profiles and transactions are rejected if this is the case and we want to\n  // warn users that this is happening if they enable debug flag\n  if (typeof traceId === 'string' && traceId.length !== 32) {\n    if (DEBUG_BUILD) {\n      logger.log(`[Profiling] Invalid traceId: ${traceId} on profiled event`);\n    }\n  }\n  if (typeof traceId !== 'string') {\n    return '';\n  }\n\n  return traceId;\n}\n/**\n * Creates a profiling event envelope from a Sentry event. If profile does not pass\n * validation, returns null.\n * @param event\n * @param dsn\n * @param metadata\n * @param tunnel\n * @returns {EventEnvelope | null}\n */\n\n/**\n * Creates a profiling event envelope from a Sentry event.\n */\nexport function createProfilePayload(\n  profile_id: string,\n  start_timestamp: number | undefined,\n  processed_profile: JSSelfProfile,\n  event: ProfiledEvent,\n): Profile {\n  if (event.type !== 'transaction') {\n    // createProfilingEventEnvelope should only be called for transactions,\n    // we type guard this behavior with isProfiledTransactionEvent.\n    throw new TypeError('Profiling events may only be attached to transactions, this should never occur.');\n  }\n\n  if (processed_profile === undefined || processed_profile === null) {\n    throw new TypeError(\n      `Cannot construct profiling event envelope without a valid profile. Got ${processed_profile} instead.`,\n    );\n  }\n\n  const traceId = getTraceId(event);\n  const enrichedThreadProfile = enrichWithThreadInformation(processed_profile);\n  const transactionStartMs = start_timestamp\n    ? start_timestamp\n    : typeof event.start_timestamp === 'number'\n      ? event.start_timestamp * 1000\n      : timestampInSeconds() * 1000;\n  const transactionEndMs = typeof event.timestamp === 'number' ? event.timestamp * 1000 : timestampInSeconds() * 1000;\n\n  const profile: Profile = {\n    event_id: profile_id,\n    timestamp: new Date(transactionStartMs).toISOString(),\n    platform: 'javascript',\n    version: '1',\n    release: event.release || '',\n    environment: event.environment || DEFAULT_ENVIRONMENT,\n    runtime: {\n      name: 'javascript',\n      version: WINDOW.navigator.userAgent,\n    },\n    os: {\n      name: OS_PLATFORM,\n      version: OS_PLATFORM_VERSION,\n      build_number: OS_BROWSER,\n    },\n    device: {\n      locale: OS_LOCALE,\n      model: OS_MODEL,\n      manufacturer: OS_BROWSER,\n      architecture: OS_ARCH,\n      is_emulator: false,\n    },\n    debug_meta: {\n      images: applyDebugMetadata(processed_profile.resources),\n    },\n    profile: enrichedThreadProfile,\n    transactions: [\n      {\n        name: event.transaction || '',\n        id: event.event_id || uuid4(),\n        trace_id: traceId,\n        active_thread_id: THREAD_ID_STRING,\n        relative_start_ns: '0',\n        relative_end_ns: ((transactionEndMs - transactionStartMs) * 1e6).toFixed(0),\n      },\n    ],\n  };\n\n  return profile;\n}\n\n/**\n *\n */\nexport function isProfiledTransactionEvent(event: Event): event is ProfiledEvent {\n  return !!(event.sdkProcessingMetadata && event.sdkProcessingMetadata['profile']);\n}\n\n/*\n  See packages/browser-utils/src/browser/router.ts\n*/\n/**\n *\n */\nexport function isAutomatedPageLoadSpan(span: Span): boolean {\n  return spanToJSON(span).op === 'pageload';\n}\n\n/**\n * Converts a JSSelfProfile to a our sampled format.\n * Does not currently perform stack indexing.\n */\nexport function convertJSSelfProfileToSampledFormat(input: JSSelfProfile): Profile['profile'] {\n  let EMPTY_STACK_ID: undefined | number = undefined;\n  let STACK_ID = 0;\n\n  // Initialize the profile that we will fill with data\n  const profile: Profile['profile'] = {\n    samples: [],\n    stacks: [],\n    frames: [],\n    thread_metadata: {\n      [THREAD_ID_STRING]: { name: THREAD_NAME },\n    },\n  };\n\n  const firstSample = input.samples[0];\n  if (!firstSample) {\n    return profile;\n  }\n\n  // We assert samples.length > 0 above and timestamp should always be present\n  const start = firstSample.timestamp;\n  // The JS SDK might change it's time origin based on some heuristic (see See packages/utils/src/time.ts)\n  // when that happens, we need to ensure we are correcting the profile timings so the two timelines stay in sync.\n  // Since JS self profiling time origin is always initialized to performance.timeOrigin, we need to adjust for\n  // the drift between the SDK selected value and our profile time origin.\n  const origin =\n    typeof performance.timeOrigin === 'number' ? performance.timeOrigin : browserPerformanceTimeOrigin || 0;\n  const adjustForOriginChange = origin - (browserPerformanceTimeOrigin || origin);\n\n  input.samples.forEach((jsSample, i) => {\n    // If sample has no stack, add an empty sample\n    if (jsSample.stackId === undefined) {\n      if (EMPTY_STACK_ID === undefined) {\n        EMPTY_STACK_ID = STACK_ID;\n        profile.stacks[EMPTY_STACK_ID] = [];\n        STACK_ID++;\n      }\n\n      profile['samples'][i] = {\n        // convert ms timestamp to ns\n        elapsed_since_start_ns: ((jsSample.timestamp + adjustForOriginChange - start) * MS_TO_NS).toFixed(0),\n        stack_id: EMPTY_STACK_ID,\n        thread_id: THREAD_ID_STRING,\n      };\n      return;\n    }\n\n    let stackTop: JSSelfProfileStack | undefined = input.stacks[jsSample.stackId];\n\n    // Functions in top->down order (root is last)\n    // We follow the stackTop.parentId trail and collect each visited frameId\n    const stack: number[] = [];\n\n    while (stackTop) {\n      stack.push(stackTop.frameId);\n\n      const frame = input.frames[stackTop.frameId];\n\n      // If our frame has not been indexed yet, index it\n      if (frame && profile.frames[stackTop.frameId] === undefined) {\n        profile.frames[stackTop.frameId] = {\n          function: frame.name,\n          abs_path: typeof frame.resourceId === 'number' ? input.resources[frame.resourceId] : undefined,\n          lineno: frame.line,\n          colno: frame.column,\n        };\n      }\n\n      stackTop = stackTop.parentId === undefined ? undefined : input.stacks[stackTop.parentId];\n    }\n\n    const sample: Profile['profile']['samples'][0] = {\n      // convert ms timestamp to ns\n      elapsed_since_start_ns: ((jsSample.timestamp + adjustForOriginChange - start) * MS_TO_NS).toFixed(0),\n      stack_id: STACK_ID,\n      thread_id: THREAD_ID_STRING,\n    };\n\n    profile['stacks'][STACK_ID] = stack;\n    profile['samples'][i] = sample;\n    STACK_ID++;\n  });\n\n  return profile;\n}\n\n/**\n * Adds items to envelope if they are not already present - mutates the envelope.\n * @param envelope\n */\nexport function addProfilesToEnvelope(envelope: EventEnvelope, profiles: Profile[]): Envelope {\n  if (!profiles.length) {\n    return envelope;\n  }\n\n  for (const profile of profiles) {\n    envelope[1].push([{ type: 'profile' }, profile]);\n  }\n  return envelope;\n}\n\n/**\n * Finds transactions with profile_id context in the envelope\n * @param envelope\n * @returns\n */\nexport function findProfiledTransactionsFromEnvelope(envelope: Envelope): Event[] {\n  const events: Event[] = [];\n\n  forEachEnvelopeItem(envelope, (item, type) => {\n    if (type !== 'transaction') {\n      return;\n    }\n\n    for (let j = 1; j < item.length; j++) {\n      const event = item[j] as Event;\n\n      if (event && event.contexts && event.contexts['profile'] && event.contexts['profile']['profile_id']) {\n        events.push(item[j] as Event);\n      }\n    }\n  });\n\n  return events;\n}\n\n/**\n * Applies debug meta data to an event from a list of paths to resources (sourcemaps)\n */\nexport function applyDebugMetadata(resource_paths: ReadonlyArray<string>): DebugImage[] {\n  const client = getClient();\n  const options = client && client.getOptions();\n  const stackParser = options && options.stackParser;\n\n  if (!stackParser) {\n    return [];\n  }\n\n  return getDebugImagesForResources(stackParser, resource_paths);\n}\n\n/**\n * Checks the given sample rate to make sure it is valid type and value (a boolean, or a number between 0 and 1).\n */\nexport function isValidSampleRate(rate: unknown): boolean {\n  // we need to check NaN explicitly because it's of type 'number' and therefore wouldn't get caught by this typecheck\n  if ((typeof rate !== 'number' && typeof rate !== 'boolean') || (typeof rate === 'number' && isNaN(rate))) {\n    DEBUG_BUILD &&\n      logger.warn(\n        `[Profiling] Invalid sample rate. Sample rate must be a boolean or a number between 0 and 1. Got ${JSON.stringify(\n          rate,\n        )} of type ${JSON.stringify(typeof rate)}.`,\n      );\n    return false;\n  }\n\n  // Boolean sample rates are always valid\n  if (rate === true || rate === false) {\n    return true;\n  }\n\n  // in case sampleRate is a boolean, it will get automatically cast to 1 if it's true and 0 if it's false\n  if (rate < 0 || rate > 1) {\n    DEBUG_BUILD && logger.warn(`[Profiling] Invalid sample rate. Sample rate must be between 0 and 1. Got ${rate}.`);\n    return false;\n  }\n  return true;\n}\n\nfunction isValidProfile(profile: JSSelfProfile): profile is JSSelfProfile & { profile_id: string } {\n  if (profile.samples.length < 2) {\n    if (DEBUG_BUILD) {\n      // Log a warning if the profile has less than 2 samples so users can know why\n      // they are not seeing any profiling data and we cant avoid the back and forth\n      // of asking them to provide us with a dump of the profile data.\n      logger.log('[Profiling] Discarding profile because it contains less than 2 samples');\n    }\n    return false;\n  }\n\n  if (!profile.frames.length) {\n    if (DEBUG_BUILD) {\n      logger.log('[Profiling] Discarding profile because it contains no frames');\n    }\n    return false;\n  }\n\n  return true;\n}\n\n// Keep a flag value to avoid re-initializing the profiler constructor. If it fails\n// once, it will always fail and this allows us to early return.\nlet PROFILING_CONSTRUCTOR_FAILED: boolean = false;\nexport const MAX_PROFILE_DURATION_MS = 30_000;\n\n/**\n * Check if profiler constructor is available.\n * @param maybeProfiler\n */\nfunction isJSProfilerSupported(maybeProfiler: unknown): maybeProfiler is typeof JSSelfProfilerConstructor {\n  return typeof maybeProfiler === 'function';\n}\n\n/**\n * Starts the profiler and returns the profiler instance.\n */\nexport function startJSSelfProfile(): JSSelfProfiler | undefined {\n  // Feature support check first\n  const JSProfilerConstructor = WINDOW.Profiler;\n\n  if (!isJSProfilerSupported(JSProfilerConstructor)) {\n    if (DEBUG_BUILD) {\n      logger.log(\n        '[Profiling] Profiling is not supported by this browser, Profiler interface missing on window object.',\n      );\n    }\n    return;\n  }\n\n  // From initial testing, it seems that the minimum value for sampleInterval is 10ms.\n  const samplingIntervalMS = 10;\n  // Start the profiler\n  const maxSamples = Math.floor(MAX_PROFILE_DURATION_MS / samplingIntervalMS);\n\n  // Attempt to initialize the profiler constructor, if it fails, we disable profiling for the current user session.\n  // This is likely due to a missing 'Document-Policy': 'js-profiling' header. We do not want to throw an error if this happens\n  // as we risk breaking the user's application, so just disable profiling and log an error.\n  try {\n    return new JSProfilerConstructor({ sampleInterval: samplingIntervalMS, maxBufferSize: maxSamples });\n  } catch (e) {\n    if (DEBUG_BUILD) {\n      logger.log(\n        \"[Profiling] Failed to initialize the Profiling constructor, this is likely due to a missing 'Document-Policy': 'js-profiling' header.\",\n      );\n      logger.log('[Profiling] Disabling profiling for current user session.');\n    }\n    PROFILING_CONSTRUCTOR_FAILED = true;\n  }\n\n  return;\n}\n\n/**\n * Determine if a profile should be profiled.\n */\nexport function shouldProfileSpan(span: Span): boolean {\n  // If constructor failed once, it will always fail, so we can early return.\n  if (PROFILING_CONSTRUCTOR_FAILED) {\n    if (DEBUG_BUILD) {\n      logger.log('[Profiling] Profiling has been disabled for the duration of the current user session.');\n    }\n    return false;\n  }\n\n  if (!span.isRecording()) {\n    if (DEBUG_BUILD) {\n      logger.log('[Profiling] Discarding profile because transaction was not sampled.');\n    }\n    return false;\n  }\n\n  const client = getClient();\n  const options = client && client.getOptions();\n  if (!options) {\n    DEBUG_BUILD && logger.log('[Profiling] Profiling disabled, no options found.');\n    return false;\n  }\n\n  // @ts-expect-error profilesSampleRate is not part of the browser options yet\n  const profilesSampleRate: number | boolean | undefined = options.profilesSampleRate;\n\n  // Since this is coming from the user (or from a function provided by the user), who knows what we might get. (The\n  // only valid values are booleans or numbers between 0 and 1.)\n  if (!isValidSampleRate(profilesSampleRate)) {\n    DEBUG_BUILD && logger.warn('[Profiling] Discarding profile because of invalid sample rate.');\n    return false;\n  }\n\n  // if the function returned 0 (or false), or if `profileSampleRate` is 0, it's a sign the profile should be dropped\n  if (!profilesSampleRate) {\n    DEBUG_BUILD &&\n      logger.log(\n        '[Profiling] Discarding profile because a negative sampling decision was inherited or profileSampleRate is set to 0',\n      );\n    return false;\n  }\n\n  // Now we roll the dice. Math.random is inclusive of 0, but not of 1, so strict < is safe here. In case sampleRate is\n  // a boolean, the < comparison will cause it to be automatically cast to 1 if it's true and 0 if it's false.\n  const sampled = profilesSampleRate === true ? true : Math.random() < profilesSampleRate;\n  // Check if we should sample this profile\n  if (!sampled) {\n    DEBUG_BUILD &&\n      logger.log(\n        `[Profiling] Discarding profile because it's not included in the random sample (sampling rate = ${Number(\n          profilesSampleRate,\n        )})`,\n      );\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Creates a profiling envelope item, if the profile does not pass validation, returns null.\n * @param event\n * @returns {Profile | null}\n */\nexport function createProfilingEvent(\n  profile_id: string,\n  start_timestamp: number | undefined,\n  profile: JSSelfProfile,\n  event: ProfiledEvent,\n): Profile | null {\n  if (!isValidProfile(profile)) {\n    return null;\n  }\n\n  return createProfilePayload(profile_id, start_timestamp, profile, event);\n}\n\n// TODO (v8): We need to obtain profile ids in @sentry-internal/tracing,\n// but we don't have access to this map because importing this map would\n// cause a circular dependency. We need to resolve this in v8.\nconst PROFILE_MAP: Map<string, JSSelfProfile> = new Map();\n/**\n *\n */\nexport function getActiveProfilesCount(): number {\n  return PROFILE_MAP.size;\n}\n\n/**\n * Retrieves profile from global cache and removes it.\n */\nexport function takeProfileFromGlobalCache(profile_id: string): JSSelfProfile | undefined {\n  const profile = PROFILE_MAP.get(profile_id);\n  if (profile) {\n    PROFILE_MAP.delete(profile_id);\n  }\n  return profile;\n}\n/**\n * Adds profile to global cache and evicts the oldest profile if the cache is full.\n */\nexport function addProfileToGlobalCache(profile_id: string, profile: JSSelfProfile): void {\n  PROFILE_MAP.set(profile_id, profile);\n\n  if (PROFILE_MAP.size > 30) {\n    const last: string = PROFILE_MAP.keys().next().value;\n    PROFILE_MAP.delete(last);\n  }\n}\n", "import { getCurrentScope, spanToJSON } from '@sentry/core';\nimport { logger, timestampInSeconds, uuid4 } from '@sentry/core';\nimport type { Span } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport type { JSSelfProfile } from './jsSelfProfiling';\nimport { MAX_PROFILE_DURATION_MS, addProfileToGlobalCache, isAutomatedPageLoadSpan, startJSSelfProfile } from './utils';\n\n/**\n * Wraps startTransaction and stopTransaction with profiling related logic.\n * startProfileForTransaction is called after the call to startTransaction in order to avoid our own code from\n * being profiled. Because of that same reason, stopProfiling is called before the call to stopTransaction.\n */\nexport function startProfileForSpan(span: Span): void {\n  // Start the profiler and get the profiler instance.\n  let startTimestamp: number | undefined;\n  if (isAutomatedPageLoadSpan(span)) {\n    startTimestamp = timestampInSeconds() * 1000;\n  }\n\n  const profiler = startJSSelfProfile();\n\n  // We failed to construct the profiler, so we skip.\n  // No need to log anything as this has already been logged in startProfile.\n  if (!profiler) {\n    return;\n  }\n\n  if (DEBUG_BUILD) {\n    logger.log(`[Profiling] started profiling span: ${spanToJSON(span).description}`);\n  }\n\n  // We create \"unique\" span names to avoid concurrent spans with same names\n  // from being ignored by the profiler. From here on, only this span name should be used when\n  // calling the profiler methods. Note: we log the original name to the user to avoid confusion.\n  const profileId = uuid4();\n\n  // A couple of important things to note here:\n  // `CpuProfilerBindings.stopProfiling` will be scheduled to run in 30seconds in order to exceed max profile duration.\n  // Whichever of the two (span.finish/timeout) is first to run, the profiling will be stopped and the gathered profile\n  // will be processed when the original span is finished. Since onProfileHandler can be invoked multiple times in the\n  // event of an error or user mistake (calling span.finish multiple times), it is important that the behavior of onProfileHandler\n  // is idempotent as we do not want any timings or profiles to be overridden by the last call to onProfileHandler.\n  // After the original finish method is called, the event will be reported through the integration and delegated to transport.\n  const processedProfile: JSSelfProfile | null = null;\n\n  getCurrentScope().setContext('profile', {\n    profile_id: profileId,\n    start_timestamp: startTimestamp,\n  });\n\n  /**\n   * Idempotent handler for profile stop\n   */\n  async function onProfileHandler(): Promise<void> {\n    // Check if the profile exists and return it the behavior has to be idempotent as users may call span.finish multiple times.\n    if (!span) {\n      return;\n    }\n    // Satisfy the type checker, but profiler will always be defined here.\n    if (!profiler) {\n      return;\n    }\n    if (processedProfile) {\n      if (DEBUG_BUILD) {\n        logger.log('[Profiling] profile for:', spanToJSON(span).description, 'already exists, returning early');\n      }\n      return;\n    }\n\n    return profiler\n      .stop()\n      .then((profile: JSSelfProfile): void => {\n        if (maxDurationTimeoutID) {\n          WINDOW.clearTimeout(maxDurationTimeoutID);\n          maxDurationTimeoutID = undefined;\n        }\n\n        if (DEBUG_BUILD) {\n          logger.log(`[Profiling] stopped profiling of span: ${spanToJSON(span).description}`);\n        }\n\n        // In case of an overlapping span, stopProfiling may return null and silently ignore the overlapping profile.\n        if (!profile) {\n          if (DEBUG_BUILD) {\n            logger.log(\n              `[Profiling] profiler returned null profile for: ${spanToJSON(span).description}`,\n              'this may indicate an overlapping span or a call to stopProfiling with a profile title that was never started',\n            );\n          }\n          return;\n        }\n\n        addProfileToGlobalCache(profileId, profile);\n      })\n      .catch(error => {\n        if (DEBUG_BUILD) {\n          logger.log('[Profiling] error while stopping profiler:', error);\n        }\n      });\n  }\n\n  // Enqueue a timeout to prevent profiles from running over max duration.\n  let maxDurationTimeoutID: number | undefined = WINDOW.setTimeout(() => {\n    if (DEBUG_BUILD) {\n      logger.log('[Profiling] max profile duration elapsed, stopping profiling for:', spanToJSON(span).description);\n    }\n    // If the timeout exceeds, we want to stop profiling, but not finish the span\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    onProfileHandler();\n  }, MAX_PROFILE_DURATION_MS);\n\n  // We need to reference the original end call to avoid creating an infinite loop\n  const originalEnd = span.end.bind(span);\n\n  /**\n   * Wraps span `end()` with profiling related logic.\n   * startProfiling is called after the call to spanStart in order to avoid our own code from\n   * being profiled. Because of that same reason, stopProfiling is called before the call to spanEnd.\n   */\n  function profilingWrappedSpanEnd(): Span {\n    if (!span) {\n      return originalEnd();\n    }\n    // onProfileHandler should always return the same profile even if this is called multiple times.\n    // Always call onProfileHandler to ensure stopProfiling is called and the timeout is cleared.\n    void onProfileHandler().then(\n      () => {\n        originalEnd();\n      },\n      () => {\n        // If onProfileHandler fails, we still want to call the original finish method.\n        originalEnd();\n      },\n    );\n\n    return span;\n  }\n\n  span.end = profilingWrappedSpanEnd;\n}\n", "import { defineIntegration, getActiveSpan, getRootSpan } from '@sentry/core';\nimport { logger } from '@sentry/core';\nimport type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/core';\n\nimport { DEBUG_BUILD } from '../debug-build';\nimport { startProfileForSpan } from './startProfileForSpan';\nimport type { ProfiledEvent } from './utils';\nimport { isAutomatedPageLoadSpan, shouldProfileSpan } from './utils';\nimport {\n  addProfilesToEnvelope,\n  createProfilingEvent,\n  findProfiledTransactionsFromEnvelope,\n  getActiveProfilesCount,\n  takeProfileFromGlobalCache,\n} from './utils';\n\nconst INTEGRATION_NAME = 'BrowserProfiling';\n\nconst _browserProfilingIntegration = (() => {\n  return {\n    name: INTEGRATION_NAME,\n    setup(client) {\n      const activeSpan = getActiveSpan();\n      const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n      if (rootSpan && isAutomatedPageLoadSpan(rootSpan)) {\n        if (shouldProfileSpan(rootSpan)) {\n          startProfileForSpan(rootSpan);\n        }\n      }\n\n      client.on('spanStart', (span: Span) => {\n        if (span === getRootSpan(span) && shouldProfileSpan(span)) {\n          startProfileForSpan(span);\n        }\n      });\n\n      client.on('beforeEnvelope', (envelope): void => {\n        // if not profiles are in queue, there is nothing to add to the envelope.\n        if (!getActiveProfilesCount()) {\n          return;\n        }\n\n        const profiledTransactionEvents = findProfiledTransactionsFromEnvelope(envelope);\n        if (!profiledTransactionEvents.length) {\n          return;\n        }\n\n        const profilesToAddToEnvelope: Profile[] = [];\n\n        for (const profiledTransaction of profiledTransactionEvents) {\n          const context = profiledTransaction && profiledTransaction.contexts;\n          const profile_id = context && context['profile'] && context['profile']['profile_id'];\n          const start_timestamp = context && context['profile'] && context['profile']['start_timestamp'];\n\n          if (typeof profile_id !== 'string') {\n            DEBUG_BUILD && logger.log('[Profiling] cannot find profile for a span without a profile context');\n            continue;\n          }\n\n          if (!profile_id) {\n            DEBUG_BUILD && logger.log('[Profiling] cannot find profile for a span without a profile context');\n            continue;\n          }\n\n          // Remove the profile from the span context before sending, relay will take care of the rest.\n          if (context && context['profile']) {\n            delete context.profile;\n          }\n\n          const profile = takeProfileFromGlobalCache(profile_id);\n          if (!profile) {\n            DEBUG_BUILD && logger.log(`[Profiling] Could not retrieve profile for span: ${profile_id}`);\n            continue;\n          }\n\n          const profileEvent = createProfilingEvent(\n            profile_id,\n            start_timestamp as number | undefined,\n            profile,\n            profiledTransaction as ProfiledEvent,\n          );\n          if (profileEvent) {\n            profilesToAddToEnvelope.push(profileEvent);\n          }\n        }\n\n        addProfilesToEnvelope(envelope as EventEnvelope, profilesToAddToEnvelope);\n      });\n    },\n  };\n}) satisfies IntegrationFn;\n\nexport const browserProfilingIntegration = defineIntegration(_browserProfilingIntegration);\n", "import { getNativeImplementation } from '@sentry-internal/browser-utils';\nimport type { Client, Envelope, Event, IntegrationFn } from '@sentry/core';\nimport { defineIntegration, logger, serializeEnvelope } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { WINDOW } from '../helpers';\n\nexport type SpotlightConnectionOptions = {\n  /**\n   * Set this if the Spotlight Sidecar is not running on localhost:8969\n   * By default, the Url is set to http://localhost:8969/stream\n   */\n  sidecarUrl?: string;\n};\n\nexport const INTEGRATION_NAME = 'SpotlightBrowser';\n\nconst _spotlightIntegration = ((options: Partial<SpotlightConnectionOptions> = {}) => {\n  const sidecarUrl = options.sidecarUrl || 'http://localhost:8969/stream';\n\n  return {\n    name: INTEGRATION_NAME,\n    setup: () => {\n      DEBUG_BUILD && logger.log('Using Sidecar URL', sidecarUrl);\n    },\n    // We don't want to send interaction transactions/root spans created from\n    // clicks within Spotlight to Sentry. Neither do we want them to be sent to\n    // spotlight.\n    processEvent: event => (isSpotlightInteraction(event) ? null : event),\n    afterAllSetup: (client: Client) => {\n      setupSidecarForwarding(client, sidecarUrl);\n    },\n  };\n}) satisfies IntegrationFn;\n\nfunction setupSidecarForwarding(client: Client, sidecarUrl: string): void {\n  const makeFetch: typeof WINDOW.fetch | undefined = getNativeImplementation('fetch');\n  let failCount = 0;\n\n  client.on('beforeEnvelope', (envelope: Envelope) => {\n    if (failCount > 3) {\n      logger.warn('[Spotlight] Disabled Sentry -> Spotlight integration due to too many failed requests:', failCount);\n      return;\n    }\n\n    makeFetch(sidecarUrl, {\n      method: 'POST',\n      body: serializeEnvelope(envelope),\n      headers: {\n        'Content-Type': 'application/x-sentry-envelope',\n      },\n      mode: 'cors',\n    }).then(\n      res => {\n        if (res.status >= 200 && res.status < 400) {\n          // Reset failed requests counter on success\n          failCount = 0;\n        }\n      },\n      err => {\n        failCount++;\n        logger.error(\n          \"Sentry SDK can't connect to Sidecar is it running? See: https://spotlightjs.com/sidecar/npx/\",\n          err,\n        );\n      },\n    );\n  });\n}\n\n/**\n * Use this integration to send errors and transactions to Spotlight.\n *\n * Learn more about spotlight at https://spotlightjs.com\n */\nexport const spotlightBrowserIntegration = defineIntegration(_spotlightIntegration);\n\n/**\n * Flags if the event is a transaction created from an interaction with the spotlight UI.\n */\nexport function isSpotlightInteraction(event: Event): boolean {\n  return Boolean(\n    event.type === 'transaction' &&\n      event.spans &&\n      event.contexts &&\n      event.contexts.trace &&\n      event.contexts.trace.op === 'ui.action.click' &&\n      event.spans.some(({ description }) => description && description.includes('#sentry-spotlight')),\n  );\n}\n", "import type { Event, FeatureFlag } from '@sentry/core';\n\nimport { getCurrentScope, logger } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Ordered LRU cache for storing feature flags in the scope context. The name\n * of each flag in the buffer is unique, and the output of getAll() is ordered\n * from oldest to newest.\n */\n\n/**\n * Max size of the LRU flag buffer stored in Sentry scope and event contexts.\n */\nexport const FLAG_BUFFER_SIZE = 100;\n\n/**\n * Copies feature flags that are in current scope context to the event context\n */\nexport function copyFlagsFromScopeToEvent(event: Event): Event {\n  const scope = getCurrentScope();\n  const flagContext = scope.getScopeData().contexts.flags;\n  const flagBuffer = flagContext ? flagContext.values : [];\n\n  if (!flagBuffer.length) {\n    return event;\n  }\n\n  if (event.contexts === undefined) {\n    event.contexts = {};\n  }\n  event.contexts.flags = { values: [...flagBuffer] };\n  return event;\n}\n\n/**\n * Creates a feature flags values array in current context if it does not exist\n * and inserts the flag into a FeatureFlag array while maintaining ordered LRU\n * properties. Not thread-safe. After inserting:\n * - `flags` is sorted in order of recency, with the newest flag at the end.\n * - No other flags with the same name exist in `flags`.\n * - The length of `flags` does not exceed `maxSize`. The oldest flag is evicted\n *  as needed.\n *\n * @param name     Name of the feature flag to insert.\n * @param value    Value of the feature flag.\n * @param maxSize  Max number of flags the buffer should store. It's recommended\n *   to keep this consistent across insertions. Default is FLAG_BUFFER_SIZE\n */\nexport function insertFlagToScope(name: string, value: unknown, maxSize: number = FLAG_BUFFER_SIZE): void {\n  const scopeContexts = getCurrentScope().getScopeData().contexts;\n  if (!scopeContexts.flags) {\n    scopeContexts.flags = { values: [] };\n  }\n  const flags = scopeContexts.flags.values as FeatureFlag[];\n  insertToFlagBuffer(flags, name, value, maxSize);\n}\n\n/**\n * Exported for tests. Currently only accepts boolean values (otherwise no-op).\n */\nexport function insertToFlagBuffer(flags: FeatureFlag[], name: string, value: unknown, maxSize: number): void {\n  if (typeof value !== 'boolean') {\n    return;\n  }\n\n  if (flags.length > maxSize) {\n    DEBUG_BUILD && logger.error(`[Feature Flags] insertToFlagBuffer called on a buffer larger than maxSize=${maxSize}`);\n    return;\n  }\n\n  // Check if the flag is already in the buffer - O(n)\n  const index = flags.findIndex(f => f.flag === name);\n\n  if (index !== -1) {\n    // The flag was found, remove it from its current position - O(n)\n    flags.splice(index, 1);\n  }\n\n  if (flags.length === maxSize) {\n    // If at capacity, pop the earliest flag - O(n)\n    flags.shift();\n  }\n\n  // Push the flag to the end - O(1)\n  flags.push({\n    flag: name,\n    result: value,\n  });\n}\n", "import type { Client, Event, EventHint, Integration, IntegrationFn } from '@sentry/core';\n\nimport { defineIntegration } from '@sentry/core';\nimport { copyFlagsFromScopeToEvent, insertFlagToScope } from '../../utils/featureFlags';\n\nexport interface FeatureFlagsIntegration extends Integration {\n  addFeatureFlag: (name: string, value: unknown) => void;\n}\n\n/**\n * Sentry integration for buffering feature flags manually with an API, and\n * capturing them on error events. We recommend you do this on each flag\n * evaluation. Flags are buffered per Sentry scope and limited to 100 per event.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import * as Sentry from '@sentry/browser';\n * import { type FeatureFlagsIntegration } from '@sentry/browser';\n *\n * // Setup\n * Sentry.init(..., integrations: [Sentry.featureFlagsIntegration()])\n *\n * // Verify\n * const flagsIntegration = Sentry.getClient()?.getIntegrationByName<FeatureFlagsIntegration>('FeatureFlags');\n * if (flagsIntegration) {\n *   flagsIntegration.addFeatureFlag('my-flag', true);\n * } else {\n *   // check your setup\n * }\n * Sentry.captureException(Exception('broke')); // 'my-flag' should be captured to this Sentry event.\n * ```\n */\nexport const featureFlagsIntegration = defineIntegration(() => {\n  return {\n    name: 'FeatureFlags',\n\n    processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n      return copyFlagsFromScopeToEvent(event);\n    },\n\n    addFeatureFlag(name: string, value: unknown): void {\n      insertFlagToScope(name, value);\n    },\n  };\n}) as IntegrationFn<FeatureFlagsIntegration>;\n", "import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core';\nimport type { LDContext, LDEvaluationDetail, LDInspectionFlagUsedHandler } from './types';\n\nimport { defineIntegration } from '@sentry/core';\nimport { copyFlagsFromScopeToEvent, insertFlagToScope } from '../../../utils/featureFlags';\n\n/**\n * Sentry integration for capturing feature flags from LaunchDarkly.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import * as Sentry from '@sentry/browser';\n * import {launchDarklyIntegration, buildLaunchDarklyFlagUsedInspector} from '@sentry/browser';\n * import * as LaunchDarkly from 'launchdarkly-js-client-sdk';\n *\n * Sentry.init(..., integrations: [launchDarklyIntegration()])\n * const ldClient = LaunchDarkly.initialize(..., {inspectors: [buildLaunchDarklyFlagUsedHandler()]});\n * ```\n */\nexport const launchDarklyIntegration = defineIntegration(() => {\n  return {\n    name: 'LaunchDarkly',\n\n    processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n      return copyFlagsFromScopeToEvent(event);\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * LaunchDarkly hook that listens for flag evaluations and updates the `flags`\n * context in our Sentry scope. This needs to be registered as an\n * 'inspector' in LaunchDarkly initialize() options, separately from\n * `launchDarklyIntegration`. Both are needed to collect feature flags on error.\n */\nexport function buildLaunchDarklyFlagUsedHandler(): LDInspectionFlagUsedHandler {\n  return {\n    name: 'sentry-flag-auditor',\n    type: 'flag-used',\n\n    synchronous: true,\n\n    /**\n     * Handle a flag evaluation by storing its name and value on the current scope.\n     */\n    method: (flagKey: string, flagDetail: LDEvaluationDetail, _context: LDContext) => {\n      insertFlagToScope(flagKey, flagDetail.value);\n    },\n  };\n}\n", "/**\n * OpenFeature integration.\n *\n * Add the openFeatureIntegration() function call to your integration lists.\n * Add the integration hook to your OpenFeature object.\n *   - OpenFeature.getClient().addHooks(new OpenFeatureIntegrationHook());\n */\nimport type { Client, Event, EventHint, IntegrationFn } from '@sentry/core';\nimport type { EvaluationDetails, HookContext, HookHints, JsonValue, OpenFeatureHook } from './types';\n\nimport { defineIntegration } from '@sentry/core';\nimport { copyFlagsFromScopeToEvent, insertFlagToScope } from '../../../utils/featureFlags';\n\nexport const openFeatureIntegration = defineIntegration(() => {\n  return {\n    name: 'OpenFeature',\n\n    processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n      return copyFlagsFromScopeToEvent(event);\n    },\n  };\n}) satisfies IntegrationFn;\n\n/**\n * OpenFeature Hook class implementation.\n */\nexport class OpenFeatureIntegrationHook implements OpenFeatureHook {\n  /**\n   * Successful evaluation result.\n   */\n  public after(_hookContext: Readonly<HookContext<JsonValue>>, evaluationDetails: EvaluationDetails<JsonValue>): void {\n    insertFlagToScope(evaluationDetails.flagKey, evaluationDetails.value);\n  }\n\n  /**\n   * On error evaluation result.\n   */\n  public error(hookContext: Readonly<HookContext<JsonValue>>, _error: unknown, _hookHints?: HookHints): void {\n    insertFlagToScope(hookContext.flagKey, hookContext.defaultValue);\n  }\n}\n", "import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core';\n\nimport { defineIntegration, fill, logger } from '@sentry/core';\nimport { DEBUG_BUILD } from '../../../debug-build';\nimport { copyFlagsFromScopeToEvent, insertFlagToScope } from '../../../utils/featureFlags';\nimport type { UnleashClient, UnleashClientClass } from './types';\n\ntype UnleashIntegrationOptions = {\n  featureFlagClientClass?: UnleashClientClass;\n\n  /**\n   * @deprecated Use `featureFlagClientClass` instead.\n   */\n  unleashClientClass?: UnleashClientClass;\n};\n\n/**\n * Sentry integration for capturing feature flag evaluations from the Unleash SDK.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import { UnleashClient } from 'unleash-proxy-client';\n * import * as Sentry from '@sentry/browser';\n *\n * Sentry.init({\n *   dsn: '___PUBLIC_DSN___',\n *   integrations: [Sentry.unleashIntegration({featureFlagClientClass: UnleashClient})],\n * });\n *\n * const unleash = new UnleashClient(...);\n * unleash.start();\n *\n * unleash.isEnabled('my-feature');\n * Sentry.captureException(new Error('something went wrong'));\n * ```\n */\nexport const unleashIntegration = defineIntegration(\n  // eslint-disable-next-line deprecation/deprecation\n  ({ featureFlagClientClass, unleashClientClass }: UnleashIntegrationOptions) => {\n    const _unleashClientClass = featureFlagClientClass ? featureFlagClientClass : unleashClientClass;\n    if (!_unleashClientClass) {\n      throw new Error('featureFlagClientClass option is required');\n    }\n\n    return {\n      name: 'Unleash',\n\n      processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n        return copyFlagsFromScopeToEvent(event);\n      },\n\n      setupOnce() {\n        const unleashClientPrototype = _unleashClientClass.prototype as UnleashClient;\n        fill(unleashClientPrototype, 'isEnabled', _wrappedIsEnabled);\n      },\n    };\n  },\n) satisfies IntegrationFn;\n\n/**\n * Wraps the UnleashClient.isEnabled method to capture feature flag evaluations. Its only side effect is writing to Sentry scope.\n *\n * This wrapper is safe for all isEnabled signatures. If the signature does not match (this: UnleashClient, toggleName: string, ...args: unknown[]) => boolean,\n * we log an error and return the original result.\n *\n * @param original - The original method.\n * @returns Wrapped method. Results should match the original.\n */\nfunction _wrappedIsEnabled(\n  original: (this: UnleashClient, ...args: unknown[]) => unknown,\n): (this: UnleashClient, ...args: unknown[]) => unknown {\n  return function (this: UnleashClient, ...args: unknown[]): unknown {\n    const toggleName = args[0];\n    const result = original.apply(this, args);\n\n    if (typeof toggleName === 'string' && typeof result === 'boolean') {\n      insertFlagToScope(toggleName, result);\n    } else if (DEBUG_BUILD) {\n      logger.error(\n        `[Feature Flags] UnleashClient.isEnabled does not match expected signature. arg0: ${toggleName} (${typeof toggleName}), result: ${result} (${typeof result})`,\n      );\n    }\n    return result;\n  };\n}\n", "import type { Client, Event, EventHint, IntegrationFn } from '@sentry/core';\n\nimport { defineIntegration } from '@sentry/core';\nimport { copyFlagsFromScopeToEvent, insertFlagToScope } from '../../../utils/featureFlags';\nimport type { FeatureGate, StatsigClient } from './types';\n\n/**\n * Sentry integration for capturing feature flag evaluations from the Statsig js-client SDK.\n *\n * See the [feature flag documentation](https://develop.sentry.dev/sdk/expected-features/#feature-flags) for more information.\n *\n * @example\n * ```\n * import { StatsigClient } from '@statsig/js-client';\n * import * as Sentry from '@sentry/browser';\n *\n * const statsigClient = new StatsigClient();\n *\n * Sentry.init({\n *   dsn: '___PUBLIC_DSN___',\n *   integrations: [Sentry.statsigIntegration({featureFlagClient: statsigClient})],\n * });\n *\n * await statsigClient.initializeAsync();  // or statsigClient.initializeSync();\n *\n * const result = statsigClient.checkGate('my-feature-gate');\n * Sentry.captureException(new Error('something went wrong'));\n * ```\n */\nexport const statsigIntegration = defineIntegration(\n  ({ featureFlagClient: statsigClient }: { featureFlagClient: StatsigClient }) => {\n    return {\n      name: 'Statsig',\n\n      processEvent(event: Event, _hint: EventHint, _client: Client): Event {\n        return copyFlagsFromScopeToEvent(event);\n      },\n\n      setup() {\n        statsigClient.on('gate_evaluation', (event: { gate: FeatureGate }) => {\n          insertFlagToScope(event.gate.name, event.gate.value);\n        });\n      },\n    };\n  },\n) satisfies IntegrationFn;\n", "import * as Sentry from '@sentry/browser';\n\nexport default function initSentry (dsn) {\n  window.Sentry = Sentry;\n\n  Sentry.init({\n    dsn,\n    environment: window.$Gunfinder.env,\n    release: window.$Gunfinder.version,\n    integrations: [\n      // window.Sentry.captureConsoleIntegration(), // sends all console.log as a new event\n      window.Sentry.contextLinesIntegration(),\n      window.Sentry.extraErrorDataIntegration(),\n      window.Sentry.httpClientIntegration(),\n      // window.Sentry.replayIntegration(),\n    ],\n    sendDefaultPii: true, // window.Sentry.httpClientIntegration option\n    // https://docs.sentry.io/platforms/javascript/configuration/filtering/\n    // https://gist.github.com/impressiver/5092952\n    allowUrls: [\n      /https:\\/\\/((cdn|www)\\.)?gunfinder\\.(de|at|ch|com)/\n    ],\n    ignoreErrors: [\n      // Random plugins/extensions\n      'top.GLOBALS',\n      'translate.goo',\n      // See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error.html\n      'originalCreateNotification',\n      'canvas.contentDocument',\n      'MyApp_RemoveAllHighlights',\n      'jigsaw is not defined',\n      'ComboSearch is not defined',\n      'http://loading.retry.widdit.com/',\n      'atomicFindClose',\n      // Facebook borked\n      'fb_xd_fragment',\n      // ISP \"optimizing\" proxy - `Cache-Control: no-transform` seems to reduce this. (thanks @acdha)\n      // See http://stackoverflow.com/questions/4113268/how-to-stop-javascript-injection-from-vodafone-proxy\n      'bmi_SafeAddOnload',\n      'EBCallBackMessageReceived',\n      // See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx\n      'conduitPage',\n      // Generic error code from errors outside the security sandbox\n      // You can delete this if using raven.js > 1.0, which ignores these automatically.\n      'Script error.',\n      // Avast extension error\n      '_avast_submit'\n    ]\n  });\n}\n", "/*!\nTurbo 8.0.23\nCopyright \u00A9 2026 37signals LLC\n */\nconst FrameLoadingStyle = {\n  eager: \"eager\",\n  lazy: \"lazy\"\n};\n\n/**\n * Contains a fragment of HTML which is updated based on navigation within\n * it (e.g. via links or form submissions).\n *\n * @customElement turbo-frame\n * @example\n *   <turbo-frame id=\"messages\">\n *     <a href=\"/messages/expanded\">\n *       Show all expanded messages in this frame.\n *     </a>\n *\n *     <form action=\"/messages\">\n *       Show response from this form within this frame.\n *     </form>\n *   </turbo-frame>\n */\nclass FrameElement extends HTMLElement {\n  static delegateConstructor = undefined\n\n  loaded = Promise.resolve()\n\n  static get observedAttributes() {\n    return [\"disabled\", \"loading\", \"src\"]\n  }\n\n  constructor() {\n    super();\n    this.delegate = new FrameElement.delegateConstructor(this);\n  }\n\n  connectedCallback() {\n    this.delegate.connect();\n  }\n\n  disconnectedCallback() {\n    this.delegate.disconnect();\n  }\n\n  reload() {\n    return this.delegate.sourceURLReloaded()\n  }\n\n  attributeChangedCallback(name) {\n    if (name == \"loading\") {\n      this.delegate.loadingStyleChanged();\n    } else if (name == \"src\") {\n      this.delegate.sourceURLChanged();\n    } else if (name == \"disabled\") {\n      this.delegate.disabledChanged();\n    }\n  }\n\n  /**\n   * Gets the URL to lazily load source HTML from\n   */\n  get src() {\n    return this.getAttribute(\"src\")\n  }\n\n  /**\n   * Sets the URL to lazily load source HTML from\n   */\n  set src(value) {\n    if (value) {\n      this.setAttribute(\"src\", value);\n    } else {\n      this.removeAttribute(\"src\");\n    }\n  }\n\n  /**\n   * Gets the refresh mode for the frame.\n   */\n  get refresh() {\n    return this.getAttribute(\"refresh\")\n  }\n\n  /**\n   * Sets the refresh mode for the frame.\n   */\n  set refresh(value) {\n    if (value) {\n      this.setAttribute(\"refresh\", value);\n    } else {\n      this.removeAttribute(\"refresh\");\n    }\n  }\n\n  get shouldReloadWithMorph() {\n    return this.src && this.refresh === \"morph\"\n  }\n\n  /**\n   * Determines if the element is loading\n   */\n  get loading() {\n    return frameLoadingStyleFromString(this.getAttribute(\"loading\") || \"\")\n  }\n\n  /**\n   * Sets the value of if the element is loading\n   */\n  set loading(value) {\n    if (value) {\n      this.setAttribute(\"loading\", value);\n    } else {\n      this.removeAttribute(\"loading\");\n    }\n  }\n\n  /**\n   * Gets the disabled state of the frame.\n   *\n   * If disabled, no requests will be intercepted by the frame.\n   */\n  get disabled() {\n    return this.hasAttribute(\"disabled\")\n  }\n\n  /**\n   * Sets the disabled state of the frame.\n   *\n   * If disabled, no requests will be intercepted by the frame.\n   */\n  set disabled(value) {\n    if (value) {\n      this.setAttribute(\"disabled\", \"\");\n    } else {\n      this.removeAttribute(\"disabled\");\n    }\n  }\n\n  /**\n   * Gets the autoscroll state of the frame.\n   *\n   * If true, the frame will be scrolled into view automatically on update.\n   */\n  get autoscroll() {\n    return this.hasAttribute(\"autoscroll\")\n  }\n\n  /**\n   * Sets the autoscroll state of the frame.\n   *\n   * If true, the frame will be scrolled into view automatically on update.\n   */\n  set autoscroll(value) {\n    if (value) {\n      this.setAttribute(\"autoscroll\", \"\");\n    } else {\n      this.removeAttribute(\"autoscroll\");\n    }\n  }\n\n  /**\n   * Determines if the element has finished loading\n   */\n  get complete() {\n    return !this.delegate.isLoading\n  }\n\n  /**\n   * Gets the active state of the frame.\n   *\n   * If inactive, source changes will not be observed.\n   */\n  get isActive() {\n    return this.ownerDocument === document && !this.isPreview\n  }\n\n  /**\n   * Sets the active state of the frame.\n   *\n   * If inactive, source changes will not be observed.\n   */\n  get isPreview() {\n    return this.ownerDocument?.documentElement?.hasAttribute(\"data-turbo-preview\")\n  }\n}\n\nfunction frameLoadingStyleFromString(style) {\n  switch (style.toLowerCase()) {\n    case \"lazy\":\n      return FrameLoadingStyle.lazy\n    default:\n      return FrameLoadingStyle.eager\n  }\n}\n\nconst drive = {\n  enabled: true,\n  progressBarDelay: 500,\n  unvisitableExtensions: new Set(\n    [\n      \".7z\", \".aac\", \".apk\", \".avi\", \".bmp\", \".bz2\", \".css\", \".csv\", \".deb\", \".dmg\", \".doc\",\n      \".docx\", \".exe\", \".gif\", \".gz\", \".heic\", \".heif\", \".ico\", \".iso\", \".jpeg\", \".jpg\",\n      \".js\", \".json\", \".m4a\", \".mkv\", \".mov\", \".mp3\", \".mp4\", \".mpeg\", \".mpg\", \".msi\",\n      \".ogg\", \".ogv\", \".pdf\", \".pkg\", \".png\", \".ppt\", \".pptx\", \".rar\", \".rtf\",\n      \".svg\", \".tar\", \".tif\", \".tiff\", \".txt\", \".wav\", \".webm\", \".webp\", \".wma\", \".wmv\",\n      \".xls\", \".xlsx\", \".xml\", \".zip\"\n    ]\n  )\n};\n\nfunction activateScriptElement(element) {\n  if (element.getAttribute(\"data-turbo-eval\") == \"false\") {\n    return element\n  } else {\n    const createdScriptElement = document.createElement(\"script\");\n    const cspNonce = getCspNonce();\n    if (cspNonce) {\n      createdScriptElement.nonce = cspNonce;\n    }\n    createdScriptElement.textContent = element.textContent;\n    createdScriptElement.async = false;\n    copyElementAttributes(createdScriptElement, element);\n    return createdScriptElement\n  }\n}\n\nfunction copyElementAttributes(destinationElement, sourceElement) {\n  for (const { name, value } of sourceElement.attributes) {\n    destinationElement.setAttribute(name, value);\n  }\n}\n\nfunction createDocumentFragment(html) {\n  const template = document.createElement(\"template\");\n  template.innerHTML = html;\n  return template.content\n}\n\nfunction dispatch(eventName, { target, cancelable, detail } = {}) {\n  const event = new CustomEvent(eventName, {\n    cancelable,\n    bubbles: true,\n    composed: true,\n    detail\n  });\n\n  if (target && target.isConnected) {\n    target.dispatchEvent(event);\n  } else {\n    document.documentElement.dispatchEvent(event);\n  }\n\n  return event\n}\n\nfunction cancelEvent(event) {\n  event.preventDefault();\n  event.stopImmediatePropagation();\n}\n\nfunction nextRepaint() {\n  if (document.visibilityState === \"hidden\") {\n    return nextEventLoopTick()\n  } else {\n    return nextAnimationFrame()\n  }\n}\n\nfunction nextAnimationFrame() {\n  return new Promise((resolve) => requestAnimationFrame(() => resolve()))\n}\n\nfunction nextEventLoopTick() {\n  return new Promise((resolve) => setTimeout(() => resolve(), 0))\n}\n\nfunction parseHTMLDocument(html = \"\") {\n  return new DOMParser().parseFromString(html, \"text/html\")\n}\n\nfunction unindent(strings, ...values) {\n  const lines = interpolate(strings, values).replace(/^\\n/, \"\").split(\"\\n\");\n  const match = lines[0].match(/^\\s+/);\n  const indent = match ? match[0].length : 0;\n  return lines.map((line) => line.slice(indent)).join(\"\\n\")\n}\n\nfunction interpolate(strings, values) {\n  return strings.reduce((result, string, i) => {\n    const value = values[i] == undefined ? \"\" : values[i];\n    return result + string + value\n  }, \"\")\n}\n\nfunction uuid() {\n  return Array.from({ length: 36 })\n    .map((_, i) => {\n      if (i == 8 || i == 13 || i == 18 || i == 23) {\n        return \"-\"\n      } else if (i == 14) {\n        return \"4\"\n      } else if (i == 19) {\n        return (Math.floor(Math.random() * 4) + 8).toString(16)\n      } else {\n        return Math.floor(Math.random() * 16).toString(16)\n      }\n    })\n    .join(\"\")\n}\n\nfunction getAttribute(attributeName, ...elements) {\n  for (const value of elements.map((element) => element?.getAttribute(attributeName))) {\n    if (typeof value == \"string\") return value\n  }\n\n  return null\n}\n\nfunction hasAttribute(attributeName, ...elements) {\n  return elements.some((element) => element && element.hasAttribute(attributeName))\n}\n\nfunction markAsBusy(...elements) {\n  for (const element of elements) {\n    if (element.localName == \"turbo-frame\") {\n      element.setAttribute(\"busy\", \"\");\n    }\n    element.setAttribute(\"aria-busy\", \"true\");\n  }\n}\n\nfunction clearBusyState(...elements) {\n  for (const element of elements) {\n    if (element.localName == \"turbo-frame\") {\n      element.removeAttribute(\"busy\");\n    }\n\n    element.removeAttribute(\"aria-busy\");\n  }\n}\n\nfunction waitForLoad(element, timeoutInMilliseconds = 2000) {\n  return new Promise((resolve) => {\n    const onComplete = () => {\n      element.removeEventListener(\"error\", onComplete);\n      element.removeEventListener(\"load\", onComplete);\n      resolve();\n    };\n\n    element.addEventListener(\"load\", onComplete, { once: true });\n    element.addEventListener(\"error\", onComplete, { once: true });\n    setTimeout(resolve, timeoutInMilliseconds);\n  })\n}\n\nfunction getHistoryMethodForAction(action) {\n  switch (action) {\n    case \"replace\":\n      return history.replaceState\n    case \"advance\":\n    case \"restore\":\n      return history.pushState\n  }\n}\n\nfunction isAction(action) {\n  return action == \"advance\" || action == \"replace\" || action == \"restore\"\n}\n\nfunction getVisitAction(...elements) {\n  const action = getAttribute(\"data-turbo-action\", ...elements);\n\n  return isAction(action) ? action : null\n}\n\nfunction getMetaElement(name) {\n  return document.querySelector(`meta[name=\"${name}\"]`)\n}\n\nfunction getMetaContent(name) {\n  const element = getMetaElement(name);\n  return element && element.content\n}\n\nfunction getCspNonce() {\n  const element = getMetaElement(\"csp-nonce\");\n\n  if (element) {\n    const { nonce, content } = element;\n    return nonce == \"\" ? content : nonce\n  }\n}\n\nfunction setMetaContent(name, content) {\n  let element = getMetaElement(name);\n\n  if (!element) {\n    element = document.createElement(\"meta\");\n    element.setAttribute(\"name\", name);\n\n    document.head.appendChild(element);\n  }\n\n  element.setAttribute(\"content\", content);\n\n  return element\n}\n\nfunction findClosestRecursively(element, selector) {\n  if (element instanceof Element) {\n    return (\n      element.closest(selector) || findClosestRecursively(element.assignedSlot || element.getRootNode()?.host, selector)\n    )\n  }\n}\n\nfunction elementIsFocusable(element) {\n  const inertDisabledOrHidden = \"[inert], :disabled, [hidden], details:not([open]), dialog:not([open])\";\n\n  return !!element && element.closest(inertDisabledOrHidden) == null && typeof element.focus == \"function\"\n}\n\nfunction queryAutofocusableElement(elementOrDocumentFragment) {\n  return Array.from(elementOrDocumentFragment.querySelectorAll(\"[autofocus]\")).find(elementIsFocusable)\n}\n\nasync function around(callback, reader) {\n  const before = reader();\n\n  callback();\n\n  await nextAnimationFrame();\n\n  const after = reader();\n\n  return [before, after]\n}\n\nfunction doesNotTargetIFrame(name) {\n  if (name === \"_blank\") {\n    return false\n  } else if (name) {\n    for (const element of document.getElementsByName(name)) {\n      if (element instanceof HTMLIFrameElement) return false\n    }\n\n    return true\n  } else {\n    return true\n  }\n}\n\nfunction findLinkFromClickTarget(target) {\n  const link = findClosestRecursively(target, \"a[href], a[xlink\\\\:href]\");\n\n  if (!link) return null\n  if (link.href.startsWith(\"#\")) return null\n  if (link.hasAttribute(\"download\")) return null\n\n  const linkTarget = link.getAttribute(\"target\");\n  if (linkTarget && linkTarget !== \"_self\") return null\n\n  return link\n}\n\nfunction debounce(fn, delay) {\n  let timeoutId = null;\n\n  return (...args) => {\n    const callback = () => fn.apply(this, args);\n    clearTimeout(timeoutId);\n    timeoutId = setTimeout(callback, delay);\n  }\n}\n\nconst submitter = {\n  \"aria-disabled\": {\n    beforeSubmit: submitter => {\n      submitter.setAttribute(\"aria-disabled\", \"true\");\n      submitter.addEventListener(\"click\", cancelEvent);\n    },\n\n    afterSubmit: submitter => {\n      submitter.removeAttribute(\"aria-disabled\");\n      submitter.removeEventListener(\"click\", cancelEvent);\n    }\n  },\n\n  \"disabled\": {\n    beforeSubmit: submitter => submitter.disabled = true,\n    afterSubmit: submitter => submitter.disabled = false\n  }\n};\n\nclass Config {\n  #submitter = null\n\n  constructor(config) {\n    Object.assign(this, config);\n  }\n\n  get submitter() {\n    return this.#submitter\n  }\n\n  set submitter(value) {\n    this.#submitter = submitter[value] || value;\n  }\n}\n\nconst forms = new Config({\n  mode: \"on\",\n  submitter: \"disabled\"\n});\n\nconst config = {\n  drive,\n  forms\n};\n\nfunction expandURL(locatable) {\n  return new URL(locatable.toString(), document.baseURI)\n}\n\nfunction getAnchor(url) {\n  let anchorMatch;\n  if (url.hash) {\n    return url.hash.slice(1)\n    // eslint-disable-next-line no-cond-assign\n  } else if ((anchorMatch = url.href.match(/#(.*)$/))) {\n    return anchorMatch[1]\n  }\n}\n\nfunction getAction$1(form, submitter) {\n  const action = submitter?.getAttribute(\"formaction\") || form.getAttribute(\"action\") || form.action;\n\n  return expandURL(action)\n}\n\nfunction getExtension(url) {\n  return (getLastPathComponent(url).match(/\\.[^.]*$/) || [])[0] || \"\"\n}\n\nfunction isPrefixedBy(baseURL, url) {\n  const prefix = addTrailingSlash(url.origin + url.pathname);\n  return addTrailingSlash(baseURL.href) === prefix || baseURL.href.startsWith(prefix)\n}\n\nfunction locationIsVisitable(location, rootLocation) {\n  return isPrefixedBy(location, rootLocation) && !config.drive.unvisitableExtensions.has(getExtension(location))\n}\n\nfunction getLocationForLink(link) {\n  return expandURL(link.getAttribute(\"href\") || \"\")\n}\n\nfunction getRequestURL(url) {\n  const anchor = getAnchor(url);\n  return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href\n}\n\nfunction toCacheKey(url) {\n  return getRequestURL(url)\n}\n\nfunction urlsAreEqual(left, right) {\n  return expandURL(left).href == expandURL(right).href\n}\n\nfunction getPathComponents(url) {\n  return url.pathname.split(\"/\").slice(1)\n}\n\nfunction getLastPathComponent(url) {\n  return getPathComponents(url).slice(-1)[0]\n}\n\nfunction addTrailingSlash(value) {\n  return value.endsWith(\"/\") ? value : value + \"/\"\n}\n\nclass FetchResponse {\n  constructor(response) {\n    this.response = response;\n  }\n\n  get succeeded() {\n    return this.response.ok\n  }\n\n  get failed() {\n    return !this.succeeded\n  }\n\n  get clientError() {\n    return this.statusCode >= 400 && this.statusCode <= 499\n  }\n\n  get serverError() {\n    return this.statusCode >= 500 && this.statusCode <= 599\n  }\n\n  get redirected() {\n    return this.response.redirected\n  }\n\n  get location() {\n    return expandURL(this.response.url)\n  }\n\n  get isHTML() {\n    return this.contentType && this.contentType.match(/^(?:text\\/([^\\s;,]+\\b)?html|application\\/xhtml\\+xml)\\b/)\n  }\n\n  get statusCode() {\n    return this.response.status\n  }\n\n  get contentType() {\n    return this.header(\"Content-Type\")\n  }\n\n  get responseText() {\n    return this.response.clone().text()\n  }\n\n  get responseHTML() {\n    if (this.isHTML) {\n      return this.response.clone().text()\n    } else {\n      return Promise.resolve(undefined)\n    }\n  }\n\n  header(name) {\n    return this.response.headers.get(name)\n  }\n}\n\nclass LimitedSet extends Set {\n  constructor(maxSize) {\n    super();\n    this.maxSize = maxSize;\n  }\n\n  add(value) {\n    if (this.size >= this.maxSize) {\n      const iterator = this.values();\n      const oldestValue = iterator.next().value;\n      this.delete(oldestValue);\n    }\n    super.add(value);\n  }\n}\n\nconst recentRequests = new LimitedSet(20);\n\nfunction fetchWithTurboHeaders(url, options = {}) {\n  const modifiedHeaders = new Headers(options.headers || {});\n  const requestUID = uuid();\n  recentRequests.add(requestUID);\n  modifiedHeaders.append(\"X-Turbo-Request-Id\", requestUID);\n\n  return window.fetch(url, {\n    ...options,\n    headers: modifiedHeaders\n  })\n}\n\nfunction fetchMethodFromString(method) {\n  switch (method.toLowerCase()) {\n    case \"get\":\n      return FetchMethod.get\n    case \"post\":\n      return FetchMethod.post\n    case \"put\":\n      return FetchMethod.put\n    case \"patch\":\n      return FetchMethod.patch\n    case \"delete\":\n      return FetchMethod.delete\n  }\n}\n\nconst FetchMethod = {\n  get: \"get\",\n  post: \"post\",\n  put: \"put\",\n  patch: \"patch\",\n  delete: \"delete\"\n};\n\nfunction fetchEnctypeFromString(encoding) {\n  switch (encoding.toLowerCase()) {\n    case FetchEnctype.multipart:\n      return FetchEnctype.multipart\n    case FetchEnctype.plain:\n      return FetchEnctype.plain\n    default:\n      return FetchEnctype.urlEncoded\n  }\n}\n\nconst FetchEnctype = {\n  urlEncoded: \"application/x-www-form-urlencoded\",\n  multipart: \"multipart/form-data\",\n  plain: \"text/plain\"\n};\n\nclass FetchRequest {\n  abortController = new AbortController()\n  #resolveRequestPromise = (_value) => {}\n\n  constructor(delegate, method, location, requestBody = new URLSearchParams(), target = null, enctype = FetchEnctype.urlEncoded) {\n    const [url, body] = buildResourceAndBody(expandURL(location), method, requestBody, enctype);\n\n    this.delegate = delegate;\n    this.url = url;\n    this.target = target;\n    this.fetchOptions = {\n      credentials: \"same-origin\",\n      redirect: \"follow\",\n      method: method.toUpperCase(),\n      headers: { ...this.defaultHeaders },\n      body: body,\n      signal: this.abortSignal,\n      referrer: this.delegate.referrer?.href\n    };\n    this.enctype = enctype;\n  }\n\n  get method() {\n    return this.fetchOptions.method\n  }\n\n  set method(value) {\n    const fetchBody = this.isSafe ? this.url.searchParams : this.fetchOptions.body || new FormData();\n    const fetchMethod = fetchMethodFromString(value) || FetchMethod.get;\n\n    this.url.search = \"\";\n\n    const [url, body] = buildResourceAndBody(this.url, fetchMethod, fetchBody, this.enctype);\n\n    this.url = url;\n    this.fetchOptions.body = body;\n    this.fetchOptions.method = fetchMethod.toUpperCase();\n  }\n\n  get headers() {\n    return this.fetchOptions.headers\n  }\n\n  set headers(value) {\n    this.fetchOptions.headers = value;\n  }\n\n  get body() {\n    if (this.isSafe) {\n      return this.url.searchParams\n    } else {\n      return this.fetchOptions.body\n    }\n  }\n\n  set body(value) {\n    this.fetchOptions.body = value;\n  }\n\n  get location() {\n    return this.url\n  }\n\n  get params() {\n    return this.url.searchParams\n  }\n\n  get entries() {\n    return this.body ? Array.from(this.body.entries()) : []\n  }\n\n  cancel() {\n    this.abortController.abort();\n  }\n\n  async perform() {\n    const { fetchOptions } = this;\n    this.delegate.prepareRequest(this);\n    const event = await this.#allowRequestToBeIntercepted(fetchOptions);\n    try {\n      this.delegate.requestStarted(this);\n\n      if (event.detail.fetchRequest) {\n        this.response = event.detail.fetchRequest.response;\n      } else {\n        this.response = fetchWithTurboHeaders(this.url.href, fetchOptions);\n      }\n\n      const response = await this.response;\n      return await this.receive(response)\n    } catch (error) {\n      if (error.name !== \"AbortError\") {\n        if (this.#willDelegateErrorHandling(error)) {\n          this.delegate.requestErrored(this, error);\n        }\n        throw error\n      }\n    } finally {\n      this.delegate.requestFinished(this);\n    }\n  }\n\n  async receive(response) {\n    const fetchResponse = new FetchResponse(response);\n    const event = dispatch(\"turbo:before-fetch-response\", {\n      cancelable: true,\n      detail: { fetchResponse },\n      target: this.target\n    });\n    if (event.defaultPrevented) {\n      this.delegate.requestPreventedHandlingResponse(this, fetchResponse);\n    } else if (fetchResponse.succeeded) {\n      this.delegate.requestSucceededWithResponse(this, fetchResponse);\n    } else {\n      this.delegate.requestFailedWithResponse(this, fetchResponse);\n    }\n    return fetchResponse\n  }\n\n  get defaultHeaders() {\n    return {\n      Accept: \"text/html, application/xhtml+xml\"\n    }\n  }\n\n  get isSafe() {\n    return isSafe(this.method)\n  }\n\n  get abortSignal() {\n    return this.abortController.signal\n  }\n\n  acceptResponseType(mimeType) {\n    this.headers[\"Accept\"] = [mimeType, this.headers[\"Accept\"]].join(\", \");\n  }\n\n  async #allowRequestToBeIntercepted(fetchOptions) {\n    const requestInterception = new Promise((resolve) => (this.#resolveRequestPromise = resolve));\n    const event = dispatch(\"turbo:before-fetch-request\", {\n      cancelable: true,\n      detail: {\n        fetchOptions,\n        url: this.url,\n        resume: this.#resolveRequestPromise\n      },\n      target: this.target\n    });\n    this.url = event.detail.url;\n    if (event.defaultPrevented) await requestInterception;\n\n    return event\n  }\n\n  #willDelegateErrorHandling(error) {\n    const event = dispatch(\"turbo:fetch-request-error\", {\n      target: this.target,\n      cancelable: true,\n      detail: { request: this, error: error }\n    });\n\n    return !event.defaultPrevented\n  }\n}\n\nfunction isSafe(fetchMethod) {\n  return fetchMethodFromString(fetchMethod) == FetchMethod.get\n}\n\nfunction buildResourceAndBody(resource, method, requestBody, enctype) {\n  const searchParams =\n    Array.from(requestBody).length > 0 ? new URLSearchParams(entriesExcludingFiles(requestBody)) : resource.searchParams;\n\n  if (isSafe(method)) {\n    return [mergeIntoURLSearchParams(resource, searchParams), null]\n  } else if (enctype == FetchEnctype.urlEncoded) {\n    return [resource, searchParams]\n  } else {\n    return [resource, requestBody]\n  }\n}\n\nfunction entriesExcludingFiles(requestBody) {\n  const entries = [];\n\n  for (const [name, value] of requestBody) {\n    if (value instanceof File) continue\n    else entries.push([name, value]);\n  }\n\n  return entries\n}\n\nfunction mergeIntoURLSearchParams(url, requestBody) {\n  const searchParams = new URLSearchParams(entriesExcludingFiles(requestBody));\n\n  url.search = searchParams.toString();\n\n  return url\n}\n\nclass AppearanceObserver {\n  started = false\n\n  constructor(delegate, element) {\n    this.delegate = delegate;\n    this.element = element;\n    this.intersectionObserver = new IntersectionObserver(this.intersect);\n  }\n\n  start() {\n    if (!this.started) {\n      this.started = true;\n      this.intersectionObserver.observe(this.element);\n    }\n  }\n\n  stop() {\n    if (this.started) {\n      this.started = false;\n      this.intersectionObserver.unobserve(this.element);\n    }\n  }\n\n  intersect = (entries) => {\n    const lastEntry = entries.slice(-1)[0];\n    if (lastEntry?.isIntersecting) {\n      this.delegate.elementAppearedInViewport(this.element);\n    }\n  }\n}\n\nclass StreamMessage {\n  static contentType = \"text/vnd.turbo-stream.html\"\n\n  static wrap(message) {\n    if (typeof message == \"string\") {\n      return new this(createDocumentFragment(message))\n    } else {\n      return message\n    }\n  }\n\n  constructor(fragment) {\n    this.fragment = importStreamElements(fragment);\n  }\n}\n\nfunction importStreamElements(fragment) {\n  for (const element of fragment.querySelectorAll(\"turbo-stream\")) {\n    const streamElement = document.importNode(element, true);\n\n    for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll(\"script\")) {\n      inertScriptElement.replaceWith(activateScriptElement(inertScriptElement));\n    }\n\n    element.replaceWith(streamElement);\n  }\n\n  return fragment\n}\n\nconst identity = key => key;\n\nclass LRUCache {\n  keys = []\n  entries = {}\n  #toCacheKey\n\n  constructor(size, toCacheKey = identity) {\n    this.size = size;\n    this.#toCacheKey = toCacheKey;\n  }\n\n  has(key) {\n    return this.#toCacheKey(key) in this.entries\n  }\n\n  get(key) {\n    if (this.has(key)) {\n      const entry = this.read(key);\n      this.touch(key);\n      return entry\n    }\n  }\n\n  put(key, entry) {\n    this.write(key, entry);\n    this.touch(key);\n    return entry\n  }\n\n  clear() {\n    for (const key of Object.keys(this.entries)) {\n      this.evict(key);\n    }\n  }\n\n  // Private\n\n  read(key) {\n    return this.entries[this.#toCacheKey(key)]\n  }\n\n  write(key, entry) {\n    this.entries[this.#toCacheKey(key)] = entry;\n  }\n\n  touch(key) {\n    key = this.#toCacheKey(key);\n    const index = this.keys.indexOf(key);\n    if (index > -1) this.keys.splice(index, 1);\n    this.keys.unshift(key);\n    this.trim();\n  }\n\n  trim() {\n    for (const key of this.keys.splice(this.size)) {\n      this.evict(key);\n    }\n  }\n\n  evict(key) {\n    delete this.entries[key];\n  }\n}\n\nconst PREFETCH_DELAY = 100;\n\nclass PrefetchCache extends LRUCache {\n  #prefetchTimeout = null\n  #maxAges = {}\n\n  constructor(size = 1, prefetchDelay = PREFETCH_DELAY) {\n    super(size, toCacheKey);\n    this.prefetchDelay = prefetchDelay;\n  }\n\n  putLater(url, request, ttl) {\n    this.#prefetchTimeout = setTimeout(() => {\n      request.perform();\n      this.put(url, request, ttl);\n      this.#prefetchTimeout = null;\n    }, this.prefetchDelay);\n  }\n\n  put(url, request, ttl = cacheTtl) {\n    super.put(url, request);\n    this.#maxAges[toCacheKey(url)] = new Date(new Date().getTime() + ttl);\n  }\n\n  clear() {\n    super.clear();\n    if (this.#prefetchTimeout) clearTimeout(this.#prefetchTimeout);\n  }\n\n  evict(key) {\n    super.evict(key);\n    delete this.#maxAges[key];\n  }\n\n  has(key) {\n    if (super.has(key)) {\n      const maxAge = this.#maxAges[toCacheKey(key)];\n\n      return maxAge && maxAge > Date.now()\n    } else {\n      return false\n    }\n  }\n}\n\nconst cacheTtl = 10 * 1000;\nconst prefetchCache = new PrefetchCache();\n\nconst FormSubmissionState = {\n  initialized: \"initialized\",\n  requesting: \"requesting\",\n  waiting: \"waiting\",\n  receiving: \"receiving\",\n  stopping: \"stopping\",\n  stopped: \"stopped\"\n};\n\nclass FormSubmission {\n  state = FormSubmissionState.initialized\n\n  static confirmMethod(message) {\n    return Promise.resolve(confirm(message))\n  }\n\n  constructor(delegate, formElement, submitter, mustRedirect = false) {\n    const method = getMethod(formElement, submitter);\n    const action = getAction(getFormAction(formElement, submitter), method);\n    const body = buildFormData(formElement, submitter);\n    const enctype = getEnctype(formElement, submitter);\n\n    this.delegate = delegate;\n    this.formElement = formElement;\n    this.submitter = submitter;\n    this.fetchRequest = new FetchRequest(this, method, action, body, formElement, enctype);\n    this.mustRedirect = mustRedirect;\n  }\n\n  get method() {\n    return this.fetchRequest.method\n  }\n\n  set method(value) {\n    this.fetchRequest.method = value;\n  }\n\n  get action() {\n    return this.fetchRequest.url.toString()\n  }\n\n  set action(value) {\n    this.fetchRequest.url = expandURL(value);\n  }\n\n  get body() {\n    return this.fetchRequest.body\n  }\n\n  get enctype() {\n    return this.fetchRequest.enctype\n  }\n\n  get isSafe() {\n    return this.fetchRequest.isSafe\n  }\n\n  get location() {\n    return this.fetchRequest.url\n  }\n\n  // The submission process\n\n  async start() {\n    const { initialized, requesting } = FormSubmissionState;\n    const confirmationMessage = getAttribute(\"data-turbo-confirm\", this.submitter, this.formElement);\n\n    if (typeof confirmationMessage === \"string\") {\n      const confirmMethod = typeof config.forms.confirm === \"function\" ?\n        config.forms.confirm :\n        FormSubmission.confirmMethod;\n\n      const answer = await confirmMethod(confirmationMessage, this.formElement, this.submitter);\n      if (!answer) {\n        return\n      }\n    }\n\n    if (this.state == initialized) {\n      this.state = requesting;\n      return this.fetchRequest.perform()\n    }\n  }\n\n  stop() {\n    const { stopping, stopped } = FormSubmissionState;\n    if (this.state != stopping && this.state != stopped) {\n      this.state = stopping;\n      this.fetchRequest.cancel();\n      return true\n    }\n  }\n\n  // Fetch request delegate\n\n  prepareRequest(request) {\n    if (!request.isSafe) {\n      const token = getCookieValue(getMetaContent(\"csrf-param\")) || getMetaContent(\"csrf-token\");\n      if (token) {\n        request.headers[\"X-CSRF-Token\"] = token;\n      }\n    }\n\n    if (this.requestAcceptsTurboStreamResponse(request)) {\n      request.acceptResponseType(StreamMessage.contentType);\n    }\n  }\n\n  requestStarted(_request) {\n    this.state = FormSubmissionState.waiting;\n    if (this.submitter) config.forms.submitter.beforeSubmit(this.submitter);\n    this.setSubmitsWith();\n    markAsBusy(this.formElement);\n    dispatch(\"turbo:submit-start\", {\n      target: this.formElement,\n      detail: { formSubmission: this }\n    });\n    this.delegate.formSubmissionStarted(this);\n  }\n\n  requestPreventedHandlingResponse(request, response) {\n    prefetchCache.clear();\n\n    this.result = { success: response.succeeded, fetchResponse: response };\n  }\n\n  requestSucceededWithResponse(request, response) {\n    if (response.clientError || response.serverError) {\n      this.delegate.formSubmissionFailedWithResponse(this, response);\n      return\n    }\n\n    prefetchCache.clear();\n\n    if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) {\n      const error = new Error(\"Form responses must redirect to another location\");\n      this.delegate.formSubmissionErrored(this, error);\n    } else {\n      this.state = FormSubmissionState.receiving;\n      this.result = { success: true, fetchResponse: response };\n      this.delegate.formSubmissionSucceededWithResponse(this, response);\n    }\n  }\n\n  requestFailedWithResponse(request, response) {\n    this.result = { success: false, fetchResponse: response };\n    this.delegate.formSubmissionFailedWithResponse(this, response);\n  }\n\n  requestErrored(request, error) {\n    this.result = { success: false, error };\n    this.delegate.formSubmissionErrored(this, error);\n  }\n\n  requestFinished(_request) {\n    this.state = FormSubmissionState.stopped;\n    if (this.submitter) config.forms.submitter.afterSubmit(this.submitter);\n    this.resetSubmitterText();\n    clearBusyState(this.formElement);\n    dispatch(\"turbo:submit-end\", {\n      target: this.formElement,\n      detail: { formSubmission: this, ...this.result }\n    });\n    this.delegate.formSubmissionFinished(this);\n  }\n\n  // Private\n\n  setSubmitsWith() {\n    if (!this.submitter || !this.submitsWith) return\n\n    if (this.submitter.matches(\"button\")) {\n      this.originalSubmitText = this.submitter.innerHTML;\n      this.submitter.innerHTML = this.submitsWith;\n    } else if (this.submitter.matches(\"input\")) {\n      const input = this.submitter;\n      this.originalSubmitText = input.value;\n      input.value = this.submitsWith;\n    }\n  }\n\n  resetSubmitterText() {\n    if (!this.submitter || !this.originalSubmitText) return\n\n    if (this.submitter.matches(\"button\")) {\n      this.submitter.innerHTML = this.originalSubmitText;\n    } else if (this.submitter.matches(\"input\")) {\n      const input = this.submitter;\n      input.value = this.originalSubmitText;\n    }\n  }\n\n  requestMustRedirect(request) {\n    return !request.isSafe && this.mustRedirect\n  }\n\n  requestAcceptsTurboStreamResponse(request) {\n    return !request.isSafe || hasAttribute(\"data-turbo-stream\", this.submitter, this.formElement)\n  }\n\n  get submitsWith() {\n    return this.submitter?.getAttribute(\"data-turbo-submits-with\")\n  }\n}\n\nfunction buildFormData(formElement, submitter) {\n  const formData = new FormData(formElement);\n  const name = submitter?.getAttribute(\"name\");\n  const value = submitter?.getAttribute(\"value\");\n\n  if (name) {\n    formData.append(name, value || \"\");\n  }\n\n  return formData\n}\n\nfunction getCookieValue(cookieName) {\n  if (cookieName != null) {\n    const cookies = document.cookie ? document.cookie.split(\"; \") : [];\n    const cookie = cookies.find((cookie) => cookie.startsWith(cookieName));\n    if (cookie) {\n      const value = cookie.split(\"=\").slice(1).join(\"=\");\n      return value ? decodeURIComponent(value) : undefined\n    }\n  }\n}\n\nfunction responseSucceededWithoutRedirect(response) {\n  return response.statusCode == 200 && !response.redirected\n}\n\nfunction getFormAction(formElement, submitter) {\n  const formElementAction = typeof formElement.action === \"string\" ? formElement.action : null;\n\n  if (submitter?.hasAttribute(\"formaction\")) {\n    return submitter.getAttribute(\"formaction\") || \"\"\n  } else {\n    return formElement.getAttribute(\"action\") || formElementAction || \"\"\n  }\n}\n\nfunction getAction(formAction, fetchMethod) {\n  const action = expandURL(formAction);\n\n  if (isSafe(fetchMethod)) {\n    action.search = \"\";\n  }\n\n  return action\n}\n\nfunction getMethod(formElement, submitter) {\n  const method = submitter?.getAttribute(\"formmethod\") || formElement.getAttribute(\"method\") || \"\";\n  return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get\n}\n\nfunction getEnctype(formElement, submitter) {\n  return fetchEnctypeFromString(submitter?.getAttribute(\"formenctype\") || formElement.enctype)\n}\n\nclass Snapshot {\n  constructor(element) {\n    this.element = element;\n  }\n\n  get activeElement() {\n    return this.element.ownerDocument.activeElement\n  }\n\n  get children() {\n    return [...this.element.children]\n  }\n\n  hasAnchor(anchor) {\n    return this.getElementForAnchor(anchor) != null\n  }\n\n  getElementForAnchor(anchor) {\n    return anchor ? this.element.querySelector(`[id='${anchor}'], a[name='${anchor}']`) : null\n  }\n\n  get isConnected() {\n    return this.element.isConnected\n  }\n\n  get firstAutofocusableElement() {\n    return queryAutofocusableElement(this.element)\n  }\n\n  get permanentElements() {\n    return queryPermanentElementsAll(this.element)\n  }\n\n  getPermanentElementById(id) {\n    return getPermanentElementById(this.element, id)\n  }\n\n  getPermanentElementMapForSnapshot(snapshot) {\n    const permanentElementMap = {};\n\n    for (const currentPermanentElement of this.permanentElements) {\n      const { id } = currentPermanentElement;\n      const newPermanentElement = snapshot.getPermanentElementById(id);\n      if (newPermanentElement) {\n        permanentElementMap[id] = [currentPermanentElement, newPermanentElement];\n      }\n    }\n\n    return permanentElementMap\n  }\n}\n\nfunction getPermanentElementById(node, id) {\n  return node.querySelector(`#${id}[data-turbo-permanent]`)\n}\n\nfunction queryPermanentElementsAll(node) {\n  return node.querySelectorAll(\"[id][data-turbo-permanent]\")\n}\n\nclass FormSubmitObserver {\n  started = false\n\n  constructor(delegate, eventTarget) {\n    this.delegate = delegate;\n    this.eventTarget = eventTarget;\n  }\n\n  start() {\n    if (!this.started) {\n      this.eventTarget.addEventListener(\"submit\", this.submitCaptured, true);\n      this.started = true;\n    }\n  }\n\n  stop() {\n    if (this.started) {\n      this.eventTarget.removeEventListener(\"submit\", this.submitCaptured, true);\n      this.started = false;\n    }\n  }\n\n  submitCaptured = () => {\n    this.eventTarget.removeEventListener(\"submit\", this.submitBubbled, false);\n    this.eventTarget.addEventListener(\"submit\", this.submitBubbled, false);\n  }\n\n  submitBubbled = (event) => {\n    if (!event.defaultPrevented) {\n      const form = event.target instanceof HTMLFormElement ? event.target : undefined;\n      const submitter = event.submitter || undefined;\n\n      if (\n        form &&\n        submissionDoesNotDismissDialog(form, submitter) &&\n        submissionDoesNotTargetIFrame(form, submitter) &&\n        this.delegate.willSubmitForm(form, submitter)\n      ) {\n        event.preventDefault();\n        event.stopImmediatePropagation();\n        this.delegate.formSubmitted(form, submitter);\n      }\n    }\n  }\n}\n\nfunction submissionDoesNotDismissDialog(form, submitter) {\n  const method = submitter?.getAttribute(\"formmethod\") || form.getAttribute(\"method\");\n\n  return method != \"dialog\"\n}\n\nfunction submissionDoesNotTargetIFrame(form, submitter) {\n  const target = submitter?.getAttribute(\"formtarget\") || form.getAttribute(\"target\");\n\n  return doesNotTargetIFrame(target)\n}\n\nclass View {\n  #resolveRenderPromise = (_value) => {}\n  #resolveInterceptionPromise = (_value) => {}\n\n  constructor(delegate, element) {\n    this.delegate = delegate;\n    this.element = element;\n  }\n\n  // Scrolling\n\n  scrollToAnchor(anchor) {\n    const element = this.snapshot.getElementForAnchor(anchor);\n    if (element) {\n      this.focusElement(element);\n      this.scrollToElement(element);\n    } else {\n      this.scrollToPosition({ x: 0, y: 0 });\n    }\n  }\n\n  scrollToAnchorFromLocation(location) {\n    this.scrollToAnchor(getAnchor(location));\n  }\n\n  scrollToElement(element) {\n    element.scrollIntoView();\n  }\n\n  focusElement(element) {\n    if (element instanceof HTMLElement) {\n      if (element.hasAttribute(\"tabindex\")) {\n        element.focus();\n      } else {\n        element.setAttribute(\"tabindex\", \"-1\");\n        element.focus();\n        element.removeAttribute(\"tabindex\");\n      }\n    }\n  }\n\n  scrollToPosition({ x, y }) {\n    this.scrollRoot.scrollTo(x, y);\n  }\n\n  scrollToTop() {\n    this.scrollToPosition({ x: 0, y: 0 });\n  }\n\n  get scrollRoot() {\n    return window\n  }\n\n  // Rendering\n\n  async render(renderer) {\n    const { isPreview, shouldRender, willRender, newSnapshot: snapshot } = renderer;\n\n    // A workaround to ignore tracked element mismatch reloads when performing\n    // a promoted Visit from a frame navigation\n    const shouldInvalidate = willRender;\n\n    if (shouldRender) {\n      try {\n        this.renderPromise = new Promise((resolve) => (this.#resolveRenderPromise = resolve));\n        this.renderer = renderer;\n        await this.prepareToRenderSnapshot(renderer);\n\n        const renderInterception = new Promise((resolve) => (this.#resolveInterceptionPromise = resolve));\n        const options = { resume: this.#resolveInterceptionPromise, render: this.renderer.renderElement, renderMethod: this.renderer.renderMethod };\n        const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);\n        if (!immediateRender) await renderInterception;\n\n        await this.renderSnapshot(renderer);\n        this.delegate.viewRenderedSnapshot(snapshot, isPreview, this.renderer.renderMethod);\n        this.delegate.preloadOnLoadLinksForView(this.element);\n        this.finishRenderingSnapshot(renderer);\n      } finally {\n        delete this.renderer;\n        this.#resolveRenderPromise(undefined);\n        delete this.renderPromise;\n      }\n    } else if (shouldInvalidate) {\n      this.invalidate(renderer.reloadReason);\n    }\n  }\n\n  invalidate(reason) {\n    this.delegate.viewInvalidated(reason);\n  }\n\n  async prepareToRenderSnapshot(renderer) {\n    this.markAsPreview(renderer.isPreview);\n    await renderer.prepareToRender();\n  }\n\n  markAsPreview(isPreview) {\n    if (isPreview) {\n      this.element.setAttribute(\"data-turbo-preview\", \"\");\n    } else {\n      this.element.removeAttribute(\"data-turbo-preview\");\n    }\n  }\n\n  markVisitDirection(direction) {\n    this.element.setAttribute(\"data-turbo-visit-direction\", direction);\n  }\n\n  unmarkVisitDirection() {\n    this.element.removeAttribute(\"data-turbo-visit-direction\");\n  }\n\n  async renderSnapshot(renderer) {\n    await renderer.render();\n  }\n\n  finishRenderingSnapshot(renderer) {\n    renderer.finishRendering();\n  }\n}\n\nclass FrameView extends View {\n  missing() {\n    this.element.innerHTML = `<strong class=\"turbo-frame-error\">Content missing</strong>`;\n  }\n\n  get snapshot() {\n    return new Snapshot(this.element)\n  }\n}\n\nclass LinkInterceptor {\n  constructor(delegate, element) {\n    this.delegate = delegate;\n    this.element = element;\n  }\n\n  start() {\n    this.element.addEventListener(\"click\", this.clickBubbled);\n    document.addEventListener(\"turbo:click\", this.linkClicked);\n    document.addEventListener(\"turbo:before-visit\", this.willVisit);\n  }\n\n  stop() {\n    this.element.removeEventListener(\"click\", this.clickBubbled);\n    document.removeEventListener(\"turbo:click\", this.linkClicked);\n    document.removeEventListener(\"turbo:before-visit\", this.willVisit);\n  }\n\n  clickBubbled = (event) => {\n    if (this.clickEventIsSignificant(event)) {\n      this.clickEvent = event;\n    } else {\n      delete this.clickEvent;\n    }\n  }\n\n  linkClicked = (event) => {\n    if (this.clickEvent && this.clickEventIsSignificant(event)) {\n      if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) {\n        this.clickEvent.preventDefault();\n        event.preventDefault();\n        this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent);\n      }\n    }\n    delete this.clickEvent;\n  }\n\n  willVisit = (_event) => {\n    delete this.clickEvent;\n  }\n\n  clickEventIsSignificant(event) {\n    const target = event.composed ? event.target?.parentElement : event.target;\n    const element = findLinkFromClickTarget(target) || target;\n\n    return element instanceof Element && element.closest(\"turbo-frame, html\") == this.element\n  }\n}\n\nclass LinkClickObserver {\n  started = false\n\n  constructor(delegate, eventTarget) {\n    this.delegate = delegate;\n    this.eventTarget = eventTarget;\n  }\n\n  start() {\n    if (!this.started) {\n      this.eventTarget.addEventListener(\"click\", this.clickCaptured, true);\n      this.started = true;\n    }\n  }\n\n  stop() {\n    if (this.started) {\n      this.eventTarget.removeEventListener(\"click\", this.clickCaptured, true);\n      this.started = false;\n    }\n  }\n\n  clickCaptured = () => {\n    this.eventTarget.removeEventListener(\"click\", this.clickBubbled, false);\n    this.eventTarget.addEventListener(\"click\", this.clickBubbled, false);\n  }\n\n  clickBubbled = (event) => {\n    if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) {\n      const target = (event.composedPath && event.composedPath()[0]) || event.target;\n      const link = findLinkFromClickTarget(target);\n      if (link && doesNotTargetIFrame(link.target)) {\n        const location = getLocationForLink(link);\n        if (this.delegate.willFollowLinkToLocation(link, location, event)) {\n          event.preventDefault();\n          this.delegate.followedLinkToLocation(link, location);\n        }\n      }\n    }\n  }\n\n  clickEventIsSignificant(event) {\n    return !(\n      (event.target && event.target.isContentEditable) ||\n      event.defaultPrevented ||\n      event.which > 1 ||\n      event.altKey ||\n      event.ctrlKey ||\n      event.metaKey ||\n      event.shiftKey\n    )\n  }\n}\n\nclass FormLinkClickObserver {\n  constructor(delegate, element) {\n    this.delegate = delegate;\n    this.linkInterceptor = new LinkClickObserver(this, element);\n  }\n\n  start() {\n    this.linkInterceptor.start();\n  }\n\n  stop() {\n    this.linkInterceptor.stop();\n  }\n\n  // Link hover observer delegate\n\n  canPrefetchRequestToLocation(link, location) {\n    return false\n  }\n\n  prefetchAndCacheRequestToLocation(link, location) {\n    return\n  }\n\n  // Link click observer delegate\n\n  willFollowLinkToLocation(link, location, originalEvent) {\n    return (\n      this.delegate.willSubmitFormLinkToLocation(link, location, originalEvent) &&\n      (link.hasAttribute(\"data-turbo-method\") || link.hasAttribute(\"data-turbo-stream\"))\n    )\n  }\n\n  followedLinkToLocation(link, location) {\n    const form = document.createElement(\"form\");\n\n    const type = \"hidden\";\n    for (const [name, value] of location.searchParams) {\n      form.append(Object.assign(document.createElement(\"input\"), { type, name, value }));\n    }\n\n    const action = Object.assign(location, { search: \"\" });\n    form.setAttribute(\"data-turbo\", \"true\");\n    form.setAttribute(\"action\", action.href);\n    form.setAttribute(\"hidden\", \"\");\n\n    const method = link.getAttribute(\"data-turbo-method\");\n    if (method) form.setAttribute(\"method\", method);\n\n    const turboFrame = link.getAttribute(\"data-turbo-frame\");\n    if (turboFrame) form.setAttribute(\"data-turbo-frame\", turboFrame);\n\n    const turboAction = getVisitAction(link);\n    if (turboAction) form.setAttribute(\"data-turbo-action\", turboAction);\n\n    const turboConfirm = link.getAttribute(\"data-turbo-confirm\");\n    if (turboConfirm) form.setAttribute(\"data-turbo-confirm\", turboConfirm);\n\n    const turboStream = link.hasAttribute(\"data-turbo-stream\");\n    if (turboStream) form.setAttribute(\"data-turbo-stream\", \"\");\n\n    this.delegate.submittedFormLinkToLocation(link, location, form);\n\n    document.body.appendChild(form);\n    form.addEventListener(\"turbo:submit-end\", () => form.remove(), { once: true });\n    requestAnimationFrame(() => form.requestSubmit());\n  }\n}\n\nclass Bardo {\n  static async preservingPermanentElements(delegate, permanentElementMap, callback) {\n    const bardo = new this(delegate, permanentElementMap);\n    bardo.enter();\n    await callback();\n    bardo.leave();\n  }\n\n  constructor(delegate, permanentElementMap) {\n    this.delegate = delegate;\n    this.permanentElementMap = permanentElementMap;\n  }\n\n  enter() {\n    for (const id in this.permanentElementMap) {\n      const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id];\n      this.delegate.enteringBardo(currentPermanentElement, newPermanentElement);\n      this.replaceNewPermanentElementWithPlaceholder(newPermanentElement);\n    }\n  }\n\n  leave() {\n    for (const id in this.permanentElementMap) {\n      const [currentPermanentElement] = this.permanentElementMap[id];\n      this.replaceCurrentPermanentElementWithClone(currentPermanentElement);\n      this.replacePlaceholderWithPermanentElement(currentPermanentElement);\n      this.delegate.leavingBardo(currentPermanentElement);\n    }\n  }\n\n  replaceNewPermanentElementWithPlaceholder(permanentElement) {\n    const placeholder = createPlaceholderForPermanentElement(permanentElement);\n    permanentElement.replaceWith(placeholder);\n  }\n\n  replaceCurrentPermanentElementWithClone(permanentElement) {\n    const clone = permanentElement.cloneNode(true);\n    permanentElement.replaceWith(clone);\n  }\n\n  replacePlaceholderWithPermanentElement(permanentElement) {\n    const placeholder = this.getPlaceholderById(permanentElement.id);\n    placeholder?.replaceWith(permanentElement);\n  }\n\n  getPlaceholderById(id) {\n    return this.placeholders.find((element) => element.content == id)\n  }\n\n  get placeholders() {\n    return [...document.querySelectorAll(\"meta[name=turbo-permanent-placeholder][content]\")]\n  }\n}\n\nfunction createPlaceholderForPermanentElement(permanentElement) {\n  const element = document.createElement(\"meta\");\n  element.setAttribute(\"name\", \"turbo-permanent-placeholder\");\n  element.setAttribute(\"content\", permanentElement.id);\n  return element\n}\n\nclass Renderer {\n  #activeElement = null\n\n  static renderElement(currentElement, newElement) {\n    // Abstract method\n  }\n\n  constructor(currentSnapshot, newSnapshot, isPreview, willRender = true) {\n    this.currentSnapshot = currentSnapshot;\n    this.newSnapshot = newSnapshot;\n    this.isPreview = isPreview;\n    this.willRender = willRender;\n    this.renderElement = this.constructor.renderElement;\n    this.promise = new Promise((resolve, reject) => (this.resolvingFunctions = { resolve, reject }));\n  }\n\n  get shouldRender() {\n    return true\n  }\n\n  get shouldAutofocus() {\n    return true\n  }\n\n  get reloadReason() {\n    return\n  }\n\n  prepareToRender() {\n    return\n  }\n\n  render() {\n    // Abstract method\n  }\n\n  finishRendering() {\n    if (this.resolvingFunctions) {\n      this.resolvingFunctions.resolve();\n      delete this.resolvingFunctions;\n    }\n  }\n\n  async preservingPermanentElements(callback) {\n    await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);\n  }\n\n  focusFirstAutofocusableElement() {\n    if (this.shouldAutofocus) {\n      const element = this.connectedSnapshot.firstAutofocusableElement;\n      if (element) {\n        element.focus();\n      }\n    }\n  }\n\n  // Bardo delegate\n\n  enteringBardo(currentPermanentElement) {\n    if (this.#activeElement) return\n\n    if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) {\n      this.#activeElement = this.currentSnapshot.activeElement;\n    }\n  }\n\n  leavingBardo(currentPermanentElement) {\n    if (currentPermanentElement.contains(this.#activeElement) && this.#activeElement instanceof HTMLElement) {\n      this.#activeElement.focus();\n\n      this.#activeElement = null;\n    }\n  }\n\n  get connectedSnapshot() {\n    return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot\n  }\n\n  get currentElement() {\n    return this.currentSnapshot.element\n  }\n\n  get newElement() {\n    return this.newSnapshot.element\n  }\n\n  get permanentElementMap() {\n    return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot)\n  }\n\n  get renderMethod() {\n    return \"replace\"\n  }\n}\n\nclass FrameRenderer extends Renderer {\n  static renderElement(currentElement, newElement) {\n    const destinationRange = document.createRange();\n    destinationRange.selectNodeContents(currentElement);\n    destinationRange.deleteContents();\n\n    const frameElement = newElement;\n    const sourceRange = frameElement.ownerDocument?.createRange();\n    if (sourceRange) {\n      sourceRange.selectNodeContents(frameElement);\n      currentElement.appendChild(sourceRange.extractContents());\n    }\n  }\n\n  constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {\n    super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);\n    this.delegate = delegate;\n  }\n\n  get shouldRender() {\n    return true\n  }\n\n  async render() {\n    await nextRepaint();\n    this.preservingPermanentElements(() => {\n      this.loadFrameElement();\n    });\n    this.scrollFrameIntoView();\n    await nextRepaint();\n    this.focusFirstAutofocusableElement();\n    await nextRepaint();\n    this.activateScriptElements();\n  }\n\n  loadFrameElement() {\n    this.delegate.willRenderFrame(this.currentElement, this.newElement);\n    this.renderElement(this.currentElement, this.newElement);\n  }\n\n  scrollFrameIntoView() {\n    if (this.currentElement.autoscroll || this.newElement.autoscroll) {\n      const element = this.currentElement.firstElementChild;\n      const block = readScrollLogicalPosition(this.currentElement.getAttribute(\"data-autoscroll-block\"), \"end\");\n      const behavior = readScrollBehavior(this.currentElement.getAttribute(\"data-autoscroll-behavior\"), \"auto\");\n\n      if (element) {\n        element.scrollIntoView({ block, behavior });\n        return true\n      }\n    }\n    return false\n  }\n\n  activateScriptElements() {\n    for (const inertScriptElement of this.newScriptElements) {\n      const activatedScriptElement = activateScriptElement(inertScriptElement);\n      inertScriptElement.replaceWith(activatedScriptElement);\n    }\n  }\n\n  get newScriptElements() {\n    return this.currentElement.querySelectorAll(\"script\")\n  }\n}\n\nfunction readScrollLogicalPosition(value, defaultValue) {\n  if (value == \"end\" || value == \"start\" || value == \"center\" || value == \"nearest\") {\n    return value\n  } else {\n    return defaultValue\n  }\n}\n\nfunction readScrollBehavior(value, defaultValue) {\n  if (value == \"auto\" || value == \"smooth\") {\n    return value\n  } else {\n    return defaultValue\n  }\n}\n\n/**\n * @typedef {object} ConfigHead\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} [style]\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {function(Element): boolean} [shouldPreserve]\n * @property {function(Element): boolean} [shouldReAppend]\n * @property {function(Element): boolean} [shouldRemove]\n * @property {function(Element, {added: Node[], kept: Element[], removed: Element[]}): void} [afterHeadMorphed]\n */\n\n/**\n * @typedef {object} ConfigCallbacks\n *\n * @property {function(Node): boolean} [beforeNodeAdded]\n * @property {function(Node): void} [afterNodeAdded]\n * @property {function(Element, Node): boolean} [beforeNodeMorphed]\n * @property {function(Element, Node): void} [afterNodeMorphed]\n * @property {function(Element): boolean} [beforeNodeRemoved]\n * @property {function(Element): void} [afterNodeRemoved]\n * @property {function(string, Element, \"update\" | \"remove\"): boolean} [beforeAttributeUpdated]\n */\n\n/**\n * @typedef {object} Config\n *\n * @property {'outerHTML' | 'innerHTML'} [morphStyle]\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacks} [callbacks]\n * @property {ConfigHead} [head]\n */\n\n/**\n * @typedef {function} NoOp\n *\n * @returns {void}\n */\n\n/**\n * @typedef {object} ConfigHeadInternal\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} style\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {(function(Element): boolean) | NoOp} shouldPreserve\n * @property {(function(Element): boolean) | NoOp} shouldReAppend\n * @property {(function(Element): boolean) | NoOp} shouldRemove\n * @property {(function(Element, {added: Node[], kept: Element[], removed: Element[]}): void) | NoOp} afterHeadMorphed\n */\n\n/**\n * @typedef {object} ConfigCallbacksInternal\n *\n * @property {(function(Node): boolean) | NoOp} beforeNodeAdded\n * @property {(function(Node): void) | NoOp} afterNodeAdded\n * @property {(function(Node, Node): boolean) | NoOp} beforeNodeMorphed\n * @property {(function(Node, Node): void) | NoOp} afterNodeMorphed\n * @property {(function(Node): boolean) | NoOp} beforeNodeRemoved\n * @property {(function(Node): void) | NoOp} afterNodeRemoved\n * @property {(function(string, Element, \"update\" | \"remove\"): boolean) | NoOp} beforeAttributeUpdated\n */\n\n/**\n * @typedef {object} ConfigInternal\n *\n * @property {'outerHTML' | 'innerHTML'} morphStyle\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacksInternal} callbacks\n * @property {ConfigHeadInternal} head\n */\n\n/**\n * @typedef {Object} IdSets\n * @property {Set<string>} persistentIds\n * @property {Map<Node, Set<string>>} idMap\n */\n\n/**\n * @typedef {Function} Morph\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {undefined | Node[]}\n */\n\n// base IIFE to define idiomorph\n/**\n *\n * @type {{defaults: ConfigInternal, morph: Morph}}\n */\nvar Idiomorph = (function () {\n\n  /**\n   * @typedef {object} MorphContext\n   *\n   * @property {Element} target\n   * @property {Element} newContent\n   * @property {ConfigInternal} config\n   * @property {ConfigInternal['morphStyle']} morphStyle\n   * @property {ConfigInternal['ignoreActive']} ignoreActive\n   * @property {ConfigInternal['ignoreActiveValue']} ignoreActiveValue\n   * @property {ConfigInternal['restoreFocus']} restoreFocus\n   * @property {Map<Node, Set<string>>} idMap\n   * @property {Set<string>} persistentIds\n   * @property {ConfigInternal['callbacks']} callbacks\n   * @property {ConfigInternal['head']} head\n   * @property {HTMLDivElement} pantry\n   * @property {Element[]} activeElementAndParents\n   */\n\n  //=============================================================================\n  // AND NOW IT BEGINS...\n  //=============================================================================\n\n  const noOp = () => {};\n  /**\n   * Default configuration values, updatable by users now\n   * @type {ConfigInternal}\n   */\n  const defaults = {\n    morphStyle: \"outerHTML\",\n    callbacks: {\n      beforeNodeAdded: noOp,\n      afterNodeAdded: noOp,\n      beforeNodeMorphed: noOp,\n      afterNodeMorphed: noOp,\n      beforeNodeRemoved: noOp,\n      afterNodeRemoved: noOp,\n      beforeAttributeUpdated: noOp,\n    },\n    head: {\n      style: \"merge\",\n      shouldPreserve: (elt) => elt.getAttribute(\"im-preserve\") === \"true\",\n      shouldReAppend: (elt) => elt.getAttribute(\"im-re-append\") === \"true\",\n      shouldRemove: noOp,\n      afterHeadMorphed: noOp,\n    },\n    restoreFocus: true,\n  };\n\n  /**\n   * Core idiomorph function for morphing one DOM tree to another\n   *\n   * @param {Element | Document} oldNode\n   * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n   * @param {Config} [config]\n   * @returns {Promise<Node[]> | Node[]}\n   */\n  function morph(oldNode, newContent, config = {}) {\n    oldNode = normalizeElement(oldNode);\n    const newNode = normalizeParent(newContent);\n    const ctx = createMorphContext(oldNode, newNode, config);\n\n    const morphedNodes = saveAndRestoreFocus(ctx, () => {\n      return withHeadBlocking(\n        ctx,\n        oldNode,\n        newNode,\n        /** @param {MorphContext} ctx */ (ctx) => {\n          if (ctx.morphStyle === \"innerHTML\") {\n            morphChildren(ctx, oldNode, newNode);\n            return Array.from(oldNode.childNodes);\n          } else {\n            return morphOuterHTML(ctx, oldNode, newNode);\n          }\n        },\n      );\n    });\n\n    ctx.pantry.remove();\n    return morphedNodes;\n  }\n\n  /**\n   * Morph just the outerHTML of the oldNode to the newContent\n   * We have to be careful because the oldNode could have siblings which need to be untouched\n   * @param {MorphContext} ctx\n   * @param {Element} oldNode\n   * @param {Element} newNode\n   * @returns {Node[]}\n   */\n  function morphOuterHTML(ctx, oldNode, newNode) {\n    const oldParent = normalizeParent(oldNode);\n    morphChildren(\n      ctx,\n      oldParent,\n      newNode,\n      // these two optional params are the secret sauce\n      oldNode, // start point for iteration\n      oldNode.nextSibling, // end point for iteration\n    );\n    // this is safe even with siblings, because normalizeParent returns a SlicedParentNode if needed.\n    return Array.from(oldParent.childNodes);\n  }\n\n  /**\n   * @param {MorphContext} ctx\n   * @param {Function} fn\n   * @returns {Promise<Node[]> | Node[]}\n   */\n  function saveAndRestoreFocus(ctx, fn) {\n    if (!ctx.config.restoreFocus) return fn();\n    let activeElement =\n      /** @type {HTMLInputElement|HTMLTextAreaElement|null} */ (\n        document.activeElement\n      );\n\n    // don't bother if the active element is not an input or textarea\n    if (\n      !(\n        activeElement instanceof HTMLInputElement ||\n        activeElement instanceof HTMLTextAreaElement\n      )\n    ) {\n      return fn();\n    }\n\n    const { id: activeElementId, selectionStart, selectionEnd } = activeElement;\n\n    const results = fn();\n\n    if (\n      activeElementId &&\n      activeElementId !== document.activeElement?.getAttribute(\"id\")\n    ) {\n      activeElement = ctx.target.querySelector(`[id=\"${activeElementId}\"]`);\n      activeElement?.focus();\n    }\n    if (activeElement && !activeElement.selectionEnd && selectionEnd) {\n      activeElement.setSelectionRange(selectionStart, selectionEnd);\n    }\n\n    return results;\n  }\n\n  const morphChildren = (function () {\n    /**\n     * This is the core algorithm for matching up children.  The idea is to use id sets to try to match up\n     * nodes as faithfully as possible.  We greedily match, which allows us to keep the algorithm fast, but\n     * by using id sets, we are able to better match up with content deeper in the DOM.\n     *\n     * Basic algorithm:\n     * - for each node in the new content:\n     *   - search self and siblings for an id set match, falling back to a soft match\n     *   - if match found\n     *     - remove any nodes up to the match:\n     *       - pantry persistent nodes\n     *       - delete the rest\n     *     - morph the match\n     *   - elsif no match found, and node is persistent\n     *     - find its match by querying the old root (future) and pantry (past)\n     *     - move it and its children here\n     *     - morph it\n     *   - else\n     *     - create a new node from scratch as a last result\n     *\n     * @param {MorphContext} ctx the merge context\n     * @param {Element} oldParent the old content that we are merging the new content into\n     * @param {Element} newParent the parent element of the new content\n     * @param {Node|null} [insertionPoint] the point in the DOM we start morphing at (defaults to first child)\n     * @param {Node|null} [endPoint] the point in the DOM we stop morphing at (defaults to after last child)\n     */\n    function morphChildren(\n      ctx,\n      oldParent,\n      newParent,\n      insertionPoint = null,\n      endPoint = null,\n    ) {\n      // normalize\n      if (\n        oldParent instanceof HTMLTemplateElement &&\n        newParent instanceof HTMLTemplateElement\n      ) {\n        // @ts-ignore we can pretend the DocumentFragment is an Element\n        oldParent = oldParent.content;\n        // @ts-ignore ditto\n        newParent = newParent.content;\n      }\n      insertionPoint ||= oldParent.firstChild;\n\n      // run through all the new content\n      for (const newChild of newParent.childNodes) {\n        // once we reach the end of the old parent content skip to the end and insert the rest\n        if (insertionPoint && insertionPoint != endPoint) {\n          const bestMatch = findBestMatch(\n            ctx,\n            newChild,\n            insertionPoint,\n            endPoint,\n          );\n          if (bestMatch) {\n            // if the node to morph is not at the insertion point then remove/move up to it\n            if (bestMatch !== insertionPoint) {\n              removeNodesBetween(ctx, insertionPoint, bestMatch);\n            }\n            morphNode(bestMatch, newChild, ctx);\n            insertionPoint = bestMatch.nextSibling;\n            continue;\n          }\n        }\n\n        // if the matching node is elsewhere in the original content\n        if (newChild instanceof Element) {\n          // we can pretend the id is non-null because the next `.has` line will reject it if not\n          const newChildId = /** @type {String} */ (\n            newChild.getAttribute(\"id\")\n          );\n          if (ctx.persistentIds.has(newChildId)) {\n            // move it and all its children here and morph\n            const movedChild = moveBeforeById(\n              oldParent,\n              newChildId,\n              insertionPoint,\n              ctx,\n            );\n            morphNode(movedChild, newChild, ctx);\n            insertionPoint = movedChild.nextSibling;\n            continue;\n          }\n        }\n\n        // last resort: insert the new node from scratch\n        const insertedNode = createNode(\n          oldParent,\n          newChild,\n          insertionPoint,\n          ctx,\n        );\n        // could be null if beforeNodeAdded prevented insertion\n        if (insertedNode) {\n          insertionPoint = insertedNode.nextSibling;\n        }\n      }\n\n      // remove any remaining old nodes that didn't match up with new content\n      while (insertionPoint && insertionPoint != endPoint) {\n        const tempNode = insertionPoint;\n        insertionPoint = insertionPoint.nextSibling;\n        removeNode(ctx, tempNode);\n      }\n    }\n\n    /**\n     * This performs the action of inserting a new node while handling situations where the node contains\n     * elements with persistent ids and possible state info we can still preserve by moving in and then morphing\n     *\n     * @param {Element} oldParent\n     * @param {Node} newChild\n     * @param {Node|null} insertionPoint\n     * @param {MorphContext} ctx\n     * @returns {Node|null}\n     */\n    function createNode(oldParent, newChild, insertionPoint, ctx) {\n      if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null;\n      if (ctx.idMap.has(newChild)) {\n        // node has children with ids with possible state so create a dummy elt of same type and apply full morph algorithm\n        const newEmptyChild = document.createElement(\n          /** @type {Element} */ (newChild).tagName,\n        );\n        oldParent.insertBefore(newEmptyChild, insertionPoint);\n        morphNode(newEmptyChild, newChild, ctx);\n        ctx.callbacks.afterNodeAdded(newEmptyChild);\n        return newEmptyChild;\n      } else {\n        // optimisation: no id state to preserve so we can just insert a clone of the newChild and its descendants\n        const newClonedChild = document.importNode(newChild, true); // importNode to not mutate newParent\n        oldParent.insertBefore(newClonedChild, insertionPoint);\n        ctx.callbacks.afterNodeAdded(newClonedChild);\n        return newClonedChild;\n      }\n    }\n\n    //=============================================================================\n    // Matching Functions\n    //=============================================================================\n    const findBestMatch = (function () {\n      /**\n       * Scans forward from the startPoint to the endPoint looking for a match\n       * for the node. It looks for an id set match first, then a soft match.\n       * We abort softmatching if we find two future soft matches, to reduce churn.\n       * @param {Node} node\n       * @param {MorphContext} ctx\n       * @param {Node | null} startPoint\n       * @param {Node | null} endPoint\n       * @returns {Node | null}\n       */\n      function findBestMatch(ctx, node, startPoint, endPoint) {\n        let softMatch = null;\n        let nextSibling = node.nextSibling;\n        let siblingSoftMatchCount = 0;\n\n        let cursor = startPoint;\n        while (cursor && cursor != endPoint) {\n          // soft matching is a prerequisite for id set matching\n          if (isSoftMatch(cursor, node)) {\n            if (isIdSetMatch(ctx, cursor, node)) {\n              return cursor; // found an id set match, we're done!\n            }\n\n            // we haven't yet saved a soft match fallback\n            if (softMatch === null) {\n              // the current soft match will hard match something else in the future, leave it\n              if (!ctx.idMap.has(cursor)) {\n                // save this as the fallback if we get through the loop without finding a hard match\n                softMatch = cursor;\n              }\n            }\n          }\n          if (\n            softMatch === null &&\n            nextSibling &&\n            isSoftMatch(cursor, nextSibling)\n          ) {\n            // The next new node has a soft match with this node, so\n            // increment the count of future soft matches\n            siblingSoftMatchCount++;\n            nextSibling = nextSibling.nextSibling;\n\n            // If there are two future soft matches, block soft matching for this node to allow\n            // future siblings to soft match. This is to reduce churn in the DOM when an element\n            // is prepended.\n            if (siblingSoftMatchCount >= 2) {\n              softMatch = undefined;\n            }\n          }\n\n          // if the current node contains active element, stop looking for better future matches,\n          // because if one is found, this node will be moved to the pantry, reparenting it and thus losing focus\n          // @ts-ignore pretend cursor is Element rather than Node, we're just testing for array inclusion\n          if (ctx.activeElementAndParents.includes(cursor)) break;\n\n          cursor = cursor.nextSibling;\n        }\n\n        return softMatch || null;\n      }\n\n      /**\n       *\n       * @param {MorphContext} ctx\n       * @param {Node} oldNode\n       * @param {Node} newNode\n       * @returns {boolean}\n       */\n      function isIdSetMatch(ctx, oldNode, newNode) {\n        let oldSet = ctx.idMap.get(oldNode);\n        let newSet = ctx.idMap.get(newNode);\n\n        if (!newSet || !oldSet) return false;\n\n        for (const id of oldSet) {\n          // a potential match is an id in the new and old nodes that\n          // has not already been merged into the DOM\n          // But the newNode content we call this on has not been\n          // merged yet and we don't allow duplicate IDs so it is simple\n          if (newSet.has(id)) {\n            return true;\n          }\n        }\n        return false;\n      }\n\n      /**\n       *\n       * @param {Node} oldNode\n       * @param {Node} newNode\n       * @returns {boolean}\n       */\n      function isSoftMatch(oldNode, newNode) {\n        // ok to cast: if one is not element, `id` and `tagName` will be undefined and we'll just compare that.\n        const oldElt = /** @type {Element} */ (oldNode);\n        const newElt = /** @type {Element} */ (newNode);\n\n        return (\n          oldElt.nodeType === newElt.nodeType &&\n          oldElt.tagName === newElt.tagName &&\n          // If oldElt has an `id` with possible state and it doesn't match newElt.id then avoid morphing.\n          // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n          // its not persistent, and new nodes can't have any hidden state.\n          // We can't use .id because of form input shadowing, and we can't count on .getAttribute's presence because it could be a document-fragment\n          (!oldElt.getAttribute?.(\"id\") ||\n            oldElt.getAttribute?.(\"id\") === newElt.getAttribute?.(\"id\"))\n        );\n      }\n\n      return findBestMatch;\n    })();\n\n    //=============================================================================\n    // DOM Manipulation Functions\n    //=============================================================================\n\n    /**\n     * Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n     * - Persistent nodes will be moved to the pantry for later reuse\n     * - Other nodes will have their hooks called, and then are removed\n     * @param {MorphContext} ctx\n     * @param {Node} node\n     */\n    function removeNode(ctx, node) {\n      // are we going to id set match this later?\n      if (ctx.idMap.has(node)) {\n        // skip callbacks and move to pantry\n        moveBefore(ctx.pantry, node, null);\n      } else {\n        // remove for realsies\n        if (ctx.callbacks.beforeNodeRemoved(node) === false) return;\n        node.parentNode?.removeChild(node);\n        ctx.callbacks.afterNodeRemoved(node);\n      }\n    }\n\n    /**\n     * Remove nodes between the start and end nodes\n     * @param {MorphContext} ctx\n     * @param {Node} startInclusive\n     * @param {Node} endExclusive\n     * @returns {Node|null}\n     */\n    function removeNodesBetween(ctx, startInclusive, endExclusive) {\n      /** @type {Node | null} */\n      let cursor = startInclusive;\n      // remove nodes until the endExclusive node\n      while (cursor && cursor !== endExclusive) {\n        let tempNode = /** @type {Node} */ (cursor);\n        cursor = cursor.nextSibling;\n        removeNode(ctx, tempNode);\n      }\n      return cursor;\n    }\n\n    /**\n     * Search for an element by id within the document and pantry, and move it using moveBefore.\n     *\n     * @param {Element} parentNode - The parent node to which the element will be moved.\n     * @param {string} id - The ID of the element to be moved.\n     * @param {Node | null} after - The reference node to insert the element before.\n     *                              If `null`, the element is appended as the last child.\n     * @param {MorphContext} ctx\n     * @returns {Element} The found element\n     */\n    function moveBeforeById(parentNode, id, after, ctx) {\n      const target =\n        /** @type {Element} - will always be found */\n        (\n          // ctx.target.id unsafe because of form input shadowing\n          // ctx.target could be a document fragment which doesn't have `getAttribute`\n          (ctx.target.getAttribute?.(\"id\") === id && ctx.target) ||\n            ctx.target.querySelector(`[id=\"${id}\"]`) ||\n            ctx.pantry.querySelector(`[id=\"${id}\"]`)\n        );\n      removeElementFromAncestorsIdMaps(target, ctx);\n      moveBefore(parentNode, target, after);\n      return target;\n    }\n\n    /**\n     * Removes an element from its ancestors' id maps. This is needed when an element is moved from the\n     * \"future\" via `moveBeforeId`. Otherwise, its erstwhile ancestors could be mistakenly moved to the\n     * pantry rather than being deleted, preventing their removal hooks from being called.\n     *\n     * @param {Element} element - element to remove from its ancestors' id maps\n     * @param {MorphContext} ctx\n     */\n    function removeElementFromAncestorsIdMaps(element, ctx) {\n      // we know id is non-null String, because this function is only called on elements with ids\n      const id = /** @type {String} */ (element.getAttribute(\"id\"));\n      /** @ts-ignore - safe to loop in this way **/\n      while ((element = element.parentNode)) {\n        let idSet = ctx.idMap.get(element);\n        if (idSet) {\n          idSet.delete(id);\n          if (!idSet.size) {\n            ctx.idMap.delete(element);\n          }\n        }\n      }\n    }\n\n    /**\n     * Moves an element before another element within the same parent.\n     * Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n     * This is essentialy a forward-compat wrapper.\n     *\n     * @param {Element} parentNode - The parent node containing the after element.\n     * @param {Node} element - The element to be moved.\n     * @param {Node | null} after - The reference node to insert `element` before.\n     *                              If `null`, `element` is appended as the last child.\n     */\n    function moveBefore(parentNode, element, after) {\n      // @ts-ignore - use proposed moveBefore feature\n      if (parentNode.moveBefore) {\n        try {\n          // @ts-ignore - use proposed moveBefore feature\n          parentNode.moveBefore(element, after);\n        } catch (e) {\n          // fall back to insertBefore as some browsers may fail on moveBefore when trying to move Dom disconnected nodes to pantry\n          parentNode.insertBefore(element, after);\n        }\n      } else {\n        parentNode.insertBefore(element, after);\n      }\n    }\n\n    return morphChildren;\n  })();\n\n  //=============================================================================\n  // Single Node Morphing Code\n  //=============================================================================\n  const morphNode = (function () {\n    /**\n     * @param {Node} oldNode root node to merge content into\n     * @param {Node} newContent new content to merge\n     * @param {MorphContext} ctx the merge context\n     * @returns {Node | null} the element that ended up in the DOM\n     */\n    function morphNode(oldNode, newContent, ctx) {\n      if (ctx.ignoreActive && oldNode === document.activeElement) {\n        // don't morph focused element\n        return null;\n      }\n\n      if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) {\n        return oldNode;\n      }\n\n      if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) ; else if (\n        oldNode instanceof HTMLHeadElement &&\n        ctx.head.style !== \"morph\"\n      ) {\n        // ok to cast: if newContent wasn't also a <head>, it would've got caught in the `!isSoftMatch` branch above\n        handleHeadElement(\n          oldNode,\n          /** @type {HTMLHeadElement} */ (newContent),\n          ctx,\n        );\n      } else {\n        morphAttributes(oldNode, newContent, ctx);\n        if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n          // @ts-ignore newContent can be a node here because .firstChild will be null\n          morphChildren(ctx, oldNode, newContent);\n        }\n      }\n      ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n      return oldNode;\n    }\n\n    /**\n     * syncs the oldNode to the newNode, copying over all attributes and\n     * inner element state from the newNode to the oldNode\n     *\n     * @param {Node} oldNode the node to copy attributes & state to\n     * @param {Node} newNode the node to copy attributes & state from\n     * @param {MorphContext} ctx the merge context\n     */\n    function morphAttributes(oldNode, newNode, ctx) {\n      let type = newNode.nodeType;\n\n      // if is an element type, sync the attributes from the\n      // new node into the new node\n      if (type === 1 /* element type */) {\n        const oldElt = /** @type {Element} */ (oldNode);\n        const newElt = /** @type {Element} */ (newNode);\n\n        const oldAttributes = oldElt.attributes;\n        const newAttributes = newElt.attributes;\n        for (const newAttribute of newAttributes) {\n          if (ignoreAttribute(newAttribute.name, oldElt, \"update\", ctx)) {\n            continue;\n          }\n          if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) {\n            oldElt.setAttribute(newAttribute.name, newAttribute.value);\n          }\n        }\n        // iterate backwards to avoid skipping over items when a delete occurs\n        for (let i = oldAttributes.length - 1; 0 <= i; i--) {\n          const oldAttribute = oldAttributes[i];\n\n          // toAttributes is a live NamedNodeMap, so iteration+mutation is unsafe\n          // e.g. custom element attribute callbacks can remove other attributes\n          if (!oldAttribute) continue;\n\n          if (!newElt.hasAttribute(oldAttribute.name)) {\n            if (ignoreAttribute(oldAttribute.name, oldElt, \"remove\", ctx)) {\n              continue;\n            }\n            oldElt.removeAttribute(oldAttribute.name);\n          }\n        }\n\n        if (!ignoreValueOfActiveElement(oldElt, ctx)) {\n          syncInputValue(oldElt, newElt, ctx);\n        }\n      }\n\n      // sync text nodes\n      if (type === 8 /* comment */ || type === 3 /* text */) {\n        if (oldNode.nodeValue !== newNode.nodeValue) {\n          oldNode.nodeValue = newNode.nodeValue;\n        }\n      }\n    }\n\n    /**\n     * NB: many bothans died to bring us information:\n     *\n     *  https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n     *  https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n     *\n     * @param {Element} oldElement the element to sync the input value to\n     * @param {Element} newElement the element to sync the input value from\n     * @param {MorphContext} ctx the merge context\n     */\n    function syncInputValue(oldElement, newElement, ctx) {\n      if (\n        oldElement instanceof HTMLInputElement &&\n        newElement instanceof HTMLInputElement &&\n        newElement.type !== \"file\"\n      ) {\n        let newValue = newElement.value;\n        let oldValue = oldElement.value;\n\n        // sync boolean attributes\n        syncBooleanAttribute(oldElement, newElement, \"checked\", ctx);\n        syncBooleanAttribute(oldElement, newElement, \"disabled\", ctx);\n\n        if (!newElement.hasAttribute(\"value\")) {\n          if (!ignoreAttribute(\"value\", oldElement, \"remove\", ctx)) {\n            oldElement.value = \"\";\n            oldElement.removeAttribute(\"value\");\n          }\n        } else if (oldValue !== newValue) {\n          if (!ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n            oldElement.setAttribute(\"value\", newValue);\n            oldElement.value = newValue;\n          }\n        }\n        // TODO: QUESTION(1cg): this used to only check `newElement` unlike the other branches -- why?\n        // did I break something?\n      } else if (\n        oldElement instanceof HTMLOptionElement &&\n        newElement instanceof HTMLOptionElement\n      ) {\n        syncBooleanAttribute(oldElement, newElement, \"selected\", ctx);\n      } else if (\n        oldElement instanceof HTMLTextAreaElement &&\n        newElement instanceof HTMLTextAreaElement\n      ) {\n        let newValue = newElement.value;\n        let oldValue = oldElement.value;\n        if (ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n          return;\n        }\n        if (newValue !== oldValue) {\n          oldElement.value = newValue;\n        }\n        if (\n          oldElement.firstChild &&\n          oldElement.firstChild.nodeValue !== newValue\n        ) {\n          oldElement.firstChild.nodeValue = newValue;\n        }\n      }\n    }\n\n    /**\n     * @param {Element} oldElement element to write the value to\n     * @param {Element} newElement element to read the value from\n     * @param {string} attributeName the attribute name\n     * @param {MorphContext} ctx the merge context\n     */\n    function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) {\n      // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n      const newLiveValue = newElement[attributeName],\n        // @ts-ignore ditto\n        oldLiveValue = oldElement[attributeName];\n      if (newLiveValue !== oldLiveValue) {\n        const ignoreUpdate = ignoreAttribute(\n          attributeName,\n          oldElement,\n          \"update\",\n          ctx,\n        );\n        if (!ignoreUpdate) {\n          // update attribute's associated DOM property\n          // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n          oldElement[attributeName] = newElement[attributeName];\n        }\n        if (newLiveValue) {\n          if (!ignoreUpdate) {\n            // https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HTML\n            // this is the correct way to set a boolean attribute to \"true\"\n            oldElement.setAttribute(attributeName, \"\");\n          }\n        } else {\n          if (!ignoreAttribute(attributeName, oldElement, \"remove\", ctx)) {\n            oldElement.removeAttribute(attributeName);\n          }\n        }\n      }\n    }\n\n    /**\n     * @param {string} attr the attribute to be mutated\n     * @param {Element} element the element that is going to be updated\n     * @param {\"update\" | \"remove\"} updateType\n     * @param {MorphContext} ctx the merge context\n     * @returns {boolean} true if the attribute should be ignored, false otherwise\n     */\n    function ignoreAttribute(attr, element, updateType, ctx) {\n      if (\n        attr === \"value\" &&\n        ctx.ignoreActiveValue &&\n        element === document.activeElement\n      ) {\n        return true;\n      }\n      return (\n        ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) ===\n        false\n      );\n    }\n\n    /**\n     * @param {Node} possibleActiveElement\n     * @param {MorphContext} ctx\n     * @returns {boolean}\n     */\n    function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n      return (\n        !!ctx.ignoreActiveValue &&\n        possibleActiveElement === document.activeElement &&\n        possibleActiveElement !== document.body\n      );\n    }\n\n    return morphNode;\n  })();\n\n  //=============================================================================\n  // Head Management Functions\n  //=============================================================================\n  /**\n   * @param {MorphContext} ctx\n   * @param {Element} oldNode\n   * @param {Element} newNode\n   * @param {function} callback\n   * @returns {Node[] | Promise<Node[]>}\n   */\n  function withHeadBlocking(ctx, oldNode, newNode, callback) {\n    if (ctx.head.block) {\n      const oldHead = oldNode.querySelector(\"head\");\n      const newHead = newNode.querySelector(\"head\");\n      if (oldHead && newHead) {\n        const promises = handleHeadElement(oldHead, newHead, ctx);\n        // when head promises resolve, proceed ignoring the head tag\n        return Promise.all(promises).then(() => {\n          const newCtx = Object.assign(ctx, {\n            head: {\n              block: false,\n              ignore: true,\n            },\n          });\n          return callback(newCtx);\n        });\n      }\n    }\n    // just proceed if we not head blocking\n    return callback(ctx);\n  }\n\n  /**\n   *  The HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n   *\n   * @param {Element} oldHead\n   * @param {Element} newHead\n   * @param {MorphContext} ctx\n   * @returns {Promise<void>[]}\n   */\n  function handleHeadElement(oldHead, newHead, ctx) {\n    let added = [];\n    let removed = [];\n    let preserved = [];\n    let nodesToAppend = [];\n\n    // put all new head elements into a Map, by their outerHTML\n    let srcToNewHeadNodes = new Map();\n    for (const newHeadChild of newHead.children) {\n      srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n    }\n\n    // for each elt in the current head\n    for (const currentHeadElt of oldHead.children) {\n      // If the current head element is in the map\n      let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n      let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n      let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n      if (inNewContent || isPreserved) {\n        if (isReAppended) {\n          // remove the current version and let the new version replace it and re-execute\n          removed.push(currentHeadElt);\n        } else {\n          // this element already exists and should not be re-appended, so remove it from\n          // the new content map, preserving it in the DOM\n          srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n          preserved.push(currentHeadElt);\n        }\n      } else {\n        if (ctx.head.style === \"append\") {\n          // we are appending and this existing element is not new content\n          // so if and only if it is marked for re-append do we do anything\n          if (isReAppended) {\n            removed.push(currentHeadElt);\n            nodesToAppend.push(currentHeadElt);\n          }\n        } else {\n          // if this is a merge, we remove this content since it is not in the new head\n          if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n            removed.push(currentHeadElt);\n          }\n        }\n      }\n    }\n\n    // Push the remaining new head elements in the Map into the\n    // nodes to append to the head tag\n    nodesToAppend.push(...srcToNewHeadNodes.values());\n\n    let promises = [];\n    for (const newNode of nodesToAppend) {\n      // TODO: This could theoretically be null, based on type\n      let newElt = /** @type {ChildNode} */ (\n        document.createRange().createContextualFragment(newNode.outerHTML)\n          .firstChild\n      );\n      if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n        if (\n          (\"href\" in newElt && newElt.href) ||\n          (\"src\" in newElt && newElt.src)\n        ) {\n          /** @type {(result?: any) => void} */ let resolve;\n          let promise = new Promise(function (_resolve) {\n            resolve = _resolve;\n          });\n          newElt.addEventListener(\"load\", function () {\n            resolve();\n          });\n          promises.push(promise);\n        }\n        oldHead.appendChild(newElt);\n        ctx.callbacks.afterNodeAdded(newElt);\n        added.push(newElt);\n      }\n    }\n\n    // remove all removed elements, after we have appended the new elements to avoid\n    // additional network requests for things like style sheets\n    for (const removedElement of removed) {\n      if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n        oldHead.removeChild(removedElement);\n        ctx.callbacks.afterNodeRemoved(removedElement);\n      }\n    }\n\n    ctx.head.afterHeadMorphed(oldHead, {\n      added: added,\n      kept: preserved,\n      removed: removed,\n    });\n    return promises;\n  }\n\n  //=============================================================================\n  // Create Morph Context Functions\n  //=============================================================================\n  const createMorphContext = (function () {\n    /**\n     *\n     * @param {Element} oldNode\n     * @param {Element} newContent\n     * @param {Config} config\n     * @returns {MorphContext}\n     */\n    function createMorphContext(oldNode, newContent, config) {\n      const { persistentIds, idMap } = createIdMaps(oldNode, newContent);\n\n      const mergedConfig = mergeDefaults(config);\n      const morphStyle = mergedConfig.morphStyle || \"outerHTML\";\n      if (![\"innerHTML\", \"outerHTML\"].includes(morphStyle)) {\n        throw `Do not understand how to morph style ${morphStyle}`;\n      }\n\n      return {\n        target: oldNode,\n        newContent: newContent,\n        config: mergedConfig,\n        morphStyle: morphStyle,\n        ignoreActive: mergedConfig.ignoreActive,\n        ignoreActiveValue: mergedConfig.ignoreActiveValue,\n        restoreFocus: mergedConfig.restoreFocus,\n        idMap: idMap,\n        persistentIds: persistentIds,\n        pantry: createPantry(),\n        activeElementAndParents: createActiveElementAndParents(oldNode),\n        callbacks: mergedConfig.callbacks,\n        head: mergedConfig.head,\n      };\n    }\n\n    /**\n     * Deep merges the config object and the Idiomorph.defaults object to\n     * produce a final configuration object\n     * @param {Config} config\n     * @returns {ConfigInternal}\n     */\n    function mergeDefaults(config) {\n      let finalConfig = Object.assign({}, defaults);\n\n      // copy top level stuff into final config\n      Object.assign(finalConfig, config);\n\n      // copy callbacks into final config (do this to deep merge the callbacks)\n      finalConfig.callbacks = Object.assign(\n        {},\n        defaults.callbacks,\n        config.callbacks,\n      );\n\n      // copy head config into final config  (do this to deep merge the head)\n      finalConfig.head = Object.assign({}, defaults.head, config.head);\n\n      return finalConfig;\n    }\n\n    /**\n     * @returns {HTMLDivElement}\n     */\n    function createPantry() {\n      const pantry = document.createElement(\"div\");\n      pantry.hidden = true;\n      document.body.insertAdjacentElement(\"afterend\", pantry);\n      return pantry;\n    }\n\n    /**\n     * @param {Element} oldNode\n     * @returns {Element[]}\n     */\n    function createActiveElementAndParents(oldNode) {\n      /** @type {Element[]} */\n      let activeElementAndParents = [];\n      let elt = document.activeElement;\n      if (elt?.tagName !== \"BODY\" && oldNode.contains(elt)) {\n        while (elt) {\n          activeElementAndParents.push(elt);\n          if (elt === oldNode) break;\n          elt = elt.parentElement;\n        }\n      }\n      return activeElementAndParents;\n    }\n\n    /**\n     * Returns all elements with an ID contained within the root element and its descendants\n     *\n     * @param {Element} root\n     * @returns {Element[]}\n     */\n    function findIdElements(root) {\n      let elements = Array.from(root.querySelectorAll(\"[id]\"));\n      // root could be a document fragment which doesn't have `getAttribute`\n      if (root.getAttribute?.(\"id\")) {\n        elements.push(root);\n      }\n      return elements;\n    }\n\n    /**\n     * A bottom-up algorithm that populates a map of Element -> IdSet.\n     * The idSet for a given element is the set of all IDs contained within its subtree.\n     * As an optimzation, we filter these IDs through the given list of persistent IDs,\n     * because we don't need to bother considering IDed elements that won't be in the new content.\n     *\n     * @param {Map<Node, Set<string>>} idMap\n     * @param {Set<string>} persistentIds\n     * @param {Element} root\n     * @param {Element[]} elements\n     */\n    function populateIdMapWithTree(idMap, persistentIds, root, elements) {\n      for (const elt of elements) {\n        // we can pretend id is non-null String, because the .has line will reject it immediately if not\n        const id = /** @type {String} */ (elt.getAttribute(\"id\"));\n        if (persistentIds.has(id)) {\n          /** @type {Element|null} */\n          let current = elt;\n          // walk up the parent hierarchy of that element, adding the id\n          // of element to the parent's id set\n          while (current) {\n            let idSet = idMap.get(current);\n            // if the id set doesn't exist, create it and insert it in the map\n            if (idSet == null) {\n              idSet = new Set();\n              idMap.set(current, idSet);\n            }\n            idSet.add(id);\n\n            if (current === root) break;\n            current = current.parentElement;\n          }\n        }\n      }\n    }\n\n    /**\n     * This function computes a map of nodes to all ids contained within that node (inclusive of the\n     * node).  This map can be used to ask if two nodes have intersecting sets of ids, which allows\n     * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n     * to contribute to a parent nodes matching.\n     *\n     * @param {Element} oldContent  the old content that will be morphed\n     * @param {Element} newContent  the new content to morph to\n     * @returns {IdSets}\n     */\n    function createIdMaps(oldContent, newContent) {\n      const oldIdElements = findIdElements(oldContent);\n      const newIdElements = findIdElements(newContent);\n\n      const persistentIds = createPersistentIds(oldIdElements, newIdElements);\n\n      /** @type {Map<Node, Set<string>>} */\n      let idMap = new Map();\n      populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements);\n\n      /** @ts-ignore - if newContent is a duck-typed parent, pass its single child node as the root to halt upwards iteration */\n      const newRoot = newContent.__idiomorphRoot || newContent;\n      populateIdMapWithTree(idMap, persistentIds, newRoot, newIdElements);\n\n      return { persistentIds, idMap };\n    }\n\n    /**\n     * This function computes the set of ids that persist between the two contents excluding duplicates\n     *\n     * @param {Element[]} oldIdElements\n     * @param {Element[]} newIdElements\n     * @returns {Set<string>}\n     */\n    function createPersistentIds(oldIdElements, newIdElements) {\n      let duplicateIds = new Set();\n\n      /** @type {Map<string, string>} */\n      let oldIdTagNameMap = new Map();\n      for (const { id, tagName } of oldIdElements) {\n        if (oldIdTagNameMap.has(id)) {\n          duplicateIds.add(id);\n        } else {\n          oldIdTagNameMap.set(id, tagName);\n        }\n      }\n\n      let persistentIds = new Set();\n      for (const { id, tagName } of newIdElements) {\n        if (persistentIds.has(id)) {\n          duplicateIds.add(id);\n        } else if (oldIdTagNameMap.get(id) === tagName) {\n          persistentIds.add(id);\n        }\n        // skip if tag types mismatch because its not possible to morph one tag into another\n      }\n\n      for (const id of duplicateIds) {\n        persistentIds.delete(id);\n      }\n      return persistentIds;\n    }\n\n    return createMorphContext;\n  })();\n\n  //=============================================================================\n  // HTML Normalization Functions\n  //=============================================================================\n  const { normalizeElement, normalizeParent } = (function () {\n    /** @type {WeakSet<Node>} */\n    const generatedByIdiomorph = new WeakSet();\n\n    /**\n     *\n     * @param {Element | Document} content\n     * @returns {Element}\n     */\n    function normalizeElement(content) {\n      if (content instanceof Document) {\n        return content.documentElement;\n      } else {\n        return content;\n      }\n    }\n\n    /**\n     *\n     * @param {null | string | Node | HTMLCollection | Node[] | Document & {generatedByIdiomorph:boolean}} newContent\n     * @returns {Element}\n     */\n    function normalizeParent(newContent) {\n      if (newContent == null) {\n        return document.createElement(\"div\"); // dummy parent element\n      } else if (typeof newContent === \"string\") {\n        return normalizeParent(parseContent(newContent));\n      } else if (\n        generatedByIdiomorph.has(/** @type {Element} */ (newContent))\n      ) {\n        // the template tag created by idiomorph parsing can serve as a dummy parent\n        return /** @type {Element} */ (newContent);\n      } else if (newContent instanceof Node) {\n        if (newContent.parentNode) {\n          // we can't use the parent directly because newContent may have siblings\n          // that we don't want in the morph, and reparenting might be expensive (TODO is it?),\n          // so instead we create a fake parent node that only sees a slice of its children.\n          /** @type {Element} */\n          return /** @type {any} */ (new SlicedParentNode(newContent));\n        } else {\n          // a single node is added as a child to a dummy parent\n          const dummyParent = document.createElement(\"div\");\n          dummyParent.append(newContent);\n          return dummyParent;\n        }\n      } else {\n        // all nodes in the array or HTMLElement collection are consolidated under\n        // a single dummy parent element\n        const dummyParent = document.createElement(\"div\");\n        for (const elt of [...newContent]) {\n          dummyParent.append(elt);\n        }\n        return dummyParent;\n      }\n    }\n\n    /**\n     * A fake duck-typed parent element to wrap a single node, without actually reparenting it.\n     * This is useful because the node may have siblings that we don't want in the morph, and it may also be moved\n     * or replaced with one or more elements during the morph. This class effectively allows us a window into\n     * a slice of a node's children.\n     * \"If it walks like a duck, and quacks like a duck, then it must be a duck!\" -- James Whitcomb Riley (1849\u20131916)\n     */\n    class SlicedParentNode {\n      /** @param {Node} node */\n      constructor(node) {\n        this.originalNode = node;\n        this.realParentNode = /** @type {Element} */ (node.parentNode);\n        this.previousSibling = node.previousSibling;\n        this.nextSibling = node.nextSibling;\n      }\n\n      /** @returns {Node[]} */\n      get childNodes() {\n        // return slice of realParent's current childNodes, based on previousSibling and nextSibling\n        const nodes = [];\n        let cursor = this.previousSibling\n          ? this.previousSibling.nextSibling\n          : this.realParentNode.firstChild;\n        while (cursor && cursor != this.nextSibling) {\n          nodes.push(cursor);\n          cursor = cursor.nextSibling;\n        }\n        return nodes;\n      }\n\n      /**\n       * @param {string} selector\n       * @returns {Element[]}\n       */\n      querySelectorAll(selector) {\n        return this.childNodes.reduce((results, node) => {\n          if (node instanceof Element) {\n            if (node.matches(selector)) results.push(node);\n            const nodeList = node.querySelectorAll(selector);\n            for (let i = 0; i < nodeList.length; i++) {\n              results.push(nodeList[i]);\n            }\n          }\n          return results;\n        }, /** @type {Element[]} */ ([]));\n      }\n\n      /**\n       * @param {Node} node\n       * @param {Node} referenceNode\n       * @returns {Node}\n       */\n      insertBefore(node, referenceNode) {\n        return this.realParentNode.insertBefore(node, referenceNode);\n      }\n\n      /**\n       * @param {Node} node\n       * @param {Node} referenceNode\n       * @returns {Node}\n       */\n      moveBefore(node, referenceNode) {\n        // @ts-ignore - use new moveBefore feature\n        return this.realParentNode.moveBefore(node, referenceNode);\n      }\n\n      /**\n       * for later use with populateIdMapWithTree to halt upwards iteration\n       * @returns {Node}\n       */\n      get __idiomorphRoot() {\n        return this.originalNode;\n      }\n    }\n\n    /**\n     *\n     * @param {string} newContent\n     * @returns {Node | null | DocumentFragment}\n     */\n    function parseContent(newContent) {\n      let parser = new DOMParser();\n\n      // remove svgs to avoid false-positive matches on head, etc.\n      let contentWithSvgsRemoved = newContent.replace(\n        /<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n        \"\",\n      );\n\n      // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n      if (\n        contentWithSvgsRemoved.match(/<\\/html>/) ||\n        contentWithSvgsRemoved.match(/<\\/head>/) ||\n        contentWithSvgsRemoved.match(/<\\/body>/)\n      ) {\n        let content = parser.parseFromString(newContent, \"text/html\");\n        // if it is a full HTML document, return the document itself as the parent container\n        if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n          generatedByIdiomorph.add(content);\n          return content;\n        } else {\n          // otherwise return the html element as the parent container\n          let htmlElement = content.firstChild;\n          if (htmlElement) {\n            generatedByIdiomorph.add(htmlElement);\n          }\n          return htmlElement;\n        }\n      } else {\n        // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n        // deal with touchy tags like tr, tbody, etc.\n        let responseDoc = parser.parseFromString(\n          \"<body><template>\" + newContent + \"</template></body>\",\n          \"text/html\",\n        );\n        let content = /** @type {HTMLTemplateElement} */ (\n          responseDoc.body.querySelector(\"template\")\n        ).content;\n        generatedByIdiomorph.add(content);\n        return content;\n      }\n    }\n\n    return { normalizeElement, normalizeParent };\n  })();\n\n  //=============================================================================\n  // This is what ends up becoming the Idiomorph global object\n  //=============================================================================\n  return {\n    morph,\n    defaults,\n  };\n})();\n\n/**\n * Morph the state of the currentElement based on the attributes and contents of\n * the newElement. Morphing may dispatch turbo:before-morph-element,\n * turbo:before-morph-attribute, and turbo:morph-element events.\n *\n * @param currentElement Element destination of morphing changes\n * @param newElement Element source of morphing changes\n */\nfunction morphElements(currentElement, newElement, { callbacks, ...options } = {}) {\n  Idiomorph.morph(currentElement, newElement, {\n    ...options,\n    callbacks: new DefaultIdiomorphCallbacks(callbacks)\n  });\n}\n\n/**\n * Morph the child elements of the currentElement based on the child elements of\n * the newElement. Morphing children may dispatch turbo:before-morph-element,\n * turbo:before-morph-attribute, and turbo:morph-element events.\n *\n * @param currentElement Element destination of morphing children changes\n * @param newElement Element source of morphing children changes\n */\nfunction morphChildren(currentElement, newElement, options = {}) {\n  morphElements(currentElement, newElement.childNodes, {\n    ...options,\n    morphStyle: \"innerHTML\"\n  });\n}\n\nfunction shouldRefreshFrameWithMorphing(currentFrame, newFrame) {\n  return currentFrame instanceof FrameElement &&\n    currentFrame.shouldReloadWithMorph && (!newFrame || areFramesCompatibleForRefreshing(currentFrame, newFrame)) &&\n    !currentFrame.closest(\"[data-turbo-permanent]\")\n}\n\nfunction areFramesCompatibleForRefreshing(currentFrame, newFrame) {\n  // newFrame cannot yet be an instance of FrameElement because custom\n  // elements don't get initialized until they're attached to the DOM, so\n  // test its Element#nodeName instead\n  return newFrame instanceof Element && newFrame.nodeName === \"TURBO-FRAME\" && currentFrame.id === newFrame.id &&\n  (!newFrame.getAttribute(\"src\") || urlsAreEqual(currentFrame.src, newFrame.getAttribute(\"src\")))\n}\n\nfunction closestFrameReloadableWithMorphing(node) {\n  return node.parentElement.closest(\"turbo-frame[src][refresh=morph]\")\n}\n\nclass DefaultIdiomorphCallbacks {\n  #beforeNodeMorphed\n\n  constructor({ beforeNodeMorphed } = {}) {\n    this.#beforeNodeMorphed = beforeNodeMorphed || (() => true);\n  }\n\n  beforeNodeAdded = (node) => {\n    return !(node.id && node.hasAttribute(\"data-turbo-permanent\") && document.getElementById(node.id))\n  }\n\n  beforeNodeMorphed = (currentElement, newElement) => {\n    if (currentElement instanceof Element) {\n      if (!currentElement.hasAttribute(\"data-turbo-permanent\") && this.#beforeNodeMorphed(currentElement, newElement)) {\n        const event = dispatch(\"turbo:before-morph-element\", {\n          cancelable: true,\n          target: currentElement,\n          detail: { currentElement, newElement }\n        });\n\n        return !event.defaultPrevented\n      } else {\n        return false\n      }\n    }\n  }\n\n  beforeAttributeUpdated = (attributeName, target, mutationType) => {\n    const event = dispatch(\"turbo:before-morph-attribute\", {\n      cancelable: true,\n      target,\n      detail: { attributeName, mutationType }\n    });\n\n    return !event.defaultPrevented\n  }\n\n  beforeNodeRemoved = (node) => {\n    return this.beforeNodeMorphed(node)\n  }\n\n  afterNodeMorphed = (currentElement, newElement) => {\n    if (currentElement instanceof Element) {\n      dispatch(\"turbo:morph-element\", {\n        target: currentElement,\n        detail: { currentElement, newElement }\n      });\n    }\n  }\n}\n\nclass MorphingFrameRenderer extends FrameRenderer {\n  static renderElement(currentElement, newElement) {\n    dispatch(\"turbo:before-frame-morph\", {\n      target: currentElement,\n      detail: { currentElement, newElement }\n    });\n\n    morphChildren(currentElement, newElement, {\n      callbacks: {\n        beforeNodeMorphed: (node, newNode) => {\n          if (\n            shouldRefreshFrameWithMorphing(node, newNode) &&\n              closestFrameReloadableWithMorphing(node) === currentElement\n          ) {\n            node.reload();\n            return false\n          }\n          return true\n        }\n      }\n    });\n  }\n\n  async preservingPermanentElements(callback) {\n    return await callback()\n  }\n}\n\nclass ProgressBar {\n  static animationDuration = 300 /*ms*/\n\n  static get defaultCSS() {\n    return unindent`\n      .turbo-progress-bar {\n        position: fixed;\n        display: block;\n        top: 0;\n        left: 0;\n        height: 3px;\n        background: #0076ff;\n        z-index: 2147483647;\n        transition:\n          width ${ProgressBar.animationDuration}ms ease-out,\n          opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in;\n        transform: translate3d(0, 0, 0);\n      }\n    `\n  }\n\n  hiding = false\n  value = 0\n  visible = false\n\n  constructor() {\n    this.stylesheetElement = this.createStylesheetElement();\n    this.progressElement = this.createProgressElement();\n    this.installStylesheetElement();\n    this.setValue(0);\n  }\n\n  show() {\n    if (!this.visible) {\n      this.visible = true;\n      this.installProgressElement();\n      this.startTrickling();\n    }\n  }\n\n  hide() {\n    if (this.visible && !this.hiding) {\n      this.hiding = true;\n      this.fadeProgressElement(() => {\n        this.uninstallProgressElement();\n        this.stopTrickling();\n        this.visible = false;\n        this.hiding = false;\n      });\n    }\n  }\n\n  setValue(value) {\n    this.value = value;\n    this.refresh();\n  }\n\n  // Private\n\n  installStylesheetElement() {\n    document.head.insertBefore(this.stylesheetElement, document.head.firstChild);\n  }\n\n  installProgressElement() {\n    this.progressElement.style.width = \"0\";\n    this.progressElement.style.opacity = \"1\";\n    document.documentElement.insertBefore(this.progressElement, document.body);\n    this.refresh();\n  }\n\n  fadeProgressElement(callback) {\n    this.progressElement.style.opacity = \"0\";\n    setTimeout(callback, ProgressBar.animationDuration * 1.5);\n  }\n\n  uninstallProgressElement() {\n    if (this.progressElement.parentNode) {\n      document.documentElement.removeChild(this.progressElement);\n    }\n  }\n\n  startTrickling() {\n    if (!this.trickleInterval) {\n      this.trickleInterval = window.setInterval(this.trickle, ProgressBar.animationDuration);\n    }\n  }\n\n  stopTrickling() {\n    window.clearInterval(this.trickleInterval);\n    delete this.trickleInterval;\n  }\n\n  trickle = () => {\n    this.setValue(this.value + Math.random() / 100);\n  }\n\n  refresh() {\n    requestAnimationFrame(() => {\n      this.progressElement.style.width = `${10 + this.value * 90}%`;\n    });\n  }\n\n  createStylesheetElement() {\n    const element = document.createElement(\"style\");\n    element.type = \"text/css\";\n    element.textContent = ProgressBar.defaultCSS;\n    const cspNonce = getCspNonce();\n    if (cspNonce) {\n      element.nonce = cspNonce;\n    }\n    return element\n  }\n\n  createProgressElement() {\n    const element = document.createElement(\"div\");\n    element.className = \"turbo-progress-bar\";\n    return element\n  }\n}\n\nclass HeadSnapshot extends Snapshot {\n  detailsByOuterHTML = this.children\n    .filter((element) => !elementIsNoscript(element))\n    .map((element) => elementWithoutNonce(element))\n    .reduce((result, element) => {\n      const { outerHTML } = element;\n      const details =\n        outerHTML in result\n          ? result[outerHTML]\n          : {\n              type: elementType(element),\n              tracked: elementIsTracked(element),\n              elements: []\n            };\n      return {\n        ...result,\n        [outerHTML]: {\n          ...details,\n          elements: [...details.elements, element]\n        }\n      }\n    }, {})\n\n  get trackedElementSignature() {\n    return Object.keys(this.detailsByOuterHTML)\n      .filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked)\n      .join(\"\")\n  }\n\n  getScriptElementsNotInSnapshot(snapshot) {\n    return this.getElementsMatchingTypeNotInSnapshot(\"script\", snapshot)\n  }\n\n  getStylesheetElementsNotInSnapshot(snapshot) {\n    return this.getElementsMatchingTypeNotInSnapshot(\"stylesheet\", snapshot)\n  }\n\n  getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) {\n    return Object.keys(this.detailsByOuterHTML)\n      .filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML))\n      .map((outerHTML) => this.detailsByOuterHTML[outerHTML])\n      .filter(({ type }) => type == matchedType)\n      .map(({ elements: [element] }) => element)\n  }\n\n  get provisionalElements() {\n    return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {\n      const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML];\n      if (type == null && !tracked) {\n        return [...result, ...elements]\n      } else if (elements.length > 1) {\n        return [...result, ...elements.slice(1)]\n      } else {\n        return result\n      }\n    }, [])\n  }\n\n  getMetaValue(name) {\n    const element = this.findMetaElementByName(name);\n    return element ? element.getAttribute(\"content\") : null\n  }\n\n  findMetaElementByName(name) {\n    return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {\n      const {\n        elements: [element]\n      } = this.detailsByOuterHTML[outerHTML];\n      return elementIsMetaElementWithName(element, name) ? element : result\n    }, undefined | undefined)\n  }\n}\n\nfunction elementType(element) {\n  if (elementIsScript(element)) {\n    return \"script\"\n  } else if (elementIsStylesheet(element)) {\n    return \"stylesheet\"\n  }\n}\n\nfunction elementIsTracked(element) {\n  return element.getAttribute(\"data-turbo-track\") == \"reload\"\n}\n\nfunction elementIsScript(element) {\n  const tagName = element.localName;\n  return tagName == \"script\"\n}\n\nfunction elementIsNoscript(element) {\n  const tagName = element.localName;\n  return tagName == \"noscript\"\n}\n\nfunction elementIsStylesheet(element) {\n  const tagName = element.localName;\n  return tagName == \"style\" || (tagName == \"link\" && element.getAttribute(\"rel\") == \"stylesheet\")\n}\n\nfunction elementIsMetaElementWithName(element, name) {\n  const tagName = element.localName;\n  return tagName == \"meta\" && element.getAttribute(\"name\") == name\n}\n\nfunction elementWithoutNonce(element) {\n  if (element.hasAttribute(\"nonce\")) {\n    element.setAttribute(\"nonce\", \"\");\n  }\n\n  return element\n}\n\nclass PageSnapshot extends Snapshot {\n  static fromHTMLString(html = \"\") {\n    return this.fromDocument(parseHTMLDocument(html))\n  }\n\n  static fromElement(element) {\n    return this.fromDocument(element.ownerDocument)\n  }\n\n  static fromDocument({ documentElement, body, head }) {\n    return new this(documentElement, body, new HeadSnapshot(head))\n  }\n\n  constructor(documentElement, body, headSnapshot) {\n    super(body);\n    this.documentElement = documentElement;\n    this.headSnapshot = headSnapshot;\n  }\n\n  clone() {\n    const clonedElement = this.element.cloneNode(true);\n\n    const selectElements = this.element.querySelectorAll(\"select\");\n    const clonedSelectElements = clonedElement.querySelectorAll(\"select\");\n\n    for (const [index, source] of selectElements.entries()) {\n      const clone = clonedSelectElements[index];\n      for (const option of clone.selectedOptions) option.selected = false;\n      for (const option of source.selectedOptions) clone.options[option.index].selected = true;\n    }\n\n    for (const clonedPasswordInput of clonedElement.querySelectorAll('input[type=\"password\"]')) {\n      clonedPasswordInput.value = \"\";\n    }\n\n    for (const clonedNoscriptElement of clonedElement.querySelectorAll(\"noscript\")) {\n      clonedNoscriptElement.remove();\n    }\n\n    return new PageSnapshot(this.documentElement, clonedElement, this.headSnapshot)\n  }\n\n  get lang() {\n    return this.documentElement.getAttribute(\"lang\")\n  }\n\n  get dir() {\n    return this.documentElement.getAttribute(\"dir\")\n  }\n\n  get headElement() {\n    return this.headSnapshot.element\n  }\n\n  get rootLocation() {\n    const root = this.getSetting(\"root\") ?? \"/\";\n    return expandURL(root)\n  }\n\n  get cacheControlValue() {\n    return this.getSetting(\"cache-control\")\n  }\n\n  get isPreviewable() {\n    return this.cacheControlValue != \"no-preview\"\n  }\n\n  get isCacheable() {\n    return this.cacheControlValue != \"no-cache\"\n  }\n\n  get isVisitable() {\n    return this.getSetting(\"visit-control\") != \"reload\"\n  }\n\n  get prefersViewTransitions() {\n    const viewTransitionEnabled = this.getSetting(\"view-transition\") === \"true\" || this.headSnapshot.getMetaValue(\"view-transition\") === \"same-origin\";\n    return viewTransitionEnabled && !window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n  }\n\n  get refreshMethod() {\n    return this.getSetting(\"refresh-method\")\n  }\n\n  get refreshScroll() {\n    return this.getSetting(\"refresh-scroll\")\n  }\n\n  // Private\n\n  getSetting(name) {\n    return this.headSnapshot.getMetaValue(`turbo-${name}`)\n  }\n}\n\nclass ViewTransitioner {\n  #viewTransitionStarted = false\n  #lastOperation = Promise.resolve()\n\n  renderChange(useViewTransition, render) {\n    if (useViewTransition && this.viewTransitionsAvailable && !this.#viewTransitionStarted) {\n      this.#viewTransitionStarted = true;\n      this.#lastOperation = this.#lastOperation.then(async () => {\n        await document.startViewTransition(render).finished;\n      });\n    } else {\n      this.#lastOperation = this.#lastOperation.then(render);\n    }\n\n    return this.#lastOperation\n  }\n\n  get viewTransitionsAvailable() {\n    return document.startViewTransition\n  }\n}\n\nconst defaultOptions = {\n  action: \"advance\",\n  historyChanged: false,\n  visitCachedSnapshot: () => {},\n  willRender: true,\n  updateHistory: true,\n  shouldCacheSnapshot: true,\n  acceptsStreamResponse: false,\n  refresh: {}\n};\n\nconst TimingMetric = {\n  visitStart: \"visitStart\",\n  requestStart: \"requestStart\",\n  requestEnd: \"requestEnd\",\n  visitEnd: \"visitEnd\"\n};\n\nconst VisitState = {\n  initialized: \"initialized\",\n  started: \"started\",\n  canceled: \"canceled\",\n  failed: \"failed\",\n  completed: \"completed\"\n};\n\nconst SystemStatusCode = {\n  networkFailure: 0,\n  timeoutFailure: -1,\n  contentTypeMismatch: -2\n};\n\nconst Direction = {\n  advance: \"forward\",\n  restore: \"back\",\n  replace: \"none\"\n};\n\nclass Visit {\n  identifier = uuid() // Required by turbo-ios\n  timingMetrics = {}\n\n  followedRedirect = false\n  historyChanged = false\n  scrolled = false\n  shouldCacheSnapshot = true\n  acceptsStreamResponse = false\n  snapshotCached = false\n  state = VisitState.initialized\n  viewTransitioner = new ViewTransitioner()\n\n  constructor(delegate, location, restorationIdentifier, options = {}) {\n    this.delegate = delegate;\n    this.location = location;\n    this.restorationIdentifier = restorationIdentifier || uuid();\n\n    const {\n      action,\n      historyChanged,\n      referrer,\n      snapshot,\n      snapshotHTML,\n      response,\n      visitCachedSnapshot,\n      willRender,\n      updateHistory,\n      shouldCacheSnapshot,\n      acceptsStreamResponse,\n      direction,\n      refresh\n    } = {\n      ...defaultOptions,\n      ...options\n    };\n    this.action = action;\n    this.historyChanged = historyChanged;\n    this.referrer = referrer;\n    this.snapshot = snapshot;\n    this.snapshotHTML = snapshotHTML;\n    this.response = response;\n    this.isPageRefresh = this.view.isPageRefresh(this);\n    this.visitCachedSnapshot = visitCachedSnapshot;\n    this.willRender = willRender;\n    this.updateHistory = updateHistory;\n    this.scrolled = !willRender;\n    this.shouldCacheSnapshot = shouldCacheSnapshot;\n    this.acceptsStreamResponse = acceptsStreamResponse;\n    this.direction = direction || Direction[action];\n    this.refresh = refresh;\n  }\n\n  get adapter() {\n    return this.delegate.adapter\n  }\n\n  get view() {\n    return this.delegate.view\n  }\n\n  get history() {\n    return this.delegate.history\n  }\n\n  get restorationData() {\n    return this.history.getRestorationDataForIdentifier(this.restorationIdentifier)\n  }\n\n  start() {\n    if (this.state == VisitState.initialized) {\n      this.recordTimingMetric(TimingMetric.visitStart);\n      this.state = VisitState.started;\n      this.adapter.visitStarted(this);\n      this.delegate.visitStarted(this);\n    }\n  }\n\n  cancel() {\n    if (this.state == VisitState.started) {\n      if (this.request) {\n        this.request.cancel();\n      }\n      this.cancelRender();\n      this.state = VisitState.canceled;\n    }\n  }\n\n  complete() {\n    if (this.state == VisitState.started) {\n      this.recordTimingMetric(TimingMetric.visitEnd);\n      this.adapter.visitCompleted(this);\n      this.state = VisitState.completed;\n      this.followRedirect();\n\n      if (!this.followedRedirect) {\n        this.delegate.visitCompleted(this);\n      }\n    }\n  }\n\n  fail() {\n    if (this.state == VisitState.started) {\n      this.state = VisitState.failed;\n      this.adapter.visitFailed(this);\n      this.delegate.visitCompleted(this);\n    }\n  }\n\n  changeHistory() {\n    if (!this.historyChanged && this.updateHistory) {\n      const actionForHistory = this.location.href === this.referrer?.href ? \"replace\" : this.action;\n      const method = getHistoryMethodForAction(actionForHistory);\n      this.history.update(method, this.location, this.restorationIdentifier);\n      this.historyChanged = true;\n    }\n  }\n\n  issueRequest() {\n    if (this.hasPreloadedResponse()) {\n      this.simulateRequest();\n    } else if (this.shouldIssueRequest() && !this.request) {\n      this.request = new FetchRequest(this, FetchMethod.get, this.location);\n      this.request.perform();\n    }\n  }\n\n  simulateRequest() {\n    if (this.response) {\n      this.startRequest();\n      this.recordResponse();\n      this.finishRequest();\n    }\n  }\n\n  startRequest() {\n    this.recordTimingMetric(TimingMetric.requestStart);\n    this.adapter.visitRequestStarted(this);\n  }\n\n  recordResponse(response = this.response) {\n    this.response = response;\n    if (response) {\n      const { statusCode } = response;\n      if (isSuccessful(statusCode)) {\n        this.adapter.visitRequestCompleted(this);\n      } else {\n        this.adapter.visitRequestFailedWithStatusCode(this, statusCode);\n      }\n    }\n  }\n\n  finishRequest() {\n    this.recordTimingMetric(TimingMetric.requestEnd);\n    this.adapter.visitRequestFinished(this);\n  }\n\n  loadResponse() {\n    if (this.response) {\n      const { statusCode, responseHTML } = this.response;\n      this.render(async () => {\n        if (this.shouldCacheSnapshot) this.cacheSnapshot();\n        if (this.view.renderPromise) await this.view.renderPromise;\n\n        if (isSuccessful(statusCode) && responseHTML != null) {\n          const snapshot = PageSnapshot.fromHTMLString(responseHTML);\n          await this.renderPageSnapshot(snapshot, false);\n\n          this.adapter.visitRendered(this);\n          this.complete();\n        } else {\n          await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this);\n          this.adapter.visitRendered(this);\n          this.fail();\n        }\n      });\n    }\n  }\n\n  getCachedSnapshot() {\n    const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot();\n\n    if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) {\n      if (this.action == \"restore\" || snapshot.isPreviewable) {\n        return snapshot\n      }\n    }\n  }\n\n  getPreloadedSnapshot() {\n    if (this.snapshotHTML) {\n      return PageSnapshot.fromHTMLString(this.snapshotHTML)\n    }\n  }\n\n  hasCachedSnapshot() {\n    return this.getCachedSnapshot() != null\n  }\n\n  loadCachedSnapshot() {\n    const snapshot = this.getCachedSnapshot();\n    if (snapshot) {\n      const isPreview = this.shouldIssueRequest();\n      this.render(async () => {\n        this.cacheSnapshot();\n        if (this.isPageRefresh) {\n          this.adapter.visitRendered(this);\n        } else {\n          if (this.view.renderPromise) await this.view.renderPromise;\n\n          await this.renderPageSnapshot(snapshot, isPreview);\n\n          this.adapter.visitRendered(this);\n          if (!isPreview) {\n            this.complete();\n          }\n        }\n      });\n    }\n  }\n\n  followRedirect() {\n    if (this.redirectedToLocation && !this.followedRedirect && this.response?.redirected) {\n      this.adapter.visitProposedToLocation(this.redirectedToLocation, {\n        action: \"replace\",\n        response: this.response,\n        shouldCacheSnapshot: false,\n        willRender: false\n      });\n      this.followedRedirect = true;\n    }\n  }\n\n  // Fetch request delegate\n\n  prepareRequest(request) {\n    if (this.acceptsStreamResponse) {\n      request.acceptResponseType(StreamMessage.contentType);\n    }\n  }\n\n  requestStarted() {\n    this.startRequest();\n  }\n\n  requestPreventedHandlingResponse(_request, _response) {}\n\n  async requestSucceededWithResponse(request, response) {\n    const responseHTML = await response.responseHTML;\n    const { redirected, statusCode } = response;\n    if (responseHTML == undefined) {\n      this.recordResponse({\n        statusCode: SystemStatusCode.contentTypeMismatch,\n        redirected\n      });\n    } else {\n      this.redirectedToLocation = response.redirected ? response.location : undefined;\n      this.recordResponse({ statusCode: statusCode, responseHTML, redirected });\n    }\n  }\n\n  async requestFailedWithResponse(request, response) {\n    const responseHTML = await response.responseHTML;\n    const { redirected, statusCode } = response;\n    if (responseHTML == undefined) {\n      this.recordResponse({\n        statusCode: SystemStatusCode.contentTypeMismatch,\n        redirected\n      });\n    } else {\n      this.recordResponse({ statusCode: statusCode, responseHTML, redirected });\n    }\n  }\n\n  requestErrored(_request, _error) {\n    this.recordResponse({\n      statusCode: SystemStatusCode.networkFailure,\n      redirected: false\n    });\n  }\n\n  requestFinished() {\n    this.finishRequest();\n  }\n\n  // Scrolling\n\n  performScroll() {\n    if (!this.scrolled && !this.view.forceReloaded && !this.view.shouldPreserveScrollPosition(this)) {\n      if (this.action == \"restore\") {\n        this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop();\n      } else {\n        this.scrollToAnchor() || this.view.scrollToTop();\n      }\n\n      this.scrolled = true;\n    }\n  }\n\n  scrollToRestoredPosition() {\n    const { scrollPosition } = this.restorationData;\n    if (scrollPosition) {\n      this.view.scrollToPosition(scrollPosition);\n      return true\n    }\n  }\n\n  scrollToAnchor() {\n    const anchor = getAnchor(this.location);\n    if (anchor != null) {\n      this.view.scrollToAnchor(anchor);\n      return true\n    }\n  }\n\n  // Instrumentation\n\n  recordTimingMetric(metric) {\n    this.timingMetrics[metric] = new Date().getTime();\n  }\n\n  getTimingMetrics() {\n    return { ...this.timingMetrics }\n  }\n\n  // Private\n\n  hasPreloadedResponse() {\n    return typeof this.response == \"object\"\n  }\n\n  shouldIssueRequest() {\n    if (this.action == \"restore\") {\n      return !this.hasCachedSnapshot()\n    } else {\n      return this.willRender\n    }\n  }\n\n  cacheSnapshot() {\n    if (!this.snapshotCached) {\n      this.view.cacheSnapshot(this.snapshot).then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot));\n      this.snapshotCached = true;\n    }\n  }\n\n  async render(callback) {\n    this.cancelRender();\n    await new Promise((resolve) => {\n      this.frame =\n        document.visibilityState === \"hidden\" ? setTimeout(() => resolve(), 0) : requestAnimationFrame(() => resolve());\n    });\n    await callback();\n    delete this.frame;\n  }\n\n  async renderPageSnapshot(snapshot, isPreview) {\n    await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(snapshot), async () => {\n      await this.view.renderPage(snapshot, isPreview, this.willRender, this);\n      this.performScroll();\n    });\n  }\n\n  cancelRender() {\n    if (this.frame) {\n      cancelAnimationFrame(this.frame);\n      delete this.frame;\n    }\n  }\n}\n\nfunction isSuccessful(statusCode) {\n  return statusCode >= 200 && statusCode < 300\n}\n\nclass BrowserAdapter {\n  progressBar = new ProgressBar()\n\n  constructor(session) {\n    this.session = session;\n  }\n\n  visitProposedToLocation(location, options) {\n    if (locationIsVisitable(location, this.navigator.rootLocation)) {\n      this.navigator.startVisit(location, options?.restorationIdentifier || uuid(), options);\n    } else {\n      window.location.href = location.toString();\n    }\n  }\n\n  visitStarted(visit) {\n    this.location = visit.location;\n    this.redirectedToLocation = null;\n\n    visit.loadCachedSnapshot();\n    visit.issueRequest();\n  }\n\n  visitRequestStarted(visit) {\n    this.progressBar.setValue(0);\n    if (visit.hasCachedSnapshot() || visit.action != \"restore\") {\n      this.showVisitProgressBarAfterDelay();\n    } else {\n      this.showProgressBar();\n    }\n  }\n\n  visitRequestCompleted(visit) {\n    visit.loadResponse();\n\n    if (visit.response.redirected) {\n      this.redirectedToLocation = visit.redirectedToLocation;\n    }\n  }\n\n  visitRequestFailedWithStatusCode(visit, statusCode) {\n    switch (statusCode) {\n      case SystemStatusCode.networkFailure:\n      case SystemStatusCode.timeoutFailure:\n      case SystemStatusCode.contentTypeMismatch:\n        return this.reload({\n          reason: \"request_failed\",\n          context: {\n            statusCode\n          }\n        })\n      default:\n        return visit.loadResponse()\n    }\n  }\n\n  visitRequestFinished(_visit) {}\n\n  visitCompleted(_visit) {\n    this.progressBar.setValue(1);\n    this.hideVisitProgressBar();\n  }\n\n  pageInvalidated(reason) {\n    this.reload(reason);\n  }\n\n  visitFailed(_visit) {\n    this.progressBar.setValue(1);\n    this.hideVisitProgressBar();\n  }\n\n  visitRendered(_visit) {}\n\n  // Link prefetching\n\n  linkPrefetchingIsEnabledForLocation(location) {\n    return true\n  }\n\n  // Form Submission Delegate\n\n  formSubmissionStarted(_formSubmission) {\n    this.progressBar.setValue(0);\n    this.showFormProgressBarAfterDelay();\n  }\n\n  formSubmissionFinished(_formSubmission) {\n    this.progressBar.setValue(1);\n    this.hideFormProgressBar();\n  }\n\n  // Private\n\n  showVisitProgressBarAfterDelay() {\n    this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);\n  }\n\n  hideVisitProgressBar() {\n    this.progressBar.hide();\n    if (this.visitProgressBarTimeout != null) {\n      window.clearTimeout(this.visitProgressBarTimeout);\n      delete this.visitProgressBarTimeout;\n    }\n  }\n\n  showFormProgressBarAfterDelay() {\n    if (this.formProgressBarTimeout == null) {\n      this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);\n    }\n  }\n\n  hideFormProgressBar() {\n    this.progressBar.hide();\n    if (this.formProgressBarTimeout != null) {\n      window.clearTimeout(this.formProgressBarTimeout);\n      delete this.formProgressBarTimeout;\n    }\n  }\n\n  showProgressBar = () => {\n    this.progressBar.show();\n  }\n\n  reload(reason) {\n    dispatch(\"turbo:reload\", { detail: reason });\n\n    window.location.href = (this.redirectedToLocation || this.location)?.toString() || window.location.href;\n  }\n\n  get navigator() {\n    return this.session.navigator\n  }\n}\n\nclass CacheObserver {\n  selector = \"[data-turbo-temporary]\"\n\n  started = false\n\n  start() {\n    if (!this.started) {\n      this.started = true;\n      addEventListener(\"turbo:before-cache\", this.removeTemporaryElements, false);\n    }\n  }\n\n  stop() {\n    if (this.started) {\n      this.started = false;\n      removeEventListener(\"turbo:before-cache\", this.removeTemporaryElements, false);\n    }\n  }\n\n  removeTemporaryElements = (_event) => {\n    for (const element of this.temporaryElements) {\n      element.remove();\n    }\n  }\n\n  get temporaryElements() {\n    return [...document.querySelectorAll(this.selector)]\n  }\n}\n\nclass FrameRedirector {\n  constructor(session, element) {\n    this.session = session;\n    this.element = element;\n    this.linkInterceptor = new LinkInterceptor(this, element);\n    this.formSubmitObserver = new FormSubmitObserver(this, element);\n  }\n\n  start() {\n    this.linkInterceptor.start();\n    this.formSubmitObserver.start();\n  }\n\n  stop() {\n    this.linkInterceptor.stop();\n    this.formSubmitObserver.stop();\n  }\n\n  // Link interceptor delegate\n\n  shouldInterceptLinkClick(element, _location, _event) {\n    return this.#shouldRedirect(element)\n  }\n\n  linkClickIntercepted(element, url, event) {\n    const frame = this.#findFrameElement(element);\n    if (frame) {\n      frame.delegate.linkClickIntercepted(element, url, event);\n    }\n  }\n\n  // Form submit observer delegate\n\n  willSubmitForm(element, submitter) {\n    return (\n      element.closest(\"turbo-frame\") == null &&\n      this.#shouldSubmit(element, submitter) &&\n      this.#shouldRedirect(element, submitter)\n    )\n  }\n\n  formSubmitted(element, submitter) {\n    const frame = this.#findFrameElement(element, submitter);\n    if (frame) {\n      frame.delegate.formSubmitted(element, submitter);\n    }\n  }\n\n  #shouldSubmit(form, submitter) {\n    const action = getAction$1(form, submitter);\n    const meta = this.element.ownerDocument.querySelector(`meta[name=\"turbo-root\"]`);\n    const rootLocation = expandURL(meta?.content ?? \"/\");\n\n    return this.#shouldRedirect(form, submitter) && locationIsVisitable(action, rootLocation)\n  }\n\n  #shouldRedirect(element, submitter) {\n    const isNavigatable =\n      element instanceof HTMLFormElement\n        ? this.session.submissionIsNavigatable(element, submitter)\n        : this.session.elementIsNavigatable(element);\n\n    if (isNavigatable) {\n      const frame = this.#findFrameElement(element, submitter);\n      return frame ? frame != element.closest(\"turbo-frame\") : false\n    } else {\n      return false\n    }\n  }\n\n  #findFrameElement(element, submitter) {\n    const id = submitter?.getAttribute(\"data-turbo-frame\") || element.getAttribute(\"data-turbo-frame\");\n    if (id && id != \"_top\") {\n      const frame = this.element.querySelector(`#${id}:not([disabled])`);\n      if (frame instanceof FrameElement) {\n        return frame\n      }\n    }\n  }\n}\n\nclass History {\n  location\n  restorationIdentifier = uuid()\n  restorationData = {}\n  started = false\n  currentIndex = 0\n\n  constructor(delegate) {\n    this.delegate = delegate;\n  }\n\n  start() {\n    if (!this.started) {\n      addEventListener(\"popstate\", this.onPopState, false);\n      this.currentIndex = history.state?.turbo?.restorationIndex || 0;\n      this.started = true;\n      this.replace(new URL(window.location.href));\n    }\n  }\n\n  stop() {\n    if (this.started) {\n      removeEventListener(\"popstate\", this.onPopState, false);\n      this.started = false;\n    }\n  }\n\n  push(location, restorationIdentifier) {\n    this.update(history.pushState, location, restorationIdentifier);\n  }\n\n  replace(location, restorationIdentifier) {\n    this.update(history.replaceState, location, restorationIdentifier);\n  }\n\n  update(method, location, restorationIdentifier = uuid()) {\n    if (method === history.pushState) ++this.currentIndex;\n\n    const state = { turbo: { restorationIdentifier, restorationIndex: this.currentIndex } };\n    method.call(history, state, \"\", location.href);\n    this.location = location;\n    this.restorationIdentifier = restorationIdentifier;\n  }\n\n  // Restoration data\n\n  getRestorationDataForIdentifier(restorationIdentifier) {\n    return this.restorationData[restorationIdentifier] || {}\n  }\n\n  updateRestorationData(additionalData) {\n    const { restorationIdentifier } = this;\n    const restorationData = this.restorationData[restorationIdentifier];\n    this.restorationData[restorationIdentifier] = {\n      ...restorationData,\n      ...additionalData\n    };\n  }\n\n  // Scroll restoration\n\n  assumeControlOfScrollRestoration() {\n    if (!this.previousScrollRestoration) {\n      this.previousScrollRestoration = history.scrollRestoration ?? \"auto\";\n      history.scrollRestoration = \"manual\";\n    }\n  }\n\n  relinquishControlOfScrollRestoration() {\n    if (this.previousScrollRestoration) {\n      history.scrollRestoration = this.previousScrollRestoration;\n      delete this.previousScrollRestoration;\n    }\n  }\n\n  // Event handlers\n\n  onPopState = (event) => {\n    const { turbo } = event.state || {};\n    this.location = new URL(window.location.href);\n\n    if (turbo) {\n      const { restorationIdentifier, restorationIndex } = turbo;\n      this.restorationIdentifier = restorationIdentifier;\n      const direction = restorationIndex > this.currentIndex ? \"forward\" : \"back\";\n      this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location, restorationIdentifier, direction);\n      this.currentIndex = restorationIndex;\n    } else {\n      this.currentIndex++;\n      this.delegate.historyPoppedWithEmptyState(this.location);\n    }\n  }\n}\n\nclass LinkPrefetchObserver {\n  started = false\n  #prefetchedLink = null\n\n  constructor(delegate, eventTarget) {\n    this.delegate = delegate;\n    this.eventTarget = eventTarget;\n  }\n\n  start() {\n    if (this.started) return\n\n    if (this.eventTarget.readyState === \"loading\") {\n      this.eventTarget.addEventListener(\"DOMContentLoaded\", this.#enable, { once: true });\n    } else {\n      this.#enable();\n    }\n  }\n\n  stop() {\n    if (!this.started) return\n\n    this.eventTarget.removeEventListener(\"mouseenter\", this.#tryToPrefetchRequest, {\n      capture: true,\n      passive: true\n    });\n    this.eventTarget.removeEventListener(\"mouseleave\", this.#cancelRequestIfObsolete, {\n      capture: true,\n      passive: true\n    });\n\n    this.eventTarget.removeEventListener(\"turbo:before-fetch-request\", this.#tryToUsePrefetchedRequest, true);\n    this.started = false;\n  }\n\n  #enable = () => {\n    this.eventTarget.addEventListener(\"mouseenter\", this.#tryToPrefetchRequest, {\n      capture: true,\n      passive: true\n    });\n    this.eventTarget.addEventListener(\"mouseleave\", this.#cancelRequestIfObsolete, {\n      capture: true,\n      passive: true\n    });\n\n    this.eventTarget.addEventListener(\"turbo:before-fetch-request\", this.#tryToUsePrefetchedRequest, true);\n    this.started = true;\n  }\n\n  #tryToPrefetchRequest = (event) => {\n    if (getMetaContent(\"turbo-prefetch\") === \"false\") return\n\n    const target = event.target;\n    const isLink = target.matches && target.matches(\"a[href]:not([target^=_]):not([download])\");\n\n    if (isLink && this.#isPrefetchable(target)) {\n      const link = target;\n      const location = getLocationForLink(link);\n\n      if (this.delegate.canPrefetchRequestToLocation(link, location)) {\n        this.#prefetchedLink = link;\n\n        const fetchRequest = new FetchRequest(\n          this,\n          FetchMethod.get,\n          location,\n          new URLSearchParams(),\n          target\n        );\n\n        fetchRequest.fetchOptions.priority = \"low\";\n\n        prefetchCache.putLater(location, fetchRequest, this.#cacheTtl);\n      }\n    }\n  }\n\n  #cancelRequestIfObsolete = (event) => {\n    if (event.target === this.#prefetchedLink) this.#cancelPrefetchRequest();\n  }\n\n  #cancelPrefetchRequest = () => {\n    prefetchCache.clear();\n    this.#prefetchedLink = null;\n  }\n\n  #tryToUsePrefetchedRequest = (event) => {\n    if (event.target.tagName !== \"FORM\" && event.detail.fetchOptions.method === \"GET\") {\n      const cached = prefetchCache.get(event.detail.url);\n\n      if (cached) {\n        // User clicked link, use cache response\n        event.detail.fetchRequest = cached;\n      }\n\n      prefetchCache.clear();\n    }\n  }\n\n  prepareRequest(request) {\n    const link = request.target;\n\n    request.headers[\"X-Sec-Purpose\"] = \"prefetch\";\n\n    const turboFrame = link.closest(\"turbo-frame\");\n    const turboFrameTarget = link.getAttribute(\"data-turbo-frame\") || turboFrame?.getAttribute(\"target\") || turboFrame?.id;\n\n    if (turboFrameTarget && turboFrameTarget !== \"_top\") {\n      request.headers[\"Turbo-Frame\"] = turboFrameTarget;\n    }\n  }\n\n  // Fetch request interface\n\n  requestSucceededWithResponse() {}\n\n  requestStarted(fetchRequest) {}\n\n  requestErrored(fetchRequest) {}\n\n  requestFinished(fetchRequest) {}\n\n  requestPreventedHandlingResponse(fetchRequest, fetchResponse) {}\n\n  requestFailedWithResponse(fetchRequest, fetchResponse) {}\n\n  get #cacheTtl() {\n    return Number(getMetaContent(\"turbo-prefetch-cache-time\")) || cacheTtl\n  }\n\n  #isPrefetchable(link) {\n    const href = link.getAttribute(\"href\");\n\n    if (!href) return false\n\n    if (unfetchableLink(link)) return false\n    if (linkToTheSamePage(link)) return false\n    if (linkOptsOut(link)) return false\n    if (nonSafeLink(link)) return false\n    if (eventPrevented(link)) return false\n\n    return true\n  }\n}\n\nconst unfetchableLink = (link) => {\n  return link.origin !== document.location.origin || ![\"http:\", \"https:\"].includes(link.protocol) || link.hasAttribute(\"target\")\n};\n\nconst linkToTheSamePage = (link) => {\n  return (link.pathname + link.search === document.location.pathname + document.location.search) || link.href.startsWith(\"#\")\n};\n\nconst linkOptsOut = (link) => {\n  if (link.getAttribute(\"data-turbo-prefetch\") === \"false\") return true\n  if (link.getAttribute(\"data-turbo\") === \"false\") return true\n\n  const turboPrefetchParent = findClosestRecursively(link, \"[data-turbo-prefetch]\");\n  if (turboPrefetchParent && turboPrefetchParent.getAttribute(\"data-turbo-prefetch\") === \"false\") return true\n\n  return false\n};\n\nconst nonSafeLink = (link) => {\n  const turboMethod = link.getAttribute(\"data-turbo-method\");\n  if (turboMethod && turboMethod.toLowerCase() !== \"get\") return true\n\n  if (isUJS(link)) return true\n  if (link.hasAttribute(\"data-turbo-confirm\")) return true\n  if (link.hasAttribute(\"data-turbo-stream\")) return true\n\n  return false\n};\n\nconst isUJS = (link) => {\n  return link.hasAttribute(\"data-remote\") || link.hasAttribute(\"data-behavior\") || link.hasAttribute(\"data-confirm\") || link.hasAttribute(\"data-method\")\n};\n\nconst eventPrevented = (link) => {\n  const event = dispatch(\"turbo:before-prefetch\", { target: link, cancelable: true });\n  return event.defaultPrevented\n};\n\nclass Navigator {\n  constructor(delegate) {\n    this.delegate = delegate;\n  }\n\n  proposeVisit(location, options = {}) {\n    if (this.delegate.allowsVisitingLocationWithAction(location, options.action)) {\n      this.delegate.visitProposedToLocation(location, options);\n    }\n  }\n\n  startVisit(locatable, restorationIdentifier, options = {}) {\n    this.stop();\n    this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, {\n      referrer: this.location,\n      ...options\n    });\n    this.currentVisit.start();\n  }\n\n  submitForm(form, submitter) {\n    this.stop();\n    this.formSubmission = new FormSubmission(this, form, submitter, true);\n\n    this.formSubmission.start();\n  }\n\n  stop() {\n    if (this.formSubmission) {\n      this.formSubmission.stop();\n      delete this.formSubmission;\n    }\n\n    if (this.currentVisit) {\n      this.currentVisit.cancel();\n      delete this.currentVisit;\n    }\n  }\n\n  get adapter() {\n    return this.delegate.adapter\n  }\n\n  get view() {\n    return this.delegate.view\n  }\n\n  get rootLocation() {\n    return this.view.snapshot.rootLocation\n  }\n\n  get history() {\n    return this.delegate.history\n  }\n\n  // Form submission delegate\n\n  formSubmissionStarted(formSubmission) {\n    // Not all adapters implement formSubmissionStarted\n    if (typeof this.adapter.formSubmissionStarted === \"function\") {\n      this.adapter.formSubmissionStarted(formSubmission);\n    }\n  }\n\n  async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) {\n    if (formSubmission == this.formSubmission) {\n      const responseHTML = await fetchResponse.responseHTML;\n      if (responseHTML) {\n        const shouldCacheSnapshot = formSubmission.isSafe;\n        if (!shouldCacheSnapshot) {\n          this.view.clearSnapshotCache();\n        }\n\n        const { statusCode, redirected } = fetchResponse;\n        const action = this.#getActionForFormSubmission(formSubmission, fetchResponse);\n        const visitOptions = {\n          action,\n          shouldCacheSnapshot,\n          response: { statusCode, responseHTML, redirected }\n        };\n        this.proposeVisit(fetchResponse.location, visitOptions);\n      }\n    }\n  }\n\n  async formSubmissionFailedWithResponse(formSubmission, fetchResponse) {\n    const responseHTML = await fetchResponse.responseHTML;\n\n    if (responseHTML) {\n      const snapshot = PageSnapshot.fromHTMLString(responseHTML);\n      if (fetchResponse.serverError) {\n        await this.view.renderError(snapshot, this.currentVisit);\n      } else {\n        await this.view.renderPage(snapshot, false, true, this.currentVisit);\n      }\n      if (snapshot.refreshScroll !== \"preserve\") {\n        this.view.scrollToTop();\n      }\n      this.view.clearSnapshotCache();\n    }\n  }\n\n  formSubmissionErrored(formSubmission, error) {\n    console.error(error);\n  }\n\n  formSubmissionFinished(formSubmission) {\n    // Not all adapters implement formSubmissionFinished\n    if (typeof this.adapter.formSubmissionFinished === \"function\") {\n      this.adapter.formSubmissionFinished(formSubmission);\n    }\n  }\n\n  // Link prefetching\n\n  linkPrefetchingIsEnabledForLocation(location) {\n    // Not all adapters implement linkPrefetchingIsEnabledForLocation\n    if (typeof this.adapter.linkPrefetchingIsEnabledForLocation === \"function\") {\n      return this.adapter.linkPrefetchingIsEnabledForLocation(location)\n    }\n\n    return true\n  }\n\n  // Visit delegate\n\n  visitStarted(visit) {\n    this.delegate.visitStarted(visit);\n  }\n\n  visitCompleted(visit) {\n    this.delegate.visitCompleted(visit);\n    delete this.currentVisit;\n  }\n\n  // Same-page links are no longer handled with a Visit.\n  // This method is still needed for Turbo Native adapters.\n  locationWithActionIsSamePage(location, action) {\n    return false\n  }\n\n  // Visits\n\n  get location() {\n    return this.history.location\n  }\n\n  get restorationIdentifier() {\n    return this.history.restorationIdentifier\n  }\n\n  #getActionForFormSubmission(formSubmission, fetchResponse) {\n    const { submitter, formElement } = formSubmission;\n    return getVisitAction(submitter, formElement) || this.#getDefaultAction(fetchResponse)\n  }\n\n  #getDefaultAction(fetchResponse) {\n    const sameLocationRedirect = fetchResponse.redirected && fetchResponse.location.href === this.location?.href;\n    return sameLocationRedirect ? \"replace\" : \"advance\"\n  }\n}\n\nconst PageStage = {\n  initial: 0,\n  loading: 1,\n  interactive: 2,\n  complete: 3\n};\n\nclass PageObserver {\n  stage = PageStage.initial\n  started = false\n\n  constructor(delegate) {\n    this.delegate = delegate;\n  }\n\n  start() {\n    if (!this.started) {\n      if (this.stage == PageStage.initial) {\n        this.stage = PageStage.loading;\n      }\n      document.addEventListener(\"readystatechange\", this.interpretReadyState, false);\n      addEventListener(\"pagehide\", this.pageWillUnload, false);\n      this.started = true;\n    }\n  }\n\n  stop() {\n    if (this.started) {\n      document.removeEventListener(\"readystatechange\", this.interpretReadyState, false);\n      removeEventListener(\"pagehide\", this.pageWillUnload, false);\n      this.started = false;\n    }\n  }\n\n  interpretReadyState = () => {\n    const { readyState } = this;\n    if (readyState == \"interactive\") {\n      this.pageIsInteractive();\n    } else if (readyState == \"complete\") {\n      this.pageIsComplete();\n    }\n  }\n\n  pageIsInteractive() {\n    if (this.stage == PageStage.loading) {\n      this.stage = PageStage.interactive;\n      this.delegate.pageBecameInteractive();\n    }\n  }\n\n  pageIsComplete() {\n    this.pageIsInteractive();\n    if (this.stage == PageStage.interactive) {\n      this.stage = PageStage.complete;\n      this.delegate.pageLoaded();\n    }\n  }\n\n  pageWillUnload = () => {\n    this.delegate.pageWillUnload();\n  }\n\n  get readyState() {\n    return document.readyState\n  }\n}\n\nclass ScrollObserver {\n  started = false\n\n  constructor(delegate) {\n    this.delegate = delegate;\n  }\n\n  start() {\n    if (!this.started) {\n      addEventListener(\"scroll\", this.onScroll, false);\n      this.onScroll();\n      this.started = true;\n    }\n  }\n\n  stop() {\n    if (this.started) {\n      removeEventListener(\"scroll\", this.onScroll, false);\n      this.started = false;\n    }\n  }\n\n  onScroll = () => {\n    this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset });\n  }\n\n  // Private\n\n  updatePosition(position) {\n    this.delegate.scrollPositionChanged(position);\n  }\n}\n\nclass StreamMessageRenderer {\n  render({ fragment }) {\n    Bardo.preservingPermanentElements(this, getPermanentElementMapForFragment(fragment), () => {\n      withAutofocusFromFragment(fragment, () => {\n        withPreservedFocus(() => {\n          document.documentElement.appendChild(fragment);\n        });\n      });\n    });\n  }\n\n  // Bardo delegate\n\n  enteringBardo(currentPermanentElement, newPermanentElement) {\n    newPermanentElement.replaceWith(currentPermanentElement.cloneNode(true));\n  }\n\n  leavingBardo() {}\n}\n\nfunction getPermanentElementMapForFragment(fragment) {\n  const permanentElementsInDocument = queryPermanentElementsAll(document.documentElement);\n  const permanentElementMap = {};\n  for (const permanentElementInDocument of permanentElementsInDocument) {\n    const { id } = permanentElementInDocument;\n\n    for (const streamElement of fragment.querySelectorAll(\"turbo-stream\")) {\n      const elementInStream = getPermanentElementById(streamElement.templateElement.content, id);\n\n      if (elementInStream) {\n        permanentElementMap[id] = [permanentElementInDocument, elementInStream];\n      }\n    }\n  }\n\n  return permanentElementMap\n}\n\nasync function withAutofocusFromFragment(fragment, callback) {\n  const generatedID = `turbo-stream-autofocus-${uuid()}`;\n  const turboStreams = fragment.querySelectorAll(\"turbo-stream\");\n  const elementWithAutofocus = firstAutofocusableElementInStreams(turboStreams);\n  let willAutofocusId = null;\n\n  if (elementWithAutofocus) {\n    if (elementWithAutofocus.id) {\n      willAutofocusId = elementWithAutofocus.id;\n    } else {\n      willAutofocusId = generatedID;\n    }\n\n    elementWithAutofocus.id = willAutofocusId;\n  }\n\n  callback();\n  await nextRepaint();\n\n  const hasNoActiveElement = document.activeElement == null || document.activeElement == document.body;\n\n  if (hasNoActiveElement && willAutofocusId) {\n    const elementToAutofocus = document.getElementById(willAutofocusId);\n\n    if (elementIsFocusable(elementToAutofocus)) {\n      elementToAutofocus.focus();\n    }\n    if (elementToAutofocus && elementToAutofocus.id == generatedID) {\n      elementToAutofocus.removeAttribute(\"id\");\n    }\n  }\n}\n\nasync function withPreservedFocus(callback) {\n  const [activeElementBeforeRender, activeElementAfterRender] = await around(callback, () => document.activeElement);\n\n  const restoreFocusTo = activeElementBeforeRender && activeElementBeforeRender.id;\n\n  if (restoreFocusTo) {\n    const elementToFocus = document.getElementById(restoreFocusTo);\n\n    if (elementIsFocusable(elementToFocus) && elementToFocus != activeElementAfterRender) {\n      elementToFocus.focus();\n    }\n  }\n}\n\nfunction firstAutofocusableElementInStreams(nodeListOfStreamElements) {\n  for (const streamElement of nodeListOfStreamElements) {\n    const elementWithAutofocus = queryAutofocusableElement(streamElement.templateElement.content);\n\n    if (elementWithAutofocus) return elementWithAutofocus\n  }\n\n  return null\n}\n\nclass StreamObserver {\n  sources = new Set()\n  #started = false\n\n  constructor(delegate) {\n    this.delegate = delegate;\n  }\n\n  start() {\n    if (!this.#started) {\n      this.#started = true;\n      addEventListener(\"turbo:before-fetch-response\", this.inspectFetchResponse, false);\n    }\n  }\n\n  stop() {\n    if (this.#started) {\n      this.#started = false;\n      removeEventListener(\"turbo:before-fetch-response\", this.inspectFetchResponse, false);\n    }\n  }\n\n  connectStreamSource(source) {\n    if (!this.streamSourceIsConnected(source)) {\n      this.sources.add(source);\n      source.addEventListener(\"message\", this.receiveMessageEvent, false);\n    }\n  }\n\n  disconnectStreamSource(source) {\n    if (this.streamSourceIsConnected(source)) {\n      this.sources.delete(source);\n      source.removeEventListener(\"message\", this.receiveMessageEvent, false);\n    }\n  }\n\n  streamSourceIsConnected(source) {\n    return this.sources.has(source)\n  }\n\n  inspectFetchResponse = (event) => {\n    const response = fetchResponseFromEvent(event);\n    if (response && fetchResponseIsStream(response)) {\n      event.preventDefault();\n      this.receiveMessageResponse(response);\n    }\n  }\n\n  receiveMessageEvent = (event) => {\n    if (this.#started && typeof event.data == \"string\") {\n      this.receiveMessageHTML(event.data);\n    }\n  }\n\n  async receiveMessageResponse(response) {\n    const html = await response.responseHTML;\n    if (html) {\n      this.receiveMessageHTML(html);\n    }\n  }\n\n  receiveMessageHTML(html) {\n    this.delegate.receivedMessageFromStream(StreamMessage.wrap(html));\n  }\n}\n\nfunction fetchResponseFromEvent(event) {\n  const fetchResponse = event.detail?.fetchResponse;\n  if (fetchResponse instanceof FetchResponse) {\n    return fetchResponse\n  }\n}\n\nfunction fetchResponseIsStream(response) {\n  const contentType = response.contentType ?? \"\";\n  return contentType.startsWith(StreamMessage.contentType)\n}\n\nclass ErrorRenderer extends Renderer {\n  static renderElement(currentElement, newElement) {\n    const { documentElement, body } = document;\n\n    documentElement.replaceChild(newElement, body);\n  }\n\n  async render() {\n    this.replaceHeadAndBody();\n    this.activateScriptElements();\n  }\n\n  replaceHeadAndBody() {\n    const { documentElement, head } = document;\n    documentElement.replaceChild(this.newHead, head);\n    this.renderElement(this.currentElement, this.newElement);\n  }\n\n  activateScriptElements() {\n    for (const replaceableElement of this.scriptElements) {\n      const parentNode = replaceableElement.parentNode;\n      if (parentNode) {\n        const element = activateScriptElement(replaceableElement);\n        parentNode.replaceChild(element, replaceableElement);\n      }\n    }\n  }\n\n  get newHead() {\n    return this.newSnapshot.headSnapshot.element\n  }\n\n  get scriptElements() {\n    return document.documentElement.querySelectorAll(\"script\")\n  }\n}\n\nclass PageRenderer extends Renderer {\n  static renderElement(currentElement, newElement) {\n    if (document.body && newElement instanceof HTMLBodyElement) {\n      document.body.replaceWith(newElement);\n    } else {\n      document.documentElement.appendChild(newElement);\n    }\n  }\n\n  get shouldRender() {\n    return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical\n  }\n\n  get reloadReason() {\n    if (!this.newSnapshot.isVisitable) {\n      return {\n        reason: \"turbo_visit_control_is_reload\"\n      }\n    }\n\n    if (!this.trackedElementsAreIdentical) {\n      return {\n        reason: \"tracked_element_mismatch\"\n      }\n    }\n  }\n\n  async prepareToRender() {\n    this.#setLanguage();\n    await this.mergeHead();\n  }\n\n  async render() {\n    if (this.willRender) {\n      await this.replaceBody();\n    }\n  }\n\n  finishRendering() {\n    super.finishRendering();\n    if (!this.isPreview) {\n      this.focusFirstAutofocusableElement();\n    }\n  }\n\n  get currentHeadSnapshot() {\n    return this.currentSnapshot.headSnapshot\n  }\n\n  get newHeadSnapshot() {\n    return this.newSnapshot.headSnapshot\n  }\n\n  get newElement() {\n    return this.newSnapshot.element\n  }\n\n  #setLanguage() {\n    const { documentElement } = this.currentSnapshot;\n    const { dir, lang } = this.newSnapshot;\n\n    if (lang) {\n      documentElement.setAttribute(\"lang\", lang);\n    } else {\n      documentElement.removeAttribute(\"lang\");\n    }\n    if (dir) {\n      documentElement.setAttribute(\"dir\", dir);\n    } else {\n      documentElement.removeAttribute(\"dir\");\n    }\n  }\n\n  async mergeHead() {\n    const mergedHeadElements = this.mergeProvisionalElements();\n    const newStylesheetElements = this.copyNewHeadStylesheetElements();\n    this.copyNewHeadScriptElements();\n\n    await mergedHeadElements;\n    await newStylesheetElements;\n\n    if (this.willRender) {\n      this.removeUnusedDynamicStylesheetElements();\n    }\n  }\n\n  async replaceBody() {\n    await this.preservingPermanentElements(async () => {\n      this.activateNewBody();\n      await this.assignNewBody();\n    });\n  }\n\n  get trackedElementsAreIdentical() {\n    return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature\n  }\n\n  async copyNewHeadStylesheetElements() {\n    const loadingElements = [];\n\n    for (const element of this.newHeadStylesheetElements) {\n      loadingElements.push(waitForLoad(element));\n\n      document.head.appendChild(element);\n    }\n\n    await Promise.all(loadingElements);\n  }\n\n  copyNewHeadScriptElements() {\n    for (const element of this.newHeadScriptElements) {\n      document.head.appendChild(activateScriptElement(element));\n    }\n  }\n\n  removeUnusedDynamicStylesheetElements() {\n    for (const element of this.unusedDynamicStylesheetElements) {\n      document.head.removeChild(element);\n    }\n  }\n\n  async mergeProvisionalElements() {\n    const newHeadElements = [...this.newHeadProvisionalElements];\n\n    for (const element of this.currentHeadProvisionalElements) {\n      if (!this.isCurrentElementInElementList(element, newHeadElements)) {\n        document.head.removeChild(element);\n      }\n    }\n\n    for (const element of newHeadElements) {\n      document.head.appendChild(element);\n    }\n  }\n\n  isCurrentElementInElementList(element, elementList) {\n    for (const [index, newElement] of elementList.entries()) {\n      // if title element...\n      if (element.tagName == \"TITLE\") {\n        if (newElement.tagName != \"TITLE\") {\n          continue\n        }\n        if (element.innerHTML == newElement.innerHTML) {\n          elementList.splice(index, 1);\n          return true\n        }\n      }\n\n      // if any other element...\n      if (newElement.isEqualNode(element)) {\n        elementList.splice(index, 1);\n        return true\n      }\n    }\n\n    return false\n  }\n\n  removeCurrentHeadProvisionalElements() {\n    for (const element of this.currentHeadProvisionalElements) {\n      document.head.removeChild(element);\n    }\n  }\n\n  copyNewHeadProvisionalElements() {\n    for (const element of this.newHeadProvisionalElements) {\n      document.head.appendChild(element);\n    }\n  }\n\n  activateNewBody() {\n    document.adoptNode(this.newElement);\n    this.removeNoscriptElements();\n    this.activateNewBodyScriptElements();\n  }\n\n  removeNoscriptElements() {\n    for (const noscriptElement of this.newElement.querySelectorAll(\"noscript\")) {\n      noscriptElement.remove();\n    }\n  }\n\n  activateNewBodyScriptElements() {\n    for (const inertScriptElement of this.newBodyScriptElements) {\n      const activatedScriptElement = activateScriptElement(inertScriptElement);\n      inertScriptElement.replaceWith(activatedScriptElement);\n    }\n  }\n\n  async assignNewBody() {\n    await this.renderElement(this.currentElement, this.newElement);\n  }\n\n  get unusedDynamicStylesheetElements() {\n    return this.oldHeadStylesheetElements.filter((element) => {\n      return element.getAttribute(\"data-turbo-track\") === \"dynamic\"\n    })\n  }\n\n  get oldHeadStylesheetElements() {\n    return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot)\n  }\n\n  get newHeadStylesheetElements() {\n    return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot)\n  }\n\n  get newHeadScriptElements() {\n    return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot)\n  }\n\n  get currentHeadProvisionalElements() {\n    return this.currentHeadSnapshot.provisionalElements\n  }\n\n  get newHeadProvisionalElements() {\n    return this.newHeadSnapshot.provisionalElements\n  }\n\n  get newBodyScriptElements() {\n    return this.newElement.querySelectorAll(\"script\")\n  }\n}\n\nclass MorphingPageRenderer extends PageRenderer {\n  static renderElement(currentElement, newElement) {\n    morphElements(currentElement, newElement, {\n      callbacks: {\n        beforeNodeMorphed: (node, newNode) => {\n          if (\n            shouldRefreshFrameWithMorphing(node, newNode) &&\n              !closestFrameReloadableWithMorphing(node)\n          ) {\n            node.reload();\n            return false\n          }\n          return true\n        }\n      }\n    });\n\n    dispatch(\"turbo:morph\", { detail: { currentElement, newElement } });\n  }\n\n  async preservingPermanentElements(callback) {\n    return await callback()\n  }\n\n  get renderMethod() {\n    return \"morph\"\n  }\n\n  get shouldAutofocus() {\n    return false\n  }\n}\n\nclass SnapshotCache extends LRUCache {\n  constructor(size) {\n    super(size, toCacheKey);\n  }\n\n  get snapshots() {\n    return this.entries\n  }\n}\n\nclass PageView extends View {\n  snapshotCache = new SnapshotCache(10)\n  lastRenderedLocation = new URL(location.href)\n  forceReloaded = false\n\n  shouldTransitionTo(newSnapshot) {\n    return this.snapshot.prefersViewTransitions && newSnapshot.prefersViewTransitions\n  }\n\n  renderPage(snapshot, isPreview = false, willRender = true, visit) {\n    const shouldMorphPage = this.isPageRefresh(visit) && (visit?.refresh?.method || this.snapshot.refreshMethod) === \"morph\";\n    const rendererClass = shouldMorphPage ? MorphingPageRenderer : PageRenderer;\n\n    const renderer = new rendererClass(this.snapshot, snapshot, isPreview, willRender);\n\n    if (!renderer.shouldRender) {\n      this.forceReloaded = true;\n    } else {\n      visit?.changeHistory();\n    }\n\n    return this.render(renderer)\n  }\n\n  renderError(snapshot, visit) {\n    visit?.changeHistory();\n    const renderer = new ErrorRenderer(this.snapshot, snapshot, false);\n    return this.render(renderer)\n  }\n\n  clearSnapshotCache() {\n    this.snapshotCache.clear();\n  }\n\n  async cacheSnapshot(snapshot = this.snapshot) {\n    if (snapshot.isCacheable) {\n      this.delegate.viewWillCacheSnapshot();\n      const { lastRenderedLocation: location } = this;\n      await nextEventLoopTick();\n      const cachedSnapshot = snapshot.clone();\n      this.snapshotCache.put(location, cachedSnapshot);\n      return cachedSnapshot\n    }\n  }\n\n  getCachedSnapshotForLocation(location) {\n    return this.snapshotCache.get(location)\n  }\n\n  isPageRefresh(visit) {\n    return !visit || (this.lastRenderedLocation.pathname === visit.location.pathname && visit.action === \"replace\")\n  }\n\n  shouldPreserveScrollPosition(visit) {\n    return this.isPageRefresh(visit) && (visit?.refresh?.scroll || this.snapshot.refreshScroll) === \"preserve\"\n  }\n\n  get snapshot() {\n    return PageSnapshot.fromElement(this.element)\n  }\n}\n\nclass Preloader {\n  selector = \"a[data-turbo-preload]\"\n\n  constructor(delegate, snapshotCache) {\n    this.delegate = delegate;\n    this.snapshotCache = snapshotCache;\n  }\n\n  start() {\n    if (document.readyState === \"loading\") {\n      document.addEventListener(\"DOMContentLoaded\", this.#preloadAll);\n    } else {\n      this.preloadOnLoadLinksForView(document.body);\n    }\n  }\n\n  stop() {\n    document.removeEventListener(\"DOMContentLoaded\", this.#preloadAll);\n  }\n\n  preloadOnLoadLinksForView(element) {\n    for (const link of element.querySelectorAll(this.selector)) {\n      if (this.delegate.shouldPreloadLink(link)) {\n        this.preloadURL(link);\n      }\n    }\n  }\n\n  async preloadURL(link) {\n    const location = new URL(link.href);\n\n    if (this.snapshotCache.has(location)) {\n      return\n    }\n\n    const fetchRequest = new FetchRequest(this, FetchMethod.get, location, new URLSearchParams(), link);\n    await fetchRequest.perform();\n  }\n\n  // Fetch request delegate\n\n  prepareRequest(fetchRequest) {\n    fetchRequest.headers[\"X-Sec-Purpose\"] = \"prefetch\";\n  }\n\n  async requestSucceededWithResponse(fetchRequest, fetchResponse) {\n    try {\n      const responseHTML = await fetchResponse.responseHTML;\n      const snapshot = PageSnapshot.fromHTMLString(responseHTML);\n\n      this.snapshotCache.put(fetchRequest.url, snapshot);\n    } catch (_) {\n      // If we cannot preload that is ok!\n    }\n  }\n\n  requestStarted(fetchRequest) {}\n\n  requestErrored(fetchRequest) {}\n\n  requestFinished(fetchRequest) {}\n\n  requestPreventedHandlingResponse(fetchRequest, fetchResponse) {}\n\n  requestFailedWithResponse(fetchRequest, fetchResponse) {}\n\n  #preloadAll = () => {\n    this.preloadOnLoadLinksForView(document.body);\n  }\n}\n\nclass Cache {\n  constructor(session) {\n    this.session = session;\n  }\n\n  clear() {\n    this.session.clearCache();\n  }\n\n  resetCacheControl() {\n    this.#setCacheControl(\"\");\n  }\n\n  exemptPageFromCache() {\n    this.#setCacheControl(\"no-cache\");\n  }\n\n  exemptPageFromPreview() {\n    this.#setCacheControl(\"no-preview\");\n  }\n\n  #setCacheControl(value) {\n    setMetaContent(\"turbo-cache-control\", value);\n  }\n}\n\nclass Session {\n  navigator = new Navigator(this)\n  history = new History(this)\n  view = new PageView(this, document.documentElement)\n  adapter = new BrowserAdapter(this)\n\n  pageObserver = new PageObserver(this)\n  cacheObserver = new CacheObserver()\n  linkPrefetchObserver = new LinkPrefetchObserver(this, document)\n  linkClickObserver = new LinkClickObserver(this, window)\n  formSubmitObserver = new FormSubmitObserver(this, document)\n  scrollObserver = new ScrollObserver(this)\n  streamObserver = new StreamObserver(this)\n  formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement)\n  frameRedirector = new FrameRedirector(this, document.documentElement)\n  streamMessageRenderer = new StreamMessageRenderer()\n  cache = new Cache(this)\n\n  enabled = true\n  started = false\n  #pageRefreshDebouncePeriod = 150\n\n  constructor(recentRequests) {\n    this.recentRequests = recentRequests;\n    this.preloader = new Preloader(this, this.view.snapshotCache);\n    this.debouncedRefresh = this.refresh;\n    this.pageRefreshDebouncePeriod = this.pageRefreshDebouncePeriod;\n  }\n\n  start() {\n    if (!this.started) {\n      this.pageObserver.start();\n      this.cacheObserver.start();\n      this.linkPrefetchObserver.start();\n      this.formLinkClickObserver.start();\n      this.linkClickObserver.start();\n      this.formSubmitObserver.start();\n      this.scrollObserver.start();\n      this.streamObserver.start();\n      this.frameRedirector.start();\n      this.history.start();\n      this.preloader.start();\n      this.started = true;\n      this.enabled = true;\n    }\n  }\n\n  disable() {\n    this.enabled = false;\n  }\n\n  stop() {\n    if (this.started) {\n      this.pageObserver.stop();\n      this.cacheObserver.stop();\n      this.linkPrefetchObserver.stop();\n      this.formLinkClickObserver.stop();\n      this.linkClickObserver.stop();\n      this.formSubmitObserver.stop();\n      this.scrollObserver.stop();\n      this.streamObserver.stop();\n      this.frameRedirector.stop();\n      this.history.stop();\n      this.preloader.stop();\n      this.started = false;\n    }\n  }\n\n  registerAdapter(adapter) {\n    this.adapter = adapter;\n  }\n\n  visit(location, options = {}) {\n    const frameElement = options.frame ? document.getElementById(options.frame) : null;\n\n    if (frameElement instanceof FrameElement) {\n      const action = options.action || getVisitAction(frameElement);\n\n      frameElement.delegate.proposeVisitIfNavigatedWithAction(frameElement, action);\n      frameElement.src = location.toString();\n    } else {\n      this.navigator.proposeVisit(expandURL(location), options);\n    }\n  }\n\n  refresh(url, options = {}) {\n    options = typeof options === \"string\" ? { requestId: options } : options;\n\n    const { method, requestId, scroll } = options;\n    const isRecentRequest = requestId && this.recentRequests.has(requestId);\n    const isCurrentUrl = url === document.baseURI;\n    if (!isRecentRequest && !this.navigator.currentVisit && isCurrentUrl) {\n      this.visit(url, { action: \"replace\", shouldCacheSnapshot: false, refresh: { method, scroll } });\n    }\n  }\n\n  connectStreamSource(source) {\n    this.streamObserver.connectStreamSource(source);\n  }\n\n  disconnectStreamSource(source) {\n    this.streamObserver.disconnectStreamSource(source);\n  }\n\n  renderStreamMessage(message) {\n    this.streamMessageRenderer.render(StreamMessage.wrap(message));\n  }\n\n  clearCache() {\n    this.view.clearSnapshotCache();\n  }\n\n  setProgressBarDelay(delay) {\n    console.warn(\n      \"Please replace `session.setProgressBarDelay(delay)` with `session.progressBarDelay = delay`. The function is deprecated and will be removed in a future version of Turbo.`\"\n    );\n\n    this.progressBarDelay = delay;\n  }\n\n  set progressBarDelay(delay) {\n    config.drive.progressBarDelay = delay;\n  }\n\n  get progressBarDelay() {\n    return config.drive.progressBarDelay\n  }\n\n  set drive(value) {\n    config.drive.enabled = value;\n  }\n\n  get drive() {\n    return config.drive.enabled\n  }\n\n  set formMode(value) {\n    config.forms.mode = value;\n  }\n\n  get formMode() {\n    return config.forms.mode\n  }\n\n  get location() {\n    return this.history.location\n  }\n\n  get restorationIdentifier() {\n    return this.history.restorationIdentifier\n  }\n\n  get pageRefreshDebouncePeriod() {\n    return this.#pageRefreshDebouncePeriod\n  }\n\n  set pageRefreshDebouncePeriod(value) {\n    this.refresh = debounce(this.debouncedRefresh.bind(this), value);\n    this.#pageRefreshDebouncePeriod = value;\n  }\n\n  // Preloader delegate\n\n  shouldPreloadLink(element) {\n    const isUnsafe = element.hasAttribute(\"data-turbo-method\");\n    const isStream = element.hasAttribute(\"data-turbo-stream\");\n    const frameTarget = element.getAttribute(\"data-turbo-frame\");\n    const frame = frameTarget == \"_top\" ?\n      null :\n      document.getElementById(frameTarget) || findClosestRecursively(element, \"turbo-frame:not([disabled])\");\n\n    if (isUnsafe || isStream || frame instanceof FrameElement) {\n      return false\n    } else {\n      const location = new URL(element.href);\n\n      return this.elementIsNavigatable(element) && locationIsVisitable(location, this.snapshot.rootLocation)\n    }\n  }\n\n  // History delegate\n\n  historyPoppedToLocationWithRestorationIdentifierAndDirection(location, restorationIdentifier, direction) {\n    if (this.enabled) {\n      this.navigator.startVisit(location, restorationIdentifier, {\n        action: \"restore\",\n        historyChanged: true,\n        direction\n      });\n    } else {\n      this.adapter.pageInvalidated({\n        reason: \"turbo_disabled\"\n      });\n    }\n  }\n\n  historyPoppedWithEmptyState(location) {\n    this.history.replace(location);\n    this.view.lastRenderedLocation = location;\n    this.view.cacheSnapshot();\n  }\n\n  // Scroll observer delegate\n\n  scrollPositionChanged(position) {\n    this.history.updateRestorationData({ scrollPosition: position });\n  }\n\n  // Form click observer delegate\n\n  willSubmitFormLinkToLocation(link, location) {\n    return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation)\n  }\n\n  submittedFormLinkToLocation() {}\n\n  // Link hover observer delegate\n\n  canPrefetchRequestToLocation(link, location) {\n    return (\n      this.elementIsNavigatable(link) &&\n      locationIsVisitable(location, this.snapshot.rootLocation) &&\n      this.navigator.linkPrefetchingIsEnabledForLocation(location)\n    )\n  }\n\n  // Link click observer delegate\n\n  willFollowLinkToLocation(link, location, event) {\n    return (\n      this.elementIsNavigatable(link) &&\n      locationIsVisitable(location, this.snapshot.rootLocation) &&\n      this.applicationAllowsFollowingLinkToLocation(link, location, event)\n    )\n  }\n\n  followedLinkToLocation(link, location) {\n    const action = this.getActionForLink(link);\n    const acceptsStreamResponse = link.hasAttribute(\"data-turbo-stream\");\n\n    this.visit(location.href, { action, acceptsStreamResponse });\n  }\n\n  // Navigator delegate\n\n  allowsVisitingLocationWithAction(location, action) {\n    return this.applicationAllowsVisitingLocation(location)\n  }\n\n  visitProposedToLocation(location, options) {\n    extendURLWithDeprecatedProperties(location);\n    this.adapter.visitProposedToLocation(location, options);\n  }\n\n  // Visit delegate\n\n  visitStarted(visit) {\n    if (!visit.acceptsStreamResponse) {\n      markAsBusy(document.documentElement);\n      this.view.markVisitDirection(visit.direction);\n    }\n    extendURLWithDeprecatedProperties(visit.location);\n    this.notifyApplicationAfterVisitingLocation(visit.location, visit.action);\n  }\n\n  visitCompleted(visit) {\n    this.view.unmarkVisitDirection();\n    clearBusyState(document.documentElement);\n    this.notifyApplicationAfterPageLoad(visit.getTimingMetrics());\n  }\n\n  // Form submit observer delegate\n\n  willSubmitForm(form, submitter) {\n    const action = getAction$1(form, submitter);\n\n    return (\n      this.submissionIsNavigatable(form, submitter) &&\n      locationIsVisitable(expandURL(action), this.snapshot.rootLocation)\n    )\n  }\n\n  formSubmitted(form, submitter) {\n    this.navigator.submitForm(form, submitter);\n  }\n\n  // Page observer delegate\n\n  pageBecameInteractive() {\n    this.view.lastRenderedLocation = this.location;\n    this.notifyApplicationAfterPageLoad();\n  }\n\n  pageLoaded() {\n    this.history.assumeControlOfScrollRestoration();\n  }\n\n  pageWillUnload() {\n    this.history.relinquishControlOfScrollRestoration();\n  }\n\n  // Stream observer delegate\n\n  receivedMessageFromStream(message) {\n    this.renderStreamMessage(message);\n  }\n\n  // Page view delegate\n\n  viewWillCacheSnapshot() {\n    this.notifyApplicationBeforeCachingSnapshot();\n  }\n\n  allowsImmediateRender({ element }, options) {\n    const event = this.notifyApplicationBeforeRender(element, options);\n    const {\n      defaultPrevented,\n      detail: { render }\n    } = event;\n\n    if (this.view.renderer && render) {\n      this.view.renderer.renderElement = render;\n    }\n\n    return !defaultPrevented\n  }\n\n  viewRenderedSnapshot(_snapshot, _isPreview, renderMethod) {\n    this.view.lastRenderedLocation = this.history.location;\n    this.notifyApplicationAfterRender(renderMethod);\n  }\n\n  preloadOnLoadLinksForView(element) {\n    this.preloader.preloadOnLoadLinksForView(element);\n  }\n\n  viewInvalidated(reason) {\n    this.adapter.pageInvalidated(reason);\n  }\n\n  // Frame element\n\n  frameLoaded(frame) {\n    this.notifyApplicationAfterFrameLoad(frame);\n  }\n\n  frameRendered(fetchResponse, frame) {\n    this.notifyApplicationAfterFrameRender(fetchResponse, frame);\n  }\n\n  // Application events\n\n  applicationAllowsFollowingLinkToLocation(link, location, ev) {\n    const event = this.notifyApplicationAfterClickingLinkToLocation(link, location, ev);\n    return !event.defaultPrevented\n  }\n\n  applicationAllowsVisitingLocation(location) {\n    const event = this.notifyApplicationBeforeVisitingLocation(location);\n    return !event.defaultPrevented\n  }\n\n  notifyApplicationAfterClickingLinkToLocation(link, location, event) {\n    return dispatch(\"turbo:click\", {\n      target: link,\n      detail: { url: location.href, originalEvent: event },\n      cancelable: true\n    })\n  }\n\n  notifyApplicationBeforeVisitingLocation(location) {\n    return dispatch(\"turbo:before-visit\", {\n      detail: { url: location.href },\n      cancelable: true\n    })\n  }\n\n  notifyApplicationAfterVisitingLocation(location, action) {\n    return dispatch(\"turbo:visit\", { detail: { url: location.href, action } })\n  }\n\n  notifyApplicationBeforeCachingSnapshot() {\n    return dispatch(\"turbo:before-cache\")\n  }\n\n  notifyApplicationBeforeRender(newBody, options) {\n    return dispatch(\"turbo:before-render\", {\n      detail: { newBody, ...options },\n      cancelable: true\n    })\n  }\n\n  notifyApplicationAfterRender(renderMethod) {\n    return dispatch(\"turbo:render\", { detail: { renderMethod } })\n  }\n\n  notifyApplicationAfterPageLoad(timing = {}) {\n    return dispatch(\"turbo:load\", {\n      detail: { url: this.location.href, timing }\n    })\n  }\n\n  notifyApplicationAfterFrameLoad(frame) {\n    return dispatch(\"turbo:frame-load\", { target: frame })\n  }\n\n  notifyApplicationAfterFrameRender(fetchResponse, frame) {\n    return dispatch(\"turbo:frame-render\", {\n      detail: { fetchResponse },\n      target: frame,\n      cancelable: true\n    })\n  }\n\n  // Helpers\n\n  submissionIsNavigatable(form, submitter) {\n    if (config.forms.mode == \"off\") {\n      return false\n    } else {\n      const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true;\n\n      if (config.forms.mode == \"optin\") {\n        return submitterIsNavigatable && form.closest('[data-turbo=\"true\"]') != null\n      } else {\n        return submitterIsNavigatable && this.elementIsNavigatable(form)\n      }\n    }\n  }\n\n  elementIsNavigatable(element) {\n    const container = findClosestRecursively(element, \"[data-turbo]\");\n    const withinFrame = findClosestRecursively(element, \"turbo-frame\");\n\n    // Check if Drive is enabled on the session or we're within a Frame.\n    if (config.drive.enabled || withinFrame) {\n      // Element is navigatable by default, unless `data-turbo=\"false\"`.\n      if (container) {\n        return container.getAttribute(\"data-turbo\") != \"false\"\n      } else {\n        return true\n      }\n    } else {\n      // Element isn't navigatable by default, unless `data-turbo=\"true\"`.\n      if (container) {\n        return container.getAttribute(\"data-turbo\") == \"true\"\n      } else {\n        return false\n      }\n    }\n  }\n\n  // Private\n\n  getActionForLink(link) {\n    return getVisitAction(link) || \"advance\"\n  }\n\n  get snapshot() {\n    return this.view.snapshot\n  }\n}\n\n// Older versions of the Turbo Native adapters referenced the\n// `Location#absoluteURL` property in their implementations of\n// the `Adapter#visitProposedToLocation()` and `#visitStarted()`\n// methods. The Location class has since been removed in favor\n// of the DOM URL API, and accordingly all Adapter methods now\n// receive URL objects.\n//\n// We alias #absoluteURL to #toString() here to avoid crashing\n// older adapters which do not expect URL objects. We should\n// consider removing this support at some point in the future.\n\nfunction extendURLWithDeprecatedProperties(url) {\n  Object.defineProperties(url, deprecatedLocationPropertyDescriptors);\n}\n\nconst deprecatedLocationPropertyDescriptors = {\n  absoluteURL: {\n    get() {\n      return this.toString()\n    }\n  }\n};\n\nconst session = new Session(recentRequests);\n\n// Rename `navigator` to avoid shadowing `window.navigator`\nconst { cache, navigator: sessionNavigator } = session;\n\n/**\n * Starts the main session.\n * This initialises any necessary observers such as those to monitor\n * link interactions.\n */\nfunction start() {\n  session.start();\n}\n\n/**\n * Registers an adapter for the main session.\n *\n * @param adapter Adapter to register\n */\nfunction registerAdapter(adapter) {\n  session.registerAdapter(adapter);\n}\n\n/**\n * Performs an application visit to the given location.\n *\n * @param location Location to visit (a URL or path)\n * @param options Options to apply\n * @param options.action Type of history navigation to apply (\"restore\",\n * \"replace\" or \"advance\")\n * @param options.historyChanged Specifies whether the browser history has\n * already been changed for this visit or not\n * @param options.referrer Specifies the referrer of this visit such that\n * navigations to the same page will not result in a new history entry.\n * @param options.snapshotHTML Cached snapshot to render\n * @param options.response Response of the specified location\n */\nfunction visit(location, options) {\n  session.visit(location, options);\n}\n\n/**\n * Connects a stream source to the main session.\n *\n * @param source Stream source to connect\n */\nfunction connectStreamSource(source) {\n  session.connectStreamSource(source);\n}\n\n/**\n * Disconnects a stream source from the main session.\n *\n * @param source Stream source to disconnect\n */\nfunction disconnectStreamSource(source) {\n  session.disconnectStreamSource(source);\n}\n\n/**\n * Renders a stream message to the main session by appending it to the\n * current document.\n *\n * @param message Message to render\n */\nfunction renderStreamMessage(message) {\n  session.renderStreamMessage(message);\n}\n\n/**\n * Sets the delay after which the progress bar will appear during navigation.\n *\n * The progress bar appears after 500ms by default.\n *\n * Note that this method has no effect when used with the iOS or Android\n * adapters.\n *\n * @param delay Time to delay in milliseconds\n */\nfunction setProgressBarDelay(delay) {\n  console.warn(\n    \"Please replace `Turbo.setProgressBarDelay(delay)` with `Turbo.config.drive.progressBarDelay = delay`. The top-level function is deprecated and will be removed in a future version of Turbo.`\"\n  );\n  config.drive.progressBarDelay = delay;\n}\n\nfunction setConfirmMethod(confirmMethod) {\n  console.warn(\n    \"Please replace `Turbo.setConfirmMethod(confirmMethod)` with `Turbo.config.forms.confirm = confirmMethod`. The top-level function is deprecated and will be removed in a future version of Turbo.`\"\n  );\n  config.forms.confirm = confirmMethod;\n}\n\nfunction setFormMode(mode) {\n  console.warn(\n    \"Please replace `Turbo.setFormMode(mode)` with `Turbo.config.forms.mode = mode`. The top-level function is deprecated and will be removed in a future version of Turbo.`\"\n  );\n  config.forms.mode = mode;\n}\n\n/**\n * Morph the state of the currentBody based on the attributes and contents of\n * the newBody. Morphing body elements may dispatch turbo:morph,\n * turbo:before-morph-element, turbo:before-morph-attribute, and\n * turbo:morph-element events.\n *\n * @param currentBody HTMLBodyElement destination of morphing changes\n * @param newBody HTMLBodyElement source of morphing changes\n */\nfunction morphBodyElements(currentBody, newBody) {\n  MorphingPageRenderer.renderElement(currentBody, newBody);\n}\n\n/**\n * Morph the child elements of the currentFrame based on the child elements of\n * the newFrame. Morphing turbo-frame elements may dispatch turbo:before-frame-morph,\n * turbo:before-morph-element, turbo:before-morph-attribute, and\n * turbo:morph-element events.\n *\n * @param currentFrame FrameElement destination of morphing children changes\n * @param newFrame FrameElement source of morphing children changes\n */\nfunction morphTurboFrameElements(currentFrame, newFrame) {\n  MorphingFrameRenderer.renderElement(currentFrame, newFrame);\n}\n\nvar Turbo = /*#__PURE__*/Object.freeze({\n  __proto__: null,\n  PageRenderer: PageRenderer,\n  PageSnapshot: PageSnapshot,\n  FrameRenderer: FrameRenderer,\n  fetch: fetchWithTurboHeaders,\n  config: config,\n  session: session,\n  cache: cache,\n  navigator: sessionNavigator,\n  start: start,\n  registerAdapter: registerAdapter,\n  visit: visit,\n  connectStreamSource: connectStreamSource,\n  disconnectStreamSource: disconnectStreamSource,\n  renderStreamMessage: renderStreamMessage,\n  setProgressBarDelay: setProgressBarDelay,\n  setConfirmMethod: setConfirmMethod,\n  setFormMode: setFormMode,\n  morphBodyElements: morphBodyElements,\n  morphTurboFrameElements: morphTurboFrameElements,\n  morphChildren: morphChildren,\n  morphElements: morphElements\n});\n\nclass TurboFrameMissingError extends Error {}\n\nclass FrameController {\n  fetchResponseLoaded = (_fetchResponse) => Promise.resolve()\n  #currentFetchRequest = null\n  #resolveVisitPromise = () => {}\n  #connected = false\n  #hasBeenLoaded = false\n  #ignoredAttributes = new Set()\n  #shouldMorphFrame = false\n  action = null\n\n  constructor(element) {\n    this.element = element;\n    this.view = new FrameView(this, this.element);\n    this.appearanceObserver = new AppearanceObserver(this, this.element);\n    this.formLinkClickObserver = new FormLinkClickObserver(this, this.element);\n    this.linkInterceptor = new LinkInterceptor(this, this.element);\n    this.restorationIdentifier = uuid();\n    this.formSubmitObserver = new FormSubmitObserver(this, this.element);\n  }\n\n  // Frame delegate\n\n  connect() {\n    if (!this.#connected) {\n      this.#connected = true;\n      if (this.loadingStyle == FrameLoadingStyle.lazy) {\n        this.appearanceObserver.start();\n      } else {\n        this.#loadSourceURL();\n      }\n      this.formLinkClickObserver.start();\n      this.linkInterceptor.start();\n      this.formSubmitObserver.start();\n    }\n  }\n\n  disconnect() {\n    if (this.#connected) {\n      this.#connected = false;\n      this.appearanceObserver.stop();\n      this.formLinkClickObserver.stop();\n      this.linkInterceptor.stop();\n      this.formSubmitObserver.stop();\n\n      if (!this.element.hasAttribute(\"recurse\")) {\n        this.#currentFetchRequest?.cancel();\n      }\n    }\n  }\n\n  disabledChanged() {\n    if (this.disabled) {\n      this.#currentFetchRequest?.cancel();\n    } else if (this.loadingStyle == FrameLoadingStyle.eager) {\n      this.#loadSourceURL();\n    }\n  }\n\n  sourceURLChanged() {\n    if (this.#isIgnoringChangesTo(\"src\")) return\n\n    if (!this.sourceURL) {\n      this.#currentFetchRequest?.cancel();\n    }\n\n    if (this.element.isConnected) {\n      this.complete = false;\n    }\n\n    if (this.loadingStyle == FrameLoadingStyle.eager || this.#hasBeenLoaded) {\n      this.#loadSourceURL();\n    }\n  }\n\n  sourceURLReloaded() {\n    const { refresh, src } = this.element;\n\n    this.#shouldMorphFrame = src && refresh === \"morph\";\n\n    this.element.removeAttribute(\"complete\");\n    this.element.src = null;\n    this.element.src = src;\n    return this.element.loaded\n  }\n\n  loadingStyleChanged() {\n    if (this.loadingStyle == FrameLoadingStyle.lazy) {\n      this.appearanceObserver.start();\n    } else {\n      this.appearanceObserver.stop();\n      this.#loadSourceURL();\n    }\n  }\n\n  async #loadSourceURL() {\n    if (this.enabled && this.isActive && !this.complete && this.sourceURL) {\n      this.element.loaded = this.#visit(expandURL(this.sourceURL));\n      this.appearanceObserver.stop();\n      await this.element.loaded;\n      this.#hasBeenLoaded = true;\n    }\n  }\n\n  async loadResponse(fetchResponse) {\n    if (fetchResponse.redirected || (fetchResponse.succeeded && fetchResponse.isHTML)) {\n      this.sourceURL = fetchResponse.response.url;\n    }\n\n    try {\n      const html = await fetchResponse.responseHTML;\n      if (html) {\n        const document = parseHTMLDocument(html);\n        const pageSnapshot = PageSnapshot.fromDocument(document);\n\n        if (pageSnapshot.isVisitable) {\n          await this.#loadFrameResponse(fetchResponse, document);\n        } else {\n          await this.#handleUnvisitableFrameResponse(fetchResponse);\n        }\n      }\n    } finally {\n      this.#shouldMorphFrame = false;\n      this.fetchResponseLoaded = () => Promise.resolve();\n    }\n  }\n\n  // Appearance observer delegate\n\n  elementAppearedInViewport(element) {\n    this.proposeVisitIfNavigatedWithAction(element, getVisitAction(element));\n    this.#loadSourceURL();\n  }\n\n  // Form link click observer delegate\n\n  willSubmitFormLinkToLocation(link) {\n    return this.#shouldInterceptNavigation(link)\n  }\n\n  submittedFormLinkToLocation(link, _location, form) {\n    const frame = this.#findFrameElement(link);\n    if (frame) form.setAttribute(\"data-turbo-frame\", frame.id);\n  }\n\n  // Link interceptor delegate\n\n  shouldInterceptLinkClick(element, _location, _event) {\n    return this.#shouldInterceptNavigation(element)\n  }\n\n  linkClickIntercepted(element, location) {\n    this.#navigateFrame(element, location);\n  }\n\n  // Form submit observer delegate\n\n  willSubmitForm(element, submitter) {\n    return element.closest(\"turbo-frame\") == this.element && this.#shouldInterceptNavigation(element, submitter)\n  }\n\n  formSubmitted(element, submitter) {\n    if (this.formSubmission) {\n      this.formSubmission.stop();\n    }\n\n    this.formSubmission = new FormSubmission(this, element, submitter);\n\n    const { fetchRequest } = this.formSubmission;\n    const frame = this.#findFrameElement(element, submitter);\n\n    this.prepareRequest(fetchRequest, frame);\n    this.formSubmission.start();\n  }\n\n  // Fetch request delegate\n\n  prepareRequest(request, frame = this) {\n    request.headers[\"Turbo-Frame\"] = frame.id;\n\n    if (this.currentNavigationElement?.hasAttribute(\"data-turbo-stream\")) {\n      request.acceptResponseType(StreamMessage.contentType);\n    }\n  }\n\n  requestStarted(_request) {\n    markAsBusy(this.element);\n  }\n\n  requestPreventedHandlingResponse(_request, _response) {\n    this.#resolveVisitPromise();\n  }\n\n  async requestSucceededWithResponse(request, response) {\n    await this.loadResponse(response);\n    this.#resolveVisitPromise();\n  }\n\n  async requestFailedWithResponse(request, response) {\n    await this.loadResponse(response);\n    this.#resolveVisitPromise();\n  }\n\n  requestErrored(request, error) {\n    console.error(error);\n    this.#resolveVisitPromise();\n  }\n\n  requestFinished(_request) {\n    clearBusyState(this.element);\n  }\n\n  // Form submission delegate\n\n  formSubmissionStarted({ formElement }) {\n    markAsBusy(formElement, this.#findFrameElement(formElement));\n  }\n\n  formSubmissionSucceededWithResponse(formSubmission, response) {\n    const frame = this.#findFrameElement(formSubmission.formElement, formSubmission.submitter);\n\n    frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(formSubmission.submitter, formSubmission.formElement, frame));\n    frame.delegate.loadResponse(response);\n\n    if (!formSubmission.isSafe) {\n      session.clearCache();\n    }\n  }\n\n  formSubmissionFailedWithResponse(formSubmission, fetchResponse) {\n    this.element.delegate.loadResponse(fetchResponse);\n    session.clearCache();\n  }\n\n  formSubmissionErrored(formSubmission, error) {\n    console.error(error);\n  }\n\n  formSubmissionFinished({ formElement }) {\n    clearBusyState(formElement, this.#findFrameElement(formElement));\n  }\n\n  // View delegate\n\n  allowsImmediateRender({ element: newFrame }, options) {\n    const event = dispatch(\"turbo:before-frame-render\", {\n      target: this.element,\n      detail: { newFrame, ...options },\n      cancelable: true\n    });\n\n    const {\n      defaultPrevented,\n      detail: { render }\n    } = event;\n\n    if (this.view.renderer && render) {\n      this.view.renderer.renderElement = render;\n    }\n\n    return !defaultPrevented\n  }\n\n  viewRenderedSnapshot(_snapshot, _isPreview, _renderMethod) {}\n\n  preloadOnLoadLinksForView(element) {\n    session.preloadOnLoadLinksForView(element);\n  }\n\n  viewInvalidated() {}\n\n  // Frame renderer delegate\n\n  willRenderFrame(currentElement, _newElement) {\n    this.previousFrameElement = currentElement.cloneNode(true);\n  }\n\n  visitCachedSnapshot = ({ element }) => {\n    const frame = element.querySelector(\"#\" + this.element.id);\n\n    if (frame && this.previousFrameElement) {\n      frame.replaceChildren(...this.previousFrameElement.children);\n    }\n\n    delete this.previousFrameElement;\n  }\n\n  // Private\n\n  async #loadFrameResponse(fetchResponse, document) {\n    const newFrameElement = await this.extractForeignFrameElement(document.body);\n    const rendererClass = this.#shouldMorphFrame ? MorphingFrameRenderer : FrameRenderer;\n\n    if (newFrameElement) {\n      const snapshot = new Snapshot(newFrameElement);\n      const renderer = new rendererClass(this, this.view.snapshot, snapshot, false, false);\n      if (this.view.renderPromise) await this.view.renderPromise;\n      this.changeHistory();\n\n      await this.view.render(renderer);\n      this.complete = true;\n      session.frameRendered(fetchResponse, this.element);\n      session.frameLoaded(this.element);\n      await this.fetchResponseLoaded(fetchResponse);\n    } else if (this.#willHandleFrameMissingFromResponse(fetchResponse)) {\n      this.#handleFrameMissingFromResponse(fetchResponse);\n    }\n  }\n\n  async #visit(url) {\n    const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element);\n\n    this.#currentFetchRequest?.cancel();\n    this.#currentFetchRequest = request;\n\n    return new Promise((resolve) => {\n      this.#resolveVisitPromise = () => {\n        this.#resolveVisitPromise = () => {};\n        this.#currentFetchRequest = null;\n        resolve();\n      };\n      request.perform();\n    })\n  }\n\n  #navigateFrame(element, url, submitter) {\n    const frame = this.#findFrameElement(element, submitter);\n\n    frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(submitter, element, frame));\n\n    this.#withCurrentNavigationElement(element, () => {\n      frame.src = url;\n    });\n  }\n\n  proposeVisitIfNavigatedWithAction(frame, action = null) {\n    this.action = action;\n\n    if (this.action) {\n      const pageSnapshot = PageSnapshot.fromElement(frame).clone();\n      const { visitCachedSnapshot } = frame.delegate;\n\n      frame.delegate.fetchResponseLoaded = async (fetchResponse) => {\n        if (frame.src) {\n          const { statusCode, redirected } = fetchResponse;\n          const responseHTML = await fetchResponse.responseHTML;\n          const response = { statusCode, redirected, responseHTML };\n          const options = {\n            response,\n            visitCachedSnapshot,\n            willRender: false,\n            updateHistory: false,\n            restorationIdentifier: this.restorationIdentifier,\n            snapshot: pageSnapshot\n          };\n\n          if (this.action) options.action = this.action;\n\n          session.visit(frame.src, options);\n        }\n      };\n    }\n  }\n\n  changeHistory() {\n    if (this.action) {\n      const method = getHistoryMethodForAction(this.action);\n      session.history.update(method, expandURL(this.element.src || \"\"), this.restorationIdentifier);\n    }\n  }\n\n  async #handleUnvisitableFrameResponse(fetchResponse) {\n    console.warn(\n      `The response (${fetchResponse.statusCode}) from <turbo-frame id=\"${this.element.id}\"> is performing a full page visit due to turbo-visit-control.`\n    );\n\n    await this.#visitResponse(fetchResponse.response);\n  }\n\n  #willHandleFrameMissingFromResponse(fetchResponse) {\n    this.element.setAttribute(\"complete\", \"\");\n\n    const response = fetchResponse.response;\n    const visit = async (url, options) => {\n      if (url instanceof Response) {\n        this.#visitResponse(url);\n      } else {\n        session.visit(url, options);\n      }\n    };\n\n    const event = dispatch(\"turbo:frame-missing\", {\n      target: this.element,\n      detail: { response, visit },\n      cancelable: true\n    });\n\n    return !event.defaultPrevented\n  }\n\n  #handleFrameMissingFromResponse(fetchResponse) {\n    this.view.missing();\n    this.#throwFrameMissingError(fetchResponse);\n  }\n\n  #throwFrameMissingError(fetchResponse) {\n    const message = `The response (${fetchResponse.statusCode}) did not contain the expected <turbo-frame id=\"${this.element.id}\"> and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;\n    throw new TurboFrameMissingError(message)\n  }\n\n  async #visitResponse(response) {\n    const wrapped = new FetchResponse(response);\n    const responseHTML = await wrapped.responseHTML;\n    const { location, redirected, statusCode } = wrapped;\n\n    return session.visit(location, { response: { redirected, statusCode, responseHTML } })\n  }\n\n  #findFrameElement(element, submitter) {\n    const id = getAttribute(\"data-turbo-frame\", submitter, element) || this.element.getAttribute(\"target\");\n    const target = this.#getFrameElementById(id);\n\n    return target instanceof FrameElement ? target : this.element\n  }\n\n  async extractForeignFrameElement(container) {\n    let element;\n    const id = CSS.escape(this.id);\n\n    try {\n      element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL);\n      if (element) {\n        return element\n      }\n\n      element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL);\n      if (element) {\n        await element.loaded;\n        return await this.extractForeignFrameElement(element)\n      }\n    } catch (error) {\n      console.error(error);\n      return new FrameElement()\n    }\n\n    return null\n  }\n\n  #formActionIsVisitable(form, submitter) {\n    const action = getAction$1(form, submitter);\n\n    return locationIsVisitable(expandURL(action), this.rootLocation)\n  }\n\n  #shouldInterceptNavigation(element, submitter) {\n    const id = getAttribute(\"data-turbo-frame\", submitter, element) || this.element.getAttribute(\"target\");\n\n    if (element instanceof HTMLFormElement && !this.#formActionIsVisitable(element, submitter)) {\n      return false\n    }\n\n    if (!this.enabled || id == \"_top\") {\n      return false\n    }\n\n    if (id) {\n      const frameElement = this.#getFrameElementById(id);\n      if (frameElement) {\n        return !frameElement.disabled\n      } else if (id == \"_parent\") {\n        return false\n      }\n    }\n\n    if (!session.elementIsNavigatable(element)) {\n      return false\n    }\n\n    if (submitter && !session.elementIsNavigatable(submitter)) {\n      return false\n    }\n\n    return true\n  }\n\n  // Computed properties\n\n  get id() {\n    return this.element.id\n  }\n\n  get disabled() {\n    return this.element.disabled\n  }\n\n  get enabled() {\n    return !this.disabled\n  }\n\n  get sourceURL() {\n    if (this.element.src) {\n      return this.element.src\n    }\n  }\n\n  set sourceURL(sourceURL) {\n    this.#ignoringChangesToAttribute(\"src\", () => {\n      this.element.src = sourceURL ?? null;\n    });\n  }\n\n  get loadingStyle() {\n    return this.element.loading\n  }\n\n  get isLoading() {\n    return this.formSubmission !== undefined || this.#resolveVisitPromise() !== undefined\n  }\n\n  get complete() {\n    return this.element.hasAttribute(\"complete\")\n  }\n\n  set complete(value) {\n    if (value) {\n      this.element.setAttribute(\"complete\", \"\");\n    } else {\n      this.element.removeAttribute(\"complete\");\n    }\n  }\n\n  get isActive() {\n    return this.element.isActive && this.#connected\n  }\n\n  get rootLocation() {\n    const meta = this.element.ownerDocument.querySelector(`meta[name=\"turbo-root\"]`);\n    const root = meta?.content ?? \"/\";\n    return expandURL(root)\n  }\n\n  #isIgnoringChangesTo(attributeName) {\n    return this.#ignoredAttributes.has(attributeName)\n  }\n\n  #ignoringChangesToAttribute(attributeName, callback) {\n    this.#ignoredAttributes.add(attributeName);\n    callback();\n    this.#ignoredAttributes.delete(attributeName);\n  }\n\n  #withCurrentNavigationElement(element, callback) {\n    this.currentNavigationElement = element;\n    callback();\n    delete this.currentNavigationElement;\n  }\n\n  #getFrameElementById(id) {\n    if (id != null) {\n      const element = id === \"_parent\" ?\n        this.element.parentElement.closest(\"turbo-frame\") :\n        document.getElementById(id);\n      if (element instanceof FrameElement) {\n        return element\n      }\n    }\n  }\n}\n\nfunction activateElement(element, currentURL) {\n  if (element) {\n    const src = element.getAttribute(\"src\");\n    if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) {\n      throw new Error(`Matching <turbo-frame id=\"${element.id}\"> element has a source URL which references itself`)\n    }\n    if (element.ownerDocument !== document) {\n      element = document.importNode(element, true);\n    }\n\n    if (element instanceof FrameElement) {\n      element.connectedCallback();\n      element.disconnectedCallback();\n      return element\n    }\n  }\n}\n\nconst StreamActions = {\n  after() {\n    this.removeDuplicateTargetSiblings();\n    this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e.nextSibling));\n  },\n\n  append() {\n    this.removeDuplicateTargetChildren();\n    this.targetElements.forEach((e) => e.append(this.templateContent));\n  },\n\n  before() {\n    this.removeDuplicateTargetSiblings();\n    this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e));\n  },\n\n  prepend() {\n    this.removeDuplicateTargetChildren();\n    this.targetElements.forEach((e) => e.prepend(this.templateContent));\n  },\n\n  remove() {\n    this.targetElements.forEach((e) => e.remove());\n  },\n\n  replace() {\n    const method = this.getAttribute(\"method\");\n\n    this.targetElements.forEach((targetElement) => {\n      if (method === \"morph\") {\n        morphElements(targetElement, this.templateContent);\n      } else {\n        targetElement.replaceWith(this.templateContent);\n      }\n    });\n  },\n\n  update() {\n    const method = this.getAttribute(\"method\");\n\n    this.targetElements.forEach((targetElement) => {\n      if (method === \"morph\") {\n        morphChildren(targetElement, this.templateContent);\n      } else {\n        targetElement.innerHTML = \"\";\n        targetElement.append(this.templateContent);\n      }\n    });\n  },\n\n  refresh() {\n    const method = this.getAttribute(\"method\");\n    const requestId = this.requestId;\n    const scroll = this.getAttribute(\"scroll\");\n\n    session.refresh(this.baseURI, { method, requestId, scroll });\n  }\n};\n\n// <turbo-stream action=replace target=id><template>...\n\n/**\n * Renders updates to the page from a stream of messages.\n *\n * Using the `action` attribute, this can be configured one of eight ways:\n *\n * - `after` - inserts the result after the target\n * - `append` - appends the result to the target\n * - `before` - inserts the result before the target\n * - `prepend` - prepends the result to the target\n * - `refresh` - initiates a page refresh\n * - `remove` - removes the target\n * - `replace` - replaces the outer HTML of the target\n * - `update` - replaces the inner HTML of the target\n *\n * @customElement turbo-stream\n * @example\n *   <turbo-stream action=\"append\" target=\"dom_id\">\n *     <template>\n *       Content to append to target designated with the dom_id.\n *     </template>\n *   </turbo-stream>\n */\nclass StreamElement extends HTMLElement {\n  static async renderElement(newElement) {\n    await newElement.performAction();\n  }\n\n  async connectedCallback() {\n    try {\n      await this.render();\n    } catch (error) {\n      console.error(error);\n    } finally {\n      this.disconnect();\n    }\n  }\n\n  async render() {\n    return (this.renderPromise ??= (async () => {\n      const event = this.beforeRenderEvent;\n\n      if (this.dispatchEvent(event)) {\n        await nextRepaint();\n        await event.detail.render(this);\n      }\n    })())\n  }\n\n  disconnect() {\n    try {\n      this.remove();\n      // eslint-disable-next-line no-empty\n    } catch {}\n  }\n\n  /**\n   * Removes duplicate children (by ID)\n   */\n  removeDuplicateTargetChildren() {\n    this.duplicateChildren.forEach((c) => c.remove());\n  }\n\n  /**\n   * Gets the list of duplicate children (i.e. those with the same ID)\n   */\n  get duplicateChildren() {\n    const existingChildren = this.targetElements.flatMap((e) => [...e.children]).filter((c) => !!c.getAttribute(\"id\"));\n    const newChildrenIds = [...(this.templateContent?.children || [])].filter((c) => !!c.getAttribute(\"id\")).map((c) => c.getAttribute(\"id\"));\n\n    return existingChildren.filter((c) => newChildrenIds.includes(c.getAttribute(\"id\")))\n  }\n\n  /**\n  * Removes duplicate siblings (by ID)\n  */\n  removeDuplicateTargetSiblings() {\n    this.duplicateSiblings.forEach((c) => c.remove());\n  }\n\n  /**\n  * Gets the list of duplicate siblings (i.e. those with the same ID)\n  */\n  get duplicateSiblings() {\n    const existingChildren = this.targetElements.flatMap((e) => [...e.parentElement.children]).filter((c) => !!c.id);\n    const newChildrenIds = [...(this.templateContent?.children || [])].filter((c) => !!c.id).map((c) => c.id);\n\n    return existingChildren.filter((c) => newChildrenIds.includes(c.id))\n  }\n\n  /**\n   * Gets the action function to be performed.\n   */\n  get performAction() {\n    if (this.action) {\n      const actionFunction = StreamActions[this.action];\n      if (actionFunction) {\n        return actionFunction\n      }\n      this.#raise(\"unknown action\");\n    }\n    this.#raise(\"action attribute is missing\");\n  }\n\n  /**\n   * Gets the target elements which the template will be rendered to.\n   */\n  get targetElements() {\n    if (this.target) {\n      return this.targetElementsById\n    } else if (this.targets) {\n      return this.targetElementsByQuery\n    } else {\n      this.#raise(\"target or targets attribute is missing\");\n    }\n  }\n\n  /**\n   * Gets the contents of the main `<template>`.\n   */\n  get templateContent() {\n    return this.templateElement.content.cloneNode(true)\n  }\n\n  /**\n   * Gets the main `<template>` used for rendering\n   */\n  get templateElement() {\n    if (this.firstElementChild === null) {\n      const template = this.ownerDocument.createElement(\"template\");\n      this.appendChild(template);\n      return template\n    } else if (this.firstElementChild instanceof HTMLTemplateElement) {\n      return this.firstElementChild\n    }\n    this.#raise(\"first child element must be a <template> element\");\n  }\n\n  /**\n   * Gets the current action.\n   */\n  get action() {\n    return this.getAttribute(\"action\")\n  }\n\n  /**\n   * Gets the current target (an element ID) to which the result will\n   * be rendered.\n   */\n  get target() {\n    return this.getAttribute(\"target\")\n  }\n\n  /**\n   * Gets the current \"targets\" selector (a CSS selector)\n   */\n  get targets() {\n    return this.getAttribute(\"targets\")\n  }\n\n  /**\n   * Reads the request-id attribute\n   */\n  get requestId() {\n    return this.getAttribute(\"request-id\")\n  }\n\n  #raise(message) {\n    throw new Error(`${this.description}: ${message}`)\n  }\n\n  get description() {\n    return (this.outerHTML.match(/<[^>]+>/) ?? [])[0] ?? \"<turbo-stream>\"\n  }\n\n  get beforeRenderEvent() {\n    return new CustomEvent(\"turbo:before-stream-render\", {\n      bubbles: true,\n      cancelable: true,\n      detail: { newStream: this, render: StreamElement.renderElement }\n    })\n  }\n\n  get targetElementsById() {\n    const element = this.ownerDocument?.getElementById(this.target);\n\n    if (element !== null) {\n      return [element]\n    } else {\n      return []\n    }\n  }\n\n  get targetElementsByQuery() {\n    const elements = this.ownerDocument?.querySelectorAll(this.targets);\n\n    if (elements.length !== 0) {\n      return Array.prototype.slice.call(elements)\n    } else {\n      return []\n    }\n  }\n}\n\nclass StreamSourceElement extends HTMLElement {\n  streamSource = null\n\n  connectedCallback() {\n    this.streamSource = this.src.match(/^ws{1,2}:/) ? new WebSocket(this.src) : new EventSource(this.src);\n\n    connectStreamSource(this.streamSource);\n  }\n\n  disconnectedCallback() {\n    if (this.streamSource) {\n      this.streamSource.close();\n\n      disconnectStreamSource(this.streamSource);\n    }\n  }\n\n  get src() {\n    return this.getAttribute(\"src\") || \"\"\n  }\n}\n\nFrameElement.delegateConstructor = FrameController;\n\nif (customElements.get(\"turbo-frame\") === undefined) {\n  customElements.define(\"turbo-frame\", FrameElement);\n}\n\nif (customElements.get(\"turbo-stream\") === undefined) {\n  customElements.define(\"turbo-stream\", StreamElement);\n}\n\nif (customElements.get(\"turbo-stream-source\") === undefined) {\n  customElements.define(\"turbo-stream-source\", StreamSourceElement);\n}\n\n(() => {\n  const scriptElement = document.currentScript;\n  if (!scriptElement) return\n  if (scriptElement.hasAttribute(\"data-turbo-suppress-warning\")) return\n\n  let element = scriptElement.parentElement;\n  while (element) {\n    if (element == document.body) {\n      return console.warn(\n        unindent`\n        You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!\n\n        Load your application\u2019s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.\n\n        For more information, see: https://turbo.hotwired.dev/handbook/building#working-with-script-elements\n\n        \u2014\u2014\n        Suppress this warning by adding a \"data-turbo-suppress-warning\" attribute to: %s\n      `,\n        scriptElement.outerHTML\n      )\n    }\n\n    element = element.parentElement;\n  }\n})();\n\nwindow.Turbo = { ...Turbo, StreamActions };\nstart();\n\nexport { FetchEnctype, FetchMethod, FetchRequest, FetchResponse, FrameElement, FrameLoadingStyle, FrameRenderer, PageRenderer, PageSnapshot, StreamActions, StreamElement, StreamSourceElement, cache, config, connectStreamSource, disconnectStreamSource, fetchWithTurboHeaders as fetch, fetchEnctypeFromString, fetchMethodFromString, isSafe, morphBodyElements, morphChildren, morphElements, morphTurboFrameElements, sessionNavigator as navigator, registerAdapter, renderStreamMessage, session, setConfirmMethod, setFormMode, setProgressBarDelay, start, visit };\n", "let consumer\n\nexport async function getConsumer() {\n  return consumer || setConsumer(createConsumer().then(setConsumer))\n}\n\nexport function setConsumer(newConsumer) {\n  return consumer = newConsumer\n}\n\nexport async function createConsumer() {\n  const { createConsumer } = await import(/* webpackChunkName: \"actioncable\" */ \"@rails/actioncable/src\")\n  return createConsumer()\n}\n\nexport async function subscribeTo(channel, mixin) {\n  const { subscriptions } = await getConsumer()\n  return subscriptions.create(channel, mixin)\n}\n", "// Based on https://github.com/nathan7/snakeize\n//\n// This software is released under the MIT license:\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n// the Software, and to permit persons to whom the Software is furnished to do so,\n// subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\nexport default function walk (obj) {\n    if (!obj || typeof obj !== 'object') return obj;\n    if (obj instanceof Date || obj instanceof RegExp) return obj;\n    if (Array.isArray(obj)) return obj.map(walk);\n    return Object.keys(obj).reduce(function (acc, key) {\n        var camel = key[0].toLowerCase() + key.slice(1).replace(/([A-Z]+)/g, function (m, x) {\n            return '_' + x.toLowerCase();\n        });\n        acc[camel] = walk(obj[key]);\n        return acc;\n    }, {});\n};", "import { connectStreamSource, disconnectStreamSource } from \"@hotwired/turbo\"\nimport { subscribeTo } from \"./cable\"\nimport snakeize from \"./snakeize\"\n\nclass TurboCableStreamSourceElement extends HTMLElement {\n  static observedAttributes = [\"channel\", \"signed-stream-name\"]\n\n  async connectedCallback() {\n    connectStreamSource(this)\n    this.subscription = await subscribeTo(this.channel, {\n      received: this.dispatchMessageEvent.bind(this),\n      connected: this.subscriptionConnected.bind(this),\n      disconnected: this.subscriptionDisconnected.bind(this)\n    })\n  }\n\n  disconnectedCallback() {\n    disconnectStreamSource(this)\n    if (this.subscription) this.subscription.unsubscribe()\n    this.subscriptionDisconnected()\n  }\n\n  attributeChangedCallback() {\n    if (this.subscription) {\n      this.disconnectedCallback()\n      this.connectedCallback()\n    }\n  }\n\n  dispatchMessageEvent(data) {\n    const event = new MessageEvent(\"message\", { data })\n    return this.dispatchEvent(event)\n  }\n\n  subscriptionConnected() {\n    this.setAttribute(\"connected\", \"\")\n  }\n\n  subscriptionDisconnected() {\n    this.removeAttribute(\"connected\")\n  }\n\n  get channel() {\n    const channel = this.getAttribute(\"channel\")\n    const signed_stream_name = this.getAttribute(\"signed-stream-name\")\n    return { channel, signed_stream_name, ...snakeize({ ...this.dataset }) }\n  }\n}\n\n\nif (customElements.get(\"turbo-cable-stream-source\") === undefined) {\n  customElements.define(\"turbo-cable-stream-source\", TurboCableStreamSourceElement)\n}\n", "export function encodeMethodIntoRequestBody(event) {\n  if (event.target instanceof HTMLFormElement) {\n    const { target: form, detail: { fetchOptions } } = event\n\n    form.addEventListener(\"turbo:submit-start\", ({ detail: { formSubmission: { submitter } } }) => {\n      const body = isBodyInit(fetchOptions.body) ? fetchOptions.body : new URLSearchParams()\n      const method = determineFetchMethod(submitter, body, form)\n\n      if (!/get/i.test(method)) {\n        if (/post/i.test(method)) {\n          body.delete(\"_method\")\n        } else {\n          body.set(\"_method\", method)\n        }\n\n        fetchOptions.method = \"post\"\n      }\n    }, { once: true })\n  }\n}\n\nfunction determineFetchMethod(submitter, body, form) {\n  const formMethod = determineFormMethod(submitter)\n  const overrideMethod = body.get(\"_method\")\n  const method = form.getAttribute(\"method\") || \"get\"\n\n  if (typeof formMethod == \"string\") {\n    return formMethod\n  } else if (typeof overrideMethod == \"string\") {\n    return overrideMethod\n  } else {\n    return method\n  }\n}\n\nfunction determineFormMethod(submitter) {\n  if (submitter instanceof HTMLButtonElement || submitter instanceof HTMLInputElement) {\n    // Rails 7 ActionView::Helpers::FormBuilder#button method has an override\n    // for formmethod if the button does not have name or value attributes\n    // set, which is the default. This means that if you use <%= f.button\n    // formmethod: :delete %>, it will generate a <button name=\"_method\"\n    // value=\"delete\" formmethod=\"post\">. Therefore, if the submitter's name\n    // is already _method, it's value attribute already contains the desired\n    // method.\n    if (submitter.name === '_method') {\n      return submitter.value\n    } else if (submitter.hasAttribute(\"formmethod\")) {\n      return submitter.formMethod\n    } else {\n      return null\n    }\n  } else {\n    return null\n  }\n}\n\nfunction isBodyInit(body) {\n  return body instanceof FormData || body instanceof URLSearchParams\n}\n", "import \"./cable_stream_source_element\"\n\nimport * as Turbo from \"@hotwired/turbo\"\nexport { Turbo }\n\nimport * as cable from \"./cable\"\nexport { cable }\n\nimport { encodeMethodIntoRequestBody } from \"./fetch_requests\"\n\nwindow.Turbo = Turbo\n\naddEventListener(\"turbo:before-fetch-request\", encodeMethodIntoRequestBody)\n", "window.$Gunfinder = window.$Gunfinder || {};\n\nwindow.$Gunfinder.fetch = async (resource, options) => {\n  const csrfToken = document.querySelector('meta[name=\"csrf-token\"]').content;\n\n  if (options && options.headers) {\n    if (!options.headers['X-CSRF-Token'])\n      options.headers['X-CSRF-Token'] = csrfToken;\n\n    if (!options.headers['X-Requested-With'])\n      options.headers['X-Requested-With'] = 'XMLHttpRequest';\n  } else if (options && !options.headers) {\n    options.headers = { 'X-CSRF-Token': csrfToken, 'X-Requested-With': 'XMLHttpRequest' };\n  } else {\n    options = { headers: { 'X-CSRF-Token': csrfToken, 'X-Requested-With': 'XMLHttpRequest' } };\n  }\n\n  return window.fetch(resource, options);\n};\n\nwindow.$Gunfinder.getDefaultHeaders = () => {\n  return {\n    'X-CSRF-Token': document.querySelector('meta[name=\"csrf-token\"]').content,\n    'X-Requested-With': 'XMLHttpRequest',\n  };\n};\n", "import Castle from '@castleio/castle-js';\n\nwindow.castle = Castle.configure({ pk: window.$Gunfinder.env === 'production' ? 'pk_UjXGzXtSkbs7sSoqerEmyFaV6BK5vXbu' : 'pk_E6iaYbyQpjb4msujoxoeMWxnAmt7ihzn' });\n", "var o=class{constructor(e){this.baseUrl=e.baseUrl,this.headers={\"Content-Type\":\"application/json\",...e.defaultHeaders},this.maxRetries=e.maxRetries??3,this.initialRetryDelay=e.initialRetryDelay??500}async resolveHeaders(){let e={};for(let[r,t]of Object.entries(this.headers)){let s=await t;s!==null&&(e[r]=s)}return e}addHeader(e,r){this.headers[e]=r}async post(e,r,t,s){try{let i=await fetch(e,{method:\"POST\",headers:await this.resolveHeaders(),body:r?JSON.stringify(r??{}):void 0,keepalive:!0,...t});if(i.status===401)return null;if(i.status!==200&&i.status!==202)throw new Error(`HTTP error! status: ${i.status}`);let n=await i.text();return n?JSON.parse(n):null}catch(i){if(s<this.maxRetries){let n=this.initialRetryDelay*2**s;return await new Promise(l=>setTimeout(l,n)),this.post(e,r,t,s+1)}return console.error(\"Max retries reached:\",i),null}}async fetch(e,r,t={}){let s=`${this.baseUrl}${e}`;return this.post(s,r,t,0)}};var a=class{constructor(e){this.groups=[];this.queue=[];this.options=e;let r={\"openpanel-client-id\":e.clientId};e.clientSecret&&(r[\"openpanel-client-secret\"]=e.clientSecret),r[\"openpanel-sdk-name\"]=e.sdk||\"node\",r[\"openpanel-sdk-version\"]=e.sdkVersion||\"1.3.1\",this.api=new o({baseUrl:e.apiUrl||\"https://api.openpanel.dev\",defaultHeaders:r})}init(){}ready(){this.options.disabled=!1,this.options.waitForProfile=!1,this.flush()}shouldQueue(e){return!!(this.options.disabled||this.options.waitForProfile&&!this.profileId||e.type===\"replay\"&&!this.sessionId)}addQueue(e){e.type===\"track\"&&(e.payload.properties={...e.payload.properties??{},__timestamp:new Date().toISOString()}),this.queue.push(e)}async send(e){if(this.options.filter&&!this.options.filter(e))return Promise.resolve();if(this.shouldQueue(e))return this.addQueue(e),Promise.resolve();let r=await this.api.fetch(\"/track\",e,{keepalive:e.type!==\"replay\"});this.deviceId=r?.deviceId;let t=!!this.sessionId;return this.sessionId=r?.sessionId,!t&&this.sessionId&&this.flush(),r}setGlobalProperties(e){this.global={...this.global,...e}}track(e,r){this.log(\"track event\",e,r);let{groups:t,profileId:s,...i}=r??{},n=[...new Set([...this.groups,...t??[]])];return this.send({type:\"track\",payload:{name:e,profileId:s??this.profileId,groups:n.length>0?n:void 0,properties:{...this.global??{},...i}}})}identify(e){if(this.log(\"identify user\",e),e.profileId&&(this.profileId=e.profileId,this.flush()),e.profileId&&Object.keys(e).length>1)return this.send({type:\"identify\",payload:{...e,properties:{...this.global,...e.properties}}})}upsertGroup(e){return this.log(\"upsert group\",e),this.send({type:\"group\",payload:e})}setGroup(e){return this.log(\"set group\",e),this.groups.includes(e)||(this.groups=[...this.groups,e]),this.send({type:\"assign_group\",payload:{groupIds:[e],profileId:this.profileId}})}setGroups(e){return this.log(\"set groups\",e),this.groups=[...new Set([...this.groups,...e])],this.send({type:\"assign_group\",payload:{groupIds:e,profileId:this.profileId}})}alias(e){}increment(e){return this.send({type:\"increment\",payload:e})}decrement(e){return this.send({type:\"decrement\",payload:e})}revenue(e,r){let t=r?.deviceId;return delete r?.deviceId,this.track(\"revenue\",{...r??{},...t?{__deviceId:t}:{},__revenue:e})}getDeviceId(){return this.deviceId??\"\"}getSessionId(){return this.sessionId??\"\"}fetchDeviceId(){return Promise.resolve(this.deviceId??\"\")}clear(){this.profileId=void 0,this.groups=[],this.deviceId=void 0,this.sessionId=void 0}buildFlushPayload(e){if(e.type===\"replay\")return e.payload;if(e.type===\"track\"){let r=\"groups\"in e.payload?e.payload.groups??[]:[],t=[...new Set([...this.groups,...r])];return{...e.payload,profileId:e.payload.profileId??this.profileId,groups:t.length>0?t:void 0}}return e.type===\"identify\"||e.type===\"increment\"||e.type===\"decrement\"?{...e.payload,profileId:e.payload.profileId??this.profileId}:e.type===\"assign_group\"?{...e.payload,profileId:e.payload.profileId??this.profileId}:e.payload}flush(){let e=[];for(let r of this.queue){if(this.shouldQueue(r)){e.push(r);continue}let t=this.buildFlushPayload(r);this.send({...r,payload:t})}this.queue=e}log(...e){this.options.debug&&console.log(\"[OpenPanel.dev]\",...e)}};export{a as OpenPanel};\n", "import{OpenPanel as u}from\"@openpanel/sdk\";import{OpenPanel as w}from\"@openpanel/sdk\";var d=typeof document<\"u\"?document.currentScript:null;function h(o){return o.replace(/([-_][a-z])/gi,p=>p.toUpperCase().replace(\"-\",\"\").replace(\"_\",\"\"))}var l=class extends u{constructor(t){super({sdk:\"web\",sdkVersion:\"1.4.1\",...t});this.options=t;this.lastPath=\"\";this.pendingRevenues=[];if(!this.isServer()){try{let e=sessionStorage.getItem(\"openpanel-pending-revenues\");if(e){let n=JSON.parse(e);Array.isArray(n)&&(this.pendingRevenues=n)}}catch{this.pendingRevenues=[]}if(this.setGlobalProperties({__referrer:document.referrer}),this.options.trackScreenViews&&(this.trackScreenViews(),setTimeout(()=>this.screenView(),0)),this.options.trackOutgoingLinks&&this.trackOutgoingLinks(),this.options.trackAttributes&&this.trackAttributes(),this.options.sessionReplay?.enabled){let e=this.options.sessionReplay.sampleRate??1;Math.random()<e&&this.loadReplayModule().then(r=>{r&&r.startReplayRecorder(this.options.sessionReplay,s=>{this.send({type:\"replay\",payload:{...s}})})})}}}async loadReplayModule(){try{if(typeof __OPENPANEL_REPLAY_URL__<\"u\"){let t=d,e=this.options.sessionReplay?.scriptUrl||t?.src?.replace(\".js\",\"-replay.js\")||\"https://openpanel.dev/op1-replay.js\";return window.__openpanel_replay?window.__openpanel_replay:new Promise(n=>{let r=document.createElement(\"script\");r.src=e,r.onload=()=>{n(window.__openpanel_replay??null)},r.onerror=()=>{console.warn(\"[OpenPanel] Failed to load replay script from\",e),n(null)},document.head.appendChild(r)})}return await import(\"./replay-V6FXES7X.js\")}catch(t){return console.warn(\"[OpenPanel] Failed to load replay module\",t),null}}debounce(t,e){clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(t,e)}isServer(){return typeof document>\"u\"}trackOutgoingLinks(){this.isServer()||document.addEventListener(\"click\",t=>{let e=t.target,n=e.closest(\"a\");if(n&&e){let r=n.getAttribute(\"href\");if(r?.startsWith(\"http\"))try{let s=new URL(r),i=window.location.hostname;s.hostname!==i&&super.track(\"link_out\",{href:r,text:n.innerText||n.getAttribute(\"title\")||e.getAttribute(\"alt\")||e.getAttribute(\"title\")})}catch{}}})}trackScreenViews(){if(this.isServer())return;let t=history.pushState;history.pushState=function(...s){let i=t.apply(this,s);return window.dispatchEvent(new Event(\"pushstate\")),window.dispatchEvent(new Event(\"locationchange\")),i};let e=history.replaceState;history.replaceState=function(...s){let i=e.apply(this,s);return window.dispatchEvent(new Event(\"replacestate\")),window.dispatchEvent(new Event(\"locationchange\")),i},window.addEventListener(\"popstate\",()=>{window.dispatchEvent(new Event(\"locationchange\"))});let n=()=>this.debounce(()=>this.screenView(),50);this.options.trackHashChanges?window.addEventListener(\"hashchange\",n):window.addEventListener(\"locationchange\",n)}trackAttributes(){this.isServer()||document.addEventListener(\"click\",t=>{let e=t.target,n=e.closest(\"button\"),r=e.closest(\"a\"),s=n?.getAttribute(\"data-track\")?n:r?.getAttribute(\"data-track\")?r:null;if(s){let i={};for(let a of s.attributes)a.name.startsWith(\"data-\")&&a.name!==\"data-track\"&&(i[h(a.name.replace(/^data-/,\"\"))]=a.value);let c=s.getAttribute(\"data-track\");c&&super.track(c,i)}})}track(t,e){return super.track(t,{...e,__path:this.lastPath})}screenView(t,e){if(this.isServer())return;let n,r;typeof t==\"string\"?(n=t,r=e):(n=window.location.href,r=t),this.lastPath!==n&&(this.lastPath=n,super.track(\"screen_view\",{...r??{},__path:n,__title:document.title}))}async flushRevenue(){let t=this.pendingRevenues.map(e=>super.revenue(e.amount,e.properties));await Promise.all(t),this.clearRevenue()}clearRevenue(){if(this.pendingRevenues=[],!this.isServer())try{sessionStorage.removeItem(\"openpanel-pending-revenues\")}catch{}}pendingRevenue(t,e){if(this.pendingRevenues.push({amount:t,properties:e}),!this.isServer())try{sessionStorage.setItem(\"openpanel-pending-revenues\",JSON.stringify(this.pendingRevenues))}catch{}}};function m(){return'window.op=window.op||function(){var n=[];return new Proxy(function(){arguments.length&&n.push([].slice.call(arguments))},{get:function(t,r){return\"q\"===r?n:function(){n.push([r].concat([].slice.call(arguments)))}} ,has:function(t,r){return\"q\"===r}}) }();'}export{l as OpenPanel,w as OpenPanelBase,m as getInitSnippet};\n", "import { OpenPanel } from '@openpanel/web';\n \nconst op = new OpenPanel({\n  apiUrl: 'https://op.outleap.de/api',\n  clientId: window.$Gunfinder.keys.openpanel,\n  trackScreenViews: true,\n  trackAttributes: true,\n  trackOutgoingLinks: true,\n  disabled: /\\.(de|com)\\/api\\//.test(window.location.href),\n});\n\nif (!window.$Gunfinder.user.virtual && window.$Gunfinder.user.signedIn) {\n  op.identify({ profileId: window.$Gunfinder.user.id.toString() })\n}\n\nwindow.openpanel = op;\n", "import './openpanel';\n\nwindow.$Gunfinder.track = (event, data) => {\n  window.openpanel?.track(event, data || {});\n};\n", "window.$Gunfinder.Adhunter = {\n  load () {\n    if (!window.reviveAsync) return;\n\n    const key = Object.keys(window.reviveAsync)[0];\n    window.reviveAsync[key].apply(window.reviveAsync[key].detect());\n\n    // window.setInterval(window.$Gunfinder.refresh, 30 * 1000);\n  },\n\n  refresh () {\n    for (const el of document.querySelectorAll('[data-revive-loaded]')) {\n      el.removeAttribute('data-revive-loaded');\n    }\n\n    const key = Object.keys(window.reviveAsync)[0];\n    window.reviveAsync[key].refresh()\n  }\n}\n", "/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nexport default freeGlobal;\n", "import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nexport default root;\n", "import root from './_root.js';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n", "import Symbol from './_Symbol.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n  var isOwn = hasOwnProperty.call(value, symToStringTag),\n      tag = value[symToStringTag];\n\n  try {\n    value[symToStringTag] = undefined;\n    var unmasked = true;\n  } catch (e) {}\n\n  var result = nativeObjectToString.call(value);\n  if (unmasked) {\n    if (isOwn) {\n      value[symToStringTag] = tag;\n    } else {\n      delete value[symToStringTag];\n    }\n  }\n  return result;\n}\n\nexport default getRawTag;\n", "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n  return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n", "import Symbol from './_Symbol.js';\nimport getRawTag from './_getRawTag.js';\nimport objectToString from './_objectToString.js';\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n    undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n  if (value == null) {\n    return value === undefined ? undefinedTag : nullTag;\n  }\n  return (symToStringTag && symToStringTag in Object(value))\n    ? getRawTag(value)\n    : objectToString(value);\n}\n\nexport default baseGetTag;\n", "/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n  return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n", "import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n  return typeof value == 'symbol' ||\n    (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nexport default isSymbol;\n", "/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n  var index = -1,\n      length = array == null ? 0 : array.length,\n      result = Array(length);\n\n  while (++index < length) {\n    result[index] = iteratee(array[index], index, array);\n  }\n  return result;\n}\n\nexport default arrayMap;\n", "/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nexport default isArray;\n", "import Symbol from './_Symbol.js';\nimport arrayMap from './_arrayMap.js';\nimport isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n    symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n  // Exit early for strings to avoid a performance hit in some environments.\n  if (typeof value == 'string') {\n    return value;\n  }\n  if (isArray(value)) {\n    // Recursively convert values (susceptible to call stack limits).\n    return arrayMap(value, baseToString) + '';\n  }\n  if (isSymbol(value)) {\n    return symbolToString ? symbolToString.call(value) : '';\n  }\n  var result = (value + '');\n  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default baseToString;\n", "/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n  var index = string.length;\n\n  while (index-- && reWhitespace.test(string.charAt(index))) {}\n  return index;\n}\n\nexport default trimmedEndIndex;\n", "import trimmedEndIndex from './_trimmedEndIndex.js';\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n  return string\n    ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n    : string;\n}\n\nexport default baseTrim;\n", "/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n  var type = typeof value;\n  return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n", "import baseTrim from './_baseTrim.js';\nimport isObject from './isObject.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n  if (typeof value == 'number') {\n    return value;\n  }\n  if (isSymbol(value)) {\n    return NAN;\n  }\n  if (isObject(value)) {\n    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n    value = isObject(other) ? (other + '') : other;\n  }\n  if (typeof value != 'string') {\n    return value === 0 ? value : +value;\n  }\n  value = baseTrim(value);\n  var isBinary = reIsBinary.test(value);\n  return (isBinary || reIsOctal.test(value))\n    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n    : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nexport default toNumber;\n", "/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n  return value;\n}\n\nexport default identity;\n", "import baseGetTag from './_baseGetTag.js';\nimport isObject from './isObject.js';\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]',\n    proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n  if (!isObject(value)) {\n    return false;\n  }\n  // The use of `Object#toString` avoids issues with the `typeof` operator\n  // in Safari 9 which returns 'object' for typed arrays and other constructors.\n  var tag = baseGetTag(value);\n  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nexport default isFunction;\n", "import root from './_root.js';\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nexport default coreJsData;\n", "import coreJsData from './_coreJsData.js';\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n  return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n  return !!maskSrcKey && (maskSrcKey in func);\n}\n\nexport default isMasked;\n", "/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n  if (func != null) {\n    try {\n      return funcToString.call(func);\n    } catch (e) {}\n    try {\n      return (func + '');\n    } catch (e) {}\n  }\n  return '';\n}\n\nexport default toSource;\n", "import isFunction from './isFunction.js';\nimport isMasked from './_isMasked.js';\nimport isObject from './isObject.js';\nimport toSource from './_toSource.js';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n    objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n  .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n *  else `false`.\n */\nfunction baseIsNative(value) {\n  if (!isObject(value) || isMasked(value)) {\n    return false;\n  }\n  var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n  return pattern.test(toSource(value));\n}\n\nexport default baseIsNative;\n", "/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n  return object == null ? undefined : object[key];\n}\n\nexport default getValue;\n", "import baseIsNative from './_baseIsNative.js';\nimport getValue from './_getValue.js';\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n  var value = getValue(object, key);\n  return baseIsNative(value) ? value : undefined;\n}\n\nexport default getNative;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar WeakMap = getNative(root, 'WeakMap');\n\nexport default WeakMap;\n", "import isObject from './isObject.js';\n\n/** Built-in value references. */\nvar objectCreate = Object.create;\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nvar baseCreate = (function() {\n  function object() {}\n  return function(proto) {\n    if (!isObject(proto)) {\n      return {};\n    }\n    if (objectCreate) {\n      return objectCreate(proto);\n    }\n    object.prototype = proto;\n    var result = new object;\n    object.prototype = undefined;\n    return result;\n  };\n}());\n\nexport default baseCreate;\n", "/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n  switch (args.length) {\n    case 0: return func.call(thisArg);\n    case 1: return func.call(thisArg, args[0]);\n    case 2: return func.call(thisArg, args[0], args[1]);\n    case 3: return func.call(thisArg, args[0], args[1], args[2]);\n  }\n  return func.apply(thisArg, args);\n}\n\nexport default apply;\n", "/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n  var index = -1,\n      length = source.length;\n\n  array || (array = Array(length));\n  while (++index < length) {\n    array[index] = source[index];\n  }\n  return array;\n}\n\nexport default copyArray;\n", "/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n    HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n  var count = 0,\n      lastCalled = 0;\n\n  return function() {\n    var stamp = nativeNow(),\n        remaining = HOT_SPAN - (stamp - lastCalled);\n\n    lastCalled = stamp;\n    if (remaining > 0) {\n      if (++count >= HOT_COUNT) {\n        return arguments[0];\n      }\n    } else {\n      count = 0;\n    }\n    return func.apply(undefined, arguments);\n  };\n}\n\nexport default shortOut;\n", "/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n  return function() {\n    return value;\n  };\n}\n\nexport default constant;\n", "import getNative from './_getNative.js';\n\nvar defineProperty = (function() {\n  try {\n    var func = getNative(Object, 'defineProperty');\n    func({}, '', {});\n    return func;\n  } catch (e) {}\n}());\n\nexport default defineProperty;\n", "import constant from './constant.js';\nimport defineProperty from './_defineProperty.js';\nimport identity from './identity.js';\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n  return defineProperty(func, 'toString', {\n    'configurable': true,\n    'enumerable': false,\n    'value': constant(string),\n    'writable': true\n  });\n};\n\nexport default baseSetToString;\n", "import baseSetToString from './_baseSetToString.js';\nimport shortOut from './_shortOut.js';\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nexport default setToString;\n", "/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  while (++index < length) {\n    if (iteratee(array[index], index, array) === false) {\n      break;\n    }\n  }\n  return array;\n}\n\nexport default arrayEach;\n", "/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n  var type = typeof value;\n  length = length == null ? MAX_SAFE_INTEGER : length;\n\n  return !!length &&\n    (type == 'number' ||\n      (type != 'symbol' && reIsUint.test(value))) &&\n        (value > -1 && value % 1 == 0 && value < length);\n}\n\nexport default isIndex;\n", "import defineProperty from './_defineProperty.js';\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n  if (key == '__proto__' && defineProperty) {\n    defineProperty(object, key, {\n      'configurable': true,\n      'enumerable': true,\n      'value': value,\n      'writable': true\n    });\n  } else {\n    object[key] = value;\n  }\n}\n\nexport default baseAssignValue;\n", "/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n  return value === other || (value !== value && other !== other);\n}\n\nexport default eq;\n", "import baseAssignValue from './_baseAssignValue.js';\nimport eq from './eq.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n  var objValue = object[key];\n  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n      (value === undefined && !(key in object))) {\n    baseAssignValue(object, key, value);\n  }\n}\n\nexport default assignValue;\n", "import assignValue from './_assignValue.js';\nimport baseAssignValue from './_baseAssignValue.js';\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n  var isNew = !object;\n  object || (object = {});\n\n  var index = -1,\n      length = props.length;\n\n  while (++index < length) {\n    var key = props[index];\n\n    var newValue = customizer\n      ? customizer(object[key], source[key], key, object, source)\n      : undefined;\n\n    if (newValue === undefined) {\n      newValue = source[key];\n    }\n    if (isNew) {\n      baseAssignValue(object, key, newValue);\n    } else {\n      assignValue(object, key, newValue);\n    }\n  }\n  return object;\n}\n\nexport default copyObject;\n", "import apply from './_apply.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n  return function() {\n    var args = arguments,\n        index = -1,\n        length = nativeMax(args.length - start, 0),\n        array = Array(length);\n\n    while (++index < length) {\n      array[index] = args[start + index];\n    }\n    index = -1;\n    var otherArgs = Array(start + 1);\n    while (++index < start) {\n      otherArgs[index] = args[index];\n    }\n    otherArgs[start] = transform(array);\n    return apply(func, this, otherArgs);\n  };\n}\n\nexport default overRest;\n", "import identity from './identity.js';\nimport overRest from './_overRest.js';\nimport setToString from './_setToString.js';\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n  return setToString(overRest(func, start, identity), func + '');\n}\n\nexport default baseRest;\n", "/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n  return typeof value == 'number' &&\n    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\nexport default isLength;\n", "import isFunction from './isFunction.js';\nimport isLength from './isLength.js';\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n  return value != null && isLength(value.length) && !isFunction(value);\n}\n\nexport default isArrayLike;\n", "import eq from './eq.js';\nimport isArrayLike from './isArrayLike.js';\nimport isIndex from './_isIndex.js';\nimport isObject from './isObject.js';\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n *  else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n  if (!isObject(object)) {\n    return false;\n  }\n  var type = typeof index;\n  if (type == 'number'\n        ? (isArrayLike(object) && isIndex(index, object.length))\n        : (type == 'string' && index in object)\n      ) {\n    return eq(object[index], value);\n  }\n  return false;\n}\n\nexport default isIterateeCall;\n", "import baseRest from './_baseRest.js';\nimport isIterateeCall from './_isIterateeCall.js';\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n  return baseRest(function(object, sources) {\n    var index = -1,\n        length = sources.length,\n        customizer = length > 1 ? sources[length - 1] : undefined,\n        guard = length > 2 ? sources[2] : undefined;\n\n    customizer = (assigner.length > 3 && typeof customizer == 'function')\n      ? (length--, customizer)\n      : undefined;\n\n    if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n      customizer = length < 3 ? undefined : customizer;\n      length = 1;\n    }\n    object = Object(object);\n    while (++index < length) {\n      var source = sources[index];\n      if (source) {\n        assigner(object, source, index, customizer);\n      }\n    }\n    return object;\n  });\n}\n\nexport default createAssigner;\n", "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n  var Ctor = value && value.constructor,\n      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n  return value === proto;\n}\n\nexport default isPrototype;\n", "/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n  var index = -1,\n      result = Array(n);\n\n  while (++index < n) {\n    result[index] = iteratee(index);\n  }\n  return result;\n}\n\nexport default baseTimes;\n", "import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]';\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n  return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\nexport default baseIsArguments;\n", "import baseIsArguments from './_baseIsArguments.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n *  else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n    !propertyIsEnumerable.call(value, 'callee');\n};\n\nexport default isArguments;\n", "/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n  return false;\n}\n\nexport default stubFalse;\n", "import root from './_root.js';\nimport stubFalse from './stubFalse.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\nexport default isBuffer;\n", "import baseGetTag from './_baseGetTag.js';\nimport isLength from './isLength.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    arrayTag = '[object Array]',\n    boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    errorTag = '[object Error]',\n    funcTag = '[object Function]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    objectTag = '[object Object]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]',\n    float32Tag = '[object Float32Array]',\n    float64Tag = '[object Float64Array]',\n    int8Tag = '[object Int8Array]',\n    int16Tag = '[object Int16Array]',\n    int32Tag = '[object Int32Array]',\n    uint8Tag = '[object Uint8Array]',\n    uint8ClampedTag = '[object Uint8ClampedArray]',\n    uint16Tag = '[object Uint16Array]',\n    uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n  return isObjectLike(value) &&\n    isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\nexport default baseIsTypedArray;\n", "/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n  return function(value) {\n    return func(value);\n  };\n}\n\nexport default baseUnary;\n", "import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n  try {\n    // Use `util.types` for Node.js 10+.\n    var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n    if (types) {\n      return types;\n    }\n\n    // Legacy `process.binding('util')` for Node.js < 10.\n    return freeProcess && freeProcess.binding && freeProcess.binding('util');\n  } catch (e) {}\n}());\n\nexport default nodeUtil;\n", "import baseIsTypedArray from './_baseIsTypedArray.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\nexport default isTypedArray;\n", "import baseTimes from './_baseTimes.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isIndex from './_isIndex.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n  var isArr = isArray(value),\n      isArg = !isArr && isArguments(value),\n      isBuff = !isArr && !isArg && isBuffer(value),\n      isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n      skipIndexes = isArr || isArg || isBuff || isType,\n      result = skipIndexes ? baseTimes(value.length, String) : [],\n      length = result.length;\n\n  for (var key in value) {\n    if ((inherited || hasOwnProperty.call(value, key)) &&\n        !(skipIndexes && (\n           // Safari 9 has enumerable `arguments.length` in strict mode.\n           key == 'length' ||\n           // Node.js 0.10 has enumerable non-index properties on buffers.\n           (isBuff && (key == 'offset' || key == 'parent')) ||\n           // PhantomJS 2 has enumerable non-index properties on typed arrays.\n           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n           // Skip index properties.\n           isIndex(key, length)\n        ))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nexport default arrayLikeKeys;\n", "/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n  return function(arg) {\n    return func(transform(arg));\n  };\n}\n\nexport default overArg;\n", "import overArg from './_overArg.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeKeys = overArg(Object.keys, Object);\n\nexport default nativeKeys;\n", "import isPrototype from './_isPrototype.js';\nimport nativeKeys from './_nativeKeys.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n  if (!isPrototype(object)) {\n    return nativeKeys(object);\n  }\n  var result = [];\n  for (var key in Object(object)) {\n    if (hasOwnProperty.call(object, key) && key != 'constructor') {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nexport default baseKeys;\n", "import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeys from './_baseKeys.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nexport default keys;\n", "/**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction nativeKeysIn(object) {\n  var result = [];\n  if (object != null) {\n    for (var key in Object(object)) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nexport default nativeKeysIn;\n", "import isObject from './isObject.js';\nimport isPrototype from './_isPrototype.js';\nimport nativeKeysIn from './_nativeKeysIn.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeysIn(object) {\n  if (!isObject(object)) {\n    return nativeKeysIn(object);\n  }\n  var isProto = isPrototype(object),\n      result = [];\n\n  for (var key in object) {\n    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n      result.push(key);\n    }\n  }\n  return result;\n}\n\nexport default baseKeysIn;\n", "import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeysIn from './_baseKeysIn.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\nfunction keysIn(object) {\n  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n}\n\nexport default keysIn;\n", "import copyObject from './_copyObject.js';\nimport createAssigner from './_createAssigner.js';\nimport keysIn from './keysIn.js';\n\n/**\n * This method is like `_.assign` except that it iterates over own and\n * inherited source properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extend\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assign\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n * }\n *\n * function Bar() {\n *   this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n */\nvar assignIn = createAssigner(function(object, source) {\n  copyObject(source, keysIn(source), object);\n});\n\nexport default assignIn;\n", "import isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n    reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n  if (isArray(value)) {\n    return false;\n  }\n  var type = typeof value;\n  if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n      value == null || isSymbol(value)) {\n    return true;\n  }\n  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n    (object != null && value in Object(object));\n}\n\nexport default isKey;\n", "import getNative from './_getNative.js';\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nexport default nativeCreate;\n", "import nativeCreate from './_nativeCreate.js';\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n  this.__data__ = nativeCreate ? nativeCreate(null) : {};\n  this.size = 0;\n}\n\nexport default hashClear;\n", "/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n  var result = this.has(key) && delete this.__data__[key];\n  this.size -= result ? 1 : 0;\n  return result;\n}\n\nexport default hashDelete;\n", "import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n  var data = this.__data__;\n  if (nativeCreate) {\n    var result = data[key];\n    return result === HASH_UNDEFINED ? undefined : result;\n  }\n  return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\nexport default hashGet;\n", "import nativeCreate from './_nativeCreate.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n  var data = this.__data__;\n  return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\nexport default hashHas;\n", "import nativeCreate from './_nativeCreate.js';\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n  var data = this.__data__;\n  this.size += this.has(key) ? 0 : 1;\n  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n  return this;\n}\n\nexport default hashSet;\n", "import hashClear from './_hashClear.js';\nimport hashDelete from './_hashDelete.js';\nimport hashGet from './_hashGet.js';\nimport hashHas from './_hashHas.js';\nimport hashSet from './_hashSet.js';\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n  var index = -1,\n      length = entries == null ? 0 : entries.length;\n\n  this.clear();\n  while (++index < length) {\n    var entry = entries[index];\n    this.set(entry[0], entry[1]);\n  }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\nexport default Hash;\n", "/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n  this.__data__ = [];\n  this.size = 0;\n}\n\nexport default listCacheClear;\n", "import eq from './eq.js';\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n  var length = array.length;\n  while (length--) {\n    if (eq(array[length][0], key)) {\n      return length;\n    }\n  }\n  return -1;\n}\n\nexport default assocIndexOf;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n  var data = this.__data__,\n      index = assocIndexOf(data, key);\n\n  if (index < 0) {\n    return false;\n  }\n  var lastIndex = data.length - 1;\n  if (index == lastIndex) {\n    data.pop();\n  } else {\n    splice.call(data, index, 1);\n  }\n  --this.size;\n  return true;\n}\n\nexport default listCacheDelete;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n  var data = this.__data__,\n      index = assocIndexOf(data, key);\n\n  return index < 0 ? undefined : data[index][1];\n}\n\nexport default listCacheGet;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n  return assocIndexOf(this.__data__, key) > -1;\n}\n\nexport default listCacheHas;\n", "import assocIndexOf from './_assocIndexOf.js';\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n  var data = this.__data__,\n      index = assocIndexOf(data, key);\n\n  if (index < 0) {\n    ++this.size;\n    data.push([key, value]);\n  } else {\n    data[index][1] = value;\n  }\n  return this;\n}\n\nexport default listCacheSet;\n", "import listCacheClear from './_listCacheClear.js';\nimport listCacheDelete from './_listCacheDelete.js';\nimport listCacheGet from './_listCacheGet.js';\nimport listCacheHas from './_listCacheHas.js';\nimport listCacheSet from './_listCacheSet.js';\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n  var index = -1,\n      length = entries == null ? 0 : entries.length;\n\n  this.clear();\n  while (++index < length) {\n    var entry = entries[index];\n    this.set(entry[0], entry[1]);\n  }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nexport default ListCache;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Map = getNative(root, 'Map');\n\nexport default Map;\n", "import Hash from './_Hash.js';\nimport ListCache from './_ListCache.js';\nimport Map from './_Map.js';\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n  this.size = 0;\n  this.__data__ = {\n    'hash': new Hash,\n    'map': new (Map || ListCache),\n    'string': new Hash\n  };\n}\n\nexport default mapCacheClear;\n", "/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n  var type = typeof value;\n  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n    ? (value !== '__proto__')\n    : (value === null);\n}\n\nexport default isKeyable;\n", "import isKeyable from './_isKeyable.js';\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n  var data = map.__data__;\n  return isKeyable(key)\n    ? data[typeof key == 'string' ? 'string' : 'hash']\n    : data.map;\n}\n\nexport default getMapData;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n  var result = getMapData(this, key)['delete'](key);\n  this.size -= result ? 1 : 0;\n  return result;\n}\n\nexport default mapCacheDelete;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n  return getMapData(this, key).get(key);\n}\n\nexport default mapCacheGet;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n  return getMapData(this, key).has(key);\n}\n\nexport default mapCacheHas;\n", "import getMapData from './_getMapData.js';\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n  var data = getMapData(this, key),\n      size = data.size;\n\n  data.set(key, value);\n  this.size += data.size == size ? 0 : 1;\n  return this;\n}\n\nexport default mapCacheSet;\n", "import mapCacheClear from './_mapCacheClear.js';\nimport mapCacheDelete from './_mapCacheDelete.js';\nimport mapCacheGet from './_mapCacheGet.js';\nimport mapCacheHas from './_mapCacheHas.js';\nimport mapCacheSet from './_mapCacheSet.js';\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n  var index = -1,\n      length = entries == null ? 0 : entries.length;\n\n  this.clear();\n  while (++index < length) {\n    var entry = entries[index];\n    this.set(entry[0], entry[1]);\n  }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\nexport default MapCache;\n", "import MapCache from './_MapCache.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n  if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n    throw new TypeError(FUNC_ERROR_TEXT);\n  }\n  var memoized = function() {\n    var args = arguments,\n        key = resolver ? resolver.apply(this, args) : args[0],\n        cache = memoized.cache;\n\n    if (cache.has(key)) {\n      return cache.get(key);\n    }\n    var result = func.apply(this, args);\n    memoized.cache = cache.set(key, result) || cache;\n    return result;\n  };\n  memoized.cache = new (memoize.Cache || MapCache);\n  return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = MapCache;\n\nexport default memoize;\n", "import memoize from './memoize.js';\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n  var result = memoize(func, function(key) {\n    if (cache.size === MAX_MEMOIZE_SIZE) {\n      cache.clear();\n    }\n    return key;\n  });\n\n  var cache = result.cache;\n  return result;\n}\n\nexport default memoizeCapped;\n", "import memoizeCapped from './_memoizeCapped.js';\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n  var result = [];\n  if (string.charCodeAt(0) === 46 /* . */) {\n    result.push('');\n  }\n  string.replace(rePropName, function(match, number, quote, subString) {\n    result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n  });\n  return result;\n});\n\nexport default stringToPath;\n", "import baseToString from './_baseToString.js';\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n  return value == null ? '' : baseToString(value);\n}\n\nexport default toString;\n", "import isArray from './isArray.js';\nimport isKey from './_isKey.js';\nimport stringToPath from './_stringToPath.js';\nimport toString from './toString.js';\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n  if (isArray(value)) {\n    return value;\n  }\n  return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nexport default castPath;\n", "import isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n  if (typeof value == 'string' || isSymbol(value)) {\n    return value;\n  }\n  var result = (value + '');\n  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default toKey;\n", "import castPath from './_castPath.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n  path = castPath(path, object);\n\n  var index = 0,\n      length = path.length;\n\n  while (object != null && index < length) {\n    object = object[toKey(path[index++])];\n  }\n  return (index && index == length) ? object : undefined;\n}\n\nexport default baseGet;\n", "import baseGet from './_baseGet.js';\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n  var result = object == null ? undefined : baseGet(object, path);\n  return result === undefined ? defaultValue : result;\n}\n\nexport default get;\n", "/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n  var index = -1,\n      length = values.length,\n      offset = array.length;\n\n  while (++index < length) {\n    array[offset + index] = values[index];\n  }\n  return array;\n}\n\nexport default arrayPush;\n", "import overArg from './_overArg.js';\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nexport default getPrototype;\n", "import baseGetTag from './_baseGetTag.js';\nimport getPrototype from './_getPrototype.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n    objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n *   this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n  if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n    return false;\n  }\n  var proto = getPrototype(value);\n  if (proto === null) {\n    return true;\n  }\n  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n  return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n    funcToString.call(Ctor) == objectCtorString;\n}\n\nexport default isPlainObject;\n", "/**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\nfunction baseSlice(array, start, end) {\n  var index = -1,\n      length = array.length;\n\n  if (start < 0) {\n    start = -start > length ? 0 : (length + start);\n  }\n  end = end > length ? length : end;\n  if (end < 0) {\n    end += length;\n  }\n  length = start > end ? 0 : ((end - start) >>> 0);\n  start >>>= 0;\n\n  var result = Array(length);\n  while (++index < length) {\n    result[index] = array[index + start];\n  }\n  return result;\n}\n\nexport default baseSlice;\n", "import baseSlice from './_baseSlice.js';\n\n/**\n * Casts `array` to a slice if it's needed.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {number} start The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the cast slice.\n */\nfunction castSlice(array, start, end) {\n  var length = array.length;\n  end = end === undefined ? length : end;\n  return (!start && end >= length) ? array : baseSlice(array, start, end);\n}\n\nexport default castSlice;\n", "/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n    rsComboMarksRange = '\\\\u0300-\\\\u036f',\n    reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n    rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n    rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsZWJ = '\\\\u200d';\n\n/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\nvar reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');\n\n/**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\nfunction hasUnicode(string) {\n  return reHasUnicode.test(string);\n}\n\nexport default hasUnicode;\n", "/**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction asciiToArray(string) {\n  return string.split('');\n}\n\nexport default asciiToArray;\n", "/** Used to compose unicode character classes. */\nvar rsAstralRange = '\\\\ud800-\\\\udfff',\n    rsComboMarksRange = '\\\\u0300-\\\\u036f',\n    reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n    rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n    rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n    rsVarRange = '\\\\ufe0e\\\\ufe0f';\n\n/** Used to compose unicode capture groups. */\nvar rsAstral = '[' + rsAstralRange + ']',\n    rsCombo = '[' + rsComboRange + ']',\n    rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n    rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n    rsNonAstral = '[^' + rsAstralRange + ']',\n    rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n    rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n    rsZWJ = '\\\\u200d';\n\n/** Used to compose unicode regexes. */\nvar reOptMod = rsModifier + '?',\n    rsOptVar = '[' + rsVarRange + ']?',\n    rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n    rsSeq = rsOptVar + reOptMod + rsOptJoin,\n    rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\nvar reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n/**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction unicodeToArray(string) {\n  return string.match(reUnicode) || [];\n}\n\nexport default unicodeToArray;\n", "import asciiToArray from './_asciiToArray.js';\nimport hasUnicode from './_hasUnicode.js';\nimport unicodeToArray from './_unicodeToArray.js';\n\n/**\n * Converts `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\nfunction stringToArray(string) {\n  return hasUnicode(string)\n    ? unicodeToArray(string)\n    : asciiToArray(string);\n}\n\nexport default stringToArray;\n", "import castSlice from './_castSlice.js';\nimport hasUnicode from './_hasUnicode.js';\nimport stringToArray from './_stringToArray.js';\nimport toString from './toString.js';\n\n/**\n * Creates a function like `_.lowerFirst`.\n *\n * @private\n * @param {string} methodName The name of the `String` case method to use.\n * @returns {Function} Returns the new case function.\n */\nfunction createCaseFirst(methodName) {\n  return function(string) {\n    string = toString(string);\n\n    var strSymbols = hasUnicode(string)\n      ? stringToArray(string)\n      : undefined;\n\n    var chr = strSymbols\n      ? strSymbols[0]\n      : string.charAt(0);\n\n    var trailing = strSymbols\n      ? castSlice(strSymbols, 1).join('')\n      : string.slice(1);\n\n    return chr[methodName]() + trailing;\n  };\n}\n\nexport default createCaseFirst;\n", "import createCaseFirst from './_createCaseFirst.js';\n\n/**\n * Converts the first character of `string` to upper case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.upperFirst('fred');\n * // => 'Fred'\n *\n * _.upperFirst('FRED');\n * // => 'FRED'\n */\nvar upperFirst = createCaseFirst('toUpperCase');\n\nexport default upperFirst;\n", "import ListCache from './_ListCache.js';\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n  this.__data__ = new ListCache;\n  this.size = 0;\n}\n\nexport default stackClear;\n", "/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n  var data = this.__data__,\n      result = data['delete'](key);\n\n  this.size = data.size;\n  return result;\n}\n\nexport default stackDelete;\n", "/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n  return this.__data__.get(key);\n}\n\nexport default stackGet;\n", "/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n  return this.__data__.has(key);\n}\n\nexport default stackHas;\n", "import ListCache from './_ListCache.js';\nimport Map from './_Map.js';\nimport MapCache from './_MapCache.js';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n  var data = this.__data__;\n  if (data instanceof ListCache) {\n    var pairs = data.__data__;\n    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n      pairs.push([key, value]);\n      this.size = ++data.size;\n      return this;\n    }\n    data = this.__data__ = new MapCache(pairs);\n  }\n  data.set(key, value);\n  this.size = data.size;\n  return this;\n}\n\nexport default stackSet;\n", "import ListCache from './_ListCache.js';\nimport stackClear from './_stackClear.js';\nimport stackDelete from './_stackDelete.js';\nimport stackGet from './_stackGet.js';\nimport stackHas from './_stackHas.js';\nimport stackSet from './_stackSet.js';\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n  var data = this.__data__ = new ListCache(entries);\n  this.size = data.size;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\nexport default Stack;\n", "import copyObject from './_copyObject.js';\nimport keys from './keys.js';\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n  return object && copyObject(source, keys(source), object);\n}\n\nexport default baseAssign;\n", "import copyObject from './_copyObject.js';\nimport keysIn from './keysIn.js';\n\n/**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssignIn(object, source) {\n  return object && copyObject(source, keysIn(source), object);\n}\n\nexport default baseAssignIn;\n", "import root from './_root.js';\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n    allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;\n\n/**\n * Creates a clone of  `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n  if (isDeep) {\n    return buffer.slice();\n  }\n  var length = buffer.length,\n      result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n  buffer.copy(result);\n  return result;\n}\n\nexport default cloneBuffer;\n", "/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n  var index = -1,\n      length = array == null ? 0 : array.length,\n      resIndex = 0,\n      result = [];\n\n  while (++index < length) {\n    var value = array[index];\n    if (predicate(value, index, array)) {\n      result[resIndex++] = value;\n    }\n  }\n  return result;\n}\n\nexport default arrayFilter;\n", "/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n  return [];\n}\n\nexport default stubArray;\n", "import arrayFilter from './_arrayFilter.js';\nimport stubArray from './stubArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n  if (object == null) {\n    return [];\n  }\n  object = Object(object);\n  return arrayFilter(nativeGetSymbols(object), function(symbol) {\n    return propertyIsEnumerable.call(object, symbol);\n  });\n};\n\nexport default getSymbols;\n", "import copyObject from './_copyObject.js';\nimport getSymbols from './_getSymbols.js';\n\n/**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n  return copyObject(source, getSymbols(source), object);\n}\n\nexport default copySymbols;\n", "import arrayPush from './_arrayPush.js';\nimport getPrototype from './_getPrototype.js';\nimport getSymbols from './_getSymbols.js';\nimport stubArray from './stubArray.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n  var result = [];\n  while (object) {\n    arrayPush(result, getSymbols(object));\n    object = getPrototype(object);\n  }\n  return result;\n};\n\nexport default getSymbolsIn;\n", "import copyObject from './_copyObject.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\n\n/**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbolsIn(source, object) {\n  return copyObject(source, getSymbolsIn(source), object);\n}\n\nexport default copySymbolsIn;\n", "import arrayPush from './_arrayPush.js';\nimport isArray from './isArray.js';\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n  var result = keysFunc(object);\n  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nexport default baseGetAllKeys;\n", "import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbols from './_getSymbols.js';\nimport keys from './keys.js';\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n  return baseGetAllKeys(object, keys, getSymbols);\n}\n\nexport default getAllKeys;\n", "import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n  return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nexport default getAllKeysIn;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView');\n\nexport default DataView;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Promise = getNative(root, 'Promise');\n\nexport default Promise;\n", "import getNative from './_getNative.js';\nimport root from './_root.js';\n\n/* Built-in method references that are verified to be native. */\nvar Set = getNative(root, 'Set');\n\nexport default Set;\n", "import DataView from './_DataView.js';\nimport Map from './_Map.js';\nimport Promise from './_Promise.js';\nimport Set from './_Set.js';\nimport WeakMap from './_WeakMap.js';\nimport baseGetTag from './_baseGetTag.js';\nimport toSource from './_toSource.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n    objectTag = '[object Object]',\n    promiseTag = '[object Promise]',\n    setTag = '[object Set]',\n    weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n    mapCtorString = toSource(Map),\n    promiseCtorString = toSource(Promise),\n    setCtorString = toSource(Set),\n    weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n    (Map && getTag(new Map) != mapTag) ||\n    (Promise && getTag(Promise.resolve()) != promiseTag) ||\n    (Set && getTag(new Set) != setTag) ||\n    (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n  getTag = function(value) {\n    var result = baseGetTag(value),\n        Ctor = result == objectTag ? value.constructor : undefined,\n        ctorString = Ctor ? toSource(Ctor) : '';\n\n    if (ctorString) {\n      switch (ctorString) {\n        case dataViewCtorString: return dataViewTag;\n        case mapCtorString: return mapTag;\n        case promiseCtorString: return promiseTag;\n        case setCtorString: return setTag;\n        case weakMapCtorString: return weakMapTag;\n      }\n    }\n    return result;\n  };\n}\n\nexport default getTag;\n", "/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n  var length = array.length,\n      result = new array.constructor(length);\n\n  // Add properties assigned by `RegExp#exec`.\n  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n    result.index = array.index;\n    result.input = array.input;\n  }\n  return result;\n}\n\nexport default initCloneArray;\n", "import root from './_root.js';\n\n/** Built-in value references. */\nvar Uint8Array = root.Uint8Array;\n\nexport default Uint8Array;\n", "import Uint8Array from './_Uint8Array.js';\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n  new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n  return result;\n}\n\nexport default cloneArrayBuffer;\n", "import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n  var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n  return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nexport default cloneDataView;\n", "/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n  var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n  result.lastIndex = regexp.lastIndex;\n  return result;\n}\n\nexport default cloneRegExp;\n", "import Symbol from './_Symbol.js';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n  return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nexport default cloneSymbol;\n", "import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n  var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\nexport default cloneTypedArray;\n", "import cloneArrayBuffer from './_cloneArrayBuffer.js';\nimport cloneDataView from './_cloneDataView.js';\nimport cloneRegExp from './_cloneRegExp.js';\nimport cloneSymbol from './_cloneSymbol.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]',\n    float32Tag = '[object Float32Array]',\n    float64Tag = '[object Float64Array]',\n    int8Tag = '[object Int8Array]',\n    int16Tag = '[object Int16Array]',\n    int32Tag = '[object Int32Array]',\n    uint8Tag = '[object Uint8Array]',\n    uint8ClampedTag = '[object Uint8ClampedArray]',\n    uint16Tag = '[object Uint16Array]',\n    uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n  var Ctor = object.constructor;\n  switch (tag) {\n    case arrayBufferTag:\n      return cloneArrayBuffer(object);\n\n    case boolTag:\n    case dateTag:\n      return new Ctor(+object);\n\n    case dataViewTag:\n      return cloneDataView(object, isDeep);\n\n    case float32Tag: case float64Tag:\n    case int8Tag: case int16Tag: case int32Tag:\n    case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n      return cloneTypedArray(object, isDeep);\n\n    case mapTag:\n      return new Ctor;\n\n    case numberTag:\n    case stringTag:\n      return new Ctor(object);\n\n    case regexpTag:\n      return cloneRegExp(object);\n\n    case setTag:\n      return new Ctor;\n\n    case symbolTag:\n      return cloneSymbol(object);\n  }\n}\n\nexport default initCloneByTag;\n", "import baseCreate from './_baseCreate.js';\nimport getPrototype from './_getPrototype.js';\nimport isPrototype from './_isPrototype.js';\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n  return (typeof object.constructor == 'function' && !isPrototype(object))\n    ? baseCreate(getPrototype(object))\n    : {};\n}\n\nexport default initCloneObject;\n", "import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n  return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nexport default baseIsMap;\n", "import baseIsMap from './_baseIsMap.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nexport default isMap;\n", "import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n  return isObjectLike(value) && getTag(value) == setTag;\n}\n\nexport default baseIsSet;\n", "import baseIsSet from './_baseIsSet.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nexport default isSet;\n", "import Stack from './_Stack.js';\nimport arrayEach from './_arrayEach.js';\nimport assignValue from './_assignValue.js';\nimport baseAssign from './_baseAssign.js';\nimport baseAssignIn from './_baseAssignIn.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport copyArray from './_copyArray.js';\nimport copySymbols from './_copySymbols.js';\nimport copySymbolsIn from './_copySymbolsIn.js';\nimport getAllKeys from './_getAllKeys.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\nimport getTag from './_getTag.js';\nimport initCloneArray from './_initCloneArray.js';\nimport initCloneByTag from './_initCloneByTag.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isMap from './isMap.js';\nimport isObject from './isObject.js';\nimport isSet from './isSet.js';\nimport keys from './keys.js';\nimport keysIn from './keysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n    CLONE_FLAT_FLAG = 2,\n    CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    arrayTag = '[object Array]',\n    boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    errorTag = '[object Error]',\n    funcTag = '[object Function]',\n    genTag = '[object GeneratorFunction]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    objectTag = '[object Object]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    symbolTag = '[object Symbol]',\n    weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]',\n    float32Tag = '[object Float32Array]',\n    float64Tag = '[object Float64Array]',\n    int8Tag = '[object Int8Array]',\n    int16Tag = '[object Int16Array]',\n    int32Tag = '[object Int32Array]',\n    uint8Tag = '[object Uint8Array]',\n    uint8ClampedTag = '[object Uint8ClampedArray]',\n    uint16Tag = '[object Uint16Array]',\n    uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n *  1 - Deep clone\n *  2 - Flatten inherited properties\n *  4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n  var result,\n      isDeep = bitmask & CLONE_DEEP_FLAG,\n      isFlat = bitmask & CLONE_FLAT_FLAG,\n      isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n  if (customizer) {\n    result = object ? customizer(value, key, object, stack) : customizer(value);\n  }\n  if (result !== undefined) {\n    return result;\n  }\n  if (!isObject(value)) {\n    return value;\n  }\n  var isArr = isArray(value);\n  if (isArr) {\n    result = initCloneArray(value);\n    if (!isDeep) {\n      return copyArray(value, result);\n    }\n  } else {\n    var tag = getTag(value),\n        isFunc = tag == funcTag || tag == genTag;\n\n    if (isBuffer(value)) {\n      return cloneBuffer(value, isDeep);\n    }\n    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n      result = (isFlat || isFunc) ? {} : initCloneObject(value);\n      if (!isDeep) {\n        return isFlat\n          ? copySymbolsIn(value, baseAssignIn(result, value))\n          : copySymbols(value, baseAssign(result, value));\n      }\n    } else {\n      if (!cloneableTags[tag]) {\n        return object ? value : {};\n      }\n      result = initCloneByTag(value, tag, isDeep);\n    }\n  }\n  // Check for circular references and return its corresponding clone.\n  stack || (stack = new Stack);\n  var stacked = stack.get(value);\n  if (stacked) {\n    return stacked;\n  }\n  stack.set(value, result);\n\n  if (isSet(value)) {\n    value.forEach(function(subValue) {\n      result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n    });\n  } else if (isMap(value)) {\n    value.forEach(function(subValue, key) {\n      result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n    });\n  }\n\n  var keysFunc = isFull\n    ? (isFlat ? getAllKeysIn : getAllKeys)\n    : (isFlat ? keysIn : keys);\n\n  var props = isArr ? undefined : keysFunc(value);\n  arrayEach(props || value, function(subValue, key) {\n    if (props) {\n      key = subValue;\n      subValue = value[key];\n    }\n    // Recursively populate clone (susceptible to call stack limits).\n    assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n  });\n  return result;\n}\n\nexport default baseClone;\n", "import baseClone from './_baseClone.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\nfunction clone(value) {\n  return baseClone(value, CLONE_SYMBOLS_FLAG);\n}\n\nexport default clone;\n", "import baseClone from './_baseClone.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n    CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n}\n\nexport default cloneDeep;\n", "import baseClone from './_baseClone.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n    CLONE_SYMBOLS_FLAG = 4;\n\n/**\n * This method is like `_.cloneWith` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the deep cloned value.\n * @see _.cloneWith\n * @example\n *\n * function customizer(value) {\n *   if (_.isElement(value)) {\n *     return value.cloneNode(true);\n *   }\n * }\n *\n * var el = _.cloneDeepWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 20\n */\nfunction cloneDeepWith(value, customizer) {\n  customizer = typeof customizer == 'function' ? customizer : undefined;\n  return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n}\n\nexport default cloneDeepWith;\n", "/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n  this.__data__.set(value, HASH_UNDEFINED);\n  return this;\n}\n\nexport default setCacheAdd;\n", "/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n  return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n", "import MapCache from './_MapCache.js';\nimport setCacheAdd from './_setCacheAdd.js';\nimport setCacheHas from './_setCacheHas.js';\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n  var index = -1,\n      length = values == null ? 0 : values.length;\n\n  this.__data__ = new MapCache;\n  while (++index < length) {\n    this.add(values[index]);\n  }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nexport default SetCache;\n", "/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n *  else `false`.\n */\nfunction arraySome(array, predicate) {\n  var index = -1,\n      length = array == null ? 0 : array.length;\n\n  while (++index < length) {\n    if (predicate(array[index], index, array)) {\n      return true;\n    }\n  }\n  return false;\n}\n\nexport default arraySome;\n", "/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n  return cache.has(key);\n}\n\nexport default cacheHas;\n", "import SetCache from './_SetCache.js';\nimport arraySome from './_arraySome.js';\nimport cacheHas from './_cacheHas.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n      arrLength = array.length,\n      othLength = other.length;\n\n  if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n    return false;\n  }\n  // Check that cyclic values are equal.\n  var arrStacked = stack.get(array);\n  var othStacked = stack.get(other);\n  if (arrStacked && othStacked) {\n    return arrStacked == other && othStacked == array;\n  }\n  var index = -1,\n      result = true,\n      seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n  stack.set(array, other);\n  stack.set(other, array);\n\n  // Ignore non-index properties.\n  while (++index < arrLength) {\n    var arrValue = array[index],\n        othValue = other[index];\n\n    if (customizer) {\n      var compared = isPartial\n        ? customizer(othValue, arrValue, index, other, array, stack)\n        : customizer(arrValue, othValue, index, array, other, stack);\n    }\n    if (compared !== undefined) {\n      if (compared) {\n        continue;\n      }\n      result = false;\n      break;\n    }\n    // Recursively compare arrays (susceptible to call stack limits).\n    if (seen) {\n      if (!arraySome(other, function(othValue, othIndex) {\n            if (!cacheHas(seen, othIndex) &&\n                (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n              return seen.push(othIndex);\n            }\n          })) {\n        result = false;\n        break;\n      }\n    } else if (!(\n          arrValue === othValue ||\n            equalFunc(arrValue, othValue, bitmask, customizer, stack)\n        )) {\n      result = false;\n      break;\n    }\n  }\n  stack['delete'](array);\n  stack['delete'](other);\n  return result;\n}\n\nexport default equalArrays;\n", "/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n  var index = -1,\n      result = Array(map.size);\n\n  map.forEach(function(value, key) {\n    result[++index] = [key, value];\n  });\n  return result;\n}\n\nexport default mapToArray;\n", "/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n  var index = -1,\n      result = Array(set.size);\n\n  set.forEach(function(value) {\n    result[++index] = value;\n  });\n  return result;\n}\n\nexport default setToArray;\n", "import Symbol from './_Symbol.js';\nimport Uint8Array from './_Uint8Array.js';\nimport eq from './eq.js';\nimport equalArrays from './_equalArrays.js';\nimport mapToArray from './_mapToArray.js';\nimport setToArray from './_setToArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n    dateTag = '[object Date]',\n    errorTag = '[object Error]',\n    mapTag = '[object Map]',\n    numberTag = '[object Number]',\n    regexpTag = '[object RegExp]',\n    setTag = '[object Set]',\n    stringTag = '[object String]',\n    symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n    dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n    symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n  switch (tag) {\n    case dataViewTag:\n      if ((object.byteLength != other.byteLength) ||\n          (object.byteOffset != other.byteOffset)) {\n        return false;\n      }\n      object = object.buffer;\n      other = other.buffer;\n\n    case arrayBufferTag:\n      if ((object.byteLength != other.byteLength) ||\n          !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n        return false;\n      }\n      return true;\n\n    case boolTag:\n    case dateTag:\n    case numberTag:\n      // Coerce booleans to `1` or `0` and dates to milliseconds.\n      // Invalid dates are coerced to `NaN`.\n      return eq(+object, +other);\n\n    case errorTag:\n      return object.name == other.name && object.message == other.message;\n\n    case regexpTag:\n    case stringTag:\n      // Coerce regexes to strings and treat strings, primitives and objects,\n      // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n      // for more details.\n      return object == (other + '');\n\n    case mapTag:\n      var convert = mapToArray;\n\n    case setTag:\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n      convert || (convert = setToArray);\n\n      if (object.size != other.size && !isPartial) {\n        return false;\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(object);\n      if (stacked) {\n        return stacked == other;\n      }\n      bitmask |= COMPARE_UNORDERED_FLAG;\n\n      // Recursively compare objects (susceptible to call stack limits).\n      stack.set(object, other);\n      var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n      stack['delete'](object);\n      return result;\n\n    case symbolTag:\n      if (symbolValueOf) {\n        return symbolValueOf.call(object) == symbolValueOf.call(other);\n      }\n  }\n  return false;\n}\n\nexport default equalByTag;\n", "import getAllKeys from './_getAllKeys.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n  var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n      objProps = getAllKeys(object),\n      objLength = objProps.length,\n      othProps = getAllKeys(other),\n      othLength = othProps.length;\n\n  if (objLength != othLength && !isPartial) {\n    return false;\n  }\n  var index = objLength;\n  while (index--) {\n    var key = objProps[index];\n    if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n      return false;\n    }\n  }\n  // Check that cyclic values are equal.\n  var objStacked = stack.get(object);\n  var othStacked = stack.get(other);\n  if (objStacked && othStacked) {\n    return objStacked == other && othStacked == object;\n  }\n  var result = true;\n  stack.set(object, other);\n  stack.set(other, object);\n\n  var skipCtor = isPartial;\n  while (++index < objLength) {\n    key = objProps[index];\n    var objValue = object[key],\n        othValue = other[key];\n\n    if (customizer) {\n      var compared = isPartial\n        ? customizer(othValue, objValue, key, other, object, stack)\n        : customizer(objValue, othValue, key, object, other, stack);\n    }\n    // Recursively compare objects (susceptible to call stack limits).\n    if (!(compared === undefined\n          ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n          : compared\n        )) {\n      result = false;\n      break;\n    }\n    skipCtor || (skipCtor = key == 'constructor');\n  }\n  if (result && !skipCtor) {\n    var objCtor = object.constructor,\n        othCtor = other.constructor;\n\n    // Non `Object` object instances with different constructors are not equal.\n    if (objCtor != othCtor &&\n        ('constructor' in object && 'constructor' in other) &&\n        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n          typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n      result = false;\n    }\n  }\n  stack['delete'](object);\n  stack['delete'](other);\n  return result;\n}\n\nexport default equalObjects;\n", "import Stack from './_Stack.js';\nimport equalArrays from './_equalArrays.js';\nimport equalByTag from './_equalByTag.js';\nimport equalObjects from './_equalObjects.js';\nimport getTag from './_getTag.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n    arrayTag = '[object Array]',\n    objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n  var objIsArr = isArray(object),\n      othIsArr = isArray(other),\n      objTag = objIsArr ? arrayTag : getTag(object),\n      othTag = othIsArr ? arrayTag : getTag(other);\n\n  objTag = objTag == argsTag ? objectTag : objTag;\n  othTag = othTag == argsTag ? objectTag : othTag;\n\n  var objIsObj = objTag == objectTag,\n      othIsObj = othTag == objectTag,\n      isSameTag = objTag == othTag;\n\n  if (isSameTag && isBuffer(object)) {\n    if (!isBuffer(other)) {\n      return false;\n    }\n    objIsArr = true;\n    objIsObj = false;\n  }\n  if (isSameTag && !objIsObj) {\n    stack || (stack = new Stack);\n    return (objIsArr || isTypedArray(object))\n      ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n      : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n  }\n  if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n    if (objIsWrapped || othIsWrapped) {\n      var objUnwrapped = objIsWrapped ? object.value() : object,\n          othUnwrapped = othIsWrapped ? other.value() : other;\n\n      stack || (stack = new Stack);\n      return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n    }\n  }\n  if (!isSameTag) {\n    return false;\n  }\n  stack || (stack = new Stack);\n  return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nexport default baseIsEqualDeep;\n", "import baseIsEqualDeep from './_baseIsEqualDeep.js';\nimport isObjectLike from './isObjectLike.js';\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n *  1 - Unordered comparison\n *  2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n  if (value === other) {\n    return true;\n  }\n  if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n    return value !== value && other !== other;\n  }\n  return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nexport default baseIsEqual;\n", "import Stack from './_Stack.js';\nimport baseIsEqual from './_baseIsEqual.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n  var index = matchData.length,\n      length = index,\n      noCustomizer = !customizer;\n\n  if (object == null) {\n    return !length;\n  }\n  object = Object(object);\n  while (index--) {\n    var data = matchData[index];\n    if ((noCustomizer && data[2])\n          ? data[1] !== object[data[0]]\n          : !(data[0] in object)\n        ) {\n      return false;\n    }\n  }\n  while (++index < length) {\n    data = matchData[index];\n    var key = data[0],\n        objValue = object[key],\n        srcValue = data[1];\n\n    if (noCustomizer && data[2]) {\n      if (objValue === undefined && !(key in object)) {\n        return false;\n      }\n    } else {\n      var stack = new Stack;\n      if (customizer) {\n        var result = customizer(objValue, srcValue, key, object, source, stack);\n      }\n      if (!(result === undefined\n            ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n            : result\n          )) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\nexport default baseIsMatch;\n", "import isObject from './isObject.js';\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n *  equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n  return value === value && !isObject(value);\n}\n\nexport default isStrictComparable;\n", "import isStrictComparable from './_isStrictComparable.js';\nimport keys from './keys.js';\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n  var result = keys(object),\n      length = result.length;\n\n  while (length--) {\n    var key = result[length],\n        value = object[key];\n\n    result[length] = [key, value, isStrictComparable(value)];\n  }\n  return result;\n}\n\nexport default getMatchData;\n", "/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n  return function(object) {\n    if (object == null) {\n      return false;\n    }\n    return object[key] === srcValue &&\n      (srcValue !== undefined || (key in Object(object)));\n  };\n}\n\nexport default matchesStrictComparable;\n", "import baseIsMatch from './_baseIsMatch.js';\nimport getMatchData from './_getMatchData.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n  var matchData = getMatchData(source);\n  if (matchData.length == 1 && matchData[0][2]) {\n    return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n  }\n  return function(object) {\n    return object === source || baseIsMatch(object, source, matchData);\n  };\n}\n\nexport default baseMatches;\n", "/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n  return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n", "import castPath from './_castPath.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isIndex from './_isIndex.js';\nimport isLength from './isLength.js';\nimport toKey from './_toKey.js';\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n  path = castPath(path, object);\n\n  var index = -1,\n      length = path.length,\n      result = false;\n\n  while (++index < length) {\n    var key = toKey(path[index]);\n    if (!(result = object != null && hasFunc(object, key))) {\n      break;\n    }\n    object = object[key];\n  }\n  if (result || ++index != length) {\n    return result;\n  }\n  length = object == null ? 0 : object.length;\n  return !!length && isLength(length) && isIndex(key, length) &&\n    (isArray(object) || isArguments(object));\n}\n\nexport default hasPath;\n", "import baseHasIn from './_baseHasIn.js';\nimport hasPath from './_hasPath.js';\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n  return object != null && hasPath(object, path, baseHasIn);\n}\n\nexport default hasIn;\n", "import baseIsEqual from './_baseIsEqual.js';\nimport get from './get.js';\nimport hasIn from './hasIn.js';\nimport isKey from './_isKey.js';\nimport isStrictComparable from './_isStrictComparable.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\nimport toKey from './_toKey.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n    COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n  if (isKey(path) && isStrictComparable(srcValue)) {\n    return matchesStrictComparable(toKey(path), srcValue);\n  }\n  return function(object) {\n    var objValue = get(object, path);\n    return (objValue === undefined && objValue === srcValue)\n      ? hasIn(object, path)\n      : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n  };\n}\n\nexport default baseMatchesProperty;\n", "/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n  return function(object) {\n    return object == null ? undefined : object[key];\n  };\n}\n\nexport default baseProperty;\n", "import baseGet from './_baseGet.js';\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n  return function(object) {\n    return baseGet(object, path);\n  };\n}\n\nexport default basePropertyDeep;\n", "import baseProperty from './_baseProperty.js';\nimport basePropertyDeep from './_basePropertyDeep.js';\nimport isKey from './_isKey.js';\nimport toKey from './_toKey.js';\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n *   { 'a': { 'b': 2 } },\n *   { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n  return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nexport default property;\n", "import baseMatches from './_baseMatches.js';\nimport baseMatchesProperty from './_baseMatchesProperty.js';\nimport identity from './identity.js';\nimport isArray from './isArray.js';\nimport property from './property.js';\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n  // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n  // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n  if (typeof value == 'function') {\n    return value;\n  }\n  if (value == null) {\n    return identity;\n  }\n  if (typeof value == 'object') {\n    return isArray(value)\n      ? baseMatchesProperty(value[0], value[1])\n      : baseMatches(value);\n  }\n  return property(value);\n}\n\nexport default baseIteratee;\n", "/**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseFor(fromRight) {\n  return function(object, iteratee, keysFunc) {\n    var index = -1,\n        iterable = Object(object),\n        props = keysFunc(object),\n        length = props.length;\n\n    while (length--) {\n      var key = props[fromRight ? length : ++index];\n      if (iteratee(iterable[key], key, iterable) === false) {\n        break;\n      }\n    }\n    return object;\n  };\n}\n\nexport default createBaseFor;\n", "import createBaseFor from './_createBaseFor.js';\n\n/**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\nvar baseFor = createBaseFor();\n\nexport default baseFor;\n", "import baseFor from './_baseFor.js';\nimport keys from './keys.js';\n\n/**\n * The base implementation of `_.forOwn` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\nfunction baseForOwn(object, iteratee) {\n  return object && baseFor(object, iteratee, keys);\n}\n\nexport default baseForOwn;\n", "import isArrayLike from './isArrayLike.js';\n\n/**\n * Creates a `baseEach` or `baseEachRight` function.\n *\n * @private\n * @param {Function} eachFunc The function to iterate over a collection.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseEach(eachFunc, fromRight) {\n  return function(collection, iteratee) {\n    if (collection == null) {\n      return collection;\n    }\n    if (!isArrayLike(collection)) {\n      return eachFunc(collection, iteratee);\n    }\n    var length = collection.length,\n        index = fromRight ? length : -1,\n        iterable = Object(collection);\n\n    while ((fromRight ? index-- : ++index < length)) {\n      if (iteratee(iterable[index], index, iterable) === false) {\n        break;\n      }\n    }\n    return collection;\n  };\n}\n\nexport default createBaseEach;\n", "import baseForOwn from './_baseForOwn.js';\nimport createBaseEach from './_createBaseEach.js';\n\n/**\n * The base implementation of `_.forEach` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\nvar baseEach = createBaseEach(baseForOwn);\n\nexport default baseEach;\n", "import root from './_root.js';\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n *   console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n  return root.Date.now();\n};\n\nexport default now;\n", "import isObject from './isObject.js';\nimport now from './now.js';\nimport toNumber from './toNumber.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n    nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n *  Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n *  The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n *  Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n *   'leading': true,\n *   'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n  var lastArgs,\n      lastThis,\n      maxWait,\n      result,\n      timerId,\n      lastCallTime,\n      lastInvokeTime = 0,\n      leading = false,\n      maxing = false,\n      trailing = true;\n\n  if (typeof func != 'function') {\n    throw new TypeError(FUNC_ERROR_TEXT);\n  }\n  wait = toNumber(wait) || 0;\n  if (isObject(options)) {\n    leading = !!options.leading;\n    maxing = 'maxWait' in options;\n    maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n    trailing = 'trailing' in options ? !!options.trailing : trailing;\n  }\n\n  function invokeFunc(time) {\n    var args = lastArgs,\n        thisArg = lastThis;\n\n    lastArgs = lastThis = undefined;\n    lastInvokeTime = time;\n    result = func.apply(thisArg, args);\n    return result;\n  }\n\n  function leadingEdge(time) {\n    // Reset any `maxWait` timer.\n    lastInvokeTime = time;\n    // Start the timer for the trailing edge.\n    timerId = setTimeout(timerExpired, wait);\n    // Invoke the leading edge.\n    return leading ? invokeFunc(time) : result;\n  }\n\n  function remainingWait(time) {\n    var timeSinceLastCall = time - lastCallTime,\n        timeSinceLastInvoke = time - lastInvokeTime,\n        timeWaiting = wait - timeSinceLastCall;\n\n    return maxing\n      ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n      : timeWaiting;\n  }\n\n  function shouldInvoke(time) {\n    var timeSinceLastCall = time - lastCallTime,\n        timeSinceLastInvoke = time - lastInvokeTime;\n\n    // Either this is the first call, activity has stopped and we're at the\n    // trailing edge, the system time has gone backwards and we're treating\n    // it as the trailing edge, or we've hit the `maxWait` limit.\n    return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n      (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n  }\n\n  function timerExpired() {\n    var time = now();\n    if (shouldInvoke(time)) {\n      return trailingEdge(time);\n    }\n    // Restart the timer.\n    timerId = setTimeout(timerExpired, remainingWait(time));\n  }\n\n  function trailingEdge(time) {\n    timerId = undefined;\n\n    // Only invoke if we have `lastArgs` which means `func` has been\n    // debounced at least once.\n    if (trailing && lastArgs) {\n      return invokeFunc(time);\n    }\n    lastArgs = lastThis = undefined;\n    return result;\n  }\n\n  function cancel() {\n    if (timerId !== undefined) {\n      clearTimeout(timerId);\n    }\n    lastInvokeTime = 0;\n    lastArgs = lastCallTime = lastThis = timerId = undefined;\n  }\n\n  function flush() {\n    return timerId === undefined ? result : trailingEdge(now());\n  }\n\n  function debounced() {\n    var time = now(),\n        isInvoking = shouldInvoke(time);\n\n    lastArgs = arguments;\n    lastThis = this;\n    lastCallTime = time;\n\n    if (isInvoking) {\n      if (timerId === undefined) {\n        return leadingEdge(lastCallTime);\n      }\n      if (maxing) {\n        // Handle invocations in a tight loop.\n        clearTimeout(timerId);\n        timerId = setTimeout(timerExpired, wait);\n        return invokeFunc(lastCallTime);\n      }\n    }\n    if (timerId === undefined) {\n      timerId = setTimeout(timerExpired, wait);\n    }\n    return result;\n  }\n  debounced.cancel = cancel;\n  debounced.flush = flush;\n  return debounced;\n}\n\nexport default debounce;\n", "import baseAssignValue from './_baseAssignValue.js';\nimport eq from './eq.js';\n\n/**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignMergeValue(object, key, value) {\n  if ((value !== undefined && !eq(object[key], value)) ||\n      (value === undefined && !(key in object))) {\n    baseAssignValue(object, key, value);\n  }\n}\n\nexport default assignMergeValue;\n", "import isArrayLike from './isArrayLike.js';\nimport isObjectLike from './isObjectLike.js';\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n *  else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n  return isObjectLike(value) && isArrayLike(value);\n}\n\nexport default isArrayLikeObject;\n", "/**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction safeGet(object, key) {\n  if (key === 'constructor' && typeof object[key] === 'function') {\n    return;\n  }\n\n  if (key == '__proto__') {\n    return;\n  }\n\n  return object[key];\n}\n\nexport default safeGet;\n", "import copyObject from './_copyObject.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n *   this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\nfunction toPlainObject(value) {\n  return copyObject(value, keysIn(value));\n}\n\nexport default toPlainObject;\n", "import assignMergeValue from './_assignMergeValue.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\nimport copyArray from './_copyArray.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isArrayLikeObject from './isArrayLikeObject.js';\nimport isBuffer from './isBuffer.js';\nimport isFunction from './isFunction.js';\nimport isObject from './isObject.js';\nimport isPlainObject from './isPlainObject.js';\nimport isTypedArray from './isTypedArray.js';\nimport safeGet from './_safeGet.js';\nimport toPlainObject from './toPlainObject.js';\n\n/**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n *  counterparts.\n */\nfunction baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n  var objValue = safeGet(object, key),\n      srcValue = safeGet(source, key),\n      stacked = stack.get(srcValue);\n\n  if (stacked) {\n    assignMergeValue(object, key, stacked);\n    return;\n  }\n  var newValue = customizer\n    ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n    : undefined;\n\n  var isCommon = newValue === undefined;\n\n  if (isCommon) {\n    var isArr = isArray(srcValue),\n        isBuff = !isArr && isBuffer(srcValue),\n        isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n    newValue = srcValue;\n    if (isArr || isBuff || isTyped) {\n      if (isArray(objValue)) {\n        newValue = objValue;\n      }\n      else if (isArrayLikeObject(objValue)) {\n        newValue = copyArray(objValue);\n      }\n      else if (isBuff) {\n        isCommon = false;\n        newValue = cloneBuffer(srcValue, true);\n      }\n      else if (isTyped) {\n        isCommon = false;\n        newValue = cloneTypedArray(srcValue, true);\n      }\n      else {\n        newValue = [];\n      }\n    }\n    else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n      newValue = objValue;\n      if (isArguments(objValue)) {\n        newValue = toPlainObject(objValue);\n      }\n      else if (!isObject(objValue) || isFunction(objValue)) {\n        newValue = initCloneObject(srcValue);\n      }\n    }\n    else {\n      isCommon = false;\n    }\n  }\n  if (isCommon) {\n    // Recursively merge objects and arrays (susceptible to call stack limits).\n    stack.set(srcValue, newValue);\n    mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n    stack['delete'](srcValue);\n  }\n  assignMergeValue(object, key, newValue);\n}\n\nexport default baseMergeDeep;\n", "import Stack from './_Stack.js';\nimport assignMergeValue from './_assignMergeValue.js';\nimport baseFor from './_baseFor.js';\nimport baseMergeDeep from './_baseMergeDeep.js';\nimport isObject from './isObject.js';\nimport keysIn from './keysIn.js';\nimport safeGet from './_safeGet.js';\n\n/**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n *  counterparts.\n */\nfunction baseMerge(object, source, srcIndex, customizer, stack) {\n  if (object === source) {\n    return;\n  }\n  baseFor(source, function(srcValue, key) {\n    stack || (stack = new Stack);\n    if (isObject(srcValue)) {\n      baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n    }\n    else {\n      var newValue = customizer\n        ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n        : undefined;\n\n      if (newValue === undefined) {\n        newValue = srcValue;\n      }\n      assignMergeValue(object, key, newValue);\n    }\n  }, keysIn);\n}\n\nexport default baseMerge;\n", "/**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\nfunction last(array) {\n  var length = array == null ? 0 : array.length;\n  return length ? array[length - 1] : undefined;\n}\n\nexport default last;\n", "import baseEach from './_baseEach.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * The base implementation of `_.map` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction baseMap(collection, iteratee) {\n  var index = -1,\n      result = isArrayLike(collection) ? Array(collection.length) : [];\n\n  baseEach(collection, function(value, key, collection) {\n    result[++index] = iteratee(value, key, collection);\n  });\n  return result;\n}\n\nexport default baseMap;\n", "import arrayMap from './_arrayMap.js';\nimport baseIteratee from './_baseIteratee.js';\nimport baseMap from './_baseMap.js';\nimport isArray from './isArray.js';\n\n/**\n * Creates an array of values by running each element in `collection` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n *\n * The guarded methods are:\n * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n * @example\n *\n * function square(n) {\n *   return n * n;\n * }\n *\n * _.map([4, 8], square);\n * // => [16, 64]\n *\n * _.map({ 'a': 4, 'b': 8 }, square);\n * // => [16, 64] (iteration order is not guaranteed)\n *\n * var users = [\n *   { 'user': 'barney' },\n *   { 'user': 'fred' }\n * ];\n *\n * // The `_.property` iteratee shorthand.\n * _.map(users, 'user');\n * // => ['barney', 'fred']\n */\nfunction map(collection, iteratee) {\n  var func = isArray(collection) ? arrayMap : baseMap;\n  return func(collection, baseIteratee(iteratee, 3));\n}\n\nexport default map;\n", "import baseGetTag from './_baseGetTag.js';\nimport isArray from './isArray.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar stringTag = '[object String]';\n\n/**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n  return typeof value == 'string' ||\n    (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n}\n\nexport default isString;\n", "import baseGet from './_baseGet.js';\nimport baseSlice from './_baseSlice.js';\n\n/**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\nfunction parent(object, path) {\n  return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n}\n\nexport default parent;\n", "import isObjectLike from './isObjectLike.js';\nimport isPlainObject from './isPlainObject.js';\n\n/**\n * Checks if `value` is likely a DOM element.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n * @example\n *\n * _.isElement(document.body);\n * // => true\n *\n * _.isElement('<body>');\n * // => false\n */\nfunction isElement(value) {\n  return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n}\n\nexport default isElement;\n", "import baseIsEqual from './_baseIsEqual.js';\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n  return baseIsEqual(value, other);\n}\n\nexport default isEqual;\n", "import baseIsEqual from './_baseIsEqual.js';\n\n/**\n * This method is like `_.isEqual` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with up to\n * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * function isGreeting(value) {\n *   return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, othValue) {\n *   if (isGreeting(objValue) && isGreeting(othValue)) {\n *     return true;\n *   }\n * }\n *\n * var array = ['hello', 'goodbye'];\n * var other = ['hi', 'goodbye'];\n *\n * _.isEqualWith(array, other, customizer);\n * // => true\n */\nfunction isEqualWith(value, other, customizer) {\n  customizer = typeof customizer == 'function' ? customizer : undefined;\n  var result = customizer ? customizer(value, other) : undefined;\n  return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n}\n\nexport default isEqualWith;\n", "import baseAssignValue from './_baseAssignValue.js';\nimport baseForOwn from './_baseForOwn.js';\nimport baseIteratee from './_baseIteratee.js';\n\n/**\n * Creates an object with the same keys as `object` and values generated\n * by running each own enumerable string keyed property of `object` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapKeys\n * @example\n *\n * var users = {\n *   'fred':    { 'user': 'fred',    'age': 40 },\n *   'pebbles': { 'user': 'pebbles', 'age': 1 }\n * };\n *\n * _.mapValues(users, function(o) { return o.age; });\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n *\n * // The `_.property` iteratee shorthand.\n * _.mapValues(users, 'age');\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n */\nfunction mapValues(object, iteratee) {\n  var result = {};\n  iteratee = baseIteratee(iteratee, 3);\n\n  baseForOwn(object, function(value, key, object) {\n    baseAssignValue(result, key, iteratee(value, key, object));\n  });\n  return result;\n}\n\nexport default mapValues;\n", "import baseMerge from './_baseMerge.js';\nimport createAssigner from './_createAssigner.js';\n\n/**\n * This method is like `_.assign` except that it recursively merges own and\n * inherited enumerable string keyed properties of source objects into the\n * destination object. Source properties that resolve to `undefined` are\n * skipped if a destination value exists. Array and plain object properties\n * are merged recursively. Other objects and value types are overridden by\n * assignment. Source objects are applied from left to right. Subsequent\n * sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {\n *   'a': [{ 'b': 2 }, { 'd': 4 }]\n * };\n *\n * var other = {\n *   'a': [{ 'c': 3 }, { 'e': 5 }]\n * };\n *\n * _.merge(object, other);\n * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n */\nvar merge = createAssigner(function(object, source, srcIndex) {\n  baseMerge(object, source, srcIndex);\n});\n\nexport default merge;\n", "import castPath from './_castPath.js';\nimport last from './last.js';\nimport parent from './_parent.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.unset`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The property path to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n */\nfunction baseUnset(object, path) {\n  path = castPath(path, object);\n  object = parent(object, path);\n  return object == null || delete object[toKey(last(path))];\n}\n\nexport default baseUnset;\n", "import assignValue from './_assignValue.js';\nimport castPath from './_castPath.js';\nimport isIndex from './_isIndex.js';\nimport isObject from './isObject.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n  if (!isObject(object)) {\n    return object;\n  }\n  path = castPath(path, object);\n\n  var index = -1,\n      length = path.length,\n      lastIndex = length - 1,\n      nested = object;\n\n  while (nested != null && ++index < length) {\n    var key = toKey(path[index]),\n        newValue = value;\n\n    if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n      return object;\n    }\n\n    if (index != lastIndex) {\n      var objValue = nested[key];\n      newValue = customizer ? customizer(objValue, key, nested) : undefined;\n      if (newValue === undefined) {\n        newValue = isObject(objValue)\n          ? objValue\n          : (isIndex(path[index + 1]) ? [] : {});\n      }\n    }\n    assignValue(nested, key, newValue);\n    nested = nested[key];\n  }\n  return object;\n}\n\nexport default baseSet;\n", "import baseSet from './_baseSet.js';\n\n/**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\nfunction set(object, path, value) {\n  return object == null ? object : baseSet(object, path, value);\n}\n\nexport default set;\n", "import debounce from './debounce.js';\nimport isObject from './isObject.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide `options` to indicate whether `func`\n * should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n *  Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n *  Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\nfunction throttle(func, wait, options) {\n  var leading = true,\n      trailing = true;\n\n  if (typeof func != 'function') {\n    throw new TypeError(FUNC_ERROR_TEXT);\n  }\n  if (isObject(options)) {\n    leading = 'leading' in options ? !!options.leading : leading;\n    trailing = 'trailing' in options ? !!options.trailing : trailing;\n  }\n  return debounce(func, wait, {\n    'leading': leading,\n    'maxWait': wait,\n    'trailing': trailing\n  });\n}\n\nexport default throttle;\n", "import baseUnset from './_baseUnset.js';\n\n/**\n * Removes the property at `path` of `object`.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 7 } }] };\n * _.unset(object, 'a[0].b.c');\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n *\n * _.unset(object, ['a', '0', 'b', 'c']);\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n */\nfunction unset(object, path) {\n  return object == null ? true : baseUnset(object, path);\n}\n\nexport default unset;\n", "import { isObject, isString, isPlainObject, cloneDeepWith, isElement as isElement$1, isFunction, merge } from 'lodash-es';\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /* globals window, document */ /**\n * @module utils/dom/global\n */ // This interface exists to make our API pages more readable.\n/**\n * A helper (module) giving an access to the global DOM objects such as `window` and `document`.\n */ /**\n * A helper (module) giving an access to the global DOM objects such as `window` and\n * `document`. Accessing these objects using this helper allows easy and bulletproof\n * testing, i.e. stubbing native properties:\n *\n * ```ts\n * import { global } from 'ckeditor5/utils';\n *\n * // This stub will work for any code using global module.\n * testUtils.sinon.stub( global, 'window', {\n * \tinnerWidth: 10000\n * } );\n *\n * console.log( global.window.innerWidth );\n * ```\n */ let globalVar; // named globalVar instead of global: https://github.com/ckeditor/ckeditor5/issues/12971\n// In some environments window and document API might not be available.\ntry {\n    globalVar = {\n        window,\n        document\n    };\n} catch (e) {\n    // It's not possible to mock a window object to simulate lack of a window object without writing extremely convoluted code.\n    /* istanbul ignore next -- @preserve */ // Let's cast it to not change module's API.\n    // We only handle this so loading editor in environments without window and document doesn't fail.\n    // For better DX we shouldn't introduce mixed types and require developers to check the type manually.\n    // This module should not be used on purpose in any environment outside browser.\n    globalVar = {\n        window: {},\n        document: {}\n    };\n}\nvar global = globalVar;\n\n/**\n * Safely returns `userAgent` from browser's navigator API in a lower case.\n * If navigator API is not available it will return an empty string.\n */ function getUserAgent() {\n    // In some environments navigator API might not be available.\n    try {\n        return navigator.userAgent.toLowerCase();\n    } catch (e) {\n        return '';\n    }\n}\nconst userAgent = /* #__PURE__ */ getUserAgent();\n/**\n * A namespace containing environment and browser information.\n */ const env = {\n    isMac: /* #__PURE__ */ isMac(userAgent),\n    isWindows: /* #__PURE__ */ isWindows(userAgent),\n    isGecko: /* #__PURE__ */ isGecko(userAgent),\n    isSafari: /* #__PURE__ */ isSafari(userAgent),\n    isiOS: /* #__PURE__ */ isiOS(userAgent),\n    isAndroid: /* #__PURE__ */ isAndroid(userAgent),\n    isBlink: /* #__PURE__ */ isBlink(userAgent),\n    get isMediaForcedColors () {\n        return isMediaForcedColors();\n    },\n    get isMotionReduced () {\n        return isMotionReduced();\n    },\n    features: {\n        isRegExpUnicodePropertySupported: /* #__PURE__ */ isRegExpUnicodePropertySupported()\n    }\n};\n/**\n * Checks if User Agent represented by the string is running on Macintosh.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is running on Macintosh or not.\n */ function isMac(userAgent) {\n    return userAgent.indexOf('macintosh') > -1;\n}\n/**\n * Checks if User Agent represented by the string is running on Windows.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is running on Windows or not.\n */ function isWindows(userAgent) {\n    return userAgent.indexOf('windows') > -1;\n}\n/**\n * Checks if User Agent represented by the string is Firefox (Gecko).\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Firefox or not.\n */ function isGecko(userAgent) {\n    return !!userAgent.match(/gecko\\/\\d+/);\n}\n/**\n * Checks if User Agent represented by the string is Safari.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Safari or not.\n */ function isSafari(userAgent) {\n    return userAgent.indexOf(' applewebkit/') > -1 && userAgent.indexOf('chrome') === -1;\n}\n/**\n * Checks if User Agent represented by the string is running in iOS.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is running in iOS or not.\n */ function isiOS(userAgent) {\n    // \"Request mobile site\" || \"Request desktop site\".\n    return !!userAgent.match(/iphone|ipad/i) || isMac(userAgent) && navigator.maxTouchPoints > 0;\n}\n/**\n * Checks if User Agent represented by the string is Android mobile device.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Safari or not.\n */ function isAndroid(userAgent) {\n    return userAgent.indexOf('android') > -1;\n}\n/**\n * Checks if User Agent represented by the string is Blink engine.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Blink engine or not.\n */ function isBlink(userAgent) {\n    // The Edge browser before switching to the Blink engine used to report itself as Chrome (and \"Edge/\")\n    // but after switching to the Blink it replaced \"Edge/\" with \"Edg/\".\n    return userAgent.indexOf('chrome/') > -1 && userAgent.indexOf('edge/') < 0;\n}\n/**\n * Checks if the current environment supports ES2018 Unicode properties like `\\p{P}` or `\\p{L}`.\n * More information about unicode properties might be found\n * [in Unicode Standard Annex #44](https://www.unicode.org/reports/tr44/#GC_Values_Table).\n */ function isRegExpUnicodePropertySupported() {\n    let isSupported = false;\n    // Feature detection for Unicode properties. Added in ES2018. Currently Firefox does not support it.\n    // See https://github.com/ckeditor/ckeditor5-mention/issues/44#issuecomment-487002174.\n    try {\n        // Usage of regular expression literal cause error during build (ckeditor/ckeditor5-dev#534).\n        isSupported = 'ć'.search(new RegExp('[\\\\p{L}]', 'u')) === 0;\n    } catch (error) {\n    // Firefox throws a SyntaxError when the group is unsupported.\n    }\n    return isSupported;\n}\n/**\n * Checks if the user agent has enabled a forced colors mode (e.g. Windows High Contrast mode).\n *\n * Returns `false` in environments where `window` global object is not available.\n */ function isMediaForcedColors() {\n    return global.window.matchMedia ? global.window.matchMedia('(forced-colors: active)').matches : false;\n}\n/**\n * Checks if the user enabled \"prefers reduced motion\" setting in browser.\n *\n * Returns `false` in environments where `window` global object is not available.\n */ function isMotionReduced() {\n    return global.window.matchMedia ? global.window.matchMedia('(prefers-reduced-motion)').matches : false;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/fastdiff\n */ /**\n * Finds positions of the first and last change in the given string/array and generates a set of changes:\n *\n * ```ts\n * fastDiff( '12a', '12xyza' );\n * // [ { index: 2, type: 'insert', values: [ 'x', 'y', 'z' ] } ]\n *\n * fastDiff( '12a', '12aa' );\n * // [ { index: 3, type: 'insert', values: [ 'a' ] } ]\n *\n * fastDiff( '12xyza', '12a' );\n * // [ { index: 2, type: 'delete', howMany: 3 } ]\n *\n * fastDiff( [ '1', '2', 'a', 'a' ], [ '1', '2', 'a' ] );\n * // [ { index: 3, type: 'delete', howMany: 1 } ]\n *\n * fastDiff( [ '1', '2', 'a', 'b', 'c', '3' ], [ '2', 'a', 'b' ] );\n * // [ { index: 0, type: 'insert', values: [ '2', 'a', 'b' ] }, { index: 3, type: 'delete', howMany: 6 } ]\n * ```\n *\n * Passed arrays can contain any type of data, however to compare them correctly custom comparator function\n * should be passed as a third parameter:\n *\n * ```ts\n * fastDiff( [ { value: 1 }, { value: 2 } ], [ { value: 1 }, { value: 3 } ], ( a, b ) => {\n * \treturn a.value === b.value;\n * } );\n * // [ { index: 1, type: 'insert', values: [ { value: 3 } ] }, { index: 2, type: 'delete', howMany: 1 } ]\n * ```\n *\n * The resulted set of changes can be applied to the input in order to transform it into the output, for example:\n *\n * ```ts\n * let input = '12abc3';\n * const output = '2ab';\n * const changes = fastDiff( input, output );\n *\n * changes.forEach( change => {\n * \tif ( change.type == 'insert' ) {\n * \t\tinput = input.substring( 0, change.index ) + change.values.join( '' ) + input.substring( change.index );\n * \t} else if ( change.type == 'delete' ) {\n * \t\tinput = input.substring( 0, change.index ) + input.substring( change.index + change.howMany );\n * \t}\n * } );\n *\n * // input equals output now\n * ```\n *\n * or in case of arrays:\n *\n * ```ts\n * let input = [ '1', '2', 'a', 'b', 'c', '3' ];\n * const output = [ '2', 'a', 'b' ];\n * const changes = fastDiff( input, output );\n *\n * changes.forEach( change => {\n * \tif ( change.type == 'insert' ) {\n * \t\tinput = input.slice( 0, change.index ).concat( change.values, input.slice( change.index ) );\n * \t} else if ( change.type == 'delete' ) {\n * \t\tinput = input.slice( 0, change.index ).concat( input.slice( change.index + change.howMany ) );\n * \t}\n * } );\n *\n * // input equals output now\n * ```\n *\n * By passing `true` as the fourth parameter (`atomicChanges`) the output of this function will become compatible with\n * the {@link module:utils/diff~diff `diff()`} function:\n *\n * ```ts\n * fastDiff( '12a', '12xyza', undefined, true );\n * // [ 'equal', 'equal', 'insert', 'insert', 'insert', 'equal' ]\n * ```\n *\n * The default output format of this function is compatible with the output format of\n * {@link module:utils/difftochanges~diffToChanges `diffToChanges()`}. The `diffToChanges()` input format is, in turn,\n * compatible with the output of {@link module:utils/diff~diff `diff()`}:\n *\n * ```ts\n * const a = '1234';\n * const b = '12xyz34';\n *\n * // Both calls will return the same results (grouped changes format).\n * fastDiff( a, b );\n * diffToChanges( diff( a, b ) );\n *\n * // Again, both calls will return the same results (atomic changes format).\n * fastDiff( a, b, undefined, true );\n * diff( a, b );\n * ```\n *\n * @typeParam T The type of array elements.\n * @typeParam AtomicChanges The type of `atomicChanges` parameter (selects the result type).\n * @param a Input array or string.\n * @param b Input array or string.\n * @param cmp Optional function used to compare array values, by default `===` (strict equal operator) is used.\n * @param atomicChanges Whether an array of `inset|delete|equal` operations should\n * be returned instead of changes set. This makes this function compatible with {@link module:utils/diff~diff `diff()`}.\n * Defaults to `false`.\n * @returns Array of changes. The elements are either {@link module:utils/diff~DiffResult} or {@link module:utils/difftochanges~Change},\n * depending on `atomicChanges` parameter.\n */ function fastDiff(a, b, cmp, atomicChanges) {\n    // Set the comparator function.\n    cmp = cmp || function(a, b) {\n        return a === b;\n    };\n    // Convert the string (or any array-like object - eg. NodeList) to an array by using the slice() method because,\n    // unlike Array.from(), it returns array of UTF-16 code units instead of the code points of a string.\n    // One code point might be a surrogate pair of two code units. All text offsets are expected to be in code units.\n    // See ckeditor/ckeditor5#3147.\n    //\n    // We need to make sure here that fastDiff() works identical to diff().\n    const arrayA = Array.isArray(a) ? a : Array.prototype.slice.call(a);\n    const arrayB = Array.isArray(b) ? b : Array.prototype.slice.call(b);\n    // Find first and last change.\n    const changeIndexes = findChangeBoundaryIndexes(arrayA, arrayB, cmp);\n    // Transform into changes array.\n    const result = atomicChanges ? changeIndexesToAtomicChanges(changeIndexes, arrayB.length) : changeIndexesToChanges(arrayB, changeIndexes);\n    return result;\n}\n/**\n * Finds position of the first and last change in the given arrays. For example:\n *\n * ```ts\n * const indexes = findChangeBoundaryIndexes( [ '1', '2', '3', '4' ], [ '1', '3', '4', '2', '4' ] );\n * console.log( indexes ); // { firstIndex: 1, lastIndexOld: 3, lastIndexNew: 4 }\n * ```\n *\n * The above indexes means that in the first array the modified part is `1[23]4` and in the second array it is `1[342]4`.\n * Based on such indexes, array with `insert`/`delete` operations which allows transforming first value into the second one\n * can be generated.\n */ function findChangeBoundaryIndexes(arr1, arr2, cmp) {\n    // Find the first difference between passed values.\n    const firstIndex = findFirstDifferenceIndex(arr1, arr2, cmp);\n    // If arrays are equal return -1 indexes object.\n    if (firstIndex === -1) {\n        return {\n            firstIndex: -1,\n            lastIndexOld: -1,\n            lastIndexNew: -1\n        };\n    }\n    // Remove the common part of each value and reverse them to make it simpler to find the last difference between them.\n    const oldArrayReversed = cutAndReverse(arr1, firstIndex);\n    const newArrayReversed = cutAndReverse(arr2, firstIndex);\n    // Find the first difference between reversed values.\n    // It should be treated as \"how many elements from the end the last difference occurred\".\n    //\n    // For example:\n    //\n    // \t\t\t\tinitial\t->\tafter cut\t-> reversed:\n    // oldValue:\t'321ba'\t->\t'21ba'\t\t-> 'ab12'\n    // newValue:\t'31xba'\t->\t'1xba'\t\t-> 'abx1'\n    // lastIndex:\t\t\t\t\t\t\t-> 2\n    //\n    // So the last change occurred two characters from the end of the arrays.\n    const lastIndex = findFirstDifferenceIndex(oldArrayReversed, newArrayReversed, cmp);\n    // Use `lastIndex` to calculate proper offset, starting from the beginning (`lastIndex` kind of starts from the end).\n    const lastIndexOld = arr1.length - lastIndex;\n    const lastIndexNew = arr2.length - lastIndex;\n    return {\n        firstIndex,\n        lastIndexOld,\n        lastIndexNew\n    };\n}\n/**\n * Returns a first index on which given arrays differ. If both arrays are the same, -1 is returned.\n */ function findFirstDifferenceIndex(arr1, arr2, cmp) {\n    for(let i = 0; i < Math.max(arr1.length, arr2.length); i++){\n        if (arr1[i] === undefined || arr2[i] === undefined || !cmp(arr1[i], arr2[i])) {\n            return i;\n        }\n    }\n    return -1; // Return -1 if arrays are equal.\n}\n/**\n * Returns a copy of the given array with `howMany` elements removed starting from the beginning and in reversed order.\n *\n * @param arr Array to be processed.\n * @param howMany How many elements from array beginning to remove.\n * @returns Shortened and reversed array.\n */ function cutAndReverse(arr, howMany) {\n    return arr.slice(howMany).reverse();\n}\n/**\n * Generates changes array based on change indexes from `findChangeBoundaryIndexes` function. This function will\n * generate array with 0 (no changes), 1 (deletion or insertion) or 2 records (insertion and deletion).\n *\n * @param newArray New array for which change indexes were calculated.\n * @param changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.\n * @returns Array of changes compatible with {@link module:utils/difftochanges~diffToChanges} format.\n */ function changeIndexesToChanges(newArray, changeIndexes) {\n    const result = [];\n    const { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;\n    // Order operations as 'insert', 'delete' array to keep compatibility with {@link module:utils/difftochanges~diffToChanges}\n    // in most cases. However, 'diffToChanges' does not stick to any order so in some cases\n    // (for example replacing '12345' with 'abcd') it will generate 'delete', 'insert' order.\n    if (lastIndexNew - firstIndex > 0) {\n        result.push({\n            index: firstIndex,\n            type: 'insert',\n            values: newArray.slice(firstIndex, lastIndexNew)\n        });\n    }\n    if (lastIndexOld - firstIndex > 0) {\n        result.push({\n            index: firstIndex + (lastIndexNew - firstIndex),\n            type: 'delete',\n            howMany: lastIndexOld - firstIndex\n        });\n    }\n    return result;\n}\n/**\n * Generates array with set `equal|insert|delete` operations based on change indexes from `findChangeBoundaryIndexes` function.\n *\n * @param changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.\n * @param newLength Length of the new array on which `findChangeBoundaryIndexes` calculated change indexes.\n * @returns Array of changes compatible with {@link module:utils/diff~diff} format.\n */ function changeIndexesToAtomicChanges(changeIndexes, newLength) {\n    const { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;\n    // No changes.\n    if (firstIndex === -1) {\n        return Array(newLength).fill('equal');\n    }\n    let result = [];\n    if (firstIndex > 0) {\n        result = result.concat(Array(firstIndex).fill('equal'));\n    }\n    if (lastIndexNew - firstIndex > 0) {\n        result = result.concat(Array(lastIndexNew - firstIndex).fill('insert'));\n    }\n    if (lastIndexOld - firstIndex > 0) {\n        result = result.concat(Array(lastIndexOld - firstIndex).fill('delete'));\n    }\n    if (lastIndexNew < newLength) {\n        result = result.concat(Array(newLength - lastIndexNew).fill('equal'));\n    }\n    return result;\n}\n\n// The following code is based on the \"O(NP) Sequence Comparison Algorithm\"\n// by Sun Wu, Udi Manber, Gene Myers, Webb Miller.\n/**\n * Calculates the difference between two arrays or strings producing an array containing a list of changes\n * necessary to transform input into output.\n *\n * ```ts\n * diff( 'aba', 'acca' ); // [ 'equal', 'insert', 'insert', 'delete', 'equal' ]\n * ```\n *\n * This function is based on the \"O(NP) Sequence Comparison Algorithm\" by Sun Wu, Udi Manber, Gene Myers, Webb Miller.\n * Unfortunately, while it gives the most precise results, its to complex for longer strings/arrow (above 200 items).\n * Therefore, `diff()` automatically switches to {@link module:utils/fastdiff~fastDiff `fastDiff()`} when detecting\n * such a scenario. The return formats of both functions are identical.\n *\n * @param a Input array or string.\n * @param b Output array or string.\n * @param cmp Optional function used to compare array values, by default === is used.\n * @returns Array of changes.\n */ function diff(a, b, cmp) {\n    // Set the comparator function.\n    cmp = cmp || function(a, b) {\n        return a === b;\n    };\n    const aLength = a.length;\n    const bLength = b.length;\n    // Perform `fastDiff` for longer strings/arrays (see #269).\n    if (aLength > 200 || bLength > 200 || aLength + bLength > 300) {\n        return diff.fastDiff(a, b, cmp, true);\n    }\n    // Temporary action type statics.\n    let _insert, _delete;\n    // Swapped the arrays to use the shorter one as the first one.\n    if (bLength < aLength) {\n        const tmp = a;\n        a = b;\n        b = tmp;\n        // We swap the action types as well.\n        _insert = 'delete';\n        _delete = 'insert';\n    } else {\n        _insert = 'insert';\n        _delete = 'delete';\n    }\n    const m = a.length;\n    const n = b.length;\n    const delta = n - m;\n    // Edit scripts, for each diagonal.\n    const es = {};\n    // Furthest points, the furthest y we can get on each diagonal.\n    const fp = {};\n    function snake(k) {\n        // We use -1 as an alternative below to handle initial values ( instead of filling the fp with -1 first ).\n        // Furthest points (y) on the diagonal below k.\n        const y1 = (fp[k - 1] !== undefined ? fp[k - 1] : -1) + 1;\n        // Furthest points (y) on the diagonal above k.\n        const y2 = fp[k + 1] !== undefined ? fp[k + 1] : -1;\n        // The way we should go to get further.\n        const dir = y1 > y2 ? -1 : 1;\n        // Clone previous changes array (if any).\n        if (es[k + dir]) {\n            es[k] = es[k + dir].slice(0);\n        }\n        // Create changes array.\n        if (!es[k]) {\n            es[k] = [];\n        }\n        // Push the action.\n        es[k].push(y1 > y2 ? _insert : _delete);\n        // Set the beginning coordinates.\n        let y = Math.max(y1, y2);\n        let x = y - k;\n        // Traverse the diagonal as long as the values match.\n        while(x < m && y < n && cmp(a[x], b[y])){\n            x++;\n            y++;\n            // Push no change action.\n            es[k].push('equal');\n        }\n        return y;\n    }\n    let p = 0;\n    let k;\n    // Traverse the graph until we reach the end of the longer string.\n    do {\n        // Updates furthest points and edit scripts for diagonals below delta.\n        for(k = -p; k < delta; k++){\n            fp[k] = snake(k);\n        }\n        // Updates furthest points and edit scripts for diagonals above delta.\n        for(k = delta + p; k > delta; k--){\n            fp[k] = snake(k);\n        }\n        // Updates furthest point and edit script for the delta diagonal.\n        // note that the delta diagonal is the one which goes through the sink (m, n).\n        fp[delta] = snake(delta);\n        p++;\n    }while (fp[delta] !== n)\n    // Return the final list of edit changes.\n    // We remove the first item that represents the action for the injected nulls.\n    return es[delta].slice(1);\n}\n// Store the API in static property to easily overwrite it in tests.\n// Too bad dependency injection does not work in Webpack + ES 6 (const) + Babel.\ndiff.fastDiff = fastDiff;\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/difftochanges\n */ /**\n * Creates a set of changes which need to be applied to the input in order to transform\n * it into the output. This function can be used with strings or arrays.\n *\n * ```ts\n * const input = Array.from( 'abc' );\n * const output = Array.from( 'xaby' );\n * const changes = diffToChanges( diff( input, output ), output );\n *\n * changes.forEach( change => {\n * \tif ( change.type == 'insert' ) {\n * \t\tinput.splice( change.index, 0, ...change.values );\n * \t} else if ( change.type == 'delete' ) {\n * \t\tinput.splice( change.index, change.howMany );\n * \t}\n * } );\n *\n * input.join( '' ) == output.join( '' ); // -> true\n * ```\n *\n * @typeParam T The type of output array element.\n * @param diff Result of {@link module:utils/diff~diff}.\n * @param output The string or array which was passed as diff's output.\n * @returns Set of changes (insert or delete) which need to be applied to the input\n * in order to transform it into the output.\n */ function diffToChanges(diff, output) {\n    const changes = [];\n    let index = 0;\n    let lastOperation = null;\n    diff.forEach((change)=>{\n        if (change == 'equal') {\n            pushLast();\n            index++;\n        } else if (change == 'insert') {\n            if (lastOperation && lastOperation.type == 'insert') {\n                lastOperation.values.push(output[index]);\n            } else {\n                pushLast();\n                lastOperation = {\n                    type: 'insert',\n                    index,\n                    values: [\n                        output[index]\n                    ]\n                };\n            }\n            index++;\n        } else /* if ( change == 'delete' ) */ {\n            if (lastOperation && lastOperation.type == 'delete') {\n                lastOperation.howMany++;\n            } else {\n                pushLast();\n                lastOperation = {\n                    type: 'delete',\n                    index,\n                    howMany: 1\n                };\n            }\n        }\n    });\n    pushLast();\n    return changes;\n    function pushLast() {\n        if (lastOperation) {\n            changes.push(lastOperation);\n            lastOperation = null;\n        }\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/mix\n */ /**\n * Copies enumerable properties and symbols from the objects given as 2nd+ parameters to the\n * prototype of first object (a constructor).\n *\n * ```\n * class Editor {\n * \t...\n * }\n *\n * const SomeMixin = {\n * \ta() {\n * \t\treturn 'a';\n * \t}\n * };\n *\n * mix( Editor, SomeMixin, ... );\n *\n * new Editor().a(); // -> 'a'\n * ```\n *\n * Note: Properties which already exist in the base class will not be overriden.\n *\n * @deprecated Use mixin pattern, see: https://www.typescriptlang.org/docs/handbook/mixins.html.\n * @param baseClass Class which prototype will be extended.\n * @param mixins Objects from which to get properties.\n */ function mix(baseClass, ...mixins) {\n    mixins.forEach((mixin)=>{\n        const propertyNames = Object.getOwnPropertyNames(mixin);\n        const propertySymbols = Object.getOwnPropertySymbols(mixin);\n        propertyNames.concat(propertySymbols).forEach((key)=>{\n            if (key in baseClass.prototype) {\n                return;\n            }\n            if (typeof mixin == 'function' && (key == 'length' || key == 'name' || key == 'prototype')) {\n                return;\n            }\n            const sourceDescriptor = Object.getOwnPropertyDescriptor(mixin, key);\n            sourceDescriptor.enumerable = false;\n            Object.defineProperty(baseClass.prototype, key, sourceDescriptor);\n        });\n    });\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/spy\n */ /**\n * Creates a spy function (ala Sinon.js) that can be used to inspect call to it.\n *\n * The following are the present features:\n *\n * * spy.called: property set to `true` if the function has been called at least once.\n *\n * @returns The spy function.\n */ function spy() {\n    return function spy() {\n        spy.called = true;\n    };\n}\n\n/**\n * The event object passed to event callbacks. It is used to provide information about the event as well as a tool to\n * manipulate it.\n */ class EventInfo {\n    /**\n\t * The object that fired the event.\n\t */ source;\n    /**\n\t * The event name.\n\t */ name;\n    /**\n\t * Path this event has followed. See {@link module:utils/emittermixin~Emitter#delegate}.\n\t */ path;\n    /**\n\t * Stops the event emitter to call further callbacks for this event interaction.\n\t */ stop;\n    /**\n\t * Removes the current callback from future interactions of this event.\n\t */ off;\n    /**\n\t * The value which will be returned by {@link module:utils/emittermixin~Emitter#fire}.\n\t *\n\t * It's `undefined` by default and can be changed by an event listener:\n\t *\n\t * ```ts\n\t * dataController.fire( 'getSelectedContent', ( evt ) => {\n\t * \t// This listener will make `dataController.fire( 'getSelectedContent' )`\n\t * \t// always return an empty DocumentFragment.\n\t * \tevt.return = new DocumentFragment();\n\t *\n\t * \t// Make sure no other listeners are executed.\n\t * \tevt.stop();\n\t * } );\n\t * ```\n\t */ return;\n    /**\n\t * @param source The emitter.\n\t * @param name The event name.\n\t */ constructor(source, name){\n        this.source = source;\n        this.name = name;\n        this.path = [];\n        // The following methods are defined in the constructor because they must be re-created per instance.\n        this.stop = spy();\n        this.off = spy();\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/uid\n */ /**\n * A hash table of hex numbers to avoid using toString() in uid() which is costly.\n * [ '00', '01', '02', ..., 'fe', 'ff' ]\n */ const HEX_NUMBERS = new Array(256).fill('').map((_, index)=>('0' + index.toString(16)).slice(-2));\n/**\n * Returns a unique id. The id starts with an \"e\" character and a randomly generated string of\n * 32 alphanumeric characters.\n *\n * **Note**: The characters the unique id is built from correspond to the hex number notation\n * (from \"0\" to \"9\", from \"a\" to \"f\"). In other words, each id corresponds to an \"e\" followed\n * by 16 8-bit numbers next to each other.\n *\n * @returns An unique id string.\n */ function uid() {\n    // Let's create some positive random 32bit integers first.\n    const [r1, r2, r3, r4] = crypto.getRandomValues(new Uint32Array(4));\n    // Make sure that id does not start with number.\n    return 'e' + HEX_NUMBERS[r1 >> 0 & 0xFF] + HEX_NUMBERS[r1 >> 8 & 0xFF] + HEX_NUMBERS[r1 >> 16 & 0xFF] + HEX_NUMBERS[r1 >> 24 & 0xFF] + HEX_NUMBERS[r2 >> 0 & 0xFF] + HEX_NUMBERS[r2 >> 8 & 0xFF] + HEX_NUMBERS[r2 >> 16 & 0xFF] + HEX_NUMBERS[r2 >> 24 & 0xFF] + HEX_NUMBERS[r3 >> 0 & 0xFF] + HEX_NUMBERS[r3 >> 8 & 0xFF] + HEX_NUMBERS[r3 >> 16 & 0xFF] + HEX_NUMBERS[r3 >> 24 & 0xFF] + HEX_NUMBERS[r4 >> 0 & 0xFF] + HEX_NUMBERS[r4 >> 8 & 0xFF] + HEX_NUMBERS[r4 >> 16 & 0xFF] + HEX_NUMBERS[r4 >> 24 & 0xFF];\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/priorities\n */ /**\n * String representing a priority value.\n */ /**\n * Provides group of constants to use instead of hardcoding numeric priority values.\n */ const priorities = {\n    get (priority = 'normal') {\n        if (typeof priority != 'number') {\n            return this[priority] || this.normal;\n        } else {\n            return priority;\n        }\n    },\n    highest: 100000,\n    high: 1000,\n    normal: 0,\n    low: -1000,\n    lowest: -100000\n};\n\n/**\n * Inserts any object with priority at correct index by priority so registered objects are always sorted from highest to lowest priority.\n *\n * @param objects Array of objects with priority to insert object to.\n * @param objectToInsert Object with `priority` property.\n */ function insertToPriorityArray(objects, objectToInsert) {\n    const priority = priorities.get(objectToInsert.priority);\n    for(let i = 0; i < objects.length; i++){\n        if (priorities.get(objects[i].priority) < priority) {\n            objects.splice(i, 0, objectToInsert);\n            return;\n        }\n    }\n    objects.push(objectToInsert);\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/ckeditorerror\n */ /* globals console */ /**\n * URL to the documentation with error codes.\n */ const DOCUMENTATION_URL = 'https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html';\n/**\n * The CKEditor error class.\n *\n * You should throw `CKEditorError` when:\n *\n * * An unexpected situation occurred and the editor (most probably) will not work properly. Such exception will be handled\n * by the {@link module:watchdog/watchdog~Watchdog watchdog} (if it is integrated),\n * * If the editor is incorrectly integrated or the editor API is used in the wrong way. This way you will give\n * feedback to the developer as soon as possible. Keep in mind that for common integration issues which should not\n * stop editor initialization (like missing upload adapter, wrong name of a toolbar component) we use\n * {@link module:utils/ckeditorerror~logWarning `logWarning()`} and\n * {@link module:utils/ckeditorerror~logError `logError()`}\n * to improve developers experience and let them see the a working editor as soon as possible.\n *\n * ```ts\n * /**\n *  * Error thrown when a plugin cannot be loaded due to JavaScript errors, lack of plugins with a given name, etc.\n *  *\n *  * @error plugin-load\n *  * @param pluginName The name of the plugin that could not be loaded.\n *  * @param moduleName The name of the module which tried to load this plugin.\n *  *\\/\n * throw new CKEditorError( 'plugin-load', {\n * \tpluginName: 'foo',\n * \tmoduleName: 'bar'\n * } );\n * ```\n */ class CKEditorError extends Error {\n    /**\n\t * A context of the error by which the Watchdog is able to determine which editor crashed.\n\t */ context;\n    /**\n\t * The additional error data passed to the constructor. Undefined if none was passed.\n\t */ data;\n    /**\n\t * Creates an instance of the CKEditorError class.\n\t *\n\t * @param errorName The error id in an `error-name` format. A link to this error documentation page will be added\n\t * to the thrown error's `message`.\n\t * @param context A context of the error by which the {@link module:watchdog/watchdog~Watchdog watchdog}\n\t * is able to determine which editor crashed. It should be an editor instance or a property connected to it. It can be also\n\t * a `null` value if the editor should not be restarted in case of the error (e.g. during the editor initialization).\n\t * The error context should be checked using the `areConnectedThroughProperties( editor, context )` utility\n\t * to check if the object works as the context.\n\t * @param data Additional data describing the error. A stringified version of this object\n\t * will be appended to the error message, so the data are quickly visible in the console. The original\n\t * data object will also be later available under the {@link #data} property.\n\t */ constructor(errorName, context, data){\n        super(getErrorMessage(errorName, data));\n        this.name = 'CKEditorError';\n        this.context = context;\n        this.data = data;\n    }\n    /**\n\t * Checks if the error is of the `CKEditorError` type.\n\t */ is(type) {\n        return type === 'CKEditorError';\n    }\n    /**\n\t * A utility that ensures that the thrown error is a {@link module:utils/ckeditorerror~CKEditorError} one.\n\t * It is useful when combined with the {@link module:watchdog/watchdog~Watchdog} feature, which can restart the editor in case\n\t * of a {@link module:utils/ckeditorerror~CKEditorError} error.\n\t *\n\t * @param err The error to rethrow.\n\t * @param context An object connected through properties with the editor instance. This context will be used\n\t * by the watchdog to verify which editor should be restarted.\n\t */ static rethrowUnexpectedError(err, context) {\n        if (err.is && err.is('CKEditorError')) {\n            throw err;\n        }\n        /**\n\t\t * An unexpected error occurred inside the CKEditor 5 codebase. This error will look like the original one\n\t\t * to make the debugging easier.\n\t\t *\n\t\t * This error is only useful when the editor is initialized using the {@link module:watchdog/watchdog~Watchdog} feature.\n\t\t * In case of such error (or any {@link module:utils/ckeditorerror~CKEditorError} error) the watchdog should restart the editor.\n\t\t *\n\t\t * @error unexpected-error\n\t\t */ const error = new CKEditorError(err.message, context);\n        // Restore the original stack trace to make the error look like the original one.\n        // See https://github.com/ckeditor/ckeditor5/issues/5595 for more details.\n        error.stack = err.stack;\n        throw error;\n    }\n}\n/**\n * Logs a warning to the console with a properly formatted message and adds a link to the documentation.\n * Use whenever you want to log a warning to the console.\n *\n * ```ts\n * /**\n *  * There was a problem processing the configuration of the toolbar. The item with the given\n *  * name does not exist, so it was omitted when rendering the toolbar.\n *  *\n *  * @error toolbarview-item-unavailable\n *  * @param {String} name The name of the component.\n *  *\\/\n * logWarning( 'toolbarview-item-unavailable', { name } );\n * ```\n *\n * See also {@link module:utils/ckeditorerror~CKEditorError} for an explanation when to throw an error and when to log\n * a warning or an error to the console.\n *\n * @param errorName The error name to be logged.\n * @param data Additional data to be logged.\n */ function logWarning(errorName, data) {\n    console.warn(...formatConsoleArguments(errorName, data));\n}\n/**\n * Logs an error to the console with a properly formatted message and adds a link to the documentation.\n * Use whenever you want to log an error to the console.\n *\n * ```ts\n * /**\n *  * There was a problem processing the configuration of the toolbar. The item with the given\n *  * name does not exist, so it was omitted when rendering the toolbar.\n *  *\n *  * @error toolbarview-item-unavailable\n *  * @param {String} name The name of the component.\n *  *\\/\n *  logError( 'toolbarview-item-unavailable', { name } );\n * ```\n *\n * **Note**: In most cases logging a warning using {@link module:utils/ckeditorerror~logWarning} is enough.\n *\n * See also {@link module:utils/ckeditorerror~CKEditorError} for an explanation when to use each method.\n *\n * @param errorName The error name to be logged.\n * @param data Additional data to be logged.\n */ function logError(errorName, data) {\n    console.error(...formatConsoleArguments(errorName, data));\n}\n/**\n * Returns formatted link to documentation message.\n */ function getLinkToDocumentationMessage(errorName) {\n    return `\\nRead more: ${DOCUMENTATION_URL}#error-${errorName}`;\n}\n/**\n * Returns formatted error message.\n */ function getErrorMessage(errorName, data) {\n    const processedObjects = new WeakSet();\n    const circularReferencesReplacer = (key, value)=>{\n        if (typeof value === 'object' && value !== null) {\n            if (processedObjects.has(value)) {\n                return `[object ${value.constructor.name}]`;\n            }\n            processedObjects.add(value);\n        }\n        return value;\n    };\n    const stringifiedData = data ? ` ${JSON.stringify(data, circularReferencesReplacer)}` : '';\n    const documentationLink = getLinkToDocumentationMessage(errorName);\n    return errorName + stringifiedData + documentationLink;\n}\n/**\n * Returns formatted console error arguments.\n */ function formatConsoleArguments(errorName, data) {\n    const documentationMessage = getLinkToDocumentationMessage(errorName);\n    return data ? [\n        errorName,\n        data,\n        documentationMessage\n    ] : [\n        errorName,\n        documentationMessage\n    ];\n}\n\nconst version = '43.3.1';\n// The second argument is not a month. It is `monthIndex` and starts from `0`.\nconst releaseDate = new Date(2024, 10, 6);\n/* istanbul ignore next -- @preserve */ if (globalThis.CKEDITOR_VERSION) {\n    /**\n\t * This error is thrown when, due to a mistake in the way CKEditor&nbsp;5 was installed,\n\t * imported, or initialized, some of its modules were evaluated and executed twice.\n\t * Duplicate modules inevitably lead to runtime errors and increased bundle size.\n\t *\n\t * # Check dependency versions\n\t *\n\t * First, make sure that you use the latest version of all CKEditor&nbsp;5 dependencies.\n\t * Depending on the installation method, you should check the versions of the `ckeditor5`,\n\t * `ckeditor5-premium-features`, or `@ckeditor/ckeditor5-<NAME>` packages. If you cannot update\n\t * to the latest version, ensure that all the CKEditor&nbsp;5 packages are\n\t * in the same version.\n\t *\n\t * If you use third-party plugins, make sure to update them, too. If they are incompatible\n\t * with the version of CKEditor&nbsp;5 you use, you may need to downgrade the CKEditor&nbsp;5 packages\n\t * (which we do not recommend). Ask the plugin's author to upgrade the dependencies,\n\t * or fork their project and update it yourself.\n\t *\n\t * # Check imports\n\t *\n\t * The next step is to look at how you import CKEditor&nbsp;5 into your project.\n\t *\n\t * **The {@glink updating/nim-migration/migration-to-new-installation-methods new installation methods}\n\t * are designed to prevent module duplication, so if you are not using them yet, you should consider\n\t * updating your project**. However, several legacy installation methods are still supported for backward\n\t * compatibility, and mixing them may result in module duplication.\n\t *\n\t * These are the most common import methods of the CKEditor&nbsp;5 packages.\n\t *\n\t * - **New installation methods (NIM)** &ndash; Imports from the `ckeditor5` and `ckeditor5-premium-features` packages.\n\t * - **Optimized build** for the new installation methods &ndash; Imports from the `@ckeditor/ckeditor5-<NAME>/dist/index.js`.\n\t * - **Predefined builds** (legacy) &ndash; Imports from the `@ckeditor/ckeditor5-build-<NAME>` packages.\n\t * - **Default imports** (legacy) &ndash; Imports from the `@ckeditor/ckeditor5-<NAME>` packages (default export).\n\t * - **`src`** (legacy) &ndash; Imports from the `@ckeditor/ckeditor5-<NAME>/src/*`.\n\t * - **DLL builds** (legacy) &ndash; Imports from the `ckeditor5/build/<NAME>` and `@ckeditor/ckeditor5-<NAME>/build/*`.\n\t *\n\t * The best way to avoid duplicate modules is to avoid mixing these installation methods. For example, if you use imports\n\t * specific to the optimized build, you should use them for all CKEditor&nbsp;5 packages. In addition, since\n\t * the Predefined and DLL builds already include the core of the editor, they cannot be used with other types of imports.\n\t *\n\t * Here is a matrix showing which installation methods are compatible with each other:\n\t *\n\t * |                  | NIM | Optimized build | Predefined builds | Default imports | `src` | DLL builds |\n\t * |------------------|-----|-----------------|-------------------|-----------------|-------|------------|\n\t * | NIM              | ✅  | ✅              | ❌                | ❌              | ❌    | ❌         |\n\t * | Optimized builds | ✅  | ✅              | ❌                | ❌              | ❌    | ❌         |\n\t * | Predefined build | ❌  | ❌              | ✅                | ❌              | ❌    | ❌         |\n\t * | Default imports  | ❌  | ❌              | ❌                | ✅              | ✅    | ❌         |\n\t * | `src`            | ❌  | ❌              | ❌                | ✅              | ✅    | ❌         |\n\t * | DLL builds       | ❌  | ❌              | ❌                | ❌              | ❌    | ✅         |\n\t *\n\t * If you use any third-party plugins, make sure the way you import them is compatible with\n\t * the way you import CKEditor&nbsp;5.\n\t *\n\t * <details>\n\t * <summary>New installation methods and optimized builds</summary>\n\t *\n\t * If you use the {@glink updating/nim-migration/migration-to-new-installation-methods new installation methods},\n\t * you should only import code from the `ckeditor5` and `ckeditor5-premium-features` packages.\n\t * Do not import code from the `@ckeditor/ckeditor5-<NAME>` packages unless you follow\n\t * the {@glink getting-started/setup/optimizing-build-size Optimizing build size} guide and the imports from\n\t * the `@ckeditor/ckeditor5-<NAME>` packages end with `/dist/index.js`.\n\t *\n\t * If you use a CDN, ensure that some files are not included twice in your project.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import { ClassicEditor, Highlight } from 'ckeditor5'; // ✅\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ✅\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ❌\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight.js'; // ❌\n\t * ```\n\t * </details>\n\t *\n\t * <details>\n\t * <summary>(Legacy) Predefined builds</summary>\n\t *\n\t * If you use the {@glink getting-started/legacy/installation-methods/predefined-builds Predefined builds},\n\t * you cannot import any additional plugins. These builds already include the editor's core\n\t * and selected plugins and importing additional ones will cause some modules to be bundled and loaded twice.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import ClassicEditor from '@ckeditor/ckeditor5-build-classic'; // ✅\n\t * import { Highlight } from 'ckeditor5'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ❌\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight'; // ❌\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight'; // ❌\n\t * ```\n\t *\n\t * If you are missing some features from the\n\t * {@glink getting-started/legacy/installation-methods/predefined-builds#plugins-included-in-the-predefined-builds list of plugins},\n\t * you should switch to the {@glink updating/nim-migration/migration-to-new-installation-methods new installation methods}\n\t * which do not have this limitation.\n\t * If you cannot migrate to the new installation methods, try the\n\t * {@glink getting-started/legacy/installation-methods/predefined-builds#superbuild superbuild} instead.\n\t * This build contains all the editor features.\n\t * </details>\n\t *\n\t * <details>\n\t * <summary>(Legacy) Default imports and `src` imports</summary>\n\t *\n\t * If you use the {@glink getting-started/legacy/installation-methods/quick-start-other legacy customized installation}\n\t * method, you should only import code from the `@ckeditor/ckeditor5-<NAME>` packages. While you can import code from\n\t * the `@ckeditor/ckeditor5-<NAME>/src/*` files, it is not recommended as it can make migration to the new installation\n\t * methods more difficult.\n\t *\n\t * If you use this installation method, you should not import code from the `ckeditor5`, `ckeditor5-premium-features`,\n\t * or `@ckeditor/ckeditor5-build-<NAME>` packages.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic'; // ✅\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ✅\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js'; // ✅ (not recommended)\n\t * import { Highlight } from 'ckeditor5'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ❌\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight'; // ❌\n\t * ```\n\t * </details>\n\t *\n\t * <details>\n\t * <summary>(Legacy) DLL builds</summary>\n\t *\n\t * If you are using the {@glink getting-started/legacy/advanced/alternative-setups/dll-builds legacy DLL builds},\n\t * you should not import any non-DLL modules.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import 'ckeditor5/build/ckeditor5-dll.js';// ✅\n\t * import '@ckeditor/ckeditor5-editor-classic/build/editor-classic.js';// ✅\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight.js';// ✅\n\t * import { Highlight } from 'ckeditor5'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ❌\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js'; // ❌\n\t * ```\n\t * </details>\n\t *\n\t * # Reinstall `node_modules`\n\t *\n\t * Usually, npm and other package managers deduplicate all packages - for example, `ckeditor5` is only installed once\n\t * in `node_modules/`. However, it is known to fail to do so occasionally.\n\t *\n\t * To rule out this possibility, you can try the following:\n\t *\n\t * 1. Remove the `node_modules` directory.\n\t * 2. Remove the `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml` files (depending on the package manager used).\n\t * 3. Run `npm install` to reinstall all packages.\n\t * 4. Run `npm ls` to check how many times packages like `@ckeditor/ckeditor5-core` are installed.\n\t * If they are installed more than once, verify which package causes that.\n\t *\n\t * @error ckeditor-duplicated-modules\n\t */ throw new CKEditorError('ckeditor-duplicated-modules', null);\n} else {\n    globalThis.CKEDITOR_VERSION = version;\n}\n\nconst _listeningTo = Symbol('listeningTo');\nconst _emitterId = Symbol('emitterId');\nconst _delegations = Symbol('delegations');\nconst defaultEmitterClass$1 = /* #__PURE__ */ EmitterMixin(Object);\nfunction EmitterMixin(base) {\n    if (!base) {\n        return defaultEmitterClass$1;\n    }\n    class Mixin extends base {\n        on(event, callback, options) {\n            this.listenTo(this, event, callback, options);\n        }\n        once(event, callback, options) {\n            let wasFired = false;\n            const onceCallback = (event, ...args)=>{\n                // Ensure the callback is called only once even if the callback itself leads to re-firing the event\n                // (which would call the callback again).\n                if (!wasFired) {\n                    wasFired = true;\n                    // Go off() at the first call.\n                    event.off();\n                    // Go with the original callback.\n                    callback.call(this, event, ...args);\n                }\n            };\n            // Make a similar on() call, simply replacing the callback.\n            this.listenTo(this, event, onceCallback, options);\n        }\n        off(event, callback) {\n            this.stopListening(this, event, callback);\n        }\n        listenTo(emitter, event, callback, options = {}) {\n            let emitterInfo, eventCallbacks;\n            // _listeningTo contains a list of emitters that this object is listening to.\n            // This list has the following format:\n            //\n            // _listeningTo: {\n            //     emitterId: {\n            //         emitter: emitter,\n            //         callbacks: {\n            //             event1: [ callback1, callback2, ... ]\n            //             ....\n            //         }\n            //     },\n            //     ...\n            // }\n            if (!this[_listeningTo]) {\n                this[_listeningTo] = {};\n            }\n            const emitters = this[_listeningTo];\n            if (!_getEmitterId(emitter)) {\n                _setEmitterId(emitter);\n            }\n            const emitterId = _getEmitterId(emitter);\n            if (!(emitterInfo = emitters[emitterId])) {\n                emitterInfo = emitters[emitterId] = {\n                    emitter,\n                    callbacks: {}\n                };\n            }\n            if (!(eventCallbacks = emitterInfo.callbacks[event])) {\n                eventCallbacks = emitterInfo.callbacks[event] = [];\n            }\n            eventCallbacks.push(callback);\n            // Finally register the callback to the event.\n            addEventListener(this, emitter, event, callback, options);\n        }\n        stopListening(emitter, event, callback) {\n            const emitters = this[_listeningTo];\n            let emitterId = emitter && _getEmitterId(emitter);\n            const emitterInfo = emitters && emitterId ? emitters[emitterId] : undefined;\n            const eventCallbacks = emitterInfo && event ? emitterInfo.callbacks[event] : undefined;\n            // Stop if nothing has been listened.\n            if (!emitters || emitter && !emitterInfo || event && !eventCallbacks) {\n                return;\n            }\n            // All params provided. off() that single callback.\n            if (callback) {\n                removeEventListener(this, emitter, event, callback);\n                // We must remove callbacks as well in order to prevent memory leaks.\n                // See https://github.com/ckeditor/ckeditor5/pull/8480\n                const index = eventCallbacks.indexOf(callback);\n                if (index !== -1) {\n                    if (eventCallbacks.length === 1) {\n                        delete emitterInfo.callbacks[event];\n                    } else {\n                        removeEventListener(this, emitter, event, callback);\n                    }\n                }\n            } else if (eventCallbacks) {\n                while(callback = eventCallbacks.pop()){\n                    removeEventListener(this, emitter, event, callback);\n                }\n                delete emitterInfo.callbacks[event];\n            } else if (emitterInfo) {\n                for(event in emitterInfo.callbacks){\n                    this.stopListening(emitter, event);\n                }\n                delete emitters[emitterId];\n            } else {\n                for(emitterId in emitters){\n                    this.stopListening(emitters[emitterId].emitter);\n                }\n                delete this[_listeningTo];\n            }\n        }\n        fire(eventOrInfo, ...args) {\n            try {\n                const eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo(this, eventOrInfo);\n                const event = eventInfo.name;\n                let callbacks = getCallbacksForEvent(this, event);\n                // Record that the event passed this emitter on its path.\n                eventInfo.path.push(this);\n                // Handle event listener callbacks first.\n                if (callbacks) {\n                    // Arguments passed to each callback.\n                    const callbackArgs = [\n                        eventInfo,\n                        ...args\n                    ];\n                    // Copying callbacks array is the easiest and most secure way of preventing infinite loops, when event callbacks\n                    // are added while processing other callbacks. Previous solution involved adding counters (unique ids) but\n                    // failed if callbacks were added to the queue before currently processed callback.\n                    // If this proves to be too inefficient, another method is to change `.on()` so callbacks are stored if same\n                    // event is currently processed. Then, `.fire()` at the end, would have to add all stored events.\n                    callbacks = Array.from(callbacks);\n                    for(let i = 0; i < callbacks.length; i++){\n                        callbacks[i].callback.apply(this, callbackArgs);\n                        // Remove the callback from future requests if off() has been called.\n                        if (eventInfo.off.called) {\n                            // Remove the called mark for the next calls.\n                            delete eventInfo.off.called;\n                            this._removeEventListener(event, callbacks[i].callback);\n                        }\n                        // Do not execute next callbacks if stop() was called.\n                        if (eventInfo.stop.called) {\n                            break;\n                        }\n                    }\n                }\n                // Delegate event to other emitters if needed.\n                const delegations = this[_delegations];\n                if (delegations) {\n                    const destinations = delegations.get(event);\n                    const passAllDestinations = delegations.get('*');\n                    if (destinations) {\n                        fireDelegatedEvents(destinations, eventInfo, args);\n                    }\n                    if (passAllDestinations) {\n                        fireDelegatedEvents(passAllDestinations, eventInfo, args);\n                    }\n                }\n                return eventInfo.return;\n            } catch (err) {\n                // @if CK_DEBUG // throw err;\n                /* istanbul ignore next -- @preserve */ CKEditorError.rethrowUnexpectedError(err, this);\n            }\n        }\n        delegate(...events) {\n            return {\n                to: (emitter, nameOrFunction)=>{\n                    if (!this[_delegations]) {\n                        this[_delegations] = new Map();\n                    }\n                    // Originally there was a for..of loop which unfortunately caused an error in Babel that didn't allow\n                    // build an application. See: https://github.com/ckeditor/ckeditor5-react/issues/40.\n                    events.forEach((eventName)=>{\n                        const destinations = this[_delegations].get(eventName);\n                        if (!destinations) {\n                            this[_delegations].set(eventName, new Map([\n                                [\n                                    emitter,\n                                    nameOrFunction\n                                ]\n                            ]));\n                        } else {\n                            destinations.set(emitter, nameOrFunction);\n                        }\n                    });\n                }\n            };\n        }\n        stopDelegating(event, emitter) {\n            if (!this[_delegations]) {\n                return;\n            }\n            if (!event) {\n                this[_delegations].clear();\n            } else if (!emitter) {\n                this[_delegations].delete(event);\n            } else {\n                const destinations = this[_delegations].get(event);\n                if (destinations) {\n                    destinations.delete(emitter);\n                }\n            }\n        }\n        _addEventListener(event, callback, options) {\n            createEventNamespace(this, event);\n            const lists = getCallbacksListsForNamespace(this, event);\n            const priority = priorities.get(options.priority);\n            const callbackDefinition = {\n                callback,\n                priority\n            };\n            // Add the callback to all callbacks list.\n            for (const callbacks of lists){\n                // Add the callback to the list in the right priority position.\n                insertToPriorityArray(callbacks, callbackDefinition);\n            }\n        }\n        _removeEventListener(event, callback) {\n            const lists = getCallbacksListsForNamespace(this, event);\n            for (const callbacks of lists){\n                for(let i = 0; i < callbacks.length; i++){\n                    if (callbacks[i].callback == callback) {\n                        // Remove the callback from the list (fixing the next index).\n                        callbacks.splice(i, 1);\n                        i--;\n                    }\n                }\n            }\n        }\n    }\n    return Mixin;\n}\n// Backward compatibility with `mix`\n[\n    'on',\n    'once',\n    'off',\n    'listenTo',\n    'stopListening',\n    'fire',\n    'delegate',\n    'stopDelegating',\n    '_addEventListener',\n    '_removeEventListener'\n].forEach((key)=>{\n    EmitterMixin[key] = defaultEmitterClass$1.prototype[key];\n});\n/**\n * Checks if `listeningEmitter` listens to an emitter with given `listenedToEmitterId` and if so, returns that emitter.\n * If not, returns `null`.\n *\n * @internal\n * @param listeningEmitter An emitter that listens.\n * @param listenedToEmitterId Unique emitter id of emitter listened to.\n */ function _getEmitterListenedTo(listeningEmitter, listenedToEmitterId) {\n    const listeningTo = listeningEmitter[_listeningTo];\n    if (listeningTo && listeningTo[listenedToEmitterId]) {\n        return listeningTo[listenedToEmitterId].emitter;\n    }\n    return null;\n}\n/**\n * Sets emitter's unique id.\n *\n * **Note:** `_emitterId` can be set only once.\n *\n * @internal\n * @param emitter An emitter for which id will be set.\n * @param id Unique id to set. If not passed, random unique id will be set.\n */ function _setEmitterId(emitter, id) {\n    if (!emitter[_emitterId]) {\n        emitter[_emitterId] = id || uid();\n    }\n}\n/**\n * Returns emitter's unique id.\n *\n * @internal\n * @param emitter An emitter which id will be returned.\n */ function _getEmitterId(emitter) {\n    return emitter[_emitterId];\n}\n/**\n * Gets the internal `_events` property of the given object.\n * `_events` property store all lists with callbacks for registered event names.\n * If there were no events registered on the object, empty `_events` object is created.\n */ function getEvents(source) {\n    if (!source._events) {\n        Object.defineProperty(source, '_events', {\n            value: {}\n        });\n    }\n    return source._events;\n}\n/**\n * Creates event node for generic-specific events relation architecture.\n */ function makeEventNode() {\n    return {\n        callbacks: [],\n        childEvents: []\n    };\n}\n/**\n * Creates an architecture for generic-specific events relation.\n * If needed, creates all events for given eventName, i.e. if the first registered event\n * is foo:bar:abc, it will create foo:bar:abc, foo:bar and foo event and tie them together.\n * It also copies callbacks from more generic events to more specific events when\n * specific events are created.\n */ function createEventNamespace(source, eventName) {\n    const events = getEvents(source);\n    // First, check if the event we want to add to the structure already exists.\n    if (events[eventName]) {\n        // If it exists, we don't have to do anything.\n        return;\n    }\n    // In other case, we have to create the structure for the event.\n    // Note, that we might need to create intermediate events too.\n    // I.e. if foo:bar:abc is being registered and we only have foo in the structure,\n    // we need to also register foo:bar.\n    // Currently processed event name.\n    let name = eventName;\n    // Name of the event that is a child event for currently processed event.\n    let childEventName = null;\n    // Array containing all newly created specific events.\n    const newEventNodes = [];\n    // While loop can't check for ':' index because we have to handle generic events too.\n    // In each loop, we truncate event name, going from the most specific name to the generic one.\n    // I.e. foo:bar:abc -> foo:bar -> foo.\n    while(name !== ''){\n        if (events[name]) {\n            break;\n        }\n        // If this event is not yet registered, create a new object for it.\n        events[name] = makeEventNode();\n        // Add it to the array with newly created events.\n        newEventNodes.push(events[name]);\n        // Add previously processed event name as a child of this event.\n        if (childEventName) {\n            events[name].childEvents.push(childEventName);\n        }\n        childEventName = name;\n        // If `.lastIndexOf()` returns -1, `.substr()` will return '' which will break the loop.\n        name = name.substr(0, name.lastIndexOf(':'));\n    }\n    if (name !== '') {\n        // If name is not empty, we found an already registered event that was a parent of the\n        // event we wanted to register.\n        // Copy that event's callbacks to newly registered events.\n        for (const node of newEventNodes){\n            node.callbacks = events[name].callbacks.slice();\n        }\n        // Add last newly created event to the already registered event.\n        events[name].childEvents.push(childEventName);\n    }\n}\n/**\n * Gets an array containing callbacks list for a given event and it's more specific events.\n * I.e. if given event is foo:bar and there is also foo:bar:abc event registered, this will\n * return callback list of foo:bar and foo:bar:abc (but not foo).\n */ function getCallbacksListsForNamespace(source, eventName) {\n    const eventNode = getEvents(source)[eventName];\n    if (!eventNode) {\n        return [];\n    }\n    let callbacksLists = [\n        eventNode.callbacks\n    ];\n    for(let i = 0; i < eventNode.childEvents.length; i++){\n        const childCallbacksLists = getCallbacksListsForNamespace(source, eventNode.childEvents[i]);\n        callbacksLists = callbacksLists.concat(childCallbacksLists);\n    }\n    return callbacksLists;\n}\n/**\n * Get the list of callbacks for a given event, but only if there any callbacks have been registered.\n * If there are no callbacks registered for given event, it checks if this is a specific event and looks\n * for callbacks for it's more generic version.\n */ function getCallbacksForEvent(source, eventName) {\n    let event;\n    if (!source._events || !(event = source._events[eventName]) || !event.callbacks.length) {\n        // There are no callbacks registered for specified eventName.\n        // But this could be a specific-type event that is in a namespace.\n        if (eventName.indexOf(':') > -1) {\n            // If the eventName is specific, try to find callback lists for more generic event.\n            return getCallbacksForEvent(source, eventName.substr(0, eventName.lastIndexOf(':')));\n        } else {\n            // If this is a top-level generic event, return null;\n            return null;\n        }\n    }\n    return event.callbacks;\n}\n/**\n * Fires delegated events for given map of destinations.\n *\n * @param destinations A map containing `[ {@link module:utils/emittermixin~Emitter}, \"event name\" ]` pair destinations.\n * @param eventInfo The original event info object.\n * @param fireArgs Arguments the original event was fired with.\n */ function fireDelegatedEvents(destinations, eventInfo, fireArgs) {\n    for (let [emitter, name] of destinations){\n        if (!name) {\n            name = eventInfo.name;\n        } else if (typeof name == 'function') {\n            name = name(eventInfo.name);\n        }\n        const delegatedInfo = new EventInfo(eventInfo.source, name);\n        delegatedInfo.path = [\n            ...eventInfo.path\n        ];\n        emitter.fire(delegatedInfo, ...fireArgs);\n    }\n}\n/**\n * Helper for registering event callback on the emitter.\n */ function addEventListener(listener, emitter, event, callback, options) {\n    if (emitter._addEventListener) {\n        emitter._addEventListener(event, callback, options);\n    } else {\n        // Allow listening on objects that do not implement Emitter interface.\n        // This is needed in some tests that are using mocks instead of the real objects with EmitterMixin mixed.\n        listener._addEventListener.call(emitter, event, callback, options);\n    }\n}\n/**\n * Helper for removing event callback from the emitter.\n */ function removeEventListener(listener, emitter, event, callback) {\n    if (emitter._removeEventListener) {\n        emitter._removeEventListener(event, callback);\n    } else {\n        // Allow listening on objects that do not implement Emitter interface.\n        // This is needed in some tests that are using mocks instead of the real objects with EmitterMixin mixed.\n        listener._removeEventListener.call(emitter, event, callback);\n    }\n}\n\nconst observablePropertiesSymbol = Symbol('observableProperties');\nconst boundObservablesSymbol = Symbol('boundObservables');\nconst boundPropertiesSymbol = Symbol('boundProperties');\nconst decoratedMethods = Symbol('decoratedMethods');\nconst decoratedOriginal = Symbol('decoratedOriginal');\nconst defaultObservableClass = /* #__PURE__ */ ObservableMixin(/* #__PURE__ */ EmitterMixin());\nfunction ObservableMixin(base) {\n    if (!base) {\n        return defaultObservableClass;\n    }\n    class Mixin extends base {\n        set(name, value) {\n            // If the first parameter is an Object, iterate over its properties.\n            if (isObject(name)) {\n                Object.keys(name).forEach((property)=>{\n                    this.set(property, name[property]);\n                }, this);\n                return;\n            }\n            initObservable(this);\n            const properties = this[observablePropertiesSymbol];\n            if (name in this && !properties.has(name)) {\n                /**\n\t\t\t\t * Cannot override an existing property.\n\t\t\t\t *\n\t\t\t\t * This error is thrown when trying to {@link module:utils/observablemixin~Observable#set set} a property with\n\t\t\t\t * a name of an already existing property. For example:\n\t\t\t\t *\n\t\t\t\t * ```ts\n\t\t\t\t * let observable = new Model();\n\t\t\t\t * observable.property = 1;\n\t\t\t\t * observable.set( 'property', 2 );\t\t\t// throws\n\t\t\t\t *\n\t\t\t\t * observable.set( 'property', 1 );\n\t\t\t\t * observable.set( 'property', 2 );\t\t\t// ok, because this is an existing property.\n\t\t\t\t * ```\n\t\t\t\t *\n\t\t\t\t * @error observable-set-cannot-override\n\t\t\t\t */ throw new CKEditorError('observable-set-cannot-override', this);\n            }\n            Object.defineProperty(this, name, {\n                enumerable: true,\n                configurable: true,\n                get () {\n                    return properties.get(name);\n                },\n                set (value) {\n                    const oldValue = properties.get(name);\n                    // Fire `set` event before the new value will be set to make it possible\n                    // to override observable property without affecting `change` event.\n                    // See https://github.com/ckeditor/ckeditor5-utils/issues/171.\n                    let newValue = this.fire(`set:${name}`, name, value, oldValue);\n                    if (newValue === undefined) {\n                        newValue = value;\n                    }\n                    // Allow undefined as an initial value like A.define( 'x', undefined ) (#132).\n                    // Note: When properties map has no such own property, then its value is undefined.\n                    if (oldValue !== newValue || !properties.has(name)) {\n                        properties.set(name, newValue);\n                        this.fire(`change:${name}`, name, newValue, oldValue);\n                    }\n                }\n            });\n            this[name] = value;\n        }\n        bind(...bindProperties) {\n            if (!bindProperties.length || !isStringArray(bindProperties)) {\n                /**\n\t\t\t\t * All properties must be strings.\n\t\t\t\t *\n\t\t\t\t * @error observable-bind-wrong-properties\n\t\t\t\t */ throw new CKEditorError('observable-bind-wrong-properties', this);\n            }\n            if (new Set(bindProperties).size !== bindProperties.length) {\n                /**\n\t\t\t\t * Properties must be unique.\n\t\t\t\t *\n\t\t\t\t * @error observable-bind-duplicate-properties\n\t\t\t\t */ throw new CKEditorError('observable-bind-duplicate-properties', this);\n            }\n            initObservable(this);\n            const boundProperties = this[boundPropertiesSymbol];\n            bindProperties.forEach((propertyName)=>{\n                if (boundProperties.has(propertyName)) {\n                    /**\n\t\t\t\t\t * Cannot bind the same property more than once.\n\t\t\t\t\t *\n\t\t\t\t\t * @error observable-bind-rebind\n\t\t\t\t\t */ throw new CKEditorError('observable-bind-rebind', this);\n                }\n            });\n            const bindings = new Map();\n            bindProperties.forEach((a)=>{\n                const binding = {\n                    property: a,\n                    to: []\n                };\n                boundProperties.set(a, binding);\n                bindings.set(a, binding);\n            });\n            return {\n                to: bindTo,\n                toMany: bindToMany,\n                _observable: this,\n                _bindProperties: bindProperties,\n                _to: [],\n                _bindings: bindings\n            };\n        }\n        unbind(...unbindProperties) {\n            // Nothing to do here if not inited yet.\n            if (!this[observablePropertiesSymbol]) {\n                return;\n            }\n            const boundProperties = this[boundPropertiesSymbol];\n            const boundObservables = this[boundObservablesSymbol];\n            if (unbindProperties.length) {\n                if (!isStringArray(unbindProperties)) {\n                    /**\n\t\t\t\t\t * Properties must be strings.\n\t\t\t\t\t *\n\t\t\t\t\t * @error observable-unbind-wrong-properties\n\t\t\t\t\t */ throw new CKEditorError('observable-unbind-wrong-properties', this);\n                }\n                unbindProperties.forEach((propertyName)=>{\n                    const binding = boundProperties.get(propertyName);\n                    // Nothing to do if the binding is not defined\n                    if (!binding) {\n                        return;\n                    }\n                    binding.to.forEach(([toObservable, toProperty])=>{\n                        const toProperties = boundObservables.get(toObservable);\n                        const toPropertyBindings = toProperties[toProperty];\n                        toPropertyBindings.delete(binding);\n                        if (!toPropertyBindings.size) {\n                            delete toProperties[toProperty];\n                        }\n                        if (!Object.keys(toProperties).length) {\n                            boundObservables.delete(toObservable);\n                            this.stopListening(toObservable, 'change');\n                        }\n                    });\n                    boundProperties.delete(propertyName);\n                });\n            } else {\n                boundObservables.forEach((bindings, boundObservable)=>{\n                    this.stopListening(boundObservable, 'change');\n                });\n                boundObservables.clear();\n                boundProperties.clear();\n            }\n        }\n        decorate(methodName) {\n            initObservable(this);\n            const originalMethod = this[methodName];\n            if (!originalMethod) {\n                /**\n\t\t\t\t * Cannot decorate an undefined method.\n\t\t\t\t *\n\t\t\t\t * @error observablemixin-cannot-decorate-undefined\n\t\t\t\t * @param {Object} object The object which method should be decorated.\n\t\t\t\t * @param {String} methodName Name of the method which does not exist.\n\t\t\t\t */ throw new CKEditorError('observablemixin-cannot-decorate-undefined', this, {\n                    object: this,\n                    methodName\n                });\n            }\n            this.on(methodName, (evt, args)=>{\n                evt.return = originalMethod.apply(this, args);\n            });\n            this[methodName] = function(...args) {\n                return this.fire(methodName, args);\n            };\n            this[methodName][decoratedOriginal] = originalMethod;\n            if (!this[decoratedMethods]) {\n                this[decoratedMethods] = [];\n            }\n            this[decoratedMethods].push(methodName);\n        }\n        // Override the EmitterMixin stopListening method to be able to clean (and restore) decorated methods.\n        // This is needed in case of:\n        //  1. Have x.foo() decorated.\n        //  2. Call x.stopListening()\n        //  3. Call x.foo(). Problem: nothing happens (the original foo() method is not executed)\n        stopListening(emitter, event, callback) {\n            // Removing all listeners so let's clean the decorated methods to the original state.\n            if (!emitter && this[decoratedMethods]) {\n                for (const methodName of this[decoratedMethods]){\n                    this[methodName] = this[methodName][decoratedOriginal];\n                }\n                delete this[decoratedMethods];\n            }\n            super.stopListening(emitter, event, callback);\n        }\n        [observablePropertiesSymbol];\n        [decoratedMethods];\n        [boundPropertiesSymbol];\n        [boundObservablesSymbol];\n    }\n    return Mixin;\n}\n// Backward compatibility with `mix`\n[\n    'set',\n    'bind',\n    'unbind',\n    'decorate',\n    'on',\n    'once',\n    'off',\n    'listenTo',\n    'stopListening',\n    'fire',\n    'delegate',\n    'stopDelegating',\n    '_addEventListener',\n    '_removeEventListener'\n].forEach((key)=>{\n    ObservableMixin[key] = defaultObservableClass.prototype[key];\n});\n// Init symbol properties needed for the observable mechanism to work.\nfunction initObservable(observable) {\n    // Do nothing if already inited.\n    if (observable[observablePropertiesSymbol]) {\n        return;\n    }\n    // The internal hash containing the observable's state.\n    Object.defineProperty(observable, observablePropertiesSymbol, {\n        value: new Map()\n    });\n    // Map containing bindings to external observables. It shares the binding objects\n    // (`{ observable: A, property: 'a', to: ... }`) with {@link module:utils/observablemixin~Observable#_boundProperties} and\n    // it is used to observe external observables to update own properties accordingly.\n    // See {@link module:utils/observablemixin~Observable#bind}.\n    //\n    //\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n    //\t\tconsole.log( A._boundObservables );\n    //\n    //\t\t\tMap( {\n    //\t\t\t\tB: {\n    //\t\t\t\t\tx: Set( [\n    //\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n    //\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n    //\t\t\t\t\t] ),\n    //\t\t\t\t\ty: Set( [\n    //\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n    //\t\t\t\t\t] )\n    //\t\t\t\t}\n    //\t\t\t} )\n    //\n    //\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n    //\t\tconsole.log( A._boundObservables );\n    //\n    //\t\t\tMap( {\n    //\t\t\t\tB: {\n    //\t\t\t\t\tx: Set( [\n    //\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n    //\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n    //\t\t\t\t\t] ),\n    //\t\t\t\t\ty: Set( [\n    //\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n    //\t\t\t\t\t] ),\n    //\t\t\t\t\tz: Set( [\n    //\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n    //\t\t\t\t\t] )\n    //\t\t\t\t},\n    //\t\t\t\tC: {\n    //\t\t\t\t\tw: Set( [\n    //\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n    //\t\t\t\t\t] )\n    //\t\t\t\t}\n    //\t\t\t} )\n    //\n    Object.defineProperty(observable, boundObservablesSymbol, {\n        value: new Map()\n    });\n    // Object that stores which properties of this observable are bound and how. It shares\n    // the binding objects (`{ observable: A, property: 'a', to: ... }`) with\n    // {@link module:utils/observablemixin~Observable#_boundObservables}. This data structure is\n    // a reverse of {@link module:utils/observablemixin~Observable#_boundObservables} and it is helpful for\n    // {@link module:utils/observablemixin~Observable#unbind}.\n    //\n    // See {@link module:utils/observablemixin~Observable#bind}.\n    //\n    //\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n    //\t\tconsole.log( A._boundProperties );\n    //\n    //\t\t\tMap( {\n    //\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n    //\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n    //\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n    //\t\t\t} )\n    //\n    //\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n    //\t\tconsole.log( A._boundProperties );\n    //\n    //\t\t\tMap( {\n    //\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n    //\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n    //\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] },\n    //\t\t\t\td: { observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n    //\t\t\t} )\n    Object.defineProperty(observable, boundPropertiesSymbol, {\n        value: new Map()\n    });\n}\n/**\n * A chaining for {@link module:utils/observablemixin~Observable#bind} providing `.to()` interface.\n *\n * @param args Arguments of the `.to( args )` binding.\n */ function bindTo(...args) {\n    const parsedArgs = parseBindToArgs(...args);\n    const bindingsKeys = Array.from(this._bindings.keys());\n    const numberOfBindings = bindingsKeys.length;\n    // Eliminate A.bind( 'x' ).to( B, C )\n    if (!parsedArgs.callback && parsedArgs.to.length > 1) {\n        /**\n\t\t * Binding multiple observables only possible with callback.\n\t\t *\n\t\t * @error observable-bind-to-no-callback\n\t\t */ throw new CKEditorError('observable-bind-to-no-callback', this);\n    }\n    // Eliminate A.bind( 'x', 'y' ).to( B, callback )\n    if (numberOfBindings > 1 && parsedArgs.callback) {\n        /**\n\t\t * Cannot bind multiple properties and use a callback in one binding.\n\t\t *\n\t\t * @error observable-bind-to-extra-callback\n\t\t */ throw new CKEditorError('observable-bind-to-extra-callback', this);\n    }\n    parsedArgs.to.forEach((to)=>{\n        // Eliminate A.bind( 'x', 'y' ).to( B, 'a' )\n        if (to.properties.length && to.properties.length !== numberOfBindings) {\n            /**\n\t\t\t * The number of properties must match.\n\t\t\t *\n\t\t\t * @error observable-bind-to-properties-length\n\t\t\t */ throw new CKEditorError('observable-bind-to-properties-length', this);\n        }\n        // When no to.properties specified, observing source properties instead i.e.\n        // A.bind( 'x', 'y' ).to( B ) -> Observe B.x and B.y\n        if (!to.properties.length) {\n            to.properties = this._bindProperties;\n        }\n    });\n    this._to = parsedArgs.to;\n    // Fill {@link BindChain#_bindings} with callback. When the callback is set there's only one binding.\n    if (parsedArgs.callback) {\n        this._bindings.get(bindingsKeys[0]).callback = parsedArgs.callback;\n    }\n    attachBindToListeners(this._observable, this._to);\n    // Update observable._boundProperties and observable._boundObservables.\n    updateBindToBound(this);\n    // Set initial values of bound properties.\n    this._bindProperties.forEach((propertyName)=>{\n        updateBoundObservableProperty(this._observable, propertyName);\n    });\n}\n/**\n * Binds to an attribute in a set of iterable observables.\n */ function bindToMany(observables, attribute, callback) {\n    if (this._bindings.size > 1) {\n        /**\n\t\t * Binding one attribute to many observables only possible with one attribute.\n\t\t *\n\t\t * @error observable-bind-to-many-not-one-binding\n\t\t */ throw new CKEditorError('observable-bind-to-many-not-one-binding', this);\n    }\n    this.to(// Bind to #attribute of each observable...\n    ...getBindingTargets(observables, attribute), // ...using given callback to parse attribute values.\n    callback);\n}\n/**\n * Returns an array of binding components for\n * {@link Observable#bind} from a set of iterable observables.\n */ function getBindingTargets(observables, attribute) {\n    const observableAndAttributePairs = observables.map((observable)=>[\n            observable,\n            attribute\n        ]);\n    // Merge pairs to one-dimension array of observables and attributes.\n    return Array.prototype.concat.apply([], observableAndAttributePairs);\n}\n/**\n * Check if all entries of the array are of `String` type.\n */ function isStringArray(arr) {\n    return arr.every((a)=>typeof a == 'string');\n}\n/**\n * Parses and validates {@link Observable#bind}`.to( args )` arguments and returns\n * an object with a parsed structure. For example\n *\n * ```ts\n * A.bind( 'x' ).to( B, 'a', C, 'b', call );\n * ```\n *\n * becomes\n *\n * ```ts\n * {\n * \tto: [\n * \t\t{ observable: B, properties: [ 'a' ] },\n * \t\t{ observable: C, properties: [ 'b' ] },\n * \t],\n * \tcallback: call\n * }\n *\n * @param args Arguments of {@link Observable#bind}`.to( args )`.\n */ function parseBindToArgs(...args) {\n    // Eliminate A.bind( 'x' ).to()\n    if (!args.length) {\n        /**\n\t\t * Invalid argument syntax in `to()`.\n\t\t *\n\t\t * @error observable-bind-to-parse-error\n\t\t */ throw new CKEditorError('observable-bind-to-parse-error', null);\n    }\n    const parsed = {\n        to: []\n    };\n    let lastObservable;\n    if (typeof args[args.length - 1] == 'function') {\n        parsed.callback = args.pop();\n    }\n    args.forEach((a)=>{\n        if (typeof a == 'string') {\n            lastObservable.properties.push(a);\n        } else if (typeof a == 'object') {\n            lastObservable = {\n                observable: a,\n                properties: []\n            };\n            parsed.to.push(lastObservable);\n        } else {\n            throw new CKEditorError('observable-bind-to-parse-error', null);\n        }\n    });\n    return parsed;\n}\n/**\n * Synchronizes {@link module:utils/observable#_boundObservables} with {@link Binding}.\n *\n * @param binding A binding to store in {@link Observable#_boundObservables}.\n * @param toObservable A observable, which is a new component of `binding`.\n * @param toPropertyName A name of `toObservable`'s property, a new component of the `binding`.\n */ function updateBoundObservables(observable, binding, toObservable, toPropertyName) {\n    const boundObservables = observable[boundObservablesSymbol];\n    const bindingsToObservable = boundObservables.get(toObservable);\n    const bindings = bindingsToObservable || {};\n    if (!bindings[toPropertyName]) {\n        bindings[toPropertyName] = new Set();\n    }\n    // Pass the binding to a corresponding Set in `observable._boundObservables`.\n    bindings[toPropertyName].add(binding);\n    if (!bindingsToObservable) {\n        boundObservables.set(toObservable, bindings);\n    }\n}\n/**\n * Synchronizes {@link Observable#_boundProperties} and {@link Observable#_boundObservables}\n * with {@link BindChain}.\n *\n * Assuming the following binding being created\n *\n * ```ts\n * A.bind( 'a', 'b' ).to( B, 'x', 'y' );\n * ```\n *\n * the following bindings were initialized by {@link Observable#bind} in {@link BindChain#_bindings}:\n *\n * ```ts\n * {\n * \ta: { observable: A, property: 'a', to: [] },\n * \tb: { observable: A, property: 'b', to: [] },\n * }\n * ```\n *\n * Iterate over all bindings in this chain and fill their `to` properties with\n * corresponding to( ... ) arguments (components of the binding), so\n *\n * ```ts\n * {\n * \ta: { observable: A, property: 'a', to: [ B, 'x' ] },\n * \tb: { observable: A, property: 'b', to: [ B, 'y' ] },\n * }\n * ```\n *\n * Then update the structure of {@link Observable#_boundObservables} with updated\n * binding, so it becomes:\n *\n * ```ts\n * Map( {\n * \tB: {\n * \t\tx: Set( [\n * \t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] }\n * \t\t] ),\n * \t\ty: Set( [\n * \t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n * \t\t] )\n * \t}\n * } )\n * ```\n *\n * @param chain The binding initialized by {@link Observable#bind}.\n */ function updateBindToBound(chain) {\n    let toProperty;\n    chain._bindings.forEach((binding, propertyName)=>{\n        // Note: For a binding without a callback, this will run only once\n        // like in A.bind( 'x', 'y' ).to( B, 'a', 'b' )\n        // TODO: ES6 destructuring.\n        chain._to.forEach((to)=>{\n            toProperty = to.properties[binding.callback ? 0 : chain._bindProperties.indexOf(propertyName)];\n            binding.to.push([\n                to.observable,\n                toProperty\n            ]);\n            updateBoundObservables(chain._observable, binding, to.observable, toProperty);\n        });\n    });\n}\n/**\n * Updates an property of a {@link Observable} with a value\n * determined by an entry in {@link Observable#_boundProperties}.\n *\n * @param observable A observable which property is to be updated.\n * @param propertyName An property to be updated.\n */ function updateBoundObservableProperty(observable, propertyName) {\n    const boundProperties = observable[boundPropertiesSymbol];\n    const binding = boundProperties.get(propertyName);\n    let propertyValue;\n    // When a binding with callback is created like\n    //\n    // \t\tA.bind( 'a' ).to( B, 'b', C, 'c', callback );\n    //\n    // collect B.b and C.c, then pass them to callback to set A.a.\n    if (binding.callback) {\n        propertyValue = binding.callback.apply(observable, binding.to.map((to)=>to[0][to[1]]));\n    } else {\n        propertyValue = binding.to[0];\n        propertyValue = propertyValue[0][propertyValue[1]];\n    }\n    if (Object.prototype.hasOwnProperty.call(observable, propertyName)) {\n        observable[propertyName] = propertyValue;\n    } else {\n        observable.set(propertyName, propertyValue);\n    }\n}\n/**\n * Starts listening to changes in {@link BindChain._to} observables to update\n * {@link BindChain._observable} {@link BindChain._bindProperties}. Also sets the\n * initial state of {@link BindChain._observable}.\n *\n * @param chain The chain initialized by {@link Observable#bind}.\n */ function attachBindToListeners(observable, toBindings) {\n    toBindings.forEach((to)=>{\n        const boundObservables = observable[boundObservablesSymbol];\n        let bindings;\n        // If there's already a chain between the observables (`observable` listens to\n        // `to.observable`), there's no need to create another `change` event listener.\n        if (!boundObservables.get(to.observable)) {\n            observable.listenTo(to.observable, 'change', (evt, propertyName)=>{\n                bindings = boundObservables.get(to.observable)[propertyName];\n                // Note: to.observable will fire for any property change, react\n                // to changes of properties which are bound only.\n                if (bindings) {\n                    bindings.forEach((binding)=>{\n                        updateBoundObservableProperty(observable, binding.property);\n                    });\n                }\n            });\n        }\n    });\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/elementreplacer\n */ /**\n * Utility class allowing to hide existing HTML elements or replace them with given ones in a way that doesn't remove\n * the original elements from the DOM.\n */ class ElementReplacer {\n    /**\n\t * The elements replaced by {@link #replace} and their replacements.\n\t */ _replacedElements;\n    constructor(){\n        this._replacedElements = [];\n    }\n    /**\n\t * Hides the `element` and, if specified, inserts the the given element next to it.\n\t *\n\t * The effect of this method can be reverted by {@link #restore}.\n\t *\n\t * @param element The element to replace.\n\t * @param newElement The replacement element. If not passed, then the `element` will just be hidden.\n\t */ replace(element, newElement) {\n        this._replacedElements.push({\n            element,\n            newElement\n        });\n        element.style.display = 'none';\n        if (newElement) {\n            element.parentNode.insertBefore(newElement, element.nextSibling);\n        }\n    }\n    /**\n\t * Restores what {@link #replace} did.\n\t */ restore() {\n        this._replacedElements.forEach(({ element, newElement })=>{\n            element.style.display = '';\n            if (newElement) {\n                newElement.remove();\n            }\n        });\n        this._replacedElements = [];\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/abortabledebounce\n */ /**\n * Returns a function wrapper that will execute the provided function and abort any previous call that is still in progress.\n *\n * @param func The function to be called. It will be provided with `AbortSignal` as the first parameter.\n */ function abortableDebounce(func) {\n    let controller = new AbortController();\n    function abortable(...args) {\n        controller.abort();\n        controller = new AbortController();\n        return func(controller.signal, ...args);\n    }\n    abortable.abort = ()=>controller.abort();\n    return abortable;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/count\n */ /**\n * Returns the number of items return by the iterator.\n *\n * ```ts\n * count( [ 1, 2, 3, 4, 5 ] ); // 5;\n * ```\n *\n * @param iterable Any iterable.\n * @returns Number of items returned by that iterable.\n */ function count(iterable) {\n    let count = 0;\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    for (const _ of iterable){\n        count++;\n    }\n    return count;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/comparearrays\n */ /**\n * Compares how given arrays relate to each other. One array can be: same as another array, prefix of another array\n * or completely different. If arrays are different, first index at which they differ is returned. Otherwise,\n * a flag specifying the relation is returned. Flags are negative numbers, so whenever a number >= 0 is returned\n * it means that arrays differ.\n *\n * ```ts\n * compareArrays( [ 0, 2 ], [ 0, 2 ] );\t\t// 'same'\n * compareArrays( [ 0, 2 ], [ 0, 2, 1 ] );\t\t// 'prefix'\n * compareArrays( [ 0, 2 ], [ 0 ] );\t\t\t// 'extension'\n * compareArrays( [ 0, 2 ], [ 1, 2 ] );\t\t// 0\n * compareArrays( [ 0, 2 ], [ 0, 1 ] );\t\t// 1\n * ```\n *\n * @param a Array that is compared.\n * @param b Array to compare with.\n * @returns How array `a` is related to `b`.\n */ function compareArrays(a, b) {\n    const minLen = Math.min(a.length, b.length);\n    for(let i = 0; i < minLen; i++){\n        if (a[i] != b[i]) {\n            // The arrays are different.\n            return i;\n        }\n    }\n    // Both arrays were same at all points.\n    if (a.length == b.length) {\n        // If their length is also same, they are the same.\n        return 'same';\n    } else if (a.length < b.length) {\n        // Compared array is shorter so it is a prefix of the other array.\n        return 'prefix';\n    } else {\n        // Compared array is longer so it is an extension of the other array.\n        return 'extension';\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/isiterable\n */ /**\n * Checks if value implements iterator interface.\n *\n * @param value The value to check.\n * @returns True if value implements iterator interface.\n */ function isIterable(value) {\n    return !!(value && value[Symbol.iterator]);\n}\n\n/**\n * Creates an HTML or SVG element with attributes and children elements.\n *\n * ```ts\n * createElement( document, 'p' ); // <p>\n * createElement( document, 'mask', { xmlns: 'http://www.w3.org/2000/svg' } ); // <mask>\n * ```\n *\n * @param doc Document used to create the element.\n * @param name Name of the element.\n * @param attributes Object where keys represent attribute keys and values represent attribute values.\n * @param children Child or any iterable of children. Strings will be automatically turned into Text nodes.\n * @returns HTML or SVG element.\n */ function createElement(doc, name, attributes = {}, children = []) {\n    const namespace = attributes && attributes.xmlns;\n    const element = namespace ? doc.createElementNS(namespace, name) : doc.createElement(name);\n    for(const key in attributes){\n        element.setAttribute(key, attributes[key]);\n    }\n    if (isString(children) || !isIterable(children)) {\n        children = [\n            children\n        ];\n    }\n    for (let child of children){\n        if (isString(child)) {\n            child = doc.createTextNode(child);\n        }\n        element.appendChild(child);\n    }\n    return element;\n}\n\n/**\n * Handles a configuration dictionary.\n *\n * @typeParam Cfg A type of the configuration dictionary.\n */ class Config {\n    /**\n\t * Store for the whole configuration.\n\t */ _config;\n    /**\n\t * Creates an instance of the {@link ~Config} class.\n\t *\n\t * @param configurations The initial configurations to be set. Usually, provided by the user.\n\t * @param defaultConfigurations The default configurations. Usually, provided by the system.\n\t */ constructor(configurations, defaultConfigurations){\n        this._config = Object.create(null);\n        // Set default configuration.\n        if (defaultConfigurations) {\n            // Clone the configuration to make sure that the properties will not be shared\n            // between editors and make the watchdog feature work correctly.\n            this.define(cloneConfig(defaultConfigurations));\n        }\n        // Set initial configuration.\n        if (configurations) {\n            this._setObjectToTarget(this._config, configurations);\n        }\n    }\n    set(name, value) {\n        this._setToTarget(this._config, name, value);\n    }\n    define(name, value) {\n        const isDefine = true;\n        this._setToTarget(this._config, name, value, isDefine);\n    }\n    /**\n\t * Gets the value for a configuration entry.\n\t *\n\t * ```ts\n\t * config.get( 'name' );\n\t * ```\n\t *\n\t * Deep configurations can be retrieved by separating each part with a dot.\n\t *\n\t * ```ts\n\t * config.get( 'toolbar.collapsed' );\n\t * ```\n\t *\n\t * @param name The configuration name. Configuration names are case-sensitive.\n\t * @returns The configuration value or `undefined` if the configuration entry was not found.\n\t */ get(name) {\n        return this._getFromSource(this._config, name);\n    }\n    /**\n\t * Iterates over all top level configuration names.\n\t */ *names() {\n        for (const name of Object.keys(this._config)){\n            yield name;\n        }\n    }\n    /**\n\t * Saves passed configuration to the specified target (nested object).\n\t *\n\t * @param target Nested config object.\n\t * @param name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param value The configuration value. Used if a name is passed.\n\t * @param isDefine Define if passed configuration should overwrite existing one.\n\t */ _setToTarget(target, name, value, isDefine = false) {\n        // In case of an object, iterate through it and call `_setToTarget` again for each property.\n        if (isPlainObject(name)) {\n            this._setObjectToTarget(target, name, isDefine);\n            return;\n        }\n        // The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n        const parts = name.split('.');\n        // Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n        name = parts.pop();\n        // Iterate over parts to check if currently stored configuration has proper structure.\n        for (const part of parts){\n            // If there is no object for specified part then create one.\n            if (!isPlainObject(target[part])) {\n                target[part] = Object.create(null);\n            }\n            // Nested object becomes a target.\n            target = target[part];\n        }\n        // In case of value is an object.\n        if (isPlainObject(value)) {\n            // We take care of proper config structure.\n            if (!isPlainObject(target[name])) {\n                target[name] = Object.create(null);\n            }\n            target = target[name];\n            // And iterate through this object calling `_setToTarget` again for each property.\n            this._setObjectToTarget(target, value, isDefine);\n            return;\n        }\n        // Do nothing if we are defining configuration for non empty name.\n        if (isDefine && typeof target[name] != 'undefined') {\n            return;\n        }\n        target[name] = value;\n    }\n    /**\n\t * Get specified configuration from specified source (nested object).\n\t *\n\t * @param source level of nested object.\n\t * @param name The configuration name. Configuration names are case-sensitive.\n\t * @returns The configuration value or `undefined` if the configuration entry was not found.\n\t */ _getFromSource(source, name) {\n        // The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n        const parts = name.split('.');\n        // Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n        name = parts.pop();\n        // Iterate over parts to check if currently stored configuration has proper structure.\n        for (const part of parts){\n            if (!isPlainObject(source[part])) {\n                source = null;\n                break;\n            }\n            // Nested object becomes a source.\n            source = source[part];\n        }\n        // Always returns undefined for non existing configuration.\n        return source ? cloneConfig(source[name]) : undefined;\n    }\n    /**\n\t * Iterates through passed object and calls {@link #_setToTarget} method with object key and value for each property.\n\t *\n\t * @param target Nested config object.\n\t * @param configuration Configuration data set\n\t * @param isDefine Defines if passed configuration is default configuration or not.\n\t */ _setObjectToTarget(target, configuration, isDefine) {\n        Object.keys(configuration).forEach((key)=>{\n            this._setToTarget(target, key, configuration[key], isDefine);\n        });\n    }\n}\n/**\n * Clones configuration object or value.\n */ function cloneConfig(source) {\n    return cloneDeepWith(source, leaveItemReferences);\n}\n/**\n * A customized function for cloneDeepWith.\n * In case if it's a DOM Element it will leave references to DOM Elements instead of cloning them.\n * If it's a function it will leave reference to actuall function.\n */ function leaveItemReferences(value) {\n    return isElement$1(value) || typeof value === 'function' ? value : undefined;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/isnode\n */ /**\n * Checks if the object is a native DOM Node.\n */ function isNode(obj) {\n    if (obj) {\n        if (obj.defaultView) {\n            return obj instanceof obj.defaultView.Document;\n        } else if (obj.ownerDocument && obj.ownerDocument.defaultView) {\n            return obj instanceof obj.ownerDocument.defaultView.Node;\n        }\n    }\n    return false;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/iswindow\n */ /**\n * Checks if the object is a native DOM Window.\n */ function isWindow(obj) {\n    const stringifiedObject = Object.prototype.toString.apply(obj);\n    // Returns `true` for the `window` object in browser environments.\n    if (stringifiedObject == '[object Window]') {\n        return true;\n    }\n    // Returns `true` for the `window` object in the Electron environment.\n    if (stringifiedObject == '[object global]') {\n        return true;\n    }\n    return false;\n}\n\nconst defaultEmitterClass = /* #__PURE__ */ DomEmitterMixin(/* #__PURE__ */ EmitterMixin());\nfunction DomEmitterMixin(base) {\n    if (!base) {\n        return defaultEmitterClass;\n    }\n    class Mixin extends base {\n        listenTo(emitter, event, callback, options = {}) {\n            // Check if emitter is an instance of DOM Node. If so, use corresponding ProxyEmitter (or create one if not existing).\n            if (isNode(emitter) || isWindow(emitter)) {\n                const proxyOptions = {\n                    capture: !!options.useCapture,\n                    passive: !!options.usePassive\n                };\n                const proxyEmitter = this._getProxyEmitter(emitter, proxyOptions) || new ProxyEmitter(emitter, proxyOptions);\n                this.listenTo(proxyEmitter, event, callback, options);\n            } else {\n                // Execute parent class method with Emitter (or ProxyEmitter) instance.\n                super.listenTo(emitter, event, callback, options);\n            }\n        }\n        stopListening(emitter, event, callback) {\n            // Check if the emitter is an instance of DOM Node. If so, forward the call to the corresponding ProxyEmitters.\n            if (isNode(emitter) || isWindow(emitter)) {\n                const proxyEmitters = this._getAllProxyEmitters(emitter);\n                for (const proxy of proxyEmitters){\n                    this.stopListening(proxy, event, callback);\n                }\n            } else {\n                // Execute parent class method with Emitter (or ProxyEmitter) instance.\n                super.stopListening(emitter, event, callback);\n            }\n        }\n        /**\n\t\t * Retrieves ProxyEmitter instance for given DOM Node residing in this Host and given options.\n\t\t *\n\t\t * @param node DOM Node of the ProxyEmitter.\n\t\t * @param options Additional options.\n\t\t * @param options.useCapture Indicates that events of this type will be dispatched to the registered\n\t\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t\t * @param options.usePassive Indicates that the function specified by listener will never call preventDefault()\n\t\t * and prevents blocking browser's main thread by this event handler.\n\t\t * @returns ProxyEmitter instance bound to the DOM Node.\n\t\t */ _getProxyEmitter(node, options) {\n            return _getEmitterListenedTo(this, getProxyEmitterId(node, options));\n        }\n        /**\n\t\t * Retrieves all the ProxyEmitter instances for given DOM Node residing in this Host.\n\t\t *\n\t\t * @param node DOM Node of the ProxyEmitter.\n\t\t */ _getAllProxyEmitters(node) {\n            return [\n                {\n                    capture: false,\n                    passive: false\n                },\n                {\n                    capture: false,\n                    passive: true\n                },\n                {\n                    capture: true,\n                    passive: false\n                },\n                {\n                    capture: true,\n                    passive: true\n                }\n            ].map((options)=>this._getProxyEmitter(node, options)).filter((proxy)=>!!proxy);\n        }\n    }\n    return Mixin;\n}\n// Backward compatibility with `mix`\n[\n    '_getProxyEmitter',\n    '_getAllProxyEmitters',\n    'on',\n    'once',\n    'off',\n    'listenTo',\n    'stopListening',\n    'fire',\n    'delegate',\n    'stopDelegating',\n    '_addEventListener',\n    '_removeEventListener'\n].forEach((key)=>{\n    DomEmitterMixin[key] = defaultEmitterClass.prototype[key];\n});\n/**\n * Creates a ProxyEmitter instance. Such an instance is a bridge between a DOM Node firing events\n * and any Host listening to them. It is backwards compatible with {@link module:utils/emittermixin~Emitter#on}.\n * There is a separate instance for each combination of modes (useCapture & usePassive). The mode is concatenated with\n * UID stored in HTMLElement to give each instance unique identifier.\n *\n *                                  listenTo( click, ... )\n *                    +-----------------------------------------+\n *                    |              stopListening( ... )       |\n *     +----------------------------+                           |             addEventListener( click, ... )\n *     | Host                       |                           |   +---------------------------------------------+\n *     +----------------------------+                           |   |       removeEventListener( click, ... )     |\n *     | _listeningTo: {            |                +----------v-------------+                                   |\n *     |   UID+mode: {              |                | ProxyEmitter           |                                   |\n *     |     emitter: ProxyEmitter, |                +------------------------+                      +------------v----------+\n *     |     callbacks: {           |                | events: {              |                      | Node (HTMLElement)    |\n *     |       click: [ callbacks ] |                |   click: [ callbacks ] |                      +-----------------------+\n *     |     }                      |                | },                     |                      | data-ck-expando: UID  |\n *     |   }                        |                | _domNode: Node,        |                      +-----------------------+\n *     | }                          |                | _domListeners: {},     |                                   |\n *     | +------------------------+ |                | _emitterId: UID+mode   |                                   |\n *     | | DomEmitterMixin        | |                +--------------^---------+                                   |\n *     | +------------------------+ |                           |   |                                             |\n *     +--------------^-------------+                           |   +---------------------------------------------+\n *                    |                                         |                  click (DOM Event)\n *                    +-----------------------------------------+\n *                                fire( click, DOM Event )\n */ class ProxyEmitter extends /* #__PURE__ */ EmitterMixin() {\n    _domNode;\n    _options;\n    /**\n\t * @param node DOM Node that fires events.\n\t * @param options Additional options.\n\t * @param options.useCapture Indicates that events of this type will be dispatched to the registered\n\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t * @param options.usePassive Indicates that the function specified by listener will never call preventDefault()\n\t * and prevents blocking browser's main thread by this event handler.\n\t */ constructor(node, options){\n        super();\n        // Set emitter ID to match DOM Node \"expando\" property.\n        _setEmitterId(this, getProxyEmitterId(node, options));\n        // Remember the DOM Node this ProxyEmitter is bound to.\n        this._domNode = node;\n        // And given options.\n        this._options = options;\n    }\n    /**\n\t * Collection of native DOM listeners.\n\t */ _domListeners;\n    /**\n\t * Registers a callback function to be executed when an event is fired.\n\t *\n\t * It attaches a native DOM listener to the DOM Node. When fired,\n\t * a corresponding Emitter event will also fire with DOM Event object as an argument.\n\t *\n\t * **Note**: This is automatically called by the\n\t * {@link module:utils/emittermixin~Emitter#listenTo `Emitter#listenTo()`}.\n\t *\n\t * @param event The name of the event.\n\t */ attach(event) {\n        // If the DOM Listener for given event already exist it is pointless\n        // to attach another one.\n        if (this._domListeners && this._domListeners[event]) {\n            return;\n        }\n        const domListener = this._createDomListener(event);\n        // Attach the native DOM listener to DOM Node.\n        this._domNode.addEventListener(event, domListener, this._options);\n        if (!this._domListeners) {\n            this._domListeners = {};\n        }\n        // Store the native DOM listener in this ProxyEmitter. It will be helpful\n        // when stopping listening to the event.\n        this._domListeners[event] = domListener;\n    }\n    /**\n\t * Stops executing the callback on the given event.\n\t *\n\t * **Note**: This is automatically called by the\n\t * {@link module:utils/emittermixin~Emitter#stopListening `Emitter#stopListening()`}.\n\t *\n\t * @param event The name of the event.\n\t */ detach(event) {\n        let events;\n        // Remove native DOM listeners which are orphans. If no callbacks\n        // are awaiting given event, detach native DOM listener from DOM Node.\n        // See: {@link attach}.\n        if (this._domListeners[event] && (!(events = this._events[event]) || !events.callbacks.length)) {\n            this._domListeners[event].removeListener();\n        }\n    }\n    /**\n\t * Adds callback to emitter for given event.\n\t *\n\t * @internal\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t */ _addEventListener(event, callback, options) {\n        this.attach(event);\n        EmitterMixin().prototype._addEventListener.call(this, event, callback, options);\n    }\n    /**\n\t * Removes callback from emitter for given event.\n\t *\n\t * @internal\n\t * @param event The name of the event.\n\t * @param callback The function to stop being called.\n\t */ _removeEventListener(event, callback) {\n        EmitterMixin().prototype._removeEventListener.call(this, event, callback);\n        this.detach(event);\n    }\n    /**\n\t * Creates a native DOM listener callback. When the native DOM event\n\t * is fired it will fire corresponding event on this ProxyEmitter.\n\t * Note: A native DOM Event is passed as an argument.\n\t *\n\t * @param event The name of the event.\n\t * @returns The DOM listener callback.\n\t */ _createDomListener(event) {\n        const domListener = (domEvt)=>{\n            this.fire(event, domEvt);\n        };\n        // Supply the DOM listener callback with a function that will help\n        // detach it from the DOM Node, when it is no longer necessary.\n        // See: {@link detach}.\n        domListener.removeListener = ()=>{\n            this._domNode.removeEventListener(event, domListener, this._options);\n            delete this._domListeners[event];\n        };\n        return domListener;\n    }\n}\n/**\n * Gets an unique DOM Node identifier. The identifier will be set if not defined.\n *\n * @returns UID for given DOM Node.\n */ function getNodeUID(node) {\n    return node['data-ck-expando'] || (node['data-ck-expando'] = uid());\n}\n/**\n * Gets id of the ProxyEmitter for the given node.\n */ function getProxyEmitterId(node, options) {\n    let id = getNodeUID(node);\n    for (const option of Object.keys(options).sort()){\n        if (options[option]) {\n            id += '-' + option;\n        }\n    }\n    return id;\n}\n\n/**\n * Returns the closest scrollable ancestor of a DOM element.\n *\n * @param domElement DOM element.\n * @returns First ancestor of `domElement` that is scrollable or null if such ancestor doesn't exist.\n */ function findClosestScrollableAncestor(domElement) {\n    let element = domElement.parentElement;\n    if (!element) {\n        return null;\n    }\n    while(element.tagName != 'BODY'){\n        const overflow = element.style.overflowY || global.window.getComputedStyle(element).overflowY;\n        if (overflow === 'auto' || overflow === 'scroll') {\n            break;\n        }\n        element = element.parentElement;\n        if (!element) {\n            return null;\n        }\n    }\n    return element;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /* globals Node */ /**\n * @module utils/dom/getancestors\n */ /**\n * Returns all ancestors of given DOM node, starting from the top-most (root). Includes the given node itself. If the\n * node is a part of `DocumentFragment` that `DocumentFragment` will be returned. In contrary, if the node is\n * appended to a `Document`, that `Document` will not be returned (algorithms operating on DOM tree care for `Document#documentElement`\n * at most, which will be returned).\n *\n * @param node DOM node.\n * @returns Array of given `node` parents.\n */ function getAncestors(node) {\n    const nodes = [];\n    let currentNode = node;\n    // We are interested in `Node`s `DocumentFragment`s only.\n    while(currentNode && currentNode.nodeType != Node.DOCUMENT_NODE){\n        nodes.unshift(currentNode);\n        currentNode = currentNode.parentNode;\n    }\n    return nodes;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /* globals HTMLTextAreaElement */ /**\n * @module utils/dom/getdatafromelement\n */ /**\n * Gets data from a given source element.\n *\n * @param el The element from which the data will be retrieved.\n * @returns The data string.\n */ function getDataFromElement(el) {\n    if (el instanceof HTMLTextAreaElement) {\n        return el.value;\n    }\n    return el.innerHTML;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/getborderwidths\n */ /**\n * Returns an object containing CSS border widths of a specified HTML element.\n *\n * @param element An element which has CSS borders.\n * @returns An object containing `top`, `left`, `right` and `bottom` properties\n * with numerical values of the `border-[top,left,right,bottom]-width` CSS styles.\n */ function getBorderWidths(element) {\n    // Call getComputedStyle on the window the element document belongs to.\n    const style = element.ownerDocument.defaultView.getComputedStyle(element);\n    return {\n        top: parseInt(style.borderTopWidth, 10),\n        right: parseInt(style.borderRightWidth, 10),\n        bottom: parseInt(style.borderBottomWidth, 10),\n        left: parseInt(style.borderLeftWidth, 10)\n    };\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/getrangefrommouseevent\n */ /**\n * Returns a DOM range from a given point specified by a mouse event.\n *\n * @param domEvent The mouse event.\n * @returns The DOM range.\n */ function getRangeFromMouseEvent(domEvent) {\n    if (!domEvent.target) {\n        return null;\n    }\n    const domDoc = domEvent.target.ownerDocument;\n    const x = domEvent.clientX;\n    const y = domEvent.clientY;\n    let domRange = null;\n    // Webkit & Blink.\n    if (domDoc.caretRangeFromPoint && domDoc.caretRangeFromPoint(x, y)) {\n        domRange = domDoc.caretRangeFromPoint(x, y);\n    } else if (domEvent.rangeParent) {\n        domRange = domDoc.createRange();\n        domRange.setStart(domEvent.rangeParent, domEvent.rangeOffset);\n        domRange.collapse(true);\n    }\n    return domRange;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/istext\n */ /**\n * Checks if the object is a native DOM Text node.\n */ function isText(obj) {\n    return Object.prototype.toString.call(obj) == '[object Text]';\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/isrange\n */ /**\n * Checks if the object is a native DOM Range.\n */ function isRange(obj) {\n    return Object.prototype.toString.apply(obj) == '[object Range]';\n}\n\n/**\n * For a given element, returns the nearest ancestor element which CSS position is not \"static\".\n *\n * @param element The native DOM element to be checked.\n */ function getPositionedAncestor(element) {\n    if (!element || !element.parentNode) {\n        return null;\n    }\n    if (element.offsetParent === global.document.body) {\n        return null;\n    }\n    return element.offsetParent;\n}\n\nconst rectProperties = [\n    'top',\n    'right',\n    'bottom',\n    'left',\n    'width',\n    'height'\n];\n/**\n * A helper class representing a `ClientRect` object, e.g. value returned by\n * the native `object.getBoundingClientRect()` method. Provides a set of methods\n * to manipulate the rect and compare it against other rect instances.\n */ class Rect {\n    /**\n\t * The \"top\" value of the rect.\n\t *\n\t * @readonly\n\t */ top;\n    /**\n\t * The \"right\" value of the rect.\n\t *\n\t * @readonly\n\t */ right;\n    /**\n\t * The \"bottom\" value of the rect.\n\t *\n\t * @readonly\n\t */ bottom;\n    /**\n\t * The \"left\" value of the rect.\n\t *\n\t * @readonly\n\t */ left;\n    /**\n\t * The \"width\" value of the rect.\n\t *\n\t * @readonly\n\t */ width;\n    /**\n\t * The \"height\" value of the rect.\n\t *\n\t * @readonly\n\t */ height;\n    /**\n\t * The object this rect is for.\n\t *\n\t * @readonly\n\t */ _source;\n    /**\n\t * Creates an instance of rect.\n\t *\n\t * ```ts\n\t * // Rect of an HTMLElement.\n\t * const rectA = new Rect( document.body );\n\t *\n\t * // Rect of a DOM Range.\n\t * const rectB = new Rect( document.getSelection().getRangeAt( 0 ) );\n\t *\n\t * // Rect of a window (web browser viewport).\n\t * const rectC = new Rect( window );\n\t *\n\t * // Rect out of an object.\n\t * const rectD = new Rect( { top: 0, right: 10, bottom: 10, left: 0, width: 10, height: 10 } );\n\t *\n\t * // Rect out of another Rect instance.\n\t * const rectE = new Rect( rectD );\n\t *\n\t * // Rect out of a ClientRect.\n\t * const rectF = new Rect( document.body.getClientRects().item( 0 ) );\n\t * ```\n\t *\n\t * **Note**: By default a rect of an HTML element includes its CSS borders and scrollbars (if any)\n\t * ant the rect of a `window` includes scrollbars too. Use {@link #excludeScrollbarsAndBorders}\n\t * to get the inner part of the rect.\n\t *\n\t * @param source A source object to create the rect.\n\t */ constructor(source){\n        const isSourceRange = isRange(source);\n        Object.defineProperty(this, '_source', {\n            // If the source is a Rect instance, copy it's #_source.\n            value: source._source || source,\n            writable: true,\n            enumerable: false\n        });\n        if (isDomElement(source) || isSourceRange) {\n            // The `Rect` class depends on `getBoundingClientRect` and `getClientRects` DOM methods. If the source\n            // of a rect in an HTML element or a DOM range but it does not belong to any rendered DOM tree, these methods\n            // will fail to obtain the geometry and the rect instance makes little sense to the features using it.\n            // To get rid of this warning make sure the source passed to the constructor is a descendant of `window.document.body`.\n            // @if CK_DEBUG // const sourceNode = isSourceRange ? source.startContainer : source;\n            // @if CK_DEBUG // if ( !sourceNode.ownerDocument || !sourceNode.ownerDocument.body.contains( sourceNode ) ) {\n            // @if CK_DEBUG // \tconsole.warn(\n            // @if CK_DEBUG // \t\t'rect-source-not-in-dom: The source of this rect does not belong to any rendered DOM tree.',\n            // @if CK_DEBUG // \t\t{ source } );\n            // @if CK_DEBUG // }\n            if (isSourceRange) {\n                const rangeRects = Rect.getDomRangeRects(source);\n                copyRectProperties(this, Rect.getBoundingRect(rangeRects));\n            } else {\n                copyRectProperties(this, source.getBoundingClientRect());\n            }\n        } else if (isWindow(source)) {\n            const { innerWidth, innerHeight } = source;\n            copyRectProperties(this, {\n                top: 0,\n                right: innerWidth,\n                bottom: innerHeight,\n                left: 0,\n                width: innerWidth,\n                height: innerHeight\n            });\n        } else {\n            copyRectProperties(this, source);\n        }\n    }\n    /**\n\t * Returns a clone of the rect.\n\t *\n\t * @returns A cloned rect.\n\t */ clone() {\n        return new Rect(this);\n    }\n    /**\n\t * Moves the rect so that its upper–left corner lands in desired `[ x, y ]` location.\n\t *\n\t * @param x Desired horizontal location.\n\t * @param y Desired vertical location.\n\t * @returns A rect which has been moved.\n\t */ moveTo(x, y) {\n        this.top = y;\n        this.right = x + this.width;\n        this.bottom = y + this.height;\n        this.left = x;\n        return this;\n    }\n    /**\n\t * Moves the rect in–place by a dedicated offset.\n\t *\n\t * @param x A horizontal offset.\n\t * @param y A vertical offset\n\t * @returns A rect which has been moved.\n\t */ moveBy(x, y) {\n        this.top += y;\n        this.right += x;\n        this.left += x;\n        this.bottom += y;\n        return this;\n    }\n    /**\n\t * Returns a new rect a a result of intersection with another rect.\n\t */ getIntersection(anotherRect) {\n        const rect = {\n            top: Math.max(this.top, anotherRect.top),\n            right: Math.min(this.right, anotherRect.right),\n            bottom: Math.min(this.bottom, anotherRect.bottom),\n            left: Math.max(this.left, anotherRect.left),\n            width: 0,\n            height: 0\n        };\n        rect.width = rect.right - rect.left;\n        rect.height = rect.bottom - rect.top;\n        if (rect.width < 0 || rect.height < 0) {\n            return null;\n        } else {\n            const newRect = new Rect(rect);\n            newRect._source = this._source;\n            return newRect;\n        }\n    }\n    /**\n\t * Returns the area of intersection with another rect.\n\t *\n\t * @returns Area of intersection.\n\t */ getIntersectionArea(anotherRect) {\n        const rect = this.getIntersection(anotherRect);\n        if (rect) {\n            return rect.getArea();\n        } else {\n            return 0;\n        }\n    }\n    /**\n\t * Returns the area of the rect.\n\t */ getArea() {\n        return this.width * this.height;\n    }\n    /**\n\t * Returns a new rect, a part of the original rect, which is actually visible to the user and is relative to the,`body`,\n\t * e.g. an original rect cropped by parent element rects which have `overflow` set in CSS\n\t * other than `\"visible\"`.\n\t *\n\t * If there's no such visible rect, which is when the rect is limited by one or many of\n\t * the ancestors, `null` is returned.\n\t *\n\t * **Note**: This method does not consider the boundaries of the viewport (window).\n\t * To get a rect cropped by all ancestors and the viewport, use an intersection such as:\n\t *\n\t * ```ts\n\t * const visibleInViewportRect = new Rect( window ).getIntersection( new Rect( source ).getVisible() );\n\t * ```\n\t *\n\t * @returns A visible rect instance or `null`, if there's none.\n\t */ getVisible() {\n        const source = this._source;\n        let visibleRect = this.clone();\n        // There's no ancestor to crop <body> with the overflow.\n        if (isBody(source)) {\n            return visibleRect;\n        }\n        let child = source;\n        let parent = source.parentNode || source.commonAncestorContainer;\n        let absolutelyPositionedChildElement;\n        // Check the ancestors all the way up to the <body>.\n        while(parent && !isBody(parent)){\n            const isParentOverflowVisible = getElementOverflow(parent) === 'visible';\n            if (child instanceof HTMLElement && getElementPosition(child) === 'absolute') {\n                absolutelyPositionedChildElement = child;\n            }\n            const parentElementPosition = getElementPosition(parent);\n            // The child will be cropped only if it has `position: absolute` and the parent has `position: relative` + some overflow.\n            // Otherwise there's no chance of visual clipping and the parent can be skipped\n            // https://github.com/ckeditor/ckeditor5/issues/14107.\n            //\n            // condition: isParentOverflowVisible\n            // \t\t+---------------------------+\n            //\t\t| #parent\t\t\t\t\t|\n            //\t\t| (overflow: visible)\t\t|\n            //\t\t|\t\t\t\t+-----------+---------------+\n            //\t\t|\t\t\t\t| child\t\t\t\t\t\t|\n            //\t\t|\t\t\t\t+-----------+---------------+\n            //\t\t+---------------------------+\n            //\n            // condition: absolutelyPositionedChildElement && parentElementPosition === 'relative' && isParentOverflowVisible\n            // \t\t+---------------------------+\n            //\t\t| parent\t\t\t\t\t|\n            //\t\t| (position: relative;)\t\t|\n            //\t\t| (overflow: visible;)\t\t|\n            //\t\t|\t\t\t\t+-----------+---------------+\n            //\t\t|\t\t\t\t| child  \t\t\t\t\t|\n            //\t\t|\t\t\t\t| (position: absolute;)\t\t|\n            //\t\t|\t\t\t\t+-----------+---------------+\n            //\t\t+---------------------------+\n            //\n            // condition: absolutelyPositionedChildElement && parentElementPosition !== 'relative'\n            // \t\t+---------------------------+\n            //\t\t| parent\t\t\t\t\t|\n            //\t\t| (position: static;)\t\t|\n            //\t\t|\t\t\t\t+-----------+---------------+\n            //\t\t|\t\t\t\t| child  \t\t\t\t\t|\n            //\t\t|\t\t\t\t| (position: absolute;)\t\t|\n            //\t\t|\t\t\t\t+-----------+---------------+\n            //\t\t+---------------------------+\n            if (isParentOverflowVisible || absolutelyPositionedChildElement && (parentElementPosition === 'relative' && isParentOverflowVisible || parentElementPosition !== 'relative')) {\n                child = parent;\n                parent = parent.parentNode;\n                continue;\n            }\n            const parentRect = new Rect(parent);\n            const intersectionRect = visibleRect.getIntersection(parentRect);\n            if (intersectionRect) {\n                if (intersectionRect.getArea() < visibleRect.getArea()) {\n                    // Reduce the visible rect to the intersection.\n                    visibleRect = intersectionRect;\n                }\n            } else {\n                // There's no intersection, the rect is completely invisible.\n                return null;\n            }\n            child = parent;\n            parent = parent.parentNode;\n        }\n        return visibleRect;\n    }\n    /**\n\t * Checks if all property values ({@link #top}, {@link #left}, {@link #right},\n\t * {@link #bottom}, {@link #width} and {@link #height}) are the equal in both rect\n\t * instances.\n\t *\n\t * @param anotherRect A rect instance to compare with.\n\t * @returns `true` when Rects are equal. `false` otherwise.\n\t */ isEqual(anotherRect) {\n        for (const prop of rectProperties){\n            if (this[prop] !== anotherRect[prop]) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Checks whether a rect fully contains another rect instance.\n\t *\n\t * @param anotherRect\n\t * @returns `true` if contains, `false` otherwise.\n\t */ contains(anotherRect) {\n        const intersectRect = this.getIntersection(anotherRect);\n        return !!(intersectRect && intersectRect.isEqual(anotherRect));\n    }\n    /**\n\t * Recalculates screen coordinates to coordinates relative to the positioned ancestor offset.\n\t */ toAbsoluteRect() {\n        const { scrollX, scrollY } = global.window;\n        const absoluteRect = this.clone().moveBy(scrollX, scrollY);\n        if (isDomElement(absoluteRect._source)) {\n            const positionedAncestor = getPositionedAncestor(absoluteRect._source);\n            if (positionedAncestor) {\n                shiftRectToCompensatePositionedAncestor(absoluteRect, positionedAncestor);\n            }\n        }\n        return absoluteRect;\n    }\n    /**\n\t * Excludes scrollbars and CSS borders from the rect.\n\t *\n\t * * Borders are removed when {@link #_source} is an HTML element.\n\t * * Scrollbars are excluded from HTML elements and the `window`.\n\t *\n\t * @returns A rect which has been updated.\n\t */ excludeScrollbarsAndBorders() {\n        const source = this._source;\n        let scrollBarWidth, scrollBarHeight, direction;\n        if (isWindow(source)) {\n            scrollBarWidth = source.innerWidth - source.document.documentElement.clientWidth;\n            scrollBarHeight = source.innerHeight - source.document.documentElement.clientHeight;\n            direction = source.getComputedStyle(source.document.documentElement).direction;\n        } else {\n            const borderWidths = getBorderWidths(source);\n            scrollBarWidth = source.offsetWidth - source.clientWidth - borderWidths.left - borderWidths.right;\n            scrollBarHeight = source.offsetHeight - source.clientHeight - borderWidths.top - borderWidths.bottom;\n            direction = source.ownerDocument.defaultView.getComputedStyle(source).direction;\n            this.left += borderWidths.left;\n            this.top += borderWidths.top;\n            this.right -= borderWidths.right;\n            this.bottom -= borderWidths.bottom;\n            this.width = this.right - this.left;\n            this.height = this.bottom - this.top;\n        }\n        this.width -= scrollBarWidth;\n        if (direction === 'ltr') {\n            this.right -= scrollBarWidth;\n        } else {\n            this.left += scrollBarWidth;\n        }\n        this.height -= scrollBarHeight;\n        this.bottom -= scrollBarHeight;\n        return this;\n    }\n    /**\n\t * Returns an array of rects of the given native DOM Range.\n\t *\n\t * @param range A native DOM range.\n\t * @returns DOM Range rects.\n\t */ static getDomRangeRects(range) {\n        const rects = [];\n        // Safari does not iterate over ClientRectList using for...of loop.\n        const clientRects = Array.from(range.getClientRects());\n        if (clientRects.length) {\n            for (const rect of clientRects){\n                rects.push(new Rect(rect));\n            }\n        } else {\n            let startContainer = range.startContainer;\n            if (isText(startContainer)) {\n                startContainer = startContainer.parentNode;\n            }\n            const rect = new Rect(startContainer.getBoundingClientRect());\n            rect.right = rect.left;\n            rect.width = 0;\n            rects.push(rect);\n        }\n        return rects;\n    }\n    /**\n\t * Returns a bounding rectangle that contains all the given `rects`.\n\t *\n\t * @param rects A list of rectangles that should be contained in the result rectangle.\n\t * @returns Bounding rectangle or `null` if no `rects` were given.\n\t */ static getBoundingRect(rects) {\n        const boundingRectData = {\n            left: Number.POSITIVE_INFINITY,\n            top: Number.POSITIVE_INFINITY,\n            right: Number.NEGATIVE_INFINITY,\n            bottom: Number.NEGATIVE_INFINITY,\n            width: 0,\n            height: 0\n        };\n        let rectangleCount = 0;\n        for (const rect of rects){\n            rectangleCount++;\n            boundingRectData.left = Math.min(boundingRectData.left, rect.left);\n            boundingRectData.top = Math.min(boundingRectData.top, rect.top);\n            boundingRectData.right = Math.max(boundingRectData.right, rect.right);\n            boundingRectData.bottom = Math.max(boundingRectData.bottom, rect.bottom);\n        }\n        if (rectangleCount == 0) {\n            return null;\n        }\n        boundingRectData.width = boundingRectData.right - boundingRectData.left;\n        boundingRectData.height = boundingRectData.bottom - boundingRectData.top;\n        return new Rect(boundingRectData);\n    }\n}\n/**\n * Acquires all the rect properties from the passed source.\n */ function copyRectProperties(rect, source) {\n    for (const p of rectProperties){\n        rect[p] = source[p];\n    }\n}\n/**\n * Checks if provided object is a <body> HTML element.\n */ function isBody(value) {\n    if (!isDomElement(value)) {\n        return false;\n    }\n    return value === value.ownerDocument.body;\n}\n/**\n * Checks if provided object \"looks like\" a DOM Element and has API required by `Rect` class.\n */ function isDomElement(value) {\n    // Note: earlier we used `isElement()` from lodash library, however that function is less performant because\n    // it makes complicated checks to make sure that given value is a DOM element.\n    return value !== null && typeof value === 'object' && value.nodeType === 1 && typeof value.getBoundingClientRect === 'function';\n}\n/**\n * Returns the value of the `position` style of an `HTMLElement`.\n */ function getElementPosition(element) {\n    return element instanceof HTMLElement ? element.ownerDocument.defaultView.getComputedStyle(element).position : 'static';\n}\n/**\n * Returns the value of the `overflow` style of an `HTMLElement` or a `Range`.\n */ function getElementOverflow(element) {\n    return element instanceof HTMLElement ? element.ownerDocument.defaultView.getComputedStyle(element).overflow : 'visible';\n}\n/**\n * For a given absolute Rect coordinates object and a positioned element ancestor, it updates its\n * coordinates that make up for the position and the scroll of the ancestor.\n *\n * This is necessary because while Rects (and DOMRects) are relative to the browser's viewport, their coordinates\n * are used in real–life to position elements with `position: absolute`, which are scoped by any positioned\n * (and scrollable) ancestors.\n */ function shiftRectToCompensatePositionedAncestor(rect, positionedElementAncestor) {\n    const ancestorPosition = new Rect(positionedElementAncestor);\n    const ancestorBorderWidths = getBorderWidths(positionedElementAncestor);\n    let moveX = 0;\n    let moveY = 0;\n    // (https://github.com/ckeditor/ckeditor5-ui-default/issues/126)\n    // If there's some positioned ancestor of the panel, then its `Rect` must be taken into\n    // consideration. `Rect` is always relative to the viewport while `position: absolute` works\n    // with respect to that positioned ancestor.\n    moveX -= ancestorPosition.left;\n    moveY -= ancestorPosition.top;\n    // (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n    // If there's some positioned ancestor of the panel, not only its position must be taken into\n    // consideration (see above) but also its internal scrolls. Scroll have an impact here because `Rect`\n    // is relative to the viewport (it doesn't care about scrolling), while `position: absolute`\n    // must compensate that scrolling.\n    moveX += positionedElementAncestor.scrollLeft;\n    moveY += positionedElementAncestor.scrollTop;\n    // (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n    // If there's some positioned ancestor of the panel, then its `Rect` includes its CSS `borderWidth`\n    // while `position: absolute` positioning does not consider it.\n    // E.g. `{ position: absolute, top: 0, left: 0 }` means upper left corner of the element,\n    // not upper-left corner of its border.\n    moveX -= ancestorBorderWidths.left;\n    moveY -= ancestorBorderWidths.top;\n    rect.moveBy(moveX, moveY);\n}\n\n/**\n * A helper class which instances allow performing custom actions when native DOM elements are resized.\n *\n * ```ts\n * const editableElement = editor.editing.view.getDomRoot();\n *\n * const observer = new ResizeObserver( editableElement, entry => {\n * \tconsole.log( 'The editable element has been resized in DOM.' );\n * \tconsole.log( entry.target ); // -> editableElement\n * \tconsole.log( entry.contentRect.width ); // -> e.g. '423px'\n * } );\n * ```\n *\n * It uses the [native DOM resize observer](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)\n * under the hood.\n */ class ResizeObserver {\n    /**\n\t * The element observed by this observer.\n\t */ _element;\n    /**\n\t * The callback executed each time {@link #_element} is resized.\n\t */ _callback;\n    /**\n\t * The single native observer instance shared across all {@link module:utils/dom/resizeobserver~ResizeObserver} instances.\n\t */ static _observerInstance = null;\n    /**\n\t * A mapping of native DOM elements and their callbacks shared across all\n\t * {@link module:utils/dom/resizeobserver~ResizeObserver} instances.\n\t */ static _elementCallbacks = null;\n    /**\n\t * Creates an instance of the `ResizeObserver` class.\n\t *\n\t * @param element A DOM element that is to be observed for resizing. Note that\n\t * the element must be visible (i.e. not detached from DOM) for the observer to work.\n\t * @param callback A function called when the observed element was resized. It passes\n\t * the [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry)\n\t * object with information about the resize event.\n\t */ constructor(element, callback){\n        // **Note**: For the maximum performance, this class ensures only a single instance of the native\n        // observer is used no matter how many instances of this class were created.\n        if (!ResizeObserver._observerInstance) {\n            ResizeObserver._createObserver();\n        }\n        this._element = element;\n        this._callback = callback;\n        ResizeObserver._addElementCallback(element, callback);\n        ResizeObserver._observerInstance.observe(element);\n    }\n    /**\n\t * The element observed by this observer.\n\t */ get element() {\n        return this._element;\n    }\n    /**\n\t * Destroys the observer which disables the `callback` passed to the {@link #constructor}.\n\t */ destroy() {\n        ResizeObserver._deleteElementCallback(this._element, this._callback);\n    }\n    /**\n\t * Registers a new resize callback for the DOM element.\n\t */ static _addElementCallback(element, callback) {\n        if (!ResizeObserver._elementCallbacks) {\n            ResizeObserver._elementCallbacks = new Map();\n        }\n        let callbacks = ResizeObserver._elementCallbacks.get(element);\n        if (!callbacks) {\n            callbacks = new Set();\n            ResizeObserver._elementCallbacks.set(element, callbacks);\n        }\n        callbacks.add(callback);\n    }\n    /**\n\t * Removes a resize callback from the DOM element. If no callbacks are left\n\t * for the element, it removes the element from the native observer.\n\t */ static _deleteElementCallback(element, callback) {\n        const callbacks = ResizeObserver._getElementCallbacks(element);\n        // Remove the element callback. Check if exist first in case someone\n        // called destroy() twice.\n        if (callbacks) {\n            callbacks.delete(callback);\n            // If no callbacks left for the element, also remove the element.\n            if (!callbacks.size) {\n                ResizeObserver._elementCallbacks.delete(element);\n                ResizeObserver._observerInstance.unobserve(element);\n            }\n        }\n        if (ResizeObserver._elementCallbacks && !ResizeObserver._elementCallbacks.size) {\n            ResizeObserver._observerInstance = null;\n            ResizeObserver._elementCallbacks = null;\n        }\n    }\n    /**\n\t * Returns are registered resize callbacks for the DOM element.\n\t */ static _getElementCallbacks(element) {\n        if (!ResizeObserver._elementCallbacks) {\n            return null;\n        }\n        return ResizeObserver._elementCallbacks.get(element);\n    }\n    /**\n\t * Creates the single native observer shared across all `ResizeObserver` instances.\n\t */ static _createObserver() {\n        ResizeObserver._observerInstance = new global.window.ResizeObserver((entries)=>{\n            for (const entry of entries){\n                const callbacks = ResizeObserver._getElementCallbacks(entry.target);\n                if (callbacks) {\n                    for (const callback of callbacks){\n                        callback(entry);\n                    }\n                }\n            }\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/setdatainelement\n */ /* globals HTMLTextAreaElement */ /**\n * Sets data in a given element.\n *\n * @param el The element in which the data will be set.\n * @param data The data string.\n */ function setDataInElement(el, data) {\n    if (el instanceof HTMLTextAreaElement) {\n        el.value = data;\n    }\n    el.innerHTML = data;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/tounit\n */ /**\n * Returns a helper function, which adds a desired trailing\n * `unit` to the passed value.\n *\n * @param unit An unit like \"px\" or \"em\".\n */ function toUnit(unit) {\n    return (value)=>value + unit;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/indexof\n */ /**\n * Returns index of the node in the parent element.\n *\n * @param node Node which index is tested.\n * @returns Index of the node in the parent element. Returns 0 if node has no parent.\n */ function indexOf(node) {\n    let index = 0;\n    while(node.previousSibling){\n        node = node.previousSibling;\n        index++;\n    }\n    return index;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/insertat\n */ /**\n * Inserts node to the parent at given index.\n *\n * @param parentElement Parent element.\n * @param index Insertions index.\n * @param nodeToInsert Node to insert.\n */ function insertAt(parentElement, index, nodeToInsert) {\n    parentElement.insertBefore(nodeToInsert, parentElement.childNodes[index] || null);\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /* globals Node */ /**\n * @module utils/dom/iscomment\n */ /**\n * Checks whether the object is a native DOM Comment node.\n */ function isComment(obj) {\n    return obj && obj.nodeType === Node.COMMENT_NODE;\n}\n\n/**\n * Checks if the given attribute name is valid in terms of HTML.\n *\n * @param name Attribute name.\n */ function isValidAttributeName(name) {\n    try {\n        global.document.createAttribute(name);\n    } catch (error) {\n        return false;\n    }\n    return true;\n}\n\n/**\n * Checks whether the element is visible to the user in DOM:\n *\n * * connected to the root of the document,\n * * has no `display: none`,\n * * has no ancestors with `display: none`.\n *\n * **Note**: This helper does not check whether the element is hidden by cropping, overflow, etc..\n * To check that, use {@link module:utils/dom/rect~Rect} instead.\n */ function isVisible(element) {\n    if (!element) {\n        return false;\n    }\n    if (isText(element)) {\n        return isVisible(element.parentElement);\n    }\n    if (element.getClientRects) {\n        return !!element.getClientRects().length;\n    }\n    return false;\n}\n\n// @if CK_DEBUG_POSITION // const {\n// @if CK_DEBUG_POSITION // \tdefault: RectDrawer,\n// @if CK_DEBUG_POSITION // \tdiagonalStylesBlack,\n// @if CK_DEBUG_POSITION // \tdiagonalStylesGreen,\n// @if CK_DEBUG_POSITION // \tdiagonalStylesRed\n// @if CK_DEBUG_POSITION // } = require( '@ckeditor/ckeditor5-utils/tests/_utils/rectdrawer' );\n// @if CK_DEBUG_POSITION // const TARGET_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px', outlineStyle: 'dashed', outlineColor: 'blue', outlineOffset: '2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const VISIBLE_TARGET_RECT_STYLE = {\n// @if CK_DEBUG_POSITION //\t\t...diagonalStylesBlack,\n// @if CK_DEBUG_POSITION //\t\topacity: '1',\n// @if CK_DEBUG_POSITION //\t\tbackgroundColor: '#00000033',\n// @if CK_DEBUG_POSITION //\t\toutlineWidth: '2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const VIEWPORT_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px',\n// @if CK_DEBUG_POSITION // \toutlineOffset: '-2px',\n// @if CK_DEBUG_POSITION // \toutlineStyle: 'solid',\n// @if CK_DEBUG_POSITION // \toutlineColor: 'red'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const VISIBLE_LIMITER_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \t...diagonalStylesGreen,\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px',\n// @if CK_DEBUG_POSITION // \toutlineOffset: '-2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const ELEMENT_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px', outlineColor: 'orange', outlineOffset: '-2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const CHOSEN_POSITION_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \topacity: .5, outlineColor: 'magenta', backgroundColor: 'magenta'\n// @if CK_DEBUG_POSITION // };\n/**\n * Calculates the `position: absolute` coordinates of a given element so it can be positioned with respect to the\n * target in the visually most efficient way, taking various restrictions like viewport or limiter geometry\n * into consideration.\n *\n * **Note**: If there are no position coordinates found that meet the requirements (arguments of this helper),\n * `null` is returned.\n *\n * ```ts\n * // The element which is to be positioned.\n * const element = document.body.querySelector( '#toolbar' );\n *\n * // A target to which the element is positioned relatively.\n * const target = document.body.querySelector( '#container' );\n *\n * // Finding the optimal coordinates for the positioning.\n * const { left, top, name } = getOptimalPosition( {\n * \telement: element,\n * \ttarget: target,\n *\n * \t// The algorithm will chose among these positions to meet the requirements such\n * \t// as \"limiter\" element or \"fitInViewport\", set below. The positions are considered\n * \t// in the order of the array.\n * \tpositions: [\n * \t\t//\n * \t \t//\t[ Target ]\n * \t\t//\t+-----------------+\n * \t\t//\t|     Element     |\n * \t\t//\t+-----------------+\n * \t\t//\n * \t\ttargetRect => ( {\n * \t\t\ttop: targetRect.bottom,\n * \t\t\tleft: targetRect.left,\n * \t\t\tname: 'mySouthEastPosition'\n * \t\t} ),\n *\n * \t\t//\n * \t\t//\t+-----------------+\n * \t\t//\t|     Element     |\n * \t\t//\t+-----------------+\n * \t\t//\t[ Target ]\n * \t\t//\n * \t\t( targetRect, elementRect ) => ( {\n * \t\t\ttop: targetRect.top - elementRect.height,\n * \t\t\tleft: targetRect.left,\n * \t\t\tname: 'myNorthEastPosition'\n * \t\t} )\n * \t],\n *\n * \t// Find a position such guarantees the element remains within visible boundaries of <body>.\n * \tlimiter: document.body,\n *\n * \t// Find a position such guarantees the element remains within visible boundaries of the browser viewport.\n * \tfitInViewport: true\n * } );\n *\n * // The best position which fits into document.body and the viewport. May be useful\n * // to set proper class on the `element`.\n * console.log( name ); // -> \"myNorthEastPosition\"\n *\n * // Using the absolute coordinates which has been found to position the element\n * // as in the diagram depicting the \"myNorthEastPosition\" position.\n * element.style.top = top;\n * element.style.left = left;\n * ```\n *\n * @param options The input data and configuration of the helper.\n */ function getOptimalPosition({ element, target, positions, limiter, fitInViewport, viewportOffsetConfig }) {\n    // If the {@link module:utils/dom/position~Options#target} is a function, use what it returns.\n    // https://github.com/ckeditor/ckeditor5-utils/issues/157\n    if (isFunction(target)) {\n        target = target();\n    }\n    // If the {@link module:utils/dom/position~Options#limiter} is a function, use what it returns.\n    // https://github.com/ckeditor/ckeditor5-ui/issues/260\n    if (isFunction(limiter)) {\n        limiter = limiter();\n    }\n    const positionedElementAncestor = getPositionedAncestor(element);\n    const constrainedViewportRect = getConstrainedViewportRect(viewportOffsetConfig);\n    const elementRect = new Rect(element);\n    const visibleTargetRect = getVisibleViewportIntersectionRect(target, constrainedViewportRect);\n    let bestPosition;\n    // @if CK_DEBUG_POSITION // const targetRect = new Rect( target );\n    // @if CK_DEBUG_POSITION // RectDrawer.clear();\n    // @if CK_DEBUG_POSITION // RectDrawer.draw( targetRect, TARGET_RECT_STYLE, 'Target' );\n    // @if CK_DEBUG_POSITION // if ( constrainedViewportRect ) {\n    // @if CK_DEBUG_POSITION //\t\tRectDrawer.draw( constrainedViewportRect, VIEWPORT_RECT_STYLE, 'Viewport' );\n    // @if CK_DEBUG_POSITION // }\n    // If the target got cropped by ancestors or went off the screen, positioning does not make any sense.\n    if (!visibleTargetRect || !constrainedViewportRect.getIntersection(visibleTargetRect)) {\n        return null;\n    }\n    // @if CK_DEBUG_POSITION //\tRectDrawer.draw( visibleTargetRect, VISIBLE_TARGET_RECT_STYLE, 'VisTgt' );\n    const positionOptions = {\n        targetRect: visibleTargetRect,\n        elementRect,\n        positionedElementAncestor,\n        viewportRect: constrainedViewportRect\n    };\n    // If there are no limits, just grab the very first position and be done with that drama.\n    if (!limiter && !fitInViewport) {\n        bestPosition = new PositionObject(positions[0], positionOptions);\n    } else {\n        if (limiter) {\n            const visibleLimiterRect = getVisibleViewportIntersectionRect(limiter, constrainedViewportRect);\n            if (visibleLimiterRect) {\n                positionOptions.limiterRect = visibleLimiterRect;\n            // @if CK_DEBUG_POSITION // RectDrawer.draw( visibleLimiterRect, VISIBLE_LIMITER_RECT_STYLE, 'VisLim' );\n            }\n        }\n        // If there's no best position found, i.e. when all intersections have no area because\n        // rects have no width or height, then just return `null`\n        bestPosition = getBestPosition(positions, positionOptions);\n    }\n    return bestPosition;\n}\n/**\n * Returns intersection of visible source `Rect` with Viewport `Rect`. In case when source `Rect` is not visible\n * or there is no intersection between source `Rect` and Viewport `Rect`, `null` will be returned.\n */ function getVisibleViewportIntersectionRect(source, viewportRect) {\n    const visibleSourceRect = new Rect(source).getVisible();\n    if (!visibleSourceRect) {\n        return null;\n    }\n    return visibleSourceRect.getIntersection(viewportRect);\n}\n/**\n * Returns a viewport `Rect` shrunk by the viewport offset config from all sides.\n */ function getConstrainedViewportRect(viewportOffsetConfig) {\n    viewportOffsetConfig = Object.assign({\n        top: 0,\n        bottom: 0,\n        left: 0,\n        right: 0\n    }, viewportOffsetConfig);\n    const viewportRect = new Rect(global.window);\n    viewportRect.top += viewportOffsetConfig.top;\n    viewportRect.height -= viewportOffsetConfig.top;\n    viewportRect.bottom -= viewportOffsetConfig.bottom;\n    viewportRect.height -= viewportOffsetConfig.bottom;\n    return viewportRect;\n}\n/**\n * For a given array of positioning functions, returns such that provides the best\n * fit of the `elementRect` into the `limiterRect` and `viewportRect`.\n */ function getBestPosition(positions, options) {\n    const { elementRect } = options;\n    // This is when element is fully visible.\n    const elementRectArea = elementRect.getArea();\n    const positionInstances = positions.map((positioningFunction)=>new PositionObject(positioningFunction, options))// Some positioning functions may return `null` if they don't want to participate.\n    .filter((position)=>!!position.name);\n    let maxFitFactor = 0;\n    let bestPosition = null;\n    for (const position of positionInstances){\n        const { limiterIntersectionArea, viewportIntersectionArea } = position;\n        // If a such position is found that element is fully contained by the limiter then, obviously,\n        // there will be no better one, so finishing.\n        if (limiterIntersectionArea === elementRectArea) {\n            // @if CK_DEBUG_POSITION //\tRectDrawer.draw( position._rect, CHOSEN_POSITION_RECT_STYLE, [\n            // @if CK_DEBUG_POSITION //\t\tposition.name,\n            // @if CK_DEBUG_POSITION //\t\t'100% fit',\n            // @if CK_DEBUG_POSITION //\t].join( '\\n' ) );\n            return position;\n        }\n        // To maximize both viewport and limiter intersection areas we use distance on _viewportIntersectionArea\n        // and _limiterIntersectionArea plane (without sqrt because we are looking for max value).\n        const fitFactor = viewportIntersectionArea ** 2 + limiterIntersectionArea ** 2;\n        // @if CK_DEBUG_POSITION //\tRectDrawer.draw( position._rect, { opacity: .4 }, [\n        // @if CK_DEBUG_POSITION //\t\tposition.name,\n        // @if CK_DEBUG_POSITION //\t\t'Vi=' +  Math.round( viewportIntersectionArea ),\n        // @if CK_DEBUG_POSITION //\t\t'Li=' + Math.round( limiterIntersectionArea )\n        // @if CK_DEBUG_POSITION //\t].join( '\\n' ) );\n        if (fitFactor > maxFitFactor) {\n            maxFitFactor = fitFactor;\n            bestPosition = position;\n        }\n    }\n    // @if CK_DEBUG_POSITION // if ( bestPosition ) {\n    // @if CK_DEBUG_POSITION // \tRectDrawer.draw( bestPosition._rect, CHOSEN_POSITION_RECT_STYLE );\n    // @if CK_DEBUG_POSITION // }\n    return bestPosition;\n}\n/**\n * A position class which instances are created and used by the {@link module:utils/dom/position~getOptimalPosition} helper.\n *\n * {@link module:utils/dom/position~Position#top} and {@link module:utils/dom/position~Position#left} properties of the position instance\n * translate directly to the `top` and `left` properties in CSS \"`position: absolute` coordinate system\". If set on the positioned element\n * in DOM, they will make it display it in the right place in the viewport.\n */ class PositionObject {\n    name;\n    config;\n    _positioningFunctionCoordinates;\n    _options;\n    _cachedRect;\n    _cachedAbsoluteRect;\n    /**\n\t * Creates an instance of the {@link module:utils/dom/position~PositionObject} class.\n\t *\n\t * @param positioningFunction function The function that defines the expected\n\t * coordinates the positioned element should move to.\n\t * @param options options object.\n\t * @param options.elementRect The positioned element rect.\n\t * @param options.targetRect The target element rect.\n\t * @param options.viewportRect The viewport rect.\n\t * @param options.limiterRect The limiter rect.\n\t * @param options.positionedElementAncestor Nearest element ancestor element which CSS position is not \"static\".\n\t */ constructor(positioningFunction, options){\n        const positioningFunctionOutput = positioningFunction(options.targetRect, options.elementRect, options.viewportRect, options.limiterRect);\n        // Nameless position for a function that didn't participate.\n        if (!positioningFunctionOutput) {\n            return;\n        }\n        const { left, top, name, config } = positioningFunctionOutput;\n        this.name = name;\n        this.config = config;\n        this._positioningFunctionCoordinates = {\n            left,\n            top\n        };\n        this._options = options;\n    }\n    /**\n\t * The left value in pixels in the CSS `position: absolute` coordinate system.\n\t * Set it on the positioned element in DOM to move it to the position.\n\t */ get left() {\n        return this._absoluteRect.left;\n    }\n    /**\n\t * The top value in pixels in the CSS `position: absolute` coordinate system.\n\t * Set it on the positioned element in DOM to move it to the position.\n\t */ get top() {\n        return this._absoluteRect.top;\n    }\n    /**\n\t * An intersection area between positioned element and limiter within viewport constraints.\n\t */ get limiterIntersectionArea() {\n        const limiterRect = this._options.limiterRect;\n        if (limiterRect) {\n            return limiterRect.getIntersectionArea(this._rect);\n        }\n        return 0;\n    }\n    /**\n\t * An intersection area between positioned element and viewport.\n\t */ get viewportIntersectionArea() {\n        const viewportRect = this._options.viewportRect;\n        return viewportRect.getIntersectionArea(this._rect);\n    }\n    /**\n\t * An already positioned element rect. A clone of the element rect passed to the constructor\n\t * but placed in the viewport according to the positioning function.\n\t */ get _rect() {\n        if (this._cachedRect) {\n            return this._cachedRect;\n        }\n        this._cachedRect = this._options.elementRect.clone().moveTo(this._positioningFunctionCoordinates.left, this._positioningFunctionCoordinates.top);\n        return this._cachedRect;\n    }\n    /**\n\t * An already absolutely positioned element rect. See ({@link #_rect}).\n\t */ get _absoluteRect() {\n        if (this._cachedAbsoluteRect) {\n            return this._cachedAbsoluteRect;\n        }\n        this._cachedAbsoluteRect = this._rect.toAbsoluteRect();\n        return this._cachedAbsoluteRect;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/dom/remove\n */ /**\n * Removes given node from parent.\n *\n * @param node Node to remove.\n */ function remove(node) {\n    const parent = node.parentNode;\n    if (parent) {\n        parent.removeChild(node);\n    }\n}\n\n/**\n * Makes any page `HTMLElement` or `Range` (`target`) visible inside the browser viewport.\n * This helper will scroll all `target` ancestors and the web browser viewport to reveal the target to\n * the user. If the `target` is already visible, nothing will happen.\n *\n * @param options Additional configuration of the scrolling behavior.\n * @param options.target A target, which supposed to become visible to the user.\n * @param options.viewportOffset An offset from the edge of the viewport (in pixels)\n * the `target` will be moved by if the viewport is scrolled. It enhances the user experience\n * by keeping the `target` some distance from the edge of the viewport and thus making it easier to\n * read or edit by the user.\n * @param options.ancestorOffset An offset from the boundary of scrollable ancestors (if any)\n * the `target` will be moved by if the viewport is scrolled. It enhances the user experience\n * by keeping the `target` some distance from the edge of the ancestors and thus making it easier to\n * read or edit by the user.\n * @param options.alignToTop When set `true`, the helper will make sure the `target` is scrolled up\n * to the top boundary of the viewport and/or scrollable ancestors if scrolled up. When not set\n * (default), the `target` will be revealed by scrolling as little as possible. This option will\n * not affect `targets` that must be scrolled down because they will appear at the top of the boundary\n * anyway.\n *\n * ```\n *                                             scrollViewportToShowTarget() with            scrollViewportToShowTarget() with\n *          Initial state                        alignToTop unset (default)                        alignToTop = true\n *\n * ┌────────────────────────────────┬─┐       ┌────────────────────────────────┬─┐        ┌────────────────────────────────┬─┐\n * │                                │▲│       │                                │▲│        │   [ Target to be revealed ]    │▲│\n * │                                │ │       │                                │ │        │                                │ │\n * │                                │█│       │                                │ │        │                                │ │\n * │                                │█│       │                                │ │        │                                │ │\n * │                                │ │       │                                │█│        │                                │ │\n * │                                │ │       │                                │█│        │                                │█│\n * │                                │ │       │                                │ │        │                                │█│\n * │                                │▼│       │   [ Target to be revealed ]    │▼│        │                                │▼│\n * └────────────────────────────────┴─┘       └────────────────────────────────┴─┘        └────────────────────────────────┴─┘\n *\n *\n *     [ Target to be revealed ]\n *```\n *\n * @param options.forceScroll When set `true`, the `target` will be aligned to the top of the viewport\n * and scrollable ancestors whether it is already visible or not. This option will only work when `alignToTop`\n * is `true`\n */ function scrollViewportToShowTarget({ target, viewportOffset = 0, ancestorOffset = 0, alignToTop, forceScroll }) {\n    const targetWindow = getWindow(target);\n    let currentWindow = targetWindow;\n    let currentFrame = null;\n    viewportOffset = normalizeViewportOffset(viewportOffset);\n    // Iterate over all windows, starting from target's parent window up to window#top.\n    while(currentWindow){\n        let firstAncestorToScroll;\n        // Let's scroll target's ancestors first to reveal it. Then, once the ancestor scrolls\n        // settled down, the algorithm can eventually scroll the viewport of the current window.\n        //\n        // Note: If the current window is target's **original** window (e.g. the first one),\n        // start scrolling the closest parent of the target. If not, scroll the closest parent\n        // of an iframe that resides in the current window.\n        if (currentWindow == targetWindow) {\n            firstAncestorToScroll = getParentElement(target);\n        } else {\n            firstAncestorToScroll = getParentElement(currentFrame);\n        }\n        // Scroll the target's ancestors first. Once done, scrolling the viewport is easy.\n        scrollAncestorsToShowRect({\n            parent: firstAncestorToScroll,\n            getRect: ()=>{\n                // Note: If the target does not belong to the current window **directly**,\n                // i.e. it resides in an iframe belonging to the window, obtain the target's rect\n                // in the coordinates of the current window. By default, a Rect returns geometry\n                // relative to the current window's viewport. To make it work in a parent window,\n                // it must be shifted.\n                return getRectRelativeToWindow(target, currentWindow);\n            },\n            alignToTop,\n            ancestorOffset,\n            forceScroll\n        });\n        // Obtain the rect of the target after it has been scrolled within its ancestors.\n        // It's time to scroll the viewport.\n        const targetRect = getRectRelativeToWindow(target, currentWindow);\n        scrollWindowToShowRect({\n            window: currentWindow,\n            rect: targetRect,\n            viewportOffset,\n            alignToTop,\n            forceScroll\n        });\n        if (currentWindow.parent != currentWindow) {\n            // Keep the reference to the <iframe> element the \"previous current window\" was\n            // rendered within. It will be useful to re–calculate the rect of the target\n            // in the parent window's relative geometry. The target's rect must be shifted\n            // by it's iframe's position.\n            currentFrame = currentWindow.frameElement;\n            currentWindow = currentWindow.parent;\n            // If the current window has some parent but frameElement is inaccessible, then they have\n            // different domains/ports and, due to security reasons, accessing and scrolling\n            // the parent window won't be possible.\n            // See https://github.com/ckeditor/ckeditor5/issues/930.\n            if (!currentFrame) {\n                return;\n            }\n        } else {\n            currentWindow = null;\n        }\n    }\n}\n/**\n * Makes any page `HTMLElement` or `Range` (target) visible within its scrollable ancestors,\n * e.g. if they have `overflow: scroll` CSS style.\n *\n * @param target A target, which supposed to become visible to the user.\n * @param ancestorOffset An offset between the target and the boundary of scrollable ancestors\n * to be maintained while scrolling.\n * @param limiterElement The outermost ancestor that should be scrolled. If specified, it can prevent\n * scrolling the whole page.\n */ function scrollAncestorsToShowTarget(target, ancestorOffset, limiterElement) {\n    const targetParent = getParentElement(target);\n    scrollAncestorsToShowRect({\n        parent: targetParent,\n        getRect: ()=>new Rect(target),\n        ancestorOffset,\n        limiterElement\n    });\n}\n/**\n * Makes a given rect visible within its parent window.\n *\n * Note: Avoid the situation where the caret is still in the viewport, but totally\n * at the edge of it. In such situation, if it moved beyond the viewport in the next\n * action e.g. after paste, the scrolling would move it to the viewportOffset level\n * and it all would look like the caret visually moved up/down:\n *\n * 1.\n * ```\n * | foo[]\n * |                                    <--- N px of space below the caret\n * +---------------------------------...\n * ```\n *\n * 2. *paste*\n * 3.\n * ```\n * |\n * |\n * +-foo-----------------------------...\n *   bar[]                              <--- caret below viewport, scrolling...\n * ```\n *\n * 4. *scrolling*\n * 5.\n * ```\n * |\n * | foo\n * | bar[]                              <--- caret precisely at the edge\n * +---------------------------------...\n * ```\n *\n * To prevent this, this method checks the rects moved by the viewportOffset to cover\n * the upper/lower edge of the viewport. It makes sure if the action repeats, there's\n * no twitching – it's a purely visual improvement:\n *\n * 5. (after fix)\n * ```\n * |\n * | foo\n * | bar[]\n * |                                    <--- N px of space below the caret\n * +---------------------------------...\n * ```\n *\n * @param options Additional configuration of the scrolling behavior.\n * @param options.window A window which is scrolled to reveal the rect.\n * @param options.rect A rect which is to be revealed.\n * @param options.viewportOffset An offset from the edge of the viewport (in pixels) the `rect` will be\n * moved by if the viewport is scrolled.\n * @param options.alignToTop When set `true`, the helper will make sure the `rect` is scrolled up\n * to the top boundary of the viewport if scrolled up. When not set (default), the `rect` will be\n * revealed by scrolling as little as possible. This option will not affect rects that must be scrolled\n * down because they will appear at the top of the boundary anyway.\n * @param options.forceScroll When set `true`, the `rect` will be aligned to the top of the viewport\n * whether it is already visible or not. This option will only work when `alignToTop` is `true`\n */ function scrollWindowToShowRect({ window, rect, alignToTop, forceScroll, viewportOffset }) {\n    const targetShiftedDownRect = rect.clone().moveBy(0, viewportOffset.bottom);\n    const targetShiftedUpRect = rect.clone().moveBy(0, -viewportOffset.top);\n    const viewportRect = new Rect(window).excludeScrollbarsAndBorders();\n    const rects = [\n        targetShiftedUpRect,\n        targetShiftedDownRect\n    ];\n    const forceScrollToTop = alignToTop && forceScroll;\n    const allRectsFitInViewport = rects.every((rect)=>viewportRect.contains(rect));\n    let { scrollX, scrollY } = window;\n    const initialScrollX = scrollX;\n    const initialScrollY = scrollY;\n    if (forceScrollToTop) {\n        scrollY -= viewportRect.top - rect.top + viewportOffset.top;\n    } else if (!allRectsFitInViewport) {\n        if (isAbove(targetShiftedUpRect, viewportRect)) {\n            scrollY -= viewportRect.top - rect.top + viewportOffset.top;\n        } else if (isBelow(targetShiftedDownRect, viewportRect)) {\n            if (alignToTop) {\n                scrollY += rect.top - viewportRect.top - viewportOffset.top;\n            } else {\n                scrollY += rect.bottom - viewportRect.bottom + viewportOffset.bottom;\n            }\n        }\n    }\n    if (!allRectsFitInViewport) {\n        // TODO: Web browsers scroll natively to place the target in the middle\n        // of the viewport. It's not a very popular case, though.\n        if (isLeftOf(rect, viewportRect)) {\n            scrollX -= viewportRect.left - rect.left + viewportOffset.left;\n        } else if (isRightOf(rect, viewportRect)) {\n            scrollX += rect.right - viewportRect.right + viewportOffset.right;\n        }\n    }\n    if (scrollX != initialScrollX || scrollY !== initialScrollY) {\n        window.scrollTo(scrollX, scrollY);\n    }\n}\n/**\n * Recursively scrolls element ancestors to visually reveal a rect.\n *\n * @param options Additional configuration of the scrolling behavior.\n * @param options.parent The first parent ancestor to start scrolling.\n * @param options.getRect A function which returns the Rect, which is to be revealed.\n * @param options.ancestorOffset An offset from the boundary of scrollable ancestors (if any)\n * the `Rect` instance will be moved by if the viewport is scrolled.\n * @param options.alignToTop When set `true`, the helper will make sure the `Rect` instance is scrolled up\n * to the top boundary of the scrollable ancestors if scrolled up. When not set (default), the `rect`\n * will be revealed by scrolling as little as possible. This option will not affect rects that must be\n * scrolled down because they will appear at the top of the boundary\n * anyway.\n * @param options.forceScroll When set `true`, the `rect` will be aligned to the top of scrollable ancestors\n * whether it is already visible or not. This option will only work when `alignToTop` is `true`\n * @param options.limiterElement The outermost ancestor that should be scrolled. Defaults to the `<body>` element.\n */ function scrollAncestorsToShowRect({ parent, getRect, alignToTop, forceScroll, ancestorOffset = 0, limiterElement }) {\n    const parentWindow = getWindow(parent);\n    const forceScrollToTop = alignToTop && forceScroll;\n    let parentRect, targetRect, targetFitsInTarget;\n    const limiter = limiterElement || parentWindow.document.body;\n    while(parent != limiter){\n        targetRect = getRect();\n        parentRect = new Rect(parent).excludeScrollbarsAndBorders();\n        targetFitsInTarget = parentRect.contains(targetRect);\n        if (forceScrollToTop) {\n            parent.scrollTop -= parentRect.top - targetRect.top + ancestorOffset;\n        } else if (!targetFitsInTarget) {\n            if (isAbove(targetRect, parentRect)) {\n                parent.scrollTop -= parentRect.top - targetRect.top + ancestorOffset;\n            } else if (isBelow(targetRect, parentRect)) {\n                if (alignToTop) {\n                    parent.scrollTop += targetRect.top - parentRect.top - ancestorOffset;\n                } else {\n                    parent.scrollTop += targetRect.bottom - parentRect.bottom + ancestorOffset;\n                }\n            }\n        }\n        if (!targetFitsInTarget) {\n            if (isLeftOf(targetRect, parentRect)) {\n                parent.scrollLeft -= parentRect.left - targetRect.left + ancestorOffset;\n            } else if (isRightOf(targetRect, parentRect)) {\n                parent.scrollLeft += targetRect.right - parentRect.right + ancestorOffset;\n            }\n        }\n        parent = parent.parentNode;\n    }\n}\n/**\n * Determines if a given `Rect` extends beyond the bottom edge of the second `Rect`.\n */ function isBelow(firstRect, secondRect) {\n    return firstRect.bottom > secondRect.bottom;\n}\n/**\n * Determines if a given `Rect` extends beyond the top edge of the second `Rect`.\n */ function isAbove(firstRect, secondRect) {\n    return firstRect.top < secondRect.top;\n}\n/**\n * Determines if a given `Rect` extends beyond the left edge of the second `Rect`.\n */ function isLeftOf(firstRect, secondRect) {\n    return firstRect.left < secondRect.left;\n}\n/**\n * Determines if a given `Rect` extends beyond the right edge of the second `Rect`.\n */ function isRightOf(firstRect, secondRect) {\n    return firstRect.right > secondRect.right;\n}\n/**\n * Returns the closest window of an element or range.\n */ function getWindow(elementOrRange) {\n    if (isRange(elementOrRange)) {\n        return elementOrRange.startContainer.ownerDocument.defaultView;\n    } else {\n        return elementOrRange.ownerDocument.defaultView;\n    }\n}\n/**\n * Returns the closest parent of an element or DOM range.\n */ function getParentElement(elementOrRange) {\n    if (isRange(elementOrRange)) {\n        let parent = elementOrRange.commonAncestorContainer;\n        // If a Range is attached to the Text, use the closest element ancestor.\n        if (isText(parent)) {\n            parent = parent.parentNode;\n        }\n        return parent;\n    } else {\n        return elementOrRange.parentNode;\n    }\n}\n/**\n * Returns the rect of an element or range residing in an iframe.\n * The result rect is relative to the geometry of the passed window instance.\n *\n * @param target Element or range which rect should be returned.\n * @param relativeWindow A window the rect should be relative to.\n */ function getRectRelativeToWindow(target, relativeWindow) {\n    const targetWindow = getWindow(target);\n    const rect = new Rect(target);\n    if (targetWindow === relativeWindow) {\n        return rect;\n    } else {\n        let currentWindow = targetWindow;\n        while(currentWindow != relativeWindow){\n            const frame = currentWindow.frameElement;\n            const frameRect = new Rect(frame).excludeScrollbarsAndBorders();\n            rect.moveBy(frameRect.left, frameRect.top);\n            currentWindow = currentWindow.parent;\n        }\n    }\n    return rect;\n}\n/**\n * A helper that explodes the `viewportOffset` configuration if defined as a plain number into an object\n * with `top`, `bottom`, `left`, and `right` properties.\n *\n * If an object value is passed, this helper will pass it through.\n *\n * @param viewportOffset Viewport offset to be normalized.\n */ function normalizeViewportOffset(viewportOffset) {\n    if (typeof viewportOffset === 'number') {\n        return {\n            top: viewportOffset,\n            bottom: viewportOffset,\n            left: viewportOffset,\n            right: viewportOffset\n        };\n    }\n    return viewportOffset;\n}\n\nconst modifiersToGlyphsMac = {\n    ctrl: '⌃',\n    cmd: '⌘',\n    alt: '⌥',\n    shift: '⇧'\n};\nconst modifiersToGlyphsNonMac = {\n    ctrl: 'Ctrl+',\n    alt: 'Alt+',\n    shift: 'Shift+'\n};\nconst keyCodesToGlyphs = {\n    37: '←',\n    38: '↑',\n    39: '→',\n    40: '↓',\n    9: '⇥',\n    33: 'Page Up',\n    34: 'Page Down'\n};\n/**\n * An object with `keyName => keyCode` pairs for a set of known keys.\n *\n * Contains:\n *\n * * `a-z`,\n * * `0-9`,\n * * `f1-f12`,\n * * `` ` ``, `-`, `=`, `[`, `]`, `;`, `'`, `,`, `.`, `/`, `\\`,\n * * `arrow(left|up|right|bottom)`,\n * * `backspace`, `delete`, `enter`, `esc`, `tab`,\n * * `ctrl`, `cmd`, `shift`, `alt`.\n */ const keyCodes = /* #__PURE__ */ generateKnownKeyCodes();\nconst keyCodeNames = /* #__PURE__ */ Object.fromEntries(/* #__PURE__ */ Object.entries(keyCodes).map(([name, code])=>{\n    let prettyKeyName;\n    if (code in keyCodesToGlyphs) {\n        prettyKeyName = keyCodesToGlyphs[code];\n    } else {\n        prettyKeyName = name.charAt(0).toUpperCase() + name.slice(1);\n    }\n    return [\n        code,\n        prettyKeyName\n    ];\n}));\n/**\n * Converts a key name or {@link module:utils/keyboard~KeystrokeInfo keystroke info} into a key code.\n *\n * Note: Key names are matched with {@link module:utils/keyboard#keyCodes} in a case-insensitive way.\n *\n * @param key A key name (see {@link module:utils/keyboard#keyCodes}) or a keystroke data object.\n * @returns Key or keystroke code.\n */ function getCode(key) {\n    let keyCode;\n    if (typeof key == 'string') {\n        keyCode = keyCodes[key.toLowerCase()];\n        if (!keyCode) {\n            /**\n\t\t\t * Unknown key name. Only key names included in the {@link module:utils/keyboard#keyCodes} can be used.\n\t\t\t *\n\t\t\t * @error keyboard-unknown-key\n\t\t\t * @param {String} key\n\t\t\t */ throw new CKEditorError('keyboard-unknown-key', null, {\n                key\n            });\n        }\n    } else {\n        keyCode = key.keyCode + (key.altKey ? keyCodes.alt : 0) + (key.ctrlKey ? keyCodes.ctrl : 0) + (key.shiftKey ? keyCodes.shift : 0) + (key.metaKey ? keyCodes.cmd : 0);\n    }\n    return keyCode;\n}\n/**\n * Parses the keystroke and returns a keystroke code that will match the code returned by\n * {@link module:utils/keyboard~getCode} for the corresponding {@link module:utils/keyboard~KeystrokeInfo keystroke info}.\n *\n * The keystroke can be passed in two formats:\n *\n * * as a single string – e.g. `ctrl + A`,\n * * as an array of {@link module:utils/keyboard~keyCodes known key names} and key codes – e.g.:\n *   * `[ 'ctrl', 32 ]` (ctrl + space),\n *   * `[ 'ctrl', 'a' ]` (ctrl + A).\n *\n * Note: Key names are matched with {@link module:utils/keyboard#keyCodes} in a case-insensitive way.\n *\n * Note: Only keystrokes with a single non-modifier key are supported (e.g. `ctrl+A` is OK, but `ctrl+A+B` is not).\n *\n * Note: On macOS, keystroke handling is translating the `Ctrl` key to the `Cmd` key and handling only that keystroke.\n * For example, a registered keystroke `Ctrl+A` will be translated to `Cmd+A` on macOS. To disable the translation of some keystroke,\n * use the forced modifier: `Ctrl!+A` (note the exclamation mark).\n *\n * @param keystroke The keystroke definition.\n * @returns Keystroke code.\n */ function parseKeystroke(keystroke) {\n    if (typeof keystroke == 'string') {\n        keystroke = splitKeystrokeText(keystroke);\n    }\n    return keystroke.map((key)=>typeof key == 'string' ? getEnvKeyCode(key) : key).reduce((key, sum)=>sum + key, 0);\n}\n/**\n * Translates any keystroke string text like `\"Ctrl+A\"` to an\n * environment–specific keystroke, i.e. `\"⌘A\"` on macOS.\n *\n * @param keystroke The keystroke text.\n * @returns The keystroke text specific for the environment.\n */ function getEnvKeystrokeText(keystroke) {\n    let keystrokeCode = parseKeystroke(keystroke);\n    const modifiersToGlyphs = Object.entries(env.isMac || env.isiOS ? modifiersToGlyphsMac : modifiersToGlyphsNonMac);\n    const modifiers = modifiersToGlyphs.reduce((modifiers, [name, glyph])=>{\n        // Modifier keys are stored as a bit mask so extract those from the keystroke code.\n        if ((keystrokeCode & keyCodes[name]) != 0) {\n            keystrokeCode &= ~keyCodes[name];\n            modifiers += glyph;\n        }\n        return modifiers;\n    }, '');\n    return modifiers + (keystrokeCode ? keyCodeNames[keystrokeCode] : '');\n}\n/**\n * Returns `true` if the provided key code represents one of the arrow keys.\n *\n * @param keyCode A key code as in {@link module:utils/keyboard~KeystrokeInfo#keyCode}.\n */ function isArrowKeyCode(keyCode) {\n    return keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup || keyCode == keyCodes.arrowdown;\n}\n/**\n * Returns the direction in which the {@link module:engine/model/documentselection~DocumentSelection selection}\n * will move when the provided arrow key code is pressed considering the language direction of the editor content.\n *\n * For instance, in right–to–left (RTL) content languages, pressing the left arrow means moving the selection right (forward)\n * in the model structure. Similarly, pressing the right arrow moves the selection left (backward).\n *\n * @param keyCode A key code as in {@link module:utils/keyboard~KeystrokeInfo#keyCode}.\n * @param contentLanguageDirection The content language direction, corresponding to\n * {@link module:utils/locale~Locale#contentLanguageDirection}.\n * @returns Localized arrow direction or `undefined` for non-arrow key codes.\n */ function getLocalizedArrowKeyCodeDirection(keyCode, contentLanguageDirection) {\n    const isLtrContent = contentLanguageDirection === 'ltr';\n    switch(keyCode){\n        case keyCodes.arrowleft:\n            return isLtrContent ? 'left' : 'right';\n        case keyCodes.arrowright:\n            return isLtrContent ? 'right' : 'left';\n        case keyCodes.arrowup:\n            return 'up';\n        case keyCodes.arrowdown:\n            return 'down';\n    }\n}\n/**\n * Converts a key name to the key code with mapping based on the env.\n *\n * See: {@link module:utils/keyboard~getCode}.\n *\n * @param key The key name (see {@link module:utils/keyboard#keyCodes}).\n * @returns Key code.\n */ function getEnvKeyCode(key) {\n    // Don't remap modifier key for forced modifiers.\n    if (key.endsWith('!')) {\n        return getCode(key.slice(0, -1));\n    }\n    const code = getCode(key);\n    return (env.isMac || env.isiOS) && code == keyCodes.ctrl ? keyCodes.cmd : code;\n}\n/**\n * Determines if the provided key code moves the {@link module:engine/model/documentselection~DocumentSelection selection}\n * forward or backward considering the language direction of the editor content.\n *\n * For instance, in right–to–left (RTL) languages, pressing the left arrow means moving forward\n * in the model structure. Similarly, pressing the right arrow moves the selection backward.\n *\n * @param keyCode A key code as in {@link module:utils/keyboard~KeystrokeInfo#keyCode}.\n * @param contentLanguageDirection The content language direction, corresponding to\n * {@link module:utils/locale~Locale#contentLanguageDirection}.\n */ function isForwardArrowKeyCode(keyCode, contentLanguageDirection) {\n    const localizedKeyCodeDirection = getLocalizedArrowKeyCodeDirection(keyCode, contentLanguageDirection);\n    return localizedKeyCodeDirection === 'down' || localizedKeyCodeDirection === 'right';\n}\nfunction generateKnownKeyCodes() {\n    const keyCodes = {\n        pageup: 33,\n        pagedown: 34,\n        arrowleft: 37,\n        arrowup: 38,\n        arrowright: 39,\n        arrowdown: 40,\n        backspace: 8,\n        delete: 46,\n        enter: 13,\n        space: 32,\n        esc: 27,\n        tab: 9,\n        // The idea about these numbers is that they do not collide with any real key codes, so we can use them\n        // like bit masks.\n        ctrl: 0x110000,\n        shift: 0x220000,\n        alt: 0x440000,\n        cmd: 0x880000\n    };\n    // a-z\n    for(let code = 65; code <= 90; code++){\n        const letter = String.fromCharCode(code);\n        keyCodes[letter.toLowerCase()] = code;\n    }\n    // 0-9\n    for(let code = 48; code <= 57; code++){\n        keyCodes[code - 48] = code;\n    }\n    // F1-F12\n    for(let code = 112; code <= 123; code++){\n        keyCodes['f' + (code - 111)] = code;\n    }\n    // other characters\n    Object.assign(keyCodes, {\n        '\\'': 222,\n        ',': 108,\n        '-': 109,\n        '.': 110,\n        '/': 111,\n        ';': 186,\n        '=': 187,\n        '[': 219,\n        '\\\\': 220,\n        ']': 221,\n        '`': 223\n    });\n    return keyCodes;\n}\nfunction splitKeystrokeText(keystroke) {\n    return keystroke.split('+').map((key)=>key.trim());\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/language\n */ /**\n * String representing a language direction.\n */ const RTL_LANGUAGE_CODES = [\n    'ar',\n    'ara',\n    'dv',\n    'div',\n    'fa',\n    'per',\n    'fas',\n    'he',\n    'heb',\n    'ku',\n    'kur',\n    'ug',\n    'uig' // Uighur, Uyghur\n];\n/**\n * Helps determine whether a language text direction is LTR or RTL.\n *\n * @param languageCode The ISO 639-1 or ISO 639-2 language code.\n */ function getLanguageDirection(languageCode) {\n    return RTL_LANGUAGE_CODES.includes(languageCode) ? 'rtl' : 'ltr';\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/toarray\n */ /**\n * Transforms any value to an array. If the provided value is already an array, it is returned unchanged.\n *\n * @label MUTABLE\n * @param data The value to transform to an array.\n * @returns An array created from data.\n */ function toArray(data) {\n    return Array.isArray(data) ? data : [\n        data\n    ];\n}\n\n/* istanbul ignore else -- @preserve */ if (!global.window.CKEDITOR_TRANSLATIONS) {\n    global.window.CKEDITOR_TRANSLATIONS = {};\n}\n/**\n * **Note:** This method is internal, use {@link module:utils/locale~Locale#t the `t()` function} instead to translate\n * the editor UI parts.\n *\n * This function is responsible for translating messages to the specified language. It uses translations added perviously\n * by {@link module:utils/translation-service~add} (a translations dictionary and the `getPluralForm()` function\n * to provide accurate translations of plural forms).\n *\n * When no translation is defined in the dictionary or the dictionary does not exist, this function returns\n * the original message string or the message plural depending on the number of elements.\n *\n * ```ts\n * translate( 'pl', { string: 'Cancel' } ); // 'Cancel'\n * ```\n *\n * The third optional argument is the number of elements, based on which the single form or one of the plural forms\n * should be picked when the message is supposed to support various plural forms.\n *\n * ```ts\n * translate( 'en', { string: 'Add a space', plural: 'Add %0 spaces' }, 1 ); // 'Add a space'\n * translate( 'en', { string: 'Add a space', plural: 'Add %0 spaces' }, 3 ); // 'Add %0 spaces'\n * ```\n *\n * The message should provide an ID using the `id` property when the message strings are not unique and their\n * translations should be different.\n *\n * ```ts\n * translate( 'en', { string: 'image', id: 'ADD_IMAGE' } );\n * translate( 'en', { string: 'image', id: 'AN_IMAGE' } );\n * ```\n *\n * @internal\n * @param language Target language.\n * @param message A message that will be translated.\n * @param quantity The number of elements for which a plural form should be picked from the target language dictionary.\n * @param translations Translations passed in editor config, if not provided use the global `window.CKEDITOR_TRANSLATIONS`.\n * @returns Translated sentence.\n */ function _translate(language, message, quantity = 1, translations) {\n    if (typeof quantity !== 'number') {\n        /**\n\t\t * An incorrect value was passed to the translation function. This was probably caused\n\t\t * by an incorrect message interpolation of a plural form. Note that for messages supporting plural forms\n\t\t * the second argument of the `t()` function should always be a number or an array with a number as the first element.\n\t\t *\n\t\t * @error translation-service-quantity-not-a-number\n\t\t */ throw new CKEditorError('translation-service-quantity-not-a-number', null, {\n            quantity\n        });\n    }\n    const normalizedTranslations = translations || global.window.CKEDITOR_TRANSLATIONS;\n    const numberOfLanguages = getNumberOfLanguages(normalizedTranslations);\n    if (numberOfLanguages === 1) {\n        // Override the language to the only supported one.\n        // This can't be done in the `Locale` class, because the translations comes after the `Locale` class initialization.\n        language = Object.keys(normalizedTranslations)[0];\n    }\n    const messageId = message.id || message.string;\n    if (numberOfLanguages === 0 || !hasTranslation(language, messageId, normalizedTranslations)) {\n        if (quantity !== 1) {\n            // Return the default plural form that was passed in the `message.plural` parameter.\n            return message.plural;\n        }\n        return message.string;\n    }\n    const dictionary = normalizedTranslations[language].dictionary;\n    const getPluralForm = normalizedTranslations[language].getPluralForm || ((n)=>n === 1 ? 0 : 1);\n    const translation = dictionary[messageId];\n    if (typeof translation === 'string') {\n        return translation;\n    }\n    const pluralFormIndex = Number(getPluralForm(quantity));\n    // Note: The `translate` function is not responsible for replacing `%0, %1, ...` with values.\n    return translation[pluralFormIndex];\n}\n/**\n * If array then merge objects which are inside otherwise return given object.\n *\n * @internal\n * @param translations Translations passed in editor config.\n */ function _unifyTranslations(translations) {\n    return Array.isArray(translations) ? translations.reduce((acc, translation)=>merge(acc, translation)) : translations;\n}\n/**\n * Checks whether the dictionary exists and translation in that dictionary exists.\n */ function hasTranslation(language, messageId, translations) {\n    return !!translations[language] && !!translations[language].dictionary[messageId];\n}\nfunction getNumberOfLanguages(translations) {\n    return Object.keys(translations).length;\n}\n\n/**\n * Represents the localization services.\n */ class Locale {\n    /**\n\t * The editor UI language code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t *\n\t * If the {@link #contentLanguage content language} was not specified in the `Locale` constructor,\n\t * it also defines the language of the content.\n\t */ uiLanguage;\n    /**\n\t * Text direction of the {@link #uiLanguage editor UI language}. Either `'ltr'` or `'rtl'`.\n\t */ uiLanguageDirection;\n    /**\n\t * The editor content language code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t *\n\t * Usually the same as the {@link #uiLanguage editor language}, it can be customized by passing an optional\n\t * argument to the `Locale` constructor.\n\t */ contentLanguage;\n    /**\n\t * Text direction of the {@link #contentLanguage editor content language}.\n\t *\n\t * If the content language was passed directly to the `Locale` constructor, this property represents the\n\t * direction of that language.\n\t *\n\t * If the {@link #contentLanguage editor content language} was derived from the {@link #uiLanguage editor language},\n\t * the content language direction is the same as the {@link #uiLanguageDirection UI language direction}.\n\t *\n\t * The value is either `'ltr'` or `'rtl'`.\n\t */ contentLanguageDirection;\n    /**\n\t * Translates the given message to the {@link #uiLanguage}. This method is also available in\n\t * {@link module:core/editor/editor~Editor#t `Editor`} and {@link module:ui/view~View#t `View`}.\n\t *\n\t * This method's context is statically bound to the `Locale` instance and **should always be called as a function**:\n\t *\n\t * ```ts\n\t * const t = locale.t;\n\t * t( 'Label' );\n\t * ```\n\t *\n\t * The message can be either a string or an object implementing the {@link module:utils/translation-service~Message} interface.\n\t *\n\t * The message may contain placeholders (`%<index>`) for value(s) that are passed as a `values` parameter.\n\t * For an array of values, the `%<index>` will be changed to an element of that array at the given index.\n\t * For a single value passed as the second argument, only the `%0` placeholders will be changed to the provided value.\n\t *\n\t * ```ts\n\t * t( 'Created file \"%0\" in %1ms.', [ fileName, timeTaken ] );\n\t * t( 'Created file \"%0\", fileName );\n\t * ```\n\t *\n\t * The message supports plural forms. To specify the plural form, use the `plural` property. Singular or plural form\n\t * will be chosen depending on the first value from the passed `values`. The value of the `plural` property is used\n\t * as a default plural translation when the translation for the target language is missing.\n\t *\n\t * ```ts\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 1 ); // 'Add a space' for the English language.\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 5 ); // 'Add 5 spaces' for the English language.\n\t * t( { string: '%1 a space', plural: '%1 %0 spaces' }, [ 2, 'Add' ] ); // 'Add 2 spaces' for the English language.\n\t *\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 1 ); // 'Dodaj spację' for the Polish language.\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 5 ); // 'Dodaj 5 spacji' for the Polish language.\n\t * t( { string: '%1 a space', plural: '%1 %0 spaces' }, [ 2, 'Add' ] ); // 'Dodaj 2 spacje' for the Polish language.\n\t * ```\n\t *\n\t *  * The message should provide an ID using the `id` property when the message strings are not unique and their\n\t * translations should be different.\n\t *\n\t * ```ts\n\t * translate( 'en', { string: 'image', id: 'ADD_IMAGE' } );\n\t * translate( 'en', { string: 'image', id: 'AN_IMAGE' } );\n\t * ```\n\t */ t;\n    /**\n\t * Object that contains translations.\n\t */ translations;\n    /**\n\t * Creates a new instance of the locale class. Learn more about\n\t * {@glink getting-started/setup/ui-language configuring the language of the editor}.\n\t *\n\t * @param options Locale configuration.\n\t * @param options.uiLanguage The editor UI language code in the\n\t * [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format. See {@link #uiLanguage}.\n\t * @param options.contentLanguage The editor content language code in the\n\t * [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format. If not specified, the same as `options.language`.\n\t * See {@link #contentLanguage}.\n\t * @param translations Translations passed as a editor config parameter.\n\t */ constructor({ uiLanguage = 'en', contentLanguage, translations } = {}){\n        this.uiLanguage = uiLanguage;\n        this.contentLanguage = contentLanguage || this.uiLanguage;\n        this.uiLanguageDirection = getLanguageDirection(this.uiLanguage);\n        this.contentLanguageDirection = getLanguageDirection(this.contentLanguage);\n        this.translations = _unifyTranslations(translations);\n        this.t = (message, values)=>this._t(message, values);\n    }\n    /**\n\t * The editor UI language code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t *\n\t * **Note**: This property was deprecated. Please use {@link #uiLanguage} and {@link #contentLanguage}\n\t * properties instead.\n\t *\n\t * @deprecated\n\t */ get language() {\n        /**\n\t\t * The {@link module:utils/locale~Locale#language `Locale#language`} property was deprecated and will\n\t\t * be removed in the near future. Please use the {@link module:utils/locale~Locale#uiLanguage `Locale#uiLanguage`} and\n\t\t * {@link module:utils/locale~Locale#contentLanguage `Locale#contentLanguage`} properties instead.\n\t\t *\n\t\t * @error locale-deprecated-language-property\n\t\t */ console.warn('locale-deprecated-language-property: ' + 'The Locale#language property has been deprecated and will be removed in the near future. ' + 'Please use #uiLanguage and #contentLanguage properties instead.');\n        return this.uiLanguage;\n    }\n    /**\n\t * An unbound version of the {@link #t} method.\n\t */ _t(message, values = []) {\n        values = toArray(values);\n        if (typeof message === 'string') {\n            message = {\n                string: message\n            };\n        }\n        const hasPluralForm = !!message.plural;\n        const quantity = hasPluralForm ? values[0] : 1;\n        const translatedString = _translate(this.uiLanguage, message, quantity, this.translations);\n        return interpolateString(translatedString, values);\n    }\n}\n/**\n * Fills the `%0, %1, ...` string placeholders with values.\n */ function interpolateString(string, values) {\n    return string.replace(/%(\\d+)/g, (match, index)=>{\n        return index < values.length ? values[index] : match;\n    });\n}\n\n/**\n * Collections are ordered sets of objects. Items in the collection can be retrieved by their indexes\n * in the collection (like in an array) or by their ids.\n *\n * If an object without an `id` property is being added to the collection, the `id` property will be generated\n * automatically. Note that the automatically generated id is unique only within this single collection instance.\n *\n * By default an item in the collection is identified by its `id` property. The name of the identifier can be\n * configured through the constructor of the collection.\n *\n * @typeParam T The type of the collection element.\n */ class Collection extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * The internal list of items in the collection.\n\t */ _items;\n    /**\n\t * The internal map of items in the collection.\n\t */ _itemMap;\n    /**\n\t * The name of the property which is considered to identify an item.\n\t */ _idProperty;\n    /**\n\t * A collection instance this collection is bound to as a result\n\t * of calling {@link #bindTo} method.\n\t */ _bindToCollection;\n    /**\n\t * A helper mapping external items of a bound collection ({@link #bindTo})\n\t * and actual items of this collection. It provides information\n\t * necessary to properly remove items bound to another collection.\n\t *\n\t * See {@link #_bindToInternalToExternalMap}.\n\t */ _bindToExternalToInternalMap;\n    /**\n\t * A helper mapping items of this collection to external items of a bound collection\n\t * ({@link #bindTo}). It provides information necessary to manage the bindings, e.g.\n\t * to avoid loops in two–way bindings.\n\t *\n\t * See {@link #_bindToExternalToInternalMap}.\n\t */ _bindToInternalToExternalMap;\n    /**\n\t * Stores indexes of skipped items from bound external collection.\n\t */ _skippedIndexesFromExternal;\n    constructor(initialItemsOrOptions = {}, options = {}){\n        super();\n        const hasInitialItems = isIterable(initialItemsOrOptions);\n        if (!hasInitialItems) {\n            options = initialItemsOrOptions;\n        }\n        this._items = [];\n        this._itemMap = new Map();\n        this._idProperty = options.idProperty || 'id';\n        this._bindToExternalToInternalMap = new WeakMap();\n        this._bindToInternalToExternalMap = new WeakMap();\n        this._skippedIndexesFromExternal = [];\n        // Set the initial content of the collection (if provided in the constructor).\n        if (hasInitialItems) {\n            for (const item of initialItemsOrOptions){\n                this._items.push(item);\n                this._itemMap.set(this._getItemIdBeforeAdding(item), item);\n            }\n        }\n    }\n    /**\n\t * The number of items available in the collection.\n\t */ get length() {\n        return this._items.length;\n    }\n    /**\n\t * Returns the first item from the collection or null when collection is empty.\n\t */ get first() {\n        return this._items[0] || null;\n    }\n    /**\n\t * Returns the last item from the collection or null when collection is empty.\n\t */ get last() {\n        return this._items[this.length - 1] || null;\n    }\n    /**\n\t * Adds an item into the collection.\n\t *\n\t * If the item does not have an id, then it will be automatically generated and set on the item.\n\t *\n\t * @param item\n\t * @param index The position of the item in the collection. The item\n\t * is pushed to the collection when `index` not specified.\n\t * @fires add\n\t * @fires change\n\t */ add(item, index) {\n        return this.addMany([\n            item\n        ], index);\n    }\n    /**\n\t * Adds multiple items into the collection.\n\t *\n\t * Any item not containing an id will get an automatically generated one.\n\t *\n\t * @param items\n\t * @param index The position of the insertion. Items will be appended if no `index` is specified.\n\t * @fires add\n\t * @fires change\n\t */ addMany(items, index) {\n        if (index === undefined) {\n            index = this._items.length;\n        } else if (index > this._items.length || index < 0) {\n            /**\n\t\t\t * The `index` passed to {@link module:utils/collection~Collection#addMany `Collection#addMany()`}\n\t\t\t * is invalid. It must be a number between 0 and the collection's length.\n\t\t\t *\n\t\t\t * @error collection-add-item-invalid-index\n\t\t\t */ throw new CKEditorError('collection-add-item-invalid-index', this);\n        }\n        let offset = 0;\n        for (const item of items){\n            const itemId = this._getItemIdBeforeAdding(item);\n            const currentItemIndex = index + offset;\n            this._items.splice(currentItemIndex, 0, item);\n            this._itemMap.set(itemId, item);\n            this.fire('add', item, currentItemIndex);\n            offset++;\n        }\n        this.fire('change', {\n            added: items,\n            removed: [],\n            index\n        });\n        return this;\n    }\n    /**\n\t * Gets an item by its ID or index.\n\t *\n\t * @param idOrIndex The item ID or index in the collection.\n\t * @returns The requested item or `null` if such item does not exist.\n\t */ get(idOrIndex) {\n        let item;\n        if (typeof idOrIndex == 'string') {\n            item = this._itemMap.get(idOrIndex);\n        } else if (typeof idOrIndex == 'number') {\n            item = this._items[idOrIndex];\n        } else {\n            /**\n\t\t\t * An index or ID must be given.\n\t\t\t *\n\t\t\t * @error collection-get-invalid-arg\n\t\t\t */ throw new CKEditorError('collection-get-invalid-arg', this);\n        }\n        return item || null;\n    }\n    /**\n\t * Returns a Boolean indicating whether the collection contains an item.\n\t *\n\t * @param itemOrId The item or its ID in the collection.\n\t * @returns `true` if the collection contains the item, `false` otherwise.\n\t */ has(itemOrId) {\n        if (typeof itemOrId == 'string') {\n            return this._itemMap.has(itemOrId);\n        } else {\n            const idProperty = this._idProperty;\n            const id = itemOrId[idProperty];\n            return id && this._itemMap.has(id);\n        }\n    }\n    /**\n\t * Gets an index of an item in the collection.\n\t * When an item is not defined in the collection, the index will equal -1.\n\t *\n\t * @param itemOrId The item or its ID in the collection.\n\t * @returns The index of a given item.\n\t */ getIndex(itemOrId) {\n        let item;\n        if (typeof itemOrId == 'string') {\n            item = this._itemMap.get(itemOrId);\n        } else {\n            item = itemOrId;\n        }\n        return item ? this._items.indexOf(item) : -1;\n    }\n    /**\n\t * Removes an item from the collection.\n\t *\n\t * @param subject The item to remove, its ID or index in the collection.\n\t * @returns The removed item.\n\t * @fires remove\n\t * @fires change\n\t */ remove(subject) {\n        const [item, index] = this._remove(subject);\n        this.fire('change', {\n            added: [],\n            removed: [\n                item\n            ],\n            index\n        });\n        return item;\n    }\n    /**\n\t * Executes the callback for each item in the collection and composes an array or values returned by this callback.\n\t *\n\t * @typeParam U The result type of the callback.\n\t * @param callback\n\t * @param ctx Context in which the `callback` will be called.\n\t * @returns The result of mapping.\n\t */ map(callback, ctx) {\n        return this._items.map(callback, ctx);\n    }\n    /**\n\t * Performs the specified action for each item in the collection.\n\t *\n\t * @param ctx Context in which the `callback` will be called.\n\t */ forEach(callback, ctx) {\n        this._items.forEach(callback, ctx);\n    }\n    /**\n\t * Finds the first item in the collection for which the `callback` returns a true value.\n\t *\n\t * @param callback\n\t * @param ctx Context in which the `callback` will be called.\n\t * @returns The item for which `callback` returned a true value.\n\t */ find(callback, ctx) {\n        return this._items.find(callback, ctx);\n    }\n    /**\n\t * Returns an array with items for which the `callback` returned a true value.\n\t *\n\t * @param callback\n\t * @param ctx Context in which the `callback` will be called.\n\t * @returns The array with matching items.\n\t */ filter(callback, ctx) {\n        return this._items.filter(callback, ctx);\n    }\n    /**\n\t * Removes all items from the collection and destroys the binding created using\n\t * {@link #bindTo}.\n\t *\n\t * @fires remove\n\t * @fires change\n\t */ clear() {\n        if (this._bindToCollection) {\n            this.stopListening(this._bindToCollection);\n            this._bindToCollection = null;\n        }\n        const removedItems = Array.from(this._items);\n        while(this.length){\n            this._remove(0);\n        }\n        this.fire('change', {\n            added: [],\n            removed: removedItems,\n            index: 0\n        });\n    }\n    /**\n\t * Binds and synchronizes the collection with another one.\n\t *\n\t * The binding can be a simple factory:\n\t *\n\t * ```ts\n\t * class FactoryClass {\n\t * \tpublic label: string;\n\t *\n\t * \tconstructor( data: { label: string } ) {\n\t * \t\tthis.label = data.label;\n\t * \t}\n\t * }\n\t *\n\t * const source = new Collection<{ label: string }>( { idProperty: 'label' } );\n\t * const target = new Collection<FactoryClass>();\n\t *\n\t * target.bindTo( source ).as( FactoryClass );\n\t *\n\t * source.add( { label: 'foo' } );\n\t * source.add( { label: 'bar' } );\n\t *\n\t * console.log( target.length ); // 2\n\t * console.log( target.get( 1 ).label ); // 'bar'\n\t *\n\t * source.remove( 0 );\n\t * console.log( target.length ); // 1\n\t * console.log( target.get( 0 ).label ); // 'bar'\n\t * ```\n\t *\n\t * or the factory driven by a custom callback:\n\t *\n\t * ```ts\n\t * class FooClass {\n\t * \tpublic label: string;\n\t *\n\t * \tconstructor( data: { label: string } ) {\n\t * \t\tthis.label = data.label;\n\t * \t}\n\t * }\n\t *\n\t * class BarClass {\n\t * \tpublic label: string;\n\t *\n\t * \tconstructor( data: { label: string } ) {\n\t * \t\tthis.label = data.label;\n\t * \t}\n\t * }\n\t *\n\t * const source = new Collection<{ label: string }>( { idProperty: 'label' } );\n\t * const target = new Collection<FooClass | BarClass>();\n\t *\n\t * target.bindTo( source ).using( ( item ) => {\n\t * \tif ( item.label == 'foo' ) {\n\t * \t\treturn new FooClass( item );\n\t * \t} else {\n\t * \t\treturn new BarClass( item );\n\t * \t}\n\t * } );\n\t *\n\t * source.add( { label: 'foo' } );\n\t * source.add( { label: 'bar' } );\n\t *\n\t * console.log( target.length ); // 2\n\t * console.log( target.get( 0 ) instanceof FooClass ); // true\n\t * console.log( target.get( 1 ) instanceof BarClass ); // true\n\t * ```\n\t *\n\t * or the factory out of property name:\n\t *\n\t * ```ts\n\t * const source = new Collection<{ nested: { value: string } }>();\n\t * const target = new Collection<{ value: string }>();\n\t *\n\t * target.bindTo( source ).using( 'nested' );\n\t *\n\t * source.add( { nested: { value: 'foo' } } );\n\t * source.add( { nested: { value: 'bar' } } );\n\t *\n\t * console.log( target.length ); // 2\n\t * console.log( target.get( 0 ).value ); // 'foo'\n\t * console.log( target.get( 1 ).value ); // 'bar'\n\t * ```\n\t *\n\t * It's possible to skip specified items by returning null value:\n\t *\n\t * ```ts\n\t * const source = new Collection<{ hidden: boolean }>();\n\t * const target = new Collection<{ hidden: boolean }>();\n\t *\n\t * target.bindTo( source ).using( item => {\n\t * \tif ( item.hidden ) {\n\t * \t\treturn null;\n\t * \t}\n\t *\n\t * \treturn item;\n\t * } );\n\t *\n\t * source.add( { hidden: true } );\n\t * source.add( { hidden: false } );\n\t *\n\t * console.log( source.length ); // 2\n\t * console.log( target.length ); // 1\n\t * ```\n\t *\n\t * **Note**: {@link #clear} can be used to break the binding.\n\t *\n\t * @typeParam S The type of `externalCollection` element.\n\t * @param externalCollection A collection to be bound.\n\t * @returns The binding chain object.\n\t */ bindTo(externalCollection) {\n        if (this._bindToCollection) {\n            /**\n\t\t\t * The collection cannot be bound more than once.\n\t\t\t *\n\t\t\t * @error collection-bind-to-rebind\n\t\t\t */ throw new CKEditorError('collection-bind-to-rebind', this);\n        }\n        this._bindToCollection = externalCollection;\n        return {\n            as: (Class)=>{\n                this._setUpBindToBinding((item)=>new Class(item));\n            },\n            using: (callbackOrProperty)=>{\n                if (typeof callbackOrProperty == 'function') {\n                    this._setUpBindToBinding(callbackOrProperty);\n                } else {\n                    this._setUpBindToBinding((item)=>item[callbackOrProperty]);\n                }\n            }\n        };\n    }\n    /**\n\t * Finalizes and activates a binding initiated by {@link #bindTo}.\n\t *\n\t * @param factory A function which produces collection items.\n\t */ _setUpBindToBinding(factory) {\n        const externalCollection = this._bindToCollection;\n        // Adds the item to the collection once a change has been done to the external collection.\n        const addItem = (evt, externalItem, index)=>{\n            const isExternalBoundToThis = externalCollection._bindToCollection == this;\n            const externalItemBound = externalCollection._bindToInternalToExternalMap.get(externalItem);\n            // If an external collection is bound to this collection, which makes it a 2–way binding,\n            // and the particular external collection item is already bound, don't add it here.\n            // The external item has been created **out of this collection's item** and (re)adding it will\n            // cause a loop.\n            if (isExternalBoundToThis && externalItemBound) {\n                this._bindToExternalToInternalMap.set(externalItem, externalItemBound);\n                this._bindToInternalToExternalMap.set(externalItemBound, externalItem);\n            } else {\n                const item = factory(externalItem);\n                // When there is no item we need to remember skipped index first and then we can skip this item.\n                if (!item) {\n                    this._skippedIndexesFromExternal.push(index);\n                    return;\n                }\n                // Lets try to put item at the same index as index in external collection\n                // but when there are a skipped items in one or both collections we need to recalculate this index.\n                let finalIndex = index;\n                // When we try to insert item after some skipped items from external collection we need\n                // to include this skipped items and decrease index.\n                //\n                // For the following example:\n                // external -> [ 'A', 'B - skipped for internal', 'C - skipped for internal' ]\n                // internal -> [ A ]\n                //\n                // Another item is been added at the end of external collection:\n                // external.add( 'D' )\n                // external -> [ 'A', 'B - skipped for internal', 'C - skipped for internal', 'D' ]\n                //\n                // We can't just add 'D' to internal at the same index as index in external because\n                // this will produce empty indexes what is invalid:\n                // internal -> [ 'A', empty, empty, 'D' ]\n                //\n                // So we need to include skipped items and decrease index\n                // internal -> [ 'A', 'D' ]\n                for (const skipped of this._skippedIndexesFromExternal){\n                    if (index > skipped) {\n                        finalIndex--;\n                    }\n                }\n                // We need to take into consideration that external collection could skip some items from\n                // internal collection.\n                //\n                // For the following example:\n                // internal -> [ 'A', 'B - skipped for external', 'C - skipped for external' ]\n                // external -> [ A ]\n                //\n                // Another item is been added at the end of external collection:\n                // external.add( 'D' )\n                // external -> [ 'A', 'D' ]\n                //\n                // We need to include skipped items and place new item after them:\n                // internal -> [ 'A', 'B - skipped for external', 'C - skipped for external', 'D' ]\n                for (const skipped of externalCollection._skippedIndexesFromExternal){\n                    if (finalIndex >= skipped) {\n                        finalIndex++;\n                    }\n                }\n                this._bindToExternalToInternalMap.set(externalItem, item);\n                this._bindToInternalToExternalMap.set(item, externalItem);\n                this.add(item, finalIndex);\n                // After adding new element to internal collection we need update indexes\n                // of skipped items in external collection.\n                for(let i = 0; i < externalCollection._skippedIndexesFromExternal.length; i++){\n                    if (finalIndex <= externalCollection._skippedIndexesFromExternal[i]) {\n                        externalCollection._skippedIndexesFromExternal[i]++;\n                    }\n                }\n            }\n        };\n        // Load the initial content of the collection.\n        for (const externalItem of externalCollection){\n            addItem(null, externalItem, externalCollection.getIndex(externalItem));\n        }\n        // Synchronize the with collection as new items are added.\n        this.listenTo(externalCollection, 'add', addItem);\n        // Synchronize the with collection as new items are removed.\n        this.listenTo(externalCollection, 'remove', (evt, externalItem, index)=>{\n            const item = this._bindToExternalToInternalMap.get(externalItem);\n            if (item) {\n                this.remove(item);\n            }\n            // After removing element from external collection we need update/remove indexes\n            // of skipped items in internal collection.\n            this._skippedIndexesFromExternal = this._skippedIndexesFromExternal.reduce((result, skipped)=>{\n                if (index < skipped) {\n                    result.push(skipped - 1);\n                }\n                if (index > skipped) {\n                    result.push(skipped);\n                }\n                return result;\n            }, []);\n        });\n    }\n    /**\n\t * Returns an unique id property for a given `item`.\n\t *\n\t * The method will generate new id and assign it to the `item` if it doesn't have any.\n\t *\n\t * @param item Item to be added.\n\t */ _getItemIdBeforeAdding(item) {\n        const idProperty = this._idProperty;\n        let itemId;\n        if (idProperty in item) {\n            itemId = item[idProperty];\n            if (typeof itemId != 'string') {\n                /**\n\t\t\t\t * This item's ID should be a string.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-invalid-id\n\t\t\t\t */ throw new CKEditorError('collection-add-invalid-id', this);\n            }\n            if (this.get(itemId)) {\n                /**\n\t\t\t\t * This item already exists in the collection.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-item-already-exists\n\t\t\t\t */ throw new CKEditorError('collection-add-item-already-exists', this);\n            }\n        } else {\n            item[idProperty] = itemId = uid();\n        }\n        return itemId;\n    }\n    /**\n\t * Core {@link #remove} method implementation shared in other functions.\n\t *\n\t * In contrast this method **does not** fire the {@link #event:change} event.\n\t *\n\t * @param subject The item to remove, its id or index in the collection.\n\t * @returns Returns an array with the removed item and its index.\n\t * @fires remove\n\t */ _remove(subject) {\n        let index, id, item;\n        let itemDoesNotExist = false;\n        const idProperty = this._idProperty;\n        if (typeof subject == 'string') {\n            id = subject;\n            item = this._itemMap.get(id);\n            itemDoesNotExist = !item;\n            if (item) {\n                index = this._items.indexOf(item);\n            }\n        } else if (typeof subject == 'number') {\n            index = subject;\n            item = this._items[index];\n            itemDoesNotExist = !item;\n            if (item) {\n                id = item[idProperty];\n            }\n        } else {\n            item = subject;\n            id = item[idProperty];\n            index = this._items.indexOf(item);\n            itemDoesNotExist = index == -1 || !this._itemMap.get(id);\n        }\n        if (itemDoesNotExist) {\n            /**\n\t\t\t * Item not found.\n\t\t\t *\n\t\t\t * @error collection-remove-404\n\t\t\t */ throw new CKEditorError('collection-remove-404', this);\n        }\n        this._items.splice(index, 1);\n        this._itemMap.delete(id);\n        const externalItem = this._bindToInternalToExternalMap.get(item);\n        this._bindToInternalToExternalMap.delete(item);\n        this._bindToExternalToInternalMap.delete(externalItem);\n        this.fire('remove', item, index);\n        return [\n            item,\n            index\n        ];\n    }\n    /**\n\t * Iterable interface.\n\t */ [Symbol.iterator]() {\n        return this._items[Symbol.iterator]();\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/first\n */ /**\n * Returns first item of the given `iterator`.\n */ function first(iterator) {\n    const iteratorItem = iterator.next();\n    if (iteratorItem.done) {\n        return null;\n    }\n    return iteratorItem.value;\n}\n\n/**\n * Allows observing a group of DOM `Element`s or {@link module:ui/view~View view instances} whether at least one of them (or their child)\n * is focused.\n *\n * Used by the {@link module:core/editor/editor~Editor} in order to track whether the focus is still within the application,\n * or were used outside of its UI.\n *\n * **Note** `focus` and `blur` listeners use event capturing, so it is only needed to register wrapper `Element`\n * which contain other `focusable` elements. But note that this wrapper element has to be focusable too\n * (have e.g. `tabindex=\"-1\"`).\n *\n * Check out the {@glink framework/deep-dive/ui/focus-tracking \"Deep dive into focus tracking\"} guide to learn more.\n */ class FocusTracker extends /* #__PURE__ */ DomEmitterMixin(/* #__PURE__ */ ObservableMixin()) {\n    /**\n\t * List of registered DOM elements.\n\t *\n\t * @internal\n\t */ _elements = new Set();\n    /**\n\t * List of views with external focus trackers that contribute to the state of this focus tracker.\n\t *\n\t * @internal\n\t */ _externalViews = new Set();\n    /**\n\t * Asynchronous blur event timeout.\n\t */ _blurTimeout = null;\n    // @if CK_DEBUG_FOCUSTRACKER // public _label?: string;\n    constructor(){\n        super();\n        this.set('isFocused', false);\n        this.set('focusedElement', null);\n    // @if CK_DEBUG_FOCUSTRACKER // FocusTracker._instances.push( this );\n    }\n    /**\n\t * List of registered DOM elements.\n\t *\n\t * **Note**: The list does do not include elements from {@link #externalViews}.\n\t */ get elements() {\n        return Array.from(this._elements.values());\n    }\n    /**\n\t * List of external focusable views that contribute to the state of this focus tracker. See {@link #add} to learn more.\n\t */ get externalViews() {\n        return Array.from(this._externalViews.values());\n    }\n    /**\n\t * Starts tracking a specified DOM element or a {@link module:ui/view~View} instance.\n\t *\n\t * * If a DOM element is passed, the focus tracker listens to the `focus` and `blur` events on this element.\n\t * Tracked elements are listed in {@link #elements}.\n\t * * If a {@link module:ui/view~View} instance is passed that has a `FocusTracker` instance ({@link ~ViewWithFocusTracker}),\n\t * the external focus tracker's state ({@link #isFocused}, {@link #focusedElement}) starts contributing to the current tracker instance.\n\t * This allows for increasing the \"reach\" of a focus tracker instance, by connecting two or more focus trackers together when DOM\n\t * elements they track are located in different subtrees in DOM. External focus trackers are listed in {@link #externalViews}.\n\t * * If a {@link module:ui/view~View} instance is passed that has no `FocusTracker` (**not** a {@link ~ViewWithFocusTracker}),\n\t * its {@link module:ui/view~View#element} is used to track focus like any other DOM element.\n\t */ add(elementOrView) {\n        if (isElement(elementOrView)) {\n            this._addElement(elementOrView);\n        } else {\n            if (isViewWithFocusTracker(elementOrView)) {\n                this._addView(elementOrView);\n            } else {\n                if (!elementOrView.element) {\n                    /**\n\t\t\t\t\t * The {@link module:ui/view~View} added to the {@link module:utils/focustracker~FocusTracker} does not have an\n\t\t\t\t\t * {@link module:ui/view~View#element}. Make sure the view is {@link module:ui/view~View#render} before adding\n\t\t\t\t\t * it to the focus tracker.\n\t\t\t\t\t *\n\t\t\t\t\t * @error focustracker-add-view-missing-element\n\t\t\t\t\t */ throw new CKEditorError('focustracker-add-view-missing-element', {\n                        focusTracker: this,\n                        view: elementOrView\n                    });\n                }\n                this._addElement(elementOrView.element);\n            }\n        }\n    }\n    /**\n\t * Stops tracking focus in the specified DOM element or a {@link module:ui/view~View view instance}. See {@link #add} to learn more.\n\t */ remove(elementOrView) {\n        if (isElement(elementOrView)) {\n            this._removeElement(elementOrView);\n        } else {\n            if (isViewWithFocusTracker(elementOrView)) {\n                this._removeView(elementOrView);\n            } else {\n                // Assuming that if the view was successfully added, it must have come with an existing #element.\n                this._removeElement(elementOrView.element);\n            }\n        }\n    }\n    /**\n\t * Adds a DOM element to the focus tracker and starts listening to the `focus` and `blur` events on it.\n\t */ _addElement(element) {\n        if (this._elements.has(element)) {\n            /**\n\t\t\t * This element is already tracked by {@link module:utils/focustracker~FocusTracker}.\n\t\t\t *\n\t\t\t * @error focustracker-add-element-already-exist\n\t\t\t */ throw new CKEditorError('focustracker-add-element-already-exist', this);\n        }\n        this.listenTo(element, 'focus', ()=>{\n            // @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": Focus with useCapture on DOM element` );\n            const externalFocusedViewInSubtree = this.externalViews.find((view)=>isExternalViewSubtreeFocused(element, view));\n            if (externalFocusedViewInSubtree) {\n                this._focus(externalFocusedViewInSubtree.element);\n            } else {\n                this._focus(element);\n            }\n        }, {\n            useCapture: true\n        });\n        this.listenTo(element, 'blur', ()=>{\n            // @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": Blur with useCapture on DOM element` );\n            this._blur();\n        }, {\n            useCapture: true\n        });\n        this._elements.add(element);\n    }\n    /**\n\t * Removes a DOM element from the focus tracker.\n\t */ _removeElement(element) {\n        if (this._elements.has(element)) {\n            this.stopListening(element);\n            this._elements.delete(element);\n        }\n        if (element === this.focusedElement) {\n            this._blur();\n        }\n    }\n    /**\n\t * Adds an external {@link module:ui/view~View view instance} to this focus tracker and makes it contribute to this focus tracker's\n\t * state either by its `View#element` or by its `View#focusTracker` instance.\n\t */ _addView(view) {\n        if (view.element) {\n            this._addElement(view.element);\n        }\n        this.listenTo(view.focusTracker, 'change:focusedElement', ()=>{\n            // @if CK_DEBUG_FOCUSTRACKER // console.log(\n            // @if CK_DEBUG_FOCUSTRACKER // \t`\"${ getName( this ) }\": Related \"${ getName( view.focusTracker ) }\"#focusedElement = `,\n            // @if CK_DEBUG_FOCUSTRACKER // \tview.focusTracker.focusedElement\n            // @if CK_DEBUG_FOCUSTRACKER // );\n            if (view.focusTracker.focusedElement) {\n                if (view.element) {\n                    this._focus(view.element);\n                }\n            } else {\n                this._blur();\n            }\n        });\n        this._externalViews.add(view);\n    }\n    /**\n\t * Removes an external {@link module:ui/view~View view instance} from this focus tracker.\n\t */ _removeView(view) {\n        if (view.element) {\n            this._removeElement(view.element);\n        }\n        this.stopListening(view.focusTracker);\n        this._externalViews.delete(view);\n    }\n    /**\n\t * Destroys the focus tracker by:\n\t * - Disabling all event listeners attached to tracked elements or external views.\n\t * - Removing all tracked elements and views that were previously added.\n\t */ destroy() {\n        this.stopListening();\n        this._elements.clear();\n        this._externalViews.clear();\n        this.isFocused = false;\n        this.focusedElement = null;\n    }\n    /**\n\t * Stores currently focused element as {@link #focusedElement} and sets {@link #isFocused} `true`.\n\t */ _focus(element) {\n        // @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": _focus() on element`, element );\n        this._clearBlurTimeout();\n        this.focusedElement = element;\n        this.isFocused = true;\n    }\n    /**\n\t * Clears currently {@link #focusedElement} and sets {@link #isFocused} `false`.\n\t *\n\t * This method uses `setTimeout()` to change order of `blur` and `focus` events calls, ensuring that moving focus between\n\t * two elements within a single focus tracker's scope, will not cause `[ blurA, focusB ]` sequence but just `[ focusB ]`.\n\t * The former would cause a momentary change of `#isFocused` to `false` which is not desired because any logic listening to\n\t * a focus tracker state would experience UI flashes and glitches as the user focus travels across the UI.\n\t */ _blur() {\n        const isAnyElementFocused = this.elements.find((element)=>element.contains(document.activeElement));\n        // Avoid blurs originating from external FTs when the focus still remains in one of the #elements.\n        if (isAnyElementFocused) {\n            return;\n        }\n        const isAnyExternalViewFocused = this.externalViews.find((view)=>{\n            // Do not consider external views's focus trackers as focused if there's a blur timeout pending.\n            return view.focusTracker.isFocused && !view.focusTracker._blurTimeout;\n        });\n        // Avoid unnecessary DOM blurs coming from #elements when the focus still remains in one of #externalViews.\n        if (isAnyExternalViewFocused) {\n            return;\n        }\n        this._clearBlurTimeout();\n        this._blurTimeout = setTimeout(()=>{\n            // @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": Blur.` );\n            this.focusedElement = null;\n            this.isFocused = false;\n        }, 0);\n    }\n    /**\n\t * Clears the asynchronous blur event timeout on demand. See {@link #_blur} to learn more.\n\t */ _clearBlurTimeout() {\n        clearTimeout(this._blurTimeout);\n        this._blurTimeout = null;\n    }\n}\n/**\n * Checks whether a view is an instance of {@link ~ViewWithFocusTracker}.\n */ function isViewWithFocusTracker(view) {\n    return 'focusTracker' in view && view.focusTracker instanceof FocusTracker;\n}\nfunction isElement(value) {\n    return isElement$1(value);\n}\nfunction isExternalViewSubtreeFocused(subTreeRoot, view) {\n    if (isFocusedView(subTreeRoot, view)) {\n        return true;\n    }\n    return !!view.focusTracker.externalViews.find((view)=>isFocusedView(subTreeRoot, view));\n}\nfunction isFocusedView(subTreeRoot, view) {\n    // Note: You cannot depend on externalView.focusTracker.focusedElement because blurs are asynchronous and the value may\n    // be outdated when moving focus between two elements. Using document.activeElement instead.\n    return !!view.element && view.element.contains(document.activeElement) && subTreeRoot.contains(view.element);\n} // @if CK_DEBUG_FOCUSTRACKER // declare global {\n // @if CK_DEBUG_FOCUSTRACKER // \tinterface Window {\n // @if CK_DEBUG_FOCUSTRACKER // \t\tlogFocusTrackers: Function;\n // @if CK_DEBUG_FOCUSTRACKER // \t}\n // @if CK_DEBUG_FOCUSTRACKER // }\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // function getName( focusTracker: FocusTracker ): string {\n // @if CK_DEBUG_FOCUSTRACKER // \treturn focusTracker._label || 'Unknown';\n // @if CK_DEBUG_FOCUSTRACKER // }\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // function logState(\n // @if CK_DEBUG_FOCUSTRACKER // \tfocusTracker: FocusTracker,\n // @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog: Array<string> = [ 'isFocused', 'focusedElement' ]\n // @if CK_DEBUG_FOCUSTRACKER // ): string {\n // @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog.forEach( key => { console.log( `${ key }=`, focusTracker[ key ] ) } );\n // @if CK_DEBUG_FOCUSTRACKER // \tconsole.log( 'elements', focusTracker.elements );\n // @if CK_DEBUG_FOCUSTRACKER // \tconsole.log( 'externalViews', focusTracker.externalViews );\n // @if CK_DEBUG_FOCUSTRACKER // }\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // window.logFocusTrackers = (\n // @if CK_DEBUG_FOCUSTRACKER // \tfilter = () => true,\n // @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog: Array<string>\n // @if CK_DEBUG_FOCUSTRACKER // ): void => {\n // @if CK_DEBUG_FOCUSTRACKER // \tconsole.group( 'FocusTrackers' );\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // \tfor ( const focusTracker of FocusTracker._instances ) {\n // @if CK_DEBUG_FOCUSTRACKER // \t\tif ( filter( focusTracker ) ) {\n // @if CK_DEBUG_FOCUSTRACKER // \t\t\tconsole.group( `\"${ getName( focusTracker ) }\"` );\n // @if CK_DEBUG_FOCUSTRACKER // \t\t\tlogState( focusTracker, keysToLog );\n // @if CK_DEBUG_FOCUSTRACKER // \t\t\tconsole.groupEnd();\n // @if CK_DEBUG_FOCUSTRACKER // \t\t}\n // @if CK_DEBUG_FOCUSTRACKER // \t}\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // \tconsole.groupEnd();\n // @if CK_DEBUG_FOCUSTRACKER // };\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // window.logFocusTrackerTree = (\n // @if CK_DEBUG_FOCUSTRACKER // \trootFocusTracker: FocusTracker,\n // @if CK_DEBUG_FOCUSTRACKER // \tfilter = () => true,\n // @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog: Array<string>\n // @if CK_DEBUG_FOCUSTRACKER // ): void => {\n // @if CK_DEBUG_FOCUSTRACKER // \tconsole.group( 'FocusTrackers tree' );\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // \tlogBranch( rootFocusTracker, filter );\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // \tfunction logBranch( focusTracker, filter ) {\n // @if CK_DEBUG_FOCUSTRACKER // \t\tconsole.group( `\"${ getName( focusTracker ) }\"` );\n // @if CK_DEBUG_FOCUSTRACKER // \t\tlogState( focusTracker, keysToLog );\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // \t\tfor ( const externalView of focusTracker.externalViews ) {\n // @if CK_DEBUG_FOCUSTRACKER // \t\t\tif ( filter( externalView.focusTracker ) ) {\n // @if CK_DEBUG_FOCUSTRACKER // \t\t\t\tlogBranch( externalView.focusTracker, filter );\n // @if CK_DEBUG_FOCUSTRACKER // \t\t\t}\n // @if CK_DEBUG_FOCUSTRACKER // \t\t}\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // \t\tconsole.groupEnd();\n // @if CK_DEBUG_FOCUSTRACKER // \t}\n // @if CK_DEBUG_FOCUSTRACKER //\n // @if CK_DEBUG_FOCUSTRACKER // \tconsole.groupEnd();\n // @if CK_DEBUG_FOCUSTRACKER // };\n\n/**\n * Keystroke handler allows registering callbacks for given keystrokes.\n *\n * The most frequent use of this class is through the {@link module:core/editor/editor~Editor#keystrokes `editor.keystrokes`}\n * property. It allows listening to keystrokes executed in the editing view:\n *\n * ```ts\n * editor.keystrokes.set( 'Ctrl+A', ( keyEvtData, cancel ) => {\n * \tconsole.log( 'Ctrl+A has been pressed' );\n * \tcancel();\n * } );\n * ```\n *\n * However, this utility class can be used in various part of the UI. For instance, a certain {@link module:ui/view~View}\n * can use it like this:\n *\n * ```ts\n * class MyView extends View {\n * \tconstructor() {\n * \t\tthis.keystrokes = new KeystrokeHandler();\n *\n * \t\tthis.keystrokes.set( 'tab', handleTabKey );\n * \t}\n *\n * \trender() {\n * \t\tsuper.render();\n *\n * \t\tthis.keystrokes.listenTo( this.element );\n * \t}\n * }\n * ```\n *\n * That keystroke handler will listen to `keydown` events fired in this view's main element.\n *\n */ class KeystrokeHandler {\n    /**\n\t * Listener used to listen to events for easier keystroke handler destruction.\n\t */ _listener;\n    /**\n\t * Creates an instance of the keystroke handler.\n\t */ constructor(){\n        this._listener = new (DomEmitterMixin())();\n    }\n    /**\n\t * Starts listening for `keydown` events from a given emitter.\n\t */ listenTo(emitter) {\n        // The #_listener works here as a kind of dispatcher. It groups the events coming from the same\n        // keystroke so the listeners can be attached to them with different priorities.\n        //\n        // E.g. all the keystrokes with the `keyCode` of 42 coming from the `emitter` are propagated\n        // as a `_keydown:42` event by the `_listener`. If there's a callback created by the `set`\n        // method for this 42 keystroke, it listens to the `_listener#_keydown:42` event only and interacts\n        // only with other listeners of this particular event, thus making it possible to prioritize\n        // the listeners and safely cancel execution, when needed. Instead of duplicating the Emitter logic,\n        // the KeystrokeHandler re–uses it to do its job.\n        this._listener.listenTo(emitter, 'keydown', (evt, keyEvtData)=>{\n            this._listener.fire('_keydown:' + getCode(keyEvtData), keyEvtData);\n        });\n    }\n    /**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * @param keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param callback A function called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a helper function to call both `preventDefault()` and `stopPropagation()` on the underlying event.\n\t * @param options Additional options.\n\t */ set(keystroke, callback, options = {}) {\n        const keyCode = parseKeystroke(keystroke);\n        const priority = options.priority;\n        // Execute the passed callback on KeystrokeHandler#_keydown.\n        // TODO: https://github.com/ckeditor/ckeditor5-utils/issues/144\n        this._listener.listenTo(this._listener, '_keydown:' + keyCode, (evt, keyEvtData)=>{\n            if (options.filter && !options.filter(keyEvtData)) {\n                return;\n            }\n            callback(keyEvtData, ()=>{\n                // Stop the event in the DOM: no listener in the web page\n                // will be triggered by this event.\n                keyEvtData.preventDefault();\n                keyEvtData.stopPropagation();\n                // Stop the event in the KeystrokeHandler: no more callbacks\n                // will be executed for this keystroke.\n                evt.stop();\n            });\n            // Mark this keystroke as handled by the callback. See: #press.\n            evt.return = true;\n        }, {\n            priority\n        });\n    }\n    /**\n\t * Triggers a keystroke handler for a specified key combination, if such a keystroke was {@link #set defined}.\n\t *\n\t * @param keyEvtData Key event data.\n\t * @returns Whether the keystroke was handled.\n\t */ press(keyEvtData) {\n        return !!this._listener.fire('_keydown:' + getCode(keyEvtData), keyEvtData);\n    }\n    /**\n\t * Stops listening to `keydown` events from the given emitter.\n\t */ stopListening(emitter) {\n        this._listener.stopListening(emitter);\n    }\n    /**\n\t * Destroys the keystroke handler.\n\t */ destroy() {\n        this.stopListening();\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/objecttomap\n */ /**\n * Transforms object to map.\n *\n * ```ts\n * const map = objectToMap( { 'foo': 1, 'bar': 2 } );\n * map.get( 'foo' ); // 1\n * ```\n *\n * **Note**: For mixed data (`Object` or `Iterable`) there's a dedicated {@link module:utils/tomap~toMap} function.\n *\n * @param obj Object to transform.\n * @returns Map created from object.\n */ function objectToMap(obj) {\n    const map = new Map();\n    for(const key in obj){\n        map.set(key, obj[key]);\n    }\n    return map;\n}\n\n/**\n * Transforms object or iterable to map. Iterable needs to be in the format acceptable by the `Map` constructor.\n *\n * ```ts\n * map = toMap( { 'foo': 1, 'bar': 2 } );\n * map = toMap( [ [ 'foo', 1 ], [ 'bar', 2 ] ] );\n * map = toMap( anotherMap );\n * ```\n *\n * @param data Object or iterable to transform.\n * @returns Map created from data.\n */ function toMap(data) {\n    if (isIterable(data)) {\n        return new Map(data);\n    } else {\n        return objectToMap(data);\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/wait\n */ /**\n * Returns a promise that is resolved after the specified time.\n *\n * @param timeout The time in milliseconds to wait.\n * @param options.signal A signal to abort the waiting.\n */ function wait(timeout, options = {}) {\n    return new Promise((resolve, reject)=>{\n        const signal = options.signal || new AbortController().signal;\n        signal.throwIfAborted();\n        const timer = setTimeout(timeoutHandler, timeout);\n        signal.addEventListener('abort', abortHandler, {\n            once: true\n        });\n        function timeoutHandler() {\n            signal.removeEventListener('abort', abortHandler);\n            resolve();\n        }\n        function abortHandler() {\n            clearTimeout(timer);\n            reject(signal.reason);\n        }\n    });\n}\n\n/**\n * Tries calling the given callback until it sucessfully resolves.\n *\n * If the callback fails `maxRetries` times, the returned promise is rejected with the last error.\n *\n * @typeParam TResult The result of a successful callback invocation.\n * @param callback The function to call until it succeeds.\n * @param options.maxRetries Maximum number of retries.\n * @param options.retryDelay The time in milliseconds between attempts. By default it implements exponential back-off policy.\n * @param options.signal The signal to abort further retries. The callback itself is not aborted automatically.\n */ async function retry(callback, options = {}) {\n    const { maxAttempts = 4, retryDelay = exponentialDelay(), signal = new AbortController().signal } = options;\n    signal.throwIfAborted();\n    for(let attempt = 0;; attempt++){\n        try {\n            return await callback();\n        } catch (err) {\n            const isLast = attempt + 1 >= maxAttempts;\n            if (isLast) {\n                throw err;\n            }\n        }\n        await wait(retryDelay(attempt), {\n            signal\n        });\n    }\n}\n/**\n * Creates a function that calculates exponential back-off delay. Pass it as `options.retryDelay` to {@link ~retry}.\n *\n * @param options.delay Base delay between invocations. Defaults to 1s.\n * @param options.factor How much to increase the delay. Defaults to 2x.\n * @param options.maxDelay Maximum timeout. Even if higher timeout is calculated, it cannot get higher than this value. Default to 10s.\n * @returns The function calculating the delay.\n */ function exponentialDelay(options = {}) {\n    const { delay = 1000, factor = 2, maxDelay = 10000 } = options;\n    return (attempt)=>Math.min(factor ** attempt * delay, maxDelay);\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/splicearray\n */ const BIG_CHUNK_SIZE = 10000;\n/**\n * Splices one array into another. To be used instead of `Array.prototype.splice` as the latter may\n * throw \"Maximum call stack size exceeded\" when passed huge number of items to insert.\n *\n * Note: in contrary to Array.splice, this function does not modify the original `target`.\n *\n * ```ts\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 0, 0 );\t// [ 3, 4, 1, 2 ]\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 1 );\t// [ 1, 3, 4 ]\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 0 );\t// [ 1, 3, 4, 2 ]\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 2, 0 );\t// [ 1, 2, 3, 4 ]\n * spliceArray( [ 1, 2 ], [],       0, 1 );\t// [ 2 ]\n * ```\n *\n * @param target Array to be spliced.\n * @param source Array of elements to be inserted to target.\n * @param start Index at which nodes should be inserted/removed.\n * @param count Number of items.\n *\n * @returns New spliced array.\n */ function spliceArray(target, source, start, count) {\n    // In case of performance problems, see: https://github.com/ckeditor/ckeditor5/pull/12429/files#r965850568\n    if (Math.max(source.length, target.length) > BIG_CHUNK_SIZE) {\n        return target.slice(0, start).concat(source).concat(target.slice(start + count, target.length));\n    } else {\n        const newTarget = Array.from(target);\n        newTarget.splice(start, count, ...source);\n        return newTarget;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module utils/delay\n */ /* globals setTimeout, clearTimeout */ /**\n * Returns a function wrapper that will trigger a function after a specified wait time.\n * The timeout can be canceled by calling the cancel function on the returned wrapped function.\n *\n * @param func The function to wrap.\n * @param wait The timeout in ms.\n */ function delay(func, wait) {\n    let timer;\n    function delayed(...args) {\n        delayed.cancel();\n        timer = setTimeout(()=>func(...args), wait);\n    }\n    delayed.cancel = ()=>{\n        clearTimeout(timer);\n    };\n    return delayed;\n}\n\n/**\n * Checks whether the given string contains information that allows you to verify the license status.\n *\n * @param token The string to check.\n * @returns String that represents the state of given `token` parameter.\n */ function verifyLicense(token) {\n    // This function implements naive and partial license key check mechanism,\n    // used only to decide whether to show or hide the \"Powered by CKEditor\" logo.\n    //\n    // You can read the reasoning behind showing the logo to unlicensed (GPL) users\n    // in this thread: https://github.com/ckeditor/ckeditor5/issues/14082.\n    //\n    // We firmly believe in the values behind creating open-source software, even when that\n    // means keeping the license verification logic open for everyone to see.\n    //\n    // Please keep this code intact. Thank you for your understanding.\n    function oldTokenCheck(token) {\n        if (token.length >= 40 && token.length <= 255) {\n            return 'VALID';\n        } else {\n            return 'INVALID';\n        }\n    }\n    // TODO: issue ci#3175\n    if (!token) {\n        return 'INVALID';\n    }\n    let decryptedData = '';\n    try {\n        decryptedData = atob(token);\n    } catch (e) {\n        return 'INVALID';\n    }\n    const splittedDecryptedData = decryptedData.split('-');\n    const firstElement = splittedDecryptedData[0];\n    const secondElement = splittedDecryptedData[1];\n    if (!secondElement) {\n        return oldTokenCheck(token);\n    }\n    try {\n        atob(secondElement);\n    } catch (e) {\n        try {\n            atob(firstElement);\n            if (!atob(firstElement).length) {\n                return oldTokenCheck(token);\n            }\n        } catch (e) {\n            return oldTokenCheck(token);\n        }\n    }\n    if (firstElement.length < 40 || firstElement.length > 255) {\n        return 'INVALID';\n    }\n    let decryptedSecondElement = '';\n    try {\n        atob(firstElement);\n        decryptedSecondElement = atob(secondElement);\n    } catch (e) {\n        return 'INVALID';\n    }\n    if (decryptedSecondElement.length !== 8) {\n        return 'INVALID';\n    }\n    const year = Number(decryptedSecondElement.substring(0, 4));\n    const monthIndex = Number(decryptedSecondElement.substring(4, 6)) - 1;\n    const day = Number(decryptedSecondElement.substring(6, 8));\n    const date = new Date(year, monthIndex, day);\n    if (date < releaseDate || isNaN(Number(date))) {\n        return 'INVALID';\n    }\n    return 'VALID';\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * Set of utils to handle unicode characters.\n *\n * @module utils/unicode\n */ /**\n * Checks whether given `character` is a combining mark.\n *\n * @param character Character to check.\n */ function isCombiningMark(character) {\n    // eslint-disable-next-line no-misleading-character-class\n    return !!character && character.length == 1 && /[\\u0300-\\u036f\\u1ab0-\\u1aff\\u1dc0-\\u1dff\\u20d0-\\u20ff\\ufe20-\\ufe2f]/.test(character);\n}\n/**\n * Checks whether given `character` is a high half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param character Character to check.\n */ function isHighSurrogateHalf(character) {\n    return !!character && character.length == 1 && /[\\ud800-\\udbff]/.test(character);\n}\n/**\n * Checks whether given `character` is a low half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param character Character to check.\n */ function isLowSurrogateHalf(character) {\n    return !!character && character.length == 1 && /[\\udc00-\\udfff]/.test(character);\n}\n/**\n * Checks whether given offset in a string is inside a surrogate pair (between two surrogate halves).\n *\n * @param string String to check.\n * @param offset Offset to check.\n */ function isInsideSurrogatePair(string, offset) {\n    return isHighSurrogateHalf(string.charAt(offset - 1)) && isLowSurrogateHalf(string.charAt(offset));\n}\n/**\n * Checks whether given offset in a string is between base character and combining mark or between two combining marks.\n *\n * @param string String to check.\n * @param offset Offset to check.\n */ function isInsideCombinedSymbol(string, offset) {\n    return isCombiningMark(string.charAt(offset));\n}\nconst EMOJI_PATTERN = /* #__PURE__ */ buildEmojiRegexp();\n/**\n * Checks whether given offset in a string is inside multi-character emoji sequence.\n *\n * @param string String to check.\n * @param offset Offset to check.\n */ function isInsideEmojiSequence(string, offset) {\n    const matches = String(string).matchAll(EMOJI_PATTERN);\n    return Array.from(matches).some((match)=>match.index < offset && offset < match.index + match[0].length);\n}\nfunction buildEmojiRegexp() {\n    const parts = [\n        // Emoji Tag Sequence (ETS)\n        /\\p{Emoji}[\\u{E0020}-\\u{E007E}]+\\u{E007F}/u,\n        // Emoji Keycap Sequence\n        /\\p{Emoji}\\u{FE0F}?\\u{20E3}/u,\n        // Emoji Presentation Sequence\n        /\\p{Emoji}\\u{FE0F}/u,\n        // Single-Character Emoji / Emoji Modifier Sequence\n        /(?=\\p{General_Category=Other_Symbol})\\p{Emoji}\\p{Emoji_Modifier}*/u\n    ];\n    const flagSequence = /\\p{Regional_Indicator}{2}/u.source;\n    const emoji = '(?:' + parts.map((part)=>part.source).join('|') + ')';\n    const sequence = `${flagSequence}|${emoji}(?:\\u{200D}${emoji})*`;\n    return new RegExp(sequence, 'ug');\n}\n\nexport { CKEditorError, Collection, Config, DomEmitterMixin, ElementReplacer, EmitterMixin, EventInfo, FocusTracker, KeystrokeHandler, Locale, ObservableMixin, Rect, ResizeObserver, abortableDebounce, compareArrays, count, createElement, delay, diff, diffToChanges, env, exponentialDelay, fastDiff, findClosestScrollableAncestor, first, getAncestors, getBorderWidths, getCode, getDataFromElement, getEnvKeystrokeText, getLanguageDirection, getLocalizedArrowKeyCodeDirection, getOptimalPosition, getRangeFromMouseEvent, global, indexOf, insertAt, insertToPriorityArray, isArrowKeyCode, isCombiningMark, isComment, isForwardArrowKeyCode, isHighSurrogateHalf, isInsideCombinedSymbol, isInsideEmojiSequence, isInsideSurrogatePair, isIterable, isLowSurrogateHalf, isNode, isRange, isText, isValidAttributeName, isViewWithFocusTracker, isVisible, keyCodes, logError, logWarning, mix, parseKeystroke, priorities, releaseDate, remove, retry, scrollAncestorsToShowTarget, scrollViewportToShowTarget, setDataInElement, spliceArray, toArray, toMap, toUnit, uid, verifyLicense, version, wait };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* globals window, document */\n\n/**\n * @module utils/dom/global\n */\n\n// This interface exists to make our API pages more readable.\n/**\n * A helper (module) giving an access to the global DOM objects such as `window` and `document`.\n */\nexport interface GlobalType {\n\treadonly window: Window & typeof globalThis;\n\treadonly document: Document;\n}\n\n/**\n * A helper (module) giving an access to the global DOM objects such as `window` and\n * `document`. Accessing these objects using this helper allows easy and bulletproof\n * testing, i.e. stubbing native properties:\n *\n * ```ts\n * import { global } from 'ckeditor5/utils';\n *\n * // This stub will work for any code using global module.\n * testUtils.sinon.stub( global, 'window', {\n * \tinnerWidth: 10000\n * } );\n *\n * console.log( global.window.innerWidth );\n * ```\n */\nlet globalVar: GlobalType; // named globalVar instead of global: https://github.com/ckeditor/ckeditor5/issues/12971\n\n// In some environments window and document API might not be available.\ntry {\n\tglobalVar = { window, document };\n} catch ( e ) {\n\t// It's not possible to mock a window object to simulate lack of a window object without writing extremely convoluted code.\n\t/* istanbul ignore next -- @preserve */\n\n\t// Let's cast it to not change module's API.\n\t// We only handle this so loading editor in environments without window and document doesn't fail.\n\t// For better DX we shouldn't introduce mixed types and require developers to check the type manually.\n\t// This module should not be used on purpose in any environment outside browser.\n\tglobalVar = { window: {} as any, document: {} as any };\n}\n\nexport default globalVar;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* globals navigator:false */\n\n/**\n * @module utils/env\n */\n\nimport global from './dom/global.js';\n\n/**\n * Safely returns `userAgent` from browser's navigator API in a lower case.\n * If navigator API is not available it will return an empty string.\n */\nexport function getUserAgent(): string {\n\t// In some environments navigator API might not be available.\n\ttry {\n\t\treturn navigator.userAgent.toLowerCase();\n\t} catch ( e ) {\n\t\treturn '';\n\t}\n}\n\nconst userAgent = /* #__PURE__ */ getUserAgent();\n\n// This interface exists to make our API pages more readable.\n/**\n * A namespace containing environment and browser information.\n */\nexport interface EnvType {\n\n\t/**\n\t * Indicates that the application is running on Macintosh.\n\t */\n\treadonly isMac: boolean;\n\n\t/**\n\t * Indicates that the application is running on Windows.\n\t */\n\treadonly isWindows: boolean;\n\n\t/**\n\t * Indicates that the application is running in Firefox (Gecko).\n\t */\n\treadonly isGecko: boolean;\n\n\t/**\n\t * Indicates that the application is running in Safari.\n\t */\n\treadonly isSafari: boolean;\n\n\t/**\n\t * Indicates that the application is running in iOS.\n\t */\n\treadonly isiOS: boolean;\n\n\t/**\n\t * Indicates that the application is running on Android mobile device.\n\t */\n\treadonly isAndroid: boolean;\n\n\t/**\n\t * Indicates that the application is running in a browser using the Blink engine.\n\t */\n\treadonly isBlink: boolean;\n\n\t/**\n\t * Indicates that the user agent has enabled a forced colors mode (e.g. Windows High Contrast mode).\n\t *\n\t * Note that the value of this property is evaluated each time it is accessed, and it may change over time, if the environment\n\t * settings have changed.\n\t */\n\treadonly isMediaForcedColors: boolean;\n\n\t/**\n\t * Indicates that \"prefer reduced motion\" browser setting is active.\n\t *\n\t * Note that the value of this property is evaluated each time it is accessed, and it may change over time, if the environment\n\t * settings have changed.\n\t */\n\treadonly isMotionReduced: boolean;\n\n\t/**\n\t * Environment features information.\n\t */\n\treadonly features: EnvFeaturesType;\n}\n\nexport interface EnvFeaturesType {\n\n\t/**\n\t * Indicates that the environment supports ES2018 Unicode property escapes — like `\\p{P}` or `\\p{L}`.\n\t * More information about unicode properties might be found\n\t * [in Unicode Standard Annex #44](https://www.unicode.org/reports/tr44/#GC_Values_Table).\n\t */\n\treadonly isRegExpUnicodePropertySupported: boolean;\n}\n\n/**\n * A namespace containing environment and browser information.\n */\nconst env: EnvType = {\n\tisMac: /* #__PURE__ */ isMac( userAgent ),\n\n\tisWindows: /* #__PURE__ */ isWindows( userAgent ),\n\n\tisGecko: /* #__PURE__ */ isGecko( userAgent ),\n\n\tisSafari: /* #__PURE__ */ isSafari( userAgent ),\n\n\tisiOS: /* #__PURE__ */ isiOS( userAgent ),\n\n\tisAndroid: /* #__PURE__ */ isAndroid( userAgent ),\n\n\tisBlink: /* #__PURE__ */ isBlink( userAgent ),\n\n\tget isMediaForcedColors() {\n\t\treturn isMediaForcedColors();\n\t},\n\n\tget isMotionReduced() {\n\t\treturn isMotionReduced();\n\t},\n\n\tfeatures: {\n\t\tisRegExpUnicodePropertySupported: /* #__PURE__ */ isRegExpUnicodePropertySupported()\n\t}\n};\n\nexport default env;\n\n/**\n * Checks if User Agent represented by the string is running on Macintosh.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is running on Macintosh or not.\n */\nexport function isMac( userAgent: string ): boolean {\n\treturn userAgent.indexOf( 'macintosh' ) > -1;\n}\n\n/**\n * Checks if User Agent represented by the string is running on Windows.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is running on Windows or not.\n */\nexport function isWindows( userAgent: string ): boolean {\n\treturn userAgent.indexOf( 'windows' ) > -1;\n}\n\n/**\n * Checks if User Agent represented by the string is Firefox (Gecko).\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Firefox or not.\n */\nexport function isGecko( userAgent: string ): boolean {\n\treturn !!userAgent.match( /gecko\\/\\d+/ );\n}\n\n/**\n * Checks if User Agent represented by the string is Safari.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Safari or not.\n */\nexport function isSafari( userAgent: string ): boolean {\n\treturn userAgent.indexOf( ' applewebkit/' ) > -1 && userAgent.indexOf( 'chrome' ) === -1;\n}\n\n/**\n * Checks if User Agent represented by the string is running in iOS.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is running in iOS or not.\n */\nexport function isiOS( userAgent: string ): boolean {\n\t// \"Request mobile site\" || \"Request desktop site\".\n\treturn !!userAgent.match( /iphone|ipad/i ) || ( isMac( userAgent ) && navigator.maxTouchPoints > 0 );\n}\n\n/**\n * Checks if User Agent represented by the string is Android mobile device.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Safari or not.\n */\nexport function isAndroid( userAgent: string ): boolean {\n\treturn userAgent.indexOf( 'android' ) > -1;\n}\n\n/**\n * Checks if User Agent represented by the string is Blink engine.\n *\n * @param userAgent **Lowercase** `navigator.userAgent` string.\n * @returns Whether User Agent is Blink engine or not.\n */\nexport function isBlink( userAgent: string ): boolean {\n\t// The Edge browser before switching to the Blink engine used to report itself as Chrome (and \"Edge/\")\n\t// but after switching to the Blink it replaced \"Edge/\" with \"Edg/\".\n\treturn userAgent.indexOf( 'chrome/' ) > -1 && userAgent.indexOf( 'edge/' ) < 0;\n}\n\n/**\n * Checks if the current environment supports ES2018 Unicode properties like `\\p{P}` or `\\p{L}`.\n * More information about unicode properties might be found\n * [in Unicode Standard Annex #44](https://www.unicode.org/reports/tr44/#GC_Values_Table).\n */\nexport function isRegExpUnicodePropertySupported(): boolean {\n\tlet isSupported = false;\n\n\t// Feature detection for Unicode properties. Added in ES2018. Currently Firefox does not support it.\n\t// See https://github.com/ckeditor/ckeditor5-mention/issues/44#issuecomment-487002174.\n\n\ttry {\n\t\t// Usage of regular expression literal cause error during build (ckeditor/ckeditor5-dev#534).\n\t\tisSupported = 'ć'.search( new RegExp( '[\\\\p{L}]', 'u' ) ) === 0;\n\t} catch ( error ) {\n\t\t// Firefox throws a SyntaxError when the group is unsupported.\n\t}\n\n\treturn isSupported;\n}\n\n/**\n * Checks if the user agent has enabled a forced colors mode (e.g. Windows High Contrast mode).\n *\n * Returns `false` in environments where `window` global object is not available.\n */\nexport function isMediaForcedColors(): boolean {\n\treturn global.window.matchMedia ? global.window.matchMedia( '(forced-colors: active)' ).matches : false;\n}\n\n/**\n * Checks if the user enabled \"prefers reduced motion\" setting in browser.\n *\n * Returns `false` in environments where `window` global object is not available.\n */\nexport function isMotionReduced(): boolean {\n\treturn global.window.matchMedia ? global.window.matchMedia( '(prefers-reduced-motion)' ).matches : false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type { DiffResult } from './diff.js';\nimport type { Change } from './difftochanges.js';\n\n/**\n * @module utils/fastdiff\n */\n\n/**\n * Finds positions of the first and last change in the given string/array and generates a set of changes:\n *\n * ```ts\n * fastDiff( '12a', '12xyza' );\n * // [ { index: 2, type: 'insert', values: [ 'x', 'y', 'z' ] } ]\n *\n * fastDiff( '12a', '12aa' );\n * // [ { index: 3, type: 'insert', values: [ 'a' ] } ]\n *\n * fastDiff( '12xyza', '12a' );\n * // [ { index: 2, type: 'delete', howMany: 3 } ]\n *\n * fastDiff( [ '1', '2', 'a', 'a' ], [ '1', '2', 'a' ] );\n * // [ { index: 3, type: 'delete', howMany: 1 } ]\n *\n * fastDiff( [ '1', '2', 'a', 'b', 'c', '3' ], [ '2', 'a', 'b' ] );\n * // [ { index: 0, type: 'insert', values: [ '2', 'a', 'b' ] }, { index: 3, type: 'delete', howMany: 6 } ]\n * ```\n *\n * Passed arrays can contain any type of data, however to compare them correctly custom comparator function\n * should be passed as a third parameter:\n *\n * ```ts\n * fastDiff( [ { value: 1 }, { value: 2 } ], [ { value: 1 }, { value: 3 } ], ( a, b ) => {\n * \treturn a.value === b.value;\n * } );\n * // [ { index: 1, type: 'insert', values: [ { value: 3 } ] }, { index: 2, type: 'delete', howMany: 1 } ]\n * ```\n *\n * The resulted set of changes can be applied to the input in order to transform it into the output, for example:\n *\n * ```ts\n * let input = '12abc3';\n * const output = '2ab';\n * const changes = fastDiff( input, output );\n *\n * changes.forEach( change => {\n * \tif ( change.type == 'insert' ) {\n * \t\tinput = input.substring( 0, change.index ) + change.values.join( '' ) + input.substring( change.index );\n * \t} else if ( change.type == 'delete' ) {\n * \t\tinput = input.substring( 0, change.index ) + input.substring( change.index + change.howMany );\n * \t}\n * } );\n *\n * // input equals output now\n * ```\n *\n * or in case of arrays:\n *\n * ```ts\n * let input = [ '1', '2', 'a', 'b', 'c', '3' ];\n * const output = [ '2', 'a', 'b' ];\n * const changes = fastDiff( input, output );\n *\n * changes.forEach( change => {\n * \tif ( change.type == 'insert' ) {\n * \t\tinput = input.slice( 0, change.index ).concat( change.values, input.slice( change.index ) );\n * \t} else if ( change.type == 'delete' ) {\n * \t\tinput = input.slice( 0, change.index ).concat( input.slice( change.index + change.howMany ) );\n * \t}\n * } );\n *\n * // input equals output now\n * ```\n *\n * By passing `true` as the fourth parameter (`atomicChanges`) the output of this function will become compatible with\n * the {@link module:utils/diff~diff `diff()`} function:\n *\n * ```ts\n * fastDiff( '12a', '12xyza', undefined, true );\n * // [ 'equal', 'equal', 'insert', 'insert', 'insert', 'equal' ]\n * ```\n *\n * The default output format of this function is compatible with the output format of\n * {@link module:utils/difftochanges~diffToChanges `diffToChanges()`}. The `diffToChanges()` input format is, in turn,\n * compatible with the output of {@link module:utils/diff~diff `diff()`}:\n *\n * ```ts\n * const a = '1234';\n * const b = '12xyz34';\n *\n * // Both calls will return the same results (grouped changes format).\n * fastDiff( a, b );\n * diffToChanges( diff( a, b ) );\n *\n * // Again, both calls will return the same results (atomic changes format).\n * fastDiff( a, b, undefined, true );\n * diff( a, b );\n * ```\n *\n * @typeParam T The type of array elements.\n * @typeParam AtomicChanges The type of `atomicChanges` parameter (selects the result type).\n * @param a Input array or string.\n * @param b Input array or string.\n * @param cmp Optional function used to compare array values, by default `===` (strict equal operator) is used.\n * @param atomicChanges Whether an array of `inset|delete|equal` operations should\n * be returned instead of changes set. This makes this function compatible with {@link module:utils/diff~diff `diff()`}.\n * Defaults to `false`.\n * @returns Array of changes. The elements are either {@link module:utils/diff~DiffResult} or {@link module:utils/difftochanges~Change},\n * depending on `atomicChanges` parameter.\n */\nexport default function fastDiff<T, AtomicChanges extends boolean = false>(\n\ta: ArrayLike<T>,\n\tb: ArrayLike<T>,\n\tcmp?: ( a: T, b: T ) => boolean,\n\tatomicChanges?: AtomicChanges\n): Array<AtomicChanges extends true ? DiffResult : Change<T>> {\n\t// Set the comparator function.\n\tcmp = cmp || function( a, b ) {\n\t\treturn a === b;\n\t};\n\n\t// Convert the string (or any array-like object - eg. NodeList) to an array by using the slice() method because,\n\t// unlike Array.from(), it returns array of UTF-16 code units instead of the code points of a string.\n\t// One code point might be a surrogate pair of two code units. All text offsets are expected to be in code units.\n\t// See ckeditor/ckeditor5#3147.\n\t//\n\t// We need to make sure here that fastDiff() works identical to diff().\n\tconst arrayA: Array<T> = Array.isArray( a ) ? a : Array.prototype.slice.call( a );\n\tconst arrayB: Array<T> = Array.isArray( b ) ? b : Array.prototype.slice.call( b );\n\n\t// Find first and last change.\n\tconst changeIndexes = findChangeBoundaryIndexes( arrayA, arrayB, cmp );\n\n\t// Transform into changes array.\n\tconst result = atomicChanges ?\n\t\tchangeIndexesToAtomicChanges( changeIndexes, arrayB.length ) :\n\t\tchangeIndexesToChanges( arrayB, changeIndexes );\n\n\treturn result as any;\n}\n\n/**\n * Finds position of the first and last change in the given arrays. For example:\n *\n * ```ts\n * const indexes = findChangeBoundaryIndexes( [ '1', '2', '3', '4' ], [ '1', '3', '4', '2', '4' ] );\n * console.log( indexes ); // { firstIndex: 1, lastIndexOld: 3, lastIndexNew: 4 }\n * ```\n *\n * The above indexes means that in the first array the modified part is `1[23]4` and in the second array it is `1[342]4`.\n * Based on such indexes, array with `insert`/`delete` operations which allows transforming first value into the second one\n * can be generated.\n */\nfunction findChangeBoundaryIndexes<T>( arr1: ReadonlyArray<T>, arr2: ReadonlyArray<T>, cmp: ( a: T, b: T ) => boolean ): ChangeIndexes {\n\t// Find the first difference between passed values.\n\tconst firstIndex = findFirstDifferenceIndex( arr1, arr2, cmp );\n\n\t// If arrays are equal return -1 indexes object.\n\tif ( firstIndex === -1 ) {\n\t\treturn { firstIndex: -1, lastIndexOld: -1, lastIndexNew: -1 };\n\t}\n\n\t// Remove the common part of each value and reverse them to make it simpler to find the last difference between them.\n\tconst oldArrayReversed = cutAndReverse( arr1, firstIndex );\n\tconst newArrayReversed = cutAndReverse( arr2, firstIndex );\n\n\t// Find the first difference between reversed values.\n\t// It should be treated as \"how many elements from the end the last difference occurred\".\n\t//\n\t// For example:\n\t//\n\t// \t\t\t\tinitial\t->\tafter cut\t-> reversed:\n\t// oldValue:\t'321ba'\t->\t'21ba'\t\t-> 'ab12'\n\t// newValue:\t'31xba'\t->\t'1xba'\t\t-> 'abx1'\n\t// lastIndex:\t\t\t\t\t\t\t-> 2\n\t//\n\t// So the last change occurred two characters from the end of the arrays.\n\tconst lastIndex = findFirstDifferenceIndex( oldArrayReversed, newArrayReversed, cmp );\n\n\t// Use `lastIndex` to calculate proper offset, starting from the beginning (`lastIndex` kind of starts from the end).\n\tconst lastIndexOld = arr1.length - lastIndex;\n\tconst lastIndexNew = arr2.length - lastIndex;\n\n\treturn { firstIndex, lastIndexOld, lastIndexNew };\n}\n\n/**\n * Returns a first index on which given arrays differ. If both arrays are the same, -1 is returned.\n */\nfunction findFirstDifferenceIndex<T>( arr1: ReadonlyArray<T>, arr2: ReadonlyArray<T>, cmp: ( a: T, b: T ) => boolean ): number {\n\tfor ( let i = 0; i < Math.max( arr1.length, arr2.length ); i++ ) {\n\t\tif ( arr1[ i ] === undefined || arr2[ i ] === undefined || !cmp( arr1[ i ], arr2[ i ] ) ) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1; // Return -1 if arrays are equal.\n}\n\n/**\n * Returns a copy of the given array with `howMany` elements removed starting from the beginning and in reversed order.\n *\n * @param arr Array to be processed.\n * @param howMany How many elements from array beginning to remove.\n * @returns Shortened and reversed array.\n */\nfunction cutAndReverse<T>( arr: ReadonlyArray<T>, howMany: number ): Array<T> {\n\treturn arr.slice( howMany ).reverse();\n}\n\n/**\n * Generates changes array based on change indexes from `findChangeBoundaryIndexes` function. This function will\n * generate array with 0 (no changes), 1 (deletion or insertion) or 2 records (insertion and deletion).\n *\n * @param newArray New array for which change indexes were calculated.\n * @param changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.\n * @returns Array of changes compatible with {@link module:utils/difftochanges~diffToChanges} format.\n */\nfunction changeIndexesToChanges<T>( newArray: ReadonlyArray<T>, changeIndexes: ChangeIndexes ): Array<Change<T>> {\n\tconst result: Array<Change<T>> = [];\n\tconst { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;\n\n\t// Order operations as 'insert', 'delete' array to keep compatibility with {@link module:utils/difftochanges~diffToChanges}\n\t// in most cases. However, 'diffToChanges' does not stick to any order so in some cases\n\t// (for example replacing '12345' with 'abcd') it will generate 'delete', 'insert' order.\n\tif ( lastIndexNew - firstIndex > 0 ) {\n\t\tresult.push( {\n\t\t\tindex: firstIndex,\n\t\t\ttype: 'insert',\n\t\t\tvalues: newArray.slice( firstIndex, lastIndexNew )\n\t\t} );\n\t}\n\n\tif ( lastIndexOld - firstIndex > 0 ) {\n\t\tresult.push( {\n\t\t\tindex: firstIndex + ( lastIndexNew - firstIndex ), // Increase index of what was inserted.\n\t\t\ttype: 'delete',\n\t\t\thowMany: lastIndexOld - firstIndex\n\t\t} );\n\t}\n\n\treturn result;\n}\n\n/**\n * Generates array with set `equal|insert|delete` operations based on change indexes from `findChangeBoundaryIndexes` function.\n *\n * @param changeIndexes Change indexes object from `findChangeBoundaryIndexes` function.\n * @param newLength Length of the new array on which `findChangeBoundaryIndexes` calculated change indexes.\n * @returns Array of changes compatible with {@link module:utils/diff~diff} format.\n */\nfunction changeIndexesToAtomicChanges( changeIndexes: ChangeIndexes, newLength: number ): Array<DiffResult> {\n\tconst { firstIndex, lastIndexOld, lastIndexNew } = changeIndexes;\n\n\t// No changes.\n\tif ( firstIndex === -1 ) {\n\t\treturn Array( newLength ).fill( 'equal' );\n\t}\n\n\tlet result: Array<DiffResult> = [];\n\n\tif ( firstIndex > 0 ) {\n\t\tresult = result.concat( Array( firstIndex ).fill( 'equal' ) );\n\t}\n\n\tif ( lastIndexNew - firstIndex > 0 ) {\n\t\tresult = result.concat( Array( lastIndexNew - firstIndex ).fill( 'insert' ) );\n\t}\n\n\tif ( lastIndexOld - firstIndex > 0 ) {\n\t\tresult = result.concat( Array( lastIndexOld - firstIndex ).fill( 'delete' ) );\n\t}\n\n\tif ( lastIndexNew < newLength ) {\n\t\tresult = result.concat( Array( newLength - lastIndexNew ).fill( 'equal' ) );\n\t}\n\n\treturn result;\n}\n\n/**\n * Indexes of the first and the last change in the given arrays.\n */\ninterface ChangeIndexes {\n\n\t/**\n\t * Index of the first change in both values (always the same for both).\n\t */\n\tfirstIndex: number;\n\n\t/**\n\t * Index of the last common value in `arr1`.\n\t */\n\tlastIndexOld: number;\n\n\t/**\n\t * Index of the last common value in `arr2`.\n\t */\n\tlastIndexNew: number;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/diff\n */\n\nimport fastDiff from './fastdiff.js';\n\n// The following code is based on the \"O(NP) Sequence Comparison Algorithm\"\n// by Sun Wu, Udi Manber, Gene Myers, Webb Miller.\n\n/**\n * Calculates the difference between two arrays or strings producing an array containing a list of changes\n * necessary to transform input into output.\n *\n * ```ts\n * diff( 'aba', 'acca' ); // [ 'equal', 'insert', 'insert', 'delete', 'equal' ]\n * ```\n *\n * This function is based on the \"O(NP) Sequence Comparison Algorithm\" by Sun Wu, Udi Manber, Gene Myers, Webb Miller.\n * Unfortunately, while it gives the most precise results, its to complex for longer strings/arrow (above 200 items).\n * Therefore, `diff()` automatically switches to {@link module:utils/fastdiff~fastDiff `fastDiff()`} when detecting\n * such a scenario. The return formats of both functions are identical.\n *\n * @param a Input array or string.\n * @param b Output array or string.\n * @param cmp Optional function used to compare array values, by default === is used.\n * @returns Array of changes.\n */\nexport default function diff<T>(\n\ta: ArrayLike<T>,\n\tb: ArrayLike<T>,\n\tcmp?: ( a: T, b: T ) => boolean\n): Array<DiffResult> {\n\t// Set the comparator function.\n\tcmp = cmp || function( a, b ) {\n\t\treturn a === b;\n\t};\n\n\tconst aLength = a.length;\n\tconst bLength = b.length;\n\n\t// Perform `fastDiff` for longer strings/arrays (see #269).\n\tif ( aLength > 200 || bLength > 200 || aLength + bLength > 300 ) {\n\t\treturn diff.fastDiff( a, b, cmp, true );\n\t}\n\n\t// Temporary action type statics.\n\tlet _insert: DiffResult, _delete: DiffResult;\n\n\t// Swapped the arrays to use the shorter one as the first one.\n\tif ( bLength < aLength ) {\n\t\tconst tmp = a;\n\n\t\ta = b;\n\t\tb = tmp;\n\n\t\t// We swap the action types as well.\n\t\t_insert = 'delete';\n\t\t_delete = 'insert';\n\t} else {\n\t\t_insert = 'insert';\n\t\t_delete = 'delete';\n\t}\n\n\tconst m = a.length;\n\tconst n = b.length;\n\tconst delta = n - m;\n\n\t// Edit scripts, for each diagonal.\n\tconst es: { [ k: number ]: Array<DiffResult> } = {};\n\t// Furthest points, the furthest y we can get on each diagonal.\n\tconst fp: { [ k: number]: number } = {};\n\n\tfunction snake( k: number ): number {\n\t\t// We use -1 as an alternative below to handle initial values ( instead of filling the fp with -1 first ).\n\t\t// Furthest points (y) on the diagonal below k.\n\t\tconst y1 = ( fp[ k - 1 ] !== undefined ? fp[ k - 1 ] : -1 ) + 1;\n\t\t// Furthest points (y) on the diagonal above k.\n\t\tconst y2 = fp[ k + 1 ] !== undefined ? fp[ k + 1 ] : -1;\n\t\t// The way we should go to get further.\n\t\tconst dir = y1 > y2 ? -1 : 1;\n\n\t\t// Clone previous changes array (if any).\n\t\tif ( es[ k + dir ] ) {\n\t\t\tes[ k ] = es[ k + dir ].slice( 0 );\n\t\t}\n\n\t\t// Create changes array.\n\t\tif ( !es[ k ] ) {\n\t\t\tes[ k ] = [];\n\t\t}\n\n\t\t// Push the action.\n\t\tes[ k ].push( y1 > y2 ? _insert : _delete );\n\n\t\t// Set the beginning coordinates.\n\t\tlet y = Math.max( y1, y2 );\n\t\tlet x = y - k;\n\n\t\t// Traverse the diagonal as long as the values match.\n\t\twhile ( x < m && y < n && cmp!( a[ x ], b[ y ] ) ) {\n\t\t\tx++;\n\t\t\ty++;\n\t\t\t// Push no change action.\n\t\t\tes[ k ].push( 'equal' );\n\t\t}\n\n\t\treturn y;\n\t}\n\n\tlet p = 0;\n\tlet k;\n\n\t// Traverse the graph until we reach the end of the longer string.\n\tdo {\n\t\t// Updates furthest points and edit scripts for diagonals below delta.\n\t\tfor ( k = -p; k < delta; k++ ) {\n\t\t\tfp[ k ] = snake( k );\n\t\t}\n\n\t\t// Updates furthest points and edit scripts for diagonals above delta.\n\t\tfor ( k = delta + p; k > delta; k-- ) {\n\t\t\tfp[ k ] = snake( k );\n\t\t}\n\n\t\t// Updates furthest point and edit script for the delta diagonal.\n\t\t// note that the delta diagonal is the one which goes through the sink (m, n).\n\t\tfp[ delta ] = snake( delta );\n\n\t\tp++;\n\t} while ( fp[ delta ] !== n );\n\n\t// Return the final list of edit changes.\n\t// We remove the first item that represents the action for the injected nulls.\n\treturn es[ delta ].slice( 1 );\n}\n\n// Store the API in static property to easily overwrite it in tests.\n// Too bad dependency injection does not work in Webpack + ES 6 (const) + Babel.\ndiff.fastDiff = fastDiff;\n\n/**\n * The element of the result of {@link module:utils/diff~diff} function.\n */\nexport type DiffResult = 'equal' | 'insert' | 'delete';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type { DiffResult } from './diff.js';\n\n/**\n * @module utils/difftochanges\n */\n\n/**\n * Creates a set of changes which need to be applied to the input in order to transform\n * it into the output. This function can be used with strings or arrays.\n *\n * ```ts\n * const input = Array.from( 'abc' );\n * const output = Array.from( 'xaby' );\n * const changes = diffToChanges( diff( input, output ), output );\n *\n * changes.forEach( change => {\n * \tif ( change.type == 'insert' ) {\n * \t\tinput.splice( change.index, 0, ...change.values );\n * \t} else if ( change.type == 'delete' ) {\n * \t\tinput.splice( change.index, change.howMany );\n * \t}\n * } );\n *\n * input.join( '' ) == output.join( '' ); // -> true\n * ```\n *\n * @typeParam T The type of output array element.\n * @param diff Result of {@link module:utils/diff~diff}.\n * @param output The string or array which was passed as diff's output.\n * @returns Set of changes (insert or delete) which need to be applied to the input\n * in order to transform it into the output.\n */\nexport default function diffToChanges<T>( diff: ReadonlyArray<DiffResult>, output: ArrayLike<T> ): Array<Change<T>> {\n\tconst changes: Array<Change<T>> = [];\n\tlet index = 0;\n\tlet lastOperation: Change<T> | null = null;\n\n\tdiff.forEach( change => {\n\t\tif ( change == 'equal' ) {\n\t\t\tpushLast();\n\n\t\t\tindex++;\n\t\t} else if ( change == 'insert' ) {\n\t\t\tif ( lastOperation && lastOperation.type == 'insert' ) {\n\t\t\t\tlastOperation.values.push( output[ index ] );\n\t\t\t} else {\n\t\t\t\tpushLast();\n\n\t\t\t\tlastOperation = {\n\t\t\t\t\ttype: 'insert',\n\t\t\t\t\tindex,\n\t\t\t\t\tvalues: [ output[ index ] ]\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tindex++;\n\t\t} else /* if ( change == 'delete' ) */ {\n\t\t\tif ( lastOperation && lastOperation.type == 'delete' ) {\n\t\t\t\tlastOperation.howMany++;\n\t\t\t} else {\n\t\t\t\tpushLast();\n\n\t\t\t\tlastOperation = {\n\t\t\t\t\ttype: 'delete',\n\t\t\t\t\tindex,\n\t\t\t\t\thowMany: 1\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t} );\n\n\tpushLast();\n\n\treturn changes;\n\n\tfunction pushLast() {\n\t\tif ( lastOperation ) {\n\t\t\tchanges.push( lastOperation );\n\t\t\tlastOperation = null;\n\t\t}\n\t}\n}\n\n/**\n * An object describing insertion change.\n *\n * @typeParam T The type of output array element.\n */\nexport interface InsertChange<T> {\n\ttype: 'insert';\n\tindex: number;\n\tvalues: Array<T>;\n}\n\n/**\n * An object describing deletion change.\n */\nexport interface DeleteChange {\n\ttype: 'delete';\n\tindex: number;\n\thowMany: number;\n}\n\n/**\n * The element of the result of {@link module:utils/difftochanges~diffToChanges} function.\n *\n * @typeParam T The type of output array element.\n */\nexport type Change<T> = InsertChange<T> | DeleteChange;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/mix\n */\n\n/**\n * Copies enumerable properties and symbols from the objects given as 2nd+ parameters to the\n * prototype of first object (a constructor).\n *\n * ```\n * class Editor {\n * \t...\n * }\n *\n * const SomeMixin = {\n * \ta() {\n * \t\treturn 'a';\n * \t}\n * };\n *\n * mix( Editor, SomeMixin, ... );\n *\n * new Editor().a(); // -> 'a'\n * ```\n *\n * Note: Properties which already exist in the base class will not be overriden.\n *\n * @deprecated Use mixin pattern, see: https://www.typescriptlang.org/docs/handbook/mixins.html.\n * @param baseClass Class which prototype will be extended.\n * @param mixins Objects from which to get properties.\n */\nexport default function mix( baseClass: Function, ...mixins: Array<object> ): void {\n\tmixins.forEach( mixin => {\n\t\tconst propertyNames: Array<string | symbol> = Object.getOwnPropertyNames( mixin );\n\t\tconst propertySymbols = Object.getOwnPropertySymbols( mixin );\n\n\t\tpropertyNames.concat( propertySymbols ).forEach( key => {\n\t\t\tif ( key in baseClass.prototype ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( typeof mixin == 'function' && ( key == 'length' || key == 'name' || key == 'prototype' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sourceDescriptor = Object.getOwnPropertyDescriptor( mixin, key )!;\n\t\t\tsourceDescriptor.enumerable = false;\n\n\t\t\tObject.defineProperty( baseClass.prototype, key, sourceDescriptor );\n\t\t} );\n\t} );\n}\n\n/**\n * Helper type that represents constructor creating given objects. Can be used as a type constraint.\n *\n * ```ts\n * // The function accepts any class constructor.\n * function MyFunction<Ctor extends Constructor>( ctor: Ctor ) {\n * \t// ...\n * }\n *\n * // The function accepts any class constructor of type derived from `MyBase`.\n * function MyFunction<Ctor extends Constructor<MyBase>>( ctor: Ctor ) {\n * \t// ...\n * }\n * ```\n */\nexport type Constructor<Instance = object> = abstract new ( ...args: Array<any> ) => Instance;\n\n/**\n * Helper type that creates constructor types from a base class and a mixin interface.\n *\n * ```ts\n * interface MyMixinInterface {\n * \tmixinMethod(): void;\n * }\n *\n * function MyMixin<Base extends Constructor>( base: Base ): Mixed<Base, MyMixinInterface> {\n * \t// ...\n * }\n *\n * class BaseClass {\n * \tbaseMethod(): void {\n * \t\t// ...\n * \t}\n * }\n *\n * const MixedClass = MyMixin( BaseClass );\n *\n * // Contains both `mixinMethod()` and `baseMethod()`.\n * const myObject = new MixedClass();\n * myObject.mixinMethod();\n * myObject.baseMethod();\n * ```\n *\n * @typeParam Base A type of constructor of a class to apply mixin to.\n * @typeParam Mixin An interface representing mixin.\n */\nexport type Mixed<Base extends Constructor, Mixin extends object> = {\n\tnew ( ...args: ConstructorParameters<Base> ): Mixin & InstanceType<Base>;\n\tprototype: Mixin & InstanceType<Base>;\n} & {\n\t// Include all static fields from Base.\n\t[ K in keyof Base ]: Base[ K ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/spy\n */\n\n/**\n * Creates a spy function (ala Sinon.js) that can be used to inspect call to it.\n *\n * The following are the present features:\n *\n * * spy.called: property set to `true` if the function has been called at least once.\n *\n * @returns The spy function.\n */\nfunction spy(): { (): void; called?: boolean } {\n\treturn function spy() {\n\t\t( spy as any ).called = true;\n\t};\n}\n\nexport default spy;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/eventinfo\n */\n\nimport spy from './spy.js';\n\n/**\n * The event object passed to event callbacks. It is used to provide information about the event as well as a tool to\n * manipulate it.\n */\nexport default class EventInfo<TName extends string = string, TReturn = unknown> {\n\t/**\n\t * The object that fired the event.\n\t */\n\tpublic readonly source: object;\n\n\t/**\n\t * The event name.\n\t */\n\tpublic readonly name: TName;\n\n\t/**\n\t * Path this event has followed. See {@link module:utils/emittermixin~Emitter#delegate}.\n\t */\n\tpublic path: Array<object>;\n\n\t/**\n\t * Stops the event emitter to call further callbacks for this event interaction.\n\t */\n\tpublic readonly stop: { (): void; called?: boolean };\n\n\t/**\n\t * Removes the current callback from future interactions of this event.\n\t */\n\tpublic readonly off: { (): void; called?: boolean };\n\n\t/**\n\t * The value which will be returned by {@link module:utils/emittermixin~Emitter#fire}.\n\t *\n\t * It's `undefined` by default and can be changed by an event listener:\n\t *\n\t * ```ts\n\t * dataController.fire( 'getSelectedContent', ( evt ) => {\n\t * \t// This listener will make `dataController.fire( 'getSelectedContent' )`\n\t * \t// always return an empty DocumentFragment.\n\t * \tevt.return = new DocumentFragment();\n\t *\n\t * \t// Make sure no other listeners are executed.\n\t * \tevt.stop();\n\t * } );\n\t * ```\n\t */\n\tpublic return: TReturn | undefined;\n\n\t/**\n\t * @param source The emitter.\n\t * @param name The event name.\n\t */\n\tconstructor( source: object, name: TName ) {\n\t\tthis.source = source;\n\t\tthis.name = name;\n\t\tthis.path = [];\n\n\t\t// The following methods are defined in the constructor because they must be re-created per instance.\n\t\tthis.stop = spy();\n\t\tthis.off = spy();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/uid\n */\n\n/**\n * A hash table of hex numbers to avoid using toString() in uid() which is costly.\n * [ '00', '01', '02', ..., 'fe', 'ff' ]\n */\nconst HEX_NUMBERS = new Array( 256 ).fill( '' )\n\t.map( ( _, index ) => ( '0' + ( index ).toString( 16 ) ).slice( -2 ) );\n\n/**\n * Returns a unique id. The id starts with an \"e\" character and a randomly generated string of\n * 32 alphanumeric characters.\n *\n * **Note**: The characters the unique id is built from correspond to the hex number notation\n * (from \"0\" to \"9\", from \"a\" to \"f\"). In other words, each id corresponds to an \"e\" followed\n * by 16 8-bit numbers next to each other.\n *\n * @returns An unique id string.\n */\nexport default function uid(): string {\n\t// Let's create some positive random 32bit integers first.\n\tconst [ r1, r2, r3, r4 ] = crypto.getRandomValues( new Uint32Array( 4 ) );\n\n\t// Make sure that id does not start with number.\n\treturn 'e' +\n\t\tHEX_NUMBERS[ r1 >> 0 & 0xFF ] +\n\t\tHEX_NUMBERS[ r1 >> 8 & 0xFF ] +\n\t\tHEX_NUMBERS[ r1 >> 16 & 0xFF ] +\n\t\tHEX_NUMBERS[ r1 >> 24 & 0xFF ] +\n\t\tHEX_NUMBERS[ r2 >> 0 & 0xFF ] +\n\t\tHEX_NUMBERS[ r2 >> 8 & 0xFF ] +\n\t\tHEX_NUMBERS[ r2 >> 16 & 0xFF ] +\n\t\tHEX_NUMBERS[ r2 >> 24 & 0xFF ] +\n\t\tHEX_NUMBERS[ r3 >> 0 & 0xFF ] +\n\t\tHEX_NUMBERS[ r3 >> 8 & 0xFF ] +\n\t\tHEX_NUMBERS[ r3 >> 16 & 0xFF ] +\n\t\tHEX_NUMBERS[ r3 >> 24 & 0xFF ] +\n\t\tHEX_NUMBERS[ r4 >> 0 & 0xFF ] +\n\t\tHEX_NUMBERS[ r4 >> 8 & 0xFF ] +\n\t\tHEX_NUMBERS[ r4 >> 16 & 0xFF ] +\n\t\tHEX_NUMBERS[ r4 >> 24 & 0xFF ];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/priorities\n */\n\n/**\n * String representing a priority value.\n */\nexport type PriorityString = 'highest' | 'high' | 'normal' | 'low' | 'lowest' | number;\n\n// This interface exists to make our API pages more readable.\n/**\n * Provides group of constants to use instead of hardcoding numeric priority values.\n */\nexport interface PrioritiesType {\n\n\t/**\n\t * Converts a string with priority name to it's numeric value. If `Number` is given, it just returns it.\n\t *\n\t * @param priority Priority to convert.\n\t * @returns Converted priority.\n\t */\n\tget( priority?: PriorityString ): number;\n\n\treadonly highest: number;\n\treadonly high: number;\n\treadonly normal: number;\n\treadonly low: number;\n\treadonly lowest: number;\n}\n\n/**\n * Provides group of constants to use instead of hardcoding numeric priority values.\n */\nconst priorities: PrioritiesType = {\n\tget( priority: PriorityString = 'normal' ): number {\n\t\tif ( typeof priority != 'number' ) {\n\t\t\treturn this[ priority ] || this.normal;\n\t\t} else {\n\t\t\treturn priority;\n\t\t}\n\t},\n\n\thighest: 100000,\n\thigh: 1000,\n\tnormal: 0,\n\tlow: -1000,\n\tlowest: -100000\n};\n\nexport default priorities;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport priorities, { type PriorityString } from './priorities.js';\n\n/**\n * @module utils/inserttopriorityarray\n */\n\n/**\n * The priority object descriptor.\n *\n * ```ts\n * const objectWithPriority = {\n * \tpriority: 'high'\n * }\n * ```\n */\nexport interface ObjectWithPriority {\n\n\t/**\n\t * Priority of the object.\n\t */\n\tpriority: PriorityString;\n}\n\n/**\n * Inserts any object with priority at correct index by priority so registered objects are always sorted from highest to lowest priority.\n *\n * @param objects Array of objects with priority to insert object to.\n * @param objectToInsert Object with `priority` property.\n */\nexport default function insertToPriorityArray<T extends ObjectWithPriority>( objects: Array<T>, objectToInsert: T ): void {\n\tconst priority = priorities.get( objectToInsert.priority );\n\n\tfor ( let i = 0; i < objects.length; i++ ) {\n\t\tif ( priorities.get( objects[ i ].priority ) < priority ) {\n\t\t\tobjects.splice( i, 0, objectToInsert );\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\tobjects.push( objectToInsert );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/ckeditorerror\n */\n\n/* globals console */\n\n/**\n * URL to the documentation with error codes.\n */\nexport const DOCUMENTATION_URL = 'https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html';\n\n/**\n * The CKEditor error class.\n *\n * You should throw `CKEditorError` when:\n *\n * * An unexpected situation occurred and the editor (most probably) will not work properly. Such exception will be handled\n * by the {@link module:watchdog/watchdog~Watchdog watchdog} (if it is integrated),\n * * If the editor is incorrectly integrated or the editor API is used in the wrong way. This way you will give\n * feedback to the developer as soon as possible. Keep in mind that for common integration issues which should not\n * stop editor initialization (like missing upload adapter, wrong name of a toolbar component) we use\n * {@link module:utils/ckeditorerror~logWarning `logWarning()`} and\n * {@link module:utils/ckeditorerror~logError `logError()`}\n * to improve developers experience and let them see the a working editor as soon as possible.\n *\n * ```ts\n * /**\n *  * Error thrown when a plugin cannot be loaded due to JavaScript errors, lack of plugins with a given name, etc.\n *  *\n *  * @error plugin-load\n *  * @param pluginName The name of the plugin that could not be loaded.\n *  * @param moduleName The name of the module which tried to load this plugin.\n *  *\\/\n * throw new CKEditorError( 'plugin-load', {\n * \tpluginName: 'foo',\n * \tmoduleName: 'bar'\n * } );\n * ```\n */\nexport default class CKEditorError extends Error {\n\t/**\n\t * A context of the error by which the Watchdog is able to determine which editor crashed.\n\t */\n\tpublic readonly context: object | null | undefined;\n\n\t/**\n\t * The additional error data passed to the constructor. Undefined if none was passed.\n\t */\n\tpublic readonly data?: object;\n\n\t/**\n\t * Creates an instance of the CKEditorError class.\n\t *\n\t * @param errorName The error id in an `error-name` format. A link to this error documentation page will be added\n\t * to the thrown error's `message`.\n\t * @param context A context of the error by which the {@link module:watchdog/watchdog~Watchdog watchdog}\n\t * is able to determine which editor crashed. It should be an editor instance or a property connected to it. It can be also\n\t * a `null` value if the editor should not be restarted in case of the error (e.g. during the editor initialization).\n\t * The error context should be checked using the `areConnectedThroughProperties( editor, context )` utility\n\t * to check if the object works as the context.\n\t * @param data Additional data describing the error. A stringified version of this object\n\t * will be appended to the error message, so the data are quickly visible in the console. The original\n\t * data object will also be later available under the {@link #data} property.\n\t */\n\tconstructor( errorName: string, context?: object | null, data?: object ) {\n\t\tsuper( getErrorMessage( errorName, data ) );\n\n\t\tthis.name = 'CKEditorError';\n\t\tthis.context = context;\n\t\tthis.data = data;\n\t}\n\n\t/**\n\t * Checks if the error is of the `CKEditorError` type.\n\t */\n\tpublic is( type: string ): boolean {\n\t\treturn type === 'CKEditorError';\n\t}\n\n\t/**\n\t * A utility that ensures that the thrown error is a {@link module:utils/ckeditorerror~CKEditorError} one.\n\t * It is useful when combined with the {@link module:watchdog/watchdog~Watchdog} feature, which can restart the editor in case\n\t * of a {@link module:utils/ckeditorerror~CKEditorError} error.\n\t *\n\t * @param err The error to rethrow.\n\t * @param context An object connected through properties with the editor instance. This context will be used\n\t * by the watchdog to verify which editor should be restarted.\n\t */\n\tpublic static rethrowUnexpectedError( err: Error, context: object ): never {\n\t\tif ( ( err as any ).is && ( err as any ).is( 'CKEditorError' ) ) {\n\t\t\tthrow err;\n\t\t}\n\n\t\t/**\n\t\t * An unexpected error occurred inside the CKEditor 5 codebase. This error will look like the original one\n\t\t * to make the debugging easier.\n\t\t *\n\t\t * This error is only useful when the editor is initialized using the {@link module:watchdog/watchdog~Watchdog} feature.\n\t\t * In case of such error (or any {@link module:utils/ckeditorerror~CKEditorError} error) the watchdog should restart the editor.\n\t\t *\n\t\t * @error unexpected-error\n\t\t */\n\t\tconst error = new CKEditorError( err.message, context );\n\n\t\t// Restore the original stack trace to make the error look like the original one.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/5595 for more details.\n\t\terror.stack = err.stack;\n\n\t\tthrow error;\n\t}\n}\n\n/**\n * Logs a warning to the console with a properly formatted message and adds a link to the documentation.\n * Use whenever you want to log a warning to the console.\n *\n * ```ts\n * /**\n *  * There was a problem processing the configuration of the toolbar. The item with the given\n *  * name does not exist, so it was omitted when rendering the toolbar.\n *  *\n *  * @error toolbarview-item-unavailable\n *  * @param {String} name The name of the component.\n *  *\\/\n * logWarning( 'toolbarview-item-unavailable', { name } );\n * ```\n *\n * See also {@link module:utils/ckeditorerror~CKEditorError} for an explanation when to throw an error and when to log\n * a warning or an error to the console.\n *\n * @param errorName The error name to be logged.\n * @param data Additional data to be logged.\n */\nexport function logWarning( errorName: string, data?: object ): void {\n\tconsole.warn( ...formatConsoleArguments( errorName, data ) );\n}\n\n/**\n * Logs an error to the console with a properly formatted message and adds a link to the documentation.\n * Use whenever you want to log an error to the console.\n *\n * ```ts\n * /**\n *  * There was a problem processing the configuration of the toolbar. The item with the given\n *  * name does not exist, so it was omitted when rendering the toolbar.\n *  *\n *  * @error toolbarview-item-unavailable\n *  * @param {String} name The name of the component.\n *  *\\/\n *  logError( 'toolbarview-item-unavailable', { name } );\n * ```\n *\n * **Note**: In most cases logging a warning using {@link module:utils/ckeditorerror~logWarning} is enough.\n *\n * See also {@link module:utils/ckeditorerror~CKEditorError} for an explanation when to use each method.\n *\n * @param errorName The error name to be logged.\n * @param data Additional data to be logged.\n */\nexport function logError( errorName: string, data?: object ): void {\n\tconsole.error( ...formatConsoleArguments( errorName, data ) );\n}\n\n/**\n * Returns formatted link to documentation message.\n */\nfunction getLinkToDocumentationMessage( errorName: string ): string {\n\treturn `\\nRead more: ${ DOCUMENTATION_URL }#error-${ errorName }`;\n}\n\n/**\n * Returns formatted error message.\n */\nfunction getErrorMessage( errorName: string, data?: object ): string {\n\tconst processedObjects = new WeakSet();\n\tconst circularReferencesReplacer = ( key: string, value: unknown ) => {\n\t\tif ( typeof value === 'object' && value !== null ) {\n\t\t\tif ( processedObjects.has( value ) ) {\n\t\t\t\treturn `[object ${ value.constructor.name }]`;\n\t\t\t}\n\n\t\t\tprocessedObjects.add( value );\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tconst stringifiedData = data ? ` ${ JSON.stringify( data, circularReferencesReplacer ) }` : '';\n\tconst documentationLink = getLinkToDocumentationMessage( errorName );\n\n\treturn errorName + stringifiedData + documentationLink;\n}\n\n/**\n * Returns formatted console error arguments.\n */\nfunction formatConsoleArguments( errorName: string, data?: object ): Array<unknown> {\n\tconst documentationMessage = getLinkToDocumentationMessage( errorName );\n\n\treturn data ? [ errorName, data, documentationMessage ] : [ errorName, documentationMessage ];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/version\n */\n\nimport CKEditorError from './ckeditorerror.js';\n\nconst version = '43.3.1';\n\nexport default version;\n\n// The second argument is not a month. It is `monthIndex` and starts from `0`.\nexport const releaseDate = new Date( 2024, 10, 6 );\n\ndeclare global {\n\t// eslint-disable-next-line no-var\n\tvar CKEDITOR_VERSION: string;\n}\n\n/* istanbul ignore next -- @preserve */\nif ( globalThis.CKEDITOR_VERSION ) {\n\t/**\n\t * This error is thrown when, due to a mistake in the way CKEditor&nbsp;5 was installed,\n\t * imported, or initialized, some of its modules were evaluated and executed twice.\n\t * Duplicate modules inevitably lead to runtime errors and increased bundle size.\n\t *\n\t * # Check dependency versions\n\t *\n\t * First, make sure that you use the latest version of all CKEditor&nbsp;5 dependencies.\n\t * Depending on the installation method, you should check the versions of the `ckeditor5`,\n\t * `ckeditor5-premium-features`, or `@ckeditor/ckeditor5-<NAME>` packages. If you cannot update\n\t * to the latest version, ensure that all the CKEditor&nbsp;5 packages are\n\t * in the same version.\n\t *\n\t * If you use third-party plugins, make sure to update them, too. If they are incompatible\n\t * with the version of CKEditor&nbsp;5 you use, you may need to downgrade the CKEditor&nbsp;5 packages\n\t * (which we do not recommend). Ask the plugin's author to upgrade the dependencies,\n\t * or fork their project and update it yourself.\n\t *\n\t * # Check imports\n\t *\n\t * The next step is to look at how you import CKEditor&nbsp;5 into your project.\n\t *\n\t * **The {@glink updating/nim-migration/migration-to-new-installation-methods new installation methods}\n\t * are designed to prevent module duplication, so if you are not using them yet, you should consider\n\t * updating your project**. However, several legacy installation methods are still supported for backward\n\t * compatibility, and mixing them may result in module duplication.\n\t *\n\t * These are the most common import methods of the CKEditor&nbsp;5 packages.\n\t *\n\t * - **New installation methods (NIM)** &ndash; Imports from the `ckeditor5` and `ckeditor5-premium-features` packages.\n\t * - **Optimized build** for the new installation methods &ndash; Imports from the `@ckeditor/ckeditor5-<NAME>/dist/index.js`.\n\t * - **Predefined builds** (legacy) &ndash; Imports from the `@ckeditor/ckeditor5-build-<NAME>` packages.\n\t * - **Default imports** (legacy) &ndash; Imports from the `@ckeditor/ckeditor5-<NAME>` packages (default export).\n\t * - **`src`** (legacy) &ndash; Imports from the `@ckeditor/ckeditor5-<NAME>/src/*`.\n\t * - **DLL builds** (legacy) &ndash; Imports from the `ckeditor5/build/<NAME>` and `@ckeditor/ckeditor5-<NAME>/build/*`.\n\t *\n\t * The best way to avoid duplicate modules is to avoid mixing these installation methods. For example, if you use imports\n\t * specific to the optimized build, you should use them for all CKEditor&nbsp;5 packages. In addition, since\n\t * the Predefined and DLL builds already include the core of the editor, they cannot be used with other types of imports.\n\t *\n\t * Here is a matrix showing which installation methods are compatible with each other:\n\t *\n\t * |                  | NIM | Optimized build | Predefined builds | Default imports | `src` | DLL builds |\n\t * |------------------|-----|-----------------|-------------------|-----------------|-------|------------|\n\t * | NIM              | ✅  | ✅              | ❌                | ❌              | ❌    | ❌         |\n\t * | Optimized builds | ✅  | ✅              | ❌                | ❌              | ❌    | ❌         |\n\t * | Predefined build | ❌  | ❌              | ✅                | ❌              | ❌    | ❌         |\n\t * | Default imports  | ❌  | ❌              | ❌                | ✅              | ✅    | ❌         |\n\t * | `src`            | ❌  | ❌              | ❌                | ✅              | ✅    | ❌         |\n\t * | DLL builds       | ❌  | ❌              | ❌                | ❌              | ❌    | ✅         |\n\t *\n\t * If you use any third-party plugins, make sure the way you import them is compatible with\n\t * the way you import CKEditor&nbsp;5.\n\t *\n\t * <details>\n\t * <summary>New installation methods and optimized builds</summary>\n\t *\n\t * If you use the {@glink updating/nim-migration/migration-to-new-installation-methods new installation methods},\n\t * you should only import code from the `ckeditor5` and `ckeditor5-premium-features` packages.\n\t * Do not import code from the `@ckeditor/ckeditor5-<NAME>` packages unless you follow\n\t * the {@glink getting-started/setup/optimizing-build-size Optimizing build size} guide and the imports from\n\t * the `@ckeditor/ckeditor5-<NAME>` packages end with `/dist/index.js`.\n\t *\n\t * If you use a CDN, ensure that some files are not included twice in your project.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import { ClassicEditor, Highlight } from 'ckeditor5'; // ✅\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ✅\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ❌\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight.js'; // ❌\n\t * ```\n\t * </details>\n\t *\n\t * <details>\n\t * <summary>(Legacy) Predefined builds</summary>\n\t *\n\t * If you use the {@glink getting-started/legacy/installation-methods/predefined-builds Predefined builds},\n\t * you cannot import any additional plugins. These builds already include the editor's core\n\t * and selected plugins and importing additional ones will cause some modules to be bundled and loaded twice.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import ClassicEditor from '@ckeditor/ckeditor5-build-classic'; // ✅\n\t * import { Highlight } from 'ckeditor5'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ❌\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight'; // ❌\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight'; // ❌\n\t * ```\n\t *\n\t * If you are missing some features from the\n\t * {@glink getting-started/legacy/installation-methods/predefined-builds#plugins-included-in-the-predefined-builds list of plugins},\n\t * you should switch to the {@glink updating/nim-migration/migration-to-new-installation-methods new installation methods}\n\t * which do not have this limitation.\n\t * If you cannot migrate to the new installation methods, try the\n\t * {@glink getting-started/legacy/installation-methods/predefined-builds#superbuild superbuild} instead.\n\t * This build contains all the editor features.\n\t * </details>\n\t *\n\t * <details>\n\t * <summary>(Legacy) Default imports and `src` imports</summary>\n\t *\n\t * If you use the {@glink getting-started/legacy/installation-methods/quick-start-other legacy customized installation}\n\t * method, you should only import code from the `@ckeditor/ckeditor5-<NAME>` packages. While you can import code from\n\t * the `@ckeditor/ckeditor5-<NAME>/src/*` files, it is not recommended as it can make migration to the new installation\n\t * methods more difficult.\n\t *\n\t * If you use this installation method, you should not import code from the `ckeditor5`, `ckeditor5-premium-features`,\n\t * or `@ckeditor/ckeditor5-build-<NAME>` packages.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic'; // ✅\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ✅\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js'; // ✅ (not recommended)\n\t * import { Highlight } from 'ckeditor5'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ❌\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight'; // ❌\n\t * ```\n\t * </details>\n\t *\n\t * <details>\n\t * <summary>(Legacy) DLL builds</summary>\n\t *\n\t * If you are using the {@glink getting-started/legacy/advanced/alternative-setups/dll-builds legacy DLL builds},\n\t * you should not import any non-DLL modules.\n\t *\n\t * Examples of valid and invalid import paths:\n\t *\n\t * ```js\n\t * import 'ckeditor5/build/ckeditor5-dll.js';// ✅\n\t * import '@ckeditor/ckeditor5-editor-classic/build/editor-classic.js';// ✅\n\t * import '@ckeditor/ckeditor5-highlight/build/highlight.js';// ✅\n\t * import { Highlight } from 'ckeditor5'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight/dist/index.js'; // ❌\n\t * import { Highlight } from '@ckeditor/ckeditor5-highlight'; // ❌\n\t * import Highlight from '@ckeditor/ckeditor5-highlight/src/highlight.js'; // ❌\n\t * ```\n\t * </details>\n\t *\n\t * # Reinstall `node_modules`\n\t *\n\t * Usually, npm and other package managers deduplicate all packages - for example, `ckeditor5` is only installed once\n\t * in `node_modules/`. However, it is known to fail to do so occasionally.\n\t *\n\t * To rule out this possibility, you can try the following:\n\t *\n\t * 1. Remove the `node_modules` directory.\n\t * 2. Remove the `package-lock.json`, `yarn.lock`, or `pnpm-lock.yaml` files (depending on the package manager used).\n\t * 3. Run `npm install` to reinstall all packages.\n\t * 4. Run `npm ls` to check how many times packages like `@ckeditor/ckeditor5-core` are installed.\n\t * If they are installed more than once, verify which package causes that.\n\t *\n\t * @error ckeditor-duplicated-modules\n\t */\n\tthrow new CKEditorError(\n\t\t'ckeditor-duplicated-modules',\n\t\tnull\n\t);\n} else {\n\tglobalThis.CKEDITOR_VERSION = version;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/emittermixin\n */\n\nimport EventInfo from './eventinfo.js';\nimport uid from './uid.js';\nimport priorities, { type PriorityString } from './priorities.js';\nimport insertToPriorityArray from './inserttopriorityarray.js';\nimport type { Constructor, Mixed } from './mix.js';\n\n// To check if component is loaded more than once.\nimport './version.js';\nimport CKEditorError from './ckeditorerror.js';\n\nconst _listeningTo = Symbol( 'listeningTo' );\nconst _emitterId = Symbol( 'emitterId' );\nconst _delegations = Symbol( 'delegations' );\n\nconst defaultEmitterClass = /* #__PURE__ */ EmitterMixin( Object );\n\n/**\n * Mixin that injects the {@link ~Emitter events API} into its host.\n *\n * This function creates a class that inherits from the provided `base` and implements `Emitter` interface.\n *\n * ```ts\n * class BaseClass { ... }\n *\n * class MyClass extends EmitterMixin( BaseClass ) {\n * \t// This class derives from `BaseClass` and implements the `Emitter` interface.\n * }\n * ```\n *\n * Read more about the concept of emitters in the:\n * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}\n * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide.\n * * {@glink framework/deep-dive/event-system Event system} deep-dive guide.\n *\n * @label EXTENDS\n */\nexport default function EmitterMixin<Base extends Constructor>( base: Base ): Mixed<Base, Emitter>;\n\n/**\n * Mixin that injects the {@link ~Emitter events API} into its host.\n *\n * This function creates a class that implements `Emitter` interface.\n *\n * ```ts\n * class MyClass extends EmitterMixin() {\n * \t// This class implements the `Emitter` interface.\n * }\n * ```\n *\n * Read more about the concept of emitters in the:\n * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}\n * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide.\n * * {@glink framework/deep-dive/event-system Event system} deep dive guide.\n *\n * @label NO_ARGUMENTS\n */\nexport default function EmitterMixin(): {\n\tnew (): Emitter;\n\tprototype: Emitter;\n};\n\nexport default function EmitterMixin( base?: Constructor ): unknown {\n\tif ( !base ) {\n\t\treturn defaultEmitterClass;\n\t}\n\n\tabstract class Mixin extends base implements EmitterInternal {\n\t\tpublic on<TEvent extends BaseEvent>(\n\t\t\tevent: TEvent[ 'name' ],\n\t\t\tcallback: GetCallback<TEvent>,\n\t\t\toptions?: CallbackOptions\n\t\t): void {\n\t\t\tthis.listenTo( this, event, callback, options );\n\t\t}\n\n\t\tpublic once<TEvent extends BaseEvent>(\n\t\t\tevent: TEvent[ 'name' ],\n\t\t\tcallback: GetCallback<TEvent>,\n\t\t\toptions?: CallbackOptions\n\t\t): void {\n\t\t\tlet wasFired = false;\n\n\t\t\tconst onceCallback: typeof callback = ( event, ...args ) => {\n\t\t\t\t// Ensure the callback is called only once even if the callback itself leads to re-firing the event\n\t\t\t\t// (which would call the callback again).\n\t\t\t\tif ( !wasFired ) {\n\t\t\t\t\twasFired = true;\n\n\t\t\t\t\t// Go off() at the first call.\n\t\t\t\t\tevent.off();\n\n\t\t\t\t\t// Go with the original callback.\n\t\t\t\t\tcallback.call( this, event, ...args );\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Make a similar on() call, simply replacing the callback.\n\t\t\tthis.listenTo( this, event, onceCallback, options );\n\t\t}\n\n\t\tpublic off( event: string, callback: Function ): void {\n\t\t\tthis.stopListening( this, event, callback );\n\t\t}\n\n\t\tpublic listenTo<TEvent extends BaseEvent>(\n\t\t\temitter: Emitter,\n\t\t\tevent: TEvent[ 'name' ],\n\t\t\tcallback: GetCallback<TEvent>,\n\t\t\toptions: CallbackOptions = {}\n\t\t): void {\n\t\t\tlet emitterInfo, eventCallbacks;\n\n\t\t\t// _listeningTo contains a list of emitters that this object is listening to.\n\t\t\t// This list has the following format:\n\t\t\t//\n\t\t\t// _listeningTo: {\n\t\t\t//     emitterId: {\n\t\t\t//         emitter: emitter,\n\t\t\t//         callbacks: {\n\t\t\t//             event1: [ callback1, callback2, ... ]\n\t\t\t//             ....\n\t\t\t//         }\n\t\t\t//     },\n\t\t\t//     ...\n\t\t\t// }\n\n\t\t\tif ( !this[ _listeningTo ] ) {\n\t\t\t\tthis[ _listeningTo ] = {};\n\t\t\t}\n\n\t\t\tconst emitters = this[ _listeningTo ]!;\n\n\t\t\tif ( !_getEmitterId( emitter ) ) {\n\t\t\t\t_setEmitterId( emitter );\n\t\t\t}\n\n\t\t\tconst emitterId = _getEmitterId( emitter )!;\n\n\t\t\tif ( !( emitterInfo = emitters[ emitterId ] ) ) {\n\t\t\t\temitterInfo = emitters[ emitterId ] = {\n\t\t\t\t\temitter,\n\t\t\t\t\tcallbacks: {}\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif ( !( eventCallbacks = emitterInfo.callbacks[ event ] ) ) {\n\t\t\t\teventCallbacks = emitterInfo.callbacks[ event ] = [];\n\t\t\t}\n\n\t\t\teventCallbacks.push( callback );\n\n\t\t\t// Finally register the callback to the event.\n\t\t\taddEventListener( this, emitter, event, callback, options );\n\t\t}\n\n\t\tpublic stopListening( emitter?: Emitter, event?: string, callback?: Function ): void {\n\t\t\tconst emitters = this[ _listeningTo ];\n\t\t\tlet emitterId = emitter && _getEmitterId( emitter );\n\t\t\tconst emitterInfo = ( emitters && emitterId ) ? emitters[ emitterId ] : undefined;\n\t\t\tconst eventCallbacks = ( emitterInfo && event ) ? emitterInfo.callbacks[ event ] : undefined;\n\n\t\t\t// Stop if nothing has been listened.\n\t\t\tif ( !emitters || ( emitter && !emitterInfo ) || ( event && !eventCallbacks ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// All params provided. off() that single callback.\n\t\t\tif ( callback ) {\n\t\t\t\tremoveEventListener( this, emitter!, event!, callback );\n\n\t\t\t\t// We must remove callbacks as well in order to prevent memory leaks.\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5/pull/8480\n\t\t\t\tconst index = eventCallbacks!.indexOf( callback );\n\n\t\t\t\tif ( index !== -1 ) {\n\t\t\t\t\tif ( eventCallbacks!.length === 1 ) {\n\t\t\t\t\t\tdelete emitterInfo!.callbacks[ event! ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tremoveEventListener( this, emitter!, event!, callback );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Only `emitter` and `event` provided. off() all callbacks for that event.\n\t\t\telse if ( eventCallbacks ) {\n\t\t\t\twhile ( ( callback = eventCallbacks.pop() ) ) {\n\t\t\t\t\tremoveEventListener( this, emitter!, event!, callback );\n\t\t\t\t}\n\n\t\t\t\tdelete emitterInfo!.callbacks[ event! ];\n\t\t\t}\n\t\t\t// Only `emitter` provided. off() all events for that emitter.\n\t\t\telse if ( emitterInfo ) {\n\t\t\t\tfor ( event in emitterInfo.callbacks ) {\n\t\t\t\t\tthis.stopListening( emitter!, event );\n\t\t\t\t}\n\t\t\t\tdelete emitters[ emitterId! ];\n\t\t\t}\n\t\t\t// No params provided. off() all emitters.\n\t\t\telse {\n\t\t\t\tfor ( emitterId in emitters ) {\n\t\t\t\t\tthis.stopListening( emitters[ emitterId ].emitter );\n\t\t\t\t}\n\t\t\t\tdelete this[ _listeningTo ];\n\t\t\t}\n\t\t}\n\n\t\tpublic fire<TEvent extends BaseEvent>(\n\t\t\teventOrInfo: GetNameOrEventInfo<TEvent>,\n\t\t\t...args: TEvent[ 'args' ]\n\t\t): GetEventInfo<TEvent>[ 'return' ] {\n\t\t\ttry {\n\t\t\t\tconst eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo( this, eventOrInfo );\n\t\t\t\tconst event = eventInfo.name;\n\t\t\t\tlet callbacks = getCallbacksForEvent( this, event );\n\n\t\t\t\t// Record that the event passed this emitter on its path.\n\t\t\t\teventInfo.path.push( this );\n\n\t\t\t\t// Handle event listener callbacks first.\n\t\t\t\tif ( callbacks ) {\n\t\t\t\t\t// Arguments passed to each callback.\n\t\t\t\t\tconst callbackArgs = [ eventInfo, ...args ];\n\n\t\t\t\t\t// Copying callbacks array is the easiest and most secure way of preventing infinite loops, when event callbacks\n\t\t\t\t\t// are added while processing other callbacks. Previous solution involved adding counters (unique ids) but\n\t\t\t\t\t// failed if callbacks were added to the queue before currently processed callback.\n\t\t\t\t\t// If this proves to be too inefficient, another method is to change `.on()` so callbacks are stored if same\n\t\t\t\t\t// event is currently processed. Then, `.fire()` at the end, would have to add all stored events.\n\t\t\t\t\tcallbacks = Array.from( callbacks );\n\n\t\t\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\t\t\tcallbacks[ i ].callback.apply( this, callbackArgs );\n\n\t\t\t\t\t\t// Remove the callback from future requests if off() has been called.\n\t\t\t\t\t\tif ( eventInfo.off.called ) {\n\t\t\t\t\t\t\t// Remove the called mark for the next calls.\n\t\t\t\t\t\t\tdelete eventInfo.off.called;\n\n\t\t\t\t\t\t\tthis._removeEventListener( event, callbacks[ i ].callback );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Do not execute next callbacks if stop() was called.\n\t\t\t\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Delegate event to other emitters if needed.\n\t\t\t\tconst delegations = this[ _delegations ];\n\n\t\t\t\tif ( delegations ) {\n\t\t\t\t\tconst destinations = delegations.get( event );\n\t\t\t\t\tconst passAllDestinations = delegations.get( '*' );\n\n\t\t\t\t\tif ( destinations ) {\n\t\t\t\t\t\tfireDelegatedEvents( destinations, eventInfo, args );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( passAllDestinations ) {\n\t\t\t\t\t\tfireDelegatedEvents( passAllDestinations, eventInfo, args );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn eventInfo.return;\n\t\t\t} catch ( err ) {\n\t\t\t\t// @if CK_DEBUG // throw err;\n\t\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\t\tCKEditorError.rethrowUnexpectedError( err as Error, this );\n\t\t\t}\n\t\t}\n\n\t\tpublic delegate( ...events: Array<string> ): EmitterMixinDelegateChain {\n\t\t\treturn {\n\t\t\t\tto: ( emitter, nameOrFunction ) => {\n\t\t\t\t\tif ( !this[ _delegations ] ) {\n\t\t\t\t\t\tthis[ _delegations ] = new Map();\n\t\t\t\t\t}\n\n\t\t\t\t\t// Originally there was a for..of loop which unfortunately caused an error in Babel that didn't allow\n\t\t\t\t\t// build an application. See: https://github.com/ckeditor/ckeditor5-react/issues/40.\n\t\t\t\t\tevents.forEach( eventName => {\n\t\t\t\t\t\tconst destinations = this[ _delegations ]!.get( eventName );\n\n\t\t\t\t\t\tif ( !destinations ) {\n\t\t\t\t\t\t\tthis[ _delegations ]!.set( eventName, new Map( [ [ emitter, nameOrFunction ] ] ) );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdestinations.set( emitter, nameOrFunction );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tpublic stopDelegating( event?: string, emitter?: Emitter ): void {\n\t\t\tif ( !this[ _delegations ] ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !event ) {\n\t\t\t\tthis[ _delegations ]!.clear();\n\t\t\t} else if ( !emitter ) {\n\t\t\t\tthis[ _delegations ]!.delete( event );\n\t\t\t} else {\n\t\t\t\tconst destinations = this[ _delegations ]!.get( event );\n\n\t\t\t\tif ( destinations ) {\n\t\t\t\t\tdestinations.delete( emitter );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic _addEventListener<TEvent extends BaseEvent>(\n\t\t\tevent: TEvent[ 'name' ],\n\t\t\tcallback: GetCallback<TEvent>,\n\t\t\toptions: CallbackOptions\n\t\t): void {\n\t\t\tcreateEventNamespace( this, event );\n\n\t\t\tconst lists = getCallbacksListsForNamespace( this, event );\n\t\t\tconst priority = priorities.get( options.priority );\n\n\t\t\tconst callbackDefinition = {\n\t\t\t\tcallback,\n\t\t\t\tpriority\n\t\t\t};\n\n\t\t\t// Add the callback to all callbacks list.\n\t\t\tfor ( const callbacks of lists ) {\n\t\t\t\t// Add the callback to the list in the right priority position.\n\t\t\t\tinsertToPriorityArray( callbacks, callbackDefinition );\n\t\t\t}\n\t\t}\n\n\t\tpublic _removeEventListener( event: string, callback: Function ): void {\n\t\t\tconst lists = getCallbacksListsForNamespace( this, event );\n\n\t\t\tfor ( const callbacks of lists ) {\n\t\t\t\tfor ( let i = 0; i < callbacks.length; i++ ) {\n\t\t\t\t\tif ( callbacks[ i ].callback == callback ) {\n\t\t\t\t\t\t// Remove the callback from the list (fixing the next index).\n\t\t\t\t\t\tcallbacks.splice( i, 1 );\n\t\t\t\t\t\ti--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic declare _events?: { [ eventName: string ]: EventNode };\n\n\t\tpublic declare [ _emitterId ]?: string;\n\n\t\tpublic declare [ _listeningTo ]?: {\n\t\t\t[ emitterId: string ]: {\n\t\t\t\temitter: Emitter;\n\t\t\t\tcallbacks: { [ event: string]: Array<Function> };\n\t\t\t};\n\t\t};\n\n\t\tpublic declare [ _delegations ]?: Map<string, Map<Emitter, string | ( ( name: string ) => string ) | undefined>>;\n\t}\n\n\treturn Mixin;\n}\n\n// Backward compatibility with `mix`\n( [\n\t'on', 'once', 'off', 'listenTo',\n\t'stopListening', 'fire', 'delegate', 'stopDelegating',\n\t'_addEventListener', '_removeEventListener'\n] ).forEach( key => {\n\t( EmitterMixin as any )[ key ] = ( defaultEmitterClass.prototype as any )[ key ];\n} );\n\n/**\n * Emitter/listener interface.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/emittermixin~Emitter} mixin.\n *\n * ```ts\n * class MyClass extends EmitterMixin() {\n * \t// This class now implements the `Emitter` interface.\n * }\n * ```\n *\n * Read more about the usage of this interface in the:\n * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}\n * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide.\n * * {@glink framework/deep-dive/event-system Event system} deep-dive guide.\n */\nexport interface Emitter {\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired.\n\t *\n\t * Shorthand for {@link #listenTo `this.listenTo( this, event, callback, options )`} (it makes the emitter\n\t * listen on itself).\n\t *\n\t * @typeParam TEvent The type descibing the event. See {@link module:utils/emittermixin~BaseEvent}.\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t */\n\ton<TEvent extends BaseEvent>(\n\t\tevent: TEvent[ 'name' ],\n\t\tcallback: GetCallback<TEvent>,\n\t\toptions?: GetCallbackOptions<TEvent>\n\t): void;\n\n\t/**\n\t * Registers a callback function to be executed on the next time the event is fired only. This is similar to\n\t * calling {@link #on} followed by {@link #off} in the callback.\n\t *\n\t * @typeParam TEvent The type descibing the event. See {@link module:utils/emittermixin~BaseEvent}.\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t */\n\tonce<TEvent extends BaseEvent>(\n\t\tevent: TEvent[ 'name' ],\n\t\tcallback: GetCallback<TEvent>,\n\t\toptions?: GetCallbackOptions<TEvent>\n\t): void;\n\n\t/**\n\t * Stops executing the callback on the given event.\n\t * Shorthand for {@link #stopListening `this.stopListening( this, event, callback )`}.\n\t *\n\t * @param event The name of the event.\n\t * @param callback The function to stop being called.\n\t */\n\toff( event: string, callback: Function ): void;\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired in a specific (emitter) object.\n\t *\n\t * Events can be grouped in namespaces using `:`.\n\t * When namespaced event is fired, it additionally fires all callbacks for that namespace.\n\t *\n\t * ```ts\n\t * // myEmitter.on( ... ) is a shorthand for myEmitter.listenTo( myEmitter, ... ).\n\t * myEmitter.on( 'myGroup', genericCallback );\n\t * myEmitter.on( 'myGroup:myEvent', specificCallback );\n\t *\n\t * // genericCallback is fired.\n\t * myEmitter.fire( 'myGroup' );\n\t * // both genericCallback and specificCallback are fired.\n\t * myEmitter.fire( 'myGroup:myEvent' );\n\t * // genericCallback is fired even though there are no callbacks for \"foo\".\n\t * myEmitter.fire( 'myGroup:foo' );\n\t * ```\n\t *\n\t * An event callback can {@link module:utils/eventinfo~EventInfo#stop stop the event} and\n\t * set the {@link module:utils/eventinfo~EventInfo#return return value} of the {@link #fire} method.\n\t *\n\t * @label BASE_EMITTER\n\t * @typeParam TEvent The type describing the event. See {@link module:utils/emittermixin~BaseEvent}.\n\t * @param emitter The object that fires the event.\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t */\n\tlistenTo<TEvent extends BaseEvent>(\n\t\temitter: Emitter,\n\t\tevent: TEvent[ 'name' ],\n\t\tcallback: GetCallback<TEvent>,\n\t\toptions?: GetCallbackOptions<TEvent>\n\t): void;\n\n\t/**\n\t * Stops listening for events. It can be used at different levels:\n\t *\n\t * * To stop listening to a specific callback.\n\t * * To stop listening to a specific event.\n\t * * To stop listening to all events fired by a specific object.\n\t * * To stop listening to all events fired by all objects.\n\t *\n\t * @label BASE_STOP\n\t * @param emitter The object to stop listening to. If omitted, stops it for all objects.\n\t * @param event (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it\n\t * for all events from `emitter`.\n\t * @param callback (Requires the `event`) The function to be removed from the call list for the given\n\t * `event`.\n\t */\n\tstopListening( emitter?: Emitter, event?: string, callback?: Function ): void;\n\n\t/**\n\t * Fires an event, executing all callbacks registered for it.\n\t *\n\t * The first parameter passed to callbacks is an {@link module:utils/eventinfo~EventInfo} object,\n\t * followed by the optional `args` provided in the `fire()` method call.\n\t *\n\t * @typeParam TEvent The type describing the event. See {@link module:utils/emittermixin~BaseEvent}.\n\t * @param eventOrInfo The name of the event or `EventInfo` object if event is delegated.\n\t * @param args Additional arguments to be passed to the callbacks.\n\t * @returns By default the method returns `undefined`. However, the return value can be changed by listeners\n\t * through modification of the {@link module:utils/eventinfo~EventInfo#return `evt.return`}'s property (the event info\n\t * is the first param of every callback).\n\t */\n\tfire<TEvent extends BaseEvent>(\n\t\teventOrInfo: GetNameOrEventInfo<TEvent>,\n\t\t...args: TEvent[ 'args' ]\n\t): GetEventInfo<TEvent>[ 'return' ];\n\n\t/**\n\t * Delegates selected events to another {@link module:utils/emittermixin~Emitter}. For instance:\n\t *\n\t * ```ts\n\t * emitterA.delegate( 'eventX' ).to( emitterB );\n\t * emitterA.delegate( 'eventX', 'eventY' ).to( emitterC );\n\t * ```\n\t *\n\t * then `eventX` is delegated (fired by) `emitterB` and `emitterC` along with `data`:\n\t *\n\t * ```ts\n\t * emitterA.fire( 'eventX', data );\n\t * ```\n\t *\n\t * and `eventY` is delegated (fired by) `emitterC` along with `data`:\n\t *\n\t * ```ts\n\t * emitterA.fire( 'eventY', data );\n\t * ```\n\t *\n\t * @param events Event names that will be delegated to another emitter.\n\t */\n\tdelegate( ...events: Array<string> ): EmitterMixinDelegateChain;\n\n\t/**\n\t * Stops delegating events. It can be used at different levels:\n\t *\n\t * * To stop delegating all events.\n\t * * To stop delegating a specific event to all emitters.\n\t * * To stop delegating a specific event to a specific emitter.\n\t *\n\t * @param event The name of the event to stop delegating. If omitted, stops it all delegations.\n\t * @param emitter (requires `event`) The object to stop delegating a particular event to.\n\t * If omitted, stops delegation of `event` to all emitters.\n\t */\n\tstopDelegating( event?: string, emitter?: Emitter ): void;\n}\n\ninterface EmitterInternal extends Emitter {\n\n\t/**\n\t * Adds callback to emitter for given event.\n\t *\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t */\n\t_addEventListener?: <TEvent extends BaseEvent>(\n\t\tevent: TEvent[ 'name' ],\n\t\tcallback: GetCallback<TEvent>,\n\t\toptions: CallbackOptions\n\t) => void;\n\n\t/**\n\t * Removes callback from emitter for given event.\n\t *\n\t * @param event The name of the event.\n\t * @param callback The function to stop being called.\n\t */\n\t_removeEventListener?: ( event: string, callback: Function ) => void;\n\n\t_events?: { [ eventName: string ]: EventNode };\n\n\t[ _emitterId ]?: string;\n\n\t[ _listeningTo ]?: {\n\t\t[ emitterId: string ]: {\n\t\t\temitter: Emitter;\n\t\t\tcallbacks: { [ event: string]: Array<Function> };\n\t\t};\n\t};\n\n\t[ _delegations ]?: Map<string, Map<Emitter, string | ( ( name: string ) => string ) | undefined>>;\n}\n\n/**\n * Default type describing any event.\n *\n * Every custom event has to be compatible with `BaseEvent`.\n *\n * ```ts\n * type MyEvent = {\n * \t// In `fire<MyEvent>( name )`, `on<MyEvent>( name )`, `once<MyEvent>( name )` and `listenTo<MyEvent>( name )` calls\n * \t// the `name` argument will be type-checked to ensure it's `'myEvent'` or have `'myEvent:'` prefix.\n * \t// Required.\n * \tname: 'myEvent' | `myEvent:${ string }`;\n *\n * \t// In `fire<MyEvent>( name, a, b )` call, `a` and `b` parameters will be type-checked against `number` and `string`.\n * \t// In `on<MyEvent>`, `once<MyEvent>` and `listenTo<MyEvent>` calls, the parameters of provided callback function\n * \t// will be automatically inferred as `EventInfo`, `number` and `string`.\n * \t// Required.\n * \targs: [ number, string ];\n *\n * \t// `fire<MyEvent>` will have return type `boolean | undefined`.\n * \t// Optional, unknown by default.\n * \treturn: boolean;\n *\n * \t// `fire<MyEvent>( eventInfo )` will type-check that `eventInfo` is `MyEventInfo`, not a base `EventInfo` or string.\n * \t// In `on<MyEvent>`, `once<MyEvent>` and `listenTo<MyEvent>` calls, the first callback parameter will be of this type.\n * \t// Optional.\n * \teventInfo: MyEventInfo;\n *\n * \t// In `on<MyEvent>`, `once<MyEvent>` and `listenTo<MyEvent>` calls, the `options` parameter will be of type\n * \t// `{ myOption?: boolean; priority?: PriorityString }\n * \t// Optional.\n * \tcallbackOptions: { myOption?: boolean };\n * };\n * ```\n */\nexport type BaseEvent = {\n\tname: string;\n\targs: Array<any>;\n};\n\n/**\n * Utility type that gets the `EventInfo` subclass for the given event.\n */\nexport type GetEventInfo<TEvent extends BaseEvent> = TEvent extends { eventInfo: EventInfo } ?\n\tTEvent[ 'eventInfo' ] :\n\tEventInfo<TEvent[ 'name' ], ( TEvent extends { return: infer TReturn } ? TReturn : unknown )>;\n\n/**\n * Utility type that gets the `EventInfo` subclass or event name type for the given event.\n */\nexport type GetNameOrEventInfo<TEvent extends BaseEvent> = TEvent extends { eventInfo: EventInfo } ?\n\tTEvent[ 'eventInfo' ] :\n\tTEvent[ 'name' ] | EventInfo<TEvent[ 'name' ], ( TEvent extends { return: infer TReturn } ? TReturn : unknown )>;\n\n/**\n * Utility type that gets the callback type for the given event.\n */\nexport type GetCallback<TEvent extends BaseEvent> = ( this: Emitter, ev: GetEventInfo<TEvent>, ...args: TEvent[ 'args' ] ) => void;\n\n/**\n * Utility type that gets the callback options for the given event.\n */\nexport type GetCallbackOptions<TEvent extends BaseEvent> = TEvent extends { callbackOptions: infer TOptions } ?\n\tTOptions & CallbackOptions :\n\tCallbackOptions;\n\n/**\n * Additional options for registering a callback.\n */\nexport interface CallbackOptions {\n\n\t/**\n\t * The priority of this event callback. The higher\n\t * the priority value the sooner the callback will be fired. Events having the same priority are called in the\n\t * order they were added.\n\t *\n\t * @defaultValue `'normal'`\n\t */\n\treadonly priority?: PriorityString;\n}\n\n/**\n * Checks if `listeningEmitter` listens to an emitter with given `listenedToEmitterId` and if so, returns that emitter.\n * If not, returns `null`.\n *\n * @internal\n * @param listeningEmitter An emitter that listens.\n * @param listenedToEmitterId Unique emitter id of emitter listened to.\n */\nexport function _getEmitterListenedTo( listeningEmitter: Emitter, listenedToEmitterId: string ): Emitter | null {\n\tconst listeningTo = ( listeningEmitter as EmitterInternal )[ _listeningTo ];\n\tif ( listeningTo && listeningTo[ listenedToEmitterId ] ) {\n\t\treturn listeningTo[ listenedToEmitterId ].emitter;\n\t}\n\n\treturn null;\n}\n\n/**\n * Sets emitter's unique id.\n *\n * **Note:** `_emitterId` can be set only once.\n *\n * @internal\n * @param emitter An emitter for which id will be set.\n * @param id Unique id to set. If not passed, random unique id will be set.\n */\nexport function _setEmitterId( emitter: Emitter, id?: string ): void {\n\tif ( !( emitter as EmitterInternal )[ _emitterId ] ) {\n\t\t( emitter as EmitterInternal )[ _emitterId ] = id || uid();\n\t}\n}\n\n/**\n * Returns emitter's unique id.\n *\n * @internal\n * @param emitter An emitter which id will be returned.\n */\nexport function _getEmitterId( emitter: Emitter ): string | undefined {\n\treturn ( emitter as EmitterInternal )[ _emitterId ];\n}\n\ninterface EventNode {\n\tcallbacks: Array<{ callback: Function; priority: number }>;\n\tchildEvents: Array<string>;\n}\n\n/**\n * Gets the internal `_events` property of the given object.\n * `_events` property store all lists with callbacks for registered event names.\n * If there were no events registered on the object, empty `_events` object is created.\n */\nfunction getEvents( source: EmitterInternal ): { [ eventName: string ]: EventNode } {\n\tif ( !source._events ) {\n\t\tObject.defineProperty( source, '_events', {\n\t\t\tvalue: {}\n\t\t} );\n\t}\n\n\treturn source._events!;\n}\n\n/**\n * Creates event node for generic-specific events relation architecture.\n */\nfunction makeEventNode(): EventNode {\n\treturn {\n\t\tcallbacks: [],\n\t\tchildEvents: []\n\t};\n}\n\n/**\n * Creates an architecture for generic-specific events relation.\n * If needed, creates all events for given eventName, i.e. if the first registered event\n * is foo:bar:abc, it will create foo:bar:abc, foo:bar and foo event and tie them together.\n * It also copies callbacks from more generic events to more specific events when\n * specific events are created.\n */\nfunction createEventNamespace( source: EmitterInternal, eventName: string ): void {\n\tconst events = getEvents( source );\n\n\t// First, check if the event we want to add to the structure already exists.\n\tif ( events[ eventName ] ) {\n\t\t// If it exists, we don't have to do anything.\n\t\treturn;\n\t}\n\n\t// In other case, we have to create the structure for the event.\n\t// Note, that we might need to create intermediate events too.\n\t// I.e. if foo:bar:abc is being registered and we only have foo in the structure,\n\t// we need to also register foo:bar.\n\n\t// Currently processed event name.\n\tlet name = eventName;\n\t// Name of the event that is a child event for currently processed event.\n\tlet childEventName = null;\n\n\t// Array containing all newly created specific events.\n\tconst newEventNodes = [];\n\n\t// While loop can't check for ':' index because we have to handle generic events too.\n\t// In each loop, we truncate event name, going from the most specific name to the generic one.\n\t// I.e. foo:bar:abc -> foo:bar -> foo.\n\twhile ( name !== '' ) {\n\t\tif ( events[ name ] ) {\n\t\t\t// If the currently processed event name is already registered, we can be sure\n\t\t\t// that it already has all the structure created, so we can break the loop here\n\t\t\t// as no more events need to be registered.\n\t\t\tbreak;\n\t\t}\n\n\t\t// If this event is not yet registered, create a new object for it.\n\t\tevents[ name ] = makeEventNode();\n\t\t// Add it to the array with newly created events.\n\t\tnewEventNodes.push( events[ name ] );\n\n\t\t// Add previously processed event name as a child of this event.\n\t\tif ( childEventName ) {\n\t\t\tevents[ name ].childEvents.push( childEventName );\n\t\t}\n\n\t\tchildEventName = name;\n\t\t// If `.lastIndexOf()` returns -1, `.substr()` will return '' which will break the loop.\n\t\tname = name.substr( 0, name.lastIndexOf( ':' ) );\n\t}\n\n\tif ( name !== '' ) {\n\t\t// If name is not empty, we found an already registered event that was a parent of the\n\t\t// event we wanted to register.\n\n\t\t// Copy that event's callbacks to newly registered events.\n\t\tfor ( const node of newEventNodes ) {\n\t\t\tnode.callbacks = events[ name ].callbacks.slice();\n\t\t}\n\n\t\t// Add last newly created event to the already registered event.\n\t\tevents[ name ].childEvents.push( childEventName! );\n\t}\n}\n\n/**\n * Gets an array containing callbacks list for a given event and it's more specific events.\n * I.e. if given event is foo:bar and there is also foo:bar:abc event registered, this will\n * return callback list of foo:bar and foo:bar:abc (but not foo).\n */\nfunction getCallbacksListsForNamespace( source: EmitterInternal, eventName: string ): Array<EventNode[ 'callbacks' ]> {\n\tconst eventNode = getEvents( source )[ eventName ];\n\n\tif ( !eventNode ) {\n\t\treturn [];\n\t}\n\n\tlet callbacksLists = [ eventNode.callbacks ];\n\n\tfor ( let i = 0; i < eventNode.childEvents.length; i++ ) {\n\t\tconst childCallbacksLists = getCallbacksListsForNamespace( source, eventNode.childEvents[ i ] );\n\n\t\tcallbacksLists = callbacksLists.concat( childCallbacksLists );\n\t}\n\n\treturn callbacksLists;\n}\n\n/**\n * Get the list of callbacks for a given event, but only if there any callbacks have been registered.\n * If there are no callbacks registered for given event, it checks if this is a specific event and looks\n * for callbacks for it's more generic version.\n */\nfunction getCallbacksForEvent( source: EmitterInternal, eventName: string ): EventNode[ 'callbacks' ] | null {\n\tlet event;\n\n\tif ( !source._events || !( event = source._events[ eventName ] ) || !event.callbacks.length ) {\n\t\t// There are no callbacks registered for specified eventName.\n\t\t// But this could be a specific-type event that is in a namespace.\n\t\tif ( eventName.indexOf( ':' ) > -1 ) {\n\t\t\t// If the eventName is specific, try to find callback lists for more generic event.\n\t\t\treturn getCallbacksForEvent( source, eventName.substr( 0, eventName.lastIndexOf( ':' ) ) );\n\t\t} else {\n\t\t\t// If this is a top-level generic event, return null;\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn event.callbacks;\n}\n\n/**\n * Fires delegated events for given map of destinations.\n *\n * @param destinations A map containing `[ {@link module:utils/emittermixin~Emitter}, \"event name\" ]` pair destinations.\n * @param eventInfo The original event info object.\n * @param fireArgs Arguments the original event was fired with.\n */\nfunction fireDelegatedEvents(\n\tdestinations: Map<Emitter, string | ( ( name: string ) => string ) | undefined>,\n\teventInfo: EventInfo,\n\tfireArgs: Array<any>\n) {\n\tfor ( let [ emitter, name ] of destinations ) {\n\t\tif ( !name ) {\n\t\t\tname = eventInfo.name;\n\t\t} else if ( typeof name == 'function' ) {\n\t\t\tname = name( eventInfo.name );\n\t\t}\n\n\t\tconst delegatedInfo = new EventInfo( eventInfo.source, name );\n\n\t\tdelegatedInfo.path = [ ...eventInfo.path ];\n\n\t\temitter.fire( delegatedInfo, ...fireArgs );\n\t}\n}\n\n/**\n * Helper for registering event callback on the emitter.\n */\nfunction addEventListener<TEvent extends BaseEvent>(\n\tlistener: EmitterInternal,\n\temitter: EmitterInternal,\n\tevent: TEvent[ 'name' ],\n\tcallback: GetCallback<TEvent>,\n\toptions: CallbackOptions\n) {\n\tif ( emitter._addEventListener ) {\n\t\temitter._addEventListener( event, callback, options );\n\t} else {\n\t\t// Allow listening on objects that do not implement Emitter interface.\n\t\t// This is needed in some tests that are using mocks instead of the real objects with EmitterMixin mixed.\n\t\t( listener._addEventListener!<TEvent> ).call( emitter, event, callback, options );\n\t}\n}\n\n/**\n * Helper for removing event callback from the emitter.\n */\nfunction removeEventListener( listener: EmitterInternal, emitter: EmitterInternal, event: string, callback: Function ): void {\n\tif ( emitter._removeEventListener ) {\n\t\temitter._removeEventListener( event, callback );\n\t} else {\n\t\t// Allow listening on objects that do not implement Emitter interface.\n\t\t// This is needed in some tests that are using mocks instead of the real objects with EmitterMixin mixed.\n\t\tlistener._removeEventListener!.call( emitter, event, callback );\n\t}\n}\n\n/**\n * The return value of {@link ~Emitter#delegate}.\n */\nexport interface EmitterMixinDelegateChain {\n\n\t/**\n\t * Selects destination for {@link module:utils/emittermixin~Emitter#delegate} events.\n\t *\n\t * @param emitter An `EmitterMixin` instance which is the destination for delegated events.\n\t * @param nameOrFunction A custom event name or function which converts the original name string.\n\t */\n\tto( emitter: Emitter, nameOrFunction?: string | ( ( name: string ) => string ) ): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* eslint-disable @typescript-eslint/unified-signatures */\n\n/**\n * @module utils/observablemixin\n */\n\nimport EmitterMixin, { type Emitter } from './emittermixin.js';\nimport CKEditorError from './ckeditorerror.js';\nimport type { Constructor, Mixed } from './mix.js';\n\nimport { isObject } from 'lodash-es';\n\nconst observablePropertiesSymbol = Symbol( 'observableProperties' );\nconst boundObservablesSymbol = Symbol( 'boundObservables' );\nconst boundPropertiesSymbol = Symbol( 'boundProperties' );\n\nconst decoratedMethods = Symbol( 'decoratedMethods' );\nconst decoratedOriginal = Symbol( 'decoratedOriginal' );\n\nconst defaultObservableClass = /* #__PURE__ */ ObservableMixin( /* #__PURE__ */ EmitterMixin() );\n\n/**\n * A mixin that injects the \"observable properties\" and data binding functionality described in the\n * {@link ~Observable} interface.\n *\n * This function creates a class that inherits from the provided `base` and implements `Observable` interface.\n *\n * ```ts\n * class BaseClass { ... }\n *\n * class MyClass extends ObservableMixin( BaseClass ) {\n * \t// This class derives from `BaseClass` and implements the `Observable` interface.\n * }\n * ```\n *\n * Read more about the concept of observables in the:\n * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}\n * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,\n * * {@glink framework/deep-dive/observables Observables deep-dive} guide.\n *\n * @label EXTENDS\n */\nexport default function ObservableMixin<Base extends Constructor<Emitter>>( base: Base ): Mixed<Base, Observable>;\n\n/**\n * A mixin that injects the \"observable properties\" and data binding functionality described in the\n * {@link ~Observable} interface.\n *\n * This function creates a class that implements `Observable` interface.\n *\n * ```ts\n * class MyClass extends ObservableMixin() {\n * \t// This class implements the `Observable` interface.\n * }\n * ```\n *\n * Read more about the concept of observables in the:\n * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}\n * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,\n * * {@glink framework/deep-dive/observables Observables deep dive} guide.\n *\n * @label NO_ARGUMENTS\n */\nexport default function ObservableMixin(): {\n\tnew (): Observable;\n\tprototype: Observable;\n};\n\nexport default function ObservableMixin( base?: Constructor<Emitter> ): unknown {\n\tif ( !base ) {\n\t\treturn defaultObservableClass;\n\t}\n\n\tabstract class Mixin extends base implements ObservableInternal {\n\t\tpublic set( name: string | { [ name: string ]: unknown }, value?: unknown ): void {\n\t\t\t// If the first parameter is an Object, iterate over its properties.\n\t\t\tif ( isObject( name ) ) {\n\t\t\t\tObject.keys( name ).forEach( property => {\n\t\t\t\t\tthis.set( property, name[ property ] );\n\t\t\t\t}, this );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tinitObservable( this );\n\n\t\t\tconst properties = this[ observablePropertiesSymbol ];\n\n\t\t\tif ( ( name in this ) && !properties!.has( name ) ) {\n\t\t\t\t/**\n\t\t\t\t * Cannot override an existing property.\n\t\t\t\t *\n\t\t\t\t * This error is thrown when trying to {@link module:utils/observablemixin~Observable#set set} a property with\n\t\t\t\t * a name of an already existing property. For example:\n\t\t\t\t *\n\t\t\t\t * ```ts\n\t\t\t\t * let observable = new Model();\n\t\t\t\t * observable.property = 1;\n\t\t\t\t * observable.set( 'property', 2 );\t\t\t// throws\n\t\t\t\t *\n\t\t\t\t * observable.set( 'property', 1 );\n\t\t\t\t * observable.set( 'property', 2 );\t\t\t// ok, because this is an existing property.\n\t\t\t\t * ```\n\t\t\t\t *\n\t\t\t\t * @error observable-set-cannot-override\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-set-cannot-override', this );\n\t\t\t}\n\n\t\t\tObject.defineProperty( this, name, {\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true,\n\n\t\t\t\tget() {\n\t\t\t\t\treturn properties!.get( name );\n\t\t\t\t},\n\n\t\t\t\tset( this: Observable, value ) {\n\t\t\t\t\tconst oldValue = properties!.get( name );\n\n\t\t\t\t\t// Fire `set` event before the new value will be set to make it possible\n\t\t\t\t\t// to override observable property without affecting `change` event.\n\t\t\t\t\t// See https://github.com/ckeditor/ckeditor5-utils/issues/171.\n\t\t\t\t\tlet newValue = this.fire<ObservableSetEvent>( `set:${ name }`, name, value, oldValue );\n\n\t\t\t\t\tif ( newValue === undefined ) {\n\t\t\t\t\t\tnewValue = value;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Allow undefined as an initial value like A.define( 'x', undefined ) (#132).\n\t\t\t\t\t// Note: When properties map has no such own property, then its value is undefined.\n\t\t\t\t\tif ( oldValue !== newValue || !properties!.has( name ) ) {\n\t\t\t\t\t\tproperties!.set( name, newValue );\n\t\t\t\t\t\tthis.fire<ObservableChangeEvent>( `change:${ name }`, name, newValue, oldValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t( this as any )[ name ] = value;\n\t\t}\n\n\t\tpublic bind( ...bindProperties: Array<string> ): any {\n\t\t\tif ( !bindProperties.length || !isStringArray( bindProperties ) ) {\n\t\t\t\t/**\n\t\t\t\t * All properties must be strings.\n\t\t\t\t *\n\t\t\t\t * @error observable-bind-wrong-properties\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-bind-wrong-properties', this );\n\t\t\t}\n\n\t\t\tif ( ( new Set( bindProperties ) ).size !== bindProperties.length ) {\n\t\t\t\t/**\n\t\t\t\t * Properties must be unique.\n\t\t\t\t *\n\t\t\t\t * @error observable-bind-duplicate-properties\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'observable-bind-duplicate-properties', this );\n\t\t\t}\n\n\t\t\tinitObservable( this );\n\n\t\t\tconst boundProperties = this[ boundPropertiesSymbol ];\n\n\t\t\tbindProperties.forEach( propertyName => {\n\t\t\t\tif ( boundProperties!.has( propertyName ) ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Cannot bind the same property more than once.\n\t\t\t\t\t *\n\t\t\t\t\t * @error observable-bind-rebind\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'observable-bind-rebind', this );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tconst bindings = new Map<string, Binding>();\n\n\t\t\tbindProperties.forEach( a => {\n\t\t\t\tconst binding = { property: a, to: [] };\n\n\t\t\t\tboundProperties!.set( a, binding );\n\t\t\t\tbindings.set( a, binding );\n\t\t\t} );\n\n\t\t\treturn {\n\t\t\t\tto: bindTo,\n\t\t\t\ttoMany: bindToMany,\n\n\t\t\t\t_observable: this,\n\t\t\t\t_bindProperties: bindProperties,\n\t\t\t\t_to: [],\n\t\t\t\t_bindings: bindings\n\t\t\t};\n\t\t}\n\n\t\tpublic unbind( ...unbindProperties: Array<keyof this & string> ): void {\n\t\t\t// Nothing to do here if not inited yet.\n\t\t\tif ( !( this[ observablePropertiesSymbol ] ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst boundProperties = this[ boundPropertiesSymbol ]!;\n\t\t\tconst boundObservables = this[ boundObservablesSymbol ]!;\n\n\t\t\tif ( unbindProperties.length ) {\n\t\t\t\tif ( !isStringArray( unbindProperties ) ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Properties must be strings.\n\t\t\t\t\t *\n\t\t\t\t\t * @error observable-unbind-wrong-properties\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'observable-unbind-wrong-properties', this );\n\t\t\t\t}\n\n\t\t\t\tunbindProperties.forEach( propertyName => {\n\t\t\t\t\tconst binding = boundProperties.get( propertyName );\n\n\t\t\t\t\t// Nothing to do if the binding is not defined\n\t\t\t\t\tif ( !binding ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tbinding.to.forEach( ( [ toObservable, toProperty ] ) => {\n\t\t\t\t\t\tconst toProperties = boundObservables.get( toObservable )!;\n\t\t\t\t\t\tconst toPropertyBindings = toProperties[ toProperty ];\n\n\t\t\t\t\t\ttoPropertyBindings.delete( binding );\n\n\t\t\t\t\t\tif ( !toPropertyBindings.size ) {\n\t\t\t\t\t\t\tdelete toProperties[ toProperty ];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( !Object.keys( toProperties ).length ) {\n\t\t\t\t\t\t\tboundObservables.delete( toObservable );\n\t\t\t\t\t\t\tthis.stopListening( toObservable, 'change' );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t\tboundProperties.delete( propertyName );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tboundObservables.forEach( ( bindings, boundObservable ) => {\n\t\t\t\t\tthis.stopListening( boundObservable, 'change' );\n\t\t\t\t} );\n\n\t\t\t\tboundObservables.clear();\n\t\t\t\tboundProperties.clear();\n\t\t\t}\n\t\t}\n\n\t\tpublic decorate( this: this & { [ x: string ]: any }, methodName: keyof this & string ): void {\n\t\t\tinitObservable( this );\n\n\t\t\tconst originalMethod = this[ methodName ];\n\n\t\t\tif ( !originalMethod ) {\n\t\t\t\t/**\n\t\t\t\t * Cannot decorate an undefined method.\n\t\t\t\t *\n\t\t\t\t * @error observablemixin-cannot-decorate-undefined\n\t\t\t\t * @param {Object} object The object which method should be decorated.\n\t\t\t\t * @param {String} methodName Name of the method which does not exist.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'observablemixin-cannot-decorate-undefined',\n\t\t\t\t\tthis,\n\t\t\t\t\t{ object: this, methodName }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tthis.on( methodName, ( evt, args ) => {\n\t\t\t\tevt.return = originalMethod.apply( this, args );\n\t\t\t} );\n\n\t\t\tthis[ methodName ] = function( ...args: Array<unknown> ) {\n\t\t\t\treturn this.fire( methodName, args );\n\t\t\t};\n\n\t\t\tthis[ methodName ][ decoratedOriginal ] = originalMethod;\n\n\t\t\tif ( !this[ decoratedMethods ] ) {\n\t\t\t\tthis[ decoratedMethods ] = [];\n\t\t\t}\n\n\t\t\tthis[ decoratedMethods ]!.push( methodName );\n\t\t}\n\n\t\t// Override the EmitterMixin stopListening method to be able to clean (and restore) decorated methods.\n\t\t// This is needed in case of:\n\t\t//  1. Have x.foo() decorated.\n\t\t//  2. Call x.stopListening()\n\t\t//  3. Call x.foo(). Problem: nothing happens (the original foo() method is not executed)\n\t\tpublic override stopListening(\n\t\t\tthis: ObservableInternal & { [ x: string ]: any },\n\t\t\temitter?: Emitter,\n\t\t\tevent?: string,\n\t\t\tcallback?: Function\n\t\t): void {\n\t\t\t// Removing all listeners so let's clean the decorated methods to the original state.\n\t\t\tif ( !emitter && this[ decoratedMethods ] ) {\n\t\t\t\tfor ( const methodName of this[ decoratedMethods ]! ) {\n\t\t\t\t\tthis[ methodName ] = this[ methodName ][ decoratedOriginal ];\n\t\t\t\t}\n\n\t\t\t\tdelete this[ decoratedMethods ];\n\t\t\t}\n\n\t\t\tsuper.stopListening( emitter, event, callback );\n\t\t}\n\n\t\tpublic [ observablePropertiesSymbol ]?: Map<string, unknown>;\n\n\t\tpublic [ decoratedMethods ]?: Array<string>;\n\n\t\tpublic [ boundPropertiesSymbol ]?: Map<string, Binding>;\n\n\t\tpublic [ boundObservablesSymbol ]?: Map<Observable, Record<string, Set<Binding>>>;\n\t}\n\n\treturn Mixin;\n}\n\n// Backward compatibility with `mix`\n( [\n\t'set', 'bind', 'unbind', 'decorate',\n\t'on', 'once', 'off', 'listenTo',\n\t'stopListening', 'fire', 'delegate', 'stopDelegating',\n\t'_addEventListener', '_removeEventListener'\n] ).forEach( key => {\n\t( ObservableMixin as any )[ key ] = ( defaultObservableClass.prototype as any )[ key ];\n} );\n\ninterface Binding {\n\n\t/**\n\t * Property which is bound.\n\t */\n\tproperty: string;\n\n\t/**\n\t * Array of observable–property components of the binding (`{ observable: ..., property: .. }`).\n\t */\n\tto: Array<[ Observable, string ]>;\n\n\t/**\n\t * A function which processes `to` components.\n\t */\n\tcallback?: Function;\n}\n\ninterface BindChainInternal {\n\tto: Function;\n\t_observable: Observable;\n\t_bindings: Map<string, Binding>;\n\t_bindProperties: Array<string>;\n\t_to: Array<{\n\t\tobservable: Observable;\n\t\tproperties: Array<string>;\n\t}>;\n}\n\n// Init symbol properties needed for the observable mechanism to work.\nfunction initObservable( observable: ObservableInternal ): void {\n\t// Do nothing if already inited.\n\tif ( observable[ observablePropertiesSymbol ] ) {\n\t\treturn;\n\t}\n\n\t// The internal hash containing the observable's state.\n\tObject.defineProperty( observable, observablePropertiesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Map containing bindings to external observables. It shares the binding objects\n\t// (`{ observable: A, property: 'a', to: ... }`) with {@link module:utils/observablemixin~Observable#_boundProperties} and\n\t// it is used to observe external observables to update own properties accordingly.\n\t// See {@link module:utils/observablemixin~Observable#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundObservables );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\tB: {\n\t//\t\t\t\t\tx: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\t\t\t{ observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\ty: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\t\t] ),\n\t//\t\t\t\t\tz: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t},\n\t//\t\t\t\tC: {\n\t//\t\t\t\t\tw: Set( [\n\t//\t\t\t\t\t\t{ observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t\t\t] )\n\t//\t\t\t\t}\n\t//\t\t\t} )\n\t//\n\tObject.defineProperty( observable, boundObservablesSymbol, {\n\t\tvalue: new Map()\n\t} );\n\n\t// Object that stores which properties of this observable are bound and how. It shares\n\t// the binding objects (`{ observable: A, property: 'a', to: ... }`) with\n\t// {@link module:utils/observablemixin~Observable#_boundObservables}. This data structure is\n\t// a reverse of {@link module:utils/observablemixin~Observable#_boundObservables} and it is helpful for\n\t// {@link module:utils/observablemixin~Observable#unbind}.\n\t//\n\t// See {@link module:utils/observablemixin~Observable#bind}.\n\t//\n\t//\t\tA.bind( 'a', 'b', 'c' ).to( B, 'x', 'y', 'x' );\n\t//\t\tconsole.log( A._boundProperties );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] }\n\t//\t\t\t} )\n\t//\n\t//\t\tA.bind( 'd' ).to( B, 'z' ).to( C, 'w' ).as( callback );\n\t//\t\tconsole.log( A._boundProperties );\n\t//\n\t//\t\t\tMap( {\n\t//\t\t\t\ta: { observable: A, property: 'a', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\tb: { observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n\t//\t\t\t\tc: { observable: A, property: 'c', to: [ [ B, 'x' ] ] },\n\t//\t\t\t\td: { observable: A, property: 'd', to: [ [ B, 'z' ], [ C, 'w' ] ], callback: callback }\n\t//\t\t\t} )\n\tObject.defineProperty( observable, boundPropertiesSymbol, {\n\t\tvalue: new Map()\n\t} );\n}\n\n/**\n * A chaining for {@link module:utils/observablemixin~Observable#bind} providing `.to()` interface.\n *\n * @param args Arguments of the `.to( args )` binding.\n */\nfunction bindTo( this: BindChainInternal, ...args: Array<Observable | string | Function> ): void {\n\tconst parsedArgs = parseBindToArgs( ...args );\n\tconst bindingsKeys = Array.from( this._bindings.keys() );\n\tconst numberOfBindings = bindingsKeys.length;\n\n\t// Eliminate A.bind( 'x' ).to( B, C )\n\tif ( !parsedArgs.callback && parsedArgs.to.length > 1 ) {\n\t\t/**\n\t\t * Binding multiple observables only possible with callback.\n\t\t *\n\t\t * @error observable-bind-to-no-callback\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-no-callback', this );\n\t}\n\n\t// Eliminate A.bind( 'x', 'y' ).to( B, callback )\n\tif ( numberOfBindings > 1 && parsedArgs.callback ) {\n\t\t/**\n\t\t * Cannot bind multiple properties and use a callback in one binding.\n\t\t *\n\t\t * @error observable-bind-to-extra-callback\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'observable-bind-to-extra-callback',\n\t\t\tthis\n\t\t);\n\t}\n\n\tparsedArgs.to.forEach( to => {\n\t\t// Eliminate A.bind( 'x', 'y' ).to( B, 'a' )\n\t\tif ( to.properties.length && to.properties.length !== numberOfBindings ) {\n\t\t\t/**\n\t\t\t * The number of properties must match.\n\t\t\t *\n\t\t\t * @error observable-bind-to-properties-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'observable-bind-to-properties-length', this );\n\t\t}\n\n\t\t// When no to.properties specified, observing source properties instead i.e.\n\t\t// A.bind( 'x', 'y' ).to( B ) -> Observe B.x and B.y\n\t\tif ( !to.properties.length ) {\n\t\t\tto.properties = this._bindProperties;\n\t\t}\n\t} );\n\n\tthis._to = parsedArgs.to;\n\n\t// Fill {@link BindChain#_bindings} with callback. When the callback is set there's only one binding.\n\tif ( parsedArgs.callback ) {\n\t\tthis._bindings.get( bindingsKeys[ 0 ] )!.callback = parsedArgs.callback;\n\t}\n\n\tattachBindToListeners( this._observable, this._to );\n\n\t// Update observable._boundProperties and observable._boundObservables.\n\tupdateBindToBound( this );\n\n\t// Set initial values of bound properties.\n\tthis._bindProperties.forEach( propertyName => {\n\t\tupdateBoundObservableProperty( this._observable, propertyName );\n\t} );\n}\n\n/**\n * Binds to an attribute in a set of iterable observables.\n */\nfunction bindToMany( this: BindChainInternal, observables: Array<Observable>, attribute: string, callback: Function ): void {\n\tif ( this._bindings.size > 1 ) {\n\t\t/**\n\t\t * Binding one attribute to many observables only possible with one attribute.\n\t\t *\n\t\t * @error observable-bind-to-many-not-one-binding\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-many-not-one-binding', this );\n\t}\n\n\tthis.to(\n\t\t// Bind to #attribute of each observable...\n\t\t...getBindingTargets( observables, attribute ),\n\t\t// ...using given callback to parse attribute values.\n\t\tcallback\n\t);\n}\n\n/**\n * Returns an array of binding components for\n * {@link Observable#bind} from a set of iterable observables.\n */\nfunction getBindingTargets( observables: Array<Observable>, attribute: string ): Array<Observable | string> {\n\tconst observableAndAttributePairs = observables.map( observable => [ observable, attribute ] );\n\n\t// Merge pairs to one-dimension array of observables and attributes.\n\treturn Array.prototype.concat.apply( [], observableAndAttributePairs );\n}\n\n/**\n * Check if all entries of the array are of `String` type.\n */\nfunction isStringArray( arr: Array<unknown> ): arr is Array<string> {\n\treturn arr.every( a => typeof a == 'string' );\n}\n\n/**\n * Parses and validates {@link Observable#bind}`.to( args )` arguments and returns\n * an object with a parsed structure. For example\n *\n * ```ts\n * A.bind( 'x' ).to( B, 'a', C, 'b', call );\n * ```\n *\n * becomes\n *\n * ```ts\n * {\n * \tto: [\n * \t\t{ observable: B, properties: [ 'a' ] },\n * \t\t{ observable: C, properties: [ 'b' ] },\n * \t],\n * \tcallback: call\n * }\n *\n * @param args Arguments of {@link Observable#bind}`.to( args )`.\n */\nfunction parseBindToArgs( ...args: Array<Observable | string | Function> ) {\n\t// Eliminate A.bind( 'x' ).to()\n\tif ( !args.length ) {\n\t\t/**\n\t\t * Invalid argument syntax in `to()`.\n\t\t *\n\t\t * @error observable-bind-to-parse-error\n\t\t */\n\t\tthrow new CKEditorError( 'observable-bind-to-parse-error', null );\n\t}\n\n\tconst parsed: { to: BindChainInternal[ '_to' ]; callback?: Function } = { to: [] };\n\tlet lastObservable: { observable: Observable; properties: Array<string> };\n\n\tif ( typeof args[ args.length - 1 ] == 'function' ) {\n\t\tparsed.callback = args.pop() as Function;\n\t}\n\n\targs.forEach( a => {\n\t\tif ( typeof a == 'string' ) {\n\t\t\tlastObservable.properties.push( a );\n\t\t} else if ( typeof a == 'object' ) {\n\t\t\tlastObservable = { observable: a, properties: [] };\n\t\t\tparsed.to.push( lastObservable );\n\t\t} else {\n\t\t\tthrow new CKEditorError( 'observable-bind-to-parse-error', null );\n\t\t}\n\t} );\n\n\treturn parsed;\n}\n\n/**\n * Synchronizes {@link module:utils/observable#_boundObservables} with {@link Binding}.\n *\n * @param binding A binding to store in {@link Observable#_boundObservables}.\n * @param toObservable A observable, which is a new component of `binding`.\n * @param toPropertyName A name of `toObservable`'s property, a new component of the `binding`.\n */\nfunction updateBoundObservables(\n\tobservable: ObservableInternal,\n\tbinding: Binding,\n\ttoObservable: Observable,\n\ttoPropertyName: string\n): void {\n\tconst boundObservables = observable[ boundObservablesSymbol ]!;\n\tconst bindingsToObservable = boundObservables.get( toObservable );\n\tconst bindings = bindingsToObservable || {};\n\n\tif ( !bindings[ toPropertyName ] ) {\n\t\tbindings[ toPropertyName ] = new Set();\n\t}\n\n\t// Pass the binding to a corresponding Set in `observable._boundObservables`.\n\tbindings[ toPropertyName ].add( binding );\n\n\tif ( !bindingsToObservable ) {\n\t\tboundObservables.set( toObservable, bindings );\n\t}\n}\n\n/**\n * Synchronizes {@link Observable#_boundProperties} and {@link Observable#_boundObservables}\n * with {@link BindChain}.\n *\n * Assuming the following binding being created\n *\n * ```ts\n * A.bind( 'a', 'b' ).to( B, 'x', 'y' );\n * ```\n *\n * the following bindings were initialized by {@link Observable#bind} in {@link BindChain#_bindings}:\n *\n * ```ts\n * {\n * \ta: { observable: A, property: 'a', to: [] },\n * \tb: { observable: A, property: 'b', to: [] },\n * }\n * ```\n *\n * Iterate over all bindings in this chain and fill their `to` properties with\n * corresponding to( ... ) arguments (components of the binding), so\n *\n * ```ts\n * {\n * \ta: { observable: A, property: 'a', to: [ B, 'x' ] },\n * \tb: { observable: A, property: 'b', to: [ B, 'y' ] },\n * }\n * ```\n *\n * Then update the structure of {@link Observable#_boundObservables} with updated\n * binding, so it becomes:\n *\n * ```ts\n * Map( {\n * \tB: {\n * \t\tx: Set( [\n * \t\t\t{ observable: A, property: 'a', to: [ [ B, 'x' ] ] }\n * \t\t] ),\n * \t\ty: Set( [\n * \t\t\t{ observable: A, property: 'b', to: [ [ B, 'y' ] ] },\n * \t\t] )\n * \t}\n * } )\n * ```\n *\n * @param chain The binding initialized by {@link Observable#bind}.\n */\nfunction updateBindToBound( chain: BindChainInternal ): void {\n\tlet toProperty;\n\n\tchain._bindings.forEach( ( binding, propertyName ) => {\n\t\t// Note: For a binding without a callback, this will run only once\n\t\t// like in A.bind( 'x', 'y' ).to( B, 'a', 'b' )\n\t\t// TODO: ES6 destructuring.\n\t\tchain._to.forEach( to => {\n\t\t\ttoProperty = to.properties[ binding.callback ? 0 : chain._bindProperties.indexOf( propertyName ) ];\n\n\t\t\tbinding.to.push( [ to.observable, toProperty ] );\n\t\t\tupdateBoundObservables( chain._observable, binding, to.observable, toProperty );\n\t\t} );\n\t} );\n}\n\n/**\n * Updates an property of a {@link Observable} with a value\n * determined by an entry in {@link Observable#_boundProperties}.\n *\n * @param observable A observable which property is to be updated.\n * @param propertyName An property to be updated.\n */\nfunction updateBoundObservableProperty( observable: ObservableInternal, propertyName: string ): void {\n\tconst boundProperties = observable[ boundPropertiesSymbol ]!;\n\tconst binding = boundProperties.get( propertyName )!;\n\tlet propertyValue;\n\n\t// When a binding with callback is created like\n\t//\n\t// \t\tA.bind( 'a' ).to( B, 'b', C, 'c', callback );\n\t//\n\t// collect B.b and C.c, then pass them to callback to set A.a.\n\tif ( binding.callback ) {\n\t\tpropertyValue = binding.callback.apply( observable, binding.to.map( to => ( to[ 0 ] as any )[ to[ 1 ] ] ) );\n\t} else {\n\t\tpropertyValue = binding.to[ 0 ];\n\t\tpropertyValue = ( propertyValue[ 0 ] as any )[ propertyValue[ 1 ] ];\n\t}\n\n\tif ( Object.prototype.hasOwnProperty.call( observable, propertyName ) ) {\n\t\t( observable as any )[ propertyName ] = propertyValue;\n\t} else {\n\t\tobservable.set( propertyName as any, propertyValue );\n\t}\n}\n\n/**\n * Starts listening to changes in {@link BindChain._to} observables to update\n * {@link BindChain._observable} {@link BindChain._bindProperties}. Also sets the\n * initial state of {@link BindChain._observable}.\n *\n * @param chain The chain initialized by {@link Observable#bind}.\n */\nfunction attachBindToListeners( observable: ObservableInternal, toBindings: BindChainInternal[ '_to' ] ): void {\n\ttoBindings.forEach( to => {\n\t\tconst boundObservables = observable[ boundObservablesSymbol ]!;\n\t\tlet bindings;\n\n\t\t// If there's already a chain between the observables (`observable` listens to\n\t\t// `to.observable`), there's no need to create another `change` event listener.\n\t\tif ( !boundObservables.get( to.observable ) ) {\n\t\t\tobservable.listenTo<ObservableChangeEvent>( to.observable, 'change', ( evt, propertyName ) => {\n\t\t\t\tbindings = boundObservables.get( to.observable )![ propertyName ];\n\n\t\t\t\t// Note: to.observable will fire for any property change, react\n\t\t\t\t// to changes of properties which are bound only.\n\t\t\t\tif ( bindings ) {\n\t\t\t\t\tbindings.forEach( binding => {\n\t\t\t\t\t\tupdateBoundObservableProperty( observable, binding.property );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n}\n\n/**\n * An interface which adds \"observable properties\" and data binding functionality.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/observablemixin~Observable} mixin.\n *\n * ```ts\n * class MyClass extends ObservableMixin( OtherBaseClass ) {\n * \t// This class now implements the `Observable` interface.\n * }\n * ```\n *\n * Read more about the usage of this interface in the:\n * * {@glink framework/architecture/core-editor-architecture#event-system-and-observables Event system and observables}\n * section of the {@glink framework/architecture/core-editor-architecture Core editor architecture} guide,\n * * {@glink framework/deep-dive/observables Observables deep-dive} guide.\n */\nexport interface Observable extends Emitter {\n\n\t/**\n\t * Creates and sets the value of an observable property of this object. Such a property becomes a part\n\t * of the state and is observable.\n\t *\n\t * This method throws the `observable-set-cannot-override` error if the observable instance already\n\t * has a property with the given property name. This prevents from mistakenly overriding existing\n\t * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.\n\t *\n\t * In TypeScript, those properties should be declared in class using `declare` keyword. In example:\n\t *\n\t * ```ts\n\t * public declare myProp: number;\n\t *\n\t * constructor() {\n\t * \tthis.set( 'myProp', 2 );\n\t * }\n\t * ```\n\t *\n\t * @label KEY_VALUE\n\t * @param name The property's name.\n\t * @param value The property's value.\n\t */\n\tset<K extends keyof this & string>( name: K, value: this[ K ] ): void;\n\n\t/**\n\t * Creates and sets the value of an observable properties of this object. Such a property becomes a part\n\t * of the state and is observable.\n\t *\n\t * It accepts a single object literal containing key/value pairs with properties to be set.\n\t *\n\t * This method throws the `observable-set-cannot-override` error if the observable instance already\n\t * has a property with the given property name. This prevents from mistakenly overriding existing\n\t * properties and methods, but means that `foo.set( 'bar', 1 )` may be slightly slower than `foo.bar = 1`.\n\t *\n\t * In TypeScript, those properties should be declared in class using `declare` keyword. In example:\n\t *\n\t * ```ts\n\t * public declare myProp1: number;\n\t * public declare myProp2: string;\n\t *\n\t * constructor() {\n\t * \tthis.set( {\n\t * \t\t'myProp1: 2,\n\t * \t\t'myProp2: 'foo'\n\t * \t} );\n\t * }\n\t * ```\n\t * @label OBJECT\n\t * @param values An object with `name=>value` pairs.\n\t */\n\tset( values: object & { readonly [ K in keyof this ]?: unknown } ): void;\n\n\t/**\n\t * Binds {@link #set observable properties} to other objects implementing the\n\t * {@link module:utils/observablemixin~Observable} interface.\n\t *\n\t * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide\n\t * covering the topic of property bindings with some additional examples.\n\t *\n\t * Consider two objects: a `button` and an associated `command` (both `Observable`).\n\t *\n\t * A simple property binding could be as follows:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t * ```\n\t *\n\t * or even shorter:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command );\n\t * ```\n\t *\n\t * which works in the following way:\n\t *\n\t * * `button.isEnabled` **instantly equals** `command.isEnabled`,\n\t * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.\n\t *\n\t * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.\n\t *\n\t * You can also \"rename\" the property in the binding by specifying the new name in the `to()` chain:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isWorking' );\n\t * ```\n\t *\n\t * It is possible to bind more than one property at a time to shorten the code:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled', 'value' ).to( command );\n\t * ```\n\t *\n\t * which corresponds to:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command );\n\t * button.bind( 'value' ).to( command );\n\t * ```\n\t *\n\t * The binding can include more than one observable, combining multiple data sources in a custom callback:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',\n\t * \t( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );\n\t * ```\n\t *\n\t * Using a custom callback allows processing the value before passing it to the target property:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );\n\t * ```\n\t *\n\t * It is also possible to bind to the same property in an array of observables.\n\t * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them\n\t * must be enabled for the button to become enabled, use the following code:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',\n\t * \t( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );\n\t * ```\n\t *\n\t * @label SINGLE_BIND\n\t * @param bindProperty Observable property that will be bound to other observable(s).\n\t * @returns The bind chain with the `to()` and `toMany()` methods.\n\t */\n\tbind<K extends keyof this & string>(\n\t\tbindProperty: K\n\t): SingleBindChain<K, this[ K ]>;\n\n\t/**\n\t * Binds {@link #set observable properties} to other objects implementing the\n\t * {@link module:utils/observablemixin~Observable} interface.\n\t *\n\t * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide\n\t * covering the topic of property bindings with some additional examples.\n\t *\n\t * Consider two objects: a `button` and an associated `command` (both `Observable`).\n\t *\n\t * A simple property binding could be as follows:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t * ```\n\t *\n\t * or even shorter:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command );\n\t * ```\n\t *\n\t * which works in the following way:\n\t *\n\t * * `button.isEnabled` **instantly equals** `command.isEnabled`,\n\t * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.\n\t *\n\t * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.\n\t *\n\t * You can also \"rename\" the property in the binding by specifying the new name in the `to()` chain:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isWorking' );\n\t * ```\n\t *\n\t * It is possible to bind more than one property at a time to shorten the code:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled', 'value' ).to( command );\n\t * ```\n\t *\n\t * which corresponds to:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command );\n\t * button.bind( 'value' ).to( command );\n\t * ```\n\t *\n\t * The binding can include more than one observable, combining multiple data sources in a custom callback:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',\n\t * \t( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );\n\t * ```\n\t *\n\t * Using a custom callback allows processing the value before passing it to the target property:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );\n\t * ```\n\t *\n\t * It is also possible to bind to the same property in an array of observables.\n\t * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them\n\t * must be enabled for the button to become enabled, use the following code:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',\n\t * \t( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );\n\t * ```\n\t *\n\t * @label DUAL_BIND\n\t * @param bindProperty1 Observable property that will be bound to other observable(s).\n\t * @param bindProperty2 Observable property that will be bound to other observable(s).\n\t * @returns The bind chain with the `to()` and `toMany()` methods.\n\t */\n\tbind<K1 extends keyof this & string, K2 extends keyof this & string>(\n\t\tbindProperty1: K1,\n\t\tbindProperty2: K2\n\t): DualBindChain<K1, this[ K1 ], K2, this[ K2 ]>;\n\n\t/**\n\t * Binds {@link #set observable properties} to other objects implementing the\n\t * {@link module:utils/observablemixin~Observable} interface.\n\t *\n\t * Read more in the {@glink framework/deep-dive/observables#property-bindings dedicated} guide\n\t * covering the topic of property bindings with some additional examples.\n\t *\n\t * Consider two objects: a `button` and an associated `command` (both `Observable`).\n\t *\n\t * A simple property binding could be as follows:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t * ```\n\t *\n\t * or even shorter:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command );\n\t * ```\n\t *\n\t * which works in the following way:\n\t *\n\t * * `button.isEnabled` **instantly equals** `command.isEnabled`,\n\t * * whenever `command.isEnabled` changes, `button.isEnabled` will immediately reflect its value.\n\t *\n\t * **Note**: To release the binding, use {@link module:utils/observablemixin~Observable#unbind}.\n\t *\n\t * You can also \"rename\" the property in the binding by specifying the new name in the `to()` chain:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isWorking' );\n\t * ```\n\t *\n\t * It is possible to bind more than one property at a time to shorten the code:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled', 'value' ).to( command );\n\t * ```\n\t *\n\t * which corresponds to:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command );\n\t * button.bind( 'value' ).to( command );\n\t * ```\n\t *\n\t * The binding can include more than one observable, combining multiple data sources in a custom callback:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'isEnabled', ui, 'isVisible',\n\t * \t( isCommandEnabled, isUIVisible ) => isCommandEnabled && isUIVisible );\n\t * ```\n\t *\n\t * Using a custom callback allows processing the value before passing it to the target property:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).to( command, 'value', value => value === 'heading1' );\n\t * ```\n\t *\n\t * It is also possible to bind to the same property in an array of observables.\n\t * To bind a `button` to multiple commands (also `Observables`) so that each and every one of them\n\t * must be enabled for the button to become enabled, use the following code:\n\t *\n\t * ```ts\n\t * button.bind( 'isEnabled' ).toMany( [ commandA, commandB, commandC ], 'isEnabled',\n\t * \t( isAEnabled, isBEnabled, isCEnabled ) => isAEnabled && isBEnabled && isCEnabled );\n\t * ```\n\t *\n\t * @label MANY_BIND\n\t * @param bindProperties Observable properties that will be bound to other observable(s).\n\t * @returns The bind chain with the `to()` and `toMany()` methods.\n\t */\n\tbind( ...bindProperties: Array<keyof this & string> ): MultiBindChain;\n\n\t/**\n\t * Removes the binding created with {@link #bind}.\n\t *\n\t * ```ts\n\t * // Removes the binding for the 'a' property.\n\t * A.unbind( 'a' );\n\t *\n\t * // Removes bindings for all properties.\n\t * A.unbind();\n\t * ```\n\t *\n\t * @param unbindProperties Observable properties to be unbound. All the bindings will\n\t * be released if no properties are provided.\n\t */\n\tunbind( ...unbindProperties: Array<keyof this & string> ): void;\n\n\t/**\n\t * Turns the given methods of this object into event-based ones. This means that the new method will fire an event\n\t * (named after the method) and the original action will be plugged as a listener to that event.\n\t *\n\t * Read more in the {@glink framework/deep-dive/observables#decorating-object-methods dedicated} guide\n\t * covering the topic of decorating methods with some additional examples.\n\t *\n\t * Decorating the method does not change its behavior (it only adds an event),\n\t * but it allows to modify it later on by listening to the method's event.\n\t *\n\t * For example, to cancel the method execution the event can be {@link module:utils/eventinfo~EventInfo#stop stopped}:\n\t *\n\t * ```ts\n\t * class Foo extends ObservableMixin() {\n\t * \tconstructor() {\n\t * \t\tsuper();\n\t * \t\tthis.decorate( 'method' );\n\t * \t}\n\t *\n\t * \tmethod() {\n\t * \t\tconsole.log( 'called!' );\n\t * \t}\n\t * }\n\t *\n\t * const foo = new Foo();\n\t * foo.on( 'method', ( evt ) => {\n\t * \tevt.stop();\n\t * }, { priority: 'high' } );\n\t *\n\t * foo.method(); // Nothing is logged.\n\t * ```\n\t *\n\t *\n\t * **Note**: The high {@link module:utils/priorities~PriorityString priority} listener\n\t * has been used to execute this particular callback before the one which calls the original method\n\t * (which uses the \"normal\" priority).\n\t *\n\t * It is also possible to change the returned value:\n\t *\n\t * ```ts\n\t * foo.on( 'method', ( evt ) => {\n\t * \tevt.return = 'Foo!';\n\t * } );\n\t *\n\t * foo.method(); // -> 'Foo'\n\t * ```\n\t *\n\t * Finally, it is possible to access and modify the arguments the method is called with:\n\t *\n\t * ```ts\n\t * method( a, b ) {\n\t * \tconsole.log( `${ a }, ${ b }`  );\n\t * }\n\t *\n\t * // ...\n\t *\n\t * foo.on( 'method', ( evt, args ) => {\n\t * \targs[ 0 ] = 3;\n\t *\n\t * \tconsole.log( args[ 1 ] ); // -> 2\n\t * }, { priority: 'high' } );\n\t *\n\t * foo.method( 1, 2 ); // -> '3, 2'\n\t * ```\n\t *\n\t * @param methodName Name of the method to decorate.\n\t */\n\tdecorate( methodName: keyof this & string ): void;\n}\n\ninterface ObservableInternal extends Observable {\n\t[ observablePropertiesSymbol ]?: Map<string, unknown>;\n\n\t[ decoratedMethods ]?: Array<string>;\n\n\t[ boundPropertiesSymbol ]?: Map<string, Binding>;\n\n\t[ boundObservablesSymbol]?: Map<Observable, Record<string, Set<Binding>>>;\n}\n\n/**\n * Fired when a property changed value.\n *\n * ```ts\n * observable.set( 'prop', 1 );\n *\n * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n * \tconsole.log( `${ propertyName } has changed from ${ oldValue } to ${ newValue }` );\n * } );\n *\n * observable.prop = 2; // -> 'prop has changed from 1 to 2'\n * ```\n *\n * @eventName ~Observable#change:\\{property\\}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\nexport type ObservableChangeEvent<TValue = any> = {\n\tname: 'change' | `change:${ string }`;\n\targs: [ name: string, value: TValue, oldValue: TValue ];\n};\n\n/**\n * Fired when a property value is going to be set but is not set yet (before the `change` event is fired).\n *\n * You can control the final value of the property by using\n * the {@link module:utils/eventinfo~EventInfo#return event's `return` property}.\n *\n * ```ts\n * observable.set( 'prop', 1 );\n *\n * observable.on<ObservableSetEvent<number>>( 'set:prop', ( evt, propertyName, newValue, oldValue ) => {\n * \tconsole.log( `Value is going to be changed from ${ oldValue } to ${ newValue }` );\n * \tconsole.log( `Current property value is ${ observable[ propertyName ] }` );\n *\n * \t// Let's override the value.\n * \tevt.return = 3;\n * } );\n *\n * observable.on<ObservableChangeEvent<number>>( 'change:prop', ( evt, propertyName, newValue, oldValue ) => {\n * \tconsole.log( `Value has changed from ${ oldValue } to ${ newValue }` );\n * } );\n *\n * observable.prop = 2; // -> 'Value is going to be changed from 1 to 2'\n *                      // -> 'Current property value is 1'\n *                      // -> 'Value has changed from 1 to 3'\n * ```\n *\n * **Note:** The event is fired even when the new value is the same as the old value.\n *\n * @eventName ~Observable#set:\\{property\\}\n * @param {String} name The property name.\n * @param {*} value The new property value.\n * @param {*} oldValue The previous property value.\n */\nexport type ObservableSetEvent<TValue = any> = {\n\tname: 'set' | `set:${ string }`;\n\targs: [ name: string, value: TValue, oldValue: TValue ];\n\treturn: TValue;\n};\n\n/**\n * Utility type that creates an event describing type from decorated method.\n *\n * ```ts\n * class Foo extends ObservableMixin() {\n * \tconstructor() {\n * \t\tsuper();\n * \t\tthis.decorate( 'method' );\n * \t}\n *\n * \tmethod( a: number, b: number ): number {\n * \t\treturn a + b;\n * \t}\n * }\n *\n * type FooMethodEvent = DecoratedMethodEvent<Foo, 'method'>;\n *\n * const foo = new Foo();\n *\n * foo.on<FooMethodEvent>( 'method', ( evt, [ a, b ] ) => {\n * \t// `a` and `b` are inferred as numbers.\n * } )\n * ```\n */\nexport type DecoratedMethodEvent<\n\tTObservable extends Observable & { [ N in TName ]: ( ...args: Array<any> ) => any },\n\tTName extends keyof TObservable & string\n> = {\n\tname: TName;\n\targs: [ Parameters<TObservable[ TName ]> ];\n\treturn: ReturnType<TObservable[ TName ]>;\n};\n\ninterface SingleBindChain<TKey extends string, TVal> {\n\ttoMany<O extends Observable, K extends keyof O>(\n\t\tobservables: ReadonlyArray<O>,\n\t\tkey: K,\n\t\tcallback: ( ...values: Array<O[ K ]> ) => TVal\n\t): void;\n\n\tto<O extends ObservableWithProperty<TKey, TVal>>(\n\t\tobservable: O\n\t): void;\n\tto<O extends ObservableWithProperty<TKey>>(\n\t\tobservable: O,\n\t\tcallback: ( value: O[ TKey ] ) => TVal\n\t): void;\n\tto<O extends ObservableWithProperty<K, TVal>, K extends keyof O>(\n\t\tobservable: O,\n\t\tkey: K\n\t): void;\n\tto<O extends Observable, K extends keyof O>(\n\t\tobservable: O,\n\t\tkey: K,\n\t\tcallback: ( value: O[ K ] ) => TVal,\n\t): void;\n\tto<\n\t\tO1 extends ObservableWithProperty<TKey>,\n\t\tO2 extends ObservableWithProperty<TKey>\n\t>(\n\t\tobservable1: O1,\n\t\tobservable2: O2,\n\t\tcallback: ( value1: O1[ TKey ], value2: O2[ TKey ] ) => TVal\n\t): void;\n\tto<\n\t\tO1 extends Observable,\n\t\tK1 extends keyof O1,\n\t\tO2 extends Observable,\n\t\tK2 extends keyof O2\n\t>(\n\t\tobservable1: O1,\n\t\tkey1: K1,\n\t\tobservable2: O2,\n\t\tkey2: K2,\n\t\tcallback: ( value1: O1[ K1 ], value2: O2[ K2 ] ) => TVal\n\t): void;\n\tto<\n\t\tO1 extends ObservableWithProperty<TKey>,\n\t\tO2 extends ObservableWithProperty<TKey>,\n\t\tO3 extends ObservableWithProperty<TKey>\n\t>(\n\t\tobservable1: O1,\n\t\tobservable2: O2,\n\t\tobservable3: O3,\n\t\tcallback: ( value1: O1[ TKey ], value2: O2[ TKey ], value3: O3[ TKey ] ) => TVal\n\t): void;\n\tto<\n\t\tO1 extends Observable,\n\t\tK1 extends keyof O1,\n\t\tO2 extends Observable,\n\t\tK2 extends keyof O2,\n\t\tO3 extends Observable,\n\t\tK3 extends keyof O3\n\t>(\n\t\tobservable1: O1,\n\t\tkey1: K1,\n\t\tobservable2: O2,\n\t\tkey2: K2,\n\t\tobservable3: O3,\n\t\tkey3: K3,\n\t\tcallback: ( value1: O1[ K1 ], value2: O2[ K2 ], value3: O3[ K3 ] ) => TVal\n\t): void;\n\tto<\n\t\tO1 extends ObservableWithProperty<TKey>,\n\t\tO2 extends ObservableWithProperty<TKey>,\n\t\tO3 extends ObservableWithProperty<TKey>,\n\t\tO4 extends ObservableWithProperty<TKey>\n\t>(\n\t\tobservable1: O1,\n\t\tobservable2: O2,\n\t\tobservable3: O3,\n\t\tobservable4: O4,\n\t\tcallback: ( value1: O1[ TKey ], value2: O2[ TKey ], value3: O3[ TKey ], value4: O4[ TKey ] ) => TVal\n\t): void;\n\tto<\n\t\tO1 extends Observable,\n\t\tK1 extends keyof O1,\n\t\tO2 extends Observable,\n\t\tK2 extends keyof O2,\n\t\tO3 extends Observable,\n\t\tK3 extends keyof O3,\n\t\tO4 extends Observable,\n\t\tK4 extends keyof O4\n\t>(\n\t\tobservable1: O1,\n\t\tkey1: K1,\n\t\tobservable2: O2,\n\t\tkey2: K2,\n\t\tobservable3: O3,\n\t\tkey3: K3,\n\t\tobservable4: O4,\n\t\tkey4: K4,\n\t\tcallback: ( value1: O1[ K1 ], value2: O2[ K2 ], value3: O3[ K3 ], value4: O4[ K4 ] ) => TVal\n\t): void;\n\tto<\n\t\tO1 extends ObservableWithProperty<TKey>,\n\t\tO2 extends ObservableWithProperty<TKey>,\n\t\tO3 extends ObservableWithProperty<TKey>,\n\t\tO4 extends ObservableWithProperty<TKey>,\n\t\tO5 extends ObservableWithProperty<TKey>\n\t>(\n\t\tobservable1: O1,\n\t\tobservable2: O2,\n\t\tobservable3: O3,\n\t\tobservable4: O4,\n\t\tobservable5: O5,\n\t\tcallback: ( value1: O1[ TKey ], value2: O2[ TKey ], value3: O3[ TKey ], value4: O4[ TKey ], value5: O5[ TKey ] ) => TVal\n\t): void;\n\tto<\n\t\tO1 extends Observable,\n\t\tK1 extends keyof O1,\n\t\tO2 extends Observable,\n\t\tK2 extends keyof O2,\n\t\tO3 extends Observable,\n\t\tK3 extends keyof O3,\n\t\tO4 extends Observable,\n\t\tK4 extends keyof O4,\n\t\tO5 extends Observable,\n\t\tK5 extends keyof O5\n\t>(\n\t\tobservable1: O1,\n\t\tkey1: K1,\n\t\tobservable2: O2,\n\t\tkey2: K2,\n\t\tobservable3: O3,\n\t\tkey3: K3,\n\t\tobservable4: O4,\n\t\tkey4: K4,\n\t\tobservable5: O5,\n\t\tkey5: K5,\n\t\tcallback: ( value1: O1[ K1 ], value2: O2[ K2 ], value3: O3[ K3 ], value4: O4[ K4 ], value5: O5[ K5 ] ) => TVal\n\t): void;\n}\n\n/**\n * A helper type that can be used as a constraint, ensuring the type is both observable and have the given property.\n *\n * ```ts\n * // Ensures that `obj` is `Observable` and have property named 'abc'.\n * function f<O extends ObservableWithProperty<'abc'>>( obj: O ) {}\n *\n * // Ensures that `obj` is `Observable` and have property named 'abc' with value `number`.\n * function f<O extends ObservableWithProperty<'abc', number>>( obj: O ) {}\n * ```\n */\nexport type ObservableWithProperty<TKey extends PropertyKey, TVal = any> = undefined extends TVal ?\n\tObservable & { [ P in TKey ]?: TVal } :\n\tObservable & { [ P in TKey ]: TVal };\n\ninterface DualBindChain<TKey1 extends string, TVal1, TKey2 extends string, TVal2> {\n\tto<\n\t\tO extends ObservableWithProperty<K1, TVal1> & ObservableWithProperty<K2, TVal2>,\n\t\tK1 extends keyof O,\n\t\tK2 extends keyof O\n\t>(\n\t\tobservable: O,\n\t\tkey1: K1,\n\t\tkey2: K2\n\t): void;\n\n\tto<\n\t\tO extends ObservableWithProperty<TKey1, TVal1> & ObservableWithProperty<TKey2, TVal2>\n\t>(\n\t\tobservable: O\n\t): void;\n}\n\ninterface MultiBindChain {\n\tto<O extends Observable>( observable: O, ...properties: Array<keyof O> ): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/elementreplacer\n */\n\n/**\n * Utility class allowing to hide existing HTML elements or replace them with given ones in a way that doesn't remove\n * the original elements from the DOM.\n */\nexport default class ElementReplacer {\n\t/**\n\t * The elements replaced by {@link #replace} and their replacements.\n\t */\n\tprivate _replacedElements: Array<{ element: HTMLElement; newElement?: HTMLElement }>;\n\n\tconstructor() {\n\t\tthis._replacedElements = [];\n\t}\n\n\t/**\n\t * Hides the `element` and, if specified, inserts the the given element next to it.\n\t *\n\t * The effect of this method can be reverted by {@link #restore}.\n\t *\n\t * @param element The element to replace.\n\t * @param newElement The replacement element. If not passed, then the `element` will just be hidden.\n\t */\n\tpublic replace( element: HTMLElement, newElement?: HTMLElement ): void {\n\t\tthis._replacedElements.push( { element, newElement } );\n\n\t\telement.style.display = 'none';\n\n\t\tif ( newElement ) {\n\t\t\telement.parentNode!.insertBefore( newElement, element.nextSibling );\n\t\t}\n\t}\n\n\t/**\n\t * Restores what {@link #replace} did.\n\t */\n\tpublic restore(): void {\n\t\tthis._replacedElements.forEach( ( { element, newElement } ) => {\n\t\t\telement.style.display = '';\n\n\t\t\tif ( newElement ) {\n\t\t\t\tnewElement.remove();\n\t\t\t}\n\t\t} );\n\n\t\tthis._replacedElements = [];\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/abortabledebounce\n */\n\n/**\n * Returns a function wrapper that will execute the provided function and abort any previous call that is still in progress.\n *\n * @param func The function to be called. It will be provided with `AbortSignal` as the first parameter.\n */\nexport default function abortableDebounce<Args extends Array<any>, Ret>(\n\tfunc: ( signal: AbortSignal, ...args: Args ) => Ret\n): AbortableFunc<Args, Ret> {\n\tlet controller = new AbortController();\n\n\tfunction abortable( ...args: Args ) {\n\t\tcontroller.abort();\n\t\tcontroller = new AbortController();\n\n\t\treturn func( controller.signal, ...args );\n\t}\n\n\tabortable.abort = () => controller.abort();\n\n\treturn abortable;\n}\n\nexport interface AbortableFunc<Args extends Array<any>, Ret> {\n\t( ...args: Args ): Ret;\n\tabort(): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/count\n */\n\n/**\n * Returns the number of items return by the iterator.\n *\n * ```ts\n * count( [ 1, 2, 3, 4, 5 ] ); // 5;\n * ```\n *\n * @param iterable Any iterable.\n * @returns Number of items returned by that iterable.\n */\nexport default function count( iterable: Iterable<unknown> ): number {\n\tlet count = 0;\n\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\tfor ( const _ of iterable ) {\n\t\tcount++;\n\t}\n\n\treturn count;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/comparearrays\n */\n\n/**\n * Compares how given arrays relate to each other. One array can be: same as another array, prefix of another array\n * or completely different. If arrays are different, first index at which they differ is returned. Otherwise,\n * a flag specifying the relation is returned. Flags are negative numbers, so whenever a number >= 0 is returned\n * it means that arrays differ.\n *\n * ```ts\n * compareArrays( [ 0, 2 ], [ 0, 2 ] );\t\t// 'same'\n * compareArrays( [ 0, 2 ], [ 0, 2, 1 ] );\t\t// 'prefix'\n * compareArrays( [ 0, 2 ], [ 0 ] );\t\t\t// 'extension'\n * compareArrays( [ 0, 2 ], [ 1, 2 ] );\t\t// 0\n * compareArrays( [ 0, 2 ], [ 0, 1 ] );\t\t// 1\n * ```\n *\n * @param a Array that is compared.\n * @param b Array to compare with.\n * @returns How array `a` is related to `b`.\n */\nexport default function compareArrays( a: ReadonlyArray<unknown>, b: ReadonlyArray<unknown> ): ArrayRelation | number {\n\tconst minLen = Math.min( a.length, b.length );\n\n\tfor ( let i = 0; i < minLen; i++ ) {\n\t\tif ( a[ i ] != b[ i ] ) {\n\t\t\t// The arrays are different.\n\t\t\treturn i;\n\t\t}\n\t}\n\n\t// Both arrays were same at all points.\n\tif ( a.length == b.length ) {\n\t\t// If their length is also same, they are the same.\n\t\treturn 'same';\n\t} else if ( a.length < b.length ) {\n\t\t// Compared array is shorter so it is a prefix of the other array.\n\t\treturn 'prefix';\n\t} else {\n\t\t// Compared array is longer so it is an extension of the other array.\n\t\treturn 'extension';\n\t}\n}\n\n/**\n * Array relation.\n */\nexport type ArrayRelation = 'extension' | 'same' | 'prefix';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/isiterable\n */\n\n/**\n * Checks if value implements iterator interface.\n *\n * @param value The value to check.\n * @returns True if value implements iterator interface.\n */\nexport default function isIterable( value: any ): value is Iterable<any> {\n\treturn !!( value && value[ Symbol.iterator ] );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/createelement\n */\n\nimport isIterable from '../isiterable.js';\nimport { isString } from 'lodash-es';\n\n/**\n * Attributes to be applied to the HTML element.\n */\ntype HTMLElementAttributes = { readonly [ key: string ]: string };\n\n/**\n * Attributes to be applied to the SVG element.\n */\ntype SVGElementAttributes = HTMLElementAttributes & { xmlns: string };\n\n/**\n * Element or elements that will be added to the created element as children. Strings will be automatically turned into Text nodes.\n */\ntype ChildrenElements = Node | string | Iterable<Node | string>;\n\n/**\n * Creates an SVG element with attributes and children elements.\n *\n * ```ts\n * createElement( document, 'mask', { xmlns: 'http://www.w3.org/2000/svg' } ); // <mask>\n * createElement( document, 'mask', { xmlns: 'http://www.w3.org/2000/svg', id: 'foo' } ); // <mask id=\"foo\">\n * createElement( document, 'mask', { xmlns: 'http://www.w3.org/2000/svg' }, 'foo' ); // <mask>foo</mask>\n * createElement( document, 'mask', { xmlns: 'http://www.w3.org/2000/svg' }, [ createElement(...) ] ); // <mask><...></mask>\n * ```\n *\n * @label SVG_ELEMENT\n * @param doc Document used to create the element.\n * @param name Name of the SVG element.\n * @param attributes Object where keys represent attribute keys and values represent attribute values.\n * @param children Child or any iterable of children. Strings will be automatically turned into Text nodes.\n * @returns SVG element.\n */\nexport default function createElement<T extends keyof SVGElementTagNameMap>(\n\tdoc: Document,\n\tname: T,\n\tattributes: SVGElementAttributes,\n\tchildren?: ChildrenElements\n): SVGElementTagNameMap[T];\n\n/**\n * Creates an HTML element with attributes and children elements.\n *\n * ```ts\n * createElement( document, 'p' ); // <p>\n * createElement( document, 'p', { class: 'foo' } ); // <p class=\"foo\">\n * createElement( document, 'p', null, 'foo' ); // <p>foo</p>\n * createElement( document, 'p', null, [ createElement(...) ] ); // <p><...></p>\n * ```\n *\n * @label HTML_ELEMENT\n * @param doc Document used to create the element.\n * @param name Name of the HTML element.\n * @param attributes Object where keys represent attribute keys and values represent attribute values.\n * @param children Child or any iterable of children. Strings will be automatically turned into Text nodes.\n * @returns HTML element.\n */\nexport default function createElement<T extends keyof HTMLElementTagNameMap>(\n\tdoc: Document,\n\tname: T,\n\tattributes?: HTMLElementAttributes,\n\tchildren?: ChildrenElements\n): HTMLElementTagNameMap[T];\n\n/**\n * Creates an HTML or SVG element with attributes and children elements.\n *\n * ```ts\n * createElement( document, 'p' ); // <p>\n * createElement( document, 'mask', { xmlns: 'http://www.w3.org/2000/svg' } ); // <mask>\n * ```\n *\n * @param doc Document used to create the element.\n * @param name Name of the element.\n * @param attributes Object where keys represent attribute keys and values represent attribute values.\n * @param children Child or any iterable of children. Strings will be automatically turned into Text nodes.\n * @returns HTML or SVG element.\n */\nexport default function createElement(\n\tdoc: Document,\n\tname: string,\n\tattributes: SVGElementAttributes | HTMLElementAttributes = {},\n\tchildren: ChildrenElements = []\n): Element {\n\tconst namespace = attributes && attributes.xmlns;\n\tconst element = namespace ? doc.createElementNS( namespace, name ) : doc.createElement( name );\n\n\tfor ( const key in attributes ) {\n\t\telement.setAttribute( key, attributes[ key ] );\n\t}\n\n\tif ( isString( children ) || !isIterable( children ) ) {\n\t\tchildren = [ children ];\n\t}\n\n\tfor ( let child of children ) {\n\t\tif ( isString( child ) ) {\n\t\t\tchild = doc.createTextNode( child );\n\t\t}\n\n\t\telement.appendChild( child );\n\t}\n\n\treturn element;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/config\n */\n\nimport { isPlainObject, isElement, cloneDeepWith } from 'lodash-es';\n\n/**\n * Handles a configuration dictionary.\n *\n * @typeParam Cfg A type of the configuration dictionary.\n */\nexport default class Config<Cfg> {\n\t/**\n\t * Store for the whole configuration.\n\t */\n\tprivate readonly _config: Record<string, any>;\n\n\t/**\n\t * Creates an instance of the {@link ~Config} class.\n\t *\n\t * @param configurations The initial configurations to be set. Usually, provided by the user.\n\t * @param defaultConfigurations The default configurations. Usually, provided by the system.\n\t */\n\tconstructor( configurations?: Partial<Cfg>, defaultConfigurations?: Partial<Cfg> ) {\n\t\tthis._config = Object.create( null );\n\n\t\t// Set default configuration.\n\t\tif ( defaultConfigurations ) {\n\t\t\t// Clone the configuration to make sure that the properties will not be shared\n\t\t\t// between editors and make the watchdog feature work correctly.\n\t\t\tthis.define( cloneConfig( defaultConfigurations ) );\n\t\t}\n\n\t\t// Set initial configuration.\n\t\tif ( configurations ) {\n\t\t\tthis._setObjectToTarget( this._config, configurations );\n\t\t}\n\t}\n\n\t/**\n\t * Set configuration values.\n\t *\n\t * It also accepts setting a \"deep configuration\" by using dots in the name. For example, `'resize.width'` sets\n\t * the value for the `width` configuration in the `resize` subset.\n\t *\n\t * ```ts\n\t * config.set( 'resize.width', 500 );\n\t * ```\n\t *\n\t * It accepts both a name/value pair or an object, which properties and values will be used to set\n\t * configurations. See {@link #set:CONFIG_OBJECT}.\n\t *\n\t * @label KEY_VALUE\n\t * @param name The configuration name. Configuration names are case-sensitive.\n\t * @param value The configuration value.\n\t */\n\tpublic set<K extends string>( name: K, value: GetSubConfig<Cfg, K> ): void;\n\n\t/**\n\t * Set configuration values.\n\t *\n\t * It accepts an object, which properties and values will be used to set configurations.\n\t *\n\t * ```ts\n\t * config.set( {\n\t * \twidth: 500\n\t * \ttoolbar: {\n\t * \t\tcollapsed: true\n\t * \t}\n\t * } );\n\t *\n\t * // Equivalent to:\n\t * config.set( 'width', 500 );\n\t * config.set( 'toolbar.collapsed', true );\n\t * ```\n\t *\n\t * Passing an object as the value will amend the configuration, not replace it.\n\t *\n\t * ```ts\n\t * config.set( 'toolbar', {\n\t * \tcollapsed: true,\n\t * } );\n\t *\n\t * config.set( 'toolbar', {\n\t * \tcolor: 'red',\n\t * } );\n\t *\n\t * config.get( 'toolbar.collapsed' ); // true\n\t * config.get( 'toolbar.color' ); // 'red'\n\t * ```\n\t *\n\t * It accepts both a name/value pair or an object, which properties and values will be used to set\n\t * configurations. See {@link #set:KEY_VALUE}.\n\t *\n\t * @label CONFIG_OBJECT\n\t * @param config The configuration object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t */\n\tpublic set( config: Partial<Cfg> ): void;\n\n\tpublic set( name: string | Record<string, any>, value?: any ): void {\n\t\tthis._setToTarget( this._config, name, value );\n\t}\n\n\t/**\n\t * Does exactly the same as {@link #set:KEY_VALUE} with one exception – passed configuration extends\n\t * existing one, but does not overwrite already defined values.\n\t *\n\t * This method is supposed to be called by plugin developers to setup plugin's configurations. It would be\n\t * rarely used for other needs.\n\t *\n\t * @label KEY_VALUE\n\t * @param name The configuration name. Configuration names are case-sensitive.\n\t * @param value The configuration value.\n\t */\n\tpublic define<K extends string>( name: K, value: GetSubConfig<Cfg, K> ): void;\n\n\t/**\n\t * Does exactly the same as {@link #set:CONFIG_OBJECT} with one exception – passed configuration extends\n\t * existing one, but does not overwrite already defined values.\n\t *\n\t * This method is supposed to be called by plugin developers to setup plugin's configurations. It would be\n\t * rarely used for other needs.\n\t *\n\t * @label CONFIG_OBJECT\n\t * @param config The configuration object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t */\n\tpublic define( config: Partial<Cfg> ): void;\n\n\tpublic define( name: string | Record<string, any>, value?: any ): void {\n\t\tconst isDefine = true;\n\n\t\tthis._setToTarget( this._config, name, value, isDefine );\n\t}\n\n\t/**\n\t * Gets the value for a configuration entry.\n\t *\n\t * ```ts\n\t * config.get( 'name' );\n\t * ```\n\t *\n\t * Deep configurations can be retrieved by separating each part with a dot.\n\t *\n\t * ```ts\n\t * config.get( 'toolbar.collapsed' );\n\t * ```\n\t *\n\t * @param name The configuration name. Configuration names are case-sensitive.\n\t * @returns The configuration value or `undefined` if the configuration entry was not found.\n\t */\n\tpublic get<K extends string>( name: K ): GetSubConfig<Cfg, K> | undefined {\n\t\treturn this._getFromSource( this._config, name );\n\t}\n\n\t/**\n\t * Iterates over all top level configuration names.\n\t */\n\tpublic* names(): Iterable<string> {\n\t\tfor ( const name of Object.keys( this._config ) ) {\n\t\t\tyield name;\n\t\t}\n\t}\n\n\t/**\n\t * Saves passed configuration to the specified target (nested object).\n\t *\n\t * @param target Nested config object.\n\t * @param name The configuration name or an object from which take properties as\n\t * configuration entries. Configuration names are case-sensitive.\n\t * @param value The configuration value. Used if a name is passed.\n\t * @param isDefine Define if passed configuration should overwrite existing one.\n\t */\n\tprivate _setToTarget( target: any, name: any, value: any, isDefine: boolean = false ): void {\n\t\t// In case of an object, iterate through it and call `_setToTarget` again for each property.\n\t\tif ( isPlainObject( name ) ) {\n\t\t\tthis._setObjectToTarget( target, name, isDefine );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n\t\tconst parts = name.split( '.' );\n\n\t\t// Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n\t\tname = parts.pop();\n\n\t\t// Iterate over parts to check if currently stored configuration has proper structure.\n\t\tfor ( const part of parts ) {\n\t\t\t// If there is no object for specified part then create one.\n\t\t\tif ( !isPlainObject( target[ part ] ) ) {\n\t\t\t\ttarget[ part ] = Object.create( null );\n\t\t\t}\n\n\t\t\t// Nested object becomes a target.\n\t\t\ttarget = target[ part ];\n\t\t}\n\n\t\t// In case of value is an object.\n\t\tif ( isPlainObject( value ) ) {\n\t\t\t// We take care of proper config structure.\n\t\t\tif ( !isPlainObject( target[ name ] ) ) {\n\t\t\t\ttarget[ name ] = Object.create( null );\n\t\t\t}\n\n\t\t\ttarget = target[ name ];\n\n\t\t\t// And iterate through this object calling `_setToTarget` again for each property.\n\t\t\tthis._setObjectToTarget( target, value, isDefine );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Do nothing if we are defining configuration for non empty name.\n\t\tif ( isDefine && typeof target[ name ] != 'undefined' ) {\n\t\t\treturn;\n\t\t}\n\n\t\ttarget[ name ] = value;\n\t}\n\n\t/**\n\t * Get specified configuration from specified source (nested object).\n\t *\n\t * @param source level of nested object.\n\t * @param name The configuration name. Configuration names are case-sensitive.\n\t * @returns The configuration value or `undefined` if the configuration entry was not found.\n\t */\n\tprivate _getFromSource( source: any, name: string ): any {\n\t\t// The configuration name should be split into parts if it has dots. E.g. `resize.width` -> [`resize`, `width`].\n\t\tconst parts = name.split( '.' );\n\n\t\t// Take the name of the configuration out of the parts. E.g. `resize.width` -> `width`.\n\t\tname = parts.pop()!;\n\n\t\t// Iterate over parts to check if currently stored configuration has proper structure.\n\t\tfor ( const part of parts ) {\n\t\t\tif ( !isPlainObject( source[ part ] ) ) {\n\t\t\t\tsource = null;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Nested object becomes a source.\n\t\t\tsource = source[ part ];\n\t\t}\n\n\t\t// Always returns undefined for non existing configuration.\n\t\treturn source ? cloneConfig( source[ name ] ) : undefined;\n\t}\n\n\t/**\n\t * Iterates through passed object and calls {@link #_setToTarget} method with object key and value for each property.\n\t *\n\t * @param target Nested config object.\n\t * @param configuration Configuration data set\n\t * @param isDefine Defines if passed configuration is default configuration or not.\n\t */\n\tprivate _setObjectToTarget( target: any, configuration: any, isDefine?: boolean ): void {\n\t\tObject.keys( configuration ).forEach( key => {\n\t\t\tthis._setToTarget( target, key, configuration[ key ], isDefine );\n\t\t} );\n\t}\n}\n\n/**\n * Clones configuration object or value.\n */\nfunction cloneConfig<T>( source: T ): T {\n\treturn cloneDeepWith( source, leaveItemReferences );\n}\n\n/**\n * A customized function for cloneDeepWith.\n * In case if it's a DOM Element it will leave references to DOM Elements instead of cloning them.\n * If it's a function it will leave reference to actuall function.\n */\nfunction leaveItemReferences( value: unknown ): unknown {\n\treturn isElement( value ) || typeof value === 'function' ? value : undefined;\n}\n\n/**\n * An utility type excluding primitive values and arrays from the union.\n */\nexport type OnlyObject<T> = Exclude<T, undefined | null | string | number | boolean | Array<any>>;\n\n/**\n * An utility type extracting configuration value from the given name.\n *\n * @typeParam T The type of a configuration dictionary.\n * @typeParam K The literal type of configuration name (dot-separated path).\n */\nexport type GetSubConfig<T, K> = K extends keyof T ?\n\tT[ K ] :\n\tK extends `${ infer K1 }.${ infer K2 }` ?\n\t\tK1 extends keyof T ?\n\t\t\tGetSubConfig<OnlyObject<T[ K1 ]>, K2> :\n\t\t\tunknown :\n\t\tunknown;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/isnode\n */\n\n/**\n * Checks if the object is a native DOM Node.\n */\nexport default function isNode( obj: any ): obj is Node {\n\tif ( obj ) {\n\t\tif ( obj.defaultView ) {\n\t\t\treturn obj instanceof obj.defaultView.Document;\n\t\t} else if ( obj.ownerDocument && obj.ownerDocument.defaultView ) {\n\t\t\treturn obj instanceof obj.ownerDocument.defaultView.Node;\n\t\t}\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/iswindow\n */\n\n/**\n * Checks if the object is a native DOM Window.\n */\nexport default function isWindow( obj: unknown ): obj is Window {\n\tconst stringifiedObject = Object.prototype.toString.apply( obj );\n\n\t// Returns `true` for the `window` object in browser environments.\n\tif ( stringifiedObject == '[object Window]' ) {\n\t\treturn true;\n\t}\n\n\t// Returns `true` for the `window` object in the Electron environment.\n\tif ( stringifiedObject == '[object global]' ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/emittermixin\n */\n\nimport EmitterMixin, {\n\t_getEmitterListenedTo,\n\t_setEmitterId,\n\ttype Emitter,\n\ttype CallbackOptions,\n\ttype BaseEvent,\n\ttype GetCallback\n} from '../emittermixin.js';\nimport uid from '../uid.js';\nimport isNode from './isnode.js';\nimport isWindow from './iswindow.js';\nimport type EventInfo from '../eventinfo.js';\nimport type { Constructor, Mixed } from '../mix.js';\n\nconst defaultEmitterClass = /* #__PURE__ */ DomEmitterMixin( /* #__PURE__ */ EmitterMixin() );\n\n/**\n * Mixin that injects the DOM events API into its host. It provides the API\n * compatible with {@link module:utils/emittermixin~Emitter}.\n *\n * This function creates a class that inherits from the provided `base` and implements `Emitter` interface.\n *\n * DOM emitter mixin is by default available in the {@link module:ui/view~View} class,\n * but it can also be mixed into any other class:\n *\n * ```ts\n * import DomEmitterMixin from '../utils/dom/emittermixin.js';\n *\n * class BaseClass { ... }\n *\n * class SomeView extends DomEmitterMixin( BaseClass ) {}\n *\n * const view = new SomeView();\n * view.listenTo( domElement, ( evt, domEvt ) => {\n * \tconsole.log( evt, domEvt );\n * } );\n * ```\n *\n * @label EXTENDS\n */\nexport default function DomEmitterMixin<Base extends Constructor<Emitter>>( base: Base ): Mixed<Base, DomEmitter>;\n\n/**\n * Mixin that injects the DOM events API into its host. It provides the API\n * compatible with {@link module:utils/emittermixin~Emitter}.\n *\n * This function creates a class that implements `Emitter` interface.\n *\n * DOM emitter mixin is by default available in the {@link module:ui/view~View} class,\n * but it can also be mixed into any other class:\n *\n * ```ts\n * import DomEmitterMixin from '../utils/dom/emittermixin.js';\n *\n * class SomeView extends DomEmitterMixin() {}\n *\n * const view = new SomeView();\n * view.listenTo( domElement, ( evt, domEvt ) => {\n * \tconsole.log( evt, domEvt );\n * } );\n * ```\n *\n * @label NO_ARGUMENTS\n */\nexport default function DomEmitterMixin(): {\n\tnew (): DomEmitter;\n\tprototype: DomEmitter;\n};\n\nexport default function DomEmitterMixin( base?: Constructor<Emitter> ): unknown {\n\tif ( !base ) {\n\t\treturn defaultEmitterClass;\n\t}\n\n\tabstract class Mixin extends base implements DomEmitter {\n\t\tpublic override listenTo<K extends keyof HTMLElementEventMap>(\n\t\t\temitter: Node | Window,\n\t\t\tevent: K,\n\t\t\tcallback: ( this: this, ev: EventInfo, event: HTMLElementEventMap[ K ] ) => void,\n\t\t\toptions?: CallbackOptions & { readonly useCapture?: boolean; readonly usePassive?: boolean }\n\t\t): void;\n\t\tpublic override listenTo<TEvent extends BaseEvent>(\n\t\t\temitter: Emitter,\n\t\t\tevent: TEvent[ 'name' ],\n\t\t\tcallback: GetCallback<TEvent>,\n\t\t\toptions?: CallbackOptions\n\t\t): void;\n\t\tpublic override listenTo(\n\t\t\temitter: Emitter | Node | Window,\n\t\t\tevent: string,\n\t\t\tcallback: ( ev: EventInfo, ...args: Array<any> ) => void,\n\t\t\toptions: CallbackOptions & { readonly useCapture?: boolean; readonly usePassive?: boolean } = {}\n\t\t): void {\n\t\t\t// Check if emitter is an instance of DOM Node. If so, use corresponding ProxyEmitter (or create one if not existing).\n\t\t\tif ( isNode( emitter ) || isWindow( emitter ) ) {\n\t\t\t\tconst proxyOptions = {\n\t\t\t\t\tcapture: !!options.useCapture,\n\t\t\t\t\tpassive: !!options.usePassive\n\t\t\t\t};\n\n\t\t\t\tconst proxyEmitter = this._getProxyEmitter( emitter, proxyOptions ) || new ProxyEmitter( emitter, proxyOptions );\n\n\t\t\t\tthis.listenTo( proxyEmitter, event, callback, options );\n\t\t\t} else {\n\t\t\t\t// Execute parent class method with Emitter (or ProxyEmitter) instance.\n\t\t\t\tsuper.listenTo( emitter, event, callback, options );\n\t\t\t}\n\t\t}\n\n\t\tpublic override stopListening(\n\t\t\temitter?: Emitter | Node | Window,\n\t\t\tevent?: string,\n\t\t\tcallback?: Function\n\t\t): void {\n\t\t\t// Check if the emitter is an instance of DOM Node. If so, forward the call to the corresponding ProxyEmitters.\n\t\t\tif ( isNode( emitter ) || isWindow( emitter ) ) {\n\t\t\t\tconst proxyEmitters = this._getAllProxyEmitters( emitter );\n\n\t\t\t\tfor ( const proxy of proxyEmitters ) {\n\t\t\t\t\tthis.stopListening( proxy, event, callback );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Execute parent class method with Emitter (or ProxyEmitter) instance.\n\t\t\t\tsuper.stopListening( emitter, event, callback );\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Retrieves ProxyEmitter instance for given DOM Node residing in this Host and given options.\n\t\t *\n\t\t * @param node DOM Node of the ProxyEmitter.\n\t\t * @param options Additional options.\n\t\t * @param options.useCapture Indicates that events of this type will be dispatched to the registered\n\t\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t\t * @param options.usePassive Indicates that the function specified by listener will never call preventDefault()\n\t\t * and prevents blocking browser's main thread by this event handler.\n\t\t * @returns ProxyEmitter instance bound to the DOM Node.\n\t\t */\n\t\tprivate _getProxyEmitter(\n\t\t\tnode: Node | Window,\n\t\t\toptions: { capture: boolean; passive: boolean }\n\t\t): Emitter | null {\n\t\t\treturn _getEmitterListenedTo( this, getProxyEmitterId( node, options ) );\n\t\t}\n\n\t\t/**\n\t\t * Retrieves all the ProxyEmitter instances for given DOM Node residing in this Host.\n\t\t *\n\t\t * @param node DOM Node of the ProxyEmitter.\n\t\t */\n\t\tprivate _getAllProxyEmitters( node: Node | Window ): Array<ProxyEmitter> {\n\t\t\treturn [\n\t\t\t\t{ capture: false, passive: false },\n\t\t\t\t{ capture: false, passive: true },\n\t\t\t\t{ capture: true, passive: false },\n\t\t\t\t{ capture: true, passive: true }\n\t\t\t].map( options => this._getProxyEmitter( node, options ) ).filter( proxy => !!proxy ) as any;\n\t\t}\n\t}\n\n\treturn Mixin;\n}\n\n// Backward compatibility with `mix`\n( [\n\t'_getProxyEmitter', '_getAllProxyEmitters',\n\t'on', 'once', 'off', 'listenTo',\n\t'stopListening', 'fire', 'delegate', 'stopDelegating',\n\t'_addEventListener', '_removeEventListener'\n] ).forEach( key => {\n\t( DomEmitterMixin as any )[ key ] = ( defaultEmitterClass.prototype as any )[ key ];\n} );\n\n/**\n * Creates a ProxyEmitter instance. Such an instance is a bridge between a DOM Node firing events\n * and any Host listening to them. It is backwards compatible with {@link module:utils/emittermixin~Emitter#on}.\n * There is a separate instance for each combination of modes (useCapture & usePassive). The mode is concatenated with\n * UID stored in HTMLElement to give each instance unique identifier.\n *\n *                                  listenTo( click, ... )\n *                    +-----------------------------------------+\n *                    |              stopListening( ... )       |\n *     +----------------------------+                           |             addEventListener( click, ... )\n *     | Host                       |                           |   +---------------------------------------------+\n *     +----------------------------+                           |   |       removeEventListener( click, ... )     |\n *     | _listeningTo: {            |                +----------v-------------+                                   |\n *     |   UID+mode: {              |                | ProxyEmitter           |                                   |\n *     |     emitter: ProxyEmitter, |                +------------------------+                      +------------v----------+\n *     |     callbacks: {           |                | events: {              |                      | Node (HTMLElement)    |\n *     |       click: [ callbacks ] |                |   click: [ callbacks ] |                      +-----------------------+\n *     |     }                      |                | },                     |                      | data-ck-expando: UID  |\n *     |   }                        |                | _domNode: Node,        |                      +-----------------------+\n *     | }                          |                | _domListeners: {},     |                                   |\n *     | +------------------------+ |                | _emitterId: UID+mode   |                                   |\n *     | | DomEmitterMixin        | |                +--------------^---------+                                   |\n *     | +------------------------+ |                           |   |                                             |\n *     +--------------^-------------+                           |   +---------------------------------------------+\n *                    |                                         |                  click (DOM Event)\n *                    +-----------------------------------------+\n *                                fire( click, DOM Event )\n */\nclass ProxyEmitter extends /* #__PURE__ */ EmitterMixin() {\n\tprivate readonly _domNode: Node | Window;\n\tprivate readonly _options: { capture: boolean; passive: boolean };\n\n\t/**\n\t * @param node DOM Node that fires events.\n\t * @param options Additional options.\n\t * @param options.useCapture Indicates that events of this type will be dispatched to the registered\n\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t * @param options.usePassive Indicates that the function specified by listener will never call preventDefault()\n\t * and prevents blocking browser's main thread by this event handler.\n\t */\n\tconstructor(\n\t\tnode: Node | Window,\n\t\toptions: { capture: boolean; passive: boolean }\n\t) {\n\t\tsuper();\n\n\t\t// Set emitter ID to match DOM Node \"expando\" property.\n\t\t_setEmitterId( this, getProxyEmitterId( node, options ) );\n\n\t\t// Remember the DOM Node this ProxyEmitter is bound to.\n\t\tthis._domNode = node;\n\n\t\t// And given options.\n\t\tthis._options = options;\n\t}\n\n\t/**\n\t * Collection of native DOM listeners.\n\t */\n\tprivate _domListeners?: {\n\t\t[ event: string ]: {\n\t\t\t( domEvent: unknown ): void;\n\t\t\tremoveListener(): void;\n\t\t};\n\t};\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired.\n\t *\n\t * It attaches a native DOM listener to the DOM Node. When fired,\n\t * a corresponding Emitter event will also fire with DOM Event object as an argument.\n\t *\n\t * **Note**: This is automatically called by the\n\t * {@link module:utils/emittermixin~Emitter#listenTo `Emitter#listenTo()`}.\n\t *\n\t * @param event The name of the event.\n\t */\n\tpublic attach( event: string ): void {\n\t\t// If the DOM Listener for given event already exist it is pointless\n\t\t// to attach another one.\n\t\tif ( this._domListeners && this._domListeners[ event ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domListener = this._createDomListener( event );\n\n\t\t// Attach the native DOM listener to DOM Node.\n\t\tthis._domNode.addEventListener( event, domListener, this._options );\n\n\t\tif ( !this._domListeners ) {\n\t\t\tthis._domListeners = {};\n\t\t}\n\n\t\t// Store the native DOM listener in this ProxyEmitter. It will be helpful\n\t\t// when stopping listening to the event.\n\t\tthis._domListeners[ event ] = domListener;\n\t}\n\n\t/**\n\t * Stops executing the callback on the given event.\n\t *\n\t * **Note**: This is automatically called by the\n\t * {@link module:utils/emittermixin~Emitter#stopListening `Emitter#stopListening()`}.\n\t *\n\t * @param event The name of the event.\n\t */\n\tpublic detach( event: string ): void {\n\t\tlet events;\n\n\t\t// Remove native DOM listeners which are orphans. If no callbacks\n\t\t// are awaiting given event, detach native DOM listener from DOM Node.\n\t\t// See: {@link attach}.\n\n\t\tif ( this._domListeners![ event ] && ( !( events = ( this as any )._events![ event ] ) || !events.callbacks.length ) ) {\n\t\t\tthis._domListeners![ event ].removeListener();\n\t\t}\n\t}\n\n\t/**\n\t * Adds callback to emitter for given event.\n\t *\n\t * @internal\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t */\n\tpublic _addEventListener<TEvent extends BaseEvent>(\n\t\tevent: TEvent[ 'name' ],\n\t\tcallback: GetCallback<TEvent>,\n\t\toptions: CallbackOptions\n\t): void {\n\t\tthis.attach( event );\n\t\t( EmitterMixin().prototype as any )._addEventListener.call( this, event, callback, options );\n\t}\n\n\t/**\n\t * Removes callback from emitter for given event.\n\t *\n\t * @internal\n\t * @param event The name of the event.\n\t * @param callback The function to stop being called.\n\t */\n\tpublic _removeEventListener( event: string, callback: Function ) {\n\t\t( EmitterMixin().prototype as any )._removeEventListener.call( this, event, callback );\n\t\tthis.detach( event );\n\t}\n\n\t/**\n\t * Creates a native DOM listener callback. When the native DOM event\n\t * is fired it will fire corresponding event on this ProxyEmitter.\n\t * Note: A native DOM Event is passed as an argument.\n\t *\n\t * @param event The name of the event.\n\t * @returns The DOM listener callback.\n\t */\n\tprivate _createDomListener( event: string ) {\n\t\tconst domListener = ( domEvt: unknown ) => {\n\t\t\tthis.fire( event, domEvt );\n\t\t};\n\n\t\t// Supply the DOM listener callback with a function that will help\n\t\t// detach it from the DOM Node, when it is no longer necessary.\n\t\t// See: {@link detach}.\n\t\tdomListener.removeListener = () => {\n\t\t\tthis._domNode.removeEventListener( event, domListener, this._options );\n\t\t\tdelete this._domListeners![ event ];\n\t\t};\n\n\t\treturn domListener;\n\t}\n}\n\n/**\n * Gets an unique DOM Node identifier. The identifier will be set if not defined.\n *\n * @returns UID for given DOM Node.\n */\nfunction getNodeUID( node: any ): string {\n\treturn node[ 'data-ck-expando' ] || ( node[ 'data-ck-expando' ] = uid() );\n}\n\n/**\n * Gets id of the ProxyEmitter for the given node.\n */\nfunction getProxyEmitterId( node: Node | Window, options: { [ option: string ]: any } ): string {\n\tlet id = getNodeUID( node );\n\n\tfor ( const option of Object.keys( options ).sort() ) {\n\t\tif ( options[ option ] ) {\n\t\t\tid += '-' + option;\n\t\t}\n\t}\n\n\treturn id;\n}\n\nexport interface DomEventMap extends HTMLElementEventMap, WindowEventMap {\n}\n\n/**\n * Interface representing classes which mix in {@link module:utils/dom/emittermixin~DomEmitterMixin}.\n *\n * Can be easily implemented by a class by mixing the {@link module:utils/dom/emittermixin~DomEmitterMixin} mixin.\n *\n * ```ts\n * class MyClass extends DomEmitterMixin( OtherBaseClass ) {\n * \t// This class now implements the `Emitter` interface.\n * }\n * ```\n */\nexport interface DomEmitter extends Emitter {\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired in a specific Emitter or DOM Node.\n\t * It is backwards compatible with {@link module:utils/emittermixin~Emitter#listenTo}.\n\t *\n\t * @label HTML_EMITTER\n\t * @param emitter The object that fires the event.\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t * @param options.useCapture Indicates that events of this type will be dispatched to the registered\n\t * listener before being dispatched to any EventTarget beneath it in the DOM tree.\n\t * @param options.usePassive Indicates that the function specified by listener will never call preventDefault()\n\t * and prevents blocking browser's main thread by this event handler.\n\t */\n\tlistenTo<K extends keyof DomEventMap>(\n\t\temitter: Node | Window,\n\t\tevent: K,\n\t\tcallback: ( this: this, ev: EventInfo, event: DomEventMap[ K ] ) => void,\n\t\toptions?: CallbackOptions & { readonly useCapture?: boolean; readonly usePassive?: boolean }\n\t): void;\n\n\t/**\n\t * Registers a callback function to be executed when an event is fired in a specific (emitter) object.\n\t *\n\t * Events can be grouped in namespaces using `:`.\n\t * When namespaced event is fired, it additionally fires all callbacks for that namespace.\n\t *\n\t * ```ts\n\t * // myEmitter.on( ... ) is a shorthand for myEmitter.listenTo( myEmitter, ... ).\n\t * myEmitter.on( 'myGroup', genericCallback );\n\t * myEmitter.on( 'myGroup:myEvent', specificCallback );\n\t *\n\t * // genericCallback is fired.\n\t * myEmitter.fire( 'myGroup' );\n\t * // both genericCallback and specificCallback are fired.\n\t * myEmitter.fire( 'myGroup:myEvent' );\n\t * // genericCallback is fired even though there are no callbacks for \"foo\".\n\t * myEmitter.fire( 'myGroup:foo' );\n\t * ```\n\t *\n\t * An event callback can {@link module:utils/eventinfo~EventInfo#stop stop the event} and\n\t * set the {@link module:utils/eventinfo~EventInfo#return return value} of the {@link #fire} method.\n\t *\n\t * @label DOM_EMITTER\n\t * @typeParam TEvent The type describing the event. See {@link module:utils/emittermixin~BaseEvent}.\n\t * @param emitter The object that fires the event.\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t */\n\tlistenTo<TEvent extends BaseEvent>(\n\t\temitter: Emitter,\n\t\tevent: TEvent[ 'name' ],\n\t\tcallback: GetCallback<TEvent>,\n\t\toptions?: CallbackOptions\n\t): void;\n\n\t/**\n\t * Stops listening for events. It can be used at different levels:\n\t * It is backwards compatible with {@link module:utils/emittermixin~Emitter#listenTo}.\n\t *\n\t * * To stop listening to a specific callback.\n\t * * To stop listening to a specific event.\n\t * * To stop listening to all events fired by a specific object.\n\t * * To stop listening to all events fired by all objects.\n\t *\n\t * @label DOM_STOP\n\t * @param emitter The object to stop listening to.\n\t * If omitted, stops it for all objects.\n\t * @param event (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it\n\t * for all events from `emitter`.\n\t * @param callback (Requires the `event`) The function to be removed from the call list for the given\n\t * `event`.\n\t */\n\tstopListening( emitter?: Emitter | Node | Window, event?: string, callback?: Function ): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/findclosestscrollableancestor\n */\n\nimport global from './global.js';\n\n/**\n * Returns the closest scrollable ancestor of a DOM element.\n *\n * @param domElement DOM element.\n * @returns First ancestor of `domElement` that is scrollable or null if such ancestor doesn't exist.\n */\nexport default function findClosestScrollableAncestor( domElement: HTMLElement ): HTMLElement | null {\n\tlet element = domElement.parentElement;\n\tif ( !element ) {\n\t\treturn null;\n\t}\n\n\twhile ( element.tagName != 'BODY' ) {\n\t\tconst overflow = element.style.overflowY || global.window.getComputedStyle( element ).overflowY;\n\n\t\tif ( overflow === 'auto' || overflow === 'scroll' ) {\n\t\t\tbreak;\n\t\t}\n\n\t\telement = element.parentElement;\n\n\t\tif ( !element ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn element;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* globals Node */\n\n/**\n * @module utils/dom/getancestors\n */\n\n/**\n * Returns all ancestors of given DOM node, starting from the top-most (root). Includes the given node itself. If the\n * node is a part of `DocumentFragment` that `DocumentFragment` will be returned. In contrary, if the node is\n * appended to a `Document`, that `Document` will not be returned (algorithms operating on DOM tree care for `Document#documentElement`\n * at most, which will be returned).\n *\n * @param node DOM node.\n * @returns Array of given `node` parents.\n */\nexport default function getAncestors( node: Node ): Array<Node> {\n\tconst nodes: Array<Node> = [];\n\tlet currentNode: Node | null = node;\n\n\t// We are interested in `Node`s `DocumentFragment`s only.\n\twhile ( currentNode && currentNode.nodeType != Node.DOCUMENT_NODE ) {\n\t\tnodes.unshift( currentNode );\n\t\tcurrentNode = currentNode.parentNode;\n\t}\n\n\treturn nodes;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* globals HTMLTextAreaElement */\n\n/**\n * @module utils/dom/getdatafromelement\n */\n\n/**\n * Gets data from a given source element.\n *\n * @param el The element from which the data will be retrieved.\n * @returns The data string.\n */\nexport default function getDataFromElement( el: HTMLElement ): string {\n\tif ( el instanceof HTMLTextAreaElement ) {\n\t\treturn el.value;\n\t}\n\n\treturn el.innerHTML;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/getborderwidths\n */\n\n/**\n * Returns an object containing CSS border widths of a specified HTML element.\n *\n * @param element An element which has CSS borders.\n * @returns An object containing `top`, `left`, `right` and `bottom` properties\n * with numerical values of the `border-[top,left,right,bottom]-width` CSS styles.\n */\nexport default function getBorderWidths( element: HTMLElement ): BorderWidths {\n\t// Call getComputedStyle on the window the element document belongs to.\n\tconst style = element.ownerDocument.defaultView!.getComputedStyle( element );\n\n\treturn {\n\t\ttop: parseInt( style.borderTopWidth, 10 ),\n\t\tright: parseInt( style.borderRightWidth, 10 ),\n\t\tbottom: parseInt( style.borderBottomWidth, 10 ),\n\t\tleft: parseInt( style.borderLeftWidth, 10 )\n\t};\n}\n\n/**\n * An object describing widths of `HTMLElement` borders.\n*/\nexport interface BorderWidths {\n\ttop: number;\n\tright: number;\n\tbottom: number;\n\tleft: number;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/getrangefrommouseevent\n */\n\n/**\n * Returns a DOM range from a given point specified by a mouse event.\n *\n * @param domEvent The mouse event.\n * @returns The DOM range.\n */\nexport default function getRangeFromMouseEvent(\n\tdomEvent: MouseEvent & {\n\t\trangeParent?: HTMLElement;\n\t\trangeOffset?: number;\n\t}\n): Range | null {\n\tif ( !domEvent.target ) {\n\t\treturn null;\n\t}\n\n\tconst domDoc = ( domEvent.target as HTMLElement ).ownerDocument;\n\tconst x = domEvent.clientX;\n\tconst y = domEvent.clientY;\n\tlet domRange = null;\n\n\t// Webkit & Blink.\n\tif ( domDoc.caretRangeFromPoint && domDoc.caretRangeFromPoint( x, y ) ) {\n\t\tdomRange = domDoc.caretRangeFromPoint( x, y );\n\t}\n\n\t// FF.\n\telse if ( domEvent.rangeParent ) {\n\t\tdomRange = domDoc.createRange();\n\t\tdomRange.setStart( domEvent.rangeParent, domEvent.rangeOffset! );\n\t\tdomRange.collapse( true );\n\t}\n\n\treturn domRange;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/istext\n */\n\n/**\n * Checks if the object is a native DOM Text node.\n */\nexport default function isText( obj: unknown ): obj is Text {\n\treturn Object.prototype.toString.call( obj ) == '[object Text]';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/isrange\n */\n\n/**\n * Checks if the object is a native DOM Range.\n */\nexport default function isRange( obj: unknown ): obj is Range {\n\treturn Object.prototype.toString.apply( obj ) == '[object Range]';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/getpositionedancestor\n */\n\nimport global from './global.js';\n\n/**\n * For a given element, returns the nearest ancestor element which CSS position is not \"static\".\n *\n * @param element The native DOM element to be checked.\n */\nexport default function getPositionedAncestor( element?: HTMLElement ): HTMLElement | null {\n\tif ( !element || !element.parentNode ) {\n\t\treturn null;\n\t}\n\n\tif ( element.offsetParent === global.document.body ) {\n\t\treturn null;\n\t}\n\n\treturn element.offsetParent as HTMLElement;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/rect\n */\n\nimport isRange from './isrange.js';\nimport isWindow from './iswindow.js';\nimport getBorderWidths from './getborderwidths.js';\nimport isText from './istext.js';\nimport getPositionedAncestor from './getpositionedancestor.js';\nimport global from './global.js';\n\nconst rectProperties: Array<keyof RectLike> = [ 'top', 'right', 'bottom', 'left', 'width', 'height' ];\n\n/**\n * A helper class representing a `ClientRect` object, e.g. value returned by\n * the native `object.getBoundingClientRect()` method. Provides a set of methods\n * to manipulate the rect and compare it against other rect instances.\n */\nexport default class Rect {\n\t/**\n\t * The \"top\" value of the rect.\n\t *\n\t * @readonly\n\t */\n\tpublic top!: number;\n\n\t/**\n\t * The \"right\" value of the rect.\n\t *\n\t * @readonly\n\t */\n\tpublic right!: number;\n\n\t/**\n\t * The \"bottom\" value of the rect.\n\t *\n\t * @readonly\n\t */\n\tpublic bottom!: number;\n\n\t/**\n\t * The \"left\" value of the rect.\n\t *\n\t * @readonly\n\t */\n\tpublic left!: number;\n\n\t/**\n\t * The \"width\" value of the rect.\n\t *\n\t * @readonly\n\t */\n\tpublic width!: number;\n\n\t/**\n\t * The \"height\" value of the rect.\n\t *\n\t * @readonly\n\t */\n\tpublic height!: number;\n\n\t/**\n\t * The object this rect is for.\n\t *\n\t * @readonly\n\t */\n\tprivate _source!: RectSource;\n\n\t/**\n\t * Creates an instance of rect.\n\t *\n\t * ```ts\n\t * // Rect of an HTMLElement.\n\t * const rectA = new Rect( document.body );\n\t *\n\t * // Rect of a DOM Range.\n\t * const rectB = new Rect( document.getSelection().getRangeAt( 0 ) );\n\t *\n\t * // Rect of a window (web browser viewport).\n\t * const rectC = new Rect( window );\n\t *\n\t * // Rect out of an object.\n\t * const rectD = new Rect( { top: 0, right: 10, bottom: 10, left: 0, width: 10, height: 10 } );\n\t *\n\t * // Rect out of another Rect instance.\n\t * const rectE = new Rect( rectD );\n\t *\n\t * // Rect out of a ClientRect.\n\t * const rectF = new Rect( document.body.getClientRects().item( 0 ) );\n\t * ```\n\t *\n\t * **Note**: By default a rect of an HTML element includes its CSS borders and scrollbars (if any)\n\t * ant the rect of a `window` includes scrollbars too. Use {@link #excludeScrollbarsAndBorders}\n\t * to get the inner part of the rect.\n\t *\n\t * @param source A source object to create the rect.\n\t */\n\tconstructor( source: RectSource ) {\n\t\tconst isSourceRange = isRange( source );\n\n\t\tObject.defineProperty( this, '_source', {\n\t\t\t// If the source is a Rect instance, copy it's #_source.\n\t\t\tvalue: ( source as any )._source || source,\n\t\t\twritable: true,\n\t\t\tenumerable: false\n\t\t} );\n\n\t\tif ( isDomElement( source ) || isSourceRange ) {\n\t\t\t// The `Rect` class depends on `getBoundingClientRect` and `getClientRects` DOM methods. If the source\n\t\t\t// of a rect in an HTML element or a DOM range but it does not belong to any rendered DOM tree, these methods\n\t\t\t// will fail to obtain the geometry and the rect instance makes little sense to the features using it.\n\t\t\t// To get rid of this warning make sure the source passed to the constructor is a descendant of `window.document.body`.\n\t\t\t// @if CK_DEBUG // const sourceNode = isSourceRange ? source.startContainer : source;\n\t\t\t// @if CK_DEBUG // if ( !sourceNode.ownerDocument || !sourceNode.ownerDocument.body.contains( sourceNode ) ) {\n\t\t\t// @if CK_DEBUG // \tconsole.warn(\n\t\t\t// @if CK_DEBUG // \t\t'rect-source-not-in-dom: The source of this rect does not belong to any rendered DOM tree.',\n\t\t\t// @if CK_DEBUG // \t\t{ source } );\n\t\t\t// @if CK_DEBUG // }\n\n\t\t\tif ( isSourceRange ) {\n\t\t\t\tconst rangeRects = Rect.getDomRangeRects( source );\n\t\t\t\tcopyRectProperties( this, Rect.getBoundingRect( rangeRects )! );\n\t\t\t} else {\n\t\t\t\tcopyRectProperties( this, source.getBoundingClientRect() );\n\t\t\t}\n\t\t} else if ( isWindow( source ) ) {\n\t\t\tconst { innerWidth, innerHeight } = source;\n\n\t\t\tcopyRectProperties( this, {\n\t\t\t\ttop: 0,\n\t\t\t\tright: innerWidth,\n\t\t\t\tbottom: innerHeight,\n\t\t\t\tleft: 0,\n\t\t\t\twidth: innerWidth,\n\t\t\t\theight: innerHeight\n\t\t\t} );\n\t\t} else {\n\t\t\tcopyRectProperties( this, source );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a clone of the rect.\n\t *\n\t * @returns A cloned rect.\n\t */\n\tpublic clone(): Rect {\n\t\treturn new Rect( this );\n\t}\n\n\t/**\n\t * Moves the rect so that its upper–left corner lands in desired `[ x, y ]` location.\n\t *\n\t * @param x Desired horizontal location.\n\t * @param y Desired vertical location.\n\t * @returns A rect which has been moved.\n\t */\n\tpublic moveTo( x: number, y: number ): this {\n\t\tthis.top = y;\n\t\tthis.right = x + this.width;\n\t\tthis.bottom = y + this.height;\n\t\tthis.left = x;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Moves the rect in–place by a dedicated offset.\n\t *\n\t * @param x A horizontal offset.\n\t * @param y A vertical offset\n\t * @returns A rect which has been moved.\n\t */\n\tpublic moveBy( x: number, y: number ): this {\n\t\tthis.top += y;\n\t\tthis.right += x;\n\t\tthis.left += x;\n\t\tthis.bottom += y;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns a new rect a a result of intersection with another rect.\n\t */\n\tpublic getIntersection( anotherRect: Rect ): Rect | null {\n\t\tconst rect = {\n\t\t\ttop: Math.max( this.top, anotherRect.top ),\n\t\t\tright: Math.min( this.right, anotherRect.right ),\n\t\t\tbottom: Math.min( this.bottom, anotherRect.bottom ),\n\t\t\tleft: Math.max( this.left, anotherRect.left ),\n\t\t\twidth: 0,\n\t\t\theight: 0\n\t\t};\n\n\t\trect.width = rect.right - rect.left;\n\t\trect.height = rect.bottom - rect.top;\n\n\t\tif ( rect.width < 0 || rect.height < 0 ) {\n\t\t\treturn null;\n\t\t} else {\n\t\t\tconst newRect = new Rect( rect );\n\n\t\t\tnewRect._source = this._source;\n\n\t\t\treturn newRect;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the area of intersection with another rect.\n\t *\n\t * @returns Area of intersection.\n\t */\n\tpublic getIntersectionArea( anotherRect: Rect ): number {\n\t\tconst rect = this.getIntersection( anotherRect );\n\n\t\tif ( rect ) {\n\t\t\treturn rect.getArea();\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the area of the rect.\n\t */\n\tpublic getArea(): number {\n\t\treturn this.width * this.height;\n\t}\n\n\t/**\n\t * Returns a new rect, a part of the original rect, which is actually visible to the user and is relative to the,`body`,\n\t * e.g. an original rect cropped by parent element rects which have `overflow` set in CSS\n\t * other than `\"visible\"`.\n\t *\n\t * If there's no such visible rect, which is when the rect is limited by one or many of\n\t * the ancestors, `null` is returned.\n\t *\n\t * **Note**: This method does not consider the boundaries of the viewport (window).\n\t * To get a rect cropped by all ancestors and the viewport, use an intersection such as:\n\t *\n\t * ```ts\n\t * const visibleInViewportRect = new Rect( window ).getIntersection( new Rect( source ).getVisible() );\n\t * ```\n\t *\n\t * @returns A visible rect instance or `null`, if there's none.\n\t */\n\tpublic getVisible(): Rect | null {\n\t\tconst source: RectSource & { parentNode?: Node | null; commonAncestorContainer?: Node | null } = this._source;\n\n\t\tlet visibleRect = this.clone();\n\n\t\t// There's no ancestor to crop <body> with the overflow.\n\t\tif ( isBody( source ) ) {\n\t\t\treturn visibleRect;\n\t\t}\n\n\t\tlet child: any = source;\n\t\tlet parent = source.parentNode || source.commonAncestorContainer;\n\t\tlet absolutelyPositionedChildElement;\n\n\t\t// Check the ancestors all the way up to the <body>.\n\t\twhile ( parent && !isBody( parent ) ) {\n\t\t\tconst isParentOverflowVisible = getElementOverflow( parent as HTMLElement ) === 'visible';\n\n\t\t\tif ( child instanceof HTMLElement && getElementPosition( child ) === 'absolute' ) {\n\t\t\t\tabsolutelyPositionedChildElement = child;\n\t\t\t}\n\n\t\t\tconst parentElementPosition = getElementPosition( parent );\n\n\t\t\t// The child will be cropped only if it has `position: absolute` and the parent has `position: relative` + some overflow.\n\t\t\t// Otherwise there's no chance of visual clipping and the parent can be skipped\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/14107.\n\t\t\t//\n\t\t\t// condition: isParentOverflowVisible\n\t\t\t// \t\t+---------------------------+\n\t\t\t//\t\t| #parent\t\t\t\t\t|\n\t\t\t//\t\t| (overflow: visible)\t\t|\n\t\t\t//\t\t|\t\t\t\t+-----------+---------------+\n\t\t\t//\t\t|\t\t\t\t| child\t\t\t\t\t\t|\n\t\t\t//\t\t|\t\t\t\t+-----------+---------------+\n\t\t\t//\t\t+---------------------------+\n\t\t\t//\n\t\t\t// condition: absolutelyPositionedChildElement && parentElementPosition === 'relative' && isParentOverflowVisible\n\t\t\t// \t\t+---------------------------+\n\t\t\t//\t\t| parent\t\t\t\t\t|\n\t\t\t//\t\t| (position: relative;)\t\t|\n\t\t\t//\t\t| (overflow: visible;)\t\t|\n\t\t\t//\t\t|\t\t\t\t+-----------+---------------+\n\t\t\t//\t\t|\t\t\t\t| child  \t\t\t\t\t|\n\t\t\t//\t\t|\t\t\t\t| (position: absolute;)\t\t|\n\t\t\t//\t\t|\t\t\t\t+-----------+---------------+\n\t\t\t//\t\t+---------------------------+\n\t\t\t//\n\t\t\t// condition: absolutelyPositionedChildElement && parentElementPosition !== 'relative'\n\t\t\t// \t\t+---------------------------+\n\t\t\t//\t\t| parent\t\t\t\t\t|\n\t\t\t//\t\t| (position: static;)\t\t|\n\t\t\t//\t\t|\t\t\t\t+-----------+---------------+\n\t\t\t//\t\t|\t\t\t\t| child  \t\t\t\t\t|\n\t\t\t//\t\t|\t\t\t\t| (position: absolute;)\t\t|\n\t\t\t//\t\t|\t\t\t\t+-----------+---------------+\n\t\t\t//\t\t+---------------------------+\n\t\t\tif (\n\t\t\t\tisParentOverflowVisible ||\n\t\t\t\tabsolutelyPositionedChildElement && (\n\t\t\t\t\t( parentElementPosition === 'relative' && isParentOverflowVisible ) ||\n\t\t\t\t\tparentElementPosition !== 'relative'\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tchild = parent;\n\t\t\t\tparent = parent.parentNode;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst parentRect = new Rect( parent as HTMLElement );\n\t\t\tconst intersectionRect = visibleRect.getIntersection( parentRect );\n\n\t\t\tif ( intersectionRect ) {\n\t\t\t\tif ( intersectionRect.getArea() < visibleRect.getArea() ) {\n\t\t\t\t\t// Reduce the visible rect to the intersection.\n\t\t\t\t\tvisibleRect = intersectionRect;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// There's no intersection, the rect is completely invisible.\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tchild = parent;\n\t\t\tparent = parent.parentNode;\n\t\t}\n\n\t\treturn visibleRect;\n\t}\n\n\t/**\n\t * Checks if all property values ({@link #top}, {@link #left}, {@link #right},\n\t * {@link #bottom}, {@link #width} and {@link #height}) are the equal in both rect\n\t * instances.\n\t *\n\t * @param anotherRect A rect instance to compare with.\n\t * @returns `true` when Rects are equal. `false` otherwise.\n\t */\n\tpublic isEqual( anotherRect: Rect ): boolean {\n\t\tfor ( const prop of rectProperties ) {\n\t\t\tif ( this[ prop ] !== anotherRect[ prop ] ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether a rect fully contains another rect instance.\n\t *\n\t * @param anotherRect\n\t * @returns `true` if contains, `false` otherwise.\n\t */\n\tpublic contains( anotherRect: Rect ): boolean {\n\t\tconst intersectRect = this.getIntersection( anotherRect );\n\n\t\treturn !!( intersectRect && intersectRect.isEqual( anotherRect ) );\n\t}\n\n\t/**\n\t * Recalculates screen coordinates to coordinates relative to the positioned ancestor offset.\n\t */\n\tpublic toAbsoluteRect(): Rect {\n\t\tconst { scrollX, scrollY } = global.window;\n\t\tconst absoluteRect = this.clone().moveBy( scrollX, scrollY );\n\n\t\tif ( isDomElement( absoluteRect._source ) ) {\n\t\t\tconst positionedAncestor = getPositionedAncestor( absoluteRect._source );\n\n\t\t\tif ( positionedAncestor ) {\n\t\t\t\tshiftRectToCompensatePositionedAncestor( absoluteRect, positionedAncestor );\n\t\t\t}\n\t\t}\n\n\t\treturn absoluteRect;\n\t}\n\n\t/**\n\t * Excludes scrollbars and CSS borders from the rect.\n\t *\n\t * * Borders are removed when {@link #_source} is an HTML element.\n\t * * Scrollbars are excluded from HTML elements and the `window`.\n\t *\n\t * @returns A rect which has been updated.\n\t */\n\tpublic excludeScrollbarsAndBorders(): this {\n\t\tconst source = this._source as ( HTMLElement | Window );\n\t\tlet scrollBarWidth, scrollBarHeight, direction;\n\n\t\tif ( isWindow( source ) ) {\n\t\t\tscrollBarWidth = source.innerWidth - source.document.documentElement.clientWidth;\n\t\t\tscrollBarHeight = source.innerHeight - source.document.documentElement.clientHeight;\n\t\t\tdirection = source.getComputedStyle( source.document.documentElement ).direction;\n\t\t} else {\n\t\t\tconst borderWidths = getBorderWidths( source );\n\n\t\t\tscrollBarWidth = source.offsetWidth - source.clientWidth - borderWidths.left - borderWidths.right;\n\t\t\tscrollBarHeight = source.offsetHeight - source.clientHeight - borderWidths.top - borderWidths.bottom;\n\t\t\tdirection = source.ownerDocument.defaultView!.getComputedStyle( source ).direction;\n\n\t\t\tthis.left += borderWidths.left;\n\t\t\tthis.top += borderWidths.top;\n\t\t\tthis.right -= borderWidths.right;\n\t\t\tthis.bottom -= borderWidths.bottom;\n\t\t\tthis.width = this.right - this.left;\n\t\t\tthis.height = this.bottom - this.top;\n\t\t}\n\n\t\tthis.width -= scrollBarWidth;\n\n\t\tif ( direction === 'ltr' ) {\n\t\t\tthis.right -= scrollBarWidth;\n\t\t} else {\n\t\t\tthis.left += scrollBarWidth;\n\t\t}\n\n\t\tthis.height -= scrollBarHeight;\n\t\tthis.bottom -= scrollBarHeight;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns an array of rects of the given native DOM Range.\n\t *\n\t * @param range A native DOM range.\n\t * @returns DOM Range rects.\n\t */\n\tpublic static getDomRangeRects( range: Range ): Array<Rect> {\n\t\tconst rects: Array<Rect> = [];\n\t\t// Safari does not iterate over ClientRectList using for...of loop.\n\t\tconst clientRects = Array.from( range.getClientRects() );\n\n\t\tif ( clientRects.length ) {\n\t\t\tfor ( const rect of clientRects ) {\n\t\t\t\trects.push( new Rect( rect ) );\n\t\t\t}\n\t\t}\n\t\t// If there's no client rects for the Range, use parent container's bounding rect\n\t\t// instead and adjust rect's width to simulate the actual geometry of such range.\n\t\t// https://github.com/ckeditor/ckeditor5-utils/issues/153\n\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/317\n\t\telse {\n\t\t\tlet startContainer = range.startContainer;\n\n\t\t\tif ( isText( startContainer ) ) {\n\t\t\t\tstartContainer = startContainer.parentNode!;\n\t\t\t}\n\n\t\t\tconst rect = new Rect( ( startContainer as Element ).getBoundingClientRect() );\n\t\t\trect.right = rect.left;\n\t\t\trect.width = 0;\n\n\t\t\trects.push( rect );\n\t\t}\n\n\t\treturn rects;\n\t}\n\n\t/**\n\t * Returns a bounding rectangle that contains all the given `rects`.\n\t *\n\t * @param rects A list of rectangles that should be contained in the result rectangle.\n\t * @returns Bounding rectangle or `null` if no `rects` were given.\n\t */\n\tpublic static getBoundingRect( rects: Iterable<Rect> ): Rect | null {\n\t\tconst boundingRectData = {\n\t\t\tleft: Number.POSITIVE_INFINITY,\n\t\t\ttop: Number.POSITIVE_INFINITY,\n\t\t\tright: Number.NEGATIVE_INFINITY,\n\t\t\tbottom: Number.NEGATIVE_INFINITY,\n\t\t\twidth: 0,\n\t\t\theight: 0\n\t\t};\n\t\tlet rectangleCount = 0;\n\n\t\tfor ( const rect of rects ) {\n\t\t\trectangleCount++;\n\n\t\t\tboundingRectData.left = Math.min( boundingRectData.left, rect.left );\n\t\t\tboundingRectData.top = Math.min( boundingRectData.top, rect.top );\n\t\t\tboundingRectData.right = Math.max( boundingRectData.right, rect.right );\n\t\t\tboundingRectData.bottom = Math.max( boundingRectData.bottom, rect.bottom );\n\t\t}\n\n\t\tif ( rectangleCount == 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tboundingRectData.width = boundingRectData.right - boundingRectData.left;\n\t\tboundingRectData.height = boundingRectData.bottom - boundingRectData.top;\n\n\t\treturn new Rect( boundingRectData );\n\t}\n}\n\n/**\n * A source of {@link module:utils/dom/rect~Rect}.\n */\nexport type RectSource = HTMLElement | Range | Window | RectLike;\n\n/**\n * An object that describes properties of `ClientRect` object.\n */\nexport interface RectLike {\n\treadonly top: number;\n\treadonly right: number;\n\treadonly bottom: number;\n\treadonly left: number;\n\treadonly width: number;\n\treadonly height: number;\n}\n\n/**\n * Acquires all the rect properties from the passed source.\n */\nfunction copyRectProperties( rect: Rect, source: RectLike ): void {\n\tfor ( const p of rectProperties ) {\n\t\trect[ p ] = source[ p ];\n\t}\n}\n\n/**\n * Checks if provided object is a <body> HTML element.\n */\nfunction isBody( value: unknown ): value is HTMLBodyElement {\n\tif ( !isDomElement( value ) ) {\n\t\treturn false;\n\t}\n\n\treturn value === value.ownerDocument.body;\n}\n\n/**\n * Checks if provided object \"looks like\" a DOM Element and has API required by `Rect` class.\n */\nfunction isDomElement( value: any ): value is Element {\n\t// Note: earlier we used `isElement()` from lodash library, however that function is less performant because\n\t// it makes complicated checks to make sure that given value is a DOM element.\n\treturn value !== null && typeof value === 'object' && value.nodeType === 1 && typeof value.getBoundingClientRect === 'function';\n}\n\n/**\n * Returns the value of the `position` style of an `HTMLElement`.\n */\nfunction getElementPosition( element: HTMLElement | Node ): string {\n\treturn element instanceof HTMLElement ? element.ownerDocument.defaultView!.getComputedStyle( element ).position : 'static';\n}\n\n/**\n * Returns the value of the `overflow` style of an `HTMLElement` or a `Range`.\n */\nfunction getElementOverflow( element: HTMLElement | Range ): string {\n\treturn element instanceof HTMLElement ? element.ownerDocument.defaultView!.getComputedStyle( element ).overflow : 'visible';\n}\n\n/**\n * For a given absolute Rect coordinates object and a positioned element ancestor, it updates its\n * coordinates that make up for the position and the scroll of the ancestor.\n *\n * This is necessary because while Rects (and DOMRects) are relative to the browser's viewport, their coordinates\n * are used in real–life to position elements with `position: absolute`, which are scoped by any positioned\n * (and scrollable) ancestors.\n */\nfunction shiftRectToCompensatePositionedAncestor( rect: Rect, positionedElementAncestor: HTMLElement ): void {\n\tconst ancestorPosition = new Rect( positionedElementAncestor );\n\tconst ancestorBorderWidths = getBorderWidths( positionedElementAncestor );\n\n\tlet moveX = 0;\n\tlet moveY = 0;\n\n\t// (https://github.com/ckeditor/ckeditor5-ui-default/issues/126)\n\t// If there's some positioned ancestor of the panel, then its `Rect` must be taken into\n\t// consideration. `Rect` is always relative to the viewport while `position: absolute` works\n\t// with respect to that positioned ancestor.\n\tmoveX -= ancestorPosition.left;\n\tmoveY -= ancestorPosition.top;\n\n\t// (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n\t// If there's some positioned ancestor of the panel, not only its position must be taken into\n\t// consideration (see above) but also its internal scrolls. Scroll have an impact here because `Rect`\n\t// is relative to the viewport (it doesn't care about scrolling), while `position: absolute`\n\t// must compensate that scrolling.\n\tmoveX += positionedElementAncestor.scrollLeft;\n\tmoveY += positionedElementAncestor.scrollTop;\n\n\t// (https://github.com/ckeditor/ckeditor5-utils/issues/139)\n\t// If there's some positioned ancestor of the panel, then its `Rect` includes its CSS `borderWidth`\n\t// while `position: absolute` positioning does not consider it.\n\t// E.g. `{ position: absolute, top: 0, left: 0 }` means upper left corner of the element,\n\t// not upper-left corner of its border.\n\tmoveX -= ancestorBorderWidths.left;\n\tmoveY -= ancestorBorderWidths.top;\n\n\trect.moveBy( moveX, moveY );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/resizeobserver\n */\n\nimport global from './global.js';\n\n/**\n * A helper class which instances allow performing custom actions when native DOM elements are resized.\n *\n * ```ts\n * const editableElement = editor.editing.view.getDomRoot();\n *\n * const observer = new ResizeObserver( editableElement, entry => {\n * \tconsole.log( 'The editable element has been resized in DOM.' );\n * \tconsole.log( entry.target ); // -> editableElement\n * \tconsole.log( entry.contentRect.width ); // -> e.g. '423px'\n * } );\n * ```\n *\n * It uses the [native DOM resize observer](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver)\n * under the hood.\n */\nexport default class ResizeObserver {\n\t/**\n\t * The element observed by this observer.\n\t */\n\tprivate readonly _element: Element;\n\n\t/**\n\t * The callback executed each time {@link #_element} is resized.\n\t */\n\tprivate readonly _callback: ( entry: ResizeObserverEntry ) => void;\n\n\t/**\n\t * The single native observer instance shared across all {@link module:utils/dom/resizeobserver~ResizeObserver} instances.\n\t */\n\tprivate static _observerInstance: InstanceType<typeof global.window.ResizeObserver> | null = null;\n\n\t/**\n\t * A mapping of native DOM elements and their callbacks shared across all\n\t * {@link module:utils/dom/resizeobserver~ResizeObserver} instances.\n\t */\n\tprivate static _elementCallbacks: Map<Element, Set<( entry: ResizeObserverEntry ) => void>> | null = null;\n\n\t/**\n\t * Creates an instance of the `ResizeObserver` class.\n\t *\n\t * @param element A DOM element that is to be observed for resizing. Note that\n\t * the element must be visible (i.e. not detached from DOM) for the observer to work.\n\t * @param callback A function called when the observed element was resized. It passes\n\t * the [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry)\n\t * object with information about the resize event.\n\t */\n\tconstructor( element: Element, callback: ( entry: ResizeObserverEntry ) => void ) {\n\t\t// **Note**: For the maximum performance, this class ensures only a single instance of the native\n\t\t// observer is used no matter how many instances of this class were created.\n\t\tif ( !ResizeObserver._observerInstance ) {\n\t\t\tResizeObserver._createObserver();\n\t\t}\n\n\t\tthis._element = element;\n\t\tthis._callback = callback;\n\n\t\tResizeObserver._addElementCallback( element, callback );\n\t\tResizeObserver._observerInstance!.observe( element );\n\t}\n\n\t/**\n\t * The element observed by this observer.\n\t */\n\tpublic get element(): Element {\n\t\treturn this._element;\n\t}\n\n\t/**\n\t * Destroys the observer which disables the `callback` passed to the {@link #constructor}.\n\t */\n\tpublic destroy(): void {\n\t\tResizeObserver._deleteElementCallback( this._element, this._callback );\n\t}\n\n\t/**\n\t * Registers a new resize callback for the DOM element.\n\t */\n\tprivate static _addElementCallback( element: Element, callback: ( entry: ResizeObserverEntry ) => void ): void {\n\t\tif ( !ResizeObserver._elementCallbacks ) {\n\t\t\tResizeObserver._elementCallbacks = new Map();\n\t\t}\n\n\t\tlet callbacks = ResizeObserver._elementCallbacks.get( element );\n\n\t\tif ( !callbacks ) {\n\t\t\tcallbacks = new Set();\n\t\t\tResizeObserver._elementCallbacks.set( element, callbacks );\n\t\t}\n\n\t\tcallbacks.add( callback );\n\t}\n\n\t/**\n\t * Removes a resize callback from the DOM element. If no callbacks are left\n\t * for the element, it removes the element from the native observer.\n\t */\n\tprivate static _deleteElementCallback( element: Element, callback: ( entry: ResizeObserverEntry ) => void ): void {\n\t\tconst callbacks = ResizeObserver._getElementCallbacks( element );\n\n\t\t// Remove the element callback. Check if exist first in case someone\n\t\t// called destroy() twice.\n\t\tif ( callbacks ) {\n\t\t\tcallbacks.delete( callback );\n\n\t\t\t// If no callbacks left for the element, also remove the element.\n\t\t\tif ( !callbacks.size ) {\n\t\t\t\tResizeObserver._elementCallbacks!.delete( element );\n\t\t\t\tResizeObserver._observerInstance!.unobserve( element );\n\t\t\t}\n\t\t}\n\n\t\tif ( ResizeObserver._elementCallbacks && !ResizeObserver._elementCallbacks.size ) {\n\t\t\tResizeObserver._observerInstance = null;\n\t\t\tResizeObserver._elementCallbacks = null;\n\t\t}\n\t}\n\n\t/**\n\t * Returns are registered resize callbacks for the DOM element.\n\t */\n\tprivate static _getElementCallbacks( element: Element ): Set<( entry: ResizeObserverEntry ) => void> | null | undefined {\n\t\tif ( !ResizeObserver._elementCallbacks ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn ResizeObserver._elementCallbacks.get( element );\n\t}\n\n\t/**\n\t * Creates the single native observer shared across all `ResizeObserver` instances.\n\t */\n\tprivate static _createObserver(): void {\n\t\tResizeObserver._observerInstance = new global.window.ResizeObserver( entries => {\n\t\t\tfor ( const entry of entries ) {\n\t\t\t\tconst callbacks = ResizeObserver._getElementCallbacks( entry.target );\n\n\t\t\t\tif ( callbacks ) {\n\t\t\t\t\tfor ( const callback of callbacks ) {\n\t\t\t\t\t\tcallback( entry );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/setdatainelement\n */\n\n/* globals HTMLTextAreaElement */\n\n/**\n * Sets data in a given element.\n *\n * @param el The element in which the data will be set.\n * @param data The data string.\n */\nexport default function setDataInElement( el: HTMLElement, data: string ): void {\n\tif ( el instanceof HTMLTextAreaElement ) {\n\t\tel.value = data;\n\t}\n\n\tel.innerHTML = data;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/tounit\n */\n\n/**\n * Returns a helper function, which adds a desired trailing\n * `unit` to the passed value.\n *\n * @param unit An unit like \"px\" or \"em\".\n */\nexport default function toUnit( unit: string ): ToUnitHelper {\n\treturn value => value + unit;\n}\n\n/**\n * A function, which adds a pre–defined trailing `unit`\n * to the passed `value`.\n *\n * @param value A value to be given the unit.\n * @returns A value with the trailing unit.\n */\nexport type ToUnitHelper = ( value: string | number ) => string;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/indexof\n */\n\n/**\n * Returns index of the node in the parent element.\n *\n * @param node Node which index is tested.\n * @returns Index of the node in the parent element. Returns 0 if node has no parent.\n */\nexport default function indexOf( node: Node ): number {\n\tlet index = 0;\n\n\twhile ( node.previousSibling ) {\n\t\tnode = node.previousSibling;\n\t\tindex++;\n\t}\n\n\treturn index;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/insertat\n */\n\n/**\n * Inserts node to the parent at given index.\n *\n * @param parentElement Parent element.\n * @param index Insertions index.\n * @param nodeToInsert Node to insert.\n */\nexport default function insertAt(\n\tparentElement: Element,\n\tindex: number,\n\tnodeToInsert: Node\n): void {\n\tparentElement.insertBefore( nodeToInsert, parentElement.childNodes[ index ] || null );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* globals Node */\n\n/**\n * @module utils/dom/iscomment\n */\n\n/**\n * Checks whether the object is a native DOM Comment node.\n */\nexport default function isComment( obj: any ): obj is Comment {\n\treturn obj && obj.nodeType === Node.COMMENT_NODE;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/isvalidattributename\n */\n\nimport global from './global.js';\n\n/**\n * Checks if the given attribute name is valid in terms of HTML.\n *\n * @param name Attribute name.\n */\nexport default function isValidAttributeName( name: string ): boolean {\n\ttry {\n\t\tglobal.document.createAttribute( name );\n\t} catch ( error ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/isvisible\n */\n\nimport isText from './istext.js';\n\n/**\n * Checks whether the element is visible to the user in DOM:\n *\n * * connected to the root of the document,\n * * has no `display: none`,\n * * has no ancestors with `display: none`.\n *\n * **Note**: This helper does not check whether the element is hidden by cropping, overflow, etc..\n * To check that, use {@link module:utils/dom/rect~Rect} instead.\n */\nexport default function isVisible( element: Text | HTMLElement | null | undefined ): boolean {\n\tif ( !element ) {\n\t\treturn false;\n\t}\n\n\tif ( isText( element ) ) {\n\t\treturn isVisible( element.parentElement );\n\t}\n\n\tif ( element.getClientRects ) {\n\t\treturn !!( element.getClientRects().length );\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/position\n */\n\nimport global from './global.js';\nimport Rect, { type RectSource } from './rect.js';\nimport getPositionedAncestor from './getpositionedancestor.js';\nimport { isFunction } from 'lodash-es';\n\n// @if CK_DEBUG_POSITION // const {\n// @if CK_DEBUG_POSITION // \tdefault: RectDrawer,\n// @if CK_DEBUG_POSITION // \tdiagonalStylesBlack,\n// @if CK_DEBUG_POSITION // \tdiagonalStylesGreen,\n// @if CK_DEBUG_POSITION // \tdiagonalStylesRed\n// @if CK_DEBUG_POSITION // } = require( '@ckeditor/ckeditor5-utils/tests/_utils/rectdrawer' );\n// @if CK_DEBUG_POSITION // const TARGET_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px', outlineStyle: 'dashed', outlineColor: 'blue', outlineOffset: '2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const VISIBLE_TARGET_RECT_STYLE = {\n// @if CK_DEBUG_POSITION //\t\t...diagonalStylesBlack,\n// @if CK_DEBUG_POSITION //\t\topacity: '1',\n// @if CK_DEBUG_POSITION //\t\tbackgroundColor: '#00000033',\n// @if CK_DEBUG_POSITION //\t\toutlineWidth: '2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const VIEWPORT_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px',\n// @if CK_DEBUG_POSITION // \toutlineOffset: '-2px',\n// @if CK_DEBUG_POSITION // \toutlineStyle: 'solid',\n// @if CK_DEBUG_POSITION // \toutlineColor: 'red'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const VISIBLE_LIMITER_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \t...diagonalStylesGreen,\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px',\n// @if CK_DEBUG_POSITION // \toutlineOffset: '-2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const ELEMENT_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \toutlineWidth: '2px', outlineColor: 'orange', outlineOffset: '-2px'\n// @if CK_DEBUG_POSITION // };\n// @if CK_DEBUG_POSITION // const CHOSEN_POSITION_RECT_STYLE = {\n// @if CK_DEBUG_POSITION // \topacity: .5, outlineColor: 'magenta', backgroundColor: 'magenta'\n// @if CK_DEBUG_POSITION // };\n\n/**\n * Calculates the `position: absolute` coordinates of a given element so it can be positioned with respect to the\n * target in the visually most efficient way, taking various restrictions like viewport or limiter geometry\n * into consideration.\n *\n * **Note**: If there are no position coordinates found that meet the requirements (arguments of this helper),\n * `null` is returned.\n *\n * ```ts\n * // The element which is to be positioned.\n * const element = document.body.querySelector( '#toolbar' );\n *\n * // A target to which the element is positioned relatively.\n * const target = document.body.querySelector( '#container' );\n *\n * // Finding the optimal coordinates for the positioning.\n * const { left, top, name } = getOptimalPosition( {\n * \telement: element,\n * \ttarget: target,\n *\n * \t// The algorithm will chose among these positions to meet the requirements such\n * \t// as \"limiter\" element or \"fitInViewport\", set below. The positions are considered\n * \t// in the order of the array.\n * \tpositions: [\n * \t\t//\n * \t \t//\t[ Target ]\n * \t\t//\t+-----------------+\n * \t\t//\t|     Element     |\n * \t\t//\t+-----------------+\n * \t\t//\n * \t\ttargetRect => ( {\n * \t\t\ttop: targetRect.bottom,\n * \t\t\tleft: targetRect.left,\n * \t\t\tname: 'mySouthEastPosition'\n * \t\t} ),\n *\n * \t\t//\n * \t\t//\t+-----------------+\n * \t\t//\t|     Element     |\n * \t\t//\t+-----------------+\n * \t\t//\t[ Target ]\n * \t\t//\n * \t\t( targetRect, elementRect ) => ( {\n * \t\t\ttop: targetRect.top - elementRect.height,\n * \t\t\tleft: targetRect.left,\n * \t\t\tname: 'myNorthEastPosition'\n * \t\t} )\n * \t],\n *\n * \t// Find a position such guarantees the element remains within visible boundaries of <body>.\n * \tlimiter: document.body,\n *\n * \t// Find a position such guarantees the element remains within visible boundaries of the browser viewport.\n * \tfitInViewport: true\n * } );\n *\n * // The best position which fits into document.body and the viewport. May be useful\n * // to set proper class on the `element`.\n * console.log( name ); // -> \"myNorthEastPosition\"\n *\n * // Using the absolute coordinates which has been found to position the element\n * // as in the diagram depicting the \"myNorthEastPosition\" position.\n * element.style.top = top;\n * element.style.left = left;\n * ```\n *\n * @param options The input data and configuration of the helper.\n */\nexport function getOptimalPosition( {\n\telement, target, positions, limiter, fitInViewport, viewportOffsetConfig\n}: Options ): DomPoint | null {\n\t// If the {@link module:utils/dom/position~Options#target} is a function, use what it returns.\n\t// https://github.com/ckeditor/ckeditor5-utils/issues/157\n\tif ( isFunction( target ) ) {\n\t\ttarget = target();\n\t}\n\n\t// If the {@link module:utils/dom/position~Options#limiter} is a function, use what it returns.\n\t// https://github.com/ckeditor/ckeditor5-ui/issues/260\n\tif ( isFunction( limiter ) ) {\n\t\tlimiter = limiter();\n\t}\n\n\tconst positionedElementAncestor = getPositionedAncestor( element );\n\tconst constrainedViewportRect = getConstrainedViewportRect( viewportOffsetConfig );\n\tconst elementRect = new Rect( element );\n\tconst visibleTargetRect = getVisibleViewportIntersectionRect( target, constrainedViewportRect );\n\n\tlet bestPosition: DomPoint | null;\n\n\t// @if CK_DEBUG_POSITION // const targetRect = new Rect( target );\n\t// @if CK_DEBUG_POSITION // RectDrawer.clear();\n\t// @if CK_DEBUG_POSITION // RectDrawer.draw( targetRect, TARGET_RECT_STYLE, 'Target' );\n\t// @if CK_DEBUG_POSITION // if ( constrainedViewportRect ) {\n\t// @if CK_DEBUG_POSITION //\t\tRectDrawer.draw( constrainedViewportRect, VIEWPORT_RECT_STYLE, 'Viewport' );\n\t// @if CK_DEBUG_POSITION // }\n\n\t// If the target got cropped by ancestors or went off the screen, positioning does not make any sense.\n\tif ( !visibleTargetRect || !constrainedViewportRect.getIntersection( visibleTargetRect ) ) {\n\t\treturn null;\n\t}\n\n\t// @if CK_DEBUG_POSITION //\tRectDrawer.draw( visibleTargetRect, VISIBLE_TARGET_RECT_STYLE, 'VisTgt' );\n\n\tconst positionOptions: PositionObjectOptions = {\n\t\ttargetRect: visibleTargetRect,\n\t\telementRect,\n\t\tpositionedElementAncestor,\n\t\tviewportRect: constrainedViewportRect\n\t};\n\n\t// If there are no limits, just grab the very first position and be done with that drama.\n\tif ( !limiter && !fitInViewport ) {\n\t\tbestPosition = new PositionObject( positions[ 0 ], positionOptions );\n\t} else {\n\t\tif ( limiter ) {\n\t\t\tconst visibleLimiterRect = getVisibleViewportIntersectionRect( limiter, constrainedViewportRect );\n\n\t\t\tif ( visibleLimiterRect ) {\n\t\t\t\tpositionOptions.limiterRect = visibleLimiterRect;\n\t\t\t\t// @if CK_DEBUG_POSITION // RectDrawer.draw( visibleLimiterRect, VISIBLE_LIMITER_RECT_STYLE, 'VisLim' );\n\t\t\t}\n\t\t}\n\n\t\t// If there's no best position found, i.e. when all intersections have no area because\n\t\t// rects have no width or height, then just return `null`\n\t\tbestPosition = getBestPosition( positions, positionOptions );\n\t}\n\n\treturn bestPosition;\n}\n\n/**\n * Returns intersection of visible source `Rect` with Viewport `Rect`. In case when source `Rect` is not visible\n * or there is no intersection between source `Rect` and Viewport `Rect`, `null` will be returned.\n */\nfunction getVisibleViewportIntersectionRect( source: RectSource, viewportRect: Rect ): Rect | null {\n\tconst visibleSourceRect = new Rect( source ).getVisible();\n\n\tif ( !visibleSourceRect ) {\n\t\treturn null;\n\t}\n\n\treturn visibleSourceRect.getIntersection( viewportRect );\n}\n\n/**\n * Returns a viewport `Rect` shrunk by the viewport offset config from all sides.\n */\nfunction getConstrainedViewportRect( viewportOffsetConfig: Options[ 'viewportOffsetConfig' ] ): Rect {\n\tviewportOffsetConfig = Object.assign( { top: 0, bottom: 0, left: 0, right: 0 }, viewportOffsetConfig );\n\n\tconst viewportRect = new Rect( global.window );\n\n\tviewportRect.top += viewportOffsetConfig.top!;\n\tviewportRect.height -= viewportOffsetConfig.top!;\n\tviewportRect.bottom -= viewportOffsetConfig.bottom!;\n\tviewportRect.height -= viewportOffsetConfig.bottom!;\n\n\treturn viewportRect;\n}\n\n/**\n * For a given array of positioning functions, returns such that provides the best\n * fit of the `elementRect` into the `limiterRect` and `viewportRect`.\n */\nfunction getBestPosition(\n\tpositions: ReadonlyArray<PositioningFunction>,\n\toptions: ConstructorParameters<typeof PositionObject>[ 1 ]\n): DomPoint | null {\n\tconst { elementRect } = options;\n\n\t// This is when element is fully visible.\n\tconst elementRectArea = elementRect.getArea();\n\n\tconst positionInstances = positions\n\t\t.map( positioningFunction => new PositionObject( positioningFunction, options ) )\n\t\t// Some positioning functions may return `null` if they don't want to participate.\n\t\t.filter( position => !!position.name );\n\n\tlet maxFitFactor = 0;\n\tlet bestPosition = null;\n\n\tfor ( const position of positionInstances ) {\n\t\tconst { limiterIntersectionArea, viewportIntersectionArea } = position;\n\n\t\t// If a such position is found that element is fully contained by the limiter then, obviously,\n\t\t// there will be no better one, so finishing.\n\t\tif ( limiterIntersectionArea === elementRectArea ) {\n\t\t\t// @if CK_DEBUG_POSITION //\tRectDrawer.draw( position._rect, CHOSEN_POSITION_RECT_STYLE, [\n\t\t\t// @if CK_DEBUG_POSITION //\t\tposition.name,\n\t\t\t// @if CK_DEBUG_POSITION //\t\t'100% fit',\n\t\t\t// @if CK_DEBUG_POSITION //\t].join( '\\n' ) );\n\n\t\t\treturn position;\n\t\t}\n\n\t\t// To maximize both viewport and limiter intersection areas we use distance on _viewportIntersectionArea\n\t\t// and _limiterIntersectionArea plane (without sqrt because we are looking for max value).\n\t\tconst fitFactor = viewportIntersectionArea ** 2 + limiterIntersectionArea ** 2;\n\n\t\t// @if CK_DEBUG_POSITION //\tRectDrawer.draw( position._rect, { opacity: .4 }, [\n\t\t// @if CK_DEBUG_POSITION //\t\tposition.name,\n\t\t// @if CK_DEBUG_POSITION //\t\t'Vi=' +  Math.round( viewportIntersectionArea ),\n\t\t// @if CK_DEBUG_POSITION //\t\t'Li=' + Math.round( limiterIntersectionArea )\n\t\t// @if CK_DEBUG_POSITION //\t].join( '\\n' ) );\n\n\t\tif ( fitFactor > maxFitFactor ) {\n\t\t\tmaxFitFactor = fitFactor;\n\t\t\tbestPosition = position;\n\t\t}\n\t}\n\n\t// @if CK_DEBUG_POSITION // if ( bestPosition ) {\n\t// @if CK_DEBUG_POSITION // \tRectDrawer.draw( bestPosition._rect, CHOSEN_POSITION_RECT_STYLE );\n\t// @if CK_DEBUG_POSITION // }\n\n\treturn bestPosition;\n}\n\n/**\n * A position object which instances are created and used by the {@link module:utils/dom/position~getOptimalPosition} helper.\n *\n * {@link module:utils/dom/position~DomPoint#top} and {@link module:utils/dom/position~DomPoint#left} properties of the position instance\n * translate directly to the `top` and `left` properties in CSS \"`position: absolute` coordinate system\". If set on the positioned element\n * in DOM, they will make it display it in the right place in the viewport.\n */\nexport interface DomPoint {\n\n\t/**\n\t * Position name.\n\t */\n\treadonly name?: string;\n\n\t/**\n\t * Additional position configuration, as passed from the {@link module:utils/dom/position~PositioningFunction positioning function}.\n\t *\n\t * This object can be use, for instance, to pass through presentation options used by the consumer of the\n\t * {@link module:utils/dom/position~getOptimalPosition} helper.\n\t */\n\treadonly config?: object;\n\n\t/**\n\t * The left value in pixels in the CSS `position: absolute` coordinate system.\n\t * Set it on the positioned element in DOM to move it to the position.\n\t */\n\treadonly left: number;\n\n\t/**\n\t * The top value in pixels in the CSS `position: absolute` coordinate system.\n\t * Set it on the positioned element in DOM to move it to the position.\n\t */\n\treadonly top: number;\n}\n\n/**\n * A position options object which options are passed in the {@link module:utils/dom/position~PositionObject Class constructor},\n * to be used by {@link module:utils/dom/position~PositioningFunction positioning function}.\n */\ntype PositionObjectOptions = {\n\telementRect: Rect;\n\ttargetRect: Rect;\n\tviewportRect: Rect;\n\tpositionedElementAncestor?: HTMLElement | null;\n\tlimiterRect?: Rect;\n};\n\n/**\n * A position class which instances are created and used by the {@link module:utils/dom/position~getOptimalPosition} helper.\n *\n * {@link module:utils/dom/position~Position#top} and {@link module:utils/dom/position~Position#left} properties of the position instance\n * translate directly to the `top` and `left` properties in CSS \"`position: absolute` coordinate system\". If set on the positioned element\n * in DOM, they will make it display it in the right place in the viewport.\n */\nclass PositionObject implements DomPoint {\n\tpublic name?: string;\n\tpublic config?: object;\n\n\tprivate _positioningFunctionCoordinates!: { left: number; top: number };\n\tprivate _options!: ConstructorParameters<typeof PositionObject>[ 1 ];\n\tprivate _cachedRect?: Rect;\n\tprivate _cachedAbsoluteRect?: Rect;\n\n\t/**\n\t * Creates an instance of the {@link module:utils/dom/position~PositionObject} class.\n\t *\n\t * @param positioningFunction function The function that defines the expected\n\t * coordinates the positioned element should move to.\n\t * @param options options object.\n\t * @param options.elementRect The positioned element rect.\n\t * @param options.targetRect The target element rect.\n\t * @param options.viewportRect The viewport rect.\n\t * @param options.limiterRect The limiter rect.\n\t * @param options.positionedElementAncestor Nearest element ancestor element which CSS position is not \"static\".\n\t */\n\tconstructor(\n\t\tpositioningFunction: PositioningFunction,\n\t\toptions: Readonly<PositionObjectOptions>\n\t) {\n\t\tconst positioningFunctionOutput = positioningFunction(\n\t\t\toptions.targetRect,\n\t\t\toptions.elementRect,\n\t\t\toptions.viewportRect,\n\t\t\toptions.limiterRect\n\t\t);\n\n\t\t// Nameless position for a function that didn't participate.\n\t\tif ( !positioningFunctionOutput ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { left, top, name, config } = positioningFunctionOutput;\n\n\t\tthis.name = name;\n\t\tthis.config = config;\n\n\t\tthis._positioningFunctionCoordinates = { left, top };\n\t\tthis._options = options;\n\t}\n\n\t/**\n\t * The left value in pixels in the CSS `position: absolute` coordinate system.\n\t * Set it on the positioned element in DOM to move it to the position.\n\t */\n\tpublic get left(): number {\n\t\treturn this._absoluteRect.left;\n\t}\n\n\t/**\n\t * The top value in pixels in the CSS `position: absolute` coordinate system.\n\t * Set it on the positioned element in DOM to move it to the position.\n\t */\n\tpublic get top(): number {\n\t\treturn this._absoluteRect.top;\n\t}\n\n\t/**\n\t * An intersection area between positioned element and limiter within viewport constraints.\n\t */\n\tpublic get limiterIntersectionArea(): number {\n\t\tconst limiterRect = this._options.limiterRect;\n\n\t\tif ( limiterRect ) {\n\t\t\treturn limiterRect.getIntersectionArea( this._rect );\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/**\n\t * An intersection area between positioned element and viewport.\n\t */\n\tpublic get viewportIntersectionArea(): number {\n\t\tconst viewportRect = this._options.viewportRect!;\n\n\t\treturn viewportRect.getIntersectionArea( this._rect );\n\t}\n\n\t/**\n\t * An already positioned element rect. A clone of the element rect passed to the constructor\n\t * but placed in the viewport according to the positioning function.\n\t */\n\tprivate get _rect(): Rect {\n\t\tif ( this._cachedRect ) {\n\t\t\treturn this._cachedRect;\n\t\t}\n\n\t\tthis._cachedRect = this._options.elementRect.clone().moveTo(\n\t\t\tthis._positioningFunctionCoordinates.left,\n\t\t\tthis._positioningFunctionCoordinates.top\n\t\t);\n\n\t\treturn this._cachedRect;\n\t}\n\n\t/**\n\t * An already absolutely positioned element rect. See ({@link #_rect}).\n\t */\n\tprivate get _absoluteRect(): Rect {\n\t\tif ( this._cachedAbsoluteRect ) {\n\t\t\treturn this._cachedAbsoluteRect;\n\t\t}\n\n\t\tthis._cachedAbsoluteRect = this._rect.toAbsoluteRect();\n\n\t\treturn this._cachedAbsoluteRect;\n\t}\n}\n\n/**\n * The `getOptimalPosition()` helper options.\n */\nexport interface Options {\n\n\t/**\n\t * Element that is to be positioned.\n\t */\n\treadonly element: HTMLElement;\n\n\t/**\n\t * Target with respect to which the `element` is to be positioned.\n\t */\n\treadonly target: RectSource | ( () => RectSource );\n\n\t/**\n\t * An array of positioning functions.\n\t *\n\t * **Note**: Positioning functions are processed in the order of preference. The first function that works\n\t * in the current environment (e.g. offers the complete fit in the viewport geometry) will be picked by\n\t * `getOptimalPosition()`.\n\t *\n\t * **Note**: Any positioning function returning `null` is ignored.\n\t */\n\treadonly positions: ReadonlyArray<PositioningFunction>;\n\n\t/**\n\t * When set, the algorithm will chose position which fits the most in the\n\t * limiter's bounding rect.\n\t */\n\treadonly limiter?: RectSource | ( () => ( RectSource | null ) ) | null;\n\n\t/**\n\t * When set, the algorithm will chose such a position which fits `element`\n\t * the most inside visible viewport.\n\t */\n\treadonly fitInViewport?: boolean;\n\n\t/**\n\t * Viewport offset config object. It restricts the visible viewport available to the `getOptimalPosition()` from each side.\n\t *\n\t * ```ts\n\t * {\n\t * \ttop: 50,\n\t * \tright: 50,\n\t * \tbottom: 50,\n\t * \tleft: 50\n\t * }\n\t * ```\n\t */\n\treadonly viewportOffsetConfig?: {\n\t\treadonly top?: number;\n\t\treadonly right?: number;\n\t\treadonly bottom?: number;\n\t\treadonly left?: number;\n\t};\n}\n\n/**\n * A positioning function which, based on positioned element and target {@link module:utils/dom/rect~Rect Rects}, returns rect coordinates\n * representing the geometrical relation between them. Used by the {@link module:utils/dom/position~getOptimalPosition} helper.\n *\n * ```ts\n * // This simple position will place the element directly under the target, in the middle:\n * //\n * //\t    [ Target ]\n * //\t+-----------------+\n * //\t|     Element     |\n * //\t+-----------------+\n * //\n * const position = ( targetRect, elementRect, [ viewportRect ] ) => ( {\n * \ttop: targetRect.bottom,\n * \tleft: targetRect.left + targetRect.width / 2 - elementRect.width / 2,\n * \tname: 'bottomMiddle',\n *\n * \t// Note: The config is optional.\n * \tconfig: {\n * \t\tzIndex: '999'\n * \t}\n * } );\n * ```\n *\n * @param elementRect The rect of the element to be positioned.\n * @param targetRect The rect of the target the element (its rect) is relatively positioned to.\n * @param viewportRect The rect of the visual browser viewport.\n * @returns When the function returns `null`, it will not be considered by {@link module:utils/dom/position~getOptimalPosition}.\n */\nexport type PositioningFunction = (\n\telementRect: Rect,\n\ttargetRect: Rect,\n\tviewportRect: Rect,\n\tlimiterRect?: Rect\n) => PositioningFunctionResult | null;\n\n/**\n * The result of {@link module:utils/dom/position~PositioningFunction}.\n */\nexport interface PositioningFunctionResult {\n\n\t/**\n\t * The `top` value of the element rect that would represent the position.\n\t */\n\ttop: number;\n\n\t/**\n\t * The `left` value of the element rect that would represent the position.\n\t */\n\tleft: number;\n\n\t/**\n\t * The name of the position. It helps the user of the {@link module:utils/dom/position~getOptimalPosition}\n\t * helper to recognize different positioning function results. It will pass through to the {@link module:utils/dom/position~DomPoint}\n\t * returned by the helper.\n\t */\n\tname?: string;\n\n\t/**\n\t * An optional configuration that will pass-through the {@link module:utils/dom/position~getOptimalPosition} helper\n\t * to the {@link module:utils/dom/position~DomPoint} returned by this helper.\n\t * This configuration may, for instance, let the user of {@link module:utils/dom/position~getOptimalPosition} know that this particular\n\t * position comes with a certain presentation.\n\t */\n\tconfig?: object;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/remove\n */\n\n/**\n * Removes given node from parent.\n *\n * @param node Node to remove.\n */\nexport default function remove( node: Node ): void {\n\tconst parent = node.parentNode;\n\n\tif ( parent ) {\n\t\tparent.removeChild( node );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/dom/scroll\n */\n\nimport isRange from './isrange.js';\nimport Rect from './rect.js';\nimport isText from './istext.js';\n\ntype IfTrue<T> = T extends true ? true : never;\n\n/**\n * Makes any page `HTMLElement` or `Range` (`target`) visible inside the browser viewport.\n * This helper will scroll all `target` ancestors and the web browser viewport to reveal the target to\n * the user. If the `target` is already visible, nothing will happen.\n *\n * @param options Additional configuration of the scrolling behavior.\n * @param options.target A target, which supposed to become visible to the user.\n * @param options.viewportOffset An offset from the edge of the viewport (in pixels)\n * the `target` will be moved by if the viewport is scrolled. It enhances the user experience\n * by keeping the `target` some distance from the edge of the viewport and thus making it easier to\n * read or edit by the user.\n * @param options.ancestorOffset An offset from the boundary of scrollable ancestors (if any)\n * the `target` will be moved by if the viewport is scrolled. It enhances the user experience\n * by keeping the `target` some distance from the edge of the ancestors and thus making it easier to\n * read or edit by the user.\n * @param options.alignToTop When set `true`, the helper will make sure the `target` is scrolled up\n * to the top boundary of the viewport and/or scrollable ancestors if scrolled up. When not set\n * (default), the `target` will be revealed by scrolling as little as possible. This option will\n * not affect `targets` that must be scrolled down because they will appear at the top of the boundary\n * anyway.\n *\n * ```\n *                                             scrollViewportToShowTarget() with            scrollViewportToShowTarget() with\n *          Initial state                        alignToTop unset (default)                        alignToTop = true\n *\n * ┌────────────────────────────────┬─┐       ┌────────────────────────────────┬─┐        ┌────────────────────────────────┬─┐\n * │                                │▲│       │                                │▲│        │   [ Target to be revealed ]    │▲│\n * │                                │ │       │                                │ │        │                                │ │\n * │                                │█│       │                                │ │        │                                │ │\n * │                                │█│       │                                │ │        │                                │ │\n * │                                │ │       │                                │█│        │                                │ │\n * │                                │ │       │                                │█│        │                                │█│\n * │                                │ │       │                                │ │        │                                │█│\n * │                                │▼│       │   [ Target to be revealed ]    │▼│        │                                │▼│\n * └────────────────────────────────┴─┘       └────────────────────────────────┴─┘        └────────────────────────────────┴─┘\n *\n *\n *     [ Target to be revealed ]\n *```\n *\n * @param options.forceScroll When set `true`, the `target` will be aligned to the top of the viewport\n * and scrollable ancestors whether it is already visible or not. This option will only work when `alignToTop`\n * is `true`\n */\nexport function scrollViewportToShowTarget<T extends boolean, U extends IfTrue<T>>(\n\t{\n\t\ttarget,\n\t\tviewportOffset = 0,\n\t\tancestorOffset = 0,\n\t\talignToTop,\n\t\tforceScroll\n\t}:\n\t{\n\t\treadonly target: HTMLElement | Range;\n\t\treadonly viewportOffset?: number | { top: number; bottom: number; left: number; right: number };\n\t\treadonly ancestorOffset?: number;\n\t\treadonly alignToTop?: T;\n\t\treadonly forceScroll?: U;\n\t}\n): void {\n\tconst targetWindow = getWindow( target );\n\tlet currentWindow: Window | null = targetWindow;\n\tlet currentFrame: HTMLElement | null = null;\n\n\tviewportOffset = normalizeViewportOffset( viewportOffset );\n\n\t// Iterate over all windows, starting from target's parent window up to window#top.\n\twhile ( currentWindow ) {\n\t\tlet firstAncestorToScroll: HTMLElement;\n\n\t\t// Let's scroll target's ancestors first to reveal it. Then, once the ancestor scrolls\n\t\t// settled down, the algorithm can eventually scroll the viewport of the current window.\n\t\t//\n\t\t// Note: If the current window is target's **original** window (e.g. the first one),\n\t\t// start scrolling the closest parent of the target. If not, scroll the closest parent\n\t\t// of an iframe that resides in the current window.\n\t\tif ( currentWindow == targetWindow ) {\n\t\t\tfirstAncestorToScroll = getParentElement( target );\n\t\t} else {\n\t\t\tfirstAncestorToScroll = getParentElement( currentFrame! );\n\t\t}\n\n\t\t// Scroll the target's ancestors first. Once done, scrolling the viewport is easy.\n\t\tscrollAncestorsToShowRect( {\n\t\t\tparent: firstAncestorToScroll,\n\t\t\tgetRect: () => {\n\t\t\t\t// Note: If the target does not belong to the current window **directly**,\n\t\t\t\t// i.e. it resides in an iframe belonging to the window, obtain the target's rect\n\t\t\t\t// in the coordinates of the current window. By default, a Rect returns geometry\n\t\t\t\t// relative to the current window's viewport. To make it work in a parent window,\n\t\t\t\t// it must be shifted.\n\t\t\t\treturn getRectRelativeToWindow( target, currentWindow! );\n\t\t\t},\n\t\t\talignToTop,\n\t\t\tancestorOffset,\n\t\t\tforceScroll\n\t\t} );\n\n\t\t// Obtain the rect of the target after it has been scrolled within its ancestors.\n\t\t// It's time to scroll the viewport.\n\t\tconst targetRect = getRectRelativeToWindow( target, currentWindow );\n\n\t\tscrollWindowToShowRect( {\n\t\t\twindow: currentWindow,\n\t\t\trect: targetRect,\n\t\t\tviewportOffset,\n\t\t\talignToTop,\n\t\t\tforceScroll\n\t\t} );\n\n\t\tif ( currentWindow.parent != currentWindow ) {\n\t\t\t// Keep the reference to the <iframe> element the \"previous current window\" was\n\t\t\t// rendered within. It will be useful to re–calculate the rect of the target\n\t\t\t// in the parent window's relative geometry. The target's rect must be shifted\n\t\t\t// by it's iframe's position.\n\t\t\tcurrentFrame = currentWindow.frameElement as HTMLElement | null;\n\t\t\tcurrentWindow = currentWindow.parent;\n\n\t\t\t// If the current window has some parent but frameElement is inaccessible, then they have\n\t\t\t// different domains/ports and, due to security reasons, accessing and scrolling\n\t\t\t// the parent window won't be possible.\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/930.\n\t\t\tif ( !currentFrame ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tcurrentWindow = null;\n\t\t}\n\t}\n}\n\n/**\n * Makes any page `HTMLElement` or `Range` (target) visible within its scrollable ancestors,\n * e.g. if they have `overflow: scroll` CSS style.\n *\n * @param target A target, which supposed to become visible to the user.\n * @param ancestorOffset An offset between the target and the boundary of scrollable ancestors\n * to be maintained while scrolling.\n * @param limiterElement The outermost ancestor that should be scrolled. If specified, it can prevent\n * scrolling the whole page.\n */\nexport function scrollAncestorsToShowTarget( target: HTMLElement | Range, ancestorOffset?: number, limiterElement?: HTMLElement ): void {\n\tconst targetParent = getParentElement( target );\n\n\tscrollAncestorsToShowRect( {\n\t\tparent: targetParent,\n\t\tgetRect: () => new Rect( target ),\n\t\tancestorOffset,\n\t\tlimiterElement\n\t} );\n}\n\n/**\n * Makes a given rect visible within its parent window.\n *\n * Note: Avoid the situation where the caret is still in the viewport, but totally\n * at the edge of it. In such situation, if it moved beyond the viewport in the next\n * action e.g. after paste, the scrolling would move it to the viewportOffset level\n * and it all would look like the caret visually moved up/down:\n *\n * 1.\n * ```\n * | foo[]\n * |                                    <--- N px of space below the caret\n * +---------------------------------...\n * ```\n *\n * 2. *paste*\n * 3.\n * ```\n * |\n * |\n * +-foo-----------------------------...\n *   bar[]                              <--- caret below viewport, scrolling...\n * ```\n *\n * 4. *scrolling*\n * 5.\n * ```\n * |\n * | foo\n * | bar[]                              <--- caret precisely at the edge\n * +---------------------------------...\n * ```\n *\n * To prevent this, this method checks the rects moved by the viewportOffset to cover\n * the upper/lower edge of the viewport. It makes sure if the action repeats, there's\n * no twitching – it's a purely visual improvement:\n *\n * 5. (after fix)\n * ```\n * |\n * | foo\n * | bar[]\n * |                                    <--- N px of space below the caret\n * +---------------------------------...\n * ```\n *\n * @param options Additional configuration of the scrolling behavior.\n * @param options.window A window which is scrolled to reveal the rect.\n * @param options.rect A rect which is to be revealed.\n * @param options.viewportOffset An offset from the edge of the viewport (in pixels) the `rect` will be\n * moved by if the viewport is scrolled.\n * @param options.alignToTop When set `true`, the helper will make sure the `rect` is scrolled up\n * to the top boundary of the viewport if scrolled up. When not set (default), the `rect` will be\n * revealed by scrolling as little as possible. This option will not affect rects that must be scrolled\n * down because they will appear at the top of the boundary anyway.\n * @param options.forceScroll When set `true`, the `rect` will be aligned to the top of the viewport\n * whether it is already visible or not. This option will only work when `alignToTop` is `true`\n */\nfunction scrollWindowToShowRect<T extends boolean, U extends IfTrue<T>>(\n\t{\n\t\twindow,\n\t\trect,\n\t\talignToTop,\n\t\tforceScroll,\n\t\tviewportOffset\n\t}: {\n\t\treadonly window: Window;\n\t\treadonly rect: Rect;\n\t\treadonly viewportOffset: { top: number; bottom: number; left: number; right: number };\n\t\treadonly alignToTop?: T;\n\t\treadonly forceScroll?: U;\n\t}\n): void {\n\tconst targetShiftedDownRect = rect.clone().moveBy( 0, viewportOffset.bottom );\n\tconst targetShiftedUpRect = rect.clone().moveBy( 0, -viewportOffset.top );\n\tconst viewportRect = new Rect( window ).excludeScrollbarsAndBorders();\n\n\tconst rects = [ targetShiftedUpRect, targetShiftedDownRect ];\n\tconst forceScrollToTop = alignToTop && forceScroll;\n\tconst allRectsFitInViewport = rects.every( rect => viewportRect.contains( rect ) );\n\n\tlet { scrollX, scrollY } = window;\n\tconst initialScrollX = scrollX;\n\tconst initialScrollY = scrollY;\n\n\tif ( forceScrollToTop ) {\n\t\tscrollY -= ( viewportRect.top - rect.top ) + viewportOffset.top;\n\t} else if ( !allRectsFitInViewport ) {\n\t\tif ( isAbove( targetShiftedUpRect, viewportRect ) ) {\n\t\t\tscrollY -= viewportRect.top - rect.top + viewportOffset.top;\n\t\t} else if ( isBelow( targetShiftedDownRect, viewportRect ) ) {\n\t\t\tif ( alignToTop ) {\n\t\t\t\tscrollY += rect.top - viewportRect.top - viewportOffset.top;\n\t\t\t} else {\n\t\t\t\tscrollY += rect.bottom - viewportRect.bottom + viewportOffset.bottom;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( !allRectsFitInViewport ) {\n\t\t// TODO: Web browsers scroll natively to place the target in the middle\n\t\t// of the viewport. It's not a very popular case, though.\n\t\tif ( isLeftOf( rect, viewportRect ) ) {\n\t\t\tscrollX -= viewportRect.left - rect.left + viewportOffset.left;\n\t\t} else if ( isRightOf( rect, viewportRect ) ) {\n\t\t\tscrollX += rect.right - viewportRect.right + viewportOffset.right;\n\t\t}\n\t}\n\n\tif ( scrollX != initialScrollX || scrollY !== initialScrollY ) {\n\t\twindow.scrollTo( scrollX, scrollY );\n\t}\n}\n\n/**\n * Recursively scrolls element ancestors to visually reveal a rect.\n *\n * @param options Additional configuration of the scrolling behavior.\n * @param options.parent The first parent ancestor to start scrolling.\n * @param options.getRect A function which returns the Rect, which is to be revealed.\n * @param options.ancestorOffset An offset from the boundary of scrollable ancestors (if any)\n * the `Rect` instance will be moved by if the viewport is scrolled.\n * @param options.alignToTop When set `true`, the helper will make sure the `Rect` instance is scrolled up\n * to the top boundary of the scrollable ancestors if scrolled up. When not set (default), the `rect`\n * will be revealed by scrolling as little as possible. This option will not affect rects that must be\n * scrolled down because they will appear at the top of the boundary\n * anyway.\n * @param options.forceScroll When set `true`, the `rect` will be aligned to the top of scrollable ancestors\n * whether it is already visible or not. This option will only work when `alignToTop` is `true`\n * @param options.limiterElement The outermost ancestor that should be scrolled. Defaults to the `<body>` element.\n */\nfunction scrollAncestorsToShowRect<T extends boolean, U extends IfTrue<T>>(\n\t{\n\t\tparent,\n\t\tgetRect,\n\t\talignToTop,\n\t\tforceScroll,\n\t\tancestorOffset = 0,\n\t\tlimiterElement\n\t}: {\n\t\treadonly parent: HTMLElement;\n\t\treadonly getRect: () => Rect;\n\t\treadonly alignToTop?: T;\n\t\treadonly forceScroll?: U;\n\t\treadonly ancestorOffset?: number;\n\t\treadonly limiterElement?: HTMLElement;\n\t}\n): void {\n\tconst parentWindow = getWindow( parent );\n\tconst forceScrollToTop = alignToTop && forceScroll;\n\tlet parentRect: Rect, targetRect: Rect, targetFitsInTarget: boolean;\n\n\tconst limiter = limiterElement || parentWindow.document.body;\n\n\twhile ( parent != limiter ) {\n\t\ttargetRect = getRect();\n\t\tparentRect = new Rect( parent ).excludeScrollbarsAndBorders();\n\t\ttargetFitsInTarget = parentRect.contains( targetRect );\n\n\t\tif ( forceScrollToTop ) {\n\t\t\tparent.scrollTop -= ( parentRect.top - targetRect.top ) + ancestorOffset;\n\t\t} else if ( !targetFitsInTarget ) {\n\t\t\tif ( isAbove( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollTop -= parentRect.top - targetRect.top + ancestorOffset;\n\t\t\t} else if ( isBelow( targetRect, parentRect ) ) {\n\t\t\t\tif ( alignToTop ) {\n\t\t\t\t\tparent.scrollTop += targetRect.top - parentRect.top - ancestorOffset;\n\t\t\t\t} else {\n\t\t\t\t\tparent.scrollTop += targetRect.bottom - parentRect.bottom + ancestorOffset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( !targetFitsInTarget ) {\n\t\t\tif ( isLeftOf( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollLeft -= parentRect.left - targetRect.left + ancestorOffset;\n\t\t\t} else if ( isRightOf( targetRect, parentRect ) ) {\n\t\t\t\tparent.scrollLeft += targetRect.right - parentRect.right + ancestorOffset;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parentNode as HTMLElement;\n\t}\n}\n\n/**\n * Determines if a given `Rect` extends beyond the bottom edge of the second `Rect`.\n */\nfunction isBelow( firstRect: Rect, secondRect: Rect ): boolean {\n\treturn firstRect.bottom > secondRect.bottom;\n}\n\n/**\n * Determines if a given `Rect` extends beyond the top edge of the second `Rect`.\n */\nfunction isAbove( firstRect: Rect, secondRect: Rect ): boolean {\n\treturn firstRect.top < secondRect.top;\n}\n\n/**\n * Determines if a given `Rect` extends beyond the left edge of the second `Rect`.\n */\nfunction isLeftOf( firstRect: Rect, secondRect: Rect ): boolean {\n\treturn firstRect.left < secondRect.left;\n}\n\n/**\n * Determines if a given `Rect` extends beyond the right edge of the second `Rect`.\n */\nfunction isRightOf( firstRect: Rect, secondRect: Rect ): boolean {\n\treturn firstRect.right > secondRect.right;\n}\n\n/**\n * Returns the closest window of an element or range.\n */\nfunction getWindow( elementOrRange: HTMLElement | Range ): Window {\n\tif ( isRange( elementOrRange ) ) {\n\t\treturn elementOrRange.startContainer.ownerDocument!.defaultView!;\n\t} else {\n\t\treturn elementOrRange.ownerDocument.defaultView!;\n\t}\n}\n\n/**\n * Returns the closest parent of an element or DOM range.\n */\nfunction getParentElement( elementOrRange: HTMLElement | Range ): HTMLElement {\n\tif ( isRange( elementOrRange ) ) {\n\t\tlet parent = elementOrRange.commonAncestorContainer as HTMLElement;\n\n\t\t// If a Range is attached to the Text, use the closest element ancestor.\n\t\tif ( isText( parent ) ) {\n\t\t\tparent = parent.parentNode as HTMLElement;\n\t\t}\n\n\t\treturn parent;\n\t} else {\n\t\treturn elementOrRange.parentNode as HTMLElement;\n\t}\n}\n\n/**\n * Returns the rect of an element or range residing in an iframe.\n * The result rect is relative to the geometry of the passed window instance.\n *\n * @param target Element or range which rect should be returned.\n * @param relativeWindow A window the rect should be relative to.\n */\nfunction getRectRelativeToWindow( target: HTMLElement | Range, relativeWindow: Window ): Rect {\n\tconst targetWindow = getWindow( target );\n\tconst rect = new Rect( target );\n\n\tif ( targetWindow === relativeWindow ) {\n\t\treturn rect;\n\t} else {\n\t\tlet currentWindow = targetWindow;\n\n\t\twhile ( currentWindow != relativeWindow ) {\n\t\t\tconst frame = currentWindow.frameElement as HTMLElement;\n\t\t\tconst frameRect = new Rect( frame ).excludeScrollbarsAndBorders();\n\n\t\t\trect.moveBy( frameRect.left, frameRect.top );\n\n\t\t\tcurrentWindow = currentWindow.parent;\n\t\t}\n\t}\n\n\treturn rect;\n}\n\n/**\n * A helper that explodes the `viewportOffset` configuration if defined as a plain number into an object\n * with `top`, `bottom`, `left`, and `right` properties.\n *\n * If an object value is passed, this helper will pass it through.\n *\n * @param viewportOffset Viewport offset to be normalized.\n */\nfunction normalizeViewportOffset( viewportOffset: number | { top: number; bottom: number; left: number; right: number } ) {\n\tif ( typeof viewportOffset === 'number' ) {\n\t\treturn {\n\t\t\ttop: viewportOffset,\n\t\t\tbottom: viewportOffset,\n\t\t\tleft: viewportOffset,\n\t\t\tright: viewportOffset\n\t\t};\n\t}\n\n\treturn viewportOffset;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * A set of utilities related to keyboard support.\n *\n * @module utils/keyboard\n */\n\nimport type { LanguageDirection } from './language.js';\nimport CKEditorError from './ckeditorerror.js';\nimport env from './env.js';\n\nconst modifiersToGlyphsMac = {\n\tctrl: '⌃',\n\tcmd: '⌘',\n\talt: '⌥',\n\tshift: '⇧'\n} as const;\n\nconst modifiersToGlyphsNonMac = {\n\tctrl: 'Ctrl+',\n\talt: 'Alt+',\n\tshift: 'Shift+'\n} as const;\n\nconst keyCodesToGlyphs: { [key: number]: string } = {\n\t37: '←',\n\t38: '↑',\n\t39: '→',\n\t40: '↓',\n\t9: '⇥',\n\t33: 'Page Up',\n\t34: 'Page Down'\n} as const;\n\n/**\n * An object with `keyName => keyCode` pairs for a set of known keys.\n *\n * Contains:\n *\n * * `a-z`,\n * * `0-9`,\n * * `f1-f12`,\n * * `` ` ``, `-`, `=`, `[`, `]`, `;`, `'`, `,`, `.`, `/`, `\\`,\n * * `arrow(left|up|right|bottom)`,\n * * `backspace`, `delete`, `enter`, `esc`, `tab`,\n * * `ctrl`, `cmd`, `shift`, `alt`.\n */\nexport const keyCodes = /* #__PURE__ */ generateKnownKeyCodes();\n\nconst keyCodeNames: { readonly [ keyCode: number ]: string } = /* #__PURE__ */ Object.fromEntries(\n\t/* #__PURE__ */ Object.entries( keyCodes ).map( ( [ name, code ] ) => {\n\t\tlet prettyKeyName;\n\n\t\tif ( code in keyCodesToGlyphs ) {\n\t\t\tprettyKeyName = keyCodesToGlyphs[ code ];\n\t\t} else {\n\t\t\tprettyKeyName = name.charAt( 0 ).toUpperCase() + name.slice( 1 );\n\t\t}\n\n\t\treturn [ code, prettyKeyName ];\n\t} )\n);\n\n/**\n * Converts a key name or {@link module:utils/keyboard~KeystrokeInfo keystroke info} into a key code.\n *\n * Note: Key names are matched with {@link module:utils/keyboard#keyCodes} in a case-insensitive way.\n *\n * @param key A key name (see {@link module:utils/keyboard#keyCodes}) or a keystroke data object.\n * @returns Key or keystroke code.\n */\nexport function getCode( key: string | Readonly<KeystrokeInfo> ): number {\n\tlet keyCode: number | undefined;\n\n\tif ( typeof key == 'string' ) {\n\t\tkeyCode = keyCodes[ key.toLowerCase() ];\n\n\t\tif ( !keyCode ) {\n\t\t\t/**\n\t\t\t * Unknown key name. Only key names included in the {@link module:utils/keyboard#keyCodes} can be used.\n\t\t\t *\n\t\t\t * @error keyboard-unknown-key\n\t\t\t * @param {String} key\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'keyboard-unknown-key', null, { key } );\n\t\t}\n\t} else {\n\t\tkeyCode = key.keyCode +\n\t\t\t( key.altKey ? keyCodes.alt : 0 ) +\n\t\t\t( key.ctrlKey ? keyCodes.ctrl : 0 ) +\n\t\t\t( key.shiftKey ? keyCodes.shift : 0 ) +\n\t\t\t( key.metaKey ? keyCodes.cmd : 0 );\n\t}\n\n\treturn keyCode;\n}\n\n/**\n * Parses the keystroke and returns a keystroke code that will match the code returned by\n * {@link module:utils/keyboard~getCode} for the corresponding {@link module:utils/keyboard~KeystrokeInfo keystroke info}.\n *\n * The keystroke can be passed in two formats:\n *\n * * as a single string – e.g. `ctrl + A`,\n * * as an array of {@link module:utils/keyboard~keyCodes known key names} and key codes – e.g.:\n *   * `[ 'ctrl', 32 ]` (ctrl + space),\n *   * `[ 'ctrl', 'a' ]` (ctrl + A).\n *\n * Note: Key names are matched with {@link module:utils/keyboard#keyCodes} in a case-insensitive way.\n *\n * Note: Only keystrokes with a single non-modifier key are supported (e.g. `ctrl+A` is OK, but `ctrl+A+B` is not).\n *\n * Note: On macOS, keystroke handling is translating the `Ctrl` key to the `Cmd` key and handling only that keystroke.\n * For example, a registered keystroke `Ctrl+A` will be translated to `Cmd+A` on macOS. To disable the translation of some keystroke,\n * use the forced modifier: `Ctrl!+A` (note the exclamation mark).\n *\n * @param keystroke The keystroke definition.\n * @returns Keystroke code.\n */\nexport function parseKeystroke( keystroke: string | ReadonlyArray<number | string> ): number {\n\tif ( typeof keystroke == 'string' ) {\n\t\tkeystroke = splitKeystrokeText( keystroke );\n\t}\n\n\treturn keystroke\n\t\t.map( key => ( typeof key == 'string' ) ? getEnvKeyCode( key ) : key )\n\t\t.reduce( ( key, sum ) => sum + key, 0 );\n}\n\n/**\n * Translates any keystroke string text like `\"Ctrl+A\"` to an\n * environment–specific keystroke, i.e. `\"⌘A\"` on macOS.\n *\n * @param keystroke The keystroke text.\n * @returns The keystroke text specific for the environment.\n */\nexport function getEnvKeystrokeText( keystroke: string ): string {\n\tlet keystrokeCode = parseKeystroke( keystroke );\n\n\tconst modifiersToGlyphs = Object.entries( ( env.isMac || env.isiOS ) ? modifiersToGlyphsMac : modifiersToGlyphsNonMac );\n\n\tconst modifiers = modifiersToGlyphs.reduce( ( modifiers, [ name, glyph ] ) => {\n\t\t// Modifier keys are stored as a bit mask so extract those from the keystroke code.\n\t\tif ( ( keystrokeCode & keyCodes[ name ] ) != 0 ) {\n\t\t\tkeystrokeCode &= ~keyCodes[ name ];\n\t\t\tmodifiers += glyph;\n\t\t}\n\n\t\treturn modifiers;\n\t}, '' );\n\n\treturn modifiers + ( keystrokeCode ? keyCodeNames[ keystrokeCode ] : '' );\n}\n\n/**\n * Returns `true` if the provided key code represents one of the arrow keys.\n *\n * @param keyCode A key code as in {@link module:utils/keyboard~KeystrokeInfo#keyCode}.\n */\nexport function isArrowKeyCode( keyCode: number ): boolean {\n\treturn keyCode == keyCodes.arrowright ||\n\t\tkeyCode == keyCodes.arrowleft ||\n\t\tkeyCode == keyCodes.arrowup ||\n\t\tkeyCode == keyCodes.arrowdown;\n}\n\n/**\n * String representing a direction of an arrow key kode.\n */\nexport type ArrowKeyCodeDirection = 'left' | 'up' | 'right' | 'down';\n\n/**\n * Returns the direction in which the {@link module:engine/model/documentselection~DocumentSelection selection}\n * will move when the provided arrow key code is pressed considering the language direction of the editor content.\n *\n * For instance, in right–to–left (RTL) content languages, pressing the left arrow means moving the selection right (forward)\n * in the model structure. Similarly, pressing the right arrow moves the selection left (backward).\n *\n * @param keyCode A key code as in {@link module:utils/keyboard~KeystrokeInfo#keyCode}.\n * @param contentLanguageDirection The content language direction, corresponding to\n * {@link module:utils/locale~Locale#contentLanguageDirection}.\n * @returns Localized arrow direction or `undefined` for non-arrow key codes.\n */\nexport function getLocalizedArrowKeyCodeDirection(\n\tkeyCode: number,\n\tcontentLanguageDirection: LanguageDirection\n): ArrowKeyCodeDirection | undefined {\n\tconst isLtrContent = contentLanguageDirection === 'ltr';\n\n\tswitch ( keyCode ) {\n\t\tcase keyCodes.arrowleft:\n\t\t\treturn isLtrContent ? 'left' : 'right';\n\n\t\tcase keyCodes.arrowright:\n\t\t\treturn isLtrContent ? 'right' : 'left';\n\n\t\tcase keyCodes.arrowup:\n\t\t\treturn 'up';\n\n\t\tcase keyCodes.arrowdown:\n\t\t\treturn 'down';\n\t}\n}\n\n/**\n * Converts a key name to the key code with mapping based on the env.\n *\n * See: {@link module:utils/keyboard~getCode}.\n *\n * @param key The key name (see {@link module:utils/keyboard#keyCodes}).\n * @returns Key code.\n */\nfunction getEnvKeyCode( key: string ): number {\n\t// Don't remap modifier key for forced modifiers.\n\tif ( key.endsWith( '!' ) ) {\n\t\treturn getCode( key.slice( 0, -1 ) );\n\t}\n\n\tconst code = getCode( key );\n\n\treturn ( env.isMac || env.isiOS ) && code == keyCodes.ctrl ? keyCodes.cmd : code;\n}\n\n/**\n * Determines if the provided key code moves the {@link module:engine/model/documentselection~DocumentSelection selection}\n * forward or backward considering the language direction of the editor content.\n *\n * For instance, in right–to–left (RTL) languages, pressing the left arrow means moving forward\n * in the model structure. Similarly, pressing the right arrow moves the selection backward.\n *\n * @param keyCode A key code as in {@link module:utils/keyboard~KeystrokeInfo#keyCode}.\n * @param contentLanguageDirection The content language direction, corresponding to\n * {@link module:utils/locale~Locale#contentLanguageDirection}.\n */\nexport function isForwardArrowKeyCode(\n\tkeyCode: number,\n\tcontentLanguageDirection: LanguageDirection\n): boolean {\n\tconst localizedKeyCodeDirection = getLocalizedArrowKeyCodeDirection( keyCode, contentLanguageDirection );\n\n\treturn localizedKeyCodeDirection === 'down' || localizedKeyCodeDirection === 'right';\n}\n\nfunction generateKnownKeyCodes(): { readonly [ keyCode: string ]: number } {\n\tconst keyCodes: { [keyCode: string]: number } = {\n\t\tpageup: 33,\n\t\tpagedown: 34,\n\t\tarrowleft: 37,\n\t\tarrowup: 38,\n\t\tarrowright: 39,\n\t\tarrowdown: 40,\n\t\tbackspace: 8,\n\t\tdelete: 46,\n\t\tenter: 13,\n\t\tspace: 32,\n\t\tesc: 27,\n\t\ttab: 9,\n\n\t\t// The idea about these numbers is that they do not collide with any real key codes, so we can use them\n\t\t// like bit masks.\n\t\tctrl: 0x110000,\n\t\tshift: 0x220000,\n\t\talt: 0x440000,\n\t\tcmd: 0x880000\n\t};\n\n\t// a-z\n\tfor ( let code = 65; code <= 90; code++ ) {\n\t\tconst letter = String.fromCharCode( code );\n\n\t\tkeyCodes[ letter.toLowerCase() ] = code;\n\t}\n\n\t// 0-9\n\tfor ( let code = 48; code <= 57; code++ ) {\n\t\tkeyCodes[ code - 48 ] = code;\n\t}\n\n\t// F1-F12\n\tfor ( let code = 112; code <= 123; code++ ) {\n\t\tkeyCodes[ 'f' + ( code - 111 ) ] = code;\n\t}\n\n\t// other characters\n\tObject.assign( keyCodes, {\n\t\t'\\'': 222,\n\t\t',': 108,\n\t\t'-': 109,\n\t\t'.': 110,\n\t\t'/': 111,\n\t\t';': 186,\n\t\t'=': 187,\n\t\t'[': 219,\n\t\t'\\\\': 220,\n\t\t']': 221,\n\t\t'`': 223\n\t} );\n\n\treturn keyCodes;\n}\n\nfunction splitKeystrokeText( keystroke: string ): Array<string> {\n\treturn keystroke.split( '+' ).map( key => key.trim() );\n}\n\n/**\n * Information about the keystroke.\n */\nexport interface KeystrokeInfo {\n\n\t/**\n\t * The [key code](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode).\n\t */\n\tkeyCode: number;\n\n\t/**\n\t * Whether the <kbd>Alt</kbd> modifier was pressed.\n\t */\n\taltKey: boolean;\n\n\t/**\n\t * Whether the <kbd>Cmd</kbd> modifier was pressed.\n\t */\n\tmetaKey: boolean;\n\n\t/**\n\t * Whether the <kbd>Ctrl</kbd> modifier was pressed.\n\t */\n\tctrlKey: boolean;\n\n\t/**\n\t * Whether the <kbd>Shift</kbd> modifier was pressed.\n\t */\n\tshiftKey: boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/language\n */\n\n/**\n * String representing a language direction.\n */\nexport type LanguageDirection = 'ltr' | 'rtl';\n\nconst RTL_LANGUAGE_CODES = [\n\t'ar', 'ara', // Arabic\n\t'dv', 'div', // Dhivehi\n\t'fa', 'per', 'fas', // Persian\n\t'he', 'heb', // Hebrew\n\t'ku', 'kur', // Kurdish\n\t'ug', 'uig' // Uighur, Uyghur\n];\n\n/**\n * Helps determine whether a language text direction is LTR or RTL.\n *\n * @param languageCode The ISO 639-1 or ISO 639-2 language code.\n */\nexport function getLanguageDirection( languageCode: string ): LanguageDirection {\n\treturn RTL_LANGUAGE_CODES.includes( languageCode ) ? 'rtl' : 'ltr';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/toarray\n */\n\n/**\n * Transforms any value to an array. If the provided value is already an array, it is returned unchanged.\n *\n * @label MUTABLE\n * @param data The value to transform to an array.\n * @returns An array created from data.\n */\nexport default function toArray<T>( data: ArrayOrItem<T> ): Array<T>;\n\n/**\n * Transforms any value to an array. If the provided value is already an array, it is returned unchanged.\n *\n * @label IMMUTABLE\n * @param data The value to transform to an array.\n * @returns An array created from data.\n */\nexport default function toArray<T>( data: ReadonlyArrayOrItem<T> ): ReadonlyArray<T>;\n\nexport default function toArray<T>( data: ArrayOrItem<T> ): Array<T> {\n\treturn Array.isArray( data ) ? data : [ data ];\n}\n\nexport type ArrayOrItem<T> = T | Array<T>;\nexport type ReadonlyArrayOrItem<T> = T | ReadonlyArray<T>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* eslint-disable no-var */\n\n/**\n * @module utils/translation-service\n */\n\nimport type { Translations } from './locale.js';\nimport CKEditorError from './ckeditorerror.js';\nimport global from './dom/global.js';\nimport { merge } from 'lodash-es';\nimport { type ArrayOrItem } from './toarray.js';\n\ndeclare global {\n\tvar CKEDITOR_TRANSLATIONS: Translations;\n}\n\n/* istanbul ignore else -- @preserve */\nif ( !global.window.CKEDITOR_TRANSLATIONS ) {\n\tglobal.window.CKEDITOR_TRANSLATIONS = {};\n}\n\n/**\n * Adds translations to existing ones or overrides the existing translations. These translations will later\n * be available for the {@link module:utils/locale~Locale#t `t()`} function.\n *\n * The `translations` is an object which consists of `messageId: translation` pairs. Note that the message ID can be\n * either constructed from the message string or from the message ID if it was passed\n * (this happens rarely and mostly for short messages or messages with placeholders).\n * Since the editor displays only the message string, the message ID can be found either in the source code or in the\n * built translations for another language.\n *\n * ```ts\n * add( 'pl', {\n * \t'Cancel': 'Anuluj',\n * \t'IMAGE': 'obraz', // Note that the `IMAGE` comes from the message ID, while the string can be `image`.\n * } );\n * ```\n *\n * If the message is supposed to support various plural forms, make sure to provide an array with the singular form and all plural forms:\n *\n * ```ts\n * add( 'pl', {\n * \t'Add space': [ 'Dodaj spację', 'Dodaj %0 spacje', 'Dodaj %0 spacji' ]\n * } );\n * ```\n *\n * You should also specify the third argument (the `getPluralForm()` function) that will be used to determine the plural form if no\n * language file was loaded for that language. All language files coming from CKEditor 5 sources will have this option set, so\n * these plural form rules will be reused by other translations added to the registered languages. The `getPluralForm()` function\n * can return either a Boolean or a number.\n *\n * ```ts\n * add( 'en', {\n * \t// ... Translations.\n * }, n => n !== 1 );\n * add( 'pl', {\n * \t// ... Translations.\n * }, n => n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && ( n % 100 < 10 || n % 100 >= 20 ) ? 1 : 2 );\n * ```\n *\n * All translations extend the global `window.CKEDITOR_TRANSLATIONS` object. An example of this object can be found below:\n *\n * ```ts\n * {\n * \tpl: {\n * \t\tdictionary: {\n * \t\t\t'Cancel': 'Anuluj',\n * \t\t\t'Add space': [ 'Dodaj spację', 'Dodaj %0 spacje', 'Dodaj %0 spacji' ]\n * \t\t},\n * \t\t// A function that returns the plural form index.\n * \t\tgetPluralForm: n => n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && ( n % 100 < 10 || n % 100 >= 20 ) ? 1 : 2 );\n * \t}\n * \t// Other languages.\n * \t}\n * ```\n *\n * If you cannot import this function from this module (e.g. because you use a CKEditor 5 build), you can\n * still add translations by extending the global `window.CKEDITOR_TRANSLATIONS` object by using a function like\n * the one below:\n *\n * ```ts\n * function addTranslations( language, translations, getPluralForm ) {\n * \tif ( !global.window.CKEDITOR_TRANSLATIONS ) {\n * \t\tglobal.window.CKEDITOR_TRANSLATIONS = {};\n * \t}\n\n * \tif ( !global.window.CKEDITOR_TRANSLATIONS[ language ] ) {\n * \t\tglobal.window.CKEDITOR_TRANSLATIONS[ language ] = {};\n * \t}\n *\n * \tconst languageTranslations = global.window.CKEDITOR_TRANSLATIONS[ language ];\n *\n * \tlanguageTranslations.dictionary = languageTranslations.dictionary || {};\n * \tlanguageTranslations.getPluralForm = getPluralForm || languageTranslations.getPluralForm;\n *\n * \t// Extend the dictionary for the given language.\n * \tObject.assign( languageTranslations.dictionary, translations );\n * }\n * ```\n *\n * @param language Target language.\n * @param translations An object with translations which will be added to the dictionary.\n * For each message ID the value should be either a translation or an array of translations if the message\n * should support plural forms.\n * @param getPluralForm A function that returns the plural form index (a number).\n */\nexport function add(\n\tlanguage: string,\n\ttranslations: { readonly [ messageId: string ]: string | ReadonlyArray<string> },\n\tgetPluralForm?: ( n: number ) => number\n): void {\n\tif ( !global.window.CKEDITOR_TRANSLATIONS[ language ] ) {\n\t\tglobal.window.CKEDITOR_TRANSLATIONS[ language ] = {} as any;\n\t}\n\n\tconst languageTranslations = global.window.CKEDITOR_TRANSLATIONS[ language ];\n\n\tlanguageTranslations.dictionary = languageTranslations.dictionary || {};\n\tlanguageTranslations.getPluralForm = getPluralForm || languageTranslations.getPluralForm;\n\n\tObject.assign( languageTranslations.dictionary, translations );\n}\n\n/**\n * **Note:** This method is internal, use {@link module:utils/locale~Locale#t the `t()` function} instead to translate\n * the editor UI parts.\n *\n * This function is responsible for translating messages to the specified language. It uses translations added perviously\n * by {@link module:utils/translation-service~add} (a translations dictionary and the `getPluralForm()` function\n * to provide accurate translations of plural forms).\n *\n * When no translation is defined in the dictionary or the dictionary does not exist, this function returns\n * the original message string or the message plural depending on the number of elements.\n *\n * ```ts\n * translate( 'pl', { string: 'Cancel' } ); // 'Cancel'\n * ```\n *\n * The third optional argument is the number of elements, based on which the single form or one of the plural forms\n * should be picked when the message is supposed to support various plural forms.\n *\n * ```ts\n * translate( 'en', { string: 'Add a space', plural: 'Add %0 spaces' }, 1 ); // 'Add a space'\n * translate( 'en', { string: 'Add a space', plural: 'Add %0 spaces' }, 3 ); // 'Add %0 spaces'\n * ```\n *\n * The message should provide an ID using the `id` property when the message strings are not unique and their\n * translations should be different.\n *\n * ```ts\n * translate( 'en', { string: 'image', id: 'ADD_IMAGE' } );\n * translate( 'en', { string: 'image', id: 'AN_IMAGE' } );\n * ```\n *\n * @internal\n * @param language Target language.\n * @param message A message that will be translated.\n * @param quantity The number of elements for which a plural form should be picked from the target language dictionary.\n * @param translations Translations passed in editor config, if not provided use the global `window.CKEDITOR_TRANSLATIONS`.\n * @returns Translated sentence.\n */\nexport function _translate(\n\tlanguage: string,\n\tmessage: Message,\n\tquantity: number = 1,\n\ttranslations?: Translations\n): string {\n\tif ( typeof quantity !== 'number' ) {\n\t\t/**\n\t\t * An incorrect value was passed to the translation function. This was probably caused\n\t\t * by an incorrect message interpolation of a plural form. Note that for messages supporting plural forms\n\t\t * the second argument of the `t()` function should always be a number or an array with a number as the first element.\n\t\t *\n\t\t * @error translation-service-quantity-not-a-number\n\t\t */\n\t\tthrow new CKEditorError( 'translation-service-quantity-not-a-number', null, { quantity } );\n\t}\n\n\tconst normalizedTranslations: Translations = translations || global.window.CKEDITOR_TRANSLATIONS;\n\tconst numberOfLanguages = getNumberOfLanguages( normalizedTranslations );\n\n\tif ( numberOfLanguages === 1 ) {\n\t\t// Override the language to the only supported one.\n\t\t// This can't be done in the `Locale` class, because the translations comes after the `Locale` class initialization.\n\t\tlanguage = Object.keys( normalizedTranslations )[ 0 ];\n\t}\n\n\tconst messageId = message.id || message.string;\n\n\tif ( numberOfLanguages === 0 || !hasTranslation( language, messageId, normalizedTranslations ) ) {\n\t\tif ( quantity !== 1 ) {\n\t\t\t// Return the default plural form that was passed in the `message.plural` parameter.\n\t\t\treturn message.plural!;\n\t\t}\n\n\t\treturn message.string;\n\t}\n\n\tconst dictionary = normalizedTranslations[ language ].dictionary;\n\tconst getPluralForm = normalizedTranslations[ language ].getPluralForm || ( n => n === 1 ? 0 : 1 );\n\tconst translation = dictionary[ messageId ];\n\n\tif ( typeof translation === 'string' ) {\n\t\treturn translation;\n\t}\n\n\tconst pluralFormIndex = Number( getPluralForm( quantity ) );\n\n\t// Note: The `translate` function is not responsible for replacing `%0, %1, ...` with values.\n\treturn translation[ pluralFormIndex ];\n}\n\n/**\n * Clears dictionaries for test purposes.\n *\n * @internal\n */\nexport function _clear(): void {\n\tif ( global.window.CKEDITOR_TRANSLATIONS ) {\n\t\tglobal.window.CKEDITOR_TRANSLATIONS = {};\n\t}\n}\n\n/**\n * If array then merge objects which are inside otherwise return given object.\n *\n * @internal\n * @param translations Translations passed in editor config.\n */\nexport function _unifyTranslations(\n\ttranslations?: ArrayOrItem<Translations>\n): Translations | undefined {\n\treturn Array.isArray( translations ) ?\n\t\ttranslations.reduce( ( acc, translation ) => merge( acc, translation ) ) :\n\t\ttranslations;\n}\n\n/**\n * Checks whether the dictionary exists and translation in that dictionary exists.\n */\nfunction hasTranslation( language: string, messageId: string, translations: Translations ): boolean {\n\treturn !!translations[ language ] && !!translations[ language ].dictionary[ messageId ];\n}\n\nfunction getNumberOfLanguages( translations: Translations ): number {\n\treturn Object.keys( translations ).length;\n}\n\n/**\n * The internationalization message interface. A message that implements this interface can be passed to the `t()` function\n * to be translated to the target UI language.\n */\nexport interface Message {\n\n\t/**\n\t * The message string to translate. Acts as a default translation if the translation for a given language\n\t * is not defined. When the message is supposed to support plural forms, the string should be the English singular form of the message.\n\t */\n\treadonly string: string;\n\n\t/**\n\t * The message ID. If passed, the message ID is taken from this property instead of the `message.string`.\n\t * This property is useful when various messages share the same message string, for example, the `editor` string in `in the editor`\n\t * and `my editor` sentences.\n\t */\n\treadonly id?: string;\n\n\t/**\n\t * The plural form of the message. This property should be skipped when a message is not supposed\n\t * to support plural forms. Otherwise it should always be set to a string with the English plural form of the message.\n\t */\n\treadonly plural?: string;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/locale\n */\n\n/* globals console */\n\nimport toArray, { type ArrayOrItem } from './toarray.js';\nimport { _translate, _unifyTranslations, type Message } from './translation-service.js';\nimport { getLanguageDirection, type LanguageDirection } from './language.js';\n\n/**\n * Represents the localization services.\n */\nexport default class Locale {\n\t/**\n\t * The editor UI language code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t *\n\t * If the {@link #contentLanguage content language} was not specified in the `Locale` constructor,\n\t * it also defines the language of the content.\n\t */\n\tpublic readonly uiLanguage: string;\n\n\t/**\n\t * Text direction of the {@link #uiLanguage editor UI language}. Either `'ltr'` or `'rtl'`.\n\t */\n\tpublic readonly uiLanguageDirection: LanguageDirection;\n\n\t/**\n\t * The editor content language code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t *\n\t * Usually the same as the {@link #uiLanguage editor language}, it can be customized by passing an optional\n\t * argument to the `Locale` constructor.\n\t */\n\tpublic readonly contentLanguage: string;\n\n\t/**\n\t * Text direction of the {@link #contentLanguage editor content language}.\n\t *\n\t * If the content language was passed directly to the `Locale` constructor, this property represents the\n\t * direction of that language.\n\t *\n\t * If the {@link #contentLanguage editor content language} was derived from the {@link #uiLanguage editor language},\n\t * the content language direction is the same as the {@link #uiLanguageDirection UI language direction}.\n\t *\n\t * The value is either `'ltr'` or `'rtl'`.\n\t */\n\tpublic readonly contentLanguageDirection: LanguageDirection;\n\n\t/**\n\t * Translates the given message to the {@link #uiLanguage}. This method is also available in\n\t * {@link module:core/editor/editor~Editor#t `Editor`} and {@link module:ui/view~View#t `View`}.\n\t *\n\t * This method's context is statically bound to the `Locale` instance and **should always be called as a function**:\n\t *\n\t * ```ts\n\t * const t = locale.t;\n\t * t( 'Label' );\n\t * ```\n\t *\n\t * The message can be either a string or an object implementing the {@link module:utils/translation-service~Message} interface.\n\t *\n\t * The message may contain placeholders (`%<index>`) for value(s) that are passed as a `values` parameter.\n\t * For an array of values, the `%<index>` will be changed to an element of that array at the given index.\n\t * For a single value passed as the second argument, only the `%0` placeholders will be changed to the provided value.\n\t *\n\t * ```ts\n\t * t( 'Created file \"%0\" in %1ms.', [ fileName, timeTaken ] );\n\t * t( 'Created file \"%0\", fileName );\n\t * ```\n\t *\n\t * The message supports plural forms. To specify the plural form, use the `plural` property. Singular or plural form\n\t * will be chosen depending on the first value from the passed `values`. The value of the `plural` property is used\n\t * as a default plural translation when the translation for the target language is missing.\n\t *\n\t * ```ts\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 1 ); // 'Add a space' for the English language.\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 5 ); // 'Add 5 spaces' for the English language.\n\t * t( { string: '%1 a space', plural: '%1 %0 spaces' }, [ 2, 'Add' ] ); // 'Add 2 spaces' for the English language.\n\t *\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 1 ); // 'Dodaj spację' for the Polish language.\n\t * t( { string: 'Add a space', plural: 'Add %0 spaces' }, 5 ); // 'Dodaj 5 spacji' for the Polish language.\n\t * t( { string: '%1 a space', plural: '%1 %0 spaces' }, [ 2, 'Add' ] ); // 'Dodaj 2 spacje' for the Polish language.\n\t * ```\n\t *\n\t *  * The message should provide an ID using the `id` property when the message strings are not unique and their\n\t * translations should be different.\n\t *\n\t * ```ts\n\t * translate( 'en', { string: 'image', id: 'ADD_IMAGE' } );\n\t * translate( 'en', { string: 'image', id: 'AN_IMAGE' } );\n\t * ```\n\t */\n\tpublic readonly t: LocaleTranslate;\n\n\t/**\n\t * Object that contains translations.\n\t */\n\tpublic translations?: Translations;\n\n\t/**\n\t * Creates a new instance of the locale class. Learn more about\n\t * {@glink getting-started/setup/ui-language configuring the language of the editor}.\n\t *\n\t * @param options Locale configuration.\n\t * @param options.uiLanguage The editor UI language code in the\n\t * [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format. See {@link #uiLanguage}.\n\t * @param options.contentLanguage The editor content language code in the\n\t * [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format. If not specified, the same as `options.language`.\n\t * See {@link #contentLanguage}.\n\t * @param translations Translations passed as a editor config parameter.\n\t */\n\tconstructor(\n\t\t{\n\t\t\tuiLanguage = 'en',\n\t\t\tcontentLanguage,\n\t\t\ttranslations\n\t\t}: {\n\t\t\treadonly uiLanguage?: string;\n\t\t\treadonly contentLanguage?: string;\n\t\t\treadonly translations?: ArrayOrItem<Translations>;\n\t\t} = {}\n\t) {\n\t\tthis.uiLanguage = uiLanguage;\n\t\tthis.contentLanguage = contentLanguage || this.uiLanguage;\n\t\tthis.uiLanguageDirection = getLanguageDirection( this.uiLanguage );\n\t\tthis.contentLanguageDirection = getLanguageDirection( this.contentLanguage );\n\t\tthis.translations = _unifyTranslations( translations );\n\t\tthis.t = ( message, values ) => this._t( message, values );\n\t}\n\n\t/**\n\t * The editor UI language code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.\n\t *\n\t * **Note**: This property was deprecated. Please use {@link #uiLanguage} and {@link #contentLanguage}\n\t * properties instead.\n\t *\n\t * @deprecated\n\t */\n\tpublic get language(): string {\n\t\t/**\n\t\t * The {@link module:utils/locale~Locale#language `Locale#language`} property was deprecated and will\n\t\t * be removed in the near future. Please use the {@link module:utils/locale~Locale#uiLanguage `Locale#uiLanguage`} and\n\t\t * {@link module:utils/locale~Locale#contentLanguage `Locale#contentLanguage`} properties instead.\n\t\t *\n\t\t * @error locale-deprecated-language-property\n\t\t */\n\t\tconsole.warn(\n\t\t\t'locale-deprecated-language-property: ' +\n\t\t\t'The Locale#language property has been deprecated and will be removed in the near future. ' +\n\t\t\t'Please use #uiLanguage and #contentLanguage properties instead.' );\n\n\t\treturn this.uiLanguage;\n\t}\n\n\t/**\n\t * An unbound version of the {@link #t} method.\n\t */\n\tprivate _t( message: string | Message, values: number | string | ReadonlyArray<number | string> = [] ): string {\n\t\tvalues = toArray( values );\n\n\t\tif ( typeof message === 'string' ) {\n\t\t\tmessage = { string: message };\n\t\t}\n\n\t\tconst hasPluralForm = !!message.plural;\n\t\tconst quantity = hasPluralForm ? values[ 0 ] as number : 1;\n\n\t\tconst translatedString = _translate( this.uiLanguage, message, quantity, this.translations );\n\n\t\treturn interpolateString( translatedString, values );\n\t}\n}\n\n/**\n * @param message A message that will be localized (translated).\n * @param values A value or an array of values that will fill message placeholders.\n * For messages supporting plural forms the first value will determine the plural form.\n */\nexport type LocaleTranslate = (\n\tmessage: string | Message,\n\tvalues?: number | string | ReadonlyArray<number | string>\n) => string;\n\n/**\n * Fills the `%0, %1, ...` string placeholders with values.\n */\nfunction interpolateString( string: string, values: ReadonlyArray<any> ): string {\n\treturn string.replace( /%(\\d+)/g, ( match, index ) => {\n\t\treturn ( index < values.length ) ? values[ index ] : match;\n\t} );\n}\n\n/**\n * Translations object definition.\n */\nexport type Translations = {\n\t[ language: string ]: {\n\t\tdictionary: { [ messageId: string ]: string | ReadonlyArray<string> };\n\t\tgetPluralForm?: ( ( n: number ) => number | boolean ) | null;\n\t};\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/collection\n */\n\nimport EmitterMixin from './emittermixin.js';\nimport CKEditorError from './ckeditorerror.js';\nimport uid from './uid.js';\nimport isIterable from './isiterable.js';\n\n/**\n * Collections are ordered sets of objects. Items in the collection can be retrieved by their indexes\n * in the collection (like in an array) or by their ids.\n *\n * If an object without an `id` property is being added to the collection, the `id` property will be generated\n * automatically. Note that the automatically generated id is unique only within this single collection instance.\n *\n * By default an item in the collection is identified by its `id` property. The name of the identifier can be\n * configured through the constructor of the collection.\n *\n * @typeParam T The type of the collection element.\n */\nexport default class Collection<T extends Record<string, any>> extends /* #__PURE__ */ EmitterMixin() implements Iterable<T> {\n\t/**\n\t * The internal list of items in the collection.\n\t */\n\tprivate readonly _items: Array<T>;\n\n\t/**\n\t * The internal map of items in the collection.\n\t */\n\tprivate readonly _itemMap: Map<string, T>;\n\n\t/**\n\t * The name of the property which is considered to identify an item.\n\t */\n\tprivate readonly _idProperty: string;\n\n\t/**\n\t * A collection instance this collection is bound to as a result\n\t * of calling {@link #bindTo} method.\n\t */\n\tprivate _bindToCollection?: Collection<any> | null;\n\n\t/**\n\t * A helper mapping external items of a bound collection ({@link #bindTo})\n\t * and actual items of this collection. It provides information\n\t * necessary to properly remove items bound to another collection.\n\t *\n\t * See {@link #_bindToInternalToExternalMap}.\n\t */\n\tprivate readonly _bindToExternalToInternalMap: WeakMap<any, T>;\n\n\t/**\n\t * A helper mapping items of this collection to external items of a bound collection\n\t * ({@link #bindTo}). It provides information necessary to manage the bindings, e.g.\n\t * to avoid loops in two–way bindings.\n\t *\n\t * See {@link #_bindToExternalToInternalMap}.\n\t */\n\tprivate readonly _bindToInternalToExternalMap: WeakMap<T, any>;\n\n\t/**\n\t * Stores indexes of skipped items from bound external collection.\n\t */\n\tprivate _skippedIndexesFromExternal: Array<number>;\n\n\t/**\n\t * Creates a new Collection instance.\n\t *\n\t * You can pass a configuration object as the argument of the constructor:\n\t *\n\t * ```ts\n\t * const emptyCollection = new Collection<{ name: string }>( { idProperty: 'name' } );\n\t * emptyCollection.add( { name: 'John' } );\n\t * console.log( collection.get( 'John' ) ); // -> { name: 'John' }\n\t * ```\n\t *\n\t * The collection is empty by default. You can add new items using the {@link #add} method:\n\t *\n\t * ```ts\n\t * const collection = new Collection<{ id: string }>();\n\t *\n\t * collection.add( { id: 'John' } );\n\t * console.log( collection.get( 0 ) ); // -> { id: 'John' }\n\t * ```\n\t *\n\t * @label NO_ITEMS\n\t * @param options The options object.\n\t * @param options.idProperty The name of the property which is used to identify an item.\n\t * Items that do not have such a property will be assigned one when added to the collection.\n\t */\n\tconstructor( options?: { readonly idProperty?: string } );\n\n\t/**\n\t * Creates a new Collection instance with specified initial items.\n\t *\n\t * ```ts\n\t * const collection = new Collection<{ id: string }>( [ { id: 'John' }, { id: 'Mike' } ] );\n\t *\n\t * console.log( collection.get( 0 ) ); // -> { id: 'John' }\n\t * console.log( collection.get( 1 ) ); // -> { id: 'Mike' }\n\t * console.log( collection.get( 'Mike' ) ); // -> { id: 'Mike' }\n\t * ```\n\t *\n\t * You can always pass a configuration object as the last argument of the constructor:\n\t *\n\t * ```ts\n\t * const nonEmptyCollection = new Collection<{ name: string }>( [ { name: 'John' } ], { idProperty: 'name' } );\n\t * nonEmptyCollection.add( { name: 'George' } );\n\t * console.log( collection.get( 'George' ) ); // -> { name: 'George' }\n\t * console.log( collection.get( 'John' ) ); // -> { name: 'John' }\n\t * ```\n\t *\n\t * @label INITIAL_ITEMS\n\t * @param initialItems The initial items of the collection.\n\t * @param options The options object.\n\t * @param options.idProperty The name of the property which is used to identify an item.\n\t * Items that do not have such a property will be assigned one when added to the collection.\n\t */\n\tconstructor( initialItems: Iterable<T>, options?: { readonly idProperty?: string } );\n\n\tconstructor(\n\t\tinitialItemsOrOptions: Iterable<T> | { readonly idProperty?: string } = {},\n\t\toptions: { readonly idProperty?: string } = {}\n\t) {\n\t\tsuper();\n\n\t\tconst hasInitialItems = isIterable( initialItemsOrOptions );\n\n\t\tif ( !hasInitialItems ) {\n\t\t\toptions = initialItemsOrOptions;\n\t\t}\n\n\t\tthis._items = [];\n\t\tthis._itemMap = new Map();\n\t\tthis._idProperty = options.idProperty || 'id';\n\t\tthis._bindToExternalToInternalMap = new WeakMap();\n\t\tthis._bindToInternalToExternalMap = new WeakMap();\n\t\tthis._skippedIndexesFromExternal = [];\n\n\t\t// Set the initial content of the collection (if provided in the constructor).\n\t\tif ( hasInitialItems ) {\n\t\t\tfor ( const item of initialItemsOrOptions ) {\n\t\t\t\tthis._items.push( item );\n\t\t\t\tthis._itemMap.set( this._getItemIdBeforeAdding( item ), item );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The number of items available in the collection.\n\t */\n\tpublic get length(): number {\n\t\treturn this._items.length;\n\t}\n\n\t/**\n\t * Returns the first item from the collection or null when collection is empty.\n\t */\n\tpublic get first(): T | null {\n\t\treturn this._items[ 0 ] || null;\n\t}\n\n\t/**\n\t * Returns the last item from the collection or null when collection is empty.\n\t */\n\tpublic get last(): T | null {\n\t\treturn this._items[ this.length - 1 ] || null;\n\t}\n\n\t/**\n\t * Adds an item into the collection.\n\t *\n\t * If the item does not have an id, then it will be automatically generated and set on the item.\n\t *\n\t * @param item\n\t * @param index The position of the item in the collection. The item\n\t * is pushed to the collection when `index` not specified.\n\t * @fires add\n\t * @fires change\n\t */\n\tpublic add( item: T, index?: number ): this {\n\t\treturn this.addMany( [ item ], index );\n\t}\n\n\t/**\n\t * Adds multiple items into the collection.\n\t *\n\t * Any item not containing an id will get an automatically generated one.\n\t *\n\t * @param items\n\t * @param index The position of the insertion. Items will be appended if no `index` is specified.\n\t * @fires add\n\t * @fires change\n\t */\n\tpublic addMany( items: Iterable<T>, index?: number ): this {\n\t\tif ( index === undefined ) {\n\t\t\tindex = this._items.length;\n\t\t} else if ( index > this._items.length || index < 0 ) {\n\t\t\t/**\n\t\t\t * The `index` passed to {@link module:utils/collection~Collection#addMany `Collection#addMany()`}\n\t\t\t * is invalid. It must be a number between 0 and the collection's length.\n\t\t\t *\n\t\t\t * @error collection-add-item-invalid-index\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-add-item-invalid-index', this );\n\t\t}\n\n\t\tlet offset = 0;\n\n\t\tfor ( const item of items ) {\n\t\t\tconst itemId = this._getItemIdBeforeAdding( item );\n\t\t\tconst currentItemIndex = index + offset;\n\n\t\t\tthis._items.splice( currentItemIndex, 0, item );\n\t\t\tthis._itemMap.set( itemId, item );\n\n\t\t\tthis.fire<CollectionAddEvent<T>>( 'add', item, currentItemIndex );\n\n\t\t\toffset++;\n\t\t}\n\n\t\tthis.fire<CollectionChangeEvent<T>>( 'change', {\n\t\t\tadded: items,\n\t\t\tremoved: [],\n\t\t\tindex\n\t\t} );\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets an item by its ID or index.\n\t *\n\t * @param idOrIndex The item ID or index in the collection.\n\t * @returns The requested item or `null` if such item does not exist.\n\t */\n\tpublic get( idOrIndex: string | number ): T | null {\n\t\tlet item: T | undefined;\n\n\t\tif ( typeof idOrIndex == 'string' ) {\n\t\t\titem = this._itemMap.get( idOrIndex );\n\t\t} else if ( typeof idOrIndex == 'number' ) {\n\t\t\titem = this._items[ idOrIndex ];\n\t\t} else {\n\t\t\t/**\n\t\t\t * An index or ID must be given.\n\t\t\t *\n\t\t\t * @error collection-get-invalid-arg\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-get-invalid-arg', this );\n\t\t}\n\n\t\treturn item || null;\n\t}\n\n\t/**\n\t * Returns a Boolean indicating whether the collection contains an item.\n\t *\n\t * @param itemOrId The item or its ID in the collection.\n\t * @returns `true` if the collection contains the item, `false` otherwise.\n\t */\n\tpublic has( itemOrId: T | string ): boolean {\n\t\tif ( typeof itemOrId == 'string' ) {\n\t\t\treturn this._itemMap.has( itemOrId );\n\t\t} else { // Object\n\t\t\tconst idProperty = this._idProperty;\n\t\t\tconst id = itemOrId[ idProperty ];\n\n\t\t\treturn id && this._itemMap.has( id );\n\t\t}\n\t}\n\n\t/**\n\t * Gets an index of an item in the collection.\n\t * When an item is not defined in the collection, the index will equal -1.\n\t *\n\t * @param itemOrId The item or its ID in the collection.\n\t * @returns The index of a given item.\n\t */\n\tpublic getIndex( itemOrId: T | string ): number {\n\t\tlet item: T | undefined;\n\n\t\tif ( typeof itemOrId == 'string' ) {\n\t\t\titem = this._itemMap.get( itemOrId );\n\t\t} else {\n\t\t\titem = itemOrId;\n\t\t}\n\n\t\treturn item ? this._items.indexOf( item ) : -1;\n\t}\n\n\t/**\n\t * Removes an item from the collection.\n\t *\n\t * @param subject The item to remove, its ID or index in the collection.\n\t * @returns The removed item.\n\t * @fires remove\n\t * @fires change\n\t */\n\tpublic remove( subject: T | number | string ): T {\n\t\tconst [ item, index ] = this._remove( subject );\n\n\t\tthis.fire<CollectionChangeEvent<T>>( 'change', {\n\t\t\tadded: [],\n\t\t\tremoved: [ item ],\n\t\t\tindex\n\t\t} );\n\n\t\treturn item;\n\t}\n\n\t/**\n\t * Executes the callback for each item in the collection and composes an array or values returned by this callback.\n\t *\n\t * @typeParam U The result type of the callback.\n\t * @param callback\n\t * @param ctx Context in which the `callback` will be called.\n\t * @returns The result of mapping.\n\t */\n\tpublic map<U>(\n\t\tcallback: ( item: T, index: number ) => U,\n\t\tctx?: any\n\t): Array<U> {\n\t\treturn this._items.map( callback, ctx );\n\t}\n\n\t/**\n\t * Performs the specified action for each item in the collection.\n\t *\n\t * @param ctx Context in which the `callback` will be called.\n\t */\n\tpublic forEach(\n\t\tcallback: ( item: T, index: number ) => unknown,\n\t\tctx?: any\n\t): void {\n\t\tthis._items.forEach( callback, ctx );\n\t}\n\n\t/**\n\t * Finds the first item in the collection for which the `callback` returns a true value.\n\t *\n\t * @param callback\n\t * @param ctx Context in which the `callback` will be called.\n\t * @returns The item for which `callback` returned a true value.\n\t */\n\tpublic find(\n\t\tcallback: ( item: T, index: number ) => boolean,\n\t\tctx?: any\n\t): T | undefined {\n\t\treturn this._items.find( callback, ctx );\n\t}\n\n\t/**\n\t * Returns an array with items for which the `callback` returned a true value.\n\t *\n\t * @param callback\n\t * @param ctx Context in which the `callback` will be called.\n\t * @returns The array with matching items.\n\t */\n\tpublic filter(\n\t\tcallback: ( item: T, index: number ) => boolean,\n\t\tctx?: any\n\t): Array<T> {\n\t\treturn this._items.filter( callback, ctx );\n\t}\n\n\t/**\n\t * Removes all items from the collection and destroys the binding created using\n\t * {@link #bindTo}.\n\t *\n\t * @fires remove\n\t * @fires change\n\t */\n\tpublic clear(): void {\n\t\tif ( this._bindToCollection ) {\n\t\t\tthis.stopListening( this._bindToCollection );\n\t\t\tthis._bindToCollection = null;\n\t\t}\n\n\t\tconst removedItems = Array.from( this._items );\n\n\t\twhile ( this.length ) {\n\t\t\tthis._remove( 0 );\n\t\t}\n\n\t\tthis.fire<CollectionChangeEvent<T>>( 'change', {\n\t\t\tadded: [],\n\t\t\tremoved: removedItems,\n\t\t\tindex: 0\n\t\t} );\n\t}\n\n\t/**\n\t * Binds and synchronizes the collection with another one.\n\t *\n\t * The binding can be a simple factory:\n\t *\n\t * ```ts\n\t * class FactoryClass {\n\t * \tpublic label: string;\n\t *\n\t * \tconstructor( data: { label: string } ) {\n\t * \t\tthis.label = data.label;\n\t * \t}\n\t * }\n\t *\n\t * const source = new Collection<{ label: string }>( { idProperty: 'label' } );\n\t * const target = new Collection<FactoryClass>();\n\t *\n\t * target.bindTo( source ).as( FactoryClass );\n\t *\n\t * source.add( { label: 'foo' } );\n\t * source.add( { label: 'bar' } );\n\t *\n\t * console.log( target.length ); // 2\n\t * console.log( target.get( 1 ).label ); // 'bar'\n\t *\n\t * source.remove( 0 );\n\t * console.log( target.length ); // 1\n\t * console.log( target.get( 0 ).label ); // 'bar'\n\t * ```\n\t *\n\t * or the factory driven by a custom callback:\n\t *\n\t * ```ts\n\t * class FooClass {\n\t * \tpublic label: string;\n\t *\n\t * \tconstructor( data: { label: string } ) {\n\t * \t\tthis.label = data.label;\n\t * \t}\n\t * }\n\t *\n\t * class BarClass {\n\t * \tpublic label: string;\n\t *\n\t * \tconstructor( data: { label: string } ) {\n\t * \t\tthis.label = data.label;\n\t * \t}\n\t * }\n\t *\n\t * const source = new Collection<{ label: string }>( { idProperty: 'label' } );\n\t * const target = new Collection<FooClass | BarClass>();\n\t *\n\t * target.bindTo( source ).using( ( item ) => {\n\t * \tif ( item.label == 'foo' ) {\n\t * \t\treturn new FooClass( item );\n\t * \t} else {\n\t * \t\treturn new BarClass( item );\n\t * \t}\n\t * } );\n\t *\n\t * source.add( { label: 'foo' } );\n\t * source.add( { label: 'bar' } );\n\t *\n\t * console.log( target.length ); // 2\n\t * console.log( target.get( 0 ) instanceof FooClass ); // true\n\t * console.log( target.get( 1 ) instanceof BarClass ); // true\n\t * ```\n\t *\n\t * or the factory out of property name:\n\t *\n\t * ```ts\n\t * const source = new Collection<{ nested: { value: string } }>();\n\t * const target = new Collection<{ value: string }>();\n\t *\n\t * target.bindTo( source ).using( 'nested' );\n\t *\n\t * source.add( { nested: { value: 'foo' } } );\n\t * source.add( { nested: { value: 'bar' } } );\n\t *\n\t * console.log( target.length ); // 2\n\t * console.log( target.get( 0 ).value ); // 'foo'\n\t * console.log( target.get( 1 ).value ); // 'bar'\n\t * ```\n\t *\n\t * It's possible to skip specified items by returning null value:\n\t *\n\t * ```ts\n\t * const source = new Collection<{ hidden: boolean }>();\n\t * const target = new Collection<{ hidden: boolean }>();\n\t *\n\t * target.bindTo( source ).using( item => {\n\t * \tif ( item.hidden ) {\n\t * \t\treturn null;\n\t * \t}\n\t *\n\t * \treturn item;\n\t * } );\n\t *\n\t * source.add( { hidden: true } );\n\t * source.add( { hidden: false } );\n\t *\n\t * console.log( source.length ); // 2\n\t * console.log( target.length ); // 1\n\t * ```\n\t *\n\t * **Note**: {@link #clear} can be used to break the binding.\n\t *\n\t * @typeParam S The type of `externalCollection` element.\n\t * @param externalCollection A collection to be bound.\n\t * @returns The binding chain object.\n\t */\n\tpublic bindTo<S extends Record<string, any>>(\n\t\texternalCollection: Collection<S>\n\t): CollectionBindToChain<S, T> {\n\t\tif ( this._bindToCollection ) {\n\t\t\t/**\n\t\t\t * The collection cannot be bound more than once.\n\t\t\t *\n\t\t\t * @error collection-bind-to-rebind\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-bind-to-rebind', this );\n\t\t}\n\n\t\tthis._bindToCollection = externalCollection;\n\n\t\treturn {\n\t\t\tas: Class => {\n\t\t\t\tthis._setUpBindToBinding<S>( item => new Class( item ) );\n\t\t\t},\n\n\t\t\tusing: callbackOrProperty => {\n\t\t\t\tif ( typeof callbackOrProperty == 'function' ) {\n\t\t\t\t\tthis._setUpBindToBinding<S>( callbackOrProperty );\n\t\t\t\t} else {\n\t\t\t\t\tthis._setUpBindToBinding<S>( item => item[ callbackOrProperty ] );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Finalizes and activates a binding initiated by {@link #bindTo}.\n\t *\n\t * @param factory A function which produces collection items.\n\t */\n\tprivate _setUpBindToBinding<S>( factory: ( item: S ) => T | null ): void {\n\t\tconst externalCollection = this._bindToCollection!;\n\n\t\t// Adds the item to the collection once a change has been done to the external collection.\n\t\tconst addItem = ( evt: unknown, externalItem: S, index: number ) => {\n\t\t\tconst isExternalBoundToThis = externalCollection._bindToCollection == this;\n\t\t\tconst externalItemBound = externalCollection._bindToInternalToExternalMap.get( externalItem );\n\n\t\t\t// If an external collection is bound to this collection, which makes it a 2–way binding,\n\t\t\t// and the particular external collection item is already bound, don't add it here.\n\t\t\t// The external item has been created **out of this collection's item** and (re)adding it will\n\t\t\t// cause a loop.\n\t\t\tif ( isExternalBoundToThis && externalItemBound ) {\n\t\t\t\tthis._bindToExternalToInternalMap.set( externalItem, externalItemBound );\n\t\t\t\tthis._bindToInternalToExternalMap.set( externalItemBound, externalItem );\n\t\t\t} else {\n\t\t\t\tconst item = factory( externalItem );\n\n\t\t\t\t// When there is no item we need to remember skipped index first and then we can skip this item.\n\t\t\t\tif ( !item ) {\n\t\t\t\t\tthis._skippedIndexesFromExternal.push( index );\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Lets try to put item at the same index as index in external collection\n\t\t\t\t// but when there are a skipped items in one or both collections we need to recalculate this index.\n\t\t\t\tlet finalIndex = index;\n\n\t\t\t\t// When we try to insert item after some skipped items from external collection we need\n\t\t\t\t// to include this skipped items and decrease index.\n\t\t\t\t//\n\t\t\t\t// For the following example:\n\t\t\t\t// external -> [ 'A', 'B - skipped for internal', 'C - skipped for internal' ]\n\t\t\t\t// internal -> [ A ]\n\t\t\t\t//\n\t\t\t\t// Another item is been added at the end of external collection:\n\t\t\t\t// external.add( 'D' )\n\t\t\t\t// external -> [ 'A', 'B - skipped for internal', 'C - skipped for internal', 'D' ]\n\t\t\t\t//\n\t\t\t\t// We can't just add 'D' to internal at the same index as index in external because\n\t\t\t\t// this will produce empty indexes what is invalid:\n\t\t\t\t// internal -> [ 'A', empty, empty, 'D' ]\n\t\t\t\t//\n\t\t\t\t// So we need to include skipped items and decrease index\n\t\t\t\t// internal -> [ 'A', 'D' ]\n\t\t\t\tfor ( const skipped of this._skippedIndexesFromExternal ) {\n\t\t\t\t\tif ( index > skipped ) {\n\t\t\t\t\t\tfinalIndex--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// We need to take into consideration that external collection could skip some items from\n\t\t\t\t// internal collection.\n\t\t\t\t//\n\t\t\t\t// For the following example:\n\t\t\t\t// internal -> [ 'A', 'B - skipped for external', 'C - skipped for external' ]\n\t\t\t\t// external -> [ A ]\n\t\t\t\t//\n\t\t\t\t// Another item is been added at the end of external collection:\n\t\t\t\t// external.add( 'D' )\n\t\t\t\t// external -> [ 'A', 'D' ]\n\t\t\t\t//\n\t\t\t\t// We need to include skipped items and place new item after them:\n\t\t\t\t// internal -> [ 'A', 'B - skipped for external', 'C - skipped for external', 'D' ]\n\t\t\t\tfor ( const skipped of externalCollection._skippedIndexesFromExternal ) {\n\t\t\t\t\tif ( finalIndex >= skipped ) {\n\t\t\t\t\t\tfinalIndex++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis._bindToExternalToInternalMap.set( externalItem, item );\n\t\t\t\tthis._bindToInternalToExternalMap.set( item, externalItem );\n\t\t\t\tthis.add( item, finalIndex );\n\n\t\t\t\t// After adding new element to internal collection we need update indexes\n\t\t\t\t// of skipped items in external collection.\n\t\t\t\tfor ( let i = 0; i < externalCollection._skippedIndexesFromExternal.length; i++ ) {\n\t\t\t\t\tif ( finalIndex <= externalCollection._skippedIndexesFromExternal[ i ] ) {\n\t\t\t\t\t\texternalCollection._skippedIndexesFromExternal[ i ]++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Load the initial content of the collection.\n\t\tfor ( const externalItem of externalCollection ) {\n\t\t\taddItem( null, externalItem, externalCollection.getIndex( externalItem ) );\n\t\t}\n\n\t\t// Synchronize the with collection as new items are added.\n\t\tthis.listenTo<CollectionAddEvent<S>>( externalCollection, 'add', addItem );\n\n\t\t// Synchronize the with collection as new items are removed.\n\t\tthis.listenTo<CollectionRemoveEvent<S>>( externalCollection, 'remove', ( evt, externalItem, index ) => {\n\t\t\tconst item = this._bindToExternalToInternalMap.get( externalItem );\n\n\t\t\tif ( item ) {\n\t\t\t\tthis.remove( item );\n\t\t\t}\n\n\t\t\t// After removing element from external collection we need update/remove indexes\n\t\t\t// of skipped items in internal collection.\n\t\t\tthis._skippedIndexesFromExternal = this._skippedIndexesFromExternal.reduce( ( result, skipped ) => {\n\t\t\t\tif ( index < skipped ) {\n\t\t\t\t\tresult.push( skipped - 1 );\n\t\t\t\t}\n\n\t\t\t\tif ( index > skipped ) {\n\t\t\t\t\tresult.push( skipped );\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t}, [] as Array<number> );\n\t\t} );\n\t}\n\n\t/**\n\t * Returns an unique id property for a given `item`.\n\t *\n\t * The method will generate new id and assign it to the `item` if it doesn't have any.\n\t *\n\t * @param item Item to be added.\n\t */\n\tprivate _getItemIdBeforeAdding( item: any ): string {\n\t\tconst idProperty = this._idProperty;\n\t\tlet itemId: string | undefined;\n\n\t\tif ( ( idProperty in item ) ) {\n\t\t\titemId = item[ idProperty ];\n\n\t\t\tif ( typeof itemId != 'string' ) {\n\t\t\t\t/**\n\t\t\t\t * This item's ID should be a string.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-invalid-id\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'collection-add-invalid-id', this );\n\t\t\t}\n\n\t\t\tif ( this.get( itemId ) ) {\n\t\t\t\t/**\n\t\t\t\t * This item already exists in the collection.\n\t\t\t\t *\n\t\t\t\t * @error collection-add-item-already-exists\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'collection-add-item-already-exists', this );\n\t\t\t}\n\t\t} else {\n\t\t\titem[ idProperty ] = itemId = uid();\n\t\t}\n\n\t\treturn itemId;\n\t}\n\n\t/**\n\t * Core {@link #remove} method implementation shared in other functions.\n\t *\n\t * In contrast this method **does not** fire the {@link #event:change} event.\n\t *\n\t * @param subject The item to remove, its id or index in the collection.\n\t * @returns Returns an array with the removed item and its index.\n\t * @fires remove\n\t */\n\tprivate _remove( subject: T | number | string ): [ item: T, index: number ] {\n\t\tlet index: number, id: string, item: T;\n\t\tlet itemDoesNotExist = false;\n\t\tconst idProperty = this._idProperty;\n\n\t\tif ( typeof subject == 'string' ) {\n\t\t\tid = subject;\n\t\t\titem = this._itemMap.get( id )!;\n\t\t\titemDoesNotExist = !item;\n\n\t\t\tif ( item ) {\n\t\t\t\tindex = this._items.indexOf( item );\n\t\t\t}\n\t\t} else if ( typeof subject == 'number' ) {\n\t\t\tindex = subject;\n\t\t\titem = this._items[ index ];\n\t\t\titemDoesNotExist = !item;\n\n\t\t\tif ( item ) {\n\t\t\t\tid = item[ idProperty ]!;\n\t\t\t}\n\t\t} else {\n\t\t\titem = subject;\n\t\t\tid = item[ idProperty ]!;\n\t\t\tindex = this._items.indexOf( item );\n\t\t\titemDoesNotExist = ( index == -1 || !this._itemMap.get( id ) );\n\t\t}\n\n\t\tif ( itemDoesNotExist ) {\n\t\t\t/**\n\t\t\t * Item not found.\n\t\t\t *\n\t\t\t * @error collection-remove-404\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'collection-remove-404', this );\n\t\t}\n\n\t\tthis._items.splice( index!, 1 );\n\t\tthis._itemMap.delete( id! );\n\n\t\tconst externalItem = this._bindToInternalToExternalMap.get( item );\n\t\tthis._bindToInternalToExternalMap.delete( item );\n\t\tthis._bindToExternalToInternalMap.delete( externalItem );\n\n\t\tthis.fire<CollectionRemoveEvent<T>>( 'remove', item, index! );\n\n\t\treturn [ item, index! ];\n\t}\n\n\t/**\n\t * Iterable interface.\n\t */\n\tpublic [ Symbol.iterator ](): Iterator<T> {\n\t\treturn this._items[ Symbol.iterator ]();\n\t}\n}\n\n/**\n * Fired when an item is added to the collection.\n *\n * @eventName ~Collection#add\n * @param item The added item.\n * @param index An index where the addition occurred.\n */\nexport type CollectionAddEvent<T = any> = {\n\tname: 'add';\n\targs: [ item: T, index: number ];\n};\n\n/**\n * Fired when the collection was changed due to adding or removing items.\n *\n * @eventName ~Collection#change\n * @param data Changed items.\n */\nexport type CollectionChangeEvent<T = any> = {\n\tname: 'change';\n\targs: [ data: CollectionChangeEventData<T> ];\n};\n\n/**\n * A structure describing the {@link ~Collection#event:change `Collection#change`} event.\n */\nexport type CollectionChangeEventData<T = any> = {\n\n\t/**\n\t * A list of added items.\n\t */\n\tadded: Iterable<T>;\n\n\t/**\n\t * A list of removed items.\n\t */\n\tremoved: Iterable<T>;\n\n\t/**\n\t * An index where the addition or removal occurred.\n\t */\n\tindex: number;\n};\n\n/**\n * Fired when an item is removed from the collection.\n *\n * @eventName ~Collection#remove\n * @param item The removed item.\n * @param index Index from which item was removed.\n */\nexport type CollectionRemoveEvent<T = any> = {\n\tname: 'remove';\n\targs: [ item: T, index: number ];\n};\n\n/**\n * An object returned by the {@link module:utils/collection~Collection#bindTo `bindTo()`} method\n * providing functions that specify the type of the binding.\n *\n * See the {@link module:utils/collection~Collection#bindTo `bindTo()`} documentation for examples.\n */\nexport interface CollectionBindToChain<S, T> {\n\n\t/**\n\t * Creates the class factory binding in which items of the source collection are passed to\n\t * the constructor of the specified class.\n\t *\n\t * @param Class The class constructor used to create instances in the factory.\n\t */\n\tas( Class: new ( item: S ) => T ): void;\n\n\t/**\n\t * Creates a callback or a property binding.\n\t *\n\t * @param callbackOrProperty When the function is passed, it should return\n\t * the collection items. When the string is provided, the property value is used to create the bound collection items.\n\t */\n\tusing( callbackOrProperty: keyof S | ( ( item: S ) => T | null ) ): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/first\n */\n\n/**\n * Returns first item of the given `iterator`.\n */\nexport default function first<T>( iterator: Iterator<T> ): T | null {\n\tconst iteratorItem = iterator.next();\n\n\tif ( iteratorItem.done ) {\n\t\treturn null;\n\t}\n\n\treturn iteratorItem.value;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* global setTimeout, clearTimeout */\n\n/**\n * @module utils/focustracker\n */\n\nimport DomEmitterMixin from './dom/emittermixin.js';\nimport ObservableMixin from './observablemixin.js';\nimport CKEditorError from './ckeditorerror.js';\nimport { type View } from '@ckeditor/ckeditor5-ui';\nimport { isElement as _isElement } from 'lodash-es';\n\n/**\n * Allows observing a group of DOM `Element`s or {@link module:ui/view~View view instances} whether at least one of them (or their child)\n * is focused.\n *\n * Used by the {@link module:core/editor/editor~Editor} in order to track whether the focus is still within the application,\n * or were used outside of its UI.\n *\n * **Note** `focus` and `blur` listeners use event capturing, so it is only needed to register wrapper `Element`\n * which contain other `focusable` elements. But note that this wrapper element has to be focusable too\n * (have e.g. `tabindex=\"-1\"`).\n *\n * Check out the {@glink framework/deep-dive/ui/focus-tracking \"Deep dive into focus tracking\"} guide to learn more.\n */\nexport default class FocusTracker extends /* #__PURE__ */ DomEmitterMixin( /* #__PURE__ */ ObservableMixin() ) {\n\t/**\n\t * True when one of the registered {@link #elements} or {@link #externalViews} is focused.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isFocused: boolean;\n\n\t/**\n\t * The currently focused element.\n\t *\n\t * While {@link #isFocused `isFocused`} remains `true`, the focus can move between different UI elements. This property tracks those\n\t * elements and tells which one is currently focused.\n\t *\n\t * **Note**: The values of this property are restricted to {@link #elements} or {@link module:ui/view~View#element elements}\n\t * registered in {@link #externalViews}.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public focusedElement: Element | null;\n\n\t/**\n\t * List of registered DOM elements.\n\t *\n\t * @internal\n\t */\n\tpublic _elements: Set<Element> = new Set();\n\n\t/**\n\t * List of views with external focus trackers that contribute to the state of this focus tracker.\n\t *\n\t * @internal\n\t */\n\tpublic _externalViews: Set<ViewWithFocusTracker> = new Set();\n\n\t/**\n\t * Asynchronous blur event timeout.\n\t */\n\tprivate _blurTimeout: ReturnType<typeof setTimeout> | null = null;\n\n\t// @if CK_DEBUG_FOCUSTRACKER // public _label?: string;\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.set( 'isFocused', false );\n\t\tthis.set( 'focusedElement', null );\n\n\t\t// @if CK_DEBUG_FOCUSTRACKER // FocusTracker._instances.push( this );\n\t}\n\n\t/**\n\t * List of registered DOM elements.\n\t *\n\t * **Note**: The list does do not include elements from {@link #externalViews}.\n\t */\n\tpublic get elements(): Array<Element> {\n\t\treturn Array.from( this._elements.values() );\n\t}\n\n\t/**\n\t * List of external focusable views that contribute to the state of this focus tracker. See {@link #add} to learn more.\n\t */\n\tpublic get externalViews(): Array<ViewWithFocusTracker> {\n\t\treturn Array.from( this._externalViews.values() );\n\t}\n\n\t/**\n\t * Starts tracking a specified DOM element or a {@link module:ui/view~View} instance.\n\t *\n\t * * If a DOM element is passed, the focus tracker listens to the `focus` and `blur` events on this element.\n\t * Tracked elements are listed in {@link #elements}.\n\t * * If a {@link module:ui/view~View} instance is passed that has a `FocusTracker` instance ({@link ~ViewWithFocusTracker}),\n\t * the external focus tracker's state ({@link #isFocused}, {@link #focusedElement}) starts contributing to the current tracker instance.\n\t * This allows for increasing the \"reach\" of a focus tracker instance, by connecting two or more focus trackers together when DOM\n\t * elements they track are located in different subtrees in DOM. External focus trackers are listed in {@link #externalViews}.\n\t * * If a {@link module:ui/view~View} instance is passed that has no `FocusTracker` (**not** a {@link ~ViewWithFocusTracker}),\n\t * its {@link module:ui/view~View#element} is used to track focus like any other DOM element.\n\t */\n\tpublic add( elementOrView: Element | View ): void {\n\t\tif ( isElement( elementOrView ) ) {\n\t\t\tthis._addElement( elementOrView );\n\t\t} else {\n\t\t\tif ( isViewWithFocusTracker( elementOrView ) ) {\n\t\t\t\tthis._addView( elementOrView );\n\t\t\t} else {\n\t\t\t\tif ( !elementOrView.element ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The {@link module:ui/view~View} added to the {@link module:utils/focustracker~FocusTracker} does not have an\n\t\t\t\t\t * {@link module:ui/view~View#element}. Make sure the view is {@link module:ui/view~View#render} before adding\n\t\t\t\t\t * it to the focus tracker.\n\t\t\t\t\t *\n\t\t\t\t\t * @error focustracker-add-view-missing-element\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'focustracker-add-view-missing-element', {\n\t\t\t\t\t\tfocusTracker: this,\n\t\t\t\t\t\tview: elementOrView\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tthis._addElement( elementOrView.element );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stops tracking focus in the specified DOM element or a {@link module:ui/view~View view instance}. See {@link #add} to learn more.\n\t */\n\tpublic remove( elementOrView: Element | View ): void {\n\t\tif ( isElement( elementOrView ) ) {\n\t\t\tthis._removeElement( elementOrView );\n\t\t} else {\n\t\t\tif ( isViewWithFocusTracker( elementOrView ) ) {\n\t\t\t\tthis._removeView( elementOrView );\n\t\t\t} else {\n\t\t\t\t// Assuming that if the view was successfully added, it must have come with an existing #element.\n\t\t\t\tthis._removeElement( elementOrView.element! );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Adds a DOM element to the focus tracker and starts listening to the `focus` and `blur` events on it.\n\t */\n\tprivate _addElement( element: Element ): void {\n\t\tif ( this._elements.has( element ) ) {\n\t\t\t/**\n\t\t\t * This element is already tracked by {@link module:utils/focustracker~FocusTracker}.\n\t\t\t *\n\t\t\t * @error focustracker-add-element-already-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'focustracker-add-element-already-exist', this );\n\t\t}\n\n\t\tthis.listenTo( element, 'focus', () => {\n\t\t\t// @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": Focus with useCapture on DOM element` );\n\n\t\t\tconst externalFocusedViewInSubtree = this.externalViews.find( view => isExternalViewSubtreeFocused( element, view ) );\n\n\t\t\tif ( externalFocusedViewInSubtree ) {\n\t\t\t\tthis._focus( externalFocusedViewInSubtree.element! );\n\t\t\t} else {\n\t\t\t\tthis._focus( element );\n\t\t\t}\n\t\t}, { useCapture: true } );\n\n\t\tthis.listenTo( element, 'blur', () => {\n\t\t\t// @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": Blur with useCapture on DOM element` );\n\n\t\t\tthis._blur();\n\t\t}, { useCapture: true } );\n\n\t\tthis._elements.add( element );\n\t}\n\n\t/**\n\t * Removes a DOM element from the focus tracker.\n\t */\n\tprivate _removeElement( element: Element ): void {\n\t\tif ( this._elements.has( element ) ) {\n\t\t\tthis.stopListening( element );\n\t\t\tthis._elements.delete( element );\n\t\t}\n\n\t\tif ( element === this.focusedElement ) {\n\t\t\tthis._blur();\n\t\t}\n\t}\n\n\t/**\n\t * Adds an external {@link module:ui/view~View view instance} to this focus tracker and makes it contribute to this focus tracker's\n\t * state either by its `View#element` or by its `View#focusTracker` instance.\n\t */\n\tprivate _addView( view: ViewWithFocusTracker ): void {\n\t\tif ( view.element ) {\n\t\t\tthis._addElement( view.element );\n\t\t}\n\n\t\tthis.listenTo( view.focusTracker, 'change:focusedElement', () => {\n\t\t\t// @if CK_DEBUG_FOCUSTRACKER // console.log(\n\t\t\t// @if CK_DEBUG_FOCUSTRACKER // \t`\"${ getName( this ) }\": Related \"${ getName( view.focusTracker ) }\"#focusedElement = `,\n\t\t\t// @if CK_DEBUG_FOCUSTRACKER // \tview.focusTracker.focusedElement\n\t\t\t// @if CK_DEBUG_FOCUSTRACKER // );\n\n\t\t\tif ( view.focusTracker.focusedElement ) {\n\t\t\t\tif ( view.element ) {\n\t\t\t\t\tthis._focus( view.element );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._blur();\n\t\t\t}\n\t\t} );\n\n\t\tthis._externalViews.add( view );\n\t}\n\n\t/**\n\t * Removes an external {@link module:ui/view~View view instance} from this focus tracker.\n\t */\n\tprivate _removeView( view: ViewWithFocusTracker ): void {\n\t\tif ( view.element ) {\n\t\t\tthis._removeElement( view.element );\n\t\t}\n\n\t\tthis.stopListening( view.focusTracker );\n\t\tthis._externalViews.delete( view );\n\t}\n\n\t/**\n\t * Destroys the focus tracker by:\n\t * - Disabling all event listeners attached to tracked elements or external views.\n\t * - Removing all tracked elements and views that were previously added.\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\n\t\tthis._elements.clear();\n\t\tthis._externalViews.clear();\n\n\t\tthis.isFocused = false;\n\t\tthis.focusedElement = null;\n\t}\n\n\t/**\n\t * Stores currently focused element as {@link #focusedElement} and sets {@link #isFocused} `true`.\n\t */\n\tprivate _focus( element: Element ): void {\n\t\t// @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": _focus() on element`, element );\n\n\t\tthis._clearBlurTimeout();\n\n\t\tthis.focusedElement = element;\n\t\tthis.isFocused = true;\n\t}\n\n\t/**\n\t * Clears currently {@link #focusedElement} and sets {@link #isFocused} `false`.\n\t *\n\t * This method uses `setTimeout()` to change order of `blur` and `focus` events calls, ensuring that moving focus between\n\t * two elements within a single focus tracker's scope, will not cause `[ blurA, focusB ]` sequence but just `[ focusB ]`.\n\t * The former would cause a momentary change of `#isFocused` to `false` which is not desired because any logic listening to\n\t * a focus tracker state would experience UI flashes and glitches as the user focus travels across the UI.\n\t */\n\tprivate _blur(): void {\n\t\tconst isAnyElementFocused = this.elements.find( element => element.contains( document.activeElement ) );\n\n\t\t// Avoid blurs originating from external FTs when the focus still remains in one of the #elements.\n\t\tif ( isAnyElementFocused ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isAnyExternalViewFocused = this.externalViews.find( view => {\n\t\t\t// Do not consider external views's focus trackers as focused if there's a blur timeout pending.\n\t\t\treturn view.focusTracker.isFocused && !view.focusTracker._blurTimeout;\n\t\t} );\n\n\t\t// Avoid unnecessary DOM blurs coming from #elements when the focus still remains in one of #externalViews.\n\t\tif ( isAnyExternalViewFocused ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._clearBlurTimeout();\n\n\t\tthis._blurTimeout = setTimeout( () => {\n\t\t\t// @if CK_DEBUG_FOCUSTRACKER // console.log( `\"${ getName( this ) }\": Blur.` );\n\n\t\t\tthis.focusedElement = null;\n\t\t\tthis.isFocused = false;\n\t\t}, 0 );\n\t}\n\n\t/**\n\t * Clears the asynchronous blur event timeout on demand. See {@link #_blur} to learn more.\n\t */\n\tprivate _clearBlurTimeout(): void {\n\t\tclearTimeout( this._blurTimeout! );\n\t\tthis._blurTimeout = null;\n\t}\n\n\t// @if CK_DEBUG_FOCUSTRACKER // public static _instances: Array<FocusTracker> = [];\n}\n\n/**\n * A {@link module:ui/view~View} instance with a {@link module:utils/focustracker~FocusTracker} instance exposed\n * at the `#focusTracker` property.\n */\nexport type ViewWithFocusTracker = View & { focusTracker: FocusTracker };\n\n/**\n * Checks whether a view is an instance of {@link ~ViewWithFocusTracker}.\n */\nexport function isViewWithFocusTracker( view: any ): view is ViewWithFocusTracker {\n\treturn 'focusTracker' in view && view.focusTracker instanceof FocusTracker;\n}\n\nfunction isElement( value: any ): value is Element {\n\treturn _isElement( value );\n}\n\nfunction isExternalViewSubtreeFocused( subTreeRoot: Element, view: ViewWithFocusTracker ): boolean {\n\tif ( isFocusedView( subTreeRoot, view ) ) {\n\t\treturn true;\n\t}\n\n\treturn !!view.focusTracker.externalViews.find( view => isFocusedView( subTreeRoot, view ) );\n}\n\nfunction isFocusedView( subTreeRoot: Element, view: View ): boolean {\n\t// Note: You cannot depend on externalView.focusTracker.focusedElement because blurs are asynchronous and the value may\n\t// be outdated when moving focus between two elements. Using document.activeElement instead.\n\treturn !!view.element && view.element.contains( document.activeElement ) && subTreeRoot.contains( view.element );\n}\n\n// @if CK_DEBUG_FOCUSTRACKER // declare global {\n// @if CK_DEBUG_FOCUSTRACKER // \tinterface Window {\n// @if CK_DEBUG_FOCUSTRACKER // \t\tlogFocusTrackers: Function;\n// @if CK_DEBUG_FOCUSTRACKER // \t}\n// @if CK_DEBUG_FOCUSTRACKER // }\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // function getName( focusTracker: FocusTracker ): string {\n// @if CK_DEBUG_FOCUSTRACKER // \treturn focusTracker._label || 'Unknown';\n// @if CK_DEBUG_FOCUSTRACKER // }\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // function logState(\n// @if CK_DEBUG_FOCUSTRACKER // \tfocusTracker: FocusTracker,\n// @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog: Array<string> = [ 'isFocused', 'focusedElement' ]\n// @if CK_DEBUG_FOCUSTRACKER // ): string {\n// @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog.forEach( key => { console.log( `${ key }=`, focusTracker[ key ] ) } );\n// @if CK_DEBUG_FOCUSTRACKER // \tconsole.log( 'elements', focusTracker.elements );\n// @if CK_DEBUG_FOCUSTRACKER // \tconsole.log( 'externalViews', focusTracker.externalViews );\n// @if CK_DEBUG_FOCUSTRACKER // }\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // window.logFocusTrackers = (\n// @if CK_DEBUG_FOCUSTRACKER // \tfilter = () => true,\n// @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog: Array<string>\n// @if CK_DEBUG_FOCUSTRACKER // ): void => {\n// @if CK_DEBUG_FOCUSTRACKER // \tconsole.group( 'FocusTrackers' );\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // \tfor ( const focusTracker of FocusTracker._instances ) {\n// @if CK_DEBUG_FOCUSTRACKER // \t\tif ( filter( focusTracker ) ) {\n// @if CK_DEBUG_FOCUSTRACKER // \t\t\tconsole.group( `\"${ getName( focusTracker ) }\"` );\n// @if CK_DEBUG_FOCUSTRACKER // \t\t\tlogState( focusTracker, keysToLog );\n// @if CK_DEBUG_FOCUSTRACKER // \t\t\tconsole.groupEnd();\n// @if CK_DEBUG_FOCUSTRACKER // \t\t}\n// @if CK_DEBUG_FOCUSTRACKER // \t}\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // \tconsole.groupEnd();\n// @if CK_DEBUG_FOCUSTRACKER // };\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // window.logFocusTrackerTree = (\n// @if CK_DEBUG_FOCUSTRACKER // \trootFocusTracker: FocusTracker,\n// @if CK_DEBUG_FOCUSTRACKER // \tfilter = () => true,\n// @if CK_DEBUG_FOCUSTRACKER // \tkeysToLog: Array<string>\n// @if CK_DEBUG_FOCUSTRACKER // ): void => {\n// @if CK_DEBUG_FOCUSTRACKER // \tconsole.group( 'FocusTrackers tree' );\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // \tlogBranch( rootFocusTracker, filter );\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // \tfunction logBranch( focusTracker, filter ) {\n// @if CK_DEBUG_FOCUSTRACKER // \t\tconsole.group( `\"${ getName( focusTracker ) }\"` );\n// @if CK_DEBUG_FOCUSTRACKER // \t\tlogState( focusTracker, keysToLog );\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // \t\tfor ( const externalView of focusTracker.externalViews ) {\n// @if CK_DEBUG_FOCUSTRACKER // \t\t\tif ( filter( externalView.focusTracker ) ) {\n// @if CK_DEBUG_FOCUSTRACKER // \t\t\t\tlogBranch( externalView.focusTracker, filter );\n// @if CK_DEBUG_FOCUSTRACKER // \t\t\t}\n// @if CK_DEBUG_FOCUSTRACKER // \t\t}\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // \t\tconsole.groupEnd();\n// @if CK_DEBUG_FOCUSTRACKER // \t}\n// @if CK_DEBUG_FOCUSTRACKER //\n// @if CK_DEBUG_FOCUSTRACKER // \tconsole.groupEnd();\n// @if CK_DEBUG_FOCUSTRACKER // };\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/keystrokehandler\n */\n\nimport DomEmitterMixin, { type DomEmitter } from './dom/emittermixin.js';\nimport type { Emitter } from './emittermixin.js';\nimport { getCode, parseKeystroke, type KeystrokeInfo } from './keyboard.js';\nimport type { PriorityString } from './priorities.js';\n\n/**\n * Keystroke handler allows registering callbacks for given keystrokes.\n *\n * The most frequent use of this class is through the {@link module:core/editor/editor~Editor#keystrokes `editor.keystrokes`}\n * property. It allows listening to keystrokes executed in the editing view:\n *\n * ```ts\n * editor.keystrokes.set( 'Ctrl+A', ( keyEvtData, cancel ) => {\n * \tconsole.log( 'Ctrl+A has been pressed' );\n * \tcancel();\n * } );\n * ```\n *\n * However, this utility class can be used in various part of the UI. For instance, a certain {@link module:ui/view~View}\n * can use it like this:\n *\n * ```ts\n * class MyView extends View {\n * \tconstructor() {\n * \t\tthis.keystrokes = new KeystrokeHandler();\n *\n * \t\tthis.keystrokes.set( 'tab', handleTabKey );\n * \t}\n *\n * \trender() {\n * \t\tsuper.render();\n *\n * \t\tthis.keystrokes.listenTo( this.element );\n * \t}\n * }\n * ```\n *\n * That keystroke handler will listen to `keydown` events fired in this view's main element.\n *\n */\nexport default class KeystrokeHandler {\n\t/**\n\t * Listener used to listen to events for easier keystroke handler destruction.\n\t */\n\tprivate readonly _listener: DomEmitter;\n\n\t/**\n\t * Creates an instance of the keystroke handler.\n\t */\n\tconstructor() {\n\t\tthis._listener = new ( DomEmitterMixin() )();\n\t}\n\n\t/**\n\t * Starts listening for `keydown` events from a given emitter.\n\t */\n\tpublic listenTo( emitter: Emitter | HTMLElement | Window ): void {\n\t\t// The #_listener works here as a kind of dispatcher. It groups the events coming from the same\n\t\t// keystroke so the listeners can be attached to them with different priorities.\n\t\t//\n\t\t// E.g. all the keystrokes with the `keyCode` of 42 coming from the `emitter` are propagated\n\t\t// as a `_keydown:42` event by the `_listener`. If there's a callback created by the `set`\n\t\t// method for this 42 keystroke, it listens to the `_listener#_keydown:42` event only and interacts\n\t\t// only with other listeners of this particular event, thus making it possible to prioritize\n\t\t// the listeners and safely cancel execution, when needed. Instead of duplicating the Emitter logic,\n\t\t// the KeystrokeHandler re–uses it to do its job.\n\t\tthis._listener.listenTo( emitter as HTMLElement | Window, 'keydown', ( evt, keyEvtData ) => {\n\t\t\tthis._listener.fire( '_keydown:' + getCode( keyEvtData ), keyEvtData );\n\t\t} );\n\t}\n\n\t/**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * @param keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param callback A function called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a helper function to call both `preventDefault()` and `stopPropagation()` on the underlying event.\n\t * @param options Additional options.\n\t */\n\tpublic set(\n\t\tkeystroke: string | ReadonlyArray<string | number>,\n\t\tcallback: ( ev: KeyboardEvent, cancel: () => void ) => void,\n\t\toptions: KeystrokeHandlerOptions = {}\n\t): void {\n\t\tconst keyCode = parseKeystroke( keystroke );\n\t\tconst priority = options.priority;\n\n\t\t// Execute the passed callback on KeystrokeHandler#_keydown.\n\t\t// TODO: https://github.com/ckeditor/ckeditor5-utils/issues/144\n\t\tthis._listener.listenTo( this._listener, '_keydown:' + keyCode, ( evt, keyEvtData: KeyboardEvent ) => {\n\t\t\tif ( options.filter && !options.filter( keyEvtData ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcallback( keyEvtData, () => {\n\t\t\t\t// Stop the event in the DOM: no listener in the web page\n\t\t\t\t// will be triggered by this event.\n\t\t\t\tkeyEvtData.preventDefault();\n\t\t\t\tkeyEvtData.stopPropagation();\n\n\t\t\t\t// Stop the event in the KeystrokeHandler: no more callbacks\n\t\t\t\t// will be executed for this keystroke.\n\t\t\t\tevt.stop();\n\t\t\t} );\n\n\t\t\t// Mark this keystroke as handled by the callback. See: #press.\n\t\t\tevt.return = true;\n\t\t}, { priority } );\n\t}\n\n\t/**\n\t * Triggers a keystroke handler for a specified key combination, if such a keystroke was {@link #set defined}.\n\t *\n\t * @param keyEvtData Key event data.\n\t * @returns Whether the keystroke was handled.\n\t */\n\tpublic press( keyEvtData: Readonly<KeystrokeInfo> ): boolean {\n\t\treturn !!this._listener.fire( '_keydown:' + getCode( keyEvtData ), keyEvtData );\n\t}\n\n\t/**\n\t * Stops listening to `keydown` events from the given emitter.\n\t */\n\tpublic stopListening( emitter?: Emitter | HTMLElement | Window ): void {\n\t\tthis._listener.stopListening( emitter );\n\t}\n\n\t/**\n\t * Destroys the keystroke handler.\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\t}\n}\n\n/**\n * {@link module:utils/keystrokehandler~KeystrokeHandler#set} method options.\n */\nexport interface KeystrokeHandlerOptions {\n\n\t/**\n\t * The priority of the keystroke callback. The higher the priority value the sooner the callback will be executed.\n\t * Keystrokes having the same priority are called in the order they were added.\n\t */\n\treadonly priority?: PriorityString;\n\n\t/**\n\t * An optional callback function allowing for filtering keystrokes based on arbitrary criteria.\n\t * The callback function receives `keydown` DOM event as a parameter.\n\t */\n\treadonly filter?: ( keyEvtData: KeyboardEvent ) => boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/objecttomap\n */\n\n/**\n * Transforms object to map.\n *\n * ```ts\n * const map = objectToMap( { 'foo': 1, 'bar': 2 } );\n * map.get( 'foo' ); // 1\n * ```\n *\n * **Note**: For mixed data (`Object` or `Iterable`) there's a dedicated {@link module:utils/tomap~toMap} function.\n *\n * @param obj Object to transform.\n * @returns Map created from object.\n */\nexport default function objectToMap<T>( obj: { readonly [ key: string ]: T } | null | undefined ): Map<string, T> {\n\tconst map = new Map<string, T>();\n\n\tfor ( const key in obj ) {\n\t\tmap.set( key, obj[ key ] );\n\t}\n\n\treturn map;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/tomap\n */\n\nimport objectToMap from './objecttomap.js';\nimport isIterable from './isiterable.js';\n\n/**\n * Transforms object or iterable to map. Iterable needs to be in the format acceptable by the `Map` constructor.\n *\n * ```ts\n * map = toMap( { 'foo': 1, 'bar': 2 } );\n * map = toMap( [ [ 'foo', 1 ], [ 'bar', 2 ] ] );\n * map = toMap( anotherMap );\n * ```\n *\n * @param data Object or iterable to transform.\n * @returns Map created from data.\n */\nexport default function toMap<T>( data: { readonly [ key: string ]: T } | Iterable<readonly [ string, T ]> | null | undefined ):\n\tMap<string, T>\n{\n\tif ( isIterable( data ) ) {\n\t\treturn new Map( data );\n\t} else {\n\t\treturn objectToMap( data );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/wait\n */\n\n/**\n * Returns a promise that is resolved after the specified time.\n *\n * @param timeout The time in milliseconds to wait.\n * @param options.signal A signal to abort the waiting.\n */\nexport default function wait( timeout: number, options: { signal?: AbortSignal } = {} ): Promise<void> {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tconst signal = options.signal || ( new AbortController() ).signal;\n\n\t\tsignal.throwIfAborted();\n\n\t\tconst timer = setTimeout( timeoutHandler, timeout );\n\n\t\tsignal.addEventListener( 'abort', abortHandler, { once: true } );\n\n\t\tfunction timeoutHandler() {\n\t\t\tsignal.removeEventListener( 'abort', abortHandler );\n\t\t\tresolve();\n\t\t}\n\n\t\tfunction abortHandler() {\n\t\t\tclearTimeout( timer );\n\t\t\treject( signal.reason );\n\t\t}\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/retry\n */\n\nimport wait from './wait.js';\n\n/**\n * Tries calling the given callback until it sucessfully resolves.\n *\n * If the callback fails `maxRetries` times, the returned promise is rejected with the last error.\n *\n * @typeParam TResult The result of a successful callback invocation.\n * @param callback The function to call until it succeeds.\n * @param options.maxRetries Maximum number of retries.\n * @param options.retryDelay The time in milliseconds between attempts. By default it implements exponential back-off policy.\n * @param options.signal The signal to abort further retries. The callback itself is not aborted automatically.\n */\nexport default async function retry<TResult>(\n\tcallback: () => Promise<TResult>,\n\toptions: {\n\t\tmaxAttempts?: number;\n\t\tretryDelay?: ( attempt: number ) => number;\n\t\tsignal?: AbortSignal;\n\t} = {}\n): Promise<TResult> {\n\tconst {\n\t\tmaxAttempts = 4,\n\t\tretryDelay = exponentialDelay(),\n\t\tsignal = ( new AbortController() ).signal\n\t} = options;\n\n\tsignal.throwIfAborted();\n\n\tfor ( let attempt = 0; ; attempt++ ) {\n\t\ttry {\n\t\t\treturn await callback();\n\t\t} catch ( err ) {\n\t\t\tconst isLast = attempt + 1 >= maxAttempts;\n\n\t\t\tif ( isLast ) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\n\t\tawait wait( retryDelay( attempt ), { signal } );\n\t}\n}\n\n/**\n * Creates a function that calculates exponential back-off delay. Pass it as `options.retryDelay` to {@link ~retry}.\n *\n * @param options.delay Base delay between invocations. Defaults to 1s.\n * @param options.factor How much to increase the delay. Defaults to 2x.\n * @param options.maxDelay Maximum timeout. Even if higher timeout is calculated, it cannot get higher than this value. Default to 10s.\n * @returns The function calculating the delay.\n */\nexport function exponentialDelay(\n\toptions: {\n\t\tdelay?: number;\n\t\tfactor?: number;\n\t\tmaxDelay?: number;\n\t} = {}\n): ( attempt: number ) => number {\n\tconst {\n\t\tdelay = 1000,\n\t\tfactor = 2,\n\t\tmaxDelay = 10000\n\t} = options;\n\n\treturn attempt => Math.min( factor ** attempt * delay, maxDelay );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/splicearray\n */\n\nconst BIG_CHUNK_SIZE = 10000;\n\n/**\n * Splices one array into another. To be used instead of `Array.prototype.splice` as the latter may\n * throw \"Maximum call stack size exceeded\" when passed huge number of items to insert.\n *\n * Note: in contrary to Array.splice, this function does not modify the original `target`.\n *\n * ```ts\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 0, 0 );\t// [ 3, 4, 1, 2 ]\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 1 );\t// [ 1, 3, 4 ]\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 1, 0 );\t// [ 1, 3, 4, 2 ]\n * spliceArray( [ 1, 2 ], [ 3, 4 ], 2, 0 );\t// [ 1, 2, 3, 4 ]\n * spliceArray( [ 1, 2 ], [],       0, 1 );\t// [ 2 ]\n * ```\n *\n * @param target Array to be spliced.\n * @param source Array of elements to be inserted to target.\n * @param start Index at which nodes should be inserted/removed.\n * @param count Number of items.\n *\n * @returns New spliced array.\n */\nexport default function spliceArray<T>( target: ReadonlyArray<T>, source: ReadonlyArray<T>, start: number, count: number ): Array<T> {\n\t// In case of performance problems, see: https://github.com/ckeditor/ckeditor5/pull/12429/files#r965850568\n\tif ( Math.max( source.length, target.length ) > BIG_CHUNK_SIZE ) {\n\t\treturn target.slice( 0, start ).concat( source ).concat( target.slice( start + count, target.length ) );\n\t} else {\n\t\tconst newTarget = Array.from( target );\n\t\tnewTarget.splice( start, count, ...source );\n\n\t\treturn newTarget;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/delay\n */\n\n/* globals setTimeout, clearTimeout */\n\n/**\n * Returns a function wrapper that will trigger a function after a specified wait time.\n * The timeout can be canceled by calling the cancel function on the returned wrapped function.\n *\n * @param func The function to wrap.\n * @param wait The timeout in ms.\n */\nexport default function delay<T extends ( ...args: Array<any> ) => any>( func: T, wait: number ): DelayedFunc<T> {\n\tlet timer: ReturnType<typeof setTimeout>;\n\n\tfunction delayed( ...args: Parameters<T> ) {\n\t\tdelayed.cancel();\n\t\ttimer = setTimeout( () => func( ...args ), wait );\n\t}\n\n\tdelayed.cancel = () => {\n\t\tclearTimeout( timer );\n\t};\n\n\treturn delayed;\n}\n\nexport interface DelayedFunc<T extends ( ...args: Array<any> ) => any> {\n\t( ...args: Parameters<T> ): void;\n\tcancel(): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module utils/verifylicense\n */\n\nimport { releaseDate } from './version.js';\n\n/**\n * Possible states of the key after verification.\n */\nexport type VerifiedKeyStatus = 'VALID' | 'INVALID';\n\n/**\n * Checks whether the given string contains information that allows you to verify the license status.\n *\n * @param token The string to check.\n * @returns String that represents the state of given `token` parameter.\n */\nexport default function verifyLicense( token: string | undefined ): VerifiedKeyStatus {\n\t// This function implements naive and partial license key check mechanism,\n\t// used only to decide whether to show or hide the \"Powered by CKEditor\" logo.\n\t//\n\t// You can read the reasoning behind showing the logo to unlicensed (GPL) users\n\t// in this thread: https://github.com/ckeditor/ckeditor5/issues/14082.\n\t//\n\t// We firmly believe in the values behind creating open-source software, even when that\n\t// means keeping the license verification logic open for everyone to see.\n\t//\n\t// Please keep this code intact. Thank you for your understanding.\n\n\tfunction oldTokenCheck( token: string ): VerifiedKeyStatus {\n\t\tif ( token.length >= 40 && token.length <= 255 ) {\n\t\t\treturn 'VALID';\n\t\t} else {\n\t\t\treturn 'INVALID';\n\t\t}\n\t}\n\n\t// TODO: issue ci#3175\n\n\tif ( !token ) {\n\t\treturn 'INVALID';\n\t}\n\n\tlet decryptedData = '';\n\n\ttry {\n\t\tdecryptedData = atob( token );\n\t} catch ( e ) {\n\t\treturn 'INVALID';\n\t}\n\n\tconst splittedDecryptedData = decryptedData.split( '-' );\n\n\tconst firstElement = splittedDecryptedData[ 0 ];\n\tconst secondElement = splittedDecryptedData[ 1 ];\n\n\tif ( !secondElement ) {\n\t\treturn oldTokenCheck( token );\n\t}\n\n\ttry {\n\t\tatob( secondElement );\n\t} catch ( e ) {\n\t\ttry {\n\t\t\tatob( firstElement );\n\n\t\t\tif ( !atob( firstElement ).length ) {\n\t\t\t\treturn oldTokenCheck( token );\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\treturn oldTokenCheck( token );\n\t\t}\n\t}\n\n\tif ( firstElement.length < 40 || firstElement.length > 255 ) {\n\t\treturn 'INVALID';\n\t}\n\n\tlet decryptedSecondElement = '';\n\n\ttry {\n\t\tatob( firstElement );\n\t\tdecryptedSecondElement = atob( secondElement );\n\t} catch ( e ) {\n\t\treturn 'INVALID';\n\t}\n\n\tif ( decryptedSecondElement.length !== 8 ) {\n\t\treturn 'INVALID';\n\t}\n\n\tconst year = Number( decryptedSecondElement.substring( 0, 4 ) );\n\tconst monthIndex = Number( decryptedSecondElement.substring( 4, 6 ) ) - 1;\n\tconst day = Number( decryptedSecondElement.substring( 6, 8 ) );\n\n\tconst date = new Date( year, monthIndex, day );\n\n\tif ( date < releaseDate || isNaN( Number( date ) ) ) {\n\t\treturn 'INVALID';\n\t}\n\n\treturn 'VALID';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * Set of utils to handle unicode characters.\n *\n * @module utils/unicode\n */\n\n/**\n * Checks whether given `character` is a combining mark.\n *\n * @param character Character to check.\n */\nexport function isCombiningMark( character: string ): boolean {\n\t// eslint-disable-next-line no-misleading-character-class\n\treturn !!character && character.length == 1 && /[\\u0300-\\u036f\\u1ab0-\\u1aff\\u1dc0-\\u1dff\\u20d0-\\u20ff\\ufe20-\\ufe2f]/.test( character );\n}\n\n/**\n * Checks whether given `character` is a high half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param character Character to check.\n */\nexport function isHighSurrogateHalf( character: string ): boolean {\n\treturn !!character && character.length == 1 && /[\\ud800-\\udbff]/.test( character );\n}\n\n/**\n * Checks whether given `character` is a low half of surrogate pair.\n *\n * Using UTF-16 terminology, a surrogate pair denotes UTF-16 character using two UTF-8 characters. The surrogate pair\n * consist of high surrogate pair character followed by low surrogate pair character.\n *\n * @param character Character to check.\n */\nexport function isLowSurrogateHalf( character: string ): boolean {\n\treturn !!character && character.length == 1 && /[\\udc00-\\udfff]/.test( character );\n}\n\n/**\n * Checks whether given offset in a string is inside a surrogate pair (between two surrogate halves).\n *\n * @param string String to check.\n * @param offset Offset to check.\n */\nexport function isInsideSurrogatePair( string: string, offset: number ): boolean {\n\treturn isHighSurrogateHalf( string.charAt( offset - 1 ) ) && isLowSurrogateHalf( string.charAt( offset ) );\n}\n\n/**\n * Checks whether given offset in a string is between base character and combining mark or between two combining marks.\n *\n * @param string String to check.\n * @param offset Offset to check.\n */\nexport function isInsideCombinedSymbol( string: string, offset: number ): boolean {\n\treturn isCombiningMark( string.charAt( offset ) );\n}\n\nconst EMOJI_PATTERN = /* #__PURE__ */ buildEmojiRegexp();\n\n/**\n * Checks whether given offset in a string is inside multi-character emoji sequence.\n *\n * @param string String to check.\n * @param offset Offset to check.\n */\nexport function isInsideEmojiSequence( string: string, offset: number ): boolean {\n\tconst matches = String( string ).matchAll( EMOJI_PATTERN );\n\n\treturn Array.from( matches ).some( match => match.index! < offset && offset < match.index! + match[ 0 ].length );\n}\n\nfunction buildEmojiRegexp(): RegExp {\n\tconst parts = [\n\t\t// Emoji Tag Sequence (ETS)\n\t\t/\\p{Emoji}[\\u{E0020}-\\u{E007E}]+\\u{E007F}/u,\n\n\t\t// Emoji Keycap Sequence\n\t\t/\\p{Emoji}\\u{FE0F}?\\u{20E3}/u,\n\n\t\t// Emoji Presentation Sequence\n\t\t/\\p{Emoji}\\u{FE0F}/u,\n\n\t\t// Single-Character Emoji / Emoji Modifier Sequence\n\t\t/(?=\\p{General_Category=Other_Symbol})\\p{Emoji}\\p{Emoji_Modifier}*/u\n\t];\n\n\tconst flagSequence = /\\p{Regional_Indicator}{2}/u.source;\n\tconst emoji = '(?:' + parts.map( part => part.source ).join( '|' ) + ')';\n\tconst sequence = `${ flagSequence }|${ emoji }(?:\\u{200D}${ emoji })*`;\n\n\treturn new RegExp( sequence, 'ug' );\n}\n", "import { logWarning, EmitterMixin, CKEditorError, compareArrays, toArray, toMap, isIterable, ObservableMixin, count, EventInfo, Collection, keyCodes, isText, env, remove as remove$1, insertAt, diff, fastDiff, isNode, isComment, indexOf, global, isValidAttributeName, first, getAncestors, DomEmitterMixin, getCode, isArrowKeyCode, scrollViewportToShowTarget, spliceArray, uid, priorities, isInsideSurrogatePair, isInsideCombinedSymbol, isInsideEmojiSequence } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { clone, isPlainObject, isObject, unset, get, merge, set, extend, debounce, isEqualWith, cloneDeep, isEqual } from 'lodash-es';\n\n// Each document stores information about its placeholder elements and check functions.\nconst documentPlaceholders = new WeakMap();\nlet hasDisplayedPlaceholderDeprecationWarning = false;\n/**\n * A helper that enables a placeholder on the provided view element (also updates its visibility).\n * The placeholder is a CSS pseudo–element (with a text content) attached to the element.\n *\n * To change the placeholder text, change value of the `placeholder` property in the provided `element`.\n *\n * To disable the placeholder, use {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} helper.\n *\n * @param options Configuration options of the placeholder.\n * @param options.view Editing view instance.\n * @param options.element Element that will gain a placeholder. See `options.isDirectHost` to learn more.\n * @param options.isDirectHost If set `false`, the placeholder will not be enabled directly\n * in the passed `element` but in one of its children (selected automatically, i.e. a first empty child element).\n * Useful when attaching placeholders to elements that can host other elements (not just text), for instance,\n * editable root elements.\n * @param options.text Placeholder text. It's **deprecated** and will be removed soon. Use\n * {@link module:engine/view/placeholder~PlaceholderableElement#placeholder `options.element.placeholder`} instead.\n * @param options.keepOnFocus If set `true`, the placeholder stay visible when the host element is focused.\n */ function enablePlaceholder({ view, element, text, isDirectHost = true, keepOnFocus = false }) {\n    const doc = view.document;\n    // Use a single a single post fixer per—document to update all placeholders.\n    if (!documentPlaceholders.has(doc)) {\n        documentPlaceholders.set(doc, new Map());\n        // If a post-fixer callback makes a change, it should return `true` so other post–fixers\n        // can re–evaluate the document again.\n        doc.registerPostFixer((writer)=>updateDocumentPlaceholders(doc, writer));\n        // Update placeholders on isComposing state change since rendering is disabled while in composition mode.\n        doc.on('change:isComposing', ()=>{\n            view.change((writer)=>updateDocumentPlaceholders(doc, writer));\n        }, {\n            priority: 'high'\n        });\n    }\n    if (element.is('editableElement')) {\n        element.on('change:placeholder', (evtInfo, evt, text)=>{\n            setPlaceholder(text);\n        });\n    }\n    if (element.placeholder) {\n        setPlaceholder(element.placeholder);\n    } else if (text) {\n        setPlaceholder(text);\n    }\n    if (text) {\n        showPlaceholderTextDeprecationWarning();\n    }\n    function setPlaceholder(text) {\n        // Store information about the element placeholder under its document.\n        documentPlaceholders.get(doc).set(element, {\n            text,\n            isDirectHost,\n            keepOnFocus,\n            hostElement: isDirectHost ? element : null\n        });\n        // Update the placeholders right away.\n        view.change((writer)=>updateDocumentPlaceholders(doc, writer));\n    }\n}\n/**\n * Disables the placeholder functionality from a given element.\n *\n * See {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} to learn more.\n */ function disablePlaceholder(view, element) {\n    const doc = element.document;\n    if (!documentPlaceholders.has(doc)) {\n        return;\n    }\n    view.change((writer)=>{\n        const placeholders = documentPlaceholders.get(doc);\n        const config = placeholders.get(element);\n        writer.removeAttribute('data-placeholder', config.hostElement);\n        hidePlaceholder(writer, config.hostElement);\n        placeholders.delete(element);\n    });\n}\n/**\n * Shows a placeholder in the provided element by changing related attributes and CSS classes.\n *\n * **Note**: This helper will not update the placeholder visibility nor manage the\n * it in any way in the future. What it does is a one–time state change of an element. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} and\n * {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} for full\n * placeholder functionality.\n *\n * **Note**: This helper will blindly show the placeholder directly in the root editable element if\n * one is passed, which could result in a visual clash if the editable element has some children\n * (for instance, an empty paragraph). Use {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`}\n * in that case or make sure the correct element is passed to the helper.\n *\n * @returns `true`, if any changes were made to the `element`.\n */ function showPlaceholder(writer, element) {\n    if (!element.hasClass('ck-placeholder')) {\n        writer.addClass('ck-placeholder', element);\n        return true;\n    }\n    return false;\n}\n/**\n * Hides a placeholder in the element by changing related attributes and CSS classes.\n *\n * **Note**: This helper will not update the placeholder visibility nor manage the\n * it in any way in the future. What it does is a one–time state change of an element. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} and\n * {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} for full\n * placeholder functionality.\n *\n * @returns `true`, if any changes were made to the `element`.\n */ function hidePlaceholder(writer, element) {\n    if (element.hasClass('ck-placeholder')) {\n        writer.removeClass('ck-placeholder', element);\n        return true;\n    }\n    return false;\n}\n/**\n * Checks if a placeholder should be displayed in the element.\n *\n * **Note**: This helper will blindly check the possibility of showing a placeholder directly in the\n * root editable element if one is passed, which may not be the expected result. If an element can\n * host other elements (not just text), most likely one of its children should be checked instead\n * because it will be the final host for the placeholder. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} in that case or make\n * sure the correct element is passed to the helper.\n *\n * @param element Element that holds the placeholder.\n * @param keepOnFocus Focusing the element will keep the placeholder visible.\n */ function needsPlaceholder(element, keepOnFocus) {\n    if (!element.isAttached()) {\n        return false;\n    }\n    // Anything but uiElement(s) counts as content.\n    const hasContent = Array.from(element.getChildren()).some((element)=>!element.is('uiElement'));\n    if (hasContent) {\n        return false;\n    }\n    const doc = element.document;\n    const viewSelection = doc.selection;\n    const selectionAnchor = viewSelection.anchor;\n    if (doc.isComposing && selectionAnchor && selectionAnchor.parent === element) {\n        return false;\n    }\n    // Skip the focus check and make the placeholder visible already regardless of document focus state.\n    if (keepOnFocus) {\n        return true;\n    }\n    // If the document is blurred.\n    if (!doc.isFocused) {\n        return true;\n    }\n    // If document is focused and the element is empty but the selection is not anchored inside it.\n    return !!selectionAnchor && selectionAnchor.parent !== element;\n}\n/**\n * Updates all placeholders associated with a document in a post–fixer callback.\n *\n * @returns True if any changes were made to the view document.\n */ function updateDocumentPlaceholders(doc, writer) {\n    const placeholders = documentPlaceholders.get(doc);\n    const directHostElements = [];\n    let wasViewModified = false;\n    // First set placeholders on the direct hosts.\n    for (const [element, config] of placeholders){\n        if (config.isDirectHost) {\n            directHostElements.push(element);\n            if (updatePlaceholder(writer, element, config)) {\n                wasViewModified = true;\n            }\n        }\n    }\n    // Then set placeholders on the indirect hosts but only on those that does not already have an direct host placeholder.\n    for (const [element, config] of placeholders){\n        if (config.isDirectHost) {\n            continue;\n        }\n        const hostElement = getChildPlaceholderHostSubstitute(element);\n        // When not a direct host, it could happen that there is no child element\n        // capable of displaying a placeholder.\n        if (!hostElement) {\n            continue;\n        }\n        // Don't override placeholder if the host element already has some direct placeholder.\n        if (directHostElements.includes(hostElement)) {\n            continue;\n        }\n        // Update the host element (used for setting and removing the placeholder).\n        config.hostElement = hostElement;\n        if (updatePlaceholder(writer, element, config)) {\n            wasViewModified = true;\n        }\n    }\n    return wasViewModified;\n}\n/**\n * Updates a single placeholder in a post–fixer callback.\n *\n * @returns True if any changes were made to the view document.\n */ function updatePlaceholder(writer, element, config) {\n    const { text, isDirectHost, hostElement } = config;\n    let wasViewModified = false;\n    // This may be necessary when updating the placeholder text to something else.\n    if (hostElement.getAttribute('data-placeholder') !== text) {\n        writer.setAttribute('data-placeholder', text, hostElement);\n        wasViewModified = true;\n    }\n    // If the host element is not a direct host then placeholder is needed only when there is only one element.\n    const isOnlyChild = isDirectHost || element.childCount == 1;\n    if (isOnlyChild && needsPlaceholder(hostElement, config.keepOnFocus)) {\n        if (showPlaceholder(writer, hostElement)) {\n            wasViewModified = true;\n        }\n    } else if (hidePlaceholder(writer, hostElement)) {\n        wasViewModified = true;\n    }\n    return wasViewModified;\n}\n/**\n * Gets a child element capable of displaying a placeholder if a parent element can host more\n * than just text (for instance, when it is a root editable element). The child element\n * can then be used in other placeholder helpers as a substitute of its parent.\n */ function getChildPlaceholderHostSubstitute(parent) {\n    if (parent.childCount) {\n        const firstChild = parent.getChild(0);\n        if (firstChild.is('element') && !firstChild.is('uiElement') && !firstChild.is('attributeElement')) {\n            return firstChild;\n        }\n    }\n    return null;\n}\n/**\n * Displays a deprecation warning message in the console, but only once per page load.\n */ function showPlaceholderTextDeprecationWarning() {\n    if (!hasDisplayedPlaceholderDeprecationWarning) {\n        /**\n\t\t * The \"text\" option in the {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`}\n\t\t * function is deprecated and will be removed soon.\n\t\t *\n\t\t * See the {@glink updating/guides/update-to-39#view-element-placeholder Migration to v39} guide for\n\t\t * more information on how to apply this change.\n\t\t *\n\t\t * @error enableplaceholder-deprecated-text-option\n\t\t */ logWarning('enableplaceholder-deprecated-text-option');\n    }\n    hasDisplayedPlaceholderDeprecationWarning = true;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module engine/view/typecheckable\n */ let TypeCheckable$1 = class TypeCheckable {\n    /* istanbul ignore next -- @preserve */ is() {\n        // There are a lot of overloads above.\n        // Overriding method in derived classes remove them and only `is( type: string ): boolean` is visible which we don't want.\n        // One option would be to copy them all to all classes, but that's ugly.\n        // It's best when TypeScript compiler doesn't see those overloads, except the one in the top base class.\n        // To overload a method, but not let the compiler see it, do after class definition:\n        // `MyClass.prototype.is = function( type: string ) {...}`\n        throw new Error('is() method is abstract');\n    }\n};\n\n/**\n * Abstract view node class.\n *\n * This is an abstract class. Its constructor should not be used directly.\n * Use the {@link module:engine/view/downcastwriter~DowncastWriter} or {@link module:engine/view/upcastwriter~UpcastWriter}\n * to create new instances of view nodes.\n */ let Node$2 = class Node extends /* #__PURE__ */ EmitterMixin(TypeCheckable$1) {\n    /**\n\t * The document instance to which this node belongs.\n\t */ document;\n    /**\n\t * Parent element. Null by default. Set by {@link module:engine/view/element~Element#_insertChild}.\n\t */ parent;\n    /**\n\t * Creates a tree view node.\n\t *\n\t * @param document The document instance to which this node belongs.\n\t */ constructor(document){\n        super();\n        this.document = document;\n        this.parent = null;\n    }\n    /**\n\t * Index of the node in the parent element or null if the node has no parent.\n\t *\n\t * Accessing this property throws an error if this node's parent element does not contain it.\n\t * This means that view tree got broken.\n\t */ get index() {\n        let pos;\n        if (!this.parent) {\n            return null;\n        }\n        // No parent or child doesn't exist in parent's children.\n        if ((pos = this.parent.getChildIndex(this)) == -1) {\n            /**\n\t\t\t * The node's parent does not contain this node. It means that the document tree is corrupted.\n\t\t\t *\n\t\t\t * @error view-node-not-found-in-parent\n\t\t\t */ throw new CKEditorError('view-node-not-found-in-parent', this);\n        }\n        return pos;\n    }\n    /**\n\t * Node's next sibling, or `null` if it is the last child.\n\t */ get nextSibling() {\n        const index = this.index;\n        return index !== null && this.parent.getChild(index + 1) || null;\n    }\n    /**\n\t * Node's previous sibling, or `null` if it is the first child.\n\t */ get previousSibling() {\n        const index = this.index;\n        return index !== null && this.parent.getChild(index - 1) || null;\n    }\n    /**\n\t * Top-most ancestor of the node. If the node has no parent it is the root itself.\n\t */ get root() {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n        let root = this;\n        while(root.parent){\n            root = root.parent;\n        }\n        return root;\n    }\n    /**\n\t * Returns true if the node is in a tree rooted in the document (is a descendant of one of its roots).\n\t */ isAttached() {\n        return this.root.is('rootElement');\n    }\n    /**\n\t * Gets a path to the node. The path is an array containing indices of consecutive ancestors of this node,\n\t * beginning from {@link module:engine/view/node~Node#root root}, down to this node's index.\n\t *\n\t * ```ts\n\t * const abc = downcastWriter.createText( 'abc' );\n\t * const foo = downcastWriter.createText( 'foo' );\n\t * const h1 = downcastWriter.createElement( 'h1', null, downcastWriter.createText( 'header' ) );\n\t * const p = downcastWriter.createElement( 'p', null, [ abc, foo ] );\n\t * const div = downcastWriter.createElement( 'div', null, [ h1, p ] );\n\t * foo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t * h1.getPath(); // Returns [ 0 ].\n\t * div.getPath(); // Returns [].\n\t * ```\n\t *\n\t * @returns The path.\n\t */ getPath() {\n        const path = [];\n        // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n        let node = this;\n        while(node.parent){\n            path.unshift(node.index);\n            node = node.parent;\n        }\n        return path;\n    }\n    /**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this node will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from node's parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */ getAncestors(options = {}) {\n        const ancestors = [];\n        let parent = options.includeSelf ? this : this.parent;\n        while(parent){\n            ancestors[options.parentFirst ? 'push' : 'unshift'](parent);\n            parent = parent.parent;\n        }\n        return ancestors;\n    }\n    /**\n\t * Returns a {@link module:engine/view/element~Element} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param node The second node.\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` both nodes will be considered \"ancestors\" too.\n\t * Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t */ getCommonAncestor(node, options = {}) {\n        const ancestorsA = this.getAncestors(options);\n        const ancestorsB = node.getAncestors(options);\n        let i = 0;\n        while(ancestorsA[i] == ancestorsB[i] && ancestorsA[i]){\n            i++;\n        }\n        return i === 0 ? null : ancestorsA[i - 1];\n    }\n    /**\n\t * Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/view/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */ isBefore(node) {\n        // Given node is not before this node if they are same.\n        if (this == node) {\n            return false;\n        }\n        // Return `false` if it is impossible to compare nodes.\n        if (this.root !== node.root) {\n            return false;\n        }\n        const thisPath = this.getPath();\n        const nodePath = node.getPath();\n        const result = compareArrays(thisPath, nodePath);\n        switch(result){\n            case 'prefix':\n                return true;\n            case 'extension':\n                return false;\n            default:\n                return thisPath[result] < nodePath[result];\n        }\n    }\n    /**\n\t * Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/view/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */ isAfter(node) {\n        // Given node is not before this node if they are same.\n        if (this == node) {\n            return false;\n        }\n        // Return `false` if it is impossible to compare nodes.\n        if (this.root !== node.root) {\n            return false;\n        }\n        // In other cases, just check if the `node` is before, and return the opposite.\n        return !this.isBefore(node);\n    }\n    /**\n\t * Removes node from parent.\n\t *\n\t * @internal\n\t */ _remove() {\n        this.parent._removeChildren(this.index);\n    }\n    /**\n\t * @internal\n\t * @param type Type of the change.\n\t * @param node Changed node.\n\t * @fires change\n\t */ _fireChange(type, node) {\n        this.fire(`change:${type}`, node);\n        if (this.parent) {\n            this.parent._fireChange(type, node);\n        }\n    }\n    /**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns Clone of this object with the parent property removed.\n\t */ toJSON() {\n        const json = clone(this);\n        // Due to circular references we need to remove parent reference.\n        delete json.parent;\n        return json;\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nNode$2.prototype.is = function(type) {\n    return type === 'node' || type === 'view:node';\n};\n\n/**\n * Tree view text node.\n *\n * The constructor of this class should not be used directly. To create a new text node instance\n * use the {@link module:engine/view/downcastwriter~DowncastWriter#createText `DowncastWriter#createText()`}\n * method when working on data downcasted from the model or the\n * {@link module:engine/view/upcastwriter~UpcastWriter#createText `UpcastWriter#createText()`}\n * method when working on non-semantic views.\n */ let Text$1 = class Text extends Node$2 {\n    /**\n\t * The text content.\n\t *\n\t * Setting the data fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t */ _textData;\n    /**\n\t * Creates a tree view text node.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createText\n\t * @internal\n\t * @param document The document instance to which this text node belongs.\n\t * @param data The text's data.\n\t */ constructor(document, data){\n        super(document);\n        this._textData = data;\n    }\n    /**\n\t * The text content.\n\t */ get data() {\n        return this._textData;\n    }\n    /**\n\t * The `_data` property is controlled by a getter and a setter.\n\t *\n\t * The getter is required when using the addition assignment operator on protected property:\n\t *\n\t * ```ts\n\t * const foo = downcastWriter.createText( 'foo' );\n\t * const bar = downcastWriter.createText( 'bar' );\n\t *\n\t * foo._data += bar.data;   // executes: `foo._data = foo._data + bar.data`\n\t * console.log( foo.data ); // prints: 'foobar'\n\t * ```\n\t *\n\t * If the protected getter didn't exist, `foo._data` will return `undefined` and result of the merge will be invalid.\n\t *\n\t * The setter sets data and fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t *\n\t * @internal\n\t */ get _data() {\n        return this.data;\n    }\n    set _data(data) {\n        this._fireChange('text', this);\n        this._textData = data;\n    }\n    /**\n\t * Checks if this text node is similar to other text node.\n\t * Both nodes should have the same data to be considered as similar.\n\t *\n\t * @param otherNode Node to check if it is same as this node.\n\t */ isSimilar(otherNode) {\n        if (!(otherNode instanceof Text)) {\n            return false;\n        }\n        return this === otherNode || this.data === otherNode.data;\n    }\n    /**\n\t * Clones this node.\n\t *\n\t * @internal\n\t * @returns Text node that is a clone of this node.\n\t */ _clone() {\n        return new Text(this.document, this.data);\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nText$1.prototype.is = function(type) {\n    return type === '$text' || type === 'view:$text' || // This are legacy values kept for backward compatibility.\n    type === 'text' || type === 'view:text' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n    type === 'node' || type === 'view:node';\n};\n\n/**\n * TextProxy is a wrapper for substring of {@link module:engine/view/text~Text}. Instance of this class is created by\n * {@link module:engine/view/treewalker~TreeWalker} when only a part of {@link module:engine/view/text~Text} needs to be returned.\n *\n * `TextProxy` has an API similar to {@link module:engine/view/text~Text Text} and allows to do most of the common tasks performed\n * on view nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/view/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is a readonly interface.\n *\n * **Note:** `TextProxy` instances are created on the fly basing on the current state of parent {@link module:engine/view/text~Text}.\n * Because of this it is highly unrecommended to store references to `TextProxy instances because they might get\n * invalidated due to operations on Document. Also TextProxy is not a {@link module:engine/view/node~Node} so it can not be\n * inserted as a child of {@link module:engine/view/element~Element}.\n *\n * `TextProxy` instances are created by {@link module:engine/view/treewalker~TreeWalker view tree walker}. You should not need to create\n * an instance of this class by your own.\n */ let TextProxy$1 = class TextProxy extends TypeCheckable$1 {\n    /**\n\t * Reference to the {@link module:engine/view/text~Text} element which TextProxy is a substring.\n\t */ textNode;\n    /**\n\t * Text data represented by this text proxy.\n\t */ data;\n    /**\n\t * Offset in the `textNode` where this `TextProxy` instance starts.\n\t */ offsetInText;\n    /**\n\t * Creates a text proxy.\n\t *\n\t * @internal\n\t * @param textNode Text node which part is represented by this text proxy.\n\t * @param offsetInText Offset in {@link module:engine/view/textproxy~TextProxy#textNode text node}\n\t * from which the text proxy starts.\n\t * @param length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t * @constructor\n\t */ constructor(textNode, offsetInText, length){\n        super();\n        this.textNode = textNode;\n        if (offsetInText < 0 || offsetInText > textNode.data.length) {\n            /**\n\t\t\t * Given offsetInText value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-offsetintext\n\t\t\t */ throw new CKEditorError('view-textproxy-wrong-offsetintext', this);\n        }\n        if (length < 0 || offsetInText + length > textNode.data.length) {\n            /**\n\t\t\t * Given length value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-length\n\t\t\t */ throw new CKEditorError('view-textproxy-wrong-length', this);\n        }\n        this.data = textNode.data.substring(offsetInText, offsetInText + length);\n        this.offsetInText = offsetInText;\n    }\n    /**\n\t * Offset size of this node.\n\t */ get offsetSize() {\n        return this.data.length;\n    }\n    /**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/view/text~Text text node}\n\t * (`true`) or the whole text node (`false`).\n\t *\n\t * This is `false` when text proxy starts at the very beginning of {@link module:engine/view/textproxy~TextProxy#textNode textNode}\n\t * ({@link module:engine/view/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t */ get isPartial() {\n        return this.data.length !== this.textNode.data.length;\n    }\n    /**\n\t * Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t */ get parent() {\n        return this.textNode.parent;\n    }\n    /**\n\t * Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t */ get root() {\n        return this.textNode.root;\n    }\n    /**\n\t * {@link module:engine/view/document~Document View document} that owns this text proxy, or `null` if the text proxy is inside\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t */ get document() {\n        return this.textNode.document;\n    }\n    /**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true`, textNode will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from text proxy parent to\n\t * root element, otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */ getAncestors(options = {}) {\n        const ancestors = [];\n        let parent = options.includeSelf ? this.textNode : this.parent;\n        while(parent !== null){\n            ancestors[options.parentFirst ? 'push' : 'unshift'](parent);\n            parent = parent.parent;\n        }\n        return ancestors;\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nTextProxy$1.prototype.is = function(type) {\n    return type === '$textProxy' || type === 'view:$textProxy' || // This are legacy values kept for backward compatibility.\n    type === 'textProxy' || type === 'view:textProxy';\n};\n\n/**\n * View matcher class.\n * Instance of this class can be used to find {@link module:engine/view/element~Element elements} that match given pattern.\n */ class Matcher {\n    _patterns = [];\n    /**\n\t * Creates new instance of Matcher.\n\t *\n\t * @param pattern Match patterns. See {@link module:engine/view/matcher~Matcher#add add method} for more information.\n\t */ constructor(...pattern){\n        this.add(...pattern);\n    }\n    /**\n\t * Adds pattern or patterns to matcher instance.\n\t *\n\t * ```ts\n\t * // String.\n\t * matcher.add( 'div' );\n\t *\n\t * // Regular expression.\n\t * matcher.add( /^\\w/ );\n\t *\n\t * // Single class.\n\t * matcher.add( {\n\t * \tclasses: 'foobar'\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/view/matcher~MatcherPattern} for more examples.\n\t *\n\t * Multiple patterns can be added in one call:\n\t *\n\t * ```ts\n\t * matcher.add( 'div', { classes: 'foobar' } );\n\t * ```\n\t *\n\t * @param pattern Object describing pattern details. If string or regular expression\n\t * is provided it will be used to match element's name. Pattern can be also provided in a form\n\t * of a function - then this function will be called with each {@link module:engine/view/element~Element element} as a parameter.\n\t * Function's return value will be stored under `match` key of the object returned from\n\t * {@link module:engine/view/matcher~Matcher#match match} or {@link module:engine/view/matcher~Matcher#matchAll matchAll} methods.\n\t */ add(...pattern) {\n        for (let item of pattern){\n            // String or RegExp pattern is used as element's name.\n            if (typeof item == 'string' || item instanceof RegExp) {\n                item = {\n                    name: item\n                };\n            }\n            this._patterns.push(item);\n        }\n    }\n    /**\n\t * Matches elements for currently stored patterns. Returns match information about first found\n\t * {@link module:engine/view/element~Element element}, otherwise returns `null`.\n\t *\n\t * Example of returned object:\n\t *\n\t * ```ts\n\t * {\n\t * \telement: <instance of found element>,\n\t * \tpattern: <pattern used to match found element>,\n\t * \tmatch: {\n\t * \t\tname: true,\n\t * \t\tattributes: [ 'title', 'href' ],\n\t * \t\tclasses: [ 'foo' ],\n\t * \t\tstyles: [ 'color', 'position' ]\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * @see module:engine/view/matcher~Matcher#add\n\t * @see module:engine/view/matcher~Matcher#matchAll\n\t * @param element View element to match against stored patterns.\n\t */ match(...element) {\n        for (const singleElement of element){\n            for (const pattern of this._patterns){\n                const match = isElementMatching(singleElement, pattern);\n                if (match) {\n                    return {\n                        element: singleElement,\n                        pattern,\n                        match\n                    };\n                }\n            }\n        }\n        return null;\n    }\n    /**\n\t * Matches elements for currently stored patterns. Returns array of match information with all found\n\t * {@link module:engine/view/element~Element elements}. If no element is found - returns `null`.\n\t *\n\t * @see module:engine/view/matcher~Matcher#add\n\t * @see module:engine/view/matcher~Matcher#match\n\t * @param element View element to match against stored patterns.\n\t * @returns Array with match information about found elements or `null`. For more information\n\t * see {@link module:engine/view/matcher~Matcher#match match method} description.\n\t */ matchAll(...element) {\n        const results = [];\n        for (const singleElement of element){\n            for (const pattern of this._patterns){\n                const match = isElementMatching(singleElement, pattern);\n                if (match) {\n                    results.push({\n                        element: singleElement,\n                        pattern,\n                        match\n                    });\n                }\n            }\n        }\n        return results.length > 0 ? results : null;\n    }\n    /**\n\t * Returns the name of the element to match if there is exactly one pattern added to the matcher instance\n\t * and it matches element name defined by `string` (not `RegExp`). Otherwise, returns `null`.\n\t *\n\t * @returns Element name trying to match.\n\t */ getElementName() {\n        if (this._patterns.length !== 1) {\n            return null;\n        }\n        const pattern = this._patterns[0];\n        const name = pattern.name;\n        return typeof pattern != 'function' && name && !(name instanceof RegExp) ? name : null;\n    }\n}\n/**\n * Returns match information if {@link module:engine/view/element~Element element} is matching provided pattern.\n * If element cannot be matched to provided pattern - returns `null`.\n *\n * @returns Returns object with match information or null if element is not matching.\n */ function isElementMatching(element, pattern) {\n    // If pattern is provided as function - return result of that function;\n    if (typeof pattern == 'function') {\n        return pattern(element);\n    }\n    const match = {};\n    // Check element's name.\n    if (pattern.name) {\n        match.name = matchName(pattern.name, element.name);\n        if (!match.name) {\n            return null;\n        }\n    }\n    // Check element's attributes.\n    if (pattern.attributes) {\n        match.attributes = matchAttributes(pattern.attributes, element);\n        if (!match.attributes) {\n            return null;\n        }\n    }\n    // Check element's classes.\n    if (pattern.classes) {\n        match.classes = matchClasses(pattern.classes, element);\n        if (!match.classes) {\n            return null;\n        }\n    }\n    // Check element's styles.\n    if (pattern.styles) {\n        match.styles = matchStyles(pattern.styles, element);\n        if (!match.styles) {\n            return null;\n        }\n    }\n    return match;\n}\n/**\n * Checks if name can be matched by provided pattern.\n *\n * @returns Returns `true` if name can be matched, `false` otherwise.\n */ function matchName(pattern, name) {\n    // If pattern is provided as RegExp - test against this regexp.\n    if (pattern instanceof RegExp) {\n        return !!name.match(pattern);\n    }\n    return pattern === name;\n}\n/**\n * Checks if an array of key/value pairs can be matched against provided patterns.\n *\n * Patterns can be provided in a following ways:\n * - a boolean value matches any attribute with any value (or no value):\n *\n * ```ts\n * pattern: true\n * ```\n *\n * - a RegExp expression or object matches any attribute name:\n *\n * ```ts\n * pattern: /h[1-6]/\n * ```\n *\n * - an object matches any attribute that has the same name as the object item's key, where object item's value is:\n * \t- equal to `true`, which matches any attribute value:\n *\n * ```ts\n * pattern: {\n * \trequired: true\n * }\n * ```\n *\n * \t- a string that is equal to attribute value:\n *\n * ```ts\n * pattern: {\n * \trel: 'nofollow'\n * }\n * ```\n *\n * \t- a regular expression that matches attribute value,\n *\n * ```ts\n * pattern: {\n * \tsrc: /^https/\n * }\n * ```\n *\n * - an array with items, where the item is:\n * \t- a string that is equal to attribute value:\n *\n * ```ts\n * pattern: [ 'data-property-1', 'data-property-2' ],\n * ```\n *\n * \t- an object with `key` and `value` property, where `key` is a regular expression matching attribute name and\n * \t\t`value` is either regular expression matching attribute value or a string equal to attribute value:\n *\n * ```ts\n * pattern: [\n * \t{ key: /^data-property-/, value: true },\n * \t// or:\n * \t{ key: /^data-property-/, value: 'foobar' },\n * \t// or:\n * \t{ key: /^data-property-/, value: /^foo/ }\n * ]\n * ```\n *\n * @param patterns Object with information about attributes to match.\n * @param keys Attribute, style or class keys.\n * @param valueGetter A function providing value for a given item key.\n * @returns Returns array with matched attribute names or `null` if no attributes were matched.\n */ function matchPatterns(patterns, keys, valueGetter) {\n    const normalizedPatterns = normalizePatterns(patterns);\n    const normalizedItems = Array.from(keys);\n    const match = [];\n    normalizedPatterns.forEach(([patternKey, patternValue])=>{\n        normalizedItems.forEach((itemKey)=>{\n            if (isKeyMatched(patternKey, itemKey) && isValueMatched(patternValue, itemKey, valueGetter)) {\n                match.push(itemKey);\n            }\n        });\n    });\n    // Return matches only if there are at least as many of them as there are patterns.\n    // The RegExp pattern can match more than one item.\n    if (!normalizedPatterns.length || match.length < normalizedPatterns.length) {\n        return undefined;\n    }\n    return match;\n}\n/**\n * Bring all the possible pattern forms to an array of arrays where first item is a key and second is a value.\n *\n * Examples:\n *\n * Boolean pattern value:\n *\n * ```ts\n * true\n * ```\n *\n * to\n *\n * ```ts\n * [ [ true, true ] ]\n * ```\n *\n * Textual pattern value:\n *\n * ```ts\n * 'attribute-name-or-class-or-style'\n * ```\n *\n * to\n *\n * ```ts\n * [ [ 'attribute-name-or-class-or-style', true ] ]\n * ```\n *\n * Regular expression:\n *\n * ```ts\n * /^data-.*$/\n * ```\n *\n * to\n *\n * ```ts\n * [ [ /^data-.*$/, true ] ]\n * ```\n *\n * Objects (plain or with `key` and `value` specified explicitly):\n *\n * ```ts\n * {\n * \tsrc: /^https:.*$/\n * }\n * ```\n *\n * or\n *\n * ```ts\n * [ {\n * \tkey: 'src',\n * \tvalue: /^https:.*$/\n * } ]\n * ```\n *\n * to:\n *\n * ```ts\n * [ [ 'src', /^https:.*$/ ] ]\n * ```\n *\n * @returns Returns an array of objects or null if provided patterns were not in an expected form.\n */ function normalizePatterns(patterns) {\n    if (Array.isArray(patterns)) {\n        return patterns.map((pattern)=>{\n            if (isPlainObject(pattern)) {\n                if (pattern.key === undefined || pattern.value === undefined) {\n                    // Documented at the end of matcher.js.\n                    logWarning('matcher-pattern-missing-key-or-value', pattern);\n                }\n                return [\n                    pattern.key,\n                    pattern.value\n                ];\n            }\n            // Assume the pattern is either String or RegExp.\n            return [\n                pattern,\n                true\n            ];\n        });\n    }\n    if (isPlainObject(patterns)) {\n        return Object.entries(patterns);\n    }\n    // Other cases (true, string or regexp).\n    return [\n        [\n            patterns,\n            true\n        ]\n    ];\n}\n/**\n * @param patternKey A pattern representing a key we want to match.\n * @param itemKey An actual item key (e.g. `'src'`, `'background-color'`, `'ck-widget'`) we're testing against pattern.\n */ function isKeyMatched(patternKey, itemKey) {\n    return patternKey === true || patternKey === itemKey || patternKey instanceof RegExp && itemKey.match(patternKey);\n}\n/**\n * @param patternValue A pattern representing a value we want to match.\n * @param itemKey An item key, e.g. `background`, `href`, 'rel', etc.\n * @param valueGetter A function used to provide a value for a given `itemKey`.\n */ function isValueMatched(patternValue, itemKey, valueGetter) {\n    if (patternValue === true) {\n        return true;\n    }\n    const itemValue = valueGetter(itemKey);\n    // For now, the reducers are not returning the full tree of properties.\n    // Casting to string preserves the old behavior until the root cause is fixed.\n    // More can be found in https://github.com/ckeditor/ckeditor5/issues/10399.\n    return patternValue === itemValue || patternValue instanceof RegExp && !!String(itemValue).match(patternValue);\n}\n/**\n * Checks if attributes of provided element can be matched against provided patterns.\n *\n * @param patterns Object with information about attributes to match. Each key of the object will be\n * used as attribute name. Value of each key can be a string or regular expression to match against attribute value.\n * @param  element Element which attributes will be tested.\n * @returns Returns array with matched attribute names or `null` if no attributes were matched.\n */ function matchAttributes(patterns, element) {\n    const attributeKeys = new Set(element.getAttributeKeys());\n    // `style` and `class` attribute keys are deprecated. Only allow them in object pattern\n    // for backward compatibility.\n    if (isPlainObject(patterns)) {\n        if (patterns.style !== undefined) {\n            // Documented at the end of matcher.js.\n            logWarning('matcher-pattern-deprecated-attributes-style-key', patterns);\n        }\n        if (patterns.class !== undefined) {\n            // Documented at the end of matcher.js.\n            logWarning('matcher-pattern-deprecated-attributes-class-key', patterns);\n        }\n    } else {\n        attributeKeys.delete('style');\n        attributeKeys.delete('class');\n    }\n    return matchPatterns(patterns, attributeKeys, (key)=>element.getAttribute(key));\n}\n/**\n * Checks if classes of provided element can be matched against provided patterns.\n *\n * @param patterns Array of strings or regular expressions to match against element's classes.\n * @param element Element which classes will be tested.\n * @returns Returns array with matched class names or `null` if no classes were matched.\n */ function matchClasses(patterns, element) {\n    // We don't need `getter` here because patterns for classes are always normalized to `[ className, true ]`.\n    return matchPatterns(patterns, element.getClassNames(), /* istanbul ignore next -- @preserve */ ()=>{});\n}\n/**\n * Checks if styles of provided element can be matched against provided patterns.\n *\n * @param patterns Object with information about styles to match. Each key of the object will be\n * used as style name. Value of each key can be a string or regular expression to match against style value.\n * @param element Element which styles will be tested.\n * @returns Returns array with matched style names or `null` if no styles were matched.\n */ function matchStyles(patterns, element) {\n    return matchPatterns(patterns, element.getStyleNames(true), (key)=>element.getStyle(key));\n}\n /**\n * The key-value matcher pattern is missing key or value. Both must be present.\n * Refer the documentation: {@link module:engine/view/matcher~MatcherPattern}.\n *\n * @param pattern Pattern with missing properties.\n * @error matcher-pattern-missing-key-or-value\n */  /**\n * The key-value matcher pattern for `attributes` option is using deprecated `style` key.\n *\n * Use `styles` matcher pattern option instead:\n *\n * ```ts\n * // Instead of:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2',\n * \t\tstyle: /^border.*$/\n * \t}\n * }\n *\n * // Use:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2'\n * \t},\n * \tstyles: /^border.*$/\n * }\n * ```\n *\n * Refer to the {@glink updating/guides/update-to-29##update-to-ckeditor-5-v2910 Migration to v29.1.0} guide\n * and {@link module:engine/view/matcher~MatcherPattern} documentation.\n *\n * @param pattern Pattern with missing properties.\n * @error matcher-pattern-deprecated-attributes-style-key\n */  /**\n * The key-value matcher pattern for `attributes` option is using deprecated `class` key.\n *\n * Use `classes` matcher pattern option instead:\n *\n * ```ts\n * // Instead of:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2',\n * \t\tclass: 'foobar'\n * \t}\n * }\n *\n * // Use:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2'\n * \t},\n * \tclasses: 'foobar'\n * }\n * ```\n *\n * Refer to the {@glink updating/guides/update-to-29##update-to-ckeditor-5-v2910 Migration to v29.1.0} guide\n * and the {@link module:engine/view/matcher~MatcherPattern} documentation.\n *\n * @param pattern Pattern with missing properties.\n * @error matcher-pattern-deprecated-attributes-class-key\n */\n\n/**\n * Styles map. Allows handling (adding, removing, retrieving) a set of style rules (usually, of an element).\n */ class StylesMap {\n    /**\n\t * Keeps an internal representation of styles map. Normalized styles are kept as object tree to allow unified modification and\n\t * value access model using lodash's get, set, unset, etc methods.\n\t *\n\t * When no style processor rules are defined it acts as simple key-value storage.\n\t */ _styles;\n    /**\n\t * An instance of the {@link module:engine/view/stylesmap~StylesProcessor}.\n\t */ _styleProcessor;\n    /**\n\t * Creates Styles instance.\n\t */ constructor(styleProcessor){\n        this._styles = {};\n        this._styleProcessor = styleProcessor;\n    }\n    /**\n\t * Returns true if style map has no styles set.\n\t */ get isEmpty() {\n        const entries = Object.entries(this._styles);\n        return !entries.length;\n    }\n    /**\n\t * Number of styles defined.\n\t */ get size() {\n        if (this.isEmpty) {\n            return 0;\n        }\n        return this.getStyleNames().length;\n    }\n    /**\n\t * Set styles map to a new value.\n\t *\n\t * ```ts\n\t * styles.setTo( 'border:1px solid blue;margin-top:1px;' );\n\t * ```\n\t */ setTo(inlineStyle) {\n        this.clear();\n        const parsedStyles = parseInlineStyles(inlineStyle);\n        for (const [key, value] of parsedStyles){\n            this._styleProcessor.toNormalizedForm(key, value, this._styles);\n        }\n    }\n    /**\n\t * Checks if a given style is set.\n\t *\n\t * ```ts\n\t * styles.setTo( 'margin-left:1px;' );\n\t *\n\t * styles.has( 'margin-left' );    // -> true\n\t * styles.has( 'padding' );        // -> false\n\t * ```\n\t *\n\t * **Note**: This check supports normalized style names.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * styles.setTo( 'margin:2px;' );\n\t *\n\t * styles.has( 'margin' );         // -> true\n\t * styles.has( 'margin-top' );     // -> true\n\t * styles.has( 'margin-left' );    // -> true\n\t *\n\t * styles.remove( 'margin-top' );\n\t *\n\t * styles.has( 'margin' );         // -> false\n\t * styles.has( 'margin-top' );     // -> false\n\t * styles.has( 'margin-left' );    // -> true\n\t * ```\n\t *\n\t * @param name Style name.\n\t */ has(name) {\n        if (this.isEmpty) {\n            return false;\n        }\n        const styles = this._styleProcessor.getReducedForm(name, this._styles);\n        const propertyDescriptor = styles.find(([property])=>property === name);\n        // Only return a value if it is set;\n        return Array.isArray(propertyDescriptor);\n    }\n    set(nameOrObject, valueOrObject) {\n        if (isObject(nameOrObject)) {\n            for (const [key, value] of Object.entries(nameOrObject)){\n                this._styleProcessor.toNormalizedForm(key, value, this._styles);\n            }\n        } else {\n            this._styleProcessor.toNormalizedForm(nameOrObject, valueOrObject, this._styles);\n        }\n    }\n    /**\n\t * Removes given style.\n\t *\n\t * ```ts\n\t * styles.setTo( 'background:#f00;margin-right:2px;' );\n\t *\n\t * styles.remove( 'background' );\n\t *\n\t * styles.toString();   // -> 'margin-right:2px;'\n\t * ```\n\t *\n\t * ***Note**:* This method uses {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules\n\t * enabled style processor rules} to normalize passed values.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * styles.setTo( 'margin:1px' );\n\t *\n\t * styles.remove( 'margin-top' );\n\t * styles.remove( 'margin-right' );\n\t *\n\t * styles.toString(); // -> 'margin-bottom:1px;margin-left:1px;'\n\t * ```\n\t *\n\t * @param name Style name.\n\t */ remove(name) {\n        const path = toPath(name);\n        unset(this._styles, path);\n        delete this._styles[name];\n        this._cleanEmptyObjectsOnPath(path);\n    }\n    /**\n\t * Returns a normalized style object or a single value.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px 2px 3em;' );\n\t *\n\t * styles.getNormalized( 'margin' );\n\t * // will log:\n\t * // {\n\t * //     top: '1px',\n\t * //     right: '2px',\n\t * //     bottom: '3em',\n\t * //     left: '2px'     // normalized value from margin shorthand\n\t * // }\n\t *\n\t * styles.getNormalized( 'margin-left' ); // -> '2px'\n\t * ```\n\t *\n\t * **Note**: This method will only return normalized styles if a style processor was defined.\n\t *\n\t * @param name Style name.\n\t */ getNormalized(name) {\n        return this._styleProcessor.getNormalized(name, this._styles);\n    }\n    /**\n\t * Returns a normalized style string. Styles are sorted by name.\n\t *\n\t * ```ts\n\t * styles.set( 'margin' , '1px' );\n\t * styles.set( 'background', '#f00' );\n\t *\n\t * styles.toString(); // -> 'background:#f00;margin:1px;'\n\t * ```\n\t *\n\t * **Note**: This method supports normalized styles if defined.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * styles.set( 'margin' , '1px' );\n\t * styles.set( 'background', '#f00' );\n\t * styles.remove( 'margin-top' );\n\t * styles.remove( 'margin-right' );\n\t *\n\t * styles.toString(); // -> 'background:#f00;margin-bottom:1px;margin-left:1px;'\n\t * ```\n\t */ toString() {\n        if (this.isEmpty) {\n            return '';\n        }\n        return this.getStylesEntries().map((arr)=>arr.join(':')).sort().join(';') + ';';\n    }\n    /**\n\t * Returns property as a value string or undefined if property is not set.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t * styles.set( 'margin-bottom', '3em' );\n\t *\n\t * styles.getAsString( 'margin' ); // -> 'margin: 1px 1px 3em;'\n\t * ```\n\t *\n\t * Note, however, that all sub-values must be set for the longhand property name to return a value:\n\t *\n\t * ```ts\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t * styles.remove( 'margin-bottom' );\n\t *\n\t * styles.getAsString( 'margin' ); // -> undefined\n\t * ```\n\t *\n\t * In the above scenario, it is not possible to return a `margin` value, so `undefined` is returned.\n\t * Instead, you should use:\n\t *\n\t * ```ts\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t * styles.remove( 'margin-bottom' );\n\t *\n\t * for ( const styleName of styles.getStyleNames() ) {\n\t * \tconsole.log( styleName, styles.getAsString( styleName ) );\n\t * }\n\t * // 'margin-top', '1px'\n\t * // 'margin-right', '1px'\n\t * // 'margin-left', '1px'\n\t * ```\n\t *\n\t * In general, it is recommend to iterate over style names like in the example above. This way, you will always get all\n\t * the currently set style values. So, if all the 4 margin values would be set\n\t * the for-of loop above would yield only `'margin'`, `'1px'`:\n\t *\n\t * ```ts\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t *\n\t * for ( const styleName of styles.getStyleNames() ) {\n\t * \tconsole.log( styleName, styles.getAsString( styleName ) );\n\t * }\n\t * // 'margin', '1px'\n\t * ```\n\t *\n\t * **Note**: To get a normalized version of a longhand property use the {@link #getNormalized `#getNormalized()`} method.\n\t */ getAsString(propertyName) {\n        if (this.isEmpty) {\n            return;\n        }\n        if (this._styles[propertyName] && !isObject(this._styles[propertyName])) {\n            // Try return styles set directly - values that are not parsed.\n            return this._styles[propertyName];\n        }\n        const styles = this._styleProcessor.getReducedForm(propertyName, this._styles);\n        const propertyDescriptor = styles.find(([property])=>property === propertyName);\n        // Only return a value if it is set;\n        if (Array.isArray(propertyDescriptor)) {\n            return propertyDescriptor[1];\n        }\n    }\n    /**\n\t * Returns all style properties names as they would appear when using {@link #toString `#toString()`}.\n\t *\n\t * When `expand` is set to true and there's a shorthand style property set, it will also return all equivalent styles:\n\t *\n\t * ```ts\n\t * stylesMap.setTo( 'margin: 1em' )\n\t * ```\n\t *\n\t * will be expanded to:\n\t *\n\t * ```ts\n\t * [ 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ]\n\t * ```\n\t *\n\t * @param expand Expand shorthand style properties and all return equivalent style representations.\n\t */ getStyleNames(expand = false) {\n        if (this.isEmpty) {\n            return [];\n        }\n        if (expand) {\n            return this._styleProcessor.getStyleNames(this._styles);\n        }\n        const entries = this.getStylesEntries();\n        return entries.map(([key])=>key);\n    }\n    /**\n\t * Removes all styles.\n\t */ clear() {\n        this._styles = {};\n    }\n    /**\n\t * Returns normalized styles entries for further processing.\n\t */ getStylesEntries() {\n        const parsed = [];\n        const keys = Object.keys(this._styles);\n        for (const key of keys){\n            parsed.push(...this._styleProcessor.getReducedForm(key, this._styles));\n        }\n        return parsed;\n    }\n    /**\n\t * Removes empty objects upon removing an entry from internal object.\n\t */ _cleanEmptyObjectsOnPath(path) {\n        const pathParts = path.split('.');\n        const isChildPath = pathParts.length > 1;\n        if (!isChildPath) {\n            return;\n        }\n        const parentPath = pathParts.splice(0, pathParts.length - 1).join('.');\n        const parentObject = get(this._styles, parentPath);\n        if (!parentObject) {\n            return;\n        }\n        const isParentEmpty = !Object.keys(parentObject).length;\n        if (isParentEmpty) {\n            this.remove(parentPath);\n        }\n    }\n}\n/**\n * Style processor is responsible for writing and reading a normalized styles object.\n */ class StylesProcessor {\n    _normalizers;\n    _extractors;\n    _reducers;\n    _consumables;\n    /**\n\t * Creates StylesProcessor instance.\n\t *\n\t * @internal\n\t */ constructor(){\n        this._normalizers = new Map();\n        this._extractors = new Map();\n        this._reducers = new Map();\n        this._consumables = new Map();\n    }\n    /**\n\t * Parse style string value to a normalized object and appends it to styles object.\n\t *\n\t * ```ts\n\t * const styles = {};\n\t *\n\t * stylesProcessor.toNormalizedForm( 'margin', '1px', styles );\n\t *\n\t * // styles will consist: { margin: { top: '1px', right: '1px', bottom: '1px', left: '1px; } }\n\t * ```\n\t *\n\t * **Note**: To define normalizer callbacks use {@link #setNormalizer}.\n\t *\n\t * @param name Name of style property.\n\t * @param propertyValue Value of style property.\n\t * @param styles Object holding normalized styles.\n\t */ toNormalizedForm(name, propertyValue, styles) {\n        if (isObject(propertyValue)) {\n            appendStyleValue(styles, toPath(name), propertyValue);\n            return;\n        }\n        if (this._normalizers.has(name)) {\n            const normalizer = this._normalizers.get(name);\n            const { path, value } = normalizer(propertyValue);\n            appendStyleValue(styles, path, value);\n        } else {\n            appendStyleValue(styles, name, propertyValue);\n        }\n    }\n    /**\n\t * Returns a normalized version of a style property.\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tmargin: { top: '1px', right: '1px', bottom: '1px', left: '1px; },\n\t * \tbackground: { color: '#f00' }\n\t * };\n\t *\n\t * stylesProcessor.getNormalized( 'background' );\n\t * // will return: { color: '#f00' }\n\t *\n\t * stylesProcessor.getNormalized( 'margin-top' );\n\t * // will return: '1px'\n\t * ```\n\t *\n\t * **Note**: In some cases extracting single value requires defining an extractor callback {@link #setExtractor}.\n\t *\n\t * @param name Name of style property.\n\t * @param styles Object holding normalized styles.\n\t */ getNormalized(name, styles) {\n        if (!name) {\n            return merge({}, styles);\n        }\n        // Might be empty string.\n        if (styles[name] !== undefined) {\n            return styles[name];\n        }\n        if (this._extractors.has(name)) {\n            const extractor = this._extractors.get(name);\n            if (typeof extractor === 'string') {\n                return get(styles, extractor);\n            }\n            const value = extractor(name, styles);\n            if (value) {\n                return value;\n            }\n        }\n        return get(styles, toPath(name));\n    }\n    /**\n\t * Returns a reduced form of style property form normalized object.\n\t *\n\t * For default margin reducer, the below code:\n\t *\n\t * ```ts\n\t * stylesProcessor.getReducedForm( 'margin', {\n\t * \tmargin: { top: '1px', right: '1px', bottom: '2px', left: '1px; }\n\t * } );\n\t * ```\n\t *\n\t * will return:\n\t *\n\t * ```ts\n\t * [\n\t * \t[ 'margin', '1px 1px 2px' ]\n\t * ]\n\t * ```\n\t *\n\t * because it might be represented as a shorthand 'margin' value. However if one of margin long hand values is missing it should return:\n\t *\n\t * ```ts\n\t * [\n\t * \t[ 'margin-top', '1px' ],\n\t * \t[ 'margin-right', '1px' ],\n\t * \t[ 'margin-bottom', '2px' ]\n\t * \t// the 'left' value is missing - cannot use 'margin' shorthand.\n\t * ]\n\t * ```\n\t *\n\t * **Note**: To define reducer callbacks use {@link #setReducer}.\n\t *\n\t * @param name Name of style property.\n\t */ getReducedForm(name, styles) {\n        const normalizedValue = this.getNormalized(name, styles);\n        // Might be empty string.\n        if (normalizedValue === undefined) {\n            return [];\n        }\n        if (this._reducers.has(name)) {\n            const reducer = this._reducers.get(name);\n            return reducer(normalizedValue);\n        }\n        return [\n            [\n                name,\n                normalizedValue\n            ]\n        ];\n    }\n    /**\n\t * Return all style properties. Also expand shorthand properties (e.g. `margin`, `background`) if respective extractor is available.\n\t *\n\t * @param styles Object holding normalized styles.\n\t */ getStyleNames(styles) {\n        const styleNamesKeysSet = new Set();\n        // Find all extractable styles that have a value.\n        for (const name of this._consumables.keys()){\n            const style = this.getNormalized(name, styles);\n            if (style && (typeof style != 'object' || Object.keys(style).length)) {\n                styleNamesKeysSet.add(name);\n            }\n        }\n        // For simple styles (for example `color`) we don't have a map of those styles\n        // but they are 1 to 1 with normalized object keys.\n        for (const name of Object.keys(styles)){\n            styleNamesKeysSet.add(name);\n        }\n        return Array.from(styleNamesKeysSet);\n    }\n    /**\n\t * Returns related style names.\n\t *\n\t * ```ts\n\t * stylesProcessor.getRelatedStyles( 'margin' );\n\t * // will return: [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ];\n\t *\n\t * stylesProcessor.getRelatedStyles( 'margin-top' );\n\t * // will return: [ 'margin' ];\n\t * ```\n\t *\n\t * **Note**: To define new style relations load an existing style processor or use\n\t * {@link module:engine/view/stylesmap~StylesProcessor#setStyleRelation `StylesProcessor.setStyleRelation()`}.\n\t */ getRelatedStyles(name) {\n        return this._consumables.get(name) || [];\n    }\n    /**\n\t * Adds a normalizer method for a style property.\n\t *\n\t * A normalizer returns describing how the value should be normalized.\n\t *\n\t * For instance 'margin' style is a shorthand for four margin values:\n\t *\n\t * - 'margin-top'\n\t * - 'margin-right'\n\t * - 'margin-bottom'\n\t * - 'margin-left'\n\t *\n\t * and can be written in various ways if some values are equal to others. For instance `'margin: 1px 2em;'` is a shorthand for\n\t * `'margin-top: 1px;margin-right: 2em;margin-bottom: 1px;margin-left: 2em'`.\n\t *\n\t * A normalizer should parse various margin notations as a single object:\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tmargin: {\n\t * \t\ttop: '1px',\n\t * \t\tright: '2em',\n\t * \t\tbottom: '1px',\n\t * \t\tleft: '2em'\n\t * \t}\n\t * };\n\t * ```\n\t *\n\t * Thus a normalizer for 'margin' style should return an object defining style path and value to store:\n\t *\n\t * ```ts\n\t * const returnValue = {\n\t * \tpath: 'margin',\n\t * \tvalue: {\n\t * \t\ttop: '1px',\n\t * \t\tright: '2em',\n\t * \t\tbottom: '1px',\n\t * \t\tleft: '2em'\n\t * \t}\n\t * };\n\t * ```\n\t *\n\t * Additionally to fully support all margin notations there should be also defined 4 normalizers for longhand margin notations. Below\n\t * is an example for 'margin-top' style property normalizer:\n\t *\n\t * ```ts\n\t * stylesProcessor.setNormalizer( 'margin-top', valueString => {\n\t * \treturn {\n\t * \t\tpath: 'margin.top',\n\t * \t\tvalue: valueString\n\t * \t}\n\t * } );\n\t * ```\n\t */ setNormalizer(name, callback) {\n        this._normalizers.set(name, callback);\n    }\n    /**\n\t * Adds a extractor callback for a style property.\n\t *\n\t * Most normalized style values are stored as one level objects. It is assumed that `'margin-top'` style will be stored as:\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tmargin: {\n\t * \t\ttop: 'value'\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * However, some styles can have conflicting notations and thus it might be harder to extract a style value from shorthand. For instance\n\t * the 'border-top-style' can be defined using `'border-top:solid'`, `'border-style:solid none none none'` or by `'border:solid'`\n\t * shorthands. The default border styles processors stores styles as:\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tborder: {\n\t * \t\tstyle: {\n\t * \t\t\ttop: 'solid'\n\t * \t\t}\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * as it is better to modify border style independently from other values. On the other part the output of the border might be\n\t * desired as `border-top`, `border-left`, etc notation.\n\t *\n\t * In the above example an extractor should return a side border value that combines style, color and width:\n\t *\n\t * ```ts\n\t * styleProcessor.setExtractor( 'border-top', styles => {\n\t * \treturn {\n\t * \t\tcolor: styles.border.color.top,\n\t * \t\tstyle: styles.border.style.top,\n\t * \t\twidth: styles.border.width.top\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * @param callbackOrPath Callback that return a requested value or path string for single values.\n\t */ setExtractor(name, callbackOrPath) {\n        this._extractors.set(name, callbackOrPath);\n    }\n    /**\n\t * Adds a reducer callback for a style property.\n\t *\n\t * Reducer returns a minimal notation for given style name. For longhand properties it is not required to write a reducer as\n\t * by default the direct value from style path is taken.\n\t *\n\t * For shorthand styles a reducer should return minimal style notation either by returning single name-value tuple or multiple tuples\n\t * if a shorthand cannot be used. For instance for a margin shorthand a reducer might return:\n\t *\n\t * ```ts\n\t * const marginShortHandTuple = [\n\t * \t[ 'margin', '1px 1px 2px' ]\n\t * ];\n\t * ```\n\t *\n\t * or a longhand tuples for defined values:\n\t *\n\t * ```ts\n\t * // Considering margin.bottom and margin.left are undefined.\n\t * const marginLonghandsTuples = [\n\t * \t[ 'margin-top', '1px' ],\n\t * \t[ 'margin-right', '1px' ]\n\t * ];\n\t * ```\n\t *\n\t * A reducer obtains a normalized style value:\n\t *\n\t * ```ts\n\t * // Simplified reducer that always outputs 4 values which are always present:\n\t * stylesProcessor.setReducer( 'margin', margin => {\n\t * \treturn [\n\t * \t\t[ 'margin', `${ margin.top } ${ margin.right } ${ margin.bottom } ${ margin.left }` ]\n\t * \t]\n\t * } );\n\t * ```\n\t */ setReducer(name, callback) {\n        this._reducers.set(name, callback);\n    }\n    /**\n\t * Defines a style shorthand relation to other style notations.\n\t *\n\t * ```ts\n\t * stylesProcessor.setStyleRelation( 'margin', [\n\t * \t'margin-top',\n\t * \t'margin-right',\n\t * \t'margin-bottom',\n\t * \t'margin-left'\n\t * ] );\n\t * ```\n\t *\n\t * This enables expanding of style names for shorthands. For instance, if defined,\n\t * {@link module:engine/conversion/viewconsumable~ViewConsumable view consumable} items are automatically created\n\t * for long-hand margin style notation alongside the `'margin'` item.\n\t *\n\t * This means that when an element being converted has a style `margin`, a converter for `margin-left` will work just\n\t * fine since the view consumable will contain a consumable `margin-left` item (thanks to the relation) and\n\t * `element.getStyle( 'margin-left' )` will work as well assuming that the style processor was correctly configured.\n\t * However, once `margin-left` is consumed, `margin` will not be consumable anymore.\n\t */ setStyleRelation(shorthandName, styleNames) {\n        this._mapStyleNames(shorthandName, styleNames);\n        for (const alsoName of styleNames){\n            this._mapStyleNames(alsoName, [\n                shorthandName\n            ]);\n        }\n    }\n    /**\n\t * Set two-way binding of style names.\n\t */ _mapStyleNames(name, styleNames) {\n        if (!this._consumables.has(name)) {\n            this._consumables.set(name, []);\n        }\n        this._consumables.get(name).push(...styleNames);\n    }\n}\n/**\n * Parses inline styles and puts property - value pairs into styles map.\n *\n * @param stylesString Styles to parse.\n * @returns Map of parsed properties and values.\n */ function parseInlineStyles(stylesString) {\n    // `null` if no quote was found in input string or last found quote was a closing quote. See below.\n    let quoteType = null;\n    let propertyNameStart = 0;\n    let propertyValueStart = 0;\n    let propertyName = null;\n    const stylesMap = new Map();\n    // Do not set anything if input string is empty.\n    if (stylesString === '') {\n        return stylesMap;\n    }\n    // Fix inline styles that do not end with `;` so they are compatible with algorithm below.\n    if (stylesString.charAt(stylesString.length - 1) != ';') {\n        stylesString = stylesString + ';';\n    }\n    // Seek the whole string for \"special characters\".\n    for(let i = 0; i < stylesString.length; i++){\n        const char = stylesString.charAt(i);\n        if (quoteType === null) {\n            // No quote found yet or last found quote was a closing quote.\n            switch(char){\n                case ':':\n                    // Most of time colon means that property name just ended.\n                    // Sometimes however `:` is found inside property value (for example in background image url).\n                    if (!propertyName) {\n                        // Treat this as end of property only if property name is not already saved.\n                        // Save property name.\n                        propertyName = stylesString.substr(propertyNameStart, i - propertyNameStart);\n                        // Save this point as the start of property value.\n                        propertyValueStart = i + 1;\n                    }\n                    break;\n                case '\"':\n                case '\\'':\n                    // Opening quote found (this is an opening quote, because `quoteType` is `null`).\n                    quoteType = char;\n                    break;\n                case ';':\n                    {\n                        // Property value just ended.\n                        // Use previously stored property value start to obtain property value.\n                        const propertyValue = stylesString.substr(propertyValueStart, i - propertyValueStart);\n                        if (propertyName) {\n                            // Save parsed part.\n                            stylesMap.set(propertyName.trim(), propertyValue.trim());\n                        }\n                        propertyName = null;\n                        // Save this point as property name start. Property name starts immediately after previous property value ends.\n                        propertyNameStart = i + 1;\n                        break;\n                    }\n            }\n        } else if (char === quoteType) {\n            // If a quote char is found and it is a closing quote, mark this fact by `null`-ing `quoteType`.\n            quoteType = null;\n        }\n    }\n    return stylesMap;\n}\n/**\n * Return lodash compatible path from style name.\n */ function toPath(name) {\n    return name.replace('-', '.');\n}\n/**\n * Appends style definition to the styles object.\n */ function appendStyleValue(stylesObject, nameOrPath, valueOrObject) {\n    let valueToSet = valueOrObject;\n    if (isObject(valueOrObject)) {\n        valueToSet = merge({}, get(stylesObject, nameOrPath), valueOrObject);\n    }\n    set(stylesObject, nameOrPath, valueToSet);\n}\n\n// @if CK_DEBUG_ENGINE // const { convertMapToTags } = require( '../dev-utils/utils' );\n/**\n * View element.\n *\n * The editing engine does not define a fixed semantics of its elements (it is \"DTD-free\").\n * This is why the type of the {@link module:engine/view/element~Element} need to\n * be defined by the feature developer. When creating an element you should use one of the following methods:\n *\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `downcastWriter#createContainerElement()`}\n * in order to create a {@link module:engine/view/containerelement~ContainerElement},\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `downcastWriter#createAttributeElement()`}\n * in order to create a {@link module:engine/view/attributeelement~AttributeElement},\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`}\n * in order to create a {@link module:engine/view/emptyelement~EmptyElement}.\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}\n * in order to create a {@link module:engine/view/uielement~UIElement}.\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`}\n * in order to create a {@link module:engine/view/editableelement~EditableElement}.\n *\n * Note that for view elements which are not created from the model, like elements from mutations, paste or\n * {@link module:engine/controller/datacontroller~DataController#set data.set} it is not possible to define the type of the element.\n * In such cases the {@link module:engine/view/upcastwriter~UpcastWriter#createElement `UpcastWriter#createElement()`} method\n * should be used to create generic view elements.\n */ let Element$1 = class Element extends Node$2 {\n    /**\n\t * Name of the element.\n\t */ name;\n    /**\n\t * A list of attribute names that should be rendered in the editing pipeline even though filtering mechanisms\n\t * implemented in the {@link module:engine/view/domconverter~DomConverter} (for instance,\n\t * {@link module:engine/view/domconverter~DomConverter#shouldRenderAttribute}) would filter them out.\n\t *\n\t * These attributes can be specified as an option when the element is created by\n\t * the {@link module:engine/view/downcastwriter~DowncastWriter}. To check whether an unsafe an attribute should\n\t * be permitted, use the {@link #shouldRenderUnsafeAttribute} method.\n\t *\n\t * @internal\n\t */ _unsafeAttributesToRender = [];\n    /**\n\t * Map of attributes, where attributes names are keys and attributes values are values.\n\t */ _attrs;\n    /**\n\t * Array of child nodes.\n\t */ _children;\n    /**\n\t * Set of classes associated with element instance.\n\t */ _classes;\n    /**\n\t * Normalized styles.\n\t */ _styles;\n    /**\n\t * Map of custom properties.\n\t * Custom properties can be added to element instance, will be cloned but not rendered into DOM.\n\t */ _customProperties = new Map();\n    /**\n\t * Creates a view element.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t * ```ts\n\t * new Element( viewDocument, 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t * new Element( viewDocument, 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t * new Element( viewDocument, 'div', mapOfAttributes ); // map\n\t * ```\n\t *\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */ constructor(document, name, attrs, children){\n        super(document);\n        this.name = name;\n        this._attrs = parseAttributes(attrs);\n        this._children = [];\n        if (children) {\n            this._insertChild(0, children);\n        }\n        this._classes = new Set();\n        if (this._attrs.has('class')) {\n            // Remove class attribute and handle it by class set.\n            const classString = this._attrs.get('class');\n            parseClasses(this._classes, classString);\n            this._attrs.delete('class');\n        }\n        this._styles = new StylesMap(this.document.stylesProcessor);\n        if (this._attrs.has('style')) {\n            // Remove style attribute and handle it by styles map.\n            this._styles.setTo(this._attrs.get('style'));\n            this._attrs.delete('style');\n        }\n    }\n    /**\n\t * Number of element's children.\n\t */ get childCount() {\n        return this._children.length;\n    }\n    /**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t */ get isEmpty() {\n        return this._children.length === 0;\n    }\n    /**\n\t * Gets child at the given index.\n\t *\n\t * @param index Index of child.\n\t * @returns Child node.\n\t */ getChild(index) {\n        return this._children[index];\n    }\n    /**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param node Child node.\n\t * @returns Index of the child node.\n\t */ getChildIndex(node) {\n        return this._children.indexOf(node);\n    }\n    /**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns Child nodes iterator.\n\t */ getChildren() {\n        return this._children[Symbol.iterator]();\n    }\n    /**\n\t * Returns an iterator that contains the keys for attributes. Order of inserting attributes is not preserved.\n\t *\n\t * @returns Keys for attributes.\n\t */ *getAttributeKeys() {\n        if (this._classes.size > 0) {\n            yield 'class';\n        }\n        if (!this._styles.isEmpty) {\n            yield 'style';\n        }\n        yield* this._attrs.keys();\n    }\n    /**\n\t * Returns iterator that iterates over this element's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */ *getAttributes() {\n        yield* this._attrs.entries();\n        if (this._classes.size > 0) {\n            yield [\n                'class',\n                this.getAttribute('class')\n            ];\n        }\n        if (!this._styles.isEmpty) {\n            yield [\n                'style',\n                this.getAttribute('style')\n            ];\n        }\n    }\n    /**\n\t * Gets attribute by key. If attribute is not present - returns undefined.\n\t *\n\t * @param key Attribute key.\n\t * @returns Attribute value.\n\t */ getAttribute(key) {\n        if (key == 'class') {\n            if (this._classes.size > 0) {\n                return [\n                    ...this._classes\n                ].join(' ');\n            }\n            return undefined;\n        }\n        if (key == 'style') {\n            const inlineStyle = this._styles.toString();\n            return inlineStyle == '' ? undefined : inlineStyle;\n        }\n        return this._attrs.get(key);\n    }\n    /**\n\t * Returns a boolean indicating whether an attribute with the specified key exists in the element.\n\t *\n\t * @param key Attribute key.\n\t * @returns `true` if attribute with the specified key exists in the element, `false` otherwise.\n\t */ hasAttribute(key) {\n        if (key == 'class') {\n            return this._classes.size > 0;\n        }\n        if (key == 'style') {\n            return !this._styles.isEmpty;\n        }\n        return this._attrs.has(key);\n    }\n    /**\n\t * Checks if this element is similar to other element.\n\t * Both elements should have the same name and attributes to be considered as similar. Two similar elements\n\t * can contain different set of children nodes.\n\t */ isSimilar(otherElement) {\n        if (!(otherElement instanceof Element)) {\n            return false;\n        }\n        // If exactly the same Element is provided - return true immediately.\n        if (this === otherElement) {\n            return true;\n        }\n        // Check element name.\n        if (this.name != otherElement.name) {\n            return false;\n        }\n        // Check number of attributes, classes and styles.\n        if (this._attrs.size !== otherElement._attrs.size || this._classes.size !== otherElement._classes.size || this._styles.size !== otherElement._styles.size) {\n            return false;\n        }\n        // Check if attributes are the same.\n        for (const [key, value] of this._attrs){\n            if (!otherElement._attrs.has(key) || otherElement._attrs.get(key) !== value) {\n                return false;\n            }\n        }\n        // Check if classes are the same.\n        for (const className of this._classes){\n            if (!otherElement._classes.has(className)) {\n                return false;\n            }\n        }\n        // Check if styles are the same.\n        for (const property of this._styles.getStyleNames()){\n            if (!otherElement._styles.has(property) || otherElement._styles.getAsString(property) !== this._styles.getAsString(property)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Returns true if class is present.\n\t * If more then one class is provided - returns true only when all classes are present.\n\t *\n\t * ```ts\n\t * element.hasClass( 'foo' ); // Returns true if 'foo' class is present.\n\t * element.hasClass( 'foo', 'bar' ); // Returns true if 'foo' and 'bar' classes are both present.\n\t * ```\n\t */ hasClass(...className) {\n        for (const name of className){\n            if (!this._classes.has(name)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Returns iterator that contains all class names.\n\t */ getClassNames() {\n        return this._classes.keys();\n    }\n    /**\n\t * Returns style value for the given property mae.\n\t * If the style does not exist `undefined` is returned.\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#getAsString `StylesMap#getAsString()`} for details.\n\t *\n\t * For an element with style set to `'margin:1px'`:\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * const element = view.change( writer => {\n\t * \tconst element = writer.createElement();\n\t * \twriter.setStyle( 'margin', '1px' );\n\t * \twriter.setStyle( 'margin-bottom', '3em' );\n\t *\n\t * \treturn element;\n\t * } );\n\t *\n\t * element.getStyle( 'margin' ); // -> 'margin: 1px 1px 3em;'\n\t * ```\n\t */ getStyle(property) {\n        return this._styles.getAsString(property);\n    }\n    /**\n\t * Returns a normalized style object or single style value.\n\t *\n\t * For an element with style set to: margin:1px 2px 3em;\n\t *\n\t * ```ts\n\t * element.getNormalizedStyle( 'margin' ) );\n\t * ```\n\t *\n\t * will return:\n\t *\n\t * ```ts\n\t * {\n\t * \ttop: '1px',\n\t * \tright: '2px',\n\t * \tbottom: '3em',\n\t * \tleft: '2px'    // a normalized value from margin shorthand\n\t * }\n\t * ```\n\t *\n\t * and reading for single style value:\n\t *\n\t * ```ts\n\t * styles.getNormalizedStyle( 'margin-left' );\n\t * ```\n\t *\n\t * Will return a `2px` string.\n\t *\n\t * **Note**: This method will return normalized values only if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#getNormalized `StylesMap#getNormalized()`} for details.\n\t *\n\t * @param property Name of CSS property\n\t */ getNormalizedStyle(property) {\n        return this._styles.getNormalized(property);\n    }\n    /**\n\t * Returns iterator that contains all style names.\n\t *\n\t * @param expand Expand shorthand style properties and return all equivalent style representations.\n\t */ getStyleNames(expand) {\n        return this._styles.getStyleNames(expand);\n    }\n    /**\n\t * Returns true if style keys are present.\n\t * If more then one style property is provided - returns true only when all properties are present.\n\t *\n\t * ```ts\n\t * element.hasStyle( 'color' ); // Returns true if 'border-top' style is present.\n\t * element.hasStyle( 'color', 'border-top' ); // Returns true if 'color' and 'border-top' styles are both present.\n\t * ```\n\t */ hasStyle(...property) {\n        for (const name of property){\n            if (!this._styles.has(name)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Returns ancestor element that match specified pattern.\n\t * Provided patterns should be compatible with {@link module:engine/view/matcher~Matcher Matcher} as it is used internally.\n\t *\n\t * @see module:engine/view/matcher~Matcher\n\t * @param patterns Patterns used to match correct ancestor. See {@link module:engine/view/matcher~Matcher}.\n\t * @returns Found element or `null` if no matching ancestor was found.\n\t */ findAncestor(...patterns) {\n        const matcher = new Matcher(...patterns);\n        let parent = this.parent;\n        while(parent && !parent.is('documentFragment')){\n            if (matcher.match(parent)) {\n                return parent;\n            }\n            parent = parent.parent;\n        }\n        return null;\n    }\n    /**\n\t * Returns the custom property value for the given key.\n\t */ getCustomProperty(key) {\n        return this._customProperties.get(key);\n    }\n    /**\n\t * Returns an iterator which iterates over this element's custom properties.\n\t * Iterator provides `[ key, value ]` pairs for each stored property.\n\t */ *getCustomProperties() {\n        yield* this._customProperties.entries();\n    }\n    /**\n\t * Returns identity string based on element's name, styles, classes and other attributes.\n\t * Two elements that {@link #isSimilar are similar} will have same identity string.\n\t * It has the following format:\n\t *\n\t * ```ts\n\t * 'name class=\"class1,class2\" style=\"style1:value1;style2:value2\" attr1=\"val1\" attr2=\"val2\"'\n\t * ```\n \t *\n\t * For example:\n\t *\n\t * ```ts\n\t * const element = writer.createContainerElement( 'foo', {\n\t * \tbanana: '10',\n\t * \tapple: '20',\n\t * \tstyle: 'color: red; border-color: white;',\n\t * \tclass: 'baz'\n\t * } );\n\t *\n\t * // returns 'foo class=\"baz\" style=\"border-color:white;color:red\" apple=\"20\" banana=\"10\"'\n\t * element.getIdentity();\n\t * ```\n\t *\n\t * **Note**: Classes, styles and other attributes are sorted alphabetically.\n\t */ getIdentity() {\n        const classes = Array.from(this._classes).sort().join(',');\n        const styles = this._styles.toString();\n        const attributes = Array.from(this._attrs).map((i)=>`${i[0]}=\"${i[1]}\"`).sort().join(' ');\n        return this.name + (classes == '' ? '' : ` class=\"${classes}\"`) + (!styles ? '' : ` style=\"${styles}\"`) + (attributes == '' ? '' : ` ${attributes}`);\n    }\n    /**\n\t * Decides whether an unsafe attribute is whitelisted and should be rendered in the editing pipeline even though filtering mechanisms\n\t * like {@link module:engine/view/domconverter~DomConverter#shouldRenderAttribute} say it should not.\n\t *\n\t * Unsafe attribute names can be specified when creating an element via {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t *\n\t * @param attributeName The name of the attribute to be checked.\n\t */ shouldRenderUnsafeAttribute(attributeName) {\n        return this._unsafeAttributesToRender.includes(attributeName);\n    }\n    /**\n\t * Clones provided element.\n\t *\n\t * @internal\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns Clone of this element.\n\t */ _clone(deep = false) {\n        const childrenClone = [];\n        if (deep) {\n            for (const child of this.getChildren()){\n                childrenClone.push(child._clone(deep));\n            }\n        }\n        // ContainerElement and AttributeElement should be also cloned properly.\n        const cloned = new this.constructor(this.document, this.name, this._attrs, childrenClone);\n        // Classes and styles are cloned separately - this solution is faster than adding them back to attributes and\n        // parse once again in constructor.\n        cloned._classes = new Set(this._classes);\n        cloned._styles.set(this._styles.getNormalized());\n        // Clone custom properties.\n        cloned._customProperties = new Map(this._customProperties);\n        // Clone filler offset method.\n        // We can't define this method in a prototype because it's behavior which\n        // is changed by e.g. toWidget() function from ckeditor5-widget. Perhaps this should be one of custom props.\n        cloned.getFillerOffset = this.getFillerOffset;\n        // Clone unsafe attributes list.\n        cloned._unsafeAttributesToRender = this._unsafeAttributesToRender;\n        return cloned;\n    }\n    /**\n\t * {@link module:engine/view/element~Element#_insertChild Insert} a child node or a list of child nodes at the end of this node\n\t * and sets the parent of these nodes to this element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#insert\n\t * @internal\n\t * @param items Items to be inserted.\n\t * @fires change\n\t * @returns Number of appended nodes.\n\t */ _appendChild(items) {\n        return this._insertChild(this.childCount, items);\n    }\n    /**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this element.\n\t *\n\t * @internal\n\t * @see module:engine/view/downcastwriter~DowncastWriter#insert\n\t * @param index Position where nodes should be inserted.\n\t * @param items Items to be inserted.\n\t * @fires change\n\t * @returns Number of inserted nodes.\n\t */ _insertChild(index, items) {\n        this._fireChange('children', this);\n        let count = 0;\n        const nodes = normalize$3(this.document, items);\n        for (const node of nodes){\n            // If node that is being added to this element is already inside another element, first remove it from the old parent.\n            if (node.parent !== null) {\n                node._remove();\n            }\n            node.parent = this;\n            node.document = this.document;\n            this._children.splice(index, 0, node);\n            index++;\n            count++;\n        }\n        return count;\n    }\n    /**\n\t * Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#remove\n\t * @internal\n\t * @param index Number of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @fires change\n\t * @returns The array of removed nodes.\n\t */ _removeChildren(index, howMany = 1) {\n        this._fireChange('children', this);\n        for(let i = index; i < index + howMany; i++){\n            this._children[i].parent = null;\n        }\n        return this._children.splice(index, howMany);\n    }\n    /**\n\t * Adds or overwrite attribute with a specified key and value.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setAttribute\n\t * @internal\n\t * @param key Attribute key.\n\t * @param value Attribute value.\n\t * @fires change\n\t */ _setAttribute(key, value) {\n        const stringValue = String(value);\n        this._fireChange('attributes', this);\n        if (key == 'class') {\n            parseClasses(this._classes, stringValue);\n        } else if (key == 'style') {\n            this._styles.setTo(stringValue);\n        } else {\n            this._attrs.set(key, stringValue);\n        }\n    }\n    /**\n\t * Removes attribute from the element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeAttribute\n\t * @internal\n\t * @param key Attribute key.\n\t * @returns Returns true if an attribute existed and has been removed.\n\t * @fires change\n\t */ _removeAttribute(key) {\n        this._fireChange('attributes', this);\n        // Remove class attribute.\n        if (key == 'class') {\n            if (this._classes.size > 0) {\n                this._classes.clear();\n                return true;\n            }\n            return false;\n        }\n        // Remove style attribute.\n        if (key == 'style') {\n            if (!this._styles.isEmpty) {\n                this._styles.clear();\n                return true;\n            }\n            return false;\n        }\n        // Remove other attributes.\n        return this._attrs.delete(key);\n    }\n    /**\n\t * Adds specified class.\n\t *\n\t * ```ts\n\t * element._addClass( 'foo' ); // Adds 'foo' class.\n\t * element._addClass( [ 'foo', 'bar' ] ); // Adds 'foo' and 'bar' classes.\n\t * ```\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#addClass\n\t * @internal\n\t * @fires change\n\t */ _addClass(className) {\n        this._fireChange('attributes', this);\n        for (const name of toArray(className)){\n            this._classes.add(name);\n        }\n    }\n    /**\n\t * Removes specified class.\n\t *\n\t * ```ts\n\t * element._removeClass( 'foo' );  // Removes 'foo' class.\n\t * element._removeClass( [ 'foo', 'bar' ] ); // Removes both 'foo' and 'bar' classes.\n\t * ```\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeClass\n\t * @internal\n\t * @fires change\n\t */ _removeClass(className) {\n        this._fireChange('attributes', this);\n        for (const name of toArray(className)){\n            this._classes.delete(name);\n        }\n    }\n    _setStyle(property, value) {\n        this._fireChange('attributes', this);\n        if (typeof property != 'string') {\n            this._styles.set(property);\n        } else {\n            this._styles.set(property, value);\n        }\n    }\n    /**\n\t * Removes specified style.\n\t *\n\t * ```ts\n\t * element._removeStyle( 'color' );  // Removes 'color' style.\n\t * element._removeStyle( [ 'color', 'border-top' ] ); // Removes both 'color' and 'border-top' styles.\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeStyle\n\t * @internal\n\t * @fires change\n\t */ _removeStyle(property) {\n        this._fireChange('attributes', this);\n        for (const name of toArray(property)){\n            this._styles.remove(name);\n        }\n    }\n    /**\n\t * Sets a custom property. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setCustomProperty\n\t * @internal\n\t */ _setCustomProperty(key, value) {\n        this._customProperties.set(key, value);\n    }\n    /**\n\t * Removes the custom property stored under the given key.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeCustomProperty\n\t * @internal\n\t * @returns Returns true if property was removed.\n\t */ _removeCustomProperty(key) {\n        return this._customProperties.delete(key);\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nElement$1.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'element' || type === 'view:element' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'element' || type === 'view:element');\n    }\n};\n/**\n * Parses attributes provided to the element constructor before they are applied to an element. If attributes are passed\n * as an object (instead of `Iterable`), the object is transformed to the map. Attributes with `null` value are removed.\n * Attributes with non-`String` value are converted to `String`.\n *\n * @param attrs Attributes to parse.\n * @returns Parsed attributes.\n */ function parseAttributes(attrs) {\n    const attrsMap = toMap(attrs);\n    for (const [key, value] of attrsMap){\n        if (value === null) {\n            attrsMap.delete(key);\n        } else if (typeof value != 'string') {\n            attrsMap.set(key, String(value));\n        }\n    }\n    return attrsMap;\n}\n/**\n * Parses class attribute and puts all classes into classes set.\n * Classes set s cleared before insertion.\n *\n * @param classesSet Set to insert parsed classes.\n * @param classesString String with classes to parse.\n */ function parseClasses(classesSet, classesString) {\n    const classArray = classesString.split(/\\s+/);\n    classesSet.clear();\n    classArray.forEach((name)=>classesSet.add(name));\n}\n/**\n * Converts strings to Text and non-iterables to arrays.\n */ function normalize$3(document, nodes) {\n    // Separate condition because string is iterable.\n    if (typeof nodes == 'string') {\n        return [\n            new Text$1(document, nodes)\n        ];\n    }\n    if (!isIterable(nodes)) {\n        nodes = [\n            nodes\n        ];\n    }\n    // Array.from to enable .map() on non-arrays.\n    return Array.from(nodes).map((node)=>{\n        if (typeof node == 'string') {\n            return new Text$1(document, node);\n        }\n        if (node instanceof TextProxy$1) {\n            return new Text$1(document, node.data);\n        }\n        return node;\n    });\n}\n\n/**\n * Containers are elements which define document structure. They define boundaries for\n * {@link module:engine/view/attributeelement~AttributeElement attributes}. They are mostly used for block elements like `<p>` or `<div>`.\n *\n * Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n * types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.\n *\n * The container element should be your default choice when writing a converter, unless:\n *\n * * this element represents a model text attribute (then use {@link module:engine/view/attributeelement~AttributeElement}),\n * * this is an empty element like `<img>` (then use {@link module:engine/view/emptyelement~EmptyElement}),\n * * this is a root element,\n * * this is a nested editable element (then use  {@link module:engine/view/editableelement~EditableElement}).\n *\n * To create a new container element instance use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `DowncastWriter#createContainerElement()`}\n * method.\n */ class ContainerElement extends Element$1 {\n    /**\n\t * Creates a container element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createContainerElement\n\t * @see module:engine/view/element~Element\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */ constructor(document, name, attrs, children){\n        super(document, name, attrs, children);\n        this.getFillerOffset = getFillerOffset$4;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nContainerElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'containerElement' || type === 'view:containerElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'element' || type === 'view:element' || type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'containerElement' || type === 'view:containerElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'element' || type === 'view:element');\n    }\n};\n/**\n * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n *\n * @returns Block filler offset or `null` if block filler is not needed.\n */ function getFillerOffset$4() {\n    const children = [\n        ...this.getChildren()\n    ];\n    const lastChild = children[this.childCount - 1];\n    // Block filler is required after a `<br>` if it's the last element in its container. See #1422.\n    if (lastChild && lastChild.is('element', 'br')) {\n        return this.childCount;\n    }\n    for (const child of children){\n        // If there's any non-UI element – don't render the bogus.\n        if (!child.is('uiElement')) {\n            return null;\n        }\n    }\n    // If there are only UI elements – render the bogus at the end of the element.\n    return this.childCount;\n}\n\n/**\n * Editable element which can be a {@link module:engine/view/rooteditableelement~RootEditableElement root}\n * or nested editable area in the editor.\n *\n * Editable is automatically read-only when its {@link module:engine/view/document~Document Document} is read-only.\n *\n * The constructor of this class shouldn't be used directly. To create new `EditableElement` use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`} method.\n */ class EditableElement extends /* #__PURE__ */ ObservableMixin(ContainerElement) {\n    /**\n\t * Creates an editable element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createEditableElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */ constructor(document, name, attributes, children){\n        super(document, name, attributes, children);\n        this.set('isReadOnly', false);\n        this.set('isFocused', false);\n        this.set('placeholder', undefined);\n        this.bind('isReadOnly').to(document);\n        this.bind('isFocused').to(document, 'isFocused', (isFocused)=>isFocused && document.selection.editableElement == this);\n        // Update focus state based on selection changes.\n        this.listenTo(document.selection, 'change', ()=>{\n            this.isFocused = document.isFocused && document.selection.editableElement == this;\n        });\n    }\n    destroy() {\n        this.stopListening();\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nEditableElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'editableElement' || type === 'view:editableElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'containerElement' || type === 'view:containerElement' || type === 'element' || type === 'view:element' || type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'editableElement' || type === 'view:editableElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'containerElement' || type === 'view:containerElement' || type === 'element' || type === 'view:element');\n    }\n};\n\nconst rootNameSymbol = Symbol('rootName');\n/**\n * Class representing a single root in the data view. A root can be either {@link ~RootEditableElement#isReadOnly editable or read-only},\n * but in both cases it is called \"an editable\". Roots can contain other {@link module:engine/view/editableelement~EditableElement\n * editable elements} making them \"nested editables\".\n */ class RootEditableElement extends EditableElement {\n    /**\n\t * Creates root editable element.\n\t *\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t */ constructor(document, name){\n        super(document, name);\n        this.rootName = 'main';\n    }\n    /**\n\t * Name of this root inside {@link module:engine/view/document~Document} that is an owner of this root. If no\n\t * other name is set, `main` name is used.\n\t *\n\t * @readonly\n\t */ get rootName() {\n        return this.getCustomProperty(rootNameSymbol);\n    }\n    set rootName(rootName) {\n        this._setCustomProperty(rootNameSymbol, rootName);\n    }\n    /**\n\t * Overrides old element name and sets new one.\n\t * This is needed because view roots are created before they are attached to the DOM.\n\t * The name of the root element is temporary at this stage. It has to be changed when the\n\t * view root element is attached to the DOM element.\n\t *\n\t * @internal\n\t * @param name The new name of element.\n\t */ set _name(name) {\n        this.name = name;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRootEditableElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'rootElement' || type === 'view:rootElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'editableElement' || type === 'view:editableElement' || type === 'containerElement' || type === 'view:containerElement' || type === 'element' || type === 'view:element' || type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'rootElement' || type === 'view:rootElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'editableElement' || type === 'view:editableElement' || type === 'containerElement' || type === 'view:containerElement' || type === 'element' || type === 'view:element');\n    }\n};\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */ let TreeWalker$1 = class TreeWalker {\n    /**\n\t * Walking direction. Defaults `'forward'`.\n\t */ direction;\n    /**\n\t * Iterator boundaries.\n\t *\n\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t * on the start of boundary, then `{ done: true }` is returned.\n\t *\n\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t */ boundaries;\n    /**\n\t * Flag indicating whether all characters from {@link module:engine/view/text~Text} should be returned as one\n\t * {@link module:engine/view/text~Text} or one by one as {@link module:engine/view/textproxy~TextProxy}.\n\t */ singleCharacters;\n    /**\n\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t * iterated node will not be returned along with `elementEnd` tag.\n\t */ shallow;\n    /**\n\t * Flag indicating whether iterator should ignore `elementEnd` tags. If set to `true`, walker will not\n\t * return a parent node of the start position. Each {@link module:engine/view/element~Element} will be returned once.\n\t * When set to `false` each element might be returned twice: for `'elementStart'` and `'elementEnd'`.\n\t */ ignoreElementEnd;\n    /**\n\t * Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t * `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t */ _position;\n    /**\n\t * Start boundary parent.\n\t */ _boundaryStartParent;\n    /**\n\t * End boundary parent.\n\t */ _boundaryEndParent;\n    /**\n\t * Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t *\n\t * @param options Object with configuration.\n\t */ constructor(options = {}){\n        if (!options.boundaries && !options.startPosition) {\n            /**\n\t\t\t * Neither boundaries nor starting position have been defined.\n\t\t\t *\n\t\t\t * @error view-tree-walker-no-start-position\n\t\t\t */ throw new CKEditorError('view-tree-walker-no-start-position', null);\n        }\n        if (options.direction && options.direction != 'forward' && options.direction != 'backward') {\n            /**\n\t\t\t * Only `backward` and `forward` direction allowed.\n\t\t\t *\n\t\t\t * @error view-tree-walker-unknown-direction\n\t\t\t */ throw new CKEditorError('view-tree-walker-unknown-direction', options.startPosition, {\n                direction: options.direction\n            });\n        }\n        this.boundaries = options.boundaries || null;\n        if (options.startPosition) {\n            this._position = Position$1._createAt(options.startPosition);\n        } else {\n            this._position = Position$1._createAt(options.boundaries[options.direction == 'backward' ? 'end' : 'start']);\n        }\n        this.direction = options.direction || 'forward';\n        this.singleCharacters = !!options.singleCharacters;\n        this.shallow = !!options.shallow;\n        this.ignoreElementEnd = !!options.ignoreElementEnd;\n        this._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n        this._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n    }\n    /**\n\t * Iterable interface.\n\t */ [Symbol.iterator]() {\n        return this;\n    }\n    /**\n\t * Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t * `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t */ get position() {\n        return this._position;\n    }\n    /**\n\t * Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * walker.skip( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * walker.skip( value => true ); // Move the position to the end: <p>{}foo</p> -> <p>foo</p>[]\n\t * walker.skip( value => false ); // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t */ skip(skip) {\n        let nextResult;\n        let prevPosition;\n        do {\n            prevPosition = this.position;\n            nextResult = this.next();\n        }while (!nextResult.done && skip(nextResult.value))\n        if (!nextResult.done) {\n            this._position = prevPosition;\n        }\n    }\n    /**\n\t * Gets the next tree walker's value.\n\t *\n\t * @returns Object implementing iterator interface, returning\n\t * information about taken step.\n\t */ next() {\n        if (this.direction == 'forward') {\n            return this._next();\n        } else {\n            return this._previous();\n        }\n    }\n    /**\n\t * Makes a step forward in view. Moves the {@link #position} to the next position and returns the encountered value.\n\t */ _next() {\n        let position = this.position.clone();\n        const previousPosition = this.position;\n        const parent = position.parent;\n        // We are at the end of the root.\n        if (parent.parent === null && position.offset === parent.childCount) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // We reached the walker boundary.\n        if (parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // Get node just after current position.\n        let node;\n        // Text is a specific parent because it contains string instead of child nodes.\n        if (parent instanceof Text$1) {\n            if (position.isAtEnd) {\n                // Prevent returning \"elementEnd\" for Text node. Skip that value and return the next walker step.\n                this._position = Position$1._createAfter(parent);\n                return this._next();\n            }\n            node = parent.data[position.offset];\n        } else {\n            node = parent.getChild(position.offset);\n        }\n        if (node instanceof Element$1) {\n            if (!this.shallow) {\n                position = new Position$1(node, 0);\n            } else {\n                // We are past the walker boundaries.\n                if (this.boundaries && this.boundaries.end.isBefore(position)) {\n                    return {\n                        done: true,\n                        value: undefined\n                    };\n                }\n                position.offset++;\n            }\n            this._position = position;\n            return this._formatReturnValue('elementStart', node, previousPosition, position, 1);\n        }\n        if (node instanceof Text$1) {\n            if (this.singleCharacters) {\n                position = new Position$1(node, 0);\n                this._position = position;\n                return this._next();\n            }\n            let charactersCount = node.data.length;\n            let item;\n            // If text stick out of walker range, we need to cut it and wrap in TextProxy.\n            if (node == this._boundaryEndParent) {\n                charactersCount = this.boundaries.end.offset;\n                item = new TextProxy$1(node, 0, charactersCount);\n                position = Position$1._createAfter(item);\n            } else {\n                item = new TextProxy$1(node, 0, node.data.length);\n                // If not just keep moving forward.\n                position.offset++;\n            }\n            this._position = position;\n            return this._formatReturnValue('text', item, previousPosition, position, charactersCount);\n        }\n        if (typeof node == 'string') {\n            let textLength;\n            if (this.singleCharacters) {\n                textLength = 1;\n            } else {\n                // Check if text stick out of walker range.\n                const endOffset = parent === this._boundaryEndParent ? this.boundaries.end.offset : parent.data.length;\n                textLength = endOffset - position.offset;\n            }\n            const textProxy = new TextProxy$1(parent, position.offset, textLength);\n            position.offset += textLength;\n            this._position = position;\n            return this._formatReturnValue('text', textProxy, previousPosition, position, textLength);\n        }\n        // `node` is not set, we reached the end of current `parent`.\n        position = Position$1._createAfter(parent);\n        this._position = position;\n        if (this.ignoreElementEnd) {\n            return this._next();\n        }\n        return this._formatReturnValue('elementEnd', parent, previousPosition, position);\n    }\n    /**\n\t * Makes a step backward in view. Moves the {@link #position} to the previous position and returns the encountered value.\n\t */ _previous() {\n        let position = this.position.clone();\n        const previousPosition = this.position;\n        const parent = position.parent;\n        // We are at the beginning of the root.\n        if (parent.parent === null && position.offset === 0) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // We reached the walker boundary.\n        if (parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // Get node just before current position.\n        let node;\n        // Text {@link module:engine/view/text~Text} element is a specific parent because contains string instead of child nodes.\n        if (parent instanceof Text$1) {\n            if (position.isAtStart) {\n                // Prevent returning \"elementStart\" for Text node. Skip that value and return the next walker step.\n                this._position = Position$1._createBefore(parent);\n                return this._previous();\n            }\n            node = parent.data[position.offset - 1];\n        } else {\n            node = parent.getChild(position.offset - 1);\n        }\n        if (node instanceof Element$1) {\n            if (this.shallow) {\n                position.offset--;\n                this._position = position;\n                return this._formatReturnValue('elementStart', node, previousPosition, position, 1);\n            }\n            position = new Position$1(node, node.childCount);\n            this._position = position;\n            if (this.ignoreElementEnd) {\n                return this._previous();\n            }\n            return this._formatReturnValue('elementEnd', node, previousPosition, position);\n        }\n        if (node instanceof Text$1) {\n            if (this.singleCharacters) {\n                position = new Position$1(node, node.data.length);\n                this._position = position;\n                return this._previous();\n            }\n            let charactersCount = node.data.length;\n            let item;\n            // If text stick out of walker range, we need to cut it and wrap in TextProxy.\n            if (node == this._boundaryStartParent) {\n                const offset = this.boundaries.start.offset;\n                item = new TextProxy$1(node, offset, node.data.length - offset);\n                charactersCount = item.data.length;\n                position = Position$1._createBefore(item);\n            } else {\n                item = new TextProxy$1(node, 0, node.data.length);\n                // If not just keep moving backward.\n                position.offset--;\n            }\n            this._position = position;\n            return this._formatReturnValue('text', item, previousPosition, position, charactersCount);\n        }\n        if (typeof node == 'string') {\n            let textLength;\n            if (!this.singleCharacters) {\n                // Check if text stick out of walker range.\n                const startOffset = parent === this._boundaryStartParent ? this.boundaries.start.offset : 0;\n                textLength = position.offset - startOffset;\n            } else {\n                textLength = 1;\n            }\n            position.offset -= textLength;\n            const textProxy = new TextProxy$1(parent, position.offset, textLength);\n            this._position = position;\n            return this._formatReturnValue('text', textProxy, previousPosition, position, textLength);\n        }\n        // `node` is not set, we reached the beginning of current `parent`.\n        position = Position$1._createBefore(parent);\n        this._position = position;\n        return this._formatReturnValue('elementStart', parent, previousPosition, position, 1);\n    }\n    /**\n\t * Format returned data and adjust `previousPosition` and `nextPosition` if reach the bound of the {@link module:engine/view/text~Text}.\n\t *\n\t * @param type Type of step.\n\t * @param item Item between old and new position.\n\t * @param previousPosition Previous position of iterator.\n\t * @param nextPosition Next position of iterator.\n\t * @param length Length of the item.\n\t */ _formatReturnValue(type, item, previousPosition, nextPosition, length) {\n        // Text is a specific parent, because contains string instead of children.\n        // Walker doesn't enter to the Text except situations when walker is iterating over every single character,\n        // or the bound starts/ends inside the Text. So when the position is at the beginning or at the end of the Text\n        // we move it just before or just after Text.\n        if (item instanceof TextProxy$1) {\n            // Position is at the end of Text.\n            if (item.offsetInText + item.data.length == item.textNode.data.length) {\n                if (this.direction == 'forward' && !(this.boundaries && this.boundaries.end.isEqual(this.position))) {\n                    nextPosition = Position$1._createAfter(item.textNode);\n                    // When we change nextPosition of returned value we need also update walker current position.\n                    this._position = nextPosition;\n                } else {\n                    previousPosition = Position$1._createAfter(item.textNode);\n                }\n            }\n            // Position is at the begining ot the text.\n            if (item.offsetInText === 0) {\n                if (this.direction == 'backward' && !(this.boundaries && this.boundaries.start.isEqual(this.position))) {\n                    nextPosition = Position$1._createBefore(item.textNode);\n                    // When we change nextPosition of returned value we need also update walker current position.\n                    this._position = nextPosition;\n                } else {\n                    previousPosition = Position$1._createBefore(item.textNode);\n                }\n            }\n        }\n        return {\n            done: false,\n            value: {\n                type,\n                item,\n                previousPosition,\n                nextPosition,\n                length\n            }\n        };\n    }\n};\n\n/**\n * Position in the view tree. Position is represented by its parent node and an offset in this parent.\n *\n * In order to create a new position instance use the `createPosition*()` factory methods available in:\n *\n * * {@link module:engine/view/view~View}\n * * {@link module:engine/view/downcastwriter~DowncastWriter}\n * * {@link module:engine/view/upcastwriter~UpcastWriter}\n */ let Position$1 = class Position extends TypeCheckable$1 {\n    /**\n\t * Position parent.\n\t */ parent;\n    /**\n\t * Position offset.\n\t */ offset;\n    /**\n\t * Creates a position.\n\t *\n\t * @param parent Position parent.\n\t * @param offset Position offset.\n\t */ constructor(parent, offset){\n        super();\n        this.parent = parent;\n        this.offset = offset;\n    }\n    /**\n\t * Node directly after the position. Equals `null` when there is no node after position or position is located\n\t * inside text node.\n\t */ get nodeAfter() {\n        if (this.parent.is('$text')) {\n            return null;\n        }\n        return this.parent.getChild(this.offset) || null;\n    }\n    /**\n\t * Node directly before the position. Equals `null` when there is no node before position or position is located\n\t * inside text node.\n\t */ get nodeBefore() {\n        if (this.parent.is('$text')) {\n            return null;\n        }\n        return this.parent.getChild(this.offset - 1) || null;\n    }\n    /**\n\t * Is `true` if position is at the beginning of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t */ get isAtStart() {\n        return this.offset === 0;\n    }\n    /**\n\t * Is `true` if position is at the end of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t */ get isAtEnd() {\n        const endOffset = this.parent.is('$text') ? this.parent.data.length : this.parent.childCount;\n        return this.offset === endOffset;\n    }\n    /**\n\t * Position's root, that is the root of the position's parent element.\n\t */ get root() {\n        return this.parent.root;\n    }\n    /**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this position, or `null` if\n\t * position is not inside an editable element.\n\t */ get editableElement() {\n        let editable = this.parent;\n        while(!(editable instanceof EditableElement)){\n            if (editable.parent) {\n                editable = editable.parent;\n            } else {\n                return null;\n            }\n        }\n        return editable;\n    }\n    /**\n\t * Returns a new instance of Position with offset incremented by `shift` value.\n\t *\n\t * @param shift How position offset should get changed. Accepts negative values.\n\t * @returns Shifted position.\n\t */ getShiftedBy(shift) {\n        const shifted = Position._createAt(this);\n        const offset = shifted.offset + shift;\n        shifted.offset = offset < 0 ? 0 : offset;\n        return shifted;\n    }\n    /**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/view/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * getLastMatchingPosition( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * getLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } ); // <p>foo[]</p> -> <p>{}foo</p>\n\t * getLastMatchingPosition( value => false ); // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @returns The position after the last item which matches the `skip` callback test.\n\t */ getLastMatchingPosition(skip, options = {}) {\n        options.startPosition = this;\n        const treeWalker = new TreeWalker$1(options);\n        treeWalker.skip(skip);\n        return treeWalker.position;\n    }\n    /**\n\t * Returns ancestors array of this position, that is this position's parent and it's ancestors.\n\t *\n\t * @returns Array with ancestors.\n\t */ getAncestors() {\n        if (this.parent.is('documentFragment')) {\n            return [\n                this.parent\n            ];\n        } else {\n            return this.parent.getAncestors({\n                includeSelf: true\n            });\n        }\n    }\n    /**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both positions.\n\t */ getCommonAncestor(position) {\n        const ancestorsA = this.getAncestors();\n        const ancestorsB = position.getAncestors();\n        let i = 0;\n        while(ancestorsA[i] == ancestorsB[i] && ancestorsA[i]){\n            i++;\n        }\n        return i === 0 ? null : ancestorsA[i - 1];\n    }\n    /**\n\t * Checks whether this position equals given position.\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if positions are same.\n\t */ isEqual(otherPosition) {\n        return this.parent == otherPosition.parent && this.offset == otherPosition.offset;\n    }\n    /**\n\t * Checks whether this position is located before given position. When method returns `false` it does not mean that\n\t * this position is after give one. Two positions may be located inside separate roots and in that situation this\n\t * method will still return `false`.\n\t *\n\t * @see module:engine/view/position~Position#isAfter\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param otherPosition Position to compare with.\n\t * @returns Returns `true` if this position is before given position.\n\t */ isBefore(otherPosition) {\n        return this.compareWith(otherPosition) == 'before';\n    }\n    /**\n\t * Checks whether this position is located after given position. When method returns `false` it does not mean that\n\t * this position is before give one. Two positions may be located inside separate roots and in that situation this\n\t * method will still return `false`.\n\t *\n\t * @see module:engine/view/position~Position#isBefore\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param otherPosition Position to compare with.\n\t * @returns Returns `true` if this position is after given position.\n\t */ isAfter(otherPosition) {\n        return this.compareWith(otherPosition) == 'after';\n    }\n    /**\n\t * Checks whether this position is before, after or in same position that other position. Two positions may be also\n\t * different when they are located in separate roots.\n\t *\n\t * @param otherPosition Position to compare with.\n\t */ compareWith(otherPosition) {\n        if (this.root !== otherPosition.root) {\n            return 'different';\n        }\n        if (this.isEqual(otherPosition)) {\n            return 'same';\n        }\n        // Get path from root to position's parent element.\n        const thisPath = this.parent.is('node') ? this.parent.getPath() : [];\n        const otherPath = otherPosition.parent.is('node') ? otherPosition.parent.getPath() : [];\n        // Add the positions' offsets to the parents offsets.\n        thisPath.push(this.offset);\n        otherPath.push(otherPosition.offset);\n        // Compare both path arrays to find common ancestor.\n        const result = compareArrays(thisPath, otherPath);\n        switch(result){\n            case 'prefix':\n                return 'before';\n            case 'extension':\n                return 'after';\n            default:\n                // Cast to number to avoid having 'same' as a type of `result`.\n                return thisPath[result] < otherPath[result] ? 'before' : 'after';\n        }\n    }\n    /**\n\t * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this positions as a start position.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}\n\t */ getWalker(options = {}) {\n        options.startPosition = this;\n        return new TreeWalker$1(options);\n    }\n    /**\n\t * Clones this position.\n\t */ clone() {\n        return new Position(this.parent, this.offset);\n    }\n    /**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link module:engine/view/position~Position._createBefore},\n\t * * {@link module:engine/view/position~Position._createAfter}.\n\t *\n\t * @internal\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */ static _createAt(itemOrPosition, offset) {\n        if (itemOrPosition instanceof Position) {\n            return new this(itemOrPosition.parent, itemOrPosition.offset);\n        } else {\n            const node = itemOrPosition;\n            if (offset == 'end') {\n                offset = node.is('$text') ? node.data.length : node.childCount;\n            } else if (offset == 'before') {\n                return this._createBefore(node);\n            } else if (offset == 'after') {\n                return this._createAfter(node);\n            } else if (offset !== 0 && !offset) {\n                /**\n\t\t\t\t * {@link module:engine/view/view~View#createPositionAt `View#createPositionAt()`}\n\t\t\t\t * requires the offset to be specified when the first parameter is a view item.\n\t\t\t\t *\n\t\t\t\t * @error view-createpositionat-offset-required\n\t\t\t\t */ throw new CKEditorError('view-createpositionat-offset-required', node);\n            }\n            return new Position(node, offset);\n        }\n    }\n    /**\n\t * Creates a new position after given view item.\n\t *\n\t * @internal\n\t * @param item View item after which the position should be located.\n\t */ static _createAfter(item) {\n        // TextProxy is not a instance of Node so we need do handle it in specific way.\n        if (item.is('$textProxy')) {\n            return new Position(item.textNode, item.offsetInText + item.data.length);\n        }\n        if (!item.parent) {\n            /**\n\t\t\t * You can not make a position after a root.\n\t\t\t *\n\t\t\t * @error view-position-after-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */ throw new CKEditorError('view-position-after-root', item, {\n                root: item\n            });\n        }\n        return new Position(item.parent, item.index + 1);\n    }\n    /**\n\t * Creates a new position before given view item.\n\t *\n\t * @internal\n\t * @param item View item before which the position should be located.\n\t */ static _createBefore(item) {\n        // TextProxy is not a instance of Node so we need do handle it in specific way.\n        if (item.is('$textProxy')) {\n            return new Position(item.textNode, item.offsetInText);\n        }\n        if (!item.parent) {\n            /**\n\t\t\t * You cannot make a position before a root.\n\t\t\t *\n\t\t\t * @error view-position-before-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */ throw new CKEditorError('view-position-before-root', item, {\n                root: item\n            });\n        }\n        return new Position(item.parent, item.index);\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nPosition$1.prototype.is = function(type) {\n    return type === 'position' || type === 'view:position';\n};\n\n/**\n * Range in the view tree. A range is represented by its start and end {@link module:engine/view/position~Position positions}.\n *\n * In order to create a new position instance use the `createPosition*()` factory methods available in:\n *\n * * {@link module:engine/view/view~View}\n * * {@link module:engine/view/downcastwriter~DowncastWriter}\n * * {@link module:engine/view/upcastwriter~UpcastWriter}\n */ let Range$1 = class Range extends TypeCheckable$1 {\n    /**\n\t * Start position.\n\t */ start;\n    /**\n\t * End position.\n\t */ end;\n    /**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** Constructor creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at the `start` position.\n\t */ constructor(start, end = null){\n        super();\n        this.start = start.clone();\n        this.end = end ? end.clone() : start.clone();\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/view/position~Position positions},\n\t * grouped as {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * This iterator uses {@link module:engine/view/treewalker~TreeWalker TreeWalker} with `boundaries` set to this range and\n\t * `ignoreElementEnd` option\n\t * set to `true`.\n\t */ *[Symbol.iterator]() {\n        yield* new TreeWalker$1({\n            boundaries: this,\n            ignoreElementEnd: true\n        });\n    }\n    /**\n\t * Returns whether the range is collapsed, that is it start and end positions are equal.\n\t */ get isCollapsed() {\n        return this.start.isEqual(this.end);\n    }\n    /**\n\t * Returns whether this range is flat, that is if {@link module:engine/view/range~Range#start start} position and\n\t * {@link module:engine/view/range~Range#end end} position are in the same {@link module:engine/view/position~Position#parent parent}.\n\t */ get isFlat() {\n        return this.start.parent === this.end.parent;\n    }\n    /**\n\t * Range root element.\n\t */ get root() {\n        return this.start.root;\n    }\n    /**\n\t * Creates a maximal range that has the same content as this range but is expanded in both ways (at the beginning\n\t * and at the end).\n\t *\n\t * For example:\n\t *\n\t * ```html\n\t * <p>Foo</p><p><b>{Bar}</b></p> -> <p>Foo</p>[<p><b>Bar</b>]</p>\n\t * <p><b>foo</b>{bar}<span></span></p> -> <p><b>foo[</b>bar<span></span>]</p>\n\t * ```\n\t *\n\t * Note that in the sample above:\n\t *\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns Enlarged range.\n\t */ getEnlarged() {\n        let start = this.start.getLastMatchingPosition(enlargeTrimSkip, {\n            direction: 'backward'\n        });\n        let end = this.end.getLastMatchingPosition(enlargeTrimSkip);\n        // Fix positions, in case if they are in Text node.\n        if (start.parent.is('$text') && start.isAtStart) {\n            start = Position$1._createBefore(start.parent);\n        }\n        if (end.parent.is('$text') && end.isAtEnd) {\n            end = Position$1._createAfter(end.parent);\n        }\n        return new Range(start, end);\n    }\n    /**\n\t * Creates a minimum range that has the same content as this range but is trimmed in both ways (at the beginning\n\t * and at the end).\n\t *\n\t * For example:\n\t *\n\t * ```html\n\t * <p>Foo</p>[<p><b>Bar</b>]</p> -> <p>Foo</p><p><b>{Bar}</b></p>\n\t * <p><b>foo[</b>bar<span></span>]</p> -> <p><b>foo</b>{bar}<span></span></p>\n\t * ```\n\t *\n\t * Note that in the sample above:\n\t *\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns Shrunk range.\n\t */ getTrimmed() {\n        let start = this.start.getLastMatchingPosition(enlargeTrimSkip);\n        if (start.isAfter(this.end) || start.isEqual(this.end)) {\n            return new Range(start, start);\n        }\n        let end = this.end.getLastMatchingPosition(enlargeTrimSkip, {\n            direction: 'backward'\n        });\n        const nodeAfterStart = start.nodeAfter;\n        const nodeBeforeEnd = end.nodeBefore;\n        // Because TreeWalker prefers positions next to text node, we need to move them manually into these text nodes.\n        if (nodeAfterStart && nodeAfterStart.is('$text')) {\n            start = new Position$1(nodeAfterStart, 0);\n        }\n        if (nodeBeforeEnd && nodeBeforeEnd.is('$text')) {\n            end = new Position$1(nodeBeforeEnd, nodeBeforeEnd.data.length);\n        }\n        return new Range(start, end);\n    }\n    /**\n\t * Two ranges are equal if their start and end positions are equal.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns `true` if ranges are equal, `false` otherwise\n\t */ isEqual(otherRange) {\n        return this == otherRange || this.start.isEqual(otherRange.start) && this.end.isEqual(otherRange.end);\n    }\n    /**\n\t * Checks whether this range contains given {@link module:engine/view/position~Position position}.\n\t *\n\t * @param position Position to check.\n\t * @returns `true` if given {@link module:engine/view/position~Position position} is contained in this range, `false` otherwise.\n\t */ containsPosition(position) {\n        return position.isAfter(this.start) && position.isBefore(this.end);\n    }\n    /**\n\t * Checks whether this range contains given {@link module:engine/view/range~Range range}.\n\t *\n\t * @param otherRange Range to check.\n\t * @param loose Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t * start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t * even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t * @returns `true` if given {@link module:engine/view/range~Range range} boundaries are contained by this range, `false`\n\t * otherwise.\n\t */ containsRange(otherRange, loose = false) {\n        if (otherRange.isCollapsed) {\n            loose = false;\n        }\n        const containsStart = this.containsPosition(otherRange.start) || loose && this.start.isEqual(otherRange.start);\n        const containsEnd = this.containsPosition(otherRange.end) || loose && this.end.isEqual(otherRange.end);\n        return containsStart && containsEnd;\n    }\n    /**\n\t * Computes which part(s) of this {@link module:engine/view/range~Range range} is not a part of given\n\t * {@link module:engine/view/range~Range range}.\n\t * Returned array contains zero, one or two {@link module:engine/view/range~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let foo = downcastWriter.createText( 'foo' );\n\t * let img = downcastWriter.createContainerElement( 'img' );\n\t * let bar = downcastWriter.createText( 'bar' );\n\t * let p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t * let range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t * let otherRange = view.createRange( // \"oo\", img, \"ba\" are in range.\n\t * \tview.createPositionAt( foo, 1 ),\n\t * \tview.createPositionAt( bar, 2 )\n\t * );\n\t * let transformed = range.getDifference( otherRange );\n\t * // transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t * otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has one range: from ( p, 2 ) to ( bar, 1 )\n\t *\n\t * otherRange = view.createRange( view.createPositionAt( p, 1 ), view.createPositionAt( p, 2 ) ); // img is in range.\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has two ranges: from ( foo, 1 ) to ( p, 1 ) and from ( p, 2 ) to ( bar, 1 )\n\t * ```\n\t *\n\t * @param otherRange Range to differentiate against.\n\t * @returns The difference between ranges.\n\t */ getDifference(otherRange) {\n        const ranges = [];\n        if (this.isIntersecting(otherRange)) {\n            // Ranges intersect.\n            if (this.containsPosition(otherRange.start)) {\n                // Given range start is inside this range. This means that we have to\n                // add shrunken range - from the start to the middle of this range.\n                ranges.push(new Range(this.start, otherRange.start));\n            }\n            if (this.containsPosition(otherRange.end)) {\n                // Given range end is inside this range. This means that we have to\n                // add shrunken range - from the middle of this range to the end.\n                ranges.push(new Range(otherRange.end, this.end));\n            }\n        } else {\n            // Ranges do not intersect, return the original range.\n            ranges.push(this.clone());\n        }\n        return ranges;\n    }\n    /**\n\t * Returns an intersection of this {@link module:engine/view/range~Range range} and given {@link module:engine/view/range~Range range}.\n\t * Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let foo = downcastWriter.createText( 'foo' );\n\t * let img = downcastWriter.createContainerElement( 'img' );\n\t * let bar = downcastWriter.createText( 'bar' );\n\t * let p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t * let range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t * let otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t * let transformed = range.getIntersection( otherRange ); // range from ( foo, 1 ) to ( p, 2 ).\n\t *\n\t * otherRange = view.createRange( view.createPositionAt( bar, 1 ), view.createPositionAt( bar, 3 ); \"ar\" is in range.\n\t * transformed = range.getIntersection( otherRange ); // null - no common part.\n\t * ```\n\t *\n\t * @param otherRange Range to check for intersection.\n\t * @returns A common part of given ranges or `null` if ranges have no common part.\n\t */ getIntersection(otherRange) {\n        if (this.isIntersecting(otherRange)) {\n            // Ranges intersect, so a common range will be returned.\n            // At most, it will be same as this range.\n            let commonRangeStart = this.start;\n            let commonRangeEnd = this.end;\n            if (this.containsPosition(otherRange.start)) {\n                // Given range start is inside this range. This means thaNt we have to\n                // shrink common range to the given range start.\n                commonRangeStart = otherRange.start;\n            }\n            if (this.containsPosition(otherRange.end)) {\n                // Given range end is inside this range. This means that we have to\n                // shrink common range to the given range end.\n                commonRangeEnd = otherRange.end;\n            }\n            return new Range(commonRangeStart, commonRangeEnd);\n        }\n        // Ranges do not intersect, so they do not have common part.\n        return null;\n    }\n    /**\n\t * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t */ getWalker(options = {}) {\n        options.boundaries = this;\n        return new TreeWalker$1(options);\n    }\n    /**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of range's both ends (in which the entire range is contained).\n\t */ getCommonAncestor() {\n        return this.start.getCommonAncestor(this.end);\n    }\n    /**\n\t * Returns an {@link module:engine/view/element~Element Element} contained by the range.\n\t * The element will be returned when it is the **only** node within the range and **fully–contained**\n\t * at the same time.\n\t */ getContainedElement() {\n        if (this.isCollapsed) {\n            return null;\n        }\n        let nodeAfterStart = this.start.nodeAfter;\n        let nodeBeforeEnd = this.end.nodeBefore;\n        // Handle the situation when the range position is at the beginning / at the end of a text node.\n        // In such situation `.nodeAfter` and `.nodeBefore` are `null` but the range still might be spanning\n        // over one element.\n        //\n        // <p>Foo{<span class=\"widget\"></span>}bar</p> vs <p>Foo[<span class=\"widget\"></span>]bar</p>\n        //\n        // These are basically the same range, only the difference is if the range position is at\n        // at the end/at the beginning of a text node or just before/just after the text node.\n        //\n        if (this.start.parent.is('$text') && this.start.isAtEnd && this.start.parent.nextSibling) {\n            nodeAfterStart = this.start.parent.nextSibling;\n        }\n        if (this.end.parent.is('$text') && this.end.isAtStart && this.end.parent.previousSibling) {\n            nodeBeforeEnd = this.end.parent.previousSibling;\n        }\n        if (nodeAfterStart && nodeAfterStart.is('element') && nodeAfterStart === nodeBeforeEnd) {\n            return nodeAfterStart;\n        }\n        return null;\n    }\n    /**\n\t * Clones this range.\n\t */ clone() {\n        return new Range(this.start, this.end);\n    }\n    /**\n\t * Returns an iterator that iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/view/item~Item items},\n\t * not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t */ *getItems(options = {}) {\n        options.boundaries = this;\n        options.ignoreElementEnd = true;\n        const treeWalker = new TreeWalker$1(options);\n        for (const value of treeWalker){\n            yield value.item;\n        }\n    }\n    /**\n\t * Returns an iterator that iterates over all {@link module:engine/view/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/view/position~Position positions}, not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t */ *getPositions(options = {}) {\n        options.boundaries = this;\n        const treeWalker = new TreeWalker$1(options);\n        yield treeWalker.position;\n        for (const value of treeWalker){\n            yield value.nextPosition;\n        }\n    }\n    /**\n\t * Checks and returns whether this range intersects with the given range.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns True if ranges intersect.\n\t */ isIntersecting(otherRange) {\n        return this.start.isBefore(otherRange.end) && this.end.isAfter(otherRange.start);\n    }\n    /**\n\t * Creates a range from the given parents and offsets.\n\t *\n\t * @internal\n\t * @param startElement Start position parent element.\n\t * @param startOffset Start position offset.\n\t * @param endElement End position parent element.\n\t * @param endOffset End position offset.\n\t * @returns Created range.\n\t */ static _createFromParentsAndOffsets(startElement, startOffset, endElement, endOffset) {\n        return new this(new Position$1(startElement, startOffset), new Position$1(endElement, endOffset));\n    }\n    /**\n\t * Creates a new range, spreading from specified {@link module:engine/view/position~Position position} to a position moved by\n\t * given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t *\n\t * @internal\n\t * @param position Beginning of the range.\n\t * @param shift How long the range should be.\n\t */ static _createFromPositionAndShift(position, shift) {\n        const start = position;\n        const end = position.getShiftedBy(shift);\n        return shift > 0 ? new this(start, end) : new this(end, start);\n    }\n    /**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @internal\n\t * @param element Element which is a parent for the range.\n\t */ static _createIn(element) {\n        return this._createFromParentsAndOffsets(element, 0, element, element.childCount);\n    }\n    /**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @internal\n\t */ static _createOn(item) {\n        const size = item.is('$textProxy') ? item.offsetSize : 1;\n        return this._createFromPositionAndShift(Position$1._createBefore(item), size);\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRange$1.prototype.is = function(type) {\n    return type === 'range' || type === 'view:range';\n};\n/**\n * Function used by getEnlarged and getTrimmed methods.\n */ function enlargeTrimSkip(value) {\n    if (value.item.is('attributeElement') || value.item.is('uiElement')) {\n        return true;\n    }\n    return false;\n}\n\n/**\n * Class representing an arbirtary selection in the view.\n * See also {@link module:engine/view/documentselection~DocumentSelection}.\n *\n * New selection instances can be created via the constructor or one these methods:\n *\n * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n *\n * A selection can consist of {@link module:engine/view/range~Range ranges} that can be set by using\n * the {@link module:engine/view/selection~Selection#setTo `Selection#setTo()`} method.\n */ let Selection$1 = class Selection extends /* #__PURE__ */ EmitterMixin(TypeCheckable$1) {\n    /**\n\t * Stores all ranges that are selected.\n\t */ _ranges;\n    /**\n\t * Specifies whether the last added range was added as a backward or forward range.\n\t */ _lastRangeBackward;\n    /**\n\t * Specifies whether selection instance is fake.\n\t */ _isFake;\n    /**\n\t * Fake selection's label.\n\t */ _fakeSelectionLabel;\n    /**\n\t * Creates new selection instance.\n\t *\n\t * **Note**: The selection constructor is available as a factory method:\n\t *\n\t * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n\t * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = writer.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = writer.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * const selection = writer.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = writer.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the document selection.\n\t * const selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * const selection = writer.createSelection( position );\n\t *\n\t * // Creates collapsed selection at the position of given item and offset.\n\t * const paragraph = writer.createContainerElement( 'paragraph' );\n\t * const selection = writer.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = writer.createSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * @internal\n\t */ constructor(...args){\n        super();\n        this._ranges = [];\n        this._lastRangeBackward = false;\n        this._isFake = false;\n        this._fakeSelectionLabel = '';\n        if (args.length) {\n            this.setTo(...args);\n        }\n    }\n    /**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #setTo\n\t */ get isFake() {\n        return this._isFake;\n    }\n    /**\n\t * Returns fake selection label.\n\t *\n\t * @see #setTo\n\t */ get fakeSelectionLabel() {\n        return this._fakeSelectionLabel;\n    }\n    /**\n\t * Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t * {@link #focus focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t * It may be a bit unintuitive when there are multiple ranges in selection.\n\t *\n\t * @see #focus\n\t */ get anchor() {\n        if (!this._ranges.length) {\n            return null;\n        }\n        const range = this._ranges[this._ranges.length - 1];\n        const anchor = this._lastRangeBackward ? range.end : range.start;\n        return anchor.clone();\n    }\n    /**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t */ get focus() {\n        if (!this._ranges.length) {\n            return null;\n        }\n        const range = this._ranges[this._ranges.length - 1];\n        const focus = this._lastRangeBackward ? range.start : range.end;\n        return focus.clone();\n    }\n    /**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t */ get isCollapsed() {\n        return this.rangeCount === 1 && this._ranges[0].isCollapsed;\n    }\n    /**\n\t * Returns number of ranges in selection.\n\t */ get rangeCount() {\n        return this._ranges.length;\n    }\n    /**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t */ get isBackward() {\n        return !this.isCollapsed && this._lastRangeBackward;\n    }\n    /**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t */ get editableElement() {\n        if (this.anchor) {\n            return this.anchor.editableElement;\n        }\n        return null;\n    }\n    /**\n\t * Returns an iterable that contains copies of all ranges added to the selection.\n\t */ *getRanges() {\n        for (const range of this._ranges){\n            yield range.clone();\n        }\n    }\n    /**\n\t * Returns copy of the first range in the selection. First range is the one which\n\t * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start\n\t * position of all other ranges (not to confuse with the first range added to the selection).\n\t * Returns `null` if no ranges are added to selection.\n\t */ getFirstRange() {\n        let first = null;\n        for (const range of this._ranges){\n            if (!first || range.start.isBefore(first.start)) {\n                first = range;\n            }\n        }\n        return first ? first.clone() : null;\n    }\n    /**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse\n\t * with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t */ getLastRange() {\n        let last = null;\n        for (const range of this._ranges){\n            if (!last || range.end.isAfter(last.end)) {\n                last = range;\n            }\n        }\n        return last ? last.clone() : null;\n    }\n    /**\n\t * Returns copy of the first position in the selection. First position is the position that\n\t * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */ getFirstPosition() {\n        const firstRange = this.getFirstRange();\n        return firstRange ? firstRange.start.clone() : null;\n    }\n    /**\n\t * Returns copy of the last position in the selection. Last position is the position that\n\t * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */ getLastPosition() {\n        const lastRange = this.getLastRange();\n        return lastRange ? lastRange.end.clone() : null;\n    }\n    /**\n\t * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t * same number of ranges and all ranges from one selection equal to a range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are equal, `false` otherwise.\n\t */ isEqual(otherSelection) {\n        if (this.isFake != otherSelection.isFake) {\n            return false;\n        }\n        if (this.isFake && this.fakeSelectionLabel != otherSelection.fakeSelectionLabel) {\n            return false;\n        }\n        if (this.rangeCount != otherSelection.rangeCount) {\n            return false;\n        } else if (this.rangeCount === 0) {\n            return true;\n        }\n        if (!this.anchor.isEqual(otherSelection.anchor) || !this.focus.isEqual(otherSelection.focus)) {\n            return false;\n        }\n        for (const thisRange of this._ranges){\n            let found = false;\n            for (const otherRange of otherSelection._ranges){\n                if (thisRange.isEqual(otherRange)) {\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are similar, `false` otherwise.\n\t */ isSimilar(otherSelection) {\n        if (this.isBackward != otherSelection.isBackward) {\n            return false;\n        }\n        const numOfRangesA = count(this.getRanges());\n        const numOfRangesB = count(otherSelection.getRanges());\n        // If selections have different number of ranges, they cannot be similar.\n        if (numOfRangesA != numOfRangesB) {\n            return false;\n        }\n        // If both selections have no ranges, they are similar.\n        if (numOfRangesA == 0) {\n            return true;\n        }\n        // Check if each range in one selection has a similar range in other selection.\n        for (let rangeA of this.getRanges()){\n            rangeA = rangeA.getTrimmed();\n            let found = false;\n            for (let rangeB of otherSelection.getRanges()){\n                rangeB = rangeB.getTrimmed();\n                if (rangeA.start.isEqual(rangeB.start) && rangeA.end.isEqual(rangeB.end)) {\n                    found = true;\n                    break;\n                }\n            }\n            // For `rangeA`, neither range in `otherSelection` was similar. So selections are not similar.\n            if (!found) {\n                return false;\n            }\n        }\n        // There were no ranges that weren't matched. Selections are similar.\n        return true;\n    }\n    /**\n\t * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */ getSelectedElement() {\n        if (this.rangeCount !== 1) {\n            return null;\n        }\n        return this.getFirstRange().getContainedElement();\n    }\n    /**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t * ```ts\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * selection.setTo( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * selection.setTo( range );\n\t *\n\t * // Sets selection to the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * selection.setTo( otherSelection );\n\t *\n\t * // Sets selection to contents of DocumentSelection.\n\t * selection.setTo( editor.editing.view.document.selection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPositionAt( root, path );\n\t * selection.setTo( position );\n\t *\n\t * // Sets collapsed selection at the position of given item and offset.\n\t * selection.setTo( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'on' );\n\t *\n\t * // Clears selection. Removes all ranges.\n\t * selection.setTo( null );\n\t * ```\n\t *\n\t * `Selection#setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * selection.setTo( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * selection.setTo( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * @fires change\n\t */ setTo(...args) {\n        let [selectable, placeOrOffset, options] = args;\n        if (typeof placeOrOffset == 'object') {\n            options = placeOrOffset;\n            placeOrOffset = undefined;\n        }\n        if (selectable === null) {\n            this._setRanges([]);\n            this._setFakeOptions(options);\n        } else if (selectable instanceof Selection || selectable instanceof DocumentSelection$1) {\n            this._setRanges(selectable.getRanges(), selectable.isBackward);\n            this._setFakeOptions({\n                fake: selectable.isFake,\n                label: selectable.fakeSelectionLabel\n            });\n        } else if (selectable instanceof Range$1) {\n            this._setRanges([\n                selectable\n            ], options && options.backward);\n            this._setFakeOptions(options);\n        } else if (selectable instanceof Position$1) {\n            this._setRanges([\n                new Range$1(selectable)\n            ]);\n            this._setFakeOptions(options);\n        } else if (selectable instanceof Node$2) {\n            const backward = !!options && !!options.backward;\n            let range;\n            if (placeOrOffset === undefined) {\n                /**\n\t\t\t\t * selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-setto-required-second-parameter\n\t\t\t\t */ throw new CKEditorError('view-selection-setto-required-second-parameter', this);\n            } else if (placeOrOffset == 'in') {\n                range = Range$1._createIn(selectable);\n            } else if (placeOrOffset == 'on') {\n                range = Range$1._createOn(selectable);\n            } else {\n                range = new Range$1(Position$1._createAt(selectable, placeOrOffset));\n            }\n            this._setRanges([\n                range\n            ], backward);\n            this._setFakeOptions(options);\n        } else if (isIterable(selectable)) {\n            // We assume that the selectable is an iterable of ranges.\n            // Array.from() is used to prevent setting ranges to the old iterable\n            this._setRanges(selectable, options && options.backward);\n            this._setFakeOptions(options);\n        } else {\n            /**\n\t\t\t * Cannot set selection to given place.\n\t\t\t *\n\t\t\t * @error view-selection-setto-not-selectable\n\t\t\t */ throw new CKEditorError('view-selection-setto-not-selectable', this);\n        }\n        this.fire('change');\n    }\n    /**\n\t * Moves {@link #focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @fires change\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */ setFocus(itemOrPosition, offset) {\n        if (this.anchor === null) {\n            /**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error view-selection-setfocus-no-ranges\n\t\t\t */ throw new CKEditorError('view-selection-setfocus-no-ranges', this);\n        }\n        const newFocus = Position$1._createAt(itemOrPosition, offset);\n        if (newFocus.compareWith(this.focus) == 'same') {\n            return;\n        }\n        const anchor = this.anchor;\n        this._ranges.pop();\n        if (newFocus.compareWith(anchor) == 'before') {\n            this._addRange(new Range$1(newFocus, anchor), true);\n        } else {\n            this._addRange(new Range$1(anchor, newFocus));\n        }\n        this.fire('change');\n    }\n    /**\n\t * Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t * is treated like the last added range and is used to set {@link #anchor anchor} and {@link #focus focus}.\n\t * Accepts a flag describing in which way the selection is made.\n\t *\n\t * @param newRanges Iterable object of ranges to set.\n\t * @param isLastBackward Flag describing if last added range was selected forward - from start to end\n\t * (`false`) or backward - from end to start (`true`). Defaults to `false`.\n\t */ _setRanges(newRanges, isLastBackward = false) {\n        // New ranges should be copied to prevent removing them by setting them to `[]` first.\n        // Only applies to situations when selection is set to the same selection or same selection's ranges.\n        newRanges = Array.from(newRanges);\n        this._ranges = [];\n        for (const range of newRanges){\n            this._addRange(range);\n        }\n        this._lastRangeBackward = !!isLastBackward;\n    }\n    /**\n\t * Sets this selection instance to be marked as `fake`. A fake selection does not render as browser native selection\n\t * over selected elements and is hidden to the user. This way, no native selection UI artifacts are displayed to\n\t * the user and selection over elements can be represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM (and be\n\t * properly handled by screen readers).\n\t */ _setFakeOptions(options = {}) {\n        this._isFake = !!options.fake;\n        this._fakeSelectionLabel = options.fake ? options.label || '' : '';\n    }\n    /**\n\t * Adds a range to the selection. Added range is copied. This means that passed range is not saved in the\n\t * selection instance and you can safely operate on it.\n\t *\n\t * Accepts a flag describing in which way the selection is made - passed range might be selected from\n\t * {@link module:engine/view/range~Range#start start} to {@link module:engine/view/range~Range#end end}\n\t * or from {@link module:engine/view/range~Range#end end} to {@link module:engine/view/range~Range#start start}.\n\t * The flag is used to set {@link #anchor anchor} and {@link #focus focus} properties.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in Selection instance.\n\t */ _addRange(range, isBackward = false) {\n        if (!(range instanceof Range$1)) {\n            /**\n\t\t\t * Selection range set to an object that is not an instance of {@link module:engine/view/range~Range}.\n\t\t\t *\n\t\t\t * @error view-selection-add-range-not-range\n\t\t\t */ throw new CKEditorError('view-selection-add-range-not-range', this);\n        }\n        this._pushRange(range);\n        this._lastRangeBackward = !!isBackward;\n    }\n    /**\n\t * Adds range to selection - creates copy of given range so it can be safely used and modified.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in selection instance.\n\t */ _pushRange(range) {\n        for (const storedRange of this._ranges){\n            if (range.isIntersecting(storedRange)) {\n                /**\n\t\t\t\t * Trying to add a range that intersects with another range from selection.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-range-intersects\n\t\t\t\t * @param {module:engine/view/range~Range} addedRange Range that was added to the selection.\n\t\t\t\t * @param {module:engine/view/range~Range} intersectingRange Range from selection that intersects with `addedRange`.\n\t\t\t\t */ throw new CKEditorError('view-selection-range-intersects', this, {\n                    addedRange: range,\n                    intersectingRange: storedRange\n                });\n            }\n        }\n        this._ranges.push(new Range$1(range.start, range.end));\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nSelection$1.prototype.is = function(type) {\n    return type === 'selection' || type === 'view:selection';\n};\n\n/**\n * Class representing the document selection in the view.\n *\n * Its instance is available in {@link module:engine/view/document~Document#selection `Document#selection`}.\n *\n * It is similar to {@link module:engine/view/selection~Selection} but\n * it has a read-only API and can be modified only by the writer available in\n * the {@link module:engine/view/view~View#change `View#change()`} block\n * (so via {@link module:engine/view/downcastwriter~DowncastWriter#setSelection `DowncastWriter#setSelection()`}).\n */ let DocumentSelection$1 = class DocumentSelection extends /* #__PURE__ */ EmitterMixin(TypeCheckable$1) {\n    /**\n\t * Selection is used internally (`DocumentSelection` is a proxy to that selection).\n\t */ _selection;\n    constructor(...args){\n        super();\n        this._selection = new Selection$1();\n        // Delegate change event to be fired on DocumentSelection instance.\n        this._selection.delegate('change').to(this);\n        // Set selection data.\n        if (args.length) {\n            this._selection.setTo(...args);\n        }\n    }\n    /**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #_setTo\n\t */ get isFake() {\n        return this._selection.isFake;\n    }\n    /**\n\t * Returns fake selection label.\n\t *\n\t * @see #_setTo\n\t */ get fakeSelectionLabel() {\n        return this._selection.fakeSelectionLabel;\n    }\n    /**\n\t * Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t * {@link #focus focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t * It may be a bit unintuitive when there are multiple ranges in selection.\n\t *\n\t * @see #focus\n\t */ get anchor() {\n        return this._selection.anchor;\n    }\n    /**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t */ get focus() {\n        return this._selection.focus;\n    }\n    /**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t */ get isCollapsed() {\n        return this._selection.isCollapsed;\n    }\n    /**\n\t * Returns number of ranges in selection.\n\t */ get rangeCount() {\n        return this._selection.rangeCount;\n    }\n    /**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t */ get isBackward() {\n        return this._selection.isBackward;\n    }\n    /**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t */ get editableElement() {\n        return this._selection.editableElement;\n    }\n    /**\n\t * Used for the compatibility with the {@link module:engine/view/selection~Selection#isEqual} method.\n\t *\n\t * @internal\n\t */ get _ranges() {\n        return this._selection._ranges;\n    }\n    /**\n\t * Returns an iterable that contains copies of all ranges added to the selection.\n\t */ *getRanges() {\n        yield* this._selection.getRanges();\n    }\n    /**\n\t * Returns copy of the first range in the selection. First range is the one which\n\t * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start\n\t * position of all other ranges (not to confuse with the first range added to the selection).\n\t * Returns `null` if no ranges are added to selection.\n\t */ getFirstRange() {\n        return this._selection.getFirstRange();\n    }\n    /**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse\n\t * with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t */ getLastRange() {\n        return this._selection.getLastRange();\n    }\n    /**\n\t * Returns copy of the first position in the selection. First position is the position that\n\t * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */ getFirstPosition() {\n        return this._selection.getFirstPosition();\n    }\n    /**\n\t * Returns copy of the last position in the selection. Last position is the position that\n\t * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */ getLastPosition() {\n        return this._selection.getLastPosition();\n    }\n    /**\n\t * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */ getSelectedElement() {\n        return this._selection.getSelectedElement();\n    }\n    /**\n\t * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t * same number of ranges and all ranges from one selection equal to a range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are equal, `false` otherwise.\n\t */ isEqual(otherSelection) {\n        return this._selection.isEqual(otherSelection);\n    }\n    /**\n\t * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are similar, `false` otherwise.\n\t */ isSimilar(otherSelection) {\n        return this._selection.isSimilar(otherSelection);\n    }\n    /**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t * ```ts\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * documentSelection._setTo( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];\n\t * documentSelection._setTo( range );\n\t *\n\t * // Sets selection to the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * documentSelection._setTo( otherSelection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPositionAt( root, offset );\n\t * documentSelection._setTo( position );\n\t *\n\t * // Sets collapsed selection at the position of given item and offset.\n\t * documentSelection._setTo( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * documentSelection._setTo( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * documentSelection._setTo( paragraph, 'on' );\n\t *\n\t * // Clears selection. Removes all ranges.\n\t * documentSelection._setTo( null );\n\t * ```\n\t *\n\t * `Selection#_setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * documentSelection._setTo( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to des cribe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * documentSelection._setTo( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * @internal\n\t * @fires change\n\t */ _setTo(...args) {\n        this._selection.setTo(...args);\n    }\n    /**\n\t * Moves {@link #focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @internal\n\t * @fires change\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */ _setFocus(itemOrPosition, offset) {\n        this._selection.setFocus(itemOrPosition, offset);\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentSelection$1.prototype.is = function(type) {\n    return type === 'selection' || type == 'documentSelection' || type == 'view:selection' || type == 'view:documentSelection';\n};\n\n/**\n * The event object passed to bubbling event callbacks. It is used to provide information about the event as well as a tool to\n * manipulate it.\n */ class BubblingEventInfo extends EventInfo {\n    /**\n\t * The view range that the bubbling should start from.\n\t */ startRange;\n    /**\n\t * The current event phase.\n\t */ _eventPhase;\n    /**\n\t * The current bubbling target.\n\t */ _currentTarget;\n    /**\n\t * @param source The emitter.\n\t * @param name The event name.\n\t * @param startRange The view range that the bubbling should start from.\n\t */ constructor(source, name, startRange){\n        super(source, name);\n        this.startRange = startRange;\n        this._eventPhase = 'none';\n        this._currentTarget = null;\n    }\n    /**\n\t * The current event phase.\n\t */ get eventPhase() {\n        return this._eventPhase;\n    }\n    /**\n\t * The current bubbling target.\n\t */ get currentTarget() {\n        return this._currentTarget;\n    }\n}\n\nconst contextsSymbol = Symbol('bubbling contexts');\n/**\n * Bubbling emitter mixin for the view document as described in the {@link ~BubblingEmitter} interface.\n *\n * This function creates a class that inherits from the provided `base` and implements `Emitter` interface.\n * The base class must implement {@link module:utils/emittermixin~Emitter} interface.\n *\n * ```ts\n * class BaseClass extends EmitterMixin() {\n * \t// ...\n * }\n *\n * class MyClass extends BubblingEmitterMixin( BaseClass ) {\n * \t// This class derives from `BaseClass` and implements the `BubblingEmitter` interface.\n * }\n * ```\n */ function BubblingEmitterMixin(base) {\n    class Mixin extends base {\n        fire(eventOrInfo, ...eventArgs) {\n            try {\n                const eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo(this, eventOrInfo);\n                const eventContexts = getBubblingContexts(this);\n                if (!eventContexts.size) {\n                    return;\n                }\n                updateEventInfo(eventInfo, 'capturing', this);\n                // The capture phase of the event.\n                if (fireListenerFor(eventContexts, '$capture', eventInfo, ...eventArgs)) {\n                    return eventInfo.return;\n                }\n                const startRange = eventInfo.startRange || this.selection.getFirstRange();\n                const selectedElement = startRange ? startRange.getContainedElement() : null;\n                const isCustomContext = selectedElement ? Boolean(getCustomContext(eventContexts, selectedElement)) : false;\n                let node = selectedElement || getDeeperRangeParent(startRange);\n                updateEventInfo(eventInfo, 'atTarget', node);\n                // For the not yet bubbling event trigger for $text node if selection can be there and it's not a custom context selected.\n                if (!isCustomContext) {\n                    if (fireListenerFor(eventContexts, '$text', eventInfo, ...eventArgs)) {\n                        return eventInfo.return;\n                    }\n                    updateEventInfo(eventInfo, 'bubbling', node);\n                }\n                while(node){\n                    // Root node handling.\n                    if (node.is('rootElement')) {\n                        if (fireListenerFor(eventContexts, '$root', eventInfo, ...eventArgs)) {\n                            return eventInfo.return;\n                        }\n                    } else if (node.is('element')) {\n                        if (fireListenerFor(eventContexts, node.name, eventInfo, ...eventArgs)) {\n                            return eventInfo.return;\n                        }\n                    }\n                    // Check custom contexts (i.e., a widget).\n                    if (fireListenerFor(eventContexts, node, eventInfo, ...eventArgs)) {\n                        return eventInfo.return;\n                    }\n                    node = node.parent;\n                    updateEventInfo(eventInfo, 'bubbling', node);\n                }\n                updateEventInfo(eventInfo, 'bubbling', this);\n                // Document context.\n                fireListenerFor(eventContexts, '$document', eventInfo, ...eventArgs);\n                return eventInfo.return;\n            } catch (err) {\n                // @if CK_DEBUG // throw err;\n                /* istanbul ignore next -- @preserve */ CKEditorError.rethrowUnexpectedError(err, this);\n            }\n        }\n        _addEventListener(event, callback, options) {\n            const contexts = toArray(options.context || '$document');\n            const eventContexts = getBubblingContexts(this);\n            for (const context of contexts){\n                let emitter = eventContexts.get(context);\n                if (!emitter) {\n                    emitter = new (EmitterMixin())();\n                    eventContexts.set(context, emitter);\n                }\n                this.listenTo(emitter, event, callback, options);\n            }\n        }\n        _removeEventListener(event, callback) {\n            const eventContexts = getBubblingContexts(this);\n            for (const emitter of eventContexts.values()){\n                this.stopListening(emitter, event, callback);\n            }\n        }\n    }\n    return Mixin;\n}\n// Backward compatibility with `mix`.\n{\n    const mixin = BubblingEmitterMixin(Object);\n    [\n        'fire',\n        '_addEventListener',\n        '_removeEventListener'\n    ].forEach((key)=>{\n        BubblingEmitterMixin[key] = mixin.prototype[key];\n    });\n}/**\n * Update the event info bubbling fields.\n *\n * @param eventInfo The event info object to update.\n * @param eventPhase The current event phase.\n * @param currentTarget The current bubbling target.\n */ function updateEventInfo(eventInfo, eventPhase, currentTarget) {\n    if (eventInfo instanceof BubblingEventInfo) {\n        eventInfo._eventPhase = eventPhase;\n        eventInfo._currentTarget = currentTarget;\n    }\n}\n/**\n * Fires the listener for the specified context. Returns `true` if event was stopped.\n *\n * @param eventInfo The `EventInfo` object.\n * @param eventArgs Additional arguments to be passed to the callbacks.\n * @returns True if event stop was called.\n */ function fireListenerFor(eventContexts, context, eventInfo, ...eventArgs) {\n    const emitter = typeof context == 'string' ? eventContexts.get(context) : getCustomContext(eventContexts, context);\n    if (!emitter) {\n        return false;\n    }\n    emitter.fire(eventInfo, ...eventArgs);\n    return eventInfo.stop.called;\n}\n/**\n * Returns an emitter for a specified view node.\n */ function getCustomContext(eventContexts, node) {\n    for (const [context, emitter] of eventContexts){\n        if (typeof context == 'function' && context(node)) {\n            return emitter;\n        }\n    }\n    return null;\n}\n/**\n * Returns bubbling contexts map for the source (emitter).\n */ function getBubblingContexts(source) {\n    if (!source[contextsSymbol]) {\n        source[contextsSymbol] = new Map();\n    }\n    return source[contextsSymbol];\n}\n/**\n * Returns the deeper parent element for the range.\n */ function getDeeperRangeParent(range) {\n    if (!range) {\n        return null;\n    }\n    const startParent = range.start.parent;\n    const endParent = range.end.parent;\n    const startPath = startParent.getPath();\n    const endPath = endParent.getPath();\n    return startPath.length > endPath.length ? startParent : endParent;\n}\n\n// @if CK_DEBUG_ENGINE // const { logDocument } = require( '../dev-utils/utils' );\n/**\n * Document class creates an abstract layer over the content editable area, contains a tree of view elements and\n * {@link module:engine/view/documentselection~DocumentSelection view selection} associated with this document.\n */ let Document$1 = class Document extends /* #__PURE__ */ BubblingEmitterMixin(/* #__PURE__ */ ObservableMixin()) {\n    /**\n\t * Selection done on this document.\n\t */ selection;\n    /**\n\t * Roots of the view tree. Collection of the {@link module:engine/view/element~Element view elements}.\n\t *\n\t * View roots are created as a result of binding between {@link module:engine/view/document~Document#roots} and\n\t * {@link module:engine/model/document~Document#roots} and this is handled by\n\t * {@link module:engine/controller/editingcontroller~EditingController}, so to create view root we need to create\n\t * model root using {@link module:engine/model/document~Document#createRoot}.\n\t */ roots;\n    /**\n\t * The styles processor instance used by this document when normalizing styles.\n\t */ stylesProcessor;\n    /**\n\t * Post-fixer callbacks registered to the view document.\n\t */ _postFixers = new Set();\n    /**\n\t * Creates a Document instance.\n\t *\n\t * @param stylesProcessor The styles processor instance.\n\t */ constructor(stylesProcessor){\n        super();\n        this.selection = new DocumentSelection$1();\n        this.roots = new Collection({\n            idProperty: 'rootName'\n        });\n        this.stylesProcessor = stylesProcessor;\n        this.set('isReadOnly', false);\n        this.set('isFocused', false);\n        this.set('isSelecting', false);\n        this.set('isComposing', false);\n    }\n    /**\n\t * Gets a {@link module:engine/view/document~Document#roots view root element} with the specified name. If the name is not\n\t * specific \"main\" root is returned.\n\t *\n\t * @param name Name of the root.\n\t * @returns The view root element with the specified name or null when there is no root of given name.\n\t */ getRoot(name = 'main') {\n        return this.roots.get(name);\n    }\n    /**\n\t * Allows registering post-fixer callbacks. A post-fixers mechanism allows to update the view tree just before it is rendered\n\t * to the DOM.\n\t *\n\t * Post-fixers are executed right after all changes from the outermost change block were applied but\n\t * before the {@link module:engine/view/view~View#event:render render event} is fired. If a post-fixer callback made\n\t * a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t * not be fixed in the new document tree state.\n\t *\n\t * View post-fixers are useful when you want to apply some fixes whenever the view structure changes. Keep in mind that\n\t * changes executed in a view post-fixer should not break model-view mapping.\n\t *\n\t * The types of changes which should be safe:\n\t *\n\t * * adding or removing attribute from elements,\n\t * * changes inside of {@link module:engine/view/uielement~UIElement UI elements},\n\t * * {@link module:engine/controller/editingcontroller~EditingController#reconvertItem marking some of the model elements to be\n\t * re-converted}.\n\t *\n\t * Try to avoid changes which touch view structure:\n\t *\n\t * * you should not add or remove nor wrap or unwrap any view elements,\n\t * * you should not change the editor data model in a view post-fixer.\n\t *\n\t * As a parameter, a post-fixer callback receives a {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}.\n\t *\n\t * Typically, a post-fixer will look like this:\n\t *\n\t * ```ts\n\t * editor.editing.view.document.registerPostFixer( writer => {\n\t * \tif ( checkSomeCondition() ) {\n\t * \t\twriter.doSomething();\n\t *\n\t * \t\t// Let other post-fixers know that something changed.\n\t * \t\treturn true;\n\t * \t}\n\t *\n\t * \treturn false;\n\t * } );\n\t * ```\n\t *\n\t * Note that nothing happens right after you register a post-fixer (e.g. execute such a code in the console).\n\t * That is because adding a post-fixer does not execute it.\n\t * The post-fixer will be executed as soon as any change in the document needs to cause its rendering.\n\t * If you want to re-render the editor's view after registering the post-fixer then you should do it manually by calling\n\t * {@link module:engine/view/view~View#forceRender `view.forceRender()`}.\n\t *\n\t * If you need to register a callback which is executed when DOM elements are already updated,\n\t * use {@link module:engine/view/view~View#event:render render event}.\n\t */ registerPostFixer(postFixer) {\n        this._postFixers.add(postFixer);\n    }\n    /**\n\t * Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t */ destroy() {\n        this.roots.forEach((root)=>root.destroy());\n        this.stopListening();\n    }\n    /**\n\t * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t *\n\t * @internal\n\t */ _callPostFixers(writer) {\n        let wasFixed = false;\n        do {\n            for (const callback of this._postFixers){\n                wasFixed = callback(writer);\n                if (wasFixed) {\n                    break;\n                }\n            }\n        }while (wasFixed)\n    }\n};\n\n// Default attribute priority.\nconst DEFAULT_PRIORITY = 10;\n/**\n * Attribute elements are used to represent formatting elements in the view (think – `<b>`, `<span style=\"font-size: 2em\">`, etc.).\n * Most often they are created when downcasting model text attributes.\n *\n * Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n * types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.\n *\n * To create a new attribute element instance use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `DowncastWriter#createAttributeElement()`} method.\n */ class AttributeElement extends Element$1 {\n    static DEFAULT_PRIORITY = DEFAULT_PRIORITY;\n    /**\n\t * Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t *\n\t * @internal\n\t * @readonly\n\t */ _priority = DEFAULT_PRIORITY;\n    /**\n\t * Element identifier. If set, it is used by {@link module:engine/view/element~Element#isSimilar},\n\t * and then two elements are considered similar if, and only if they have the same `_id`.\n\t *\n\t * @internal\n\t * @readonly\n\t */ _id = null;\n    /**\n\t * Keeps all the attribute elements that have the same {@link module:engine/view/attributeelement~AttributeElement#id ids}\n\t * and still exist in the view tree.\n\t *\n\t * This property is managed by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t */ _clonesGroup = null;\n    /**\n\t * Creates an attribute element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createAttributeElement\n\t * @see module:engine/view/element~Element\n\t * @protected\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */ constructor(document, name, attrs, children){\n        super(document, name, attrs, children);\n        this.getFillerOffset = getFillerOffset$3;\n    }\n    /**\n\t * Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t */ get priority() {\n        return this._priority;\n    }\n    /**\n\t * Element identifier. If set, it is used by {@link module:engine/view/element~Element#isSimilar},\n\t * and then two elements are considered similar if, and only if they have the same `id`.\n\t */ get id() {\n        return this._id;\n    }\n    /**\n\t * Returns all {@link module:engine/view/attributeelement~AttributeElement attribute elements} that has the\n\t * same {@link module:engine/view/attributeelement~AttributeElement#id id} and are in the view tree (were not removed).\n\t *\n\t * Note: If this element has been removed from the tree, returned set will not include it.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError attribute-element-get-elements-with-same-id-no-id}\n\t * if this element has no `id`.\n\t *\n\t * @returns Set containing all the attribute elements\n\t * with the same `id` that were added and not removed from the view tree.\n\t */ getElementsWithSameId() {\n        if (this.id === null) {\n            /**\n\t\t\t * Cannot get elements with the same id for an attribute element without id.\n\t\t\t *\n\t\t\t * @error attribute-element-get-elements-with-same-id-no-id\n\t\t\t */ throw new CKEditorError('attribute-element-get-elements-with-same-id-no-id', this);\n        }\n        return new Set(this._clonesGroup);\n    }\n    /**\n\t * Checks if this element is similar to other element.\n\t *\n\t * If none of elements has set {@link module:engine/view/attributeelement~AttributeElement#id}, then both elements\n\t * should have the same name, attributes and priority to be considered as similar. Two similar elements can contain\n\t * different set of children nodes.\n\t *\n\t * If at least one element has {@link module:engine/view/attributeelement~AttributeElement#id} set, then both\n\t * elements have to have the same {@link module:engine/view/attributeelement~AttributeElement#id} value to be\n\t * considered similar.\n\t *\n\t * Similarity is important for {@link module:engine/view/downcastwriter~DowncastWriter}. For example:\n\t *\n\t * * two following similar elements can be merged together into one, longer element,\n\t * * {@link module:engine/view/downcastwriter~DowncastWriter#unwrap} checks similarity of passed element and processed element to\n\t * decide whether processed element should be unwrapped,\n\t * * etc.\n\t */ isSimilar(otherElement) {\n        // If any element has an `id` set, just compare the ids.\n        if (this.id !== null || otherElement.id !== null) {\n            return this.id === otherElement.id;\n        }\n        return super.isSimilar(otherElement) && this.priority == otherElement.priority;\n    }\n    /**\n\t * Clones provided element with priority.\n\t *\n\t * @internal\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns Clone of this element.\n\t */ _clone(deep = false) {\n        const cloned = super._clone(deep);\n        // Clone priority too.\n        cloned._priority = this._priority;\n        // And id too.\n        cloned._id = this._id;\n        return cloned;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nAttributeElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'attributeElement' || type === 'view:attributeElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'element' || type === 'view:element' || type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'attributeElement' || type === 'view:attributeElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'element' || type === 'view:element');\n    }\n};\n/**\n * Returns block {@link module:engine/view/filler~Filler filler} offset or `null` if block filler is not needed.\n *\n * @returns Block filler offset or `null` if block filler is not needed.\n */ function getFillerOffset$3() {\n    // <b>foo</b> does not need filler.\n    if (nonUiChildrenCount(this)) {\n        return null;\n    }\n    let element = this.parent;\n    // <p><b></b></p> needs filler -> <p><b><br></b></p>\n    while(element && element.is('attributeElement')){\n        if (nonUiChildrenCount(element) > 1) {\n            return null;\n        }\n        element = element.parent;\n    }\n    if (!element || nonUiChildrenCount(element) > 1) {\n        return null;\n    }\n    // Render block filler at the end of element (after all ui elements).\n    return this.childCount;\n}\n/**\n * Returns total count of children that are not {@link module:engine/view/uielement~UIElement UIElements}.\n */ function nonUiChildrenCount(element) {\n    return Array.from(element.getChildren()).filter((element)=>!element.is('uiElement')).length;\n}\n\n/**\n * Empty element class. It is used to represent elements that cannot contain any child nodes (for example `<img>` elements).\n *\n * To create a new empty element use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`} method.\n */ class EmptyElement extends Element$1 {\n    /**\n\t * Creates new instance of EmptyElement.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` when third parameter is passed,\n\t * to inform that usage of EmptyElement is incorrect (adding child nodes to EmptyElement is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createEmptyElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */ constructor(document, name, attributes, children){\n        super(document, name, attributes, children);\n        this.getFillerOffset = getFillerOffset$2;\n    }\n    /**\n\t * Overrides {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` to prevent\n\t * adding any child nodes to EmptyElement.\n\t *\n\t * @internal\n\t */ _insertChild(index, items) {\n        if (items && (items instanceof Node$2 || Array.from(items).length > 0)) {\n            /**\n\t\t\t * Cannot add children to {@link module:engine/view/emptyelement~EmptyElement}.\n\t\t\t *\n\t\t\t * @error view-emptyelement-cannot-add\n\t\t\t */ throw new CKEditorError('view-emptyelement-cannot-add', [\n                this,\n                items\n            ]);\n        }\n        return 0;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nEmptyElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'emptyElement' || type === 'view:emptyElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'element' || type === 'view:element' || type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'emptyElement' || type === 'view:emptyElement' || type === 'element' || type === 'view:element');\n    }\n};\n/**\n * Returns `null` because block filler is not needed for EmptyElements.\n */ function getFillerOffset$2() {\n    return null;\n}\n\n/**\n * UI element class. It should be used to represent editing UI which needs to be injected into the editing view\n * If possible, you should keep your UI outside the editing view. However, if that is not possible,\n * UI elements can be used.\n *\n * How a UI element is rendered is in your control (you pass a callback to\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}).\n * The editor will ignore your UI element – the selection cannot be placed in it, it is skipped (invisible) when\n * the user modifies the selection by using arrow keys and the editor does not listen to any mutations which\n * happen inside your UI elements.\n *\n * The limitation is that you cannot convert a model element to a UI element. UI elements need to be\n * created for {@link module:engine/model/markercollection~Marker markers} or as additinal elements\n * inside normal {@link module:engine/view/containerelement~ContainerElement container elements}.\n *\n * To create a new UI element use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`} method.\n */ class UIElement extends Element$1 {\n    /**\n\t * Creates new instance of UIElement.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` when third parameter is passed,\n\t * to inform that usage of UIElement is incorrect (adding child nodes to UIElement is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createUIElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */ constructor(document, name, attrs, children){\n        super(document, name, attrs, children);\n        this.getFillerOffset = getFillerOffset$1;\n    }\n    /**\n\t * Overrides {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` to prevent adding any child nodes\n\t * to UIElement.\n\t *\n\t * @internal\n\t */ _insertChild(index, items) {\n        if (items && (items instanceof Node$2 || Array.from(items).length > 0)) {\n            /**\n\t\t\t * Cannot add children to {@link module:engine/view/uielement~UIElement}.\n\t\t\t *\n\t\t\t * @error view-uielement-cannot-add\n\t\t\t */ throw new CKEditorError('view-uielement-cannot-add', [\n                this,\n                items\n            ]);\n        }\n        return 0;\n    }\n    /**\n\t * Renders this {@link module:engine/view/uielement~UIElement} to DOM. This method is called by\n\t * {@link module:engine/view/domconverter~DomConverter}.\n\t * Do not use inheritance to create custom rendering method, replace `render()` method instead:\n\t *\n\t * ```ts\n\t * const myUIElement = downcastWriter.createUIElement( 'span' );\n\t * myUIElement.render = function( domDocument, domConverter ) {\n\t * \tconst domElement = this.toDomElement( domDocument );\n\t *\n\t * \tdomConverter.setContentOf( domElement, '<b>this is ui element</b>' );\n\t *\n\t * \treturn domElement;\n\t * };\n\t * ```\n\t *\n\t * If changes in your UI element should trigger some editor UI update you should call\n\t * the {@link module:ui/editorui/editorui~EditorUI#update `editor.ui.update()`} method\n\t * after rendering your UI element.\n\t *\n\t * @param domConverter Instance of the DomConverter used to optimize the output.\n\t */ render(domDocument, domConverter// eslint-disable-line @typescript-eslint/no-unused-vars\n    ) {\n        // Provide basic, default output.\n        return this.toDomElement(domDocument);\n    }\n    /**\n\t * Creates DOM element based on this view UIElement.\n\t * Note that each time this method is called new DOM element is created.\n\t */ toDomElement(domDocument) {\n        const domElement = domDocument.createElement(this.name);\n        for (const key of this.getAttributeKeys()){\n            domElement.setAttribute(key, this.getAttribute(key));\n        }\n        return domElement;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nUIElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'uiElement' || type === 'view:uiElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'element' || type === 'view:element' || type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'uiElement' || type === 'view:uiElement' || type === 'element' || type === 'view:element');\n    }\n};\n/**\n * This function injects UI element handling to the given {@link module:engine/view/document~Document document}.\n *\n * A callback is added to {@link module:engine/view/document~Document#event:keydown document keydown event}.\n * The callback handles the situation when right arrow key is pressed and selection is collapsed before a UI element.\n * Without this handler, it would be impossible to \"jump over\" UI element using right arrow key.\n *\n * @param view View controller to which the quirks handling will be injected.\n */ function injectUiElementHandling(view) {\n    view.document.on('arrowKey', (evt, data)=>jumpOverUiElement(evt, data, view.domConverter), {\n        priority: 'low'\n    });\n}\n/**\n * Returns `null` because block filler is not needed for UIElements.\n */ function getFillerOffset$1() {\n    return null;\n}\n/**\n * Selection cannot be placed in a `UIElement`. Whenever it is placed there, it is moved before it. This\n * causes a situation when it is impossible to jump over `UIElement` using right arrow key, because the selection\n * ends up in ui element (in DOM) and is moved back to the left. This handler fixes this situation.\n */ function jumpOverUiElement(evt, data, domConverter) {\n    if (data.keyCode == keyCodes.arrowright) {\n        const domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n        const domSelectionCollapsed = domSelection.rangeCount == 1 && domSelection.getRangeAt(0).collapsed;\n        // Jump over UI element if selection is collapsed or shift key is pressed. These are the cases when selection would extend.\n        if (domSelectionCollapsed || data.shiftKey) {\n            const domParent = domSelection.focusNode;\n            const domOffset = domSelection.focusOffset;\n            const viewPosition = domConverter.domPositionToView(domParent, domOffset);\n            // In case if dom element is not converted to view or is not mapped or something. Happens for example in some tests.\n            if (viewPosition === null) {\n                return;\n            }\n            // Skip all following ui elements.\n            let jumpedOverAnyUiElement = false;\n            const nextViewPosition = viewPosition.getLastMatchingPosition((value)=>{\n                if (value.item.is('uiElement')) {\n                    // Remember that there was at least one ui element.\n                    jumpedOverAnyUiElement = true;\n                }\n                // Jump over ui elements, jump over empty attribute elements, move up from inside of attribute element.\n                if (value.item.is('uiElement') || value.item.is('attributeElement')) {\n                    return true;\n                }\n                // Don't jump over text or don't get out of container element.\n                return false;\n            });\n            // If anything has been skipped, fix position.\n            // This `if` could be possibly omitted but maybe it is better not to mess with DOM selection if not needed.\n            if (jumpedOverAnyUiElement) {\n                const newDomPosition = domConverter.viewPositionToDom(nextViewPosition);\n                if (domSelectionCollapsed) {\n                    // Selection was collapsed, so collapse it at further position.\n                    domSelection.collapse(newDomPosition.parent, newDomPosition.offset);\n                } else {\n                    // Selection was not collapse, so extend it instead of collapsing.\n                    domSelection.extend(newDomPosition.parent, newDomPosition.offset);\n                }\n            }\n        }\n    }\n}\n\n/**\n * The raw element class.\n *\n * The raw elements work as data containers (\"wrappers\", \"sandboxes\") but their children are not managed or\n * even recognized by the editor. This encapsulation allows integrations to maintain custom DOM structures\n * in the editor content without, for instance, worrying about compatibility with other editor features.\n * Raw elements are a perfect tool for integration with external frameworks and data sources.\n *\n * Unlike {@link module:engine/view/uielement~UIElement UI elements}, raw elements act like real editor\n * content (similar to {@link module:engine/view/containerelement~ContainerElement} or\n * {@link module:engine/view/emptyelement~EmptyElement}), they are considered by the editor selection and\n * {@link module:widget/utils~toWidget they can work as widgets}.\n *\n * To create a new raw element, use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createRawElement `downcastWriter#createRawElement()`} method.\n */ class RawElement extends Element$1 {\n    /**\n\t * Creates a new instance of a raw element.\n\t *\n\t * Throws the `view-rawelement-cannot-add` {@link module:utils/ckeditorerror~CKEditorError CKEditorError} when the `children`\n\t * parameter is passed to inform that the usage of `RawElement` is incorrect (adding child nodes to `RawElement` is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createRawElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */ constructor(document, name, attrs, children){\n        super(document, name, attrs, children);\n        // Returns `null` because filler is not needed for raw elements.\n        this.getFillerOffset = getFillerOffset;\n    }\n    /**\n\t * Overrides the {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws the `view-rawelement-cannot-add` {@link module:utils/ckeditorerror~CKEditorError CKEditorError} to prevent\n\t * adding any child nodes to a raw element.\n\t *\n\t * @internal\n\t */ _insertChild(index, items) {\n        if (items && (items instanceof Node$2 || Array.from(items).length > 0)) {\n            /**\n\t\t\t * Cannot add children to a {@link module:engine/view/rawelement~RawElement} instance.\n\t\t\t *\n\t\t\t * @error view-rawelement-cannot-add\n\t\t\t */ throw new CKEditorError('view-rawelement-cannot-add', [\n                this,\n                items\n            ]);\n        }\n        return 0;\n    }\n    /**\n\t * This allows rendering the children of a {@link module:engine/view/rawelement~RawElement} on the DOM level.\n\t * This method is called by the {@link module:engine/view/domconverter~DomConverter} with the raw DOM element\n\t * passed as an argument, leaving the number and shape of the children up to the integrator.\n\t *\n\t * This method **must be defined** for the raw element to work:\n\t *\n\t * ```ts\n\t * const myRawElement = downcastWriter.createRawElement( 'div' );\n\t *\n\t * myRawElement.render = function( domElement, domConverter ) {\n\t * \tdomConverter.setContentOf( domElement, '<b>This is the raw content of myRawElement.</b>' );\n\t * };\n\t * ```\n\t *\n\t * @param domElement The native DOM element representing the raw view element.\n\t * @param domConverter Instance of the DomConverter used to optimize the output.\n\t */ render(domElement, domConverter) {}\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRawElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'rawElement' || type === 'view:rawElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === this.name || type === 'view:' + this.name || type === 'element' || type === 'view:element' || type === 'node' || type === 'view:node';\n    } else {\n        return name === this.name && (type === 'rawElement' || type === 'view:rawElement' || type === 'element' || type === 'view:element');\n    }\n};\n/**\n * Returns `null` because block filler is not needed for raw elements.\n */ function getFillerOffset() {\n    return null;\n}\n\n/**\n * Document fragment.\n *\n * To create a new document fragment instance use the\n * {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment `UpcastWriter#createDocumentFragment()`}\n * method.\n */ let DocumentFragment$1 = class DocumentFragment extends /* #__PURE__ */ EmitterMixin(TypeCheckable$1) {\n    /**\n\t * The document to which this document fragment belongs.\n\t */ document;\n    /**\n\t * Array of child nodes.\n\t */ _children = [];\n    /**\n\t * Map of custom properties.\n\t * Custom properties can be added to document fragment instance.\n\t */ _customProperties = new Map();\n    /**\n\t * Creates new DocumentFragment instance.\n\t *\n\t * @internal\n\t * @param document The document to which this document fragment belongs.\n\t * @param children A list of nodes to be inserted into the created document fragment.\n\t */ constructor(document, children){\n        super();\n        this.document = document;\n        if (children) {\n            this._insertChild(0, children);\n        }\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * Iterates over nodes added to this document fragment.\n\t */ [Symbol.iterator]() {\n        return this._children[Symbol.iterator]();\n    }\n    /**\n\t * Number of child nodes in this document fragment.\n\t */ get childCount() {\n        return this._children.length;\n    }\n    /**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t */ get isEmpty() {\n        return this.childCount === 0;\n    }\n    /**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t */ get root() {\n        return this;\n    }\n    /**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t */ get parent() {\n        return null;\n    }\n    /**\n\t * Artificial element name. Returns `undefined`. Added for compatibility reasons.\n\t */ get name() {\n        return undefined;\n    }\n    /**\n\t * Artificial element getFillerOffset. Returns `undefined`. Added for compatibility reasons.\n\t */ get getFillerOffset() {\n        return undefined;\n    }\n    /**\n\t * Returns the custom property value for the given key.\n\t */ getCustomProperty(key) {\n        return this._customProperties.get(key);\n    }\n    /**\n\t * Returns an iterator which iterates over this document fragment's custom properties.\n\t * Iterator provides `[ key, value ]` pairs for each stored property.\n\t */ *getCustomProperties() {\n        yield* this._customProperties.entries();\n    }\n    /**\n\t * {@link module:engine/view/documentfragment~DocumentFragment#_insertChild Insert} a child node or a list of child nodes at the end\n\t * and sets the parent of these nodes to this fragment.\n\t *\n\t * @internal\n\t * @param items Items to be inserted.\n\t * @returns Number of appended nodes.\n\t */ _appendChild(items) {\n        return this._insertChild(this.childCount, items);\n    }\n    /**\n\t * Gets child at the given index.\n\t *\n\t * @param index Index of child.\n\t * @returns Child node.\n\t */ getChild(index) {\n        return this._children[index];\n    }\n    /**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param node Child node.\n\t * @returns Index of the child node.\n\t */ getChildIndex(node) {\n        return this._children.indexOf(node);\n    }\n    /**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns Child nodes iterator.\n\t */ getChildren() {\n        return this._children[Symbol.iterator]();\n    }\n    /**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this fragment.\n\t *\n\t * @internal\n\t * @param index Position where nodes should be inserted.\n\t * @param items Items to be inserted.\n\t * @returns Number of inserted nodes.\n\t */ _insertChild(index, items) {\n        this._fireChange('children', this);\n        let count = 0;\n        const nodes = normalize$2(this.document, items);\n        for (const node of nodes){\n            // If node that is being added to this element is already inside another element, first remove it from the old parent.\n            if (node.parent !== null) {\n                node._remove();\n            }\n            node.parent = this;\n            this._children.splice(index, 0, node);\n            index++;\n            count++;\n        }\n        return count;\n    }\n    /**\n\t * Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @internal\n\t * @param index Number of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns The array of removed nodes.\n\t */ _removeChildren(index, howMany = 1) {\n        this._fireChange('children', this);\n        for(let i = index; i < index + howMany; i++){\n            this._children[i].parent = null;\n        }\n        return this._children.splice(index, howMany);\n    }\n    /**\n\t * Fires `change` event with given type of the change.\n\t *\n\t * @internal\n\t * @param type Type of the change.\n\t * @param node Changed node.\n\t */ _fireChange(type, node) {\n        this.fire('change:' + type, node);\n    }\n    /**\n\t * Sets a custom property. They can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setCustomProperty\n\t * @internal\n\t */ _setCustomProperty(key, value) {\n        this._customProperties.set(key, value);\n    }\n    /**\n\t * Removes the custom property stored under the given key.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeCustomProperty\n\t * @internal\n\t * @returns Returns true if property was removed.\n\t */ _removeCustomProperty(key) {\n        return this._customProperties.delete(key);\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentFragment$1.prototype.is = function(type) {\n    return type === 'documentFragment' || type === 'view:documentFragment';\n};\n/**\n * Converts strings to Text and non-iterables to arrays.\n */ function normalize$2(document, nodes) {\n    // Separate condition because string is iterable.\n    if (typeof nodes == 'string') {\n        return [\n            new Text$1(document, nodes)\n        ];\n    }\n    if (!isIterable(nodes)) {\n        nodes = [\n            nodes\n        ];\n    }\n    // Array.from to enable .map() on non-arrays.\n    return Array.from(nodes).map((node)=>{\n        if (typeof node == 'string') {\n            return new Text$1(document, node);\n        }\n        if (node instanceof TextProxy$1) {\n            return new Text$1(document, node.data);\n        }\n        return node;\n    });\n}\n\n/**\n * View downcast writer.\n *\n * It provides a set of methods used to manipulate view nodes.\n *\n * Do not create an instance of this writer manually. To modify a view structure, use\n * the {@link module:engine/view/view~View#change `View#change()`} block.\n *\n * The `DowncastWriter` is designed to work with semantic views which are the views that were/are being downcasted from the model.\n * To work with ordinary views (e.g. parsed from a pasted content) use the\n * {@link module:engine/view/upcastwriter~UpcastWriter upcast writer}.\n *\n * Read more about changing the view in the {@glink framework/architecture/editing-engine#changing-the-view Changing the view}\n * section of the {@glink framework/architecture/editing-engine Editing engine architecture} guide.\n */ class DowncastWriter {\n    /**\n\t * The view document instance in which this writer operates.\n\t */ document;\n    /**\n\t * Holds references to the attribute groups that share the same {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t * The keys are `id`s, the values are `Set`s holding {@link module:engine/view/attributeelement~AttributeElement}s.\n\t */ _cloneGroups = new Map();\n    /**\n\t * The slot factory used by the `elementToStructure` downcast helper.\n\t */ _slotFactory = null;\n    /**\n\t * @param document The view document instance.\n\t */ constructor(document){\n        this.document = document;\n    }\n    setSelection(...args) {\n        this.document.selection._setTo(...args);\n    }\n    /**\n\t * Moves {@link module:engine/view/documentselection~DocumentSelection#focus selection's focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @param Offset or one of the flags. Used only when the first parameter is a {@link module:engine/view/item~Item view item}.\n\t */ setSelectionFocus(itemOrPosition, offset) {\n        this.document.selection._setFocus(itemOrPosition, offset);\n    }\n    /**\n\t * Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance.\n\t *\n\t * @param children A list of nodes to be inserted into the created document fragment.\n\t * @returns The created document fragment.\n\t */ createDocumentFragment(children) {\n        return new DocumentFragment$1(this.document, children);\n    }\n    /**\n\t * Creates a new {@link module:engine/view/text~Text text node}.\n\t *\n\t * ```ts\n\t * writer.createText( 'foo' );\n\t * ```\n\t *\n\t * @param data The text's data.\n\t * @returns The created text node.\n\t */ createText(data) {\n        return new Text$1(this.document, data);\n    }\n    /**\n\t * Creates a new {@link module:engine/view/attributeelement~AttributeElement}.\n\t *\n\t * ```ts\n\t * writer.createAttributeElement( 'strong' );\n\t * writer.createAttributeElement( 'a', { href: 'foo.bar' } );\n\t *\n\t * // Make `<a>` element contain other attributes element so the `<a>` element is not broken.\n\t * writer.createAttributeElement( 'a', { href: 'foo.bar' }, { priority: 5 } );\n\t *\n\t * // Set `id` of a marker element so it is not joined or merged with \"normal\" elements.\n\t * writer.createAttributeElement( 'span', { class: 'my-marker' }, { id: 'marker:my' } );\n\t * ```\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Element's attributes.\n\t * @param options Element's options.\n\t * @param options.priority Element's {@link module:engine/view/attributeelement~AttributeElement#priority priority}.\n\t * @param options.id Element's {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */ createAttributeElement(name, attributes, options = {}) {\n        const attributeElement = new AttributeElement(this.document, name, attributes);\n        if (typeof options.priority === 'number') {\n            attributeElement._priority = options.priority;\n        }\n        if (options.id) {\n            attributeElement._id = options.id;\n        }\n        if (options.renderUnsafeAttributes) {\n            attributeElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n        }\n        return attributeElement;\n    }\n    createContainerElement(name, attributes, childrenOrOptions = {}, options = {}) {\n        let children = null;\n        if (isPlainObject(childrenOrOptions)) {\n            options = childrenOrOptions;\n        } else {\n            children = childrenOrOptions;\n        }\n        const containerElement = new ContainerElement(this.document, name, attributes, children);\n        if (options.renderUnsafeAttributes) {\n            containerElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n        }\n        return containerElement;\n    }\n    /**\n\t * Creates a new {@link module:engine/view/editableelement~EditableElement}.\n\t *\n\t * ```ts\n\t * writer.createEditableElement( 'div' );\n\t * writer.createEditableElement( 'div', { id: 'foo-1234' } );\n\t * ```\n\t *\n\t * Note: The editable element is to be used in the editing pipeline. Usually, together with\n\t * {@link module:widget/utils~toWidgetEditable `toWidgetEditable()`}.\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */ createEditableElement(name, attributes, options = {}) {\n        const editableElement = new EditableElement(this.document, name, attributes);\n        if (options.renderUnsafeAttributes) {\n            editableElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n        }\n        return editableElement;\n    }\n    /**\n\t * Creates a new {@link module:engine/view/emptyelement~EmptyElement}.\n\t *\n\t * ```ts\n\t * writer.createEmptyElement( 'img' );\n\t * writer.createEmptyElement( 'img', { id: 'foo-1234' } );\n\t * ```\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */ createEmptyElement(name, attributes, options = {}) {\n        const emptyElement = new EmptyElement(this.document, name, attributes);\n        if (options.renderUnsafeAttributes) {\n            emptyElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n        }\n        return emptyElement;\n    }\n    /**\n\t * Creates a new {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * ```ts\n\t * writer.createUIElement( 'span' );\n\t * writer.createUIElement( 'span', { id: 'foo-1234' } );\n\t * ```\n\t *\n\t * A custom render function can be provided as the third parameter:\n\t *\n\t * ```ts\n\t * writer.createUIElement( 'span', null, function( domDocument ) {\n\t * \tconst domElement = this.toDomElement( domDocument );\n\t * \tdomElement.innerHTML = '<b>this is ui element</b>';\n\t *\n\t * \treturn domElement;\n\t * } );\n\t * ```\n\t *\n\t * Unlike {@link #createRawElement raw elements}, UI elements are by no means editor content, for instance,\n\t * they are ignored by the editor selection system.\n\t *\n\t * You should not use UI elements as data containers. Check out {@link #createRawElement} instead.\n\t *\n\t * @param name The name of the element.\n\t * @param attributes Element attributes.\n\t * @param renderFunction A custom render function.\n\t * @returns The created element.\n\t */ createUIElement(name, attributes, renderFunction) {\n        const uiElement = new UIElement(this.document, name, attributes);\n        if (renderFunction) {\n            uiElement.render = renderFunction;\n        }\n        return uiElement;\n    }\n    /**\n\t * Creates a new {@link module:engine/view/rawelement~RawElement}.\n\t *\n\t * ```ts\n\t * writer.createRawElement( 'span', { id: 'foo-1234' }, function( domElement ) {\n\t * \tdomElement.innerHTML = '<b>This is the raw content of the raw element.</b>';\n\t * } );\n\t * ```\n\t *\n\t * Raw elements work as data containers (\"wrappers\", \"sandboxes\") but their children are not managed or\n\t * even recognized by the editor. This encapsulation allows integrations to maintain custom DOM structures\n\t * in the editor content without, for instance, worrying about compatibility with other editor features.\n\t * Raw elements are a perfect tool for integration with external frameworks and data sources.\n\t *\n\t * Unlike {@link #createUIElement UI elements}, raw elements act like \"real\" editor content (similar to\n\t * {@link module:engine/view/containerelement~ContainerElement} or {@link module:engine/view/emptyelement~EmptyElement}),\n\t * and they are considered by the editor selection.\n\t *\n\t * You should not use raw elements to render the UI in the editor content. Check out {@link #createUIElement `#createUIElement()`}\n\t * instead.\n\t *\n\t * @param name The name of the element.\n\t * @param attributes Element attributes.\n\t * @param renderFunction A custom render function.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns The created element.\n\t */ createRawElement(name, attributes, renderFunction, options = {}) {\n        const rawElement = new RawElement(this.document, name, attributes);\n        if (renderFunction) {\n            rawElement.render = renderFunction;\n        }\n        if (options.renderUnsafeAttributes) {\n            rawElement._unsafeAttributesToRender.push(...options.renderUnsafeAttributes);\n        }\n        return rawElement;\n    }\n    /**\n\t * Adds or overwrites the element's attribute with a specified key and value.\n\t *\n\t * ```ts\n\t * writer.setAttribute( 'href', 'http://ckeditor.com', linkElement );\n\t * ```\n\t *\n\t * @param key The attribute key.\n\t * @param value The attribute value.\n\t */ setAttribute(key, value, element) {\n        element._setAttribute(key, value);\n    }\n    /**\n\t * Removes attribute from the element.\n\t *\n\t * ```ts\n\t * writer.removeAttribute( 'href', linkElement );\n\t * ```\n\t *\n\t * @param key Attribute key.\n\t */ removeAttribute(key, element) {\n        element._removeAttribute(key);\n    }\n    /**\n\t * Adds specified class to the element.\n\t *\n\t * ```ts\n\t * writer.addClass( 'foo', linkElement );\n\t * writer.addClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t */ addClass(className, element) {\n        element._addClass(className);\n    }\n    /**\n\t * Removes specified class from the element.\n\t *\n\t * ```ts\n\t * writer.removeClass( 'foo', linkElement );\n\t * writer.removeClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t */ removeClass(className, element) {\n        element._removeClass(className);\n    }\n    setStyle(property, value, element) {\n        if (isPlainObject(property) && element === undefined) {\n            value._setStyle(property);\n        } else {\n            element._setStyle(property, value);\n        }\n    }\n    /**\n\t * Removes specified style from the element.\n\t *\n\t * ```ts\n\t * writer.removeStyle( 'color', element ); // Removes 'color' style.\n\t * writer.removeStyle( [ 'color', 'border-top' ], element ); // Removes both 'color' and 'border-top' styles.\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t */ removeStyle(property, element) {\n        element._removeStyle(property);\n    }\n    /**\n\t * Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t */ setCustomProperty(key, value, element) {\n        element._setCustomProperty(key, value);\n    }\n    /**\n\t * Removes a custom property stored under the given key.\n\t *\n\t * @returns Returns true if property was removed.\n\t */ removeCustomProperty(key, element) {\n        return element._removeCustomProperty(key);\n    }\n    /**\n\t * Breaks attribute elements at the provided position or at the boundaries of a provided range. It breaks attribute elements\n\t * up to their first ancestor that is a container element.\n\t *\n\t * In following examples `<p>` is a container, `<b>` and `<u>` are attribute elements:\n\t *\n\t * ```html\n\t * <p>foo<b><u>bar{}</u></b></p> -> <p>foo<b><u>bar</u></b>[]</p>\n\t * <p>foo<b><u>{}bar</u></b></p> -> <p>foo{}<b><u>bar</u></b></p>\n\t * <p>foo<b><u>b{}ar</u></b></p> -> <p>foo<b><u>b</u></b>[]<b><u>ar</u></b></p>\n\t * <p><b>fo{o</b><u>ba}r</u></p> -> <p><b>fo</b><b>o</b><u>ba</u><u>r</u></b></p>\n\t * ```\n\t *\n\t * **Note:** {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n\t *\n\t * **Note:** The difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes()} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of a given `position`,\n\t * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.\n\t * `breakContainer()` assumes that a given `position` is directly in the container element and breaks that container element.\n\t *\n\t * Throws the `view-writer-invalid-range-container` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * when the {@link module:engine/view/range~Range#start start}\n\t * and {@link module:engine/view/range~Range#end end} positions of a passed range are not placed inside same parent container.\n\t *\n\t * Throws the `view-writer-cannot-break-empty-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * when trying to break attributes inside an {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n\t *\n\t * Throws the `view-writer-cannot-break-ui-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * when trying to break attributes inside a {@link module:engine/view/uielement~UIElement UIElement}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#breakContainer\n\t * @param positionOrRange The position where to break attribute elements.\n\t * @returns The new position or range, after breaking the attribute elements.\n\t */ breakAttributes(positionOrRange) {\n        if (positionOrRange instanceof Position$1) {\n            return this._breakAttributes(positionOrRange);\n        } else {\n            return this._breakAttributesRange(positionOrRange);\n        }\n    }\n    /**\n\t * Breaks a {@link module:engine/view/containerelement~ContainerElement container view element} into two, at the given position.\n\t * The position has to be directly inside the container element and cannot be in the root. It does not break the conrainer view element\n\t * if the position is at the beginning or at the end of its parent element.\n\t *\n\t * ```html\n\t * <p>foo^bar</p> -> <p>foo</p><p>bar</p>\n\t * <div><p>foo</p>^<p>bar</p></div> -> <div><p>foo</p></div><div><p>bar</p></div>\n\t * <p>^foobar</p> -> ^<p>foobar</p>\n\t * <p>foobar^</p> -> <p>foobar</p>^\n\t * ```\n\t *\n\t * **Note:** The difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes()} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of a given `position`,\n\t * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.\n\t * `breakContainer()` assumes that the given `position` is directly in the container element and breaks that container element.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#breakAttributes\n\t * @param position The position where to break the element.\n\t * @returns The position between broken elements. If an element has not been broken,\n\t * the returned position is placed either before or after it.\n\t */ breakContainer(position) {\n        const element = position.parent;\n        if (!element.is('containerElement')) {\n            /**\n\t\t\t * Trying to break an element which is not a container element.\n\t\t\t *\n\t\t\t * @error view-writer-break-non-container-element\n\t\t\t */ throw new CKEditorError('view-writer-break-non-container-element', this.document);\n        }\n        if (!element.parent) {\n            /**\n\t\t\t * Trying to break root element.\n\t\t\t *\n\t\t\t * @error view-writer-break-root\n\t\t\t */ throw new CKEditorError('view-writer-break-root', this.document);\n        }\n        if (position.isAtStart) {\n            return Position$1._createBefore(element);\n        } else if (!position.isAtEnd) {\n            const newElement = element._clone(false);\n            this.insert(Position$1._createAfter(element), newElement);\n            const sourceRange = new Range$1(position, Position$1._createAt(element, 'end'));\n            const targetPosition = new Position$1(newElement, 0);\n            this.move(sourceRange, targetPosition);\n        }\n        return Position$1._createAfter(element);\n    }\n    /**\n\t * Merges {@link module:engine/view/attributeelement~AttributeElement attribute elements}. It also merges text nodes if needed.\n\t * Only {@link module:engine/view/attributeelement~AttributeElement#isSimilar similar} attribute elements can be merged.\n\t *\n\t * In following examples `<p>` is a container and `<b>` is an attribute element:\n\t *\n\t * ```html\n\t * <p>foo[]bar</p> -> <p>foo{}bar</p>\n\t * <p><b>foo</b>[]<b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t * <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p> -> <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p>\n\t * ```\n\t *\n\t * It will also take care about empty attributes when merging:\n\t *\n\t * ```html\n\t * <p><b>[]</b></p> -> <p>[]</p>\n\t * <p><b>foo</b><i>[]</i><b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t * ```\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#mergeAttributes mergeAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n\t * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#mergeContainers\n\t * @param position Merge position.\n\t * @returns Position after merge.\n\t */ mergeAttributes(position) {\n        const positionOffset = position.offset;\n        const positionParent = position.parent;\n        // When inside text node - nothing to merge.\n        if (positionParent.is('$text')) {\n            return position;\n        }\n        // When inside empty attribute - remove it.\n        if (positionParent.is('attributeElement') && positionParent.childCount === 0) {\n            const parent = positionParent.parent;\n            const offset = positionParent.index;\n            positionParent._remove();\n            this._removeFromClonedElementsGroup(positionParent);\n            return this.mergeAttributes(new Position$1(parent, offset));\n        }\n        const nodeBefore = positionParent.getChild(positionOffset - 1);\n        const nodeAfter = positionParent.getChild(positionOffset);\n        // Position should be placed between two nodes.\n        if (!nodeBefore || !nodeAfter) {\n            return position;\n        }\n        // When position is between two text nodes.\n        if (nodeBefore.is('$text') && nodeAfter.is('$text')) {\n            return mergeTextNodes(nodeBefore, nodeAfter);\n        } else if (nodeBefore.is('attributeElement') && nodeAfter.is('attributeElement') && nodeBefore.isSimilar(nodeAfter)) {\n            // Move all children nodes from node placed after selection and remove that node.\n            const count = nodeBefore.childCount;\n            nodeBefore._appendChild(nodeAfter.getChildren());\n            nodeAfter._remove();\n            this._removeFromClonedElementsGroup(nodeAfter);\n            // New position is located inside the first node, before new nodes.\n            // Call this method recursively to merge again if needed.\n            return this.mergeAttributes(new Position$1(nodeBefore, count));\n        }\n        return position;\n    }\n    /**\n\t * Merges two {@link module:engine/view/containerelement~ContainerElement container elements} that are before and after given position.\n\t * Precisely, the element after the position is removed and it's contents are moved to element before the position.\n\t *\n\t * ```html\n\t * <p>foo</p>^<p>bar</p> -> <p>foo^bar</p>\n\t * <div>foo</div>^<p>bar</p> -> <div>foo^bar</div>\n\t * ```\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#mergeAttributes mergeAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n\t * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#mergeAttributes\n\t * @param position Merge position.\n\t * @returns Position after merge.\n\t */ mergeContainers(position) {\n        const prev = position.nodeBefore;\n        const next = position.nodeAfter;\n        if (!prev || !next || !prev.is('containerElement') || !next.is('containerElement')) {\n            /**\n\t\t\t * Element before and after given position cannot be merged.\n\t\t\t *\n\t\t\t * @error view-writer-merge-containers-invalid-position\n\t\t\t */ throw new CKEditorError('view-writer-merge-containers-invalid-position', this.document);\n        }\n        const lastChild = prev.getChild(prev.childCount - 1);\n        const newPosition = lastChild instanceof Text$1 ? Position$1._createAt(lastChild, 'end') : Position$1._createAt(prev, 'end');\n        this.move(Range$1._createIn(next), Position$1._createAt(prev, 'end'));\n        this.remove(Range$1._createOn(next));\n        return newPosition;\n    }\n    /**\n\t * Inserts a node or nodes at specified position. Takes care about breaking attributes before insertion\n\t * and merging them afterwards.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n\t * contains instances that are not {@link module:engine/view/text~Text Texts},\n\t * {@link module:engine/view/attributeelement~AttributeElement AttributeElements},\n\t * {@link module:engine/view/containerelement~ContainerElement ContainerElements},\n\t * {@link module:engine/view/emptyelement~EmptyElement EmptyElements},\n\t * {@link module:engine/view/rawelement~RawElement RawElements} or\n\t * {@link module:engine/view/uielement~UIElement UIElements}.\n\t *\n\t * @param position Insertion position.\n\t * @param nodes Node or nodes to insert.\n\t * @returns Range around inserted nodes.\n\t */ insert(position, nodes) {\n        nodes = isIterable(nodes) ? [\n            ...nodes\n        ] : [\n            nodes\n        ];\n        // Check if nodes to insert are instances of AttributeElements, ContainerElements, EmptyElements, UIElements or Text.\n        validateNodesToInsert(nodes, this.document);\n        // Group nodes in batches of nodes that require or do not require breaking an AttributeElements.\n        const nodeGroups = nodes.reduce((groups, node)=>{\n            const lastGroup = groups[groups.length - 1];\n            // Break attributes on nodes that do exist in the model tree so they can have attributes, other elements\n            // can't have an attribute in model and won't get wrapped with an AttributeElement while down-casted.\n            const breakAttributes = !node.is('uiElement');\n            if (!lastGroup || lastGroup.breakAttributes != breakAttributes) {\n                groups.push({\n                    breakAttributes,\n                    nodes: [\n                        node\n                    ]\n                });\n            } else {\n                lastGroup.nodes.push(node);\n            }\n            return groups;\n        }, []);\n        // Insert nodes in batches.\n        let start = null;\n        let end = position;\n        for (const { nodes, breakAttributes } of nodeGroups){\n            const range = this._insertNodes(end, nodes, breakAttributes);\n            if (!start) {\n                start = range.start;\n            }\n            end = range.end;\n        }\n        // When no nodes were inserted - return collapsed range.\n        if (!start) {\n            return new Range$1(position);\n        }\n        return new Range$1(start, end);\n    }\n    /**\n\t * Removes provided range from the container.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param rangeOrItem Range to remove from container\n\t * or an {@link module:engine/view/item~Item item} to remove. If range is provided, after removing, it will be updated\n\t * to a collapsed range showing the new position.\n\t * @returns Document fragment containing removed nodes.\n\t */ remove(rangeOrItem) {\n        const range = rangeOrItem instanceof Range$1 ? rangeOrItem : Range$1._createOn(rangeOrItem);\n        validateRangeContainer(range, this.document);\n        // If range is collapsed - nothing to remove.\n        if (range.isCollapsed) {\n            return new DocumentFragment$1(this.document);\n        }\n        // Break attributes at range start and end.\n        const { start: breakStart, end: breakEnd } = this._breakAttributesRange(range, true);\n        const parentContainer = breakStart.parent;\n        const count = breakEnd.offset - breakStart.offset;\n        // Remove nodes in range.\n        const removed = parentContainer._removeChildren(breakStart.offset, count);\n        for (const node of removed){\n            this._removeFromClonedElementsGroup(node);\n        }\n        // Merge after removing.\n        const mergePosition = this.mergeAttributes(breakStart);\n        range.start = mergePosition;\n        range.end = mergePosition.clone();\n        // Return removed nodes.\n        return new DocumentFragment$1(this.document, removed);\n    }\n    /**\n\t * Removes matching elements from given range.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param range Range to clear.\n\t * @param element Element to remove.\n\t */ clear(range, element) {\n        validateRangeContainer(range, this.document);\n        // Create walker on given range.\n        // We walk backward because when we remove element during walk it modifies range end position.\n        const walker = range.getWalker({\n            direction: 'backward',\n            ignoreElementEnd: true\n        });\n        // Let's walk.\n        for (const current of walker){\n            const item = current.item;\n            let rangeToRemove;\n            // When current item matches to the given element.\n            if (item.is('element') && element.isSimilar(item)) {\n                // Create range on this element.\n                rangeToRemove = Range$1._createOn(item);\n            // When range starts inside Text or TextProxy element.\n            } else if (!current.nextPosition.isAfter(range.start) && item.is('$textProxy')) {\n                // We need to check if parent of this text matches to given element.\n                const parentElement = item.getAncestors().find((ancestor)=>{\n                    return ancestor.is('element') && element.isSimilar(ancestor);\n                });\n                // If it is then create range inside this element.\n                if (parentElement) {\n                    rangeToRemove = Range$1._createIn(parentElement);\n                }\n            }\n            // If we have found element to remove.\n            if (rangeToRemove) {\n                // We need to check if element range stick out of the given range and truncate if it is.\n                if (rangeToRemove.end.isAfter(range.end)) {\n                    rangeToRemove.end = range.end;\n                }\n                if (rangeToRemove.start.isBefore(range.start)) {\n                    rangeToRemove.start = range.start;\n                }\n                // At the end we remove range with found element.\n                this.remove(rangeToRemove);\n            }\n        }\n    }\n    /**\n\t * Moves nodes from provided range to target position.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param sourceRange Range containing nodes to move.\n\t * @param targetPosition Position to insert.\n\t * @returns Range in target container. Inserted nodes are placed between\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions.\n\t */ move(sourceRange, targetPosition) {\n        let nodes;\n        if (targetPosition.isAfter(sourceRange.end)) {\n            targetPosition = this._breakAttributes(targetPosition, true);\n            const parent = targetPosition.parent;\n            const countBefore = parent.childCount;\n            sourceRange = this._breakAttributesRange(sourceRange, true);\n            nodes = this.remove(sourceRange);\n            targetPosition.offset += parent.childCount - countBefore;\n        } else {\n            nodes = this.remove(sourceRange);\n        }\n        return this.insert(targetPosition, nodes);\n    }\n    /**\n\t * Wraps elements within range with provided {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t * If a collapsed range is provided, it will be wrapped only if it is equal to view selection.\n\t *\n\t * If a collapsed range was passed and is same as selection, the selection\n\t * will be moved to the inside of the wrapped attribute element.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-invalid-range-container`\n\t * when {@link module:engine/view/range~Range#start}\n\t * and {@link module:engine/view/range~Range#end} positions are not placed inside same parent container.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-nonselection-collapsed-range` when passed range\n\t * is collapsed and different than view selection.\n\t *\n\t * @param range Range to wrap.\n\t * @param attribute Attribute element to use as wrapper.\n\t * @returns range Range after wrapping, spanning over wrapping attribute element.\n\t */ wrap(range, attribute) {\n        if (!(attribute instanceof AttributeElement)) {\n            throw new CKEditorError('view-writer-wrap-invalid-attribute', this.document);\n        }\n        validateRangeContainer(range, this.document);\n        if (!range.isCollapsed) {\n            // Non-collapsed range. Wrap it with the attribute element.\n            return this._wrapRange(range, attribute);\n        } else {\n            // Collapsed range. Wrap position.\n            let position = range.start;\n            if (position.parent.is('element') && !_hasNonUiChildren(position.parent)) {\n                position = position.getLastMatchingPosition((value)=>value.item.is('uiElement'));\n            }\n            position = this._wrapPosition(position, attribute);\n            const viewSelection = this.document.selection;\n            // If wrapping position is equal to view selection, move view selection inside wrapping attribute element.\n            if (viewSelection.isCollapsed && viewSelection.getFirstPosition().isEqual(range.start)) {\n                this.setSelection(position);\n            }\n            return new Range$1(position);\n        }\n    }\n    /**\n\t * Unwraps nodes within provided range from attribute element.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t */ unwrap(range, attribute) {\n        if (!(attribute instanceof AttributeElement)) {\n            /**\n\t\t\t * The `attribute` passed to {@link module:engine/view/downcastwriter~DowncastWriter#unwrap `DowncastWriter#unwrap()`}\n\t\t\t * must be an instance of {@link module:engine/view/attributeelement~AttributeElement `AttributeElement`}.\n\t\t\t *\n\t\t\t * @error view-writer-unwrap-invalid-attribute\n\t\t\t */ throw new CKEditorError('view-writer-unwrap-invalid-attribute', this.document);\n        }\n        validateRangeContainer(range, this.document);\n        // If range is collapsed - nothing to unwrap.\n        if (range.isCollapsed) {\n            return range;\n        }\n        // Break attributes at range start and end.\n        const { start: breakStart, end: breakEnd } = this._breakAttributesRange(range, true);\n        const parentContainer = breakStart.parent;\n        // Unwrap children located between break points.\n        const newRange = this._unwrapChildren(parentContainer, breakStart.offset, breakEnd.offset, attribute);\n        // Merge attributes at the both ends and return a new range.\n        const start = this.mergeAttributes(newRange.start);\n        // If start position was merged - move end position back.\n        if (!start.isEqual(newRange.start)) {\n            newRange.end.offset--;\n        }\n        const end = this.mergeAttributes(newRange.end);\n        return new Range$1(start, end);\n    }\n    /**\n\t * Renames element by creating a copy of renamed element but with changed name and then moving contents of the\n\t * old element to the new one. Keep in mind that this will invalidate all {@link module:engine/view/position~Position positions} which\n\t * has renamed element as {@link module:engine/view/position~Position#parent a parent}.\n\t *\n\t * New element has to be created because `Element#tagName` property in DOM is readonly.\n\t *\n\t * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t *\n\t * @param newName New name for element.\n\t * @param viewElement Element to be renamed.\n\t * @returns Element created due to rename.\n\t */ rename(newName, viewElement) {\n        const newElement = new ContainerElement(this.document, newName, viewElement.getAttributes());\n        this.insert(Position$1._createAfter(viewElement), newElement);\n        this.move(Range$1._createIn(viewElement), Position$1._createAt(newElement, 0));\n        this.remove(Range$1._createOn(viewElement));\n        return newElement;\n    }\n    /**\n\t * Cleans up memory by removing obsolete cloned elements group from the writer.\n\t *\n\t * Should be used whenever all {@link module:engine/view/attributeelement~AttributeElement attribute elements}\n\t * with the same {@link module:engine/view/attributeelement~AttributeElement#id id} are going to be removed from the view and\n\t * the group will no longer be needed.\n\t *\n\t * Cloned elements group are not removed automatically in case if the group is still needed after all its elements\n\t * were removed from the view.\n\t *\n\t * Keep in mind that group names are equal to the `id` property of the attribute element.\n\t *\n\t * @param groupName Name of the group to clear.\n\t */ clearClonedElementsGroup(groupName) {\n        this._cloneGroups.delete(groupName);\n    }\n    /**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param offset Offset or one of the flags. Used only when the first parameter is a {@link module:engine/view/item~Item view item}.\n\t */ createPositionAt(itemOrPosition, offset) {\n        return Position$1._createAt(itemOrPosition, offset);\n    }\n    /**\n\t * Creates a new position after given view item.\n\t *\n\t * @param item View item after which the position should be located.\n\t */ createPositionAfter(item) {\n        return Position$1._createAfter(item);\n    }\n    /**\n\t * Creates a new position before given view item.\n\t *\n\t * @param item View item before which the position should be located.\n\t */ createPositionBefore(item) {\n        return Position$1._createBefore(item);\n    }\n    /**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates its own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */ createRange(start, end) {\n        return new Range$1(start, end);\n    }\n    /**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t */ createRangeOn(item) {\n        return Range$1._createOn(item);\n    }\n    /**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */ createRangeIn(element) {\n        return Range$1._createIn(element);\n    }\n    createSelection(...args) {\n        return new Selection$1(...args);\n    }\n    /**\n\t * Creates placeholders for child elements of the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n\t * `elementToStructure()`} conversion helper.\n\t *\n\t * ```ts\n\t * const viewSlot = conversionApi.writer.createSlot();\n\t * const viewPosition = conversionApi.writer.createPositionAt( viewElement, 0 );\n\t *\n\t * conversionApi.writer.insert( viewPosition, viewSlot );\n\t * ```\n\t *\n\t * It could be filtered down to a specific subset of children (only `<foo>` model elements in this case):\n\t *\n\t * ```ts\n\t * const viewSlot = conversionApi.writer.createSlot( node => node.is( 'element', 'foo' ) );\n\t * const viewPosition = conversionApi.writer.createPositionAt( viewElement, 0 );\n\t *\n\t * conversionApi.writer.insert( viewPosition, viewSlot );\n\t * ```\n\t *\n\t * While providing a filtered slot, make sure to provide slots for all child nodes. A single node can not be downcasted into\n\t * multiple slots.\n\t *\n\t * **Note**: You should not change the order of nodes. View elements should be in the same order as model nodes.\n\t *\n\t * @param modeOrFilter The filter for child nodes.\n\t * @returns The slot element to be placed in to the view structure while processing\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure `elementToStructure()`}.\n\t */ createSlot(modeOrFilter = 'children') {\n        if (!this._slotFactory) {\n            /**\n\t\t\t * The `createSlot()` method is only allowed inside the `elementToStructure` downcast helper callback.\n\t\t\t *\n\t\t\t * @error view-writer-invalid-create-slot-context\n\t\t\t */ throw new CKEditorError('view-writer-invalid-create-slot-context', this.document);\n        }\n        return this._slotFactory(this, modeOrFilter);\n    }\n    /**\n\t * Registers a slot factory.\n\t *\n\t * @internal\n\t * @param slotFactory The slot factory.\n\t */ _registerSlotFactory(slotFactory) {\n        this._slotFactory = slotFactory;\n    }\n    /**\n\t * Clears the registered slot factory.\n\t *\n\t * @internal\n\t */ _clearSlotFactory() {\n        this._slotFactory = null;\n    }\n    /**\n\t * Inserts a node or nodes at the specified position. Takes care of breaking attributes before insertion\n\t * and merging them afterwards if requested by the breakAttributes param.\n\t *\n\t * @param position Insertion position.\n\t * @param nodes Node or nodes to insert.\n\t * @param breakAttributes Whether attributes should be broken.\n\t * @returns Range around inserted nodes.\n\t */ _insertNodes(position, nodes, breakAttributes) {\n        let parentElement;\n        // Break attributes on nodes that do exist in the model tree so they can have attributes, other elements\n        // can't have an attribute in model and won't get wrapped with an AttributeElement while down-casted.\n        if (breakAttributes) {\n            parentElement = getParentContainer(position);\n        } else {\n            parentElement = position.parent.is('$text') ? position.parent.parent : position.parent;\n        }\n        if (!parentElement) {\n            /**\n\t\t\t * Position's parent container cannot be found.\n\t\t\t *\n\t\t\t * @error view-writer-invalid-position-container\n\t\t\t */ throw new CKEditorError('view-writer-invalid-position-container', this.document);\n        }\n        let insertionPosition;\n        if (breakAttributes) {\n            insertionPosition = this._breakAttributes(position, true);\n        } else {\n            insertionPosition = position.parent.is('$text') ? breakTextNode(position) : position;\n        }\n        const length = parentElement._insertChild(insertionPosition.offset, nodes);\n        for (const node of nodes){\n            this._addToClonedElementsGroup(node);\n        }\n        const endPosition = insertionPosition.getShiftedBy(length);\n        const start = this.mergeAttributes(insertionPosition);\n        // If start position was merged - move end position.\n        if (!start.isEqual(insertionPosition)) {\n            endPosition.offset--;\n        }\n        const end = this.mergeAttributes(endPosition);\n        return new Range$1(start, end);\n    }\n    /**\n\t * Wraps children with provided `wrapElement`. Only children contained in `parent` element between\n\t * `startOffset` and `endOffset` will be wrapped.\n\t */ _wrapChildren(parent, startOffset, endOffset, wrapElement) {\n        let i = startOffset;\n        const wrapPositions = [];\n        while(i < endOffset){\n            const child = parent.getChild(i);\n            const isText = child.is('$text');\n            const isAttribute = child.is('attributeElement');\n            //\n            // (In all examples, assume that `wrapElement` is `<span class=\"foo\">` element.)\n            //\n            // Check if `wrapElement` can be joined with the wrapped element. One of requirements is having same name.\n            // If possible, join elements.\n            //\n            // <p><span class=\"bar\">abc</span></p>  -->  <p><span class=\"foo bar\">abc</span></p>\n            //\n            if (isAttribute && this._wrapAttributeElement(wrapElement, child)) {\n                wrapPositions.push(new Position$1(parent, i));\n            } else if (isText || !isAttribute || shouldABeOutsideB(wrapElement, child)) {\n                // Clone attribute.\n                const newAttribute = wrapElement._clone();\n                // Wrap current node with new attribute.\n                child._remove();\n                newAttribute._appendChild(child);\n                parent._insertChild(i, newAttribute);\n                this._addToClonedElementsGroup(newAttribute);\n                wrapPositions.push(new Position$1(parent, i));\n            } else /* if ( isAttribute ) */ {\n                this._wrapChildren(child, 0, child.childCount, wrapElement);\n            }\n            i++;\n        }\n        // Merge at each wrap.\n        let offsetChange = 0;\n        for (const position of wrapPositions){\n            position.offset -= offsetChange;\n            // Do not merge with elements outside selected children.\n            if (position.offset == startOffset) {\n                continue;\n            }\n            const newPosition = this.mergeAttributes(position);\n            // If nodes were merged - other merge offsets will change.\n            if (!newPosition.isEqual(position)) {\n                offsetChange++;\n                endOffset--;\n            }\n        }\n        return Range$1._createFromParentsAndOffsets(parent, startOffset, parent, endOffset);\n    }\n    /**\n\t * Unwraps children from provided `unwrapElement`. Only children contained in `parent` element between\n\t * `startOffset` and `endOffset` will be unwrapped.\n\t */ _unwrapChildren(parent, startOffset, endOffset, unwrapElement) {\n        let i = startOffset;\n        const unwrapPositions = [];\n        // Iterate over each element between provided offsets inside parent.\n        // We don't use tree walker or range iterator because we will be removing and merging potentially multiple nodes,\n        // so it could get messy. It is safer to it manually in this case.\n        while(i < endOffset){\n            const child = parent.getChild(i);\n            // Skip all text nodes. There should be no container element's here either.\n            if (!child.is('attributeElement')) {\n                i++;\n                continue;\n            }\n            //\n            // (In all examples, assume that `unwrapElement` is `<span class=\"foo\">` element.)\n            //\n            // If the child is similar to the given attribute element, unwrap it - it will be completely removed.\n            //\n            // <p><span class=\"foo\">abc</span>xyz</p>  -->  <p>abcxyz</p>\n            //\n            if (child.isSimilar(unwrapElement)) {\n                const unwrapped = child.getChildren();\n                const count = child.childCount;\n                // Replace wrapper element with its children\n                child._remove();\n                parent._insertChild(i, unwrapped);\n                this._removeFromClonedElementsGroup(child);\n                // Save start and end position of moved items.\n                unwrapPositions.push(new Position$1(parent, i), new Position$1(parent, i + count));\n                // Skip elements that were unwrapped. Assuming there won't be another element to unwrap in child elements.\n                i += count;\n                endOffset += count - 1;\n                continue;\n            }\n            //\n            // If the child is not similar but is an attribute element, try partial unwrapping - remove the same attributes/styles/classes.\n            // Partial unwrapping will happen only if the elements have the same name.\n            //\n            // <p><span class=\"foo bar\">abc</span>xyz</p>  -->  <p><span class=\"bar\">abc</span>xyz</p>\n            // <p><i class=\"foo\">abc</i>xyz</p>            -->  <p><i class=\"foo\">abc</i>xyz</p>\n            //\n            if (this._unwrapAttributeElement(unwrapElement, child)) {\n                unwrapPositions.push(new Position$1(parent, i), new Position$1(parent, i + 1));\n                i++;\n                continue;\n            }\n            //\n            // If other nested attribute is found, look through it's children for elements to unwrap.\n            //\n            // <p><i><span class=\"foo\">abc</span></i><p>  -->  <p><i>abc</i><p>\n            //\n            this._unwrapChildren(child, 0, child.childCount, unwrapElement);\n            i++;\n        }\n        // Merge at each unwrap.\n        let offsetChange = 0;\n        for (const position of unwrapPositions){\n            position.offset -= offsetChange;\n            // Do not merge with elements outside selected children.\n            if (position.offset == startOffset || position.offset == endOffset) {\n                continue;\n            }\n            const newPosition = this.mergeAttributes(position);\n            // If nodes were merged - other merge offsets will change.\n            if (!newPosition.isEqual(position)) {\n                offsetChange++;\n                endOffset--;\n            }\n        }\n        return Range$1._createFromParentsAndOffsets(parent, startOffset, parent, endOffset);\n    }\n    /**\n\t * Helper function for `view.writer.wrap`. Wraps range with provided attribute element.\n\t * This method will also merge newly added attribute element with its siblings whenever possible.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * @returns New range after wrapping, spanning over wrapping attribute element.\n\t */ _wrapRange(range, attribute) {\n        // Break attributes at range start and end.\n        const { start: breakStart, end: breakEnd } = this._breakAttributesRange(range, true);\n        const parentContainer = breakStart.parent;\n        // Wrap all children with attribute.\n        const newRange = this._wrapChildren(parentContainer, breakStart.offset, breakEnd.offset, attribute);\n        // Merge attributes at the both ends and return a new range.\n        const start = this.mergeAttributes(newRange.start);\n        // If start position was merged - move end position back.\n        if (!start.isEqual(newRange.start)) {\n            newRange.end.offset--;\n        }\n        const end = this.mergeAttributes(newRange.end);\n        return new Range$1(start, end);\n    }\n    /**\n\t * Helper function for {@link #wrap}. Wraps position with provided attribute element.\n\t * This method will also merge newly added attribute element with its siblings whenever possible.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * @returns New position after wrapping.\n\t */ _wrapPosition(position, attribute) {\n        // Return same position when trying to wrap with attribute similar to position parent.\n        if (attribute.isSimilar(position.parent)) {\n            return movePositionToTextNode(position.clone());\n        }\n        // When position is inside text node - break it and place new position between two text nodes.\n        if (position.parent.is('$text')) {\n            position = breakTextNode(position);\n        }\n        // Create fake element that will represent position, and will not be merged with other attributes.\n        const fakeElement = this.createAttributeElement('_wrapPosition-fake-element');\n        fakeElement._priority = Number.POSITIVE_INFINITY;\n        fakeElement.isSimilar = ()=>false;\n        // Insert fake element in position location.\n        position.parent._insertChild(position.offset, fakeElement);\n        // Range around inserted fake attribute element.\n        const wrapRange = new Range$1(position, position.getShiftedBy(1));\n        // Wrap fake element with attribute (it will also merge if possible).\n        this.wrap(wrapRange, attribute);\n        // Remove fake element and place new position there.\n        const newPosition = new Position$1(fakeElement.parent, fakeElement.index);\n        fakeElement._remove();\n        // If position is placed between text nodes - merge them and return position inside.\n        const nodeBefore = newPosition.nodeBefore;\n        const nodeAfter = newPosition.nodeAfter;\n        if (nodeBefore instanceof Text$1 && nodeAfter instanceof Text$1) {\n            return mergeTextNodes(nodeBefore, nodeAfter);\n        }\n        // If position is next to text node - move position inside.\n        return movePositionToTextNode(newPosition);\n    }\n    /**\n\t * Wraps one {@link module:engine/view/attributeelement~AttributeElement AttributeElement} into another by\n\t * merging them if possible. When merging is possible - all attributes, styles and classes are moved from wrapper\n\t * element to element being wrapped.\n\t *\n\t * @param wrapper Wrapper AttributeElement.\n\t * @param toWrap AttributeElement to wrap using wrapper element.\n\t * @returns Returns `true` if elements are merged.\n\t */ _wrapAttributeElement(wrapper, toWrap) {\n        if (!canBeJoined(wrapper, toWrap)) {\n            return false;\n        }\n        // Can't merge if name or priority differs.\n        if (wrapper.name !== toWrap.name || wrapper.priority !== toWrap.priority) {\n            return false;\n        }\n        // Check if attributes can be merged.\n        for (const key of wrapper.getAttributeKeys()){\n            // Classes and styles should be checked separately.\n            if (key === 'class' || key === 'style') {\n                continue;\n            }\n            // If some attributes are different we cannot wrap.\n            if (toWrap.hasAttribute(key) && toWrap.getAttribute(key) !== wrapper.getAttribute(key)) {\n                return false;\n            }\n        }\n        // Check if styles can be merged.\n        for (const key of wrapper.getStyleNames()){\n            if (toWrap.hasStyle(key) && toWrap.getStyle(key) !== wrapper.getStyle(key)) {\n                return false;\n            }\n        }\n        // Move all attributes/classes/styles from wrapper to wrapped AttributeElement.\n        for (const key of wrapper.getAttributeKeys()){\n            // Classes and styles should be checked separately.\n            if (key === 'class' || key === 'style') {\n                continue;\n            }\n            // Move only these attributes that are not present - other are similar.\n            if (!toWrap.hasAttribute(key)) {\n                this.setAttribute(key, wrapper.getAttribute(key), toWrap);\n            }\n        }\n        for (const key of wrapper.getStyleNames()){\n            if (!toWrap.hasStyle(key)) {\n                this.setStyle(key, wrapper.getStyle(key), toWrap);\n            }\n        }\n        for (const key of wrapper.getClassNames()){\n            if (!toWrap.hasClass(key)) {\n                this.addClass(key, toWrap);\n            }\n        }\n        return true;\n    }\n    /**\n\t * Unwraps {@link module:engine/view/attributeelement~AttributeElement AttributeElement} from another by removing\n\t * corresponding attributes, classes and styles. All attributes, classes and styles from wrapper should be present\n\t * inside element being unwrapped.\n\t *\n\t * @param wrapper Wrapper AttributeElement.\n\t * @param toUnwrap AttributeElement to unwrap using wrapper element.\n\t * @returns Returns `true` if elements are unwrapped.\n\t **/ _unwrapAttributeElement(wrapper, toUnwrap) {\n        if (!canBeJoined(wrapper, toUnwrap)) {\n            return false;\n        }\n        // Can't unwrap if name or priority differs.\n        if (wrapper.name !== toUnwrap.name || wrapper.priority !== toUnwrap.priority) {\n            return false;\n        }\n        // Check if AttributeElement has all wrapper attributes.\n        for (const key of wrapper.getAttributeKeys()){\n            // Classes and styles should be checked separately.\n            if (key === 'class' || key === 'style') {\n                continue;\n            }\n            // If some attributes are missing or different we cannot unwrap.\n            if (!toUnwrap.hasAttribute(key) || toUnwrap.getAttribute(key) !== wrapper.getAttribute(key)) {\n                return false;\n            }\n        }\n        // Check if AttributeElement has all wrapper classes.\n        if (!toUnwrap.hasClass(...wrapper.getClassNames())) {\n            return false;\n        }\n        // Check if AttributeElement has all wrapper styles.\n        for (const key of wrapper.getStyleNames()){\n            // If some styles are missing or different we cannot unwrap.\n            if (!toUnwrap.hasStyle(key) || toUnwrap.getStyle(key) !== wrapper.getStyle(key)) {\n                return false;\n            }\n        }\n        // Remove all wrapper's attributes from unwrapped element.\n        for (const key of wrapper.getAttributeKeys()){\n            // Classes and styles should be checked separately.\n            if (key === 'class' || key === 'style') {\n                continue;\n            }\n            this.removeAttribute(key, toUnwrap);\n        }\n        // Remove all wrapper's classes from unwrapped element.\n        this.removeClass(Array.from(wrapper.getClassNames()), toUnwrap);\n        // Remove all wrapper's styles from unwrapped element.\n        this.removeStyle(Array.from(wrapper.getStyleNames()), toUnwrap);\n        return true;\n    }\n    /**\n\t * Helper function used by other `DowncastWriter` methods. Breaks attribute elements at the boundaries of given range.\n\t *\n\t * @param range Range which `start` and `end` positions will be used to break attributes.\n\t * @param forceSplitText If set to `true`, will break text nodes even if they are directly in container element.\n\t * This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t * @returns New range with located at break positions.\n\t */ _breakAttributesRange(range, forceSplitText = false) {\n        const rangeStart = range.start;\n        const rangeEnd = range.end;\n        validateRangeContainer(range, this.document);\n        // Break at the collapsed position. Return new collapsed range.\n        if (range.isCollapsed) {\n            const position = this._breakAttributes(range.start, forceSplitText);\n            return new Range$1(position, position);\n        }\n        const breakEnd = this._breakAttributes(rangeEnd, forceSplitText);\n        const count = breakEnd.parent.childCount;\n        const breakStart = this._breakAttributes(rangeStart, forceSplitText);\n        // Calculate new break end offset.\n        breakEnd.offset += breakEnd.parent.childCount - count;\n        return new Range$1(breakStart, breakEnd);\n    }\n    /**\n\t * Helper function used by other `DowncastWriter` methods. Breaks attribute elements at given position.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element` when break position\n\t * is placed inside {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element` when break position\n\t * is placed inside {@link module:engine/view/uielement~UIElement UIElement}.\n\t *\n\t * @param position Position where to break attributes.\n\t * @param forceSplitText If set to `true`, will break text nodes even if they are directly in container element.\n\t * This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t * @returns New position after breaking the attributes.\n\t */ _breakAttributes(position, forceSplitText = false) {\n        const positionOffset = position.offset;\n        const positionParent = position.parent;\n        // If position is placed inside EmptyElement - throw an exception as we cannot break inside.\n        if (position.parent.is('emptyElement')) {\n            /**\n\t\t\t * Cannot break an `EmptyElement` instance.\n\t\t\t *\n\t\t\t * This error is thrown if\n\t\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes `DowncastWriter#breakAttributes()`}\n\t\t\t * was executed in an incorrect position.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-empty-element\n\t\t\t */ throw new CKEditorError('view-writer-cannot-break-empty-element', this.document);\n        }\n        // If position is placed inside UIElement - throw an exception as we cannot break inside.\n        if (position.parent.is('uiElement')) {\n            /**\n\t\t\t * Cannot break a `UIElement` instance.\n\t\t\t *\n\t\t\t * This error is thrown if\n\t\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes `DowncastWriter#breakAttributes()`}\n\t\t\t * was executed in an incorrect position.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-ui-element\n\t\t\t */ throw new CKEditorError('view-writer-cannot-break-ui-element', this.document);\n        }\n        // If position is placed inside RawElement - throw an exception as we cannot break inside.\n        if (position.parent.is('rawElement')) {\n            /**\n\t\t\t * Cannot break a `RawElement` instance.\n\t\t\t *\n\t\t\t * This error is thrown if\n\t\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes `DowncastWriter#breakAttributes()`}\n\t\t\t * was executed in an incorrect position.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-raw-element\n\t\t\t */ throw new CKEditorError('view-writer-cannot-break-raw-element', this.document);\n        }\n        // There are no attributes to break and text nodes breaking is not forced.\n        if (!forceSplitText && positionParent.is('$text') && isContainerOrFragment(positionParent.parent)) {\n            return position.clone();\n        }\n        // Position's parent is container, so no attributes to break.\n        if (isContainerOrFragment(positionParent)) {\n            return position.clone();\n        }\n        // Break text and start again in new position.\n        if (positionParent.is('$text')) {\n            return this._breakAttributes(breakTextNode(position), forceSplitText);\n        }\n        const length = positionParent.childCount;\n        // <p>foo<b><u>bar{}</u></b></p>\n        // <p>foo<b><u>bar</u>[]</b></p>\n        // <p>foo<b><u>bar</u></b>[]</p>\n        if (positionOffset == length) {\n            const newPosition = new Position$1(positionParent.parent, positionParent.index + 1);\n            return this._breakAttributes(newPosition, forceSplitText);\n        } else {\n            // <p>foo<b><u>{}bar</u></b></p>\n            // <p>foo<b>[]<u>bar</u></b></p>\n            // <p>foo{}<b><u>bar</u></b></p>\n            if (positionOffset === 0) {\n                const newPosition = new Position$1(positionParent.parent, positionParent.index);\n                return this._breakAttributes(newPosition, forceSplitText);\n            } else {\n                const offsetAfter = positionParent.index + 1;\n                // Break element.\n                const clonedNode = positionParent._clone();\n                // Insert cloned node to position's parent node.\n                positionParent.parent._insertChild(offsetAfter, clonedNode);\n                this._addToClonedElementsGroup(clonedNode);\n                // Get nodes to move.\n                const count = positionParent.childCount - positionOffset;\n                const nodesToMove = positionParent._removeChildren(positionOffset, count);\n                // Move nodes to cloned node.\n                clonedNode._appendChild(nodesToMove);\n                // Create new position to work on.\n                const newPosition = new Position$1(positionParent.parent, offsetAfter);\n                return this._breakAttributes(newPosition, forceSplitText);\n            }\n        }\n    }\n    /**\n\t * Stores the information that an {@link module:engine/view/attributeelement~AttributeElement attribute element} was\n\t * added to the tree. Saves the reference to the group in the given element and updates the group, so other elements\n\t * from the group now keep a reference to the given attribute element.\n\t *\n\t * The clones group can be obtained using {@link module:engine/view/attributeelement~AttributeElement#getElementsWithSameId}.\n\t *\n\t * Does nothing if added element has no {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t *\n\t * @param element Attribute element to save.\n\t */ _addToClonedElementsGroup(element) {\n        // Add only if the element is in document tree.\n        if (!element.root.is('rootElement')) {\n            return;\n        }\n        // Traverse the element's children recursively to find other attribute elements that also might got inserted.\n        // The loop is at the beginning so we can make fast returns later in the code.\n        if (element.is('element')) {\n            for (const child of element.getChildren()){\n                this._addToClonedElementsGroup(child);\n            }\n        }\n        const id = element.id;\n        if (!id) {\n            return;\n        }\n        let group = this._cloneGroups.get(id);\n        if (!group) {\n            group = new Set();\n            this._cloneGroups.set(id, group);\n        }\n        group.add(element);\n        element._clonesGroup = group;\n    }\n    /**\n\t * Removes all the information about the given {@link module:engine/view/attributeelement~AttributeElement attribute element}\n\t * from its clones group.\n\t *\n\t * Keep in mind, that the element will still keep a reference to the group (but the group will not keep a reference to it).\n\t * This allows to reference the whole group even if the element was already removed from the tree.\n\t *\n\t * Does nothing if the element has no {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t *\n\t * @param element Attribute element to remove.\n\t */ _removeFromClonedElementsGroup(element) {\n        // Traverse the element's children recursively to find other attribute elements that also got removed.\n        // The loop is at the beginning so we can make fast returns later in the code.\n        if (element.is('element')) {\n            for (const child of element.getChildren()){\n                this._removeFromClonedElementsGroup(child);\n            }\n        }\n        const id = element.id;\n        if (!id) {\n            return;\n        }\n        const group = this._cloneGroups.get(id);\n        if (!group) {\n            return;\n        }\n        group.delete(element);\n    // Not removing group from element on purpose!\n    // If other parts of code have reference to this element, they will be able to get references to other elements from the group.\n    }\n}\n// Helper function for `view.writer.wrap`. Checks if given element has any children that are not ui elements.\nfunction _hasNonUiChildren(parent) {\n    return Array.from(parent.getChildren()).some((child)=>!child.is('uiElement'));\n}\n/**\n * The `attribute` passed to {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#wrap()`}\n * must be an instance of {@link module:engine/view/attributeelement~AttributeElement `AttributeElement`}.\n *\n * @error view-writer-wrap-invalid-attribute\n */ /**\n * Returns first parent container of specified {@link module:engine/view/position~Position Position}.\n * Position's parent node is checked as first, then next parents are checked.\n * Note that {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n *\n * @param position Position used as a start point to locate parent container.\n * @returns Parent container element or `undefined` if container is not found.\n */ function getParentContainer(position) {\n    let parent = position.parent;\n    while(!isContainerOrFragment(parent)){\n        if (!parent) {\n            return undefined;\n        }\n        parent = parent.parent;\n    }\n    return parent;\n}\n/**\n * Checks if first {@link module:engine/view/attributeelement~AttributeElement AttributeElement} provided to the function\n * can be wrapped outside second element. It is done by comparing elements'\n * {@link module:engine/view/attributeelement~AttributeElement#priority priorities}, if both have same priority\n * {@link module:engine/view/element~Element#getIdentity identities} are compared.\n */ function shouldABeOutsideB(a, b) {\n    if (a.priority < b.priority) {\n        return true;\n    } else if (a.priority > b.priority) {\n        return false;\n    }\n    // When priorities are equal and names are different - use identities.\n    return a.getIdentity() < b.getIdentity();\n}\n/**\n * Returns new position that is moved to near text node. Returns same position if there is no text node before of after\n * specified position.\n *\n * ```html\n * <p>foo[]</p>  ->  <p>foo{}</p>\n * <p>[]foo</p>  ->  <p>{}foo</p>\n * ```\n *\n * @returns Position located inside text node or same position if there is no text nodes\n * before or after position location.\n */ function movePositionToTextNode(position) {\n    const nodeBefore = position.nodeBefore;\n    if (nodeBefore && nodeBefore.is('$text')) {\n        return new Position$1(nodeBefore, nodeBefore.data.length);\n    }\n    const nodeAfter = position.nodeAfter;\n    if (nodeAfter && nodeAfter.is('$text')) {\n        return new Position$1(nodeAfter, 0);\n    }\n    return position;\n}\n/**\n * Breaks text node into two text nodes when possible.\n *\n * ```html\n * <p>foo{}bar</p> -> <p>foo[]bar</p>\n * <p>{}foobar</p> -> <p>[]foobar</p>\n * <p>foobar{}</p> -> <p>foobar[]</p>\n * ```\n *\n * @param position Position that need to be placed inside text node.\n * @returns New position after breaking text node.\n */ function breakTextNode(position) {\n    if (position.offset == position.parent.data.length) {\n        return new Position$1(position.parent.parent, position.parent.index + 1);\n    }\n    if (position.offset === 0) {\n        return new Position$1(position.parent.parent, position.parent.index);\n    }\n    // Get part of the text that need to be moved.\n    const textToMove = position.parent.data.slice(position.offset);\n    // Leave rest of the text in position's parent.\n    position.parent._data = position.parent.data.slice(0, position.offset);\n    // Insert new text node after position's parent text node.\n    position.parent.parent._insertChild(position.parent.index + 1, new Text$1(position.root.document, textToMove));\n    // Return new position between two newly created text nodes.\n    return new Position$1(position.parent.parent, position.parent.index + 1);\n}\n/**\n * Merges two text nodes into first node. Removes second node and returns merge position.\n *\n * @param t1 First text node to merge. Data from second text node will be moved at the end of this text node.\n * @param t2 Second text node to merge. This node will be removed after merging.\n * @returns Position after merging text nodes.\n */ function mergeTextNodes(t1, t2) {\n    // Merge text data into first text node and remove second one.\n    const nodeBeforeLength = t1.data.length;\n    t1._data += t2.data;\n    t2._remove();\n    return new Position$1(t1, nodeBeforeLength);\n}\nconst validNodesToInsert = [\n    Text$1,\n    AttributeElement,\n    ContainerElement,\n    EmptyElement,\n    RawElement,\n    UIElement\n];\n/**\n * Checks if provided nodes are valid to insert.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n * contains instances that are not supported ones (see error description for valid ones.\n */ function validateNodesToInsert(nodes, errorContext) {\n    for (const node of nodes){\n        if (!validNodesToInsert.some((validNode)=>node instanceof validNode)) {\n            /**\n\t\t\t * One of the nodes to be inserted is of an invalid type.\n\t\t\t *\n\t\t\t * Nodes to be inserted with {@link module:engine/view/downcastwriter~DowncastWriter#insert `DowncastWriter#insert()`} should be\n\t\t\t * of the following types:\n\t\t\t *\n\t\t\t * * {@link module:engine/view/attributeelement~AttributeElement AttributeElement},\n\t\t\t * * {@link module:engine/view/containerelement~ContainerElement ContainerElement},\n\t\t\t * * {@link module:engine/view/emptyelement~EmptyElement EmptyElement},\n\t\t\t * * {@link module:engine/view/uielement~UIElement UIElement},\n\t\t\t * * {@link module:engine/view/rawelement~RawElement RawElement},\n\t\t\t * * {@link module:engine/view/text~Text Text}.\n\t\t\t *\n\t\t\t * @error view-writer-insert-invalid-node-type\n\t\t\t */ throw new CKEditorError('view-writer-insert-invalid-node-type', errorContext);\n        }\n        if (!node.is('$text')) {\n            validateNodesToInsert(node.getChildren(), errorContext);\n        }\n    }\n}\n/**\n * Checks if node is ContainerElement or DocumentFragment, because in most cases they should be treated the same way.\n *\n * @returns Returns `true` if node is instance of ContainerElement or DocumentFragment.\n */ function isContainerOrFragment(node) {\n    return node && (node.is('containerElement') || node.is('documentFragment'));\n}\n/**\n * Checks if {@link module:engine/view/range~Range#start range start} and {@link module:engine/view/range~Range#end range end} are placed\n * inside same {@link module:engine/view/containerelement~ContainerElement container element}.\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when validation fails.\n */ function validateRangeContainer(range, errorContext) {\n    const startContainer = getParentContainer(range.start);\n    const endContainer = getParentContainer(range.end);\n    if (!startContainer || !endContainer || startContainer !== endContainer) {\n        /**\n\t\t * The container of the given range is invalid.\n\t\t *\n\t\t * This may happen if {@link module:engine/view/range~Range#start range start} and\n\t\t * {@link module:engine/view/range~Range#end range end} positions are not placed inside the same container element or\n\t\t * a parent container for these positions cannot be found.\n\t\t *\n\t\t * Methods like {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#remove()`},\n\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#clean()`},\n\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#wrap()`},\n\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#unwrap()`} need to be called\n\t\t * on a range that has its start and end positions located in the same container element. Both positions can be\n\t\t * nested within other elements (e.g. an attribute element) but the closest container ancestor must be the same.\n\t\t *\n\t\t * @error view-writer-invalid-range-container\n\t\t */ throw new CKEditorError('view-writer-invalid-range-container', errorContext);\n    }\n}\n/**\n * Checks if two attribute elements can be joined together. Elements can be joined together if, and only if\n * they do not have ids specified.\n */ function canBeJoined(a, b) {\n    return a.id === null && b.id === null;\n}\n\n/**\n * Set of utilities related to handling block and inline fillers.\n *\n * Browsers do not allow to put caret in elements which does not have height. Because of it, we need to fill all\n * empty elements which should be selectable with elements or characters called \"fillers\". Unfortunately there is no one\n * universal filler, this is why two types are uses:\n *\n * * Block filler is an element which fill block elements, like `<p>`. CKEditor uses `<br>` as a block filler during the editing,\n * as browsers do natively. So instead of an empty `<p>` there will be `<p><br></p>`. The advantage of block filler is that\n * it is transparent for the selection, so when the caret is before the `<br>` and user presses right arrow he will be\n * moved to the next paragraph, not after the `<br>`. The disadvantage is that it breaks a block, so it can not be used\n * in the middle of a line of text. The {@link module:engine/view/filler~BR_FILLER `<br>` filler} can be replaced with any other\n * character in the data output, for instance {@link module:engine/view/filler~NBSP_FILLER non-breaking space} or\n * {@link module:engine/view/filler~MARKED_NBSP_FILLER marked non-breaking space}.\n *\n * * Inline filler is a filler which does not break a line of text, so it can be used inside the text, for instance in the empty\n * `<b>` surrendered by text: `foo<b></b>bar`, if we want to put the caret there. CKEditor uses a sequence of the zero-width\n * spaces as an {@link module:engine/view/filler~INLINE_FILLER inline filler} having the predetermined\n * {@link module:engine/view/filler~INLINE_FILLER_LENGTH length}. A sequence is used, instead of a single character to\n * avoid treating random zero-width spaces as the inline filler. Disadvantage of the inline filler is that it is not\n * transparent for the selection. The arrow key moves the caret between zero-width spaces characters, so the additional\n * code is needed to handle the caret.\n *\n * Both inline and block fillers are handled by the {@link module:engine/view/renderer~Renderer renderer} and are not present in the\n * view.\n *\n * @module engine/view/filler\n */ /**\n * Non-breaking space filler creator. This function creates the `&nbsp;` text node.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~MARKED_NBSP_FILLER\n * @see module:engine/view/filler~BR_FILLER\n */ const NBSP_FILLER = (domDocument)=>domDocument.createTextNode('\\u00A0');\n/**\n * Marked non-breaking space filler creator. This function creates the `<span data-cke-filler=\"true\">&nbsp;</span>` element.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~NBSP_FILLER\n * @see module:engine/view/filler~BR_FILLER\n */ const MARKED_NBSP_FILLER = (domDocument)=>{\n    const span = domDocument.createElement('span');\n    span.dataset.ckeFiller = 'true';\n    span.innerText = '\\u00A0';\n    return span;\n};\n/**\n * `<br>` filler creator. This function creates the `<br data-cke-filler=\"true\">` element.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~NBSP_FILLER\n * @see module:engine/view/filler~MARKED_NBSP_FILLER\n */ const BR_FILLER = (domDocument)=>{\n    const fillerBr = domDocument.createElement('br');\n    fillerBr.dataset.ckeFiller = 'true';\n    return fillerBr;\n};\n/**\n * Length of the {@link module:engine/view/filler~INLINE_FILLER INLINE_FILLER}.\n */ const INLINE_FILLER_LENGTH = 7;\n/**\n * Inline filler which is a sequence of the word joiners.\n */ const INLINE_FILLER = '\\u2060'.repeat(INLINE_FILLER_LENGTH);\n/**\n * Checks if the node is a text node which starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n *\n * ```ts\n * startsWithFiller( document.createTextNode( INLINE_FILLER ) ); // true\n * startsWithFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // true\n * startsWithFiller( document.createTextNode( 'foo' ) ); // false\n * startsWithFiller( document.createElement( 'p' ) ); // false\n * ```\n *\n * @param domNode DOM node.\n * @returns True if the text node starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */ function startsWithFiller(domNode) {\n    if (typeof domNode == 'string') {\n        return domNode.substr(0, INLINE_FILLER_LENGTH) === INLINE_FILLER;\n    }\n    return isText(domNode) && domNode.data.substr(0, INLINE_FILLER_LENGTH) === INLINE_FILLER;\n}\n/**\n * Checks if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n *\n * ```ts\n * isInlineFiller( document.createTextNode( INLINE_FILLER ) ); // true\n * isInlineFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // false\n * ```\n *\n * @param domText DOM text node.\n * @returns True if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */ function isInlineFiller(domText) {\n    return domText.data.length == INLINE_FILLER_LENGTH && startsWithFiller(domText);\n}\n/**\n * Get string data from the text node, removing an {@link module:engine/view/filler~INLINE_FILLER inline filler} from it,\n * if text node contains it.\n *\n * ```ts\n * getDataWithoutFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ) == 'foo' // true\n * getDataWithoutFiller( document.createTextNode( 'foo' ) ) == 'foo' // true\n * ```\n *\n * @param domText DOM text node, possible with inline filler.\n * @returns Data without filler.\n */ function getDataWithoutFiller(domText) {\n    const data = typeof domText == 'string' ? domText : domText.data;\n    if (startsWithFiller(domText)) {\n        return data.slice(INLINE_FILLER_LENGTH);\n    }\n    return data;\n}\n/**\n * Assign key observer which move cursor from the end of the inline filler to the beginning of it when\n * the left arrow is pressed, so the filler does not break navigation.\n *\n * @param view View controller instance we should inject quirks handling on.\n */ function injectQuirksHandling(view) {\n    view.document.on('arrowKey', jumpOverInlineFiller, {\n        priority: 'low'\n    });\n}\n/**\n * Move cursor from the end of the inline filler to the beginning of it when, so the filler does not break navigation.\n */ function jumpOverInlineFiller(evt, data) {\n    if (data.keyCode == keyCodes.arrowleft) {\n        const domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n        if (domSelection.rangeCount == 1 && domSelection.getRangeAt(0).collapsed) {\n            const domParent = domSelection.getRangeAt(0).startContainer;\n            const domOffset = domSelection.getRangeAt(0).startOffset;\n            if (startsWithFiller(domParent) && domOffset <= INLINE_FILLER_LENGTH) {\n                domSelection.collapse(domParent, 0);\n            }\n        }\n    }\n}\n\n/**\n * Renderer is responsible for updating the DOM structure and the DOM selection based on\n * the {@link module:engine/view/renderer~Renderer#markToSync information about updated view nodes}.\n * In other words, it renders the view to the DOM.\n *\n * Its main responsibility is to make only the necessary, minimal changes to the DOM. However, unlike in many\n * virtual DOM implementations, the primary reason for doing minimal changes is not the performance but ensuring\n * that native editing features such as text composition, autocompletion, spell checking, selection's x-index are\n * affected as little as possible.\n *\n * Renderer uses {@link module:engine/view/domconverter~DomConverter} to transform view nodes and positions\n * to and from the DOM.\n */ class Renderer extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * Set of DOM Documents instances.\n\t */ domDocuments = new Set();\n    /**\n\t * Converter instance.\n\t */ domConverter;\n    /**\n\t * Set of nodes which attributes changed and may need to be rendered.\n\t */ markedAttributes = new Set();\n    /**\n\t * Set of elements which child lists changed and may need to be rendered.\n\t */ markedChildren = new Set();\n    /**\n\t * Set of text nodes which text data changed and may need to be rendered.\n\t */ markedTexts = new Set();\n    /**\n\t * View selection. Renderer updates DOM selection based on the view selection.\n\t */ selection;\n    /**\n\t * The text node in which the inline filler was rendered.\n\t */ _inlineFiller = null;\n    /**\n\t * DOM element containing fake selection.\n\t */ _fakeSelectionContainer = null;\n    /**\n\t * Creates a renderer instance.\n\t *\n\t * @param domConverter Converter instance.\n\t * @param selection View selection.\n\t */ constructor(domConverter, selection){\n        super();\n        this.domConverter = domConverter;\n        this.selection = selection;\n        this.set('isFocused', false);\n        this.set('isSelecting', false);\n        this.set('isComposing', false);\n        // Rendering the selection and inline filler manipulation should be postponed in (non-Android) Blink until the user finishes\n        // creating the selection in DOM to avoid accidental selection collapsing\n        // (https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723).\n        // When the user stops selecting, all pending changes should be rendered ASAP, though.\n        if (env.isBlink && !env.isAndroid) {\n            this.on('change:isSelecting', ()=>{\n                if (!this.isSelecting) {\n                    this.render();\n                }\n            });\n        }\n    }\n    /**\n\t * Marks a view node to be updated in the DOM by {@link #render `render()`}.\n\t *\n\t * Note that only view nodes whose parents have corresponding DOM elements need to be marked to be synchronized.\n\t *\n\t * @see #markedAttributes\n\t * @see #markedChildren\n\t * @see #markedTexts\n\t *\n\t * @param type Type of the change.\n\t * @param node ViewNode to be marked.\n\t */ markToSync(type, node) {\n        if (type === 'text') {\n            if (this.domConverter.mapViewToDom(node.parent)) {\n                this.markedTexts.add(node);\n            }\n        } else {\n            // If the node has no DOM element it is not rendered yet,\n            // its children/attributes do not need to be marked to be sync.\n            if (!this.domConverter.mapViewToDom(node)) {\n                return;\n            }\n            if (type === 'attributes') {\n                this.markedAttributes.add(node);\n            } else if (type === 'children') {\n                this.markedChildren.add(node);\n            } else {\n                /**\n\t\t\t\t * Unknown type passed to Renderer.markToSync.\n\t\t\t\t *\n\t\t\t\t * @error view-renderer-unknown-type\n\t\t\t\t */ throw new CKEditorError('view-renderer-unknown-type', this);\n            }\n        }\n    }\n    /**\n\t * Renders all buffered changes ({@link #markedAttributes}, {@link #markedChildren} and {@link #markedTexts}) and\n\t * the current view selection (if needed) to the DOM by applying a minimal set of changes to it.\n\t *\n\t * Renderer tries not to break the text composition (e.g. IME) and x-index of the selection,\n\t * so it does as little as it is needed to update the DOM.\n\t *\n\t * Renderer also handles {@link module:engine/view/filler fillers}. Especially, it checks if the inline filler is needed\n\t * at the selection position and adds or removes it. To prevent breaking text composition inline filler will not be\n\t * removed as long as the selection is in the text node which needed it at first.\n\t */ render() {\n        // Ignore rendering while in the composition mode. Composition events are not cancellable and browser will modify the DOM tree.\n        // All marked elements, attributes, etc. will wait until next render after the composition ends.\n        // On Android composition events are immediately applied to the model, so we don't need to skip rendering,\n        // and we should not do it because the difference between view and DOM could lead to position mapping problems.\n        if (this.isComposing && !env.isAndroid) {\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Rendering aborted while isComposing.',\n            // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic'\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            return;\n        }\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.group( '%c[Renderer]%c Rendering',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        let inlineFillerPosition = null;\n        const isInlineFillerRenderingPossible = env.isBlink && !env.isAndroid ? !this.isSelecting : true;\n        // Refresh mappings.\n        for (const element of this.markedChildren){\n            this._updateChildrenMappings(element);\n        }\n        // Don't manipulate inline fillers while the selection is being made in (non-Android) Blink to prevent accidental\n        // DOM selection collapsing\n        // (https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723).\n        if (isInlineFillerRenderingPossible) {\n            // There was inline filler rendered in the DOM but it's not\n            // at the selection position any more, so we can remove it\n            // (cause even if it's needed, it must be placed in another location).\n            if (this._inlineFiller && !this._isSelectionInInlineFiller()) {\n                this._removeInlineFiller();\n            }\n            // If we've got the filler, let's try to guess its position in the view.\n            if (this._inlineFiller) {\n                inlineFillerPosition = this._getInlineFillerPosition();\n            } else if (this._needsInlineFillerAtSelection()) {\n                inlineFillerPosition = this.selection.getFirstPosition();\n                // Do not use `markToSync` so it will be added even if the parent is already added.\n                this.markedChildren.add(inlineFillerPosition.parent);\n            }\n        } else if (this._inlineFiller && this._inlineFiller.parentNode) {\n            // While the user is making selection, preserve the inline filler at its original position.\n            inlineFillerPosition = this.domConverter.domPositionToView(this._inlineFiller);\n            // While down-casting the document selection attributes, all existing empty\n            // attribute elements (for selection position) are removed from the view and DOM,\n            // so make sure that we were able to map filler position.\n            // https://github.com/ckeditor/ckeditor5/issues/12026\n            if (inlineFillerPosition && inlineFillerPosition.parent.is('$text')) {\n                // The inline filler position is expected to be before the text node.\n                inlineFillerPosition = Position$1._createBefore(inlineFillerPosition.parent);\n            }\n        }\n        for (const element of this.markedAttributes){\n            this._updateAttrs(element);\n        }\n        for (const element of this.markedChildren){\n            this._updateChildren(element, {\n                inlineFillerPosition\n            });\n        }\n        for (const node of this.markedTexts){\n            if (!this.markedChildren.has(node.parent) && this.domConverter.mapViewToDom(node.parent)) {\n                this._updateText(node, {\n                    inlineFillerPosition\n                });\n            }\n        }\n        // * Check whether the inline filler is required and where it really is in the DOM.\n        //   At this point in most cases it will be in the DOM, but there are exceptions.\n        //   For example, if the inline filler was deep in the created DOM structure, it will not be created.\n        //   Similarly, if it was removed at the beginning of this function and then neither text nor children were updated,\n        //   it will not be present. Fix those and similar scenarios.\n        // * Don't manipulate inline fillers while the selection is being made in (non-Android) Blink to prevent accidental\n        //   DOM selection collapsing\n        //   (https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723).\n        if (isInlineFillerRenderingPossible) {\n            if (inlineFillerPosition) {\n                const fillerDomPosition = this.domConverter.viewPositionToDom(inlineFillerPosition);\n                const domDocument = fillerDomPosition.parent.ownerDocument;\n                if (!startsWithFiller(fillerDomPosition.parent)) {\n                    // Filler has not been created at filler position. Create it now.\n                    this._inlineFiller = addInlineFiller(domDocument, fillerDomPosition.parent, fillerDomPosition.offset);\n                } else {\n                    // Filler has been found, save it.\n                    this._inlineFiller = fillerDomPosition.parent;\n                }\n            } else {\n                // There is no filler needed.\n                this._inlineFiller = null;\n            }\n        }\n        // First focus the new editing host, then update the selection.\n        // Otherwise, FF may throw an error (https://github.com/ckeditor/ckeditor5/issues/721).\n        this._updateFocus();\n        this._updateSelection();\n        this.domConverter._clearTemporaryCustomProperties();\n        this.markedTexts.clear();\n        this.markedAttributes.clear();\n        this.markedChildren.clear();\n    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n    // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n    // @if CK_DEBUG_TYPING // }\n    }\n    /**\n\t * Updates mappings of view element's children.\n\t *\n\t * Children that were replaced in the view structure by similar elements (same tag name) are treated as 'replaced'.\n\t * This means that their mappings can be updated so the new view elements are mapped to the existing DOM elements.\n\t * Thanks to that these elements do not need to be re-rendered completely.\n\t *\n\t * @param viewElement The view element whose children mappings will be updated.\n\t */ _updateChildrenMappings(viewElement) {\n        const domElement = this.domConverter.mapViewToDom(viewElement);\n        if (!domElement) {\n            // If there is no `domElement` it means that it was already removed from DOM and there is no need to process it.\n            return;\n        }\n        // Removing nodes from the DOM as we iterate can cause `actualDomChildren`\n        // (which is a live-updating `NodeList`) to get out of sync with the\n        // indices that we compute as we iterate over `actions`.\n        // This would produce incorrect element mappings.\n        //\n        // Converting live list to an array to make the list static.\n        const actualDomChildren = Array.from(domElement.childNodes);\n        const expectedDomChildren = Array.from(this.domConverter.viewChildrenToDom(viewElement, {\n            withChildren: false\n        }));\n        const diff = this._diffNodeLists(actualDomChildren, expectedDomChildren);\n        const actions = this._findUpdateActions(diff, actualDomChildren, expectedDomChildren, areSimilarElements);\n        if (actions.indexOf('update') !== -1) {\n            const counter = {\n                equal: 0,\n                insert: 0,\n                delete: 0\n            };\n            for (const action of actions){\n                if (action === 'update') {\n                    const insertIndex = counter.equal + counter.insert;\n                    const deleteIndex = counter.equal + counter.delete;\n                    const viewChild = viewElement.getChild(insertIndex);\n                    // UIElement and RawElement are special cases. Their children are not stored in a view (#799)\n                    // so we cannot use them with replacing flow (since they use view children during rendering\n                    // which will always result in rendering empty elements).\n                    if (viewChild && !viewChild.is('uiElement') && !viewChild.is('rawElement')) {\n                        this._updateElementMappings(viewChild, actualDomChildren[deleteIndex]);\n                    }\n                    remove$1(expectedDomChildren[insertIndex]);\n                    counter.equal++;\n                } else {\n                    counter[action]++;\n                }\n            }\n        }\n    }\n    /**\n\t * Updates mappings of a given view element.\n\t *\n\t * @param viewElement The view element whose mappings will be updated.\n\t * @param domElement The DOM element representing the given view element.\n\t */ _updateElementMappings(viewElement, domElement) {\n        // Remap 'DomConverter' bindings.\n        this.domConverter.unbindDomElement(domElement);\n        this.domConverter.bindElements(domElement, viewElement);\n        // View element may have children which needs to be updated, but are not marked, mark them to update.\n        this.markedChildren.add(viewElement);\n        // Because we replace new view element mapping with the existing one, the corresponding DOM element\n        // will not be rerendered. The new view element may have different attributes than the previous one.\n        // Since its corresponding DOM element will not be rerendered, new attributes will not be added\n        // to the DOM, so we need to mark it here to make sure its attributes gets updated. See #1427 for more\n        // detailed case study.\n        // Also there are cases where replaced element is removed from the view structure and then has\n        // its attributes changed or removed. In such cases the element will not be present in `markedAttributes`\n        // and also may be the same (`element.isSimilar()`) as the reused element not having its attributes updated.\n        // To prevent such situations we always mark reused element to have its attributes rerenderd (#1560).\n        this.markedAttributes.add(viewElement);\n    }\n    /**\n\t * Gets the position of the inline filler based on the current selection.\n\t * Here, we assume that we know that the filler is needed and\n\t * {@link #_isSelectionInInlineFiller is at the selection position}, and, since it is needed,\n\t * it is somewhere at the selection position.\n\t *\n\t * Note: The filler position cannot be restored based on the filler's DOM text node, because\n\t * when this method is called (before rendering), the bindings will often be broken. View-to-DOM\n\t * bindings are only dependable after rendering.\n\t */ _getInlineFillerPosition() {\n        const firstPos = this.selection.getFirstPosition();\n        if (firstPos.parent.is('$text')) {\n            return Position$1._createBefore(firstPos.parent);\n        } else {\n            return firstPos;\n        }\n    }\n    /**\n\t * Returns `true` if the selection has not left the inline filler's text node.\n\t * If it is `true`, it means that the filler had been added for a reason and the selection did not\n\t * leave the filler's text node. For example, the user can be in the middle of a composition so it should not be touched.\n\t *\n\t * @returns `true` if the inline filler and selection are in the same place.\n\t */ _isSelectionInInlineFiller() {\n        if (this.selection.rangeCount != 1 || !this.selection.isCollapsed) {\n            return false;\n        }\n        // Note, we can't check if selection's position equals position of the\n        // this._inlineFiller node, because of #663. We may not be able to calculate\n        // the filler's position in the view at this stage.\n        // Instead, we check it the other way – whether selection is anchored in\n        // that text node or next to it.\n        // Possible options are:\n        // \"FILLER{}\"\n        // \"FILLERadded-text{}\"\n        const selectionPosition = this.selection.getFirstPosition();\n        const position = this.domConverter.viewPositionToDom(selectionPosition);\n        if (position && isText(position.parent) && startsWithFiller(position.parent)) {\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Removes the inline filler.\n\t */ _removeInlineFiller() {\n        const domFillerNode = this._inlineFiller;\n        // Something weird happened and the stored node doesn't contain the filler's text.\n        if (!startsWithFiller(domFillerNode)) {\n            /**\n\t\t\t * The inline filler node was lost. Most likely, something overwrote the filler text node\n\t\t\t * in the DOM.\n\t\t\t *\n\t\t\t * @error view-renderer-filler-was-lost\n\t\t\t */ throw new CKEditorError('view-renderer-filler-was-lost', this);\n        }\n        if (isInlineFiller(domFillerNode)) {\n            domFillerNode.remove();\n        } else {\n            domFillerNode.data = domFillerNode.data.substr(INLINE_FILLER_LENGTH);\n        }\n        this._inlineFiller = null;\n    }\n    /**\n\t * Checks if the inline {@link module:engine/view/filler filler} should be added.\n\t *\n\t * @returns `true` if the inline filler should be added.\n\t */ _needsInlineFillerAtSelection() {\n        if (this.selection.rangeCount != 1 || !this.selection.isCollapsed) {\n            return false;\n        }\n        const selectionPosition = this.selection.getFirstPosition();\n        const selectionParent = selectionPosition.parent;\n        const selectionOffset = selectionPosition.offset;\n        // If there is no DOM root we do not care about fillers.\n        if (!this.domConverter.mapViewToDom(selectionParent.root)) {\n            return false;\n        }\n        if (!selectionParent.is('element')) {\n            return false;\n        }\n        // Prevent adding inline filler inside elements with contenteditable=false.\n        // https://github.com/ckeditor/ckeditor5-engine/issues/1170\n        if (!isEditable(selectionParent)) {\n            return false;\n        }\n        const nodeBefore = selectionPosition.nodeBefore;\n        const nodeAfter = selectionPosition.nodeAfter;\n        if (nodeBefore instanceof Text$1 || nodeAfter instanceof Text$1) {\n            return false;\n        }\n        // We have block filler, we do not need inline one.\n        if (selectionOffset === selectionParent.getFillerOffset() && (!nodeBefore || !nodeBefore.is('element', 'br'))) {\n            return false;\n        }\n        // Do not use inline filler while typing outside inline elements on Android.\n        // The deleteContentBackward would remove part of the inline filler instead of removing last letter in a link.\n        if (env.isAndroid && (nodeBefore || nodeAfter)) {\n            return false;\n        }\n        return true;\n    }\n    /**\n\t * Checks if text needs to be updated and possibly updates it.\n\t *\n\t * @param viewText View text to update.\n\t * @param options.inlineFillerPosition The position where the inline filler should be rendered.\n\t */ _updateText(viewText, options) {\n        const domText = this.domConverter.findCorrespondingDomText(viewText);\n        const newDomText = this.domConverter.viewToDom(viewText);\n        let expectedText = newDomText.data;\n        const filler = options.inlineFillerPosition;\n        if (filler && filler.parent == viewText.parent && filler.offset == viewText.index) {\n            expectedText = INLINE_FILLER + expectedText;\n        }\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.group( '%c[Renderer]%c Update text',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: normal'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        this._updateTextNode(domText, expectedText);\n    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n    // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n    // @if CK_DEBUG_TYPING // }\n    }\n    /**\n\t * Checks if attribute list needs to be updated and possibly updates it.\n\t *\n\t * @param viewElement The view element to update.\n\t */ _updateAttrs(viewElement) {\n        const domElement = this.domConverter.mapViewToDom(viewElement);\n        if (!domElement) {\n            // If there is no `domElement` it means that 'viewElement' is outdated as its mapping was updated\n            // in 'this._updateChildrenMappings()'. There is no need to process it as new view element which\n            // replaced old 'viewElement' mapping was also added to 'this.markedAttributes'\n            // in 'this._updateChildrenMappings()' so it will be processed separately.\n            return;\n        }\n        // Remove attributes from DOM elements if they do not exist in the view.\n        //\n        // Note: It is important to first remove DOM attributes and then set new ones, because some view attributes may be renamed\n        // as they are set on DOM (due to unsafe attributes handling). If we set the view attribute first, and then remove\n        // non-existing DOM attributes, then we would remove the attribute that we just set.\n        for (const domAttr of domElement.attributes){\n            const key = domAttr.name;\n            // All other attributes not present in the DOM should be removed.\n            if (!viewElement.hasAttribute(key)) {\n                this.domConverter.removeDomElementAttribute(domElement, key);\n            }\n        }\n        // Add or overwrite attributes.\n        for (const key of viewElement.getAttributeKeys()){\n            this.domConverter.setDomElementAttribute(domElement, key, viewElement.getAttribute(key), viewElement);\n        }\n    }\n    /**\n\t * Checks if elements child list needs to be updated and possibly updates it.\n\t *\n\t * Note that on Android, to reduce the risk of composition breaks, it tries to update data of an existing\n\t * child text nodes instead of replacing them completely.\n\t *\n\t * @param viewElement View element to update.\n\t * @param options.inlineFillerPosition The position where the inline filler should be rendered.\n\t */ _updateChildren(viewElement, options) {\n        const domElement = this.domConverter.mapViewToDom(viewElement);\n        if (!domElement) {\n            // If there is no `domElement` it means that it was already removed from DOM.\n            // There is no need to process it. It will be processed when re-inserted.\n            return;\n        }\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.group( '%c[Renderer]%c Update children',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: normal'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        // IME on Android inserts a new text node while typing after a link\n        // instead of updating an existing text node that follows the link.\n        // We must normalize those text nodes so the diff won't get confused.\n        // https://github.com/ckeditor/ckeditor5/issues/12574.\n        if (env.isAndroid) {\n            let previousDomNode = null;\n            for (const domNode of Array.from(domElement.childNodes)){\n                if (previousDomNode && isText(previousDomNode) && isText(domNode)) {\n                    domElement.normalize();\n                    break;\n                }\n                previousDomNode = domNode;\n            }\n        }\n        const inlineFillerPosition = options.inlineFillerPosition;\n        const actualDomChildren = domElement.childNodes;\n        const expectedDomChildren = Array.from(this.domConverter.viewChildrenToDom(viewElement, {\n            bind: true\n        }));\n        // Inline filler element has to be created as it is present in the DOM, but not in the view. It is required\n        // during diffing so text nodes could be compared correctly and also during rendering to maintain\n        // proper order and indexes while updating the DOM.\n        if (inlineFillerPosition && inlineFillerPosition.parent === viewElement) {\n            addInlineFiller(domElement.ownerDocument, expectedDomChildren, inlineFillerPosition.offset);\n        }\n        const diff = this._diffNodeLists(actualDomChildren, expectedDomChildren);\n        // We need to make sure that we update the existing text node and not replace it with another one.\n        // The composition and different \"language\" browser extensions are fragile to text node being completely replaced.\n        const actions = this._findUpdateActions(diff, actualDomChildren, expectedDomChildren, areTextNodes);\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping && actions.every( a => a == 'equal' ) ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Nothing to update.',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        let i = 0;\n        const nodesToUnbind = new Set();\n        // Handle deletions first.\n        // This is to prevent a situation where an element that already exists in `actualDomChildren` is inserted at a different\n        // index in `actualDomChildren`. Since `actualDomChildren` is a `NodeList`, this works like move, not like an insert,\n        // and it disrupts the whole algorithm. See https://github.com/ckeditor/ckeditor5/issues/6367.\n        //\n        // It doesn't matter in what order we remove or add nodes, as long as we remove and add correct nodes at correct indexes.\n        for (const action of actions){\n            if (action === 'delete') {\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING //\tconst node = actualDomChildren[ i ];\n                // @if CK_DEBUG_TYPING // \tif ( isText( node ) ) {\n                // @if CK_DEBUG_TYPING // \t\tconsole.info( '%c[Renderer]%c Remove text node' +\n                // @if CK_DEBUG_TYPING // \t\t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +\n                // @if CK_DEBUG_TYPING // \t\t\t`%c${ _escapeTextNodeData( node.data ) }%c (${ node.data.length })`,\n                // @if CK_DEBUG_TYPING // \t\t\t'color: green; font-weight: bold',\n                // @if CK_DEBUG_TYPING // \t\t\tthis.isComposing ? 'color: red; font-weight: bold' : '', 'color: blue', ''\n                // @if CK_DEBUG_TYPING // \t\t);\n                // @if CK_DEBUG_TYPING // \t} else {\n                // @if CK_DEBUG_TYPING // \t\tconsole.info( '%c[Renderer]%c Remove element' +\n                // @if CK_DEBUG_TYPING // \t\t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: `,\n                // @if CK_DEBUG_TYPING // \t\t\t'color: green; font-weight: bold',\n                // @if CK_DEBUG_TYPING // \t\t\tthis.isComposing ? 'color: red; font-weight: bold' : '',\n                // @if CK_DEBUG_TYPING // \t\t\tnode\n                // @if CK_DEBUG_TYPING // \t\t);\n                // @if CK_DEBUG_TYPING // \t}\n                // @if CK_DEBUG_TYPING // }\n                nodesToUnbind.add(actualDomChildren[i]);\n                remove$1(actualDomChildren[i]);\n            } else if (action === 'equal' || action === 'update') {\n                i++;\n            }\n        }\n        i = 0;\n        for (const action of actions){\n            if (action === 'insert') {\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING //\tconst node = expectedDomChildren[ i ];\n                // @if CK_DEBUG_TYPING //\tif ( isText( node ) ) {\n                // @if CK_DEBUG_TYPING //\t\tconsole.info( '%c[Renderer]%c Insert text node' +\n                // @if CK_DEBUG_TYPING //\t\t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +\n                // @if CK_DEBUG_TYPING //\t\t\t`%c${ _escapeTextNodeData( node.data ) }%c (${ node.data.length })`,\n                // @if CK_DEBUG_TYPING //\t\t\t'color: green; font-weight: bold',\n                // @if CK_DEBUG_TYPING //\t\t\tthis.isComposing ? 'color: red; font-weight: bold' : '',\n                // @if CK_DEBUG_TYPING //\t\t\t'color: blue', ''\n                // @if CK_DEBUG_TYPING //\t\t);\n                // @if CK_DEBUG_TYPING //\t} else {\n                // @if CK_DEBUG_TYPING //\t\tconsole.info( '%c[Renderer]%c Insert element:',\n                // @if CK_DEBUG_TYPING //\t\t\t'color: green; font-weight: bold', 'font-weight: normal',\n                // @if CK_DEBUG_TYPING //\t\t\tnode\n                // @if CK_DEBUG_TYPING //\t\t);\n                // @if CK_DEBUG_TYPING //\t}\n                // @if CK_DEBUG_TYPING // }\n                insertAt(domElement, i, expectedDomChildren[i]);\n                i++;\n            } else if (action === 'update') {\n                this._updateTextNode(actualDomChildren[i], expectedDomChildren[i].data);\n                i++;\n            } else if (action === 'equal') {\n                // Force updating text nodes inside elements which did not change and do not need to be re-rendered (#1125).\n                // Do it here (not in the loop above) because only after insertions the `i` index is correct.\n                this._markDescendantTextToSync(this.domConverter.domToView(expectedDomChildren[i]));\n                i++;\n            }\n        }\n        // Unbind removed nodes. When node does not have a parent it means that it was removed from DOM tree during\n        // comparison with the expected DOM. We don't need to check child nodes, because if child node was reinserted,\n        // it was moved to DOM tree out of the removed node.\n        for (const node of nodesToUnbind){\n            if (!node.parentNode) {\n                this.domConverter.unbindDomElement(node);\n            }\n        }\n    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n    // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n    // @if CK_DEBUG_TYPING // }\n    }\n    /**\n\t * Shorthand for diffing two arrays or node lists of DOM nodes.\n\t *\n\t * @param actualDomChildren Actual DOM children\n\t * @param expectedDomChildren Expected DOM children.\n\t * @returns The list of actions based on the {@link module:utils/diff~diff} function.\n\t */ _diffNodeLists(actualDomChildren, expectedDomChildren) {\n        actualDomChildren = filterOutFakeSelectionContainer(actualDomChildren, this._fakeSelectionContainer);\n        return diff(actualDomChildren, expectedDomChildren, sameNodes$1.bind(null, this.domConverter));\n    }\n    /**\n\t * Finds DOM nodes that were replaced with the similar nodes (same tag name) in the view. All nodes are compared\n\t * within one `insert`/`delete` action group, for example:\n\t *\n\t * ```\n\t * Actual DOM:\t\t<p><b>Foo</b>Bar<i>Baz</i><b>Bax</b></p>\n\t * Expected DOM:\t<p>Bar<b>123</b><i>Baz</i><b>456</b></p>\n\t * Input actions:\t[ insert, insert, delete, delete, equal, insert, delete ]\n\t * Output actions:\t[ insert, replace, delete, equal, replace ]\n\t * ```\n\t *\n\t * @param actions Actions array which is a result of the {@link module:utils/diff~diff} function.\n\t * @param actualDom Actual DOM children\n\t * @param expectedDom Expected DOM children.\n\t * @param comparator A comparator function that should return `true` if the given node should be reused\n\t * (either by the update of a text node data or an element children list for similar elements).\n\t * @returns Actions array modified with the `update` actions.\n\t */ _findUpdateActions(actions, actualDom, expectedDom, comparator) {\n        // If there is no both 'insert' and 'delete' actions, no need to check for replaced elements.\n        if (actions.indexOf('insert') === -1 || actions.indexOf('delete') === -1) {\n            return actions;\n        }\n        let newActions = [];\n        let actualSlice = [];\n        let expectedSlice = [];\n        const counter = {\n            equal: 0,\n            insert: 0,\n            delete: 0\n        };\n        for (const action of actions){\n            if (action === 'insert') {\n                expectedSlice.push(expectedDom[counter.equal + counter.insert]);\n            } else if (action === 'delete') {\n                actualSlice.push(actualDom[counter.equal + counter.delete]);\n            } else {\n                newActions = newActions.concat(diff(actualSlice, expectedSlice, comparator).map((action)=>action === 'equal' ? 'update' : action));\n                newActions.push('equal');\n                // Reset stored elements on 'equal'.\n                actualSlice = [];\n                expectedSlice = [];\n            }\n            counter[action]++;\n        }\n        return newActions.concat(diff(actualSlice, expectedSlice, comparator).map((action)=>action === 'equal' ? 'update' : action));\n    }\n    /**\n\t * Checks if text needs to be updated and possibly updates it by removing and inserting only parts\n\t * of the data from the existing text node to reduce impact on the IME composition.\n\t *\n\t * @param domText DOM text node to update.\n\t * @param expectedText The expected data of a text node.\n\t */ _updateTextNode(domText, expectedText) {\n        const actualText = domText.data;\n        if (actualText == expectedText) {\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Text node does not need update:%c ' +\n            // @if CK_DEBUG_TYPING // \t\t`${ _escapeTextNodeData( actualText ) }%c (${ actualText.length })`,\n            // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic', 'color: blue', ''\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            return;\n        }\n        // Our approach to interleaving space character with NBSP might differ with the one implemented by the browser.\n        // Avoid modifying the text node in the DOM if only NBSPs and spaces are interchanged.\n        // We should avoid DOM modifications while composing to avoid breakage of composition.\n        // See: https://github.com/ckeditor/ckeditor5/issues/13994.\n        if (env.isAndroid && this.isComposing && actualText.replace(/\\u00A0/g, ' ') == expectedText.replace(/\\u00A0/g, ' ')) {\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Text node ignore NBSP changes while composing: ' +\n            // @if CK_DEBUG_TYPING // \t\t`%c${ _escapeTextNodeData( actualText ) }%c (${ actualText.length }) ->` +\n            // @if CK_DEBUG_TYPING // \t\t` %c${ _escapeTextNodeData( expectedText ) }%c (${ expectedText.length })`,\n            // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic', 'color: blue', '', 'color: blue', ''\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            return;\n        }\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Update text node' +\n        // @if CK_DEBUG_TYPING // \t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +\n        // @if CK_DEBUG_TYPING // \t\t`%c${ _escapeTextNodeData( actualText ) }%c (${ actualText.length }) ->` +\n        // @if CK_DEBUG_TYPING // \t\t` %c${ _escapeTextNodeData( expectedText ) }%c (${ expectedText.length })`,\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', this.isComposing ? 'color: red; font-weight: bold' : '',\n        // @if CK_DEBUG_TYPING // \t\t'color: blue', '', 'color: blue', ''\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        this._updateTextNodeInternal(domText, expectedText);\n    }\n    /**\n\t * Part of the `_updateTextNode` method extracted for easier testing.\n\t */ _updateTextNodeInternal(domText, expectedText) {\n        const actions = fastDiff(domText.data, expectedText);\n        for (const action of actions){\n            if (action.type === 'insert') {\n                domText.insertData(action.index, action.values.join(''));\n            } else {\n                domText.deleteData(action.index, action.howMany);\n            }\n        }\n    }\n    /**\n\t * Marks text nodes to be synchronized.\n\t *\n\t * If a text node is passed, it will be marked. If an element is passed, all descendant text nodes inside it will be marked.\n\t *\n\t * @param viewNode View node to sync.\n\t */ _markDescendantTextToSync(viewNode) {\n        if (!viewNode) {\n            return;\n        }\n        if (viewNode.is('$text')) {\n            this.markedTexts.add(viewNode);\n        } else if (viewNode.is('element')) {\n            for (const child of viewNode.getChildren()){\n                this._markDescendantTextToSync(child);\n            }\n        }\n    }\n    /**\n\t * Checks if the selection needs to be updated and possibly updates it.\n\t */ _updateSelection() {\n        // Block updating DOM selection in (non-Android) Blink while the user is selecting to prevent accidental selection collapsing.\n        // Note: Structural changes in DOM must trigger selection rendering, though. Nodes the selection was anchored\n        // to, may disappear in DOM which would break the selection (e.g. in real-time collaboration scenarios).\n        // https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723\n        if (env.isBlink && !env.isAndroid && this.isSelecting && !this.markedChildren.size) {\n            return;\n        }\n        // If there is no selection - remove DOM and fake selections.\n        if (this.selection.rangeCount === 0) {\n            this._removeDomSelection();\n            this._removeFakeSelection();\n            return;\n        }\n        const domRoot = this.domConverter.mapViewToDom(this.selection.editableElement);\n        // Do nothing if there is no focus, or there is no DOM element corresponding to selection's editable element.\n        if (!this.isFocused || !domRoot) {\n            return;\n        }\n        // Render fake selection - create the fake selection container (if needed) and move DOM selection to it.\n        if (this.selection.isFake) {\n            this._updateFakeSelection(domRoot);\n        } else if (this._fakeSelectionContainer && this._fakeSelectionContainer.isConnected) {\n            this._removeFakeSelection();\n            this._updateDomSelection(domRoot);\n        } else if (!(this.isComposing && env.isAndroid)) {\n            this._updateDomSelection(domRoot);\n        }\n    }\n    /**\n\t * Updates the fake selection.\n\t *\n\t * @param domRoot A valid DOM root where the fake selection container should be added.\n\t */ _updateFakeSelection(domRoot) {\n        const domDocument = domRoot.ownerDocument;\n        if (!this._fakeSelectionContainer) {\n            this._fakeSelectionContainer = createFakeSelectionContainer(domDocument);\n        }\n        const container = this._fakeSelectionContainer;\n        // Bind fake selection container with the current selection *position*.\n        this.domConverter.bindFakeSelection(container, this.selection);\n        if (!this._fakeSelectionNeedsUpdate(domRoot)) {\n            return;\n        }\n        if (!container.parentElement || container.parentElement != domRoot) {\n            domRoot.appendChild(container);\n        }\n        container.textContent = this.selection.fakeSelectionLabel || '\\u00A0';\n        const domSelection = domDocument.getSelection();\n        const domRange = domDocument.createRange();\n        domSelection.removeAllRanges();\n        domRange.selectNodeContents(container);\n        domSelection.addRange(domRange);\n    }\n    /**\n\t * Updates the DOM selection.\n\t *\n\t * @param domRoot A valid DOM root where the DOM selection should be rendered.\n\t */ _updateDomSelection(domRoot) {\n        const domSelection = domRoot.ownerDocument.defaultView.getSelection();\n        // Let's check whether DOM selection needs updating at all.\n        if (!this._domSelectionNeedsUpdate(domSelection)) {\n            return;\n        }\n        // Multi-range selection is not available in most browsers, and, at least in Chrome, trying to\n        // set such selection, that is not continuous, throws an error. Because of that, we will just use anchor\n        // and focus of view selection.\n        // Since we are not supporting multi-range selection, we also do not need to check if proper editable is\n        // selected. If there is any editable selected, it is okay (editable is taken from selection anchor).\n        const anchor = this.domConverter.viewPositionToDom(this.selection.anchor);\n        const focus = this.domConverter.viewPositionToDom(this.selection.focus);\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Update DOM selection:',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', '', anchor, focus\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        domSelection.setBaseAndExtent(anchor.parent, anchor.offset, focus.parent, focus.offset);\n        // Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).\n        if (env.isGecko) {\n            fixGeckoSelectionAfterBr(focus, domSelection);\n        }\n    }\n    /**\n\t * Checks whether a given DOM selection needs to be updated.\n\t *\n\t * @param domSelection The DOM selection to check.\n\t */ _domSelectionNeedsUpdate(domSelection) {\n        if (!this.domConverter.isDomSelectionCorrect(domSelection)) {\n            // Current DOM selection is in incorrect position. We need to update it.\n            return true;\n        }\n        const oldViewSelection = domSelection && this.domConverter.domSelectionToView(domSelection);\n        if (oldViewSelection && this.selection.isEqual(oldViewSelection)) {\n            return false;\n        }\n        // If selection is not collapsed, it does not need to be updated if it is similar.\n        if (!this.selection.isCollapsed && this.selection.isSimilar(oldViewSelection)) {\n            // Selection did not changed and is correct, do not update.\n            return false;\n        }\n        // Selections are not similar.\n        return true;\n    }\n    /**\n\t * Checks whether the fake selection needs to be updated.\n\t *\n\t * @param domRoot A valid DOM root where a new fake selection container should be added.\n\t */ _fakeSelectionNeedsUpdate(domRoot) {\n        const container = this._fakeSelectionContainer;\n        const domSelection = domRoot.ownerDocument.getSelection();\n        // Fake selection needs to be updated if there's no fake selection container, or the container currently sits\n        // in a different root.\n        if (!container || container.parentElement !== domRoot) {\n            return true;\n        }\n        // Make sure that the selection actually is within the fake selection.\n        if (domSelection.anchorNode !== container && !container.contains(domSelection.anchorNode)) {\n            return true;\n        }\n        return container.textContent !== this.selection.fakeSelectionLabel;\n    }\n    /**\n\t * Removes the DOM selection.\n\t */ _removeDomSelection() {\n        for (const doc of this.domDocuments){\n            const domSelection = doc.getSelection();\n            if (domSelection.rangeCount) {\n                const activeDomElement = doc.activeElement;\n                const viewElement = this.domConverter.mapDomToView(activeDomElement);\n                if (activeDomElement && viewElement) {\n                    domSelection.removeAllRanges();\n                }\n            }\n        }\n    }\n    /**\n\t * Removes the fake selection.\n\t */ _removeFakeSelection() {\n        const container = this._fakeSelectionContainer;\n        if (container) {\n            container.remove();\n        }\n    }\n    /**\n\t * Checks if focus needs to be updated and possibly updates it.\n\t */ _updateFocus() {\n        if (this.isFocused) {\n            const editable = this.selection.editableElement;\n            if (editable) {\n                this.domConverter.focus(editable);\n            }\n        }\n    }\n}\n/**\n * Checks if provided element is editable.\n */ function isEditable(element) {\n    if (element.getAttribute('contenteditable') == 'false') {\n        return false;\n    }\n    const parent = element.findAncestor((element)=>element.hasAttribute('contenteditable'));\n    return !parent || parent.getAttribute('contenteditable') == 'true';\n}\n/**\n * Adds inline filler at a given position.\n *\n * The position can be given as an array of DOM nodes and an offset in that array,\n * or a DOM parent element and an offset in that element.\n *\n * @returns The DOM text node that contains an inline filler.\n */ function addInlineFiller(domDocument, domParentOrArray, offset) {\n    const childNodes = domParentOrArray instanceof Array ? domParentOrArray : domParentOrArray.childNodes;\n    const nodeAfterFiller = childNodes[offset];\n    if (isText(nodeAfterFiller)) {\n        nodeAfterFiller.data = INLINE_FILLER + nodeAfterFiller.data;\n        return nodeAfterFiller;\n    } else {\n        const fillerNode = domDocument.createTextNode(INLINE_FILLER);\n        if (Array.isArray(domParentOrArray)) {\n            childNodes.splice(offset, 0, fillerNode);\n        } else {\n            insertAt(domParentOrArray, offset, fillerNode);\n        }\n        return fillerNode;\n    }\n}\n/**\n * Whether two DOM nodes should be considered as similar.\n * Nodes are considered similar if they have the same tag name.\n */ function areSimilarElements(node1, node2) {\n    return isNode(node1) && isNode(node2) && !isText(node1) && !isText(node2) && !isComment(node1) && !isComment(node2) && node1.tagName.toLowerCase() === node2.tagName.toLowerCase();\n}\n/**\n * Whether two DOM nodes are text nodes.\n */ function areTextNodes(node1, node2) {\n    return isNode(node1) && isNode(node2) && isText(node1) && isText(node2);\n}\n/**\n * Whether two dom nodes should be considered as the same.\n * Two nodes which are considered the same are:\n *\n * * Text nodes with the same text.\n * * Element nodes represented by the same object.\n * * Two block filler elements.\n *\n * @param blockFillerMode Block filler mode, see {@link module:engine/view/domconverter~DomConverter#blockFillerMode}.\n */ function sameNodes$1(domConverter, actualDomChild, expectedDomChild) {\n    // Elements.\n    if (actualDomChild === expectedDomChild) {\n        return true;\n    } else if (isText(actualDomChild) && isText(expectedDomChild)) {\n        return actualDomChild.data === expectedDomChild.data;\n    } else if (domConverter.isBlockFiller(actualDomChild) && domConverter.isBlockFiller(expectedDomChild)) {\n        return true;\n    }\n    // Not matching types.\n    return false;\n}\n/**\n * The following is a Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).\n * When the native DOM selection is at the end of the block and preceded by <br /> e.g.\n *\n * ```html\n * <p>foo<br/>[]</p>\n * ```\n *\n * which happens a lot when using the soft line break, the browser fails to (visually) move the\n * caret to the new line. A quick fix is as simple as force–refreshing the selection with the same range.\n */ function fixGeckoSelectionAfterBr(focus, domSelection) {\n    let parent = focus.parent;\n    let offset = focus.offset;\n    if (isText(parent) && isInlineFiller(parent)) {\n        offset = indexOf(parent) + 1;\n        parent = parent.parentNode;\n    }\n    // This fix works only when the focus point is at the very end of an element.\n    // There is no point in running it in cases unrelated to the browser bug.\n    if (parent.nodeType != Node.ELEMENT_NODE || offset != parent.childNodes.length - 1) {\n        return;\n    }\n    const childAtOffset = parent.childNodes[offset];\n    // To stay on the safe side, the fix being as specific as possible, it targets only the\n    // selection which is at the very end of the element and preceded by <br />.\n    if (childAtOffset && childAtOffset.tagName == 'BR') {\n        domSelection.addRange(domSelection.getRangeAt(0));\n    }\n}\nfunction filterOutFakeSelectionContainer(domChildList, fakeSelectionContainer) {\n    const childList = Array.from(domChildList);\n    if (childList.length == 0 || !fakeSelectionContainer) {\n        return childList;\n    }\n    const last = childList[childList.length - 1];\n    if (last == fakeSelectionContainer) {\n        childList.pop();\n    }\n    return childList;\n}\n/**\n * Creates a fake selection container for a given document.\n */ function createFakeSelectionContainer(domDocument) {\n    const container = domDocument.createElement('div');\n    container.className = 'ck-fake-selection-container';\n    Object.assign(container.style, {\n        position: 'fixed',\n        top: 0,\n        left: '-9999px',\n        // See https://github.com/ckeditor/ckeditor5/issues/752.\n        width: '42px'\n    });\n    // Fill it with a text node so we can update it later.\n    container.textContent = '\\u00A0';\n    return container;\n} // @if CK_DEBUG_TYPING // function _escapeTextNodeData( text ) {\n // @if CK_DEBUG_TYPING // \tconst escapedText = text\n // @if CK_DEBUG_TYPING // \t\t.replace( /&/g, '&amp;' )\n // @if CK_DEBUG_TYPING // \t\t.replace( /\\u00A0/g, '&nbsp;' )\n // @if CK_DEBUG_TYPING // \t\t.replace( /\\u2060/g, '&NoBreak;' );\n // @if CK_DEBUG_TYPING //\n // @if CK_DEBUG_TYPING // \treturn `\"${ escapedText }\"`;\n // @if CK_DEBUG_TYPING // }\n\nconst BR_FILLER_REF = BR_FILLER(global.document); // eslint-disable-line new-cap\nconst NBSP_FILLER_REF = NBSP_FILLER(global.document); // eslint-disable-line new-cap\nconst MARKED_NBSP_FILLER_REF = MARKED_NBSP_FILLER(global.document); // eslint-disable-line new-cap\nconst UNSAFE_ATTRIBUTE_NAME_PREFIX = 'data-ck-unsafe-attribute-';\nconst UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE = 'data-ck-unsafe-element';\n/**\n * `DomConverter` is a set of tools to do transformations between DOM nodes and view nodes. It also handles\n * {@link module:engine/view/domconverter~DomConverter#bindElements bindings} between these nodes.\n *\n * An instance of the DOM converter is available under\n * {@link module:engine/view/view~View#domConverter `editor.editing.view.domConverter`}.\n *\n * The DOM converter does not check which nodes should be rendered (use {@link module:engine/view/renderer~Renderer}), does not keep the\n * state of a tree nor keeps the synchronization between the tree view and the DOM tree (use {@link module:engine/view/document~Document}).\n *\n * The DOM converter keeps DOM elements to view element bindings, so when the converter gets destroyed, the bindings are lost.\n * Two converters will keep separate binding maps, so one tree view can be bound with two DOM trees.\n */ class DomConverter {\n    document;\n    /**\n\t * Whether to leave the View-to-DOM conversion result unchanged or improve editing experience by filtering out interactive data.\n\t */ renderingMode;\n    /**\n\t * The mode of a block filler used by the DOM converter.\n\t */ blockFillerMode;\n    /**\n\t * Elements which are considered pre-formatted elements.\n\t */ preElements;\n    /**\n\t * Elements which are considered block elements (and hence should be filled with a\n\t * {@link #isBlockFiller block filler}).\n\t *\n\t * Whether an element is considered a block element also affects handling of trailing whitespaces.\n\t *\n\t * You can extend this array if you introduce support for block elements which are not yet recognized here.\n\t */ blockElements;\n    /**\n\t * A list of elements that exist inline (in text) but their inner structure cannot be edited because\n\t * of the way they are rendered by the browser. They are mostly HTML form elements but there are other\n\t * elements such as `<img>` or `<iframe>` that also have non-editable children or no children whatsoever.\n\t *\n\t * Whether an element is considered an inline object has an impact on white space rendering (trimming)\n\t * around (and inside of it). In short, white spaces in text nodes next to inline objects are not trimmed.\n\t *\n\t * You can extend this array if you introduce support for inline object elements which are not yet recognized here.\n\t */ inlineObjectElements;\n    /**\n\t * A list of elements which may affect the editing experience. To avoid this, those elements are replaced with\n\t * `<span data-ck-unsafe-element=\"[element name]\"></span>` while rendering in the editing mode.\n\t */ unsafeElements;\n    /**\n\t * The DOM Document used to create DOM nodes.\n\t */ _domDocument;\n    /**\n\t * The DOM-to-view mapping.\n\t */ _domToViewMapping = new WeakMap();\n    /**\n\t * The view-to-DOM mapping.\n\t */ _viewToDomMapping = new WeakMap();\n    /**\n\t * Holds the mapping between fake selection containers and corresponding view selections.\n\t */ _fakeSelectionMapping = new WeakMap();\n    /**\n\t * Matcher for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from DOM nodes to view elements.\n\t */ _rawContentElementMatcher = new Matcher();\n    /**\n\t * Matcher for inline object view elements. This is an extension of a simple {@link #inlineObjectElements} array of element names.\n\t */ _inlineObjectElementMatcher = new Matcher();\n    /**\n\t * Set of elements with temporary custom properties that require clearing after render.\n\t */ _elementsWithTemporaryCustomProperties = new Set();\n    /**\n\t * Creates a DOM converter.\n\t *\n\t * @param document The view document instance.\n\t * @param options An object with configuration options.\n\t * @param options.blockFillerMode The type of the block filler to use.\n\t * Default value depends on the options.renderingMode:\n\t *  'nbsp' when options.renderingMode == 'data',\n\t *  'br' when options.renderingMode == 'editing'.\n\t * @param options.renderingMode Whether to leave the View-to-DOM conversion result unchanged\n\t * or improve editing experience by filtering out interactive data.\n\t */ constructor(document, { blockFillerMode, renderingMode = 'editing' } = {}){\n        this.document = document;\n        this.renderingMode = renderingMode;\n        this.blockFillerMode = blockFillerMode || (renderingMode === 'editing' ? 'br' : 'nbsp');\n        this.preElements = [\n            'pre',\n            'textarea'\n        ];\n        this.blockElements = [\n            'address',\n            'article',\n            'aside',\n            'blockquote',\n            'caption',\n            'center',\n            'dd',\n            'details',\n            'dir',\n            'div',\n            'dl',\n            'dt',\n            'fieldset',\n            'figcaption',\n            'figure',\n            'footer',\n            'form',\n            'h1',\n            'h2',\n            'h3',\n            'h4',\n            'h5',\n            'h6',\n            'header',\n            'hgroup',\n            'legend',\n            'li',\n            'main',\n            'menu',\n            'nav',\n            'ol',\n            'p',\n            'pre',\n            'section',\n            'summary',\n            'table',\n            'tbody',\n            'td',\n            'tfoot',\n            'th',\n            'thead',\n            'tr',\n            'ul'\n        ];\n        this.inlineObjectElements = [\n            'object',\n            'iframe',\n            'input',\n            'button',\n            'textarea',\n            'select',\n            'option',\n            'video',\n            'embed',\n            'audio',\n            'img',\n            'canvas'\n        ];\n        this.unsafeElements = [\n            'script',\n            'style'\n        ];\n        this._domDocument = this.renderingMode === 'editing' ? global.document : global.document.implementation.createHTMLDocument('');\n    }\n    /**\n\t * Binds a given DOM element that represents fake selection to a **position** of a\n\t * {@link module:engine/view/documentselection~DocumentSelection document selection}.\n\t * Document selection copy is stored and can be retrieved by the\n\t * {@link module:engine/view/domconverter~DomConverter#fakeSelectionToView} method.\n\t */ bindFakeSelection(domElement, viewDocumentSelection) {\n        this._fakeSelectionMapping.set(domElement, new Selection$1(viewDocumentSelection));\n    }\n    /**\n\t * Returns a {@link module:engine/view/selection~Selection view selection} instance corresponding to a given\n\t * DOM element that represents fake selection. Returns `undefined` if binding to the given DOM element does not exist.\n\t */ fakeSelectionToView(domElement) {\n        return this._fakeSelectionMapping.get(domElement);\n    }\n    /**\n\t * Binds DOM and view elements, so it will be possible to get corresponding elements using\n\t * {@link module:engine/view/domconverter~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param domElement The DOM element to bind.\n\t * @param viewElement The view element to bind.\n\t */ bindElements(domElement, viewElement) {\n        this._domToViewMapping.set(domElement, viewElement);\n        this._viewToDomMapping.set(viewElement, domElement);\n    }\n    /**\n\t * Unbinds a given DOM element from the view element it was bound to. Unbinding is deep, meaning that all children of\n\t * the DOM element will be unbound too.\n\t *\n\t * @param domElement The DOM element to unbind.\n\t */ unbindDomElement(domElement) {\n        const viewElement = this._domToViewMapping.get(domElement);\n        if (viewElement) {\n            this._domToViewMapping.delete(domElement);\n            this._viewToDomMapping.delete(viewElement);\n            for (const child of domElement.children){\n                this.unbindDomElement(child);\n            }\n        }\n    }\n    /**\n\t * Binds DOM and view document fragments, so it will be possible to get corresponding document fragments using\n\t * {@link module:engine/view/domconverter~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param domFragment The DOM document fragment to bind.\n\t * @param viewFragment The view document fragment to bind.\n\t */ bindDocumentFragments(domFragment, viewFragment) {\n        this._domToViewMapping.set(domFragment, viewFragment);\n        this._viewToDomMapping.set(viewFragment, domFragment);\n    }\n    /**\n\t * Decides whether a given pair of attribute key and value should be passed further down the pipeline.\n\t *\n\t * @param elementName Element name in lower case.\n\t */ shouldRenderAttribute(attributeKey, attributeValue, elementName) {\n        if (this.renderingMode === 'data') {\n            return true;\n        }\n        attributeKey = attributeKey.toLowerCase();\n        if (attributeKey.startsWith('on')) {\n            return false;\n        }\n        if (attributeKey === 'srcdoc' && attributeValue.match(/\\bon\\S+\\s*=|javascript:|<\\s*\\/*script/i)) {\n            return false;\n        }\n        if (elementName === 'img' && (attributeKey === 'src' || attributeKey === 'srcset')) {\n            return true;\n        }\n        if (elementName === 'source' && attributeKey === 'srcset') {\n            return true;\n        }\n        if (attributeValue.match(/^\\s*(javascript:|data:(image\\/svg|text\\/x?html))/i)) {\n            return false;\n        }\n        return true;\n    }\n    /**\n\t * Set `domElement`'s content using provided `html` argument. Apply necessary filtering for the editing pipeline.\n\t *\n\t * @param domElement DOM element that should have `html` set as its content.\n\t * @param html Textual representation of the HTML that will be set on `domElement`.\n\t */ setContentOf(domElement, html) {\n        // For data pipeline we pass the HTML as-is.\n        if (this.renderingMode === 'data') {\n            domElement.innerHTML = html;\n            return;\n        }\n        const document = new DOMParser().parseFromString(html, 'text/html');\n        const fragment = document.createDocumentFragment();\n        const bodyChildNodes = document.body.childNodes;\n        while(bodyChildNodes.length > 0){\n            fragment.appendChild(bodyChildNodes[0]);\n        }\n        const treeWalker = document.createTreeWalker(fragment, NodeFilter.SHOW_ELEMENT);\n        const nodes = [];\n        let currentNode;\n        // eslint-disable-next-line no-cond-assign\n        while(currentNode = treeWalker.nextNode()){\n            nodes.push(currentNode);\n        }\n        for (const currentNode of nodes){\n            // Go through nodes to remove those that are prohibited in editing pipeline.\n            for (const attributeName of currentNode.getAttributeNames()){\n                this.setDomElementAttribute(currentNode, attributeName, currentNode.getAttribute(attributeName));\n            }\n            const elementName = currentNode.tagName.toLowerCase();\n            // There are certain nodes, that should be renamed to <span> in editing pipeline.\n            if (this._shouldRenameElement(elementName)) {\n                _logUnsafeElement(elementName);\n                currentNode.replaceWith(this._createReplacementDomElement(elementName, currentNode));\n            }\n        }\n        // Empty the target element.\n        while(domElement.firstChild){\n            domElement.firstChild.remove();\n        }\n        domElement.append(fragment);\n    }\n    /**\n\t * Converts the view to the DOM. For all text nodes, not bound elements and document fragments new items will\n\t * be created. For bound elements and document fragments the method will return corresponding items.\n\t *\n\t * @param viewNode View node or document fragment to transform.\n\t * @param options Conversion options.\n\t * @param options.bind Determines whether new elements will be bound.\n\t * @param options.withChildren If `false`, node's and document fragment's children will not be converted.\n\t * @returns Converted node or DocumentFragment.\n\t */ viewToDom(viewNode, options = {}) {\n        if (viewNode.is('$text')) {\n            const textData = this._processDataFromViewText(viewNode);\n            return this._domDocument.createTextNode(textData);\n        } else {\n            const viewElementOrFragment = viewNode;\n            if (this.mapViewToDom(viewElementOrFragment)) {\n                // Do not reuse element that is marked to not reuse (for example an IMG element\n                // so it can immediately display a placeholder background instead of waiting for the new src to load).\n                if (viewElementOrFragment.getCustomProperty('editingPipeline:doNotReuseOnce')) {\n                    this._elementsWithTemporaryCustomProperties.add(viewElementOrFragment);\n                } else {\n                    return this.mapViewToDom(viewElementOrFragment);\n                }\n            }\n            let domElement;\n            if (viewElementOrFragment.is('documentFragment')) {\n                // Create DOM document fragment.\n                domElement = this._domDocument.createDocumentFragment();\n                if (options.bind) {\n                    this.bindDocumentFragments(domElement, viewElementOrFragment);\n                }\n            } else if (viewElementOrFragment.is('uiElement')) {\n                if (viewElementOrFragment.name === '$comment') {\n                    domElement = this._domDocument.createComment(viewElementOrFragment.getCustomProperty('$rawContent'));\n                } else {\n                    // UIElement has its own render() method (see #799).\n                    domElement = viewElementOrFragment.render(this._domDocument, this);\n                }\n                if (options.bind) {\n                    this.bindElements(domElement, viewElementOrFragment);\n                }\n                return domElement;\n            } else {\n                // Create DOM element.\n                if (this._shouldRenameElement(viewElementOrFragment.name)) {\n                    _logUnsafeElement(viewElementOrFragment.name);\n                    domElement = this._createReplacementDomElement(viewElementOrFragment.name);\n                } else if (viewElementOrFragment.hasAttribute('xmlns')) {\n                    domElement = this._domDocument.createElementNS(viewElementOrFragment.getAttribute('xmlns'), viewElementOrFragment.name);\n                } else {\n                    domElement = this._domDocument.createElement(viewElementOrFragment.name);\n                }\n                // RawElement take care of their children in RawElement#render() method which can be customized\n                // (see https://github.com/ckeditor/ckeditor5/issues/4469).\n                if (viewElementOrFragment.is('rawElement')) {\n                    viewElementOrFragment.render(domElement, this);\n                }\n                if (options.bind) {\n                    this.bindElements(domElement, viewElementOrFragment);\n                }\n                // Copy element's attributes.\n                for (const key of viewElementOrFragment.getAttributeKeys()){\n                    this.setDomElementAttribute(domElement, key, viewElementOrFragment.getAttribute(key), viewElementOrFragment);\n                }\n            }\n            if (options.withChildren !== false) {\n                for (const child of this.viewChildrenToDom(viewElementOrFragment, options)){\n                    if (domElement instanceof HTMLTemplateElement) {\n                        domElement.content.appendChild(child);\n                    } else {\n                        domElement.appendChild(child);\n                    }\n                }\n            }\n            return domElement;\n        }\n    }\n    /**\n\t * Sets the attribute on a DOM element.\n\t *\n\t * **Note**: To remove the attribute, use {@link #removeDomElementAttribute}.\n\t *\n\t * @param domElement The DOM element the attribute should be set on.\n\t * @param key The name of the attribute.\n\t * @param value The value of the attribute.\n\t * @param relatedViewElement The view element related to the `domElement` (if there is any).\n\t * It helps decide whether the attribute set is unsafe. For instance, view elements created via the\n\t * {@link module:engine/view/downcastwriter~DowncastWriter} methods can allow certain attributes that would normally be filtered out.\n\t */ setDomElementAttribute(domElement, key, value, relatedViewElement) {\n        const shouldRenderAttribute = this.shouldRenderAttribute(key, value, domElement.tagName.toLowerCase()) || relatedViewElement && relatedViewElement.shouldRenderUnsafeAttribute(key);\n        if (!shouldRenderAttribute) {\n            logWarning('domconverter-unsafe-attribute-detected', {\n                domElement,\n                key,\n                value\n            });\n        }\n        if (!isValidAttributeName(key)) {\n            /**\n\t\t\t * Invalid attribute name was ignored during rendering.\n\t\t\t *\n\t\t\t * @error domconverter-invalid-attribute-detected\n\t\t\t */ logWarning('domconverter-invalid-attribute-detected', {\n                domElement,\n                key,\n                value\n            });\n            return;\n        }\n        // The old value was safe but the new value is unsafe.\n        if (domElement.hasAttribute(key) && !shouldRenderAttribute) {\n            domElement.removeAttribute(key);\n        } else if (domElement.hasAttribute(UNSAFE_ATTRIBUTE_NAME_PREFIX + key) && shouldRenderAttribute) {\n            domElement.removeAttribute(UNSAFE_ATTRIBUTE_NAME_PREFIX + key);\n        }\n        // If the attribute should not be rendered, rename it (instead of removing) to give developers some idea of what\n        // is going on (https://github.com/ckeditor/ckeditor5/issues/10801).\n        domElement.setAttribute(shouldRenderAttribute ? key : UNSAFE_ATTRIBUTE_NAME_PREFIX + key, value);\n    }\n    /**\n\t * Removes an attribute from a DOM element.\n\t *\n\t * **Note**: To set the attribute, use {@link #setDomElementAttribute}.\n\t *\n\t * @param domElement The DOM element the attribute should be removed from.\n\t * @param key The name of the attribute.\n\t */ removeDomElementAttribute(domElement, key) {\n        // See #_createReplacementDomElement() to learn what this is.\n        if (key == UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE) {\n            return;\n        }\n        domElement.removeAttribute(key);\n        // See setDomElementAttribute() to learn what this is.\n        domElement.removeAttribute(UNSAFE_ATTRIBUTE_NAME_PREFIX + key);\n    }\n    /**\n\t * Converts children of the view element to DOM using the\n\t * {@link module:engine/view/domconverter~DomConverter#viewToDom} method.\n\t * Additionally, this method adds block {@link module:engine/view/filler filler} to the list of children, if needed.\n\t *\n\t * @param viewElement Parent view element.\n\t * @param options See {@link module:engine/view/domconverter~DomConverter#viewToDom} options parameter.\n\t * @returns DOM nodes.\n\t */ *viewChildrenToDom(viewElement, options = {}) {\n        const fillerPositionOffset = viewElement.getFillerOffset && viewElement.getFillerOffset();\n        let offset = 0;\n        for (const childView of viewElement.getChildren()){\n            if (fillerPositionOffset === offset) {\n                yield this._getBlockFiller();\n            }\n            const transparentRendering = childView.is('element') && !!childView.getCustomProperty('dataPipeline:transparentRendering') && !first(childView.getAttributes());\n            if (transparentRendering && this.renderingMode == 'data') {\n                // `RawElement` doesn't have #children defined, so they need to be temporarily rendered\n                // and extracted directly.\n                if (childView.is('rawElement')) {\n                    const tempElement = this._domDocument.createElement(childView.name);\n                    childView.render(tempElement, this);\n                    yield* [\n                        ...tempElement.childNodes\n                    ];\n                } else {\n                    yield* this.viewChildrenToDom(childView, options);\n                }\n            } else {\n                if (transparentRendering) {\n                    /**\n\t\t\t\t\t * The `dataPipeline:transparentRendering` flag is supported only in the data pipeline.\n\t\t\t\t\t *\n\t\t\t\t\t * @error domconverter-transparent-rendering-unsupported-in-editing-pipeline\n\t\t\t\t\t */ logWarning('domconverter-transparent-rendering-unsupported-in-editing-pipeline', {\n                        viewElement: childView\n                    });\n                }\n                yield this.viewToDom(childView, options);\n            }\n            offset++;\n        }\n        if (fillerPositionOffset === offset) {\n            yield this._getBlockFiller();\n        }\n    }\n    /**\n\t * Converts view {@link module:engine/view/range~Range} to DOM range.\n\t * Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t *\n\t * @param viewRange View range.\n\t * @returns DOM range.\n\t */ viewRangeToDom(viewRange) {\n        const domStart = this.viewPositionToDom(viewRange.start);\n        const domEnd = this.viewPositionToDom(viewRange.end);\n        const domRange = this._domDocument.createRange();\n        domRange.setStart(domStart.parent, domStart.offset);\n        domRange.setEnd(domEnd.parent, domEnd.offset);\n        return domRange;\n    }\n    /**\n\t * Converts view {@link module:engine/view/position~Position} to DOM parent and offset.\n\t *\n\t * Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t * If the converted position is directly before inline filler it is moved inside the filler.\n\t *\n\t * @param viewPosition View position.\n\t * @returns DOM position or `null` if view position could not be converted to DOM.\n\t * DOM position has two properties:\n\t * * `parent` - DOM position parent.\n\t * * `offset` - DOM position offset.\n\t */ viewPositionToDom(viewPosition) {\n        const viewParent = viewPosition.parent;\n        if (viewParent.is('$text')) {\n            const domParent = this.findCorrespondingDomText(viewParent);\n            if (!domParent) {\n                // Position is in a view text node that has not been rendered to DOM yet.\n                return null;\n            }\n            let offset = viewPosition.offset;\n            if (startsWithFiller(domParent)) {\n                offset += INLINE_FILLER_LENGTH;\n            }\n            return {\n                parent: domParent,\n                offset\n            };\n        } else {\n            // viewParent is instance of ViewElement.\n            let domParent, domBefore, domAfter;\n            if (viewPosition.offset === 0) {\n                domParent = this.mapViewToDom(viewParent);\n                if (!domParent) {\n                    // Position is in a view element that has not been rendered to DOM yet.\n                    return null;\n                }\n                domAfter = domParent.childNodes[0];\n            } else {\n                const nodeBefore = viewPosition.nodeBefore;\n                domBefore = nodeBefore.is('$text') ? this.findCorrespondingDomText(nodeBefore) : this.mapViewToDom(nodeBefore);\n                if (!domBefore) {\n                    // Position is after a view element that has not been rendered to DOM yet.\n                    return null;\n                }\n                domParent = domBefore.parentNode;\n                domAfter = domBefore.nextSibling;\n            }\n            // If there is an inline filler at position return position inside the filler. We should never return\n            // the position before the inline filler.\n            if (isText(domAfter) && startsWithFiller(domAfter)) {\n                return {\n                    parent: domAfter,\n                    offset: INLINE_FILLER_LENGTH\n                };\n            }\n            const offset = domBefore ? indexOf(domBefore) + 1 : 0;\n            return {\n                parent: domParent,\n                offset\n            };\n        }\n    }\n    /**\n\t * Converts DOM to view. For all text nodes, not bound elements and document fragments new items will\n\t * be created. For bound elements and document fragments function will return corresponding items. For\n\t * {@link module:engine/view/filler fillers} `null` will be returned.\n\t * For all DOM elements rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned.\n\t *\n\t * @param domNode DOM node or document fragment to transform.\n\t * @param options Conversion options.\n\t * @param options.bind Determines whether new elements will be bound. False by default.\n\t * @param options.withChildren If `true`, node's and document fragment's children will be converted too. True by default.\n\t * @param options.keepOriginalCase If `false`, node's tag name will be converted to lower case. False by default.\n\t * @param options.skipComments If `false`, comment nodes will be converted to `$comment`\n\t * {@link module:engine/view/uielement~UIElement view UI elements}. False by default.\n\t * @returns Converted node or document fragment or `null` if DOM node is a {@link module:engine/view/filler filler}\n\t * or the given node is an empty text node.\n\t */ domToView(domNode, options = {}) {\n        const inlineNodes = [];\n        const generator = this._domToView(domNode, options, inlineNodes);\n        // Get the first yielded value or a returned value.\n        const node = generator.next().value;\n        if (!node) {\n            return null;\n        }\n        // Trigger children handling.\n        generator.next();\n        // Whitespace cleaning.\n        this._processDomInlineNodes(null, inlineNodes, options);\n        // Text not got trimmed to an empty string so there is no result node.\n        if (node.is('$text') && node.data.length == 0) {\n            return null;\n        }\n        return node;\n    }\n    /**\n\t * Converts children of the DOM element to view nodes using\n\t * the {@link module:engine/view/domconverter~DomConverter#domToView} method.\n\t * Additionally this method omits block {@link module:engine/view/filler filler}, if it exists in the DOM parent.\n\t *\n\t * @param domElement Parent DOM element.\n\t * @param options See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t * @param inlineNodes An array that will be populated with inline nodes. It's used internally for whitespace processing.\n\t * @returns View nodes.\n\t */ *domChildrenToView(domElement, options = {}, inlineNodes = []) {\n        // Get child nodes from content document fragment if element is template\n        let childNodes = [];\n        if (domElement instanceof HTMLTemplateElement) {\n            childNodes = [\n                ...domElement.content.childNodes\n            ];\n        } else {\n            childNodes = [\n                ...domElement.childNodes\n            ];\n        }\n        for(let i = 0; i < childNodes.length; i++){\n            const domChild = childNodes[i];\n            const generator = this._domToView(domChild, options, inlineNodes);\n            // Get the first yielded value or a returned value.\n            const viewChild = generator.next().value;\n            if (viewChild !== null) {\n                // Whitespace cleaning before entering a block element (between block elements).\n                if (this._isBlockViewElement(viewChild)) {\n                    this._processDomInlineNodes(domElement, inlineNodes, options);\n                }\n                yield viewChild;\n                // Trigger children handling.\n                generator.next();\n            }\n        }\n        // Whitespace cleaning before leaving a block element (content of block element).\n        this._processDomInlineNodes(domElement, inlineNodes, options);\n    }\n    /**\n\t * Converts DOM selection to view {@link module:engine/view/selection~Selection}.\n\t * Ranges which cannot be converted will be omitted.\n\t *\n\t * @param domSelection DOM selection.\n\t * @returns View selection.\n\t */ domSelectionToView(domSelection) {\n        // See: https://github.com/ckeditor/ckeditor5/issues/9635.\n        if (isGeckoRestrictedDomSelection(domSelection)) {\n            return new Selection$1([]);\n        }\n        // DOM selection might be placed in fake selection container.\n        // If container contains fake selection - return corresponding view selection.\n        if (domSelection.rangeCount === 1) {\n            let container = domSelection.getRangeAt(0).startContainer;\n            // The DOM selection might be moved to the text node inside the fake selection container.\n            if (isText(container)) {\n                container = container.parentNode;\n            }\n            const viewSelection = this.fakeSelectionToView(container);\n            if (viewSelection) {\n                return viewSelection;\n            }\n        }\n        const isBackward = this.isDomSelectionBackward(domSelection);\n        const viewRanges = [];\n        for(let i = 0; i < domSelection.rangeCount; i++){\n            // DOM Range have correct start and end, no matter what is the DOM Selection direction. So we don't have to fix anything.\n            const domRange = domSelection.getRangeAt(i);\n            const viewRange = this.domRangeToView(domRange);\n            if (viewRange) {\n                viewRanges.push(viewRange);\n            }\n        }\n        return new Selection$1(viewRanges, {\n            backward: isBackward\n        });\n    }\n    /**\n\t * Converts DOM Range to view {@link module:engine/view/range~Range}.\n\t * If the start or end position can not be converted `null` is returned.\n\t *\n\t * @param domRange DOM range.\n\t * @returns View range.\n\t */ domRangeToView(domRange) {\n        const viewStart = this.domPositionToView(domRange.startContainer, domRange.startOffset);\n        const viewEnd = this.domPositionToView(domRange.endContainer, domRange.endOffset);\n        if (viewStart && viewEnd) {\n            return new Range$1(viewStart, viewEnd);\n        }\n        return null;\n    }\n    /**\n\t * Converts DOM parent and offset to view {@link module:engine/view/position~Position}.\n\t *\n\t * If the position is inside a {@link module:engine/view/filler filler} which has no corresponding view node,\n\t * position of the filler will be converted and returned.\n\t *\n\t * If the position is inside DOM element rendered by {@link module:engine/view/uielement~UIElement}\n\t * that position will be converted to view position before that UIElement.\n\t *\n\t * If structures are too different and it is not possible to find corresponding position then `null` will be returned.\n\t *\n\t * @param domParent DOM position parent.\n\t * @param domOffset DOM position offset. You can skip it when converting the inline filler node.\n\t * @returns View position.\n\t */ domPositionToView(domParent, domOffset = 0) {\n        if (this.isBlockFiller(domParent)) {\n            return this.domPositionToView(domParent.parentNode, indexOf(domParent));\n        }\n        // If position is somewhere inside UIElement or a RawElement - return position before that element.\n        const viewElement = this.mapDomToView(domParent);\n        if (viewElement && (viewElement.is('uiElement') || viewElement.is('rawElement'))) {\n            return Position$1._createBefore(viewElement);\n        }\n        if (isText(domParent)) {\n            if (isInlineFiller(domParent)) {\n                return this.domPositionToView(domParent.parentNode, indexOf(domParent));\n            }\n            const viewParent = this.findCorrespondingViewText(domParent);\n            let offset = domOffset;\n            if (!viewParent) {\n                return null;\n            }\n            if (startsWithFiller(domParent)) {\n                offset -= INLINE_FILLER_LENGTH;\n                offset = offset < 0 ? 0 : offset;\n            }\n            return new Position$1(viewParent, offset);\n        } else {\n            if (domOffset === 0) {\n                const viewParent = this.mapDomToView(domParent);\n                if (viewParent) {\n                    return new Position$1(viewParent, 0);\n                }\n            } else {\n                const domBefore = domParent.childNodes[domOffset - 1];\n                // Jump over an inline filler (and also on Firefox jump over a block filler while pressing backspace in an empty paragraph).\n                if (isText(domBefore) && isInlineFiller(domBefore) || domBefore && this.isBlockFiller(domBefore)) {\n                    return this.domPositionToView(domBefore.parentNode, indexOf(domBefore));\n                }\n                const viewBefore = isText(domBefore) ? this.findCorrespondingViewText(domBefore) : this.mapDomToView(domBefore);\n                // TODO #663\n                if (viewBefore && viewBefore.parent) {\n                    return new Position$1(viewBefore.parent, viewBefore.index + 1);\n                }\n            }\n            return null;\n        }\n    }\n    /**\n\t * Returns corresponding view {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment} for provided DOM element or\n\t * document fragment. If there is no view item {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * to the given DOM - `undefined` is returned.\n\t *\n\t * For all DOM elements rendered by a {@link module:engine/view/uielement~UIElement} or\n\t * a {@link module:engine/view/rawelement~RawElement}, the parent `UIElement` or `RawElement` will be returned.\n\t *\n\t * @param domElementOrDocumentFragment DOM element or document fragment.\n\t * @returns Corresponding view element, document fragment or `undefined` if no element was bound.\n\t */ mapDomToView(domElementOrDocumentFragment) {\n        const hostElement = this.getHostViewElement(domElementOrDocumentFragment);\n        return hostElement || this._domToViewMapping.get(domElementOrDocumentFragment);\n    }\n    /**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#bindElements bound},\n\t * corresponding text node is returned based on the sibling or parent.\n\t *\n\t * If the directly previous sibling is a {@link module:engine/view/domconverter~DomConverter#bindElements bound} element, it is used\n\t * to find the corresponding text node.\n\t *\n\t * If this is a first child in the parent and the parent is a {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * element, it is used to find the corresponding text node.\n\t *\n\t * For all text nodes rendered by a {@link module:engine/view/uielement~UIElement} or\n\t * a {@link module:engine/view/rawelement~RawElement}, the parent `UIElement` or `RawElement` will be returned.\n\t *\n\t * Otherwise `null` is returned.\n\t *\n\t * Note that for the block or inline {@link module:engine/view/filler filler} this method returns `null`.\n\t *\n\t * @param domText DOM text node.\n\t * @returns Corresponding view text node or `null`, if it was not possible to find a corresponding node.\n\t */ findCorrespondingViewText(domText) {\n        if (isInlineFiller(domText)) {\n            return null;\n        }\n        // If DOM text was rendered by a UIElement or a RawElement - return this parent element.\n        const hostElement = this.getHostViewElement(domText);\n        if (hostElement) {\n            return hostElement;\n        }\n        const previousSibling = domText.previousSibling;\n        // Try to use previous sibling to find the corresponding text node.\n        if (previousSibling) {\n            if (!this.isElement(previousSibling)) {\n                // The previous is text or comment.\n                return null;\n            }\n            const viewElement = this.mapDomToView(previousSibling);\n            if (viewElement) {\n                const nextSibling = viewElement.nextSibling;\n                // It might be filler which has no corresponding view node.\n                if (nextSibling instanceof Text$1) {\n                    return nextSibling;\n                } else {\n                    return null;\n                }\n            }\n        } else {\n            const viewElement = this.mapDomToView(domText.parentNode);\n            if (viewElement) {\n                const firstChild = viewElement.getChild(0);\n                // It might be filler which has no corresponding view node.\n                if (firstChild instanceof Text$1) {\n                    return firstChild;\n                } else {\n                    return null;\n                }\n            }\n        }\n        return null;\n    }\n    mapViewToDom(documentFragmentOrElement) {\n        return this._viewToDomMapping.get(documentFragmentOrElement);\n    }\n    /**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#bindElements bound},\n\t * corresponding text node is returned based on the sibling or parent.\n\t *\n\t * If the directly previous sibling is a {@link module:engine/view/domconverter~DomConverter#bindElements bound} element, it is used\n\t * to find the corresponding text node.\n\t *\n\t * If this is a first child in the parent and the parent is a {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * element, it is used to find the corresponding text node.\n\t *\n\t * Otherwise `null` is returned.\n\t *\n\t * @param viewText View text node.\n\t * @returns Corresponding DOM text node or `null`, if it was not possible to find a corresponding node.\n\t */ findCorrespondingDomText(viewText) {\n        const previousSibling = viewText.previousSibling;\n        // Try to use previous sibling to find the corresponding text node.\n        if (previousSibling && this.mapViewToDom(previousSibling)) {\n            return this.mapViewToDom(previousSibling).nextSibling;\n        }\n        // If this is a first node, try to use parent to find the corresponding text node.\n        if (!previousSibling && viewText.parent && this.mapViewToDom(viewText.parent)) {\n            return this.mapViewToDom(viewText.parent).childNodes[0];\n        }\n        return null;\n    }\n    /**\n\t * Focuses DOM editable that is corresponding to provided {@link module:engine/view/editableelement~EditableElement}.\n\t */ focus(viewEditable) {\n        const domEditable = this.mapViewToDom(viewEditable);\n        if (domEditable && domEditable.ownerDocument.activeElement !== domEditable) {\n            // Save the scrollX and scrollY positions before the focus.\n            const { scrollX, scrollY } = global.window;\n            const scrollPositions = [];\n            // Save all scrollLeft and scrollTop values starting from domEditable up to\n            // document#documentElement.\n            forEachDomElementAncestor(domEditable, (node)=>{\n                const { scrollLeft, scrollTop } = node;\n                scrollPositions.push([\n                    scrollLeft,\n                    scrollTop\n                ]);\n            });\n            domEditable.focus();\n            // Restore scrollLeft and scrollTop values starting from domEditable up to\n            // document#documentElement.\n            // https://github.com/ckeditor/ckeditor5-engine/issues/951\n            // https://github.com/ckeditor/ckeditor5-engine/issues/957\n            forEachDomElementAncestor(domEditable, (node)=>{\n                const [scrollLeft, scrollTop] = scrollPositions.shift();\n                node.scrollLeft = scrollLeft;\n                node.scrollTop = scrollTop;\n            });\n            // Restore the scrollX and scrollY positions after the focus.\n            // https://github.com/ckeditor/ckeditor5-engine/issues/951\n            global.window.scrollTo(scrollX, scrollY);\n        }\n    }\n    /**\n\t * Remove DOM selection from blurred editable, so it won't interfere with clicking on dropdowns (especially on iOS).\n\t *\n\t * @internal\n\t */ _clearDomSelection() {\n        const domEditable = this.mapViewToDom(this.document.selection.editableElement);\n        if (!domEditable) {\n            return;\n        }\n        // Check if DOM selection is inside editor editable element.\n        const domSelection = domEditable.ownerDocument.defaultView.getSelection();\n        const newViewSelection = this.domSelectionToView(domSelection);\n        const selectionInEditable = newViewSelection && newViewSelection.rangeCount > 0;\n        if (selectionInEditable) {\n            domSelection.removeAllRanges();\n        }\n    }\n    /**\n\t * Returns `true` when `node.nodeType` equals `Node.ELEMENT_NODE`.\n\t *\n\t * @param node Node to check.\n\t */ isElement(node) {\n        return node && node.nodeType == Node.ELEMENT_NODE;\n    }\n    /**\n\t * Returns `true` when `node.nodeType` equals `Node.DOCUMENT_FRAGMENT_NODE`.\n\t *\n\t * @param node Node to check.\n\t */ isDocumentFragment(node) {\n        return node && node.nodeType == Node.DOCUMENT_FRAGMENT_NODE;\n    }\n    /**\n\t * Checks if the node is an instance of the block filler for this DOM converter.\n\t *\n\t * ```ts\n\t * const converter = new DomConverter( viewDocument, { blockFillerMode: 'br' } );\n\t *\n\t * converter.isBlockFiller( BR_FILLER( document ) ); // true\n\t * converter.isBlockFiller( NBSP_FILLER( document ) ); // false\n\t * ```\n\t *\n\t * **Note:**: For the `'nbsp'` mode the method also checks context of a node so it cannot be a detached node.\n\t *\n\t * **Note:** A special case in the `'nbsp'` mode exists where the `<br>` in `<p><br></p>` is treated as a block filler.\n\t *\n\t * @param domNode DOM node to check.\n\t * @returns True if a node is considered a block filler for given mode.\n\t */ isBlockFiller(domNode) {\n        if (this.blockFillerMode == 'br') {\n            return domNode.isEqualNode(BR_FILLER_REF);\n        }\n        // Special case for <p><br></p> in which <br> should be treated as filler even when we are not in the 'br' mode. See ckeditor5#5564.\n        if (domNode.tagName === 'BR' && hasBlockParent(domNode, this.blockElements) && domNode.parentNode.childNodes.length === 1) {\n            return true;\n        }\n        // If not in 'br' mode, try recognizing both marked and regular nbsp block fillers.\n        return domNode.isEqualNode(MARKED_NBSP_FILLER_REF) || isNbspBlockFiller(domNode, this.blockElements);\n    }\n    /**\n\t * Returns `true` if given selection is a backward selection, that is, if it's `focus` is before `anchor`.\n\t *\n\t * @param DOM Selection instance to check.\n\t */ isDomSelectionBackward(selection) {\n        if (selection.isCollapsed) {\n            return false;\n        }\n        // Since it takes multiple lines of code to check whether a \"DOM Position\" is before/after another \"DOM Position\",\n        // we will use the fact that range will collapse if it's end is before it's start.\n        const range = this._domDocument.createRange();\n        try {\n            range.setStart(selection.anchorNode, selection.anchorOffset);\n            range.setEnd(selection.focusNode, selection.focusOffset);\n        } catch (e) {\n            // Safari sometimes gives us a selection that makes Range.set{Start,End} throw.\n            // See https://github.com/ckeditor/ckeditor5/issues/12375.\n            return false;\n        }\n        const backward = range.collapsed;\n        range.detach();\n        return backward;\n    }\n    /**\n\t * Returns a parent {@link module:engine/view/uielement~UIElement} or {@link module:engine/view/rawelement~RawElement}\n\t * that hosts the provided DOM node. Returns `null` if there is no such parent.\n\t */ getHostViewElement(domNode) {\n        const ancestors = getAncestors(domNode);\n        // Remove domNode from the list.\n        ancestors.pop();\n        while(ancestors.length){\n            const domNode = ancestors.pop();\n            const viewNode = this._domToViewMapping.get(domNode);\n            if (viewNode && (viewNode.is('uiElement') || viewNode.is('rawElement'))) {\n                return viewNode;\n            }\n        }\n        return null;\n    }\n    /**\n\t * Checks if the given selection's boundaries are at correct places.\n\t *\n\t * The following places are considered as incorrect for selection boundaries:\n\t *\n\t * * before or in the middle of an inline filler sequence,\n\t * * inside a DOM element which represents {@link module:engine/view/uielement~UIElement a view UI element},\n\t * * inside a DOM element which represents {@link module:engine/view/rawelement~RawElement a view raw element}.\n\t *\n\t * @param domSelection The DOM selection object to be checked.\n\t * @returns `true` if the given selection is at a correct place, `false` otherwise.\n\t */ isDomSelectionCorrect(domSelection) {\n        return this._isDomSelectionPositionCorrect(domSelection.anchorNode, domSelection.anchorOffset) && this._isDomSelectionPositionCorrect(domSelection.focusNode, domSelection.focusOffset);\n    }\n    /**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from DOM nodes to view elements.\n\t *\n\t * This is affecting how {@link module:engine/view/domconverter~DomConverter#domToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#domChildrenToView} process DOM nodes.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching a view element whose content should\n\t * be treated as raw data.\n\t */ registerRawContentMatcher(pattern) {\n        this._rawContentElementMatcher.add(pattern);\n    }\n    /**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for inline object view elements.\n\t *\n\t * This is affecting how {@link module:engine/view/domconverter~DomConverter#domToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#domChildrenToView} process DOM nodes.\n\t *\n\t * This is an extension of a simple {@link #inlineObjectElements} array of element names.\n\t *\n\t * @param pattern Pattern matching a view element which should be treated as an inline object.\n\t */ registerInlineObjectMatcher(pattern) {\n        this._inlineObjectElementMatcher.add(pattern);\n    }\n    /**\n\t * Clear temporary custom properties.\n\t *\n\t * @internal\n\t */ _clearTemporaryCustomProperties() {\n        for (const element of this._elementsWithTemporaryCustomProperties){\n            element._removeCustomProperty('editingPipeline:doNotReuseOnce');\n        }\n        this._elementsWithTemporaryCustomProperties.clear();\n    }\n    /**\n\t * Returns the block {@link module:engine/view/filler filler} node based on the current {@link #blockFillerMode} setting.\n\t */ _getBlockFiller() {\n        switch(this.blockFillerMode){\n            case 'nbsp':\n                return NBSP_FILLER(this._domDocument); // eslint-disable-line new-cap\n            case 'markedNbsp':\n                return MARKED_NBSP_FILLER(this._domDocument); // eslint-disable-line new-cap\n            case 'br':\n                return BR_FILLER(this._domDocument); // eslint-disable-line new-cap\n        }\n    }\n    /**\n\t * Checks if the given DOM position is a correct place for selection boundary. See {@link #isDomSelectionCorrect}.\n\t *\n\t * @param domParent Position parent.\n\t * @param offset Position offset.\n\t * @returns `true` if given position is at a correct place for selection boundary, `false` otherwise.\n\t */ _isDomSelectionPositionCorrect(domParent, offset) {\n        // If selection is before or in the middle of inline filler string, it is incorrect.\n        if (isText(domParent) && startsWithFiller(domParent) && offset < INLINE_FILLER_LENGTH) {\n            // Selection in a text node, at wrong position (before or in the middle of filler).\n            return false;\n        }\n        if (this.isElement(domParent) && startsWithFiller(domParent.childNodes[offset])) {\n            // Selection in an element node, before filler text node.\n            return false;\n        }\n        const viewParent = this.mapDomToView(domParent);\n        // The position is incorrect when anchored inside a UIElement or a RawElement.\n        // Note: In case of UIElement and RawElement, mapDomToView() returns a parent element for any DOM child\n        // so there's no need to perform any additional checks.\n        if (viewParent && (viewParent.is('uiElement') || viewParent.is('rawElement'))) {\n            return false;\n        }\n        return true;\n    }\n    /**\n\t * Internal generator for {@link #domToView}. Also used by {@link #domChildrenToView}.\n\t * Separates DOM nodes conversion from whitespaces processing.\n\t *\n\t * @param domNode DOM node or document fragment to transform.\n\t * @param inlineNodes An array of recently encountered inline nodes truncated to the block element boundaries.\n\t * Used later to process whitespaces.\n\t */ *_domToView(domNode, options, inlineNodes) {\n        if (this.isBlockFiller(domNode)) {\n            return null;\n        }\n        // When node is inside a UIElement or a RawElement return that parent as it's view representation.\n        const hostElement = this.getHostViewElement(domNode);\n        if (hostElement) {\n            return hostElement;\n        }\n        if (isComment(domNode) && options.skipComments) {\n            return null;\n        }\n        if (isText(domNode)) {\n            if (isInlineFiller(domNode)) {\n                return null;\n            } else {\n                const textData = domNode.data;\n                if (textData === '') {\n                    return null;\n                }\n                const textNode = new Text$1(this.document, textData);\n                inlineNodes.push(textNode);\n                return textNode;\n            }\n        } else {\n            let viewElement = this.mapDomToView(domNode);\n            if (viewElement) {\n                if (this._isInlineObjectElement(viewElement)) {\n                    inlineNodes.push(viewElement);\n                }\n                return viewElement;\n            }\n            if (this.isDocumentFragment(domNode)) {\n                // Create view document fragment.\n                viewElement = new DocumentFragment$1(this.document);\n                if (options.bind) {\n                    this.bindDocumentFragments(domNode, viewElement);\n                }\n            } else {\n                // Create view element.\n                viewElement = this._createViewElement(domNode, options);\n                if (options.bind) {\n                    this.bindElements(domNode, viewElement);\n                }\n                // Copy element's attributes.\n                const attrs = domNode.attributes;\n                if (attrs) {\n                    for(let l = attrs.length, i = 0; i < l; i++){\n                        viewElement._setAttribute(attrs[i].name, attrs[i].value);\n                    }\n                }\n                // Treat this element's content as a raw data if it was registered as such.\n                if (this._isViewElementWithRawContent(viewElement, options)) {\n                    viewElement._setCustomProperty('$rawContent', domNode.innerHTML);\n                    if (!this._isBlockViewElement(viewElement)) {\n                        inlineNodes.push(viewElement);\n                    }\n                    return viewElement;\n                }\n                // Comment node is also treated as an element with raw data.\n                if (isComment(domNode)) {\n                    viewElement._setCustomProperty('$rawContent', domNode.data);\n                    return viewElement;\n                }\n            }\n            // Yield the element first so the flow of nested inline nodes is not reversed inside elements.\n            yield viewElement;\n            const nestedInlineNodes = [];\n            if (options.withChildren !== false) {\n                for (const child of this.domChildrenToView(domNode, options, nestedInlineNodes)){\n                    viewElement._appendChild(child);\n                }\n            }\n            // Check if this is an inline object after processing child nodes so matcher\n            // for inline objects can verify if the element is empty.\n            if (this._isInlineObjectElement(viewElement)) {\n                inlineNodes.push(viewElement);\n                // Inline object content should be handled as a flow-root.\n                this._processDomInlineNodes(null, nestedInlineNodes, options);\n            } else {\n                // It's an inline element that is not an object (like <b>, <i>) or a block element.\n                for (const inlineNode of nestedInlineNodes){\n                    inlineNodes.push(inlineNode);\n                }\n            }\n        }\n    }\n    /**\n\t * Internal helper that walks the list of inline view nodes already generated from DOM nodes\n\t * and handles whitespaces and NBSPs.\n\t *\n\t * @param domParent The DOM parent of the given inline nodes. This should be a document fragment or\n\t * a block element to whitespace processing start cleaning.\n\t * @param inlineNodes An array of recently encountered inline nodes truncated to the block element boundaries.\n\t */ _processDomInlineNodes(domParent, inlineNodes, options) {\n        if (!inlineNodes.length) {\n            return;\n        }\n        // Process text nodes only after reaching a block or document fragment,\n        // do not alter whitespaces while processing an inline element like <b> or <i>.\n        if (domParent && !this.isDocumentFragment(domParent) && !this._isBlockDomElement(domParent)) {\n            return;\n        }\n        let prevNodeEndsWithSpace = false;\n        for(let i = 0; i < inlineNodes.length; i++){\n            const node = inlineNodes[i];\n            if (!node.is('$text')) {\n                prevNodeEndsWithSpace = false;\n                continue;\n            }\n            let data;\n            let nodeEndsWithSpace = false;\n            if (this._isPreFormatted(node)) {\n                data = getDataWithoutFiller(node.data);\n            } else {\n                // Change all consecutive whitespace characters (from the [ \\n\\t\\r] set –\n                // see https://github.com/ckeditor/ckeditor5-engine/issues/822#issuecomment-311670249) to a single space character.\n                // That's how multiple whitespaces are treated when rendered, so we normalize those whitespaces.\n                // We're replacing 1+ (and not 2+) to also normalize singular \\n\\t\\r characters (#822).\n                data = node.data.replace(/[ \\n\\t\\r]{1,}/g, ' ');\n                nodeEndsWithSpace = /[^\\S\\u00A0]/.test(data.charAt(data.length - 1));\n                const prevNode = i > 0 ? inlineNodes[i - 1] : null;\n                const nextNode = i + 1 < inlineNodes.length ? inlineNodes[i + 1] : null;\n                const shouldLeftTrim = !prevNode || prevNode.is('element') && prevNode.name == 'br' || prevNodeEndsWithSpace;\n                const shouldRightTrim = nextNode ? false : !startsWithFiller(node.data);\n                // Do not try to clear whitespaces if this is flat mapping for the purpose of mutation observer and differ in rendering.\n                if (options.withChildren !== false) {\n                    // If the previous dom text node does not exist or it ends by whitespace character, remove space character from the\n                    // beginning of this text node. Such space character is treated as a whitespace.\n                    if (shouldLeftTrim) {\n                        data = data.replace(/^ /, '');\n                    }\n                    // If the next text node does not exist remove space character from the end of this text node.\n                    if (shouldRightTrim) {\n                        data = data.replace(/ $/, '');\n                    }\n                }\n                // At the beginning and end of a block element, Firefox inserts normal space + <br> instead of non-breaking space.\n                // This means that the text node starts/end with normal space instead of non-breaking space.\n                // This causes a problem because the normal space would be removed in `.replace` calls above. To prevent that,\n                // the inline filler is removed only after the data is initially processed (by the `.replace` above). See ckeditor5#692.\n                data = getDataWithoutFiller(data);\n                // At this point we should have removed all whitespaces from DOM text data.\n                //\n                // Now, We will reverse the process that happens in `_processDataFromViewText`.\n                //\n                // We have to change &nbsp; chars, that were in DOM text data because of rendering reasons, to spaces.\n                // First, change all ` \\u00A0` pairs (space + &nbsp;) to two spaces. DOM converter changes two spaces from model/view to\n                // ` \\u00A0` to ensure proper rendering. Since here we convert back, we recognize those pairs and change them back to `  `.\n                data = data.replace(/ \\u00A0/g, '  ');\n                const isNextNodeInlineObjectElement = nextNode && nextNode.is('element') && nextNode.name != 'br';\n                const isNextNodeStartingWithSpace = nextNode && nextNode.is('$text') && nextNode.data.charAt(0) == ' ';\n                // Then, let's change the last nbsp to a space.\n                if (/[ \\u00A0]\\u00A0$/.test(data) || !nextNode || isNextNodeInlineObjectElement || isNextNodeStartingWithSpace) {\n                    data = data.replace(/\\u00A0$/, ' ');\n                }\n                // Then, change &nbsp; character that is at the beginning of the text node to space character.\n                // We do that replacement only if this is the first node or the previous node ends on whitespace character.\n                if (shouldLeftTrim || prevNode && prevNode.is('element') && prevNode.name != 'br') {\n                    data = data.replace(/^\\u00A0/, ' ');\n                }\n            }\n            // At this point, all whitespaces should be removed and all &nbsp; created for rendering reasons should be\n            // changed to normal space. All left &nbsp; are &nbsp; inserted intentionally.\n            if (data.length == 0 && node.parent) {\n                node._remove();\n                inlineNodes.splice(i, 1);\n                i--;\n            } else {\n                node._data = data;\n                prevNodeEndsWithSpace = nodeEndsWithSpace;\n            }\n        }\n        inlineNodes.length = 0;\n    }\n    /**\n\t * Takes text data from a given {@link module:engine/view/text~Text#data} and processes it so\n\t * it is correctly displayed in the DOM.\n\t *\n\t * Following changes are done:\n\t *\n\t * * a space at the beginning is changed to `&nbsp;` if this is the first text node in its container\n\t * element or if a previous text node ends with a space character,\n\t * * space at the end of the text node is changed to `&nbsp;` if there are two spaces at the end of a node or if next node\n\t * starts with a space or if it is the last text node in its container,\n\t * * remaining spaces are replaced to a chain of spaces and `&nbsp;` (e.g. `'x   x'` becomes `'x &nbsp; x'`).\n\t *\n\t * Content of {@link #preElements} is not processed.\n\t *\n\t * @param node View text node to process.\n\t * @returns Processed text data.\n\t */ _processDataFromViewText(node) {\n        let data = node.data;\n        // If the currently processed view text node is preformatted, we should not change whitespaces.\n        if (this._isPreFormatted(node)) {\n            return data;\n        }\n        // 1. Replace the first space with a nbsp if the previous node ends with a space or there is no previous node\n        // (container element boundary).\n        if (data.charAt(0) == ' ') {\n            const prevNode = this._getTouchingInlineViewNode(node, false);\n            const prevEndsWithSpace = prevNode && prevNode.is('$textProxy') && this._nodeEndsWithSpace(prevNode);\n            if (prevEndsWithSpace || !prevNode) {\n                data = '\\u00A0' + data.substr(1);\n            }\n        }\n        // 2. Replace the last space with nbsp if there are two spaces at the end or if the next node starts with space or there is no\n        // next node (container element boundary).\n        //\n        // Keep in mind that Firefox prefers $nbsp; before tag, not inside it:\n        //\n        // Foo <span>&nbsp;bar</span>  <-- bad.\n        // Foo&nbsp;<span> bar</span>  <-- good.\n        //\n        // More here: https://github.com/ckeditor/ckeditor5-engine/issues/1747.\n        if (data.charAt(data.length - 1) == ' ') {\n            const nextNode = this._getTouchingInlineViewNode(node, true);\n            const nextStartsWithSpace = nextNode && nextNode.is('$textProxy') && nextNode.data.charAt(0) == ' ';\n            if (data.charAt(data.length - 2) == ' ' || !nextNode || nextStartsWithSpace) {\n                data = data.substr(0, data.length - 1) + '\\u00A0';\n            }\n        }\n        // 3. Create space+nbsp pairs.\n        return data.replace(/ {2}/g, ' \\u00A0');\n    }\n    /**\n\t * Checks whether given node ends with a space character after changing appropriate space characters to `&nbsp;`s.\n\t *\n\t * @param  node Node to check.\n\t * @returns `true` if given `node` ends with space, `false` otherwise.\n\t */ _nodeEndsWithSpace(node) {\n        if (this._isPreFormatted(node)) {\n            return false;\n        }\n        const data = this._processDataFromViewText(node);\n        return data.charAt(data.length - 1) == ' ';\n    }\n    /**\n\t * Checks whether given text contains preformatted white space. This is the case if\n\t * * any of node ancestors has a name which is in `preElements` array, or\n\t * * the closest ancestor that has the `white-space` CSS property sets it to a value that preserves spaces\n\t *\n\t * @param node Node to check\n\t * @returns `true` if given node contains preformatted white space, `false` otherwise.\n\t */ _isPreFormatted(node) {\n        if (_hasViewParentOfType(node, this.preElements)) {\n            return true;\n        }\n        for (const ancestor of node.getAncestors({\n            parentFirst: true\n        })){\n            if (!ancestor.is('element') || !ancestor.hasStyle('white-space') || ancestor.getStyle('white-space') === 'inherit') {\n                continue;\n            }\n            // If the node contains the `white-space` property with a value that does not preserve spaces, it will take\n            // precedence over any white-space settings its ancestors contain, so no further parent checking needs to\n            // be done.\n            return [\n                'pre',\n                'pre-wrap',\n                'break-spaces'\n            ].includes(ancestor.getStyle('white-space'));\n        }\n        return false;\n    }\n    /**\n\t * Helper function. For given {@link module:engine/view/text~Text view text node}, it finds previous or next sibling\n\t * that is contained in the same container element. If there is no such sibling, `null` is returned.\n\t *\n\t * @param node Reference node.\n\t * @returns Touching text node, an inline object\n\t * or `null` if there is no next or previous touching text node.\n\t */ _getTouchingInlineViewNode(node, getNext) {\n        const treeWalker = new TreeWalker$1({\n            startPosition: getNext ? Position$1._createAfter(node) : Position$1._createBefore(node),\n            direction: getNext ? 'forward' : 'backward'\n        });\n        for (const { item } of treeWalker){\n            // Found a text node in the same container element.\n            if (item.is('$textProxy')) {\n                return item;\n            } else if (item.is('element') && item.getCustomProperty('dataPipeline:transparentRendering')) {\n                continue;\n            } else if (item.is('element', 'br')) {\n                return null;\n            } else if (this._isInlineObjectElement(item)) {\n                return item;\n            } else if (item.is('containerElement')) {\n                return null;\n            }\n        }\n        return null;\n    }\n    /**\n\t * Returns `true` if a DOM node belongs to {@link #blockElements}. `false` otherwise.\n\t */ _isBlockDomElement(node) {\n        return this.isElement(node) && this.blockElements.includes(node.tagName.toLowerCase());\n    }\n    /**\n\t * Returns `true` if a view node belongs to {@link #blockElements}. `false` otherwise.\n\t */ _isBlockViewElement(node) {\n        return node.is('element') && this.blockElements.includes(node.name);\n    }\n    /**\n\t * Returns `true` if a DOM node belongs to {@link #inlineObjectElements}. `false` otherwise.\n\t */ _isInlineObjectElement(node) {\n        if (!node.is('element')) {\n            return false;\n        }\n        return node.name == 'br' || this.inlineObjectElements.includes(node.name) || !!this._inlineObjectElementMatcher.match(node);\n    }\n    /**\n\t * Creates view element basing on the node type.\n\t *\n\t * @param node DOM node to check.\n\t * @param options Conversion options. See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t */ _createViewElement(node, options) {\n        if (isComment(node)) {\n            return new UIElement(this.document, '$comment');\n        }\n        const viewName = options.keepOriginalCase ? node.tagName : node.tagName.toLowerCase();\n        return new Element$1(this.document, viewName);\n    }\n    /**\n\t * Checks if view element's content should be treated as a raw data.\n\t *\n\t * @param viewElement View element to check.\n\t * @param options Conversion options. See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t */ _isViewElementWithRawContent(viewElement, options) {\n        return options.withChildren !== false && viewElement.is('element') && !!this._rawContentElementMatcher.match(viewElement);\n    }\n    /**\n\t * Checks whether a given element name should be renamed in a current rendering mode.\n\t *\n\t * @param elementName The name of view element.\n\t */ _shouldRenameElement(elementName) {\n        const name = elementName.toLowerCase();\n        return this.renderingMode === 'editing' && this.unsafeElements.includes(name);\n    }\n    /**\n\t * Return a <span> element with a special attribute holding the name of the original element.\n\t * Optionally, copy all the attributes of the original element if that element is provided.\n\t *\n\t * @param elementName The name of view element.\n\t * @param originalDomElement The original DOM element to copy attributes and content from.\n\t */ _createReplacementDomElement(elementName, originalDomElement) {\n        const newDomElement = this._domDocument.createElement('span');\n        // Mark the span replacing a script as hidden.\n        newDomElement.setAttribute(UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE, elementName);\n        if (originalDomElement) {\n            while(originalDomElement.firstChild){\n                newDomElement.appendChild(originalDomElement.firstChild);\n            }\n            for (const attributeName of originalDomElement.getAttributeNames()){\n                newDomElement.setAttribute(attributeName, originalDomElement.getAttribute(attributeName));\n            }\n        }\n        return newDomElement;\n    }\n}\n/**\n * Helper function.\n * Used to check if given native `Element` or `Text` node has parent with tag name from `types` array.\n *\n * @returns`true` if such parent exists or `false` if it does not.\n */ function _hasViewParentOfType(node, types) {\n    return node.getAncestors().some((parent)=>parent.is('element') && types.includes(parent.name));\n}\n/**\n * A helper that executes given callback for each DOM node's ancestor, starting from the given node\n * and ending in document#documentElement.\n *\n * @param callback A callback to be executed for each ancestor.\n */ function forEachDomElementAncestor(element, callback) {\n    let node = element;\n    while(node){\n        callback(node);\n        node = node.parentElement;\n    }\n}\n/**\n * Checks if given node is a nbsp block filler.\n *\n * A &nbsp; is a block filler only if it is a single child of a block element.\n *\n * @param domNode DOM node.\n */ function isNbspBlockFiller(domNode, blockElements) {\n    const isNBSP = domNode.isEqualNode(NBSP_FILLER_REF);\n    return isNBSP && hasBlockParent(domNode, blockElements) && domNode.parentNode.childNodes.length === 1;\n}\n/**\n * Checks if domNode has block parent.\n *\n * @param domNode DOM node.\n */ function hasBlockParent(domNode, blockElements) {\n    const parent = domNode.parentNode;\n    return !!parent && !!parent.tagName && blockElements.includes(parent.tagName.toLowerCase());\n}\n/**\n * Log to console the information about element that was replaced.\n * Check UNSAFE_ELEMENTS for all recognized unsafe elements.\n *\n * @param elementName The name of the view element.\n */ function _logUnsafeElement(elementName) {\n    if (elementName === 'script') {\n        logWarning('domconverter-unsafe-script-element-detected');\n    }\n    if (elementName === 'style') {\n        logWarning('domconverter-unsafe-style-element-detected');\n    }\n}\n/**\n * In certain cases, Firefox mysteriously assigns so called \"restricted objects\" to native DOM Range properties.\n * Any attempt at accessing restricted object's properties causes errors.\n * See: https://github.com/ckeditor/ckeditor5/issues/9635.\n */ function isGeckoRestrictedDomSelection(domSelection) {\n    if (!env.isGecko) {\n        return false;\n    }\n    if (!domSelection.rangeCount) {\n        return false;\n    }\n    const container = domSelection.getRangeAt(0).startContainer;\n    try {\n        Object.prototype.toString.call(container);\n    } catch (error) {\n        return true;\n    }\n    return false;\n}\n /**\n * While rendering the editor content, the {@link module:engine/view/domconverter~DomConverter} detected a `<script>` element that may\n * disrupt the editing experience. To avoid this, the `<script>` element was replaced with `<span data-ck-unsafe-element=\"script\"></span>`.\n *\n * @error domconverter-unsafe-script-element-detected\n */  /**\n * While rendering the editor content, the {@link module:engine/view/domconverter~DomConverter} detected a `<style>` element that may affect\n * the editing experience. To avoid this, the `<style>` element was replaced with `<span data-ck-unsafe-element=\"style\"></span>`.\n *\n * @error domconverter-unsafe-style-element-detected\n */  /**\n * The {@link module:engine/view/domconverter~DomConverter} detected an interactive attribute in the\n * {@glink framework/architecture/editing-engine#editing-pipeline editing pipeline}. For the best\n * editing experience, the attribute was renamed to `data-ck-unsafe-attribute-[original attribute name]`.\n *\n * If you are the author of the plugin that generated this attribute and you want it to be preserved\n * in the editing pipeline, you can configure this when creating the element\n * using {@link module:engine/view/downcastwriter~DowncastWriter} during the\n * {@glink framework/architecture/editing-engine#conversion model–view conversion}. Methods such as\n * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement},\n * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement}, or\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement}\n * accept an option that will disable filtering of specific attributes:\n *\n * ```ts\n * const paragraph = writer.createContainerElement( 'p',\n * \t{\n * \t\tclass: 'clickable-paragraph',\n * \t\tonclick: 'alert( \"Paragraph clicked!\" )'\n * \t},\n * \t{\n * \t\t// Make sure the \"onclick\" attribute will pass through.\n * \t\trenderUnsafeAttributes: [ 'onclick' ]\n * \t}\n * );\n * ```\n *\n * @error domconverter-unsafe-attribute-detected\n * @param domElement The DOM element the attribute was set on.\n * @param key The original name of the attribute\n * @param value The value of the original attribute\n */\n\n/**\n * Abstract base observer class. Observers are classes which listen to DOM events, do the preliminary\n * processing and fire events on the {@link module:engine/view/document~Document} objects.\n * Observers can also add features to the view, for instance by updating its status or marking elements\n * which need a refresh on DOM events.\n */ class Observer extends /* #__PURE__ */ DomEmitterMixin() {\n    /**\n\t * An instance of the view controller.\n\t */ view;\n    /**\n\t * A reference to the {@link module:engine/view/document~Document} object.\n\t */ document;\n    /**\n\t * The state of the observer. If it is disabled, no events will be fired.\n\t */ _isEnabled = false;\n    /**\n\t * Creates an instance of the observer.\n\t */ constructor(view){\n        super();\n        this.view = view;\n        this.document = view.document;\n    }\n    /**\n\t * The state of the observer. If it is disabled, no events will be fired.\n\t */ get isEnabled() {\n        return this._isEnabled;\n    }\n    /**\n\t * Enables the observer. This method is called when the observer is registered to the\n\t * {@link module:engine/view/view~View} and after {@link module:engine/view/view~View#forceRender rendering}\n\t * (all observers are {@link #disable disabled} before rendering).\n\t *\n\t * A typical use case for disabling observers is that mutation observers need to be disabled for the rendering.\n\t * However, a child class may not need to be disabled, so it can implement an empty method.\n\t *\n\t * @see module:engine/view/observer/observer~Observer#disable\n\t */ enable() {\n        this._isEnabled = true;\n    }\n    /**\n\t * Disables the observer. This method is called before\n\t * {@link module:engine/view/view~View#forceRender rendering} to prevent firing events during rendering.\n\t *\n\t * @see module:engine/view/observer/observer~Observer#enable\n\t */ disable() {\n        this._isEnabled = false;\n    }\n    /**\n\t * Disables and destroys the observer, among others removes event listeners created by the observer.\n\t */ destroy() {\n        this.disable();\n        this.stopListening();\n    }\n    /**\n\t * Checks whether a given DOM event should be ignored (should not be turned into a synthetic view document event).\n\t *\n\t * Currently, an event will be ignored only if its target or any of its ancestors has the `data-cke-ignore-events` attribute.\n\t * This attribute can be used inside the structures generated by\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `DowncastWriter#createUIElement()`} to ignore events\n\t * fired within a UI that should be excluded from CKEditor 5's realms.\n\t *\n\t * @param domTarget The DOM event target to check (usually an element, sometimes a text node and\n\t * potentially sometimes a document, too).\n\t * @returns Whether this event should be ignored by the observer.\n\t */ checkShouldIgnoreEventFromTarget(domTarget) {\n        if (domTarget && domTarget.nodeType === 3) {\n            domTarget = domTarget.parentNode;\n        }\n        if (!domTarget || domTarget.nodeType !== 1) {\n            return false;\n        }\n        return domTarget.matches('[data-cke-ignore-events], [data-cke-ignore-events] *');\n    }\n}\n\n/**\n * Information about a DOM event in context of the {@link module:engine/view/document~Document}.\n * It wraps the native event, which usually should not be used as the wrapper contains\n * additional data (like key code for keyboard events).\n *\n * @typeParam TEvent The type of DOM Event that this class represents.\n */ class DomEventData {\n    /**\n\t * Instance of the view controller.\n\t */ view;\n    /**\n\t * The instance of the document.\n\t */ document;\n    /**\n\t * The DOM event.\n\t */ domEvent;\n    /**\n\t * The DOM target.\n\t */ domTarget;\n    /**\n\t * @param view The instance of the view controller.\n\t * @param domEvent The DOM event.\n\t * @param additionalData Additional properties that the instance should contain.\n\t */ constructor(view, domEvent, additionalData){\n        this.view = view;\n        this.document = view.document;\n        this.domEvent = domEvent;\n        this.domTarget = domEvent.target;\n        extend(this, additionalData);\n    }\n    /**\n\t * The tree view element representing the target.\n\t */ get target() {\n        return this.view.domConverter.mapDomToView(this.domTarget);\n    }\n    /**\n\t * Prevents the native's event default action.\n\t */ preventDefault() {\n        this.domEvent.preventDefault();\n    }\n    /**\n\t * Stops native event propagation.\n\t */ stopPropagation() {\n        this.domEvent.stopPropagation();\n    }\n}\n\n/**\n * Base class for DOM event observers. This class handles\n * {@link module:engine/view/observer/observer~Observer#observe adding} listeners to DOM elements,\n * {@link module:engine/view/observer/observer~Observer#disable disabling} and\n * {@link module:engine/view/observer/observer~Observer#enable re-enabling} events.\n * Child class needs to define\n * {@link module:engine/view/observer/domeventobserver~DomEventObserver#domEventType DOM event type} and\n * {@link module:engine/view/observer/domeventobserver~DomEventObserver#onDomEvent callback}.\n *\n * For instance:\n *\n * ```ts\n * class ClickObserver extends DomEventObserver<'click'> {\n * \t// It can also be defined as a normal property in the constructor.\n * \tget domEventType(): 'click' {\n * \t\treturn 'click';\n * \t}\n *\n * \tonDomEvent( domEvent: MouseEvent ): void {\n * \t\tthis.fire( 'click', domEvent );\n * \t}\n * }\n * ```\n *\n * @typeParam EventType DOM Event type name or an union of those.\n * @typeParam AdditionalData Additional data passed along with the event.\n */ class DomEventObserver extends Observer {\n    /**\n\t * If set to `true` DOM events will be listened on the capturing phase.\n\t * Default value is `false`.\n\t */ useCapture = false;\n    /**\n\t * If set to `true`, indicates that the function specified by listener will never call `preventDefault()`.\n\t * Default value is `false`.\n\t */ usePassive = false;\n    /**\n\t * @inheritDoc\n\t */ observe(domElement) {\n        const types = typeof this.domEventType == 'string' ? [\n            this.domEventType\n        ] : this.domEventType;\n        types.forEach((type)=>{\n            this.listenTo(domElement, type, (eventInfo, domEvent)=>{\n                if (this.isEnabled && !this.checkShouldIgnoreEventFromTarget(domEvent.target)) {\n                    this.onDomEvent(domEvent);\n                }\n            }, {\n                useCapture: this.useCapture,\n                usePassive: this.usePassive\n            });\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ stopObserving(domElement) {\n        this.stopListening(domElement);\n    }\n    /**\n\t * Calls `Document#fire()` if observer {@link #isEnabled is enabled}.\n\t *\n\t * @see module:utils/emittermixin~Emitter#fire\n\t * @param eventType The event type (name).\n\t * @param domEvent The DOM event.\n\t * @param additionalData The additional data which should extend the\n\t * {@link module:engine/view/observer/domeventdata~DomEventData event data} object.\n\t */ fire(eventType, domEvent, additionalData) {\n        if (this.isEnabled) {\n            this.document.fire(eventType, new DomEventData(this.view, domEvent, additionalData));\n        }\n    }\n}\n\n/**\n * Observer for events connected with pressing keyboard keys.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */ class KeyObserver extends DomEventObserver {\n    /**\n\t * @inheritDoc\n\t */ domEventType = [\n        'keydown',\n        'keyup'\n    ];\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvt) {\n        const data = {\n            keyCode: domEvt.keyCode,\n            altKey: domEvt.altKey,\n            ctrlKey: domEvt.ctrlKey,\n            shiftKey: domEvt.shiftKey,\n            metaKey: domEvt.metaKey,\n            get keystroke () {\n                return getCode(this);\n            }\n        };\n        this.fire(domEvt.type, domEvt, data);\n    }\n}\n\n/**\n * Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens\n * on {@link module:engine/view/document~Document#event:keydown keydown} events and handles moving fake view selection to the correct place\n * if arrow keys are pressed.\n * Fires {@link module:engine/view/document~Document#event:selectionChange selectionChange event} simulating natural behaviour of\n * {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.\n */ class FakeSelectionObserver extends Observer {\n    /**\n\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t */ _fireSelectionChangeDoneDebounced;\n    /**\n\t * Creates new FakeSelectionObserver instance.\n\t */ constructor(view){\n        super(view);\n        this._fireSelectionChangeDoneDebounced = debounce((data)=>{\n            this.document.fire('selectionChangeDone', data);\n        }, 200);\n    }\n    /**\n\t * @inheritDoc\n\t */ observe() {\n        const document = this.document;\n        document.on('arrowKey', (eventInfo, data)=>{\n            const selection = document.selection;\n            if (selection.isFake && this.isEnabled) {\n                // Prevents default key down handling - no selection change will occur.\n                data.preventDefault();\n            }\n        }, {\n            context: '$capture'\n        });\n        document.on('arrowKey', (eventInfo, data)=>{\n            const selection = document.selection;\n            if (selection.isFake && this.isEnabled) {\n                this._handleSelectionMove(data.keyCode);\n            }\n        }, {\n            priority: 'lowest'\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ stopObserving() {}\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this._fireSelectionChangeDoneDebounced.cancel();\n    }\n    /**\n\t * Handles collapsing view selection according to given key code. If left or up key is provided - new selection will be\n\t * collapsed to left. If right or down key is pressed - new selection will be collapsed to right.\n\t *\n\t * This method fires {@link module:engine/view/document~Document#event:selectionChange} and\n\t * {@link module:engine/view/document~Document#event:selectionChangeDone} events imitating behaviour of\n\t * {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n\t */ _handleSelectionMove(keyCode) {\n        const selection = this.document.selection;\n        const newSelection = new Selection$1(selection.getRanges(), {\n            backward: selection.isBackward,\n            fake: false\n        });\n        // Left or up arrow pressed - move selection to start.\n        if (keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup) {\n            newSelection.setTo(newSelection.getFirstPosition());\n        }\n        // Right or down arrow pressed - move selection to end.\n        if (keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowdown) {\n            newSelection.setTo(newSelection.getLastPosition());\n        }\n        const data = {\n            oldSelection: selection,\n            newSelection,\n            domSelection: null\n        };\n        // Fire dummy selection change event.\n        this.document.fire('selectionChange', data);\n        // Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n        // This function is debounced what means that `selectionChangeDone` event will be fired only when\n        // defined int the function time will elapse since the last time the function was called.\n        // So `selectionChangeDone` will be fired when selection will stop changing.\n        this._fireSelectionChangeDoneDebounced(data);\n    }\n}\n\n// @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );\n/**\n * Mutation observer's role is to watch for any DOM changes inside the editor that weren't\n * done by the editor's {@link module:engine/view/renderer~Renderer} itself and reverting these changes.\n *\n * It does this by observing all mutations in the DOM, marking related view elements as changed and calling\n * {@link module:engine/view/renderer~Renderer#render}. Because all mutated nodes are marked as\n * \"to be rendered\" and the {@link module:engine/view/renderer~Renderer#render `render()`} method is called,\n * all changes are reverted in the DOM (the DOM is synced with the editor's view structure).\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */ class MutationObserver extends Observer {\n    /**\n\t * Reference to the {@link module:engine/view/view~View#domConverter}.\n\t */ domConverter;\n    /**\n\t * Native mutation observer config.\n\t */ _config;\n    /**\n\t * Observed DOM elements.\n\t */ _domElements;\n    /**\n\t * Native mutation observer.\n\t */ _mutationObserver;\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        this._config = {\n            childList: true,\n            characterData: true,\n            subtree: true\n        };\n        this.domConverter = view.domConverter;\n        this._domElements = new Set();\n        this._mutationObserver = new window.MutationObserver(this._onMutations.bind(this));\n    }\n    /**\n\t * Synchronously handles mutations and empties the queue.\n\t */ flush() {\n        this._onMutations(this._mutationObserver.takeRecords());\n    }\n    /**\n\t * @inheritDoc\n\t */ observe(domElement) {\n        this._domElements.add(domElement);\n        if (this.isEnabled) {\n            this._mutationObserver.observe(domElement, this._config);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ stopObserving(domElement) {\n        this._domElements.delete(domElement);\n        if (this.isEnabled) {\n            // Unfortunately, it is not possible to stop observing particular DOM element.\n            // In order to stop observing one of multiple DOM elements, we need to re-connect the mutation observer.\n            this._mutationObserver.disconnect();\n            for (const domElement of this._domElements){\n                this._mutationObserver.observe(domElement, this._config);\n            }\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ enable() {\n        super.enable();\n        for (const domElement of this._domElements){\n            this._mutationObserver.observe(domElement, this._config);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ disable() {\n        super.disable();\n        this._mutationObserver.disconnect();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this._mutationObserver.disconnect();\n    }\n    /**\n\t * Handles mutations. Mark view elements to sync and call render.\n\t *\n\t * @param domMutations Array of native mutations.\n\t */ _onMutations(domMutations) {\n        // As a result of this.flush() we can have an empty collection.\n        if (domMutations.length === 0) {\n            return;\n        }\n        const domConverter = this.domConverter;\n        // Use map and set for deduplication.\n        const mutatedTextNodes = new Set();\n        const elementsWithMutatedChildren = new Set();\n        // Handle `childList` mutations first, so we will be able to check if the `characterData` mutation is in the\n        // element with changed structure anyway.\n        for (const mutation of domMutations){\n            const element = domConverter.mapDomToView(mutation.target);\n            if (!element) {\n                continue;\n            }\n            // Do not collect mutations from UIElements and RawElements.\n            if (element.is('uiElement') || element.is('rawElement')) {\n                continue;\n            }\n            if (mutation.type === 'childList' && !this._isBogusBrMutation(mutation)) {\n                elementsWithMutatedChildren.add(element);\n            }\n        }\n        // Handle `characterData` mutations later, when we have the full list of nodes which changed structure.\n        for (const mutation of domMutations){\n            const element = domConverter.mapDomToView(mutation.target);\n            // Do not collect mutations from UIElements and RawElements.\n            if (element && (element.is('uiElement') || element.is('rawElement'))) {\n                continue;\n            }\n            if (mutation.type === 'characterData') {\n                const text = domConverter.findCorrespondingViewText(mutation.target);\n                if (text && !elementsWithMutatedChildren.has(text.parent)) {\n                    mutatedTextNodes.add(text);\n                } else if (!text && startsWithFiller(mutation.target)) {\n                    elementsWithMutatedChildren.add(domConverter.mapDomToView(mutation.target.parentNode));\n                }\n            }\n        }\n        // Now we build the list of mutations to mark elements. We did not do it earlier to avoid marking the\n        // same node multiple times in case of duplication.\n        const mutations = [];\n        for (const textNode of mutatedTextNodes){\n            mutations.push({\n                type: 'text',\n                node: textNode\n            });\n        }\n        for (const viewElement of elementsWithMutatedChildren){\n            const domElement = domConverter.mapViewToDom(viewElement);\n            const viewChildren = Array.from(viewElement.getChildren());\n            const newViewChildren = Array.from(domConverter.domChildrenToView(domElement, {\n                withChildren: false\n            }));\n            // It may happen that as a result of many changes (sth was inserted and then removed),\n            // both elements haven't really changed. #1031\n            if (!isEqualWith(viewChildren, newViewChildren, sameNodes)) {\n                mutations.push({\n                    type: 'children',\n                    node: viewElement\n                });\n            }\n        }\n        // In case only non-relevant mutations were recorded it skips the event and force render (#5600).\n        if (mutations.length) {\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \t_debouncedLine();\n            // @if CK_DEBUG_TYPING // \tconsole.group( '%c[MutationObserver]%c Mutations detected',\n            // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', 'font-weight: bold'\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            this.document.fire('mutations', {\n                mutations\n            });\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n        // @if CK_DEBUG_TYPING // }\n        }\n    }\n    /**\n\t * Checks if mutation was generated by the browser inserting bogus br on the end of the block element.\n\t * Such mutations are generated while pressing space or performing native spellchecker correction\n\t * on the end of the block element in Firefox browser.\n\t *\n\t * @param mutation Native mutation object.\n\t */ _isBogusBrMutation(mutation) {\n        let addedNode = null;\n        // Check if mutation added only one node on the end of its parent.\n        if (mutation.nextSibling === null && mutation.removedNodes.length === 0 && mutation.addedNodes.length == 1) {\n            addedNode = this.domConverter.domToView(mutation.addedNodes[0], {\n                withChildren: false\n            });\n        }\n        return addedNode && addedNode.is('element', 'br');\n    }\n}\nfunction sameNodes(child1, child2) {\n    // First level of comparison (array of children vs array of children) – use the Lodash's default behavior.\n    if (Array.isArray(child1)) {\n        return;\n    }\n    // Elements.\n    if (child1 === child2) {\n        return true;\n    } else if (child1.is('$text') && child2.is('$text')) {\n        return child1.data === child2.data;\n    }\n    // Not matching types.\n    return false;\n}\n\n/**\n * {@link module:engine/view/document~Document#event:focus Focus}\n * and {@link module:engine/view/document~Document#event:blur blur} events observer.\n * Focus observer handle also {@link module:engine/view/rooteditableelement~RootEditableElement#isFocused isFocused} property of the\n * {@link module:engine/view/rooteditableelement~RootEditableElement root elements}.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */ class FocusObserver extends DomEventObserver {\n    /**\n\t * Identifier of the timeout currently used by focus listener to delay rendering execution.\n\t */ _renderTimeoutId = null;\n    /**\n\t * Set to `true` if the document is in the process of setting the focus.\n\t *\n\t * The flag is used to indicate that setting the focus is in progress.\n\t */ _isFocusChanging = false;\n    /**\n\t * @inheritDoc\n\t */ domEventType = [\n        'focus',\n        'blur'\n    ];\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        this.useCapture = true;\n        const document = this.document;\n        document.on('focus', ()=>this._handleFocus());\n        document.on('blur', (evt, data)=>this._handleBlur(data));\n        // Focus the editor in cases where browser dispatches `beforeinput` event to a not-focused editable element.\n        // This is flushed by the beforeinput listener in the `InsertTextObserver`.\n        // Note that focus is set only if the document is not focused yet.\n        // See https://github.com/ckeditor/ckeditor5/issues/14702.\n        document.on('beforeinput', ()=>{\n            if (!document.isFocused) {\n                this._handleFocus();\n            }\n        }, {\n            priority: 'highest'\n        });\n    }\n    /**\n\t * Finishes setting the document focus state.\n\t */ flush() {\n        if (this._isFocusChanging) {\n            this._isFocusChanging = false;\n            this.document.isFocused = true;\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvent) {\n        this.fire(domEvent.type, domEvent);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this._clearTimeout();\n        super.destroy();\n    }\n    /**\n\t * The `focus` event handler.\n\t */ _handleFocus() {\n        this._clearTimeout();\n        this._isFocusChanging = true;\n        // Unfortunately native `selectionchange` event is fired asynchronously.\n        // We need to wait until `SelectionObserver` handle the event and then render. Otherwise rendering will\n        // overwrite new DOM selection with selection from the view.\n        // See https://github.com/ckeditor/ckeditor5-engine/issues/795 for more details.\n        // Long timeout is needed to solve #676 and https://github.com/ckeditor/ckeditor5-engine/issues/1157 issues.\n        //\n        // Using `view.change()` instead of `view.forceRender()` to prevent double rendering\n        // in a situation where `selectionchange` already caused selection change.\n        this._renderTimeoutId = setTimeout(()=>{\n            this._renderTimeoutId = null;\n            this.flush();\n            this.view.change(()=>{});\n        }, 50);\n    }\n    /**\n\t * The `blur` event handler.\n\t */ _handleBlur(data) {\n        const selectedEditable = this.document.selection.editableElement;\n        if (selectedEditable === null || selectedEditable === data.target) {\n            this.document.isFocused = false;\n            this._isFocusChanging = false;\n            // Re-render the document to update view elements\n            // (changing document.isFocused already marked view as changed since last rendering).\n            this.view.change(()=>{});\n        }\n    }\n    /**\n\t * Clears timeout.\n\t */ _clearTimeout() {\n        if (this._renderTimeoutId) {\n            clearTimeout(this._renderTimeoutId);\n            this._renderTimeoutId = null;\n        }\n    }\n}\n\n/**\n * Selection observer class observes selection changes in the document. If a selection changes on the document this\n * observer checks if the DOM selection is different from the {@link module:engine/view/document~Document#selection view selection}.\n * The selection observer fires {@link module:engine/view/document~Document#event:selectionChange} event only if\n * a selection change was the only change in the document and the DOM selection is different from the view selection.\n *\n * This observer also manages the {@link module:engine/view/document~Document#isSelecting} property of the view document.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */ class SelectionObserver extends Observer {\n    /**\n\t * Instance of the mutation observer. Selection observer calls\n\t * {@link module:engine/view/observer/mutationobserver~MutationObserver#flush} to ensure that the mutations will be handled\n\t * before the {@link module:engine/view/document~Document#event:selectionChange} event is fired.\n\t */ mutationObserver;\n    /**\n\t * Instance of the focus observer. Focus observer calls\n\t * {@link module:engine/view/observer/focusobserver~FocusObserver#flush} to mark the latest focus change as complete.\n\t */ focusObserver;\n    /**\n\t * Reference to the view {@link module:engine/view/documentselection~DocumentSelection} object used to compare\n\t * new selection with it.\n\t */ selection;\n    /**\n\t * Reference to the {@link module:engine/view/view~View#domConverter}.\n\t */ domConverter;\n    /**\n\t * A set of documents which have added `selectionchange` listener to avoid adding a listener twice to the same\n\t * document.\n\t */ _documents;\n    /**\n\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t */ _fireSelectionChangeDoneDebounced;\n    /**\n\t * When called, starts clearing the {@link #_loopbackCounter} counter in time intervals. When the number of selection\n\t * changes exceeds a certain limit within the interval of time, the observer will not fire `selectionChange` but warn about\n\t * possible infinite selection loop.\n\t */ _clearInfiniteLoopInterval;\n    /**\n\t * Unlocks the `isSelecting` state of the view document in case the selection observer did not record this fact\n\t * correctly (for whatever reason). It is a safeguard (paranoid check), that returns document to the normal state\n\t * after a certain period of time (debounced, postponed by each selectionchange event).\n\t */ _documentIsSelectingInactivityTimeoutDebounced;\n    /**\n\t * Private property to check if the code does not enter infinite loop.\n\t */ _loopbackCounter;\n    constructor(view){\n        super(view);\n        this.mutationObserver = view.getObserver(MutationObserver);\n        this.focusObserver = view.getObserver(FocusObserver);\n        this.selection = this.document.selection;\n        this.domConverter = view.domConverter;\n        this._documents = new WeakSet();\n        this._fireSelectionChangeDoneDebounced = debounce((data)=>{\n            this.document.fire('selectionChangeDone', data);\n        }, 200);\n        this._clearInfiniteLoopInterval = setInterval(()=>this._clearInfiniteLoop(), 1000);\n        this._documentIsSelectingInactivityTimeoutDebounced = debounce(()=>this.document.isSelecting = false, 5000);\n        this._loopbackCounter = 0;\n    }\n    /**\n\t * @inheritDoc\n\t */ observe(domElement) {\n        const domDocument = domElement.ownerDocument;\n        const startDocumentIsSelecting = ()=>{\n            this.document.isSelecting = true;\n            // Let's activate the safety timeout each time the document enters the \"is selecting\" state.\n            this._documentIsSelectingInactivityTimeoutDebounced();\n        };\n        const endDocumentIsSelecting = ()=>{\n            if (!this.document.isSelecting) {\n                return;\n            }\n            // Make sure that model selection is up-to-date at the end of selecting process.\n            // Sometimes `selectionchange` events could arrive after the `mouseup` event and that selection could be already outdated.\n            this._handleSelectionChange(domDocument);\n            this.document.isSelecting = false;\n            // The safety timeout can be canceled when the document leaves the \"is selecting\" state.\n            this._documentIsSelectingInactivityTimeoutDebounced.cancel();\n        };\n        // The document has the \"is selecting\" state while the user keeps making (extending) the selection\n        // (e.g. by holding the mouse button and moving the cursor). The state resets when they either released\n        // the mouse button or interrupted the process by pressing or releasing any key.\n        this.listenTo(domElement, 'selectstart', startDocumentIsSelecting, {\n            priority: 'highest'\n        });\n        this.listenTo(domElement, 'keydown', endDocumentIsSelecting, {\n            priority: 'highest',\n            useCapture: true\n        });\n        this.listenTo(domElement, 'keyup', endDocumentIsSelecting, {\n            priority: 'highest',\n            useCapture: true\n        });\n        // Add document-wide listeners only once. This method could be called for multiple editing roots.\n        if (this._documents.has(domDocument)) {\n            return;\n        }\n        // This listener is using capture mode to make sure that selection is upcasted before any other\n        // handler would like to check it and update (for example table multi cell selection).\n        this.listenTo(domDocument, 'mouseup', endDocumentIsSelecting, {\n            priority: 'highest',\n            useCapture: true\n        });\n        this.listenTo(domDocument, 'selectionchange', ()=>{\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \t_debouncedLine();\n            // @if CK_DEBUG_TYPING // \tconst domSelection = domDocument.defaultView!.getSelection();\n            // @if CK_DEBUG_TYPING // \tconsole.group( '%c[SelectionObserver]%c selectionchange', 'color: green', ''\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c DOM Selection:', 'font-weight: bold; color: green', '',\n            // @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },\n            // @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.focusNode, offset: domSelection!.focusOffset }\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            // The Renderer is disabled while composing on non-android browsers, so we can't update the view selection\n            // because the DOM and view tree drifted apart. Position mapping could fail because of it.\n            if (this.document.isComposing && !env.isAndroid) {\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c Selection change ignored (isComposing)',\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', ''\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n                // @if CK_DEBUG_TYPING // }\n                return;\n            }\n            this._handleSelectionChange(domDocument);\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n            // @if CK_DEBUG_TYPING // }\n            // Defer the safety timeout when the selection changes (e.g. the user keeps extending the selection\n            // using their mouse).\n            this._documentIsSelectingInactivityTimeoutDebounced();\n        });\n        // Update the model DocumentSelection just after the Renderer and the SelectionObserver are locked.\n        // We do this synchronously (without waiting for the `selectionchange` DOM event) as browser updates\n        // the DOM selection (but not visually) to span the text that is under composition and could be replaced.\n        this.listenTo(this.view.document, 'compositionstart', ()=>{\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconst domSelection = domDocument.defaultView!.getSelection();\n            // @if CK_DEBUG_TYPING // \tconsole.group( '%c[SelectionObserver]%c update selection on compositionstart', 'color: green', ''\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c DOM Selection:', 'font-weight: bold; color: green', '',\n            // @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },\n            // @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.focusNode, offset: domSelection!.focusOffset }\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            this._handleSelectionChange(domDocument);\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n        // @if CK_DEBUG_TYPING // }\n        }, {\n            priority: 'lowest'\n        });\n        this._documents.add(domDocument);\n    }\n    /**\n\t * @inheritDoc\n\t */ stopObserving(domElement) {\n        this.stopListening(domElement);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        clearInterval(this._clearInfiniteLoopInterval);\n        this._fireSelectionChangeDoneDebounced.cancel();\n        this._documentIsSelectingInactivityTimeoutDebounced.cancel();\n    }\n    /* istanbul ignore next -- @preserve */ _reportInfiniteLoop() {\n    // @if CK_DEBUG //\t\tthrow new Error(\n    // @if CK_DEBUG //\t\t\t'Selection change observer detected an infinite rendering loop.\\n\\n' +\n    // @if CK_DEBUG //\t \t\t'⚠️⚠️ Report this error on https://github.com/ckeditor/ckeditor5/issues/11658.'\n    // @if CK_DEBUG //\t\t);\n    }\n    /**\n\t * Selection change listener. {@link module:engine/view/observer/mutationobserver~MutationObserver#flush Flush} mutations, check if\n\t * a selection changes and fires {@link module:engine/view/document~Document#event:selectionChange} event on every change\n\t * and {@link module:engine/view/document~Document#event:selectionChangeDone} when a selection stop changing.\n\t *\n\t * @param domDocument DOM document.\n\t */ _handleSelectionChange(domDocument) {\n        if (!this.isEnabled) {\n            return;\n        }\n        const domSelection = domDocument.defaultView.getSelection();\n        if (this.checkShouldIgnoreEventFromTarget(domSelection.anchorNode)) {\n            return;\n        }\n        // Ensure the mutation event will be before selection event on all browsers.\n        this.mutationObserver.flush();\n        const newViewSelection = this.domConverter.domSelectionToView(domSelection);\n        // Do not convert selection change if the new view selection has no ranges in it.\n        //\n        // It means that the DOM selection is in some way incorrect. Ranges that were in the DOM selection could not be\n        // converted to the view. This happens when the DOM selection was moved outside of the editable element.\n        if (newViewSelection.rangeCount == 0) {\n            this.view.hasDomSelection = false;\n            return;\n        }\n        this.view.hasDomSelection = true;\n        // Mark the latest focus change as complete (we got new selection after the focus so the selection is in the focused element).\n        this.focusObserver.flush();\n        if (this.selection.isEqual(newViewSelection) && this.domConverter.isDomSelectionCorrect(domSelection)) {\n            return;\n        }\n        // Ensure we are not in the infinite loop (#400).\n        // This counter is reset each second. 60 selection changes in 1 second is enough high number\n        // to be very difficult (impossible) to achieve using just keyboard keys (during normal editor use).\n        if (++this._loopbackCounter > 60) {\n            // Selection change observer detected an infinite rendering loop.\n            // Most probably you try to put the selection in the position which is not allowed\n            // by the browser and browser fixes it automatically what causes `selectionchange` event on\n            // which a loopback through a model tries to re-render the wrong selection and again.\n            this._reportInfiniteLoop();\n            return;\n        }\n        if (this.selection.isSimilar(newViewSelection)) {\n            // If selection was equal and we are at this point of algorithm, it means that it was incorrect.\n            // Just re-render it, no need to fire any events, etc.\n            this.view.forceRender();\n        } else {\n            const data = {\n                oldSelection: this.selection,\n                newSelection: newViewSelection,\n                domSelection\n            };\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c Fire selection change:',\n            // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', '',\n            // @if CK_DEBUG_TYPING // \t\tnewViewSelection.getFirstRange()\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            // Prepare data for new selection and fire appropriate events.\n            this.document.fire('selectionChange', data);\n            // Call `#_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n            // This function is debounced what means that `selectionChangeDone` event will be fired only when\n            // defined int the function time will elapse since the last time the function was called.\n            // So `selectionChangeDone` will be fired when selection will stop changing.\n            this._fireSelectionChangeDoneDebounced(data);\n        }\n    }\n    /**\n\t * Clears `SelectionObserver` internal properties connected with preventing infinite loop.\n\t */ _clearInfiniteLoop() {\n        this._loopbackCounter = 0;\n    }\n}\n\n// @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );\n/**\n * {@link module:engine/view/document~Document#event:compositionstart Compositionstart},\n * {@link module:engine/view/document~Document#event:compositionupdate compositionupdate} and\n * {@link module:engine/view/document~Document#event:compositionend compositionend} events observer.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */ class CompositionObserver extends DomEventObserver {\n    /**\n\t * @inheritDoc\n\t */ domEventType = [\n        'compositionstart',\n        'compositionupdate',\n        'compositionend'\n    ];\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        const document = this.document;\n        document.on('compositionstart', ()=>{\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.log( '%c[CompositionObserver] ' +\n            // @if CK_DEBUG_TYPING // \t\t'┌───────────────────────────── isComposing = true ─────────────────────────────┐',\n            // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green'\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            document.isComposing = true;\n        }, {\n            priority: 'low'\n        });\n        document.on('compositionend', ()=>{\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.log( '%c[CompositionObserver] ' +\n            // @if CK_DEBUG_TYPING // \t\t'└───────────────────────────── isComposing = false ─────────────────────────────┘',\n            // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green'\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            document.isComposing = false;\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvent) {\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \t_debouncedLine();\n        // @if CK_DEBUG_TYPING // \tconsole.group( `%c[CompositionObserver]%c ${ domEvent.type }`, 'color: green', '' );\n        // @if CK_DEBUG_TYPING // }\n        this.fire(domEvent.type, domEvent, {\n            data: domEvent.data\n        });\n    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n    // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n    // @if CK_DEBUG_TYPING // }\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module engine/view/datatransfer\n */ /**\n * A facade over the native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n */ class DataTransfer {\n    /**\n\t * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t */ _files;\n    /**\n\t * The native DataTransfer object.\n\t */ _native;\n    /**\n\t * @param nativeDataTransfer The native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n\t * @param options.cacheFiles Whether `files` list should be initialized in the constructor.\n\t */ constructor(nativeDataTransfer, options = {}){\n        // We should store references to the File instances in case someone would like to process this files\n        // outside the event handler. Files are stored only for `drop` and `paste` events because they are not usable\n        // in other events and are generating a huge delay on Firefox while dragging.\n        // See https://github.com/ckeditor/ckeditor5/issues/13366.\n        this._files = options.cacheFiles ? getFiles(nativeDataTransfer) : null;\n        this._native = nativeDataTransfer;\n    }\n    /**\n\t * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t */ get files() {\n        if (!this._files) {\n            this._files = getFiles(this._native);\n        }\n        return this._files;\n    }\n    /**\n\t * Returns an array of available native content types.\n\t */ get types() {\n        return this._native.types;\n    }\n    /**\n\t * Gets the data from the data transfer by its MIME type.\n\t *\n\t * ```ts\n\t * dataTransfer.getData( 'text/plain' );\n\t * ```\n\t *\n\t * @param type The MIME type. E.g. `text/html` or `text/plain`.\n\t */ getData(type) {\n        return this._native.getData(type);\n    }\n    /**\n\t * Sets the data in the data transfer.\n\t *\n\t * @param type The MIME type. E.g. `text/html` or `text/plain`.\n\t */ setData(type, data) {\n        this._native.setData(type, data);\n    }\n    /**\n\t * The effect that is allowed for a drag operation.\n\t */ set effectAllowed(value) {\n        this._native.effectAllowed = value;\n    }\n    get effectAllowed() {\n        return this._native.effectAllowed;\n    }\n    /**\n\t * The actual drop effect.\n\t */ set dropEffect(value) {\n        this._native.dropEffect = value;\n    }\n    get dropEffect() {\n        return this._native.dropEffect;\n    }\n    /**\n\t * Set a preview image of the dragged content.\n\t */ setDragImage(image, x, y) {\n        this._native.setDragImage(image, x, y);\n    }\n    /**\n\t * Whether the dragging operation was canceled.\n\t */ get isCanceled() {\n        return this._native.dropEffect == 'none' || !!this._native.mozUserCancelled;\n    }\n}\nfunction getFiles(nativeDataTransfer) {\n    // DataTransfer.files and items are array-like and might not have an iterable interface.\n    const files = Array.from(nativeDataTransfer.files || []);\n    const items = Array.from(nativeDataTransfer.items || []);\n    if (files.length) {\n        return files;\n    }\n    // Chrome has empty DataTransfer.files, but allows getting files through the items interface.\n    return items.filter((item)=>item.kind === 'file').map((item)=>item.getAsFile());\n}\n\n// @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );\n/**\n * Observer for events connected with data input.\n *\n * **Note**: This observer is attached by {@link module:engine/view/view~View} and available by default in all\n * editor instances.\n */ class InputObserver extends DomEventObserver {\n    /**\n\t * @inheritDoc\n\t */ domEventType = 'beforeinput';\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvent) {\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \t_debouncedLine();\n        // @if CK_DEBUG_TYPING // \tconsole.group( `%c[InputObserver]%c ${ domEvent.type }: ${ domEvent.inputType }`,\n        // @if CK_DEBUG_TYPING // \t\t'color: green', 'color: default'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        const domTargetRanges = domEvent.getTargetRanges();\n        const view = this.view;\n        const viewDocument = view.document;\n        let dataTransfer = null;\n        let data = null;\n        let targetRanges = [];\n        if (domEvent.dataTransfer) {\n            dataTransfer = new DataTransfer(domEvent.dataTransfer);\n        }\n        if (domEvent.data !== null) {\n            data = domEvent.data;\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( `%c[InputObserver]%c event data: %c${ JSON.stringify( data ) }`,\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', 'color: blue;'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        } else if (dataTransfer) {\n            data = dataTransfer.getData('text/plain');\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( `%c[InputObserver]%c event data transfer: %c${ JSON.stringify( data ) }`,\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', 'color: blue;'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        }\n        // If the editor selection is fake (an object is selected), the DOM range does not make sense because it is anchored\n        // in the fake selection container.\n        if (viewDocument.selection.isFake) {\n            // Future-proof: in case of multi-range fake selections being possible.\n            targetRanges = Array.from(viewDocument.selection.getRanges());\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( '%c[InputObserver]%c using fake selection:',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', targetRanges,\n        // @if CK_DEBUG_TYPING // \t\tviewDocument.selection.isFake ? 'fake view selection' : 'fake DOM parent'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        } else if (domTargetRanges.length) {\n            targetRanges = domTargetRanges.map((domRange)=>{\n                // Sometimes browser provides range that starts before editable node.\n                // We try to fall back to collapsed range at the valid end position.\n                // See https://github.com/ckeditor/ckeditor5/issues/14411.\n                // See https://github.com/ckeditor/ckeditor5/issues/14050.\n                const viewStart = view.domConverter.domPositionToView(domRange.startContainer, domRange.startOffset);\n                const viewEnd = view.domConverter.domPositionToView(domRange.endContainer, domRange.endOffset);\n                if (viewStart) {\n                    return view.createRange(viewStart, viewEnd);\n                } else if (viewEnd) {\n                    return view.createRange(viewEnd);\n                }\n            }).filter((range)=>!!range);\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( '%c[InputObserver]%c using target ranges:',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', targetRanges\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        } else if (env.isAndroid) {\n            const domSelection = domEvent.target.ownerDocument.defaultView.getSelection();\n            targetRanges = Array.from(view.domConverter.domSelectionToView(domSelection).getRanges());\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( '%c[InputObserver]%c using selection ranges:',\n        // @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', targetRanges\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        }\n        // Android sometimes fires insertCompositionText with a new-line character at the end of the data\n        // instead of firing insertParagraph beforeInput event.\n        // Fire the correct type of beforeInput event and ignore the replaced fragment of text because\n        // it wants to replace \"test\" with \"test\\n\".\n        // https://github.com/ckeditor/ckeditor5/issues/12368.\n        if (env.isAndroid && domEvent.inputType == 'insertCompositionText' && data && data.endsWith('\\n')) {\n            this.fire(domEvent.type, domEvent, {\n                inputType: 'insertParagraph',\n                targetRanges: [\n                    view.createRange(targetRanges[0].end)\n                ]\n            });\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n            // @if CK_DEBUG_TYPING // }\n            return;\n        }\n        // Normalize the insertText data that includes new-line characters.\n        // https://github.com/ckeditor/ckeditor5/issues/2045.\n        if (domEvent.inputType == 'insertText' && data && data.includes('\\n')) {\n            // There might be a single new-line or double for new paragraph, but we translate\n            // it to paragraphs as it is our default action for enter handling.\n            const parts = data.split(/\\n{1,2}/g);\n            let partTargetRanges = targetRanges;\n            for(let i = 0; i < parts.length; i++){\n                const dataPart = parts[i];\n                if (dataPart != '') {\n                    this.fire(domEvent.type, domEvent, {\n                        data: dataPart,\n                        dataTransfer,\n                        targetRanges: partTargetRanges,\n                        inputType: domEvent.inputType,\n                        isComposing: domEvent.isComposing\n                    });\n                    // Use the result view selection so following events will be added one after another.\n                    partTargetRanges = [\n                        viewDocument.selection.getFirstRange()\n                    ];\n                }\n                if (i + 1 < parts.length) {\n                    this.fire(domEvent.type, domEvent, {\n                        inputType: 'insertParagraph',\n                        targetRanges: partTargetRanges\n                    });\n                    // Use the result view selection so following events will be added one after another.\n                    partTargetRanges = [\n                        viewDocument.selection.getFirstRange()\n                    ];\n                }\n            }\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n            // @if CK_DEBUG_TYPING // }\n            return;\n        }\n        // Fire the normalized beforeInput event.\n        this.fire(domEvent.type, domEvent, {\n            data,\n            dataTransfer,\n            targetRanges,\n            inputType: domEvent.inputType,\n            isComposing: domEvent.isComposing\n        });\n    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n    // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n    // @if CK_DEBUG_TYPING // }\n    }\n}\n\n/**\n * Arrow keys observer introduces the {@link module:engine/view/document~Document#event:arrowKey `Document#arrowKey`} event.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */ class ArrowKeysObserver extends Observer {\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        this.document.on('keydown', (event, data)=>{\n            if (this.isEnabled && isArrowKeyCode(data.keyCode)) {\n                const eventInfo = new BubblingEventInfo(this.document, 'arrowKey', this.document.selection.getFirstRange());\n                this.document.fire(eventInfo, data);\n                if (eventInfo.stop.called) {\n                    event.stop();\n                }\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ observe() {}\n    /**\n\t * @inheritDoc\n\t */ stopObserving() {}\n}\n\n/**\n * Tab observer introduces the {@link module:engine/view/document~Document#event:tab `Document#tab`} event.\n *\n * Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the\n * {@link module:engine/view/view~View}, this event is available by default.\n */ class TabObserver extends Observer {\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        const doc = this.document;\n        doc.on('keydown', (evt, data)=>{\n            if (!this.isEnabled || data.keyCode != keyCodes.tab || data.ctrlKey) {\n                return;\n            }\n            const event = new BubblingEventInfo(doc, 'tab', doc.selection.getFirstRange());\n            doc.fire(event, data);\n            if (event.stop.called) {\n                evt.stop();\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ observe() {}\n    /**\n\t * @inheritDoc\n\t */ stopObserving() {}\n}\n\n/**\n * Editor's view controller class. Its main responsibility is DOM - View management for editing purposes, to provide\n * abstraction over the DOM structure and events and hide all browsers quirks.\n *\n * View controller renders view document to DOM whenever view structure changes. To determine when view can be rendered,\n * all changes need to be done using the {@link module:engine/view/view~View#change} method, using\n * {@link module:engine/view/downcastwriter~DowncastWriter}:\n *\n * ```ts\n * view.change( writer => {\n * \twriter.insert( position, writer.createText( 'foo' ) );\n * } );\n * ```\n *\n * View controller also register {@link module:engine/view/observer/observer~Observer observers} which observes changes\n * on DOM and fire events on the {@link module:engine/view/document~Document Document}.\n * Note that the following observers are added by the class constructor and are always available:\n *\n * * {@link module:engine/view/observer/selectionobserver~SelectionObserver},\n * * {@link module:engine/view/observer/focusobserver~FocusObserver},\n * * {@link module:engine/view/observer/keyobserver~KeyObserver},\n * * {@link module:engine/view/observer/fakeselectionobserver~FakeSelectionObserver}.\n * * {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n * * {@link module:engine/view/observer/inputobserver~InputObserver}.\n * * {@link module:engine/view/observer/arrowkeysobserver~ArrowKeysObserver}.\n * * {@link module:engine/view/observer/tabobserver~TabObserver}.\n *\n * This class also {@link module:engine/view/view~View#attachDomRoot binds the DOM and the view elements}.\n *\n * If you do not need full a DOM - view management, and only want to transform a tree of view elements to a tree of DOM\n * elements you do not need this controller. You can use the {@link module:engine/view/domconverter~DomConverter DomConverter} instead.\n */ class View extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * Instance of the {@link module:engine/view/document~Document} associated with this view controller.\n\t */ document;\n    /**\n\t * Instance of the {@link module:engine/view/domconverter~DomConverter domConverter} used by\n\t * {@link module:engine/view/view~View#_renderer renderer}\n\t * and {@link module:engine/view/observer/observer~Observer observers}.\n\t */ domConverter;\n    /**\n\t * Roots of the DOM tree. Map on the `HTMLElement`s with roots names as keys.\n\t */ domRoots = new Map();\n    /**\n\t * Instance of the {@link module:engine/view/renderer~Renderer renderer}.\n\t */ _renderer;\n    /**\n\t * A DOM root attributes cache. It saves the initial values of DOM root attributes before the DOM element\n\t * is {@link module:engine/view/view~View#attachDomRoot attached} to the view so later on, when\n\t * the view is destroyed ({@link module:engine/view/view~View#detachDomRoot}), they can be easily restored.\n\t * This way, the DOM element can go back to the (clean) state as if the editing view never used it.\n\t */ _initialDomRootAttributes = new WeakMap();\n    /**\n\t * Map of registered {@link module:engine/view/observer/observer~Observer observers}.\n\t */ _observers = new Map();\n    /**\n\t * DowncastWriter instance used in {@link #change change method} callbacks.\n\t */ _writer;\n    /**\n\t * Is set to `true` when {@link #change view changes} are currently in progress.\n\t */ _ongoingChange = false;\n    /**\n\t * Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t */ _postFixersInProgress = false;\n    /**\n\t * Internal flag to temporary disable rendering. See the usage in the {@link #_disableRendering}.\n\t */ _renderingDisabled = false;\n    /**\n\t * Internal flag that disables rendering when there are no changes since the last rendering.\n\t * It stores information about changed selection and changed elements from attached document roots.\n\t */ _hasChangedSinceTheLastRendering = false;\n    /**\n\t * @param stylesProcessor The styles processor instance.\n\t */ constructor(stylesProcessor){\n        super();\n        this.document = new Document$1(stylesProcessor);\n        this.domConverter = new DomConverter(this.document);\n        this.set('isRenderingInProgress', false);\n        this.set('hasDomSelection', false);\n        this._renderer = new Renderer(this.domConverter, this.document.selection);\n        this._renderer.bind('isFocused', 'isSelecting', 'isComposing').to(this.document, 'isFocused', 'isSelecting', 'isComposing');\n        this._writer = new DowncastWriter(this.document);\n        // Add default observers.\n        // Make sure that this list matches AlwaysRegisteredObservers type.\n        this.addObserver(MutationObserver);\n        this.addObserver(FocusObserver);\n        this.addObserver(SelectionObserver);\n        this.addObserver(KeyObserver);\n        this.addObserver(FakeSelectionObserver);\n        this.addObserver(CompositionObserver);\n        this.addObserver(ArrowKeysObserver);\n        this.addObserver(InputObserver);\n        this.addObserver(TabObserver);\n        // Inject quirks handlers.\n        injectQuirksHandling(this);\n        injectUiElementHandling(this);\n        // Use 'normal' priority so that rendering is performed as first when using that priority.\n        this.on('render', ()=>{\n            this._render();\n            // Informs that layout has changed after render.\n            this.document.fire('layoutChanged');\n            // Reset the `_hasChangedSinceTheLastRendering` flag after rendering.\n            this._hasChangedSinceTheLastRendering = false;\n        });\n        // Listen to the document selection changes directly.\n        this.listenTo(this.document.selection, 'change', ()=>{\n            this._hasChangedSinceTheLastRendering = true;\n        });\n        // Trigger re-render if only the focus changed.\n        this.listenTo(this.document, 'change:isFocused', ()=>{\n            this._hasChangedSinceTheLastRendering = true;\n        });\n        // Remove ranges from DOM selection if editor is blurred.\n        // See https://github.com/ckeditor/ckeditor5/issues/5753.\n        if (env.isiOS) {\n            this.listenTo(this.document, 'blur', (evt, data)=>{\n                const relatedViewElement = this.domConverter.mapDomToView(data.domEvent.relatedTarget);\n                // Do not modify DOM selection if focus is moved to other editable of the same editor.\n                if (!relatedViewElement) {\n                    this.domConverter._clearDomSelection();\n                }\n            });\n        }\n        // Listen to external content mutations (directly in the DOM) and mark them to get verified by the renderer.\n        this.listenTo(this.document, 'mutations', (evt, { mutations })=>{\n            mutations.forEach((mutation)=>this._renderer.markToSync(mutation.type, mutation.node));\n        }, {\n            priority: 'low'\n        });\n        // After all mutated nodes were marked to sync we can trigger view to DOM synchronization\n        // to make sure the DOM structure matches the view.\n        this.listenTo(this.document, 'mutations', ()=>{\n            this.forceRender();\n        }, {\n            priority: 'lowest'\n        });\n    }\n    /**\n\t * Attaches a DOM root element to the view element and enable all observers on that element.\n\t * Also {@link module:engine/view/renderer~Renderer#markToSync mark element} to be synchronized\n\t * with the view what means that all child nodes will be removed and replaced with content of the view root.\n\t *\n\t * This method also will change view element name as the same as tag name of given dom root.\n\t * Name is always transformed to lower case.\n\t *\n\t * **Note:** Use {@link #detachDomRoot `detachDomRoot()`} to revert this action.\n\t *\n\t * @param domRoot DOM root element.\n\t * @param name Name of the root.\n\t */ attachDomRoot(domRoot, name = 'main') {\n        const viewRoot = this.document.getRoot(name);\n        // Set view root name the same as DOM root tag name.\n        viewRoot._name = domRoot.tagName.toLowerCase();\n        const initialDomRootAttributes = {};\n        // 1. Copy and cache the attributes to remember the state of the element before attaching.\n        //    The cached attributes will be restored in detachDomRoot() so the element goes to the\n        //    clean state as if the editing view never used it.\n        // 2. Apply the attributes using the view writer, so they all go under the control of the engine.\n        //    The editing view takes over the attribute management completely because various\n        //    features (e.g. addPlaceholder()) require dynamic changes of those attributes and they\n        //    cannot be managed by the engine and the UI library at the same time.\n        for (const { name, value } of Array.from(domRoot.attributes)){\n            initialDomRootAttributes[name] = value;\n            // Do not use writer.setAttribute() for the class attribute. The EditableUIView class\n            // and its descendants could have already set some using the writer.addClass() on the view\n            // document root. They haven't been rendered yet so they are not present in the DOM root.\n            // Using writer.setAttribute( 'class', ... ) would override them completely.\n            if (name === 'class') {\n                this._writer.addClass(value.split(' '), viewRoot);\n            } else {\n                // There is a chance that some attributes have already been set on the view root before attaching\n                // the DOM root and should be preserved. This is a similar case to the \"class\" attribute except\n                // this time there is no workaround using a some low-level API.\n                if (!viewRoot.hasAttribute(name)) {\n                    this._writer.setAttribute(name, value, viewRoot);\n                }\n            }\n        }\n        this._initialDomRootAttributes.set(domRoot, initialDomRootAttributes);\n        const updateContenteditableAttribute = ()=>{\n            this._writer.setAttribute('contenteditable', (!viewRoot.isReadOnly).toString(), viewRoot);\n            if (viewRoot.isReadOnly) {\n                this._writer.addClass('ck-read-only', viewRoot);\n            } else {\n                this._writer.removeClass('ck-read-only', viewRoot);\n            }\n        };\n        // Set initial value.\n        updateContenteditableAttribute();\n        this.domRoots.set(name, domRoot);\n        this.domConverter.bindElements(domRoot, viewRoot);\n        this._renderer.markToSync('children', viewRoot);\n        this._renderer.markToSync('attributes', viewRoot);\n        this._renderer.domDocuments.add(domRoot.ownerDocument);\n        viewRoot.on('change:children', (evt, node)=>this._renderer.markToSync('children', node));\n        viewRoot.on('change:attributes', (evt, node)=>this._renderer.markToSync('attributes', node));\n        viewRoot.on('change:text', (evt, node)=>this._renderer.markToSync('text', node));\n        viewRoot.on('change:isReadOnly', ()=>this.change(updateContenteditableAttribute));\n        viewRoot.on('change', ()=>{\n            this._hasChangedSinceTheLastRendering = true;\n        });\n        for (const observer of this._observers.values()){\n            observer.observe(domRoot, name);\n        }\n    }\n    /**\n\t * Detaches a DOM root element from the view element and restores its attributes to the state before\n\t * {@link #attachDomRoot `attachDomRoot()`}.\n\t *\n\t * @param name Name of the root to detach.\n\t */ detachDomRoot(name) {\n        const domRoot = this.domRoots.get(name);\n        // Remove all root attributes so the DOM element is \"bare\".\n        Array.from(domRoot.attributes).forEach(({ name })=>domRoot.removeAttribute(name));\n        const initialDomRootAttributes = this._initialDomRootAttributes.get(domRoot);\n        // Revert all view root attributes back to the state before attachDomRoot was called.\n        for(const attribute in initialDomRootAttributes){\n            domRoot.setAttribute(attribute, initialDomRootAttributes[attribute]);\n        }\n        this.domRoots.delete(name);\n        this.domConverter.unbindDomElement(domRoot);\n        for (const observer of this._observers.values()){\n            observer.stopObserving(domRoot);\n        }\n    }\n    /**\n\t * Gets DOM root element.\n\t *\n\t * @param name  Name of the root.\n\t * @returns DOM root element instance.\n\t */ getDomRoot(name = 'main') {\n        return this.domRoots.get(name);\n    }\n    /**\n\t * Creates observer of the given type if not yet created, {@link module:engine/view/observer/observer~Observer#enable enables} it\n\t * and {@link module:engine/view/observer/observer~Observer#observe attaches} to all existing and future\n\t * {@link #domRoots DOM roots}.\n\t *\n\t * Note: Observers are recognized by their constructor (classes). A single observer will be instantiated and used only\n\t * when registered for the first time. This means that features and other components can register a single observer\n\t * multiple times without caring whether it has been already added or not.\n\t *\n\t * @param ObserverConstructor The constructor of an observer to add.\n\t * Should create an instance inheriting from {@link module:engine/view/observer/observer~Observer}.\n\t * @returns Added observer instance.\n\t */ addObserver(ObserverConstructor) {\n        let observer = this._observers.get(ObserverConstructor);\n        if (observer) {\n            return observer;\n        }\n        observer = new ObserverConstructor(this);\n        this._observers.set(ObserverConstructor, observer);\n        for (const [name, domElement] of this.domRoots){\n            observer.observe(domElement, name);\n        }\n        observer.enable();\n        return observer;\n    }\n    /**\n\t * Returns observer of the given type or `undefined` if such observer has not been added yet.\n\t *\n\t * @param ObserverConstructor The constructor of an observer to get.\n\t * @returns Observer instance or undefined.\n\t */ getObserver(ObserverConstructor) {\n        return this._observers.get(ObserverConstructor);\n    }\n    /**\n\t * Disables all added observers.\n\t */ disableObservers() {\n        for (const observer of this._observers.values()){\n            observer.disable();\n        }\n    }\n    /**\n\t * Enables all added observers.\n\t */ enableObservers() {\n        for (const observer of this._observers.values()){\n            observer.enable();\n        }\n    }\n    /**\n\t * Scrolls the page viewport and {@link #domRoots} with their ancestors to reveal the\n\t * caret, **if not already visible to the user**.\n\t *\n\t * **Note**: Calling this method fires the {@link module:engine/view/view~ViewScrollToTheSelectionEvent} event that\n\t * allows custom behaviors.\n\t *\n\t * @param options Additional configuration of the scrolling behavior.\n\t * @param options.viewportOffset A distance between the DOM selection and the viewport boundary to be maintained\n\t * while scrolling to the selection (default is 20px). Setting this value to `0` will reveal the selection precisely at\n\t * the viewport boundary.\n\t * @param options.ancestorOffset A distance between the DOM selection and scrollable DOM root ancestor(s) to be maintained\n\t * while scrolling to the selection (default is 20px). Setting this value to `0` will reveal the selection precisely at\n\t * the scrollable ancestor(s) boundary.\n\t * @param options.alignToTop When set `true`, the DOM selection will be aligned to the top of the viewport if not already visible\n\t * (see `forceScroll` to learn more).\n\t * @param options.forceScroll When set `true`, the DOM selection will be aligned to the top of the viewport and scrollable ancestors\n\t * whether it is already visible or not. This option will only work when `alignToTop` is `true`.\n\t */ scrollToTheSelection({ alignToTop, forceScroll, viewportOffset = 20, ancestorOffset = 20 } = {}) {\n        const range = this.document.selection.getFirstRange();\n        if (!range) {\n            return;\n        }\n        // Clone to make sure properties like `viewportOffset` are not mutated in the event listeners.\n        const originalArgs = cloneDeep({\n            alignToTop,\n            forceScroll,\n            viewportOffset,\n            ancestorOffset\n        });\n        if (typeof viewportOffset === 'number') {\n            viewportOffset = {\n                top: viewportOffset,\n                bottom: viewportOffset,\n                left: viewportOffset,\n                right: viewportOffset\n            };\n        }\n        const options = {\n            target: this.domConverter.viewRangeToDom(range),\n            viewportOffset,\n            ancestorOffset,\n            alignToTop,\n            forceScroll\n        };\n        this.fire('scrollToTheSelection', options, originalArgs);\n        scrollViewportToShowTarget(options);\n    }\n    /**\n\t * It will focus DOM element representing {@link module:engine/view/editableelement~EditableElement EditableElement}\n\t * that is currently having selection inside.\n\t */ focus() {\n        if (!this.document.isFocused) {\n            const editable = this.document.selection.editableElement;\n            if (editable) {\n                this.domConverter.focus(editable);\n                this.forceRender();\n            }\n        }\n    }\n    /**\n\t * The `change()` method is the primary way of changing the view. You should use it to modify any node in the view tree.\n\t * It makes sure that after all changes are made the view is rendered to the DOM (assuming that the view will be changed\n\t * inside the callback). It prevents situations when the DOM is updated when the view state is not yet correct. It allows\n\t * to nest calls one inside another and still performs a single rendering after all those changes are made.\n\t * It also returns the return value of its callback.\n\t *\n\t * ```ts\n\t * const text = view.change( writer => {\n\t * \tconst newText = writer.createText( 'foo' );\n\t * \twriter.insert( position1, newText );\n\t *\n\t * \tview.change( writer => {\n\t * \t\twriter.insert( position2, writer.createText( 'bar' ) );\n\t * \t} );\n\t *\n\t * \twriter.remove( range );\n\t *\n\t * \treturn newText;\n\t * } );\n\t * ```\n\t *\n\t * When the outermost change block is done and rendering to the DOM is over the\n\t * {@link module:engine/view/view~View#event:render `View#render`} event is fired.\n\t *\n\t * This method throws a `applying-view-changes-on-rendering` error when\n\t * the change block is used after rendering to the DOM has started.\n\t *\n\t * @param callback Callback function which may modify the view.\n\t * @returns Value returned by the callback.\n\t */ change(callback) {\n        if (this.isRenderingInProgress || this._postFixersInProgress) {\n            /**\n\t\t\t * Thrown when there is an attempt to make changes to the view tree when it is in incorrect state. This may\n\t\t\t * cause some unexpected behaviour and inconsistency between the DOM and the view.\n\t\t\t * This may be caused by:\n\t\t\t *\n\t\t\t * * calling {@link module:engine/view/view~View#change} or {@link module:engine/view/view~View#forceRender} during rendering\n\t\t\t * process,\n\t\t\t * * calling {@link module:engine/view/view~View#change} or {@link module:engine/view/view~View#forceRender} inside of\n\t\t\t *   {@link module:engine/view/document~Document#registerPostFixer post-fixer function}.\n\t\t\t *\n\t\t\t * @error cannot-change-view-tree\n\t\t\t */ throw new CKEditorError('cannot-change-view-tree', this);\n        }\n        try {\n            // Recursive call to view.change() method - execute listener immediately.\n            if (this._ongoingChange) {\n                return callback(this._writer);\n            }\n            // This lock will assure that all recursive calls to view.change() will end up in same block - one \"render\"\n            // event for all nested calls.\n            this._ongoingChange = true;\n            const callbackResult = callback(this._writer);\n            this._ongoingChange = false;\n            // This lock is used by editing controller to render changes from outer most model.change() once. As plugins might call\n            // view.change() inside model.change() block - this will ensures that postfixers and rendering are called once after all\n            // changes. Also, we don't need to render anything if there're no changes since last rendering.\n            if (!this._renderingDisabled && this._hasChangedSinceTheLastRendering) {\n                this._postFixersInProgress = true;\n                this.document._callPostFixers(this._writer);\n                this._postFixersInProgress = false;\n                this.fire('render');\n            }\n            return callbackResult;\n        } catch (err) {\n            // @if CK_DEBUG // throw err;\n            /* istanbul ignore next -- @preserve */ CKEditorError.rethrowUnexpectedError(err, this);\n        }\n    }\n    /**\n\t * Forces rendering {@link module:engine/view/document~Document view document} to DOM. If any view changes are\n\t * currently in progress, rendering will start after all {@link #change change blocks} are processed.\n\t *\n\t * Note that this method is dedicated for special cases. All view changes should be wrapped in the {@link #change}\n\t * block and the view will automatically check whether it needs to render DOM or not.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `applying-view-changes-on-rendering` when\n\t * trying to re-render when rendering to DOM has already started.\n\t */ forceRender() {\n        this._hasChangedSinceTheLastRendering = true;\n        this.getObserver(FocusObserver).flush();\n        this.change(()=>{});\n    }\n    /**\n\t * Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t */ destroy() {\n        for (const observer of this._observers.values()){\n            observer.destroy();\n        }\n        this.document.destroy();\n        this.stopListening();\n    }\n    /**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */ createPositionAt(itemOrPosition, offset) {\n        return Position$1._createAt(itemOrPosition, offset);\n    }\n    /**\n\t * Creates a new position after given view item.\n\t *\n\t * @param item View item after which the position should be located.\n\t */ createPositionAfter(item) {\n        return Position$1._createAfter(item);\n    }\n    /**\n\t * Creates a new position before given view item.\n\t *\n\t * @param item View item before which the position should be located.\n\t */ createPositionBefore(item) {\n        return Position$1._createBefore(item);\n    }\n    /**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */ createRange(start, end) {\n        return new Range$1(start, end);\n    }\n    /**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t */ createRangeOn(item) {\n        return Range$1._createOn(item);\n    }\n    /**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */ createRangeIn(element) {\n        return Range$1._createIn(element);\n    }\n    createSelection(...args) {\n        return new Selection$1(...args);\n    }\n    /**\n\t * Disables or enables rendering. If the flag is set to `true` then the rendering will be disabled.\n\t * If the flag is set to `false` and if there was some change in the meantime, then the rendering action will be performed.\n\t *\n\t * @internal\n\t * @param flag A flag indicates whether the rendering should be disabled.\n\t */ _disableRendering(flag) {\n        this._renderingDisabled = flag;\n        if (flag == false) {\n            // Render when you stop blocking rendering.\n            this.change(()=>{});\n        }\n    }\n    /**\n\t * Renders all changes. In order to avoid triggering the observers (e.g. selection) all observers are disabled\n\t * before rendering and re-enabled after that.\n\t */ _render() {\n        this.isRenderingInProgress = true;\n        this.disableObservers();\n        this._renderer.render();\n        this.enableObservers();\n        this.isRenderingInProgress = false;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module engine/model/typecheckable\n */ class TypeCheckable {\n    /* istanbul ignore next -- @preserve */ is() {\n        // There are a lot of overloads above.\n        // Overriding method in derived classes remove them and only `is( type: string ): boolean` is visible which we don't want.\n        // One option would be to copy them all to all classes, but that's ugly.\n        // It's best when TypeScript compiler doesn't see those overloads, except the one in the top base class.\n        // To overload a method, but not let the compiler see it, do after class definition:\n        // `MyClass.prototype.is = function( type: string ) {...}`\n        throw new Error('is() method is abstract');\n    }\n}\n\n/**\n * Model node. Most basic structure of model tree.\n *\n * This is an abstract class that is a base for other classes representing different nodes in model.\n *\n * **Note:** If a node is detached from the model tree, you can manipulate it using it's API.\n * However, it is **very important** that nodes already attached to model tree should be only changed through\n * {@link module:engine/model/writer~Writer Writer API}.\n *\n * Changes done by `Node` methods, like {@link module:engine/model/element~Element#_insertChild _insertChild} or\n * {@link module:engine/model/node~Node#_setAttribute _setAttribute}\n * do not generate {@link module:engine/model/operation/operation~Operation operations}\n * which are essential for correct editor work if you modify nodes in {@link module:engine/model/document~Document document} root.\n *\n * The flow of working on `Node` (and classes that inherits from it) is as such:\n * 1. You can create a `Node` instance, modify it using it's API.\n * 2. Add `Node` to the model using `Batch` API.\n * 3. Change `Node` that was already added to the model using `Batch` API.\n *\n * Similarly, you cannot use `Batch` API on a node that has not been added to the model tree, with the exception\n * of {@link module:engine/model/writer~Writer#insert inserting} that node to the model tree.\n *\n * Be aware that using {@link module:engine/model/writer~Writer#remove remove from Batch API} does not allow to use `Node` API because\n * the information about `Node` is still kept in model document.\n *\n * In case of {@link module:engine/model/element~Element element node}, adding and removing children also counts as changing a node and\n * follows same rules.\n */ let Node$1 = class Node extends TypeCheckable {\n    /**\n\t * Parent of this node. It could be {@link module:engine/model/element~Element}\n\t * or {@link module:engine/model/documentfragment~DocumentFragment}.\n\t * Equals to `null` if the node has no parent.\n\t */ parent = null;\n    /**\n\t * Attributes set on this node.\n\t */ _attrs;\n    /**\n\t * Index of this node in its parent or `null` if the node has no parent.\n\t *\n\t * @internal\n\t */ _index = null;\n    /**\n\t * Offset at which this node starts in its parent or `null` if the node has no parent.\n\t *\n\t * @internal\n\t */ _startOffset = null;\n    /**\n\t * Creates a model node.\n\t *\n\t * This is an abstract class, so this constructor should not be used directly.\n\t *\n\t * @param attrs Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */ constructor(attrs){\n        super();\n        this._attrs = toMap(attrs);\n    }\n    /**\n\t * {@link module:engine/model/document~Document Document} that owns this root element.\n\t */ get document() {\n        return null;\n    }\n    /**\n\t * Index of this node in its parent or `null` if the node has no parent.\n\t */ get index() {\n        return this._index;\n    }\n    /**\n\t * Offset at which this node starts in its parent. It is equal to the sum of {@link #offsetSize offsetSize}\n\t * of all its previous siblings. Equals to `null` if node has no parent.\n\t */ get startOffset() {\n        return this._startOffset;\n    }\n    /**\n\t * Offset size of this node.\n\t *\n\t * Represents how much \"offset space\" is occupied by the node in its parent. It is important for\n\t * {@link module:engine/model/position~Position position}. When node has `offsetSize` greater than `1`, position can be placed between\n\t * that node start and end. `offsetSize` greater than `1` is for nodes that represents more than one entity, i.e.\n\t * a {@link module:engine/model/text~Text text node}.\n\t */ get offsetSize() {\n        return 1;\n    }\n    /**\n\t * Offset at which this node ends in its parent. It is equal to the sum of this node's\n\t * {@link module:engine/model/node~Node#startOffset start offset} and {@link #offsetSize offset size}.\n\t * Equals to `null` if the node has no parent.\n\t */ get endOffset() {\n        if (this.startOffset === null) {\n            return null;\n        }\n        return this.startOffset + this.offsetSize;\n    }\n    /**\n\t * Node's next sibling or `null` if the node is a last child of it's parent or if the node has no parent.\n\t */ get nextSibling() {\n        const index = this.index;\n        return index !== null && this.parent.getChild(index + 1) || null;\n    }\n    /**\n\t * Node's previous sibling or `null` if the node is a first child of it's parent or if the node has no parent.\n\t */ get previousSibling() {\n        const index = this.index;\n        return index !== null && this.parent.getChild(index - 1) || null;\n    }\n    /**\n\t * The top-most ancestor of the node. If node has no parent it is the root itself. If the node is a part\n\t * of {@link module:engine/model/documentfragment~DocumentFragment}, it's `root` is equal to that `DocumentFragment`.\n\t */ get root() {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n        let root = this;\n        while(root.parent){\n            root = root.parent;\n        }\n        return root;\n    }\n    /**\n\t * Returns `true` if the node is inside a document root that is attached to the document.\n\t */ isAttached() {\n        // If the node has no parent it means that it is a root.\n        // But this is not a `RootElement`, so it means that it is not attached.\n        //\n        // If this is not the root, check if this element's root is attached.\n        return this.parent === null ? false : this.root.isAttached();\n    }\n    /**\n\t * Gets path to the node. The path is an array containing starting offsets of consecutive ancestors of this node,\n\t * beginning from {@link module:engine/model/node~Node#root root}, down to this node's starting offset. The path can be used to\n\t * create {@link module:engine/model/position~Position Position} instance.\n\t *\n\t * ```ts\n\t * const abc = new Text( 'abc' );\n\t * const foo = new Text( 'foo' );\n\t * const h1 = new Element( 'h1', null, new Text( 'header' ) );\n\t * const p = new Element( 'p', null, [ abc, foo ] );\n\t * const div = new Element( 'div', null, [ h1, p ] );\n\t * foo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t * h1.getPath(); // Returns [ 0 ].\n\t * div.getPath(); // Returns [].\n\t * ```\n\t */ getPath() {\n        const path = [];\n        // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n        let node = this;\n        while(node.parent){\n            path.unshift(node.startOffset);\n            node = node.parent;\n        }\n        return path;\n    }\n    /**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this node will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from node's parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */ getAncestors(options = {}) {\n        const ancestors = [];\n        let parent = options.includeSelf ? this : this.parent;\n        while(parent){\n            ancestors[options.parentFirst ? 'push' : 'unshift'](parent);\n            parent = parent.parent;\n        }\n        return ancestors;\n    }\n    /**\n\t * Returns a {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param node The second node.\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` both nodes will be considered \"ancestors\" too.\n\t * Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t */ getCommonAncestor(node, options = {}) {\n        const ancestorsA = this.getAncestors(options);\n        const ancestorsB = node.getAncestors(options);\n        let i = 0;\n        while(ancestorsA[i] == ancestorsB[i] && ancestorsA[i]){\n            i++;\n        }\n        return i === 0 ? null : ancestorsA[i - 1];\n    }\n    /**\n\t * Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/model/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */ isBefore(node) {\n        // Given node is not before this node if they are same.\n        if (this == node) {\n            return false;\n        }\n        // Return `false` if it is impossible to compare nodes.\n        if (this.root !== node.root) {\n            return false;\n        }\n        const thisPath = this.getPath();\n        const nodePath = node.getPath();\n        const result = compareArrays(thisPath, nodePath);\n        switch(result){\n            case 'prefix':\n                return true;\n            case 'extension':\n                return false;\n            default:\n                return thisPath[result] < nodePath[result];\n        }\n    }\n    /**\n\t * Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/model/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */ isAfter(node) {\n        // Given node is not before this node if they are same.\n        if (this == node) {\n            return false;\n        }\n        // Return `false` if it is impossible to compare nodes.\n        if (this.root !== node.root) {\n            return false;\n        }\n        // In other cases, just check if the `node` is before, and return the opposite.\n        return !this.isBefore(node);\n    }\n    /**\n\t * Checks if the node has an attribute with given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on node, `false` otherwise.\n\t */ hasAttribute(key) {\n        return this._attrs.has(key);\n    }\n    /**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on node.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */ getAttribute(key) {\n        return this._attrs.get(key);\n    }\n    /**\n\t * Returns iterator that iterates over this node's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */ getAttributes() {\n        return this._attrs.entries();\n    }\n    /**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t */ getAttributeKeys() {\n        return this._attrs.keys();\n    }\n    /**\n\t * Converts `Node` to plain object and returns it.\n\t *\n\t * @returns `Node` converted to plain object.\n\t */ toJSON() {\n        const json = {};\n        // Serializes attributes to the object.\n        // attributes = { a: 'foo', b: 1, c: true }.\n        if (this._attrs.size) {\n            json.attributes = Array.from(this._attrs).reduce((result, attr)=>{\n                result[attr[0]] = attr[1];\n                return result;\n            }, {});\n        }\n        return json;\n    }\n    /**\n\t * Creates a copy of this node, that is a node with exactly same attributes, and returns it.\n\t *\n\t * @internal\n\t * @returns Node with same attributes as this node.\n\t */ _clone(_deep) {\n        return new this.constructor(this._attrs);\n    }\n    /**\n\t * Removes this node from its parent.\n\t *\n\t * @internal\n\t * @see module:engine/model/writer~Writer#remove\n\t */ _remove() {\n        this.parent._removeChildren(this.index);\n    }\n    /**\n\t * Sets attribute on the node. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * @see module:engine/model/writer~Writer#setAttribute\n\t * @internal\n\t * @param key Key of attribute to set.\n\t * @param value Attribute value.\n\t */ _setAttribute(key, value) {\n        this._attrs.set(key, value);\n    }\n    /**\n\t * Removes all attributes from the node and sets given attributes.\n\t *\n\t * @see module:engine/model/writer~Writer#setAttributes\n\t * @internal\n\t * @param attrs Attributes to set. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */ _setAttributesTo(attrs) {\n        this._attrs = toMap(attrs);\n    }\n    /**\n\t * Removes an attribute with given key from the node.\n\t *\n\t * @see module:engine/model/writer~Writer#removeAttribute\n\t * @internal\n\t * @param key Key of attribute to remove.\n\t * @returns `true` if the attribute was set on the element, `false` otherwise.\n\t */ _removeAttribute(key) {\n        return this._attrs.delete(key);\n    }\n    /**\n\t * Removes all attributes from the node.\n\t *\n\t * @see module:engine/model/writer~Writer#clearAttributes\n\t * @internal\n\t */ _clearAttributes() {\n        this._attrs.clear();\n    }\n};\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nNode$1.prototype.is = function(type) {\n    return type === 'node' || type === 'model:node';\n};\n\n/**\n * Provides an interface to operate on a list of {@link module:engine/model/node~Node nodes}. `NodeList` is used internally\n * in classes like {@link module:engine/model/element~Element Element}\n * or {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n */ class NodeList {\n    /**\n\t * Nodes contained in this node list.\n\t */ _nodes = [];\n    /**\n\t * This array maps numbers (offsets) to node that is placed at that offset.\n\t *\n\t * This array is similar to `_nodes` with the difference that one node may occupy multiple consecutive items in the array.\n\t *\n\t * This array is needed to quickly retrieve a node that is placed at given offset.\n\t */ _offsetToNode = [];\n    /**\n\t * Creates a node list.\n\t *\n\t * @internal\n\t * @param nodes Nodes contained in this node list.\n\t */ constructor(nodes){\n        if (nodes) {\n            this._insertNodes(0, nodes);\n        }\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * Iterates over all nodes contained inside this node list.\n\t */ [Symbol.iterator]() {\n        return this._nodes[Symbol.iterator]();\n    }\n    /**\n\t * Number of nodes contained inside this node list.\n\t */ get length() {\n        return this._nodes.length;\n    }\n    /**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all nodes contained inside this node list.\n\t */ get maxOffset() {\n        return this._offsetToNode.length;\n    }\n    /**\n\t * Gets the node at the given index. Returns `null` if incorrect index was passed.\n\t */ getNode(index) {\n        return this._nodes[index] || null;\n    }\n    /**\n\t * Gets the node at the given offset. Returns `null` if incorrect offset was passed.\n\t */ getNodeAtOffset(offset) {\n        return this._offsetToNode[offset] || null;\n    }\n    /**\n\t * Returns an index of the given node or `null` if given node does not have a parent.\n\t *\n\t * This is an alias to {@link module:engine/model/node~Node#index}.\n\t */ getNodeIndex(node) {\n        return node.index;\n    }\n    /**\n\t * Returns the offset at which given node is placed in its parent or `null` if given node does not have a parent.\n\t *\n\t * This is an alias to {@link module:engine/model/node~Node#startOffset}.\n\t */ getNodeStartOffset(node) {\n        return node.startOffset;\n    }\n    /**\n\t * Converts index to offset in node list.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `model-nodelist-index-out-of-bounds` if given index is less\n\t * than `0` or more than {@link #length}.\n\t */ indexToOffset(index) {\n        if (index == this._nodes.length) {\n            return this.maxOffset;\n        }\n        const node = this._nodes[index];\n        if (!node) {\n            /**\n\t\t\t * Given index cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error model-nodelist-index-out-of-bounds\n\t\t\t */ throw new CKEditorError('model-nodelist-index-out-of-bounds', this);\n        }\n        return this.getNodeStartOffset(node);\n    }\n    /**\n\t * Converts offset in node list to index.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `model-nodelist-offset-out-of-bounds` if given offset is less\n\t * than `0` or more than {@link #maxOffset}.\n\t */ offsetToIndex(offset) {\n        if (offset == this._offsetToNode.length) {\n            return this._nodes.length;\n        }\n        const node = this._offsetToNode[offset];\n        if (!node) {\n            /**\n\t\t\t * Given offset cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error model-nodelist-offset-out-of-bounds\n\t\t\t * @param offset\n\t\t\t * @param nodeList Stringified node list.\n\t\t\t */ throw new CKEditorError('model-nodelist-offset-out-of-bounds', this, {\n                offset,\n                nodeList: this\n            });\n        }\n        return this.getNodeIndex(node);\n    }\n    /**\n\t * Inserts given nodes at given index.\n\t *\n\t * @internal\n\t * @param index Index at which nodes should be inserted.\n\t * @param nodes Nodes to be inserted.\n\t */ _insertNodes(index, nodes) {\n        // Validation.\n        for (const node of nodes){\n            if (!(node instanceof Node$1)) {\n                /**\n\t\t\t\t * Trying to insert an object which is not a Node instance.\n\t\t\t\t *\n\t\t\t\t * @error model-nodelist-insertnodes-not-node\n\t\t\t\t */ throw new CKEditorError('model-nodelist-insertnodes-not-node', this);\n            }\n        }\n        const nodesArray = Array.from(nodes);\n        const offsetsArray = makeOffsetsArray(nodesArray);\n        let offset = this.indexToOffset(index);\n        // Splice nodes array and offsets array into the nodelist.\n        this._nodes = spliceArray(this._nodes, nodesArray, index, 0);\n        this._offsetToNode = spliceArray(this._offsetToNode, offsetsArray, offset, 0);\n        // Refresh indexes and offsets for nodes inside this node list. We need to do this for all inserted nodes and all nodes after them.\n        for(let i = index; i < this._nodes.length; i++){\n            this._nodes[i]._index = i;\n            this._nodes[i]._startOffset = offset;\n            offset += this._nodes[i].offsetSize;\n        }\n    }\n    /**\n\t * Removes one or more nodes starting at the given index.\n\t *\n\t * @internal\n\t * @param indexStart Index of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns Array containing removed nodes.\n\t */ _removeNodes(indexStart, howMany = 1) {\n        if (howMany == 0) {\n            return [];\n        }\n        // Remove nodes from this nodelist.\n        let offset = this.indexToOffset(indexStart);\n        const nodes = this._nodes.splice(indexStart, howMany);\n        const lastNode = nodes[nodes.length - 1];\n        const removedOffsetSum = lastNode.startOffset + lastNode.offsetSize - offset;\n        this._offsetToNode.splice(offset, removedOffsetSum);\n        // Reset index and start offset properties for the removed nodes -- they do not have a parent anymore.\n        for (const node of nodes){\n            node._index = null;\n            node._startOffset = null;\n        }\n        for(let i = indexStart; i < this._nodes.length; i++){\n            this._nodes[i]._index = i;\n            this._nodes[i]._startOffset = offset;\n            offset += this._nodes[i].offsetSize;\n        }\n        return nodes;\n    }\n    /**\n\t * Converts `NodeList` instance to an array containing nodes that were inserted in the node list. Nodes\n\t * are also converted to their plain object representation.\n\t *\n\t * @returns `NodeList` instance converted to `Array`.\n\t */ toJSON() {\n        return this._nodes.map((node)=>node.toJSON());\n    }\n}\n/**\n * Creates an array of nodes in the format as in {@link module:engine/model/nodelist~NodeList#_offsetToNode}, i.e. one node will\n * occupy multiple items if its offset size is greater than one.\n */ function makeOffsetsArray(nodes) {\n    const offsets = [];\n    for (const node of nodes){\n        const start = offsets.length;\n        offsets.length += node.offsetSize;\n        offsets.fill(node, start);\n    }\n    return offsets;\n}\n\n// @if CK_DEBUG_ENGINE // const { convertMapToStringifiedObject } = require( '../dev-utils/utils' );\n/**\n * Model text node. Type of {@link module:engine/model/node~Node node} that contains {@link module:engine/model/text~Text#data text data}.\n *\n * **Important:** see {@link module:engine/model/node~Node} to read about restrictions using `Text` and `Node` API.\n *\n * **Note:** keep in mind that `Text` instances might indirectly got removed from model tree when model is changed.\n * This happens when {@link module:engine/model/writer~Writer model writer} is used to change model and the text node is merged with\n * another text node. Then, both text nodes are removed and a new text node is inserted into the model. Because of\n * this behavior, keeping references to `Text` is not recommended. Instead, consider creating\n * {@link module:engine/model/liveposition~LivePosition live position} placed before the text node.\n */ class Text extends Node$1 {\n    /**\n\t * Text data contained in this text node.\n\t *\n\t * @internal\n\t */ _data;\n    /**\n\t * Creates a text node.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createText} method instead.\n\t *\n\t * @internal\n\t * @param data Node's text.\n\t * @param attrs Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */ constructor(data, attrs){\n        super(attrs);\n        this._data = data || '';\n    }\n    /**\n\t * @inheritDoc\n\t */ get offsetSize() {\n        return this.data.length;\n    }\n    /**\n\t * Returns a text data contained in the node.\n\t */ get data() {\n        return this._data;\n    }\n    /**\n\t * Converts `Text` instance to plain object and returns it.\n\t *\n\t * @returns`Text` instance converted to plain object.\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.data = this.data;\n        return json;\n    }\n    /**\n\t * Creates a copy of this text node and returns it. Created text node has same text data and attributes as original text node.\n\t *\n\t * @internal\n\t * @returns `Text` instance created using given plain object.\n\t */ _clone() {\n        return new Text(this.data, this.getAttributes());\n    }\n    /**\n\t * Creates a `Text` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param json Plain object to be converted to `Text`.\n\t * @returns `Text` instance created using given plain object.\n\t */ static fromJSON(json) {\n        return new Text(json.data, json.attributes);\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nText.prototype.is = function(type) {\n    return type === '$text' || type === 'model:$text' || // This are legacy values kept for backward compatibility.\n    type === 'text' || type === 'model:text' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n    type === 'node' || type === 'model:node';\n};\n\n// @if CK_DEBUG_ENGINE // const { convertMapToStringifiedObject } = require( '../dev-utils/utils' );\n/**\n * `TextProxy` represents a part of {@link module:engine/model/text~Text text node}.\n *\n * Since {@link module:engine/model/position~Position positions} can be placed between characters of a text node,\n * {@link module:engine/model/range~Range ranges} may contain only parts of text nodes. When {@link module:engine/model/range~Range#getItems\n * getting items}\n * contained in such range, we need to represent a part of that text node, since returning the whole text node would be incorrect.\n * `TextProxy` solves this issue.\n *\n * `TextProxy` has an API similar to {@link module:engine/model/text~Text Text} and allows to do most of the common tasks performed\n * on model nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/model/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is not an instance of {@link module:engine/model/node~Node node}. Keep this in mind when using it as a\n * parameter of methods.\n *\n * **Note:** `TextProxy` is a readonly interface. If you want to perform changes on model data represented by a `TextProxy`\n * use {@link module:engine/model/writer~Writer model writer API}.\n *\n * **Note:** `TextProxy` instances are created on the fly, basing on the current state of model. Because of this, it is\n * highly unrecommended to store references to `TextProxy` instances. `TextProxy` instances are not refreshed when\n * model changes, so they might get invalidated. Instead, consider creating {@link module:engine/model/liveposition~LivePosition live\n * position}.\n *\n * `TextProxy` instances are created by {@link module:engine/model/treewalker~TreeWalker model tree walker}. You should not need to create\n * an instance of this class by your own.\n */ class TextProxy extends TypeCheckable {\n    /**\n\t * Text node which part is represented by this text proxy.\n\t */ textNode;\n    /**\n\t * Text data represented by this text proxy.\n\t */ data;\n    /**\n\t * Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy starts.\n\t */ offsetInText;\n    /**\n\t * Creates a text proxy.\n\t *\n\t * @internal\n\t * @param textNode Text node which part is represented by this text proxy.\n\t * @param offsetInText Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy\n\t * starts.\n\t * @param length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t */ constructor(textNode, offsetInText, length){\n        super();\n        this.textNode = textNode;\n        if (offsetInText < 0 || offsetInText > textNode.offsetSize) {\n            /**\n\t\t\t * Given `offsetInText` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-offsetintext\n\t\t\t */ throw new CKEditorError('model-textproxy-wrong-offsetintext', this);\n        }\n        if (length < 0 || offsetInText + length > textNode.offsetSize) {\n            /**\n\t\t\t * Given `length` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-length\n\t\t\t */ throw new CKEditorError('model-textproxy-wrong-length', this);\n        }\n        this.data = textNode.data.substring(offsetInText, offsetInText + length);\n        this.offsetInText = offsetInText;\n    }\n    /**\n\t * Offset at which this text proxy starts in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#startOffset\n\t */ get startOffset() {\n        return this.textNode.startOffset !== null ? this.textNode.startOffset + this.offsetInText : null;\n    }\n    /**\n\t * Offset size of this text proxy. Equal to the number of characters represented by the text proxy.\n\t *\n\t * @see module:engine/model/node~Node#offsetSize\n\t */ get offsetSize() {\n        return this.data.length;\n    }\n    /**\n\t * Offset at which this text proxy ends in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#endOffset\n\t */ get endOffset() {\n        return this.startOffset !== null ? this.startOffset + this.offsetSize : null;\n    }\n    /**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/model/text~Text text node}\n\t * (`true`) or the whole text node (`false`).\n\t *\n\t * This is `false` when text proxy starts at the very beginning of {@link module:engine/model/textproxy~TextProxy#textNode textNode}\n\t * ({@link module:engine/model/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t */ get isPartial() {\n        return this.offsetSize !== this.textNode.offsetSize;\n    }\n    /**\n\t * Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t */ get parent() {\n        return this.textNode.parent;\n    }\n    /**\n\t * Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t */ get root() {\n        return this.textNode.root;\n    }\n    /**\n\t * Gets path to this text proxy.\n\t *\n\t * @see module:engine/model/node~Node#getPath\n\t */ getPath() {\n        const path = this.textNode.getPath();\n        if (path.length > 0) {\n            path[path.length - 1] += this.offsetInText;\n        }\n        return path;\n    }\n    /**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this text proxy will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from text proxy parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */ getAncestors(options = {}) {\n        const ancestors = [];\n        let parent = options.includeSelf ? this : this.parent;\n        while(parent){\n            ancestors[options.parentFirst ? 'push' : 'unshift'](parent);\n            parent = parent.parent;\n        }\n        return ancestors;\n    }\n    /**\n\t * Checks if this text proxy has an attribute for given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on text proxy, `false` otherwise.\n\t */ hasAttribute(key) {\n        return this.textNode.hasAttribute(key);\n    }\n    /**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on text proxy.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */ getAttribute(key) {\n        return this.textNode.getAttribute(key);\n    }\n    /**\n\t * Returns iterator that iterates over this node's attributes. Attributes are returned as arrays containing two\n\t * items. First one is attribute key and second is attribute value.\n\t *\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */ getAttributes() {\n        return this.textNode.getAttributes();\n    }\n    /**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t */ getAttributeKeys() {\n        return this.textNode.getAttributeKeys();\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nTextProxy.prototype.is = function(type) {\n    return type === '$textProxy' || type === 'model:$textProxy' || // This are legacy values kept for backward compatibility.\n    type === 'textProxy' || type === 'model:textProxy';\n};\n\n// @if CK_DEBUG_ENGINE // const { stringifyMap, convertMapToStringifiedObject, convertMapToTags } = require( '../dev-utils/utils' );\n/**\n * Model element. Type of {@link module:engine/model/node~Node node} that has a {@link module:engine/model/element~Element#name name} and\n * {@link module:engine/model/element~Element#getChildren child nodes}.\n *\n * **Important**: see {@link module:engine/model/node~Node} to read about restrictions using `Element` and `Node` API.\n */ class Element extends Node$1 {\n    /**\n\t * Element name.\n\t */ name;\n    /**\n\t * List of children nodes.\n\t */ _children = new NodeList();\n    /**\n\t * Creates a model element.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createElement} method instead.\n\t *\n\t * @internal\n\t * @param name Element's name.\n\t * @param attrs Element's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t * @param children One or more nodes to be inserted as children of created element.\n\t */ constructor(name, attrs, children){\n        super(attrs);\n        this.name = name;\n        if (children) {\n            this._insertChild(0, children);\n        }\n    }\n    /**\n\t * Number of this element's children.\n\t */ get childCount() {\n        return this._children.length;\n    }\n    /**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all of this element's children.\n\t */ get maxOffset() {\n        return this._children.maxOffset;\n    }\n    /**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t */ get isEmpty() {\n        return this.childCount === 0;\n    }\n    /**\n\t * Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param index Index in this element.\n\t * @returns Child node.\n\t */ getChild(index) {\n        return this._children.getNode(index);\n    }\n    /**\n\t * Gets the child at the given offset. Returns `null` if incorrect index was passed.\n\t *\n\t * @param offset Offset in this element.\n\t * @returns Child node.\n\t */ getChildAtOffset(offset) {\n        return this._children.getNodeAtOffset(offset);\n    }\n    /**\n\t * Returns an iterator that iterates over all of this element's children.\n\t */ getChildren() {\n        return this._children[Symbol.iterator]();\n    }\n    /**\n\t * Returns an index of the given child node. Returns `null` if given node is not a child of this element.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's index in this element.\n\t */ getChildIndex(node) {\n        return this._children.getNodeIndex(node);\n    }\n    /**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {@link module:engine/model/node~Node#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t * given node is not a child of this element.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's starting offset.\n\t */ getChildStartOffset(node) {\n        return this._children.getNodeStartOffset(node);\n    }\n    /**\n\t * Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t * too high, returns {@link module:engine/model/element~Element#getChildIndex index after last child}.\n\t *\n\t * ```ts\n\t * const textNode = new Text( 'foo' );\n\t * const pElement = new Element( 'p' );\n\t * const divElement = new Element( [ textNode, pElement ] );\n\t * divElement.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t * divElement.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t * divElement.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t * divElement.offsetToIndex( 2 ); // Returns 0.\n\t * divElement.offsetToIndex( 3 ); // Returns 1.\n\t * divElement.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t * ```\n\t */ offsetToIndex(offset) {\n        return this._children.offsetToIndex(offset);\n    }\n    /**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t * ```ts\n\t * // <this>a<b>c</b></this>\n\t * this.getNodeByPath( [ 0 ] );     // -> \"a\"\n\t * this.getNodeByPath( [ 1 ] );     // -> <b>\n\t * this.getNodeByPath( [ 1, 0 ] );  // -> \"c\"\n\t * ```\n\t *\n\t * @param relativePath Path of the node to find, relative to this element.\n\t */ getNodeByPath(relativePath) {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n        let node = this;\n        for (const offset of relativePath){\n            node = node.getChildAtOffset(offset);\n        }\n        return node;\n    }\n    /**\n\t * Returns the parent element of the given name. Returns null if the element is not inside the desired parent.\n\t *\n\t * @param parentName The name of the parent element to find.\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this node will be also included while searching.\n\t */ findAncestor(parentName, options = {}) {\n        let parent = options.includeSelf ? this : this.parent;\n        while(parent){\n            if (parent.name === parentName) {\n                return parent;\n            }\n            parent = parent.parent;\n        }\n        return null;\n    }\n    /**\n\t * Converts `Element` instance to plain object and returns it. Takes care of converting all of this element's children.\n\t *\n\t * @returns `Element` instance converted to plain object.\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.name = this.name;\n        if (this._children.length > 0) {\n            json.children = [];\n            for (const node of this._children){\n                json.children.push(node.toJSON());\n            }\n        }\n        return json;\n    }\n    /**\n\t * Creates a copy of this element and returns it. Created element has the same name and attributes as the original element.\n\t * If clone is deep, the original element's children are also cloned. If not, then empty element is returned.\n\t *\n\t * @internal\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any child.\n\t */ _clone(deep = false) {\n        const children = deep ? Array.from(this._children).map((node)=>node._clone(true)) : undefined;\n        return new Element(this.name, this.getAttributes(), children);\n    }\n    /**\n\t * {@link module:engine/model/element~Element#_insertChild Inserts} one or more nodes at the end of this element.\n\t *\n\t * @see module:engine/model/writer~Writer#append\n\t * @internal\n\t * @param nodes Nodes to be inserted.\n\t */ _appendChild(nodes) {\n        this._insertChild(this.childCount, nodes);\n    }\n    /**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this element.\n\t *\n\t * @see module:engine/model/writer~Writer#insert\n\t * @internal\n\t * @param index Index at which nodes should be inserted.\n\t * @param items Items to be inserted.\n\t */ _insertChild(index, items) {\n        const nodes = normalize$1(items);\n        for (const node of nodes){\n            // If node that is being added to this element is already inside another element, first remove it from the old parent.\n            if (node.parent !== null) {\n                node._remove();\n            }\n            node.parent = this;\n        }\n        this._children._insertNodes(index, nodes);\n    }\n    /**\n\t * Removes one or more nodes starting at the given index and sets\n\t * {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @see module:engine/model/writer~Writer#remove\n\t * @internal\n\t * @param index Index of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns Array containing removed nodes.\n\t */ _removeChildren(index, howMany = 1) {\n        const nodes = this._children._removeNodes(index, howMany);\n        for (const node of nodes){\n            node.parent = null;\n        }\n        return nodes;\n    }\n    /**\n\t * Creates an `Element` instance from given plain object (i.e. parsed JSON string).\n\t * Converts `Element` children to proper nodes.\n\t *\n\t * @param json Plain object to be converted to `Element`.\n\t * @returns `Element` instance created using given plain object.\n\t */ static fromJSON(json) {\n        let children;\n        if (json.children) {\n            children = [];\n            for (const child of json.children){\n                if (child.name) {\n                    // If child has name property, it is an Element.\n                    children.push(Element.fromJSON(child));\n                } else {\n                    // Otherwise, it is a Text node.\n                    children.push(Text.fromJSON(child));\n                }\n            }\n        }\n        return new Element(json.name, json.attributes, children);\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'element' || type === 'model:element' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'node' || type === 'model:node';\n    }\n    return name === this.name && (type === 'element' || type === 'model:element');\n};\n/**\n * Converts strings to Text and non-iterables to arrays.\n */ function normalize$1(nodes) {\n    // Separate condition because string is iterable.\n    if (typeof nodes == 'string') {\n        return [\n            new Text(nodes)\n        ];\n    }\n    if (!isIterable(nodes)) {\n        nodes = [\n            nodes\n        ];\n    }\n    // Array.from to enable .map() on non-arrays.\n    return Array.from(nodes).map((node)=>{\n        if (typeof node == 'string') {\n            return new Text(node);\n        }\n        if (node instanceof TextProxy) {\n            return new Text(node.data, node.getAttributes());\n        }\n        return node;\n    });\n}\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */ class TreeWalker {\n    /**\n\t * Walking direction. Defaults `'forward'`.\n\t */ direction;\n    /**\n\t * Iterator boundaries.\n\t *\n\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t * on the start of boundary, then `{ done: true }` is returned.\n\t *\n\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t */ boundaries;\n    /**\n\t * Flag indicating whether all consecutive characters with the same attributes should be\n\t * returned as one {@link module:engine/model/textproxy~TextProxy} (`true`) or one by one (`false`).\n\t */ singleCharacters;\n    /**\n\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t * iterated node will not be returned along with `elementEnd` tag.\n\t */ shallow;\n    /**\n\t * Flag indicating whether iterator should ignore `elementEnd` tags. If the option is true walker will not\n\t * return a parent node of the start position. If this option is `true` each {@link module:engine/model/element~Element} will\n\t * be returned once, while if the option is `false` they might be returned twice:\n\t * for `'elementStart'` and `'elementEnd'`.\n\t */ ignoreElementEnd;\n    /**\n\t * Iterator position. This is always static position, even if the initial position was a\n\t * {@link module:engine/model/liveposition~LivePosition live position}. If start position is not defined then position depends\n\t * on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t * is `'backward'` position starts from the end.\n\t */ _position;\n    /**\n\t * Start boundary cached for optimization purposes.\n\t */ _boundaryStartParent;\n    /**\n\t * End boundary cached for optimization purposes.\n\t */ _boundaryEndParent;\n    /**\n\t * Parent of the most recently visited node. Cached for optimization purposes.\n\t */ _visitedParent;\n    /**\n\t * Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t *\n\t * @param options Object with configuration.\n\t */ constructor(options){\n        if (!options || !options.boundaries && !options.startPosition) {\n            /**\n\t\t\t * Neither boundaries nor starting position of a `TreeWalker` have been defined.\n\t\t\t *\n\t\t\t * @error model-tree-walker-no-start-position\n\t\t\t */ throw new CKEditorError('model-tree-walker-no-start-position', null);\n        }\n        const direction = options.direction || 'forward';\n        if (direction != 'forward' && direction != 'backward') {\n            /**\n\t\t\t * Only `backward` and `forward` direction allowed.\n\t\t\t *\n\t\t\t * @error model-tree-walker-unknown-direction\n\t\t\t */ throw new CKEditorError('model-tree-walker-unknown-direction', options, {\n                direction\n            });\n        }\n        this.direction = direction;\n        this.boundaries = options.boundaries || null;\n        if (options.startPosition) {\n            this._position = options.startPosition.clone();\n        } else {\n            this._position = Position._createAt(this.boundaries[this.direction == 'backward' ? 'end' : 'start']);\n        }\n        // Reset position stickiness in case it was set to other value, as the stickiness is kept after cloning.\n        this.position.stickiness = 'toNone';\n        this.singleCharacters = !!options.singleCharacters;\n        this.shallow = !!options.shallow;\n        this.ignoreElementEnd = !!options.ignoreElementEnd;\n        this._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n        this._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n        this._visitedParent = this.position.parent;\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:engine/model/treewalker~TreeWalkerValue>}\n\t */ [Symbol.iterator]() {\n        return this;\n    }\n    /**\n\t * Iterator position. This is always static position, even if the initial position was a\n\t * {@link module:engine/model/liveposition~LivePosition live position}. If start position is not defined then position depends\n\t * on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t * is `'backward'` position starts from the end.\n\t */ get position() {\n        return this._position;\n    }\n    /**\n\t * Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * walker.skip( value => value.type == 'text' ); // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t * walker.skip( () => true ); // Move the position to the end: <paragraph>[]foo</paragraph> -> <paragraph>foo</paragraph>[]\n\t * walker.skip( () => false ); // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t */ skip(skip) {\n        let done, value, prevPosition, prevVisitedParent;\n        do {\n            prevPosition = this.position;\n            prevVisitedParent = this._visitedParent;\n            ({ done, value } = this.next());\n        }while (!done && skip(value))\n        if (!done) {\n            this._position = prevPosition;\n            this._visitedParent = prevVisitedParent;\n        }\n    }\n    /**\n\t * Gets the next tree walker's value.\n\t */ next() {\n        if (this.direction == 'forward') {\n            return this._next();\n        } else {\n            return this._previous();\n        }\n    }\n    /**\n\t * Makes a step forward in model. Moves the {@link #position} to the next position and returns the encountered value.\n\t */ _next() {\n        const previousPosition = this.position;\n        const position = this.position.clone();\n        const parent = this._visitedParent;\n        // We are at the end of the root.\n        if (parent.parent === null && position.offset === parent.maxOffset) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // We reached the walker boundary.\n        if (parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // Get node just after the current position.\n        // Use a highly optimized version instead of checking the text node first and then getting the node after. See #6582.\n        const textNodeAtPosition = getTextNodeAtPosition(position, parent);\n        const node = textNodeAtPosition || getNodeAfterPosition(position, parent, textNodeAtPosition);\n        if (node instanceof Element) {\n            if (!this.shallow) {\n                // Manual operations on path internals for optimization purposes. Here and in the rest of the method.\n                position.path.push(0);\n                this._visitedParent = node;\n            } else {\n                // We are past the walker boundaries.\n                if (this.boundaries && this.boundaries.end.isBefore(position)) {\n                    return {\n                        done: true,\n                        value: undefined\n                    };\n                }\n                position.offset++;\n            }\n            this._position = position;\n            return formatReturnValue('elementStart', node, previousPosition, position, 1);\n        }\n        if (node instanceof Text) {\n            let charactersCount;\n            if (this.singleCharacters) {\n                charactersCount = 1;\n            } else {\n                let offset = node.endOffset;\n                if (this._boundaryEndParent == parent && this.boundaries.end.offset < offset) {\n                    offset = this.boundaries.end.offset;\n                }\n                charactersCount = offset - position.offset;\n            }\n            const offsetInTextNode = position.offset - node.startOffset;\n            const item = new TextProxy(node, offsetInTextNode, charactersCount);\n            position.offset += charactersCount;\n            this._position = position;\n            return formatReturnValue('text', item, previousPosition, position, charactersCount);\n        }\n        // `node` is not set, we reached the end of current `parent`.\n        position.path.pop();\n        position.offset++;\n        this._position = position;\n        this._visitedParent = parent.parent;\n        if (this.ignoreElementEnd) {\n            return this._next();\n        }\n        return formatReturnValue('elementEnd', parent, previousPosition, position);\n    }\n    /**\n\t * Makes a step backward in model. Moves the {@link #position} to the previous position and returns the encountered value.\n\t */ _previous() {\n        const previousPosition = this.position;\n        const position = this.position.clone();\n        const parent = this._visitedParent;\n        // We are at the beginning of the root.\n        if (parent.parent === null && position.offset === 0) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // We reached the walker boundary.\n        if (parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // Get node just before the current position.\n        // Use a highly optimized version instead of checking the text node first and then getting the node before. See #6582.\n        const positionParent = position.parent;\n        const textNodeAtPosition = getTextNodeAtPosition(position, positionParent);\n        const node = textNodeAtPosition || getNodeBeforePosition(position, positionParent, textNodeAtPosition);\n        if (node instanceof Element) {\n            position.offset--;\n            if (this.shallow) {\n                this._position = position;\n                return formatReturnValue('elementStart', node, previousPosition, position, 1);\n            }\n            position.path.push(node.maxOffset);\n            this._position = position;\n            this._visitedParent = node;\n            if (this.ignoreElementEnd) {\n                return this._previous();\n            }\n            return formatReturnValue('elementEnd', node, previousPosition, position);\n        }\n        if (node instanceof Text) {\n            let charactersCount;\n            if (this.singleCharacters) {\n                charactersCount = 1;\n            } else {\n                let offset = node.startOffset;\n                if (this._boundaryStartParent == parent && this.boundaries.start.offset > offset) {\n                    offset = this.boundaries.start.offset;\n                }\n                charactersCount = position.offset - offset;\n            }\n            const offsetInTextNode = position.offset - node.startOffset;\n            const item = new TextProxy(node, offsetInTextNode - charactersCount, charactersCount);\n            position.offset -= charactersCount;\n            this._position = position;\n            return formatReturnValue('text', item, previousPosition, position, charactersCount);\n        }\n        // `node` is not set, we reached the beginning of current `parent`.\n        position.path.pop();\n        this._position = position;\n        this._visitedParent = parent.parent;\n        return formatReturnValue('elementStart', parent, previousPosition, position, 1);\n    }\n}\nfunction formatReturnValue(type, item, previousPosition, nextPosition, length) {\n    return {\n        done: false,\n        value: {\n            type,\n            item,\n            previousPosition,\n            nextPosition,\n            length\n        }\n    };\n}\n\n/**\n * Represents a position in the model tree.\n *\n * A position is represented by its {@link module:engine/model/position~Position#root} and\n * a {@link module:engine/model/position~Position#path} in that root.\n *\n * You can create position instances via its constructor or the `createPosition*()` factory methods of\n * {@link module:engine/model/model~Model} and {@link module:engine/model/writer~Writer}.\n *\n * **Note:** Position is based on offsets, not indexes. This means that a position between two text nodes\n * `foo` and `bar` has offset `3`, not `1`. See {@link module:engine/model/position~Position#path} for more information.\n *\n * Since a position in the model is represented by a {@link module:engine/model/position~Position#root position root} and\n * {@link module:engine/model/position~Position#path position path} it is possible to create positions placed in non-existing places.\n * This requirement is important for operational transformation algorithms.\n *\n * Also, {@link module:engine/model/operation/operation~Operation operations}\n * kept in the {@link module:engine/model/document~Document#history document history}\n * are storing positions (and ranges) which were correct when those operations were applied, but may not be correct\n * after the document has changed.\n *\n * When changes are applied to the model, it may also happen that {@link module:engine/model/position~Position#parent position parent}\n * will change even if position path has not changed. Keep in mind, that if a position leads to non-existing element,\n * {@link module:engine/model/position~Position#parent} and some other properties and methods will throw errors.\n *\n * In most cases, position with wrong path is caused by an error in code, but it is sometimes needed, as described above.\n */ class Position extends TypeCheckable {\n    /**\n\t * Root of the position path.\n\t */ root;\n    /**\n\t * Position of the node in the tree. **Path contains offsets, not indexes.**\n\t *\n\t * Position can be placed before, after or in a {@link module:engine/model/node~Node node} if that node has\n\t * {@link module:engine/model/node~Node#offsetSize} greater than `1`. Items in position path are\n\t * {@link module:engine/model/node~Node#startOffset starting offsets} of position ancestors, starting from direct root children,\n\t * down to the position offset in it's parent.\n\t *\n\t * ```\n\t * ROOT\n\t *  |- P            before: [ 0 ]         after: [ 1 ]\n\t *  |- UL           before: [ 1 ]         after: [ 2 ]\n\t *     |- LI        before: [ 1, 0 ]      after: [ 1, 1 ]\n\t *     |  |- foo    before: [ 1, 0, 0 ]   after: [ 1, 0, 3 ]\n\t *     |- LI        before: [ 1, 1 ]      after: [ 1, 2 ]\n\t *        |- bar    before: [ 1, 1, 0 ]   after: [ 1, 1, 3 ]\n\t * ```\n\t *\n\t * `foo` and `bar` are representing {@link module:engine/model/text~Text text nodes}. Since text nodes has offset size\n\t * greater than `1` you can place position offset between their start and end:\n\t *\n\t * ```\n\t * ROOT\n\t *  |- P\n\t *  |- UL\n\t *     |- LI\n\t *     |  |- f^o|o  ^ has path: [ 1, 0, 1 ]   | has path: [ 1, 0, 2 ]\n\t *     |- LI\n\t *        |- b^a|r  ^ has path: [ 1, 1, 1 ]   | has path: [ 1, 1, 2 ]\n\t * ```\n\t */ path;\n    /**\n\t * Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */ stickiness;\n    /**\n\t * Creates a position.\n\t *\n\t * @param root Root of the position.\n\t * @param path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param stickiness Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */ constructor(root, path, stickiness = 'toNone'){\n        super();\n        if (!root.is('element') && !root.is('documentFragment')) {\n            /**\n\t\t\t * Position root is invalid.\n\t\t\t *\n\t\t\t * Positions can only be anchored in elements or document fragments.\n\t\t\t *\n\t\t\t * @error model-position-root-invalid\n\t\t\t */ throw new CKEditorError('model-position-root-invalid', root);\n        }\n        if (!(path instanceof Array) || path.length === 0) {\n            /**\n\t\t\t * Position path must be an array with at least one item.\n\t\t\t *\n\t\t\t * @error model-position-path-incorrect-format\n\t\t\t * @param path\n\t\t\t */ throw new CKEditorError('model-position-path-incorrect-format', root, {\n                path\n            });\n        }\n        // Normalize the root and path when element (not root) is passed.\n        if (root.is('rootElement')) {\n            path = path.slice();\n        } else {\n            path = [\n                ...root.getPath(),\n                ...path\n            ];\n            root = root.root;\n        }\n        this.root = root;\n        this.path = path;\n        this.stickiness = stickiness;\n    }\n    /**\n\t * Offset at which this position is located in its {@link module:engine/model/position~Position#parent parent}. It is equal\n\t * to the last item in position {@link module:engine/model/position~Position#path path}.\n\t *\n\t * @type {Number}\n\t */ get offset() {\n        return this.path[this.path.length - 1];\n    }\n    set offset(newOffset) {\n        this.path[this.path.length - 1] = newOffset;\n    }\n    /**\n\t * Parent element of this position.\n\t *\n\t * Keep in mind that `parent` value is calculated when the property is accessed.\n\t * If {@link module:engine/model/position~Position#path position path}\n\t * leads to a non-existing element, `parent` property will throw error.\n\t *\n\t * Also it is a good idea to cache `parent` property if it is used frequently in an algorithm (i.e. in a long loop).\n\t */ get parent() {\n        let parent = this.root;\n        for(let i = 0; i < this.path.length - 1; i++){\n            parent = parent.getChildAtOffset(this.path[i]);\n            if (!parent) {\n                /**\n\t\t\t\t * The position's path is incorrect. This means that a position does not point to\n\t\t\t\t * a correct place in the tree and hence, some of its methods and getters cannot work correctly.\n\t\t\t\t *\n\t\t\t\t * **Note**: Unlike DOM and view positions, in the model, the\n\t\t\t\t * {@link module:engine/model/position~Position#parent position's parent} is always an element or a document fragment.\n\t\t\t\t * The last offset in the {@link module:engine/model/position~Position#path position's path} is the point in this element\n\t\t\t\t * where this position points.\n\t\t\t\t *\n\t\t\t\t * Read more about model positions and offsets in\n\t\t\t\t * the {@glink framework/architecture/editing-engine#indexes-and-offsets Editing engine architecture} guide.\n\t\t\t\t *\n\t\t\t\t * @error model-position-path-incorrect\n\t\t\t\t * @param position The incorrect position.\n\t\t\t\t */ throw new CKEditorError('model-position-path-incorrect', this, {\n                    position: this\n                });\n            }\n        }\n        if (parent.is('$text')) {\n            throw new CKEditorError('model-position-path-incorrect', this, {\n                position: this\n            });\n        }\n        return parent;\n    }\n    /**\n\t * Position {@link module:engine/model/position~Position#offset offset} converted to an index in position's parent node. It is\n\t * equal to the {@link module:engine/model/node~Node#index index} of a node after this position. If position is placed\n\t * in text node, position index is equal to the index of that text node.\n\t */ get index() {\n        return this.parent.offsetToIndex(this.offset);\n    }\n    /**\n\t * Returns {@link module:engine/model/text~Text text node} instance in which this position is placed or `null` if this\n\t * position is not in a text node.\n\t */ get textNode() {\n        return getTextNodeAtPosition(this, this.parent);\n    }\n    /**\n\t * Node directly after this position. Returns `null` if this position is at the end of its parent, or if it is in a text node.\n\t */ get nodeAfter() {\n        // Cache the parent and reuse for performance reasons. See #6579 and #6582.\n        const parent = this.parent;\n        return getNodeAfterPosition(this, parent, getTextNodeAtPosition(this, parent));\n    }\n    /**\n\t * Node directly before this position. Returns `null` if this position is at the start of its parent, or if it is in a text node.\n\t */ get nodeBefore() {\n        // Cache the parent and reuse for performance reasons. See #6579 and #6582.\n        const parent = this.parent;\n        return getNodeBeforePosition(this, parent, getTextNodeAtPosition(this, parent));\n    }\n    /**\n\t * Is `true` if position is at the beginning of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t */ get isAtStart() {\n        return this.offset === 0;\n    }\n    /**\n\t * Is `true` if position is at the end of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t */ get isAtEnd() {\n        return this.offset == this.parent.maxOffset;\n    }\n    /**\n\t * Checks whether the position is valid in current model tree, that is whether it points to an existing place in the model.\n\t */ isValid() {\n        if (this.offset < 0) {\n            return false;\n        }\n        let parent = this.root;\n        for(let i = 0; i < this.path.length - 1; i++){\n            parent = parent.getChildAtOffset(this.path[i]);\n            if (!parent) {\n                return false;\n            }\n        }\n        return this.offset <= parent.maxOffset;\n    }\n    /**\n\t * Checks whether this position is before or after given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t */ compareWith(otherPosition) {\n        if (this.root != otherPosition.root) {\n            return 'different';\n        }\n        const result = compareArrays(this.path, otherPosition.path);\n        switch(result){\n            case 'same':\n                return 'same';\n            case 'prefix':\n                return 'before';\n            case 'extension':\n                return 'after';\n            default:\n                return this.path[result] < otherPosition.path[result] ? 'before' : 'after';\n        }\n    }\n    /**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/model/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * getLastMatchingPosition( value => value.type == 'text' );\n\t * // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t *\n\t * getLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } );\n\t * // <paragraph>foo[]</paragraph> -> <paragraph>[]foo</paragraph>\n\t *\n\t * getLastMatchingPosition( value => false );\n\t * // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t *\n\t * @returns The position after the last item which matches the `skip` callback test.\n\t */ getLastMatchingPosition(skip, options = {}) {\n        options.startPosition = this;\n        const treeWalker = new TreeWalker(options);\n        treeWalker.skip(skip);\n        return treeWalker.position;\n    }\n    /**\n\t * Returns a path to this position's parent. Parent path is equal to position {@link module:engine/model/position~Position#path path}\n\t * but without the last item.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @returns Path to the parent.\n\t */ getParentPath() {\n        return this.path.slice(0, -1);\n    }\n    /**\n\t * Returns ancestors array of this position, that is this position's parent and its ancestors.\n\t *\n\t * @returns Array with ancestors.\n\t */ getAncestors() {\n        const parent = this.parent;\n        if (parent.is('documentFragment')) {\n            return [\n                parent\n            ];\n        } else {\n            return parent.getAncestors({\n                includeSelf: true\n            });\n        }\n    }\n    /**\n\t * Returns the parent element of the given name. Returns null if the position is not inside the desired parent.\n\t *\n\t * @param parentName The name of the parent element to find.\n\t */ findAncestor(parentName) {\n        const parent = this.parent;\n        if (parent.is('element')) {\n            return parent.findAncestor(parentName, {\n                includeSelf: true\n            });\n        }\n        return null;\n    }\n    /**\n\t * Returns the slice of two position {@link #path paths} which is identical. The {@link #root roots}\n\t * of these two paths must be identical.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param position The second position.\n\t * @returns The common path.\n\t */ getCommonPath(position) {\n        if (this.root != position.root) {\n            return [];\n        }\n        // We find on which tree-level start and end have the lowest common ancestor\n        const cmp = compareArrays(this.path, position.path);\n        // If comparison returned string it means that arrays are same.\n        const diffAt = typeof cmp == 'string' ? Math.min(this.path.length, position.path.length) : cmp;\n        return this.path.slice(0, diffAt);\n    }\n    /**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both positions. The {@link #root roots} of these two positions must be identical.\n\t *\n\t * @param position The second position.\n\t */ getCommonAncestor(position) {\n        const ancestorsA = this.getAncestors();\n        const ancestorsB = position.getAncestors();\n        let i = 0;\n        while(ancestorsA[i] == ancestorsB[i] && ancestorsA[i]){\n            i++;\n        }\n        return i === 0 ? null : ancestorsA[i - 1];\n    }\n    /**\n\t * Returns a new instance of `Position`, that has same {@link #parent parent} but it's offset\n\t * is shifted by `shift` value (can be a negative value).\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param shift Offset shift. Can be a negative value.\n\t * @returns Shifted position.\n\t */ getShiftedBy(shift) {\n        const shifted = this.clone();\n        const offset = shifted.offset + shift;\n        shifted.offset = offset < 0 ? 0 : offset;\n        return shifted;\n    }\n    /**\n\t * Checks whether this position is after given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @see module:engine/model/position~Position#isBefore\n\t * @param  otherPosition Position to compare with.\n\t * @returns True if this position is after given position.\n\t */ isAfter(otherPosition) {\n        return this.compareWith(otherPosition) == 'after';\n    }\n    /**\n\t * Checks whether this position is before given position.\n\t *\n\t * **Note:** watch out when using negation of the value returned by this method, because the negation will also\n\t * be `true` if positions are in different roots and you might not expect this. You should probably use\n\t * `a.isAfter( b ) || a.isEqual( b )` or `!a.isBefore( p ) && a.root == b.root` in most scenarios. If your\n\t * condition uses multiple `isAfter` and `isBefore` checks, build them so they do not use negated values, i.e.:\n\t *\n\t * ```ts\n\t * if ( a.isBefore( b ) && c.isAfter( d ) ) {\n\t * \t// do A.\n\t * } else {\n\t * \t// do B.\n\t * }\n\t * ```\n\t *\n\t * or, if you have only one if-branch:\n\t *\n\t * ```ts\n\t * if ( !( a.isBefore( b ) && c.isAfter( d ) ) {\n\t * \t// do B.\n\t * }\n\t * ```\n\t *\n\t * rather than:\n\t *\n\t * ```ts\n\t * if ( !a.isBefore( b ) || && !c.isAfter( d ) ) {\n\t * \t// do B.\n\t * } else {\n\t * \t// do A.\n\t * }\n\t * ```\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if this position is before given position.\n\t */ isBefore(otherPosition) {\n        return this.compareWith(otherPosition) == 'before';\n    }\n    /**\n\t * Checks whether this position is equal to given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if positions are same.\n\t */ isEqual(otherPosition) {\n        return this.compareWith(otherPosition) == 'same';\n    }\n    /**\n\t * Checks whether this position is touching given position. Positions touch when there are no text nodes\n\t * or empty nodes in a range between them. Technically, those positions are not equal but in many cases\n\t * they are very similar or even indistinguishable.\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if positions touch.\n\t */ isTouching(otherPosition) {\n        if (this.root !== otherPosition.root) {\n            return false;\n        }\n        const commonLevel = Math.min(this.path.length, otherPosition.path.length);\n        for(let level = 0; level < commonLevel; level++){\n            const diff = this.path[level] - otherPosition.path[level];\n            // Positions are spread by a node, so they are not touching.\n            if (diff < -1 || diff > 1) {\n                return false;\n            } else if (diff === 1) {\n                // `otherPosition` is on the left.\n                // `this` is on the right.\n                return checkTouchingBranch(otherPosition, this, level);\n            } else if (diff === -1) {\n                // `this` is on the left.\n                // `otherPosition` is on the right.\n                return checkTouchingBranch(this, otherPosition, level);\n            }\n        // `diff === 0`.\n        // Positions are inside the same element on this level, compare deeper.\n        }\n        // If we ended up here, it means that positions paths have the same beginning.\n        // If the paths have the same length, then it means that they are identical, so the positions are same.\n        if (this.path.length === otherPosition.path.length) {\n            return true;\n        } else if (this.path.length > otherPosition.path.length) {\n            return checkOnlyZeroes(this.path, commonLevel);\n        } else {\n            return checkOnlyZeroes(otherPosition.path, commonLevel);\n        }\n    }\n    /**\n\t * Checks if two positions are in the same parent.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param position Position to compare with.\n\t * @returns `true` if positions have the same parent, `false` otherwise.\n\t */ hasSameParentAs(position) {\n        if (this.root !== position.root) {\n            return false;\n        }\n        const thisParentPath = this.getParentPath();\n        const posParentPath = position.getParentPath();\n        return compareArrays(thisParentPath, posParentPath) == 'same';\n    }\n    /**\n\t * Returns a copy of this position that is transformed by given `operation`.\n\t *\n\t * The new position's parameters are updated accordingly to the effect of the `operation`.\n\t *\n\t * For example, if `n` nodes are inserted before the position, the returned position {@link ~Position#offset} will be\n\t * increased by `n`. If the position was in a merged element, it will be accordingly moved to the new element, etc.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param operation Operation to transform by.\n\t * @returns Transformed position.\n\t */ getTransformedByOperation(operation) {\n        let result;\n        switch(operation.type){\n            case 'insert':\n                result = this._getTransformedByInsertOperation(operation);\n                break;\n            case 'move':\n            case 'remove':\n            case 'reinsert':\n                result = this._getTransformedByMoveOperation(operation);\n                break;\n            case 'split':\n                result = this._getTransformedBySplitOperation(operation);\n                break;\n            case 'merge':\n                result = this._getTransformedByMergeOperation(operation);\n                break;\n            default:\n                result = Position._createAt(this);\n                break;\n        }\n        return result;\n    }\n    /**\n\t * Returns a copy of this position transformed by an insert operation.\n\t *\n\t * @internal\n\t */ _getTransformedByInsertOperation(operation) {\n        return this._getTransformedByInsertion(operation.position, operation.howMany);\n    }\n    /**\n\t * Returns a copy of this position transformed by a move operation.\n\t *\n\t * @internal\n\t */ _getTransformedByMoveOperation(operation) {\n        return this._getTransformedByMove(operation.sourcePosition, operation.targetPosition, operation.howMany);\n    }\n    /**\n\t * Returns a copy of this position transformed by a split operation.\n\t *\n\t * @internal\n\t */ _getTransformedBySplitOperation(operation) {\n        const movedRange = operation.movedRange;\n        const isContained = movedRange.containsPosition(this) || movedRange.start.isEqual(this) && this.stickiness == 'toNext';\n        if (isContained) {\n            return this._getCombined(operation.splitPosition, operation.moveTargetPosition);\n        } else {\n            if (operation.graveyardPosition) {\n                return this._getTransformedByMove(operation.graveyardPosition, operation.insertionPosition, 1);\n            } else {\n                return this._getTransformedByInsertion(operation.insertionPosition, 1);\n            }\n        }\n    }\n    /**\n\t * Returns a copy of this position transformed by merge operation.\n\t *\n\t * @internal\n\t */ _getTransformedByMergeOperation(operation) {\n        const movedRange = operation.movedRange;\n        const isContained = movedRange.containsPosition(this) || movedRange.start.isEqual(this);\n        let pos;\n        if (isContained) {\n            pos = this._getCombined(operation.sourcePosition, operation.targetPosition);\n            if (operation.sourcePosition.isBefore(operation.targetPosition)) {\n                // Above happens during OT when the merged element is moved before the merged-to element.\n                pos = pos._getTransformedByDeletion(operation.deletionPosition, 1);\n            }\n        } else if (this.isEqual(operation.deletionPosition)) {\n            pos = Position._createAt(operation.deletionPosition);\n        } else {\n            pos = this._getTransformedByMove(operation.deletionPosition, operation.graveyardPosition, 1);\n        }\n        return pos;\n    }\n    /**\n\t * Returns a copy of this position that is updated by removing `howMany` nodes starting from `deletePosition`.\n\t * It may happen that this position is in a removed node. If that is the case, `null` is returned instead.\n\t *\n\t * @internal\n\t * @param deletePosition Position before the first removed node.\n\t * @param howMany How many nodes are removed.\n\t * @returns Transformed position or `null`.\n\t */ _getTransformedByDeletion(deletePosition, howMany) {\n        const transformed = Position._createAt(this);\n        // This position can't be affected if deletion was in a different root.\n        if (this.root != deletePosition.root) {\n            return transformed;\n        }\n        if (compareArrays(deletePosition.getParentPath(), this.getParentPath()) == 'same') {\n            // If nodes are removed from the node that is pointed by this position...\n            if (deletePosition.offset < this.offset) {\n                // And are removed from before an offset of that position...\n                if (deletePosition.offset + howMany > this.offset) {\n                    // Position is in removed range, it's no longer in the tree.\n                    return null;\n                } else {\n                    // Decrement the offset accordingly.\n                    transformed.offset -= howMany;\n                }\n            }\n        } else if (compareArrays(deletePosition.getParentPath(), this.getParentPath()) == 'prefix') {\n            // If nodes are removed from a node that is on a path to this position...\n            const i = deletePosition.path.length - 1;\n            if (deletePosition.offset <= this.path[i]) {\n                // And are removed from before next node of that path...\n                if (deletePosition.offset + howMany > this.path[i]) {\n                    // If the next node of that path is removed return null\n                    // because the node containing this position got removed.\n                    return null;\n                } else {\n                    // Otherwise, decrement index on that path.\n                    transformed.path[i] -= howMany;\n                }\n            }\n        }\n        return transformed;\n    }\n    /**\n\t * Returns a copy of this position that is updated by inserting `howMany` nodes at `insertPosition`.\n\t *\n\t * @internal\n\t * @param insertPosition Position where nodes are inserted.\n\t * @param howMany How many nodes are inserted.\n\t * @returns Transformed position.\n\t */ _getTransformedByInsertion(insertPosition, howMany) {\n        const transformed = Position._createAt(this);\n        // This position can't be affected if insertion was in a different root.\n        if (this.root != insertPosition.root) {\n            return transformed;\n        }\n        if (compareArrays(insertPosition.getParentPath(), this.getParentPath()) == 'same') {\n            // If nodes are inserted in the node that is pointed by this position...\n            if (insertPosition.offset < this.offset || insertPosition.offset == this.offset && this.stickiness != 'toPrevious') {\n                // And are inserted before an offset of that position...\n                // \"Push\" this positions offset.\n                transformed.offset += howMany;\n            }\n        } else if (compareArrays(insertPosition.getParentPath(), this.getParentPath()) == 'prefix') {\n            // If nodes are inserted in a node that is on a path to this position...\n            const i = insertPosition.path.length - 1;\n            if (insertPosition.offset <= this.path[i]) {\n                // And are inserted before next node of that path...\n                // \"Push\" the index on that path.\n                transformed.path[i] += howMany;\n            }\n        }\n        return transformed;\n    }\n    /**\n\t * Returns a copy of this position that is updated by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t *\n\t * @internal\n\t * @param sourcePosition Position before the first element to move.\n\t * @param targetPosition Position where moved elements will be inserted.\n\t * @param howMany How many consecutive nodes to move, starting from `sourcePosition`.\n\t * @returns Transformed position.\n\t */ _getTransformedByMove(sourcePosition, targetPosition, howMany) {\n        // Update target position, as it could be affected by nodes removal.\n        targetPosition = targetPosition._getTransformedByDeletion(sourcePosition, howMany);\n        if (sourcePosition.isEqual(targetPosition)) {\n            // If `targetPosition` is equal to `sourcePosition` this isn't really any move. Just return position as it is.\n            return Position._createAt(this);\n        }\n        // Moving a range removes nodes from their original position. We acknowledge this by proper transformation.\n        const transformed = this._getTransformedByDeletion(sourcePosition, howMany);\n        const isMoved = transformed === null || sourcePosition.isEqual(this) && this.stickiness == 'toNext' || sourcePosition.getShiftedBy(howMany).isEqual(this) && this.stickiness == 'toPrevious';\n        if (isMoved) {\n            // This position is inside moved range (or sticks to it).\n            // In this case, we calculate a combination of this position, move source position and target position.\n            return this._getCombined(sourcePosition, targetPosition);\n        } else {\n            // This position is not inside a removed range.\n            //\n            // In next step, we simply reflect inserting `howMany` nodes, which might further affect the position.\n            return transformed._getTransformedByInsertion(targetPosition, howMany);\n        }\n    }\n    /**\n\t * Returns a new position that is a combination of this position and given positions.\n\t *\n\t * The combined position is a copy of this position transformed by moving a range starting at `source` position\n\t * to the `target` position. It is expected that this position is inside the moved range.\n\t *\n\t * Example:\n\t *\n\t * ```ts\n\t * let original = model.createPositionFromPath( root, [ 2, 3, 1 ] );\n\t * let source = model.createPositionFromPath( root, [ 2, 2 ] );\n\t * let target = model.createPositionFromPath( otherRoot, [ 1, 1, 3 ] );\n\t * original._getCombined( source, target ); // path is [ 1, 1, 4, 1 ], root is `otherRoot`\n\t * ```\n\t *\n\t * Explanation:\n\t *\n\t * We have a position `[ 2, 3, 1 ]` and move some nodes from `[ 2, 2 ]` to `[ 1, 1, 3 ]`. The original position\n\t * was inside moved nodes and now should point to the new place. The moved nodes will be after\n\t * positions `[ 1, 1, 3 ]`, `[ 1, 1, 4 ]`, `[ 1, 1, 5 ]`. Since our position was in the second moved node,\n\t * the transformed position will be in a sub-tree of a node at `[ 1, 1, 4 ]`. Looking at original path, we\n\t * took care of `[ 2, 3 ]` part of it. Now we have to add the rest of the original path to the transformed path.\n\t * Finally, the transformed position will point to `[ 1, 1, 4, 1 ]`.\n\t *\n\t * @internal\n\t * @param source Beginning of the moved range.\n\t * @param target Position where the range is moved.\n\t * @returns Combined position.\n\t */ _getCombined(source, target) {\n        const i = source.path.length - 1;\n        // The first part of a path to combined position is a path to the place where nodes were moved.\n        const combined = Position._createAt(target);\n        combined.stickiness = this.stickiness;\n        // Then we have to update the rest of the path.\n        // Fix the offset because this position might be after `from` position and we have to reflect that.\n        combined.offset = combined.offset + this.path[i] - source.offset;\n        // Then, add the rest of the path.\n        // If this position is at the same level as `from` position nothing will get added.\n        combined.path = [\n            ...combined.path,\n            ...this.path.slice(i + 1)\n        ];\n        return combined;\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        return {\n            root: this.root.toJSON(),\n            path: Array.from(this.path),\n            stickiness: this.stickiness\n        };\n    }\n    /**\n\t * Returns a new position that is equal to current position.\n\t */ clone() {\n        return new this.constructor(this.root, this.path, this.stickiness);\n    }\n    /**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/model/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/model/item~Item model item} and `'before'` or `'after'` (sets position before or after given model item).\n\t *\n\t * This method is a shortcut to other factory methods such as:\n\t *\n\t * * {@link module:engine/model/position~Position._createBefore},\n\t * * {@link module:engine/model/position~Position._createAfter}.\n\t *\n\t * @internal\n\t * @param offset Offset or one of the flags. Used only when the first parameter is a {@link module:engine/model/item~Item model item}.\n\t * @param stickiness Position stickiness. Used only when the first parameter is a {@link module:engine/model/item~Item model item}.\n\t */ static _createAt(itemOrPosition, offset, stickiness = 'toNone') {\n        if (itemOrPosition instanceof Position) {\n            return new Position(itemOrPosition.root, itemOrPosition.path, itemOrPosition.stickiness);\n        } else {\n            const node = itemOrPosition;\n            if (offset == 'end') {\n                offset = node.maxOffset;\n            } else if (offset == 'before') {\n                return this._createBefore(node, stickiness);\n            } else if (offset == 'after') {\n                return this._createAfter(node, stickiness);\n            } else if (offset !== 0 && !offset) {\n                /**\n\t\t\t\t * {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}\n\t\t\t\t * requires the offset to be specified when the first parameter is a model item.\n\t\t\t\t *\n\t\t\t\t * @error model-createpositionat-offset-required\n\t\t\t\t */ throw new CKEditorError('model-createpositionat-offset-required', [\n                    this,\n                    itemOrPosition\n                ]);\n            }\n            if (!node.is('element') && !node.is('documentFragment')) {\n                /**\n\t\t\t\t * Position parent have to be a model element or model document fragment.\n\t\t\t\t *\n\t\t\t\t * @error model-position-parent-incorrect\n\t\t\t\t */ throw new CKEditorError('model-position-parent-incorrect', [\n                    this,\n                    itemOrPosition\n                ]);\n            }\n            const path = node.getPath();\n            path.push(offset);\n            return new this(node.root, path, stickiness);\n        }\n    }\n    /**\n\t * Creates a new position, after given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @internal\n\t * @param item Item after which the position should be placed.\n\t * @param stickiness Position stickiness.\n\t */ static _createAfter(item, stickiness) {\n        if (!item.parent) {\n            /**\n\t\t\t * You can not make a position after a root element.\n\t\t\t *\n\t\t\t * @error model-position-after-root\n\t\t\t * @param root\n\t\t\t */ throw new CKEditorError('model-position-after-root', [\n                this,\n                item\n            ], {\n                root: item\n            });\n        }\n        return this._createAt(item.parent, item.endOffset, stickiness);\n    }\n    /**\n\t * Creates a new position, before the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @internal\n\t * @param item Item before which the position should be placed.\n\t * @param stickiness Position stickiness.\n\t */ static _createBefore(item, stickiness) {\n        if (!item.parent) {\n            /**\n\t\t\t * You can not make a position before a root element.\n\t\t\t *\n\t\t\t * @error model-position-before-root\n\t\t\t * @param root\n\t\t\t */ throw new CKEditorError('model-position-before-root', item, {\n                root: item\n            });\n        }\n        return this._createAt(item.parent, item.startOffset, stickiness);\n    }\n    /**\n\t * Creates a `Position` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param json Plain object to be converted to `Position`.\n\t * @param doc Document object that will be position owner.\n\t * @returns `Position` instance created using given plain object.\n\t */ static fromJSON(json, doc) {\n        if (json.root === '$graveyard') {\n            const pos = new Position(doc.graveyard, json.path);\n            pos.stickiness = json.stickiness;\n            return pos;\n        }\n        if (!doc.getRoot(json.root)) {\n            /**\n\t\t\t * Cannot create position for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error model-position-fromjson-no-root\n\t\t\t * @param rootName\n\t\t\t */ throw new CKEditorError('model-position-fromjson-no-root', doc, {\n                rootName: json.root\n            });\n        }\n        return new Position(doc.getRoot(json.root), json.path, json.stickiness);\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nPosition.prototype.is = function(type) {\n    return type === 'position' || type === 'model:position';\n};\n/**\n * Returns a text node at the given position.\n *\n * This is a helper function optimized to reuse the position parent instance for performance reasons.\n *\n * Normally, you should use {@link module:engine/model/position~Position#textNode `Position#textNode`}.\n * If you start hitting performance issues with {@link module:engine/model/position~Position#parent `Position#parent`}\n * check if your algorithm does not access it multiple times (which can happen directly or indirectly via other position properties).\n *\n * See https://github.com/ckeditor/ckeditor5/issues/6579.\n *\n * See also:\n *\n * * {@link module:engine/model/position~getNodeAfterPosition}\n * * {@link module:engine/model/position~getNodeBeforePosition}\n *\n * @param position\n * @param positionParent The parent of the given position.\n */ function getTextNodeAtPosition(position, positionParent) {\n    const node = positionParent.getChildAtOffset(position.offset);\n    if (node && node.is('$text') && node.startOffset < position.offset) {\n        return node;\n    }\n    return null;\n}\n/**\n * Returns the node after the given position.\n *\n * This is a helper function optimized to reuse the position parent instance and the calculation of the text node at the\n * specific position for performance reasons.\n *\n * Normally, you should use {@link module:engine/model/position~Position#nodeAfter `Position#nodeAfter`}.\n * If you start hitting performance issues with {@link module:engine/model/position~Position#parent `Position#parent`} and/or\n * {@link module:engine/model/position~Position#textNode `Position#textNode`}\n * check if your algorithm does not access those properties multiple times\n * (which can happen directly or indirectly via other position properties).\n *\n * See https://github.com/ckeditor/ckeditor5/issues/6579 and https://github.com/ckeditor/ckeditor5/issues/6582.\n *\n * See also:\n *\n * * {@link module:engine/model/position~getTextNodeAtPosition}\n * * {@link module:engine/model/position~getNodeBeforePosition}\n *\n * @param position Position to check.\n * @param positionParent The parent of the given position.\n * @param textNode Text node at the given position.\n */ function getNodeAfterPosition(position, positionParent, textNode) {\n    if (textNode !== null) {\n        return null;\n    }\n    return positionParent.getChildAtOffset(position.offset);\n}\n/**\n * Returns the node before the given position.\n *\n * Refer to {@link module:engine/model/position~getNodeBeforePosition} for documentation on when to use this util method.\n *\n * See also:\n *\n * * {@link module:engine/model/position~getTextNodeAtPosition}\n * * {@link module:engine/model/position~getNodeAfterPosition}\n *\n * @param position Position to check.\n * @param positionParent The parent of the given position.\n * @param textNode Text node at the given position.\n */ function getNodeBeforePosition(position, positionParent, textNode) {\n    if (textNode !== null) {\n        return null;\n    }\n    return positionParent.getChild(positionParent.offsetToIndex(position.offset) - 1);\n}\n/**\n * This is a helper function for `Position#isTouching()`.\n *\n * It checks whether to given positions are touching, considering that they have the same root and paths\n * until given level, and at given level they differ by 1 (so they are branching at `level` point).\n *\n * The exact requirements for touching positions are described in `Position#isTouching()` and also\n * in the body of this function.\n *\n * @param left Position \"on the left\" (it is before `right`).\n * @param right Position \"on the right\" (it is after `left`).\n * @param level Level on which the positions are different.\n */ function checkTouchingBranch(left, right, level) {\n    if (level + 1 === left.path.length) {\n        // Left position does not have any more entries after the point where the positions differ.\n        // [ 2 ] vs [ 3 ]\n        // [ 2 ] vs [ 3, 0, 0 ]\n        // The positions are spread by node at [ 2 ].\n        return false;\n    }\n    if (!checkOnlyZeroes(right.path, level + 1)) {\n        // Right position does not have only zeroes, so we have situation like:\n        // [ 2, maxOffset ] vs [ 3, 1 ]\n        // [ 2, maxOffset ] vs [ 3, 1, 0, 0 ]\n        // The positions are spread by node at [ 3, 0 ].\n        return false;\n    }\n    if (!checkOnlyMaxOffset(left, level + 1)) {\n        // Left position does not have only max offsets, so we have situation like:\n        // [ 2, 4 ] vs [ 3 ]\n        // [ 2, 4 ] vs [ 3, 0, 0 ]\n        // The positions are spread by node at [ 2, 5 ].\n        return false;\n    }\n    // Left position has only max offsets and right position has only zeroes or nothing.\n    // [ 2, maxOffset ] vs [ 3 ]\n    // [ 2, maxOffset, maxOffset ] vs [ 3, 0 ]\n    // There are not elements between positions. The positions are touching.\n    return true;\n}\n/**\n * Checks whether for given array, starting from given index until the end of the array, all items are `0`s.\n *\n * This is a helper function for `Position#isTouching()`.\n */ function checkOnlyZeroes(arr, idx) {\n    while(idx < arr.length){\n        if (arr[idx] !== 0) {\n            return false;\n        }\n        idx++;\n    }\n    return true;\n}\n/**\n * Checks whether for given position, starting from given path level, whether the position is at the end of\n * its parent and whether each element on the path to the position is also at at the end of its parent.\n *\n * This is a helper function for `Position#isTouching()`.\n */ function checkOnlyMaxOffset(pos, level) {\n    let parent = pos.parent;\n    let idx = pos.path.length - 1;\n    let add = 0;\n    while(idx >= level){\n        if (pos.path[idx] + add !== parent.maxOffset) {\n            return false;\n        }\n        // After the first check, we \"go up\", and check whether the position's parent-parent is the last element.\n        // However, we need to add 1 to the value in the path to \"simulate\" moving the path after the parent.\n        // It happens just once.\n        add = 1;\n        idx--;\n        parent = parent.parent;\n    }\n    return true;\n}\n\n/**\n * Represents a range in the model tree.\n *\n * A range is defined by its {@link module:engine/model/range~Range#start} and {@link module:engine/model/range~Range#end}\n * positions.\n *\n * You can create range instances via its constructor or the `createRange*()` factory methods of\n * {@link module:engine/model/model~Model} and {@link module:engine/model/writer~Writer}.\n */ class Range extends TypeCheckable {\n    /**\n\t * Start position.\n\t */ start;\n    /**\n\t * End position.\n\t */ end;\n    /**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * @param start The start position.\n\t * @param end The end position. If not set, the range will be collapsed at the `start` position.\n\t */ constructor(start, end){\n        super();\n        this.start = Position._createAt(start);\n        this.end = end ? Position._createAt(end) : Position._createAt(start);\n        // If the range is collapsed, treat in a similar way as a position and set its boundaries stickiness to 'toNone'.\n        // In other case, make the boundaries stick to the \"inside\" of the range.\n        this.start.stickiness = this.isCollapsed ? 'toNone' : 'toNext';\n        this.end.stickiness = this.isCollapsed ? 'toNone' : 'toPrevious';\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/model/position~Position positions},\n\t * grouped as {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t * It iterates over all {@link module:engine/model/textproxy~TextProxy text contents} that are inside the range\n\t * and all the {@link module:engine/model/element~Element}s that are entered into when iterating over this range.\n\t *\n\t * This iterator uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range\n\t * and `ignoreElementEnd` option set to `true`.\n\t */ *[Symbol.iterator]() {\n        yield* new TreeWalker({\n            boundaries: this,\n            ignoreElementEnd: true\n        });\n    }\n    /**\n\t * Describes whether the range is collapsed, that is if {@link #start} and\n\t * {@link #end} positions are equal.\n\t */ get isCollapsed() {\n        return this.start.isEqual(this.end);\n    }\n    /**\n\t * Describes whether this range is flat, that is if {@link #start} position and\n\t * {@link #end} position are in the same {@link module:engine/model/position~Position#parent}.\n\t */ get isFlat() {\n        const startParentPath = this.start.getParentPath();\n        const endParentPath = this.end.getParentPath();\n        return compareArrays(startParentPath, endParentPath) == 'same';\n    }\n    /**\n\t * Range root element.\n\t */ get root() {\n        return this.start.root;\n    }\n    /**\n\t * Checks whether this range contains given {@link module:engine/model/position~Position position}.\n\t *\n\t * @param position Position to check.\n\t * @returns `true` if given {@link module:engine/model/position~Position position} is contained\n\t * in this range,`false` otherwise.\n\t */ containsPosition(position) {\n        return position.isAfter(this.start) && position.isBefore(this.end);\n    }\n    /**\n\t * Checks whether this range contains given {@link ~Range range}.\n\t *\n\t * @param otherRange Range to check.\n\t * @param loose Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t * start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t * even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t * @returns {Boolean} `true` if given {@link ~Range range} boundaries are contained by this range, `false` otherwise.\n\t */ containsRange(otherRange, loose = false) {\n        if (otherRange.isCollapsed) {\n            loose = false;\n        }\n        const containsStart = this.containsPosition(otherRange.start) || loose && this.start.isEqual(otherRange.start);\n        const containsEnd = this.containsPosition(otherRange.end) || loose && this.end.isEqual(otherRange.end);\n        return containsStart && containsEnd;\n    }\n    /**\n\t * Checks whether given {@link module:engine/model/item~Item} is inside this range.\n\t */ containsItem(item) {\n        const pos = Position._createBefore(item);\n        return this.containsPosition(pos) || this.start.isEqual(pos);\n    }\n    /**\n\t * Two ranges are equal if their {@link #start} and {@link #end} positions are equal.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns `true` if ranges are equal, `false` otherwise.\n\t */ isEqual(otherRange) {\n        return this.start.isEqual(otherRange.start) && this.end.isEqual(otherRange.end);\n    }\n    /**\n\t * Checks and returns whether this range intersects with given range.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns `true` if ranges intersect, `false` otherwise.\n\t */ isIntersecting(otherRange) {\n        return this.start.isBefore(otherRange.end) && this.end.isAfter(otherRange.start);\n    }\n    /**\n\t * Computes which part(s) of this {@link ~Range range} is not a part of given {@link ~Range range}.\n\t * Returned array contains zero, one or two {@link ~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t * let transformed = range.getDifference( otherRange );\n\t * // transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t * otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 3 ] ) );\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has one range: from [ 3 ] to [ 4, 0, 1 ]\n\t *\n\t * otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 4 ] ) );\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has two ranges: from [ 2, 7 ] to [ 3 ] and from [ 4 ] to [ 4, 0, 1 ]\n\t * ```\n\t *\n\t * @param otherRange Range to differentiate against.\n\t * @returns The difference between ranges.\n\t */ getDifference(otherRange) {\n        const ranges = [];\n        if (this.isIntersecting(otherRange)) {\n            // Ranges intersect.\n            if (this.containsPosition(otherRange.start)) {\n                // Given range start is inside this range. This means that we have to\n                // add shrunken range - from the start to the middle of this range.\n                ranges.push(new Range(this.start, otherRange.start));\n            }\n            if (this.containsPosition(otherRange.end)) {\n                // Given range end is inside this range. This means that we have to\n                // add shrunken range - from the middle of this range to the end.\n                ranges.push(new Range(otherRange.end, this.end));\n            }\n        } else {\n            // Ranges do not intersect, return the original range.\n            ranges.push(new Range(this.start, this.end));\n        }\n        return ranges;\n    }\n    /**\n\t * Returns an intersection of this {@link ~Range range} and given {@link ~Range range}.\n\t * Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 2 ] ) );\n\t * let transformed = range.getIntersection( otherRange ); // null - ranges have no common part\n\t *\n\t * otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t * transformed = range.getIntersection( otherRange ); // range from [ 3 ] to [ 4, 0, 1 ]\n\t * ```\n\t *\n\t * @param otherRange Range to check for intersection.\n\t * @returns A common part of given ranges or `null` if ranges have no common part.\n\t */ getIntersection(otherRange) {\n        if (this.isIntersecting(otherRange)) {\n            // Ranges intersect, so a common range will be returned.\n            // At most, it will be same as this range.\n            let commonRangeStart = this.start;\n            let commonRangeEnd = this.end;\n            if (this.containsPosition(otherRange.start)) {\n                // Given range start is inside this range. This means thaNt we have to\n                // shrink common range to the given range start.\n                commonRangeStart = otherRange.start;\n            }\n            if (this.containsPosition(otherRange.end)) {\n                // Given range end is inside this range. This means that we have to\n                // shrink common range to the given range end.\n                commonRangeEnd = otherRange.end;\n            }\n            return new Range(commonRangeStart, commonRangeEnd);\n        }\n        // Ranges do not intersect, so they do not have common part.\n        return null;\n    }\n    /**\n\t * Returns a range created by joining this {@link ~Range range} with the given {@link ~Range range}.\n\t * If ranges have no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let otherRange = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 1 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 2 ] )\n \t * );\n\t * let transformed = range.getJoined( otherRange ); // null - ranges have no common part\n\t *\n\t * otherRange = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 3 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 5 ] )\n\t * );\n\t * transformed = range.getJoined( otherRange ); // range from [ 2, 7 ] to [ 5 ]\n\t * ```\n\t *\n\t * @param otherRange Range to be joined.\n\t * @param loose Whether the intersection check is loose or strict. If the check is strict (`false`),\n\t * ranges are tested for intersection or whether start/end positions are equal. If the check is loose (`true`),\n\t * compared range is also checked if it's {@link module:engine/model/position~Position#isTouching touching} current range.\n\t * @returns A sum of given ranges or `null` if ranges have no common part.\n\t */ getJoined(otherRange, loose = false) {\n        let shouldJoin = this.isIntersecting(otherRange);\n        if (!shouldJoin) {\n            if (this.start.isBefore(otherRange.start)) {\n                shouldJoin = loose ? this.end.isTouching(otherRange.start) : this.end.isEqual(otherRange.start);\n            } else {\n                shouldJoin = loose ? otherRange.end.isTouching(this.start) : otherRange.end.isEqual(this.start);\n            }\n        }\n        if (!shouldJoin) {\n            return null;\n        }\n        let startPosition = this.start;\n        let endPosition = this.end;\n        if (otherRange.start.isBefore(startPosition)) {\n            startPosition = otherRange.start;\n        }\n        if (otherRange.end.isAfter(endPosition)) {\n            endPosition = otherRange.end;\n        }\n        return new Range(startPosition, endPosition);\n    }\n    /**\n\t * Computes and returns the smallest set of {@link #isFlat flat} ranges, that covers this range in whole.\n\t *\n\t * See an example of a model structure (`[` and `]` are range boundaries):\n\t *\n\t * ```\n\t * root                                                            root\n\t *  |- element DIV                         DIV             P2              P3             DIV\n\t *  |   |- element H                   H        P1        f o o           b a r       H         P4\n\t *  |   |   |- \"fir[st\"             fir[st     lorem                               se]cond     ipsum\n\t *  |   |- element P1\n\t *  |   |   |- \"lorem\"                                              ||\n\t *  |- element P2                                                   ||\n\t *  |   |- \"foo\"                                                    VV\n\t *  |- element P3\n\t *  |   |- \"bar\"                                                   root\n\t *  |- element DIV                         DIV             [P2             P3]             DIV\n\t *  |   |- element H                   H       [P1]       f o o           b a r        H         P4\n\t *  |   |   |- \"se]cond\"            fir[st]    lorem                               [se]cond     ipsum\n\t *  |   |- element P4\n\t *  |   |   |- \"ipsum\"\n\t * ```\n\t *\n\t * As it can be seen, letters contained in the range are: `stloremfoobarse`, spread across different parents.\n\t * We are looking for minimal set of flat ranges that contains the same nodes.\n\t *\n\t * Minimal flat ranges for above range `( [ 0, 0, 3 ], [ 3, 0, 2 ] )` will be:\n\t *\n\t * ```\n\t * ( [ 0, 0, 3 ], [ 0, 0, 5 ] ) = \"st\"\n\t * ( [ 0, 1 ], [ 0, 2 ] ) = element P1 (\"lorem\")\n\t * ( [ 1 ], [ 3 ] ) = element P2, element P3 (\"foobar\")\n\t * ( [ 3, 0, 0 ], [ 3, 0, 2 ] ) = \"se\"\n\t * ```\n\t *\n\t * **Note:** if an {@link module:engine/model/element~Element element} is not wholly contained in this range, it won't be returned\n\t * in any of the returned flat ranges. See in the example how `H` elements at the beginning and at the end of the range\n\t * were omitted. Only their parts that were wholly in the range were returned.\n\t *\n\t * **Note:** this method is not returning flat ranges that contain no nodes.\n\t *\n\t * @returns Array of flat ranges covering this range.\n\t */ getMinimalFlatRanges() {\n        const ranges = [];\n        const diffAt = this.start.getCommonPath(this.end).length;\n        const pos = Position._createAt(this.start);\n        let posParent = pos.parent;\n        // Go up.\n        while(pos.path.length > diffAt + 1){\n            const howMany = posParent.maxOffset - pos.offset;\n            if (howMany !== 0) {\n                ranges.push(new Range(pos, pos.getShiftedBy(howMany)));\n            }\n            pos.path = pos.path.slice(0, -1);\n            pos.offset++;\n            posParent = posParent.parent;\n        }\n        // Go down.\n        while(pos.path.length <= this.end.path.length){\n            const offset = this.end.path[pos.path.length - 1];\n            const howMany = offset - pos.offset;\n            if (howMany !== 0) {\n                ranges.push(new Range(pos, pos.getShiftedBy(howMany)));\n            }\n            pos.offset = offset;\n            pos.path.push(0);\n        }\n        return ranges;\n    }\n    /**\n\t * Creates a {@link module:engine/model/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * For example, to iterate over all items in the entire document root:\n\t *\n\t * ```ts\n\t * // Create a range spanning over the entire root content:\n\t * const range = editor.model.createRangeIn( editor.model.document.getRoot() );\n\t *\n\t * // Iterate over all items in this range:\n\t * for ( const value of range.getWalker() ) {\n\t * \tconsole.log( value.item );\n\t * }\n\t * ```\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t */ getWalker(options = {}) {\n        options.boundaries = this;\n        return new TreeWalker(options);\n    }\n    /**\n\t * Returns an iterator that iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/model/item~Item model items},\n\t * not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t */ *getItems(options = {}) {\n        options.boundaries = this;\n        options.ignoreElementEnd = true;\n        const treeWalker = new TreeWalker(options);\n        for (const value of treeWalker){\n            yield value.item;\n        }\n    }\n    /**\n\t * Returns an iterator that iterates over all {@link module:engine/model/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/model/position~Position positions}, not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t */ *getPositions(options = {}) {\n        options.boundaries = this;\n        const treeWalker = new TreeWalker(options);\n        yield treeWalker.position;\n        for (const value of treeWalker){\n            yield value.nextPosition;\n        }\n    }\n    /**\n\t * Returns a range that is a result of transforming this range by given `operation`.\n\t *\n\t * **Note:** transformation may break one range into multiple ranges (for example, when a part of the range is\n\t * moved to a different part of document tree). For this reason, an array is returned by this method and it\n\t * may contain one or more `Range` instances.\n\t *\n\t * @param operation Operation to transform range by.\n\t * @returns Range which is the result of transformation.\n\t */ getTransformedByOperation(operation) {\n        switch(operation.type){\n            case 'insert':\n                return this._getTransformedByInsertOperation(operation);\n            case 'move':\n            case 'remove':\n            case 'reinsert':\n                return this._getTransformedByMoveOperation(operation);\n            case 'split':\n                return [\n                    this._getTransformedBySplitOperation(operation)\n                ];\n            case 'merge':\n                return [\n                    this._getTransformedByMergeOperation(operation)\n                ];\n        }\n        return [\n            new Range(this.start, this.end)\n        ];\n    }\n    /**\n\t * Returns a range that is a result of transforming this range by multiple `operations`.\n\t *\n\t * @see ~Range#getTransformedByOperation\n\t * @param operations Operations to transform the range by.\n\t * @returns Range which is the result of transformation.\n\t */ getTransformedByOperations(operations) {\n        const ranges = [\n            new Range(this.start, this.end)\n        ];\n        for (const operation of operations){\n            for(let i = 0; i < ranges.length; i++){\n                const result = ranges[i].getTransformedByOperation(operation);\n                ranges.splice(i, 1, ...result);\n                i += result.length - 1;\n            }\n        }\n        // It may happen that a range is split into two, and then the part of second \"piece\" is moved into first\n        // \"piece\". In this case we will have incorrect third range, which should not be included in the result --\n        // because it is already included in the first \"piece\". In this loop we are looking for all such ranges that\n        // are inside other ranges and we simply remove them.\n        for(let i = 0; i < ranges.length; i++){\n            const range = ranges[i];\n            for(let j = i + 1; j < ranges.length; j++){\n                const next = ranges[j];\n                if (range.containsRange(next) || next.containsRange(range) || range.isEqual(next)) {\n                    ranges.splice(j, 1);\n                }\n            }\n        }\n        return ranges;\n    }\n    /**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of the range's both ends (in which the entire range is contained).\n\t */ getCommonAncestor() {\n        return this.start.getCommonAncestor(this.end);\n    }\n    /**\n\t * Returns an {@link module:engine/model/element~Element Element} contained by the range.\n\t * The element will be returned when it is the **only** node within the range and **fully–contained**\n\t * at the same time.\n\t */ getContainedElement() {\n        if (this.isCollapsed) {\n            return null;\n        }\n        const nodeAfterStart = this.start.nodeAfter;\n        const nodeBeforeEnd = this.end.nodeBefore;\n        if (nodeAfterStart && nodeAfterStart.is('element') && nodeAfterStart === nodeBeforeEnd) {\n            return nodeAfterStart;\n        }\n        return null;\n    }\n    /**\n\t * Converts `Range` to plain object and returns it.\n\t *\n\t * @returns `Node` converted to plain object.\n\t */ toJSON() {\n        return {\n            start: this.start.toJSON(),\n            end: this.end.toJSON()\n        };\n    }\n    /**\n\t * Returns a new range that is equal to current range.\n\t */ clone() {\n        return new this.constructor(this.start, this.end);\n    }\n    /**\n\t * Returns a result of transforming a copy of this range by insert operation.\n\t *\n\t * One or more ranges may be returned as a result of this transformation.\n\t *\n\t * @internal\n\t */ _getTransformedByInsertOperation(operation, spread = false) {\n        return this._getTransformedByInsertion(operation.position, operation.howMany, spread);\n    }\n    /**\n\t * Returns a result of transforming a copy of this range by move operation.\n\t *\n\t * One or more ranges may be returned as a result of this transformation.\n\t *\n\t * @internal\n\t */ _getTransformedByMoveOperation(operation, spread = false) {\n        const sourcePosition = operation.sourcePosition;\n        const howMany = operation.howMany;\n        const targetPosition = operation.targetPosition;\n        return this._getTransformedByMove(sourcePosition, targetPosition, howMany, spread);\n    }\n    /**\n\t * Returns a result of transforming a copy of this range by split operation.\n\t *\n\t * Always one range is returned. The transformation is done in a way to not break the range.\n\t *\n\t * @internal\n\t */ _getTransformedBySplitOperation(operation) {\n        const start = this.start._getTransformedBySplitOperation(operation);\n        let end = this.end._getTransformedBySplitOperation(operation);\n        if (this.end.isEqual(operation.insertionPosition)) {\n            end = this.end.getShiftedBy(1);\n        }\n        // Below may happen when range contains graveyard element used by split operation.\n        if (start.root != end.root) {\n            // End position was next to the moved graveyard element and was moved with it.\n            // Fix it by using old `end` which has proper `root`.\n            end = this.end.getShiftedBy(-1);\n        }\n        return new Range(start, end);\n    }\n    /**\n\t * Returns a result of transforming a copy of this range by merge operation.\n\t *\n\t * Always one range is returned. The transformation is done in a way to not break the range.\n\t *\n\t * @internal\n\t */ _getTransformedByMergeOperation(operation) {\n        // Special case when the marker is set on \"the closing tag\" of an element. Marker can be set like that during\n        // transformations, especially when a content of a few block elements were removed. For example:\n        //\n        // {} is the transformed range, [] is the removed range.\n        // <p>F[o{o</p><p>B}ar</p><p>Xy]z</p>\n        //\n        // <p>Fo{o</p><p>B}ar</p><p>z</p>\n        // <p>F{</p><p>B}ar</p><p>z</p>\n        // <p>F{</p>}<p>z</p>\n        // <p>F{}z</p>\n        //\n        if (this.start.isEqual(operation.targetPosition) && this.end.isEqual(operation.deletionPosition)) {\n            return new Range(this.start);\n        }\n        let start = this.start._getTransformedByMergeOperation(operation);\n        let end = this.end._getTransformedByMergeOperation(operation);\n        if (start.root != end.root) {\n            // This happens when the end position was next to the merged (deleted) element.\n            // Then, the end position was moved to the graveyard root. In this case we need to fix\n            // the range cause its boundaries would be in different roots.\n            end = this.end.getShiftedBy(-1);\n        }\n        if (start.isAfter(end)) {\n            // This happens in three following cases:\n            //\n            // Case 1: Merge operation source position is before the target position (due to some transformations, OT, etc.)\n            //         This means that start can be moved before the end of the range.\n            //\n            // Before: <p>a{a</p><p>b}b</p><p>cc</p>\n            // Merge:  <p>b}b</p><p>cca{a</p>\n            // Fix:    <p>{b}b</p><p>ccaa</p>\n            //\n            // Case 2: Range start is before merged node but not directly.\n            //         Result should include all nodes that were in the original range.\n            //\n            // Before: <p>aa</p>{<p>cc</p><p>b}b</p>\n            // Merge:  <p>aab}b</p>{<p>cc</p>\n            // Fix:    <p>aa{bb</p><p>cc</p>}\n            //\n            //         The range is expanded by an additional `b` letter but it is better than dropping the whole `cc` paragraph.\n            //\n            // Case 3: Range start is directly before merged node.\n            //         Resulting range should include only nodes from the merged element:\n            //\n            // Before: <p>aa</p>{<p>b}b</p><p>cc</p>\n            // Merge:  <p>aab}b</p>{<p>cc</p>\n            // Fix:    <p>aa{b}b</p><p>cc</p>\n            //\n            if (operation.sourcePosition.isBefore(operation.targetPosition)) {\n                // Case 1.\n                start = Position._createAt(end);\n                start.offset = 0;\n            } else {\n                if (!operation.deletionPosition.isEqual(start)) {\n                    // Case 2.\n                    end = operation.deletionPosition;\n                }\n                // In both case 2 and 3 start is at the end of the merge-to element.\n                start = operation.targetPosition;\n            }\n            return new Range(start, end);\n        }\n        return new Range(start, end);\n    }\n    /**\n\t * Returns an array containing one or two {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by inserting `howMany` nodes at `insertPosition`. Two {@link ~Range ranges} are\n\t * returned if the insertion was inside this {@link ~Range range} and `spread` is set to `true`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 1 ] ), 2 );\n\t * // transformed array has one range from [ 4, 7 ] to [ 6, 0, 1 ]\n\t *\n\t * transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 4, 0, 0 ] ), 4 );\n\t * // transformed array has one range from [ 2, 7 ] to [ 4, 0, 5 ]\n\t *\n\t * transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4 );\n\t * // transformed array has one range, which is equal to original range\n\t *\n\t * transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4, true );\n\t * // transformed array has two ranges: from [ 2, 7 ] to [ 3, 2 ] and from [ 3, 6 ] to [ 4, 0, 1 ]\n\t * ```\n\t *\n\t * @internal\n\t * @param insertPosition Position where nodes are inserted.\n\t * @param howMany How many nodes are inserted.\n\t * @param spread Flag indicating whether this range should be spread if insertion\n\t * was inside the range. Defaults to `false`.\n\t * @returns Result of the transformation.\n\t */ _getTransformedByInsertion(insertPosition, howMany, spread = false) {\n        if (spread && this.containsPosition(insertPosition)) {\n            // Range has to be spread. The first part is from original start to the spread point.\n            // The other part is from spread point to the original end, but transformed by\n            // insertion to reflect insertion changes.\n            return [\n                new Range(this.start, insertPosition),\n                new Range(insertPosition.getShiftedBy(howMany), this.end._getTransformedByInsertion(insertPosition, howMany))\n            ];\n        } else {\n            const range = new Range(this.start, this.end);\n            range.start = range.start._getTransformedByInsertion(insertPosition, howMany);\n            range.end = range.end._getTransformedByInsertion(insertPosition, howMany);\n            return [\n                range\n            ];\n        }\n    }\n    /**\n\t * Returns an array containing {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t *\n\t * @internal\n\t * @param sourcePosition Position from which nodes are moved.\n\t * @param targetPosition Position to where nodes are moved.\n\t * @param howMany How many nodes are moved.\n\t * @param spread Whether the range should be spread if the move points inside the range.\n\t * @returns  Result of the transformation.\n\t */ _getTransformedByMove(sourcePosition, targetPosition, howMany, spread = false) {\n        // Special case for transforming a collapsed range. Just transform it like a position.\n        if (this.isCollapsed) {\n            const newPos = this.start._getTransformedByMove(sourcePosition, targetPosition, howMany);\n            return [\n                new Range(newPos)\n            ];\n        }\n        // Special case for transformation when a part of the range is moved towards the range.\n        //\n        // Examples:\n        //\n        // <div><p>ab</p><p>c[d</p></div><p>e]f</p> --> <div><p>ab</p></div><p>c[d</p><p>e]f</p>\n        // <p>e[f</p><div><p>a]b</p><p>cd</p></div> --> <p>e[f</p><p>a]b</p><div><p>cd</p></div>\n        //\n        // Without this special condition, the default algorithm leaves an \"artifact\" range from one of `differenceSet` parts:\n        //\n        // <div><p>ab</p><p>c[d</p></div><p>e]f</p> --> <div><p>ab</p>{</div>}<p>c[d</p><p>e]f</p>\n        //\n        // This special case is applied only if the range is to be kept together (not spread).\n        const moveRange = Range._createFromPositionAndShift(sourcePosition, howMany);\n        const insertPosition = targetPosition._getTransformedByDeletion(sourcePosition, howMany);\n        if (this.containsPosition(targetPosition) && !spread) {\n            if (moveRange.containsPosition(this.start) || moveRange.containsPosition(this.end)) {\n                const start = this.start._getTransformedByMove(sourcePosition, targetPosition, howMany);\n                const end = this.end._getTransformedByMove(sourcePosition, targetPosition, howMany);\n                return [\n                    new Range(start, end)\n                ];\n            }\n        }\n        // Default algorithm.\n        let result;\n        const differenceSet = this.getDifference(moveRange);\n        let difference = null;\n        const common = this.getIntersection(moveRange);\n        if (differenceSet.length == 1) {\n            // `moveRange` and this range may intersect but may be separate.\n            difference = new Range(differenceSet[0].start._getTransformedByDeletion(sourcePosition, howMany), differenceSet[0].end._getTransformedByDeletion(sourcePosition, howMany));\n        } else if (differenceSet.length == 2) {\n            // `moveRange` is inside this range.\n            difference = new Range(this.start, this.end._getTransformedByDeletion(sourcePosition, howMany));\n        } // else, `moveRange` contains this range.\n        if (difference) {\n            result = difference._getTransformedByInsertion(insertPosition, howMany, common !== null || spread);\n        } else {\n            result = [];\n        }\n        if (common) {\n            const transformedCommon = new Range(common.start._getCombined(moveRange.start, insertPosition), common.end._getCombined(moveRange.start, insertPosition));\n            if (result.length == 2) {\n                result.splice(1, 0, transformedCommon);\n            } else {\n                result.push(transformedCommon);\n            }\n        }\n        return result;\n    }\n    /**\n\t * Returns a copy of this range that is transformed by deletion of `howMany` nodes from `deletePosition`.\n\t *\n\t * If the deleted range is intersecting with the transformed range, the transformed range will be shrank.\n\t *\n\t * If the deleted range contains transformed range, `null` will be returned.\n\t *\n\t * @internal\n\t * @param deletionPosition Position from which nodes are removed.\n\t * @param howMany How many nodes are removed.\n\t * @returns Result of the transformation.\n\t */ _getTransformedByDeletion(deletePosition, howMany) {\n        let newStart = this.start._getTransformedByDeletion(deletePosition, howMany);\n        let newEnd = this.end._getTransformedByDeletion(deletePosition, howMany);\n        if (newStart == null && newEnd == null) {\n            return null;\n        }\n        if (newStart == null) {\n            newStart = deletePosition;\n        }\n        if (newEnd == null) {\n            newEnd = deletePosition;\n        }\n        return new Range(newStart, newEnd);\n    }\n    /**\n\t * Creates a new range, spreading from specified {@link module:engine/model/position~Position position} to a position moved by\n\t * given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t *\n\t * @internal\n\t * @param position Beginning of the range.\n\t * @param shift How long the range should be.\n\t */ static _createFromPositionAndShift(position, shift) {\n        const start = position;\n        const end = position.getShiftedBy(shift);\n        return shift > 0 ? new this(start, end) : new this(end, start);\n    }\n    /**\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @internal\n\t * @param element Element which is a parent for the range.\n\t */ static _createIn(element) {\n        return new this(Position._createAt(element, 0), Position._createAt(element, element.maxOffset));\n    }\n    /**\n\t * Creates a range that starts before given {@link module:engine/model/item~Item model item} and ends after it.\n\t *\n\t * @internal\n\t */ static _createOn(item) {\n        return this._createFromPositionAndShift(Position._createBefore(item), item.offsetSize);\n    }\n    /**\n\t * Combines all ranges from the passed array into a one range. At least one range has to be passed.\n\t * Passed ranges must not have common parts.\n\t *\n\t * The first range from the array is a reference range. If other ranges start or end on the exactly same position where\n\t * the reference range, they get combined into one range.\n\t *\n\t * ```\n\t * [  ][]  [    ][ ][             ][ ][]  [  ]  // Passed ranges, shown sorted\n\t * [    ]                                       // The result of the function if the first range was a reference range.\n\t *         [                           ]        // The result of the function if the third-to-seventh range was a reference range.\n\t *                                        [  ]  // The result of the function if the last range was a reference range.\n\t * ```\n\t *\n\t * @internal\n\t * @param ranges Ranges to combine.\n\t * @returns Combined range.\n\t */ static _createFromRanges(ranges) {\n        if (ranges.length === 0) {\n            /**\n\t\t\t * At least one range has to be passed to\n\t\t\t * {@link module:engine/model/range~Range._createFromRanges `Range._createFromRanges()`}.\n\t\t\t *\n\t\t\t * @error range-create-from-ranges-empty-array\n\t\t\t */ throw new CKEditorError('range-create-from-ranges-empty-array', null);\n        } else if (ranges.length == 1) {\n            return ranges[0].clone();\n        }\n        // 1. Set the first range in `ranges` array as a reference range.\n        // If we are going to return just a one range, one of the ranges need to be the reference one.\n        // Other ranges will be stuck to that range, if possible.\n        const ref = ranges[0];\n        // 2. Sort all the ranges, so it's easier to process them.\n        ranges.sort((a, b)=>{\n            return a.start.isAfter(b.start) ? 1 : -1;\n        });\n        // 3. Check at which index the reference range is now.\n        const refIndex = ranges.indexOf(ref);\n        // 4. At this moment we don't need the original range.\n        // We are going to modify the result, and we need to return a new instance of Range.\n        // We have to create a copy of the reference range.\n        const result = new this(ref.start, ref.end);\n        // 5. Ranges should be checked and glued starting from the range that is closest to the reference range.\n        // Since ranges are sorted, start with the range with index that is closest to reference range index.\n        for(let i = refIndex - 1; i >= 0; i--){\n            if (ranges[i].end.isEqual(result.start)) {\n                result.start = Position._createAt(ranges[i].start);\n            } else {\n                break;\n            }\n        }\n        // 6. Ranges should be checked and glued starting from the range that is closest to the reference range.\n        // Since ranges are sorted, start with the range with index that is closest to reference range index.\n        for(let i = refIndex + 1; i < ranges.length; i++){\n            if (ranges[i].start.isEqual(result.end)) {\n                result.end = Position._createAt(ranges[i].end);\n            } else {\n                break;\n            }\n        }\n        return result;\n    }\n    /**\n\t * Creates a `Range` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param json Plain object to be converted to `Range`.\n\t * @param doc Document object that will be range owner.\n\t * @returns `Range` instance created using given plain object.\n\t */ static fromJSON(json, doc) {\n        return new this(Position.fromJSON(json.start, doc), Position.fromJSON(json.end, doc));\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRange.prototype.is = function(type) {\n    return type === 'range' || type === 'model:range';\n};\n\n/**\n * Maps elements, positions and markers between the {@link module:engine/view/document~Document view} and\n * the {@link module:engine/model/model model}.\n *\n * The instance of the Mapper used for the editing pipeline is available in\n * {@link module:engine/controller/editingcontroller~EditingController#mapper `editor.editing.mapper`}.\n *\n * Mapper uses bound elements to find corresponding elements and positions, so, to get proper results,\n * all model elements should be {@link module:engine/conversion/mapper~Mapper#bindElements bound}.\n *\n * To map the complex model to/from view relations, you may provide custom callbacks for the\n * {@link module:engine/conversion/mapper~Mapper#event:modelToViewPosition modelToViewPosition event} and\n * {@link module:engine/conversion/mapper~Mapper#event:viewToModelPosition viewToModelPosition event} that are fired whenever\n * a position mapping request occurs.\n * Those events are fired by the {@link module:engine/conversion/mapper~Mapper#toViewPosition toViewPosition}\n * and {@link module:engine/conversion/mapper~Mapper#toModelPosition toModelPosition} methods. `Mapper` adds its own default callbacks\n * with `'lowest'` priority. To override default `Mapper` mapping, add custom callback with higher priority and\n * stop the event.\n */ class Mapper extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * Model element to view element mapping.\n\t */ _modelToViewMapping = new WeakMap();\n    /**\n\t * View element to model element mapping.\n\t */ _viewToModelMapping = new WeakMap();\n    /**\n\t * A map containing callbacks between view element names and functions evaluating length of view elements\n\t * in model.\n\t */ _viewToModelLengthCallbacks = new Map();\n    /**\n\t * Model marker name to view elements mapping.\n\t *\n\t * Keys are `String`s while values are `Set`s with {@link module:engine/view/element~Element view elements}.\n\t * One marker (name) can be mapped to multiple elements.\n\t */ _markerNameToElements = new Map();\n    /**\n\t * View element to model marker names mapping.\n\t *\n\t * This is reverse to {@link ~Mapper#_markerNameToElements} map.\n\t */ _elementToMarkerNames = new Map();\n    /**\n\t * The map of removed view elements with their current root (used for deferred unbinding).\n\t */ _deferredBindingRemovals = new Map();\n    /**\n\t * Stores marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element\n\t * has been removed, moved or renamed).\n\t */ _unboundMarkerNames = new Set();\n    /**\n\t * Creates an instance of the mapper.\n\t */ constructor(){\n        super();\n        // Default mapper algorithm for mapping model position to view position.\n        this.on('modelToViewPosition', (evt, data)=>{\n            if (data.viewPosition) {\n                return;\n            }\n            const viewContainer = this._modelToViewMapping.get(data.modelPosition.parent);\n            if (!viewContainer) {\n                /**\n\t\t\t\t * A model position could not be mapped to the view because the parent of the model position\n\t\t\t\t * does not have a mapped view element (might have not been converted yet or it has no converter).\n\t\t\t\t *\n\t\t\t\t * Make sure that the model element is correctly converted to the view.\n\t\t\t\t *\n\t\t\t\t * @error mapping-model-position-view-parent-not-found\n\t\t\t\t */ throw new CKEditorError('mapping-model-position-view-parent-not-found', this, {\n                    modelPosition: data.modelPosition\n                });\n            }\n            data.viewPosition = this.findPositionIn(viewContainer, data.modelPosition.offset);\n        }, {\n            priority: 'low'\n        });\n        // Default mapper algorithm for mapping view position to model position.\n        this.on('viewToModelPosition', (evt, data)=>{\n            if (data.modelPosition) {\n                return;\n            }\n            const viewBlock = this.findMappedViewAncestor(data.viewPosition);\n            const modelParent = this._viewToModelMapping.get(viewBlock);\n            const modelOffset = this._toModelOffset(data.viewPosition.parent, data.viewPosition.offset, viewBlock);\n            data.modelPosition = Position._createAt(modelParent, modelOffset);\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * Marks model and view elements as corresponding. Corresponding elements can be retrieved by using\n\t * the {@link module:engine/conversion/mapper~Mapper#toModelElement toModelElement} and\n\t * {@link module:engine/conversion/mapper~Mapper#toViewElement toViewElement} methods.\n\t * The information that elements are bound is also used to translate positions.\n\t *\n\t * @param modelElement Model element.\n\t * @param viewElement View element.\n\t */ bindElements(modelElement, viewElement) {\n        this._modelToViewMapping.set(modelElement, viewElement);\n        this._viewToModelMapping.set(viewElement, modelElement);\n    }\n    /**\n\t * Unbinds the given {@link module:engine/view/element~Element view element} from the map.\n\t *\n\t * **Note:** view-to-model binding will be removed, if it existed. However, corresponding model-to-view binding\n\t * will be removed only if model element is still bound to the passed `viewElement`.\n\t *\n\t * This behavior allows for re-binding model element to another view element without fear of losing the new binding\n\t * when the previously bound view element is unbound.\n\t *\n\t * @param viewElement View element to unbind.\n\t * @param options The options object.\n\t * @param options.defer Controls whether the binding should be removed immediately or deferred until a\n\t * {@link #flushDeferredBindings `flushDeferredBindings()`} call.\n\t */ unbindViewElement(viewElement, options = {}) {\n        const modelElement = this.toModelElement(viewElement);\n        if (this._elementToMarkerNames.has(viewElement)) {\n            for (const markerName of this._elementToMarkerNames.get(viewElement)){\n                this._unboundMarkerNames.add(markerName);\n            }\n        }\n        if (options.defer) {\n            this._deferredBindingRemovals.set(viewElement, viewElement.root);\n        } else {\n            this._viewToModelMapping.delete(viewElement);\n            if (this._modelToViewMapping.get(modelElement) == viewElement) {\n                this._modelToViewMapping.delete(modelElement);\n            }\n        }\n    }\n    /**\n\t * Unbinds the given {@link module:engine/model/element~Element model element} from the map.\n\t *\n\t * **Note:** the model-to-view binding will be removed, if it existed. However, the corresponding view-to-model binding\n\t * will be removed only if the view element is still bound to the passed `modelElement`.\n\t *\n\t * This behavior lets for re-binding view element to another model element without fear of losing the new binding\n\t * when the previously bound model element is unbound.\n\t *\n\t * @param modelElement Model element to unbind.\n\t */ unbindModelElement(modelElement) {\n        const viewElement = this.toViewElement(modelElement);\n        this._modelToViewMapping.delete(modelElement);\n        if (this._viewToModelMapping.get(viewElement) == modelElement) {\n            this._viewToModelMapping.delete(viewElement);\n        }\n    }\n    /**\n\t * Binds the given marker name with the given {@link module:engine/view/element~Element view element}. The element\n\t * will be added to the current set of elements bound with the given marker name.\n\t *\n\t * @param element Element to bind.\n\t * @param name Marker name.\n\t */ bindElementToMarker(element, name) {\n        const elements = this._markerNameToElements.get(name) || new Set();\n        elements.add(element);\n        const names = this._elementToMarkerNames.get(element) || new Set();\n        names.add(name);\n        this._markerNameToElements.set(name, elements);\n        this._elementToMarkerNames.set(element, names);\n    }\n    /**\n\t * Unbinds an element from given marker name.\n\t *\n\t * @param element Element to unbind.\n\t * @param name Marker name.\n\t */ unbindElementFromMarkerName(element, name) {\n        const nameToElements = this._markerNameToElements.get(name);\n        if (nameToElements) {\n            nameToElements.delete(element);\n            if (nameToElements.size == 0) {\n                this._markerNameToElements.delete(name);\n            }\n        }\n        const elementToNames = this._elementToMarkerNames.get(element);\n        if (elementToNames) {\n            elementToNames.delete(name);\n            if (elementToNames.size == 0) {\n                this._elementToMarkerNames.delete(element);\n            }\n        }\n    }\n    /**\n\t * Returns all marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element\n\t * has been removed, moved or renamed) since the last flush. After returning, the marker names list is cleared.\n\t */ flushUnboundMarkerNames() {\n        const markerNames = Array.from(this._unboundMarkerNames);\n        this._unboundMarkerNames.clear();\n        return markerNames;\n    }\n    /**\n\t * Unbinds all deferred binding removals of view elements that in the meantime were not re-attached to some root or document fragment.\n\t *\n\t * See: {@link #unbindViewElement `unbindViewElement()`}.\n\t */ flushDeferredBindings() {\n        for (const [viewElement, root] of this._deferredBindingRemovals){\n            // Unbind it only if it wasn't re-attached to some root or document fragment.\n            if (viewElement.root == root) {\n                this.unbindViewElement(viewElement);\n            }\n        }\n        this._deferredBindingRemovals = new Map();\n    }\n    /**\n\t * Removes all model to view and view to model bindings.\n\t */ clearBindings() {\n        this._modelToViewMapping = new WeakMap();\n        this._viewToModelMapping = new WeakMap();\n        this._markerNameToElements = new Map();\n        this._elementToMarkerNames = new Map();\n        this._unboundMarkerNames = new Set();\n        this._deferredBindingRemovals = new Map();\n    }\n    toModelElement(viewElement) {\n        return this._viewToModelMapping.get(viewElement);\n    }\n    toViewElement(modelElement) {\n        return this._modelToViewMapping.get(modelElement);\n    }\n    /**\n\t * Gets the corresponding model range.\n\t *\n\t * @param viewRange View range.\n\t * @returns Corresponding model range.\n\t */ toModelRange(viewRange) {\n        return new Range(this.toModelPosition(viewRange.start), this.toModelPosition(viewRange.end));\n    }\n    /**\n\t * Gets the corresponding view range.\n\t *\n\t * @param modelRange Model range.\n\t * @returns Corresponding view range.\n\t */ toViewRange(modelRange) {\n        return new Range$1(this.toViewPosition(modelRange.start), this.toViewPosition(modelRange.end));\n    }\n    /**\n\t * Gets the corresponding model position.\n\t *\n\t * @fires viewToModelPosition\n\t * @param viewPosition View position.\n\t * @returns Corresponding model position.\n\t */ toModelPosition(viewPosition) {\n        const data = {\n            viewPosition,\n            mapper: this\n        };\n        this.fire('viewToModelPosition', data);\n        return data.modelPosition;\n    }\n    /**\n\t * Gets the corresponding view position.\n\t *\n\t * @fires modelToViewPosition\n\t * @param modelPosition Model position.\n\t * @param options Additional options for position mapping process.\n\t * @param options.isPhantom Should be set to `true` if the model position to map is pointing to a place\n\t * in model tree which no longer exists. For example, it could be an end of a removed model range.\n\t * @returns Corresponding view position.\n\t */ toViewPosition(modelPosition, options = {}) {\n        const data = {\n            modelPosition,\n            mapper: this,\n            isPhantom: options.isPhantom\n        };\n        this.fire('modelToViewPosition', data);\n        return data.viewPosition;\n    }\n    /**\n\t * Gets all view elements bound to the given marker name.\n\t *\n\t * @param name Marker name.\n\t * @returns View elements bound with the given marker name or `null`\n\t * if no elements are bound to the given marker name.\n\t */ markerNameToElements(name) {\n        const boundElements = this._markerNameToElements.get(name);\n        if (!boundElements) {\n            return null;\n        }\n        const elements = new Set();\n        for (const element of boundElements){\n            if (element.is('attributeElement')) {\n                for (const clone of element.getElementsWithSameId()){\n                    elements.add(clone);\n                }\n            } else {\n                elements.add(element);\n            }\n        }\n        return elements;\n    }\n    /**\n\t * Registers a callback that evaluates the length in the model of a view element with the given name.\n\t *\n\t * The callback is fired with one argument, which is a view element instance. The callback is expected to return\n\t * a number representing the length of the view element in the model.\n\t *\n\t * ```ts\n\t * // List item in view may contain nested list, which have other list items. In model though,\n\t * // the lists are represented by flat structure. Because of those differences, length of list view element\n\t * // may be greater than one. In the callback it's checked how many nested list items are in evaluated list item.\n\t *\n\t * function getViewListItemLength( element ) {\n\t * \tlet length = 1;\n\t *\n\t * \tfor ( let child of element.getChildren() ) {\n\t * \t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t * \t\t\tfor ( let item of child.getChildren() ) {\n\t * \t\t\t\tlength += getViewListItemLength( item );\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t *\n\t * \treturn length;\n\t * }\n\t *\n\t * mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t * ```\n\t *\n\t * @param viewElementName Name of view element for which callback is registered.\n\t * @param lengthCallback Function return a length of view element instance in model.\n\t */ registerViewToModelLength(viewElementName, lengthCallback) {\n        this._viewToModelLengthCallbacks.set(viewElementName, lengthCallback);\n    }\n    /**\n\t * For the given `viewPosition`, finds and returns the closest ancestor of this position that has a mapping to\n\t * the model.\n\t *\n\t * @param viewPosition Position for which a mapped ancestor should be found.\n\t */ findMappedViewAncestor(viewPosition) {\n        let parent = viewPosition.parent;\n        while(!this._viewToModelMapping.has(parent)){\n            parent = parent.parent;\n        }\n        return parent;\n    }\n    /**\n\t * Calculates model offset based on the view position and the block element.\n\t *\n\t * Example:\n\t *\n\t * ```html\n\t * <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, p ) -> 5\n\t * ```\n\t *\n\t * Is a sum of:\n\t *\n\t * ```html\n\t * <p>foo|<b>bar</b></p> // _toModelOffset( p, 3, p ) -> 3\n\t * <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, b ) -> 2\n\t * ```\n\t *\n\t * @param viewParent Position parent.\n\t * @param viewOffset Position offset.\n\t * @param viewBlock Block used as a base to calculate offset.\n\t * @returns Offset in the model.\n\t */ _toModelOffset(viewParent, viewOffset, viewBlock) {\n        if (viewBlock != viewParent) {\n            // See example.\n            const offsetToParentStart = this._toModelOffset(viewParent.parent, viewParent.index, viewBlock);\n            const offsetInParent = this._toModelOffset(viewParent, viewOffset, viewParent);\n            return offsetToParentStart + offsetInParent;\n        }\n        // viewBlock == viewParent, so we need to calculate the offset in the parent element.\n        // If the position is a text it is simple (\"ba|r\" -> 2).\n        if (viewParent.is('$text')) {\n            return viewOffset;\n        }\n        // If the position is in an element we need to sum lengths of siblings ( <b> bar </b> foo | -> 3 + 3 = 6 ).\n        let modelOffset = 0;\n        for(let i = 0; i < viewOffset; i++){\n            modelOffset += this.getModelLength(viewParent.getChild(i));\n        }\n        return modelOffset;\n    }\n    /**\n\t * Gets the length of the view element in the model.\n\t *\n\t * The length is calculated as follows:\n\t * * if a {@link #registerViewToModelLength length mapping callback} is provided for the given `viewNode`, it is used to\n\t * evaluate the model length (`viewNode` is used as first and only parameter passed to the callback),\n\t * * length of a {@link module:engine/view/text~Text text node} is equal to the length of its\n\t * {@link module:engine/view/text~Text#data data},\n\t * * length of a {@link module:engine/view/uielement~UIElement ui element} is equal to 0,\n\t * * length of a mapped {@link module:engine/view/element~Element element} is equal to 1,\n\t * * length of a non-mapped {@link module:engine/view/element~Element element} is equal to the length of its children.\n\t *\n\t * Examples:\n\t *\n\t * ```\n\t * foo                          -> 3 // Text length is equal to its data length.\n\t * <p>foo</p>                   -> 1 // Length of an element which is mapped is by default equal to 1.\n\t * <b>foo</b>                   -> 3 // Length of an element which is not mapped is a length of its children.\n\t * <div><p>x</p><p>y</p></div>  -> 2 // Assuming that <div> is not mapped and <p> are mapped.\n\t * ```\n\t *\n\t * @param viewNode View node.\n\t * @returns Length of the node in the tree model.\n\t */ getModelLength(viewNode) {\n        if (this._viewToModelLengthCallbacks.get(viewNode.name)) {\n            const callback = this._viewToModelLengthCallbacks.get(viewNode.name);\n            return callback(viewNode);\n        } else if (this._viewToModelMapping.has(viewNode)) {\n            return 1;\n        } else if (viewNode.is('$text')) {\n            return viewNode.data.length;\n        } else if (viewNode.is('uiElement')) {\n            return 0;\n        } else {\n            let len = 0;\n            for (const child of viewNode.getChildren()){\n                len += this.getModelLength(child);\n            }\n            return len;\n        }\n    }\n    /**\n\t * Finds the position in the view node (or in its children) with the expected model offset.\n\t *\n\t * Example:\n\t *\n\t * ```\n\t * <p>fo<b>bar</b>bom</p> -> expected offset: 4\n\t *\n\t * findPositionIn( p, 4 ):\n\t * <p>|fo<b>bar</b>bom</p> -> expected offset: 4, actual offset: 0\n\t * <p>fo|<b>bar</b>bom</p> -> expected offset: 4, actual offset: 2\n\t * <p>fo<b>bar</b>|bom</p> -> expected offset: 4, actual offset: 5 -> we are too far\n\t *\n\t * findPositionIn( b, 4 - ( 5 - 3 ) ):\n\t * <p>fo<b>|bar</b>bom</p> -> expected offset: 2, actual offset: 0\n\t * <p>fo<b>bar|</b>bom</p> -> expected offset: 2, actual offset: 3 -> we are too far\n\t *\n\t * findPositionIn( bar, 2 - ( 3 - 3 ) ):\n\t * We are in the text node so we can simple find the offset.\n\t * <p>fo<b>ba|r</b>bom</p> -> expected offset: 2, actual offset: 2 -> position found\n\t * ```\n\t *\n\t * @param viewParent Tree view element in which we are looking for the position.\n\t * @param expectedOffset Expected offset.\n\t * @returns Found position.\n\t */ findPositionIn(viewParent, expectedOffset) {\n        // Last scanned view node.\n        let viewNode;\n        // Length of the last scanned view node.\n        let lastLength = 0;\n        let modelOffset = 0;\n        let viewOffset = 0;\n        // In the text node it is simple: the offset in the model equals the offset in the text.\n        if (viewParent.is('$text')) {\n            return new Position$1(viewParent, expectedOffset);\n        }\n        // In other cases we add lengths of child nodes to find the proper offset.\n        // If it is smaller we add the length.\n        while(modelOffset < expectedOffset){\n            viewNode = viewParent.getChild(viewOffset);\n            lastLength = this.getModelLength(viewNode);\n            modelOffset += lastLength;\n            viewOffset++;\n        }\n        // If it equals we found the position.\n        if (modelOffset == expectedOffset) {\n            return this._moveViewPositionToTextNode(new Position$1(viewParent, viewOffset));\n        } else {\n            // ( modelOffset - lastLength ) is the offset to the child we enter,\n            // so we subtract it from the expected offset to fine the offset in the child.\n            return this.findPositionIn(viewNode, expectedOffset - (modelOffset - lastLength));\n        }\n    }\n    /**\n\t * Because we prefer positions in the text nodes over positions next to text nodes, if the view position was next to a text node,\n\t * it moves it into the text node instead.\n\t *\n\t * ```\n\t * <p>[]<b>foo</b></p> -> <p>[]<b>foo</b></p> // do not touch if position is not directly next to text\n\t * <p>foo[]<b>foo</b></p> -> <p>foo{}<b>foo</b></p> // move to text node\n\t * <p><b>[]foo</b></p> -> <p><b>{}foo</b></p> // move to text node\n\t * ```\n\t *\n\t * @param viewPosition Position potentially next to the text node.\n\t * @returns Position in the text node if possible.\n\t */ _moveViewPositionToTextNode(viewPosition) {\n        // If the position is just after a text node, put it at the end of that text node.\n        // If the position is just before a text node, put it at the beginning of that text node.\n        const nodeBefore = viewPosition.nodeBefore;\n        const nodeAfter = viewPosition.nodeAfter;\n        if (nodeBefore instanceof Text$1) {\n            return new Position$1(nodeBefore, nodeBefore.data.length);\n        } else if (nodeAfter instanceof Text$1) {\n            return new Position$1(nodeAfter, 0);\n        }\n        // Otherwise, just return the given position.\n        return viewPosition;\n    }\n}\n\n/**\n * Manages a list of consumable values for the {@link module:engine/model/item~Item model items}.\n *\n * Consumables are various aspects of the model. A model item can be broken down into separate, single properties that might be\n * taken into consideration when converting that item.\n *\n * `ModelConsumable` is used by {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} while analyzing the changed\n * parts of {@link module:engine/model/document~Document the document}. The added / changed / removed model items are broken down\n * into singular properties (the item itself and its attributes). All those parts are saved in `ModelConsumable`. Then,\n * during conversion, when the given part of a model item is converted (i.e. the view element has been inserted into the view,\n * but without attributes), the consumable value is removed from `ModelConsumable`.\n *\n * For model items, `ModelConsumable` stores consumable values of one of following types: `insert`, `addattribute:<attributeKey>`,\n * `changeattributes:<attributeKey>`, `removeattributes:<attributeKey>`.\n *\n * In most cases, it is enough to let th {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n * gather consumable values, so there is no need to use\n * the {@link module:engine/conversion/modelconsumable~ModelConsumable#add add method} directly.\n * However, it is important to understand how consumable values can be\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed}.\n * See {@link module:engine/conversion/downcasthelpers default downcast converters} for more information.\n *\n * Keep in mind that one conversion event may have multiple callbacks (converters) attached to it. Each of those is\n * able to convert one or more parts of the model. However, when one of those callbacks actually converts\n * something, the others should not, because they would duplicate the results. Using `ModelConsumable` helps to avoid\n * this situation, because callbacks should only convert these values that were not yet consumed from `ModelConsumable`.\n *\n * Consuming multiple values in a single callback:\n *\n * ```ts\n * // Converter for custom `imageBlock` element that might have a `caption` element inside which changes\n * // how the image is displayed in the view:\n * //\n * // Model:\n * //\n * // [imageBlock]\n * //   └─ [caption]\n * //       └─ foo\n * //\n * // View:\n * //\n * // <figure>\n * //   ├─ <img />\n * //   └─ <caption>\n * //       └─ foo\n * modelConversionDispatcher.on( 'insert:imageBlock', ( evt, data, conversionApi ) => {\n * \t// First, consume the `imageBlock` element.\n * \tconversionApi.consumable.consume( data.item, 'insert' );\n *\n * \t// Just create normal image element for the view.\n * \t// Maybe it will be \"decorated\" later.\n * \tconst viewImage = new ViewElement( 'img' );\n * \tconst insertPosition = conversionApi.mapper.toViewPosition( data.range.start );\n * \tconst viewWriter = conversionApi.writer;\n *\n * \t// Check if the `imageBlock` element has children.\n * \tif ( data.item.childCount > 0 ) {\n * \t\tconst modelCaption = data.item.getChild( 0 );\n *\n * \t\t// `modelCaption` insertion change is consumed from consumable values.\n * \t\t// It will not be converted by other converters, but it's children (probably some text) will be.\n * \t\t// Through mapping, converters for text will know where to insert contents of `modelCaption`.\n * \t\tif ( conversionApi.consumable.consume( modelCaption, 'insert' ) ) {\n * \t\t\tconst viewCaption = new ViewElement( 'figcaption' );\n *\n * \t\t\tconst viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );\n *\n * \t\t\tconversionApi.mapper.bindElements( modelCaption, viewCaption );\n * \t\t\tconversionApi.mapper.bindElements( data.item, viewImageHolder );\n * \t\t\tviewWriter.insert( insertPosition, viewImageHolder );\n * \t\t}\n * \t} else {\n * \t\tconversionApi.mapper.bindElements( data.item, viewImage );\n * \t\tviewWriter.insert( insertPosition, viewImage );\n * \t}\n *\n * \tevt.stop();\n * } );\n * ```\n */ class ModelConsumable {\n    /**\n\t * Contains list of consumable values.\n\t */ _consumable = new Map();\n    /**\n\t * For each {@link module:engine/model/textproxy~TextProxy} added to `ModelConsumable`, this registry holds a parent\n\t * of that `TextProxy` and the start and end indices of that `TextProxy`. This allows identification of the `TextProxy`\n\t * instances that point to the same part of the model but are different instances. Each distinct `TextProxy`\n\t * is given a unique `Symbol` which is then registered as consumable. This process is transparent for the `ModelConsumable`\n\t * API user because whenever `TextProxy` is added, tested, consumed or reverted, the internal mechanisms of\n\t * `ModelConsumable` translate `TextProxy` to that unique `Symbol`.\n\t */ _textProxyRegistry = new Map();\n    /**\n\t * Adds a consumable value to the consumables list and links it with a given model item.\n\t *\n\t * ```ts\n\t * modelConsumable.add( modelElement, 'insert' ); // Add `modelElement` insertion change to consumable values.\n\t * modelConsumable.add( modelElement, 'addAttribute:bold' ); // Add `bold` attribute insertion on `modelElement` change.\n\t * modelConsumable.add( modelElement, 'removeAttribute:bold' ); // Add `bold` attribute removal on `modelElement` change.\n\t * modelConsumable.add( modelSelection, 'selection' ); // Add `modelSelection` to consumable values.\n\t * modelConsumable.add( modelRange, 'range' ); // Add `modelRange` to consumable values.\n\t * ```\n\t *\n\t * @param item Model item, range or selection that has the consumable.\n\t * @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t */ add(item, type) {\n        type = _normalizeConsumableType(type);\n        if (item instanceof TextProxy) {\n            item = this._getSymbolForTextProxy(item);\n        }\n        if (!this._consumable.has(item)) {\n            this._consumable.set(item, new Map());\n        }\n        this._consumable.get(item).set(type, true);\n    }\n    /**\n\t * Removes a given consumable value from a given model item.\n\t *\n\t * ```ts\n\t * modelConsumable.consume( modelElement, 'insert' ); // Remove `modelElement` insertion change from consumable values.\n\t * modelConsumable.consume( modelElement, 'addAttribute:bold' ); // Remove `bold` attribute insertion on `modelElement` change.\n\t * modelConsumable.consume( modelElement, 'removeAttribute:bold' ); // Remove `bold` attribute removal on `modelElement` change.\n\t * modelConsumable.consume( modelSelection, 'selection' ); // Remove `modelSelection` from consumable values.\n\t * modelConsumable.consume( modelRange, 'range' ); // Remove 'modelRange' from consumable values.\n\t * ```\n\t *\n\t * @param item Model item, range or selection from which consumable will be consumed.\n\t * @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t * @returns `true` if consumable value was available and was consumed, `false` otherwise.\n\t */ consume(item, type) {\n        type = _normalizeConsumableType(type);\n        if (item instanceof TextProxy) {\n            item = this._getSymbolForTextProxy(item);\n        }\n        if (this.test(item, type)) {\n            this._consumable.get(item).set(type, false);\n            return true;\n        } else {\n            return false;\n        }\n    }\n    /**\n\t * Tests whether there is a consumable value of a given type connected with a given model item.\n\t *\n\t * ```ts\n\t * modelConsumable.test( modelElement, 'insert' ); // Check for `modelElement` insertion change.\n\t * modelConsumable.test( modelElement, 'addAttribute:bold' ); // Check for `bold` attribute insertion on `modelElement` change.\n\t * modelConsumable.test( modelElement, 'removeAttribute:bold' ); // Check for `bold` attribute removal on `modelElement` change.\n\t * modelConsumable.test( modelSelection, 'selection' ); // Check if `modelSelection` is consumable.\n\t * modelConsumable.test( modelRange, 'range' ); // Check if `modelRange` is consumable.\n\t * ```\n\t *\n\t * @param item Model item, range or selection to be tested.\n\t * @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t * @returns `null` if such consumable was never added, `false` if the consumable values was\n\t * already consumed or `true` if it was added and not consumed yet.\n\t */ test(item, type) {\n        type = _normalizeConsumableType(type);\n        if (item instanceof TextProxy) {\n            item = this._getSymbolForTextProxy(item);\n        }\n        const itemConsumables = this._consumable.get(item);\n        if (itemConsumables === undefined) {\n            return null;\n        }\n        const value = itemConsumables.get(type);\n        if (value === undefined) {\n            return null;\n        }\n        return value;\n    }\n    /**\n\t * Reverts consuming of a consumable value.\n\t *\n\t * ```ts\n\t * modelConsumable.revert( modelElement, 'insert' ); // Revert consuming `modelElement` insertion change.\n\t * modelConsumable.revert( modelElement, 'addAttribute:bold' ); // Revert consuming `bold` attribute insert from `modelElement`.\n\t * modelConsumable.revert( modelElement, 'removeAttribute:bold' ); // Revert consuming `bold` attribute remove from `modelElement`.\n\t * modelConsumable.revert( modelSelection, 'selection' ); // Revert consuming `modelSelection`.\n\t * modelConsumable.revert( modelRange, 'range' ); // Revert consuming `modelRange`.\n\t * ```\n\t *\n\t * @param item Model item, range or selection to be reverted.\n\t * @param type Consumable type.\n\t * @returns `true` if consumable has been reversed, `false` otherwise. `null` if the consumable has\n\t * never been added.\n\t */ revert(item, type) {\n        type = _normalizeConsumableType(type);\n        if (item instanceof TextProxy) {\n            item = this._getSymbolForTextProxy(item);\n        }\n        const test = this.test(item, type);\n        if (test === false) {\n            this._consumable.get(item).set(type, true);\n            return true;\n        } else if (test === true) {\n            return false;\n        }\n        return null;\n    }\n    /**\n\t * Verifies if all events from the specified group were consumed.\n\t *\n\t * @param eventGroup The events group to verify.\n\t */ verifyAllConsumed(eventGroup) {\n        const items = [];\n        for (const [item, consumables] of this._consumable){\n            for (const [event, canConsume] of consumables){\n                const eventPrefix = event.split(':')[0];\n                if (canConsume && eventGroup == eventPrefix) {\n                    items.push({\n                        event,\n                        item: item.name || item.description\n                    });\n                }\n            }\n        }\n        if (items.length) {\n            /**\n\t\t\t * Some of the {@link module:engine/model/item~Item model items} were not consumed while downcasting the model to view.\n\t\t\t *\n\t\t\t * This might be the effect of:\n\t\t\t *\n\t\t\t * * A missing converter for some model elements. Make sure that you registered downcast converters for all model elements.\n\t\t\t * * A custom converter that does not consume converted items. Make sure that you\n\t\t\t * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} all model elements that you converted\n\t\t\t * from the model to the view.\n\t\t\t * * A custom converter that called `event.stop()`. When providing a custom converter, keep in mind that you should not stop\n\t\t\t * the event. If you stop it then the default converter at the `lowest` priority will not trigger the conversion of this node's\n\t\t\t * attributes and child nodes.\n\t\t\t *\n\t\t\t * @error conversion-model-consumable-not-consumed\n\t\t\t * @param {Array.<module:engine/model/item~Item>} items Items that were not consumed.\n\t\t\t */ throw new CKEditorError('conversion-model-consumable-not-consumed', null, {\n                items\n            });\n        }\n    }\n    /**\n\t * Gets a unique symbol for the passed {@link module:engine/model/textproxy~TextProxy} instance. All `TextProxy` instances that\n\t * have same parent, same start index and same end index will get the same symbol.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @internal\n\t * @param textProxy `TextProxy` instance to get a symbol for.\n\t * @returns Symbol representing all equal instances of `TextProxy`.\n\t */ _getSymbolForTextProxy(textProxy) {\n        let symbol = null;\n        const startMap = this._textProxyRegistry.get(textProxy.startOffset);\n        if (startMap) {\n            const endMap = startMap.get(textProxy.endOffset);\n            if (endMap) {\n                symbol = endMap.get(textProxy.parent);\n            }\n        }\n        if (!symbol) {\n            symbol = this._addSymbolForTextProxy(textProxy);\n        }\n        return symbol;\n    }\n    /**\n\t * Adds a symbol for the given {@link module:engine/model/textproxy~TextProxy} instance.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @param textProxy Text proxy instance.\n\t * @returns Symbol generated for given `TextProxy`.\n\t */ _addSymbolForTextProxy(textProxy) {\n        const start = textProxy.startOffset;\n        const end = textProxy.endOffset;\n        const parent = textProxy.parent;\n        const symbol = Symbol('$textProxy:' + textProxy.data);\n        let startMap;\n        let endMap;\n        startMap = this._textProxyRegistry.get(start);\n        if (!startMap) {\n            startMap = new Map();\n            this._textProxyRegistry.set(start, startMap);\n        }\n        endMap = startMap.get(end);\n        if (!endMap) {\n            endMap = new Map();\n            startMap.set(end, endMap);\n        }\n        endMap.set(parent, symbol);\n        return symbol;\n    }\n}\n/**\n * Returns a normalized consumable type name from the given string. A normalized consumable type name is a string that has\n * at most one colon, for example: `insert` or `addMarker:highlight`. If a string to normalize has more \"parts\" (more colons),\n * the further parts are dropped, for example: `addattribute:bold:$text` -> `addattributes:bold`.\n *\n * @param type Consumable type.\n * @returns Normalized consumable type.\n */ function _normalizeConsumableType(type) {\n    const parts = type.split(':');\n    // For inserts allow passing event name, it's stored in the context of a specified element so the element name is not needed.\n    if (parts[0] == 'insert') {\n        return parts[0];\n    }\n    // Markers are identified by the whole name (otherwise we would consume the whole markers group).\n    if (parts[0] == 'addMarker' || parts[0] == 'removeMarker') {\n        return type;\n    }\n    return parts.length > 1 ? parts[0] + ':' + parts[1] : parts[0];\n}\n\n/**\n * The downcast dispatcher is a central point of downcasting (conversion from the model to the view), which is a process of reacting\n * to changes in the model and firing a set of events. The callbacks listening to these events are called converters. The\n * converters' role is to convert the model changes to changes in view (for example, adding view nodes or\n * changing attributes on view elements).\n *\n * During the conversion process, downcast dispatcher fires events basing on the state of the model and prepares\n * data for these events. It is important to understand that the events are connected with the changes done on the model,\n * for example: \"a node has been inserted\" or \"an attribute has changed\". This is in contrary to upcasting (a view-to-model conversion)\n * where you convert the view state (view nodes) to a model tree.\n *\n * The events are prepared basing on a diff created by the {@link module:engine/model/differ~Differ Differ}, which buffers them\n * and then passes to the downcast dispatcher as a diff between the old model state and the new model state.\n *\n * Note that because the changes are converted, there is a need to have a mapping between the model structure and the view structure.\n * To map positions and elements during the downcast (a model-to-view conversion), use {@link module:engine/conversion/mapper~Mapper}.\n *\n * Downcast dispatcher fires the following events for model tree changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`} &ndash;\n * If a range of nodes was inserted to the model tree.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove `remove`} &ndash;\n * If a range of nodes was removed from the model tree.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`} &ndash;\n * If an attribute was added, changed or removed from a model node.\n *\n * For {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`}\n * and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`},\n * the downcast dispatcher generates {@link module:engine/conversion/modelconsumable~ModelConsumable consumables}.\n * These are used to have control over which changes have already been consumed. It is useful when some converters\n * overwrite others or convert multiple changes (for example, it converts an insertion of an element and also converts that\n * element's attributes during the insertion).\n *\n * Additionally, downcast dispatcher fires events for {@link module:engine/model/markercollection~Marker marker} changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker `addMarker`} &ndash; If a marker was added.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker `removeMarker`} &ndash; If a marker was\n * removed.\n *\n * Note that changing a marker is done through removing the marker from the old range and adding it to the new range,\n * so both of these events are fired.\n *\n * Finally, a downcast dispatcher also handles firing events for the {@link module:engine/model/selection model selection}\n * conversion:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:selection `selection`}\n * &ndash; Converts the selection from the model to the view.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`}\n * &ndash; Fired for every selection attribute.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker `addMarker`}\n * &ndash; Fired for every marker that contains a selection.\n *\n * Unlike the model tree and the markers, the events for selection are not fired for changes but for a selection state.\n *\n * When providing custom listeners for a downcast dispatcher, remember to check whether a given change has not been\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} yet.\n *\n * When providing custom listeners for a downcast dispatcher, keep in mind that you **should not** stop the event. If you stop it,\n * then the default converter at the `lowest` priority will not trigger the conversion of this node's attributes and child nodes.\n *\n * When providing custom listeners for a downcast dispatcher, remember to use the provided\n * {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} to apply changes to the view document.\n *\n * You can read more about conversion in the following guide:\n *\n * * {@glink framework/deep-dive/conversion/downcast Downcast conversion}\n *\n * An example of a custom converter for the downcast dispatcher:\n *\n * ```ts\n * // You will convert inserting a \"paragraph\" model element into the model.\n * downcastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {\n * \t// Remember to check whether the change has not been consumed yet and consume it.\n * \tif ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {\n * \t\treturn;\n * \t}\n *\n * \t// Translate the position in the model to a position in the view.\n * \tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n *\n * \t// Create a <p> element that will be inserted into the view at the `viewPosition`.\n * \tconst viewElement = conversionApi.writer.createContainerElement( 'p' );\n *\n * \t// Bind the newly created view element to the model element so positions will map accordingly in the future.\n * \tconversionApi.mapper.bindElements( data.item, viewElement );\n *\n * \t// Add the newly created view element to the view.\n * \tconversionApi.writer.insert( viewPosition, viewElement );\n * } );\n * ```\n */ class DowncastDispatcher extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * A template for an interface passed by the dispatcher to the event callbacks.\n\t *\n\t * @internal\n\t */ _conversionApi;\n    /**\n\t * A map of already fired events for a given `ModelConsumable`.\n\t */ _firedEventsMap;\n    /**\n\t * Creates a downcast dispatcher instance.\n\t *\n\t * @see module:engine/conversion/downcastdispatcher~DowncastConversionApi\n\t *\n\t * @param conversionApi Additional properties for an interface that will be passed to events fired\n\t * by the downcast dispatcher.\n\t */ constructor(conversionApi){\n        super();\n        this._conversionApi = {\n            dispatcher: this,\n            ...conversionApi\n        };\n        this._firedEventsMap = new WeakMap();\n    }\n    /**\n\t * Converts changes buffered in the given {@link module:engine/model/differ~Differ model differ}\n\t * and fires conversion events based on it.\n\t *\n\t * @fires insert\n\t * @fires remove\n\t * @fires attribute\n\t * @fires addMarker\n\t * @fires removeMarker\n\t * @fires reduceChanges\n\t * @param differ The differ object with buffered changes.\n\t * @param markers Markers related to the model fragment to convert.\n\t * @param writer The view writer that should be used to modify the view document.\n\t */ convertChanges(differ, markers, writer) {\n        const conversionApi = this._createConversionApi(writer, differ.getRefreshedItems());\n        // Before the view is updated, remove markers which have changed.\n        for (const change of differ.getMarkersToRemove()){\n            this._convertMarkerRemove(change.name, change.range, conversionApi);\n        }\n        // Let features modify the change list (for example to allow reconversion).\n        const changes = this._reduceChanges(differ.getChanges());\n        // Convert changes that happened on model tree.\n        for (const entry of changes){\n            if (entry.type === 'insert') {\n                this._convertInsert(Range._createFromPositionAndShift(entry.position, entry.length), conversionApi);\n            } else if (entry.type === 'reinsert') {\n                this._convertReinsert(Range._createFromPositionAndShift(entry.position, entry.length), conversionApi);\n            } else if (entry.type === 'remove') {\n                this._convertRemove(entry.position, entry.length, entry.name, conversionApi);\n            } else {\n                // Defaults to 'attribute' change.\n                this._convertAttribute(entry.range, entry.attributeKey, entry.attributeOldValue, entry.attributeNewValue, conversionApi);\n            }\n        }\n        // Remove mappings for all removed view elements.\n        // Remove these mappings as soon as they are not needed (https://github.com/ckeditor/ckeditor5/issues/15411).\n        conversionApi.mapper.flushDeferredBindings();\n        for (const markerName of conversionApi.mapper.flushUnboundMarkerNames()){\n            const markerRange = markers.get(markerName).getRange();\n            this._convertMarkerRemove(markerName, markerRange, conversionApi);\n            this._convertMarkerAdd(markerName, markerRange, conversionApi);\n        }\n        // After the view is updated, convert markers which have changed.\n        for (const change of differ.getMarkersToAdd()){\n            this._convertMarkerAdd(change.name, change.range, conversionApi);\n        }\n        // Verify if all insert consumables were consumed.\n        conversionApi.consumable.verifyAllConsumed('insert');\n    }\n    /**\n\t * Starts a conversion of a model range and the provided markers.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @fires addMarker\n\t * @param range The inserted range.\n\t * @param markers The map of markers that should be down-casted.\n\t * @param writer The view writer that should be used to modify the view document.\n\t * @param options Optional options object passed to `convertionApi.options`.\n\t */ convert(range, markers, writer, options = {}) {\n        const conversionApi = this._createConversionApi(writer, undefined, options);\n        this._convertInsert(range, conversionApi);\n        for (const [name, range] of markers){\n            this._convertMarkerAdd(name, range, conversionApi);\n        }\n        // Verify if all insert consumables were consumed.\n        conversionApi.consumable.verifyAllConsumed('insert');\n    }\n    /**\n\t * Starts the model selection conversion.\n\t *\n\t * Fires events for a given {@link module:engine/model/selection~Selection selection} to start the selection conversion.\n\t *\n\t * @fires selection\n\t * @fires addMarker\n\t * @fires attribute\n\t * @param selection The selection to convert.\n\t * @param markers Markers connected with the converted model.\n\t * @param writer View writer that should be used to modify the view document.\n\t */ convertSelection(selection, markers, writer) {\n        const conversionApi = this._createConversionApi(writer);\n        // First perform a clean-up at the current position of the selection.\n        this.fire('cleanSelection', {\n            selection\n        }, conversionApi);\n        // Don't convert selection if it is in a model root that does not have a view root (for now this is only the graveyard root).\n        const modelRoot = selection.getFirstPosition().root;\n        if (!conversionApi.mapper.toViewElement(modelRoot)) {\n            return;\n        }\n        // Now, perform actual selection conversion.\n        const markersAtSelection = Array.from(markers.getMarkersAtPosition(selection.getFirstPosition()));\n        this._addConsumablesForSelection(conversionApi.consumable, selection, markersAtSelection);\n        this.fire('selection', {\n            selection\n        }, conversionApi);\n        if (!selection.isCollapsed) {\n            return;\n        }\n        for (const marker of markersAtSelection){\n            // Do not fire event if the marker has been consumed.\n            if (conversionApi.consumable.test(selection, 'addMarker:' + marker.name)) {\n                const markerRange = marker.getRange();\n                if (!shouldMarkerChangeBeConverted(selection.getFirstPosition(), marker, conversionApi.mapper)) {\n                    continue;\n                }\n                const data = {\n                    item: selection,\n                    markerName: marker.name,\n                    markerRange\n                };\n                this.fire(`addMarker:${marker.name}`, data, conversionApi);\n            }\n        }\n        for (const key of selection.getAttributeKeys()){\n            // Do not fire event if the attribute has been consumed.\n            if (conversionApi.consumable.test(selection, 'attribute:' + key)) {\n                const data = {\n                    item: selection,\n                    range: selection.getFirstRange(),\n                    attributeKey: key,\n                    attributeOldValue: null,\n                    attributeNewValue: selection.getAttribute(key)\n                };\n                this.fire(`attribute:${key}:$text`, data, conversionApi);\n            }\n        }\n    }\n    /**\n\t * Fires insertion conversion of a range of nodes.\n\t *\n\t * For each node in the range, {@link #event:insert `insert` event is fired}. For each attribute on each node,\n\t * {@link #event:attribute `attribute` event is fired}.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param range The inserted range.\n\t * @param conversionApi The conversion API object.\n\t * @param options.doNotAddConsumables Whether the ModelConsumable should not get populated\n\t * for items in the provided range.\n\t */ _convertInsert(range, conversionApi, options = {}) {\n        if (!options.doNotAddConsumables) {\n            // Collect a list of things that can be consumed, consisting of nodes and their attributes.\n            this._addConsumablesForInsert(conversionApi.consumable, range);\n        }\n        // Fire a separate insert event for each node and text fragment contained in the range.\n        for (const data of Array.from(range.getWalker({\n            shallow: true\n        })).map(walkerValueToEventData)){\n            this._testAndFire('insert', data, conversionApi);\n        }\n    }\n    /**\n\t * Fires conversion of a single node removal. Fires {@link #event:remove remove event} with provided data.\n\t *\n\t * @param position Position from which node was removed.\n\t * @param length Offset size of removed node.\n\t * @param name Name of removed node.\n\t * @param conversionApi The conversion API object.\n\t */ _convertRemove(position, length, name, conversionApi) {\n        this.fire(`remove:${name}`, {\n            position,\n            length\n        }, conversionApi);\n    }\n    /**\n\t * Starts a conversion of an attribute change on a given `range`.\n\t *\n\t * For each node in the given `range`, {@link #event:attribute attribute event} is fired with the passed data.\n\t *\n\t * @fires attribute\n\t * @param range Changed range.\n\t * @param key Key of the attribute that has changed.\n\t * @param oldValue Attribute value before the change or `null` if the attribute has not been set before.\n\t * @param newValue New attribute value or `null` if the attribute has been removed.\n\t * @param conversionApi The conversion API object.\n\t */ _convertAttribute(range, key, oldValue, newValue, conversionApi) {\n        // Create a list with attributes to consume.\n        this._addConsumablesForRange(conversionApi.consumable, range, `attribute:${key}`);\n        // Create a separate attribute event for each node in the range.\n        for (const value of range){\n            const data = {\n                item: value.item,\n                range: Range._createFromPositionAndShift(value.previousPosition, value.length),\n                attributeKey: key,\n                attributeOldValue: oldValue,\n                attributeNewValue: newValue\n            };\n            this._testAndFire(`attribute:${key}`, data, conversionApi);\n        }\n    }\n    /**\n\t * Fires re-insertion conversion (with a `reconversion` flag passed to `insert` events)\n\t * of a range of elements (only elements on the range depth, without children).\n\t *\n\t * For each node in the range on its depth (without children), {@link #event:insert `insert` event} is fired.\n\t * For each attribute on each node, {@link #event:attribute `attribute` event} is fired.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param range The range to reinsert.\n\t * @param conversionApi The conversion API object.\n\t */ _convertReinsert(range, conversionApi) {\n        // Convert the elements - without converting children.\n        const walkerValues = Array.from(range.getWalker({\n            shallow: true\n        }));\n        // Collect a list of things that can be consumed, consisting of nodes and their attributes.\n        this._addConsumablesForInsert(conversionApi.consumable, walkerValues);\n        // Fire a separate insert event for each node and text fragment contained shallowly in the range.\n        for (const data of walkerValues.map(walkerValueToEventData)){\n            this._testAndFire('insert', {\n                ...data,\n                reconversion: true\n            }, conversionApi);\n        }\n    }\n    /**\n\t * Converts the added marker. Fires the {@link #event:addMarker `addMarker`} event for each item\n\t * in the marker's range. If the range is collapsed, a single event is dispatched. See the event description for more details.\n\t *\n\t * @fires addMarker\n\t * @param markerName Marker name.\n\t * @param markerRange The marker range.\n\t * @param conversionApi The conversion API object.\n\t */ _convertMarkerAdd(markerName, markerRange, conversionApi) {\n        // Do not convert if range is in graveyard.\n        if (markerRange.root.rootName == '$graveyard') {\n            return;\n        }\n        // In markers' case, event name == consumable name.\n        const eventName = `addMarker:${markerName}`;\n        //\n        // First, fire an event for the whole marker.\n        //\n        conversionApi.consumable.add(markerRange, eventName);\n        this.fire(eventName, {\n            markerName,\n            markerRange\n        }, conversionApi);\n        //\n        // Do not fire events for each item inside the range if the range got consumed.\n        // Also consume the whole marker consumable if it wasn't consumed.\n        //\n        if (!conversionApi.consumable.consume(markerRange, eventName)) {\n            return;\n        }\n        //\n        // Then, fire an event for each item inside the marker range.\n        //\n        this._addConsumablesForRange(conversionApi.consumable, markerRange, eventName);\n        for (const item of markerRange.getItems()){\n            // Do not fire event for already consumed items.\n            if (!conversionApi.consumable.test(item, eventName)) {\n                continue;\n            }\n            const data = {\n                item,\n                range: Range._createOn(item),\n                markerName,\n                markerRange\n            };\n            this.fire(eventName, data, conversionApi);\n        }\n    }\n    /**\n\t * Fires the conversion of the marker removal. Fires the {@link #event:removeMarker `removeMarker`} event with the provided data.\n\t *\n\t * @fires removeMarker\n\t * @param markerName Marker name.\n\t * @param markerRange The marker range.\n\t * @param conversionApi The conversion API object.\n\t */ _convertMarkerRemove(markerName, markerRange, conversionApi) {\n        // Do not convert if range is in graveyard.\n        if (markerRange.root.rootName == '$graveyard') {\n            return;\n        }\n        this.fire(`removeMarker:${markerName}`, {\n            markerName,\n            markerRange\n        }, conversionApi);\n    }\n    /**\n\t * Fires the reduction of changes buffered in the {@link module:engine/model/differ~Differ `Differ`}.\n\t *\n\t * Features can replace selected {@link module:engine/model/differ~DiffItem `DiffItem`}s with `reinsert` entries to trigger\n\t * reconversion. The {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n\t * `DowncastHelpers.elementToStructure()`} is using this event to trigger reconversion.\n\t *\n\t * @fires reduceChanges\n\t */ _reduceChanges(changes) {\n        const data = {\n            changes\n        };\n        this.fire('reduceChanges', data);\n        return data.changes;\n    }\n    /**\n\t * Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume from a given range,\n\t * assuming that the range has just been inserted to the model.\n\t *\n\t * @param consumable The consumable.\n\t * @param walkerValues The walker values for the inserted range.\n\t * @returns The values to consume.\n\t */ _addConsumablesForInsert(consumable, walkerValues) {\n        for (const value of walkerValues){\n            const item = value.item;\n            // Add consumable if it wasn't there yet.\n            if (consumable.test(item, 'insert') === null) {\n                consumable.add(item, 'insert');\n                for (const key of item.getAttributeKeys()){\n                    consumable.add(item, 'attribute:' + key);\n                }\n            }\n        }\n        return consumable;\n    }\n    /**\n\t * Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume for a given range.\n\t *\n\t * @param consumable The consumable.\n\t * @param range The affected range.\n\t * @param type Consumable type.\n\t * @returns The values to consume.\n\t */ _addConsumablesForRange(consumable, range, type) {\n        for (const item of range.getItems()){\n            consumable.add(item, type);\n        }\n        return consumable;\n    }\n    /**\n\t * Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with selection consumable values.\n\t *\n\t * @param consumable The consumable.\n\t * @param selection The selection to create the consumable from.\n\t * @param markers Markers that contain the selection.\n\t * @returns The values to consume.\n\t */ _addConsumablesForSelection(consumable, selection, markers) {\n        consumable.add(selection, 'selection');\n        for (const marker of markers){\n            consumable.add(selection, 'addMarker:' + marker.name);\n        }\n        for (const key of selection.getAttributeKeys()){\n            consumable.add(selection, 'attribute:' + key);\n        }\n        return consumable;\n    }\n    /**\n\t * Tests whether given event wasn't already fired and if so, fires it.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param type Event type.\n\t * @param data Event data.\n\t * @param conversionApi The conversion API object.\n\t */ _testAndFire(type, data, conversionApi) {\n        const eventName = getEventName(type, data);\n        const itemKey = data.item.is('$textProxy') ? conversionApi.consumable._getSymbolForTextProxy(data.item) : data.item;\n        const eventsFiredForConversion = this._firedEventsMap.get(conversionApi);\n        const eventsFiredForItem = eventsFiredForConversion.get(itemKey);\n        if (!eventsFiredForItem) {\n            eventsFiredForConversion.set(itemKey, new Set([\n                eventName\n            ]));\n        } else if (!eventsFiredForItem.has(eventName)) {\n            eventsFiredForItem.add(eventName);\n        } else {\n            return;\n        }\n        this.fire(eventName, data, conversionApi);\n    }\n    /**\n\t * Fires not already fired events for setting attributes on just inserted item.\n\t *\n\t * @param item The model item to convert attributes for.\n\t * @param conversionApi The conversion API object.\n\t */ _testAndFireAddAttributes(item, conversionApi) {\n        const data = {\n            item,\n            range: Range._createOn(item)\n        };\n        for (const key of data.item.getAttributeKeys()){\n            data.attributeKey = key;\n            data.attributeOldValue = null;\n            data.attributeNewValue = data.item.getAttribute(key);\n            this._testAndFire(`attribute:${key}`, data, conversionApi);\n        }\n    }\n    /**\n\t * Builds an instance of the {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi} from a template and a given\n\t * {@link module:engine/view/downcastwriter~DowncastWriter `DowncastWriter`} and options object.\n\t *\n\t * @param writer View writer that should be used to modify the view document.\n\t * @param refreshedItems A set of model elements that should not reuse their\n\t * previous view representations.\n\t * @param options Optional options passed to `convertionApi.options`.\n\t * @return The conversion API object.\n\t */ _createConversionApi(writer, refreshedItems = new Set(), options = {}) {\n        const conversionApi = {\n            ...this._conversionApi,\n            consumable: new ModelConsumable(),\n            writer,\n            options,\n            convertItem: (item)=>this._convertInsert(Range._createOn(item), conversionApi),\n            convertChildren: (element)=>this._convertInsert(Range._createIn(element), conversionApi, {\n                    doNotAddConsumables: true\n                }),\n            convertAttributes: (item)=>this._testAndFireAddAttributes(item, conversionApi),\n            canReuseView: (viewElement)=>!refreshedItems.has(conversionApi.mapper.toModelElement(viewElement))\n        };\n        this._firedEventsMap.set(conversionApi, new Map());\n        return conversionApi;\n    }\n}\n/**\n * Helper function, checks whether change of `marker` at `modelPosition` should be converted. Marker changes are not\n * converted if they happen inside an element with custom conversion method.\n */ function shouldMarkerChangeBeConverted(modelPosition, marker, mapper) {\n    const range = marker.getRange();\n    const ancestors = Array.from(modelPosition.getAncestors());\n    ancestors.shift(); // Remove root element. It cannot be passed to `model.Range#containsItem`.\n    ancestors.reverse();\n    const hasCustomHandling = ancestors.some((element)=>{\n        if (range.containsItem(element)) {\n            const viewElement = mapper.toViewElement(element);\n            return !!viewElement.getCustomProperty('addHighlight');\n        }\n    });\n    return !hasCustomHandling;\n}\nfunction getEventName(type, data) {\n    const name = data.item.is('element') ? data.item.name : '$text';\n    return `${type}:${name}`;\n}\nfunction walkerValueToEventData(value) {\n    const item = value.item;\n    const itemRange = Range._createFromPositionAndShift(value.previousPosition, value.length);\n    return {\n        item,\n        range: itemRange\n    };\n}\n\n/**\n * Selection is a set of {@link module:engine/model/range~Range ranges}. It has a direction specified by its\n * {@link module:engine/model/selection~Selection#anchor anchor} and {@link module:engine/model/selection~Selection#focus focus}\n * (it can be {@link module:engine/model/selection~Selection#isBackward forward or backward}).\n * Additionally, selection may have its own attributes (think – whether text typed in in this selection\n * should have those attributes – e.g. whether you type a bolded text).\n */ class Selection extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {\n    /**\n\t * Specifies whether the last added range was added as a backward or forward range.\n\t */ _lastRangeBackward = false;\n    /**\n\t * List of attributes set on current selection.\n\t */ _attrs = new Map();\n    /** @internal */ _ranges = [];\n    /**\n\t * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}\n\t * or creates an empty selection if no arguments were passed.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = writer.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = writer.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * const selection = writer.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = writer.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the given document selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const documentSelection = model.document.selection;\n\t * const selection = writer.createSelection( documentSelection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * const selection = writer.createSelection( position );\n\t *\n\t * // Creates selection at the given offset in the given element.\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * const selection = writer.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/model/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = writer.createSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * Selection's constructor allow passing additional options (`'backward'`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * @internal\n\t */ constructor(...args){\n        super();\n        if (args.length) {\n            this.setTo(...args);\n        }\n    }\n    /**\n\t * Selection anchor. Anchor is the position from which the selection was started. If a user is making a selection\n\t * by dragging the mouse, the anchor is where the user pressed the mouse button (the beginning of the selection).\n\t *\n\t * Anchor and {@link #focus} define the direction of the selection, which is important\n\t * when expanding/shrinking selection. The focus moves, while the anchor should remain in the same place.\n\t *\n\t * Anchor is always set to the {@link module:engine/model/range~Range#start start} or\n\t * {@link module:engine/model/range~Range#end end} position of the last of selection's ranges. Whether it is\n\t * the `start` or `end` depends on the specified `options.backward`. See the {@link #setTo `setTo()`} method.\n\t *\n\t * May be set to `null` if there are no ranges in the selection.\n\t *\n\t * @see #focus\n\t */ get anchor() {\n        if (this._ranges.length > 0) {\n            const range = this._ranges[this._ranges.length - 1];\n            return this._lastRangeBackward ? range.end : range.start;\n        }\n        return null;\n    }\n    /**\n\t * Selection focus. Focus is the position where the selection ends. If a user is making a selection\n\t * by dragging the mouse, the focus is where the mouse cursor is.\n\t *\n\t * May be set to `null` if there are no ranges in the selection.\n\t *\n\t * @see #anchor\n\t */ get focus() {\n        if (this._ranges.length > 0) {\n            const range = this._ranges[this._ranges.length - 1];\n            return this._lastRangeBackward ? range.start : range.end;\n        }\n        return null;\n    }\n    /**\n\t * Whether the selection is collapsed. Selection is collapsed when there is exactly one range in it\n\t * and it is collapsed.\n\t */ get isCollapsed() {\n        const length = this._ranges.length;\n        if (length === 1) {\n            return this._ranges[0].isCollapsed;\n        } else {\n            return false;\n        }\n    }\n    /**\n\t * Returns the number of ranges in the selection.\n\t */ get rangeCount() {\n        return this._ranges.length;\n    }\n    /**\n\t * Specifies whether the selection's {@link #focus} precedes the selection's {@link #anchor}.\n\t */ get isBackward() {\n        return !this.isCollapsed && this._lastRangeBackward;\n    }\n    /**\n\t * Checks whether this selection is equal to the given selection. Selections are equal if they have the same directions,\n\t * the same number of ranges and all ranges from one selection equal to ranges from the another selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are equal, `false` otherwise.\n\t */ isEqual(otherSelection) {\n        if (this.rangeCount != otherSelection.rangeCount) {\n            return false;\n        } else if (this.rangeCount === 0) {\n            return true;\n        }\n        if (!this.anchor.isEqual(otherSelection.anchor) || !this.focus.isEqual(otherSelection.focus)) {\n            return false;\n        }\n        for (const thisRange of this._ranges){\n            let found = false;\n            for (const otherRange of otherSelection._ranges){\n                if (thisRange.isEqual(otherRange)) {\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Returns an iterable object that iterates over copies of selection ranges.\n\t */ *getRanges() {\n        for (const range of this._ranges){\n            yield new Range(range.start, range.end);\n        }\n    }\n    /**\n\t * Returns a copy of the first range in the selection.\n\t * First range is the one which {@link module:engine/model/range~Range#start start} position\n\t * {@link module:engine/model/position~Position#isBefore is before} start position of all other ranges\n\t * (not to confuse with the first range added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getFirstRange() {\n        let first = null;\n        for (const range of this._ranges){\n            if (!first || range.start.isBefore(first.start)) {\n                first = range;\n            }\n        }\n        return first ? new Range(first.start, first.end) : null;\n    }\n    /**\n\t * Returns a copy of the last range in the selection.\n\t * Last range is the one which {@link module:engine/model/range~Range#end end} position\n\t * {@link module:engine/model/position~Position#isAfter is after} end position of all other ranges (not to confuse with the range most\n\t * recently added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getLastRange() {\n        let last = null;\n        for (const range of this._ranges){\n            if (!last || range.end.isAfter(last.end)) {\n                last = range;\n            }\n        }\n        return last ? new Range(last.start, last.end) : null;\n    }\n    /**\n\t * Returns the first position in the selection.\n\t * First position is the position that {@link module:engine/model/position~Position#isBefore is before}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getFirstPosition() {\n        const first = this.getFirstRange();\n        return first ? first.start.clone() : null;\n    }\n    /**\n\t * Returns the last position in the selection.\n\t * Last position is the position that {@link module:engine/model/position~Position#isAfter is after}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getLastPosition() {\n        const lastRange = this.getLastRange();\n        return lastRange ? lastRange.end.clone() : null;\n    }\n    /**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable}.\n\t *\n\t * ```ts\n\t * // Removes all selection's ranges.\n\t * selection.setTo( null );\n\t *\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * selection.setTo( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * selection.setTo( ranges );\n\t *\n\t * // Sets selection to other selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const otherSelection = writer.createSelection();\n\t * selection.setTo( otherSelection );\n\t *\n\t * // Sets selection to the given document selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const documentSelection = new DocumentSelection( doc );\n\t * selection.setTo( documentSelection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * selection.setTo( position );\n\t *\n\t * // Sets collapsed selection at the position of the given node and an offset.\n\t * selection.setTo( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n \t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection#setTo()`' method allow passing additional options (`backward`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t */ setTo(...args) {\n        let [selectable, placeOrOffset, options] = args;\n        if (typeof placeOrOffset == 'object') {\n            options = placeOrOffset;\n            placeOrOffset = undefined;\n        }\n        if (selectable === null) {\n            this._setRanges([]);\n        } else if (selectable instanceof Selection) {\n            this._setRanges(selectable.getRanges(), selectable.isBackward);\n        } else if (selectable && typeof selectable.getRanges == 'function') {\n            // We assume that the selectable is a DocumentSelection.\n            // It can't be imported here, because it would lead to circular imports.\n            this._setRanges(selectable.getRanges(), selectable.isBackward);\n        } else if (selectable instanceof Range) {\n            this._setRanges([\n                selectable\n            ], !!options && !!options.backward);\n        } else if (selectable instanceof Position) {\n            this._setRanges([\n                new Range(selectable)\n            ]);\n        } else if (selectable instanceof Node$1) {\n            const backward = !!options && !!options.backward;\n            let range;\n            if (placeOrOffset == 'in') {\n                range = Range._createIn(selectable);\n            } else if (placeOrOffset == 'on') {\n                range = Range._createOn(selectable);\n            } else if (placeOrOffset !== undefined) {\n                range = new Range(Position._createAt(selectable, placeOrOffset));\n            } else {\n                /**\n\t\t\t\t * selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-setto-required-second-parameter\n\t\t\t\t */ throw new CKEditorError('model-selection-setto-required-second-parameter', [\n                    this,\n                    selectable\n                ]);\n            }\n            this._setRanges([\n                range\n            ], backward);\n        } else if (isIterable(selectable)) {\n            // We assume that the selectable is an iterable of ranges.\n            this._setRanges(selectable, options && !!options.backward);\n        } else {\n            /**\n\t\t\t * Cannot set the selection to the given place.\n\t\t\t *\n\t\t\t * Invalid parameters were specified when setting the selection. Common issues:\n\t\t\t *\n\t\t\t * * A {@link module:engine/model/textproxy~TextProxy} instance was passed instead of\n\t\t\t * a real {@link module:engine/model/text~Text}.\n\t\t\t * * View nodes were passed instead of model nodes.\n\t\t\t * * `null`/`undefined` was passed.\n\t\t\t *\n\t\t\t * @error model-selection-setto-not-selectable\n\t\t\t */ throw new CKEditorError('model-selection-setto-not-selectable', [\n                this,\n                selectable\n            ]);\n        }\n    }\n    /**\n\t * Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t * is treated like the last added range and is used to set {@link module:engine/model/selection~Selection#anchor} and\n\t * {@link module:engine/model/selection~Selection#focus}. Accepts a flag describing in which direction the selection is made.\n\t *\n\t * @fires change:range\n\t * @param newRanges Ranges to set.\n\t * @param isLastBackward Flag describing if last added range was selected forward - from start to end (`false`)\n\t * or backward - from end to start (`true`).\n\t */ _setRanges(newRanges, isLastBackward = false) {\n        const ranges = Array.from(newRanges);\n        // Check whether there is any range in new ranges set that is different than all already added ranges.\n        const anyNewRange = ranges.some((newRange)=>{\n            if (!(newRange instanceof Range)) {\n                /**\n\t\t\t\t * Selection range set to an object that is not an instance of {@link module:engine/model/range~Range}.\n\t\t\t\t *\n\t\t\t\t * Only {@link module:engine/model/range~Range} instances can be used to set a selection.\n\t\t\t\t * Common mistakes leading to this error are:\n\t\t\t\t *\n\t\t\t\t * * using DOM `Range` object,\n\t\t\t\t * * incorrect CKEditor 5 installation with multiple `ckeditor5-engine` packages having different versions.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-set-ranges-not-range\n\t\t\t\t */ throw new CKEditorError('model-selection-set-ranges-not-range', [\n                    this,\n                    newRanges\n                ]);\n            }\n            return this._ranges.every((oldRange)=>{\n                return !oldRange.isEqual(newRange);\n            });\n        });\n        // Don't do anything if nothing changed.\n        if (ranges.length === this._ranges.length && !anyNewRange) {\n            return;\n        }\n        this._replaceAllRanges(ranges);\n        this._lastRangeBackward = !!isLastBackward;\n        this.fire('change:range', {\n            directChange: true\n        });\n    }\n    /**\n\t * Moves {@link module:engine/model/selection~Selection#focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link module:engine/model/writer~Writer#createPositionAt writer.createPositionAt()} parameters.\n\t *\n\t * @fires change:range\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */ setFocus(itemOrPosition, offset) {\n        if (this.anchor === null) {\n            /**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error model-selection-setfocus-no-ranges\n\t\t\t */ throw new CKEditorError('model-selection-setfocus-no-ranges', [\n                this,\n                itemOrPosition\n            ]);\n        }\n        const newFocus = Position._createAt(itemOrPosition, offset);\n        if (newFocus.compareWith(this.focus) == 'same') {\n            return;\n        }\n        const anchor = this.anchor;\n        if (this._ranges.length) {\n            this._popRange();\n        }\n        if (newFocus.compareWith(anchor) == 'before') {\n            this._pushRange(new Range(newFocus, anchor));\n            this._lastRangeBackward = true;\n        } else {\n            this._pushRange(new Range(anchor, newFocus));\n            this._lastRangeBackward = false;\n        }\n        this.fire('change:range', {\n            directChange: true\n        });\n    }\n    /**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */ getAttribute(key) {\n        return this._attrs.get(key);\n    }\n    /**\n\t * Returns iterable that iterates over this selection's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */ getAttributes() {\n        return this._attrs.entries();\n    }\n    /**\n\t * Returns iterable that iterates over this selection's attribute keys.\n\t */ getAttributeKeys() {\n        return this._attrs.keys();\n    }\n    /**\n\t * Checks if the selection has an attribute for given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on selection, `false` otherwise.\n\t */ hasAttribute(key) {\n        return this._attrs.has(key);\n    }\n    /**\n\t * Removes an attribute with given key from the selection.\n\t *\n\t * If given attribute was set on the selection, fires the {@link #event:change:range} event with\n\t * removed attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param key Key of attribute to remove.\n\t */ removeAttribute(key) {\n        if (this.hasAttribute(key)) {\n            this._attrs.delete(key);\n            this.fire('change:attribute', {\n                attributeKeys: [\n                    key\n                ],\n                directChange: true\n            });\n        }\n    }\n    /**\n\t * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * If the attribute value has changed, fires the {@link #event:change:range} event with\n\t * the attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param key Key of attribute to set.\n\t * @param value Attribute value.\n\t */ setAttribute(key, value) {\n        if (this.getAttribute(key) !== value) {\n            this._attrs.set(key, value);\n            this.fire('change:attribute', {\n                attributeKeys: [\n                    key\n                ],\n                directChange: true\n            });\n        }\n    }\n    /**\n\t * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */ getSelectedElement() {\n        if (this.rangeCount !== 1) {\n            return null;\n        }\n        return this.getFirstRange().getContainedElement();\n    }\n    /**\n\t * Gets elements of type {@link module:engine/model/schema~Schema#isBlock \"block\"} touched by the selection.\n\t *\n\t * This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t *\n\t * **Note:** `getSelectedBlocks()` returns blocks that are nested in other non-block elements\n\t * but will not return blocks nested in other blocks.\n\t *\n\t * In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):\n\t *\n\t * ```xml\n\t * <paragraph>[a</paragraph>\n\t * <blockQuote>\n\t * \t<paragraph>b</paragraph>\n\t * </blockQuote>\n\t * <paragraph>c]d</paragraph>\n\t * ```\n\t *\n\t * In this case the paragraph will also be returned, despite the collapsed selection:\n\t *\n\t * ```xml\n\t * <paragraph>[]a</paragraph>\n\t * ```\n\t *\n\t * In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:\n\t *\n\t * ```xml\n\t * [<blockA></blockA>\n\t * <blockB>\n\t * \t<blockC></blockC>\n\t * \t<blockD></blockD>\n\t * </blockB>\n\t * <blockE></blockE>]\n\t * ```\n\t *\n\t * If the selection is inside a block all the inner blocks (A & B) are returned:\n\t *\n\t * ```xml\n\t * <block>\n\t * \t<blockA>[a</blockA>\n\t * \t<blockB>b]</blockB>\n\t * </block>\n\t * ```\n\t *\n\t * **Special case**: Selection ignores first and/or last blocks if nothing (from user perspective) is selected in them.\n\t *\n\t * ```xml\n\t * // Selection ends and the beginning of the last block.\n\t * <paragraph>[a</paragraph>\n\t * <paragraph>b</paragraph>\n\t * <paragraph>]c</paragraph> // This block will not be returned\n\t *\n\t * // Selection begins at the end of the first block.\n\t * <paragraph>a[</paragraph> // This block will not be returned\n\t * <paragraph>b</paragraph>\n\t * <paragraph>c]</paragraph>\n\t *\n\t * // Selection begings at the end of the first block and ends at the beginning of the last block.\n\t * <paragraph>a[</paragraph> // This block will not be returned\n\t * <paragraph>b</paragraph>\n\t * <paragraph>]c</paragraph> // This block will not be returned\n\t * ```\n\t */ *getSelectedBlocks() {\n        const visited = new WeakSet();\n        for (const range of this.getRanges()){\n            // Get start block of range in case of a collapsed range.\n            const startBlock = getParentBlock$1(range.start, visited);\n            if (isStartBlockSelected(startBlock, range)) {\n                yield startBlock;\n            }\n            for (const value of range.getWalker()){\n                const block = value.item;\n                if (value.type == 'elementEnd' && isUnvisitedTopBlock(block, visited, range)) {\n                    yield block;\n                }\n            }\n            const endBlock = getParentBlock$1(range.end, visited);\n            if (isEndBlockSelected(endBlock, range)) {\n                yield endBlock;\n            }\n        }\n    }\n    /**\n\t * Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t * at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position\n\t * touching the element's end.\n\t *\n\t * By default, this method will check whether the entire content of the selection's current root is selected.\n\t * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t */ containsEntireContent(element = this.anchor.root) {\n        const limitStartPosition = Position._createAt(element, 0);\n        const limitEndPosition = Position._createAt(element, 'end');\n        return limitStartPosition.isTouching(this.getFirstPosition()) && limitEndPosition.isTouching(this.getLastPosition());\n    }\n    /**\n\t * Adds given range to internal {@link #_ranges ranges array}. Throws an error\n\t * if given range is intersecting with any range that is already stored in this selection.\n\t */ _pushRange(range) {\n        this._checkRange(range);\n        this._ranges.push(new Range(range.start, range.end));\n    }\n    /**\n\t * Checks if given range intersects with ranges that are already in the selection. Throws an error if it does.\n\t */ _checkRange(range) {\n        for(let i = 0; i < this._ranges.length; i++){\n            if (range.isIntersecting(this._ranges[i])) {\n                /**\n\t\t\t\t * Trying to add a range that intersects with another range in the selection.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-range-intersects\n\t\t\t\t * @param addedRange Range that was added to the selection.\n\t\t\t\t * @param intersectingRange Range in the selection that intersects with `addedRange`.\n\t\t\t\t */ throw new CKEditorError('model-selection-range-intersects', [\n                    this,\n                    range\n                ], {\n                    addedRange: range,\n                    intersectingRange: this._ranges[i]\n                });\n            }\n        }\n    }\n    /**\n\t * Replaces all the ranges by the given ones.\n\t * Uses {@link #_popRange _popRange} and {@link #_pushRange _pushRange} to ensure proper ranges removal and addition.\n\t */ _replaceAllRanges(ranges) {\n        this._removeAllRanges();\n        for (const range of ranges){\n            this._pushRange(range);\n        }\n    }\n    /**\n\t * Deletes ranges from internal range array. Uses {@link #_popRange _popRange} to\n\t * ensure proper ranges removal.\n\t */ _removeAllRanges() {\n        while(this._ranges.length > 0){\n            this._popRange();\n        }\n    }\n    /**\n\t * Removes most recently added range from the selection.\n\t */ _popRange() {\n        this._ranges.pop();\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nSelection.prototype.is = function(type) {\n    return type === 'selection' || type === 'model:selection';\n};\n/**\n * Checks whether the given element extends $block in the schema and has a parent (is not a root).\n * Marks it as already visited.\n */ function isUnvisitedBlock(element, visited) {\n    if (visited.has(element)) {\n        return false;\n    }\n    visited.add(element);\n    return element.root.document.model.schema.isBlock(element) && !!element.parent;\n}\n/**\n * Checks if the given element is a $block was not previously visited and is a top block in a range.\n */ function isUnvisitedTopBlock(element, visited, range) {\n    return isUnvisitedBlock(element, visited) && isTopBlockInRange(element, range);\n}\n/**\n * Finds the lowest element in position's ancestors which is a block.\n * It will search until first ancestor that is a limit element.\n * Marks all ancestors as already visited to not include any of them later on.\n */ function getParentBlock$1(position, visited) {\n    const element = position.parent;\n    const schema = element.root.document.model.schema;\n    const ancestors = position.parent.getAncestors({\n        parentFirst: true,\n        includeSelf: true\n    });\n    let hasParentLimit = false;\n    const block = ancestors.find((element)=>{\n        // Stop searching after first parent node that is limit element.\n        if (hasParentLimit) {\n            return false;\n        }\n        hasParentLimit = schema.isLimit(element);\n        return !hasParentLimit && isUnvisitedBlock(element, visited);\n    });\n    // Mark all ancestors of this position's parent, because find() might've stopped early and\n    // the found block may be a child of another block.\n    ancestors.forEach((element)=>visited.add(element));\n    return block;\n}\n/**\n * Checks if the blocks is not nested in other block inside a range.\n */ function isTopBlockInRange(block, range) {\n    const parentBlock = findAncestorBlock(block);\n    if (!parentBlock) {\n        return true;\n    }\n    // Add loose flag to check as parentRange can be equal to range.\n    const isParentInRange = range.containsRange(Range._createOn(parentBlock), true);\n    return !isParentInRange;\n}\n/**\n * If a selection starts at the end of a block, that block is not returned as from the user's perspective this block wasn't selected.\n * See [#11585](https://github.com/ckeditor/ckeditor5/issues/11585) for more details.\n *\n * ```xml\n * <paragraph>a[</paragraph> // This block will not be returned\n * <paragraph>b</paragraph>\n * <paragraph>c]</paragraph>\n * ```\n *\n * Collapsed selection is not affected by it:\n *\n * ```xml\n * <paragraph>a[]</paragraph> // This block will be returned\n * ```\n */ function isStartBlockSelected(startBlock, range) {\n    if (!startBlock) {\n        return false;\n    }\n    if (range.isCollapsed || startBlock.isEmpty) {\n        return true;\n    }\n    if (range.start.isTouching(Position._createAt(startBlock, startBlock.maxOffset))) {\n        return false;\n    }\n    return isTopBlockInRange(startBlock, range);\n}\n/**\n * If a selection ends at the beginning of a block, that block is not returned as from the user's perspective this block wasn't selected.\n * See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n *\n * ```xml\n * <paragraph>[a</paragraph>\n * <paragraph>b</paragraph>\n * <paragraph>]c</paragraph> // this block will not be returned\n * ```\n *\n * Collapsed selection is not affected by it:\n *\n * ```xml\n * <paragraph>[]a</paragraph> // this block will be returned\n * ```\n */ function isEndBlockSelected(endBlock, range) {\n    if (!endBlock) {\n        return false;\n    }\n    if (range.isCollapsed || endBlock.isEmpty) {\n        return true;\n    }\n    if (range.end.isTouching(Position._createAt(endBlock, 0))) {\n        return false;\n    }\n    return isTopBlockInRange(endBlock, range);\n}\n/**\n * Returns first ancestor block of a node.\n */ function findAncestorBlock(node) {\n    const schema = node.root.document.model.schema;\n    let parent = node.parent;\n    while(parent){\n        if (schema.isBlock(parent)) {\n            return parent;\n        }\n        parent = parent.parent;\n    }\n}\n\n/**\n * `LiveRange` is a type of {@link module:engine/model/range~Range Range}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Be very careful when dealing with `LiveRange`. Each `LiveRange` instance bind events that might\n * have to be unbound. Use {@link module:engine/model/liverange~LiveRange#detach detach} whenever you don't need `LiveRange` anymore.\n */ class LiveRange extends /* #__PURE__ */ EmitterMixin(Range) {\n    /**\n\t * Creates a live range.\n\t *\n\t * @see module:engine/model/range~Range\n\t */ constructor(start, end){\n        super(start, end);\n        bindWithDocument$1.call(this);\n    }\n    /**\n\t * Unbinds all events previously bound by `LiveRange`. Use it whenever you don't need `LiveRange` instance\n\t * anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t * referring to it).\n\t */ detach() {\n        this.stopListening();\n    }\n    /**\n\t * Creates a {@link module:engine/model/range~Range range instance} that is equal to this live range.\n\t */ toRange() {\n        return new Range(this.start, this.end);\n    }\n    /**\n\t * Creates a `LiveRange` instance that is equal to the given range.\n\t */ static fromRange(range) {\n        return new LiveRange(range.start, range.end);\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nLiveRange.prototype.is = function(type) {\n    return type === 'liveRange' || type === 'model:liveRange' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n    type == 'range' || type === 'model:range';\n};\n/**\n * Binds this `LiveRange` to the {@link module:engine/model/document~Document document}\n * that owns this range's {@link module:engine/model/range~Range#root root}.\n */ function bindWithDocument$1() {\n    this.listenTo(this.root.document.model, 'applyOperation', (event, args)=>{\n        const operation = args[0];\n        if (!operation.isDocumentOperation) {\n            return;\n        }\n        transform$2.call(this, operation);\n    }, {\n        priority: 'low'\n    });\n}\n/**\n * Updates this range accordingly to the updates applied to the model. Bases on change events.\n */ function transform$2(operation) {\n    // Transform the range by the operation. Join the result ranges if needed.\n    const ranges = this.getTransformedByOperation(operation);\n    const result = Range._createFromRanges(ranges);\n    const boundariesChanged = !result.isEqual(this);\n    const contentChanged = doesOperationChangeRangeContent(this, operation);\n    let deletionPosition = null;\n    if (boundariesChanged) {\n        // If range boundaries have changed, fire `change:range` event.\n        //\n        if (result.root.rootName == '$graveyard') {\n            // If the range was moved to the graveyard root, set `deletionPosition`.\n            if (operation.type == 'remove') {\n                deletionPosition = operation.sourcePosition;\n            } else {\n                // Merge operation.\n                deletionPosition = operation.deletionPosition;\n            }\n        }\n        const oldRange = this.toRange();\n        this.start = result.start;\n        this.end = result.end;\n        this.fire('change:range', oldRange, {\n            deletionPosition\n        });\n    } else if (contentChanged) {\n        // If range boundaries have not changed, but there was change inside the range, fire `change:content` event.\n        this.fire('change:content', this.toRange(), {\n            deletionPosition\n        });\n    }\n}\n/**\n * Checks whether given operation changes something inside the range (even if it does not change boundaries).\n */ function doesOperationChangeRangeContent(range, operation) {\n    switch(operation.type){\n        case 'insert':\n            return range.containsPosition(operation.position);\n        case 'move':\n        case 'remove':\n        case 'reinsert':\n        case 'merge':\n            return range.containsPosition(operation.sourcePosition) || range.start.isEqual(operation.sourcePosition) || range.containsPosition(operation.targetPosition);\n        case 'split':\n            return range.containsPosition(operation.splitPosition) || range.containsPosition(operation.insertionPosition);\n    }\n    return false;\n}\n\nconst storePrefix = 'selection:';\n/**\n * `DocumentSelection` is a special selection which is used as the\n * {@link module:engine/model/document~Document#selection document's selection}.\n * There can be only one instance of `DocumentSelection` per document.\n *\n * Document selection can only be changed by using the {@link module:engine/model/writer~Writer} instance\n * inside the {@link module:engine/model/model~Model#change `change()`} block, as it provides a secure way to modify model.\n *\n * `DocumentSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}\n * to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n *\n * Differences between {@link module:engine/model/selection~Selection} and `DocumentSelection` are:\n * * there is always a range in `DocumentSelection` - even if no ranges were added there is a \"default range\"\n * present in the selection,\n * * ranges added to this selection updates automatically when the document changes,\n * * attributes of `DocumentSelection` are updated automatically according to selection ranges.\n *\n * Since `DocumentSelection` uses {@link module:engine/model/liverange~LiveRange live ranges}\n * and is updated when {@link module:engine/model/document~Document document}\n * changes, it cannot be set on {@link module:engine/model/node~Node nodes}\n * that are inside {@link module:engine/model/documentfragment~DocumentFragment document fragment}.\n * If you need to represent a selection in document fragment,\n * use {@link module:engine/model/selection~Selection Selection class} instead.\n */ class DocumentSelection extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {\n    /**\n\t * Selection used internally by that class (`DocumentSelection` is a proxy to that selection).\n\t */ _selection;\n    /**\n\t * Creates an empty live selection for given {@link module:engine/model/document~Document}.\n\t *\n\t * @param doc Document which owns this selection.\n\t */ constructor(doc){\n        super();\n        this._selection = new LiveSelection(doc);\n        this._selection.delegate('change:range').to(this);\n        this._selection.delegate('change:attribute').to(this);\n        this._selection.delegate('change:marker').to(this);\n    }\n    /**\n\t * Describes whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t */ get isCollapsed() {\n        return this._selection.isCollapsed;\n    }\n    /**\n\t * Selection anchor. Anchor may be described as a position where the most recent part of the selection starts.\n\t * Together with {@link #focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always {@link module:engine/model/range~Range#start start} or\n\t * {@link module:engine/model/range~Range#end end} position of the most recently added range.\n\t *\n\t * Is set to `null` if there are no ranges in selection.\n\t *\n\t * @see #focus\n\t */ get anchor() {\n        return this._selection.anchor;\n    }\n    /**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * Is set to `null` if there are no ranges in selection.\n\t *\n\t * @see #anchor\n\t */ get focus() {\n        return this._selection.focus;\n    }\n    /**\n\t * Number of ranges in selection.\n\t */ get rangeCount() {\n        return this._selection.rangeCount;\n    }\n    /**\n\t * Describes whether `Documentselection` has own range(s) set, or if it is defaulted to\n\t * {@link module:engine/model/document~Document#_getDefaultRange document's default range}.\n\t */ get hasOwnRange() {\n        return this._selection.hasOwnRange;\n    }\n    /**\n\t * Specifies whether the {@link #focus}\n\t * precedes {@link #anchor}.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */ get isBackward() {\n        return this._selection.isBackward;\n    }\n    /**\n\t * Describes whether the gravity is overridden (using {@link module:engine/model/writer~Writer#overrideSelectionGravity}) or not.\n\t *\n\t * Note that the gravity remains overridden as long as will not be restored the same number of times as it was overridden.\n\t */ get isGravityOverridden() {\n        return this._selection.isGravityOverridden;\n    }\n    /**\n\t * A collection of selection {@link module:engine/model/markercollection~Marker markers}.\n\t * Marker is a selection marker when selection range is inside the marker range.\n\t *\n\t * **Note**: Only markers from {@link ~DocumentSelection#observeMarkers observed markers groups} are collected.\n\t */ get markers() {\n        return this._selection.markers;\n    }\n    /**\n\t * Used for the compatibility with the {@link module:engine/model/selection~Selection#isEqual} method.\n\t *\n\t * @internal\n\t */ get _ranges() {\n        return this._selection._ranges;\n    }\n    /**\n\t * Returns an iterable that iterates over copies of selection ranges.\n\t */ getRanges() {\n        return this._selection.getRanges();\n    }\n    /**\n\t * Returns the first position in the selection.\n\t * First position is the position that {@link module:engine/model/position~Position#isBefore is before}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getFirstPosition() {\n        return this._selection.getFirstPosition();\n    }\n    /**\n\t * Returns the last position in the selection.\n\t * Last position is the position that {@link module:engine/model/position~Position#isAfter is after}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getLastPosition() {\n        return this._selection.getLastPosition();\n    }\n    /**\n\t * Returns a copy of the first range in the selection.\n\t * First range is the one which {@link module:engine/model/range~Range#start start} position\n\t * {@link module:engine/model/position~Position#isBefore is before} start position of all other ranges\n\t * (not to confuse with the first range added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getFirstRange() {\n        return this._selection.getFirstRange();\n    }\n    /**\n\t * Returns a copy of the last range in the selection.\n\t * Last range is the one which {@link module:engine/model/range~Range#end end} position\n\t * {@link module:engine/model/position~Position#isAfter is after} end position of all other ranges (not to confuse with the range most\n\t * recently added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */ getLastRange() {\n        return this._selection.getLastRange();\n    }\n    /**\n\t * Gets elements of type {@link module:engine/model/schema~Schema#isBlock \"block\"} touched by the selection.\n\t *\n\t * This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t *\n\t * **Note:** `getSelectedBlocks()` returns blocks that are nested in other non-block elements\n\t * but will not return blocks nested in other blocks.\n\t *\n\t * In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):\n\t *\n\t * ```\n\t * <paragraph>[a</paragraph>\n\t * <blockQuote>\n\t * \t<paragraph>b</paragraph>\n\t * </blockQuote>\n\t * <paragraph>c]d</paragraph>\n\t * ```\n\t *\n\t * In this case the paragraph will also be returned, despite the collapsed selection:\n\t *\n\t * ```\n\t * <paragraph>[]a</paragraph>\n\t * ```\n\t *\n\t * In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:\n\t *\n\t * ```\n\t * [<blockA></blockA>\n\t * <blockB>\n\t * \t<blockC></blockC>\n\t * \t<blockD></blockD>\n\t * </blockB>\n\t * <blockE></blockE>]\n\t * ```\n\t *\n\t * If the selection is inside a block all the inner blocks (A & B) are returned:\n\t *\n\t * ```\n\t * <block>\n\t * \t<blockA>[a</blockA>\n\t * \t<blockB>b]</blockB>\n\t * </block>\n\t * ```\n\t *\n\t * **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective\n\t * this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n\t *\n\t * ```\n\t * <paragraph>[a</paragraph>\n\t * <paragraph>b</paragraph>\n\t * <paragraph>]c</paragraph> // this block will not be returned\n\t * ```\n\t */ getSelectedBlocks() {\n        return this._selection.getSelectedBlocks();\n    }\n    /**\n\t * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */ getSelectedElement() {\n        return this._selection.getSelectedElement();\n    }\n    /**\n\t * Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t * at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position\n\t * touching the element's end.\n\t *\n\t * By default, this method will check whether the entire content of the selection's current root is selected.\n\t * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t */ containsEntireContent(element) {\n        return this._selection.containsEntireContent(element);\n    }\n    /**\n\t * Unbinds all events previously bound by document selection.\n\t */ destroy() {\n        this._selection.destroy();\n    }\n    /**\n\t * Returns iterable that iterates over this selection's attribute keys.\n\t */ getAttributeKeys() {\n        return this._selection.getAttributeKeys();\n    }\n    /**\n\t * Returns iterable that iterates over this selection's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */ getAttributes() {\n        return this._selection.getAttributes();\n    }\n    /**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */ getAttribute(key) {\n        return this._selection.getAttribute(key);\n    }\n    /**\n\t * Checks if the selection has an attribute for given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on selection, `false` otherwise.\n\t */ hasAttribute(key) {\n        return this._selection.hasAttribute(key);\n    }\n    /**\n\t * Refreshes selection attributes and markers according to the current position in the model.\n\t */ refresh() {\n        this._selection.updateMarkers();\n        this._selection._updateAttributes(false);\n    }\n    /**\n\t * Registers a marker group prefix or a marker name to be collected in the\n\t * {@link ~DocumentSelection#markers selection markers collection}.\n\t *\n\t * See also {@link module:engine/model/markercollection~MarkerCollection#getMarkersGroup `MarkerCollection#getMarkersGroup()`}.\n\t *\n\t * @param prefixOrName The marker group prefix or marker name.\n\t */ observeMarkers(prefixOrName) {\n        this._selection.observeMarkers(prefixOrName);\n    }\n    /**\n\t * Moves {@link module:engine/model/documentselection~DocumentSelection#focus} to the specified location.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelectionFocus} method.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link module:engine/model/writer~Writer#createPositionAt writer.createPositionAt()} parameters.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelectionFocus\n\t * @internal\n\t * @param offset Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */ _setFocus(itemOrPosition, offset) {\n        this._selection.setFocus(itemOrPosition, offset);\n    }\n    /**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable}.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelection} method.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelection\n\t * @internal\n\t */ _setTo(...args) {\n        this._selection.setTo(...args);\n    }\n    /**\n\t * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelectionAttribute} method.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelectionAttribute\n\t * @internal\n\t * @param key Key of the attribute to set.\n\t * @param value Attribute value.\n\t */ _setAttribute(key, value) {\n        this._selection.setAttribute(key, value);\n    }\n    /**\n\t * Removes an attribute with given key from the selection.\n\t * If the given attribute was set on the selection, fires the {@link module:engine/model/selection~Selection#event:change:range}\n\t * event with removed attribute key.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#removeSelectionAttribute} method.\n\t *\n\t * @see module:engine/model/writer~Writer#removeSelectionAttribute\n\t * @internal\n\t * @param key Key of the attribute to remove.\n\t */ _removeAttribute(key) {\n        this._selection.removeAttribute(key);\n    }\n    /**\n\t * Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t *\n\t * @internal\n\t */ _getStoredAttributes() {\n        return this._selection.getStoredAttributes();\n    }\n    /**\n\t * Temporarily changes the gravity of the selection from the left to the right.\n\t *\n\t * The gravity defines from which direction the selection inherits its attributes. If it's the default left\n\t * gravity, the selection (after being moved by the the user) inherits attributes from its left hand side.\n\t * This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t *\n\t * It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t * of the process.\n\t *\n\t * @see module:engine/model/writer~Writer#overrideSelectionGravity\n\t * @internal\n\t * @returns The unique id which allows restoring the gravity.\n\t */ _overrideGravity() {\n        return this._selection.overrideGravity();\n    }\n    /**\n\t * Restores the {@link ~DocumentSelection#_overrideGravity overridden gravity}.\n\t *\n\t * Restoring the gravity is only possible using the unique identifier returned by\n\t * {@link ~DocumentSelection#_overrideGravity}. Note that the gravity remains overridden as long as won't be restored\n\t * the same number of times it was overridden.\n\t *\n\t * @see module:engine/model/writer~Writer#restoreSelectionGravity\n\t * @internal\n\t * @param uid The unique id returned by {@link #_overrideGravity}.\n\t */ _restoreGravity(uid) {\n        this._selection.restoreGravity(uid);\n    }\n    /**\n\t * Generates and returns an attribute key for selection attributes store, basing on original attribute key.\n\t *\n\t * @internal\n\t * @param key Attribute key to convert.\n\t * @returns Converted attribute key, applicable for selection store.\n\t */ static _getStoreAttributeKey(key) {\n        return storePrefix + key;\n    }\n    /**\n\t * Checks whether the given attribute key is an attribute stored on an element.\n\t *\n\t * @internal\n\t */ static _isStoreAttributeKey(key) {\n        return key.startsWith(storePrefix);\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentSelection.prototype.is = function(type) {\n    return type === 'selection' || type == 'model:selection' || type == 'documentSelection' || type == 'model:documentSelection';\n};\n/**\n * `LiveSelection` is used internally by {@link module:engine/model/documentselection~DocumentSelection} and shouldn't be used directly.\n *\n * LiveSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}\n * to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n *\n * Differences between {@link module:engine/model/selection~Selection} and `LiveSelection` are:\n * * there is always a range in `LiveSelection` - even if no ranges were added there is a \"default range\"\n * present in the selection,\n * * ranges added to this selection updates automatically when the document changes,\n * * attributes of `LiveSelection` are updated automatically according to selection ranges.\n */ class LiveSelection extends Selection {\n    /**\n\t * List of selection markers.\n\t * Marker is a selection marker when selection range is inside the marker range.\n\t */ markers = new Collection({\n        idProperty: 'name'\n    });\n    /**\n\t * Document which owns this selection.\n\t */ _model;\n    /**\n\t * Document which owns this selection.\n\t */ _document;\n    /**\n\t * Keeps mapping of attribute name to priority with which the attribute got modified (added/changed/removed)\n\t * last time. Possible values of priority are: `'low'` and `'normal'`.\n\t *\n\t * Priorities are used by internal `LiveSelection` mechanisms. All attributes set using `LiveSelection`\n\t * attributes API are set with `'normal'` priority.\n\t */ _attributePriority = new Map();\n    /**\n\t * Position to which the selection should be set if the last selection range was moved to the graveyard.\n\t */ _selectionRestorePosition = null;\n    /**\n\t * Flag that informs whether the selection ranges have changed. It is changed on true when `LiveRange#change:range` event is fired.\n\t */ _hasChangedRange = false;\n    /**\n\t * Each overriding gravity adds an UID to the set and each removal removes it.\n\t * Gravity is overridden when there's at least one UID in the set.\n\t * Gravity is restored when the set is empty.\n\t * This is to prevent conflicts when gravity is overridden by more than one feature at the same time.\n\t */ _overriddenGravityRegister = new Set();\n    /**\n\t * Prefixes of marker names that should affect `LiveSelection#markers` collection.\n\t */ _observedMarkers = new Set();\n    /**\n\t * Creates an empty live selection for given {@link module:engine/model/document~Document}.\n\t *\n\t * @param doc Document which owns this selection.\n\t */ constructor(doc){\n        super();\n        this._model = doc.model;\n        this._document = doc;\n        // Ensure selection is correct after each operation.\n        this.listenTo(this._model, 'applyOperation', (evt, args)=>{\n            const operation = args[0];\n            if (!operation.isDocumentOperation || operation.type == 'marker' || operation.type == 'rename' || operation.type == 'noop') {\n                return;\n            }\n            // Fix selection if the last range was removed from it and we have a position to which we can restore the selection.\n            if (this._ranges.length == 0 && this._selectionRestorePosition) {\n                this._fixGraveyardSelection(this._selectionRestorePosition);\n            }\n            // \"Forget\" the restore position even if it was not \"used\".\n            this._selectionRestorePosition = null;\n            if (this._hasChangedRange) {\n                this._hasChangedRange = false;\n                this.fire('change:range', {\n                    directChange: false\n                });\n            }\n        }, {\n            priority: 'lowest'\n        });\n        // Ensure selection is correct and up to date after each range change.\n        this.on('change:range', ()=>{\n            this._validateSelectionRanges(this.getRanges());\n        });\n        // Update markers data stored by the selection after each marker change.\n        // This handles only marker changes done through marker operations (not model tree changes).\n        this.listenTo(this._model.markers, 'update', (evt, marker, oldRange, newRange)=>{\n            this._updateMarker(marker, newRange);\n        });\n        // Ensure selection is up to date after each change block.\n        this.listenTo(this._document, 'change', (evt, batch)=>{\n            clearAttributesStoredInElement(this._model, batch);\n        });\n    }\n    get isCollapsed() {\n        const length = this._ranges.length;\n        return length === 0 ? this._document._getDefaultRange().isCollapsed : super.isCollapsed;\n    }\n    get anchor() {\n        return super.anchor || this._document._getDefaultRange().start;\n    }\n    get focus() {\n        return super.focus || this._document._getDefaultRange().end;\n    }\n    get rangeCount() {\n        return this._ranges.length ? this._ranges.length : 1;\n    }\n    /**\n\t * Describes whether `LiveSelection` has own range(s) set, or if it is defaulted to\n\t * {@link module:engine/model/document~Document#_getDefaultRange document's default range}.\n\t */ get hasOwnRange() {\n        return this._ranges.length > 0;\n    }\n    /**\n\t * When set to `true` then selection attributes on node before the caret won't be taken\n\t * into consideration while updating selection attributes.\n\t */ get isGravityOverridden() {\n        return !!this._overriddenGravityRegister.size;\n    }\n    /**\n\t * Unbinds all events previously bound by live selection.\n\t */ destroy() {\n        for(let i = 0; i < this._ranges.length; i++){\n            this._ranges[i].detach();\n        }\n        this.stopListening();\n    }\n    *getRanges() {\n        if (this._ranges.length) {\n            yield* super.getRanges();\n        } else {\n            yield this._document._getDefaultRange();\n        }\n    }\n    getFirstRange() {\n        return super.getFirstRange() || this._document._getDefaultRange();\n    }\n    getLastRange() {\n        return super.getLastRange() || this._document._getDefaultRange();\n    }\n    setTo(...args) {\n        super.setTo(...args);\n        this._updateAttributes(true);\n        this.updateMarkers();\n    }\n    setFocus(itemOrPosition, offset) {\n        super.setFocus(itemOrPosition, offset);\n        this._updateAttributes(true);\n        this.updateMarkers();\n    }\n    setAttribute(key, value) {\n        if (this._setAttribute(key, value)) {\n            // Fire event with exact data.\n            const attributeKeys = [\n                key\n            ];\n            this.fire('change:attribute', {\n                attributeKeys,\n                directChange: true\n            });\n        }\n    }\n    removeAttribute(key) {\n        if (this._removeAttribute(key)) {\n            // Fire event with exact data.\n            const attributeKeys = [\n                key\n            ];\n            this.fire('change:attribute', {\n                attributeKeys,\n                directChange: true\n            });\n        }\n    }\n    overrideGravity() {\n        const overrideUid = uid();\n        // Remember that another overriding has been requested. It will need to be removed\n        // before the gravity is to be restored.\n        this._overriddenGravityRegister.add(overrideUid);\n        if (this._overriddenGravityRegister.size === 1) {\n            this._updateAttributes(true);\n        }\n        return overrideUid;\n    }\n    restoreGravity(uid) {\n        if (!this._overriddenGravityRegister.has(uid)) {\n            /**\n\t\t\t * Restoring gravity for an unknown UID is not possible. Make sure you are using a correct\n\t\t\t * UID obtained from the {@link module:engine/model/writer~Writer#overrideSelectionGravity} to restore.\n\t\t\t *\n\t\t\t * @error document-selection-gravity-wrong-restore\n\t\t\t * @param uid The unique identifier returned by\n\t\t\t * {@link module:engine/model/documentselection~DocumentSelection#_overrideGravity}.\n\t\t\t */ throw new CKEditorError('document-selection-gravity-wrong-restore', this, {\n                uid\n            });\n        }\n        this._overriddenGravityRegister.delete(uid);\n        // Restore gravity only when all overriding have been restored.\n        if (!this.isGravityOverridden) {\n            this._updateAttributes(true);\n        }\n    }\n    observeMarkers(prefixOrName) {\n        this._observedMarkers.add(prefixOrName);\n        this.updateMarkers();\n    }\n    _replaceAllRanges(ranges) {\n        this._validateSelectionRanges(ranges);\n        super._replaceAllRanges(ranges);\n    }\n    _popRange() {\n        this._ranges.pop().detach();\n    }\n    _pushRange(range) {\n        const liveRange = this._prepareRange(range);\n        // `undefined` is returned when given `range` is in graveyard root.\n        if (liveRange) {\n            this._ranges.push(liveRange);\n        }\n    }\n    _validateSelectionRanges(ranges) {\n        for (const range of ranges){\n            if (!this._document._validateSelectionRange(range)) {\n                /**\n\t\t\t\t * Range from {@link module:engine/model/documentselection~DocumentSelection document selection}\n\t\t\t\t * starts or ends at incorrect position.\n\t\t\t\t *\n\t\t\t\t * @error document-selection-wrong-position\n\t\t\t\t * @param range\n\t\t\t\t */ throw new CKEditorError('document-selection-wrong-position', this, {\n                    range\n                });\n            }\n        }\n    }\n    /**\n\t * Prepares given range to be added to selection. Checks if it is correct,\n\t * converts it to {@link module:engine/model/liverange~LiveRange LiveRange}\n\t * and sets listeners listening to the range's change event.\n\t */ _prepareRange(range) {\n        this._checkRange(range);\n        if (range.root == this._document.graveyard) {\n            // @if CK_DEBUG // console.warn( 'Trying to add a Range that is in the graveyard root. Range rejected.' );\n            return;\n        }\n        const liveRange = LiveRange.fromRange(range);\n        // If selection range is moved to the graveyard remove it from the selection object.\n        // Also, save some data that can be used to restore selection later, on `Model#applyOperation` event.\n        liveRange.on('change:range', (evt, oldRange, data)=>{\n            this._hasChangedRange = true;\n            if (liveRange.root == this._document.graveyard) {\n                this._selectionRestorePosition = data.deletionPosition;\n                const index = this._ranges.indexOf(liveRange);\n                this._ranges.splice(index, 1);\n                liveRange.detach();\n            }\n        });\n        return liveRange;\n    }\n    updateMarkers() {\n        if (!this._observedMarkers.size) {\n            return;\n        }\n        const markers = [];\n        let changed = false;\n        for (const marker of this._model.markers){\n            const markerGroup = marker.name.split(':', 1)[0];\n            if (!this._observedMarkers.has(markerGroup)) {\n                continue;\n            }\n            const markerRange = marker.getRange();\n            for (const selectionRange of this.getRanges()){\n                if (markerRange.containsRange(selectionRange, !selectionRange.isCollapsed)) {\n                    markers.push(marker);\n                }\n            }\n        }\n        const oldMarkers = Array.from(this.markers);\n        for (const marker of markers){\n            if (!this.markers.has(marker)) {\n                this.markers.add(marker);\n                changed = true;\n            }\n        }\n        for (const marker of Array.from(this.markers)){\n            if (!markers.includes(marker)) {\n                this.markers.remove(marker);\n                changed = true;\n            }\n        }\n        if (changed) {\n            this.fire('change:marker', {\n                oldMarkers,\n                directChange: false\n            });\n        }\n    }\n    _updateMarker(marker, markerRange) {\n        const markerGroup = marker.name.split(':', 1)[0];\n        if (!this._observedMarkers.has(markerGroup)) {\n            return;\n        }\n        let changed = false;\n        const oldMarkers = Array.from(this.markers);\n        const hasMarker = this.markers.has(marker);\n        if (!markerRange) {\n            if (hasMarker) {\n                this.markers.remove(marker);\n                changed = true;\n            }\n        } else {\n            let contained = false;\n            for (const selectionRange of this.getRanges()){\n                if (markerRange.containsRange(selectionRange, !selectionRange.isCollapsed)) {\n                    contained = true;\n                    break;\n                }\n            }\n            if (contained && !hasMarker) {\n                this.markers.add(marker);\n                changed = true;\n            } else if (!contained && hasMarker) {\n                this.markers.remove(marker);\n                changed = true;\n            }\n        }\n        if (changed) {\n            this.fire('change:marker', {\n                oldMarkers,\n                directChange: false\n            });\n        }\n    }\n    /**\n\t * Updates this selection attributes according to its ranges and the {@link module:engine/model/document~Document model document}.\n\t */ _updateAttributes(clearAll) {\n        const newAttributes = toMap(this._getSurroundingAttributes());\n        const oldAttributes = toMap(this.getAttributes());\n        if (clearAll) {\n            // If `clearAll` remove all attributes and reset priorities.\n            this._attributePriority = new Map();\n            this._attrs = new Map();\n        } else {\n            // If not, remove only attributes added with `low` priority.\n            for (const [key, priority] of this._attributePriority){\n                if (priority == 'low') {\n                    this._attrs.delete(key);\n                    this._attributePriority.delete(key);\n                }\n            }\n        }\n        this._setAttributesTo(newAttributes);\n        // Let's evaluate which attributes really changed.\n        const changed = [];\n        // First, loop through all attributes that are set on selection right now.\n        // Check which of them are different than old attributes.\n        for (const [newKey, newValue] of this.getAttributes()){\n            if (!oldAttributes.has(newKey) || oldAttributes.get(newKey) !== newValue) {\n                changed.push(newKey);\n            }\n        }\n        // Then, check which of old attributes got removed.\n        for (const [oldKey] of oldAttributes){\n            if (!this.hasAttribute(oldKey)) {\n                changed.push(oldKey);\n            }\n        }\n        // Fire event with exact data (fire only if anything changed).\n        if (changed.length > 0) {\n            this.fire('change:attribute', {\n                attributeKeys: changed,\n                directChange: false\n            });\n        }\n    }\n    /**\n\t * Internal method for setting `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t * parameter).\n\t */ _setAttribute(key, value, directChange = true) {\n        const priority = directChange ? 'normal' : 'low';\n        if (priority == 'low' && this._attributePriority.get(key) == 'normal') {\n            // Priority too low.\n            return false;\n        }\n        const oldValue = super.getAttribute(key);\n        // Don't do anything if value has not changed.\n        if (oldValue === value) {\n            return false;\n        }\n        this._attrs.set(key, value);\n        // Update priorities map.\n        this._attributePriority.set(key, priority);\n        return true;\n    }\n    /**\n\t * Internal method for removing `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t * parameter).\n\t *\n\t * NOTE: Even if attribute is not present in the selection but is provided to this method, it's priority will\n\t * be changed according to `directChange` parameter.\n\t */ _removeAttribute(key, directChange = true) {\n        const priority = directChange ? 'normal' : 'low';\n        if (priority == 'low' && this._attributePriority.get(key) == 'normal') {\n            // Priority too low.\n            return false;\n        }\n        // Update priorities map.\n        this._attributePriority.set(key, priority);\n        // Don't do anything if value has not changed.\n        if (!super.hasAttribute(key)) {\n            return false;\n        }\n        this._attrs.delete(key);\n        return true;\n    }\n    /**\n\t * Internal method for setting multiple `LiveSelection` attributes. Supports attribute priorities (through\n\t * `directChange` parameter).\n\t */ _setAttributesTo(attrs) {\n        const changed = new Set();\n        for (const [oldKey, oldValue] of this.getAttributes()){\n            // Do not remove attribute if attribute with same key and value is about to be set.\n            if (attrs.get(oldKey) === oldValue) {\n                continue;\n            }\n            // All rest attributes will be removed so changed attributes won't change .\n            this._removeAttribute(oldKey, false);\n        }\n        for (const [key, value] of attrs){\n            // Attribute may not be set because of attributes or because same key/value is already added.\n            const gotAdded = this._setAttribute(key, value, false);\n            if (gotAdded) {\n                changed.add(key);\n            }\n        }\n        return changed;\n    }\n    /**\n\t * Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t */ *getStoredAttributes() {\n        const selectionParent = this.getFirstPosition().parent;\n        if (this.isCollapsed && selectionParent.isEmpty) {\n            for (const key of selectionParent.getAttributeKeys()){\n                if (key.startsWith(storePrefix)) {\n                    const realKey = key.substr(storePrefix.length);\n                    yield [\n                        realKey,\n                        selectionParent.getAttribute(key)\n                    ];\n                }\n            }\n        }\n    }\n    /**\n\t * Checks model text nodes that are closest to the selection's first position and returns attributes of first\n\t * found element. If there are no text nodes in selection's first position parent, it returns selection\n\t * attributes stored in that parent.\n\t */ _getSurroundingAttributes() {\n        const position = this.getFirstPosition();\n        const schema = this._model.schema;\n        if (position.root.rootName == '$graveyard') {\n            return null;\n        }\n        let attrs = null;\n        if (!this.isCollapsed) {\n            // 1. If selection is a range...\n            const range = this.getFirstRange();\n            // ...look for a first character node in that range and take attributes from it.\n            for (const value of range){\n                // If the item is an object, we don't want to get attributes from its children...\n                if (value.item.is('element') && schema.isObject(value.item)) {\n                    // ...but collect attributes from inline object.\n                    attrs = getTextAttributes(value.item, schema);\n                    break;\n                }\n                if (value.type == 'text') {\n                    attrs = value.item.getAttributes();\n                    break;\n                }\n            }\n        } else {\n            // 2. If the selection is a caret or the range does not contain a character node...\n            const nodeBefore = position.textNode ? position.textNode : position.nodeBefore;\n            const nodeAfter = position.textNode ? position.textNode : position.nodeAfter;\n            // When gravity is overridden then don't take node before into consideration.\n            if (!this.isGravityOverridden) {\n                // ...look at the node before caret and take attributes from it if it is a character node.\n                attrs = getTextAttributes(nodeBefore, schema);\n            }\n            // 3. If not, look at the node after caret...\n            if (!attrs) {\n                attrs = getTextAttributes(nodeAfter, schema);\n            }\n            // 4. If not, try to find the first character on the left, that is in the same node.\n            // When gravity is overridden then don't take node before into consideration.\n            if (!this.isGravityOverridden && !attrs) {\n                let node = nodeBefore;\n                while(node && !attrs){\n                    node = node.previousSibling;\n                    attrs = getTextAttributes(node, schema);\n                }\n            }\n            // 5. If not found, try to find the first character on the right, that is in the same node.\n            if (!attrs) {\n                let node = nodeAfter;\n                while(node && !attrs){\n                    node = node.nextSibling;\n                    attrs = getTextAttributes(node, schema);\n                }\n            }\n            // 6. If not found, selection should retrieve attributes from parent.\n            if (!attrs) {\n                attrs = this.getStoredAttributes();\n            }\n        }\n        return attrs;\n    }\n    /**\n\t * Fixes the selection after all its ranges got removed.\n\t * @param deletionPosition Position where the deletion happened.\n\t */ _fixGraveyardSelection(deletionPosition) {\n        // Find a range that is a correct selection range and is closest to the position where the deletion happened.\n        const selectionRange = this._model.schema.getNearestSelectionRange(deletionPosition);\n        // If nearest valid selection range has been found - add it in the place of old range.\n        if (selectionRange) {\n            // Check the range, convert it to live range, bind events, etc.\n            this._pushRange(selectionRange);\n        }\n    // If nearest valid selection range cannot be found don't add any range. Selection will be set to the default range.\n    }\n}\n/**\n * Helper function for {@link module:engine/model/liveselection~LiveSelection#_updateAttributes}.\n *\n * It checks if the passed model item is a text node (or text proxy) and, if so, returns it's attributes.\n * If not, it checks if item is an inline object and does the same. Otherwise it returns `null`.\n */ function getTextAttributes(node, schema) {\n    if (!node) {\n        return null;\n    }\n    if (node instanceof TextProxy || node instanceof Text) {\n        return node.getAttributes();\n    }\n    if (!schema.isInline(node)) {\n        return null;\n    }\n    // Stop on inline elements (such as `<softBreak>`) that are not objects (such as `<imageInline>` or `<mathml>`).\n    if (!schema.isObject(node)) {\n        return [];\n    }\n    const attributes = [];\n    // Collect all attributes that can be applied to the text node.\n    for (const [key, value] of node.getAttributes()){\n        if (schema.checkAttribute('$text', key) && schema.getAttributeProperties(key).copyFromObject !== false) {\n            attributes.push([\n                key,\n                value\n            ]);\n        }\n    }\n    return attributes;\n}\n/**\n * Removes selection attributes from element which is not empty anymore.\n */ function clearAttributesStoredInElement(model, batch) {\n    const differ = model.document.differ;\n    for (const entry of differ.getChanges()){\n        if (entry.type != 'insert') {\n            continue;\n        }\n        const changeParent = entry.position.parent;\n        const isNoLongerEmpty = entry.length === changeParent.maxOffset;\n        if (isNoLongerEmpty) {\n            model.enqueueChange(batch, (writer)=>{\n                const storedAttributes = Array.from(changeParent.getAttributeKeys()).filter((key)=>key.startsWith(storePrefix));\n                for (const key of storedAttributes){\n                    writer.removeAttribute(key, changeParent);\n                }\n            });\n        }\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module engine/conversion/conversionhelpers\n */ /**\n * Base class for conversion helpers.\n */ class ConversionHelpers {\n    _dispatchers;\n    /**\n\t * Creates a conversion helpers instance.\n\t */ constructor(dispatchers){\n        this._dispatchers = dispatchers;\n    }\n    /**\n\t * Registers a conversion helper.\n\t *\n\t * **Note**: See full usage example in the `{@link module:engine/conversion/conversion~Conversion#for conversion.for()}`\n\t * method description.\n\t *\n\t * @param conversionHelper The function to be called on event.\n\t */ add(conversionHelper) {\n        for (const dispatcher of this._dispatchers){\n            conversionHelper(dispatcher);\n        }\n        return this;\n    }\n}\n\n/**\n * Downcast conversion helper functions.\n *\n * Learn more about {@glink framework/deep-dive/conversion/downcast downcast helpers}.\n *\n * @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n */ class DowncastHelpers extends ConversionHelpers {\n    /**\n\t * Model element to view element conversion helper.\n\t *\n\t * This conversion results in creating a view element. For example, model `<paragraph>Foo</paragraph>` becomes `<p>Foo</p>` in the view.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'paragraph',\n\t * \tview: 'p'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'paragraph',\n\t * \tview: 'div',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'fancyParagraph',\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'fancy'\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'heading',\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * The element-to-element conversion supports the reconversion mechanism. It can be enabled by using either the `attributes` or\n\t * the `children` props on a model description. You will find a couple examples below.\n\t *\n\t * In order to reconvert an element if any of its direct children have been added or removed, use the `children` property on a `model`\n\t * description. For example, this model:\n\t *\n\t * ```xml\n\t * <box>\n\t * \t<paragraph>Some text.</paragraph>\n\t * </box>\n\t * ```\n\t *\n\t * will be converted into this structure in the view:\n\t *\n\t * ```html\n\t * <div class=\"box\" data-type=\"single\">\n\t * \t<p>Some text.</p>\n\t * </div>\n\t * ```\n\t *\n\t * But if more items were inserted in the model:\n\t *\n\t * ```xml\n\t * <box>\n\t * \t<paragraph>Some text.</paragraph>\n\t * \t<paragraph>Other item.</paragraph>\n\t * </box>\n\t * ```\n\t *\n\t * it will be converted into this structure in the view (note the element `data-type` change):\n\t *\n\t * ```html\n\t * <div class=\"box\" data-type=\"multiple\">\n\t * \t<p>Some text.</p>\n\t * \t<p>Other item.</p>\n\t * </div>\n\t * ```\n\t *\n\t * Such a converter would look like this (note that the `paragraph` elements are converted separately):\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: {\n\t * \t\tname: 'box',\n\t * \t\tchildren: true\n\t * \t},\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createContainerElement( 'div', {\n\t * \t\t\tclass: 'box',\n\t * \t\t\t'data-type': modelElement.childCount == 1 ? 'single' : 'multiple'\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * In order to reconvert element if any of its attributes have been updated, use the `attributes` property on a `model`\n\t * description. For example, this model:\n\t *\n\t * ```xml\n\t * <heading level=\"2\">Some text.</heading>\n\t * ```\n\t *\n\t * will be converted into this structure in the view:\n\t *\n\t * ```html\n\t * <h2>Some text.</h2>\n\t * ```\n\t *\n\t * But if the `heading` element's `level` attribute has been updated to `3` for example, then\n\t * it will be converted into this structure in the view:\n\t *\n\t * ```html\n\t * <h3>Some text.</h3>\n\t * ```\n\t *\n\t * Such a converter would look as follows:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: {\n\t * \t\tname: 'heading',\n\t * \t\tattributes: 'level'\n\t * \t},\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * You can read more about the element-to-element conversion in the\n\t * {@glink framework/deep-dive/conversion/downcast downcast conversion} guide.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The description or a name of the model element to convert.\n\t * @param config.model.attributes The list of attribute names that should be consumed while creating\n\t * the view element. Note that the view will be reconverted if any of the listed attributes changes.\n \t * @param config.model.children Specifies whether the view element requires reconversion if the list\n\t * of the model child nodes changed.\n\t * @param config.view A view element definition or a function that takes the model element and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as parameters and returns a view container element.\n\t */ elementToElement(config) {\n        return this.add(downcastElementToElement(config));\n    }\n    /**\n\t * The model element to view structure (several elements) conversion helper.\n\t *\n\t * This conversion results in creating a view structure with one or more slots defined for the child nodes.\n\t * For example, a model `<table>` may become this structure in the view:\n\t *\n\t * ```html\n\t * <figure class=\"table\">\n\t * \t<table>\n\t * \t\t<tbody>${ slot for table rows }</tbody>\n\t * \t</table>\n\t * </figure>\n\t * ```\n\t *\n\t * The children of the model's `<table>` element will be inserted into the `<tbody>` element.\n\t * If the `elementToElement()` helper was used, the children would be inserted into the `<figure>`.\n\t *\n\t * Imagine a table feature where for this model structure:\n\t *\n\t * ```xml\n\t * <table headingRows=\"1\">\n\t * \t<tableRow> ... table cells 1 ... </tableRow>\n\t * \t<tableRow> ... table cells 2 ... </tableRow>\n\t * \t<tableRow> ... table cells 3 ... </tableRow>\n\t * \t<caption>Caption text</caption>\n\t * </table>\n\t * ```\n\t *\n\t * we want to generate this view structure:\n\t *\n\t * ```html\n\t * <figure class=\"table\">\n\t * \t<table>\n\t * \t\t<thead>\n\t * \t\t\t<tr> ... table cells 1 ... </tr>\n\t * \t\t</thead>\n\t * \t\t<tbody>\n\t * \t\t\t<tr> ... table cells 2 ... </tr>\n\t * \t\t\t<tr> ... table cells 3 ... </tr>\n\t * \t\t</tbody>\n\t * \t</table>\n\t * \t<figcaption>Caption text</figcaption>\n\t * </figure>\n\t * ```\n\t *\n\t * The converter has to take the `headingRows` attribute into consideration when allocating the `<tableRow>` elements\n\t * into the `<tbody>` and `<thead>` elements. Hence, we need two slots and need to define proper filter callbacks for them.\n\t *\n\t * Additionally, all elements other than `<tableRow>` should be placed outside the `<table>` tag.\n\t * In the example above, this will handle the table caption.\n\t *\n\t * Such a converter would look like this:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToStructure( {\n\t * \tmodel: {\n\t * \t\tname: 'table',\n\t * \t\tattributes: [ 'headingRows' ]\n\t * \t},\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\tconst figureElement = writer.createContainerElement( 'figure', { class: 'table' } );\n\t * \t\tconst tableElement = writer.createContainerElement( 'table' );\n\t *\n\t * \t\twriter.insert( writer.createPositionAt( figureElement, 0 ), tableElement );\n\t *\n\t * \t\tconst headingRows = modelElement.getAttribute( 'headingRows' ) || 0;\n\t *\n\t * \t\tif ( headingRows > 0 ) {\n\t * \t\t\tconst tableHead = writer.createContainerElement( 'thead' );\n\t *\n\t * \t\t\tconst headSlot = writer.createSlot( node => node.is( 'element', 'tableRow' ) && node.index < headingRows );\n\t *\n\t * \t\t\twriter.insert( writer.createPositionAt( tableElement, 'end' ), tableHead );\n\t * \t\t\twriter.insert( writer.createPositionAt( tableHead, 0 ), headSlot );\n\t * \t\t}\n\t *\n\t * \t\tif ( headingRows < tableUtils.getRows( table ) ) {\n\t * \t\t\tconst tableBody = writer.createContainerElement( 'tbody' );\n\t *\n\t * \t\t\tconst bodySlot = writer.createSlot( node => node.is( 'element', 'tableRow' ) && node.index >= headingRows );\n\t *\n\t * \t\t\twriter.insert( writer.createPositionAt( tableElement, 'end' ), tableBody );\n\t * \t\t\twriter.insert( writer.createPositionAt( tableBody, 0 ), bodySlot );\n\t * \t\t}\n\t *\n\t * \t\tconst restSlot = writer.createSlot( node => !node.is( 'element', 'tableRow' ) );\n\t *\n\t * \t\twriter.insert( writer.createPositionAt( figureElement, 'end' ), restSlot );\n\t *\n\t * \t\treturn figureElement;\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Note: The children of a model element that's being converted must be allocated in the same order in the view\n\t * in which they are placed in the model.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n \t * @param config.model The description or a name of the model element to convert.\n\t * @param config.model.name The name of the model element to convert.\n \t * @param config.model.attributes The list of attribute names that should be consumed while creating\n\t * the view structure. Note that the view will be reconverted if any of the listed attributes will change.\n\t * @param config.view A function that takes the model element and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters\n\t * and returns a view container element with slots for model child nodes to be converted into.\n\t */ elementToStructure(config) {\n        return this.add(downcastElementToStructure(config));\n    }\n    /**\n\t * Model attribute to view element conversion helper.\n\t *\n\t * This conversion results in wrapping view nodes with a view attribute element. For example, a model text node with\n\t * `\"Foo\"` as data and the `bold` attribute becomes `<strong>Foo</strong>` in the view.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: 'strong'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: 'b',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'invert',\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: [ 'font-light', 'bg-dark' ]\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'fontSize',\n\t * \t\tvalues: [ 'big', 'small' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tbig: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '1.2em'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tsmall: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '0.8em'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: ( modelAttributeValue, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createAttributeElement( 'span', {\n\t * \t\t\tstyle: 'font-weight:' + modelAttributeValue\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'color',\n\t * \t\tname: '$text'\n\t * \t},\n\t * \tview: ( modelAttributeValue, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createAttributeElement( 'span', {\n\t * \t\t\tstyle: 'color:' + modelAttributeValue\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n\t * of `String`s with possible values if the model attribute is an enumerable.\n\t * @param config.view A view element definition or a function\n\t * that takes the model attribute value and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters and returns a view\n\t * attribute element. If `config.model.values` is given, `config.view` should be an object assigning values from `config.model.values`\n\t * to view element definitions or functions.\n\t * @param config.converterPriority Converter priority.\n\t */ attributeToElement(config) {\n        return this.add(downcastAttributeToElement(config));\n    }\n    /**\n\t * Model attribute to view attribute conversion helper.\n\t *\n\t * This conversion results in adding an attribute to a view node, basing on an attribute from a model node. For example,\n\t * `<imageInline src='foo.jpg'></imageInline>` is converted to `<img src='foo.jpg'></img>`.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'source',\n\t * \tview: 'src'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'source',\n\t * \tview: 'href',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'imageInline',\n\t * \t\tkey: 'source'\n\t * \t},\n\t * \tview: 'src'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'styled',\n\t * \t\tvalues: [ 'dark', 'light' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tdark: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: [ 'styled', 'styled-dark' ]\n\t * \t\t},\n\t * \t\tlight: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: [ 'styled', 'styled-light' ]\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'styled',\n\t * \tview: modelAttributeValue => ( {\n\t * \t\tkey: 'class',\n\t * \t\tvalue: 'styled-' + modelAttributeValue\n\t * \t} )\n\t * } );\n\t * ```\n\t *\n\t * **Note**: Downcasting to a style property requires providing `value` as an object:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'lineHeight',\n\t * \tview: modelAttributeValue => ( {\n\t * \t\tkey: 'style',\n\t * \t\tvalue: {\n\t * \t\t\t'line-height': modelAttributeValue,\n\t * \t\t\t'border-bottom': '1px dotted #ba2'\n\t * \t\t}\n\t * \t} )\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n\t * the attribute key, possible values and, optionally, an element name to convert from.\n\t * @param config.view A view attribute key, or a `{ key, value }` object or a function that takes the model attribute value and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as parameters and returns a `{ key, value }` object. If the `key` is `'class'`, the `value` can be a `String` or an\n\t * array of `String`s. If the `key` is `'style'`, the `value` is an object with key-value pairs. In other cases, `value` is a `String`.\n\t * If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n\t * `{ key, value }` objects or a functions.\n\t * @param config.converterPriority Converter priority.\n\t */ attributeToAttribute(config) {\n        return this.add(downcastAttributeToAttribute(config));\n    }\n    /**\n\t * Model marker to view element conversion helper.\n\t *\n\t * **Note**: This method should be used mainly for editing the downcast and it is recommended\n\t * to use the {@link #markerToData `#markerToData()`} helper instead.\n\t *\n\t * This helper may produce invalid HTML code (e.g. a span between table cells).\n\t * It should only be used when you are sure that the produced HTML will be semantically correct.\n\t *\n\t * This conversion results in creating a view element on the boundaries of the converted marker. If the converted marker\n\t * is collapsed, only one element is created. For example, a model marker set like this: `<paragraph>F[oo b]ar</paragraph>`\n\t * becomes `<p>F<span data-marker=\"search\"></span>oo b<span data-marker=\"search\"></span>ar</p>` in the view.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: 'marker-search'\n\t * } );\n\t *\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: 'search-result',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tattributes: {\n\t * \t\t\t'data-marker': 'search'\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: ( markerData, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createUIElement( 'span', {\n\t * \t\t\t'data-marker': 'search',\n\t * \t\t\t'data-start': markerData.isOpening\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * If a function is passed as the `config.view` parameter, it will be used to generate both boundary elements. The function\n\t * receives the `data` object and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as a parameters and should return an instance of the\n\t * {@link module:engine/view/uielement~UIElement view UI element}. The `data` object and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi `conversionApi`} are passed from\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}. Additionally,\n\t * the `data.isOpening` parameter is passed, which is set to `true` for the marker start boundary element, and `false` for\n\t * the marker end boundary element.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The name of the model marker (or model marker group) to convert.\n\t * @param config.view A view element definition or a function that takes the model marker data and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as a parameters\n\t * and returns a view UI element.\n\t * @param config.converterPriority Converter priority.\n\t */ markerToElement(config) {\n        return this.add(downcastMarkerToElement(config));\n    }\n    /**\n\t * Model marker to highlight conversion helper.\n\t *\n\t * This conversion results in creating a highlight on view nodes. For this kind of conversion,\n\t * the {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} should be provided.\n\t *\n\t * For text nodes, a `<span>` {@link module:engine/view/attributeelement~AttributeElement} is created and it wraps all text nodes\n\t * in the converted marker range. For example, a model marker set like this: `<paragraph>F[oo b]ar</paragraph>` becomes\n\t * `<p>F<span class=\"comment\">oo b</span>ar</p>` in the view.\n\t *\n\t * {@link module:engine/view/containerelement~ContainerElement} may provide a custom way of handling highlight. Most often,\n\t * the element itself is given classes and attributes described in the highlight descriptor (instead of being wrapped in `<span>`).\n\t * For example, a model marker set like this:\n\t * `[<imageInline src=\"foo.jpg\"></imageInline>]` becomes `<img src=\"foo.jpg\" class=\"comment\"></img>` in the view.\n\t *\n\t * For container elements, the conversion is two-step. While the converter processes the highlight descriptor and passes it\n\t * to a container element, it is the container element instance itself that applies values from the highlight descriptor.\n\t * So, in a sense, the converter takes care of stating what should be applied on what, while the element decides how to apply that.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).markerToHighlight( { model: 'comment', view: { classes: 'comment' } } );\n\t *\n\t * editor.conversion.for( 'downcast' ).markerToHighlight( {\n\t * \tmodel: 'comment',\n\t * \tview: { classes: 'comment' },\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).markerToHighlight( {\n\t * \tmodel: 'comment',\n\t * \tview: ( data, conversionApi ) => {\n\t * \t\t// Assuming that the marker name is in a form of comment:commentType:commentId.\n\t * \t\tconst [ , commentType, commentId ] = data.markerName.split( ':' );\n\t *\n\t * \t\treturn {\n\t * \t\t\tclasses: [ 'comment', 'comment-' + commentType ],\n\t * \t\t\tattributes: { 'data-comment-id': commentId }\n\t * \t\t};\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * If a function is passed as the `config.view` parameter, it will be used to generate the highlight descriptor. The function\n\t * receives the `data` object and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as the parameters and should return a\n\t * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor highlight descriptor}.\n\t * The `data` object properties are passed from {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The name of the model marker (or model marker group) to convert.\n\t * @param config.view A highlight descriptor that will be used for highlighting or a function that takes the model marker data and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as a parameters\n\t * and returns a highlight descriptor.\n\t * @param config.converterPriority Converter priority.\n\t */ markerToHighlight(config) {\n        return this.add(downcastMarkerToHighlight(config));\n    }\n    /**\n\t * Model marker converter for data downcast.\n\t *\n\t * This conversion creates a representation for model marker boundaries in the view:\n\t *\n\t * * If the marker boundary is before or after a model element, a view attribute is set on a corresponding view element.\n\t * * In other cases, a view element with the specified tag name is inserted at the corresponding view position.\n\t *\n\t * Typically, the marker names use the `group:uniqueId:otherData` convention. For example: `comment:e34zfk9k2n459df53sjl34:zx32c`.\n\t * The default configuration for this conversion is that the first part is the `group` part and the rest of\n\t * the marker name becomes the `name` part.\n\t *\n\t * Tag and attribute names and values are generated from the marker name:\n\t *\n\t * * The templates for attributes are `data-[group]-start-before=\"[name]\"`, `data-[group]-start-after=\"[name]\"`,\n\t * `data-[group]-end-before=\"[name]\"` and `data-[group]-end-after=\"[name]\"`.\n\t * * The templates for view elements are `<[group]-start name=\"[name]\">` and `<[group]-end name=\"[name]\">`.\n\t *\n\t * Attributes mark whether the given marker's start or end boundary is before or after the given element.\n\t * The `data-[group]-start-before` and `data-[group]-end-after` attributes are favored.\n\t * The other two are used when the former two cannot be used.\n\t *\n\t * The conversion configuration can take a function that will generate different group and name parts.\n\t * If such a function is set as the `config.view` parameter, it is passed a marker name and it is expected to return an object with two\n\t * properties: `group` and `name`. If the function returns a falsy value, the conversion will not take place.\n\t *\n\t * Basic usage:\n\t *\n\t * ```ts\n\t * // Using the default conversion.\n\t * // In this case, all markers with names starting with 'comment:' will be converted.\n\t * // The `group` parameter will be set to `comment`.\n\t * // The `name` parameter will be the rest of the marker name (without the `:`).\n\t * editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t * \tmodel: 'comment'\n\t * } );\n\t * ```\n\t *\n\t * An example of a view that may be generated by this conversion (assuming a marker with the name `comment:commentId:uid` marked\n\t * by `[]`):\n\t *\n\t * ```\n\t * // Model:\n\t * <paragraph>Foo[bar</paragraph>\n\t * <imageBlock src=\"abc.jpg\"></imageBlock>]\n\t *\n\t * // View:\n\t * <p>Foo<comment-start name=\"commentId:uid\"></comment-start>bar</p>\n\t * <figure data-comment-end-after=\"commentId:uid\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t * ```\n\t *\n\t * In the example above, the comment starts before \"bar\" and ends after the image.\n\t *\n\t * If the `name` part is empty, the following view may be generated:\n\t *\n\t * ```html\n\t * <p>Foo <myMarker-start></myMarker-start>bar</p>\n\t * <figure data-myMarker-end-after=\"\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t * ```\n\t *\n\t * **Note:** A situation where some markers have the `name` part and some do not, is incorrect and should be avoided.\n\t *\n\t * Examples where `data-group-start-after` and `data-group-end-before` are used:\n\t *\n\t * ```\n\t * // Model:\n\t * <blockQuote>[]<paragraph>Foo</paragraph></blockQuote>\n\t *\n\t * // View:\n\t * <blockquote><p data-group-end-before=\"name\" data-group-start-before=\"name\">Foo</p></blockquote>\n\t * ```\n\t *\n\t * Similarly, when a marker is collapsed after the last element:\n\t *\n\t * ```\n\t * // Model:\n\t * <blockQuote><paragraph>Foo</paragraph>[]</blockQuote>\n\t *\n\t * // View:\n\t * <blockquote><p data-group-end-after=\"name\" data-group-start-after=\"name\">Foo</p></blockquote>\n\t * ```\n\t *\n\t * When there are multiple markers from the same group stored in the same attribute of the same element, their\n\t * name parts are put together in the attribute value, for example: `data-group-start-before=\"name1,name2,name3\"`.\n\t *\n\t * Other examples of usage:\n\t *\n\t * ```ts\n\t * // Using a custom function which is the same as the default conversion:\n\t * editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t * \tmodel: 'comment',\n\t * \tview: markerName => ( {\n\t * \t\tgroup: 'comment',\n\t * \t\tname: markerName.substr( 8 ) // Removes 'comment:' part.\n\t * \t} )\n\t * } );\n\t *\n\t * // Using the converter priority:\n\t * editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t * \tmodel: 'comment',\n\t * \tview: markerName => ( {\n\t * \t\tgroup: 'comment',\n\t * \t\tname: markerName.substr( 8 ) // Removes 'comment:' part.\n\t * \t} ),\n\t * \tconverterPriority: 'high'\n\t * } );\n\t * ```\n\t *\n\t * This kind of conversion is useful for saving data into the database, so it should be used in the data conversion pipeline.\n\t *\n\t * See the {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} API guide to learn how to\n\t * add a converter to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The name of the model marker (or the model marker group) to convert.\n\t * @param config.view A function that takes the model marker name and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as the parameters\n\t * and returns an object with the `group` and `name` properties.\n\t * @param config.converterPriority Converter priority.\n\t */ markerToData(config) {\n        return this.add(downcastMarkerToData(config));\n    }\n}\n/**\n * Function factory that creates a default downcast converter for text insertion changes.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n * ```ts\n * modelDispatcher.on( 'insert:$text', insertText() );\n * ```\n *\n * @returns Insert text event converter.\n */ function insertText() {\n    return (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const viewWriter = conversionApi.writer;\n        const viewPosition = conversionApi.mapper.toViewPosition(data.range.start);\n        const viewText = viewWriter.createText(data.item.data);\n        viewWriter.insert(viewPosition, viewText);\n    };\n}\n/**\n * Function factory that creates a default downcast converter for triggering attributes and children conversion.\n *\n * @returns The converter.\n */ function insertAttributesAndChildren() {\n    return (evt, data, conversionApi)=>{\n        conversionApi.convertAttributes(data.item);\n        // Start converting children of the current item.\n        // In case of reconversion children were already re-inserted or converted separately.\n        if (!data.reconversion && data.item.is('element') && !data.item.isEmpty) {\n            conversionApi.convertChildren(data.item);\n        }\n    };\n}\n/**\n * Function factory that creates a default downcast converter for node remove changes.\n *\n * ```ts\n * modelDispatcher.on( 'remove', remove() );\n * ```\n *\n * @returns Remove event converter.\n */ function remove() {\n    return (evt, data, conversionApi)=>{\n        // Find the view range start position by mapping the model position at which the remove happened.\n        const viewStart = conversionApi.mapper.toViewPosition(data.position);\n        const modelEnd = data.position.getShiftedBy(data.length);\n        const viewEnd = conversionApi.mapper.toViewPosition(modelEnd, {\n            isPhantom: true\n        });\n        const viewRange = conversionApi.writer.createRange(viewStart, viewEnd);\n        // Trim the range to remove in case some UI elements are on the view range boundaries.\n        const removed = conversionApi.writer.remove(viewRange.getTrimmed());\n        // After the range is removed, unbind all view elements from the model.\n        // Range inside view document fragment is used to unbind deeply.\n        for (const child of conversionApi.writer.createRangeIn(removed).getItems()){\n            conversionApi.mapper.unbindViewElement(child, {\n                defer: true\n            });\n        }\n    };\n}\n/**\n * Creates a `<span>` {@link module:engine/view/attributeelement~AttributeElement view attribute element} from the information\n * provided by the {@link module:engine/conversion/downcasthelpers~HighlightDescriptor highlight descriptor} object. If the priority\n * is not provided in the descriptor, the default priority will be used.\n */ function createViewElementFromHighlightDescriptor(writer, descriptor) {\n    const viewElement = writer.createAttributeElement('span', descriptor.attributes);\n    if (descriptor.classes) {\n        viewElement._addClass(descriptor.classes);\n    }\n    if (typeof descriptor.priority === 'number') {\n        viewElement._priority = descriptor.priority;\n    }\n    viewElement._id = descriptor.id;\n    return viewElement;\n}\n/**\n * Function factory that creates a converter which converts a non-collapsed {@link module:engine/model/selection~Selection model selection}\n * to a {@link module:engine/view/documentselection~DocumentSelection view selection}. The converter consumes appropriate\n * value from the `consumable` object and maps model positions from the selection to view positions.\n *\n * ```ts\n * modelDispatcher.on( 'selection', convertRangeSelection() );\n * ```\n *\n * @returns Selection converter.\n */ function convertRangeSelection() {\n    return (evt, data, conversionApi)=>{\n        const selection = data.selection;\n        if (selection.isCollapsed) {\n            return;\n        }\n        if (!conversionApi.consumable.consume(selection, 'selection')) {\n            return;\n        }\n        const viewRanges = [];\n        for (const range of selection.getRanges()){\n            viewRanges.push(conversionApi.mapper.toViewRange(range));\n        }\n        conversionApi.writer.setSelection(viewRanges, {\n            backward: selection.isBackward\n        });\n    };\n}\n/**\n * Function factory that creates a converter which converts a collapsed {@link module:engine/model/selection~Selection model selection} to\n * a {@link module:engine/view/documentselection~DocumentSelection view selection}. The converter consumes appropriate\n * value from the `consumable` object, maps the model selection position to the view position and breaks\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} at the selection position.\n *\n * ```ts\n * modelDispatcher.on( 'selection', convertCollapsedSelection() );\n * ```\n *\n * An example of the view state before and after converting the collapsed selection:\n *\n * ```\n *    <p><strong>f^oo<strong>bar</p>\n * -> <p><strong>f</strong>^<strong>oo</strong>bar</p>\n * ```\n *\n * By breaking attribute elements like `<strong>`, the selection is in a correct element. Then, when the selection attribute is\n * converted, broken attributes might be merged again, or the position where the selection is may be wrapped\n * with different, appropriate attribute elements.\n *\n * See also {@link module:engine/conversion/downcasthelpers~cleanSelection} which does a clean-up\n * by merging attributes.\n *\n * @returns Selection converter.\n */ function convertCollapsedSelection() {\n    return (evt, data, conversionApi)=>{\n        const selection = data.selection;\n        if (!selection.isCollapsed) {\n            return;\n        }\n        if (!conversionApi.consumable.consume(selection, 'selection')) {\n            return;\n        }\n        const viewWriter = conversionApi.writer;\n        const modelPosition = selection.getFirstPosition();\n        const viewPosition = conversionApi.mapper.toViewPosition(modelPosition);\n        const brokenPosition = viewWriter.breakAttributes(viewPosition);\n        viewWriter.setSelection(brokenPosition);\n    };\n}\n/**\n * Function factory that creates a converter which cleans artifacts after the previous\n * {@link module:engine/model/selection~Selection model selection} conversion. It removes all empty\n * {@link module:engine/view/attributeelement~AttributeElement view attribute elements} and merges sibling attributes at all start and end\n * positions of all ranges.\n *\n * ```\n *    <p><strong>^</strong></p>\n * -> <p>^</p>\n *\n *    <p><strong>foo</strong>^<strong>bar</strong>bar</p>\n * -> <p><strong>foo^bar<strong>bar</p>\n *\n *    <p><strong>foo</strong><em>^</em><strong>bar</strong>bar</p>\n * -> <p><strong>foo^bar<strong>bar</p>\n * ```\n *\n * This listener should be assigned before any converter for the new selection:\n *\n * ```ts\n * modelDispatcher.on( 'cleanSelection', cleanSelection() );\n * ```\n *\n * See {@link module:engine/conversion/downcasthelpers~convertCollapsedSelection}\n * which does the opposite by breaking attributes in the selection position.\n *\n * @returns Selection converter.\n */ function cleanSelection() {\n    return (evt, data, conversionApi)=>{\n        const viewWriter = conversionApi.writer;\n        const viewSelection = viewWriter.document.selection;\n        for (const range of viewSelection.getRanges()){\n            // Not collapsed selection should not have artifacts.\n            if (range.isCollapsed) {\n                // Position might be in the node removed by the view writer.\n                if (range.end.parent.isAttached()) {\n                    conversionApi.writer.mergeAttributes(range.start);\n                }\n            }\n        }\n        viewWriter.setSelection(null);\n    };\n}\n/**\n * Function factory that creates a converter which converts the set/change/remove attribute changes from the model to the view.\n * It can also be used to convert selection attributes. In that case, an empty attribute element will be created and the\n * selection will be put inside it.\n *\n * Attributes from the model are converted to a view element that will be wrapping these view nodes that are bound to\n * model elements having the given attribute. This is useful for attributes like `bold` that may be set on text nodes in the model\n * but are represented as an element in the view:\n *\n * ```\n * [paragraph]              MODEL ====> VIEW        <p>\n * \t|- a {bold: true}                             |- <b>\n * \t|- b {bold: true}                             |   |- ab\n * \t|- c                                          |- c\n * \t```\n *\n * Passed `Function` will be provided with the attribute value and then all the parameters of the\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute` event}.\n * It is expected that the function returns an {@link module:engine/view/element~Element}.\n * The result of the function will be the wrapping element.\n * When the provided `Function` does not return any element, no conversion will take place.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n * ```ts\n * modelDispatcher.on( 'attribute:bold', wrap( ( modelAttributeValue, { writer } ) => {\n * \treturn writer.createAttributeElement( 'strong' );\n * } );\n * ```\n *\n * @internal\n * @param elementCreator Function returning a view element that will be used for wrapping.\n * @returns Set/change attribute converter.\n */ function wrap(elementCreator) {\n    return (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.test(data.item, evt.name)) {\n            return;\n        }\n        // Recreate current wrapping node. It will be used to unwrap view range if the attribute value has changed\n        // or the attribute was removed.\n        const oldViewElement = elementCreator(data.attributeOldValue, conversionApi, data);\n        // Create node to wrap with.\n        const newViewElement = elementCreator(data.attributeNewValue, conversionApi, data);\n        if (!oldViewElement && !newViewElement) {\n            return;\n        }\n        conversionApi.consumable.consume(data.item, evt.name);\n        const viewWriter = conversionApi.writer;\n        const viewSelection = viewWriter.document.selection;\n        if (data.item instanceof Selection || data.item instanceof DocumentSelection) {\n            // Selection attribute conversion.\n            viewWriter.wrap(viewSelection.getFirstRange(), newViewElement);\n        } else {\n            // Node attribute conversion.\n            let viewRange = conversionApi.mapper.toViewRange(data.range);\n            // First, unwrap the range from current wrapper.\n            if (data.attributeOldValue !== null && oldViewElement) {\n                viewRange = viewWriter.unwrap(viewRange, oldViewElement);\n            }\n            if (data.attributeNewValue !== null && newViewElement) {\n                viewWriter.wrap(viewRange, newViewElement);\n            }\n        }\n    };\n}\n/**\n * Function factory that creates a converter which converts node insertion changes from the model to the view.\n * The function passed will be provided with all the parameters of the dispatcher's\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert` event}.\n * It is expected that the function returns an {@link module:engine/view/element~Element}.\n * The result of the function will be inserted into the view.\n *\n * The converter automatically consumes the corresponding value from the consumables list and binds the model and view elements.\n *\n * ```ts\n * downcastDispatcher.on(\n * \t'insert:myElem',\n * \tinsertElement( ( modelItem, { writer } ) => {\n * \t\tconst text = writer.createText( 'myText' );\n * \t\tconst myElem = writer.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );\n *\n * \t\t// Do something fancy with `myElem` using `modelItem` or other parameters.\n *\n * \t\treturn myElem;\n * \t}\n * ) );\n * ```\n *\n * @internal\n * @param  elementCreator Function returning a view element, which will be inserted.\n * @param consumer Function defining element consumption process.\n * By default this function just consume passed item insertion.\n * @returns Insert element event converter.\n */ function insertElement(elementCreator, consumer = defaultConsumer) {\n    return (evt, data, conversionApi)=>{\n        if (!consumer(data.item, conversionApi.consumable, {\n            preflight: true\n        })) {\n            return;\n        }\n        const viewElement = elementCreator(data.item, conversionApi, data);\n        if (!viewElement) {\n            return;\n        }\n        // Consume an element insertion and all present attributes that are specified as a reconversion triggers.\n        consumer(data.item, conversionApi.consumable);\n        const viewPosition = conversionApi.mapper.toViewPosition(data.range.start);\n        conversionApi.mapper.bindElements(data.item, viewElement);\n        conversionApi.writer.insert(viewPosition, viewElement);\n        // Convert attributes before converting children.\n        conversionApi.convertAttributes(data.item);\n        // Convert children or reinsert previous view elements.\n        reinsertOrConvertNodes(viewElement, data.item.getChildren(), conversionApi, {\n            reconversion: data.reconversion\n        });\n    };\n}\n/**\n * Function factory that creates a converter which converts a single model node insertion to a view structure.\n *\n * It is expected that the passed element creator function returns an {@link module:engine/view/element~Element} with attached slots\n * created with `writer.createSlot()` to indicate where child nodes should be converted.\n *\n * @see module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n *\n * @internal\n * @param elementCreator Function returning a view structure, which will be inserted.\n * @param consumer A callback that is expected to consume all the consumables\n * that were used by the element creator.\n * @returns Insert element event converter.\n*/ function insertStructure(elementCreator, consumer) {\n    return (evt, data, conversionApi)=>{\n        if (!consumer(data.item, conversionApi.consumable, {\n            preflight: true\n        })) {\n            return;\n        }\n        const slotsMap = new Map();\n        conversionApi.writer._registerSlotFactory(createSlotFactory(data.item, slotsMap, conversionApi));\n        // View creation.\n        const viewElement = elementCreator(data.item, conversionApi, data);\n        conversionApi.writer._clearSlotFactory();\n        if (!viewElement) {\n            return;\n        }\n        // Check if all children are covered by slots and there is no child that landed in multiple slots.\n        validateSlotsChildren(data.item, slotsMap, conversionApi);\n        // Consume an element insertion and all present attributes that are specified as a reconversion triggers.\n        consumer(data.item, conversionApi.consumable);\n        const viewPosition = conversionApi.mapper.toViewPosition(data.range.start);\n        conversionApi.mapper.bindElements(data.item, viewElement);\n        conversionApi.writer.insert(viewPosition, viewElement);\n        // Convert attributes before converting children.\n        conversionApi.convertAttributes(data.item);\n        // Fill view slots with previous view elements or create new ones.\n        fillSlots(viewElement, slotsMap, conversionApi, {\n            reconversion: data.reconversion\n        });\n    };\n}\n/**\n * Function factory that creates a converter which converts marker adding change to the\n * {@link module:engine/view/uielement~UIElement view UI element}.\n *\n * The view UI element that will be added to the view depends on the passed parameter. See {@link ~insertElement}.\n * In case of a non-collapsed range, the UI element will not wrap nodes but separate elements will be placed at the beginning\n * and at the end of the range.\n *\n * This converter binds created UI elements with the marker name using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.\n *\n * @internal\n * @param elementCreator A view UI element or a function returning the view element that will be inserted.\n * @returns Insert element event converter.\n */ function insertUIElement(elementCreator) {\n    return (evt, data, conversionApi)=>{\n        // Create two view elements. One will be inserted at the beginning of marker, one at the end.\n        // If marker is collapsed, only \"opening\" element will be inserted.\n        data.isOpening = true;\n        const viewStartElement = elementCreator(data, conversionApi);\n        data.isOpening = false;\n        const viewEndElement = elementCreator(data, conversionApi);\n        if (!viewStartElement || !viewEndElement) {\n            return;\n        }\n        const markerRange = data.markerRange;\n        // Marker that is collapsed has consumable build differently that non-collapsed one.\n        // For more information see `addMarker` event description.\n        // If marker's range is collapsed - check if it can be consumed.\n        if (markerRange.isCollapsed && !conversionApi.consumable.consume(markerRange, evt.name)) {\n            return;\n        }\n        // If marker's range is not collapsed - consume all items inside.\n        for (const value of markerRange){\n            if (!conversionApi.consumable.consume(value.item, evt.name)) {\n                return;\n            }\n        }\n        const mapper = conversionApi.mapper;\n        const viewWriter = conversionApi.writer;\n        // Add \"opening\" element.\n        viewWriter.insert(mapper.toViewPosition(markerRange.start), viewStartElement);\n        conversionApi.mapper.bindElementToMarker(viewStartElement, data.markerName);\n        // Add \"closing\" element only if range is not collapsed.\n        if (!markerRange.isCollapsed) {\n            viewWriter.insert(mapper.toViewPosition(markerRange.end), viewEndElement);\n            conversionApi.mapper.bindElementToMarker(viewEndElement, data.markerName);\n        }\n        evt.stop();\n    };\n}\n/**\n * Function factory that returns a default downcast converter for removing a {@link module:engine/view/uielement~UIElement UI element}\n * based on marker remove change.\n *\n * This converter unbinds elements from the marker name.\n *\n * @returns Removed UI element converter.\n */ function removeUIElement() {\n    return (evt, data, conversionApi)=>{\n        const elements = conversionApi.mapper.markerNameToElements(data.markerName);\n        if (!elements) {\n            return;\n        }\n        for (const element of elements){\n            conversionApi.mapper.unbindElementFromMarkerName(element, data.markerName);\n            conversionApi.writer.clear(conversionApi.writer.createRangeOn(element), element);\n        }\n        conversionApi.writer.clearClonedElementsGroup(data.markerName);\n        evt.stop();\n    };\n}\n/**\n * Function factory that creates a default converter for model markers.\n *\n * See {@link DowncastHelpers#markerToData} for more information what type of view is generated.\n *\n * This converter binds created UI elements and affected view elements with the marker name\n * using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.\n *\n * @returns Add marker converter.\n */ function insertMarkerData(viewCreator) {\n    return (evt, data, conversionApi)=>{\n        const viewMarkerData = viewCreator(data.markerName, conversionApi);\n        if (!viewMarkerData) {\n            return;\n        }\n        const markerRange = data.markerRange;\n        if (!conversionApi.consumable.consume(markerRange, evt.name)) {\n            return;\n        }\n        // Adding closing data first to keep the proper order in the view.\n        handleMarkerBoundary(markerRange, false, conversionApi, data, viewMarkerData);\n        handleMarkerBoundary(markerRange, true, conversionApi, data, viewMarkerData);\n        evt.stop();\n    };\n}\n/**\n * Helper function for `insertMarkerData()` that marks a marker boundary at the beginning or end of given `range`.\n */ function handleMarkerBoundary(range, isStart, conversionApi, data, viewMarkerData) {\n    const modelPosition = isStart ? range.start : range.end;\n    const elementAfter = modelPosition.nodeAfter && modelPosition.nodeAfter.is('element') ? modelPosition.nodeAfter : null;\n    const elementBefore = modelPosition.nodeBefore && modelPosition.nodeBefore.is('element') ? modelPosition.nodeBefore : null;\n    if (elementAfter || elementBefore) {\n        let modelElement;\n        let isBefore;\n        // If possible, we want to add `data-group-start-before` and `data-group-end-after` attributes.\n        if (isStart && elementAfter || !isStart && !elementBefore) {\n            // [<elementAfter>...</elementAfter> -> <elementAfter data-group-start-before=\"...\">...</elementAfter>\n            // <parent>]<elementAfter> -> <parent><elementAfter data-group-end-before=\"...\">\n            modelElement = elementAfter;\n            isBefore = true;\n        } else {\n            // <elementBefore>...</elementBefore>] -> <elementBefore data-group-end-after=\"...\">...</elementBefore>\n            // </elementBefore>[</parent> -> </elementBefore data-group-start-after=\"...\"></parent>\n            modelElement = elementBefore;\n            isBefore = false;\n        }\n        const viewElement = conversionApi.mapper.toViewElement(modelElement);\n        // In rare circumstances, the model element may be not mapped to any view element and that would cause an error.\n        // One of those situations is a soft break inside code block.\n        if (viewElement) {\n            insertMarkerAsAttribute(viewElement, isStart, isBefore, conversionApi, data, viewMarkerData);\n            return;\n        }\n    }\n    const viewPosition = conversionApi.mapper.toViewPosition(modelPosition);\n    insertMarkerAsElement(viewPosition, isStart, conversionApi, data, viewMarkerData);\n}\n/**\n * Helper function for `insertMarkerData()` that marks a marker boundary in the view as an attribute on a view element.\n */ function insertMarkerAsAttribute(viewElement, isStart, isBefore, conversionApi, data, viewMarkerData) {\n    const attributeName = `data-${viewMarkerData.group}-${isStart ? 'start' : 'end'}-${isBefore ? 'before' : 'after'}`;\n    const markerNames = viewElement.hasAttribute(attributeName) ? viewElement.getAttribute(attributeName).split(',') : [];\n    // Adding marker name at the beginning to have the same order in the attribute as there is with marker elements.\n    markerNames.unshift(viewMarkerData.name);\n    conversionApi.writer.setAttribute(attributeName, markerNames.join(','), viewElement);\n    conversionApi.mapper.bindElementToMarker(viewElement, data.markerName);\n}\n/**\n * Helper function for `insertMarkerData()` that marks a marker boundary in the view as a separate view ui element.\n */ function insertMarkerAsElement(position, isStart, conversionApi, data, viewMarkerData) {\n    const viewElementName = `${viewMarkerData.group}-${isStart ? 'start' : 'end'}`;\n    const attrs = viewMarkerData.name ? {\n        'name': viewMarkerData.name\n    } : null;\n    const viewElement = conversionApi.writer.createUIElement(viewElementName, attrs);\n    conversionApi.writer.insert(position, viewElement);\n    conversionApi.mapper.bindElementToMarker(viewElement, data.markerName);\n}\n/**\n * Function factory that creates a converter for removing a model marker data added by the {@link #insertMarkerData} converter.\n *\n * @returns Remove marker converter.\n */ function removeMarkerData(viewCreator) {\n    return (evt, data, conversionApi)=>{\n        const viewData = viewCreator(data.markerName, conversionApi);\n        if (!viewData) {\n            return;\n        }\n        const elements = conversionApi.mapper.markerNameToElements(data.markerName);\n        if (!elements) {\n            return;\n        }\n        for (const element of elements){\n            conversionApi.mapper.unbindElementFromMarkerName(element, data.markerName);\n            if (element.is('containerElement')) {\n                removeMarkerFromAttribute(`data-${viewData.group}-start-before`, element);\n                removeMarkerFromAttribute(`data-${viewData.group}-start-after`, element);\n                removeMarkerFromAttribute(`data-${viewData.group}-end-before`, element);\n                removeMarkerFromAttribute(`data-${viewData.group}-end-after`, element);\n            } else {\n                conversionApi.writer.clear(conversionApi.writer.createRangeOn(element), element);\n            }\n        }\n        conversionApi.writer.clearClonedElementsGroup(data.markerName);\n        evt.stop();\n        function removeMarkerFromAttribute(attributeName, element) {\n            if (element.hasAttribute(attributeName)) {\n                const markerNames = new Set(element.getAttribute(attributeName).split(','));\n                markerNames.delete(viewData.name);\n                if (markerNames.size == 0) {\n                    conversionApi.writer.removeAttribute(attributeName, element);\n                } else {\n                    conversionApi.writer.setAttribute(attributeName, Array.from(markerNames).join(','), element);\n                }\n            }\n        }\n    };\n}\n/**\n * Function factory that creates a converter which converts the set/change/remove attribute changes from the model to the view.\n *\n * Attributes from the model are converted to the view element attributes in the view. You may provide a custom function to generate\n * a key-value attribute pair to add/change/remove. If not provided, model attributes will be converted to view element\n * attributes on a one-to-one basis.\n *\n * *Note:** The provided attribute creator should always return the same `key` for a given attribute from the model.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n * ```ts\n * modelDispatcher.on( 'attribute:customAttr:myElem', changeAttribute( ( value, data ) => {\n * \t// Change attribute key from `customAttr` to `class` in the view.\n * \tconst key = 'class';\n * \tlet value = data.attributeNewValue;\n *\n * \t// Force attribute value to 'empty' if the model element is empty.\n * \tif ( data.item.childCount === 0 ) {\n * \t\tvalue = 'empty';\n * \t}\n *\n * \t// Return the key-value pair.\n * \treturn { key, value };\n * } ) );\n * ```\n *\n * @param attributeCreator Function returning an object with two properties: `key` and `value`, which\n * represent the attribute key and attribute value to be set on a {@link module:engine/view/element~Element view element}.\n * The function is passed the model attribute value as the first parameter and additional data about the change as the second parameter.\n * @returns Set/change attribute converter.\n */ function changeAttribute(attributeCreator) {\n    return (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.test(data.item, evt.name)) {\n            return;\n        }\n        const oldAttribute = attributeCreator(data.attributeOldValue, conversionApi, data);\n        const newAttribute = attributeCreator(data.attributeNewValue, conversionApi, data);\n        if (!oldAttribute && !newAttribute) {\n            return;\n        }\n        conversionApi.consumable.consume(data.item, evt.name);\n        const viewElement = conversionApi.mapper.toViewElement(data.item);\n        const viewWriter = conversionApi.writer;\n        // If model item cannot be mapped to a view element, it means item is not an `Element` instance but a `TextProxy` node.\n        // Only elements can have attributes in a view so do not proceed for anything else (#1587).\n        if (!viewElement) {\n            /**\n\t\t\t * This error occurs when a {@link module:engine/model/textproxy~TextProxy text node's} attribute is to be downcasted\n\t\t\t * by an {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `Attribute to Attribute converter`}.\n\t\t\t * In most cases it is caused by converters misconfiguration when only \"generic\" converter is defined:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t\t\t * \tmodel: 'attribute-name',\n\t\t\t * \tview: 'attribute-name'\n\t\t\t * } ) );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * and given attribute is used on text node, for example:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * model.change( writer => {\n\t\t\t * \twriter.insertText( 'Foo', { 'attribute-name': 'bar' }, parent, 0 );\n\t\t\t * } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * In such cases, to convert the same attribute for both {@link module:engine/model/element~Element}\n\t\t\t * and {@link module:engine/model/textproxy~TextProxy `Text`} nodes, text specific\n\t\t\t * {@link module:engine/conversion/conversion~Conversion#attributeToElement `Attribute to Element converter`}\n\t\t\t * with higher {@link module:utils/priorities~PriorityString priority} must also be defined:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t\t\t * \tmodel: {\n\t\t\t * \t\tkey: 'attribute-name',\n\t\t\t * \t\tname: '$text'\n\t\t\t * \t},\n\t\t\t * \tview: ( value, { writer } ) => {\n\t\t\t * \t\treturn writer.createAttributeElement( 'span', { 'attribute-name': value } );\n\t\t\t * \t},\n\t\t\t * \tconverterPriority: 'high'\n\t\t\t * } ) );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * @error conversion-attribute-to-attribute-on-text\n\t\t\t */ throw new CKEditorError('conversion-attribute-to-attribute-on-text', conversionApi.dispatcher, data);\n        }\n        // First remove the old attribute if there was one.\n        if (data.attributeOldValue !== null && oldAttribute) {\n            if (oldAttribute.key == 'class') {\n                const classes = typeof oldAttribute.value == 'string' ? oldAttribute.value.split(/\\s+/) : oldAttribute.value;\n                for (const className of classes){\n                    viewWriter.removeClass(className, viewElement);\n                }\n            } else if (oldAttribute.key == 'style') {\n                if (typeof oldAttribute.value == 'string') {\n                    const styles = new StylesMap(viewWriter.document.stylesProcessor);\n                    styles.setTo(oldAttribute.value);\n                    for (const [key] of styles.getStylesEntries()){\n                        viewWriter.removeStyle(key, viewElement);\n                    }\n                } else {\n                    const keys = Object.keys(oldAttribute.value);\n                    for (const key of keys){\n                        viewWriter.removeStyle(key, viewElement);\n                    }\n                }\n            } else {\n                viewWriter.removeAttribute(oldAttribute.key, viewElement);\n            }\n        }\n        // Then set the new attribute.\n        if (data.attributeNewValue !== null && newAttribute) {\n            if (newAttribute.key == 'class') {\n                const classes = typeof newAttribute.value == 'string' ? newAttribute.value.split(/\\s+/) : newAttribute.value;\n                for (const className of classes){\n                    viewWriter.addClass(className, viewElement);\n                }\n            } else if (newAttribute.key == 'style') {\n                if (typeof newAttribute.value == 'string') {\n                    const styles = new StylesMap(viewWriter.document.stylesProcessor);\n                    styles.setTo(newAttribute.value);\n                    for (const [key, value] of styles.getStylesEntries()){\n                        viewWriter.setStyle(key, value, viewElement);\n                    }\n                } else {\n                    const keys = Object.keys(newAttribute.value);\n                    for (const key of keys){\n                        viewWriter.setStyle(key, newAttribute.value[key], viewElement);\n                    }\n                }\n            } else {\n                viewWriter.setAttribute(newAttribute.key, newAttribute.value, viewElement);\n            }\n        }\n    };\n}\n/**\n * Function factory that creates a converter which converts the text inside marker's range. The converter wraps the text with\n * {@link module:engine/view/attributeelement~AttributeElement} created from the provided descriptor.\n * See {link module:engine/conversion/downcasthelpers~createViewElementFromHighlightDescriptor}.\n *\n * It can also be used to convert the selection that is inside a marker. In that case, an empty attribute element will be\n * created and the selection will be put inside it.\n *\n * If the highlight descriptor does not provide the `priority` property, `10` will be used.\n *\n * If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n *\n * This converter binds the created {@link module:engine/view/attributeelement~AttributeElement attribute elemens} with the marker name\n * using the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n */ function highlightText(highlightDescriptor) {\n    return (evt, data, conversionApi)=>{\n        if (!data.item) {\n            return;\n        }\n        if (!(data.item instanceof Selection || data.item instanceof DocumentSelection) && !data.item.is('$textProxy')) {\n            return;\n        }\n        const descriptor = prepareDescriptor(highlightDescriptor, data, conversionApi);\n        if (!descriptor) {\n            return;\n        }\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const viewWriter = conversionApi.writer;\n        const viewElement = createViewElementFromHighlightDescriptor(viewWriter, descriptor);\n        const viewSelection = viewWriter.document.selection;\n        if (data.item instanceof Selection || data.item instanceof DocumentSelection) {\n            viewWriter.wrap(viewSelection.getFirstRange(), viewElement);\n        } else {\n            const viewRange = conversionApi.mapper.toViewRange(data.range);\n            const rangeAfterWrap = viewWriter.wrap(viewRange, viewElement);\n            for (const element of rangeAfterWrap.getItems()){\n                if (element.is('attributeElement') && element.isSimilar(viewElement)) {\n                    conversionApi.mapper.bindElementToMarker(element, data.markerName);\n                    break;\n                }\n            }\n        }\n    };\n}\n/**\n * Converter function factory. It creates a function which applies the marker's highlight to an element inside the marker's range.\n *\n * The converter checks if an element has the `addHighlight` function stored as a\n * {@link module:engine/view/element~Element#_setCustomProperty custom property} and, if so, uses it to apply the highlight.\n * In such case the converter will consume all element's children, assuming that they were handled by the element itself.\n *\n * When the `addHighlight` custom property is not present, the element is not converted in any special way.\n * This means that converters will proceed to convert the element's child nodes.\n *\n * If the highlight descriptor does not provide the `priority` property, `10` will be used.\n *\n * If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n *\n * This converter binds altered {@link module:engine/view/containerelement~ContainerElement container elements} with the marker name using\n * the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n */ function highlightElement(highlightDescriptor) {\n    return (evt, data, conversionApi)=>{\n        if (!data.item) {\n            return;\n        }\n        if (!(data.item instanceof Element)) {\n            return;\n        }\n        const descriptor = prepareDescriptor(highlightDescriptor, data, conversionApi);\n        if (!descriptor) {\n            return;\n        }\n        if (!conversionApi.consumable.test(data.item, evt.name)) {\n            return;\n        }\n        const viewElement = conversionApi.mapper.toViewElement(data.item);\n        if (viewElement && viewElement.getCustomProperty('addHighlight')) {\n            // Consume element itself.\n            conversionApi.consumable.consume(data.item, evt.name);\n            // Consume all children nodes.\n            for (const value of Range._createIn(data.item)){\n                conversionApi.consumable.consume(value.item, evt.name);\n            }\n            const addHighlightCallback = viewElement.getCustomProperty('addHighlight');\n            addHighlightCallback(viewElement, descriptor, conversionApi.writer);\n            conversionApi.mapper.bindElementToMarker(viewElement, data.markerName);\n        }\n    };\n}\n/**\n * Function factory that creates a converter which converts the removing model marker to the view.\n *\n * Both text nodes and elements are handled by this converter but they are handled a bit differently.\n *\n * Text nodes are unwrapped using the {@link module:engine/view/attributeelement~AttributeElement attribute element} created from the\n * provided highlight descriptor. See {link module:engine/conversion/downcasthelpers~HighlightDescriptor}.\n *\n * For elements, the converter checks if an element has the `removeHighlight` function stored as a\n * {@link module:engine/view/element~Element#_setCustomProperty custom property}. If so, it uses it to remove the highlight.\n * In such case, the children of that element will not be converted.\n *\n * When `removeHighlight` is not present, the element is not converted in any special way.\n * The converter will proceed to convert the element's child nodes instead.\n *\n * If the highlight descriptor does not provide the `priority` property, `10` will be used.\n *\n * If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n *\n * This converter unbinds elements from the marker name.\n */ function removeHighlight(highlightDescriptor) {\n    return (evt, data, conversionApi)=>{\n        // This conversion makes sense only for non-collapsed range.\n        if (data.markerRange.isCollapsed) {\n            return;\n        }\n        const descriptor = prepareDescriptor(highlightDescriptor, data, conversionApi);\n        if (!descriptor) {\n            return;\n        }\n        // View element that will be used to unwrap `AttributeElement`s.\n        const viewHighlightElement = createViewElementFromHighlightDescriptor(conversionApi.writer, descriptor);\n        // Get all elements bound with given marker name.\n        const elements = conversionApi.mapper.markerNameToElements(data.markerName);\n        if (!elements) {\n            return;\n        }\n        for (const element of elements){\n            conversionApi.mapper.unbindElementFromMarkerName(element, data.markerName);\n            if (element.is('attributeElement')) {\n                conversionApi.writer.unwrap(conversionApi.writer.createRangeOn(element), viewHighlightElement);\n            } else {\n                // if element.is( 'containerElement' ).\n                const removeHighlightCallback = element.getCustomProperty('removeHighlight');\n                removeHighlightCallback(element, descriptor.id, conversionApi.writer);\n            }\n        }\n        conversionApi.writer.clearClonedElementsGroup(data.markerName);\n        evt.stop();\n    };\n}\n/**\n * Model element to view element conversion helper.\n *\n * See {@link ~DowncastHelpers#elementToElement `.elementToElement()` downcast helper} for examples and config params description.\n *\n * @param config Conversion configuration.\n * @param config.model The description or a name of the model element to convert.\n * @param config.model.attributes List of attributes triggering element reconversion.\n * @param config.model.children Should reconvert element if the list of model child nodes changed.\n * @returns Conversion helper.\n */ function downcastElementToElement(config) {\n    const model = normalizeModelElementConfig(config.model);\n    const view = normalizeToElementConfig(config.view, 'container');\n    // Trigger reconversion on children list change if element is a subject to any reconversion.\n    // This is required to be able to trigger Differ#refreshItem() on a direct child of the reconverted element.\n    if (model.attributes.length) {\n        model.children = true;\n    }\n    return (dispatcher)=>{\n        dispatcher.on(`insert:${model.name}`, insertElement(view, createConsumer(model)), {\n            priority: config.converterPriority || 'normal'\n        });\n        if (model.children || model.attributes.length) {\n            dispatcher.on('reduceChanges', createChangeReducer(model), {\n                priority: 'low'\n            });\n        }\n    };\n}\n/**\n * Model element to view structure conversion helper.\n *\n * See {@link ~DowncastHelpers#elementToStructure `.elementToStructure()` downcast helper} for examples and config params description.\n *\n * @param config Conversion configuration.\n * @returns Conversion helper.\n */ function downcastElementToStructure(config) {\n    const model = normalizeModelElementConfig(config.model);\n    const view = normalizeToElementConfig(config.view, 'container');\n    // Trigger reconversion on children list change because it always needs to use slots to put children in proper places.\n    // This is required to be able to trigger Differ#refreshItem() on a direct child of the reconverted element.\n    model.children = true;\n    return (dispatcher)=>{\n        if (dispatcher._conversionApi.schema.checkChild(model.name, '$text')) {\n            /**\n\t\t\t * This error occurs when a {@link module:engine/model/element~Element model element} is downcasted\n\t\t\t * via {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure} helper but the element was\n\t\t\t * allowed to host `$text` by the {@link module:engine/model/schema~Schema model schema}.\n\t\t\t *\n\t\t\t * For instance, this may be the result of `myElement` allowing the content of\n\t\t\t * {@glink framework/deep-dive/schema#generic-items `$block`} in its schema definition:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * // Element definition in schema.\n\t\t\t * schema.register( 'myElement', {\n\t\t\t * \tallowContentOf: '$block',\n\t\t\t *\n\t\t\t * \t// ...\n\t\t\t * } );\n\t\t\t *\n\t\t\t * // ...\n\t\t\t *\n\t\t\t * // Conversion of myElement with the use of elementToStructure().\n\t\t\t * editor.conversion.for( 'downcast' ).elementToStructure( {\n\t\t\t * \tmodel: 'myElement',\n\t\t\t * \tview: ( modelElement, { writer } ) => {\n\t\t\t * \t\t// ...\n\t\t\t * \t}\n\t\t\t * } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * In such case, {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`} helper\n\t\t\t * can be used instead to get around this problem:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t\t\t * \tmodel: 'myElement',\n\t\t\t * \tview: ( modelElement, { writer } ) => {\n\t\t\t * \t\t// ...\n\t\t\t * \t}\n\t\t\t * } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * @error conversion-element-to-structure-disallowed-text\n\t\t\t * @param {String} elementName The name of the element the structure is to be created for.\n\t\t\t */ throw new CKEditorError('conversion-element-to-structure-disallowed-text', dispatcher, {\n                elementName: model.name\n            });\n        }\n        dispatcher.on(`insert:${model.name}`, insertStructure(view, createConsumer(model)), {\n            priority: config.converterPriority || 'normal'\n        });\n        dispatcher.on('reduceChanges', createChangeReducer(model), {\n            priority: 'low'\n        });\n    };\n}\n/**\n * Model attribute to view element conversion helper.\n *\n * See {@link ~DowncastHelpers#attributeToElement `.attributeToElement()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n * of `String`s with possible values if the model attribute is an enumerable.\n * @param config.view A view element definition or a function that takes the model attribute value and\n * {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} as parameters and returns a view attribute element.\n * If `config.model.values` is given, `config.view` should be an object assigning values from `config.model.values` to view element\n * definitions or functions.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */ function downcastAttributeToElement(config) {\n    config = cloneDeep(config);\n    let model = config.model;\n    if (typeof model == 'string') {\n        model = {\n            key: model\n        };\n    }\n    let eventName = `attribute:${model.key}`;\n    if (model.name) {\n        eventName += ':' + model.name;\n    }\n    if (model.values) {\n        for (const modelValue of model.values){\n            config.view[modelValue] = normalizeToElementConfig(config.view[modelValue], 'attribute');\n        }\n    } else {\n        config.view = normalizeToElementConfig(config.view, 'attribute');\n    }\n    const elementCreator = getFromAttributeCreator(config);\n    return (dispatcher)=>{\n        dispatcher.on(eventName, wrap(elementCreator), {\n            priority: config.converterPriority || 'normal'\n        });\n    };\n}\n/**\n * Model attribute to view attribute conversion helper.\n *\n * See {@link ~DowncastHelpers#attributeToAttribute `.attributeToAttribute()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n * the attribute key, possible values and, optionally, an element name to convert from.\n * @param config.view A view attribute key, or a `{ key, value }` object or a function that takes the model attribute value and returns\n * a `{ key, value }` object.\n * If `key` is `'class'`, `value` can be a `String` or an array of `String`s. If `key` is `'style'`, `value` is an object with\n * key-value pairs. In other cases, `value` is a `String`.\n * If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n * `{ key, value }` objects or a functions.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */ function downcastAttributeToAttribute(config) {\n    config = cloneDeep(config);\n    let model = config.model;\n    if (typeof model == 'string') {\n        model = {\n            key: model\n        };\n    }\n    let eventName = `attribute:${model.key}`;\n    if (model.name) {\n        eventName += ':' + model.name;\n    }\n    if (model.values) {\n        for (const modelValue of model.values){\n            config.view[modelValue] = normalizeToAttributeConfig(config.view[modelValue]);\n        }\n    } else {\n        config.view = normalizeToAttributeConfig(config.view);\n    }\n    const elementCreator = getFromAttributeCreator(config);\n    return (dispatcher)=>{\n        dispatcher.on(eventName, changeAttribute(elementCreator), {\n            priority: config.converterPriority || 'normal'\n        });\n    };\n}\n/**\n * Model marker to view element conversion helper.\n *\n * See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The name of the model marker (or model marker group) to convert.\n * @param config.view A view element definition or a function that takes the model marker data as a parameter and returns a view UI element.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */ function downcastMarkerToElement(config) {\n    const view = normalizeToElementConfig(config.view, 'ui');\n    return (dispatcher)=>{\n        dispatcher.on(`addMarker:${config.model}`, insertUIElement(view), {\n            priority: config.converterPriority || 'normal'\n        });\n        dispatcher.on(`removeMarker:${config.model}`, removeUIElement(), {\n            priority: config.converterPriority || 'normal'\n        });\n    };\n}\n/**\n * Model marker to view data conversion helper.\n *\n * See {@link ~DowncastHelpers#markerToData `markerToData()` downcast helper} to learn more.\n *\n * @returns Conversion helper.\n */ function downcastMarkerToData(config) {\n    config = cloneDeep(config);\n    const group = config.model;\n    let view = config.view;\n    // Default conversion.\n    if (!view) {\n        view = (markerName)=>({\n                group,\n                name: markerName.substr(config.model.length + 1)\n            });\n    }\n    return (dispatcher)=>{\n        dispatcher.on(`addMarker:${group}`, insertMarkerData(view), {\n            priority: config.converterPriority || 'normal'\n        });\n        dispatcher.on(`removeMarker:${group}`, removeMarkerData(view), {\n            priority: config.converterPriority || 'normal'\n        });\n    };\n}\n/**\n * Model marker to highlight conversion helper.\n *\n * See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The name of the model marker (or model marker group) to convert.\n * @param config.view A highlight descriptor that will be used for highlighting or a function that takes\n * the model marker data as a parameter and returns a highlight descriptor.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */ function downcastMarkerToHighlight(config) {\n    return (dispatcher)=>{\n        dispatcher.on(`addMarker:${config.model}`, highlightText(config.view), {\n            priority: config.converterPriority || 'normal'\n        });\n        dispatcher.on(`addMarker:${config.model}`, highlightElement(config.view), {\n            priority: config.converterPriority || 'normal'\n        });\n        dispatcher.on(`removeMarker:${config.model}`, removeHighlight(config.view), {\n            priority: config.converterPriority || 'normal'\n        });\n    };\n}\n/**\n * Takes `config.model`, and converts it to an object with normalized structure.\n *\n * @param model Model configuration or element name.\n */ function normalizeModelElementConfig(model) {\n    if (typeof model == 'string') {\n        model = {\n            name: model\n        };\n    }\n    return {\n        name: model.name,\n        attributes: model.attributes ? toArray(model.attributes) : [],\n        children: !!model.children\n    };\n}\n/**\n * Takes `config.view`, and if it is an {@link module:engine/view/elementdefinition~ElementDefinition}, converts it\n * to a function (because lower level converters accept only element creator functions).\n *\n * @param view View configuration.\n * @param viewElementType View element type to create.\n * @returns Element creator function to use in lower level converters.\n */ function normalizeToElementConfig(view, viewElementType) {\n    if (typeof view == 'function') {\n        // If `view` is already a function, don't do anything.\n        return view;\n    }\n    return (modelData, conversionApi)=>createViewElementFromDefinition(view, conversionApi, viewElementType);\n}\n/**\n * Creates a view element instance from the provided {@link module:engine/view/elementdefinition~ElementDefinition} and class.\n */ function createViewElementFromDefinition(viewElementDefinition, conversionApi, viewElementType) {\n    if (typeof viewElementDefinition == 'string') {\n        // If `viewElementDefinition` is given as a `String`, normalize it to an object with `name` property.\n        viewElementDefinition = {\n            name: viewElementDefinition\n        };\n    }\n    let element;\n    const viewWriter = conversionApi.writer;\n    const attributes = Object.assign({}, viewElementDefinition.attributes);\n    if (viewElementType == 'container') {\n        element = viewWriter.createContainerElement(viewElementDefinition.name, attributes);\n    } else if (viewElementType == 'attribute') {\n        const options = {\n            priority: viewElementDefinition.priority || AttributeElement.DEFAULT_PRIORITY\n        };\n        element = viewWriter.createAttributeElement(viewElementDefinition.name, attributes, options);\n    } else {\n        // 'ui'.\n        element = viewWriter.createUIElement(viewElementDefinition.name, attributes);\n    }\n    if (viewElementDefinition.styles) {\n        const keys = Object.keys(viewElementDefinition.styles);\n        for (const key of keys){\n            viewWriter.setStyle(key, viewElementDefinition.styles[key], element);\n        }\n    }\n    if (viewElementDefinition.classes) {\n        const classes = viewElementDefinition.classes;\n        if (typeof classes == 'string') {\n            viewWriter.addClass(classes, element);\n        } else {\n            for (const className of classes){\n                viewWriter.addClass(className, element);\n            }\n        }\n    }\n    return element;\n}\nfunction getFromAttributeCreator(config) {\n    if (config.model.values) {\n        return (modelAttributeValue, conversionApi, data)=>{\n            const view = config.view[modelAttributeValue];\n            if (view) {\n                return view(modelAttributeValue, conversionApi, data);\n            }\n            return null;\n        };\n    } else {\n        return config.view;\n    }\n}\n/**\n * Takes the configuration, adds default parameters if they do not exist and normalizes other parameters to be used in downcast converters\n * for generating a view attribute.\n *\n * @param view View configuration.\n */ function normalizeToAttributeConfig(view) {\n    if (typeof view == 'string') {\n        return (modelAttributeValue)=>({\n                key: view,\n                value: modelAttributeValue\n            });\n    } else if (typeof view == 'object') {\n        // { key, value, ... }\n        if (view.value) {\n            return ()=>view;\n        } else {\n            return (modelAttributeValue)=>({\n                    key: view.key,\n                    value: modelAttributeValue\n                });\n        }\n    } else {\n        // function.\n        return view;\n    }\n}\n/**\n * Helper function for `highlight`. Prepares the actual descriptor object using value passed to the converter.\n */ function prepareDescriptor(highlightDescriptor, data, conversionApi) {\n    // If passed descriptor is a creator function, call it. If not, just use passed value.\n    const descriptor = typeof highlightDescriptor == 'function' ? highlightDescriptor(data, conversionApi) : highlightDescriptor;\n    if (!descriptor) {\n        return null;\n    }\n    // Apply default descriptor priority.\n    if (!descriptor.priority) {\n        descriptor.priority = 10;\n    }\n    // Default descriptor id is marker name.\n    if (!descriptor.id) {\n        descriptor.id = data.markerName;\n    }\n    return descriptor;\n}\n/**\n * Creates a function that checks a single differ diff item whether it should trigger reconversion.\n *\n * @param model A normalized `config.model` converter configuration.\n * @param model.name The name of element.\n * @param model.attributes The list of attribute names that should trigger reconversion.\n * @param model.children Whether the child list change should trigger reconversion.\n */ function createChangeReducerCallback(model) {\n    return (node, change)=>{\n        if (!node.is('element', model.name)) {\n            return false;\n        }\n        if (change.type == 'attribute') {\n            if (model.attributes.includes(change.attributeKey)) {\n                return true;\n            }\n        } else {\n            /* istanbul ignore else: This is always true because otherwise it would not register a reducer callback. -- @preserve */ if (model.children) {\n                return true;\n            }\n        }\n        return false;\n    };\n}\n/**\n * Creates a `reduceChanges` event handler for reconversion.\n *\n * @param model A normalized `config.model` converter configuration.\n * @param model.name The name of element.\n * @param model.attributes The list of attribute names that should trigger reconversion.\n * @param model.children Whether the child list change should trigger reconversion.\n */ function createChangeReducer(model) {\n    const shouldReplace = createChangeReducerCallback(model);\n    return (evt, data)=>{\n        const reducedChanges = [];\n        if (!data.reconvertedElements) {\n            data.reconvertedElements = new Set();\n        }\n        for (const change of data.changes){\n            // For attribute use node affected by the change.\n            // For insert or remove use parent element because we need to check if it's added/removed child.\n            const node = change.type == 'attribute' ? change.range.start.nodeAfter : change.position.parent;\n            if (!node || !shouldReplace(node, change)) {\n                reducedChanges.push(change);\n                continue;\n            }\n            // If it's already marked for reconversion, so skip this change, otherwise add the diff items.\n            if (!data.reconvertedElements.has(node)) {\n                data.reconvertedElements.add(node);\n                const position = Position._createBefore(node);\n                let changeIndex = reducedChanges.length;\n                // We need to insert remove+reinsert before any other change on and inside the re-converted element.\n                // This is important because otherwise we would remove element that had already been modified by the previous change.\n                // Note that there could be some element removed before the re-converted element, so we must not break this behavior.\n                for(let i = reducedChanges.length - 1; i >= 0; i--){\n                    const change = reducedChanges[i];\n                    const changePosition = change.type == 'attribute' ? change.range.start : change.position;\n                    const positionRelation = changePosition.compareWith(position);\n                    if (positionRelation == 'before' || change.type == 'remove' && positionRelation == 'same') {\n                        break;\n                    }\n                    changeIndex = i;\n                }\n                reducedChanges.splice(changeIndex, 0, {\n                    type: 'remove',\n                    name: node.name,\n                    position,\n                    length: 1\n                }, {\n                    type: 'reinsert',\n                    name: node.name,\n                    position,\n                    length: 1\n                });\n            }\n        }\n        data.changes = reducedChanges;\n    };\n}\n/**\n * Creates a function that checks if an element and its watched attributes can be consumed and consumes them.\n *\n * @param model A normalized `config.model` converter configuration.\n * @param model.name The name of element.\n * @param model.attributes The list of attribute names that should trigger reconversion.\n * @param model.children Whether the child list change should trigger reconversion.\n */ function createConsumer(model) {\n    return (node, consumable, options = {})=>{\n        const events = [\n            'insert'\n        ];\n        // Collect all set attributes that are triggering conversion.\n        for (const attributeName of model.attributes){\n            if (node.hasAttribute(attributeName)) {\n                events.push(`attribute:${attributeName}`);\n            }\n        }\n        if (!events.every((event)=>consumable.test(node, event))) {\n            return false;\n        }\n        if (!options.preflight) {\n            events.forEach((event)=>consumable.consume(node, event));\n        }\n        return true;\n    };\n}\n/**\n * Creates a function that create view slots.\n *\n * @returns Function exposed by writer as createSlot().\n */ function createSlotFactory(element, slotsMap, conversionApi) {\n    return (writer, modeOrFilter)=>{\n        const slot = writer.createContainerElement('$slot');\n        let children = null;\n        if (modeOrFilter === 'children') {\n            children = Array.from(element.getChildren());\n        } else if (typeof modeOrFilter == 'function') {\n            children = Array.from(element.getChildren()).filter((element)=>modeOrFilter(element));\n        } else {\n            /**\n\t\t\t * Unknown slot mode was provided to `writer.createSlot()` in downcast converter.\n\t\t\t *\n\t\t\t * @error conversion-slot-mode-unknown\n\t\t\t */ throw new CKEditorError('conversion-slot-mode-unknown', conversionApi.dispatcher, {\n                modeOrFilter\n            });\n        }\n        slotsMap.set(slot, children);\n        return slot;\n    };\n}\n/**\n * Checks if all children are covered by slots and there is no child that landed in multiple slots.\n */ function validateSlotsChildren(element, slotsMap, conversionApi) {\n    const childrenInSlots = Array.from(slotsMap.values()).flat();\n    const uniqueChildrenInSlots = new Set(childrenInSlots);\n    if (uniqueChildrenInSlots.size != childrenInSlots.length) {\n        /**\n\t\t * Filters provided to `writer.createSlot()` overlap (at least two filters accept the same child element).\n\t\t *\n\t\t * @error conversion-slot-filter-overlap\n\t\t * @param {module:engine/model/element~Element} element The element of which children would not be properly\n\t\t * allocated to multiple slots.\n\t\t */ throw new CKEditorError('conversion-slot-filter-overlap', conversionApi.dispatcher, {\n            element\n        });\n    }\n    if (uniqueChildrenInSlots.size != element.childCount) {\n        /**\n\t\t * Filters provided to `writer.createSlot()` are incomplete and exclude at least one children element (one of\n\t\t * the children elements would not be assigned to any of the slots).\n\t\t *\n\t\t * @error conversion-slot-filter-incomplete\n\t\t * @param {module:engine/model/element~Element} element The element of which children would not be properly\n\t\t * allocated to multiple slots.\n\t\t */ throw new CKEditorError('conversion-slot-filter-incomplete', conversionApi.dispatcher, {\n            element\n        });\n    }\n}\n/**\n * Fill slots with appropriate view elements.\n */ function fillSlots(viewElement, slotsMap, conversionApi, options) {\n    // Set temporary position mapping to redirect child view elements into a proper slots.\n    conversionApi.mapper.on('modelToViewPosition', toViewPositionMapping, {\n        priority: 'highest'\n    });\n    let currentSlot = null;\n    let currentSlotNodes = null;\n    // Fill slots with nested view nodes.\n    for ([currentSlot, currentSlotNodes] of slotsMap){\n        reinsertOrConvertNodes(viewElement, currentSlotNodes, conversionApi, options);\n        conversionApi.writer.move(conversionApi.writer.createRangeIn(currentSlot), conversionApi.writer.createPositionBefore(currentSlot));\n        conversionApi.writer.remove(currentSlot);\n    }\n    conversionApi.mapper.off('modelToViewPosition', toViewPositionMapping);\n    function toViewPositionMapping(evt, data) {\n        const element = data.modelPosition.nodeAfter;\n        // Find the proper offset within the slot.\n        const index = currentSlotNodes.indexOf(element);\n        if (index < 0) {\n            return;\n        }\n        data.viewPosition = data.mapper.findPositionIn(currentSlot, index);\n    }\n}\n/**\n * Inserts view representation of `nodes` into the `viewElement` either by bringing back just removed view nodes\n * or by triggering conversion for them.\n */ function reinsertOrConvertNodes(viewElement, modelNodes, conversionApi, options) {\n    // Fill with nested view nodes.\n    for (const modelChildNode of modelNodes){\n        // Try reinserting the view node for the specified model node...\n        if (!reinsertNode(viewElement.root, modelChildNode, conversionApi, options)) {\n            // ...or else convert the model element to the view.\n            conversionApi.convertItem(modelChildNode);\n        }\n    }\n}\n/**\n * Checks if the view for the given model element could be reused and reinserts it to the view.\n *\n * @returns `false` if view element can't be reused.\n */ function reinsertNode(viewRoot, modelNode, conversionApi, options) {\n    const { writer, mapper } = conversionApi;\n    // Don't reinsert if this is not a reconversion...\n    if (!options.reconversion) {\n        return false;\n    }\n    const viewChildNode = mapper.toViewElement(modelNode);\n    // ...or there is no view to reinsert or it was already inserted to the view structure...\n    if (!viewChildNode || viewChildNode.root == viewRoot) {\n        return false;\n    }\n    // ...or it was strictly marked as not to be reused.\n    if (!conversionApi.canReuseView(viewChildNode)) {\n        return false;\n    }\n    // Otherwise reinsert the view node.\n    writer.move(writer.createRangeOn(viewChildNode), mapper.toViewPosition(Position._createBefore(modelNode)));\n    return true;\n}\n/**\n * The default consumer for insert events.\n *\n * @param item Model item.\n * @param consumable The model consumable.\n * @param options.preflight Whether should consume or just check if can be consumed.\n */ function defaultConsumer(item, consumable, { preflight } = {}) {\n    if (preflight) {\n        return consumable.test(item, 'insert');\n    } else {\n        return consumable.consume(item, 'insert');\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module engine/model/utils/autoparagraphing\n */ /**\n * Fixes all empty roots.\n *\n * @internal\n * @param writer The model writer.\n * @returns `true` if any change has been applied, `false` otherwise.\n */ function autoParagraphEmptyRoots(writer) {\n    const { schema, document } = writer.model;\n    for (const root of document.getRoots()){\n        if (root.isEmpty && !schema.checkChild(root, '$text')) {\n            // If paragraph element is allowed in the root, create paragraph element.\n            if (schema.checkChild(root, 'paragraph')) {\n                writer.insertElement('paragraph', root);\n                // Other roots will get fixed in the next post-fixer round. Those will be triggered\n                // in the same batch no matter if this method was triggered by the post-fixing or not\n                // (the above insertElement call will trigger the post-fixers).\n                return true;\n            }\n        }\n    }\n    return false;\n}\n/**\n * Checks if the given node wrapped with a paragraph would be accepted by the schema in the given position.\n *\n * @internal\n * @param position The position at which to check.\n * @param nodeOrType The child node or child type to check.\n * @param schema A schema instance used for element validation.\n */ function isParagraphable(position, nodeOrType, schema) {\n    const context = schema.createContext(position);\n    // When paragraph is allowed in this context...\n    if (!schema.checkChild(context, 'paragraph')) {\n        return false;\n    }\n    // And a node would be allowed in this paragraph...\n    if (!schema.checkChild(context.push('paragraph'), nodeOrType)) {\n        return false;\n    }\n    return true;\n}\n/**\n * Inserts a new paragraph at the given position and returns a position inside that paragraph.\n *\n * @internal\n * @param position The position where a paragraph should be inserted.\n * @param writer The model writer.\n * @returns  Position inside the created paragraph.\n */ function wrapInParagraph(position, writer) {\n    const paragraph = writer.createElement('paragraph');\n    writer.insert(paragraph, position);\n    return writer.createPositionAt(paragraph, 0);\n}\n\n/**\n * Contains the {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for\n * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}.\n *\n * @module engine/conversion/upcasthelpers\n */ /**\n * Upcast conversion helper functions.\n *\n * Learn more about {@glink framework/deep-dive/conversion/upcast upcast helpers}.\n *\n * @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n */ class UpcastHelpers extends ConversionHelpers {\n    /**\n\t * View element to model element conversion helper.\n\t *\n\t * This conversion results in creating a model element. For example,\n\t * view `<p>Foo</p>` becomes `<paragraph>Foo</paragraph>` in the model.\n\t *\n\t * Keep in mind that the element will be inserted only if it is allowed\n\t * by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: 'p',\n\t * \tmodel: 'paragraph'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: 'p',\n\t * \tmodel: 'paragraph',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'fancy'\n\t * \t},\n\t * \tmodel: 'fancyParagraph'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'heading'\n\t * \t},\n\t * \tmodel: ( viewElement, conversionApi ) => {\n\t * \t\tconst modelWriter = conversionApi.writer;\n\t *\n\t * \t\treturn modelWriter.createElement( 'heading', { level: viewElement.getAttribute( 'data-level' ) } );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Pattern matching all view elements which should be converted. If not set, the converter\n\t * will fire for every view element.\n\t * @param config.model Name of the model element, a model element instance or a function that takes a view element\n\t * and {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API}\n\t * and returns a model element. The model element will be inserted in the model.\n\t * @param config.converterPriority Converter priority.\n\t */ elementToElement(config) {\n        return this.add(upcastElementToElement(config));\n    }\n    /**\n\t * View element to model attribute conversion helper.\n\t *\n\t * This conversion results in setting an attribute on a model node. For example, view `<strong>Foo</strong>` becomes\n\t * `Foo` {@link module:engine/model/text~Text model text node} with `bold` attribute set to `true`.\n\t *\n\t * This helper is meant to set a model attribute on all the elements that are inside the converted element:\n\t *\n\t * ```\n\t * <strong>Foo</strong>   -->   <strong><p>Foo</p></strong>   -->   <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t * ```\n\t *\n\t * Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t * Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text. See\n\t * {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute} for comparison.\n\t *\n\t * Keep in mind that the attribute will be set only if it is allowed by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: 'strong',\n\t * \tmodel: 'bold'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: 'strong',\n\t * \tmodel: 'bold',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: 'bold'\n\t * \t},\n\t * \tmodel: 'bold'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: [ 'styled', 'styled-dark' ]\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'styled',\n\t * \t\tvalue: 'dark'\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tstyles: {\n\t * \t\t\t'font-size': /[\\s\\S]+/\n\t * \t\t}\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'fontSize',\n\t * \t\tvalue: ( viewElement, conversionApi ) => {\n\t * \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t * \t\t\tconst value = fontSize.substr( 0, fontSize.length - 2 );\n\t *\n\t * \t\t\tif ( value <= 10 ) {\n\t * \t\t\t\treturn 'small';\n\t * \t\t\t} else if ( value > 12 ) {\n\t * \t\t\t\treturn 'big';\n\t * \t\t\t}\n\t *\n\t * \t\t\treturn null;\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Pattern matching all view elements which should be converted.\n\t * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n\t * the model attribute. `value` property may be set as a function that takes a view element and\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the value.\n\t * If `String` is given, the model attribute value will be set to `true`.\n\t * @param config.converterPriority Converter priority. Defaults to `low`.\n\t */ elementToAttribute(config) {\n        return this.add(upcastElementToAttribute(config));\n    }\n    /**\n\t * View attribute to model attribute conversion helper.\n\t *\n\t * This conversion results in setting an attribute on a model node. For example, view `<img src=\"foo.jpg\"></img>` becomes\n\t * `<imageBlock source=\"foo.jpg\"></imageBlock>` in the model.\n\t *\n\t * This helper is meant to convert view attributes from view elements which got converted to the model, so the view attribute\n\t * is set only on the corresponding model node:\n\t *\n\t * ```\n\t * <div class=\"dark\"><div>foo</div></div>    -->    <div dark=\"true\"><div>foo</div></div>\n\t * ```\n\t *\n\t * Above, `class=\"dark\"` attribute is added only to the `<div>` elements that has it. This is in contrast to\n\t * {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute} which sets attributes for\n\t * all the children in the model:\n\t *\n\t * ```\n\t * <strong>Foo</strong>   -->   <strong><p>Foo</p></strong>   -->   <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t * ```\n\t *\n\t * Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t * Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text.\n\t *\n\t * Keep in mind that the attribute will be set only if it is allowed by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: 'src',\n\t * \tmodel: 'source'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: { key: 'src' },\n\t * \tmodel: 'source'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: { key: 'src' },\n\t * \tmodel: 'source',\n\t * \tconverterPriority: 'normal'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tkey: 'data-style',\n\t * \t\tvalue: /[\\s\\S]+/\n\t * \t},\n\t * \tmodel: 'styled'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'img',\n\t * \t\tkey: 'class',\n\t * \t\tvalue: 'styled-dark'\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'styled',\n\t * \t\tvalue: 'dark'\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tkey: 'class',\n\t * \t\tvalue: /styled-[\\S]+/\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'styled'\n\t * \t\tvalue: ( viewElement, conversionApi ) => {\n\t * \t\t\tconst regexp = /styled-([\\S]+)/;\n\t * \t\t\tconst match = viewElement.getAttribute( 'class' ).match( regexp );\n\t *\n\t * \t\t\treturn match[ 1 ];\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Converting styles works a bit differently as it requires `view.styles` to be an object and by default\n\t * a model attribute will be set to `true` by such a converter. You can set the model attribute to any value by providing the `value`\n\t * callback that returns the desired value.\n\t *\n\t * ```ts\n\t * // Default conversion of font-weight style will result in setting bold attribute to true.\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tstyles: {\n\t * \t\t\t'font-weight': 'bold'\n\t * \t\t}\n\t * \t},\n\t * \tmodel: 'bold'\n\t * } );\n\t *\n\t * // This converter will pass any style value to the `lineHeight` model attribute.\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tstyles: {\n\t * \t\t\t'line-height': /[\\s\\S]+/\n\t * \t\t}\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'lineHeight',\n\t * \t\tvalue: ( viewElement, conversionApi ) => viewElement.getStyle( 'line-height' )\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Specifies which view attribute will be converted. If a `String` is passed,\n\t * attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n\t * specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n\t * property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n\t * a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n\t * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n\t * the model attribute. `value` property may be set as a function that takes a view element and\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the value.\n\t * If `String` is given, the model attribute value will be same as view attribute value.\n\t * @param config.converterPriority Converter priority. Defaults to `low`.\n\t */ attributeToAttribute(config) {\n        return this.add(upcastAttributeToAttribute(config));\n    }\n    /**\n\t * View element to model marker conversion helper.\n\t *\n\t * This conversion results in creating a model marker. For example, if the marker was stored in a view as an element:\n\t * `<p>Fo<span data-marker=\"comment\" data-comment-id=\"7\"></span>o</p><p>B<span data-marker=\"comment\" data-comment-id=\"7\"></span>ar</p>`,\n\t * after the conversion is done, the marker will be available in\n\t * {@link module:engine/model/model~Model#markers model document markers}.\n\t *\n\t * **Note**: When this helper is used in the data upcast in combination with\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} in the data downcast,\n\t * then invalid HTML code (e.g. a span between table cells) may be produced by the latter converter.\n\t *\n\t * In most of the cases, the {@link #dataToMarker} should be used instead.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: 'marker-search',\n\t * \tmodel: 'search'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: 'marker-search',\n\t * \tmodel: 'search',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: 'marker-search',\n\t * \tmodel: ( viewElement, conversionApi ) => 'comment:' + viewElement.getAttribute( 'data-comment-id' )\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tattributes: {\n\t * \t\t\t'data-marker': 'search'\n\t * \t\t}\n\t * \t},\n\t * \tmodel: 'search'\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Pattern matching all view elements which should be converted.\n\t * @param config.model Name of the model marker, or a function that takes a view element and returns\n\t * a model marker name.\n\t * @param config.converterPriority Converter priority.\n\t */ elementToMarker(config) {\n        return this.add(upcastElementToMarker(config));\n    }\n    /**\n\t * View-to-model marker conversion helper.\n\t *\n\t * Converts view data created by {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`}\n\t * back to a model marker.\n\t *\n\t * This converter looks for specific view elements and view attributes that mark marker boundaries. See\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} to learn what view data\n\t * is expected by this converter.\n\t *\n\t * The `config.view` property is equal to the marker group name to convert.\n\t *\n\t * By default, this converter creates markers with the `group:name` name convention (to match the default `markerToData` conversion).\n\t *\n\t * The conversion configuration can take a function that will generate a marker name.\n\t * If such function is set as the `config.model` parameter, it is passed the `name` part from the view element or attribute and it is\n\t * expected to return a string with the marker name.\n\t *\n\t * Basic usage:\n\t *\n\t * ```ts\n\t * // Using the default conversion.\n\t * // In this case, all markers from the `comment` group will be converted.\n\t * // The conversion will look for `<comment-start>` and `<comment-end>` tags and\n\t * // `data-comment-start-before`, `data-comment-start-after`,\n\t * // `data-comment-end-before` and `data-comment-end-after` attributes.\n\t * editor.conversion.for( 'upcast' ).dataToMarker( {\n\t * \tview: 'comment'\n\t * } );\n\t * ```\n\t *\n\t * An example of a model that may be generated by this conversion:\n\t *\n\t * ```\n\t * // View:\n\t * <p>Foo<comment-start name=\"commentId:uid\"></comment-start>bar</p>\n\t * <figure data-comment-end-after=\"commentId:uid\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t *\n\t * // Model:\n\t * <paragraph>Foo[bar</paragraph>\n\t * <imageBlock src=\"abc.jpg\"></imageBlock>]\n\t * ```\n\t *\n\t * Where `[]` are boundaries of a marker that will receive the `comment:commentId:uid` name.\n\t *\n\t * Other examples of usage:\n\t *\n\t * ```ts\n\t * // Using a custom function which is the same as the default conversion:\n\t * editor.conversion.for( 'upcast' ).dataToMarker( {\n\t * \tview: 'comment',\n\t * \tmodel: ( name, conversionApi ) => 'comment:' + name,\n\t * } );\n\t *\n\t * // Using the converter priority:\n\t * editor.conversion.for( 'upcast' ).dataToMarker( {\n\t * \tview: 'comment',\n\t * \tmodel: ( name, conversionApi ) => 'comment:' + name,\n\t * \tconverterPriority: 'high'\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view The marker group name to convert.\n\t * @param config.model A function that takes the `name` part from the view element or attribute and\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the marker name.\n\t * @param config.converterPriority Converter priority.\n\t */ dataToMarker(config) {\n        return this.add(upcastDataToMarker(config));\n    }\n}\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * or all children of {@link module:engine/view/element~Element} into\n * {@link module:engine/model/documentfragment~DocumentFragment model document fragment}.\n * This is the \"entry-point\" converter for upcast (view to model conversion). This converter starts the conversion of all children\n * of passed view document fragment. Those children {@link module:engine/view/node~Node view nodes} are then handled by other converters.\n *\n * This also a \"default\", last resort converter for all view elements that has not been converted by other converters.\n * When a view element is being converted to the model but it does not have converter specified, that view element\n * will be converted to {@link module:engine/model/documentfragment~DocumentFragment model document fragment} and returned.\n *\n * @returns Universal converter for view {@link module:engine/view/documentfragment~DocumentFragment fragments} and\n * {@link module:engine/view/element~Element elements} that returns\n * {@link module:engine/model/documentfragment~DocumentFragment model fragment} with children of converted view item.\n */ function convertToModelFragment$1() {\n    return (evt, data, conversionApi)=>{\n        // Second argument in `consumable.consume` is discarded for ViewDocumentFragment but is needed for ViewElement.\n        if (!data.modelRange && conversionApi.consumable.consume(data.viewItem, {\n            name: true\n        })) {\n            const { modelRange, modelCursor } = conversionApi.convertChildren(data.viewItem, data.modelCursor);\n            data.modelRange = modelRange;\n            data.modelCursor = modelCursor;\n        }\n    };\n}\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/text~Text} to {@link module:engine/model/text~Text}.\n *\n * @returns {@link module:engine/view/text~Text View text} converter.\n */ function convertText() {\n    return (evt, data, { schema, consumable, writer })=>{\n        let position = data.modelCursor;\n        // When node is already converted then do nothing.\n        if (!consumable.test(data.viewItem)) {\n            return;\n        }\n        if (!schema.checkChild(position, '$text')) {\n            if (!isParagraphable(position, '$text', schema)) {\n                return;\n            }\n            // Do not auto-paragraph whitespaces.\n            if (data.viewItem.data.trim().length == 0) {\n                return;\n            }\n            position = wrapInParagraph(position, writer);\n        }\n        consumable.consume(data.viewItem);\n        const text = writer.createText(data.viewItem.data);\n        writer.insert(text, position);\n        data.modelRange = writer.createRange(position, position.getShiftedBy(text.offsetSize));\n        data.modelCursor = data.modelRange.end;\n    };\n}\n/**\n * Function factory, creates a callback function which converts a {@link module:engine/view/selection~Selection\n * view selection} taken from the {@link module:engine/view/document~Document#event:selectionChange} event\n * and sets in on the {@link module:engine/model/document~Document#selection model}.\n *\n * **Note**: because there is no view selection change dispatcher nor any other advanced view selection to model\n * conversion mechanism, the callback should be set directly on view document.\n *\n * ```ts\n * view.document.on( 'selectionChange', convertSelectionChange( modelDocument, mapper ) );\n * ```\n *\n * @param model Data model.\n * @param mapper Conversion mapper.\n * @returns {@link module:engine/view/document~Document#event:selectionChange} callback function.\n */ function convertSelectionChange(model, mapper) {\n    return (evt, data)=>{\n        const viewSelection = data.newSelection;\n        const ranges = [];\n        for (const viewRange of viewSelection.getRanges()){\n            ranges.push(mapper.toModelRange(viewRange));\n        }\n        const modelSelection = model.createSelection(ranges, {\n            backward: viewSelection.isBackward\n        });\n        if (!modelSelection.isEqual(model.document.selection)) {\n            model.change((writer)=>{\n                writer.setSelection(modelSelection);\n            });\n        }\n    };\n}\n/**\n * View element to model element conversion helper.\n *\n * See {@link ~UpcastHelpers#elementToElement `.elementToElement()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Pattern matching all view elements which should be converted. If not\n * set, the converter will fire for every view element.\n * @param config.model Name of the model element, a model element\n * instance or a function that takes a view element and returns a model element. The model element will be inserted in the model.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */ function upcastElementToElement(config) {\n    config = cloneDeep(config);\n    const converter = prepareToElementConverter(config);\n    const elementName = getViewElementNameFromConfig(config.view);\n    const eventName = elementName ? `element:${elementName}` : 'element';\n    return (dispatcher)=>{\n        dispatcher.on(eventName, converter, {\n            priority: config.converterPriority || 'normal'\n        });\n    };\n}\n/**\n * View element to model attribute conversion helper.\n *\n * See {@link ~UpcastHelpers#elementToAttribute `.elementToAttribute()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Pattern matching all view elements which should be converted.\n * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n * the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n * If `String` is given, the model attribute value will be set to `true`.\n * @param config.converterPriority Converter priority. Defaults to `low`.\n * @returns Conversion helper.\n */ function upcastElementToAttribute(config) {\n    config = cloneDeep(config);\n    normalizeModelAttributeConfig(config);\n    const converter = prepareToAttributeConverter(config, false);\n    const elementName = getViewElementNameFromConfig(config.view);\n    const eventName = elementName ? `element:${elementName}` : 'element';\n    return (dispatcher)=>{\n        dispatcher.on(eventName, converter, {\n            priority: config.converterPriority || 'low'\n        });\n    };\n}\n/**\n * View attribute to model attribute conversion helper.\n *\n * See {@link ~UpcastHelpers#attributeToAttribute `.attributeToAttribute()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Specifies which view attribute will be converted. If a `String` is passed,\n * attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n * specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n * property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n * a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n * the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n * If `String` is given, the model attribute value will be same as view attribute value.\n * @param config.converterPriority Converter priority. Defaults to `low`.\n * @returns Conversion helper.\n */ function upcastAttributeToAttribute(config) {\n    config = cloneDeep(config);\n    let viewKey = null;\n    if (typeof config.view == 'string' || config.view.key) {\n        viewKey = normalizeViewAttributeKeyValueConfig(config);\n    }\n    normalizeModelAttributeConfig(config, viewKey);\n    const converter = prepareToAttributeConverter(config, true);\n    return (dispatcher)=>{\n        dispatcher.on('element', converter, {\n            priority: config.converterPriority || 'low'\n        });\n    };\n}\n/**\n * View element to model marker conversion helper.\n *\n * See {@link ~UpcastHelpers#elementToMarker `.elementToMarker()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Pattern matching all view elements which should be converted.\n * @param config.model Name of the model marker, or a function that takes a view element and returns\n * a model marker name.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */ function upcastElementToMarker(config) {\n    const model = normalizeElementToMarkerModelConfig(config.model);\n    return upcastElementToElement({\n        ...config,\n        model\n    });\n}\n/**\n * View data to model marker conversion helper.\n *\n * See {@link ~UpcastHelpers#dataToMarker} to learn more.\n *\n * @returns Conversion helper.\n */ function upcastDataToMarker(config) {\n    config = cloneDeep(config);\n    // Default conversion.\n    if (!config.model) {\n        config.model = (name)=>{\n            return name ? config.view + ':' + name : config.view;\n        };\n    }\n    const normalizedConfig = {\n        view: config.view,\n        model: config.model\n    };\n    const converterStart = prepareToElementConverter(normalizeDataToMarkerConfig(normalizedConfig, 'start'));\n    const converterEnd = prepareToElementConverter(normalizeDataToMarkerConfig(normalizedConfig, 'end'));\n    return (dispatcher)=>{\n        dispatcher.on(`element:${config.view}-start`, converterStart, {\n            priority: config.converterPriority || 'normal'\n        });\n        dispatcher.on(`element:${config.view}-end`, converterEnd, {\n            priority: config.converterPriority || 'normal'\n        });\n        // Below is a hack that is needed to properly handle `converterPriority` for both elements and attributes.\n        // Attribute conversion needs to be performed *after* element conversion.\n        // This converter handles both element conversion and attribute conversion, which means that if a single\n        // `config.converterPriority` is used, it will lead to problems. For example, if the `'high'` priority is used,\n        // the attribute conversion will be performed before a lot of element upcast converters.\n        // On the other hand, we want to support `config.converterPriority` and converter overwriting.\n        //\n        // To make it work, we need to do some extra processing for priority for attribute converter.\n        // Priority `'low'` value should be the base value and then we will change it depending on `config.converterPriority` value.\n        //\n        // This hack probably would not be needed if attributes are upcasted separately.\n        //\n        const basePriority = priorities.low;\n        const maxPriority = priorities.highest;\n        const priorityFactor = priorities.get(config.converterPriority) / maxPriority; // Number in range [ -1, 1 ].\n        dispatcher.on('element', upcastAttributeToMarker(normalizedConfig), {\n            priority: basePriority + priorityFactor\n        });\n    };\n}\n/**\n * Function factory, returns a callback function which converts view attributes to a model marker.\n *\n * The converter looks for elements with `data-group-start-before`, `data-group-start-after`, `data-group-end-before`\n * and `data-group-end-after` attributes and inserts `$marker` model elements before/after those elements.\n * `group` part is specified in `config.view`.\n *\n * @returns Marker converter.\n */ function upcastAttributeToMarker(config) {\n    return (evt, data, conversionApi)=>{\n        const attrName = `data-${config.view}`;\n        // Check if any attribute for the given view item can be consumed before changing the conversion data\n        // and consuming view items with these attributes.\n        if (!conversionApi.consumable.test(data.viewItem, {\n            attributes: attrName + '-end-after'\n        }) && !conversionApi.consumable.test(data.viewItem, {\n            attributes: attrName + '-start-after'\n        }) && !conversionApi.consumable.test(data.viewItem, {\n            attributes: attrName + '-end-before'\n        }) && !conversionApi.consumable.test(data.viewItem, {\n            attributes: attrName + '-start-before'\n        })) {\n            return;\n        }\n        // This converter wants to add a model element, marking a marker, before/after an element (or maybe even group of elements).\n        // To do that, we can use `data.modelRange` which is set on an element (or a group of elements) that has been upcasted.\n        // But, if the processed view element has not been upcasted yet (it does not have been converted), we need to\n        // fire conversion for its children first, then we will have `data.modelRange` available.\n        if (!data.modelRange) {\n            Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n        }\n        if (conversionApi.consumable.consume(data.viewItem, {\n            attributes: attrName + '-end-after'\n        })) {\n            addMarkerElements(data.modelRange.end, data.viewItem.getAttribute(attrName + '-end-after').split(','));\n        }\n        if (conversionApi.consumable.consume(data.viewItem, {\n            attributes: attrName + '-start-after'\n        })) {\n            addMarkerElements(data.modelRange.end, data.viewItem.getAttribute(attrName + '-start-after').split(','));\n        }\n        if (conversionApi.consumable.consume(data.viewItem, {\n            attributes: attrName + '-end-before'\n        })) {\n            addMarkerElements(data.modelRange.start, data.viewItem.getAttribute(attrName + '-end-before').split(','));\n        }\n        if (conversionApi.consumable.consume(data.viewItem, {\n            attributes: attrName + '-start-before'\n        })) {\n            addMarkerElements(data.modelRange.start, data.viewItem.getAttribute(attrName + '-start-before').split(','));\n        }\n        function addMarkerElements(position, markerViewNames) {\n            for (const markerViewName of markerViewNames){\n                const markerName = config.model(markerViewName, conversionApi);\n                const element = conversionApi.writer.createElement('$marker', {\n                    'data-name': markerName\n                });\n                conversionApi.writer.insert(element, position);\n                if (data.modelCursor.isEqual(position)) {\n                    data.modelCursor = data.modelCursor.getShiftedBy(1);\n                } else {\n                    data.modelCursor = data.modelCursor._getTransformedByInsertion(position, 1);\n                }\n                data.modelRange = data.modelRange._getTransformedByInsertion(position, 1)[0];\n            }\n        }\n    };\n}\n/**\n * Helper function for from-view-element conversion. Checks if `config.view` directly specifies converted view element's name\n * and if so, returns it.\n *\n * @param config Conversion view config.\n * @returns View element name or `null` if name is not directly set.\n */ function getViewElementNameFromConfig(viewConfig) {\n    if (typeof viewConfig == 'string') {\n        return viewConfig;\n    }\n    if (typeof viewConfig == 'object' && typeof viewConfig.name == 'string') {\n        return viewConfig.name;\n    }\n    return null;\n}\n/**\n * Helper for to-model-element conversion. Takes a config object and returns a proper converter function.\n *\n * @param config Conversion configuration.\n * @returns View to model converter.\n */ function prepareToElementConverter(config) {\n    const matcher = new Matcher(config.view);\n    return (evt, data, conversionApi)=>{\n        const matcherResult = matcher.match(data.viewItem);\n        if (!matcherResult) {\n            return;\n        }\n        const match = matcherResult.match;\n        // Force consuming element's name.\n        match.name = true;\n        if (!conversionApi.consumable.test(data.viewItem, match)) {\n            return;\n        }\n        const modelElement = getModelElement(config.model, data.viewItem, conversionApi);\n        if (!modelElement) {\n            return;\n        }\n        if (!conversionApi.safeInsert(modelElement, data.modelCursor)) {\n            return;\n        }\n        conversionApi.consumable.consume(data.viewItem, match);\n        conversionApi.convertChildren(data.viewItem, modelElement);\n        conversionApi.updateConversionResult(modelElement, data);\n    };\n}\n/**\n * Helper function for upcasting-to-element converter. Takes the model configuration, the converted view element\n * and a writer instance and returns a model element instance to be inserted in the model.\n *\n * @param model Model conversion configuration.\n * @param input The converted view node.\n * @param conversionApi The upcast conversion API.\n */ function getModelElement(model, input, conversionApi) {\n    if (model instanceof Function) {\n        return model(input, conversionApi);\n    } else {\n        return conversionApi.writer.createElement(model);\n    }\n}\n/**\n * Helper function view-attribute-to-model-attribute helper. Normalizes `config.view` which was set as `String` or\n * as an `Object` with `key`, `value` and `name` properties. Normalized `config.view` has is compatible with\n * {@link module:engine/view/matcher~MatcherPattern}.\n *\n * @param config Conversion config.\n * @returns Key of the converted view attribute.\n */ function normalizeViewAttributeKeyValueConfig(config) {\n    if (typeof config.view == 'string') {\n        config.view = {\n            key: config.view\n        };\n    }\n    const key = config.view.key;\n    const value = typeof config.view.value == 'undefined' ? /[\\s\\S]*/ : config.view.value;\n    let normalized;\n    if (key == 'class' || key == 'style') {\n        const keyName = key == 'class' ? 'classes' : 'styles';\n        normalized = {\n            [keyName]: value\n        };\n    } else {\n        normalized = {\n            attributes: {\n                [key]: value\n            }\n        };\n    }\n    if (config.view.name) {\n        normalized.name = config.view.name;\n    }\n    config.view = normalized;\n    return key;\n}\n/**\n * Helper function that normalizes `config.model` in from-model-attribute conversion. `config.model` can be set\n * as a `String`, an `Object` with only `key` property or an `Object` with `key` and `value` properties. Normalized\n * `config.model` is an `Object` with `key` and `value` properties.\n *\n * @param config Conversion config.\n * @param viewAttributeKeyToCopy Key of the converted view attribute. If it is set, model attribute value\n * will be equal to view attribute value.\n */ function normalizeModelAttributeConfig(config, viewAttributeKeyToCopy = null) {\n    const defaultModelValue = viewAttributeKeyToCopy === null ? true : (viewElement)=>viewElement.getAttribute(viewAttributeKeyToCopy);\n    const key = typeof config.model != 'object' ? config.model : config.model.key;\n    const value = typeof config.model != 'object' || typeof config.model.value == 'undefined' ? defaultModelValue : config.model.value;\n    config.model = {\n        key,\n        value\n    };\n}\n/**\n * Helper for to-model-attribute conversion. Takes the model attribute name and conversion configuration and returns\n * a proper converter function.\n *\n * @param config Conversion configuration. It is possible to provide multiple configurations in an array.\n * @param shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n * on all elements in the range.\n */ function prepareToAttributeConverter(config, shallow) {\n    const matcher = new Matcher(config.view);\n    return (evt, data, conversionApi)=>{\n        // Converting an attribute of an element that has not been converted to anything does not make sense\n        // because there will be nowhere to set that attribute on. At this stage, the element should've already\n        // been converted (https://github.com/ckeditor/ckeditor5/issues/11000).\n        if (!data.modelRange && shallow) {\n            return;\n        }\n        const match = matcher.match(data.viewItem);\n        // If there is no match, this callback should not do anything.\n        if (!match) {\n            return;\n        }\n        if (onlyViewNameIsDefined(config.view, data.viewItem)) {\n            match.match.name = true;\n        } else {\n            // Do not test `name` consumable because it could get consumed already while upcasting some other attribute\n            // on the same element (for example <span class=\"big\" style=\"color: red\">foo</span>).\n            delete match.match.name;\n        }\n        // Try to consume appropriate values from consumable values list.\n        if (!conversionApi.consumable.test(data.viewItem, match.match)) {\n            return;\n        }\n        const modelKey = config.model.key;\n        const modelValue = typeof config.model.value == 'function' ? config.model.value(data.viewItem, conversionApi) : config.model.value;\n        // Do not convert if attribute building function returned falsy value.\n        if (modelValue === null) {\n            return;\n        }\n        // Since we are converting to attribute we need a range on which we will set the attribute.\n        // If the range is not created yet, let's create it by converting children of the current node first.\n        if (!data.modelRange) {\n            // Convert children and set conversion result as a current data.\n            Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n        }\n        // Set attribute on current `output`. `Schema` is checked inside this helper function.\n        const attributeWasSet = setAttributeOn(data.modelRange, {\n            key: modelKey,\n            value: modelValue\n        }, shallow, conversionApi);\n        // It may happen that a converter will try to set an attribute that is not allowed in the given context.\n        // In such a situation we cannot consume the attribute. See: https://github.com/ckeditor/ckeditor5/pull/9249#issuecomment-815658459.\n        if (attributeWasSet) {\n            // Verify if the element itself wasn't consumed yet. It could be consumed already while upcasting some other attribute\n            // on the same element (for example <span class=\"big\" style=\"color: red\">foo</span>).\n            // We need to consume it so other features (especially GHS) won't try to convert it.\n            // Note that it's not tested by the other element-to-attribute converters whether an element was consumed before\n            // (in case of converters that the element itself is just a context and not the primary information to convert).\n            if (conversionApi.consumable.test(data.viewItem, {\n                name: true\n            })) {\n                match.match.name = true;\n            }\n            conversionApi.consumable.consume(data.viewItem, match.match);\n        }\n    };\n}\n/**\n * Helper function that checks if element name should be consumed in attribute converters.\n *\n * @param viewConfig Conversion view config.\n */ function onlyViewNameIsDefined(viewConfig, viewItem) {\n    // https://github.com/ckeditor/ckeditor5-engine/issues/1786\n    const configToTest = typeof viewConfig == 'function' ? viewConfig(viewItem) : viewConfig;\n    if (typeof configToTest == 'object' && !getViewElementNameFromConfig(configToTest)) {\n        return false;\n    }\n    return !configToTest.classes && !configToTest.attributes && !configToTest.styles;\n}\n/**\n * Helper function for to-model-attribute converter. Sets model attribute on given range. Checks {@link module:engine/model/schema~Schema}\n * to ensure proper model structure.\n *\n * If any node on the given range has already defined an attribute with the same name, its value will not be updated.\n *\n * @param modelRange Model range on which attribute should be set.\n * @param modelAttribute Model attribute to set.\n * @param conversionApi Conversion API.\n * @param shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n * on all elements in the range.\n * @returns `true` if attribute was set on at least one node from given `modelRange`.\n */ function setAttributeOn(modelRange, modelAttribute, shallow, conversionApi) {\n    let result = false;\n    // Set attribute on each item in range according to Schema.\n    for (const node of Array.from(modelRange.getItems({\n        shallow\n    }))){\n        // Skip if not allowed.\n        if (!conversionApi.schema.checkAttribute(node, modelAttribute.key)) {\n            continue;\n        }\n        // Mark the node as consumed even if the attribute will not be updated because it's in a valid context (schema)\n        // and would be converted if the attribute wouldn't be present. See #8921.\n        result = true;\n        // Do not override the attribute if it's already present.\n        if (node.hasAttribute(modelAttribute.key)) {\n            continue;\n        }\n        conversionApi.writer.setAttribute(modelAttribute.key, modelAttribute.value, node);\n    }\n    return result;\n}\n/**\n * Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastElementToMarker()`\n * function and converts it to a format that is supported by `upcastElementToElement()` function.\n */ function normalizeElementToMarkerModelConfig(model) {\n    return (viewElement, conversionApi)=>{\n        const markerName = typeof model == 'string' ? model : model(viewElement, conversionApi);\n        return conversionApi.writer.createElement('$marker', {\n            'data-name': markerName\n        });\n    };\n}\n/**\n * Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastDataToMarker()`\n * function and converts it to a format that is supported by `upcastElementToElement()` function.\n */ function normalizeDataToMarkerConfig(config, type) {\n    const elementCreatorFunction = (viewElement, conversionApi)=>{\n        const viewName = viewElement.getAttribute('name');\n        const markerName = config.model(viewName, conversionApi);\n        return conversionApi.writer.createElement('$marker', {\n            'data-name': markerName\n        });\n    };\n    return {\n        // Upcast <markerGroup-start> and <markerGroup-end> elements.\n        view: `${config.view}-${type}`,\n        model: elementCreatorFunction\n    };\n}\n\n/**\n * Injects selection post-fixer to the model.\n *\n * The role of the selection post-fixer is to ensure that the selection is in a correct place\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct position means that:\n *\n * * All collapsed selection ranges are in a place where the {@link module:engine/model/schema~Schema}\n * allows a `$text`.\n * * None of the selection's non-collapsed ranges crosses a {@link module:engine/model/schema~Schema#isLimit limit element}\n * boundary (a range must be rooted within one limit element).\n * * Only {@link module:engine/model/schema~Schema#isSelectable selectable elements} can be selected from the outside\n * (e.g. `[<paragraph>foo</paragraph>]` is invalid). This rule applies independently to both selection ends, so this\n * selection is correct: `<paragraph>f[oo</paragraph><imageBlock></imageBlock>]`.\n *\n * If the position is not correct, the post-fixer will automatically correct it.\n *\n * ## Fixing a non-collapsed selection\n *\n * See as an example a selection that starts in a P1 element and ends inside the text of a TD element\n * (`[` and `]` are range boundaries and `(l)` denotes an element defined as `isLimit=true`):\n *\n * ```\n * root\n *  |- element P1\n *  |   |- \"foo\"                                      root\n *  |- element TABLE (l)                   P1         TABLE             P2\n *  |   |- element TR (l)                 f o[o     TR      TR         b a r\n *  |   |   |- element TD (l)                       TD      TD\n *  |   |       |- \"aaa\"                          a]a a    b b b\n *  |   |- element TR (l)\n *  |   |   |- element TD (l)                           ||\n *  |   |       |- \"bbb\"                                ||\n *  |- element P2                                       VV\n *  |   |- \"bar\"\n *                                                    root\n *                                         P1         TABLE]            P2\n *                                        f o[o     TR      TR         b a r\n *                                                  TD      TD\n *                                                a a a    b b b\n * ```\n *\n * In the example above, the TABLE, TR and TD are defined as `isLimit=true` in the schema. The range which is not contained within\n * a single limit element must be expanded to select the outermost limit element. The range end is inside the text node of the TD element.\n * As the TD element is a child of the TR and TABLE elements, where both are defined as `isLimit=true` in the schema, the range must be\n * expanded to select the whole TABLE element.\n *\n * **Note** If the selection contains multiple ranges, the method returns a minimal set of ranges that are not intersecting after expanding\n * them to select `isLimit=true` elements.\n */ function injectSelectionPostFixer(model) {\n    model.document.registerPostFixer((writer)=>selectionPostFixer(writer, model));\n}\n/**\n * The selection post-fixer.\n */ function selectionPostFixer(writer, model) {\n    const selection = model.document.selection;\n    const schema = model.schema;\n    const ranges = [];\n    let wasFixed = false;\n    for (const modelRange of selection.getRanges()){\n        // Go through all ranges in selection and try fixing each of them.\n        // Those ranges might overlap but will be corrected later.\n        const correctedRange = tryFixingRange(modelRange, schema);\n        // \"Selection fixing\" algorithms sometimes get lost. In consequence, it may happen\n        // that a new range is returned but, in fact, it has the same positions as the original\n        // range anyway. If this range is not discarded, a new selection will be set and that,\n        // for instance, would destroy the selection attributes. Let's make sure that the post-fixer\n        // actually worked first before setting a new selection.\n        //\n        // https://github.com/ckeditor/ckeditor5/issues/6693\n        if (correctedRange && !correctedRange.isEqual(modelRange)) {\n            ranges.push(correctedRange);\n            wasFixed = true;\n        } else {\n            ranges.push(modelRange);\n        }\n    }\n    // If any of ranges were corrected update the selection.\n    if (wasFixed) {\n        writer.setSelection(mergeIntersectingRanges(ranges), {\n            backward: selection.isBackward\n        });\n    }\n    return false;\n}\n/**\n * Tries fixing a range if it's incorrect.\n *\n * **Note:** This helper is used by the selection post-fixer and to fix the `beforeinput` target ranges.\n *\n * @returns Returns fixed range or null if range is valid.\n */ function tryFixingRange(range, schema) {\n    if (range.isCollapsed) {\n        return tryFixingCollapsedRange(range, schema);\n    }\n    return tryFixingNonCollapsedRage(range, schema);\n}\n/**\n * Tries to fix collapsed ranges.\n *\n * * Fixes situation when a range is in a place where $text is not allowed\n *\n * @param range Collapsed range to fix.\n * @returns Returns fixed range or null if range is valid.\n */ function tryFixingCollapsedRange(range, schema) {\n    const originalPosition = range.start;\n    const nearestSelectionRange = schema.getNearestSelectionRange(originalPosition);\n    // This might be null, i.e. when the editor data is empty or the selection is inside a limit element\n    // that doesn't allow text inside.\n    // In the first case, there is no need to fix the selection range.\n    // In the second, let's go up to the outer selectable element\n    if (!nearestSelectionRange) {\n        const ancestorObject = originalPosition.getAncestors().reverse().find((item)=>schema.isObject(item));\n        if (ancestorObject) {\n            return Range._createOn(ancestorObject);\n        }\n        return null;\n    }\n    if (!nearestSelectionRange.isCollapsed) {\n        return nearestSelectionRange;\n    }\n    const fixedPosition = nearestSelectionRange.start;\n    // Fixed position is the same as original - no need to return corrected range.\n    if (originalPosition.isEqual(fixedPosition)) {\n        return null;\n    }\n    return new Range(fixedPosition);\n}\n/**\n * Tries to fix an expanded range.\n *\n * @param range Expanded range to fix.\n * @returns Returns fixed range or null if range is valid.\n */ function tryFixingNonCollapsedRage(range, schema) {\n    const { start, end } = range;\n    const isTextAllowedOnStart = schema.checkChild(start, '$text');\n    const isTextAllowedOnEnd = schema.checkChild(end, '$text');\n    const startLimitElement = schema.getLimitElement(start);\n    const endLimitElement = schema.getLimitElement(end);\n    // Ranges which both end are inside the same limit element (or root) might needs only minor fix.\n    if (startLimitElement === endLimitElement) {\n        // Range is valid when both position allows to place a text:\n        // - <block>f[oobarba]z</block>\n        // This would be \"fixed\" by a next check but as it will be the same it's better to return null so the selection stays the same.\n        if (isTextAllowedOnStart && isTextAllowedOnEnd) {\n            return null;\n        }\n        // Range that is on non-limit element (or is partially) must be fixed so it is placed inside the block around $text:\n        // - [<block>foo</block>]    ->    <block>[foo]</block>\n        // - [<block>foo]</block>    ->    <block>[foo]</block>\n        // - <block>f[oo</block>]    ->    <block>f[oo]</block>\n        // - [<block>foo</block><selectable></selectable>]    ->    <block>[foo</block><selectable></selectable>]\n        if (checkSelectionOnNonLimitElements(start, end, schema)) {\n            const isStartBeforeSelectable = start.nodeAfter && schema.isSelectable(start.nodeAfter);\n            const fixedStart = isStartBeforeSelectable ? null : schema.getNearestSelectionRange(start, 'forward');\n            const isEndAfterSelectable = end.nodeBefore && schema.isSelectable(end.nodeBefore);\n            const fixedEnd = isEndAfterSelectable ? null : schema.getNearestSelectionRange(end, 'backward');\n            // The schema.getNearestSelectionRange might return null - if that happens use original position.\n            const rangeStart = fixedStart ? fixedStart.start : start;\n            const rangeEnd = fixedEnd ? fixedEnd.end : end;\n            return new Range(rangeStart, rangeEnd);\n        }\n    }\n    const isStartInLimit = startLimitElement && !startLimitElement.is('rootElement');\n    const isEndInLimit = endLimitElement && !endLimitElement.is('rootElement');\n    // At this point we eliminated valid positions on text nodes so if one of range positions is placed inside a limit element\n    // then the range crossed limit element boundaries and needs to be fixed.\n    if (isStartInLimit || isEndInLimit) {\n        const bothInSameParent = start.nodeAfter && end.nodeBefore && start.nodeAfter.parent === end.nodeBefore.parent;\n        const expandStart = isStartInLimit && (!bothInSameParent || !isSelectable(start.nodeAfter, schema));\n        const expandEnd = isEndInLimit && (!bothInSameParent || !isSelectable(end.nodeBefore, schema));\n        // Although we've already found limit element on start/end positions we must find the outer-most limit element.\n        // as limit elements might be nested directly inside (ie table > tableRow > tableCell).\n        let fixedStart = start;\n        let fixedEnd = end;\n        if (expandStart) {\n            fixedStart = Position._createBefore(findOutermostLimitAncestor(startLimitElement, schema));\n        }\n        if (expandEnd) {\n            fixedEnd = Position._createAfter(findOutermostLimitAncestor(endLimitElement, schema));\n        }\n        return new Range(fixedStart, fixedEnd);\n    }\n    // Range was not fixed at this point so it is valid - ie it was placed around limit element already.\n    return null;\n}\n/**\n * Finds the outer-most ancestor.\n */ function findOutermostLimitAncestor(startingNode, schema) {\n    let isLimitNode = startingNode;\n    let parent = isLimitNode;\n    // Find outer most isLimit block as such blocks might be nested (ie. in tables).\n    while(schema.isLimit(parent) && parent.parent){\n        isLimitNode = parent;\n        parent = parent.parent;\n    }\n    return isLimitNode;\n}\n/**\n * Checks whether any of range boundaries is placed around non-limit elements.\n */ function checkSelectionOnNonLimitElements(start, end, schema) {\n    const startIsOnBlock = start.nodeAfter && !schema.isLimit(start.nodeAfter) || schema.checkChild(start, '$text');\n    const endIsOnBlock = end.nodeBefore && !schema.isLimit(end.nodeBefore) || schema.checkChild(end, '$text');\n    // We should fix such selection when one of those nodes needs fixing.\n    return startIsOnBlock || endIsOnBlock;\n}\n/**\n * Returns a minimal non-intersecting array of ranges without duplicates.\n *\n * @param ranges Ranges to merge.\n * @returns Array of unique and non-intersecting ranges.\n */ function mergeIntersectingRanges(ranges) {\n    const rangesToMerge = [\n        ...ranges\n    ];\n    const rangeIndexesToRemove = new Set();\n    let currentRangeIndex = 1;\n    while(currentRangeIndex < rangesToMerge.length){\n        const currentRange = rangesToMerge[currentRangeIndex];\n        const previousRanges = rangesToMerge.slice(0, currentRangeIndex);\n        for (const [previousRangeIndex, previousRange] of previousRanges.entries()){\n            if (rangeIndexesToRemove.has(previousRangeIndex)) {\n                continue;\n            }\n            if (currentRange.isEqual(previousRange)) {\n                rangeIndexesToRemove.add(previousRangeIndex);\n            } else if (currentRange.isIntersecting(previousRange)) {\n                rangeIndexesToRemove.add(previousRangeIndex);\n                rangeIndexesToRemove.add(currentRangeIndex);\n                const mergedRange = currentRange.getJoined(previousRange);\n                rangesToMerge.push(mergedRange);\n            }\n        }\n        currentRangeIndex++;\n    }\n    const nonIntersectingRanges = rangesToMerge.filter((_, index)=>!rangeIndexesToRemove.has(index));\n    return nonIntersectingRanges;\n}\n/**\n * Checks if node exists and if it's a selectable.\n */ function isSelectable(node, schema) {\n    return node && schema.isSelectable(node);\n}\n\n// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' );\n/**\n * A controller for the editing pipeline. The editing pipeline controls the {@link ~EditingController#model model} rendering,\n * including selection handling. It also creates the {@link ~EditingController#view view} which builds a\n * browser-independent virtualization over the DOM elements. The editing controller also attaches default converters.\n */ class EditingController extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * Editor model.\n\t */ model;\n    /**\n\t * Editing view controller.\n\t */ view;\n    /**\n\t * A mapper that describes the model-view binding.\n\t */ mapper;\n    /**\n\t * Downcast dispatcher that converts changes from the model to the {@link #view editing view}.\n\t */ downcastDispatcher;\n    /**\n\t * Creates an editing controller instance.\n\t *\n\t * @param model Editing model.\n\t * @param stylesProcessor The styles processor instance.\n\t */ constructor(model, stylesProcessor){\n        super();\n        this.model = model;\n        this.view = new View(stylesProcessor);\n        this.mapper = new Mapper();\n        this.downcastDispatcher = new DowncastDispatcher({\n            mapper: this.mapper,\n            schema: model.schema\n        });\n        const doc = this.model.document;\n        const selection = doc.selection;\n        const markers = this.model.markers;\n        // When plugins listen on model changes (on selection change, post fixers, etc.) and change the view as a result of\n        // the model's change, they might trigger view rendering before the conversion is completed (e.g. before the selection\n        // is converted). We disable rendering for the length of the outermost model change() block to prevent that.\n        //\n        // See https://github.com/ckeditor/ckeditor5-engine/issues/1528\n        this.listenTo(this.model, '_beforeChanges', ()=>{\n            this.view._disableRendering(true);\n        }, {\n            priority: 'highest'\n        });\n        this.listenTo(this.model, '_afterChanges', ()=>{\n            this.view._disableRendering(false);\n        }, {\n            priority: 'lowest'\n        });\n        // Whenever model document is changed, convert those changes to the view (using model.Document#differ).\n        // Do it on 'low' priority, so changes are converted after other listeners did their job.\n        // Also convert model selection.\n        this.listenTo(doc, 'change', ()=>{\n            this.view.change((writer)=>{\n                this.downcastDispatcher.convertChanges(doc.differ, markers, writer);\n                this.downcastDispatcher.convertSelection(selection, markers, writer);\n            });\n        }, {\n            priority: 'low'\n        });\n        // Convert selection from the view to the model when it changes in the view.\n        this.listenTo(this.view.document, 'selectionChange', convertSelectionChange(this.model, this.mapper));\n        // Fix `beforeinput` target ranges so that they map to the valid model ranges.\n        this.listenTo(this.view.document, 'beforeinput', fixTargetRanges(this.mapper, this.model.schema, this.view), {\n            priority: 'high'\n        });\n        // Attach default model converters.\n        this.downcastDispatcher.on('insert:$text', insertText(), {\n            priority: 'lowest'\n        });\n        this.downcastDispatcher.on('insert', insertAttributesAndChildren(), {\n            priority: 'lowest'\n        });\n        this.downcastDispatcher.on('remove', remove(), {\n            priority: 'low'\n        });\n        // Attach default model selection converters.\n        this.downcastDispatcher.on('cleanSelection', cleanSelection());\n        this.downcastDispatcher.on('selection', convertRangeSelection(), {\n            priority: 'low'\n        });\n        this.downcastDispatcher.on('selection', convertCollapsedSelection(), {\n            priority: 'low'\n        });\n        // Binds {@link module:engine/view/document~Document#roots view roots collection} to\n        // {@link module:engine/model/document~Document#roots model roots collection} so creating\n        // model root automatically creates corresponding view root.\n        this.view.document.roots.bindTo(this.model.document.roots).using((root)=>{\n            // $graveyard is a special root that has no reflection in the view.\n            if (root.rootName == '$graveyard') {\n                return null;\n            }\n            const viewRoot = new RootEditableElement(this.view.document, root.name);\n            viewRoot.rootName = root.rootName;\n            this.mapper.bindElements(root, viewRoot);\n            return viewRoot;\n        });\n    // @if CK_DEBUG_ENGINE // initDocumentDumping( this.model.document );\n    // @if CK_DEBUG_ENGINE // initDocumentDumping( this.view.document );\n    // @if CK_DEBUG_ENGINE // dumpTrees( this.model.document, this.model.document.version );\n    // @if CK_DEBUG_ENGINE // dumpTrees( this.view.document, this.model.document.version );\n    // @if CK_DEBUG_ENGINE // this.model.document.on( 'change', () => {\n    // @if CK_DEBUG_ENGINE //\tdumpTrees( this.view.document, this.model.document.version );\n    // @if CK_DEBUG_ENGINE // }, { priority: 'lowest' } );\n    }\n    /**\n\t * Removes all event listeners attached to the `EditingController`. Destroys all objects created\n\t * by `EditingController` that need to be destroyed.\n\t */ destroy() {\n        this.view.destroy();\n        this.stopListening();\n    }\n    /**\n\t * Calling this method will refresh the marker by triggering the downcast conversion for it.\n\t *\n\t * Reconverting the marker is useful when you want to change its {@link module:engine/view/element~Element view element}\n\t * without changing any marker data. For instance:\n\t *\n\t * ```ts\n\t * let isCommentActive = false;\n\t *\n\t * model.conversion.markerToHighlight( {\n\t * \tmodel: 'comment',\n\t * \tview: data => {\n\t * \t\tconst classes = [ 'comment-marker' ];\n\t *\n\t * \t\tif ( isCommentActive ) {\n\t * \t\t\tclasses.push( 'comment-marker--active' );\n\t * \t\t}\n\t *\n\t * \t\treturn { classes };\n\t * \t}\n\t * } );\n\t *\n\t * // ...\n\t *\n\t * // Change the property that indicates if marker is displayed as active or not.\n\t * isCommentActive = true;\n\t *\n\t * // Reconverting will downcast and synchronize the marker with the new isCommentActive state value.\n\t * editor.editing.reconvertMarker( 'comment' );\n\t * ```\n\t *\n\t * **Note**: If you want to reconvert a model item, use {@link #reconvertItem} instead.\n\t *\n\t * @param markerOrName Name of a marker to update, or a marker instance.\n\t */ reconvertMarker(markerOrName) {\n        const markerName = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n        const currentMarker = this.model.markers.get(markerName);\n        if (!currentMarker) {\n            /**\n\t\t\t * The marker with the provided name does not exist and cannot be reconverted.\n\t\t\t *\n\t\t\t * @error editingcontroller-reconvertmarker-marker-not-exist\n\t\t\t * @param {String} markerName The name of the reconverted marker.\n\t\t\t */ throw new CKEditorError('editingcontroller-reconvertmarker-marker-not-exist', this, {\n                markerName\n            });\n        }\n        this.model.change(()=>{\n            this.model.markers._refresh(currentMarker);\n        });\n    }\n    /**\n\t * Calling this method will downcast a model item on demand (by requesting a refresh in the {@link module:engine/model/differ~Differ}).\n\t *\n\t * You can use it if you want the view representation of a specific item updated as a response to external modifications. For instance,\n\t * when the view structure depends not only on the associated model data but also on some external state.\n\t *\n\t * **Note**: If you want to reconvert a model marker, use {@link #reconvertMarker} instead.\n\t *\n\t * @param item Item to refresh.\n\t */ reconvertItem(item) {\n        this.model.change(()=>{\n            this.model.document.differ._refreshItem(item);\n        });\n    }\n}\n/**\n * Checks whether the target ranges provided by the `beforeInput` event can be properly mapped to model ranges and fixes them if needed.\n *\n * This is using the same logic as the selection post-fixer.\n */ function fixTargetRanges(mapper, schema, view) {\n    return (evt, data)=>{\n        // The Renderer is disabled while composing on non-android browsers, so we can't be sure that target ranges\n        // could be properly mapped to view and model because the DOM and view tree drifted apart.\n        if (view.document.isComposing && !env.isAndroid) {\n            return;\n        }\n        for(let i = 0; i < data.targetRanges.length; i++){\n            const viewRange = data.targetRanges[i];\n            const modelRange = mapper.toModelRange(viewRange);\n            const correctedRange = tryFixingRange(modelRange, schema);\n            if (!correctedRange || correctedRange.isEqual(modelRange)) {\n                continue;\n            }\n            data.targetRanges[i] = mapper.toViewRange(correctedRange);\n        }\n    };\n}\n\n/**\n * Class used for handling consumption of view {@link module:engine/view/element~Element elements},\n * {@link module:engine/view/text~Text text nodes} and {@link module:engine/view/documentfragment~DocumentFragment document fragments}.\n * Element's name and its parts (attributes, classes and styles) can be consumed separately. Consuming an element's name\n * does not consume its attributes, classes and styles.\n * To add items for consumption use {@link module:engine/conversion/viewconsumable~ViewConsumable#add add method}.\n * To test items use {@link module:engine/conversion/viewconsumable~ViewConsumable#test test method}.\n * To consume items use {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consume method}.\n * To revert already consumed items use {@link module:engine/conversion/viewconsumable~ViewConsumable#revert revert method}.\n *\n * ```ts\n * viewConsumable.add( element, { name: true } ); // Adds element's name as ready to be consumed.\n * viewConsumable.add( textNode ); // Adds text node for consumption.\n * viewConsumable.add( docFragment ); // Adds document fragment for consumption.\n * viewConsumable.test( element, { name: true }  ); // Tests if element's name can be consumed.\n * viewConsumable.test( textNode ); // Tests if text node can be consumed.\n * viewConsumable.test( docFragment ); // Tests if document fragment can be consumed.\n * viewConsumable.consume( element, { name: true }  ); // Consume element's name.\n * viewConsumable.consume( textNode ); // Consume text node.\n * viewConsumable.consume( docFragment ); // Consume document fragment.\n * viewConsumable.revert( element, { name: true }  ); // Revert already consumed element's name.\n * viewConsumable.revert( textNode ); // Revert already consumed text node.\n * viewConsumable.revert( docFragment ); // Revert already consumed document fragment.\n * ```\n */ class ViewConsumable {\n    /**\n\t * Map of consumable elements. If {@link module:engine/view/element~Element element} is used as a key,\n\t * {@link module:engine/conversion/viewconsumable~ViewElementConsumables ViewElementConsumables} instance is stored as value.\n\t * For {@link module:engine/view/text~Text text nodes} and\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragments} boolean value is stored as value.\n\t */ _consumables = new Map();\n    add(element, consumables) {\n        let elementConsumables;\n        // For text nodes and document fragments just mark them as consumable.\n        if (element.is('$text') || element.is('documentFragment')) {\n            this._consumables.set(element, true);\n            return;\n        }\n        // For elements create new ViewElementConsumables or update already existing one.\n        if (!this._consumables.has(element)) {\n            elementConsumables = new ViewElementConsumables(element);\n            this._consumables.set(element, elementConsumables);\n        } else {\n            elementConsumables = this._consumables.get(element);\n        }\n        elementConsumables.add(consumables);\n    }\n    /**\n\t * Tests if {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} can be consumed.\n\t * It returns `true` when all items included in method's call can be consumed. Returns `false` when\n\t * first already consumed item is found and `null` when first non-consumable item is found.\n\t *\n\t * ```ts\n\t * viewConsumable.test( p, { name: true } ); // Tests element's name.\n\t * viewConsumable.test( p, { attributes: 'name' } ); // Tests attribute.\n\t * viewConsumable.test( p, { classes: 'foobar' } ); // Tests class.\n\t * viewConsumable.test( p, { styles: 'color' } ); // Tests style.\n\t * viewConsumable.test( p, { attributes: 'name', styles: 'color' } ); // Tests attribute and style.\n\t * viewConsumable.test( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be tested.\n\t * viewConsumable.test( textNode ); // Tests text node.\n\t * viewConsumable.test( docFragment ); // Tests document fragment.\n\t * ```\n\t *\n\t * Testing classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t * ```ts\n\t * viewConsumable.test( p, { attributes: 'class' } ); // Tests if all added classes can be consumed.\n\t * viewConsumable.test( p, { attributes: 'style' } ); // Tests if all added styles can be consumed.\n\t * ```\n\t *\n\t * @param consumables Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param consumables.name If set to true element's name will be included.\n\t * @param consumables.attributes Attribute name or array of attribute names.\n\t * @param consumables.classes Class name or array of class names.\n\t * @param consumables.styles Style name or array of style names.\n\t * @returns Returns `true` when all items included in method's call can be consumed. Returns `false`\n\t * when first already consumed item is found and `null` when first non-consumable item is found.\n\t */ test(element, consumables) {\n        const elementConsumables = this._consumables.get(element);\n        if (elementConsumables === undefined) {\n            return null;\n        }\n        // For text nodes and document fragments return stored boolean value.\n        if (element.is('$text') || element.is('documentFragment')) {\n            return elementConsumables;\n        }\n        // For elements test consumables object.\n        return elementConsumables.test(consumables);\n    }\n    /**\n\t * Consumes {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t * It returns `true` when all items included in method's call can be consumed, otherwise returns `false`.\n\t *\n\t * ```ts\n\t * viewConsumable.consume( p, { name: true } ); // Consumes element's name.\n\t * viewConsumable.consume( p, { attributes: 'name' } ); // Consumes element's attribute.\n\t * viewConsumable.consume( p, { classes: 'foobar' } ); // Consumes element's class.\n\t * viewConsumable.consume( p, { styles: 'color' } ); // Consumes element's style.\n\t * viewConsumable.consume( p, { attributes: 'name', styles: 'color' } ); // Consumes attribute and style.\n\t * viewConsumable.consume( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be consumed.\n\t * viewConsumable.consume( textNode ); // Consumes text node.\n\t * viewConsumable.consume( docFragment ); // Consumes document fragment.\n\t * ```\n\t *\n\t * Consuming classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t * ```ts\n\t * viewConsumable.consume( p, { attributes: 'class' } ); // Consume only if all added classes can be consumed.\n\t * viewConsumable.consume( p, { attributes: 'style' } ); // Consume only if all added styles can be consumed.\n\t * ```\n\t *\n\t * @param consumables Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param consumables.name If set to true element's name will be included.\n\t * @param consumables.attributes Attribute name or array of attribute names.\n\t * @param consumables.classes Class name or array of class names.\n\t * @param consumables.styles Style name or array of style names.\n\t * @returns Returns `true` when all items included in method's call can be consumed,\n\t * otherwise returns `false`.\n\t */ consume(element, consumables) {\n        if (this.test(element, consumables)) {\n            if (element.is('$text') || element.is('documentFragment')) {\n                // For text nodes and document fragments set value to false.\n                this._consumables.set(element, false);\n            } else {\n                // For elements - consume consumables object.\n                this._consumables.get(element).consume(consumables);\n            }\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Reverts {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} so they can be consumed once again.\n\t * Method does not revert items that were never previously added for consumption, even if they are included in\n\t * method's call.\n\t *\n\t * ```ts\n\t * viewConsumable.revert( p, { name: true } ); // Reverts element's name.\n\t * viewConsumable.revert( p, { attributes: 'name' } ); // Reverts element's attribute.\n\t * viewConsumable.revert( p, { classes: 'foobar' } ); // Reverts element's class.\n\t * viewConsumable.revert( p, { styles: 'color' } ); // Reverts element's style.\n\t * viewConsumable.revert( p, { attributes: 'name', styles: 'color' } ); // Reverts attribute and style.\n\t * viewConsumable.revert( p, { classes: [ 'baz', 'bar' ] } ); // Multiple names can be reverted.\n\t * viewConsumable.revert( textNode ); // Reverts text node.\n\t * viewConsumable.revert( docFragment ); // Reverts document fragment.\n\t * ```\n\t *\n\t * Reverting classes and styles as attribute will revert all classes/styles that were previously added for\n\t * consumption.\n\t *\n\t * ```ts\n\t * viewConsumable.revert( p, { attributes: 'class' } ); // Reverts all classes added for consumption.\n\t * viewConsumable.revert( p, { attributes: 'style' } ); // Reverts all styles added for consumption.\n\t * ```\n\t *\n\t * @param consumables Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param consumables.name If set to true element's name will be included.\n\t * @param consumables.attributes Attribute name or array of attribute names.\n\t * @param consumables.classes Class name or array of class names.\n\t * @param consumables.styles Style name or array of style names.\n\t */ revert(element, consumables) {\n        const elementConsumables = this._consumables.get(element);\n        if (elementConsumables !== undefined) {\n            if (element.is('$text') || element.is('documentFragment')) {\n                // For text nodes and document fragments - set consumable to true.\n                this._consumables.set(element, true);\n            } else {\n                // For elements - revert items from consumables object.\n                elementConsumables.revert(consumables);\n            }\n        }\n    }\n    /**\n\t * Creates consumable object from {@link module:engine/view/element~Element view element}. Consumable object will include\n\t * element's name and all its attributes, classes and styles.\n\t */ static consumablesFromElement(element) {\n        const consumables = {\n            element,\n            name: true,\n            attributes: [],\n            classes: [],\n            styles: []\n        };\n        const attributes = element.getAttributeKeys();\n        for (const attribute of attributes){\n            // Skip classes and styles - will be added separately.\n            if (attribute == 'style' || attribute == 'class') {\n                continue;\n            }\n            consumables.attributes.push(attribute);\n        }\n        const classes = element.getClassNames();\n        for (const className of classes){\n            consumables.classes.push(className);\n        }\n        const styles = element.getStyleNames();\n        for (const style of styles){\n            consumables.styles.push(style);\n        }\n        return consumables;\n    }\n    /**\n\t * Creates {@link module:engine/conversion/viewconsumable~ViewConsumable ViewConsumable} instance from\n\t * {@link module:engine/view/node~Node node} or {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t * Instance will contain all elements, child nodes, attributes, styles and classes added for consumption.\n\t *\n\t * @param from View node or document fragment from which `ViewConsumable` will be created.\n\t * @param instance If provided, given `ViewConsumable` instance will be used\n\t * to add all consumables. It will be returned instead of a new instance.\n\t */ static createFrom(from, instance) {\n        if (!instance) {\n            instance = new ViewConsumable();\n        }\n        if (from.is('$text')) {\n            instance.add(from);\n            return instance;\n        }\n        // Add `from` itself, if it is an element.\n        if (from.is('element')) {\n            instance.add(from, ViewConsumable.consumablesFromElement(from));\n        }\n        if (from.is('documentFragment')) {\n            instance.add(from);\n        }\n        for (const child of from.getChildren()){\n            instance = ViewConsumable.createFrom(child, instance);\n        }\n        return instance;\n    }\n}\nconst CONSUMABLE_TYPES = [\n    'attributes',\n    'classes',\n    'styles'\n];\n/**\n * This is a private helper-class for {@link module:engine/conversion/viewconsumable~ViewConsumable}.\n * It represents and manipulates consumable parts of a single {@link module:engine/view/element~Element}.\n */ class ViewElementConsumables {\n    element;\n    /**\n\t * Flag indicating if name of the element can be consumed.\n\t */ _canConsumeName;\n    /**\n\t * Contains maps of element's consumables: attributes, classes and styles.\n\t */ _consumables;\n    /**\n\t * Creates ViewElementConsumables instance.\n\t *\n\t * @param from View node or document fragment from which `ViewElementConsumables` is being created.\n\t */ constructor(from){\n        this.element = from;\n        this._canConsumeName = null;\n        this._consumables = {\n            attributes: new Map(),\n            styles: new Map(),\n            classes: new Map()\n        };\n    }\n    /**\n\t * Adds consumable parts of the {@link module:engine/view/element~Element view element}.\n\t * Element's name itself can be marked to be consumed (when element's name is consumed its attributes, classes and\n\t * styles still could be consumed):\n\t *\n\t * ```ts\n\t * consumables.add( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.add( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.add( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * attribute is provided - it should be handled separately by providing `style` and `class` in consumables object.\n\t *\n\t * @param consumables Object describing which parts of the element can be consumed.\n\t * @param consumables.name If set to `true` element's name will be added as consumable.\n\t * @param consumables.attributes Attribute name or array of attribute names to add as consumable.\n\t * @param consumables.classes Class name or array of class names to add as consumable.\n\t * @param consumables.styles Style name or array of style names to add as consumable.\n\t */ add(consumables) {\n        if (consumables.name) {\n            this._canConsumeName = true;\n        }\n        for (const type of CONSUMABLE_TYPES){\n            if (type in consumables) {\n                this._add(type, consumables[type]);\n            }\n        }\n    }\n    /**\n\t * Tests if parts of the {@link module:engine/view/node~Node view node} can be consumed.\n\t *\n\t * Element's name can be tested:\n\t *\n\t * ```ts\n\t * consumables.test( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.test( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.test( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * @param consumables Object describing which parts of the element should be tested.\n\t * @param consumables.name If set to `true` element's name will be tested.\n\t * @param consumables.attributes Attribute name or array of attribute names to test.\n\t * @param consumables.classes Class name or array of class names to test.\n\t * @param consumables.styles Style name or array of style names to test.\n\t * @returns `true` when all tested items can be consumed, `null` when even one of the items\n\t * was never marked for consumption and `false` when even one of the items was already consumed.\n\t */ test(consumables) {\n        // Check if name can be consumed.\n        if (consumables.name && !this._canConsumeName) {\n            return this._canConsumeName;\n        }\n        for (const type of CONSUMABLE_TYPES){\n            if (type in consumables) {\n                const value = this._test(type, consumables[type]);\n                if (value !== true) {\n                    return value;\n                }\n            }\n        }\n        // Return true only if all can be consumed.\n        return true;\n    }\n    /**\n\t * Consumes parts of {@link module:engine/view/element~Element view element}. This function does not check if consumable item\n\t * is already consumed - it consumes all consumable items provided.\n\t * Element's name can be consumed:\n\t *\n\t * ```ts\n\t * consumables.consume( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.consume( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.consume( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * @param consumables Object describing which parts of the element should be consumed.\n\t * @param consumables.name If set to `true` element's name will be consumed.\n\t * @param consumables.attributes Attribute name or array of attribute names to consume.\n\t * @param consumables.classes Class name or array of class names to consume.\n\t * @param consumables.styles Style name or array of style names to consume.\n\t */ consume(consumables) {\n        if (consumables.name) {\n            this._canConsumeName = false;\n        }\n        for (const type of CONSUMABLE_TYPES){\n            if (type in consumables) {\n                this._consume(type, consumables[type]);\n            }\n        }\n    }\n    /**\n\t * Revert already consumed parts of {@link module:engine/view/element~Element view Element}, so they can be consumed once again.\n\t * Element's name can be reverted:\n\t *\n\t * ```ts\n\t * consumables.revert( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.revert( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.revert( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * @param consumables Object describing which parts of the element should be reverted.\n\t * @param consumables.name If set to `true` element's name will be reverted.\n\t * @param consumables.attributes Attribute name or array of attribute names to revert.\n\t * @param consumables.classes Class name or array of class names to revert.\n\t * @param consumables.styles Style name or array of style names to revert.\n\t */ revert(consumables) {\n        if (consumables.name) {\n            this._canConsumeName = true;\n        }\n        for (const type of CONSUMABLE_TYPES){\n            if (type in consumables) {\n                this._revert(type, consumables[type]);\n            }\n        }\n    }\n    /**\n\t * Helper method that adds consumables of a given type: attribute, class or style.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * type is provided - it should be handled separately by providing actual style/class type.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param item Consumable item or array of items.\n\t */ _add(type, item) {\n        const items = toArray(item);\n        const consumables = this._consumables[type];\n        for (const name of items){\n            if (type === 'attributes' && (name === 'class' || name === 'style')) {\n                /**\n\t\t\t\t * Class and style attributes should be handled separately in\n\t\t\t\t * {@link module:engine/conversion/viewconsumable~ViewConsumable#add `ViewConsumable#add()`}.\n\t\t\t\t *\n\t\t\t\t * What you have done is trying to use:\n\t\t\t\t *\n\t\t\t\t * ```ts\n\t\t\t\t * consumables.add( { attributes: [ 'class', 'style' ] } );\n\t\t\t\t * ```\n\t\t\t\t *\n\t\t\t\t * While each class and style should be registered separately:\n\t\t\t\t *\n\t\t\t\t * ```ts\n\t\t\t\t * consumables.add( { classes: 'some-class', styles: 'font-weight' } );\n\t\t\t\t * ```\n\t\t\t\t *\n\t\t\t\t * @error viewconsumable-invalid-attribute\n\t\t\t\t */ throw new CKEditorError('viewconsumable-invalid-attribute', this);\n            }\n            consumables.set(name, true);\n            if (type === 'styles') {\n                for (const alsoName of this.element.document.stylesProcessor.getRelatedStyles(name)){\n                    consumables.set(alsoName, true);\n                }\n            }\n        }\n    }\n    /**\n\t * Helper method that tests consumables of a given type: attribute, class or style.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param item Consumable item or array of items.\n\t * @returns Returns `true` if all items can be consumed, `null` when one of the items cannot be\n\t * consumed and `false` when one of the items is already consumed.\n\t */ _test(type, item) {\n        const items = toArray(item);\n        const consumables = this._consumables[type];\n        for (const name of items){\n            if (type === 'attributes' && (name === 'class' || name === 'style')) {\n                const consumableName = name == 'class' ? 'classes' : 'styles';\n                // Check all classes/styles if class/style attribute is tested.\n                const value = this._test(consumableName, [\n                    ...this._consumables[consumableName].keys()\n                ]);\n                if (value !== true) {\n                    return value;\n                }\n            } else {\n                const value = consumables.get(name);\n                // Return null if attribute is not found.\n                if (value === undefined) {\n                    return null;\n                }\n                if (!value) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n    /**\n\t * Helper method that consumes items of a given type: attribute, class or style.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param item Consumable item or array of items.\n\t */ _consume(type, item) {\n        const items = toArray(item);\n        const consumables = this._consumables[type];\n        for (const name of items){\n            if (type === 'attributes' && (name === 'class' || name === 'style')) {\n                const consumableName = name == 'class' ? 'classes' : 'styles';\n                // If class or style is provided for consumption - consume them all.\n                this._consume(consumableName, [\n                    ...this._consumables[consumableName].keys()\n                ]);\n            } else {\n                consumables.set(name, false);\n                if (type == 'styles') {\n                    for (const toConsume of this.element.document.stylesProcessor.getRelatedStyles(name)){\n                        consumables.set(toConsume, false);\n                    }\n                }\n            }\n        }\n    }\n    /**\n\t * Helper method that reverts items of a given type: attribute, class or style.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or , `styles`.\n\t * @param item Consumable item or array of items.\n\t */ _revert(type, item) {\n        const items = toArray(item);\n        const consumables = this._consumables[type];\n        for (const name of items){\n            if (type === 'attributes' && (name === 'class' || name === 'style')) {\n                const consumableName = name == 'class' ? 'classes' : 'styles';\n                // If class or style is provided for reverting - revert them all.\n                this._revert(consumableName, [\n                    ...this._consumables[consumableName].keys()\n                ]);\n            } else {\n                const value = consumables.get(name);\n                if (value === false) {\n                    consumables.set(name, true);\n                }\n            }\n        }\n    }\n}\n\n/**\n * The model's schema. It defines the allowed and disallowed structures of nodes as well as nodes' attributes.\n * The schema is usually defined by the features and based on them, the editing framework and features\n * make decisions on how to change and process the model.\n *\n * The instance of schema is available in {@link module:engine/model/model~Model#schema `editor.model.schema`}.\n *\n * Read more about the schema in:\n *\n * * The {@glink framework/architecture/editing-engine#schema schema section} of the\n * {@glink framework/architecture/editing-engine Introduction to the Editing engine architecture} guide.\n * * The {@glink framework/deep-dive/schema Schema deep-dive} guide.\n */ class Schema extends /* #__PURE__ */ ObservableMixin() {\n    _sourceDefinitions = {};\n    /**\n\t * A dictionary containing attribute properties.\n\t */ _attributeProperties = Object.create(null);\n    /**\n\t * Stores additional callbacks registered for schema items, which are evaluated when {@link ~Schema#checkChild} is called.\n\t *\n\t * Keys are schema item names for which the callbacks are registered. Values are arrays with the callbacks.\n\t *\n\t * Some checks are added under {@link ~Schema#_genericCheckSymbol} key, these are evaluated for every {@link ~Schema#checkChild} call.\n\t */ _customChildChecks = new Map();\n    /**\n\t * Stores additional callbacks registered for attribute names, which are evaluated when {@link ~Schema#checkAttribute} is called.\n\t *\n\t * Keys are schema attribute names for which the callbacks are registered. Values are arrays with the callbacks.\n\t *\n\t * Some checks are added under {@link ~Schema#_genericCheckSymbol} key, these are evaluated for every\n\t * {@link ~Schema#checkAttribute} call.\n\t */ _customAttributeChecks = new Map();\n    _genericCheckSymbol = Symbol('$generic');\n    _compiledDefinitions;\n    /**\n\t * Creates a schema instance.\n\t */ constructor(){\n        super();\n        this.decorate('checkChild');\n        this.decorate('checkAttribute');\n        this.on('checkAttribute', (evt, args)=>{\n            args[0] = new SchemaContext(args[0]);\n        }, {\n            priority: 'highest'\n        });\n        this.on('checkChild', (evt, args)=>{\n            args[0] = new SchemaContext(args[0]);\n            args[1] = this.getDefinition(args[1]);\n        }, {\n            priority: 'highest'\n        });\n    }\n    /**\n\t * Registers a schema item. Can only be called once for every item name.\n\t *\n\t * ```ts\n\t * schema.register( 'paragraph', {\n\t * \tinheritAllFrom: '$block'\n\t * } );\n\t * ```\n\t */ register(itemName, definition) {\n        if (this._sourceDefinitions[itemName]) {\n            /**\n\t\t\t * A single item cannot be registered twice in the schema.\n\t\t\t *\n\t\t\t * This situation may happen when:\n\t\t\t *\n\t\t\t * * Two or more plugins called {@link module:engine/model/schema~Schema#register `register()`} with the same name.\n\t\t\t * This will usually mean that there is a collision between plugins which try to use the same element in the model.\n\t\t\t * Unfortunately, the only way to solve this is by modifying one of these plugins to use a unique model element name.\n\t\t\t * * A single plugin was loaded twice. This happens when it is installed by npm/yarn in two versions\n\t\t\t * and usually means one or more of the following issues:\n\t\t\t *     * a version mismatch (two of your dependencies require two different versions of this plugin),\n\t\t\t *     * incorrect imports (this plugin is somehow imported twice in a way which confuses webpack),\n\t\t\t *     * mess in `node_modules/` (`rm -rf node_modules/` may help).\n\t\t\t *\n\t\t\t * **Note:** Check the logged `itemName` to better understand which plugin was duplicated/conflicting.\n\t\t\t *\n\t\t\t * @param itemName The name of the model element that is being registered twice.\n\t\t\t * @error schema-cannot-register-item-twice\n\t\t\t */ throw new CKEditorError('schema-cannot-register-item-twice', this, {\n                itemName\n            });\n        }\n        this._sourceDefinitions[itemName] = [\n            Object.assign({}, definition)\n        ];\n        this._clearCache();\n    }\n    /**\n\t * Extends a {@link #register registered} item's definition.\n\t *\n\t * Extending properties such as `allowIn` will add more items to the existing properties,\n\t * while redefining properties such as `isBlock` will override the previously defined ones.\n\t *\n\t * ```ts\n\t * schema.register( 'foo', {\n\t * \tallowIn: '$root',\n\t * \tisBlock: true;\n\t * } );\n\t * schema.extend( 'foo', {\n\t * \tallowIn: 'blockQuote',\n\t * \tisBlock: false\n\t * } );\n\t *\n\t * schema.getDefinition( 'foo' );\n\t * //\t{\n\t * //\t\tallowIn: [ '$root', 'blockQuote' ],\n\t * // \t\tisBlock: false\n\t * //\t}\n\t * ```\n\t */ extend(itemName, definition) {\n        if (!this._sourceDefinitions[itemName]) {\n            /**\n\t\t\t * Cannot extend an item which was not registered yet.\n\t\t\t *\n\t\t\t * This error happens when a plugin tries to extend the schema definition of an item which was not\n\t\t\t * {@link module:engine/model/schema~Schema#register registered} yet.\n\t\t\t *\n\t\t\t * @param itemName The name of the model element which is being extended.\n\t\t\t * @error schema-cannot-extend-missing-item\n\t\t\t */ throw new CKEditorError('schema-cannot-extend-missing-item', this, {\n                itemName\n            });\n        }\n        this._sourceDefinitions[itemName].push(Object.assign({}, definition));\n        this._clearCache();\n    }\n    /**\n\t * Returns data of all registered items.\n\t *\n\t * This method should normally be used for reflection purposes (e.g. defining a clone of a certain element,\n\t * checking a list of all block elements, etc).\n\t * Use specific methods (such as {@link #checkChild `checkChild()`} or {@link #isLimit `isLimit()`})\n\t * in other cases.\n\t */ getDefinitions() {\n        if (!this._compiledDefinitions) {\n            this._compile();\n        }\n        return this._compiledDefinitions;\n    }\n    /**\n\t * Returns a definition of the given item or `undefined` if an item is not registered.\n\t *\n\t * This method should normally be used for reflection purposes (e.g. defining a clone of a certain element,\n\t * checking a list of all block elements, etc).\n\t * Use specific methods (such as {@link #checkChild `checkChild()`} or {@link #isLimit `isLimit()`})\n\t * in other cases.\n\t */ getDefinition(item) {\n        let itemName;\n        if (typeof item == 'string') {\n            itemName = item;\n        } else if ('is' in item && (item.is('$text') || item.is('$textProxy'))) {\n            itemName = '$text';\n        } else {\n            itemName = item.name;\n        }\n        return this.getDefinitions()[itemName];\n    }\n    /**\n\t * Returns `true` if the given item is registered in the schema.\n\t *\n\t * ```ts\n\t * schema.isRegistered( 'paragraph' ); // -> true\n\t * schema.isRegistered( editor.model.document.getRoot() ); // -> true\n\t * schema.isRegistered( 'foo' ); // -> false\n\t * ```\n\t */ isRegistered(item) {\n        return !!this.getDefinition(item);\n    }\n    /**\n\t * Returns `true` if the given item is defined to be\n\t * a block by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isBlock` property.\n\t *\n\t * ```ts\n\t * schema.isBlock( 'paragraph' ); // -> true\n\t * schema.isBlock( '$root' ); // -> false\n\t *\n\t * const paragraphElement = writer.createElement( 'paragraph' );\n\t * schema.isBlock( paragraphElement ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#block-elements Block elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */ isBlock(item) {\n        const def = this.getDefinition(item);\n        return !!(def && def.isBlock);\n    }\n    /**\n\t * Returns `true` if the given item should be treated as a limit element.\n\t *\n\t * It considers an item to be a limit element if its\n\t * {@link module:engine/model/schema~SchemaItemDefinition}'s\n\t * {@link module:engine/model/schema~SchemaItemDefinition#isLimit `isLimit`} or\n\t * {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} property\n\t * was set to `true`.\n\t *\n\t * ```ts\n\t * schema.isLimit( 'paragraph' ); // -> false\n\t * schema.isLimit( '$root' ); // -> true\n\t * schema.isLimit( editor.model.document.getRoot() ); // -> true\n\t * schema.isLimit( 'imageBlock' ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#limit-elements Limit elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */ isLimit(item) {\n        const def = this.getDefinition(item);\n        if (!def) {\n            return false;\n        }\n        return !!(def.isLimit || def.isObject);\n    }\n    /**\n\t * Returns `true` if the given item should be treated as an object element.\n\t *\n\t * It considers an item to be an object element if its\n\t * {@link module:engine/model/schema~SchemaItemDefinition}'s\n\t * {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} property\n\t * was set to `true`.\n\t *\n\t * ```ts\n\t * schema.isObject( 'paragraph' ); // -> false\n\t * schema.isObject( 'imageBlock' ); // -> true\n\t *\n\t * const imageElement = writer.createElement( 'imageBlock' );\n\t * schema.isObject( imageElement ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#object-elements Object elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */ isObject(item) {\n        const def = this.getDefinition(item);\n        if (!def) {\n            return false;\n        }\n        // Note: Check out the implementation of #isLimit(), #isSelectable(), and #isContent()\n        // to understand why these three constitute an object.\n        return !!(def.isObject || def.isLimit && def.isSelectable && def.isContent);\n    }\n    /**\n\t * Returns `true` if the given item is defined to be\n\t * an inline element by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isInline` property.\n\t *\n\t * ```ts\n\t * schema.isInline( 'paragraph' ); // -> false\n\t * schema.isInline( 'softBreak' ); // -> true\n\t *\n\t * const text = writer.createText( 'foo' );\n\t * schema.isInline( text ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#inline-elements Inline elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */ isInline(item) {\n        const def = this.getDefinition(item);\n        return !!(def && def.isInline);\n    }\n    /**\n\t * Returns `true` if the given item is defined to be\n\t * a selectable element by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isSelectable` property.\n\t *\n\t * ```ts\n\t * schema.isSelectable( 'paragraph' ); // -> false\n\t * schema.isSelectable( 'heading1' ); // -> false\n\t * schema.isSelectable( 'imageBlock' ); // -> true\n\t * schema.isSelectable( 'tableCell' ); // -> true\n\t *\n\t * const text = writer.createText( 'foo' );\n\t * schema.isSelectable( text ); // -> false\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#selectable-elements Selectable elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */ isSelectable(item) {\n        const def = this.getDefinition(item);\n        if (!def) {\n            return false;\n        }\n        return !!(def.isSelectable || def.isObject);\n    }\n    /**\n\t * Returns `true` if the given item is defined to be\n\t * a content by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isContent` property.\n\t *\n\t * ```ts\n\t * schema.isContent( 'paragraph' ); // -> false\n\t * schema.isContent( 'heading1' ); // -> false\n\t * schema.isContent( 'imageBlock' ); // -> true\n\t * schema.isContent( 'horizontalLine' ); // -> true\n\t *\n\t * const text = writer.createText( 'foo' );\n\t * schema.isContent( text ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#content-elements Content elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */ isContent(item) {\n        const def = this.getDefinition(item);\n        if (!def) {\n            return false;\n        }\n        return !!(def.isContent || def.isObject);\n    }\n    /**\n\t * Checks whether the given node can be a child of the given context.\n\t *\n\t * ```ts\n\t * schema.checkChild( model.document.getRoot(), paragraph ); // -> false\n\t *\n\t * schema.register( 'paragraph', {\n\t * \tallowIn: '$root'\n\t * } );\n\t *\n\t * schema.checkChild( model.document.getRoot(), paragraph ); // -> true\n\t * ```\n\t *\n\t * Both {@link module:engine/model/schema~Schema#addChildCheck callback checks} and declarative rules (added when\n\t * {@link module:engine/model/schema~Schema#register registering} and {@link module:engine/model/schema~Schema#extend extending} items)\n\t * are evaluated when this method is called.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * Note that when verifying whether the given node can be a child of the given context, the schema also verifies the entire\n\t * context &ndash; from its root to its last element. Therefore, it is possible for `checkChild()` to return `false` even though\n\t * the `context` last element can contain the checked child. It happens if one of the `context` elements does not allow its child.\n\t * When `context` is verified, {@link module:engine/model/schema~Schema#addChildCheck custom checks} are considered as well.\n\t *\n\t * @fires checkChild\n\t * @param context The context in which the child will be checked.\n\t * @param def The child to check.\n\t */ checkChild(context, def) {\n        // Note: `context` and `def` are already normalized here to `SchemaContext` and `SchemaCompiledItemDefinition`.\n        if (!def) {\n            return false;\n        }\n        return this._checkContextMatch(context, def);\n    }\n    /**\n\t * Checks whether the given attribute can be applied in the given context (on the last item of the context).\n\t *\n\t * ```ts\n\t * schema.checkAttribute( textNode, 'bold' ); // -> false\n\t *\n\t * schema.extend( '$text', {\n\t * \tallowAttributes: 'bold'\n\t * } );\n\t *\n\t * schema.checkAttribute( textNode, 'bold' ); // -> true\n\t * ```\n\t *\n\t * Both {@link module:engine/model/schema~Schema#addAttributeCheck callback checks} and declarative rules (added when\n\t * {@link module:engine/model/schema~Schema#register registering} and {@link module:engine/model/schema~Schema#extend extending} items)\n\t * are evaluated when this method is called.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * @fires checkAttribute\n\t * @param context The context in which the attribute will be checked.\n\t * @param attributeName Name of attribute to check in the given context.\n\t */ checkAttribute(context, attributeName) {\n        // Note: `context` is already normalized here to `SchemaContext`.\n        const def = this.getDefinition(context.last);\n        if (!def) {\n            return false;\n        }\n        // First, check all attribute checks declared as callbacks.\n        // Note that `_evaluateAttributeChecks()` will return `undefined` if neither child check was applicable (no decision was made).\n        const isAllowed = this._evaluateAttributeChecks(context, attributeName);\n        // If the decision was not made inside attribute check callbacks, then use declarative rules.\n        return isAllowed !== undefined ? isAllowed : def.allowAttributes.includes(attributeName);\n    }\n    /**\n\t * Checks whether the given element (`elementToMerge`) can be merged with the specified base element (`positionOrBaseElement`).\n\t *\n\t * In other words &ndash; both elements are not a limit elements and whether `elementToMerge`'s children\n\t * {@link #checkChild are allowed} in the `positionOrBaseElement`.\n\t *\n\t * This check ensures that elements merged with {@link module:engine/model/writer~Writer#merge `Writer#merge()`}\n\t * will be valid.\n\t *\n\t * Instead of elements, you can pass the instance of the {@link module:engine/model/position~Position} class as the\n\t * `positionOrBaseElement`. It means that the elements before and after the position will be checked whether they can be merged.\n\t *\n\t * @param positionOrBaseElement The position or base element to which the `elementToMerge` will be merged.\n\t * @param elementToMerge The element to merge. Required if `positionOrBaseElement` is an element.\n\t */ checkMerge(positionOrBaseElement, elementToMerge) {\n        if (positionOrBaseElement instanceof Position) {\n            const nodeBefore = positionOrBaseElement.nodeBefore;\n            const nodeAfter = positionOrBaseElement.nodeAfter;\n            if (!(nodeBefore instanceof Element)) {\n                /**\n\t\t\t\t * The node before the merge position must be an element.\n\t\t\t\t *\n\t\t\t\t * @error schema-check-merge-no-element-before\n\t\t\t\t */ throw new CKEditorError('schema-check-merge-no-element-before', this);\n            }\n            if (!(nodeAfter instanceof Element)) {\n                /**\n\t\t\t\t * The node after the merge position must be an element.\n\t\t\t\t *\n\t\t\t\t * @error schema-check-merge-no-element-after\n\t\t\t\t */ throw new CKEditorError('schema-check-merge-no-element-after', this);\n            }\n            return this.checkMerge(nodeBefore, nodeAfter);\n        }\n        if (this.isLimit(positionOrBaseElement) || this.isLimit(elementToMerge)) {\n            return false;\n        }\n        for (const child of elementToMerge.getChildren()){\n            if (!this.checkChild(positionOrBaseElement, child)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Allows registering a callback to the {@link #checkChild} method calls.\n\t *\n\t * Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t * by using the declarative API of {@link module:engine/model/schema~SchemaItemDefinition}.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * For example, by using this method you can disallow elements in specific contexts:\n\t *\n\t * ```ts\n\t * // Disallow `heading1` inside a `blockQuote` that is inside a table.\n\t * schema.addChildCheck( ( context, childDefinition ) => {\n\t * \tif ( context.endsWith( 'tableCell blockQuote' ) ) {\n\t * \t\treturn false;\n\t * \t}\n\t * }, 'heading1' );\n\t * ```\n\t *\n\t * You can skip the optional `itemName` parameter to evaluate the callback for every `checkChild()` call.\n\t *\n\t * ```ts\n\t * // Inside specific custom element, allow only children, which allows for a specific attribute.\n\t * schema.addChildCheck( ( context, childDefinition ) => {\n\t * \tif ( context.endsWith( 'myElement' ) ) {\n\t * \t\treturn childDefinition.allowAttributes.includes( 'myAttribute' );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Please note that the generic callbacks may affect the editor performance and should be avoided if possible.\n\t *\n\t * When one of the callbacks makes a decision (returns `true` or `false`) the processing is finished and other callbacks are not fired.\n\t * Callbacks are fired in the order they were added, however generic callbacks are fired before callbacks added for a specified item.\n\t *\n\t * You can also use `checkChild` event, if you need even better control. The result from the example above could also be\n\t * achieved with following event callback:\n\t *\n\t * ```ts\n\t * schema.on( 'checkChild', ( evt, args ) => {\n\t * \tconst context = args[ 0 ];\n\t * \tconst childDefinition = args[ 1 ];\n\t *\n\t * \tif ( context.endsWith( 'myElement' ) ) {\n\t * \t\t// Prevent next listeners from being called.\n\t * \t\tevt.stop();\n\t * \t\t// Set the `checkChild()` return value.\n\t * \t\tevt.return = childDefinition.allowAttributes.includes( 'myAttribute' );\n\t * \t}\n\t * }, { priority: 'high' } );\n\t * ```\n\t *\n\t * Note that the callback checks and declarative rules checks are processed on `normal` priority.\n\t *\n\t * Adding callbacks this way can also negatively impact editor performance.\n\t *\n\t * @param callback The callback to be called. It is called with two parameters:\n\t * {@link module:engine/model/schema~SchemaContext} (context) instance and\n\t * {@link module:engine/model/schema~SchemaCompiledItemDefinition} (definition). The callback may return `true/false` to override\n\t * `checkChild()`'s return value. If it does not return a boolean value, the default algorithm (or other callbacks) will define\n\t * `checkChild()`'s return value.\n\t * @param itemName Name of the schema item for which the callback is registered. If specified, the callback will be run only for\n\t * `checkChild()` calls which `def` parameter matches the `itemName`. Otherwise, the callback will run for every `checkChild` call.\n\t */ addChildCheck(callback, itemName) {\n        const key = itemName !== undefined ? itemName : this._genericCheckSymbol;\n        const checks = this._customChildChecks.get(key) || [];\n        checks.push(callback);\n        this._customChildChecks.set(key, checks);\n    }\n    /**\n\t * Allows registering a callback to the {@link #checkAttribute} method calls.\n\t *\n\t * Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t * by using the declarative API of {@link module:engine/model/schema~SchemaItemDefinition}.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * For example, by using this method you can disallow setting attributes on nodes in specific contexts:\n\t *\n\t * ```ts\n\t * // Disallow setting `bold` on text inside `heading1` element:\n\t * schema.addAttributeCheck( context => {\n\t * \tif ( context.endsWith( 'heading1 $text' ) ) {\n\t * \t\treturn false;\n\t * \t}\n\t * }, 'bold' );\n\t * ```\n\t *\n\t * You can skip the optional `attributeName` parameter to evaluate the callback for every `checkAttribute()` call.\n\t *\n\t * ```ts\n\t * // Disallow formatting attributes on text inside custom `myTitle` element:\n\t * schema.addAttributeCheck( ( context, attributeName ) => {\n\t * \tif ( context.endsWith( 'myTitle $text' ) && schema.getAttributeProperties( attributeName ).isFormatting ) {\n\t * \t\treturn false;\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Please note that the generic callbacks may affect the editor performance and should be avoided if possible.\n\t *\n\t * When one of the callbacks makes a decision (returns `true` or `false`) the processing is finished and other callbacks are not fired.\n\t * Callbacks are fired in the order they were added, however generic callbacks are fired before callbacks added for a specified item.\n\t *\n\t * You can also use {@link #event:checkAttribute} event, if you need even better control. The result from the example above could also\n\t * be achieved with following event callback:\n\t *\n\t * ```ts\n\t * schema.on( 'checkAttribute', ( evt, args ) => {\n\t * \tconst context = args[ 0 ];\n\t * \tconst attributeName = args[ 1 ];\n\t *\n\t * \tif ( context.endsWith( 'myTitle $text' ) && schema.getAttributeProperties( attributeName ).isFormatting ) {\n\t * \t\t// Prevent next listeners from being called.\n\t * \t\tevt.stop();\n\t * \t\t// Set the `checkAttribute()` return value.\n\t * \t\tevt.return = false;\n\t * \t}\n\t * }, { priority: 'high' } );\n\t * ```\n\t *\n\t * Note that the callback checks and declarative rules checks are processed on `normal` priority.\n\t *\n\t * Adding callbacks this way can also negatively impact editor performance.\n\t *\n\t * @param callback The callback to be called. It is called with two parameters:\n\t * {@link module:engine/model/schema~SchemaContext `context`} and attribute name. The callback may return `true` or `false`, to\n\t * override `checkAttribute()`'s return value. If it does not return a boolean value, the default algorithm (or other callbacks)\n\t * will define `checkAttribute()`'s return value.\n\t * @param attributeName Name of the attribute for which the callback is registered. If specified, the callback will be run only for\n\t * `checkAttribute()` calls with matching `attributeName`. Otherwise, the callback will run for every `checkAttribute()` call.\n\t */ addAttributeCheck(callback, attributeName) {\n        const key = attributeName !== undefined ? attributeName : this._genericCheckSymbol;\n        const checks = this._customAttributeChecks.get(key) || [];\n        checks.push(callback);\n        this._customAttributeChecks.set(key, checks);\n    }\n    /**\n\t * This method allows assigning additional metadata to the model attributes. For example,\n\t * {@link module:engine/model/schema~AttributeProperties `AttributeProperties#isFormatting` property} is\n\t * used to mark formatting attributes (like `bold` or `italic`).\n\t *\n\t * ```ts\n\t * // Mark bold as a formatting attribute.\n\t * schema.setAttributeProperties( 'bold', {\n\t * \tisFormatting: true\n\t * } );\n\t *\n\t * // Override code not to be considered a formatting markup.\n\t * schema.setAttributeProperties( 'code', {\n\t * \tisFormatting: false\n\t * } );\n\t * ```\n\t *\n\t * Properties are not limited to members defined in the\n\t * {@link module:engine/model/schema~AttributeProperties `AttributeProperties` type} and you can also use custom properties:\n\t *\n\t * ```ts\n\t * schema.setAttributeProperties( 'blockQuote', {\n\t * \tcustomProperty: 'value'\n\t * } );\n\t * ```\n\t *\n\t * Subsequent calls with the same attribute will extend its custom properties:\n\t *\n\t * ```ts\n\t * schema.setAttributeProperties( 'blockQuote', {\n\t * \tone: 1\n\t * } );\n\t *\n\t * schema.setAttributeProperties( 'blockQuote', {\n\t * \ttwo: 2\n\t * } );\n\t *\n\t * console.log( schema.getAttributeProperties( 'blockQuote' ) );\n\t * // Logs: { one: 1, two: 2 }\n\t * ```\n\t *\n\t * @param attributeName A name of the attribute to receive the properties.\n\t * @param properties A dictionary of properties.\n\t */ setAttributeProperties(attributeName, properties) {\n        this._attributeProperties[attributeName] = Object.assign(this.getAttributeProperties(attributeName), properties);\n    }\n    /**\n\t * Returns properties associated with a given model attribute. See {@link #setAttributeProperties `setAttributeProperties()`}.\n\t *\n\t * @param attributeName A name of the attribute.\n\t */ getAttributeProperties(attributeName) {\n        return this._attributeProperties[attributeName] || Object.create(null);\n    }\n    /**\n\t * Returns the lowest {@link module:engine/model/schema~Schema#isLimit limit element} containing the entire\n\t * selection/range/position or the root otherwise.\n\t *\n\t * @param selectionOrRangeOrPosition The selection/range/position to check.\n\t * @returns The lowest limit element containing the entire `selectionOrRangeOrPosition`.\n\t */ getLimitElement(selectionOrRangeOrPosition) {\n        let element;\n        if (selectionOrRangeOrPosition instanceof Position) {\n            element = selectionOrRangeOrPosition.parent;\n        } else {\n            const ranges = selectionOrRangeOrPosition instanceof Range ? [\n                selectionOrRangeOrPosition\n            ] : Array.from(selectionOrRangeOrPosition.getRanges());\n            // Find the common ancestor for all selection's ranges.\n            element = ranges.reduce((element, range)=>{\n                const rangeCommonAncestor = range.getCommonAncestor();\n                if (!element) {\n                    return rangeCommonAncestor;\n                }\n                return element.getCommonAncestor(rangeCommonAncestor, {\n                    includeSelf: true\n                });\n            }, null);\n        }\n        while(!this.isLimit(element)){\n            if (element.parent) {\n                element = element.parent;\n            } else {\n                break;\n            }\n        }\n        return element;\n    }\n    /**\n\t * Checks whether the attribute is allowed in selection:\n\t *\n\t * * if the selection is not collapsed, then checks if the attribute is allowed on any of nodes in that range,\n\t * * if the selection is collapsed, then checks if on the selection position there's a text with the\n\t * specified attribute allowed.\n\t *\n\t * @param selection Selection which will be checked.\n\t * @param attribute The name of the attribute to check.\n\t */ checkAttributeInSelection(selection, attribute) {\n        if (selection.isCollapsed) {\n            const firstPosition = selection.getFirstPosition();\n            const context = [\n                ...firstPosition.getAncestors(),\n                new Text('', selection.getAttributes())\n            ];\n            // Check whether schema allows for a text with the attribute in the selection.\n            return this.checkAttribute(context, attribute);\n        } else {\n            const ranges = selection.getRanges();\n            // For all ranges, check nodes in them until you find a node that is allowed to have the attribute.\n            for (const range of ranges){\n                for (const value of range){\n                    if (this.checkAttribute(value.item, attribute)) {\n                        // If we found a node that is allowed to have the attribute, return true.\n                        return true;\n                    }\n                }\n            }\n        }\n        // If we haven't found such node, return false.\n        return false;\n    }\n    /**\n\t * Transforms the given set of ranges into a set of ranges where the given attribute is allowed (and can be applied).\n\t *\n\t * @param ranges Ranges to be validated.\n\t * @param attribute The name of the attribute to check.\n\t * @returns Ranges in which the attribute is allowed.\n\t */ *getValidRanges(ranges, attribute) {\n        ranges = convertToMinimalFlatRanges(ranges);\n        for (const range of ranges){\n            yield* this._getValidRangesForRange(range, attribute);\n        }\n    }\n    /**\n\t * Basing on given `position`, finds and returns a {@link module:engine/model/range~Range range} which is\n\t * nearest to that `position` and is a correct range for selection.\n\t *\n\t * The correct selection range might be collapsed when it is located in a position where the text node can be placed.\n\t * Non-collapsed range is returned when selection can be placed around element marked as an \"object\" in\n\t * the {@link module:engine/model/schema~Schema schema}.\n\t *\n\t * Direction of searching for the nearest correct selection range can be specified as:\n\t *\n\t * * `both` - searching will be performed in both ways,\n\t * * `forward` - searching will be performed only forward,\n\t * * `backward` - searching will be performed only backward.\n\t *\n\t * When valid selection range cannot be found, `null` is returned.\n\t *\n\t * @param position Reference position where new selection range should be looked for.\n\t * @param direction Search direction.\n\t * @returns Nearest selection range or `null` if one cannot be found.\n\t */ getNearestSelectionRange(position, direction = 'both') {\n        if (position.root.rootName == '$graveyard') {\n            // No valid selection range in the graveyard.\n            // This is important when getting the document selection default range.\n            return null;\n        }\n        // Return collapsed range if provided position is valid.\n        if (this.checkChild(position, '$text')) {\n            return new Range(position);\n        }\n        let backwardWalker, forwardWalker;\n        // Never leave a limit element.\n        const limitElement = position.getAncestors().reverse().find((item)=>this.isLimit(item)) || position.root;\n        if (direction == 'both' || direction == 'backward') {\n            backwardWalker = new TreeWalker({\n                boundaries: Range._createIn(limitElement),\n                startPosition: position,\n                direction: 'backward'\n            });\n        }\n        if (direction == 'both' || direction == 'forward') {\n            forwardWalker = new TreeWalker({\n                boundaries: Range._createIn(limitElement),\n                startPosition: position\n            });\n        }\n        for (const data of combineWalkers(backwardWalker, forwardWalker)){\n            const type = data.walker == backwardWalker ? 'elementEnd' : 'elementStart';\n            const value = data.value;\n            if (value.type == type && this.isObject(value.item)) {\n                return Range._createOn(value.item);\n            }\n            if (this.checkChild(value.nextPosition, '$text')) {\n                return new Range(value.nextPosition);\n            }\n        }\n        return null;\n    }\n    /**\n\t * Tries to find position ancestors that allow to insert a given node.\n\t * It starts searching from the given position and goes node by node to the top of the model tree\n\t * as long as a {@link module:engine/model/schema~Schema#isLimit limit element}, an\n\t * {@link module:engine/model/schema~Schema#isObject object element} or a topmost ancestor is not reached.\n\t *\n\t * @param position The position that the search will start from.\n\t * @param node The node for which an allowed parent should be found or its name.\n\t * @returns Allowed parent or null if nothing was found.\n\t */ findAllowedParent(position, node) {\n        let parent = position.parent;\n        while(parent){\n            if (this.checkChild(parent, node)) {\n                return parent;\n            }\n            // Do not split limit elements.\n            if (this.isLimit(parent)) {\n                return null;\n            }\n            parent = parent.parent;\n        }\n        return null;\n    }\n    /**\n\t * Sets attributes allowed by the schema on a given node.\n\t *\n\t * @param node A node to set attributes on.\n\t * @param attributes Attributes keys and values.\n\t * @param writer An instance of the model writer.\n\t */ setAllowedAttributes(node, attributes, writer) {\n        const model = writer.model;\n        for (const [attributeName, attributeValue] of Object.entries(attributes)){\n            if (model.schema.checkAttribute(node, attributeName)) {\n                writer.setAttribute(attributeName, attributeValue, node);\n            }\n        }\n    }\n    /**\n\t * Removes attributes disallowed by the schema.\n\t *\n\t * @param nodes Nodes that will be filtered.\n\t */ removeDisallowedAttributes(nodes, writer) {\n        for (const node of nodes){\n            // When node is a `Text` it has no children, so just filter it out.\n            if (node.is('$text')) {\n                removeDisallowedAttributeFromNode(this, node, writer);\n            } else {\n                const rangeInNode = Range._createIn(node);\n                const positionsInRange = rangeInNode.getPositions();\n                for (const position of positionsInRange){\n                    const item = position.nodeBefore || position.parent;\n                    removeDisallowedAttributeFromNode(this, item, writer);\n                }\n            }\n        }\n    }\n    /**\n\t * Gets attributes of a node that have a given property.\n\t *\n\t * @param node Node to get attributes from.\n\t * @param propertyName Name of the property that attribute must have to return it.\n\t * @param propertyValue Desired value of the property that we want to check.\n\t * When `undefined` attributes will be returned if they have set a given property no matter what the value is. If specified it will\n\t * return attributes which given property's value is equal to this parameter.\n\t * @returns Object with attributes' names as key and attributes' values as value.\n\t */ getAttributesWithProperty(node, propertyName, propertyValue) {\n        const attributes = {};\n        for (const [attributeName, attributeValue] of node.getAttributes()){\n            const attributeProperties = this.getAttributeProperties(attributeName);\n            if (attributeProperties[propertyName] === undefined) {\n                continue;\n            }\n            if (propertyValue === undefined || propertyValue === attributeProperties[propertyName]) {\n                attributes[attributeName] = attributeValue;\n            }\n        }\n        return attributes;\n    }\n    /**\n\t * Creates an instance of the schema context.\n\t */ createContext(context) {\n        return new SchemaContext(context);\n    }\n    _clearCache() {\n        this._compiledDefinitions = null;\n    }\n    _compile() {\n        const definitions = {};\n        const sourceRules = this._sourceDefinitions;\n        const itemNames = Object.keys(sourceRules);\n        for (const itemName of itemNames){\n            definitions[itemName] = compileBaseItemRule(sourceRules[itemName], itemName);\n        }\n        const items = Object.values(definitions);\n        // Sometimes features add rules (allows, disallows) for items that has not been registered yet. We allow that, to make it easier\n        // to put the schema together. However, sometimes these items are never registered. To prevent operating\n        // removeUnregisteredEntries( definitions, items );\n        // 1. Propagate `childItem.allowIn` to `parentItem.allowChildren` and vice versa, so that these properties are completely mirrored\n        // for all children and parents. Do the same for `disallowIn` and `disallowChildren`.\n        for (const item of items){\n            propagateAllowIn(definitions, item);\n            propagateAllowChildren(definitions, item);\n            propagateDisallowIn(definitions, item);\n            propagateDisallowChildren(definitions, item);\n        }\n        // 2. Remove from `allowIn` and `allowChildren` these items which where disallowed by `disallowIn` and `disallowChildren`.\n        // Do the same for attributes. Now we have a clear situation where which item/attribute is allowed. Inheritance is in next steps.\n        for (const item of items){\n            resolveDisallows(definitions, item);\n        }\n        // 3. Compile `item.allowContentOf` property. For each entry in `allowContentOf`, we want to take `allowChildren` and rewrite\n        // them into `item.allowChildren`. `item.disallowChildren` is used to filter out some entries. This way \"own rules\" have higher\n        // priority than \"inherited rules\". Mirroring from step 1. is maintained.\n        for (const item of items){\n            compileAllowContentOf(definitions, item);\n        }\n        // 4. Compile `item.allowWhere` property. For each entry in `allowWhere`, we want to take `allowIn` and rewrite them into\n        // `item.allowIn`. `item.disallowIn` is used to filter out some entries. This way \"own rules\" have higher priority than\n        // \"inherited rules\". Mirroring from step 1. is maintained.\n        for (const item of items){\n            compileAllowWhere(definitions, item);\n        }\n        // 5. Compile `item.allowAttributesOf`. For each entry in `allowAttributesOf`, we want to take `allowAttributes` and rewrite them\n        // into `item.allowAttributes`. `item.disallowAttributes` is used to filter out some entries. This way \"own rules\" have higher\n        // priority than \"inherited rules\".\n        for (const item of items){\n            compileAllowAttributesOf(definitions, item);\n        }\n        // 6. Compile `item.inheritTypesFrom` property. For each entry in `inheritTypesFrom`, we want to take `is*` properties and\n        // set them on `item` (if they are not set yet).\n        for (const item of items){\n            compileInheritPropertiesFrom(definitions, item);\n        }\n        // Compile final definitions. Unnecessary properties are removed and some additional cleaning is applied.\n        this._compiledDefinitions = compileDefinitions(definitions);\n    }\n    _checkContextMatch(context, def) {\n        const parentItem = context.last;\n        // First, check all child checks declared as callbacks.\n        // Note that `_evaluateChildChecks()` will return `undefined` if neither child check was applicable (no decision was made).\n        let isAllowed = this._evaluateChildChecks(context, def);\n        // If the decision was not made inside child check callbacks, then use declarative rules.\n        isAllowed = isAllowed !== undefined ? isAllowed : def.allowIn.includes(parentItem.name);\n        // If the item is not allowed in the `context`, return `false`.\n        if (!isAllowed) {\n            return false;\n        }\n        // If the item is allowed, recursively verify the rest of the `context`.\n        const parentItemDefinition = this.getDefinition(parentItem);\n        const parentContext = context.trimLast();\n        // One of the items in the original `context` did not have a definition specified. In this case, the whole context is disallowed.\n        if (!parentItemDefinition) {\n            return false;\n        }\n        // Whole `context` was verified and passed checks.\n        if (parentContext.length == 0) {\n            return true;\n        }\n        // Verify \"truncated\" parent context. The last item of the original context is now the definition to check.\n        return this._checkContextMatch(parentContext, parentItemDefinition);\n    }\n    /**\n\t * Calls child check callbacks to decide whether `def` is allowed in `context`. It uses both generic and specific (defined for `def`\n\t * item) callbacks. If neither callback makes a decision, `undefined` is returned.\n\t *\n\t * Note that the first callback that makes a decision \"wins\", i.e., if any callback returns `true` or `false`, then the processing\n\t * is over and that result is returned.\n\t */ _evaluateChildChecks(context, def) {\n        const genericChecks = this._customChildChecks.get(this._genericCheckSymbol) || [];\n        const childChecks = this._customChildChecks.get(def.name) || [];\n        for (const check of [\n            ...genericChecks,\n            ...childChecks\n        ]){\n            const result = check(context, def);\n            if (result !== undefined) {\n                return result;\n            }\n        }\n    }\n    /**\n\t * Calls attribute check callbacks to decide whether `attributeName` can be set on the last element of `context`. It uses both\n\t * generic and specific (defined for `attributeName`) callbacks. If neither callback makes a decision, `undefined` is returned.\n\t *\n\t * Note that the first callback that makes a decision \"wins\", i.e., if any callback returns `true` or `false`, then the processing\n\t * is over and that result is returned.\n\t */ _evaluateAttributeChecks(context, attributeName) {\n        const genericChecks = this._customAttributeChecks.get(this._genericCheckSymbol) || [];\n        const childChecks = this._customAttributeChecks.get(attributeName) || [];\n        for (const check of [\n            ...genericChecks,\n            ...childChecks\n        ]){\n            const result = check(context, attributeName);\n            if (result !== undefined) {\n                return result;\n            }\n        }\n    }\n    /**\n\t * Takes a flat range and an attribute name. Traverses the range recursively and deeply to find and return all ranges\n\t * inside the given range on which the attribute can be applied.\n\t *\n\t * This is a helper function for {@link ~Schema#getValidRanges}.\n\t *\n\t * @param range The range to process.\n\t * @param attribute The name of the attribute to check.\n\t * @returns Ranges in which the attribute is allowed.\n\t */ *_getValidRangesForRange(range, attribute) {\n        let start = range.start;\n        let end = range.start;\n        for (const item of range.getItems({\n            shallow: true\n        })){\n            if (item.is('element')) {\n                yield* this._getValidRangesForRange(Range._createIn(item), attribute);\n            }\n            if (!this.checkAttribute(item, attribute)) {\n                if (!start.isEqual(end)) {\n                    yield new Range(start, end);\n                }\n                start = Position._createAfter(item);\n            }\n            end = Position._createAfter(item);\n        }\n        if (!start.isEqual(end)) {\n            yield new Range(start, end);\n        }\n    }\n    /**\n\t * Returns a model range which is optimal (in terms of UX) for inserting a widget block.\n\t *\n\t * For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph\n\t * will be returned so that it is not split. If the selection is at the end of a paragraph,\n\t * the collapsed range after this paragraph will be returned.\n\t *\n\t * Note: If the selection is placed in an empty block, the range in that block will be returned. If that range\n\t * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced\n\t * by the inserted widget block.\n\t *\n\t * @internal\n\t * @param selection The selection based on which the insertion position should be calculated.\n\t * @param place The place where to look for optimal insertion range.\n\t * The `auto` value will determine itself the best position for insertion.\n\t * The `before` value will try to find a position before selection.\n\t * The `after` value will try to find a position after selection.\n\t * @returns The optimal range.\n\t */ findOptimalInsertionRange(selection, place) {\n        const selectedElement = selection.getSelectedElement();\n        if (selectedElement && this.isObject(selectedElement) && !this.isInline(selectedElement)) {\n            if (place == 'before' || place == 'after') {\n                return new Range(Position._createAt(selectedElement, place));\n            }\n            return Range._createOn(selectedElement);\n        }\n        const firstBlock = first(selection.getSelectedBlocks());\n        // There are no block elements within ancestors (in the current limit element).\n        if (!firstBlock) {\n            return new Range(selection.focus);\n        }\n        // If inserting into an empty block – return position in that block. It will get\n        // replaced with the image by insertContent(). #42.\n        if (firstBlock.isEmpty) {\n            return new Range(Position._createAt(firstBlock, 0));\n        }\n        const positionAfter = Position._createAfter(firstBlock);\n        // If selection is at the end of the block - return position after the block.\n        if (selection.focus.isTouching(positionAfter)) {\n            return new Range(positionAfter);\n        }\n        // Otherwise, return position before the block.\n        return new Range(Position._createBefore(firstBlock));\n    }\n}\n/**\n * A schema context &ndash; a list of ancestors of a given position in the document.\n *\n * Considering such position:\n *\n * ```xml\n * <$root>\n * \t<blockQuote>\n * \t\t<paragraph>\n * \t\t\t^\n * \t\t</paragraph>\n * \t</blockQuote>\n * </$root>\n * ```\n *\n * The context of this position is its {@link module:engine/model/position~Position#getAncestors lists of ancestors}:\n *\n *\t\t[ rootElement, blockQuoteElement, paragraphElement ]\n *\n * Contexts are used in the {@link module:engine/model/schema~Schema#event:checkChild `Schema#checkChild`} and\n * {@link module:engine/model/schema~Schema#event:checkAttribute `Schema#checkAttribute`} events as a definition\n * of a place in the document where the check occurs. The context instances are created based on the first arguments\n * of the {@link module:engine/model/schema~Schema#checkChild `Schema#checkChild()`} and\n * {@link module:engine/model/schema~Schema#checkAttribute `Schema#checkAttribute()`} methods so when\n * using these methods you need to use {@link module:engine/model/schema~SchemaContextDefinition}s.\n */ class SchemaContext {\n    _items;\n    /**\n\t * Creates an instance of the context.\n\t */ constructor(context){\n        if (context instanceof SchemaContext) {\n            return context;\n        }\n        let items;\n        if (typeof context == 'string') {\n            items = [\n                context\n            ];\n        } else if (!Array.isArray(context)) {\n            // `context` is item or position.\n            // Position#getAncestors() doesn't accept any parameters but it works just fine here.\n            items = context.getAncestors({\n                includeSelf: true\n            });\n        } else {\n            items = context;\n        }\n        this._items = items.map(mapContextItem);\n    }\n    /**\n\t * The number of items.\n\t */ get length() {\n        return this._items.length;\n    }\n    /**\n\t * The last item (the lowest node).\n\t */ get last() {\n        return this._items[this._items.length - 1];\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * Iterates over all context items.\n\t */ [Symbol.iterator]() {\n        return this._items[Symbol.iterator]();\n    }\n    /**\n\t * Returns a new schema context instance with an additional item.\n\t *\n\t * Item can be added as:\n\t *\n\t * ```ts\n\t * const context = new SchemaContext( [ '$root' ] );\n\t *\n\t * // An element.\n\t * const fooElement = writer.createElement( 'fooElement' );\n\t * const newContext = context.push( fooElement ); // [ '$root', 'fooElement' ]\n\t *\n\t * // A text node.\n\t * const text = writer.createText( 'foobar' );\n\t * const newContext = context.push( text ); // [ '$root', '$text' ]\n\t *\n\t * // A string (element name).\n\t * const newContext = context.push( 'barElement' ); // [ '$root', 'barElement' ]\n\t * ```\n\t *\n\t * **Note** {@link module:engine/model/node~Node} that is already in the model tree will be added as the only item\n\t * (without ancestors).\n\t *\n\t * @param item An item that will be added to the current context.\n\t * @returns A new schema context instance with an additional item.\n\t */ push(item) {\n        const ctx = new SchemaContext([\n            item\n        ]);\n        ctx._items = [\n            ...this._items,\n            ...ctx._items\n        ];\n        return ctx;\n    }\n    /**\n\t * Returns a new schema context that is based on this context but has the last item removed.\n\t *\n\t * ```ts\n\t * const ctxParagraph = new SchemaContext( [ '$root', 'blockQuote', 'paragraph' ] );\n\t * const ctxBlockQuote = ctxParagraph.trimLast(); // Items in `ctxBlockQuote` are: `$root` an `blockQuote`.\n\t * const ctxRoot = ctxBlockQuote.trimLast(); // Items in `ctxRoot` are: `$root`.\n\t * ```\n\t *\n\t * @returns A new reduced schema context instance.\n\t */ trimLast() {\n        const ctx = new SchemaContext([]);\n        ctx._items = this._items.slice(0, -1);\n        return ctx;\n    }\n    /**\n\t * Gets an item on the given index.\n\t */ getItem(index) {\n        return this._items[index];\n    }\n    /**\n\t * Returns the names of items.\n\t */ *getNames() {\n        yield* this._items.map((item)=>item.name);\n    }\n    /**\n\t * Checks whether the context ends with the given nodes.\n\t *\n\t * ```ts\n\t * const ctx = new SchemaContext( [ rootElement, paragraphElement, textNode ] );\n\t *\n\t * ctx.endsWith( '$text' ); // -> true\n\t * ctx.endsWith( 'paragraph $text' ); // -> true\n\t * ctx.endsWith( '$root' ); // -> false\n\t * ctx.endsWith( 'paragraph' ); // -> false\n\t * ```\n\t */ endsWith(query) {\n        return Array.from(this.getNames()).join(' ').endsWith(query);\n    }\n    /**\n\t * Checks whether the context starts with the given nodes.\n\t *\n\t * ```ts\n\t * const ctx = new SchemaContext( [ rootElement, paragraphElement, textNode ] );\n\t *\n\t * ctx.endsWith( '$root' ); // -> true\n\t * ctx.endsWith( '$root paragraph' ); // -> true\n\t * ctx.endsWith( '$text' ); // -> false\n\t * ctx.endsWith( 'paragraph' ); // -> false\n\t * ```\n\t */ startsWith(query) {\n        return Array.from(this.getNames()).join(' ').startsWith(query);\n    }\n}\nfunction compileBaseItemRule(sourceItemRules, itemName) {\n    const itemRule = {\n        name: itemName,\n        allowIn: new Set(),\n        allowChildren: new Set(),\n        disallowIn: new Set(),\n        disallowChildren: new Set(),\n        allowContentOf: new Set(),\n        allowWhere: new Set(),\n        allowAttributes: new Set(),\n        disallowAttributes: new Set(),\n        allowAttributesOf: new Set(),\n        inheritTypesFrom: new Set()\n    };\n    copyTypes(sourceItemRules, itemRule);\n    copyProperty(sourceItemRules, itemRule, 'allowIn');\n    copyProperty(sourceItemRules, itemRule, 'allowChildren');\n    copyProperty(sourceItemRules, itemRule, 'disallowIn');\n    copyProperty(sourceItemRules, itemRule, 'disallowChildren');\n    copyProperty(sourceItemRules, itemRule, 'allowContentOf');\n    copyProperty(sourceItemRules, itemRule, 'allowWhere');\n    copyProperty(sourceItemRules, itemRule, 'allowAttributes');\n    copyProperty(sourceItemRules, itemRule, 'disallowAttributes');\n    copyProperty(sourceItemRules, itemRule, 'allowAttributesOf');\n    copyProperty(sourceItemRules, itemRule, 'inheritTypesFrom');\n    resolveInheritAll(sourceItemRules, itemRule);\n    return itemRule;\n}\nfunction propagateAllowIn(definitions, item) {\n    for (const parentName of item.allowIn){\n        const parentItem = definitions[parentName];\n        if (parentItem) {\n            parentItem.allowChildren.add(item.name);\n        } else {\n            item.allowIn.delete(parentName);\n        }\n    }\n}\nfunction propagateAllowChildren(definitions, item) {\n    for (const childName of item.allowChildren){\n        const childItem = definitions[childName];\n        if (childItem) {\n            childItem.allowIn.add(item.name);\n        } else {\n            item.allowChildren.delete(childName);\n        }\n    }\n}\nfunction propagateDisallowIn(definitions, item) {\n    for (const parentName of item.disallowIn){\n        const parentItem = definitions[parentName];\n        if (parentItem) {\n            parentItem.disallowChildren.add(item.name);\n        } else {\n            item.disallowIn.delete(parentName);\n        }\n    }\n}\nfunction propagateDisallowChildren(definitions, item) {\n    for (const childName of item.disallowChildren){\n        const childItem = definitions[childName];\n        if (childItem) {\n            childItem.disallowIn.add(item.name);\n        } else {\n            item.disallowChildren.delete(childName);\n        }\n    }\n}\nfunction resolveDisallows(definitions, item) {\n    for (const childName of item.disallowChildren){\n        item.allowChildren.delete(childName);\n    }\n    for (const parentName of item.disallowIn){\n        item.allowIn.delete(parentName);\n    }\n    for (const attributeName of item.disallowAttributes){\n        item.allowAttributes.delete(attributeName);\n    }\n}\nfunction compileAllowContentOf(definitions, item) {\n    for (const allowContentOfItemName of item.allowContentOf){\n        const baseItem = definitions[allowContentOfItemName];\n        if (!baseItem) {\n            continue;\n        }\n        // Copy `disallowChildren` to propagate this \"knowledge\" down the inheritance chain. The inheritance may involve multiple items and\n        // if this is not propagated, then items down the chain may start to allow for items that were disallowed by previous base items.\n        //\n        // The scenarios were it is important involves multiple inherits both on parent items side and on the child items side.\n        baseItem.disallowChildren.forEach((childName)=>{\n            // Own item's rules takes precedence before inherited.\n            // If the item directly allows for given child, ignore that base item disallowed that child.\n            if (item.allowChildren.has(childName)) {\n                return;\n            }\n            item.disallowChildren.add(childName);\n            definitions[childName].disallowIn.add(item.name);\n        });\n        // Copy `allowChildren` from the base item to allow for the same items.\n        baseItem.allowChildren.forEach((childName)=>{\n            // Own item's rules takes precedence before inherited.\n            // Also, `item.disallowChildren` might get some new items during inheritance process.\n            if (item.disallowChildren.has(childName)) {\n                return;\n            }\n            item.allowChildren.add(childName);\n            definitions[childName].allowIn.add(item.name);\n        });\n    }\n}\nfunction compileAllowWhere(definitions, item) {\n    for (const allowWhereItemName of item.allowWhere){\n        const baseItem = definitions[allowWhereItemName];\n        if (!baseItem) {\n            continue;\n        }\n        // Copy `disallowIn` to propagate this \"knowledge\" down the inheritance chain. The inheritance may involve multiple items and\n        // if this is not propagated, then items down the chain may start to be allowed in items in which they were disallowed previously.\n        //\n        // The scenarios were it is important involves multiple inherits both on parent items side and on the child items side.\n        baseItem.disallowIn.forEach((parentName)=>{\n            // Own item's rules takes precedence before inherited.\n            // If the item is directly allowed in given parent, ignore that base item was disallowed in it.\n            if (item.allowIn.has(parentName)) {\n                return;\n            }\n            item.disallowIn.add(parentName);\n            definitions[parentName].disallowChildren.add(item.name);\n        });\n        // Copy `allowIn` from the base item to allow item in same parents.\n        baseItem.allowIn.forEach((parentName)=>{\n            // Own item's rules takes precedence before inherited.\n            // Also, `item.disallowIn` might get some new items during inheritance process.\n            if (item.disallowIn.has(parentName)) {\n                return;\n            }\n            item.allowIn.add(parentName);\n            definitions[parentName].allowChildren.add(item.name);\n        });\n    }\n}\nfunction compileDefinitions(definitions) {\n    const finalDefinitions = {};\n    for (const item of Object.values(definitions)){\n        finalDefinitions[item.name] = {\n            name: item.name,\n            // `is*` properties may not be set - convert `undefined` to `false`.\n            isBlock: !!item.isBlock,\n            isContent: !!item.isContent,\n            isInline: !!item.isInline,\n            isLimit: !!item.isLimit,\n            isObject: !!item.isObject,\n            isSelectable: !!item.isSelectable,\n            // Filter out non-existing items.\n            allowIn: Array.from(item.allowIn).filter((name)=>!!definitions[name]),\n            allowChildren: Array.from(item.allowChildren).filter((name)=>!!definitions[name]),\n            allowAttributes: Array.from(item.allowAttributes)\n        };\n    }\n    return finalDefinitions;\n}\nfunction compileAllowAttributesOf(definitions, item) {\n    for (const allowAttributeOfItemName of item.allowAttributesOf){\n        const baseItem = definitions[allowAttributeOfItemName];\n        if (!baseItem) {\n            return;\n        }\n        baseItem.allowAttributes.forEach((attributeName)=>{\n            if (item.disallowAttributes.has(attributeName)) {\n                return;\n            }\n            item.allowAttributes.add(attributeName);\n        });\n    }\n}\nfunction compileInheritPropertiesFrom(definitions, item) {\n    for (const inheritPropertiesOfItemName of item.inheritTypesFrom){\n        const inheritFrom = definitions[inheritPropertiesOfItemName];\n        if (inheritFrom) {\n            const typeNames = Object.keys(inheritFrom).filter((name)=>name.startsWith('is'));\n            for (const name of typeNames){\n                if (!(name in item)) {\n                    item[name] = inheritFrom[name];\n                }\n            }\n        }\n    }\n}\nfunction copyTypes(sourceItemRules, itemRule) {\n    for (const sourceItemRule of sourceItemRules){\n        const typeNames = Object.keys(sourceItemRule).filter((name)=>name.startsWith('is'));\n        for (const name of typeNames){\n            itemRule[name] = !!sourceItemRule[name];\n        }\n    }\n}\nfunction copyProperty(sourceItemRules, itemRule, propertyName) {\n    for (const sourceItemRule of sourceItemRules){\n        let value = sourceItemRule[propertyName];\n        // `value` can be a string, an array or undefined.\n        // Convert a string to an array with one item, then handle an array. Skip undefined this way.\n        if (typeof value == 'string') {\n            value = [\n                value\n            ];\n        }\n        if (Array.isArray(value)) {\n            value.forEach((singleValue)=>itemRule[propertyName].add(singleValue));\n        }\n    }\n}\nfunction resolveInheritAll(sourceItemRules, itemRule) {\n    for (const sourceItemRule of sourceItemRules){\n        const inheritFrom = sourceItemRule.inheritAllFrom;\n        if (inheritFrom) {\n            itemRule.allowContentOf.add(inheritFrom);\n            itemRule.allowWhere.add(inheritFrom);\n            itemRule.allowAttributesOf.add(inheritFrom);\n            itemRule.inheritTypesFrom.add(inheritFrom);\n        }\n    }\n}\nfunction mapContextItem(ctxItem) {\n    if (typeof ctxItem == 'string' || ctxItem.is('documentFragment')) {\n        return {\n            name: typeof ctxItem == 'string' ? ctxItem : '$documentFragment',\n            *getAttributeKeys () {},\n            getAttribute () {}\n        };\n    } else {\n        return {\n            // '$text' means text nodes and text proxies.\n            name: ctxItem.is('element') ? ctxItem.name : '$text',\n            *getAttributeKeys () {\n                yield* ctxItem.getAttributeKeys();\n            },\n            getAttribute (key) {\n                return ctxItem.getAttribute(key);\n            }\n        };\n    }\n}\n/**\n * Generator function returning values from provided walkers, switching between them at each iteration. If only one walker\n * is provided it will return data only from that walker.\n *\n * @param backward Walker iterating in backward direction.\n * @param forward Walker iterating in forward direction.\n * @returns Object returned at each iteration contains `value` and `walker` (informing which walker returned\n * given value) fields.\n */ function* combineWalkers(backward, forward) {\n    let done = false;\n    while(!done){\n        done = true;\n        if (backward) {\n            const step = backward.next();\n            if (!step.done) {\n                done = false;\n                yield {\n                    walker: backward,\n                    value: step.value\n                };\n            }\n        }\n        if (forward) {\n            const step = forward.next();\n            if (!step.done) {\n                done = false;\n                yield {\n                    walker: forward,\n                    value: step.value\n                };\n            }\n        }\n    }\n}\n/**\n * Takes an array of non-intersecting ranges. For each of them gets minimal flat ranges covering that range and returns\n * all those minimal flat ranges.\n *\n * @param ranges Ranges to process.\n * @returns Minimal flat ranges of given `ranges`.\n */ function* convertToMinimalFlatRanges(ranges) {\n    for (const range of ranges){\n        yield* range.getMinimalFlatRanges();\n    }\n}\nfunction removeDisallowedAttributeFromNode(schema, node, writer) {\n    for (const attribute of node.getAttributeKeys()){\n        if (!schema.checkAttribute(node, attribute)) {\n            writer.removeAttribute(attribute, node);\n        }\n    }\n}\n\n/**\n * Upcast dispatcher is a central point of the view-to-model conversion, which is a process of\n * converting a given {@link module:engine/view/documentfragment~DocumentFragment view document fragment} or\n * {@link module:engine/view/element~Element view element} into a correct model structure.\n *\n * During the conversion process, the dispatcher fires events for all {@link module:engine/view/node~Node view nodes}\n * from the converted view document fragment.\n * Special callbacks called \"converters\" should listen to these events in order to convert the view nodes.\n *\n * The second parameter of the callback is the `data` object with the following properties:\n *\n * * `data.viewItem` contains a {@link module:engine/view/node~Node view node} or a\n * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * that is converted at the moment and might be handled by the callback.\n * * `data.modelRange` is used to point to the result\n * of the current conversion (e.g. the element that is being inserted)\n * and is always a {@link module:engine/model/range~Range} when the conversion succeeds.\n * * `data.modelCursor` is a {@link module:engine/model/position~Position position} on which the converter should insert\n * the newly created items.\n *\n * The third parameter of the callback is an instance of {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi}\n * which provides additional tools for converters.\n *\n * You can read more about conversion in the {@glink framework/deep-dive/conversion/upcast Upcast conversion} guide.\n *\n * Examples of event-based converters:\n *\n * ```ts\n * // A converter for links (<a>).\n * editor.data.upcastDispatcher.on( 'element:a', ( evt, data, conversionApi ) => {\n * \tif ( conversionApi.consumable.consume( data.viewItem, { name: true, attributes: [ 'href' ] } ) ) {\n * \t\t// The <a> element is inline and is represented by an attribute in the model.\n * \t\t// This is why you need to convert only children.\n * \t\tconst { modelRange } = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n *\n * \t\tfor ( let item of modelRange.getItems() ) {\n * \t\t\tif ( conversionApi.schema.checkAttribute( item, 'linkHref' ) ) {\n * \t\t\t\tconversionApi.writer.setAttribute( 'linkHref', data.viewItem.getAttribute( 'href' ), item );\n * \t\t\t}\n * \t\t}\n * \t}\n * } );\n *\n * // Convert <p> element's font-size style.\n * // Note: You should use a low-priority observer in order to ensure that\n * // it is executed after the element-to-element converter.\n * editor.data.upcastDispatcher.on( 'element:p', ( evt, data, conversionApi ) => {\n * \tconst { consumable, schema, writer } = conversionApi;\n *\n * \tif ( !consumable.consume( data.viewItem, { style: 'font-size' } ) ) {\n * \t\treturn;\n * \t}\n *\n * \tconst fontSize = data.viewItem.getStyle( 'font-size' );\n *\n * \t// Do not go for the model element after data.modelCursor because it might happen\n * \t// that a single view element was converted to multiple model elements. Get all of them.\n * \tfor ( const item of data.modelRange.getItems( { shallow: true } ) ) {\n * \t\tif ( schema.checkAttribute( item, 'fontSize' ) ) {\n * \t\t\twriter.setAttribute( 'fontSize', fontSize, item );\n * \t\t}\n * \t}\n * }, { priority: 'low' } );\n *\n * // Convert all elements which have no custom converter into a paragraph (autoparagraphing).\n * editor.data.upcastDispatcher.on( 'element', ( evt, data, conversionApi ) => {\n * \t// Check if an element can be converted.\n * \tif ( !conversionApi.consumable.test( data.viewItem, { name: data.viewItem.name } ) ) {\n * \t\t// When an element is already consumed by higher priority converters, do nothing.\n * \t\treturn;\n * \t}\n *\n * \tconst paragraph = conversionApi.writer.createElement( 'paragraph' );\n *\n * \t// Try to safely insert a paragraph at the model cursor - it will find an allowed parent for the current element.\n * \tif ( !conversionApi.safeInsert( paragraph, data.modelCursor ) ) {\n * \t\t// When an element was not inserted, it means that you cannot insert a paragraph at this position.\n * \t\treturn;\n * \t}\n *\n * \t// Consume the inserted element.\n * \tconversionApi.consumable.consume( data.viewItem, { name: data.viewItem.name } ) );\n *\n * \t// Convert the children to a paragraph.\n * \tconst { modelRange } = conversionApi.convertChildren( data.viewItem,  paragraph ) );\n *\n * \t// Update `modelRange` and `modelCursor` in the `data` as a conversion result.\n * \tconversionApi.updateConversionResult( paragraph, data );\n * }, { priority: 'low' } );\n * ```\n *\n * @fires viewCleanup\n * @fires element\n * @fires text\n * @fires documentFragment\n */ class UpcastDispatcher extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * An interface passed by the dispatcher to the event callbacks.\n\t */ conversionApi;\n    /**\n\t * The list of elements that were created during splitting.\n\t *\n\t * After the conversion process, the list is cleared.\n\t */ _splitParts = new Map();\n    /**\n\t * The list of cursor parent elements that were created during splitting.\n\t *\n\t * After the conversion process the list is cleared.\n\t */ _cursorParents = new Map();\n    /**\n\t * The position in the temporary structure where the converted content is inserted. The structure reflects the context of\n\t * the target position where the content will be inserted. This property is built based on the context parameter of the\n\t * convert method.\n\t */ _modelCursor = null;\n    /**\n\t * The list of elements that were created during the splitting but should not get removed on conversion end even if they are empty.\n\t *\n\t * The list is cleared after the conversion process.\n\t */ _emptyElementsToKeep = new Set();\n    /**\n\t * Creates an upcast dispatcher that operates using the passed API.\n\t *\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi\n\t * @param conversionApi Additional properties for an interface that will be passed to events fired\n\t * by the upcast dispatcher.\n\t */ constructor(conversionApi){\n        super();\n        this.conversionApi = {\n            ...conversionApi,\n            consumable: null,\n            writer: null,\n            store: null,\n            convertItem: (viewItem, modelCursor)=>this._convertItem(viewItem, modelCursor),\n            convertChildren: (viewElement, positionOrElement)=>this._convertChildren(viewElement, positionOrElement),\n            safeInsert: (modelNode, position)=>this._safeInsert(modelNode, position),\n            updateConversionResult: (modelElement, data)=>this._updateConversionResult(modelElement, data),\n            // Advanced API - use only if custom position handling is needed.\n            splitToAllowedParent: (modelNode, modelCursor)=>this._splitToAllowedParent(modelNode, modelCursor),\n            getSplitParts: (modelElement)=>this._getSplitParts(modelElement),\n            keepEmptyElement: (modelElement)=>this._keepEmptyElement(modelElement)\n        };\n    }\n    /**\n\t * Starts the conversion process. The entry point for the conversion.\n\t *\n\t * @fires element\n\t * @fires text\n\t * @fires documentFragment\n\t * @param viewElement The part of the view to be converted.\n\t * @param writer An instance of the model writer.\n\t * @param context Elements will be converted according to this context.\n\t * @returns Model data that is the result of the conversion process\n\t * wrapped in `DocumentFragment`. Converted marker elements will be set as the document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t */ convert(viewElement, writer, context = [\n        '$root'\n    ]) {\n        this.fire('viewCleanup', viewElement);\n        // Create context tree and set position in the top element.\n        // Items will be converted according to this position.\n        this._modelCursor = createContextTree(context, writer);\n        // Store writer in conversion as a conversion API\n        // to be sure that conversion process will use the same batch.\n        this.conversionApi.writer = writer;\n        // Create consumable values list for conversion process.\n        this.conversionApi.consumable = ViewConsumable.createFrom(viewElement);\n        // Custom data stored by converter for conversion process.\n        this.conversionApi.store = {};\n        // Do the conversion.\n        const { modelRange } = this._convertItem(viewElement, this._modelCursor);\n        // Conversion result is always a document fragment so let's create it.\n        const documentFragment = writer.createDocumentFragment();\n        // When there is a conversion result.\n        if (modelRange) {\n            // Remove all empty elements that were created while splitting.\n            this._removeEmptyElements();\n            // Move all items that were converted in context tree to the document fragment.\n            for (const item of Array.from(this._modelCursor.parent.getChildren())){\n                writer.append(item, documentFragment);\n            }\n            // Extract temporary markers elements from model and set as static markers collection.\n            documentFragment.markers = extractMarkersFromModelFragment(documentFragment, writer);\n        }\n        // Clear context position.\n        this._modelCursor = null;\n        // Clear split elements & parents lists.\n        this._splitParts.clear();\n        this._cursorParents.clear();\n        this._emptyElementsToKeep.clear();\n        // Clear conversion API.\n        this.conversionApi.writer = null;\n        this.conversionApi.store = null;\n        // Return fragment as conversion result.\n        return documentFragment;\n    }\n    /**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertItem\n\t */ _convertItem(viewItem, modelCursor) {\n        const data = {\n            viewItem,\n            modelCursor,\n            modelRange: null\n        };\n        if (viewItem.is('element')) {\n            this.fire(`element:${viewItem.name}`, data, this.conversionApi);\n        } else if (viewItem.is('$text')) {\n            this.fire('text', data, this.conversionApi);\n        } else {\n            this.fire('documentFragment', data, this.conversionApi);\n        }\n        // Handle incorrect conversion result.\n        if (data.modelRange && !(data.modelRange instanceof Range)) {\n            /**\n\t\t\t * Incorrect conversion result was dropped.\n\t\t\t *\n\t\t\t * {@link module:engine/model/range~Range Model range} should be a conversion result.\n\t\t\t *\n\t\t\t * @error view-conversion-dispatcher-incorrect-result\n\t\t\t */ throw new CKEditorError('view-conversion-dispatcher-incorrect-result', this);\n        }\n        return {\n            modelRange: data.modelRange,\n            modelCursor: data.modelCursor\n        };\n    }\n    /**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertChildren\n\t */ _convertChildren(viewItem, elementOrModelCursor) {\n        let nextModelCursor = elementOrModelCursor.is('position') ? elementOrModelCursor : Position._createAt(elementOrModelCursor, 0);\n        const modelRange = new Range(nextModelCursor);\n        for (const viewChild of Array.from(viewItem.getChildren())){\n            const result = this._convertItem(viewChild, nextModelCursor);\n            if (result.modelRange instanceof Range) {\n                modelRange.end = result.modelRange.end;\n                nextModelCursor = result.modelCursor;\n            }\n        }\n        return {\n            modelRange,\n            modelCursor: nextModelCursor\n        };\n    }\n    /**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#safeInsert\n\t */ _safeInsert(modelNode, position) {\n        // Find allowed parent for element that we are going to insert.\n        // If current parent does not allow to insert element but one of the ancestors does\n        // then split nodes to allowed parent.\n        const splitResult = this._splitToAllowedParent(modelNode, position);\n        // When there is no split result it means that we can't insert element to model tree, so let's skip it.\n        if (!splitResult) {\n            return false;\n        }\n        // Insert element on allowed position.\n        this.conversionApi.writer.insert(modelNode, splitResult.position);\n        return true;\n    }\n    /**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#updateConversionResult\n\t */ _updateConversionResult(modelElement, data) {\n        const parts = this._getSplitParts(modelElement);\n        const writer = this.conversionApi.writer;\n        // Set conversion result range - only if not set already.\n        if (!data.modelRange) {\n            data.modelRange = writer.createRange(writer.createPositionBefore(modelElement), writer.createPositionAfter(parts[parts.length - 1]));\n        }\n        const savedCursorParent = this._cursorParents.get(modelElement);\n        // Now we need to check where the `modelCursor` should be.\n        if (savedCursorParent) {\n            // If we split parent to insert our element then we want to continue conversion in the new part of the split parent.\n            //\n            // before: <allowed><notAllowed>foo[]</notAllowed></allowed>\n            // after:  <allowed><notAllowed>foo</notAllowed> <converted></converted> <notAllowed>[]</notAllowed></allowed>\n            data.modelCursor = writer.createPositionAt(savedCursorParent, 0);\n        } else {\n            // Otherwise just continue after inserted element.\n            data.modelCursor = data.modelRange.end;\n        }\n    }\n    /**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#splitToAllowedParent\n\t */ _splitToAllowedParent(node, modelCursor) {\n        const { schema, writer } = this.conversionApi;\n        // Try to find allowed parent.\n        let allowedParent = schema.findAllowedParent(modelCursor, node);\n        if (allowedParent) {\n            // When current position parent allows to insert node then return this position.\n            if (allowedParent === modelCursor.parent) {\n                return {\n                    position: modelCursor\n                };\n            }\n            // When allowed parent is in context tree (it's outside the converted tree).\n            if (this._modelCursor.parent.getAncestors().includes(allowedParent)) {\n                allowedParent = null;\n            }\n        }\n        if (!allowedParent) {\n            // Check if the node wrapped with a paragraph would be accepted by the schema.\n            if (!isParagraphable(modelCursor, node, schema)) {\n                return null;\n            }\n            return {\n                position: wrapInParagraph(modelCursor, writer)\n            };\n        }\n        // Split element to allowed parent.\n        const splitResult = this.conversionApi.writer.split(modelCursor, allowedParent);\n        // Using the range returned by `model.Writer#split`, we will pair original elements with their split parts.\n        //\n        // The range returned from the writer spans \"over the split\" or, precisely saying, from the end of the original element (the one\n        // that got split) to the beginning of the other part of that element:\n        //\n        // <limit><a><b><c>X[]Y</c></b><a></limit> ->\n        // <limit><a><b><c>X[</c></b></a><a><b><c>]Y</c></b></a>\n        //\n        // After the split there cannot be any full node between the positions in `splitRange`. The positions are touching.\n        // Also, because of how splitting works, it is easy to notice, that \"closing tags\" are in the reverse order than \"opening tags\".\n        // Also, since we split all those elements, each of them has to have the other part.\n        //\n        // With those observations in mind, we will pair the original elements with their split parts by saving \"closing tags\" and matching\n        // them with \"opening tags\" in the reverse order. For that we can use a stack.\n        const stack = [];\n        for (const treeWalkerValue of splitResult.range.getWalker()){\n            if (treeWalkerValue.type == 'elementEnd') {\n                stack.push(treeWalkerValue.item);\n            } else {\n                // There should not be any text nodes after the element is split, so the only other value is `elementStart`.\n                const originalPart = stack.pop();\n                const splitPart = treeWalkerValue.item;\n                this._registerSplitPair(originalPart, splitPart);\n            }\n        }\n        const cursorParent = splitResult.range.end.parent;\n        this._cursorParents.set(node, cursorParent);\n        return {\n            position: splitResult.position,\n            cursorParent\n        };\n    }\n    /**\n\t * Registers that a `splitPart` element is a split part of the `originalPart` element.\n\t *\n\t * The data set by this method is used by {@link #_getSplitParts} and {@link #_removeEmptyElements}.\n\t */ _registerSplitPair(originalPart, splitPart) {\n        if (!this._splitParts.has(originalPart)) {\n            this._splitParts.set(originalPart, [\n                originalPart\n            ]);\n        }\n        const list = this._splitParts.get(originalPart);\n        this._splitParts.set(splitPart, list);\n        list.push(splitPart);\n    }\n    /**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#getSplitParts\n\t */ _getSplitParts(element) {\n        let parts;\n        if (!this._splitParts.has(element)) {\n            parts = [\n                element\n            ];\n        } else {\n            parts = this._splitParts.get(element);\n        }\n        return parts;\n    }\n    /**\n\t * Mark an element that were created during the splitting to not get removed on conversion end even if it is empty.\n\t */ _keepEmptyElement(element) {\n        this._emptyElementsToKeep.add(element);\n    }\n    /**\n\t * Checks if there are any empty elements created while splitting and removes them.\n\t *\n\t * This method works recursively to re-check empty elements again after at least one element was removed in the initial call,\n\t * as some elements might have become empty after other empty elements were removed from them.\n\t */ _removeEmptyElements() {\n        let anyRemoved = false;\n        for (const element of this._splitParts.keys()){\n            if (element.isEmpty && !this._emptyElementsToKeep.has(element)) {\n                this.conversionApi.writer.remove(element);\n                this._splitParts.delete(element);\n                anyRemoved = true;\n            }\n        }\n        if (anyRemoved) {\n            this._removeEmptyElements();\n        }\n    }\n}\n/**\n * Traverses given model item and searches elements which marks marker range. Found element is removed from\n * DocumentFragment but path of this element is stored in a Map which is then returned.\n *\n * @param modelItem Fragment of model.\n * @returns List of static markers.\n */ function extractMarkersFromModelFragment(modelItem, writer) {\n    const markerElements = new Set();\n    const markers = new Map();\n    // Create ModelTreeWalker.\n    const range = Range._createIn(modelItem).getItems();\n    // Walk through DocumentFragment and collect marker elements.\n    for (const item of range){\n        // Check if current element is a marker.\n        if (item.is('element', '$marker')) {\n            markerElements.add(item);\n        }\n    }\n    // Walk through collected marker elements store its path and remove its from the DocumentFragment.\n    for (const markerElement of markerElements){\n        const markerName = markerElement.getAttribute('data-name');\n        const currentPosition = writer.createPositionBefore(markerElement);\n        // When marker of given name is not stored it means that we have found the beginning of the range.\n        if (!markers.has(markerName)) {\n            markers.set(markerName, new Range(currentPosition.clone()));\n        // Otherwise is means that we have found end of the marker range.\n        } else {\n            markers.get(markerName).end = currentPosition.clone();\n        }\n        // Remove marker element from DocumentFragment.\n        writer.remove(markerElement);\n    }\n    return markers;\n}\n/**\n * Creates model fragment according to given context and returns position in the bottom (the deepest) element.\n */ function createContextTree(contextDefinition, writer) {\n    let position;\n    for (const item of new SchemaContext(contextDefinition)){\n        const attributes = {};\n        for (const key of item.getAttributeKeys()){\n            attributes[key] = item.getAttribute(key);\n        }\n        const current = writer.createElement(item.name, attributes);\n        if (position) {\n            writer.insert(current, position);\n        }\n        position = Position._createAt(current, 0);\n    }\n    return position;\n}\n\n/**\n * Basic HTML writer. It uses the native `innerHTML` property for basic conversion\n * from a document fragment to an HTML string.\n */ class BasicHtmlWriter {\n    /**\n\t * Returns an HTML string created from the document fragment.\n\t */ getHtml(fragment) {\n        const doc = global.document.implementation.createHTMLDocument('');\n        const container = doc.createElement('div');\n        container.appendChild(fragment);\n        return container.innerHTML;\n    }\n}\n\n/**\n * The HTML data processor class.\n * This data processor implementation uses HTML as input and output data.\n */ class HtmlDataProcessor {\n    /**\n\t * A DOM parser instance used to parse an HTML string to an HTML document.\n\t */ domParser;\n    /**\n\t * A DOM converter used to convert DOM elements to view elements.\n\t */ domConverter;\n    /**\n\t * A basic HTML writer instance used to convert DOM elements to an HTML string.\n\t */ htmlWriter;\n    skipComments = true;\n    /**\n\t * Creates a new instance of the HTML data processor class.\n\t *\n\t * @param document The view document instance.\n\t */ constructor(document){\n        this.domParser = new DOMParser();\n        this.domConverter = new DomConverter(document, {\n            renderingMode: 'data'\n        });\n        this.htmlWriter = new BasicHtmlWriter();\n    }\n    /**\n\t * Converts a provided {@link module:engine/view/documentfragment~DocumentFragment document fragment}\n\t * to data format &ndash; in this case to an HTML string.\n\t *\n\t * @returns HTML string.\n\t */ toData(viewFragment) {\n        // Convert view DocumentFragment to DOM DocumentFragment.\n        const domFragment = this.domConverter.viewToDom(viewFragment);\n        // Convert DOM DocumentFragment to HTML output.\n        return this.htmlWriter.getHtml(domFragment);\n    }\n    /**\n\t * Converts the provided HTML string to a view tree.\n\t *\n\t * @param data An HTML string.\n\t * @returns A converted view element.\n\t */ toView(data) {\n        // Convert input HTML data to DOM DocumentFragment.\n        const domFragment = this._toDom(data);\n        // Convert DOM DocumentFragment to view DocumentFragment.\n        return this.domConverter.domToView(domFragment, {\n            skipComments: this.skipComments\n        });\n    }\n    /**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from the DOM to the view elements.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching all view elements whose content should be treated as raw data.\n\t */ registerRawContentMatcher(pattern) {\n        this.domConverter.registerRawContentMatcher(pattern);\n    }\n    /**\n\t * If the processor is set to use marked fillers, it will insert `&nbsp;` fillers wrapped in `<span>` elements\n\t * (`<span data-cke-filler=\"true\">&nbsp;</span>`) instead of regular `&nbsp;` characters.\n\t *\n\t * This mode allows for a more precise handling of the block fillers (so they do not leak into the editor content) but\n\t * bloats the editor data with additional markup.\n\t *\n\t * This mode may be required by some features and will be turned on by them automatically.\n\t *\n\t * @param type Whether to use the default or the marked `&nbsp;` block fillers.\n\t */ useFillerType(type) {\n        this.domConverter.blockFillerMode = type == 'marked' ? 'markedNbsp' : 'nbsp';\n    }\n    /**\n\t * Converts an HTML string to its DOM representation. Returns a document fragment containing nodes parsed from\n\t * the provided data.\n\t */ _toDom(data) {\n        // Wrap data with a <body> tag so leading non-layout nodes (like <script>, <style>, HTML comment)\n        // will be preserved in the body collection.\n        // Do it only for data that is not a full HTML document.\n        if (!/<(?:html|body|head|meta)(?:\\s[^>]*)?>/i.test(data.trim().slice(0, 10_000))) {\n            data = `<body>${data}</body>`;\n        }\n        const document = this.domParser.parseFromString(data, 'text/html');\n        const fragment = document.createDocumentFragment();\n        const bodyChildNodes = document.body.childNodes;\n        while(bodyChildNodes.length > 0){\n            fragment.appendChild(bodyChildNodes[0]);\n        }\n        return fragment;\n    }\n}\n\n/**\n * Controller for the data pipeline. The data pipeline controls how data is retrieved from the document\n * and set inside it. Hence, the controller features two methods which allow to {@link ~DataController#get get}\n * and {@link ~DataController#set set} data of the {@link ~DataController#model model}\n * using the given:\n *\n * * {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor},\n * * downcast converters,\n * * upcast converters.\n *\n * An instance of the data controller is always available in the {@link module:core/editor/editor~Editor#data `editor.data`}\n * property:\n *\n * ```ts\n * editor.data.get( { rootName: 'customRoot' } ); // -> '<p>Hello!</p>'\n * ```\n */ class DataController extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * Data model.\n\t */ model;\n    /**\n\t * Mapper used for the conversion. It has no permanent bindings, because these are created while getting data and\n\t * are cleared directly after the data are converted. However, the mapper is defined as a class property, because\n\t * it needs to be passed to the `DowncastDispatcher` as a conversion API.\n\t */ mapper;\n    /**\n\t * Downcast dispatcher used by the {@link #get get method}. Downcast converters should be attached to it.\n\t */ downcastDispatcher;\n    /**\n\t * Upcast dispatcher used by the {@link #set set method}. Upcast converters should be attached to it.\n\t */ upcastDispatcher;\n    /**\n\t * The view document used by the data controller.\n\t */ viewDocument;\n    /**\n\t * Styles processor used during the conversion.\n\t */ stylesProcessor;\n    /**\n\t * Data processor used specifically for HTML conversion.\n\t */ htmlProcessor;\n    /**\n\t * Data processor used during the conversion.\n\t * Same instance as {@link #htmlProcessor} by default. Can be replaced at run time to handle different format, e.g. XML or Markdown.\n\t */ processor;\n    /**\n\t * The view downcast writer just for data conversion purposes, i.e. to modify\n\t * the {@link #viewDocument}.\n\t */ _viewWriter;\n    /**\n\t * Creates a data controller instance.\n\t *\n\t * @param model Data model.\n\t * @param stylesProcessor The styles processor instance.\n\t */ constructor(model, stylesProcessor){\n        super();\n        this.model = model;\n        this.mapper = new Mapper();\n        this.downcastDispatcher = new DowncastDispatcher({\n            mapper: this.mapper,\n            schema: model.schema\n        });\n        this.downcastDispatcher.on('insert:$text', insertText(), {\n            priority: 'lowest'\n        });\n        this.downcastDispatcher.on('insert', insertAttributesAndChildren(), {\n            priority: 'lowest'\n        });\n        this.upcastDispatcher = new UpcastDispatcher({\n            schema: model.schema\n        });\n        this.viewDocument = new Document$1(stylesProcessor);\n        this.stylesProcessor = stylesProcessor;\n        this.htmlProcessor = new HtmlDataProcessor(this.viewDocument);\n        this.processor = this.htmlProcessor;\n        this._viewWriter = new DowncastWriter(this.viewDocument);\n        // Define default converters for text and elements.\n        //\n        // Note that if there is no default converter for the element it will be skipped, for instance `<b>foo</b>` will be\n        // converted to nothing. We therefore add `convertToModelFragment` as a last converter so it converts children of that\n        // element to the document fragment so `<b>foo</b>` will still be converted to `foo` even if there is no converter for `<b>`.\n        this.upcastDispatcher.on('text', convertText(), {\n            priority: 'lowest'\n        });\n        this.upcastDispatcher.on('element', convertToModelFragment$1(), {\n            priority: 'lowest'\n        });\n        this.upcastDispatcher.on('documentFragment', convertToModelFragment$1(), {\n            priority: 'lowest'\n        });\n        ObservableMixin().prototype.decorate.call(this, 'init');\n        ObservableMixin().prototype.decorate.call(this, 'set');\n        ObservableMixin().prototype.decorate.call(this, 'get');\n        ObservableMixin().prototype.decorate.call(this, 'toView');\n        ObservableMixin().prototype.decorate.call(this, 'toModel');\n        // Fire the `ready` event when the initialization has completed. Such low-level listener offers the possibility\n        // to plug into the initialization pipeline without interrupting the initialization flow.\n        this.on('init', ()=>{\n            this.fire('ready');\n        }, {\n            priority: 'lowest'\n        });\n        // Fix empty roots after DataController is 'ready' (note that the init method could be decorated and stopped).\n        // We need to handle this event because initial data could be empty and the post-fixer would not get triggered.\n        this.on('ready', ()=>{\n            this.model.enqueueChange({\n                isUndoable: false\n            }, autoParagraphEmptyRoots);\n        }, {\n            priority: 'lowest'\n        });\n    }\n    /**\n\t * Returns the model's data converted by downcast dispatchers attached to {@link #downcastDispatcher} and\n\t * formatted by the {@link #processor data processor}.\n\t *\n\t * A warning is logged when you try to retrieve data for a detached root, as most probably this is a mistake. A detached root should\n\t * be treated like it is removed, and you should not save its data. Note, that the detached root data is always an empty string.\n\t *\n\t * @fires get\n\t * @param options Additional configuration for the retrieved data. `DataController` provides two optional\n\t * properties: `rootName` and `trim`. Other properties of this object are specified by various editor features.\n\t * @param options.rootName Root name. Default 'main'.\n\t * @param options.trim Whether returned data should be trimmed. This option is set to `empty` by default,\n\t * which means whenever editor content is considered empty, an empty string will be returned. To turn off trimming completely\n\t * use `'none'`. In such cases the exact content will be returned (for example a `<p>&nbsp;</p>` for an empty editor).\n\t * @returns Output data.\n\t */ get(options = {}) {\n        const { rootName = 'main', trim = 'empty' } = options;\n        if (!this._checkIfRootsExists([\n            rootName\n        ])) {\n            /**\n\t\t\t * Cannot get data from a non-existing root. This error is thrown when\n\t\t\t * {@link module:engine/controller/datacontroller~DataController#get `DataController#get()` method}\n\t\t\t * is called with a non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link module:engine/controller/datacontroller~DataController#get} like:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * data.get( { rootName: 'root2' } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-get-non-existent-root\n\t\t\t */ throw new CKEditorError('datacontroller-get-non-existent-root', this);\n        }\n        const root = this.model.document.getRoot(rootName);\n        if (!root.isAttached()) {\n            /**\n\t\t\t * Retrieving document data for a detached root.\n\t\t\t *\n\t\t\t * This usually indicates an error as a detached root should be considered \"removed\" and should not be included in the\n\t\t\t * document data.\n\t\t\t *\n\t\t\t * @error datacontroller-get-detached-root\n\t\t\t */ logWarning('datacontroller-get-detached-root', this);\n        }\n        if (trim === 'empty' && !this.model.hasContent(root, {\n            ignoreWhitespaces: true\n        })) {\n            return '';\n        }\n        return this.stringify(root, options);\n    }\n    /**\n\t * Returns the content of the given {@link module:engine/model/element~Element model's element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast converters\n\t * attached to the {@link #downcastDispatcher} and formatted by the {@link #processor data processor}.\n\t *\n\t * @param modelElementOrFragment The element whose content will be stringified.\n\t * @param options Additional configuration passed to the conversion process.\n\t * @returns Output data.\n\t */ stringify(modelElementOrFragment, options = {}) {\n        // Model -> view.\n        const viewDocumentFragment = this.toView(modelElementOrFragment, options);\n        // View -> data.\n        return this.processor.toData(viewDocumentFragment);\n    }\n    /**\n\t * Returns the content of the given {@link module:engine/model/element~Element model element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast\n\t * converters attached to {@link #downcastDispatcher} into a\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.\n\t *\n\t * @fires toView\n\t * @param modelElementOrFragment Element or document fragment whose content will be converted.\n\t * @param options Additional configuration that will be available through the\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi#options} during the conversion process.\n\t * @returns Output view DocumentFragment.\n\t */ toView(modelElementOrFragment, options = {}) {\n        const viewDocument = this.viewDocument;\n        const viewWriter = this._viewWriter;\n        // Clear bindings so the call to this method returns correct results.\n        this.mapper.clearBindings();\n        // First, convert elements.\n        const modelRange = Range._createIn(modelElementOrFragment);\n        const viewDocumentFragment = new DocumentFragment$1(viewDocument);\n        this.mapper.bindElements(modelElementOrFragment, viewDocumentFragment);\n        // Prepare list of markers.\n        // For document fragment, simply take the markers assigned to this document fragment.\n        // For model root, all markers in that root will be taken.\n        // For model element, we need to check which markers are intersecting with this element and relatively modify the markers' ranges.\n        // Collapsed markers at element boundary, although considered as not intersecting with the element, will also be returned.\n        const markers = modelElementOrFragment.is('documentFragment') ? modelElementOrFragment.markers : _getMarkersRelativeToElement(modelElementOrFragment);\n        this.downcastDispatcher.convert(modelRange, markers, viewWriter, options);\n        return viewDocumentFragment;\n    }\n    /**\n\t * Sets the initial input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * Initial data can be only set to a document whose {@link module:engine/model/document~Document#version} is equal 0.\n\t *\n\t * **Note** This method is {@link module:utils/observablemixin~Observable#decorate decorated} which is\n\t * used by e.g. collaborative editing plugin that syncs remote data on init.\n\t *\n\t * When data is passed as a string, it is initialized on the default `main` root:\n\t *\n\t * ```ts\n\t * dataController.init( '<p>Foo</p>' ); // Initializes data on the `main` root only, as no other is specified.\n\t * ```\n\t *\n\t * To initialize data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:\n\t *\n\t * ```ts\n\t * dataController.init( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Initializes data on both the `main` and `title` roots.\n\t * ```\n\t *\n\t * @fires init\n\t * @param data Input data as a string or an object containing the `rootName` - `data`\n\t * pairs to initialize data on multiple roots at once.\n\t * @returns Promise that is resolved after the data is set on the editor.\n\t */ init(data) {\n        if (this.model.document.version) {\n            /**\n\t\t\t * Cannot set initial data to a non-empty {@link module:engine/model/document~Document}.\n\t\t\t * Initial data should be set once, during the {@link module:core/editor/editor~Editor} initialization,\n\t\t\t * when the {@link module:engine/model/document~Document#version} is equal 0.\n\t\t\t *\n\t\t\t * @error datacontroller-init-document-not-empty\n\t\t\t */ throw new CKEditorError('datacontroller-init-document-not-empty', this);\n        }\n        let initialData = {};\n        if (typeof data === 'string') {\n            initialData.main = data; // Default root is 'main'. To initiate data on a different root, object should be passed.\n        } else {\n            initialData = data;\n        }\n        if (!this._checkIfRootsExists(Object.keys(initialData))) {\n            /**\n\t\t\t * Cannot init data on a non-existent root. This error is thrown when\n\t\t\t * {@link module:engine/controller/datacontroller~DataController#init DataController#init() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link module:engine/controller/datacontroller~DataController#init} like:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * data.init( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-init-non-existent-root\n\t\t\t */ throw new CKEditorError('datacontroller-init-non-existent-root', this);\n        }\n        this.model.enqueueChange({\n            isUndoable: false\n        }, (writer)=>{\n            for (const rootName of Object.keys(initialData)){\n                const modelRoot = this.model.document.getRoot(rootName);\n                writer.insert(this.parse(initialData[rootName], modelRoot), modelRoot, 0);\n            }\n        });\n        return Promise.resolve();\n    }\n    /**\n\t * Sets the input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * This method can be used any time to replace existing editor data with the new one without clearing the\n\t * {@link module:engine/model/document~Document#history document history}.\n\t *\n\t * This method also creates a batch with all the changes applied. If all you need is to parse data, use\n\t * the {@link #parse} method.\n\t *\n\t * When data is passed as a string it is set on the default `main` root:\n\t *\n\t * ```ts\n\t * dataController.set( '<p>Foo</p>' ); // Sets data on the `main` root, as no other is specified.\n\t * ```\n\t *\n\t * To set data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:\n\t *\n\t * ```ts\n\t * dataController.set( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Sets data on the `main` and `title` roots as specified.\n\t * ```\n\t *\n\t * To set the data with a preserved undo stack and add the change to the undo stack, set `{ isUndoable: true }` as a `batchType` option.\n\t *\n\t * ```ts\n\t * dataController.set( '<p>Foo</p>', { batchType: { isUndoable: true } } );\n\t * ```\n\t *\n\t * @fires set\n\t * @param data Input data as a string or an object containing the `rootName` - `data`\n\t * pairs to set data on multiple roots at once.\n\t * @param options Options for setting data.\n\t * @param options.batchType The batch type that will be used to create a batch for the changes applied by this method.\n\t * By default, the batch will be set as {@link module:engine/model/batch~Batch#isUndoable not undoable} and the undo stack will be\n\t * cleared after the new data is applied (all undo steps will be removed). If the batch type `isUndoable` flag is be set to `true`,\n\t * the undo stack will be preserved instead and not cleared when new data is applied.\n\t */ set(data, options = {}) {\n        let newData = {};\n        if (typeof data === 'string') {\n            newData.main = data; // The default root is 'main'. To set data on a different root, an object should be passed.\n        } else {\n            newData = data;\n        }\n        if (!this._checkIfRootsExists(Object.keys(newData))) {\n            /**\n\t\t\t * Cannot set data on a non-existent root. This error is thrown when the\n\t\t\t * {@link module:engine/controller/datacontroller~DataController#set DataController#set() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only the default `main` root,\n\t\t\t * calling {@link module:engine/controller/datacontroller~DataController#set} like:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * data.set( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-set-non-existent-root\n\t\t\t */ throw new CKEditorError('datacontroller-set-non-existent-root', this);\n        }\n        this.model.enqueueChange(options.batchType || {}, (writer)=>{\n            writer.setSelection(null);\n            writer.removeSelectionAttribute(this.model.document.selection.getAttributeKeys());\n            for (const rootName of Object.keys(newData)){\n                // Save to model.\n                const modelRoot = this.model.document.getRoot(rootName);\n                writer.remove(writer.createRangeIn(modelRoot));\n                writer.insert(this.parse(newData[rootName], modelRoot), modelRoot, 0);\n            }\n        });\n    }\n    /**\n\t * Returns the data parsed by the {@link #processor data processor} and then converted by upcast converters\n\t * attached to the {@link #upcastDispatcher}.\n\t *\n\t * @see #set\n\t * @param data Data to parse.\n\t * @param context Base context in which the view will be converted to the model.\n\t * See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns Parsed data.\n\t */ parse(data, context = '$root') {\n        // data -> view\n        const viewDocumentFragment = this.processor.toView(data);\n        // view -> model\n        return this.toModel(viewDocumentFragment, context);\n    }\n    /**\n\t * Returns the result of the given {@link module:engine/view/element~Element view element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment} converted by the\n\t * {@link #upcastDispatcher view-to-model converters}, wrapped by {@link module:engine/model/documentfragment~DocumentFragment}.\n\t *\n\t * When marker elements were converted during the conversion process, it will be set as a document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t *\n\t * @fires toModel\n\t * @param viewElementOrFragment The element or document fragment whose content will be converted.\n\t * @param context Base context in which the view will be converted to the model.\n\t * See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns Output document fragment.\n\t */ toModel(viewElementOrFragment, context = '$root') {\n        return this.model.change((writer)=>{\n            return this.upcastDispatcher.convert(viewElementOrFragment, writer, context);\n        });\n    }\n    /**\n\t * Adds the style processor normalization rules.\n\t *\n\t * You can implement your own rules as well as use one of the available processor rules:\n\t *\n\t * * background: {@link module:engine/view/styles/background~addBackgroundRules}\n\t * * border: {@link module:engine/view/styles/border~addBorderRules}\n\t * * margin: {@link module:engine/view/styles/margin~addMarginRules}\n\t * * padding: {@link module:engine/view/styles/padding~addPaddingRules}\n\t */ addStyleProcessorRules(callback) {\n        callback(this.stylesProcessor);\n    }\n    /**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} on an {@link #htmlProcessor htmlProcessor}\n\t * and a {@link #processor processor} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from DOM to view elements.\n\t *\n\t * The raw data can be later accessed by the {@link module:engine/view/element~Element#getCustomProperty view element custom property}\n\t * `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching all view elements whose content should be treated as a raw data.\n\t */ registerRawContentMatcher(pattern) {\n        // No need to register the pattern if both the `htmlProcessor` and `processor` are the same instances.\n        if (this.processor && this.processor !== this.htmlProcessor) {\n            this.processor.registerRawContentMatcher(pattern);\n        }\n        this.htmlProcessor.registerRawContentMatcher(pattern);\n    }\n    /**\n\t * Removes all event listeners set by the DataController.\n\t */ destroy() {\n        this.stopListening();\n    }\n    /**\n\t * Checks whether all provided root names are actually existing editor roots.\n\t *\n\t * @param rootNames Root names to check.\n\t * @returns Whether all provided root names are existing editor roots.\n\t */ _checkIfRootsExists(rootNames) {\n        for (const rootName of rootNames){\n            if (!this.model.document.getRoot(rootName)) {\n                return false;\n            }\n        }\n        return true;\n    }\n}\n/**\n * Helper function for downcast conversion.\n *\n * Takes a document element (element that is added to a model document) and checks which markers are inside it. If the marker is collapsed\n * at element boundary, it is considered as contained inside the element and marker range is returned. Otherwise, if the marker is\n * intersecting with the element, the intersection is returned.\n */ function _getMarkersRelativeToElement(element) {\n    const result = [];\n    const doc = element.root.document;\n    if (!doc) {\n        return new Map();\n    }\n    const elementRange = Range._createIn(element);\n    for (const marker of doc.model.markers){\n        const markerRange = marker.getRange();\n        const isMarkerCollapsed = markerRange.isCollapsed;\n        const isMarkerAtElementBoundary = markerRange.start.isEqual(elementRange.start) || markerRange.end.isEqual(elementRange.end);\n        if (isMarkerCollapsed && isMarkerAtElementBoundary) {\n            result.push([\n                marker.name,\n                markerRange\n            ]);\n        } else {\n            const updatedMarkerRange = elementRange.getIntersection(markerRange);\n            if (updatedMarkerRange) {\n                result.push([\n                    marker.name,\n                    updatedMarkerRange\n                ]);\n            }\n        }\n    }\n    // Sort the markers in a stable fashion to ensure that the order in which they are\n    // added to the model's marker collection does not affect how they are\n    // downcast. One particular use case that we are targeting here, is one where\n    // two markers are adjacent but not overlapping, such as an insertion/deletion\n    // suggestion pair representing the replacement of a range of text. In this\n    // case, putting the markers in DOM order causes the first marker's end to be\n    // serialized right after the second marker's start, while putting the markers\n    // in reverse DOM order causes it to be right before the second marker's\n    // start. So, we sort these in a way that ensures non-intersecting ranges are in\n    // reverse DOM order, and intersecting ranges are in something approximating\n    // reverse DOM order (since reverse DOM order doesn't have a precise meaning\n    // when working with intersecting ranges).\n    result.sort(([n1, r1], [n2, r2])=>{\n        if (r1.end.compareWith(r2.start) !== 'after') {\n            // m1.end <= m2.start -- m1 is entirely <= m2\n            return 1;\n        } else if (r1.start.compareWith(r2.end) !== 'before') {\n            // m1.start >= m2.end -- m1 is entirely >= m2\n            return -1;\n        } else {\n            // they overlap, so use their start positions as the primary sort key and\n            // end positions as the secondary sort key\n            switch(r1.start.compareWith(r2.start)){\n                case 'before':\n                    return 1;\n                case 'after':\n                    return -1;\n                default:\n                    switch(r1.end.compareWith(r2.end)){\n                        case 'before':\n                            return 1;\n                        case 'after':\n                            return -1;\n                        default:\n                            return n2.localeCompare(n1);\n                    }\n            }\n        }\n    });\n    return new Map(result);\n}\n\n/**\n * A utility class that helps add converters to upcast and downcast dispatchers.\n *\n * We recommend reading the {@glink framework/deep-dive/conversion/intro editor conversion} guide first to\n * understand the core concepts of the conversion mechanisms.\n *\n * An instance of the conversion manager is available in the\n * {@link module:core/editor/editor~Editor#conversion `editor.conversion`} property\n * and by default has the following groups of dispatchers (i.e. directions of conversion):\n *\n * * `downcast` (editing and data downcasts)\n * * `editingDowncast`\n * * `dataDowncast`\n * * `upcast`\n *\n * # One-way converters\n *\n * To add a converter to a specific group, use the {@link module:engine/conversion/conversion~Conversion#for `for()`}\n * method:\n *\n * ```ts\n * // Add a converter to editing downcast and data downcast.\n * editor.conversion.for( 'downcast' ).elementToElement( config ) );\n *\n * // Add a converter to the data pipepline only:\n * editor.conversion.for( 'dataDowncast' ).elementToElement( dataConversionConfig ) );\n *\n * // And a slightly different one for the editing pipeline:\n * editor.conversion.for( 'editingDowncast' ).elementToElement( editingConversionConfig ) );\n * ```\n *\n * See {@link module:engine/conversion/conversion~Conversion#for `for()`} method documentation to learn more about\n * available conversion helpers and how to use your custom ones.\n *\n * # Two-way converters\n *\n * Besides using one-way converters via the `for()` method, you can also use other methods available in this\n * class to add two-way converters (upcast and downcast):\n *\n * * {@link module:engine/conversion/conversion~Conversion#elementToElement `elementToElement()`} &ndash;\n * Model element to view element and vice versa.\n * * {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement()`} &ndash;\n * Model attribute to view element and vice versa.\n * * {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `attributeToAttribute()`} &ndash;\n * Model attribute to view attribute and vice versa.\n */ class Conversion {\n    /**\n\t * Maps dispatchers group name to ConversionHelpers instances.\n\t */ _helpers = new Map();\n    _downcast;\n    _upcast;\n    /**\n\t * Creates a new conversion instance.\n\t */ constructor(downcastDispatchers, upcastDispatchers){\n        // Define default 'downcast' & 'upcast' dispatchers groups. Those groups are always available as two-way converters needs them.\n        this._downcast = toArray(downcastDispatchers);\n        this._createConversionHelpers({\n            name: 'downcast',\n            dispatchers: this._downcast,\n            isDowncast: true\n        });\n        this._upcast = toArray(upcastDispatchers);\n        this._createConversionHelpers({\n            name: 'upcast',\n            dispatchers: this._upcast,\n            isDowncast: false\n        });\n    }\n    /**\n\t * Define an alias for registered dispatcher.\n\t *\n\t * ```ts\n\t * const conversion = new Conversion(\n\t * \t[ dataDowncastDispatcher, editingDowncastDispatcher ],\n\t * \tupcastDispatcher\n\t * );\n\t *\n\t * conversion.addAlias( 'dataDowncast', dataDowncastDispatcher );\n\t * ```\n\t *\n\t * @param alias An alias of a dispatcher.\n\t * @param dispatcher Dispatcher which should have an alias.\n\t */ addAlias(alias, dispatcher) {\n        const isDowncast = this._downcast.includes(dispatcher);\n        const isUpcast = this._upcast.includes(dispatcher);\n        if (!isUpcast && !isDowncast) {\n            /**\n\t\t\t * Trying to register an alias for a dispatcher that nas not been registered.\n\t\t\t *\n\t\t\t * @error conversion-add-alias-dispatcher-not-registered\n\t\t\t */ throw new CKEditorError('conversion-add-alias-dispatcher-not-registered', this);\n        }\n        this._createConversionHelpers({\n            name: alias,\n            dispatchers: [\n                dispatcher\n            ],\n            isDowncast\n        });\n    }\n    /**\n\t * Provides a chainable API to assign converters to a conversion dispatchers group.\n\t *\n\t * If the given group name has not been registered, the\n\t * {@link module:utils/ckeditorerror~CKEditorError `conversion-for-unknown-group` error} is thrown.\n\t *\n\t * You can use conversion helpers available directly in the `for()` chain or your custom ones via\n\t * the {@link module:engine/conversion/conversionhelpers~ConversionHelpers#add `add()`} method.\n\t *\n\t * # Using built-in conversion helpers\n\t *\n\t * The `for()` chain comes with a set of conversion helpers which you can use like this:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' )\n\t * \t.elementToElement( config1 )        // Adds an element-to-element downcast converter.\n\t * \t.attributeToElement( config2 );     // Adds an attribute-to-element downcast converter.\n\t *\n\t * editor.conversion.for( 'upcast' )\n\t * \t.elementToAttribute( config3 );     // Adds an element-to-attribute upcast converter.\n\t * ```\n\t *\n\t * Refer to the documentation of built-in conversion helpers to learn about their configuration options.\n\t *\n\t * * downcast (model-to-view) conversion helpers:\n\t *\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`},\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement `attributeToElement()`},\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToElement `markerToElement()`}.\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToHighlight `markerToHighlight()`}.\n\t *\n\t * * upcast (view-to-model) conversion helpers:\n\t *\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `elementToElement()`},\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute `elementToAttribute()`},\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToMarker `elementToMarker()`}.\n\t *\n\t * # Using custom conversion helpers\n\t *\n\t * If you need to implement an atypical converter, you can do so by calling:\n\t *\n\t * ```ts\n\t * editor.conversion.for( direction ).add( customHelper );\n\t * ```\n\t *\n\t * The `.add()` method takes exactly one parameter, which is a function. This function should accept one parameter that\n\t * is a dispatcher instance. The function should add an actual converter to the passed dispatcher instance.\n\t *\n\t * Example:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).add( dispatcher => {\n\t * \tdispatcher.on( 'element:a',  ( evt, data, conversionApi ) => {\n\t * \t\t// Do something with a view <a> element.\n\t * \t} );\n\t * } );\n\t * ```\n\t *\n\t * Refer to the documentation of {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}\n\t * and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} to learn how to write\n\t * custom converters.\n\t *\n\t * @param groupName The name of dispatchers group to add the converters to.\n\t */ for(groupName) {\n        if (!this._helpers.has(groupName)) {\n            /**\n\t\t\t * Trying to add a converter to an unknown dispatchers group.\n\t\t\t *\n\t\t\t * @error conversion-for-unknown-group\n\t\t\t */ throw new CKEditorError('conversion-for-unknown-group', this);\n        }\n        return this._helpers.get(groupName);\n    }\n    /**\n\t * Sets up converters between the model and the view that convert a model element to a view element (and vice versa).\n\t * For example, the model `<paragraph>Foo</paragraph>` is turned into `<p>Foo</p>` in the view.\n\t *\n\t * ```ts\n\t * // A simple conversion from the `paragraph` model element to the `<p>` view element (and vice versa).\n\t * editor.conversion.elementToElement( { model: 'paragraph', view: 'p' } );\n\t *\n\t * // Override other converters by specifying a converter definition with a higher priority.\n\t * editor.conversion.elementToElement( { model: 'paragraph', view: 'div', converterPriority: 'high' } );\n\t *\n\t * // View specified as an object instead of a string.\n\t * editor.conversion.elementToElement( {\n\t * \tmodel: 'fancyParagraph',\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'fancy'\n\t * \t}\n\t * } );\n\t *\n\t * // Use `upcastAlso` to define other view elements that should also be converted to a `paragraph` element.\n\t * editor.conversion.elementToElement( {\n\t * \tmodel: 'paragraph',\n\t * \tview: 'p',\n\t * \tupcastAlso: [\n\t * \t\t'div',\n\t * \t\t{\n\t * \t\t\t// Any element with the `display: block` style.\n\t * \t\t\tstyles: {\n\t * \t\t\t\tdisplay: 'block'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t]\n\t * } );\n\t *\n\t * // `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t * editor.conversion.elementToElement( {\n\t * \tmodel: 'heading',\n\t * \tview: 'h2',\n\t * \t// Convert \"heading-like\" paragraphs to headings.\n\t * \tupcastAlso: viewElement => {\n\t * \t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t * \t\tif ( !fontSize ) {\n\t * \t\t\treturn null;\n\t * \t\t}\n\t *\n\t * \t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t * \t\tif ( !match ) {\n\t * \t\t\treturn null;\n\t * \t\t}\n\t *\n\t * \t\tconst size = Number( match[ 1 ] );\n\t *\n\t * \t\tif ( size > 26 ) {\n\t * \t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t * \t\t}\n\t *\n\t * \t\treturn null;\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * `definition.model` is a `String` with a model element name to convert from or to.\n\t *\n\t * @param definition The converter definition.\n\t */ elementToElement(definition) {\n        // Set up downcast converter.\n        this.for('downcast').elementToElement(definition);\n        // Set up upcast converter.\n        for (const { model, view } of _getAllUpcastDefinitions(definition)){\n            this.for('upcast').elementToElement({\n                model,\n                view,\n                converterPriority: definition.converterPriority\n            });\n        }\n    }\n    /**\n\t * Sets up converters between the model and the view that convert a model attribute to a view element (and vice versa).\n\t * For example, a model text node with `\"Foo\"` as data and the `bold` attribute will be turned to `<strong>Foo</strong>` in the view.\n\t *\n\t * ```ts\n\t * // A simple conversion from the `bold=true` attribute to the `<strong>` view element (and vice versa).\n\t * editor.conversion.attributeToElement( { model: 'bold', view: 'strong' } );\n\t *\n\t * // Override other converters by specifying a converter definition with a higher priority.\n\t * editor.conversion.attributeToElement( { model: 'bold', view: 'b', converterPriority: 'high' } );\n\t *\n\t * // View specified as an object instead of a string.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: 'bold'\n\t * \t}\n\t * } );\n\t *\n\t * // Use `config.model.name` to define the conversion only from a given node type, `$text` in this case.\n\t * // The same attribute on different elements may then be handled by a different converter.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'textDecoration',\n\t * \t\tvalues: [ 'underline', 'lineThrough' ],\n\t * \t\tname: '$text'\n\t * \t},\n\t * \tview: {\n\t * \t\tunderline: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-decoration': 'underline'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tlineThrough: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-decoration': 'line-through'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * // Use `upcastAlso` to define other view elements that should also be converted to the `bold` attribute.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: 'strong',\n\t * \tupcastAlso: [\n\t * \t\t'b',\n\t * \t\t{\n\t * \t\t\tname: 'span',\n\t * \t\t\tclasses: 'bold'\n\t * \t\t},\n\t * \t\t{\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-weight': 'bold'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tviewElement => {\n\t * \t\t\tconst fontWeight = viewElement.getStyle( 'font-weight' );\n\t *\n\t * \t\t\tif ( viewElement.is( 'element', 'span' ) && fontWeight && /\\d+/.test() && Number( fontWeight ) > 500 ) {\n\t * \t\t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\t\treturn {\n\t * \t\t\t\t\tname: true,\n\t * \t\t\t\t\tstyles: [ 'font-weight' ]\n\t * \t\t\t\t};\n\t * \t\t\t}\n\t * \t\t}\n\t * \t]\n\t * } );\n\t *\n\t * // Conversion from and to a model attribute key whose value is an enum (`fontSize=big|small`).\n\t * // `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'fontSize',\n\t * \t\tvalues: [ 'big', 'small' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tbig: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '1.2em'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tsmall: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '0.8em'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t},\n\t * \tupcastAlso: {\n\t * \t\tbig: viewElement => {\n\t * \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t * \t\t\tif ( !fontSize ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t * \t\t\tif ( !match ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst size = Number( match[ 1 ] );\n\t *\n\t * \t\t\tif ( viewElement.is( 'element', 'span' ) && size > 10 ) {\n\t * \t\t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t * \t\t\t}\n\t *\n\t * \t\t\treturn null;\n\t * \t\t},\n\t * \t\tsmall: viewElement => {\n\t * \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t * \t\t\tif ( !fontSize ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t * \t\t\tif ( !match ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst size = Number( match[ 1 ] );\n\t *\n\t * \t\t\tif ( viewElement.is( 'element', 'span' ) && size < 10 ) {\n\t * \t\t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t * \t\t\t}\n\t *\n\t * \t\t\treturn null;\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * The `definition.model` parameter specifies which model attribute should be converted from or to. It can be a `{ key, value }` object\n\t * describing the attribute key and value to convert or a `String` specifying just the attribute key (in such a case\n\t * `value` is set to `true`).\n\t *\n\t * @param definition The converter definition.\n\t */ attributeToElement(definition) {\n        // Set up downcast converter.\n        this.for('downcast').attributeToElement(definition);\n        // Set up upcast converter.\n        for (const { model, view } of _getAllUpcastDefinitions(definition)){\n            this.for('upcast').elementToAttribute({\n                view,\n                model,\n                converterPriority: definition.converterPriority\n            });\n        }\n    }\n    /**\n\t * Sets up converters between the model and the view that convert a model attribute to a view attribute (and vice versa). For example,\n\t * `<imageBlock src='foo.jpg'></imageBlock>` is converted to `<img src='foo.jpg'></img>` (the same attribute key and value).\n\t * This type of converters is intended to be used with {@link module:engine/model/element~Element model element} nodes.\n\t * To convert the text attributes,\n\t * the {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement converter`}should be set up.\n\t *\n\t * ```ts\n\t * // A simple conversion from the `source` model attribute to the `src` view attribute (and vice versa).\n\t * editor.conversion.attributeToAttribute( { model: 'source', view: 'src' } );\n\t *\n\t * // Attribute values are strictly specified.\n\t * editor.conversion.attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'imageInline',\n\t * \t\tkey: 'aside',\n\t * \t\tvalues: [ 'aside' ]\n\t * \t},\n\t * \tview: {\n\t * \t\taside: {\n\t * \t\t\tname: 'img',\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: [ 'aside', 'half-size' ]\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * // Set the style attribute.\n\t * editor.conversion.attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'imageInline',\n\t * \t\tkey: 'aside',\n\t * \t\tvalues: [ 'aside' ]\n\t * \t},\n\t * \tview: {\n\t * \t\taside: {\n\t * \t\t\tname: 'img',\n\t * \t\t\tkey: 'style',\n\t * \t\t\tvalue: {\n\t * \t\t\t\tfloat: 'right',\n\t * \t\t\t\twidth: '50%',\n\t * \t\t\t\tmargin: '5px'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * // Conversion from and to a model attribute key whose value is an enum (`align=right|center`).\n\t * // Use `upcastAlso` to define other view elements that should also be converted to the `align=right` attribute.\n\t * editor.conversion.attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tkey: 'align',\n\t * \t\tvalues: [ 'right', 'center' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tright: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: 'align-right'\n\t * \t\t},\n\t * \t\tcenter: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: 'align-center'\n\t * \t\t}\n\t * \t},\n\t * \tupcastAlso: {\n\t * \t\tright: {\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-align': 'right'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tcenter: {\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-align': 'center'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * The `definition.model` parameter specifies which model attribute should be converted from and to.\n\t * It can be a `{ key, [ values ], [ name ] }` object or a `String`, which will be treated like `{ key: definition.model }`.\n\t * The `key` property is the model attribute key to convert from and to.\n\t * The `values` are the possible model attribute values. If the `values` parameter is not set, the model attribute value\n\t * will be the same as the view attribute value.\n\t * If `name` is set, the conversion will be set up only for model elements with the given name.\n\t *\n\t * The `definition.view` parameter specifies which view attribute should be converted from and to.\n\t * It can be a `{ key, value, [ name ] }` object or a `String`, which will be treated like `{ key: definition.view }`.\n\t * The `key` property is the view attribute key to convert from and to.\n\t * The `value` is the view attribute value to convert from and to. If `definition.value` is not set, the view attribute value will be\n\t * the same as the model attribute value.\n\t * If `key` is `'class'`, `value` can be a `String` or an array of `String`s.\n\t * If `key` is `'style'`, `value` is an object with key-value pairs.\n\t * In other cases, `value` is a `String`.\n\t * If `name` is set, the conversion will be set up only for model elements with the given name.\n\t * If `definition.model.values` is set, `definition.view` is an object that assigns values from `definition.model.values`\n\t * to `{ key, value, [ name ] }` objects.\n\t *\n\t * `definition.upcastAlso` specifies which other matching view elements should also be upcast to the given model configuration.\n\t * If `definition.model.values` is set, `definition.upcastAlso` should be an object assigning values from `definition.model.values`\n\t * to {@link module:engine/view/matcher~MatcherPattern}s or arrays of {@link module:engine/view/matcher~MatcherPattern}s.\n\t *\n\t * **Note:** `definition.model` and `definition.view` form should be mirrored, so the same types of parameters should\n\t * be given in both parameters.\n\t *\n\t * @param definition The converter definition.\n\t * @param definition.model The model attribute to convert from and to.\n\t * @param definition.view The view attribute to convert from and to.\n\t * @param definition.upcastAlso Any view element matching `definition.upcastAlso` will also be converted to the given model attribute.\n\t * `definition.upcastAlso` is used only if `config.model.values` is specified.\n\t */ attributeToAttribute(definition) {\n        // Set up downcast converter.\n        this.for('downcast').attributeToAttribute(definition);\n        // Set up upcast converter.\n        for (const { model, view } of _getAllUpcastDefinitions(definition)){\n            this.for('upcast').attributeToAttribute({\n                view,\n                model\n            });\n        }\n    }\n    /**\n\t * Creates and caches conversion helpers for given dispatchers group.\n\t *\n\t * @param options.name Group name.\n\t */ _createConversionHelpers({ name, dispatchers, isDowncast }) {\n        if (this._helpers.has(name)) {\n            /**\n\t\t\t * Trying to register a group name that has already been registered.\n\t\t\t *\n\t\t\t * @error conversion-group-exists\n\t\t\t */ throw new CKEditorError('conversion-group-exists', this);\n        }\n        const helpers = isDowncast ? new DowncastHelpers(dispatchers) : new UpcastHelpers(dispatchers);\n        this._helpers.set(name, helpers);\n    }\n}\n/**\n * Helper function that creates a joint array out of an item passed in `definition.view` and items passed in\n * `definition.upcastAlso`.\n */ function* _getAllUpcastDefinitions(definition) {\n    if (definition.model.values) {\n        for (const value of definition.model.values){\n            const model = {\n                key: definition.model.key,\n                value\n            };\n            const view = definition.view[value];\n            const upcastAlso = definition.upcastAlso ? definition.upcastAlso[value] : undefined;\n            yield* _getUpcastDefinition(model, view, upcastAlso);\n        }\n    } else {\n        yield* _getUpcastDefinition(definition.model, definition.view, definition.upcastAlso);\n    }\n}\nfunction* _getUpcastDefinition(model, view, upcastAlso) {\n    yield {\n        model,\n        view\n    };\n    if (upcastAlso) {\n        for (const upcastAlsoItem of toArray(upcastAlso)){\n            yield {\n                model,\n                view: upcastAlsoItem\n            };\n        }\n    }\n}\n\n/**\n * The XML data processor class.\n * This data processor implementation uses XML as input and output data.\n * This class is needed because unlike HTML, XML allows to use any tag with any value.\n * For example, `<link>Text</link>` is a valid XML but invalid HTML.\n */ class XmlDataProcessor {\n    /**\n\t * A list of namespaces allowed to use in the XML input.\n\t *\n\t * For example, registering namespaces [ 'attribute', 'container' ] allows to use `<attirbute:tagName></attribute:tagName>`\n\t * and `<container:tagName></container:tagName>` input. It is mainly for debugging.\n\t */ namespaces;\n    /**\n\t * DOM parser instance used to parse an XML string to an XML document.\n\t */ domParser;\n    /**\n\t * DOM converter used to convert DOM elements to view elements.\n\t */ domConverter;\n    /**\n\t * A basic HTML writer instance used to convert DOM elements to an XML string.\n\t * There is no need to use a dedicated XML writer because the basic HTML writer works well in this case.\n\t */ htmlWriter;\n    skipComments = true;\n    /**\n\t * Creates a new instance of the XML data processor class.\n\t *\n\t * @param document The view document instance.\n\t * @param options Configuration options.\n\t * @param options.namespaces A list of namespaces allowed to use in the XML input.\n\t */ constructor(document, options = {}){\n        this.namespaces = options.namespaces || [];\n        this.domParser = new DOMParser();\n        this.domConverter = new DomConverter(document, {\n            renderingMode: 'data'\n        });\n        this.htmlWriter = new BasicHtmlWriter();\n    }\n    /**\n\t * Converts the provided {@link module:engine/view/documentfragment~DocumentFragment document fragment}\n\t * to data format &ndash; in this case an XML string.\n\t *\n\t * @returns An XML string.\n\t */ toData(viewFragment) {\n        // Convert view DocumentFragment to DOM DocumentFragment.\n        const domFragment = this.domConverter.viewToDom(viewFragment);\n        // Convert DOM DocumentFragment to XML output.\n        // There is no need to use dedicated for XML serializing method because BasicHtmlWriter works well in this case.\n        return this.htmlWriter.getHtml(domFragment);\n    }\n    /**\n\t * Converts the provided XML string to a view tree.\n\t *\n\t * @param data An XML string.\n\t * @returns A converted view element.\n\t */ toView(data) {\n        // Convert input XML data to DOM DocumentFragment.\n        const domFragment = this._toDom(data);\n        // Convert DOM DocumentFragment to view DocumentFragment.\n        return this.domConverter.domToView(domFragment, {\n            keepOriginalCase: true,\n            skipComments: this.skipComments\n        });\n    }\n    /**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from XML to view elements.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching all view elements whose content should be treated as raw data.\n\t */ registerRawContentMatcher(pattern) {\n        this.domConverter.registerRawContentMatcher(pattern);\n    }\n    /**\n\t * If the processor is set to use marked fillers, it will insert `&nbsp;` fillers wrapped in `<span>` elements\n\t * (`<span data-cke-filler=\"true\">&nbsp;</span>`) instead of regular `&nbsp;` characters.\n\t *\n\t * This mode allows for a more precise handling of block fillers (so they do not leak into editor content) but\n\t * bloats the editor data with additional markup.\n\t *\n\t * This mode may be required by some features and will be turned on by them automatically.\n\t *\n\t * @param type Whether to use the default or the marked `&nbsp;` block fillers.\n\t */ useFillerType(type) {\n        this.domConverter.blockFillerMode = type == 'marked' ? 'markedNbsp' : 'nbsp';\n    }\n    /**\n\t * Converts an XML string to its DOM representation. Returns a document fragment containing nodes parsed from\n\t * the provided data.\n\t */ _toDom(data) {\n        // Stringify namespaces.\n        const namespaces = this.namespaces.map((nsp)=>`xmlns:${nsp}=\"nsp\"`).join(' ');\n        // Wrap data into root element with optional namespace definitions.\n        data = `<xml ${namespaces}>${data}</xml>`;\n        const parsedDocument = this.domParser.parseFromString(data, 'text/xml');\n        // Parse validation.\n        const parserError = parsedDocument.querySelector('parsererror');\n        if (parserError) {\n            throw new Error('Parse error - ' + parserError.textContent);\n        }\n        const fragment = parsedDocument.createDocumentFragment();\n        const nodes = parsedDocument.documentElement.childNodes;\n        while(nodes.length > 0){\n            fragment.appendChild(nodes[0]);\n        }\n        return fragment;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /* eslint-disable @typescript-eslint/no-unused-vars */ /**\n * @module engine/model/operation/operation\n */ /**\n * Abstract base operation class.\n */ class Operation {\n    /**\n\t * {@link module:engine/model/document~Document#version} on which operation can be applied. If you try to\n\t * {@link module:engine/model/model~Model#applyOperation apply} operation with different base version than the\n\t * {@link module:engine/model/document~Document#version document version} the\n\t * {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.\n\t */ baseVersion;\n    /**\n\t * Defines whether operation is executed on attached or detached {@link module:engine/model/item~Item items}.\n\t */ isDocumentOperation;\n    /**\n\t * {@link module:engine/model/batch~Batch Batch} to which the operation is added or `null` if the operation is not\n\t * added to any batch yet.\n\t */ batch;\n    /**\n\t * Base operation constructor.\n\t *\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(baseVersion){\n        this.baseVersion = baseVersion;\n        this.isDocumentOperation = this.baseVersion !== null;\n        this.batch = null;\n    }\n    /**\n\t * Checks whether the operation's parameters are correct and the operation can be correctly executed. Throws\n\t * an error if operation is not valid.\n\t *\n\t * @internal\n\t */ _validate() {}\n    /**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns Clone of this object with the operation property replaced with string.\n\t */ toJSON() {\n        // This method creates only a shallow copy, all nested objects should be defined separately.\n        // See https://github.com/ckeditor/ckeditor5-engine/issues/1477.\n        const json = Object.assign({}, this);\n        json.__className = this.constructor.className;\n        // Remove reference to the parent `Batch` to avoid circular dependencies.\n        delete json.batch;\n        // Only document operations are shared with other clients so it is not necessary to keep this information.\n        delete json.isDocumentOperation;\n        return json;\n    }\n    /**\n\t * Name of the operation class used for serialization.\n\t */ static get className() {\n        return 'Operation';\n    }\n    /**\n\t * Creates `Operation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param doc Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        return new this(json.baseVersion);\n    }\n}\n\n/**\n * Inserts given nodes at given position.\n *\n * @internal\n * @param position Position at which nodes should be inserted.\n * @param normalizedNodes Nodes to insert.\n * @returns Range spanning over inserted elements.\n */ function _insert(position, nodes) {\n    const normalizedNodes = _normalizeNodes(nodes);\n    // We have to count offset before inserting nodes because they can get merged and we would get wrong offsets.\n    const offset = normalizedNodes.reduce((sum, node)=>sum + node.offsetSize, 0);\n    const parent = position.parent;\n    // Insertion might be in a text node, we should split it if that's the case.\n    _splitNodeAtPosition(position);\n    const index = position.index;\n    // Insert nodes at given index. After splitting we have a proper index and insertion is between nodes,\n    // using basic `Element` API.\n    parent._insertChild(index, normalizedNodes);\n    // Merge text nodes, if possible. Merging is needed only at points where inserted nodes \"touch\" \"old\" nodes.\n    _mergeNodesAtIndex(parent, index + normalizedNodes.length);\n    _mergeNodesAtIndex(parent, index);\n    return new Range(position, position.getShiftedBy(offset));\n}\n/**\n * Removed nodes in given range. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @internal\n * @param range Range containing nodes to remove.\n */ function _remove(range) {\n    if (!range.isFlat) {\n        /**\n\t\t * Trying to remove a range which starts and ends in different element.\n\t\t *\n\t\t * @error operation-utils-remove-range-not-flat\n\t\t */ throw new CKEditorError('operation-utils-remove-range-not-flat', this);\n    }\n    const parent = range.start.parent;\n    // Range may be inside text nodes, we have to split them if that's the case.\n    _splitNodeAtPosition(range.start);\n    _splitNodeAtPosition(range.end);\n    // Remove the text nodes using basic `Element` API.\n    const removed = parent._removeChildren(range.start.index, range.end.index - range.start.index);\n    // Merge text nodes, if possible. After some nodes were removed, node before and after removed range will be\n    // touching at the position equal to the removed range beginning. We check merging possibility there.\n    _mergeNodesAtIndex(parent, range.start.index);\n    return removed;\n}\n/**\n * Moves nodes in given range to given target position. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @internal\n * @param sourceRange Range containing nodes to move.\n * @param targetPosition Position to which nodes should be moved.\n * @returns Range containing moved nodes.\n */ function _move(sourceRange, targetPosition) {\n    if (!sourceRange.isFlat) {\n        /**\n\t\t * Trying to move a range which starts and ends in different element.\n\t\t *\n\t\t * @error operation-utils-move-range-not-flat\n\t\t */ throw new CKEditorError('operation-utils-move-range-not-flat', this);\n    }\n    const nodes = _remove(sourceRange);\n    // We have to fix `targetPosition` because model changed after nodes from `sourceRange` got removed and\n    // that change might have an impact on `targetPosition`.\n    targetPosition = targetPosition._getTransformedByDeletion(sourceRange.start, sourceRange.end.offset - sourceRange.start.offset);\n    return _insert(targetPosition, nodes);\n}\n/**\n * Sets given attribute on nodes in given range. The attributes are only set on top-level nodes of the range, not on its children.\n *\n * @internal\n * @param range Range containing nodes that should have the attribute set. Must be a flat range.\n * @param key Key of attribute to set.\n * @param value Attribute value.\n */ function _setAttribute(range, key, value) {\n    // Range might start or end in text nodes, so we have to split them.\n    _splitNodeAtPosition(range.start);\n    _splitNodeAtPosition(range.end);\n    // Iterate over all items in the range.\n    for (const item of range.getItems({\n        shallow: true\n    })){\n        // Iterator will return `TextProxy` instances but we know that those text proxies will\n        // always represent full text nodes (this is guaranteed thanks to splitting we did before).\n        // So, we can operate on those text proxies' text nodes.\n        const node = item.is('$textProxy') ? item.textNode : item;\n        if (value !== null) {\n            node._setAttribute(key, value);\n        } else {\n            node._removeAttribute(key);\n        }\n        // After attributes changing it may happen that some text nodes can be merged. Try to merge with previous node.\n        _mergeNodesAtIndex(node.parent, node.index);\n    }\n    // Try to merge last changed node with it's previous sibling (not covered by the loop above).\n    _mergeNodesAtIndex(range.end.parent, range.end.index);\n}\n/**\n * Normalizes given object or an array of objects to an array of {@link module:engine/model/node~Node nodes}. See\n * {@link ~NodeSet NodeSet} for details on how normalization is performed.\n *\n * @internal\n * @param nodes Objects to normalize.\n * @returns Normalized nodes.\n */ function _normalizeNodes(nodes) {\n    const normalized = [];\n    function convert(nodes) {\n        if (typeof nodes == 'string') {\n            normalized.push(new Text(nodes));\n        } else if (nodes instanceof TextProxy) {\n            normalized.push(new Text(nodes.data, nodes.getAttributes()));\n        } else if (nodes instanceof Node$1) {\n            normalized.push(nodes);\n        } else if (isIterable(nodes)) {\n            for (const node of nodes){\n                convert(node);\n            }\n        } else ;\n    }\n    convert(nodes);\n    // Merge text nodes.\n    for(let i = 1; i < normalized.length; i++){\n        const node = normalized[i];\n        const prev = normalized[i - 1];\n        if (node instanceof Text && prev instanceof Text && _haveSameAttributes(node, prev)) {\n            // Doing this instead changing `prev.data` because `data` is readonly.\n            normalized.splice(i - 1, 2, new Text(prev.data + node.data, prev.getAttributes()));\n            i--;\n        }\n    }\n    return normalized;\n}\n/**\n * Checks if nodes before and after given index in given element are {@link module:engine/model/text~Text text nodes} and\n * merges them into one node if they have same attributes.\n *\n * Merging is done by removing two text nodes and inserting a new text node containing data from both merged text nodes.\n *\n * @param element Parent element of nodes to merge.\n * @param index Index between nodes to merge.\n */ function _mergeNodesAtIndex(element, index) {\n    const nodeBefore = element.getChild(index - 1);\n    const nodeAfter = element.getChild(index);\n    // Check if both of those nodes are text objects with same attributes.\n    if (nodeBefore && nodeAfter && nodeBefore.is('$text') && nodeAfter.is('$text') && _haveSameAttributes(nodeBefore, nodeAfter)) {\n        // Append text of text node after index to the before one.\n        const mergedNode = new Text(nodeBefore.data + nodeAfter.data, nodeBefore.getAttributes());\n        // Remove separate text nodes.\n        element._removeChildren(index - 1, 2);\n        // Insert merged text node.\n        element._insertChild(index - 1, mergedNode);\n    }\n}\n/**\n * Checks if given position is in a text node, and if so, splits the text node in two text nodes, each of them\n * containing a part of original text node.\n *\n * @param position Position at which node should be split.\n */ function _splitNodeAtPosition(position) {\n    const textNode = position.textNode;\n    const element = position.parent;\n    if (textNode) {\n        const offsetDiff = position.offset - textNode.startOffset;\n        const index = textNode.index;\n        element._removeChildren(index, 1);\n        const firstPart = new Text(textNode.data.substr(0, offsetDiff), textNode.getAttributes());\n        const secondPart = new Text(textNode.data.substr(offsetDiff), textNode.getAttributes());\n        element._insertChild(index, [\n            firstPart,\n            secondPart\n        ]);\n    }\n}\n/**\n * Checks whether two given nodes have same attributes.\n *\n * @param nodeA Node to check.\n * @param nodeB Node to check.\n * @returns `true` if nodes have same attributes, `false` otherwise.\n */ function _haveSameAttributes(nodeA, nodeB) {\n    const iteratorA = nodeA.getAttributes();\n    const iteratorB = nodeB.getAttributes();\n    for (const attr of iteratorA){\n        if (attr[1] !== nodeB.getAttribute(attr[0])) {\n            return false;\n        }\n        iteratorB.next();\n    }\n    return iteratorB.next().done;\n}\n\n// @if CK_DEBUG_ENGINE // const ModelRange = require( '../range' ).default;\n/**\n * Operation to move a range of {@link module:engine/model/item~Item model items}\n * to given {@link module:engine/model/position~Position target position}.\n */ class MoveOperation extends Operation {\n    /**\n\t * Position before the first {@link module:engine/model/item~Item model item} to move.\n\t */ sourcePosition;\n    /**\n\t * Offset size of moved range.\n\t */ howMany;\n    /**\n\t * Position at which moved nodes will be inserted.\n\t */ targetPosition;\n    /**\n\t * Creates a move operation.\n\t *\n\t * @param sourcePosition Position before the first {@link module:engine/model/item~Item model item} to move.\n\t * @param howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t * `sourcePosition` with offset shifted by `howMany`.\n\t * @param targetPosition Position at which moved nodes will be inserted.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(sourcePosition, howMany, targetPosition, baseVersion){\n        super(baseVersion);\n        this.sourcePosition = sourcePosition.clone();\n        // `'toNext'` because `sourcePosition` is a bit like a start of the moved range.\n        this.sourcePosition.stickiness = 'toNext';\n        this.howMany = howMany;\n        this.targetPosition = targetPosition.clone();\n        this.targetPosition.stickiness = 'toNone';\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        if (this.targetPosition.root.rootName == '$graveyard') {\n            return 'remove';\n        } else if (this.sourcePosition.root.rootName == '$graveyard') {\n            return 'reinsert';\n        }\n        return 'move';\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return [\n            Range._createFromPositionAndShift(this.sourcePosition, this.howMany),\n            Range._createFromPositionAndShift(this.targetPosition, 0)\n        ];\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */ clone() {\n        return new MoveOperation(this.sourcePosition, this.howMany, this.targetPosition, this.baseVersion);\n    }\n    /**\n\t * Returns the start position of the moved range after it got moved. This may be different than\n\t * {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition} in some cases, i.e. when a range is moved\n\t * inside the same parent but {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition targetPosition}\n\t * is after {@link module:engine/model/operation/moveoperation~MoveOperation#sourcePosition sourcePosition}.\n\t *\n\t * ```\n\t *  vv              vv\n\t * abcdefg ===> adefbcg\n\t *      ^          ^\n\t *      targetPos  movedRangeStart\n\t *      offset 6   offset 4\n\t *```\n\t */ getMovedRangeStart() {\n        return this.targetPosition._getTransformedByDeletion(this.sourcePosition, this.howMany);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        const newTargetPosition = this.sourcePosition._getTransformedByInsertion(this.targetPosition, this.howMany);\n        return new MoveOperation(this.getMovedRangeStart(), this.howMany, newTargetPosition, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        const sourceElement = this.sourcePosition.parent;\n        const targetElement = this.targetPosition.parent;\n        const sourceOffset = this.sourcePosition.offset;\n        const targetOffset = this.targetPosition.offset;\n        // Validate whether move operation has correct parameters.\n        // Validation is pretty complex but move operation is one of the core ways to manipulate the document state.\n        // We expect that many errors might be connected with one of scenarios described below.\n        if (sourceOffset + this.howMany > sourceElement.maxOffset) {\n            /**\n\t\t\t * The nodes which should be moved do not exist.\n\t\t\t *\n\t\t\t * @error move-operation-nodes-do-not-exist\n\t\t\t */ throw new CKEditorError('move-operation-nodes-do-not-exist', this);\n        } else if (sourceElement === targetElement && sourceOffset < targetOffset && targetOffset < sourceOffset + this.howMany) {\n            /**\n\t\t\t * Trying to move a range of nodes into the middle of that range.\n\t\t\t *\n\t\t\t * @error move-operation-range-into-itself\n\t\t\t */ throw new CKEditorError('move-operation-range-into-itself', this);\n        } else if (this.sourcePosition.root == this.targetPosition.root) {\n            if (compareArrays(this.sourcePosition.getParentPath(), this.targetPosition.getParentPath()) == 'prefix') {\n                const i = this.sourcePosition.path.length - 1;\n                if (this.targetPosition.path[i] >= sourceOffset && this.targetPosition.path[i] < sourceOffset + this.howMany) {\n                    /**\n\t\t\t\t\t * Trying to move a range of nodes into one of nodes from that range.\n\t\t\t\t\t *\n\t\t\t\t\t * @error move-operation-node-into-itself\n\t\t\t\t\t */ throw new CKEditorError('move-operation-node-into-itself', this);\n                }\n            }\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        _move(Range._createFromPositionAndShift(this.sourcePosition, this.howMany), this.targetPosition);\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.sourcePosition = this.sourcePosition.toJSON();\n        json.targetPosition = this.targetPosition.toJSON();\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'MoveOperation';\n    }\n    /**\n\t * Creates `MoveOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        const sourcePosition = Position.fromJSON(json.sourcePosition, document);\n        const targetPosition = Position.fromJSON(json.targetPosition, document);\n        return new this(sourcePosition, json.howMany, targetPosition, json.baseVersion);\n    }\n}\n\n/**\n * Operation to insert one or more nodes at given position in the model.\n */ class InsertOperation extends Operation {\n    /**\n\t * Position of insertion.\n\t *\n\t * @readonly\n\t */ position;\n    /**\n\t * List of nodes to insert.\n\t *\n\t * @readonly\n\t */ nodes;\n    /**\n\t * Flag deciding how the operation should be transformed. If set to `true`, nodes might get additional attributes\n\t * during operational transformation. This happens when the operation insertion position is inside of a range\n\t * where attributes have changed.\n\t */ shouldReceiveAttributes;\n    /**\n\t * Creates an insert operation.\n\t *\n\t * @param position Position of insertion.\n\t * @param nodes The list of nodes to be inserted.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(position, nodes, baseVersion){\n        super(baseVersion);\n        this.position = position.clone();\n        this.position.stickiness = 'toNone';\n        this.nodes = new NodeList(_normalizeNodes(nodes));\n        this.shouldReceiveAttributes = false;\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        return 'insert';\n    }\n    /**\n\t * Total offset size of inserted nodes.\n\t */ get howMany() {\n        return this.nodes.maxOffset;\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return this.position.clone();\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */ clone() {\n        const nodes = new NodeList([\n            ...this.nodes\n        ].map((node)=>node._clone(true)));\n        const insert = new InsertOperation(this.position, nodes, this.baseVersion);\n        insert.shouldReceiveAttributes = this.shouldReceiveAttributes;\n        return insert;\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        const graveyard = this.position.root.document.graveyard;\n        const gyPosition = new Position(graveyard, [\n            0\n        ]);\n        return new MoveOperation(this.position, this.nodes.maxOffset, gyPosition, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        const targetElement = this.position.parent;\n        if (!targetElement || targetElement.maxOffset < this.position.offset) {\n            /**\n\t\t\t * Insertion position is invalid.\n\t\t\t *\n\t\t\t * @error insert-operation-position-invalid\n\t\t\t */ throw new CKEditorError('insert-operation-position-invalid', this);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        // What happens here is that we want original nodes be passed to writer because we want original nodes\n        // to be inserted to the model. But in InsertOperation, we want to keep those nodes as they were added\n        // to the operation, not modified. For example, text nodes can get merged or cropped while Elements can\n        // get children. It is important that InsertOperation has the copy of original nodes in intact state.\n        const originalNodes = this.nodes;\n        this.nodes = new NodeList([\n            ...originalNodes\n        ].map((node)=>node._clone(true)));\n        _insert(this.position, originalNodes);\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.position = this.position.toJSON();\n        json.nodes = this.nodes.toJSON();\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'InsertOperation';\n    }\n    /**\n\t * Creates `InsertOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        const children = [];\n        for (const child of json.nodes){\n            if (child.name) {\n                // If child has name property, it is an Element.\n                children.push(Element.fromJSON(child));\n            } else {\n                // Otherwise, it is a Text node.\n                children.push(Text.fromJSON(child));\n            }\n        }\n        const insert = new InsertOperation(Position.fromJSON(json.position, document), children, json.baseVersion);\n        insert.shouldReceiveAttributes = json.shouldReceiveAttributes;\n        return insert;\n    }\n}\n\n/**\n * Operation to split {@link module:engine/model/element~Element an element} at given\n * {@link module:engine/model/operation/splitoperation~SplitOperation#splitPosition split position} into two elements,\n * both containing a part of the element's original content.\n */ class SplitOperation extends Operation {\n    /**\n\t * Position at which an element should be split.\n\t */ splitPosition;\n    /**\n\t * Total offset size of elements that are in the split element after `position`.\n\t */ howMany;\n    /**\n\t * Position at which the clone of split element (or element from graveyard) will be inserted.\n\t */ insertionPosition;\n    /**\n\t * Position in the graveyard root before the element which should be used as a parent of the nodes after `position`.\n\t * If it is not set, a copy of the the `position` parent will be used.\n\t *\n\t * The default behavior is to clone the split element. Element from graveyard is used during undo.\n\t */ graveyardPosition;\n    /**\n\t * Creates a split operation.\n\t *\n\t * @param splitPosition Position at which an element should be split.\n\t * @param howMany Total offset size of elements that are in the split element after `position`.\n\t * @param insertionPosition Position at which the clone of split element (or element from graveyard) will be inserted.\n\t * @param graveyardPosition Position in the graveyard root before the element which\n\t * should be used as a parent of the nodes after `position`. If it is not set, a copy of the the `position` parent will be used.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(splitPosition, howMany, insertionPosition, graveyardPosition, baseVersion){\n        super(baseVersion);\n        this.splitPosition = splitPosition.clone();\n        // Keep position sticking to the next node. This way any new content added at the place where the element is split\n        // will be left in the original element.\n        this.splitPosition.stickiness = 'toNext';\n        this.howMany = howMany;\n        this.insertionPosition = insertionPosition;\n        this.graveyardPosition = graveyardPosition ? graveyardPosition.clone() : null;\n        if (this.graveyardPosition) {\n            this.graveyardPosition.stickiness = 'toNext';\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        return 'split';\n    }\n    /**\n\t * Position inside the new clone of a split element.\n\t *\n\t * This is a position where nodes that are after the split position will be moved to.\n\t */ get moveTargetPosition() {\n        const path = this.insertionPosition.path.slice();\n        path.push(0);\n        return new Position(this.insertionPosition.root, path);\n    }\n    /**\n\t * Artificial range that contains all the nodes from the split element that will be moved to the new element.\n\t * The range starts at {@link #splitPosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t */ get movedRange() {\n        const end = this.splitPosition.getShiftedBy(Number.POSITIVE_INFINITY);\n        return new Range(this.splitPosition, end);\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        // These could be positions but `Selectable` type only supports `Iterable<Range>`.\n        const ranges = [\n            Range._createFromPositionAndShift(this.splitPosition, 0),\n            Range._createFromPositionAndShift(this.insertionPosition, 0)\n        ];\n        if (this.graveyardPosition) {\n            ranges.push(Range._createFromPositionAndShift(this.graveyardPosition, 0));\n        }\n        return ranges;\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns Clone of this operation.\n\t */ clone() {\n        return new SplitOperation(this.splitPosition, this.howMany, this.insertionPosition, this.graveyardPosition, this.baseVersion);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        const graveyard = this.splitPosition.root.document.graveyard;\n        const graveyardPosition = new Position(graveyard, [\n            0\n        ]);\n        return new MergeOperation(this.moveTargetPosition, this.howMany, this.splitPosition, graveyardPosition, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        const element = this.splitPosition.parent;\n        const offset = this.splitPosition.offset;\n        // Validate whether split operation has correct parameters.\n        if (!element || element.maxOffset < offset) {\n            /**\n\t\t\t * Split position is invalid.\n\t\t\t *\n\t\t\t * @error split-operation-position-invalid\n\t\t\t */ throw new CKEditorError('split-operation-position-invalid', this);\n        } else if (!element.parent) {\n            /**\n\t\t\t * Cannot split root element.\n\t\t\t *\n\t\t\t * @error split-operation-split-in-root\n\t\t\t */ throw new CKEditorError('split-operation-split-in-root', this);\n        } else if (this.howMany != element.maxOffset - this.splitPosition.offset) {\n            /**\n\t\t\t * Split operation specifies wrong number of nodes to move.\n\t\t\t *\n\t\t\t * @error split-operation-how-many-invalid\n\t\t\t */ throw new CKEditorError('split-operation-how-many-invalid', this);\n        } else if (this.graveyardPosition && !this.graveyardPosition.nodeAfter) {\n            /**\n\t\t\t * Graveyard position invalid.\n\t\t\t *\n\t\t\t * @error split-operation-graveyard-position-invalid\n\t\t\t */ throw new CKEditorError('split-operation-graveyard-position-invalid', this);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        const splitElement = this.splitPosition.parent;\n        if (this.graveyardPosition) {\n            _move(Range._createFromPositionAndShift(this.graveyardPosition, 1), this.insertionPosition);\n        } else {\n            const newElement = splitElement._clone();\n            _insert(this.insertionPosition, newElement);\n        }\n        const sourceRange = new Range(Position._createAt(splitElement, this.splitPosition.offset), Position._createAt(splitElement, splitElement.maxOffset));\n        _move(sourceRange, this.moveTargetPosition);\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.splitPosition = this.splitPosition.toJSON();\n        json.insertionPosition = this.insertionPosition.toJSON();\n        if (this.graveyardPosition) {\n            json.graveyardPosition = this.graveyardPosition.toJSON();\n        }\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'SplitOperation';\n    }\n    /**\n\t * Helper function that returns a default insertion position basing on given `splitPosition`. The default insertion\n\t * position is after the split element.\n\t */ static getInsertionPosition(splitPosition) {\n        const path = splitPosition.path.slice(0, -1);\n        path[path.length - 1]++;\n        return new Position(splitPosition.root, path, 'toPrevious');\n    }\n    /**\n\t * Creates `SplitOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        const splitPosition = Position.fromJSON(json.splitPosition, document);\n        const insertionPosition = Position.fromJSON(json.insertionPosition, document);\n        const graveyardPosition = json.graveyardPosition ? Position.fromJSON(json.graveyardPosition, document) : null;\n        return new this(splitPosition, json.howMany, insertionPosition, graveyardPosition, json.baseVersion);\n    }\n}\n\n/**\n * Operation to merge two {@link module:engine/model/element~Element elements}.\n *\n * The merged element is the parent of {@link ~MergeOperation#sourcePosition} and it is merged into the parent of\n * {@link ~MergeOperation#targetPosition}. All nodes from the merged element are moved to {@link ~MergeOperation#targetPosition}.\n *\n * The merged element is moved to the graveyard at {@link ~MergeOperation#graveyardPosition}.\n */ class MergeOperation extends Operation {\n    /**\n\t * Position inside the merged element. All nodes from that element after that position will be moved to {@link #targetPosition}.\n\t */ sourcePosition;\n    /**\n\t * Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t */ howMany;\n    /**\n\t * Position which the nodes from the merged elements will be moved to.\n\t */ targetPosition;\n    /**\n\t * Position in graveyard to which the merged element will be moved.\n\t */ graveyardPosition;\n    /**\n\t * Creates a merge operation.\n\t *\n\t * @param sourcePosition Position inside the merged element. All nodes from that\n\t * element after that position will be moved to {@link #targetPosition}.\n\t * @param howMany Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t * @param targetPosition Position which the nodes from the merged elements will be moved to.\n\t * @param graveyardPosition Position in graveyard to which the merged element will be moved.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(sourcePosition, howMany, targetPosition, graveyardPosition, baseVersion){\n        super(baseVersion);\n        this.sourcePosition = sourcePosition.clone();\n        // This is, and should always remain, the first position in its parent.\n        this.sourcePosition.stickiness = 'toPrevious';\n        this.howMany = howMany;\n        this.targetPosition = targetPosition.clone();\n        // Except of a rare scenario in `MergeOperation` x `MergeOperation` transformation,\n        // this is, and should always remain, the last position in its parent.\n        this.targetPosition.stickiness = 'toNext';\n        this.graveyardPosition = graveyardPosition.clone();\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        return 'merge';\n    }\n    /**\n\t * Position before the merged element (which will be deleted).\n\t */ get deletionPosition() {\n        return new Position(this.sourcePosition.root, this.sourcePosition.path.slice(0, -1));\n    }\n    /**\n\t * Artificial range that contains all the nodes from the merged element that will be moved to {@link ~MergeOperation#sourcePosition}.\n\t * The range starts at {@link ~MergeOperation#sourcePosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t */ get movedRange() {\n        const end = this.sourcePosition.getShiftedBy(Number.POSITIVE_INFINITY);\n        return new Range(this.sourcePosition, end);\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        const mergedElement = this.sourcePosition.parent;\n        return [\n            Range._createOn(mergedElement),\n            // These could be positions but `Selectable` type only supports `Iterable<Range>`.\n            Range._createFromPositionAndShift(this.targetPosition, 0),\n            Range._createFromPositionAndShift(this.graveyardPosition, 0)\n        ];\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */ clone() {\n        return new MergeOperation(this.sourcePosition, this.howMany, this.targetPosition, this.graveyardPosition, this.baseVersion);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        // Positions in this method are transformed by this merge operation because the split operation bases on\n        // the context after this merge operation happened (because split operation reverses it).\n        // So we need to acknowledge that the merge operation happened and those positions changed a little.\n        const targetPosition = this.targetPosition._getTransformedByMergeOperation(this);\n        const path = this.sourcePosition.path.slice(0, -1);\n        const insertionPosition = new Position(this.sourcePosition.root, path)._getTransformedByMergeOperation(this);\n        return new SplitOperation(targetPosition, this.howMany, insertionPosition, this.graveyardPosition, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        const sourceElement = this.sourcePosition.parent;\n        const targetElement = this.targetPosition.parent;\n        // Validate whether merge operation has correct parameters.\n        if (!sourceElement.parent) {\n            /**\n\t\t\t * Merge source position is invalid. The element to be merged must have a parent node.\n\t\t\t *\n\t\t\t * @error merge-operation-source-position-invalid\n\t\t\t */ throw new CKEditorError('merge-operation-source-position-invalid', this);\n        } else if (!targetElement.parent) {\n            /**\n\t\t\t * Merge target position is invalid. The element to be merged must have a parent node.\n\t\t\t *\n\t\t\t * @error merge-operation-target-position-invalid\n\t\t\t */ throw new CKEditorError('merge-operation-target-position-invalid', this);\n        } else if (this.howMany != sourceElement.maxOffset) {\n            /**\n\t\t\t * Merge operation specifies wrong number of nodes to move.\n\t\t\t *\n\t\t\t * @error merge-operation-how-many-invalid\n\t\t\t */ throw new CKEditorError('merge-operation-how-many-invalid', this);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        const mergedElement = this.sourcePosition.parent;\n        const sourceRange = Range._createIn(mergedElement);\n        _move(sourceRange, this.targetPosition);\n        _move(Range._createOn(mergedElement), this.graveyardPosition);\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.sourcePosition = json.sourcePosition.toJSON();\n        json.targetPosition = json.targetPosition.toJSON();\n        json.graveyardPosition = json.graveyardPosition.toJSON();\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'MergeOperation';\n    }\n    /**\n\t * Creates `MergeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        const sourcePosition = Position.fromJSON(json.sourcePosition, document);\n        const targetPosition = Position.fromJSON(json.targetPosition, document);\n        const graveyardPosition = Position.fromJSON(json.graveyardPosition, document);\n        return new this(sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion);\n    }\n}\n\nclass MarkerOperation extends Operation {\n    /**\n\t * Marker name.\n\t *\n\t * @readonly\n\t */ name;\n    /**\n\t * Marker range before the change.\n\t *\n\t * @readonly\n\t */ oldRange;\n    /**\n\t * Marker range after the change.\n\t *\n\t * @readonly\n\t */ newRange;\n    /**\n\t * Specifies whether the marker operation affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t *\n\t * @readonly\n\t */ affectsData;\n    /**\n\t * Marker collection on which change should be executed.\n\t */ _markers;\n    /**\n\t * @param name Marker name.\n\t * @param oldRange Marker range before the change.\n\t * @param newRange Marker range after the change.\n\t * @param markers Marker collection on which change should be executed.\n\t * @param affectsData Specifies whether the marker operation affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(name, oldRange, newRange, markers, affectsData, baseVersion){\n        super(baseVersion);\n        this.name = name;\n        this.oldRange = oldRange ? oldRange.clone() : null;\n        this.newRange = newRange ? newRange.clone() : null;\n        this.affectsData = affectsData;\n        this._markers = markers;\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        return 'marker';\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        const ranges = [];\n        if (this.oldRange) {\n            ranges.push(this.oldRange.clone());\n        }\n        if (this.newRange) {\n            if (this.oldRange) {\n                ranges.push(...this.newRange.getDifference(this.oldRange));\n            } else {\n                ranges.push(this.newRange.clone());\n            }\n        }\n        return ranges;\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */ clone() {\n        return new MarkerOperation(this.name, this.oldRange, this.newRange, this._markers, this.affectsData, this.baseVersion);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        return new MarkerOperation(this.name, this.newRange, this.oldRange, this._markers, this.affectsData, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        if (this.newRange) {\n            this._markers._set(this.name, this.newRange, true, this.affectsData);\n        } else {\n            this._markers._remove(this.name);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ toJSON() {\n        const json = super.toJSON();\n        if (this.oldRange) {\n            json.oldRange = this.oldRange.toJSON();\n        }\n        if (this.newRange) {\n            json.newRange = this.newRange.toJSON();\n        }\n        delete json._markers;\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'MarkerOperation';\n    }\n    /**\n\t * Creates `MarkerOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        return new MarkerOperation(json.name, json.oldRange ? Range.fromJSON(json.oldRange, document) : null, json.newRange ? Range.fromJSON(json.newRange, document) : null, document.model.markers, json.affectsData, json.baseVersion);\n    }\n}\n\n/**\n * Operation to change nodes' attribute.\n *\n * Using this class you can add, remove or change value of the attribute.\n */ class AttributeOperation extends Operation {\n    /**\n\t * Range on which operation should be applied.\n\t *\n\t * @readonly\n\t */ range;\n    /**\n\t * Key of an attribute to change or remove.\n\t *\n\t * @readonly\n\t */ key;\n    /**\n\t * Old value of the attribute with given key or `null`, if attribute was not set before.\n\t *\n\t * @readonly\n\t */ oldValue;\n    /**\n\t * New value of the attribute with given key or `null`, if operation should remove attribute.\n\t *\n\t * @readonly\n\t */ newValue;\n    /**\n\t * Creates an operation that changes, removes or adds attributes.\n\t *\n\t * If only `newValue` is set, attribute will be added on a node. Note that all nodes in operation's range must not\n\t * have an attribute with the same key as the added attribute.\n\t *\n\t * If only `oldValue` is set, then attribute with given key will be removed. Note that all nodes in operation's range\n\t * must have an attribute with that key added.\n\t *\n\t * If both `newValue` and `oldValue` are set, then the operation will change the attribute value. Note that all nodes in\n\t * operation's ranges must already have an attribute with given key and `oldValue` as value\n\t *\n\t * @param range Range on which the operation should be applied. Must be a flat range.\n\t * @param key Key of an attribute to change or remove.\n\t * @param oldValue Old value of the attribute with given key or `null`, if attribute was not set before.\n\t * @param newValue New value of the attribute with given key or `null`, if operation should remove attribute.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(range, key, oldValue, newValue, baseVersion){\n        super(baseVersion);\n        this.range = range.clone();\n        this.key = key;\n        this.oldValue = oldValue === undefined ? null : oldValue;\n        this.newValue = newValue === undefined ? null : newValue;\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        if (this.oldValue === null) {\n            return 'addAttribute';\n        } else if (this.newValue === null) {\n            return 'removeAttribute';\n        } else {\n            return 'changeAttribute';\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return this.range.clone();\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */ clone() {\n        return new AttributeOperation(this.range, this.key, this.oldValue, this.newValue, this.baseVersion);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        return new AttributeOperation(this.range, this.key, this.newValue, this.oldValue, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.range = this.range.toJSON();\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        if (!this.range.isFlat) {\n            /**\n\t\t\t * The range to change is not flat.\n\t\t\t *\n\t\t\t * @error attribute-operation-range-not-flat\n\t\t\t */ throw new CKEditorError('attribute-operation-range-not-flat', this);\n        }\n        for (const item of this.range.getItems({\n            shallow: true\n        })){\n            if (this.oldValue !== null && !isEqual(item.getAttribute(this.key), this.oldValue)) {\n                /**\n\t\t\t\t * Changed node has different attribute value than operation's old attribute value.\n\t\t\t\t *\n\t\t\t\t * @error attribute-operation-wrong-old-value\n\t\t\t\t * @param item\n\t\t\t\t * @param key\n\t\t\t\t * @param value\n\t\t\t\t */ throw new CKEditorError('attribute-operation-wrong-old-value', this, {\n                    item,\n                    key: this.key,\n                    value: this.oldValue\n                });\n            }\n            if (this.oldValue === null && this.newValue !== null && item.hasAttribute(this.key)) {\n                /**\n\t\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t\t *\n\t\t\t\t * @error attribute-operation-attribute-exists\n\t\t\t\t * @param node\n\t\t\t\t * @param key\n\t\t\t\t */ throw new CKEditorError('attribute-operation-attribute-exists', this, {\n                    node: item,\n                    key: this.key\n                });\n            }\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        // If value to set is same as old value, don't do anything.\n        if (!isEqual(this.oldValue, this.newValue)) {\n            // Execution.\n            _setAttribute(this.range, this.key, this.newValue);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'AttributeOperation';\n    }\n    /**\n\t * Creates `AttributeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        return new AttributeOperation(Range.fromJSON(json.range, document), json.key, json.oldValue, json.newValue, json.baseVersion);\n    }\n}\n\n/**\n * Operation which is doing nothing (\"empty operation\", \"do-nothing operation\", \"noop\"). This is an operation,\n * which when executed does not change the tree model. It still has some parameters defined for transformation purposes.\n *\n * In most cases this operation is a result of transforming operations. When transformation returns\n * {@link module:engine/model/operation/nooperation~NoOperation} it means that changes done by the transformed operation\n * have already been applied.\n */ class NoOperation extends Operation {\n    get type() {\n        return 'noop';\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return null;\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */ clone() {\n        return new NoOperation(this.baseVersion);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        return new NoOperation(this.baseVersion + 1);\n    }\n    /** @internal */ _execute() {}\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'NoOperation';\n    }\n}\n\n/**\n * Operation to change element's name.\n *\n * Using this class you can change element's name.\n */ class RenameOperation extends Operation {\n    /**\n\t * Position before an element to change.\n\t */ position;\n    /**\n\t * Current name of the element.\n\t */ oldName;\n    /**\n\t * New name for the element.\n\t */ newName;\n    /**\n\t * Creates an operation that changes element's name.\n\t *\n\t * @param position Position before an element to change.\n\t * @param oldName Current name of the element.\n\t * @param newName New name for the element.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(position, oldName, newName, baseVersion){\n        super(baseVersion);\n        this.position = position;\n        // This position sticks to the next node because it is a position before the node that we want to change.\n        this.position.stickiness = 'toNext';\n        this.oldName = oldName;\n        this.newName = newName;\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        return 'rename';\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return this.position.nodeAfter;\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns Clone of this operation.\n\t */ clone() {\n        return new RenameOperation(this.position.clone(), this.oldName, this.newName, this.baseVersion);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        return new RenameOperation(this.position.clone(), this.newName, this.oldName, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        const element = this.position.nodeAfter;\n        if (!(element instanceof Element)) {\n            /**\n\t\t\t * Given position is invalid or node after it is not instance of Element.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-position\n\t\t\t */ throw new CKEditorError('rename-operation-wrong-position', this);\n        } else if (element.name !== this.oldName) {\n            /**\n\t\t\t * Element to change has different name than operation's old name.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-name\n\t\t\t */ throw new CKEditorError('rename-operation-wrong-name', this);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        const element = this.position.nodeAfter;\n        element.name = this.newName;\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.position = this.position.toJSON();\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'RenameOperation';\n    }\n    /**\n\t * Creates `RenameOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        return new RenameOperation(Position.fromJSON(json.position, document), json.oldName, json.newName, json.baseVersion);\n    }\n}\n\n/**\n * Operation to change root element's attribute. Using this class you can add, remove or change value of the attribute.\n *\n * This operation is needed, because root elements can't be changed through\n * {@link module:engine/model/operation/attributeoperation~AttributeOperation}.\n * It is because {@link module:engine/model/operation/attributeoperation~AttributeOperation}\n * requires a range to change and root element can't\n * be a part of range because every {@link module:engine/model/position~Position} has to be inside a root.\n * {@link module:engine/model/position~Position} can't be created before a root element.\n */ class RootAttributeOperation extends Operation {\n    /**\n\t * Root element to change.\n\t */ root;\n    /**\n\t * Key of an attribute to change or remove.\n\t */ key;\n    /**\n\t * Old value of the attribute with given key or `null`, if attribute was not set before.\n\t *\n\t * @readonly\n\t */ oldValue;\n    /**\n\t * New value of the attribute with given key or `null`, if operation should remove attribute.\n\t *\n\t * @readonly\n\t */ newValue;\n    /**\n\t * Creates an operation that changes, removes or adds attributes on root element.\n\t *\n\t * @see module:engine/model/operation/attributeoperation~AttributeOperation\n\t * @param root Root element to change.\n\t * @param key Key of an attribute to change or remove.\n\t * @param oldValue Old value of the attribute with given key or `null`, if attribute was not set before.\n\t * @param newValue New value of the attribute with given key or `null`, if operation should remove attribute.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */ constructor(root, key, oldValue, newValue, baseVersion){\n        super(baseVersion);\n        this.root = root;\n        this.key = key;\n        this.oldValue = oldValue === undefined ? null : oldValue;\n        this.newValue = newValue === undefined ? null : newValue;\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        if (this.oldValue === null) {\n            return 'addRootAttribute';\n        } else if (this.newValue === null) {\n            return 'removeRootAttribute';\n        } else {\n            return 'changeRootAttribute';\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return this.root;\n    }\n    /**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns Clone of this operation.\n\t */ clone() {\n        return new RootAttributeOperation(this.root, this.key, this.oldValue, this.newValue, this.baseVersion);\n    }\n    /**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */ getReversed() {\n        return new RootAttributeOperation(this.root, this.key, this.newValue, this.oldValue, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        if (this.root != this.root.root || this.root.is('documentFragment')) {\n            /**\n\t\t\t * The element to change is not a root element.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-not-a-root\n\t\t\t * @param root\n\t\t\t * @param key\n\t\t\t * @param value\n\t\t\t */ throw new CKEditorError('rootattribute-operation-not-a-root', this, {\n                root: this.root,\n                key: this.key\n            });\n        }\n        if (this.oldValue !== null && this.root.getAttribute(this.key) !== this.oldValue) {\n            /**\n\t\t\t * The attribute which should be removed does not exist for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-wrong-old-value\n\t\t\t * @param root\n\t\t\t * @param key\n\t\t\t * @param value\n\t\t\t */ throw new CKEditorError('rootattribute-operation-wrong-old-value', this, {\n                root: this.root,\n                key: this.key\n            });\n        }\n        if (this.oldValue === null && this.newValue !== null && this.root.hasAttribute(this.key)) {\n            /**\n\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-attribute-exists\n\t\t\t * @param root\n\t\t\t * @param key\n\t\t\t */ throw new CKEditorError('rootattribute-operation-attribute-exists', this, {\n                root: this.root,\n                key: this.key\n            });\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        if (this.newValue !== null) {\n            this.root._setAttribute(this.key, this.newValue);\n        } else {\n            this.root._removeAttribute(this.key);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.root = this.root.toJSON();\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'RootAttributeOperation';\n    }\n    /**\n\t * Creates `RootAttributeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        if (!document.getRoot(json.root)) {\n            /**\n\t\t\t * Cannot create RootAttributeOperation for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-fromjson-no-root\n\t\t\t * @param rootName\n\t\t\t */ throw new CKEditorError('rootattribute-operation-fromjson-no-root', this, {\n                rootName: json.root\n            });\n        }\n        return new RootAttributeOperation(document.getRoot(json.root), json.key, json.oldValue, json.newValue, json.baseVersion);\n    }\n}\n\n/**\n * Operation that creates (or attaches) or detaches a root element.\n */ class RootOperation extends Operation {\n    /**\n\t * Root name to create or detach.\n\t */ rootName;\n    /**\n\t * Root element name.\n\t */ elementName;\n    /**\n\t * Specifies whether the operation adds (`true`) or detaches the root (`false`).\n\t */ isAdd;\n    /**\n\t * Document which owns the root.\n\t */ _document;\n    /**\n\t * Creates an operation that creates or removes a root element.\n\t *\n\t * @param rootName Root name to create or detach.\n\t * @param elementName Root element name.\n\t * @param isAdd Specifies whether the operation adds (`true`) or detaches the root (`false`).\n\t * @param document Document which owns the root.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation can be applied.\n\t */ constructor(rootName, elementName, isAdd, document, baseVersion){\n        super(baseVersion);\n        this.rootName = rootName;\n        this.elementName = elementName;\n        this.isAdd = isAdd;\n        this._document = document;\n        // Make sure that the root exists ASAP, this is important for RTC.\n        // If the root was dynamically added, there will be more operations that operate on/in this root.\n        // These operations will require root element instance (in operation property or in position instance).\n        // If the root is not created ahead of time, instantiating such operations may fail.\n        if (!this._document.getRoot(this.rootName)) {\n            const root = this._document.createRoot(this.elementName, this.rootName);\n            root._isAttached = false;\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        return this.isAdd ? 'addRoot' : 'detachRoot';\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return this._document.getRoot(this.rootName);\n    }\n    /**\n\t * @inheritDoc\n\t */ clone() {\n        return new RootOperation(this.rootName, this.elementName, this.isAdd, this._document, this.baseVersion);\n    }\n    /**\n\t * @inheritDoc\n\t */ getReversed() {\n        return new RootOperation(this.rootName, this.elementName, !this.isAdd, this._document, this.baseVersion + 1);\n    }\n    /**\n\t * @inheritDoc\n\t */ _execute() {\n        this._document.getRoot(this.rootName)._isAttached = this.isAdd;\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        delete json._document;\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'RootOperation';\n    }\n    /**\n\t * Creates `RootOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        return new RootOperation(json.rootName, json.elementName, json.isAdd, document, json.baseVersion);\n    }\n}\n\nconst operations = {};\noperations[AttributeOperation.className] = AttributeOperation;\noperations[InsertOperation.className] = InsertOperation;\noperations[MarkerOperation.className] = MarkerOperation;\noperations[MoveOperation.className] = MoveOperation;\noperations[NoOperation.className] = NoOperation;\noperations[Operation.className] = Operation;\noperations[RenameOperation.className] = RenameOperation;\noperations[RootAttributeOperation.className] = RootAttributeOperation;\noperations[RootOperation.className] = RootOperation;\noperations[SplitOperation.className] = SplitOperation;\noperations[MergeOperation.className] = MergeOperation;\n/**\n * A factory class for creating operations.\n */ class OperationFactory {\n    /**\n\t * Creates an operation instance from a JSON object (parsed JSON string).\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */ static fromJSON(json, document) {\n        return operations[json.__className].fromJSON(json, document);\n    }\n}\n\nconst transformations = new Map();\n/**\n * Sets a transformation function to be be used to transform instances of class `OperationA` by instances of class `OperationB`.\n *\n * The `transformationFunction` is passed three parameters:\n *\n * * `a` - operation to be transformed, an instance of `OperationA`,\n * * `b` - operation to be transformed by, an instance of `OperationB`,\n * * {@link module:engine/model/operation/transform~TransformationContext `context`} - object with additional information about\n * transformation context.\n *\n * The `transformationFunction` should return transformation result, which is an array with one or multiple\n * {@link module:engine/model/operation/operation~Operation operation} instances.\n *\n * @param transformationFunction Function to use for transforming.\n */ function setTransformation(OperationA, OperationB, transformationFunction) {\n    let aGroup = transformations.get(OperationA);\n    if (!aGroup) {\n        aGroup = new Map();\n        transformations.set(OperationA, aGroup);\n    }\n    aGroup.set(OperationB, transformationFunction);\n}\n/**\n * Returns a previously set transformation function for transforming an instance of `OperationA` by an instance of `OperationB`.\n *\n * If no transformation was set for given pair of operations, {@link module:engine/model/operation/transform~noUpdateTransformation}\n * is returned. This means that if no transformation was set, the `OperationA` instance will not change when transformed\n * by the `OperationB` instance.\n *\n * @returns Function set to transform an instance of `OperationA` by an instance of `OperationB`.\n */ function getTransformation(OperationA, OperationB) {\n    const aGroup = transformations.get(OperationA);\n    if (aGroup && aGroup.has(OperationB)) {\n        return aGroup.get(OperationB);\n    }\n    return noUpdateTransformation;\n}\n/**\n * A transformation function that only clones operation to transform, without changing it.\n */ function noUpdateTransformation(a) {\n    return [\n        a\n    ];\n}\n/**\n * Transforms operation `a` by operation `b`.\n *\n * @param a Operation to be transformed.\n * @param b Operation to transform by.\n * @param context Transformation context for this transformation.\n * @returns Transformation result.\n */ function transform$1(a, b, context = {}) {\n    const transformationFunction = getTransformation(a.constructor, b.constructor);\n    /* eslint-disable no-useless-catch */ try {\n        a = a.clone();\n        return transformationFunction(a, b, context);\n    } catch (e) {\n        // @if CK_DEBUG // console.warn( 'Error during operation transformation!', e.message );\n        // @if CK_DEBUG // console.warn( 'Transformed operation', a );\n        // @if CK_DEBUG // console.warn( 'Operation transformed by', b );\n        // @if CK_DEBUG // console.warn( 'context.aIsStrong', context.aIsStrong );\n        // @if CK_DEBUG // console.warn( 'context.aWasUndone', context.aWasUndone );\n        // @if CK_DEBUG // console.warn( 'context.bWasUndone', context.bWasUndone );\n        // @if CK_DEBUG // console.warn( 'context.abRelation', context.abRelation );\n        // @if CK_DEBUG // console.warn( 'context.baRelation', context.baRelation );\n        throw e;\n    }\n/* eslint-enable no-useless-catch */ }\n/**\n * Performs a transformation of two sets of operations - `operationsA` and `operationsB`. The transformation is two-way -\n * both transformed `operationsA` and transformed `operationsB` are returned.\n *\n * Note, that the first operation in each set should base on the same document state (\n * {@link module:engine/model/document~Document#version document version}).\n *\n * It is assumed that `operationsA` are \"more important\" during conflict resolution between two operations.\n *\n * New copies of both passed arrays and operations inside them are returned. Passed arguments are not altered.\n *\n * Base versions of the transformed operations sets are updated accordingly. For example, assume that base versions are `4`\n * and there are `3` operations in `operationsA` and `5` operations in `operationsB`. Then:\n *\n * * transformed `operationsA` will start from base version `9` (`4` base version + `5` operations B),\n * * transformed `operationsB` will start from base version `7` (`4` base version + `3` operations A).\n *\n * If no operation was broken into two during transformation, then both sets will end up with an operation that bases on version `11`:\n *\n * * transformed `operationsA` start from `9` and there are `3` of them, so the last will have `baseVersion` equal to `11`,\n * * transformed `operationsB` start from `7` and there are `5` of them, so the last will have `baseVersion` equal to `11`.\n *\n * @param operationsA\n * @param operationsB\n * @param options Additional transformation options.\n * @param options.document Document which the operations change.\n * @param options.useRelations Whether during transformation relations should be used (used during undo for better conflict resolution).\n * @param options.padWithNoOps Whether additional {@link module:engine/model/operation/nooperation~NoOperation}s\n * should be added to the transformation results to force the same last base version for both transformed sets (in case\n * if some operations got broken into multiple operations during transformation).\n * @param options.forceWeakRemove If set to `false`, remove operation will be always stronger than move operation,\n * so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.\n * @returns Transformation result.\n */ function transformSets(operationsA, operationsB, options) {\n    // Create new arrays so the originally passed arguments are not changed.\n    // No need to clone operations, they are cloned as they are transformed.\n    operationsA = operationsA.slice();\n    operationsB = operationsB.slice();\n    const contextFactory = new ContextFactory(options.document, options.useRelations, options.forceWeakRemove);\n    contextFactory.setOriginalOperations(operationsA);\n    contextFactory.setOriginalOperations(operationsB);\n    const originalOperations = contextFactory.originalOperations;\n    // If one of sets is empty there is simply nothing to transform, so return sets as they are.\n    if (operationsA.length == 0 || operationsB.length == 0) {\n        return {\n            operationsA,\n            operationsB,\n            originalOperations\n        };\n    }\n    //\n    // Following is a description of transformation process:\n    //\n    // There are `operationsA` and `operationsB` to be transformed, both by both.\n    //\n    // So, suppose we have sets of two operations each: `operationsA` = `[ a1, a2 ]`, `operationsB` = `[ b1, b2 ]`.\n    //\n    // Remember, that we can only transform operations that base on the same context. We assert that `a1` and `b1` base on\n    // the same context and we transform them. Then, we get `a1'` and `b1'`. `a2` bases on a context with `a1` -- `a2`\n    // is an operation that followed `a1`. Similarly, `b2` bases on a context with `b1`.\n    //\n    // However, since `a1'` is a result of transformation by `b1`, `a1'` now also has a context with `b1`. This means that\n    // we can safely transform `a1'` by `b2`. As we finish transforming `a1`, we also transformed all `operationsB`.\n    // All `operationsB` also have context including `a1`. Now, we can properly transform `a2` by those operations.\n    //\n    // The transformation process can be visualized on a transformation diagram (\"diamond diagram\"):\n    //\n    //          [the initial state]\n    //         [common for a1 and b1]\n    //\n    //                   *\n    //                  / \\\n    //                 /   \\\n    //               b1     a1\n    //               /       \\\n    //              /         \\\n    //             *           *\n    //            / \\         / \\\n    //           /   \\       /   \\\n    //         b2    a1'   b1'    a2\n    //         /       \\   /       \\\n    //        /         \\ /         \\\n    //       *           *           *\n    //        \\         / \\         /\n    //         \\       /   \\       /\n    //        a1''   b2'   a2'   b1''\n    //           \\   /       \\   /\n    //            \\ /         \\ /\n    //             *           *\n    //              \\         /\n    //               \\       /\n    //              a2''   b2''\n    //                 \\   /\n    //                  \\ /\n    //                   *\n    //\n    //           [the final state]\n    //\n    // The final state can be reached from the initial state by applying `a1`, `a2`, `b1''` and `b2''`, as well as by\n    // applying `b1`, `b2`, `a1''`, `a2''`. Note how the operations get to a proper common state before each pair is\n    // transformed.\n    //\n    // Another thing to consider is that an operation during transformation can be broken into multiple operations.\n    // Suppose that `a1` * `b1` = `[ a11', a12' ]` (instead of `a1'` that we considered previously).\n    //\n    // In that case, we leave `a12'` for later and we continue transforming `a11'` until it is transformed by all `operationsB`\n    // (in our case it is just `b2`). At this point, `b1` is transformed by \"whole\" `a1`, while `b2` is only transformed\n    // by `a11'`. Similarly, `a12'` is only transformed by `b1`. This leads to a conclusion that we need to start transforming `a12'`\n    // from the moment just after it was broken. So, `a12'` is transformed by `b2`. Now, \"the whole\" `a1` is transformed\n    // by `operationsB`, while all `operationsB` are transformed by \"the whole\" `a1`. This means that we can continue with\n    // following `operationsA` (in our case it is just `a2`).\n    //\n    // Of course, also `operationsB` can be broken. However, since we focus on transforming operation `a` to the end,\n    // the only thing to do is to store both pieces of operation `b`, so that the next transformed operation `a` will\n    // be transformed by both of them.\n    //\n    //                       *\n    //                      / \\\n    //                     /   \\\n    //                    /     \\\n    //                  b1       a1\n    //                  /         \\\n    //                 /           \\\n    //                /             \\\n    //               *               *\n    //              / \\             / \\\n    //             /  a11'         /   \\\n    //            /     \\         /     \\\n    //          b2       *      b1'      a2\n    //          /       / \\     /         \\\n    //         /       /  a12' /           \\\n    //        /       /     \\ /             \\\n    //       *       b2'     *               *\n    //        \\     /       / \\             /\n    //       a11'' /     b21'' \\           /\n    //          \\ /       /     \\         /\n    //           *       *      a2'     b1''\n    //            \\     / \\       \\     /\n    //          a12'' b22''\\       \\   /\n    //              \\ /     \\       \\ /\n    //               *      a2''     *\n    //                \\       \\     /\n    //                 \\       \\  b21'''\n    //                  \\       \\ /\n    //                a2'''      *\n    //                    \\     /\n    //                     \\  b22'''\n    //                      \\ /\n    //                       *\n    //\n    // Note, how `a1` is broken and transformed into `a11'` and `a12'`, while `b2'` got broken and transformed into `b21''` and `b22''`.\n    //\n    // Having all that on mind, here is an outline for the transformation process algorithm:\n    //\n    // 1. We have `operationsA` and `operationsB` array, which we dynamically update as the transformation process goes.\n    //\n    // 2. We take next (or first) operation from `operationsA` and check from which operation `b` we need to start transforming it.\n    // All original `operationsA` are set to be transformed starting from the first operation `b`.\n    //\n    // 3. We take operations from `operationsB`, one by one, starting from the correct one, and transform operation `a`\n    // by operation `b` (and vice versa). We update `operationsA` and `operationsB` by replacing the original operations\n    // with the transformation results.\n    //\n    // 4. If operation is broken into multiple operations, we save all the new operations in the place of the\n    // original operation.\n    //\n    // 5. Additionally, if operation `a` was broken, for the \"new\" operation, we remember from which operation `b` it should\n    // be transformed by.\n    //\n    // 6. We continue transforming \"current\" operation `a` until it is transformed by all `operationsB`. Then, go to 2.\n    // unless the last operation `a` was transformed.\n    //\n    // The actual implementation of the above algorithm is slightly different, as only one loop (while) is used.\n    // The difference is that we have \"current\" `a` operation to transform and we store the index of the next `b` operation\n    // to transform by. Each loop operates on two indexes then: index pointing to currently processed `a` operation and\n    // index pointing to next `b` operation. Each loop is just one `a * b` + `b * a` transformation. After each loop\n    // operation `b` index is updated. If all `b` operations were visited for the current `a` operation, we change\n    // current `a` operation index to the next one.\n    //\n    // For each operation `a`, keeps information what is the index in `operationsB` from which the transformation should start.\n    const nextTransformIndex = new WeakMap();\n    // For all the original `operationsA`, set that they should be transformed starting from the first of `operationsB`.\n    for (const op of operationsA){\n        nextTransformIndex.set(op, 0);\n    }\n    // Additional data that is used for some postprocessing after the main transformation process is done.\n    const data = {\n        nextBaseVersionA: operationsA[operationsA.length - 1].baseVersion + 1,\n        nextBaseVersionB: operationsB[operationsB.length - 1].baseVersion + 1,\n        originalOperationsACount: operationsA.length,\n        originalOperationsBCount: operationsB.length\n    };\n    // Index of currently transformed operation `a`.\n    let i = 0;\n    // While not all `operationsA` are transformed...\n    while(i < operationsA.length){\n        // Get \"current\" operation `a`.\n        const opA = operationsA[i];\n        // For the \"current\" operation `a`, get the index of the next operation `b` to transform by.\n        const indexB = nextTransformIndex.get(opA);\n        // If operation `a` was already transformed by every operation `b`, change \"current\" operation `a` to the next one.\n        if (indexB == operationsB.length) {\n            i++;\n            continue;\n        }\n        const opB = operationsB[indexB];\n        // Transform `a` by `b` and `b` by `a`.\n        const newOpsA = transform$1(opA, opB, contextFactory.getContext(opA, opB, true));\n        const newOpsB = transform$1(opB, opA, contextFactory.getContext(opB, opA, false));\n        // As a result we get one or more `newOpsA` and one or more `newOpsB` operations.\n        // Update contextual information about operations.\n        contextFactory.updateRelation(opA, opB);\n        contextFactory.setOriginalOperations(newOpsA, opA);\n        contextFactory.setOriginalOperations(newOpsB, opB);\n        // For new `a` operations, update their index of the next operation `b` to transform them by.\n        //\n        // This is needed even if there was only one result (`a` was not broken) because that information is used\n        // at the beginning of this loop every time.\n        for (const newOpA of newOpsA){\n            // Acknowledge, that operation `b` also might be broken into multiple operations.\n            //\n            // This is why we raise `indexB` not just by 1. If `newOpsB` are multiple operations, they will be\n            // spliced in the place of `opB`. So we need to change `transformBy` accordingly, so that an operation won't\n            // be transformed by the same operation (part of it) again.\n            nextTransformIndex.set(newOpA, indexB + newOpsB.length);\n        }\n        // Update `operationsA` and `operationsB` with the transformed versions.\n        operationsA.splice(i, 1, ...newOpsA);\n        operationsB.splice(indexB, 1, ...newOpsB);\n    }\n    handlePartialMarkerOperations(operationsA);\n    handlePartialMarkerOperations(operationsB);\n    if (options.padWithNoOps) {\n        // If no-operations padding is enabled, count how many extra `a` and `b` operations were generated.\n        const brokenOperationsACount = operationsA.length - data.originalOperationsACount;\n        const brokenOperationsBCount = operationsB.length - data.originalOperationsBCount;\n        // Then, if that number is not the same, pad `operationsA` or `operationsB` with correct number of no-ops so\n        // that the base versions are equalled.\n        //\n        // Note that only one array will be updated, as only one of those subtractions can be greater than zero.\n        padWithNoOps(operationsA, brokenOperationsBCount - brokenOperationsACount);\n        padWithNoOps(operationsB, brokenOperationsACount - brokenOperationsBCount);\n    }\n    // Finally, update base versions of transformed operations.\n    updateBaseVersions(operationsA, data.nextBaseVersionB);\n    updateBaseVersions(operationsB, data.nextBaseVersionA);\n    return {\n        operationsA,\n        operationsB,\n        originalOperations\n    };\n}\n/**\n * Gathers additional data about operations processed during transformation. Can be used to obtain contextual information\n * about two operations that are about to be transformed. This contextual information can be used for better conflict resolution.\n */ class ContextFactory {\n    originalOperations;\n    _history;\n    _useRelations;\n    _forceWeakRemove;\n    _relations;\n    /**\n\t * Creates `ContextFactory` instance.\n\t *\n\t * @param document Document which the operations change.\n\t * @param useRelations Whether during transformation relations should be used (used during undo for\n\t * better conflict resolution).\n\t * @param forceWeakRemove If set to `false`, remove operation will be always stronger than move operation,\n\t * so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.\n\t */ constructor(document, useRelations, forceWeakRemove = false){\n        // For each operation that is created during transformation process, we keep a reference to the original operation\n        // which it comes from. The original operation works as a kind of \"identifier\". Every contextual information\n        // gathered during transformation that we want to save for given operation, is actually saved for the original operation.\n        // This way no matter if operation `a` is cloned, then transformed, even breaks, we still have access to the previously\n        // gathered data through original operation reference.\n        this.originalOperations = new Map();\n        // `model.History` instance which information about undone operations will be taken from.\n        this._history = document.history;\n        // Whether additional context should be used.\n        this._useRelations = useRelations;\n        this._forceWeakRemove = !!forceWeakRemove;\n        // Relations is a double-map structure (maps in map) where for two operations we store how those operations were related\n        // to each other. Those relations are evaluated during transformation process. For every transformated pair of operations\n        // we keep relations between them.\n        this._relations = new Map();\n    }\n    /**\n\t * Sets \"original operation\" for given operations.\n\t *\n\t * During transformation process, operations are cloned, then changed, then processed again, sometimes broken into two\n\t * or multiple operations. When gathering additional data it is important that all operations can be somehow linked\n\t * so a cloned and transformed \"version\" still kept track of the data assigned earlier to it.\n\t *\n\t * The original operation object will be used as such an universal linking id. Throughout the transformation process\n\t * all cloned operations will refer to \"the original operation\" when storing and reading additional data.\n\t *\n\t * If `takeFrom` is not set, each operation from `operations` array will be assigned itself as \"the original operation\".\n\t * This should be used as an initialization step.\n\t *\n\t * If `takeFrom` is set, each operation from `operations` will be assigned the same original operation as assigned\n\t * for `takeFrom` operation. This should be used to update original operations. It should be used in a way that\n\t * `operations` are the result of `takeFrom` transformation to ensure proper \"original operation propagation\".\n\t */ setOriginalOperations(operations, takeFrom = null) {\n        const originalOperation = takeFrom ? this.originalOperations.get(takeFrom) : null;\n        for (const operation of operations){\n            this.originalOperations.set(operation, originalOperation || operation);\n        }\n    }\n    /**\n\t * Saves a relation between operations `opA` and `opB`.\n\t *\n\t * Relations are then later used to help solve conflicts when operations are transformed.\n\t */ updateRelation(opA, opB) {\n        // The use of relations is described in a bigger detail in transformation functions.\n        //\n        // In brief, this function, for specified pairs of operation types, checks how positions defined in those operations relate.\n        // Then those relations are saved. For example, for two move operations, it is saved if one of those operations target\n        // position is before the other operation source position. This kind of information gives contextual information when\n        // transformation is used during undo. Similar checks are done for other pairs of operations.\n        //\n        if (opA instanceof MoveOperation) {\n            if (opB instanceof MergeOperation) {\n                if (opA.targetPosition.isEqual(opB.sourcePosition) || opB.movedRange.containsPosition(opA.targetPosition)) {\n                    this._setRelation(opA, opB, 'insertAtSource');\n                } else if (opA.targetPosition.isEqual(opB.deletionPosition)) {\n                    this._setRelation(opA, opB, 'insertBetween');\n                } else if (opA.targetPosition.isAfter(opB.sourcePosition)) {\n                    this._setRelation(opA, opB, 'moveTargetAfter');\n                }\n            } else if (opB instanceof MoveOperation) {\n                if (opA.targetPosition.isEqual(opB.sourcePosition) || opA.targetPosition.isBefore(opB.sourcePosition)) {\n                    this._setRelation(opA, opB, 'insertBefore');\n                } else {\n                    this._setRelation(opA, opB, 'insertAfter');\n                }\n            }\n        } else if (opA instanceof SplitOperation) {\n            if (opB instanceof MergeOperation) {\n                if (opA.splitPosition.isBefore(opB.sourcePosition)) {\n                    this._setRelation(opA, opB, 'splitBefore');\n                }\n            } else if (opB instanceof MoveOperation) {\n                if (opA.splitPosition.isEqual(opB.sourcePosition) || opA.splitPosition.isBefore(opB.sourcePosition)) {\n                    this._setRelation(opA, opB, 'splitBefore');\n                } else {\n                    const range = Range._createFromPositionAndShift(opB.sourcePosition, opB.howMany);\n                    if (opA.splitPosition.hasSameParentAs(opB.sourcePosition) && range.containsPosition(opA.splitPosition)) {\n                        // TODO: Potential bug -- we are saving offset value directly and it is not later updated during OT.\n                        // TODO: This may cause a bug it here was an non-undone operation that may have impacted this offset.\n                        // TODO: Similar error was with MarkerOperation relations, where full path was saved and never updated.\n                        const howMany = range.end.offset - opA.splitPosition.offset;\n                        const offset = opA.splitPosition.offset - range.start.offset;\n                        this._setRelation(opA, opB, {\n                            howMany,\n                            offset\n                        });\n                    }\n                }\n            }\n        } else if (opA instanceof MergeOperation) {\n            if (opB instanceof MergeOperation) {\n                if (!opA.targetPosition.isEqual(opB.sourcePosition)) {\n                    this._setRelation(opA, opB, 'mergeTargetNotMoved');\n                }\n                if (opA.sourcePosition.isEqual(opB.targetPosition)) {\n                    this._setRelation(opA, opB, 'mergeSourceNotMoved');\n                }\n                if (opA.sourcePosition.isEqual(opB.sourcePosition)) {\n                    this._setRelation(opA, opB, 'mergeSameElement');\n                }\n            } else if (opB instanceof SplitOperation) {\n                if (opA.sourcePosition.isEqual(opB.splitPosition)) {\n                    this._setRelation(opA, opB, 'splitAtSource');\n                }\n            } else if (opB instanceof MoveOperation && opB.howMany > 0) {\n                if (opA.sourcePosition.isEqual(opB.sourcePosition.getShiftedBy(opB.howMany))) {\n                    this._setRelation(opA, opB, 'mergeSourceAffected');\n                }\n                if (opA.targetPosition.isEqual(opB.sourcePosition)) {\n                    this._setRelation(opA, opB, 'mergeTargetWasBefore');\n                }\n            }\n        } else if (opA instanceof MarkerOperation) {\n            const markerRange = opA.newRange;\n            if (!markerRange) {\n                return;\n            }\n            if (opB instanceof MergeOperation) {\n                const wasInLeftElement = markerRange.start.isEqual(opB.targetPosition);\n                const wasStartBeforeMergedElement = markerRange.start.isEqual(opB.deletionPosition);\n                const wasEndBeforeMergedElement = markerRange.end.isEqual(opB.deletionPosition);\n                const wasInRightElement = markerRange.end.isEqual(opB.sourcePosition);\n                if (wasInLeftElement || wasStartBeforeMergedElement || wasEndBeforeMergedElement || wasInRightElement) {\n                    this._setRelation(opA, opB, {\n                        wasInLeftElement,\n                        wasStartBeforeMergedElement,\n                        wasEndBeforeMergedElement,\n                        wasInRightElement\n                    });\n                }\n            }\n        }\n    }\n    /**\n\t * Evaluates and returns contextual information about two given operations `opA` and `opB` which are about to be transformed.\n\t */ getContext(opA, opB, aIsStrong) {\n        return {\n            aIsStrong,\n            aWasUndone: this._wasUndone(opA),\n            bWasUndone: this._wasUndone(opB),\n            abRelation: this._useRelations ? this._getRelation(opA, opB) : null,\n            baRelation: this._useRelations ? this._getRelation(opB, opA) : null,\n            forceWeakRemove: this._forceWeakRemove\n        };\n    }\n    /**\n\t * Returns whether given operation `op` has already been undone.\n\t *\n\t * Information whether an operation was undone gives more context when making a decision when two operations are in conflict.\n\t */ _wasUndone(op) {\n        // For `op`, get its original operation. After all, if `op` is a clone (or even transformed clone) of another\n        // operation, literally `op` couldn't be undone. It was just generated. If anything, it was the operation it origins\n        // from which was undone. So get that original operation.\n        const originalOp = this.originalOperations.get(op);\n        // And check with the document if the original operation was undone.\n        return originalOp.wasUndone || this._history.isUndoneOperation(originalOp);\n    }\n    /**\n\t * Returns a relation between `opA` and an operation which is undone by `opB`. This can be `String` value if a relation\n\t * was set earlier or `null` if there was no relation between those operations.\n\t *\n\t * This is a little tricky to understand, so let's compare it to `ContextFactory#_wasUndone`.\n\t *\n\t * When `wasUndone( opB )` is used, we check if the `opB` has already been undone. It is obvious, that the\n\t * undoing operation must happen after the undone operation. So, essentially, we have `opB`, we take document history,\n\t * we look forward in the future and ask if in that future `opB` was undone.\n\t *\n\t * Relations is a backward process to `wasUndone()`.\n\t *\n\t * Long story short - using relations is asking what happened in the past. Looking back. This time we have an undoing\n\t * operation `opB` which has undone some other operation. When there is a transformation `opA` x `opB` and there is\n\t * a conflict to solve and `opB` is an undoing operation, we can look back in the history and see what was a relation\n\t * between `opA` and the operation which `opB` undone. Basing on that relation from the past, we can now make\n\t * a better decision when resolving a conflict between two operations, because we know more about the context of\n\t * those two operations.\n\t *\n\t * This is why this function does not return a relation directly between `opA` and `opB` because we need to look\n\t * back to search for a meaningful contextual information.\n\t */ _getRelation(opA, opB) {\n        // Get the original operation. Similarly as in `wasUndone()` it is used as an universal identifier for stored data.\n        const origB = this.originalOperations.get(opB);\n        const undoneB = this._history.getUndoneOperation(origB);\n        // If `opB` is not undoing any operation, there is no relation.\n        if (!undoneB) {\n            return null;\n        }\n        const origA = this.originalOperations.get(opA);\n        const relationsA = this._relations.get(origA);\n        // Get all relations for `opA`, and check if there is a relation with `opB`-undone-counterpart. If so, return it.\n        if (relationsA) {\n            return relationsA.get(undoneB) || null;\n        }\n        return null;\n    }\n    /**\n\t * Helper function for `ContextFactory#updateRelations`.\n\t */ _setRelation(opA, opB, relation) {\n        // As always, setting is for original operations, not the clones/transformed operations.\n        const origA = this.originalOperations.get(opA);\n        const origB = this.originalOperations.get(opB);\n        let relationsA = this._relations.get(origA);\n        if (!relationsA) {\n            relationsA = new Map();\n            this._relations.set(origA, relationsA);\n        }\n        relationsA.set(origB, relation);\n    }\n}\n/**\n * An utility function that updates {@link module:engine/model/operation/operation~Operation#baseVersion base versions}\n * of passed operations.\n *\n * The function simply sets `baseVersion` as a base version of the first passed operation and then increments it for\n * each following operation in `operations`.\n *\n * @param operations Operations to update.\n * @param baseVersion Base version to set for the first operation in `operations`.\n */ function updateBaseVersions(operations, baseVersion) {\n    for (const operation of operations){\n        operation.baseVersion = baseVersion++;\n    }\n}\n/**\n * Adds `howMany` instances of {@link module:engine/model/operation/nooperation~NoOperation} to `operations` set.\n */ function padWithNoOps(operations, howMany) {\n    for(let i = 0; i < howMany; i++){\n        operations.push(new NoOperation(0));\n    }\n}\n/**\n * Transformed operations set may include marker operations which were broken into multiple marker operations during transformation.\n * It represents marker range being broken into multiple pieces as the transformation was processed. Each partial marker operation is\n * a piece of the original marker range.\n *\n * These partial marker operations (\"marker range pieces\") should be \"glued\" together if, after transformations, the ranges ended up\n * next to each other.\n *\n * If the ranges did not end up next to each other, then partial marker operations should be discarded, as the marker range cannot\n * be broken into two pieces.\n *\n * There is always one \"reference\" marker operation (the original operation) and there may be some partial marker operations. Partial\n * marker operations have base version set to `-1`. If the `operations` set includes partial marker operations, then they are always\n * after the original marker operation.\n *\n * See also `MarkerOperation` x `MoveOperation` transformation.\n * See also https://github.com/ckeditor/ckeditor5/pull/17071.\n */ function handlePartialMarkerOperations(operations) {\n    const markerOps = new Map();\n    for(let i = 0; i < operations.length; i++){\n        const op = operations[i];\n        if (!(op instanceof MarkerOperation)) {\n            continue;\n        }\n        if (op.baseVersion !== -1) {\n            markerOps.set(op.name, {\n                op,\n                ranges: op.newRange ? [\n                    op.newRange\n                ] : []\n            });\n        } else {\n            if (op.newRange) {\n                // `markerOps.get( op.name )` must exist because original marker operation is always before partial marker operations.\n                // If the original marker operation was changed to `NoOperation`, then the partial marker operations would be changed\n                // to `NoOperation` as well, so this is not a case.\n                markerOps.get(op.name).ranges.push(op.newRange);\n            }\n            operations.splice(i, 1);\n            i--;\n        }\n    }\n    for (const { op, ranges } of markerOps.values()){\n        if (ranges.length) {\n            op.newRange = Range._createFromRanges(ranges);\n        } else {\n            op.newRange = null;\n        }\n    }\n}\n// -----------------------\nsetTransformation(AttributeOperation, AttributeOperation, (a, b, context)=>{\n    // If operations in conflict, check if their ranges intersect and manage them properly.\n    //\n    // Operations can be in conflict only if:\n    //\n    // * their key is the same (they change the same attribute), and\n    // * they are in the same parent (operations for ranges [ 1 ] - [ 3 ] and [ 2, 0 ] - [ 2, 5 ] change different\n    // elements and can't be in conflict).\n    if (a.key === b.key && a.range.start.hasSameParentAs(b.range.start)) {\n        // First, we want to apply change to the part of a range that has not been changed by the other operation.\n        const operations = a.range.getDifference(b.range).map((range)=>{\n            return new AttributeOperation(range, a.key, a.oldValue, a.newValue, 0);\n        });\n        // Then we take care of the common part of ranges.\n        const common = a.range.getIntersection(b.range);\n        if (common) {\n            // If this operation is more important, we also want to apply change to the part of the\n            // original range that has already been changed by the other operation. Since that range\n            // got changed we also have to update `oldValue`.\n            if (context.aIsStrong) {\n                operations.push(new AttributeOperation(common, b.key, b.newValue, a.newValue, 0));\n            }\n        }\n        if (operations.length == 0) {\n            return [\n                new NoOperation(0)\n            ];\n        }\n        return operations;\n    } else {\n        // If operations don't conflict, simply return an array containing just a clone of this operation.\n        return [\n            a\n        ];\n    }\n});\nsetTransformation(AttributeOperation, InsertOperation, (a, b)=>{\n    // Case 1:\n    //\n    // The attribute operation range includes the position where nodes were inserted.\n    // There are two possible scenarios: the inserted nodes were text and they should receive attributes or\n    // the inserted nodes were elements and they should not receive attributes.\n    //\n    if (a.range.start.hasSameParentAs(b.position) && a.range.containsPosition(b.position)) {\n        // If new nodes should not receive attributes, two separated ranges will be returned.\n        // Otherwise, one expanded range will be returned.\n        const range = a.range._getTransformedByInsertion(b.position, b.howMany, !b.shouldReceiveAttributes);\n        const result = range.map((r)=>{\n            return new AttributeOperation(r, a.key, a.oldValue, a.newValue, a.baseVersion);\n        });\n        if (b.shouldReceiveAttributes) {\n            // `AttributeOperation#range` includes some newly inserted text.\n            // The operation should also change the attribute of that text. An example:\n            //\n            // Bold should be applied on the following range:\n            // <p>Fo[zb]ar</p>\n            //\n            // In meantime, new text is typed:\n            // <p>Fozxxbar</p>\n            //\n            // Bold should be applied also on the new text:\n            // <p>Fo[zxxb]ar</p>\n            // <p>Fo<$text bold=\"true\">zxxb</$text>ar</p>\n            //\n            // There is a special case to consider here to consider.\n            //\n            // Consider setting an attribute with multiple possible values, for example `highlight`. The inserted text might\n            // have already an attribute value applied and the `oldValue` property of the attribute operation might be wrong:\n            //\n            // Attribute `highlight=\"yellow\"` should be applied on the following range:\n            // <p>Fo[zb]ar<p>\n            //\n            // In meantime, character `x` with `highlight=\"red\"` is typed:\n            // <p>Fo[z<$text highlight=\"red\">x</$text>b]ar</p>\n            //\n            // In this case we cannot simply apply operation changing the attribute value from `null` to `\"yellow\"` for the whole range\n            // because that would lead to an exception (`oldValue` is incorrect for `x`).\n            //\n            // We also cannot break the original range as this would mess up a scenario when there are multiple following\n            // insert operations, because then only the first inserted character is included in those ranges:\n            // <p>Fo[z][x][b]ar</p>   -->   <p>Fo[z][x]x[b]ar</p>   -->   <p>Fo[z][x]xx[b]ar</p>\n            //\n            // So, the attribute range needs be expanded, no matter what attributes are set on the inserted nodes:\n            //\n            // <p>Fo[z<$text highlight=\"red\">x</$text>b]ar</p>      <--- Change from `null` to `yellow`, throwing an exception.\n            //\n            // But before that operation would be applied, we will add an additional attribute operation that will change\n            // attributes on the inserted nodes in a way which would make the original operation correct:\n            //\n            // <p>Fo[z{<$text highlight=\"red\">}x</$text>b]ar</p>    <--- Change range `{}` from `red` to `null`.\n            // <p>Fo[zxb]ar</p>                                     <--- Now change from `null` to `yellow` is completely fine.\n            //\n            // Generate complementary attribute operation. Be sure to add it before the original operation.\n            const op = _getComplementaryAttributeOperations(b, a.key, a.oldValue);\n            if (op) {\n                result.unshift(op);\n            }\n        }\n        // If nodes should not receive new attribute, we are done here.\n        return result;\n    }\n    // If insert operation is not expanding the attribute operation range, simply transform the range.\n    a.range = a.range._getTransformedByInsertion(b.position, b.howMany, false)[0];\n    return [\n        a\n    ];\n});\n/**\n * Helper function for `AttributeOperation` x `InsertOperation` (and reverse) transformation.\n *\n * For given `insertOperation` it checks the inserted node if it has an attribute `key` set to a value different\n * than `newValue`. If so, it generates an `AttributeOperation` which changes the value of `key` attribute to `newValue`.\n */ function _getComplementaryAttributeOperations(insertOperation, key, newValue) {\n    const nodes = insertOperation.nodes;\n    // At the beginning we store the attribute value from the first node.\n    const insertValue = nodes.getNode(0).getAttribute(key);\n    if (insertValue == newValue) {\n        return null;\n    }\n    const range = new Range(insertOperation.position, insertOperation.position.getShiftedBy(insertOperation.howMany));\n    return new AttributeOperation(range, key, insertValue, newValue, 0);\n}\nsetTransformation(AttributeOperation, MergeOperation, (a, b)=>{\n    const ranges = [];\n    // Case 1:\n    //\n    // Attribute change on the merged element. In this case, the merged element was moved to the graveyard.\n    // An additional attribute operation that will change the (re)moved element needs to be generated.\n    //\n    if (a.range.start.hasSameParentAs(b.deletionPosition)) {\n        if (a.range.containsPosition(b.deletionPosition) || a.range.start.isEqual(b.deletionPosition)) {\n            ranges.push(Range._createFromPositionAndShift(b.graveyardPosition, 1));\n        }\n    }\n    const range = a.range._getTransformedByMergeOperation(b);\n    // Do not add empty (collapsed) ranges to the result. `range` may be collapsed if it contained only the merged element.\n    if (!range.isCollapsed) {\n        ranges.push(range);\n    }\n    // Create `AttributeOperation`s out of the ranges.\n    return ranges.map((range)=>{\n        return new AttributeOperation(range, a.key, a.oldValue, a.newValue, a.baseVersion);\n    });\n});\nsetTransformation(AttributeOperation, MoveOperation, (a, b)=>{\n    const ranges = _breakRangeByMoveOperation(a.range, b);\n    // Create `AttributeOperation`s out of the ranges.\n    return ranges.map((range)=>new AttributeOperation(range, a.key, a.oldValue, a.newValue, a.baseVersion));\n});\n/**\n * Helper function for `AttributeOperation` x `MoveOperation` transformation.\n *\n * Takes the passed `range` and transforms it by move operation `moveOp` in a specific way. Only top-level nodes of `range`\n * are considered to be in the range. If move operation moves nodes deep from inside of the range, those nodes won't\n * be included in the result. In other words, top-level nodes of the ranges from the result are exactly the same as\n * top-level nodes of the original `range`.\n *\n * This is important for `AttributeOperation` because, for its range, it changes only the top-level nodes. So we need to\n * track only how those nodes have been affected by `MoveOperation`.\n */ function _breakRangeByMoveOperation(range, moveOp) {\n    const moveRange = Range._createFromPositionAndShift(moveOp.sourcePosition, moveOp.howMany);\n    // We are transforming `range` (original range) by `moveRange` (range moved by move operation). As usual when it comes to\n    // transforming a ranges, we may have a common part of the ranges and we may have a difference part (zero to two ranges).\n    let common = null;\n    let difference = [];\n    // Let's compare the ranges.\n    if (moveRange.containsRange(range, true)) {\n        // If the whole original range is moved, treat it whole as a common part. There's also no difference part.\n        common = range;\n    } else if (range.start.hasSameParentAs(moveRange.start)) {\n        // If the ranges are \"on the same level\" (in the same parent) then move operation may move exactly those nodes\n        // that are changed by the attribute operation. In this case we get common part and difference part in the usual way.\n        difference = range.getDifference(moveRange);\n        common = range.getIntersection(moveRange);\n    } else {\n        // In any other situation we assume that original range is different than move range, that is that move operation\n        // moves other nodes that attribute operation change. Even if the moved range is deep inside in the original range.\n        //\n        // Note that this is different than in `.getIntersection` (we would get a common part in that case) and different\n        // than `.getDifference` (we would get two ranges).\n        difference = [\n            range\n        ];\n    }\n    const result = [];\n    // The default behaviour of `_getTransformedByMove` might get wrong results for difference part, though, so\n    // we do it by hand.\n    for (let diff of difference){\n        // First, transform the range by removing moved nodes. Since this is a difference, this is safe, `null` won't be returned\n        // as the range is different than the moved range.\n        diff = diff._getTransformedByDeletion(moveOp.sourcePosition, moveOp.howMany);\n        // Transform also `targetPosition`.\n        const targetPosition = moveOp.getMovedRangeStart();\n        // Spread the range only if moved nodes are inserted only between the top-level nodes of the `diff` range.\n        const spread = diff.start.hasSameParentAs(targetPosition);\n        // Transform by insertion of moved nodes.\n        const diffs = diff._getTransformedByInsertion(targetPosition, moveOp.howMany, spread);\n        result.push(...diffs);\n    }\n    // Common part can be simply transformed by the move operation. This is because move operation will not target to\n    // that common part (the operation would have to target inside its own moved range).\n    if (common) {\n        result.push(common._getTransformedByMove(moveOp.sourcePosition, moveOp.targetPosition, moveOp.howMany, false)[0]);\n    }\n    return result;\n}\nsetTransformation(AttributeOperation, SplitOperation, (a, b)=>{\n    // Case 1:\n    //\n    // Split node is the last node in `AttributeOperation#range`.\n    // `AttributeOperation#range` needs to be expanded to include the new (split) node.\n    //\n    // Attribute `type` to be changed to `numbered` but the `listItem` is split.\n    // <listItem type=\"bulleted\">foobar</listItem>\n    //\n    // After split:\n    // <listItem type=\"bulleted\">foo</listItem><listItem type=\"bulleted\">bar</listItem>\n    //\n    // After attribute change:\n    // <listItem type=\"numbered\">foo</listItem><listItem type=\"numbered\">foo</listItem>\n    //\n    if (a.range.end.isEqual(b.insertionPosition)) {\n        if (!b.graveyardPosition) {\n            a.range.end.offset++;\n        }\n        return [\n            a\n        ];\n    }\n    // Case 2:\n    //\n    // Split position is inside `AttributeOperation#range`, at the same level, so the nodes to change are\n    // not going to make a flat range.\n    //\n    // Content with range-to-change and split position:\n    // <p>Fo[zb^a]r</p>\n    //\n    // After split:\n    // <p>Fozb</p><p>ar</p>\n    //\n    // Make two separate ranges containing all nodes to change:\n    // <p>Fo[zb]</p><p>[a]r</p>\n    //\n    if (a.range.start.hasSameParentAs(b.splitPosition) && a.range.containsPosition(b.splitPosition)) {\n        const secondPart = a.clone();\n        secondPart.range = new Range(b.moveTargetPosition.clone(), a.range.end._getCombined(b.splitPosition, b.moveTargetPosition));\n        a.range.end = b.splitPosition.clone();\n        a.range.end.stickiness = 'toPrevious';\n        return [\n            a,\n            secondPart\n        ];\n    }\n    // The default case.\n    //\n    a.range = a.range._getTransformedBySplitOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(InsertOperation, AttributeOperation, (a, b)=>{\n    const result = [\n        a\n    ];\n    // Case 1:\n    //\n    // The attribute operation range includes the position where nodes were inserted.\n    // There are two possible scenarios: the inserted nodes were text and they should receive attributes or\n    // the inserted nodes were elements and they should not receive attributes.\n    //\n    // This is a mirror scenario to the one described in `AttributeOperation` x `InsertOperation` transformation,\n    // although this case is a little less complicated. In this case we simply need to change attributes of the\n    // inserted nodes and that's it.\n    //\n    if (a.shouldReceiveAttributes && a.position.hasSameParentAs(b.range.start) && b.range.containsPosition(a.position)) {\n        const op = _getComplementaryAttributeOperations(a, b.key, b.newValue);\n        if (op) {\n            result.push(op);\n        }\n    }\n    // The default case is: do nothing.\n    // `AttributeOperation` does not change the model tree structure so `InsertOperation` does not need to be changed.\n    //\n    return result;\n});\nsetTransformation(InsertOperation, InsertOperation, (a, b, context)=>{\n    // Case 1:\n    //\n    // Two insert operations insert nodes at the same position. Since they are the same, it needs to be decided\n    // what will be the order of inserted nodes. However, there is no additional information to help in that\n    // decision. Also, when `b` will be transformed by `a`, the same order must be maintained.\n    //\n    // To achieve that, we will check if the operation is strong.\n    // If it is, it won't get transformed. If it is not, it will be moved.\n    //\n    if (a.position.isEqual(b.position) && context.aIsStrong) {\n        return [\n            a\n        ];\n    }\n    // The default case.\n    //\n    a.position = a.position._getTransformedByInsertOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(InsertOperation, MoveOperation, (a, b)=>{\n    // The default case.\n    //\n    a.position = a.position._getTransformedByMoveOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(InsertOperation, SplitOperation, (a, b)=>{\n    // The default case.\n    //\n    a.position = a.position._getTransformedBySplitOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(InsertOperation, MergeOperation, (a, b)=>{\n    a.position = a.position._getTransformedByMergeOperation(b);\n    return [\n        a\n    ];\n});\n// -----------------------\nsetTransformation(MarkerOperation, InsertOperation, (a, b)=>{\n    if (a.oldRange) {\n        a.oldRange = a.oldRange._getTransformedByInsertOperation(b)[0];\n    }\n    if (a.newRange) {\n        a.newRange = a.newRange._getTransformedByInsertOperation(b)[0];\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(MarkerOperation, MarkerOperation, (a, b, context)=>{\n    if (a.name == b.name) {\n        if (context.aIsStrong) {\n            a.oldRange = b.newRange ? b.newRange.clone() : null;\n        } else {\n            return [\n                new NoOperation(0)\n            ];\n        }\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(MarkerOperation, MergeOperation, (a, b)=>{\n    if (a.oldRange) {\n        a.oldRange = a.oldRange._getTransformedByMergeOperation(b);\n    }\n    if (a.newRange) {\n        a.newRange = a.newRange._getTransformedByMergeOperation(b);\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(MarkerOperation, MoveOperation, (a, b)=>{\n    const result = [\n        a\n    ];\n    if (a.oldRange) {\n        a.oldRange = Range._createFromRanges(a.oldRange._getTransformedByMoveOperation(b));\n    }\n    if (a.newRange) {\n        // In many simple cases the marker range will be kept integral after the transformation. For example, if some nodes\n        // were inserted before the range, or into the range, then the marker range is not broken into two.\n        //\n        // However, if some nodes are taken out of the range and moved somewhere else, or are moved into the range, then the marker\n        // range is \"broken\" into two or three pieces, and these pieces must be transformed and updated separately.\n        //\n        // When the marker range is transformed by move operation, as a result we get an array with one (simple case) or multiple\n        // (\"broken range\" case) ranges.\n        const ranges = a.newRange._getTransformedByMoveOperation(b);\n        a.newRange = ranges[0];\n        // If there are multiple ranges, we will create separate marker operations for each piece of the original marker range.\n        // Since they will be marker operations, they will be processed through the transformation process.\n        //\n        // However, we cannot create multiple ranges for the same marker (for the same marker name). A marker has only one range.\n        // So, we cannot really have multiple marker operations for the same marker. We will keep the track of the separate marker\n        // operations to see, if after all transformations, the marker pieces are next to each other or not. If so, we will glue\n        // them together to the original marker operation (`a`). If not, we will discard them. These extra operations will never\n        // be executed, as they will only exist temporarily during the transformation process.\n        //\n        // We will call these additional marker operations \"partial marker operations\" and we will mark them with negative base version.\n        //\n        // See also `handlePartialMarkerOperations()`.\n        // See also https://github.com/ckeditor/ckeditor5/pull/17071.\n        //\n        for(let i = 1; i < ranges.length; i++){\n            const op = a.clone();\n            op.oldRange = null;\n            op.newRange = ranges[i];\n            op.baseVersion = -1;\n            result.push(op);\n        }\n    }\n    return result;\n});\nsetTransformation(MarkerOperation, SplitOperation, (a, b, context)=>{\n    if (a.oldRange) {\n        a.oldRange = a.oldRange._getTransformedBySplitOperation(b);\n    }\n    if (a.newRange) {\n        if (context.abRelation) {\n            const aNewRange = a.newRange._getTransformedBySplitOperation(b);\n            if (a.newRange.start.isEqual(b.splitPosition) && context.abRelation.wasStartBeforeMergedElement) {\n                a.newRange.start = Position._createAt(b.insertionPosition);\n            } else if (a.newRange.start.isEqual(b.splitPosition) && !context.abRelation.wasInLeftElement) {\n                a.newRange.start = Position._createAt(b.moveTargetPosition);\n            } else {\n                a.newRange.start = aNewRange.start;\n            }\n            if (a.newRange.end.isEqual(b.splitPosition) && context.abRelation.wasInRightElement) {\n                a.newRange.end = Position._createAt(b.moveTargetPosition);\n            } else if (a.newRange.end.isEqual(b.splitPosition) && context.abRelation.wasEndBeforeMergedElement) {\n                a.newRange.end = Position._createAt(b.insertionPosition);\n            } else {\n                a.newRange.end = aNewRange.end;\n            }\n            return [\n                a\n            ];\n        }\n        a.newRange = a.newRange._getTransformedBySplitOperation(b);\n    }\n    return [\n        a\n    ];\n});\n// -----------------------\nsetTransformation(MergeOperation, InsertOperation, (a, b)=>{\n    if (a.sourcePosition.hasSameParentAs(b.position)) {\n        a.howMany += b.howMany;\n    }\n    a.sourcePosition = a.sourcePosition._getTransformedByInsertOperation(b);\n    a.targetPosition = a.targetPosition._getTransformedByInsertOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(MergeOperation, MergeOperation, (a, b, context)=>{\n    // Case 1:\n    //\n    // Same merge operations.\n    //\n    // Both operations have same source and target positions. So the element already got merged and there is\n    // theoretically nothing to do.\n    //\n    if (a.sourcePosition.isEqual(b.sourcePosition) && a.targetPosition.isEqual(b.targetPosition)) {\n        // There are two ways that we can provide a do-nothing operation.\n        //\n        // First is simply a NoOperation instance. We will use it if `b` operation was not undone.\n        //\n        // Second is a merge operation that has the source operation in the merged element - in the graveyard -\n        // same target position and `howMany` equal to `0`. So it is basically merging an empty element from graveyard\n        // which is almost the same as NoOperation.\n        //\n        // This way the merge operation can be later transformed by split operation\n        // to provide correct undo. This will be used if `b` operation was undone (only then it is correct).\n        //\n        if (!context.bWasUndone) {\n            return [\n                new NoOperation(0)\n            ];\n        } else {\n            const path = b.graveyardPosition.path.slice();\n            path.push(0);\n            a.sourcePosition = new Position(b.graveyardPosition.root, path);\n            a.howMany = 0;\n            return [\n                a\n            ];\n        }\n    }\n    // Case 2:\n    //\n    // Same merge source position but different target position.\n    //\n    // This can happen during collaboration. For example, if one client merged a paragraph to the previous paragraph\n    // and the other person removed that paragraph and merged the same paragraph to something before:\n    //\n    // Client A:\n    // <p>Foo</p><p>Bar</p><p>[]Xyz</p>\n    // <p>Foo</p><p>BarXyz</p>\n    //\n    // Client B:\n    // <p>Foo</p>[<p>Bar</p>]<p>Xyz</p>\n    // <p>Foo</p><p>[]Xyz</p>\n    // <p>FooXyz</p>\n    //\n    // In this case we need to decide where finally \"Xyz\" will land:\n    //\n    // <p>FooXyz</p>               graveyard: <p>Bar</p>\n    // <p>Foo</p>                  graveyard: <p>BarXyz</p>\n    //\n    // Let's move it in a way so that a merge operation that does not target to graveyard is more important so that\n    // nodes does not end up in the graveyard. It makes sense. Both for Client A and for Client B \"Xyz\" finally did not\n    // end up in the graveyard (see above).\n    //\n    // If neither or both operations point to graveyard, then let `aIsStrong` decide.\n    //\n    if (a.sourcePosition.isEqual(b.sourcePosition) && !a.targetPosition.isEqual(b.targetPosition) && !context.bWasUndone && context.abRelation != 'splitAtSource') {\n        const aToGraveyard = a.targetPosition.root.rootName == '$graveyard';\n        const bToGraveyard = b.targetPosition.root.rootName == '$graveyard';\n        // If `aIsWeak` it means that `a` points to graveyard while `b` doesn't. Don't move nodes then.\n        const aIsWeak = aToGraveyard && !bToGraveyard;\n        // If `bIsWeak` it means that `b` points to graveyard while `a` doesn't. Force moving nodes then.\n        const bIsWeak = bToGraveyard && !aToGraveyard;\n        // Force move if `b` is weak or neither operation is weak but `a` is stronger through `context.aIsStrong`.\n        const forceMove = bIsWeak || !aIsWeak && context.aIsStrong;\n        if (forceMove) {\n            const sourcePosition = b.targetPosition._getTransformedByMergeOperation(b);\n            const targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n            return [\n                new MoveOperation(sourcePosition, a.howMany, targetPosition, 0)\n            ];\n        } else {\n            return [\n                new NoOperation(0)\n            ];\n        }\n    }\n    // The default case.\n    // TODO: Possibly, there's a missing case for same `targetPosition` but different `sourcePosition`.\n    //\n    if (a.sourcePosition.hasSameParentAs(b.targetPosition)) {\n        a.howMany += b.howMany;\n    }\n    a.sourcePosition = a.sourcePosition._getTransformedByMergeOperation(b);\n    a.targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n    // Handle positions in graveyard.\n    // If graveyard positions are same and `a` operation is strong - do not transform.\n    if (!a.graveyardPosition.isEqual(b.graveyardPosition) || !context.aIsStrong) {\n        a.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation(b);\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(MergeOperation, MoveOperation, (a, b, context)=>{\n    // Case 1:\n    //\n    // The element to merge got removed.\n    //\n    // Merge operation does support merging elements which are not siblings. So it would not be a problem\n    // from technical point of view. However, if the element was removed, the intention of the user deleting it\n    // was to have it all deleted, together with its children. From user experience point of view, moving back the\n    // removed nodes might be unexpected. This means that in this scenario we will block the merging.\n    //\n    // The exception to this rule would be if the remove operation was later undone.\n    //\n    const removedRange = Range._createFromPositionAndShift(b.sourcePosition, b.howMany);\n    if (b.type == 'remove' && !context.bWasUndone) {\n        if (a.deletionPosition.hasSameParentAs(b.sourcePosition) && removedRange.containsPosition(a.sourcePosition)) {\n            return [\n                new NoOperation(0)\n            ];\n        }\n    }\n    // In most cases we want `sourcePosition` to stick to previous and `targetPosition` to stick to next.\n    // Usually, `sourcePosition` is at the beginning of the merged element and `targetPosition` is at the end of the merge-target element.\n    //\n    // However, `sourcePosition` and `targetPosition` may end up in the middle of an element due to some OT magic that happens during undo.\n    // It is expected and used in `MergeOperation` x `SplitOperation` transformation.\n    //\n    // But when these positions are in the middle, it messes up the regular `MergeOperation` x `MoveOperation` transformation because\n    // these positions may \"follow\" some moved elements. And we want them stick in the original elements.\n    //\n    // This is why we add two extra cases: (1) and (2).\n    //\n    // But after this `MergeOperation` is transformed by \"this\" move (which is undone), we also need to define extra cases for\n    // the operation undoing previous move. These are (3) and (4).\n    //\n    // (1). Note that this case is also added to `updateRelations()` and sets `mergeSourceAffected` relation.\n    //\n    // [] is move operation, } is merge source position (sticks to previous by default):\n    // <p>A[b]}c</p>  ->  <p>A}c</p>\n    //\n    if (b.sourcePosition.getShiftedBy(b.howMany).isEqual(a.sourcePosition)) {\n        a.sourcePosition.stickiness = 'toNone';\n    } else if (b.targetPosition.isEqual(a.sourcePosition) && context.abRelation == 'mergeSourceAffected') {\n        a.sourcePosition.stickiness = 'toNext';\n    } else if (b.sourcePosition.isEqual(a.targetPosition)) {\n        a.targetPosition.stickiness = 'toNone';\n        a.howMany -= b.howMany;\n    } else if (b.targetPosition.isEqual(a.targetPosition) && context.abRelation == 'mergeTargetWasBefore') {\n        a.targetPosition.stickiness = 'toPrevious';\n        a.howMany += b.howMany;\n    } else {\n        if (a.sourcePosition.hasSameParentAs(b.targetPosition)) {\n            a.howMany += b.howMany;\n        }\n        if (a.sourcePosition.hasSameParentAs(b.sourcePosition)) {\n            a.howMany -= b.howMany;\n        }\n    }\n    a.sourcePosition = a.sourcePosition._getTransformedByMoveOperation(b);\n    a.targetPosition = a.targetPosition._getTransformedByMoveOperation(b);\n    // After transformations are done, make sure to revert stickiness in case if (1) - (4) scenario happened.\n    a.sourcePosition.stickiness = 'toPrevious';\n    a.targetPosition.stickiness = 'toNext';\n    // `MergeOperation` graveyard position is like `MoveOperation` target position. It is a position where element(s) will\n    // be moved. Like in other similar cases, we need to consider the scenario when those positions are same.\n    // Here, we will treat `MergeOperation` like it is always strong (see `InsertOperation` x `InsertOperation` for comparison).\n    // This means that we won't transform graveyard position if it is equal to move operation target position.\n    if (!a.graveyardPosition.isEqual(b.targetPosition)) {\n        a.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation(b);\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(MergeOperation, SplitOperation, (a, b, context)=>{\n    if (b.graveyardPosition) {\n        // If `b` operation defines graveyard position, a node from graveyard will be moved. This means that we need to\n        // transform `a.graveyardPosition` accordingly.\n        a.graveyardPosition = a.graveyardPosition._getTransformedByDeletion(b.graveyardPosition, 1);\n        // This is a scenario foreseen in `MergeOperation` x `MergeOperation`, with two identical merge operations.\n        //\n        // So, there was `MergeOperation` x `MergeOperation` transformation earlier. Now, `a` is a merge operation which\n        // source position is in graveyard. Interestingly, split operation wants to use the node to be merged by `a`. This\n        // means that `b` is undoing that merge operation from earlier, which caused `a` to be in graveyard.\n        //\n        // If that's the case, at this point, we will only \"fix\" `a.howMany`. It was earlier set to `0` in\n        // `MergeOperation` x `MergeOperation` transformation. Later transformations in this function will change other\n        // properties.\n        //\n        if (a.deletionPosition.isEqual(b.graveyardPosition)) {\n            a.howMany = b.howMany;\n        }\n    }\n    // Case 1:\n    //\n    // Merge operation moves nodes to the place where split happens.\n    //\n    // This is a classic situation when there are two paragraphs, and there is a split (enter) at the end of the first\n    // paragraph and there is a merge (delete) at the beginning of the second paragraph:\n    //\n    // <p>Foo{}</p><p>[]Bar</p>.\n    //\n    // User A presses enter after `Foo`, while User B presses backspace before `Bar`. It is intuitive that after both operations, the\n    // editor state should stay the same.\n    //\n    // State after split:\n    // <p>Foo</p><p></p><p>[]Bar</p>\n    //\n    // When this happens, `Bar` should be merged to the newly created paragraph, to maintain the editor state:\n    // <p>Foo</p><p>Bar</p>\n    //\n    // Another option is to merge into the original paragraph `Foo`, according to the `targetPosition`. This results in an incorrect state:\n    // <p>FooBar</p><p></p>\n    //\n    // Also, consider an example where User A also writes something in the new paragraph:\n    // <p>Foo</p><p>Xyz</p><p>[]Bar</p>\n    //\n    // In this case it is clear that merge should happen into `[ 1, 3 ]` not into `[ 0, 3 ]`. It first has to be transformed to `[ 1, 0 ]`,\n    // and then transformed be insertion into `[ 1, 3 ]`.\n    //\n    // So, usually we want to move `targetPosition` to the new paragraph when it is same as split position. This is how it is handled\n    // in the default transformation (`_getTransformedBySplitOperation()`). We don't need a special case for this.\n    //\n    // However, there are two exceptions, when we **do not** want to transform `targetPosition`, and we need a special case then.\n    //\n    // These exceptions happen only if undo is involved. During OT, above presented case (`<p>Foo{}</p><p>[]Bar</p>`) is the only way\n    // how `SplitOperation#splitPosition` and `MergeOperation#targetPosition` can be the same.\n    //\n    // First exception is when the element to merge is in the graveyard and split operation uses it. In that case\n    // if target position would be transformed, the merge operation would target at the source position:\n    //\n    // root: <p>Foo[]</p>\t\t\t\tgraveyard: <p></p>\n    //\n    // SplitOperation: root [ 0, 3 ] using graveyard [ 0 ] (howMany = 0)\n    // MergeOperation: graveyard [ 0, 0 ] -> root [ 0, 3 ] (howMany = 0)\n    //\n    // Since split operation moves the graveyard element back to the root (to path `[ 1 ]`), the merge operation `sourcePosition` changes.\n    // After split we have: `<p>Foo</p><p></p>`, so `sourcePosition` is `[ 1, 0 ]`. But if `targetPosition` is transformed, then it\n    // also becomes `[ 1, 0 ]`. In this case, we want to keep the `targetPosition` as it was.\n    //\n    // Second exception is connected strictly with undo relations. If this `MergeOperation` was earlier transformed by\n    // `MergeOperation` and we stored an information that earlier the target position was not affected, then here, when transforming by\n    // `SplitOperation` we are not going to change it as well.\n    //\n    // For these two cases we will only transform `sourcePosition` and return early.\n    //\n    // Note, that earlier there was also third special case here. `targetPosition` was not transformed, if it pointed into the middle of\n    // target element, not into its end (as usual). This can also happen only with undo involved. However, it wasn't always a correct\n    // solution, as in some cases we actually wanted to transform `targetPosition`. Also, this case usually happens together with the second\n    // case described above. There is only one scenario that we have in our unit tests, where this third case happened without second case.\n    // However, this scenario went fine no matter if we transformed `targetPosition` or not. That's because this happened in the middle\n    // of transformation process and the operation was correctly transformed later on.\n    //\n    if (a.targetPosition.isEqual(b.splitPosition)) {\n        const mergeSplittingElement = b.graveyardPosition && a.deletionPosition.isEqual(b.graveyardPosition);\n        if (mergeSplittingElement || context.abRelation == 'mergeTargetNotMoved') {\n            a.sourcePosition = a.sourcePosition._getTransformedBySplitOperation(b);\n            return [\n                a\n            ];\n        }\n    }\n    // Case 2:\n    //\n    // Merge source is at the same position as split position. This sometimes happen, mostly during undo.\n    // The decision here is mostly to choose whether merge source position should stay where it is (so it will be at the end of the\n    // split element) or should be move to the beginning of the new element.\n    //\n    if (a.sourcePosition.isEqual(b.splitPosition)) {\n        // Use context to check if `SplitOperation` is not undoing a merge operation, that didn't change the `a` operation.\n        // This scenario happens the undone merge operation moved nodes at the source position of `a` operation.\n        // In that case `a` operation source position should stay where it is.\n        if (context.abRelation == 'mergeSourceNotMoved') {\n            a.howMany = 0;\n            a.targetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n            return [\n                a\n            ];\n        }\n        // This merge operation might have been earlier transformed by a merge operation which both merged the same element.\n        // See that case in `MergeOperation` x `MergeOperation` transformation. In that scenario, if the merge operation has been undone,\n        // the special case is not applied.\n        //\n        // Now, the merge operation is transformed by the split which has undone that previous merge operation.\n        // So now we are fixing situation which was skipped in `MergeOperation` x `MergeOperation` case.\n        //\n        if (context.abRelation == 'mergeSameElement' || a.sourcePosition.offset > 0) {\n            a.sourcePosition = b.moveTargetPosition.clone();\n            a.targetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n            return [\n                a\n            ];\n        }\n    }\n    // The default case.\n    //\n    if (a.sourcePosition.hasSameParentAs(b.splitPosition)) {\n        a.howMany = b.splitPosition.offset;\n    }\n    a.sourcePosition = a.sourcePosition._getTransformedBySplitOperation(b);\n    a.targetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n    return [\n        a\n    ];\n});\n// -----------------------\nsetTransformation(MoveOperation, InsertOperation, (a, b)=>{\n    const moveRange = Range._createFromPositionAndShift(a.sourcePosition, a.howMany);\n    const transformed = moveRange._getTransformedByInsertOperation(b, false)[0];\n    a.sourcePosition = transformed.start;\n    a.howMany = transformed.end.offset - transformed.start.offset;\n    // See `InsertOperation` x `MoveOperation` transformation for details on this case.\n    //\n    // In summary, both operations point to the same place, so the order of nodes needs to be decided.\n    // `MoveOperation` is considered weaker, so it is always transformed, unless there was a certain relation\n    // between operations.\n    //\n    if (!a.targetPosition.isEqual(b.position)) {\n        a.targetPosition = a.targetPosition._getTransformedByInsertOperation(b);\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(MoveOperation, MoveOperation, (a, b, context)=>{\n    //\n    // Setting and evaluating some variables that will be used in special cases and default algorithm.\n    //\n    // Create ranges from `MoveOperations` properties.\n    const rangeA = Range._createFromPositionAndShift(a.sourcePosition, a.howMany);\n    const rangeB = Range._createFromPositionAndShift(b.sourcePosition, b.howMany);\n    // Assign `context.aIsStrong` to a different variable, because the value may change during execution of\n    // this algorithm and we do not want to override original `context.aIsStrong` that will be used in later transformations.\n    let aIsStrong = context.aIsStrong;\n    // This will be used to decide the order of nodes if both operations target at the same position.\n    // By default, use strong/weak operation mechanism.\n    let insertBefore = !context.aIsStrong;\n    // If the relation is set, then use it to decide nodes order.\n    if (context.abRelation == 'insertBefore' || context.baRelation == 'insertAfter') {\n        insertBefore = true;\n    } else if (context.abRelation == 'insertAfter' || context.baRelation == 'insertBefore') {\n        insertBefore = false;\n    }\n    // `a.targetPosition` could be affected by the `b` operation. We will transform it.\n    let newTargetPosition;\n    if (a.targetPosition.isEqual(b.targetPosition) && insertBefore) {\n        newTargetPosition = a.targetPosition._getTransformedByDeletion(b.sourcePosition, b.howMany);\n    } else {\n        newTargetPosition = a.targetPosition._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n    }\n    //\n    // Special case #1 + mirror.\n    //\n    // Special case when both move operations' target positions are inside nodes that are\n    // being moved by the other move operation. So in other words, we move ranges into inside of each other.\n    // This case can't be solved reasonably (on the other hand, it should not happen often).\n    if (_moveTargetIntoMovedRange(a, b) && _moveTargetIntoMovedRange(b, a)) {\n        // Instead of transforming operation, we return a reverse of the operation that we transform by.\n        // So when the results of this \"transformation\" will be applied, `b` MoveOperation will get reversed.\n        return [\n            b.getReversed()\n        ];\n    }\n    //\n    // End of special case #1.\n    //\n    //\n    // Special case #2.\n    //\n    // Check if `b` operation targets inside `rangeA`.\n    const bTargetsToA = rangeA.containsPosition(b.targetPosition);\n    // If `b` targets to `rangeA` and `rangeA` contains `rangeB`, `b` operation has no influence on `a` operation.\n    // You might say that operation `b` is captured inside operation `a`.\n    if (bTargetsToA && rangeA.containsRange(rangeB, true)) {\n        // There is a mini-special case here, where `rangeB` is on other level than `rangeA`. That's why\n        // we need to transform `a` operation anyway.\n        rangeA.start = rangeA.start._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n        rangeA.end = rangeA.end._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n        return _makeMoveOperationsFromRanges([\n            rangeA\n        ], newTargetPosition);\n    }\n    //\n    // Special case #2 mirror.\n    //\n    const aTargetsToB = rangeB.containsPosition(a.targetPosition);\n    if (aTargetsToB && rangeB.containsRange(rangeA, true)) {\n        // `a` operation is \"moved together\" with `b` operation.\n        // Here, just move `rangeA` \"inside\" `rangeB`.\n        rangeA.start = rangeA.start._getCombined(b.sourcePosition, b.getMovedRangeStart());\n        rangeA.end = rangeA.end._getCombined(b.sourcePosition, b.getMovedRangeStart());\n        return _makeMoveOperationsFromRanges([\n            rangeA\n        ], newTargetPosition);\n    }\n    //\n    // End of special case #2.\n    //\n    //\n    // Special case #3 + mirror.\n    //\n    // `rangeA` has a node which is an ancestor of `rangeB`. In other words, `rangeB` is inside `rangeA`\n    // but not on the same tree level. In such case ranges have common part but we have to treat it\n    // differently, because in such case those ranges are not really conflicting and should be treated like\n    // two separate ranges. Also we have to discard two difference parts.\n    const aCompB = compareArrays(a.sourcePosition.getParentPath(), b.sourcePosition.getParentPath());\n    if (aCompB == 'prefix' || aCompB == 'extension') {\n        // Transform `rangeA` by `b` operation and make operation out of it, and that's all.\n        // Note that this is a simplified version of default case, but here we treat the common part (whole `rangeA`)\n        // like a one difference part.\n        rangeA.start = rangeA.start._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n        rangeA.end = rangeA.end._getTransformedByMove(b.sourcePosition, b.targetPosition, b.howMany);\n        return _makeMoveOperationsFromRanges([\n            rangeA\n        ], newTargetPosition);\n    }\n    //\n    // End of special case #3.\n    //\n    //\n    // Default case - ranges are on the same level or are not connected with each other.\n    //\n    // Modifier for default case.\n    // Modifies `aIsStrong` flag in certain conditions.\n    //\n    // If only one of operations is a remove operation, we force remove operation to be the \"stronger\" one\n    // to provide more expected results.\n    if (a.type == 'remove' && b.type != 'remove' && !context.aWasUndone && !context.forceWeakRemove) {\n        aIsStrong = true;\n    } else if (a.type != 'remove' && b.type == 'remove' && !context.bWasUndone && !context.forceWeakRemove) {\n        aIsStrong = false;\n    }\n    // Handle operation's source ranges - check how `rangeA` is affected by `b` operation.\n    // This will aggregate transformed ranges.\n    const ranges = [];\n    // Get the \"difference part\" of `a` operation source range.\n    // This is an array with one or two ranges. Two ranges if `rangeB` is inside `rangeA`.\n    const difference = rangeA.getDifference(rangeB);\n    for (const range of difference){\n        // Transform those ranges by `b` operation. For example if `b` moved range from before those ranges, fix those ranges.\n        range.start = range.start._getTransformedByDeletion(b.sourcePosition, b.howMany);\n        range.end = range.end._getTransformedByDeletion(b.sourcePosition, b.howMany);\n        // If `b` operation targets into `rangeA` on the same level, spread `rangeA` into two ranges.\n        const shouldSpread = compareArrays(range.start.getParentPath(), b.getMovedRangeStart().getParentPath()) == 'same';\n        const newRanges = range._getTransformedByInsertion(b.getMovedRangeStart(), b.howMany, shouldSpread);\n        ranges.push(...newRanges);\n    }\n    // Then, we have to manage the \"common part\" of both move ranges.\n    const common = rangeA.getIntersection(rangeB);\n    if (common !== null && aIsStrong) {\n        // Calculate the new position of that part of original range.\n        common.start = common.start._getCombined(b.sourcePosition, b.getMovedRangeStart());\n        common.end = common.end._getCombined(b.sourcePosition, b.getMovedRangeStart());\n        // Take care of proper range order.\n        //\n        // Put `common` at appropriate place. Keep in mind that we are interested in original order.\n        // Basically there are only three cases: there is zero, one or two difference ranges.\n        //\n        // If there is zero difference ranges, just push `common` in the array.\n        if (ranges.length === 0) {\n            ranges.push(common);\n        } else if (ranges.length == 1) {\n            if (rangeB.start.isBefore(rangeA.start) || rangeB.start.isEqual(rangeA.start)) {\n                ranges.unshift(common);\n            } else {\n                ranges.push(common);\n            }\n        } else {\n            ranges.splice(1, 0, common);\n        }\n    }\n    if (ranges.length === 0) {\n        // If there are no \"source ranges\", nothing should be changed.\n        // Note that this can happen only if `aIsStrong == false` and `rangeA.isEqual( rangeB )`.\n        return [\n            new NoOperation(a.baseVersion)\n        ];\n    }\n    return _makeMoveOperationsFromRanges(ranges, newTargetPosition);\n});\nsetTransformation(MoveOperation, SplitOperation, (a, b, context)=>{\n    let newTargetPosition = a.targetPosition.clone();\n    // Do not transform if target position is same as split insertion position and this split comes from undo.\n    // This should be done on relations but it is too much work for now as it would require relations working in collaboration.\n    // We need to make a decision how we will resolve such conflict and this is less harmful way.\n    if (!a.targetPosition.isEqual(b.insertionPosition) || !b.graveyardPosition || context.abRelation == 'moveTargetAfter') {\n        newTargetPosition = a.targetPosition._getTransformedBySplitOperation(b);\n    }\n    // Case 1:\n    //\n    // Last element in the moved range got split.\n    //\n    // In this case the default range transformation will not work correctly as the element created by\n    // split operation would be outside the range. The range to move needs to be fixed manually.\n    //\n    const moveRange = Range._createFromPositionAndShift(a.sourcePosition, a.howMany);\n    if (moveRange.end.isEqual(b.insertionPosition)) {\n        // Do it only if this is a \"natural\" split, not a one that comes from undo.\n        // If this is undo split, only `targetPosition` needs to be changed (if the move is a remove).\n        if (!b.graveyardPosition) {\n            a.howMany++;\n        }\n        a.targetPosition = newTargetPosition;\n        return [\n            a\n        ];\n    }\n    // Case 2:\n    //\n    // Split happened between the moved nodes. In this case two ranges to move need to be generated.\n    //\n    // Characters `ozba` are moved to the end of paragraph `Xyz` but split happened.\n    // <p>F[oz|ba]r</p><p>Xyz</p>\n    //\n    // After split:\n    // <p>F[oz</p><p>ba]r</p><p>Xyz</p>\n    //\n    // Correct ranges:\n    // <p>F[oz]</p><p>[ba]r</p><p>Xyz</p>\n    //\n    // After move:\n    // <p>F</p><p>r</p><p>Xyzozba</p>\n    //\n    if (moveRange.start.hasSameParentAs(b.splitPosition) && moveRange.containsPosition(b.splitPosition)) {\n        let rightRange = new Range(b.splitPosition, moveRange.end);\n        rightRange = rightRange._getTransformedBySplitOperation(b);\n        const ranges = [\n            new Range(moveRange.start, b.splitPosition),\n            rightRange\n        ];\n        return _makeMoveOperationsFromRanges(ranges, newTargetPosition);\n    }\n    // Case 3:\n    //\n    // Move operation targets at the split position. We need to decide if the nodes should be inserted\n    // at the end of the split element or at the beginning of the new element.\n    //\n    if (a.targetPosition.isEqual(b.splitPosition) && context.abRelation == 'insertAtSource') {\n        newTargetPosition = b.moveTargetPosition;\n    }\n    // Case 4:\n    //\n    // Move operation targets just after the split element. We need to decide if the nodes should be inserted\n    // between two parts of split element, or after the new element.\n    //\n    // Split at `|`, while move operation moves `<p>Xyz</p>` and targets at `^`:\n    // <p>Foo|bar</p>^<p>baz</p>\n    // <p>Foo</p>^<p>bar</p><p>baz</p> or <p>Foo</p><p>bar</p>^<p>baz</p>?\n    //\n    // If there is no contextual information between operations (for example, they come from collaborative\n    // editing), we don't want to put some unrelated content (move) between parts of related content (split parts).\n    // However, if the split is from undo, in the past, the moved content might be targeting between the\n    // split parts, meaning that was exactly user's intention:\n    //\n    // <p>Foo</p>^<p>bar</p>\t\t<--- original situation, in \"past\".\n    // <p>Foobar</p>^\t\t\t\t<--- after merge target position is transformed.\n    // <p>Foo|bar</p>^\t\t\t\t<--- then the merge is undone, and split happens, which leads us to current situation.\n    //\n    // In this case it is pretty clear that the intention was to put new paragraph between those nodes,\n    // so we need to transform accordingly. We can detect this scenario thanks to relations.\n    //\n    if (a.targetPosition.isEqual(b.insertionPosition) && context.abRelation == 'insertBetween') {\n        newTargetPosition = a.targetPosition;\n    }\n    // The default case.\n    //\n    const transformed = moveRange._getTransformedBySplitOperation(b);\n    const ranges = [\n        transformed\n    ];\n    // Case 5:\n    //\n    // Moved range contains graveyard element used by split operation. Add extra move operation to the result.\n    //\n    if (b.graveyardPosition) {\n        const movesGraveyardElement = moveRange.start.isEqual(b.graveyardPosition) || moveRange.containsPosition(b.graveyardPosition);\n        if (a.howMany > 1 && movesGraveyardElement && !context.aWasUndone) {\n            ranges.push(Range._createFromPositionAndShift(b.insertionPosition, 1));\n        }\n    }\n    return _makeMoveOperationsFromRanges(ranges, newTargetPosition);\n});\nsetTransformation(MoveOperation, MergeOperation, (a, b, context)=>{\n    const movedRange = Range._createFromPositionAndShift(a.sourcePosition, a.howMany);\n    if (b.deletionPosition.hasSameParentAs(a.sourcePosition) && movedRange.containsPosition(b.sourcePosition)) {\n        if (a.type == 'remove' && !context.forceWeakRemove) {\n            // Case 1:\n            //\n            // The element to remove got merged.\n            //\n            // Merge operation does support merging elements which are not siblings. So it would not be a problem\n            // from technical point of view. However, if the element was removed, the intention of the user\n            // deleting it was to have it all deleted. From user experience point of view, moving back the\n            // removed nodes might be unexpected. This means that in this scenario we will reverse merging and remove the element.\n            //\n            if (!context.aWasUndone) {\n                const results = [];\n                let gyMoveSource = b.graveyardPosition.clone();\n                let splitNodesMoveSource = b.targetPosition._getTransformedByMergeOperation(b);\n                // `a.targetPosition` points to graveyard, so it was probably affected by `b` (which moved merged element to the graveyard).\n                const aTarget = a.targetPosition.getTransformedByOperation(b);\n                if (a.howMany > 1) {\n                    results.push(new MoveOperation(a.sourcePosition, a.howMany - 1, aTarget, 0));\n                    gyMoveSource = gyMoveSource._getTransformedByMove(a.sourcePosition, aTarget, a.howMany - 1);\n                    splitNodesMoveSource = splitNodesMoveSource._getTransformedByMove(a.sourcePosition, aTarget, a.howMany - 1);\n                }\n                const gyMoveTarget = b.deletionPosition._getCombined(a.sourcePosition, aTarget);\n                const gyMove = new MoveOperation(gyMoveSource, 1, gyMoveTarget, 0);\n                const splitNodesMoveTargetPath = gyMove.getMovedRangeStart().path.slice();\n                splitNodesMoveTargetPath.push(0);\n                const splitNodesMoveTarget = new Position(gyMove.targetPosition.root, splitNodesMoveTargetPath);\n                splitNodesMoveSource = splitNodesMoveSource._getTransformedByMove(gyMoveSource, gyMoveTarget, 1);\n                const splitNodesMove = new MoveOperation(splitNodesMoveSource, b.howMany, splitNodesMoveTarget, 0);\n                results.push(gyMove);\n                results.push(splitNodesMove);\n                return results;\n            }\n        } else {\n            // Case 2:\n            //\n            // The element to move got merged and it was the only element to move.\n            // In this case just don't do anything, leave the node in the graveyard. Without special case\n            // it would be a move operation that moves 0 nodes, so maybe it is better just to return no-op.\n            //\n            if (a.howMany == 1) {\n                if (!context.bWasUndone) {\n                    return [\n                        new NoOperation(0)\n                    ];\n                } else {\n                    a.sourcePosition = b.graveyardPosition.clone();\n                    a.targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n                    return [\n                        a\n                    ];\n                }\n            }\n        }\n    }\n    // The default case.\n    //\n    const moveRange = Range._createFromPositionAndShift(a.sourcePosition, a.howMany);\n    const transformed = moveRange._getTransformedByMergeOperation(b);\n    a.sourcePosition = transformed.start;\n    a.howMany = transformed.end.offset - transformed.start.offset;\n    a.targetPosition = a.targetPosition._getTransformedByMergeOperation(b);\n    return [\n        a\n    ];\n});\n// -----------------------\nsetTransformation(RenameOperation, InsertOperation, (a, b)=>{\n    a.position = a.position._getTransformedByInsertOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(RenameOperation, MergeOperation, (a, b)=>{\n    // Case 1:\n    //\n    // Element to rename got merged, so it was moved to `b.graveyardPosition`.\n    //\n    if (a.position.isEqual(b.deletionPosition)) {\n        a.position = b.graveyardPosition.clone();\n        a.position.stickiness = 'toNext';\n        return [\n            a\n        ];\n    }\n    a.position = a.position._getTransformedByMergeOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(RenameOperation, MoveOperation, (a, b)=>{\n    a.position = a.position._getTransformedByMoveOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(RenameOperation, RenameOperation, (a, b, context)=>{\n    if (a.position.isEqual(b.position)) {\n        if (context.aIsStrong) {\n            a.oldName = b.newName;\n        } else {\n            return [\n                new NoOperation(0)\n            ];\n        }\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(RenameOperation, SplitOperation, (a, b)=>{\n    // Case 1:\n    //\n    // The element to rename has been split. In this case, the new element should be also renamed.\n    //\n    // User decides to change the paragraph to a list item:\n    // <paragraph>Foobar</paragraph>\n    //\n    // However, in meantime, split happens:\n    // <paragraph>Foo</paragraph><paragraph>bar</paragraph>\n    //\n    // As a result, rename both elements:\n    // <listItem>Foo</listItem><listItem>bar</listItem>\n    //\n    const renamePath = a.position.path;\n    const splitPath = b.splitPosition.getParentPath();\n    if (compareArrays(renamePath, splitPath) == 'same' && !b.graveyardPosition) {\n        const extraRename = new RenameOperation(a.position.getShiftedBy(1), a.oldName, a.newName, 0);\n        return [\n            a,\n            extraRename\n        ];\n    }\n    // The default case.\n    //\n    a.position = a.position._getTransformedBySplitOperation(b);\n    return [\n        a\n    ];\n});\n// -----------------------\nsetTransformation(RootAttributeOperation, RootAttributeOperation, (a, b, context)=>{\n    if (a.root === b.root && a.key === b.key) {\n        if (!context.aIsStrong || a.newValue === b.newValue) {\n            return [\n                new NoOperation(0)\n            ];\n        } else {\n            a.oldValue = b.newValue;\n        }\n    }\n    return [\n        a\n    ];\n});\n// -----------------------\nsetTransformation(RootOperation, RootOperation, (a, b)=>{\n    if (a.rootName === b.rootName && a.isAdd === b.isAdd) {\n        return [\n            new NoOperation(0)\n        ];\n    }\n    return [\n        a\n    ];\n});\n// -----------------------\nsetTransformation(SplitOperation, InsertOperation, (a, b)=>{\n    // The default case.\n    //\n    if (a.splitPosition.hasSameParentAs(b.position) && a.splitPosition.offset < b.position.offset) {\n        a.howMany += b.howMany;\n    }\n    a.splitPosition = a.splitPosition._getTransformedByInsertOperation(b);\n    a.insertionPosition = a.insertionPosition._getTransformedByInsertOperation(b);\n    return [\n        a\n    ];\n});\nsetTransformation(SplitOperation, MergeOperation, (a, b, context)=>{\n    // Case 1:\n    //\n    // Split element got merged. If two different elements were merged, clients will have different content.\n    //\n    // Example. Merge at `{}`, split at `[]`:\n    // <heading>Foo</heading>{}<paragraph>B[]ar</paragraph>\n    //\n    // On merge side it will look like this:\n    // <heading>FooB[]ar</heading>\n    // <heading>FooB</heading><heading>ar</heading>\n    //\n    // On split side it will look like this:\n    // <heading>Foo</heading>{}<paragraph>B</paragraph><paragraph>ar</paragraph>\n    // <heading>FooB</heading><paragraph>ar</paragraph>\n    //\n    // Clearly, the second element is different for both clients.\n    //\n    // We could use the removed merge element from graveyard as a split element but then clients would have a different\n    // model state (in graveyard), because the split side client would still have an element in graveyard (removed by merge).\n    //\n    // To overcome this, in `SplitOperation` x `MergeOperation` transformation we will add additional `SplitOperation`\n    // in the graveyard, which will actually clone the merged-and-deleted element. Then, that cloned element will be\n    // used for splitting. Example below.\n    //\n    // Original state:\n    // <heading>Foo</heading>{}<paragraph>B[]ar</paragraph>\n    //\n    // Merge side client:\n    //\n    // After merge:\n    // <heading>FooB[]ar</heading>                                 graveyard: <paragraph></paragraph>\n    //\n    // Extra split:\n    // <heading>FooB[]ar</heading>                                 graveyard: <paragraph></paragraph><paragraph></paragraph>\n    //\n    // Use the \"cloned\" element from graveyard:\n    // <heading>FooB</heading><paragraph>ar</paragraph>            graveyard: <paragraph></paragraph>\n    //\n    // Split side client:\n    //\n    // After split:\n    // <heading>Foo</heading>{}<paragraph>B</paragraph><paragraph>ar</paragraph>\n    //\n    // After merge:\n    // <heading>FooB</heading><paragraph>ar</paragraph>            graveyard: <paragraph></paragraph>\n    //\n    // This special case scenario only applies if the original split operation clones the split element.\n    // If the original split operation has `graveyardPosition` set, it all doesn't have sense because split operation\n    // knows exactly which element it should use. So there would be no original problem with different contents.\n    //\n    // Additionally, the special case applies only if the merge wasn't already undone.\n    //\n    if (!a.graveyardPosition && !context.bWasUndone && a.splitPosition.hasSameParentAs(b.sourcePosition)) {\n        const splitPath = b.graveyardPosition.path.slice();\n        splitPath.push(0);\n        const splitPosition = new Position(b.graveyardPosition.root, splitPath);\n        const insertionPosition = SplitOperation.getInsertionPosition(new Position(b.graveyardPosition.root, splitPath));\n        const additionalSplit = new SplitOperation(splitPosition, 0, insertionPosition, null, 0);\n        a.splitPosition = a.splitPosition._getTransformedByMergeOperation(b);\n        a.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n        a.graveyardPosition = additionalSplit.insertionPosition.clone();\n        a.graveyardPosition.stickiness = 'toNext';\n        return [\n            additionalSplit,\n            a\n        ];\n    }\n    // The default case.\n    //\n    if (a.splitPosition.hasSameParentAs(b.deletionPosition) && !a.splitPosition.isAfter(b.deletionPosition)) {\n        a.howMany--;\n    }\n    if (a.splitPosition.hasSameParentAs(b.targetPosition)) {\n        a.howMany += b.howMany;\n    }\n    a.splitPosition = a.splitPosition._getTransformedByMergeOperation(b);\n    a.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n    if (a.graveyardPosition) {\n        a.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation(b);\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(SplitOperation, MoveOperation, (a, b, context)=>{\n    const rangeToMove = Range._createFromPositionAndShift(b.sourcePosition, b.howMany);\n    if (a.graveyardPosition) {\n        // Case 1:\n        //\n        // Split operation graveyard node was moved. In this case move operation is stronger. Since graveyard element\n        // is already moved to the correct position, we need to only move the nodes after the split position.\n        // This will be done by `MoveOperation` instead of `SplitOperation`.\n        //\n        const gyElementMoved = rangeToMove.start.isEqual(a.graveyardPosition) || rangeToMove.containsPosition(a.graveyardPosition);\n        if (!context.bWasUndone && gyElementMoved) {\n            const sourcePosition = a.splitPosition._getTransformedByMoveOperation(b);\n            const newParentPosition = a.graveyardPosition._getTransformedByMoveOperation(b);\n            const newTargetPath = newParentPosition.path.slice();\n            newTargetPath.push(0);\n            const newTargetPosition = new Position(newParentPosition.root, newTargetPath);\n            const moveOp = new MoveOperation(sourcePosition, a.howMany, newTargetPosition, 0);\n            return [\n                moveOp\n            ];\n        }\n        a.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation(b);\n    }\n    // Case 2:\n    //\n    // Split is at a position where nodes were moved.\n    //\n    // This is a scenario described in `MoveOperation` x `SplitOperation` transformation but from the\n    // \"split operation point of view\".\n    //\n    const splitAtTarget = a.splitPosition.isEqual(b.targetPosition);\n    if (splitAtTarget && (context.baRelation == 'insertAtSource' || context.abRelation == 'splitBefore')) {\n        a.howMany += b.howMany;\n        a.splitPosition = a.splitPosition._getTransformedByDeletion(b.sourcePosition, b.howMany);\n        a.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n        return [\n            a\n        ];\n    }\n    if (splitAtTarget && context.abRelation && context.abRelation.howMany) {\n        const { howMany, offset } = context.abRelation;\n        a.howMany += howMany;\n        a.splitPosition = a.splitPosition.getShiftedBy(offset);\n        return [\n            a\n        ];\n    }\n    // Case 3:\n    //\n    // If the split position is inside the moved range, we need to shift the split position to a proper place.\n    // The position cannot be moved together with moved range because that would result in splitting of an incorrect element.\n    //\n    // Characters `bc` should be moved to the second paragraph while split position is between them:\n    // <paragraph>A[b|c]d</paragraph><paragraph>Xyz</paragraph>\n    //\n    // After move, new split position is incorrect:\n    // <paragraph>Ad</paragraph><paragraph>Xb|cyz</paragraph>\n    //\n    // Correct split position:\n    // <paragraph>A|d</paragraph><paragraph>Xbcyz</paragraph>\n    //\n    // After split:\n    // <paragraph>A</paragraph><paragraph>d</paragraph><paragraph>Xbcyz</paragraph>\n    //\n    if (a.splitPosition.hasSameParentAs(b.sourcePosition) && rangeToMove.containsPosition(a.splitPosition)) {\n        const howManyRemoved = b.howMany - (a.splitPosition.offset - b.sourcePosition.offset);\n        a.howMany -= howManyRemoved;\n        if (a.splitPosition.hasSameParentAs(b.targetPosition) && a.splitPosition.offset < b.targetPosition.offset) {\n            a.howMany += b.howMany;\n        }\n        a.splitPosition = b.sourcePosition.clone();\n        a.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n        return [\n            a\n        ];\n    }\n    // The default case.\n    // Don't change `howMany` if move operation does not really move anything.\n    //\n    if (!b.sourcePosition.isEqual(b.targetPosition)) {\n        if (a.splitPosition.hasSameParentAs(b.sourcePosition) && a.splitPosition.offset <= b.sourcePosition.offset) {\n            a.howMany -= b.howMany;\n        }\n        if (a.splitPosition.hasSameParentAs(b.targetPosition) && a.splitPosition.offset < b.targetPosition.offset) {\n            a.howMany += b.howMany;\n        }\n    }\n    // Change position stickiness to force a correct transformation.\n    a.splitPosition.stickiness = 'toNone';\n    a.splitPosition = a.splitPosition._getTransformedByMoveOperation(b);\n    a.splitPosition.stickiness = 'toNext';\n    if (a.graveyardPosition) {\n        a.insertionPosition = a.insertionPosition._getTransformedByMoveOperation(b);\n    } else {\n        a.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n    }\n    return [\n        a\n    ];\n});\nsetTransformation(SplitOperation, SplitOperation, (a, b, context)=>{\n    // Case 1:\n    //\n    // Split at the same position.\n    //\n    // If there already was a split at the same position as in `a` operation, it means that the intention\n    // conveyed by `a` operation has already been fulfilled and `a` should not do anything (to avoid double split).\n    //\n    // However, there is a difference if these are new splits or splits created by undo. These have different\n    // intentions. Also splits moving back different elements from graveyard have different intentions. They\n    // are just different operations.\n    //\n    // So we cancel split operation only if it was really identical.\n    //\n    // Also, there is additional case, where split operations aren't identical and should not be cancelled, however the\n    // default transformation is incorrect too.\n    //\n    if (a.splitPosition.isEqual(b.splitPosition)) {\n        if (!a.graveyardPosition && !b.graveyardPosition) {\n            return [\n                new NoOperation(0)\n            ];\n        }\n        if (a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual(b.graveyardPosition)) {\n            return [\n                new NoOperation(0)\n            ];\n        }\n        // Use context to know that the `a.splitPosition` should stay where it is.\n        // This happens during undo when first a merge operation moved nodes to `a.splitPosition` and now `b` operation undoes that merge.\n        if (context.abRelation == 'splitBefore') {\n            // Since split is at the same position, there are no nodes left to split.\n            a.howMany = 0;\n            // Note: there was `if ( a.graveyardPosition )` here but it was uncovered in tests and I couldn't find any scenarios for now.\n            // That would have to be a `SplitOperation` that didn't come from undo but is transformed by operations that were undone.\n            // It could happen if `context` is enabled in collaboration.\n            a.graveyardPosition = a.graveyardPosition._getTransformedBySplitOperation(b);\n            return [\n                a\n            ];\n        }\n    }\n    // Case 2:\n    //\n    // Same node is using to split different elements. This happens in undo when previously same element was merged to\n    // two different elements. This is described in `MergeOperation` x `MergeOperation` transformation.\n    //\n    // In this case we will follow the same logic. We will assume that `insertionPosition` is same for both\n    // split operations. This might not always be true but in the real cases that were experienced it was. After all,\n    // if these splits are reverses of merge operations that were merging the same element, then the `insertionPosition`\n    // should be same for both of those splits.\n    //\n    // Again, we will decide which operation is stronger by checking if split happens in graveyard or in non-graveyard root.\n    //\n    if (a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual(b.graveyardPosition)) {\n        const aInGraveyard = a.splitPosition.root.rootName == '$graveyard';\n        const bInGraveyard = b.splitPosition.root.rootName == '$graveyard';\n        // If `aIsWeak` it means that `a` points to graveyard while `b` doesn't. Don't move nodes then.\n        const aIsWeak = aInGraveyard && !bInGraveyard;\n        // If `bIsWeak` it means that `b` points to graveyard while `a` doesn't. Force moving nodes then.\n        const bIsWeak = bInGraveyard && !aInGraveyard;\n        // Force move if `b` is weak or neither operation is weak but `a` is stronger through `context.aIsStrong`.\n        const forceMove = bIsWeak || !aIsWeak && context.aIsStrong;\n        if (forceMove) {\n            const result = [];\n            // First we need to move any nodes split by `b` back to where they were.\n            // Do it only if `b` actually moved something.\n            if (b.howMany) {\n                result.push(new MoveOperation(b.moveTargetPosition, b.howMany, b.splitPosition, 0));\n            }\n            // Then we need to move nodes from `a` split position to their new element.\n            // Do it only if `a` actually should move something.\n            if (a.howMany) {\n                result.push(new MoveOperation(a.splitPosition, a.howMany, a.moveTargetPosition, 0));\n            }\n            return result;\n        } else {\n            return [\n                new NoOperation(0)\n            ];\n        }\n    }\n    if (a.graveyardPosition) {\n        a.graveyardPosition = a.graveyardPosition._getTransformedBySplitOperation(b);\n    }\n    // Case 3:\n    //\n    // Position where operation `b` inserted a new node after split is the same as the operation `a` split position.\n    // As in similar cases, there is ambiguity if the split should be before the new node (created by `b`) or after.\n    //\n    if (a.splitPosition.isEqual(b.insertionPosition) && context.abRelation == 'splitBefore') {\n        a.howMany++;\n        return [\n            a\n        ];\n    }\n    // Case 4:\n    //\n    // This is a mirror to the case 2. above.\n    //\n    if (b.splitPosition.isEqual(a.insertionPosition) && context.baRelation == 'splitBefore') {\n        const newPositionPath = b.insertionPosition.path.slice();\n        newPositionPath.push(0);\n        const newPosition = new Position(b.insertionPosition.root, newPositionPath);\n        const moveOp = new MoveOperation(a.insertionPosition, 1, newPosition, 0);\n        return [\n            a,\n            moveOp\n        ];\n    }\n    // The default case.\n    //\n    if (a.splitPosition.hasSameParentAs(b.splitPosition) && a.splitPosition.offset < b.splitPosition.offset) {\n        a.howMany -= b.howMany;\n    }\n    a.splitPosition = a.splitPosition._getTransformedBySplitOperation(b);\n    a.insertionPosition = SplitOperation.getInsertionPosition(a.splitPosition);\n    return [\n        a\n    ];\n});\n/**\n * Checks whether `MoveOperation` `targetPosition` is inside a node from the moved range of the other `MoveOperation`.\n */ function _moveTargetIntoMovedRange(a, b) {\n    return a.targetPosition._getTransformedByDeletion(b.sourcePosition, b.howMany) === null;\n}\n/**\n * Helper function for `MoveOperation` x `MoveOperation` transformation. Converts given ranges and target position to\n * move operations and returns them.\n *\n * Ranges and target position will be transformed on-the-fly when generating operations.\n *\n * Given `ranges` should be in the order of how they were in the original transformed operation.\n *\n * Given `targetPosition` is the target position of the first range from `ranges`.\n */ function _makeMoveOperationsFromRanges(ranges, targetPosition) {\n    // At this moment we have some ranges and a target position, to which those ranges should be moved.\n    // Order in `ranges` array is the go-to order of after transformation.\n    //\n    // We are almost done. We have `ranges` and `targetPosition` to make operations from.\n    // Unfortunately, those operations may affect each other. Precisely, first operation after move\n    // may affect source range and target position of second and third operation. Same with second\n    // operation affecting third.\n    //\n    // We need to fix those source ranges and target positions once again, before converting `ranges` to operations.\n    const operations = [];\n    // Keep in mind that nothing will be transformed if there is just one range in `ranges`.\n    for(let i = 0; i < ranges.length; i++){\n        // Create new operation out of a range and target position.\n        const range = ranges[i];\n        const op = new MoveOperation(range.start, range.end.offset - range.start.offset, targetPosition, 0);\n        operations.push(op);\n        // Transform other ranges by the generated operation.\n        for(let j = i + 1; j < ranges.length; j++){\n            // All ranges in `ranges` array should be:\n            //\n            // * non-intersecting (these are part of original operation source range), and\n            // * `targetPosition` does not target into them (opposite would mean that transformed operation targets \"inside itself\").\n            //\n            // This means that the transformation will be \"clean\" and always return one result.\n            ranges[j] = ranges[j]._getTransformedByMove(op.sourcePosition, op.targetPosition, op.howMany)[0];\n        }\n        targetPosition = targetPosition._getTransformedByMove(op.sourcePosition, op.targetPosition, op.howMany);\n    }\n    return operations;\n}\n\n/**\n * `LivePosition` is a type of {@link module:engine/model/position~Position Position}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Contrary to {@link module:engine/model/position~Position}, `LivePosition` works only in roots that are\n * {@link module:engine/model/rootelement~RootElement}.\n * If {@link module:engine/model/documentfragment~DocumentFragment} is passed, error will be thrown.\n *\n * **Note:** Be very careful when dealing with `LivePosition`. Each `LivePosition` instance bind events that might\n * have to be unbound.\n * Use {@link module:engine/model/liveposition~LivePosition#detach} whenever you don't need `LivePosition` anymore.\n */ class LivePosition extends /* #__PURE__ */ EmitterMixin(Position) {\n    /**\n\t * Creates a live position.\n\t *\n\t * @see module:engine/model/position~Position\n\t */ constructor(root, path, stickiness = 'toNone'){\n        super(root, path, stickiness);\n        if (!this.root.is('rootElement')) {\n            /**\n\t\t\t * LivePosition's root has to be an instance of RootElement.\n\t\t\t *\n\t\t\t * @error model-liveposition-root-not-rootelement\n\t\t\t */ throw new CKEditorError('model-liveposition-root-not-rootelement', root);\n        }\n        bindWithDocument.call(this);\n    }\n    /**\n\t * Unbinds all events previously bound by `LivePosition`. Use it whenever you don't need `LivePosition` instance\n\t * anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t * referring to it).\n\t */ detach() {\n        this.stopListening();\n    }\n    /**\n\t * Creates a {@link module:engine/model/position~Position position instance}, which is equal to this live position.\n\t */ toPosition() {\n        return new Position(this.root, this.path.slice(), this.stickiness);\n    }\n    /**\n\t * Creates a `LivePosition` instance that is equal to position.\n\t */ static fromPosition(position, stickiness) {\n        return new this(position.root, position.path.slice(), stickiness ? stickiness : position.stickiness);\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nLivePosition.prototype.is = function(type) {\n    return type === 'livePosition' || type === 'model:livePosition' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n    type == 'position' || type === 'model:position';\n};\n/**\n * Binds this `LivePosition` to the {@link module:engine/model/document~Document document} that owns\n * this position's {@link module:engine/model/position~Position#root root}.\n */ function bindWithDocument() {\n    this.listenTo(this.root.document.model, 'applyOperation', (event, args)=>{\n        const operation = args[0];\n        if (!operation.isDocumentOperation) {\n            return;\n        }\n        transform.call(this, operation);\n    }, {\n        priority: 'low'\n    });\n}\n/**\n * Updates this position accordingly to the updates applied to the model. Bases on change events.\n */ function transform(operation) {\n    const result = this.getTransformedByOperation(operation);\n    if (!this.isEqual(result)) {\n        const oldPosition = this.toPosition();\n        this.path = result.path;\n        this.root = result.root;\n        this.fire('change', oldPosition);\n    }\n}\n\n/**\n * A batch instance groups model changes ({@link module:engine/model/operation/operation~Operation operations}). All operations\n * grouped in a single batch can be reverted together, so you can also think about a batch as of a single undo step. If you want\n * to extend a given undo step, you can add more changes to the batch using {@link module:engine/model/model~Model#enqueueChange}:\n *\n * ```ts\n * model.enqueueChange( batch, writer => {\n * \twriter.insertText( 'foo', paragraph, 'end' );\n * } );\n * ```\n *\n * @see module:engine/model/model~Model#enqueueChange\n * @see module:engine/model/model~Model#change\n */ class Batch {\n    /**\n\t * An array of operations that compose this batch.\n\t */ operations;\n    /**\n\t * Whether the batch can be undone through the undo feature.\n\t */ isUndoable;\n    /**\n\t * Whether the batch includes operations created locally (`true`) or operations created on other, remote editors (`false`).\n\t */ isLocal;\n    /**\n\t * Whether the batch was created by the undo feature and undoes other operations.\n\t */ isUndo;\n    /**\n\t * Whether the batch includes operations connected with typing.\n\t */ isTyping;\n    /**\n\t * Creates a batch instance.\n\t *\n\t * @see module:engine/model/model~Model#enqueueChange\n\t * @see module:engine/model/model~Model#change\n\t * @param type A set of flags that specify the type of the batch. Batch type can alter how some of the features work\n\t * when encountering a given `Batch` instance (for example, when a feature listens to applied operations).\n\t */ constructor(type = {}){\n        if (typeof type === 'string') {\n            type = type === 'transparent' ? {\n                isUndoable: false\n            } : {};\n            /**\n\t\t\t * The string value for a `type` property of the `Batch` constructor has been deprecated and will be removed in the near future.\n\t\t\t * Please refer to the {@link module:engine/model/batch~Batch#constructor `Batch` constructor API documentation} for more\n\t\t\t * information.\n\t\t\t *\n\t\t\t * @error batch-constructor-deprecated-string-type\n\t\t\t */ logWarning('batch-constructor-deprecated-string-type');\n        }\n        const { isUndoable = true, isLocal = true, isUndo = false, isTyping = false } = type;\n        this.operations = [];\n        this.isUndoable = isUndoable;\n        this.isLocal = isLocal;\n        this.isUndo = isUndo;\n        this.isTyping = isTyping;\n    }\n    /**\n\t * The type of the batch.\n\t *\n\t * **This property has been deprecated and is always set to the `'default'` value.**\n\t *\n\t * It can be one of the following values:\n\t * * `'default'` &ndash; All \"normal\" batches. This is the most commonly used type.\n\t * * `'transparent'` &ndash; A batch that should be ignored by other features, i.e. an initial batch or collaborative editing\n\t * changes.\n\t *\n\t * @deprecated\n\t */ get type() {\n        /**\n\t\t * The {@link module:engine/model/batch~Batch#type `Batch#type` } property has been deprecated and will be removed in the near\n\t\t * future. Use `Batch#isLocal`, `Batch#isUndoable`, `Batch#isUndo` and `Batch#isTyping` instead.\n\t\t *\n\t\t * @error batch-type-deprecated\n\t\t */ logWarning('batch-type-deprecated');\n        return 'default';\n    }\n    /**\n\t * Returns the base version of this batch, which is equal to the base version of the first operation in the batch.\n\t * If there are no operations in the batch or neither operation has the base version set, it returns `null`.\n\t */ get baseVersion() {\n        for (const op of this.operations){\n            if (op.baseVersion !== null) {\n                return op.baseVersion;\n            }\n        }\n        return null;\n    }\n    /**\n\t * Adds an operation to the batch instance.\n\t *\n\t * @param operation An operation to add.\n\t * @returns The added operation.\n\t */ addOperation(operation) {\n        operation.batch = this;\n        this.operations.push(operation);\n        return operation;\n    }\n}\n\n/**\n * Calculates the difference between two model states.\n *\n * Receives operations that are to be applied on the model document. Marks parts of the model document tree which\n * are changed and saves the state of these elements before the change. Then, it compares saved elements with the\n * changed elements, after all changes are applied on the model document. Calculates the diff between saved\n * elements and new ones and returns a change set.\n */ class Differ {\n    /**\n\t * Priority of the {@link ~Differ#_elementState element states}. States on higher indexes of the array can overwrite states on the lower\n\t * indexes.\n\t */ static _statesPriority = [\n        undefined,\n        'refresh',\n        'rename',\n        'move'\n    ];\n    /**\n\t * Reference to the model's marker collection.\n\t */ _markerCollection;\n    /**\n\t * A map that stores changes that happened in a given element.\n\t *\n\t * The keys of the map are references to the model elements.\n\t * The values of the map are arrays with changes that were done on this element.\n\t */ _changesInElement = new Map();\n    /**\n\t * Stores a snapshot for these model nodes that might have changed.\n\t *\n\t * This complements {@link ~Differ#_elementChildrenSnapshots `_elementChildrenSnapshots`}.\n\t *\n\t * See also {@link ~DifferSnapshot}.\n\t */ _elementsSnapshots = new Map();\n    /**\n\t * For each element or document fragment inside which there was a change, it stores a snapshot of the child nodes list (an array\n\t * of children snapshots that represent the state in the element / fragment before any change has happened).\n\t *\n\t * This complements {@link ~Differ#_elementsSnapshots `_elementsSnapshots`}.\n\t *\n\t * See also {@link ~DifferSnapshot}.\n\t */ _elementChildrenSnapshots = new Map();\n    /**\n\t * Keeps the state for a given element, describing how the element was changed so far. It is used to evaluate the `action` property\n\t * of diff items returned by {@link ~Differ#getChanges}.\n\t *\n\t * Possible values, in the order from the lowest priority to the highest priority:\n\t *\n\t * * `'refresh'` - element was refreshed,\n\t * * `'rename'` - element was renamed,\n\t * * `'move'` - element was moved (or, usually, removed, that is moved to the graveyard).\n\t *\n\t * Element that was refreshed, may change its state to `'rename'` if it was later renamed, or to `'move'` if it was removed.\n\t * But the element cannot change its state from `'move'` to `'rename'`, or from `'rename'` to `'refresh'`.\n\t *\n\t * Only already existing elements are registered in `_elementState`. If a new element was inserted as a result of a buffered operation,\n\t * it is not be registered in `_elementState`.\n\t */ _elementState = new Map();\n    /**\n\t * A map that stores all changed markers.\n\t *\n\t * The keys of the map are marker names.\n\t *\n\t * The values of the map are objects with the following properties:\n\t *\n\t * * `oldMarkerData`,\n\t * * `newMarkerData`.\n\t */ _changedMarkers = new Map();\n    /**\n\t * A map that stores all roots that have been changed.\n\t *\n\t * The keys are the names of the roots while value represents the changes.\n\t */ _changedRoots = new Map();\n    /**\n\t * Stores the number of changes that were processed. Used to order the changes chronologically. It is important\n\t * when changes are sorted.\n\t */ _changeCount = 0;\n    /**\n\t * For efficiency purposes, `Differ` stores the change set returned by the differ after {@link #getChanges} call.\n\t * Cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t * return the cached value instead of calculating it again.\n\t *\n\t * This property stores those changes that did not take place in graveyard root.\n\t */ _cachedChanges = null;\n    /**\n\t * For efficiency purposes, `Differ` stores the change set returned by the differ after the {@link #getChanges} call.\n\t * The cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t * return the cached value instead of calculating it again.\n\t *\n\t * This property stores all changes evaluated by `Differ`, including those that took place in the graveyard.\n\t */ _cachedChangesWithGraveyard = null;\n    /**\n\t * Set of model items that were marked to get refreshed in {@link #_refreshItem}.\n\t */ _refreshedItems = new Set();\n    /**\n\t * Creates a `Differ` instance.\n\t *\n\t * @param markerCollection Model's marker collection.\n\t */ constructor(markerCollection){\n        this._markerCollection = markerCollection;\n    }\n    /**\n\t * Informs whether there are any changes buffered in `Differ`.\n\t */ get isEmpty() {\n        return this._changesInElement.size == 0 && this._changedMarkers.size == 0 && this._changedRoots.size == 0;\n    }\n    /**\n\t * Buffers the given operation. **An operation has to be buffered before it is executed.**\n\t *\n\t * @param operationToBuffer An operation to buffer.\n\t */ bufferOperation(operationToBuffer) {\n        // Below we take an operation, check its type, then use its parameters in marking (private) methods.\n        // The general rule is to not mark elements inside inserted element. All inserted elements are re-rendered.\n        // Marking changes in them would cause a \"double\" changing then.\n        //\n        const operation = operationToBuffer;\n        // Note: an operation that happens inside a non-loaded root will be ignored. If the operation happens partially inside\n        // a non-loaded root, that part will be ignored (this may happen for move or marker operations).\n        //\n        switch(operation.type){\n            case 'insert':\n                {\n                    if (this._isInInsertedElement(operation.position.parent)) {\n                        return;\n                    }\n                    this._markInsert(operation.position.parent, operation.position.offset, operation.nodes.maxOffset);\n                    break;\n                }\n            case 'addAttribute':\n            case 'removeAttribute':\n            case 'changeAttribute':\n                {\n                    for (const item of operation.range.getItems({\n                        shallow: true\n                    })){\n                        if (this._isInInsertedElement(item.parent)) {\n                            continue;\n                        }\n                        this._markAttribute(item);\n                    }\n                    break;\n                }\n            case 'remove':\n            case 'move':\n            case 'reinsert':\n                {\n                    // When range is moved to the same position then not mark it as a change.\n                    // See: https://github.com/ckeditor/ckeditor5-engine/issues/1664.\n                    if (operation.sourcePosition.isEqual(operation.targetPosition) || operation.sourcePosition.getShiftedBy(operation.howMany).isEqual(operation.targetPosition)) {\n                        return;\n                    }\n                    const sourceParentInserted = this._isInInsertedElement(operation.sourcePosition.parent);\n                    const targetParentInserted = this._isInInsertedElement(operation.targetPosition.parent);\n                    if (!sourceParentInserted) {\n                        this._markRemove(operation.sourcePosition.parent, operation.sourcePosition.offset, operation.howMany);\n                    }\n                    if (!targetParentInserted) {\n                        this._markInsert(operation.targetPosition.parent, operation.getMovedRangeStart().offset, operation.howMany);\n                    }\n                    // Remember -- operation is buffered before it is executed. So, it was not executed yet.\n                    const range = Range._createFromPositionAndShift(operation.sourcePosition, operation.howMany);\n                    for (const node of range.getItems({\n                        shallow: true\n                    })){\n                        this._setElementState(node, 'move');\n                    }\n                    break;\n                }\n            case 'rename':\n                {\n                    if (this._isInInsertedElement(operation.position.parent)) {\n                        return;\n                    }\n                    this._markRemove(operation.position.parent, operation.position.offset, 1);\n                    this._markInsert(operation.position.parent, operation.position.offset, 1);\n                    const range = Range._createFromPositionAndShift(operation.position, 1);\n                    for (const marker of this._markerCollection.getMarkersIntersectingRange(range)){\n                        const markerData = marker.getData();\n                        this.bufferMarkerChange(marker.name, markerData, markerData);\n                    }\n                    this._setElementState(operation.position.nodeAfter, 'rename');\n                    break;\n                }\n            case 'split':\n                {\n                    const splitElement = operation.splitPosition.parent;\n                    // Mark that children of the split element were removed.\n                    if (!this._isInInsertedElement(splitElement)) {\n                        this._markRemove(splitElement, operation.splitPosition.offset, operation.howMany);\n                        // Remember -- operation is buffered before it is executed. So, it was not executed yet.\n                        const range = Range._createFromPositionAndShift(operation.splitPosition, operation.howMany);\n                        for (const node of range.getItems({\n                            shallow: true\n                        })){\n                            this._setElementState(node, 'move');\n                        }\n                    }\n                    // Mark that the new element (split copy) was inserted.\n                    if (!this._isInInsertedElement(operation.insertionPosition.parent)) {\n                        this._markInsert(operation.insertionPosition.parent, operation.insertionPosition.offset, 1);\n                    }\n                    // If the split took the element from the graveyard, mark that the element from the graveyard was removed.\n                    if (operation.graveyardPosition) {\n                        this._markRemove(operation.graveyardPosition.parent, operation.graveyardPosition.offset, 1);\n                        this._setElementState(operation.graveyardPosition.nodeAfter, 'move');\n                    }\n                    break;\n                }\n            case 'merge':\n                {\n                    // Mark that the merged element was removed.\n                    const mergedElement = operation.sourcePosition.parent;\n                    if (!this._isInInsertedElement(mergedElement.parent)) {\n                        this._markRemove(mergedElement.parent, mergedElement.startOffset, 1);\n                    }\n                    // Mark that the merged element was inserted into graveyard.\n                    const graveyardParent = operation.graveyardPosition.parent;\n                    this._markInsert(graveyardParent, operation.graveyardPosition.offset, 1);\n                    this._setElementState(mergedElement, 'move');\n                    // Mark that children of merged element were inserted at new parent.\n                    const mergedIntoElement = operation.targetPosition.parent;\n                    if (!this._isInInsertedElement(mergedIntoElement)) {\n                        this._markInsert(mergedIntoElement, operation.targetPosition.offset, mergedElement.maxOffset);\n                        // Remember -- operation is buffered before it is executed. So, it was not executed yet.\n                        const range = Range._createFromPositionAndShift(operation.sourcePosition, operation.howMany);\n                        for (const node of range.getItems({\n                            shallow: true\n                        })){\n                            this._setElementState(node, 'move');\n                        }\n                    }\n                    break;\n                }\n            case 'detachRoot':\n            case 'addRoot':\n                {\n                    const root = operation.affectedSelectable;\n                    if (!root._isLoaded) {\n                        return;\n                    }\n                    // Don't buffer if the root state does not change.\n                    if (root.isAttached() == operation.isAdd) {\n                        return;\n                    }\n                    this._bufferRootStateChange(operation.rootName, operation.isAdd);\n                    break;\n                }\n            case 'addRootAttribute':\n            case 'removeRootAttribute':\n            case 'changeRootAttribute':\n                {\n                    if (!operation.root._isLoaded) {\n                        return;\n                    }\n                    const rootName = operation.root.rootName;\n                    this._bufferRootAttributeChange(rootName, operation.key, operation.oldValue, operation.newValue);\n                    break;\n                }\n        }\n        // Clear cache after each buffered operation as it is no longer valid.\n        this._cachedChanges = null;\n    }\n    /**\n\t * Buffers a marker change.\n\t *\n\t * @param markerName The name of the marker that changed.\n\t * @param oldMarkerData Marker data before the change.\n\t * @param newMarkerData Marker data after the change.\n\t */ bufferMarkerChange(markerName, oldMarkerData, newMarkerData) {\n        if (oldMarkerData.range && oldMarkerData.range.root.is('rootElement') && !oldMarkerData.range.root._isLoaded) {\n            oldMarkerData.range = null;\n        }\n        if (newMarkerData.range && newMarkerData.range.root.is('rootElement') && !newMarkerData.range.root._isLoaded) {\n            newMarkerData.range = null;\n        }\n        let buffered = this._changedMarkers.get(markerName);\n        if (!buffered) {\n            buffered = {\n                newMarkerData,\n                oldMarkerData\n            };\n            this._changedMarkers.set(markerName, buffered);\n        } else {\n            buffered.newMarkerData = newMarkerData;\n        }\n        if (buffered.oldMarkerData.range == null && newMarkerData.range == null) {\n            // The marker is going to be removed (`newMarkerData.range == null`) but it did not exist before the first buffered change\n            // (`buffered.oldMarkerData.range == null`). In this case, do not keep the marker in buffer at all.\n            this._changedMarkers.delete(markerName);\n        }\n    }\n    /**\n\t * Returns all markers that should be removed as a result of buffered changes.\n\t *\n\t * @returns Markers to remove. Each array item is an object containing the `name` and `range` properties.\n\t */ getMarkersToRemove() {\n        const result = [];\n        for (const [name, change] of this._changedMarkers){\n            if (change.oldMarkerData.range != null) {\n                result.push({\n                    name,\n                    range: change.oldMarkerData.range\n                });\n            }\n        }\n        return result;\n    }\n    /**\n\t * Returns all markers which should be added as a result of buffered changes.\n\t *\n\t * @returns Markers to add. Each array item is an object containing the `name` and `range` properties.\n\t */ getMarkersToAdd() {\n        const result = [];\n        for (const [name, change] of this._changedMarkers){\n            if (change.newMarkerData.range != null) {\n                result.push({\n                    name,\n                    range: change.newMarkerData.range\n                });\n            }\n        }\n        return result;\n    }\n    /**\n\t * Returns all markers which changed.\n\t */ getChangedMarkers() {\n        return Array.from(this._changedMarkers).map(([name, change])=>({\n                name,\n                data: {\n                    oldRange: change.oldMarkerData.range,\n                    newRange: change.newMarkerData.range\n                }\n            }));\n    }\n    /**\n\t * Checks whether some of the buffered changes affect the editor data.\n\t *\n\t * Types of changes which affect the editor data:\n\t *\n\t * * model structure changes,\n\t * * attribute changes,\n\t * * a root is added or detached,\n\t * * changes of markers which were defined as `affectsData`,\n\t * * changes of markers' `affectsData` property.\n\t */ hasDataChanges() {\n        if (this.getChanges().length) {\n            return true;\n        }\n        if (this._changedRoots.size > 0) {\n            return true;\n        }\n        for (const { newMarkerData, oldMarkerData } of this._changedMarkers.values()){\n            if (newMarkerData.affectsData !== oldMarkerData.affectsData) {\n                return true;\n            }\n            if (newMarkerData.affectsData) {\n                const markerAdded = newMarkerData.range && !oldMarkerData.range;\n                const markerRemoved = !newMarkerData.range && oldMarkerData.range;\n                const markerChanged = newMarkerData.range && oldMarkerData.range && !newMarkerData.range.isEqual(oldMarkerData.range);\n                if (markerAdded || markerRemoved || markerChanged) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    /**\n\t * Calculates the diff between the old model tree state (the state before the first buffered operations since the last {@link #reset}\n\t * call) and the new model tree state (actual one). It should be called after all buffered operations are executed.\n\t *\n\t * The diff set is returned as an array of {@link module:engine/model/differ~DiffItem diff items}, each describing a change done\n\t * on the model. The items are sorted by the position on which the change happened. If a position\n\t * {@link module:engine/model/position~Position#isBefore is before} another one, it will be on an earlier index in the diff set.\n\t *\n\t * **Note**: Elements inside inserted element will not have a separate diff item, only the top most element change will be reported.\n\t *\n\t * Because calculating the diff is a costly operation, the result is cached. If no new operation was buffered since the\n\t * previous {@link #getChanges} call, the next call will return the cached value.\n\t *\n\t * @param options Additional options.\n\t * @param options.includeChangesInGraveyard If set to `true`, also changes that happened\n\t * in the graveyard root will be returned. By default, changes in the graveyard root are not returned.\n\t * @returns Diff between the old and the new model tree state.\n\t */ getChanges(options = {}) {\n        // If there are cached changes, just return them instead of calculating changes again.\n        if (this._cachedChanges) {\n            if (options.includeChangesInGraveyard) {\n                return this._cachedChangesWithGraveyard.slice();\n            } else {\n                return this._cachedChanges.slice();\n            }\n        }\n        // Will contain returned results.\n        let diffSet = [];\n        // Check all changed elements/roots.\n        for (const element of this._changesInElement.keys()){\n            // Get changes inside this element/root and sort them.\n            const changes = this._changesInElement.get(element).sort((a, b)=>{\n                if (a.offset === b.offset) {\n                    if (a.type != b.type) {\n                        // If there are multiple changes at the same position, \"remove\" change should be first.\n                        // If the order is different, for example, we would first add some nodes and then removed them\n                        // (instead of the nodes that we should remove).\n                        return a.type == 'remove' ? -1 : 1;\n                    }\n                    return 0;\n                }\n                return a.offset < b.offset ? -1 : 1;\n            });\n            // Get children of this element before any change was applied on it.\n            const childrenBefore = this._elementChildrenSnapshots.get(element);\n            // Get snapshot of current element's children.\n            const childrenAfter = _getChildrenSnapshots(element.getChildren());\n            // Generate diff instructions based on changes done in the element/root.\n            const diffInstructions = _generateDiffInstructionsFromChanges(childrenBefore.length, changes);\n            let i = 0; // Iterator in `childrenAfter` array -- iterates through current children of element.\n            let j = 0; // Iterator in `childrenBefore` array -- iterates through old children of element.\n            // Process every action.\n            for (const instruction of diffInstructions){\n                if (instruction === 'i') {\n                    const action = this._getDiffActionForNode(childrenAfter[i].node, 'insert');\n                    const childSnapshotBefore = this._elementsSnapshots.get(childrenAfter[i].node);\n                    const diffItem = this._getInsertDiff(element, i, action, childrenAfter[i], childSnapshotBefore);\n                    diffSet.push(diffItem);\n                    i++;\n                } else if (instruction === 'r') {\n                    const action = this._getDiffActionForNode(childrenBefore[j].node, 'remove');\n                    const diffItem = this._getRemoveDiff(element, i, action, childrenBefore[j]);\n                    diffSet.push(diffItem);\n                    j++;\n                } else if (instruction === 'a') {\n                    // Take attributes from saved and current children.\n                    const beforeAttributes = childrenBefore[j].attributes;\n                    const afterAttributes = childrenAfter[i].attributes;\n                    let range;\n                    if (childrenAfter[i].name == '$text') {\n                        range = new Range(Position._createAt(element, i), Position._createAt(element, i + 1));\n                    } else {\n                        const index = element.offsetToIndex(i);\n                        range = new Range(Position._createAt(element, i), Position._createAt(element.getChild(index), 0));\n                    }\n                    // Generate diff items for this change (there might be multiple attributes changed and\n                    // there is a single diff for each of them) and insert them into the diff set.\n                    const diffItems = this._getAttributesDiff(range, beforeAttributes, afterAttributes);\n                    diffSet.push(...diffItems);\n                    i++;\n                    j++;\n                } else {\n                    // `action` is 'equal'. Child not changed.\n                    i++;\n                    j++;\n                }\n            }\n        }\n        // Then, sort the changes by the position (change at position before other changes is first).\n        diffSet.sort((a, b)=>{\n            // If the change is in different root, we don't care much, but we'd like to have all changes in given\n            // root \"together\" in the array. So let's just sort them by the root name. It does not matter which root\n            // will be processed first.\n            if (a.position.root != b.position.root) {\n                return a.position.root.rootName < b.position.root.rootName ? -1 : 1;\n            }\n            // If change happens at the same position...\n            if (a.position.isEqual(b.position)) {\n                // Keep chronological order of operations.\n                return a.changeCount - b.changeCount;\n            }\n            // If positions differ, position \"on the left\" should be earlier in the result.\n            return a.position.isBefore(b.position) ? -1 : 1;\n        });\n        // Glue together multiple changes (mostly on text nodes).\n        for(let i = 1, prevIndex = 0; i < diffSet.length; i++){\n            const prevDiff = diffSet[prevIndex];\n            const thisDiff = diffSet[i];\n            // Glue remove changes if they happen on text on same position.\n            const isConsecutiveTextRemove = prevDiff.type == 'remove' && thisDiff.type == 'remove' && prevDiff.name == '$text' && thisDiff.name == '$text' && prevDiff.position.isEqual(thisDiff.position);\n            // Glue insert changes if they happen on text on consecutive fragments.\n            const isConsecutiveTextAdd = prevDiff.type == 'insert' && thisDiff.type == 'insert' && prevDiff.name == '$text' && thisDiff.name == '$text' && prevDiff.position.parent == thisDiff.position.parent && prevDiff.position.offset + prevDiff.length == thisDiff.position.offset;\n            // Glue attribute changes if they happen on consecutive fragments and have same key, old value and new value.\n            const isConsecutiveAttributeChange = prevDiff.type == 'attribute' && thisDiff.type == 'attribute' && prevDiff.position.parent == thisDiff.position.parent && prevDiff.range.isFlat && thisDiff.range.isFlat && prevDiff.position.offset + prevDiff.length == thisDiff.position.offset && prevDiff.attributeKey == thisDiff.attributeKey && prevDiff.attributeOldValue == thisDiff.attributeOldValue && prevDiff.attributeNewValue == thisDiff.attributeNewValue;\n            if (isConsecutiveTextRemove || isConsecutiveTextAdd || isConsecutiveAttributeChange) {\n                prevDiff.length++;\n                if (isConsecutiveAttributeChange) {\n                    prevDiff.range.end = prevDiff.range.end.getShiftedBy(1);\n                }\n                diffSet[i] = null;\n            } else {\n                prevIndex = i;\n            }\n        }\n        diffSet = diffSet.filter((v)=>v);\n        // Remove `changeCount` property from diff items. It is used only for sorting and is internal thing.\n        for (const item of diffSet){\n            delete item.changeCount;\n            if (item.type == 'attribute') {\n                delete item.position;\n                delete item.length;\n            }\n        }\n        this._changeCount = 0;\n        // Cache changes.\n        this._cachedChangesWithGraveyard = diffSet;\n        this._cachedChanges = diffSet.filter(_changesInGraveyardFilter);\n        if (options.includeChangesInGraveyard) {\n            return this._cachedChangesWithGraveyard.slice();\n        } else {\n            return this._cachedChanges.slice();\n        }\n    }\n    /**\n\t * Returns all roots that have changed (either were attached, or detached, or their attributes changed).\n\t *\n\t * @returns Diff between the old and the new roots state.\n\t */ getChangedRoots() {\n        return Array.from(this._changedRoots.values()).map((diffItem)=>{\n            const entry = {\n                ...diffItem\n            };\n            if (entry.state !== undefined) {\n                // The root was attached or detached -- do not return its attributes changes.\n                // If the root was attached, it should be handled as a whole, together with its attributes, the same way as model nodes.\n                // If the root was detached, its attributes should be discarded anyway.\n                //\n                // Keep in mind that filtering must happen on this stage (when retrieving changes). If filtering happens on-the-fly as\n                // the attributes change, it may lead to incorrect situation, e.g.: detach root, change attribute, re-attach root.\n                // In this case, attribute change cannot be filtered. After the root is re-attached, the attribute change must be kept.\n                delete entry.attributes;\n            }\n            return entry;\n        });\n    }\n    /**\n\t * Returns a set of model items that were marked to get refreshed.\n\t */ getRefreshedItems() {\n        return new Set(this._refreshedItems);\n    }\n    /**\n\t * Resets `Differ`. Removes all buffered changes.\n\t */ reset() {\n        this._changesInElement.clear();\n        this._elementChildrenSnapshots.clear();\n        this._elementsSnapshots.clear();\n        this._elementState.clear();\n        this._changedMarkers.clear();\n        this._changedRoots.clear();\n        this._refreshedItems.clear();\n        this._cachedChanges = null;\n    }\n    /**\n\t * Marks the given `item` in differ to be \"refreshed\". It means that the item will be marked as removed and inserted\n\t * in the differ changes set, so it will be effectively re-converted when the differ changes are handled by a dispatcher.\n\t *\n\t * @internal\n\t * @param item Item to refresh.\n\t */ _refreshItem(item) {\n        if (this._isInInsertedElement(item.parent)) {\n            return;\n        }\n        this._markRemove(item.parent, item.startOffset, item.offsetSize);\n        this._markInsert(item.parent, item.startOffset, item.offsetSize);\n        this._refreshedItems.add(item);\n        this._setElementState(item, 'refresh');\n        const range = Range._createOn(item);\n        for (const marker of this._markerCollection.getMarkersIntersectingRange(range)){\n            const markerData = marker.getData();\n            this.bufferMarkerChange(marker.name, markerData, markerData);\n        }\n        // Clear cache after each buffered operation as it is no longer valid.\n        this._cachedChanges = null;\n    }\n    /**\n\t * Buffers all the data related to given root like it was all just added to the editor.\n\t *\n\t * Following changes are buffered:\n\t *\n\t * * root is attached,\n\t * * all root content is inserted,\n\t * * all root attributes are added,\n\t * * all markers inside the root are added.\n\t *\n\t * @internal\n\t */ _bufferRootLoad(root) {\n        if (!root.isAttached()) {\n            return;\n        }\n        this._bufferRootStateChange(root.rootName, true);\n        this._markInsert(root, 0, root.maxOffset);\n        // Buffering root attribute changes makes sense and is actually needed, even though we buffer root state change above.\n        // Because the root state change is buffered, the root attributes changes are not returned by the differ.\n        // But, if the root attribute is removed in the same change block, or the root is detached, then the differ results would be wrong.\n        //\n        for (const key of root.getAttributeKeys()){\n            this._bufferRootAttributeChange(root.rootName, key, null, root.getAttribute(key));\n        }\n        for (const marker of this._markerCollection){\n            if (marker.getRange().root == root) {\n                const markerData = marker.getData();\n                this.bufferMarkerChange(marker.name, {\n                    ...markerData,\n                    range: null\n                }, markerData);\n            }\n        }\n    }\n    /**\n\t * Buffers the root state change after the root was attached or detached\n\t */ _bufferRootStateChange(rootName, isAttached) {\n        if (!this._changedRoots.has(rootName)) {\n            this._changedRoots.set(rootName, {\n                name: rootName,\n                state: isAttached ? 'attached' : 'detached'\n            });\n            return;\n        }\n        const diffItem = this._changedRoots.get(rootName);\n        if (diffItem.state !== undefined) {\n            // Root `state` can only toggle between one of the values and no value. It cannot be any other way,\n            // because if the root was originally attached it can only become detached. Then, if it is re-attached in the same batch of\n            // changes, it gets back to \"no change\" (which means no value). Same if the root was originally detached.\n            delete diffItem.state;\n            if (diffItem.attributes === undefined) {\n                // If there is no `state` change and no `attributes` change, remove the entry.\n                this._changedRoots.delete(rootName);\n            }\n        } else {\n            diffItem.state = isAttached ? 'attached' : 'detached';\n        }\n    }\n    /**\n\t * Buffers a root attribute change.\n\t */ _bufferRootAttributeChange(rootName, key, oldValue, newValue) {\n        const diffItem = this._changedRoots.get(rootName) || {\n            name: rootName\n        };\n        const attrs = diffItem.attributes || {};\n        if (attrs[key]) {\n            // If this attribute or metadata was already changed earlier and is changed again, check to what value it is changed.\n            const attrEntry = attrs[key];\n            if (newValue === attrEntry.oldValue) {\n                // If it was changed back to the old value, remove the entry.\n                delete attrs[key];\n            } else {\n                // If it was changed to a different value, update the entry.\n                attrEntry.newValue = newValue;\n            }\n        } else {\n            // If this attribute or metadata was not set earlier, add an entry.\n            attrs[key] = {\n                oldValue,\n                newValue\n            };\n        }\n        if (Object.entries(attrs).length === 0) {\n            // If attributes or metadata changes set became empty, remove it from the diff item.\n            delete diffItem.attributes;\n            if (diffItem.state === undefined) {\n                // If there is no `state` change and no `attributes` change, remove the entry.\n                this._changedRoots.delete(rootName);\n            }\n        } else {\n            // Make sure that, if a new object in the structure was created, it gets set.\n            diffItem.attributes = attrs;\n            this._changedRoots.set(rootName, diffItem);\n        }\n    }\n    /**\n\t * Saves and handles an insert change.\n\t */ _markInsert(parent, offset, howMany) {\n        if (parent.root.is('rootElement') && !parent.root._isLoaded) {\n            return;\n        }\n        const changeItem = {\n            type: 'insert',\n            offset,\n            howMany,\n            count: this._changeCount++\n        };\n        this._markChange(parent, changeItem);\n    }\n    /**\n\t * Saves and handles a remove change.\n\t */ _markRemove(parent, offset, howMany) {\n        if (parent.root.is('rootElement') && !parent.root._isLoaded) {\n            return;\n        }\n        const changeItem = {\n            type: 'remove',\n            offset,\n            howMany,\n            count: this._changeCount++\n        };\n        this._markChange(parent, changeItem);\n        this._removeAllNestedChanges(parent, offset, howMany);\n    }\n    /**\n\t * Saves and handles an attribute change.\n\t */ _markAttribute(item) {\n        if (item.root.is('rootElement') && !item.root._isLoaded) {\n            return;\n        }\n        const changeItem = {\n            type: 'attribute',\n            offset: item.startOffset,\n            howMany: item.offsetSize,\n            count: this._changeCount++\n        };\n        this._markChange(item.parent, changeItem);\n    }\n    /**\n\t * Saves and handles a model change.\n\t */ _markChange(parent, changeItem) {\n        // First, make a snapshot of the parent and its children (it will be made only if it was not made before).\n        this._makeSnapshots(parent);\n        // Then, get all changes that already were done on the element (empty array if this is the first change).\n        const changes = this._getChangesForElement(parent);\n        // Then, look through all the changes, and transform them or the new change.\n        this._handleChange(changeItem, changes);\n        // Add the new change.\n        changes.push(changeItem);\n        // Remove incorrect changes. During transformation some change might be, for example, included in another.\n        // In that case, the change will have `howMany` property set to `0` or less. We need to remove those changes.\n        for(let i = 0; i < changes.length; i++){\n            if (changes[i].howMany < 1) {\n                changes.splice(i, 1);\n                i--;\n            }\n        }\n    }\n    /**\n\t * Tries to set given state for given item.\n\t *\n\t * This method does simple validation (it sets the state only for model elements, not for text proxy nodes). It also follows state\n\t * setting rules, that is, `'refresh'` cannot overwrite `'rename'`, and `'rename'` cannot overwrite `'move'`.\n\t */ _setElementState(node, state) {\n        if (!node.is('element')) {\n            return;\n        }\n        const currentStatePriority = Differ._statesPriority.indexOf(this._elementState.get(node));\n        const newStatePriority = Differ._statesPriority.indexOf(state);\n        if (newStatePriority > currentStatePriority) {\n            this._elementState.set(node, state);\n        }\n    }\n    /**\n\t * Returns a value for {@link ~DifferItemAction `action`} property for diff items returned by {@link ~Differ#getChanges}.\n\t * This method aims to return `'rename'` or `'refresh'` when it should, and `diffItemType` (\"default action\") in all other cases.\n\t *\n\t * It bases on a few factors:\n\t *\n\t * * for text nodes, the method always returns `diffItemType`,\n\t * * for newly inserted element, the method returns `diffItemType`,\n\t * * if {@link ~Differ#_elementState element state} was not recorded, the method returns `diffItemType`,\n\t * * if state was recorded, and it was `'move'` (default action), the method returns `diffItemType`,\n\t * * finally, if state was `'refresh'` or `'rename'`, the method returns the state value.\n\t */ _getDiffActionForNode(node, diffItemType) {\n        if (!node.is('element')) {\n            // Text node.\n            return diffItemType;\n        }\n        if (!this._elementsSnapshots.has(node)) {\n            // Newly inserted element.\n            return diffItemType;\n        }\n        const state = this._elementState.get(node);\n        if (!state || state == 'move') {\n            return diffItemType;\n        }\n        return state;\n    }\n    /**\n\t * Gets an array of changes that have already been saved for a given element.\n\t */ _getChangesForElement(element) {\n        let changes;\n        if (this._changesInElement.has(element)) {\n            changes = this._changesInElement.get(element);\n        } else {\n            changes = [];\n            this._changesInElement.set(element, changes);\n        }\n        return changes;\n    }\n    /**\n\t * Creates and saves a snapshot for all children of the given element.\n\t */ _makeSnapshots(element) {\n        if (this._elementChildrenSnapshots.has(element)) {\n            return;\n        }\n        const childrenSnapshots = _getChildrenSnapshots(element.getChildren());\n        this._elementChildrenSnapshots.set(element, childrenSnapshots);\n        for (const snapshot of childrenSnapshots){\n            this._elementsSnapshots.set(snapshot.node, snapshot);\n        }\n    }\n    /**\n\t * For a given newly saved change, compares it with a change already done on the element and modifies the incoming\n\t * change and/or the old change.\n\t *\n\t * @param inc Incoming (new) change.\n\t * @param changes An array containing all the changes done on that element.\n\t */ _handleChange(inc, changes) {\n        // We need a helper variable that will store how many nodes are to be still handled for this change item.\n        // `nodesToHandle` (how many nodes still need to be handled) and `howMany` (how many nodes were affected)\n        // needs to be differentiated.\n        //\n        // This comes up when there are multiple changes that are affected by `inc` change item.\n        //\n        // For example: assume two insert changes: `{ offset: 2, howMany: 1 }` and `{ offset: 5, howMany: 1 }`.\n        // Assume that `inc` change is remove `{ offset: 2, howMany: 2, nodesToHandle: 2 }`.\n        //\n        // Then, we:\n        // - \"forget\" about first insert change (it is \"eaten\" by remove),\n        // - because of that, at the end we will want to remove only one node (`nodesToHandle = 1`),\n        // - but still we have to change offset of the second insert change from `5` to `3`!\n        //\n        // So, `howMany` does not change throughout items transformation and keeps information about how many nodes were affected,\n        // while `nodesToHandle` means how many nodes need to be handled after the change item is transformed by other changes.\n        inc.nodesToHandle = inc.howMany;\n        for (const old of changes){\n            const incEnd = inc.offset + inc.howMany;\n            const oldEnd = old.offset + old.howMany;\n            if (inc.type == 'insert') {\n                if (old.type == 'insert') {\n                    if (inc.offset <= old.offset) {\n                        old.offset += inc.howMany;\n                    } else if (inc.offset < oldEnd) {\n                        old.howMany += inc.nodesToHandle;\n                        inc.nodesToHandle = 0;\n                    }\n                }\n                if (old.type == 'remove') {\n                    if (inc.offset < old.offset) {\n                        old.offset += inc.howMany;\n                    }\n                }\n                if (old.type == 'attribute') {\n                    if (inc.offset <= old.offset) {\n                        old.offset += inc.howMany;\n                    } else if (inc.offset < oldEnd) {\n                        // This case is more complicated, because attribute change has to be split into two.\n                        // Example (assume that uppercase and lowercase letters mean different attributes):\n                        //\n                        // initial state:\t\tabcxyz\n                        // attribute change:\taBCXYz\n                        // incoming insert:\t\taBCfooXYz\n                        //\n                        // Change ranges cannot intersect because each item has to be described exactly (it was either\n                        // not changed, inserted, removed, or its attribute was changed). That's why old attribute\n                        // change has to be split and both parts has to be handled separately from now on.\n                        const howMany = old.howMany;\n                        old.howMany = inc.offset - old.offset;\n                        // Add the second part of attribute change to the beginning of processed array so it won't\n                        // be processed again in this loop.\n                        changes.unshift({\n                            type: 'attribute',\n                            offset: incEnd,\n                            howMany: howMany - old.howMany,\n                            count: this._changeCount++\n                        });\n                    }\n                }\n            }\n            if (inc.type == 'remove') {\n                if (old.type == 'insert') {\n                    if (incEnd <= old.offset) {\n                        old.offset -= inc.howMany;\n                    } else if (incEnd <= oldEnd) {\n                        if (inc.offset < old.offset) {\n                            const intersectionLength = incEnd - old.offset;\n                            old.offset = inc.offset;\n                            old.howMany -= intersectionLength;\n                            inc.nodesToHandle -= intersectionLength;\n                        } else {\n                            old.howMany -= inc.nodesToHandle;\n                            inc.nodesToHandle = 0;\n                        }\n                    } else {\n                        if (inc.offset <= old.offset) {\n                            inc.nodesToHandle -= old.howMany;\n                            old.howMany = 0;\n                        } else if (inc.offset < oldEnd) {\n                            const intersectionLength = oldEnd - inc.offset;\n                            old.howMany -= intersectionLength;\n                            inc.nodesToHandle -= intersectionLength;\n                        }\n                    }\n                }\n                if (old.type == 'remove') {\n                    if (incEnd <= old.offset) {\n                        old.offset -= inc.howMany;\n                    } else if (inc.offset < old.offset) {\n                        inc.nodesToHandle += old.howMany;\n                        old.howMany = 0;\n                    }\n                }\n                if (old.type == 'attribute') {\n                    if (incEnd <= old.offset) {\n                        old.offset -= inc.howMany;\n                    } else if (inc.offset < old.offset) {\n                        const intersectionLength = incEnd - old.offset;\n                        old.offset = inc.offset;\n                        old.howMany -= intersectionLength;\n                    } else if (inc.offset < oldEnd) {\n                        if (incEnd <= oldEnd) {\n                            // On first sight in this case we don't need to split attribute operation into two.\n                            // However the changes set is later converted to actions (see `_generateActionsFromChanges`).\n                            // For that reason, no two changes may intersect.\n                            // So we cannot have an attribute change that \"contains\" remove change.\n                            // Attribute change needs to be split.\n                            const howMany = old.howMany;\n                            old.howMany = inc.offset - old.offset;\n                            const howManyAfter = howMany - old.howMany - inc.nodesToHandle;\n                            // Add the second part of attribute change to the beginning of processed array so it won't\n                            // be processed again in this loop.\n                            changes.unshift({\n                                type: 'attribute',\n                                offset: inc.offset,\n                                howMany: howManyAfter,\n                                count: this._changeCount++\n                            });\n                        } else {\n                            old.howMany -= oldEnd - inc.offset;\n                        }\n                    }\n                }\n            }\n            if (inc.type == 'attribute') {\n                // In case of attribute change, `howMany` should be kept same as `nodesToHandle`. It's not an error.\n                if (old.type == 'insert') {\n                    if (inc.offset < old.offset && incEnd > old.offset) {\n                        if (incEnd > oldEnd) {\n                            // This case is similar to a case described when incoming change was insert and old change was attribute.\n                            // See comment above.\n                            //\n                            // This time incoming change is attribute. We need to split incoming change in this case too.\n                            // However this time, the second part of the attribute change needs to be processed further\n                            // because there might be other changes that it collides with.\n                            const attributePart = {\n                                type: 'attribute',\n                                offset: oldEnd,\n                                howMany: incEnd - oldEnd,\n                                count: this._changeCount++\n                            };\n                            this._handleChange(attributePart, changes);\n                            changes.push(attributePart);\n                        }\n                        inc.nodesToHandle = old.offset - inc.offset;\n                        inc.howMany = inc.nodesToHandle;\n                    } else if (inc.offset >= old.offset && inc.offset < oldEnd) {\n                        if (incEnd > oldEnd) {\n                            inc.nodesToHandle = incEnd - oldEnd;\n                            inc.offset = oldEnd;\n                        } else {\n                            inc.nodesToHandle = 0;\n                        }\n                    }\n                }\n                if (old.type == 'remove') {\n                    // This is a case when attribute change \"contains\" remove change.\n                    // The attribute change needs to be split into two because changes cannot intersect.\n                    if (inc.offset < old.offset && incEnd > old.offset) {\n                        const attributePart = {\n                            type: 'attribute',\n                            offset: old.offset,\n                            howMany: incEnd - old.offset,\n                            count: this._changeCount++\n                        };\n                        this._handleChange(attributePart, changes);\n                        changes.push(attributePart);\n                        inc.nodesToHandle = old.offset - inc.offset;\n                        inc.howMany = inc.nodesToHandle;\n                    }\n                }\n                if (old.type == 'attribute') {\n                    // There are only two conflicting scenarios possible here:\n                    if (inc.offset >= old.offset && incEnd <= oldEnd) {\n                        // `old` change includes `inc` change, or they are the same.\n                        inc.nodesToHandle = 0;\n                        inc.howMany = 0;\n                        inc.offset = 0;\n                    } else if (inc.offset <= old.offset && incEnd >= oldEnd) {\n                        // `inc` change includes `old` change.\n                        old.howMany = 0;\n                    }\n                }\n            }\n        }\n        inc.howMany = inc.nodesToHandle;\n        delete inc.nodesToHandle;\n    }\n    /**\n\t * Returns an object with a single insert change description.\n\t *\n\t * @param parent The element in which the change happened.\n\t * @param offset The offset at which change happened.\n\t * @param action Further specifies what kind of action led to generating this change.\n\t * @param elementSnapshot Snapshot of the inserted node after changes.\n\t * @param elementSnapshotBefore Snapshot of the inserted node before changes.\n\t * @returns The diff item.\n\t */ _getInsertDiff(parent, offset, action, elementSnapshot, elementSnapshotBefore) {\n        const diffItem = {\n            type: 'insert',\n            position: Position._createAt(parent, offset),\n            name: elementSnapshot.name,\n            attributes: new Map(elementSnapshot.attributes),\n            length: 1,\n            changeCount: this._changeCount++,\n            action\n        };\n        if (action != 'insert' && elementSnapshotBefore) {\n            diffItem.before = {\n                name: elementSnapshotBefore.name,\n                attributes: new Map(elementSnapshotBefore.attributes)\n            };\n        }\n        return diffItem;\n    }\n    /**\n\t * Returns an object with a single remove change description.\n\t *\n\t * @param parent The element in which change happened.\n\t * @param offset The offset at which change happened.\n\t * @param action Further specifies what kind of action led to generating this change.\n\t * @param elementSnapshot The snapshot of the removed node before changes.\n\t * @returns The diff item.\n\t */ _getRemoveDiff(parent, offset, action, elementSnapshot) {\n        return {\n            type: 'remove',\n            action,\n            position: Position._createAt(parent, offset),\n            name: elementSnapshot.name,\n            attributes: new Map(elementSnapshot.attributes),\n            length: 1,\n            changeCount: this._changeCount++\n        };\n    }\n    /**\n\t * Returns an array of objects where each one is a single attribute change description.\n\t *\n\t * @param range The range where the change happened.\n\t * @param oldAttributes A map, map iterator or compatible object that contains attributes before the change.\n\t * @param newAttributes A map, map iterator or compatible object that contains attributes after the change.\n\t * @returns An array containing one or more diff items.\n\t */ _getAttributesDiff(range, oldAttributes, newAttributes) {\n        // Results holder.\n        const diffs = [];\n        // Clone new attributes as we will be performing changes on this object.\n        newAttributes = new Map(newAttributes);\n        // Look through old attributes.\n        for (const [key, oldValue] of oldAttributes){\n            // Check what is the new value of the attribute (or if it was removed).\n            const newValue = newAttributes.has(key) ? newAttributes.get(key) : null;\n            // If values are different (or attribute was removed)...\n            if (newValue !== oldValue) {\n                // Add diff item.\n                diffs.push({\n                    type: 'attribute',\n                    position: range.start,\n                    range: range.clone(),\n                    length: 1,\n                    attributeKey: key,\n                    attributeOldValue: oldValue,\n                    attributeNewValue: newValue,\n                    changeCount: this._changeCount++\n                });\n            }\n            // Prevent returning two diff items for the same change.\n            newAttributes.delete(key);\n        }\n        // Look through new attributes that weren't handled above.\n        for (const [key, newValue] of newAttributes){\n            // Each of them is a new attribute. Add diff item.\n            diffs.push({\n                type: 'attribute',\n                position: range.start,\n                range: range.clone(),\n                length: 1,\n                attributeKey: key,\n                attributeOldValue: null,\n                attributeNewValue: newValue,\n                changeCount: this._changeCount++\n            });\n        }\n        return diffs;\n    }\n    /**\n\t * Checks whether given element or any of its parents is an element that is buffered as an inserted element.\n\t */ _isInInsertedElement(element) {\n        const parent = element.parent;\n        if (!parent) {\n            return false;\n        }\n        const changes = this._changesInElement.get(parent);\n        const offset = element.startOffset;\n        if (changes) {\n            for (const change of changes){\n                if (change.type == 'insert' && offset >= change.offset && offset < change.offset + change.howMany) {\n                    return true;\n                }\n            }\n        }\n        return this._isInInsertedElement(parent);\n    }\n    /**\n\t * Removes deeply all buffered changes that are registered in elements from range specified by `parent`, `offset`\n\t * and `howMany`.\n\t */ _removeAllNestedChanges(parent, offset, howMany) {\n        const range = new Range(Position._createAt(parent, offset), Position._createAt(parent, offset + howMany));\n        for (const item of range.getItems({\n            shallow: true\n        })){\n            if (item.is('element')) {\n                this._changesInElement.delete(item);\n                this._removeAllNestedChanges(item, 0, item.maxOffset);\n            }\n        }\n    }\n}\n/**\n * Returns a snapshot for the specified child node. Text node snapshots have the `name` property set to `$text`.\n */ function _getSingleNodeSnapshot(node) {\n    return {\n        node,\n        name: node.is('$text') ? '$text' : node.name,\n        attributes: new Map(node.getAttributes())\n    };\n}\n/**\n * Returns an array that is a copy of passed child list with the exception that text nodes are split to one or more\n * objects, each representing one character and attributes set on that character.\n */ function _getChildrenSnapshots(children) {\n    const snapshots = [];\n    for (const child of children){\n        if (child.is('$text')) {\n            for(let i = 0; i < child.data.length; ++i){\n                snapshots.push(_getSingleNodeSnapshot(child));\n            }\n        } else {\n            snapshots.push(_getSingleNodeSnapshot(child));\n        }\n    }\n    return snapshots;\n}\n/**\n * Generates array of diff instructions for given changes set.\n *\n * Generated actions are:\n *\n * - 'e' for 'equal' - when item at that position did not change,\n * - 'i' for 'insert' - when item at that position was inserted,\n * - 'r' for 'remove' - when item at that position was removed,\n * - 'a' for 'attribute' - when item at that position has it attributes changed.\n *\n * Example (assume that uppercase letters have bold attribute, compare with function code):\n *\n * children before:\tfooBAR\n * children after:\tfoxybAR\n *\n * changes: type: remove, offset: 1, howMany: 1\n *\t\t\ttype: insert, offset: 2, howMany: 2\n *\t\t\ttype: attribute, offset: 4, howMany: 1\n *\n * Expected actions: equal (f), remove (o), equal (o), insert (x), insert (y), attribute (b), equal (A), equal (R)\n *\n * Steps taken by the script:\n *\n * 1. change = \"type: remove, offset: 1, howMany: 1\"; offset = 0; oldChildrenHandled = 0\n *    1.1 between this change and the beginning is one not-changed node, fill with one equal action, one old child has been handled\n *    1.2 this change removes one node, add one remove action\n *    1.3 change last visited `offset` to 1\n *    1.4 since an old child has been removed, one more old child has been handled\n *    1.5 actions at this point are: equal, remove\n *\n * 2. change = \"type: insert, offset: 2, howMany: 2\"; offset = 1; oldChildrenHandled = 2\n *    2.1 between this change and previous change is one not-changed node, add equal action, another one old children has been handled\n *    2.2 this change inserts two nodes, add two insert actions\n *    2.3 change last visited offset to the end of the inserted range, that is 4\n *    2.4 actions at this point are: equal, remove, equal, insert, insert\n *\n * 3. change = \"type: attribute, offset: 4, howMany: 1\"; offset = 4, oldChildrenHandled = 3\n *    3.1 between this change and previous change are no not-changed nodes\n *    3.2 this change changes one node, add one attribute action\n *    3.3 change last visited `offset` to the end of change range, that is 5\n *    3.4 since an old child has been changed, one more old child has been handled\n *    3.5 actions at this point are: equal, remove, equal, insert, insert, attribute\n *\n * 4. after loop oldChildrenHandled = 4, oldChildrenLength = 6 (fooBAR is 6 characters)\n *    4.1 fill up with two equal actions\n *\n * The result actions are: equal, remove, equal, insert, insert, attribute, equal, equal.\n */ function _generateDiffInstructionsFromChanges(oldChildrenLength, changes) {\n    const diff = [];\n    let offset = 0;\n    let oldChildrenHandled = 0;\n    // Go through all buffered changes.\n    for (const change of changes){\n        // First, fill \"holes\" between changes with \"equal\" actions.\n        if (change.offset > offset) {\n            for(let i = 0; i < change.offset - offset; i++){\n                diff.push('e');\n            }\n            oldChildrenHandled += change.offset - offset;\n        }\n        // Then, fill up actions accordingly to change type.\n        if (change.type == 'insert') {\n            for(let i = 0; i < change.howMany; i++){\n                diff.push('i');\n            }\n            // The last handled offset is after inserted range.\n            offset = change.offset + change.howMany;\n        } else if (change.type == 'remove') {\n            for(let i = 0; i < change.howMany; i++){\n                diff.push('r');\n            }\n            // The last handled offset is at the position where the nodes were removed.\n            offset = change.offset;\n            // We removed `howMany` old nodes, update `oldChildrenHandled`.\n            oldChildrenHandled += change.howMany;\n        } else {\n            // Total maximum amount of arguments that can be passed to `Array.prototype.push` may be limited so we need to\n            // add them manually one by one to avoid this limit. However loop might be a bit slower than `push` method on\n            // smaller changesets so we need to decide which method to use based on the size of the change.\n            // See: https://github.com/ckeditor/ckeditor5/issues/16819\n            if (change.howMany > 1500) {\n                for(let i = 0; i < change.howMany; i++){\n                    diff.push('a');\n                }\n            } else {\n                diff.push(...'a'.repeat(change.howMany).split(''));\n            }\n            // The last handled offset is at the position after the changed range.\n            offset = change.offset + change.howMany;\n            // We changed `howMany` old nodes, update `oldChildrenHandled`.\n            oldChildrenHandled += change.howMany;\n        }\n    }\n    // Fill \"equal\" actions at the end of actions set. Use `oldChildrenHandled` to see how many children\n    // has not been changed / removed at the end of their parent.\n    if (oldChildrenHandled < oldChildrenLength) {\n        for(let i = 0; i < oldChildrenLength - oldChildrenHandled - offset; i++){\n            diff.push('e');\n        }\n    }\n    return diff;\n}\n/**\n * Filter callback for `Array.filter` that filters out change entries that are in graveyard.\n */ function _changesInGraveyardFilter(entry) {\n    const posInGy = 'position' in entry && entry.position.root.rootName == '$graveyard';\n    const rangeInGy = 'range' in entry && entry.range.root.rootName == '$graveyard';\n    return !posInGy && !rangeInGy;\n}\n\n/**\n * @module engine/model/history\n */ /**\n * `History` keeps the track of all the operations applied to the {@link module:engine/model/document~Document document}.\n */ class History {\n    /**\n\t * Operations added to the history.\n\t */ _operations = [];\n    /**\n\t * Holds an information which {@link module:engine/model/operation/operation~Operation operation} undoes which\n\t * {@link module:engine/model/operation/operation~Operation operation}.\n\t *\n\t * Keys of the map are \"undoing operations\", that is operations that undone some other operations. For each key, the\n\t * value is an operation that has been undone by the \"undoing operation\".\n\t */ _undoPairs = new Map();\n    /**\n\t * Holds all undone operations.\n\t */ _undoneOperations = new Set();\n    /**\n\t * A map that allows retrieving the operations fast based on the given base version.\n\t */ _baseVersionToOperationIndex = new Map();\n    /**\n\t * The history version.\n\t */ _version = 0;\n    /**\n\t * The gap pairs kept in the <from,to> format.\n\t *\n\t * Anytime the `history.version` is set to a version larger than `history.version + 1`,\n\t * a new <lastHistoryVersion, newHistoryVersion> entry is added to the map.\n\t */ _gaps = new Map();\n    /**\n\t * The version of the last operation in the history.\n\t *\n\t * The history version is incremented automatically when a new operation is added to the history.\n\t * Setting the version manually should be done only in rare circumstances when a gap is planned\n\t * between history versions. When doing so, a gap will be created and the history will accept adding\n\t * an operation with base version equal to the new history version.\n\t */ get version() {\n        return this._version;\n    }\n    set version(version) {\n        // Store a gap if there are some operations already in the history and the\n        // new version does not increment the latest one.\n        if (this._operations.length && version > this._version + 1) {\n            this._gaps.set(this._version, version);\n        }\n        this._version = version;\n    }\n    /**\n\t * The last history operation.\n\t */ get lastOperation() {\n        return this._operations[this._operations.length - 1];\n    }\n    /**\n\t * Adds an operation to the history and increments the history version.\n\t *\n\t * The operation's base version should be equal to the history version. Otherwise an error is thrown.\n\t */ addOperation(operation) {\n        if (operation.baseVersion !== this.version) {\n            /**\n\t\t\t * Only operations with matching versions can be added to the history.\n\t\t\t *\n\t\t\t * @error model-document-history-addoperation-incorrect-version\n\t\t\t * @param errorData The operation and the current document history version.\n\t\t\t */ throw new CKEditorError('model-document-history-addoperation-incorrect-version', this, {\n                operation,\n                historyVersion: this.version\n            });\n        }\n        this._operations.push(operation);\n        this._version++;\n        this._baseVersionToOperationIndex.set(operation.baseVersion, this._operations.length - 1);\n    }\n    /**\n\t * Returns operations from the given range of operation base versions that were added to the history.\n\t *\n\t * Note that there may be gaps in operations base versions.\n\t *\n\t * @param fromBaseVersion Base version from which operations should be returned (inclusive).\n\t * @param toBaseVersion Base version up to which operations should be returned (exclusive).\n     * @returns History operations for the given range, in chronological order.\n\t */ getOperations(fromBaseVersion, toBaseVersion = this.version) {\n        // When there is no operation in the history, return an empty array.\n        // After that we can be sure that `firstOperation`, `lastOperation` are not nullish.\n        if (!this._operations.length) {\n            return [];\n        }\n        const firstOperation = this._operations[0];\n        if (fromBaseVersion === undefined) {\n            fromBaseVersion = firstOperation.baseVersion;\n        }\n        // Change exclusive `toBaseVersion` to inclusive, so it will refer to the actual index.\n        // Thanks to that mapping from base versions to operation indexes are possible.\n        let inclusiveTo = toBaseVersion - 1;\n        // Check if \"from\" or \"to\" point to a gap between versions.\n        // If yes, then change the incorrect position to the proper side of the gap.\n        // Thanks to it, it will be possible to get index of the operation.\n        for (const [gapFrom, gapTo] of this._gaps){\n            if (fromBaseVersion > gapFrom && fromBaseVersion < gapTo) {\n                fromBaseVersion = gapTo;\n            }\n            if (inclusiveTo > gapFrom && inclusiveTo < gapTo) {\n                inclusiveTo = gapFrom - 1;\n            }\n        }\n        // If the whole range is outside of the operation versions, then return an empty array.\n        if (inclusiveTo < firstOperation.baseVersion || fromBaseVersion > this.lastOperation.baseVersion) {\n            return [];\n        }\n        let fromIndex = this._baseVersionToOperationIndex.get(fromBaseVersion);\n        // If the range starts before the first operation, then use the first operation as the range's start.\n        if (fromIndex === undefined) {\n            fromIndex = 0;\n        }\n        let toIndex = this._baseVersionToOperationIndex.get(inclusiveTo);\n        // If the range ends after the last operation, then use the last operation as the range's end.\n        if (toIndex === undefined) {\n            toIndex = this._operations.length - 1;\n        }\n        // Return the part of the history operations based on the calculated start index and end index.\n        return this._operations.slice(fromIndex, // The `toIndex` should be included in the returned operations, so add `1`.\n        toIndex + 1);\n    }\n    /**\n\t * Returns operation from the history that bases on given `baseVersion`.\n\t *\n\t * @param baseVersion Base version of the operation to get.\n\t * @returns Operation with given base version or `undefined` if there is no such operation in history.\n\t */ getOperation(baseVersion) {\n        const operationIndex = this._baseVersionToOperationIndex.get(baseVersion);\n        if (operationIndex === undefined) {\n            return;\n        }\n        return this._operations[operationIndex];\n    }\n    /**\n\t * Marks in history that one operation is an operation that is undoing the other operation. By marking operation this way,\n\t * history is keeping more context information about operations, which helps in operational transformation.\n\t *\n\t * @param undoneOperation Operation which is undone by `undoingOperation`.\n\t * @param undoingOperation Operation which undoes `undoneOperation`.\n\t */ setOperationAsUndone(undoneOperation, undoingOperation) {\n        this._undoPairs.set(undoingOperation, undoneOperation);\n        this._undoneOperations.add(undoneOperation);\n    }\n    /**\n\t * Checks whether given `operation` is undoing any other operation.\n\t *\n\t * @param operation Operation to check.\n\t * @returns `true` if given `operation` is undoing any other operation, `false` otherwise.\n\t */ isUndoingOperation(operation) {\n        return this._undoPairs.has(operation);\n    }\n    /**\n\t * Checks whether given `operation` has been undone by any other operation.\n\t *\n\t * @param operation Operation to check.\n\t * @returns `true` if given `operation` has been undone any other operation, `false` otherwise.\n\t */ isUndoneOperation(operation) {\n        return this._undoneOperations.has(operation);\n    }\n    /**\n\t * For given `undoingOperation`, returns the operation which has been undone by it.\n\t *\n\t * @returns Operation that has been undone by given `undoingOperation` or `undefined`\n\t * if given `undoingOperation` is not undoing any other operation.\n\t */ getUndoneOperation(undoingOperation) {\n        return this._undoPairs.get(undoingOperation);\n    }\n    /**\n\t * Resets the history of operations.\n\t */ reset() {\n        this._version = 0;\n        this._undoPairs = new Map();\n        this._operations = [];\n        this._undoneOperations = new Set();\n        this._gaps = new Map();\n        this._baseVersionToOperationIndex = new Map();\n    }\n}\n\n/**\n * Type of {@link module:engine/model/element~Element} that is a root of a model tree.\n */ class RootElement extends Element {\n    /**\n\t * Unique root name used to identify this root element by {@link module:engine/model/document~Document}.\n\t */ rootName;\n    /**\n\t * Document that is an owner of this root.\n\t */ _document;\n    /**\n\t * @internal\n\t */ _isAttached = true;\n    /**\n\t * Informs if the root element is loaded (default).\n\t *\n\t * @internal\n\t */ _isLoaded = true;\n    /**\n\t * Creates root element.\n\t *\n\t * @param document Document that is an owner of this root.\n\t * @param name Node name.\n\t * @param rootName Unique root name used to identify this root element by {@link module:engine/model/document~Document}.\n\t */ constructor(document, name, rootName = 'main'){\n        super(name);\n        this._document = document;\n        this.rootName = rootName;\n    }\n    /**\n\t * {@link module:engine/model/document~Document Document} that owns this root element.\n\t */ get document() {\n        return this._document;\n    }\n    /**\n\t * Informs if the root element is currently attached to the document, or not.\n\t *\n\t * A detached root is equivalent to being removed and cannot contain any children or markers.\n\t *\n\t * By default, a newly added root is attached. It can be detached using\n\t * {@link module:engine/model/writer~Writer#detachRoot `Writer#detachRoot`}. A detached root can be re-attached again using\n\t * {@link module:engine/model/writer~Writer#addRoot `Writer#addRoot`}.\n\t */ isAttached() {\n        return this._isAttached;\n    }\n    /**\n\t * Converts `RootElement` instance to `string` containing its name.\n\t *\n\t * @returns `RootElement` instance converted to `string`.\n\t */ toJSON() {\n        return this.rootName;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRootElement.prototype.is = function(type, name) {\n    if (!name) {\n        return type === 'rootElement' || type === 'model:rootElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n        type === 'element' || type === 'model:element' || type === 'node' || type === 'model:node';\n    }\n    return name === this.name && (type === 'rootElement' || type === 'model:rootElement' || // From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n    type === 'element' || type === 'model:element');\n};\n\n// @if CK_DEBUG_ENGINE // const { logDocument } = require( '../dev-utils/utils' );\nconst graveyardName = '$graveyard';\n/**\n * Data model's document. It contains the model's structure, its selection and the history of changes.\n *\n * Read more about working with the model in\n * {@glink framework/architecture/editing-engine#model introduction to the the editing engine's architecture}.\n *\n * Usually, the document contains just one {@link module:engine/model/document~Document#roots root element}, so\n * you can retrieve it by just calling {@link module:engine/model/document~Document#getRoot} without specifying its name:\n *\n * ```ts\n * model.document.getRoot(); // -> returns the main root\n * ```\n *\n * However, the document may contain multiple roots – e.g. when the editor has multiple editable areas\n * (e.g. a title and a body of a message).\n */ class Document extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * The {@link module:engine/model/model~Model model} that the document is a part of.\n\t */ model;\n    /**\n\t * The document's history.\n\t */ history;\n    /**\n\t * The selection in this document.\n\t */ selection;\n    /**\n\t * A list of roots that are owned and managed by this document. Use {@link #createRoot}, {@link #getRoot} and\n\t * {@link #getRootNames} to manipulate it.\n\t */ roots;\n    /**\n\t * The model differ object. Its role is to buffer changes done on the model document and then calculate a diff of those changes.\n\t */ differ;\n    /**\n\t * Defines whether the document is in a read-only mode.\n\t *\n\t * The user should not be able to change the data of a document that is read-only.\n\t *\n\t * @readonly\n\t */ isReadOnly;\n    /**\n\t * Post-fixer callbacks registered to the model document.\n\t */ _postFixers;\n    /**\n\t * A flag that indicates whether the selection has changed since last change block.\n\t */ _hasSelectionChangedFromTheLastChangeBlock;\n    /**\n\t * Creates an empty document instance with no {@link #roots} (other than\n\t * the {@link #graveyard graveyard root}).\n\t */ constructor(model){\n        super();\n        this.model = model;\n        this.history = new History();\n        this.selection = new DocumentSelection(this);\n        this.roots = new Collection({\n            idProperty: 'rootName'\n        });\n        this.differ = new Differ(model.markers);\n        this.isReadOnly = false;\n        this._postFixers = new Set();\n        this._hasSelectionChangedFromTheLastChangeBlock = false;\n        // Graveyard tree root. Document always have a graveyard root, which stores removed nodes.\n        this.createRoot('$root', graveyardName);\n        // Then, still before an operation is applied on model, buffer the change in differ.\n        this.listenTo(model, 'applyOperation', (evt, args)=>{\n            const operation = args[0];\n            if (operation.isDocumentOperation) {\n                this.differ.bufferOperation(operation);\n            }\n        }, {\n            priority: 'high'\n        });\n        // After the operation is applied, bump document's version and add the operation to the history.\n        this.listenTo(model, 'applyOperation', (evt, args)=>{\n            const operation = args[0];\n            if (operation.isDocumentOperation) {\n                this.history.addOperation(operation);\n            }\n        }, {\n            priority: 'low'\n        });\n        // Listen to selection changes. If selection changed, mark it.\n        this.listenTo(this.selection, 'change', ()=>{\n            this._hasSelectionChangedFromTheLastChangeBlock = true;\n        });\n        // Buffer marker changes.\n        // This is not covered in buffering operations because markers may change outside of them (when they\n        // are modified using `model.markers` collection, not through `MarkerOperation`).\n        this.listenTo(model.markers, 'update', (evt, marker, oldRange, newRange, oldMarkerData)=>{\n            // Copy the `newRange` to the new marker data as during the marker removal the range is not updated.\n            const newMarkerData = {\n                ...marker.getData(),\n                range: newRange\n            };\n            // Whenever marker is updated, buffer that change.\n            this.differ.bufferMarkerChange(marker.name, oldMarkerData, newMarkerData);\n            if (oldRange === null) {\n                // If this is a new marker, add a listener that will buffer change whenever marker changes.\n                marker.on('change', (evt, oldRange)=>{\n                    const markerData = marker.getData();\n                    this.differ.bufferMarkerChange(marker.name, {\n                        ...markerData,\n                        range: oldRange\n                    }, markerData);\n                });\n            }\n        });\n        // This is a solution for a problem that may occur during real-time editing. If one client detached a root and another added\n        // something there at the same moment, the OT does not solve this problem currently. In such situation, the added elements would\n        // stay in the detached root.\n        //\n        // This is incorrect, a detached root should be empty and all elements from it should be removed. To solve this, the post-fixer will\n        // remove any element that is left in a detached root.\n        //\n        // Similarly, markers that are created at the beginning or at the end of the detached root will not be removed as well.\n        //\n        // The drawback of this solution over the OT solution is that the elements removed by the post-fixer will never be brought back.\n        // If the root detachment gets undone (and the root is brought back), the removed elements will not be there.\n        this.registerPostFixer((writer)=>{\n            let result = false;\n            for (const root of this.roots){\n                if (!root.isAttached() && !root.isEmpty) {\n                    writer.remove(writer.createRangeIn(root));\n                    result = true;\n                }\n            }\n            for (const marker of this.model.markers){\n                if (!marker.getRange().root.isAttached()) {\n                    writer.removeMarker(marker);\n                    result = true;\n                }\n            }\n            return result;\n        });\n    }\n    /**\n\t * The document version. Every applied operation increases the version number. It is used to\n\t * ensure that operations are applied on a proper document version.\n\t *\n\t * This property is equal to {@link module:engine/model/history~History#version `model.Document#history#version`}.\n\t *\n\t * If the {@link module:engine/model/operation/operation~Operation#baseVersion base version} does not match the document version,\n\t * a {@link module:utils/ckeditorerror~CKEditorError model-document-applyoperation-wrong-version} error is thrown.\n\t */ get version() {\n        return this.history.version;\n    }\n    set version(version) {\n        this.history.version = version;\n    }\n    /**\n\t * The graveyard tree root. A document always has a graveyard root that stores removed nodes.\n\t */ get graveyard() {\n        return this.getRoot(graveyardName);\n    }\n    /**\n\t * Creates a new root.\n\t *\n\t * **Note:** do not use this method after the editor has been initialized! If you want to dynamically add a root, use\n\t * {@link module:engine/model/writer~Writer#addRoot `model.Writer#addRoot`} instead.\n\t *\n\t * @param elementName The element name. Defaults to `'$root'` which also has some basic schema defined\n\t * (e.g. `$block` elements are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.\n\t * @param rootName A unique root name.\n\t * @returns The created root.\n\t */ createRoot(elementName = '$root', rootName = 'main') {\n        if (this.roots.get(rootName)) {\n            /**\n\t\t\t * A root with the specified name already exists.\n\t\t\t *\n\t\t\t * @error model-document-createroot-name-exists\n\t\t\t */ throw new CKEditorError('model-document-createroot-name-exists', this, {\n                name: rootName\n            });\n        }\n        const root = new RootElement(this, elementName, rootName);\n        this.roots.add(root);\n        return root;\n    }\n    /**\n\t * Removes all event listeners set by the document instance.\n\t */ destroy() {\n        this.selection.destroy();\n        this.stopListening();\n    }\n    /**\n\t * Returns a root by its name.\n\t *\n\t * Detached roots are returned by this method. This is to be able to operate on the detached root (for example, to be able to create\n\t * a position inside such a root for undo feature purposes).\n\t *\n\t * @param name The root name of the root to return.\n\t * @returns The root registered under a given name or `null` when there is no root with the given name.\n\t */ getRoot(name = 'main') {\n        return this.roots.get(name);\n    }\n    /**\n\t * Returns an array with names of all roots added to the document (except the {@link #graveyard graveyard root}).\n\t *\n\t * Detached roots **are not** returned by this method by default. This is to make sure that all features or algorithms that operate\n\t * on the document data know which roots are still a part of the document and should be processed.\n\t *\n\t * @param includeDetached Specified whether detached roots should be returned as well.\n\t */ getRootNames(includeDetached = false) {\n        return this.getRoots(includeDetached).map((root)=>root.rootName);\n    }\n    /**\n\t * Returns an array with all roots added to the document (except the {@link #graveyard graveyard root}).\n\t *\n\t * Detached roots **are not** returned by this method by default. This is to make sure that all features or algorithms that operate\n\t * on the document data know which roots are still a part of the document and should be processed.\n\t *\n\t * @param includeDetached Specified whether detached roots should be returned as well.\n\t */ getRoots(includeDetached = false) {\n        return this.roots.filter((root)=>root != this.graveyard && (includeDetached || root.isAttached()) && root._isLoaded);\n    }\n    /**\n\t * Used to register a post-fixer callback. A post-fixer mechanism guarantees that the features\n\t * will operate on a correct model state.\n\t *\n\t * An execution of a feature may lead to an incorrect document tree state. The callbacks are used to fix the document tree after\n\t * it has changed. Post-fixers are fired just after all changes from the outermost change block were applied but\n\t * before the {@link module:engine/model/document~Document#event:change change event} is fired. If a post-fixer callback made\n\t * a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t * not be fixed in the new document tree state.\n\t *\n\t * As a parameter, a post-fixer callback receives a {@link module:engine/model/writer~Writer writer} instance connected with the\n\t * executed changes block. Thanks to that, all changes done by the callback will be added to the same\n\t * {@link module:engine/model/batch~Batch batch} (and undo step) as the original changes. This makes post-fixer changes transparent\n\t * for the user.\n\t *\n\t * An example of a post-fixer is a callback that checks if all the data were removed from the editor. If so, the\n\t * callback should add an empty paragraph so that the editor is never empty:\n\t *\n\t * ```ts\n\t * document.registerPostFixer( writer => {\n\t * \tconst changes = document.differ.getChanges();\n\t *\n\t * \t// Check if the changes lead to an empty root in the editor.\n\t * \tfor ( const entry of changes ) {\n\t * \t\tif ( entry.type == 'remove' && entry.position.root.isEmpty ) {\n\t * \t\t\twriter.insertElement( 'paragraph', entry.position.root, 0 );\n\t *\n\t * \t\t\t// It is fine to return early, even if multiple roots would need to be fixed.\n\t * \t\t\t// All post-fixers will be fired again, so if there are more empty roots, those will be fixed, too.\n\t * \t\t\treturn true;\n\t * \t\t}\n\t * \t}\n\t *\n\t * \treturn false;\n\t * } );\n\t * ```\n\t */ registerPostFixer(postFixer) {\n        this._postFixers.add(postFixer);\n    }\n    /**\n\t * A custom `toJSON()` method to solve child-parent circular dependencies.\n\t *\n\t * @returns A clone of this object with the document property changed to a string.\n\t */ toJSON() {\n        const json = clone(this);\n        // Due to circular references we need to remove parent reference.\n        json.selection = '[engine.model.DocumentSelection]';\n        json.model = '[engine.model.Model]';\n        return json;\n    }\n    /**\n\t * Check if there were any changes done on document, and if so, call post-fixers,\n\t * fire `change` event for features and conversion and then reset the differ.\n\t * Fire `change:data` event when at least one operation or buffered marker changes the data.\n\t *\n\t * @internal\n\t * @fires change\n\t * @fires change:data\n\t * @param writer The writer on which post-fixers will be called.\n\t */ _handleChangeBlock(writer) {\n        if (this._hasDocumentChangedFromTheLastChangeBlock()) {\n            this._callPostFixers(writer);\n            // Refresh selection attributes according to the final position in the model after the change.\n            this.selection.refresh();\n            if (this.differ.hasDataChanges()) {\n                this.fire('change:data', writer.batch);\n            } else {\n                this.fire('change', writer.batch);\n            }\n            // Theoretically, it is not necessary to refresh selection after change event because\n            // post-fixers are the last who should change the model, but just in case...\n            this.selection.refresh();\n            this.differ.reset();\n        }\n        this._hasSelectionChangedFromTheLastChangeBlock = false;\n    }\n    /**\n\t * Returns whether there is a buffered change or if the selection has changed from the last\n\t * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block}\n\t * or {@link module:engine/model/model~Model#change `change()` block}.\n\t *\n\t * @returns Returns `true` if document has changed from the last `change()` or `enqueueChange()` block.\n\t */ _hasDocumentChangedFromTheLastChangeBlock() {\n        return !this.differ.isEmpty || this._hasSelectionChangedFromTheLastChangeBlock;\n    }\n    /**\n\t * Returns the default root for this document which is either the first root that was added to the document using\n\t * {@link #createRoot} or the {@link #graveyard graveyard root} if no other roots were created.\n\t *\n\t * @returns The default root for this document.\n\t */ _getDefaultRoot() {\n        const roots = this.getRoots();\n        return roots.length ? roots[0] : this.graveyard;\n    }\n    /**\n\t * Returns the default range for this selection. The default range is a collapsed range that starts and ends\n\t * at the beginning of this selection's document {@link #_getDefaultRoot default root}.\n\t *\n\t * @internal\n\t */ _getDefaultRange() {\n        const defaultRoot = this._getDefaultRoot();\n        const model = this.model;\n        const schema = model.schema;\n        // Find the first position where the selection can be put.\n        const position = model.createPositionFromPath(defaultRoot, [\n            0\n        ]);\n        const nearestRange = schema.getNearestSelectionRange(position);\n        // If valid selection range is not found - return range collapsed at the beginning of the root.\n        return nearestRange || model.createRange(position);\n    }\n    /**\n\t * Checks whether a given {@link module:engine/model/range~Range range} is a valid range for\n\t * the {@link #selection document's selection}.\n\t *\n\t * @internal\n\t * @param range A range to check.\n\t * @returns `true` if `range` is valid, `false` otherwise.\n\t */ _validateSelectionRange(range) {\n        return range.start.isValid() && range.end.isValid() && validateTextNodePosition(range.start) && validateTextNodePosition(range.end);\n    }\n    /**\n\t * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t *\n\t * @param writer The writer on which post-fixer callbacks will be called.\n\t */ _callPostFixers(writer) {\n        let wasFixed = false;\n        do {\n            for (const callback of this._postFixers){\n                // Ensure selection attributes are up to date before each post-fixer.\n                // https://github.com/ckeditor/ckeditor5-engine/issues/1673.\n                //\n                // It might be good to refresh the selection after each operation but at the moment it leads\n                // to losing attributes for composition or and spell checking\n                // https://github.com/ckeditor/ckeditor5-typing/issues/188\n                this.selection.refresh();\n                wasFixed = callback(writer);\n                if (wasFixed) {\n                    break;\n                }\n            }\n        }while (wasFixed)\n    }\n}\n/**\n * Checks whether given range boundary position is valid for document selection, meaning that is not between\n * unicode surrogate pairs or base character and combining marks.\n */ function validateTextNodePosition(rangeBoundary) {\n    const textNode = rangeBoundary.textNode;\n    if (textNode) {\n        const data = textNode.data;\n        const offset = rangeBoundary.offset - textNode.startOffset;\n        return !isInsideSurrogatePair(data, offset) && !isInsideCombinedSymbol(data, offset);\n    }\n    return true;\n}\n\n/**\n * The collection of all {@link module:engine/model/markercollection~Marker markers} attached to the document.\n * It lets you {@link module:engine/model/markercollection~MarkerCollection#get get} markers or track them using\n * {@link module:engine/model/markercollection~MarkerCollection#event:update} event.\n *\n * To create, change or remove makers use {@link module:engine/model/writer~Writer model writers'} methods:\n * {@link module:engine/model/writer~Writer#addMarker} or {@link module:engine/model/writer~Writer#removeMarker}. Since\n * the writer is the only proper way to change the data model it is not possible to change markers directly using this\n * collection. All markers created by the writer will be automatically added to this collection.\n *\n * By default there is one marker collection available as {@link module:engine/model/model~Model#markers model property}.\n *\n * @see module:engine/model/markercollection~Marker\n */ class MarkerCollection extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * Stores {@link ~Marker markers} added to the collection.\n\t */ _markers = new Map();\n    /**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link ~Marker markers} added to the collection.\n\t */ [Symbol.iterator]() {\n        return this._markers.values();\n    }\n    /**\n\t * Checks if given {@link ~Marker marker} or marker name is in the collection.\n\t *\n\t * @param markerOrName Name of marker or marker instance to check.\n\t * @returns `true` if marker is in the collection, `false` otherwise.\n\t */ has(markerOrName) {\n        const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n        return this._markers.has(markerName);\n    }\n    /**\n\t * Returns {@link ~Marker marker} with given `markerName`.\n\t *\n\t * @param markerName Name of marker to get.\n\t * @returns Marker with given name or `null` if such marker was\n\t * not added to the collection.\n\t */ get(markerName) {\n        return this._markers.get(markerName) || null;\n    }\n    /**\n\t * Creates and adds a {@link ~Marker marker} to the `MarkerCollection` with given name on given\n\t * {@link module:engine/model/range~Range range}.\n\t *\n\t * If `MarkerCollection` already had a marker with given name (or {@link ~Marker marker} was passed), the marker in\n\t * collection is updated and {@link module:engine/model/markercollection~MarkerCollection#event:update} event is fired\n\t * but only if there was a change (marker range or {@link module:engine/model/markercollection~Marker#managedUsingOperations}\n\t * flag has changed.\n\t *\n\t * @internal\n\t * @fires update\n\t * @param markerOrName Name of marker to set or marker instance to update.\n\t * @param range Marker range.\n\t * @param managedUsingOperations Specifies whether the marker is managed using operations.\n\t * @param affectsData Specifies whether the marker affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t * @returns `Marker` instance which was added or updated.\n\t */ _set(markerOrName, range, managedUsingOperations = false, affectsData = false) {\n        const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n        if (markerName.includes(',')) {\n            /**\n\t\t\t * Marker name cannot contain the \",\" character.\n\t\t\t *\n\t\t\t * @error markercollection-incorrect-marker-name\n\t\t\t */ throw new CKEditorError('markercollection-incorrect-marker-name', this);\n        }\n        const oldMarker = this._markers.get(markerName);\n        if (oldMarker) {\n            const oldMarkerData = oldMarker.getData();\n            const oldRange = oldMarker.getRange();\n            let hasChanged = false;\n            if (!oldRange.isEqual(range)) {\n                oldMarker._attachLiveRange(LiveRange.fromRange(range));\n                hasChanged = true;\n            }\n            if (managedUsingOperations != oldMarker.managedUsingOperations) {\n                oldMarker._managedUsingOperations = managedUsingOperations;\n                hasChanged = true;\n            }\n            if (typeof affectsData === 'boolean' && affectsData != oldMarker.affectsData) {\n                oldMarker._affectsData = affectsData;\n                hasChanged = true;\n            }\n            if (hasChanged) {\n                this.fire(`update:${markerName}`, oldMarker, oldRange, range, oldMarkerData);\n            }\n            return oldMarker;\n        }\n        const liveRange = LiveRange.fromRange(range);\n        const marker = new Marker(markerName, liveRange, managedUsingOperations, affectsData);\n        this._markers.set(markerName, marker);\n        this.fire(`update:${markerName}`, marker, null, range, {\n            ...marker.getData(),\n            range: null\n        });\n        return marker;\n    }\n    /**\n\t * Removes given {@link ~Marker marker} or a marker with given name from the `MarkerCollection`.\n\t *\n\t * @internal\n\t * @fires update\n\t * @param markerOrName Marker or name of a marker to remove.\n\t * @returns `true` if marker was found and removed, `false` otherwise.\n\t */ _remove(markerOrName) {\n        const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n        const oldMarker = this._markers.get(markerName);\n        if (oldMarker) {\n            this._markers.delete(markerName);\n            this.fire(`update:${markerName}`, oldMarker, oldMarker.getRange(), null, oldMarker.getData());\n            this._destroyMarker(oldMarker);\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Fires an {@link module:engine/model/markercollection~MarkerCollection#event:update} event for the given {@link ~Marker marker}\n\t * but does not change the marker. Useful to force {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher downcast\n\t * conversion} for the marker.\n\t *\n\t * @internal\n\t * @fires update\n\t * @param markerOrName Marker or name of a marker to refresh.\n\t */ _refresh(markerOrName) {\n        const markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n        const marker = this._markers.get(markerName);\n        if (!marker) {\n            /**\n\t\t\t * Marker with provided name does not exists.\n\t\t\t *\n\t\t\t * @error markercollection-refresh-marker-not-exists\n\t\t\t */ throw new CKEditorError('markercollection-refresh-marker-not-exists', this);\n        }\n        const range = marker.getRange();\n        this.fire(`update:${markerName}`, marker, range, range, marker.getData());\n    }\n    /**\n\t * Returns iterator that iterates over all markers, which ranges contain given {@link module:engine/model/position~Position position}.\n\t */ *getMarkersAtPosition(position) {\n        for (const marker of this){\n            if (marker.getRange().containsPosition(position)) {\n                yield marker;\n            }\n        }\n    }\n    /**\n\t * Returns iterator that iterates over all markers, which intersects with given {@link module:engine/model/range~Range range}.\n\t */ *getMarkersIntersectingRange(range) {\n        for (const marker of this){\n            if (marker.getRange().getIntersection(range) !== null) {\n                yield marker;\n            }\n        }\n    }\n    /**\n\t * Destroys marker collection and all markers inside it.\n\t */ destroy() {\n        for (const marker of this._markers.values()){\n            this._destroyMarker(marker);\n        }\n        this._markers = null;\n        this.stopListening();\n    }\n    /**\n\t * Iterates over all markers that starts with given `prefix`.\n\t *\n\t * ```ts\n\t * const markerFooA = markersCollection._set( 'foo:a', rangeFooA );\n\t * const markerFooB = markersCollection._set( 'foo:b', rangeFooB );\n\t * const markerBarA = markersCollection._set( 'bar:a', rangeBarA );\n\t * const markerFooBarA = markersCollection._set( 'foobar:a', rangeFooBarA );\n\t * Array.from( markersCollection.getMarkersGroup( 'foo' ) ); // [ markerFooA, markerFooB ]\n\t * Array.from( markersCollection.getMarkersGroup( 'a' ) ); // []\n\t * ```\n\t */ *getMarkersGroup(prefix) {\n        for (const marker of this._markers.values()){\n            if (marker.name.startsWith(prefix + ':')) {\n                yield marker;\n            }\n        }\n    }\n    /**\n\t * Destroys the marker.\n\t */ _destroyMarker(marker) {\n        marker.stopListening();\n        marker._detachLiveRange();\n    }\n}\n/**\n * `Marker` is a continuous part of the model (like a range), is named and represents some kind of information about the\n * marked part of the model document. In contrary to {@link module:engine/model/node~Node nodes}, which are building blocks of\n * the model document tree, markers are not stored directly in the document tree but in the\n * {@link module:engine/model/model~Model#markers model markers' collection}. Still, they are document data, by giving\n * additional meaning to the part of a model document between marker start and marker end.\n *\n * In this sense, markers are similar to adding and converting attributes on nodes. The difference is that attribute is\n * connected with a given node (e.g. a character is bold no matter if it gets moved or content around it changes).\n * Markers on the other hand are continuous ranges and are characterized by their start and end position. This means that\n * any character in the marker is marked by the marker. For example, if a character is moved outside of marker it stops being\n * \"special\" and the marker is shrunk. Similarly, when a character is moved into the marker from other place in document\n * model, it starts being \"special\" and the marker is enlarged.\n *\n * Another upside of markers is that finding marked part of document is fast and easy. Using attributes to mark some nodes\n * and then trying to find that part of document would require traversing whole document tree. Marker gives instant access\n * to the range which it is marking at the moment.\n *\n * Markers are built from a name and a range.\n *\n * Range of the marker is updated automatically when document changes, using\n * {@link module:engine/model/liverange~LiveRange live range} mechanism.\n *\n * Name is used to group and identify markers. Names have to be unique, but markers can be grouped by\n * using common prefixes, separated with `:`, for example: `user:john` or `search:3`. That's useful in term of creating\n * namespaces for custom elements (e.g. comments, highlights). You can use this prefixes in\n * {@link module:engine/model/markercollection~MarkerCollection#event:update} listeners to listen on changes in a group of markers.\n * For instance: `model.markers.on( 'update:user', callback );` will be called whenever any `user:*` markers changes.\n *\n * There are two types of markers.\n *\n * 1. Markers managed directly, without using operations. They are added directly by {@link module:engine/model/writer~Writer}\n * to the {@link module:engine/model/markercollection~MarkerCollection} without any additional mechanism. They can be used\n * as bookmarks or visual markers. They are great for showing results of the find, or select link when the focus is in the input.\n *\n * 1. Markers managed using operations. These markers are also stored in {@link module:engine/model/markercollection~MarkerCollection}\n * but changes in these markers is managed the same way all other changes in the model structure - using operations.\n * Therefore, they are handled in the undo stack and synchronized between clients if the collaboration plugin is enabled.\n * This type of markers is useful for solutions like spell checking or comments.\n *\n * Both type of them should be added / updated by {@link module:engine/model/writer~Writer#addMarker}\n * and removed by {@link module:engine/model/writer~Writer#removeMarker} methods.\n *\n * ```ts\n * model.change( ( writer ) => {\n * \tconst marker = writer.addMarker( name, { range, usingOperation: true } );\n *\n * \t// ...\n *\n * \twriter.removeMarker( marker );\n * } );\n * ```\n *\n * See {@link module:engine/model/writer~Writer} to find more examples.\n *\n * Since markers need to track change in the document, for efficiency reasons, it is best to create and keep as little\n * markers as possible and remove them as soon as they are not needed anymore.\n *\n * Markers can be downcasted and upcasted.\n *\n * Markers downcast happens on {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker} and\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker} events.\n * Use {@link module:engine/conversion/downcasthelpers downcast converters} or attach a custom converter to mentioned events.\n * For {@link module:engine/controller/datacontroller~DataController data pipeline}, marker should be downcasted to an element.\n * Then, it can be upcasted back to a marker. Again, use {@link module:engine/conversion/upcasthelpers upcast converters} or\n * attach a custom converter to {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element}.\n *\n * `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.\n */ class Marker extends /* #__PURE__ */ EmitterMixin(TypeCheckable) {\n    /**\n\t * Marker's name.\n\t */ name;\n    /**\n\t * Flag indicates if the marker is managed using operations or not.\n\t *\n\t * @internal\n\t */ _managedUsingOperations;\n    /**\n\t * Specifies whether the marker affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t *\n\t * @internal\n\t */ _affectsData;\n    /**\n\t * Range marked by the marker.\n\t */ _liveRange;\n    /**\n\t * Creates a marker instance.\n\t *\n\t * @param name Marker name.\n\t * @param liveRange Range marked by the marker.\n\t * @param managedUsingOperations Specifies whether the marker is managed using operations.\n\t * @param affectsData Specifies whether the marker affects the data produced by the data pipeline (is persisted in the editor's data).\n\t */ constructor(name, liveRange, managedUsingOperations, affectsData){\n        super();\n        this.name = name;\n        this._liveRange = this._attachLiveRange(liveRange);\n        this._managedUsingOperations = managedUsingOperations;\n        this._affectsData = affectsData;\n    }\n    /**\n\t * A value indicating if the marker is managed using operations.\n\t * See {@link ~Marker marker class description} to learn more about marker types.\n\t * See {@link module:engine/model/writer~Writer#addMarker}.\n\t */ get managedUsingOperations() {\n        if (!this._liveRange) {\n            throw new CKEditorError('marker-destroyed', this);\n        }\n        return this._managedUsingOperations;\n    }\n    /**\n\t * A value indicating if the marker changes the data.\n\t */ get affectsData() {\n        if (!this._liveRange) {\n            throw new CKEditorError('marker-destroyed', this);\n        }\n        return this._affectsData;\n    }\n    /**\n\t * Returns the marker data (properties defining the marker).\n\t */ getData() {\n        return {\n            range: this.getRange(),\n            affectsData: this.affectsData,\n            managedUsingOperations: this.managedUsingOperations\n        };\n    }\n    /**\n\t * Returns current marker start position.\n\t */ getStart() {\n        if (!this._liveRange) {\n            throw new CKEditorError('marker-destroyed', this);\n        }\n        return this._liveRange.start.clone();\n    }\n    /**\n\t * Returns current marker end position.\n\t */ getEnd() {\n        if (!this._liveRange) {\n            throw new CKEditorError('marker-destroyed', this);\n        }\n        return this._liveRange.end.clone();\n    }\n    /**\n\t * Returns a range that represents the current state of the marker.\n\t *\n\t * Keep in mind that returned value is a {@link module:engine/model/range~Range Range}, not a\n\t * {@link module:engine/model/liverange~LiveRange LiveRange}. This means that it is up-to-date and relevant only\n\t * until next model document change. Do not store values returned by this method. Instead, store {@link ~Marker#name}\n\t * and get `Marker` instance from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection} every\n\t * time there is a need to read marker properties. This will guarantee that the marker has not been removed and\n\t * that it's data is up-to-date.\n\t */ getRange() {\n        if (!this._liveRange) {\n            throw new CKEditorError('marker-destroyed', this);\n        }\n        return this._liveRange.toRange();\n    }\n    /**\n\t * Binds new live range to the marker and detach the old one if is attached.\n\t *\n\t * @internal\n\t * @param liveRange Live range to attach\n\t * @returns Attached live range.\n\t */ _attachLiveRange(liveRange) {\n        if (this._liveRange) {\n            this._detachLiveRange();\n        }\n        // Delegating does not work with namespaces. Alternatively, we could delegate all events (using `*`).\n        liveRange.delegate('change:range').to(this);\n        liveRange.delegate('change:content').to(this);\n        this._liveRange = liveRange;\n        return liveRange;\n    }\n    /**\n\t * Unbinds and destroys currently attached live range.\n\t *\n\t * @internal\n\t */ _detachLiveRange() {\n        this._liveRange.stopDelegating('change:range', this);\n        this._liveRange.stopDelegating('change:content', this);\n        this._liveRange.detach();\n        this._liveRange = null;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nMarker.prototype.is = function(type) {\n    return type === 'marker' || type === 'model:marker';\n};\n /**\n * Cannot use a {@link module:engine/model/markercollection~MarkerCollection#destroy destroyed marker} instance.\n *\n * @error marker-destroyed\n */\n\n// @if CK_DEBUG_ENGINE // const ModelRange = require( '../range' ).default;\n/**\n * Operation to permanently remove node from detached root.\n * Note this operation is only a local operation and won't be send to the other clients.\n */ class DetachOperation extends Operation {\n    /**\n\t * Position before the first {@link module:engine/model/item~Item model item} to detach.\n\t */ sourcePosition;\n    /**\n\t * Offset size of moved range.\n\t */ howMany;\n    /**\n\t * Creates an insert operation.\n\t *\n\t * @param sourcePosition Position before the first {@link module:engine/model/item~Item model item} to move.\n\t * @param howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t * `sourcePosition` with offset shifted by `howMany`.\n\t */ constructor(sourcePosition, howMany){\n        super(null);\n        this.sourcePosition = sourcePosition.clone();\n        this.howMany = howMany;\n    }\n    /**\n\t * @inheritDoc\n\t */ get type() {\n        return 'detach';\n    }\n    /**\n\t * @inheritDoc\n\t */ get affectedSelectable() {\n        return null;\n    }\n    /**\n\t * @inheritDoc\n\t */ toJSON() {\n        const json = super.toJSON();\n        json.sourcePosition = this.sourcePosition.toJSON();\n        return json;\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _validate() {\n        if (this.sourcePosition.root.document) {\n            /**\n\t\t\t * Cannot detach document node.\n\t\t\t *\n\t\t\t * @error detach-operation-on-document-node\n\t\t\t */ throw new CKEditorError('detach-operation-on-document-node', this);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t * @internal\n\t */ _execute() {\n        _remove(Range._createFromPositionAndShift(this.sourcePosition, this.howMany));\n    }\n    /**\n\t * @inheritDoc\n\t */ static get className() {\n        return 'DetachOperation';\n    }\n}\n\n// @if CK_DEBUG_ENGINE // const { stringifyMap } = require( '../dev-utils/utils' );\n/**\n * DocumentFragment represents a part of model which does not have a common root but its top-level nodes\n * can be seen as siblings. In other words, it is a detached part of model tree, without a root.\n *\n * DocumentFragment has own {@link module:engine/model/markercollection~MarkerCollection}. Markers from this collection\n * will be set to the {@link module:engine/model/model~Model#markers model markers} by a\n * {@link module:engine/model/writer~Writer#insert} function.\n */ class DocumentFragment extends TypeCheckable {\n    /**\n\t * DocumentFragment static markers map. This is a list of names and {@link module:engine/model/range~Range ranges}\n\t * which will be set as Markers to {@link module:engine/model/model~Model#markers model markers collection}\n\t * when DocumentFragment will be inserted to the document.\n\t */ markers = new Map();\n    /**\n\t * List of nodes contained inside the document fragment.\n\t */ _children = new NodeList();\n    /**\n\t * Creates an empty `DocumentFragment`.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createDocumentFragment} method instead.\n\t *\n\t * @internal\n\t * @param children Nodes to be contained inside the `DocumentFragment`.\n\t */ constructor(children){\n        super();\n        if (children) {\n            this._insertChild(0, children);\n        }\n    }\n    /**\n\t * Returns an iterator that iterates over all nodes contained inside this document fragment.\n\t */ [Symbol.iterator]() {\n        return this.getChildren();\n    }\n    /**\n\t * Number of this document fragment's children.\n\t */ get childCount() {\n        return this._children.length;\n    }\n    /**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all of this document fragment's children.\n\t */ get maxOffset() {\n        return this._children.maxOffset;\n    }\n    /**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t */ get isEmpty() {\n        return this.childCount === 0;\n    }\n    /**\n\t * Artificial next sibling. Returns `null`. Added for compatibility reasons.\n\t */ get nextSibling() {\n        return null;\n    }\n    /**\n\t * Artificial previous sibling. Returns `null`. Added for compatibility reasons.\n\t */ get previousSibling() {\n        return null;\n    }\n    /**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t */ get root() {\n        return this;\n    }\n    /**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t */ get parent() {\n        return null;\n    }\n    /**\n\t * Artificial owner of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t */ get document() {\n        return null;\n    }\n    /**\n\t * Returns `false` as `DocumentFragment` by definition is not attached to a document. Added for compatibility reasons.\n\t */ isAttached() {\n        return false;\n    }\n    /**\n\t * Returns empty array. Added for compatibility reasons.\n\t */ getAncestors() {\n        return [];\n    }\n    /**\n\t * Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param index Index in this document fragment.\n\t * @returns Child node.\n\t */ getChild(index) {\n        return this._children.getNode(index);\n    }\n    /**\n\t * Gets the child at the given offset. Returns `null` if incorrect index was passed.\n\t *\n\t * @param offset Offset in this document fragment.\n\t * @returns Child node.\n\t */ getChildAtOffset(offset) {\n        return this._children.getNodeAtOffset(offset);\n    }\n    /**\n\t * Returns an iterator that iterates over all of this document fragment's children.\n\t */ getChildren() {\n        return this._children[Symbol.iterator]();\n    }\n    /**\n\t * Returns an index of the given child node. Returns `null` if given node is not a child of this document fragment.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's index.\n\t */ getChildIndex(node) {\n        return this._children.getNodeIndex(node);\n    }\n    /**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {@link module:engine/model/node~Node#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t * given node is not a child of this document fragment.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's starting offset.\n\t */ getChildStartOffset(node) {\n        return this._children.getNodeStartOffset(node);\n    }\n    /**\n\t * Returns path to a `DocumentFragment`, which is an empty array. Added for compatibility reasons.\n\t */ getPath() {\n        return [];\n    }\n    /**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t * ```ts\n\t * // <this>a<b>c</b></this>\n\t * this.getNodeByPath( [ 0 ] );     // -> \"a\"\n\t * this.getNodeByPath( [ 1 ] );     // -> <b>\n\t * this.getNodeByPath( [ 1, 0 ] );  // -> \"c\"\n\t * ```\n\t *\n\t * @param relativePath Path of the node to find, relative to this element.\n\t */ getNodeByPath(relativePath) {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n        let node = this;\n        for (const offset of relativePath){\n            node = node.getChildAtOffset(offset);\n        }\n        return node;\n    }\n    /**\n\t * Converts offset \"position\" to index \"position\".\n\t *\n\t * Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t * too high, returns index after last child.\n\t *\n\t * ```ts\n\t * const textNode = new Text( 'foo' );\n\t * const pElement = new Element( 'p' );\n\t * const docFrag = new DocumentFragment( [ textNode, pElement ] );\n\t * docFrag.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t * docFrag.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t * docFrag.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t * docFrag.offsetToIndex( 2 ); // Returns 0.\n\t * docFrag.offsetToIndex( 3 ); // Returns 1.\n\t * docFrag.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t * ```\n\t *\n\t * @param offset Offset to look for.\n\t * @returns Index of a node that occupies given offset.\n\t */ offsetToIndex(offset) {\n        return this._children.offsetToIndex(offset);\n    }\n    /**\n\t * Converts `DocumentFragment` instance to plain object and returns it.\n\t * Takes care of converting all of this document fragment's children.\n\t *\n\t * @returns `DocumentFragment` instance converted to plain object.\n\t */ toJSON() {\n        const json = [];\n        for (const node of this._children){\n            json.push(node.toJSON());\n        }\n        return json;\n    }\n    /**\n\t * Creates a `DocumentFragment` instance from given plain object (i.e. parsed JSON string).\n\t * Converts `DocumentFragment` children to proper nodes.\n\t *\n\t * @param json Plain object to be converted to `DocumentFragment`.\n\t * @returns `DocumentFragment` instance created using given plain object.\n\t */ static fromJSON(json) {\n        const children = [];\n        for (const child of json){\n            if (child.name) {\n                // If child has name property, it is an Element.\n                children.push(Element.fromJSON(child));\n            } else {\n                // Otherwise, it is a Text node.\n                children.push(Text.fromJSON(child));\n            }\n        }\n        return new DocumentFragment(children);\n    }\n    /**\n\t * {@link #_insertChild Inserts} one or more nodes at the end of this document fragment.\n\t *\n\t * @internal\n\t * @param items Items to be inserted.\n\t */ _appendChild(items) {\n        this._insertChild(this.childCount, items);\n    }\n    /**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this document fragment.\n\t *\n\t * @internal\n\t * @param index Index at which nodes should be inserted.\n\t * @param items Items to be inserted.\n\t */ _insertChild(index, items) {\n        const nodes = normalize(items);\n        for (const node of nodes){\n            // If node that is being added to this element is already inside another element, first remove it from the old parent.\n            if (node.parent !== null) {\n                node._remove();\n            }\n            node.parent = this;\n        }\n        this._children._insertNodes(index, nodes);\n    }\n    /**\n\t * Removes one or more nodes starting at the given index\n\t * and sets {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @internal\n\t * @param index Index of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns Array containing removed nodes.\n\t */ _removeChildren(index, howMany = 1) {\n        const nodes = this._children._removeNodes(index, howMany);\n        for (const node of nodes){\n            node.parent = null;\n        }\n        return nodes;\n    }\n}\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentFragment.prototype.is = function(type) {\n    return type === 'documentFragment' || type === 'model:documentFragment';\n};\n/**\n * Converts strings to Text and non-iterables to arrays.\n */ function normalize(nodes) {\n    // Separate condition because string is iterable.\n    if (typeof nodes == 'string') {\n        return [\n            new Text(nodes)\n        ];\n    }\n    if (!isIterable(nodes)) {\n        nodes = [\n            nodes\n        ];\n    }\n    // Array.from to enable .map() on non-arrays.\n    return Array.from(nodes).map((node)=>{\n        if (typeof node == 'string') {\n            return new Text(node);\n        }\n        if (node instanceof TextProxy) {\n            return new Text(node.data, node.getAttributes());\n        }\n        return node;\n    });\n}\n\n/**\n * The model can only be modified by using the writer. It should be used whenever you want to create a node, modify\n * child nodes, attributes or text, set the selection's position and its attributes.\n *\n * The instance of the writer is only available in the {@link module:engine/model/model~Model#change `change()`} or\n * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`}.\n *\n * ```ts\n * model.change( writer => {\n * \twriter.insertText( 'foo', paragraph, 'end' );\n * } );\n * ```\n *\n * Note that the writer should never be stored and used outside of the `change()` and\n * `enqueueChange()` blocks.\n *\n * Note that writer's methods do not check the {@link module:engine/model/schema~Schema}. It is possible\n * to create incorrect model structures by using the writer. Read more about in\n * {@glink framework/deep-dive/schema#who-checks-the-schema \"Who checks the schema?\"}.\n *\n * @see module:engine/model/model~Model#change\n * @see module:engine/model/model~Model#enqueueChange\n */ class Writer {\n    /**\n\t * Instance of the model on which this writer operates.\n\t */ model;\n    /**\n\t * The batch to which this writer will add changes.\n\t */ batch;\n    /**\n\t * Creates a writer instance.\n\t *\n\t * **Note:** It is not recommended to use it directly. Use {@link module:engine/model/model~Model#change `Model#change()`} or\n\t * {@link module:engine/model/model~Model#enqueueChange `Model#enqueueChange()`} instead.\n\t *\n\t * @internal\n\t */ constructor(model, batch){\n        this.model = model;\n        this.batch = batch;\n    }\n    /**\n\t * Creates a new {@link module:engine/model/text~Text text node}.\n\t *\n\t * ```ts\n\t * writer.createText( 'foo' );\n\t * writer.createText( 'foo', { bold: true } );\n\t * ```\n\t *\n\t * @param data Text data.\n\t * @param attributes Text attributes.\n\t * @returns {module:engine/model/text~Text} Created text node.\n\t */ createText(data, attributes) {\n        return new Text(data, attributes);\n    }\n    /**\n\t * Creates a new {@link module:engine/model/element~Element element}.\n\t *\n\t * ```ts\n\t * writer.createElement( 'paragraph' );\n\t * writer.createElement( 'paragraph', { alignment: 'center' } );\n\t * ```\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @returns Created element.\n\t */ createElement(name, attributes) {\n        return new Element(name, attributes);\n    }\n    /**\n\t * Creates a new {@link module:engine/model/documentfragment~DocumentFragment document fragment}.\n\t *\n\t * @returns Created document fragment.\n\t */ createDocumentFragment() {\n        return new DocumentFragment();\n    }\n    /**\n\t * Creates a copy of the element and returns it. Created element has the same name and attributes as the original element.\n\t * If clone is deep, the original element's children are also cloned. If not, then empty element is returned.\n\t *\n\t * @param element The element to clone.\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any child.\n\t */ cloneElement(element, deep = true) {\n        return element._clone(deep);\n    }\n    /**\n\t * Inserts item on given position.\n\t *\n\t * ```ts\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * writer.insert( paragraph, position );\n\t * ```\n\t *\n\t * Instead of using position you can use parent and offset:\n\t *\n\t * ```ts\n\t * const text = writer.createText( 'foo' );\n\t * writer.insert( text, paragraph, 5 );\n\t * ```\n\t *\n\t * You can also use `end` instead of the offset to insert at the end:\n\t *\n\t * ```ts\n\t * const text = writer.createText( 'foo' );\n\t * writer.insert( text, paragraph, 'end' );\n\t * ```\n\t *\n\t * Or insert before or after another element:\n\t *\n\t * ```ts\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * writer.insert( paragraph, anotherParagraph, 'after' );\n\t * ```\n\t *\n\t * These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * Note that if the item already has parent it will be removed from the previous parent.\n\t *\n\t * Note that you cannot re-insert a node from a document to a different document or a document fragment. In this case,\n\t * `model-writer-insert-forbidden-move` is thrown.\n\t *\n\t * If you want to move {@link module:engine/model/range~Range range} instead of an\n\t * {@link module:engine/model/item~Item item} use {@link module:engine/model/writer~Writer#move `Writer#move()`}.\n\t *\n\t * **Note:** For a paste-like content insertion mechanism see\n\t * {@link module:engine/model/model~Model#insertContent `model.insertContent()`}.\n\t *\n\t * @param item Item or document fragment to insert.\n\t * @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~Item model item}.\n\t */ insert(item, itemOrPosition, offset = 0) {\n        this._assertWriterUsedCorrectly();\n        if (item instanceof Text && item.data == '') {\n            return;\n        }\n        const position = Position._createAt(itemOrPosition, offset);\n        // If item has a parent already.\n        if (item.parent) {\n            // We need to check if item is going to be inserted within the same document.\n            if (isSameTree(item.root, position.root)) {\n                // If it's we just need to move it.\n                this.move(Range._createOn(item), position);\n                return;\n            } else {\n                if (item.root.document) {\n                    /**\n\t\t\t\t\t * Cannot move a node from a document to a different tree.\n\t\t\t\t\t * It is forbidden to move a node that was already in a document outside of it.\n\t\t\t\t\t *\n\t\t\t\t\t * @error model-writer-insert-forbidden-move\n\t\t\t\t\t */ throw new CKEditorError('model-writer-insert-forbidden-move', this);\n                } else {\n                    // Move between two different document fragments or from document fragment to a document is possible.\n                    // In that case, remove the item from it's original parent.\n                    this.remove(item);\n                }\n            }\n        }\n        const version = position.root.document ? position.root.document.version : null;\n        const insert = new InsertOperation(position, item, version);\n        if (item instanceof Text) {\n            insert.shouldReceiveAttributes = true;\n        }\n        this.batch.addOperation(insert);\n        this.model.applyOperation(insert);\n        // When element is a DocumentFragment we need to move its markers to Document#markers.\n        if (item instanceof DocumentFragment) {\n            for (const [markerName, markerRange] of item.markers){\n                // We need to migrate marker range from DocumentFragment to Document.\n                const rangeRootPosition = Position._createAt(markerRange.root, 0);\n                const range = new Range(markerRange.start._getCombined(rangeRootPosition, position), markerRange.end._getCombined(rangeRootPosition, position));\n                const options = {\n                    range,\n                    usingOperation: true,\n                    affectsData: true\n                };\n                if (this.model.markers.has(markerName)) {\n                    this.updateMarker(markerName, options);\n                } else {\n                    this.addMarker(markerName, options);\n                }\n            }\n        }\n    }\n    insertText(text, attributes, itemOrPosition, offset// Too complicated when not using `any`.\n    ) {\n        if (attributes instanceof DocumentFragment || attributes instanceof Element || attributes instanceof Position) {\n            this.insert(this.createText(text), attributes, itemOrPosition);\n        } else {\n            this.insert(this.createText(text, attributes), itemOrPosition, offset);\n        }\n    }\n    insertElement(name, attributes, itemOrPositionOrOffset, offset// Too complicated when not using `any`.\n    ) {\n        if (attributes instanceof DocumentFragment || attributes instanceof Element || attributes instanceof Position) {\n            this.insert(this.createElement(name), attributes, itemOrPositionOrOffset);\n        } else {\n            this.insert(this.createElement(name, attributes), itemOrPositionOrOffset, offset);\n        }\n    }\n    /**\n\t * Inserts item at the end of the given parent.\n\t *\n\t * ```ts\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * writer.append( paragraph, root );\n\t * ```\n\t *\n\t * Note that if the item already has parent it will be removed from the previous parent.\n\t *\n\t * If you want to move {@link module:engine/model/range~Range range} instead of an\n\t * {@link module:engine/model/item~Item item} use {@link module:engine/model/writer~Writer#move `Writer#move()`}.\n\t *\n\t * @param item Item or document fragment to insert.\n\t */ append(item, parent) {\n        this.insert(item, parent, 'end');\n    }\n    appendText(text, attributes, parent) {\n        if (attributes instanceof DocumentFragment || attributes instanceof Element) {\n            this.insert(this.createText(text), attributes, 'end');\n        } else {\n            this.insert(this.createText(text, attributes), parent, 'end');\n        }\n    }\n    appendElement(name, attributes, parent) {\n        if (attributes instanceof DocumentFragment || attributes instanceof Element) {\n            this.insert(this.createElement(name), attributes, 'end');\n        } else {\n            this.insert(this.createElement(name, attributes), parent, 'end');\n        }\n    }\n    /**\n\t * Sets value of the attribute with given key on a {@link module:engine/model/item~Item model item}\n\t * or on a {@link module:engine/model/range~Range range}.\n\t *\n\t * @param key Attribute key.\n\t * @param value Attribute new value.\n\t * @param itemOrRange Model item or range on which the attribute will be set.\n\t */ setAttribute(key, value, itemOrRange) {\n        this._assertWriterUsedCorrectly();\n        if (itemOrRange instanceof Range) {\n            const ranges = itemOrRange.getMinimalFlatRanges();\n            for (const range of ranges){\n                setAttributeOnRange(this, key, value, range);\n            }\n        } else {\n            setAttributeOnItem(this, key, value, itemOrRange);\n        }\n    }\n    /**\n\t * Sets values of attributes on a {@link module:engine/model/item~Item model item}\n\t * or on a {@link module:engine/model/range~Range range}.\n\t *\n\t * ```ts\n\t * writer.setAttributes( {\n\t * \tbold: true,\n\t * \titalic: true\n\t * }, range );\n\t * ```\n\t *\n\t * @param attributes Attributes keys and values.\n\t * @param itemOrRange Model item or range on which the attributes will be set.\n\t */ setAttributes(attributes, itemOrRange) {\n        for (const [key, val] of toMap(attributes)){\n            this.setAttribute(key, val, itemOrRange);\n        }\n    }\n    /**\n\t * Removes an attribute with given key from a {@link module:engine/model/item~Item model item}\n\t * or from a {@link module:engine/model/range~Range range}.\n\t *\n\t * @param key Attribute key.\n\t * @param itemOrRange Model item or range from which the attribute will be removed.\n\t */ removeAttribute(key, itemOrRange) {\n        this._assertWriterUsedCorrectly();\n        if (itemOrRange instanceof Range) {\n            const ranges = itemOrRange.getMinimalFlatRanges();\n            for (const range of ranges){\n                setAttributeOnRange(this, key, null, range);\n            }\n        } else {\n            setAttributeOnItem(this, key, null, itemOrRange);\n        }\n    }\n    /**\n\t * Removes all attributes from all elements in the range or from the given item.\n\t *\n\t * @param itemOrRange Model item or range from which all attributes will be removed.\n\t */ clearAttributes(itemOrRange) {\n        this._assertWriterUsedCorrectly();\n        const removeAttributesFromItem = (item)=>{\n            for (const attribute of item.getAttributeKeys()){\n                this.removeAttribute(attribute, item);\n            }\n        };\n        if (!(itemOrRange instanceof Range)) {\n            removeAttributesFromItem(itemOrRange);\n        } else {\n            for (const item of itemOrRange.getItems()){\n                removeAttributesFromItem(item);\n            }\n        }\n    }\n    /**\n\t * Moves all items in the source range to the target position.\n\t *\n\t * ```ts\n\t * writer.move( sourceRange, targetPosition );\n\t * ```\n\t *\n\t * Instead of the target position you can use parent and offset or define that range should be moved to the end\n\t * or before or after chosen item:\n\t *\n\t * ```ts\n\t * // Moves all items in the range to the paragraph at offset 5:\n\t * writer.move( sourceRange, paragraph, 5 );\n\t * // Moves all items in the range to the end of a blockquote:\n\t * writer.move( sourceRange, blockquote, 'end' );\n\t * // Moves all items in the range to a position after an image:\n\t * writer.move( sourceRange, image, 'after' );\n\t * ```\n\t *\n\t * These parameters work the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * Note that items can be moved only within the same tree. It means that you can move items within the same root\n\t * (element or document fragment) or between {@link module:engine/model/document~Document#roots documents roots},\n\t * but you can not move items from document fragment to the document or from one detached element to another. Use\n\t * {@link module:engine/model/writer~Writer#insert} in such cases.\n\t *\n\t * @param range Source range.\n\t * @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~Item model item}.\n\t */ move(range, itemOrPosition, offset) {\n        this._assertWriterUsedCorrectly();\n        if (!(range instanceof Range)) {\n            /**\n\t\t\t * Invalid range to move.\n\t\t\t *\n\t\t\t * @error writer-move-invalid-range\n\t\t\t */ throw new CKEditorError('writer-move-invalid-range', this);\n        }\n        if (!range.isFlat) {\n            /**\n\t\t\t * Range to move is not flat.\n\t\t\t *\n\t\t\t * @error writer-move-range-not-flat\n\t\t\t */ throw new CKEditorError('writer-move-range-not-flat', this);\n        }\n        const position = Position._createAt(itemOrPosition, offset);\n        // Do not move anything if the move target is same as moved range start.\n        if (position.isEqual(range.start)) {\n            return;\n        }\n        // If part of the marker is removed, create additional marker operation for undo purposes.\n        this._addOperationForAffectedMarkers('move', range);\n        if (!isSameTree(range.root, position.root)) {\n            /**\n\t\t\t * Range is going to be moved within not the same document. Please use\n\t\t\t * {@link module:engine/model/writer~Writer#insert insert} instead.\n\t\t\t *\n\t\t\t * @error writer-move-different-document\n\t\t\t */ throw new CKEditorError('writer-move-different-document', this);\n        }\n        const version = range.root.document ? range.root.document.version : null;\n        const operation = new MoveOperation(range.start, range.end.offset - range.start.offset, position, version);\n        this.batch.addOperation(operation);\n        this.model.applyOperation(operation);\n    }\n    /**\n\t * Removes given model {@link module:engine/model/item~Item item} or {@link module:engine/model/range~Range range}.\n\t *\n\t * @param itemOrRange Model item or range to remove.\n\t */ remove(itemOrRange) {\n        this._assertWriterUsedCorrectly();\n        const rangeToRemove = itemOrRange instanceof Range ? itemOrRange : Range._createOn(itemOrRange);\n        const ranges = rangeToRemove.getMinimalFlatRanges().reverse();\n        for (const flat of ranges){\n            // If part of the marker is removed, create additional marker operation for undo purposes.\n            this._addOperationForAffectedMarkers('move', flat);\n            applyRemoveOperation(flat.start, flat.end.offset - flat.start.offset, this.batch, this.model);\n        }\n    }\n    /**\n\t * Merges two siblings at the given position.\n\t *\n\t * Node before and after the position have to be an element. Otherwise `writer-merge-no-element-before` or\n\t * `writer-merge-no-element-after` error will be thrown.\n\t *\n\t * @param position Position between merged elements.\n\t */ merge(position) {\n        this._assertWriterUsedCorrectly();\n        const nodeBefore = position.nodeBefore;\n        const nodeAfter = position.nodeAfter;\n        // If part of the marker is removed, create additional marker operation for undo purposes.\n        this._addOperationForAffectedMarkers('merge', position);\n        if (!(nodeBefore instanceof Element)) {\n            /**\n\t\t\t * Node before merge position must be an element.\n\t\t\t *\n\t\t\t * @error writer-merge-no-element-before\n\t\t\t */ throw new CKEditorError('writer-merge-no-element-before', this);\n        }\n        if (!(nodeAfter instanceof Element)) {\n            /**\n\t\t\t * Node after merge position must be an element.\n\t\t\t *\n\t\t\t * @error writer-merge-no-element-after\n\t\t\t */ throw new CKEditorError('writer-merge-no-element-after', this);\n        }\n        if (!position.root.document) {\n            this._mergeDetached(position);\n        } else {\n            this._merge(position);\n        }\n    }\n    /**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionFromPath `Model#createPositionFromPath()`}.\n\t *\n\t * @param root Root of the position.\n\t * @param path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param stickiness Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */ createPositionFromPath(root, path, stickiness) {\n        return this.model.createPositionFromPath(root, path, stickiness);\n    }\n    /**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}.\n\t *\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */ createPositionAt(itemOrPosition, offset) {\n        return this.model.createPositionAt(itemOrPosition, offset);\n    }\n    /**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionAfter `Model#createPositionAfter()`}.\n\t *\n\t * @param item Item after which the position should be placed.\n\t */ createPositionAfter(item) {\n        return this.model.createPositionAfter(item);\n    }\n    /**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionBefore `Model#createPositionBefore()`}.\n\t *\n\t * @param item Item after which the position should be placed.\n\t */ createPositionBefore(item) {\n        return this.model.createPositionBefore(item);\n    }\n    /**\n\t * Shortcut for {@link module:engine/model/model~Model#createRange `Model#createRange()`}.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */ createRange(start, end) {\n        return this.model.createRange(start, end);\n    }\n    /**\n\t * Shortcut for {@link module:engine/model/model~Model#createRangeIn `Model#createRangeIn()`}.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */ createRangeIn(element) {\n        return this.model.createRangeIn(element);\n    }\n    /**\n\t * Shortcut for {@link module:engine/model/model~Model#createRangeOn `Model#createRangeOn()`}.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */ createRangeOn(element) {\n        return this.model.createRangeOn(element);\n    }\n    createSelection(...args) {\n        return this.model.createSelection(...args);\n    }\n    /**\n\t * Performs merge action in a detached tree.\n\t *\n\t * @param position Position between merged elements.\n\t */ _mergeDetached(position) {\n        const nodeBefore = position.nodeBefore;\n        const nodeAfter = position.nodeAfter;\n        this.move(Range._createIn(nodeAfter), Position._createAt(nodeBefore, 'end'));\n        this.remove(nodeAfter);\n    }\n    /**\n\t * Performs merge action in a non-detached tree.\n\t *\n\t * @param position Position between merged elements.\n\t */ _merge(position) {\n        const targetPosition = Position._createAt(position.nodeBefore, 'end');\n        const sourcePosition = Position._createAt(position.nodeAfter, 0);\n        const graveyard = position.root.document.graveyard;\n        const graveyardPosition = new Position(graveyard, [\n            0\n        ]);\n        const version = position.root.document.version;\n        const merge = new MergeOperation(sourcePosition, position.nodeAfter.maxOffset, targetPosition, graveyardPosition, version);\n        this.batch.addOperation(merge);\n        this.model.applyOperation(merge);\n    }\n    /**\n\t * Renames the given element.\n\t *\n\t * @param element The element to rename.\n\t * @param newName New element name.\n\t */ rename(element, newName) {\n        this._assertWriterUsedCorrectly();\n        if (!(element instanceof Element)) {\n            /**\n\t\t\t * Trying to rename an object which is not an instance of Element.\n\t\t\t *\n\t\t\t * @error writer-rename-not-element-instance\n\t\t\t */ throw new CKEditorError('writer-rename-not-element-instance', this);\n        }\n        const version = element.root.document ? element.root.document.version : null;\n        const renameOperation = new RenameOperation(Position._createBefore(element), element.name, newName, version);\n        this.batch.addOperation(renameOperation);\n        this.model.applyOperation(renameOperation);\n    }\n    /**\n\t * Splits elements starting from the given position and going to the top of the model tree as long as given\n\t * `limitElement` is reached. When `limitElement` is not defined then only the parent of the given position will be split.\n\t *\n\t * The element needs to have a parent. It cannot be a root element nor a document fragment.\n\t * The `writer-split-element-no-parent` error will be thrown if you try to split an element with no parent.\n\t *\n\t * @param position Position of split.\n\t * @param limitElement Stop splitting when this element will be reached.\n\t * @returns Split result with properties:\n\t * * `position` - Position between split elements.\n\t * * `range` - Range that stars from the end of the first split element and ends at the beginning of the first copy element.\n\t */ split(position, limitElement) {\n        this._assertWriterUsedCorrectly();\n        let splitElement = position.parent;\n        if (!splitElement.parent) {\n            /**\n\t\t\t * Element with no parent can not be split.\n\t\t\t *\n\t\t\t * @error writer-split-element-no-parent\n\t\t\t */ throw new CKEditorError('writer-split-element-no-parent', this);\n        }\n        // When limit element is not defined lets set splitElement parent as limit.\n        if (!limitElement) {\n            limitElement = splitElement.parent;\n        }\n        if (!position.parent.getAncestors({\n            includeSelf: true\n        }).includes(limitElement)) {\n            /**\n\t\t\t * Limit element is not a position ancestor.\n\t\t\t *\n\t\t\t * @error writer-split-invalid-limit-element\n\t\t\t */ throw new CKEditorError('writer-split-invalid-limit-element', this);\n        }\n        // We need to cache elements that will be created as a result of the first split because\n        // we need to create a range from the end of the first split element to the beginning of the\n        // first copy element. This should be handled by LiveRange but it doesn't work on detached nodes.\n        let firstSplitElement;\n        let firstCopyElement;\n        do {\n            const version = splitElement.root.document ? splitElement.root.document.version : null;\n            const howMany = splitElement.maxOffset - position.offset;\n            const insertionPosition = SplitOperation.getInsertionPosition(position);\n            const split = new SplitOperation(position, howMany, insertionPosition, null, version);\n            this.batch.addOperation(split);\n            this.model.applyOperation(split);\n            // Cache result of the first split.\n            if (!firstSplitElement && !firstCopyElement) {\n                firstSplitElement = splitElement;\n                firstCopyElement = position.parent.nextSibling;\n            }\n            position = this.createPositionAfter(position.parent);\n            splitElement = position.parent;\n        }while (splitElement !== limitElement)\n        return {\n            position,\n            range: new Range(Position._createAt(firstSplitElement, 'end'), Position._createAt(firstCopyElement, 0))\n        };\n    }\n    /**\n\t * Wraps the given range with the given element or with a new element (if a string was passed).\n\t *\n\t * **Note:** range to wrap should be a \"flat range\" (see {@link module:engine/model/range~Range#isFlat `Range#isFlat`}).\n\t * If not, an error will be thrown.\n\t *\n\t * @param range Range to wrap.\n\t * @param elementOrString Element or name of element to wrap the range with.\n\t */ wrap(range, elementOrString) {\n        this._assertWriterUsedCorrectly();\n        if (!range.isFlat) {\n            /**\n\t\t\t * Range to wrap is not flat.\n\t\t\t *\n\t\t\t * @error writer-wrap-range-not-flat\n\t\t\t */ throw new CKEditorError('writer-wrap-range-not-flat', this);\n        }\n        const element = elementOrString instanceof Element ? elementOrString : new Element(elementOrString);\n        if (element.childCount > 0) {\n            /**\n\t\t\t * Element to wrap with is not empty.\n\t\t\t *\n\t\t\t * @error writer-wrap-element-not-empty\n\t\t\t */ throw new CKEditorError('writer-wrap-element-not-empty', this);\n        }\n        if (element.parent !== null) {\n            /**\n\t\t\t * Element to wrap with is already attached to a tree model.\n\t\t\t *\n\t\t\t * @error writer-wrap-element-attached\n\t\t\t */ throw new CKEditorError('writer-wrap-element-attached', this);\n        }\n        this.insert(element, range.start);\n        // Shift the range-to-wrap because we just inserted an element before that range.\n        const shiftedRange = new Range(range.start.getShiftedBy(1), range.end.getShiftedBy(1));\n        this.move(shiftedRange, Position._createAt(element, 0));\n    }\n    /**\n\t * Unwraps children of the given element – all its children are moved before it and then the element is removed.\n\t * Throws error if you try to unwrap an element which does not have a parent.\n\t *\n\t * @param element Element to unwrap.\n\t */ unwrap(element) {\n        this._assertWriterUsedCorrectly();\n        if (element.parent === null) {\n            /**\n\t\t\t * Trying to unwrap an element which has no parent.\n\t\t\t *\n\t\t\t * @error writer-unwrap-element-no-parent\n\t\t\t */ throw new CKEditorError('writer-unwrap-element-no-parent', this);\n        }\n        this.move(Range._createIn(element), this.createPositionAfter(element));\n        this.remove(element);\n    }\n    /**\n\t * Adds a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t * changes in the document and updates its range automatically, when model tree changes.\n\t *\n\t * As the first parameter you can set marker name.\n\t *\n\t * The required `options.usingOperation` parameter lets you decide if the marker should be managed by operations or not. See\n\t * {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t * markers managed by operations and not-managed by operations.\n\t *\n\t * The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t * `true` when the marker change changes the data returned by the\n\t * {@link module:core/editor/editor~Editor#getData `editor.getData()`} method.\n\t * When set to `true` it fires the {@link module:engine/model/document~Document#event:change:data `change:data`} event.\n\t * When set to `false` it fires the {@link module:engine/model/document~Document#event:change `change`} event.\n\t *\n\t * Create marker directly base on marker's name:\n\t *\n\t * ```ts\n\t * addMarker( markerName, { range, usingOperation: false } );\n\t * ```\n\t *\n\t * Create marker using operation:\n\t *\n\t * ```ts\n\t * addMarker( markerName, { range, usingOperation: true } );\n\t * ```\n\t *\n\t * Create marker that affects the editor data:\n\t *\n\t * ```ts\n\t * addMarker( markerName, { range, usingOperation: false, affectsData: true } );\n\t * ```\n\t *\n\t * Note: For efficiency reasons, it's best to create and keep as little markers as possible.\n\t *\n\t * @see module:engine/model/markercollection~Marker\n\t * @param name Name of a marker to create - must be unique.\n\t * @param options.usingOperation Flag indicating that the marker should be added by MarkerOperation.\n\t * See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t * @param options.range Marker range.\n\t * @param options.affectsData Flag indicating that the marker changes the editor data.\n\t * @returns Marker that was set.\n\t */ addMarker(name, options) {\n        this._assertWriterUsedCorrectly();\n        if (!options || typeof options.usingOperation != 'boolean') {\n            /**\n\t\t\t * The `options.usingOperation` parameter is required when adding a new marker.\n\t\t\t *\n\t\t\t * @error writer-addmarker-no-usingoperation\n\t\t\t */ throw new CKEditorError('writer-addmarker-no-usingoperation', this);\n        }\n        const usingOperation = options.usingOperation;\n        const range = options.range;\n        const affectsData = options.affectsData === undefined ? false : options.affectsData;\n        if (this.model.markers.has(name)) {\n            /**\n\t\t\t * Marker with provided name already exists.\n\t\t\t *\n\t\t\t * @error writer-addmarker-marker-exists\n\t\t\t */ throw new CKEditorError('writer-addmarker-marker-exists', this);\n        }\n        if (!range) {\n            /**\n\t\t\t * Range parameter is required when adding a new marker.\n\t\t\t *\n\t\t\t * @error writer-addmarker-no-range\n\t\t\t */ throw new CKEditorError('writer-addmarker-no-range', this);\n        }\n        if (!usingOperation) {\n            return this.model.markers._set(name, range, usingOperation, affectsData);\n        }\n        applyMarkerOperation(this, name, null, range, affectsData);\n        return this.model.markers.get(name);\n    }\n    /**\n\t * Adds, updates or refreshes a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t * changes in the document and updates its range automatically, when model tree changes. Still, it is possible to change the\n\t * marker's range directly using this method.\n\t *\n\t * As the first parameter you can set marker name or instance. If none of them is provided, new marker, with a unique\n\t * name is created and returned.\n\t *\n\t * **Note**: If you want to change the {@link module:engine/view/element~Element view element} of the marker while its data in the model\n\t * remains the same, use the dedicated {@link module:engine/controller/editingcontroller~EditingController#reconvertMarker} method.\n\t *\n\t * The `options.usingOperation` parameter lets you change if the marker should be managed by operations or not. See\n\t * {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t * markers managed by operations and not-managed by operations. It is possible to change this option for an existing marker.\n\t *\n\t * The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t * `true` when the marker change changes the data returned by\n\t * the {@link module:core/editor/editor~Editor#getData `editor.getData()`} method.\n\t * When set to `true` it fires the {@link module:engine/model/document~Document#event:change:data `change:data`} event.\n\t * When set to `false` it fires the {@link module:engine/model/document~Document#event:change `change`} event.\n\t *\n\t * Update marker directly base on marker's name:\n\t *\n\t * ```ts\n\t * updateMarker( markerName, { range } );\n\t * ```\n\t *\n\t * Update marker using operation:\n\t *\n\t * ```ts\n\t * updateMarker( marker, { range, usingOperation: true } );\n\t * updateMarker( markerName, { range, usingOperation: true } );\n\t * ```\n\t *\n\t * Change marker's option (start using operations to manage it):\n\t *\n\t * ```ts\n\t * updateMarker( marker, { usingOperation: true } );\n\t * ```\n\t *\n\t * Change marker's option (inform the engine, that the marker does not affect the data anymore):\n\t *\n\t * ```ts\n\t * updateMarker( markerName, { affectsData: false } );\n\t * ```\n\t *\n\t * @see module:engine/model/markercollection~Marker\n\t * @param markerOrName Name of a marker to update, or a marker instance.\n\t * @param options If options object is not defined then marker will be refreshed by triggering\n\t * downcast conversion for this marker with the same data.\n\t * @param options.range Marker range to update.\n\t * @param options.usingOperation Flag indicated whether the marker should be added by MarkerOperation.\n\t * See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t * @param options.affectsData Flag indicating that the marker changes the editor data.\n\t */ updateMarker(markerOrName, options) {\n        this._assertWriterUsedCorrectly();\n        const markerName = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n        const currentMarker = this.model.markers.get(markerName);\n        if (!currentMarker) {\n            /**\n\t\t\t * Marker with provided name does not exist and will not be updated.\n\t\t\t *\n\t\t\t * @error writer-updatemarker-marker-not-exists\n\t\t\t */ throw new CKEditorError('writer-updatemarker-marker-not-exists', this);\n        }\n        if (!options) {\n            /**\n\t\t\t * The usage of `writer.updateMarker()` only to reconvert (refresh) a\n\t\t\t * {@link module:engine/model/markercollection~Marker model marker} was deprecated and may not work in the future.\n\t\t\t * Please update your code to use\n\t\t\t * {@link module:engine/controller/editingcontroller~EditingController#reconvertMarker `editor.editing.reconvertMarker()`}\n\t\t\t * instead.\n\t\t\t *\n\t\t\t * @error writer-updatemarker-reconvert-using-editingcontroller\n\t\t\t * @param markerName The name of the updated marker.\n\t\t\t */ logWarning('writer-updatemarker-reconvert-using-editingcontroller', {\n                markerName\n            });\n            this.model.markers._refresh(currentMarker);\n            return;\n        }\n        const hasUsingOperationDefined = typeof options.usingOperation == 'boolean';\n        const affectsDataDefined = typeof options.affectsData == 'boolean';\n        // Use previously defined marker's affectsData if the property is not provided.\n        const affectsData = affectsDataDefined ? options.affectsData : currentMarker.affectsData;\n        if (!hasUsingOperationDefined && !options.range && !affectsDataDefined) {\n            /**\n\t\t\t * One of the options is required - provide range, usingOperations or affectsData.\n\t\t\t *\n\t\t\t * @error writer-updatemarker-wrong-options\n\t\t\t */ throw new CKEditorError('writer-updatemarker-wrong-options', this);\n        }\n        const currentRange = currentMarker.getRange();\n        const updatedRange = options.range ? options.range : currentRange;\n        if (hasUsingOperationDefined && options.usingOperation !== currentMarker.managedUsingOperations) {\n            // The marker type is changed so it's necessary to create proper operations.\n            if (options.usingOperation) {\n                // If marker changes to a managed one treat this as synchronizing existing marker.\n                // Create `MarkerOperation` with `oldRange` set to `null`, so reverse operation will remove the marker.\n                applyMarkerOperation(this, markerName, null, updatedRange, affectsData);\n            } else {\n                // If marker changes to a marker that do not use operations then we need to create additional operation\n                // that removes that marker first.\n                applyMarkerOperation(this, markerName, currentRange, null, affectsData);\n                // Although not managed the marker itself should stay in model and its range should be preserver or changed to passed range.\n                this.model.markers._set(markerName, updatedRange, undefined, affectsData);\n            }\n            return;\n        }\n        // Marker's type doesn't change so update it accordingly.\n        if (currentMarker.managedUsingOperations) {\n            applyMarkerOperation(this, markerName, currentRange, updatedRange, affectsData);\n        } else {\n            this.model.markers._set(markerName, updatedRange, undefined, affectsData);\n        }\n    }\n    /**\n\t * Removes given {@link module:engine/model/markercollection~Marker marker} or marker with given name.\n\t * The marker is removed accordingly to how it has been created, so if the marker was created using operation,\n\t * it will be destroyed using operation.\n\t *\n\t * @param markerOrName Marker or marker name to remove.\n\t */ removeMarker(markerOrName) {\n        this._assertWriterUsedCorrectly();\n        const name = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n        if (!this.model.markers.has(name)) {\n            /**\n\t\t\t * Trying to remove marker which does not exist.\n\t\t\t *\n\t\t\t * @error writer-removemarker-no-marker\n\t\t\t */ throw new CKEditorError('writer-removemarker-no-marker', this);\n        }\n        const marker = this.model.markers.get(name);\n        if (!marker.managedUsingOperations) {\n            this.model.markers._remove(name);\n            return;\n        }\n        const oldRange = marker.getRange();\n        applyMarkerOperation(this, name, oldRange, null, marker.affectsData);\n    }\n    /**\n\t * Adds a new root to the document (or re-attaches a {@link #detachRoot detached root}).\n\t *\n\t * Throws an error, if trying to add a root that is already added and attached.\n\t *\n\t * @param rootName Name of the added root.\n\t * @param elementName The element name. Defaults to `'$root'` which also has some basic schema defined\n\t * (e.g. `$block` elements are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.\n\t * @returns The added root element.\n\t */ addRoot(rootName, elementName = '$root') {\n        this._assertWriterUsedCorrectly();\n        const root = this.model.document.getRoot(rootName);\n        if (root && root.isAttached()) {\n            /**\n\t\t\t * Root with provided name already exists and is attached.\n\t\t\t *\n\t\t\t * @error writer-addroot-root-exists\n\t\t\t */ throw new CKEditorError('writer-addroot-root-exists', this);\n        }\n        const document = this.model.document;\n        const operation = new RootOperation(rootName, elementName, true, document, document.version);\n        this.batch.addOperation(operation);\n        this.model.applyOperation(operation);\n        return this.model.document.getRoot(rootName);\n    }\n    /**\n\t * Detaches the root from the document.\n\t *\n\t * All content and markers are removed from the root upon detaching. New content and new markers cannot be added to the root, as long\n\t * as it is detached.\n\t *\n\t * A root cannot be fully removed from the document, it can be only detached. A root is permanently removed only after you\n\t * re-initialize the editor and do not specify the root in the initial data.\n\t *\n\t * A detached root can be re-attached using {@link #addRoot}.\n\t *\n\t * Throws an error if the root does not exist or the root is already detached.\n\t *\n\t * @param rootOrName Name of the detached root.\n\t */ detachRoot(rootOrName) {\n        this._assertWriterUsedCorrectly();\n        const root = typeof rootOrName == 'string' ? this.model.document.getRoot(rootOrName) : rootOrName;\n        if (!root || !root.isAttached()) {\n            /**\n\t\t\t * Root with provided name does not exist or is already detached.\n\t\t\t *\n\t\t\t * @error writer-detachroot-no-root\n\t\t\t */ throw new CKEditorError('writer-detachroot-no-root', this);\n        }\n        // First, remove all markers from the root. It is better to do it before removing stuff for undo purposes.\n        // However, looking through all the markers may not be the best performance wise. But there's no better solution for now.\n        for (const marker of this.model.markers){\n            if (marker.getRange().root === root) {\n                this.removeMarker(marker);\n            }\n        }\n        // Remove all attributes from the root.\n        for (const key of root.getAttributeKeys()){\n            this.removeAttribute(key, root);\n        }\n        // Remove all contents of the root.\n        this.remove(this.createRangeIn(root));\n        // Finally, detach the root.\n        const document = this.model.document;\n        const operation = new RootOperation(root.rootName, root.name, false, document, document.version);\n        this.batch.addOperation(operation);\n        this.model.applyOperation(operation);\n    }\n    setSelection(...args) {\n        this._assertWriterUsedCorrectly();\n        this.model.document.selection._setTo(...args);\n    }\n    /**\n\t * Moves {@link module:engine/model/documentselection~DocumentSelection#focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link #createPositionAt `writer.createPositionAt()`} parameters.\n\t *\n\t * @param itemOrPosition\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */ setSelectionFocus(itemOrPosition, offset) {\n        this._assertWriterUsedCorrectly();\n        this.model.document.selection._setFocus(itemOrPosition, offset);\n    }\n    setSelectionAttribute(keyOrObjectOrIterable, value) {\n        this._assertWriterUsedCorrectly();\n        if (typeof keyOrObjectOrIterable === 'string') {\n            this._setSelectionAttribute(keyOrObjectOrIterable, value);\n        } else {\n            for (const [key, value] of toMap(keyOrObjectOrIterable)){\n                this._setSelectionAttribute(key, value);\n            }\n        }\n    }\n    /**\n\t * Removes attribute(s) with given key(s) from the selection.\n\t *\n\t * Remove one attribute:\n\t *\n\t * ```ts\n\t * writer.removeSelectionAttribute( 'italic' );\n\t * ```\n\t *\n\t * Remove multiple attributes:\n\t *\n\t * ```ts\n\t * writer.removeSelectionAttribute( [ 'italic', 'bold' ] );\n\t * ```\n\t *\n\t * @param keyOrIterableOfKeys Key of the attribute to remove or an iterable of attribute keys to remove.\n\t */ removeSelectionAttribute(keyOrIterableOfKeys) {\n        this._assertWriterUsedCorrectly();\n        if (typeof keyOrIterableOfKeys === 'string') {\n            this._removeSelectionAttribute(keyOrIterableOfKeys);\n        } else {\n            for (const key of keyOrIterableOfKeys){\n                this._removeSelectionAttribute(key);\n            }\n        }\n    }\n    /**\n\t * Temporarily changes the {@link module:engine/model/documentselection~DocumentSelection#isGravityOverridden gravity}\n\t * of the selection from left to right.\n\t *\n\t * The gravity defines from which direction the selection inherits its attributes. If it's the default left gravity,\n\t * then the selection (after being moved by the user) inherits attributes from its left-hand side.\n\t * This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t *\n\t * For the following model fragment:\n\t *\n\t * ```xml\n\t * <$text bold=\"true\" linkHref=\"url\">bar[]</$text><$text bold=\"true\">biz</$text>\n\t * ```\n\t *\n\t * * Default gravity: selection will have the `bold` and `linkHref` attributes.\n\t * * Overridden gravity: selection will have `bold` attribute.\n\t *\n\t * **Note**: It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t * of the process.\n\t *\n\t * @returns The unique id which allows restoring the gravity.\n\t */ overrideSelectionGravity() {\n        return this.model.document.selection._overrideGravity();\n    }\n    /**\n\t * Restores {@link ~Writer#overrideSelectionGravity} gravity to default.\n\t *\n\t * Restoring the gravity is only possible using the unique identifier returned by\n\t * {@link ~Writer#overrideSelectionGravity}. Note that the gravity remains overridden as long as won't be restored\n\t * the same number of times it was overridden.\n\t *\n\t * @param uid The unique id returned by {@link ~Writer#overrideSelectionGravity}.\n\t */ restoreSelectionGravity(uid) {\n        this.model.document.selection._restoreGravity(uid);\n    }\n    /**\n\t * @param key Key of the attribute to remove.\n\t * @param value Attribute value.\n\t */ _setSelectionAttribute(key, value) {\n        const selection = this.model.document.selection;\n        // Store attribute in parent element if the selection is collapsed in an empty node.\n        if (selection.isCollapsed && selection.anchor.parent.isEmpty) {\n            const storeKey = DocumentSelection._getStoreAttributeKey(key);\n            this.setAttribute(storeKey, value, selection.anchor.parent);\n        }\n        selection._setAttribute(key, value);\n    }\n    /**\n\t * @param key Key of the attribute to remove.\n\t */ _removeSelectionAttribute(key) {\n        const selection = this.model.document.selection;\n        // Remove stored attribute from parent element if the selection is collapsed in an empty node.\n        if (selection.isCollapsed && selection.anchor.parent.isEmpty) {\n            const storeKey = DocumentSelection._getStoreAttributeKey(key);\n            this.removeAttribute(storeKey, selection.anchor.parent);\n        }\n        selection._removeAttribute(key);\n    }\n    /**\n\t * Throws `writer-detached-writer-tries-to-modify-model` error when the writer is used outside of the `change()` block.\n\t */ _assertWriterUsedCorrectly() {\n        /**\n\t\t * Trying to use a writer outside a {@link module:engine/model/model~Model#change `change()`} or\n\t\t * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`} blocks.\n\t\t *\n\t\t * The writer can only be used inside these blocks which ensures that the model\n\t\t * can only be changed during such \"sessions\".\n\t\t *\n\t\t * @error writer-incorrect-use\n\t\t */ if (this.model._currentWriter !== this) {\n            throw new CKEditorError('writer-incorrect-use', this);\n        }\n    }\n    /**\n\t * For given action `type` and `positionOrRange` where the action happens, this function finds all affected markers\n\t * and applies a marker operation with the new marker range equal to the current range. Thanks to this, the marker range\n\t * can be later correctly processed during undo.\n\t *\n\t * @param type Writer action type.\n\t * @param positionOrRange Position or range where the writer action happens.\n\t */ _addOperationForAffectedMarkers(type, positionOrRange) {\n        for (const marker of this.model.markers){\n            if (!marker.managedUsingOperations) {\n                continue;\n            }\n            const markerRange = marker.getRange();\n            let isAffected = false;\n            if (type === 'move') {\n                const range = positionOrRange;\n                isAffected = range.containsPosition(markerRange.start) || range.start.isEqual(markerRange.start) || range.containsPosition(markerRange.end) || range.end.isEqual(markerRange.end);\n            } else {\n                // if type === 'merge'.\n                const position = positionOrRange;\n                const elementBefore = position.nodeBefore;\n                const elementAfter = position.nodeAfter;\n                //               Start:  <p>Foo[</p><p>Bar]</p>\n                //         After merge:  <p>Foo[Bar]</p>\n                // After undoing split:  <p>Foo</p><p>[Bar]</p>     <-- incorrect, needs remembering for undo.\n                //\n                const affectedInLeftElement = markerRange.start.parent == elementBefore && markerRange.start.isAtEnd;\n                //               Start:  <p>[Foo</p><p>]Bar</p>\n                //         After merge:  <p>[Foo]Bar</p>\n                // After undoing split:  <p>[Foo]</p><p>Bar</p>     <-- incorrect, needs remembering for undo.\n                //\n                const affectedInRightElement = markerRange.end.parent == elementAfter && markerRange.end.offset == 0;\n                //               Start:  <p>[Foo</p>]<p>Bar</p>\n                //         After merge:  <p>[Foo]Bar</p>\n                // After undoing split:  <p>[Foo]</p><p>Bar</p>     <-- incorrect, needs remembering for undo.\n                //\n                const affectedAfterLeftElement = markerRange.end.nodeAfter == elementAfter;\n                //               Start:  <p>Foo</p>[<p>Bar]</p>\n                //         After merge:  <p>Foo[Bar]</p>\n                // After undoing split:  <p>Foo</p><p>[Bar]</p>     <-- incorrect, needs remembering for undo.\n                //\n                const affectedBeforeRightElement = markerRange.start.nodeAfter == elementAfter;\n                isAffected = affectedInLeftElement || affectedInRightElement || affectedAfterLeftElement || affectedBeforeRightElement;\n            }\n            if (isAffected) {\n                this.updateMarker(marker.name, {\n                    range: markerRange\n                });\n            }\n        }\n    }\n}\n/**\n * Sets given attribute to each node in given range. When attribute value is null then attribute will be removed.\n *\n * Because attribute operation needs to have the same attribute value on the whole range, this function splits\n * the range into smaller parts.\n *\n * Given `range` must be flat.\n */ function setAttributeOnRange(writer, key, value, range) {\n    const model = writer.model;\n    const doc = model.document;\n    // Position of the last split, the beginning of the new range.\n    let lastSplitPosition = range.start;\n    // Currently position in the scanning range. Because we need value after the position, it is not a current\n    // position of the iterator but the previous one (we need to iterate one more time to get the value after).\n    let position;\n    // Value before the currently position.\n    let valueBefore;\n    // Value after the currently position.\n    let valueAfter;\n    for (const val of range.getWalker({\n        shallow: true\n    })){\n        valueAfter = val.item.getAttribute(key);\n        // At the first run of the iterator the position in undefined. We also do not have a valueBefore, but\n        // because valueAfter may be null, valueBefore may be equal valueAfter ( undefined == null ).\n        if (position && valueBefore != valueAfter) {\n            // if valueBefore == value there is nothing to change, so we add operation only if these values are different.\n            if (valueBefore != value) {\n                addOperation();\n            }\n            lastSplitPosition = position;\n        }\n        position = val.nextPosition;\n        valueBefore = valueAfter;\n    }\n    // Because position in the loop is not the iterator position (see let position comment), the last position in\n    // the while loop will be last but one position in the range. We need to check the last position manually.\n    if (position instanceof Position && position != lastSplitPosition && valueBefore != value) {\n        addOperation();\n    }\n    function addOperation() {\n        const range = new Range(lastSplitPosition, position);\n        const version = range.root.document ? doc.version : null;\n        const operation = new AttributeOperation(range, key, valueBefore, value, version);\n        writer.batch.addOperation(operation);\n        model.applyOperation(operation);\n    }\n}\n/**\n * Sets given attribute to the given node. When attribute value is null then attribute will be removed.\n */ function setAttributeOnItem(writer, key, value, item) {\n    const model = writer.model;\n    const doc = model.document;\n    const previousValue = item.getAttribute(key);\n    let range, operation;\n    if (previousValue != value) {\n        const isRootChanged = item.root === item;\n        if (isRootChanged) {\n            // If we change attributes of root element, we have to use `RootAttributeOperation`.\n            const version = item.document ? doc.version : null;\n            operation = new RootAttributeOperation(item, key, previousValue, value, version);\n        } else {\n            range = new Range(Position._createBefore(item), writer.createPositionAfter(item));\n            const version = range.root.document ? doc.version : null;\n            operation = new AttributeOperation(range, key, previousValue, value, version);\n        }\n        writer.batch.addOperation(operation);\n        model.applyOperation(operation);\n    }\n}\n/**\n * Creates and applies marker operation to {@link module:engine/model/operation/operation~Operation operation}.\n */ function applyMarkerOperation(writer, name, oldRange, newRange, affectsData) {\n    const model = writer.model;\n    const doc = model.document;\n    const operation = new MarkerOperation(name, oldRange, newRange, model.markers, !!affectsData, doc.version);\n    writer.batch.addOperation(operation);\n    model.applyOperation(operation);\n}\n/**\n * Creates `MoveOperation` or `DetachOperation` that removes `howMany` nodes starting from `position`.\n * The operation will be applied on given model instance and added to given operation instance.\n *\n * @param position Position from which nodes are removed.\n * @param howMany Number of nodes to remove.\n * @param batch Batch to which the operation will be added.\n * @param model Model instance on which operation will be applied.\n */ function applyRemoveOperation(position, howMany, batch, model) {\n    let operation;\n    if (position.root.document) {\n        const doc = model.document;\n        const graveyardPosition = new Position(doc.graveyard, [\n            0\n        ]);\n        operation = new MoveOperation(position, howMany, graveyardPosition, doc.version);\n    } else {\n        operation = new DetachOperation(position, howMany);\n    }\n    batch.addOperation(operation);\n    model.applyOperation(operation);\n}\n/**\n * Returns `true` if both root elements are the same element or both are documents root elements.\n *\n * Elements in the same tree can be moved (for instance you can move element form one documents root to another, or\n * within the same document fragment), but when element supposed to be moved from document fragment to the document, or\n * to another document it should be removed and inserted to avoid problems with OT. This is because features like undo or\n * collaboration may track changes on the document but ignore changes on detached fragments and should not get\n * unexpected `move` operation.\n */ function isSameTree(rootA, rootB) {\n    // If it is the same root this is the same tree.\n    if (rootA === rootB) {\n        return true;\n    }\n    // If both roots are documents root it is operation within the document what we still treat as the same tree.\n    if (rootA instanceof RootElement && rootB instanceof RootElement) {\n        return true;\n    }\n    return false;\n}\n\n/**\n * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n *\n * **Note:** Use {@link module:engine/model/model~Model#deleteContent} instead of this function.\n * This function is only exposed to be reusable in algorithms\n * which change the {@link module:engine/model/model~Model#deleteContent}\n * method's behavior.\n *\n * @param model The model in context of which the insertion should be performed.\n * @param selection Selection of which the content should be deleted.\n * @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.\n *\n * For example `<heading>x[x</heading><paragraph>y]y</paragraph>` will become:\n *\n * * `<heading>x^y</heading>` with the option disabled (`leaveUnmerged == false`)\n * * `<heading>x^</heading><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n *\n * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}\n * elements will not be merged.\n *\n * @param options.doNotResetEntireContent Whether to skip replacing the entire content with a\n * paragraph when the entire content was selected.\n *\n * For example `<heading>[x</heading><paragraph>y]</paragraph>` will become:\n *\n * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n * * `<heading>^</heading>` with enabled (`doNotResetEntireContent == true`).\n *\n * @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved\n * to a place where text cannot be inserted.\n *\n * For example `<paragraph>x</paragraph>[<imageBlock src=\"foo.jpg\"></imageBlock>]` will become:\n *\n * * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n * * `<paragraph>x</paragraph>[]` with the option enabled (`doNotAutoparagraph == true`).\n *\n * If you use this option you need to make sure to handle invalid selections yourself or leave\n * them to the selection post-fixer (may not always work).\n *\n * **Note:** If there is no valid position for the selection, the paragraph will always be created:\n *\n * `[<imageBlock src=\"foo.jpg\"></imageBlock>]` -> `<paragraph>[]</paragraph>`.\n */ function deleteContent(model, selection, options = {}) {\n    if (selection.isCollapsed) {\n        return;\n    }\n    const selRange = selection.getFirstRange();\n    // If the selection is already removed, don't do anything.\n    if (selRange.root.rootName == '$graveyard') {\n        return;\n    }\n    const schema = model.schema;\n    model.change((writer)=>{\n        // 1. Replace the entire content with paragraph.\n        // See: https://github.com/ckeditor/ckeditor5-engine/issues/1012#issuecomment-315017594.\n        if (!options.doNotResetEntireContent && shouldEntireContentBeReplacedWithParagraph(schema, selection)) {\n            replaceEntireContentWithParagraph(writer, selection);\n            return;\n        }\n        // Collect attributes to copy in case of autoparagraphing.\n        const attributesForAutoparagraph = {};\n        if (!options.doNotAutoparagraph) {\n            const selectedElement = selection.getSelectedElement();\n            if (selectedElement) {\n                Object.assign(attributesForAutoparagraph, schema.getAttributesWithProperty(selectedElement, 'copyOnReplace', true));\n            }\n        }\n        // Get the live positions for the range adjusted to span only blocks selected from the user perspective.\n        const [startPosition, endPosition] = getLivePositionsForSelectedBlocks(selRange);\n        // 2. Remove the content if there is any.\n        if (!startPosition.isTouching(endPosition)) {\n            writer.remove(writer.createRange(startPosition, endPosition));\n        }\n        // 3. Merge elements in the right branch to the elements in the left branch.\n        // The only reasonable (in terms of data and selection correctness) case in which we need to do that is:\n        //\n        // <heading type=1>Fo[</heading><paragraph>]ar</paragraph> => <heading type=1>Fo^ar</heading>\n        //\n        // However, the algorithm supports also merging deeper structures (up to the depth of the shallower branch),\n        // as it's hard to imagine what should actually be the default behavior. Usually, specific features will\n        // want to override that behavior anyway.\n        if (!options.leaveUnmerged) {\n            mergeBranches(writer, startPosition, endPosition);\n            // TMP this will be replaced with a postfixer.\n            // We need to check and strip disallowed attributes in all nested nodes because after merge\n            // some attributes could end up in a path where are disallowed.\n            //\n            // e.g. bold is disallowed for <H1>\n            // <h1>Fo{o</h1><p>b}a<b>r</b><p> -> <h1>Fo{}a<b>r</b><h1> -> <h1>Fo{}ar<h1>.\n            schema.removeDisallowedAttributes(startPosition.parent.getChildren(), writer);\n        }\n        collapseSelectionAt(writer, selection, startPosition);\n        // 4. Add a paragraph to set selection in it.\n        // Check if a text is allowed in the new container. If not, try to create a new paragraph (if it's allowed here).\n        // If autoparagraphing is off, we assume that you know what you do so we leave the selection wherever it was.\n        if (!options.doNotAutoparagraph && shouldAutoparagraph(schema, startPosition)) {\n            insertParagraph(writer, startPosition, selection, attributesForAutoparagraph);\n        }\n        startPosition.detach();\n        endPosition.detach();\n    });\n}\n/**\n * Returns the live positions for the range adjusted to span only blocks selected from the user perspective. Example:\n *\n * ```\n * <heading1>[foo</heading1>\n * <paragraph>bar</paragraph>\n * <heading1>]abc</heading1>  <-- this block is not considered as selected\n * ```\n *\n * This is the same behavior as in Selection#getSelectedBlocks() \"special case\".\n */ function getLivePositionsForSelectedBlocks(range) {\n    const model = range.root.document.model;\n    const startPosition = range.start;\n    let endPosition = range.end;\n    // If the end of selection is at the start position of last block in the selection, then\n    // shrink it to not include that trailing block. Note that this should happen only for not empty selection.\n    if (model.hasContent(range, {\n        ignoreMarkers: true\n    })) {\n        const endBlock = getParentBlock(endPosition);\n        if (endBlock && endPosition.isTouching(model.createPositionAt(endBlock, 0))) {\n            // Create forward selection as a probe to find a valid position after excluding last block from the range.\n            const selection = model.createSelection(range);\n            // Modify the forward selection in backward direction to shrink it and remove first position of following block from it.\n            // This is how modifySelection works and here we are making use of it.\n            model.modifySelection(selection, {\n                direction: 'backward'\n            });\n            const newEndPosition = selection.getLastPosition();\n            // For such a model and selection:\n            //     <paragraph>A[</paragraph><imageBlock></imageBlock><paragraph>]B</paragraph>\n            //\n            // After modifySelection(), we would end up with this:\n            //     <paragraph>A[</paragraph>]<imageBlock></imageBlock><paragraph>B</paragraph>\n            //\n            // So we need to check if there is no content in the skipped range (because we want to include the <imageBlock>).\n            const skippedRange = model.createRange(newEndPosition, endPosition);\n            if (!model.hasContent(skippedRange, {\n                ignoreMarkers: true\n            })) {\n                endPosition = newEndPosition;\n            }\n        }\n    }\n    return [\n        LivePosition.fromPosition(startPosition, 'toPrevious'),\n        LivePosition.fromPosition(endPosition, 'toNext')\n    ];\n}\n/**\n * Finds the lowest element in position's ancestors which is a block.\n * Returns null if a limit element is encountered before reaching a block element.\n */ function getParentBlock(position) {\n    const element = position.parent;\n    const schema = element.root.document.model.schema;\n    const ancestors = element.getAncestors({\n        parentFirst: true,\n        includeSelf: true\n    });\n    for (const element of ancestors){\n        if (schema.isLimit(element)) {\n            return null;\n        }\n        if (schema.isBlock(element)) {\n            return element;\n        }\n    }\n}\n/**\n * This function is a result of reaching the Ballmer's peak for just the right amount of time.\n * Even I had troubles documenting it after a while and after reading it again I couldn't believe that it really works.\n */ function mergeBranches(writer, startPosition, endPosition) {\n    const model = writer.model;\n    // Verify if there is a need and possibility to merge.\n    if (!checkShouldMerge(writer.model.schema, startPosition, endPosition)) {\n        return;\n    }\n    // If the start element on the common ancestor level is empty, and the end element on the same level is not empty\n    // then merge those to the right element so that it's properties are preserved (name, attributes).\n    // Because of OT merging is used instead of removing elements.\n    //\n    // Merge left:\n    //     <heading1>foo[</heading1>    ->  <heading1>foo[]bar</heading1>\n    //     <paragraph>]bar</paragraph>  ->               --^\n    //\n    // Merge right:\n    //     <heading1>[</heading1>       ->\n    //     <paragraph>]bar</paragraph>  ->  <paragraph>[]bar</paragraph>\n    //\n    // Merge left:\n    //     <blockQuote>                     ->  <blockQuote>\n    //         <heading1>foo[</heading1>    ->      <heading1>foo[]bar</heading1>\n    //         <paragraph>]bar</paragraph>  ->                   --^\n    //     </blockQuote>                    ->  </blockQuote>\n    //\n    // Merge right:\n    //     <blockQuote>                     ->  <blockQuote>\n    //         <heading1>[</heading1>       ->\n    //         <paragraph>]bar</paragraph>  ->      <paragraph>[]bar</paragraph>\n    //     </blockQuote>                    ->  </blockQuote>\n    // Merging should not go deeper than common ancestor.\n    const [startAncestor, endAncestor] = getAncestorsJustBelowCommonAncestor(startPosition, endPosition);\n    // Branches can't be merged if one of the positions is directly inside a common ancestor.\n    //\n    // Example:\n    //     <blockQuote>\n    //         <paragraph>[foo</paragraph>]\n    //         <table> ... </table>\n    //     <blockQuote>\n    //\n    if (!startAncestor || !endAncestor) {\n        return;\n    }\n    if (!model.hasContent(startAncestor, {\n        ignoreMarkers: true\n    }) && model.hasContent(endAncestor, {\n        ignoreMarkers: true\n    })) {\n        mergeBranchesRight(writer, startPosition, endPosition, startAncestor.parent);\n    } else {\n        mergeBranchesLeft(writer, startPosition, endPosition, startAncestor.parent);\n    }\n}\n/**\n * Merging blocks to the left (properties of the left block are preserved).\n * Simple example:\n *\n * ```\n * <heading1>foo[</heading1>    ->  <heading1>foo[bar</heading1>]\n * <paragraph>]bar</paragraph>  ->              --^\n * ```\n *\n * Nested example:\n *\n * ```\n * <blockQuote>                     ->  <blockQuote>\n *     <heading1>foo[</heading1>    ->      <heading1>foo[bar</heading1>\n * </blockQuote>                    ->  </blockQuote>]    ^\n * <blockBlock>                     ->                    |\n *     <paragraph>]bar</paragraph>  ->                 ---\n * </blockBlock>                    ->\n * ```\n */ function mergeBranchesLeft(writer, startPosition, endPosition, commonAncestor) {\n    const startElement = startPosition.parent;\n    const endElement = endPosition.parent;\n    // Merging reached the common ancestor element, stop here.\n    if (startElement == commonAncestor || endElement == commonAncestor) {\n        return;\n    }\n    // Remember next positions to merge in next recursive step (also used as modification points pointers).\n    startPosition = writer.createPositionAfter(startElement);\n    endPosition = writer.createPositionBefore(endElement);\n    // Move endElement just after startElement if they aren't siblings.\n    if (!endPosition.isEqual(startPosition)) {\n        //\n        //     <blockQuote>                     ->  <blockQuote>\n        //         <heading1>foo[</heading1>    ->      <heading1>foo</heading1>[<paragraph>bar</paragraph>\n        //     </blockQuote>                    ->  </blockQuote>                ^\n        //     <blockBlock>                     ->  <blockBlock>                 |\n        //         <paragraph>]bar</paragraph>  ->      ]                     ---\n        //     </blockBlock>                    ->  </blockBlock>\n        //\n        writer.insert(endElement, startPosition);\n    }\n    // Merge two siblings (nodes on sides of startPosition):\n    //\n    //     <blockQuote>                                             ->  <blockQuote>\n    //         <heading1>foo</heading1>[<paragraph>bar</paragraph>  ->      <heading1>foo[bar</heading1>\n    //     </blockQuote>                                            ->  </blockQuote>\n    //     <blockBlock>                                             ->  <blockBlock>\n    //         ]                                                    ->      ]\n    //     </blockBlock>                                            ->  </blockBlock>\n    //\n    // Or in simple case (without moving elements in above if):\n    //     <heading1>foo</heading1>[<paragraph>bar</paragraph>]  ->  <heading1>foo[bar</heading1>]\n    //\n    writer.merge(startPosition);\n    // Remove empty end ancestors:\n    //\n    //     <blockQuote>                      ->  <blockQuote>\n    //         <heading1>foo[bar</heading1>  ->      <heading1>foo[bar</heading1>\n    //     </blockQuote>                     ->  </blockQuote>\n    //     <blockBlock>                      ->\n    //         ]                             ->  ]\n    //     </blockBlock>                     ->\n    //\n    while(endPosition.parent.isEmpty){\n        const parentToRemove = endPosition.parent;\n        endPosition = writer.createPositionBefore(parentToRemove);\n        writer.remove(parentToRemove);\n    }\n    // Verify if there is a need and possibility to merge next level.\n    if (!checkShouldMerge(writer.model.schema, startPosition, endPosition)) {\n        return;\n    }\n    // Continue merging next level (blockQuote with blockBlock in the examples above if it would not be empty and got removed).\n    mergeBranchesLeft(writer, startPosition, endPosition, commonAncestor);\n}\n/**\n * Merging blocks to the right (properties of the right block are preserved).\n * Simple example:\n *\n * ```\n * <heading1>foo[</heading1>    ->            --v\n * <paragraph>]bar</paragraph>  ->  [<paragraph>foo]bar</paragraph>\n * ```\n *\n * Nested example:\n *\n * ```\n * <blockQuote>                     ->\n *     <heading1>foo[</heading1>    ->              ---\n * </blockQuote>                    ->                 |\n * <blockBlock>                     ->  [<blockBlock>  v\n *     <paragraph>]bar</paragraph>  ->      <paragraph>foo]bar</paragraph>\n * </blockBlock>                    ->  </blockBlock>\n * ```\n */ function mergeBranchesRight(writer, startPosition, endPosition, commonAncestor) {\n    const startElement = startPosition.parent;\n    const endElement = endPosition.parent;\n    // Merging reached the common ancestor element, stop here.\n    if (startElement == commonAncestor || endElement == commonAncestor) {\n        return;\n    }\n    // Remember next positions to merge in next recursive step (also used as modification points pointers).\n    startPosition = writer.createPositionAfter(startElement);\n    endPosition = writer.createPositionBefore(endElement);\n    // Move startElement just before endElement if they aren't siblings.\n    if (!endPosition.isEqual(startPosition)) {\n        //\n        //     <blockQuote>                     ->  <blockQuote>\n        //         <heading1>foo[</heading1>    ->      [                   ---\n        //     </blockQuote>                    ->  </blockQuote>              |\n        //     <blockBlock>                     ->  <blockBlock>               v\n        //         <paragraph>]bar</paragraph>  ->      <heading1>foo</heading1>]<paragraph>bar</paragraph>\n        //     </blockBlock>                    ->  </blockBlock>\n        //\n        writer.insert(startElement, endPosition);\n    }\n    // Remove empty end ancestors:\n    //\n    //     <blockQuote>                                             ->\n    //         [                                                    ->  [\n    //     </blockQuote>                                            ->\n    //     <blockBlock>                                             ->  <blockBlock>\n    //         <heading1>foo</heading1>]<paragraph>bar</paragraph>  ->      <heading1>foo</heading1>]<paragraph>bar</paragraph>\n    //     </blockBlock>                                            ->  </blockBlock>\n    //\n    while(startPosition.parent.isEmpty){\n        const parentToRemove = startPosition.parent;\n        startPosition = writer.createPositionBefore(parentToRemove);\n        writer.remove(parentToRemove);\n    }\n    // Update endPosition after inserting and removing elements.\n    endPosition = writer.createPositionBefore(endElement);\n    // Merge right two siblings (nodes on sides of endPosition):\n    //                                                              ->\n    //     [                                                        ->  [\n    //                                                              ->\n    //     <blockBlock>                                             ->  <blockBlock>\n    //         <heading1>foo</heading1>]<paragraph>bar</paragraph>  ->      <paragraph>foo]bar</paragraph>\n    //     </blockBlock>                                            ->  </blockBlock>\n    //\n    // Or in simple case (without moving elements in above if):\n    //     [<heading1>foo</heading1>]<paragraph>bar</paragraph>  ->  [<heading1>foo]bar</heading1>\n    //\n    mergeRight(writer, endPosition);\n    // Verify if there is a need and possibility to merge next level.\n    if (!checkShouldMerge(writer.model.schema, startPosition, endPosition)) {\n        return;\n    }\n    // Continue merging next level (blockQuote with blockBlock in the examples above if it would not be empty and got removed).\n    mergeBranchesRight(writer, startPosition, endPosition, commonAncestor);\n}\n/**\n * There is no right merge operation so we need to simulate it.\n */ function mergeRight(writer, position) {\n    const startElement = position.nodeBefore;\n    const endElement = position.nodeAfter;\n    if (startElement.name != endElement.name) {\n        writer.rename(startElement, endElement.name);\n    }\n    writer.clearAttributes(startElement);\n    writer.setAttributes(Object.fromEntries(endElement.getAttributes()), startElement);\n    writer.merge(position);\n}\n/**\n * Verifies if merging is needed and possible. It's not needed if both positions are in the same element\n * and it's not possible if some element is a limit or the range crosses a limit element.\n */ function checkShouldMerge(schema, startPosition, endPosition) {\n    const startElement = startPosition.parent;\n    const endElement = endPosition.parent;\n    // If both positions ended up in the same parent, then there's nothing more to merge:\n    // <$root><p>x[</p><p>]y</p></$root> => <$root><p>xy</p>[]</$root>\n    if (startElement == endElement) {\n        return false;\n    }\n    // If one of the positions is a limit element, then there's nothing to merge because we don't want to cross the limit boundaries.\n    if (schema.isLimit(startElement) || schema.isLimit(endElement)) {\n        return false;\n    }\n    // Check if operations we'll need to do won't need to cross object or limit boundaries.\n    // E.g., we can't merge endElement into startElement in this case:\n    // <limit><startElement>x[</startElement></limit><endElement>]</endElement>\n    return isCrossingLimitElement(startPosition, endPosition, schema);\n}\n/**\n * Returns the elements that are the ancestors of the provided positions that are direct children of the common ancestor.\n */ function getAncestorsJustBelowCommonAncestor(positionA, positionB) {\n    const ancestorsA = positionA.getAncestors();\n    const ancestorsB = positionB.getAncestors();\n    let i = 0;\n    while(ancestorsA[i] && ancestorsA[i] == ancestorsB[i]){\n        i++;\n    }\n    return [\n        ancestorsA[i],\n        ancestorsB[i]\n    ];\n}\nfunction shouldAutoparagraph(schema, position) {\n    const isTextAllowed = schema.checkChild(position, '$text');\n    const isParagraphAllowed = schema.checkChild(position, 'paragraph');\n    return !isTextAllowed && isParagraphAllowed;\n}\n/**\n * Check if parents of two positions can be merged by checking if there are no limit/object\n * boundaries between those two positions.\n *\n * E.g. in <bQ><p>x[]</p></bQ><widget><caption>{}</caption></widget>\n * we'll check <p>, <bQ>, <widget> and <caption>.\n * Usually, widget and caption are marked as objects/limits in the schema, so in this case merging will be blocked.\n */ function isCrossingLimitElement(leftPos, rightPos, schema) {\n    const rangeToCheck = new Range(leftPos, rightPos);\n    for (const value of rangeToCheck.getWalker()){\n        if (schema.isLimit(value.item)) {\n            return false;\n        }\n    }\n    return true;\n}\nfunction insertParagraph(writer, position, selection, attributes = {}) {\n    const paragraph = writer.createElement('paragraph');\n    writer.model.schema.setAllowedAttributes(paragraph, attributes, writer);\n    writer.insert(paragraph, position);\n    collapseSelectionAt(writer, selection, writer.createPositionAt(paragraph, 0));\n}\nfunction replaceEntireContentWithParagraph(writer, selection) {\n    const limitElement = writer.model.schema.getLimitElement(selection);\n    writer.remove(writer.createRangeIn(limitElement));\n    insertParagraph(writer, writer.createPositionAt(limitElement, 0), selection);\n}\n/**\n * We want to replace the entire content with a paragraph when:\n * * the entire content is selected,\n * * selection contains at least two elements,\n * * whether the paragraph is allowed in schema in the common ancestor.\n */ function shouldEntireContentBeReplacedWithParagraph(schema, selection) {\n    const limitElement = schema.getLimitElement(selection);\n    if (!selection.containsEntireContent(limitElement)) {\n        return false;\n    }\n    const range = selection.getFirstRange();\n    if (range.start.parent == range.end.parent) {\n        return false;\n    }\n    return schema.checkChild(limitElement, 'paragraph');\n}\n/**\n * Helper function that sets the selection. Depending whether given `selection` is a document selection or not,\n * uses a different method to set it.\n */ function collapseSelectionAt(writer, selection, positionOrRange) {\n    if (selection instanceof DocumentSelection) {\n        writer.setSelection(positionOrRange);\n    } else {\n        selection.setTo(positionOrRange);\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module engine/model/utils/getselectedcontent\n */ /**\n * Gets a clone of the selected content.\n *\n * For example, for the following selection:\n *\n * ```html\n * <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n * ```\n *\n * It will return a document fragment with such a content:\n *\n * ```html\n * <quote><h>st</h></quote><p>se</p>\n * ```\n *\n * @param model The model in context of which the selection modification should be performed.\n * @param selection The selection of which content will be returned.\n */ function getSelectedContent(model, selection) {\n    return model.change((writer)=>{\n        const frag = writer.createDocumentFragment();\n        const range = selection.getFirstRange();\n        if (!range || range.isCollapsed) {\n            return frag;\n        }\n        const root = range.start.root;\n        const commonPath = range.start.getCommonPath(range.end);\n        const commonParent = root.getNodeByPath(commonPath);\n        // ## 1st step\n        //\n        // First, we'll clone a fragment represented by a minimal flat range\n        // containing the original range to be cloned.\n        // E.g. let's consider such a range:\n        //\n        // <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n        //\n        // A minimal flat range containing this one is:\n        //\n        // <p>x</p>[<quote><p>y</p><h>first</h></quote><p>second</p>]<p>z</p>\n        //\n        // We can easily clone this structure, preserving e.g. the <quote> element.\n        let flatSubtreeRange;\n        if (range.start.parent == range.end.parent) {\n            // The original range is flat, so take it.\n            flatSubtreeRange = range;\n        } else {\n            flatSubtreeRange = writer.createRange(writer.createPositionAt(commonParent, range.start.path[commonPath.length]), writer.createPositionAt(commonParent, range.end.path[commonPath.length] + 1));\n        }\n        const howMany = flatSubtreeRange.end.offset - flatSubtreeRange.start.offset;\n        // Clone the whole contents.\n        for (const item of flatSubtreeRange.getItems({\n            shallow: true\n        })){\n            if (item.is('$textProxy')) {\n                writer.appendText(item.data, item.getAttributes(), frag);\n            } else {\n                writer.append(writer.cloneElement(item, true), frag);\n            }\n        }\n        // ## 2nd step\n        //\n        // If the original range wasn't flat, then we need to remove the excess nodes from the both ends of the cloned fragment.\n        //\n        // For example, for the range shown in the 1st step comment, we need to remove these pieces:\n        //\n        // <quote>[<p>y</p>]<h>[fir]st</h></quote><p>se[cond]</p>\n        //\n        // So this will be the final copied content:\n        //\n        // <quote><h>st</h></quote><p>se</p>\n        //\n        // In order to do that, we remove content from these two ranges:\n        //\n        // [<quote><p>y</p><h>fir]st</h></quote><p>se[cond</p>]\n        if (flatSubtreeRange != range) {\n            // Find the position of the original range in the cloned fragment.\n            const newRange = range._getTransformedByMove(flatSubtreeRange.start, writer.createPositionAt(frag, 0), howMany)[0];\n            const leftExcessRange = writer.createRange(writer.createPositionAt(frag, 0), newRange.start);\n            const rightExcessRange = writer.createRange(newRange.end, writer.createPositionAt(frag, 'end'));\n            removeRangeContent(rightExcessRange, writer);\n            removeRangeContent(leftExcessRange, writer);\n        }\n        return frag;\n    });\n}\n// After https://github.com/ckeditor/ckeditor5-engine/issues/690 is fixed,\n// this function will, most likely, be able to rewritten using getMinimalFlatRanges().\nfunction removeRangeContent(range, writer) {\n    const parentsToCheck = [];\n    Array.from(range.getItems({\n        direction: 'backward'\n    }))// We should better store ranges because text proxies will lose integrity\n    // with the text nodes when we'll start removing content.\n    .map((item)=>writer.createRangeOn(item))// Filter only these items which are fully contained in the passed range.\n    //\n    // E.g. for the following range: [<quote><p>y</p><h>fir]st</h>\n    // the walker will return the entire <h> element, when only the \"fir\" item inside it is fully contained.\n    .filter((itemRange)=>{\n        // We should be able to use Range.containsRange, but https://github.com/ckeditor/ckeditor5-engine/issues/691.\n        const contained = (itemRange.start.isAfter(range.start) || itemRange.start.isEqual(range.start)) && (itemRange.end.isBefore(range.end) || itemRange.end.isEqual(range.end));\n        return contained;\n    }).forEach((itemRange)=>{\n        parentsToCheck.push(itemRange.start.parent);\n        writer.remove(itemRange);\n    });\n    // Remove ancestors of the removed items if they turned to be empty now\n    // (their whole content was contained in the range).\n    parentsToCheck.forEach((parentToCheck)=>{\n        let parent = parentToCheck;\n        while(parent.parent && parent.isEmpty){\n            const removeRange = writer.createRangeOn(parent);\n            parent = parent.parent;\n            writer.remove(removeRange);\n        }\n    });\n}\n\n/**\n * Inserts content into the editor (specified selection) as one would expect the paste functionality to work.\n *\n * It takes care of removing the selected content, splitting elements (if needed), inserting elements and merging elements appropriately.\n *\n * Some examples:\n *\n * ```html\n * <p>x^</p> + <p>y</p> => <p>x</p><p>y</p> => <p>xy[]</p>\n * <p>x^y</p> + <p>z</p> => <p>x</p>^<p>y</p> + <p>z</p> => <p>x</p><p>z</p><p>y</p> => <p>xz[]y</p>\n * <p>x^y</p> + <img /> => <p>x</p>^<p>y</p> + <img /> => <p>x</p><img /><p>y</p>\n * <p>x</p><p>^</p><p>z</p> + <p>y</p> => <p>x</p><p>y[]</p><p>z</p> (no merging)\n * <p>x</p>[<img />]<p>z</p> + <p>y</p> => <p>x</p>^<p>z</p> + <p>y</p> => <p>x</p><p>y[]</p><p>z</p>\n * ```\n *\n * If an instance of {@link module:engine/model/selection~Selection} is passed as `selectable` it will be modified\n * to the insertion selection (equal to a range to be selected after insertion).\n *\n * If `selectable` is not passed, the content will be inserted using the current selection of the model document.\n *\n * **Note:** Use {@link module:engine/model/model~Model#insertContent} instead of this function.\n * This function is only exposed to be reusable in algorithms which change the {@link module:engine/model/model~Model#insertContent}\n * method's behavior.\n *\n * @param model The model in context of which the insertion should be performed.\n * @param content The content to insert.\n * @param selectable Selection into which the content should be inserted.\n * @param placeOrOffset Sets place or offset of the selection.\n * @returns Range which contains all the performed changes. This is a range that, if removed,\n * would return the model to the state before the insertion. If no changes were preformed by `insertContent`, returns a range collapsed\n * at the insertion position.\n */ function insertContent(model, content, selectable) {\n    return model.change((writer)=>{\n        const selection = selectable ? selectable : model.document.selection;\n        if (!selection.isCollapsed) {\n            model.deleteContent(selection, {\n                doNotAutoparagraph: true\n            });\n        }\n        const insertion = new Insertion(model, writer, selection.anchor);\n        const fakeMarkerElements = [];\n        let nodesToInsert;\n        if (content.is('documentFragment')) {\n            // If document fragment has any markers, these markers should be inserted into the model as well.\n            if (content.markers.size) {\n                const markersPosition = [];\n                for (const [name, range] of content.markers){\n                    const { start, end } = range;\n                    const isCollapsed = start.isEqual(end);\n                    markersPosition.push({\n                        position: start,\n                        name,\n                        isCollapsed\n                    }, {\n                        position: end,\n                        name,\n                        isCollapsed\n                    });\n                }\n                // Markers position is sorted backwards to ensure that the insertion of fake markers will not change\n                // the position of the next markers.\n                markersPosition.sort(({ position: posA }, { position: posB })=>posA.isBefore(posB) ? 1 : -1);\n                for (const { position, name, isCollapsed } of markersPosition){\n                    let fakeElement = null;\n                    let collapsed = null;\n                    const isAtBeginning = position.parent === content && position.isAtStart;\n                    const isAtEnd = position.parent === content && position.isAtEnd;\n                    // We have two ways of handling markers. In general, we want to add temporary <$marker> model elements to\n                    // represent marker boundaries. These elements will be inserted into content together with the rest\n                    // of the document fragment. After insertion is done, positions for these elements will be read\n                    // and proper, actual markers will be created in the model and fake elements will be removed.\n                    //\n                    // However, if the <$marker> element is at the beginning or at the end of the document fragment,\n                    // it may affect how the inserted content is merged with current model, impacting the insertion\n                    // result. To avoid that, we don't add <$marker> elements at these positions. Instead, we will use\n                    // `Insertion#getAffectedRange()` to figure out new positions for these marker boundaries.\n                    if (!isAtBeginning && !isAtEnd) {\n                        fakeElement = writer.createElement('$marker');\n                        writer.insert(fakeElement, position);\n                    } else if (isCollapsed) {\n                        // Save whether the collapsed marker was at the beginning or at the end of document fragment\n                        // to know where to create it after the insertion is done.\n                        collapsed = isAtBeginning ? 'start' : 'end';\n                    }\n                    fakeMarkerElements.push({\n                        name,\n                        element: fakeElement,\n                        collapsed\n                    });\n                }\n            }\n            nodesToInsert = content.getChildren();\n        } else {\n            nodesToInsert = [\n                content\n            ];\n        }\n        insertion.handleNodes(nodesToInsert);\n        let newRange = insertion.getSelectionRange();\n        if (content.is('documentFragment') && fakeMarkerElements.length) {\n            // After insertion was done, the selection was set but the model contains fake <$marker> elements.\n            // These <$marker> elements will be now removed. Because of that, we will need to fix the selection.\n            // We will create a live range that will automatically be update as <$marker> elements are removed.\n            const selectionLiveRange = newRange ? LiveRange.fromRange(newRange) : null;\n            // Marker name -> [ start position, end position ].\n            const markersData = {};\n            // Note: `fakeMarkerElements` are sorted backwards. However, now, we want to handle the markers\n            // from the beginning, so that existing <$marker> elements do not affect markers positions.\n            // This is why we iterate from the end to the start.\n            for(let i = fakeMarkerElements.length - 1; i >= 0; i--){\n                const { name, element, collapsed } = fakeMarkerElements[i];\n                const isStartBoundary = !markersData[name];\n                if (isStartBoundary) {\n                    markersData[name] = [];\n                }\n                if (element) {\n                    // Read fake marker element position to learn where the marker should be created.\n                    const elementPosition = writer.createPositionAt(element, 'before');\n                    markersData[name].push(elementPosition);\n                    writer.remove(element);\n                } else {\n                    // If the fake marker element does not exist, it means that the marker boundary was at the beginning or at the end.\n                    const rangeOnInsertion = insertion.getAffectedRange();\n                    if (!rangeOnInsertion) {\n                        // If affected range is `null` it means that nothing was in the document fragment or all content was filtered out.\n                        // Some markers that were in the filtered content may be removed (partially or totally).\n                        // Let's handle only those markers that were at the beginning or at the end of the document fragment.\n                        if (collapsed) {\n                            markersData[name].push(insertion.position);\n                        }\n                        continue;\n                    }\n                    if (collapsed) {\n                        // If the marker was collapsed at the beginning or at the end of the document fragment,\n                        // put both boundaries at the beginning or at the end of inserted range (to keep the marker collapsed).\n                        markersData[name].push(rangeOnInsertion[collapsed]);\n                    } else {\n                        markersData[name].push(isStartBoundary ? rangeOnInsertion.start : rangeOnInsertion.end);\n                    }\n                }\n            }\n            for (const [name, [start, end]] of Object.entries(markersData)){\n                // For now, we ignore markers if they are included in the filtered-out content.\n                // In the future implementation we will improve that case to create markers that are not filtered out completely.\n                if (start && end && start.root === end.root && start.root.document && !writer.model.markers.has(name)) {\n                    writer.addMarker(name, {\n                        usingOperation: true,\n                        affectsData: true,\n                        range: new Range(start, end)\n                    });\n                }\n            }\n            if (selectionLiveRange) {\n                newRange = selectionLiveRange.toRange();\n                selectionLiveRange.detach();\n            }\n        }\n        /* istanbul ignore else -- @preserve */ if (newRange) {\n            if (selection instanceof DocumentSelection) {\n                writer.setSelection(newRange);\n            } else {\n                selection.setTo(newRange);\n            }\n        }\n        const affectedRange = insertion.getAffectedRange() || model.createRange(selection.anchor);\n        insertion.destroy();\n        return affectedRange;\n    });\n}\n/**\n * Utility class for performing content insertion.\n */ class Insertion {\n    /**\n\t * The model in context of which the insertion should be performed.\n\t */ model;\n    /**\n\t * Batch to which operations will be added.\n\t */ writer;\n    /**\n\t * The position at which (or near which) the next node will be inserted.\n\t */ position;\n    /**\n\t * Elements with which the inserted elements can be merged.\n\t *\n\t * ```html\n\t * <p>x^</p><p>y</p> + <p>z</p> (can merge to <p>x</p>)\n\t * <p>x</p><p>^y</p> + <p>z</p> (can merge to <p>y</p>)\n\t * <p>x^y</p> + <p>z</p> (can merge to <p>xy</p> which will be split during the action,\n\t * \t\t\t\t\t\tso both its pieces will be added to this set)\n\t * ```\n\t */ canMergeWith;\n    /**\n\t * Schema of the model.\n\t */ schema;\n    /**\n\t * The temporary DocumentFragment used for grouping multiple nodes for single insert operation.\n\t */ _documentFragment;\n    /**\n\t * The current position in the temporary DocumentFragment.\n\t */ _documentFragmentPosition;\n    /**\n\t * The reference to the first inserted node.\n\t */ _firstNode = null;\n    /**\n\t * The reference to the last inserted node.\n\t */ _lastNode = null;\n    /**\n\t * The reference to the last auto paragraph node.\n\t */ _lastAutoParagraph = null;\n    /**\n\t * The array of nodes that should be cleaned of not allowed attributes.\n\t */ _filterAttributesOf = [];\n    /**\n\t * Beginning of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t */ _affectedStart = null;\n    /**\n\t * End of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t */ _affectedEnd = null;\n    _nodeToSelect = null;\n    constructor(model, writer, position){\n        this.model = model;\n        this.writer = writer;\n        this.position = position;\n        this.canMergeWith = new Set([\n            this.position.parent\n        ]);\n        this.schema = model.schema;\n        this._documentFragment = writer.createDocumentFragment();\n        this._documentFragmentPosition = writer.createPositionAt(this._documentFragment, 0);\n    }\n    /**\n\t * Handles insertion of a set of nodes.\n\t *\n\t * @param nodes Nodes to insert.\n\t */ handleNodes(nodes) {\n        for (const node of Array.from(nodes)){\n            this._handleNode(node);\n        }\n        // Insert nodes collected in temporary DocumentFragment.\n        this._insertPartialFragment();\n        // If there was an auto paragraph then we might need to adjust the end of insertion.\n        if (this._lastAutoParagraph) {\n            this._updateLastNodeFromAutoParagraph(this._lastAutoParagraph);\n        }\n        // After the content was inserted we may try to merge it with its next sibling if the selection was in it initially.\n        // Merging with the previous sibling was performed just after inserting the first node to the document.\n        this._mergeOnRight();\n        // TMP this will become a post-fixer.\n        this.schema.removeDisallowedAttributes(this._filterAttributesOf, this.writer);\n        this._filterAttributesOf = [];\n    }\n    /**\n\t * Updates the last node after the auto paragraphing.\n\t *\n\t * @param node The last auto paragraphing node.\n\t */ _updateLastNodeFromAutoParagraph(node) {\n        const positionAfterLastNode = this.writer.createPositionAfter(this._lastNode);\n        const positionAfterNode = this.writer.createPositionAfter(node);\n        // If the real end was after the last auto paragraph then update relevant properties.\n        if (positionAfterNode.isAfter(positionAfterLastNode)) {\n            this._lastNode = node;\n            /* istanbul ignore if -- @preserve */ if (this.position.parent != node || !this.position.isAtEnd) {\n                // Algorithm's correctness check. We should never end up here but it's good to know that we did.\n                // At this point the insertion position should be at the end of the last auto paragraph.\n                // Note: This error is documented in other place in this file.\n                throw new CKEditorError('insertcontent-invalid-insertion-position', this);\n            }\n            this.position = positionAfterNode;\n            this._setAffectedBoundaries(this.position);\n        }\n    }\n    /**\n\t * Returns range to be selected after insertion.\n\t * Returns `null` if there is no valid range to select after insertion.\n\t */ getSelectionRange() {\n        if (this._nodeToSelect) {\n            return Range._createOn(this._nodeToSelect);\n        }\n        return this.model.schema.getNearestSelectionRange(this.position);\n    }\n    /**\n\t * Returns a range which contains all the performed changes. This is a range that, if removed, would return the model to the state\n\t * before the insertion. Returns `null` if no changes were done.\n\t */ getAffectedRange() {\n        if (!this._affectedStart) {\n            return null;\n        }\n        return new Range(this._affectedStart, this._affectedEnd);\n    }\n    /**\n\t * Destroys `Insertion` instance.\n\t */ destroy() {\n        if (this._affectedStart) {\n            this._affectedStart.detach();\n        }\n        if (this._affectedEnd) {\n            this._affectedEnd.detach();\n        }\n    }\n    /**\n\t * Handles insertion of a single node.\n\t */ _handleNode(node) {\n        // Split the position.parent's branch up to a point where the node can be inserted.\n        // If it isn't allowed in the whole branch, then of course don't split anything.\n        if (!this._checkAndSplitToAllowedPosition(node)) {\n            // Handle element children if it's not an object (strip container).\n            if (!this.schema.isObject(node)) {\n                this._handleDisallowedNode(node);\n            }\n            return;\n        }\n        // Add node to the current temporary DocumentFragment.\n        this._appendToFragment(node);\n        // Store the first and last nodes for easy access for merging with sibling nodes.\n        if (!this._firstNode) {\n            this._firstNode = node;\n        }\n        this._lastNode = node;\n    }\n    /**\n\t * Inserts the temporary DocumentFragment into the model.\n\t */ _insertPartialFragment() {\n        if (this._documentFragment.isEmpty) {\n            return;\n        }\n        const livePosition = LivePosition.fromPosition(this.position, 'toNext');\n        this._setAffectedBoundaries(this.position);\n        // If the very first node of the whole insertion process is inserted, insert it separately for OT reasons (undo).\n        // Note: there can be multiple calls to `_insertPartialFragment()` during one insertion process.\n        // Note: only the very first node can be merged so we have to do separate operation only for it.\n        if (this._documentFragment.getChild(0) == this._firstNode) {\n            this.writer.insert(this._firstNode, this.position);\n            // We must merge the first node just after inserting it to avoid problems with OT.\n            // (See: https://github.com/ckeditor/ckeditor5/pull/8773#issuecomment-760945652).\n            this._mergeOnLeft();\n            this.position = livePosition.toPosition();\n        }\n        // Insert the remaining nodes from document fragment.\n        if (!this._documentFragment.isEmpty) {\n            this.writer.insert(this._documentFragment, this.position);\n        }\n        this._documentFragmentPosition = this.writer.createPositionAt(this._documentFragment, 0);\n        this.position = livePosition.toPosition();\n        livePosition.detach();\n    }\n    /**\n\t * @param node The disallowed node which needs to be handled.\n\t */ _handleDisallowedNode(node) {\n        // If the node is an element, try inserting its children (strip the parent).\n        if (node.is('element')) {\n            this.handleNodes(node.getChildren());\n        }\n    }\n    /**\n\t * Append a node to the temporary DocumentFragment.\n\t *\n\t * @param node The node to insert.\n\t */ _appendToFragment(node) {\n        /* istanbul ignore if -- @preserve */ if (!this.schema.checkChild(this.position, node)) {\n            // Algorithm's correctness check. We should never end up here but it's good to know that we did.\n            // Note that it would often be a silent issue if we insert node in a place where it's not allowed.\n            /**\n\t\t\t * Given node cannot be inserted on the given position.\n\t\t\t *\n\t\t\t * @error insertcontent-wrong-position\n\t\t\t * @param node Node to insert.\n\t\t\t * @param position Position to insert the node at.\n\t\t\t */ throw new CKEditorError('insertcontent-wrong-position', this, {\n                node,\n                position: this.position\n            });\n        }\n        this.writer.insert(node, this._documentFragmentPosition);\n        this._documentFragmentPosition = this._documentFragmentPosition.getShiftedBy(node.offsetSize);\n        // The last inserted object should be selected because we can't put a collapsed selection after it.\n        if (this.schema.isObject(node) && !this.schema.checkChild(this.position, '$text')) {\n            this._nodeToSelect = node;\n        } else {\n            this._nodeToSelect = null;\n        }\n        this._filterAttributesOf.push(node);\n    }\n    /**\n\t * Sets `_affectedStart` and `_affectedEnd` to the given `position`. Should be used before a change is done during insertion process to\n\t * mark the affected range.\n\t *\n\t * This method is used before inserting a node or splitting a parent node. `_affectedStart` and `_affectedEnd` are also changed\n\t * during merging, but the logic there is more complicated so it is left out of this function.\n\t */ _setAffectedBoundaries(position) {\n        // Set affected boundaries stickiness so that those position will \"expand\" when something is inserted in between them:\n        // <paragraph>Foo][bar</paragraph> -> <paragraph>Foo]xx[bar</paragraph>\n        // This is why it cannot be a range but two separate positions.\n        if (!this._affectedStart) {\n            this._affectedStart = LivePosition.fromPosition(position, 'toPrevious');\n        }\n        // If `_affectedEnd` is before the new boundary position, expand `_affectedEnd`. This can happen if first inserted node was\n        // inserted into the parent but the next node is moved-out of that parent:\n        // (1) <paragraph>Foo][</paragraph> -> <paragraph>Foo]xx[</paragraph>\n        // (2) <paragraph>Foo]xx[</paragraph> -> <paragraph>Foo]xx</paragraph><widget></widget>[\n        if (!this._affectedEnd || this._affectedEnd.isBefore(position)) {\n            if (this._affectedEnd) {\n                this._affectedEnd.detach();\n            }\n            this._affectedEnd = LivePosition.fromPosition(position, 'toNext');\n        }\n    }\n    /**\n\t * Merges the previous sibling of the first node if it should be merged.\n\t *\n\t * After the content was inserted we may try to merge it with its siblings.\n\t * This should happen only if the selection was in those elements initially.\n\t */ _mergeOnLeft() {\n        const node = this._firstNode;\n        if (!(node instanceof Element)) {\n            return;\n        }\n        if (!this._canMergeLeft(node)) {\n            return;\n        }\n        const mergePosLeft = LivePosition._createBefore(node);\n        mergePosLeft.stickiness = 'toNext';\n        const livePosition = LivePosition.fromPosition(this.position, 'toNext');\n        // If `_affectedStart` is sames as merge position, it means that the element \"marked\" by `_affectedStart` is going to be\n        // removed and its contents will be moved. This won't transform `LivePosition` so `_affectedStart` needs to be moved\n        // by hand to properly reflect affected range. (Due to `_affectedStart` and `_affectedEnd` stickiness, the \"range\" is\n        // shown as `][`).\n        //\n        // Example - insert `<paragraph>Abc</paragraph><paragraph>Xyz</paragraph>` at the end of `<paragraph>Foo^</paragraph>`:\n        //\n        // <paragraph>Foo</paragraph><paragraph>Bar</paragraph>   -->\n        // <paragraph>Foo</paragraph>]<paragraph>Abc</paragraph><paragraph>Xyz</paragraph>[<paragraph>Bar</paragraph>   -->\n        // <paragraph>Foo]Abc</paragraph><paragraph>Xyz</paragraph>[<paragraph>Bar</paragraph>\n        //\n        // Note, that if we are here then something must have been inserted, so `_affectedStart` and `_affectedEnd` have to be set.\n        if (this._affectedStart.isEqual(mergePosLeft)) {\n            this._affectedStart.detach();\n            this._affectedStart = LivePosition._createAt(mergePosLeft.nodeBefore, 'end', 'toPrevious');\n        }\n        // We need to update the references to the first and last nodes if they will be merged into the previous sibling node\n        // because the reference would point to the removed node.\n        //\n        // <p>A^A</p> + <p>X</p>\n        //\n        // <p>A</p>^<p>A</p>\n        // <p>A</p><p>X</p><p>A</p>\n        // <p>AX</p><p>A</p>\n        // <p>AXA</p>\n        if (this._firstNode === this._lastNode) {\n            this._firstNode = mergePosLeft.nodeBefore;\n            this._lastNode = mergePosLeft.nodeBefore;\n        }\n        this.writer.merge(mergePosLeft);\n        // If only one element (the merged one) is in the \"affected range\", also move the affected range end appropriately.\n        //\n        // Example - insert `<paragraph>Abc</paragraph>` at the of `<paragraph>Foo^</paragraph>`:\n        //\n        // <paragraph>Foo</paragraph><paragraph>Bar</paragraph>   -->\n        // <paragraph>Foo</paragraph>]<paragraph>Abc</paragraph>[<paragraph>Bar</paragraph>   -->\n        // <paragraph>Foo]Abc</paragraph>[<paragraph>Bar</paragraph>   -->\n        // <paragraph>Foo]Abc[</paragraph><paragraph>Bar</paragraph>\n        if (mergePosLeft.isEqual(this._affectedEnd) && this._firstNode === this._lastNode) {\n            this._affectedEnd.detach();\n            this._affectedEnd = LivePosition._createAt(mergePosLeft.nodeBefore, 'end', 'toNext');\n        }\n        this.position = livePosition.toPosition();\n        livePosition.detach();\n        // After merge elements that were marked by _insert() to be filtered might be gone so\n        // we need to mark the new container.\n        this._filterAttributesOf.push(this.position.parent);\n        mergePosLeft.detach();\n    }\n    /**\n\t * Merges the next sibling of the last node if it should be merged.\n\t *\n\t * After the content was inserted we may try to merge it with its siblings.\n\t * This should happen only if the selection was in those elements initially.\n\t */ _mergeOnRight() {\n        const node = this._lastNode;\n        if (!(node instanceof Element)) {\n            return;\n        }\n        if (!this._canMergeRight(node)) {\n            return;\n        }\n        const mergePosRight = LivePosition._createAfter(node);\n        mergePosRight.stickiness = 'toNext';\n        /* istanbul ignore if -- @preserve */ if (!this.position.isEqual(mergePosRight)) {\n            // Algorithm's correctness check. We should never end up here but it's good to know that we did.\n            // At this point the insertion position should be after the node we'll merge. If it isn't,\n            // it should need to be secured as in the left merge case.\n            /**\n\t\t\t * An internal error occurred when merging inserted content with its siblings.\n\t\t\t * The insertion position should equal the merge position.\n\t\t\t *\n\t\t\t * If you encountered this error, report it back to the CKEditor 5 team\n\t\t\t * with as many details as possible regarding the content being inserted and the insertion position.\n\t\t\t *\n\t\t\t * @error insertcontent-invalid-insertion-position\n\t\t\t */ throw new CKEditorError('insertcontent-invalid-insertion-position', this);\n        }\n        // Move the position to the previous node, so it isn't moved to the graveyard on merge.\n        // <p>x</p>[]<p>y</p> => <p>x[]</p><p>y</p>\n        this.position = Position._createAt(mergePosRight.nodeBefore, 'end');\n        // Explanation of setting position stickiness to `'toPrevious'`:\n        // OK:  <p>xx[]</p> + <p>yy</p> => <p>xx[]yy</p> (when sticks to previous)\n        // NOK: <p>xx[]</p> + <p>yy</p> => <p>xxyy[]</p> (when sticks to next)\n        const livePosition = LivePosition.fromPosition(this.position, 'toPrevious');\n        // See comment in `_mergeOnLeft()` on moving `_affectedStart`.\n        if (this._affectedEnd.isEqual(mergePosRight)) {\n            this._affectedEnd.detach();\n            this._affectedEnd = LivePosition._createAt(mergePosRight.nodeBefore, 'end', 'toNext');\n        }\n        // We need to update the references to the first and last nodes if they will be merged into the previous sibling node\n        // because the reference would point to the removed node.\n        //\n        // <p>A^A</p> + <p>X</p>\n        //\n        // <p>A</p>^<p>A</p>\n        // <p>A</p><p>X</p><p>A</p>\n        // <p>AX</p><p>A</p>\n        // <p>AXA</p>\n        if (this._firstNode === this._lastNode) {\n            this._firstNode = mergePosRight.nodeBefore;\n            this._lastNode = mergePosRight.nodeBefore;\n        }\n        this.writer.merge(mergePosRight);\n        // See comment in `_mergeOnLeft()` on moving `_affectedStart`.\n        if (mergePosRight.getShiftedBy(-1).isEqual(this._affectedStart) && this._firstNode === this._lastNode) {\n            this._affectedStart.detach();\n            this._affectedStart = LivePosition._createAt(mergePosRight.nodeBefore, 0, 'toPrevious');\n        }\n        this.position = livePosition.toPosition();\n        livePosition.detach();\n        // After merge elements that were marked by _insert() to be filtered might be gone so\n        // we need to mark the new container.\n        this._filterAttributesOf.push(this.position.parent);\n        mergePosRight.detach();\n    }\n    /**\n\t * Checks whether specified node can be merged with previous sibling element.\n\t *\n\t * @param node The node which could potentially be merged.\n\t */ _canMergeLeft(node) {\n        const previousSibling = node.previousSibling;\n        return previousSibling instanceof Element && this.canMergeWith.has(previousSibling) && this.model.schema.checkMerge(previousSibling, node);\n    }\n    /**\n\t * Checks whether specified node can be merged with next sibling element.\n\t *\n\t * @param node The node which could potentially be merged.\n\t */ _canMergeRight(node) {\n        const nextSibling = node.nextSibling;\n        return nextSibling instanceof Element && this.canMergeWith.has(nextSibling) && this.model.schema.checkMerge(node, nextSibling);\n    }\n    /**\n\t * Inserts a paragraph and moves the insertion position into it.\n\t */ _insertAutoParagraph() {\n        // Insert nodes collected in temporary DocumentFragment if the position parent needs change to process further nodes.\n        this._insertPartialFragment();\n        // Insert a paragraph and move insertion position to it.\n        const paragraph = this.writer.createElement('paragraph');\n        this.writer.insert(paragraph, this.position);\n        this._setAffectedBoundaries(this.position);\n        this._lastAutoParagraph = paragraph;\n        this.position = this.writer.createPositionAt(paragraph, 0);\n    }\n    /**\n\t * @returns Whether an allowed position was found.\n\t * `false` is returned if the node isn't allowed at any position up in the tree, `true` if was.\n\t */ _checkAndSplitToAllowedPosition(node) {\n        const allowedIn = this._getAllowedIn(this.position.parent, node);\n        if (!allowedIn) {\n            return false;\n        }\n        // Insert nodes collected in temporary DocumentFragment if the position parent needs change to process further nodes.\n        if (allowedIn != this.position.parent) {\n            this._insertPartialFragment();\n        }\n        while(allowedIn != this.position.parent){\n            if (this.position.isAtStart) {\n                // If insertion position is at the beginning of the parent, move it out instead of splitting.\n                // <p>^Foo</p> -> ^<p>Foo</p>\n                const parent = this.position.parent;\n                this.position = this.writer.createPositionBefore(parent);\n                // Special case – parent is empty (<p>^</p>).\n                //\n                // 1. parent.isEmpty\n                // We can remove the element after moving insertion position out of it.\n                //\n                // 2. parent.parent === allowedIn\n                // However parent should remain in place when allowed element is above limit element in document tree.\n                // For example there shouldn't be allowed to remove empty paragraph from tableCell, when is pasted\n                // content allowed in $root.\n                if (parent.isEmpty && parent.parent === allowedIn) {\n                    this.writer.remove(parent);\n                }\n            } else if (this.position.isAtEnd) {\n                // If insertion position is at the end of the parent, move it out instead of splitting.\n                // <p>Foo^</p> -> <p>Foo</p>^\n                this.position = this.writer.createPositionAfter(this.position.parent);\n            } else {\n                const tempPos = this.writer.createPositionAfter(this.position.parent);\n                this._setAffectedBoundaries(this.position);\n                this.writer.split(this.position);\n                this.position = tempPos;\n                this.canMergeWith.add(this.position.nodeAfter);\n            }\n        }\n        // At this point, we split elements up to the parent in which `node` is allowed.\n        // Note that `_getAllowedIn()` checks if the `node` is allowed either directly, or when auto-paragraphed.\n        // So, let's check if the `node` is allowed directly. If not, we need to auto-paragraph it.\n        if (!this.schema.checkChild(this.position.parent, node)) {\n            this._insertAutoParagraph();\n        }\n        return true;\n    }\n    /**\n\t * Gets the element in which the given node is allowed. It checks the passed element and all its ancestors.\n\t *\n\t * It also verifies if auto-paragraphing could help.\n\t *\n\t * @param contextElement The element in which context the node should be checked.\n\t * @param childNode The node to check.\n\t */ _getAllowedIn(contextElement, childNode) {\n        // Check if a node can be inserted in the given context...\n        if (this.schema.checkChild(contextElement, childNode)) {\n            return contextElement;\n        }\n        // ...or it would be accepted if a paragraph would be inserted.\n        if (this.schema.checkChild(contextElement, 'paragraph') && this.schema.checkChild('paragraph', childNode)) {\n            return contextElement;\n        }\n        // If the child wasn't allowed in the context element and the element is a limit there's no point in\n        // checking any further towards the root. This is it: the limit is unsplittable and there's nothing\n        // we can do about it. Without this check, the algorithm will analyze parent of the limit and may create\n        // an illusion of the child being allowed. There's no way to insert it down there, though. It results in\n        // infinite loops.\n        if (this.schema.isLimit(contextElement)) {\n            return null;\n        }\n        return this._getAllowedIn(contextElement.parent, childNode);\n    }\n}\n\n/**\n * Inserts an {@glink framework/deep-dive/schema#object-elements object element} at a specific position in the editor content.\n *\n * **Note:** Use {@link module:engine/model/model~Model#insertObject} instead of this function.\n * This function is only exposed to be reusable in algorithms which change the {@link module:engine/model/model~Model#insertObject}\n * method's behavior.\n *\n * **Note**: For more documentation and examples, see {@link module:engine/model/model~Model#insertObject}.\n *\n * @param model The model in context of which the insertion should be performed.\n * @param object An object to be inserted into the model document.\n * @param selectable A selectable where the content should be inserted. If not specified, the current\n * {@link module:engine/model/document~Document#selection document selection} will be used instead.\n * @param placeOrOffset Specifies the exact place or offset for the insertion to take place, relative to `selectable`.\n * @param options Additional options.\n * @param options.findOptimalPosition An option that, when set, adjusts the insertion position (relative to\n * `selectable` and `placeOrOffset`) so that the content of `selectable` is not split upon insertion (a.k.a. non-destructive insertion).\n * * When `'auto'`, the algorithm will decide whether to insert the object before or after `selectable` to avoid content splitting.\n * * When `'before'`, the closest position before `selectable` will be used that will not result in content splitting.\n * * When `'after'`, the closest position after `selectable` will be used that will not result in content splitting.\n *\n * Note that this option works only for block objects. Inline objects are inserted into text and do not split blocks.\n * @param options.setSelection An option that, when set, moves the\n * {@link module:engine/model/document~Document#selection document selection} after inserting the object.\n * * When `'on'`, the document selection will be set on the inserted object.\n * * When `'after'`, the document selection will move to the closest text node after the inserted object. If there is no\n * such text node, a paragraph will be created and the document selection will be moved inside it.\n * @returns A range which contains all the performed changes. This is a range that, if removed,\n * would return the model to the state before the insertion. If no changes were preformed by `insertObject()`, returns a range collapsed\n * at the insertion position.\n */ function insertObject(model, object, selectable, options = {}) {\n    if (!model.schema.isObject(object)) {\n        /**\n\t\t * Tried to insert an element with {@link module:engine/model/utils/insertobject insertObject()} function\n\t\t * that is not defined as an object in schema.\n\t\t * See {@link module:engine/model/schema~SchemaItemDefinition#isObject `SchemaItemDefinition`}.\n\t\t * If you want to insert content that is not an object you might want to use\n\t\t * {@link module:engine/model/utils/insertcontent insertContent()} function.\n\t\t * @error insertobject-element-not-an-object\n\t\t */ throw new CKEditorError('insertobject-element-not-an-object', model, {\n            object\n        });\n    }\n    // Normalize selectable to a selection instance.\n    const originalSelection = selectable ? selectable : model.document.selection;\n    // Adjust the insertion selection.\n    let insertionSelection = originalSelection;\n    if (options.findOptimalPosition && model.schema.isBlock(object)) {\n        insertionSelection = model.createSelection(model.schema.findOptimalInsertionRange(originalSelection, options.findOptimalPosition));\n    }\n    // Collect attributes to be copied on the inserted object.\n    const firstSelectedBlock = first(originalSelection.getSelectedBlocks());\n    const attributesToCopy = {};\n    if (firstSelectedBlock) {\n        Object.assign(attributesToCopy, model.schema.getAttributesWithProperty(firstSelectedBlock, 'copyOnReplace', true));\n    }\n    return model.change((writer)=>{\n        // Remove the selected content to find out what the parent of the inserted object would be.\n        // It would be removed inside model.insertContent() anyway.\n        if (!insertionSelection.isCollapsed) {\n            model.deleteContent(insertionSelection, {\n                doNotAutoparagraph: true\n            });\n        }\n        let elementToInsert = object;\n        const insertionPositionParent = insertionSelection.anchor.parent;\n        // Autoparagraphing of an inline objects.\n        if (!model.schema.checkChild(insertionPositionParent, object) && model.schema.checkChild(insertionPositionParent, 'paragraph') && model.schema.checkChild('paragraph', object)) {\n            elementToInsert = writer.createElement('paragraph');\n            writer.insert(object, elementToInsert);\n        }\n        // Apply attributes that are allowed on the inserted object (or paragraph if autoparagraphed).\n        model.schema.setAllowedAttributes(elementToInsert, attributesToCopy, writer);\n        // Insert the prepared content at the optionally adjusted selection.\n        const affectedRange = model.insertContent(elementToInsert, insertionSelection);\n        // Nothing got inserted.\n        if (affectedRange.isCollapsed) {\n            return affectedRange;\n        }\n        if (options.setSelection) {\n            updateSelection(writer, object, options.setSelection, attributesToCopy);\n        }\n        return affectedRange;\n    });\n}\n/**\n * Updates document selection based on given `place` parameter in relation to `contextElement` element.\n *\n * @param writer An instance of the model writer.\n * @param contextElement An element to set the attributes on.\n * @param place The place where selection should be set in relation to the `contextElement` element.\n * Value `on` will set selection on the passed `contextElement`. Value `after` will set selection after `contextElement`.\n * @param attributes Attributes keys and values to set on a paragraph that this function can create when\n * `place` parameter is equal to `after` but there is no element with `$text` node to set selection in.\n */ function updateSelection(writer, contextElement, place, paragraphAttributes) {\n    const model = writer.model;\n    if (place == 'on') {\n        writer.setSelection(contextElement, 'on');\n        return;\n    }\n    if (place != 'after') {\n        /**\n\t\t * The unsupported `options.setSelection` parameter was passed\n\t\t * to the {@link module:engine/model/utils/insertobject insertObject()} function.\n\t\t * Check the {@link module:engine/model/utils/insertobject insertObject()} API documentation for allowed\n\t\t * `options.setSelection` parameter values.\n\t\t *\n\t\t * @error insertobject-invalid-place-parameter-value\n\t\t */ throw new CKEditorError('insertobject-invalid-place-parameter-value', model);\n    }\n    let nextElement = contextElement.nextSibling;\n    if (model.schema.isInline(contextElement)) {\n        writer.setSelection(contextElement, 'after');\n        return;\n    }\n    // Check whether an element next to the inserted element is defined and can contain a text.\n    const canSetSelection = nextElement && model.schema.checkChild(nextElement, '$text');\n    // If the element is missing, but a paragraph could be inserted next to the element, let's add it.\n    if (!canSetSelection && model.schema.checkChild(contextElement.parent, 'paragraph')) {\n        nextElement = writer.createElement('paragraph');\n        model.schema.setAllowedAttributes(nextElement, paragraphAttributes, writer);\n        model.insertContent(nextElement, writer.createPositionAfter(contextElement));\n    }\n    // Put the selection inside the element, at the beginning.\n    if (nextElement) {\n        writer.setSelection(nextElement, 0);\n    }\n}\n\nconst wordBoundaryCharacters = ' ,.?!:;\"-()';\n/**\n * Modifies the selection. Currently, the supported modifications are:\n *\n * * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n * Possible values for `unit` are:\n *  * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n *  character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n *  with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n *  letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n *  selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n *  why `'character'` value is most natural and common method of modifying selection.\n *  * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n *  selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n *  However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n *  two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n *  For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n *  outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n *  extension will include whole \"surrogate pair\".\n *  * `'word'` - moves selection by a whole word.\n *\n * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n *\n * **Note:** Use {@link module:engine/model/model~Model#modifySelection} instead of this function.\n * This function is only exposed to be reusable in algorithms\n * which change the {@link module:engine/model/model~Model#modifySelection}\n * method's behavior.\n *\n * @param model The model in context of which the selection modification should be performed.\n * @param selection The selection to modify.\n * @param options.direction The direction in which the selection should be modified. Default 'forward'.\n * @param options.unit The unit by which selection should be modified. Default 'character'.\n * @param options.treatEmojiAsSingleUnit Whether multi-characer emoji sequences should be handled as single unit.\n */ function modifySelection(model, selection, options = {}) {\n    const schema = model.schema;\n    const isForward = options.direction != 'backward';\n    const unit = options.unit ? options.unit : 'character';\n    const treatEmojiAsSingleUnit = !!options.treatEmojiAsSingleUnit;\n    const focus = selection.focus;\n    const walker = new TreeWalker({\n        boundaries: getSearchRange(focus, isForward),\n        singleCharacters: true,\n        direction: isForward ? 'forward' : 'backward'\n    });\n    const data = {\n        walker,\n        schema,\n        isForward,\n        unit,\n        treatEmojiAsSingleUnit\n    };\n    let next;\n    while(next = walker.next()){\n        if (next.done) {\n            return;\n        }\n        const position = tryExtendingTo(data, next.value);\n        if (position) {\n            if (selection instanceof DocumentSelection) {\n                model.change((writer)=>{\n                    writer.setSelectionFocus(position);\n                });\n            } else {\n                selection.setFocus(position);\n            }\n            return;\n        }\n    }\n}\n/**\n * Checks whether the selection can be extended to the the walker's next value (next position).\n */ function tryExtendingTo(data, value) {\n    const { isForward, walker, unit, schema, treatEmojiAsSingleUnit } = data;\n    const { type, item, nextPosition } = value;\n    // If found text, we can certainly put the focus in it. Let's just find a correct position\n    // based on the unit.\n    if (type == 'text') {\n        if (data.unit === 'word') {\n            return getCorrectWordBreakPosition(walker, isForward);\n        }\n        return getCorrectPosition(walker, unit, treatEmojiAsSingleUnit);\n    }\n    // Entering an element.\n    if (type == (isForward ? 'elementStart' : 'elementEnd')) {\n        // If it's a selectable, we can select it now.\n        if (schema.isSelectable(item)) {\n            return Position._createAt(item, isForward ? 'after' : 'before');\n        }\n        // If text allowed on this position, extend to this place.\n        if (schema.checkChild(nextPosition, '$text')) {\n            return nextPosition;\n        }\n    } else {\n        // If leaving a limit element, stop.\n        if (schema.isLimit(item)) {\n            // NOTE: Fast-forward the walker until the end.\n            walker.skip(()=>true);\n            return;\n        }\n        // If text allowed on this position, extend to this place.\n        if (schema.checkChild(nextPosition, '$text')) {\n            return nextPosition;\n        }\n    }\n}\n/**\n * Finds a correct position by walking in a text node and checking whether selection can be extended to given position\n * or should be extended further.\n */ function getCorrectPosition(walker, unit, treatEmojiAsSingleUnit) {\n    const textNode = walker.position.textNode;\n    if (textNode) {\n        const data = textNode.data;\n        let offset = walker.position.offset - textNode.startOffset;\n        while(isInsideSurrogatePair(data, offset) || unit == 'character' && isInsideCombinedSymbol(data, offset) || treatEmojiAsSingleUnit && isInsideEmojiSequence(data, offset)){\n            walker.next();\n            offset = walker.position.offset - textNode.startOffset;\n        }\n    }\n    return walker.position;\n}\n/**\n * Finds a correct position of a word break by walking in a text node and checking whether selection can be extended to given position\n * or should be extended further.\n */ function getCorrectWordBreakPosition(walker, isForward) {\n    let textNode = walker.position.textNode;\n    if (!textNode) {\n        textNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;\n    }\n    while(textNode && textNode.is('$text')){\n        const offset = walker.position.offset - textNode.startOffset;\n        // Check of adjacent text nodes with different attributes (like BOLD).\n        // Example          : 'foofoo []bar<$text bold=\"true\">bar</$text> bazbaz'\n        // should expand to : 'foofoo [bar<$text bold=\"true\">bar</$text>] bazbaz'.\n        if (isAtNodeBoundary(textNode, offset, isForward)) {\n            textNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;\n        } else if (isAtWordBoundary(textNode.data, offset, isForward)) {\n            break;\n        } else {\n            walker.next();\n        }\n    }\n    return walker.position;\n}\nfunction getSearchRange(start, isForward) {\n    const root = start.root;\n    const searchEnd = Position._createAt(root, isForward ? 'end' : 0);\n    if (isForward) {\n        return new Range(start, searchEnd);\n    } else {\n        return new Range(searchEnd, start);\n    }\n}\n/**\n * Checks if selection is on word boundary.\n */ function isAtWordBoundary(data, offset, isForward) {\n    // The offset to check depends on direction.\n    const offsetToCheck = offset + (isForward ? 0 : -1);\n    return wordBoundaryCharacters.includes(data.charAt(offsetToCheck));\n}\n/**\n * Checks if selection is on node boundary.\n */ function isAtNodeBoundary(textNode, offset, isForward) {\n    return offset === (isForward ? textNode.offsetSize : 0);\n}\n\n// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' );\n// @if CK_DEBUG_ENGINE // const { OperationReplayer } = require( '../dev-utils/operationreplayer' ).default;\n/**\n * Editor's data model. Read about the model in the\n * {@glink framework/architecture/editing-engine engine architecture} guide.\n */ class Model extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * Model's marker collection.\n\t */ markers;\n    /**\n\t * Model's document.\n\t */ document;\n    /**\n\t * Model's schema.\n\t */ schema;\n    /**\n\t * All callbacks added by {@link module:engine/model/model~Model#change} or\n\t * {@link module:engine/model/model~Model#enqueueChange} methods waiting to be executed.\n\t */ _pendingChanges;\n    /**\n\t * The last created and currently used writer instance.\n\t */ _currentWriter;\n    // @if CK_DEBUG_ENGINE // private _operationLogs: Array<string>;\n    // @if CK_DEBUG_ENGINE // private _appliedOperations: Array<Operation>;\n    constructor(){\n        super();\n        this.markers = new MarkerCollection();\n        this.document = new Document(this);\n        this.schema = new Schema();\n        this._pendingChanges = [];\n        this._currentWriter = null;\n        [\n            'deleteContent',\n            'modifySelection',\n            'getSelectedContent',\n            'applyOperation'\n        ].forEach((methodName)=>this.decorate(methodName));\n        // Adding operation validation with `highest` priority, so it is called before any other feature would like\n        // to do anything with the operation. If the operation has incorrect parameters it should throw on the earliest occasion.\n        this.on('applyOperation', (evt, args)=>{\n            const operation = args[0];\n            operation._validate();\n        }, {\n            priority: 'highest'\n        });\n        // Register some default abstract entities.\n        this.schema.register('$root', {\n            isLimit: true\n        });\n        this.schema.register('$container', {\n            allowIn: [\n                '$root',\n                '$container'\n            ]\n        });\n        this.schema.register('$block', {\n            allowIn: [\n                '$root',\n                '$container'\n            ],\n            isBlock: true\n        });\n        this.schema.register('$blockObject', {\n            allowWhere: '$block',\n            isBlock: true,\n            isObject: true\n        });\n        this.schema.register('$inlineObject', {\n            allowWhere: '$text',\n            allowAttributesOf: '$text',\n            isInline: true,\n            isObject: true\n        });\n        this.schema.register('$text', {\n            allowIn: '$block',\n            isInline: true,\n            isContent: true\n        });\n        this.schema.register('$clipboardHolder', {\n            allowContentOf: '$root',\n            allowChildren: '$text',\n            isLimit: true\n        });\n        this.schema.register('$documentFragment', {\n            allowContentOf: '$root',\n            allowChildren: '$text',\n            isLimit: true\n        });\n        // An element needed by the `upcastElementToMarker` converter.\n        // This element temporarily represents a marker boundary during the conversion process and is removed\n        // at the end of the conversion. `UpcastDispatcher` or at least `Conversion` class looks like a\n        // better place for this registration but both know nothing about `Schema`.\n        this.schema.register('$marker');\n        this.schema.addChildCheck(()=>true, '$marker'); // Allow everywhere.\n        injectSelectionPostFixer(this);\n        // Post-fixer which takes care of adding empty paragraph elements to the empty roots.\n        this.document.registerPostFixer(autoParagraphEmptyRoots);\n        // The base implementation for \"decorated\" method with remapped arguments.\n        this.on('insertContent', (evt, [content, selectable])=>{\n            evt.return = insertContent(this, content, selectable);\n        });\n        // The base implementation for \"decorated\" method with remapped arguments.\n        this.on('insertObject', (evt, [element, selection, options])=>{\n            evt.return = insertObject(this, element, selection, options);\n        });\n        // The base implementation for \"decorated\" method with remapped arguments.\n        this.on('canEditAt', (evt)=>{\n            const canEditAt = !this.document.isReadOnly;\n            evt.return = canEditAt;\n            if (!canEditAt) {\n                // Prevent further processing if the selection is at non-editable place.\n                evt.stop();\n            }\n        });\n    // @if CK_DEBUG_ENGINE // initDocumentDumping( this.document );\n    // @if CK_DEBUG_ENGINE // this.on( 'applyOperation', () => {\n    // @if CK_DEBUG_ENGINE // \tdumpTrees( this.document, this.document.version );\n    // @if CK_DEBUG_ENGINE // }, { priority: 'lowest' } );\n    // @if CK_DEBUG_ENGINE // this._operationLogs = [];\n    // @if CK_DEBUG_ENGINE // this._appliedOperations = [];\n    }\n    /**\n\t * The `change()` method is the primary way of changing the model. You should use it to modify all document nodes\n\t * (including detached nodes – i.e. nodes not added to the {@link module:engine/model/model~Model#document model document}),\n\t * the {@link module:engine/model/document~Document#selection document's selection}, and\n\t * {@link module:engine/model/model~Model#markers model markers}.\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \twriter.insertText( 'foo', paragraph, 'end' );\n\t * } );\n\t * ```\n\t *\n\t * All changes inside the change block use the same {@link module:engine/model/batch~Batch} so they are combined\n\t * into a single undo step.\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \twriter.insertText( 'foo', paragraph, 'end' ); // foo.\n\t *\n\t * \tmodel.change( writer => {\n\t * \t\twriter.insertText( 'bar', paragraph, 'end' ); // foobar.\n\t * \t} );\n\t *\n\t * \twriter.insertText( 'bom', paragraph, 'end' ); // foobarbom.\n\t * } );\n\t * ```\n\t *\n\t * The callback of the `change()` block is executed synchronously.\n\t *\n\t * You can also return a value from the change block.\n\t *\n\t * ```ts\n\t * const img = model.change( writer => {\n\t * \treturn writer.createElement( 'img' );\n\t * } );\n\t * ```\n\t *\n\t * @see #enqueueChange\n\t * @typeParam TReturn The return type of the provided callback.\n\t * @param callback Callback function which may modify the model.\n\t */ change(callback) {\n        try {\n            if (this._pendingChanges.length === 0) {\n                // If this is the outermost block, create a new batch and start `_runPendingChanges` execution flow.\n                this._pendingChanges.push({\n                    batch: new Batch(),\n                    callback\n                });\n                return this._runPendingChanges()[0];\n            } else {\n                // If this is not the outermost block, just execute the callback.\n                return callback(this._currentWriter);\n            }\n        } catch (err) {\n            // @if CK_DEBUG // throw err;\n            /* istanbul ignore next -- @preserve */ CKEditorError.rethrowUnexpectedError(err, this);\n        }\n    }\n    enqueueChange(batchOrType, callback) {\n        try {\n            if (!batchOrType) {\n                batchOrType = new Batch();\n            } else if (typeof batchOrType === 'function') {\n                callback = batchOrType;\n                batchOrType = new Batch();\n            } else if (!(batchOrType instanceof Batch)) {\n                batchOrType = new Batch(batchOrType);\n            }\n            this._pendingChanges.push({\n                batch: batchOrType,\n                callback\n            });\n            if (this._pendingChanges.length == 1) {\n                this._runPendingChanges();\n            }\n        } catch (err) {\n            // @if CK_DEBUG // throw err;\n            /* istanbul ignore next -- @preserve */ CKEditorError.rethrowUnexpectedError(err, this);\n        }\n    }\n    /**\n\t * {@link module:utils/observablemixin~Observable#decorate Decorated} function for applying\n\t * {@link module:engine/model/operation/operation~Operation operations} to the model.\n\t *\n\t * This is a low-level way of changing the model. It is exposed for very specific use cases (like the undo feature).\n\t * Normally, to modify the model, you will want to use {@link module:engine/model/writer~Writer `Writer`}.\n\t * See also {@glink framework/architecture/editing-engine#changing-the-model Changing the model} section\n\t * of the {@glink framework/architecture/editing-engine Editing architecture} guide.\n\t *\n\t * @param operation The operation to apply.\n\t */ applyOperation(operation) {\n        // @if CK_DEBUG_ENGINE // console.log( 'Applying ' + operation );\n        // @if CK_DEBUG_ENGINE // this._operationLogs.push( JSON.stringify( operation ) );\n        // @if CK_DEBUG_ENGINE // this._appliedOperations.push( operation );\n        operation._execute();\n    }\n    // @if CK_DEBUG_ENGINE // public getAppliedOperation(): string {\n    // @if CK_DEBUG_ENGINE // \tif ( !this._appliedOperations ) {\n    // @if CK_DEBUG_ENGINE // \t\treturn '';\n    // @if CK_DEBUG_ENGINE // \t}\n    // @if CK_DEBUG_ENGINE // \treturn this._appliedOperations.map( operation => JSON.stringify( operation ) ).join( '-------' );\n    // @if CK_DEBUG_ENGINE // }\n    // @if CK_DEBUG_ENGINE // public createReplayer( stringifiedOperations: string ): typeof OperationReplayer {\n    // @if CK_DEBUG_ENGINE // \treturn new OperationReplayer( this, '-------', stringifiedOperations );\n    // @if CK_DEBUG_ENGINE // }\n    /**\n\t * Inserts content at the position in the editor specified by the selection, as one would expect the paste\n\t * functionality to work.\n\t *\n\t * **Note**: If you want to insert an {@glink framework/deep-dive/schema#object-elements object element}\n\t * (e.g. a {@link module:widget/utils~toWidget widget}), see {@link #insertObject} instead.\n\t *\n\t * This is a high-level method. It takes the {@link #schema schema} into consideration when inserting\n\t * the content, clears the given selection's content before inserting nodes and moves the selection\n\t * to its target position at the end of the process.\n\t * It can split elements, merge them, wrap bare text nodes with paragraphs, etc. &ndash; just like the\n\t * pasting feature should do.\n\t *\n\t * For lower-level methods see {@link module:engine/model/writer~Writer `Writer`}.\n\t *\n\t * This method, unlike {@link module:engine/model/writer~Writer `Writer`}'s methods, does not have to be used\n\t * inside a {@link #change `change()` block}.\n\t *\n\t * # Conversion and schema\n\t *\n\t * Inserting elements and text nodes into the model is not enough to make CKEditor 5 render that content\n\t * to the user. CKEditor 5 implements a model-view-controller architecture and what `model.insertContent()` does\n\t * is only adding nodes to the model. Additionally, you need to define\n\t * {@glink framework/architecture/editing-engine#conversion converters} between the model and view\n\t * and define those nodes in the {@glink framework/architecture/editing-engine#schema schema}.\n\t *\n\t * So, while this method may seem similar to CKEditor 4 `editor.insertHtml()` (in fact, both methods\n\t * are used for paste-like content insertion), the CKEditor 5 method cannot be use to insert arbitrary HTML\n\t * unless converters are defined for all elements and attributes in that HTML.\n\t *\n\t * # Examples\n\t *\n\t * Using `insertContent()` with a manually created model structure:\n\t *\n\t * ```ts\n\t * // Let's create a document fragment containing such content as:\n\t * //\n\t * // <paragraph>foo</paragraph>\n\t * // <blockQuote>\n\t * //    <paragraph>bar</paragraph>\n\t * // </blockQuote>\n\t * const docFrag = editor.model.change( writer => {\n\t * \tconst p1 = writer.createElement( 'paragraph' );\n\t * \tconst p2 = writer.createElement( 'paragraph' );\n\t * \tconst blockQuote = writer.createElement( 'blockQuote' );\n\t * \tconst docFrag = writer.createDocumentFragment();\n\t *\n\t * \twriter.append( p1, docFrag );\n\t * \twriter.append( blockQuote, docFrag );\n\t * \twriter.append( p2, blockQuote );\n\t * \twriter.insertText( 'foo', p1 );\n\t * \twriter.insertText( 'bar', p2 );\n\t *\n\t * \treturn docFrag;\n\t * } );\n\t *\n\t * // insertContent() does not have to be used in a change() block. It can, though,\n\t * // so this code could be moved to the callback defined above.\n\t * editor.model.insertContent( docFrag );\n\t * ```\n\t *\n\t * Using `insertContent()` with an HTML string converted to a model document fragment (similar to the pasting mechanism):\n\t *\n\t * ```ts\n\t * // You can create your own HtmlDataProcessor instance or use editor.data.processor\n\t * // if you have not overridden the default one (which is the HtmlDataProcessor instance).\n\t * const htmlDP = new HtmlDataProcessor( viewDocument );\n\t *\n\t * // Convert an HTML string to a view document fragment:\n\t * const viewFragment = htmlDP.toView( htmlString );\n\t *\n\t * // Convert the view document fragment to a model document fragment\n\t * // in the context of $root. This conversion takes the schema into\n\t * // account so if, for example, the view document fragment contained a bare text node,\n\t * // this text node cannot be a child of $root, so it will be automatically\n\t * // wrapped with a <paragraph>. You can define the context yourself (in the second parameter),\n\t * // and e.g. convert the content like it would happen in a <paragraph>.\n\t * // Note: The clipboard feature uses a custom context called $clipboardHolder\n\t * // which has a loosened schema.\n\t * const modelFragment = editor.data.toModel( viewFragment );\n\t *\n\t * editor.model.insertContent( modelFragment );\n\t * ```\n\t *\n\t * By default this method will use the document selection but it can also be used with a position, range or selection instance.\n\t *\n\t * ```ts\n\t * // Insert text at the current document selection position.\n\t * editor.model.change( writer => {\n\t * \teditor.model.insertContent( writer.createText( 'x' ) );\n\t * } );\n\t *\n\t * // Insert text at a given position - the document selection will not be modified.\n\t * editor.model.change( writer => {\n\t * \teditor.model.insertContent( writer.createText( 'x' ), doc.getRoot(), 2 );\n\t *\n\t * \t// Which is a shorthand for:\n\t * \teditor.model.insertContent( writer.createText( 'x' ), writer.createPositionAt( doc.getRoot(), 2 ) );\n\t * } );\n\t * ```\n\t *\n\t * If you want the document selection to be moved to the inserted content, use the\n\t * {@link module:engine/model/writer~Writer#setSelection `setSelection()`} method of the writer after inserting\n\t * the content:\n\t *\n\t * ```ts\n\t * editor.model.change( writer => {\n\t * \tconst paragraph = writer.createElement( 'paragraph' );\n\t *\n\t * \t// Insert an empty paragraph at the beginning of the root.\n\t * \teditor.model.insertContent( paragraph, writer.createPositionAt( editor.model.document.getRoot(), 0 ) );\n\t *\n\t * \t// Move the document selection to the inserted paragraph.\n\t * \twriter.setSelection( paragraph, 'in' );\n\t * } );\n\t * ```\n\t *\n\t * If an instance of the {@link module:engine/model/selection~Selection model selection} is passed as `selectable`,\n\t * the new content will be inserted at the passed selection (instead of document selection):\n\t *\n\t * ```ts\n\t * editor.model.change( writer => {\n\t * \t// Create a selection in a paragraph that will be used as a place of insertion.\n\t * \tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * \t// Insert the new text at the created selection.\n\t * \teditor.model.insertContent( writer.createText( 'x' ), selection );\n\t *\n\t * \t// insertContent() modifies the passed selection instance so it can be used to set the document selection.\n\t * \t// Note: This is not necessary when you passed the document selection to insertContent().\n\t * \twriter.setSelection( selection );\n\t * } );\n\t * ```\n\t *\n\t * @fires insertContent\n\t * @param content The content to insert.\n\t * @param selectable The selection into which the content should be inserted.\n\t * If not provided the current model document selection will be used.\n\t * @param placeOrOffset To be used when a model item was passed as `selectable`.\n\t * This param defines a position in relation to that item.\n\t * at the insertion position.\n\t */ insertContent(content, selectable, placeOrOffset, ...rest) {\n        const selection = normalizeSelectable(selectable, placeOrOffset);\n        // Passing all call arguments so it acts like decorated method.\n        return this.fire('insertContent', [\n            content,\n            selection,\n            placeOrOffset,\n            ...rest\n        ]);\n    }\n    /**\n\t * Inserts an {@glink framework/deep-dive/schema#object-elements object element} at a specific position in the editor content.\n\t *\n\t * This is a high-level API:\n\t * * It takes the {@link #schema schema} into consideration,\n\t * * It clears the content of passed `selectable` before inserting,\n\t * * It can move the selection at the end of the process,\n\t * * It will copy the selected block's attributes to preserve them upon insertion,\n\t * * It can split elements or wrap inline objects with paragraphs if they are not allowed in target position,\n\t * * etc.\n\t *\n\t * # Notes\n\t *\n\t * * If you want to insert a non-object content, see {@link #insertContent} instead.\n\t * * For lower-level API, see {@link module:engine/model/writer~Writer `Writer`}.\n\t * * Unlike {@link module:engine/model/writer~Writer `Writer`}, this method does not have to be used inside\n\t * a {@link #change `change()` block}.\n\t * * Inserting object into the model is not enough to make CKEditor 5 render that content to the user.\n\t * CKEditor 5 implements a model-view-controller architecture and what `model.insertObject()` does\n\t * is only adding nodes to the model. Additionally, you need to define\n\t * {@glink framework/architecture/editing-engine#conversion converters} between the model and view\n\t * and define those nodes in the {@glink framework/architecture/editing-engine#schema schema}.\n\t *\n\t * # Examples\n\t *\n\t * Use the following code to insert an object at the current selection and keep the selection on the inserted element:\n\t *\n\t * ```ts\n\t * const rawHtmlEmbedElement = writer.createElement( 'rawHtml' );\n\t *\n\t * model.insertObject( rawHtmlEmbedElement, null, null, {\n\t * \tsetSelection: 'on'\n\t * } );\n\t * ```\n\t *\n\t * Use the following code to insert an object at the current selection and nudge the selection after the inserted object:\n\t *\n\t * ```ts\n\t * const pageBreakElement = writer.createElement( 'pageBreak' );\n \t *\n\t * model.insertObject( pageBreakElement, null, null, {\n\t * \tsetSelection: 'after'\n\t * } );\n\t * ```\n\t *\n\t * Use the following code to insert an object at the current selection and avoid splitting the content (non-destructive insertion):\n\t *\n\t * ```ts\n\t * const tableElement = writer.createElement( 'table' );\n \t *\n\t * model.insertObject( tableElement, null, null, {\n\t * \tfindOptimalPosition: 'auto'\n\t * } );\n\t * ```\n\t *\n\t * Use the following code to insert an object at the specific range (also: replace the content of the range):\n\t *\n\t * ```ts\n\t * const tableElement = writer.createElement( 'table' );\n\t * const range = model.createRangeOn( model.document.getRoot().getChild( 1 ) );\n \t *\n\t * model.insertObject( tableElement, range );\n\t * ```\n\t *\n\t * @param element An object to be inserted into the model document.\n\t * @param selectable A selectable where the content should be inserted. If not specified, the current\n\t * {@link module:engine/model/document~Document#selection document selection} will be used instead.\n\t * @param placeOrOffset Specifies the exact place or offset for the insertion to take place, relative to `selectable`.\n\t * @param options Additional options.\n\t * @param options.findOptimalPosition An option that, when set, adjusts the insertion position (relative to\n\t * `selectable` and `placeOrOffset`) so that the content of `selectable` is not split upon insertion (a.k.a. non-destructive insertion).\n\t * * When `'auto'`, the algorithm will decide whether to insert the object before or after `selectable` to avoid content splitting.\n\t * * When `'before'`, the closest position before `selectable` will be used that will not result in content splitting.\n\t * * When `'after'`, the closest position after `selectable` will be used that will not result in content splitting.\n\t *\n\t * Note that this option only works for block objects. Inline objects are inserted into text and do not split blocks.\n\t * @param options.setSelection An option that, when set, moves the\n\t * {@link module:engine/model/document~Document#selection document selection} after inserting the object.\n\t * * When `'on'`, the document selection will be set on the inserted object.\n\t * * When `'after'`, the document selection will move to the closest text node after the inserted object. If there is no\n\t * such text node, a paragraph will be created and the document selection will be moved inside it.\n\t * at the insertion position.\n\t */ insertObject(element, selectable, placeOrOffset, options, ...rest) {\n        const selection = normalizeSelectable(selectable, placeOrOffset);\n        // Note that options are fired as 2 arguments for backward compatibility with the decorated method.\n        // Passing all call arguments so it acts like decorated method.\n        return this.fire('insertObject', [\n            element,\n            selection,\n            options,\n            options,\n            ...rest\n        ]);\n    }\n    /**\n\t * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n\t *\n\t * **Note:** For the sake of predictability, the resulting selection should always be collapsed.\n\t * In cases where a feature wants to modify deleting behavior so selection isn't collapsed\n\t * (e.g. a table feature may want to keep row selection after pressing <kbd>Backspace</kbd>),\n\t * then that behavior should be implemented in the view's listener. At the same time, the table feature\n\t * will need to modify this method's behavior too, e.g. to \"delete contents and then collapse\n\t * the selection inside the last selected cell\" or \"delete the row and collapse selection somewhere near\".\n\t * That needs to be done in order to ensure that other features which use `deleteContent()` will work well with tables.\n\t *\n\t * @fires deleteContent\n\t * @param selection Selection of which the content should be deleted.\n\t * @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.\n\t *\n\t * For example `<heading1>x[x</heading1><paragraph>y]y</paragraph>` will become:\n\t *\n\t * * `<heading1>x^y</heading1>` with the option disabled (`leaveUnmerged == false`)\n\t * * `<heading1>x^</heading1><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n\t *\n\t * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}\n\t * elements will not be merged.\n\t *\n\t * @param options.doNotResetEntireContent Whether to skip replacing the entire content with a\n\t * paragraph when the entire content was selected.\n\t *\n\t * For example `<heading1>[x</heading1><paragraph>y]</paragraph>` will become:\n\t *\n\t * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n\t * * `<heading1>^</heading1>` with enabled (`doNotResetEntireContent == true`)\n\t *\n\t * @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved\n\t * to a place where text cannot be inserted.\n\t *\n\t * For example `<paragraph>x</paragraph>[<imageBlock src=\"foo.jpg\"></imageBlock>]` will become:\n\t *\n\t * * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n\t * * `<paragraph>x[]</paragraph>` with the option enabled (`doNotAutoparagraph == true`).\n\t *\n\t * **Note:** if there is no valid position for the selection, the paragraph will always be created:\n\t *\n\t * `[<imageBlock src=\"foo.jpg\"></imageBlock>]` -> `<paragraph>[]</paragraph>`.\n\t *\n\t * @param options.direction The direction in which the content is being consumed.\n\t * Deleting backward corresponds to using the <kbd>Backspace</kbd> key, while deleting content forward corresponds to\n\t * the <kbd>Shift</kbd>+<kbd>Backspace</kbd> keystroke.\n\t */ deleteContent(selection, options) {\n        deleteContent(this, selection, options);\n    }\n    /**\n\t * Modifies the selection. Currently, the supported modifications are:\n\t *\n\t * * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n\t * Possible values for `unit` are:\n\t *  * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n\t *  character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n\t *  with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n\t *  letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n\t *  selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n\t *  why `'character'` value is most natural and common method of modifying selection.\n\t *  * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n\t *  selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n\t *  However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n\t *  two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n\t *  For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n\t *  outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n\t *  extension will include whole \"surrogate pair\".\n\t *  * `'word'` - moves selection by a whole word.\n\t *\n\t * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n\t *\n\t * @fires modifySelection\n\t * @param selection The selection to modify.\n\t * @param options.direction The direction in which the selection should be modified.\n\t * @param options.unit The unit by which selection should be modified.\n\t * @param options.treatEmojiAsSingleUnit Whether multi-characer emoji sequences should be handled as single unit.\n\t */ modifySelection(selection, options) {\n        modifySelection(this, selection, options);\n    }\n    /**\n\t * Gets a clone of the selected content.\n\t *\n\t * For example, for the following selection:\n\t *\n\t * ```html\n\t * <paragraph>x</paragraph>\n\t * <blockQuote>\n\t * \t<paragraph>y</paragraph>\n\t * \t<heading1>fir[st</heading1>\n\t * </blockQuote>\n\t * <paragraph>se]cond</paragraph>\n\t * <paragraph>z</paragraph>\n\t * ```\n\t *\n\t * It will return a document fragment with such a content:\n\t *\n\t * ```html\n\t * <blockQuote>\n\t * \t<heading1>st</heading1>\n\t * </blockQuote>\n\t * <paragraph>se</paragraph>\n\t * ```\n\t *\n\t * @fires getSelectedContent\n\t * @param selection The selection of which content will be returned.\n\t */ getSelectedContent(selection) {\n        return getSelectedContent(this, selection);\n    }\n    /**\n\t * Checks whether the given {@link module:engine/model/range~Range range} or\n\t * {@link module:engine/model/element~Element element} has any meaningful content.\n\t *\n\t * Meaningful content is:\n\t *\n\t * * any text node (`options.ignoreWhitespaces` allows controlling whether this text node must also contain\n\t * any non-whitespace characters),\n\t * * or any {@link module:engine/model/schema~Schema#isContent content element},\n\t * * or any {@link module:engine/model/markercollection~Marker marker} which\n\t * {@link module:engine/model/markercollection~Marker#_affectsData affects data}.\n\t *\n\t * This means that a range containing an empty `<paragraph></paragraph>` is not considered to have a meaningful content.\n\t * However, a range containing an `<imageBlock></imageBlock>` (which would normally be marked in the schema as an object element)\n\t * is considered non-empty.\n\t *\n\t * @param rangeOrElement Range or element to check.\n\t * @param options.ignoreWhitespaces Whether text node with whitespaces only should be considered empty.\n\t * @param options.ignoreMarkers Whether markers should be ignored.\n\t */ hasContent(rangeOrElement, options = {}) {\n        const range = rangeOrElement instanceof Range ? rangeOrElement : Range._createIn(rangeOrElement);\n        if (range.isCollapsed) {\n            return false;\n        }\n        const { ignoreWhitespaces = false, ignoreMarkers = false } = options;\n        // Check if there are any markers which affects data in this given range.\n        if (!ignoreMarkers) {\n            for (const intersectingMarker of this.markers.getMarkersIntersectingRange(range)){\n                if (intersectingMarker.affectsData) {\n                    return true;\n                }\n            }\n        }\n        for (const item of range.getItems()){\n            if (this.schema.isContent(item)) {\n                if (item.is('$textProxy')) {\n                    if (!ignoreWhitespaces) {\n                        return true;\n                    } else if (item.data.search(/\\S/) !== -1) {\n                        return true;\n                    }\n                } else {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    /**\n\t * Check whether given selectable is at a place in the model where it can be edited (returns `true`) or not (returns `false`).\n\t *\n\t * Should be used instead of {@link module:core/editor/editor~Editor#isReadOnly} to check whether a user action can happen at\n\t * given selectable. It may be decorated and used differently in different environment (e.g. multi-root editor can disable\n\t * a particular root).\n\t *\n\t * This method is decorated. Although this method accepts any parameter of `Selectable` type, the\n\t * {@link ~Model#event:canEditAt `canEditAt` event} is fired with `selectable` normalized to an instance of\n\t * {@link module:engine/model/selection~Selection} or {@link module:engine/model/documentselection~DocumentSelection}\n\t *\n\t * @fires canEditAt\n\t */ canEditAt(selectable) {\n        const selection = normalizeSelectable(selectable);\n        return this.fire('canEditAt', [\n            selection\n        ]);\n    }\n    /**\n\t * Creates a position from the given root and path in that root.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionFromPath `Writer#createPositionFromPath()`}.\n\t *\n\t * @param root Root of the position.\n\t * @param path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param stickiness Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */ createPositionFromPath(root, path, stickiness) {\n        return new Position(root, path, stickiness);\n    }\n    /**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/model/position~Position position},\n\t * * a parent element and offset in that element,\n\t * * a parent element and `'end'` (the position will be set at the end of that element),\n\t * * a {@link module:engine/model/item~Item model item} and `'before'` or `'after'`\n\t * (the position will be set before or after the given model item).\n\t *\n\t * This method is a shortcut to other factory methods such as:\n\t *\n\t * * {@link module:engine/model/model~Model#createPositionBefore `createPositionBefore()`},\n\t * * {@link module:engine/model/model~Model#createPositionAfter `createPositionAfter()`}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionAt `Writer#createPositionAt()`},\n\t *\n\t * @param itemOrPosition\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */ createPositionAt(itemOrPosition, offset) {\n        return Position._createAt(itemOrPosition, offset);\n    }\n    /**\n\t * Creates a new position after the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionAfter `Writer#createPositionAfter()`}.\n\t *\n\t * @param item Item after which the position should be placed.\n\t */ createPositionAfter(item) {\n        return Position._createAfter(item);\n    }\n    /**\n\t * Creates a new position before the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionBefore `Writer#createPositionBefore()`}.\n\t *\n\t * @param item Item before which the position should be placed.\n\t */ createPositionBefore(item) {\n        return Position._createBefore(item);\n    }\n    /**\n\t * Creates a range spanning from the `start` position to the `end` position.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createRange `Writer#createRange()`}:\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \tconst range = writer.createRange( start, end );\n\t * } );\n\t * ```\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, the range will be collapsed to the `start` position.\n\t */ createRange(start, end) {\n        return new Range(start, end);\n    }\n    /**\n\t * Creates a range inside the given element which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createRangeIn `Writer#createRangeIn()`}:\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \tconst range = writer.createRangeIn( paragraph );\n\t * } );\n\t * ```\n\t *\n\t * @param element Element which is a parent for the range.\n\t */ createRangeIn(element) {\n        return Range._createIn(element);\n    }\n    /**\n\t * Creates a range that starts before the given {@link module:engine/model/item~Item model item} and ends after it.\n\t *\n\t * Note: This method is also available on `writer` instance as\n\t * {@link module:engine/model/writer~Writer#createRangeOn `Writer.createRangeOn()`}:\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \tconst range = writer.createRangeOn( paragraph );\n\t * } );\n\t * ```\n\t *\n\t * @param item\n\t */ createRangeOn(item) {\n        return Range._createOn(item);\n    }\n    createSelection(...args) {\n        return new Selection(...args);\n    }\n    /**\n\t * Creates a {@link module:engine/model/batch~Batch} instance.\n\t *\n\t * **Note:** In most cases creating a batch instance is not necessary as they are created when using:\n\t *\n\t * * {@link #change `change()`},\n\t * * {@link #enqueueChange `enqueueChange()`}.\n\t *\n\t * @param type {@link module:engine/model/batch~Batch#constructor The type} of the batch.\n\t */ createBatch(type) {\n        return new Batch(type);\n    }\n    /**\n\t * Creates an operation instance from a JSON object (parsed JSON string).\n\t *\n\t * This is an alias for {@link module:engine/model/operation/operationfactory~OperationFactory.fromJSON `OperationFactory.fromJSON()`}.\n\t *\n\t * @param json Deserialized JSON object.\n\t */ createOperationFromJSON(json) {\n        return OperationFactory.fromJSON(json, this.document);\n    }\n    /**\n\t * Removes all events listeners set by model instance and destroys {@link module:engine/model/document~Document}.\n\t */ destroy() {\n        this.document.destroy();\n        this.stopListening();\n    }\n    /**\n\t * Common part of {@link module:engine/model/model~Model#change} and {@link module:engine/model/model~Model#enqueueChange}\n\t * which calls callbacks and returns array of values returned by these callbacks.\n\t */ _runPendingChanges() {\n        const ret = [];\n        this.fire('_beforeChanges');\n        try {\n            while(this._pendingChanges.length){\n                // Create a new writer using batch instance created for this chain of changes.\n                const currentBatch = this._pendingChanges[0].batch;\n                this._currentWriter = new Writer(this, currentBatch);\n                // Execute changes callback and gather the returned value.\n                const callbackReturnValue = this._pendingChanges[0].callback(this._currentWriter);\n                ret.push(callbackReturnValue);\n                this.document._handleChangeBlock(this._currentWriter);\n                this._pendingChanges.shift();\n                this._currentWriter = null;\n            }\n        } finally{\n            this._pendingChanges.length = 0;\n            this._currentWriter = null;\n            this.fire('_afterChanges');\n        }\n        return ret;\n    }\n}\n/**\n * Normalizes a selectable to a Selection or DocumentSelection.\n */ function normalizeSelectable(selectable, placeOrOffset) {\n    if (!selectable) {\n        return;\n    }\n    if (selectable instanceof Selection || selectable instanceof DocumentSelection) {\n        return selectable;\n    }\n    if (selectable instanceof Node$1) {\n        if (placeOrOffset || placeOrOffset === 0) {\n            return new Selection(selectable, placeOrOffset);\n        } else if (selectable.is('rootElement')) {\n            return new Selection(selectable, 'in');\n        } else {\n            return new Selection(selectable, 'on');\n        }\n    }\n    return new Selection(selectable);\n}\n\n/**\n * {@link module:engine/view/document~Document#event:click Click} event observer.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View view controller} by a {@link module:engine/view/view~View#addObserver} method.\n */ class ClickObserver extends DomEventObserver {\n    /**\n\t * @inheritDoc\n\t */ domEventType = 'click';\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvent) {\n        this.fire(domEvent.type, domEvent);\n    }\n}\n\n/**\n * Mouse events observer.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View} by {@link module:engine/view/view~View#addObserver} method.\n */ class MouseObserver extends DomEventObserver {\n    /**\n\t * @inheritDoc\n\t */ domEventType = [\n        'mousedown',\n        'mouseup',\n        'mouseover',\n        'mouseout'\n    ];\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvent) {\n        this.fire(domEvent.type, domEvent);\n    }\n}\n\n/**\n * View upcast writer. It provides a set of methods used to manipulate non-semantic view trees.\n *\n * It should be used only while working on a non-semantic view\n * (e.g. a view created from HTML string on paste).\n * To manipulate a view which was or is being downcasted from the the model use the\n * {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}.\n *\n * Read more about changing the view in the {@glink framework/architecture/editing-engine#changing-the-view Changing the view}\n * section of the {@glink framework/architecture/editing-engine Editing engine architecture} guide.\n *\n * Unlike `DowncastWriter`, which is available in the {@link module:engine/view/view~View#change `View#change()`} block,\n * `UpcastWriter` can be created wherever you need it:\n *\n * ```ts\n * const writer = new UpcastWriter( viewDocument );\n * const text = writer.createText( 'foo!' );\n *\n * writer.appendChild( text, someViewElement );\n * ```\n */ class UpcastWriter {\n    /**\n\t * The view document instance in which this upcast writer operates.\n\t */ document;\n    /**\n\t * @param document The view document instance in which this upcast writer operates.\n\t */ constructor(document){\n        this.document = document;\n    }\n    /**\n\t * Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance.\n\t *\n\t * @param children A list of nodes to be inserted into the created document fragment.\n\t * @returns The created document fragment.\n\t */ createDocumentFragment(children) {\n        return new DocumentFragment$1(this.document, children);\n    }\n    /**\n\t * Creates a new {@link module:engine/view/element~Element} instance.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t * ```ts\n\t * upcastWriter.createElement( 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t * upcastWriter.createElement( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t * upcastWriter.createElement( 'div', mapOfAttributes ); // map\n\t * ```\n\t *\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t * @returns Created element.\n\t */ createElement(name, attrs, children) {\n        return new Element$1(this.document, name, attrs, children);\n    }\n    /**\n\t * Creates a new {@link module:engine/view/text~Text} instance.\n\t *\n\t * @param data The text's data.\n\t * @returns The created text node.\n\t */ createText(data) {\n        return new Text$1(this.document, data);\n    }\n    /**\n\t * Clones the provided element.\n\t *\n\t * @see module:engine/view/element~Element#_clone\n\t * @param element Element to be cloned.\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns Clone of this element.\n\t */ clone(element, deep = false) {\n        return element._clone(deep);\n    }\n    /**\n\t * Appends a child node or a list of child nodes at the end of this node\n\t * and sets the parent of these nodes to this element.\n\t *\n\t * @see module:engine/view/element~Element#_appendChild\n\t * @param items Items to be inserted.\n\t * @param element Element to which items will be appended.\n\t * @returns Number of appended nodes.\n\t */ appendChild(items, element) {\n        return element._appendChild(items);\n    }\n    /**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this element.\n\t *\n\t * @see module:engine/view/element~Element#_insertChild\n\t * @param index Offset at which nodes should be inserted.\n\t * @param items Items to be inserted.\n\t * @param element Element to which items will be inserted.\n\t * @returns Number of inserted nodes.\n\t */ insertChild(index, items, element) {\n        return element._insertChild(index, items);\n    }\n    /**\n\t * Removes the given number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @see module:engine/view/element~Element#_removeChildren\n\t * @param index Offset from which nodes will be removed.\n\t * @param howMany Number of nodes to remove.\n\t * @param element Element which children will be removed.\n\t * @returns The array containing removed nodes.\n\t */ removeChildren(index, howMany, element) {\n        return element._removeChildren(index, howMany);\n    }\n    /**\n\t * Removes given element from the view structure. Will not have effect on detached elements.\n\t *\n\t * @param element Element which will be removed.\n\t * @returns The array containing removed nodes.\n\t */ remove(element) {\n        const parent = element.parent;\n        if (parent) {\n            return this.removeChildren(parent.getChildIndex(element), 1, parent);\n        }\n        return [];\n    }\n    /**\n\t * Replaces given element with the new one in the view structure. Will not have effect on detached elements.\n\t *\n\t * @param oldElement Element which will be replaced.\n\t * @param newElement Element which will be inserted in the place of the old element.\n\t * @returns Whether old element was successfully replaced.\n\t */ replace(oldElement, newElement) {\n        const parent = oldElement.parent;\n        if (parent) {\n            const index = parent.getChildIndex(oldElement);\n            this.removeChildren(index, 1, parent);\n            this.insertChild(index, newElement, parent);\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Removes given element from view structure and places its children in its position.\n\t * It does nothing if element has no parent.\n\t *\n\t * @param element Element to unwrap.\n\t */ unwrapElement(element) {\n        const parent = element.parent;\n        if (parent) {\n            const index = parent.getChildIndex(element);\n            this.remove(element);\n            this.insertChild(index, element.getChildren(), parent);\n        }\n    }\n    /**\n\t * Renames element by creating a copy of a given element but with its name changed and then moving contents of the\n\t * old element to the new one.\n\t *\n\t * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t *\n\t * @param newName New element name.\n\t * @param  element Element to be renamed.\n\t * @returns New element or null if the old element was not replaced (happens for detached elements).\n\t */ rename(newName, element) {\n        const newElement = new Element$1(this.document, newName, element.getAttributes(), element.getChildren());\n        return this.replace(element, newElement) ? newElement : null;\n    }\n    /**\n\t * Adds or overwrites element's attribute with a specified key and value.\n\t *\n\t * ```ts\n\t * writer.setAttribute( 'href', 'http://ckeditor.com', linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_setAttribute\n\t * @param key Attribute key.\n\t * @param value Attribute value.\n\t * @param element Element for which attribute will be set.\n\t */ setAttribute(key, value, element) {\n        element._setAttribute(key, value);\n    }\n    /**\n\t * Removes attribute from the element.\n\t *\n\t * ```ts\n\t * writer.removeAttribute( 'href', linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_removeAttribute\n\t * @param key Attribute key.\n\t * @param element Element from which attribute will be removed.\n\t */ removeAttribute(key, element) {\n        element._removeAttribute(key);\n    }\n    /**\n\t * Adds specified class to the element.\n\t *\n\t * ```ts\n\t * writer.addClass( 'foo', linkElement );\n\t * writer.addClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_addClass\n\t * @param className Single class name or array of class names which will be added.\n\t * @param element Element for which class will be added.\n\t */ addClass(className, element) {\n        element._addClass(className);\n    }\n    /**\n\t * Removes specified class from the element.\n\t *\n\t * ```ts\n\t * writer.removeClass( 'foo', linkElement );\n\t * writer.removeClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_removeClass\n\t * @param className Single class name or array of class names which will be removed.\n\t * @param element Element from which class will be removed.\n\t */ removeClass(className, element) {\n        element._removeClass(className);\n    }\n    setStyle(property, valueOrElement, element) {\n        if (isPlainObject(property) && element === undefined) {\n            valueOrElement._setStyle(property);\n        } else {\n            element._setStyle(property, valueOrElement);\n        }\n    }\n    /**\n\t * Removes specified style from the element.\n\t *\n\t * ```ts\n\t * writer.removeStyle( 'color', element );  // Removes 'color' style.\n\t * writer.removeStyle( [ 'color', 'border-top' ], element ); // Removes both 'color' and 'border-top' styles.\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t *\n\t * @see module:engine/view/element~Element#_removeStyle\n\t * @param property Style property name or names to be removed.\n\t * @param element Element from which style will be removed.\n\t */ removeStyle(property, element) {\n        element._removeStyle(property);\n    }\n    /**\n\t * Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/element~Element#_setCustomProperty\n\t * @param key Custom property name/key.\n\t * @param value Custom property value to be stored.\n\t * @param element Element for which custom property will be set.\n\t */ setCustomProperty(key, value, element) {\n        element._setCustomProperty(key, value);\n    }\n    /**\n\t * Removes a custom property stored under the given key.\n\t *\n\t * @see module:engine/view/element~Element#_removeCustomProperty\n\t * @param key Name/key of the custom property to be removed.\n\t * @param element Element from which the custom property will be removed.\n\t * @returns Returns true if property was removed.\n\t */ removeCustomProperty(key, element) {\n        return element._removeCustomProperty(key);\n    }\n    /**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */ createPositionAt(itemOrPosition, offset) {\n        return Position$1._createAt(itemOrPosition, offset);\n    }\n    /**\n\t * Creates a new position after given view item.\n\t *\n\t * @param item View item after which the position should be located.\n\t */ createPositionAfter(item) {\n        return Position$1._createAfter(item);\n    }\n    /**\n\t * Creates a new position before given view item.\n\t *\n\t * @param item View item before which the position should be located.\n\t */ createPositionBefore(item) {\n        return Position$1._createBefore(item);\n    }\n    /**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */ createRange(start, end) {\n        return new Range$1(start, end);\n    }\n    /**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t */ createRangeOn(item) {\n        return Range$1._createOn(item);\n    }\n    /**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */ createRangeIn(element) {\n        return Range$1._createIn(element);\n    }\n    createSelection(...args) {\n        return new Selection$1(...args);\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module engine/view/styles/utils\n */ const HEX_COLOR_REGEXP = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst RGB_COLOR_REGEXP = /^rgb\\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}[0-9]{1,3}[ %]?\\)$/i;\nconst RGBA_COLOR_REGEXP = /^rgba\\([ ]?([0-9]{1,3}[ %]?,[ ]?){3}(1|[0-9]+%|[0]?\\.?[0-9]+)\\)$/i;\nconst HSL_COLOR_REGEXP = /^hsl\\([ ]?([0-9]{1,3}[ %]?[,]?[ ]*){3}(1|[0-9]+%|[0]?\\.?[0-9]+)?\\)$/i;\nconst HSLA_COLOR_REGEXP = /^hsla\\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}(1|[0-9]+%|[0]?\\.?[0-9]+)\\)$/i;\n// Note: This regexp hardcodes a single level of nested () for values such as `calc( var( ...) + ...)`.\n// If this gets more complex, a proper parser should be used instead.\nconst CSS_SHORTHAND_VALUE_REGEXP = /\\w+\\((?:[^()]|\\([^()]*\\))*\\)|\\S+/gi;\nconst COLOR_NAMES = new Set([\n    // CSS Level 1\n    'black',\n    'silver',\n    'gray',\n    'white',\n    'maroon',\n    'red',\n    'purple',\n    'fuchsia',\n    'green',\n    'lime',\n    'olive',\n    'yellow',\n    'navy',\n    'blue',\n    'teal',\n    'aqua',\n    // CSS Level 2 (Revision 1)\n    'orange',\n    // CSS Color Module Level 3\n    'aliceblue',\n    'antiquewhite',\n    'aquamarine',\n    'azure',\n    'beige',\n    'bisque',\n    'blanchedalmond',\n    'blueviolet',\n    'brown',\n    'burlywood',\n    'cadetblue',\n    'chartreuse',\n    'chocolate',\n    'coral',\n    'cornflowerblue',\n    'cornsilk',\n    'crimson',\n    'cyan',\n    'darkblue',\n    'darkcyan',\n    'darkgoldenrod',\n    'darkgray',\n    'darkgreen',\n    'darkgrey',\n    'darkkhaki',\n    'darkmagenta',\n    'darkolivegreen',\n    'darkorange',\n    'darkorchid',\n    'darkred',\n    'darksalmon',\n    'darkseagreen',\n    'darkslateblue',\n    'darkslategray',\n    'darkslategrey',\n    'darkturquoise',\n    'darkviolet',\n    'deeppink',\n    'deepskyblue',\n    'dimgray',\n    'dimgrey',\n    'dodgerblue',\n    'firebrick',\n    'floralwhite',\n    'forestgreen',\n    'gainsboro',\n    'ghostwhite',\n    'gold',\n    'goldenrod',\n    'greenyellow',\n    'grey',\n    'honeydew',\n    'hotpink',\n    'indianred',\n    'indigo',\n    'ivory',\n    'khaki',\n    'lavender',\n    'lavenderblush',\n    'lawngreen',\n    'lemonchiffon',\n    'lightblue',\n    'lightcoral',\n    'lightcyan',\n    'lightgoldenrodyellow',\n    'lightgray',\n    'lightgreen',\n    'lightgrey',\n    'lightpink',\n    'lightsalmon',\n    'lightseagreen',\n    'lightskyblue',\n    'lightslategray',\n    'lightslategrey',\n    'lightsteelblue',\n    'lightyellow',\n    'limegreen',\n    'linen',\n    'magenta',\n    'mediumaquamarine',\n    'mediumblue',\n    'mediumorchid',\n    'mediumpurple',\n    'mediumseagreen',\n    'mediumslateblue',\n    'mediumspringgreen',\n    'mediumturquoise',\n    'mediumvioletred',\n    'midnightblue',\n    'mintcream',\n    'mistyrose',\n    'moccasin',\n    'navajowhite',\n    'oldlace',\n    'olivedrab',\n    'orangered',\n    'orchid',\n    'palegoldenrod',\n    'palegreen',\n    'paleturquoise',\n    'palevioletred',\n    'papayawhip',\n    'peachpuff',\n    'peru',\n    'pink',\n    'plum',\n    'powderblue',\n    'rosybrown',\n    'royalblue',\n    'saddlebrown',\n    'salmon',\n    'sandybrown',\n    'seagreen',\n    'seashell',\n    'sienna',\n    'skyblue',\n    'slateblue',\n    'slategray',\n    'slategrey',\n    'snow',\n    'springgreen',\n    'steelblue',\n    'tan',\n    'thistle',\n    'tomato',\n    'turquoise',\n    'violet',\n    'wheat',\n    'whitesmoke',\n    'yellowgreen',\n    // CSS Color Module Level 3 (System Colors)\n    'activeborder',\n    'activecaption',\n    'appworkspace',\n    'background',\n    'buttonface',\n    'buttonhighlight',\n    'buttonshadow',\n    'buttontext',\n    'captiontext',\n    'graytext',\n    'highlight',\n    'highlighttext',\n    'inactiveborder',\n    'inactivecaption',\n    'inactivecaptiontext',\n    'infobackground',\n    'infotext',\n    'menu',\n    'menutext',\n    'scrollbar',\n    'threeddarkshadow',\n    'threedface',\n    'threedhighlight',\n    'threedlightshadow',\n    'threedshadow',\n    'window',\n    'windowframe',\n    'windowtext',\n    // CSS Color Module Level 4\n    'rebeccapurple',\n    // Keywords\n    'currentcolor',\n    'transparent'\n]);\n/**\n * Checks if string contains [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) CSS value.\n *\n * ```ts\n * isColor( '#f00' );\t\t\t\t\t\t// true\n * isColor( '#AA00BB33' );\t\t\t\t\t// true\n * isColor( 'rgb(0, 0, 250)' );\t\t\t\t// true\n * isColor( 'hsla(240, 100%, 50%, .7)' );\t// true\n * isColor( 'deepskyblue' );\t\t\t\t// true\n * ```\n *\n * **Note**: It does not support CSS Level 4 whitespace syntax, system colors and radius values for HSL colors.\n */ function isColor(string) {\n    // As far as I was able to test checking some pre-conditions is faster than joining each test with ||.\n    if (string.startsWith('#')) {\n        return HEX_COLOR_REGEXP.test(string);\n    }\n    if (string.startsWith('rgb')) {\n        return RGB_COLOR_REGEXP.test(string) || RGBA_COLOR_REGEXP.test(string);\n    }\n    if (string.startsWith('hsl')) {\n        return HSL_COLOR_REGEXP.test(string) || HSLA_COLOR_REGEXP.test(string);\n    }\n    // Array check > RegExp test.\n    return COLOR_NAMES.has(string.toLowerCase());\n}\nconst lineStyleValues = [\n    'none',\n    'hidden',\n    'dotted',\n    'dashed',\n    'solid',\n    'double',\n    'groove',\n    'ridge',\n    'inset',\n    'outset'\n];\n/**\n * Checks if string contains [line style](https://developer.mozilla.org/en-US/docs/Web/CSS/border-style) CSS value.\n */ function isLineStyle(string) {\n    return lineStyleValues.includes(string);\n}\nconst lengthRegExp = /^([+-]?[0-9]*([.][0-9]+)?(px|cm|mm|in|pc|pt|ch|em|ex|rem|vh|vw|vmin|vmax)|0)$/;\n/**\n * Checks if string contains [length](https://developer.mozilla.org/en-US/docs/Web/CSS/length) CSS value.\n */ function isLength(string) {\n    return lengthRegExp.test(string);\n}\nconst PERCENTAGE_VALUE_REGEXP = /^[+-]?[0-9]*([.][0-9]+)?%$/;\n/**\n * Checks if string contains [percentage](https://developer.mozilla.org/en-US/docs/Web/CSS/percentage) CSS value.\n */ function isPercentage(string) {\n    return PERCENTAGE_VALUE_REGEXP.test(string);\n}\nconst repeatValues = [\n    'repeat-x',\n    'repeat-y',\n    'repeat',\n    'space',\n    'round',\n    'no-repeat'\n];\n/**\n * Checks if string contains [background repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat) CSS value.\n */ function isRepeat(string) {\n    return repeatValues.includes(string);\n}\nconst positionValues = [\n    'center',\n    'top',\n    'bottom',\n    'left',\n    'right'\n];\n/**\n * Checks if string contains [background position](https://developer.mozilla.org/en-US/docs/Web/CSS/background-position) CSS value.\n */ function isPosition(string) {\n    return positionValues.includes(string);\n}\nconst attachmentValues = [\n    'fixed',\n    'scroll',\n    'local'\n];\n/**\n * Checks if string contains [background attachment](https://developer.mozilla.org/en-US/docs/Web/CSS/background-attachment) CSS value.\n */ function isAttachment(string) {\n    return attachmentValues.includes(string);\n}\nconst urlRegExp = /^url\\(/;\n/**\n * Checks if string contains [URL](https://developer.mozilla.org/en-US/docs/Web/CSS/url) CSS value.\n */ function isURL(string) {\n    return urlRegExp.test(string);\n}\n/**\n * Parses box sides as individual values.\n */ function getBoxSidesValues(value = '') {\n    if (value === '') {\n        return {\n            top: undefined,\n            right: undefined,\n            bottom: undefined,\n            left: undefined\n        };\n    }\n    const values = getShorthandValues(value);\n    const top = values[0];\n    const bottom = values[2] || top;\n    const right = values[1] || top;\n    const left = values[3] || right;\n    return {\n        top,\n        bottom,\n        right,\n        left\n    };\n}\n/**\n * Default reducer for CSS properties that concerns edges of a box\n * [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) notations:\n *\n * ```ts\n * stylesProcessor.setReducer( 'padding', getBoxSidesValueReducer( 'padding' ) );\n * ```\n */ function getBoxSidesValueReducer(styleShorthand) {\n    return (value)=>{\n        const { top, right, bottom, left } = value;\n        const reduced = [];\n        if (![\n            top,\n            right,\n            left,\n            bottom\n        ].every((value)=>!!value)) {\n            if (top) {\n                reduced.push([\n                    styleShorthand + '-top',\n                    top\n                ]);\n            }\n            if (right) {\n                reduced.push([\n                    styleShorthand + '-right',\n                    right\n                ]);\n            }\n            if (bottom) {\n                reduced.push([\n                    styleShorthand + '-bottom',\n                    bottom\n                ]);\n            }\n            if (left) {\n                reduced.push([\n                    styleShorthand + '-left',\n                    left\n                ]);\n            }\n        } else {\n            reduced.push([\n                styleShorthand,\n                getBoxSidesShorthandValue(value)\n            ]);\n        }\n        return reduced;\n    };\n}\n/**\n * Returns a [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) notation\n * of a CSS property value.\n *\n * ```ts\n * getBoxSidesShorthandValue( { top: '1px', right: '1px', bottom: '2px', left: '1px' } );\n * // will return '1px 1px 2px'\n * ```\n */ function getBoxSidesShorthandValue({ top, right, bottom, left }) {\n    const out = [];\n    if (left !== right) {\n        out.push(top, right, bottom, left);\n    } else if (bottom !== top) {\n        out.push(top, right, bottom);\n    } else if (right !== top) {\n        out.push(top, right);\n    } else {\n        out.push(top);\n    }\n    return out.join(' ');\n}\n/**\n * Creates a normalizer for a [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) 1-to-4 value.\n *\n * ```ts\n * stylesProcessor.setNormalizer( 'margin', getPositionShorthandNormalizer( 'margin' ) );\n * ```\n */ function getPositionShorthandNormalizer(shorthand) {\n    return (value)=>{\n        return {\n            path: shorthand,\n            value: getBoxSidesValues(value)\n        };\n    };\n}\n/**\n * Parses parts of a 1-to-4 value notation - handles some CSS values with spaces (like RGB()).\n *\n * ```ts\n * getShorthandValues( 'red blue RGB(0, 0, 0)');\n * // will return [ 'red', 'blue', 'RGB(0, 0, 0)' ]\n * ```\n */ function getShorthandValues(string) {\n    const matches = string.trim().slice(0, 1500).matchAll(CSS_SHORTHAND_VALUE_REGEXP);\n    return Array.from(matches).map((i)=>i[0]);\n}\n\n/**\n * Adds a background CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addBackgroundRules );\n * ```\n *\n * The normalized value is stored as:\n *\n * ```ts\n * const styles = {\n * \tbackground: {\n * \t\tcolor,\n * \t\trepeat,\n * \t\tposition,\n * \t\tattachment,\n * \t\timage\n * \t}\n * };\n * ````\n *\n * **Note**: Currently only `'background-color'` longhand value is parsed besides `'background'` shorthand. The reducer also supports only\n * `'background-color'` value.\n */ function addBackgroundRules(stylesProcessor) {\n    stylesProcessor.setNormalizer('background', getBackgroundNormalizer());\n    stylesProcessor.setNormalizer('background-color', getBackgroundColorNormalizer());\n    stylesProcessor.setReducer('background', getBackgroundReducer());\n    stylesProcessor.setStyleRelation('background', [\n        'background-color'\n    ]);\n}\nfunction getBackgroundNormalizer() {\n    return (value)=>{\n        const background = {};\n        const parts = getShorthandValues(value);\n        for (const part of parts){\n            if (isRepeat(part)) {\n                background.repeat = background.repeat || [];\n                background.repeat.push(part);\n            } else if (isPosition(part)) {\n                background.position = background.position || [];\n                background.position.push(part);\n            } else if (isAttachment(part)) {\n                background.attachment = part;\n            } else if (isColor(part)) {\n                background.color = part;\n            } else if (isURL(part)) {\n                background.image = part;\n            }\n        }\n        return {\n            path: 'background',\n            value: background\n        };\n    };\n}\nfunction getBackgroundColorNormalizer() {\n    return (value)=>({\n            path: 'background.color',\n            value\n        });\n}\nfunction getBackgroundReducer() {\n    return (value)=>{\n        const ret = [];\n        ret.push([\n            'background-color',\n            value.color\n        ]);\n        return ret;\n    };\n}\n\n/**\n * Adds a border CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addBorderRules );\n * ```\n *\n * This rules merges all [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) styles notation shorthands:\n *\n * - border\n * - border-top\n * - border-right\n * - border-bottom\n * - border-left\n * - border-color\n * - border-style\n * - border-width\n *\n * and all corresponding longhand forms (like `border-top-color`, `border-top-style`, etc).\n *\n * It does not handle other shorthands (like `border-radius` or `border-image`).\n *\n * The normalized model stores border values as:\n *\n * ```ts\n * const styles = {\n * \tborder: {\n * \t\tcolor: { top, right, bottom, left },\n * \t\tstyle: { top, right, bottom, left },\n * \t\twidth: { top, right, bottom, left },\n * \t}\n * };\n * ```\n */ function addBorderRules(stylesProcessor) {\n    stylesProcessor.setNormalizer('border', getBorderNormalizer());\n    // Border-position shorthands.\n    stylesProcessor.setNormalizer('border-top', getBorderPositionNormalizer('top'));\n    stylesProcessor.setNormalizer('border-right', getBorderPositionNormalizer('right'));\n    stylesProcessor.setNormalizer('border-bottom', getBorderPositionNormalizer('bottom'));\n    stylesProcessor.setNormalizer('border-left', getBorderPositionNormalizer('left'));\n    // Border-property shorthands.\n    stylesProcessor.setNormalizer('border-color', getBorderPropertyNormalizer('color'));\n    stylesProcessor.setNormalizer('border-width', getBorderPropertyNormalizer('width'));\n    stylesProcessor.setNormalizer('border-style', getBorderPropertyNormalizer('style'));\n    // Border longhands.\n    stylesProcessor.setNormalizer('border-top-color', getBorderPropertyPositionNormalizer('color', 'top'));\n    stylesProcessor.setNormalizer('border-top-style', getBorderPropertyPositionNormalizer('style', 'top'));\n    stylesProcessor.setNormalizer('border-top-width', getBorderPropertyPositionNormalizer('width', 'top'));\n    stylesProcessor.setNormalizer('border-right-color', getBorderPropertyPositionNormalizer('color', 'right'));\n    stylesProcessor.setNormalizer('border-right-style', getBorderPropertyPositionNormalizer('style', 'right'));\n    stylesProcessor.setNormalizer('border-right-width', getBorderPropertyPositionNormalizer('width', 'right'));\n    stylesProcessor.setNormalizer('border-bottom-color', getBorderPropertyPositionNormalizer('color', 'bottom'));\n    stylesProcessor.setNormalizer('border-bottom-style', getBorderPropertyPositionNormalizer('style', 'bottom'));\n    stylesProcessor.setNormalizer('border-bottom-width', getBorderPropertyPositionNormalizer('width', 'bottom'));\n    stylesProcessor.setNormalizer('border-left-color', getBorderPropertyPositionNormalizer('color', 'left'));\n    stylesProcessor.setNormalizer('border-left-style', getBorderPropertyPositionNormalizer('style', 'left'));\n    stylesProcessor.setNormalizer('border-left-width', getBorderPropertyPositionNormalizer('width', 'left'));\n    stylesProcessor.setExtractor('border-top', getBorderPositionExtractor('top'));\n    stylesProcessor.setExtractor('border-right', getBorderPositionExtractor('right'));\n    stylesProcessor.setExtractor('border-bottom', getBorderPositionExtractor('bottom'));\n    stylesProcessor.setExtractor('border-left', getBorderPositionExtractor('left'));\n    stylesProcessor.setExtractor('border-top-color', 'border.color.top');\n    stylesProcessor.setExtractor('border-right-color', 'border.color.right');\n    stylesProcessor.setExtractor('border-bottom-color', 'border.color.bottom');\n    stylesProcessor.setExtractor('border-left-color', 'border.color.left');\n    stylesProcessor.setExtractor('border-top-width', 'border.width.top');\n    stylesProcessor.setExtractor('border-right-width', 'border.width.right');\n    stylesProcessor.setExtractor('border-bottom-width', 'border.width.bottom');\n    stylesProcessor.setExtractor('border-left-width', 'border.width.left');\n    stylesProcessor.setExtractor('border-top-style', 'border.style.top');\n    stylesProcessor.setExtractor('border-right-style', 'border.style.right');\n    stylesProcessor.setExtractor('border-bottom-style', 'border.style.bottom');\n    stylesProcessor.setExtractor('border-left-style', 'border.style.left');\n    stylesProcessor.setReducer('border-color', getBoxSidesValueReducer('border-color'));\n    stylesProcessor.setReducer('border-style', getBoxSidesValueReducer('border-style'));\n    stylesProcessor.setReducer('border-width', getBoxSidesValueReducer('border-width'));\n    stylesProcessor.setReducer('border-top', getBorderPositionReducer('top'));\n    stylesProcessor.setReducer('border-right', getBorderPositionReducer('right'));\n    stylesProcessor.setReducer('border-bottom', getBorderPositionReducer('bottom'));\n    stylesProcessor.setReducer('border-left', getBorderPositionReducer('left'));\n    stylesProcessor.setReducer('border', getBorderReducer());\n    stylesProcessor.setStyleRelation('border', [\n        'border-color',\n        'border-style',\n        'border-width',\n        'border-top',\n        'border-right',\n        'border-bottom',\n        'border-left',\n        'border-top-color',\n        'border-right-color',\n        'border-bottom-color',\n        'border-left-color',\n        'border-top-style',\n        'border-right-style',\n        'border-bottom-style',\n        'border-left-style',\n        'border-top-width',\n        'border-right-width',\n        'border-bottom-width',\n        'border-left-width'\n    ]);\n    stylesProcessor.setStyleRelation('border-color', [\n        'border-top-color',\n        'border-right-color',\n        'border-bottom-color',\n        'border-left-color'\n    ]);\n    stylesProcessor.setStyleRelation('border-style', [\n        'border-top-style',\n        'border-right-style',\n        'border-bottom-style',\n        'border-left-style'\n    ]);\n    stylesProcessor.setStyleRelation('border-width', [\n        'border-top-width',\n        'border-right-width',\n        'border-bottom-width',\n        'border-left-width'\n    ]);\n    stylesProcessor.setStyleRelation('border-top', [\n        'border-top-color',\n        'border-top-style',\n        'border-top-width'\n    ]);\n    stylesProcessor.setStyleRelation('border-right', [\n        'border-right-color',\n        'border-right-style',\n        'border-right-width'\n    ]);\n    stylesProcessor.setStyleRelation('border-bottom', [\n        'border-bottom-color',\n        'border-bottom-style',\n        'border-bottom-width'\n    ]);\n    stylesProcessor.setStyleRelation('border-left', [\n        'border-left-color',\n        'border-left-style',\n        'border-left-width'\n    ]);\n}\nfunction getBorderNormalizer() {\n    return (value)=>{\n        const { color, style, width } = normalizeBorderShorthand(value);\n        return {\n            path: 'border',\n            value: {\n                color: getBoxSidesValues(color),\n                style: getBoxSidesValues(style),\n                width: getBoxSidesValues(width)\n            }\n        };\n    };\n}\nfunction getBorderPositionNormalizer(side) {\n    return (value)=>{\n        const { color, style, width } = normalizeBorderShorthand(value);\n        const border = {};\n        if (color !== undefined) {\n            border.color = {\n                [side]: color\n            };\n        }\n        if (style !== undefined) {\n            border.style = {\n                [side]: style\n            };\n        }\n        if (width !== undefined) {\n            border.width = {\n                [side]: width\n            };\n        }\n        return {\n            path: 'border',\n            value: border\n        };\n    };\n}\nfunction getBorderPropertyNormalizer(propertyName) {\n    return (value)=>{\n        return {\n            path: 'border',\n            value: toBorderPropertyShorthand(value, propertyName)\n        };\n    };\n}\nfunction toBorderPropertyShorthand(value, property) {\n    return {\n        [property]: getBoxSidesValues(value)\n    };\n}\nfunction getBorderPropertyPositionNormalizer(property, side) {\n    return (value)=>{\n        return {\n            path: 'border',\n            value: {\n                [property]: {\n                    [side]: value\n                }\n            }\n        };\n    };\n}\nfunction getBorderPositionExtractor(which) {\n    return (name, styles)=>{\n        if (styles.border) {\n            return extractBorderPosition(styles.border, which);\n        }\n    };\n}\nfunction extractBorderPosition(border, which) {\n    const value = {};\n    if (border.width && border.width[which]) {\n        value.width = border.width[which];\n    }\n    if (border.style && border.style[which]) {\n        value.style = border.style[which];\n    }\n    if (border.color && border.color[which]) {\n        value.color = border.color[which];\n    }\n    return value;\n}\nfunction normalizeBorderShorthand(string) {\n    const result = {};\n    const parts = getShorthandValues(string);\n    for (const part of parts){\n        if (isLength(part) || /thin|medium|thick/.test(part)) {\n            result.width = part;\n        } else if (isLineStyle(part)) {\n            result.style = part;\n        } else {\n            result.color = part;\n        }\n    }\n    return result;\n}\n/**\n * The border reducer factory.\n *\n * It tries to produce the most optimal output for the specified styles.\n *\n * For a border style:\n *\n * ```css\n * style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n * ```\n *\n * It will produce: `border-style: solid`.\n * For a border style and color:\n *\n * ```css\n * color: {top: \"#ff0\", bottom: \"#ff0\", right: \"#ff0\", left: \"#ff0\"}\n * style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n * ```\n *\n * It will produce: `border-color: #ff0; border-style: solid`.\n * If all border parameters are specified:\n *\n * ```css\n * color: {top: \"#ff0\", bottom: \"#ff0\", right: \"#ff0\", left: \"#ff0\"}\n * style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n * width: {top: \"2px\", bottom: \"2px\", right: \"2px\", left: \"2px\"}\n * ```\n *\n * It will combine everything into a single property: `border: 2px solid #ff0`.\n *\n * The definitions are merged only if all border selectors have the same values.\n */ function getBorderReducer() {\n    return (value)=>{\n        const topStyles = extractBorderPosition(value, 'top');\n        const rightStyles = extractBorderPosition(value, 'right');\n        const bottomStyles = extractBorderPosition(value, 'bottom');\n        const leftStyles = extractBorderPosition(value, 'left');\n        const borderStyles = [\n            topStyles,\n            rightStyles,\n            bottomStyles,\n            leftStyles\n        ];\n        const borderStylesByType = {\n            width: getReducedStyleValueForType(borderStyles, 'width'),\n            style: getReducedStyleValueForType(borderStyles, 'style'),\n            color: getReducedStyleValueForType(borderStyles, 'color')\n        };\n        // Try reducing to a single `border:` property.\n        const reducedBorderStyle = reduceBorderPosition(borderStylesByType, 'all');\n        if (reducedBorderStyle.length) {\n            return reducedBorderStyle;\n        }\n        // Try reducing to `border-style:`, `border-width:`, `border-color:` properties.\n        const reducedStyleTypes = Object.entries(borderStylesByType).reduce((reducedStyleTypes, [type, value])=>{\n            if (value) {\n                reducedStyleTypes.push([\n                    `border-${type}`,\n                    value\n                ]);\n                // Remove it from the full set to not include it in the most specific properties later.\n                borderStyles.forEach((style)=>delete style[type]);\n            }\n            return reducedStyleTypes;\n        }, []);\n        // The reduced properties (by type) and all that remains that could not be reduced.\n        return [\n            ...reducedStyleTypes,\n            ...reduceBorderPosition(topStyles, 'top'),\n            ...reduceBorderPosition(rightStyles, 'right'),\n            ...reduceBorderPosition(bottomStyles, 'bottom'),\n            ...reduceBorderPosition(leftStyles, 'left')\n        ];\n    };\n    /**\n\t * @param styles The array of objects with `style`, `color`, `width` properties.\n\t */ function getReducedStyleValueForType(styles, type) {\n        return styles.map((style)=>style[type]).reduce((result, style)=>result == style ? result : null);\n    }\n}\nfunction getBorderPositionReducer(which) {\n    return (value)=>reduceBorderPosition(value, which);\n}\n/**\n * Returns an array with reduced border styles depending on the specified values.\n *\n * If all border properties (width, style, color) are specified, the returned selector will be\n * merged into a group: `border-*: [width] [style] [color]`.\n *\n * Otherwise, the specific definitions will be returned: `border-(width|style|color)-*: [value]`.\n *\n * @param value Styles if defined.\n * @param which The border position.\n */ function reduceBorderPosition(value, which) {\n    const borderTypes = [];\n    if (value && value.width) {\n        borderTypes.push('width');\n    }\n    if (value && value.style) {\n        borderTypes.push('style');\n    }\n    if (value && value.color) {\n        borderTypes.push('color');\n    }\n    if (borderTypes.length == 3) {\n        const borderValue = borderTypes.map((item)=>value[item]).join(' ');\n        return [\n            which == 'all' ? [\n                'border',\n                borderValue\n            ] : [\n                `border-${which}`,\n                borderValue\n            ]\n        ];\n    }\n    // We are unable to reduce to a single `border:` property.\n    if (which == 'all') {\n        return [];\n    }\n    return borderTypes.map((type)=>{\n        return [\n            `border-${which}-${type}`,\n            value[type]\n        ];\n    });\n}\n\n/**\n * Adds a margin CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addMarginRules );\n * ```\n *\n * The normalized value is stored as:\n *\n * ```ts\n * const styles = {\n * \tmargin: {\n * \t\ttop,\n * \t\tright,\n * \t\tbottom,\n * \t\tleft\n * \t}\n * };\n * ```\n */ function addMarginRules(stylesProcessor) {\n    stylesProcessor.setNormalizer('margin', getPositionShorthandNormalizer('margin'));\n    stylesProcessor.setNormalizer('margin-top', (value)=>({\n            path: 'margin.top',\n            value\n        }));\n    stylesProcessor.setNormalizer('margin-right', (value)=>({\n            path: 'margin.right',\n            value\n        }));\n    stylesProcessor.setNormalizer('margin-bottom', (value)=>({\n            path: 'margin.bottom',\n            value\n        }));\n    stylesProcessor.setNormalizer('margin-left', (value)=>({\n            path: 'margin.left',\n            value\n        }));\n    stylesProcessor.setReducer('margin', getBoxSidesValueReducer('margin'));\n    stylesProcessor.setStyleRelation('margin', [\n        'margin-top',\n        'margin-right',\n        'margin-bottom',\n        'margin-left'\n    ]);\n}\n\n/**\n * Adds a padding CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addPaddingRules );\n * ```\n *\n * The normalized value is stored as:\n *\n * ```ts\n * const styles = {\n * \tpadding: {\n * \t\ttop,\n * \t\tright,\n * \t\tbottom,\n * \t\tleft\n * \t}\n * };\n * ```\n */ function addPaddingRules(stylesProcessor) {\n    stylesProcessor.setNormalizer('padding', getPositionShorthandNormalizer('padding'));\n    stylesProcessor.setNormalizer('padding-top', (value)=>({\n            path: 'padding.top',\n            value\n        }));\n    stylesProcessor.setNormalizer('padding-right', (value)=>({\n            path: 'padding.right',\n            value\n        }));\n    stylesProcessor.setNormalizer('padding-bottom', (value)=>({\n            path: 'padding.bottom',\n            value\n        }));\n    stylesProcessor.setNormalizer('padding-left', (value)=>({\n            path: 'padding.left',\n            value\n        }));\n    stylesProcessor.setReducer('padding', getBoxSidesValueReducer('padding'));\n    stylesProcessor.setStyleRelation('padding', [\n        'padding-top',\n        'padding-right',\n        'padding-bottom',\n        'padding-left'\n    ]);\n}\n\nconst ELEMENT_RANGE_START_TOKEN = '[';\nconst ELEMENT_RANGE_END_TOKEN = ']';\nconst TEXT_RANGE_START_TOKEN = '{';\nconst TEXT_RANGE_END_TOKEN = '}';\nconst allowedTypes = {\n    'container': ContainerElement,\n    'attribute': AttributeElement,\n    'empty': EmptyElement,\n    'ui': UIElement,\n    'raw': RawElement\n};\n// Returns simplified implementation of {@link module:engine/view/domconverter~DomConverter#setContentOf DomConverter.setContentOf} method.\n// Used to render UIElement and RawElement.\nconst domConverterStub = {\n    setContentOf: (node, html)=>{\n        node.innerHTML = html;\n    }\n};\n/**\n * Writes the content of the {@link module:engine/view/document~Document document} to an HTML-like string.\n *\n * @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will\n * not be included in the returned string.\n * @param options.rootName The name of the root from which the data should be stringified. If not provided,\n * the default `main` name will be used.\n * @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n * instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n * @param options.showPriority When set to `true`, the attribute element's priority will be printed\n * (`<span view-priority=\"12\">`, `<b view-priority=\"10\">`).\n * @param options.showAttributeElementId When set to `true`, the attribute element's ID will be printed\n * (`<span id=\"marker:foo\">`).\n * @param options.renderUIElements When set to `true`, the inner content of each\n * {@link module:engine/view/uielement~UIElement} will be printed.\n * @param options.renderRawElements When set to `true`, the inner content of each\n * {@link module:engine/view/rawelement~RawElement} will be printed.\n * @param options.domConverter When set to an actual {@link module:engine/view/domconverter~DomConverter DomConverter}\n * instance, it lets the conversion go through exactly the same flow the editing view is going through,\n * i.e. with view data filtering. Otherwise the simple stub is used.\n * @returns The stringified data.\n */ function getData$1(view, options = {}) {\n    if (!(view instanceof View)) {\n        throw new TypeError('View needs to be an instance of module:engine/view/view~View.');\n    }\n    const document1 = view.document;\n    const withoutSelection = !!options.withoutSelection;\n    const rootName = options.rootName || 'main';\n    const root = document1.getRoot(rootName);\n    const stringifyOptions = {\n        showType: options.showType,\n        showPriority: options.showPriority,\n        renderUIElements: options.renderUIElements,\n        renderRawElements: options.renderRawElements,\n        ignoreRoot: true,\n        domConverter: options.domConverter\n    };\n    return withoutSelection ? getData$1._stringify(root, null, stringifyOptions) : getData$1._stringify(root, document1.selection, stringifyOptions);\n}\n// Set stringify as getData private method - needed for testing/spying.\ngetData$1._stringify = stringify$1;\n/**\n * Sets the content of a view {@link module:engine/view/document~Document document} provided as an HTML-like string.\n *\n * @param data An HTML-like string to write into the document.\n * @param options.rootName The root name where parsed data will be stored. If not provided,\n * the default `main` name will be used.\n */ function setData$1(view, data, options = {}) {\n    if (!(view instanceof View)) {\n        throw new TypeError('View needs to be an instance of module:engine/view/view~View.');\n    }\n    const document1 = view.document;\n    const rootName = options.rootName || 'main';\n    const root = document1.getRoot(rootName);\n    view.change((writer)=>{\n        const result = setData$1._parse(data, {\n            rootElement: root\n        });\n        if (result.view && result.selection) {\n            writer.setSelection(result.selection);\n        }\n    });\n}\n// Set parse as setData private method - needed for testing/spying.\nsetData$1._parse = parse$1;\n/**\n * Converts view elements to HTML-like string representation.\n *\n * A root element can be provided as {@link module:engine/view/text~Text text}:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * stringify( text ); // 'foobar'\n * ```\n *\n * or as an {@link module:engine/view/element~Element element}:\n *\n * ```ts\n * const element = downcastWriter.createElement( 'p', null, downcastWriter.createText( 'foobar' ) );\n * stringify( element ); // '<p>foobar</p>'\n * ```\n *\n * or as a {@link module:engine/view/documentfragment~DocumentFragment document fragment}:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const b = downcastWriter.createElement( 'b', { name: 'test' }, text );\n * const p = downcastWriter.createElement( 'p', { style: 'color:red;' } );\n * const fragment = downcastWriter.createDocumentFragment( [ p, b ] );\n *\n * stringify( fragment ); // '<p style=\"color:red;\"></p><b name=\"test\">foobar</b>'\n * ```\n *\n * Additionally, a {@link module:engine/view/documentselection~DocumentSelection selection} instance can be provided.\n * Ranges from the selection will then be included in the output data.\n * If a range position is placed inside the element node, it will be represented with `[` and `]`:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const b = downcastWriter.createElement( 'b', null, text );\n * const p = downcastWriter.createElement( 'p', null, b );\n * const selection = downcastWriter.createSelection(\n * \tdowncastWriter.createRangeIn( p )\n * );\n *\n * stringify( p, selection ); // '<p>[<b>foobar</b>]</p>'\n * ```\n *\n * If a range is placed inside the text node, it will be represented with `{` and `}`:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const b = downcastWriter.createElement( 'b', null, text );\n * const p = downcastWriter.createElement( 'p', null, b );\n * const selection = downcastWriter.createSelection(\n * \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 1 ), downcastWriter.createPositionAt( text, 5 ) )\n * );\n *\n * stringify( p, selection ); // '<p><b>f{ooba}r</b></p>'\n * ```\n *\n * ** Note: **\n * It is possible to unify selection markers to `[` and `]` for both (inside and outside text)\n * by setting the `sameSelectionCharacters=true` option. It is mainly used when the view stringify option is used by\n * model utilities.\n *\n * Multiple ranges are supported:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const selection = downcastWriter.createSelection( [\n * \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) ),\n * \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 3 ), downcastWriter.createPositionAt( text, 5 ) )\n * ] );\n *\n * stringify( text, selection ); // '{f}oo{ba}r'\n * ```\n *\n * A {@link module:engine/view/range~Range range} or {@link module:engine/view/position~Position position} instance can be provided\n * instead of the {@link module:engine/view/documentselection~DocumentSelection selection} instance. If a range instance\n * is provided, it will be converted to a selection containing this range. If a position instance is provided, it will\n * be converted to a selection containing one range collapsed at this position.\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const range = downcastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) );\n * const position = downcastWriter.createPositionAt( text, 3 );\n *\n * stringify( text, range ); // '{f}oobar'\n * stringify( text, position ); // 'foo{}bar'\n * ```\n *\n * An additional `options` object can be provided.\n * If `options.showType` is set to `true`, element's types will be\n * presented for {@link module:engine/view/attributeelement~AttributeElement attribute elements},\n * {@link module:engine/view/containerelement~ContainerElement container elements}\n * {@link module:engine/view/emptyelement~EmptyElement empty elements}\n * and {@link module:engine/view/uielement~UIElement UI elements}:\n *\n * ```ts\n * const attribute = downcastWriter.createAttributeElement( 'b' );\n * const container = downcastWriter.createContainerElement( 'p' );\n * const empty = downcastWriter.createEmptyElement( 'img' );\n * const ui = downcastWriter.createUIElement( 'span' );\n * getData( attribute, null, { showType: true } ); // '<attribute:b></attribute:b>'\n * getData( container, null, { showType: true } ); // '<container:p></container:p>'\n * getData( empty, null, { showType: true } ); // '<empty:img></empty:img>'\n * getData( ui, null, { showType: true } ); // '<ui:span></ui:span>'\n * ```\n *\n * If `options.showPriority` is set to `true`, a priority will be displayed for all\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements}.\n *\n * ```ts\n * const attribute = downcastWriter.createAttributeElement( 'b' );\n * attribute._priority = 20;\n * getData( attribute, null, { showPriority: true } ); // <b view-priority=\"20\"></b>\n * ```\n *\n * If `options.showAttributeElementId` is set to `true`, the attribute element's id will be displayed for all\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that have it set.\n *\n * ```ts\n * const attribute = downcastWriter.createAttributeElement( 'span' );\n * attribute._id = 'marker:foo';\n * getData( attribute, null, { showAttributeElementId: true } ); // <span view-id=\"marker:foo\"></span>\n * ```\n *\n * @param node The node to stringify.\n * @param selectionOrPositionOrRange A selection instance whose ranges will be included in the returned string data.\n * If a range instance is provided, it will be converted to a selection containing this range. If a position instance\n * is provided, it will be converted to a selection containing one range collapsed at this position.\n * @param options An object with additional options.\n * @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n * instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n * @param options.showPriority When set to `true`,  the attribute element's priority will be printed\n * (`<span view-priority=\"12\">`, `<b view-priority=\"10\">`).\n * @param options.showAttributeElementId When set to `true`, attribute element's id will be printed\n * (`<span id=\"marker:foo\">`).\n * @param options.ignoreRoot When set to `true`, the root's element opening and closing will not be printed.\n * Mainly used by the `getData` function to ignore the {@link module:engine/view/document~Document document's} root element.\n * @param options.sameSelectionCharacters When set to `true`, the selection inside the text will be marked as\n *  `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both will be marked as `[` and `]` only.\n * @param options.renderUIElements When set to `true`, the inner content of each\n * {@link module:engine/view/uielement~UIElement} will be printed.\n * @param options.renderRawElements When set to `true`, the inner content of each\n * {@link module:engine/view/rawelement~RawElement} will be printed.\n * @param options.domConverter When set to an actual {@link module:engine/view/domconverter~DomConverter DomConverter}\n * instance, it lets the conversion go through exactly the same flow the editing view is going through,\n * i.e. with view data filtering. Otherwise the simple stub is used.\n * @returns An HTML-like string representing the view.\n */ function stringify$1(node, selectionOrPositionOrRange = null, options = {}) {\n    let selection;\n    if (selectionOrPositionOrRange instanceof Position$1 || selectionOrPositionOrRange instanceof Range$1) {\n        selection = new DocumentSelection$1(selectionOrPositionOrRange);\n    } else {\n        selection = selectionOrPositionOrRange;\n    }\n    const viewStringify = new ViewStringify(node, selection, options);\n    return viewStringify.stringify();\n}\n/**\n * Parses an HTML-like string and returns a view tree.\n * A simple string will be converted to a {@link module:engine/view/text~Text text} node:\n *\n * ```ts\n * parse( 'foobar' ); // Returns an instance of text.\n * ```\n *\n * {@link module:engine/view/element~Element Elements} will be parsed with attributes as children:\n *\n * ```ts\n * parse( '<b name=\"baz\">foobar</b>' ); // Returns an instance of element with the `baz` attribute and a text child node.\n * ```\n *\n * Multiple nodes provided on root level will be converted to a\n * {@link module:engine/view/documentfragment~DocumentFragment document fragment}:\n *\n * ```ts\n * parse( '<b>foo</b><i>bar</i>' ); // Returns a document fragment with two child elements.\n * ```\n *\n * The method can parse multiple {@link module:engine/view/range~Range ranges} provided in string data and return a\n * {@link module:engine/view/documentselection~DocumentSelection selection} instance containing these ranges. Ranges placed inside\n * {@link module:engine/view/text~Text text} nodes should be marked using `{` and `}` brackets:\n *\n * ```ts\n * const { text, selection } = parse( 'f{ooba}r' );\n * ```\n *\n * Ranges placed outside text nodes should be marked using `[` and `]` brackets:\n *\n * ```ts\n * const { root, selection } = parse( '<p>[<b>foobar</b>]</p>' );\n * ```\n *\n * ** Note: **\n * It is possible to unify selection markers to `[` and `]` for both (inside and outside text)\n * by setting `sameSelectionCharacters=true` option. It is mainly used when the view parse option is used by model utilities.\n *\n * Sometimes there is a need for defining the order of ranges inside the created selection. This can be achieved by providing\n * the range order array as an additional parameter:\n *\n * ```ts\n * const { root, selection } = parse( '{fo}ob{ar}{ba}z', { order: [ 2, 3, 1 ] } );\n * ```\n *\n * In the example above, the first range (`{fo}`) will be added to the selection as the second one, the second range (`{ar}`) will be\n * added as the third and the third range (`{ba}`) will be added as the first one.\n *\n * If the selection's last range should be added as a backward one\n * (so the {@link module:engine/view/documentselection~DocumentSelection#anchor selection anchor} is represented\n * by the `end` position and {@link module:engine/view/documentselection~DocumentSelection#focus selection focus} is\n * represented by the `start` position), use the `lastRangeBackward` flag:\n *\n * ```ts\n * const { root, selection } = parse( `{foo}bar{baz}`, { lastRangeBackward: true } );\n * ```\n *\n * Some more examples and edge cases:\n *\n * ```ts\n * // Returns an empty document fragment.\n * parse( '' );\n *\n * // Returns an empty document fragment and a collapsed selection.\n * const { root, selection } = parse( '[]' );\n *\n * // Returns an element and a selection that is placed inside the document fragment containing that element.\n * const { root, selection } = parse( '[<a></a>]' );\n * ```\n *\n * @param data An HTML-like string to be parsed.\n * @param options.order An array with the order of parsed ranges added to the returned\n * {@link module:engine/view/documentselection~DocumentSelection Selection} instance. Each element should represent the\n * desired position of each range in the selection instance. For example: `[2, 3, 1]` means that the first range will be\n * placed as the second, the second as the third and the third as the first.\n * @param options.lastRangeBackward If set to `true`, the last range will be added as backward to the returned\n * {@link module:engine/view/documentselection~DocumentSelection selection} instance.\n * @param options.rootElement The default root to use when parsing elements.\n * When set to `null`, the root element will be created automatically. If set to\n * {@link module:engine/view/element~Element Element} or {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment},\n * this node will be used as the root for all parsed nodes.\n * @param options.sameSelectionCharacters When set to `false`, the selection inside the text should be marked using\n * `{` and `}` and the selection outside the ext using `[` and `]`. When set to `true`, both should be marked with `[` and `]` only.\n * @param options.stylesProcessor Styles processor.\n * @returns Returns the parsed view node or an object with two fields: `view` and `selection` when selection ranges were included in the\n * data to parse.\n */ function parse$1(data, options = {}) {\n    const viewDocument = new Document$1(new StylesProcessor());\n    options.order = options.order || [];\n    const rangeParser = new RangeParser({\n        sameSelectionCharacters: options.sameSelectionCharacters\n    });\n    const processor = new XmlDataProcessor(viewDocument, {\n        namespaces: Object.keys(allowedTypes)\n    });\n    if (options.inlineObjectElements) {\n        processor.domConverter.inlineObjectElements.push(...options.inlineObjectElements);\n    }\n    // Convert data to view.\n    let view = processor.toView(data);\n    // At this point we have a view tree with Elements that could have names like `attribute:b:1`. In the next step\n    // we need to parse Element's names and convert them to AttributeElements and ContainerElements.\n    view = _convertViewElements(view);\n    // If custom root is provided - move all nodes there.\n    if (options.rootElement) {\n        const root = options.rootElement;\n        const nodes = view._removeChildren(0, view.childCount);\n        root._removeChildren(0, root.childCount);\n        root._appendChild(nodes);\n        view = root;\n    }\n    // Parse ranges included in view text nodes.\n    const ranges = rangeParser.parse(view, options.order);\n    // If only one element is returned inside DocumentFragment - return that element.\n    if (view.is('documentFragment') && view.childCount === 1) {\n        view = view.getChild(0);\n    }\n    // When ranges are present - return object containing view, and selection.\n    if (ranges.length) {\n        const selection = new DocumentSelection$1(ranges, {\n            backward: !!options.lastRangeBackward\n        });\n        return {\n            view,\n            selection\n        };\n    }\n    // If single element is returned without selection - remove it from parent and return detached element.\n    if (view.parent) {\n        view._remove();\n    }\n    return view;\n}\n/**\n * Private helper class used for converting ranges represented as text inside view {@link module:engine/view/text~Text text nodes}.\n */ class RangeParser {\n    sameSelectionCharacters;\n    _positions;\n    /**\n\t * Creates a range parser instance.\n\t *\n\t * @param options The range parser configuration.\n\t * @param options.sameSelectionCharacters When set to `true`, the selection inside the text is marked as\n\t * `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both are marked as `[` and `]`.\n\t */ constructor(options){\n        this.sameSelectionCharacters = !!options.sameSelectionCharacters;\n    }\n    /**\n\t * Parses the view and returns ranges represented inside {@link module:engine/view/text~Text text nodes}.\n\t * The method will remove all occurrences of `{`, `}`, `[` and `]` from found text nodes. If a text node is empty after\n\t * the process, it will be removed, too.\n\t *\n\t * @param node The starting node.\n\t * @param order The order of ranges. Each element should represent the desired position of the range after\n\t * sorting. For example: `[2, 3, 1]` means that the first range will be placed as the second, the second as the third and the third\n\t * as the first.\n\t * @returns An array with ranges found.\n\t */ parse(node, order) {\n        this._positions = [];\n        // Remove all range brackets from view nodes and save their positions.\n        this._getPositions(node);\n        // Create ranges using gathered positions.\n        let ranges = this._createRanges();\n        // Sort ranges if needed.\n        if (order.length) {\n            if (order.length != ranges.length) {\n                throw new Error(`Parse error - there are ${ranges.length} ranges found, but ranges order array contains ${order.length} elements.`);\n            }\n            ranges = this._sortRanges(ranges, order);\n        }\n        return ranges;\n    }\n    /**\n\t * Gathers positions of brackets inside the view tree starting from the provided node. The method will remove all occurrences of\n\t * `{`, `}`, `[` and `]` from found text nodes. If a text node is empty after the process, it will be removed, too.\n\t *\n\t * @param node Staring node.\n\t */ _getPositions(node) {\n        if (node.is('documentFragment') || node.is('element')) {\n            // Copy elements into the array, when nodes will be removed from parent node this array will still have all the\n            // items needed for iteration.\n            const children = [\n                ...node.getChildren()\n            ];\n            for (const child of children){\n                this._getPositions(child);\n            }\n        }\n        if (node.is('$text')) {\n            const regexp = new RegExp(`[${TEXT_RANGE_START_TOKEN}${TEXT_RANGE_END_TOKEN}\\\\${ELEMENT_RANGE_END_TOKEN}\\\\${ELEMENT_RANGE_START_TOKEN}]`, 'g');\n            let text = node.data;\n            let match;\n            let offset = 0;\n            const brackets = [];\n            // Remove brackets from text and store info about offset inside text node.\n            while(match = regexp.exec(text)){\n                const index = match.index;\n                const bracket = match[0];\n                brackets.push({\n                    bracket,\n                    textOffset: index - offset\n                });\n                offset++;\n            }\n            text = text.replace(regexp, '');\n            node._data = text;\n            const index = node.index;\n            const parent = node.parent;\n            // Remove empty text nodes.\n            if (!text) {\n                node._remove();\n            }\n            for (const item of brackets){\n                // Non-empty text node.\n                if (text) {\n                    if (this.sameSelectionCharacters || !this.sameSelectionCharacters && (item.bracket == TEXT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN)) {\n                        // Store information about text range delimiter.\n                        this._positions.push({\n                            bracket: item.bracket,\n                            position: new Position$1(node, item.textOffset)\n                        });\n                    } else {\n                        // Check if element range delimiter is not placed inside text node.\n                        if (!this.sameSelectionCharacters && item.textOffset !== 0 && item.textOffset !== text.length) {\n                            throw new Error(`Parse error - range delimiter '${item.bracket}' is placed inside text node.`);\n                        }\n                        // If bracket is placed at the end of the text node - it should be positioned after it.\n                        const offset = item.textOffset === 0 ? index : index + 1;\n                        // Store information about element range delimiter.\n                        this._positions.push({\n                            bracket: item.bracket,\n                            position: new Position$1(parent, offset)\n                        });\n                    }\n                } else {\n                    if (!this.sameSelectionCharacters && item.bracket == TEXT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN) {\n                        throw new Error(`Parse error - text range delimiter '${item.bracket}' is placed inside empty text node. `);\n                    }\n                    // Store information about element range delimiter.\n                    this._positions.push({\n                        bracket: item.bracket,\n                        position: new Position$1(parent, index)\n                    });\n                }\n            }\n        }\n    }\n    /**\n\t * Sorts ranges in a given order. Range order should be an array and each element should represent the desired position\n\t * of the range after sorting.\n\t * For example: `[2, 3, 1]` means that the first range will be placed as the second, the second as the third and the third\n\t * as the first.\n\t *\n\t * @param ranges Ranges to sort.\n\t * @param rangesOrder An array with new range order.\n\t * @returns Sorted ranges array.\n\t */ _sortRanges(ranges, rangesOrder) {\n        const sortedRanges = [];\n        let index = 0;\n        for (const newPosition of rangesOrder){\n            if (ranges[newPosition - 1] === undefined) {\n                throw new Error('Parse error - provided ranges order is invalid.');\n            }\n            sortedRanges[newPosition - 1] = ranges[index];\n            index++;\n        }\n        return sortedRanges;\n    }\n    /**\n\t * Uses all found bracket positions to create ranges from them.\n\t */ _createRanges() {\n        const ranges = [];\n        let range = null;\n        for (const item of this._positions){\n            // When end of range is found without opening.\n            if (!range && (item.bracket == ELEMENT_RANGE_END_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN)) {\n                throw new Error(`Parse error - end of range was found '${item.bracket}' but range was not started before.`);\n            }\n            // When second start of range is found when one is already opened - selection does not allow intersecting\n            // ranges.\n            if (range && (item.bracket == ELEMENT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_START_TOKEN)) {\n                throw new Error(`Parse error - start of range was found '${item.bracket}' but one range is already started.`);\n            }\n            if (item.bracket == ELEMENT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_START_TOKEN) {\n                range = new Range$1(item.position, item.position);\n            } else {\n                range.end = item.position;\n                ranges.push(range);\n                range = null;\n            }\n        }\n        // Check if all ranges have proper ending.\n        if (range !== null) {\n            throw new Error('Parse error - range was started but no end delimiter was found.');\n        }\n        return ranges;\n    }\n}\n/**\n * Private helper class used for converting the view tree to a string.\n */ class ViewStringify {\n    root;\n    selection;\n    ranges;\n    showType;\n    showPriority;\n    showAttributeElementId;\n    ignoreRoot;\n    sameSelectionCharacters;\n    renderUIElements;\n    renderRawElements;\n    domConverter;\n    /**\n\t * Creates a view stringify instance.\n\t *\n\t * @param selection A selection whose ranges should also be converted to a string.\n\t * @param options An options object.\n\t * @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n\t * instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n\t * @param options.showPriority When set to `true`, the attribute element's priority will be printed.\n\t * @param options.ignoreRoot When set to `true`, the root's element opening and closing tag will not\n\t * be outputted.\n\t * @param options.sameSelectionCharacters When set to `true`, the selection inside the text is marked as\n\t * `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both are marked as `[` and `]`.\n\t * @param options.renderUIElements When set to `true`, the inner content of each\n\t * {@link module:engine/view/uielement~UIElement} will be printed.\n\t * @param options.renderRawElements When set to `true`, the inner content of each\n\t * @param options.domConverter When set to an actual {@link module:engine/view/domconverter~DomConverter DomConverter}\n\t * instance, it lets the conversion go through exactly the same flow the editing view is going through,\n\t * i.e. with view data filtering. Otherwise the simple stub is used.\n\t * {@link module:engine/view/rawelement~RawElement} will be printed.\n\t */ constructor(root, selection, options){\n        this.root = root;\n        this.selection = selection;\n        this.ranges = [];\n        if (selection) {\n            this.ranges = [\n                ...selection.getRanges()\n            ];\n        }\n        this.showType = !!options.showType;\n        this.showPriority = !!options.showPriority;\n        this.showAttributeElementId = !!options.showAttributeElementId;\n        this.ignoreRoot = !!options.ignoreRoot;\n        this.sameSelectionCharacters = !!options.sameSelectionCharacters;\n        this.renderUIElements = !!options.renderUIElements;\n        this.renderRawElements = !!options.renderRawElements;\n        this.domConverter = options.domConverter || domConverterStub;\n    }\n    /**\n\t * Converts the view to a string.\n\t *\n\t * @returns String representation of the view elements.\n\t */ stringify() {\n        let result = '';\n        this._walkView(this.root, (chunk)=>{\n            result += chunk;\n        });\n        return result;\n    }\n    /**\n\t * Executes a simple walker that iterates over all elements in the view tree starting from the root element.\n\t * Calls the `callback` with parsed chunks of string data.\n\t */ _walkView(root, callback) {\n        const ignore = this.ignoreRoot && this.root === root;\n        if (root.is('element') || root.is('documentFragment')) {\n            if (root.is('element') && !ignore) {\n                callback(this._stringifyElementOpen(root));\n            }\n            if (this.renderUIElements && root.is('uiElement')) {\n                callback(root.render(document, this.domConverter).innerHTML);\n            } else if (this.renderRawElements && root.is('rawElement')) {\n                // There's no DOM element for \"root\" to pass to render(). Creating\n                // a surrogate container to render the children instead.\n                const rawContentContainer = document.createElement('div');\n                root.render(rawContentContainer, this.domConverter);\n                callback(rawContentContainer.innerHTML);\n            } else {\n                let offset = 0;\n                callback(this._stringifyElementRanges(root, offset));\n                for (const child of root.getChildren()){\n                    this._walkView(child, callback);\n                    offset++;\n                    callback(this._stringifyElementRanges(root, offset));\n                }\n            }\n            if (root.is('element') && !ignore) {\n                callback(this._stringifyElementClose(root));\n            }\n        }\n        if (root.is('$text')) {\n            callback(this._stringifyTextRanges(root));\n        }\n    }\n    /**\n\t * Checks if a given {@link module:engine/view/element~Element element} has a {@link module:engine/view/range~Range#start range start}\n\t * or a {@link module:engine/view/range~Range#start range end} placed at a given offset and returns its string representation.\n\t */ _stringifyElementRanges(element, offset) {\n        let start = '';\n        let end = '';\n        let collapsed = '';\n        for (const range of this.ranges){\n            if (range.start.parent == element && range.start.offset === offset) {\n                if (range.isCollapsed) {\n                    collapsed += ELEMENT_RANGE_START_TOKEN + ELEMENT_RANGE_END_TOKEN;\n                } else {\n                    start += ELEMENT_RANGE_START_TOKEN;\n                }\n            }\n            if (range.end.parent === element && range.end.offset === offset && !range.isCollapsed) {\n                end += ELEMENT_RANGE_END_TOKEN;\n            }\n        }\n        return end + collapsed + start;\n    }\n    /**\n\t * Checks if a given {@link module:engine/view/element~Element Text node} has a\n\t * {@link module:engine/view/range~Range#start range start} or a\n\t * {@link module:engine/view/range~Range#start range end} placed somewhere inside. Returns a string representation of text\n\t * with range delimiters placed inside.\n\t */ _stringifyTextRanges(node) {\n        const length = node.data.length;\n        const data = node.data.split('');\n        let rangeStartToken, rangeEndToken;\n        if (this.sameSelectionCharacters) {\n            rangeStartToken = ELEMENT_RANGE_START_TOKEN;\n            rangeEndToken = ELEMENT_RANGE_END_TOKEN;\n        } else {\n            rangeStartToken = TEXT_RANGE_START_TOKEN;\n            rangeEndToken = TEXT_RANGE_END_TOKEN;\n        }\n        // Add one more element for ranges ending after last character in text.\n        data[length] = '';\n        // Represent each letter as object with information about opening/closing ranges at each offset.\n        const result = data.map((letter)=>{\n            return {\n                letter,\n                start: '',\n                end: '',\n                collapsed: ''\n            };\n        });\n        for (const range of this.ranges){\n            const start = range.start;\n            const end = range.end;\n            if (start.parent == node && start.offset >= 0 && start.offset <= length) {\n                if (range.isCollapsed) {\n                    result[end.offset].collapsed += rangeStartToken + rangeEndToken;\n                } else {\n                    result[start.offset].start += rangeStartToken;\n                }\n            }\n            if (end.parent == node && end.offset >= 0 && end.offset <= length && !range.isCollapsed) {\n                result[end.offset].end += rangeEndToken;\n            }\n        }\n        return result.map((item)=>item.end + item.collapsed + item.start + item.letter).join('');\n    }\n    /**\n\t * Converts the passed {@link module:engine/view/element~Element element} to an opening tag.\n\t *\n\t * Depending on the current configuration, the opening tag can be simple (`<a>`), contain a type prefix (`<container:p>`,\n\t * `<attribute:a>` or `<empty:img>`), contain priority information ( `<attribute:a view-priority=\"20\">` ),\n\t * or contain element id ( `<attribute:span view-id=\"foo\">` ). Element attributes will also be included\n\t * (`<a href=\"https://ckeditor.com\" name=\"foobar\">`).\n\t */ _stringifyElementOpen(element) {\n        const priority = this._stringifyElementPriority(element);\n        const id = this._stringifyElementId(element);\n        const type = this._stringifyElementType(element);\n        const name = [\n            type,\n            element.name\n        ].filter((i)=>i !== '').join(':');\n        const attributes = this._stringifyElementAttributes(element);\n        const parts = [\n            name,\n            priority,\n            id,\n            attributes\n        ];\n        return `<${parts.filter((i)=>i !== '').join(' ')}>`;\n    }\n    /**\n\t * Converts the passed {@link module:engine/view/element~Element element} to a closing tag.\n\t * Depending on the current configuration, the closing tag can be simple (`</a>`) or contain a type prefix (`</container:p>`,\n\t * `</attribute:a>` or `</empty:img>`).\n\t */ _stringifyElementClose(element) {\n        const type = this._stringifyElementType(element);\n        const name = [\n            type,\n            element.name\n        ].filter((i)=>i !== '').join(':');\n        return `</${name}>`;\n    }\n    /**\n\t * Converts the passed {@link module:engine/view/element~Element element's} type to its string representation\n\t *\n\t * Returns:\n\t * * 'attribute' for {@link module:engine/view/attributeelement~AttributeElement attribute elements},\n\t * * 'container' for {@link module:engine/view/containerelement~ContainerElement container elements},\n\t * * 'empty' for {@link module:engine/view/emptyelement~EmptyElement empty elements},\n\t * * 'ui' for {@link module:engine/view/uielement~UIElement UI elements},\n\t * * 'raw' for {@link module:engine/view/rawelement~RawElement raw elements},\n\t * * an empty string when the current configuration is preventing showing elements' types.\n\t */ _stringifyElementType(element) {\n        if (this.showType) {\n            for(const type in allowedTypes){\n                if (element instanceof allowedTypes[type]) {\n                    return type;\n                }\n            }\n        }\n        return '';\n    }\n    /**\n\t * Converts the passed {@link module:engine/view/element~Element element} to its priority representation.\n\t *\n\t * The priority string representation will be returned when the passed element is an instance of\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute element} and the current configuration allows to show the\n\t * priority. Otherwise returns an empty string.\n\t */ _stringifyElementPriority(element) {\n        if (this.showPriority && element.is('attributeElement')) {\n            return `view-priority=\"${element.priority}\"`;\n        }\n        return '';\n    }\n    /**\n\t * Converts the passed {@link module:engine/view/element~Element element} to its id representation.\n\t *\n\t * The id string representation will be returned when the passed element is an instance of\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute element}, the element has an id\n\t * and the current configuration allows to show the id. Otherwise returns an empty string.\n\t */ _stringifyElementId(element) {\n        if (this.showAttributeElementId && element.is('attributeElement') && element.id) {\n            return `view-id=\"${element.id}\"`;\n        }\n        return '';\n    }\n    /**\n\t * Converts the passed {@link module:engine/view/element~Element element} attributes to their string representation.\n\t * If an element has no attributes, an empty string is returned.\n\t */ _stringifyElementAttributes(element) {\n        const attributes = [];\n        const keys = [\n            ...element.getAttributeKeys()\n        ].sort();\n        for (const attribute of keys){\n            let attributeValue;\n            if (attribute === 'class') {\n                attributeValue = [\n                    ...element.getClassNames()\n                ].sort().join(' ');\n            } else if (attribute === 'style') {\n                attributeValue = [\n                    ...element.getStyleNames()\n                ].sort().map((style)=>`${style}:${element.getStyle(style).replace(/\"/g, '&quot;')}`).join(';');\n            } else {\n                attributeValue = element.getAttribute(attribute);\n            }\n            attributes.push(`${attribute}=\"${attributeValue}\"`);\n        }\n        return attributes.join(' ');\n    }\n}\n/**\n * Converts {@link module:engine/view/element~Element elements} to\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements},\n * {@link module:engine/view/containerelement~ContainerElement container elements},\n * {@link module:engine/view/emptyelement~EmptyElement empty elements} or\n * {@link module:engine/view/uielement~UIElement UI elements}.\n * It converts the whole tree starting from the `rootNode`. The conversion is based on element names.\n * See the `_convertElement` method for more details.\n *\n * @param rootNode The root node to convert.\n * @returns The root node of converted elements.\n */ function _convertViewElements(rootNode) {\n    if (rootNode.is('element') || rootNode.is('documentFragment')) {\n        // Convert element or leave document fragment.\n        const convertedElement = rootNode.is('documentFragment') ? new DocumentFragment$1(rootNode.document) : _convertElement(rootNode.document, rootNode);\n        // Convert all child nodes.\n        // Cache the nodes in array. Otherwise, we would skip some nodes because during iteration we move nodes\n        // from `rootNode` to `convertedElement`. This would interfere with iteration.\n        for (const child of [\n            ...rootNode.getChildren()\n        ]){\n            if (convertedElement.is('emptyElement')) {\n                throw new Error('Parse error - cannot parse inside EmptyElement.');\n            } else if (convertedElement.is('uiElement')) {\n                throw new Error('Parse error - cannot parse inside UIElement.');\n            } else if (convertedElement.is('rawElement')) {\n                throw new Error('Parse error - cannot parse inside RawElement.');\n            }\n            convertedElement._appendChild(_convertViewElements(child));\n        }\n        return convertedElement;\n    }\n    return rootNode;\n}\n/**\n * Converts an {@link module:engine/view/element~Element element} to\n * {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/containerelement~ContainerElement container element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element} or\n * {@link module:engine/view/uielement~UIElement UI element}.\n * If the element's name is in the format of `attribute:b`, it will be converted to\n * an {@link module:engine/view/attributeelement~AttributeElement attribute element} with a priority of 11.\n * Additionally, attribute elements may have specified priority (for example `view-priority=\"11\"`) and/or\n * id (for example `view-id=\"foo\"`).\n * If the element's name is in the format of `container:p`, it will be converted to\n * a {@link module:engine/view/containerelement~ContainerElement container element}.\n * If the element's name is in the format of `empty:img`, it will be converted to\n * an {@link module:engine/view/emptyelement~EmptyElement empty element}.\n * If the element's name is in the format of `ui:span`, it will be converted to\n * a {@link module:engine/view/uielement~UIElement UI element}.\n * If the element's name does not contain any additional information, a {@link module:engine/view/element~Element view Element} will be\n * returned.\n *\n * @param viewElement A view element to convert.\n * @returns A tree view element converted according to its name.\n */ function _convertElement(viewDocument, viewElement) {\n    const info = _convertElementNameAndInfo(viewElement);\n    const ElementConstructor = allowedTypes[info.type];\n    const newElement = ElementConstructor ? new ElementConstructor(viewDocument, info.name) : new Element$1(viewDocument, info.name);\n    if (newElement.is('attributeElement')) {\n        if (info.priority !== null) {\n            newElement._priority = info.priority;\n        }\n        if (info.id !== null) {\n            newElement._id = info.id;\n        }\n    }\n    // Move attributes.\n    for (const attributeKey of viewElement.getAttributeKeys()){\n        newElement._setAttribute(attributeKey, viewElement.getAttribute(attributeKey));\n    }\n    return newElement;\n}\n/**\n * Converts the `view-priority` attribute and the {@link module:engine/view/element~Element#name element's name} information needed for\n * creating {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/containerelement~ContainerElement container element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element} or\n * {@link module:engine/view/uielement~UIElement UI element}.\n * The name can be provided in two formats: as a simple element's name (`div`), or as a type and name (`container:div`,\n * `attribute:span`, `empty:img`, `ui:span`);\n *\n * @param viewElement The element whose name should be converted.\n * @returns An object with parsed information:\n * * `name` The parsed name of the element.\n * * `type` The parsed type of the element. It can be `attribute`, `container` or `empty`.\n * * `priority` The parsed priority of the element.\n */ function _convertElementNameAndInfo(viewElement) {\n    const parts = viewElement.name.split(':');\n    const priority = _convertPriority(viewElement.getAttribute('view-priority'));\n    const id = viewElement.hasAttribute('view-id') ? viewElement.getAttribute('view-id') : null;\n    viewElement._removeAttribute('view-priority');\n    viewElement._removeAttribute('view-id');\n    if (parts.length == 1) {\n        return {\n            name: parts[0],\n            type: priority !== null ? 'attribute' : null,\n            priority,\n            id\n        };\n    }\n    // Check if type and name: container:div.\n    const type = _convertType(parts[0]);\n    if (type) {\n        return {\n            name: parts[1],\n            type,\n            priority,\n            id\n        };\n    }\n    throw new Error(`Parse error - cannot parse element's name: ${viewElement.name}.`);\n}\n/**\n * Checks if the element's type is allowed. Returns `attribute`, `container`, `empty` or `null`.\n */ function _convertType(type) {\n    return type in allowedTypes ? type : null;\n}\n/**\n * Checks if a given priority is allowed. Returns null if the priority cannot be converted.\n */ function _convertPriority(priorityString) {\n    const priority = parseInt(priorityString, 10);\n    if (!isNaN(priority)) {\n        return priority;\n    }\n    return null;\n}\n\n/**\n * Writes the content of a model {@link module:engine/model/document~Document document} to an HTML-like string.\n *\n * ```ts\n * getData( editor.model ); // -> '<paragraph>Foo![]</paragraph>'\n * ```\n *\n * **Note:** A {@link module:engine/model/text~Text text} node that contains attributes will be represented as:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * **Note:** Using this tool in production-grade code is not recommended. It was designed for development, prototyping,\n * debugging and testing.\n *\n * @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will\n * not be included in the returned string.\n * @param options.rootName The name of the root from which the data should be stringified. If not provided,\n * the default `main` name will be used.\n * @param options.convertMarkers Whether to include markers in the returned string.\n * @returns The stringified data.\n */ function getData(model, options = {}) {\n    if (!(model instanceof Model)) {\n        throw new TypeError('Model needs to be an instance of module:engine/model/model~Model.');\n    }\n    const rootName = options.rootName || 'main';\n    const root = model.document.getRoot(rootName);\n    return getData._stringify(root, options.withoutSelection ? null : model.document.selection, options.convertMarkers ? model.markers : null);\n}\n// Set stringify as getData private method - needed for testing/spying.\ngetData._stringify = stringify;\n/**\n * Sets the content of a model {@link module:engine/model/document~Document document} provided as an HTML-like string.\n *\n * ```ts\n * setData( editor.model, '<paragraph>Foo![]</paragraph>' );\n * ```\n *\n * **Note:** Remember to register elements in the {@link module:engine/model/model~Model#schema model's schema} before\n * trying to use them.\n *\n * **Note:** To create a {@link module:engine/model/text~Text text} node that contains attributes use:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * **Note:** Using this tool in production-grade code is not recommended. It was designed for development, prototyping,\n * debugging and testing.\n *\n * @param data HTML-like string to write into the document.\n * @param options.rootName Root name where parsed data will be stored. If not provided, the default `main`\n * name will be used.\n * @param options.selectionAttributes A list of attributes which will be passed to the selection.\n * @param options.lastRangeBackward If set to `true`, the last range will be added as backward.\n * @param options.batchType Batch type used for inserting elements. See {@link module:engine/model/batch~Batch#constructor}.\n * See {@link module:engine/model/batch~Batch#type}.\n */ function setData(model, data, options = {}) {\n    if (!(model instanceof Model)) {\n        throw new TypeError('Model needs to be an instance of module:engine/model/model~Model.');\n    }\n    let modelDocumentFragment;\n    let selection = null;\n    const modelRoot = model.document.getRoot(options.rootName || 'main');\n    // Parse data string to model.\n    const parsedResult = setData._parse(data, model.schema, {\n        lastRangeBackward: options.lastRangeBackward,\n        selectionAttributes: options.selectionAttributes,\n        context: [\n            modelRoot.name\n        ],\n        inlineObjectElements: options.inlineObjectElements\n    });\n    // Retrieve DocumentFragment and Selection from parsed model.\n    if ('model' in parsedResult) {\n        modelDocumentFragment = parsedResult.model;\n        selection = parsedResult.selection;\n    } else {\n        modelDocumentFragment = parsedResult;\n    }\n    if (options.batchType !== undefined) {\n        model.enqueueChange(options.batchType, writeToModel);\n    } else {\n        model.change(writeToModel);\n    }\n    function writeToModel(writer) {\n        // Replace existing model in document by new one.\n        writer.remove(writer.createRangeIn(modelRoot));\n        writer.insert(modelDocumentFragment, modelRoot);\n        // Clean up previous document selection.\n        writer.setSelection(null);\n        writer.removeSelectionAttribute(model.document.selection.getAttributeKeys());\n        // Update document selection if specified.\n        if (selection) {\n            const ranges = [];\n            for (const range of selection.getRanges()){\n                const start = new Position(modelRoot, range.start.path);\n                const end = new Position(modelRoot, range.end.path);\n                ranges.push(new Range(start, end));\n            }\n            writer.setSelection(ranges, {\n                backward: selection.isBackward\n            });\n            if (options.selectionAttributes) {\n                writer.setSelectionAttribute(selection.getAttributes());\n            }\n        }\n    }\n}\n// Set parse as setData private method - needed for testing/spying.\nsetData._parse = parse;\n/**\n * Converts model nodes to HTML-like string representation.\n *\n * **Note:** A {@link module:engine/model/text~Text text} node that contains attributes will be represented as:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * @param node A node to stringify.\n * @param selectionOrPositionOrRange A selection instance whose ranges will be included in the returned string data.\n * If a range instance is provided, it will be converted to a selection containing this range. If a position instance\n * is provided, it will be converted to a selection containing one range collapsed at this position.\n * @param markers Markers to include.\n * @returns An HTML-like string representing the model.\n */ function stringify(node, selectionOrPositionOrRange = null, markers = null) {\n    const model = new Model();\n    const mapper = new Mapper();\n    let selection = null;\n    let range;\n    // Create a range witch wraps passed node.\n    if (node instanceof RootElement || node instanceof DocumentFragment) {\n        range = model.createRangeIn(node);\n    } else {\n        // Node is detached - create new document fragment.\n        if (!node.parent) {\n            const fragment = new DocumentFragment(node);\n            range = model.createRangeIn(fragment);\n        } else {\n            range = new Range(model.createPositionBefore(node), model.createPositionAfter(node));\n        }\n    }\n    // Get selection from passed selection or position or range if at least one is specified.\n    if (selectionOrPositionOrRange instanceof Selection) {\n        selection = selectionOrPositionOrRange;\n    } else if (selectionOrPositionOrRange instanceof DocumentSelection) {\n        selection = selectionOrPositionOrRange;\n    } else if (selectionOrPositionOrRange instanceof Range) {\n        selection = new Selection(selectionOrPositionOrRange);\n    } else if (selectionOrPositionOrRange instanceof Position) {\n        selection = new Selection(selectionOrPositionOrRange);\n    }\n    // Set up conversion.\n    // Create a temporary view controller.\n    const stylesProcessor = new StylesProcessor();\n    const view = new View(stylesProcessor);\n    const viewDocument = view.document;\n    const viewRoot = new RootEditableElement(viewDocument, 'div');\n    // Create a temporary root element in view document.\n    viewRoot.rootName = 'main';\n    viewDocument.roots.add(viewRoot);\n    // Create and setup downcast dispatcher.\n    const downcastDispatcher = new DowncastDispatcher({\n        mapper,\n        schema: model.schema\n    });\n    // Bind root elements.\n    mapper.bindElements(node.root, viewRoot);\n    downcastDispatcher.on('insert:$text', insertText());\n    downcastDispatcher.on('insert', insertAttributesAndChildren(), {\n        priority: 'lowest'\n    });\n    downcastDispatcher.on('attribute', (evt, data, conversionApi)=>{\n        if (data.item instanceof Selection || data.item instanceof DocumentSelection || data.item.is('$textProxy')) {\n            const converter = wrap((modelAttributeValue, { writer })=>{\n                return writer.createAttributeElement('model-text-with-attributes', {\n                    [data.attributeKey]: stringifyAttributeValue(modelAttributeValue)\n                });\n            });\n            converter(evt, data, conversionApi);\n        }\n    });\n    downcastDispatcher.on('insert', insertElement((modelItem)=>{\n        // Stringify object types values for properly display as an output string.\n        const attributes = convertAttributes(modelItem.getAttributes(), stringifyAttributeValue);\n        return new ContainerElement(viewDocument, modelItem.name, attributes);\n    }));\n    downcastDispatcher.on('selection', convertRangeSelection());\n    downcastDispatcher.on('selection', convertCollapsedSelection());\n    downcastDispatcher.on('addMarker', insertUIElement((data, { writer })=>{\n        const name = data.markerName + ':' + (data.isOpening ? 'start' : 'end');\n        return writer.createUIElement(name);\n    }));\n    const markersMap = new Map();\n    if (markers) {\n        // To provide stable results, sort markers by name.\n        for (const marker of Array.from(markers).sort((a, b)=>a.name < b.name ? 1 : -1)){\n            markersMap.set(marker.name, marker.getRange());\n        }\n    }\n    // Convert model to view.\n    const writer = view._writer;\n    downcastDispatcher.convert(range, markersMap, writer);\n    // Convert model selection to view selection.\n    if (selection) {\n        downcastDispatcher.convertSelection(selection, markers || model.markers, writer);\n    }\n    // Parse view to data string.\n    let data = stringify$1(viewRoot, viewDocument.selection, {\n        sameSelectionCharacters: true\n    });\n    // Removing unnecessary <div> and </div> added because `viewRoot` was also stringified alongside input data.\n    data = data.substr(5, data.length - 11);\n    view.destroy();\n    // Replace valid XML `model-text-with-attributes` element name to `$text`.\n    return data.replace(new RegExp('model-text-with-attributes', 'g'), '$text');\n}\n/**\n * Parses an HTML-like string and returns the model {@link module:engine/model/rootelement~RootElement rootElement}.\n *\n * **Note:** To create a {@link module:engine/model/text~Text text} node that contains attributes use:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * @param data HTML-like string to be parsed.\n * @param schema A schema instance used by converters for element validation.\n * @param options Additional configuration.\n * @param options.selectionAttributes A list of attributes which will be passed to the selection.\n * @param options.lastRangeBackward If set to `true`, the last range will be added as backward.\n * @param options.context The conversion context. If not provided, the default `'$root'` will be used.\n * @returns Returns the parsed model node or an object with two fields: `model` and `selection`,\n * when selection ranges were included in the data to parse.\n */ function parse(data, schema, options = {}) {\n    const mapper = new Mapper();\n    // Replace not accepted by XML `$text` tag name by valid one `model-text-with-attributes`.\n    data = data.replace(new RegExp('\\\\$text', 'g'), 'model-text-with-attributes');\n    // Parse data to view using view utils.\n    const parsedResult = parse$1(data, {\n        sameSelectionCharacters: true,\n        lastRangeBackward: !!options.lastRangeBackward,\n        inlineObjectElements: options.inlineObjectElements\n    });\n    // Retrieve DocumentFragment and Selection from parsed view.\n    let viewDocumentFragment;\n    let viewSelection = null;\n    let selection = null;\n    if ('view' in parsedResult && 'selection' in parsedResult) {\n        viewDocumentFragment = parsedResult.view;\n        viewSelection = parsedResult.selection;\n    } else {\n        viewDocumentFragment = parsedResult;\n    }\n    // Set up upcast dispatcher.\n    const modelController = new Model();\n    const upcastDispatcher = new UpcastDispatcher({\n        schema\n    });\n    upcastDispatcher.on('documentFragment', convertToModelFragment(mapper));\n    upcastDispatcher.on('element:model-text-with-attributes', convertToModelText());\n    upcastDispatcher.on('element', convertToModelElement(mapper));\n    upcastDispatcher.on('text', convertToModelText());\n    // Convert view to model.\n    let model = modelController.change((writer)=>upcastDispatcher.convert(viewDocumentFragment.root, writer, options.context || '$root'));\n    mapper.bindElements(model, viewDocumentFragment.root);\n    // If root DocumentFragment contains only one element - return that element.\n    if (model.childCount == 1) {\n        model = model.getChild(0);\n    }\n    // Convert view selection to model selection.\n    if (viewSelection) {\n        const ranges = [];\n        // Convert ranges.\n        for (const viewRange of viewSelection.getRanges()){\n            ranges.push(mapper.toModelRange(viewRange));\n        }\n        // Create new selection.\n        selection = new Selection(ranges, {\n            backward: viewSelection.isBackward\n        });\n        // Set attributes to selection if specified.\n        for (const [key, value] of toMap(options.selectionAttributes || [])){\n            selection.setAttribute(key, value);\n        }\n    }\n    // Return model end selection when selection was specified.\n    if (selection) {\n        return {\n            model,\n            selection\n        };\n    }\n    // Otherwise return model only.\n    return model;\n}\n// -- Converters view -> model -----------------------------------------------------\nfunction convertToModelFragment(mapper) {\n    return (evt, data, conversionApi)=>{\n        const childrenResult = conversionApi.convertChildren(data.viewItem, data.modelCursor);\n        mapper.bindElements(data.modelCursor.parent, data.viewItem);\n        data = Object.assign(data, childrenResult);\n        evt.stop();\n    };\n}\nfunction convertToModelElement(mapper) {\n    return (evt, data, conversionApi)=>{\n        const elementName = data.viewItem.name;\n        if (!conversionApi.schema.checkChild(data.modelCursor, elementName)) {\n            throw new Error(`Element '${elementName}' was not allowed in given position.`);\n        }\n        // View attribute value is a string so we want to typecast it to the original type.\n        // E.g. `bold=\"true\"` - value will be parsed from string `\"true\"` to boolean `true`.\n        const attributes = convertAttributes(data.viewItem.getAttributes(), parseAttributeValue);\n        const element = conversionApi.writer.createElement(data.viewItem.name, attributes);\n        conversionApi.writer.insert(element, data.modelCursor);\n        mapper.bindElements(element, data.viewItem);\n        conversionApi.convertChildren(data.viewItem, element);\n        data.modelRange = Range._createOn(element);\n        data.modelCursor = data.modelRange.end;\n        evt.stop();\n    };\n}\nfunction convertToModelText() {\n    return (evt, data, conversionApi)=>{\n        if (!conversionApi.schema.checkChild(data.modelCursor, '$text')) {\n            throw new Error('Text was not allowed in given position.');\n        }\n        let node;\n        if (data.viewItem.is('element')) {\n            // View attribute value is a string so we want to typecast it to the original type.\n            // E.g. `bold=\"true\"` - value will be parsed from string `\"true\"` to boolean `true`.\n            const attributes = convertAttributes(data.viewItem.getAttributes(), parseAttributeValue);\n            const viewText = data.viewItem.getChild(0);\n            node = conversionApi.writer.createText(viewText.data, attributes);\n        } else {\n            node = conversionApi.writer.createText(data.viewItem.data);\n        }\n        conversionApi.writer.insert(node, data.modelCursor);\n        data.modelRange = Range._createFromPositionAndShift(data.modelCursor, node.offsetSize);\n        data.modelCursor = data.modelRange.end;\n        evt.stop();\n    };\n}\n// Tries to get original type of attribute value using JSON parsing:\n//\n//\t\t`'true'` => `true`\n//\t\t`'1'` => `1`\n//\t\t`'{\"x\":1,\"y\":2}'` => `{ x: 1, y: 2 }`\n//\n// Parse error means that value should be a string:\n//\n//\t\t`'foobar'` => `'foobar'`\nfunction parseAttributeValue(attribute) {\n    try {\n        return JSON.parse(attribute);\n    } catch (e) {\n        return attribute;\n    }\n}\n// When value is an Object stringify it.\nfunction stringifyAttributeValue(data) {\n    if (isPlainObject(data)) {\n        return JSON.stringify(data);\n    }\n    return data;\n}\n// Loop trough attributes map and converts each value by passed converter.\nfunction* convertAttributes(attributes, converter) {\n    for (const [key, value] of attributes){\n        yield [\n            key,\n            converter(value)\n        ];\n    }\n}\n\nexport { AttributeElement, AttributeOperation, BubblingEventInfo, ClickObserver, Conversion, DataController, DataTransfer, DocumentFragment, DocumentSelection, DomConverter, DomEventData, DomEventObserver, DowncastWriter, EditingController, View as EditingView, Element, FocusObserver, History, HtmlDataProcessor, InsertOperation, LivePosition, LiveRange, MarkerOperation, Matcher, MergeOperation, Model, MouseObserver, MoveOperation, NoOperation, Observer, OperationFactory, Position, Range, RenameOperation, Renderer, RootAttributeOperation, RootOperation, SplitOperation, StylesMap, StylesProcessor, TabObserver, Text, TextProxy, TreeWalker, UpcastWriter, AttributeElement as ViewAttributeElement, ContainerElement as ViewContainerElement, Document$1 as ViewDocument, DocumentFragment$1 as ViewDocumentFragment, EditableElement as ViewEditableElement, Element$1 as ViewElement, EmptyElement as ViewEmptyElement, RawElement as ViewRawElement, RootEditableElement as ViewRootEditableElement, Text$1 as ViewText, TreeWalker$1 as ViewTreeWalker, UIElement as ViewUIElement, XmlDataProcessor, getData as _getModelData, getData$1 as _getViewData, parse as _parseModel, parse$1 as _parseView, setData as _setModelData, setData$1 as _setViewData, stringify as _stringifyModel, stringify$1 as _stringifyView, addBackgroundRules, addBorderRules, addMarginRules, addPaddingRules, autoParagraphEmptyRoots, disablePlaceholder, enablePlaceholder, getBoxSidesShorthandValue, getBoxSidesValueReducer, getBoxSidesValues, getFillerOffset$4 as getFillerOffset, getPositionShorthandNormalizer, getShorthandValues, hidePlaceholder, isAttachment, isColor, isLength, isLineStyle, isParagraphable, isPercentage, isPosition, isRepeat, isURL, needsPlaceholder, showPlaceholder, transformSets, wrapInParagraph };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/placeholder\n */\n\nimport '../../theme/placeholder.css';\n\nimport type Document from './document.js';\nimport type DowncastWriter from './downcastwriter.js';\nimport type EditableElement from './editableelement.js';\nimport type Element from './element.js';\nimport type View from './view.js';\n\nimport { logWarning, type ObservableChangeEvent } from '@ckeditor/ckeditor5-utils';\n\n// Each document stores information about its placeholder elements and check functions.\nconst documentPlaceholders = new WeakMap<Document, Map<Element, PlaceholderConfig>>();\n\nlet hasDisplayedPlaceholderDeprecationWarning = false;\n\n/**\n * A helper that enables a placeholder on the provided view element (also updates its visibility).\n * The placeholder is a CSS pseudo–element (with a text content) attached to the element.\n *\n * To change the placeholder text, change value of the `placeholder` property in the provided `element`.\n *\n * To disable the placeholder, use {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} helper.\n *\n * @param options Configuration options of the placeholder.\n * @param options.view Editing view instance.\n * @param options.element Element that will gain a placeholder. See `options.isDirectHost` to learn more.\n * @param options.isDirectHost If set `false`, the placeholder will not be enabled directly\n * in the passed `element` but in one of its children (selected automatically, i.e. a first empty child element).\n * Useful when attaching placeholders to elements that can host other elements (not just text), for instance,\n * editable root elements.\n * @param options.text Placeholder text. It's **deprecated** and will be removed soon. Use\n * {@link module:engine/view/placeholder~PlaceholderableElement#placeholder `options.element.placeholder`} instead.\n * @param options.keepOnFocus If set `true`, the placeholder stay visible when the host element is focused.\n */\nexport function enablePlaceholder( { view, element, text, isDirectHost = true, keepOnFocus = false }: {\n\tview: View;\n\telement: PlaceholderableElement | EditableElement;\n\tisDirectHost?: boolean;\n\ttext?: string;\n\tkeepOnFocus?: boolean;\n} ): void {\n\tconst doc = view.document;\n\n\t// Use a single a single post fixer per—document to update all placeholders.\n\tif ( !documentPlaceholders.has( doc ) ) {\n\t\tdocumentPlaceholders.set( doc, new Map() );\n\n\t\t// If a post-fixer callback makes a change, it should return `true` so other post–fixers\n\t\t// can re–evaluate the document again.\n\t\tdoc.registerPostFixer( writer => updateDocumentPlaceholders( doc, writer ) );\n\n\t\t// Update placeholders on isComposing state change since rendering is disabled while in composition mode.\n\t\tdoc.on<ObservableChangeEvent>( 'change:isComposing', () => {\n\t\t\tview.change( writer => updateDocumentPlaceholders( doc, writer ) );\n\t\t}, { priority: 'high' } );\n\t}\n\n\tif ( element.is( 'editableElement' ) ) {\n\t\telement.on( 'change:placeholder', ( evtInfo, evt, text ) => {\n\t\t\tsetPlaceholder( text );\n\t\t} );\n\t}\n\n\tif ( element.placeholder ) {\n\t\tsetPlaceholder( element.placeholder );\n\t} else if ( text ) {\n\t\tsetPlaceholder( text );\n\t}\n\n\tif ( text ) {\n\t\tshowPlaceholderTextDeprecationWarning();\n\t}\n\n\tfunction setPlaceholder( text: string ) {\n\t\t// Store information about the element placeholder under its document.\n\t\tdocumentPlaceholders.get( doc )!.set( element, {\n\t\t\ttext,\n\t\t\tisDirectHost,\n\t\t\tkeepOnFocus,\n\t\t\thostElement: isDirectHost ? element : null\n\t\t} );\n\n\t\t// Update the placeholders right away.\n\t\tview.change( writer => updateDocumentPlaceholders( doc, writer ) );\n\t}\n}\n\n/**\n * Disables the placeholder functionality from a given element.\n *\n * See {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} to learn more.\n */\nexport function disablePlaceholder( view: View, element: Element ): void {\n\tconst doc = element.document;\n\n\tif ( !documentPlaceholders.has( doc ) ) {\n\t\treturn;\n\t}\n\n\tview.change( writer => {\n\t\tconst placeholders = documentPlaceholders.get( doc )!;\n\t\tconst config = placeholders.get( element )!;\n\n\t\twriter.removeAttribute( 'data-placeholder', config.hostElement! );\n\t\thidePlaceholder( writer, config.hostElement! );\n\n\t\tplaceholders.delete( element );\n\t} );\n}\n\n/**\n * Shows a placeholder in the provided element by changing related attributes and CSS classes.\n *\n * **Note**: This helper will not update the placeholder visibility nor manage the\n * it in any way in the future. What it does is a one–time state change of an element. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} and\n * {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} for full\n * placeholder functionality.\n *\n * **Note**: This helper will blindly show the placeholder directly in the root editable element if\n * one is passed, which could result in a visual clash if the editable element has some children\n * (for instance, an empty paragraph). Use {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`}\n * in that case or make sure the correct element is passed to the helper.\n *\n * @returns `true`, if any changes were made to the `element`.\n */\nexport function showPlaceholder( writer: DowncastWriter, element: Element ): boolean {\n\tif ( !element.hasClass( 'ck-placeholder' ) ) {\n\t\twriter.addClass( 'ck-placeholder', element );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Hides a placeholder in the element by changing related attributes and CSS classes.\n *\n * **Note**: This helper will not update the placeholder visibility nor manage the\n * it in any way in the future. What it does is a one–time state change of an element. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} and\n * {@link module:engine/view/placeholder~disablePlaceholder `disablePlaceholder()`} for full\n * placeholder functionality.\n *\n * @returns `true`, if any changes were made to the `element`.\n */\nexport function hidePlaceholder( writer: DowncastWriter, element: Element ): boolean {\n\tif ( element.hasClass( 'ck-placeholder' ) ) {\n\t\twriter.removeClass( 'ck-placeholder', element );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Checks if a placeholder should be displayed in the element.\n *\n * **Note**: This helper will blindly check the possibility of showing a placeholder directly in the\n * root editable element if one is passed, which may not be the expected result. If an element can\n * host other elements (not just text), most likely one of its children should be checked instead\n * because it will be the final host for the placeholder. Use\n * {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`} in that case or make\n * sure the correct element is passed to the helper.\n *\n * @param element Element that holds the placeholder.\n * @param keepOnFocus Focusing the element will keep the placeholder visible.\n */\nexport function needsPlaceholder( element: Element, keepOnFocus: boolean ): boolean {\n\tif ( !element.isAttached() ) {\n\t\treturn false;\n\t}\n\n\t// Anything but uiElement(s) counts as content.\n\tconst hasContent = Array.from( element.getChildren() )\n\t\t.some( element => !element.is( 'uiElement' ) );\n\n\tif ( hasContent ) {\n\t\treturn false;\n\t}\n\n\tconst doc = element.document;\n\tconst viewSelection = doc.selection;\n\tconst selectionAnchor = viewSelection.anchor;\n\n\tif ( doc.isComposing && selectionAnchor && selectionAnchor.parent === element ) {\n\t\treturn false;\n\t}\n\n\t// Skip the focus check and make the placeholder visible already regardless of document focus state.\n\tif ( keepOnFocus ) {\n\t\treturn true;\n\t}\n\n\t// If the document is blurred.\n\tif ( !doc.isFocused ) {\n\t\treturn true;\n\t}\n\n\t// If document is focused and the element is empty but the selection is not anchored inside it.\n\treturn !!selectionAnchor && selectionAnchor.parent !== element;\n}\n\n/**\n * Updates all placeholders associated with a document in a post–fixer callback.\n *\n * @returns True if any changes were made to the view document.\n */\nfunction updateDocumentPlaceholders( doc: Document, writer: DowncastWriter ): boolean {\n\tconst placeholders = documentPlaceholders.get( doc )!;\n\tconst directHostElements: Array<Element> = [];\n\tlet wasViewModified = false;\n\n\t// First set placeholders on the direct hosts.\n\tfor ( const [ element, config ] of placeholders ) {\n\t\tif ( config.isDirectHost ) {\n\t\t\tdirectHostElements.push( element );\n\n\t\t\tif ( updatePlaceholder( writer, element, config ) ) {\n\t\t\t\twasViewModified = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Then set placeholders on the indirect hosts but only on those that does not already have an direct host placeholder.\n\tfor ( const [ element, config ] of placeholders ) {\n\t\tif ( config.isDirectHost ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst hostElement = getChildPlaceholderHostSubstitute( element );\n\n\t\t// When not a direct host, it could happen that there is no child element\n\t\t// capable of displaying a placeholder.\n\t\tif ( !hostElement ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Don't override placeholder if the host element already has some direct placeholder.\n\t\tif ( directHostElements.includes( hostElement ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Update the host element (used for setting and removing the placeholder).\n\t\tconfig.hostElement = hostElement;\n\n\t\tif ( updatePlaceholder( writer, element, config ) ) {\n\t\t\twasViewModified = true;\n\t\t}\n\t}\n\n\treturn wasViewModified;\n}\n\n/**\n * Updates a single placeholder in a post–fixer callback.\n *\n * @returns True if any changes were made to the view document.\n */\nfunction updatePlaceholder( writer: DowncastWriter, element: Element, config: PlaceholderConfig ) {\n\tconst { text, isDirectHost, hostElement } = config;\n\n\tlet wasViewModified = false;\n\n\t// This may be necessary when updating the placeholder text to something else.\n\tif ( hostElement!.getAttribute( 'data-placeholder' ) !== text ) {\n\t\twriter.setAttribute( 'data-placeholder', text, hostElement! );\n\t\twasViewModified = true;\n\t}\n\n\t// If the host element is not a direct host then placeholder is needed only when there is only one element.\n\tconst isOnlyChild = isDirectHost || element.childCount == 1;\n\n\tif ( isOnlyChild && needsPlaceholder( hostElement!, config.keepOnFocus ) ) {\n\t\tif ( showPlaceholder( writer, hostElement! ) ) {\n\t\t\twasViewModified = true;\n\t\t}\n\t} else if ( hidePlaceholder( writer, hostElement! ) ) {\n\t\twasViewModified = true;\n\t}\n\n\treturn wasViewModified;\n}\n\n/**\n * Gets a child element capable of displaying a placeholder if a parent element can host more\n * than just text (for instance, when it is a root editable element). The child element\n * can then be used in other placeholder helpers as a substitute of its parent.\n */\nfunction getChildPlaceholderHostSubstitute( parent: Element ): Element | null {\n\tif ( parent.childCount ) {\n\t\tconst firstChild = parent.getChild( 0 )!;\n\n\t\tif ( firstChild.is( 'element' ) && !firstChild.is( 'uiElement' ) && !firstChild.is( 'attributeElement' ) ) {\n\t\t\treturn firstChild;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Displays a deprecation warning message in the console, but only once per page load.\n */\nfunction showPlaceholderTextDeprecationWarning() {\n\tif ( !hasDisplayedPlaceholderDeprecationWarning ) {\n\t\t/**\n\t\t * The \"text\" option in the {@link module:engine/view/placeholder~enablePlaceholder `enablePlaceholder()`}\n\t\t * function is deprecated and will be removed soon.\n\t\t *\n\t\t * See the {@glink updating/guides/update-to-39#view-element-placeholder Migration to v39} guide for\n\t\t * more information on how to apply this change.\n\t\t *\n\t\t * @error enableplaceholder-deprecated-text-option\n\t\t */\n\t\tlogWarning( 'enableplaceholder-deprecated-text-option' );\n\t}\n\n\thasDisplayedPlaceholderDeprecationWarning = true;\n}\n\n/**\n * Configuration of the placeholder.\n */\ninterface PlaceholderConfig {\n\ttext: string;\n\tisDirectHost: boolean;\n\tkeepOnFocus: boolean;\n\thostElement: Element | null;\n}\n\n/**\n * Element that could have a placeholder.\n */\nexport interface PlaceholderableElement extends Element {\n\n\t/**\n\t * The text of element's placeholder.\n\t */\n\tplaceholder?: string;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type AttributeElement from './attributeelement.js';\nimport type ContainerElement from './containerelement.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type DocumentSelection from './documentselection.js';\nimport type EditableElement from './editableelement.js';\nimport type Element from './element.js';\nimport type EmptyElement from './emptyelement.js';\nimport type Node from './node.js';\nimport type Position from './position.js';\nimport type Range from './range.js';\nimport type RawElement from './rawelement.js';\nimport type RootEditableElement from './rooteditableelement.js';\nimport type Selection from './selection.js';\nimport type Text from './text.js';\nimport type TextProxy from './textproxy.js';\nimport type UIElement from './uielement.js';\n\n/**\n * @module engine/view/typecheckable\n */\n\nexport default abstract class TypeCheckable {\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/node~Node} or its subclass.\n\t *\n\t * This method is useful when processing view objects that are of unknown type. For example, a function\n\t * may return a {@link module:engine/view/documentfragment~DocumentFragment} or a {@link module:engine/view/node~Node}\n\t * that can be either a text node or an element. This method can be used to check what kind of object is returned.\n\t *\n\t * ```ts\n\t * someObject.is( 'element' ); // -> true if this is an element\n\t * someObject.is( 'node' ); // -> true if this is a node (a text node or an element)\n\t * someObject.is( 'documentFragment' ); // -> true if this is a document fragment\n\t * ```\n\t *\n\t * Since this method is also available on a range of model objects, you can prefix the type of the object with\n\t * `model:` or `view:` to check, for example, if this is the model's or view's element:\n\t *\n\t * ```ts\n\t * viewElement.is( 'view:element' ); // -> true\n\t * viewElement.is( 'model:element' ); // -> false\n\t * ```\n\t *\n\t * By using this method it is also possible to check a name of an element:\n\t *\n\t * ```ts\n\t * imgElement.is( 'element', 'img' ); // -> true\n\t * imgElement.is( 'view:element', 'img' ); // -> same as above, but more precise\n\t * ```\n\t * @label NODE\n\t */\n\tpublic is( type: 'node' | 'view:node' ): this is (\n\t\tNode |\n\t\tText |\n\t\tElement |\n\t\tAttributeElement |\n\t\tContainerElement |\n\t\tEditableElement |\n\t\tEmptyElement |\n\t\tRawElement |\n\t\tRootEditableElement |\n\t\tUIElement\n\t);\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/element~Element} or its subclass.\n\t *\n\t * ```ts\n\t * element.is( 'element' ); // -> true\n\t * element.is( 'node' ); // -> true\n\t * element.is( 'view:element' ); // -> true\n\t * element.is( 'view:node' ); // -> true\n\t *\n\t * element.is( 'model:element' ); // -> false\n\t * element.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is an element, you can also check its\n\t * {@link module:engine/view/element~Element#name name}:\n\t *\n\t * ```ts\n\t * element.is( 'element', 'img' ); // -> true if this is an <img> element\n\t * text.is( 'element', 'img' ); -> false\n\t * ```\n\t *\n\t * @label ELEMENT\n\t */\n\tpublic is( type: 'element' | 'view:element' ): this is (\n\t\tElement |\n\t\tAttributeElement |\n\t\tContainerElement |\n\t\tEditableElement |\n\t\tEmptyElement |\n\t\tRawElement |\n\t\tRootEditableElement |\n\t\tUIElement\n\t);\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/attributeelement~AttributeElement}.\n\t *\n\t * ```ts\n\t * attributeElement.is( 'attributeElement' ); // -> true\n\t * attributeElement.is( 'element' ); // -> true\n\t * attributeElement.is( 'node' ); // -> true\n\t * attributeElement.is( 'view:attributeElement' ); // -> true\n\t * attributeElement.is( 'view:element' ); // -> true\n\t * attributeElement.is( 'view:node' ); // -> true\n\t *\n\t * attributeElement.is( 'model:element' ); // -> false\n\t * attributeElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is an attribute element, you can also check its\n\t * {@link module:engine/view/attributeelement~AttributeElement#name name}:\n\t *\n\t * ```ts\n\t * attributeElement.is( 'element', 'b' ); // -> true if this is a bold element\n\t * attributeElement.is( 'attributeElement', 'b' ); // -> same as above\n\t * text.is( 'element', 'b' ); -> false\n\t * ```\n\t *\n\t * @label ATTRIBUTE_ELEMENT\n\t */\n\tpublic is( type: 'attributeElement' | 'view:attributeElement' ): this is AttributeElement;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/containerelement~ContainerElement} or its subclass.\n\t *\n\t * ```ts\n\t * containerElement.is( 'containerElement' ); // -> true\n\t * containerElement.is( 'element' ); // -> true\n\t * containerElement.is( 'node' ); // -> true\n\t * containerElement.is( 'view:containerElement' ); // -> true\n\t * containerElement.is( 'view:element' ); // -> true\n\t * containerElement.is( 'view:node' ); // -> true\n\t *\n\t * containerElement.is( 'model:element' ); // -> false\n\t * containerElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is a container element, you can also check its\n\t * {@link module:engine/view/containerelement~ContainerElement#name name}:\n\t *\n\t * ```ts\n\t * containerElement.is( 'element', 'div' ); // -> true if this is a div container element\n\t * containerElement.is( 'contaienrElement', 'div' ); // -> same as above\n\t * text.is( 'element', 'div' ); -> false\n\t * ```\n\t *\n\t * @label CONTAINER_ELEMENT\n\t */\n\tpublic is( type: 'containerElement' | 'view:containerElement' ): this is ContainerElement | EditableElement | RootEditableElement;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/editableelement~EditableElement} or its subclass.\n\t *\n\t * ```ts\n\t * editableElement.is( 'editableElement' ); // -> true\n\t * editableElement.is( 'element' ); // -> true\n\t * editableElement.is( 'node' ); // -> true\n\t * editableElement.is( 'view:editableElement' ); // -> true\n\t * editableElement.is( 'view:element' ); // -> true\n\t * editableElement.is( 'view:node' ); // -> true\n\t *\n\t * editableElement.is( 'model:element' ); // -> false\n\t * editableElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is an editbale element, you can also check its\n\t * {@link module:engine/view/editableelement~EditableElement#name name}:\n\t *\n\t * ```ts\n\t * editableElement.is( 'element', 'div' ); // -> true if this is a div element\n\t * editableElement.is( 'editableElement', 'div' ); // -> same as above\n\t * text.is( 'element', 'div' ); -> false\n\t * ```\n\t *\n\t * @label EDITABLE_ELEMENT\n\t */\n\tpublic is( type: 'editableElement' | 'view:editableElement' ): this is EditableElement | RootEditableElement;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/emptyelement~EmptyElement}.\n\t *\n\t * ```ts\n\t * emptyElement.is( 'emptyElement' ); // -> true\n\t * emptyElement.is( 'element' ); // -> true\n\t * emptyElement.is( 'node' ); // -> true\n\t * emptyElement.is( 'view:emptyElement' ); // -> true\n\t * emptyElement.is( 'view:element' ); // -> true\n\t * emptyElement.is( 'view:node' ); // -> true\n\t *\n\t * emptyElement.is( 'model:element' ); // -> false\n\t * emptyElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is an empty element, you can also check its\n\t * {@link module:engine/view/emptyelement~EmptyElement#name name}:\n\t *\n\t * ```ts\n\t * emptyElement.is( 'element', 'img' ); // -> true if this is a img element\n\t * emptyElement.is( 'emptyElement', 'img' ); // -> same as above\n\t * text.is( 'element', 'img' ); -> false\n\t * ```\n\t *\n\t * @label EMPTY_ELEMENT\n\t */\n\tpublic is( type: 'emptyElement' | 'view:emptyElement' ): this is EmptyElement;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/rawelement~RawElement}.\n\t *\n\t * ```ts\n\t * rawElement.is( 'rawElement' ); // -> true\n\t * rawElement.is( 'element' ); // -> true\n\t * rawElement.is( 'node' ); // -> true\n\t * rawElement.is( 'view:rawElement' ); // -> true\n\t * rawElement.is( 'view:element' ); // -> true\n\t * rawElement.is( 'view:node' ); // -> true\n\t *\n\t * rawElement.is( 'model:element' ); // -> false\n\t * rawElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is a raw element, you can also check its\n\t * {@link module:engine/view/rawelement~RawElement#name name}:\n\t *\n\t * ```ts\n\t * rawElement.is( 'img' ); // -> true if this is an img element\n\t * rawElement.is( 'rawElement', 'img' ); // -> same as above\n\t * text.is( 'img' ); -> false\n\t * ```\n\t *\n\t * @label RAW_ELEMENT\n\t */\n\tpublic is( type: 'rawElement' | 'view:rawElement' ): this is RawElement;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/rooteditableelement~RootEditableElement}.\n\t *\n\t * ```ts\n\t * rootEditableElement.is( 'rootElement' ); // -> true\n\t * rootEditableElement.is( 'editableElement' ); // -> true\n\t * rootEditableElement.is( 'element' ); // -> true\n\t * rootEditableElement.is( 'node' ); // -> true\n\t * rootEditableElement.is( 'view:editableElement' ); // -> true\n\t * rootEditableElement.is( 'view:element' ); // -> true\n\t * rootEditableElement.is( 'view:node' ); // -> true\n\t *\n\t * rootEditableElement.is( 'model:element' ); // -> false\n\t * rootEditableElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is a root editable element, you can also check its\n\t * {@link module:engine/view/rooteditableelement~RootEditableElement#name name}:\n\t *\n\t * ```ts\n\t * rootEditableElement.is( 'element', 'div' ); // -> true if this is a div root editable element\n\t * rootEditableElement.is( 'rootElement', 'div' ); // -> same as above\n\t * text.is( 'element', 'div' ); -> false\n\t * ```\n\t *\n\t * @label ROOT_ELEMENT\n\t */\n\tpublic is( type: 'rootElement' | 'view:rootElement' ): this is RootEditableElement;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * ```ts\n\t * uiElement.is( 'uiElement' ); // -> true\n\t * uiElement.is( 'element' ); // -> true\n\t * uiElement.is( 'node' ); // -> true\n\t * uiElement.is( 'view:uiElement' ); // -> true\n\t * uiElement.is( 'view:element' ); // -> true\n\t * uiElement.is( 'view:node' ); // -> true\n\t *\n\t * uiElement.is( 'model:element' ); // -> false\n\t * uiElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is an ui element, you can also check its\n\t * {@link module:engine/view/uielement~UIElement#name name}:\n\t *\n\t * ```ts\n\t * uiElement.is( 'element', 'span' ); // -> true if this is a span ui element\n\t * uiElement.is( 'uiElement', 'span' ); // -> same as above\n\t * text.is( 'element', 'span' ); -> false\n\t * ```\n\t *\n\t * @label UI_ELEMENT\n\t */\n\tpublic is( type: 'uiElement' | 'view:uiElement' ): this is UIElement;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/text~Text}.\n\t *\n\t * ```ts\n\t * text.is( '$text' ); // -> true\n\t * text.is( 'node' ); // -> true\n\t * text.is( 'view:$text' ); // -> true\n\t * text.is( 'view:node' ); // -> true\n\t *\n\t * text.is( 'model:$text' ); // -> false\n\t * text.is( 'element' ); // -> false\n\t * text.is( 'range' ); // -> false\n\t * ```\n\t *\n\t * @label TEXT\n\t */\n\tpublic is( type: '$text' | 'view:$text' ): this is Text;\n\n\t/**\n\t * hecks whether this object is of type {@link module:engine/view/documentfragment~DocumentFragment}.\n\t *\n\t * ```ts\n\t * docFrag.is( 'documentFragment' ); // -> true\n\t * docFrag.is( 'view:documentFragment' ); // -> true\n\t *\n\t * docFrag.is( 'model:documentFragment' ); // -> false\n\t * docFrag.is( 'element' ); // -> false\n\t * docFrag.is( 'node' ); // -> false\n\t * ```\n\t *\n\t * @label DOCUMENT_FRAGMENT\n\t */\n\tpublic is( type: 'documentFragment' | 'view:documentFragment' ): this is DocumentFragment;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/textproxy~TextProxy}.\n\t *\n\t * ```ts\n\t * textProxy.is( '$textProxy' ); // -> true\n\t * textProxy.is( 'view:$textProxy' ); // -> true\n\t *\n\t * textProxy.is( 'model:$textProxy' ); // -> false\n\t * textProxy.is( 'element' ); // -> false\n\t * textProxy.is( 'range' ); // -> false\n\t * ```\n\t *\n\t * **Note:** Until version 20.0.0 this method wasn't accepting `'$textProxy'` type. The legacy `'textProxy'` type is still\n\t * accepted for backward compatibility.\n\t *\n\t * @label TEXT_PROXY\n\t */\n\tpublic is( type: '$textProxy' | 'view:$textProxy' ): this is TextProxy;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/position~Position}.\n\t *\n\t * ```ts\n\t * position.is( 'position' ); // -> true\n\t * position.is( 'view:position' ); // -> true\n\t *\n\t * position.is( 'model:position' ); // -> false\n\t * position.is( 'element' ); // -> false\n\t * position.is( 'range' ); // -> false\n\t * ```\n\t *\n\t * @label POSITION\n\t */\n\tpublic is( type: 'position' | 'view:position' ): this is Position;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/range~Range}.\n\t *\n\t * ```ts\n\t * range.is( 'range' ); // -> true\n\t * range.is( 'view:range' ); // -> true\n\t *\n\t * range.is( 'model:range' ); // -> false\n\t * range.is( 'element' ); // -> false\n\t * range.is( 'selection' ); // -> false\n\t * ```\n\t *\n\t * @label RANGE\n\t */\n\tpublic is( type: 'range' | 'view:range' ): this is Range;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/selection~Selection} or\n\t * {@link module:engine/view/documentselection~DocumentSelection}.\n\t *\n\t * ```ts\n\t * selection.is( 'selection' ); // -> true\n\t * selection.is( 'view:selection' ); // -> true\n\t *\n\t * selection.is( 'model:selection' ); // -> false\n\t * selection.is( 'element' ); // -> false\n\t * selection.is( 'range' ); // -> false\n\t * ```\n\t *\n\t * @label SELECTION\n\t */\n\tpublic is( type: 'selection' | 'view:selection' ): this is Selection | DocumentSelection;\n\n\t/**\n\t * Checks whether this object is of type {@link module:engine/view/documentselection~DocumentSelection}.\n\t *\n\t * ```ts\n\t * `docSelection.is( 'selection' ); // -> true\n\t * docSelection.is( 'documentSelection' ); // -> true\n\t * docSelection.is( 'view:selection' ); // -> true\n\t * docSelection.is( 'view:documentSelection' ); // -> true\n\t *\n\t * docSelection.is( 'model:documentSelection' ); // -> false\n\t * docSelection.is( 'element' ); // -> false\n\t * docSelection.is( 'node' ); // -> false\n\t * ```\n\t *\n\t * @label DOCUMENT_SELECTION\n\t */\n\tpublic is( type: 'documentSelection' | 'view:documentSelection' ): this is DocumentSelection;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/element~Element} or its subclass and has the specified `name`.\n\t *\n\t * @label ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'element' | 'view:element', name: N ): this is (\n\t\tElement |\n\t\tAttributeElement |\n\t\tContainerElement |\n\t\tEditableElement |\n\t\tEmptyElement |\n\t\tRawElement |\n\t\tRootEditableElement |\n\t\tUIElement\n\t) & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/attributeelement~AttributeElement} and has the specified `name`.\n\t *\n\t * @label ATTRIBUTE_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'attributeElement' | 'view:attributeElement', name: N ): this is AttributeElement & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/containerelement~ContainerElement}\n\t * or its subclass and has the specified `name`.\n\t *\n\t * @label CONTAINER_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'containerElement' | 'view:containerElement', name: N ): this is (\n\t\tContainerElement |\n\t\tEditableElement |\n\t\tRootEditableElement\n\t) & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/editableelement~EditableElement}\n\t * or its subclass and has the specified `name`.\n\t *\n\t * @label EDITABLE_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'editableElement' | 'view:editableElement', name: N ): this is (\n\t\tEditableElement |\n\t\tRootEditableElement\n\t) & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/emptyelement~EmptyElement} has the specified `name`.\n\t *\n\t * @label EMPTY_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'emptyElement' | 'view:emptyElement', name: N ): this is EmptyElement & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/rawelement~RawElement} and has the specified `name`.\n\t *\n\t * @label RAW_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'rawElement' | 'view:rawElement', name: N ): this is RawElement & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/rooteditableelement~RootEditableElement} and has the specified `name`.\n\t *\n\t * @label ROOT_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'rootElement' | 'view:rootElement', name: N ): this is RootEditableElement & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/view/uielement~UIElement} and has the specified `name`.\n\t *\n\t * @label UI_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'uiElement' | 'view:uiElement', name: N ): this is UIElement & { name: N };\n\n\t/* istanbul ignore next -- @preserve */\n\tpublic is(): boolean {\n\t\t// There are a lot of overloads above.\n\t\t// Overriding method in derived classes remove them and only `is( type: string ): boolean` is visible which we don't want.\n\t\t// One option would be to copy them all to all classes, but that's ugly.\n\t\t// It's best when TypeScript compiler doesn't see those overloads, except the one in the top base class.\n\t\t// To overload a method, but not let the compiler see it, do after class definition:\n\t\t// `MyClass.prototype.is = function( type: string ) {...}`\n\t\tthrow new Error( 'is() method is abstract' );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/node\n */\n\nimport TypeCheckable from './typecheckable.js';\n\nimport {\n\tCKEditorError,\n\tEmitterMixin,\n\tcompareArrays\n} from '@ckeditor/ckeditor5-utils';\n\nimport { clone } from 'lodash-es';\n\nimport type { default as Document, ChangeType } from './document.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\n\n/**\n * Abstract view node class.\n *\n * This is an abstract class. Its constructor should not be used directly.\n * Use the {@link module:engine/view/downcastwriter~DowncastWriter} or {@link module:engine/view/upcastwriter~UpcastWriter}\n * to create new instances of view nodes.\n */\nexport default abstract class Node extends /* #__PURE__ */ EmitterMixin( TypeCheckable ) {\n\t/**\n\t * The document instance to which this node belongs.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * Parent element. Null by default. Set by {@link module:engine/view/element~Element#_insertChild}.\n\t */\n\tpublic readonly parent: Element | DocumentFragment | null;\n\n\t/**\n\t * Creates a tree view node.\n\t *\n\t * @param document The document instance to which this node belongs.\n\t */\n\tprotected constructor( document: Document ) {\n\t\tsuper();\n\n\t\tthis.document = document;\n\t\tthis.parent = null;\n\t}\n\n\t/**\n\t * Index of the node in the parent element or null if the node has no parent.\n\t *\n\t * Accessing this property throws an error if this node's parent element does not contain it.\n\t * This means that view tree got broken.\n\t */\n\tpublic get index(): number | null {\n\t\tlet pos;\n\n\t\tif ( !this.parent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// No parent or child doesn't exist in parent's children.\n\t\tif ( ( pos = this.parent.getChildIndex( this ) ) == -1 ) {\n\t\t\t/**\n\t\t\t * The node's parent does not contain this node. It means that the document tree is corrupted.\n\t\t\t *\n\t\t\t * @error view-node-not-found-in-parent\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-node-not-found-in-parent', this );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Node's next sibling, or `null` if it is the last child.\n\t */\n\tpublic get nextSibling(): Node | null {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent!.getChild( index + 1 ) ) || null;\n\t}\n\n\t/**\n\t * Node's previous sibling, or `null` if it is the first child.\n\t */\n\tpublic get previousSibling(): Node | null {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent!.getChild( index - 1 ) ) || null;\n\t}\n\n\t/**\n\t * Top-most ancestor of the node. If the node has no parent it is the root itself.\n\t */\n\tpublic get root(): Element | DocumentFragment {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n\t\tlet root: Node | DocumentFragment = this;\n\n\t\twhile ( root.parent ) {\n\t\t\troot = root.parent;\n\t\t}\n\n\t\treturn root as any;\n\t}\n\n\t/**\n\t * Returns true if the node is in a tree rooted in the document (is a descendant of one of its roots).\n\t */\n\tpublic isAttached(): boolean {\n\t\treturn this.root.is( 'rootElement' );\n\t}\n\n\t/**\n\t * Gets a path to the node. The path is an array containing indices of consecutive ancestors of this node,\n\t * beginning from {@link module:engine/view/node~Node#root root}, down to this node's index.\n\t *\n\t * ```ts\n\t * const abc = downcastWriter.createText( 'abc' );\n\t * const foo = downcastWriter.createText( 'foo' );\n\t * const h1 = downcastWriter.createElement( 'h1', null, downcastWriter.createText( 'header' ) );\n\t * const p = downcastWriter.createElement( 'p', null, [ abc, foo ] );\n\t * const div = downcastWriter.createElement( 'div', null, [ h1, p ] );\n\t * foo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t * h1.getPath(); // Returns [ 0 ].\n\t * div.getPath(); // Returns [].\n\t * ```\n\t *\n\t * @returns The path.\n\t */\n\tpublic getPath(): Array<number> {\n\t\tconst path = [];\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n\t\tlet node: Node | DocumentFragment = this;\n\n\t\twhile ( node.parent ) {\n\t\t\tpath.unshift( node.index! );\n\t\t\tnode = node.parent;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this node will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from node's parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */\n\tpublic getAncestors( options: { includeSelf?: boolean; parentFirst?: boolean } = {} ): Array<Node | DocumentFragment> {\n\t\tconst ancestors: Array<Node | DocumentFragment> = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/element~Element} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param node The second node.\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` both nodes will be considered \"ancestors\" too.\n\t * Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t */\n\tpublic getCommonAncestor( node: Node, options: { includeSelf?: boolean } = {} ): Element | DocumentFragment | null {\n\t\tconst ancestorsA = this.getAncestors( options );\n\t\tconst ancestorsB = node.getAncestors( options );\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ] as ( Element | DocumentFragment );\n\t}\n\n\t/**\n\t * Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/view/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */\n\tpublic isBefore( node: Node ): boolean {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst thisPath = this.getPath();\n\t\tconst nodePath = node.getPath();\n\n\t\tconst result = compareArrays( thisPath, nodePath );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'prefix':\n\t\t\t\treturn true;\n\n\t\t\tcase 'extension':\n\t\t\t\treturn false;\n\n\t\t\tdefault:\n\t\t\t\treturn thisPath[ result as number ] < nodePath[ result as number ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/view/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */\n\tpublic isAfter( node: Node ): boolean {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// In other cases, just check if the `node` is before, and return the opposite.\n\t\treturn !this.isBefore( node );\n\t}\n\n\t/**\n\t * Removes node from parent.\n\t *\n\t * @internal\n\t */\n\tpublic _remove(): void {\n\t\tthis.parent!._removeChildren( this.index! );\n\t}\n\n\t/**\n\t * @internal\n\t * @param type Type of the change.\n\t * @param node Changed node.\n\t * @fires change\n\t */\n\tpublic _fireChange( type: ChangeType, node: Node ): void {\n\t\tthis.fire<ViewNodeChangeEvent>( `change:${ type }`, node );\n\n\t\tif ( this.parent ) {\n\t\t\tthis.parent._fireChange( type, node );\n\t\t}\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns Clone of this object with the parent property removed.\n\t */\n\tpublic toJSON(): unknown {\n\t\tconst json: any = clone( this );\n\n\t\t// Due to circular references we need to remove parent reference.\n\t\tdelete json.parent;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Clones this node.\n\t *\n\t * @internal\n\t * @returns Clone of this node.\n\t */\n\tpublic abstract _clone( deep?: boolean ): Node;\n\n\t/**\n\t * Checks if provided node is similar to this node.\n\t *\n\t * @returns True if nodes are similar.\n\t */\n\tpublic abstract isSimilar( other: Node ): boolean;\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nNode.prototype.is = function( type: string ): boolean {\n\treturn type === 'node' || type === 'view:node';\n};\n\n/**\n * Fired when list of {@link module:engine/view/element~Element elements} children, attributes or data changes.\n *\n * Change event is bubbled – it is fired on all ancestors.\n *\n * @eventName ~Node#change\n * @eventName ~Node#change:children\n * @eventName ~Node#change:attributes\n * @eventName ~Node#change:text\n */\nexport type ViewNodeChangeEvent = {\n\tname: 'change' | `change:${ ChangeType }`;\n\targs: [ changedNode: Node ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/text\n */\n\nimport Node from './node.js';\n\nimport type Document from './document.js';\n\n/**\n * Tree view text node.\n *\n * The constructor of this class should not be used directly. To create a new text node instance\n * use the {@link module:engine/view/downcastwriter~DowncastWriter#createText `DowncastWriter#createText()`}\n * method when working on data downcasted from the model or the\n * {@link module:engine/view/upcastwriter~UpcastWriter#createText `UpcastWriter#createText()`}\n * method when working on non-semantic views.\n */\nexport default class Text extends Node {\n\t/**\n\t * The text content.\n\t *\n\t * Setting the data fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t */\n\tprivate _textData: string;\n\n\t/**\n\t * Creates a tree view text node.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createText\n\t * @internal\n\t * @param document The document instance to which this text node belongs.\n\t * @param data The text's data.\n\t */\n\tconstructor( document: Document, data: string ) {\n\t\tsuper( document );\n\n\t\tthis._textData = data;\n\t}\n\n\t/**\n\t * The text content.\n\t */\n\tpublic get data(): string {\n\t\treturn this._textData;\n\t}\n\n\t/**\n\t * The `_data` property is controlled by a getter and a setter.\n\t *\n\t * The getter is required when using the addition assignment operator on protected property:\n\t *\n\t * ```ts\n\t * const foo = downcastWriter.createText( 'foo' );\n\t * const bar = downcastWriter.createText( 'bar' );\n\t *\n\t * foo._data += bar.data;   // executes: `foo._data = foo._data + bar.data`\n\t * console.log( foo.data ); // prints: 'foobar'\n\t * ```\n\t *\n\t * If the protected getter didn't exist, `foo._data` will return `undefined` and result of the merge will be invalid.\n\t *\n\t * The setter sets data and fires the {@link module:engine/view/node~Node#event:change:text change event}.\n\t *\n\t * @internal\n\t */\n\tpublic get _data(): string {\n\t\treturn this.data;\n\t}\n\n\tpublic set _data( data: string ) {\n\t\tthis._fireChange( 'text', this );\n\n\t\tthis._textData = data;\n\t}\n\n\t/**\n\t * Checks if this text node is similar to other text node.\n\t * Both nodes should have the same data to be considered as similar.\n\t *\n\t * @param otherNode Node to check if it is same as this node.\n\t */\n\tpublic isSimilar( otherNode: Node ): boolean {\n\t\tif ( !( otherNode instanceof Text ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this === otherNode || this.data === otherNode.data;\n\t}\n\n\t/**\n\t * Clones this node.\n\t *\n\t * @internal\n\t * @returns Text node that is a clone of this node.\n\t */\n\tpublic _clone(): Text {\n\t\treturn new Text( this.document, this.data );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `#${ this.data }`;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ViewText: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logExtended(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ViewText: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nText.prototype.is = function( type: string ): boolean {\n\treturn type === '$text' || type === 'view:$text' ||\n\t\t// This are legacy values kept for backward compatibility.\n\t\ttype === 'text' || type === 'view:text' ||\n\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\ttype === 'node' || type === 'view:node';\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/textproxy\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type Document from './document.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type Node from './node.js';\nimport type Text from './text.js';\n\n/**\n * TextProxy is a wrapper for substring of {@link module:engine/view/text~Text}. Instance of this class is created by\n * {@link module:engine/view/treewalker~TreeWalker} when only a part of {@link module:engine/view/text~Text} needs to be returned.\n *\n * `TextProxy` has an API similar to {@link module:engine/view/text~Text Text} and allows to do most of the common tasks performed\n * on view nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/view/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is a readonly interface.\n *\n * **Note:** `TextProxy` instances are created on the fly basing on the current state of parent {@link module:engine/view/text~Text}.\n * Because of this it is highly unrecommended to store references to `TextProxy instances because they might get\n * invalidated due to operations on Document. Also TextProxy is not a {@link module:engine/view/node~Node} so it can not be\n * inserted as a child of {@link module:engine/view/element~Element}.\n *\n * `TextProxy` instances are created by {@link module:engine/view/treewalker~TreeWalker view tree walker}. You should not need to create\n * an instance of this class by your own.\n */\nexport default class TextProxy extends TypeCheckable {\n\t/**\n\t * Reference to the {@link module:engine/view/text~Text} element which TextProxy is a substring.\n\t */\n\tpublic readonly textNode: Text;\n\n\t/**\n\t * Text data represented by this text proxy.\n\t */\n\tpublic readonly data: string;\n\n\t/**\n\t * Offset in the `textNode` where this `TextProxy` instance starts.\n\t */\n\tpublic readonly offsetInText: number;\n\n\t/**\n\t * Creates a text proxy.\n\t *\n\t * @internal\n\t * @param textNode Text node which part is represented by this text proxy.\n\t * @param offsetInText Offset in {@link module:engine/view/textproxy~TextProxy#textNode text node}\n\t * from which the text proxy starts.\n\t * @param length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t * @constructor\n\t */\n\tconstructor( textNode: Text, offsetInText: number, length: number ) {\n\t\tsuper();\n\n\t\tthis.textNode = textNode;\n\n\t\tif ( offsetInText < 0 || offsetInText > textNode.data.length ) {\n\t\t\t/**\n\t\t\t * Given offsetInText value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-offsetintext\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-textproxy-wrong-offsetintext', this );\n\t\t}\n\n\t\tif ( length < 0 || offsetInText + length > textNode.data.length ) {\n\t\t\t/**\n\t\t\t * Given length value is incorrect.\n\t\t\t *\n\t\t\t * @error view-textproxy-wrong-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-textproxy-wrong-length', this );\n\t\t}\n\n\t\tthis.data = textNode.data.substring( offsetInText, offsetInText + length );\n\t\tthis.offsetInText = offsetInText;\n\t}\n\n\t/**\n\t * Offset size of this node.\n\t */\n\tpublic get offsetSize(): number {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/view/text~Text text node}\n\t * (`true`) or the whole text node (`false`).\n\t *\n\t * This is `false` when text proxy starts at the very beginning of {@link module:engine/view/textproxy~TextProxy#textNode textNode}\n\t * ({@link module:engine/view/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t */\n\tpublic get isPartial(): boolean {\n\t\treturn this.data.length !== this.textNode.data.length;\n\t}\n\n\t/**\n\t * Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t */\n\tpublic get parent(): Element | DocumentFragment | null {\n\t\treturn this.textNode.parent;\n\t}\n\n\t/**\n\t * Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t */\n\tpublic get root(): Node | DocumentFragment {\n\t\treturn this.textNode.root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/document~Document View document} that owns this text proxy, or `null` if the text proxy is inside\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t */\n\tpublic get document(): Document | null {\n\t\treturn this.textNode.document;\n\t}\n\n\t/**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true`, textNode will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from text proxy parent to\n\t * root element, otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */\n\tpublic getAncestors( options: {\n\t\tincludeSelf?: boolean;\n\t\tparentFirst?: boolean;\n\t} = {} ): Array<Text | Element | DocumentFragment> {\n\t\tconst ancestors: Array<Text | Element | DocumentFragment> = [];\n\t\tlet parent: Text | Element | DocumentFragment | null = options.includeSelf ? this.textNode : this.parent;\n\n\t\twhile ( parent !== null ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `#${ this.data }`;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ViewTextProxy: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logExtended(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ViewTextProxy: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nTextProxy.prototype.is = function( type: string ): boolean {\n\treturn type === '$textProxy' || type === 'view:$textProxy' ||\n\t\t// This are legacy values kept for backward compatibility.\n\t\ttype === 'textProxy' || type === 'view:textProxy';\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/matcher\n */\n\nimport type Element from './element.js';\n\nimport { isPlainObject } from 'lodash-es';\n\nimport { logWarning } from '@ckeditor/ckeditor5-utils';\n\n/**\n * View matcher class.\n * Instance of this class can be used to find {@link module:engine/view/element~Element elements} that match given pattern.\n */\nexport default class Matcher {\n\tprivate readonly _patterns: Array<MatcherFunctionPattern | MatcherObjectPattern> = [];\n\n\t/**\n\t * Creates new instance of Matcher.\n\t *\n\t * @param pattern Match patterns. See {@link module:engine/view/matcher~Matcher#add add method} for more information.\n\t */\n\tconstructor( ...pattern: Array<MatcherPattern> ) {\n\t\tthis.add( ...pattern );\n\t}\n\n\t/**\n\t * Adds pattern or patterns to matcher instance.\n\t *\n\t * ```ts\n\t * // String.\n\t * matcher.add( 'div' );\n\t *\n\t * // Regular expression.\n\t * matcher.add( /^\\w/ );\n\t *\n\t * // Single class.\n\t * matcher.add( {\n\t * \tclasses: 'foobar'\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/view/matcher~MatcherPattern} for more examples.\n\t *\n\t * Multiple patterns can be added in one call:\n\t *\n\t * ```ts\n\t * matcher.add( 'div', { classes: 'foobar' } );\n\t * ```\n\t *\n\t * @param pattern Object describing pattern details. If string or regular expression\n\t * is provided it will be used to match element's name. Pattern can be also provided in a form\n\t * of a function - then this function will be called with each {@link module:engine/view/element~Element element} as a parameter.\n\t * Function's return value will be stored under `match` key of the object returned from\n\t * {@link module:engine/view/matcher~Matcher#match match} or {@link module:engine/view/matcher~Matcher#matchAll matchAll} methods.\n\t */\n\tpublic add( ...pattern: Array<MatcherPattern> ): void {\n\t\tfor ( let item of pattern ) {\n\t\t\t// String or RegExp pattern is used as element's name.\n\t\t\tif ( typeof item == 'string' || item instanceof RegExp ) {\n\t\t\t\titem = { name: item };\n\t\t\t}\n\n\t\t\tthis._patterns.push( item );\n\t\t}\n\t}\n\n\t/**\n\t * Matches elements for currently stored patterns. Returns match information about first found\n\t * {@link module:engine/view/element~Element element}, otherwise returns `null`.\n\t *\n\t * Example of returned object:\n\t *\n\t * ```ts\n\t * {\n\t * \telement: <instance of found element>,\n\t * \tpattern: <pattern used to match found element>,\n\t * \tmatch: {\n\t * \t\tname: true,\n\t * \t\tattributes: [ 'title', 'href' ],\n\t * \t\tclasses: [ 'foo' ],\n\t * \t\tstyles: [ 'color', 'position' ]\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * @see module:engine/view/matcher~Matcher#add\n\t * @see module:engine/view/matcher~Matcher#matchAll\n\t * @param element View element to match against stored patterns.\n\t */\n\tpublic match( ...element: Array<Element> ): MatchResult | null {\n\t\tfor ( const singleElement of element ) {\n\t\t\tfor ( const pattern of this._patterns ) {\n\t\t\t\tconst match = isElementMatching( singleElement, pattern );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\telement: singleElement,\n\t\t\t\t\t\tpattern,\n\t\t\t\t\t\tmatch\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Matches elements for currently stored patterns. Returns array of match information with all found\n\t * {@link module:engine/view/element~Element elements}. If no element is found - returns `null`.\n\t *\n\t * @see module:engine/view/matcher~Matcher#add\n\t * @see module:engine/view/matcher~Matcher#match\n\t * @param element View element to match against stored patterns.\n\t * @returns Array with match information about found elements or `null`. For more information\n\t * see {@link module:engine/view/matcher~Matcher#match match method} description.\n\t */\n\tpublic matchAll( ...element: Array<Element> ): Array<MatchResult> | null {\n\t\tconst results: Array<MatchResult> = [];\n\n\t\tfor ( const singleElement of element ) {\n\t\t\tfor ( const pattern of this._patterns ) {\n\t\t\t\tconst match = isElementMatching( singleElement, pattern );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\tresults.push( {\n\t\t\t\t\t\telement: singleElement,\n\t\t\t\t\t\tpattern,\n\t\t\t\t\t\tmatch\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn results.length > 0 ? results : null;\n\t}\n\n\t/**\n\t * Returns the name of the element to match if there is exactly one pattern added to the matcher instance\n\t * and it matches element name defined by `string` (not `RegExp`). Otherwise, returns `null`.\n\t *\n\t * @returns Element name trying to match.\n\t */\n\tpublic getElementName(): string | null {\n\t\tif ( this._patterns.length !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst pattern = this._patterns[ 0 ];\n\t\tconst name = pattern.name;\n\n\t\treturn ( typeof pattern != 'function' && name && !( name instanceof RegExp ) ) ? name : null;\n\t}\n}\n\n/**\n * Returns match information if {@link module:engine/view/element~Element element} is matching provided pattern.\n * If element cannot be matched to provided pattern - returns `null`.\n *\n * @returns Returns object with match information or null if element is not matching.\n */\nfunction isElementMatching( element: Element, pattern: MatcherFunctionPattern | MatcherObjectPattern ): Match | null {\n\t// If pattern is provided as function - return result of that function;\n\tif ( typeof pattern == 'function' ) {\n\t\treturn pattern( element );\n\t}\n\n\tconst match: Match = {};\n\n\t// Check element's name.\n\tif ( pattern.name ) {\n\t\tmatch.name = matchName( pattern.name, element.name );\n\n\t\tif ( !match.name ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Check element's attributes.\n\tif ( pattern.attributes ) {\n\t\tmatch.attributes = matchAttributes( pattern.attributes, element );\n\n\t\tif ( !match.attributes ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Check element's classes.\n\tif ( pattern.classes ) {\n\t\tmatch.classes = matchClasses( pattern.classes, element );\n\n\t\tif ( !match.classes ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Check element's styles.\n\tif ( pattern.styles ) {\n\t\tmatch.styles = matchStyles( pattern.styles, element );\n\n\t\tif ( !match.styles ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn match;\n}\n\n/**\n * Checks if name can be matched by provided pattern.\n *\n * @returns Returns `true` if name can be matched, `false` otherwise.\n */\nfunction matchName( pattern: string | RegExp, name: string ): boolean {\n\t// If pattern is provided as RegExp - test against this regexp.\n\tif ( pattern instanceof RegExp ) {\n\t\treturn !!name.match( pattern );\n\t}\n\n\treturn pattern === name;\n}\n\n/**\n * Checks if an array of key/value pairs can be matched against provided patterns.\n *\n * Patterns can be provided in a following ways:\n * - a boolean value matches any attribute with any value (or no value):\n *\n * ```ts\n * pattern: true\n * ```\n *\n * - a RegExp expression or object matches any attribute name:\n *\n * ```ts\n * pattern: /h[1-6]/\n * ```\n *\n * - an object matches any attribute that has the same name as the object item's key, where object item's value is:\n * \t- equal to `true`, which matches any attribute value:\n *\n * ```ts\n * pattern: {\n * \trequired: true\n * }\n * ```\n *\n * \t- a string that is equal to attribute value:\n *\n * ```ts\n * pattern: {\n * \trel: 'nofollow'\n * }\n * ```\n *\n * \t- a regular expression that matches attribute value,\n *\n * ```ts\n * pattern: {\n * \tsrc: /^https/\n * }\n * ```\n *\n * - an array with items, where the item is:\n * \t- a string that is equal to attribute value:\n *\n * ```ts\n * pattern: [ 'data-property-1', 'data-property-2' ],\n * ```\n *\n * \t- an object with `key` and `value` property, where `key` is a regular expression matching attribute name and\n * \t\t`value` is either regular expression matching attribute value or a string equal to attribute value:\n *\n * ```ts\n * pattern: [\n * \t{ key: /^data-property-/, value: true },\n * \t// or:\n * \t{ key: /^data-property-/, value: 'foobar' },\n * \t// or:\n * \t{ key: /^data-property-/, value: /^foo/ }\n * ]\n * ```\n *\n * @param patterns Object with information about attributes to match.\n * @param keys Attribute, style or class keys.\n * @param valueGetter A function providing value for a given item key.\n * @returns Returns array with matched attribute names or `null` if no attributes were matched.\n */\nfunction matchPatterns(\n\tpatterns: PropertyPatterns,\n\tkeys: Iterable<string>,\n\tvalueGetter: ( value: string ) => unknown\n): Array<string> | undefined {\n\tconst normalizedPatterns = normalizePatterns( patterns );\n\tconst normalizedItems = Array.from( keys );\n\tconst match: Array<string> = [];\n\n\tnormalizedPatterns.forEach( ( [ patternKey, patternValue ] ) => {\n\t\tnormalizedItems.forEach( itemKey => {\n\t\t\tif (\n\t\t\t\tisKeyMatched( patternKey, itemKey ) &&\n\t\t\t\tisValueMatched( patternValue, itemKey, valueGetter )\n\t\t\t) {\n\t\t\t\tmatch.push( itemKey );\n\t\t\t}\n\t\t} );\n\t} );\n\n\t// Return matches only if there are at least as many of them as there are patterns.\n\t// The RegExp pattern can match more than one item.\n\tif ( !normalizedPatterns.length || match.length < normalizedPatterns.length ) {\n\t\treturn undefined;\n\t}\n\n\treturn match;\n}\n\n/**\n * Bring all the possible pattern forms to an array of arrays where first item is a key and second is a value.\n *\n * Examples:\n *\n * Boolean pattern value:\n *\n * ```ts\n * true\n * ```\n *\n * to\n *\n * ```ts\n * [ [ true, true ] ]\n * ```\n *\n * Textual pattern value:\n *\n * ```ts\n * 'attribute-name-or-class-or-style'\n * ```\n *\n * to\n *\n * ```ts\n * [ [ 'attribute-name-or-class-or-style', true ] ]\n * ```\n *\n * Regular expression:\n *\n * ```ts\n * /^data-.*$/\n * ```\n *\n * to\n *\n * ```ts\n * [ [ /^data-.*$/, true ] ]\n * ```\n *\n * Objects (plain or with `key` and `value` specified explicitly):\n *\n * ```ts\n * {\n * \tsrc: /^https:.*$/\n * }\n * ```\n *\n * or\n *\n * ```ts\n * [ {\n * \tkey: 'src',\n * \tvalue: /^https:.*$/\n * } ]\n * ```\n *\n * to:\n *\n * ```ts\n * [ [ 'src', /^https:.*$/ ] ]\n * ```\n *\n * @returns Returns an array of objects or null if provided patterns were not in an expected form.\n */\nfunction normalizePatterns( patterns: PropertyPatterns ): Array<[ true | string | RegExp, true | string | RegExp ]> {\n\tif ( Array.isArray( patterns ) ) {\n\t\treturn patterns.map( ( pattern: any ) => {\n\t\t\tif ( isPlainObject( pattern ) ) {\n\t\t\t\tif ( pattern.key === undefined || pattern.value === undefined ) {\n\t\t\t\t\t// Documented at the end of matcher.js.\n\t\t\t\t\tlogWarning( 'matcher-pattern-missing-key-or-value', pattern );\n\t\t\t\t}\n\n\t\t\t\treturn [ pattern.key, pattern.value ];\n\t\t\t}\n\n\t\t\t// Assume the pattern is either String or RegExp.\n\t\t\treturn [ pattern, true ];\n\t\t} );\n\t}\n\n\tif ( isPlainObject( patterns ) ) {\n\t\treturn Object.entries( patterns );\n\t}\n\n\t// Other cases (true, string or regexp).\n\treturn [ [ patterns as any, true ] ];\n}\n\n/**\n * @param patternKey A pattern representing a key we want to match.\n * @param itemKey An actual item key (e.g. `'src'`, `'background-color'`, `'ck-widget'`) we're testing against pattern.\n */\nfunction isKeyMatched( patternKey: true | string | RegExp, itemKey: string ): unknown {\n\treturn patternKey === true ||\n\t\tpatternKey === itemKey ||\n\t\tpatternKey instanceof RegExp && itemKey.match( patternKey );\n}\n\n/**\n * @param patternValue A pattern representing a value we want to match.\n * @param itemKey An item key, e.g. `background`, `href`, 'rel', etc.\n * @param valueGetter A function used to provide a value for a given `itemKey`.\n */\nfunction isValueMatched(\n\tpatternValue: true | string | RegExp,\n\titemKey: string,\n\tvalueGetter: ( itemKey: string ) => unknown\n): boolean {\n\tif ( patternValue === true ) {\n\t\treturn true;\n\t}\n\n\tconst itemValue = valueGetter( itemKey );\n\n\t// For now, the reducers are not returning the full tree of properties.\n\t// Casting to string preserves the old behavior until the root cause is fixed.\n\t// More can be found in https://github.com/ckeditor/ckeditor5/issues/10399.\n\treturn patternValue === itemValue ||\n\t\tpatternValue instanceof RegExp && !!String( itemValue ).match( patternValue );\n}\n\n/**\n * Checks if attributes of provided element can be matched against provided patterns.\n *\n * @param patterns Object with information about attributes to match. Each key of the object will be\n * used as attribute name. Value of each key can be a string or regular expression to match against attribute value.\n * @param  element Element which attributes will be tested.\n * @returns Returns array with matched attribute names or `null` if no attributes were matched.\n */\nfunction matchAttributes(\n\tpatterns: AttributePatterns,\n\telement: Element\n): Array<string> | undefined {\n\tconst attributeKeys = new Set( element.getAttributeKeys() );\n\n\t// `style` and `class` attribute keys are deprecated. Only allow them in object pattern\n\t// for backward compatibility.\n\tif ( isPlainObject( patterns ) ) {\n\t\tif ( ( patterns as any ).style !== undefined ) {\n\t\t\t// Documented at the end of matcher.js.\n\t\t\tlogWarning( 'matcher-pattern-deprecated-attributes-style-key', patterns as any );\n\t\t}\n\t\tif ( ( patterns as any ).class !== undefined ) {\n\t\t\t// Documented at the end of matcher.js.\n\t\t\tlogWarning( 'matcher-pattern-deprecated-attributes-class-key', patterns as any );\n\t\t}\n\t} else {\n\t\tattributeKeys.delete( 'style' );\n\t\tattributeKeys.delete( 'class' );\n\t}\n\n\treturn matchPatterns( patterns, attributeKeys, key => element.getAttribute( key ) );\n}\n\n/**\n * Checks if classes of provided element can be matched against provided patterns.\n *\n * @param patterns Array of strings or regular expressions to match against element's classes.\n * @param element Element which classes will be tested.\n * @returns Returns array with matched class names or `null` if no classes were matched.\n */\nfunction matchClasses( patterns: ClassPatterns, element: Element ): Array<string> | undefined {\n\t// We don't need `getter` here because patterns for classes are always normalized to `[ className, true ]`.\n\treturn matchPatterns( patterns, element.getClassNames(), /* istanbul ignore next -- @preserve */ () => {} );\n}\n\n/**\n * Checks if styles of provided element can be matched against provided patterns.\n *\n * @param patterns Object with information about styles to match. Each key of the object will be\n * used as style name. Value of each key can be a string or regular expression to match against style value.\n * @param element Element which styles will be tested.\n * @returns Returns array with matched style names or `null` if no styles were matched.\n */\nfunction matchStyles( patterns: StylePatterns, element: Element ): Array<string> | undefined {\n\treturn matchPatterns( patterns, element.getStyleNames( true ), key => element.getStyle( key ) );\n}\n\n/**\n * An entity that is a valid pattern recognized by a matcher. `MatcherPattern` is used by {@link ~Matcher} to recognize\n * if a view element fits in a group of view elements described by the pattern.\n *\n * `MatcherPattern` can be given as a `String`, a `RegExp`, an `Object` or a `Function`.\n *\n * If `MatcherPattern` is given as a `String` or `RegExp`, it will match any view element that has a matching name:\n *\n * ```ts\n * // Match any element with name equal to 'div'.\n * const pattern = 'div';\n *\n * // Match any element which name starts on 'p'.\n * const pattern = /^p/;\n * ```\n *\n * If `MatcherPattern` is given as an `Object`, all the object's properties will be matched with view element properties.\n * If the view element does not meet all of the object's pattern properties, the match will not happen.\n * Available `Object` matching properties:\n *\n * Matching view element:\n *\n * ```ts\n * // Match view element's name using String:\n * const pattern = { name: 'p' };\n *\n * // or by providing RegExp:\n * const pattern = { name: /^(ul|ol)$/ };\n *\n * // The name can also be skipped to match any view element with matching attributes:\n * const pattern = {\n * \tattributes: {\n * \t\t'title': true\n * \t}\n * };\n * ```\n *\n * Matching view element attributes:\n *\n * ```ts\n * // Match view element with any attribute value.\n * const pattern = {\n * \tname: 'p',\n * \tattributes: true\n * };\n *\n * // Match view element which has matching attributes (String).\n * const pattern = {\n * \tname: 'figure',\n * \tattributes: 'title' // Match title attribute (can be empty).\n * };\n *\n * // Match view element which has matching attributes (RegExp).\n * const pattern = {\n * \tname: 'figure',\n * \tattributes: /^data-.*$/ // Match attributes starting with `data-` e.g. `data-foo` with any value (can be empty).\n * };\n *\n * // Match view element which has matching attributes (Object).\n * const pattern = {\n * \tname: 'figure',\n * \tattributes: {\n * \t\ttitle: 'foobar',           // Match `title` attribute with 'foobar' value.\n * \t\talt: true,                 // Match `alt` attribute with any value (can be empty).\n * \t\t'data-type': /^(jpg|png)$/ // Match `data-type` attribute with `jpg` or `png` value.\n * \t}\n * };\n *\n * // Match view element which has matching attributes (Array).\n * const pattern = {\n * \tname: 'figure',\n * \tattributes: [\n * \t\t'title',    // Match `title` attribute (can be empty).\n * \t\t/^data-*$/ // Match attributes starting with `data-` e.g. `data-foo` with any value (can be empty).\n * \t]\n * };\n *\n * // Match view element which has matching attributes (key-value pairs).\n * const pattern = {\n * \tname: 'input',\n * \tattributes: [\n * \t\t{\n * \t\t\tkey: 'type',                     // Match `type` as an attribute key.\n * \t\t\tvalue: /^(text|number|date)$/\t // Match `text`, `number` or `date` values.\n * \t\t},\n * \t\t{\n * \t\t\tkey: /^data-.*$/,                // Match attributes starting with `data-` e.g. `data-foo`.\n * \t\t\tvalue: true                      // Match any value (can be empty).\n * \t\t}\n * \t]\n * };\n * ```\n *\n * Matching view element styles:\n *\n * ```ts\n * // Match view element with any style.\n * const pattern = {\n * \tname: 'p',\n * \tstyles: true\n * };\n *\n * // Match view element which has matching styles (String).\n * const pattern = {\n * \tname: 'p',\n * \tstyles: 'color' // Match attributes with `color` style.\n * };\n *\n * // Match view element which has matching styles (RegExp).\n * const pattern = {\n * \tname: 'p',\n * \tstyles: /^border.*$/ // Match view element with any border style.\n * };\n *\n * // Match view element which has matching styles (Object).\n * const pattern = {\n * \tname: 'p',\n * \tstyles: {\n * \t\tcolor: /rgb\\((\\d{1,3}), (\\d{1,3}), (\\d{1,3})\\)/, // Match `color` in RGB format only.\n * \t\t'font-weight': 600,                              // Match `font-weight` only if it's `600`.\n * \t\t'text-decoration': true                          // Match any text decoration.\n * \t}\n * };\n *\n * // Match view element which has matching styles (Array).\n * const pattern = {\n * \tname: 'p',\n * \tstyles: [\n * \t\t'color',      // Match `color` with any value.\n * \t\t/^border.*$/ // Match all border properties.\n * \t]\n * };\n *\n * // Match view element which has matching styles (key-value pairs).\n * const pattern = {\n * \tname: 'p',\n * \tstyles: [\n * \t\t{\n * \t\t\tkey: 'color',                                  \t\t// Match `color` as an property key.\n * \t\t\tvalue: /rgb\\((\\d{1,3}), (\\d{1,3}), (\\d{1,3})\\)/\t\t// Match RGB format only.\n * \t\t},\n * \t\t{\n * \t\t\tkey: /^border.*$/, // Match any border style.\n * \t\t\tvalue: true        // Match any value.\n * \t\t}\n * \t]\n * };\n * ```\n *\n * Matching view element classes:\n *\n * ```ts\n * // Match view element with any class.\n * const pattern = {\n * \tname: 'p',\n * \tclasses: true\n * };\n *\n * // Match view element which has matching class (String).\n * const pattern = {\n * \tname: 'p',\n * \tclasses: 'highlighted' // Match `highlighted` class.\n * };\n *\n * // Match view element which has matching classes (RegExp).\n * const pattern = {\n * \tname: 'figure',\n * \tclasses: /^image-side-(left|right)$/ // Match `image-side-left` or `image-side-right` class.\n * };\n *\n * // Match view element which has matching classes (Object).\n * const pattern = {\n * \tname: 'p',\n * \tclasses: {\n * \t\thighlighted: true, // Match `highlighted` class.\n * \t\tmarker: true       // Match `marker` class.\n * \t}\n * };\n *\n * // Match view element which has matching classes (Array).\n * const pattern = {\n * \tname: 'figure',\n * \tclasses: [\n * \t\t'image',                    // Match `image` class.\n * \t\t/^image-side-(left|right)$/ // Match `image-side-left` or `image-side-right` class.\n * \t]\n * };\n *\n * // Match view element which has matching classes (key-value pairs).\n * const pattern = {\n * \tname: 'figure',\n * \tclasses: [\n * \t\t{\n * \t\t\tkey: 'image', // Match `image` class.\n * \t\t\tvalue: true\n * \t\t},\n * \t\t{\n * \t\t\tkey: /^image-side-(left|right)$/, // Match `image-side-left` or `image-side-right` class.\n * \t\t\tvalue: true\n * \t\t}\n * \t]\n * };\n * ```\n *\n * Pattern can combine multiple properties allowing for more complex view element matching:\n *\n * ```ts\n * const pattern = {\n * \tname: 'span',\n * \tattributes: [ 'title' ],\n * \tstyles: {\n * \t\t'font-weight': 'bold'\n * \t},\n * \tclasses: 'highlighted'\n * };\n * ```\n *\n * If `MatcherPattern` is given as a `Function`, the function takes a view element as a first and only parameter and\n * the function should decide whether that element matches. If so, it should return what part of the view element has been matched.\n * Otherwise, the function should return `null`. The returned result will be included in `match` property of the object\n * returned by {@link ~Matcher#match} call.\n *\n * ```ts\n * // Match an empty <div> element.\n * const pattern = element => {\n * \tif ( element.name == 'div' && element.childCount > 0 ) {\n * \t\t// Return which part of the element was matched.\n * \t\treturn { name: true };\n * \t}\n *\n * \treturn null;\n * };\n *\n * // Match a <p> element with big font (\"heading-like\" element).\n * const pattern = element => {\n * \tif ( element.name == 'p' ) {\n * \t\tconst fontSize = element.getStyle( 'font-size' );\n * \t\tconst size = fontSize.match( /(\\d+)/px );\n *\n * \t\tif ( size && Number( size[ 1 ] ) > 26 ) {\n * \t\t\treturn { name: true, attributes: [ 'font-size' ] };\n * \t\t}\n * \t}\n *\n * \treturn null;\n * };\n * ```\n *\n * `MatcherPattern` is defined in a way that it is a superset of {@link module:engine/view/elementdefinition~ElementDefinition},\n * that is, every `ElementDefinition` also can be used as a `MatcherPattern`.\n */\nexport type MatcherPattern = string | RegExp | MatcherFunctionPattern | MatcherObjectPattern;\n\n/**\n * A function describing `MatcherPattern`. See {@link ~MatcherPattern} for examples and other options.\n */\nexport type MatcherFunctionPattern = ( element: Element ) => Match | null;\n\n/**\n * An object describing `MatcherPattern`. See {@link ~MatcherPattern} for examples and other options.\n */\nexport interface MatcherObjectPattern {\n\n\t/**\n\t * View element name to match.\n\t */\n\tname?: string | RegExp;\n\n\tkey?: string;\n\n\t/**\n\t * View element's classes to match.\n\t */\n\tclasses?: ClassPatterns;\n\n\t/**\n\t * View element's styles to match.\n\t */\n\tstyles?: StylePatterns;\n\n\t/**\n\t * View element's attributes to match.\n\t */\n\tattributes?: AttributePatterns;\n}\n\n/**\n * An object representing matched element parts.\n */\nexport interface Match {\n\n\t/**\n\t * True if name of the element was matched.\n\t */\n\tname?: boolean;\n\n\t/**\n\t * Array with matched attribute names.\n\t */\n\tattributes?: Array<string>;\n\n\t/**\n\t * Array with matched class names.\n\t */\n\tclasses?: Array<string>;\n\n\t/**\n\t * Array with matched style names.\n\t */\n\tstyles?: Array<string>;\n}\n\n/**\n * The result of {@link ~Matcher#match}.\n */\nexport interface MatchResult {\n\n\t/**\n\t * Matched view element.\n\t */\n\telement: Element;\n\n\t/**\n\t * Pattern that was used to find matched element.\n\t */\n\tpattern: MatcherFunctionPattern | MatcherObjectPattern;\n\n\t/**\n\t * An object representing matched element parts.\n\t */\n\tmatch: Match;\n}\n\nexport type PropertyPatterns<ValuePattern = string | RegExp> =\n\ttrue |\n\tstring |\n\tRegExp |\n\tRecord<string, true | ValuePattern> |\n\tArray<string | RegExp | { key: string | RegExp; value: true | ValuePattern }>;\n\nexport type AttributePatterns = PropertyPatterns;\nexport type StylePatterns = PropertyPatterns;\nexport type ClassPatterns = PropertyPatterns<never>;\n\n/**\n * The key-value matcher pattern is missing key or value. Both must be present.\n * Refer the documentation: {@link module:engine/view/matcher~MatcherPattern}.\n *\n * @param pattern Pattern with missing properties.\n * @error matcher-pattern-missing-key-or-value\n */\n\n/**\n * The key-value matcher pattern for `attributes` option is using deprecated `style` key.\n *\n * Use `styles` matcher pattern option instead:\n *\n * ```ts\n * // Instead of:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2',\n * \t\tstyle: /^border.*$/\n * \t}\n * }\n *\n * // Use:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2'\n * \t},\n * \tstyles: /^border.*$/\n * }\n * ```\n *\n * Refer to the {@glink updating/guides/update-to-29##update-to-ckeditor-5-v2910 Migration to v29.1.0} guide\n * and {@link module:engine/view/matcher~MatcherPattern} documentation.\n *\n * @param pattern Pattern with missing properties.\n * @error matcher-pattern-deprecated-attributes-style-key\n */\n\n/**\n * The key-value matcher pattern for `attributes` option is using deprecated `class` key.\n *\n * Use `classes` matcher pattern option instead:\n *\n * ```ts\n * // Instead of:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2',\n * \t\tclass: 'foobar'\n * \t}\n * }\n *\n * // Use:\n * const pattern = {\n * \tattributes: {\n * \t\tkey1: 'value1',\n * \t\tkey2: 'value2'\n * \t},\n * \tclasses: 'foobar'\n * }\n * ```\n *\n * Refer to the {@glink updating/guides/update-to-29##update-to-ckeditor-5-v2910 Migration to v29.1.0} guide\n * and the {@link module:engine/view/matcher~MatcherPattern} documentation.\n *\n * @param pattern Pattern with missing properties.\n * @error matcher-pattern-deprecated-attributes-class-key\n */\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/stylesmap\n */\n\nimport { get, isObject, merge, set, unset } from 'lodash-es';\n\n/**\n * Styles map. Allows handling (adding, removing, retrieving) a set of style rules (usually, of an element).\n */\nexport default class StylesMap {\n\t/**\n\t * Keeps an internal representation of styles map. Normalized styles are kept as object tree to allow unified modification and\n\t * value access model using lodash's get, set, unset, etc methods.\n\t *\n\t * When no style processor rules are defined it acts as simple key-value storage.\n\t */\n\tprivate _styles: Styles;\n\n\t/**\n\t * An instance of the {@link module:engine/view/stylesmap~StylesProcessor}.\n\t */\n\tprivate readonly _styleProcessor: StylesProcessor;\n\n\t/**\n\t * Creates Styles instance.\n\t */\n\tconstructor( styleProcessor: StylesProcessor ) {\n\t\tthis._styles = {};\n\t\tthis._styleProcessor = styleProcessor;\n\t}\n\n\t/**\n\t * Returns true if style map has no styles set.\n\t */\n\tpublic get isEmpty(): boolean {\n\t\tconst entries = Object.entries( this._styles );\n\n\t\treturn !entries.length;\n\t}\n\n\t/**\n\t * Number of styles defined.\n\t */\n\tpublic get size(): number {\n\t\tif ( this.isEmpty ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn this.getStyleNames().length;\n\t}\n\n\t/**\n\t * Set styles map to a new value.\n\t *\n\t * ```ts\n\t * styles.setTo( 'border:1px solid blue;margin-top:1px;' );\n\t * ```\n\t */\n\tpublic setTo( inlineStyle: string ): void {\n\t\tthis.clear();\n\n\t\tconst parsedStyles = parseInlineStyles( inlineStyle );\n\n\t\tfor ( const [ key, value ] of parsedStyles ) {\n\t\t\tthis._styleProcessor.toNormalizedForm( key, value, this._styles );\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a given style is set.\n\t *\n\t * ```ts\n\t * styles.setTo( 'margin-left:1px;' );\n\t *\n\t * styles.has( 'margin-left' );    // -> true\n\t * styles.has( 'padding' );        // -> false\n\t * ```\n\t *\n\t * **Note**: This check supports normalized style names.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * styles.setTo( 'margin:2px;' );\n\t *\n\t * styles.has( 'margin' );         // -> true\n\t * styles.has( 'margin-top' );     // -> true\n\t * styles.has( 'margin-left' );    // -> true\n\t *\n\t * styles.remove( 'margin-top' );\n\t *\n\t * styles.has( 'margin' );         // -> false\n\t * styles.has( 'margin-top' );     // -> false\n\t * styles.has( 'margin-left' );    // -> true\n\t * ```\n\t *\n\t * @param name Style name.\n\t */\n\tpublic has( name: string ): boolean {\n\t\tif ( this.isEmpty ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst styles = this._styleProcessor.getReducedForm( name, this._styles );\n\n\t\tconst propertyDescriptor = styles.find( ( [ property ] ) => property === name );\n\n\t\t// Only return a value if it is set;\n\t\treturn Array.isArray( propertyDescriptor );\n\t}\n\n\t/**\n\t * Sets a given style.\n\t *\n\t * Can insert one by one:\n\t *\n\t * ```ts\n\t * styles.set( 'color', 'blue' );\n\t * styles.set( 'margin-right', '1em' );\n\t * ```\n\t *\n\t * ***Note**:* This method uses {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules\n\t * enabled style processor rules} to normalize passed values.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * styles.set( 'margin', '2px' );\n\t * ```\n\t *\n\t * The above code will set margin to:\n\t *\n\t * ```ts\n\t * styles.getNormalized( 'margin' );\n\t * // -> { top: '2px', right: '2px', bottom: '2px', left: '2px' }\n\t * ```\n\t *\n\t * Which makes it possible to retrieve a \"sub-value\":\n\t *\n\t * ```ts\n\t * styles.get( 'margin-left' );       // -> '2px'\n\t * ```\n\t *\n\t * Or modify it:\n\t *\n\t * ```ts\n\t * styles.remove( 'margin-left' );\n\t *\n\t * styles.getNormalized( 'margin' );  // -> { top: '1px', bottom: '1px', right: '1px' }\n\t * styles.toString();                 // -> 'margin-bottom:1px;margin-right:1px;margin-top:1px;'\n\t * ```\n\t *\n\t * This method also allows to set normalized values directly (if a particular styles processor rule was enabled):\n\t *\n\t * ```ts\n\t * styles.set( 'border-color', { top: 'blue' } );\n\t * styles.set( 'margin', { right: '2em' } );\n\t *\n\t * styles.toString();                 // -> 'border-color-top:blue;margin-right:2em;'\n\t * ```\n\t *\n\t * @label KEY_VALUE\n\t * @param name Style property name.\n\t * @param value Value to set.\n\t */\n\tpublic set( name: string, value: StyleValue ): void;\n\n\t/**\n\t * Sets many styles at once:\n\t *\n\t * ```ts\n\t * styles.set( {\n\t * \tcolor: 'blue',\n\t * \t'margin-right': '1em'\n\t * } );\n\t * ```\n\t *\n\t * It is equivalent to:\n\t *\n\t * ```ts\n\t * styles.set( 'color', 'blue' );\n\t * styles.set( 'margin-right', '1em' );\n\t * ```\n\t *\n\t * See {@link #set:KEY_VALUE}\n\t *\n\t * @label CONFIG_OBJECT\n\t */\n\tpublic set( styles: Styles ): void;\n\n\tpublic set( nameOrObject: string | Styles, valueOrObject?: StyleValue ): void {\n\t\tif ( isObject( nameOrObject ) ) {\n\t\t\tfor ( const [ key, value ] of Object.entries( nameOrObject ) ) {\n\t\t\t\tthis._styleProcessor.toNormalizedForm( key, value, this._styles );\n\t\t\t}\n\t\t} else {\n\t\t\tthis._styleProcessor.toNormalizedForm( nameOrObject, valueOrObject!, this._styles );\n\t\t}\n\t}\n\n\t/**\n\t * Removes given style.\n\t *\n\t * ```ts\n\t * styles.setTo( 'background:#f00;margin-right:2px;' );\n\t *\n\t * styles.remove( 'background' );\n\t *\n\t * styles.toString();   // -> 'margin-right:2px;'\n\t * ```\n\t *\n\t * ***Note**:* This method uses {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules\n\t * enabled style processor rules} to normalize passed values.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * styles.setTo( 'margin:1px' );\n\t *\n\t * styles.remove( 'margin-top' );\n\t * styles.remove( 'margin-right' );\n\t *\n\t * styles.toString(); // -> 'margin-bottom:1px;margin-left:1px;'\n\t * ```\n\t *\n\t * @param name Style name.\n\t */\n\tpublic remove( name: string ): void {\n\t\tconst path = toPath( name );\n\n\t\tunset( this._styles, path );\n\t\tdelete this._styles[ name ];\n\n\t\tthis._cleanEmptyObjectsOnPath( path );\n\t}\n\n\t/**\n\t * Returns a normalized style object or a single value.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px 2px 3em;' );\n\t *\n\t * styles.getNormalized( 'margin' );\n\t * // will log:\n\t * // {\n\t * //     top: '1px',\n\t * //     right: '2px',\n\t * //     bottom: '3em',\n\t * //     left: '2px'     // normalized value from margin shorthand\n\t * // }\n\t *\n\t * styles.getNormalized( 'margin-left' ); // -> '2px'\n\t * ```\n\t *\n\t * **Note**: This method will only return normalized styles if a style processor was defined.\n\t *\n\t * @param name Style name.\n\t */\n\tpublic getNormalized( name?: string ): StyleValue {\n\t\treturn this._styleProcessor.getNormalized( name, this._styles );\n\t}\n\n\t/**\n\t * Returns a normalized style string. Styles are sorted by name.\n\t *\n\t * ```ts\n\t * styles.set( 'margin' , '1px' );\n\t * styles.set( 'background', '#f00' );\n\t *\n\t * styles.toString(); // -> 'background:#f00;margin:1px;'\n\t * ```\n\t *\n\t * **Note**: This method supports normalized styles if defined.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * styles.set( 'margin' , '1px' );\n\t * styles.set( 'background', '#f00' );\n\t * styles.remove( 'margin-top' );\n\t * styles.remove( 'margin-right' );\n\t *\n\t * styles.toString(); // -> 'background:#f00;margin-bottom:1px;margin-left:1px;'\n\t * ```\n\t */\n\tpublic toString(): string {\n\t\tif ( this.isEmpty ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn this.getStylesEntries()\n\t\t\t.map( arr => arr.join( ':' ) )\n\t\t\t.sort()\n\t\t\t.join( ';' ) + ';';\n\t}\n\n\t/**\n\t * Returns property as a value string or undefined if property is not set.\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t * styles.set( 'margin-bottom', '3em' );\n\t *\n\t * styles.getAsString( 'margin' ); // -> 'margin: 1px 1px 3em;'\n\t * ```\n\t *\n\t * Note, however, that all sub-values must be set for the longhand property name to return a value:\n\t *\n\t * ```ts\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t * styles.remove( 'margin-bottom' );\n\t *\n\t * styles.getAsString( 'margin' ); // -> undefined\n\t * ```\n\t *\n\t * In the above scenario, it is not possible to return a `margin` value, so `undefined` is returned.\n\t * Instead, you should use:\n\t *\n\t * ```ts\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t * styles.remove( 'margin-bottom' );\n\t *\n\t * for ( const styleName of styles.getStyleNames() ) {\n\t * \tconsole.log( styleName, styles.getAsString( styleName ) );\n\t * }\n\t * // 'margin-top', '1px'\n\t * // 'margin-right', '1px'\n\t * // 'margin-left', '1px'\n\t * ```\n\t *\n\t * In general, it is recommend to iterate over style names like in the example above. This way, you will always get all\n\t * the currently set style values. So, if all the 4 margin values would be set\n\t * the for-of loop above would yield only `'margin'`, `'1px'`:\n\t *\n\t * ```ts\n\t * const styles = new Styles();\n\t * styles.setTo( 'margin:1px;' );\n\t *\n\t * for ( const styleName of styles.getStyleNames() ) {\n\t * \tconsole.log( styleName, styles.getAsString( styleName ) );\n\t * }\n\t * // 'margin', '1px'\n\t * ```\n\t *\n\t * **Note**: To get a normalized version of a longhand property use the {@link #getNormalized `#getNormalized()`} method.\n\t */\n\tpublic getAsString( propertyName: string ): string | undefined {\n\t\tif ( this.isEmpty ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this._styles[ propertyName ] && !isObject( this._styles[ propertyName ] ) ) {\n\t\t\t// Try return styles set directly - values that are not parsed.\n\t\t\treturn this._styles[ propertyName ] as string;\n\t\t}\n\n\t\tconst styles = this._styleProcessor.getReducedForm( propertyName, this._styles );\n\n\t\tconst propertyDescriptor = styles.find( ( [ property ] ) => property === propertyName );\n\n\t\t// Only return a value if it is set;\n\t\tif ( Array.isArray( propertyDescriptor ) ) {\n\t\t\treturn propertyDescriptor[ 1 ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns all style properties names as they would appear when using {@link #toString `#toString()`}.\n\t *\n\t * When `expand` is set to true and there's a shorthand style property set, it will also return all equivalent styles:\n\t *\n\t * ```ts\n\t * stylesMap.setTo( 'margin: 1em' )\n\t * ```\n\t *\n\t * will be expanded to:\n\t *\n\t * ```ts\n\t * [ 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ]\n\t * ```\n\t *\n\t * @param expand Expand shorthand style properties and all return equivalent style representations.\n\t */\n\tpublic getStyleNames( expand = false ): Array<string> {\n\t\tif ( this.isEmpty ) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif ( expand ) {\n\t\t\treturn this._styleProcessor.getStyleNames( this._styles );\n\t\t}\n\n\t\tconst entries = this.getStylesEntries();\n\n\t\treturn entries.map( ( [ key ] ) => key );\n\t}\n\n\t/**\n\t * Removes all styles.\n\t */\n\tpublic clear(): void {\n\t\tthis._styles = {};\n\t}\n\n\t/**\n\t * Returns normalized styles entries for further processing.\n\t */\n\tpublic getStylesEntries(): Array<PropertyDescriptor> {\n\t\tconst parsed: Array<PropertyDescriptor> = [];\n\n\t\tconst keys = Object.keys( this._styles );\n\n\t\tfor ( const key of keys ) {\n\t\t\tparsed.push( ...this._styleProcessor.getReducedForm( key, this._styles ) );\n\t\t}\n\n\t\treturn parsed;\n\t}\n\n\t/**\n\t * Removes empty objects upon removing an entry from internal object.\n\t */\n\tprivate _cleanEmptyObjectsOnPath( path: string ): void {\n\t\tconst pathParts = path.split( '.' );\n\t\tconst isChildPath = pathParts.length > 1;\n\n\t\tif ( !isChildPath ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst parentPath = pathParts.splice( 0, pathParts.length - 1 ).join( '.' );\n\n\t\tconst parentObject = get( this._styles, parentPath );\n\n\t\tif ( !parentObject ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isParentEmpty = !Object.keys( parentObject ).length;\n\n\t\tif ( isParentEmpty ) {\n\t\t\tthis.remove( parentPath );\n\t\t}\n\t}\n}\n\n/**\n * Style processor is responsible for writing and reading a normalized styles object.\n */\nexport class StylesProcessor {\n\tprivate readonly _normalizers: Map<string, Normalizer>;\n\tprivate readonly _extractors: Map<string, Extractor>;\n\tprivate readonly _reducers: Map<string, Reducer>;\n\tprivate readonly _consumables: Map<string, Array<string>>;\n\n\t/**\n\t * Creates StylesProcessor instance.\n\t *\n\t * @internal\n\t */\n\tconstructor() {\n\t\tthis._normalizers = new Map();\n\t\tthis._extractors = new Map();\n\t\tthis._reducers = new Map();\n\t\tthis._consumables = new Map();\n\t}\n\n\t/**\n\t * Parse style string value to a normalized object and appends it to styles object.\n\t *\n\t * ```ts\n\t * const styles = {};\n\t *\n\t * stylesProcessor.toNormalizedForm( 'margin', '1px', styles );\n\t *\n\t * // styles will consist: { margin: { top: '1px', right: '1px', bottom: '1px', left: '1px; } }\n\t * ```\n\t *\n\t * **Note**: To define normalizer callbacks use {@link #setNormalizer}.\n\t *\n\t * @param name Name of style property.\n\t * @param propertyValue Value of style property.\n\t * @param styles Object holding normalized styles.\n\t */\n\tpublic toNormalizedForm( name: string, propertyValue: StyleValue, styles: Styles ): void {\n\t\tif ( isObject( propertyValue ) ) {\n\t\t\tappendStyleValue( styles, toPath( name ), propertyValue );\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this._normalizers.has( name ) ) {\n\t\t\tconst normalizer = this._normalizers.get( name )!;\n\n\t\t\tconst { path, value } = normalizer( propertyValue );\n\n\t\t\tappendStyleValue( styles, path, value );\n\t\t} else {\n\t\t\tappendStyleValue( styles, name, propertyValue );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a normalized version of a style property.\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tmargin: { top: '1px', right: '1px', bottom: '1px', left: '1px; },\n\t * \tbackground: { color: '#f00' }\n\t * };\n\t *\n\t * stylesProcessor.getNormalized( 'background' );\n\t * // will return: { color: '#f00' }\n\t *\n\t * stylesProcessor.getNormalized( 'margin-top' );\n\t * // will return: '1px'\n\t * ```\n\t *\n\t * **Note**: In some cases extracting single value requires defining an extractor callback {@link #setExtractor}.\n\t *\n\t * @param name Name of style property.\n\t * @param styles Object holding normalized styles.\n\t */\n\tpublic getNormalized( name: string | undefined, styles: Styles ): StyleValue {\n\t\tif ( !name ) {\n\t\t\treturn merge( {}, styles );\n\t\t}\n\n\t\t// Might be empty string.\n\t\tif ( styles[ name ] !== undefined ) {\n\t\t\treturn styles[ name ];\n\t\t}\n\n\t\tif ( this._extractors.has( name ) ) {\n\t\t\tconst extractor = this._extractors.get( name )!;\n\n\t\t\tif ( typeof extractor === 'string' ) {\n\t\t\t\treturn get( styles, extractor );\n\t\t\t}\n\n\t\t\tconst value = extractor( name, styles );\n\n\t\t\tif ( value ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\n\t\treturn get( styles, toPath( name ) );\n\t}\n\n\t/**\n\t * Returns a reduced form of style property form normalized object.\n\t *\n\t * For default margin reducer, the below code:\n\t *\n\t * ```ts\n\t * stylesProcessor.getReducedForm( 'margin', {\n\t * \tmargin: { top: '1px', right: '1px', bottom: '2px', left: '1px; }\n\t * } );\n\t * ```\n\t *\n\t * will return:\n\t *\n\t * ```ts\n\t * [\n\t * \t[ 'margin', '1px 1px 2px' ]\n\t * ]\n\t * ```\n\t *\n\t * because it might be represented as a shorthand 'margin' value. However if one of margin long hand values is missing it should return:\n\t *\n\t * ```ts\n\t * [\n\t * \t[ 'margin-top', '1px' ],\n\t * \t[ 'margin-right', '1px' ],\n\t * \t[ 'margin-bottom', '2px' ]\n\t * \t// the 'left' value is missing - cannot use 'margin' shorthand.\n\t * ]\n\t * ```\n\t *\n\t * **Note**: To define reducer callbacks use {@link #setReducer}.\n\t *\n\t * @param name Name of style property.\n\t */\n\tpublic getReducedForm( name: string, styles: Styles ): Array<PropertyDescriptor> {\n\t\tconst normalizedValue = this.getNormalized( name, styles );\n\n\t\t// Might be empty string.\n\t\tif ( normalizedValue === undefined ) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif ( this._reducers.has( name ) ) {\n\t\t\tconst reducer = this._reducers.get( name )!;\n\n\t\t\treturn reducer( normalizedValue );\n\t\t}\n\n\t\treturn [ [ name, normalizedValue as string ] ];\n\t}\n\n\t/**\n\t * Return all style properties. Also expand shorthand properties (e.g. `margin`, `background`) if respective extractor is available.\n\t *\n\t * @param styles Object holding normalized styles.\n\t */\n\tpublic getStyleNames( styles: Styles ): Array<string> {\n\t\tconst styleNamesKeysSet = new Set<string>();\n\n\t\t// Find all extractable styles that have a value.\n\t\tfor ( const name of this._consumables.keys() ) {\n\t\t\tconst style = this.getNormalized( name, styles );\n\n\t\t\tif ( style && ( typeof style != 'object' || Object.keys( style ).length ) ) {\n\t\t\t\tstyleNamesKeysSet.add( name );\n\t\t\t}\n\t\t}\n\n\t\t// For simple styles (for example `color`) we don't have a map of those styles\n\t\t// but they are 1 to 1 with normalized object keys.\n\t\tfor ( const name of Object.keys( styles ) ) {\n\t\t\tstyleNamesKeysSet.add( name );\n\t\t}\n\n\t\treturn Array.from( styleNamesKeysSet );\n\t}\n\n\t/**\n\t * Returns related style names.\n\t *\n\t * ```ts\n\t * stylesProcessor.getRelatedStyles( 'margin' );\n\t * // will return: [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ];\n\t *\n\t * stylesProcessor.getRelatedStyles( 'margin-top' );\n\t * // will return: [ 'margin' ];\n\t * ```\n\t *\n\t * **Note**: To define new style relations load an existing style processor or use\n\t * {@link module:engine/view/stylesmap~StylesProcessor#setStyleRelation `StylesProcessor.setStyleRelation()`}.\n\t */\n\tpublic getRelatedStyles( name: string ): Array<string> {\n\t\treturn this._consumables.get( name ) || [];\n\t}\n\n\t/**\n\t * Adds a normalizer method for a style property.\n\t *\n\t * A normalizer returns describing how the value should be normalized.\n\t *\n\t * For instance 'margin' style is a shorthand for four margin values:\n\t *\n\t * - 'margin-top'\n\t * - 'margin-right'\n\t * - 'margin-bottom'\n\t * - 'margin-left'\n\t *\n\t * and can be written in various ways if some values are equal to others. For instance `'margin: 1px 2em;'` is a shorthand for\n\t * `'margin-top: 1px;margin-right: 2em;margin-bottom: 1px;margin-left: 2em'`.\n\t *\n\t * A normalizer should parse various margin notations as a single object:\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tmargin: {\n\t * \t\ttop: '1px',\n\t * \t\tright: '2em',\n\t * \t\tbottom: '1px',\n\t * \t\tleft: '2em'\n\t * \t}\n\t * };\n\t * ```\n\t *\n\t * Thus a normalizer for 'margin' style should return an object defining style path and value to store:\n\t *\n\t * ```ts\n\t * const returnValue = {\n\t * \tpath: 'margin',\n\t * \tvalue: {\n\t * \t\ttop: '1px',\n\t * \t\tright: '2em',\n\t * \t\tbottom: '1px',\n\t * \t\tleft: '2em'\n\t * \t}\n\t * };\n\t * ```\n\t *\n\t * Additionally to fully support all margin notations there should be also defined 4 normalizers for longhand margin notations. Below\n\t * is an example for 'margin-top' style property normalizer:\n\t *\n\t * ```ts\n\t * stylesProcessor.setNormalizer( 'margin-top', valueString => {\n\t * \treturn {\n\t * \t\tpath: 'margin.top',\n\t * \t\tvalue: valueString\n\t * \t}\n\t * } );\n\t * ```\n\t */\n\tpublic setNormalizer( name: string, callback: Normalizer ): void {\n\t\tthis._normalizers.set( name, callback );\n\t}\n\n\t/**\n\t * Adds a extractor callback for a style property.\n\t *\n\t * Most normalized style values are stored as one level objects. It is assumed that `'margin-top'` style will be stored as:\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tmargin: {\n\t * \t\ttop: 'value'\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * However, some styles can have conflicting notations and thus it might be harder to extract a style value from shorthand. For instance\n\t * the 'border-top-style' can be defined using `'border-top:solid'`, `'border-style:solid none none none'` or by `'border:solid'`\n\t * shorthands. The default border styles processors stores styles as:\n\t *\n\t * ```ts\n\t * const styles = {\n\t * \tborder: {\n\t * \t\tstyle: {\n\t * \t\t\ttop: 'solid'\n\t * \t\t}\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * as it is better to modify border style independently from other values. On the other part the output of the border might be\n\t * desired as `border-top`, `border-left`, etc notation.\n\t *\n\t * In the above example an extractor should return a side border value that combines style, color and width:\n\t *\n\t * ```ts\n\t * styleProcessor.setExtractor( 'border-top', styles => {\n\t * \treturn {\n\t * \t\tcolor: styles.border.color.top,\n\t * \t\tstyle: styles.border.style.top,\n\t * \t\twidth: styles.border.width.top\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * @param callbackOrPath Callback that return a requested value or path string for single values.\n\t */\n\tpublic setExtractor( name: string, callbackOrPath: Extractor ): void {\n\t\tthis._extractors.set( name, callbackOrPath );\n\t}\n\n\t/**\n\t * Adds a reducer callback for a style property.\n\t *\n\t * Reducer returns a minimal notation for given style name. For longhand properties it is not required to write a reducer as\n\t * by default the direct value from style path is taken.\n\t *\n\t * For shorthand styles a reducer should return minimal style notation either by returning single name-value tuple or multiple tuples\n\t * if a shorthand cannot be used. For instance for a margin shorthand a reducer might return:\n\t *\n\t * ```ts\n\t * const marginShortHandTuple = [\n\t * \t[ 'margin', '1px 1px 2px' ]\n\t * ];\n\t * ```\n\t *\n\t * or a longhand tuples for defined values:\n\t *\n\t * ```ts\n\t * // Considering margin.bottom and margin.left are undefined.\n\t * const marginLonghandsTuples = [\n\t * \t[ 'margin-top', '1px' ],\n\t * \t[ 'margin-right', '1px' ]\n\t * ];\n\t * ```\n\t *\n\t * A reducer obtains a normalized style value:\n\t *\n\t * ```ts\n\t * // Simplified reducer that always outputs 4 values which are always present:\n\t * stylesProcessor.setReducer( 'margin', margin => {\n\t * \treturn [\n\t * \t\t[ 'margin', `${ margin.top } ${ margin.right } ${ margin.bottom } ${ margin.left }` ]\n\t * \t]\n\t * } );\n\t * ```\n\t */\n\tpublic setReducer( name: string, callback: Reducer ): void {\n\t\tthis._reducers.set( name, callback );\n\t}\n\n\t/**\n\t * Defines a style shorthand relation to other style notations.\n\t *\n\t * ```ts\n\t * stylesProcessor.setStyleRelation( 'margin', [\n\t * \t'margin-top',\n\t * \t'margin-right',\n\t * \t'margin-bottom',\n\t * \t'margin-left'\n\t * ] );\n\t * ```\n\t *\n\t * This enables expanding of style names for shorthands. For instance, if defined,\n\t * {@link module:engine/conversion/viewconsumable~ViewConsumable view consumable} items are automatically created\n\t * for long-hand margin style notation alongside the `'margin'` item.\n\t *\n\t * This means that when an element being converted has a style `margin`, a converter for `margin-left` will work just\n\t * fine since the view consumable will contain a consumable `margin-left` item (thanks to the relation) and\n\t * `element.getStyle( 'margin-left' )` will work as well assuming that the style processor was correctly configured.\n\t * However, once `margin-left` is consumed, `margin` will not be consumable anymore.\n\t */\n\tpublic setStyleRelation( shorthandName: string, styleNames: Array<string> ): void {\n\t\tthis._mapStyleNames( shorthandName, styleNames );\n\n\t\tfor ( const alsoName of styleNames ) {\n\t\t\tthis._mapStyleNames( alsoName, [ shorthandName ] );\n\t\t}\n\t}\n\n\t/**\n\t * Set two-way binding of style names.\n\t */\n\tprivate _mapStyleNames( name: string, styleNames: Array<string> ) {\n\t\tif ( !this._consumables.has( name ) ) {\n\t\t\tthis._consumables.set( name, [] );\n\t\t}\n\n\t\tthis._consumables.get( name )!.push( ...styleNames );\n\t}\n}\n\n/**\n * Parses inline styles and puts property - value pairs into styles map.\n *\n * @param stylesString Styles to parse.\n * @returns Map of parsed properties and values.\n */\nfunction parseInlineStyles( stylesString: string ): Map<string, string> {\n\t// `null` if no quote was found in input string or last found quote was a closing quote. See below.\n\tlet quoteType = null;\n\tlet propertyNameStart = 0;\n\tlet propertyValueStart = 0;\n\tlet propertyName = null;\n\n\tconst stylesMap = new Map();\n\n\t// Do not set anything if input string is empty.\n\tif ( stylesString === '' ) {\n\t\treturn stylesMap;\n\t}\n\n\t// Fix inline styles that do not end with `;` so they are compatible with algorithm below.\n\tif ( stylesString.charAt( stylesString.length - 1 ) != ';' ) {\n\t\tstylesString = stylesString + ';';\n\t}\n\n\t// Seek the whole string for \"special characters\".\n\tfor ( let i = 0; i < stylesString.length; i++ ) {\n\t\tconst char = stylesString.charAt( i );\n\n\t\tif ( quoteType === null ) {\n\t\t\t// No quote found yet or last found quote was a closing quote.\n\t\t\tswitch ( char ) {\n\t\t\t\tcase ':':\n\t\t\t\t\t// Most of time colon means that property name just ended.\n\t\t\t\t\t// Sometimes however `:` is found inside property value (for example in background image url).\n\t\t\t\t\tif ( !propertyName ) {\n\t\t\t\t\t\t// Treat this as end of property only if property name is not already saved.\n\t\t\t\t\t\t// Save property name.\n\t\t\t\t\t\tpropertyName = stylesString.substr( propertyNameStart, i - propertyNameStart );\n\t\t\t\t\t\t// Save this point as the start of property value.\n\t\t\t\t\t\tpropertyValueStart = i + 1;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase '\"':\n\t\t\t\tcase '\\'':\n\t\t\t\t\t// Opening quote found (this is an opening quote, because `quoteType` is `null`).\n\t\t\t\t\tquoteType = char;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase ';': {\n\t\t\t\t\t// Property value just ended.\n\t\t\t\t\t// Use previously stored property value start to obtain property value.\n\t\t\t\t\tconst propertyValue = stylesString.substr( propertyValueStart, i - propertyValueStart );\n\n\t\t\t\t\tif ( propertyName ) {\n\t\t\t\t\t\t// Save parsed part.\n\t\t\t\t\t\tstylesMap.set( propertyName.trim(), propertyValue.trim() );\n\t\t\t\t\t}\n\n\t\t\t\t\tpropertyName = null;\n\n\t\t\t\t\t// Save this point as property name start. Property name starts immediately after previous property value ends.\n\t\t\t\t\tpropertyNameStart = i + 1;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( char === quoteType ) {\n\t\t\t// If a quote char is found and it is a closing quote, mark this fact by `null`-ing `quoteType`.\n\t\t\tquoteType = null;\n\t\t}\n\t}\n\n\treturn stylesMap;\n}\n\n/**\n * Return lodash compatible path from style name.\n */\nfunction toPath( name: string ): string {\n\treturn name.replace( '-', '.' );\n}\n\n/**\n * Appends style definition to the styles object.\n */\nfunction appendStyleValue( stylesObject: Styles, nameOrPath: string, valueOrObject: StyleValue ) {\n\tlet valueToSet = valueOrObject;\n\n\tif ( isObject( valueOrObject ) ) {\n\t\tvalueToSet = merge( {}, get( stylesObject, nameOrPath ), valueOrObject );\n\t}\n\n\tset( stylesObject, nameOrPath, valueToSet );\n}\n\n/**\n * A CSS style property descriptor that contains tuple of two strings:\n *\n * - first string describes property name\n * - second string describes property value\n *\n * ```ts\n * const marginDescriptor = [ 'margin', '2px 3em' ];\n * const marginTopDescriptor = [ 'margin-top', '2px' ];\n * ```\n */\nexport type PropertyDescriptor = [ name: string, value: string ];\n\n/**\n * An object describing values associated with the sides of a box, for instance margins, paddings,\n * border widths, border colors, etc.\n *\n * ```ts\n * const margin = {\n * \ttop: '1px',\n * \tright: '3px',\n * \tbottom: '3px',\n * \tleft: '7px'\n * };\n *\n * const borderColor = {\n * \ttop: 'red',\n * \tright: 'blue',\n * \tbottom: 'blue',\n * \tleft: 'red'\n * };\n * ```\n */\nexport type BoxSides = {\n\n\t/**\n\t * Top side value.\n\t */\n\ttop: undefined | string;\n\n\t/**\n\t * Left side value.\n\t */\n\tleft: undefined | string;\n\n\t/**\n\t * Right side value.\n\t */\n\tright: undefined | string;\n\n\t/**\n\t * Bottom side value.\n\t */\n\tbottom: undefined | string;\n};\n\n/**\n * Object holding styles as key-value pairs.\n */\nexport interface Styles {\n\t[ name: string ]: StyleValue;\n}\n\n/**\n * The value of style.\n */\nexport type StyleValue = string | Array<string> | Styles | BoxSides;\n\n/**\n * A normalizer method for a style property.\n *\n * @see ~StylesProcessor#setNormalizer\n */\nexport type Normalizer = ( name: string ) => { path: string; value: StyleValue };\n\n/**\n * An extractor callback for a style property or path string for single values.\n *\n * @see ~StylesProcessor#setExtractor\n */\nexport type Extractor = string | ( ( name: string, styles: Styles ) => StyleValue | undefined );\n\n/**\n * A reducer callback for a style property.\n *\n * @see ~StylesProcessor#setReducer\n */\nexport type Reducer = ( value: StyleValue ) => Array<PropertyDescriptor>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/element\n */\n\nimport Node from './node.js';\nimport Text from './text.js';\nimport TextProxy from './textproxy.js';\nimport { isIterable, toArray, toMap, type ArrayOrItem } from '@ckeditor/ckeditor5-utils';\nimport { default as Matcher, type MatcherPattern } from './matcher.js';\nimport { default as StylesMap, type StyleValue } from './stylesmap.js';\n\nimport type Document from './document.js';\nimport type Item from './item.js';\n\n// @if CK_DEBUG_ENGINE // const { convertMapToTags } = require( '../dev-utils/utils' );\n\n/**\n * View element.\n *\n * The editing engine does not define a fixed semantics of its elements (it is \"DTD-free\").\n * This is why the type of the {@link module:engine/view/element~Element} need to\n * be defined by the feature developer. When creating an element you should use one of the following methods:\n *\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `downcastWriter#createContainerElement()`}\n * in order to create a {@link module:engine/view/containerelement~ContainerElement},\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `downcastWriter#createAttributeElement()`}\n * in order to create a {@link module:engine/view/attributeelement~AttributeElement},\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`}\n * in order to create a {@link module:engine/view/emptyelement~EmptyElement}.\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}\n * in order to create a {@link module:engine/view/uielement~UIElement}.\n * * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`}\n * in order to create a {@link module:engine/view/editableelement~EditableElement}.\n *\n * Note that for view elements which are not created from the model, like elements from mutations, paste or\n * {@link module:engine/controller/datacontroller~DataController#set data.set} it is not possible to define the type of the element.\n * In such cases the {@link module:engine/view/upcastwriter~UpcastWriter#createElement `UpcastWriter#createElement()`} method\n * should be used to create generic view elements.\n */\nexport default class Element extends Node {\n\t/**\n\t * Name of the element.\n\t */\n\tpublic readonly name: string;\n\n\t/**\n\t * A list of attribute names that should be rendered in the editing pipeline even though filtering mechanisms\n\t * implemented in the {@link module:engine/view/domconverter~DomConverter} (for instance,\n\t * {@link module:engine/view/domconverter~DomConverter#shouldRenderAttribute}) would filter them out.\n\t *\n\t * These attributes can be specified as an option when the element is created by\n\t * the {@link module:engine/view/downcastwriter~DowncastWriter}. To check whether an unsafe an attribute should\n\t * be permitted, use the {@link #shouldRenderUnsafeAttribute} method.\n\t *\n\t * @internal\n\t */\n\tpublic readonly _unsafeAttributesToRender: Array<string> = [];\n\n\t/**\n\t * Map of attributes, where attributes names are keys and attributes values are values.\n\t */\n\tprivate readonly _attrs: Map<string, string>;\n\n\t/**\n\t * Array of child nodes.\n\t */\n\tprivate readonly _children: Array<Node>;\n\n\t/**\n\t * Set of classes associated with element instance.\n\t */\n\tprivate readonly _classes: Set<string>;\n\n\t/**\n\t * Normalized styles.\n\t */\n\tprivate readonly _styles: StylesMap;\n\n\t/**\n\t * Map of custom properties.\n\t * Custom properties can be added to element instance, will be cloned but not rendered into DOM.\n\t */\n\tprivate readonly _customProperties = new Map<string | symbol, unknown>();\n\n\t/**\n\t * Creates a view element.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t * ```ts\n\t * new Element( viewDocument, 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t * new Element( viewDocument, 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t * new Element( viewDocument, 'div', mapOfAttributes ); // map\n\t * ```\n\t *\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string,\n\t\tattrs?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t) {\n\t\tsuper( document );\n\n\t\tthis.name = name;\n\n\t\tthis._attrs = parseAttributes( attrs );\n\t\tthis._children = [];\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\n\t\tthis._classes = new Set();\n\n\t\tif ( this._attrs.has( 'class' ) ) {\n\t\t\t// Remove class attribute and handle it by class set.\n\t\t\tconst classString = this._attrs.get( 'class' );\n\t\t\tparseClasses( this._classes, classString! );\n\t\t\tthis._attrs.delete( 'class' );\n\t\t}\n\n\t\tthis._styles = new StylesMap( this.document.stylesProcessor );\n\n\t\tif ( this._attrs.has( 'style' ) ) {\n\t\t\t// Remove style attribute and handle it by styles map.\n\t\t\tthis._styles.setTo( this._attrs.get( 'style' )! );\n\n\t\t\tthis._attrs.delete( 'style' );\n\t\t}\n\t}\n\n\t/**\n\t * Number of element's children.\n\t */\n\tpublic get childCount(): number {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t */\n\tpublic get isEmpty(): boolean {\n\t\treturn this._children.length === 0;\n\t}\n\n\t/**\n\t * Gets child at the given index.\n\t *\n\t * @param index Index of child.\n\t * @returns Child node.\n\t */\n\tpublic getChild( index: number ): Node | undefined {\n\t\treturn this._children[ index ];\n\t}\n\n\t/**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param node Child node.\n\t * @returns Index of the child node.\n\t */\n\tpublic getChildIndex( node: Node ): number {\n\t\treturn this._children.indexOf( node );\n\t}\n\n\t/**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns Child nodes iterator.\n\t */\n\tpublic getChildren(): IterableIterator<Node> {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns an iterator that contains the keys for attributes. Order of inserting attributes is not preserved.\n\t *\n\t * @returns Keys for attributes.\n\t */\n\tpublic* getAttributeKeys(): IterableIterator<string> {\n\t\tif ( this._classes.size > 0 ) {\n\t\t\tyield 'class';\n\t\t}\n\n\t\tif ( !this._styles.isEmpty ) {\n\t\t\tyield 'style';\n\t\t}\n\n\t\tyield* this._attrs.keys();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this element's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */\n\tpublic* getAttributes(): IterableIterator<[ string, string ]> {\n\t\tyield* this._attrs.entries();\n\n\t\tif ( this._classes.size > 0 ) {\n\t\t\tyield [ 'class', this.getAttribute( 'class' )! ];\n\t\t}\n\n\t\tif ( !this._styles.isEmpty ) {\n\t\t\tyield [ 'style', this.getAttribute( 'style' )! ];\n\t\t}\n\t}\n\n\t/**\n\t * Gets attribute by key. If attribute is not present - returns undefined.\n\t *\n\t * @param key Attribute key.\n\t * @returns Attribute value.\n\t */\n\tpublic getAttribute( key: string ): string | undefined {\n\t\tif ( key == 'class' ) {\n\t\t\tif ( this._classes.size > 0 ) {\n\t\t\t\treturn [ ...this._classes ].join( ' ' );\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( key == 'style' ) {\n\t\t\tconst inlineStyle = this._styles.toString();\n\n\t\t\treturn inlineStyle == '' ? undefined : inlineStyle;\n\t\t}\n\n\t\treturn this._attrs.get( key );\n\t}\n\n\t/**\n\t * Returns a boolean indicating whether an attribute with the specified key exists in the element.\n\t *\n\t * @param key Attribute key.\n\t * @returns `true` if attribute with the specified key exists in the element, `false` otherwise.\n\t */\n\tpublic hasAttribute( key: string ): boolean {\n\t\tif ( key == 'class' ) {\n\t\t\treturn this._classes.size > 0;\n\t\t}\n\n\t\tif ( key == 'style' ) {\n\t\t\treturn !this._styles.isEmpty;\n\t\t}\n\n\t\treturn this._attrs.has( key );\n\t}\n\n\t/**\n\t * Checks if this element is similar to other element.\n\t * Both elements should have the same name and attributes to be considered as similar. Two similar elements\n\t * can contain different set of children nodes.\n\t */\n\tpublic isSimilar( otherElement: Item ): boolean {\n\t\tif ( !( otherElement instanceof Element ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If exactly the same Element is provided - return true immediately.\n\t\tif ( this === otherElement ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check element name.\n\t\tif ( this.name != otherElement.name ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check number of attributes, classes and styles.\n\t\tif ( this._attrs.size !== otherElement._attrs.size || this._classes.size !== otherElement._classes.size ||\n\t\t\tthis._styles.size !== otherElement._styles.size ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if attributes are the same.\n\t\tfor ( const [ key, value ] of this._attrs ) {\n\t\t\tif ( !otherElement._attrs.has( key ) || otherElement._attrs.get( key ) !== value ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if classes are the same.\n\t\tfor ( const className of this._classes ) {\n\t\t\tif ( !otherElement._classes.has( className ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if styles are the same.\n\t\tfor ( const property of this._styles.getStyleNames() ) {\n\t\t\tif (\n\t\t\t\t!otherElement._styles.has( property ) ||\n\t\t\t\totherElement._styles.getAsString( property ) !== this._styles.getAsString( property )\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns true if class is present.\n\t * If more then one class is provided - returns true only when all classes are present.\n\t *\n\t * ```ts\n\t * element.hasClass( 'foo' ); // Returns true if 'foo' class is present.\n\t * element.hasClass( 'foo', 'bar' ); // Returns true if 'foo' and 'bar' classes are both present.\n\t * ```\n\t */\n\tpublic hasClass( ...className: Array<string> ): boolean {\n\t\tfor ( const name of className ) {\n\t\t\tif ( !this._classes.has( name ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns iterator that contains all class names.\n\t */\n\tpublic getClassNames(): Iterable<string> {\n\t\treturn this._classes.keys();\n\t}\n\n\t/**\n\t * Returns style value for the given property mae.\n\t * If the style does not exist `undefined` is returned.\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#getAsString `StylesMap#getAsString()`} for details.\n\t *\n\t * For an element with style set to `'margin:1px'`:\n\t *\n\t * ```ts\n\t * // Enable 'margin' shorthand processing:\n\t * editor.data.addStyleProcessorRules( addMarginRules );\n\t *\n\t * const element = view.change( writer => {\n\t * \tconst element = writer.createElement();\n\t * \twriter.setStyle( 'margin', '1px' );\n\t * \twriter.setStyle( 'margin-bottom', '3em' );\n\t *\n\t * \treturn element;\n\t * } );\n\t *\n\t * element.getStyle( 'margin' ); // -> 'margin: 1px 1px 3em;'\n\t * ```\n\t */\n\tpublic getStyle( property: string ): string | undefined {\n\t\treturn this._styles.getAsString( property );\n\t}\n\n\t/**\n\t * Returns a normalized style object or single style value.\n\t *\n\t * For an element with style set to: margin:1px 2px 3em;\n\t *\n\t * ```ts\n\t * element.getNormalizedStyle( 'margin' ) );\n\t * ```\n\t *\n\t * will return:\n\t *\n\t * ```ts\n\t * {\n\t * \ttop: '1px',\n\t * \tright: '2px',\n\t * \tbottom: '3em',\n\t * \tleft: '2px'    // a normalized value from margin shorthand\n\t * }\n\t * ```\n\t *\n\t * and reading for single style value:\n\t *\n\t * ```ts\n\t * styles.getNormalizedStyle( 'margin-left' );\n\t * ```\n\t *\n\t * Will return a `2px` string.\n\t *\n\t * **Note**: This method will return normalized values only if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#getNormalized `StylesMap#getNormalized()`} for details.\n\t *\n\t * @param property Name of CSS property\n\t */\n\tpublic getNormalizedStyle( property: string ): StyleValue {\n\t\treturn this._styles.getNormalized( property );\n\t}\n\n\t/**\n\t * Returns iterator that contains all style names.\n\t *\n\t * @param expand Expand shorthand style properties and return all equivalent style representations.\n\t */\n\tpublic getStyleNames( expand?: boolean ): Iterable<string> {\n\t\treturn this._styles.getStyleNames( expand );\n\t}\n\n\t/**\n\t * Returns true if style keys are present.\n\t * If more then one style property is provided - returns true only when all properties are present.\n\t *\n\t * ```ts\n\t * element.hasStyle( 'color' ); // Returns true if 'border-top' style is present.\n\t * element.hasStyle( 'color', 'border-top' ); // Returns true if 'color' and 'border-top' styles are both present.\n\t * ```\n\t */\n\tpublic hasStyle( ...property: Array<string> ): boolean {\n\t\tfor ( const name of property ) {\n\t\t\tif ( !this._styles.has( name ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns ancestor element that match specified pattern.\n\t * Provided patterns should be compatible with {@link module:engine/view/matcher~Matcher Matcher} as it is used internally.\n\t *\n\t * @see module:engine/view/matcher~Matcher\n\t * @param patterns Patterns used to match correct ancestor. See {@link module:engine/view/matcher~Matcher}.\n\t * @returns Found element or `null` if no matching ancestor was found.\n\t */\n\tpublic findAncestor( ...patterns: Array<MatcherPattern | ( ( element: Element ) => boolean )> ): Element | null {\n\t\tconst matcher = new Matcher( ...patterns as any );\n\t\tlet parent = this.parent;\n\n\t\twhile ( parent && !parent.is( 'documentFragment' ) ) {\n\t\t\tif ( matcher.match( parent ) ) {\n\t\t\t\treturn parent;\n\t\t\t}\n\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns the custom property value for the given key.\n\t */\n\tpublic getCustomProperty( key: string | symbol ): unknown {\n\t\treturn this._customProperties.get( key );\n\t}\n\n\t/**\n\t * Returns an iterator which iterates over this element's custom properties.\n\t * Iterator provides `[ key, value ]` pairs for each stored property.\n\t */\n\tpublic* getCustomProperties(): IterableIterator<[ string | symbol, unknown ]> {\n\t\tyield* this._customProperties.entries();\n\t}\n\n\t/**\n\t * Returns identity string based on element's name, styles, classes and other attributes.\n\t * Two elements that {@link #isSimilar are similar} will have same identity string.\n\t * It has the following format:\n\t *\n\t * ```ts\n\t * 'name class=\"class1,class2\" style=\"style1:value1;style2:value2\" attr1=\"val1\" attr2=\"val2\"'\n\t * ```\n \t *\n\t * For example:\n\t *\n\t * ```ts\n\t * const element = writer.createContainerElement( 'foo', {\n\t * \tbanana: '10',\n\t * \tapple: '20',\n\t * \tstyle: 'color: red; border-color: white;',\n\t * \tclass: 'baz'\n\t * } );\n\t *\n\t * // returns 'foo class=\"baz\" style=\"border-color:white;color:red\" apple=\"20\" banana=\"10\"'\n\t * element.getIdentity();\n\t * ```\n\t *\n\t * **Note**: Classes, styles and other attributes are sorted alphabetically.\n\t */\n\tpublic getIdentity(): string {\n\t\tconst classes = Array.from( this._classes ).sort().join( ',' );\n\t\tconst styles = this._styles.toString();\n\t\tconst attributes = Array.from( this._attrs ).map( i => `${ i[ 0 ] }=\"${ i[ 1 ] }\"` ).sort().join( ' ' );\n\n\t\treturn this.name +\n\t\t\t( classes == '' ? '' : ` class=\"${ classes }\"` ) +\n\t\t\t( !styles ? '' : ` style=\"${ styles }\"` ) +\n\t\t\t( attributes == '' ? '' : ` ${ attributes }` );\n\t}\n\n\t/**\n\t * Decides whether an unsafe attribute is whitelisted and should be rendered in the editing pipeline even though filtering mechanisms\n\t * like {@link module:engine/view/domconverter~DomConverter#shouldRenderAttribute} say it should not.\n\t *\n\t * Unsafe attribute names can be specified when creating an element via {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t *\n\t * @param attributeName The name of the attribute to be checked.\n\t */\n\tpublic shouldRenderUnsafeAttribute( attributeName: string ): boolean {\n\t\treturn this._unsafeAttributesToRender.includes( attributeName );\n\t}\n\n\t/**\n\t * Clones provided element.\n\t *\n\t * @internal\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns Clone of this element.\n\t */\n\tpublic _clone( deep = false ): this {\n\t\tconst childrenClone: Array<Node> = [];\n\n\t\tif ( deep ) {\n\t\t\tfor ( const child of this.getChildren() ) {\n\t\t\t\tchildrenClone.push( child._clone( deep ) );\n\t\t\t}\n\t\t}\n\n\t\t// ContainerElement and AttributeElement should be also cloned properly.\n\t\tconst cloned = new ( this.constructor as any )( this.document, this.name, this._attrs, childrenClone );\n\n\t\t// Classes and styles are cloned separately - this solution is faster than adding them back to attributes and\n\t\t// parse once again in constructor.\n\t\tcloned._classes = new Set( this._classes );\n\t\tcloned._styles.set( this._styles.getNormalized() );\n\n\t\t// Clone custom properties.\n\t\tcloned._customProperties = new Map( this._customProperties );\n\n\t\t// Clone filler offset method.\n\t\t// We can't define this method in a prototype because it's behavior which\n\t\t// is changed by e.g. toWidget() function from ckeditor5-widget. Perhaps this should be one of custom props.\n\t\tcloned.getFillerOffset = this.getFillerOffset;\n\n\t\t// Clone unsafe attributes list.\n\t\tcloned._unsafeAttributesToRender = this._unsafeAttributesToRender;\n\n\t\treturn cloned;\n\t}\n\n\t/**\n\t * {@link module:engine/view/element~Element#_insertChild Insert} a child node or a list of child nodes at the end of this node\n\t * and sets the parent of these nodes to this element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#insert\n\t * @internal\n\t * @param items Items to be inserted.\n\t * @fires change\n\t * @returns Number of appended nodes.\n\t */\n\tpublic _appendChild( items: Item | string | Iterable<Item | string> ): number {\n\t\treturn this._insertChild( this.childCount, items );\n\t}\n\n\t/**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this element.\n\t *\n\t * @internal\n\t * @see module:engine/view/downcastwriter~DowncastWriter#insert\n\t * @param index Position where nodes should be inserted.\n\t * @param items Items to be inserted.\n\t * @fires change\n\t * @returns Number of inserted nodes.\n\t */\n\tpublic _insertChild( index: number, items: Item | string | Iterable<Item | string> ): number {\n\t\tthis._fireChange( 'children', this );\n\t\tlet count = 0;\n\n\t\tconst nodes = normalize( this.document, items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\t( node as any ).parent = this;\n\t\t\t( node as any ).document = this.document;\n\n\t\t\tthis._children.splice( index, 0, node );\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\n\t\treturn count;\n\t}\n\n\t/**\n\t * Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#remove\n\t * @internal\n\t * @param index Number of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @fires change\n\t * @returns The array of removed nodes.\n\t */\n\tpublic _removeChildren( index: number, howMany: number = 1 ): Array<Node> {\n\t\tthis._fireChange( 'children', this );\n\n\t\tfor ( let i = index; i < index + howMany; i++ ) {\n\t\t\t( this._children[ i ] as any ).parent = null;\n\t\t}\n\n\t\treturn this._children.splice( index, howMany );\n\t}\n\n\t/**\n\t * Adds or overwrite attribute with a specified key and value.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setAttribute\n\t * @internal\n\t * @param key Attribute key.\n\t * @param value Attribute value.\n\t * @fires change\n\t */\n\tpublic _setAttribute( key: string, value: unknown ): void {\n\t\tconst stringValue = String( value );\n\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tif ( key == 'class' ) {\n\t\t\tparseClasses( this._classes, stringValue );\n\t\t} else if ( key == 'style' ) {\n\t\t\tthis._styles.setTo( stringValue );\n\t\t} else {\n\t\t\tthis._attrs.set( key, stringValue );\n\t\t}\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeAttribute\n\t * @internal\n\t * @param key Attribute key.\n\t * @returns Returns true if an attribute existed and has been removed.\n\t * @fires change\n\t */\n\tpublic _removeAttribute( key: string ): boolean {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\t// Remove class attribute.\n\t\tif ( key == 'class' ) {\n\t\t\tif ( this._classes.size > 0 ) {\n\t\t\t\tthis._classes.clear();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// Remove style attribute.\n\t\tif ( key == 'style' ) {\n\t\t\tif ( !this._styles.isEmpty ) {\n\t\t\t\tthis._styles.clear();\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// Remove other attributes.\n\t\treturn this._attrs.delete( key );\n\t}\n\n\t/**\n\t * Adds specified class.\n\t *\n\t * ```ts\n\t * element._addClass( 'foo' ); // Adds 'foo' class.\n\t * element._addClass( [ 'foo', 'bar' ] ); // Adds 'foo' and 'bar' classes.\n\t * ```\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#addClass\n\t * @internal\n\t * @fires change\n\t */\n\tpublic _addClass( className: ArrayOrItem<string> ): void {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tfor ( const name of toArray( className ) ) {\n\t\t\tthis._classes.add( name );\n\t\t}\n\t}\n\n\t/**\n\t * Removes specified class.\n\t *\n\t * ```ts\n\t * element._removeClass( 'foo' );  // Removes 'foo' class.\n\t * element._removeClass( [ 'foo', 'bar' ] ); // Removes both 'foo' and 'bar' classes.\n\t * ```\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeClass\n\t * @internal\n\t * @fires change\n\t */\n\tpublic _removeClass( className: ArrayOrItem<string> ): void {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tfor ( const name of toArray( className ) ) {\n\t\t\tthis._classes.delete( name );\n\t\t}\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t * ```ts\n\t * element._setStyle( 'color', 'red' );\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setStyle\n\t * @label KEY_VALUE\n\t * @internal\n\t * @param property Property name.\n\t * @param value Value to set.\n\t * @fires change\n\t */\n\tpublic _setStyle( property: string, value: string ): void;\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t * ```ts\n\t * element._setStyle( {\n\t * \tcolor: 'red',\n\t * \tposition: 'fixed'\n\t * } );\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setStyle\n\t * @label OBJECT\n\t * @internal\n\t * @param properties Object with key - value pairs.\n\t * @fires change\n\t */\n\tpublic _setStyle( properties: Record<string, string> ): void;\n\n\tpublic _setStyle( property: string | Record<string, string>, value?: string ): void {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tif ( typeof property != 'string' ) {\n\t\t\tthis._styles.set( property );\n\t\t} else {\n\t\t\tthis._styles.set( property, value! );\n\t\t}\n\t}\n\n\t/**\n\t * Removes specified style.\n\t *\n\t * ```ts\n\t * element._removeStyle( 'color' );  // Removes 'color' style.\n\t * element._removeStyle( [ 'color', 'border-top' ] ); // Removes both 'color' and 'border-top' styles.\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeStyle\n\t * @internal\n\t * @fires change\n\t */\n\tpublic _removeStyle( property: ArrayOrItem<string> ): void {\n\t\tthis._fireChange( 'attributes', this );\n\n\t\tfor ( const name of toArray( property ) ) {\n\t\t\tthis._styles.remove( name );\n\t\t}\n\t}\n\n\t/**\n\t * Sets a custom property. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setCustomProperty\n\t * @internal\n\t */\n\tpublic _setCustomProperty( key: string | symbol, value: unknown ): void {\n\t\tthis._customProperties.set( key, value );\n\t}\n\n\t/**\n\t * Removes the custom property stored under the given key.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeCustomProperty\n\t * @internal\n\t * @returns Returns true if property was removed.\n\t */\n\tpublic _removeCustomProperty( key: string | symbol ): boolean {\n\t\treturn this._customProperties.delete( key );\n\t}\n\n\t/**\n\t * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n\t */\n\tpublic getFillerOffset?(): number | null;\n\n\t// @if CK_DEBUG_ENGINE // public printTree( level = 0 ): string {\n\t// @if CK_DEBUG_ENGINE // \tlet string = '';\n\n\t// @if CK_DEBUG_ENGINE // \tstring += '\\t'.repeat( level ) + `<${ this.name }${ convertMapToTags( this.getAttributes() ) }>`;\n\n\t// @if CK_DEBUG_ENGINE // \tfor ( const child of this.getChildren() as any ) {\n\t// @if CK_DEBUG_ENGINE // \t\tif ( child.is( '$text' ) ) {\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += '\\n' + '\\t'.repeat( level + 1 ) + child.data;\n\t// @if CK_DEBUG_ENGINE // \t\t} else {\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += '\\n' + child.printTree( level + 1 );\n\t// @if CK_DEBUG_ENGINE // \t\t}\n\t// @if CK_DEBUG_ENGINE // \t}\n\n\t// @if CK_DEBUG_ENGINE // \tif ( this.childCount ) {\n\t// @if CK_DEBUG_ENGINE // \t\tstring += '\\n' + '\\t'.repeat( level );\n\t// @if CK_DEBUG_ENGINE // \t}\n\n\t// @if CK_DEBUG_ENGINE // \tstring += `</${ this.name }>`;\n\n\t// @if CK_DEBUG_ENGINE // \treturn string;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logTree(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( this.printTree() );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'element' || type === 'view:element' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && ( type === 'element' || type === 'view:element' );\n\t}\n};\n\n/**\n * Collection of attributes.\n */\nexport type ElementAttributes = Record<string, unknown> | Iterable<[ string, unknown ]> | null;\n\n/**\n * Parses attributes provided to the element constructor before they are applied to an element. If attributes are passed\n * as an object (instead of `Iterable`), the object is transformed to the map. Attributes with `null` value are removed.\n * Attributes with non-`String` value are converted to `String`.\n *\n * @param attrs Attributes to parse.\n * @returns Parsed attributes.\n */\nfunction parseAttributes( attrs?: ElementAttributes ) {\n\tconst attrsMap = toMap( attrs );\n\n\tfor ( const [ key, value ] of attrsMap ) {\n\t\tif ( value === null ) {\n\t\t\tattrsMap.delete( key );\n\t\t} else if ( typeof value != 'string' ) {\n\t\t\tattrsMap.set( key, String( value ) );\n\t\t}\n\t}\n\n\treturn attrsMap as Map<string, string>;\n}\n\n/**\n * Parses class attribute and puts all classes into classes set.\n * Classes set s cleared before insertion.\n *\n * @param classesSet Set to insert parsed classes.\n * @param classesString String with classes to parse.\n */\nfunction parseClasses( classesSet: Set<string>, classesString: string ) {\n\tconst classArray = classesString.split( /\\s+/ );\n\tclassesSet.clear();\n\tclassArray.forEach( name => classesSet.add( name ) );\n}\n\n/**\n * Converts strings to Text and non-iterables to arrays.\n */\nfunction normalize( document: Document, nodes: string | Item | Iterable<string | Item> ): Array<Node> {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( document, nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( document, node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( document, node.data );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/containerelement\n */\n\nimport Element, { type ElementAttributes } from './element.js';\nimport type Document from './document.js';\nimport type Node from './node.js';\n\n/**\n * Containers are elements which define document structure. They define boundaries for\n * {@link module:engine/view/attributeelement~AttributeElement attributes}. They are mostly used for block elements like `<p>` or `<div>`.\n *\n * Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n * types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.\n *\n * The container element should be your default choice when writing a converter, unless:\n *\n * * this element represents a model text attribute (then use {@link module:engine/view/attributeelement~AttributeElement}),\n * * this is an empty element like `<img>` (then use {@link module:engine/view/emptyelement~EmptyElement}),\n * * this is a root element,\n * * this is a nested editable element (then use  {@link module:engine/view/editableelement~EditableElement}).\n *\n * To create a new container element instance use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement `DowncastWriter#createContainerElement()`}\n * method.\n */\nexport default class ContainerElement extends Element {\n\t/**\n\t * Creates a container element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createContainerElement\n\t * @see module:engine/view/element~Element\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string,\n\t\tattrs?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t) {\n\t\tsuper( document, name, attrs, children );\n\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nContainerElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'containerElement' || type === 'view:containerElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && (\n\t\t\ttype === 'containerElement' || type === 'view:containerElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'element' || type === 'view:element'\n\t\t);\n\t}\n};\n\n/**\n * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.\n *\n * @returns Block filler offset or `null` if block filler is not needed.\n */\nexport function getFillerOffset( this: ContainerElement ): number | null {\n\tconst children = [ ...this.getChildren() ];\n\tconst lastChild = children[ this.childCount - 1 ];\n\n\t// Block filler is required after a `<br>` if it's the last element in its container. See #1422.\n\tif ( lastChild && lastChild.is( 'element', 'br' ) ) {\n\t\treturn this.childCount;\n\t}\n\n\tfor ( const child of children ) {\n\t\t// If there's any non-UI element – don't render the bogus.\n\t\tif ( !child.is( 'uiElement' ) ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// If there are only UI elements – render the bogus at the end of the element.\n\treturn this.childCount;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/editableelement\n */\n\nimport ContainerElement from './containerelement.js';\nimport { ObservableMixin } from '@ckeditor/ckeditor5-utils';\nimport type { ViewSelectionChangeEvent } from './selection.js';\nimport type { ElementAttributes } from './element.js';\nimport type Document from './document.js';\nimport type Node from './node.js';\n\n/**\n * Editable element which can be a {@link module:engine/view/rooteditableelement~RootEditableElement root}\n * or nested editable area in the editor.\n *\n * Editable is automatically read-only when its {@link module:engine/view/document~Document Document} is read-only.\n *\n * The constructor of this class shouldn't be used directly. To create new `EditableElement` use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement `downcastWriter#createEditableElement()`} method.\n */\nexport default class EditableElement extends /* #__PURE__ */ ObservableMixin( ContainerElement ) {\n\t/**\n\t * Whether the editable is in read-write or read-only mode.\n\t *\n\t * @observable\n\t */\n\tdeclare public isReadOnly: boolean;\n\n\t/**\n\t * Whether the editable is focused.\n\t *\n\t * This property updates when {@link module:engine/view/document~Document#isFocused document.isFocused} or view\n\t * selection is changed.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isFocused: boolean;\n\n\t/**\n\t * Placeholder of editable element.\n\t *\n\t * ```ts\n\t * editor.editing.view.document.getRoot( 'main' ).placeholder = 'New placeholder';\n\t * ```\n\t *\n\t * @observable\n\t */\n\tdeclare public placeholder?: string;\n\n\t/**\n\t * Creates an editable element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createEditableElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t) {\n\t\tsuper( document, name, attributes, children );\n\n\t\tthis.set( 'isReadOnly', false );\n\t\tthis.set( 'isFocused', false );\n\t\tthis.set( 'placeholder', undefined );\n\n\t\tthis.bind( 'isReadOnly' ).to( document );\n\n\t\tthis.bind( 'isFocused' ).to(\n\t\t\tdocument,\n\t\t\t'isFocused',\n\t\t\tisFocused => isFocused && document.selection.editableElement == this\n\t\t);\n\n\t\t// Update focus state based on selection changes.\n\t\tthis.listenTo<ViewSelectionChangeEvent>( document.selection, 'change', () => {\n\t\t\tthis.isFocused = document.isFocused && document.selection.editableElement == this;\n\t\t} );\n\t}\n\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nEditableElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'editableElement' || type === 'view:editableElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'containerElement' || type === 'view:containerElement' ||\n\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && (\n\t\t\ttype === 'editableElement' || type === 'view:editableElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'containerElement' || type === 'view:containerElement' ||\n\t\t\ttype === 'element' || type === 'view:element'\n\t\t);\n\t}\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/rooteditableelement\n */\n\nimport EditableElement from './editableelement.js';\n\nimport type Document from './document.js';\n\nconst rootNameSymbol = Symbol( 'rootName' );\n\n/**\n * Class representing a single root in the data view. A root can be either {@link ~RootEditableElement#isReadOnly editable or read-only},\n * but in both cases it is called \"an editable\". Roots can contain other {@link module:engine/view/editableelement~EditableElement\n * editable elements} making them \"nested editables\".\n */\nexport default class RootEditableElement extends EditableElement {\n\t/**\n\t * Creates root editable element.\n\t *\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string\n\t) {\n\t\tsuper( document, name );\n\n\t\tthis.rootName = 'main';\n\t}\n\n\t/**\n\t * Name of this root inside {@link module:engine/view/document~Document} that is an owner of this root. If no\n\t * other name is set, `main` name is used.\n\t *\n\t * @readonly\n\t */\n\tpublic get rootName(): string {\n\t\treturn this.getCustomProperty( rootNameSymbol ) as string;\n\t}\n\n\tpublic set rootName( rootName: string ) {\n\t\tthis._setCustomProperty( rootNameSymbol, rootName );\n\t}\n\n\t/**\n\t * Overrides old element name and sets new one.\n\t * This is needed because view roots are created before they are attached to the DOM.\n\t * The name of the root element is temporary at this stage. It has to be changed when the\n\t * view root element is attached to the DOM element.\n\t *\n\t * @internal\n\t * @param name The new name of element.\n\t */\n\tpublic set _name( name: string ) {\n\t\t( this as any ).name = name;\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRootEditableElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'rootElement' || type === 'view:rootElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'editableElement' || type === 'view:editableElement' ||\n\t\t\ttype === 'containerElement' || type === 'view:containerElement' ||\n\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && (\n\t\t\ttype === 'rootElement' || type === 'view:rootElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'editableElement' || type === 'view:editableElement' ||\n\t\t\ttype === 'containerElement' || type === 'view:containerElement' ||\n\t\t\ttype === 'element' || type === 'view:element'\n\t\t);\n\t}\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/treewalker\n */\n\nimport Element from './element.js';\nimport Text from './text.js';\nimport TextProxy from './textproxy.js';\nimport Position from './position.js';\nimport type Item from './item.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Range from './range.js';\nimport type Node from './node.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */\nexport default class TreeWalker implements IterableIterator<TreeWalkerValue> {\n\t/**\n\t * Walking direction. Defaults `'forward'`.\n\t */\n\tpublic readonly direction: TreeWalkerDirection;\n\n\t/**\n\t * Iterator boundaries.\n\t *\n\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t * on the start of boundary, then `{ done: true }` is returned.\n\t *\n\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t */\n\tpublic readonly boundaries: Range | null;\n\n\t/**\n\t * Flag indicating whether all characters from {@link module:engine/view/text~Text} should be returned as one\n\t * {@link module:engine/view/text~Text} or one by one as {@link module:engine/view/textproxy~TextProxy}.\n\t */\n\tpublic readonly singleCharacters: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t * iterated node will not be returned along with `elementEnd` tag.\n\t */\n\tpublic readonly shallow: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should ignore `elementEnd` tags. If set to `true`, walker will not\n\t * return a parent node of the start position. Each {@link module:engine/view/element~Element} will be returned once.\n\t * When set to `false` each element might be returned twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tpublic readonly ignoreElementEnd: boolean;\n\n\t/**\n\t * Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t * `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t */\n\tprivate _position: Position;\n\n\t/**\n\t * Start boundary parent.\n\t */\n\tprivate readonly _boundaryStartParent: Node | DocumentFragment | null;\n\n\t/**\n\t * End boundary parent.\n\t */\n\tprivate readonly _boundaryEndParent: Node | DocumentFragment | null;\n\n\t/**\n\t * Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t *\n\t * @param options Object with configuration.\n\t */\n\tconstructor( options: TreeWalkerOptions = {} ) {\n\t\tif ( !options.boundaries && !options.startPosition ) {\n\t\t\t/**\n\t\t\t * Neither boundaries nor starting position have been defined.\n\t\t\t *\n\t\t\t * @error view-tree-walker-no-start-position\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-tree-walker-no-start-position',\n\t\t\t\tnull\n\t\t\t);\n\t\t}\n\n\t\tif ( options.direction && options.direction != 'forward' && options.direction != 'backward' ) {\n\t\t\t/**\n\t\t\t * Only `backward` and `forward` direction allowed.\n\t\t\t *\n\t\t\t * @error view-tree-walker-unknown-direction\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-tree-walker-unknown-direction', options.startPosition, { direction: options.direction } );\n\t\t}\n\n\t\tthis.boundaries = options.boundaries || null;\n\n\t\tif ( options.startPosition ) {\n\t\t\tthis._position = Position._createAt( options.startPosition );\n\t\t} else {\n\t\t\tthis._position = Position._createAt( options.boundaries![ options.direction == 'backward' ? 'end' : 'start' ] );\n\t\t}\n\n\t\tthis.direction = options.direction || 'forward';\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\t\tthis.shallow = !!options.shallow;\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t */\n\tpublic [ Symbol.iterator ](): IterableIterator<TreeWalkerValue> {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t * `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t */\n\tpublic get position(): Position {\n\t\treturn this._position;\n\t}\n\n\t/**\n\t * Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * walker.skip( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * walker.skip( value => true ); // Move the position to the end: <p>{}foo</p> -> <p>foo</p>[]\n\t * walker.skip( value => false ); // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t */\n\tpublic skip( skip: ( value: TreeWalkerValue ) => boolean ): void {\n\t\tlet nextResult: IteratorResult<TreeWalkerValue>;\n\t\tlet prevPosition: Position;\n\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\t\t\tnextResult = this.next();\n\t\t} while ( !nextResult.done && skip( nextResult.value ) );\n\n\t\tif ( !nextResult.done ) {\n\t\t\tthis._position = prevPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the next tree walker's value.\n\t *\n\t * @returns Object implementing iterator interface, returning\n\t * information about taken step.\n\t */\n\tpublic next(): IteratorResult<TreeWalkerValue, undefined> {\n\t\tif ( this.direction == 'forward' ) {\n\t\t\treturn this._next();\n\t\t} else {\n\t\t\treturn this._previous();\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step forward in view. Moves the {@link #position} to the next position and returns the encountered value.\n\t */\n\tprivate _next(): IteratorResult<TreeWalkerValue, undefined> {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the end of the root.\n\t\tif ( parent.parent === null && position.offset === ( parent as any ).childCount ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent === this._boundaryEndParent && position.offset == this.boundaries!.end.offset ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// Get node just after current position.\n\t\tlet node;\n\n\t\t// Text is a specific parent because it contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtEnd ) {\n\t\t\t\t// Prevent returning \"elementEnd\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis._position = Position._createAfter( parent );\n\n\t\t\t\treturn this._next();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset ];\n\t\t} else {\n\t\t\tnode = ( parent as Element | DocumentFragment ).getChild( position.offset );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t} else {\n\t\t\t\t// We are past the walker boundaries.\n\t\t\t\tif ( this.boundaries && this.boundaries.end.isBefore( position ) ) {\n\t\t\t\t\treturn { done: true, value: undefined };\n\t\t\t\t}\n\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis._position = position;\n\n\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t}\n\n\t\tif ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t\tthis._position = position;\n\n\t\t\t\treturn this._next();\n\t\t\t}\n\n\t\t\tlet charactersCount = node.data.length;\n\t\t\tlet item;\n\n\t\t\t// If text stick out of walker range, we need to cut it and wrap in TextProxy.\n\t\t\tif ( node == this._boundaryEndParent ) {\n\t\t\t\tcharactersCount = this.boundaries!.end.offset;\n\t\t\t\titem = new TextProxy( node, 0, charactersCount );\n\t\t\t\tposition = Position._createAfter( item );\n\t\t\t} else {\n\t\t\t\titem = new TextProxy( node, 0, node.data.length );\n\t\t\t\t// If not just keep moving forward.\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis._position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t}\n\n\t\tif ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\ttextLength = 1;\n\t\t\t} else {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst endOffset = parent === this._boundaryEndParent ? this.boundaries!.end.offset : ( parent as Text ).data.length;\n\n\t\t\t\ttextLength = endOffset - position.offset;\n\t\t\t}\n\n\t\t\tconst textProxy = new TextProxy( parent as Text, position.offset, textLength );\n\n\t\t\tposition.offset += textLength;\n\t\t\tthis._position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t}\n\n\t\t// `node` is not set, we reached the end of current `parent`.\n\t\tposition = Position._createAfter( parent as any );\n\t\tthis._position = position;\n\n\t\tif ( this.ignoreElementEnd ) {\n\t\t\treturn this._next();\n\t\t}\n\n\t\treturn this._formatReturnValue( 'elementEnd', parent as any, previousPosition, position );\n\t}\n\n\t/**\n\t * Makes a step backward in view. Moves the {@link #position} to the previous position and returns the encountered value.\n\t */\n\tprivate _previous(): IteratorResult<TreeWalkerValue, undefined> {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the beginning of the root.\n\t\tif ( parent.parent === null && position.offset === 0 ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent == this._boundaryStartParent && position.offset == this.boundaries!.start.offset ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// Get node just before current position.\n\t\tlet node;\n\n\t\t// Text {@link module:engine/view/text~Text} element is a specific parent because contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtStart ) {\n\t\t\t\t// Prevent returning \"elementStart\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis._position = Position._createBefore( parent );\n\n\t\t\t\treturn this._previous();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset - 1 ];\n\t\t} else {\n\t\t\tnode = ( parent as Element | DocumentFragment ).getChild( position.offset - 1 );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( this.shallow ) {\n\t\t\t\tposition.offset--;\n\t\t\t\tthis._position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t\t}\n\n\t\t\tposition = new Position( node, node.childCount );\n\t\t\tthis._position = position;\n\n\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\treturn this._previous();\n\t\t\t}\n\n\t\t\treturn this._formatReturnValue( 'elementEnd', node, previousPosition, position );\n\t\t}\n\n\t\tif ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, node.data.length );\n\t\t\t\tthis._position = position;\n\n\t\t\t\treturn this._previous();\n\t\t\t}\n\n\t\t\tlet charactersCount = node.data.length;\n\t\t\tlet item;\n\n\t\t\t// If text stick out of walker range, we need to cut it and wrap in TextProxy.\n\t\t\tif ( node == this._boundaryStartParent ) {\n\t\t\t\tconst offset = this.boundaries!.start.offset;\n\n\t\t\t\titem = new TextProxy( node, offset, node.data.length - offset );\n\t\t\t\tcharactersCount = item.data.length;\n\t\t\t\tposition = Position._createBefore( item );\n\t\t\t} else {\n\t\t\t\titem = new TextProxy( node, 0, node.data.length );\n\t\t\t\t// If not just keep moving backward.\n\t\t\t\tposition.offset--;\n\t\t\t}\n\n\t\t\tthis._position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t}\n\n\t\tif ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( !this.singleCharacters ) {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst startOffset = parent === this._boundaryStartParent ? this.boundaries!.start.offset : 0;\n\n\t\t\t\ttextLength = position.offset - startOffset;\n\t\t\t} else {\n\t\t\t\ttextLength = 1;\n\t\t\t}\n\n\t\t\tposition.offset -= textLength;\n\n\t\t\tconst textProxy = new TextProxy( parent as Text, position.offset, textLength );\n\n\t\t\tthis._position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t}\n\n\t\t// `node` is not set, we reached the beginning of current `parent`.\n\t\tposition = Position._createBefore( parent as any );\n\t\tthis._position = position;\n\n\t\treturn this._formatReturnValue( 'elementStart', parent as Element, previousPosition, position, 1 );\n\t}\n\n\t/**\n\t * Format returned data and adjust `previousPosition` and `nextPosition` if reach the bound of the {@link module:engine/view/text~Text}.\n\t *\n\t * @param type Type of step.\n\t * @param item Item between old and new position.\n\t * @param previousPosition Previous position of iterator.\n\t * @param nextPosition Next position of iterator.\n\t * @param length Length of the item.\n\t */\n\tprivate _formatReturnValue(\n\t\ttype: TreeWalkerValueType,\n\t\titem: Item,\n\t\tpreviousPosition: Position,\n\t\tnextPosition: Position,\n\t\tlength?: number\n\t): IteratorYieldResult<TreeWalkerValue> {\n\t\t// Text is a specific parent, because contains string instead of children.\n\t\t// Walker doesn't enter to the Text except situations when walker is iterating over every single character,\n\t\t// or the bound starts/ends inside the Text. So when the position is at the beginning or at the end of the Text\n\t\t// we move it just before or just after Text.\n\t\tif ( item instanceof TextProxy ) {\n\t\t\t// Position is at the end of Text.\n\t\t\tif ( item.offsetInText + item.data.length == item.textNode.data.length ) {\n\t\t\t\tif ( this.direction == 'forward' && !( this.boundaries && this.boundaries.end.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position._createAfter( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis._position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position._createAfter( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Position is at the begining ot the text.\n\t\t\tif ( item.offsetInText === 0 ) {\n\t\t\t\tif ( this.direction == 'backward' && !( this.boundaries && this.boundaries.start.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position._createBefore( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis._position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position._createBefore( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdone: false,\n\t\t\tvalue: {\n\t\t\t\ttype,\n\t\t\t\titem,\n\t\t\t\tpreviousPosition,\n\t\t\t\tnextPosition,\n\t\t\t\tlength\n\t\t\t}\n\t\t};\n\t}\n}\n\n/**\n * Type of the step made by {@link module:engine/view/treewalker~TreeWalker}.\n * Possible values: `'elementStart'` if walker is at the beginning of a node, `'elementEnd'` if walker is at the end\n * of node, or `'text'` if walker traversed over single and multiple characters.\n * For {@link module:engine/view/text~Text} `elementStart` and `elementEnd` is not returned.\n */\nexport type TreeWalkerValueType = 'elementStart' | 'elementEnd' | 'text';\n\n/**\n * Object returned by {@link module:engine/view/treewalker~TreeWalker} when traversing tree view.\n */\nexport interface TreeWalkerValue {\n\n\t/**\n\t * Type of the step made by {@link module:engine/view/treewalker~TreeWalker}.\n\t */\n\ttype: TreeWalkerValueType;\n\n\t/**\n\t * Item between the old and the new positions of the tree walker.\n\t */\n\titem: Item;\n\n\t/**\n\t * Previous position of the iterator.\n\t * * Forward iteration: For `'elementEnd'` it is the last position inside the element. For all other types it is the\n\t * position before the item.\n\t * * Backward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n\t * the position after item.\n\t * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n\t * inside of the text to its parent just before or just after that text.\n\t */\n\tpreviousPosition: Position;\n\n\t/**\n\t * Next position of the iterator.\n\t * * Forward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n\t * the position after the item.\n\t * * Backward iteration: For `'elementEnd'` it is last position inside element. For all other types it is the position\n\t * before the item.\n\t * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n\t * inside of the text to its parent just before or just after that text.\n\t */\n\tnextPosition: Position;\n\n\t/**\n\t * Length of the item. For `'elementStart'` it is `1`. For `'text'` it is\n\t * the length of that text. For `'elementEnd'` it is `undefined`.\n\t */\n\tlength?: number;\n}\n\n/**\n * Tree walking direction.\n */\nexport type TreeWalkerDirection = 'forward' | 'backward';\n\n/**\n * The configuration of {@link ~TreeWalker}.\n */\nexport interface TreeWalkerOptions {\n\n\t/**\n\t * Walking direction.\n\t *\n\t * @default 'forward'\n\t */\n\tdirection?: TreeWalkerDirection;\n\n\t/**\n\t * Range to define boundaries of the iterator.\n\t */\n\tboundaries?: Range | null;\n\n\t/**\n\t * Starting position.\n\t */\n\tstartPosition?: Position;\n\n\t/**\n\t * Flag indicating whether all characters from\n\t * {@link module:engine/view/text~Text} should be returned as one {@link module:engine/view/text~Text} (`false`) or one by one as\n\t * {@link module:engine/view/textproxy~TextProxy} (`true`).\n\t */\n\tsingleCharacters?: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should enter elements or not. If the\n\t * iterator is shallow child nodes of any iterated node will not be returned along with `elementEnd` tag.\n\t */\n\tshallow?: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should ignore `elementEnd`\n\t * tags. If the option is true walker will not return a parent node of start position. If this option is `true`\n\t * each {@link module:engine/view/element~Element} will be returned once, while if the option is `false` they might be returned\n\t * twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tignoreElementEnd?: boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/position\n */\n\nimport TypeCheckable from './typecheckable.js';\n\nimport { CKEditorError, compareArrays } from '@ckeditor/ckeditor5-utils';\n\nimport EditableElement from './editableelement.js';\n\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type Item from './item.js';\nimport type Node from './node.js';\nimport { default as TreeWalker, type TreeWalkerValue, type TreeWalkerOptions } from './treewalker.js';\n\n/**\n * Position in the view tree. Position is represented by its parent node and an offset in this parent.\n *\n * In order to create a new position instance use the `createPosition*()` factory methods available in:\n *\n * * {@link module:engine/view/view~View}\n * * {@link module:engine/view/downcastwriter~DowncastWriter}\n * * {@link module:engine/view/upcastwriter~UpcastWriter}\n */\nexport default class Position extends TypeCheckable {\n\t/**\n\t * Position parent.\n\t */\n\tpublic readonly parent: Node | DocumentFragment;\n\n\t/**\n\t * Position offset.\n\t */\n\tpublic offset: number;\n\n\t/**\n\t * Creates a position.\n\t *\n\t * @param parent Position parent.\n\t * @param offset Position offset.\n\t */\n\tconstructor( parent: Node | DocumentFragment, offset: number ) {\n\t\tsuper();\n\n\t\tthis.parent = parent;\n\t\tthis.offset = offset;\n\t}\n\n\t/**\n\t * Node directly after the position. Equals `null` when there is no node after position or position is located\n\t * inside text node.\n\t */\n\tpublic get nodeAfter(): Node | null {\n\t\tif ( this.parent.is( '$text' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn ( this.parent as Element ).getChild( this.offset ) || null;\n\t}\n\n\t/**\n\t * Node directly before the position. Equals `null` when there is no node before position or position is located\n\t * inside text node.\n\t */\n\tpublic get nodeBefore(): Node | null {\n\t\tif ( this.parent.is( '$text' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn ( this.parent as Element ).getChild( this.offset - 1 ) || null;\n\t}\n\n\t/**\n\t * Is `true` if position is at the beginning of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t */\n\tpublic get isAtStart(): boolean {\n\t\treturn this.offset === 0;\n\t}\n\n\t/**\n\t * Is `true` if position is at the end of its {@link module:engine/view/position~Position#parent parent}, `false` otherwise.\n\t */\n\tpublic get isAtEnd(): boolean {\n\t\tconst endOffset = this.parent.is( '$text' ) ? this.parent.data.length : ( this.parent as any ).childCount;\n\n\t\treturn this.offset === endOffset;\n\t}\n\n\t/**\n\t * Position's root, that is the root of the position's parent element.\n\t */\n\tpublic get root(): Node | DocumentFragment {\n\t\treturn this.parent.root;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this position, or `null` if\n\t * position is not inside an editable element.\n\t */\n\tpublic get editableElement(): EditableElement | null {\n\t\tlet editable = this.parent;\n\n\t\twhile ( !( editable instanceof EditableElement ) ) {\n\t\t\tif ( editable.parent ) {\n\t\t\t\teditable = editable.parent;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn editable;\n\t}\n\n\t/**\n\t * Returns a new instance of Position with offset incremented by `shift` value.\n\t *\n\t * @param shift How position offset should get changed. Accepts negative values.\n\t * @returns Shifted position.\n\t */\n\tpublic getShiftedBy( shift: number ): Position {\n\t\tconst shifted = Position._createAt( this );\n\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\n\t\treturn shifted;\n\t}\n\n\t/**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/view/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * getLastMatchingPosition( value => value.type == 'text' ); // <p>{}foo</p> -> <p>foo[]</p>\n\t * getLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } ); // <p>foo[]</p> -> <p>{}foo</p>\n\t * getLastMatchingPosition( value => false ); // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t * @returns The position after the last item which matches the `skip` callback test.\n\t */\n\tpublic getLastMatchingPosition( skip: ( value: TreeWalkerValue ) => boolean, options: TreeWalkerOptions = {} ): Position {\n\t\toptions.startPosition = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\t\ttreeWalker.skip( skip );\n\n\t\treturn treeWalker.position;\n\t}\n\n\t/**\n\t * Returns ancestors array of this position, that is this position's parent and it's ancestors.\n\t *\n\t * @returns Array with ancestors.\n\t */\n\tpublic getAncestors(): Array<Node | DocumentFragment> {\n\t\tif ( this.parent.is( 'documentFragment' ) ) {\n\t\t\treturn [ this.parent ];\n\t\t} else {\n\t\t\treturn this.parent.getAncestors( { includeSelf: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both positions.\n\t */\n\tpublic getCommonAncestor( position: Position ): Node | DocumentFragment | null {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Checks whether this position equals given position.\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if positions are same.\n\t */\n\tpublic isEqual( otherPosition: Position ): boolean {\n\t\treturn ( this.parent == otherPosition.parent && this.offset == otherPosition.offset );\n\t}\n\n\t/**\n\t * Checks whether this position is located before given position. When method returns `false` it does not mean that\n\t * this position is after give one. Two positions may be located inside separate roots and in that situation this\n\t * method will still return `false`.\n\t *\n\t * @see module:engine/view/position~Position#isAfter\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param otherPosition Position to compare with.\n\t * @returns Returns `true` if this position is before given position.\n\t */\n\tpublic isBefore( otherPosition: Position ): boolean {\n\t\treturn this.compareWith( otherPosition ) == 'before';\n\t}\n\n\t/**\n\t * Checks whether this position is located after given position. When method returns `false` it does not mean that\n\t * this position is before give one. Two positions may be located inside separate roots and in that situation this\n\t * method will still return `false`.\n\t *\n\t * @see module:engine/view/position~Position#isBefore\n\t * @see module:engine/view/position~Position#compareWith\n\t * @param otherPosition Position to compare with.\n\t * @returns Returns `true` if this position is after given position.\n\t */\n\tpublic isAfter( otherPosition: Position ): boolean {\n\t\treturn this.compareWith( otherPosition ) == 'after';\n\t}\n\n\t/**\n\t * Checks whether this position is before, after or in same position that other position. Two positions may be also\n\t * different when they are located in separate roots.\n\t *\n\t * @param otherPosition Position to compare with.\n\t */\n\tpublic compareWith( otherPosition: Position ): PositionRelation {\n\t\tif ( this.root !== otherPosition.root ) {\n\t\t\treturn 'different';\n\t\t}\n\n\t\tif ( this.isEqual( otherPosition ) ) {\n\t\t\treturn 'same';\n\t\t}\n\n\t\t// Get path from root to position's parent element.\n\t\tconst thisPath = this.parent.is( 'node' ) ? this.parent.getPath() : [];\n\t\tconst otherPath = otherPosition.parent.is( 'node' ) ? otherPosition.parent.getPath() : [];\n\n\t\t// Add the positions' offsets to the parents offsets.\n\t\tthisPath.push( this.offset );\n\t\totherPath.push( otherPosition.offset );\n\n\t\t// Compare both path arrays to find common ancestor.\n\t\tconst result = compareArrays( thisPath, otherPath );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'prefix':\n\t\t\t\treturn 'before';\n\n\t\t\tcase 'extension':\n\t\t\t\treturn 'after';\n\n\t\t\tdefault:\n\t\t\t\t// Cast to number to avoid having 'same' as a type of `result`.\n\t\t\t\treturn thisPath[ result as number ] < otherPath[ result as number ] ? 'before' : 'after';\n\t\t}\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this positions as a start position.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}\n\t */\n\tpublic getWalker( options: TreeWalkerOptions = {} ): TreeWalker {\n\t\toptions.startPosition = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\t/**\n\t * Clones this position.\n\t */\n\tpublic clone(): Position {\n\t\treturn new Position( this.parent, this.offset );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link module:engine/view/position~Position._createBefore},\n\t * * {@link module:engine/view/position~Position._createAfter}.\n\t *\n\t * @internal\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tpublic static _createAt( itemOrPosition: Item | Position, offset?: PositionOffset ): Position {\n\t\tif ( itemOrPosition instanceof Position ) {\n\t\t\treturn new this( itemOrPosition.parent, itemOrPosition.offset );\n\t\t} else {\n\t\t\tconst node = itemOrPosition;\n\n\t\t\tif ( offset == 'end' ) {\n\t\t\t\toffset = node.is( '$text' ) ? node.data.length : ( node as any ).childCount;\n\t\t\t} else if ( offset == 'before' ) {\n\t\t\t\treturn this._createBefore( node );\n\t\t\t} else if ( offset == 'after' ) {\n\t\t\t\treturn this._createAfter( node );\n\t\t\t} else if ( offset !== 0 && !offset ) {\n\t\t\t\t/**\n\t\t\t\t * {@link module:engine/view/view~View#createPositionAt `View#createPositionAt()`}\n\t\t\t\t * requires the offset to be specified when the first parameter is a view item.\n\t\t\t\t *\n\t\t\t\t * @error view-createpositionat-offset-required\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'view-createpositionat-offset-required', node );\n\t\t\t}\n\n\t\t\treturn new Position( node as any, offset as number );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @internal\n\t * @param item View item after which the position should be located.\n\t */\n\tpublic static _createAfter( item: Item ): Position {\n\t\t// TextProxy is not a instance of Node so we need do handle it in specific way.\n\t\tif ( item.is( '$textProxy' ) ) {\n\t\t\treturn new Position( item.textNode, item.offsetInText + item.data.length );\n\t\t}\n\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position after a root.\n\t\t\t *\n\t\t\t * @error view-position-after-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-position-after-root', item, { root: item } );\n\t\t}\n\n\t\treturn new Position( item.parent, ( item.index as number ) + 1 );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @internal\n\t * @param item View item before which the position should be located.\n\t */\n\tpublic static _createBefore( item: Item ): Position {\n\t\t// TextProxy is not a instance of Node so we need do handle it in specific way.\n\t\tif ( item.is( '$textProxy' ) ) {\n\t\t\treturn new Position( item.textNode, item.offsetInText );\n\t\t}\n\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You cannot make a position before a root.\n\t\t\t *\n\t\t\t * @error view-position-before-root\n\t\t\t * @param {module:engine/view/node~Node} root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-position-before-root', item, { root: item } );\n\t\t}\n\n\t\treturn new Position( item.parent, item.index as number );\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nPosition.prototype.is = function( type: string ): boolean {\n\treturn type === 'position' || type === 'view:position';\n};\n\n/**\n * A flag indicating whether this position is `'before'` or `'after'` or `'same'` as given position.\n * If positions are in different roots `'different'` flag is returned.\n */\nexport type PositionRelation = 'before' | 'after' | 'same' | 'different';\n\n/**\n * Offset or one of the flags.\n */\nexport type PositionOffset = number | 'before' | 'after' | 'end';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/range\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport Position from './position.js';\n\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type Item from './item.js';\nimport type Node from './node.js';\nimport { default as TreeWalker, type TreeWalkerValue, type TreeWalkerOptions } from './treewalker.js';\n\n/**\n * Range in the view tree. A range is represented by its start and end {@link module:engine/view/position~Position positions}.\n *\n * In order to create a new position instance use the `createPosition*()` factory methods available in:\n *\n * * {@link module:engine/view/view~View}\n * * {@link module:engine/view/downcastwriter~DowncastWriter}\n * * {@link module:engine/view/upcastwriter~UpcastWriter}\n */\nexport default class Range extends TypeCheckable implements Iterable<TreeWalkerValue> {\n\t/**\n\t * Start position.\n\t */\n\tpublic readonly start: Position;\n\n\t/**\n\t * End position.\n\t */\n\tpublic readonly end: Position;\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** Constructor creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at the `start` position.\n\t */\n\tconstructor( start: Position, end: Position | null = null ) {\n\t\tsuper();\n\n\t\tthis.start = start.clone();\n\t\tthis.end = end ? end.clone() : start.clone();\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/view/position~Position positions},\n\t * grouped as {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * This iterator uses {@link module:engine/view/treewalker~TreeWalker TreeWalker} with `boundaries` set to this range and\n\t * `ignoreElementEnd` option\n\t * set to `true`.\n\t */\n\tpublic* [ Symbol.iterator ](): IterableIterator<TreeWalkerValue> {\n\t\tyield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );\n\t}\n\n\t/**\n\t * Returns whether the range is collapsed, that is it start and end positions are equal.\n\t */\n\tpublic get isCollapsed(): boolean {\n\t\treturn this.start.isEqual( this.end );\n\t}\n\n\t/**\n\t * Returns whether this range is flat, that is if {@link module:engine/view/range~Range#start start} position and\n\t * {@link module:engine/view/range~Range#end end} position are in the same {@link module:engine/view/position~Position#parent parent}.\n\t */\n\tpublic get isFlat(): boolean {\n\t\treturn this.start.parent === this.end.parent;\n\t}\n\n\t/**\n\t * Range root element.\n\t */\n\tpublic get root(): Node | DocumentFragment {\n\t\treturn this.start.root;\n\t}\n\n\t/**\n\t * Creates a maximal range that has the same content as this range but is expanded in both ways (at the beginning\n\t * and at the end).\n\t *\n\t * For example:\n\t *\n\t * ```html\n\t * <p>Foo</p><p><b>{Bar}</b></p> -> <p>Foo</p>[<p><b>Bar</b>]</p>\n\t * <p><b>foo</b>{bar}<span></span></p> -> <p><b>foo[</b>bar<span></span>]</p>\n\t * ```\n\t *\n\t * Note that in the sample above:\n\t *\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns Enlarged range.\n\t */\n\tpublic getEnlarged(): Range {\n\t\tlet start = this.start.getLastMatchingPosition( enlargeTrimSkip, { direction: 'backward' } );\n\t\tlet end = this.end.getLastMatchingPosition( enlargeTrimSkip );\n\n\t\t// Fix positions, in case if they are in Text node.\n\t\tif ( start.parent.is( '$text' ) && start.isAtStart ) {\n\t\t\tstart = Position._createBefore( start.parent );\n\t\t}\n\n\t\tif ( end.parent.is( '$text' ) && end.isAtEnd ) {\n\t\t\tend = Position._createAfter( end.parent );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a minimum range that has the same content as this range but is trimmed in both ways (at the beginning\n\t * and at the end).\n\t *\n\t * For example:\n\t *\n\t * ```html\n\t * <p>Foo</p>[<p><b>Bar</b>]</p> -> <p>Foo</p><p><b>{Bar}</b></p>\n\t * <p><b>foo[</b>bar<span></span>]</p> -> <p><b>foo</b>{bar}<span></span></p>\n\t * ```\n\t *\n\t * Note that in the sample above:\n\t *\n\t * - `<p>` have type of {@link module:engine/view/containerelement~ContainerElement},\n\t * - `<b>` have type of {@link module:engine/view/attributeelement~AttributeElement},\n\t * - `<span>` have type of {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * @returns Shrunk range.\n\t */\n\tpublic getTrimmed(): Range {\n\t\tlet start = this.start.getLastMatchingPosition( enlargeTrimSkip );\n\n\t\tif ( start.isAfter( this.end ) || start.isEqual( this.end ) ) {\n\t\t\treturn new Range( start, start );\n\t\t}\n\n\t\tlet end = this.end.getLastMatchingPosition( enlargeTrimSkip, { direction: 'backward' } );\n\t\tconst nodeAfterStart = start.nodeAfter;\n\t\tconst nodeBeforeEnd = end.nodeBefore;\n\n\t\t// Because TreeWalker prefers positions next to text node, we need to move them manually into these text nodes.\n\t\tif ( nodeAfterStart && nodeAfterStart.is( '$text' ) ) {\n\t\t\tstart = new Position( nodeAfterStart, 0 );\n\t\t}\n\n\t\tif ( nodeBeforeEnd && nodeBeforeEnd.is( '$text' ) ) {\n\t\t\tend = new Position( nodeBeforeEnd, nodeBeforeEnd.data.length );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Two ranges are equal if their start and end positions are equal.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns `true` if ranges are equal, `false` otherwise\n\t */\n\tpublic isEqual( otherRange: Range ): boolean {\n\t\treturn this == otherRange || ( this.start.isEqual( otherRange.start ) && this.end.isEqual( otherRange.end ) );\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/view/position~Position position}.\n\t *\n\t * @param position Position to check.\n\t * @returns `true` if given {@link module:engine/view/position~Position position} is contained in this range, `false` otherwise.\n\t */\n\tpublic containsPosition( position: Position ): boolean {\n\t\treturn position.isAfter( this.start ) && position.isBefore( this.end );\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/view/range~Range range}.\n\t *\n\t * @param otherRange Range to check.\n\t * @param loose Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t * start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t * even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t * @returns `true` if given {@link module:engine/view/range~Range range} boundaries are contained by this range, `false`\n\t * otherwise.\n\t */\n\tpublic containsRange( otherRange: Range, loose: boolean = false ): boolean {\n\t\tif ( otherRange.isCollapsed ) {\n\t\t\tloose = false;\n\t\t}\n\n\t\tconst containsStart = this.containsPosition( otherRange.start ) || ( loose && this.start.isEqual( otherRange.start ) );\n\t\tconst containsEnd = this.containsPosition( otherRange.end ) || ( loose && this.end.isEqual( otherRange.end ) );\n\n\t\treturn containsStart && containsEnd;\n\t}\n\n\t/**\n\t * Computes which part(s) of this {@link module:engine/view/range~Range range} is not a part of given\n\t * {@link module:engine/view/range~Range range}.\n\t * Returned array contains zero, one or two {@link module:engine/view/range~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let foo = downcastWriter.createText( 'foo' );\n\t * let img = downcastWriter.createContainerElement( 'img' );\n\t * let bar = downcastWriter.createText( 'bar' );\n\t * let p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t * let range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t * let otherRange = view.createRange( // \"oo\", img, \"ba\" are in range.\n\t * \tview.createPositionAt( foo, 1 ),\n\t * \tview.createPositionAt( bar, 2 )\n\t * );\n\t * let transformed = range.getDifference( otherRange );\n\t * // transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t * otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has one range: from ( p, 2 ) to ( bar, 1 )\n\t *\n\t * otherRange = view.createRange( view.createPositionAt( p, 1 ), view.createPositionAt( p, 2 ) ); // img is in range.\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has two ranges: from ( foo, 1 ) to ( p, 1 ) and from ( p, 2 ) to ( bar, 1 )\n\t * ```\n\t *\n\t * @param otherRange Range to differentiate against.\n\t * @returns The difference between ranges.\n\t */\n\tpublic getDifference( otherRange: Range ): Array<Range> {\n\t\tconst ranges: Array<Range> = [];\n\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect.\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the start to the middle of this range.\n\t\t\t\tranges.push( new Range( this.start, otherRange.start ) );\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the middle of this range to the end.\n\t\t\t\tranges.push( new Range( otherRange.end, this.end ) );\n\t\t\t}\n\t\t} else {\n\t\t\t// Ranges do not intersect, return the original range.\n\t\t\tranges.push( this.clone() );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an intersection of this {@link module:engine/view/range~Range range} and given {@link module:engine/view/range~Range range}.\n\t * Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let foo = downcastWriter.createText( 'foo' );\n\t * let img = downcastWriter.createContainerElement( 'img' );\n\t * let bar = downcastWriter.createText( 'bar' );\n\t * let p = downcastWriter.createContainerElement( 'p', null, [ foo, img, bar ] );\n\t *\n\t * let range = view.createRange( view.createPositionAt( foo, 2 ), view.createPositionAt( bar, 1 ); // \"o\", img, \"b\" are in range.\n\t * let otherRange = view.createRange( view.createPositionAt( foo, 1 ), view.createPositionAt( p, 2 ); // \"oo\", img are in range.\n\t * let transformed = range.getIntersection( otherRange ); // range from ( foo, 1 ) to ( p, 2 ).\n\t *\n\t * otherRange = view.createRange( view.createPositionAt( bar, 1 ), view.createPositionAt( bar, 3 ); \"ar\" is in range.\n\t * transformed = range.getIntersection( otherRange ); // null - no common part.\n\t * ```\n\t *\n\t * @param otherRange Range to check for intersection.\n\t * @returns A common part of given ranges or `null` if ranges have no common part.\n\t */\n\tpublic getIntersection( otherRange: Range ): Range | null {\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect, so a common range will be returned.\n\t\t\t// At most, it will be same as this range.\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means thaNt we have to\n\t\t\t\t// shrink common range to the given range start.\n\t\t\t\tcommonRangeStart = otherRange.start;\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// shrink common range to the given range end.\n\t\t\t\tcommonRangeEnd = otherRange.end;\n\t\t\t}\n\n\t\t\treturn new Range( commonRangeStart, commonRangeEnd );\n\t\t}\n\n\t\t// Ranges do not intersect, so they do not have common part.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/view/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t */\n\tpublic getWalker( options: TreeWalkerOptions = {} ): TreeWalker {\n\t\toptions.boundaries = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/node~Node} or {@link module:engine/view/documentfragment~DocumentFragment}\n\t * which is a common ancestor of range's both ends (in which the entire range is contained).\n\t */\n\tpublic getCommonAncestor(): Node | DocumentFragment | null {\n\t\treturn this.start.getCommonAncestor( this.end );\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/view/element~Element Element} contained by the range.\n\t * The element will be returned when it is the **only** node within the range and **fully–contained**\n\t * at the same time.\n\t */\n\tpublic getContainedElement(): Element | null {\n\t\tif ( this.isCollapsed ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet nodeAfterStart = this.start.nodeAfter;\n\t\tlet nodeBeforeEnd = this.end.nodeBefore;\n\n\t\t// Handle the situation when the range position is at the beginning / at the end of a text node.\n\t\t// In such situation `.nodeAfter` and `.nodeBefore` are `null` but the range still might be spanning\n\t\t// over one element.\n\t\t//\n\t\t// <p>Foo{<span class=\"widget\"></span>}bar</p> vs <p>Foo[<span class=\"widget\"></span>]bar</p>\n\t\t//\n\t\t// These are basically the same range, only the difference is if the range position is at\n\t\t// at the end/at the beginning of a text node or just before/just after the text node.\n\t\t//\n\t\tif ( this.start.parent.is( '$text' ) && this.start.isAtEnd && this.start.parent.nextSibling ) {\n\t\t\tnodeAfterStart = this.start.parent.nextSibling;\n\t\t}\n\n\t\tif ( this.end.parent.is( '$text' ) && this.end.isAtStart && this.end.parent.previousSibling ) {\n\t\t\tnodeBeforeEnd = this.end.parent.previousSibling;\n\t\t}\n\n\t\tif ( nodeAfterStart && nodeAfterStart.is( 'element' ) && nodeAfterStart === nodeBeforeEnd ) {\n\t\t\treturn nodeAfterStart;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Clones this range.\n\t */\n\tpublic clone(): Range {\n\t\treturn new Range( this.start, this.end );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/view/item~Item view items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/view/item~Item items},\n\t * not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t */\n\tpublic* getItems( options: TreeWalkerOptions = {} ): IterableIterator<Item> {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/view/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/view/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/view/position~Position positions}, not {@link module:engine/view/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/view/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.\n\t */\n\tpublic* getPositions( options: TreeWalkerOptions = {} ): IterableIterator<Position> {\n\t\toptions.boundaries = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tyield treeWalker.position;\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.nextPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Checks and returns whether this range intersects with the given range.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns True if ranges intersect.\n\t */\n\tpublic isIntersecting( otherRange: Range ): boolean {\n\t\treturn this.start.isBefore( otherRange.end ) && this.end.isAfter( otherRange.start );\n\t}\n\n\t/**\n\t * Creates a range from the given parents and offsets.\n\t *\n\t * @internal\n\t * @param startElement Start position parent element.\n\t * @param startOffset Start position offset.\n\t * @param endElement End position parent element.\n\t * @param endOffset End position offset.\n\t * @returns Created range.\n\t */\n\tpublic static _createFromParentsAndOffsets(\n\t\tstartElement: Element | DocumentFragment,\n\t\tstartOffset: number,\n\t\tendElement: Element | DocumentFragment,\n\t\tendOffset: number\n\t): Range {\n\t\treturn new this(\n\t\t\tnew Position( startElement, startOffset ),\n\t\t\tnew Position( endElement, endOffset )\n\t\t);\n\t}\n\n\t/**\n\t * Creates a new range, spreading from specified {@link module:engine/view/position~Position position} to a position moved by\n\t * given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t *\n\t * @internal\n\t * @param position Beginning of the range.\n\t * @param shift How long the range should be.\n\t */\n\tpublic static _createFromPositionAndShift( position: Position, shift: number ): Range {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy( shift );\n\n\t\treturn shift > 0 ? new this( start, end ) : new this( end, start );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @internal\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic static _createIn( element: Element | DocumentFragment ): Range {\n\t\treturn this._createFromParentsAndOffsets( element, 0, element, element.childCount );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @internal\n\t */\n\tpublic static _createOn( item: Item ): Range {\n\t\tconst size = item.is( '$textProxy' ) ? item.offsetSize : 1;\n\n\t\treturn this._createFromPositionAndShift( Position._createBefore( item ), size );\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRange.prototype.is = function( type: string ): boolean {\n\treturn type === 'range' || type === 'view:range';\n};\n\n/**\n * Function used by getEnlarged and getTrimmed methods.\n */\nfunction enlargeTrimSkip( value: TreeWalkerValue ): boolean {\n\tif ( value.item.is( 'attributeElement' ) || value.item.is( 'uiElement' ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/selection\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport Range from './range.js';\nimport Position, { type PositionOffset } from './position.js';\nimport Node from './node.js';\nimport DocumentSelection from './documentselection.js';\n\nimport {\n\tCKEditorError,\n\tEmitterMixin,\n\tcount,\n\tisIterable\n} from '@ckeditor/ckeditor5-utils';\n\nimport type Element from './element.js';\nimport type Item from './item.js';\nimport type EditableElement from './editableelement.js';\n\n/**\n * Class representing an arbirtary selection in the view.\n * See also {@link module:engine/view/documentselection~DocumentSelection}.\n *\n * New selection instances can be created via the constructor or one these methods:\n *\n * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n *\n * A selection can consist of {@link module:engine/view/range~Range ranges} that can be set by using\n * the {@link module:engine/view/selection~Selection#setTo `Selection#setTo()`} method.\n */\nexport default class Selection extends /* #__PURE__ */ EmitterMixin( TypeCheckable ) {\n\t/**\n\t * Stores all ranges that are selected.\n\t */\n\tprivate _ranges: Array<Range>;\n\n\t/**\n\t * Specifies whether the last added range was added as a backward or forward range.\n\t */\n\tprivate _lastRangeBackward: boolean;\n\n\t/**\n\t * Specifies whether selection instance is fake.\n\t */\n\tprivate _isFake: boolean;\n\n\t/**\n\t * Fake selection's label.\n\t */\n\tprivate _fakeSelectionLabel: string;\n\n\t/**\n\t * Creates new selection instance.\n\t *\n\t * **Note**: The selection constructor is available as a factory method:\n\t *\n\t * * {@link module:engine/view/view~View#createSelection `View#createSelection()`},\n\t * * {@link module:engine/view/upcastwriter~UpcastWriter#createSelection `UpcastWriter#createSelection()`}.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = writer.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = writer.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * const selection = writer.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = writer.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the document selection.\n\t * const selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * const selection = writer.createSelection( position );\n\t *\n\t * // Creates collapsed selection at the position of given item and offset.\n\t * const paragraph = writer.createContainerElement( 'paragraph' );\n\t * const selection = writer.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = writer.createSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * @internal\n\t */\n\tconstructor(\n\t\t...args: [] | [\n\t\t\tselectable: Node,\n\t\t\tplaceOrOffset: PlaceOrOffset,\n\t\t\toptions?: SelectionOptions\n\t\t] | [\n\t\t\tselectable?: Exclude<Selectable, Node>,\n\t\t\toptions?: SelectionOptions\n\t\t]\n\t) {\n\t\tsuper();\n\n\t\tthis._ranges = [];\n\t\tthis._lastRangeBackward = false;\n\t\tthis._isFake = false;\n\t\tthis._fakeSelectionLabel = '';\n\n\t\tif ( args.length ) {\n\t\t\tthis.setTo( ...args );\n\t\t}\n\t}\n\n\t/**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #setTo\n\t */\n\tpublic get isFake(): boolean {\n\t\treturn this._isFake;\n\t}\n\n\t/**\n\t * Returns fake selection label.\n\t *\n\t * @see #setTo\n\t */\n\tpublic get fakeSelectionLabel(): string {\n\t\treturn this._fakeSelectionLabel;\n\t}\n\n\t/**\n\t * Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t * {@link #focus focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t * It may be a bit unintuitive when there are multiple ranges in selection.\n\t *\n\t * @see #focus\n\t */\n\tpublic get anchor(): Position | null {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst anchor = this._lastRangeBackward ? range.end : range.start;\n\n\t\treturn anchor.clone();\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t */\n\tpublic get focus(): Position | null {\n\t\tif ( !this._ranges.length ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\t\tconst focus = this._lastRangeBackward ? range.start : range.end;\n\n\t\treturn focus.clone();\n\t}\n\n\t/**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t */\n\tpublic get isCollapsed(): boolean {\n\t\treturn this.rangeCount === 1 && this._ranges[ 0 ].isCollapsed;\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t */\n\tpublic get rangeCount(): number {\n\t\treturn this._ranges.length;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t */\n\tpublic get isBackward(): boolean {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t */\n\tpublic get editableElement(): EditableElement | null {\n\t\tif ( this.anchor ) {\n\t\t\treturn this.anchor.editableElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns an iterable that contains copies of all ranges added to the selection.\n\t */\n\tpublic* getRanges(): IterableIterator<Range> {\n\t\tfor ( const range of this._ranges ) {\n\t\t\tyield range.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Returns copy of the first range in the selection. First range is the one which\n\t * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start\n\t * position of all other ranges (not to confuse with the first range added to the selection).\n\t * Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getFirstRange(): Range | null {\n\t\tlet first = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !first || range.start.isBefore( first.start ) ) {\n\t\t\t\tfirst = range;\n\t\t\t}\n\t\t}\n\n\t\treturn first ? first.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse\n\t * with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getLastRange(): Range | null {\n\t\tlet last = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !last || range.end.isAfter( last.end ) ) {\n\t\t\t\tlast = range;\n\t\t\t}\n\t\t}\n\n\t\treturn last ? last.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the first position in the selection. First position is the position that\n\t * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getFirstPosition(): Position | null {\n\t\tconst firstRange = this.getFirstRange();\n\n\t\treturn firstRange ? firstRange.start.clone() : null;\n\t}\n\n\t/**\n\t * Returns copy of the last position in the selection. Last position is the position that\n\t * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getLastPosition(): Position | null {\n\t\tconst lastRange = this.getLastRange();\n\n\t\treturn lastRange ? lastRange.end.clone() : null;\n\t}\n\n\t/**\n\t * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t * same number of ranges and all ranges from one selection equal to a range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are equal, `false` otherwise.\n\t */\n\tpublic isEqual( otherSelection: Selection | DocumentSelection ): boolean {\n\t\tif ( this.isFake != otherSelection.isFake ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.isFake && this.fakeSelectionLabel != otherSelection.fakeSelectionLabel ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.rangeCount != otherSelection.rangeCount ) {\n\t\t\treturn false;\n\t\t} else if ( this.rangeCount === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.anchor!.isEqual( otherSelection.anchor! ) || !this.focus!.isEqual( otherSelection.focus! ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const thisRange of this._ranges ) {\n\t\t\tlet found = false;\n\n\t\t\tfor ( const otherRange of ( otherSelection as any )._ranges ) {\n\t\t\t\tif ( thisRange.isEqual( otherRange ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are similar, `false` otherwise.\n\t */\n\tpublic isSimilar( otherSelection: Selection | DocumentSelection ): boolean {\n\t\tif ( this.isBackward != otherSelection.isBackward ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst numOfRangesA = count( this.getRanges() );\n\t\tconst numOfRangesB = count( otherSelection.getRanges() );\n\n\t\t// If selections have different number of ranges, they cannot be similar.\n\t\tif ( numOfRangesA != numOfRangesB ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If both selections have no ranges, they are similar.\n\t\tif ( numOfRangesA == 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if each range in one selection has a similar range in other selection.\n\t\tfor ( let rangeA of this.getRanges() ) {\n\t\t\trangeA = rangeA.getTrimmed();\n\n\t\t\tlet found = false;\n\n\t\t\tfor ( let rangeB of otherSelection.getRanges() ) {\n\t\t\t\trangeB = rangeB.getTrimmed();\n\n\t\t\t\tif ( rangeA.start.isEqual( rangeB.start ) && rangeA.end.isEqual( rangeB.end ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For `rangeA`, neither range in `otherSelection` was similar. So selections are not similar.\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// There were no ranges that weren't matched. Selections are similar.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */\n\tpublic getSelectedElement(): Element | null {\n\t\tif ( this.rangeCount !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.getFirstRange()!.getContainedElement();\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t * ```ts\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * selection.setTo( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * selection.setTo( range );\n\t *\n\t * // Sets selection to the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * selection.setTo( otherSelection );\n\t *\n\t * // Sets selection to contents of DocumentSelection.\n\t * selection.setTo( editor.editing.view.document.selection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPositionAt( root, path );\n\t * selection.setTo( position );\n\t *\n\t * // Sets collapsed selection at the position of given item and offset.\n\t * selection.setTo( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'on' );\n\t *\n\t * // Clears selection. Removes all ranges.\n\t * selection.setTo( null );\n\t * ```\n\t *\n\t * `Selection#setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * selection.setTo( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * selection.setTo( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * @fires change\n\t */\n\tpublic setTo(\n\t\t...args: [\n\t\t\tselectable: Node,\n\t\t\tplaceOrOffset: PlaceOrOffset,\n\t\t\toptions?: SelectionOptions\n\t\t] | [\n\t\t\tselectable?: Exclude<Selectable, Node>,\n\t\t\toptions?: SelectionOptions\n\t\t]\n\t): void {\n\t\tlet [ selectable, placeOrOffset, options ] = args;\n\n\t\tif ( typeof placeOrOffset == 'object' ) {\n\t\t\toptions = placeOrOffset;\n\t\t\tplaceOrOffset = undefined;\n\t\t}\n\n\t\tif ( selectable === null ) {\n\t\t\tthis._setRanges( [] );\n\t\t\tthis._setFakeOptions( options );\n\t\t} else if ( selectable instanceof Selection || selectable instanceof DocumentSelection ) {\n\t\t\tthis._setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t\tthis._setFakeOptions( { fake: selectable.isFake, label: selectable.fakeSelectionLabel } );\n\t\t} else if ( selectable instanceof Range ) {\n\t\t\tthis._setRanges( [ selectable ], options && options.backward );\n\t\t\tthis._setFakeOptions( options );\n\t\t} else if ( selectable instanceof Position ) {\n\t\t\tthis._setRanges( [ new Range( selectable ) ] );\n\t\t\tthis._setFakeOptions( options );\n\t\t} else if ( selectable instanceof Node ) {\n\t\t\tconst backward = !!options && !!options.backward;\n\t\t\tlet range;\n\n\t\t\tif ( placeOrOffset === undefined ) {\n\t\t\t\t/**\n\t\t\t\t * selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-setto-required-second-parameter\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'view-selection-setto-required-second-parameter', this );\n\t\t\t} else if ( placeOrOffset == 'in' ) {\n\t\t\t\trange = Range._createIn( selectable as Element );\n\t\t\t} else if ( placeOrOffset == 'on' ) {\n\t\t\t\trange = Range._createOn( selectable );\n\t\t\t} else {\n\t\t\t\trange = new Range( Position._createAt( selectable, placeOrOffset ) );\n\t\t\t}\n\n\t\t\tthis._setRanges( [ range ], backward );\n\t\t\tthis._setFakeOptions( options );\n\t\t} else if ( isIterable( selectable ) ) {\n\t\t\t// We assume that the selectable is an iterable of ranges.\n\t\t\t// Array.from() is used to prevent setting ranges to the old iterable\n\t\t\tthis._setRanges( selectable, options && options.backward );\n\t\t\tthis._setFakeOptions( options );\n\t\t} else {\n\t\t\t/**\n\t\t\t * Cannot set selection to given place.\n\t\t\t *\n\t\t\t * @error view-selection-setto-not-selectable\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-selection-setto-not-selectable', this );\n\t\t}\n\n\t\tthis.fire<ViewSelectionChangeEvent>( 'change' );\n\t}\n\n\t/**\n\t * Moves {@link #focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @fires change\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tpublic setFocus( itemOrPosition: Item | Position, offset?: PositionOffset ): void {\n\t\tif ( this.anchor === null ) {\n\t\t\t/**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error view-selection-setfocus-no-ranges\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-selection-setfocus-no-ranges', this );\n\t\t}\n\n\t\tconst newFocus = Position._createAt( itemOrPosition, offset );\n\n\t\tif ( newFocus.compareWith( this.focus! ) == 'same' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst anchor = this.anchor;\n\n\t\tthis._ranges.pop();\n\n\t\tif ( newFocus.compareWith( anchor ) == 'before' ) {\n\t\t\tthis._addRange( new Range( newFocus, anchor ), true );\n\t\t} else {\n\t\t\tthis._addRange( new Range( anchor, newFocus ) );\n\t\t}\n\n\t\tthis.fire<ViewSelectionChangeEvent>( 'change' );\n\t}\n\n\t/**\n\t * Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t * is treated like the last added range and is used to set {@link #anchor anchor} and {@link #focus focus}.\n\t * Accepts a flag describing in which way the selection is made.\n\t *\n\t * @param newRanges Iterable object of ranges to set.\n\t * @param isLastBackward Flag describing if last added range was selected forward - from start to end\n\t * (`false`) or backward - from end to start (`true`). Defaults to `false`.\n\t */\n\tprivate _setRanges( newRanges: Iterable<Range>, isLastBackward: boolean = false ) {\n\t\t// New ranges should be copied to prevent removing them by setting them to `[]` first.\n\t\t// Only applies to situations when selection is set to the same selection or same selection's ranges.\n\t\tnewRanges = Array.from( newRanges );\n\n\t\tthis._ranges = [];\n\n\t\tfor ( const range of newRanges ) {\n\t\t\tthis._addRange( range );\n\t\t}\n\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\t}\n\n\t/**\n\t * Sets this selection instance to be marked as `fake`. A fake selection does not render as browser native selection\n\t * over selected elements and is hidden to the user. This way, no native selection UI artifacts are displayed to\n\t * the user and selection over elements can be represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM (and be\n\t * properly handled by screen readers).\n\t */\n\tprivate _setFakeOptions( options: SelectionOptions = {} ) {\n\t\tthis._isFake = !!options.fake;\n\t\tthis._fakeSelectionLabel = options.fake ? options.label || '' : '';\n\t}\n\n\t/**\n\t * Adds a range to the selection. Added range is copied. This means that passed range is not saved in the\n\t * selection instance and you can safely operate on it.\n\t *\n\t * Accepts a flag describing in which way the selection is made - passed range might be selected from\n\t * {@link module:engine/view/range~Range#start start} to {@link module:engine/view/range~Range#end end}\n\t * or from {@link module:engine/view/range~Range#end end} to {@link module:engine/view/range~Range#start start}.\n\t * The flag is used to set {@link #anchor anchor} and {@link #focus focus} properties.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in Selection instance.\n\t */\n\tprivate _addRange( range: Range, isBackward: boolean = false ): void {\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\t/**\n\t\t\t * Selection range set to an object that is not an instance of {@link module:engine/view/range~Range}.\n\t\t\t *\n\t\t\t * @error view-selection-add-range-not-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-selection-add-range-not-range',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tthis._pushRange( range );\n\t\tthis._lastRangeBackward = !!isBackward;\n\t}\n\n\t/**\n\t * Adds range to selection - creates copy of given range so it can be safely used and modified.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-selection-range-intersects` if added range intersects\n\t * with ranges already stored in selection instance.\n\t */\n\tprivate _pushRange( range: Range ): void {\n\t\tfor ( const storedRange of this._ranges ) {\n\t\t\tif ( range.isIntersecting( storedRange ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to add a range that intersects with another range from selection.\n\t\t\t\t *\n\t\t\t\t * @error view-selection-range-intersects\n\t\t\t\t * @param {module:engine/view/range~Range} addedRange Range that was added to the selection.\n\t\t\t\t * @param {module:engine/view/range~Range} intersectingRange Range from selection that intersects with `addedRange`.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'view-selection-range-intersects',\n\t\t\t\t\tthis,\n\t\t\t\t\t{ addedRange: range, intersectingRange: storedRange }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tthis._ranges.push( new Range( range.start, range.end ) );\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nSelection.prototype.is = function( type: string ): boolean {\n\treturn type === 'selection' || type === 'view:selection';\n};\n\n/**\n * Additional options for {@link ~Selection}.\n */\nexport interface SelectionOptions {\n\n\t/**\n\t * Sets this selection instance to be backward.\n\t */\n\tbackward?: boolean;\n\n\t/**\n\t * Sets this selection instance to be marked as `fake`.\n\t */\n\tfake?: boolean;\n\n\t/**\n\t * Label for the fake selection.\n\t */\n\tlabel?: string;\n}\n\n/**\n * The place or offset of the selection.\n */\nexport type PlaceOrOffset = number | 'before' | 'end' | 'after' | 'on' | 'in';\n\n/**\n * Fired whenever selection ranges are changed through {@link ~Selection Selection API}.\n *\n * @eventName ~Selection#change\n */\nexport type ViewSelectionChangeEvent = {\n\tname: 'change';\n\targs: [];\n};\n\n/**\n * An entity that is used to set selection.\n *\n * See also {@link module:engine/view/selection~Selection#setTo}\n */\nexport type Selectable = Selection | DocumentSelection | Position | Iterable<Range> | Range | Node | null;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/documentselection\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport Selection, {\n\ttype PlaceOrOffset,\n\ttype Selectable,\n\ttype SelectionOptions,\n\ttype ViewSelectionChangeEvent\n} from './selection.js';\n\nimport { EmitterMixin } from '@ckeditor/ckeditor5-utils';\n\nimport type EditableElement from './editableelement.js';\nimport type Element from './element.js';\nimport type Node from './node.js';\nimport type Item from './item.js';\nimport type { default as Position, PositionOffset } from './position.js';\nimport type Range from './range.js';\n\n/**\n * Class representing the document selection in the view.\n *\n * Its instance is available in {@link module:engine/view/document~Document#selection `Document#selection`}.\n *\n * It is similar to {@link module:engine/view/selection~Selection} but\n * it has a read-only API and can be modified only by the writer available in\n * the {@link module:engine/view/view~View#change `View#change()`} block\n * (so via {@link module:engine/view/downcastwriter~DowncastWriter#setSelection `DowncastWriter#setSelection()`}).\n */\nexport default class DocumentSelection extends /* #__PURE__ */ EmitterMixin( TypeCheckable ) {\n\t/**\n\t * Selection is used internally (`DocumentSelection` is a proxy to that selection).\n\t */\n\tprivate readonly _selection: Selection;\n\n\t/**\n\t * Creates new DocumentSelection instance.\n\t *\n\t * ```ts\n\t * // Creates collapsed selection at the position of given item and offset.\n\t * const paragraph = writer.createContainerElement( 'paragraph' );\n\t * const selection = new DocumentSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = new DocumentSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = new DocumentSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = new DocumentSelection( element, 'in', { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = new DocumentSelection( element, 'in', { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #constructor:SELECTABLE `constructor( selectable, options )`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic constructor( selectable: Node, placeOrOffset: PlaceOrOffset, options?: SelectionOptions );\n\n\t/**\n\t * Creates new DocumentSelection instance.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = new DocumentSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = new DocumentSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];\n\t * const selection = new DocumentSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = new DocumentSelection( otherSelection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionAt( root, offset );\n\t * const selection = new DocumentSelection( position );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = new DocumentSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = new DocumentSelection( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #constructor:NODE_OFFSET `constructor( node, placeOrOffset, options )`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic constructor( selectable?: Exclude<Selectable, Node>, options?: SelectionOptions );\n\n\tconstructor( ...args: ConstructorParameters<typeof Selection> ) {\n\t\tsuper();\n\n\t\tthis._selection = new Selection();\n\n\t\t// Delegate change event to be fired on DocumentSelection instance.\n\t\tthis._selection.delegate( 'change' ).to( this );\n\n\t\t// Set selection data.\n\t\tif ( args.length ) {\n\t\t\tthis._selection.setTo( ...args );\n\t\t}\n\t}\n\n\t/**\n\t * Returns true if selection instance is marked as `fake`.\n\t *\n\t * @see #_setTo\n\t */\n\tpublic get isFake(): boolean {\n\t\treturn this._selection.isFake;\n\t}\n\n\t/**\n\t * Returns fake selection label.\n\t *\n\t * @see #_setTo\n\t */\n\tpublic get fakeSelectionLabel(): string {\n\t\treturn this._selection.fakeSelectionLabel;\n\t}\n\n\t/**\n\t * Selection anchor. Anchor may be described as a position where the selection starts. Together with\n\t * {@link #focus focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always the start or end of the most recent added range.\n\t * It may be a bit unintuitive when there are multiple ranges in selection.\n\t *\n\t * @see #focus\n\t */\n\tpublic get anchor(): Position | null {\n\t\treturn this._selection.anchor;\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * @see #anchor\n\t */\n\tpublic get focus(): Position | null {\n\t\treturn this._selection.focus;\n\t}\n\n\t/**\n\t * Returns whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t */\n\tpublic get isCollapsed(): boolean {\n\t\treturn this._selection.isCollapsed;\n\t}\n\n\t/**\n\t * Returns number of ranges in selection.\n\t */\n\tpublic get rangeCount(): number {\n\t\treturn this._selection.rangeCount;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus} precedes {@link #anchor}.\n\t */\n\tpublic get isBackward(): boolean {\n\t\treturn this._selection.isBackward;\n\t}\n\n\t/**\n\t * {@link module:engine/view/editableelement~EditableElement EditableElement} instance that contains this selection, or `null`\n\t * if the selection is not inside an editable element.\n\t */\n\tpublic get editableElement(): EditableElement | null {\n\t\treturn this._selection.editableElement;\n\t}\n\n\t/**\n\t * Used for the compatibility with the {@link module:engine/view/selection~Selection#isEqual} method.\n\t *\n\t * @internal\n\t */\n\tpublic get _ranges(): Array<Range> {\n\t\treturn ( this._selection as any )._ranges;\n\t}\n\n\t/**\n\t * Returns an iterable that contains copies of all ranges added to the selection.\n\t */\n\tpublic* getRanges(): IterableIterator<Range> {\n\t\tyield* this._selection.getRanges();\n\t}\n\n\t/**\n\t * Returns copy of the first range in the selection. First range is the one which\n\t * {@link module:engine/view/range~Range#start start} position {@link module:engine/view/position~Position#isBefore is before} start\n\t * position of all other ranges (not to confuse with the first range added to the selection).\n\t * Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getFirstRange(): Range | null {\n\t\treturn this._selection.getFirstRange();\n\t}\n\n\t/**\n\t * Returns copy of the last range in the selection. Last range is the one which {@link module:engine/view/range~Range#end end}\n\t * position {@link module:engine/view/position~Position#isAfter is after} end position of all other ranges (not to confuse\n\t * with the last range added to the selection). Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getLastRange(): Range | null {\n\t\treturn this._selection.getLastRange();\n\t}\n\n\t/**\n\t * Returns copy of the first position in the selection. First position is the position that\n\t * {@link module:engine/view/position~Position#isBefore is before} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getFirstPosition(): Position | null {\n\t\treturn this._selection.getFirstPosition();\n\t}\n\n\t/**\n\t * Returns copy of the last position in the selection. Last position is the position that\n\t * {@link module:engine/view/position~Position#isAfter is after} any other position in the selection ranges.\n\t * Returns `null` if no ranges are added to selection.\n\t */\n\tpublic getLastPosition(): Position | null {\n\t\treturn this._selection.getLastPosition();\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/view/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */\n\tpublic getSelectedElement(): Element | null {\n\t\treturn this._selection.getSelectedElement();\n\t}\n\n\t/**\n\t * Checks whether, this selection is equal to given selection. Selections are equal if they have same directions,\n\t * same number of ranges and all ranges from one selection equal to a range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are equal, `false` otherwise.\n\t */\n\tpublic isEqual( otherSelection: Selection | DocumentSelection ): boolean {\n\t\treturn this._selection.isEqual( otherSelection );\n\t}\n\n\t/**\n\t * Checks whether this selection is similar to given selection. Selections are similar if they have same directions, same\n\t * number of ranges, and all {@link module:engine/view/range~Range#getTrimmed trimmed} ranges from one selection are\n\t * equal to any trimmed range from other selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are similar, `false` otherwise.\n\t */\n\tpublic isSimilar( otherSelection: Selection | DocumentSelection ): boolean {\n\t\treturn this._selection.isSimilar( otherSelection );\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t * ```ts\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * documentSelection._setTo( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];\n\t * documentSelection._setTo( range );\n\t *\n\t * // Sets selection to the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * documentSelection._setTo( otherSelection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPositionAt( root, offset );\n\t * documentSelection._setTo( position );\n\t *\n\t * // Sets collapsed selection at the position of given item and offset.\n\t * documentSelection._setTo( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * documentSelection._setTo( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * documentSelection._setTo( paragraph, 'on' );\n\t *\n\t * // Clears selection. Removes all ranges.\n\t * documentSelection._setTo( null );\n\t * ```\n\t *\n\t * `Selection#_setTo()` method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * documentSelection._setTo( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to des cribe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * documentSelection._setTo( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * @internal\n\t * @fires change\n\t */\n\tpublic _setTo( ...args: Parameters<Selection[ 'setTo' ]> ): void {\n\t\tthis._selection.setTo( ...args );\n\t}\n\n\t/**\n\t * Moves {@link #focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @internal\n\t * @fires change\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tpublic _setFocus( itemOrPosition: Item | Position, offset?: PositionOffset ): void {\n\t\tthis._selection.setFocus( itemOrPosition, offset );\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentSelection.prototype.is = function( type: string ): boolean {\n\treturn type === 'selection' ||\n\t\ttype == 'documentSelection' ||\n\t\ttype == 'view:selection' ||\n\t\ttype == 'view:documentSelection';\n};\n\n/**\n * Fired whenever selection ranges are changed through {@link ~DocumentSelection Selection API}.\n *\n * @eventName ~DocumentSelection#change\n */\nexport type ViewDocumentSelectionChangeEvent = ViewSelectionChangeEvent;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/bubblingeventinfo\n */\n\nimport { EventInfo } from '@ckeditor/ckeditor5-utils';\nimport type Document from '../document.js';\nimport type Node from '../node.js';\nimport type Range from '../range.js';\n\n/**\n * The event object passed to bubbling event callbacks. It is used to provide information about the event as well as a tool to\n * manipulate it.\n */\nexport default class BubblingEventInfo<TName extends string = string, TReturn = unknown> extends EventInfo<TName, TReturn> {\n\t/**\n\t * The view range that the bubbling should start from.\n\t */\n\tpublic readonly startRange: Range;\n\n\t/**\n\t * The current event phase.\n\t */\n\tprivate _eventPhase: EventPhase;\n\n\t/**\n\t * The current bubbling target.\n\t */\n\tprivate _currentTarget: Document | Node | null;\n\n\t/**\n\t * @param source The emitter.\n\t * @param name The event name.\n\t * @param startRange The view range that the bubbling should start from.\n\t */\n\tconstructor( source: object, name: TName, startRange: Range ) {\n\t\tsuper( source, name );\n\n\t\tthis.startRange = startRange;\n\t\tthis._eventPhase = 'none';\n\t\tthis._currentTarget = null;\n\t}\n\n\t/**\n\t * The current event phase.\n\t */\n\tpublic get eventPhase(): EventPhase {\n\t\treturn this._eventPhase;\n\t}\n\n\t/**\n\t * The current bubbling target.\n\t */\n\tpublic get currentTarget(): Document | Node | null {\n\t\treturn this._currentTarget;\n\t}\n}\n\n/**\n * The phase the event is in.\n */\nexport type EventPhase = 'none' | 'capturing' | 'atTarget' | 'bubbling';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/bubblingemittermixin\n */\n\nimport {\n\tCKEditorError,\n\tEmitterMixin,\n\tEventInfo,\n\ttoArray,\n\ttype ArrayOrItem,\n\ttype Emitter,\n\ttype GetEventInfo,\n\ttype GetNameOrEventInfo,\n\ttype BaseEvent,\n\ttype CallbackOptions,\n\ttype Constructor,\n\ttype Mixed\n} from '@ckeditor/ckeditor5-utils';\n\nimport BubblingEventInfo, { type EventPhase } from './bubblingeventinfo.js';\nimport type Document from '../document.js';\nimport type Node from '../node.js';\nimport type Range from '../range.js';\nimport type Element from '../element.js';\nimport type DocumentSelection from '../documentselection.js';\n\nconst contextsSymbol = Symbol( 'bubbling contexts' );\n\n/**\n * Bubbling emitter mixin for the view document as described in the {@link ~BubblingEmitter} interface.\n *\n * This function creates a class that inherits from the provided `base` and implements `Emitter` interface.\n * The base class must implement {@link module:utils/emittermixin~Emitter} interface.\n *\n * ```ts\n * class BaseClass extends EmitterMixin() {\n * \t// ...\n * }\n *\n * class MyClass extends BubblingEmitterMixin( BaseClass ) {\n * \t// This class derives from `BaseClass` and implements the `BubblingEmitter` interface.\n * }\n * ```\n */\nexport default function BubblingEmitterMixin<Base extends Constructor<Emitter>>( base: Base ): Mixed<Base, BubblingEmitter> {\n\tabstract class Mixin extends base implements BubblingEmitter {\n\t\tpublic abstract get selection(): DocumentSelection;\n\n\t\tpublic override fire<TEvent extends BaseEvent>(\n\t\t\teventOrInfo: GetNameOrEventInfo<TEvent>,\n\t\t\t...eventArgs: TEvent[ 'args' ]\n\t\t): GetEventInfo<TEvent>[ 'return' ] {\n\t\t\ttry {\n\t\t\t\tconst eventInfo = eventOrInfo instanceof EventInfo ? eventOrInfo : new EventInfo( this, eventOrInfo );\n\t\t\t\tconst eventContexts = getBubblingContexts( this );\n\n\t\t\t\tif ( !eventContexts.size ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tupdateEventInfo( eventInfo, 'capturing', this );\n\n\t\t\t\t// The capture phase of the event.\n\t\t\t\tif ( fireListenerFor( eventContexts, '$capture', eventInfo, ...eventArgs ) ) {\n\t\t\t\t\treturn eventInfo.return;\n\t\t\t\t}\n\n\t\t\t\tconst startRange = ( eventInfo as BubblingEventInfo ).startRange || this.selection.getFirstRange();\n\t\t\t\tconst selectedElement = startRange ? startRange.getContainedElement() : null;\n\t\t\t\tconst isCustomContext = selectedElement ? Boolean( getCustomContext( eventContexts, selectedElement ) ) : false;\n\n\t\t\t\tlet node: Node | null = selectedElement || getDeeperRangeParent( startRange );\n\n\t\t\t\tupdateEventInfo( eventInfo, 'atTarget', node );\n\n\t\t\t\t// For the not yet bubbling event trigger for $text node if selection can be there and it's not a custom context selected.\n\t\t\t\tif ( !isCustomContext ) {\n\t\t\t\t\tif ( fireListenerFor( eventContexts, '$text', eventInfo, ...eventArgs ) ) {\n\t\t\t\t\t\treturn eventInfo.return;\n\t\t\t\t\t}\n\n\t\t\t\t\tupdateEventInfo( eventInfo, 'bubbling', node );\n\t\t\t\t}\n\n\t\t\t\twhile ( node ) {\n\t\t\t\t\t// Root node handling.\n\t\t\t\t\tif ( node.is( 'rootElement' ) ) {\n\t\t\t\t\t\tif ( fireListenerFor( eventContexts, '$root', eventInfo, ...eventArgs ) ) {\n\t\t\t\t\t\t\treturn eventInfo.return;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Element node handling.\n\t\t\t\t\telse if ( node.is( 'element' ) ) {\n\t\t\t\t\t\tif ( fireListenerFor( eventContexts, node.name, eventInfo, ...eventArgs ) ) {\n\t\t\t\t\t\t\treturn eventInfo.return;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check custom contexts (i.e., a widget).\n\t\t\t\t\tif ( fireListenerFor( eventContexts, node, eventInfo, ...eventArgs ) ) {\n\t\t\t\t\t\treturn eventInfo.return;\n\t\t\t\t\t}\n\n\t\t\t\t\tnode = node.parent as Node;\n\n\t\t\t\t\tupdateEventInfo( eventInfo, 'bubbling', node );\n\t\t\t\t}\n\n\t\t\t\tupdateEventInfo( eventInfo, 'bubbling', this );\n\n\t\t\t\t// Document context.\n\t\t\t\tfireListenerFor( eventContexts, '$document', eventInfo, ...eventArgs );\n\n\t\t\t\treturn eventInfo.return;\n\t\t\t} catch ( err: any ) {\n\t\t\t\t// @if CK_DEBUG // throw err;\n\t\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\t\tCKEditorError.rethrowUnexpectedError( err, this );\n\t\t\t}\n\t\t}\n\n\t\tpublic _addEventListener(\n\t\t\tthis: Document,\n\t\t\tevent: string,\n\t\t\tcallback: ( ev: EventInfo, ...args: Array<any> ) => void,\n\t\t\toptions: BubblingCallbackOptions\n\t\t) {\n\t\t\tconst contexts = toArray( options.context || '$document' );\n\t\t\tconst eventContexts = getBubblingContexts( this );\n\n\t\t\tfor ( const context of contexts ) {\n\t\t\t\tlet emitter = eventContexts.get( context );\n\n\t\t\t\tif ( !emitter ) {\n\t\t\t\t\temitter = new ( EmitterMixin() )();\n\t\t\t\t\teventContexts.set( context, emitter! );\n\t\t\t\t}\n\n\t\t\t\tthis.listenTo( emitter!, event, callback, options );\n\t\t\t}\n\t\t}\n\n\t\tpublic _removeEventListener( this: Document, event: string, callback: Function ): void {\n\t\t\tconst eventContexts = getBubblingContexts( this );\n\n\t\t\tfor ( const emitter of eventContexts.values() ) {\n\t\t\t\tthis.stopListening( emitter, event, callback );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Mixin as any;\n}\n\n// Backward compatibility with `mix`.\n{\n\tconst mixin = ( BubblingEmitterMixin as any )( Object );\n\n\t[ 'fire', '_addEventListener', '_removeEventListener' ].forEach( key => {\n\t\t( BubblingEmitterMixin as any )[ key ] = mixin.prototype[ key ];\n\t} );\n}\n\n/**\n * Update the event info bubbling fields.\n *\n * @param eventInfo The event info object to update.\n * @param eventPhase The current event phase.\n * @param currentTarget The current bubbling target.\n */\nfunction updateEventInfo(\n\teventInfo: EventInfo,\n\teventPhase: EventPhase,\n\tcurrentTarget: unknown\n) {\n\tif ( eventInfo instanceof BubblingEventInfo ) {\n\t\t( eventInfo as any )._eventPhase = eventPhase;\n\t\t( eventInfo as any )._currentTarget = currentTarget;\n\t}\n}\n\n/**\n * Fires the listener for the specified context. Returns `true` if event was stopped.\n *\n * @param eventInfo The `EventInfo` object.\n * @param eventArgs Additional arguments to be passed to the callbacks.\n * @returns True if event stop was called.\n */\nfunction fireListenerFor(\n\teventContexts: BubblingEventContexts,\n\tcontext: string | Node,\n\teventInfo: EventInfo,\n\t...eventArgs: Array<unknown>\n) {\n\tconst emitter = typeof context == 'string' ? eventContexts.get( context ) : getCustomContext( eventContexts, context );\n\n\tif ( !emitter ) {\n\t\treturn false;\n\t}\n\n\temitter.fire( eventInfo, ...eventArgs );\n\n\treturn eventInfo.stop.called;\n}\n\n/**\n * Returns an emitter for a specified view node.\n */\nfunction getCustomContext( eventContexts: BubblingEventContexts, node: Node ): Emitter | null {\n\tfor ( const [ context, emitter ] of eventContexts ) {\n\t\tif ( typeof context == 'function' && context( node ) ) {\n\t\t\treturn emitter;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns bubbling contexts map for the source (emitter).\n */\nfunction getBubblingContexts( source: { [ x: string ]: any; [ contextsSymbol ]?: BubblingEventContexts } ) {\n\tif ( !source[ contextsSymbol ] ) {\n\t\tsource[ contextsSymbol ] = new Map();\n\t}\n\n\treturn source[ contextsSymbol ];\n}\n\n/**\n * Returns the deeper parent element for the range.\n */\nfunction getDeeperRangeParent( range: Range ): Node | null {\n\tif ( !range ) {\n\t\treturn null;\n\t}\n\n\tconst startParent = range.start.parent as Element;\n\tconst endParent = range.end.parent as Element;\n\n\tconst startPath = startParent.getPath();\n\tconst endPath = endParent.getPath();\n\n\treturn startPath.length > endPath.length ? startParent : endParent;\n}\n\n/**\n * Bubbling emitter for the view document.\n *\n * Bubbling emitter is triggering events in the context of specified {@link module:engine/view/element~Element view element} name,\n * predefined `'$text'`, `'$root'`, `'$document'` and `'$capture'` contexts, and context matchers provided as a function.\n *\n * Before bubbling starts, listeners for `'$capture'` context are triggered. Then the bubbling starts from the deeper selection\n * position (by firing event on the `'$text'` context) and propagates the view document tree up to the `'$root'` and finally\n * the listeners at `'$document'` context are fired (this is the default context).\n *\n * Examples:\n *\n * ```ts\n * // Listeners registered in the context of the view element names:\n * this.listenTo( viewDocument, 'enter', ( evt, data ) => {\n * \t// ...\n * }, { context: 'blockquote' } );\n *\n * this.listenTo( viewDocument, 'enter', ( evt, data ) => {\n * \t// ...\n * }, { context: 'li' } );\n *\n * // Listeners registered in the context of the '$text' and '$root' nodes.\n * this.listenTo( view.document, 'arrowKey', ( evt, data ) => {\n * \t// ...\n * }, { context: '$text', priority: 'high' } );\n *\n * this.listenTo( view.document, 'arrowKey', ( evt, data ) => {\n * \t// ...\n * }, { context: '$root' } );\n *\n * // Listeners registered in the context of custom callback function.\n * this.listenTo( view.document, 'arrowKey', ( evt, data ) => {\n * \t// ...\n * }, { context: isWidget } );\n *\n * this.listenTo( view.document, 'arrowKey', ( evt, data ) => {\n * \t// ...\n * }, { context: isWidget, priority: 'high' } );\n * ```\n *\n * Example flow for selection in text:\n *\n * ```xml\n * <blockquote><p>Foo[]bar</p></blockquote>\n * ```\n *\n * Fired events on contexts:\n * 1. `'$capture'`\n * 2. `'$text'`\n * 3. `'p'`\n * 4. `'blockquote'`\n * 5. `'$root'`\n * 6. `'$document'`\n *\n * Example flow for selection on element (i.e., Widget):\n *\n * ```xml\n * <blockquote><p>Foo[<widget/>]bar</p></blockquote>\n * ```\n *\n * Fired events on contexts:\n * 1. `'$capture'`\n * 2. *widget* (custom matcher)\n * 3. `'p'`\n * 4. `'blockquote'`\n * 5. `'$root'`\n * 6. `'$document'`\n *\n * There could be multiple listeners registered for the same context and at different priority levels:\n *\n * ```html\n * <p>Foo[]bar</p>\n * ```\n *\n * 1. `'$capture'` at priorities:\n *    1. `'highest'`\n *    2. `'high'`\n *    3. `'normal'`\n *    4. `'low'`\n *    5. `'lowest'`\n * 2. `'$text'` at priorities:\n *    1. `'highest'`\n *    2. `'high'`\n *    3. `'normal'`\n *    4. `'low'`\n *    5. `'lowest'`\n * 3. `'p'` at priorities:\n *    1. `'highest'`\n *    2. `'high'`\n *    3. `'normal'`\n *    4. `'low'`\n *    5. `'lowest'`\n * 4. `'$root'` at priorities:\n *    1. `'highest'`\n *    2. `'high'`\n *    3. `'normal'`\n *    4. `'low'`\n *    5. `'lowest'`\n * 5. `'$document'` at priorities:\n *    1. `'highest'`\n *    2. `'high'`\n *    3. `'normal'`\n *    4. `'low'`\n *    5. `'lowest'`\n */\nexport type BubblingEmitter = Emitter;\n\n/**\n * A context matcher function.\n *\n * Should return true for nodes that that match the custom context.\n */\nexport type BubblingEventContextFunction = ( node: Node ) => boolean;\n\n/**\n * Helper type that allows describing bubbling event. Extends `TEvent` so that:\n *\n * * the event is called with {@link module:engine/view/observer/bubblingeventinfo~BubblingEventInfo}`\n * instead of {@link module:utils/eventinfo~EventInfo}, and\n * * {@link ~BubblingCallbackOptions} can be specified as additional options.\n *\n * @typeParam TEvent The event description to extend.\n */\nexport type BubblingEvent<TEvent extends BaseEvent> = TEvent & {\n\teventInfo: BubblingEventInfo<TEvent[ 'name' ], ( TEvent extends { return: infer TReturn } ? TReturn : unknown )>;\n\tcallbackOptions: BubblingCallbackOptions;\n};\n\n/**\n * Additional options for registering a callback.\n */\nexport interface BubblingCallbackOptions extends CallbackOptions {\n\n\t/**\n\t * Specifies the context in which the event should be triggered to call the callback.\n\t *\n\t * @see ~BubblingEmitter\n\t */\n\tcontext?: ArrayOrItem<string | BubblingEventContextFunction>;\n}\n\ntype BubblingEventContexts = Map<string | BubblingEventContextFunction, Emitter>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/document\n */\n\nimport DocumentSelection from './documentselection.js';\nimport BubblingEmitterMixin from './observer/bubblingemittermixin.js';\n\nimport { Collection, ObservableMixin } from '@ckeditor/ckeditor5-utils';\n\nimport type { StylesProcessor } from './stylesmap.js';\nimport type RootEditableElement from './rooteditableelement.js';\nimport type DowncastWriter from './downcastwriter.js';\n\n// @if CK_DEBUG_ENGINE // const { logDocument } = require( '../dev-utils/utils' );\n\n/**\n * Document class creates an abstract layer over the content editable area, contains a tree of view elements and\n * {@link module:engine/view/documentselection~DocumentSelection view selection} associated with this document.\n */\nexport default class Document extends /* #__PURE__ */ BubblingEmitterMixin( /* #__PURE__ */ ObservableMixin() ) {\n\t/**\n\t * Selection done on this document.\n\t */\n\tpublic readonly selection: DocumentSelection;\n\n\t/**\n\t * Roots of the view tree. Collection of the {@link module:engine/view/element~Element view elements}.\n\t *\n\t * View roots are created as a result of binding between {@link module:engine/view/document~Document#roots} and\n\t * {@link module:engine/model/document~Document#roots} and this is handled by\n\t * {@link module:engine/controller/editingcontroller~EditingController}, so to create view root we need to create\n\t * model root using {@link module:engine/model/document~Document#createRoot}.\n\t */\n\tpublic readonly roots: Collection<RootEditableElement>;\n\n\t/**\n\t * The styles processor instance used by this document when normalizing styles.\n\t */\n\tpublic readonly stylesProcessor: StylesProcessor;\n\n\t/**\n\t * Defines whether document is in read-only mode.\n\t *\n\t * When document is read-ony then all roots are read-only as well and caret placed inside this root is hidden.\n\t *\n\t * @observable\n\t */\n\tdeclare public isReadOnly: boolean;\n\n\t/**\n\t * True if document is focused.\n\t *\n\t * This property is updated by the {@link module:engine/view/observer/focusobserver~FocusObserver}.\n\t * If the {@link module:engine/view/observer/focusobserver~FocusObserver} is disabled this property will not change.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isFocused: boolean;\n\n\t/**\n\t * `true` while the user is making a selection in the document (e.g. holding the mouse button and moving the cursor).\n\t * When they stop selecting, the property goes back to `false`.\n\t *\n\t * This property is updated by the {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isSelecting: boolean;\n\n\t/**\n\t * True if composition is in progress inside the document.\n\t *\n\t * This property is updated by the {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n\t * If the {@link module:engine/view/observer/compositionobserver~CompositionObserver} is disabled this property will not change.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isComposing: boolean;\n\n\t/**\n\t * Post-fixer callbacks registered to the view document.\n\t */\n\tprivate readonly _postFixers = new Set<ViewDocumentPostFixer>();\n\n\t/**\n\t * Creates a Document instance.\n\t *\n\t * @param stylesProcessor The styles processor instance.\n\t */\n\tconstructor( stylesProcessor: StylesProcessor ) {\n\t\tsuper();\n\n\t\tthis.selection = new DocumentSelection();\n\t\tthis.roots = new Collection( { idProperty: 'rootName' } );\n\t\tthis.stylesProcessor = stylesProcessor;\n\n\t\tthis.set( 'isReadOnly', false );\n\t\tthis.set( 'isFocused', false );\n\t\tthis.set( 'isSelecting', false );\n\t\tthis.set( 'isComposing', false );\n\t}\n\n\t/**\n\t * Gets a {@link module:engine/view/document~Document#roots view root element} with the specified name. If the name is not\n\t * specific \"main\" root is returned.\n\t *\n\t * @param name Name of the root.\n\t * @returns The view root element with the specified name or null when there is no root of given name.\n\t */\n\tpublic getRoot( name: string = 'main' ): RootEditableElement | null {\n\t\treturn this.roots.get( name );\n\t}\n\n\t/**\n\t * Allows registering post-fixer callbacks. A post-fixers mechanism allows to update the view tree just before it is rendered\n\t * to the DOM.\n\t *\n\t * Post-fixers are executed right after all changes from the outermost change block were applied but\n\t * before the {@link module:engine/view/view~View#event:render render event} is fired. If a post-fixer callback made\n\t * a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t * not be fixed in the new document tree state.\n\t *\n\t * View post-fixers are useful when you want to apply some fixes whenever the view structure changes. Keep in mind that\n\t * changes executed in a view post-fixer should not break model-view mapping.\n\t *\n\t * The types of changes which should be safe:\n\t *\n\t * * adding or removing attribute from elements,\n\t * * changes inside of {@link module:engine/view/uielement~UIElement UI elements},\n\t * * {@link module:engine/controller/editingcontroller~EditingController#reconvertItem marking some of the model elements to be\n\t * re-converted}.\n\t *\n\t * Try to avoid changes which touch view structure:\n\t *\n\t * * you should not add or remove nor wrap or unwrap any view elements,\n\t * * you should not change the editor data model in a view post-fixer.\n\t *\n\t * As a parameter, a post-fixer callback receives a {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}.\n\t *\n\t * Typically, a post-fixer will look like this:\n\t *\n\t * ```ts\n\t * editor.editing.view.document.registerPostFixer( writer => {\n\t * \tif ( checkSomeCondition() ) {\n\t * \t\twriter.doSomething();\n\t *\n\t * \t\t// Let other post-fixers know that something changed.\n\t * \t\treturn true;\n\t * \t}\n\t *\n\t * \treturn false;\n\t * } );\n\t * ```\n\t *\n\t * Note that nothing happens right after you register a post-fixer (e.g. execute such a code in the console).\n\t * That is because adding a post-fixer does not execute it.\n\t * The post-fixer will be executed as soon as any change in the document needs to cause its rendering.\n\t * If you want to re-render the editor's view after registering the post-fixer then you should do it manually by calling\n\t * {@link module:engine/view/view~View#forceRender `view.forceRender()`}.\n\t *\n\t * If you need to register a callback which is executed when DOM elements are already updated,\n\t * use {@link module:engine/view/view~View#event:render render event}.\n\t */\n\tpublic registerPostFixer( postFixer: ViewDocumentPostFixer ): void {\n\t\tthis._postFixers.add( postFixer );\n\t}\n\n\t/**\n\t * Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t */\n\tpublic destroy(): void {\n\t\tthis.roots.forEach( root => root.destroy() );\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t *\n\t * @internal\n\t */\n\tpublic _callPostFixers( writer: DowncastWriter ): void {\n\t\tlet wasFixed = false;\n\n\t\tdo {\n\t\t\tfor ( const callback of this._postFixers ) {\n\t\t\t\twasFixed = callback( writer );\n\n\t\t\t\tif ( wasFixed ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} while ( wasFixed );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public log( version: any ): void {\n\t// @if CK_DEBUG_ENGINE // \tlogDocument( this, version );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n/**\n * Document PostFixer.\n *\n * @see module:engine/view/document~Document#registerPostFixer\n */\nexport type ViewDocumentPostFixer = ( writer: DowncastWriter ) => boolean;\n\n/**\n * Enum representing type of the change.\n *\n * Possible values:\n *\n * * `children` - for child list changes,\n * * `attributes` - for element attributes changes,\n * * `text` - for text nodes changes.\n */\nexport type ChangeType = 'children' | 'attributes' | 'text';\n\n/**\n * Event fired whenever document content layout changes. It is fired whenever content is\n * {@link module:engine/view/view~View#event:render rendered}, but should be also fired by observers in case of\n * other actions which may change layout, for instance when image loads.\n *\n * @eventName ~Document#layoutChanged\n */\nexport type ViewDocumentLayoutChangedEvent = {\n\tname: 'layoutChanged';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/attributeelement\n */\n\nimport Element, { type ElementAttributes } from './element.js';\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type DocumentFragment from './documentfragment.js';\nimport type Document from './document.js';\nimport type Node from './node.js';\n\n// Default attribute priority.\nconst DEFAULT_PRIORITY = 10;\n\n/**\n * Attribute elements are used to represent formatting elements in the view (think – `<b>`, `<span style=\"font-size: 2em\">`, etc.).\n * Most often they are created when downcasting model text attributes.\n *\n * Editing engine does not define a fixed HTML DTD. This is why a feature developer needs to choose between various\n * types (container element, {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element}, etc) when developing a feature.\n *\n * To create a new attribute element instance use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement `DowncastWriter#createAttributeElement()`} method.\n */\nexport default class AttributeElement extends Element {\n\tpublic static readonly DEFAULT_PRIORITY: number = DEFAULT_PRIORITY;\n\n\t/**\n\t * Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t *\n\t * @internal\n\t * @readonly\n\t */\n\tpublic _priority: number = DEFAULT_PRIORITY;\n\n\t/**\n\t * Element identifier. If set, it is used by {@link module:engine/view/element~Element#isSimilar},\n\t * and then two elements are considered similar if, and only if they have the same `_id`.\n\t *\n\t * @internal\n\t * @readonly\n\t */\n\tpublic _id: string | number | null = null;\n\n\t/**\n\t * Keeps all the attribute elements that have the same {@link module:engine/view/attributeelement~AttributeElement#id ids}\n\t * and still exist in the view tree.\n\t *\n\t * This property is managed by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t */\n\tprivate readonly _clonesGroup: Set<AttributeElement> | null = null;\n\n\t/**\n\t * Creates an attribute element.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createAttributeElement\n\t * @see module:engine/view/element~Element\n\t * @protected\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string,\n\t\tattrs?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t) {\n\t\tsuper( document, name, attrs, children );\n\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * Element priority. Decides in what order elements are wrapped by {@link module:engine/view/downcastwriter~DowncastWriter}.\n\t */\n\tpublic get priority(): number {\n\t\treturn this._priority;\n\t}\n\n\t/**\n\t * Element identifier. If set, it is used by {@link module:engine/view/element~Element#isSimilar},\n\t * and then two elements are considered similar if, and only if they have the same `id`.\n\t */\n\tpublic get id(): string | number | null {\n\t\treturn this._id;\n\t}\n\n\t/**\n\t * Returns all {@link module:engine/view/attributeelement~AttributeElement attribute elements} that has the\n\t * same {@link module:engine/view/attributeelement~AttributeElement#id id} and are in the view tree (were not removed).\n\t *\n\t * Note: If this element has been removed from the tree, returned set will not include it.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError attribute-element-get-elements-with-same-id-no-id}\n\t * if this element has no `id`.\n\t *\n\t * @returns Set containing all the attribute elements\n\t * with the same `id` that were added and not removed from the view tree.\n\t */\n\tpublic getElementsWithSameId(): Set<AttributeElement> {\n\t\tif ( this.id === null ) {\n\t\t\t/**\n\t\t\t * Cannot get elements with the same id for an attribute element without id.\n\t\t\t *\n\t\t\t * @error attribute-element-get-elements-with-same-id-no-id\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'attribute-element-get-elements-with-same-id-no-id',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\treturn new Set( this._clonesGroup );\n\t}\n\n\t/**\n\t * Checks if this element is similar to other element.\n\t *\n\t * If none of elements has set {@link module:engine/view/attributeelement~AttributeElement#id}, then both elements\n\t * should have the same name, attributes and priority to be considered as similar. Two similar elements can contain\n\t * different set of children nodes.\n\t *\n\t * If at least one element has {@link module:engine/view/attributeelement~AttributeElement#id} set, then both\n\t * elements have to have the same {@link module:engine/view/attributeelement~AttributeElement#id} value to be\n\t * considered similar.\n\t *\n\t * Similarity is important for {@link module:engine/view/downcastwriter~DowncastWriter}. For example:\n\t *\n\t * * two following similar elements can be merged together into one, longer element,\n\t * * {@link module:engine/view/downcastwriter~DowncastWriter#unwrap} checks similarity of passed element and processed element to\n\t * decide whether processed element should be unwrapped,\n\t * * etc.\n\t */\n\tpublic override isSimilar( otherElement: Element ): boolean {\n\t\t// If any element has an `id` set, just compare the ids.\n\t\tif ( this.id !== null || ( otherElement as any ).id !== null ) {\n\t\t\treturn this.id === ( otherElement as any ).id;\n\t\t}\n\n\t\treturn super.isSimilar( otherElement ) && this.priority == ( otherElement as any ).priority;\n\t}\n\n\t/**\n\t * Clones provided element with priority.\n\t *\n\t * @internal\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns Clone of this element.\n\t */\n\tpublic override _clone( deep: boolean = false ): this {\n\t\tconst cloned = super._clone( deep );\n\n\t\t// Clone priority too.\n\t\tcloned._priority = this._priority;\n\n\t\t// And id too.\n\t\tcloned._id = this._id;\n\n\t\treturn cloned;\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nAttributeElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'attributeElement' || type === 'view:attributeElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && (\n\t\t\ttype === 'attributeElement' || type === 'view:attributeElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'element' || type === 'view:element'\n\t\t);\n\t}\n};\n\n/**\n * Returns block {@link module:engine/view/filler~Filler filler} offset or `null` if block filler is not needed.\n *\n * @returns Block filler offset or `null` if block filler is not needed.\n */\nfunction getFillerOffset( this: AttributeElement ): number | null {\n\t// <b>foo</b> does not need filler.\n\tif ( nonUiChildrenCount( this ) ) {\n\t\treturn null;\n\t}\n\n\tlet element = this.parent;\n\n\t// <p><b></b></p> needs filler -> <p><b><br></b></p>\n\twhile ( element && element.is( 'attributeElement' ) ) {\n\t\tif ( nonUiChildrenCount( element ) > 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\telement = element.parent;\n\t}\n\n\tif ( !element || nonUiChildrenCount( element ) > 1 ) {\n\t\treturn null;\n\t}\n\n\t// Render block filler at the end of element (after all ui elements).\n\treturn this.childCount;\n}\n\n/**\n * Returns total count of children that are not {@link module:engine/view/uielement~UIElement UIElements}.\n */\nfunction nonUiChildrenCount( element: Element | DocumentFragment ): number {\n\treturn Array.from( element.getChildren() ).filter( element => !element.is( 'uiElement' ) ).length;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/emptyelement\n */\n\nimport Element, { type ElementAttributes } from './element.js';\nimport Node from './node.js';\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type Document from './document.js';\nimport type Item from './item.js';\n\n/**\n * Empty element class. It is used to represent elements that cannot contain any child nodes (for example `<img>` elements).\n *\n * To create a new empty element use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement `downcastWriter#createEmptyElement()`} method.\n */\nexport default class EmptyElement extends Element {\n\t/**\n\t * Creates new instance of EmptyElement.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` when third parameter is passed,\n\t * to inform that usage of EmptyElement is incorrect (adding child nodes to EmptyElement is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createEmptyElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t) {\n\t\tsuper( document, name, attributes, children );\n\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * Overrides {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-emptyelement-cannot-add` to prevent\n\t * adding any child nodes to EmptyElement.\n\t *\n\t * @internal\n\t */\n\tpublic override _insertChild( index: number, items: Item | Iterable<Item> ): number {\n\t\tif ( items && ( items instanceof Node || Array.from( items as Iterable<Item> ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to {@link module:engine/view/emptyelement~EmptyElement}.\n\t\t\t *\n\t\t\t * @error view-emptyelement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-emptyelement-cannot-add',\n\t\t\t\t[ this, items ]\n\t\t\t);\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nEmptyElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'emptyElement' || type === 'view:emptyElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && (\n\t\t\ttype === 'emptyElement' || type === 'view:emptyElement' ||\n\t\t\ttype === 'element' || type === 'view:element'\n\t\t);\n\t}\n};\n\n/**\n * Returns `null` because block filler is not needed for EmptyElements.\n */\nfunction getFillerOffset() {\n\treturn null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/uielement\n */\n\nimport Element, { type ElementAttributes } from './element.js';\nimport Node from './node.js';\nimport { CKEditorError, keyCodes } from '@ckeditor/ckeditor5-utils';\n\nimport type View from './view.js';\nimport type Document from './document.js';\nimport type DomConverter from './domconverter.js';\nimport type Item from './item.js';\nimport type { ViewDocumentArrowKeyEvent } from './observer/arrowkeysobserver.js';\nimport type { KeyEventData } from './observer/keyobserver.js';\n\ntype DomDocument = globalThis.Document;\ntype DomElement = globalThis.HTMLElement;\n\n/**\n * UI element class. It should be used to represent editing UI which needs to be injected into the editing view\n * If possible, you should keep your UI outside the editing view. However, if that is not possible,\n * UI elements can be used.\n *\n * How a UI element is rendered is in your control (you pass a callback to\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}).\n * The editor will ignore your UI element – the selection cannot be placed in it, it is skipped (invisible) when\n * the user modifies the selection by using arrow keys and the editor does not listen to any mutations which\n * happen inside your UI elements.\n *\n * The limitation is that you cannot convert a model element to a UI element. UI elements need to be\n * created for {@link module:engine/model/markercollection~Marker markers} or as additinal elements\n * inside normal {@link module:engine/view/containerelement~ContainerElement container elements}.\n *\n * To create a new UI element use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`} method.\n */\nexport default class UIElement extends Element {\n\t/**\n\t * Creates new instance of UIElement.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` when third parameter is passed,\n\t * to inform that usage of UIElement is incorrect (adding child nodes to UIElement is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createUIElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string,\n\t\tattrs?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t) {\n\t\tsuper( document, name, attrs, children );\n\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * Overrides {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` to prevent adding any child nodes\n\t * to UIElement.\n\t *\n\t * @internal\n\t */\n\tpublic override _insertChild( index: number, items: Item | Iterable<Item> ): number {\n\t\tif ( items && ( items instanceof Node || Array.from( items as Iterable<Item> ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to {@link module:engine/view/uielement~UIElement}.\n\t\t\t *\n\t\t\t * @error view-uielement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-uielement-cannot-add', [ this, items ] );\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Renders this {@link module:engine/view/uielement~UIElement} to DOM. This method is called by\n\t * {@link module:engine/view/domconverter~DomConverter}.\n\t * Do not use inheritance to create custom rendering method, replace `render()` method instead:\n\t *\n\t * ```ts\n\t * const myUIElement = downcastWriter.createUIElement( 'span' );\n\t * myUIElement.render = function( domDocument, domConverter ) {\n\t * \tconst domElement = this.toDomElement( domDocument );\n\t *\n\t * \tdomConverter.setContentOf( domElement, '<b>this is ui element</b>' );\n\t *\n\t * \treturn domElement;\n\t * };\n\t * ```\n\t *\n\t * If changes in your UI element should trigger some editor UI update you should call\n\t * the {@link module:ui/editorui/editorui~EditorUI#update `editor.ui.update()`} method\n\t * after rendering your UI element.\n\t *\n\t * @param domConverter Instance of the DomConverter used to optimize the output.\n\t */\n\tpublic render(\n\t\tdomDocument: DomDocument,\n\t\tdomConverter: DomConverter // eslint-disable-line @typescript-eslint/no-unused-vars\n\t): DomElement {\n\t\t// Provide basic, default output.\n\t\treturn this.toDomElement( domDocument );\n\t}\n\n\t/**\n\t * Creates DOM element based on this view UIElement.\n\t * Note that each time this method is called new DOM element is created.\n\t */\n\tpublic toDomElement( domDocument: DomDocument ): DomElement {\n\t\tconst domElement = domDocument.createElement( this.name );\n\n\t\tfor ( const key of this.getAttributeKeys() ) {\n\t\t\tdomElement.setAttribute( key, this.getAttribute( key )! );\n\t\t}\n\n\t\treturn domElement;\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nUIElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'uiElement' || type === 'view:uiElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && (\n\t\t\ttype === 'uiElement' || type === 'view:uiElement' ||\n\t\t\ttype === 'element' || type === 'view:element'\n\t\t);\n\t}\n};\n\n/**\n * This function injects UI element handling to the given {@link module:engine/view/document~Document document}.\n *\n * A callback is added to {@link module:engine/view/document~Document#event:keydown document keydown event}.\n * The callback handles the situation when right arrow key is pressed and selection is collapsed before a UI element.\n * Without this handler, it would be impossible to \"jump over\" UI element using right arrow key.\n *\n * @param view View controller to which the quirks handling will be injected.\n */\nexport function injectUiElementHandling( view: View ): void {\n\tview.document.on<ViewDocumentArrowKeyEvent>( 'arrowKey', ( evt, data ) =>\n\t\tjumpOverUiElement( evt, data, view.domConverter ), { priority: 'low' } );\n}\n\n/**\n * Returns `null` because block filler is not needed for UIElements.\n */\nfunction getFillerOffset() {\n\treturn null;\n}\n\n/**\n * Selection cannot be placed in a `UIElement`. Whenever it is placed there, it is moved before it. This\n * causes a situation when it is impossible to jump over `UIElement` using right arrow key, because the selection\n * ends up in ui element (in DOM) and is moved back to the left. This handler fixes this situation.\n */\nfunction jumpOverUiElement( evt: unknown, data: KeyEventData, domConverter: DomConverter ) {\n\tif ( data.keyCode == keyCodes.arrowright ) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView!.getSelection()!;\n\t\tconst domSelectionCollapsed = domSelection.rangeCount == 1 && domSelection.getRangeAt( 0 ).collapsed;\n\n\t\t// Jump over UI element if selection is collapsed or shift key is pressed. These are the cases when selection would extend.\n\t\tif ( domSelectionCollapsed || data.shiftKey ) {\n\t\t\tconst domParent = domSelection.focusNode!;\n\t\t\tconst domOffset = domSelection.focusOffset;\n\n\t\t\tconst viewPosition = domConverter.domPositionToView( domParent, domOffset );\n\n\t\t\t// In case if dom element is not converted to view or is not mapped or something. Happens for example in some tests.\n\t\t\tif ( viewPosition === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip all following ui elements.\n\t\t\tlet jumpedOverAnyUiElement = false;\n\n\t\t\tconst nextViewPosition = viewPosition.getLastMatchingPosition( value => {\n\t\t\t\tif ( value.item.is( 'uiElement' ) ) {\n\t\t\t\t\t// Remember that there was at least one ui element.\n\t\t\t\t\tjumpedOverAnyUiElement = true;\n\t\t\t\t}\n\n\t\t\t\t// Jump over ui elements, jump over empty attribute elements, move up from inside of attribute element.\n\t\t\t\tif ( value.item.is( 'uiElement' ) || value.item.is( 'attributeElement' ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// Don't jump over text or don't get out of container element.\n\t\t\t\treturn false;\n\t\t\t} );\n\n\t\t\t// If anything has been skipped, fix position.\n\t\t\t// This `if` could be possibly omitted but maybe it is better not to mess with DOM selection if not needed.\n\t\t\tif ( jumpedOverAnyUiElement ) {\n\t\t\t\tconst newDomPosition = domConverter.viewPositionToDom( nextViewPosition )!;\n\n\t\t\t\tif ( domSelectionCollapsed ) {\n\t\t\t\t\t// Selection was collapsed, so collapse it at further position.\n\t\t\t\t\tdomSelection.collapse( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t} else {\n\t\t\t\t\t// Selection was not collapse, so extend it instead of collapsing.\n\t\t\t\t\tdomSelection.extend( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/**\n * @module engine/view/rawelement\n */\n\nimport Element, { type ElementAttributes } from './element.js';\nimport Node from './node.js';\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type Document from './document.js';\nimport type DomConverter from './domconverter.js';\nimport type Item from './item.js';\n\ntype DomElement = globalThis.HTMLElement;\n\n/**\n * The raw element class.\n *\n * The raw elements work as data containers (\"wrappers\", \"sandboxes\") but their children are not managed or\n * even recognized by the editor. This encapsulation allows integrations to maintain custom DOM structures\n * in the editor content without, for instance, worrying about compatibility with other editor features.\n * Raw elements are a perfect tool for integration with external frameworks and data sources.\n *\n * Unlike {@link module:engine/view/uielement~UIElement UI elements}, raw elements act like real editor\n * content (similar to {@link module:engine/view/containerelement~ContainerElement} or\n * {@link module:engine/view/emptyelement~EmptyElement}), they are considered by the editor selection and\n * {@link module:widget/utils~toWidget they can work as widgets}.\n *\n * To create a new raw element, use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createRawElement `downcastWriter#createRawElement()`} method.\n */\nexport default class RawElement extends Element {\n\t/**\n\t * Creates a new instance of a raw element.\n\t *\n\t * Throws the `view-rawelement-cannot-add` {@link module:utils/ckeditorerror~CKEditorError CKEditorError} when the `children`\n\t * parameter is passed to inform that the usage of `RawElement` is incorrect (adding child nodes to `RawElement` is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createRawElement\n\t * @internal\n\t * @param document The document instance to which this element belongs.\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\tname: string,\n\t\tattrs?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t) {\n\t\tsuper( document, name, attrs, children );\n\n\t\t// Returns `null` because filler is not needed for raw elements.\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * Overrides the {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws the `view-rawelement-cannot-add` {@link module:utils/ckeditorerror~CKEditorError CKEditorError} to prevent\n\t * adding any child nodes to a raw element.\n\t *\n\t * @internal\n\t */\n\tpublic override _insertChild( index: number, items: Item | Iterable<Item> ): number {\n\t\tif ( items && ( items instanceof Node || Array.from( items as Iterable<Item> ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to a {@link module:engine/view/rawelement~RawElement} instance.\n\t\t\t *\n\t\t\t * @error view-rawelement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-rawelement-cannot-add',\n\t\t\t\t[ this, items ]\n\t\t\t);\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/**\n\t * This allows rendering the children of a {@link module:engine/view/rawelement~RawElement} on the DOM level.\n\t * This method is called by the {@link module:engine/view/domconverter~DomConverter} with the raw DOM element\n\t * passed as an argument, leaving the number and shape of the children up to the integrator.\n\t *\n\t * This method **must be defined** for the raw element to work:\n\t *\n\t * ```ts\n\t * const myRawElement = downcastWriter.createRawElement( 'div' );\n\t *\n\t * myRawElement.render = function( domElement, domConverter ) {\n\t * \tdomConverter.setContentOf( domElement, '<b>This is the raw content of myRawElement.</b>' );\n\t * };\n\t * ```\n\t *\n\t * @param domElement The native DOM element representing the raw view element.\n\t * @param domConverter Instance of the DomConverter used to optimize the output.\n\t */\n\tpublic render( domElement: DomElement, domConverter: DomConverter ): void {}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRawElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'rawElement' || type === 'view:rawElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === this.name || type === 'view:' + this.name ||\n\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\ttype === 'node' || type === 'view:node';\n\t} else {\n\t\treturn name === this.name && (\n\t\t\ttype === 'rawElement' || type === 'view:rawElement' ||\n\t\t\ttype === 'element' || type === 'view:element'\n\t\t);\n\t}\n};\n\n/**\n * Returns `null` because block filler is not needed for raw elements.\n */\nfunction getFillerOffset() {\n\treturn null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/documentfragment\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport Text from './text.js';\nimport TextProxy from './textproxy.js';\n\nimport { EmitterMixin, isIterable } from '@ckeditor/ckeditor5-utils';\n\nimport type { default as Document, ChangeType } from './document.js';\n\nimport type Item from './item.js';\nimport type Node from './node.js';\n\n/**\n * Document fragment.\n *\n * To create a new document fragment instance use the\n * {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment `UpcastWriter#createDocumentFragment()`}\n * method.\n */\nexport default class DocumentFragment extends /* #__PURE__ */ EmitterMixin( TypeCheckable ) implements Iterable<Node> {\n\t/**\n\t * The document to which this document fragment belongs.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * Array of child nodes.\n\t */\n\tprivate readonly _children: Array<Node> = [];\n\n\t/**\n\t * Map of custom properties.\n\t * Custom properties can be added to document fragment instance.\n\t */\n\tprivate readonly _customProperties = new Map<string | symbol, unknown>();\n\n\t/**\n\t * Creates new DocumentFragment instance.\n\t *\n\t * @internal\n\t * @param document The document to which this document fragment belongs.\n\t * @param children A list of nodes to be inserted into the created document fragment.\n\t */\n\tconstructor( document: Document, children?: Node | Iterable<Node> ) {\n\t\tsuper();\n\n\t\tthis.document = document;\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over nodes added to this document fragment.\n\t */\n\tpublic [ Symbol.iterator ](): Iterator<Node> {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Number of child nodes in this document fragment.\n\t */\n\tpublic get childCount(): number {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t */\n\tpublic get isEmpty(): boolean {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t */\n\tpublic get root(): this {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t */\n\tpublic get parent(): null {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Artificial element name. Returns `undefined`. Added for compatibility reasons.\n\t */\n\tpublic get name(): undefined {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Artificial element getFillerOffset. Returns `undefined`. Added for compatibility reasons.\n\t */\n\tpublic get getFillerOffset(): undefined {\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Returns the custom property value for the given key.\n\t */\n\tpublic getCustomProperty( key: string | symbol ): unknown {\n\t\treturn this._customProperties.get( key );\n\t}\n\n\t/**\n\t * Returns an iterator which iterates over this document fragment's custom properties.\n\t * Iterator provides `[ key, value ]` pairs for each stored property.\n\t */\n\tpublic* getCustomProperties(): Iterable<[ string | symbol, unknown ]> {\n\t\tyield* this._customProperties.entries();\n\t}\n\n\t/**\n\t * {@link module:engine/view/documentfragment~DocumentFragment#_insertChild Insert} a child node or a list of child nodes at the end\n\t * and sets the parent of these nodes to this fragment.\n\t *\n\t * @internal\n\t * @param items Items to be inserted.\n\t * @returns Number of appended nodes.\n\t */\n\tpublic _appendChild( items: Item | string | Iterable<Item | string> ): number {\n\t\treturn this._insertChild( this.childCount, items );\n\t}\n\n\t/**\n\t * Gets child at the given index.\n\t *\n\t * @param index Index of child.\n\t * @returns Child node.\n\t */\n\tpublic getChild( index: number ): Node {\n\t\treturn this._children[ index ];\n\t}\n\n\t/**\n\t * Gets index of the given child node. Returns `-1` if child node is not found.\n\t *\n\t * @param node Child node.\n\t * @returns Index of the child node.\n\t */\n\tpublic getChildIndex( node: Node ): number {\n\t\treturn this._children.indexOf( node );\n\t}\n\n\t/**\n\t * Gets child nodes iterator.\n\t *\n\t * @returns Child nodes iterator.\n\t */\n\tpublic getChildren(): IterableIterator<Node> {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this fragment.\n\t *\n\t * @internal\n\t * @param index Position where nodes should be inserted.\n\t * @param items Items to be inserted.\n\t * @returns Number of inserted nodes.\n\t */\n\tpublic _insertChild( index: number, items: Item | string | Iterable<Item | string> ): number {\n\t\tthis._fireChange( 'children', this );\n\t\tlet count = 0;\n\n\t\tconst nodes = normalize( this.document, items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\t( node as any ).parent = this;\n\n\t\t\tthis._children.splice( index, 0, node );\n\t\t\tindex++;\n\t\t\tcount++;\n\t\t}\n\n\t\treturn count;\n\t}\n\n\t/**\n\t * Removes number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @internal\n\t * @param index Number of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns The array of removed nodes.\n\t */\n\tpublic _removeChildren( index: number, howMany: number = 1 ): Array<Node> {\n\t\tthis._fireChange( 'children', this );\n\n\t\tfor ( let i = index; i < index + howMany; i++ ) {\n\t\t\t( this._children[ i ] as any ).parent = null;\n\t\t}\n\n\t\treturn this._children.splice( index, howMany );\n\t}\n\n\t/**\n\t * Fires `change` event with given type of the change.\n\t *\n\t * @internal\n\t * @param type Type of the change.\n\t * @param node Changed node.\n\t */\n\tpublic _fireChange( type: ChangeType, node: Node | DocumentFragment ): void {\n\t\tthis.fire( 'change:' + type, node );\n\t}\n\n\t/**\n\t * Sets a custom property. They can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#setCustomProperty\n\t * @internal\n\t */\n\tpublic _setCustomProperty( key: string | symbol, value: unknown ): void {\n\t\tthis._customProperties.set( key, value );\n\t}\n\n\t/**\n\t * Removes the custom property stored under the given key.\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#removeCustomProperty\n\t * @internal\n\t * @returns Returns true if property was removed.\n\t */\n\tpublic _removeCustomProperty( key: string | symbol ): boolean {\n\t\treturn this._customProperties.delete( key );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public printTree(): string {\n\t// @if CK_DEBUG_ENGINE // \tlet string = 'ViewDocumentFragment: [';\n\n\t// @if CK_DEBUG_ENGINE // \tfor ( const child of this.getChildren() as any ) {\n\t// @if CK_DEBUG_ENGINE // \t\tif ( child.is( '$text' ) ) {\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += '\\n' + '\\t'.repeat( 1 ) + child.data;\n\t// @if CK_DEBUG_ENGINE // \t\t} else {\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += '\\n' + child.printTree( 1 );\n\t// @if CK_DEBUG_ENGINE // \t\t}\n\t// @if CK_DEBUG_ENGINE // \t}\n\n\t// @if CK_DEBUG_ENGINE // \tstring += '\\n]';\n\n\t// @if CK_DEBUG_ENGINE // \treturn string;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logTree(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( this.printTree() );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentFragment.prototype.is = function( type: string ): boolean {\n\treturn type === 'documentFragment' || type === 'view:documentFragment';\n};\n\n/**\n * Converts strings to Text and non-iterables to arrays.\n */\nfunction normalize( document: Document, nodes: Item | string | Iterable<Item | string> ): Array<Node> {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( document, nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( document, node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( document, node.data );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/downcastwriter\n */\n\nimport Position, { type PositionOffset } from './position.js';\nimport Range from './range.js';\nimport Selection, {\n\ttype PlaceOrOffset,\n\ttype Selectable,\n\ttype SelectionOptions\n} from './selection.js';\nimport ContainerElement from './containerelement.js';\nimport AttributeElement from './attributeelement.js';\nimport EmptyElement from './emptyelement.js';\nimport UIElement from './uielement.js';\nimport RawElement from './rawelement.js';\nimport { CKEditorError, isIterable } from '@ckeditor/ckeditor5-utils';\nimport DocumentFragment from './documentfragment.js';\nimport Text from './text.js';\nimport EditableElement from './editableelement.js';\nimport { isPlainObject } from 'lodash-es';\n\nimport type Document from './document.js';\nimport type Node from './node.js';\nimport type { default as Element, ElementAttributes } from './element.js';\nimport type DomConverter from './domconverter.js';\nimport type Item from './item.js';\nimport type { SlotFilter } from '../conversion/downcasthelpers.js';\n\ntype DomDocument = globalThis.Document;\ntype DomElement = globalThis.HTMLElement;\n\n/**\n * View downcast writer.\n *\n * It provides a set of methods used to manipulate view nodes.\n *\n * Do not create an instance of this writer manually. To modify a view structure, use\n * the {@link module:engine/view/view~View#change `View#change()`} block.\n *\n * The `DowncastWriter` is designed to work with semantic views which are the views that were/are being downcasted from the model.\n * To work with ordinary views (e.g. parsed from a pasted content) use the\n * {@link module:engine/view/upcastwriter~UpcastWriter upcast writer}.\n *\n * Read more about changing the view in the {@glink framework/architecture/editing-engine#changing-the-view Changing the view}\n * section of the {@glink framework/architecture/editing-engine Editing engine architecture} guide.\n */\nexport default class DowncastWriter {\n\t/**\n\t * The view document instance in which this writer operates.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * Holds references to the attribute groups that share the same {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t * The keys are `id`s, the values are `Set`s holding {@link module:engine/view/attributeelement~AttributeElement}s.\n\t */\n\tprivate readonly _cloneGroups = new Map<string | number, Set<AttributeElement>>();\n\n\t/**\n\t * The slot factory used by the `elementToStructure` downcast helper.\n\t */\n\tprivate _slotFactory: ( ( writer: DowncastWriter, modeOrFilter: 'children' | SlotFilter ) => Element ) | null = null;\n\n\t/**\n\t * @param document The view document instance.\n\t */\n\tconstructor( document: Document ) {\n\t\tthis.document = document;\n\t}\n\n\t/**\n\t * Sets {@link module:engine/view/documentselection~DocumentSelection selection's} ranges and direction to the\n\t * specified location based on the given {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t * Usage:\n\t *\n\t * ```ts\n\t * // Sets collapsed selection at the position of given item and offset.\n\t * const paragraph = writer.createContainerElement( 'p' );\n\t * writer.setSelection( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * writer.setSelection( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on the {@link module:engine/view/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * writer.setSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `DowncastWriter#setSelection()` allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * writer.setSelection( element, 'in', { backward: true } );\n\t *\n\t * // Sets selection as fake.\n\t * // Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * // This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * // represented in other way, for example by applying proper CSS class.\n\t * writer.setSelection( element, 'in', { fake: true } );\n\t *\n\t * // Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * // (and be  properly handled by screen readers).\n\t * writer.setSelection( element, 'in', { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #setSelection:SELECTABLE `setSelection( selectable, options )`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic setSelection( selectable: Node, placeOrOffset: PlaceOrOffset, options?: SelectionOptions ): void;\n\n\t/**\n\t * Sets {@link module:engine/view/documentselection~DocumentSelection selection's} ranges and direction to the\n\t * specified location based on the given {@link module:engine/view/selection~Selectable selectable}.\n\t *\n\t * Usage:\n\t *\n\t * ```ts\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * writer.setSelection( range );\n\t *\n\t * // Sets backward selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * writer.setSelection( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( start2, end2 ) ];\n\t * writer.setSelection( range );\n\t *\n\t * // Sets selection to the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * writer.setSelection( otherSelection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * writer.setSelection( position );\n\t *\n\t * // Removes all ranges.\n\t * writer.setSelection( null );\n\t * ```\n\t *\n\t * `DowncastWriter#setSelection()` allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * writer.setSelection( range, { backward: true } );\n\t *\n\t * // Sets selection as fake.\n\t * // Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * // This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * // represented in other way, for example by applying proper CSS class.\n\t * writer.setSelection( range, { fake: true } );\n\t *\n\t * // Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * // (and be  properly handled by screen readers).\n\t * writer.setSelection( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #setSelection:NODE_OFFSET `setSelection( node, placeOrOffset, options )`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic setSelection( selectable: Exclude<Selectable, Node>, options?: SelectionOptions ): void;\n\n\tpublic setSelection( ...args: Parameters<Selection[ 'setTo' ]> ): void {\n\t\tthis.document.selection._setTo( ...args );\n\t}\n\n\t/**\n\t * Moves {@link module:engine/view/documentselection~DocumentSelection#focus selection's focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as {@link module:engine/view/view~View#createPositionAt view.createPositionAt()}\n\t * parameters.\n\t *\n\t * @param Offset or one of the flags. Used only when the first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tpublic setSelectionFocus( itemOrPosition: Item | Position, offset?: PositionOffset ): void {\n\t\tthis.document.selection._setFocus( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance.\n\t *\n\t * @param children A list of nodes to be inserted into the created document fragment.\n\t * @returns The created document fragment.\n\t */\n\tpublic createDocumentFragment( children?: Node | Iterable<Node> ): DocumentFragment {\n\t\treturn new DocumentFragment( this.document, children );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/text~Text text node}.\n\t *\n\t * ```ts\n\t * writer.createText( 'foo' );\n\t * ```\n\t *\n\t * @param data The text's data.\n\t * @returns The created text node.\n\t */\n\tpublic createText( data: string ): Text {\n\t\treturn new Text( this.document, data );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/attributeelement~AttributeElement}.\n\t *\n\t * ```ts\n\t * writer.createAttributeElement( 'strong' );\n\t * writer.createAttributeElement( 'a', { href: 'foo.bar' } );\n\t *\n\t * // Make `<a>` element contain other attributes element so the `<a>` element is not broken.\n\t * writer.createAttributeElement( 'a', { href: 'foo.bar' }, { priority: 5 } );\n\t *\n\t * // Set `id` of a marker element so it is not joined or merged with \"normal\" elements.\n\t * writer.createAttributeElement( 'span', { class: 'my-marker' }, { id: 'marker:my' } );\n\t * ```\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Element's attributes.\n\t * @param options Element's options.\n\t * @param options.priority Element's {@link module:engine/view/attributeelement~AttributeElement#priority priority}.\n\t * @param options.id Element's {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */\n\tpublic createAttributeElement(\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\toptions: {\n\t\t\tpriority?: number;\n\t\t\tid?: number | string;\n\t\t\trenderUnsafeAttributes?: Array<string>;\n\t\t} = {}\n\t): AttributeElement {\n\t\tconst attributeElement = new AttributeElement( this.document, name, attributes );\n\n\t\tif ( typeof options.priority === 'number' ) {\n\t\t\tattributeElement._priority = options.priority;\n\t\t}\n\n\t\tif ( options.id ) {\n\t\t\tattributeElement._id = options.id;\n\t\t}\n\n\t\tif ( options.renderUnsafeAttributes ) {\n\t\t\tattributeElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );\n\t\t}\n\n\t\treturn attributeElement;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/containerelement~ContainerElement}.\n\t *\n\t * ```ts\n\t * writer.createContainerElement( 'p' );\n\t *\n\t * // Create element with custom attributes.\n\t * writer.createContainerElement( 'div', { id: 'foo-bar', 'data-baz': '123' } );\n\t *\n\t * // Create element with custom styles.\n\t * writer.createContainerElement( 'p', { style: 'font-weight: bold; padding-bottom: 10px' } );\n\t *\n\t * // Create element with custom classes.\n\t * writer.createContainerElement( 'p', { class: 'foo bar baz' } );\n\t *\n\t * // Create element with specific options.\n\t * writer.createContainerElement( 'span', { class: 'placeholder' }, { renderUnsafeAttributes: [ 'foo' ] } );\n\t * ```\n\t *\n\t * @label WITHOUT_CHILDREN\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */\n\tpublic createContainerElement(\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\toptions?: { renderUnsafeAttributes?: Array<string> }\n\t): ContainerElement;\n\n\t/**\n\t * Creates a new {@link module:engine/view/containerelement~ContainerElement} with children.\n\t *\n\t * ```ts\n\t * // Create element with children.\n\t * writer.createContainerElement( 'figure', { class: 'image' }, [\n\t * \twriter.createEmptyElement( 'img' ),\n\t * \twriter.createContainerElement( 'figcaption' )\n\t * ] );\n\t *\n\t * // Create element with specific options.\n\t * writer.createContainerElement( 'figure', { class: 'image' }, [\n\t * \twriter.createEmptyElement( 'img' ),\n\t * \twriter.createContainerElement( 'figcaption' )\n\t * ], { renderUnsafeAttributes: [ 'foo' ] } );\n\t * ```\n\t *\n\t * @label WITH_CHILDREN\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @param children A node or a list of nodes to be inserted into the created element.\n\t * If no children were specified, element's `options` can be passed in this argument.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */\n\tpublic createContainerElement(\n\t\tname: string,\n\t\tattributes: ElementAttributes,\n\t\tchildren: Node | Iterable<Node>,\n\t\toptions?: { renderUnsafeAttributes?: Array<string> }\n\t): ContainerElement;\n\n\tpublic createContainerElement(\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\tchildrenOrOptions: Node | Iterable<Node> | { renderUnsafeAttributes?: Array<string> } = {},\n\t\toptions: { renderUnsafeAttributes?: Array<string> } = {}\n\t): ContainerElement {\n\t\tlet children = null;\n\n\t\tif ( isPlainObject( childrenOrOptions ) ) {\n\t\t\toptions = childrenOrOptions as { renderUnsafeAttributes?: Array<string> };\n\t\t} else {\n\t\t\tchildren = childrenOrOptions;\n\t\t}\n\n\t\tconst containerElement = new ContainerElement( this.document, name, attributes, children as Node | Iterable<Node> );\n\n\t\tif ( options.renderUnsafeAttributes ) {\n\t\t\tcontainerElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );\n\t\t}\n\n\t\treturn containerElement;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/editableelement~EditableElement}.\n\t *\n\t * ```ts\n\t * writer.createEditableElement( 'div' );\n\t * writer.createEditableElement( 'div', { id: 'foo-1234' } );\n\t * ```\n\t *\n\t * Note: The editable element is to be used in the editing pipeline. Usually, together with\n\t * {@link module:widget/utils~toWidgetEditable `toWidgetEditable()`}.\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */\n\tpublic createEditableElement(\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\toptions: {\n\t\t\trenderUnsafeAttributes?: Array<string>;\n\t\t} = {}\n\t): EditableElement {\n\t\tconst editableElement = new EditableElement( this.document, name, attributes );\n\n\t\tif ( options.renderUnsafeAttributes ) {\n\t\t\teditableElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );\n\t\t}\n\n\t\treturn editableElement;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/emptyelement~EmptyElement}.\n\t *\n\t * ```ts\n\t * writer.createEmptyElement( 'img' );\n\t * writer.createEmptyElement( 'img', { id: 'foo-1234' } );\n\t * ```\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns Created element.\n\t */\n\tpublic createEmptyElement(\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\toptions: {\n\t\t\trenderUnsafeAttributes?: Array<string>;\n\t\t} = {}\n\t): EmptyElement {\n\t\tconst emptyElement = new EmptyElement( this.document, name, attributes );\n\n\t\tif ( options.renderUnsafeAttributes ) {\n\t\t\temptyElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );\n\t\t}\n\n\t\treturn emptyElement;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/uielement~UIElement}.\n\t *\n\t * ```ts\n\t * writer.createUIElement( 'span' );\n\t * writer.createUIElement( 'span', { id: 'foo-1234' } );\n\t * ```\n\t *\n\t * A custom render function can be provided as the third parameter:\n\t *\n\t * ```ts\n\t * writer.createUIElement( 'span', null, function( domDocument ) {\n\t * \tconst domElement = this.toDomElement( domDocument );\n\t * \tdomElement.innerHTML = '<b>this is ui element</b>';\n\t *\n\t * \treturn domElement;\n\t * } );\n\t * ```\n\t *\n\t * Unlike {@link #createRawElement raw elements}, UI elements are by no means editor content, for instance,\n\t * they are ignored by the editor selection system.\n\t *\n\t * You should not use UI elements as data containers. Check out {@link #createRawElement} instead.\n\t *\n\t * @param name The name of the element.\n\t * @param attributes Element attributes.\n\t * @param renderFunction A custom render function.\n\t * @returns The created element.\n\t */\n\tpublic createUIElement(\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\trenderFunction?: ( this: UIElement, domDocument: DomDocument, domConverter: DomConverter ) => DomElement\n\t): UIElement {\n\t\tconst uiElement = new UIElement( this.document, name, attributes );\n\n\t\tif ( renderFunction ) {\n\t\t\tuiElement.render = renderFunction;\n\t\t}\n\n\t\treturn uiElement;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/rawelement~RawElement}.\n\t *\n\t * ```ts\n\t * writer.createRawElement( 'span', { id: 'foo-1234' }, function( domElement ) {\n\t * \tdomElement.innerHTML = '<b>This is the raw content of the raw element.</b>';\n\t * } );\n\t * ```\n\t *\n\t * Raw elements work as data containers (\"wrappers\", \"sandboxes\") but their children are not managed or\n\t * even recognized by the editor. This encapsulation allows integrations to maintain custom DOM structures\n\t * in the editor content without, for instance, worrying about compatibility with other editor features.\n\t * Raw elements are a perfect tool for integration with external frameworks and data sources.\n\t *\n\t * Unlike {@link #createUIElement UI elements}, raw elements act like \"real\" editor content (similar to\n\t * {@link module:engine/view/containerelement~ContainerElement} or {@link module:engine/view/emptyelement~EmptyElement}),\n\t * and they are considered by the editor selection.\n\t *\n\t * You should not use raw elements to render the UI in the editor content. Check out {@link #createUIElement `#createUIElement()`}\n\t * instead.\n\t *\n\t * @param name The name of the element.\n\t * @param attributes Element attributes.\n\t * @param renderFunction A custom render function.\n\t * @param options Element's options.\n\t * @param options.renderUnsafeAttributes A list of attribute names that should be rendered in the editing\n\t * pipeline even though they would normally be filtered out by unsafe attribute detection mechanisms.\n\t * @returns The created element.\n\t */\n\tpublic createRawElement(\n\t\tname: string,\n\t\tattributes?: ElementAttributes,\n\t\trenderFunction?: ( domElement: DomElement, domConverter: DomConverter ) => void,\n\t\toptions: {\n\t\t\trenderUnsafeAttributes?: Array<string>;\n\t\t} = {}\n\t): RawElement {\n\t\tconst rawElement = new RawElement( this.document, name, attributes );\n\n\t\tif ( renderFunction ) {\n\t\t\trawElement.render = renderFunction;\n\t\t}\n\n\t\tif ( options.renderUnsafeAttributes ) {\n\t\t\trawElement._unsafeAttributesToRender.push( ...options.renderUnsafeAttributes );\n\t\t}\n\n\t\treturn rawElement;\n\t}\n\n\t/**\n\t * Adds or overwrites the element's attribute with a specified key and value.\n\t *\n\t * ```ts\n\t * writer.setAttribute( 'href', 'http://ckeditor.com', linkElement );\n\t * ```\n\t *\n\t * @param key The attribute key.\n\t * @param value The attribute value.\n\t */\n\tpublic setAttribute( key: string, value: unknown, element: Element ): void {\n\t\telement._setAttribute( key, value );\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t * ```ts\n\t * writer.removeAttribute( 'href', linkElement );\n\t * ```\n\t *\n\t * @param key Attribute key.\n\t */\n\tpublic removeAttribute( key: string, element: Element ): void {\n\t\telement._removeAttribute( key );\n\t}\n\n\t/**\n\t * Adds specified class to the element.\n\t *\n\t * ```ts\n\t * writer.addClass( 'foo', linkElement );\n\t * writer.addClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t */\n\tpublic addClass( className: string | Array<string>, element: Element ): void {\n\t\telement._addClass( className );\n\t}\n\n\t/**\n\t * Removes specified class from the element.\n\t *\n\t * ```ts\n\t * writer.removeClass( 'foo', linkElement );\n\t * writer.removeClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t */\n\tpublic removeClass( className: string | Array<string>, element: Element ): void {\n\t\telement._removeClass( className );\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t * ```ts\n\t * writer.setStyle( 'color', 'red', element );\n\t * ```\n\t *\n\t * **Note**: The passed style can be normalized if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details.\n\t *\n\t * @label KEY_VALUE\n\t * @param property Property name.\n\t * @param value Value to set.\n\t * @param element Element to set styles on.\n\t */\n\tpublic setStyle( property: string, value: string, element: Element ): void;\n\n\t/**\n\t * Adds many styles to the element.\n\t *\n\t * ```ts\n\t * writer.setStyle( {\n\t * \tcolor: 'red',\n\t * \tposition: 'fixed'\n\t * }, element );\n\t * ```\n\t *\n\t * **Note**: The passed style can be normalized if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details.\n\t *\n\t * @label OBJECT\n\t * @param property Object with key - value pairs.\n\t * @param element Element to set styles on.\n\t */\n\tpublic setStyle( property: Record<string, string>, element: Element ): void;\n\n\tpublic setStyle(\n\t\tproperty: string | Record<string, string>,\n\t\tvalue: string | Element,\n\t\telement?: Element\n\t): void\n\t{\n\t\tif ( isPlainObject( property ) && element === undefined ) {\n\t\t\t( value as Element )._setStyle( property as Record<string, string> );\n\t\t} else {\n\t\t\telement!._setStyle( property as string, value as string );\n\t\t}\n\t}\n\n\t/**\n\t * Removes specified style from the element.\n\t *\n\t * ```ts\n\t * writer.removeStyle( 'color', element ); // Removes 'color' style.\n\t * writer.removeStyle( [ 'color', 'border-top' ], element ); // Removes both 'color' and 'border-top' styles.\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t */\n\tpublic removeStyle( property: string | Array<string>, element: Element ): void {\n\t\telement._removeStyle( property );\n\t}\n\n\t/**\n\t * Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t */\n\tpublic setCustomProperty( key: string | symbol, value: unknown, element: Element | DocumentFragment ): void {\n\t\telement._setCustomProperty( key, value );\n\t}\n\n\t/**\n\t * Removes a custom property stored under the given key.\n\t *\n\t * @returns Returns true if property was removed.\n\t */\n\tpublic removeCustomProperty( key: string | symbol, element: Element | DocumentFragment ): boolean {\n\t\treturn element._removeCustomProperty( key );\n\t}\n\n\t/**\n\t * Breaks attribute elements at the provided position or at the boundaries of a provided range. It breaks attribute elements\n\t * up to their first ancestor that is a container element.\n\t *\n\t * In following examples `<p>` is a container, `<b>` and `<u>` are attribute elements:\n\t *\n\t * ```html\n\t * <p>foo<b><u>bar{}</u></b></p> -> <p>foo<b><u>bar</u></b>[]</p>\n\t * <p>foo<b><u>{}bar</u></b></p> -> <p>foo{}<b><u>bar</u></b></p>\n\t * <p>foo<b><u>b{}ar</u></b></p> -> <p>foo<b><u>b</u></b>[]<b><u>ar</u></b></p>\n\t * <p><b>fo{o</b><u>ba}r</u></p> -> <p><b>fo</b><b>o</b><u>ba</u><u>r</u></b></p>\n\t * ```\n\t *\n\t * **Note:** {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n\t *\n\t * **Note:** The difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes()} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of a given `position`,\n\t * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.\n\t * `breakContainer()` assumes that a given `position` is directly in the container element and breaks that container element.\n\t *\n\t * Throws the `view-writer-invalid-range-container` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * when the {@link module:engine/view/range~Range#start start}\n\t * and {@link module:engine/view/range~Range#end end} positions of a passed range are not placed inside same parent container.\n\t *\n\t * Throws the `view-writer-cannot-break-empty-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * when trying to break attributes inside an {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n\t *\n\t * Throws the `view-writer-cannot-break-ui-element` {@link module:utils/ckeditorerror~CKEditorError CKEditorError}\n\t * when trying to break attributes inside a {@link module:engine/view/uielement~UIElement UIElement}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#breakContainer\n\t * @param positionOrRange The position where to break attribute elements.\n\t * @returns The new position or range, after breaking the attribute elements.\n\t */\n\tpublic breakAttributes( positionOrRange: Position | Range ): Position | Range {\n\t\tif ( positionOrRange instanceof Position ) {\n\t\t\treturn this._breakAttributes( positionOrRange );\n\t\t} else {\n\t\t\treturn this._breakAttributesRange( positionOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Breaks a {@link module:engine/view/containerelement~ContainerElement container view element} into two, at the given position.\n\t * The position has to be directly inside the container element and cannot be in the root. It does not break the conrainer view element\n\t * if the position is at the beginning or at the end of its parent element.\n\t *\n\t * ```html\n\t * <p>foo^bar</p> -> <p>foo</p><p>bar</p>\n\t * <div><p>foo</p>^<p>bar</p></div> -> <div><p>foo</p></div><div><p>bar</p></div>\n\t * <p>^foobar</p> -> ^<p>foobar</p>\n\t * <p>foobar^</p> -> <p>foobar</p>^\n\t * ```\n\t *\n\t * **Note:** The difference between {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes breakAttributes()} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakContainer breakContainer()} is that `breakAttributes()` breaks all\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that are ancestors of a given `position`,\n\t * up to the first encountered {@link module:engine/view/containerelement~ContainerElement container element}.\n\t * `breakContainer()` assumes that the given `position` is directly in the container element and breaks that container element.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#breakAttributes\n\t * @param position The position where to break the element.\n\t * @returns The position between broken elements. If an element has not been broken,\n\t * the returned position is placed either before or after it.\n\t */\n\tpublic breakContainer( position: Position ): Position {\n\t\tconst element = position.parent;\n\n\t\tif ( !( element.is( 'containerElement' ) ) ) {\n\t\t\t/**\n\t\t\t * Trying to break an element which is not a container element.\n\t\t\t *\n\t\t\t * @error view-writer-break-non-container-element\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-break-non-container-element', this.document );\n\t\t}\n\n\t\tif ( !element.parent ) {\n\t\t\t/**\n\t\t\t * Trying to break root element.\n\t\t\t *\n\t\t\t * @error view-writer-break-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-break-root', this.document );\n\t\t}\n\n\t\tif ( position.isAtStart ) {\n\t\t\treturn Position._createBefore( element );\n\t\t} else if ( !position.isAtEnd ) {\n\t\t\tconst newElement = element._clone( false );\n\n\t\t\tthis.insert( Position._createAfter( element ), newElement as any );\n\n\t\t\tconst sourceRange = new Range( position, Position._createAt( element, 'end' ) );\n\t\t\tconst targetPosition = new Position( newElement, 0 );\n\n\t\t\tthis.move( sourceRange, targetPosition );\n\t\t}\n\n\t\treturn Position._createAfter( element );\n\t}\n\n\t/**\n\t * Merges {@link module:engine/view/attributeelement~AttributeElement attribute elements}. It also merges text nodes if needed.\n\t * Only {@link module:engine/view/attributeelement~AttributeElement#isSimilar similar} attribute elements can be merged.\n\t *\n\t * In following examples `<p>` is a container and `<b>` is an attribute element:\n\t *\n\t * ```html\n\t * <p>foo[]bar</p> -> <p>foo{}bar</p>\n\t * <p><b>foo</b>[]<b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t * <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p> -> <p><b foo=\"bar\">a</b>[]<b foo=\"baz\">b</b></p>\n\t * ```\n\t *\n\t * It will also take care about empty attributes when merging:\n\t *\n\t * ```html\n\t * <p><b>[]</b></p> -> <p>[]</p>\n\t * <p><b>foo</b><i>[]</i><b>bar</b></p> -> <p><b>foo{}bar</b></p>\n\t * ```\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#mergeAttributes mergeAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n\t * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#mergeContainers\n\t * @param position Merge position.\n\t * @returns Position after merge.\n\t */\n\tpublic mergeAttributes( position: Position ): Position {\n\t\tconst positionOffset = position.offset;\n\t\tconst positionParent = position.parent;\n\n\t\t// When inside text node - nothing to merge.\n\t\tif ( positionParent.is( '$text' ) ) {\n\t\t\treturn position;\n\t\t}\n\n\t\t// When inside empty attribute - remove it.\n\t\tif ( positionParent.is( 'attributeElement' ) && positionParent.childCount === 0 ) {\n\t\t\tconst parent = positionParent.parent;\n\t\t\tconst offset = positionParent.index;\n\n\t\t\tpositionParent._remove();\n\t\t\tthis._removeFromClonedElementsGroup( positionParent );\n\n\t\t\treturn this.mergeAttributes( new Position( parent!, offset! ) );\n\t\t}\n\n\t\tconst nodeBefore = ( positionParent as Element ).getChild( positionOffset - 1 );\n\t\tconst nodeAfter = ( positionParent as Element ).getChild( positionOffset );\n\n\t\t// Position should be placed between two nodes.\n\t\tif ( !nodeBefore || !nodeAfter ) {\n\t\t\treturn position;\n\t\t}\n\n\t\t// When position is between two text nodes.\n\t\tif ( nodeBefore.is( '$text' ) && nodeAfter.is( '$text' ) ) {\n\t\t\treturn mergeTextNodes( nodeBefore, nodeAfter );\n\t\t}\n\t\t// When position is between two same attribute elements.\n\t\telse if ( nodeBefore.is( 'attributeElement' ) && nodeAfter.is( 'attributeElement' ) && nodeBefore.isSimilar( nodeAfter ) ) {\n\t\t\t// Move all children nodes from node placed after selection and remove that node.\n\t\t\tconst count = nodeBefore.childCount;\n\t\t\tnodeBefore._appendChild( nodeAfter.getChildren() );\n\n\t\t\tnodeAfter._remove();\n\t\t\tthis._removeFromClonedElementsGroup( nodeAfter );\n\n\t\t\t// New position is located inside the first node, before new nodes.\n\t\t\t// Call this method recursively to merge again if needed.\n\t\t\treturn this.mergeAttributes( new Position( nodeBefore, count ) );\n\t\t}\n\n\t\treturn position;\n\t}\n\n\t/**\n\t * Merges two {@link module:engine/view/containerelement~ContainerElement container elements} that are before and after given position.\n\t * Precisely, the element after the position is removed and it's contents are moved to element before the position.\n\t *\n\t * ```html\n\t * <p>foo</p>^<p>bar</p> -> <p>foo^bar</p>\n\t * <div>foo</div>^<p>bar</p> -> <div>foo^bar</div>\n\t * ```\n\t *\n\t * **Note:** Difference between {@link module:engine/view/downcastwriter~DowncastWriter#mergeAttributes mergeAttributes} and\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#mergeContainers mergeContainers} is that `mergeAttributes` merges two\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute elements} or {@link module:engine/view/text~Text text nodes}\n\t * while `mergeContainer` merges two {@link module:engine/view/containerelement~ContainerElement container elements}.\n\t *\n\t * @see module:engine/view/attributeelement~AttributeElement\n\t * @see module:engine/view/containerelement~ContainerElement\n\t * @see module:engine/view/downcastwriter~DowncastWriter#mergeAttributes\n\t * @param position Merge position.\n\t * @returns Position after merge.\n\t */\n\tpublic mergeContainers( position: Position ): Position {\n\t\tconst prev = position.nodeBefore;\n\t\tconst next = position.nodeAfter;\n\n\t\tif ( !prev || !next || !prev.is( 'containerElement' ) || !next.is( 'containerElement' ) ) {\n\t\t\t/**\n\t\t\t * Element before and after given position cannot be merged.\n\t\t\t *\n\t\t\t * @error view-writer-merge-containers-invalid-position\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-merge-containers-invalid-position', this.document );\n\t\t}\n\n\t\tconst lastChild = prev.getChild( prev.childCount - 1 );\n\t\tconst newPosition = lastChild instanceof Text ? Position._createAt( lastChild, 'end' ) : Position._createAt( prev, 'end' );\n\n\t\tthis.move( Range._createIn( next ), Position._createAt( prev, 'end' ) );\n\t\tthis.remove( Range._createOn( next ) );\n\n\t\treturn newPosition;\n\t}\n\n\t/**\n\t * Inserts a node or nodes at specified position. Takes care about breaking attributes before insertion\n\t * and merging them afterwards.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n\t * contains instances that are not {@link module:engine/view/text~Text Texts},\n\t * {@link module:engine/view/attributeelement~AttributeElement AttributeElements},\n\t * {@link module:engine/view/containerelement~ContainerElement ContainerElements},\n\t * {@link module:engine/view/emptyelement~EmptyElement EmptyElements},\n\t * {@link module:engine/view/rawelement~RawElement RawElements} or\n\t * {@link module:engine/view/uielement~UIElement UIElements}.\n\t *\n\t * @param position Insertion position.\n\t * @param nodes Node or nodes to insert.\n\t * @returns Range around inserted nodes.\n\t */\n\tpublic insert( position: Position, nodes: Node | Iterable<Node> ): Range {\n\t\tnodes = isIterable( nodes ) ? [ ...nodes ] : [ nodes ];\n\n\t\t// Check if nodes to insert are instances of AttributeElements, ContainerElements, EmptyElements, UIElements or Text.\n\t\tvalidateNodesToInsert( nodes, this.document );\n\n\t\t// Group nodes in batches of nodes that require or do not require breaking an AttributeElements.\n\t\tconst nodeGroups = ( nodes as Array<Node> ).reduce( ( groups: Array<{ breakAttributes: boolean; nodes: Array<Node> }>, node ) => {\n\t\t\tconst lastGroup = groups[ groups.length - 1 ];\n\n\t\t\t// Break attributes on nodes that do exist in the model tree so they can have attributes, other elements\n\t\t\t// can't have an attribute in model and won't get wrapped with an AttributeElement while down-casted.\n\t\t\tconst breakAttributes = !node.is( 'uiElement' );\n\n\t\t\tif ( !lastGroup || lastGroup.breakAttributes != breakAttributes ) {\n\t\t\t\tgroups.push( {\n\t\t\t\t\tbreakAttributes,\n\t\t\t\t\tnodes: [ node ]\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tlastGroup.nodes.push( node );\n\t\t\t}\n\n\t\t\treturn groups;\n\t\t}, [] );\n\n\t\t// Insert nodes in batches.\n\t\tlet start = null;\n\t\tlet end = position;\n\n\t\tfor ( const { nodes, breakAttributes } of nodeGroups ) {\n\t\t\tconst range = this._insertNodes( end, nodes, breakAttributes );\n\n\t\t\tif ( !start ) {\n\t\t\t\tstart = range.start;\n\t\t\t}\n\n\t\t\tend = range.end;\n\t\t}\n\n\t\t// When no nodes were inserted - return collapsed range.\n\t\tif ( !start ) {\n\t\t\treturn new Range( position );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Removes provided range from the container.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param rangeOrItem Range to remove from container\n\t * or an {@link module:engine/view/item~Item item} to remove. If range is provided, after removing, it will be updated\n\t * to a collapsed range showing the new position.\n\t * @returns Document fragment containing removed nodes.\n\t */\n\tpublic remove( rangeOrItem: Range | Item ): DocumentFragment {\n\t\tconst range = rangeOrItem instanceof Range ? rangeOrItem : Range._createOn( rangeOrItem );\n\n\t\tvalidateRangeContainer( range, this.document );\n\n\t\t// If range is collapsed - nothing to remove.\n\t\tif ( range.isCollapsed ) {\n\t\t\treturn new DocumentFragment( this.document );\n\t\t}\n\n\t\t// Break attributes at range start and end.\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange( range, true );\n\t\tconst parentContainer = breakStart.parent as Element;\n\n\t\tconst count = breakEnd.offset - breakStart.offset;\n\n\t\t// Remove nodes in range.\n\t\tconst removed = parentContainer._removeChildren( breakStart.offset, count );\n\n\t\tfor ( const node of removed ) {\n\t\t\tthis._removeFromClonedElementsGroup( node );\n\t\t}\n\n\t\t// Merge after removing.\n\t\tconst mergePosition = this.mergeAttributes( breakStart );\n\t\t( range as any ).start = mergePosition;\n\t\t( range as any ).end = mergePosition.clone();\n\n\t\t// Return removed nodes.\n\t\treturn new DocumentFragment( this.document, removed );\n\t}\n\n\t/**\n\t * Removes matching elements from given range.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param range Range to clear.\n\t * @param element Element to remove.\n\t */\n\tpublic clear( range: Range, element: Element ): void {\n\t\tvalidateRangeContainer( range, this.document );\n\n\t\t// Create walker on given range.\n\t\t// We walk backward because when we remove element during walk it modifies range end position.\n\t\tconst walker = range.getWalker( {\n\t\t\tdirection: 'backward',\n\t\t\tignoreElementEnd: true\n\t\t} );\n\n\t\t// Let's walk.\n\t\tfor ( const current of walker ) {\n\t\t\tconst item = current.item;\n\t\t\tlet rangeToRemove;\n\n\t\t\t// When current item matches to the given element.\n\t\t\tif ( item.is( 'element' ) && element.isSimilar( item ) ) {\n\t\t\t\t// Create range on this element.\n\t\t\t\trangeToRemove = Range._createOn( item );\n\t\t\t\t// When range starts inside Text or TextProxy element.\n\t\t\t} else if ( !current.nextPosition.isAfter( range.start ) && item.is( '$textProxy' ) ) {\n\t\t\t\t// We need to check if parent of this text matches to given element.\n\t\t\t\tconst parentElement = item.getAncestors().find( ancestor => {\n\t\t\t\t\treturn ancestor.is( 'element' ) && element.isSimilar( ancestor );\n\t\t\t\t} );\n\n\t\t\t\t// If it is then create range inside this element.\n\t\t\t\tif ( parentElement ) {\n\t\t\t\t\trangeToRemove = Range._createIn( parentElement as Element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we have found element to remove.\n\t\t\tif ( rangeToRemove ) {\n\t\t\t\t// We need to check if element range stick out of the given range and truncate if it is.\n\t\t\t\tif ( rangeToRemove.end.isAfter( range.end ) ) {\n\t\t\t\t\t( rangeToRemove as any ).end = range.end;\n\t\t\t\t}\n\n\t\t\t\tif ( rangeToRemove.start.isBefore( range.start ) ) {\n\t\t\t\t\t( rangeToRemove as any ).start = range.start;\n\t\t\t\t}\n\n\t\t\t\t// At the end we remove range with found element.\n\t\t\t\tthis.remove( rangeToRemove );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Moves nodes from provided range to target position.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t *\n\t * @param sourceRange Range containing nodes to move.\n\t * @param targetPosition Position to insert.\n\t * @returns Range in target container. Inserted nodes are placed between\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions.\n\t */\n\tpublic move( sourceRange: Range, targetPosition: Position ): Range {\n\t\tlet nodes;\n\n\t\tif ( targetPosition.isAfter( sourceRange.end ) ) {\n\t\t\ttargetPosition = this._breakAttributes( targetPosition, true );\n\n\t\t\tconst parent = targetPosition.parent as Element;\n\t\t\tconst countBefore = parent.childCount;\n\n\t\t\tsourceRange = this._breakAttributesRange( sourceRange, true );\n\n\t\t\tnodes = this.remove( sourceRange );\n\n\t\t\ttargetPosition.offset += ( parent.childCount - countBefore );\n\t\t} else {\n\t\t\tnodes = this.remove( sourceRange );\n\t\t}\n\n\t\treturn this.insert( targetPosition, nodes );\n\t}\n\n\t/**\n\t * Wraps elements within range with provided {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t * If a collapsed range is provided, it will be wrapped only if it is equal to view selection.\n\t *\n\t * If a collapsed range was passed and is same as selection, the selection\n\t * will be moved to the inside of the wrapped attribute element.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-invalid-range-container`\n\t * when {@link module:engine/view/range~Range#start}\n\t * and {@link module:engine/view/range~Range#end} positions are not placed inside same parent container.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-nonselection-collapsed-range` when passed range\n\t * is collapsed and different than view selection.\n\t *\n\t * @param range Range to wrap.\n\t * @param attribute Attribute element to use as wrapper.\n\t * @returns range Range after wrapping, spanning over wrapping attribute element.\n\t */\n\tpublic wrap( range: Range, attribute: AttributeElement ): Range {\n\t\tif ( !( attribute instanceof AttributeElement ) ) {\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-writer-wrap-invalid-attribute',\n\t\t\t\tthis.document\n\t\t\t);\n\t\t}\n\n\t\tvalidateRangeContainer( range, this.document );\n\n\t\tif ( !range.isCollapsed ) {\n\t\t\t// Non-collapsed range. Wrap it with the attribute element.\n\t\t\treturn this._wrapRange( range, attribute );\n\t\t} else {\n\t\t\t// Collapsed range. Wrap position.\n\t\t\tlet position = range.start;\n\n\t\t\tif ( position.parent.is( 'element' ) && !_hasNonUiChildren( position.parent ) ) {\n\t\t\t\tposition = position.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n\t\t\t}\n\n\t\t\tposition = this._wrapPosition( position, attribute );\n\t\t\tconst viewSelection = this.document.selection;\n\n\t\t\t// If wrapping position is equal to view selection, move view selection inside wrapping attribute element.\n\t\t\tif ( viewSelection.isCollapsed && viewSelection.getFirstPosition()!.isEqual( range.start ) ) {\n\t\t\t\tthis.setSelection( position );\n\t\t\t}\n\n\t\t\treturn new Range( position );\n\t\t}\n\t}\n\n\t/**\n\t * Unwraps nodes within provided range from attribute element.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when\n\t * {@link module:engine/view/range~Range#start start} and {@link module:engine/view/range~Range#end end} positions are not placed inside\n\t * same parent container.\n\t */\n\tpublic unwrap( range: Range, attribute: AttributeElement ): Range {\n\t\tif ( !( attribute instanceof AttributeElement ) ) {\n\t\t\t/**\n\t\t\t * The `attribute` passed to {@link module:engine/view/downcastwriter~DowncastWriter#unwrap `DowncastWriter#unwrap()`}\n\t\t\t * must be an instance of {@link module:engine/view/attributeelement~AttributeElement `AttributeElement`}.\n\t\t\t *\n\t\t\t * @error view-writer-unwrap-invalid-attribute\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-writer-unwrap-invalid-attribute',\n\t\t\t\tthis.document\n\t\t\t);\n\t\t}\n\n\t\tvalidateRangeContainer( range, this.document );\n\n\t\t// If range is collapsed - nothing to unwrap.\n\t\tif ( range.isCollapsed ) {\n\t\t\treturn range;\n\t\t}\n\n\t\t// Break attributes at range start and end.\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange( range, true );\n\t\tconst parentContainer = breakStart.parent as Element;\n\n\t\t// Unwrap children located between break points.\n\t\tconst newRange = this._unwrapChildren( parentContainer, breakStart.offset, breakEnd.offset, attribute );\n\n\t\t// Merge attributes at the both ends and return a new range.\n\t\tconst start = this.mergeAttributes( newRange.start );\n\n\t\t// If start position was merged - move end position back.\n\t\tif ( !start.isEqual( newRange.start ) ) {\n\t\t\tnewRange.end.offset--;\n\t\t}\n\n\t\tconst end = this.mergeAttributes( newRange.end );\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Renames element by creating a copy of renamed element but with changed name and then moving contents of the\n\t * old element to the new one. Keep in mind that this will invalidate all {@link module:engine/view/position~Position positions} which\n\t * has renamed element as {@link module:engine/view/position~Position#parent a parent}.\n\t *\n\t * New element has to be created because `Element#tagName` property in DOM is readonly.\n\t *\n\t * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t *\n\t * @param newName New name for element.\n\t * @param viewElement Element to be renamed.\n\t * @returns Element created due to rename.\n\t */\n\tpublic rename( newName: string, viewElement: ContainerElement ): ContainerElement {\n\t\tconst newElement = new ContainerElement( this.document, newName, viewElement.getAttributes() );\n\n\t\tthis.insert( Position._createAfter( viewElement ), newElement );\n\t\tthis.move( Range._createIn( viewElement ), Position._createAt( newElement, 0 ) );\n\t\tthis.remove( Range._createOn( viewElement ) );\n\n\t\treturn newElement;\n\t}\n\n\t/**\n\t * Cleans up memory by removing obsolete cloned elements group from the writer.\n\t *\n\t * Should be used whenever all {@link module:engine/view/attributeelement~AttributeElement attribute elements}\n\t * with the same {@link module:engine/view/attributeelement~AttributeElement#id id} are going to be removed from the view and\n\t * the group will no longer be needed.\n\t *\n\t * Cloned elements group are not removed automatically in case if the group is still needed after all its elements\n\t * were removed from the view.\n\t *\n\t * Keep in mind that group names are equal to the `id` property of the attribute element.\n\t *\n\t * @param groupName Name of the group to clear.\n\t */\n\tpublic clearClonedElementsGroup( groupName: string ): void {\n\t\tthis._cloneGroups.delete( groupName );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param offset Offset or one of the flags. Used only when the first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tpublic createPositionAt( itemOrPosition: Item | Position, offset?: PositionOffset ): Position {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param item View item after which the position should be located.\n\t */\n\tpublic createPositionAfter( item: Item ): Position {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param item View item before which the position should be located.\n\t */\n\tpublic createPositionBefore( item: Item ): Position {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates its own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */\n\tpublic createRange( start: Position, end?: Position | null ): Range {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t */\n\tpublic createRangeOn( item: Item ): Range {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic createRangeIn( element: Element | DocumentFragment ): Range {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t * Creates new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * ```ts\n\t * // Creates collapsed selection at the position of given item and offset.\n\t * const paragraph = writer.createContainerElement( 'p' );\n\t * const selection = writer.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = writer.createSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( element, 'in', { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = writer.createSelection( element, 'in', { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:SELECTABLE `createSelection( selectable, options )`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic createSelection( selectable: Node, placeOrOffset: PlaceOrOffset, options?: SelectionOptions ): Selection;\n\n\t/**\n\t * Creates new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = writer.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = writer.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * const selection = writer.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = writer.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the document selection.\n\t * const selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * const selection = writer.createSelection( position );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:NODE_OFFSET `createSelection( node, placeOrOffset, options )`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic createSelection( selectable?: Exclude<Selectable, Node>, option?: SelectionOptions ): Selection;\n\n\tpublic createSelection( ...args: ConstructorParameters<typeof Selection> ): Selection {\n\t\treturn new Selection( ...args );\n\t}\n\n\t/**\n\t * Creates placeholders for child elements of the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n\t * `elementToStructure()`} conversion helper.\n\t *\n\t * ```ts\n\t * const viewSlot = conversionApi.writer.createSlot();\n\t * const viewPosition = conversionApi.writer.createPositionAt( viewElement, 0 );\n\t *\n\t * conversionApi.writer.insert( viewPosition, viewSlot );\n\t * ```\n\t *\n\t * It could be filtered down to a specific subset of children (only `<foo>` model elements in this case):\n\t *\n\t * ```ts\n\t * const viewSlot = conversionApi.writer.createSlot( node => node.is( 'element', 'foo' ) );\n\t * const viewPosition = conversionApi.writer.createPositionAt( viewElement, 0 );\n\t *\n\t * conversionApi.writer.insert( viewPosition, viewSlot );\n\t * ```\n\t *\n\t * While providing a filtered slot, make sure to provide slots for all child nodes. A single node can not be downcasted into\n\t * multiple slots.\n\t *\n\t * **Note**: You should not change the order of nodes. View elements should be in the same order as model nodes.\n\t *\n\t * @param modeOrFilter The filter for child nodes.\n\t * @returns The slot element to be placed in to the view structure while processing\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure `elementToStructure()`}.\n\t */\n\tpublic createSlot( modeOrFilter: 'children' | SlotFilter = 'children' ): Element {\n\t\tif ( !this._slotFactory ) {\n\t\t\t/**\n\t\t\t * The `createSlot()` method is only allowed inside the `elementToStructure` downcast helper callback.\n\t\t\t *\n\t\t\t * @error view-writer-invalid-create-slot-context\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-invalid-create-slot-context', this.document );\n\t\t}\n\n\t\treturn this._slotFactory( this, modeOrFilter );\n\t}\n\n\t/**\n\t * Registers a slot factory.\n\t *\n\t * @internal\n\t * @param slotFactory The slot factory.\n\t */\n\tpublic _registerSlotFactory( slotFactory: ( writer: DowncastWriter, modeOrFilter: 'children' | SlotFilter ) => Element ): void {\n\t\tthis._slotFactory = slotFactory;\n\t}\n\n\t/**\n\t * Clears the registered slot factory.\n\t *\n\t * @internal\n\t */\n\tpublic _clearSlotFactory(): void {\n\t\tthis._slotFactory = null;\n\t}\n\n\t/**\n\t * Inserts a node or nodes at the specified position. Takes care of breaking attributes before insertion\n\t * and merging them afterwards if requested by the breakAttributes param.\n\t *\n\t * @param position Insertion position.\n\t * @param nodes Node or nodes to insert.\n\t * @param breakAttributes Whether attributes should be broken.\n\t * @returns Range around inserted nodes.\n\t */\n\tprivate _insertNodes( position: Position, nodes: Iterable<Node>, breakAttributes: boolean ): Range {\n\t\tlet parentElement;\n\n\t\t// Break attributes on nodes that do exist in the model tree so they can have attributes, other elements\n\t\t// can't have an attribute in model and won't get wrapped with an AttributeElement while down-casted.\n\t\tif ( breakAttributes ) {\n\t\t\tparentElement = getParentContainer( position );\n\t\t} else {\n\t\t\tparentElement = position.parent.is( '$text' ) ? position.parent.parent : position.parent;\n\t\t}\n\n\t\tif ( !parentElement ) {\n\t\t\t/**\n\t\t\t * Position's parent container cannot be found.\n\t\t\t *\n\t\t\t * @error view-writer-invalid-position-container\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-writer-invalid-position-container',\n\t\t\t\tthis.document\n\t\t\t);\n\t\t}\n\n\t\tlet insertionPosition;\n\n\t\tif ( breakAttributes ) {\n\t\t\tinsertionPosition = this._breakAttributes( position, true );\n\t\t} else {\n\t\t\tinsertionPosition = position.parent.is( '$text' ) ? breakTextNode( position ) : position;\n\t\t}\n\n\t\tconst length = ( parentElement as Element | DocumentFragment )._insertChild( insertionPosition.offset, nodes );\n\n\t\tfor ( const node of nodes ) {\n\t\t\tthis._addToClonedElementsGroup( node );\n\t\t}\n\n\t\tconst endPosition = insertionPosition.getShiftedBy( length );\n\t\tconst start = this.mergeAttributes( insertionPosition );\n\n\t\t// If start position was merged - move end position.\n\t\tif ( !start.isEqual( insertionPosition ) ) {\n\t\t\tendPosition.offset--;\n\t\t}\n\n\t\tconst end = this.mergeAttributes( endPosition );\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Wraps children with provided `wrapElement`. Only children contained in `parent` element between\n\t * `startOffset` and `endOffset` will be wrapped.\n\t */\n\tprivate _wrapChildren( parent: Element, startOffset: number, endOffset: number, wrapElement: AttributeElement ) {\n\t\tlet i = startOffset;\n\t\tconst wrapPositions: Array<Position> = [];\n\n\t\twhile ( i < endOffset ) {\n\t\t\tconst child = parent.getChild( i )!;\n\t\t\tconst isText = child.is( '$text' );\n\t\t\tconst isAttribute = child.is( 'attributeElement' );\n\n\t\t\t//\n\t\t\t// (In all examples, assume that `wrapElement` is `<span class=\"foo\">` element.)\n\t\t\t//\n\t\t\t// Check if `wrapElement` can be joined with the wrapped element. One of requirements is having same name.\n\t\t\t// If possible, join elements.\n\t\t\t//\n\t\t\t// <p><span class=\"bar\">abc</span></p>  -->  <p><span class=\"foo bar\">abc</span></p>\n\t\t\t//\n\t\t\tif ( isAttribute && this._wrapAttributeElement( wrapElement, child ) ) {\n\t\t\t\twrapPositions.push( new Position( parent, i ) );\n\t\t\t}\n\t\t\t//\n\t\t\t// Wrap the child if it is not an attribute element or if it is an attribute element that should be inside\n\t\t\t// `wrapElement` (due to priority).\n\t\t\t//\n\t\t\t// <p>abc</p>                   -->  <p><span class=\"foo\">abc</span></p>\n\t\t\t// <p><strong>abc</strong></p>  -->  <p><span class=\"foo\"><strong>abc</strong></span></p>\n\t\t\telse if ( isText || !isAttribute || shouldABeOutsideB( wrapElement, child ) ) {\n\t\t\t\t// Clone attribute.\n\t\t\t\tconst newAttribute = wrapElement._clone();\n\n\t\t\t\t// Wrap current node with new attribute.\n\t\t\t\tchild._remove();\n\t\t\t\tnewAttribute._appendChild( child );\n\n\t\t\t\tparent._insertChild( i, newAttribute );\n\t\t\t\tthis._addToClonedElementsGroup( newAttribute );\n\n\t\t\t\twrapPositions.push( new Position( parent, i ) );\n\t\t\t}\n\t\t\t//\n\t\t\t// If other nested attribute is found and it wasn't wrapped (see above), continue wrapping inside it.\n\t\t\t//\n\t\t\t// <p><a href=\"foo.html\">abc</a></p>  -->  <p><a href=\"foo.html\"><span class=\"foo\">abc</span></a></p>\n\t\t\t//\n\t\t\telse /* if ( isAttribute ) */ {\n\t\t\t\tthis._wrapChildren( child, 0, child.childCount, wrapElement );\n\t\t\t}\n\n\t\t\ti++;\n\t\t}\n\n\t\t// Merge at each wrap.\n\t\tlet offsetChange = 0;\n\n\t\tfor ( const position of wrapPositions ) {\n\t\t\tposition.offset -= offsetChange;\n\n\t\t\t// Do not merge with elements outside selected children.\n\t\t\tif ( position.offset == startOffset ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst newPosition = this.mergeAttributes( position );\n\n\t\t\t// If nodes were merged - other merge offsets will change.\n\t\t\tif ( !newPosition.isEqual( position ) ) {\n\t\t\t\toffsetChange++;\n\t\t\t\tendOffset--;\n\t\t\t}\n\t\t}\n\n\t\treturn Range._createFromParentsAndOffsets( parent, startOffset, parent, endOffset );\n\t}\n\n\t/**\n\t * Unwraps children from provided `unwrapElement`. Only children contained in `parent` element between\n\t * `startOffset` and `endOffset` will be unwrapped.\n\t */\n\tprivate _unwrapChildren( parent: Element, startOffset: number, endOffset: number, unwrapElement: AttributeElement ) {\n\t\tlet i = startOffset;\n\t\tconst unwrapPositions: Array<Position> = [];\n\n\t\t// Iterate over each element between provided offsets inside parent.\n\t\t// We don't use tree walker or range iterator because we will be removing and merging potentially multiple nodes,\n\t\t// so it could get messy. It is safer to it manually in this case.\n\t\twhile ( i < endOffset ) {\n\t\t\tconst child = parent.getChild( i )!;\n\n\t\t\t// Skip all text nodes. There should be no container element's here either.\n\t\t\tif ( !child.is( 'attributeElement' ) ) {\n\t\t\t\ti++;\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// (In all examples, assume that `unwrapElement` is `<span class=\"foo\">` element.)\n\t\t\t//\n\t\t\t// If the child is similar to the given attribute element, unwrap it - it will be completely removed.\n\t\t\t//\n\t\t\t// <p><span class=\"foo\">abc</span>xyz</p>  -->  <p>abcxyz</p>\n\t\t\t//\n\t\t\tif ( child.isSimilar( unwrapElement ) ) {\n\t\t\t\tconst unwrapped = child.getChildren();\n\t\t\t\tconst count = child.childCount;\n\n\t\t\t\t// Replace wrapper element with its children\n\t\t\t\tchild._remove();\n\t\t\t\tparent._insertChild( i, unwrapped );\n\n\t\t\t\tthis._removeFromClonedElementsGroup( child );\n\n\t\t\t\t// Save start and end position of moved items.\n\t\t\t\tunwrapPositions.push(\n\t\t\t\t\tnew Position( parent, i ),\n\t\t\t\t\tnew Position( parent, i + count )\n\t\t\t\t);\n\n\t\t\t\t// Skip elements that were unwrapped. Assuming there won't be another element to unwrap in child elements.\n\t\t\t\ti += count;\n\t\t\t\tendOffset += count - 1;\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// If the child is not similar but is an attribute element, try partial unwrapping - remove the same attributes/styles/classes.\n\t\t\t// Partial unwrapping will happen only if the elements have the same name.\n\t\t\t//\n\t\t\t// <p><span class=\"foo bar\">abc</span>xyz</p>  -->  <p><span class=\"bar\">abc</span>xyz</p>\n\t\t\t// <p><i class=\"foo\">abc</i>xyz</p>            -->  <p><i class=\"foo\">abc</i>xyz</p>\n\t\t\t//\n\t\t\tif ( this._unwrapAttributeElement( unwrapElement, child ) ) {\n\t\t\t\tunwrapPositions.push(\n\t\t\t\t\tnew Position( parent, i ),\n\t\t\t\t\tnew Position( parent, i + 1 )\n\t\t\t\t);\n\n\t\t\t\ti++;\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t//\n\t\t\t// If other nested attribute is found, look through it's children for elements to unwrap.\n\t\t\t//\n\t\t\t// <p><i><span class=\"foo\">abc</span></i><p>  -->  <p><i>abc</i><p>\n\t\t\t//\n\t\t\tthis._unwrapChildren( child, 0, child.childCount, unwrapElement );\n\n\t\t\ti++;\n\t\t}\n\n\t\t// Merge at each unwrap.\n\t\tlet offsetChange = 0;\n\n\t\tfor ( const position of unwrapPositions ) {\n\t\t\tposition.offset -= offsetChange;\n\n\t\t\t// Do not merge with elements outside selected children.\n\t\t\tif ( position.offset == startOffset || position.offset == endOffset ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst newPosition = this.mergeAttributes( position );\n\n\t\t\t// If nodes were merged - other merge offsets will change.\n\t\t\tif ( !newPosition.isEqual( position ) ) {\n\t\t\t\toffsetChange++;\n\t\t\t\tendOffset--;\n\t\t\t}\n\t\t}\n\n\t\treturn Range._createFromParentsAndOffsets( parent, startOffset, parent, endOffset );\n\t}\n\n\t/**\n\t * Helper function for `view.writer.wrap`. Wraps range with provided attribute element.\n\t * This method will also merge newly added attribute element with its siblings whenever possible.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * @returns New range after wrapping, spanning over wrapping attribute element.\n\t */\n\tprivate _wrapRange( range: Range, attribute: AttributeElement ): Range {\n\t\t// Break attributes at range start and end.\n\t\tconst { start: breakStart, end: breakEnd } = this._breakAttributesRange( range, true );\n\t\tconst parentContainer = breakStart.parent as Element;\n\n\t\t// Wrap all children with attribute.\n\t\tconst newRange = this._wrapChildren( parentContainer, breakStart.offset, breakEnd.offset, attribute );\n\n\t\t// Merge attributes at the both ends and return a new range.\n\t\tconst start = this.mergeAttributes( newRange.start );\n\n\t\t// If start position was merged - move end position back.\n\t\tif ( !start.isEqual( newRange.start ) ) {\n\t\t\tnewRange.end.offset--;\n\t\t}\n\t\tconst end = this.mergeAttributes( newRange.end );\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Helper function for {@link #wrap}. Wraps position with provided attribute element.\n\t * This method will also merge newly added attribute element with its siblings whenever possible.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not\n\t * an instance of {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.\n\t *\n\t * @returns New position after wrapping.\n\t */\n\tprivate _wrapPosition( position: Position, attribute: AttributeElement ): Position {\n\t\t// Return same position when trying to wrap with attribute similar to position parent.\n\t\tif ( attribute.isSimilar( position.parent as any ) ) {\n\t\t\treturn movePositionToTextNode( position.clone() );\n\t\t}\n\n\t\t// When position is inside text node - break it and place new position between two text nodes.\n\t\tif ( position.parent.is( '$text' ) ) {\n\t\t\tposition = breakTextNode( position );\n\t\t}\n\n\t\t// Create fake element that will represent position, and will not be merged with other attributes.\n\t\tconst fakeElement = this.createAttributeElement( '_wrapPosition-fake-element' );\n\t\t( fakeElement as any )._priority = Number.POSITIVE_INFINITY;\n\t\tfakeElement.isSimilar = () => false;\n\n\t\t// Insert fake element in position location.\n\t\t( position.parent as Element )._insertChild( position.offset, fakeElement );\n\n\t\t// Range around inserted fake attribute element.\n\t\tconst wrapRange = new Range( position, position.getShiftedBy( 1 ) );\n\n\t\t// Wrap fake element with attribute (it will also merge if possible).\n\t\tthis.wrap( wrapRange, attribute );\n\n\t\t// Remove fake element and place new position there.\n\t\tconst newPosition = new Position( fakeElement.parent!, fakeElement.index! );\n\t\tfakeElement._remove();\n\n\t\t// If position is placed between text nodes - merge them and return position inside.\n\t\tconst nodeBefore = newPosition.nodeBefore;\n\t\tconst nodeAfter = newPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof Text && nodeAfter instanceof Text ) {\n\t\t\treturn mergeTextNodes( nodeBefore, nodeAfter );\n\t\t}\n\n\t\t// If position is next to text node - move position inside.\n\t\treturn movePositionToTextNode( newPosition );\n\t}\n\n\t/**\n\t * Wraps one {@link module:engine/view/attributeelement~AttributeElement AttributeElement} into another by\n\t * merging them if possible. When merging is possible - all attributes, styles and classes are moved from wrapper\n\t * element to element being wrapped.\n\t *\n\t * @param wrapper Wrapper AttributeElement.\n\t * @param toWrap AttributeElement to wrap using wrapper element.\n\t * @returns Returns `true` if elements are merged.\n\t */\n\tprivate _wrapAttributeElement( wrapper: AttributeElement, toWrap: AttributeElement ): boolean {\n\t\tif ( !canBeJoined( wrapper, toWrap ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Can't merge if name or priority differs.\n\t\tif ( wrapper.name !== toWrap.name || wrapper.priority !== toWrap.priority ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if attributes can be merged.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If some attributes are different we cannot wrap.\n\t\t\tif ( toWrap.hasAttribute( key ) && toWrap.getAttribute( key ) !== wrapper.getAttribute( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if styles can be merged.\n\t\tfor ( const key of wrapper.getStyleNames() ) {\n\t\t\tif ( toWrap.hasStyle( key ) && toWrap.getStyle( key ) !== wrapper.getStyle( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Move all attributes/classes/styles from wrapper to wrapped AttributeElement.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Move only these attributes that are not present - other are similar.\n\t\t\tif ( !toWrap.hasAttribute( key ) ) {\n\t\t\t\tthis.setAttribute( key, wrapper.getAttribute( key )!, toWrap );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of wrapper.getStyleNames() ) {\n\t\t\tif ( !toWrap.hasStyle( key ) ) {\n\t\t\t\tthis.setStyle( key, wrapper.getStyle( key )!, toWrap );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of wrapper.getClassNames() ) {\n\t\t\tif ( !toWrap.hasClass( key ) ) {\n\t\t\t\tthis.addClass( key, toWrap );\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Unwraps {@link module:engine/view/attributeelement~AttributeElement AttributeElement} from another by removing\n\t * corresponding attributes, classes and styles. All attributes, classes and styles from wrapper should be present\n\t * inside element being unwrapped.\n\t *\n\t * @param wrapper Wrapper AttributeElement.\n\t * @param toUnwrap AttributeElement to unwrap using wrapper element.\n\t * @returns Returns `true` if elements are unwrapped.\n\t **/\n\tprivate _unwrapAttributeElement( wrapper: AttributeElement, toUnwrap: AttributeElement ): boolean {\n\t\tif ( !canBeJoined( wrapper, toUnwrap ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Can't unwrap if name or priority differs.\n\t\tif ( wrapper.name !== toUnwrap.name || wrapper.priority !== toUnwrap.priority ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if AttributeElement has all wrapper attributes.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If some attributes are missing or different we cannot unwrap.\n\t\t\tif ( !toUnwrap.hasAttribute( key ) || toUnwrap.getAttribute( key ) !== wrapper.getAttribute( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Check if AttributeElement has all wrapper classes.\n\t\tif ( !toUnwrap.hasClass( ...wrapper.getClassNames() ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check if AttributeElement has all wrapper styles.\n\t\tfor ( const key of wrapper.getStyleNames() ) {\n\t\t\t// If some styles are missing or different we cannot unwrap.\n\t\t\tif ( !toUnwrap.hasStyle( key ) || toUnwrap.getStyle( key ) !== wrapper.getStyle( key ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// Remove all wrapper's attributes from unwrapped element.\n\t\tfor ( const key of wrapper.getAttributeKeys() ) {\n\t\t\t// Classes and styles should be checked separately.\n\t\t\tif ( key === 'class' || key === 'style' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.removeAttribute( key, toUnwrap );\n\t\t}\n\n\t\t// Remove all wrapper's classes from unwrapped element.\n\t\tthis.removeClass( Array.from( wrapper.getClassNames() ), toUnwrap );\n\n\t\t// Remove all wrapper's styles from unwrapped element.\n\t\tthis.removeStyle( Array.from( wrapper.getStyleNames() ), toUnwrap );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Helper function used by other `DowncastWriter` methods. Breaks attribute elements at the boundaries of given range.\n\t *\n\t * @param range Range which `start` and `end` positions will be used to break attributes.\n\t * @param forceSplitText If set to `true`, will break text nodes even if they are directly in container element.\n\t * This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t * @returns New range with located at break positions.\n\t */\n\tprivate _breakAttributesRange( range: Range, forceSplitText: boolean = false ) {\n\t\tconst rangeStart = range.start;\n\t\tconst rangeEnd = range.end;\n\n\t\tvalidateRangeContainer( range, this.document );\n\n\t\t// Break at the collapsed position. Return new collapsed range.\n\t\tif ( range.isCollapsed ) {\n\t\t\tconst position = this._breakAttributes( range.start, forceSplitText );\n\n\t\t\treturn new Range( position, position );\n\t\t}\n\n\t\tconst breakEnd = this._breakAttributes( rangeEnd, forceSplitText );\n\t\tconst count = ( breakEnd.parent as Element ).childCount;\n\t\tconst breakStart = this._breakAttributes( rangeStart, forceSplitText );\n\n\t\t// Calculate new break end offset.\n\t\tbreakEnd.offset += ( breakEnd.parent as Element ).childCount - count;\n\n\t\treturn new Range( breakStart, breakEnd );\n\t}\n\n\t/**\n\t * Helper function used by other `DowncastWriter` methods. Breaks attribute elements at given position.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-empty-element` when break position\n\t * is placed inside {@link module:engine/view/emptyelement~EmptyElement EmptyElement}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-cannot-break-ui-element` when break position\n\t * is placed inside {@link module:engine/view/uielement~UIElement UIElement}.\n\t *\n\t * @param position Position where to break attributes.\n\t * @param forceSplitText If set to `true`, will break text nodes even if they are directly in container element.\n\t * This behavior will result in incorrect view state, but is needed by other view writing methods which then fixes view state.\n\t * @returns New position after breaking the attributes.\n\t */\n\tprivate _breakAttributes( position: Position, forceSplitText: boolean = false ): Position {\n\t\tconst positionOffset = position.offset;\n\t\tconst positionParent = position.parent;\n\n\t\t// If position is placed inside EmptyElement - throw an exception as we cannot break inside.\n\t\tif ( position.parent.is( 'emptyElement' ) ) {\n\t\t\t/**\n\t\t\t * Cannot break an `EmptyElement` instance.\n\t\t\t *\n\t\t\t * This error is thrown if\n\t\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes `DowncastWriter#breakAttributes()`}\n\t\t\t * was executed in an incorrect position.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-empty-element\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-cannot-break-empty-element', this.document );\n\t\t}\n\n\t\t// If position is placed inside UIElement - throw an exception as we cannot break inside.\n\t\tif ( position.parent.is( 'uiElement' ) ) {\n\t\t\t/**\n\t\t\t * Cannot break a `UIElement` instance.\n\t\t\t *\n\t\t\t * This error is thrown if\n\t\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes `DowncastWriter#breakAttributes()`}\n\t\t\t * was executed in an incorrect position.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-ui-element\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-cannot-break-ui-element', this.document );\n\t\t}\n\n\t\t// If position is placed inside RawElement - throw an exception as we cannot break inside.\n\t\tif ( position.parent.is( 'rawElement' ) ) {\n\t\t\t/**\n\t\t\t * Cannot break a `RawElement` instance.\n\t\t\t *\n\t\t\t * This error is thrown if\n\t\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#breakAttributes `DowncastWriter#breakAttributes()`}\n\t\t\t * was executed in an incorrect position.\n\t\t\t *\n\t\t\t * @error view-writer-cannot-break-raw-element\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-cannot-break-raw-element', this.document );\n\t\t}\n\n\t\t// There are no attributes to break and text nodes breaking is not forced.\n\t\tif ( !forceSplitText && positionParent.is( '$text' ) && isContainerOrFragment( positionParent.parent! ) ) {\n\t\t\treturn position.clone();\n\t\t}\n\n\t\t// Position's parent is container, so no attributes to break.\n\t\tif ( isContainerOrFragment( positionParent ) ) {\n\t\t\treturn position.clone();\n\t\t}\n\n\t\t// Break text and start again in new position.\n\t\tif ( positionParent.is( '$text' ) ) {\n\t\t\treturn this._breakAttributes( breakTextNode( position ), forceSplitText );\n\t\t}\n\n\t\tconst length = ( positionParent as any ).childCount;\n\n\t\t// <p>foo<b><u>bar{}</u></b></p>\n\t\t// <p>foo<b><u>bar</u>[]</b></p>\n\t\t// <p>foo<b><u>bar</u></b>[]</p>\n\t\tif ( positionOffset == length ) {\n\t\t\tconst newPosition = new Position( positionParent.parent as any, ( positionParent as any ).index + 1 );\n\n\t\t\treturn this._breakAttributes( newPosition, forceSplitText );\n\t\t} else {\n\t\t\t// <p>foo<b><u>{}bar</u></b></p>\n\t\t\t// <p>foo<b>[]<u>bar</u></b></p>\n\t\t\t// <p>foo{}<b><u>bar</u></b></p>\n\t\t\tif ( positionOffset === 0 ) {\n\t\t\t\tconst newPosition = new Position( positionParent.parent as Element, ( positionParent as any ).index );\n\n\t\t\t\treturn this._breakAttributes( newPosition, forceSplitText );\n\t\t\t}\n\t\t\t// <p>foo<b><u>b{}ar</u></b></p>\n\t\t\t// <p>foo<b><u>b[]ar</u></b></p>\n\t\t\t// <p>foo<b><u>b</u>[]<u>ar</u></b></p>\n\t\t\t// <p>foo<b><u>b</u></b>[]<b><u>ar</u></b></p>\n\t\t\telse {\n\t\t\t\tconst offsetAfter = ( positionParent as any ).index + 1;\n\n\t\t\t\t// Break element.\n\t\t\t\tconst clonedNode = ( positionParent as any )._clone();\n\n\t\t\t\t// Insert cloned node to position's parent node.\n\t\t\t\t( positionParent.parent as any )._insertChild( offsetAfter, clonedNode );\n\t\t\t\tthis._addToClonedElementsGroup( clonedNode );\n\n\t\t\t\t// Get nodes to move.\n\t\t\t\tconst count = ( positionParent as any ).childCount - positionOffset;\n\t\t\t\tconst nodesToMove = ( positionParent as any )._removeChildren( positionOffset, count );\n\n\t\t\t\t// Move nodes to cloned node.\n\t\t\t\tclonedNode._appendChild( nodesToMove );\n\n\t\t\t\t// Create new position to work on.\n\t\t\t\tconst newPosition = new Position( ( positionParent as any ).parent, offsetAfter );\n\n\t\t\t\treturn this._breakAttributes( newPosition, forceSplitText );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stores the information that an {@link module:engine/view/attributeelement~AttributeElement attribute element} was\n\t * added to the tree. Saves the reference to the group in the given element and updates the group, so other elements\n\t * from the group now keep a reference to the given attribute element.\n\t *\n\t * The clones group can be obtained using {@link module:engine/view/attributeelement~AttributeElement#getElementsWithSameId}.\n\t *\n\t * Does nothing if added element has no {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t *\n\t * @param element Attribute element to save.\n\t */\n\tprivate _addToClonedElementsGroup( element: Node ): void {\n\t\t// Add only if the element is in document tree.\n\t\tif ( !element.root.is( 'rootElement' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Traverse the element's children recursively to find other attribute elements that also might got inserted.\n\t\t// The loop is at the beginning so we can make fast returns later in the code.\n\t\tif ( element.is( 'element' ) ) {\n\t\t\tfor ( const child of element.getChildren() ) {\n\t\t\t\tthis._addToClonedElementsGroup( child );\n\t\t\t}\n\t\t}\n\n\t\tconst id = ( element as any ).id;\n\n\t\tif ( !id ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet group = this._cloneGroups.get( id );\n\n\t\tif ( !group ) {\n\t\t\tgroup = new Set();\n\t\t\tthis._cloneGroups.set( id, group );\n\t\t}\n\n\t\tgroup.add( element as AttributeElement );\n\t\t( element as any )._clonesGroup = group;\n\t}\n\n\t/**\n\t * Removes all the information about the given {@link module:engine/view/attributeelement~AttributeElement attribute element}\n\t * from its clones group.\n\t *\n\t * Keep in mind, that the element will still keep a reference to the group (but the group will not keep a reference to it).\n\t * This allows to reference the whole group even if the element was already removed from the tree.\n\t *\n\t * Does nothing if the element has no {@link module:engine/view/attributeelement~AttributeElement#id id}.\n\t *\n\t * @param element Attribute element to remove.\n\t */\n\tprivate _removeFromClonedElementsGroup( element: Node ) {\n\t\t// Traverse the element's children recursively to find other attribute elements that also got removed.\n\t\t// The loop is at the beginning so we can make fast returns later in the code.\n\t\tif ( element.is( 'element' ) ) {\n\t\t\tfor ( const child of element.getChildren() ) {\n\t\t\t\tthis._removeFromClonedElementsGroup( child );\n\t\t\t}\n\t\t}\n\n\t\tconst id = ( element as any ).id;\n\n\t\tif ( !id ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst group = this._cloneGroups.get( id );\n\n\t\tif ( !group ) {\n\t\t\treturn;\n\t\t}\n\n\t\tgroup.delete( element as AttributeElement );\n\t\t// Not removing group from element on purpose!\n\t\t// If other parts of code have reference to this element, they will be able to get references to other elements from the group.\n\t}\n}\n\n// Helper function for `view.writer.wrap`. Checks if given element has any children that are not ui elements.\nfunction _hasNonUiChildren( parent: Element ): boolean {\n\treturn Array.from( parent.getChildren() ).some( child => !child.is( 'uiElement' ) );\n}\n\n/**\n * The `attribute` passed to {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#wrap()`}\n * must be an instance of {@link module:engine/view/attributeelement~AttributeElement `AttributeElement`}.\n *\n * @error view-writer-wrap-invalid-attribute\n */\n\n/**\n * Returns first parent container of specified {@link module:engine/view/position~Position Position}.\n * Position's parent node is checked as first, then next parents are checked.\n * Note that {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment} is treated like a container.\n *\n * @param position Position used as a start point to locate parent container.\n * @returns Parent container element or `undefined` if container is not found.\n */\nfunction getParentContainer( position: Position ): ContainerElement | DocumentFragment | undefined {\n\tlet parent = position.parent;\n\n\twhile ( !isContainerOrFragment( parent ) ) {\n\t\tif ( !parent ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tparent = parent.parent as any;\n\t}\n\n\treturn ( parent as ContainerElement | DocumentFragment );\n}\n\n/**\n * Checks if first {@link module:engine/view/attributeelement~AttributeElement AttributeElement} provided to the function\n * can be wrapped outside second element. It is done by comparing elements'\n * {@link module:engine/view/attributeelement~AttributeElement#priority priorities}, if both have same priority\n * {@link module:engine/view/element~Element#getIdentity identities} are compared.\n */\nfunction shouldABeOutsideB( a: AttributeElement, b: AttributeElement ): boolean {\n\tif ( a.priority < b.priority ) {\n\t\treturn true;\n\t} else if ( a.priority > b.priority ) {\n\t\treturn false;\n\t}\n\n\t// When priorities are equal and names are different - use identities.\n\treturn a.getIdentity() < b.getIdentity();\n}\n\n/**\n * Returns new position that is moved to near text node. Returns same position if there is no text node before of after\n * specified position.\n *\n * ```html\n * <p>foo[]</p>  ->  <p>foo{}</p>\n * <p>[]foo</p>  ->  <p>{}foo</p>\n * ```\n *\n * @returns Position located inside text node or same position if there is no text nodes\n * before or after position location.\n */\nfunction movePositionToTextNode( position: Position ): Position {\n\tconst nodeBefore = position.nodeBefore;\n\n\tif ( nodeBefore && nodeBefore.is( '$text' ) ) {\n\t\treturn new Position( nodeBefore, nodeBefore.data.length );\n\t}\n\n\tconst nodeAfter = position.nodeAfter;\n\n\tif ( nodeAfter && nodeAfter.is( '$text' ) ) {\n\t\treturn new Position( nodeAfter, 0 );\n\t}\n\n\treturn position;\n}\n\n/**\n * Breaks text node into two text nodes when possible.\n *\n * ```html\n * <p>foo{}bar</p> -> <p>foo[]bar</p>\n * <p>{}foobar</p> -> <p>[]foobar</p>\n * <p>foobar{}</p> -> <p>foobar[]</p>\n * ```\n *\n * @param position Position that need to be placed inside text node.\n * @returns New position after breaking text node.\n */\nfunction breakTextNode( position: Position ): Position {\n\tif ( position.offset == ( position.parent as Text ).data.length ) {\n\t\treturn new Position( position.parent.parent as any, ( position.parent as Text ).index! + 1 );\n\t}\n\n\tif ( position.offset === 0 ) {\n\t\treturn new Position( position.parent.parent as any, ( position.parent as Text ).index! );\n\t}\n\n\t// Get part of the text that need to be moved.\n\tconst textToMove = ( position.parent as Text ).data.slice( position.offset );\n\n\t// Leave rest of the text in position's parent.\n\t( position.parent as Text )._data = ( position.parent as Text ).data.slice( 0, position.offset );\n\n\t// Insert new text node after position's parent text node.\n\t( position.parent.parent as any )._insertChild(\n\t\t( position.parent as Text ).index! + 1,\n\t\tnew Text( position.root.document, textToMove )\n\t);\n\n\t// Return new position between two newly created text nodes.\n\treturn new Position( position.parent.parent as any, ( position.parent as Text ).index! + 1 );\n}\n\n/**\n * Merges two text nodes into first node. Removes second node and returns merge position.\n *\n * @param t1 First text node to merge. Data from second text node will be moved at the end of this text node.\n * @param t2 Second text node to merge. This node will be removed after merging.\n * @returns Position after merging text nodes.\n */\nfunction mergeTextNodes( t1: Text, t2: Text ): Position {\n\t// Merge text data into first text node and remove second one.\n\tconst nodeBeforeLength = t1.data.length;\n\tt1._data += t2.data;\n\tt2._remove();\n\n\treturn new Position( t1, nodeBeforeLength );\n}\n\nconst validNodesToInsert = [ Text, AttributeElement, ContainerElement, EmptyElement, RawElement, UIElement ];\n\n/**\n * Checks if provided nodes are valid to insert.\n *\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-insert-invalid-node` when nodes to insert\n * contains instances that are not supported ones (see error description for valid ones.\n */\nfunction validateNodesToInsert( nodes: Iterable<Node>, errorContext: Document ): void {\n\tfor ( const node of nodes ) {\n\t\tif ( !validNodesToInsert.some( ( validNode => node instanceof validNode ) ) ) { // eslint-disable-line no-use-before-define\n\t\t\t/**\n\t\t\t * One of the nodes to be inserted is of an invalid type.\n\t\t\t *\n\t\t\t * Nodes to be inserted with {@link module:engine/view/downcastwriter~DowncastWriter#insert `DowncastWriter#insert()`} should be\n\t\t\t * of the following types:\n\t\t\t *\n\t\t\t * * {@link module:engine/view/attributeelement~AttributeElement AttributeElement},\n\t\t\t * * {@link module:engine/view/containerelement~ContainerElement ContainerElement},\n\t\t\t * * {@link module:engine/view/emptyelement~EmptyElement EmptyElement},\n\t\t\t * * {@link module:engine/view/uielement~UIElement UIElement},\n\t\t\t * * {@link module:engine/view/rawelement~RawElement RawElement},\n\t\t\t * * {@link module:engine/view/text~Text Text}.\n\t\t\t *\n\t\t\t * @error view-writer-insert-invalid-node-type\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-writer-insert-invalid-node-type', errorContext );\n\t\t}\n\n\t\tif ( !node.is( '$text' ) ) {\n\t\t\tvalidateNodesToInsert( ( node as Element ).getChildren(), errorContext );\n\t\t}\n\t}\n}\n\n/**\n * Checks if node is ContainerElement or DocumentFragment, because in most cases they should be treated the same way.\n *\n * @returns Returns `true` if node is instance of ContainerElement or DocumentFragment.\n */\nfunction isContainerOrFragment( node: Node | DocumentFragment ): boolean {\n\treturn node && ( node.is( 'containerElement' ) || node.is( 'documentFragment' ) );\n}\n\n/**\n * Checks if {@link module:engine/view/range~Range#start range start} and {@link module:engine/view/range~Range#end range end} are placed\n * inside same {@link module:engine/view/containerelement~ContainerElement container element}.\n * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-writer-invalid-range-container` when validation fails.\n */\nfunction validateRangeContainer( range: Range, errorContext: Document ) {\n\tconst startContainer = getParentContainer( range.start );\n\tconst endContainer = getParentContainer( range.end );\n\n\tif ( !startContainer || !endContainer || startContainer !== endContainer ) {\n\t\t/**\n\t\t * The container of the given range is invalid.\n\t\t *\n\t\t * This may happen if {@link module:engine/view/range~Range#start range start} and\n\t\t * {@link module:engine/view/range~Range#end range end} positions are not placed inside the same container element or\n\t\t * a parent container for these positions cannot be found.\n\t\t *\n\t\t * Methods like {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#remove()`},\n\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#clean()`},\n\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#wrap()`},\n\t\t * {@link module:engine/view/downcastwriter~DowncastWriter#wrap `DowncastWriter#unwrap()`} need to be called\n\t\t * on a range that has its start and end positions located in the same container element. Both positions can be\n\t\t * nested within other elements (e.g. an attribute element) but the closest container ancestor must be the same.\n\t\t *\n\t\t * @error view-writer-invalid-range-container\n\t\t */\n\t\tthrow new CKEditorError( 'view-writer-invalid-range-container', errorContext );\n\t}\n}\n\n/**\n * Checks if two attribute elements can be joined together. Elements can be joined together if, and only if\n * they do not have ids specified.\n */\nfunction canBeJoined( a: AttributeElement, b: AttributeElement ) {\n\treturn a.id === null && b.id === null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport { keyCodes, isText, type KeystrokeInfo } from '@ckeditor/ckeditor5-utils';\nimport type View from './view.js';\nimport type DomEventData from './observer/domeventdata.js';\nimport type { ViewDocumentArrowKeyEvent } from './observer/arrowkeysobserver.js';\n\n/**\n * Set of utilities related to handling block and inline fillers.\n *\n * Browsers do not allow to put caret in elements which does not have height. Because of it, we need to fill all\n * empty elements which should be selectable with elements or characters called \"fillers\". Unfortunately there is no one\n * universal filler, this is why two types are uses:\n *\n * * Block filler is an element which fill block elements, like `<p>`. CKEditor uses `<br>` as a block filler during the editing,\n * as browsers do natively. So instead of an empty `<p>` there will be `<p><br></p>`. The advantage of block filler is that\n * it is transparent for the selection, so when the caret is before the `<br>` and user presses right arrow he will be\n * moved to the next paragraph, not after the `<br>`. The disadvantage is that it breaks a block, so it can not be used\n * in the middle of a line of text. The {@link module:engine/view/filler~BR_FILLER `<br>` filler} can be replaced with any other\n * character in the data output, for instance {@link module:engine/view/filler~NBSP_FILLER non-breaking space} or\n * {@link module:engine/view/filler~MARKED_NBSP_FILLER marked non-breaking space}.\n *\n * * Inline filler is a filler which does not break a line of text, so it can be used inside the text, for instance in the empty\n * `<b>` surrendered by text: `foo<b></b>bar`, if we want to put the caret there. CKEditor uses a sequence of the zero-width\n * spaces as an {@link module:engine/view/filler~INLINE_FILLER inline filler} having the predetermined\n * {@link module:engine/view/filler~INLINE_FILLER_LENGTH length}. A sequence is used, instead of a single character to\n * avoid treating random zero-width spaces as the inline filler. Disadvantage of the inline filler is that it is not\n * transparent for the selection. The arrow key moves the caret between zero-width spaces characters, so the additional\n * code is needed to handle the caret.\n *\n * Both inline and block fillers are handled by the {@link module:engine/view/renderer~Renderer renderer} and are not present in the\n * view.\n *\n * @module engine/view/filler\n */\n\n/**\n * Non-breaking space filler creator. This function creates the `&nbsp;` text node.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~MARKED_NBSP_FILLER\n * @see module:engine/view/filler~BR_FILLER\n */\nexport const NBSP_FILLER = ( domDocument: Document ): Text => domDocument.createTextNode( '\\u00A0' );\n\n/**\n * Marked non-breaking space filler creator. This function creates the `<span data-cke-filler=\"true\">&nbsp;</span>` element.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~NBSP_FILLER\n * @see module:engine/view/filler~BR_FILLER\n */\nexport const MARKED_NBSP_FILLER = ( domDocument: Document ): HTMLSpanElement => {\n\tconst span = domDocument.createElement( 'span' );\n\tspan.dataset.ckeFiller = 'true';\n\tspan.innerText = '\\u00A0';\n\n\treturn span;\n};\n\n/**\n * `<br>` filler creator. This function creates the `<br data-cke-filler=\"true\">` element.\n * It defines how the filler is created.\n *\n * @see module:engine/view/filler~NBSP_FILLER\n * @see module:engine/view/filler~MARKED_NBSP_FILLER\n */\nexport const BR_FILLER = ( domDocument: Document ): HTMLBRElement => {\n\tconst fillerBr = domDocument.createElement( 'br' );\n\tfillerBr.dataset.ckeFiller = 'true';\n\n\treturn fillerBr;\n};\n\n/**\n * Length of the {@link module:engine/view/filler~INLINE_FILLER INLINE_FILLER}.\n */\nexport const INLINE_FILLER_LENGTH = 7;\n\n/**\n * Inline filler which is a sequence of the word joiners.\n */\nexport const INLINE_FILLER = '\\u2060'.repeat( INLINE_FILLER_LENGTH );\n\n/**\n * Checks if the node is a text node which starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n *\n * ```ts\n * startsWithFiller( document.createTextNode( INLINE_FILLER ) ); // true\n * startsWithFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // true\n * startsWithFiller( document.createTextNode( 'foo' ) ); // false\n * startsWithFiller( document.createElement( 'p' ) ); // false\n * ```\n *\n * @param domNode DOM node.\n * @returns True if the text node starts with the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function startsWithFiller( domNode: Node | string ): boolean {\n\tif ( typeof domNode == 'string' ) {\n\t\treturn domNode.substr( 0, INLINE_FILLER_LENGTH ) === INLINE_FILLER;\n\t}\n\n\treturn isText( domNode ) && ( domNode.data.substr( 0, INLINE_FILLER_LENGTH ) === INLINE_FILLER );\n}\n\n/**\n * Checks if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n *\n * ```ts\n * isInlineFiller( document.createTextNode( INLINE_FILLER ) ); // true\n * isInlineFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ); // false\n * ```\n *\n * @param domText DOM text node.\n * @returns True if the text node contains only the {@link module:engine/view/filler~INLINE_FILLER inline filler}.\n */\nexport function isInlineFiller( domText: Text ): boolean {\n\treturn domText.data.length == INLINE_FILLER_LENGTH && startsWithFiller( domText );\n}\n\n/**\n * Get string data from the text node, removing an {@link module:engine/view/filler~INLINE_FILLER inline filler} from it,\n * if text node contains it.\n *\n * ```ts\n * getDataWithoutFiller( document.createTextNode( INLINE_FILLER + 'foo' ) ) == 'foo' // true\n * getDataWithoutFiller( document.createTextNode( 'foo' ) ) == 'foo' // true\n * ```\n *\n * @param domText DOM text node, possible with inline filler.\n * @returns Data without filler.\n */\nexport function getDataWithoutFiller( domText: Text | string ): string {\n\tconst data = typeof domText == 'string' ? domText : domText.data;\n\n\tif ( startsWithFiller( domText ) ) {\n\t\treturn data.slice( INLINE_FILLER_LENGTH );\n\t}\n\n\treturn data;\n}\n\n/**\n * Assign key observer which move cursor from the end of the inline filler to the beginning of it when\n * the left arrow is pressed, so the filler does not break navigation.\n *\n * @param view View controller instance we should inject quirks handling on.\n */\nexport function injectQuirksHandling( view: View ): void {\n\tview.document.on<ViewDocumentArrowKeyEvent>( 'arrowKey', jumpOverInlineFiller, { priority: 'low' } );\n}\n\n/**\n * Move cursor from the end of the inline filler to the beginning of it when, so the filler does not break navigation.\n */\nfunction jumpOverInlineFiller( evt: unknown, data: DomEventData & KeystrokeInfo ) {\n\tif ( data.keyCode == keyCodes.arrowleft ) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView!.getSelection()!;\n\n\t\tif ( domSelection.rangeCount == 1 && domSelection.getRangeAt( 0 ).collapsed ) {\n\t\t\tconst domParent = domSelection.getRangeAt( 0 ).startContainer;\n\t\t\tconst domOffset = domSelection.getRangeAt( 0 ).startOffset;\n\n\t\t\tif ( startsWithFiller( domParent ) && domOffset <= INLINE_FILLER_LENGTH ) {\n\t\t\t\tdomSelection.collapse( domParent, 0 );\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/renderer\n */\n\nimport ViewText from './text.js';\nimport ViewPosition from './position.js';\nimport { INLINE_FILLER, INLINE_FILLER_LENGTH, startsWithFiller, isInlineFiller } from './filler.js';\n\nimport {\n\tCKEditorError,\n\tObservableMixin,\n\tdiff,\n\tenv,\n\tfastDiff,\n\tinsertAt,\n\tisComment,\n\tisNode,\n\tisText,\n\tremove,\n\tindexOf,\n\ttype DiffResult,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport type { ChangeType } from './document.js';\nimport type DocumentSelection from './documentselection.js';\nimport type DomConverter from './domconverter.js';\nimport type ViewElement from './element.js';\nimport type ViewNode from './node.js';\n\nimport '../../theme/renderer.css';\n\ntype DomText = globalThis.Text;\ntype DomNode = globalThis.Node;\ntype DomDocument = globalThis.Document;\ntype DomElement = globalThis.HTMLElement;\ntype DomSelection = globalThis.Selection;\n\n/**\n * Renderer is responsible for updating the DOM structure and the DOM selection based on\n * the {@link module:engine/view/renderer~Renderer#markToSync information about updated view nodes}.\n * In other words, it renders the view to the DOM.\n *\n * Its main responsibility is to make only the necessary, minimal changes to the DOM. However, unlike in many\n * virtual DOM implementations, the primary reason for doing minimal changes is not the performance but ensuring\n * that native editing features such as text composition, autocompletion, spell checking, selection's x-index are\n * affected as little as possible.\n *\n * Renderer uses {@link module:engine/view/domconverter~DomConverter} to transform view nodes and positions\n * to and from the DOM.\n */\nexport default class Renderer extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * Set of DOM Documents instances.\n\t */\n\tpublic readonly domDocuments: Set<DomDocument> = new Set();\n\n\t/**\n\t * Converter instance.\n\t */\n\tpublic readonly domConverter: DomConverter;\n\n\t/**\n\t * Set of nodes which attributes changed and may need to be rendered.\n\t */\n\tpublic readonly markedAttributes: Set<ViewElement> = new Set();\n\n\t/**\n\t * Set of elements which child lists changed and may need to be rendered.\n\t */\n\tpublic readonly markedChildren: Set<ViewElement> = new Set();\n\n\t/**\n\t * Set of text nodes which text data changed and may need to be rendered.\n\t */\n\tpublic readonly markedTexts: Set<ViewNode> = new Set();\n\n\t/**\n\t * View selection. Renderer updates DOM selection based on the view selection.\n\t */\n\tpublic readonly selection: DocumentSelection;\n\n\t/**\n\t * Indicates if the view document is focused and selection can be rendered. Selection will not be rendered if\n\t * this is set to `false`.\n\t *\n\t * @observable\n\t */\n\tdeclare public readonly isFocused: boolean;\n\n\t/**\n\t * Indicates whether the user is making a selection in the document (e.g. holding the mouse button and moving the cursor).\n\t * When they stop selecting, the property goes back to `false`.\n\t *\n\t * Note: In some browsers, the renderer will stop rendering the selection and inline fillers while the user is making\n\t * a selection to avoid glitches in DOM selection\n\t * (https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723).\n\t *\n\t * @observable\n\t */\n\tdeclare public readonly isSelecting: boolean;\n\n\t/**\n\t * True if composition is in progress inside the document.\n\t *\n\t * This property is bound to the {@link module:engine/view/document~Document#isComposing `Document#isComposing`} property.\n\t *\n\t * @observable\n\t */\n\tdeclare public readonly isComposing: boolean;\n\n\t/**\n\t * The text node in which the inline filler was rendered.\n\t */\n\tprivate _inlineFiller: DomText | null = null;\n\n\t/**\n\t * DOM element containing fake selection.\n\t */\n\tprivate _fakeSelectionContainer: DomElement | null = null;\n\n\t/**\n\t * Creates a renderer instance.\n\t *\n\t * @param domConverter Converter instance.\n\t * @param selection View selection.\n\t */\n\tconstructor( domConverter: DomConverter, selection: DocumentSelection ) {\n\t\tsuper();\n\n\t\tthis.domConverter = domConverter;\n\t\tthis.selection = selection;\n\n\t\tthis.set( 'isFocused', false );\n\t\tthis.set( 'isSelecting', false );\n\t\tthis.set( 'isComposing', false );\n\n\t\t// Rendering the selection and inline filler manipulation should be postponed in (non-Android) Blink until the user finishes\n\t\t// creating the selection in DOM to avoid accidental selection collapsing\n\t\t// (https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723).\n\t\t// When the user stops selecting, all pending changes should be rendered ASAP, though.\n\t\tif ( env.isBlink && !env.isAndroid ) {\n\t\t\tthis.on<ObservableChangeEvent>( 'change:isSelecting', () => {\n\t\t\t\tif ( !this.isSelecting ) {\n\t\t\t\t\tthis.render();\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Marks a view node to be updated in the DOM by {@link #render `render()`}.\n\t *\n\t * Note that only view nodes whose parents have corresponding DOM elements need to be marked to be synchronized.\n\t *\n\t * @see #markedAttributes\n\t * @see #markedChildren\n\t * @see #markedTexts\n\t *\n\t * @param type Type of the change.\n\t * @param node ViewNode to be marked.\n\t */\n\tpublic markToSync( type: ChangeType, node: ViewNode ): void {\n\t\tif ( type === 'text' ) {\n\t\t\tif ( this.domConverter.mapViewToDom( node.parent! ) ) {\n\t\t\t\tthis.markedTexts.add( node );\n\t\t\t}\n\t\t} else {\n\t\t\t// If the node has no DOM element it is not rendered yet,\n\t\t\t// its children/attributes do not need to be marked to be sync.\n\t\t\tif ( !this.domConverter.mapViewToDom( node as ViewElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( type === 'attributes' ) {\n\t\t\t\tthis.markedAttributes.add( node as ViewElement );\n\t\t\t} else if ( type === 'children' ) {\n\t\t\t\tthis.markedChildren.add( node as ViewElement );\n\t\t\t} else {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t\t\t\tconst unreachable: never = type;\n\n\t\t\t\t/**\n\t\t\t\t * Unknown type passed to Renderer.markToSync.\n\t\t\t\t *\n\t\t\t\t * @error view-renderer-unknown-type\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'view-renderer-unknown-type', this );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Renders all buffered changes ({@link #markedAttributes}, {@link #markedChildren} and {@link #markedTexts}) and\n\t * the current view selection (if needed) to the DOM by applying a minimal set of changes to it.\n\t *\n\t * Renderer tries not to break the text composition (e.g. IME) and x-index of the selection,\n\t * so it does as little as it is needed to update the DOM.\n\t *\n\t * Renderer also handles {@link module:engine/view/filler fillers}. Especially, it checks if the inline filler is needed\n\t * at the selection position and adds or removes it. To prevent breaking text composition inline filler will not be\n\t * removed as long as the selection is in the text node which needed it at first.\n\t */\n\tpublic render(): void {\n\t\t// Ignore rendering while in the composition mode. Composition events are not cancellable and browser will modify the DOM tree.\n\t\t// All marked elements, attributes, etc. will wait until next render after the composition ends.\n\t\t// On Android composition events are immediately applied to the model, so we don't need to skip rendering,\n\t\t// and we should not do it because the difference between view and DOM could lead to position mapping problems.\n\t\tif ( this.isComposing && !env.isAndroid ) {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Rendering aborted while isComposing.',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic'\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\treturn;\n\t\t}\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[Renderer]%c Rendering',\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold'\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tlet inlineFillerPosition: ViewPosition | null = null;\n\t\tconst isInlineFillerRenderingPossible = env.isBlink && !env.isAndroid ? !this.isSelecting : true;\n\n\t\t// Refresh mappings.\n\t\tfor ( const element of this.markedChildren ) {\n\t\t\tthis._updateChildrenMappings( element );\n\t\t}\n\n\t\t// Don't manipulate inline fillers while the selection is being made in (non-Android) Blink to prevent accidental\n\t\t// DOM selection collapsing\n\t\t// (https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723).\n\t\tif ( isInlineFillerRenderingPossible ) {\n\t\t\t// There was inline filler rendered in the DOM but it's not\n\t\t\t// at the selection position any more, so we can remove it\n\t\t\t// (cause even if it's needed, it must be placed in another location).\n\t\t\tif ( this._inlineFiller && !this._isSelectionInInlineFiller() ) {\n\t\t\t\tthis._removeInlineFiller();\n\t\t\t}\n\n\t\t\t// If we've got the filler, let's try to guess its position in the view.\n\t\t\tif ( this._inlineFiller ) {\n\t\t\t\tinlineFillerPosition = this._getInlineFillerPosition();\n\t\t\t}\n\t\t\t// Otherwise, if it's needed, create it at the selection position.\n\t\t\telse if ( this._needsInlineFillerAtSelection() ) {\n\t\t\t\tinlineFillerPosition = this.selection.getFirstPosition()!;\n\n\t\t\t\t// Do not use `markToSync` so it will be added even if the parent is already added.\n\t\t\t\tthis.markedChildren.add( inlineFillerPosition.parent as ViewElement );\n\t\t\t}\n\t\t}\n\t\t// Make sure the inline filler has any parent, so it can be mapped to view position by DomConverter.\n\t\telse if ( this._inlineFiller && this._inlineFiller.parentNode ) {\n\t\t\t// While the user is making selection, preserve the inline filler at its original position.\n\t\t\tinlineFillerPosition = this.domConverter.domPositionToView( this._inlineFiller )!;\n\n\t\t\t// While down-casting the document selection attributes, all existing empty\n\t\t\t// attribute elements (for selection position) are removed from the view and DOM,\n\t\t\t// so make sure that we were able to map filler position.\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/12026\n\t\t\tif ( inlineFillerPosition && inlineFillerPosition.parent.is( '$text' ) ) {\n\t\t\t\t// The inline filler position is expected to be before the text node.\n\t\t\t\tinlineFillerPosition = ViewPosition._createBefore( inlineFillerPosition.parent );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const element of this.markedAttributes ) {\n\t\t\tthis._updateAttrs( element );\n\t\t}\n\n\t\tfor ( const element of this.markedChildren ) {\n\t\t\tthis._updateChildren( element, { inlineFillerPosition } );\n\t\t}\n\n\t\tfor ( const node of this.markedTexts ) {\n\t\t\tif ( !this.markedChildren.has( node.parent as ViewElement ) && this.domConverter.mapViewToDom( node.parent as ViewElement ) ) {\n\t\t\t\tthis._updateText( node as ViewText, { inlineFillerPosition } );\n\t\t\t}\n\t\t}\n\n\t\t// * Check whether the inline filler is required and where it really is in the DOM.\n\t\t//   At this point in most cases it will be in the DOM, but there are exceptions.\n\t\t//   For example, if the inline filler was deep in the created DOM structure, it will not be created.\n\t\t//   Similarly, if it was removed at the beginning of this function and then neither text nor children were updated,\n\t\t//   it will not be present. Fix those and similar scenarios.\n\t\t// * Don't manipulate inline fillers while the selection is being made in (non-Android) Blink to prevent accidental\n\t\t//   DOM selection collapsing\n\t\t//   (https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723).\n\t\tif ( isInlineFillerRenderingPossible ) {\n\t\t\tif ( inlineFillerPosition ) {\n\t\t\t\tconst fillerDomPosition = this.domConverter.viewPositionToDom( inlineFillerPosition )!;\n\t\t\t\tconst domDocument = fillerDomPosition.parent.ownerDocument!;\n\n\t\t\t\tif ( !startsWithFiller( fillerDomPosition.parent ) ) {\n\t\t\t\t\t// Filler has not been created at filler position. Create it now.\n\t\t\t\t\tthis._inlineFiller = addInlineFiller( domDocument, fillerDomPosition.parent, fillerDomPosition.offset );\n\t\t\t\t} else {\n\t\t\t\t\t// Filler has been found, save it.\n\t\t\t\t\tthis._inlineFiller = fillerDomPosition.parent as DomText;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// There is no filler needed.\n\t\t\t\tthis._inlineFiller = null;\n\t\t\t}\n\t\t}\n\n\t\t// First focus the new editing host, then update the selection.\n\t\t// Otherwise, FF may throw an error (https://github.com/ckeditor/ckeditor5/issues/721).\n\t\tthis._updateFocus();\n\t\tthis._updateSelection();\n\n\t\tthis.domConverter._clearTemporaryCustomProperties();\n\n\t\tthis.markedTexts.clear();\n\t\tthis.markedAttributes.clear();\n\t\tthis.markedChildren.clear();\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t// @if CK_DEBUG_TYPING // }\n\t}\n\n\t/**\n\t * Updates mappings of view element's children.\n\t *\n\t * Children that were replaced in the view structure by similar elements (same tag name) are treated as 'replaced'.\n\t * This means that their mappings can be updated so the new view elements are mapped to the existing DOM elements.\n\t * Thanks to that these elements do not need to be re-rendered completely.\n\t *\n\t * @param viewElement The view element whose children mappings will be updated.\n\t */\n\tprivate _updateChildrenMappings( viewElement: ViewElement ): void {\n\t\tconst domElement = this.domConverter.mapViewToDom( viewElement );\n\n\t\tif ( !domElement ) {\n\t\t\t// If there is no `domElement` it means that it was already removed from DOM and there is no need to process it.\n\t\t\treturn;\n\t\t}\n\n\t\t// Removing nodes from the DOM as we iterate can cause `actualDomChildren`\n\t\t// (which is a live-updating `NodeList`) to get out of sync with the\n\t\t// indices that we compute as we iterate over `actions`.\n\t\t// This would produce incorrect element mappings.\n\t\t//\n\t\t// Converting live list to an array to make the list static.\n\t\tconst actualDomChildren = Array.from(\n\t\t\tdomElement.childNodes\n\t\t);\n\t\tconst expectedDomChildren = Array.from(\n\t\t\tthis.domConverter.viewChildrenToDom( viewElement, { withChildren: false } )\n\t\t);\n\t\tconst diff = this._diffNodeLists( actualDomChildren, expectedDomChildren );\n\t\tconst actions = this._findUpdateActions( diff, actualDomChildren, expectedDomChildren, areSimilarElements );\n\n\t\tif ( actions.indexOf( 'update' ) !== -1 ) {\n\t\t\tconst counter = { equal: 0, insert: 0, delete: 0 };\n\n\t\t\tfor ( const action of actions ) {\n\t\t\t\tif ( action === 'update' ) {\n\t\t\t\t\tconst insertIndex = counter.equal + counter.insert;\n\t\t\t\t\tconst deleteIndex = counter.equal + counter.delete;\n\t\t\t\t\tconst viewChild = viewElement.getChild( insertIndex );\n\n\t\t\t\t\t// UIElement and RawElement are special cases. Their children are not stored in a view (#799)\n\t\t\t\t\t// so we cannot use them with replacing flow (since they use view children during rendering\n\t\t\t\t\t// which will always result in rendering empty elements).\n\t\t\t\t\tif ( viewChild && !viewChild.is( 'uiElement' ) && !viewChild.is( 'rawElement' ) ) {\n\t\t\t\t\t\tthis._updateElementMappings( viewChild as ViewElement, actualDomChildren[ deleteIndex ] as DomElement );\n\t\t\t\t\t}\n\n\t\t\t\t\tremove( expectedDomChildren[ insertIndex ] );\n\t\t\t\t\tcounter.equal++;\n\t\t\t\t} else {\n\t\t\t\t\tcounter[ action ]++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Updates mappings of a given view element.\n\t *\n\t * @param viewElement The view element whose mappings will be updated.\n\t * @param domElement The DOM element representing the given view element.\n\t */\n\tprivate _updateElementMappings( viewElement: ViewElement, domElement: DomElement ): void {\n\t\t// Remap 'DomConverter' bindings.\n\t\tthis.domConverter.unbindDomElement( domElement );\n\t\tthis.domConverter.bindElements( domElement, viewElement );\n\n\t\t// View element may have children which needs to be updated, but are not marked, mark them to update.\n\t\tthis.markedChildren.add( viewElement );\n\n\t\t// Because we replace new view element mapping with the existing one, the corresponding DOM element\n\t\t// will not be rerendered. The new view element may have different attributes than the previous one.\n\t\t// Since its corresponding DOM element will not be rerendered, new attributes will not be added\n\t\t// to the DOM, so we need to mark it here to make sure its attributes gets updated. See #1427 for more\n\t\t// detailed case study.\n\t\t// Also there are cases where replaced element is removed from the view structure and then has\n\t\t// its attributes changed or removed. In such cases the element will not be present in `markedAttributes`\n\t\t// and also may be the same (`element.isSimilar()`) as the reused element not having its attributes updated.\n\t\t// To prevent such situations we always mark reused element to have its attributes rerenderd (#1560).\n\t\tthis.markedAttributes.add( viewElement );\n\t}\n\n\t/**\n\t * Gets the position of the inline filler based on the current selection.\n\t * Here, we assume that we know that the filler is needed and\n\t * {@link #_isSelectionInInlineFiller is at the selection position}, and, since it is needed,\n\t * it is somewhere at the selection position.\n\t *\n\t * Note: The filler position cannot be restored based on the filler's DOM text node, because\n\t * when this method is called (before rendering), the bindings will often be broken. View-to-DOM\n\t * bindings are only dependable after rendering.\n\t */\n\tprivate _getInlineFillerPosition(): ViewPosition {\n\t\tconst firstPos = this.selection.getFirstPosition()!;\n\n\t\tif ( firstPos.parent.is( '$text' ) ) {\n\t\t\treturn ViewPosition._createBefore( firstPos.parent );\n\t\t} else {\n\t\t\treturn firstPos;\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` if the selection has not left the inline filler's text node.\n\t * If it is `true`, it means that the filler had been added for a reason and the selection did not\n\t * leave the filler's text node. For example, the user can be in the middle of a composition so it should not be touched.\n\t *\n\t * @returns `true` if the inline filler and selection are in the same place.\n\t */\n\tprivate _isSelectionInInlineFiller(): boolean {\n\t\tif ( this.selection.rangeCount != 1 || !this.selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Note, we can't check if selection's position equals position of the\n\t\t// this._inlineFiller node, because of #663. We may not be able to calculate\n\t\t// the filler's position in the view at this stage.\n\t\t// Instead, we check it the other way – whether selection is anchored in\n\t\t// that text node or next to it.\n\n\t\t// Possible options are:\n\t\t// \"FILLER{}\"\n\t\t// \"FILLERadded-text{}\"\n\t\tconst selectionPosition = this.selection.getFirstPosition()!;\n\t\tconst position = this.domConverter.viewPositionToDom( selectionPosition );\n\n\t\tif ( position && isText( position.parent ) && startsWithFiller( position.parent ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Removes the inline filler.\n\t */\n\tprivate _removeInlineFiller(): void {\n\t\tconst domFillerNode = this._inlineFiller!;\n\n\t\t// Something weird happened and the stored node doesn't contain the filler's text.\n\t\tif ( !startsWithFiller( domFillerNode ) ) {\n\t\t\t/**\n\t\t\t * The inline filler node was lost. Most likely, something overwrote the filler text node\n\t\t\t * in the DOM.\n\t\t\t *\n\t\t\t * @error view-renderer-filler-was-lost\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-renderer-filler-was-lost', this );\n\t\t}\n\n\t\tif ( isInlineFiller( domFillerNode ) ) {\n\t\t\tdomFillerNode.remove();\n\t\t} else {\n\t\t\tdomFillerNode.data = domFillerNode.data.substr( INLINE_FILLER_LENGTH );\n\t\t}\n\n\t\tthis._inlineFiller = null;\n\t}\n\n\t/**\n\t * Checks if the inline {@link module:engine/view/filler filler} should be added.\n\t *\n\t * @returns `true` if the inline filler should be added.\n\t */\n\tprivate _needsInlineFillerAtSelection(): boolean {\n\t\tif ( this.selection.rangeCount != 1 || !this.selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst selectionPosition = this.selection.getFirstPosition()!;\n\t\tconst selectionParent = selectionPosition.parent;\n\t\tconst selectionOffset = selectionPosition.offset;\n\n\t\t// If there is no DOM root we do not care about fillers.\n\t\tif ( !this.domConverter.mapViewToDom( selectionParent.root ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !( selectionParent.is( 'element' ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Prevent adding inline filler inside elements with contenteditable=false.\n\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/1170\n\t\tif ( !isEditable( selectionParent ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst nodeBefore = selectionPosition.nodeBefore;\n\t\tconst nodeAfter = selectionPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof ViewText || nodeAfter instanceof ViewText ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We have block filler, we do not need inline one.\n\t\tif ( selectionOffset === selectionParent.getFillerOffset!() && ( !nodeBefore || !nodeBefore.is( 'element', 'br' ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Do not use inline filler while typing outside inline elements on Android.\n\t\t// The deleteContentBackward would remove part of the inline filler instead of removing last letter in a link.\n\t\tif ( env.isAndroid && ( nodeBefore || nodeAfter ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks if text needs to be updated and possibly updates it.\n\t *\n\t * @param viewText View text to update.\n\t * @param options.inlineFillerPosition The position where the inline filler should be rendered.\n\t */\n\tprivate _updateText( viewText: ViewText, options: { inlineFillerPosition?: ViewPosition | null } ) {\n\t\tconst domText = this.domConverter.findCorrespondingDomText( viewText )!;\n\t\tconst newDomText = this.domConverter.viewToDom( viewText );\n\n\t\tlet expectedText = newDomText.data;\n\t\tconst filler = options.inlineFillerPosition;\n\n\t\tif ( filler && filler.parent == viewText.parent && filler.offset == viewText.index ) {\n\t\t\texpectedText = INLINE_FILLER + expectedText;\n\t\t}\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[Renderer]%c Update text',\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: normal'\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tthis._updateTextNode( domText, expectedText );\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t// @if CK_DEBUG_TYPING // }\n\t}\n\n\t/**\n\t * Checks if attribute list needs to be updated and possibly updates it.\n\t *\n\t * @param viewElement The view element to update.\n\t */\n\tprivate _updateAttrs( viewElement: ViewElement ): void {\n\t\tconst domElement = this.domConverter.mapViewToDom( viewElement );\n\n\t\tif ( !domElement ) {\n\t\t\t// If there is no `domElement` it means that 'viewElement' is outdated as its mapping was updated\n\t\t\t// in 'this._updateChildrenMappings()'. There is no need to process it as new view element which\n\t\t\t// replaced old 'viewElement' mapping was also added to 'this.markedAttributes'\n\t\t\t// in 'this._updateChildrenMappings()' so it will be processed separately.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove attributes from DOM elements if they do not exist in the view.\n\t\t//\n\t\t// Note: It is important to first remove DOM attributes and then set new ones, because some view attributes may be renamed\n\t\t// as they are set on DOM (due to unsafe attributes handling). If we set the view attribute first, and then remove\n\t\t// non-existing DOM attributes, then we would remove the attribute that we just set.\n\t\tfor ( const domAttr of ( domElement as DomElement ).attributes ) {\n\t\t\tconst key = domAttr.name;\n\n\t\t\t// All other attributes not present in the DOM should be removed.\n\t\t\tif ( !viewElement.hasAttribute( key ) ) {\n\t\t\t\tthis.domConverter.removeDomElementAttribute( domElement as DomElement, key );\n\t\t\t}\n\t\t}\n\n\t\t// Add or overwrite attributes.\n\t\tfor ( const key of viewElement.getAttributeKeys() ) {\n\t\t\tthis.domConverter.setDomElementAttribute( domElement as DomElement, key, viewElement.getAttribute( key )!, viewElement );\n\t\t}\n\t}\n\n\t/**\n\t * Checks if elements child list needs to be updated and possibly updates it.\n\t *\n\t * Note that on Android, to reduce the risk of composition breaks, it tries to update data of an existing\n\t * child text nodes instead of replacing them completely.\n\t *\n\t * @param viewElement View element to update.\n\t * @param options.inlineFillerPosition The position where the inline filler should be rendered.\n\t */\n\tprivate _updateChildren( viewElement: ViewElement, options: { inlineFillerPosition: ViewPosition | null } ) {\n\t\tconst domElement = this.domConverter.mapViewToDom( viewElement );\n\n\t\tif ( !domElement ) {\n\t\t\t// If there is no `domElement` it means that it was already removed from DOM.\n\t\t\t// There is no need to process it. It will be processed when re-inserted.\n\t\t\treturn;\n\t\t}\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[Renderer]%c Update children',\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: normal'\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t// IME on Android inserts a new text node while typing after a link\n\t\t// instead of updating an existing text node that follows the link.\n\t\t// We must normalize those text nodes so the diff won't get confused.\n\t\t// https://github.com/ckeditor/ckeditor5/issues/12574.\n\t\tif ( env.isAndroid ) {\n\t\t\tlet previousDomNode = null;\n\n\t\t\tfor ( const domNode of Array.from( domElement.childNodes ) ) {\n\t\t\t\tif ( previousDomNode && isText( previousDomNode ) && isText( domNode ) ) {\n\t\t\t\t\tdomElement.normalize();\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tpreviousDomNode = domNode;\n\t\t\t}\n\t\t}\n\n\t\tconst inlineFillerPosition = options.inlineFillerPosition;\n\t\tconst actualDomChildren = domElement.childNodes;\n\t\tconst expectedDomChildren = Array.from(\n\t\t\tthis.domConverter.viewChildrenToDom( viewElement, { bind: true } )\n\t\t);\n\n\t\t// Inline filler element has to be created as it is present in the DOM, but not in the view. It is required\n\t\t// during diffing so text nodes could be compared correctly and also during rendering to maintain\n\t\t// proper order and indexes while updating the DOM.\n\t\tif ( inlineFillerPosition && inlineFillerPosition.parent === viewElement ) {\n\t\t\taddInlineFiller( ( domElement as DomElement ).ownerDocument, expectedDomChildren, inlineFillerPosition.offset );\n\t\t}\n\n\t\tconst diff = this._diffNodeLists( actualDomChildren, expectedDomChildren );\n\n\t\t// We need to make sure that we update the existing text node and not replace it with another one.\n\t\t// The composition and different \"language\" browser extensions are fragile to text node being completely replaced.\n\t\tconst actions = this._findUpdateActions( diff, actualDomChildren, expectedDomChildren, areTextNodes );\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping && actions.every( a => a == 'equal' ) ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Nothing to update.',\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic'\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tlet i = 0;\n\t\tconst nodesToUnbind: Set<DomNode> = new Set();\n\n\t\t// Handle deletions first.\n\t\t// This is to prevent a situation where an element that already exists in `actualDomChildren` is inserted at a different\n\t\t// index in `actualDomChildren`. Since `actualDomChildren` is a `NodeList`, this works like move, not like an insert,\n\t\t// and it disrupts the whole algorithm. See https://github.com/ckeditor/ckeditor5/issues/6367.\n\t\t//\n\t\t// It doesn't matter in what order we remove or add nodes, as long as we remove and add correct nodes at correct indexes.\n\t\tfor ( const action of actions ) {\n\t\t\tif ( action === 'delete' ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING //\tconst node = actualDomChildren[ i ];\n\t\t\t\t// @if CK_DEBUG_TYPING // \tif ( isText( node ) ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\tconsole.info( '%c[Renderer]%c Remove text node' +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\t`%c${ _escapeTextNodeData( node.data ) }%c (${ node.data.length })`,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\t'color: green; font-weight: bold',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\tthis.isComposing ? 'color: red; font-weight: bold' : '', 'color: blue', ''\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t);\n\t\t\t\t// @if CK_DEBUG_TYPING // \t} else {\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\tconsole.info( '%c[Renderer]%c Remove element' +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: `,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\t'color: green; font-weight: bold',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\tthis.isComposing ? 'color: red; font-weight: bold' : '',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t\tnode\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t);\n\t\t\t\t// @if CK_DEBUG_TYPING // \t}\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\tnodesToUnbind.add( actualDomChildren[ i ] as DomElement );\n\t\t\t\tremove( actualDomChildren[ i ] );\n\t\t\t} else if ( action === 'equal' || action === 'update' ) {\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\ti = 0;\n\n\t\tfor ( const action of actions ) {\n\t\t\tif ( action === 'insert' ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING //\tconst node = expectedDomChildren[ i ];\n\t\t\t\t// @if CK_DEBUG_TYPING //\tif ( isText( node ) ) {\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\tconsole.info( '%c[Renderer]%c Insert text node' +\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t\t`%c${ _escapeTextNodeData( node.data ) }%c (${ node.data.length })`,\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t\t'color: green; font-weight: bold',\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t\tthis.isComposing ? 'color: red; font-weight: bold' : '',\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t\t'color: blue', ''\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t);\n\t\t\t\t// @if CK_DEBUG_TYPING //\t} else {\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\tconsole.info( '%c[Renderer]%c Insert element:',\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t\t'color: green; font-weight: bold', 'font-weight: normal',\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t\tnode\n\t\t\t\t// @if CK_DEBUG_TYPING //\t\t);\n\t\t\t\t// @if CK_DEBUG_TYPING //\t}\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\tinsertAt( domElement as DomElement, i, expectedDomChildren[ i ] );\n\t\t\t\ti++;\n\t\t\t}\n\t\t\t// Update the existing text node data.\n\t\t\telse if ( action === 'update' ) {\n\t\t\t\tthis._updateTextNode( actualDomChildren[ i ] as DomText, ( expectedDomChildren[ i ] as DomText ).data );\n\t\t\t\ti++;\n\t\t\t} else if ( action === 'equal' ) {\n\t\t\t\t// Force updating text nodes inside elements which did not change and do not need to be re-rendered (#1125).\n\t\t\t\t// Do it here (not in the loop above) because only after insertions the `i` index is correct.\n\t\t\t\tthis._markDescendantTextToSync( this.domConverter.domToView( expectedDomChildren[ i ] ) as any );\n\t\t\t\ti++;\n\t\t\t}\n\t\t}\n\n\t\t// Unbind removed nodes. When node does not have a parent it means that it was removed from DOM tree during\n\t\t// comparison with the expected DOM. We don't need to check child nodes, because if child node was reinserted,\n\t\t// it was moved to DOM tree out of the removed node.\n\t\tfor ( const node of nodesToUnbind ) {\n\t\t\tif ( !node.parentNode ) {\n\t\t\t\tthis.domConverter.unbindDomElement( node as DomElement );\n\t\t\t}\n\t\t}\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t// @if CK_DEBUG_TYPING // }\n\t}\n\n\t/**\n\t * Shorthand for diffing two arrays or node lists of DOM nodes.\n\t *\n\t * @param actualDomChildren Actual DOM children\n\t * @param expectedDomChildren Expected DOM children.\n\t * @returns The list of actions based on the {@link module:utils/diff~diff} function.\n\t */\n\tprivate _diffNodeLists( actualDomChildren: Array<DomNode> | NodeList, expectedDomChildren: Array<DomNode> | NodeList ) {\n\t\tactualDomChildren = filterOutFakeSelectionContainer( actualDomChildren, this._fakeSelectionContainer );\n\n\t\treturn diff( actualDomChildren, expectedDomChildren, sameNodes.bind( null, this.domConverter ) );\n\t}\n\n\t/**\n\t * Finds DOM nodes that were replaced with the similar nodes (same tag name) in the view. All nodes are compared\n\t * within one `insert`/`delete` action group, for example:\n\t *\n\t * ```\n\t * Actual DOM:\t\t<p><b>Foo</b>Bar<i>Baz</i><b>Bax</b></p>\n\t * Expected DOM:\t<p>Bar<b>123</b><i>Baz</i><b>456</b></p>\n\t * Input actions:\t[ insert, insert, delete, delete, equal, insert, delete ]\n\t * Output actions:\t[ insert, replace, delete, equal, replace ]\n\t * ```\n\t *\n\t * @param actions Actions array which is a result of the {@link module:utils/diff~diff} function.\n\t * @param actualDom Actual DOM children\n\t * @param expectedDom Expected DOM children.\n\t * @param comparator A comparator function that should return `true` if the given node should be reused\n\t * (either by the update of a text node data or an element children list for similar elements).\n\t * @returns Actions array modified with the `update` actions.\n\t */\n\tprivate _findUpdateActions(\n\t\tactions: Array<DiffResult>,\n\t\tactualDom: Array<DomNode> | NodeList,\n\t\texpectedDom: Array<DomNode>,\n\t\tcomparator: ( a: DomNode, b: DomNode ) => boolean\n\t): Array<DiffResult | 'update'> {\n\t\t// If there is no both 'insert' and 'delete' actions, no need to check for replaced elements.\n\t\tif ( actions.indexOf( 'insert' ) === -1 || actions.indexOf( 'delete' ) === -1 ) {\n\t\t\treturn actions;\n\t\t}\n\n\t\tlet newActions: Array<DiffResult | 'update'> = [];\n\t\tlet actualSlice = [];\n\t\tlet expectedSlice = [];\n\n\t\tconst counter = { equal: 0, insert: 0, delete: 0 };\n\n\t\tfor ( const action of actions ) {\n\t\t\tif ( action === 'insert' ) {\n\t\t\t\texpectedSlice.push( expectedDom[ counter.equal + counter.insert ] );\n\t\t\t} else if ( action === 'delete' ) {\n\t\t\t\tactualSlice.push( actualDom[ counter.equal + counter.delete ] );\n\t\t\t} else { // equal\n\t\t\t\tnewActions = newActions.concat(\n\t\t\t\t\tdiff( actualSlice, expectedSlice, comparator )\n\t\t\t\t\t\t.map( action => action === 'equal' ? 'update' : action )\n\t\t\t\t);\n\n\t\t\t\tnewActions.push( 'equal' );\n\n\t\t\t\t// Reset stored elements on 'equal'.\n\t\t\t\tactualSlice = [];\n\t\t\t\texpectedSlice = [];\n\t\t\t}\n\t\t\tcounter[ action ]++;\n\t\t}\n\n\t\treturn newActions.concat(\n\t\t\tdiff( actualSlice, expectedSlice, comparator )\n\t\t\t\t.map( action => action === 'equal' ? 'update' : action )\n\t\t);\n\t}\n\n\t/**\n\t * Checks if text needs to be updated and possibly updates it by removing and inserting only parts\n\t * of the data from the existing text node to reduce impact on the IME composition.\n\t *\n\t * @param domText DOM text node to update.\n\t * @param expectedText The expected data of a text node.\n\t */\n\tprivate _updateTextNode( domText: DomText, expectedText: string ): void {\n\t\tconst actualText = domText.data;\n\n\t\tif ( actualText == expectedText ) {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Text node does not need update:%c ' +\n\t\t\t// @if CK_DEBUG_TYPING // \t\t`${ _escapeTextNodeData( actualText ) }%c (${ actualText.length })`,\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic', 'color: blue', ''\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Our approach to interleaving space character with NBSP might differ with the one implemented by the browser.\n\t\t// Avoid modifying the text node in the DOM if only NBSPs and spaces are interchanged.\n\t\t// We should avoid DOM modifications while composing to avoid breakage of composition.\n\t\t// See: https://github.com/ckeditor/ckeditor5/issues/13994.\n\t\tif ( env.isAndroid && this.isComposing && actualText.replace( /\\u00A0/g, ' ' ) == expectedText.replace( /\\u00A0/g, ' ' ) ) {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Text node ignore NBSP changes while composing: ' +\n\t\t\t// @if CK_DEBUG_TYPING // \t\t`%c${ _escapeTextNodeData( actualText ) }%c (${ actualText.length }) ->` +\n\t\t\t// @if CK_DEBUG_TYPING // \t\t` %c${ _escapeTextNodeData( expectedText ) }%c (${ expectedText.length })`,\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-style: italic', 'color: blue', '', 'color: blue', ''\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\treturn;\n\t\t}\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Update text node' +\n\t\t// @if CK_DEBUG_TYPING // \t\t`${ this.isComposing ? ' while composing (may break composition)' : '' }: ` +\n\t\t// @if CK_DEBUG_TYPING // \t\t`%c${ _escapeTextNodeData( actualText ) }%c (${ actualText.length }) ->` +\n\t\t// @if CK_DEBUG_TYPING // \t\t` %c${ _escapeTextNodeData( expectedText ) }%c (${ expectedText.length })`,\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', this.isComposing ? 'color: red; font-weight: bold' : '',\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: blue', '', 'color: blue', ''\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tthis._updateTextNodeInternal( domText, expectedText );\n\t}\n\n\t/**\n\t * Part of the `_updateTextNode` method extracted for easier testing.\n\t */\n\tprivate _updateTextNodeInternal( domText: DomText, expectedText: string ): void {\n\t\tconst actions = fastDiff( domText.data, expectedText );\n\n\t\tfor ( const action of actions ) {\n\t\t\tif ( action.type === 'insert' ) {\n\t\t\t\tdomText.insertData( action.index, action.values.join( '' ) );\n\t\t\t} else { // 'delete'\n\t\t\t\tdomText.deleteData( action.index, action.howMany );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Marks text nodes to be synchronized.\n\t *\n\t * If a text node is passed, it will be marked. If an element is passed, all descendant text nodes inside it will be marked.\n\t *\n\t * @param viewNode View node to sync.\n\t */\n\tprivate _markDescendantTextToSync( viewNode: ViewNode | undefined ): void {\n\t\tif ( !viewNode ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( viewNode.is( '$text' ) ) {\n\t\t\tthis.markedTexts.add( viewNode );\n\t\t} else if ( viewNode.is( 'element' ) ) {\n\t\t\tfor ( const child of viewNode.getChildren() ) {\n\t\t\t\tthis._markDescendantTextToSync( child );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the selection needs to be updated and possibly updates it.\n\t */\n\tprivate _updateSelection(): void {\n\t\t// Block updating DOM selection in (non-Android) Blink while the user is selecting to prevent accidental selection collapsing.\n\t\t// Note: Structural changes in DOM must trigger selection rendering, though. Nodes the selection was anchored\n\t\t// to, may disappear in DOM which would break the selection (e.g. in real-time collaboration scenarios).\n\t\t// https://github.com/ckeditor/ckeditor5/issues/10562, https://github.com/ckeditor/ckeditor5/issues/10723\n\t\tif ( env.isBlink && !env.isAndroid && this.isSelecting && !this.markedChildren.size ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there is no selection - remove DOM and fake selections.\n\t\tif ( this.selection.rangeCount === 0 ) {\n\t\t\tthis._removeDomSelection();\n\t\t\tthis._removeFakeSelection();\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst domRoot = this.domConverter.mapViewToDom( this.selection.editableElement! );\n\n\t\t// Do nothing if there is no focus, or there is no DOM element corresponding to selection's editable element.\n\t\tif ( !this.isFocused || !domRoot ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Render fake selection - create the fake selection container (if needed) and move DOM selection to it.\n\t\tif ( this.selection.isFake ) {\n\t\t\tthis._updateFakeSelection( domRoot );\n\t\t}\n\t\t// There was a fake selection so remove it and update the DOM selection.\n\t\t// This is especially important on Android because otherwise IME will try to compose over the fake selection container.\n\t\telse if ( this._fakeSelectionContainer && this._fakeSelectionContainer.isConnected ) {\n\t\t\tthis._removeFakeSelection();\n\t\t\tthis._updateDomSelection( domRoot );\n\t\t}\n\t\t// Update the DOM selection in case of a plain selection change (no fake selection is involved).\n\t\t// On non-Android the whole rendering is disabled in composition mode (including DOM selection update),\n\t\t// but updating DOM selection should be also disabled on Android if in the middle of the composition\n\t\t// (to not interrupt it).\n\t\telse if ( !( this.isComposing && env.isAndroid ) ) {\n\t\t\tthis._updateDomSelection( domRoot );\n\t\t}\n\t}\n\n\t/**\n\t * Updates the fake selection.\n\t *\n\t * @param domRoot A valid DOM root where the fake selection container should be added.\n\t */\n\tprivate _updateFakeSelection( domRoot: DomElement ): void {\n\t\tconst domDocument = domRoot.ownerDocument;\n\n\t\tif ( !this._fakeSelectionContainer ) {\n\t\t\tthis._fakeSelectionContainer = createFakeSelectionContainer( domDocument );\n\t\t}\n\n\t\tconst container = this._fakeSelectionContainer;\n\n\t\t// Bind fake selection container with the current selection *position*.\n\t\tthis.domConverter.bindFakeSelection( container, this.selection );\n\n\t\tif ( !this._fakeSelectionNeedsUpdate( domRoot ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !container.parentElement || container.parentElement != domRoot ) {\n\t\t\tdomRoot.appendChild( container );\n\t\t}\n\n\t\tcontainer.textContent = this.selection.fakeSelectionLabel || '\\u00A0';\n\n\t\tconst domSelection = domDocument.getSelection()!;\n\t\tconst domRange = domDocument.createRange();\n\n\t\tdomSelection.removeAllRanges();\n\t\tdomRange.selectNodeContents( container );\n\t\tdomSelection.addRange( domRange );\n\t}\n\n\t/**\n\t * Updates the DOM selection.\n\t *\n\t * @param domRoot A valid DOM root where the DOM selection should be rendered.\n\t */\n\tprivate _updateDomSelection( domRoot: DomElement ) {\n\t\tconst domSelection = domRoot.ownerDocument.defaultView!.getSelection()!;\n\n\t\t// Let's check whether DOM selection needs updating at all.\n\t\tif ( !this._domSelectionNeedsUpdate( domSelection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Multi-range selection is not available in most browsers, and, at least in Chrome, trying to\n\t\t// set such selection, that is not continuous, throws an error. Because of that, we will just use anchor\n\t\t// and focus of view selection.\n\t\t// Since we are not supporting multi-range selection, we also do not need to check if proper editable is\n\t\t// selected. If there is any editable selected, it is okay (editable is taken from selection anchor).\n\t\tconst anchor = this.domConverter.viewPositionToDom( this.selection.anchor! )!;\n\t\tconst focus = this.domConverter.viewPositionToDom( this.selection.focus! )!;\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[Renderer]%c Update DOM selection:',\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', '', anchor, focus\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tdomSelection.setBaseAndExtent( anchor.parent, anchor.offset, focus.parent, focus.offset );\n\n\t\t// Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).\n\t\tif ( env.isGecko ) {\n\t\t\tfixGeckoSelectionAfterBr( focus, domSelection );\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether a given DOM selection needs to be updated.\n\t *\n\t * @param domSelection The DOM selection to check.\n\t */\n\tprivate _domSelectionNeedsUpdate( domSelection: Selection ): boolean {\n\t\tif ( !this.domConverter.isDomSelectionCorrect( domSelection ) ) {\n\t\t\t// Current DOM selection is in incorrect position. We need to update it.\n\t\t\treturn true;\n\t\t}\n\n\t\tconst oldViewSelection = domSelection && this.domConverter.domSelectionToView( domSelection );\n\n\t\tif ( oldViewSelection && this.selection.isEqual( oldViewSelection ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If selection is not collapsed, it does not need to be updated if it is similar.\n\t\tif ( !this.selection.isCollapsed && this.selection.isSimilar( oldViewSelection ) ) {\n\t\t\t// Selection did not changed and is correct, do not update.\n\t\t\treturn false;\n\t\t}\n\n\t\t// Selections are not similar.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether the fake selection needs to be updated.\n\t *\n\t * @param domRoot A valid DOM root where a new fake selection container should be added.\n\t */\n\tprivate _fakeSelectionNeedsUpdate( domRoot: DomElement ): boolean {\n\t\tconst container = this._fakeSelectionContainer;\n\t\tconst domSelection = domRoot.ownerDocument.getSelection()!;\n\n\t\t// Fake selection needs to be updated if there's no fake selection container, or the container currently sits\n\t\t// in a different root.\n\t\tif ( !container || container.parentElement !== domRoot ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Make sure that the selection actually is within the fake selection.\n\t\tif ( domSelection.anchorNode !== container && !container.contains( domSelection.anchorNode ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn container.textContent !== this.selection.fakeSelectionLabel;\n\t}\n\n\t/**\n\t * Removes the DOM selection.\n\t */\n\tprivate _removeDomSelection(): void {\n\t\tfor ( const doc of this.domDocuments ) {\n\t\t\tconst domSelection = doc.getSelection()!;\n\n\t\t\tif ( domSelection.rangeCount ) {\n\t\t\t\tconst activeDomElement = doc.activeElement!;\n\t\t\t\tconst viewElement = this.domConverter.mapDomToView( activeDomElement as DomElement );\n\n\t\t\t\tif ( activeDomElement && viewElement ) {\n\t\t\t\t\tdomSelection.removeAllRanges();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes the fake selection.\n\t */\n\tprivate _removeFakeSelection(): void {\n\t\tconst container = this._fakeSelectionContainer;\n\n\t\tif ( container ) {\n\t\t\tcontainer.remove();\n\t\t}\n\t}\n\n\t/**\n\t * Checks if focus needs to be updated and possibly updates it.\n\t */\n\tprivate _updateFocus(): void {\n\t\tif ( this.isFocused ) {\n\t\t\tconst editable = this.selection.editableElement;\n\n\t\t\tif ( editable ) {\n\t\t\t\tthis.domConverter.focus( editable );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Checks if provided element is editable.\n */\nfunction isEditable( element: ViewElement ): boolean {\n\tif ( element.getAttribute( 'contenteditable' ) == 'false' ) {\n\t\treturn false;\n\t}\n\n\tconst parent = element.findAncestor( element => element.hasAttribute( 'contenteditable' ) );\n\n\treturn !parent || parent.getAttribute( 'contenteditable' ) == 'true';\n}\n\n/**\n * Adds inline filler at a given position.\n *\n * The position can be given as an array of DOM nodes and an offset in that array,\n * or a DOM parent element and an offset in that element.\n *\n * @returns The DOM text node that contains an inline filler.\n */\nfunction addInlineFiller( domDocument: DomDocument, domParentOrArray: DomNode | Array<DomNode>, offset: number ): DomText {\n\tconst childNodes = domParentOrArray instanceof Array ? domParentOrArray : domParentOrArray.childNodes;\n\tconst nodeAfterFiller = childNodes[ offset ];\n\n\tif ( isText( nodeAfterFiller ) ) {\n\t\tnodeAfterFiller.data = INLINE_FILLER + nodeAfterFiller.data;\n\n\t\treturn nodeAfterFiller;\n\t} else {\n\t\tconst fillerNode = domDocument.createTextNode( INLINE_FILLER );\n\n\t\tif ( Array.isArray( domParentOrArray ) ) {\n\t\t\t( childNodes as Array<DomNode> ).splice( offset, 0, fillerNode );\n\t\t} else {\n\t\t\tinsertAt( domParentOrArray as DomElement, offset, fillerNode );\n\t\t}\n\n\t\treturn fillerNode;\n\t}\n}\n\n/**\n * Whether two DOM nodes should be considered as similar.\n * Nodes are considered similar if they have the same tag name.\n */\nfunction areSimilarElements( node1: DomNode, node2: DomNode ): boolean {\n\treturn isNode( node1 ) && isNode( node2 ) &&\n\t\t!isText( node1 ) && !isText( node2 ) &&\n\t\t!isComment( node1 ) && !isComment( node2 ) &&\n\t\t( node1 as DomElement ).tagName.toLowerCase() === ( node2 as DomElement ).tagName.toLowerCase();\n}\n\n/**\n * Whether two DOM nodes are text nodes.\n */\nfunction areTextNodes( node1: DomNode, node2: DomNode ): boolean {\n\treturn isNode( node1 ) && isNode( node2 ) &&\n\t\tisText( node1 ) && isText( node2 );\n}\n\n/**\n * Whether two dom nodes should be considered as the same.\n * Two nodes which are considered the same are:\n *\n * * Text nodes with the same text.\n * * Element nodes represented by the same object.\n * * Two block filler elements.\n *\n * @param blockFillerMode Block filler mode, see {@link module:engine/view/domconverter~DomConverter#blockFillerMode}.\n */\nfunction sameNodes( domConverter: DomConverter, actualDomChild: DomNode, expectedDomChild: DomNode ): boolean {\n\t// Elements.\n\tif ( actualDomChild === expectedDomChild ) {\n\t\treturn true;\n\t}\n\t// Texts.\n\telse if ( isText( actualDomChild ) && isText( expectedDomChild ) ) {\n\t\treturn actualDomChild.data === expectedDomChild.data;\n\t}\n\t// Block fillers.\n\telse if ( domConverter.isBlockFiller( actualDomChild ) &&\n\t\tdomConverter.isBlockFiller( expectedDomChild ) ) {\n\t\treturn true;\n\t}\n\n\t// Not matching types.\n\treturn false;\n}\n\n/**\n * The following is a Firefox–specific hack (https://github.com/ckeditor/ckeditor5-engine/issues/1439).\n * When the native DOM selection is at the end of the block and preceded by <br /> e.g.\n *\n * ```html\n * <p>foo<br/>[]</p>\n * ```\n *\n * which happens a lot when using the soft line break, the browser fails to (visually) move the\n * caret to the new line. A quick fix is as simple as force–refreshing the selection with the same range.\n */\nfunction fixGeckoSelectionAfterBr( focus: ReturnType<DomConverter[ 'viewPositionToDom' ]>, domSelection: DomSelection ) {\n\tlet parent = focus!.parent;\n\tlet offset = focus!.offset;\n\n\tif ( isText( parent ) && isInlineFiller( parent ) ) {\n\t\toffset = indexOf( parent ) + 1;\n\t\tparent = parent.parentNode!;\n\t}\n\n\t// This fix works only when the focus point is at the very end of an element.\n\t// There is no point in running it in cases unrelated to the browser bug.\n\tif ( parent.nodeType != Node.ELEMENT_NODE || offset != parent.childNodes.length - 1 ) {\n\t\treturn;\n\t}\n\n\tconst childAtOffset = parent.childNodes[ offset ];\n\n\t// To stay on the safe side, the fix being as specific as possible, it targets only the\n\t// selection which is at the very end of the element and preceded by <br />.\n\tif ( childAtOffset && ( childAtOffset as DomElement ).tagName == 'BR' ) {\n\t\tdomSelection.addRange( domSelection.getRangeAt( 0 ) );\n\t}\n}\n\nfunction filterOutFakeSelectionContainer( domChildList: Array<DomNode> | NodeList, fakeSelectionContainer: DomElement | null ) {\n\tconst childList = Array.from( domChildList );\n\n\tif ( childList.length == 0 || !fakeSelectionContainer ) {\n\t\treturn childList;\n\t}\n\n\tconst last = childList[ childList.length - 1 ];\n\n\tif ( last == fakeSelectionContainer ) {\n\t\tchildList.pop();\n\t}\n\n\treturn childList;\n}\n\n/**\n * Creates a fake selection container for a given document.\n */\nfunction createFakeSelectionContainer( domDocument: DomDocument ): DomElement {\n\tconst container = domDocument.createElement( 'div' );\n\n\tcontainer.className = 'ck-fake-selection-container';\n\n\tObject.assign( container.style, {\n\t\tposition: 'fixed',\n\t\ttop: 0,\n\t\tleft: '-9999px',\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/752.\n\t\twidth: '42px'\n\t} );\n\n\t// Fill it with a text node so we can update it later.\n\tcontainer.textContent = '\\u00A0';\n\n\treturn container;\n}\n\n// @if CK_DEBUG_TYPING // function _escapeTextNodeData( text ) {\n// @if CK_DEBUG_TYPING // \tconst escapedText = text\n// @if CK_DEBUG_TYPING // \t\t.replace( /&/g, '&amp;' )\n// @if CK_DEBUG_TYPING // \t\t.replace( /\\u00A0/g, '&nbsp;' )\n// @if CK_DEBUG_TYPING // \t\t.replace( /\\u2060/g, '&NoBreak;' );\n// @if CK_DEBUG_TYPING //\n// @if CK_DEBUG_TYPING // \treturn `\"${ escapedText }\"`;\n// @if CK_DEBUG_TYPING // }\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/domconverter\n */\n\n/* globals Node, NodeFilter, DOMParser */\n\nimport ViewText from './text.js';\nimport ViewElement from './element.js';\nimport ViewUIElement from './uielement.js';\nimport ViewPosition from './position.js';\nimport ViewRange from './range.js';\nimport ViewSelection from './selection.js';\nimport ViewDocumentFragment from './documentfragment.js';\nimport ViewTreeWalker from './treewalker.js';\nimport { default as Matcher, type MatcherPattern } from './matcher.js';\nimport {\n\tBR_FILLER, INLINE_FILLER_LENGTH, NBSP_FILLER, MARKED_NBSP_FILLER,\n\tgetDataWithoutFiller, isInlineFiller, startsWithFiller\n} from './filler.js';\n\nimport {\n\tglobal,\n\tlogWarning,\n\tindexOf,\n\tgetAncestors,\n\tisText,\n\tisComment,\n\tisValidAttributeName,\n\tfirst,\n\tenv\n} from '@ckeditor/ckeditor5-utils';\n\nimport type ViewNode from './node.js';\nimport type Document from './document.js';\nimport type DocumentSelection from './documentselection.js';\nimport type EditableElement from './editableelement.js';\nimport type ViewTextProxy from './textproxy.js';\nimport type ViewRawElement from './rawelement.js';\n\ntype DomNode = globalThis.Node;\ntype DomElement = globalThis.HTMLElement;\ntype DomDocument = globalThis.Document;\ntype DomDocumentFragment = globalThis.DocumentFragment;\ntype DomComment = globalThis.Comment;\ntype DomRange = globalThis.Range;\ntype DomText = globalThis.Text;\ntype DomSelection = globalThis.Selection;\n\nconst BR_FILLER_REF = BR_FILLER( global.document ); // eslint-disable-line new-cap\nconst NBSP_FILLER_REF = NBSP_FILLER( global.document ); // eslint-disable-line new-cap\nconst MARKED_NBSP_FILLER_REF = MARKED_NBSP_FILLER( global.document ); // eslint-disable-line new-cap\nconst UNSAFE_ATTRIBUTE_NAME_PREFIX = 'data-ck-unsafe-attribute-';\nconst UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE = 'data-ck-unsafe-element';\n\n/**\n * `DomConverter` is a set of tools to do transformations between DOM nodes and view nodes. It also handles\n * {@link module:engine/view/domconverter~DomConverter#bindElements bindings} between these nodes.\n *\n * An instance of the DOM converter is available under\n * {@link module:engine/view/view~View#domConverter `editor.editing.view.domConverter`}.\n *\n * The DOM converter does not check which nodes should be rendered (use {@link module:engine/view/renderer~Renderer}), does not keep the\n * state of a tree nor keeps the synchronization between the tree view and the DOM tree (use {@link module:engine/view/document~Document}).\n *\n * The DOM converter keeps DOM elements to view element bindings, so when the converter gets destroyed, the bindings are lost.\n * Two converters will keep separate binding maps, so one tree view can be bound with two DOM trees.\n */\nexport default class DomConverter {\n\tpublic readonly document: Document;\n\n\t/**\n\t * Whether to leave the View-to-DOM conversion result unchanged or improve editing experience by filtering out interactive data.\n\t */\n\tpublic readonly renderingMode: 'data' | 'editing';\n\n\t/**\n\t * The mode of a block filler used by the DOM converter.\n\t */\n\tpublic blockFillerMode: BlockFillerMode;\n\n\t/**\n\t * Elements which are considered pre-formatted elements.\n\t */\n\tpublic readonly preElements: Array<string>;\n\n\t/**\n\t * Elements which are considered block elements (and hence should be filled with a\n\t * {@link #isBlockFiller block filler}).\n\t *\n\t * Whether an element is considered a block element also affects handling of trailing whitespaces.\n\t *\n\t * You can extend this array if you introduce support for block elements which are not yet recognized here.\n\t */\n\tpublic readonly blockElements: Array<string>;\n\n\t/**\n\t * A list of elements that exist inline (in text) but their inner structure cannot be edited because\n\t * of the way they are rendered by the browser. They are mostly HTML form elements but there are other\n\t * elements such as `<img>` or `<iframe>` that also have non-editable children or no children whatsoever.\n\t *\n\t * Whether an element is considered an inline object has an impact on white space rendering (trimming)\n\t * around (and inside of it). In short, white spaces in text nodes next to inline objects are not trimmed.\n\t *\n\t * You can extend this array if you introduce support for inline object elements which are not yet recognized here.\n\t */\n\tpublic readonly inlineObjectElements: Array<string>;\n\n\t/**\n\t * A list of elements which may affect the editing experience. To avoid this, those elements are replaced with\n\t * `<span data-ck-unsafe-element=\"[element name]\"></span>` while rendering in the editing mode.\n\t */\n\tpublic readonly unsafeElements: Array<string>;\n\n\t/**\n\t * The DOM Document used to create DOM nodes.\n\t */\n\tprivate readonly _domDocument: DomDocument;\n\n\t/**\n\t * The DOM-to-view mapping.\n\t */\n\tprivate readonly _domToViewMapping = new WeakMap<DomElement | DomDocumentFragment, ViewElement | ViewDocumentFragment>();\n\n\t/**\n\t * The view-to-DOM mapping.\n\t */\n\tprivate readonly _viewToDomMapping = new WeakMap<ViewElement | ViewDocumentFragment, DomElement | DomDocumentFragment>();\n\n\t/**\n\t * Holds the mapping between fake selection containers and corresponding view selections.\n\t */\n\tprivate readonly _fakeSelectionMapping = new WeakMap<DomElement, ViewSelection>();\n\n\t/**\n\t * Matcher for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from DOM nodes to view elements.\n\t */\n\tprivate readonly _rawContentElementMatcher = new Matcher();\n\n\t/**\n\t * Matcher for inline object view elements. This is an extension of a simple {@link #inlineObjectElements} array of element names.\n\t */\n\tprivate readonly _inlineObjectElementMatcher = new Matcher();\n\n\t/**\n\t * Set of elements with temporary custom properties that require clearing after render.\n\t */\n\tprivate readonly _elementsWithTemporaryCustomProperties = new Set<ViewElement | ViewDocumentFragment>();\n\n\t/**\n\t * Creates a DOM converter.\n\t *\n\t * @param document The view document instance.\n\t * @param options An object with configuration options.\n\t * @param options.blockFillerMode The type of the block filler to use.\n\t * Default value depends on the options.renderingMode:\n\t *  'nbsp' when options.renderingMode == 'data',\n\t *  'br' when options.renderingMode == 'editing'.\n\t * @param options.renderingMode Whether to leave the View-to-DOM conversion result unchanged\n\t * or improve editing experience by filtering out interactive data.\n\t */\n\tconstructor(\n\t\tdocument: Document,\n\t\t{ blockFillerMode, renderingMode = 'editing' }: {\n\t\t\tblockFillerMode?: BlockFillerMode;\n\t\t\trenderingMode?: 'data' | 'editing';\n\t\t} = {}\n\t) {\n\t\tthis.document = document;\n\t\tthis.renderingMode = renderingMode;\n\t\tthis.blockFillerMode = blockFillerMode || ( renderingMode === 'editing' ? 'br' : 'nbsp' );\n\t\tthis.preElements = [ 'pre', 'textarea' ];\n\t\tthis.blockElements = [\n\t\t\t'address', 'article', 'aside', 'blockquote', 'caption', 'center', 'dd', 'details', 'dir', 'div',\n\t\t\t'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header',\n\t\t\t'hgroup', 'legend', 'li', 'main', 'menu', 'nav', 'ol', 'p', 'pre', 'section', 'summary', 'table', 'tbody',\n\t\t\t'td', 'tfoot', 'th', 'thead', 'tr', 'ul'\n\t\t];\n\t\tthis.inlineObjectElements = [\n\t\t\t'object', 'iframe', 'input', 'button', 'textarea', 'select', 'option', 'video', 'embed', 'audio', 'img', 'canvas'\n\t\t];\n\t\tthis.unsafeElements = [ 'script', 'style' ];\n\n\t\tthis._domDocument = this.renderingMode === 'editing' ? global.document : global.document.implementation.createHTMLDocument( '' );\n\t}\n\n\t/**\n\t * Binds a given DOM element that represents fake selection to a **position** of a\n\t * {@link module:engine/view/documentselection~DocumentSelection document selection}.\n\t * Document selection copy is stored and can be retrieved by the\n\t * {@link module:engine/view/domconverter~DomConverter#fakeSelectionToView} method.\n\t */\n\tpublic bindFakeSelection( domElement: DomElement, viewDocumentSelection: DocumentSelection ): void {\n\t\tthis._fakeSelectionMapping.set( domElement, new ViewSelection( viewDocumentSelection ) );\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/view/selection~Selection view selection} instance corresponding to a given\n\t * DOM element that represents fake selection. Returns `undefined` if binding to the given DOM element does not exist.\n\t */\n\tpublic fakeSelectionToView( domElement: DomElement ): ViewSelection | undefined {\n\t\treturn this._fakeSelectionMapping.get( domElement );\n\t}\n\n\t/**\n\t * Binds DOM and view elements, so it will be possible to get corresponding elements using\n\t * {@link module:engine/view/domconverter~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param domElement The DOM element to bind.\n\t * @param viewElement The view element to bind.\n\t */\n\tpublic bindElements( domElement: DomElement, viewElement: ViewElement ): void {\n\t\tthis._domToViewMapping.set( domElement, viewElement );\n\t\tthis._viewToDomMapping.set( viewElement, domElement );\n\t}\n\n\t/**\n\t * Unbinds a given DOM element from the view element it was bound to. Unbinding is deep, meaning that all children of\n\t * the DOM element will be unbound too.\n\t *\n\t * @param domElement The DOM element to unbind.\n\t */\n\tpublic unbindDomElement( domElement: DomElement ): void {\n\t\tconst viewElement = this._domToViewMapping.get( domElement );\n\n\t\tif ( viewElement ) {\n\t\t\tthis._domToViewMapping.delete( domElement );\n\t\t\tthis._viewToDomMapping.delete( viewElement );\n\n\t\t\tfor ( const child of domElement.children ) {\n\t\t\t\tthis.unbindDomElement( child as DomElement );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Binds DOM and view document fragments, so it will be possible to get corresponding document fragments using\n\t * {@link module:engine/view/domconverter~DomConverter#mapDomToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#mapViewToDom}.\n\t *\n\t * @param domFragment The DOM document fragment to bind.\n\t * @param viewFragment The view document fragment to bind.\n\t */\n\tpublic bindDocumentFragments( domFragment: DomDocumentFragment, viewFragment: ViewDocumentFragment ): void {\n\t\tthis._domToViewMapping.set( domFragment, viewFragment );\n\t\tthis._viewToDomMapping.set( viewFragment, domFragment );\n\t}\n\n\t/**\n\t * Decides whether a given pair of attribute key and value should be passed further down the pipeline.\n\t *\n\t * @param elementName Element name in lower case.\n\t */\n\tpublic shouldRenderAttribute( attributeKey: string, attributeValue: string, elementName: string ): boolean {\n\t\tif ( this.renderingMode === 'data' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tattributeKey = attributeKey.toLowerCase();\n\n\t\tif ( attributeKey.startsWith( 'on' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (\n\t\t\tattributeKey === 'srcdoc' &&\n\t\t\tattributeValue.match( /\\bon\\S+\\s*=|javascript:|<\\s*\\/*script/i )\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (\n\t\t\telementName === 'img' &&\n\t\t\t( attributeKey === 'src' || attributeKey === 'srcset' )\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( elementName === 'source' && attributeKey === 'srcset' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( attributeValue.match( /^\\s*(javascript:|data:(image\\/svg|text\\/x?html))/i ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set `domElement`'s content using provided `html` argument. Apply necessary filtering for the editing pipeline.\n\t *\n\t * @param domElement DOM element that should have `html` set as its content.\n\t * @param html Textual representation of the HTML that will be set on `domElement`.\n\t */\n\tpublic setContentOf( domElement: DomElement, html: string ): void {\n\t\t// For data pipeline we pass the HTML as-is.\n\t\tif ( this.renderingMode === 'data' ) {\n\t\t\tdomElement.innerHTML = html;\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst document = new DOMParser().parseFromString( html, 'text/html' );\n\t\tconst fragment = document.createDocumentFragment();\n\t\tconst bodyChildNodes = document.body.childNodes;\n\n\t\twhile ( bodyChildNodes.length > 0 ) {\n\t\t\tfragment.appendChild( bodyChildNodes[ 0 ] );\n\t\t}\n\n\t\tconst treeWalker = document.createTreeWalker( fragment, NodeFilter.SHOW_ELEMENT );\n\t\tconst nodes: Array<DomElement> = [];\n\n\t\tlet currentNode;\n\n\t\t// eslint-disable-next-line no-cond-assign\n\t\twhile ( currentNode = treeWalker.nextNode() ) {\n\t\t\tnodes.push( currentNode as DomElement );\n\t\t}\n\n\t\tfor ( const currentNode of nodes ) {\n\t\t\t// Go through nodes to remove those that are prohibited in editing pipeline.\n\t\t\tfor ( const attributeName of currentNode.getAttributeNames() ) {\n\t\t\t\tthis.setDomElementAttribute( currentNode, attributeName, currentNode.getAttribute( attributeName )! );\n\t\t\t}\n\n\t\t\tconst elementName = currentNode.tagName.toLowerCase();\n\n\t\t\t// There are certain nodes, that should be renamed to <span> in editing pipeline.\n\t\t\tif ( this._shouldRenameElement( elementName ) ) {\n\t\t\t\t_logUnsafeElement( elementName );\n\n\t\t\t\tcurrentNode.replaceWith( this._createReplacementDomElement( elementName, currentNode ) );\n\t\t\t}\n\t\t}\n\n\t\t// Empty the target element.\n\t\twhile ( domElement.firstChild ) {\n\t\t\tdomElement.firstChild.remove();\n\t\t}\n\n\t\tdomElement.append( fragment );\n\t}\n\n\tpublic viewToDom(\n\t\tviewNode: ViewText,\n\t\toptions?: { bind?: boolean; withChildren?: boolean }\n\t): DomText;\n\n\tpublic viewToDom(\n\t\tviewNode: ViewElement,\n\t\toptions?: { bind?: boolean; withChildren?: boolean }\n\t): DomElement;\n\n\tpublic viewToDom(\n\t\tviewNode: ViewNode,\n\t\toptions?: { bind?: boolean; withChildren?: boolean }\n\t): DomNode;\n\n\tpublic viewToDom(\n\t\tviewNode: ViewDocumentFragment,\n\t\toptions?: { bind?: boolean; withChildren?: boolean }\n\t): DomDocumentFragment;\n\n\t/**\n\t * Converts the view to the DOM. For all text nodes, not bound elements and document fragments new items will\n\t * be created. For bound elements and document fragments the method will return corresponding items.\n\t *\n\t * @param viewNode View node or document fragment to transform.\n\t * @param options Conversion options.\n\t * @param options.bind Determines whether new elements will be bound.\n\t * @param options.withChildren If `false`, node's and document fragment's children will not be converted.\n\t * @returns Converted node or DocumentFragment.\n\t */\n\tpublic viewToDom(\n\t\tviewNode: ViewNode | ViewDocumentFragment,\n\t\toptions: { bind?: boolean; withChildren?: boolean } = {}\n\t): DomNode | DomDocumentFragment {\n\t\tif ( viewNode.is( '$text' ) ) {\n\t\t\tconst textData = this._processDataFromViewText( viewNode );\n\n\t\t\treturn this._domDocument.createTextNode( textData );\n\t\t} else {\n\t\t\tconst viewElementOrFragment = viewNode as ViewElement | ViewDocumentFragment;\n\n\t\t\tif ( this.mapViewToDom( viewElementOrFragment ) ) {\n\t\t\t\t// Do not reuse element that is marked to not reuse (for example an IMG element\n\t\t\t\t// so it can immediately display a placeholder background instead of waiting for the new src to load).\n\t\t\t\tif ( viewElementOrFragment.getCustomProperty( 'editingPipeline:doNotReuseOnce' ) ) {\n\t\t\t\t\tthis._elementsWithTemporaryCustomProperties.add( viewElementOrFragment );\n\t\t\t\t} else {\n\t\t\t\t\treturn this.mapViewToDom( viewElementOrFragment )!;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet domElement: DomElement | DomDocumentFragment | DomComment;\n\n\t\t\tif ( viewElementOrFragment.is( 'documentFragment' ) ) {\n\t\t\t\t// Create DOM document fragment.\n\t\t\t\tdomElement = this._domDocument.createDocumentFragment();\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindDocumentFragments( domElement, viewElementOrFragment );\n\t\t\t\t}\n\t\t\t} else if ( viewElementOrFragment.is( 'uiElement' ) ) {\n\t\t\t\tif ( viewElementOrFragment.name === '$comment' ) {\n\t\t\t\t\tdomElement = this._domDocument.createComment( viewElementOrFragment.getCustomProperty( '$rawContent' ) as string );\n\t\t\t\t} else {\n\t\t\t\t\t// UIElement has its own render() method (see #799).\n\t\t\t\t\tdomElement = viewElementOrFragment.render( this._domDocument, this );\n\t\t\t\t}\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domElement as DomElement, viewElementOrFragment );\n\t\t\t\t}\n\n\t\t\t\treturn domElement;\n\t\t\t} else {\n\t\t\t\t// Create DOM element.\n\t\t\t\tif ( this._shouldRenameElement( viewElementOrFragment.name ) ) {\n\t\t\t\t\t_logUnsafeElement( viewElementOrFragment.name );\n\n\t\t\t\t\tdomElement = this._createReplacementDomElement( viewElementOrFragment.name );\n\t\t\t\t} else if ( viewElementOrFragment.hasAttribute( 'xmlns' ) ) {\n\t\t\t\t\tdomElement = this._domDocument.createElementNS(\n\t\t\t\t\t\tviewElementOrFragment.getAttribute( 'xmlns' )!,\n\t\t\t\t\t\tviewElementOrFragment.name\n\t\t\t\t\t) as HTMLElement;\n\t\t\t\t} else {\n\t\t\t\t\tdomElement = this._domDocument.createElement( viewElementOrFragment.name );\n\t\t\t\t}\n\n\t\t\t\t// RawElement take care of their children in RawElement#render() method which can be customized\n\t\t\t\t// (see https://github.com/ckeditor/ckeditor5/issues/4469).\n\t\t\t\tif ( viewElementOrFragment.is( 'rawElement' ) ) {\n\t\t\t\t\tviewElementOrFragment.render( domElement, this );\n\t\t\t\t}\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domElement, viewElementOrFragment );\n\t\t\t\t}\n\n\t\t\t\t// Copy element's attributes.\n\t\t\t\tfor ( const key of viewElementOrFragment.getAttributeKeys() ) {\n\t\t\t\t\tthis.setDomElementAttribute(\n\t\t\t\t\t\tdomElement,\n\t\t\t\t\t\tkey,\n\t\t\t\t\t\tviewElementOrFragment.getAttribute( key )!,\n\t\t\t\t\t\tviewElementOrFragment\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( options.withChildren !== false ) {\n\t\t\t\tfor ( const child of this.viewChildrenToDom( viewElementOrFragment, options ) ) {\n\t\t\t\t\tif ( domElement instanceof HTMLTemplateElement ) {\n\t\t\t\t\t\tdomElement.content.appendChild( child );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdomElement.appendChild( child );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn domElement;\n\t\t}\n\t}\n\n\t/**\n\t * Sets the attribute on a DOM element.\n\t *\n\t * **Note**: To remove the attribute, use {@link #removeDomElementAttribute}.\n\t *\n\t * @param domElement The DOM element the attribute should be set on.\n\t * @param key The name of the attribute.\n\t * @param value The value of the attribute.\n\t * @param relatedViewElement The view element related to the `domElement` (if there is any).\n\t * It helps decide whether the attribute set is unsafe. For instance, view elements created via the\n\t * {@link module:engine/view/downcastwriter~DowncastWriter} methods can allow certain attributes that would normally be filtered out.\n\t */\n\tpublic setDomElementAttribute( domElement: DomElement, key: string, value: string, relatedViewElement?: ViewElement ): void {\n\t\tconst shouldRenderAttribute = this.shouldRenderAttribute( key, value, domElement.tagName.toLowerCase() ) ||\n\t\t\trelatedViewElement && relatedViewElement.shouldRenderUnsafeAttribute( key );\n\n\t\tif ( !shouldRenderAttribute ) {\n\t\t\tlogWarning( 'domconverter-unsafe-attribute-detected', { domElement, key, value } );\n\t\t}\n\n\t\tif ( !isValidAttributeName( key ) ) {\n\t\t\t/**\n\t\t\t * Invalid attribute name was ignored during rendering.\n\t\t\t *\n\t\t\t * @error domconverter-invalid-attribute-detected\n\t\t\t */\n\t\t\tlogWarning( 'domconverter-invalid-attribute-detected', { domElement, key, value } );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// The old value was safe but the new value is unsafe.\n\t\tif ( domElement.hasAttribute( key ) && !shouldRenderAttribute ) {\n\t\t\tdomElement.removeAttribute( key );\n\t\t}\n\t\t// The old value was unsafe (but prefixed) but the new value will be safe (will be unprefixed).\n\t\telse if ( domElement.hasAttribute( UNSAFE_ATTRIBUTE_NAME_PREFIX + key ) && shouldRenderAttribute ) {\n\t\t\tdomElement.removeAttribute( UNSAFE_ATTRIBUTE_NAME_PREFIX + key );\n\t\t}\n\n\t\t// If the attribute should not be rendered, rename it (instead of removing) to give developers some idea of what\n\t\t// is going on (https://github.com/ckeditor/ckeditor5/issues/10801).\n\t\tdomElement.setAttribute( shouldRenderAttribute ? key : UNSAFE_ATTRIBUTE_NAME_PREFIX + key, value );\n\t}\n\n\t/**\n\t * Removes an attribute from a DOM element.\n\t *\n\t * **Note**: To set the attribute, use {@link #setDomElementAttribute}.\n\t *\n\t * @param domElement The DOM element the attribute should be removed from.\n\t * @param key The name of the attribute.\n\t */\n\tpublic removeDomElementAttribute( domElement: DomElement, key: string ): void {\n\t\t// See #_createReplacementDomElement() to learn what this is.\n\t\tif ( key == UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdomElement.removeAttribute( key );\n\n\t\t// See setDomElementAttribute() to learn what this is.\n\t\tdomElement.removeAttribute( UNSAFE_ATTRIBUTE_NAME_PREFIX + key );\n\t}\n\n\t/**\n\t * Converts children of the view element to DOM using the\n\t * {@link module:engine/view/domconverter~DomConverter#viewToDom} method.\n\t * Additionally, this method adds block {@link module:engine/view/filler filler} to the list of children, if needed.\n\t *\n\t * @param viewElement Parent view element.\n\t * @param options See {@link module:engine/view/domconverter~DomConverter#viewToDom} options parameter.\n\t * @returns DOM nodes.\n\t */\n\tpublic* viewChildrenToDom(\n\t\tviewElement: ViewElement | ViewDocumentFragment,\n\t\toptions: { bind?: boolean; withChildren?: boolean } = {}\n\t): IterableIterator<Node> {\n\t\tconst fillerPositionOffset = viewElement.getFillerOffset && viewElement.getFillerOffset();\n\t\tlet offset = 0;\n\n\t\tfor ( const childView of viewElement.getChildren() ) {\n\t\t\tif ( fillerPositionOffset === offset ) {\n\t\t\t\tyield this._getBlockFiller();\n\t\t\t}\n\n\t\t\tconst transparentRendering = childView.is( 'element' ) &&\n\t\t\t\t!!childView.getCustomProperty( 'dataPipeline:transparentRendering' ) &&\n\t\t\t\t!first( childView.getAttributes() );\n\n\t\t\tif ( transparentRendering && this.renderingMode == 'data' ) {\n\t\t\t\t// `RawElement` doesn't have #children defined, so they need to be temporarily rendered\n\t\t\t\t// and extracted directly.\n\t\t\t\tif ( childView.is( 'rawElement' ) ) {\n\t\t\t\t\tconst tempElement = this._domDocument.createElement( childView.name );\n\n\t\t\t\t\tchildView.render( tempElement, this );\n\n\t\t\t\t\tyield* [ ...tempElement.childNodes ];\n\t\t\t\t} else {\n\t\t\t\t\tyield* this.viewChildrenToDom( childView, options );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( transparentRendering ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The `dataPipeline:transparentRendering` flag is supported only in the data pipeline.\n\t\t\t\t\t *\n\t\t\t\t\t * @error domconverter-transparent-rendering-unsupported-in-editing-pipeline\n\t\t\t\t\t */\n\t\t\t\t\tlogWarning( 'domconverter-transparent-rendering-unsupported-in-editing-pipeline', { viewElement: childView } );\n\t\t\t\t}\n\n\t\t\t\tyield this.viewToDom( childView, options );\n\t\t\t}\n\n\t\t\toffset++;\n\t\t}\n\n\t\tif ( fillerPositionOffset === offset ) {\n\t\t\tyield this._getBlockFiller();\n\t\t}\n\t}\n\n\t/**\n\t * Converts view {@link module:engine/view/range~Range} to DOM range.\n\t * Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t *\n\t * @param viewRange View range.\n\t * @returns DOM range.\n\t */\n\tpublic viewRangeToDom( viewRange: ViewRange ): DomRange {\n\t\tconst domStart = this.viewPositionToDom( viewRange.start )!;\n\t\tconst domEnd = this.viewPositionToDom( viewRange.end )!;\n\n\t\tconst domRange = this._domDocument.createRange();\n\t\tdomRange.setStart( domStart.parent, domStart.offset );\n\t\tdomRange.setEnd( domEnd.parent, domEnd.offset );\n\n\t\treturn domRange;\n\t}\n\n\t/**\n\t * Converts view {@link module:engine/view/position~Position} to DOM parent and offset.\n\t *\n\t * Inline and block {@link module:engine/view/filler fillers} are handled during the conversion.\n\t * If the converted position is directly before inline filler it is moved inside the filler.\n\t *\n\t * @param viewPosition View position.\n\t * @returns DOM position or `null` if view position could not be converted to DOM.\n\t * DOM position has two properties:\n\t * * `parent` - DOM position parent.\n\t * * `offset` - DOM position offset.\n\t */\n\tpublic viewPositionToDom( viewPosition: ViewPosition ): { parent: DomNode; offset: number } | null {\n\t\tconst viewParent = viewPosition.parent;\n\n\t\tif ( viewParent.is( '$text' ) ) {\n\t\t\tconst domParent = this.findCorrespondingDomText( viewParent );\n\n\t\t\tif ( !domParent ) {\n\t\t\t\t// Position is in a view text node that has not been rendered to DOM yet.\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tlet offset = viewPosition.offset;\n\n\t\t\tif ( startsWithFiller( domParent ) ) {\n\t\t\t\toffset += INLINE_FILLER_LENGTH;\n\t\t\t}\n\n\t\t\treturn { parent: domParent, offset };\n\t\t} else {\n\t\t\t// viewParent is instance of ViewElement.\n\t\t\tlet domParent, domBefore, domAfter;\n\n\t\t\tif ( viewPosition.offset === 0 ) {\n\t\t\t\tdomParent = this.mapViewToDom( viewParent as ViewElement );\n\n\t\t\t\tif ( !domParent ) {\n\t\t\t\t\t// Position is in a view element that has not been rendered to DOM yet.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tdomAfter = domParent.childNodes[ 0 ];\n\t\t\t} else {\n\t\t\t\tconst nodeBefore = viewPosition.nodeBefore!;\n\n\t\t\t\tdomBefore = nodeBefore.is( '$text' ) ?\n\t\t\t\t\tthis.findCorrespondingDomText( nodeBefore ) :\n\t\t\t\t\tthis.mapViewToDom( nodeBefore as ViewElement );\n\n\t\t\t\tif ( !domBefore ) {\n\t\t\t\t\t// Position is after a view element that has not been rendered to DOM yet.\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tdomParent = domBefore.parentNode;\n\t\t\t\tdomAfter = domBefore.nextSibling;\n\t\t\t}\n\n\t\t\t// If there is an inline filler at position return position inside the filler. We should never return\n\t\t\t// the position before the inline filler.\n\t\t\tif ( isText( domAfter ) && startsWithFiller( domAfter ) ) {\n\t\t\t\treturn { parent: domAfter, offset: INLINE_FILLER_LENGTH };\n\t\t\t}\n\n\t\t\tconst offset = domBefore ? indexOf( domBefore ) + 1 : 0;\n\n\t\t\treturn { parent: domParent!, offset };\n\t\t}\n\t}\n\n\t/**\n\t * Converts DOM to view. For all text nodes, not bound elements and document fragments new items will\n\t * be created. For bound elements and document fragments function will return corresponding items. For\n\t * {@link module:engine/view/filler fillers} `null` will be returned.\n\t * For all DOM elements rendered by {@link module:engine/view/uielement~UIElement} that UIElement will be returned.\n\t *\n\t * @param domNode DOM node or document fragment to transform.\n\t * @param options Conversion options.\n\t * @param options.bind Determines whether new elements will be bound. False by default.\n\t * @param options.withChildren If `true`, node's and document fragment's children will be converted too. True by default.\n\t * @param options.keepOriginalCase If `false`, node's tag name will be converted to lower case. False by default.\n\t * @param options.skipComments If `false`, comment nodes will be converted to `$comment`\n\t * {@link module:engine/view/uielement~UIElement view UI elements}. False by default.\n\t * @returns Converted node or document fragment or `null` if DOM node is a {@link module:engine/view/filler filler}\n\t * or the given node is an empty text node.\n\t */\n\tpublic domToView(\n\t\tdomNode: DomNode,\n\t\toptions: {\n\t\t\tbind?: boolean;\n\t\t\twithChildren?: boolean;\n\t\t\tkeepOriginalCase?: boolean;\n\t\t\tskipComments?: boolean;\n\t\t} = {}\n\t): ViewNode | ViewDocumentFragment | null {\n\t\tconst inlineNodes: Array<ViewNode> = [];\n\t\tconst generator = this._domToView( domNode, options, inlineNodes );\n\n\t\t// Get the first yielded value or a returned value.\n\t\tconst node = generator.next().value;\n\n\t\tif ( !node ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Trigger children handling.\n\t\tgenerator.next();\n\n\t\t// Whitespace cleaning.\n\t\tthis._processDomInlineNodes( null, inlineNodes, options );\n\n\t\t// Text not got trimmed to an empty string so there is no result node.\n\t\tif ( node.is( '$text' ) && node.data.length == 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Converts children of the DOM element to view nodes using\n\t * the {@link module:engine/view/domconverter~DomConverter#domToView} method.\n\t * Additionally this method omits block {@link module:engine/view/filler filler}, if it exists in the DOM parent.\n\t *\n\t * @param domElement Parent DOM element.\n\t * @param options See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t * @param inlineNodes An array that will be populated with inline nodes. It's used internally for whitespace processing.\n\t * @returns View nodes.\n\t */\n\tpublic* domChildrenToView(\n\t\tdomElement: DomElement,\n\t\toptions: Parameters<DomConverter[ 'domToView' ]>[ 1 ] = {},\n\t\tinlineNodes: Array<ViewNode> = []\n\t): IterableIterator<ViewNode> {\n\t\t// Get child nodes from content document fragment if element is template\n\t\tlet childNodes: Array<ChildNode> = [];\n\n\t\tif ( domElement instanceof HTMLTemplateElement ) {\n\t\t\tchildNodes = [ ...domElement.content.childNodes ];\n\t\t} else {\n\t\t\tchildNodes = [ ...domElement.childNodes ];\n\t\t}\n\n\t\tfor ( let i = 0; i < childNodes.length; i++ ) {\n\t\t\tconst domChild = childNodes[ i ];\n\t\t\tconst generator = this._domToView( domChild, options, inlineNodes );\n\n\t\t\t// Get the first yielded value or a returned value.\n\t\t\tconst viewChild = generator.next().value as ViewNode | null;\n\n\t\t\tif ( viewChild !== null ) {\n\t\t\t\t// Whitespace cleaning before entering a block element (between block elements).\n\t\t\t\tif ( this._isBlockViewElement( viewChild ) ) {\n\t\t\t\t\tthis._processDomInlineNodes( domElement, inlineNodes, options );\n\t\t\t\t}\n\n\t\t\t\tyield viewChild;\n\n\t\t\t\t// Trigger children handling.\n\t\t\t\tgenerator.next();\n\t\t\t}\n\t\t}\n\n\t\t// Whitespace cleaning before leaving a block element (content of block element).\n\t\tthis._processDomInlineNodes( domElement, inlineNodes, options );\n\t}\n\n\t/**\n\t * Converts DOM selection to view {@link module:engine/view/selection~Selection}.\n\t * Ranges which cannot be converted will be omitted.\n\t *\n\t * @param domSelection DOM selection.\n\t * @returns View selection.\n\t */\n\tpublic domSelectionToView( domSelection: DomSelection ): ViewSelection {\n\t\t// See: https://github.com/ckeditor/ckeditor5/issues/9635.\n\t\tif ( isGeckoRestrictedDomSelection( domSelection ) ) {\n\t\t\treturn new ViewSelection( [] );\n\t\t}\n\n\t\t// DOM selection might be placed in fake selection container.\n\t\t// If container contains fake selection - return corresponding view selection.\n\t\tif ( domSelection.rangeCount === 1 ) {\n\t\t\tlet container: Node | null = domSelection.getRangeAt( 0 ).startContainer;\n\n\t\t\t// The DOM selection might be moved to the text node inside the fake selection container.\n\t\t\tif ( isText( container ) ) {\n\t\t\t\tcontainer = container.parentNode;\n\t\t\t}\n\n\t\t\tconst viewSelection = this.fakeSelectionToView( container as DomElement );\n\n\t\t\tif ( viewSelection ) {\n\t\t\t\treturn viewSelection;\n\t\t\t}\n\t\t}\n\n\t\tconst isBackward = this.isDomSelectionBackward( domSelection );\n\n\t\tconst viewRanges: Array<ViewRange> = [];\n\n\t\tfor ( let i = 0; i < domSelection.rangeCount; i++ ) {\n\t\t\t// DOM Range have correct start and end, no matter what is the DOM Selection direction. So we don't have to fix anything.\n\t\t\tconst domRange = domSelection.getRangeAt( i );\n\t\t\tconst viewRange = this.domRangeToView( domRange );\n\n\t\t\tif ( viewRange ) {\n\t\t\t\tviewRanges.push( viewRange );\n\t\t\t}\n\t\t}\n\n\t\treturn new ViewSelection( viewRanges, { backward: isBackward } );\n\t}\n\n\t/**\n\t * Converts DOM Range to view {@link module:engine/view/range~Range}.\n\t * If the start or end position can not be converted `null` is returned.\n\t *\n\t * @param domRange DOM range.\n\t * @returns View range.\n\t */\n\tpublic domRangeToView( domRange: DomRange | StaticRange ): ViewRange | null {\n\t\tconst viewStart = this.domPositionToView( domRange.startContainer, domRange.startOffset );\n\t\tconst viewEnd = this.domPositionToView( domRange.endContainer, domRange.endOffset );\n\n\t\tif ( viewStart && viewEnd ) {\n\t\t\treturn new ViewRange( viewStart, viewEnd );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Converts DOM parent and offset to view {@link module:engine/view/position~Position}.\n\t *\n\t * If the position is inside a {@link module:engine/view/filler filler} which has no corresponding view node,\n\t * position of the filler will be converted and returned.\n\t *\n\t * If the position is inside DOM element rendered by {@link module:engine/view/uielement~UIElement}\n\t * that position will be converted to view position before that UIElement.\n\t *\n\t * If structures are too different and it is not possible to find corresponding position then `null` will be returned.\n\t *\n\t * @param domParent DOM position parent.\n\t * @param domOffset DOM position offset. You can skip it when converting the inline filler node.\n\t * @returns View position.\n\t */\n\tpublic domPositionToView( domParent: DomNode, domOffset: number = 0 ): ViewPosition | null {\n\t\tif ( this.isBlockFiller( domParent ) ) {\n\t\t\treturn this.domPositionToView( domParent.parentNode!, indexOf( domParent ) );\n\t\t}\n\n\t\t// If position is somewhere inside UIElement or a RawElement - return position before that element.\n\t\tconst viewElement = this.mapDomToView( domParent as DomElement );\n\n\t\tif ( viewElement && ( viewElement.is( 'uiElement' ) || viewElement.is( 'rawElement' ) ) ) {\n\t\t\treturn ViewPosition._createBefore( viewElement );\n\t\t}\n\n\t\tif ( isText( domParent ) ) {\n\t\t\tif ( isInlineFiller( domParent ) ) {\n\t\t\t\treturn this.domPositionToView( domParent.parentNode!, indexOf( domParent ) );\n\t\t\t}\n\n\t\t\tconst viewParent = this.findCorrespondingViewText( domParent );\n\t\t\tlet offset = domOffset;\n\n\t\t\tif ( !viewParent ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( startsWithFiller( domParent ) ) {\n\t\t\t\toffset -= INLINE_FILLER_LENGTH;\n\t\t\t\toffset = offset < 0 ? 0 : offset;\n\t\t\t}\n\n\t\t\treturn new ViewPosition( viewParent, offset );\n\t\t}\n\t\t// domParent instanceof HTMLElement.\n\t\telse {\n\t\t\tif ( domOffset === 0 ) {\n\t\t\t\tconst viewParent = this.mapDomToView( domParent as DomElement );\n\n\t\t\t\tif ( viewParent ) {\n\t\t\t\t\treturn new ViewPosition( viewParent, 0 );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst domBefore = domParent.childNodes[ domOffset - 1 ];\n\n\t\t\t\t// Jump over an inline filler (and also on Firefox jump over a block filler while pressing backspace in an empty paragraph).\n\t\t\t\tif ( isText( domBefore ) && isInlineFiller( domBefore ) || domBefore && this.isBlockFiller( domBefore ) ) {\n\t\t\t\t\treturn this.domPositionToView( domBefore.parentNode!, indexOf( domBefore ) );\n\t\t\t\t}\n\n\t\t\t\tconst viewBefore = isText( domBefore ) ?\n\t\t\t\t\tthis.findCorrespondingViewText( domBefore ) :\n\t\t\t\t\tthis.mapDomToView( domBefore as DomElement );\n\n\t\t\t\t// TODO #663\n\t\t\t\tif ( viewBefore && viewBefore.parent ) {\n\t\t\t\t\treturn new ViewPosition( viewBefore.parent, viewBefore.index! + 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Returns corresponding view {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment} for provided DOM element or\n\t * document fragment. If there is no view item {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * to the given DOM - `undefined` is returned.\n\t *\n\t * For all DOM elements rendered by a {@link module:engine/view/uielement~UIElement} or\n\t * a {@link module:engine/view/rawelement~RawElement}, the parent `UIElement` or `RawElement` will be returned.\n\t *\n\t * @param domElementOrDocumentFragment DOM element or document fragment.\n\t * @returns Corresponding view element, document fragment or `undefined` if no element was bound.\n\t */\n\tpublic mapDomToView( domElementOrDocumentFragment: DomElement | DomDocumentFragment ): ViewElement | ViewDocumentFragment | undefined {\n\t\tconst hostElement = this.getHostViewElement( domElementOrDocumentFragment );\n\n\t\treturn hostElement || this._domToViewMapping.get( domElementOrDocumentFragment );\n\t}\n\n\t/**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#bindElements bound},\n\t * corresponding text node is returned based on the sibling or parent.\n\t *\n\t * If the directly previous sibling is a {@link module:engine/view/domconverter~DomConverter#bindElements bound} element, it is used\n\t * to find the corresponding text node.\n\t *\n\t * If this is a first child in the parent and the parent is a {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * element, it is used to find the corresponding text node.\n\t *\n\t * For all text nodes rendered by a {@link module:engine/view/uielement~UIElement} or\n\t * a {@link module:engine/view/rawelement~RawElement}, the parent `UIElement` or `RawElement` will be returned.\n\t *\n\t * Otherwise `null` is returned.\n\t *\n\t * Note that for the block or inline {@link module:engine/view/filler filler} this method returns `null`.\n\t *\n\t * @param domText DOM text node.\n\t * @returns Corresponding view text node or `null`, if it was not possible to find a corresponding node.\n\t */\n\tpublic findCorrespondingViewText( domText: DomText ): ViewText | ViewUIElement | ViewRawElement | null {\n\t\tif ( isInlineFiller( domText ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// If DOM text was rendered by a UIElement or a RawElement - return this parent element.\n\t\tconst hostElement = this.getHostViewElement( domText );\n\n\t\tif ( hostElement ) {\n\t\t\treturn hostElement;\n\t\t}\n\n\t\tconst previousSibling = domText.previousSibling;\n\n\t\t// Try to use previous sibling to find the corresponding text node.\n\t\tif ( previousSibling ) {\n\t\t\tif ( !( this.isElement( previousSibling ) ) ) {\n\t\t\t\t// The previous is text or comment.\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst viewElement = this.mapDomToView( previousSibling );\n\n\t\t\tif ( viewElement ) {\n\t\t\t\tconst nextSibling = ( viewElement as ViewElement ).nextSibling;\n\n\t\t\t\t// It might be filler which has no corresponding view node.\n\t\t\t\tif ( nextSibling instanceof ViewText ) {\n\t\t\t\t\treturn nextSibling;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Try to use parent to find the corresponding text node.\n\t\telse {\n\t\t\tconst viewElement = this.mapDomToView( domText.parentNode as ( DomElement | DomDocumentFragment ) );\n\n\t\t\tif ( viewElement ) {\n\t\t\t\tconst firstChild = ( viewElement as ViewElement ).getChild( 0 );\n\n\t\t\t\t// It might be filler which has no corresponding view node.\n\t\t\t\tif ( firstChild instanceof ViewText ) {\n\t\t\t\t\treturn firstChild;\n\t\t\t\t} else {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns corresponding DOM item for provided {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment}.\n\t * To find a corresponding text for {@link module:engine/view/text~Text view Text instance}\n\t * use {@link #findCorrespondingDomText}.\n\t *\n\t * @label ELEMENT\n\t * @param element View element or document fragment.\n\t * @returns Corresponding DOM node or document fragment.\n\t */\n\tpublic mapViewToDom( element: ViewElement ): DomElement | undefined;\n\n\t/**\n\t * Returns corresponding DOM item for provided {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment}.\n\t * To find a corresponding text for {@link module:engine/view/text~Text view Text instance}\n\t * use {@link #findCorrespondingDomText}.\n\t *\n\t * @label DOCUMENT_FRAGMENT\n\t * @param documentFragment View element or document fragment.\n\t * @returns Corresponding DOM node or document fragment.\n\t */\n\tpublic mapViewToDom( documentFragment: ViewDocumentFragment ): DomDocumentFragment | undefined;\n\n\t/**\n\t * Returns corresponding DOM item for provided {@link module:engine/view/element~Element Element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment}.\n\t * To find a corresponding text for {@link module:engine/view/text~Text view Text instance}\n\t * use {@link #findCorrespondingDomText}.\n\t *\n\t * @label DOCUMENT_FRAGMENT_OR_ELEMENT\n\t * @param documentFragmentOrElement View element or document fragment.\n\t * @returns Corresponding DOM node or document fragment.\n\t */\n\tpublic mapViewToDom( documentFragmentOrElement: ViewElement | ViewDocumentFragment ): DomElement | DomDocumentFragment | undefined;\n\n\tpublic mapViewToDom( documentFragmentOrElement: ViewElement | ViewDocumentFragment ): DomElement | DomDocumentFragment | undefined {\n\t\treturn this._viewToDomMapping.get( documentFragmentOrElement );\n\t}\n\n\t/**\n\t * Finds corresponding text node. Text nodes are not {@link module:engine/view/domconverter~DomConverter#bindElements bound},\n\t * corresponding text node is returned based on the sibling or parent.\n\t *\n\t * If the directly previous sibling is a {@link module:engine/view/domconverter~DomConverter#bindElements bound} element, it is used\n\t * to find the corresponding text node.\n\t *\n\t * If this is a first child in the parent and the parent is a {@link module:engine/view/domconverter~DomConverter#bindElements bound}\n\t * element, it is used to find the corresponding text node.\n\t *\n\t * Otherwise `null` is returned.\n\t *\n\t * @param viewText View text node.\n\t * @returns Corresponding DOM text node or `null`, if it was not possible to find a corresponding node.\n\t */\n\tpublic findCorrespondingDomText( viewText: ViewText ): DomText | null {\n\t\tconst previousSibling = viewText.previousSibling;\n\n\t\t// Try to use previous sibling to find the corresponding text node.\n\t\tif ( previousSibling && this.mapViewToDom( previousSibling as ViewElement ) ) {\n\t\t\treturn this.mapViewToDom( previousSibling as ViewElement )!.nextSibling as DomText;\n\t\t}\n\n\t\t// If this is a first node, try to use parent to find the corresponding text node.\n\t\tif ( !previousSibling && viewText.parent && this.mapViewToDom( viewText.parent ) ) {\n\t\t\treturn this.mapViewToDom( viewText.parent )!.childNodes[ 0 ] as DomText;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Focuses DOM editable that is corresponding to provided {@link module:engine/view/editableelement~EditableElement}.\n\t */\n\tpublic focus( viewEditable: EditableElement ): void {\n\t\tconst domEditable = this.mapViewToDom( viewEditable );\n\n\t\tif ( domEditable && domEditable.ownerDocument.activeElement !== domEditable ) {\n\t\t\t// Save the scrollX and scrollY positions before the focus.\n\t\t\tconst { scrollX, scrollY } = global.window;\n\t\t\tconst scrollPositions: Array<[ number, number ]> = [];\n\n\t\t\t// Save all scrollLeft and scrollTop values starting from domEditable up to\n\t\t\t// document#documentElement.\n\t\t\tforEachDomElementAncestor( domEditable, node => {\n\t\t\t\tconst { scrollLeft, scrollTop } = ( node as DomElement );\n\n\t\t\t\tscrollPositions.push( [ scrollLeft, scrollTop ] );\n\t\t\t} );\n\n\t\t\tdomEditable.focus();\n\n\t\t\t// Restore scrollLeft and scrollTop values starting from domEditable up to\n\t\t\t// document#documentElement.\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/951\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/957\n\t\t\tforEachDomElementAncestor( domEditable, node => {\n\t\t\t\tconst [ scrollLeft, scrollTop ] = scrollPositions.shift() as [ number, number ];\n\n\t\t\t\tnode.scrollLeft = scrollLeft;\n\t\t\t\tnode.scrollTop = scrollTop;\n\t\t\t} );\n\n\t\t\t// Restore the scrollX and scrollY positions after the focus.\n\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/951\n\t\t\tglobal.window.scrollTo( scrollX, scrollY );\n\t\t}\n\t}\n\n\t/**\n\t * Remove DOM selection from blurred editable, so it won't interfere with clicking on dropdowns (especially on iOS).\n\t *\n\t * @internal\n\t */\n\tpublic _clearDomSelection(): void {\n\t\tconst domEditable = this.mapViewToDom( this.document.selection.editableElement! );\n\n\t\tif ( !domEditable ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if DOM selection is inside editor editable element.\n\t\tconst domSelection = domEditable.ownerDocument.defaultView!.getSelection()!;\n\t\tconst newViewSelection = this.domSelectionToView( domSelection );\n\t\tconst selectionInEditable = newViewSelection && newViewSelection.rangeCount > 0;\n\n\t\tif ( selectionInEditable ) {\n\t\t\tdomSelection.removeAllRanges();\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.ELEMENT_NODE`.\n\t *\n\t * @param node Node to check.\n\t */\n\tpublic isElement( node: DomNode ): node is DomElement {\n\t\treturn node && node.nodeType == Node.ELEMENT_NODE;\n\t}\n\n\t/**\n\t * Returns `true` when `node.nodeType` equals `Node.DOCUMENT_FRAGMENT_NODE`.\n\t *\n\t * @param node Node to check.\n\t */\n\tpublic isDocumentFragment( node: DomNode ): node is DomDocumentFragment {\n\t\treturn node && node.nodeType == Node.DOCUMENT_FRAGMENT_NODE;\n\t}\n\n\t/**\n\t * Checks if the node is an instance of the block filler for this DOM converter.\n\t *\n\t * ```ts\n\t * const converter = new DomConverter( viewDocument, { blockFillerMode: 'br' } );\n\t *\n\t * converter.isBlockFiller( BR_FILLER( document ) ); // true\n\t * converter.isBlockFiller( NBSP_FILLER( document ) ); // false\n\t * ```\n\t *\n\t * **Note:**: For the `'nbsp'` mode the method also checks context of a node so it cannot be a detached node.\n\t *\n\t * **Note:** A special case in the `'nbsp'` mode exists where the `<br>` in `<p><br></p>` is treated as a block filler.\n\t *\n\t * @param domNode DOM node to check.\n\t * @returns True if a node is considered a block filler for given mode.\n\t */\n\tpublic isBlockFiller( domNode: DomNode ): boolean {\n\t\tif ( this.blockFillerMode == 'br' ) {\n\t\t\treturn domNode.isEqualNode( BR_FILLER_REF );\n\t\t}\n\n\t\t// Special case for <p><br></p> in which <br> should be treated as filler even when we are not in the 'br' mode. See ckeditor5#5564.\n\t\tif (\n\t\t\t( domNode as DomElement ).tagName === 'BR' &&\n\t\t\thasBlockParent( domNode, this.blockElements ) &&\n\t\t\t( domNode as DomElement ).parentNode!.childNodes.length === 1\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// If not in 'br' mode, try recognizing both marked and regular nbsp block fillers.\n\t\treturn domNode.isEqualNode( MARKED_NBSP_FILLER_REF ) || isNbspBlockFiller( domNode, this.blockElements );\n\t}\n\n\t/**\n\t * Returns `true` if given selection is a backward selection, that is, if it's `focus` is before `anchor`.\n\t *\n\t * @param DOM Selection instance to check.\n\t */\n\tpublic isDomSelectionBackward( selection: DomSelection ): boolean {\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Since it takes multiple lines of code to check whether a \"DOM Position\" is before/after another \"DOM Position\",\n\t\t// we will use the fact that range will collapse if it's end is before it's start.\n\t\tconst range = this._domDocument.createRange();\n\n\t\ttry {\n\t\t\trange.setStart( selection.anchorNode!, selection.anchorOffset );\n\t\t\trange.setEnd( selection.focusNode!, selection.focusOffset );\n\t\t} catch ( e ) {\n\t\t\t// Safari sometimes gives us a selection that makes Range.set{Start,End} throw.\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/12375.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst backward = range.collapsed;\n\n\t\trange.detach();\n\n\t\treturn backward;\n\t}\n\n\t/**\n\t * Returns a parent {@link module:engine/view/uielement~UIElement} or {@link module:engine/view/rawelement~RawElement}\n\t * that hosts the provided DOM node. Returns `null` if there is no such parent.\n\t */\n\tpublic getHostViewElement( domNode: DomNode ): ViewUIElement | ViewRawElement | null {\n\t\tconst ancestors = getAncestors( domNode );\n\n\t\t// Remove domNode from the list.\n\t\tancestors.pop();\n\n\t\twhile ( ancestors.length ) {\n\t\t\tconst domNode = ancestors.pop();\n\t\t\tconst viewNode = this._domToViewMapping.get( domNode as DomElement );\n\n\t\t\tif ( viewNode && ( viewNode.is( 'uiElement' ) || viewNode.is( 'rawElement' ) ) ) {\n\t\t\t\treturn viewNode;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks if the given selection's boundaries are at correct places.\n\t *\n\t * The following places are considered as incorrect for selection boundaries:\n\t *\n\t * * before or in the middle of an inline filler sequence,\n\t * * inside a DOM element which represents {@link module:engine/view/uielement~UIElement a view UI element},\n\t * * inside a DOM element which represents {@link module:engine/view/rawelement~RawElement a view raw element}.\n\t *\n\t * @param domSelection The DOM selection object to be checked.\n\t * @returns `true` if the given selection is at a correct place, `false` otherwise.\n\t */\n\tpublic isDomSelectionCorrect( domSelection: DomSelection ): boolean {\n\t\treturn this._isDomSelectionPositionCorrect( domSelection.anchorNode!, domSelection.anchorOffset ) &&\n\t\t\tthis._isDomSelectionPositionCorrect( domSelection.focusNode!, domSelection.focusOffset );\n\t}\n\n\t/**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from DOM nodes to view elements.\n\t *\n\t * This is affecting how {@link module:engine/view/domconverter~DomConverter#domToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#domChildrenToView} process DOM nodes.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching a view element whose content should\n\t * be treated as raw data.\n\t */\n\tpublic registerRawContentMatcher( pattern: MatcherPattern ): void {\n\t\tthis._rawContentElementMatcher.add( pattern );\n\t}\n\n\t/**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for inline object view elements.\n\t *\n\t * This is affecting how {@link module:engine/view/domconverter~DomConverter#domToView} and\n\t * {@link module:engine/view/domconverter~DomConverter#domChildrenToView} process DOM nodes.\n\t *\n\t * This is an extension of a simple {@link #inlineObjectElements} array of element names.\n\t *\n\t * @param pattern Pattern matching a view element which should be treated as an inline object.\n\t */\n\tpublic registerInlineObjectMatcher( pattern: MatcherPattern ): void {\n\t\tthis._inlineObjectElementMatcher.add( pattern );\n\t}\n\n\t/**\n\t * Clear temporary custom properties.\n\t *\n\t * @internal\n\t */\n\tpublic _clearTemporaryCustomProperties(): void {\n\t\tfor ( const element of this._elementsWithTemporaryCustomProperties ) {\n\t\t\telement._removeCustomProperty( 'editingPipeline:doNotReuseOnce' );\n\t\t}\n\n\t\tthis._elementsWithTemporaryCustomProperties.clear();\n\t}\n\n\t/**\n\t * Returns the block {@link module:engine/view/filler filler} node based on the current {@link #blockFillerMode} setting.\n\t */\n\tprivate _getBlockFiller(): DomNode {\n\t\tswitch ( this.blockFillerMode ) {\n\t\t\tcase 'nbsp':\n\t\t\t\treturn NBSP_FILLER( this._domDocument ); // eslint-disable-line new-cap\n\t\t\tcase 'markedNbsp':\n\t\t\t\treturn MARKED_NBSP_FILLER( this._domDocument ); // eslint-disable-line new-cap\n\t\t\tcase 'br':\n\t\t\t\treturn BR_FILLER( this._domDocument ); // eslint-disable-line new-cap\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given DOM position is a correct place for selection boundary. See {@link #isDomSelectionCorrect}.\n\t *\n\t * @param domParent Position parent.\n\t * @param offset Position offset.\n\t * @returns `true` if given position is at a correct place for selection boundary, `false` otherwise.\n\t */\n\tprivate _isDomSelectionPositionCorrect( domParent: DomNode, offset: number ): boolean {\n\t\t// If selection is before or in the middle of inline filler string, it is incorrect.\n\t\tif ( isText( domParent ) && startsWithFiller( domParent ) && offset < INLINE_FILLER_LENGTH ) {\n\t\t\t// Selection in a text node, at wrong position (before or in the middle of filler).\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.isElement( domParent ) && startsWithFiller( domParent.childNodes[ offset ] ) ) {\n\t\t\t// Selection in an element node, before filler text node.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewParent = this.mapDomToView( domParent as DomElement );\n\n\t\t// The position is incorrect when anchored inside a UIElement or a RawElement.\n\t\t// Note: In case of UIElement and RawElement, mapDomToView() returns a parent element for any DOM child\n\t\t// so there's no need to perform any additional checks.\n\t\tif ( viewParent && ( viewParent.is( 'uiElement' ) || viewParent.is( 'rawElement' ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Internal generator for {@link #domToView}. Also used by {@link #domChildrenToView}.\n\t * Separates DOM nodes conversion from whitespaces processing.\n\t *\n\t * @param domNode DOM node or document fragment to transform.\n\t * @param inlineNodes An array of recently encountered inline nodes truncated to the block element boundaries.\n\t * Used later to process whitespaces.\n\t */\n\tprivate* _domToView(\n\t\tdomNode: DomNode,\n\t\toptions: {\n\t\t\tbind?: boolean;\n\t\t\twithChildren?: boolean;\n\t\t\tkeepOriginalCase?: boolean;\n\t\t\tskipComments?: boolean;\n\t\t},\n\t\tinlineNodes: Array<ViewNode>\n\t): IterableIterator<ViewNode | ViewDocumentFragment | null> {\n\t\tif ( this.isBlockFiller( domNode ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// When node is inside a UIElement or a RawElement return that parent as it's view representation.\n\t\tconst hostElement = this.getHostViewElement( domNode );\n\n\t\tif ( hostElement ) {\n\t\t\treturn hostElement;\n\t\t}\n\n\t\tif ( isComment( domNode ) && options.skipComments ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( isText( domNode ) ) {\n\t\t\tif ( isInlineFiller( domNode ) ) {\n\t\t\t\treturn null;\n\t\t\t} else {\n\t\t\t\tconst textData = domNode.data;\n\n\t\t\t\tif ( textData === '' ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst textNode = new ViewText( this.document, textData );\n\n\t\t\t\tinlineNodes.push( textNode );\n\n\t\t\t\treturn textNode;\n\t\t\t}\n\t\t} else {\n\t\t\tlet viewElement = this.mapDomToView( domNode as ( DomElement | DomDocumentFragment ) );\n\n\t\t\tif ( viewElement ) {\n\t\t\t\tif ( this._isInlineObjectElement( viewElement ) ) {\n\t\t\t\t\tinlineNodes.push( viewElement );\n\t\t\t\t}\n\n\t\t\t\treturn viewElement;\n\t\t\t}\n\n\t\t\tif ( this.isDocumentFragment( domNode ) ) {\n\t\t\t\t// Create view document fragment.\n\t\t\t\tviewElement = new ViewDocumentFragment( this.document );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindDocumentFragments( domNode, viewElement );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Create view element.\n\t\t\t\tviewElement = this._createViewElement( domNode, options );\n\n\t\t\t\tif ( options.bind ) {\n\t\t\t\t\tthis.bindElements( domNode as DomElement, viewElement );\n\t\t\t\t}\n\n\t\t\t\t// Copy element's attributes.\n\t\t\t\tconst attrs = ( domNode as DomElement ).attributes;\n\n\t\t\t\tif ( attrs ) {\n\t\t\t\t\tfor ( let l = attrs.length, i = 0; i < l; i++ ) {\n\t\t\t\t\t\tviewElement._setAttribute( attrs[ i ].name, attrs[ i ].value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Treat this element's content as a raw data if it was registered as such.\n\t\t\t\tif ( this._isViewElementWithRawContent( viewElement, options ) ) {\n\t\t\t\t\tviewElement._setCustomProperty( '$rawContent', ( domNode as DomElement ).innerHTML );\n\n\t\t\t\t\tif ( !this._isBlockViewElement( viewElement ) ) {\n\t\t\t\t\t\tinlineNodes.push( viewElement );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn viewElement;\n\t\t\t\t}\n\n\t\t\t\t// Comment node is also treated as an element with raw data.\n\t\t\t\tif ( isComment( domNode ) ) {\n\t\t\t\t\tviewElement._setCustomProperty( '$rawContent', domNode.data );\n\n\t\t\t\t\treturn viewElement;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Yield the element first so the flow of nested inline nodes is not reversed inside elements.\n\t\t\tyield viewElement;\n\n\t\t\tconst nestedInlineNodes: Array<ViewNode> = [];\n\n\t\t\tif ( options.withChildren !== false ) {\n\t\t\t\tfor ( const child of this.domChildrenToView( domNode as DomElement, options, nestedInlineNodes ) ) {\n\t\t\t\t\tviewElement._appendChild( child );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check if this is an inline object after processing child nodes so matcher\n\t\t\t// for inline objects can verify if the element is empty.\n\t\t\tif ( this._isInlineObjectElement( viewElement ) ) {\n\t\t\t\tinlineNodes.push( viewElement );\n\n\t\t\t\t// Inline object content should be handled as a flow-root.\n\t\t\t\tthis._processDomInlineNodes( null, nestedInlineNodes, options );\n\t\t\t} else {\n\t\t\t\t// It's an inline element that is not an object (like <b>, <i>) or a block element.\n\t\t\t\tfor ( const inlineNode of nestedInlineNodes ) {\n\t\t\t\t\tinlineNodes.push( inlineNode );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Internal helper that walks the list of inline view nodes already generated from DOM nodes\n\t * and handles whitespaces and NBSPs.\n\t *\n\t * @param domParent The DOM parent of the given inline nodes. This should be a document fragment or\n\t * a block element to whitespace processing start cleaning.\n\t * @param inlineNodes An array of recently encountered inline nodes truncated to the block element boundaries.\n\t */\n\tprivate _processDomInlineNodes(\n\t\tdomParent: DomElement | null,\n\t\tinlineNodes: Array<ViewNode>,\n\t\toptions: { withChildren?: boolean }\n\t): void {\n\t\tif ( !inlineNodes.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Process text nodes only after reaching a block or document fragment,\n\t\t// do not alter whitespaces while processing an inline element like <b> or <i>.\n\t\tif ( domParent && !this.isDocumentFragment( domParent ) && !this._isBlockDomElement( domParent ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet prevNodeEndsWithSpace = false;\n\n\t\tfor ( let i = 0; i < inlineNodes.length; i++ ) {\n\t\t\tconst node = inlineNodes[ i ];\n\n\t\t\tif ( !node.is( '$text' ) ) {\n\t\t\t\tprevNodeEndsWithSpace = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet data: string;\n\t\t\tlet nodeEndsWithSpace: boolean = false;\n\n\t\t\tif ( this._isPreFormatted( node ) ) {\n\t\t\t\tdata = getDataWithoutFiller( node.data );\n\t\t\t} else {\n\t\t\t\t// Change all consecutive whitespace characters (from the [ \\n\\t\\r] set –\n\t\t\t\t// see https://github.com/ckeditor/ckeditor5-engine/issues/822#issuecomment-311670249) to a single space character.\n\t\t\t\t// That's how multiple whitespaces are treated when rendered, so we normalize those whitespaces.\n\t\t\t\t// We're replacing 1+ (and not 2+) to also normalize singular \\n\\t\\r characters (#822).\n\t\t\t\tdata = node.data.replace( /[ \\n\\t\\r]{1,}/g, ' ' );\n\t\t\t\tnodeEndsWithSpace = /[^\\S\\u00A0]/.test( data.charAt( data.length - 1 ) );\n\n\t\t\t\tconst prevNode = i > 0 ? inlineNodes[ i - 1 ] : null;\n\t\t\t\tconst nextNode = i + 1 < inlineNodes.length ? inlineNodes[ i + 1 ] : null;\n\n\t\t\t\tconst shouldLeftTrim = !prevNode || prevNode.is( 'element' ) && prevNode.name == 'br' || prevNodeEndsWithSpace;\n\t\t\t\tconst shouldRightTrim = nextNode ? false : !startsWithFiller( node.data );\n\n\t\t\t\t// Do not try to clear whitespaces if this is flat mapping for the purpose of mutation observer and differ in rendering.\n\t\t\t\tif ( options.withChildren !== false ) {\n\t\t\t\t\t// If the previous dom text node does not exist or it ends by whitespace character, remove space character from the\n\t\t\t\t\t// beginning of this text node. Such space character is treated as a whitespace.\n\t\t\t\t\tif ( shouldLeftTrim ) {\n\t\t\t\t\t\tdata = data.replace( /^ /, '' );\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the next text node does not exist remove space character from the end of this text node.\n\t\t\t\t\tif ( shouldRightTrim ) {\n\t\t\t\t\t\tdata = data.replace( / $/, '' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// At the beginning and end of a block element, Firefox inserts normal space + <br> instead of non-breaking space.\n\t\t\t\t// This means that the text node starts/end with normal space instead of non-breaking space.\n\t\t\t\t// This causes a problem because the normal space would be removed in `.replace` calls above. To prevent that,\n\t\t\t\t// the inline filler is removed only after the data is initially processed (by the `.replace` above). See ckeditor5#692.\n\t\t\t\tdata = getDataWithoutFiller( data );\n\n\t\t\t\t// At this point we should have removed all whitespaces from DOM text data.\n\t\t\t\t//\n\t\t\t\t// Now, We will reverse the process that happens in `_processDataFromViewText`.\n\t\t\t\t//\n\t\t\t\t// We have to change &nbsp; chars, that were in DOM text data because of rendering reasons, to spaces.\n\t\t\t\t// First, change all ` \\u00A0` pairs (space + &nbsp;) to two spaces. DOM converter changes two spaces from model/view to\n\t\t\t\t// ` \\u00A0` to ensure proper rendering. Since here we convert back, we recognize those pairs and change them back to `  `.\n\t\t\t\tdata = data.replace( / \\u00A0/g, '  ' );\n\n\t\t\t\tconst isNextNodeInlineObjectElement = nextNode && nextNode.is( 'element' ) && nextNode.name != 'br';\n\t\t\t\tconst isNextNodeStartingWithSpace = nextNode && nextNode.is( '$text' ) && nextNode.data.charAt( 0 ) == ' ';\n\n\t\t\t\t// Then, let's change the last nbsp to a space.\n\t\t\t\tif ( /[ \\u00A0]\\u00A0$/.test( data ) || !nextNode || isNextNodeInlineObjectElement || isNextNodeStartingWithSpace ) {\n\t\t\t\t\tdata = data.replace( /\\u00A0$/, ' ' );\n\t\t\t\t}\n\n\t\t\t\t// Then, change &nbsp; character that is at the beginning of the text node to space character.\n\t\t\t\t// We do that replacement only if this is the first node or the previous node ends on whitespace character.\n\t\t\t\tif ( shouldLeftTrim || prevNode && prevNode.is( 'element' ) && prevNode.name != 'br' ) {\n\t\t\t\t\tdata = data.replace( /^\\u00A0/, ' ' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// At this point, all whitespaces should be removed and all &nbsp; created for rendering reasons should be\n\t\t\t// changed to normal space. All left &nbsp; are &nbsp; inserted intentionally.\n\n\t\t\tif ( data.length == 0 && node.parent ) {\n\t\t\t\tnode._remove();\n\t\t\t\tinlineNodes.splice( i, 1 );\n\t\t\t\ti--;\n\t\t\t} else {\n\t\t\t\tnode._data = data;\n\t\t\t\tprevNodeEndsWithSpace = nodeEndsWithSpace;\n\t\t\t}\n\t\t}\n\n\t\tinlineNodes.length = 0;\n\t}\n\n\t/**\n\t * Takes text data from a given {@link module:engine/view/text~Text#data} and processes it so\n\t * it is correctly displayed in the DOM.\n\t *\n\t * Following changes are done:\n\t *\n\t * * a space at the beginning is changed to `&nbsp;` if this is the first text node in its container\n\t * element or if a previous text node ends with a space character,\n\t * * space at the end of the text node is changed to `&nbsp;` if there are two spaces at the end of a node or if next node\n\t * starts with a space or if it is the last text node in its container,\n\t * * remaining spaces are replaced to a chain of spaces and `&nbsp;` (e.g. `'x   x'` becomes `'x &nbsp; x'`).\n\t *\n\t * Content of {@link #preElements} is not processed.\n\t *\n\t * @param node View text node to process.\n\t * @returns Processed text data.\n\t */\n\tprivate _processDataFromViewText( node: ViewText | ViewTextProxy ): string {\n\t\tlet data = node.data;\n\n\t\t// If the currently processed view text node is preformatted, we should not change whitespaces.\n\t\tif ( this._isPreFormatted( node ) ) {\n\t\t\treturn data;\n\t\t}\n\n\t\t// 1. Replace the first space with a nbsp if the previous node ends with a space or there is no previous node\n\t\t// (container element boundary).\n\t\tif ( data.charAt( 0 ) == ' ' ) {\n\t\t\tconst prevNode = this._getTouchingInlineViewNode( node as ViewText, false );\n\t\t\tconst prevEndsWithSpace = prevNode && prevNode.is( '$textProxy' ) && this._nodeEndsWithSpace( prevNode as ViewTextProxy );\n\n\t\t\tif ( prevEndsWithSpace || !prevNode ) {\n\t\t\t\tdata = '\\u00A0' + data.substr( 1 );\n\t\t\t}\n\t\t}\n\n\t\t// 2. Replace the last space with nbsp if there are two spaces at the end or if the next node starts with space or there is no\n\t\t// next node (container element boundary).\n\t\t//\n\t\t// Keep in mind that Firefox prefers $nbsp; before tag, not inside it:\n\t\t//\n\t\t// Foo <span>&nbsp;bar</span>  <-- bad.\n\t\t// Foo&nbsp;<span> bar</span>  <-- good.\n\t\t//\n\t\t// More here: https://github.com/ckeditor/ckeditor5-engine/issues/1747.\n\t\tif ( data.charAt( data.length - 1 ) == ' ' ) {\n\t\t\tconst nextNode = this._getTouchingInlineViewNode( node as ViewText, true );\n\t\t\tconst nextStartsWithSpace = nextNode && nextNode.is( '$textProxy' ) && nextNode.data.charAt( 0 ) == ' ';\n\n\t\t\tif ( data.charAt( data.length - 2 ) == ' ' || !nextNode || nextStartsWithSpace ) {\n\t\t\t\tdata = data.substr( 0, data.length - 1 ) + '\\u00A0';\n\t\t\t}\n\t\t}\n\n\t\t// 3. Create space+nbsp pairs.\n\t\treturn data.replace( / {2}/g, ' \\u00A0' );\n\t}\n\n\t/**\n\t * Checks whether given node ends with a space character after changing appropriate space characters to `&nbsp;`s.\n\t *\n\t * @param  node Node to check.\n\t * @returns `true` if given `node` ends with space, `false` otherwise.\n\t */\n\tprivate _nodeEndsWithSpace( node: ViewTextProxy ): boolean {\n\t\tif ( this._isPreFormatted( node ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst data = this._processDataFromViewText( node );\n\n\t\treturn data.charAt( data.length - 1 ) == ' ';\n\t}\n\n\t/**\n\t * Checks whether given text contains preformatted white space. This is the case if\n\t * * any of node ancestors has a name which is in `preElements` array, or\n\t * * the closest ancestor that has the `white-space` CSS property sets it to a value that preserves spaces\n\t *\n\t * @param node Node to check\n\t * @returns `true` if given node contains preformatted white space, `false` otherwise.\n\t */\n\tprivate _isPreFormatted( node: ViewText | ViewTextProxy ): boolean {\n\t\tif ( _hasViewParentOfType( node, this.preElements ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tfor ( const ancestor of node.getAncestors( { parentFirst: true } ) ) {\n\t\t\tif ( !ancestor.is( 'element' ) || !ancestor.hasStyle( 'white-space' ) || ancestor.getStyle( 'white-space' ) === 'inherit' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If the node contains the `white-space` property with a value that does not preserve spaces, it will take\n\t\t\t// precedence over any white-space settings its ancestors contain, so no further parent checking needs to\n\t\t\t// be done.\n\t\t\treturn [ 'pre', 'pre-wrap', 'break-spaces' ].includes( ancestor.getStyle( 'white-space' )! );\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Helper function. For given {@link module:engine/view/text~Text view text node}, it finds previous or next sibling\n\t * that is contained in the same container element. If there is no such sibling, `null` is returned.\n\t *\n\t * @param node Reference node.\n\t * @returns Touching text node, an inline object\n\t * or `null` if there is no next or previous touching text node.\n\t */\n\tprivate _getTouchingInlineViewNode( node: ViewText, getNext: boolean ): ViewElement | ViewTextProxy | null {\n\t\tconst treeWalker = new ViewTreeWalker( {\n\t\t\tstartPosition: getNext ? ViewPosition._createAfter( node ) : ViewPosition._createBefore( node ),\n\t\t\tdirection: getNext ? 'forward' : 'backward'\n\t\t} );\n\n\t\tfor ( const { item } of treeWalker ) {\n\t\t\t// Found a text node in the same container element.\n\t\t\tif ( item.is( '$textProxy' ) ) {\n\t\t\t\treturn item;\n\t\t\t}\n\t\t\t// Found a transparent element, skip it and continue inside it.\n\t\t\telse if ( item.is( 'element' ) && item.getCustomProperty( 'dataPipeline:transparentRendering' ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// <br> found – it works like a block boundary, so do not scan further.\n\t\t\telse if ( item.is( 'element', 'br' ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t// Found an inline object (for example an image).\n\t\t\telse if ( this._isInlineObjectElement( item ) ) {\n\t\t\t\treturn item;\n\t\t\t}\n\t\t\t// ViewContainerElement is found on a way to next ViewText node, so given `node` was first/last\n\t\t\t// text node in its container element.\n\t\t\telse if ( item.is( 'containerElement' ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns `true` if a DOM node belongs to {@link #blockElements}. `false` otherwise.\n\t */\n\tprivate _isBlockDomElement( node: DomNode ): boolean {\n\t\treturn this.isElement( node ) && this.blockElements.includes( node.tagName.toLowerCase() );\n\t}\n\n\t/**\n\t * Returns `true` if a view node belongs to {@link #blockElements}. `false` otherwise.\n\t */\n\tprivate _isBlockViewElement( node: ViewNode ): boolean {\n\t\treturn node.is( 'element' ) && this.blockElements.includes( node.name );\n\t}\n\n\t/**\n\t * Returns `true` if a DOM node belongs to {@link #inlineObjectElements}. `false` otherwise.\n\t */\n\tprivate _isInlineObjectElement( node: ViewNode | ViewTextProxy | ViewDocumentFragment ): node is ViewElement {\n\t\tif ( !node.is( 'element' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn node.name == 'br' ||\n\t\t\tthis.inlineObjectElements.includes( node.name ) ||\n\t\t\t!!this._inlineObjectElementMatcher.match( node );\n\t}\n\n\t/**\n\t * Creates view element basing on the node type.\n\t *\n\t * @param node DOM node to check.\n\t * @param options Conversion options. See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t */\n\tprivate _createViewElement( node: DomNode, options: { keepOriginalCase?: boolean } ): ViewElement {\n\t\tif ( isComment( node ) ) {\n\t\t\treturn new ViewUIElement( this.document, '$comment' );\n\t\t}\n\n\t\tconst viewName = options.keepOriginalCase ? ( node as DomElement ).tagName : ( node as DomElement ).tagName.toLowerCase();\n\n\t\treturn new ViewElement( this.document, viewName );\n\t}\n\n\t/**\n\t * Checks if view element's content should be treated as a raw data.\n\t *\n\t * @param viewElement View element to check.\n\t * @param options Conversion options. See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.\n\t */\n\tprivate _isViewElementWithRawContent( viewElement: ViewElement | ViewDocumentFragment, options: { withChildren?: boolean } ): boolean {\n\t\treturn options.withChildren !== false && viewElement.is( 'element' ) && !!this._rawContentElementMatcher.match( viewElement );\n\t}\n\n\t/**\n\t * Checks whether a given element name should be renamed in a current rendering mode.\n\t *\n\t * @param elementName The name of view element.\n\t */\n\tprivate _shouldRenameElement( elementName: string ): boolean {\n\t\tconst name = elementName.toLowerCase();\n\n\t\treturn this.renderingMode === 'editing' && this.unsafeElements.includes( name );\n\t}\n\n\t/**\n\t * Return a <span> element with a special attribute holding the name of the original element.\n\t * Optionally, copy all the attributes of the original element if that element is provided.\n\t *\n\t * @param elementName The name of view element.\n\t * @param originalDomElement The original DOM element to copy attributes and content from.\n\t */\n\tprivate _createReplacementDomElement( elementName: string, originalDomElement?: DomElement ): DomElement {\n\t\tconst newDomElement = this._domDocument.createElement( 'span' );\n\n\t\t// Mark the span replacing a script as hidden.\n\t\tnewDomElement.setAttribute( UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE, elementName );\n\n\t\tif ( originalDomElement ) {\n\t\t\twhile ( originalDomElement.firstChild ) {\n\t\t\t\tnewDomElement.appendChild( originalDomElement.firstChild );\n\t\t\t}\n\n\t\t\tfor ( const attributeName of originalDomElement.getAttributeNames() ) {\n\t\t\t\tnewDomElement.setAttribute( attributeName, originalDomElement.getAttribute( attributeName )! );\n\t\t\t}\n\t\t}\n\n\t\treturn newDomElement;\n\t}\n}\n\n/**\n * Helper function.\n * Used to check if given native `Element` or `Text` node has parent with tag name from `types` array.\n *\n * @returns`true` if such parent exists or `false` if it does not.\n */\nfunction _hasViewParentOfType( node: ViewNode | ViewTextProxy, types: ReadonlyArray<string> ) {\n\treturn node.getAncestors().some( parent => parent.is( 'element' ) && types.includes( parent.name ) );\n}\n\n/**\n * A helper that executes given callback for each DOM node's ancestor, starting from the given node\n * and ending in document#documentElement.\n *\n * @param callback A callback to be executed for each ancestor.\n */\nfunction forEachDomElementAncestor( element: DomElement, callback: ( node: DomElement ) => void ) {\n\tlet node: DomElement | null = element;\n\n\twhile ( node ) {\n\t\tcallback( node );\n\t\tnode = node.parentElement;\n\t}\n}\n\n/**\n * Checks if given node is a nbsp block filler.\n *\n * A &nbsp; is a block filler only if it is a single child of a block element.\n *\n * @param domNode DOM node.\n */\nfunction isNbspBlockFiller( domNode: DomNode, blockElements: ReadonlyArray<string> ): boolean {\n\tconst isNBSP = domNode.isEqualNode( NBSP_FILLER_REF );\n\n\treturn isNBSP && hasBlockParent( domNode, blockElements ) && ( domNode as DomElement ).parentNode!.childNodes.length === 1;\n}\n\n/**\n * Checks if domNode has block parent.\n *\n * @param domNode DOM node.\n */\nfunction hasBlockParent( domNode: DomNode, blockElements: ReadonlyArray<string> ): boolean {\n\tconst parent = domNode.parentNode;\n\n\treturn !!parent && !!( parent as DomElement ).tagName && blockElements.includes( ( parent as DomElement ).tagName.toLowerCase() );\n}\n\n/**\n * Log to console the information about element that was replaced.\n * Check UNSAFE_ELEMENTS for all recognized unsafe elements.\n *\n * @param elementName The name of the view element.\n */\nfunction _logUnsafeElement( elementName: string ): void {\n\tif ( elementName === 'script' ) {\n\t\tlogWarning( 'domconverter-unsafe-script-element-detected' );\n\t}\n\n\tif ( elementName === 'style' ) {\n\t\tlogWarning( 'domconverter-unsafe-style-element-detected' );\n\t}\n}\n\n/**\n * In certain cases, Firefox mysteriously assigns so called \"restricted objects\" to native DOM Range properties.\n * Any attempt at accessing restricted object's properties causes errors.\n * See: https://github.com/ckeditor/ckeditor5/issues/9635.\n */\nfunction isGeckoRestrictedDomSelection( domSelection: DomSelection ): boolean {\n\tif ( !env.isGecko ) {\n\t\treturn false;\n\t}\n\n\tif ( !domSelection.rangeCount ) {\n\t\treturn false;\n\t}\n\n\tconst container = domSelection.getRangeAt( 0 ).startContainer;\n\n\ttry {\n\t\tObject.prototype.toString.call( container );\n\t} catch ( error ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Enum representing the type of the block filler.\n *\n * Possible values:\n *\n * * `br` &ndash; For the `<br data-cke-filler=\"true\">` block filler used in the editing view.\n * * `nbsp` &ndash; For the `&nbsp;` block fillers used in the data.\n * * `markedNbsp` &ndash; For the `&nbsp;` block fillers wrapped in `<span>` elements: `<span data-cke-filler=\"true\">&nbsp;</span>`\n * used in the data.\n */\ntype BlockFillerMode = 'br' | 'nbsp' | 'markedNbsp';\n\n/**\n * While rendering the editor content, the {@link module:engine/view/domconverter~DomConverter} detected a `<script>` element that may\n * disrupt the editing experience. To avoid this, the `<script>` element was replaced with `<span data-ck-unsafe-element=\"script\"></span>`.\n *\n * @error domconverter-unsafe-script-element-detected\n */\n\n/**\n * While rendering the editor content, the {@link module:engine/view/domconverter~DomConverter} detected a `<style>` element that may affect\n * the editing experience. To avoid this, the `<style>` element was replaced with `<span data-ck-unsafe-element=\"style\"></span>`.\n *\n * @error domconverter-unsafe-style-element-detected\n */\n\n/**\n * The {@link module:engine/view/domconverter~DomConverter} detected an interactive attribute in the\n * {@glink framework/architecture/editing-engine#editing-pipeline editing pipeline}. For the best\n * editing experience, the attribute was renamed to `data-ck-unsafe-attribute-[original attribute name]`.\n *\n * If you are the author of the plugin that generated this attribute and you want it to be preserved\n * in the editing pipeline, you can configure this when creating the element\n * using {@link module:engine/view/downcastwriter~DowncastWriter} during the\n * {@glink framework/architecture/editing-engine#conversion model–view conversion}. Methods such as\n * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement},\n * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement}, or\n * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement}\n * accept an option that will disable filtering of specific attributes:\n *\n * ```ts\n * const paragraph = writer.createContainerElement( 'p',\n * \t{\n * \t\tclass: 'clickable-paragraph',\n * \t\tonclick: 'alert( \"Paragraph clicked!\" )'\n * \t},\n * \t{\n * \t\t// Make sure the \"onclick\" attribute will pass through.\n * \t\trenderUnsafeAttributes: [ 'onclick' ]\n * \t}\n * );\n * ```\n *\n * @error domconverter-unsafe-attribute-detected\n * @param domElement The DOM element the attribute was set on.\n * @param key The original name of the attribute\n * @param value The value of the original attribute\n */\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/observer\n */\n\nimport { DomEmitterMixin } from '@ckeditor/ckeditor5-utils';\n\nimport type Document from '../document.js';\nimport type View from '../view.js';\n\n/**\n * Abstract base observer class. Observers are classes which listen to DOM events, do the preliminary\n * processing and fire events on the {@link module:engine/view/document~Document} objects.\n * Observers can also add features to the view, for instance by updating its status or marking elements\n * which need a refresh on DOM events.\n */\nexport default abstract class Observer extends /* #__PURE__ */ DomEmitterMixin() {\n\t/**\n\t * An instance of the view controller.\n\t */\n\tpublic readonly view: View;\n\n\t/**\n\t * A reference to the {@link module:engine/view/document~Document} object.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * The state of the observer. If it is disabled, no events will be fired.\n\t */\n\tprivate _isEnabled: boolean = false;\n\n\t/**\n\t * Creates an instance of the observer.\n\t */\n\tconstructor( view: View ) {\n\t\tsuper();\n\n\t\tthis.view = view;\n\t\tthis.document = view.document;\n\t}\n\n\t/**\n\t * The state of the observer. If it is disabled, no events will be fired.\n\t */\n\tpublic get isEnabled(): boolean {\n\t\treturn this._isEnabled;\n\t}\n\n\t/**\n\t * Enables the observer. This method is called when the observer is registered to the\n\t * {@link module:engine/view/view~View} and after {@link module:engine/view/view~View#forceRender rendering}\n\t * (all observers are {@link #disable disabled} before rendering).\n\t *\n\t * A typical use case for disabling observers is that mutation observers need to be disabled for the rendering.\n\t * However, a child class may not need to be disabled, so it can implement an empty method.\n\t *\n\t * @see module:engine/view/observer/observer~Observer#disable\n\t */\n\tpublic enable(): void {\n\t\tthis._isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the observer. This method is called before\n\t * {@link module:engine/view/view~View#forceRender rendering} to prevent firing events during rendering.\n\t *\n\t * @see module:engine/view/observer/observer~Observer#enable\n\t */\n\tpublic disable(): void {\n\t\tthis._isEnabled = false;\n\t}\n\n\t/**\n\t * Disables and destroys the observer, among others removes event listeners created by the observer.\n\t */\n\tpublic destroy(): void {\n\t\tthis.disable();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Checks whether a given DOM event should be ignored (should not be turned into a synthetic view document event).\n\t *\n\t * Currently, an event will be ignored only if its target or any of its ancestors has the `data-cke-ignore-events` attribute.\n\t * This attribute can be used inside the structures generated by\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `DowncastWriter#createUIElement()`} to ignore events\n\t * fired within a UI that should be excluded from CKEditor 5's realms.\n\t *\n\t * @param domTarget The DOM event target to check (usually an element, sometimes a text node and\n\t * potentially sometimes a document, too).\n\t * @returns Whether this event should be ignored by the observer.\n\t */\n\tpublic checkShouldIgnoreEventFromTarget( domTarget: Node | null ): boolean {\n\t\tif ( domTarget && domTarget.nodeType === 3 ) {\n\t\t\tdomTarget = domTarget.parentNode as any;\n\t\t}\n\n\t\tif ( !domTarget || domTarget.nodeType !== 1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn ( domTarget as any ).matches( '[data-cke-ignore-events], [data-cke-ignore-events] *' );\n\t}\n\n\t/**\n\t * Starts observing given DOM element.\n\t *\n\t * @param domElement DOM element to observe.\n\t * @param name The name of the related root element.\n\t */\n\tpublic abstract observe( domElement: HTMLElement, name: string ): void;\n\n\t/**\n\t * Stops observing given DOM element.\n\t */\n\tpublic abstract stopObserving( domElement: HTMLElement ): void;\n}\n\n/**\n * The constructor of {@link ~Observer} subclass.\n */\nexport type ObserverConstructor = new ( view: View ) => Observer;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/domeventdata\n */\n\nimport { extend } from 'lodash-es';\n\nimport type Document from '../document.js';\nimport type Element from '../element.js';\nimport type View from '../view.js';\n\n/**\n * Information about a DOM event in context of the {@link module:engine/view/document~Document}.\n * It wraps the native event, which usually should not be used as the wrapper contains\n * additional data (like key code for keyboard events).\n *\n * @typeParam TEvent The type of DOM Event that this class represents.\n */\nexport default class DomEventData<TEvent extends Event = Event> {\n\t/**\n\t * Instance of the view controller.\n\t */\n\tpublic readonly view: View;\n\n\t/**\n\t * The instance of the document.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * The DOM event.\n\t */\n\tpublic readonly domEvent: TEvent;\n\n\t/**\n\t * The DOM target.\n\t */\n\tpublic readonly domTarget: HTMLElement;\n\n\t/**\n\t * @param view The instance of the view controller.\n\t * @param domEvent The DOM event.\n\t * @param additionalData Additional properties that the instance should contain.\n\t */\n\tconstructor( view: View, domEvent: TEvent, additionalData?: object ) {\n\t\tthis.view = view;\n\t\tthis.document = view.document;\n\t\tthis.domEvent = domEvent;\n\t\tthis.domTarget = domEvent.target as any;\n\n\t\textend( this, additionalData );\n\t}\n\n\t/**\n\t * The tree view element representing the target.\n\t */\n\tpublic get target(): Element {\n\t\treturn this.view.domConverter.mapDomToView( this.domTarget ) as Element;\n\t}\n\n\t/**\n\t * Prevents the native's event default action.\n\t */\n\tpublic preventDefault(): void {\n\t\tthis.domEvent.preventDefault();\n\t}\n\n\t/**\n\t * Stops native event propagation.\n\t */\n\tpublic stopPropagation(): void {\n\t\tthis.domEvent.stopPropagation();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/domeventobserver\n */\n\nimport Observer from './observer.js';\nimport DomEventData from './domeventdata.js';\n\nimport type { EventInfo } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Base class for DOM event observers. This class handles\n * {@link module:engine/view/observer/observer~Observer#observe adding} listeners to DOM elements,\n * {@link module:engine/view/observer/observer~Observer#disable disabling} and\n * {@link module:engine/view/observer/observer~Observer#enable re-enabling} events.\n * Child class needs to define\n * {@link module:engine/view/observer/domeventobserver~DomEventObserver#domEventType DOM event type} and\n * {@link module:engine/view/observer/domeventobserver~DomEventObserver#onDomEvent callback}.\n *\n * For instance:\n *\n * ```ts\n * class ClickObserver extends DomEventObserver<'click'> {\n * \t// It can also be defined as a normal property in the constructor.\n * \tget domEventType(): 'click' {\n * \t\treturn 'click';\n * \t}\n *\n * \tonDomEvent( domEvent: MouseEvent ): void {\n * \t\tthis.fire( 'click', domEvent );\n * \t}\n * }\n * ```\n *\n * @typeParam EventType DOM Event type name or an union of those.\n * @typeParam AdditionalData Additional data passed along with the event.\n */\n\nexport default abstract class DomEventObserver<\n\tEventType extends keyof HTMLElementEventMap,\n\tAdditionalData extends object = object\n> extends Observer {\n\t/**\n\t * Type of the DOM event the observer should listen to. Array of types can be defined\n\t * if the observer should listen to multiple DOM events.\n\t */\n\tpublic abstract get domEventType(): EventType | ReadonlyArray<EventType>;\n\n\t/**\n\t * If set to `true` DOM events will be listened on the capturing phase.\n\t * Default value is `false`.\n\t */\n\tpublic useCapture: boolean = false;\n\n\t/**\n\t * If set to `true`, indicates that the function specified by listener will never call `preventDefault()`.\n\t * Default value is `false`.\n\t */\n\tpublic usePassive: boolean = false;\n\n\t/**\n\t * Callback which should be called when the DOM event occurred. Note that the callback will not be called if\n\t * observer {@link #isEnabled is not enabled}.\n\t *\n\t * @see #domEventType\n\t */\n\tpublic abstract onDomEvent( event: HTMLElementEventMap[ EventType ] ): void;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override observe( domElement: HTMLElement ): void {\n\t\tconst types = typeof this.domEventType == 'string' ? [ this.domEventType ] : this.domEventType;\n\n\t\ttypes.forEach( type => {\n\t\t\tthis.listenTo( domElement, type, ( eventInfo, domEvent ) => {\n\t\t\t\tif ( this.isEnabled && !this.checkShouldIgnoreEventFromTarget( domEvent.target as any ) ) {\n\t\t\t\t\tthis.onDomEvent( domEvent );\n\t\t\t\t}\n\t\t\t}, { useCapture: this.useCapture, usePassive: this.usePassive } );\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override stopObserving( domElement: HTMLElement ): void {\n\t\tthis.stopListening( domElement );\n\t}\n\n\t/**\n\t * Calls `Document#fire()` if observer {@link #isEnabled is enabled}.\n\t *\n\t * @see module:utils/emittermixin~Emitter#fire\n\t * @param eventType The event type (name).\n\t * @param domEvent The DOM event.\n\t * @param additionalData The additional data which should extend the\n\t * {@link module:engine/view/observer/domeventdata~DomEventData event data} object.\n\t */\n\tpublic override fire( eventType: string | EventInfo, domEvent: Event, additionalData?: AdditionalData ): void {\n\t\tif ( this.isEnabled ) {\n\t\t\tthis.document.fire( eventType, new DomEventData( this.view, domEvent, additionalData ) );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/keyobserver\n */\n\nimport DomEventObserver from './domeventobserver.js';\nimport type DomEventData from './domeventdata.js';\nimport { getCode, type KeystrokeInfo } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Observer for events connected with pressing keyboard keys.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */\nexport default class KeyObserver extends DomEventObserver<'keydown' | 'keyup', KeystrokeInfo & { keystroke: number }> {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly domEventType = [ 'keydown', 'keyup' ] as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvt: KeyboardEvent ): void {\n\t\tconst data = {\n\t\t\tkeyCode: domEvt.keyCode,\n\n\t\t\taltKey: domEvt.altKey,\n\t\t\tctrlKey: domEvt.ctrlKey,\n\t\t\tshiftKey: domEvt.shiftKey,\n\t\t\tmetaKey: domEvt.metaKey,\n\n\t\t\tget keystroke() {\n\t\t\t\treturn getCode( this );\n\t\t\t}\n\t\t};\n\n\t\tthis.fire( domEvt.type, domEvt, data );\n\t}\n}\n\n/**\n * Fired when a key has been pressed.\n *\n * Introduced by {@link module:engine/view/observer/keyobserver~KeyObserver}.\n *\n * Note that because {@link module:engine/view/observer/keyobserver~KeyObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/keyobserver~KeyObserver\n * @eventName module:engine/view/document~Document#keydown\n */\nexport type ViewDocumentKeyDownEvent = {\n\tname: 'keydown';\n\targs: [ data: KeyEventData ];\n};\n\n/**\n * Fired when a key has been released.\n *\n * Introduced by {@link module:engine/view/observer/keyobserver~KeyObserver}.\n *\n * Note that because {@link module:engine/view/observer/keyobserver~KeyObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/keyobserver~KeyObserver\n * @eventName module:engine/view/document~Document#keyup\n */\nexport type ViewDocumentKeyUpEvent = {\n\tname: 'keyup';\n\targs: [ data: KeyEventData ];\n};\n\n/**\n * The value of both events - {@link ~ViewDocumentKeyDownEvent} and {@link ~ViewDocumentKeyUpEvent}.\n */\nexport interface KeyEventData extends DomEventData<KeyboardEvent>, KeystrokeInfo {\n\n\t/**\n\t * Code of the whole keystroke. See {@link module:utils/keyboard~getCode}.\n\t */\n\tkeystroke: number;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/fakeselectionobserver\n */\n\nimport Observer from './observer.js';\nimport type { ViewDocumentArrowKeyEvent } from './arrowkeysobserver.js';\nimport ViewSelection from '../selection.js';\nimport type View from '../view.js';\nimport type {\n\tViewDocumentSelectionChangeEvent,\n\tViewDocumentSelectionChangeDoneEvent,\n\tViewDocumentSelectionEventData\n} from './selectionobserver.js';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils';\nimport { debounce, type DebouncedFunc } from 'lodash-es';\n\n/**\n * Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens\n * on {@link module:engine/view/document~Document#event:keydown keydown} events and handles moving fake view selection to the correct place\n * if arrow keys are pressed.\n * Fires {@link module:engine/view/document~Document#event:selectionChange selectionChange event} simulating natural behaviour of\n * {@link module:engine/view/observer/selectionobserver~SelectionObserver SelectionObserver}.\n */\nexport default class FakeSelectionObserver extends Observer {\n\t/**\n\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t */\n\tprivate readonly _fireSelectionChangeDoneDebounced: DebouncedFunc<( data: ViewDocumentSelectionEventData ) => void>;\n\n\t/**\n\t * Creates new FakeSelectionObserver instance.\n\t */\n\tconstructor( view: View ) {\n\t\tsuper( view );\n\n\t\tthis._fireSelectionChangeDoneDebounced = debounce( data => {\n\t\t\tthis.document.fire<ViewDocumentSelectionChangeDoneEvent>( 'selectionChangeDone', data );\n\t\t}, 200 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override observe(): void {\n\t\tconst document = this.document;\n\n\t\tdocument.on<ViewDocumentArrowKeyEvent>( 'arrowKey', ( eventInfo, data ) => {\n\t\t\tconst selection = document.selection;\n\n\t\t\tif ( selection.isFake && this.isEnabled ) {\n\t\t\t\t// Prevents default key down handling - no selection change will occur.\n\t\t\t\tdata.preventDefault();\n\t\t\t}\n\t\t}, { context: '$capture' } );\n\n\t\tdocument.on<ViewDocumentArrowKeyEvent>( 'arrowKey', ( eventInfo, data ) => {\n\t\t\tconst selection = document.selection;\n\n\t\t\tif ( selection.isFake && this.isEnabled ) {\n\t\t\t\tthis._handleSelectionMove( data.keyCode );\n\t\t\t}\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override stopObserving(): void {}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t}\n\n\t/**\n\t * Handles collapsing view selection according to given key code. If left or up key is provided - new selection will be\n\t * collapsed to left. If right or down key is pressed - new selection will be collapsed to right.\n\t *\n\t * This method fires {@link module:engine/view/document~Document#event:selectionChange} and\n\t * {@link module:engine/view/document~Document#event:selectionChangeDone} events imitating behaviour of\n\t * {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n\t */\n\tprivate _handleSelectionMove( keyCode: number ): void {\n\t\tconst selection = this.document.selection;\n\t\tconst newSelection = new ViewSelection( selection.getRanges(), { backward: selection.isBackward, fake: false } );\n\n\t\t// Left or up arrow pressed - move selection to start.\n\t\tif ( keyCode == keyCodes.arrowleft || keyCode == keyCodes.arrowup ) {\n\t\t\tnewSelection.setTo( newSelection.getFirstPosition() );\n\t\t}\n\n\t\t// Right or down arrow pressed - move selection to end.\n\t\tif ( keyCode == keyCodes.arrowright || keyCode == keyCodes.arrowdown ) {\n\t\t\tnewSelection.setTo( newSelection.getLastPosition() );\n\t\t}\n\n\t\tconst data = {\n\t\t\toldSelection: selection,\n\t\t\tnewSelection,\n\t\t\tdomSelection: null\n\t\t};\n\n\t\t// Fire dummy selection change event.\n\t\tthis.document.fire<ViewDocumentSelectionChangeEvent>( 'selectionChange', data );\n\n\t\t// Call` #_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n\t\t// This function is debounced what means that `selectionChangeDone` event will be fired only when\n\t\t// defined int the function time will elapse since the last time the function was called.\n\t\t// So `selectionChangeDone` will be fired when selection will stop changing.\n\t\tthis._fireSelectionChangeDoneDebounced( data );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/mutationobserver\n */\n\n/* globals window */\n\nimport Observer from './observer.js';\nimport { startsWithFiller } from '../filler.js';\nimport { isEqualWith } from 'lodash-es';\n\nimport type DomConverter from '../domconverter.js';\nimport type View from '../view.js';\nimport type ViewElement from '../element.js';\nimport type ViewNode from '../node.js';\nimport type ViewText from '../text.js';\nimport type { ChangeType } from '../document.js';\n\n// @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );\n\n/**\n * Mutation observer's role is to watch for any DOM changes inside the editor that weren't\n * done by the editor's {@link module:engine/view/renderer~Renderer} itself and reverting these changes.\n *\n * It does this by observing all mutations in the DOM, marking related view elements as changed and calling\n * {@link module:engine/view/renderer~Renderer#render}. Because all mutated nodes are marked as\n * \"to be rendered\" and the {@link module:engine/view/renderer~Renderer#render `render()`} method is called,\n * all changes are reverted in the DOM (the DOM is synced with the editor's view structure).\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */\nexport default class MutationObserver extends Observer {\n\t/**\n\t * Reference to the {@link module:engine/view/view~View#domConverter}.\n\t */\n\tpublic readonly domConverter: DomConverter;\n\n\t/**\n\t * Native mutation observer config.\n\t */\n\tprivate readonly _config: MutationObserverInit;\n\n\t/**\n\t * Observed DOM elements.\n\t */\n\tprivate readonly _domElements: Set<HTMLElement>;\n\n\t/**\n\t * Native mutation observer.\n\t */\n\tprivate _mutationObserver: InstanceType<typeof window.MutationObserver>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: View ) {\n\t\tsuper( view );\n\n\t\tthis._config = {\n\t\t\tchildList: true,\n\t\t\tcharacterData: true,\n\t\t\tsubtree: true\n\t\t};\n\n\t\tthis.domConverter = view.domConverter;\n\n\t\tthis._domElements = new Set();\n\t\tthis._mutationObserver = new window.MutationObserver( this._onMutations.bind( this ) );\n\t}\n\n\t/**\n\t * Synchronously handles mutations and empties the queue.\n\t */\n\tpublic flush(): void {\n\t\tthis._onMutations( this._mutationObserver.takeRecords() );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic observe( domElement: HTMLElement ): void {\n\t\tthis._domElements.add( domElement );\n\n\t\tif ( this.isEnabled ) {\n\t\t\tthis._mutationObserver.observe( domElement, this._config );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override stopObserving( domElement: HTMLElement ): void {\n\t\tthis._domElements.delete( domElement );\n\n\t\tif ( this.isEnabled ) {\n\t\t\t// Unfortunately, it is not possible to stop observing particular DOM element.\n\t\t\t// In order to stop observing one of multiple DOM elements, we need to re-connect the mutation observer.\n\t\t\tthis._mutationObserver.disconnect();\n\n\t\t\tfor ( const domElement of this._domElements ) {\n\t\t\t\tthis._mutationObserver.observe( domElement, this._config );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override enable(): void {\n\t\tsuper.enable();\n\n\t\tfor ( const domElement of this._domElements ) {\n\t\t\tthis._mutationObserver.observe( domElement, this._config );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override disable(): void {\n\t\tsuper.disable();\n\n\t\tthis._mutationObserver.disconnect();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis._mutationObserver.disconnect();\n\t}\n\n\t/**\n\t * Handles mutations. Mark view elements to sync and call render.\n\t *\n\t * @param domMutations Array of native mutations.\n\t */\n\tprivate _onMutations( domMutations: Array<MutationRecord> ) {\n\t\t// As a result of this.flush() we can have an empty collection.\n\t\tif ( domMutations.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domConverter = this.domConverter;\n\n\t\t// Use map and set for deduplication.\n\t\tconst mutatedTextNodes = new Set<ViewText>();\n\t\tconst elementsWithMutatedChildren = new Set<ViewElement>();\n\n\t\t// Handle `childList` mutations first, so we will be able to check if the `characterData` mutation is in the\n\t\t// element with changed structure anyway.\n\t\tfor ( const mutation of domMutations ) {\n\t\t\tconst element = domConverter.mapDomToView( mutation.target as HTMLElement );\n\n\t\t\tif ( !element ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Do not collect mutations from UIElements and RawElements.\n\t\t\tif ( element.is( 'uiElement' ) || element.is( 'rawElement' ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( mutation.type === 'childList' && !this._isBogusBrMutation( mutation ) ) {\n\t\t\t\telementsWithMutatedChildren.add( element as ViewElement );\n\t\t\t}\n\t\t}\n\n\t\t// Handle `characterData` mutations later, when we have the full list of nodes which changed structure.\n\t\tfor ( const mutation of domMutations ) {\n\t\t\tconst element = domConverter.mapDomToView( mutation.target as HTMLElement );\n\n\t\t\t// Do not collect mutations from UIElements and RawElements.\n\t\t\tif ( element && ( element.is( 'uiElement' ) || element.is( 'rawElement' ) ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( mutation.type === 'characterData' ) {\n\t\t\t\tconst text = domConverter.findCorrespondingViewText( mutation.target as Text ) as ViewText;\n\n\t\t\t\tif ( text && !elementsWithMutatedChildren.has( text.parent as ViewElement ) ) {\n\t\t\t\t\tmutatedTextNodes.add( text );\n\t\t\t\t}\n\t\t\t\t// When we added first letter to the text node which had only inline filler, for the DOM it is mutation\n\t\t\t\t// on text, but for the view, where filler text node did not exist, new text node was created, so we\n\t\t\t\t// need to handle it as a 'children' mutation instead of 'text'.\n\t\t\t\telse if ( !text && startsWithFiller( mutation.target ) ) {\n\t\t\t\t\telementsWithMutatedChildren.add(\n\t\t\t\t\t\tdomConverter.mapDomToView( mutation.target.parentNode as HTMLElement ) as ViewElement\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Now we build the list of mutations to mark elements. We did not do it earlier to avoid marking the\n\t\t// same node multiple times in case of duplication.\n\n\t\tconst mutations: Array<MutationData> = [];\n\n\t\tfor ( const textNode of mutatedTextNodes ) {\n\t\t\tmutations.push( { type: 'text', node: textNode } );\n\t\t}\n\n\t\tfor ( const viewElement of elementsWithMutatedChildren ) {\n\t\t\tconst domElement = domConverter.mapViewToDom( viewElement )!;\n\t\t\tconst viewChildren = Array.from( viewElement.getChildren() );\n\t\t\tconst newViewChildren = Array.from( domConverter.domChildrenToView( domElement, { withChildren: false } ) );\n\n\t\t\t// It may happen that as a result of many changes (sth was inserted and then removed),\n\t\t\t// both elements haven't really changed. #1031\n\t\t\tif ( !isEqualWith( viewChildren, newViewChildren, sameNodes ) ) {\n\t\t\t\tmutations.push( { type: 'children', node: viewElement } );\n\t\t\t}\n\t\t}\n\n\t\t// In case only non-relevant mutations were recorded it skips the event and force render (#5600).\n\t\tif ( mutations.length ) {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \t_debouncedLine();\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[MutationObserver]%c Mutations detected',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', 'font-weight: bold'\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\tthis.document.fire<ViewDocumentMutationsEvent>( 'mutations', { mutations } );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t}\n\t}\n\n\t/**\n\t * Checks if mutation was generated by the browser inserting bogus br on the end of the block element.\n\t * Such mutations are generated while pressing space or performing native spellchecker correction\n\t * on the end of the block element in Firefox browser.\n\t *\n\t * @param mutation Native mutation object.\n\t */\n\tprivate _isBogusBrMutation( mutation: MutationRecord ) {\n\t\tlet addedNode = null;\n\n\t\t// Check if mutation added only one node on the end of its parent.\n\t\tif ( mutation.nextSibling === null && mutation.removedNodes.length === 0 && mutation.addedNodes.length == 1 ) {\n\t\t\taddedNode = this.domConverter.domToView( mutation.addedNodes[ 0 ], {\n\t\t\t\twithChildren: false\n\t\t\t} );\n\t\t}\n\n\t\treturn addedNode && addedNode.is( 'element', 'br' );\n\t}\n}\n\nfunction sameNodes( child1: ViewNode, child2: ViewNode ) {\n\t// First level of comparison (array of children vs array of children) – use the Lodash's default behavior.\n\tif ( Array.isArray( child1 ) ) {\n\t\treturn;\n\t}\n\n\t// Elements.\n\tif ( child1 === child2 ) {\n\t\treturn true;\n\t}\n\t// Texts.\n\telse if ( child1.is( '$text' ) && child2.is( '$text' ) ) {\n\t\treturn child1.data === child2.data;\n\t}\n\n\t// Not matching types.\n\treturn false;\n}\n\n/**\n * Event fired on DOM mutations detected.\n *\n * This event is introduced by {@link module:engine/view/observer/mutationobserver~MutationObserver} and available\n * by default in all editor instances (attached by {@link module:engine/view/view~View}).\n *\n * @eventName module:engine/view/document~Document#mutations\n * @param data Event data containing detailed information about the event.\n */\nexport type ViewDocumentMutationsEvent = {\n\tname: 'mutations';\n\targs: [ data: MutationsEventData ];\n};\n\n/**\n * The value of {@link ~ViewDocumentMutationsEvent}.\n */\nexport type MutationsEventData = {\n\tmutations: Array<MutationData>;\n};\n\n/**\n * A single entry in {@link ~MutationsEventData} mutations array.\n */\nexport type MutationData = {\n\n\t/**\n\t * Type of mutation detected.\n\t */\n\ttype: ChangeType;\n\n\t/**\n\t * The view node related to the detected mutation.\n\t */\n\tnode: ViewNode;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/focusobserver\n */\n\n/* globals setTimeout, clearTimeout */\n\nimport DomEventObserver from './domeventobserver.js';\nimport type DomEventData from './domeventdata.js';\nimport type View from '../view.js';\nimport type { ViewDocumentInputEvent } from './inputobserver.js';\n\n/**\n * {@link module:engine/view/document~Document#event:focus Focus}\n * and {@link module:engine/view/document~Document#event:blur blur} events observer.\n * Focus observer handle also {@link module:engine/view/rooteditableelement~RootEditableElement#isFocused isFocused} property of the\n * {@link module:engine/view/rooteditableelement~RootEditableElement root elements}.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */\nexport default class FocusObserver extends DomEventObserver<'focus' | 'blur'> {\n\t/**\n\t * Identifier of the timeout currently used by focus listener to delay rendering execution.\n\t */\n\tprivate _renderTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t/**\n\t * Set to `true` if the document is in the process of setting the focus.\n\t *\n\t * The flag is used to indicate that setting the focus is in progress.\n\t */\n\tprivate _isFocusChanging: boolean = false;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly domEventType = [ 'focus', 'blur' ] as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: View ) {\n\t\tsuper( view );\n\n\t\tthis.useCapture = true;\n\t\tconst document = this.document;\n\n\t\tdocument.on<ViewDocumentFocusEvent>( 'focus', () => this._handleFocus() );\n\t\tdocument.on<ViewDocumentBlurEvent>( 'blur', ( evt, data ) => this._handleBlur( data ) );\n\n\t\t// Focus the editor in cases where browser dispatches `beforeinput` event to a not-focused editable element.\n\t\t// This is flushed by the beforeinput listener in the `InsertTextObserver`.\n\t\t// Note that focus is set only if the document is not focused yet.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/14702.\n\t\tdocument.on<ViewDocumentInputEvent>( 'beforeinput', () => {\n\t\t\tif ( !document.isFocused ) {\n\t\t\t\tthis._handleFocus();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Finishes setting the document focus state.\n\t */\n\tpublic flush(): void {\n\t\tif ( this._isFocusChanging ) {\n\t\t\tthis._isFocusChanging = false;\n\t\t\tthis.document.isFocused = true;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvent: FocusEvent ): void {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis._clearTimeout();\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * The `focus` event handler.\n\t */\n\tprivate _handleFocus(): void {\n\t\tthis._clearTimeout();\n\t\tthis._isFocusChanging = true;\n\n\t\t// Unfortunately native `selectionchange` event is fired asynchronously.\n\t\t// We need to wait until `SelectionObserver` handle the event and then render. Otherwise rendering will\n\t\t// overwrite new DOM selection with selection from the view.\n\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/795 for more details.\n\t\t// Long timeout is needed to solve #676 and https://github.com/ckeditor/ckeditor5-engine/issues/1157 issues.\n\t\t//\n\t\t// Using `view.change()` instead of `view.forceRender()` to prevent double rendering\n\t\t// in a situation where `selectionchange` already caused selection change.\n\t\tthis._renderTimeoutId = setTimeout( () => {\n\t\t\tthis._renderTimeoutId = null;\n\t\t\tthis.flush();\n\t\t\tthis.view.change( () => {} );\n\t\t}, 50 );\n\t}\n\n\t/**\n\t * The `blur` event handler.\n\t */\n\tprivate _handleBlur( data: DomEventData<FocusEvent> ): void {\n\t\tconst selectedEditable = this.document.selection.editableElement;\n\n\t\tif ( selectedEditable === null || selectedEditable === data.target ) {\n\t\t\tthis.document.isFocused = false;\n\t\t\tthis._isFocusChanging = false;\n\n\t\t\t// Re-render the document to update view elements\n\t\t\t// (changing document.isFocused already marked view as changed since last rendering).\n\t\t\tthis.view.change( () => {} );\n\t\t}\n\t}\n\n\t/**\n\t * Clears timeout.\n\t */\n\tprivate _clearTimeout(): void {\n\t\tif ( this._renderTimeoutId ) {\n\t\t\tclearTimeout( this._renderTimeoutId );\n\t\t\tthis._renderTimeoutId = null;\n\t\t}\n\t}\n}\n\n/**\n * Fired when one of the editables gets focus.\n *\n * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.\n *\n * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/focusobserver~FocusObserver\n * @eventName module:engine/view/document~Document#focus\n * @param data Event data.\n */\nexport type ViewDocumentFocusEvent = {\n\tname: 'focus';\n\targs: [ data: DomEventData<FocusEvent> ];\n};\n\n/**\n * Fired when one of the editables loses focus.\n *\n * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.\n *\n * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/focusobserver~FocusObserver\n * @eventName module:engine/view/document~Document#blur\n * @param data Event data.\n */\nexport type ViewDocumentBlurEvent = {\n\tname: 'blur';\n\targs: [ data: DomEventData<FocusEvent> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/selectionobserver\n */\n\n/* global setInterval, clearInterval */\n\nimport Observer from './observer.js';\nimport MutationObserver from './mutationobserver.js';\nimport FocusObserver from './focusobserver.js';\nimport { env } from '@ckeditor/ckeditor5-utils';\nimport { debounce, type DebouncedFunc } from 'lodash-es';\n\nimport type View from '../view.js';\nimport type DocumentSelection from '../documentselection.js';\nimport type DomConverter from '../domconverter.js';\nimport type Selection from '../selection.js';\nimport type { ViewDocumentCompositionStartEvent } from './compositionobserver.js';\n\n// @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );\n\ntype DomSelection = globalThis.Selection;\n\n/**\n * Selection observer class observes selection changes in the document. If a selection changes on the document this\n * observer checks if the DOM selection is different from the {@link module:engine/view/document~Document#selection view selection}.\n * The selection observer fires {@link module:engine/view/document~Document#event:selectionChange} event only if\n * a selection change was the only change in the document and the DOM selection is different from the view selection.\n *\n * This observer also manages the {@link module:engine/view/document~Document#isSelecting} property of the view document.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */\nexport default class SelectionObserver extends Observer {\n\t/**\n\t * Instance of the mutation observer. Selection observer calls\n\t * {@link module:engine/view/observer/mutationobserver~MutationObserver#flush} to ensure that the mutations will be handled\n\t * before the {@link module:engine/view/document~Document#event:selectionChange} event is fired.\n\t */\n\tpublic readonly mutationObserver: MutationObserver;\n\n\t/**\n\t * Instance of the focus observer. Focus observer calls\n\t * {@link module:engine/view/observer/focusobserver~FocusObserver#flush} to mark the latest focus change as complete.\n\t */\n\tpublic readonly focusObserver: FocusObserver;\n\n\t/**\n\t * Reference to the view {@link module:engine/view/documentselection~DocumentSelection} object used to compare\n\t * new selection with it.\n\t */\n\tpublic readonly selection: DocumentSelection;\n\n\t/**\n\t * Reference to the {@link module:engine/view/view~View#domConverter}.\n\t */\n\tpublic readonly domConverter: DomConverter;\n\n\t/**\n\t * A set of documents which have added `selectionchange` listener to avoid adding a listener twice to the same\n\t * document.\n\t */\n\tprivate readonly _documents: WeakSet<Document>;\n\n\t/**\n\t * Fires debounced event `selectionChangeDone`. It uses `lodash#debounce` method to delay function call.\n\t */\n\tprivate readonly _fireSelectionChangeDoneDebounced: DebouncedFunc<( data: ViewDocumentSelectionEventData ) => void>;\n\n\t/**\n\t * When called, starts clearing the {@link #_loopbackCounter} counter in time intervals. When the number of selection\n\t * changes exceeds a certain limit within the interval of time, the observer will not fire `selectionChange` but warn about\n\t * possible infinite selection loop.\n\t */\n\tprivate readonly _clearInfiniteLoopInterval: ReturnType<typeof setInterval>;\n\n\t/**\n\t * Unlocks the `isSelecting` state of the view document in case the selection observer did not record this fact\n\t * correctly (for whatever reason). It is a safeguard (paranoid check), that returns document to the normal state\n\t * after a certain period of time (debounced, postponed by each selectionchange event).\n\t */\n\tprivate readonly _documentIsSelectingInactivityTimeoutDebounced: DebouncedFunc<() => void>;\n\n\t/**\n\t * Private property to check if the code does not enter infinite loop.\n\t */\n\tprivate _loopbackCounter: number;\n\n\tconstructor( view: View ) {\n\t\tsuper( view );\n\n\t\tthis.mutationObserver = view.getObserver( MutationObserver );\n\t\tthis.focusObserver = view.getObserver( FocusObserver );\n\t\tthis.selection = this.document.selection;\n\t\tthis.domConverter = view.domConverter;\n\n\t\tthis._documents = new WeakSet();\n\n\t\tthis._fireSelectionChangeDoneDebounced = debounce( data => {\n\t\t\tthis.document.fire<ViewDocumentSelectionChangeDoneEvent>( 'selectionChangeDone', data );\n\t\t}, 200 );\n\n\t\tthis._clearInfiniteLoopInterval = setInterval( () => this._clearInfiniteLoop(), 1000 );\n\n\t\tthis._documentIsSelectingInactivityTimeoutDebounced = debounce( () => ( this.document.isSelecting = false ), 5000 );\n\n\t\tthis._loopbackCounter = 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override observe( domElement: HTMLElement ): void {\n\t\tconst domDocument = domElement.ownerDocument;\n\n\t\tconst startDocumentIsSelecting = () => {\n\t\t\tthis.document.isSelecting = true;\n\n\t\t\t// Let's activate the safety timeout each time the document enters the \"is selecting\" state.\n\t\t\tthis._documentIsSelectingInactivityTimeoutDebounced();\n\t\t};\n\n\t\tconst endDocumentIsSelecting = () => {\n\t\t\tif ( !this.document.isSelecting ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Make sure that model selection is up-to-date at the end of selecting process.\n\t\t\t// Sometimes `selectionchange` events could arrive after the `mouseup` event and that selection could be already outdated.\n\t\t\tthis._handleSelectionChange( domDocument );\n\n\t\t\tthis.document.isSelecting = false;\n\n\t\t\t// The safety timeout can be canceled when the document leaves the \"is selecting\" state.\n\t\t\tthis._documentIsSelectingInactivityTimeoutDebounced.cancel();\n\t\t};\n\n\t\t// The document has the \"is selecting\" state while the user keeps making (extending) the selection\n\t\t// (e.g. by holding the mouse button and moving the cursor). The state resets when they either released\n\t\t// the mouse button or interrupted the process by pressing or releasing any key.\n\t\tthis.listenTo( domElement, 'selectstart', startDocumentIsSelecting, { priority: 'highest' } );\n\n\t\tthis.listenTo( domElement, 'keydown', endDocumentIsSelecting, { priority: 'highest', useCapture: true } );\n\t\tthis.listenTo( domElement, 'keyup', endDocumentIsSelecting, { priority: 'highest', useCapture: true } );\n\n\t\t// Add document-wide listeners only once. This method could be called for multiple editing roots.\n\t\tif ( this._documents.has( domDocument ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// This listener is using capture mode to make sure that selection is upcasted before any other\n\t\t// handler would like to check it and update (for example table multi cell selection).\n\t\tthis.listenTo( domDocument, 'mouseup', endDocumentIsSelecting, { priority: 'highest', useCapture: true } );\n\n\t\tthis.listenTo( domDocument, 'selectionchange', () => {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \t_debouncedLine();\n\t\t\t// @if CK_DEBUG_TYPING // \tconst domSelection = domDocument.defaultView!.getSelection();\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[SelectionObserver]%c selectionchange', 'color: green', ''\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c DOM Selection:', 'font-weight: bold; color: green', '',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },\n\t\t\t// @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.focusNode, offset: domSelection!.focusOffset }\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t// The Renderer is disabled while composing on non-android browsers, so we can't update the view selection\n\t\t\t// because the DOM and view tree drifted apart. Position mapping could fail because of it.\n\t\t\tif ( this.document.isComposing && !env.isAndroid ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c Selection change ignored (isComposing)',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', ''\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._handleSelectionChange( domDocument );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t// Defer the safety timeout when the selection changes (e.g. the user keeps extending the selection\n\t\t\t// using their mouse).\n\t\t\tthis._documentIsSelectingInactivityTimeoutDebounced();\n\t\t} );\n\n\t\t// Update the model DocumentSelection just after the Renderer and the SelectionObserver are locked.\n\t\t// We do this synchronously (without waiting for the `selectionchange` DOM event) as browser updates\n\t\t// the DOM selection (but not visually) to span the text that is under composition and could be replaced.\n\t\tthis.listenTo<ViewDocumentCompositionStartEvent>( this.view.document, 'compositionstart', () => {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconst domSelection = domDocument.defaultView!.getSelection();\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[SelectionObserver]%c update selection on compositionstart', 'color: green', ''\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c DOM Selection:', 'font-weight: bold; color: green', '',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.anchorNode, offset: domSelection!.anchorOffset },\n\t\t\t// @if CK_DEBUG_TYPING // \t\t{ node: domSelection!.focusNode, offset: domSelection!.focusOffset }\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\tthis._handleSelectionChange( domDocument );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t}, { priority: 'lowest' } );\n\n\t\tthis._documents.add( domDocument );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override stopObserving( domElement: HTMLElement ): void {\n\t\tthis.stopListening( domElement );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tclearInterval( this._clearInfiniteLoopInterval );\n\t\tthis._fireSelectionChangeDoneDebounced.cancel();\n\t\tthis._documentIsSelectingInactivityTimeoutDebounced.cancel();\n\t}\n\n\t/* istanbul ignore next -- @preserve */\n\tprivate _reportInfiniteLoop() {\n\t// @if CK_DEBUG //\t\tthrow new Error(\n\t// @if CK_DEBUG //\t\t\t'Selection change observer detected an infinite rendering loop.\\n\\n' +\n\t// @if CK_DEBUG //\t \t\t'⚠️⚠️ Report this error on https://github.com/ckeditor/ckeditor5/issues/11658.'\n\t// @if CK_DEBUG //\t\t);\n\t}\n\n\t/**\n\t * Selection change listener. {@link module:engine/view/observer/mutationobserver~MutationObserver#flush Flush} mutations, check if\n\t * a selection changes and fires {@link module:engine/view/document~Document#event:selectionChange} event on every change\n\t * and {@link module:engine/view/document~Document#event:selectionChangeDone} when a selection stop changing.\n\t *\n\t * @param domDocument DOM document.\n\t */\n\tprivate _handleSelectionChange( domDocument: Document ) {\n\t\tif ( !this.isEnabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domSelection = domDocument.defaultView!.getSelection()!;\n\n\t\tif ( this.checkShouldIgnoreEventFromTarget( domSelection.anchorNode! ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ensure the mutation event will be before selection event on all browsers.\n\t\tthis.mutationObserver.flush();\n\n\t\tconst newViewSelection = this.domConverter.domSelectionToView( domSelection );\n\n\t\t// Do not convert selection change if the new view selection has no ranges in it.\n\t\t//\n\t\t// It means that the DOM selection is in some way incorrect. Ranges that were in the DOM selection could not be\n\t\t// converted to the view. This happens when the DOM selection was moved outside of the editable element.\n\t\tif ( newViewSelection.rangeCount == 0 ) {\n\t\t\tthis.view.hasDomSelection = false;\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.view.hasDomSelection = true;\n\n\t\t// Mark the latest focus change as complete (we got new selection after the focus so the selection is in the focused element).\n\t\tthis.focusObserver.flush();\n\n\t\tif ( this.selection.isEqual( newViewSelection ) && this.domConverter.isDomSelectionCorrect( domSelection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ensure we are not in the infinite loop (#400).\n\t\t// This counter is reset each second. 60 selection changes in 1 second is enough high number\n\t\t// to be very difficult (impossible) to achieve using just keyboard keys (during normal editor use).\n\t\tif ( ++this._loopbackCounter > 60 ) {\n\t\t\t// Selection change observer detected an infinite rendering loop.\n\t\t\t// Most probably you try to put the selection in the position which is not allowed\n\t\t\t// by the browser and browser fixes it automatically what causes `selectionchange` event on\n\t\t\t// which a loopback through a model tries to re-render the wrong selection and again.\n\t\t\tthis._reportInfiniteLoop();\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.selection.isSimilar( newViewSelection ) ) {\n\t\t\t// If selection was equal and we are at this point of algorithm, it means that it was incorrect.\n\t\t\t// Just re-render it, no need to fire any events, etc.\n\t\t\tthis.view.forceRender();\n\t\t} else {\n\t\t\tconst data: ViewDocumentSelectionEventData = {\n\t\t\t\toldSelection: this.selection,\n\t\t\t\tnewSelection: newViewSelection,\n\t\t\t\tdomSelection\n\t\t\t};\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[SelectionObserver]%c Fire selection change:',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', '',\n\t\t\t// @if CK_DEBUG_TYPING // \t\tnewViewSelection.getFirstRange()\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t// Prepare data for new selection and fire appropriate events.\n\t\t\tthis.document.fire<ViewDocumentSelectionChangeEvent>( 'selectionChange', data );\n\n\t\t\t// Call `#_fireSelectionChangeDoneDebounced` every time when `selectionChange` event is fired.\n\t\t\t// This function is debounced what means that `selectionChangeDone` event will be fired only when\n\t\t\t// defined int the function time will elapse since the last time the function was called.\n\t\t\t// So `selectionChangeDone` will be fired when selection will stop changing.\n\t\t\tthis._fireSelectionChangeDoneDebounced( data );\n\t\t}\n\t}\n\n\t/**\n\t * Clears `SelectionObserver` internal properties connected with preventing infinite loop.\n\t */\n\tprivate _clearInfiniteLoop(): void {\n\t\tthis._loopbackCounter = 0;\n\t}\n}\n\n/**\n * The value of {@link ~ViewDocumentSelectionChangeEvent} and {@link ~ViewDocumentSelectionChangeDoneEvent} events.\n */\nexport type ViewDocumentSelectionEventData = {\n\n\t/**\n\t * Old View selection which is {@link module:engine/view/document~Document#selection}.\n\t */\n\toldSelection: DocumentSelection;\n\n\t/**\n\t * New View selection which is converted DOM selection.\n\t */\n\tnewSelection: Selection;\n\n\t/**\n\t * Native DOM selection.\n\t */\n\tdomSelection: DomSelection | null;\n};\n\n/**\n * Fired when a selection has changed. This event is fired only when the selection change was the only change that happened\n * in the document, and the old selection is different then the new selection.\n *\n * Introduced by {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n *\n * Note that because {@link module:engine/view/observer/selectionobserver~SelectionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/selectionobserver~SelectionObserver\n * @eventName module:engine/view/document~Document#selectionChange\n */\nexport type ViewDocumentSelectionChangeEvent = {\n\tname: 'selectionChange';\n\targs: [ ViewDocumentSelectionEventData ];\n};\n\n/**\n * Fired when selection stops changing.\n *\n * Introduced by {@link module:engine/view/observer/selectionobserver~SelectionObserver}.\n *\n * Note that because {@link module:engine/view/observer/selectionobserver~SelectionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/selectionobserver~SelectionObserver\n * @eventName module:engine/view/document~Document#selectionChangeDone\n */\nexport type ViewDocumentSelectionChangeDoneEvent = {\n\tname: 'selectionChangeDone';\n\targs: [ ViewDocumentSelectionEventData ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/compositionobserver\n */\n\nimport DomEventObserver from './domeventobserver.js';\nimport type View from '../view.js';\nimport type DomEventData from './domeventdata.js';\n\n// @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );\n\n/**\n * {@link module:engine/view/document~Document#event:compositionstart Compositionstart},\n * {@link module:engine/view/document~Document#event:compositionupdate compositionupdate} and\n * {@link module:engine/view/document~Document#event:compositionend compositionend} events observer.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */\nexport default class CompositionObserver extends DomEventObserver<'compositionstart' | 'compositionupdate' | 'compositionend'> {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly domEventType = [ 'compositionstart', 'compositionupdate', 'compositionend' ] as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: View ) {\n\t\tsuper( view );\n\n\t\tconst document = this.document;\n\n\t\tdocument.on<ViewDocumentCompositionStartEvent>( 'compositionstart', () => {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[CompositionObserver] ' +\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'┌───────────────────────────── isComposing = true ─────────────────────────────┐',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green'\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t\tdocument.isComposing = true;\n\t\t}, { priority: 'low' } );\n\n\t\tdocument.on<ViewDocumentCompositionEndEvent>( 'compositionend', () => {\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[CompositionObserver] ' +\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'└───────────────────────────── isComposing = false ─────────────────────────────┘',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green'\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t\tdocument.isComposing = false;\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvent: CompositionEvent ): void {\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \t_debouncedLine();\n\t\t// @if CK_DEBUG_TYPING // \tconsole.group( `%c[CompositionObserver]%c ${ domEvent.type }`, 'color: green', '' );\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tthis.fire( domEvent.type, domEvent, {\n\t\t\tdata: domEvent.data\n\t\t} );\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t// @if CK_DEBUG_TYPING // }\n\t}\n}\n\nexport interface CompositionEventData extends DomEventData<CompositionEvent> {\n\tdata: string | null;\n}\n\n/**\n * Fired when composition starts inside one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * Note that because {@link module:engine/view/observer/compositionobserver~CompositionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/compositionobserver~CompositionObserver\n * @eventName module:engine/view/document~Document#compositionstart\n * @param data Event data.\n */\nexport type ViewDocumentCompositionStartEvent = {\n\tname: 'compositionstart';\n\targs: [ data: CompositionEventData ];\n};\n\n/**\n * Fired when composition is updated inside one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * Note that because {@link module:engine/view/observer/compositionobserver~CompositionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/compositionobserver~CompositionObserver\n * @eventName module:engine/view/document~Document#compositionupdate\n * @param data Event data.\n */\nexport type ViewDocumentCompositionUpdateEvent = {\n\tname: 'compositionupdate';\n\targs: [ data: CompositionEventData ];\n};\n\n/**\n * Fired when composition ends inside one of the editables.\n *\n * Introduced by {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * Note that because {@link module:engine/view/observer/compositionobserver~CompositionObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @see module:engine/view/observer/compositionobserver~CompositionObserver\n * @eventName module:engine/view/document~Document#compositionend\n * @param data Event data.\n */\nexport type ViewDocumentCompositionEndEvent = {\n\tname: 'compositionend';\n\targs: [ data: CompositionEventData ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/datatransfer\n */\n\ntype DomDataTransfer = globalThis.DataTransfer;\n\n/**\n * A facade over the native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n */\nexport default class DataTransfer {\n\t/**\n\t * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t */\n\tprivate _files: Array<File> | null;\n\n\t/**\n\t * The native DataTransfer object.\n\t */\n\tprivate _native: DomDataTransfer;\n\n\t/**\n\t * @param nativeDataTransfer The native [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object.\n\t * @param options.cacheFiles Whether `files` list should be initialized in the constructor.\n\t */\n\tconstructor( nativeDataTransfer: DomDataTransfer, options: { cacheFiles?: boolean } = {} ) {\n\t\t// We should store references to the File instances in case someone would like to process this files\n\t\t// outside the event handler. Files are stored only for `drop` and `paste` events because they are not usable\n\t\t// in other events and are generating a huge delay on Firefox while dragging.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/13366.\n\t\tthis._files = options.cacheFiles ? getFiles( nativeDataTransfer ) : null;\n\n\t\tthis._native = nativeDataTransfer;\n\t}\n\n\t/**\n\t * The array of files created from the native `DataTransfer#files` or `DataTransfer#items`.\n\t */\n\tpublic get files(): Array<File> {\n\t\tif ( !this._files ) {\n\t\t\tthis._files = getFiles( this._native );\n\t\t}\n\n\t\treturn this._files;\n\t}\n\n\t/**\n\t * Returns an array of available native content types.\n\t */\n\tpublic get types(): ReadonlyArray<string> {\n\t\treturn this._native.types;\n\t}\n\n\t/**\n\t * Gets the data from the data transfer by its MIME type.\n\t *\n\t * ```ts\n\t * dataTransfer.getData( 'text/plain' );\n\t * ```\n\t *\n\t * @param type The MIME type. E.g. `text/html` or `text/plain`.\n\t */\n\tpublic getData( type: string ): string {\n\t\treturn this._native.getData( type );\n\t}\n\n\t/**\n\t * Sets the data in the data transfer.\n\t *\n\t * @param type The MIME type. E.g. `text/html` or `text/plain`.\n\t */\n\tpublic setData( type: string, data: string ): void {\n\t\tthis._native.setData( type, data );\n\t}\n\n\t/**\n\t * The effect that is allowed for a drag operation.\n\t */\n\tpublic set effectAllowed( value: EffectAllowed ) {\n\t\tthis._native.effectAllowed = value;\n\t}\n\n\tpublic get effectAllowed(): EffectAllowed {\n\t\treturn this._native.effectAllowed;\n\t}\n\n\t/**\n\t * The actual drop effect.\n\t */\n\tpublic set dropEffect( value: DropEffect ) {\n\t\tthis._native.dropEffect = value;\n\t}\n\n\tpublic get dropEffect(): DropEffect {\n\t\treturn this._native.dropEffect;\n\t}\n\n\t/**\n\t * Set a preview image of the dragged content.\n\t */\n\tpublic setDragImage( image: Element, x: number, y: number ): void {\n\t\tthis._native.setDragImage( image, x, y );\n\t}\n\n\t/**\n\t * Whether the dragging operation was canceled.\n\t */\n\tpublic get isCanceled(): boolean {\n\t\treturn this._native.dropEffect == 'none' || !!( this._native as any ).mozUserCancelled;\n\t}\n}\n\n/**\n * The effect that is allowed for a drag operation.\n */\nexport type EffectAllowed = DomDataTransfer[ 'effectAllowed' ];\n\n/**\n * The actual drop effect.\n */\nexport type DropEffect = DomDataTransfer[ 'dropEffect' ];\n\nfunction getFiles( nativeDataTransfer: DomDataTransfer ): Array<File> {\n\t// DataTransfer.files and items are array-like and might not have an iterable interface.\n\tconst files = Array.from( nativeDataTransfer.files || [] );\n\tconst items = Array.from( nativeDataTransfer.items || [] );\n\n\tif ( files.length ) {\n\t\treturn files;\n\t}\n\n\t// Chrome has empty DataTransfer.files, but allows getting files through the items interface.\n\treturn items\n\t\t.filter( item => item.kind === 'file' )\n\t\t.map( item => item.getAsFile()! );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/inputobserver\n */\n\nimport DomEventObserver from './domeventobserver.js';\nimport type DomEventData from './domeventdata.js';\nimport type ViewRange from '../range.js';\nimport DataTransfer from '../datatransfer.js';\nimport { env } from '@ckeditor/ckeditor5-utils';\n\n// @if CK_DEBUG_TYPING // const { _debouncedLine } = require( '../../dev-utils/utils.js' );\n\n/**\n * Observer for events connected with data input.\n *\n * **Note**: This observer is attached by {@link module:engine/view/view~View} and available by default in all\n * editor instances.\n */\nexport default class InputObserver extends DomEventObserver<'beforeinput'> {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly domEventType = 'beforeinput' as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvent: InputEvent ): void {\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \t_debouncedLine();\n\t\t// @if CK_DEBUG_TYPING // \tconsole.group( `%c[InputObserver]%c ${ domEvent.type }: ${ domEvent.inputType }`,\n\t\t// @if CK_DEBUG_TYPING // \t\t'color: green', 'color: default'\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tconst domTargetRanges = domEvent.getTargetRanges();\n\t\tconst view = this.view;\n\t\tconst viewDocument = view.document;\n\n\t\tlet dataTransfer: DataTransfer | null = null;\n\t\tlet data: string | null = null;\n\t\tlet targetRanges: Array<ViewRange> = [];\n\n\t\tif ( domEvent.dataTransfer ) {\n\t\t\tdataTransfer = new DataTransfer( domEvent.dataTransfer );\n\t\t}\n\n\t\tif ( domEvent.data !== null ) {\n\t\t\tdata = domEvent.data;\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( `%c[InputObserver]%c event data: %c${ JSON.stringify( data ) }`,\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', 'color: blue;'\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t} else if ( dataTransfer ) {\n\t\t\tdata = dataTransfer.getData( 'text/plain' );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( `%c[InputObserver]%c event data transfer: %c${ JSON.stringify( data ) }`,\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', 'color: blue;'\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t}\n\n\t\t// If the editor selection is fake (an object is selected), the DOM range does not make sense because it is anchored\n\t\t// in the fake selection container.\n\t\tif ( viewDocument.selection.isFake ) {\n\t\t\t// Future-proof: in case of multi-range fake selections being possible.\n\t\t\ttargetRanges = Array.from( viewDocument.selection.getRanges() );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[InputObserver]%c using fake selection:',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', targetRanges,\n\t\t\t// @if CK_DEBUG_TYPING // \t\tviewDocument.selection.isFake ? 'fake view selection' : 'fake DOM parent'\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t} else if ( domTargetRanges.length ) {\n\t\t\ttargetRanges = domTargetRanges.map( domRange => {\n\t\t\t\t// Sometimes browser provides range that starts before editable node.\n\t\t\t\t// We try to fall back to collapsed range at the valid end position.\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/14411.\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/14050.\n\t\t\t\tconst viewStart = view.domConverter.domPositionToView( domRange.startContainer, domRange.startOffset );\n\t\t\t\tconst viewEnd = view.domConverter.domPositionToView( domRange.endContainer, domRange.endOffset );\n\n\t\t\t\tif ( viewStart ) {\n\t\t\t\t\treturn view.createRange( viewStart, viewEnd );\n\t\t\t\t} else if ( viewEnd ) {\n\t\t\t\t\treturn view.createRange( viewEnd );\n\t\t\t\t}\n\t\t\t} ).filter( ( range ): range is ViewRange => !!range );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[InputObserver]%c using target ranges:',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', targetRanges\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t}\n\t\t// For Android devices we use a fallback to the current DOM selection, Android modifies it according\n\t\t// to the expected target ranges of input event.\n\t\telse if ( env.isAndroid ) {\n\t\t\tconst domSelection = ( domEvent.target as HTMLElement ).ownerDocument.defaultView!.getSelection()!;\n\n\t\t\ttargetRanges = Array.from( view.domConverter.domSelectionToView( domSelection ).getRanges() );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[InputObserver]%c using selection ranges:',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'color: green; font-weight: bold', 'font-weight: bold', targetRanges\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t}\n\n\t\t// Android sometimes fires insertCompositionText with a new-line character at the end of the data\n\t\t// instead of firing insertParagraph beforeInput event.\n\t\t// Fire the correct type of beforeInput event and ignore the replaced fragment of text because\n\t\t// it wants to replace \"test\" with \"test\\n\".\n\t\t// https://github.com/ckeditor/ckeditor5/issues/12368.\n\t\tif ( env.isAndroid && domEvent.inputType == 'insertCompositionText' && data && data.endsWith( '\\n' ) ) {\n\t\t\tthis.fire( domEvent.type, domEvent, {\n\t\t\t\tinputType: 'insertParagraph',\n\t\t\t\ttargetRanges: [ view.createRange( targetRanges[ 0 ].end ) ]\n\t\t\t} );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Normalize the insertText data that includes new-line characters.\n\t\t// https://github.com/ckeditor/ckeditor5/issues/2045.\n\t\tif ( domEvent.inputType == 'insertText' && data && data.includes( '\\n' ) ) {\n\t\t\t// There might be a single new-line or double for new paragraph, but we translate\n\t\t\t// it to paragraphs as it is our default action for enter handling.\n\t\t\tconst parts = data.split( /\\n{1,2}/g );\n\n\t\t\tlet partTargetRanges = targetRanges;\n\n\t\t\tfor ( let i = 0; i < parts.length; i++ ) {\n\t\t\t\tconst dataPart = parts[ i ];\n\n\t\t\t\tif ( dataPart != '' ) {\n\t\t\t\t\tthis.fire( domEvent.type, domEvent, {\n\t\t\t\t\t\tdata: dataPart,\n\t\t\t\t\t\tdataTransfer,\n\t\t\t\t\t\ttargetRanges: partTargetRanges,\n\t\t\t\t\t\tinputType: domEvent.inputType,\n\t\t\t\t\t\tisComposing: domEvent.isComposing\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Use the result view selection so following events will be added one after another.\n\t\t\t\t\tpartTargetRanges = [ viewDocument.selection.getFirstRange()! ];\n\t\t\t\t}\n\n\t\t\t\tif ( i + 1 < parts.length ) {\n\t\t\t\t\tthis.fire( domEvent.type, domEvent, {\n\t\t\t\t\t\tinputType: 'insertParagraph',\n\t\t\t\t\t\ttargetRanges: partTargetRanges\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Use the result view selection so following events will be added one after another.\n\t\t\t\t\tpartTargetRanges = [ viewDocument.selection.getFirstRange()! ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Fire the normalized beforeInput event.\n\t\tthis.fire( domEvent.type, domEvent, {\n\t\t\tdata,\n\t\t\tdataTransfer,\n\t\t\ttargetRanges,\n\t\t\tinputType: domEvent.inputType,\n\t\t\tisComposing: domEvent.isComposing\n\t\t} );\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t// @if CK_DEBUG_TYPING // }\n\t}\n}\n\n/**\n * Fired before the web browser inputs, deletes, or formats some data.\n *\n * This event is introduced by {@link module:engine/view/observer/inputobserver~InputObserver} and available\n * by default in all editor instances (attached by {@link module:engine/view/view~View}).\n *\n * @see module:engine/view/observer/inputobserver~InputObserver\n * @eventName module:engine/view/document~Document#beforeinput\n * @param data Event data containing detailed information about the event.\n */\nexport type ViewDocumentInputEvent = {\n\tname: 'beforeinput';\n\targs: [ data: InputEventData ];\n};\n\n/**\n * The value of the {@link ~ViewDocumentInputEvent} event.\n */\nexport interface InputEventData extends DomEventData<InputEvent> {\n\n\t/**\n\t * The type of the input event (e.g. \"insertText\" or \"deleteWordBackward\"). Corresponds to native `InputEvent#inputType`.\n\t */\n\treadonly inputType: string;\n\n\t/**\n\t * A unified text data passed along with the input event. Depending on:\n\t *\n\t * * the web browser and input events implementation (for instance [Level 1](https://www.w3.org/TR/input-events-1/) or\n\t * [Level 2](https://www.w3.org/TR/input-events-2/)),\n\t * * {@link module:engine/view/observer/inputobserver~InputEventData#inputType input type}\n\t *\n\t * text data is sometimes passed in the `data` and sometimes in the `dataTransfer` property.\n\t *\n\t * * If `InputEvent#data` was set, this property reflects its value.\n\t * * If `InputEvent#data` is unavailable, this property contains the `'text/plain'` data from\n\t * {@link module:engine/view/observer/inputobserver~InputEventData#dataTransfer}.\n\t * * If the event ({@link module:engine/view/observer/inputobserver~InputEventData#inputType input type})\n\t * provides no data whatsoever, this property is `null`.\n\t */\n\treadonly data: string | null;\n\n\t/**\n\t * The data transfer instance of the input event. Corresponds to native `InputEvent#dataTransfer`.\n\t *\n\t * The value is `null` when no `dataTransfer` was passed along with the input event.\n\t */\n\treadonly dataTransfer: DataTransfer;\n\n\t/**\n\t * A flag indicating that the `beforeinput` event was fired during composition.\n\t *\n\t * Corresponds to the\n\t * {@link module:engine/view/document~Document#event:compositionstart},\n\t * {@link module:engine/view/document~Document#event:compositionupdate},\n\t * and {@link module:engine/view/document~Document#event:compositionend } trio.\n\t */\n\treadonly isComposing: boolean;\n\n\t/**\n\t * Editing {@link module:engine/view/range~Range view ranges} corresponding to DOM ranges provided by the web browser\n\t * (as returned by `InputEvent#getTargetRanges()`).\n\t */\n\treadonly targetRanges: Array<ViewRange>;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/arrowkeysobserver\n */\n\nimport Observer from './observer.js';\nimport BubblingEventInfo from './bubblingeventinfo.js';\nimport type View from '../view.js';\nimport type { KeyEventData, ViewDocumentKeyDownEvent } from './keyobserver.js';\nimport type { BubblingEvent } from './bubblingemittermixin.js';\n\nimport { isArrowKeyCode } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Arrow keys observer introduces the {@link module:engine/view/document~Document#event:arrowKey `Document#arrowKey`} event.\n *\n * Note that this observer is attached by the {@link module:engine/view/view~View} and is available by default.\n */\nexport default class ArrowKeysObserver extends Observer {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: View ) {\n\t\tsuper( view );\n\n\t\tthis.document.on<ViewDocumentKeyDownEvent>( 'keydown', ( event, data ) => {\n\t\t\tif ( this.isEnabled && isArrowKeyCode( data.keyCode ) ) {\n\t\t\t\tconst eventInfo = new BubblingEventInfo( this.document, 'arrowKey', this.document.selection.getFirstRange()! );\n\n\t\t\t\tthis.document.fire<ViewDocumentArrowKeyEvent>( eventInfo, data );\n\n\t\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\t\tevent.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override observe(): void {}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override stopObserving(): void {}\n}\n\n/**\n * Event fired when the user presses an arrow keys.\n *\n * Introduced by {@link module:engine/view/observer/arrowkeysobserver~ArrowKeysObserver}.\n *\n * Note that because {@link module:engine/view/observer/arrowkeysobserver~ArrowKeysObserver} is attached by the\n * {@link module:engine/view/view~View} this event is available by default.\n *\n * @eventName module:engine/view/document~Document#arrowKey\n * @param data\n */\n\nexport type ViewDocumentArrowKeyEvent = BubblingEvent<{\n\tname: 'arrowKey';\n\targs: [ data: KeyEventData ];\n}>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/tabobserver\n */\n\nimport type View from '../view.js';\nimport Observer from './observer.js';\nimport BubblingEventInfo from './bubblingeventinfo.js';\nimport type { KeyEventData, ViewDocumentKeyDownEvent } from './keyobserver.js';\nimport type { BubblingEvent } from './bubblingemittermixin.js';\n\nimport { keyCodes } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Tab observer introduces the {@link module:engine/view/document~Document#event:tab `Document#tab`} event.\n *\n * Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the\n * {@link module:engine/view/view~View}, this event is available by default.\n */\nexport default class TabObserver extends Observer {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: View ) {\n\t\tsuper( view );\n\n\t\tconst doc = this.document;\n\n\t\tdoc.on<ViewDocumentKeyDownEvent>( 'keydown', ( evt, data ) => {\n\t\t\tif (\n\t\t\t\t!this.isEnabled ||\n\t\t\t\tdata.keyCode != keyCodes.tab ||\n\t\t\t\tdata.ctrlKey\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst event = new BubblingEventInfo( doc, 'tab', doc.selection.getFirstRange()! );\n\n\t\t\tdoc.fire<ViewDocumentTabEvent>( event, data );\n\n\t\t\tif ( event.stop.called ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override observe(): void {}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override stopObserving(): void {}\n}\n\n/**\n * Event fired when the user presses a tab key.\n *\n * Introduced by {@link module:engine/view/observer/tabobserver~TabObserver}.\n *\n * Note that because {@link module:engine/view/observer/tabobserver~TabObserver} is attached by the\n * {@link module:engine/view/view~View}, this event is available by default.\n *\n * @eventName module:engine/view/document~Document#tab\n * @param data\n */\nexport type ViewDocumentTabEvent = BubblingEvent<{\n\tname: 'tab';\n\targs: [ data: KeyEventData ];\n}>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/view\n */\n\nimport Document, { type ViewDocumentLayoutChangedEvent } from './document.js';\nimport DowncastWriter from './downcastwriter.js';\nimport Renderer from './renderer.js';\nimport DomConverter from './domconverter.js';\nimport Position, { type PositionOffset } from './position.js';\nimport Range from './range.js';\nimport Selection, {\n\ttype PlaceOrOffset,\n\ttype Selectable,\n\ttype SelectionOptions\n} from './selection.js';\n\nimport type { default as Observer, ObserverConstructor } from './observer/observer.js';\nimport type { ViewDocumentSelectionChangeEvent } from './documentselection.js';\nimport type { StylesProcessor } from './stylesmap.js';\nimport type Element from './element.js';\nimport type { default as Node, ViewNodeChangeEvent } from './node.js';\nimport type Item from './item.js';\n\nimport KeyObserver from './observer/keyobserver.js';\nimport FakeSelectionObserver from './observer/fakeselectionobserver.js';\nimport MutationObserver, { type ViewDocumentMutationsEvent } from './observer/mutationobserver.js';\nimport SelectionObserver from './observer/selectionobserver.js';\nimport FocusObserver, { type ViewDocumentBlurEvent } from './observer/focusobserver.js';\nimport CompositionObserver from './observer/compositionobserver.js';\nimport InputObserver from './observer/inputobserver.js';\nimport ArrowKeysObserver from './observer/arrowkeysobserver.js';\nimport TabObserver from './observer/tabobserver.js';\n\nimport {\n\tCKEditorError,\n\tenv,\n\tObservableMixin,\n\tscrollViewportToShowTarget,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\nimport { injectUiElementHandling } from './uielement.js';\nimport { injectQuirksHandling } from './filler.js';\n\nimport { cloneDeep } from 'lodash-es';\n\ntype IfTrue<T> = T extends true ? true : never;\ntype DomRange = globalThis.Range;\n\n/**\n * Editor's view controller class. Its main responsibility is DOM - View management for editing purposes, to provide\n * abstraction over the DOM structure and events and hide all browsers quirks.\n *\n * View controller renders view document to DOM whenever view structure changes. To determine when view can be rendered,\n * all changes need to be done using the {@link module:engine/view/view~View#change} method, using\n * {@link module:engine/view/downcastwriter~DowncastWriter}:\n *\n * ```ts\n * view.change( writer => {\n * \twriter.insert( position, writer.createText( 'foo' ) );\n * } );\n * ```\n *\n * View controller also register {@link module:engine/view/observer/observer~Observer observers} which observes changes\n * on DOM and fire events on the {@link module:engine/view/document~Document Document}.\n * Note that the following observers are added by the class constructor and are always available:\n *\n * * {@link module:engine/view/observer/selectionobserver~SelectionObserver},\n * * {@link module:engine/view/observer/focusobserver~FocusObserver},\n * * {@link module:engine/view/observer/keyobserver~KeyObserver},\n * * {@link module:engine/view/observer/fakeselectionobserver~FakeSelectionObserver}.\n * * {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n * * {@link module:engine/view/observer/inputobserver~InputObserver}.\n * * {@link module:engine/view/observer/arrowkeysobserver~ArrowKeysObserver}.\n * * {@link module:engine/view/observer/tabobserver~TabObserver}.\n *\n * This class also {@link module:engine/view/view~View#attachDomRoot binds the DOM and the view elements}.\n *\n * If you do not need full a DOM - view management, and only want to transform a tree of view elements to a tree of DOM\n * elements you do not need this controller. You can use the {@link module:engine/view/domconverter~DomConverter DomConverter} instead.\n */\nexport default class View extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * Instance of the {@link module:engine/view/document~Document} associated with this view controller.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * Instance of the {@link module:engine/view/domconverter~DomConverter domConverter} used by\n\t * {@link module:engine/view/view~View#_renderer renderer}\n\t * and {@link module:engine/view/observer/observer~Observer observers}.\n\t */\n\tpublic readonly domConverter: DomConverter;\n\n\t/**\n\t * Roots of the DOM tree. Map on the `HTMLElement`s with roots names as keys.\n\t */\n\tpublic readonly domRoots: Map<string, HTMLElement> = new Map();\n\n\t/**\n\t * Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public isRenderingInProgress: boolean;\n\n\t/**\n\t * Informs whether the DOM selection is inside any of the DOM roots managed by the view.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public hasDomSelection: boolean;\n\n\t/**\n\t * Instance of the {@link module:engine/view/renderer~Renderer renderer}.\n\t */\n\tprivate readonly _renderer: Renderer;\n\n\t/**\n\t * A DOM root attributes cache. It saves the initial values of DOM root attributes before the DOM element\n\t * is {@link module:engine/view/view~View#attachDomRoot attached} to the view so later on, when\n\t * the view is destroyed ({@link module:engine/view/view~View#detachDomRoot}), they can be easily restored.\n\t * This way, the DOM element can go back to the (clean) state as if the editing view never used it.\n\t */\n\tprivate readonly _initialDomRootAttributes: WeakMap<HTMLElement, Record<string, string>> = new WeakMap();\n\n\t/**\n\t * Map of registered {@link module:engine/view/observer/observer~Observer observers}.\n\t */\n\tprivate readonly _observers: Map<ObserverConstructor, Observer> = new Map();\n\n\t/**\n\t * DowncastWriter instance used in {@link #change change method} callbacks.\n\t */\n\tprivate readonly _writer: DowncastWriter;\n\n\t/**\n\t * Is set to `true` when {@link #change view changes} are currently in progress.\n\t */\n\tprivate _ongoingChange: boolean = false;\n\n\t/**\n\t * Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t */\n\tprivate _postFixersInProgress: boolean = false;\n\n\t/**\n\t * Internal flag to temporary disable rendering. See the usage in the {@link #_disableRendering}.\n\t */\n\tprivate _renderingDisabled: boolean = false;\n\n\t/**\n\t * Internal flag that disables rendering when there are no changes since the last rendering.\n\t * It stores information about changed selection and changed elements from attached document roots.\n\t */\n\tprivate _hasChangedSinceTheLastRendering: boolean = false;\n\n\t/**\n\t * @param stylesProcessor The styles processor instance.\n\t */\n\tconstructor( stylesProcessor: StylesProcessor ) {\n\t\tsuper();\n\n\t\tthis.document = new Document( stylesProcessor );\n\t\tthis.domConverter = new DomConverter( this.document );\n\n\t\tthis.set( 'isRenderingInProgress', false );\n\t\tthis.set( 'hasDomSelection', false );\n\n\t\tthis._renderer = new Renderer( this.domConverter, this.document.selection );\n\t\tthis._renderer.bind( 'isFocused', 'isSelecting', 'isComposing' )\n\t\t\t.to( this.document, 'isFocused', 'isSelecting', 'isComposing' );\n\n\t\tthis._writer = new DowncastWriter( this.document );\n\n\t\t// Add default observers.\n\t\t// Make sure that this list matches AlwaysRegisteredObservers type.\n\t\tthis.addObserver( MutationObserver );\n\t\tthis.addObserver( FocusObserver );\n\t\tthis.addObserver( SelectionObserver );\n\t\tthis.addObserver( KeyObserver );\n\t\tthis.addObserver( FakeSelectionObserver );\n\t\tthis.addObserver( CompositionObserver );\n\t\tthis.addObserver( ArrowKeysObserver );\n\t\tthis.addObserver( InputObserver );\n\t\tthis.addObserver( TabObserver );\n\n\t\t// Inject quirks handlers.\n\t\tinjectQuirksHandling( this );\n\t\tinjectUiElementHandling( this );\n\n\t\t// Use 'normal' priority so that rendering is performed as first when using that priority.\n\t\tthis.on<ViewRenderEvent>( 'render', () => {\n\t\t\tthis._render();\n\n\t\t\t// Informs that layout has changed after render.\n\t\t\tthis.document.fire<ViewDocumentLayoutChangedEvent>( 'layoutChanged' );\n\n\t\t\t// Reset the `_hasChangedSinceTheLastRendering` flag after rendering.\n\t\t\tthis._hasChangedSinceTheLastRendering = false;\n\t\t} );\n\n\t\t// Listen to the document selection changes directly.\n\t\tthis.listenTo<ViewDocumentSelectionChangeEvent>( this.document.selection, 'change', () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t} );\n\n\t\t// Trigger re-render if only the focus changed.\n\t\tthis.listenTo<ObservableChangeEvent>( this.document, 'change:isFocused', () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t} );\n\n\t\t// Remove ranges from DOM selection if editor is blurred.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/5753.\n\t\tif ( env.isiOS ) {\n\t\t\tthis.listenTo<ViewDocumentBlurEvent>( this.document, 'blur', ( evt, data ) => {\n\t\t\t\tconst relatedViewElement = this.domConverter.mapDomToView( data.domEvent.relatedTarget as HTMLElement );\n\n\t\t\t\t// Do not modify DOM selection if focus is moved to other editable of the same editor.\n\t\t\t\tif ( !relatedViewElement ) {\n\t\t\t\t\tthis.domConverter._clearDomSelection();\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Listen to external content mutations (directly in the DOM) and mark them to get verified by the renderer.\n\t\tthis.listenTo<ViewDocumentMutationsEvent>( this.document, 'mutations', ( evt, { mutations } ) => {\n\t\t\tmutations.forEach( mutation => this._renderer.markToSync( mutation.type, mutation.node ) );\n\t\t}, { priority: 'low' } );\n\n\t\t// After all mutated nodes were marked to sync we can trigger view to DOM synchronization\n\t\t// to make sure the DOM structure matches the view.\n\t\tthis.listenTo<ViewDocumentMutationsEvent>( this.document, 'mutations', () => {\n\t\t\tthis.forceRender();\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Attaches a DOM root element to the view element and enable all observers on that element.\n\t * Also {@link module:engine/view/renderer~Renderer#markToSync mark element} to be synchronized\n\t * with the view what means that all child nodes will be removed and replaced with content of the view root.\n\t *\n\t * This method also will change view element name as the same as tag name of given dom root.\n\t * Name is always transformed to lower case.\n\t *\n\t * **Note:** Use {@link #detachDomRoot `detachDomRoot()`} to revert this action.\n\t *\n\t * @param domRoot DOM root element.\n\t * @param name Name of the root.\n\t */\n\tpublic attachDomRoot( domRoot: HTMLElement, name: string = 'main' ): void {\n\t\tconst viewRoot = this.document.getRoot( name )!;\n\n\t\t// Set view root name the same as DOM root tag name.\n\t\tviewRoot._name = domRoot.tagName.toLowerCase();\n\n\t\tconst initialDomRootAttributes: Record<string, string> = {};\n\n\t\t// 1. Copy and cache the attributes to remember the state of the element before attaching.\n\t\t//    The cached attributes will be restored in detachDomRoot() so the element goes to the\n\t\t//    clean state as if the editing view never used it.\n\t\t// 2. Apply the attributes using the view writer, so they all go under the control of the engine.\n\t\t//    The editing view takes over the attribute management completely because various\n\t\t//    features (e.g. addPlaceholder()) require dynamic changes of those attributes and they\n\t\t//    cannot be managed by the engine and the UI library at the same time.\n\t\tfor ( const { name, value } of Array.from( domRoot.attributes ) ) {\n\t\t\tinitialDomRootAttributes[ name ] = value;\n\n\t\t\t// Do not use writer.setAttribute() for the class attribute. The EditableUIView class\n\t\t\t// and its descendants could have already set some using the writer.addClass() on the view\n\t\t\t// document root. They haven't been rendered yet so they are not present in the DOM root.\n\t\t\t// Using writer.setAttribute( 'class', ... ) would override them completely.\n\t\t\tif ( name === 'class' ) {\n\t\t\t\tthis._writer.addClass( value.split( ' ' ), viewRoot );\n\t\t\t} else {\n\t\t\t\t// There is a chance that some attributes have already been set on the view root before attaching\n\t\t\t\t// the DOM root and should be preserved. This is a similar case to the \"class\" attribute except\n\t\t\t\t// this time there is no workaround using a some low-level API.\n\t\t\t\tif ( !viewRoot.hasAttribute( name ) ) {\n\t\t\t\t\tthis._writer.setAttribute( name, value, viewRoot );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._initialDomRootAttributes.set( domRoot, initialDomRootAttributes );\n\n\t\tconst updateContenteditableAttribute = () => {\n\t\t\tthis._writer.setAttribute( 'contenteditable', ( !viewRoot.isReadOnly ).toString(), viewRoot );\n\n\t\t\tif ( viewRoot.isReadOnly ) {\n\t\t\t\tthis._writer.addClass( 'ck-read-only', viewRoot );\n\t\t\t} else {\n\t\t\t\tthis._writer.removeClass( 'ck-read-only', viewRoot );\n\t\t\t}\n\t\t};\n\n\t\t// Set initial value.\n\t\tupdateContenteditableAttribute();\n\n\t\tthis.domRoots.set( name, domRoot );\n\t\tthis.domConverter.bindElements( domRoot, viewRoot );\n\t\tthis._renderer.markToSync( 'children', viewRoot );\n\t\tthis._renderer.markToSync( 'attributes', viewRoot );\n\t\tthis._renderer.domDocuments.add( domRoot.ownerDocument );\n\n\t\tviewRoot.on<ViewNodeChangeEvent>( 'change:children', ( evt, node ) => this._renderer.markToSync( 'children', node ) );\n\t\tviewRoot.on<ViewNodeChangeEvent>( 'change:attributes', ( evt, node ) => this._renderer.markToSync( 'attributes', node ) );\n\t\tviewRoot.on<ViewNodeChangeEvent>( 'change:text', ( evt, node ) => this._renderer.markToSync( 'text', node ) );\n\t\tviewRoot.on<ObservableChangeEvent>( 'change:isReadOnly', () => this.change( updateContenteditableAttribute ) );\n\n\t\tviewRoot.on( 'change', () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t} );\n\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.observe( domRoot, name );\n\t\t}\n\t}\n\n\t/**\n\t * Detaches a DOM root element from the view element and restores its attributes to the state before\n\t * {@link #attachDomRoot `attachDomRoot()`}.\n\t *\n\t * @param name Name of the root to detach.\n\t */\n\tpublic detachDomRoot( name: string ): void {\n\t\tconst domRoot = this.domRoots.get( name )!;\n\n\t\t// Remove all root attributes so the DOM element is \"bare\".\n\t\tArray.from( domRoot.attributes ).forEach( ( { name } ) => domRoot.removeAttribute( name ) );\n\n\t\tconst initialDomRootAttributes = this._initialDomRootAttributes.get( domRoot );\n\n\t\t// Revert all view root attributes back to the state before attachDomRoot was called.\n\t\tfor ( const attribute in initialDomRootAttributes ) {\n\t\t\tdomRoot.setAttribute( attribute, initialDomRootAttributes[ attribute ] );\n\t\t}\n\n\t\tthis.domRoots.delete( name );\n\t\tthis.domConverter.unbindDomElement( domRoot );\n\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.stopObserving( domRoot );\n\t\t}\n\t}\n\n\t/**\n\t * Gets DOM root element.\n\t *\n\t * @param name  Name of the root.\n\t * @returns DOM root element instance.\n\t */\n\tpublic getDomRoot( name: string = 'main' ): HTMLElement | undefined {\n\t\treturn this.domRoots.get( name );\n\t}\n\n\t/**\n\t * Creates observer of the given type if not yet created, {@link module:engine/view/observer/observer~Observer#enable enables} it\n\t * and {@link module:engine/view/observer/observer~Observer#observe attaches} to all existing and future\n\t * {@link #domRoots DOM roots}.\n\t *\n\t * Note: Observers are recognized by their constructor (classes). A single observer will be instantiated and used only\n\t * when registered for the first time. This means that features and other components can register a single observer\n\t * multiple times without caring whether it has been already added or not.\n\t *\n\t * @param ObserverConstructor The constructor of an observer to add.\n\t * Should create an instance inheriting from {@link module:engine/view/observer/observer~Observer}.\n\t * @returns Added observer instance.\n\t */\n\tpublic addObserver( ObserverConstructor: ObserverConstructor ): Observer {\n\t\tlet observer = this._observers.get( ObserverConstructor );\n\n\t\tif ( observer ) {\n\t\t\treturn observer;\n\t\t}\n\n\t\tobserver = new ObserverConstructor( this );\n\n\t\tthis._observers.set( ObserverConstructor, observer );\n\n\t\tfor ( const [ name, domElement ] of this.domRoots ) {\n\t\t\tobserver.observe( domElement, name );\n\t\t}\n\n\t\tobserver.enable();\n\n\t\treturn observer;\n\t}\n\n\tpublic getObserver<T extends ObserverConstructor>( ObserverConstructor: T ):\n\t\tT extends AlwaysRegisteredObservers ? InstanceType<T> : InstanceType<T> | undefined;\n\n\t/**\n\t * Returns observer of the given type or `undefined` if such observer has not been added yet.\n\t *\n\t * @param ObserverConstructor The constructor of an observer to get.\n\t * @returns Observer instance or undefined.\n\t */\n\tpublic getObserver<T extends ObserverConstructor>( ObserverConstructor: T ): InstanceType<T> | undefined {\n\t\treturn this._observers.get( ObserverConstructor ) as ( InstanceType<T> | undefined );\n\t}\n\n\t/**\n\t * Disables all added observers.\n\t */\n\tpublic disableObservers(): void {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Enables all added observers.\n\t */\n\tpublic enableObservers(): void {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.enable();\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the page viewport and {@link #domRoots} with their ancestors to reveal the\n\t * caret, **if not already visible to the user**.\n\t *\n\t * **Note**: Calling this method fires the {@link module:engine/view/view~ViewScrollToTheSelectionEvent} event that\n\t * allows custom behaviors.\n\t *\n\t * @param options Additional configuration of the scrolling behavior.\n\t * @param options.viewportOffset A distance between the DOM selection and the viewport boundary to be maintained\n\t * while scrolling to the selection (default is 20px). Setting this value to `0` will reveal the selection precisely at\n\t * the viewport boundary.\n\t * @param options.ancestorOffset A distance between the DOM selection and scrollable DOM root ancestor(s) to be maintained\n\t * while scrolling to the selection (default is 20px). Setting this value to `0` will reveal the selection precisely at\n\t * the scrollable ancestor(s) boundary.\n\t * @param options.alignToTop When set `true`, the DOM selection will be aligned to the top of the viewport if not already visible\n\t * (see `forceScroll` to learn more).\n\t * @param options.forceScroll When set `true`, the DOM selection will be aligned to the top of the viewport and scrollable ancestors\n\t * whether it is already visible or not. This option will only work when `alignToTop` is `true`.\n\t */\n\tpublic scrollToTheSelection<T extends boolean, U extends IfTrue<T>>( {\n\t\talignToTop,\n\t\tforceScroll,\n\t\tviewportOffset = 20,\n\t\tancestorOffset = 20\n\t}: {\n\t\treadonly viewportOffset?: number | { top: number; bottom: number; left: number; right: number };\n\t\treadonly ancestorOffset?: number;\n\t\treadonly alignToTop?: T;\n\t\treadonly forceScroll?: U;\n\t} = {} ): void {\n\t\tconst range = this.document.selection.getFirstRange();\n\n\t\tif ( !range ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clone to make sure properties like `viewportOffset` are not mutated in the event listeners.\n\t\tconst originalArgs = cloneDeep( { alignToTop, forceScroll, viewportOffset, ancestorOffset } );\n\n\t\tif ( typeof viewportOffset === 'number' ) {\n\t\t\tviewportOffset = {\n\t\t\t\ttop: viewportOffset,\n\t\t\t\tbottom: viewportOffset,\n\t\t\t\tleft: viewportOffset,\n\t\t\t\tright: viewportOffset\n\t\t\t};\n\t\t}\n\n\t\tconst options = {\n\t\t\ttarget: this.domConverter.viewRangeToDom( range ),\n\t\t\tviewportOffset,\n\t\t\tancestorOffset,\n\t\t\talignToTop,\n\t\t\tforceScroll\n\t\t};\n\n\t\tthis.fire<ViewScrollToTheSelectionEvent>( 'scrollToTheSelection', options, originalArgs );\n\n\t\tscrollViewportToShowTarget( options );\n\t}\n\n\t/**\n\t * It will focus DOM element representing {@link module:engine/view/editableelement~EditableElement EditableElement}\n\t * that is currently having selection inside.\n\t */\n\tpublic focus(): void {\n\t\tif ( !this.document.isFocused ) {\n\t\t\tconst editable = this.document.selection.editableElement;\n\n\t\t\tif ( editable ) {\n\t\t\t\tthis.domConverter.focus( editable );\n\t\t\t\tthis.forceRender();\n\t\t\t} else {\n\t\t\t\t// Before focusing view document, selection should be placed inside one of the view's editables.\n\t\t\t\t// Normally its selection will be converted from model document (which have default selection), but\n\t\t\t\t// when using view document on its own, we need to manually place selection before focusing it.\n\t\t\t\t//\n\t\t\t\t// @if CK_DEBUG // console.warn( 'There is no selection in any editable to focus.' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The `change()` method is the primary way of changing the view. You should use it to modify any node in the view tree.\n\t * It makes sure that after all changes are made the view is rendered to the DOM (assuming that the view will be changed\n\t * inside the callback). It prevents situations when the DOM is updated when the view state is not yet correct. It allows\n\t * to nest calls one inside another and still performs a single rendering after all those changes are made.\n\t * It also returns the return value of its callback.\n\t *\n\t * ```ts\n\t * const text = view.change( writer => {\n\t * \tconst newText = writer.createText( 'foo' );\n\t * \twriter.insert( position1, newText );\n\t *\n\t * \tview.change( writer => {\n\t * \t\twriter.insert( position2, writer.createText( 'bar' ) );\n\t * \t} );\n\t *\n\t * \twriter.remove( range );\n\t *\n\t * \treturn newText;\n\t * } );\n\t * ```\n\t *\n\t * When the outermost change block is done and rendering to the DOM is over the\n\t * {@link module:engine/view/view~View#event:render `View#render`} event is fired.\n\t *\n\t * This method throws a `applying-view-changes-on-rendering` error when\n\t * the change block is used after rendering to the DOM has started.\n\t *\n\t * @param callback Callback function which may modify the view.\n\t * @returns Value returned by the callback.\n\t */\n\tpublic change<TReturn>( callback: ( writer: DowncastWriter ) => TReturn ): TReturn {\n\t\tif ( this.isRenderingInProgress || this._postFixersInProgress ) {\n\t\t\t/**\n\t\t\t * Thrown when there is an attempt to make changes to the view tree when it is in incorrect state. This may\n\t\t\t * cause some unexpected behaviour and inconsistency between the DOM and the view.\n\t\t\t * This may be caused by:\n\t\t\t *\n\t\t\t * * calling {@link module:engine/view/view~View#change} or {@link module:engine/view/view~View#forceRender} during rendering\n\t\t\t * process,\n\t\t\t * * calling {@link module:engine/view/view~View#change} or {@link module:engine/view/view~View#forceRender} inside of\n\t\t\t *   {@link module:engine/view/document~Document#registerPostFixer post-fixer function}.\n\t\t\t *\n\t\t\t * @error cannot-change-view-tree\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'cannot-change-view-tree',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\t// Recursive call to view.change() method - execute listener immediately.\n\t\t\tif ( this._ongoingChange ) {\n\t\t\t\treturn callback( this._writer );\n\t\t\t}\n\n\t\t\t// This lock will assure that all recursive calls to view.change() will end up in same block - one \"render\"\n\t\t\t// event for all nested calls.\n\t\t\tthis._ongoingChange = true;\n\t\t\tconst callbackResult = callback( this._writer );\n\t\t\tthis._ongoingChange = false;\n\n\t\t\t// This lock is used by editing controller to render changes from outer most model.change() once. As plugins might call\n\t\t\t// view.change() inside model.change() block - this will ensures that postfixers and rendering are called once after all\n\t\t\t// changes. Also, we don't need to render anything if there're no changes since last rendering.\n\t\t\tif ( !this._renderingDisabled && this._hasChangedSinceTheLastRendering ) {\n\t\t\t\tthis._postFixersInProgress = true;\n\t\t\t\tthis.document._callPostFixers( this._writer );\n\t\t\t\tthis._postFixersInProgress = false;\n\n\t\t\t\tthis.fire<ViewRenderEvent>( 'render' );\n\t\t\t}\n\n\t\t\treturn callbackResult;\n\t\t} catch ( err: any ) {\n\t\t\t// @if CK_DEBUG // throw err;\n\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\tCKEditorError.rethrowUnexpectedError( err, this );\n\t\t}\n\t}\n\n\t/**\n\t * Forces rendering {@link module:engine/view/document~Document view document} to DOM. If any view changes are\n\t * currently in progress, rendering will start after all {@link #change change blocks} are processed.\n\t *\n\t * Note that this method is dedicated for special cases. All view changes should be wrapped in the {@link #change}\n\t * block and the view will automatically check whether it needs to render DOM or not.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `applying-view-changes-on-rendering` when\n\t * trying to re-render when rendering to DOM has already started.\n\t */\n\tpublic forceRender(): void {\n\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\tthis.getObserver( FocusObserver ).flush();\n\t\tthis.change( () => {} );\n\t}\n\n\t/**\n\t * Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t */\n\tpublic destroy(): void {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.destroy();\n\t\t}\n\n\t\tthis.document.destroy();\n\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tpublic createPositionAt( itemOrPosition: Item | Position, offset?: PositionOffset ): Position {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param item View item after which the position should be located.\n\t */\n\tpublic createPositionAfter( item: Item ): Position {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param item View item before which the position should be located.\n\t */\n\tpublic createPositionBefore( item: Item ): Position {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */\n\tpublic createRange( start: Position, end?: Position | null ): Range {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t */\n\tpublic createRangeOn( item: Item ): Range {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic createRangeIn( element: Element ): Range {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t * Creates new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * ```ts\n\t * // Creates collapsed selection at the position of given item and offset.\n\t * const paragraph = view.createContainerElement( 'paragraph' );\n\t * const selection = view.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = view.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = view.createSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection`'s factory method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = view.createSelection( paragraph, 'in', { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = view.createSelection( element, 'in', { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:SELECTABLE `createSelection( selectable, options )`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic createSelection( selectable: Node, placeOrOffset: PlaceOrOffset, options?: SelectionOptions ): Selection;\n\n\t/**\n\t * Creates new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = view.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = view.createRange( start, end );\n\t * const selection = view.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ view.createRange( start1, end2 ), view.createRange( star2, end2 ) ];\n\t * const selection = view.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * const otherSelection = view.createSelection();\n\t * const selection = view.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the document selection.\n\t * const selection = view.createSelection( editor.editing.view.document.selection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = view.createPositionFromPath( root, path );\n\t * const selection = view.createSelection( position );\n\t * ```\n\t *\n\t * `Selection`'s factory method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = view.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = view.createSelection( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:NODE_OFFSET `createSelection( node, placeOrOffset, options )`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic createSelection( selectable?: Exclude<Selectable, Node>, options?: SelectionOptions ): Selection;\n\n\tpublic createSelection( ...args: ConstructorParameters<typeof Selection> ): Selection {\n\t\treturn new Selection( ...args );\n\t}\n\n\t/**\n\t * Disables or enables rendering. If the flag is set to `true` then the rendering will be disabled.\n\t * If the flag is set to `false` and if there was some change in the meantime, then the rendering action will be performed.\n\t *\n\t * @internal\n\t * @param flag A flag indicates whether the rendering should be disabled.\n\t */\n\tpublic _disableRendering( flag: boolean ): void {\n\t\tthis._renderingDisabled = flag;\n\n\t\tif ( flag == false ) {\n\t\t\t// Render when you stop blocking rendering.\n\t\t\tthis.change( () => {} );\n\t\t}\n\t}\n\n\t/**\n\t * Renders all changes. In order to avoid triggering the observers (e.g. selection) all observers are disabled\n\t * before rendering and re-enabled after that.\n\t */\n\tprivate _render(): void {\n\t\tthis.isRenderingInProgress = true;\n\t\tthis.disableObservers();\n\t\tthis._renderer.render();\n\t\tthis.enableObservers();\n\t\tthis.isRenderingInProgress = false;\n\t}\n}\n\n/**\n * Fired after a topmost {@link module:engine/view/view~View#change change block} and all\n * {@link module:engine/view/document~Document#registerPostFixer post-fixers} are executed.\n *\n * Actual rendering is performed as a first listener on 'normal' priority.\n *\n * ```ts\n * view.on( 'render', () => {\n * \t// Rendering to the DOM is complete.\n * } );\n * ```\n *\n * This event is useful when you want to update interface elements after the rendering, e.g. position of the\n * balloon panel. If you wants to change view structure use\n * {@link module:engine/view/document~Document#registerPostFixer post-fixers}.\n *\n * @eventName ~View#render\n */\nexport type ViewRenderEvent = {\n\tname: 'render';\n\targs: [];\n};\n\n/**\n * An event fired at the moment of {@link module:engine/view/view~View#scrollToTheSelection} being called. It\n * carries two objects in its payload (`args`):\n *\n * * The first argument is the {@link module:engine/view/view~ViewScrollToTheSelectionEventData object containing data} that gets\n *   passed down to the {@link module:utils/dom/scroll~scrollViewportToShowTarget} helper. If some event listener modifies it, it can\n *   adjust the behavior of the scrolling (e.g. include additional `viewportOffset`).\n * * The second argument corresponds to the original arguments passed to {@link module:utils/dom/scroll~scrollViewportToShowTarget}.\n *   It allows listeners to re-execute the `scrollViewportToShowTarget()` method with its original arguments if there is such a need,\n *   for instance, if the integration requires re–scrolling after certain interaction.\n *\n * @eventName ~View#scrollToTheSelection\n */\nexport type ViewScrollToTheSelectionEvent = {\n\tname: 'scrollToTheSelection';\n\targs: [\n\t\tViewScrollToTheSelectionEventData,\n\t\tParameters<View[ 'scrollToTheSelection' ]>[ 0 ]\n\t];\n};\n\n/**\n * An object passed down to the {@link module:utils/dom/scroll~scrollViewportToShowTarget} helper while calling\n * {@link module:engine/view/view~View#scrollToTheSelection}.\n */\nexport type ViewScrollToTheSelectionEventData = {\n\ttarget: DomRange;\n\tviewportOffset: { top: number; bottom: number; left: number; right: number };\n\tancestorOffset: number;\n\talignToTop?: boolean;\n\tforceScroll?: boolean;\n};\n\n/**\n * Observers that are always registered.\n */\nexport type AlwaysRegisteredObservers =\n\t| typeof MutationObserver\n\t| typeof FocusObserver\n\t| typeof SelectionObserver\n\t| typeof KeyObserver\n\t| typeof FakeSelectionObserver\n\t| typeof CompositionObserver\n\t| typeof ArrowKeysObserver\n\t| typeof InputObserver\n\t| typeof TabObserver;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/typecheckable\n */\n\nimport type { Marker } from './markercollection.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type DocumentSelection from './documentselection.js';\nimport type Element from './element.js';\nimport type LivePosition from './liveposition.js';\nimport type LiveRange from './liverange.js';\nimport type Node from './node.js';\nimport type Position from './position.js';\nimport type Range from './range.js';\nimport type RootElement from './rootelement.js';\nimport type Selection from './selection.js';\nimport type Text from './text.js';\nimport type TextProxy from './textproxy.js';\n\nexport default abstract class TypeCheckable {\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/node~Node} or its subclass.\n\t *\n\t * This method is useful when processing model objects that are of unknown type. For example, a function\n\t * may return a {@link module:engine/model/documentfragment~DocumentFragment} or a {@link module:engine/model/node~Node}\n\t * that can be either a text node or an element. This method can be used to check what kind of object is returned.\n\t *\n\t * ```ts\n\t * someObject.is( 'element' ); // -> true if this is an element\n\t * someObject.is( 'node' ); // -> true if this is a node (a text node or an element)\n\t * someObject.is( 'documentFragment' ); // -> true if this is a document fragment\n\t * ```\n\t *\n\t * Since this method is also available on a range of view objects, you can prefix the type of the object with\n\t * `model:` or `view:` to check, for example, if this is the model's or view's element:\n\t *\n\t * ```ts\n\t * modelElement.is( 'model:element' ); // -> true\n\t * modelElement.is( 'view:element' ); // -> false\n\t * ```\n\t *\n\t * By using this method it is also possible to check a name of an element:\n\t *\n\t * ```ts\n\t * imageElement.is( 'element', 'imageBlock' ); // -> true\n\t * imageElement.is( 'element', 'imageBlock' ); // -> same as above\n\t * imageElement.is( 'model:element', 'imageBlock' ); // -> same as above, but more precise\n\t * ```\n\t *\n\t * @label NODE\n\t */\n\tpublic is( type: 'node' | 'model:node' ): this is Node | Element | Text | RootElement;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/element~Element} or its subclass.\n\t *\n\t * ```ts\n\t * element.is( 'element' ); // -> true\n\t * element.is( 'node' ); // -> true\n\t * element.is( 'model:element' ); // -> true\n\t * element.is( 'model:node' ); // -> true\n\t *\n\t * element.is( 'view:element' ); // -> false\n\t * element.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is an element, you can also check its\n\t * {@link module:engine/model/element~Element#name name}:\n\t *\n\t * ```ts\n\t * element.is( 'element', 'imageBlock' ); // -> true if this is an <imageBlock> element\n\t * text.is( 'element', 'imageBlock' ); -> false\n\t * ```\n\t *\n\t * @label ELEMENT\n\t */\n\tpublic is( type: 'element' | 'model:element' ): this is Element | RootElement;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/rootelement~RootElement}.\n\t *\n\t * ```ts\n\t * rootElement.is( 'rootElement' ); // -> true\n\t * rootElement.is( 'element' ); // -> true\n\t * rootElement.is( 'node' ); // -> true\n\t * rootElement.is( 'model:rootElement' ); // -> true\n\t * rootElement.is( 'model:element' ); // -> true\n\t * rootElement.is( 'model:node' ); // -> true\n\t *\n\t * rootElement.is( 'view:element' ); // -> false\n\t * rootElement.is( 'documentFragment' ); // -> false\n\t * ```\n\t *\n\t * Assuming that the object being checked is an element, you can also check its\n\t * {@link module:engine/model/element~Element#name name}:\n\t *\n\t * ```ts\n\t * rootElement.is( 'rootElement', '$root' ); // -> same as above\n\t * ```\n\t *\n\t * @label ROOT_ELEMENT\n\t */\n\tpublic is( type: 'rootElement' | 'model:rootElement' ): this is RootElement;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/text~Text}.\n\t *\n\t * ```ts\n\t * text.is( '$text' ); // -> true\n\t * text.is( 'node' ); // -> true\n\t * text.is( 'model:$text' ); // -> true\n\t * text.is( 'model:node' ); // -> true\n\t *\n\t * text.is( 'view:$text' ); // -> false\n\t * text.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * **Note:** Until version 20.0.0 this method wasn't accepting `'$text'` type. The legacy `'text'` type is still\n\t * accepted for backward compatibility.\n\t *\n\t * @label TEXT\n\t */\n\tpublic is( type: '$text' | 'model:$text' ): this is Text;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/position~Position} or its subclass.\n\t *\n\t * ```ts\n\t * position.is( 'position' ); // -> true\n\t * position.is( 'model:position' ); // -> true\n\t *\n\t * position.is( 'view:position' ); // -> false\n\t * position.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * @label POSITION\n\t */\n\tpublic is( type: 'position' | 'model:position' ): this is Position | LivePosition;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/liveposition~LivePosition}.\n\t *\n\t * ```ts\n\t * livePosition.is( 'position' ); // -> true\n\t * livePosition.is( 'model:position' ); // -> true\n\t * livePosition.is( 'liveposition' ); // -> true\n\t * livePosition.is( 'model:livePosition' ); // -> true\n\t *\n\t * livePosition.is( 'view:position' ); // -> false\n\t * livePosition.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * @label LIVE_POSITION\n\t */\n\tpublic is( type: 'livePosition' | 'model:livePosition' ): this is LivePosition;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/range~Range} or its subclass.\n\t *\n\t * ```ts\n\t * range.is( 'range' ); // -> true\n\t * range.is( 'model:range' ); // -> true\n\t *\n\t * range.is( 'view:range' ); // -> false\n\t * range.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * @label RANGE\n\t */\n\tpublic is( type: 'range' | 'model:range' ): this is Range | LiveRange;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/liverange~LiveRange}.\n\t *\n\t * ```ts\n\t * liveRange.is( 'range' ); // -> true\n\t * liveRange.is( 'model:range' ); // -> true\n\t * liveRange.is( 'liveRange' ); // -> true\n\t * liveRange.is( 'model:liveRange' ); // -> true\n\t *\n\t * liveRange.is( 'view:range' ); // -> false\n\t * liveRange.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * @label LIVE_RANGE\n\t */\n\tpublic is( type: 'liveRange' | 'model:liveRange' ): this is LiveRange;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/documentfragment~DocumentFragment}.\n\t *\n\t * ```ts\n\t * docFrag.is( 'documentFragment' ); // -> true\n\t * docFrag.is( 'model:documentFragment' ); // -> true\n\t *\n\t * docFrag.is( 'view:documentFragment' ); // -> false\n\t * docFrag.is( 'element' ); // -> false\n\t * docFrag.is( 'node' ); // -> false\n\t * ```\n\t *\n\t * @label DOCUMENT_FRAGMENT\n\t */\n\tpublic is( type: 'documentFragment' | 'model:documentFragment' ): this is DocumentFragment;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/selection~Selection}\n\t * or {@link module:engine/model/documentselection~DocumentSelection}.\n\t *\n\t * ```ts\n\t * selection.is( 'selection' ); // -> true\n\t * selection.is( 'model:selection' ); // -> true\n\t *\n\t * selection.is( 'view:selection' ); // -> false\n\t * selection.is( 'range' ); // -> false\n\t * ```\n\t *\n\t * @label SELECTION\n\t */\n\tpublic is( type: 'selection' | 'model:selection' ): this is Selection | DocumentSelection;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/documentselection~DocumentSelection}.\n\t *\n\t * ```ts\n\t * selection.is( 'selection' ); // -> true\n\t * selection.is( 'documentSelection' ); // -> true\n\t * selection.is( 'model:selection' ); // -> true\n\t * selection.is( 'model:documentSelection' ); // -> true\n\t *\n\t * selection.is( 'view:selection' ); // -> false\n\t * selection.is( 'element' ); // -> false\n\t * selection.is( 'node' ); // -> false\n\t * ```\n\t *\n\t * @label DOCUMENT_SELECTION\n\t */\n\tpublic is( type: 'documentSelection' | 'model:documentSelection' ): this is DocumentSelection;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/markercollection~Marker}.\n\t *\n\t * ```ts\n\t * marker.is( 'marker' ); // -> true\n\t * marker.is( 'model:marker' ); // -> true\n\t *\n\t * marker.is( 'view:element' ); // -> false\n\t * marker.is( 'documentSelection' ); // -> false\n\t * ```\n\t *\n\t * @label MARKER\n\t */\n\tpublic is( type: 'marker' | 'model:marker' ): this is Marker;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/textproxy~TextProxy}.\n\t *\n\t * ```ts\n\t * textProxy.is( '$textProxy' ); // -> true\n\t * textProxy.is( 'model:$textProxy' ); // -> true\n\t *\n\t * textProxy.is( 'view:$textProxy' ); // -> false\n\t * textProxy.is( 'range' ); // -> false\n\t * ```\n\t *\n\t * **Note:** Until version 20.0.0 this method wasn't accepting `'$textProxy'` type. The legacy `'textProxt'` type is still\n\t * accepted for backward compatibility.\n\t *\n\t * @label TEXT_PROXY\n\t */\n\tpublic is( type: '$textProxy' | 'model:$textProxy' ): this is TextProxy;\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/element~Element} or its subclass and has the specified `name`.\n\t *\n\t * ```ts\n\t * element.is( 'element', 'imageBlock' ); // -> true if this is an <imageBlock> element\n\t * text.is( 'element', 'imageBlock' ); -> false\n\t * ```\n\t *\n\t * @label ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'element' | 'model:element', name: N ): this is ( Element | RootElement ) & { name: N };\n\n\t/**\n\t * Checks whether the object is of type {@link module:engine/model/rootelement~RootElement} and has the specified `name`.\n\t *\n\t * ```ts\n\t * rootElement.is( 'rootElement', '$root' );\n\t * ```\n\t *\n\t * @label ROOT_ELEMENT_NAME\n\t */\n\tpublic is<N extends string>( type: 'rootElement' | 'model:rootElement', name: N ): this is RootElement & { name: N };\n\n\t/* istanbul ignore next -- @preserve */\n\tpublic is(): boolean {\n\t\t// There are a lot of overloads above.\n\t\t// Overriding method in derived classes remove them and only `is( type: string ): boolean` is visible which we don't want.\n\t\t// One option would be to copy them all to all classes, but that's ugly.\n\t\t// It's best when TypeScript compiler doesn't see those overloads, except the one in the top base class.\n\t\t// To overload a method, but not let the compiler see it, do after class definition:\n\t\t// `MyClass.prototype.is = function( type: string ) {...}`\n\t\tthrow new Error( 'is() method is abstract' );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/**\n * @module engine/model/node\n */\n\nimport TypeCheckable from './typecheckable.js';\n\nimport type Document from './document.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\n\nimport { CKEditorError, compareArrays, toMap } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Model node. Most basic structure of model tree.\n *\n * This is an abstract class that is a base for other classes representing different nodes in model.\n *\n * **Note:** If a node is detached from the model tree, you can manipulate it using it's API.\n * However, it is **very important** that nodes already attached to model tree should be only changed through\n * {@link module:engine/model/writer~Writer Writer API}.\n *\n * Changes done by `Node` methods, like {@link module:engine/model/element~Element#_insertChild _insertChild} or\n * {@link module:engine/model/node~Node#_setAttribute _setAttribute}\n * do not generate {@link module:engine/model/operation/operation~Operation operations}\n * which are essential for correct editor work if you modify nodes in {@link module:engine/model/document~Document document} root.\n *\n * The flow of working on `Node` (and classes that inherits from it) is as such:\n * 1. You can create a `Node` instance, modify it using it's API.\n * 2. Add `Node` to the model using `Batch` API.\n * 3. Change `Node` that was already added to the model using `Batch` API.\n *\n * Similarly, you cannot use `Batch` API on a node that has not been added to the model tree, with the exception\n * of {@link module:engine/model/writer~Writer#insert inserting} that node to the model tree.\n *\n * Be aware that using {@link module:engine/model/writer~Writer#remove remove from Batch API} does not allow to use `Node` API because\n * the information about `Node` is still kept in model document.\n *\n * In case of {@link module:engine/model/element~Element element node}, adding and removing children also counts as changing a node and\n * follows same rules.\n */\nexport default abstract class Node extends TypeCheckable {\n\t/**\n\t * Parent of this node. It could be {@link module:engine/model/element~Element}\n\t * or {@link module:engine/model/documentfragment~DocumentFragment}.\n\t * Equals to `null` if the node has no parent.\n\t */\n\tpublic readonly parent: Element | DocumentFragment | null = null;\n\n\t/**\n\t * Unique root name used to identify this root element by {@link module:engine/model/document~Document}.\n\t */\n\tdeclare public readonly rootName: string | undefined;\n\n\t/**\n\t * Attributes set on this node.\n\t */\n\tprivate _attrs: Map<string, unknown>;\n\n\t/**\n\t * Index of this node in its parent or `null` if the node has no parent.\n\t *\n\t * @internal\n\t */\n\tpublic _index: number | null = null;\n\n\t/**\n\t * Offset at which this node starts in its parent or `null` if the node has no parent.\n\t *\n\t * @internal\n\t */\n\tpublic _startOffset: number | null = null;\n\n\t/**\n\t * Creates a model node.\n\t *\n\t * This is an abstract class, so this constructor should not be used directly.\n\t *\n\t * @param attrs Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\tconstructor( attrs?: NodeAttributes ) {\n\t\tsuper();\n\n\t\tthis._attrs = toMap( attrs! );\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns this root element.\n\t */\n\tpublic get document(): Document | null {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Index of this node in its parent or `null` if the node has no parent.\n\t */\n\tpublic get index(): number | null {\n\t\treturn this._index;\n\t}\n\n\t/**\n\t * Offset at which this node starts in its parent. It is equal to the sum of {@link #offsetSize offsetSize}\n\t * of all its previous siblings. Equals to `null` if node has no parent.\n\t */\n\tpublic get startOffset(): number | null {\n\t\treturn this._startOffset;\n\t}\n\n\t/**\n\t * Offset size of this node.\n\t *\n\t * Represents how much \"offset space\" is occupied by the node in its parent. It is important for\n\t * {@link module:engine/model/position~Position position}. When node has `offsetSize` greater than `1`, position can be placed between\n\t * that node start and end. `offsetSize` greater than `1` is for nodes that represents more than one entity, i.e.\n\t * a {@link module:engine/model/text~Text text node}.\n\t */\n\tpublic get offsetSize(): number {\n\t\treturn 1;\n\t}\n\n\t/**\n\t * Offset at which this node ends in its parent. It is equal to the sum of this node's\n\t * {@link module:engine/model/node~Node#startOffset start offset} and {@link #offsetSize offset size}.\n\t * Equals to `null` if the node has no parent.\n\t */\n\tpublic get endOffset(): number | null {\n\t\tif ( this.startOffset === null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.startOffset + this.offsetSize;\n\t}\n\n\t/**\n\t * Node's next sibling or `null` if the node is a last child of it's parent or if the node has no parent.\n\t */\n\tpublic get nextSibling(): Node | null {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent!.getChild( index + 1 ) ) || null;\n\t}\n\n\t/**\n\t * Node's previous sibling or `null` if the node is a first child of it's parent or if the node has no parent.\n\t */\n\tpublic get previousSibling(): Node | null {\n\t\tconst index = this.index;\n\n\t\treturn ( index !== null && this.parent!.getChild( index - 1 ) ) || null;\n\t}\n\n\t/**\n\t * The top-most ancestor of the node. If node has no parent it is the root itself. If the node is a part\n\t * of {@link module:engine/model/documentfragment~DocumentFragment}, it's `root` is equal to that `DocumentFragment`.\n\t */\n\tpublic get root(): Node | DocumentFragment {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n\t\tlet root: Node | DocumentFragment = this;\n\n\t\twhile ( root.parent ) {\n\t\t\troot = root.parent;\n\t\t}\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * Returns `true` if the node is inside a document root that is attached to the document.\n\t */\n\tpublic isAttached(): boolean {\n\t\t// If the node has no parent it means that it is a root.\n\t\t// But this is not a `RootElement`, so it means that it is not attached.\n\t\t//\n\t\t// If this is not the root, check if this element's root is attached.\n\t\treturn this.parent === null ? false : this.root.isAttached();\n\t}\n\n\t/**\n\t * Gets path to the node. The path is an array containing starting offsets of consecutive ancestors of this node,\n\t * beginning from {@link module:engine/model/node~Node#root root}, down to this node's starting offset. The path can be used to\n\t * create {@link module:engine/model/position~Position Position} instance.\n\t *\n\t * ```ts\n\t * const abc = new Text( 'abc' );\n\t * const foo = new Text( 'foo' );\n\t * const h1 = new Element( 'h1', null, new Text( 'header' ) );\n\t * const p = new Element( 'p', null, [ abc, foo ] );\n\t * const div = new Element( 'div', null, [ h1, p ] );\n\t * foo.getPath(); // Returns [ 1, 3 ]. `foo` is in `p` which is in `div`. `p` starts at offset 1, while `foo` at 3.\n\t * h1.getPath(); // Returns [ 0 ].\n\t * div.getPath(); // Returns [].\n\t * ```\n\t */\n\tpublic getPath(): Array<number> {\n\t\tconst path = [];\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n\t\tlet node: Node | DocumentFragment = this;\n\n\t\twhile ( node.parent ) {\n\t\t\tpath.unshift( node.startOffset! );\n\t\t\tnode = node.parent;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this node.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this node will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from node's parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */\n\tpublic getAncestors( options: { includeSelf?: boolean; parentFirst?: boolean } = {} ): Array<Node | DocumentFragment> {\n\t\tconst ancestors: Array<Node | DocumentFragment> = [];\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Returns a {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both nodes.\n\t *\n\t * @param node The second node.\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` both nodes will be considered \"ancestors\" too.\n\t * Which means that if e.g. node A is inside B, then their common ancestor will be B.\n\t */\n\tpublic getCommonAncestor( node: Node, options: { includeSelf?: boolean } = {} ): Element | DocumentFragment | null {\n\t\tconst ancestorsA = this.getAncestors( options );\n\t\tconst ancestorsB = node.getAncestors( options );\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ] as ( Element | DocumentFragment );\n\t}\n\n\t/**\n\t * Returns whether this node is before given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/model/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */\n\tpublic isBefore( node: Node ): boolean {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst thisPath = this.getPath();\n\t\tconst nodePath = node.getPath();\n\n\t\tconst result = compareArrays( thisPath, nodePath );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'prefix':\n\t\t\t\treturn true;\n\n\t\t\tcase 'extension':\n\t\t\t\treturn false;\n\n\t\t\tdefault:\n\t\t\t\treturn thisPath[ result as number ] < nodePath[ result as number ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns whether this node is after given node. `false` is returned if nodes are in different trees (for example,\n\t * in different {@link module:engine/model/documentfragment~DocumentFragment}s).\n\t *\n\t * @param node Node to compare with.\n\t */\n\tpublic isAfter( node: Node ): boolean {\n\t\t// Given node is not before this node if they are same.\n\t\tif ( this == node ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Return `false` if it is impossible to compare nodes.\n\t\tif ( this.root !== node.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// In other cases, just check if the `node` is before, and return the opposite.\n\t\treturn !this.isBefore( node );\n\t}\n\n\t/**\n\t * Checks if the node has an attribute with given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on node, `false` otherwise.\n\t */\n\tpublic hasAttribute( key: string ): boolean {\n\t\treturn this._attrs.has( key );\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on node.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */\n\tpublic getAttribute( key: string ): unknown {\n\t\treturn this._attrs.get( key );\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */\n\tpublic getAttributes(): IterableIterator<[ string, unknown ]> {\n\t\treturn this._attrs.entries();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t */\n\tpublic getAttributeKeys(): IterableIterator<string> {\n\t\treturn this._attrs.keys();\n\t}\n\n\t/**\n\t * Converts `Node` to plain object and returns it.\n\t *\n\t * @returns `Node` converted to plain object.\n\t */\n\tpublic toJSON(): unknown {\n\t\tconst json: any = {};\n\n\t\t// Serializes attributes to the object.\n\t\t// attributes = { a: 'foo', b: 1, c: true }.\n\t\tif ( this._attrs.size ) {\n\t\t\tjson.attributes = Array.from( this._attrs ).reduce( ( result, attr ) => {\n\t\t\t\tresult[ attr[ 0 ] ] = attr[ 1 ];\n\n\t\t\t\treturn result;\n\t\t\t}, {} as any );\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a copy of this node, that is a node with exactly same attributes, and returns it.\n\t *\n\t * @internal\n\t * @returns Node with same attributes as this node.\n\t */\n\tpublic _clone( _deep?: boolean ): Node {\n\t\treturn new ( this.constructor as any )( this._attrs );\n\t}\n\n\t/**\n\t * Removes this node from its parent.\n\t *\n\t * @internal\n\t * @see module:engine/model/writer~Writer#remove\n\t */\n\tpublic _remove(): void {\n\t\tthis.parent!._removeChildren( this.index! );\n\t}\n\n\t/**\n\t * Sets attribute on the node. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * @see module:engine/model/writer~Writer#setAttribute\n\t * @internal\n\t * @param key Key of attribute to set.\n\t * @param value Attribute value.\n\t */\n\tpublic _setAttribute( key: string, value: unknown ): void {\n\t\tthis._attrs.set( key, value );\n\t}\n\n\t/**\n\t * Removes all attributes from the node and sets given attributes.\n\t *\n\t * @see module:engine/model/writer~Writer#setAttributes\n\t * @internal\n\t * @param attrs Attributes to set. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\tpublic _setAttributesTo( attrs: NodeAttributes ): void {\n\t\tthis._attrs = toMap( attrs );\n\t}\n\n\t/**\n\t * Removes an attribute with given key from the node.\n\t *\n\t * @see module:engine/model/writer~Writer#removeAttribute\n\t * @internal\n\t * @param key Key of attribute to remove.\n\t * @returns `true` if the attribute was set on the element, `false` otherwise.\n\t */\n\tpublic _removeAttribute( key: string ): boolean {\n\t\treturn this._attrs.delete( key );\n\t}\n\n\t/**\n\t * Removes all attributes from the node.\n\t *\n\t * @see module:engine/model/writer~Writer#clearAttributes\n\t * @internal\n\t */\n\tpublic _clearAttributes(): void {\n\t\tthis._attrs.clear();\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nNode.prototype.is = function( type: string ): boolean {\n\treturn type === 'node' || type === 'model:node';\n};\n\n/**\n * Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n */\nexport type NodeAttributes = Record<string, unknown> | Iterable<[ string, unknown ]>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/nodelist\n */\n\nimport Node from './node.js';\n\nimport { CKEditorError, spliceArray } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Provides an interface to operate on a list of {@link module:engine/model/node~Node nodes}. `NodeList` is used internally\n * in classes like {@link module:engine/model/element~Element Element}\n * or {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment}.\n */\nexport default class NodeList implements Iterable<Node> {\n\t/**\n\t * Nodes contained in this node list.\n\t */\n\tprivate _nodes: Array<Node> = [];\n\n\t/**\n\t * This array maps numbers (offsets) to node that is placed at that offset.\n\t *\n\t * This array is similar to `_nodes` with the difference that one node may occupy multiple consecutive items in the array.\n\t *\n\t * This array is needed to quickly retrieve a node that is placed at given offset.\n\t */\n\tprivate _offsetToNode: Array<Node> = [];\n\n\t/**\n\t * Creates a node list.\n\t *\n\t * @internal\n\t * @param nodes Nodes contained in this node list.\n\t */\n\tconstructor( nodes?: Iterable<Node> ) {\n\t\tif ( nodes ) {\n\t\t\tthis._insertNodes( 0, nodes );\n\t\t}\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all nodes contained inside this node list.\n\t */\n\tpublic [ Symbol.iterator ](): IterableIterator<Node> {\n\t\treturn this._nodes[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Number of nodes contained inside this node list.\n\t */\n\tpublic get length(): number {\n\t\treturn this._nodes.length;\n\t}\n\n\t/**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all nodes contained inside this node list.\n\t */\n\tpublic get maxOffset(): number {\n\t\treturn this._offsetToNode.length;\n\t}\n\n\t/**\n\t * Gets the node at the given index. Returns `null` if incorrect index was passed.\n\t */\n\tpublic getNode( index: number ): Node | null {\n\t\treturn this._nodes[ index ] || null;\n\t}\n\n\t/**\n\t * Gets the node at the given offset. Returns `null` if incorrect offset was passed.\n\t */\n\tpublic getNodeAtOffset( offset: number ): Node | null {\n\t\treturn this._offsetToNode[ offset ] || null;\n\t}\n\n\t/**\n\t * Returns an index of the given node or `null` if given node does not have a parent.\n\t *\n\t * This is an alias to {@link module:engine/model/node~Node#index}.\n\t */\n\tpublic getNodeIndex( node: Node ): number | null {\n\t\treturn node.index;\n\t}\n\n\t/**\n\t * Returns the offset at which given node is placed in its parent or `null` if given node does not have a parent.\n\t *\n\t * This is an alias to {@link module:engine/model/node~Node#startOffset}.\n\t */\n\tpublic getNodeStartOffset( node: Node ): number | null {\n\t\treturn node.startOffset;\n\t}\n\n\t/**\n\t * Converts index to offset in node list.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `model-nodelist-index-out-of-bounds` if given index is less\n\t * than `0` or more than {@link #length}.\n\t */\n\tpublic indexToOffset( index: number ): number {\n\t\tif ( index == this._nodes.length ) {\n\t\t\treturn this.maxOffset;\n\t\t}\n\n\t\tconst node = this._nodes[ index ];\n\n\t\tif ( !node ) {\n\t\t\t/**\n\t\t\t * Given index cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error model-nodelist-index-out-of-bounds\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-nodelist-index-out-of-bounds', this );\n\t\t}\n\n\t\treturn this.getNodeStartOffset( node )!;\n\t}\n\n\t/**\n\t * Converts offset in node list to index.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `model-nodelist-offset-out-of-bounds` if given offset is less\n\t * than `0` or more than {@link #maxOffset}.\n\t */\n\tpublic offsetToIndex( offset: number ): number {\n\t\tif ( offset == this._offsetToNode.length ) {\n\t\t\treturn this._nodes.length;\n\t\t}\n\n\t\tconst node = this._offsetToNode[ offset ];\n\n\t\tif ( !node ) {\n\t\t\t/**\n\t\t\t * Given offset cannot be found in the node list.\n\t\t\t *\n\t\t\t * @error model-nodelist-offset-out-of-bounds\n\t\t\t * @param offset\n\t\t\t * @param nodeList Stringified node list.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-nodelist-offset-out-of-bounds',\n\t\t\t\tthis,\n\t\t\t\t{\n\t\t\t\t\toffset,\n\t\t\t\t\tnodeList: this\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\treturn this.getNodeIndex( node )!;\n\t}\n\n\t/**\n\t * Inserts given nodes at given index.\n\t *\n\t * @internal\n\t * @param index Index at which nodes should be inserted.\n\t * @param nodes Nodes to be inserted.\n\t */\n\tpublic _insertNodes( index: number, nodes: Iterable<Node> ): void {\n\t\t// Validation.\n\t\tfor ( const node of nodes ) {\n\t\t\tif ( !( node instanceof Node ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to insert an object which is not a Node instance.\n\t\t\t\t *\n\t\t\t\t * @error model-nodelist-insertnodes-not-node\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'model-nodelist-insertnodes-not-node', this );\n\t\t\t}\n\t\t}\n\n\t\tconst nodesArray = Array.from( nodes );\n\t\tconst offsetsArray = makeOffsetsArray( nodesArray );\n\n\t\tlet offset = this.indexToOffset( index );\n\n\t\t// Splice nodes array and offsets array into the nodelist.\n\t\tthis._nodes = spliceArray<Node>( this._nodes, nodesArray, index, 0 );\n\t\tthis._offsetToNode = spliceArray<Node>( this._offsetToNode, offsetsArray, offset, 0 );\n\n\t\t// Refresh indexes and offsets for nodes inside this node list. We need to do this for all inserted nodes and all nodes after them.\n\t\tfor ( let i = index; i < this._nodes.length; i++ ) {\n\t\t\tthis._nodes[ i ]._index = i;\n\t\t\tthis._nodes[ i ]._startOffset = offset;\n\n\t\t\toffset += this._nodes[ i ].offsetSize;\n\t\t}\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index.\n\t *\n\t * @internal\n\t * @param indexStart Index of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns Array containing removed nodes.\n\t */\n\tpublic _removeNodes( indexStart: number, howMany: number = 1 ): Array<Node> {\n\t\tif ( howMany == 0 ) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Remove nodes from this nodelist.\n\t\tlet offset = this.indexToOffset( indexStart );\n\t\tconst nodes = this._nodes.splice( indexStart, howMany );\n\n\t\tconst lastNode = nodes[ nodes.length - 1 ];\n\t\tconst removedOffsetSum = lastNode.startOffset! + lastNode.offsetSize - offset;\n\t\tthis._offsetToNode.splice( offset, removedOffsetSum );\n\n\t\t// Reset index and start offset properties for the removed nodes -- they do not have a parent anymore.\n\t\tfor ( const node of nodes ) {\n\t\t\tnode._index = null;\n\t\t\tnode._startOffset = null;\n\t\t}\n\n\t\tfor ( let i = indexStart; i < this._nodes.length; i++ ) {\n\t\t\tthis._nodes[ i ]._index = i;\n\t\t\tthis._nodes[ i ]._startOffset = offset;\n\n\t\t\toffset += this._nodes[ i ].offsetSize;\n\t\t}\n\n\t\treturn nodes;\n\t}\n\n\t/**\n\t * Converts `NodeList` instance to an array containing nodes that were inserted in the node list. Nodes\n\t * are also converted to their plain object representation.\n\t *\n\t * @returns `NodeList` instance converted to `Array`.\n\t */\n\tpublic toJSON(): unknown {\n\t\treturn this._nodes.map( node => node.toJSON() );\n\t}\n}\n\n/**\n * Creates an array of nodes in the format as in {@link module:engine/model/nodelist~NodeList#_offsetToNode}, i.e. one node will\n * occupy multiple items if its offset size is greater than one.\n */\nfunction makeOffsetsArray( nodes: Array<Node> ): Array<Node> {\n\tconst offsets: Array<Node> = [];\n\n\tfor ( const node of nodes ) {\n\t\tconst start = offsets.length;\n\n\t\toffsets.length += node.offsetSize;\n\t\toffsets.fill( node, start );\n\t}\n\n\treturn offsets;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/text\n */\n\nimport Node, { type NodeAttributes } from './node.js';\n\n// @if CK_DEBUG_ENGINE // const { convertMapToStringifiedObject } = require( '../dev-utils/utils' );\n\n/**\n * Model text node. Type of {@link module:engine/model/node~Node node} that contains {@link module:engine/model/text~Text#data text data}.\n *\n * **Important:** see {@link module:engine/model/node~Node} to read about restrictions using `Text` and `Node` API.\n *\n * **Note:** keep in mind that `Text` instances might indirectly got removed from model tree when model is changed.\n * This happens when {@link module:engine/model/writer~Writer model writer} is used to change model and the text node is merged with\n * another text node. Then, both text nodes are removed and a new text node is inserted into the model. Because of\n * this behavior, keeping references to `Text` is not recommended. Instead, consider creating\n * {@link module:engine/model/liveposition~LivePosition live position} placed before the text node.\n */\nexport default class Text extends Node {\n\t/**\n\t * Text data contained in this text node.\n\t *\n\t * @internal\n\t */\n\tpublic _data: string;\n\n\t/**\n\t * Creates a text node.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createText} method instead.\n\t *\n\t * @internal\n\t * @param data Node's text.\n\t * @param attrs Node's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t */\n\tconstructor( data?: string, attrs?: NodeAttributes ) {\n\t\tsuper( attrs );\n\t\tthis._data = data || '';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override get offsetSize(): number {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Returns a text data contained in the node.\n\t */\n\tpublic get data(): string {\n\t\treturn this._data;\n\t}\n\n\t/**\n\t * Converts `Text` instance to plain object and returns it.\n\t *\n\t * @returns`Text` instance converted to plain object.\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.data = this.data;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a copy of this text node and returns it. Created text node has same text data and attributes as original text node.\n\t *\n\t * @internal\n\t * @returns `Text` instance created using given plain object.\n\t */\n\tpublic override _clone(): Text {\n\t\treturn new Text( this.data, this.getAttributes() );\n\t}\n\n\t/**\n\t * Creates a `Text` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param json Plain object to be converted to `Text`.\n\t * @returns `Text` instance created using given plain object.\n\t */\n\tpublic static fromJSON( json: any ): Text {\n\t\treturn new Text( json.data, json.attributes );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `#${ this.data }`;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logExtended(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( `ModelText: ${ this }, attrs: ${ convertMapToStringifiedObject( this.getAttributes() ) }` );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ModelText: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nText.prototype.is = function( type: string ): boolean {\n\treturn type === '$text' || type === 'model:$text' ||\n\t\t// This are legacy values kept for backward compatibility.\n\t\ttype === 'text' || type === 'model:text' ||\n\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\ttype === 'node' || type === 'model:node';\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/textproxy\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type Node from './node.js';\nimport type Text from './text.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\n// @if CK_DEBUG_ENGINE // const { convertMapToStringifiedObject } = require( '../dev-utils/utils' );\n\n/**\n * `TextProxy` represents a part of {@link module:engine/model/text~Text text node}.\n *\n * Since {@link module:engine/model/position~Position positions} can be placed between characters of a text node,\n * {@link module:engine/model/range~Range ranges} may contain only parts of text nodes. When {@link module:engine/model/range~Range#getItems\n * getting items}\n * contained in such range, we need to represent a part of that text node, since returning the whole text node would be incorrect.\n * `TextProxy` solves this issue.\n *\n * `TextProxy` has an API similar to {@link module:engine/model/text~Text Text} and allows to do most of the common tasks performed\n * on model nodes.\n *\n * **Note:** Some `TextProxy` instances may represent whole text node, not just a part of it.\n * See {@link module:engine/model/textproxy~TextProxy#isPartial}.\n *\n * **Note:** `TextProxy` is not an instance of {@link module:engine/model/node~Node node}. Keep this in mind when using it as a\n * parameter of methods.\n *\n * **Note:** `TextProxy` is a readonly interface. If you want to perform changes on model data represented by a `TextProxy`\n * use {@link module:engine/model/writer~Writer model writer API}.\n *\n * **Note:** `TextProxy` instances are created on the fly, basing on the current state of model. Because of this, it is\n * highly unrecommended to store references to `TextProxy` instances. `TextProxy` instances are not refreshed when\n * model changes, so they might get invalidated. Instead, consider creating {@link module:engine/model/liveposition~LivePosition live\n * position}.\n *\n * `TextProxy` instances are created by {@link module:engine/model/treewalker~TreeWalker model tree walker}. You should not need to create\n * an instance of this class by your own.\n */\nexport default class TextProxy extends TypeCheckable {\n\t/**\n\t * Text node which part is represented by this text proxy.\n\t */\n\tpublic readonly textNode: Text;\n\n\t/**\n\t * Text data represented by this text proxy.\n\t */\n\tpublic readonly data: string;\n\n\t/**\n\t * Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy starts.\n\t */\n\tpublic readonly offsetInText: number;\n\n\t/**\n\t * Creates a text proxy.\n\t *\n\t * @internal\n\t * @param textNode Text node which part is represented by this text proxy.\n\t * @param offsetInText Offset in {@link module:engine/model/textproxy~TextProxy#textNode text node} from which the text proxy\n\t * starts.\n\t * @param length Text proxy length, that is how many text node's characters, starting from `offsetInText` it represents.\n\t */\n\tconstructor( textNode: Text, offsetInText: number, length: number ) {\n\t\tsuper();\n\n\t\tthis.textNode = textNode;\n\n\t\tif ( offsetInText < 0 || offsetInText > textNode.offsetSize ) {\n\t\t\t/**\n\t\t\t * Given `offsetInText` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-offsetintext\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-textproxy-wrong-offsetintext', this );\n\t\t}\n\n\t\tif ( length < 0 || offsetInText + length > textNode.offsetSize ) {\n\t\t\t/**\n\t\t\t * Given `length` value is incorrect.\n\t\t\t *\n\t\t\t * @error model-textproxy-wrong-length\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-textproxy-wrong-length', this );\n\t\t}\n\t\tthis.data = textNode.data.substring( offsetInText, offsetInText + length );\n\n\t\tthis.offsetInText = offsetInText;\n\t}\n\n\t/**\n\t * Offset at which this text proxy starts in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#startOffset\n\t */\n\tpublic get startOffset(): number | null {\n\t\treturn this.textNode.startOffset !== null ? this.textNode.startOffset + this.offsetInText : null;\n\t}\n\n\t/**\n\t * Offset size of this text proxy. Equal to the number of characters represented by the text proxy.\n\t *\n\t * @see module:engine/model/node~Node#offsetSize\n\t */\n\tpublic get offsetSize(): number {\n\t\treturn this.data.length;\n\t}\n\n\t/**\n\t * Offset at which this text proxy ends in it's parent.\n\t *\n\t * @see module:engine/model/node~Node#endOffset\n\t */\n\tpublic get endOffset(): number | null {\n\t\treturn this.startOffset !== null ? this.startOffset + this.offsetSize : null;\n\t}\n\n\t/**\n\t * Flag indicating whether `TextProxy` instance covers only part of the original {@link module:engine/model/text~Text text node}\n\t * (`true`) or the whole text node (`false`).\n\t *\n\t * This is `false` when text proxy starts at the very beginning of {@link module:engine/model/textproxy~TextProxy#textNode textNode}\n\t * ({@link module:engine/model/textproxy~TextProxy#offsetInText offsetInText} equals `0`) and text proxy sizes is equal to\n\t * text node size.\n\t */\n\tpublic get isPartial(): boolean {\n\t\treturn this.offsetSize !== this.textNode.offsetSize;\n\t}\n\n\t/**\n\t * Parent of this text proxy, which is same as parent of text node represented by this text proxy.\n\t */\n\tpublic get parent(): Element | DocumentFragment | null {\n\t\treturn this.textNode.parent;\n\t}\n\n\t/**\n\t * Root of this text proxy, which is same as root of text node represented by this text proxy.\n\t */\n\tpublic get root(): Node | DocumentFragment {\n\t\treturn this.textNode.root;\n\t}\n\n\t/**\n\t * Gets path to this text proxy.\n\t *\n\t * @see module:engine/model/node~Node#getPath\n\t */\n\tpublic getPath(): Array<number> {\n\t\tconst path = this.textNode.getPath();\n\n\t\tif ( path.length > 0 ) {\n\t\t\tpath[ path.length - 1 ] += this.offsetInText;\n\t\t}\n\n\t\treturn path;\n\t}\n\n\t/**\n\t * Returns ancestors array of this text proxy.\n\t *\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this text proxy will be also included in parent's array.\n\t * @param options.parentFirst When set to `true`, array will be sorted from text proxy parent to root element,\n\t * otherwise root element will be the first item in the array.\n\t * @returns Array with ancestors.\n\t */\n\tpublic getAncestors( options: {\n\t\tincludeSelf?: boolean;\n\t\tparentFirst?: boolean;\n\t} = {} ): Array<TextProxy | Element | DocumentFragment> {\n\t\tconst ancestors: Array<TextProxy | Element | DocumentFragment> = [];\n\t\tlet parent: TextProxy | Element | DocumentFragment | null = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tancestors[ options.parentFirst ? 'push' : 'unshift' ]( parent );\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn ancestors;\n\t}\n\n\t/**\n\t * Checks if this text proxy has an attribute for given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on text proxy, `false` otherwise.\n\t */\n\tpublic hasAttribute( key: string ): boolean {\n\t\treturn this.textNode.hasAttribute( key );\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on text proxy.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */\n\tpublic getAttribute( key: string ): unknown {\n\t\treturn this.textNode.getAttribute( key );\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attributes. Attributes are returned as arrays containing two\n\t * items. First one is attribute key and second is attribute value.\n\t *\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */\n\tpublic getAttributes(): IterableIterator<[ string, unknown ]> {\n\t\treturn this.textNode.getAttributes();\n\t}\n\n\t/**\n\t * Returns iterator that iterates over this node's attribute keys.\n\t */\n\tpublic getAttributeKeys(): IterableIterator<string> {\n\t\treturn this.textNode.getAttributeKeys();\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `#${ this.data }`;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ModelTextProxy: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logExtended(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( `ModelTextProxy: ${ this }, ` +\n\t// @if CK_DEBUG_ENGINE // \t\t`attrs: ${ convertMapToStringifiedObject( this.getAttributes() ) }` );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nTextProxy.prototype.is = function( type: string ): boolean {\n\treturn type === '$textProxy' || type === 'model:$textProxy' ||\n\t\t// This are legacy values kept for backward compatibility.\n\t\ttype === 'textProxy' || type === 'model:textProxy';\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/element\n */\n\nimport Node, { type NodeAttributes } from './node.js';\nimport NodeList from './nodelist.js';\nimport Text from './text.js';\nimport TextProxy from './textproxy.js';\n\nimport type Item from './item.js';\n\nimport { isIterable } from '@ckeditor/ckeditor5-utils';\n\n// @if CK_DEBUG_ENGINE // const { stringifyMap, convertMapToStringifiedObject, convertMapToTags } = require( '../dev-utils/utils' );\n\n/**\n * Model element. Type of {@link module:engine/model/node~Node node} that has a {@link module:engine/model/element~Element#name name} and\n * {@link module:engine/model/element~Element#getChildren child nodes}.\n *\n * **Important**: see {@link module:engine/model/node~Node} to read about restrictions using `Element` and `Node` API.\n */\nexport default class Element extends Node {\n\t/**\n\t * Element name.\n\t */\n\tpublic readonly name: string;\n\n\t/**\n\t * List of children nodes.\n\t */\n\tprivate readonly _children: NodeList = new NodeList();\n\n\t/**\n\t * Creates a model element.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createElement} method instead.\n\t *\n\t * @internal\n\t * @param name Element's name.\n\t * @param attrs Element's attributes. See {@link module:utils/tomap~toMap} for a list of accepted values.\n\t * @param children One or more nodes to be inserted as children of created element.\n\t */\n\tconstructor(\n\t\tname: string,\n\t\tattrs?: NodeAttributes,\n\t\tchildren?: string | Item | Iterable<string | Item>\n\t) {\n\t\tsuper( attrs );\n\n\t\tthis.name = name;\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Number of this element's children.\n\t */\n\tpublic get childCount(): number {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all of this element's children.\n\t */\n\tpublic get maxOffset(): number {\n\t\treturn this._children.maxOffset;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this element, `false` otherwise.\n\t */\n\tpublic get isEmpty(): boolean {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param index Index in this element.\n\t * @returns Child node.\n\t */\n\tpublic getChild( index: number ): Node | null {\n\t\treturn this._children.getNode( index );\n\t}\n\n\t/**\n\t * Gets the child at the given offset. Returns `null` if incorrect index was passed.\n\t *\n\t * @param offset Offset in this element.\n\t * @returns Child node.\n\t */\n\tpublic getChildAtOffset( offset: number ): Node | null {\n\t\treturn this._children.getNodeAtOffset( offset );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all of this element's children.\n\t */\n\tpublic getChildren(): IterableIterator<Node> {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns an index of the given child node. Returns `null` if given node is not a child of this element.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's index in this element.\n\t */\n\tpublic getChildIndex( node: Node ): number | null {\n\t\treturn this._children.getNodeIndex( node );\n\t}\n\n\t/**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {@link module:engine/model/node~Node#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t * given node is not a child of this element.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's starting offset.\n\t */\n\tpublic getChildStartOffset( node: Node ): number | null {\n\t\treturn this._children.getNodeStartOffset( node );\n\t}\n\n\t/**\n\t * Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t * too high, returns {@link module:engine/model/element~Element#getChildIndex index after last child}.\n\t *\n\t * ```ts\n\t * const textNode = new Text( 'foo' );\n\t * const pElement = new Element( 'p' );\n\t * const divElement = new Element( [ textNode, pElement ] );\n\t * divElement.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t * divElement.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t * divElement.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t * divElement.offsetToIndex( 2 ); // Returns 0.\n\t * divElement.offsetToIndex( 3 ); // Returns 1.\n\t * divElement.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t * ```\n\t */\n\tpublic offsetToIndex( offset: number ): number {\n\t\treturn this._children.offsetToIndex( offset );\n\t}\n\n\t/**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t * ```ts\n\t * // <this>a<b>c</b></this>\n\t * this.getNodeByPath( [ 0 ] );     // -> \"a\"\n\t * this.getNodeByPath( [ 1 ] );     // -> <b>\n\t * this.getNodeByPath( [ 1, 0 ] );  // -> \"c\"\n\t * ```\n\t *\n\t * @param relativePath Path of the node to find, relative to this element.\n\t */\n\tpublic getNodeByPath( relativePath: Array<number> ): Node {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n\t\tlet node: Node = this;\n\n\t\tfor ( const offset of relativePath ) {\n\t\t\tnode = ( node as Element ).getChildAtOffset( offset )!;\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Returns the parent element of the given name. Returns null if the element is not inside the desired parent.\n\t *\n\t * @param parentName The name of the parent element to find.\n\t * @param options Options object.\n\t * @param options.includeSelf When set to `true` this node will be also included while searching.\n\t */\n\tpublic findAncestor( parentName: string, options: { includeSelf?: boolean } = {} ): Element | null {\n\t\tlet parent = options.includeSelf ? this : this.parent;\n\n\t\twhile ( parent ) {\n\t\t\tif ( parent.name === parentName ) {\n\t\t\t\treturn parent;\n\t\t\t}\n\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Converts `Element` instance to plain object and returns it. Takes care of converting all of this element's children.\n\t *\n\t * @returns `Element` instance converted to plain object.\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.name = this.name;\n\n\t\tif ( this._children.length > 0 ) {\n\t\t\tjson.children = [];\n\n\t\t\tfor ( const node of this._children ) {\n\t\t\t\tjson.children.push( node.toJSON() );\n\t\t\t}\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a copy of this element and returns it. Created element has the same name and attributes as the original element.\n\t * If clone is deep, the original element's children are also cloned. If not, then empty element is returned.\n\t *\n\t * @internal\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any child.\n\t */\n\tpublic override _clone( deep = false ): Element {\n\t\tconst children = deep ? Array.from( this._children ).map( node => node._clone( true ) ) : undefined;\n\n\t\treturn new Element( this.name, this.getAttributes(), children );\n\t}\n\n\t/**\n\t * {@link module:engine/model/element~Element#_insertChild Inserts} one or more nodes at the end of this element.\n\t *\n\t * @see module:engine/model/writer~Writer#append\n\t * @internal\n\t * @param nodes Nodes to be inserted.\n\t */\n\tpublic _appendChild( nodes: string | Item | Iterable<string | Item> ): void {\n\t\tthis._insertChild( this.childCount, nodes );\n\t}\n\n\t/**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this element.\n\t *\n\t * @see module:engine/model/writer~Writer#insert\n\t * @internal\n\t * @param index Index at which nodes should be inserted.\n\t * @param items Items to be inserted.\n\t */\n\tpublic _insertChild( index: number, items: string | Item | Iterable<string | Item> ): void {\n\t\tconst nodes = normalize( items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\t( node as any ).parent = this;\n\t\t}\n\n\t\tthis._children._insertNodes( index, nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index and sets\n\t * {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @see module:engine/model/writer~Writer#remove\n\t * @internal\n\t * @param index Index of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns Array containing removed nodes.\n\t */\n\tpublic _removeChildren( index: number, howMany: number = 1 ): Array<Node> {\n\t\tconst nodes = this._children._removeNodes( index, howMany );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t( node as any ).parent = null;\n\t\t}\n\n\t\treturn nodes;\n\t}\n\n\t/**\n\t * Creates an `Element` instance from given plain object (i.e. parsed JSON string).\n\t * Converts `Element` children to proper nodes.\n\t *\n\t * @param json Plain object to be converted to `Element`.\n\t * @returns `Element` instance created using given plain object.\n\t */\n\tpublic static fromJSON( json: any ): Element {\n\t\tlet children: Array<Node> | undefined;\n\n\t\tif ( json.children ) {\n\t\t\tchildren = [];\n\n\t\t\tfor ( const child of json.children ) {\n\t\t\t\tif ( child.name ) {\n\t\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn new Element( json.name, json.attributes, children );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `<${ this.rootName || this.name }>`;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ModelElement: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logExtended(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( `ModelElement: ${ this }, ${ this.childCount } children,\n\t// @if CK_DEBUG_ENGINE // \tattrs: ${ convertMapToStringifiedObject( this.getAttributes() ) }` );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logAll(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( '--------------------' );\n\n\t// @if CK_DEBUG_ENGINE // \tthis.logExtended();\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'List of children:' );\n\n\t// @if CK_DEBUG_ENGINE // \tfor ( const child of this.getChildren() as any ) {\n\t// @if CK_DEBUG_ENGINE // \t\tchild.log();\n\t// @if CK_DEBUG_ENGINE // \t}\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public printTree( level = 0 ): string {\n\t// @if CK_DEBUG_ENGINE // \tlet string = '';\n\n\t// @if CK_DEBUG_ENGINE // \tstring += '\\t'.repeat( level );\n\t// @if CK_DEBUG_ENGINE // \tstring += `<${ this.rootName || this.name }${ convertMapToTags( this.getAttributes() ) }>`;\n\n\t// @if CK_DEBUG_ENGINE // \tfor ( const child of this.getChildren() as any ) {\n\t// @if CK_DEBUG_ENGINE // \t\tstring += '\\n';\n\n\t// @if CK_DEBUG_ENGINE // \t\tif ( child.is( '$text' ) ) {\n\t// @if CK_DEBUG_ENGINE // \t\t\tconst textAttrs = convertMapToTags( child._attrs );\n\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += '\\t'.repeat( level + 1 );\n\n\t// @if CK_DEBUG_ENGINE // \t\t\tif ( textAttrs !== '' ) {\n\t// @if CK_DEBUG_ENGINE // \t\t\t\tstring += `<$text${ textAttrs }>` + child.data + '</$text>';\n\t// @if CK_DEBUG_ENGINE // \t\t\t} else {\n\t// @if CK_DEBUG_ENGINE // \t\t\t\tstring += child.data;\n\t// @if CK_DEBUG_ENGINE // \t\t\t}\n\t// @if CK_DEBUG_ENGINE // \t\t} else {\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += child.printTree( level + 1 );\n\t// @if CK_DEBUG_ENGINE // \t\t}\n\t// @if CK_DEBUG_ENGINE // \t}\n\n\t// @if CK_DEBUG_ENGINE // \tif ( this.childCount ) {\n\t// @if CK_DEBUG_ENGINE // \t\tstring += '\\n' + '\\t'.repeat( level );\n\t// @if CK_DEBUG_ENGINE // \t}\n\n\t// @if CK_DEBUG_ENGINE // \tstring += `</${ this.rootName || this.name }>`;\n\n\t// @if CK_DEBUG_ENGINE // \treturn string;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logTree(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( this.printTree() );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'element' || type === 'model:element' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'node' || type === 'model:node';\n\t}\n\n\treturn name === this.name && ( type === 'element' || type === 'model:element' );\n};\n\n/**\n * Converts strings to Text and non-iterables to arrays.\n */\nfunction normalize( nodes: string | Item | Iterable<string | Item> ): Array<Node> {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( node.data, node.getAttributes() );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/treewalker\n */\n\nimport Element from './element.js';\nimport {\n\tdefault as Position,\n\tgetTextNodeAtPosition,\n\tgetNodeAfterPosition,\n\tgetNodeBeforePosition\n} from './position.js';\nimport Text from './text.js';\nimport TextProxy from './textproxy.js';\n\nimport type DocumentFragment from './documentfragment.js';\nimport type Item from './item.js';\nimport type Range from './range.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */\nexport default class TreeWalker implements Iterable<TreeWalkerValue> {\n\t/**\n\t * Walking direction. Defaults `'forward'`.\n\t */\n\tpublic readonly direction: TreeWalkerDirection;\n\n\t/**\n\t * Iterator boundaries.\n\t *\n\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t * on the start of boundary, then `{ done: true }` is returned.\n\t *\n\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t */\n\tpublic readonly boundaries: Range | null;\n\n\t/**\n\t * Flag indicating whether all consecutive characters with the same attributes should be\n\t * returned as one {@link module:engine/model/textproxy~TextProxy} (`true`) or one by one (`false`).\n\t */\n\tpublic readonly singleCharacters: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t * iterated node will not be returned along with `elementEnd` tag.\n\t */\n\tpublic readonly shallow: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should ignore `elementEnd` tags. If the option is true walker will not\n\t * return a parent node of the start position. If this option is `true` each {@link module:engine/model/element~Element} will\n\t * be returned once, while if the option is `false` they might be returned twice:\n\t * for `'elementStart'` and `'elementEnd'`.\n\t */\n\tpublic readonly ignoreElementEnd: boolean;\n\n\t/**\n\t * Iterator position. This is always static position, even if the initial position was a\n\t * {@link module:engine/model/liveposition~LivePosition live position}. If start position is not defined then position depends\n\t * on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t * is `'backward'` position starts from the end.\n\t */\n\tprivate _position: Position;\n\n\t/**\n\t * Start boundary cached for optimization purposes.\n\t */\n\tprivate _boundaryStartParent: Element | DocumentFragment | null;\n\n\t/**\n\t * End boundary cached for optimization purposes.\n\t */\n\tprivate _boundaryEndParent: Element | DocumentFragment | null;\n\n\t/**\n\t * Parent of the most recently visited node. Cached for optimization purposes.\n\t */\n\tprivate _visitedParent: Element | DocumentFragment;\n\n\t/**\n\t * Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t *\n\t * @param options Object with configuration.\n\t */\n\tconstructor( options: TreeWalkerOptions ) {\n\t\tif ( !options || ( !options.boundaries && !options.startPosition ) ) {\n\t\t\t/**\n\t\t\t * Neither boundaries nor starting position of a `TreeWalker` have been defined.\n\t\t\t *\n\t\t\t * @error model-tree-walker-no-start-position\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-tree-walker-no-start-position',\n\t\t\t\tnull\n\t\t\t);\n\t\t}\n\n\t\tconst direction = options.direction || 'forward';\n\n\t\tif ( direction != 'forward' && direction != 'backward' ) {\n\t\t\t/**\n\t\t\t * Only `backward` and `forward` direction allowed.\n\t\t\t *\n\t\t\t * @error model-tree-walker-unknown-direction\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-tree-walker-unknown-direction', options, { direction } );\n\t\t}\n\n\t\tthis.direction = direction;\n\t\tthis.boundaries = options.boundaries || null;\n\n\t\tif ( options.startPosition ) {\n\t\t\tthis._position = options.startPosition.clone();\n\t\t} else {\n\t\t\tthis._position = Position._createAt( this.boundaries![ this.direction == 'backward' ? 'end' : 'start' ] );\n\t\t}\n\n\t\t// Reset position stickiness in case it was set to other value, as the stickiness is kept after cloning.\n\t\tthis.position.stickiness = 'toNone';\n\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\t\tthis.shallow = !!options.shallow;\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\t\tthis._visitedParent = this.position.parent;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:engine/model/treewalker~TreeWalkerValue>}\n\t */\n\tpublic [ Symbol.iterator ](): IterableIterator<TreeWalkerValue> {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Iterator position. This is always static position, even if the initial position was a\n\t * {@link module:engine/model/liveposition~LivePosition live position}. If start position is not defined then position depends\n\t * on {@link #direction}. If direction is `'forward'` position starts form the beginning, when direction\n\t * is `'backward'` position starts from the end.\n\t */\n\tpublic get position(): Position {\n\t\treturn this._position;\n\t}\n\n\t/**\n\t * Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * walker.skip( value => value.type == 'text' ); // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t * walker.skip( () => true ); // Move the position to the end: <paragraph>[]foo</paragraph> -> <paragraph>foo</paragraph>[]\n\t * walker.skip( () => false ); // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t */\n\tpublic skip( skip: ( value: TreeWalkerValue ) => boolean ): void {\n\t\tlet done, value, prevPosition, prevVisitedParent;\n\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\t\t\tprevVisitedParent = this._visitedParent;\n\n\t\t\t( { done, value } = this.next() );\n\t\t} while ( !done && skip( value ) );\n\n\t\tif ( !done ) {\n\t\t\tthis._position = prevPosition;\n\t\t\tthis._visitedParent = prevVisitedParent;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the next tree walker's value.\n\t */\n\tpublic next(): IteratorResult<TreeWalkerValue> {\n\t\tif ( this.direction == 'forward' ) {\n\t\t\treturn this._next();\n\t\t} else {\n\t\t\treturn this._previous();\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step forward in model. Moves the {@link #position} to the next position and returns the encountered value.\n\t */\n\tprivate _next(): IteratorResult<TreeWalkerValue> {\n\t\tconst previousPosition = this.position;\n\t\tconst position = this.position.clone();\n\t\tconst parent = this._visitedParent;\n\n\t\t// We are at the end of the root.\n\t\tif ( parent.parent === null && position.offset === parent.maxOffset ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent === this._boundaryEndParent && position.offset == this.boundaries!.end.offset ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// Get node just after the current position.\n\t\t// Use a highly optimized version instead of checking the text node first and then getting the node after. See #6582.\n\t\tconst textNodeAtPosition = getTextNodeAtPosition( position, parent );\n\t\tconst node = textNodeAtPosition || getNodeAfterPosition( position, parent, textNodeAtPosition );\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\t// Manual operations on path internals for optimization purposes. Here and in the rest of the method.\n\t\t\t\t( position.path as Array<number> ).push( 0 );\n\t\t\t\tthis._visitedParent = node;\n\t\t\t} else {\n\t\t\t\t// We are past the walker boundaries.\n\t\t\t\tif ( this.boundaries && this.boundaries.end.isBefore( position ) ) {\n\t\t\t\t\treturn { done: true, value: undefined };\n\t\t\t\t}\n\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis._position = position;\n\n\t\t\treturn formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t}\n\n\t\tif ( node instanceof Text ) {\n\t\t\tlet charactersCount;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tcharactersCount = 1;\n\t\t\t} else {\n\t\t\t\tlet offset = node.endOffset!;\n\n\t\t\t\tif ( this._boundaryEndParent == parent && this.boundaries!.end.offset < offset ) {\n\t\t\t\t\toffset = this.boundaries!.end.offset;\n\t\t\t\t}\n\n\t\t\t\tcharactersCount = offset - position.offset;\n\t\t\t}\n\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset!;\n\t\t\tconst item = new TextProxy( node, offsetInTextNode, charactersCount );\n\n\t\t\tposition.offset += charactersCount;\n\t\t\tthis._position = position;\n\n\t\t\treturn formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t}\n\n\t\t// `node` is not set, we reached the end of current `parent`.\n\t\t( position.path as Array<number> ).pop();\n\t\tposition.offset++;\n\t\tthis._position = position;\n\t\tthis._visitedParent = parent.parent!;\n\n\t\tif ( this.ignoreElementEnd ) {\n\t\t\treturn this._next();\n\t\t}\n\n\t\treturn formatReturnValue( 'elementEnd', parent as Element, previousPosition, position );\n\t}\n\n\t/**\n\t * Makes a step backward in model. Moves the {@link #position} to the previous position and returns the encountered value.\n\t */\n\tprivate _previous(): IteratorResult<TreeWalkerValue> {\n\t\tconst previousPosition = this.position;\n\t\tconst position = this.position.clone();\n\t\tconst parent = this._visitedParent;\n\n\t\t// We are at the beginning of the root.\n\t\tif ( parent.parent === null && position.offset === 0 ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent == this._boundaryStartParent && position.offset == this.boundaries!.start.offset ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// Get node just before the current position.\n\t\t// Use a highly optimized version instead of checking the text node first and then getting the node before. See #6582.\n\t\tconst positionParent = position.parent;\n\t\tconst textNodeAtPosition = getTextNodeAtPosition( position, positionParent );\n\t\tconst node = textNodeAtPosition || getNodeBeforePosition( position, positionParent, textNodeAtPosition );\n\n\t\tif ( node instanceof Element ) {\n\t\t\tposition.offset--;\n\n\t\t\tif ( this.shallow ) {\n\t\t\t\tthis._position = position;\n\n\t\t\t\treturn formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t\t}\n\n\t\t\t( position.path as Array<number> ).push( node.maxOffset );\n\t\t\tthis._position = position;\n\t\t\tthis._visitedParent = node;\n\n\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\treturn this._previous();\n\t\t\t}\n\n\t\t\treturn formatReturnValue( 'elementEnd', node, previousPosition, position );\n\t\t}\n\n\t\tif ( node instanceof Text ) {\n\t\t\tlet charactersCount;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tcharactersCount = 1;\n\t\t\t} else {\n\t\t\t\tlet offset = node.startOffset!;\n\n\t\t\t\tif ( this._boundaryStartParent == parent && this.boundaries!.start.offset > offset ) {\n\t\t\t\t\toffset = this.boundaries!.start.offset;\n\t\t\t\t}\n\n\t\t\t\tcharactersCount = position.offset - offset;\n\t\t\t}\n\n\t\t\tconst offsetInTextNode = position.offset - node.startOffset!;\n\t\t\tconst item = new TextProxy( node, offsetInTextNode - charactersCount, charactersCount );\n\n\t\t\tposition.offset -= charactersCount;\n\t\t\tthis._position = position;\n\n\t\t\treturn formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t}\n\n\t\t// `node` is not set, we reached the beginning of current `parent`.\n\t\t( position.path as Array<number> ).pop();\n\t\tthis._position = position;\n\t\tthis._visitedParent = parent.parent!;\n\n\t\treturn formatReturnValue( 'elementStart', parent as Element, previousPosition, position, 1 );\n\t}\n}\n\nfunction formatReturnValue(\n\ttype: TreeWalkerValueType,\n\titem: Item,\n\tpreviousPosition: Position,\n\tnextPosition: Position,\n\tlength?: number\n): IteratorYieldResult<TreeWalkerValue> {\n\treturn {\n\t\tdone: false,\n\t\tvalue: {\n\t\t\ttype,\n\t\t\titem,\n\t\t\tpreviousPosition,\n\t\t\tnextPosition,\n\t\t\tlength\n\t\t}\n\t};\n}\n\n/**\n * Type of the step made by {@link module:engine/model/treewalker~TreeWalker}.\n * Possible values: `'elementStart'` if walker is at the beginning of a node, `'elementEnd'` if walker is at the end of node,\n * or `'text'` if walker traversed over text.\n */\nexport type TreeWalkerValueType = 'elementStart' | 'elementEnd' | 'text';\n\n/**\n * Object returned by {@link module:engine/model/treewalker~TreeWalker} when traversing tree model.\n */\nexport interface TreeWalkerValue {\n\ttype: TreeWalkerValueType;\n\n\t/**\n\t * Item between old and new positions of {@link module:engine/model/treewalker~TreeWalker}.\n\t */\n\titem: Item;\n\n\t/**\n\t * Previous position of the iterator.\n\t * * Forward iteration: For `'elementEnd'` it is the last position inside the element. For all other types it is the\n\t * position before the item.\n\t * * Backward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n\t * the position after item.\n\t */\n\tpreviousPosition: Position;\n\n\t/**\n\t * Next position of the iterator.\n\t * * Forward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n\t * the position after the item.\n\t * * Backward iteration: For `'elementEnd'` it is last position inside element. For all other types it is the position\n\t * before the item.\n\t */\n\tnextPosition: Position;\n\n\t/**\n\t * Length of the item. For `'elementStart'` it is 1. For `'text'` it is the length of the text. For `'elementEnd'` it is `undefined`.\n\t */\n\tlength?: number;\n}\n\n/**\n * Tree walking direction.\n */\nexport type TreeWalkerDirection = 'forward' | 'backward';\n\n/**\n * The configuration of TreeWalker.\n *\n * All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n */\nexport interface TreeWalkerOptions {\n\n\t/**\n\t * Walking direction.\n\t *\n\t * @default 'forward'\n\t */\n\tdirection?: TreeWalkerDirection;\n\n\t/**\n\t * Range to define boundaries of the iterator.\n\t */\n\tboundaries?: Range | null;\n\n\t/**\n\t * Starting position.\n\t */\n\tstartPosition?: Position;\n\n\t/**\n\t * Flag indicating whether all consecutive characters with the same attributes\n\t * should be returned one by one as multiple {@link module:engine/model/textproxy~TextProxy} (`true`) objects or as one\n\t * {@link module:engine/model/textproxy~TextProxy} (`false`).\n\t */\n\tsingleCharacters?: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should enter elements or not. If the\n\t * iterator is shallow child nodes of any iterated node will not be returned along with `elementEnd` tag.\n\t */\n\tshallow?: boolean;\n\n\t/**\n\t * Flag indicating whether iterator should ignore `elementEnd` tags.\n\t * If the option is true walker will not return a parent node of start position. If this option is `true`\n\t * each {@link module:engine/model/element~Element} will be returned once, while if the option is `false` they might be returned\n\t * twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tignoreElementEnd?: boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/position\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport TreeWalker, { type TreeWalkerOptions, type TreeWalkerValue } from './treewalker.js';\n\nimport type Document from './document.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type InsertOperation from './operation/insertoperation.js';\nimport type Item from './item.js';\nimport type MergeOperation from './operation/mergeoperation.js';\nimport type MoveOperation from './operation/moveoperation.js';\nimport type Node from './node.js';\nimport type Operation from './operation/operation.js';\nimport type SplitOperation from './operation/splitoperation.js';\nimport type Text from './text.js';\n\nimport { CKEditorError, compareArrays } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Represents a position in the model tree.\n *\n * A position is represented by its {@link module:engine/model/position~Position#root} and\n * a {@link module:engine/model/position~Position#path} in that root.\n *\n * You can create position instances via its constructor or the `createPosition*()` factory methods of\n * {@link module:engine/model/model~Model} and {@link module:engine/model/writer~Writer}.\n *\n * **Note:** Position is based on offsets, not indexes. This means that a position between two text nodes\n * `foo` and `bar` has offset `3`, not `1`. See {@link module:engine/model/position~Position#path} for more information.\n *\n * Since a position in the model is represented by a {@link module:engine/model/position~Position#root position root} and\n * {@link module:engine/model/position~Position#path position path} it is possible to create positions placed in non-existing places.\n * This requirement is important for operational transformation algorithms.\n *\n * Also, {@link module:engine/model/operation/operation~Operation operations}\n * kept in the {@link module:engine/model/document~Document#history document history}\n * are storing positions (and ranges) which were correct when those operations were applied, but may not be correct\n * after the document has changed.\n *\n * When changes are applied to the model, it may also happen that {@link module:engine/model/position~Position#parent position parent}\n * will change even if position path has not changed. Keep in mind, that if a position leads to non-existing element,\n * {@link module:engine/model/position~Position#parent} and some other properties and methods will throw errors.\n *\n * In most cases, position with wrong path is caused by an error in code, but it is sometimes needed, as described above.\n */\nexport default class Position extends TypeCheckable {\n\t/**\n\t * Root of the position path.\n\t */\n\tpublic readonly root: Element | DocumentFragment;\n\n\t/**\n\t * Position of the node in the tree. **Path contains offsets, not indexes.**\n\t *\n\t * Position can be placed before, after or in a {@link module:engine/model/node~Node node} if that node has\n\t * {@link module:engine/model/node~Node#offsetSize} greater than `1`. Items in position path are\n\t * {@link module:engine/model/node~Node#startOffset starting offsets} of position ancestors, starting from direct root children,\n\t * down to the position offset in it's parent.\n\t *\n\t * ```\n\t * ROOT\n\t *  |- P            before: [ 0 ]         after: [ 1 ]\n\t *  |- UL           before: [ 1 ]         after: [ 2 ]\n\t *     |- LI        before: [ 1, 0 ]      after: [ 1, 1 ]\n\t *     |  |- foo    before: [ 1, 0, 0 ]   after: [ 1, 0, 3 ]\n\t *     |- LI        before: [ 1, 1 ]      after: [ 1, 2 ]\n\t *        |- bar    before: [ 1, 1, 0 ]   after: [ 1, 1, 3 ]\n\t * ```\n\t *\n\t * `foo` and `bar` are representing {@link module:engine/model/text~Text text nodes}. Since text nodes has offset size\n\t * greater than `1` you can place position offset between their start and end:\n\t *\n\t * ```\n\t * ROOT\n\t *  |- P\n\t *  |- UL\n\t *     |- LI\n\t *     |  |- f^o|o  ^ has path: [ 1, 0, 1 ]   | has path: [ 1, 0, 2 ]\n\t *     |- LI\n\t *        |- b^a|r  ^ has path: [ 1, 1, 1 ]   | has path: [ 1, 1, 2 ]\n\t * ```\n\t */\n\tpublic readonly path: ReadonlyArray<number>;\n\n\t/**\n\t * Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */\n\tpublic stickiness: PositionStickiness;\n\n\t/**\n\t * Creates a position.\n\t *\n\t * @param root Root of the position.\n\t * @param path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param stickiness Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */\n\tconstructor(\n\t\troot: Element | DocumentFragment,\n\t\tpath: ReadonlyArray<number>,\n\t\tstickiness: PositionStickiness = 'toNone'\n\t) {\n\t\tsuper();\n\n\t\tif ( !root.is( 'element' ) && !root.is( 'documentFragment' ) ) {\n\t\t\t/**\n\t\t\t * Position root is invalid.\n\t\t\t *\n\t\t\t * Positions can only be anchored in elements or document fragments.\n\t\t\t *\n\t\t\t * @error model-position-root-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-position-root-invalid',\n\t\t\t\troot\n\t\t\t);\n\t\t}\n\n\t\tif ( !( path instanceof Array ) || path.length === 0 ) {\n\t\t\t/**\n\t\t\t * Position path must be an array with at least one item.\n\t\t\t *\n\t\t\t * @error model-position-path-incorrect-format\n\t\t\t * @param path\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-position-path-incorrect-format',\n\t\t\t\troot,\n\t\t\t\t{ path }\n\t\t\t);\n\t\t}\n\n\t\t// Normalize the root and path when element (not root) is passed.\n\t\tif ( root.is( 'rootElement' ) ) {\n\t\t\tpath = path.slice();\n\t\t} else {\n\t\t\tpath = [ ...root.getPath(), ...path ];\n\t\t\troot = root.root as any;\n\t\t}\n\n\t\tthis.root = root;\n\t\tthis.path = path;\n\t\tthis.stickiness = stickiness;\n\t}\n\n\t/**\n\t * Offset at which this position is located in its {@link module:engine/model/position~Position#parent parent}. It is equal\n\t * to the last item in position {@link module:engine/model/position~Position#path path}.\n\t *\n\t * @type {Number}\n\t */\n\tpublic get offset(): number {\n\t\treturn this.path[ this.path.length - 1 ];\n\t}\n\n\tpublic set offset( newOffset: number ) {\n\t\t( this.path as Array<number> )[ this.path.length - 1 ] = newOffset;\n\t}\n\n\t/**\n\t * Parent element of this position.\n\t *\n\t * Keep in mind that `parent` value is calculated when the property is accessed.\n\t * If {@link module:engine/model/position~Position#path position path}\n\t * leads to a non-existing element, `parent` property will throw error.\n\t *\n\t * Also it is a good idea to cache `parent` property if it is used frequently in an algorithm (i.e. in a long loop).\n\t */\n\tpublic get parent(): Element | DocumentFragment {\n\t\tlet parent: any = this.root;\n\n\t\tfor ( let i = 0; i < this.path.length - 1; i++ ) {\n\t\t\tparent = parent.getChildAtOffset( this.path[ i ] );\n\n\t\t\tif ( !parent ) {\n\t\t\t\t/**\n\t\t\t\t * The position's path is incorrect. This means that a position does not point to\n\t\t\t\t * a correct place in the tree and hence, some of its methods and getters cannot work correctly.\n\t\t\t\t *\n\t\t\t\t * **Note**: Unlike DOM and view positions, in the model, the\n\t\t\t\t * {@link module:engine/model/position~Position#parent position's parent} is always an element or a document fragment.\n\t\t\t\t * The last offset in the {@link module:engine/model/position~Position#path position's path} is the point in this element\n\t\t\t\t * where this position points.\n\t\t\t\t *\n\t\t\t\t * Read more about model positions and offsets in\n\t\t\t\t * the {@glink framework/architecture/editing-engine#indexes-and-offsets Editing engine architecture} guide.\n\t\t\t\t *\n\t\t\t\t * @error model-position-path-incorrect\n\t\t\t\t * @param position The incorrect position.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'model-position-path-incorrect', this, { position: this } );\n\t\t\t}\n\t\t}\n\n\t\tif ( parent.is( '$text' ) ) {\n\t\t\tthrow new CKEditorError( 'model-position-path-incorrect', this, { position: this } );\n\t\t}\n\n\t\treturn parent;\n\t}\n\n\t/**\n\t * Position {@link module:engine/model/position~Position#offset offset} converted to an index in position's parent node. It is\n\t * equal to the {@link module:engine/model/node~Node#index index} of a node after this position. If position is placed\n\t * in text node, position index is equal to the index of that text node.\n\t */\n\tpublic get index(): number {\n\t\treturn this.parent.offsetToIndex( this.offset );\n\t}\n\n\t/**\n\t * Returns {@link module:engine/model/text~Text text node} instance in which this position is placed or `null` if this\n\t * position is not in a text node.\n\t */\n\tpublic get textNode(): Text | null {\n\t\treturn getTextNodeAtPosition( this, this.parent );\n\t}\n\n\t/**\n\t * Node directly after this position. Returns `null` if this position is at the end of its parent, or if it is in a text node.\n\t */\n\tpublic get nodeAfter(): Node | null {\n\t\t// Cache the parent and reuse for performance reasons. See #6579 and #6582.\n\t\tconst parent = this.parent;\n\n\t\treturn getNodeAfterPosition( this, parent, getTextNodeAtPosition( this, parent ) );\n\t}\n\n\t/**\n\t * Node directly before this position. Returns `null` if this position is at the start of its parent, or if it is in a text node.\n\t */\n\tpublic get nodeBefore(): Node | null {\n\t\t// Cache the parent and reuse for performance reasons. See #6579 and #6582.\n\t\tconst parent = this.parent;\n\n\t\treturn getNodeBeforePosition( this, parent, getTextNodeAtPosition( this, parent ) );\n\t}\n\n\t/**\n\t * Is `true` if position is at the beginning of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t */\n\tpublic get isAtStart(): boolean {\n\t\treturn this.offset === 0;\n\t}\n\n\t/**\n\t * Is `true` if position is at the end of its {@link module:engine/model/position~Position#parent parent}, `false` otherwise.\n\t */\n\tpublic get isAtEnd(): boolean {\n\t\treturn this.offset == this.parent.maxOffset;\n\t}\n\n\t/**\n\t * Checks whether the position is valid in current model tree, that is whether it points to an existing place in the model.\n\t */\n\tpublic isValid(): boolean {\n\t\tif ( this.offset < 0 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet parent: any = this.root;\n\n\t\tfor ( let i = 0; i < this.path.length - 1; i++ ) {\n\t\t\tparent = parent.getChildAtOffset( this.path[ i ] );\n\n\t\t\tif ( !parent ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn this.offset <= parent.maxOffset;\n\t}\n\n\t/**\n\t * Checks whether this position is before or after given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t */\n\tpublic compareWith( otherPosition: Position ): PositionRelation {\n\t\tif ( this.root != otherPosition.root ) {\n\t\t\treturn 'different';\n\t\t}\n\n\t\tconst result = compareArrays( this.path, otherPosition.path );\n\n\t\tswitch ( result ) {\n\t\t\tcase 'same':\n\t\t\t\treturn 'same';\n\n\t\t\tcase 'prefix':\n\t\t\t\treturn 'before';\n\n\t\t\tcase 'extension':\n\t\t\t\treturn 'after';\n\n\t\t\tdefault:\n\t\t\t\treturn this.path[ result ] < otherPosition.path[ result ] ? 'before' : 'after';\n\t\t}\n\t}\n\n\t/**\n\t * Gets the farthest position which matches the callback using\n\t * {@link module:engine/model/treewalker~TreeWalker TreeWalker}.\n\t *\n\t * For example:\n\t *\n\t * ```ts\n\t * getLastMatchingPosition( value => value.type == 'text' );\n\t * // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph>\n\t *\n\t * getLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } );\n\t * // <paragraph>foo[]</paragraph> -> <paragraph>[]foo</paragraph>\n\t *\n\t * getLastMatchingPosition( value => false );\n\t * // Do not move the position.\n\t * ```\n\t *\n\t * @param skip Callback function. Gets {@link module:engine/model/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t *\n\t * @returns The position after the last item which matches the `skip` callback test.\n\t */\n\tpublic getLastMatchingPosition(\n\t\tskip: ( value: TreeWalkerValue ) => boolean,\n\t\toptions: TreeWalkerOptions = {}\n\t): Position {\n\t\toptions.startPosition = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\t\ttreeWalker.skip( skip );\n\n\t\treturn treeWalker.position;\n\t}\n\n\t/**\n\t * Returns a path to this position's parent. Parent path is equal to position {@link module:engine/model/position~Position#path path}\n\t * but without the last item.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @returns Path to the parent.\n\t */\n\tpublic getParentPath(): Array<number> {\n\t\treturn this.path.slice( 0, -1 );\n\t}\n\n\t/**\n\t * Returns ancestors array of this position, that is this position's parent and its ancestors.\n\t *\n\t * @returns Array with ancestors.\n\t */\n\tpublic getAncestors(): Array<Element | DocumentFragment> {\n\t\tconst parent = this.parent;\n\n\t\tif ( parent.is( 'documentFragment' ) ) {\n\t\t\treturn [ parent ];\n\t\t} else {\n\t\t\treturn parent.getAncestors( { includeSelf: true } ) as any;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the parent element of the given name. Returns null if the position is not inside the desired parent.\n\t *\n\t * @param parentName The name of the parent element to find.\n\t */\n\tpublic findAncestor( parentName: string ): Element | null {\n\t\tconst parent = this.parent;\n\n\t\tif ( parent.is( 'element' ) ) {\n\t\t\treturn parent.findAncestor( parentName, { includeSelf: true } );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns the slice of two position {@link #path paths} which is identical. The {@link #root roots}\n\t * of these two paths must be identical.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param position The second position.\n\t * @returns The common path.\n\t */\n\tpublic getCommonPath( position: Position ): Array<number> {\n\t\tif ( this.root != position.root ) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// We find on which tree-level start and end have the lowest common ancestor\n\t\tconst cmp = compareArrays( this.path, position.path );\n\t\t// If comparison returned string it means that arrays are same.\n\t\tconst diffAt = ( typeof cmp == 'string' ) ? Math.min( this.path.length, position.path.length ) : cmp;\n\n\t\treturn this.path.slice( 0, diffAt );\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of both positions. The {@link #root roots} of these two positions must be identical.\n\t *\n\t * @param position The second position.\n\t */\n\tpublic getCommonAncestor( position: Position ): Element | DocumentFragment | null {\n\t\tconst ancestorsA = this.getAncestors();\n\t\tconst ancestorsB = position.getAncestors();\n\n\t\tlet i = 0;\n\n\t\twhile ( ancestorsA[ i ] == ancestorsB[ i ] && ancestorsA[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i === 0 ? null : ancestorsA[ i - 1 ];\n\t}\n\n\t/**\n\t * Returns a new instance of `Position`, that has same {@link #parent parent} but it's offset\n\t * is shifted by `shift` value (can be a negative value).\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param shift Offset shift. Can be a negative value.\n\t * @returns Shifted position.\n\t */\n\tpublic getShiftedBy( shift: number ): Position {\n\t\tconst shifted = this.clone();\n\n\t\tconst offset = shifted.offset + shift;\n\t\tshifted.offset = offset < 0 ? 0 : offset;\n\n\t\treturn shifted;\n\t}\n\n\t/**\n\t * Checks whether this position is after given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @see module:engine/model/position~Position#isBefore\n\t * @param  otherPosition Position to compare with.\n\t * @returns True if this position is after given position.\n\t */\n\tpublic isAfter( otherPosition: Position ): boolean {\n\t\treturn this.compareWith( otherPosition ) == 'after';\n\t}\n\n\t/**\n\t * Checks whether this position is before given position.\n\t *\n\t * **Note:** watch out when using negation of the value returned by this method, because the negation will also\n\t * be `true` if positions are in different roots and you might not expect this. You should probably use\n\t * `a.isAfter( b ) || a.isEqual( b )` or `!a.isBefore( p ) && a.root == b.root` in most scenarios. If your\n\t * condition uses multiple `isAfter` and `isBefore` checks, build them so they do not use negated values, i.e.:\n\t *\n\t * ```ts\n\t * if ( a.isBefore( b ) && c.isAfter( d ) ) {\n\t * \t// do A.\n\t * } else {\n\t * \t// do B.\n\t * }\n\t * ```\n\t *\n\t * or, if you have only one if-branch:\n\t *\n\t * ```ts\n\t * if ( !( a.isBefore( b ) && c.isAfter( d ) ) {\n\t * \t// do B.\n\t * }\n\t * ```\n\t *\n\t * rather than:\n\t *\n\t * ```ts\n\t * if ( !a.isBefore( b ) || && !c.isAfter( d ) ) {\n\t * \t// do B.\n\t * } else {\n\t * \t// do A.\n\t * }\n\t * ```\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if this position is before given position.\n\t */\n\tpublic isBefore( otherPosition: Position ): boolean {\n\t\treturn this.compareWith( otherPosition ) == 'before';\n\t}\n\n\t/**\n\t * Checks whether this position is equal to given position.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if positions are same.\n\t */\n\tpublic isEqual( otherPosition: Position ): boolean {\n\t\treturn this.compareWith( otherPosition ) == 'same';\n\t}\n\n\t/**\n\t * Checks whether this position is touching given position. Positions touch when there are no text nodes\n\t * or empty nodes in a range between them. Technically, those positions are not equal but in many cases\n\t * they are very similar or even indistinguishable.\n\t *\n\t * @param otherPosition Position to compare with.\n\t * @returns True if positions touch.\n\t */\n\tpublic isTouching( otherPosition: Position ): boolean {\n\t\tif ( this.root !== otherPosition.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst commonLevel = Math.min( this.path.length, otherPosition.path.length );\n\n\t\tfor ( let level = 0; level < commonLevel; level++ ) {\n\t\t\tconst diff = this.path[ level ] - otherPosition.path[ level ];\n\n\t\t\t// Positions are spread by a node, so they are not touching.\n\t\t\tif ( diff < -1 || diff > 1 ) {\n\t\t\t\treturn false;\n\t\t\t} else if ( diff === 1 ) {\n\t\t\t\t// `otherPosition` is on the left.\n\t\t\t\t// `this` is on the right.\n\t\t\t\treturn checkTouchingBranch( otherPosition, this, level );\n\t\t\t} else if ( diff === -1 ) {\n\t\t\t\t// `this` is on the left.\n\t\t\t\t// `otherPosition` is on the right.\n\t\t\t\treturn checkTouchingBranch( this, otherPosition, level );\n\t\t\t}\n\t\t\t// `diff === 0`.\n\t\t\t// Positions are inside the same element on this level, compare deeper.\n\t\t}\n\n\t\t// If we ended up here, it means that positions paths have the same beginning.\n\t\t// If the paths have the same length, then it means that they are identical, so the positions are same.\n\t\tif ( this.path.length === otherPosition.path.length ) {\n\t\t\treturn true;\n\t\t}\n\t\t// If positions have different length of paths, then the common part is the same.\n\t\t// In this case, the \"shorter\" position is on the left, the \"longer\" position is on the right.\n\t\t//\n\t\t// If the positions are touching, the \"longer\" position must have only zeroes. For example:\n\t\t// [ 1, 2 ] vs [ 1, 2, 0 ]\n\t\t// [ 1, 2 ] vs [ 1, 2, 0, 0, 0 ]\n\t\telse if ( this.path.length > otherPosition.path.length ) {\n\t\t\treturn checkOnlyZeroes( this.path, commonLevel );\n\t\t} else {\n\t\t\treturn checkOnlyZeroes( otherPosition.path, commonLevel );\n\t\t}\n\t}\n\n\t/**\n\t * Checks if two positions are in the same parent.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param position Position to compare with.\n\t * @returns `true` if positions have the same parent, `false` otherwise.\n\t */\n\tpublic hasSameParentAs( position: Position ): boolean {\n\t\tif ( this.root !== position.root ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst thisParentPath = this.getParentPath();\n\t\tconst posParentPath = position.getParentPath();\n\n\t\treturn compareArrays( thisParentPath, posParentPath ) == 'same';\n\t}\n\n\t/**\n\t * Returns a copy of this position that is transformed by given `operation`.\n\t *\n\t * The new position's parameters are updated accordingly to the effect of the `operation`.\n\t *\n\t * For example, if `n` nodes are inserted before the position, the returned position {@link ~Position#offset} will be\n\t * increased by `n`. If the position was in a merged element, it will be accordingly moved to the new element, etc.\n\t *\n\t * This method is safe to use it on non-existing positions (for example during operational transformation).\n\t *\n\t * @param operation Operation to transform by.\n\t * @returns Transformed position.\n\t */\n\tpublic getTransformedByOperation( operation: Operation ): Position {\n\t\tlet result;\n\n\t\tswitch ( operation.type ) {\n\t\t\tcase 'insert':\n\t\t\t\tresult = this._getTransformedByInsertOperation( operation as InsertOperation );\n\t\t\t\tbreak;\n\t\t\tcase 'move':\n\t\t\tcase 'remove':\n\t\t\tcase 'reinsert':\n\t\t\t\tresult = this._getTransformedByMoveOperation( operation as MoveOperation );\n\t\t\t\tbreak;\n\t\t\tcase 'split':\n\t\t\t\tresult = this._getTransformedBySplitOperation( operation as SplitOperation );\n\t\t\t\tbreak;\n\t\t\tcase 'merge':\n\t\t\t\tresult = this._getTransformedByMergeOperation( operation as MergeOperation );\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tresult = Position._createAt( this );\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by an insert operation.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedByInsertOperation( operation: InsertOperation ): Position {\n\t\treturn this._getTransformedByInsertion( operation.position, operation.howMany );\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by a move operation.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedByMoveOperation( operation: MoveOperation ): Position {\n\t\treturn this._getTransformedByMove( operation.sourcePosition, operation.targetPosition, operation.howMany );\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by a split operation.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedBySplitOperation( operation: SplitOperation ): Position {\n\t\tconst movedRange = operation.movedRange;\n\n\t\tconst isContained = movedRange.containsPosition( this ) ||\n\t\t\t( movedRange.start.isEqual( this ) && this.stickiness == 'toNext' );\n\n\t\tif ( isContained ) {\n\t\t\treturn this._getCombined( operation.splitPosition, operation.moveTargetPosition );\n\t\t} else {\n\t\t\tif ( operation.graveyardPosition ) {\n\t\t\t\treturn this._getTransformedByMove( operation.graveyardPosition, operation.insertionPosition, 1 );\n\t\t\t} else {\n\t\t\t\treturn this._getTransformedByInsertion( operation.insertionPosition, 1 );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns a copy of this position transformed by merge operation.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedByMergeOperation( operation: MergeOperation ): Position {\n\t\tconst movedRange = operation.movedRange;\n\t\tconst isContained = movedRange.containsPosition( this ) || movedRange.start.isEqual( this );\n\n\t\tlet pos;\n\n\t\tif ( isContained ) {\n\t\t\tpos = this._getCombined( operation.sourcePosition, operation.targetPosition );\n\n\t\t\tif ( operation.sourcePosition.isBefore( operation.targetPosition ) ) {\n\t\t\t\t// Above happens during OT when the merged element is moved before the merged-to element.\n\t\t\t\tpos = pos._getTransformedByDeletion( operation.deletionPosition, 1 )!;\n\t\t\t}\n\t\t} else if ( this.isEqual( operation.deletionPosition ) ) {\n\t\t\tpos = Position._createAt( operation.deletionPosition );\n\t\t} else {\n\t\t\tpos = this._getTransformedByMove( operation.deletionPosition, operation.graveyardPosition, 1 );\n\t\t}\n\n\t\treturn pos;\n\t}\n\n\t/**\n\t * Returns a copy of this position that is updated by removing `howMany` nodes starting from `deletePosition`.\n\t * It may happen that this position is in a removed node. If that is the case, `null` is returned instead.\n\t *\n\t * @internal\n\t * @param deletePosition Position before the first removed node.\n\t * @param howMany How many nodes are removed.\n\t * @returns Transformed position or `null`.\n\t */\n\tpublic _getTransformedByDeletion( deletePosition: Position, howMany: number ): Position | null {\n\t\tconst transformed = Position._createAt( this );\n\n\t\t// This position can't be affected if deletion was in a different root.\n\t\tif ( this.root != deletePosition.root ) {\n\t\t\treturn transformed;\n\t\t}\n\n\t\tif ( compareArrays( deletePosition.getParentPath(), this.getParentPath() ) == 'same' ) {\n\t\t\t// If nodes are removed from the node that is pointed by this position...\n\t\t\tif ( deletePosition.offset < this.offset ) {\n\t\t\t\t// And are removed from before an offset of that position...\n\t\t\t\tif ( deletePosition.offset + howMany > this.offset ) {\n\t\t\t\t\t// Position is in removed range, it's no longer in the tree.\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\t// Decrement the offset accordingly.\n\t\t\t\t\ttransformed.offset -= howMany;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( compareArrays( deletePosition.getParentPath(), this.getParentPath() ) == 'prefix' ) {\n\t\t\t// If nodes are removed from a node that is on a path to this position...\n\t\t\tconst i = deletePosition.path.length - 1;\n\n\t\t\tif ( deletePosition.offset <= this.path[ i ] ) {\n\t\t\t\t// And are removed from before next node of that path...\n\t\t\t\tif ( deletePosition.offset + howMany > this.path[ i ] ) {\n\t\t\t\t\t// If the next node of that path is removed return null\n\t\t\t\t\t// because the node containing this position got removed.\n\t\t\t\t\treturn null;\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, decrement index on that path.\n\t\t\t\t\t( transformed.path as Array<number> )[ i ] -= howMany;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn transformed;\n\t}\n\n\t/**\n\t * Returns a copy of this position that is updated by inserting `howMany` nodes at `insertPosition`.\n\t *\n\t * @internal\n\t * @param insertPosition Position where nodes are inserted.\n\t * @param howMany How many nodes are inserted.\n\t * @returns Transformed position.\n\t */\n\tpublic _getTransformedByInsertion( insertPosition: Position, howMany: number ): Position {\n\t\tconst transformed = Position._createAt( this );\n\n\t\t// This position can't be affected if insertion was in a different root.\n\t\tif ( this.root != insertPosition.root ) {\n\t\t\treturn transformed;\n\t\t}\n\n\t\tif ( compareArrays( insertPosition.getParentPath(), this.getParentPath() ) == 'same' ) {\n\t\t\t// If nodes are inserted in the node that is pointed by this position...\n\t\t\tif ( insertPosition.offset < this.offset || ( insertPosition.offset == this.offset && this.stickiness != 'toPrevious' ) ) {\n\t\t\t\t// And are inserted before an offset of that position...\n\t\t\t\t// \"Push\" this positions offset.\n\t\t\t\ttransformed.offset += howMany;\n\t\t\t}\n\t\t} else if ( compareArrays( insertPosition.getParentPath(), this.getParentPath() ) == 'prefix' ) {\n\t\t\t// If nodes are inserted in a node that is on a path to this position...\n\t\t\tconst i = insertPosition.path.length - 1;\n\n\t\t\tif ( insertPosition.offset <= this.path[ i ] ) {\n\t\t\t\t// And are inserted before next node of that path...\n\t\t\t\t// \"Push\" the index on that path.\n\t\t\t\t( transformed.path as Array<number> )[ i ] += howMany;\n\t\t\t}\n\t\t}\n\n\t\treturn transformed;\n\t}\n\n\t/**\n\t * Returns a copy of this position that is updated by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t *\n\t * @internal\n\t * @param sourcePosition Position before the first element to move.\n\t * @param targetPosition Position where moved elements will be inserted.\n\t * @param howMany How many consecutive nodes to move, starting from `sourcePosition`.\n\t * @returns Transformed position.\n\t */\n\tpublic _getTransformedByMove( sourcePosition: Position, targetPosition: Position, howMany: number ): Position {\n\t\t// Update target position, as it could be affected by nodes removal.\n\t\ttargetPosition = targetPosition._getTransformedByDeletion( sourcePosition, howMany )!;\n\n\t\tif ( sourcePosition.isEqual( targetPosition ) ) {\n\t\t\t// If `targetPosition` is equal to `sourcePosition` this isn't really any move. Just return position as it is.\n\t\t\treturn Position._createAt( this );\n\t\t}\n\n\t\t// Moving a range removes nodes from their original position. We acknowledge this by proper transformation.\n\t\tconst transformed = this._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\tconst isMoved = transformed === null ||\n\t\t\t( sourcePosition.isEqual( this ) && this.stickiness == 'toNext' ) ||\n\t\t\t( sourcePosition.getShiftedBy( howMany ).isEqual( this ) && this.stickiness == 'toPrevious' );\n\n\t\tif ( isMoved ) {\n\t\t\t// This position is inside moved range (or sticks to it).\n\t\t\t// In this case, we calculate a combination of this position, move source position and target position.\n\t\t\treturn this._getCombined( sourcePosition, targetPosition );\n\t\t} else {\n\t\t\t// This position is not inside a removed range.\n\t\t\t//\n\t\t\t// In next step, we simply reflect inserting `howMany` nodes, which might further affect the position.\n\t\t\treturn transformed._getTransformedByInsertion( targetPosition, howMany );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a new position that is a combination of this position and given positions.\n\t *\n\t * The combined position is a copy of this position transformed by moving a range starting at `source` position\n\t * to the `target` position. It is expected that this position is inside the moved range.\n\t *\n\t * Example:\n\t *\n\t * ```ts\n\t * let original = model.createPositionFromPath( root, [ 2, 3, 1 ] );\n\t * let source = model.createPositionFromPath( root, [ 2, 2 ] );\n\t * let target = model.createPositionFromPath( otherRoot, [ 1, 1, 3 ] );\n\t * original._getCombined( source, target ); // path is [ 1, 1, 4, 1 ], root is `otherRoot`\n\t * ```\n\t *\n\t * Explanation:\n\t *\n\t * We have a position `[ 2, 3, 1 ]` and move some nodes from `[ 2, 2 ]` to `[ 1, 1, 3 ]`. The original position\n\t * was inside moved nodes and now should point to the new place. The moved nodes will be after\n\t * positions `[ 1, 1, 3 ]`, `[ 1, 1, 4 ]`, `[ 1, 1, 5 ]`. Since our position was in the second moved node,\n\t * the transformed position will be in a sub-tree of a node at `[ 1, 1, 4 ]`. Looking at original path, we\n\t * took care of `[ 2, 3 ]` part of it. Now we have to add the rest of the original path to the transformed path.\n\t * Finally, the transformed position will point to `[ 1, 1, 4, 1 ]`.\n\t *\n\t * @internal\n\t * @param source Beginning of the moved range.\n\t * @param target Position where the range is moved.\n\t * @returns Combined position.\n\t */\n\tpublic _getCombined( source: Position, target: Position ): Position {\n\t\tconst i = source.path.length - 1;\n\n\t\t// The first part of a path to combined position is a path to the place where nodes were moved.\n\t\tconst combined = Position._createAt( target );\n\t\tcombined.stickiness = this.stickiness;\n\n\t\t// Then we have to update the rest of the path.\n\n\t\t// Fix the offset because this position might be after `from` position and we have to reflect that.\n\t\tcombined.offset = combined.offset + this.path[ i ] - source.offset;\n\n\t\t// Then, add the rest of the path.\n\t\t// If this position is at the same level as `from` position nothing will get added.\n\t\t( combined as any ).path = [ ...combined.path, ...this.path.slice( i + 1 ) ];\n\n\t\treturn combined;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic toJSON(): unknown {\n\t\treturn {\n\t\t\troot: this.root.toJSON(),\n\t\t\tpath: Array.from( this.path ),\n\t\t\tstickiness: this.stickiness\n\t\t};\n\t}\n\n\t/**\n\t * Returns a new position that is equal to current position.\n\t */\n\tpublic clone(): this {\n\t\treturn new ( this.constructor as any )( this.root, this.path, this.stickiness );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/model/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/model/item~Item model item} and `'before'` or `'after'` (sets position before or after given model item).\n\t *\n\t * This method is a shortcut to other factory methods such as:\n\t *\n\t * * {@link module:engine/model/position~Position._createBefore},\n\t * * {@link module:engine/model/position~Position._createAfter}.\n\t *\n\t * @internal\n\t * @param offset Offset or one of the flags. Used only when the first parameter is a {@link module:engine/model/item~Item model item}.\n\t * @param stickiness Position stickiness. Used only when the first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic static _createAt(\n\t\titemOrPosition: Item | Position | DocumentFragment,\n\t\toffset?: PositionOffset,\n\t\tstickiness: PositionStickiness = 'toNone'\n\t): Position {\n\t\tif ( itemOrPosition instanceof Position ) {\n\t\t\treturn new Position( itemOrPosition.root, itemOrPosition.path, itemOrPosition.stickiness );\n\t\t} else {\n\t\t\tconst node = itemOrPosition;\n\n\t\t\tif ( offset == 'end' ) {\n\t\t\t\toffset = ( node as any ).maxOffset;\n\t\t\t} else if ( offset == 'before' ) {\n\t\t\t\treturn this._createBefore( node, stickiness );\n\t\t\t} else if ( offset == 'after' ) {\n\t\t\t\treturn this._createAfter( node, stickiness );\n\t\t\t} else if ( offset !== 0 && !offset ) {\n\t\t\t\t/**\n\t\t\t\t * {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}\n\t\t\t\t * requires the offset to be specified when the first parameter is a model item.\n\t\t\t\t *\n\t\t\t\t * @error model-createpositionat-offset-required\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'model-createpositionat-offset-required', [ this, itemOrPosition ] );\n\t\t\t}\n\n\t\t\tif ( !node.is( 'element' ) && !node.is( 'documentFragment' ) ) {\n\t\t\t\t/**\n\t\t\t\t * Position parent have to be a model element or model document fragment.\n\t\t\t\t *\n\t\t\t\t * @error model-position-parent-incorrect\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-position-parent-incorrect',\n\t\t\t\t\t[ this, itemOrPosition ]\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst path = node.getPath();\n\n\t\t\tpath.push( offset as any );\n\n\t\t\treturn new this( node.root as any, path, stickiness );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new position, after given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @internal\n\t * @param item Item after which the position should be placed.\n\t * @param stickiness Position stickiness.\n\t */\n\tpublic static _createAfter( item: Item | DocumentFragment, stickiness?: PositionStickiness ): Position {\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position after a root element.\n\t\t\t *\n\t\t\t * @error model-position-after-root\n\t\t\t * @param root\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-position-after-root',\n\t\t\t\t[ this, item ],\n\t\t\t\t{ root: item }\n\t\t\t);\n\t\t}\n\n\t\treturn this._createAt( item.parent, item.endOffset!, stickiness );\n\t}\n\n\t/**\n\t * Creates a new position, before the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * @internal\n\t * @param item Item before which the position should be placed.\n\t * @param stickiness Position stickiness.\n\t */\n\tpublic static _createBefore( item: Item | DocumentFragment, stickiness?: PositionStickiness ): Position {\n\t\tif ( !item.parent ) {\n\t\t\t/**\n\t\t\t * You can not make a position before a root element.\n\t\t\t *\n\t\t\t * @error model-position-before-root\n\t\t\t * @param root\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-position-before-root',\n\t\t\t\titem,\n\t\t\t\t{ root: item }\n\t\t\t);\n\t\t}\n\n\t\treturn this._createAt( item.parent, item.startOffset!, stickiness );\n\t}\n\n\t/**\n\t * Creates a `Position` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param json Plain object to be converted to `Position`.\n\t * @param doc Document object that will be position owner.\n\t * @returns `Position` instance created using given plain object.\n\t */\n\tpublic static fromJSON( json: any, doc: Document ): Position {\n\t\tif ( json.root === '$graveyard' ) {\n\t\t\tconst pos = new Position( doc.graveyard, json.path );\n\t\t\tpos.stickiness = json.stickiness;\n\n\t\t\treturn pos;\n\t\t}\n\n\t\tif ( !doc.getRoot( json.root ) ) {\n\t\t\t/**\n\t\t\t * Cannot create position for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error model-position-fromjson-no-root\n\t\t\t * @param rootName\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'model-position-fromjson-no-root',\n\t\t\t\tdoc,\n\t\t\t\t{ rootName: json.root }\n\t\t\t);\n\t\t}\n\n\t\treturn new Position( doc.getRoot( json.root )!, json.path, json.stickiness );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `${ this.root } [ ${ this.path.join( ', ' ) } ]`;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ModelPosition: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nPosition.prototype.is = function( type: string ): boolean {\n\treturn type === 'position' || type === 'model:position';\n};\n\n/**\n * A flag indicating whether this position is `'before'` or `'after'` or `'same'` as given position.\n * If positions are in different roots `'different'` flag is returned.\n */\nexport type PositionRelation = 'before' | 'after' | 'same' | 'different';\n\n/**\n * Offset or one of the flags.\n */\nexport type PositionOffset = number | 'before' | 'after' | 'end';\n\n/**\n * Represents how position is \"sticking\" with neighbour nodes. Used to define how position should be transformed (moved)\n * in edge cases. Possible values: `'toNone'`, `'toNext'`, `'toPrevious'`.\n *\n * Examples:\n *\n * ```\n * Insert. Position is at | and nodes are inserted at the same position, marked as ^:\n *\n * - sticks to none:           <p>f^|oo</p>  ->  <p>fbar|oo</p>\n * - sticks to next node:      <p>f^|oo</p>  ->  <p>fbar|oo</p>\n * - sticks to previous node:  <p>f|^oo</p>  ->  <p>f|baroo</p>\n * ```\n *\n *\n * Move. Position is at | and range [oo] is moved to position ^:\n *\n * ```\n * - sticks to none:           <p>f|[oo]</p><p>b^ar</p>  ->  <p>f|</p><p>booar</p>\n * - sticks to none:           <p>f[oo]|</p><p>b^ar</p>  ->  <p>f|</p><p>booar</p>\n *\n * - sticks to next node:      <p>f|[oo]</p><p>b^ar</p>  ->  <p>f</p><p>b|ooar</p>\n * - sticks to next node:      <p>f[oo]|</p><p>b^ar</p>  ->  <p>f|</p><p>booar</p>\n *\n * - sticks to previous node:  <p>f|[oo]</p><p>b^ar</p>  ->  <p>f|</p><p>booar</p>\n * - sticks to previous node:  <p>f[oo]|</p><p>b^ar</p>  ->  <p>f</p><p>boo|ar</p>\n * ```\n */\nexport type PositionStickiness = 'toNone' | 'toNext' | 'toPrevious';\n\n/**\n * Returns a text node at the given position.\n *\n * This is a helper function optimized to reuse the position parent instance for performance reasons.\n *\n * Normally, you should use {@link module:engine/model/position~Position#textNode `Position#textNode`}.\n * If you start hitting performance issues with {@link module:engine/model/position~Position#parent `Position#parent`}\n * check if your algorithm does not access it multiple times (which can happen directly or indirectly via other position properties).\n *\n * See https://github.com/ckeditor/ckeditor5/issues/6579.\n *\n * See also:\n *\n * * {@link module:engine/model/position~getNodeAfterPosition}\n * * {@link module:engine/model/position~getNodeBeforePosition}\n *\n * @param position\n * @param positionParent The parent of the given position.\n */\nexport function getTextNodeAtPosition( position: Position, positionParent: Element | DocumentFragment ): Text | null {\n\tconst node = positionParent.getChildAtOffset( position.offset );\n\n\tif ( node && node.is( '$text' ) && node.startOffset! < position.offset ) {\n\t\treturn node;\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns the node after the given position.\n *\n * This is a helper function optimized to reuse the position parent instance and the calculation of the text node at the\n * specific position for performance reasons.\n *\n * Normally, you should use {@link module:engine/model/position~Position#nodeAfter `Position#nodeAfter`}.\n * If you start hitting performance issues with {@link module:engine/model/position~Position#parent `Position#parent`} and/or\n * {@link module:engine/model/position~Position#textNode `Position#textNode`}\n * check if your algorithm does not access those properties multiple times\n * (which can happen directly or indirectly via other position properties).\n *\n * See https://github.com/ckeditor/ckeditor5/issues/6579 and https://github.com/ckeditor/ckeditor5/issues/6582.\n *\n * See also:\n *\n * * {@link module:engine/model/position~getTextNodeAtPosition}\n * * {@link module:engine/model/position~getNodeBeforePosition}\n *\n * @param position Position to check.\n * @param positionParent The parent of the given position.\n * @param textNode Text node at the given position.\n */\nexport function getNodeAfterPosition(\n\tposition: Position,\n\tpositionParent: Element | DocumentFragment,\n\ttextNode: Text | null\n): Node | null {\n\tif ( textNode !== null ) {\n\t\treturn null;\n\t}\n\n\treturn positionParent.getChildAtOffset( position.offset );\n}\n\n/**\n * Returns the node before the given position.\n *\n * Refer to {@link module:engine/model/position~getNodeBeforePosition} for documentation on when to use this util method.\n *\n * See also:\n *\n * * {@link module:engine/model/position~getTextNodeAtPosition}\n * * {@link module:engine/model/position~getNodeAfterPosition}\n *\n * @param position Position to check.\n * @param positionParent The parent of the given position.\n * @param textNode Text node at the given position.\n */\nexport function getNodeBeforePosition(\n\tposition: Position,\n\tpositionParent: Element | DocumentFragment,\n\ttextNode: Text | null\n): Node | null {\n\tif ( textNode !== null ) {\n\t\treturn null;\n\t}\n\n\treturn positionParent.getChild( positionParent.offsetToIndex( position.offset ) - 1 );\n}\n\n/**\n * This is a helper function for `Position#isTouching()`.\n *\n * It checks whether to given positions are touching, considering that they have the same root and paths\n * until given level, and at given level they differ by 1 (so they are branching at `level` point).\n *\n * The exact requirements for touching positions are described in `Position#isTouching()` and also\n * in the body of this function.\n *\n * @param left Position \"on the left\" (it is before `right`).\n * @param right Position \"on the right\" (it is after `left`).\n * @param level Level on which the positions are different.\n */\nfunction checkTouchingBranch( left: Position, right: Position, level: number ): boolean {\n\tif ( level + 1 === left.path.length ) {\n\t\t// Left position does not have any more entries after the point where the positions differ.\n\t\t// [ 2 ] vs [ 3 ]\n\t\t// [ 2 ] vs [ 3, 0, 0 ]\n\t\t// The positions are spread by node at [ 2 ].\n\t\treturn false;\n\t}\n\n\tif ( !checkOnlyZeroes( right.path, level + 1 ) ) {\n\t\t// Right position does not have only zeroes, so we have situation like:\n\t\t// [ 2, maxOffset ] vs [ 3, 1 ]\n\t\t// [ 2, maxOffset ] vs [ 3, 1, 0, 0 ]\n\t\t// The positions are spread by node at [ 3, 0 ].\n\t\treturn false;\n\t}\n\n\tif ( !checkOnlyMaxOffset( left, level + 1 ) ) {\n\t\t// Left position does not have only max offsets, so we have situation like:\n\t\t// [ 2, 4 ] vs [ 3 ]\n\t\t// [ 2, 4 ] vs [ 3, 0, 0 ]\n\t\t// The positions are spread by node at [ 2, 5 ].\n\t\treturn false;\n\t}\n\n\t// Left position has only max offsets and right position has only zeroes or nothing.\n\t// [ 2, maxOffset ] vs [ 3 ]\n\t// [ 2, maxOffset, maxOffset ] vs [ 3, 0 ]\n\t// There are not elements between positions. The positions are touching.\n\treturn true;\n}\n\n/**\n * Checks whether for given array, starting from given index until the end of the array, all items are `0`s.\n *\n * This is a helper function for `Position#isTouching()`.\n */\nfunction checkOnlyZeroes( arr: ReadonlyArray<number>, idx: number ): boolean {\n\twhile ( idx < arr.length ) {\n\t\tif ( arr[ idx ] !== 0 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tidx++;\n\t}\n\n\treturn true;\n}\n\n/**\n * Checks whether for given position, starting from given path level, whether the position is at the end of\n * its parent and whether each element on the path to the position is also at at the end of its parent.\n *\n * This is a helper function for `Position#isTouching()`.\n */\nfunction checkOnlyMaxOffset( pos: Position, level: number ): boolean {\n\tlet parent = pos.parent;\n\tlet idx = pos.path.length - 1;\n\tlet add = 0;\n\n\twhile ( idx >= level ) {\n\t\tif ( pos.path[ idx ] + add !== parent.maxOffset ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// After the first check, we \"go up\", and check whether the position's parent-parent is the last element.\n\t\t// However, we need to add 1 to the value in the path to \"simulate\" moving the path after the parent.\n\t\t// It happens just once.\n\t\tadd = 1;\n\t\tidx--;\n\t\tparent = parent.parent!;\n\t}\n\n\treturn true;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/range\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport Position from './position.js';\nimport TreeWalker, { type TreeWalkerOptions, type TreeWalkerValue } from './treewalker.js';\n\nimport type Document from './document.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type InsertOperation from './operation/insertoperation.js';\nimport type Item from './item.js';\nimport type MergeOperation from './operation/mergeoperation.js';\nimport type MoveOperation from './operation/moveoperation.js';\nimport type Operation from './operation/operation.js';\nimport type SplitOperation from './operation/splitoperation.js';\n\nimport { CKEditorError, compareArrays } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Represents a range in the model tree.\n *\n * A range is defined by its {@link module:engine/model/range~Range#start} and {@link module:engine/model/range~Range#end}\n * positions.\n *\n * You can create range instances via its constructor or the `createRange*()` factory methods of\n * {@link module:engine/model/model~Model} and {@link module:engine/model/writer~Writer}.\n */\nexport default class Range extends TypeCheckable implements Iterable<TreeWalkerValue> {\n\t/**\n\t * Start position.\n\t */\n\tpublic readonly start: Position;\n\n\t/**\n\t * End position.\n\t */\n\tpublic readonly end: Position;\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * @param start The start position.\n\t * @param end The end position. If not set, the range will be collapsed at the `start` position.\n\t */\n\tconstructor( start: Position, end?: Position | null ) {\n\t\tsuper();\n\n\t\tthis.start = Position._createAt( start );\n\t\tthis.end = end ? Position._createAt( end ) : Position._createAt( start );\n\n\t\t// If the range is collapsed, treat in a similar way as a position and set its boundaries stickiness to 'toNone'.\n\t\t// In other case, make the boundaries stick to the \"inside\" of the range.\n\t\tthis.start.stickiness = this.isCollapsed ? 'toNone' : 'toNext';\n\t\tthis.end.stickiness = this.isCollapsed ? 'toNone' : 'toPrevious';\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them together with additional information like length or {@link module:engine/model/position~Position positions},\n\t * grouped as {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t * It iterates over all {@link module:engine/model/textproxy~TextProxy text contents} that are inside the range\n\t * and all the {@link module:engine/model/element~Element}s that are entered into when iterating over this range.\n\t *\n\t * This iterator uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range\n\t * and `ignoreElementEnd` option set to `true`.\n\t */\n\tpublic* [ Symbol.iterator ](): IterableIterator<TreeWalkerValue> {\n\t\tyield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );\n\t}\n\n\t/**\n\t * Describes whether the range is collapsed, that is if {@link #start} and\n\t * {@link #end} positions are equal.\n\t */\n\tpublic get isCollapsed(): boolean {\n\t\treturn this.start.isEqual( this.end );\n\t}\n\n\t/**\n\t * Describes whether this range is flat, that is if {@link #start} position and\n\t * {@link #end} position are in the same {@link module:engine/model/position~Position#parent}.\n\t */\n\tpublic get isFlat(): boolean {\n\t\tconst startParentPath = this.start.getParentPath();\n\t\tconst endParentPath = this.end.getParentPath();\n\n\t\treturn compareArrays( startParentPath, endParentPath ) == 'same';\n\t}\n\n\t/**\n\t * Range root element.\n\t */\n\tpublic get root(): Element | DocumentFragment {\n\t\treturn this.start.root;\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link module:engine/model/position~Position position}.\n\t *\n\t * @param position Position to check.\n\t * @returns `true` if given {@link module:engine/model/position~Position position} is contained\n\t * in this range,`false` otherwise.\n\t */\n\tpublic containsPosition( position: Position ): boolean {\n\t\treturn position.isAfter( this.start ) && position.isBefore( this.end );\n\t}\n\n\t/**\n\t * Checks whether this range contains given {@link ~Range range}.\n\t *\n\t * @param otherRange Range to check.\n\t * @param loose Whether the check is loose or strict. If the check is strict (`false`), compared range cannot\n\t * start or end at the same position as this range boundaries. If the check is loose (`true`), compared range can start, end or\n\t * even be equal to this range. Note that collapsed ranges are always compared in strict mode.\n\t * @returns {Boolean} `true` if given {@link ~Range range} boundaries are contained by this range, `false` otherwise.\n\t */\n\tpublic containsRange( otherRange: Range, loose: boolean = false ): boolean {\n\t\tif ( otherRange.isCollapsed ) {\n\t\t\tloose = false;\n\t\t}\n\n\t\tconst containsStart = this.containsPosition( otherRange.start ) || ( loose && this.start.isEqual( otherRange.start ) );\n\t\tconst containsEnd = this.containsPosition( otherRange.end ) || ( loose && this.end.isEqual( otherRange.end ) );\n\n\t\treturn containsStart && containsEnd;\n\t}\n\n\t/**\n\t * Checks whether given {@link module:engine/model/item~Item} is inside this range.\n\t */\n\tpublic containsItem( item: Item ): boolean {\n\t\tconst pos = Position._createBefore( item );\n\n\t\treturn this.containsPosition( pos ) || this.start.isEqual( pos );\n\t}\n\n\t/**\n\t * Two ranges are equal if their {@link #start} and {@link #end} positions are equal.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns `true` if ranges are equal, `false` otherwise.\n\t */\n\tpublic isEqual( otherRange: Range ): boolean {\n\t\treturn this.start.isEqual( otherRange.start ) && this.end.isEqual( otherRange.end );\n\t}\n\n\t/**\n\t * Checks and returns whether this range intersects with given range.\n\t *\n\t * @param otherRange Range to compare with.\n\t * @returns `true` if ranges intersect, `false` otherwise.\n\t */\n\tpublic isIntersecting( otherRange: Range ): boolean {\n\t\treturn this.start.isBefore( otherRange.end ) && this.end.isAfter( otherRange.start );\n\t}\n\n\t/**\n\t * Computes which part(s) of this {@link ~Range range} is not a part of given {@link ~Range range}.\n\t * Returned array contains zero, one or two {@link ~Range ranges}.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t * let transformed = range.getDifference( otherRange );\n\t * // transformed array has no ranges because `otherRange` contains `range`\n\t *\n\t * otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 3 ] ) );\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has one range: from [ 3 ] to [ 4, 0, 1 ]\n\t *\n\t * otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 4 ] ) );\n\t * transformed = range.getDifference( otherRange );\n\t * // transformed array has two ranges: from [ 2, 7 ] to [ 3 ] and from [ 4 ] to [ 4, 0, 1 ]\n\t * ```\n\t *\n\t * @param otherRange Range to differentiate against.\n\t * @returns The difference between ranges.\n\t */\n\tpublic getDifference( otherRange: Range ): Array<Range> {\n\t\tconst ranges = [];\n\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect.\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the start to the middle of this range.\n\t\t\t\tranges.push( new Range( this.start, otherRange.start ) );\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// add shrunken range - from the middle of this range to the end.\n\t\t\t\tranges.push( new Range( otherRange.end, this.end ) );\n\t\t\t}\n\t\t} else {\n\t\t\t// Ranges do not intersect, return the original range.\n\t\t\tranges.push( new Range( this.start, this.end ) );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an intersection of this {@link ~Range range} and given {@link ~Range range}.\n\t * Intersection is a common part of both of those ranges. If ranges has no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let otherRange = model.createRange( model.createPositionFromPath( root, [ 1 ] ), model.createPositionFromPath( root, [ 2 ] ) );\n\t * let transformed = range.getIntersection( otherRange ); // null - ranges have no common part\n\t *\n\t * otherRange = model.createRange( model.createPositionFromPath( root, [ 3 ] ), model.createPositionFromPath( root, [ 5 ] ) );\n\t * transformed = range.getIntersection( otherRange ); // range from [ 3 ] to [ 4, 0, 1 ]\n\t * ```\n\t *\n\t * @param otherRange Range to check for intersection.\n\t * @returns A common part of given ranges or `null` if ranges have no common part.\n\t */\n\tpublic getIntersection( otherRange: Range ): Range | null {\n\t\tif ( this.isIntersecting( otherRange ) ) {\n\t\t\t// Ranges intersect, so a common range will be returned.\n\t\t\t// At most, it will be same as this range.\n\t\t\tlet commonRangeStart = this.start;\n\t\t\tlet commonRangeEnd = this.end;\n\n\t\t\tif ( this.containsPosition( otherRange.start ) ) {\n\t\t\t\t// Given range start is inside this range. This means thaNt we have to\n\t\t\t\t// shrink common range to the given range start.\n\t\t\t\tcommonRangeStart = otherRange.start;\n\t\t\t}\n\n\t\t\tif ( this.containsPosition( otherRange.end ) ) {\n\t\t\t\t// Given range end is inside this range. This means that we have to\n\t\t\t\t// shrink common range to the given range end.\n\t\t\t\tcommonRangeEnd = otherRange.end;\n\t\t\t}\n\n\t\t\treturn new Range( commonRangeStart, commonRangeEnd );\n\t\t}\n\n\t\t// Ranges do not intersect, so they do not have common part.\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns a range created by joining this {@link ~Range range} with the given {@link ~Range range}.\n\t * If ranges have no common part, returns `null`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let otherRange = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 1 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 2 ] )\n \t * );\n\t * let transformed = range.getJoined( otherRange ); // null - ranges have no common part\n\t *\n\t * otherRange = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 3 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 5 ] )\n\t * );\n\t * transformed = range.getJoined( otherRange ); // range from [ 2, 7 ] to [ 5 ]\n\t * ```\n\t *\n\t * @param otherRange Range to be joined.\n\t * @param loose Whether the intersection check is loose or strict. If the check is strict (`false`),\n\t * ranges are tested for intersection or whether start/end positions are equal. If the check is loose (`true`),\n\t * compared range is also checked if it's {@link module:engine/model/position~Position#isTouching touching} current range.\n\t * @returns A sum of given ranges or `null` if ranges have no common part.\n\t */\n\tpublic getJoined( otherRange: Range, loose: boolean = false ): Range | null {\n\t\tlet shouldJoin = this.isIntersecting( otherRange );\n\n\t\tif ( !shouldJoin ) {\n\t\t\tif ( this.start.isBefore( otherRange.start ) ) {\n\t\t\t\tshouldJoin = loose ? this.end.isTouching( otherRange.start ) : this.end.isEqual( otherRange.start );\n\t\t\t} else {\n\t\t\t\tshouldJoin = loose ? otherRange.end.isTouching( this.start ) : otherRange.end.isEqual( this.start );\n\t\t\t}\n\t\t}\n\n\t\tif ( !shouldJoin ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet startPosition = this.start;\n\t\tlet endPosition = this.end;\n\n\t\tif ( otherRange.start.isBefore( startPosition ) ) {\n\t\t\tstartPosition = otherRange.start;\n\t\t}\n\n\t\tif ( otherRange.end.isAfter( endPosition ) ) {\n\t\t\tendPosition = otherRange.end;\n\t\t}\n\n\t\treturn new Range( startPosition, endPosition );\n\t}\n\n\t/**\n\t * Computes and returns the smallest set of {@link #isFlat flat} ranges, that covers this range in whole.\n\t *\n\t * See an example of a model structure (`[` and `]` are range boundaries):\n\t *\n\t * ```\n\t * root                                                            root\n\t *  |- element DIV                         DIV             P2              P3             DIV\n\t *  |   |- element H                   H        P1        f o o           b a r       H         P4\n\t *  |   |   |- \"fir[st\"             fir[st     lorem                               se]cond     ipsum\n\t *  |   |- element P1\n\t *  |   |   |- \"lorem\"                                              ||\n\t *  |- element P2                                                   ||\n\t *  |   |- \"foo\"                                                    VV\n\t *  |- element P3\n\t *  |   |- \"bar\"                                                   root\n\t *  |- element DIV                         DIV             [P2             P3]             DIV\n\t *  |   |- element H                   H       [P1]       f o o           b a r        H         P4\n\t *  |   |   |- \"se]cond\"            fir[st]    lorem                               [se]cond     ipsum\n\t *  |   |- element P4\n\t *  |   |   |- \"ipsum\"\n\t * ```\n\t *\n\t * As it can be seen, letters contained in the range are: `stloremfoobarse`, spread across different parents.\n\t * We are looking for minimal set of flat ranges that contains the same nodes.\n\t *\n\t * Minimal flat ranges for above range `( [ 0, 0, 3 ], [ 3, 0, 2 ] )` will be:\n\t *\n\t * ```\n\t * ( [ 0, 0, 3 ], [ 0, 0, 5 ] ) = \"st\"\n\t * ( [ 0, 1 ], [ 0, 2 ] ) = element P1 (\"lorem\")\n\t * ( [ 1 ], [ 3 ] ) = element P2, element P3 (\"foobar\")\n\t * ( [ 3, 0, 0 ], [ 3, 0, 2 ] ) = \"se\"\n\t * ```\n\t *\n\t * **Note:** if an {@link module:engine/model/element~Element element} is not wholly contained in this range, it won't be returned\n\t * in any of the returned flat ranges. See in the example how `H` elements at the beginning and at the end of the range\n\t * were omitted. Only their parts that were wholly in the range were returned.\n\t *\n\t * **Note:** this method is not returning flat ranges that contain no nodes.\n\t *\n\t * @returns Array of flat ranges covering this range.\n\t */\n\tpublic getMinimalFlatRanges(): Array<Range> {\n\t\tconst ranges = [];\n\t\tconst diffAt = this.start.getCommonPath( this.end ).length;\n\n\t\tconst pos = Position._createAt( this.start );\n\t\tlet posParent = pos.parent;\n\n\t\t// Go up.\n\t\twhile ( pos.path.length > diffAt + 1 ) {\n\t\t\tconst howMany = posParent.maxOffset - pos.offset;\n\n\t\t\tif ( howMany !== 0 ) {\n\t\t\t\tranges.push( new Range( pos, pos.getShiftedBy( howMany ) ) );\n\t\t\t}\n\n\t\t\t( pos as any ).path = pos.path.slice( 0, -1 );\n\t\t\tpos.offset++;\n\t\t\tposParent = posParent.parent!;\n\t\t}\n\n\t\t// Go down.\n\t\twhile ( pos.path.length <= this.end.path.length ) {\n\t\t\tconst offset = this.end.path[ pos.path.length - 1 ];\n\t\t\tconst howMany = offset - pos.offset;\n\n\t\t\tif ( howMany !== 0 ) {\n\t\t\t\tranges.push( new Range( pos, pos.getShiftedBy( howMany ) ) );\n\t\t\t}\n\n\t\t\tpos.offset = offset;\n\t\t\t( pos.path as Array<number> ).push( 0 );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/treewalker~TreeWalker TreeWalker} instance with this range as a boundary.\n\t *\n\t * For example, to iterate over all items in the entire document root:\n\t *\n\t * ```ts\n\t * // Create a range spanning over the entire root content:\n\t * const range = editor.model.createRangeIn( editor.model.document.getRoot() );\n\t *\n\t * // Iterate over all items in this range:\n\t * for ( const value of range.getWalker() ) {\n\t * \tconsole.log( value.item );\n\t * }\n\t * ```\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t */\n\tpublic getWalker( options: TreeWalkerOptions = {} ): TreeWalker {\n\t\toptions.boundaries = this;\n\n\t\treturn new TreeWalker( options );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/model/item~Item items} that are in this range and returns\n\t * them.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range and `ignoreElementEnd` option\n\t * set to `true`. However it returns only {@link module:engine/model/item~Item model items},\n\t * not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t */\n\tpublic* getItems( options: TreeWalkerOptions = {} ): IterableIterator<Item> {\n\t\toptions.boundaries = this;\n\t\toptions.ignoreElementEnd = true;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.item;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all {@link module:engine/model/position~Position positions} that are boundaries or\n\t * contained in this range.\n\t *\n\t * This method uses {@link module:engine/model/treewalker~TreeWalker} with `boundaries` set to this range. However it returns only\n\t * {@link module:engine/model/position~Position positions}, not {@link module:engine/model/treewalker~TreeWalkerValue}.\n\t *\n\t * You may specify additional options for the tree walker. See {@link module:engine/model/treewalker~TreeWalker} for\n\t * a full list of available options.\n\t *\n\t * @param options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.\n\t */\n\tpublic* getPositions( options: TreeWalkerOptions = {} ): IterableIterator<Position> {\n\t\toptions.boundaries = this;\n\n\t\tconst treeWalker = new TreeWalker( options );\n\n\t\tyield treeWalker.position;\n\n\t\tfor ( const value of treeWalker ) {\n\t\t\tyield value.nextPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Returns a range that is a result of transforming this range by given `operation`.\n\t *\n\t * **Note:** transformation may break one range into multiple ranges (for example, when a part of the range is\n\t * moved to a different part of document tree). For this reason, an array is returned by this method and it\n\t * may contain one or more `Range` instances.\n\t *\n\t * @param operation Operation to transform range by.\n\t * @returns Range which is the result of transformation.\n\t */\n\tpublic getTransformedByOperation( operation: Operation ): Array<Range> {\n\t\tswitch ( operation.type ) {\n\t\t\tcase 'insert':\n\t\t\t\treturn this._getTransformedByInsertOperation( operation as InsertOperation );\n\t\t\tcase 'move':\n\t\t\tcase 'remove':\n\t\t\tcase 'reinsert':\n\t\t\t\treturn this._getTransformedByMoveOperation( operation as MoveOperation );\n\t\t\tcase 'split':\n\t\t\t\treturn [ this._getTransformedBySplitOperation( operation as SplitOperation ) ];\n\t\t\tcase 'merge':\n\t\t\t\treturn [ this._getTransformedByMergeOperation( operation as MergeOperation ) ];\n\t\t}\n\n\t\treturn [ new Range( this.start, this.end ) ];\n\t}\n\n\t/**\n\t * Returns a range that is a result of transforming this range by multiple `operations`.\n\t *\n\t * @see ~Range#getTransformedByOperation\n\t * @param operations Operations to transform the range by.\n\t * @returns Range which is the result of transformation.\n\t */\n\tpublic getTransformedByOperations( operations: Iterable<Operation> ): Array<Range> {\n\t\tconst ranges = [ new Range( this.start, this.end ) ];\n\n\t\tfor ( const operation of operations ) {\n\t\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\t\tconst result = ranges[ i ].getTransformedByOperation( operation );\n\n\t\t\t\tranges.splice( i, 1, ...result );\n\t\t\t\ti += result.length - 1;\n\t\t\t}\n\t\t}\n\n\t\t// It may happen that a range is split into two, and then the part of second \"piece\" is moved into first\n\t\t// \"piece\". In this case we will have incorrect third range, which should not be included in the result --\n\t\t// because it is already included in the first \"piece\". In this loop we are looking for all such ranges that\n\t\t// are inside other ranges and we simply remove them.\n\t\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t\tconst range = ranges[ i ];\n\n\t\t\tfor ( let j = i + 1; j < ranges.length; j++ ) {\n\t\t\t\tconst next = ranges[ j ];\n\n\t\t\t\tif ( range.containsRange( next ) || next.containsRange( range ) || range.isEqual( next ) ) {\n\t\t\t\t\tranges.splice( j, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/model/element~Element} or {@link module:engine/model/documentfragment~DocumentFragment}\n\t * which is a common ancestor of the range's both ends (in which the entire range is contained).\n\t */\n\tpublic getCommonAncestor(): Element | DocumentFragment | null {\n\t\treturn this.start.getCommonAncestor( this.end );\n\t}\n\n\t/**\n\t * Returns an {@link module:engine/model/element~Element Element} contained by the range.\n\t * The element will be returned when it is the **only** node within the range and **fully–contained**\n\t * at the same time.\n\t */\n\tpublic getContainedElement(): Element | null {\n\t\tif ( this.isCollapsed ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst nodeAfterStart = this.start.nodeAfter;\n\t\tconst nodeBeforeEnd = this.end.nodeBefore;\n\n\t\tif ( nodeAfterStart && nodeAfterStart.is( 'element' ) && nodeAfterStart === nodeBeforeEnd ) {\n\t\t\treturn nodeAfterStart;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Converts `Range` to plain object and returns it.\n\t *\n\t * @returns `Node` converted to plain object.\n\t */\n\tpublic toJSON(): unknown {\n\t\treturn {\n\t\t\tstart: this.start.toJSON(),\n\t\t\tend: this.end.toJSON()\n\t\t};\n\t}\n\n\t/**\n\t * Returns a new range that is equal to current range.\n\t */\n\tpublic clone(): this {\n\t\treturn new ( this.constructor as any )( this.start, this.end );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by insert operation.\n\t *\n\t * One or more ranges may be returned as a result of this transformation.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedByInsertOperation( operation: InsertOperation, spread: boolean = false ): Array<Range> {\n\t\treturn this._getTransformedByInsertion( operation.position, operation.howMany, spread );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by move operation.\n\t *\n\t * One or more ranges may be returned as a result of this transformation.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedByMoveOperation( operation: MoveOperation, spread: boolean = false ): Array<Range> {\n\t\tconst sourcePosition = operation.sourcePosition;\n\t\tconst howMany = operation.howMany;\n\t\tconst targetPosition = operation.targetPosition;\n\n\t\treturn this._getTransformedByMove( sourcePosition, targetPosition, howMany, spread );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by split operation.\n\t *\n\t * Always one range is returned. The transformation is done in a way to not break the range.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedBySplitOperation( operation: SplitOperation ): Range {\n\t\tconst start = this.start._getTransformedBySplitOperation( operation );\n\t\tlet end = this.end._getTransformedBySplitOperation( operation );\n\n\t\tif ( this.end.isEqual( operation.insertionPosition ) ) {\n\t\t\tend = this.end.getShiftedBy( 1 );\n\t\t}\n\n\t\t// Below may happen when range contains graveyard element used by split operation.\n\t\tif ( start.root != end.root ) {\n\t\t\t// End position was next to the moved graveyard element and was moved with it.\n\t\t\t// Fix it by using old `end` which has proper `root`.\n\t\t\tend = this.end.getShiftedBy( -1 );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Returns a result of transforming a copy of this range by merge operation.\n\t *\n\t * Always one range is returned. The transformation is done in a way to not break the range.\n\t *\n\t * @internal\n\t */\n\tpublic _getTransformedByMergeOperation( operation: MergeOperation ): Range {\n\t\t// Special case when the marker is set on \"the closing tag\" of an element. Marker can be set like that during\n\t\t// transformations, especially when a content of a few block elements were removed. For example:\n\t\t//\n\t\t// {} is the transformed range, [] is the removed range.\n\t\t// <p>F[o{o</p><p>B}ar</p><p>Xy]z</p>\n\t\t//\n\t\t// <p>Fo{o</p><p>B}ar</p><p>z</p>\n\t\t// <p>F{</p><p>B}ar</p><p>z</p>\n\t\t// <p>F{</p>}<p>z</p>\n\t\t// <p>F{}z</p>\n\t\t//\n\t\tif ( this.start.isEqual( operation.targetPosition ) && this.end.isEqual( operation.deletionPosition ) ) {\n\t\t\treturn new Range( this.start );\n\t\t}\n\n\t\tlet start = this.start._getTransformedByMergeOperation( operation );\n\t\tlet end = this.end._getTransformedByMergeOperation( operation );\n\n\t\tif ( start.root != end.root ) {\n\t\t\t// This happens when the end position was next to the merged (deleted) element.\n\t\t\t// Then, the end position was moved to the graveyard root. In this case we need to fix\n\t\t\t// the range cause its boundaries would be in different roots.\n\t\t\tend = this.end.getShiftedBy( -1 );\n\t\t}\n\n\t\tif ( start.isAfter( end ) ) {\n\t\t\t// This happens in three following cases:\n\t\t\t//\n\t\t\t// Case 1: Merge operation source position is before the target position (due to some transformations, OT, etc.)\n\t\t\t//         This means that start can be moved before the end of the range.\n\t\t\t//\n\t\t\t// Before: <p>a{a</p><p>b}b</p><p>cc</p>\n\t\t\t// Merge:  <p>b}b</p><p>cca{a</p>\n\t\t\t// Fix:    <p>{b}b</p><p>ccaa</p>\n\t\t\t//\n\t\t\t// Case 2: Range start is before merged node but not directly.\n\t\t\t//         Result should include all nodes that were in the original range.\n\t\t\t//\n\t\t\t// Before: <p>aa</p>{<p>cc</p><p>b}b</p>\n\t\t\t// Merge:  <p>aab}b</p>{<p>cc</p>\n\t\t\t// Fix:    <p>aa{bb</p><p>cc</p>}\n\t\t\t//\n\t\t\t//         The range is expanded by an additional `b` letter but it is better than dropping the whole `cc` paragraph.\n\t\t\t//\n\t\t\t// Case 3: Range start is directly before merged node.\n\t\t\t//         Resulting range should include only nodes from the merged element:\n\t\t\t//\n\t\t\t// Before: <p>aa</p>{<p>b}b</p><p>cc</p>\n\t\t\t// Merge:  <p>aab}b</p>{<p>cc</p>\n\t\t\t// Fix:    <p>aa{b}b</p><p>cc</p>\n\t\t\t//\n\n\t\t\tif ( operation.sourcePosition.isBefore( operation.targetPosition ) ) {\n\t\t\t\t// Case 1.\n\t\t\t\tstart = Position._createAt( end );\n\t\t\t\tstart.offset = 0;\n\t\t\t} else {\n\t\t\t\tif ( !operation.deletionPosition.isEqual( start ) ) {\n\t\t\t\t\t// Case 2.\n\t\t\t\t\tend = operation.deletionPosition;\n\t\t\t\t}\n\n\t\t\t\t// In both case 2 and 3 start is at the end of the merge-to element.\n\t\t\t\tstart = operation.targetPosition;\n\t\t\t}\n\n\t\t\treturn new Range( start, end );\n\t\t}\n\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Returns an array containing one or two {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by inserting `howMany` nodes at `insertPosition`. Two {@link ~Range ranges} are\n\t * returned if the insertion was inside this {@link ~Range range} and `spread` is set to `true`.\n\t *\n\t * Examples:\n\t *\n\t * ```ts\n\t * let range = model.createRange(\n\t * \tmodel.createPositionFromPath( root, [ 2, 7 ] ),\n\t * \tmodel.createPositionFromPath( root, [ 4, 0, 1 ] )\n\t * );\n\t * let transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 1 ] ), 2 );\n\t * // transformed array has one range from [ 4, 7 ] to [ 6, 0, 1 ]\n\t *\n\t * transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 4, 0, 0 ] ), 4 );\n\t * // transformed array has one range from [ 2, 7 ] to [ 4, 0, 5 ]\n\t *\n\t * transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4 );\n\t * // transformed array has one range, which is equal to original range\n\t *\n\t * transformed = range._getTransformedByInsertion( model.createPositionFromPath( root, [ 3, 2 ] ), 4, true );\n\t * // transformed array has two ranges: from [ 2, 7 ] to [ 3, 2 ] and from [ 3, 6 ] to [ 4, 0, 1 ]\n\t * ```\n\t *\n\t * @internal\n\t * @param insertPosition Position where nodes are inserted.\n\t * @param howMany How many nodes are inserted.\n\t * @param spread Flag indicating whether this range should be spread if insertion\n\t * was inside the range. Defaults to `false`.\n\t * @returns Result of the transformation.\n\t */\n\tpublic _getTransformedByInsertion( insertPosition: Position, howMany: number, spread: boolean = false ): Array<Range> {\n\t\tif ( spread && this.containsPosition( insertPosition ) ) {\n\t\t\t// Range has to be spread. The first part is from original start to the spread point.\n\t\t\t// The other part is from spread point to the original end, but transformed by\n\t\t\t// insertion to reflect insertion changes.\n\n\t\t\treturn [\n\t\t\t\tnew Range( this.start, insertPosition ),\n\t\t\t\tnew Range(\n\t\t\t\t\tinsertPosition.getShiftedBy( howMany ),\n\t\t\t\t\tthis.end._getTransformedByInsertion( insertPosition, howMany )\n\t\t\t\t)\n\t\t\t];\n\t\t} else {\n\t\t\tconst range = new Range( this.start, this.end );\n\n\t\t\t( range as any ).start = range.start._getTransformedByInsertion( insertPosition, howMany );\n\t\t\t( range as any ).end = range.end._getTransformedByInsertion( insertPosition, howMany );\n\n\t\t\treturn [ range ];\n\t\t}\n\t}\n\n\t/**\n\t * Returns an array containing {@link ~Range ranges} that are a result of transforming this\n\t * {@link ~Range range} by moving `howMany` nodes from `sourcePosition` to `targetPosition`.\n\t *\n\t * @internal\n\t * @param sourcePosition Position from which nodes are moved.\n\t * @param targetPosition Position to where nodes are moved.\n\t * @param howMany How many nodes are moved.\n\t * @param spread Whether the range should be spread if the move points inside the range.\n\t * @returns  Result of the transformation.\n\t */\n\tpublic _getTransformedByMove(\n\t\tsourcePosition: Position,\n\t\ttargetPosition: Position,\n\t\thowMany: number,\n\t\tspread: boolean = false\n\t): Array<Range> {\n\t\t// Special case for transforming a collapsed range. Just transform it like a position.\n\t\tif ( this.isCollapsed ) {\n\t\t\tconst newPos = this.start._getTransformedByMove( sourcePosition, targetPosition, howMany );\n\n\t\t\treturn [ new Range( newPos ) ];\n\t\t}\n\n\t\t// Special case for transformation when a part of the range is moved towards the range.\n\t\t//\n\t\t// Examples:\n\t\t//\n\t\t// <div><p>ab</p><p>c[d</p></div><p>e]f</p> --> <div><p>ab</p></div><p>c[d</p><p>e]f</p>\n\t\t// <p>e[f</p><div><p>a]b</p><p>cd</p></div> --> <p>e[f</p><p>a]b</p><div><p>cd</p></div>\n\t\t//\n\t\t// Without this special condition, the default algorithm leaves an \"artifact\" range from one of `differenceSet` parts:\n\t\t//\n\t\t// <div><p>ab</p><p>c[d</p></div><p>e]f</p> --> <div><p>ab</p>{</div>}<p>c[d</p><p>e]f</p>\n\t\t//\n\t\t// This special case is applied only if the range is to be kept together (not spread).\n\t\tconst moveRange = Range._createFromPositionAndShift( sourcePosition, howMany );\n\t\tconst insertPosition = targetPosition._getTransformedByDeletion( sourcePosition, howMany );\n\n\t\tif ( this.containsPosition( targetPosition ) && !spread ) {\n\t\t\tif ( moveRange.containsPosition( this.start ) || moveRange.containsPosition( this.end ) ) {\n\t\t\t\tconst start = this.start._getTransformedByMove( sourcePosition, targetPosition, howMany );\n\t\t\t\tconst end = this.end._getTransformedByMove( sourcePosition, targetPosition, howMany );\n\n\t\t\t\treturn [ new Range( start, end ) ];\n\t\t\t}\n\t\t}\n\n\t\t// Default algorithm.\n\t\tlet result: Array<Range>;\n\n\t\tconst differenceSet = this.getDifference( moveRange );\n\t\tlet difference = null;\n\n\t\tconst common = this.getIntersection( moveRange );\n\n\t\tif ( differenceSet.length == 1 ) {\n\t\t\t// `moveRange` and this range may intersect but may be separate.\n\t\t\tdifference = new Range(\n\t\t\t\tdifferenceSet[ 0 ].start._getTransformedByDeletion( sourcePosition, howMany )!,\n\t\t\t\tdifferenceSet[ 0 ].end._getTransformedByDeletion( sourcePosition, howMany )!\n\t\t\t);\n\t\t} else if ( differenceSet.length == 2 ) {\n\t\t\t// `moveRange` is inside this range.\n\t\t\tdifference = new Range(\n\t\t\t\tthis.start,\n\t\t\t\tthis.end._getTransformedByDeletion( sourcePosition, howMany )\n\t\t\t);\n\t\t} // else, `moveRange` contains this range.\n\n\t\tif ( difference ) {\n\t\t\tresult = difference._getTransformedByInsertion( insertPosition!, howMany, common !== null || spread );\n\t\t} else {\n\t\t\tresult = [];\n\t\t}\n\n\t\tif ( common ) {\n\t\t\tconst transformedCommon = new Range(\n\t\t\t\tcommon.start._getCombined( moveRange.start, insertPosition! ),\n\t\t\t\tcommon.end._getCombined( moveRange.start, insertPosition! )\n\t\t\t);\n\n\t\t\tif ( result.length == 2 ) {\n\t\t\t\tresult.splice( 1, 0, transformedCommon );\n\t\t\t} else {\n\t\t\t\tresult.push( transformedCommon );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns a copy of this range that is transformed by deletion of `howMany` nodes from `deletePosition`.\n\t *\n\t * If the deleted range is intersecting with the transformed range, the transformed range will be shrank.\n\t *\n\t * If the deleted range contains transformed range, `null` will be returned.\n\t *\n\t * @internal\n\t * @param deletionPosition Position from which nodes are removed.\n\t * @param howMany How many nodes are removed.\n\t * @returns Result of the transformation.\n\t */\n\tpublic _getTransformedByDeletion( deletePosition: Position, howMany: number ): Range | null {\n\t\tlet newStart = this.start._getTransformedByDeletion( deletePosition, howMany );\n\t\tlet newEnd = this.end._getTransformedByDeletion( deletePosition, howMany );\n\n\t\tif ( newStart == null && newEnd == null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( newStart == null ) {\n\t\t\tnewStart = deletePosition;\n\t\t}\n\n\t\tif ( newEnd == null ) {\n\t\t\tnewEnd = deletePosition;\n\t\t}\n\n\t\treturn new Range( newStart, newEnd );\n\t}\n\n\t/**\n\t * Creates a new range, spreading from specified {@link module:engine/model/position~Position position} to a position moved by\n\t * given `shift`. If `shift` is a negative value, shifted position is treated as the beginning of the range.\n\t *\n\t * @internal\n\t * @param position Beginning of the range.\n\t * @param shift How long the range should be.\n\t */\n\tpublic static _createFromPositionAndShift( position: Position, shift: number ): Range {\n\t\tconst start = position;\n\t\tconst end = position.getShiftedBy( shift );\n\n\t\treturn shift > 0 ? new this( start, end ) : new this( end, start );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @internal\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic static _createIn( element: Element | DocumentFragment ): Range {\n\t\treturn new this( Position._createAt( element, 0 ), Position._createAt( element, element.maxOffset ) );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/model/item~Item model item} and ends after it.\n\t *\n\t * @internal\n\t */\n\tpublic static _createOn( item: Item ): Range {\n\t\treturn this._createFromPositionAndShift( Position._createBefore( item ), item.offsetSize );\n\t}\n\n\t/**\n\t * Combines all ranges from the passed array into a one range. At least one range has to be passed.\n\t * Passed ranges must not have common parts.\n\t *\n\t * The first range from the array is a reference range. If other ranges start or end on the exactly same position where\n\t * the reference range, they get combined into one range.\n\t *\n\t * ```\n\t * [  ][]  [    ][ ][             ][ ][]  [  ]  // Passed ranges, shown sorted\n\t * [    ]                                       // The result of the function if the first range was a reference range.\n\t *         [                           ]        // The result of the function if the third-to-seventh range was a reference range.\n\t *                                        [  ]  // The result of the function if the last range was a reference range.\n\t * ```\n\t *\n\t * @internal\n\t * @param ranges Ranges to combine.\n\t * @returns Combined range.\n\t */\n\tpublic static _createFromRanges( ranges: Array<Range> ): Range {\n\t\tif ( ranges.length === 0 ) {\n\t\t\t/**\n\t\t\t * At least one range has to be passed to\n\t\t\t * {@link module:engine/model/range~Range._createFromRanges `Range._createFromRanges()`}.\n\t\t\t *\n\t\t\t * @error range-create-from-ranges-empty-array\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'range-create-from-ranges-empty-array',\n\t\t\t\tnull\n\t\t\t);\n\t\t} else if ( ranges.length == 1 ) {\n\t\t\treturn ranges[ 0 ].clone();\n\t\t}\n\n\t\t// 1. Set the first range in `ranges` array as a reference range.\n\t\t// If we are going to return just a one range, one of the ranges need to be the reference one.\n\t\t// Other ranges will be stuck to that range, if possible.\n\t\tconst ref = ranges[ 0 ];\n\n\t\t// 2. Sort all the ranges, so it's easier to process them.\n\t\tranges.sort( ( a, b ) => {\n\t\t\treturn a.start.isAfter( b.start ) ? 1 : -1;\n\t\t} );\n\n\t\t// 3. Check at which index the reference range is now.\n\t\tconst refIndex = ranges.indexOf( ref );\n\n\t\t// 4. At this moment we don't need the original range.\n\t\t// We are going to modify the result, and we need to return a new instance of Range.\n\t\t// We have to create a copy of the reference range.\n\t\tconst result = new this( ref.start, ref.end );\n\n\t\t// 5. Ranges should be checked and glued starting from the range that is closest to the reference range.\n\t\t// Since ranges are sorted, start with the range with index that is closest to reference range index.\n\t\tfor ( let i = refIndex - 1; i >= 0; i-- ) {\n\t\t\tif ( ranges[ i ].end.isEqual( result.start ) ) {\n\t\t\t\t( result as any ).start = Position._createAt( ranges[ i ].start );\n\t\t\t} else {\n\t\t\t\t// If ranges are not starting/ending at the same position there is no point in looking further.\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// 6. Ranges should be checked and glued starting from the range that is closest to the reference range.\n\t\t// Since ranges are sorted, start with the range with index that is closest to reference range index.\n\t\tfor ( let i = refIndex + 1; i < ranges.length; i++ ) {\n\t\t\tif ( ranges[ i ].start.isEqual( result.end ) ) {\n\t\t\t\t( result as any ).end = Position._createAt( ranges[ i ].end );\n\t\t\t} else {\n\t\t\t\t// If ranges are not starting/ending at the same position there is no point in looking further.\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Creates a `Range` instance from given plain object (i.e. parsed JSON string).\n\t *\n\t * @param json Plain object to be converted to `Range`.\n\t * @param doc Document object that will be range owner.\n\t * @returns `Range` instance created using given plain object.\n\t */\n\tpublic static fromJSON( json: any, doc: Document ): Range {\n\t\treturn new this( Position.fromJSON( json.start, doc ), Position.fromJSON( json.end, doc ) );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `${ this.root } [ ${ this.start.path.join( ', ' ) } ] - [ ${ this.end.path.join( ', ' ) } ]`;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ModelPosition: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRange.prototype.is = function( type: string ): boolean {\n\treturn type === 'range' || type === 'model:range';\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/conversion/mapper\n */\n\nimport ModelPosition from '../model/position.js';\nimport ModelRange from '../model/range.js';\n\nimport ViewPosition from '../view/position.js';\nimport ViewRange from '../view/range.js';\nimport ViewText from '../view/text.js';\n\nimport { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';\n\nimport type ViewDocumentFragment from '../view/documentfragment.js';\nimport type ViewElement from '../view/element.js';\nimport type ModelElement from '../model/element.js';\nimport type ModelDocumentFragment from '../model/documentfragment.js';\nimport type ViewNode from '../view/node.js';\n\n/**\n * Maps elements, positions and markers between the {@link module:engine/view/document~Document view} and\n * the {@link module:engine/model/model model}.\n *\n * The instance of the Mapper used for the editing pipeline is available in\n * {@link module:engine/controller/editingcontroller~EditingController#mapper `editor.editing.mapper`}.\n *\n * Mapper uses bound elements to find corresponding elements and positions, so, to get proper results,\n * all model elements should be {@link module:engine/conversion/mapper~Mapper#bindElements bound}.\n *\n * To map the complex model to/from view relations, you may provide custom callbacks for the\n * {@link module:engine/conversion/mapper~Mapper#event:modelToViewPosition modelToViewPosition event} and\n * {@link module:engine/conversion/mapper~Mapper#event:viewToModelPosition viewToModelPosition event} that are fired whenever\n * a position mapping request occurs.\n * Those events are fired by the {@link module:engine/conversion/mapper~Mapper#toViewPosition toViewPosition}\n * and {@link module:engine/conversion/mapper~Mapper#toModelPosition toModelPosition} methods. `Mapper` adds its own default callbacks\n * with `'lowest'` priority. To override default `Mapper` mapping, add custom callback with higher priority and\n * stop the event.\n */\nexport default class Mapper extends /* #__PURE__ */ EmitterMixin() {\n\t/**\n\t * Model element to view element mapping.\n\t */\n\tprivate _modelToViewMapping = new WeakMap<ModelElement | ModelDocumentFragment, ViewElement | ViewDocumentFragment>();\n\n\t/**\n\t * View element to model element mapping.\n\t */\n\tprivate _viewToModelMapping = new WeakMap<ViewElement | ViewDocumentFragment, ModelElement | ModelDocumentFragment>();\n\n\t/**\n\t * A map containing callbacks between view element names and functions evaluating length of view elements\n\t * in model.\n\t */\n\tprivate _viewToModelLengthCallbacks = new Map<string, ( element: ViewElement ) => number>();\n\n\t/**\n\t * Model marker name to view elements mapping.\n\t *\n\t * Keys are `String`s while values are `Set`s with {@link module:engine/view/element~Element view elements}.\n\t * One marker (name) can be mapped to multiple elements.\n\t */\n\tprivate _markerNameToElements = new Map<string, Set<ViewElement>>();\n\n\t/**\n\t * View element to model marker names mapping.\n\t *\n\t * This is reverse to {@link ~Mapper#_markerNameToElements} map.\n\t */\n\tprivate _elementToMarkerNames = new Map<ViewElement, Set<string>>();\n\n\t/**\n\t * The map of removed view elements with their current root (used for deferred unbinding).\n\t */\n\tprivate _deferredBindingRemovals = new Map<ViewElement, ViewElement | ViewDocumentFragment>();\n\n\t/**\n\t * Stores marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element\n\t * has been removed, moved or renamed).\n\t */\n\tprivate _unboundMarkerNames = new Set<string>();\n\n\t/**\n\t * Creates an instance of the mapper.\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t// Default mapper algorithm for mapping model position to view position.\n\t\tthis.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', ( evt, data ) => {\n\t\t\tif ( data.viewPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst viewContainer = this._modelToViewMapping.get( data.modelPosition.parent as ModelElement );\n\n\t\t\tif ( !viewContainer ) {\n\t\t\t\t/**\n\t\t\t\t * A model position could not be mapped to the view because the parent of the model position\n\t\t\t\t * does not have a mapped view element (might have not been converted yet or it has no converter).\n\t\t\t\t *\n\t\t\t\t * Make sure that the model element is correctly converted to the view.\n\t\t\t\t *\n\t\t\t\t * @error mapping-model-position-view-parent-not-found\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'mapping-model-position-view-parent-not-found', this, { modelPosition: data.modelPosition } );\n\t\t\t}\n\n\t\t\tdata.viewPosition = this.findPositionIn( viewContainer, data.modelPosition.offset );\n\t\t}, { priority: 'low' } );\n\n\t\t// Default mapper algorithm for mapping view position to model position.\n\t\tthis.on<MapperViewToModelPositionEvent>( 'viewToModelPosition', ( evt, data ) => {\n\t\t\tif ( data.modelPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst viewBlock = this.findMappedViewAncestor( data.viewPosition );\n\t\t\tconst modelParent = this._viewToModelMapping.get( viewBlock );\n\t\t\tconst modelOffset = this._toModelOffset( data.viewPosition.parent as ViewElement, data.viewPosition.offset, viewBlock );\n\n\t\t\tdata.modelPosition = ModelPosition._createAt( modelParent!, modelOffset );\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Marks model and view elements as corresponding. Corresponding elements can be retrieved by using\n\t * the {@link module:engine/conversion/mapper~Mapper#toModelElement toModelElement} and\n\t * {@link module:engine/conversion/mapper~Mapper#toViewElement toViewElement} methods.\n\t * The information that elements are bound is also used to translate positions.\n\t *\n\t * @param modelElement Model element.\n\t * @param viewElement View element.\n\t */\n\tpublic bindElements(\n\t\tmodelElement: ModelElement | ModelDocumentFragment,\n\t\tviewElement: ViewElement | ViewDocumentFragment\n\t): void {\n\t\tthis._modelToViewMapping.set( modelElement, viewElement );\n\t\tthis._viewToModelMapping.set( viewElement, modelElement );\n\t}\n\n\t/**\n\t * Unbinds the given {@link module:engine/view/element~Element view element} from the map.\n\t *\n\t * **Note:** view-to-model binding will be removed, if it existed. However, corresponding model-to-view binding\n\t * will be removed only if model element is still bound to the passed `viewElement`.\n\t *\n\t * This behavior allows for re-binding model element to another view element without fear of losing the new binding\n\t * when the previously bound view element is unbound.\n\t *\n\t * @param viewElement View element to unbind.\n\t * @param options The options object.\n\t * @param options.defer Controls whether the binding should be removed immediately or deferred until a\n\t * {@link #flushDeferredBindings `flushDeferredBindings()`} call.\n\t */\n\tpublic unbindViewElement(\n\t\tviewElement: ViewElement,\n\t\toptions: { defer?: boolean } = {}\n\t): void {\n\t\tconst modelElement = this.toModelElement( viewElement )!;\n\n\t\tif ( this._elementToMarkerNames.has( viewElement ) ) {\n\t\t\tfor ( const markerName of this._elementToMarkerNames.get( viewElement )! ) {\n\t\t\t\tthis._unboundMarkerNames.add( markerName );\n\t\t\t}\n\t\t}\n\n\t\tif ( options.defer ) {\n\t\t\tthis._deferredBindingRemovals.set( viewElement, viewElement.root );\n\t\t} else {\n\t\t\tthis._viewToModelMapping.delete( viewElement );\n\n\t\t\tif ( this._modelToViewMapping.get( modelElement ) == viewElement ) {\n\t\t\t\tthis._modelToViewMapping.delete( modelElement );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Unbinds the given {@link module:engine/model/element~Element model element} from the map.\n\t *\n\t * **Note:** the model-to-view binding will be removed, if it existed. However, the corresponding view-to-model binding\n\t * will be removed only if the view element is still bound to the passed `modelElement`.\n\t *\n\t * This behavior lets for re-binding view element to another model element without fear of losing the new binding\n\t * when the previously bound model element is unbound.\n\t *\n\t * @param modelElement Model element to unbind.\n\t */\n\tpublic unbindModelElement( modelElement: ModelElement ): void {\n\t\tconst viewElement = this.toViewElement( modelElement )!;\n\n\t\tthis._modelToViewMapping.delete( modelElement );\n\n\t\tif ( this._viewToModelMapping.get( viewElement ) == modelElement ) {\n\t\t\tthis._viewToModelMapping.delete( viewElement );\n\t\t}\n\t}\n\n\t/**\n\t * Binds the given marker name with the given {@link module:engine/view/element~Element view element}. The element\n\t * will be added to the current set of elements bound with the given marker name.\n\t *\n\t * @param element Element to bind.\n\t * @param name Marker name.\n\t */\n\tpublic bindElementToMarker( element: ViewElement, name: string ): void {\n\t\tconst elements = this._markerNameToElements.get( name ) || new Set();\n\t\telements.add( element );\n\n\t\tconst names = this._elementToMarkerNames.get( element ) || new Set();\n\t\tnames.add( name );\n\n\t\tthis._markerNameToElements.set( name, elements );\n\t\tthis._elementToMarkerNames.set( element, names );\n\t}\n\n\t/**\n\t * Unbinds an element from given marker name.\n\t *\n\t * @param element Element to unbind.\n\t * @param name Marker name.\n\t */\n\tpublic unbindElementFromMarkerName( element: ViewElement, name: string ): void {\n\t\tconst nameToElements = this._markerNameToElements.get( name );\n\n\t\tif ( nameToElements ) {\n\t\t\tnameToElements.delete( element );\n\n\t\t\tif ( nameToElements.size == 0 ) {\n\t\t\t\tthis._markerNameToElements.delete( name );\n\t\t\t}\n\t\t}\n\n\t\tconst elementToNames = this._elementToMarkerNames.get( element );\n\n\t\tif ( elementToNames ) {\n\t\t\telementToNames.delete( name );\n\n\t\t\tif ( elementToNames.size == 0 ) {\n\t\t\t\tthis._elementToMarkerNames.delete( element );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns all marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element\n\t * has been removed, moved or renamed) since the last flush. After returning, the marker names list is cleared.\n\t */\n\tpublic flushUnboundMarkerNames(): Array<string> {\n\t\tconst markerNames = Array.from( this._unboundMarkerNames );\n\n\t\tthis._unboundMarkerNames.clear();\n\n\t\treturn markerNames;\n\t}\n\n\t/**\n\t * Unbinds all deferred binding removals of view elements that in the meantime were not re-attached to some root or document fragment.\n\t *\n\t * See: {@link #unbindViewElement `unbindViewElement()`}.\n\t */\n\tpublic flushDeferredBindings(): void {\n\t\tfor ( const [ viewElement, root ] of this._deferredBindingRemovals ) {\n\t\t\t// Unbind it only if it wasn't re-attached to some root or document fragment.\n\t\t\tif ( viewElement.root == root ) {\n\t\t\t\tthis.unbindViewElement( viewElement );\n\t\t\t}\n\t\t}\n\n\t\tthis._deferredBindingRemovals = new Map();\n\t}\n\n\t/**\n\t * Removes all model to view and view to model bindings.\n\t */\n\tpublic clearBindings(): void {\n\t\tthis._modelToViewMapping = new WeakMap();\n\t\tthis._viewToModelMapping = new WeakMap();\n\t\tthis._markerNameToElements = new Map();\n\t\tthis._elementToMarkerNames = new Map();\n\t\tthis._unboundMarkerNames = new Set();\n\t\tthis._deferredBindingRemovals = new Map();\n\t}\n\n\t/**\n\t * Gets the corresponding model element.\n\t *\n\t * **Note:** {@link module:engine/view/uielement~UIElement} does not have corresponding element in model.\n\t *\n\t * @label ELEMENT\n\t * @param viewElement View element.\n\t * @returns Corresponding model element or `undefined` if not found.\n\t */\n\tpublic toModelElement( viewElement: ViewElement ): ModelElement | undefined;\n\n\t/**\n\t * Gets the corresponding model document fragment.\n\t *\n\t * @label DOCUMENT_FRAGMENT\n\t * @param viewDocumentFragment View document fragment.\n\t * @returns Corresponding model document fragment or `undefined` if not found.\n\t */\n\tpublic toModelElement( viewDocumentFragment: ViewDocumentFragment ): ModelDocumentFragment | undefined;\n\n\tpublic toModelElement( viewElement: ViewElement | ViewDocumentFragment ): ModelElement | ModelDocumentFragment | undefined {\n\t\treturn this._viewToModelMapping.get( viewElement );\n\t}\n\n\t/**\n\t * Gets the corresponding view element.\n\t *\n\t * @label ELEMENT\n\t * @param modelElement Model element.\n\t * @returns Corresponding view element or `undefined` if not found.\n\t */\n\tpublic toViewElement( modelElement: ModelElement ): ViewElement | undefined;\n\n\t/**\n\t * Gets the corresponding view document fragment.\n\t *\n\t * @label DOCUMENT_FRAGMENT\n\t * @param modelDocumentFragment Model document fragment.\n\t * @returns Corresponding view document fragment or `undefined` if not found.\n\t */\n\tpublic toViewElement( modelDocumentFragment: ModelDocumentFragment ): ViewDocumentFragment | undefined;\n\n\tpublic toViewElement( modelElement: ModelElement | ModelDocumentFragment ): ViewElement | ViewDocumentFragment | undefined {\n\t\treturn this._modelToViewMapping.get( modelElement );\n\t}\n\n\t/**\n\t * Gets the corresponding model range.\n\t *\n\t * @param viewRange View range.\n\t * @returns Corresponding model range.\n\t */\n\tpublic toModelRange( viewRange: ViewRange ): ModelRange {\n\t\treturn new ModelRange( this.toModelPosition( viewRange.start ), this.toModelPosition( viewRange.end ) );\n\t}\n\n\t/**\n\t * Gets the corresponding view range.\n\t *\n\t * @param modelRange Model range.\n\t * @returns Corresponding view range.\n\t */\n\tpublic toViewRange( modelRange: ModelRange ): ViewRange {\n\t\treturn new ViewRange( this.toViewPosition( modelRange.start ), this.toViewPosition( modelRange.end ) );\n\t}\n\n\t/**\n\t * Gets the corresponding model position.\n\t *\n\t * @fires viewToModelPosition\n\t * @param viewPosition View position.\n\t * @returns Corresponding model position.\n\t */\n\tpublic toModelPosition( viewPosition: ViewPosition ): ModelPosition {\n\t\tconst data: MapperViewToModelPositionEventData = {\n\t\t\tviewPosition,\n\t\t\tmapper: this\n\t\t};\n\n\t\tthis.fire<MapperViewToModelPositionEvent>( 'viewToModelPosition', data );\n\n\t\treturn data.modelPosition!;\n\t}\n\n\t/**\n\t * Gets the corresponding view position.\n\t *\n\t * @fires modelToViewPosition\n\t * @param modelPosition Model position.\n\t * @param options Additional options for position mapping process.\n\t * @param options.isPhantom Should be set to `true` if the model position to map is pointing to a place\n\t * in model tree which no longer exists. For example, it could be an end of a removed model range.\n\t * @returns Corresponding view position.\n\t */\n\tpublic toViewPosition(\n\t\tmodelPosition: ModelPosition,\n\t\toptions: { isPhantom?: boolean } = {}\n\t): ViewPosition {\n\t\tconst data: MapperModelToViewPositionEventData = {\n\t\t\tmodelPosition,\n\t\t\tmapper: this,\n\t\t\tisPhantom: options.isPhantom\n\t\t};\n\n\t\tthis.fire<MapperModelToViewPositionEvent>( 'modelToViewPosition', data );\n\n\t\treturn data.viewPosition!;\n\t}\n\n\t/**\n\t * Gets all view elements bound to the given marker name.\n\t *\n\t * @param name Marker name.\n\t * @returns View elements bound with the given marker name or `null`\n\t * if no elements are bound to the given marker name.\n\t */\n\tpublic markerNameToElements( name: string ): Set<ViewElement> | null {\n\t\tconst boundElements = this._markerNameToElements.get( name );\n\n\t\tif ( !boundElements ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst elements = new Set<ViewElement>();\n\n\t\tfor ( const element of boundElements ) {\n\t\t\tif ( element.is( 'attributeElement' ) ) {\n\t\t\t\tfor ( const clone of element.getElementsWithSameId() ) {\n\t\t\t\t\telements.add( clone );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\telements.add( element );\n\t\t\t}\n\t\t}\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Registers a callback that evaluates the length in the model of a view element with the given name.\n\t *\n\t * The callback is fired with one argument, which is a view element instance. The callback is expected to return\n\t * a number representing the length of the view element in the model.\n\t *\n\t * ```ts\n\t * // List item in view may contain nested list, which have other list items. In model though,\n\t * // the lists are represented by flat structure. Because of those differences, length of list view element\n\t * // may be greater than one. In the callback it's checked how many nested list items are in evaluated list item.\n\t *\n\t * function getViewListItemLength( element ) {\n\t * \tlet length = 1;\n\t *\n\t * \tfor ( let child of element.getChildren() ) {\n\t * \t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t * \t\t\tfor ( let item of child.getChildren() ) {\n\t * \t\t\t\tlength += getViewListItemLength( item );\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t *\n\t * \treturn length;\n\t * }\n\t *\n\t * mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t * ```\n\t *\n\t * @param viewElementName Name of view element for which callback is registered.\n\t * @param lengthCallback Function return a length of view element instance in model.\n\t */\n\tpublic registerViewToModelLength(\n\t\tviewElementName: string,\n\t\tlengthCallback: ( element: ViewElement ) => number\n\t): void {\n\t\tthis._viewToModelLengthCallbacks.set( viewElementName, lengthCallback );\n\t}\n\n\t/**\n\t * For the given `viewPosition`, finds and returns the closest ancestor of this position that has a mapping to\n\t * the model.\n\t *\n\t * @param viewPosition Position for which a mapped ancestor should be found.\n\t */\n\tpublic findMappedViewAncestor( viewPosition: ViewPosition ): ViewElement {\n\t\tlet parent: any = viewPosition.parent;\n\n\t\twhile ( !this._viewToModelMapping.has( parent ) ) {\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn parent;\n\t}\n\n\t/**\n\t * Calculates model offset based on the view position and the block element.\n\t *\n\t * Example:\n\t *\n\t * ```html\n\t * <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, p ) -> 5\n\t * ```\n\t *\n\t * Is a sum of:\n\t *\n\t * ```html\n\t * <p>foo|<b>bar</b></p> // _toModelOffset( p, 3, p ) -> 3\n\t * <p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, b ) -> 2\n\t * ```\n\t *\n\t * @param viewParent Position parent.\n\t * @param viewOffset Position offset.\n\t * @param viewBlock Block used as a base to calculate offset.\n\t * @returns Offset in the model.\n\t */\n\tprivate _toModelOffset(\n\t\tviewParent: ViewElement,\n\t\tviewOffset: number,\n\t\tviewBlock: ViewElement\n\t): number {\n\t\tif ( viewBlock != viewParent ) {\n\t\t\t// See example.\n\t\t\tconst offsetToParentStart = this._toModelOffset( viewParent.parent as any, viewParent.index!, viewBlock );\n\t\t\tconst offsetInParent = this._toModelOffset( viewParent, viewOffset, viewParent );\n\n\t\t\treturn offsetToParentStart + offsetInParent;\n\t\t}\n\n\t\t// viewBlock == viewParent, so we need to calculate the offset in the parent element.\n\n\t\t// If the position is a text it is simple (\"ba|r\" -> 2).\n\t\tif ( viewParent.is( '$text' ) ) {\n\t\t\treturn viewOffset;\n\t\t}\n\n\t\t// If the position is in an element we need to sum lengths of siblings ( <b> bar </b> foo | -> 3 + 3 = 6 ).\n\t\tlet modelOffset = 0;\n\n\t\tfor ( let i = 0; i < viewOffset; i++ ) {\n\t\t\tmodelOffset += this.getModelLength( viewParent.getChild( i ) as any );\n\t\t}\n\n\t\treturn modelOffset;\n\t}\n\n\t/**\n\t * Gets the length of the view element in the model.\n\t *\n\t * The length is calculated as follows:\n\t * * if a {@link #registerViewToModelLength length mapping callback} is provided for the given `viewNode`, it is used to\n\t * evaluate the model length (`viewNode` is used as first and only parameter passed to the callback),\n\t * * length of a {@link module:engine/view/text~Text text node} is equal to the length of its\n\t * {@link module:engine/view/text~Text#data data},\n\t * * length of a {@link module:engine/view/uielement~UIElement ui element} is equal to 0,\n\t * * length of a mapped {@link module:engine/view/element~Element element} is equal to 1,\n\t * * length of a non-mapped {@link module:engine/view/element~Element element} is equal to the length of its children.\n\t *\n\t * Examples:\n\t *\n\t * ```\n\t * foo                          -> 3 // Text length is equal to its data length.\n\t * <p>foo</p>                   -> 1 // Length of an element which is mapped is by default equal to 1.\n\t * <b>foo</b>                   -> 3 // Length of an element which is not mapped is a length of its children.\n\t * <div><p>x</p><p>y</p></div>  -> 2 // Assuming that <div> is not mapped and <p> are mapped.\n\t * ```\n\t *\n\t * @param viewNode View node.\n\t * @returns Length of the node in the tree model.\n\t */\n\tpublic getModelLength( viewNode: ViewNode | ViewDocumentFragment ): number {\n\t\tif ( this._viewToModelLengthCallbacks.get( ( viewNode as any ).name ) ) {\n\t\t\tconst callback = this._viewToModelLengthCallbacks.get( ( viewNode as any ).name )!;\n\n\t\t\treturn callback( viewNode as ViewElement );\n\t\t} else if ( this._viewToModelMapping.has( viewNode as ViewElement ) ) {\n\t\t\treturn 1;\n\t\t} else if ( viewNode.is( '$text' ) ) {\n\t\t\treturn viewNode.data.length;\n\t\t} else if ( viewNode.is( 'uiElement' ) ) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\tlet len = 0;\n\n\t\t\tfor ( const child of ( viewNode as ViewElement ).getChildren() ) {\n\t\t\t\tlen += this.getModelLength( child );\n\t\t\t}\n\n\t\t\treturn len;\n\t\t}\n\t}\n\n\t/**\n\t * Finds the position in the view node (or in its children) with the expected model offset.\n\t *\n\t * Example:\n\t *\n\t * ```\n\t * <p>fo<b>bar</b>bom</p> -> expected offset: 4\n\t *\n\t * findPositionIn( p, 4 ):\n\t * <p>|fo<b>bar</b>bom</p> -> expected offset: 4, actual offset: 0\n\t * <p>fo|<b>bar</b>bom</p> -> expected offset: 4, actual offset: 2\n\t * <p>fo<b>bar</b>|bom</p> -> expected offset: 4, actual offset: 5 -> we are too far\n\t *\n\t * findPositionIn( b, 4 - ( 5 - 3 ) ):\n\t * <p>fo<b>|bar</b>bom</p> -> expected offset: 2, actual offset: 0\n\t * <p>fo<b>bar|</b>bom</p> -> expected offset: 2, actual offset: 3 -> we are too far\n\t *\n\t * findPositionIn( bar, 2 - ( 3 - 3 ) ):\n\t * We are in the text node so we can simple find the offset.\n\t * <p>fo<b>ba|r</b>bom</p> -> expected offset: 2, actual offset: 2 -> position found\n\t * ```\n\t *\n\t * @param viewParent Tree view element in which we are looking for the position.\n\t * @param expectedOffset Expected offset.\n\t * @returns Found position.\n\t */\n\tpublic findPositionIn( viewParent: ViewNode | ViewDocumentFragment, expectedOffset: number ): ViewPosition {\n\t\t// Last scanned view node.\n\t\tlet viewNode: ViewNode;\n\t\t// Length of the last scanned view node.\n\t\tlet lastLength = 0;\n\n\t\tlet modelOffset = 0;\n\t\tlet viewOffset = 0;\n\n\t\t// In the text node it is simple: the offset in the model equals the offset in the text.\n\t\tif ( viewParent.is( '$text' ) ) {\n\t\t\treturn new ViewPosition( viewParent, expectedOffset );\n\t\t}\n\n\t\t// In other cases we add lengths of child nodes to find the proper offset.\n\n\t\t// If it is smaller we add the length.\n\t\twhile ( modelOffset < expectedOffset ) {\n\t\t\tviewNode = ( viewParent as ViewElement | ViewDocumentFragment ).getChild( viewOffset )!;\n\t\t\tlastLength = this.getModelLength( viewNode );\n\t\t\tmodelOffset += lastLength;\n\t\t\tviewOffset++;\n\t\t}\n\n\t\t// If it equals we found the position.\n\t\tif ( modelOffset == expectedOffset ) {\n\t\t\treturn this._moveViewPositionToTextNode( new ViewPosition( viewParent, viewOffset ) );\n\t\t}\n\t\t// If it is higher we need to enter last child.\n\t\telse {\n\t\t\t// ( modelOffset - lastLength ) is the offset to the child we enter,\n\t\t\t// so we subtract it from the expected offset to fine the offset in the child.\n\t\t\treturn this.findPositionIn( viewNode!, expectedOffset - ( modelOffset - lastLength ) );\n\t\t}\n\t}\n\n\t/**\n\t * Because we prefer positions in the text nodes over positions next to text nodes, if the view position was next to a text node,\n\t * it moves it into the text node instead.\n\t *\n\t * ```\n\t * <p>[]<b>foo</b></p> -> <p>[]<b>foo</b></p> // do not touch if position is not directly next to text\n\t * <p>foo[]<b>foo</b></p> -> <p>foo{}<b>foo</b></p> // move to text node\n\t * <p><b>[]foo</b></p> -> <p><b>{}foo</b></p> // move to text node\n\t * ```\n\t *\n\t * @param viewPosition Position potentially next to the text node.\n\t * @returns Position in the text node if possible.\n\t */\n\tprivate _moveViewPositionToTextNode( viewPosition: ViewPosition ): ViewPosition {\n\t\t// If the position is just after a text node, put it at the end of that text node.\n\t\t// If the position is just before a text node, put it at the beginning of that text node.\n\t\tconst nodeBefore = viewPosition.nodeBefore;\n\t\tconst nodeAfter = viewPosition.nodeAfter;\n\n\t\tif ( nodeBefore instanceof ViewText ) {\n\t\t\treturn new ViewPosition( nodeBefore, nodeBefore.data.length );\n\t\t} else if ( nodeAfter instanceof ViewText ) {\n\t\t\treturn new ViewPosition( nodeAfter, 0 );\n\t\t}\n\n\t\t// Otherwise, just return the given position.\n\t\treturn viewPosition;\n\t}\n}\n\n/**\n * Fired for each model-to-view position mapping request. The purpose of this event is to enable custom model-to-view position\n * mapping. Callbacks added to this event take {@link module:engine/model/position~Position model position} and are expected to\n * calculate the {@link module:engine/view/position~Position view position}. The calculated view position should be added as\n * a `viewPosition` value in the `data` object that is passed as one of parameters to the event callback.\n *\n * ```ts\n * // Assume that \"captionedImage\" model element is converted to <img> and following <span> elements in view,\n * // and the model element is bound to <img> element. Force mapping model positions inside \"captionedImage\" to that\n * // <span> element.\n * mapper.on( 'modelToViewPosition', ( evt, data ) => {\n * \tconst positionParent = modelPosition.parent;\n *\n * \tif ( positionParent.name == 'captionedImage' ) {\n * \t\tconst viewImg = data.mapper.toViewElement( positionParent );\n * \t\tconst viewCaption = viewImg.nextSibling; // The <span> element.\n *\n * \t\tdata.viewPosition = new ViewPosition( viewCaption, modelPosition.offset );\n *\n * \t\t// Stop the event if other callbacks should not modify calculated value.\n * \t\tevt.stop();\n * \t}\n * } );\n * ```\n *\n * **Note:** keep in mind that sometimes a \"phantom\" model position is being converted. A \"phantom\" model position is\n * a position that points to a nonexistent place in model. Such a position might still be valid for conversion, though\n * (it would point to a correct place in the view when converted). One example of such a situation is when a range is\n * removed from the model, there may be a need to map the range's end (which is no longer a valid model position). To\n * handle such situations, check the `data.isPhantom` flag:\n *\n * ```ts\n * // Assume that there is a \"customElement\" model element and whenever the position is before it,\n * // we want to move it to the inside of the view element bound to \"customElement\".\n * mapper.on( 'modelToViewPosition', ( evt, data ) => {\n * \tif ( data.isPhantom ) {\n * \t\treturn;\n * \t}\n *\n * \t// Below line might crash for phantom position that does not exist in model.\n * \tconst sibling = data.modelPosition.nodeBefore;\n *\n * \t// Check if this is the element we are interested in.\n * \tif ( !sibling.is( 'element', 'customElement' ) ) {\n * \t\treturn;\n * \t}\n *\n * \tconst viewElement = data.mapper.toViewElement( sibling );\n *\n * \tdata.viewPosition = new ViewPosition( sibling, 0 );\n *\n * \tevt.stop();\n * } );\n * ```\n *\n * **Note:** the default mapping callback is provided with a `low` priority setting and does not cancel the event, so it is possible to\n * attach a custom callback after a default callback and also use `data.viewPosition` calculated by the default callback\n * (for example to fix it).\n *\n * **Note:** the default mapping callback will not fire if `data.viewPosition` is already set.\n *\n * **Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position\n * mapping between the given model and view elements is unsolvable by using just elements mapping and default algorithm.\n * Also, the condition that checks if a special case scenario happened should be as simple as possible.\n *\n * @eventName ~Mapper#modelToViewPosition\n */\nexport type MapperModelToViewPositionEvent = {\n\tname: 'modelToViewPosition';\n\targs: [ MapperModelToViewPositionEventData ];\n};\n\n/**\n * Data pipeline object that can store and pass data between callbacks. The callback should add\n * the `viewPosition` value to that object with calculated the {@link module:engine/view/position~Position view position}.\n */\nexport type MapperModelToViewPositionEventData = {\n\n\t/**\n\t * Mapper instance that fired the event.\n\t */\n\tmapper: Mapper;\n\n\t/**\n\t * The model position.\n\t */\n\tmodelPosition: ModelPosition;\n\n\t/**\n\t * The callback should add the `viewPosition` value to that object with calculated the\n\t * {@link module:engine/view/position~Position view position}.\n\t */\n\tviewPosition?: ViewPosition;\n\n\t/**\n\t * Should be set to `true` if the model position to map is pointing to a place\n\t * in model tree which no longer exists. For example, it could be an end of a removed model range.\n\t */\n\tisPhantom?: boolean;\n};\n\n/**\n * Fired for each view-to-model position mapping request. See {@link module:engine/conversion/mapper~Mapper#event:modelToViewPosition}.\n *\n * ```ts\n * // See example in `modelToViewPosition` event description.\n * // This custom mapping will map positions from <span> element next to <img> to the \"captionedImage\" element.\n * mapper.on( 'viewToModelPosition', ( evt, data ) => {\n * \tconst positionParent = viewPosition.parent;\n *\n * \tif ( positionParent.hasClass( 'image-caption' ) ) {\n * \t\tconst viewImg = positionParent.previousSibling;\n * \t\tconst modelImg = data.mapper.toModelElement( viewImg );\n *\n * \t\tdata.modelPosition = new ModelPosition( modelImg, viewPosition.offset );\n * \t\tevt.stop();\n * \t}\n * } );\n * ```\n *\n * **Note:** the default mapping callback is provided with a `low` priority setting and does not cancel the event, so it is possible to\n * attach a custom callback after the default callback and also use `data.modelPosition` calculated by the default callback\n * (for example to fix it).\n *\n * **Note:** the default mapping callback will not fire if `data.modelPosition` is already set.\n *\n * **Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position\n * mapping between the given model and view elements is unsolvable by using just elements mapping and default algorithm.\n * Also, the condition that checks if special case scenario happened should be as simple as possible.\n *\n * @eventName ~Mapper#viewToModelPosition\n */\nexport type MapperViewToModelPositionEvent = {\n\tname: 'viewToModelPosition';\n\targs: [ MapperViewToModelPositionEventData ];\n};\n\n/**\n * Data pipeline object that can store and pass data between callbacks. The callback should add\n * `modelPosition` value to that object with calculated {@link module:engine/model/position~Position model position}.\n */\nexport type MapperViewToModelPositionEventData = {\n\n\t/**\n\t * Mapper instance that fired the event.\n\t */\n\tmapper: Mapper;\n\n\t/**\n\t * The callback should add `modelPosition` value to that object with calculated\n\t * {@link module:engine/model/position~Position model position}.\n\t */\n\tmodelPosition?: ModelPosition;\n\n\t/**\n\t * The view position.\n\t */\n\tviewPosition: ViewPosition;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/conversion/modelconsumable\n */\n\nimport TextProxy from '../model/textproxy.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type Item from '../model/item.js';\nimport type Selection from '../model/selection.js';\nimport type DocumentSelection from '../model/documentselection.js';\nimport type Range from '../model/range.js';\n\n/**\n * Manages a list of consumable values for the {@link module:engine/model/item~Item model items}.\n *\n * Consumables are various aspects of the model. A model item can be broken down into separate, single properties that might be\n * taken into consideration when converting that item.\n *\n * `ModelConsumable` is used by {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} while analyzing the changed\n * parts of {@link module:engine/model/document~Document the document}. The added / changed / removed model items are broken down\n * into singular properties (the item itself and its attributes). All those parts are saved in `ModelConsumable`. Then,\n * during conversion, when the given part of a model item is converted (i.e. the view element has been inserted into the view,\n * but without attributes), the consumable value is removed from `ModelConsumable`.\n *\n * For model items, `ModelConsumable` stores consumable values of one of following types: `insert`, `addattribute:<attributeKey>`,\n * `changeattributes:<attributeKey>`, `removeattributes:<attributeKey>`.\n *\n * In most cases, it is enough to let th {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n * gather consumable values, so there is no need to use\n * the {@link module:engine/conversion/modelconsumable~ModelConsumable#add add method} directly.\n * However, it is important to understand how consumable values can be\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed}.\n * See {@link module:engine/conversion/downcasthelpers default downcast converters} for more information.\n *\n * Keep in mind that one conversion event may have multiple callbacks (converters) attached to it. Each of those is\n * able to convert one or more parts of the model. However, when one of those callbacks actually converts\n * something, the others should not, because they would duplicate the results. Using `ModelConsumable` helps to avoid\n * this situation, because callbacks should only convert these values that were not yet consumed from `ModelConsumable`.\n *\n * Consuming multiple values in a single callback:\n *\n * ```ts\n * // Converter for custom `imageBlock` element that might have a `caption` element inside which changes\n * // how the image is displayed in the view:\n * //\n * // Model:\n * //\n * // [imageBlock]\n * //   └─ [caption]\n * //       └─ foo\n * //\n * // View:\n * //\n * // <figure>\n * //   ├─ <img />\n * //   └─ <caption>\n * //       └─ foo\n * modelConversionDispatcher.on( 'insert:imageBlock', ( evt, data, conversionApi ) => {\n * \t// First, consume the `imageBlock` element.\n * \tconversionApi.consumable.consume( data.item, 'insert' );\n *\n * \t// Just create normal image element for the view.\n * \t// Maybe it will be \"decorated\" later.\n * \tconst viewImage = new ViewElement( 'img' );\n * \tconst insertPosition = conversionApi.mapper.toViewPosition( data.range.start );\n * \tconst viewWriter = conversionApi.writer;\n *\n * \t// Check if the `imageBlock` element has children.\n * \tif ( data.item.childCount > 0 ) {\n * \t\tconst modelCaption = data.item.getChild( 0 );\n *\n * \t\t// `modelCaption` insertion change is consumed from consumable values.\n * \t\t// It will not be converted by other converters, but it's children (probably some text) will be.\n * \t\t// Through mapping, converters for text will know where to insert contents of `modelCaption`.\n * \t\tif ( conversionApi.consumable.consume( modelCaption, 'insert' ) ) {\n * \t\t\tconst viewCaption = new ViewElement( 'figcaption' );\n *\n * \t\t\tconst viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );\n *\n * \t\t\tconversionApi.mapper.bindElements( modelCaption, viewCaption );\n * \t\t\tconversionApi.mapper.bindElements( data.item, viewImageHolder );\n * \t\t\tviewWriter.insert( insertPosition, viewImageHolder );\n * \t\t}\n * \t} else {\n * \t\tconversionApi.mapper.bindElements( data.item, viewImage );\n * \t\tviewWriter.insert( insertPosition, viewImage );\n * \t}\n *\n * \tevt.stop();\n * } );\n * ```\n */\nexport default class ModelConsumable {\n\t/**\n\t * Contains list of consumable values.\n\t */\n\tprivate _consumable = new Map<any, Map<string, boolean>>();\n\n\t/**\n\t * For each {@link module:engine/model/textproxy~TextProxy} added to `ModelConsumable`, this registry holds a parent\n\t * of that `TextProxy` and the start and end indices of that `TextProxy`. This allows identification of the `TextProxy`\n\t * instances that point to the same part of the model but are different instances. Each distinct `TextProxy`\n\t * is given a unique `Symbol` which is then registered as consumable. This process is transparent for the `ModelConsumable`\n\t * API user because whenever `TextProxy` is added, tested, consumed or reverted, the internal mechanisms of\n\t * `ModelConsumable` translate `TextProxy` to that unique `Symbol`.\n\t */\n\tprivate _textProxyRegistry = new Map<number | null, Map<number | null, Map<unknown, symbol>>>();\n\n\t/**\n\t * Adds a consumable value to the consumables list and links it with a given model item.\n\t *\n\t * ```ts\n\t * modelConsumable.add( modelElement, 'insert' ); // Add `modelElement` insertion change to consumable values.\n\t * modelConsumable.add( modelElement, 'addAttribute:bold' ); // Add `bold` attribute insertion on `modelElement` change.\n\t * modelConsumable.add( modelElement, 'removeAttribute:bold' ); // Add `bold` attribute removal on `modelElement` change.\n\t * modelConsumable.add( modelSelection, 'selection' ); // Add `modelSelection` to consumable values.\n\t * modelConsumable.add( modelRange, 'range' ); // Add `modelRange` to consumable values.\n\t * ```\n\t *\n\t * @param item Model item, range or selection that has the consumable.\n\t * @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t */\n\tpublic add(\n\t\titem: Item | Selection | DocumentSelection | Range,\n\t\ttype: string\n\t): void {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item ) as any;\n\t\t}\n\n\t\tif ( !this._consumable.has( item ) ) {\n\t\t\tthis._consumable.set( item, new Map() );\n\t\t}\n\n\t\tthis._consumable.get( item )!.set( type, true );\n\t}\n\n\t/**\n\t * Removes a given consumable value from a given model item.\n\t *\n\t * ```ts\n\t * modelConsumable.consume( modelElement, 'insert' ); // Remove `modelElement` insertion change from consumable values.\n\t * modelConsumable.consume( modelElement, 'addAttribute:bold' ); // Remove `bold` attribute insertion on `modelElement` change.\n\t * modelConsumable.consume( modelElement, 'removeAttribute:bold' ); // Remove `bold` attribute removal on `modelElement` change.\n\t * modelConsumable.consume( modelSelection, 'selection' ); // Remove `modelSelection` from consumable values.\n\t * modelConsumable.consume( modelRange, 'range' ); // Remove 'modelRange' from consumable values.\n\t * ```\n\t *\n\t * @param item Model item, range or selection from which consumable will be consumed.\n\t * @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t * @returns `true` if consumable value was available and was consumed, `false` otherwise.\n\t */\n\tpublic consume(\n\t\titem: Item | Selection | DocumentSelection | Range,\n\t\ttype: string\n\t): boolean {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item ) as any;\n\t\t}\n\n\t\tif ( this.test( item, type ) ) {\n\t\t\tthis._consumable.get( item )!.set( type, false );\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Tests whether there is a consumable value of a given type connected with a given model item.\n\t *\n\t * ```ts\n\t * modelConsumable.test( modelElement, 'insert' ); // Check for `modelElement` insertion change.\n\t * modelConsumable.test( modelElement, 'addAttribute:bold' ); // Check for `bold` attribute insertion on `modelElement` change.\n\t * modelConsumable.test( modelElement, 'removeAttribute:bold' ); // Check for `bold` attribute removal on `modelElement` change.\n\t * modelConsumable.test( modelSelection, 'selection' ); // Check if `modelSelection` is consumable.\n\t * modelConsumable.test( modelRange, 'range' ); // Check if `modelRange` is consumable.\n\t * ```\n\t *\n\t * @param item Model item, range or selection to be tested.\n\t * @param type Consumable type. Will be normalized to a proper form, that is either `<word>` or `<part>:<part>`.\n\t * Second colon and everything after will be cut. Passing event name is a safe and good practice.\n\t * @returns `null` if such consumable was never added, `false` if the consumable values was\n\t * already consumed or `true` if it was added and not consumed yet.\n\t */\n\tpublic test(\n\t\titem: Item | Selection | DocumentSelection | Range,\n\t\ttype: string\n\t): boolean | null {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item ) as any;\n\t\t}\n\n\t\tconst itemConsumables = this._consumable.get( item );\n\n\t\tif ( itemConsumables === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst value = itemConsumables.get( type );\n\n\t\tif ( value === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Reverts consuming of a consumable value.\n\t *\n\t * ```ts\n\t * modelConsumable.revert( modelElement, 'insert' ); // Revert consuming `modelElement` insertion change.\n\t * modelConsumable.revert( modelElement, 'addAttribute:bold' ); // Revert consuming `bold` attribute insert from `modelElement`.\n\t * modelConsumable.revert( modelElement, 'removeAttribute:bold' ); // Revert consuming `bold` attribute remove from `modelElement`.\n\t * modelConsumable.revert( modelSelection, 'selection' ); // Revert consuming `modelSelection`.\n\t * modelConsumable.revert( modelRange, 'range' ); // Revert consuming `modelRange`.\n\t * ```\n\t *\n\t * @param item Model item, range or selection to be reverted.\n\t * @param type Consumable type.\n\t * @returns `true` if consumable has been reversed, `false` otherwise. `null` if the consumable has\n\t * never been added.\n\t */\n\tpublic revert(\n\t\titem: Item | Selection | DocumentSelection | Range,\n\t\ttype: string\n\t): boolean | null {\n\t\ttype = _normalizeConsumableType( type );\n\n\t\tif ( item instanceof TextProxy ) {\n\t\t\titem = this._getSymbolForTextProxy( item ) as any;\n\t\t}\n\n\t\tconst test = this.test( item, type );\n\n\t\tif ( test === false ) {\n\t\t\tthis._consumable.get( item )!.set( type, true );\n\n\t\t\treturn true;\n\t\t} else if ( test === true ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Verifies if all events from the specified group were consumed.\n\t *\n\t * @param eventGroup The events group to verify.\n\t */\n\tpublic verifyAllConsumed( eventGroup: string ): void {\n\t\tconst items = [];\n\n\t\tfor ( const [ item, consumables ] of this._consumable ) {\n\t\t\tfor ( const [ event, canConsume ] of consumables ) {\n\t\t\t\tconst eventPrefix = event.split( ':' )[ 0 ];\n\n\t\t\t\tif ( canConsume && eventGroup == eventPrefix ) {\n\t\t\t\t\titems.push( {\n\t\t\t\t\t\tevent,\n\t\t\t\t\t\titem: item.name || item.description\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( items.length ) {\n\t\t\t/**\n\t\t\t * Some of the {@link module:engine/model/item~Item model items} were not consumed while downcasting the model to view.\n\t\t\t *\n\t\t\t * This might be the effect of:\n\t\t\t *\n\t\t\t * * A missing converter for some model elements. Make sure that you registered downcast converters for all model elements.\n\t\t\t * * A custom converter that does not consume converted items. Make sure that you\n\t\t\t * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} all model elements that you converted\n\t\t\t * from the model to the view.\n\t\t\t * * A custom converter that called `event.stop()`. When providing a custom converter, keep in mind that you should not stop\n\t\t\t * the event. If you stop it then the default converter at the `lowest` priority will not trigger the conversion of this node's\n\t\t\t * attributes and child nodes.\n\t\t\t *\n\t\t\t * @error conversion-model-consumable-not-consumed\n\t\t\t * @param {Array.<module:engine/model/item~Item>} items Items that were not consumed.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-model-consumable-not-consumed', null, { items } );\n\t\t}\n\t}\n\n\t/**\n\t * Gets a unique symbol for the passed {@link module:engine/model/textproxy~TextProxy} instance. All `TextProxy` instances that\n\t * have same parent, same start index and same end index will get the same symbol.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @internal\n\t * @param textProxy `TextProxy` instance to get a symbol for.\n\t * @returns Symbol representing all equal instances of `TextProxy`.\n\t */\n\tpublic _getSymbolForTextProxy( textProxy: TextProxy ): symbol {\n\t\tlet symbol = null;\n\n\t\tconst startMap = this._textProxyRegistry.get( textProxy.startOffset );\n\n\t\tif ( startMap ) {\n\t\t\tconst endMap = startMap.get( textProxy.endOffset );\n\n\t\t\tif ( endMap ) {\n\t\t\t\tsymbol = endMap.get( textProxy.parent );\n\t\t\t}\n\t\t}\n\n\t\tif ( !symbol ) {\n\t\t\tsymbol = this._addSymbolForTextProxy( textProxy );\n\t\t}\n\n\t\treturn symbol;\n\t}\n\n\t/**\n\t * Adds a symbol for the given {@link module:engine/model/textproxy~TextProxy} instance.\n\t *\n\t * Used internally to correctly consume `TextProxy` instances.\n\t *\n\t * @param textProxy Text proxy instance.\n\t * @returns Symbol generated for given `TextProxy`.\n\t */\n\tprivate _addSymbolForTextProxy( textProxy: TextProxy ): symbol {\n\t\tconst start = textProxy.startOffset;\n\t\tconst end = textProxy.endOffset;\n\t\tconst parent = textProxy.parent;\n\n\t\tconst symbol = Symbol( '$textProxy:' + textProxy.data );\n\t\tlet startMap: Map<number | null, Map<unknown, symbol>> | undefined;\n\t\tlet endMap: Map<unknown, symbol> | undefined;\n\n\t\tstartMap = this._textProxyRegistry.get( start );\n\n\t\tif ( !startMap ) {\n\t\t\tstartMap = new Map();\n\t\t\tthis._textProxyRegistry.set( start, startMap );\n\t\t}\n\n\t\tendMap = startMap.get( end );\n\n\t\tif ( !endMap ) {\n\t\t\tendMap = new Map();\n\t\t\tstartMap.set( end, endMap );\n\t\t}\n\n\t\tendMap.set( parent, symbol );\n\n\t\treturn symbol;\n\t}\n}\n\n/**\n * Returns a normalized consumable type name from the given string. A normalized consumable type name is a string that has\n * at most one colon, for example: `insert` or `addMarker:highlight`. If a string to normalize has more \"parts\" (more colons),\n * the further parts are dropped, for example: `addattribute:bold:$text` -> `addattributes:bold`.\n *\n * @param type Consumable type.\n * @returns Normalized consumable type.\n */\nfunction _normalizeConsumableType( type: string ) {\n\tconst parts = type.split( ':' );\n\n\t// For inserts allow passing event name, it's stored in the context of a specified element so the element name is not needed.\n\tif ( parts[ 0 ] == 'insert' ) {\n\t\treturn parts[ 0 ];\n\t}\n\n\t// Markers are identified by the whole name (otherwise we would consume the whole markers group).\n\tif ( parts[ 0 ] == 'addMarker' || parts[ 0 ] == 'removeMarker' ) {\n\t\treturn type;\n\t}\n\n\treturn parts.length > 1 ? parts[ 0 ] + ':' + parts[ 1 ] : parts[ 0 ];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/conversion/downcastdispatcher\n */\n\nimport Consumable from './modelconsumable.js';\nimport Range from '../model/range.js';\n\nimport { EmitterMixin } from '@ckeditor/ckeditor5-utils';\n\nimport type { default as Differ, DiffItem } from '../model/differ.js';\nimport type { default as MarkerCollection, Marker } from '../model/markercollection.js';\nimport type { TreeWalkerValue } from '../model/treewalker.js';\nimport type DocumentSelection from '../model/documentselection.js';\nimport type DowncastWriter from '../view/downcastwriter.js';\nimport type RootElement from '../model/rootelement.js';\nimport type Element from '../model/element.js';\nimport type Item from '../model/item.js';\nimport type Mapper from './mapper.js';\nimport type Position from '../model/position.js';\nimport type Schema from '../model/schema.js';\nimport type Selection from '../model/selection.js';\nimport type ViewElement from '../view/element.js';\n\n/**\n * The downcast dispatcher is a central point of downcasting (conversion from the model to the view), which is a process of reacting\n * to changes in the model and firing a set of events. The callbacks listening to these events are called converters. The\n * converters' role is to convert the model changes to changes in view (for example, adding view nodes or\n * changing attributes on view elements).\n *\n * During the conversion process, downcast dispatcher fires events basing on the state of the model and prepares\n * data for these events. It is important to understand that the events are connected with the changes done on the model,\n * for example: \"a node has been inserted\" or \"an attribute has changed\". This is in contrary to upcasting (a view-to-model conversion)\n * where you convert the view state (view nodes) to a model tree.\n *\n * The events are prepared basing on a diff created by the {@link module:engine/model/differ~Differ Differ}, which buffers them\n * and then passes to the downcast dispatcher as a diff between the old model state and the new model state.\n *\n * Note that because the changes are converted, there is a need to have a mapping between the model structure and the view structure.\n * To map positions and elements during the downcast (a model-to-view conversion), use {@link module:engine/conversion/mapper~Mapper}.\n *\n * Downcast dispatcher fires the following events for model tree changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`} &ndash;\n * If a range of nodes was inserted to the model tree.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove `remove`} &ndash;\n * If a range of nodes was removed from the model tree.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`} &ndash;\n * If an attribute was added, changed or removed from a model node.\n *\n * For {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`}\n * and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`},\n * the downcast dispatcher generates {@link module:engine/conversion/modelconsumable~ModelConsumable consumables}.\n * These are used to have control over which changes have already been consumed. It is useful when some converters\n * overwrite others or convert multiple changes (for example, it converts an insertion of an element and also converts that\n * element's attributes during the insertion).\n *\n * Additionally, downcast dispatcher fires events for {@link module:engine/model/markercollection~Marker marker} changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker `addMarker`} &ndash; If a marker was added.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker `removeMarker`} &ndash; If a marker was\n * removed.\n *\n * Note that changing a marker is done through removing the marker from the old range and adding it to the new range,\n * so both of these events are fired.\n *\n * Finally, a downcast dispatcher also handles firing events for the {@link module:engine/model/selection model selection}\n * conversion:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:selection `selection`}\n * &ndash; Converts the selection from the model to the view.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`}\n * &ndash; Fired for every selection attribute.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker `addMarker`}\n * &ndash; Fired for every marker that contains a selection.\n *\n * Unlike the model tree and the markers, the events for selection are not fired for changes but for a selection state.\n *\n * When providing custom listeners for a downcast dispatcher, remember to check whether a given change has not been\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} yet.\n *\n * When providing custom listeners for a downcast dispatcher, keep in mind that you **should not** stop the event. If you stop it,\n * then the default converter at the `lowest` priority will not trigger the conversion of this node's attributes and child nodes.\n *\n * When providing custom listeners for a downcast dispatcher, remember to use the provided\n * {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} to apply changes to the view document.\n *\n * You can read more about conversion in the following guide:\n *\n * * {@glink framework/deep-dive/conversion/downcast Downcast conversion}\n *\n * An example of a custom converter for the downcast dispatcher:\n *\n * ```ts\n * // You will convert inserting a \"paragraph\" model element into the model.\n * downcastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {\n * \t// Remember to check whether the change has not been consumed yet and consume it.\n * \tif ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {\n * \t\treturn;\n * \t}\n *\n * \t// Translate the position in the model to a position in the view.\n * \tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n *\n * \t// Create a <p> element that will be inserted into the view at the `viewPosition`.\n * \tconst viewElement = conversionApi.writer.createContainerElement( 'p' );\n *\n * \t// Bind the newly created view element to the model element so positions will map accordingly in the future.\n * \tconversionApi.mapper.bindElements( data.item, viewElement );\n *\n * \t// Add the newly created view element to the view.\n * \tconversionApi.writer.insert( viewPosition, viewElement );\n * } );\n * ```\n */\nexport default class DowncastDispatcher extends /* #__PURE__ */ EmitterMixin() {\n\t/**\n\t * A template for an interface passed by the dispatcher to the event callbacks.\n\t *\n\t * @internal\n\t */\n\tpublic readonly _conversionApi: Pick<DowncastConversionApi, 'dispatcher' | 'mapper' | 'schema'>;\n\n\t/**\n\t * A map of already fired events for a given `ModelConsumable`.\n\t */\n\tprivate readonly _firedEventsMap: WeakMap<DowncastConversionApi, Map<unknown, Set<string>>>;\n\n\t/**\n\t * Creates a downcast dispatcher instance.\n\t *\n\t * @see module:engine/conversion/downcastdispatcher~DowncastConversionApi\n\t *\n\t * @param conversionApi Additional properties for an interface that will be passed to events fired\n\t * by the downcast dispatcher.\n\t */\n\tconstructor( conversionApi: Pick<DowncastConversionApi, 'mapper' | 'schema'> ) {\n\t\tsuper();\n\n\t\tthis._conversionApi = { dispatcher: this, ...conversionApi };\n\t\tthis._firedEventsMap = new WeakMap();\n\t}\n\n\t/**\n\t * Converts changes buffered in the given {@link module:engine/model/differ~Differ model differ}\n\t * and fires conversion events based on it.\n\t *\n\t * @fires insert\n\t * @fires remove\n\t * @fires attribute\n\t * @fires addMarker\n\t * @fires removeMarker\n\t * @fires reduceChanges\n\t * @param differ The differ object with buffered changes.\n\t * @param markers Markers related to the model fragment to convert.\n\t * @param writer The view writer that should be used to modify the view document.\n\t */\n\tpublic convertChanges(\n\t\tdiffer: Differ,\n\t\tmarkers: MarkerCollection,\n\t\twriter: DowncastWriter\n\t): void {\n\t\tconst conversionApi = this._createConversionApi( writer, differ.getRefreshedItems() );\n\n\t\t// Before the view is updated, remove markers which have changed.\n\t\tfor ( const change of differ.getMarkersToRemove() ) {\n\t\t\tthis._convertMarkerRemove( change.name, change.range, conversionApi );\n\t\t}\n\n\t\t// Let features modify the change list (for example to allow reconversion).\n\t\tconst changes = this._reduceChanges( differ.getChanges() );\n\n\t\t// Convert changes that happened on model tree.\n\t\tfor ( const entry of changes ) {\n\t\t\tif ( entry.type === 'insert' ) {\n\t\t\t\tthis._convertInsert( Range._createFromPositionAndShift( entry.position, entry.length ), conversionApi );\n\t\t\t} else if ( entry.type === 'reinsert' ) {\n\t\t\t\tthis._convertReinsert( Range._createFromPositionAndShift( entry.position, entry.length ), conversionApi );\n\t\t\t} else if ( entry.type === 'remove' ) {\n\t\t\t\tthis._convertRemove( entry.position, entry.length, entry.name, conversionApi );\n\t\t\t} else {\n\t\t\t\t// Defaults to 'attribute' change.\n\t\t\t\tthis._convertAttribute( entry.range, entry.attributeKey, entry.attributeOldValue, entry.attributeNewValue, conversionApi );\n\t\t\t}\n\t\t}\n\n\t\t// Remove mappings for all removed view elements.\n\t\t// Remove these mappings as soon as they are not needed (https://github.com/ckeditor/ckeditor5/issues/15411).\n\t\tconversionApi.mapper.flushDeferredBindings();\n\n\t\tfor ( const markerName of conversionApi.mapper.flushUnboundMarkerNames() ) {\n\t\t\tconst markerRange = markers.get( markerName )!.getRange();\n\n\t\t\tthis._convertMarkerRemove( markerName, markerRange, conversionApi );\n\t\t\tthis._convertMarkerAdd( markerName, markerRange, conversionApi );\n\t\t}\n\n\t\t// After the view is updated, convert markers which have changed.\n\t\tfor ( const change of differ.getMarkersToAdd() ) {\n\t\t\tthis._convertMarkerAdd( change.name, change.range, conversionApi );\n\t\t}\n\n\t\t// Verify if all insert consumables were consumed.\n\t\tconversionApi.consumable.verifyAllConsumed( 'insert' );\n\t}\n\n\t/**\n\t * Starts a conversion of a model range and the provided markers.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @fires addMarker\n\t * @param range The inserted range.\n\t * @param markers The map of markers that should be down-casted.\n\t * @param writer The view writer that should be used to modify the view document.\n\t * @param options Optional options object passed to `convertionApi.options`.\n\t */\n\tpublic convert(\n\t\trange: Range,\n\t\tmarkers: Map<string, Range>,\n\t\twriter: DowncastWriter,\n\t\toptions: DowncastConversionApi[ 'options' ] = {}\n\t): void {\n\t\tconst conversionApi = this._createConversionApi( writer, undefined, options );\n\n\t\tthis._convertInsert( range, conversionApi );\n\n\t\tfor ( const [ name, range ] of markers ) {\n\t\t\tthis._convertMarkerAdd( name, range, conversionApi );\n\t\t}\n\n\t\t// Verify if all insert consumables were consumed.\n\t\tconversionApi.consumable.verifyAllConsumed( 'insert' );\n\t}\n\n\t/**\n\t * Starts the model selection conversion.\n\t *\n\t * Fires events for a given {@link module:engine/model/selection~Selection selection} to start the selection conversion.\n\t *\n\t * @fires selection\n\t * @fires addMarker\n\t * @fires attribute\n\t * @param selection The selection to convert.\n\t * @param markers Markers connected with the converted model.\n\t * @param writer View writer that should be used to modify the view document.\n\t */\n\tpublic convertSelection(\n\t\tselection: Selection | DocumentSelection,\n\t\tmarkers: MarkerCollection,\n\t\twriter: DowncastWriter\n\t): void {\n\t\tconst conversionApi = this._createConversionApi( writer );\n\n\t\t// First perform a clean-up at the current position of the selection.\n\t\tthis.fire<DowncastCleanSelectionEvent>( 'cleanSelection', { selection }, conversionApi );\n\n\t\t// Don't convert selection if it is in a model root that does not have a view root (for now this is only the graveyard root).\n\t\tconst modelRoot = selection.getFirstPosition()!.root as RootElement;\n\n\t\tif ( !conversionApi.mapper.toViewElement( modelRoot ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Now, perform actual selection conversion.\n\t\tconst markersAtSelection = Array.from( markers.getMarkersAtPosition( selection.getFirstPosition()! ) );\n\n\t\tthis._addConsumablesForSelection( conversionApi.consumable, selection, markersAtSelection );\n\n\t\tthis.fire<DowncastSelectionEvent>( 'selection', { selection }, conversionApi );\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const marker of markersAtSelection ) {\n\t\t\t// Do not fire event if the marker has been consumed.\n\t\t\tif ( conversionApi.consumable.test( selection, 'addMarker:' + marker.name ) ) {\n\t\t\t\tconst markerRange = marker.getRange();\n\n\t\t\t\tif ( !shouldMarkerChangeBeConverted( selection.getFirstPosition()!, marker, conversionApi.mapper ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst data = {\n\t\t\t\t\titem: selection,\n\t\t\t\t\tmarkerName: marker.name,\n\t\t\t\t\tmarkerRange\n\t\t\t\t};\n\n\t\t\t\tthis.fire<DowncastAddMarkerEvent>( `addMarker:${ marker.name }`, data, conversionApi );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\t// Do not fire event if the attribute has been consumed.\n\t\t\tif ( conversionApi.consumable.test( selection, 'attribute:' + key ) ) {\n\t\t\t\tconst data = {\n\t\t\t\t\titem: selection,\n\t\t\t\t\trange: selection.getFirstRange()!,\n\t\t\t\t\tattributeKey: key,\n\t\t\t\t\tattributeOldValue: null,\n\t\t\t\t\tattributeNewValue: selection.getAttribute( key )\n\t\t\t\t};\n\n\t\t\t\tthis.fire<DowncastAttributeEvent>( `attribute:${ key }:$text`, data, conversionApi );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fires insertion conversion of a range of nodes.\n\t *\n\t * For each node in the range, {@link #event:insert `insert` event is fired}. For each attribute on each node,\n\t * {@link #event:attribute `attribute` event is fired}.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param range The inserted range.\n\t * @param conversionApi The conversion API object.\n\t * @param options.doNotAddConsumables Whether the ModelConsumable should not get populated\n\t * for items in the provided range.\n\t */\n\tprivate _convertInsert(\n\t\trange: Range,\n\t\tconversionApi: DowncastConversionApi,\n\t\toptions: { doNotAddConsumables?: boolean } = {}\n\t): void {\n\t\tif ( !options.doNotAddConsumables ) {\n\t\t\t// Collect a list of things that can be consumed, consisting of nodes and their attributes.\n\t\t\tthis._addConsumablesForInsert( conversionApi.consumable, range );\n\t\t}\n\n\t\t// Fire a separate insert event for each node and text fragment contained in the range.\n\t\tfor ( const data of Array.from( range.getWalker( { shallow: true } ) ).map( walkerValueToEventData ) ) {\n\t\t\tthis._testAndFire( 'insert', data, conversionApi );\n\t\t}\n\t}\n\n\t/**\n\t * Fires conversion of a single node removal. Fires {@link #event:remove remove event} with provided data.\n\t *\n\t * @param position Position from which node was removed.\n\t * @param length Offset size of removed node.\n\t * @param name Name of removed node.\n\t * @param conversionApi The conversion API object.\n\t */\n\tprivate _convertRemove(\n\t\tposition: Position,\n\t\tlength: number,\n\t\tname: string,\n\t\tconversionApi: DowncastConversionApi\n\t): void {\n\t\tthis.fire<DowncastRemoveEvent>( `remove:${ name }`, { position, length }, conversionApi );\n\t}\n\n\t/**\n\t * Starts a conversion of an attribute change on a given `range`.\n\t *\n\t * For each node in the given `range`, {@link #event:attribute attribute event} is fired with the passed data.\n\t *\n\t * @fires attribute\n\t * @param range Changed range.\n\t * @param key Key of the attribute that has changed.\n\t * @param oldValue Attribute value before the change or `null` if the attribute has not been set before.\n\t * @param newValue New attribute value or `null` if the attribute has been removed.\n\t * @param conversionApi The conversion API object.\n\t */\n\tprivate _convertAttribute(\n\t\trange: Range,\n\t\tkey: string,\n\t\toldValue: unknown,\n\t\tnewValue: unknown,\n\t\tconversionApi: DowncastConversionApi\n\t): void {\n\t\t// Create a list with attributes to consume.\n\t\tthis._addConsumablesForRange( conversionApi.consumable, range, `attribute:${ key }` );\n\n\t\t// Create a separate attribute event for each node in the range.\n\t\tfor ( const value of range ) {\n\t\t\tconst data = {\n\t\t\t\titem: value.item,\n\t\t\t\trange: Range._createFromPositionAndShift( value.previousPosition, value.length! ),\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\tattributeNewValue: newValue\n\t\t\t};\n\n\t\t\tthis._testAndFire( `attribute:${ key }`, data, conversionApi );\n\t\t}\n\t}\n\n\t/**\n\t * Fires re-insertion conversion (with a `reconversion` flag passed to `insert` events)\n\t * of a range of elements (only elements on the range depth, without children).\n\t *\n\t * For each node in the range on its depth (without children), {@link #event:insert `insert` event} is fired.\n\t * For each attribute on each node, {@link #event:attribute `attribute` event} is fired.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param range The range to reinsert.\n\t * @param conversionApi The conversion API object.\n\t */\n\tprivate _convertReinsert( range: Range, conversionApi: DowncastConversionApi ): void {\n\t\t// Convert the elements - without converting children.\n\t\tconst walkerValues = Array.from( range.getWalker( { shallow: true } ) );\n\n\t\t// Collect a list of things that can be consumed, consisting of nodes and their attributes.\n\t\tthis._addConsumablesForInsert( conversionApi.consumable, walkerValues );\n\n\t\t// Fire a separate insert event for each node and text fragment contained shallowly in the range.\n\t\tfor ( const data of walkerValues.map( walkerValueToEventData ) ) {\n\t\t\tthis._testAndFire( 'insert', { ...data, reconversion: true }, conversionApi );\n\t\t}\n\t}\n\n\t/**\n\t * Converts the added marker. Fires the {@link #event:addMarker `addMarker`} event for each item\n\t * in the marker's range. If the range is collapsed, a single event is dispatched. See the event description for more details.\n\t *\n\t * @fires addMarker\n\t * @param markerName Marker name.\n\t * @param markerRange The marker range.\n\t * @param conversionApi The conversion API object.\n\t */\n\tprivate _convertMarkerAdd(\n\t\tmarkerName: string,\n\t\tmarkerRange: Range,\n\t\tconversionApi: DowncastConversionApi\n\t): void {\n\t\t// Do not convert if range is in graveyard.\n\t\tif ( markerRange.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// In markers' case, event name == consumable name.\n\t\tconst eventName = `addMarker:${ markerName }` as const;\n\n\t\t//\n\t\t// First, fire an event for the whole marker.\n\t\t//\n\t\tconversionApi.consumable.add( markerRange, eventName );\n\n\t\tthis.fire<DowncastAddMarkerEvent>( eventName, { markerName, markerRange }, conversionApi );\n\n\t\t//\n\t\t// Do not fire events for each item inside the range if the range got consumed.\n\t\t// Also consume the whole marker consumable if it wasn't consumed.\n\t\t//\n\t\tif ( !conversionApi.consumable.consume( markerRange, eventName ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t//\n\t\t// Then, fire an event for each item inside the marker range.\n\t\t//\n\t\tthis._addConsumablesForRange( conversionApi.consumable, markerRange, eventName );\n\n\t\tfor ( const item of markerRange.getItems() ) {\n\t\t\t// Do not fire event for already consumed items.\n\t\t\tif ( !conversionApi.consumable.test( item, eventName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst data = { item, range: Range._createOn( item ), markerName, markerRange };\n\n\t\t\tthis.fire<DowncastAddMarkerEvent>( eventName, data, conversionApi );\n\t\t}\n\t}\n\n\t/**\n\t * Fires the conversion of the marker removal. Fires the {@link #event:removeMarker `removeMarker`} event with the provided data.\n\t *\n\t * @fires removeMarker\n\t * @param markerName Marker name.\n\t * @param markerRange The marker range.\n\t * @param conversionApi The conversion API object.\n\t */\n\tprivate _convertMarkerRemove( markerName: string, markerRange: Range, conversionApi: DowncastConversionApi ) {\n\t\t// Do not convert if range is in graveyard.\n\t\tif ( markerRange.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.fire<DowncastRemoveMarkerEvent>( `removeMarker:${ markerName }`, { markerName, markerRange }, conversionApi );\n\t}\n\n\t/**\n\t * Fires the reduction of changes buffered in the {@link module:engine/model/differ~Differ `Differ`}.\n\t *\n\t * Features can replace selected {@link module:engine/model/differ~DiffItem `DiffItem`}s with `reinsert` entries to trigger\n\t * reconversion. The {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n\t * `DowncastHelpers.elementToStructure()`} is using this event to trigger reconversion.\n\t *\n\t * @fires reduceChanges\n\t */\n\tprivate _reduceChanges( changes: Iterable<DiffItem> ): Iterable<DiffItem | DiffItemReinsert> {\n\t\tconst data: { changes: Iterable<DiffItem | DiffItemReinsert> } = { changes };\n\n\t\tthis.fire<DowncastReduceChangesEvent>( 'reduceChanges', data );\n\n\t\treturn data.changes;\n\t}\n\n\t/**\n\t * Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume from a given range,\n\t * assuming that the range has just been inserted to the model.\n\t *\n\t * @param consumable The consumable.\n\t * @param walkerValues The walker values for the inserted range.\n\t * @returns The values to consume.\n\t */\n\tprivate _addConsumablesForInsert(\n\t\tconsumable: Consumable,\n\t\twalkerValues: Iterable<TreeWalkerValue>\n\t): Consumable {\n\t\tfor ( const value of walkerValues ) {\n\t\t\tconst item = value.item;\n\n\t\t\t// Add consumable if it wasn't there yet.\n\t\t\tif ( consumable.test( item, 'insert' ) === null ) {\n\t\t\t\tconsumable.add( item, 'insert' );\n\n\t\t\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\t\t\tconsumable.add( item, 'attribute:' + key );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume for a given range.\n\t *\n\t * @param consumable The consumable.\n\t * @param range The affected range.\n\t * @param type Consumable type.\n\t * @returns The values to consume.\n\t */\n\tprivate _addConsumablesForRange(\n\t\tconsumable: Consumable,\n\t\trange: Range,\n\t\ttype: string\n\t): Consumable {\n\t\tfor ( const item of range.getItems() ) {\n\t\t\tconsumable.add( item, type );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Populates provided {@link module:engine/conversion/modelconsumable~ModelConsumable} with selection consumable values.\n\t *\n\t * @param consumable The consumable.\n\t * @param selection The selection to create the consumable from.\n\t * @param markers Markers that contain the selection.\n\t * @returns The values to consume.\n\t */\n\tprivate _addConsumablesForSelection(\n\t\tconsumable: Consumable,\n\t\tselection: Selection | DocumentSelection,\n\t\tmarkers: Iterable<Marker>\n\t): Consumable {\n\t\tconsumable.add( selection, 'selection' );\n\n\t\tfor ( const marker of markers ) {\n\t\t\tconsumable.add( selection, 'addMarker:' + marker.name );\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\tconsumable.add( selection, 'attribute:' + key );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Tests whether given event wasn't already fired and if so, fires it.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param type Event type.\n\t * @param data Event data.\n\t * @param conversionApi The conversion API object.\n\t */\n\tprivate _testAndFire<TType extends 'insert' | 'attribute'>(\n\t\ttype: TType | `${ TType }:${ string }`,\n\t\tdata: EventMap[ TType ],\n\t\tconversionApi: DowncastConversionApi\n\t): void {\n\t\tconst eventName = getEventName( type, data );\n\t\tconst itemKey = data.item.is( '$textProxy' ) ? conversionApi.consumable._getSymbolForTextProxy( data.item ) : data.item;\n\n\t\tconst eventsFiredForConversion = this._firedEventsMap.get( conversionApi )!;\n\t\tconst eventsFiredForItem = eventsFiredForConversion.get( itemKey );\n\n\t\tif ( !eventsFiredForItem ) {\n\t\t\teventsFiredForConversion.set( itemKey, new Set( [ eventName ] ) );\n\t\t} else if ( !eventsFiredForItem.has( eventName ) ) {\n\t\t\teventsFiredForItem.add( eventName );\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.fire<DowncastEvent<TType>>( eventName, data, conversionApi );\n\t}\n\n\t/**\n\t * Fires not already fired events for setting attributes on just inserted item.\n\t *\n\t * @param item The model item to convert attributes for.\n\t * @param conversionApi The conversion API object.\n\t */\n\tprivate _testAndFireAddAttributes(\n\t\titem: Item,\n\t\tconversionApi: DowncastConversionApi\n\t): void {\n\t\tconst data: EventMap[ 'attribute' ] = {\n\t\t\titem,\n\t\t\trange: Range._createOn( item )\n\t\t} as any;\n\n\t\tfor ( const key of data.item.getAttributeKeys() ) {\n\t\t\tdata.attributeKey = key;\n\t\t\tdata.attributeOldValue = null;\n\t\t\tdata.attributeNewValue = data.item.getAttribute( key );\n\n\t\t\tthis._testAndFire( `attribute:${ key }`, data, conversionApi );\n\t\t}\n\t}\n\n\t/**\n\t * Builds an instance of the {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi} from a template and a given\n\t * {@link module:engine/view/downcastwriter~DowncastWriter `DowncastWriter`} and options object.\n\t *\n\t * @param writer View writer that should be used to modify the view document.\n\t * @param refreshedItems A set of model elements that should not reuse their\n\t * previous view representations.\n\t * @param options Optional options passed to `convertionApi.options`.\n\t * @return The conversion API object.\n\t */\n\tprivate _createConversionApi(\n\t\twriter: DowncastWriter,\n\t\trefreshedItems: Set<Item> = new Set(),\n\t\toptions: DowncastConversionApi[ 'options' ] = {}\n\t): DowncastConversionApi {\n\t\tconst conversionApi: DowncastConversionApi = {\n\t\t\t...this._conversionApi,\n\t\t\tconsumable: new Consumable(),\n\t\t\twriter,\n\t\t\toptions,\n\t\t\tconvertItem: item => this._convertInsert( Range._createOn( item ), conversionApi ),\n\t\t\tconvertChildren: element => this._convertInsert( Range._createIn( element ), conversionApi, { doNotAddConsumables: true } ),\n\t\t\tconvertAttributes: item => this._testAndFireAddAttributes( item, conversionApi ),\n\t\t\tcanReuseView: viewElement => !refreshedItems.has( conversionApi.mapper.toModelElement( viewElement )! )\n\t\t};\n\n\t\tthis._firedEventsMap.set( conversionApi, new Map() );\n\n\t\treturn conversionApi;\n\t}\n}\n\n/**\n * Fired to enable reducing (transforming) changes buffered in the {@link module:engine/model/differ~Differ `Differ`} before\n * {@link ~DowncastDispatcher#convertChanges `convertChanges()`} will fire any conversion events.\n *\n * For instance, a feature can replace selected {@link module:engine/model/differ~DiffItem `DiffItem`}s with a `reinsert` entry\n * to trigger reconversion of an element when e.g. its attribute has changes.\n * The {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n\t * `DowncastHelpers.elementToStructure()`} helper is using this event to trigger reconversion of an element when the element,\n * its attributes or direct children changed.\n *\n * @eventName ~DowncastDispatcher#reduceChanges\n */\nexport type DowncastReduceChangesEvent = {\n\tname: 'reduceChanges';\n\targs: [ data: DowncastReduceChangesEventData ];\n};\n\nexport type DowncastReduceChangesEventData = {\n\n\t/**\n\t * A buffered changes to get reduced.\n\t */\n\tchanges: Iterable<DiffItem | DiffItemReinsert>;\n};\n\ntype EventMap<TItem = Item> = {\n\tinsert: {\n\t\titem: TItem;\n\t\trange: Range;\n\t\treconversion?: boolean;\n\t};\n\tremove: {\n\t\tposition: Position;\n\t\tlength: number;\n\t};\n\tattribute: {\n\t\titem: TItem;\n\t\trange: Range;\n\t\tattributeKey: string;\n\t\tattributeOldValue: unknown;\n\t\tattributeNewValue: unknown;\n\t};\n\tcleanSelection: {\n\t\tselection: Selection | DocumentSelection;\n\t};\n\tselection: {\n\t\tselection: Selection | DocumentSelection;\n\t};\n\taddMarker: {\n\t\titem?: Item | Selection | DocumentSelection;\n\t\trange?: Range;\n\t\tmarkerRange: Range;\n\t\tmarkerName: string;\n\t};\n\tremoveMarker: {\n\t\tmarkerRange: Range;\n\t\tmarkerName: string;\n\t};\n};\n\nexport type DowncastEvent<TName extends keyof EventMap<TItem>, TItem = Item> = {\n\tname: TName | `${ TName }:${ string }`;\n\targs: [ data: EventMap<TItem>[ TName ], conversionApi: DowncastConversionApi ];\n};\n\n/**\n * Fired for inserted nodes.\n *\n * `insert` is a namespace for a class of events. Names of actually called events follow this pattern:\n * `insert:name`. `name` is either `'$text'`, when {@link module:engine/model/text~Text a text node} has been inserted,\n * or {@link module:engine/model/element~Element#name name} of inserted element.\n *\n * This way, the listeners can either listen to a general `insert` event or specific event (for example `insert:paragraph`).\n *\n * @eventName ~DowncastDispatcher#insert\n * @param {Object} data Additional information about the change.\n * @param {module:engine/model/item~Item} data.item The inserted item.\n * @param {module:engine/model/range~Range} data.range Range spanning over inserted item.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n * to be used by callback, passed in the `DowncastDispatcher` constructor.\n */\nexport type DowncastInsertEvent<TItem extends Item = Item> = DowncastEvent<'insert', TItem>;\n\n/**\n * Fired for removed nodes.\n *\n * `remove` is a namespace for a class of events. Names of actually called events follow this pattern:\n * `remove:name`. `name` is either `'$text'`, when a {@link module:engine/model/text~Text a text node} has been removed,\n * or the {@link module:engine/model/element~Element#name name} of removed element.\n *\n * This way, listeners can either listen to a general `remove` event or specific event (for example `remove:paragraph`).\n *\n * @eventName ~DowncastDispatcher#remove\n * @param {Object} data Additional information about the change.\n * @param {module:engine/model/position~Position} data.position Position from which the node has been removed.\n * @param {Number} data.length Offset size of the removed node.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n * to be used by callback, passed in `DowncastDispatcher` constructor.\n */\nexport type DowncastRemoveEvent = DowncastEvent<'remove'>;\n\n/**\n * Fired in the following cases:\n *\n * * when an attribute has been added, changed, or removed from a node,\n * * when a node with an attribute is inserted,\n * * when a collapsed model selection attribute is converted.\n *\n * `attribute` is a namespace for a class of events. Names of actually called events follow this pattern:\n * `attribute:attributeKey:name`. `attributeKey` is the key of added/changed/removed attribute.\n * `name` is either `'$text'` if change was on {@link module:engine/model/text~Text a text node},\n * or the {@link module:engine/model/element~Element#name name} of element which attribute has changed.\n *\n * This way listeners can either listen to a general `attribute:bold` event or specific event (for example `attribute:src:imageBlock`).\n *\n * @eventName ~DowncastDispatcher#attribute\n * @param {Object} data Additional information about the change.\n * @param {module:engine/model/item~Item|module:engine/model/documentselection~DocumentSelection} data.item Changed item\n * or converted selection.\n * @param {module:engine/model/range~Range} data.range Range spanning over changed item or selection range.\n * @param {String} data.attributeKey Attribute key.\n * @param {*} data.attributeOldValue Attribute value before the change. This is `null` when selection attribute is converted.\n * @param {*} data.attributeNewValue New attribute value.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n * to be used by callback, passed in `DowncastDispatcher` constructor.\n */\nexport type DowncastAttributeEvent<TItem = Item | Selection | DocumentSelection> = DowncastEvent<'attribute', TItem>;\n\n/**\n * Fired for {@link module:engine/model/selection~Selection selection} changes.\n *\n * @eventName ~DowncastDispatcher#selection\n * @param {module:engine/model/selection~Selection} selection Selection that is converted.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n * to be used by callback, passed in `DowncastDispatcher` constructor.\n */\nexport type DowncastSelectionEvent = DowncastEvent<'selection'>;\n\n/**\n * Fired at the beginning of selection conversion, before\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:selection selection} events.\n *\n * Should be used to clean up the view state at the current selection position, before the selection is moved to another place.\n *\n * @eventName ~DowncastDispatcher#cleanSelection\n * @param {module:engine/model/selection~Selection} selection Selection that is converted.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n * to be used by callback, passed in `DowncastDispatcher` constructor.\n */\nexport type DowncastCleanSelectionEvent = DowncastEvent<'cleanSelection'>;\n\n/**\n * Fired when a new marker is added to the model. Also fired when a collapsed model selection that is inside a marker is converted.\n *\n * `addMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n * `addMarker:markerName`. By specifying certain marker names, you can make the events even more gradual. For example,\n * if markers are named `foo:abc`, `foo:bar`, then it is possible to listen to `addMarker:foo` or `addMarker:foo:abc` and\n * `addMarker:foo:bar` events.\n *\n * If the marker range is not collapsed:\n *\n * * the event is fired for each item in the marker range one by one,\n * * `conversionApi.consumable` includes each item of the marker range and the consumable value is same as the event name.\n *\n * If the marker range is collapsed:\n *\n * * there is only one event,\n * * `conversionApi.consumable` includes marker range with the event name.\n *\n * If the selection inside a marker is converted:\n *\n * * there is only one event,\n * * `conversionApi.consumable` includes the selection instance with the event name.\n *\n * @eventName ~DowncastDispatcher#addMarker\n * @param {Object} data Additional information about the change.\n * @param {module:engine/model/item~Item|module:engine/model/selection~Selection} data.item Item inside the new marker or\n * the selection that is being converted.\n * @param {module:engine/model/range~Range} [data.range] Range spanning over converted item. Available only in marker conversion, if\n * the marker range was not collapsed.\n * @param {module:engine/model/range~Range} data.markerRange Marker range.\n * @param {String} data.markerName Marker name.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n * to be used by callback, passed in `DowncastDispatcher` constructor.\n */\nexport type DowncastAddMarkerEvent = DowncastEvent<'addMarker'>;\n\n/**\n * Fired when a marker is removed from the model.\n *\n * `removeMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n * `removeMarker:markerName`. By specifying certain marker names, you can make the events even more gradual. For example,\n * if markers are named `foo:abc`, `foo:bar`, then it is possible to listen to `removeMarker:foo` or `removeMarker:foo:abc` and\n * `removeMarker:foo:bar` events.\n *\n * @eventName ~DowncastDispatcher#removeMarker\n * @param {Object} data Additional information about the change.\n * @param {module:engine/model/range~Range} data.markerRange Marker range.\n * @param {String} data.markerName Marker name.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n * to be used by callback, passed in `DowncastDispatcher` constructor.\n */\nexport type DowncastRemoveMarkerEvent = DowncastEvent<'removeMarker'>;\n\nexport interface DiffItemReinsert {\n\ttype: 'reinsert';\n\tname: string;\n\tposition: Position;\n\tlength: number;\n}\n\n/**\n * Helper function, checks whether change of `marker` at `modelPosition` should be converted. Marker changes are not\n * converted if they happen inside an element with custom conversion method.\n */\nfunction shouldMarkerChangeBeConverted(\n\tmodelPosition: Position,\n\tmarker: Marker,\n\tmapper: Mapper\n): boolean {\n\tconst range = marker.getRange();\n\tconst ancestors = Array.from( modelPosition.getAncestors() );\n\tancestors.shift(); // Remove root element. It cannot be passed to `model.Range#containsItem`.\n\tancestors.reverse();\n\n\tconst hasCustomHandling = ( ancestors as Array<Element> ).some( element => {\n\t\tif ( range.containsItem( element ) ) {\n\t\t\tconst viewElement = mapper.toViewElement( element )!;\n\n\t\t\treturn !!viewElement.getCustomProperty( 'addHighlight' );\n\t\t}\n\t} );\n\n\treturn !hasCustomHandling;\n}\n\nfunction getEventName<TType extends string>( type: TType, data: { item: Item | Selection | DocumentSelection } ) {\n\tconst name = data.item.is( 'element' ) ? data.item.name : '$text';\n\n\treturn `${ type }:${ name }` as const;\n}\n\nfunction walkerValueToEventData( value: TreeWalkerValue ) {\n\tconst item = value.item;\n\tconst itemRange = Range._createFromPositionAndShift( value.previousPosition, value.length! );\n\n\treturn {\n\t\titem,\n\t\trange: itemRange\n\t};\n}\n\n/**\n * Conversion interface that is registered for given {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n * and is passed as one of parameters when {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher dispatcher}\n * fires its events.\n */\nexport interface DowncastConversionApi {\n\n\t/**\n\t * The {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} instance.\n\t */\n\tdispatcher: DowncastDispatcher;\n\n\t/**\n\t * Stores the information about what parts of a processed model item are still waiting to be handled. After a piece of a model item was\n\t * converted, an appropriate consumable value should be {@link module:engine/conversion/modelconsumable~ModelConsumable#consume\n\t * consumed}.\n\t */\n\tconsumable: Consumable;\n\n\t/**\n\t * The {@link module:engine/conversion/mapper~Mapper} instance.\n\t */\n\tmapper: Mapper;\n\n\t/**\n\t * The {@link module:engine/model/schema~Schema} instance set for the model that is downcast.\n\t */\n\tschema: Schema;\n\n\t/**\n\t * The {@link module:engine/view/downcastwriter~DowncastWriter} instance used to manipulate the data during conversion.\n\t */\n\twriter: DowncastWriter;\n\n\t/**\n\t * An object with an additional configuration which can be used during the conversion process.\n\t * Available only for data downcast conversion.\n\t */\n\toptions: Record<string, unknown>;\n\n\t/**\n\t * Triggers conversion of a specified item.\n\t * This conversion is triggered within (as a separate process of) the parent conversion.\n\t *\n\t * @param item The model item to trigger nested insert conversion on.\n\t */\n\tconvertItem( item: Item ): void;\n\n\t/**\n\t * Triggers conversion of children of a specified element.\n\t *\n\t * @param element The model element to trigger children insert conversion on.\n\t */\n\tconvertChildren( element: Element ): void;\n\n\t/**\n\t * Triggers conversion of attributes of a specified item.\n\t *\n\t * @param item The model item to trigger attribute conversion on.\n\t */\n\tconvertAttributes( item: Item ): void;\n\tcanReuseView( element: ViewElement ): boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/selection\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport Node from './node.js';\nimport Position, { type PositionOffset } from './position.js';\nimport Range from './range.js';\n\nimport type DocumentFragment from './documentfragment.js';\nimport type DocumentSelection from './documentselection.js';\nimport type Element from './element.js';\nimport type Item from './item.js';\n\nimport { CKEditorError, EmitterMixin, isIterable } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Selection is a set of {@link module:engine/model/range~Range ranges}. It has a direction specified by its\n * {@link module:engine/model/selection~Selection#anchor anchor} and {@link module:engine/model/selection~Selection#focus focus}\n * (it can be {@link module:engine/model/selection~Selection#isBackward forward or backward}).\n * Additionally, selection may have its own attributes (think – whether text typed in in this selection\n * should have those attributes – e.g. whether you type a bolded text).\n */\nexport default class Selection extends /* #__PURE__ */ EmitterMixin( TypeCheckable ) {\n\t/**\n\t * Specifies whether the last added range was added as a backward or forward range.\n\t */\n\tprivate _lastRangeBackward: boolean = false;\n\n\t/**\n\t * List of attributes set on current selection.\n\t */\n\tprotected _attrs: Map<string, unknown> = new Map();\n\n\t/** @internal */\n\tpublic _ranges: Array<Range> = [];\n\n\t/**\n\t * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}\n\t * or creates an empty selection if no arguments were passed.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = writer.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = writer.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * const selection = writer.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = writer.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the given document selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const documentSelection = model.document.selection;\n\t * const selection = writer.createSelection( documentSelection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * const selection = writer.createSelection( position );\n\t *\n\t * // Creates selection at the given offset in the given element.\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * const selection = writer.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/model/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = writer.createSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * Selection's constructor allow passing additional options (`'backward'`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * @internal\n\t */\n\tconstructor(\n\t\t...args: [] |\n\t\t[\n\t\t\tselectable: Node,\n\t\t\tplaceOrOffset: PlaceOrOffset,\n\t\t\toptions?: { backward?: boolean }\n\t\t] |\n\t\t[\n\t\t\tselectable?: Exclude<Selectable, Node>,\n\t\t\toptions?: { backward?: boolean }\n\t\t]\n\t) {\n\t\tsuper();\n\n\t\tif ( args.length ) {\n\t\t\tthis.setTo( ...args );\n\t\t}\n\t}\n\n\t/**\n\t * Selection anchor. Anchor is the position from which the selection was started. If a user is making a selection\n\t * by dragging the mouse, the anchor is where the user pressed the mouse button (the beginning of the selection).\n\t *\n\t * Anchor and {@link #focus} define the direction of the selection, which is important\n\t * when expanding/shrinking selection. The focus moves, while the anchor should remain in the same place.\n\t *\n\t * Anchor is always set to the {@link module:engine/model/range~Range#start start} or\n\t * {@link module:engine/model/range~Range#end end} position of the last of selection's ranges. Whether it is\n\t * the `start` or `end` depends on the specified `options.backward`. See the {@link #setTo `setTo()`} method.\n\t *\n\t * May be set to `null` if there are no ranges in the selection.\n\t *\n\t * @see #focus\n\t */\n\tpublic get anchor(): Position | null {\n\t\tif ( this._ranges.length > 0 ) {\n\t\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\n\t\t\treturn this._lastRangeBackward ? range.end : range.start;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Selection focus. Focus is the position where the selection ends. If a user is making a selection\n\t * by dragging the mouse, the focus is where the mouse cursor is.\n\t *\n\t * May be set to `null` if there are no ranges in the selection.\n\t *\n\t * @see #anchor\n\t */\n\tpublic get focus(): Position | null {\n\t\tif ( this._ranges.length > 0 ) {\n\t\t\tconst range = this._ranges[ this._ranges.length - 1 ];\n\n\t\t\treturn this._lastRangeBackward ? range.start : range.end;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Whether the selection is collapsed. Selection is collapsed when there is exactly one range in it\n\t * and it is collapsed.\n\t */\n\tpublic get isCollapsed(): boolean {\n\t\tconst length = this._ranges.length;\n\n\t\tif ( length === 1 ) {\n\t\t\treturn this._ranges[ 0 ].isCollapsed;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the number of ranges in the selection.\n\t */\n\tpublic get rangeCount(): number {\n\t\treturn this._ranges.length;\n\t}\n\n\t/**\n\t * Specifies whether the selection's {@link #focus} precedes the selection's {@link #anchor}.\n\t */\n\tpublic get isBackward(): boolean {\n\t\treturn !this.isCollapsed && this._lastRangeBackward;\n\t}\n\n\t/**\n\t * Checks whether this selection is equal to the given selection. Selections are equal if they have the same directions,\n\t * the same number of ranges and all ranges from one selection equal to ranges from the another selection.\n\t *\n\t * @param otherSelection Selection to compare with.\n\t * @returns `true` if selections are equal, `false` otherwise.\n\t */\n\tpublic isEqual( otherSelection: Selection | DocumentSelection ): boolean {\n\t\tif ( this.rangeCount != otherSelection.rangeCount ) {\n\t\t\treturn false;\n\t\t} else if ( this.rangeCount === 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !this.anchor!.isEqual( otherSelection.anchor! ) || !this.focus!.isEqual( otherSelection.focus! ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const thisRange of this._ranges ) {\n\t\t\tlet found = false;\n\n\t\t\tfor ( const otherRange of otherSelection._ranges ) {\n\t\t\t\tif ( thisRange.isEqual( otherRange ) ) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !found ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns an iterable object that iterates over copies of selection ranges.\n\t */\n\tpublic* getRanges(): IterableIterator<Range> {\n\t\tfor ( const range of this._ranges ) {\n\t\t\tyield new Range( range.start, range.end );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a copy of the first range in the selection.\n\t * First range is the one which {@link module:engine/model/range~Range#start start} position\n\t * {@link module:engine/model/position~Position#isBefore is before} start position of all other ranges\n\t * (not to confuse with the first range added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getFirstRange(): Range | null {\n\t\tlet first = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !first || range.start.isBefore( first.start ) ) {\n\t\t\t\tfirst = range;\n\t\t\t}\n\t\t}\n\n\t\treturn first ? new Range( first.start, first.end ) : null;\n\t}\n\n\t/**\n\t * Returns a copy of the last range in the selection.\n\t * Last range is the one which {@link module:engine/model/range~Range#end end} position\n\t * {@link module:engine/model/position~Position#isAfter is after} end position of all other ranges (not to confuse with the range most\n\t * recently added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getLastRange(): Range | null {\n\t\tlet last = null;\n\n\t\tfor ( const range of this._ranges ) {\n\t\t\tif ( !last || range.end.isAfter( last.end ) ) {\n\t\t\t\tlast = range;\n\t\t\t}\n\t\t}\n\n\t\treturn last ? new Range( last.start, last.end ) : null;\n\t}\n\n\t/**\n\t * Returns the first position in the selection.\n\t * First position is the position that {@link module:engine/model/position~Position#isBefore is before}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getFirstPosition(): Position | null {\n\t\tconst first = this.getFirstRange();\n\n\t\treturn first ? first.start.clone() : null;\n\t}\n\n\t/**\n\t * Returns the last position in the selection.\n\t * Last position is the position that {@link module:engine/model/position~Position#isAfter is after}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getLastPosition(): Position | null {\n\t\tconst lastRange = this.getLastRange();\n\n\t\treturn lastRange ? lastRange.end.clone() : null;\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable}.\n\t *\n\t * ```ts\n\t * // Removes all selection's ranges.\n\t * selection.setTo( null );\n\t *\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * selection.setTo( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * selection.setTo( ranges );\n\t *\n\t * // Sets selection to other selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const otherSelection = writer.createSelection();\n\t * selection.setTo( otherSelection );\n\t *\n\t * // Sets selection to the given document selection.\n\t * // Note: It doesn't copy selection attributes.\n\t * const documentSelection = new DocumentSelection( doc );\n\t * selection.setTo( documentSelection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * selection.setTo( position );\n\t *\n\t * // Sets collapsed selection at the position of the given node and an offset.\n\t * selection.setTo( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n \t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * selection.setTo( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection#setTo()`' method allow passing additional options (`backward`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t */\n\tpublic setTo(\n\t\t...args: [\n\t\t\tselectable: Node,\n\t\t\tplaceOrOffset: PlaceOrOffset,\n\t\t\toptions?: { backward?: boolean }\n\t\t] | [\n\t\t\tselectable?: Exclude<Selectable, Node>,\n\t\t\toptions?: { backward?: boolean }\n\t\t]\n\t): void {\n\t\tlet [ selectable, placeOrOffset, options ] = args;\n\n\t\tif ( typeof placeOrOffset == 'object' ) {\n\t\t\toptions = placeOrOffset;\n\t\t\tplaceOrOffset = undefined;\n\t\t}\n\n\t\tif ( selectable === null ) {\n\t\t\tthis._setRanges( [] );\n\t\t} else if ( selectable instanceof Selection ) {\n\t\t\tthis._setRanges( selectable.getRanges(), selectable.isBackward );\n\t\t} else if ( selectable && typeof ( selectable as any ).getRanges == 'function' ) {\n\t\t\t// We assume that the selectable is a DocumentSelection.\n\t\t\t// It can't be imported here, because it would lead to circular imports.\n\t\t\tthis._setRanges( ( selectable as DocumentSelection ).getRanges(), ( selectable as DocumentSelection ).isBackward );\n\t\t} else if ( selectable instanceof Range ) {\n\t\t\tthis._setRanges( [ selectable ], !!options && !!options.backward );\n\t\t} else if ( selectable instanceof Position ) {\n\t\t\tthis._setRanges( [ new Range( selectable ) ] );\n\t\t} else if ( selectable instanceof Node ) {\n\t\t\tconst backward = !!options && !!options.backward;\n\t\t\tlet range;\n\n\t\t\tif ( placeOrOffset == 'in' ) {\n\t\t\t\trange = Range._createIn( selectable as Element );\n\t\t\t} else if ( placeOrOffset == 'on' ) {\n\t\t\t\trange = Range._createOn( selectable );\n\t\t\t} else if ( placeOrOffset !== undefined ) {\n\t\t\t\trange = new Range( Position._createAt( selectable, placeOrOffset ) );\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * selection.setTo requires the second parameter when the first parameter is a node.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-setto-required-second-parameter\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'model-selection-setto-required-second-parameter', [ this, selectable ] );\n\t\t\t}\n\n\t\t\tthis._setRanges( [ range ], backward );\n\t\t} else if ( isIterable( selectable ) ) {\n\t\t\t// We assume that the selectable is an iterable of ranges.\n\t\t\tthis._setRanges( selectable, options && !!options.backward );\n\t\t} else {\n\t\t\t/**\n\t\t\t * Cannot set the selection to the given place.\n\t\t\t *\n\t\t\t * Invalid parameters were specified when setting the selection. Common issues:\n\t\t\t *\n\t\t\t * * A {@link module:engine/model/textproxy~TextProxy} instance was passed instead of\n\t\t\t * a real {@link module:engine/model/text~Text}.\n\t\t\t * * View nodes were passed instead of model nodes.\n\t\t\t * * `null`/`undefined` was passed.\n\t\t\t *\n\t\t\t * @error model-selection-setto-not-selectable\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-selection-setto-not-selectable', [ this, selectable ] );\n\t\t}\n\t}\n\n\t/**\n\t * Replaces all ranges that were added to the selection with given array of ranges. Last range of the array\n\t * is treated like the last added range and is used to set {@link module:engine/model/selection~Selection#anchor} and\n\t * {@link module:engine/model/selection~Selection#focus}. Accepts a flag describing in which direction the selection is made.\n\t *\n\t * @fires change:range\n\t * @param newRanges Ranges to set.\n\t * @param isLastBackward Flag describing if last added range was selected forward - from start to end (`false`)\n\t * or backward - from end to start (`true`).\n\t */\n\tprotected _setRanges( newRanges: Iterable<Range>, isLastBackward: boolean = false ): void {\n\t\tconst ranges = Array.from( newRanges );\n\n\t\t// Check whether there is any range in new ranges set that is different than all already added ranges.\n\t\tconst anyNewRange = ranges.some( newRange => {\n\t\t\tif ( !( newRange instanceof Range ) ) {\n\t\t\t\t/**\n\t\t\t\t * Selection range set to an object that is not an instance of {@link module:engine/model/range~Range}.\n\t\t\t\t *\n\t\t\t\t * Only {@link module:engine/model/range~Range} instances can be used to set a selection.\n\t\t\t\t * Common mistakes leading to this error are:\n\t\t\t\t *\n\t\t\t\t * * using DOM `Range` object,\n\t\t\t\t * * incorrect CKEditor 5 installation with multiple `ckeditor5-engine` packages having different versions.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-set-ranges-not-range\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-selection-set-ranges-not-range',\n\t\t\t\t\t[ this, newRanges ]\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn this._ranges.every( oldRange => {\n\t\t\t\treturn !oldRange.isEqual( newRange );\n\t\t\t} );\n\t\t} );\n\n\t\t// Don't do anything if nothing changed.\n\t\tif ( ranges.length === this._ranges.length && !anyNewRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._replaceAllRanges( ranges );\n\n\t\tthis._lastRangeBackward = !!isLastBackward;\n\n\t\tthis.fire<SelectionChangeRangeEvent>( 'change:range', { directChange: true } );\n\t}\n\n\t/**\n\t * Moves {@link module:engine/model/selection~Selection#focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link module:engine/model/writer~Writer#createPositionAt writer.createPositionAt()} parameters.\n\t *\n\t * @fires change:range\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic setFocus( itemOrPosition: Item | Position, offset?: PositionOffset ): void {\n\t\tif ( this.anchor === null ) {\n\t\t\t/**\n\t\t\t * Cannot set selection focus if there are no ranges in selection.\n\t\t\t *\n\t\t\t * @error model-selection-setfocus-no-ranges\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-selection-setfocus-no-ranges', [ this, itemOrPosition ] );\n\t\t}\n\n\t\tconst newFocus = Position._createAt( itemOrPosition, offset );\n\n\t\tif ( newFocus.compareWith( this.focus! ) == 'same' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst anchor = this.anchor;\n\n\t\tif ( this._ranges.length ) {\n\t\t\tthis._popRange();\n\t\t}\n\n\t\tif ( newFocus.compareWith( anchor ) == 'before' ) {\n\t\t\tthis._pushRange( new Range( newFocus, anchor ) );\n\t\t\tthis._lastRangeBackward = true;\n\t\t} else {\n\t\t\tthis._pushRange( new Range( anchor, newFocus ) );\n\t\t\tthis._lastRangeBackward = false;\n\t\t}\n\n\t\tthis.fire<SelectionChangeRangeEvent>( 'change:range', { directChange: true } );\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */\n\tpublic getAttribute( key: string ): unknown {\n\t\treturn this._attrs.get( key );\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */\n\tpublic getAttributes(): IterableIterator<[ string, unknown ]> {\n\t\treturn this._attrs.entries();\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attribute keys.\n\t */\n\tpublic getAttributeKeys(): IterableIterator<string> {\n\t\treturn this._attrs.keys();\n\t}\n\n\t/**\n\t * Checks if the selection has an attribute for given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on selection, `false` otherwise.\n\t */\n\tpublic hasAttribute( key: string ): boolean {\n\t\treturn this._attrs.has( key );\n\t}\n\n\t/**\n\t * Removes an attribute with given key from the selection.\n\t *\n\t * If given attribute was set on the selection, fires the {@link #event:change:range} event with\n\t * removed attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param key Key of attribute to remove.\n\t */\n\tpublic removeAttribute( key: string ): void {\n\t\tif ( this.hasAttribute( key ) ) {\n\t\t\tthis._attrs.delete( key );\n\n\t\t\tthis.fire<SelectionChangeAttributeEvent>( 'change:attribute', { attributeKeys: [ key ], directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * If the attribute value has changed, fires the {@link #event:change:range} event with\n\t * the attribute key.\n\t *\n\t * @fires change:attribute\n\t * @param key Key of attribute to set.\n\t * @param value Attribute value.\n\t */\n\tpublic setAttribute( key: string, value: unknown ): void {\n\t\tif ( this.getAttribute( key ) !== value ) {\n\t\t\tthis._attrs.set( key, value );\n\n\t\t\tthis.fire<SelectionChangeAttributeEvent>( 'change:attribute', { attributeKeys: [ key ], directChange: true } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */\n\tpublic getSelectedElement(): Element | null {\n\t\tif ( this.rangeCount !== 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.getFirstRange()!.getContainedElement();\n\t}\n\n\t/**\n\t * Gets elements of type {@link module:engine/model/schema~Schema#isBlock \"block\"} touched by the selection.\n\t *\n\t * This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t *\n\t * **Note:** `getSelectedBlocks()` returns blocks that are nested in other non-block elements\n\t * but will not return blocks nested in other blocks.\n\t *\n\t * In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):\n\t *\n\t * ```xml\n\t * <paragraph>[a</paragraph>\n\t * <blockQuote>\n\t * \t<paragraph>b</paragraph>\n\t * </blockQuote>\n\t * <paragraph>c]d</paragraph>\n\t * ```\n\t *\n\t * In this case the paragraph will also be returned, despite the collapsed selection:\n\t *\n\t * ```xml\n\t * <paragraph>[]a</paragraph>\n\t * ```\n\t *\n\t * In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:\n\t *\n\t * ```xml\n\t * [<blockA></blockA>\n\t * <blockB>\n\t * \t<blockC></blockC>\n\t * \t<blockD></blockD>\n\t * </blockB>\n\t * <blockE></blockE>]\n\t * ```\n\t *\n\t * If the selection is inside a block all the inner blocks (A & B) are returned:\n\t *\n\t * ```xml\n\t * <block>\n\t * \t<blockA>[a</blockA>\n\t * \t<blockB>b]</blockB>\n\t * </block>\n\t * ```\n\t *\n\t * **Special case**: Selection ignores first and/or last blocks if nothing (from user perspective) is selected in them.\n\t *\n\t * ```xml\n\t * // Selection ends and the beginning of the last block.\n\t * <paragraph>[a</paragraph>\n\t * <paragraph>b</paragraph>\n\t * <paragraph>]c</paragraph> // This block will not be returned\n\t *\n\t * // Selection begins at the end of the first block.\n\t * <paragraph>a[</paragraph> // This block will not be returned\n\t * <paragraph>b</paragraph>\n\t * <paragraph>c]</paragraph>\n\t *\n\t * // Selection begings at the end of the first block and ends at the beginning of the last block.\n\t * <paragraph>a[</paragraph> // This block will not be returned\n\t * <paragraph>b</paragraph>\n\t * <paragraph>]c</paragraph> // This block will not be returned\n\t * ```\n\t */\n\tpublic* getSelectedBlocks(): IterableIterator<Element> {\n\t\tconst visited = new WeakSet<Node | DocumentFragment>();\n\n\t\tfor ( const range of this.getRanges() ) {\n\t\t\t// Get start block of range in case of a collapsed range.\n\t\t\tconst startBlock = getParentBlock( range.start, visited );\n\n\t\t\tif ( isStartBlockSelected( startBlock, range ) ) {\n\t\t\t\tyield startBlock as any;\n\t\t\t}\n\n\t\t\tfor ( const value of range.getWalker() ) {\n\t\t\t\tconst block = value.item;\n\n\t\t\t\tif ( value.type == 'elementEnd' && isUnvisitedTopBlock( block as any, visited, range ) ) {\n\t\t\t\t\tyield block as Element;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst endBlock = getParentBlock( range.end, visited );\n\n\t\t\tif ( isEndBlockSelected( endBlock, range ) ) {\n\t\t\t\tyield endBlock as any;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t * at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position\n\t * touching the element's end.\n\t *\n\t * By default, this method will check whether the entire content of the selection's current root is selected.\n\t * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t */\n\tpublic containsEntireContent( element: Element = this.anchor!.root as Element ): boolean {\n\t\tconst limitStartPosition = Position._createAt( element, 0 );\n\t\tconst limitEndPosition = Position._createAt( element, 'end' );\n\n\t\treturn limitStartPosition.isTouching( this.getFirstPosition()! ) &&\n\t\t\tlimitEndPosition.isTouching( this.getLastPosition()! );\n\t}\n\n\t/**\n\t * Adds given range to internal {@link #_ranges ranges array}. Throws an error\n\t * if given range is intersecting with any range that is already stored in this selection.\n\t */\n\tprotected _pushRange( range: Range ): void {\n\t\tthis._checkRange( range );\n\t\tthis._ranges.push( new Range( range.start, range.end ) );\n\t}\n\n\t/**\n\t * Checks if given range intersects with ranges that are already in the selection. Throws an error if it does.\n\t */\n\tprotected _checkRange( range: Range ): void {\n\t\tfor ( let i = 0; i < this._ranges.length; i++ ) {\n\t\t\tif ( range.isIntersecting( this._ranges[ i ] ) ) {\n\t\t\t\t/**\n\t\t\t\t * Trying to add a range that intersects with another range in the selection.\n\t\t\t\t *\n\t\t\t\t * @error model-selection-range-intersects\n\t\t\t\t * @param addedRange Range that was added to the selection.\n\t\t\t\t * @param intersectingRange Range in the selection that intersects with `addedRange`.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'model-selection-range-intersects',\n\t\t\t\t\t[ this, range ],\n\t\t\t\t\t{ addedRange: range, intersectingRange: this._ranges[ i ] }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Replaces all the ranges by the given ones.\n\t * Uses {@link #_popRange _popRange} and {@link #_pushRange _pushRange} to ensure proper ranges removal and addition.\n\t */\n\tprotected _replaceAllRanges( ranges: Array<Range> ): void {\n\t\tthis._removeAllRanges();\n\n\t\tfor ( const range of ranges ) {\n\t\t\tthis._pushRange( range );\n\t\t}\n\t}\n\n\t/**\n\t * Deletes ranges from internal range array. Uses {@link #_popRange _popRange} to\n\t * ensure proper ranges removal.\n\t */\n\tprotected _removeAllRanges(): void {\n\t\twhile ( this._ranges.length > 0 ) {\n\t\t\tthis._popRange();\n\t\t}\n\t}\n\n\t/**\n\t * Removes most recently added range from the selection.\n\t */\n\tprotected _popRange(): void {\n\t\tthis._ranges.pop();\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nSelection.prototype.is = function( type: string ): boolean {\n\treturn type === 'selection' || type === 'model:selection';\n};\n\n/**\n * Describes one of the events: `change:range` or `change:attribute`.\n */\nexport type SelectionChangeEvent = {\n\tname: 'change' | 'change:range' | 'change:attribute';\n\targs: [ {\n\t\tdirectChange: boolean;\n\t\tattributeKeys?: Array<string>;\n\t} ];\n};\n\n/**\n * Fired when selection range(s) changed.\n *\n * @eventName ~Selection#change:range\n * @param directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its position\n * was directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n * changed because the structure of the model has been changed (which means an indirect change).\n * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n * which mean that they are not updated once the document changes.\n */\nexport type SelectionChangeRangeEvent = {\n\tname: 'change' | 'change:range';\n\targs: [ {\n\t\tdirectChange: boolean;\n\t} ];\n};\n\n/**\n * Fired when selection attribute changed.\n *\n * @eventName ~Selection#change:attribute\n * @param directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its attributes\n * were directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n * changed in the model and its attributes were refreshed (which means an indirect change).\n * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n * which mean that they are not updated once the document changes.\n * @param attributeKeys Array containing keys of attributes that changed.\n */\nexport type SelectionChangeAttributeEvent = {\n\tname: 'change' | 'change:attribute';\n\targs: [ {\n\t\tdirectChange: boolean;\n\t\tattributeKeys: Array<string>;\n\t} ];\n};\n\n/**\n * Checks whether the given element extends $block in the schema and has a parent (is not a root).\n * Marks it as already visited.\n */\nfunction isUnvisitedBlock( element: Node | DocumentFragment, visited: WeakSet<Node | DocumentFragment> ) {\n\tif ( visited.has( element ) ) {\n\t\treturn false;\n\t}\n\n\tvisited.add( element );\n\n\treturn element.root.document!.model.schema.isBlock( element ) && !!element.parent;\n}\n\n/**\n * Checks if the given element is a $block was not previously visited and is a top block in a range.\n */\nfunction isUnvisitedTopBlock( element: Element, visited: WeakSet<Node | DocumentFragment>, range: Range ) {\n\treturn isUnvisitedBlock( element, visited ) && isTopBlockInRange( element, range );\n}\n\n/**\n * Finds the lowest element in position's ancestors which is a block.\n * It will search until first ancestor that is a limit element.\n * Marks all ancestors as already visited to not include any of them later on.\n */\nfunction getParentBlock( position: Position, visited: WeakSet<Node | DocumentFragment> ) {\n\tconst element = position.parent;\n\tconst schema = element.root.document!.model.schema;\n\n\tconst ancestors = position.parent.getAncestors( { parentFirst: true, includeSelf: true } );\n\n\tlet hasParentLimit = false;\n\n\tconst block = ancestors.find( ( element ): element is Element => {\n\t\t// Stop searching after first parent node that is limit element.\n\t\tif ( hasParentLimit ) {\n\t\t\treturn false;\n\t\t}\n\n\t\thasParentLimit = schema.isLimit( element );\n\n\t\treturn !hasParentLimit && isUnvisitedBlock( element, visited );\n\t} );\n\n\t// Mark all ancestors of this position's parent, because find() might've stopped early and\n\t// the found block may be a child of another block.\n\tancestors.forEach( element => visited.add( element ) );\n\n\treturn block;\n}\n\n/**\n * Checks if the blocks is not nested in other block inside a range.\n */\nfunction isTopBlockInRange( block: Node, range: Range ) {\n\tconst parentBlock = findAncestorBlock( block );\n\n\tif ( !parentBlock ) {\n\t\treturn true;\n\t}\n\n\t// Add loose flag to check as parentRange can be equal to range.\n\tconst isParentInRange = range.containsRange( Range._createOn( parentBlock ), true );\n\n\treturn !isParentInRange;\n}\n\n/**\n * If a selection starts at the end of a block, that block is not returned as from the user's perspective this block wasn't selected.\n * See [#11585](https://github.com/ckeditor/ckeditor5/issues/11585) for more details.\n *\n * ```xml\n * <paragraph>a[</paragraph> // This block will not be returned\n * <paragraph>b</paragraph>\n * <paragraph>c]</paragraph>\n * ```\n *\n * Collapsed selection is not affected by it:\n *\n * ```xml\n * <paragraph>a[]</paragraph> // This block will be returned\n * ```\n */\nfunction isStartBlockSelected( startBlock: Element | undefined, range: Range ): boolean {\n\tif ( !startBlock ) {\n\t\treturn false;\n\t}\n\n\tif ( range.isCollapsed || startBlock.isEmpty ) {\n\t\treturn true;\n\t}\n\n\tif ( range.start.isTouching( Position._createAt( startBlock, startBlock.maxOffset ) ) ) {\n\t\treturn false;\n\t}\n\n\treturn isTopBlockInRange( startBlock, range );\n}\n\n/**\n * If a selection ends at the beginning of a block, that block is not returned as from the user's perspective this block wasn't selected.\n * See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n *\n * ```xml\n * <paragraph>[a</paragraph>\n * <paragraph>b</paragraph>\n * <paragraph>]c</paragraph> // this block will not be returned\n * ```\n *\n * Collapsed selection is not affected by it:\n *\n * ```xml\n * <paragraph>[]a</paragraph> // this block will be returned\n * ```\n */\nfunction isEndBlockSelected( endBlock: Element | undefined, range: Range ): boolean {\n\tif ( !endBlock ) {\n\t\treturn false;\n\t}\n\n\tif ( range.isCollapsed || endBlock.isEmpty ) {\n\t\treturn true;\n\t}\n\n\tif ( range.end.isTouching( Position._createAt( endBlock, 0 ) ) ) {\n\t\treturn false;\n\t}\n\n\treturn isTopBlockInRange( endBlock, range );\n}\n\n/**\n * Returns first ancestor block of a node.\n */\nfunction findAncestorBlock( node: Node | DocumentFragment ) {\n\tconst schema = node.root.document!.model.schema;\n\n\tlet parent = node.parent;\n\n\twhile ( parent ) {\n\t\tif ( schema.isBlock( parent ) ) {\n\t\t\treturn parent as Element;\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n}\n\n/**\n * An entity that is used to set selection.\n *\n * See also {@link module:engine/model/selection~Selection#setTo}.\n */\nexport type Selectable = Selection | DocumentSelection | Position | Range | Node | Iterable<Range> | null;\n\n/**\n * The place or offset of the selection.\n */\nexport type PlaceOrOffset = number | 'before' | 'end' | 'after' | 'on' | 'in';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/liverange\n */\n\nimport Range from './range.js';\n\nimport type { ModelApplyOperationEvent } from './model.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type Item from './item.js';\nimport type MergeOperation from './operation/mergeoperation.js';\nimport type MoveOperation from './operation/moveoperation.js';\nimport type Operation from './operation/operation.js';\nimport type Position from './position.js';\n\nimport { EmitterMixin } from '@ckeditor/ckeditor5-utils';\n\n/**\n * `LiveRange` is a type of {@link module:engine/model/range~Range Range}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Be very careful when dealing with `LiveRange`. Each `LiveRange` instance bind events that might\n * have to be unbound. Use {@link module:engine/model/liverange~LiveRange#detach detach} whenever you don't need `LiveRange` anymore.\n */\nexport default class LiveRange extends /* #__PURE__ */ EmitterMixin( Range ) {\n\t/**\n\t * Creates a live range.\n\t *\n\t * @see module:engine/model/range~Range\n\t */\n\tconstructor( start: Position, end?: Position | null ) {\n\t\tsuper( start, end );\n\n\t\tbindWithDocument.call( this );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by `LiveRange`. Use it whenever you don't need `LiveRange` instance\n\t * anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t * referring to it).\n\t */\n\tpublic detach(): void {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/range~Range range instance} that is equal to this live range.\n\t */\n\tpublic toRange(): Range {\n\t\treturn new Range( this.start, this.end );\n\t}\n\n\t/**\n\t * Creates a `LiveRange` instance that is equal to the given range.\n\t */\n\tpublic static fromRange( range: Range ): LiveRange {\n\t\treturn new LiveRange( range.start, range.end );\n\t}\n\n\t/**\n\t * @see module:engine/model/range~Range._createIn\n\t * @internal\n\t */\n\n\tdeclare public static readonly _createIn: ( element: Element | DocumentFragment ) => LiveRange;\n\n\t/**\n\t * @see module:engine/model/range~Range._createOn\n\t * @internal\n\t */\n\n\tdeclare public static readonly _createOn: ( element: Item | DocumentFragment ) => LiveRange;\n\n\t/**\n\t * @see module:engine/model/range~Range._createFromPositionAndShift\n\t * @internal\n\t */\n\n\tdeclare public static readonly _createFromPositionAndShift: ( position: Position, shift: number ) => LiveRange;\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nLiveRange.prototype.is = function( type: string ): boolean {\n\treturn type === 'liveRange' || type === 'model:liveRange' ||\n\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\ttype == 'range' || type === 'model:range';\n};\n\n/**\n * Fired when `LiveRange` instance boundaries have changed due to changes in the\n * {@link module:engine/model/document~Document document}.\n *\n * @eventName ~LiveRange#change:range\n * @param oldRange Range with start and end position equal to start and end position of this live\n * range before it got changed.\n * @param data Object with additional information about the change.\n * @param data.deletionPosition Source position for remove and merge changes.\n * Available if the range was moved to the graveyard root, `null` otherwise.\n */\nexport type LiveRangeChangeRangeEvent = {\n\tname: 'change' | 'change:range';\n\targs: [ range: Range, data: { deletionPosition: Position | null } ];\n};\n\n/**\n * Fired when `LiveRange` instance boundaries have not changed after a change in {@link module:engine/model/document~Document document}\n * but the change took place inside the range, effectively changing its content.\n *\n * @eventName ~LiveRange#change:content\n * @param range Range with start and end position equal to start and end position of\n * change range.\n * @param data Object with additional information about the change.\n * @param data.deletionPosition Due to the nature of this event, this property is always set to `null`. It is passed\n * for compatibility with the {@link module:engine/model/liverange~LiveRange#event:change:range} event.\n */\nexport type LiveRangeChangeContentEvent = {\n\tname: 'change' | 'change:content';\n\targs: [ range: Range, data: { deletionPosition: null } ];\n};\n\n/**\n * Describes `change:range` or `change:content` event.\n */\nexport type LiveRangeChangeEvent = {\n\tname: 'change' | 'change:range' | 'change:content';\n\targs: [ range: Range, data: { deletionPosition: Position | null } ];\n};\n\n/**\n * Binds this `LiveRange` to the {@link module:engine/model/document~Document document}\n * that owns this range's {@link module:engine/model/range~Range#root root}.\n */\nfunction bindWithDocument( this: LiveRange ) {\n\tthis.listenTo<ModelApplyOperationEvent>(\n\t\tthis.root.document!.model,\n\t\t'applyOperation',\n\t\t( event, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( !operation.isDocumentOperation ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttransform.call( this, operation );\n\t\t},\n\t\t{ priority: 'low' }\n\t);\n}\n\n/**\n * Updates this range accordingly to the updates applied to the model. Bases on change events.\n */\nfunction transform( this: LiveRange, operation: Operation ) {\n\t// Transform the range by the operation. Join the result ranges if needed.\n\tconst ranges = this.getTransformedByOperation( operation );\n\tconst result = Range._createFromRanges( ranges );\n\n\tconst boundariesChanged = !result.isEqual( this );\n\tconst contentChanged = doesOperationChangeRangeContent( this, operation );\n\n\tlet deletionPosition = null;\n\n\tif ( boundariesChanged ) {\n\t\t// If range boundaries have changed, fire `change:range` event.\n\t\t//\n\t\tif ( result.root.rootName == '$graveyard' ) {\n\t\t\t// If the range was moved to the graveyard root, set `deletionPosition`.\n\t\t\tif ( operation.type == 'remove' ) {\n\t\t\t\tdeletionPosition = ( operation as MoveOperation ).sourcePosition;\n\t\t\t} else {\n\t\t\t\t// Merge operation.\n\t\t\t\tdeletionPosition = ( operation as MergeOperation ).deletionPosition;\n\t\t\t}\n\t\t}\n\n\t\tconst oldRange = this.toRange();\n\n\t\t( this as any ).start = result.start;\n\t\t( this as any ).end = result.end;\n\n\t\tthis.fire<LiveRangeChangeRangeEvent>( 'change:range', oldRange, { deletionPosition } );\n\t} else if ( contentChanged ) {\n\t\t// If range boundaries have not changed, but there was change inside the range, fire `change:content` event.\n\t\tthis.fire<LiveRangeChangeContentEvent>( 'change:content', this.toRange(), { deletionPosition } );\n\t}\n}\n\n/**\n * Checks whether given operation changes something inside the range (even if it does not change boundaries).\n */\nfunction doesOperationChangeRangeContent( range: Range, operation: any ) {\n\tswitch ( operation.type ) {\n\t\tcase 'insert':\n\t\t\treturn range.containsPosition( operation.position );\n\t\tcase 'move':\n\t\tcase 'remove':\n\t\tcase 'reinsert':\n\t\tcase 'merge':\n\t\t\treturn range.containsPosition( operation.sourcePosition ) ||\n\t\t\t\trange.start.isEqual( operation.sourcePosition ) ||\n\t\t\t\trange.containsPosition( operation.targetPosition );\n\t\tcase 'split':\n\t\t\treturn range.containsPosition( operation.splitPosition ) || range.containsPosition( operation.insertionPosition );\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/documentselection\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport LiveRange from './liverange.js';\nimport Selection, {\n\ttype SelectionChangeAttributeEvent,\n\ttype SelectionChangeRangeEvent\n} from './selection.js';\nimport Text from './text.js';\nimport TextProxy from './textproxy.js';\n\nimport type { default as Document, DocumentChangeEvent } from './document.js';\nimport type { default as Model, ModelApplyOperationEvent } from './model.js';\nimport type { Marker, MarkerCollectionUpdateEvent } from './markercollection.js';\nimport type Batch from './batch.js';\nimport type Element from './element.js';\nimport type Item from './item.js';\nimport type { default as Position, PositionOffset } from './position.js';\nimport type Range from './range.js';\nimport type Schema from './schema.js';\n\nimport {\n\tCKEditorError,\n\tCollection,\n\tEmitterMixin,\n\ttoMap,\n\tuid\n} from '@ckeditor/ckeditor5-utils';\n\nconst storePrefix = 'selection:';\n\n/**\n * `DocumentSelection` is a special selection which is used as the\n * {@link module:engine/model/document~Document#selection document's selection}.\n * There can be only one instance of `DocumentSelection` per document.\n *\n * Document selection can only be changed by using the {@link module:engine/model/writer~Writer} instance\n * inside the {@link module:engine/model/model~Model#change `change()`} block, as it provides a secure way to modify model.\n *\n * `DocumentSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}\n * to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n *\n * Differences between {@link module:engine/model/selection~Selection} and `DocumentSelection` are:\n * * there is always a range in `DocumentSelection` - even if no ranges were added there is a \"default range\"\n * present in the selection,\n * * ranges added to this selection updates automatically when the document changes,\n * * attributes of `DocumentSelection` are updated automatically according to selection ranges.\n *\n * Since `DocumentSelection` uses {@link module:engine/model/liverange~LiveRange live ranges}\n * and is updated when {@link module:engine/model/document~Document document}\n * changes, it cannot be set on {@link module:engine/model/node~Node nodes}\n * that are inside {@link module:engine/model/documentfragment~DocumentFragment document fragment}.\n * If you need to represent a selection in document fragment,\n * use {@link module:engine/model/selection~Selection Selection class} instead.\n */\nexport default class DocumentSelection extends /* #__PURE__ */ EmitterMixin( TypeCheckable ) {\n\t/**\n\t * Selection used internally by that class (`DocumentSelection` is a proxy to that selection).\n\t */\n\tprivate _selection: LiveSelection;\n\n\t/**\n\t * Creates an empty live selection for given {@link module:engine/model/document~Document}.\n\t *\n\t * @param doc Document which owns this selection.\n\t */\n\tconstructor( doc: Document ) {\n\t\tsuper();\n\n\t\tthis._selection = new LiveSelection( doc );\n\n\t\tthis._selection.delegate( 'change:range' ).to( this );\n\t\tthis._selection.delegate( 'change:attribute' ).to( this );\n\t\tthis._selection.delegate( 'change:marker' ).to( this );\n\t}\n\n\t/**\n\t * Describes whether the selection is collapsed. Selection is collapsed when there is exactly one range which is\n\t * collapsed.\n\t */\n\tpublic get isCollapsed(): boolean {\n\t\treturn this._selection.isCollapsed;\n\t}\n\n\t/**\n\t * Selection anchor. Anchor may be described as a position where the most recent part of the selection starts.\n\t * Together with {@link #focus} they define the direction of selection, which is important\n\t * when expanding/shrinking selection. Anchor is always {@link module:engine/model/range~Range#start start} or\n\t * {@link module:engine/model/range~Range#end end} position of the most recently added range.\n\t *\n\t * Is set to `null` if there are no ranges in selection.\n\t *\n\t * @see #focus\n\t */\n\tpublic get anchor(): Position | null {\n\t\treturn this._selection.anchor;\n\t}\n\n\t/**\n\t * Selection focus. Focus is a position where the selection ends.\n\t *\n\t * Is set to `null` if there are no ranges in selection.\n\t *\n\t * @see #anchor\n\t */\n\tpublic get focus(): Position | null {\n\t\treturn this._selection.focus;\n\t}\n\n\t/**\n\t * Number of ranges in selection.\n\t */\n\tpublic get rangeCount(): number {\n\t\treturn this._selection.rangeCount;\n\t}\n\n\t/**\n\t * Describes whether `Documentselection` has own range(s) set, or if it is defaulted to\n\t * {@link module:engine/model/document~Document#_getDefaultRange document's default range}.\n\t */\n\tpublic get hasOwnRange(): boolean {\n\t\treturn this._selection.hasOwnRange;\n\t}\n\n\t/**\n\t * Specifies whether the {@link #focus}\n\t * precedes {@link #anchor}.\n\t *\n\t * @readonly\n\t * @type {Boolean}\n\t */\n\tpublic get isBackward(): boolean {\n\t\treturn this._selection.isBackward;\n\t}\n\n\t/**\n\t * Describes whether the gravity is overridden (using {@link module:engine/model/writer~Writer#overrideSelectionGravity}) or not.\n\t *\n\t * Note that the gravity remains overridden as long as will not be restored the same number of times as it was overridden.\n\t */\n\tpublic get isGravityOverridden(): boolean {\n\t\treturn this._selection.isGravityOverridden;\n\t}\n\n\t/**\n\t * A collection of selection {@link module:engine/model/markercollection~Marker markers}.\n\t * Marker is a selection marker when selection range is inside the marker range.\n\t *\n\t * **Note**: Only markers from {@link ~DocumentSelection#observeMarkers observed markers groups} are collected.\n\t */\n\tpublic get markers(): Collection<Marker> {\n\t\treturn this._selection.markers;\n\t}\n\n\t/**\n\t * Used for the compatibility with the {@link module:engine/model/selection~Selection#isEqual} method.\n\t *\n\t * @internal\n\t */\n\tpublic get _ranges(): Array<Range> {\n\t\treturn this._selection._ranges;\n\t}\n\n\t/**\n\t * Returns an iterable that iterates over copies of selection ranges.\n\t */\n\tpublic getRanges(): IterableIterator<Range> {\n\t\treturn this._selection.getRanges();\n\t}\n\n\t/**\n\t * Returns the first position in the selection.\n\t * First position is the position that {@link module:engine/model/position~Position#isBefore is before}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getFirstPosition(): Position | null {\n\t\treturn this._selection.getFirstPosition();\n\t}\n\n\t/**\n\t * Returns the last position in the selection.\n\t * Last position is the position that {@link module:engine/model/position~Position#isAfter is after}\n\t * any other position in the selection.\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getLastPosition(): Position | null {\n\t\treturn this._selection.getLastPosition();\n\t}\n\n\t/**\n\t * Returns a copy of the first range in the selection.\n\t * First range is the one which {@link module:engine/model/range~Range#start start} position\n\t * {@link module:engine/model/position~Position#isBefore is before} start position of all other ranges\n\t * (not to confuse with the first range added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getFirstRange(): Range | null {\n\t\treturn this._selection.getFirstRange();\n\t}\n\n\t/**\n\t * Returns a copy of the last range in the selection.\n\t * Last range is the one which {@link module:engine/model/range~Range#end end} position\n\t * {@link module:engine/model/position~Position#isAfter is after} end position of all other ranges (not to confuse with the range most\n\t * recently added to the selection).\n\t *\n\t * Returns `null` if there are no ranges in selection.\n\t */\n\tpublic getLastRange(): Range | null {\n\t\treturn this._selection.getLastRange();\n\t}\n\n\t/**\n\t * Gets elements of type {@link module:engine/model/schema~Schema#isBlock \"block\"} touched by the selection.\n\t *\n\t * This method's result can be used for example to apply block styling to all blocks covered by this selection.\n\t *\n\t * **Note:** `getSelectedBlocks()` returns blocks that are nested in other non-block elements\n\t * but will not return blocks nested in other blocks.\n\t *\n\t * In this case the function will return exactly all 3 paragraphs (note: `<blockQuote>` is not a block itself):\n\t *\n\t * ```\n\t * <paragraph>[a</paragraph>\n\t * <blockQuote>\n\t * \t<paragraph>b</paragraph>\n\t * </blockQuote>\n\t * <paragraph>c]d</paragraph>\n\t * ```\n\t *\n\t * In this case the paragraph will also be returned, despite the collapsed selection:\n\t *\n\t * ```\n\t * <paragraph>[]a</paragraph>\n\t * ```\n\t *\n\t * In such a scenario, however, only blocks A, B & E will be returned as blocks C & D are nested in block B:\n\t *\n\t * ```\n\t * [<blockA></blockA>\n\t * <blockB>\n\t * \t<blockC></blockC>\n\t * \t<blockD></blockD>\n\t * </blockB>\n\t * <blockE></blockE>]\n\t * ```\n\t *\n\t * If the selection is inside a block all the inner blocks (A & B) are returned:\n\t *\n\t * ```\n\t * <block>\n\t * \t<blockA>[a</blockA>\n\t * \t<blockB>b]</blockB>\n\t * </block>\n\t * ```\n\t *\n\t * **Special case**: If a selection ends at the beginning of a block, that block is not returned as from user perspective\n\t * this block wasn't selected. See [#984](https://github.com/ckeditor/ckeditor5-engine/issues/984) for more details.\n\t *\n\t * ```\n\t * <paragraph>[a</paragraph>\n\t * <paragraph>b</paragraph>\n\t * <paragraph>]c</paragraph> // this block will not be returned\n\t * ```\n\t */\n\tpublic getSelectedBlocks(): IterableIterator<Element> {\n\t\treturn this._selection.getSelectedBlocks();\n\t}\n\n\t/**\n\t * Returns the selected element. {@link module:engine/model/element~Element Element} is considered as selected if there is only\n\t * one range in the selection, and that range contains exactly one element.\n\t * Returns `null` if there is no selected element.\n\t */\n\tpublic getSelectedElement(): Element | null {\n\t\treturn this._selection.getSelectedElement();\n\t}\n\n\t/**\n\t * Checks whether the selection contains the entire content of the given element. This means that selection must start\n\t * at a position {@link module:engine/model/position~Position#isTouching touching} the element's start and ends at position\n\t * touching the element's end.\n\t *\n\t * By default, this method will check whether the entire content of the selection's current root is selected.\n\t * Useful to check if e.g. the user has just pressed <kbd>Ctrl</kbd> + <kbd>A</kbd>.\n\t */\n\tpublic containsEntireContent( element: Element ): boolean {\n\t\treturn this._selection.containsEntireContent( element );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by document selection.\n\t */\n\tpublic destroy(): void {\n\t\tthis._selection.destroy();\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attribute keys.\n\t */\n\tpublic getAttributeKeys(): IterableIterator<string> {\n\t\treturn this._selection.getAttributeKeys();\n\t}\n\n\t/**\n\t * Returns iterable that iterates over this selection's attributes.\n\t *\n\t * Attributes are returned as arrays containing two items. First one is attribute key and second is attribute value.\n\t * This format is accepted by native `Map` object and also can be passed in `Node` constructor.\n\t */\n\tpublic getAttributes(): IterableIterator<[ string, unknown ]> {\n\t\treturn this._selection.getAttributes();\n\t}\n\n\t/**\n\t * Gets an attribute value for given key or `undefined` if that attribute is not set on the selection.\n\t *\n\t * @param key Key of attribute to look for.\n\t * @returns Attribute value or `undefined`.\n\t */\n\tpublic getAttribute( key: string ): unknown {\n\t\treturn this._selection.getAttribute( key );\n\t}\n\n\t/**\n\t * Checks if the selection has an attribute for given key.\n\t *\n\t * @param key Key of attribute to check.\n\t * @returns `true` if attribute with given key is set on selection, `false` otherwise.\n\t */\n\tpublic hasAttribute( key: string ): boolean {\n\t\treturn this._selection.hasAttribute( key );\n\t}\n\n\t/**\n\t * Refreshes selection attributes and markers according to the current position in the model.\n\t */\n\tpublic refresh(): void {\n\t\tthis._selection.updateMarkers();\n\t\tthis._selection._updateAttributes( false );\n\t}\n\n\t/**\n\t * Registers a marker group prefix or a marker name to be collected in the\n\t * {@link ~DocumentSelection#markers selection markers collection}.\n\t *\n\t * See also {@link module:engine/model/markercollection~MarkerCollection#getMarkersGroup `MarkerCollection#getMarkersGroup()`}.\n\t *\n\t * @param prefixOrName The marker group prefix or marker name.\n\t */\n\tpublic observeMarkers( prefixOrName: string ): void {\n\t\tthis._selection.observeMarkers( prefixOrName );\n\t}\n\n\t/**\n\t * Moves {@link module:engine/model/documentselection~DocumentSelection#focus} to the specified location.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelectionFocus} method.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link module:engine/model/writer~Writer#createPositionAt writer.createPositionAt()} parameters.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelectionFocus\n\t * @internal\n\t * @param offset Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic _setFocus( itemOrPosition: Item | Position, offset?: PositionOffset ): void {\n\t\tthis._selection.setFocus( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Sets this selection's ranges and direction to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable}.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelection} method.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelection\n\t * @internal\n\t */\n\tpublic _setTo( ...args: Parameters<Selection[ 'setTo' ]> ): void {\n\t\tthis._selection.setTo( ...args );\n\t}\n\n\t/**\n\t * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#setSelectionAttribute} method.\n\t *\n\t * @see module:engine/model/writer~Writer#setSelectionAttribute\n\t * @internal\n\t * @param key Key of the attribute to set.\n\t * @param value Attribute value.\n\t */\n\tpublic _setAttribute( key: string, value: unknown ): void {\n\t\tthis._selection.setAttribute( key, value );\n\t}\n\n\t/**\n\t * Removes an attribute with given key from the selection.\n\t * If the given attribute was set on the selection, fires the {@link module:engine/model/selection~Selection#event:change:range}\n\t * event with removed attribute key.\n\t * Should be used only within the {@link module:engine/model/writer~Writer#removeSelectionAttribute} method.\n\t *\n\t * @see module:engine/model/writer~Writer#removeSelectionAttribute\n\t * @internal\n\t * @param key Key of the attribute to remove.\n\t */\n\tpublic _removeAttribute( key: string ): void {\n\t\tthis._selection.removeAttribute( key );\n\t}\n\n\t/**\n\t * Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t *\n\t * @internal\n\t */\n\tpublic _getStoredAttributes(): Iterable<[ string, unknown ]> {\n\t\treturn this._selection.getStoredAttributes();\n\t}\n\n\t/**\n\t * Temporarily changes the gravity of the selection from the left to the right.\n\t *\n\t * The gravity defines from which direction the selection inherits its attributes. If it's the default left\n\t * gravity, the selection (after being moved by the the user) inherits attributes from its left hand side.\n\t * This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t *\n\t * It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t * of the process.\n\t *\n\t * @see module:engine/model/writer~Writer#overrideSelectionGravity\n\t * @internal\n\t * @returns The unique id which allows restoring the gravity.\n\t */\n\tpublic _overrideGravity(): string {\n\t\treturn this._selection.overrideGravity();\n\t}\n\n\t/**\n\t * Restores the {@link ~DocumentSelection#_overrideGravity overridden gravity}.\n\t *\n\t * Restoring the gravity is only possible using the unique identifier returned by\n\t * {@link ~DocumentSelection#_overrideGravity}. Note that the gravity remains overridden as long as won't be restored\n\t * the same number of times it was overridden.\n\t *\n\t * @see module:engine/model/writer~Writer#restoreSelectionGravity\n\t * @internal\n\t * @param uid The unique id returned by {@link #_overrideGravity}.\n\t */\n\tpublic _restoreGravity( uid: string ): void {\n\t\tthis._selection.restoreGravity( uid );\n\t}\n\n\t/**\n\t * Generates and returns an attribute key for selection attributes store, basing on original attribute key.\n\t *\n\t * @internal\n\t * @param key Attribute key to convert.\n\t * @returns Converted attribute key, applicable for selection store.\n\t */\n\tpublic static _getStoreAttributeKey( key: string ): string {\n\t\treturn storePrefix + key;\n\t}\n\n\t/**\n\t * Checks whether the given attribute key is an attribute stored on an element.\n\t *\n\t * @internal\n\t */\n\tpublic static _isStoreAttributeKey( key: string ): boolean {\n\t\treturn key.startsWith( storePrefix );\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentSelection.prototype.is = function( type: string ): boolean {\n\treturn type === 'selection' ||\n\t\ttype == 'model:selection' ||\n\t\ttype == 'documentSelection' ||\n\t\ttype == 'model:documentSelection';\n};\n\n/**\n * Fired when selection range(s) changed.\n *\n * @eventName ~DocumentSelection#change:range\n * @param directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its position\n * was directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n * changed because the structure of the model has been changed (which means an indirect change).\n * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n * which mean that they are not updated once the document changes.\n */\nexport type DocumentSelectionChangeRangeEvent = SelectionChangeRangeEvent;\n\n/**\n * Fired when selection attribute changed.\n *\n * @eventName ~DocumentSelection#change:attribute\n * @param directChange In case of {@link module:engine/model/selection~Selection} class it is always set\n * to `true` which indicates that the selection change was caused by a direct use of selection's API.\n * The {@link module:engine/model/documentselection~DocumentSelection}, however, may change because its attributes\n * were directly changed through the {@link module:engine/model/writer~Writer writer} or because its position was\n * changed in the model and its attributes were refreshed (which means an indirect change).\n * The indirect change does not occur in case of normal (detached) selections because they are \"static\" (as \"not live\")\n * which mean that they are not updated once the document changes.\n * @param attributeKeys Array containing keys of attributes that changed.\n*/\nexport type DocumentSelectionChangeAttributeEvent = SelectionChangeAttributeEvent;\n\n/**\n * Fired when selection marker(s) changed.\n *\n * @eventName ~DocumentSelection#change:marker\n * @param directChange This is always set to `false` in case of `change:marker` event as there is no possibility\n * to change markers directly through {@link module:engine/model/documentselection~DocumentSelection} API.\n * See also {@link module:engine/model/documentselection~DocumentSelection#event:change:range} and\n * {@link module:engine/model/documentselection~DocumentSelection#event:change:attribute}.\n * @param oldMarkers Markers in which the selection was before the change.\n */\nexport type DocumentSelectionChangeMarkerEvent = {\n\tname: 'change:marker';\n\targs: [ {\n\t\tdirectChange: boolean;\n\t\toldMarkers: Array<Marker>;\n\t} ];\n};\n\n/**\n * Fired when selection range(s), attribute(s) or marker(s) changed.\n *\n * @eventName ~DocumentSelection#change\n * @param directChange This is always set to `false` in case of `change:marker` event as there is no possibility\n * to change markers directly through {@link module:engine/model/documentselection~DocumentSelection} API.\n * See also {@link module:engine/model/documentselection~DocumentSelection#event:change:range} and\n * {@link module:engine/model/documentselection~DocumentSelection#event:change:attribute}.\n * @param attributeKeys Array containing keys of attributes that changed.\n * @param oldMarkers Markers in which the selection was before the change.\n */\nexport type DocumentSelectionChangeEvent = {\n\tname: 'change' | 'change:attribute' | 'change:marker' | 'change:range';\n\targs: [ {\n\t\tdirectChange: boolean;\n\t\tattributeKeys?: Array<string>;\n\t\toldMarkers?: Array<Marker>;\n\t} ];\n};\n\n/**\n * `LiveSelection` is used internally by {@link module:engine/model/documentselection~DocumentSelection} and shouldn't be used directly.\n *\n * LiveSelection` is automatically updated upon changes in the {@link module:engine/model/document~Document document}\n * to always contain valid ranges. Its attributes are inherited from the text unless set explicitly.\n *\n * Differences between {@link module:engine/model/selection~Selection} and `LiveSelection` are:\n * * there is always a range in `LiveSelection` - even if no ranges were added there is a \"default range\"\n * present in the selection,\n * * ranges added to this selection updates automatically when the document changes,\n * * attributes of `LiveSelection` are updated automatically according to selection ranges.\n */\nclass LiveSelection extends Selection {\n\t/**\n\t * List of selection markers.\n\t * Marker is a selection marker when selection range is inside the marker range.\n\t */\n\tpublic markers: Collection<Marker> = new Collection( { idProperty: 'name' } );\n\n\t/**\n\t * Document which owns this selection.\n\t */\n\tprivate _model: Model;\n\n\t/**\n\t * Document which owns this selection.\n\t */\n\tprivate _document: Document;\n\n\t/**\n\t * Stores selection ranges.\n\t *\n\t * @internal\n\t */\n\tpublic declare _ranges: Array<LiveRange>;\n\n\t/**\n\t * Keeps mapping of attribute name to priority with which the attribute got modified (added/changed/removed)\n\t * last time. Possible values of priority are: `'low'` and `'normal'`.\n\t *\n\t * Priorities are used by internal `LiveSelection` mechanisms. All attributes set using `LiveSelection`\n\t * attributes API are set with `'normal'` priority.\n\t */\n\tprivate _attributePriority: Map<string, 'low' | 'normal'> = new Map();\n\n\t/**\n\t * Position to which the selection should be set if the last selection range was moved to the graveyard.\n\t */\n\tprivate _selectionRestorePosition: Position | null = null;\n\n\t/**\n\t * Flag that informs whether the selection ranges have changed. It is changed on true when `LiveRange#change:range` event is fired.\n\t */\n\tprivate _hasChangedRange: boolean = false;\n\n\t/**\n\t * Each overriding gravity adds an UID to the set and each removal removes it.\n\t * Gravity is overridden when there's at least one UID in the set.\n\t * Gravity is restored when the set is empty.\n\t * This is to prevent conflicts when gravity is overridden by more than one feature at the same time.\n\t */\n\tprivate _overriddenGravityRegister: Set<string> = new Set();\n\n\t/**\n\t * Prefixes of marker names that should affect `LiveSelection#markers` collection.\n\t */\n\tprivate _observedMarkers: Set<string> = new Set();\n\n\t/**\n\t * Creates an empty live selection for given {@link module:engine/model/document~Document}.\n\t *\n\t * @param doc Document which owns this selection.\n\t */\n\tconstructor( doc: Document ) {\n\t\tsuper();\n\n\t\tthis._model = doc.model;\n\t\tthis._document = doc;\n\n\t\t// Ensure selection is correct after each operation.\n\t\tthis.listenTo<ModelApplyOperationEvent>( this._model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( !operation.isDocumentOperation || operation.type == 'marker' || operation.type == 'rename' || operation.type == 'noop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Fix selection if the last range was removed from it and we have a position to which we can restore the selection.\n\t\t\tif ( this._ranges.length == 0 && this._selectionRestorePosition ) {\n\t\t\t\tthis._fixGraveyardSelection( this._selectionRestorePosition );\n\t\t\t}\n\n\t\t\t// \"Forget\" the restore position even if it was not \"used\".\n\t\t\tthis._selectionRestorePosition = null;\n\n\t\t\tif ( this._hasChangedRange ) {\n\t\t\t\tthis._hasChangedRange = false;\n\t\t\t\tthis.fire<DocumentSelectionChangeRangeEvent>( 'change:range', { directChange: false } );\n\t\t\t}\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Ensure selection is correct and up to date after each range change.\n\t\tthis.on<DocumentSelectionChangeRangeEvent>( 'change:range', () => {\n\t\t\tthis._validateSelectionRanges( this.getRanges() );\n\t\t} );\n\n\t\t// Update markers data stored by the selection after each marker change.\n\t\t// This handles only marker changes done through marker operations (not model tree changes).\n\t\tthis.listenTo<MarkerCollectionUpdateEvent>( this._model.markers, 'update', ( evt, marker, oldRange, newRange ) => {\n\t\t\tthis._updateMarker( marker, newRange );\n\t\t} );\n\n\t\t// Ensure selection is up to date after each change block.\n\t\tthis.listenTo<DocumentChangeEvent>( this._document, 'change', ( evt, batch ) => {\n\t\t\tclearAttributesStoredInElement( this._model, batch );\n\t\t} );\n\t}\n\n\tpublic override get isCollapsed(): boolean {\n\t\tconst length = this._ranges.length;\n\n\t\treturn length === 0 ? this._document._getDefaultRange().isCollapsed : super.isCollapsed;\n\t}\n\n\tpublic override get anchor(): Position {\n\t\treturn super.anchor || this._document._getDefaultRange().start;\n\t}\n\n\tpublic override get focus(): Position {\n\t\treturn super.focus || this._document._getDefaultRange().end;\n\t}\n\n\tpublic override get rangeCount(): number {\n\t\treturn this._ranges.length ? this._ranges.length : 1;\n\t}\n\n\t/**\n\t * Describes whether `LiveSelection` has own range(s) set, or if it is defaulted to\n\t * {@link module:engine/model/document~Document#_getDefaultRange document's default range}.\n\t */\n\tpublic get hasOwnRange(): boolean {\n\t\treturn this._ranges.length > 0;\n\t}\n\n\t/**\n\t * When set to `true` then selection attributes on node before the caret won't be taken\n\t * into consideration while updating selection attributes.\n\t */\n\tpublic get isGravityOverridden(): boolean {\n\t\treturn !!this._overriddenGravityRegister.size;\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by live selection.\n\t */\n\tpublic destroy(): void {\n\t\tfor ( let i = 0; i < this._ranges.length; i++ ) {\n\t\t\tthis._ranges[ i ].detach();\n\t\t}\n\n\t\tthis.stopListening();\n\t}\n\n\tpublic override* getRanges(): IterableIterator<Range> {\n\t\tif ( this._ranges.length ) {\n\t\t\tyield* super.getRanges();\n\t\t} else {\n\t\t\tyield this._document._getDefaultRange();\n\t\t}\n\t}\n\n\tpublic override getFirstRange(): Range {\n\t\treturn super.getFirstRange() || this._document._getDefaultRange();\n\t}\n\n\tpublic override getLastRange(): Range {\n\t\treturn super.getLastRange() || this._document._getDefaultRange();\n\t}\n\n\tpublic override setTo( ...args: Parameters<Selection[ 'setTo' ]> ) {\n\t\tsuper.setTo( ...args );\n\t\tthis._updateAttributes( true );\n\t\tthis.updateMarkers();\n\t}\n\n\tpublic override setFocus( itemOrPosition: Item | Position, offset?: PositionOffset ): void {\n\t\tsuper.setFocus( itemOrPosition, offset );\n\t\tthis._updateAttributes( true );\n\t\tthis.updateMarkers();\n\t}\n\n\tpublic override setAttribute( key: string, value: unknown ): void {\n\t\tif ( this._setAttribute( key, value ) ) {\n\t\t\t// Fire event with exact data.\n\t\t\tconst attributeKeys = [ key ];\n\t\t\tthis.fire<DocumentSelectionChangeAttributeEvent>( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\n\tpublic override removeAttribute( key: string ): void {\n\t\tif ( this._removeAttribute( key ) ) {\n\t\t\t// Fire event with exact data.\n\t\t\tconst attributeKeys = [ key ];\n\t\t\tthis.fire<DocumentSelectionChangeAttributeEvent>( 'change:attribute', { attributeKeys, directChange: true } );\n\t\t}\n\t}\n\n\tpublic overrideGravity(): string {\n\t\tconst overrideUid = uid();\n\n\t\t// Remember that another overriding has been requested. It will need to be removed\n\t\t// before the gravity is to be restored.\n\t\tthis._overriddenGravityRegister.add( overrideUid );\n\n\t\tif ( this._overriddenGravityRegister.size === 1 ) {\n\t\t\tthis._updateAttributes( true );\n\t\t}\n\n\t\treturn overrideUid;\n\t}\n\n\tpublic restoreGravity( uid: string ): void {\n\t\tif ( !this._overriddenGravityRegister.has( uid ) ) {\n\t\t\t/**\n\t\t\t * Restoring gravity for an unknown UID is not possible. Make sure you are using a correct\n\t\t\t * UID obtained from the {@link module:engine/model/writer~Writer#overrideSelectionGravity} to restore.\n\t\t\t *\n\t\t\t * @error document-selection-gravity-wrong-restore\n\t\t\t * @param uid The unique identifier returned by\n\t\t\t * {@link module:engine/model/documentselection~DocumentSelection#_overrideGravity}.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'document-selection-gravity-wrong-restore',\n\t\t\t\tthis,\n\t\t\t\t{ uid }\n\t\t\t);\n\t\t}\n\n\t\tthis._overriddenGravityRegister.delete( uid );\n\n\t\t// Restore gravity only when all overriding have been restored.\n\t\tif ( !this.isGravityOverridden ) {\n\t\t\tthis._updateAttributes( true );\n\t\t}\n\t}\n\n\tpublic observeMarkers( prefixOrName: string ): void {\n\t\tthis._observedMarkers.add( prefixOrName );\n\t\tthis.updateMarkers();\n\t}\n\n\tprotected override _replaceAllRanges( ranges: Array<Range> ): void {\n\t\tthis._validateSelectionRanges( ranges );\n\n\t\tsuper._replaceAllRanges( ranges );\n\t}\n\n\tprotected override _popRange(): void {\n\t\tthis._ranges.pop()!.detach();\n\t}\n\n\tprotected override _pushRange( range: Range ): void {\n\t\tconst liveRange = this._prepareRange( range );\n\n\t\t// `undefined` is returned when given `range` is in graveyard root.\n\t\tif ( liveRange ) {\n\t\t\tthis._ranges.push( liveRange );\n\t\t}\n\t}\n\n\tprivate _validateSelectionRanges( ranges: Iterable<Range> ) {\n\t\tfor ( const range of ranges ) {\n\t\t\tif ( !this._document._validateSelectionRange( range ) ) {\n\t\t\t\t/**\n\t\t\t\t * Range from {@link module:engine/model/documentselection~DocumentSelection document selection}\n\t\t\t\t * starts or ends at incorrect position.\n\t\t\t\t *\n\t\t\t\t * @error document-selection-wrong-position\n\t\t\t\t * @param range\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'document-selection-wrong-position',\n\t\t\t\t\tthis,\n\t\t\t\t\t{ range }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Prepares given range to be added to selection. Checks if it is correct,\n\t * converts it to {@link module:engine/model/liverange~LiveRange LiveRange}\n\t * and sets listeners listening to the range's change event.\n\t */\n\tprivate _prepareRange( range: Range ): LiveRange | undefined {\n\t\tthis._checkRange( range );\n\n\t\tif ( range.root == this._document.graveyard ) {\n\t\t\t// @if CK_DEBUG // console.warn( 'Trying to add a Range that is in the graveyard root. Range rejected.' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst liveRange = LiveRange.fromRange( range );\n\n\t\t// If selection range is moved to the graveyard remove it from the selection object.\n\t\t// Also, save some data that can be used to restore selection later, on `Model#applyOperation` event.\n\t\tliveRange.on( 'change:range', ( evt, oldRange, data ) => {\n\t\t\tthis._hasChangedRange = true;\n\n\t\t\tif ( liveRange.root == this._document.graveyard ) {\n\t\t\t\tthis._selectionRestorePosition = data.deletionPosition;\n\n\t\t\t\tconst index = this._ranges.indexOf( liveRange );\n\t\t\t\tthis._ranges.splice( index, 1 );\n\t\t\t\tliveRange.detach();\n\t\t\t}\n\t\t} );\n\n\t\treturn liveRange;\n\t}\n\n\tpublic updateMarkers(): void {\n\t\tif ( !this._observedMarkers.size ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst markers = [];\n\t\tlet changed = false;\n\n\t\tfor ( const marker of this._model.markers ) {\n\t\t\tconst markerGroup = marker.name.split( ':', 1 )[ 0 ];\n\n\t\t\tif ( !this._observedMarkers.has( markerGroup ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst markerRange = marker.getRange();\n\n\t\t\tfor ( const selectionRange of this.getRanges() ) {\n\t\t\t\tif ( markerRange.containsRange( selectionRange, !selectionRange.isCollapsed ) ) {\n\t\t\t\t\tmarkers.push( marker );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst oldMarkers = Array.from( this.markers );\n\n\t\tfor ( const marker of markers ) {\n\t\t\tif ( !this.markers.has( marker ) ) {\n\t\t\t\tthis.markers.add( marker );\n\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\tfor ( const marker of Array.from( this.markers ) ) {\n\t\t\tif ( !markers.includes( marker ) ) {\n\t\t\t\tthis.markers.remove( marker );\n\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\tif ( changed ) {\n\t\t\tthis.fire<DocumentSelectionChangeMarkerEvent>( 'change:marker', { oldMarkers, directChange: false } );\n\t\t}\n\t}\n\n\tprivate _updateMarker( marker: Marker, markerRange: Range | null ): void {\n\t\tconst markerGroup = marker.name.split( ':', 1 )[ 0 ];\n\n\t\tif ( !this._observedMarkers.has( markerGroup ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet changed = false;\n\n\t\tconst oldMarkers = Array.from( this.markers );\n\t\tconst hasMarker = this.markers.has( marker );\n\n\t\tif ( !markerRange ) {\n\t\t\tif ( hasMarker ) {\n\t\t\t\tthis.markers.remove( marker );\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t} else {\n\t\t\tlet contained = false;\n\n\t\t\tfor ( const selectionRange of this.getRanges() ) {\n\t\t\t\tif ( markerRange.containsRange( selectionRange, !selectionRange.isCollapsed ) ) {\n\t\t\t\t\tcontained = true;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( contained && !hasMarker ) {\n\t\t\t\tthis.markers.add( marker );\n\n\t\t\t\tchanged = true;\n\t\t\t} else if ( !contained && hasMarker ) {\n\t\t\t\tthis.markers.remove( marker );\n\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\tif ( changed ) {\n\t\t\tthis.fire<DocumentSelectionChangeMarkerEvent>( 'change:marker', { oldMarkers, directChange: false } );\n\t\t}\n\t}\n\n\t/**\n\t * Updates this selection attributes according to its ranges and the {@link module:engine/model/document~Document model document}.\n\t */\n\tpublic _updateAttributes( clearAll: boolean ): void {\n\t\tconst newAttributes = toMap( this._getSurroundingAttributes() );\n\t\tconst oldAttributes = toMap( this.getAttributes() );\n\n\t\tif ( clearAll ) {\n\t\t\t// If `clearAll` remove all attributes and reset priorities.\n\t\t\tthis._attributePriority = new Map();\n\t\t\tthis._attrs = new Map();\n\t\t} else {\n\t\t\t// If not, remove only attributes added with `low` priority.\n\t\t\tfor ( const [ key, priority ] of this._attributePriority ) {\n\t\t\t\tif ( priority == 'low' ) {\n\t\t\t\t\tthis._attrs.delete( key );\n\t\t\t\t\tthis._attributePriority.delete( key );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._setAttributesTo( newAttributes );\n\n\t\t// Let's evaluate which attributes really changed.\n\t\tconst changed = [];\n\n\t\t// First, loop through all attributes that are set on selection right now.\n\t\t// Check which of them are different than old attributes.\n\t\tfor ( const [ newKey, newValue ] of this.getAttributes() ) {\n\t\t\tif ( !oldAttributes.has( newKey ) || oldAttributes.get( newKey ) !== newValue ) {\n\t\t\t\tchanged.push( newKey );\n\t\t\t}\n\t\t}\n\n\t\t// Then, check which of old attributes got removed.\n\t\tfor ( const [ oldKey ] of oldAttributes ) {\n\t\t\tif ( !this.hasAttribute( oldKey ) ) {\n\t\t\t\tchanged.push( oldKey );\n\t\t\t}\n\t\t}\n\n\t\t// Fire event with exact data (fire only if anything changed).\n\t\tif ( changed.length > 0 ) {\n\t\t\tthis.fire<DocumentSelectionChangeAttributeEvent>( 'change:attribute', { attributeKeys: changed, directChange: false } );\n\t\t}\n\t}\n\n\t/**\n\t * Internal method for setting `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t * parameter).\n\t */\n\tprivate _setAttribute( key: string, value: unknown, directChange: boolean = true ): boolean {\n\t\tconst priority = directChange ? 'normal' : 'low';\n\n\t\tif ( priority == 'low' && this._attributePriority.get( key ) == 'normal' ) {\n\t\t\t// Priority too low.\n\t\t\treturn false;\n\t\t}\n\n\t\tconst oldValue = super.getAttribute( key );\n\n\t\t// Don't do anything if value has not changed.\n\t\tif ( oldValue === value ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis._attrs.set( key, value );\n\n\t\t// Update priorities map.\n\t\tthis._attributePriority.set( key, priority );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Internal method for removing `LiveSelection` attribute. Supports attribute priorities (through `directChange`\n\t * parameter).\n\t *\n\t * NOTE: Even if attribute is not present in the selection but is provided to this method, it's priority will\n\t * be changed according to `directChange` parameter.\n\t */\n\tprivate _removeAttribute( key: string, directChange: boolean = true ): boolean {\n\t\tconst priority = directChange ? 'normal' : 'low';\n\n\t\tif ( priority == 'low' && this._attributePriority.get( key ) == 'normal' ) {\n\t\t\t// Priority too low.\n\t\t\treturn false;\n\t\t}\n\n\t\t// Update priorities map.\n\t\tthis._attributePriority.set( key, priority );\n\n\t\t// Don't do anything if value has not changed.\n\t\tif ( !super.hasAttribute( key ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis._attrs.delete( key );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Internal method for setting multiple `LiveSelection` attributes. Supports attribute priorities (through\n\t * `directChange` parameter).\n\t */\n\tprivate _setAttributesTo( attrs: Map<string, unknown> ): Set<string> {\n\t\tconst changed = new Set<string>();\n\n\t\tfor ( const [ oldKey, oldValue ] of this.getAttributes() ) {\n\t\t\t// Do not remove attribute if attribute with same key and value is about to be set.\n\t\t\tif ( attrs.get( oldKey ) === oldValue ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// All rest attributes will be removed so changed attributes won't change .\n\t\t\tthis._removeAttribute( oldKey, false );\n\t\t}\n\n\t\tfor ( const [ key, value ] of attrs ) {\n\t\t\t// Attribute may not be set because of attributes or because same key/value is already added.\n\t\t\tconst gotAdded = this._setAttribute( key, value, false );\n\n\t\t\tif ( gotAdded ) {\n\t\t\t\tchanged.add( key );\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t}\n\n\t/**\n\t * Returns an iterable that iterates through all selection attributes stored in current selection's parent.\n\t */\n\tpublic* getStoredAttributes(): IterableIterator<[ string, unknown ]> {\n\t\tconst selectionParent = this.getFirstPosition()!.parent as Element;\n\n\t\tif ( this.isCollapsed && selectionParent.isEmpty ) {\n\t\t\tfor ( const key of selectionParent.getAttributeKeys() ) {\n\t\t\t\tif ( key.startsWith( storePrefix ) ) {\n\t\t\t\t\tconst realKey = key.substr( storePrefix.length );\n\n\t\t\t\t\tyield [ realKey, selectionParent.getAttribute( key ) ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks model text nodes that are closest to the selection's first position and returns attributes of first\n\t * found element. If there are no text nodes in selection's first position parent, it returns selection\n\t * attributes stored in that parent.\n\t */\n\tprivate _getSurroundingAttributes(): Iterable<[ string, unknown ]> | null {\n\t\tconst position = this.getFirstPosition()!;\n\t\tconst schema = this._model.schema;\n\n\t\tif ( position.root.rootName == '$graveyard' ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet attrs = null;\n\n\t\tif ( !this.isCollapsed ) {\n\t\t\t// 1. If selection is a range...\n\t\t\tconst range = this.getFirstRange();\n\n\t\t\t// ...look for a first character node in that range and take attributes from it.\n\t\t\tfor ( const value of range ) {\n\t\t\t\t// If the item is an object, we don't want to get attributes from its children...\n\t\t\t\tif ( value.item.is( 'element' ) && schema.isObject( value.item ) ) {\n\t\t\t\t\t// ...but collect attributes from inline object.\n\t\t\t\t\tattrs = getTextAttributes( value.item, schema );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( value.type == 'text' ) {\n\t\t\t\t\tattrs = value.item.getAttributes();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// 2. If the selection is a caret or the range does not contain a character node...\n\n\t\t\tconst nodeBefore = position.textNode ? position.textNode : position.nodeBefore;\n\t\t\tconst nodeAfter = position.textNode ? position.textNode : position.nodeAfter;\n\n\t\t\t// When gravity is overridden then don't take node before into consideration.\n\t\t\tif ( !this.isGravityOverridden ) {\n\t\t\t\t// ...look at the node before caret and take attributes from it if it is a character node.\n\t\t\t\tattrs = getTextAttributes( nodeBefore, schema );\n\t\t\t}\n\n\t\t\t// 3. If not, look at the node after caret...\n\t\t\tif ( !attrs ) {\n\t\t\t\tattrs = getTextAttributes( nodeAfter, schema );\n\t\t\t}\n\n\t\t\t// 4. If not, try to find the first character on the left, that is in the same node.\n\t\t\t// When gravity is overridden then don't take node before into consideration.\n\t\t\tif ( !this.isGravityOverridden && !attrs ) {\n\t\t\t\tlet node = nodeBefore;\n\n\t\t\t\twhile ( node && !attrs ) {\n\t\t\t\t\tnode = node.previousSibling;\n\t\t\t\t\tattrs = getTextAttributes( node, schema );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 5. If not found, try to find the first character on the right, that is in the same node.\n\t\t\tif ( !attrs ) {\n\t\t\t\tlet node = nodeAfter;\n\n\t\t\t\twhile ( node && !attrs ) {\n\t\t\t\t\tnode = node.nextSibling;\n\t\t\t\t\tattrs = getTextAttributes( node, schema );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 6. If not found, selection should retrieve attributes from parent.\n\t\t\tif ( !attrs ) {\n\t\t\t\tattrs = this.getStoredAttributes();\n\t\t\t}\n\t\t}\n\n\t\treturn attrs;\n\t}\n\n\t/**\n\t * Fixes the selection after all its ranges got removed.\n\t * @param deletionPosition Position where the deletion happened.\n\t */\n\tprivate _fixGraveyardSelection( deletionPosition: Position ): void {\n\t\t// Find a range that is a correct selection range and is closest to the position where the deletion happened.\n\t\tconst selectionRange = this._model.schema.getNearestSelectionRange( deletionPosition );\n\n\t\t// If nearest valid selection range has been found - add it in the place of old range.\n\t\tif ( selectionRange ) {\n\t\t\t// Check the range, convert it to live range, bind events, etc.\n\t\t\tthis._pushRange( selectionRange );\n\t\t}\n\t\t// If nearest valid selection range cannot be found don't add any range. Selection will be set to the default range.\n\t}\n}\n\n/**\n * Helper function for {@link module:engine/model/liveselection~LiveSelection#_updateAttributes}.\n *\n * It checks if the passed model item is a text node (or text proxy) and, if so, returns it's attributes.\n * If not, it checks if item is an inline object and does the same. Otherwise it returns `null`.\n */\nfunction getTextAttributes( node: Item | null, schema: Schema ): Iterable<[string, unknown]> | null {\n\tif ( !node ) {\n\t\treturn null;\n\t}\n\n\tif ( node instanceof TextProxy || node instanceof Text ) {\n\t\treturn node.getAttributes();\n\t}\n\n\tif ( !schema.isInline( node ) ) {\n\t\treturn null;\n\t}\n\n\t// Stop on inline elements (such as `<softBreak>`) that are not objects (such as `<imageInline>` or `<mathml>`).\n\tif ( !schema.isObject( node ) ) {\n\t\treturn [];\n\t}\n\n\tconst attributes: Array<[string, unknown]> = [];\n\n\t// Collect all attributes that can be applied to the text node.\n\tfor ( const [ key, value ] of node.getAttributes() ) {\n\t\tif (\n\t\t\tschema.checkAttribute( '$text', key ) &&\n\t\t\tschema.getAttributeProperties( key ).copyFromObject !== false\n\t\t) {\n\t\t\tattributes.push( [ key, value ] );\n\t\t}\n\t}\n\n\treturn attributes;\n}\n\n/**\n * Removes selection attributes from element which is not empty anymore.\n */\nfunction clearAttributesStoredInElement( model: Model, batch: Batch ) {\n\tconst differ = model.document.differ;\n\n\tfor ( const entry of differ.getChanges() ) {\n\t\tif ( entry.type != 'insert' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst changeParent = entry.position.parent as Element;\n\t\tconst isNoLongerEmpty = entry.length === changeParent.maxOffset;\n\n\t\tif ( isNoLongerEmpty ) {\n\t\t\tmodel.enqueueChange( batch, writer => {\n\t\t\t\tconst storedAttributes = Array.from( changeParent.getAttributeKeys() )\n\t\t\t\t\t.filter( key => key.startsWith( storePrefix ) );\n\n\t\t\t\tfor ( const key of storedAttributes ) {\n\t\t\t\t\twriter.removeAttribute( key, changeParent );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/conversion/conversionhelpers\n */\n\n/**\n * Base class for conversion helpers.\n */\nexport default class ConversionHelpers<TDispatcher> {\n\tprivate readonly _dispatchers: Array<TDispatcher>;\n\n\t/**\n\t * Creates a conversion helpers instance.\n\t */\n\tconstructor( dispatchers: Array<TDispatcher> ) {\n\t\tthis._dispatchers = dispatchers;\n\t}\n\n\t/**\n\t * Registers a conversion helper.\n\t *\n\t * **Note**: See full usage example in the `{@link module:engine/conversion/conversion~Conversion#for conversion.for()}`\n\t * method description.\n\t *\n\t * @param conversionHelper The function to be called on event.\n\t */\n\tpublic add( conversionHelper: ( dispatcher: TDispatcher ) => void ): this {\n\t\tfor ( const dispatcher of this._dispatchers ) {\n\t\t\tconversionHelper( dispatcher );\n\t\t}\n\n\t\treturn this;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * Contains downcast (model-to-view) converters for {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}.\n *\n * @module engine/conversion/downcasthelpers\n */\n\nimport ModelRange from '../model/range.js';\nimport ModelSelection from '../model/selection.js';\nimport ModelDocumentSelection from '../model/documentselection.js';\nimport ModelElement from '../model/element.js';\nimport ModelPosition from '../model/position.js';\n\nimport ViewAttributeElement from '../view/attributeelement.js';\nimport ConversionHelpers from './conversionhelpers.js';\n\nimport type {\n\tdefault as DowncastDispatcher,\n\tDiffItemReinsert,\n\tDowncastConversionApi,\n\tDowncastInsertEvent,\n\tDowncastAddMarkerEvent,\n\tDowncastAttributeEvent,\n\tDowncastReduceChangesEvent,\n\tDowncastRemoveMarkerEvent\n} from './downcastdispatcher.js';\nimport type ModelConsumable from './modelconsumable.js';\nimport type { DiffItem } from '../model/differ.js';\nimport type ModelNode from '../model/node.js';\nimport type ModelItem from '../model/item.js';\nimport type ModelTextProxy from '../model/textproxy.js';\nimport type ModelText from '../model/text.js';\n\nimport type DowncastWriter from '../view/downcastwriter.js';\nimport type ElementDefinition from '../view/elementdefinition.js';\nimport type ViewDocumentFragment from '../view/documentfragment.js';\nimport type UIElement from '../view/uielement.js';\nimport type ViewElement from '../view/element.js';\nimport type ViewNode from '../view/node.js';\nimport type ViewPosition from '../view/position.js';\nimport type ViewRange from '../view/range.js';\nimport StylesMap from '../view/stylesmap.js';\nimport type {\n\tdefault as Mapper,\n\tMapperModelToViewPositionEvent\n} from './mapper.js';\n\nimport {\n\tCKEditorError,\n\ttoArray,\n\ttype ArrayOrItem,\n\ttype EventInfo,\n\ttype PriorityString\n} from '@ckeditor/ckeditor5-utils';\n\nimport { cloneDeep } from 'lodash-es';\n\n/**\n * Downcast conversion helper functions.\n *\n * Learn more about {@glink framework/deep-dive/conversion/downcast downcast helpers}.\n *\n * @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n */\nexport default class DowncastHelpers extends ConversionHelpers<DowncastDispatcher> {\n\t/**\n\t * Model element to view element conversion helper.\n\t *\n\t * This conversion results in creating a view element. For example, model `<paragraph>Foo</paragraph>` becomes `<p>Foo</p>` in the view.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'paragraph',\n\t * \tview: 'p'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'paragraph',\n\t * \tview: 'div',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'fancyParagraph',\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'fancy'\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: 'heading',\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * The element-to-element conversion supports the reconversion mechanism. It can be enabled by using either the `attributes` or\n\t * the `children` props on a model description. You will find a couple examples below.\n\t *\n\t * In order to reconvert an element if any of its direct children have been added or removed, use the `children` property on a `model`\n\t * description. For example, this model:\n\t *\n\t * ```xml\n\t * <box>\n\t * \t<paragraph>Some text.</paragraph>\n\t * </box>\n\t * ```\n\t *\n\t * will be converted into this structure in the view:\n\t *\n\t * ```html\n\t * <div class=\"box\" data-type=\"single\">\n\t * \t<p>Some text.</p>\n\t * </div>\n\t * ```\n\t *\n\t * But if more items were inserted in the model:\n\t *\n\t * ```xml\n\t * <box>\n\t * \t<paragraph>Some text.</paragraph>\n\t * \t<paragraph>Other item.</paragraph>\n\t * </box>\n\t * ```\n\t *\n\t * it will be converted into this structure in the view (note the element `data-type` change):\n\t *\n\t * ```html\n\t * <div class=\"box\" data-type=\"multiple\">\n\t * \t<p>Some text.</p>\n\t * \t<p>Other item.</p>\n\t * </div>\n\t * ```\n\t *\n\t * Such a converter would look like this (note that the `paragraph` elements are converted separately):\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: {\n\t * \t\tname: 'box',\n\t * \t\tchildren: true\n\t * \t},\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createContainerElement( 'div', {\n\t * \t\t\tclass: 'box',\n\t * \t\t\t'data-type': modelElement.childCount == 1 ? 'single' : 'multiple'\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * In order to reconvert element if any of its attributes have been updated, use the `attributes` property on a `model`\n\t * description. For example, this model:\n\t *\n\t * ```xml\n\t * <heading level=\"2\">Some text.</heading>\n\t * ```\n\t *\n\t * will be converted into this structure in the view:\n\t *\n\t * ```html\n\t * <h2>Some text.</h2>\n\t * ```\n\t *\n\t * But if the `heading` element's `level` attribute has been updated to `3` for example, then\n\t * it will be converted into this structure in the view:\n\t *\n\t * ```html\n\t * <h3>Some text.</h3>\n\t * ```\n\t *\n\t * Such a converter would look as follows:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t * \tmodel: {\n\t * \t\tname: 'heading',\n\t * \t\tattributes: 'level'\n\t * \t},\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * You can read more about the element-to-element conversion in the\n\t * {@glink framework/deep-dive/conversion/downcast downcast conversion} guide.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The description or a name of the model element to convert.\n\t * @param config.model.attributes The list of attribute names that should be consumed while creating\n\t * the view element. Note that the view will be reconverted if any of the listed attributes changes.\n \t * @param config.model.children Specifies whether the view element requires reconversion if the list\n\t * of the model child nodes changed.\n\t * @param config.view A view element definition or a function that takes the model element and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as parameters and returns a view container element.\n\t */\n\tpublic elementToElement( config: {\n\t\tmodel: string | {\n\t\t\tname: string;\n\t\t\tattributes?: string | Array<string>;\n\t\t\tchildren?: boolean;\n\t\t};\n\t\tview: ElementDefinition | ElementCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( downcastElementToElement( config ) );\n\t}\n\n\t/**\n\t * The model element to view structure (several elements) conversion helper.\n\t *\n\t * This conversion results in creating a view structure with one or more slots defined for the child nodes.\n\t * For example, a model `<table>` may become this structure in the view:\n\t *\n\t * ```html\n\t * <figure class=\"table\">\n\t * \t<table>\n\t * \t\t<tbody>${ slot for table rows }</tbody>\n\t * \t</table>\n\t * </figure>\n\t * ```\n\t *\n\t * The children of the model's `<table>` element will be inserted into the `<tbody>` element.\n\t * If the `elementToElement()` helper was used, the children would be inserted into the `<figure>`.\n\t *\n\t * Imagine a table feature where for this model structure:\n\t *\n\t * ```xml\n\t * <table headingRows=\"1\">\n\t * \t<tableRow> ... table cells 1 ... </tableRow>\n\t * \t<tableRow> ... table cells 2 ... </tableRow>\n\t * \t<tableRow> ... table cells 3 ... </tableRow>\n\t * \t<caption>Caption text</caption>\n\t * </table>\n\t * ```\n\t *\n\t * we want to generate this view structure:\n\t *\n\t * ```html\n\t * <figure class=\"table\">\n\t * \t<table>\n\t * \t\t<thead>\n\t * \t\t\t<tr> ... table cells 1 ... </tr>\n\t * \t\t</thead>\n\t * \t\t<tbody>\n\t * \t\t\t<tr> ... table cells 2 ... </tr>\n\t * \t\t\t<tr> ... table cells 3 ... </tr>\n\t * \t\t</tbody>\n\t * \t</table>\n\t * \t<figcaption>Caption text</figcaption>\n\t * </figure>\n\t * ```\n\t *\n\t * The converter has to take the `headingRows` attribute into consideration when allocating the `<tableRow>` elements\n\t * into the `<tbody>` and `<thead>` elements. Hence, we need two slots and need to define proper filter callbacks for them.\n\t *\n\t * Additionally, all elements other than `<tableRow>` should be placed outside the `<table>` tag.\n\t * In the example above, this will handle the table caption.\n\t *\n\t * Such a converter would look like this:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).elementToStructure( {\n\t * \tmodel: {\n\t * \t\tname: 'table',\n\t * \t\tattributes: [ 'headingRows' ]\n\t * \t},\n\t * \tview: ( modelElement, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\tconst figureElement = writer.createContainerElement( 'figure', { class: 'table' } );\n\t * \t\tconst tableElement = writer.createContainerElement( 'table' );\n\t *\n\t * \t\twriter.insert( writer.createPositionAt( figureElement, 0 ), tableElement );\n\t *\n\t * \t\tconst headingRows = modelElement.getAttribute( 'headingRows' ) || 0;\n\t *\n\t * \t\tif ( headingRows > 0 ) {\n\t * \t\t\tconst tableHead = writer.createContainerElement( 'thead' );\n\t *\n\t * \t\t\tconst headSlot = writer.createSlot( node => node.is( 'element', 'tableRow' ) && node.index < headingRows );\n\t *\n\t * \t\t\twriter.insert( writer.createPositionAt( tableElement, 'end' ), tableHead );\n\t * \t\t\twriter.insert( writer.createPositionAt( tableHead, 0 ), headSlot );\n\t * \t\t}\n\t *\n\t * \t\tif ( headingRows < tableUtils.getRows( table ) ) {\n\t * \t\t\tconst tableBody = writer.createContainerElement( 'tbody' );\n\t *\n\t * \t\t\tconst bodySlot = writer.createSlot( node => node.is( 'element', 'tableRow' ) && node.index >= headingRows );\n\t *\n\t * \t\t\twriter.insert( writer.createPositionAt( tableElement, 'end' ), tableBody );\n\t * \t\t\twriter.insert( writer.createPositionAt( tableBody, 0 ), bodySlot );\n\t * \t\t}\n\t *\n\t * \t\tconst restSlot = writer.createSlot( node => !node.is( 'element', 'tableRow' ) );\n\t *\n\t * \t\twriter.insert( writer.createPositionAt( figureElement, 'end' ), restSlot );\n\t *\n\t * \t\treturn figureElement;\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Note: The children of a model element that's being converted must be allocated in the same order in the view\n\t * in which they are placed in the model.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n \t * @param config.model The description or a name of the model element to convert.\n\t * @param config.model.name The name of the model element to convert.\n \t * @param config.model.attributes The list of attribute names that should be consumed while creating\n\t * the view structure. Note that the view will be reconverted if any of the listed attributes will change.\n\t * @param config.view A function that takes the model element and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters\n\t * and returns a view container element with slots for model child nodes to be converted into.\n\t */\n\tpublic elementToStructure( config: {\n\t\tmodel: string | {\n\t\t\tname: string;\n\t\t\tattributes?: string | Array<string>;\n\t\t};\n\t\tview: StructureCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( downcastElementToStructure( config ) );\n\t}\n\n\t/**\n\t * Model attribute to view element conversion helper.\n\t *\n\t * This conversion results in wrapping view nodes with a view attribute element. For example, a model text node with\n\t * `\"Foo\"` as data and the `bold` attribute becomes `<strong>Foo</strong>` in the view.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: 'strong'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: 'b',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'invert',\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: [ 'font-light', 'bg-dark' ]\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'fontSize',\n\t * \t\tvalues: [ 'big', 'small' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tbig: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '1.2em'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tsmall: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '0.8em'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: ( modelAttributeValue, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createAttributeElement( 'span', {\n\t * \t\t\tstyle: 'font-weight:' + modelAttributeValue\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'color',\n\t * \t\tname: '$text'\n\t * \t},\n\t * \tview: ( modelAttributeValue, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createAttributeElement( 'span', {\n\t * \t\t\tstyle: 'color:' + modelAttributeValue\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n\t * of `String`s with possible values if the model attribute is an enumerable.\n\t * @param config.view A view element definition or a function\n\t * that takes the model attribute value and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters and returns a view\n\t * attribute element. If `config.model.values` is given, `config.view` should be an object assigning values from `config.model.values`\n\t * to view element definitions or functions.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic attributeToElement<TValues extends string>(\n\t\tconfig: {\n\t\t\tmodel: string | {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t};\n\t\t\tview: ElementDefinition | AttributeElementCreatorFunction;\n\t\t\tconverterPriority?: PriorityString;\n\t\t} | {\n\t\t\tmodel: {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t\tvalues: Array<TValues>;\n\t\t\t};\n\t\t\tview: Record<TValues, ElementDefinition | AttributeElementCreatorFunction>;\n\t\t\tconverterPriority?: PriorityString;\n\t\t}\n\t): this {\n\t\treturn this.add( downcastAttributeToElement( config ) );\n\t}\n\n\t/**\n\t * Model attribute to view attribute conversion helper.\n\t *\n\t * This conversion results in adding an attribute to a view node, basing on an attribute from a model node. For example,\n\t * `<imageInline src='foo.jpg'></imageInline>` is converted to `<img src='foo.jpg'></img>`.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'source',\n\t * \tview: 'src'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'source',\n\t * \tview: 'href',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'imageInline',\n\t * \t\tkey: 'source'\n\t * \t},\n\t * \tview: 'src'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'styled',\n\t * \t\tvalues: [ 'dark', 'light' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tdark: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: [ 'styled', 'styled-dark' ]\n\t * \t\t},\n\t * \t\tlight: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: [ 'styled', 'styled-light' ]\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'styled',\n\t * \tview: modelAttributeValue => ( {\n\t * \t\tkey: 'class',\n\t * \t\tvalue: 'styled-' + modelAttributeValue\n\t * \t} )\n\t * } );\n\t * ```\n\t *\n\t * **Note**: Downcasting to a style property requires providing `value` as an object:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t * \tmodel: 'lineHeight',\n\t * \tview: modelAttributeValue => ( {\n\t * \t\tkey: 'style',\n\t * \t\tvalue: {\n\t * \t\t\t'line-height': modelAttributeValue,\n\t * \t\t\t'border-bottom': '1px dotted #ba2'\n\t * \t\t}\n\t * \t} )\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n\t * the attribute key, possible values and, optionally, an element name to convert from.\n\t * @param config.view A view attribute key, or a `{ key, value }` object or a function that takes the model attribute value and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as parameters and returns a `{ key, value }` object. If the `key` is `'class'`, the `value` can be a `String` or an\n\t * array of `String`s. If the `key` is `'style'`, the `value` is an object with key-value pairs. In other cases, `value` is a `String`.\n\t * If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n\t * `{ key, value }` objects or a functions.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic attributeToAttribute<TValues extends string>(\n\t\tconfig: {\n\t\t\tmodel: string | {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t};\n\t\t\tview: string | AttributeDescriptor | AttributeCreatorFunction;\n\t\t\tconverterPriority?: PriorityString;\n\t\t} | {\n\t\t\tmodel: {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t\tvalues?: Array<TValues>;\n\t\t\t};\n\t\t\tview: Record<TValues, AttributeDescriptor | AttributeCreatorFunction>;\n\t\t\tconverterPriority?: PriorityString;\n\t\t}\n\t): this {\n\t\treturn this.add( downcastAttributeToAttribute( config ) );\n\t}\n\n\t/**\n\t * Model marker to view element conversion helper.\n\t *\n\t * **Note**: This method should be used mainly for editing the downcast and it is recommended\n\t * to use the {@link #markerToData `#markerToData()`} helper instead.\n\t *\n\t * This helper may produce invalid HTML code (e.g. a span between table cells).\n\t * It should only be used when you are sure that the produced HTML will be semantically correct.\n\t *\n\t * This conversion results in creating a view element on the boundaries of the converted marker. If the converted marker\n\t * is collapsed, only one element is created. For example, a model marker set like this: `<paragraph>F[oo b]ar</paragraph>`\n\t * becomes `<p>F<span data-marker=\"search\"></span>oo b<span data-marker=\"search\"></span>ar</p>` in the view.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: 'marker-search'\n\t * } );\n\t *\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: 'search-result',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tattributes: {\n\t * \t\t\t'data-marker': 'search'\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t * \tmodel: 'search',\n\t * \tview: ( markerData, conversionApi ) => {\n\t * \t\tconst { writer } = conversionApi;\n\t *\n\t * \t\treturn writer.createUIElement( 'span', {\n\t * \t\t\t'data-marker': 'search',\n\t * \t\t\t'data-start': markerData.isOpening\n\t * \t\t} );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * If a function is passed as the `config.view` parameter, it will be used to generate both boundary elements. The function\n\t * receives the `data` object and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as a parameters and should return an instance of the\n\t * {@link module:engine/view/uielement~UIElement view UI element}. The `data` object and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi `conversionApi`} are passed from\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}. Additionally,\n\t * the `data.isOpening` parameter is passed, which is set to `true` for the marker start boundary element, and `false` for\n\t * the marker end boundary element.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The name of the model marker (or model marker group) to convert.\n\t * @param config.view A view element definition or a function that takes the model marker data and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as a parameters\n\t * and returns a view UI element.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic markerToElement( config: {\n\t\tmodel: string;\n\t\tview: ElementDefinition | MarkerElementCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( downcastMarkerToElement( config ) );\n\t}\n\n\t/**\n\t * Model marker to highlight conversion helper.\n\t *\n\t * This conversion results in creating a highlight on view nodes. For this kind of conversion,\n\t * the {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} should be provided.\n\t *\n\t * For text nodes, a `<span>` {@link module:engine/view/attributeelement~AttributeElement} is created and it wraps all text nodes\n\t * in the converted marker range. For example, a model marker set like this: `<paragraph>F[oo b]ar</paragraph>` becomes\n\t * `<p>F<span class=\"comment\">oo b</span>ar</p>` in the view.\n\t *\n\t * {@link module:engine/view/containerelement~ContainerElement} may provide a custom way of handling highlight. Most often,\n\t * the element itself is given classes and attributes described in the highlight descriptor (instead of being wrapped in `<span>`).\n\t * For example, a model marker set like this:\n\t * `[<imageInline src=\"foo.jpg\"></imageInline>]` becomes `<img src=\"foo.jpg\" class=\"comment\"></img>` in the view.\n\t *\n\t * For container elements, the conversion is two-step. While the converter processes the highlight descriptor and passes it\n\t * to a container element, it is the container element instance itself that applies values from the highlight descriptor.\n\t * So, in a sense, the converter takes care of stating what should be applied on what, while the element decides how to apply that.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' ).markerToHighlight( { model: 'comment', view: { classes: 'comment' } } );\n\t *\n\t * editor.conversion.for( 'downcast' ).markerToHighlight( {\n\t * \tmodel: 'comment',\n\t * \tview: { classes: 'comment' },\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'downcast' ).markerToHighlight( {\n\t * \tmodel: 'comment',\n\t * \tview: ( data, conversionApi ) => {\n\t * \t\t// Assuming that the marker name is in a form of comment:commentType:commentId.\n\t * \t\tconst [ , commentType, commentId ] = data.markerName.split( ':' );\n\t *\n\t * \t\treturn {\n\t * \t\t\tclasses: [ 'comment', 'comment-' + commentType ],\n\t * \t\t\tattributes: { 'data-comment-id': commentId }\n\t * \t\t};\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * If a function is passed as the `config.view` parameter, it will be used to generate the highlight descriptor. The function\n\t * receives the `data` object and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n\t * as the parameters and should return a\n\t * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor highlight descriptor}.\n\t * The `data` object properties are passed from {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}.\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The name of the model marker (or model marker group) to convert.\n\t * @param config.view A highlight descriptor that will be used for highlighting or a function that takes the model marker data and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as a parameters\n\t * and returns a highlight descriptor.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic markerToHighlight( config: {\n\t\tmodel: string;\n\t\tview: HighlightDescriptor | HighlightDescriptorCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( downcastMarkerToHighlight( config ) );\n\t}\n\n\t/**\n\t * Model marker converter for data downcast.\n\t *\n\t * This conversion creates a representation for model marker boundaries in the view:\n\t *\n\t * * If the marker boundary is before or after a model element, a view attribute is set on a corresponding view element.\n\t * * In other cases, a view element with the specified tag name is inserted at the corresponding view position.\n\t *\n\t * Typically, the marker names use the `group:uniqueId:otherData` convention. For example: `comment:e34zfk9k2n459df53sjl34:zx32c`.\n\t * The default configuration for this conversion is that the first part is the `group` part and the rest of\n\t * the marker name becomes the `name` part.\n\t *\n\t * Tag and attribute names and values are generated from the marker name:\n\t *\n\t * * The templates for attributes are `data-[group]-start-before=\"[name]\"`, `data-[group]-start-after=\"[name]\"`,\n\t * `data-[group]-end-before=\"[name]\"` and `data-[group]-end-after=\"[name]\"`.\n\t * * The templates for view elements are `<[group]-start name=\"[name]\">` and `<[group]-end name=\"[name]\">`.\n\t *\n\t * Attributes mark whether the given marker's start or end boundary is before or after the given element.\n\t * The `data-[group]-start-before` and `data-[group]-end-after` attributes are favored.\n\t * The other two are used when the former two cannot be used.\n\t *\n\t * The conversion configuration can take a function that will generate different group and name parts.\n\t * If such a function is set as the `config.view` parameter, it is passed a marker name and it is expected to return an object with two\n\t * properties: `group` and `name`. If the function returns a falsy value, the conversion will not take place.\n\t *\n\t * Basic usage:\n\t *\n\t * ```ts\n\t * // Using the default conversion.\n\t * // In this case, all markers with names starting with 'comment:' will be converted.\n\t * // The `group` parameter will be set to `comment`.\n\t * // The `name` parameter will be the rest of the marker name (without the `:`).\n\t * editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t * \tmodel: 'comment'\n\t * } );\n\t * ```\n\t *\n\t * An example of a view that may be generated by this conversion (assuming a marker with the name `comment:commentId:uid` marked\n\t * by `[]`):\n\t *\n\t * ```\n\t * // Model:\n\t * <paragraph>Foo[bar</paragraph>\n\t * <imageBlock src=\"abc.jpg\"></imageBlock>]\n\t *\n\t * // View:\n\t * <p>Foo<comment-start name=\"commentId:uid\"></comment-start>bar</p>\n\t * <figure data-comment-end-after=\"commentId:uid\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t * ```\n\t *\n\t * In the example above, the comment starts before \"bar\" and ends after the image.\n\t *\n\t * If the `name` part is empty, the following view may be generated:\n\t *\n\t * ```html\n\t * <p>Foo <myMarker-start></myMarker-start>bar</p>\n\t * <figure data-myMarker-end-after=\"\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t * ```\n\t *\n\t * **Note:** A situation where some markers have the `name` part and some do not, is incorrect and should be avoided.\n\t *\n\t * Examples where `data-group-start-after` and `data-group-end-before` are used:\n\t *\n\t * ```\n\t * // Model:\n\t * <blockQuote>[]<paragraph>Foo</paragraph></blockQuote>\n\t *\n\t * // View:\n\t * <blockquote><p data-group-end-before=\"name\" data-group-start-before=\"name\">Foo</p></blockquote>\n\t * ```\n\t *\n\t * Similarly, when a marker is collapsed after the last element:\n\t *\n\t * ```\n\t * // Model:\n\t * <blockQuote><paragraph>Foo</paragraph>[]</blockQuote>\n\t *\n\t * // View:\n\t * <blockquote><p data-group-end-after=\"name\" data-group-start-after=\"name\">Foo</p></blockquote>\n\t * ```\n\t *\n\t * When there are multiple markers from the same group stored in the same attribute of the same element, their\n\t * name parts are put together in the attribute value, for example: `data-group-start-before=\"name1,name2,name3\"`.\n\t *\n\t * Other examples of usage:\n\t *\n\t * ```ts\n\t * // Using a custom function which is the same as the default conversion:\n\t * editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t * \tmodel: 'comment',\n\t * \tview: markerName => ( {\n\t * \t\tgroup: 'comment',\n\t * \t\tname: markerName.substr( 8 ) // Removes 'comment:' part.\n\t * \t} )\n\t * } );\n\t *\n\t * // Using the converter priority:\n\t * editor.conversion.for( 'dataDowncast' ).markerToData( {\n\t * \tmodel: 'comment',\n\t * \tview: markerName => ( {\n\t * \t\tgroup: 'comment',\n\t * \t\tname: markerName.substr( 8 ) // Removes 'comment:' part.\n\t * \t} ),\n\t * \tconverterPriority: 'high'\n\t * } );\n\t * ```\n\t *\n\t * This kind of conversion is useful for saving data into the database, so it should be used in the data conversion pipeline.\n\t *\n\t * See the {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} API guide to learn how to\n\t * add a converter to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.model The name of the model marker (or the model marker group) to convert.\n\t * @param config.view A function that takes the model marker name and\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as the parameters\n\t * and returns an object with the `group` and `name` properties.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic markerToData( config: {\n\t\tmodel: string;\n\t\tview?: MarkerDataCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( downcastMarkerToData( config ) );\n\t}\n}\n\n/**\n * Function factory that creates a default downcast converter for text insertion changes.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n * ```ts\n * modelDispatcher.on( 'insert:$text', insertText() );\n * ```\n *\n * @returns Insert text event converter.\n */\nexport function insertText() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: { item: ModelText | ModelTextProxy; range: ModelRange },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\t\tconst viewText = viewWriter.createText( data.item.data );\n\n\t\tviewWriter.insert( viewPosition, viewText );\n\t};\n}\n\n/**\n * Function factory that creates a default downcast converter for triggering attributes and children conversion.\n *\n * @returns The converter.\n */\nexport function insertAttributesAndChildren() {\n\treturn (\n\t\tevt: unknown,\n\t\tdata: { item: ModelItem; reconversion?: boolean },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tconversionApi.convertAttributes( data.item );\n\n\t\t// Start converting children of the current item.\n\t\t// In case of reconversion children were already re-inserted or converted separately.\n\t\tif ( !data.reconversion && data.item.is( 'element' ) && !data.item.isEmpty ) {\n\t\t\tconversionApi.convertChildren( data.item );\n\t\t}\n\t};\n}\n\n/**\n * Function factory that creates a default downcast converter for node remove changes.\n *\n * ```ts\n * modelDispatcher.on( 'remove', remove() );\n * ```\n *\n * @returns Remove event converter.\n */\nexport function remove() {\n\treturn (\n\t\tevt: unknown,\n\t\tdata: { position: ModelPosition; length: number },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\t// Find the view range start position by mapping the model position at which the remove happened.\n\t\tconst viewStart = conversionApi.mapper.toViewPosition( data.position );\n\n\t\tconst modelEnd = data.position.getShiftedBy( data.length );\n\t\tconst viewEnd = conversionApi.mapper.toViewPosition( modelEnd, { isPhantom: true } );\n\n\t\tconst viewRange = conversionApi.writer.createRange( viewStart, viewEnd );\n\n\t\t// Trim the range to remove in case some UI elements are on the view range boundaries.\n\t\tconst removed = conversionApi.writer.remove( viewRange.getTrimmed() );\n\n\t\t// After the range is removed, unbind all view elements from the model.\n\t\t// Range inside view document fragment is used to unbind deeply.\n\t\tfor ( const child of conversionApi.writer.createRangeIn( removed ).getItems() ) {\n\t\t\tconversionApi.mapper.unbindViewElement( child as ViewElement, { defer: true } );\n\t\t}\n\t};\n}\n\n/**\n * Creates a `<span>` {@link module:engine/view/attributeelement~AttributeElement view attribute element} from the information\n * provided by the {@link module:engine/conversion/downcasthelpers~HighlightDescriptor highlight descriptor} object. If the priority\n * is not provided in the descriptor, the default priority will be used.\n */\nexport function createViewElementFromHighlightDescriptor( writer: DowncastWriter, descriptor: HighlightDescriptor ): ViewAttributeElement {\n\tconst viewElement = writer.createAttributeElement( 'span', descriptor.attributes );\n\n\tif ( descriptor.classes ) {\n\t\tviewElement._addClass( descriptor.classes );\n\t}\n\n\tif ( typeof descriptor.priority === 'number' ) {\n\t\t( viewElement as any )._priority = descriptor.priority;\n\t}\n\n\t( viewElement as any )._id = descriptor.id;\n\n\treturn viewElement;\n}\n\n/**\n * Function factory that creates a converter which converts a non-collapsed {@link module:engine/model/selection~Selection model selection}\n * to a {@link module:engine/view/documentselection~DocumentSelection view selection}. The converter consumes appropriate\n * value from the `consumable` object and maps model positions from the selection to view positions.\n *\n * ```ts\n * modelDispatcher.on( 'selection', convertRangeSelection() );\n * ```\n *\n * @returns Selection converter.\n */\nexport function convertRangeSelection() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: { selection: ModelSelection | ModelDocumentSelection },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tconst selection = data.selection;\n\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( selection, 'selection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewRanges: Array<ViewRange> = [];\n\n\t\tfor ( const range of selection.getRanges() ) {\n\t\t\tviewRanges.push( conversionApi.mapper.toViewRange( range ) );\n\t\t}\n\n\t\tconversionApi.writer.setSelection( viewRanges, { backward: selection.isBackward } );\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts a collapsed {@link module:engine/model/selection~Selection model selection} to\n * a {@link module:engine/view/documentselection~DocumentSelection view selection}. The converter consumes appropriate\n * value from the `consumable` object, maps the model selection position to the view position and breaks\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} at the selection position.\n *\n * ```ts\n * modelDispatcher.on( 'selection', convertCollapsedSelection() );\n * ```\n *\n * An example of the view state before and after converting the collapsed selection:\n *\n * ```\n *    <p><strong>f^oo<strong>bar</p>\n * -> <p><strong>f</strong>^<strong>oo</strong>bar</p>\n * ```\n *\n * By breaking attribute elements like `<strong>`, the selection is in a correct element. Then, when the selection attribute is\n * converted, broken attributes might be merged again, or the position where the selection is may be wrapped\n * with different, appropriate attribute elements.\n *\n * See also {@link module:engine/conversion/downcasthelpers~cleanSelection} which does a clean-up\n * by merging attributes.\n *\n * @returns Selection converter.\n */\nexport function convertCollapsedSelection() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: { selection: ModelSelection | ModelDocumentSelection },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tconst selection = data.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( selection, 'selection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst modelPosition = selection.getFirstPosition()!;\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( modelPosition );\n\t\tconst brokenPosition = viewWriter.breakAttributes( viewPosition );\n\n\t\tviewWriter.setSelection( brokenPosition );\n\t};\n}\n\n/**\n * Function factory that creates a converter which cleans artifacts after the previous\n * {@link module:engine/model/selection~Selection model selection} conversion. It removes all empty\n * {@link module:engine/view/attributeelement~AttributeElement view attribute elements} and merges sibling attributes at all start and end\n * positions of all ranges.\n *\n * ```\n *    <p><strong>^</strong></p>\n * -> <p>^</p>\n *\n *    <p><strong>foo</strong>^<strong>bar</strong>bar</p>\n * -> <p><strong>foo^bar<strong>bar</p>\n *\n *    <p><strong>foo</strong><em>^</em><strong>bar</strong>bar</p>\n * -> <p><strong>foo^bar<strong>bar</p>\n * ```\n *\n * This listener should be assigned before any converter for the new selection:\n *\n * ```ts\n * modelDispatcher.on( 'cleanSelection', cleanSelection() );\n * ```\n *\n * See {@link module:engine/conversion/downcasthelpers~convertCollapsedSelection}\n * which does the opposite by breaking attributes in the selection position.\n *\n * @returns Selection converter.\n */\nexport function cleanSelection() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: unknown,\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\tfor ( const range of viewSelection.getRanges() ) {\n\t\t\t// Not collapsed selection should not have artifacts.\n\t\t\tif ( range.isCollapsed ) {\n\t\t\t\t// Position might be in the node removed by the view writer.\n\t\t\t\tif ( ( range.end.parent as ViewNode ).isAttached() ) {\n\t\t\t\t\tconversionApi.writer.mergeAttributes( range.start );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tviewWriter.setSelection( null );\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts the set/change/remove attribute changes from the model to the view.\n * It can also be used to convert selection attributes. In that case, an empty attribute element will be created and the\n * selection will be put inside it.\n *\n * Attributes from the model are converted to a view element that will be wrapping these view nodes that are bound to\n * model elements having the given attribute. This is useful for attributes like `bold` that may be set on text nodes in the model\n * but are represented as an element in the view:\n *\n * ```\n * [paragraph]              MODEL ====> VIEW        <p>\n * \t|- a {bold: true}                             |- <b>\n * \t|- b {bold: true}                             |   |- ab\n * \t|- c                                          |- c\n * \t```\n *\n * Passed `Function` will be provided with the attribute value and then all the parameters of the\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute` event}.\n * It is expected that the function returns an {@link module:engine/view/element~Element}.\n * The result of the function will be the wrapping element.\n * When the provided `Function` does not return any element, no conversion will take place.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n * ```ts\n * modelDispatcher.on( 'attribute:bold', wrap( ( modelAttributeValue, { writer } ) => {\n * \treturn writer.createAttributeElement( 'strong' );\n * } );\n * ```\n *\n * @internal\n * @param elementCreator Function returning a view element that will be used for wrapping.\n * @returns Set/change attribute converter.\n */\nexport function wrap( elementCreator: AttributeElementCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: {\n\t\t\titem: ModelItem | ModelSelection | ModelDocumentSelection;\n\t\t\trange: ModelRange;\n\t\t\tattributeKey: string;\n\t\t\tattributeOldValue: unknown;\n\t\t\tattributeNewValue: unknown;\n\t\t},\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Recreate current wrapping node. It will be used to unwrap view range if the attribute value has changed\n\t\t// or the attribute was removed.\n\t\tconst oldViewElement = elementCreator( data.attributeOldValue, conversionApi, data );\n\n\t\t// Create node to wrap with.\n\t\tconst newViewElement = elementCreator( data.attributeNewValue, conversionApi, data );\n\n\t\tif ( !oldViewElement && !newViewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconversionApi.consumable.consume( data.item, evt.name );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\tif ( data.item instanceof ModelSelection || data.item instanceof ModelDocumentSelection ) {\n\t\t\t// Selection attribute conversion.\n\t\t\tviewWriter.wrap( viewSelection.getFirstRange()!, newViewElement! );\n\t\t} else {\n\t\t\t// Node attribute conversion.\n\t\t\tlet viewRange = conversionApi.mapper.toViewRange( data.range );\n\n\t\t\t// First, unwrap the range from current wrapper.\n\t\t\tif ( data.attributeOldValue !== null && oldViewElement ) {\n\t\t\t\tviewRange = viewWriter.unwrap( viewRange, oldViewElement );\n\t\t\t}\n\n\t\t\tif ( data.attributeNewValue !== null && newViewElement ) {\n\t\t\t\tviewWriter.wrap( viewRange, newViewElement );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts node insertion changes from the model to the view.\n * The function passed will be provided with all the parameters of the dispatcher's\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert` event}.\n * It is expected that the function returns an {@link module:engine/view/element~Element}.\n * The result of the function will be inserted into the view.\n *\n * The converter automatically consumes the corresponding value from the consumables list and binds the model and view elements.\n *\n * ```ts\n * downcastDispatcher.on(\n * \t'insert:myElem',\n * \tinsertElement( ( modelItem, { writer } ) => {\n * \t\tconst text = writer.createText( 'myText' );\n * \t\tconst myElem = writer.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );\n *\n * \t\t// Do something fancy with `myElem` using `modelItem` or other parameters.\n *\n * \t\treturn myElem;\n * \t}\n * ) );\n * ```\n *\n * @internal\n * @param  elementCreator Function returning a view element, which will be inserted.\n * @param consumer Function defining element consumption process.\n * By default this function just consume passed item insertion.\n * @returns Insert element event converter.\n */\nexport function insertElement( elementCreator: ElementCreatorFunction, consumer: ConsumerFunction = defaultConsumer ) {\n\treturn (\n\t\tevt: unknown,\n\t\tdata: { item: ModelElement; range: ModelRange; reconversion?: boolean },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tif ( !consumer( data.item, conversionApi.consumable, { preflight: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = elementCreator( data.item, conversionApi, data );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Consume an element insertion and all present attributes that are specified as a reconversion triggers.\n\t\tconsumer( data.item, conversionApi.consumable );\n\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconversionApi.mapper.bindElements( data.item, viewElement );\n\t\tconversionApi.writer.insert( viewPosition, viewElement );\n\n\t\t// Convert attributes before converting children.\n\t\tconversionApi.convertAttributes( data.item );\n\n\t\t// Convert children or reinsert previous view elements.\n\t\treinsertOrConvertNodes( viewElement, data.item.getChildren(), conversionApi, { reconversion: data.reconversion } );\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts a single model node insertion to a view structure.\n *\n * It is expected that the passed element creator function returns an {@link module:engine/view/element~Element} with attached slots\n * created with `writer.createSlot()` to indicate where child nodes should be converted.\n *\n * @see module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n *\n * @internal\n * @param elementCreator Function returning a view structure, which will be inserted.\n * @param consumer A callback that is expected to consume all the consumables\n * that were used by the element creator.\n * @returns Insert element event converter.\n*/\nexport function insertStructure( elementCreator: StructureCreatorFunction, consumer: ConsumerFunction ) {\n\treturn (\n\t\tevt: unknown,\n\t\tdata: { item: ModelElement; range: ModelRange; reconversion?: boolean },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tif ( !consumer( data.item, conversionApi.consumable, { preflight: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst slotsMap = new Map<ViewElement, Array<ModelNode>>();\n\n\t\tconversionApi.writer._registerSlotFactory( createSlotFactory( data.item, slotsMap, conversionApi ) );\n\n\t\t// View creation.\n\t\tconst viewElement = elementCreator( data.item, conversionApi, data );\n\n\t\tconversionApi.writer._clearSlotFactory();\n\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all children are covered by slots and there is no child that landed in multiple slots.\n\t\tvalidateSlotsChildren( data.item, slotsMap, conversionApi );\n\n\t\t// Consume an element insertion and all present attributes that are specified as a reconversion triggers.\n\t\tconsumer( data.item, conversionApi.consumable );\n\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconversionApi.mapper.bindElements( data.item, viewElement );\n\t\tconversionApi.writer.insert( viewPosition, viewElement );\n\n\t\t// Convert attributes before converting children.\n\t\tconversionApi.convertAttributes( data.item );\n\n\t\t// Fill view slots with previous view elements or create new ones.\n\t\tfillSlots( viewElement, slotsMap, conversionApi, { reconversion: data.reconversion } );\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts marker adding change to the\n * {@link module:engine/view/uielement~UIElement view UI element}.\n *\n * The view UI element that will be added to the view depends on the passed parameter. See {@link ~insertElement}.\n * In case of a non-collapsed range, the UI element will not wrap nodes but separate elements will be placed at the beginning\n * and at the end of the range.\n *\n * This converter binds created UI elements with the marker name using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.\n *\n * @internal\n * @param elementCreator A view UI element or a function returning the view element that will be inserted.\n * @returns Insert element event converter.\n */\nexport function insertUIElement( elementCreator: MarkerElementCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: {\n\t\t\tmarkerRange: ModelRange;\n\t\t\tmarkerName: string;\n\t\t\tisOpening?: boolean;\n\t\t},\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\t// Create two view elements. One will be inserted at the beginning of marker, one at the end.\n\t\t// If marker is collapsed, only \"opening\" element will be inserted.\n\t\tdata.isOpening = true;\n\t\tconst viewStartElement = elementCreator( data, conversionApi );\n\n\t\tdata.isOpening = false;\n\t\tconst viewEndElement = elementCreator( data, conversionApi );\n\n\t\tif ( !viewStartElement || !viewEndElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst markerRange = data.markerRange;\n\n\t\t// Marker that is collapsed has consumable build differently that non-collapsed one.\n\t\t// For more information see `addMarker` event description.\n\t\t// If marker's range is collapsed - check if it can be consumed.\n\t\tif ( markerRange.isCollapsed && !conversionApi.consumable.consume( markerRange, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If marker's range is not collapsed - consume all items inside.\n\t\tfor ( const value of markerRange ) {\n\t\t\tif ( !conversionApi.consumable.consume( value.item, evt.name ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tconst mapper = conversionApi.mapper;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// Add \"opening\" element.\n\t\tviewWriter.insert( mapper.toViewPosition( markerRange.start ), viewStartElement );\n\t\tconversionApi.mapper.bindElementToMarker( viewStartElement, data.markerName );\n\n\t\t// Add \"closing\" element only if range is not collapsed.\n\t\tif ( !markerRange.isCollapsed ) {\n\t\t\tviewWriter.insert( mapper.toViewPosition( markerRange.end ), viewEndElement );\n\t\t\tconversionApi.mapper.bindElementToMarker( viewEndElement, data.markerName );\n\t\t}\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * Function factory that returns a default downcast converter for removing a {@link module:engine/view/uielement~UIElement UI element}\n * based on marker remove change.\n *\n * This converter unbinds elements from the marker name.\n *\n * @returns Removed UI element converter.\n */\nfunction removeUIElement() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: { markerName: string },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tconst elements = conversionApi.mapper.markerNameToElements( data.markerName );\n\n\t\tif ( !elements ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const element of elements ) {\n\t\t\tconversionApi.mapper.unbindElementFromMarkerName( element, data.markerName );\n\t\t\tconversionApi.writer.clear( conversionApi.writer.createRangeOn( element ), element );\n\t\t}\n\n\t\tconversionApi.writer.clearClonedElementsGroup( data.markerName );\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * Function factory that creates a default converter for model markers.\n *\n * See {@link DowncastHelpers#markerToData} for more information what type of view is generated.\n *\n * This converter binds created UI elements and affected view elements with the marker name\n * using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.\n *\n * @returns Add marker converter.\n */\nfunction insertMarkerData( viewCreator: MarkerDataCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: {\n\t\t\tmarkerName: string;\n\t\t\tmarkerRange: ModelRange;\n\t\t},\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tconst viewMarkerData = viewCreator( data.markerName, conversionApi );\n\n\t\tif ( !viewMarkerData ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst markerRange = data.markerRange;\n\n\t\tif ( !conversionApi.consumable.consume( markerRange, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Adding closing data first to keep the proper order in the view.\n\t\thandleMarkerBoundary( markerRange, false, conversionApi, data, viewMarkerData );\n\t\thandleMarkerBoundary( markerRange, true, conversionApi, data, viewMarkerData );\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * Helper function for `insertMarkerData()` that marks a marker boundary at the beginning or end of given `range`.\n */\nfunction handleMarkerBoundary(\n\trange: ModelRange,\n\tisStart: boolean,\n\tconversionApi: DowncastConversionApi,\n\tdata: { markerName: string },\n\tviewMarkerData: { name: string; group: string }\n): void {\n\tconst modelPosition = isStart ? range.start : range.end;\n\tconst elementAfter = modelPosition.nodeAfter && modelPosition.nodeAfter.is( 'element' ) ? modelPosition.nodeAfter : null;\n\tconst elementBefore = modelPosition.nodeBefore && modelPosition.nodeBefore.is( 'element' ) ? modelPosition.nodeBefore : null;\n\n\tif ( elementAfter || elementBefore ) {\n\t\tlet modelElement;\n\t\tlet isBefore;\n\n\t\t// If possible, we want to add `data-group-start-before` and `data-group-end-after` attributes.\n\t\tif ( isStart && elementAfter || !isStart && !elementBefore ) {\n\t\t\t// [<elementAfter>...</elementAfter> -> <elementAfter data-group-start-before=\"...\">...</elementAfter>\n\t\t\t// <parent>]<elementAfter> -> <parent><elementAfter data-group-end-before=\"...\">\n\t\t\tmodelElement = elementAfter;\n\t\t\tisBefore = true;\n\t\t} else {\n\t\t\t// <elementBefore>...</elementBefore>] -> <elementBefore data-group-end-after=\"...\">...</elementBefore>\n\t\t\t// </elementBefore>[</parent> -> </elementBefore data-group-start-after=\"...\"></parent>\n\t\t\tmodelElement = elementBefore;\n\t\t\tisBefore = false;\n\t\t}\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( modelElement! );\n\n\t\t// In rare circumstances, the model element may be not mapped to any view element and that would cause an error.\n\t\t// One of those situations is a soft break inside code block.\n\t\tif ( viewElement ) {\n\t\t\tinsertMarkerAsAttribute( viewElement, isStart, isBefore, conversionApi, data, viewMarkerData );\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\tconst viewPosition = conversionApi.mapper.toViewPosition( modelPosition );\n\n\tinsertMarkerAsElement( viewPosition, isStart, conversionApi, data, viewMarkerData );\n}\n\n/**\n * Helper function for `insertMarkerData()` that marks a marker boundary in the view as an attribute on a view element.\n */\nfunction insertMarkerAsAttribute(\n\tviewElement: ViewElement,\n\tisStart: boolean,\n\tisBefore: boolean,\n\tconversionApi: DowncastConversionApi,\n\tdata: { markerName: string },\n\tviewMarkerData: { name: string; group: string }\n) {\n\tconst attributeName = `data-${ viewMarkerData.group }-${ isStart ? 'start' : 'end' }-${ isBefore ? 'before' : 'after' }`;\n\n\tconst markerNames = viewElement.hasAttribute( attributeName ) ? viewElement.getAttribute( attributeName )!.split( ',' ) : [];\n\n\t// Adding marker name at the beginning to have the same order in the attribute as there is with marker elements.\n\tmarkerNames.unshift( viewMarkerData.name );\n\n\tconversionApi.writer.setAttribute( attributeName, markerNames.join( ',' ), viewElement );\n\tconversionApi.mapper.bindElementToMarker( viewElement, data.markerName );\n}\n\n/**\n * Helper function for `insertMarkerData()` that marks a marker boundary in the view as a separate view ui element.\n */\nfunction insertMarkerAsElement(\n\tposition: ViewPosition,\n\tisStart: boolean,\n\tconversionApi: DowncastConversionApi,\n\tdata: { markerName: string },\n\tviewMarkerData: { name: string; group: string }\n) {\n\tconst viewElementName = `${ viewMarkerData.group }-${ isStart ? 'start' : 'end' }`;\n\n\tconst attrs = viewMarkerData.name ? { 'name': viewMarkerData.name } : null;\n\tconst viewElement = conversionApi.writer.createUIElement( viewElementName, attrs );\n\n\tconversionApi.writer.insert( position, viewElement );\n\tconversionApi.mapper.bindElementToMarker( viewElement, data.markerName );\n}\n\n/**\n * Function factory that creates a converter for removing a model marker data added by the {@link #insertMarkerData} converter.\n *\n * @returns Remove marker converter.\n */\nfunction removeMarkerData( viewCreator: MarkerDataCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: { markerName: string },\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tconst viewData = viewCreator( data.markerName, conversionApi );\n\n\t\tif ( !viewData ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst elements = conversionApi.mapper.markerNameToElements( data.markerName );\n\n\t\tif ( !elements ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const element of elements ) {\n\t\t\tconversionApi.mapper.unbindElementFromMarkerName( element, data.markerName );\n\n\t\t\tif ( element.is( 'containerElement' ) ) {\n\t\t\t\tremoveMarkerFromAttribute( `data-${ viewData.group }-start-before`, element );\n\t\t\t\tremoveMarkerFromAttribute( `data-${ viewData.group }-start-after`, element );\n\t\t\t\tremoveMarkerFromAttribute( `data-${ viewData.group }-end-before`, element );\n\t\t\t\tremoveMarkerFromAttribute( `data-${ viewData.group }-end-after`, element );\n\t\t\t} else {\n\t\t\t\tconversionApi.writer.clear( conversionApi.writer.createRangeOn( element ), element );\n\t\t\t}\n\t\t}\n\n\t\tconversionApi.writer.clearClonedElementsGroup( data.markerName );\n\n\t\tevt.stop();\n\n\t\tfunction removeMarkerFromAttribute( attributeName: string, element: ViewElement ): void {\n\t\t\tif ( element.hasAttribute( attributeName ) ) {\n\t\t\t\tconst markerNames = new Set( element.getAttribute( attributeName )!.split( ',' ) );\n\n\t\t\t\tmarkerNames.delete( viewData!.name );\n\n\t\t\t\tif ( markerNames.size == 0 ) {\n\t\t\t\t\tconversionApi.writer.removeAttribute( attributeName, element );\n\t\t\t\t} else {\n\t\t\t\t\tconversionApi.writer.setAttribute( attributeName, Array.from( markerNames ).join( ',' ), element );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts the set/change/remove attribute changes from the model to the view.\n *\n * Attributes from the model are converted to the view element attributes in the view. You may provide a custom function to generate\n * a key-value attribute pair to add/change/remove. If not provided, model attributes will be converted to view element\n * attributes on a one-to-one basis.\n *\n * *Note:** The provided attribute creator should always return the same `key` for a given attribute from the model.\n *\n * The converter automatically consumes the corresponding value from the consumables list and stops the event (see\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).\n *\n * ```ts\n * modelDispatcher.on( 'attribute:customAttr:myElem', changeAttribute( ( value, data ) => {\n * \t// Change attribute key from `customAttr` to `class` in the view.\n * \tconst key = 'class';\n * \tlet value = data.attributeNewValue;\n *\n * \t// Force attribute value to 'empty' if the model element is empty.\n * \tif ( data.item.childCount === 0 ) {\n * \t\tvalue = 'empty';\n * \t}\n *\n * \t// Return the key-value pair.\n * \treturn { key, value };\n * } ) );\n * ```\n *\n * @param attributeCreator Function returning an object with two properties: `key` and `value`, which\n * represent the attribute key and attribute value to be set on a {@link module:engine/view/element~Element view element}.\n * The function is passed the model attribute value as the first parameter and additional data about the change as the second parameter.\n * @returns Set/change attribute converter.\n */\nfunction changeAttribute( attributeCreator: AttributeCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: {\n\t\t\titem: ModelElement;\n\t\t\trange: ModelRange;\n\t\t\tattributeKey: string;\n\t\t\tattributeOldValue: unknown;\n\t\t\tattributeNewValue: unknown;\n\t\t},\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst oldAttribute = attributeCreator( data.attributeOldValue, conversionApi, data );\n\t\tconst newAttribute = attributeCreator( data.attributeNewValue, conversionApi, data );\n\n\t\tif ( !oldAttribute && !newAttribute ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconversionApi.consumable.consume( data.item, evt.name );\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// If model item cannot be mapped to a view element, it means item is not an `Element` instance but a `TextProxy` node.\n\t\t// Only elements can have attributes in a view so do not proceed for anything else (#1587).\n\t\tif ( !viewElement ) {\n\t\t\t/**\n\t\t\t * This error occurs when a {@link module:engine/model/textproxy~TextProxy text node's} attribute is to be downcasted\n\t\t\t * by an {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `Attribute to Attribute converter`}.\n\t\t\t * In most cases it is caused by converters misconfiguration when only \"generic\" converter is defined:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * editor.conversion.for( 'downcast' ).attributeToAttribute( {\n\t\t\t * \tmodel: 'attribute-name',\n\t\t\t * \tview: 'attribute-name'\n\t\t\t * } ) );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * and given attribute is used on text node, for example:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * model.change( writer => {\n\t\t\t * \twriter.insertText( 'Foo', { 'attribute-name': 'bar' }, parent, 0 );\n\t\t\t * } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * In such cases, to convert the same attribute for both {@link module:engine/model/element~Element}\n\t\t\t * and {@link module:engine/model/textproxy~TextProxy `Text`} nodes, text specific\n\t\t\t * {@link module:engine/conversion/conversion~Conversion#attributeToElement `Attribute to Element converter`}\n\t\t\t * with higher {@link module:utils/priorities~PriorityString priority} must also be defined:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * editor.conversion.for( 'downcast' ).attributeToElement( {\n\t\t\t * \tmodel: {\n\t\t\t * \t\tkey: 'attribute-name',\n\t\t\t * \t\tname: '$text'\n\t\t\t * \t},\n\t\t\t * \tview: ( value, { writer } ) => {\n\t\t\t * \t\treturn writer.createAttributeElement( 'span', { 'attribute-name': value } );\n\t\t\t * \t},\n\t\t\t * \tconverterPriority: 'high'\n\t\t\t * } ) );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * @error conversion-attribute-to-attribute-on-text\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-attribute-to-attribute-on-text', conversionApi.dispatcher, data );\n\t\t}\n\n\t\t// First remove the old attribute if there was one.\n\t\tif ( data.attributeOldValue !== null && oldAttribute ) {\n\t\t\tif ( oldAttribute.key == 'class' ) {\n\t\t\t\tconst classes = typeof oldAttribute.value == 'string' ? oldAttribute.value.split( /\\s+/ ) : oldAttribute.value;\n\n\t\t\t\tfor ( const className of classes ) {\n\t\t\t\t\tviewWriter.removeClass( className, viewElement );\n\t\t\t\t}\n\t\t\t} else if ( oldAttribute.key == 'style' ) {\n\t\t\t\tif ( typeof oldAttribute.value == 'string' ) {\n\t\t\t\t\tconst styles = new StylesMap( viewWriter.document.stylesProcessor );\n\n\t\t\t\t\tstyles.setTo( oldAttribute.value );\n\n\t\t\t\t\tfor ( const [ key ] of styles.getStylesEntries() ) {\n\t\t\t\t\t\tviewWriter.removeStyle( key, viewElement );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst keys = Object.keys( oldAttribute.value );\n\n\t\t\t\t\tfor ( const key of keys ) {\n\t\t\t\t\t\tviewWriter.removeStyle( key, viewElement );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tviewWriter.removeAttribute( oldAttribute.key, viewElement );\n\t\t\t}\n\t\t}\n\n\t\t// Then set the new attribute.\n\t\tif ( data.attributeNewValue !== null && newAttribute ) {\n\t\t\tif ( newAttribute.key == 'class' ) {\n\t\t\t\tconst classes = typeof newAttribute.value == 'string' ? newAttribute.value.split( /\\s+/ ) : newAttribute.value;\n\n\t\t\t\tfor ( const className of classes ) {\n\t\t\t\t\tviewWriter.addClass( className, viewElement );\n\t\t\t\t}\n\t\t\t} else if ( newAttribute.key == 'style' ) {\n\t\t\t\tif ( typeof newAttribute.value == 'string' ) {\n\t\t\t\t\tconst styles = new StylesMap( viewWriter.document.stylesProcessor );\n\n\t\t\t\t\tstyles.setTo( newAttribute.value );\n\n\t\t\t\t\tfor ( const [ key, value ] of styles.getStylesEntries() ) {\n\t\t\t\t\t\tviewWriter.setStyle( key, value, viewElement );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst keys = Object.keys( newAttribute.value );\n\n\t\t\t\t\tfor ( const key of keys ) {\n\t\t\t\t\t\tviewWriter.setStyle( key, ( newAttribute.value as Record<string, string> )[ key ], viewElement );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tviewWriter.setAttribute( newAttribute.key, newAttribute.value as string, viewElement );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts the text inside marker's range. The converter wraps the text with\n * {@link module:engine/view/attributeelement~AttributeElement} created from the provided descriptor.\n * See {link module:engine/conversion/downcasthelpers~createViewElementFromHighlightDescriptor}.\n *\n * It can also be used to convert the selection that is inside a marker. In that case, an empty attribute element will be\n * created and the selection will be put inside it.\n *\n * If the highlight descriptor does not provide the `priority` property, `10` will be used.\n *\n * If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n *\n * This converter binds the created {@link module:engine/view/attributeelement~AttributeElement attribute elemens} with the marker name\n * using the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n */\nfunction highlightText( highlightDescriptor: HighlightDescriptor | HighlightDescriptorCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: {\n\t\t\titem?: ModelItem | ModelSelection | ModelDocumentSelection;\n\t\t\trange?: ModelRange;\n\t\t\tmarkerRange: ModelRange;\n\t\t\tmarkerName: string;\n\t\t},\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tif ( !data.item ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !( data.item instanceof ModelSelection || data.item instanceof ModelDocumentSelection ) && !data.item.is( '$textProxy' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst descriptor = prepareDescriptor( highlightDescriptor, data, conversionApi );\n\n\t\tif ( !descriptor ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewElement = createViewElementFromHighlightDescriptor( viewWriter, descriptor );\n\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\tif ( data.item instanceof ModelSelection || data.item instanceof ModelDocumentSelection ) {\n\t\t\tviewWriter.wrap( viewSelection.getFirstRange()!, viewElement );\n\t\t} else {\n\t\t\tconst viewRange = conversionApi.mapper.toViewRange( data.range! );\n\t\t\tconst rangeAfterWrap = viewWriter.wrap( viewRange, viewElement );\n\n\t\t\tfor ( const element of rangeAfterWrap.getItems() ) {\n\t\t\t\tif ( element.is( 'attributeElement' ) && element.isSimilar( viewElement ) ) {\n\t\t\t\t\tconversionApi.mapper.bindElementToMarker( element, data.markerName );\n\n\t\t\t\t\t// One attribute element is enough, because all of them are bound together by the view writer.\n\t\t\t\t\t// Mapper uses this binding to get all the elements no matter how many of them are registered in the mapper.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Converter function factory. It creates a function which applies the marker's highlight to an element inside the marker's range.\n *\n * The converter checks if an element has the `addHighlight` function stored as a\n * {@link module:engine/view/element~Element#_setCustomProperty custom property} and, if so, uses it to apply the highlight.\n * In such case the converter will consume all element's children, assuming that they were handled by the element itself.\n *\n * When the `addHighlight` custom property is not present, the element is not converted in any special way.\n * This means that converters will proceed to convert the element's child nodes.\n *\n * If the highlight descriptor does not provide the `priority` property, `10` will be used.\n *\n * If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n *\n * This converter binds altered {@link module:engine/view/containerelement~ContainerElement container elements} with the marker name using\n * the {@link module:engine/conversion/mapper~Mapper#bindElementToMarker} method.\n */\nfunction highlightElement( highlightDescriptor: HighlightDescriptor | HighlightDescriptorCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: {\n\t\t\titem?: ModelItem | ModelSelection | ModelDocumentSelection;\n\t\t\tmarkerName: string;\n\t\t\tmarkerRange: ModelRange;\n\t\t},\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\tif ( !data.item ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !( data.item instanceof ModelElement ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst descriptor = prepareDescriptor( highlightDescriptor, data, conversionApi );\n\n\t\tif ( !descriptor ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item );\n\n\t\tif ( viewElement && viewElement.getCustomProperty( 'addHighlight' ) ) {\n\t\t\t// Consume element itself.\n\t\t\tconversionApi.consumable.consume( data.item, evt.name );\n\n\t\t\t// Consume all children nodes.\n\t\t\tfor ( const value of ModelRange._createIn( data.item ) ) {\n\t\t\t\tconversionApi.consumable.consume( value.item, evt.name );\n\t\t\t}\n\n\t\t\tconst addHighlightCallback = viewElement.getCustomProperty( 'addHighlight' ) as AddHighlightCallback;\n\n\t\t\taddHighlightCallback( viewElement, descriptor, conversionApi.writer );\n\n\t\t\tconversionApi.mapper.bindElementToMarker( viewElement, data.markerName );\n\t\t}\n\t};\n}\n\n/**\n * Function factory that creates a converter which converts the removing model marker to the view.\n *\n * Both text nodes and elements are handled by this converter but they are handled a bit differently.\n *\n * Text nodes are unwrapped using the {@link module:engine/view/attributeelement~AttributeElement attribute element} created from the\n * provided highlight descriptor. See {link module:engine/conversion/downcasthelpers~HighlightDescriptor}.\n *\n * For elements, the converter checks if an element has the `removeHighlight` function stored as a\n * {@link module:engine/view/element~Element#_setCustomProperty custom property}. If so, it uses it to remove the highlight.\n * In such case, the children of that element will not be converted.\n *\n * When `removeHighlight` is not present, the element is not converted in any special way.\n * The converter will proceed to convert the element's child nodes instead.\n *\n * If the highlight descriptor does not provide the `priority` property, `10` will be used.\n *\n * If the highlight descriptor does not provide the `id` property, the name of the marker will be used.\n *\n * This converter unbinds elements from the marker name.\n */\nfunction removeHighlight( highlightDescriptor: HighlightDescriptor | HighlightDescriptorCreatorFunction ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: {\n\t\t\tmarkerName: string;\n\t\t\tmarkerRange: ModelRange;\n\t\t},\n\t\tconversionApi: DowncastConversionApi\n\t): void => {\n\t\t// This conversion makes sense only for non-collapsed range.\n\t\tif ( data.markerRange.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst descriptor = prepareDescriptor( highlightDescriptor, data, conversionApi );\n\n\t\tif ( !descriptor ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// View element that will be used to unwrap `AttributeElement`s.\n\t\tconst viewHighlightElement = createViewElementFromHighlightDescriptor( conversionApi.writer, descriptor );\n\n\t\t// Get all elements bound with given marker name.\n\t\tconst elements = conversionApi.mapper.markerNameToElements( data.markerName );\n\n\t\tif ( !elements ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const element of elements ) {\n\t\t\tconversionApi.mapper.unbindElementFromMarkerName( element, data.markerName );\n\n\t\t\tif ( element.is( 'attributeElement' ) ) {\n\t\t\t\tconversionApi.writer.unwrap( conversionApi.writer.createRangeOn( element ), viewHighlightElement );\n\t\t\t} else {\n\t\t\t\t// if element.is( 'containerElement' ).\n\t\t\t\tconst removeHighlightCallback = element.getCustomProperty( 'removeHighlight' ) as RemoveHighlightCallback;\n\n\t\t\t\tremoveHighlightCallback( element, descriptor.id!, conversionApi.writer );\n\t\t\t}\n\t\t}\n\n\t\tconversionApi.writer.clearClonedElementsGroup( data.markerName );\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * Model element to view element conversion helper.\n *\n * See {@link ~DowncastHelpers#elementToElement `.elementToElement()` downcast helper} for examples and config params description.\n *\n * @param config Conversion configuration.\n * @param config.model The description or a name of the model element to convert.\n * @param config.model.attributes List of attributes triggering element reconversion.\n * @param config.model.children Should reconvert element if the list of model child nodes changed.\n * @returns Conversion helper.\n */\nfunction downcastElementToElement( config: {\n\tmodel: string | {\n\t\tname: string;\n\t\tattributes?: string | Array<string>;\n\t\tchildren?: boolean;\n\t};\n\tview: ElementDefinition | ElementCreatorFunction;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconst model = normalizeModelElementConfig( config.model );\n\tconst view = normalizeToElementConfig( config.view, 'container' );\n\n\t// Trigger reconversion on children list change if element is a subject to any reconversion.\n\t// This is required to be able to trigger Differ#refreshItem() on a direct child of the reconverted element.\n\tif ( model.attributes.length ) {\n\t\tmodel.children = true;\n\t}\n\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tdispatcher.on<DowncastInsertEvent<ModelElement>>(\n\t\t\t`insert:${ model.name }`,\n\t\t\tinsertElement( view, createConsumer( model ) ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\n\t\tif ( model.children || model.attributes.length ) {\n\t\t\tdispatcher.on<DowncastReduceChangesEvent>( 'reduceChanges', createChangeReducer( model ), { priority: 'low' } );\n\t\t}\n\t};\n}\n\n/**\n * Model element to view structure conversion helper.\n *\n * See {@link ~DowncastHelpers#elementToStructure `.elementToStructure()` downcast helper} for examples and config params description.\n *\n * @param config Conversion configuration.\n * @returns Conversion helper.\n */\nfunction downcastElementToStructure(\n\tconfig: {\n\t\tmodel: string | {\n\t\t\tname: string;\n\t\t\tattributes?: string | Array<string>;\n\t\t};\n\t\tview: StructureCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t}\n) {\n\tconst model = normalizeModelElementConfig( config.model );\n\tconst view = normalizeToElementConfig( config.view, 'container' );\n\n\t// Trigger reconversion on children list change because it always needs to use slots to put children in proper places.\n\t// This is required to be able to trigger Differ#refreshItem() on a direct child of the reconverted element.\n\tmodel.children = true;\n\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tif ( dispatcher._conversionApi.schema.checkChild( model.name, '$text' ) ) {\n\t\t\t/**\n\t\t\t * This error occurs when a {@link module:engine/model/element~Element model element} is downcasted\n\t\t\t * via {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure} helper but the element was\n\t\t\t * allowed to host `$text` by the {@link module:engine/model/schema~Schema model schema}.\n\t\t\t *\n\t\t\t * For instance, this may be the result of `myElement` allowing the content of\n\t\t\t * {@glink framework/deep-dive/schema#generic-items `$block`} in its schema definition:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * // Element definition in schema.\n\t\t\t * schema.register( 'myElement', {\n\t\t\t * \tallowContentOf: '$block',\n\t\t\t *\n\t\t\t * \t// ...\n\t\t\t * } );\n\t\t\t *\n\t\t\t * // ...\n\t\t\t *\n\t\t\t * // Conversion of myElement with the use of elementToStructure().\n\t\t\t * editor.conversion.for( 'downcast' ).elementToStructure( {\n\t\t\t * \tmodel: 'myElement',\n\t\t\t * \tview: ( modelElement, { writer } ) => {\n\t\t\t * \t\t// ...\n\t\t\t * \t}\n\t\t\t * } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * In such case, {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`} helper\n\t\t\t * can be used instead to get around this problem:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * editor.conversion.for( 'downcast' ).elementToElement( {\n\t\t\t * \tmodel: 'myElement',\n\t\t\t * \tview: ( modelElement, { writer } ) => {\n\t\t\t * \t\t// ...\n\t\t\t * \t}\n\t\t\t * } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * @error conversion-element-to-structure-disallowed-text\n\t\t\t * @param {String} elementName The name of the element the structure is to be created for.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-element-to-structure-disallowed-text', dispatcher, { elementName: model.name } );\n\t\t}\n\n\t\tdispatcher.on<DowncastInsertEvent<ModelElement>>(\n\t\t\t`insert:${ model.name }`,\n\t\t\tinsertStructure( view, createConsumer( model ) ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\n\t\tdispatcher.on<DowncastReduceChangesEvent>( 'reduceChanges', createChangeReducer( model ), { priority: 'low' } );\n\t};\n}\n\n/**\n * Model attribute to view element conversion helper.\n *\n * See {@link ~DowncastHelpers#attributeToElement `.attributeToElement()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The key of the attribute to convert from or a `{ key, values }` object. `values` is an array\n * of `String`s with possible values if the model attribute is an enumerable.\n * @param config.view A view element definition or a function that takes the model attribute value and\n * {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} as parameters and returns a view attribute element.\n * If `config.model.values` is given, `config.view` should be an object assigning values from `config.model.values` to view element\n * definitions or functions.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */\nfunction downcastAttributeToElement( config: {\n\tmodel: string | {\n\t\tkey: string;\n\t\tname?: string;\n\t\tvalues?: Array<string>;\n\t};\n\tview: ElementDefinition | AttributeElementCreatorFunction | Record<string, ElementDefinition | AttributeElementCreatorFunction>;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconfig = cloneDeep( config );\n\n\tlet model = config.model;\n\n\tif ( typeof model == 'string' ) {\n\t\tmodel = { key: model };\n\t}\n\n\tlet eventName = `attribute:${ model.key }` as const;\n\n\tif ( model.name ) {\n\t\teventName += ':' + model.name;\n\t}\n\n\tif ( model.values ) {\n\t\tfor ( const modelValue of model.values ) {\n\t\t\t( config.view as any )[ modelValue ] = normalizeToElementConfig( ( config.view as any )[ modelValue ], 'attribute' );\n\t\t}\n\t} else {\n\t\tconfig.view = normalizeToElementConfig( config.view as any, 'attribute' );\n\t}\n\n\tconst elementCreator = getFromAttributeCreator<AttributeElementCreatorFunction>( config );\n\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tdispatcher.on<DowncastAttributeEvent>(\n\t\t\teventName,\n\t\t\twrap( elementCreator ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t};\n}\n\n/**\n * Model attribute to view attribute conversion helper.\n *\n * See {@link ~DowncastHelpers#attributeToAttribute `.attributeToAttribute()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The key of the attribute to convert from or a `{ key, values, [ name ] }` object describing\n * the attribute key, possible values and, optionally, an element name to convert from.\n * @param config.view A view attribute key, or a `{ key, value }` object or a function that takes the model attribute value and returns\n * a `{ key, value }` object.\n * If `key` is `'class'`, `value` can be a `String` or an array of `String`s. If `key` is `'style'`, `value` is an object with\n * key-value pairs. In other cases, `value` is a `String`.\n * If `config.model.values` is set, `config.view` should be an object assigning values from `config.model.values` to\n * `{ key, value }` objects or a functions.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */\nfunction downcastAttributeToAttribute( config: {\n\tmodel: string | {\n\t\tkey: string;\n\t\tname?: string;\n\t\tvalues?: Array<string>;\n\t};\n\tview: string | AttributeDescriptor | AttributeCreatorFunction | Record<string, AttributeDescriptor | AttributeCreatorFunction>;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconfig = cloneDeep( config );\n\n\tlet model = config.model;\n\n\tif ( typeof model == 'string' ) {\n\t\tmodel = { key: model };\n\t}\n\n\tlet eventName = `attribute:${ model.key }` as const;\n\n\tif ( model.name ) {\n\t\teventName += ':' + model.name;\n\t}\n\n\tif ( model.values ) {\n\t\tfor ( const modelValue of model.values ) {\n\t\t\t( config.view as any )[ modelValue ] = normalizeToAttributeConfig( ( config.view as any )[ modelValue ] );\n\t\t}\n\t} else {\n\t\tconfig.view = normalizeToAttributeConfig( config.view );\n\t}\n\n\tconst elementCreator = getFromAttributeCreator<AttributeCreatorFunction>( config );\n\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tdispatcher.on<DowncastAttributeEvent<ModelElement>>(\n\t\t\teventName,\n\t\t\tchangeAttribute( elementCreator ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t};\n}\n\n/**\n * Model marker to view element conversion helper.\n *\n * See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The name of the model marker (or model marker group) to convert.\n * @param config.view A view element definition or a function that takes the model marker data as a parameter and returns a view UI element.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */\nfunction downcastMarkerToElement( config: {\n\tmodel: string;\n\tview: ElementDefinition | MarkerElementCreatorFunction;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconst view = normalizeToElementConfig( config.view, 'ui' );\n\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tdispatcher.on<DowncastAddMarkerEvent>(\n\t\t\t`addMarker:${ config.model }`,\n\t\t\tinsertUIElement( view ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t\tdispatcher.on<DowncastRemoveMarkerEvent>(\n\t\t\t`removeMarker:${ config.model }`,\n\t\t\tremoveUIElement(),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t};\n}\n\n/**\n * Model marker to view data conversion helper.\n *\n * See {@link ~DowncastHelpers#markerToData `markerToData()` downcast helper} to learn more.\n *\n * @returns Conversion helper.\n */\nfunction downcastMarkerToData( config: {\n\tmodel: string;\n\tview?: MarkerDataCreatorFunction;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconfig = cloneDeep( config );\n\n\tconst group = config.model;\n\tlet view = config.view;\n\n\t// Default conversion.\n\tif ( !view ) {\n\t\tview = markerName => ( {\n\t\t\tgroup,\n\t\t\tname: markerName.substr( config.model.length + 1 )\n\t\t} );\n\t}\n\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tdispatcher.on<DowncastAddMarkerEvent>(\n\t\t\t`addMarker:${ group }`,\n\t\t\tinsertMarkerData( view! ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t\tdispatcher.on<DowncastRemoveMarkerEvent>(\n\t\t\t`removeMarker:${ group }`,\n\t\t\tremoveMarkerData( view! ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t};\n}\n\n/**\n * Model marker to highlight conversion helper.\n *\n * See {@link ~DowncastHelpers#markerToElement `.markerToElement()` downcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.model The name of the model marker (or model marker group) to convert.\n * @param config.view A highlight descriptor that will be used for highlighting or a function that takes\n * the model marker data as a parameter and returns a highlight descriptor.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */\nfunction downcastMarkerToHighlight( config: {\n\tmodel: string;\n\tview: HighlightDescriptor | HighlightDescriptorCreatorFunction;\n\tconverterPriority?: PriorityString;\n} ) {\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tdispatcher.on<DowncastAddMarkerEvent>(\n\t\t\t`addMarker:${ config.model }`,\n\t\t\thighlightText( config.view ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t\tdispatcher.on<DowncastAddMarkerEvent>(\n\t\t\t`addMarker:${ config.model }`,\n\t\t\thighlightElement( config.view ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t\tdispatcher.on<DowncastRemoveMarkerEvent>(\n\t\t\t`removeMarker:${ config.model }`,\n\t\t\tremoveHighlight( config.view ),\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t};\n}\n\n/**\n * Takes `config.model`, and converts it to an object with normalized structure.\n *\n * @param model Model configuration or element name.\n */\nfunction normalizeModelElementConfig( model: string | {\n\tname: string;\n\tattributes?: ArrayOrItem<string>;\n\tchildren?: boolean;\n} ): NormalizedModelElementConfig {\n\tif ( typeof model == 'string' ) {\n\t\tmodel = { name: model };\n\t}\n\n\treturn {\n\t\tname: model.name,\n\t\tattributes: model.attributes ? toArray( model.attributes ) : [],\n\t\tchildren: !!model.children\n\t};\n}\n\ninterface NormalizedModelElementConfig {\n\tname: string;\n\n\t/**\n\t * List of attributes that should trigger reconversion.\n\t */\n\tattributes: Array<string>;\n\n\t/**\n\t * Whether children insertion/deletion should trigger reconversion.\n\t */\n\tchildren: boolean;\n}\n\n/**\n * Takes `config.view`, and if it is an {@link module:engine/view/elementdefinition~ElementDefinition}, converts it\n * to a function (because lower level converters accept only element creator functions).\n *\n * @param view View configuration.\n * @param viewElementType View element type to create.\n * @returns Element creator function to use in lower level converters.\n */\nfunction normalizeToElementConfig<T extends Function>(\n\tview: ElementDefinition | T,\n\tviewElementType: 'container' | 'attribute' | 'ui'\n): T {\n\tif ( typeof view == 'function' ) {\n\t\t// If `view` is already a function, don't do anything.\n\t\treturn view as any;\n\t}\n\n\treturn ( ( modelData: unknown, conversionApi: DowncastConversionApi ) =>\n\t\tcreateViewElementFromDefinition( view, conversionApi, viewElementType ) ) as any;\n}\n\n/**\n * Creates a view element instance from the provided {@link module:engine/view/elementdefinition~ElementDefinition} and class.\n */\nfunction createViewElementFromDefinition(\n\tviewElementDefinition: ElementDefinition,\n\tconversionApi: DowncastConversionApi,\n\tviewElementType: 'container' | 'attribute' | 'ui'\n): ViewElement {\n\tif ( typeof viewElementDefinition == 'string' ) {\n\t\t// If `viewElementDefinition` is given as a `String`, normalize it to an object with `name` property.\n\t\tviewElementDefinition = { name: viewElementDefinition };\n\t}\n\n\tlet element: ViewElement;\n\tconst viewWriter = conversionApi.writer;\n\tconst attributes = Object.assign( {}, viewElementDefinition.attributes );\n\n\tif ( viewElementType == 'container' ) {\n\t\telement = viewWriter.createContainerElement( viewElementDefinition.name, attributes );\n\t} else if ( viewElementType == 'attribute' ) {\n\t\tconst options = {\n\t\t\tpriority: viewElementDefinition.priority || ViewAttributeElement.DEFAULT_PRIORITY\n\t\t};\n\n\t\telement = viewWriter.createAttributeElement( viewElementDefinition.name, attributes, options );\n\t} else {\n\t\t// 'ui'.\n\t\telement = viewWriter.createUIElement( viewElementDefinition.name, attributes );\n\t}\n\n\tif ( viewElementDefinition.styles ) {\n\t\tconst keys = Object.keys( viewElementDefinition.styles );\n\n\t\tfor ( const key of keys ) {\n\t\t\tviewWriter.setStyle( key, viewElementDefinition.styles[ key ], element );\n\t\t}\n\t}\n\n\tif ( viewElementDefinition.classes ) {\n\t\tconst classes = viewElementDefinition.classes;\n\n\t\tif ( typeof classes == 'string' ) {\n\t\t\tviewWriter.addClass( classes, element );\n\t\t} else {\n\t\t\tfor ( const className of classes ) {\n\t\t\t\tviewWriter.addClass( className, element );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn element;\n}\n\nfunction getFromAttributeCreator<T extends AttributeElementCreatorFunction | AttributeCreatorFunction>( config: any ): T {\n\tif ( config.model.values ) {\n\t\treturn ( ( modelAttributeValue: any, conversionApi: DowncastConversionApi, data: any ) => {\n\t\t\tconst view = config.view[ modelAttributeValue ];\n\n\t\t\tif ( view ) {\n\t\t\t\treturn view( modelAttributeValue, conversionApi, data );\n\t\t\t}\n\n\t\t\treturn null;\n\t\t} ) as any;\n\t} else {\n\t\treturn config.view;\n\t}\n}\n\n/**\n * Takes the configuration, adds default parameters if they do not exist and normalizes other parameters to be used in downcast converters\n * for generating a view attribute.\n *\n * @param view View configuration.\n */\nfunction normalizeToAttributeConfig( view: any ): AttributeCreatorFunction {\n\tif ( typeof view == 'string' ) {\n\t\treturn modelAttributeValue => ( { key: view, value: modelAttributeValue as string } );\n\t} else if ( typeof view == 'object' ) {\n\t\t// { key, value, ... }\n\t\tif ( view.value ) {\n\t\t\treturn () => view;\n\t\t}\n\t\t// { key, ... }\n\t\telse {\n\t\t\treturn modelAttributeValue => ( { key: view.key, value: modelAttributeValue as string } );\n\t\t}\n\t} else {\n\t\t// function.\n\t\treturn view;\n\t}\n}\n\n/**\n * Helper function for `highlight`. Prepares the actual descriptor object using value passed to the converter.\n */\nfunction prepareDescriptor(\n\thighlightDescriptor: HighlightDescriptor | HighlightDescriptorCreatorFunction,\n\tdata: {\n\t\tmarkerName: string;\n\t\tmarkerRange: ModelRange;\n\t},\n\tconversionApi: DowncastConversionApi\n): HighlightDescriptor | null {\n\t// If passed descriptor is a creator function, call it. If not, just use passed value.\n\tconst descriptor = typeof highlightDescriptor == 'function' ?\n\t\thighlightDescriptor( data, conversionApi ) :\n\t\thighlightDescriptor;\n\n\tif ( !descriptor ) {\n\t\treturn null;\n\t}\n\n\t// Apply default descriptor priority.\n\tif ( !descriptor.priority ) {\n\t\tdescriptor.priority = 10;\n\t}\n\n\t// Default descriptor id is marker name.\n\tif ( !descriptor.id ) {\n\t\tdescriptor.id = data.markerName;\n\t}\n\n\treturn descriptor;\n}\n\n/**\n * Creates a function that checks a single differ diff item whether it should trigger reconversion.\n *\n * @param model A normalized `config.model` converter configuration.\n * @param model.name The name of element.\n * @param model.attributes The list of attribute names that should trigger reconversion.\n * @param model.children Whether the child list change should trigger reconversion.\n */\nfunction createChangeReducerCallback( model: NormalizedModelElementConfig ) {\n\treturn ( node: ModelNode, change: DiffItem | DiffItemReinsert ): boolean => {\n\t\tif ( !node.is( 'element', model.name ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( change.type == 'attribute' ) {\n\t\t\tif ( model.attributes.includes( change.attributeKey ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else {\n\t\t\t/* istanbul ignore else: This is always true because otherwise it would not register a reducer callback. -- @preserve */\n\t\t\tif ( model.children ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t};\n}\n\n/**\n * Creates a `reduceChanges` event handler for reconversion.\n *\n * @param model A normalized `config.model` converter configuration.\n * @param model.name The name of element.\n * @param model.attributes The list of attribute names that should trigger reconversion.\n * @param model.children Whether the child list change should trigger reconversion.\n */\nfunction createChangeReducer( model: NormalizedModelElementConfig ) {\n\tconst shouldReplace = createChangeReducerCallback( model );\n\n\treturn (\n\t\tevt: unknown,\n\t\tdata: { changes: Iterable<DiffItem | DiffItemReinsert>; reconvertedElements?: Set<ModelNode> }\n\t) => {\n\t\tconst reducedChanges: Array<DiffItem | DiffItemReinsert> = [];\n\n\t\tif ( !data.reconvertedElements ) {\n\t\t\tdata.reconvertedElements = new Set();\n\t\t}\n\n\t\tfor ( const change of data.changes ) {\n\t\t\t// For attribute use node affected by the change.\n\t\t\t// For insert or remove use parent element because we need to check if it's added/removed child.\n\t\t\tconst node = change.type == 'attribute' ? change.range.start.nodeAfter : change.position.parent as ModelNode;\n\n\t\t\tif ( !node || !shouldReplace( node, change ) ) {\n\t\t\t\treducedChanges.push( change );\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If it's already marked for reconversion, so skip this change, otherwise add the diff items.\n\t\t\tif ( !data.reconvertedElements.has( node ) ) {\n\t\t\t\tdata.reconvertedElements.add( node );\n\n\t\t\t\tconst position = ModelPosition._createBefore( node );\n\t\t\t\tlet changeIndex = reducedChanges.length;\n\n\t\t\t\t// We need to insert remove+reinsert before any other change on and inside the re-converted element.\n\t\t\t\t// This is important because otherwise we would remove element that had already been modified by the previous change.\n\t\t\t\t// Note that there could be some element removed before the re-converted element, so we must not break this behavior.\n\t\t\t\tfor ( let i = reducedChanges.length - 1; i >= 0; i-- ) {\n\t\t\t\t\tconst change = reducedChanges[ i ];\n\t\t\t\t\tconst changePosition = change.type == 'attribute' ? change.range.start : change.position;\n\t\t\t\t\tconst positionRelation = changePosition.compareWith( position );\n\n\t\t\t\t\tif ( positionRelation == 'before' || change.type == 'remove' && positionRelation == 'same' ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tchangeIndex = i;\n\t\t\t\t}\n\n\t\t\t\treducedChanges.splice( changeIndex, 0, {\n\t\t\t\t\ttype: 'remove',\n\t\t\t\t\tname: ( node as ModelElement ).name,\n\t\t\t\t\tposition,\n\t\t\t\t\tlength: 1\n\t\t\t\t} as any, {\n\t\t\t\t\ttype: 'reinsert',\n\t\t\t\t\tname: ( node as ModelElement ).name,\n\t\t\t\t\tposition,\n\t\t\t\t\tlength: 1\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\tdata.changes = reducedChanges;\n\t};\n}\n\n/**\n * Creates a function that checks if an element and its watched attributes can be consumed and consumes them.\n *\n * @param model A normalized `config.model` converter configuration.\n * @param model.name The name of element.\n * @param model.attributes The list of attribute names that should trigger reconversion.\n * @param model.children Whether the child list change should trigger reconversion.\n */\nfunction createConsumer( model: NormalizedModelElementConfig ): ConsumerFunction {\n\treturn ( node, consumable, options = {} ) => {\n\t\tconst events = [ 'insert' ];\n\n\t\t// Collect all set attributes that are triggering conversion.\n\t\tfor ( const attributeName of model.attributes ) {\n\t\t\tif ( node.hasAttribute( attributeName ) ) {\n\t\t\t\tevents.push( `attribute:${ attributeName }` );\n\t\t\t}\n\t\t}\n\n\t\tif ( !events.every( event => consumable.test( node, event ) ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !options.preflight ) {\n\t\t\tevents.forEach( event => consumable.consume( node, event ) );\n\t\t}\n\n\t\treturn true;\n\t};\n}\n\n/**\n * Creates a function that create view slots.\n *\n * @returns Function exposed by writer as createSlot().\n */\nfunction createSlotFactory( element: ModelElement, slotsMap: Map<ViewElement, Array<ModelNode>>, conversionApi: DowncastConversionApi ) {\n\treturn ( writer: DowncastWriter, modeOrFilter: 'children' | SlotFilter ) => {\n\t\tconst slot = writer.createContainerElement( '$slot' );\n\n\t\tlet children: Array<ModelNode> | null = null;\n\n\t\tif ( modeOrFilter === 'children' ) {\n\t\t\tchildren = Array.from( element.getChildren() );\n\t\t} else if ( typeof modeOrFilter == 'function' ) {\n\t\t\tchildren = Array.from( element.getChildren() ).filter( element => modeOrFilter( element ) );\n\t\t} else {\n\t\t\t/**\n\t\t\t * Unknown slot mode was provided to `writer.createSlot()` in downcast converter.\n\t\t\t *\n\t\t\t * @error conversion-slot-mode-unknown\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-slot-mode-unknown', conversionApi.dispatcher, { modeOrFilter } );\n\t\t}\n\n\t\tslotsMap.set( slot, children );\n\n\t\treturn slot;\n\t};\n}\n\n/**\n * Checks if all children are covered by slots and there is no child that landed in multiple slots.\n */\nfunction validateSlotsChildren(\n\telement: ModelElement,\n\tslotsMap: Map<ViewElement, Array<ModelNode>>,\n\tconversionApi: DowncastConversionApi\n) {\n\tconst childrenInSlots = Array.from( slotsMap.values() ).flat();\n\tconst uniqueChildrenInSlots = new Set( childrenInSlots );\n\n\tif ( uniqueChildrenInSlots.size != childrenInSlots.length ) {\n\t\t/**\n\t\t * Filters provided to `writer.createSlot()` overlap (at least two filters accept the same child element).\n\t\t *\n\t\t * @error conversion-slot-filter-overlap\n\t\t * @param {module:engine/model/element~Element} element The element of which children would not be properly\n\t\t * allocated to multiple slots.\n\t\t */\n\t\tthrow new CKEditorError( 'conversion-slot-filter-overlap', conversionApi.dispatcher, { element } );\n\t}\n\n\tif ( uniqueChildrenInSlots.size != element.childCount ) {\n\t\t/**\n\t\t * Filters provided to `writer.createSlot()` are incomplete and exclude at least one children element (one of\n\t\t * the children elements would not be assigned to any of the slots).\n\t\t *\n\t\t * @error conversion-slot-filter-incomplete\n\t\t * @param {module:engine/model/element~Element} element The element of which children would not be properly\n\t\t * allocated to multiple slots.\n\t\t */\n\t\tthrow new CKEditorError( 'conversion-slot-filter-incomplete', conversionApi.dispatcher, { element } );\n\t}\n}\n\n/**\n * Fill slots with appropriate view elements.\n */\nfunction fillSlots(\n\tviewElement: ViewElement,\n\tslotsMap: Map<ViewElement, Array<ModelNode>>,\n\tconversionApi: DowncastConversionApi,\n\toptions: { reconversion?: boolean }\n): void {\n\t// Set temporary position mapping to redirect child view elements into a proper slots.\n\tconversionApi.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', toViewPositionMapping, { priority: 'highest' } );\n\n\tlet currentSlot: ViewElement | null = null;\n\tlet currentSlotNodes: Array<ModelNode> | null = null;\n\n\t// Fill slots with nested view nodes.\n\tfor ( [ currentSlot, currentSlotNodes ] of slotsMap ) {\n\t\treinsertOrConvertNodes( viewElement, currentSlotNodes, conversionApi, options );\n\n\t\tconversionApi.writer.move(\n\t\t\tconversionApi.writer.createRangeIn( currentSlot ),\n\t\t\tconversionApi.writer.createPositionBefore( currentSlot )\n\t\t);\n\t\tconversionApi.writer.remove( currentSlot );\n\t}\n\n\tconversionApi.mapper.off( 'modelToViewPosition', toViewPositionMapping );\n\n\tfunction toViewPositionMapping( evt: unknown, data: {\n\t\tmapper: Mapper;\n\t\tmodelPosition: ModelPosition;\n\t\tviewPosition?: ViewPosition;\n\t\tisPhantom?: boolean;\n\t} ) {\n\t\tconst element = data.modelPosition.nodeAfter!;\n\n\t\t// Find the proper offset within the slot.\n\t\tconst index = currentSlotNodes!.indexOf( element );\n\n\t\tif ( index < 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdata.viewPosition = data.mapper.findPositionIn( currentSlot!, index );\n\t}\n}\n\n/**\n * Inserts view representation of `nodes` into the `viewElement` either by bringing back just removed view nodes\n * or by triggering conversion for them.\n */\nfunction reinsertOrConvertNodes(\n\tviewElement: ViewElement,\n\tmodelNodes: Iterable<ModelNode>,\n\tconversionApi: DowncastConversionApi,\n\toptions: { reconversion?: boolean }\n) {\n\t// Fill with nested view nodes.\n\tfor ( const modelChildNode of modelNodes ) {\n\t\t// Try reinserting the view node for the specified model node...\n\t\tif ( !reinsertNode( viewElement.root, modelChildNode, conversionApi, options ) ) {\n\t\t\t// ...or else convert the model element to the view.\n\t\t\tconversionApi.convertItem( modelChildNode );\n\t\t}\n\t}\n}\n\n/**\n * Checks if the view for the given model element could be reused and reinserts it to the view.\n *\n * @returns `false` if view element can't be reused.\n */\nfunction reinsertNode(\n\tviewRoot: ViewElement | ViewDocumentFragment,\n\tmodelNode: ModelNode,\n\tconversionApi: DowncastConversionApi,\n\toptions: { reconversion?: boolean }\n): boolean {\n\tconst { writer, mapper } = conversionApi;\n\n\t// Don't reinsert if this is not a reconversion...\n\tif ( !options.reconversion ) {\n\t\treturn false;\n\t}\n\n\tconst viewChildNode = mapper.toViewElement( modelNode as ModelElement );\n\n\t// ...or there is no view to reinsert or it was already inserted to the view structure...\n\tif ( !viewChildNode || viewChildNode.root == viewRoot ) {\n\t\treturn false;\n\t}\n\n\t// ...or it was strictly marked as not to be reused.\n\tif ( !conversionApi.canReuseView( viewChildNode ) ) {\n\t\treturn false;\n\t}\n\n\t// Otherwise reinsert the view node.\n\twriter.move(\n\t\twriter.createRangeOn( viewChildNode ),\n\t\tmapper.toViewPosition( ModelPosition._createBefore( modelNode ) )\n\t);\n\n\treturn true;\n}\n\n/**\n * The default consumer for insert events.\n *\n * @param item Model item.\n * @param consumable The model consumable.\n * @param options.preflight Whether should consume or just check if can be consumed.\n */\nfunction defaultConsumer(\n\titem: ModelItem,\n\tconsumable: ModelConsumable,\n\t{ preflight }: { preflight?: boolean } = {}\n): boolean | null {\n\tif ( preflight ) {\n\t\treturn consumable.test( item, 'insert' );\n\t} else {\n\t\treturn consumable.consume( item, 'insert' );\n\t}\n}\n\n/**\n * An object describing how the marker highlight should be represented in the view.\n *\n * Each text node contained in a highlighted range will be wrapped in a `<span>`\n * {@link module:engine/view/attributeelement~AttributeElement view attribute element} with CSS class(es), attributes and a priority\n * described by this object.\n *\n * Additionally, each {@link module:engine/view/containerelement~ContainerElement container element} can handle displaying the highlight\n * separately by providing the `addHighlight` and `removeHighlight` custom properties. In this case:\n *\n *  * The `HighlightDescriptor` object is passed to the `addHighlight` function upon conversion and should be used to apply the highlight to\n *  the element.\n *  * The descriptor `id` is passed to the `removeHighlight` function upon conversion and should be used to remove the highlight with the\n *  given ID from the element.\n */\nexport interface HighlightDescriptor {\n\n\t/**\n\t * A CSS class or an array of classes to set. If the descriptor is used to\n\t * create an {@link module:engine/view/attributeelement~AttributeElement attribute element} over text nodes, these classes will be set\n\t * on that attribute element. If the descriptor is applied to an element, usually these classes will be set on that element, however,\n\t * this depends on how the element converts the descriptor.\n\t */\n\tclasses: string | Array<string>;\n\n\t/**\n\t * Descriptor identifier. If not provided, it defaults to the converted marker's name.\n\t */\n\tid?: string;\n\n\t/**\n\t * Descriptor priority. If not provided, it defaults to `10`. If the descriptor is used to create\n\t * an {@link module:engine/view/attributeelement~AttributeElement attribute element}, it will be that element's\n\t * {@link module:engine/view/attributeelement~AttributeElement#priority priority}. If the descriptor is applied to an element,\n\t * the priority will be used to determine which descriptor is more important.\n\t */\n\tpriority?: number;\n\n\t/**\n\t * Attributes to set. If the descriptor is used to create\n\t * an {@link module:engine/view/attributeelement~AttributeElement attribute element} over text nodes, these attributes will be set\n\t * on that attribute element. If the descriptor is applied to an element, usually these attributes will be set on that element, however,\n\t * this depends on how the element converts the descriptor.\n\t */\n\tattributes?: Record<string, string>;\n}\n\n/**\n * A filtering function used to choose model child nodes to be downcasted into the specific view\n * {@link module:engine/view/downcastwriter~DowncastWriter#createSlot \"slot\"} while executing the\n * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure `elementToStructure()`} converter.\n *\n * @callback module:engine/conversion/downcasthelpers~SlotFilter\n *\n * @param node A model node.\n * @returns Whether the provided model node should be downcasted into this slot.\n *\n * @see module:engine/view/downcastwriter~DowncastWriter#createSlot\n * @see module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n * @see module:engine/conversion/downcasthelpers~insertStructure\n */\nexport type SlotFilter = ( node: ModelNode ) => boolean;\n\n/**\n * A view element creator function that takes the model element and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi\n * downcast conversion API} as parameters and returns a view container element.\n *\n * @callback module:engine/conversion/downcasthelpers~ElementCreatorFunction\n *\n * @param element The model element to be converted to the view structure.\n * @param conversionApi The conversion interface.\n * @param data Additional information about the change (same as for\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`} event).\n * @param data.item Inserted item.\n * @param data.range Range spanning over inserted item.\n * @returns The view element.\n *\n * @see module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement\n * @see module:engine/conversion/downcasthelpers~insertElement\n */\nexport type ElementCreatorFunction = (\n\telement: ModelElement,\n\tconversionApi: DowncastConversionApi,\n\tdata: {\n\t\titem: ModelItem;\n\t\trange: ModelRange;\n\t}\n) => ViewElement | null;\n\n/**\n * A function that takes the model element and {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast\n * conversion API} as parameters and returns a view container element with slots for model child nodes to be converted into.\n *\n * @callback module:engine/conversion/downcasthelpers~StructureCreatorFunction\n *\n * @param element The model element to be converted to the view structure.\n * @param conversionApi The conversion interface.\n * @param data Additional information about the change (same as for\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`} event).\n * @param data.item Inserted item.\n * @param data.range Range spanning over inserted item.\n * @returns The view structure with slots for model child nodes.\n *\n * @see module:engine/conversion/downcasthelpers~DowncastHelpers#elementToStructure\n * @see module:engine/conversion/downcasthelpers~insertStructure\n */\nexport type StructureCreatorFunction = ElementCreatorFunction;\n\n/**\n * A view element creator function that takes the model attribute value and\n * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API} as parameters and returns a view\n * attribute element.\n *\n * @callback module:engine/conversion/downcasthelpers~AttributeElementCreatorFunction\n *\n * @param attributeValue The model attribute value to be converted to the view attribute element.\n * @param conversionApi The conversion interface.\n * @param data Additional information about the change (same as for\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`} event).\n * @param data.item Changed item or converted selection.\n * @param data.range Range spanning over changed item or selection range.\n * @param data.attributeKey Attribute key.\n * @param data.attributeOldValue Attribute value before the change. This is `null` when selection attribute is converted.\n * @param data.attributeNewValue New attribute value.\n * @returns The view attribute element.\n *\n * @see module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement\n * @see module:engine/conversion/downcasthelpers~wrap\n */\nexport type AttributeElementCreatorFunction = (\n\tattributeValue: any,\n\tconversionApi: DowncastConversionApi,\n\tdata: {\n\t\titem: ModelItem | ModelSelection | ModelDocumentSelection;\n\t\trange: ModelRange;\n\t\tattributeKey: string;\n\t\tattributeOldValue: unknown;\n\t\tattributeNewValue: unknown;\n\t}\n) => ViewAttributeElement | null;\n\n/**\n * A function that takes the model attribute value and\n * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi downcast conversion API}\n * as parameters.\n *\n * @callback module:engine/conversion/downcasthelpers~AttributeCreatorFunction\n *\n * @param attributeValue The model attribute value to be converted to the view attribute element.\n * @param conversionApi The conversion interface.\n * @param data Additional information about the change (same as for\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`} event).\n * @param data.item Changed item or converted selection.\n * @param data.range Range spanning over changed item or selection range.\n * @param data.attributeKey Attribute key.\n * @param data.attributeOldValue Attribute value before the change. This is `null` when selection attribute is converted.\n * @param data.attributeNewValue New attribute value.\n * @returns A `{ key, value }` object. If `key` is `'class'`, `value` can be a `String` or an\n * array of `String`s. If `key` is `'style'`, `value` is an object with key-value pairs. In other cases, `value` is a `String`.\n *\n * @see module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToAttribute\n */\nexport type AttributeCreatorFunction = (\n\tattributeValue: unknown,\n\tconversionApi: DowncastConversionApi,\n\tdata: {\n\t\titem: ModelItem;\n\t\trange: ModelRange;\n\t\tattributeKey: string;\n\t\tattributeOldValue: unknown;\n\t\tattributeNewValue: unknown;\n\t}\n) => AttributeDescriptor | null;\n\nexport type AttributeDescriptor = {\n\tkey: 'class';\n\tvalue: string | Array<string>;\n} | {\n\tkey: 'style';\n\tvalue: Record<string, string>;\n} | {\n\tkey: Exclude<string, 'class' | 'style'>;\n\tvalue: string;\n};\n\nexport type MarkerElementCreatorFunction = (\n\tdata: {\n\t\tmarkerRange: ModelRange;\n\t\tmarkerName: string;\n\t\tisOpening?: boolean;\n\t},\n\tconversionApi: DowncastConversionApi\n) => UIElement | null;\n\nexport type HighlightDescriptorCreatorFunction = (\n\tdata: {\n\t\tmarkerRange: ModelRange;\n\t\tmarkerName: string;\n\t},\n\tconversionApi: DowncastConversionApi\n) => HighlightDescriptor | null;\n\nexport type AddHighlightCallback = (\n\tviewElement: ViewElement,\n\tdescriptor: HighlightDescriptor,\n\twriter: DowncastWriter\n) => void;\n\nexport type RemoveHighlightCallback = (\n\tviewElement: ViewElement,\n\tid: string,\n\twriter: DowncastWriter\n) => void;\n\nexport type MarkerDataCreatorFunction = (\n\tmarkerName: string,\n\tconversionApi: DowncastConversionApi\n) => { name: string; group: string } | null;\n\n/**\n * A function that is expected to consume all the consumables that were used by the element creator.\n *\n * @callback module:engine/conversion/downcasthelpers~ConsumerFunction\n *\n * @param element The model element to be converted to the view structure.\n * @param consumable The `ModelConsumable` same as in\n * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi#consumable `DowncastConversionApi.consumable`}.\n * @param options.preflight Whether should consume or just check if can be consumed.\n * @returns `true` if all consumable values were available and were consumed, `false` otherwise.\n *\n * @see module:engine/conversion/downcasthelpers~insertStructure\n */\nexport type ConsumerFunction = (\n\telement: ModelElement,\n\tconsumable: ModelConsumable,\n\toptions?: { preflight?: boolean }\n) => boolean | null;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type Node from '../node.js';\nimport type Position from '../position.js';\nimport type Schema from '../schema.js';\nimport type Writer from '../writer.js';\n\n/**\n * @module engine/model/utils/autoparagraphing\n */\n\n/**\n * Fixes all empty roots.\n *\n * @internal\n * @param writer The model writer.\n * @returns `true` if any change has been applied, `false` otherwise.\n */\nexport function autoParagraphEmptyRoots( writer: Writer ): boolean {\n\tconst { schema, document } = writer.model;\n\n\tfor ( const root of document.getRoots() ) {\n\t\tif ( root.isEmpty && !schema.checkChild( root, '$text' ) ) {\n\t\t\t// If paragraph element is allowed in the root, create paragraph element.\n\t\t\tif ( schema.checkChild( root, 'paragraph' ) ) {\n\t\t\t\twriter.insertElement( 'paragraph', root );\n\n\t\t\t\t// Other roots will get fixed in the next post-fixer round. Those will be triggered\n\t\t\t\t// in the same batch no matter if this method was triggered by the post-fixing or not\n\t\t\t\t// (the above insertElement call will trigger the post-fixers).\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Checks if the given node wrapped with a paragraph would be accepted by the schema in the given position.\n *\n * @internal\n * @param position The position at which to check.\n * @param nodeOrType The child node or child type to check.\n * @param schema A schema instance used for element validation.\n */\nexport function isParagraphable(\n\tposition: Position,\n\tnodeOrType: Node | string,\n\tschema: Schema\n): boolean {\n\tconst context = schema.createContext( position );\n\n\t// When paragraph is allowed in this context...\n\tif ( !schema.checkChild( context, 'paragraph' ) ) {\n\t\treturn false;\n\t}\n\n\t// And a node would be allowed in this paragraph...\n\tif ( !schema.checkChild( context.push( 'paragraph' ), nodeOrType ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Inserts a new paragraph at the given position and returns a position inside that paragraph.\n *\n * @internal\n * @param position The position where a paragraph should be inserted.\n * @param writer The model writer.\n * @returns  Position inside the created paragraph.\n */\nexport function wrapInParagraph( position: Position, writer: Writer ): Position {\n\tconst paragraph = writer.createElement( 'paragraph' );\n\n\twriter.insert( paragraph, position );\n\n\treturn writer.createPositionAt( paragraph, 0 );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport Matcher, { type ClassPatterns, type MatcherPattern, type PropertyPatterns } from '../view/matcher.js';\nimport ConversionHelpers from './conversionhelpers.js';\n\nimport type { default as UpcastDispatcher, UpcastElementEvent, UpcastConversionApi, UpcastConversionData } from './upcastdispatcher.js';\nimport type ModelElement from '../model/element.js';\nimport type ModelRange from '../model/range.js';\nimport type ModelPosition from '../model/position.js';\nimport type { ViewDocumentFragment, ViewElement, ViewText } from '../index.js';\nimport type Mapper from './mapper.js';\nimport type Model from '../model/model.js';\nimport type ViewSelection from '../view/selection.js';\nimport type ViewDocumentSelection from '../view/documentselection.js';\nimport { isParagraphable, wrapInParagraph } from '../model/utils/autoparagraphing.js';\n\nimport { priorities, type EventInfo, type PriorityString } from '@ckeditor/ckeditor5-utils';\n\nimport { cloneDeep } from 'lodash-es';\n\n/**\n * Contains the {@link module:engine/view/view view} to {@link module:engine/model/model model} converters for\n * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}.\n *\n * @module engine/conversion/upcasthelpers\n */\n\n/**\n * Upcast conversion helper functions.\n *\n * Learn more about {@glink framework/deep-dive/conversion/upcast upcast helpers}.\n *\n * @extends module:engine/conversion/conversionhelpers~ConversionHelpers\n */\nexport default class UpcastHelpers extends ConversionHelpers<UpcastDispatcher> {\n\t/**\n\t * View element to model element conversion helper.\n\t *\n\t * This conversion results in creating a model element. For example,\n\t * view `<p>Foo</p>` becomes `<paragraph>Foo</paragraph>` in the model.\n\t *\n\t * Keep in mind that the element will be inserted only if it is allowed\n\t * by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: 'p',\n\t * \tmodel: 'paragraph'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: 'p',\n\t * \tmodel: 'paragraph',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'fancy'\n\t * \t},\n\t * \tmodel: 'fancyParagraph'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToElement( {\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'heading'\n\t * \t},\n\t * \tmodel: ( viewElement, conversionApi ) => {\n\t * \t\tconst modelWriter = conversionApi.writer;\n\t *\n\t * \t\treturn modelWriter.createElement( 'heading', { level: viewElement.getAttribute( 'data-level' ) } );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Pattern matching all view elements which should be converted. If not set, the converter\n\t * will fire for every view element.\n\t * @param config.model Name of the model element, a model element instance or a function that takes a view element\n\t * and {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API}\n\t * and returns a model element. The model element will be inserted in the model.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic elementToElement( config: {\n\t\tview: MatcherPattern;\n\t\tmodel: string | ElementCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( upcastElementToElement( config ) );\n\t}\n\n\t/**\n\t * View element to model attribute conversion helper.\n\t *\n\t * This conversion results in setting an attribute on a model node. For example, view `<strong>Foo</strong>` becomes\n\t * `Foo` {@link module:engine/model/text~Text model text node} with `bold` attribute set to `true`.\n\t *\n\t * This helper is meant to set a model attribute on all the elements that are inside the converted element:\n\t *\n\t * ```\n\t * <strong>Foo</strong>   -->   <strong><p>Foo</p></strong>   -->   <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t * ```\n\t *\n\t * Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t * Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text. See\n\t * {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute} for comparison.\n\t *\n\t * Keep in mind that the attribute will be set only if it is allowed by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: 'strong',\n\t * \tmodel: 'bold'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: 'strong',\n\t * \tmodel: 'bold',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: 'bold'\n\t * \t},\n\t * \tmodel: 'bold'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: [ 'styled', 'styled-dark' ]\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'styled',\n\t * \t\tvalue: 'dark'\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tstyles: {\n\t * \t\t\t'font-size': /[\\s\\S]+/\n\t * \t\t}\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'fontSize',\n\t * \t\tvalue: ( viewElement, conversionApi ) => {\n\t * \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t * \t\t\tconst value = fontSize.substr( 0, fontSize.length - 2 );\n\t *\n\t * \t\t\tif ( value <= 10 ) {\n\t * \t\t\t\treturn 'small';\n\t * \t\t\t} else if ( value > 12 ) {\n\t * \t\t\t\treturn 'big';\n\t * \t\t\t}\n\t *\n\t * \t\t\treturn null;\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Pattern matching all view elements which should be converted.\n\t * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n\t * the model attribute. `value` property may be set as a function that takes a view element and\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the value.\n\t * If `String` is given, the model attribute value will be set to `true`.\n\t * @param config.converterPriority Converter priority. Defaults to `low`.\n\t */\n\tpublic elementToAttribute( config: {\n\t\tview: MatcherPattern;\n\t\tmodel: string | {\n\t\t\tkey: string;\n\t\t\tvalue?: unknown;\n\t\t};\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( upcastElementToAttribute( config ) );\n\t}\n\n\t/**\n\t * View attribute to model attribute conversion helper.\n\t *\n\t * This conversion results in setting an attribute on a model node. For example, view `<img src=\"foo.jpg\"></img>` becomes\n\t * `<imageBlock source=\"foo.jpg\"></imageBlock>` in the model.\n\t *\n\t * This helper is meant to convert view attributes from view elements which got converted to the model, so the view attribute\n\t * is set only on the corresponding model node:\n\t *\n\t * ```\n\t * <div class=\"dark\"><div>foo</div></div>    -->    <div dark=\"true\"><div>foo</div></div>\n\t * ```\n\t *\n\t * Above, `class=\"dark\"` attribute is added only to the `<div>` elements that has it. This is in contrast to\n\t * {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute} which sets attributes for\n\t * all the children in the model:\n\t *\n\t * ```\n\t * <strong>Foo</strong>   -->   <strong><p>Foo</p></strong>   -->   <paragraph><$text bold=\"true\">Foo</$text></paragraph>\n\t * ```\n\t *\n\t * Above is a sample of HTML code, that goes through autoparagraphing (first step) and then is converted (second step).\n\t * Even though `<strong>` is over `<p>` element, `bold=\"true\"` was added to the text.\n\t *\n\t * Keep in mind that the attribute will be set only if it is allowed by {@link module:engine/model/schema~Schema schema} configuration.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: 'src',\n\t * \tmodel: 'source'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: { key: 'src' },\n\t * \tmodel: 'source'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: { key: 'src' },\n\t * \tmodel: 'source',\n\t * \tconverterPriority: 'normal'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tkey: 'data-style',\n\t * \t\tvalue: /[\\s\\S]+/\n\t * \t},\n\t * \tmodel: 'styled'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tname: 'img',\n\t * \t\tkey: 'class',\n\t * \t\tvalue: 'styled-dark'\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'styled',\n\t * \t\tvalue: 'dark'\n\t * \t}\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tkey: 'class',\n\t * \t\tvalue: /styled-[\\S]+/\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'styled'\n\t * \t\tvalue: ( viewElement, conversionApi ) => {\n\t * \t\t\tconst regexp = /styled-([\\S]+)/;\n\t * \t\t\tconst match = viewElement.getAttribute( 'class' ).match( regexp );\n\t *\n\t * \t\t\treturn match[ 1 ];\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Converting styles works a bit differently as it requires `view.styles` to be an object and by default\n\t * a model attribute will be set to `true` by such a converter. You can set the model attribute to any value by providing the `value`\n\t * callback that returns the desired value.\n\t *\n\t * ```ts\n\t * // Default conversion of font-weight style will result in setting bold attribute to true.\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tstyles: {\n\t * \t\t\t'font-weight': 'bold'\n\t * \t\t}\n\t * \t},\n\t * \tmodel: 'bold'\n\t * } );\n\t *\n\t * // This converter will pass any style value to the `lineHeight` model attribute.\n\t * editor.conversion.for( 'upcast' ).attributeToAttribute( {\n\t * \tview: {\n\t * \t\tstyles: {\n\t * \t\t\t'line-height': /[\\s\\S]+/\n\t * \t\t}\n\t * \t},\n\t * \tmodel: {\n\t * \t\tkey: 'lineHeight',\n\t * \t\tvalue: ( viewElement, conversionApi ) => viewElement.getStyle( 'line-height' )\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Specifies which view attribute will be converted. If a `String` is passed,\n\t * attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n\t * specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n\t * property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n\t * a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n\t * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n\t * the model attribute. `value` property may be set as a function that takes a view element and\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the value.\n\t * If `String` is given, the model attribute value will be same as view attribute value.\n\t * @param config.converterPriority Converter priority. Defaults to `low`.\n\t */\n\tpublic attributeToAttribute( config: {\n\t\tview: string | {\n\t\t\tkey: string;\n\t\t\tvalue?: string | RegExp | Array<string> | Record<string, string> | Record<string, RegExp> | ( ( value: unknown ) => boolean );\n\t\t\tname?: string;\n\t\t} | {\n\t\t\tname?: string | RegExp;\n\t\t\tstyles?: PropertyPatterns;\n\t\t\tclasses?: ClassPatterns;\n\t\t\tattributes?: PropertyPatterns;\n\t\t};\n\t\tmodel: string | {\n\t\t\tkey: string;\n\t\t\tvalue: unknown | ( ( viewElement: ViewElement, conversionApi: UpcastConversionApi ) => unknown );\n\t\t\tname?: string;\n\t\t};\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( upcastAttributeToAttribute( config ) );\n\t}\n\n\t/**\n\t * View element to model marker conversion helper.\n\t *\n\t * This conversion results in creating a model marker. For example, if the marker was stored in a view as an element:\n\t * `<p>Fo<span data-marker=\"comment\" data-comment-id=\"7\"></span>o</p><p>B<span data-marker=\"comment\" data-comment-id=\"7\"></span>ar</p>`,\n\t * after the conversion is done, the marker will be available in\n\t * {@link module:engine/model/model~Model#markers model document markers}.\n\t *\n\t * **Note**: When this helper is used in the data upcast in combination with\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} in the data downcast,\n\t * then invalid HTML code (e.g. a span between table cells) may be produced by the latter converter.\n\t *\n\t * In most of the cases, the {@link #dataToMarker} should be used instead.\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: 'marker-search',\n\t * \tmodel: 'search'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: 'marker-search',\n\t * \tmodel: 'search',\n\t * \tconverterPriority: 'high'\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: 'marker-search',\n\t * \tmodel: ( viewElement, conversionApi ) => 'comment:' + viewElement.getAttribute( 'data-comment-id' )\n\t * } );\n\t *\n\t * editor.conversion.for( 'upcast' ).elementToMarker( {\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tattributes: {\n\t * \t\t\t'data-marker': 'search'\n\t * \t\t}\n\t * \t},\n\t * \tmodel: 'search'\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view Pattern matching all view elements which should be converted.\n\t * @param config.model Name of the model marker, or a function that takes a view element and returns\n\t * a model marker name.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic elementToMarker( config: {\n\t\tview: MatcherPattern;\n\t\tmodel: string | MarkerFromElementCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( upcastElementToMarker( config ) );\n\t}\n\n\t/**\n\t * View-to-model marker conversion helper.\n\t *\n\t * Converts view data created by {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`}\n\t * back to a model marker.\n\t *\n\t * This converter looks for specific view elements and view attributes that mark marker boundaries. See\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToData `#markerToData()`} to learn what view data\n\t * is expected by this converter.\n\t *\n\t * The `config.view` property is equal to the marker group name to convert.\n\t *\n\t * By default, this converter creates markers with the `group:name` name convention (to match the default `markerToData` conversion).\n\t *\n\t * The conversion configuration can take a function that will generate a marker name.\n\t * If such function is set as the `config.model` parameter, it is passed the `name` part from the view element or attribute and it is\n\t * expected to return a string with the marker name.\n\t *\n\t * Basic usage:\n\t *\n\t * ```ts\n\t * // Using the default conversion.\n\t * // In this case, all markers from the `comment` group will be converted.\n\t * // The conversion will look for `<comment-start>` and `<comment-end>` tags and\n\t * // `data-comment-start-before`, `data-comment-start-after`,\n\t * // `data-comment-end-before` and `data-comment-end-after` attributes.\n\t * editor.conversion.for( 'upcast' ).dataToMarker( {\n\t * \tview: 'comment'\n\t * } );\n\t * ```\n\t *\n\t * An example of a model that may be generated by this conversion:\n\t *\n\t * ```\n\t * // View:\n\t * <p>Foo<comment-start name=\"commentId:uid\"></comment-start>bar</p>\n\t * <figure data-comment-end-after=\"commentId:uid\" class=\"image\"><img src=\"abc.jpg\" /></figure>\n\t *\n\t * // Model:\n\t * <paragraph>Foo[bar</paragraph>\n\t * <imageBlock src=\"abc.jpg\"></imageBlock>]\n\t * ```\n\t *\n\t * Where `[]` are boundaries of a marker that will receive the `comment:commentId:uid` name.\n\t *\n\t * Other examples of usage:\n\t *\n\t * ```ts\n\t * // Using a custom function which is the same as the default conversion:\n\t * editor.conversion.for( 'upcast' ).dataToMarker( {\n\t * \tview: 'comment',\n\t * \tmodel: ( name, conversionApi ) => 'comment:' + name,\n\t * } );\n\t *\n\t * // Using the converter priority:\n\t * editor.conversion.for( 'upcast' ).dataToMarker( {\n\t * \tview: 'comment',\n\t * \tmodel: ( name, conversionApi ) => 'comment:' + name,\n\t * \tconverterPriority: 'high'\n\t * } );\n\t * ```\n\t *\n\t * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter\n\t * to the conversion process.\n\t *\n\t * @param config Conversion configuration.\n\t * @param config.view The marker group name to convert.\n\t * @param config.model A function that takes the `name` part from the view element or attribute and\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi upcast conversion API} and returns the marker name.\n\t * @param config.converterPriority Converter priority.\n\t */\n\tpublic dataToMarker( config: {\n\t\tview: string;\n\t\tmodel?: MarkerFromAttributeCreatorFunction;\n\t\tconverterPriority?: PriorityString;\n\t} ): this {\n\t\treturn this.add( upcastDataToMarker( config ) );\n\t}\n}\n\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * or all children of {@link module:engine/view/element~Element} into\n * {@link module:engine/model/documentfragment~DocumentFragment model document fragment}.\n * This is the \"entry-point\" converter for upcast (view to model conversion). This converter starts the conversion of all children\n * of passed view document fragment. Those children {@link module:engine/view/node~Node view nodes} are then handled by other converters.\n *\n * This also a \"default\", last resort converter for all view elements that has not been converted by other converters.\n * When a view element is being converted to the model but it does not have converter specified, that view element\n * will be converted to {@link module:engine/model/documentfragment~DocumentFragment model document fragment} and returned.\n *\n * @returns Universal converter for view {@link module:engine/view/documentfragment~DocumentFragment fragments} and\n * {@link module:engine/view/element~Element elements} that returns\n * {@link module:engine/model/documentfragment~DocumentFragment model fragment} with children of converted view item.\n */\nexport function convertToModelFragment() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewElement | ViewDocumentFragment>,\n\t\tconversionApi: UpcastConversionApi\n\t): void => {\n\t\t// Second argument in `consumable.consume` is discarded for ViewDocumentFragment but is needed for ViewElement.\n\t\tif ( !data.modelRange && conversionApi.consumable.consume( data.viewItem, { name: true } ) ) {\n\t\t\tconst { modelRange, modelCursor } = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n\n\t\t\tdata.modelRange = modelRange;\n\t\t\tdata.modelCursor = modelCursor;\n\t\t}\n\t};\n}\n\n/**\n * Function factory, creates a converter that converts {@link module:engine/view/text~Text} to {@link module:engine/model/text~Text}.\n *\n * @returns {@link module:engine/view/text~Text View text} converter.\n */\nexport function convertText() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewText>,\n\t\t{ schema, consumable, writer }: UpcastConversionApi\n\t): void => {\n\t\tlet position = data.modelCursor;\n\n\t\t// When node is already converted then do nothing.\n\t\tif ( !consumable.test( data.viewItem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !schema.checkChild( position, '$text' ) ) {\n\t\t\tif ( !isParagraphable( position, '$text', schema ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Do not auto-paragraph whitespaces.\n\t\t\tif ( data.viewItem.data.trim().length == 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tposition = wrapInParagraph( position, writer );\n\t\t}\n\n\t\tconsumable.consume( data.viewItem );\n\n\t\tconst text = writer.createText( data.viewItem.data );\n\n\t\twriter.insert( text, position );\n\n\t\tdata.modelRange = writer.createRange(\n\t\t\tposition,\n\t\t\tposition.getShiftedBy( text.offsetSize )\n\t\t);\n\t\tdata.modelCursor = data.modelRange.end;\n\t};\n}\n\n/**\n * Function factory, creates a callback function which converts a {@link module:engine/view/selection~Selection\n * view selection} taken from the {@link module:engine/view/document~Document#event:selectionChange} event\n * and sets in on the {@link module:engine/model/document~Document#selection model}.\n *\n * **Note**: because there is no view selection change dispatcher nor any other advanced view selection to model\n * conversion mechanism, the callback should be set directly on view document.\n *\n * ```ts\n * view.document.on( 'selectionChange', convertSelectionChange( modelDocument, mapper ) );\n * ```\n *\n * @param model Data model.\n * @param mapper Conversion mapper.\n * @returns {@link module:engine/view/document~Document#event:selectionChange} callback function.\n */\nexport function convertSelectionChange( model: Model, mapper: Mapper ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: { newSelection: ViewSelection | ViewDocumentSelection }\n\t): void => {\n\t\tconst viewSelection = data.newSelection;\n\n\t\tconst ranges: Array<ModelRange> = [];\n\n\t\tfor ( const viewRange of viewSelection.getRanges() ) {\n\t\t\tranges.push( mapper.toModelRange( viewRange ) );\n\t\t}\n\n\t\tconst modelSelection = model.createSelection( ranges, { backward: viewSelection.isBackward } );\n\n\t\tif ( !modelSelection.isEqual( model.document.selection ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( modelSelection );\n\t\t\t} );\n\t\t}\n\t};\n}\n\n/**\n * View element to model element conversion helper.\n *\n * See {@link ~UpcastHelpers#elementToElement `.elementToElement()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Pattern matching all view elements which should be converted. If not\n * set, the converter will fire for every view element.\n * @param config.model Name of the model element, a model element\n * instance or a function that takes a view element and returns a model element. The model element will be inserted in the model.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */\nfunction upcastElementToElement( config: {\n\tview: MatcherPattern;\n\tmodel: string | ElementCreatorFunction;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconfig = cloneDeep( config );\n\n\tconst converter = prepareToElementConverter( config );\n\n\tconst elementName = getViewElementNameFromConfig( config.view );\n\tconst eventName = elementName ? `element:${ elementName }` as const : 'element';\n\n\treturn ( dispatcher: UpcastDispatcher ) => {\n\t\tdispatcher.on<UpcastElementEvent>( eventName, converter, { priority: config.converterPriority || 'normal' } );\n\t};\n}\n\n/**\n * View element to model attribute conversion helper.\n *\n * See {@link ~UpcastHelpers#elementToAttribute `.elementToAttribute()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Pattern matching all view elements which should be converted.\n * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n * the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n * If `String` is given, the model attribute value will be set to `true`.\n * @param config.converterPriority Converter priority. Defaults to `low`.\n * @returns Conversion helper.\n */\nfunction upcastElementToAttribute( config: {\n\tview: MatcherPattern;\n\tmodel: string | {\n\t\tkey: string;\n\t\tvalue?: unknown | AttributeCreatorFunction;\n\t};\n\tconverterPriority?: PriorityString;\n} ) {\n\tconfig = cloneDeep( config );\n\n\tnormalizeModelAttributeConfig( config );\n\n\tconst converter = prepareToAttributeConverter( config as any, false );\n\n\tconst elementName = getViewElementNameFromConfig( config.view );\n\tconst eventName = elementName ? `element:${ elementName }` as const : 'element';\n\n\treturn ( dispatcher: UpcastDispatcher ) => {\n\t\tdispatcher.on<UpcastElementEvent>( eventName, converter, { priority: config.converterPriority || 'low' } );\n\t};\n}\n\n/**\n * View attribute to model attribute conversion helper.\n *\n * See {@link ~UpcastHelpers#attributeToAttribute `.attributeToAttribute()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Specifies which view attribute will be converted. If a `String` is passed,\n * attributes with given key will be converted. If an `Object` is passed, it must have a required `key` property,\n * specifying view attribute key, and may have an optional `value` property, specifying view attribute value and optional `name`\n * property specifying a view element name from/on which the attribute should be converted. `value` can be given as a `String`,\n * a `RegExp` or a function callback, that takes view attribute value as the only parameter and returns `Boolean`.\n * @param config.model Model attribute key or an object with `key` and `value` properties, describing\n * the model attribute. `value` property may be set as a function that takes a view element and returns the value.\n * If `String` is given, the model attribute value will be same as view attribute value.\n * @param config.converterPriority Converter priority. Defaults to `low`.\n * @returns Conversion helper.\n */\nfunction upcastAttributeToAttribute( config: {\n\tview: string | {\n\t\tkey?: string;\n\t\tvalue?: string | RegExp | Array<string> | Record<string, string> | Record<string, RegExp> | ( ( value: unknown ) => boolean );\n\t\tname?: string | RegExp;\n\t\tstyles?: PropertyPatterns;\n\t\tclasses?: ClassPatterns;\n\t\tattributes?: PropertyPatterns;\n\t};\n\tmodel: string | {\n\t\tkey: string;\n\t\tvalue: unknown | ( ( viewElement: ViewElement, conversionApi: UpcastConversionApi ) => unknown );\n\t};\n\tconverterPriority?: PriorityString;\n} ) {\n\tconfig = cloneDeep( config );\n\n\tlet viewKey: string | null = null;\n\n\tif ( typeof config.view == 'string' || config.view.key ) {\n\t\tviewKey = normalizeViewAttributeKeyValueConfig( config );\n\t}\n\n\tnormalizeModelAttributeConfig( config, viewKey );\n\n\tconst converter = prepareToAttributeConverter( config as any, true );\n\n\treturn ( dispatcher: UpcastDispatcher ) => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element', converter, { priority: config.converterPriority || 'low' } );\n\t};\n}\n\n/**\n * View element to model marker conversion helper.\n *\n * See {@link ~UpcastHelpers#elementToMarker `.elementToMarker()` upcast helper} for examples.\n *\n * @param config Conversion configuration.\n * @param config.view Pattern matching all view elements which should be converted.\n * @param config.model Name of the model marker, or a function that takes a view element and returns\n * a model marker name.\n * @param config.converterPriority Converter priority.\n * @returns Conversion helper.\n */\nfunction upcastElementToMarker( config: {\n\tview: MatcherPattern;\n\tmodel: string | MarkerFromElementCreatorFunction;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconst model = normalizeElementToMarkerModelConfig( config.model );\n\n\treturn upcastElementToElement( { ...config, model } );\n}\n\n/**\n * View data to model marker conversion helper.\n *\n * See {@link ~UpcastHelpers#dataToMarker} to learn more.\n *\n * @returns Conversion helper.\n */\nfunction upcastDataToMarker( config: {\n\tview: string;\n\tmodel?: MarkerFromAttributeCreatorFunction;\n\tconverterPriority?: PriorityString;\n} ) {\n\tconfig = cloneDeep( config );\n\n\t// Default conversion.\n\tif ( !config.model ) {\n\t\tconfig.model = name => {\n\t\t\treturn name ? config.view + ':' + name : config.view;\n\t\t};\n\t}\n\n\tconst normalizedConfig = {\n\t\tview: config.view,\n\t\tmodel: config.model!\n\t};\n\n\tconst converterStart = prepareToElementConverter( normalizeDataToMarkerConfig( normalizedConfig, 'start' ) );\n\tconst converterEnd = prepareToElementConverter( normalizeDataToMarkerConfig( normalizedConfig, 'end' ) );\n\n\treturn ( dispatcher: UpcastDispatcher ): void => {\n\t\tdispatcher.on<UpcastElementEvent>(\n\t\t\t`element:${ config.view }-start`,\n\t\t\tconverterStart,\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\t\tdispatcher.on<UpcastElementEvent>(\n\t\t\t`element:${ config.view }-end`,\n\t\t\tconverterEnd,\n\t\t\t{ priority: config.converterPriority || 'normal' }\n\t\t);\n\n\t\t// Below is a hack that is needed to properly handle `converterPriority` for both elements and attributes.\n\t\t// Attribute conversion needs to be performed *after* element conversion.\n\t\t// This converter handles both element conversion and attribute conversion, which means that if a single\n\t\t// `config.converterPriority` is used, it will lead to problems. For example, if the `'high'` priority is used,\n\t\t// the attribute conversion will be performed before a lot of element upcast converters.\n\t\t// On the other hand, we want to support `config.converterPriority` and converter overwriting.\n\t\t//\n\t\t// To make it work, we need to do some extra processing for priority for attribute converter.\n\t\t// Priority `'low'` value should be the base value and then we will change it depending on `config.converterPriority` value.\n\t\t//\n\t\t// This hack probably would not be needed if attributes are upcasted separately.\n\t\t//\n\t\tconst basePriority = priorities.low;\n\t\tconst maxPriority = priorities.highest;\n\t\tconst priorityFactor = priorities.get( config.converterPriority ) / maxPriority; // Number in range [ -1, 1 ].\n\n\t\tdispatcher.on<UpcastElementEvent>(\n\t\t\t'element',\n\t\t\tupcastAttributeToMarker( normalizedConfig ),\n\t\t\t{ priority: basePriority + priorityFactor }\n\t\t);\n\t};\n}\n\n/**\n * Function factory, returns a callback function which converts view attributes to a model marker.\n *\n * The converter looks for elements with `data-group-start-before`, `data-group-start-after`, `data-group-end-before`\n * and `data-group-end-after` attributes and inserts `$marker` model elements before/after those elements.\n * `group` part is specified in `config.view`.\n *\n * @returns Marker converter.\n */\nfunction upcastAttributeToMarker( config: {\n\tview: string;\n\tmodel: MarkerFromAttributeCreatorFunction;\n} ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewElement>,\n\t\tconversionApi: UpcastConversionApi\n\t) => {\n\t\tconst attrName = `data-${ config.view }`;\n\n\t\t// Check if any attribute for the given view item can be consumed before changing the conversion data\n\t\t// and consuming view items with these attributes.\n\t\tif (\n\t\t\t!conversionApi.consumable.test( data.viewItem, { attributes: attrName + '-end-after' } ) &&\n\t\t\t!conversionApi.consumable.test( data.viewItem, { attributes: attrName + '-start-after' } ) &&\n\t\t\t!conversionApi.consumable.test( data.viewItem, { attributes: attrName + '-end-before' } ) &&\n\t\t\t!conversionApi.consumable.test( data.viewItem, { attributes: attrName + '-start-before' } )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// This converter wants to add a model element, marking a marker, before/after an element (or maybe even group of elements).\n\t\t// To do that, we can use `data.modelRange` which is set on an element (or a group of elements) that has been upcasted.\n\t\t// But, if the processed view element has not been upcasted yet (it does not have been converted), we need to\n\t\t// fire conversion for its children first, then we will have `data.modelRange` available.\n\t\tif ( !data.modelRange ) {\n\t\t\tObject.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t\t}\n\n\t\tif ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-end-after' } ) ) {\n\t\t\taddMarkerElements( data.modelRange!.end, data.viewItem.getAttribute( attrName + '-end-after' )!.split( ',' ) );\n\t\t}\n\n\t\tif ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-start-after' } ) ) {\n\t\t\taddMarkerElements( data.modelRange!.end, data.viewItem.getAttribute( attrName + '-start-after' )!.split( ',' ) );\n\t\t}\n\n\t\tif ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-end-before' } ) ) {\n\t\t\taddMarkerElements( data.modelRange!.start, data.viewItem.getAttribute( attrName + '-end-before' )!.split( ',' ) );\n\t\t}\n\n\t\tif ( conversionApi.consumable.consume( data.viewItem, { attributes: attrName + '-start-before' } ) ) {\n\t\t\taddMarkerElements( data.modelRange!.start, data.viewItem.getAttribute( attrName + '-start-before' )!.split( ',' ) );\n\t\t}\n\n\t\tfunction addMarkerElements( position: ModelPosition, markerViewNames: Array<string> ): void {\n\t\t\tfor ( const markerViewName of markerViewNames ) {\n\t\t\t\tconst markerName = config.model( markerViewName, conversionApi );\n\t\t\t\tconst element = conversionApi.writer.createElement( '$marker', { 'data-name': markerName } );\n\n\t\t\t\tconversionApi.writer.insert( element, position );\n\n\t\t\t\tif ( data.modelCursor.isEqual( position ) ) {\n\t\t\t\t\tdata.modelCursor = data.modelCursor.getShiftedBy( 1 );\n\t\t\t\t} else {\n\t\t\t\t\tdata.modelCursor = data.modelCursor._getTransformedByInsertion( position, 1 );\n\t\t\t\t}\n\n\t\t\t\tdata.modelRange = data.modelRange!._getTransformedByInsertion( position, 1 )[ 0 ];\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Helper function for from-view-element conversion. Checks if `config.view` directly specifies converted view element's name\n * and if so, returns it.\n *\n * @param config Conversion view config.\n * @returns View element name or `null` if name is not directly set.\n */\nfunction getViewElementNameFromConfig( viewConfig: any ): string | null {\n\tif ( typeof viewConfig == 'string' ) {\n\t\treturn viewConfig;\n\t}\n\n\tif ( typeof viewConfig == 'object' && typeof viewConfig.name == 'string' ) {\n\t\treturn viewConfig.name;\n\t}\n\n\treturn null;\n}\n\n/**\n * Helper for to-model-element conversion. Takes a config object and returns a proper converter function.\n *\n * @param config Conversion configuration.\n * @returns View to model converter.\n */\nfunction prepareToElementConverter( config: {\n\tview: MatcherPattern;\n\tmodel: string | ElementCreatorFunction;\n} ) {\n\tconst matcher = new Matcher( config.view );\n\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewElement>,\n\t\tconversionApi: UpcastConversionApi\n\t): void => {\n\t\tconst matcherResult = matcher.match( data.viewItem );\n\n\t\tif ( !matcherResult ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst match = matcherResult.match;\n\n\t\t// Force consuming element's name.\n\t\tmatch.name = true;\n\n\t\tif ( !conversionApi.consumable.test( data.viewItem, match ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelElement = getModelElement( config.model, data.viewItem, conversionApi );\n\n\t\tif ( !modelElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.safeInsert( modelElement, data.modelCursor ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconversionApi.consumable.consume( data.viewItem, match );\n\t\tconversionApi.convertChildren( data.viewItem, modelElement );\n\t\tconversionApi.updateConversionResult( modelElement, data );\n\t};\n}\n\n/**\n * Helper function for upcasting-to-element converter. Takes the model configuration, the converted view element\n * and a writer instance and returns a model element instance to be inserted in the model.\n *\n * @param model Model conversion configuration.\n * @param input The converted view node.\n * @param conversionApi The upcast conversion API.\n */\nfunction getModelElement(\n\tmodel: string | ElementCreatorFunction,\n\tinput: ViewElement,\n\tconversionApi: UpcastConversionApi\n): ModelElement | null {\n\tif ( model instanceof Function ) {\n\t\treturn model( input, conversionApi );\n\t} else {\n\t\treturn conversionApi.writer.createElement( model );\n\t}\n}\n\n/**\n * Helper function view-attribute-to-model-attribute helper. Normalizes `config.view` which was set as `String` or\n * as an `Object` with `key`, `value` and `name` properties. Normalized `config.view` has is compatible with\n * {@link module:engine/view/matcher~MatcherPattern}.\n *\n * @param config Conversion config.\n * @returns Key of the converted view attribute.\n */\nfunction normalizeViewAttributeKeyValueConfig( config: any ) {\n\tif ( typeof config.view == 'string' ) {\n\t\tconfig.view = { key: config.view };\n\t}\n\n\tconst key: string = config.view.key;\n\tconst value = typeof config.view.value == 'undefined' ? /[\\s\\S]*/ : config.view.value;\n\tlet normalized: MatcherPattern;\n\n\tif ( key == 'class' || key == 'style' ) {\n\t\tconst keyName = key == 'class' ? 'classes' : 'styles';\n\n\t\tnormalized = {\n\t\t\t[ keyName ]: value\n\t\t};\n\t} else {\n\t\tnormalized = {\n\t\t\tattributes: {\n\t\t\t\t[ key ]: value\n\t\t\t}\n\t\t};\n\t}\n\n\tif ( config.view.name ) {\n\t\tnormalized.name = config.view.name;\n\t}\n\n\tconfig.view = normalized;\n\n\treturn key;\n}\n\n/**\n * Helper function that normalizes `config.model` in from-model-attribute conversion. `config.model` can be set\n * as a `String`, an `Object` with only `key` property or an `Object` with `key` and `value` properties. Normalized\n * `config.model` is an `Object` with `key` and `value` properties.\n *\n * @param config Conversion config.\n * @param viewAttributeKeyToCopy Key of the converted view attribute. If it is set, model attribute value\n * will be equal to view attribute value.\n */\nfunction normalizeModelAttributeConfig( config: any, viewAttributeKeyToCopy: string | null = null ) {\n\tconst defaultModelValue = viewAttributeKeyToCopy === null ? true :\n\t\t( viewElement: ViewElement ) => viewElement.getAttribute( viewAttributeKeyToCopy );\n\n\tconst key = typeof config.model != 'object' ? config.model : config.model.key;\n\tconst value = typeof config.model != 'object' || typeof config.model.value == 'undefined' ? defaultModelValue : config.model.value;\n\n\tconfig.model = { key, value };\n}\n\n/**\n * Helper for to-model-attribute conversion. Takes the model attribute name and conversion configuration and returns\n * a proper converter function.\n *\n * @param config Conversion configuration. It is possible to provide multiple configurations in an array.\n * @param shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n * on all elements in the range.\n */\nfunction prepareToAttributeConverter(\n\tconfig: {\n\t\tview: MatcherPattern;\n\t\tmodel: {\n\t\t\tkey: string;\n\t\t\tvalue: AttributeCreatorFunction | unknown;\n\t\t};\n\t},\n\tshallow: boolean\n) {\n\tconst matcher = new Matcher( config.view );\n\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewElement>,\n\t\tconversionApi: UpcastConversionApi\n\t): void => {\n\t\t// Converting an attribute of an element that has not been converted to anything does not make sense\n\t\t// because there will be nowhere to set that attribute on. At this stage, the element should've already\n\t\t// been converted (https://github.com/ckeditor/ckeditor5/issues/11000).\n\t\tif ( !data.modelRange && shallow ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst match = matcher.match( data.viewItem );\n\n\t\t// If there is no match, this callback should not do anything.\n\t\tif ( !match ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( onlyViewNameIsDefined( config.view, data.viewItem ) ) {\n\t\t\tmatch.match.name = true;\n\t\t} else {\n\t\t\t// Do not test `name` consumable because it could get consumed already while upcasting some other attribute\n\t\t\t// on the same element (for example <span class=\"big\" style=\"color: red\">foo</span>).\n\t\t\tdelete match.match.name;\n\t\t}\n\n\t\t// Try to consume appropriate values from consumable values list.\n\t\tif ( !conversionApi.consumable.test( data.viewItem, match.match ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelKey = config.model.key;\n\t\tconst modelValue: unknown = typeof config.model.value == 'function' ?\n\t\t\tconfig.model.value( data.viewItem, conversionApi ) : config.model.value;\n\n\t\t// Do not convert if attribute building function returned falsy value.\n\t\tif ( modelValue === null ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Since we are converting to attribute we need a range on which we will set the attribute.\n\t\t// If the range is not created yet, let's create it by converting children of the current node first.\n\t\tif ( !data.modelRange ) {\n\t\t\t// Convert children and set conversion result as a current data.\n\t\t\tObject.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t\t}\n\n\t\t// Set attribute on current `output`. `Schema` is checked inside this helper function.\n\t\tconst attributeWasSet = setAttributeOn( data.modelRange!, { key: modelKey, value: modelValue }, shallow, conversionApi );\n\n\t\t// It may happen that a converter will try to set an attribute that is not allowed in the given context.\n\t\t// In such a situation we cannot consume the attribute. See: https://github.com/ckeditor/ckeditor5/pull/9249#issuecomment-815658459.\n\t\tif ( attributeWasSet ) {\n\t\t\t// Verify if the element itself wasn't consumed yet. It could be consumed already while upcasting some other attribute\n\t\t\t// on the same element (for example <span class=\"big\" style=\"color: red\">foo</span>).\n\t\t\t// We need to consume it so other features (especially GHS) won't try to convert it.\n\t\t\t// Note that it's not tested by the other element-to-attribute converters whether an element was consumed before\n\t\t\t// (in case of converters that the element itself is just a context and not the primary information to convert).\n\t\t\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t\t\tmatch.match.name = true;\n\t\t\t}\n\n\t\t\tconversionApi.consumable.consume( data.viewItem, match.match );\n\t\t}\n\t};\n}\n\n/**\n * Helper function that checks if element name should be consumed in attribute converters.\n *\n * @param viewConfig Conversion view config.\n */\nfunction onlyViewNameIsDefined( viewConfig: any, viewItem: ViewElement ): boolean {\n\t// https://github.com/ckeditor/ckeditor5-engine/issues/1786\n\tconst configToTest = typeof viewConfig == 'function' ? viewConfig( viewItem ) : viewConfig;\n\n\tif ( typeof configToTest == 'object' && !getViewElementNameFromConfig( configToTest ) ) {\n\t\treturn false;\n\t}\n\n\treturn !configToTest.classes && !configToTest.attributes && !configToTest.styles;\n}\n\n/**\n * Helper function for to-model-attribute converter. Sets model attribute on given range. Checks {@link module:engine/model/schema~Schema}\n * to ensure proper model structure.\n *\n * If any node on the given range has already defined an attribute with the same name, its value will not be updated.\n *\n * @param modelRange Model range on which attribute should be set.\n * @param modelAttribute Model attribute to set.\n * @param conversionApi Conversion API.\n * @param shallow If set to `true` the attribute will be set only on top-level nodes. Otherwise, it will be set\n * on all elements in the range.\n * @returns `true` if attribute was set on at least one node from given `modelRange`.\n */\nfunction setAttributeOn(\n\tmodelRange: ModelRange,\n\tmodelAttribute: {\n\t\tkey: string;\n\t\tvalue: unknown;\n\t},\n\tshallow: boolean,\n\tconversionApi: UpcastConversionApi\n): boolean {\n\tlet result = false;\n\n\t// Set attribute on each item in range according to Schema.\n\tfor ( const node of Array.from( modelRange.getItems( { shallow } ) ) ) {\n\t\t// Skip if not allowed.\n\t\tif ( !conversionApi.schema.checkAttribute( node, modelAttribute.key ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Mark the node as consumed even if the attribute will not be updated because it's in a valid context (schema)\n\t\t// and would be converted if the attribute wouldn't be present. See #8921.\n\t\tresult = true;\n\n\t\t// Do not override the attribute if it's already present.\n\t\tif ( node.hasAttribute( modelAttribute.key ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconversionApi.writer.setAttribute( modelAttribute.key, modelAttribute.value, node );\n\t}\n\n\treturn result;\n}\n\n/**\n * Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastElementToMarker()`\n * function and converts it to a format that is supported by `upcastElementToElement()` function.\n */\nfunction normalizeElementToMarkerModelConfig( model: string | MarkerFromElementCreatorFunction ): ElementCreatorFunction {\n\treturn ( viewElement, conversionApi ) => {\n\t\tconst markerName = typeof model == 'string' ? model : model( viewElement, conversionApi );\n\n\t\treturn conversionApi.writer.createElement( '$marker', { 'data-name': markerName } );\n\t};\n}\n\n/**\n * Helper function for upcasting-to-marker conversion. Takes the config in a format requested by `upcastDataToMarker()`\n * function and converts it to a format that is supported by `upcastElementToElement()` function.\n */\nfunction normalizeDataToMarkerConfig(\n\tconfig: {\n\t\tview: string;\n\t\tmodel: MarkerFromAttributeCreatorFunction;\n\t},\n\ttype: string\n) {\n\tconst elementCreatorFunction: ElementCreatorFunction = ( viewElement, conversionApi ) => {\n\t\tconst viewName = viewElement.getAttribute( 'name' )!;\n\t\tconst markerName = config.model( viewName, conversionApi );\n\n\t\treturn conversionApi.writer.createElement( '$marker', { 'data-name': markerName } );\n\t};\n\n\treturn {\n\t\t// Upcast <markerGroup-start> and <markerGroup-end> elements.\n\t\tview: `${ config.view }-${ type }`,\n\t\tmodel: elementCreatorFunction\n\t};\n}\n\nexport type ElementCreatorFunction = (\n\tviewElement: ViewElement,\n\tconversionApi: UpcastConversionApi\n) => ModelElement | null;\n\nexport type AttributeCreatorFunction = (\n\tmodelElement: ModelElement,\n\tconversionApi: UpcastConversionApi\n) => unknown;\n\nexport type MarkerFromElementCreatorFunction = (\n\tviewElement: ViewElement,\n\tconversionApi: UpcastConversionApi\n) => string;\n\nexport type MarkerFromAttributeCreatorFunction = (\n\tattributeValue: string,\n\tconversionApi: UpcastConversionApi\n) => string;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/utils/selection-post-fixer\n */\n\nimport Position from '../position.js';\nimport Range from '../range.js';\n\nimport type DocumentFragment from '../documentfragment.js';\nimport type Model from '../model.js';\nimport type Node from '../node.js';\nimport type Schema from '../schema.js';\nimport type Writer from '../writer.js';\nimport type Element from '../element.js';\n\n/**\n * Injects selection post-fixer to the model.\n *\n * The role of the selection post-fixer is to ensure that the selection is in a correct place\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct position means that:\n *\n * * All collapsed selection ranges are in a place where the {@link module:engine/model/schema~Schema}\n * allows a `$text`.\n * * None of the selection's non-collapsed ranges crosses a {@link module:engine/model/schema~Schema#isLimit limit element}\n * boundary (a range must be rooted within one limit element).\n * * Only {@link module:engine/model/schema~Schema#isSelectable selectable elements} can be selected from the outside\n * (e.g. `[<paragraph>foo</paragraph>]` is invalid). This rule applies independently to both selection ends, so this\n * selection is correct: `<paragraph>f[oo</paragraph><imageBlock></imageBlock>]`.\n *\n * If the position is not correct, the post-fixer will automatically correct it.\n *\n * ## Fixing a non-collapsed selection\n *\n * See as an example a selection that starts in a P1 element and ends inside the text of a TD element\n * (`[` and `]` are range boundaries and `(l)` denotes an element defined as `isLimit=true`):\n *\n * ```\n * root\n *  |- element P1\n *  |   |- \"foo\"                                      root\n *  |- element TABLE (l)                   P1         TABLE             P2\n *  |   |- element TR (l)                 f o[o     TR      TR         b a r\n *  |   |   |- element TD (l)                       TD      TD\n *  |   |       |- \"aaa\"                          a]a a    b b b\n *  |   |- element TR (l)\n *  |   |   |- element TD (l)                           ||\n *  |   |       |- \"bbb\"                                ||\n *  |- element P2                                       VV\n *  |   |- \"bar\"\n *                                                    root\n *                                         P1         TABLE]            P2\n *                                        f o[o     TR      TR         b a r\n *                                                  TD      TD\n *                                                a a a    b b b\n * ```\n *\n * In the example above, the TABLE, TR and TD are defined as `isLimit=true` in the schema. The range which is not contained within\n * a single limit element must be expanded to select the outermost limit element. The range end is inside the text node of the TD element.\n * As the TD element is a child of the TR and TABLE elements, where both are defined as `isLimit=true` in the schema, the range must be\n * expanded to select the whole TABLE element.\n *\n * **Note** If the selection contains multiple ranges, the method returns a minimal set of ranges that are not intersecting after expanding\n * them to select `isLimit=true` elements.\n */\nexport function injectSelectionPostFixer( model: Model ): void {\n\tmodel.document.registerPostFixer( writer => selectionPostFixer( writer, model ) );\n}\n\n/**\n * The selection post-fixer.\n */\nfunction selectionPostFixer( writer: Writer, model: Model ): boolean {\n\tconst selection = model.document.selection;\n\tconst schema = model.schema;\n\n\tconst ranges = [];\n\n\tlet wasFixed = false;\n\n\tfor ( const modelRange of selection.getRanges() ) {\n\t\t// Go through all ranges in selection and try fixing each of them.\n\t\t// Those ranges might overlap but will be corrected later.\n\t\tconst correctedRange = tryFixingRange( modelRange, schema );\n\n\t\t// \"Selection fixing\" algorithms sometimes get lost. In consequence, it may happen\n\t\t// that a new range is returned but, in fact, it has the same positions as the original\n\t\t// range anyway. If this range is not discarded, a new selection will be set and that,\n\t\t// for instance, would destroy the selection attributes. Let's make sure that the post-fixer\n\t\t// actually worked first before setting a new selection.\n\t\t//\n\t\t// https://github.com/ckeditor/ckeditor5/issues/6693\n\t\tif ( correctedRange && !correctedRange.isEqual( modelRange ) ) {\n\t\t\tranges.push( correctedRange );\n\t\t\twasFixed = true;\n\t\t} else {\n\t\t\tranges.push( modelRange );\n\t\t}\n\t}\n\n\t// If any of ranges were corrected update the selection.\n\tif ( wasFixed ) {\n\t\twriter.setSelection( mergeIntersectingRanges( ranges ), { backward: selection.isBackward } );\n\t}\n\n\treturn false;\n}\n\n/**\n * Tries fixing a range if it's incorrect.\n *\n * **Note:** This helper is used by the selection post-fixer and to fix the `beforeinput` target ranges.\n *\n * @returns Returns fixed range or null if range is valid.\n */\nexport function tryFixingRange( range: Range, schema: Schema ): Range | null {\n\tif ( range.isCollapsed ) {\n\t\treturn tryFixingCollapsedRange( range, schema );\n\t}\n\n\treturn tryFixingNonCollapsedRage( range, schema );\n}\n\n/**\n * Tries to fix collapsed ranges.\n *\n * * Fixes situation when a range is in a place where $text is not allowed\n *\n * @param range Collapsed range to fix.\n * @returns Returns fixed range or null if range is valid.\n */\nfunction tryFixingCollapsedRange( range: Range, schema: Schema ) {\n\tconst originalPosition = range.start;\n\n\tconst nearestSelectionRange = schema.getNearestSelectionRange( originalPosition );\n\n\t// This might be null, i.e. when the editor data is empty or the selection is inside a limit element\n\t// that doesn't allow text inside.\n\t// In the first case, there is no need to fix the selection range.\n\t// In the second, let's go up to the outer selectable element\n\tif ( !nearestSelectionRange ) {\n\t\tconst ancestorObject = originalPosition.getAncestors().reverse().find( ( item ): item is Element => schema.isObject( item ) );\n\n\t\tif ( ancestorObject ) {\n\t\t\treturn Range._createOn( ancestorObject );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tif ( !nearestSelectionRange.isCollapsed ) {\n\t\treturn nearestSelectionRange;\n\t}\n\n\tconst fixedPosition = nearestSelectionRange.start;\n\n\t// Fixed position is the same as original - no need to return corrected range.\n\tif ( originalPosition.isEqual( fixedPosition ) ) {\n\t\treturn null;\n\t}\n\n\treturn new Range( fixedPosition );\n}\n\n/**\n * Tries to fix an expanded range.\n *\n * @param range Expanded range to fix.\n * @returns Returns fixed range or null if range is valid.\n */\nfunction tryFixingNonCollapsedRage( range: Range, schema: Schema ) {\n\tconst { start, end } = range;\n\n\tconst isTextAllowedOnStart = schema.checkChild( start, '$text' );\n\tconst isTextAllowedOnEnd = schema.checkChild( end, '$text' );\n\n\tconst startLimitElement = schema.getLimitElement( start );\n\tconst endLimitElement = schema.getLimitElement( end );\n\n\t// Ranges which both end are inside the same limit element (or root) might needs only minor fix.\n\tif ( startLimitElement === endLimitElement ) {\n\t\t// Range is valid when both position allows to place a text:\n\t\t// - <block>f[oobarba]z</block>\n\t\t// This would be \"fixed\" by a next check but as it will be the same it's better to return null so the selection stays the same.\n\t\tif ( isTextAllowedOnStart && isTextAllowedOnEnd ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Range that is on non-limit element (or is partially) must be fixed so it is placed inside the block around $text:\n\t\t// - [<block>foo</block>]    ->    <block>[foo]</block>\n\t\t// - [<block>foo]</block>    ->    <block>[foo]</block>\n\t\t// - <block>f[oo</block>]    ->    <block>f[oo]</block>\n\t\t// - [<block>foo</block><selectable></selectable>]    ->    <block>[foo</block><selectable></selectable>]\n\t\tif ( checkSelectionOnNonLimitElements( start, end, schema ) ) {\n\t\t\tconst isStartBeforeSelectable = start.nodeAfter && schema.isSelectable( start.nodeAfter );\n\t\t\tconst fixedStart = isStartBeforeSelectable ? null : schema.getNearestSelectionRange( start, 'forward' );\n\n\t\t\tconst isEndAfterSelectable = end.nodeBefore && schema.isSelectable( end.nodeBefore );\n\t\t\tconst fixedEnd = isEndAfterSelectable ? null : schema.getNearestSelectionRange( end, 'backward' );\n\n\t\t\t// The schema.getNearestSelectionRange might return null - if that happens use original position.\n\t\t\tconst rangeStart = fixedStart ? fixedStart.start : start;\n\t\t\tconst rangeEnd = fixedEnd ? fixedEnd.end : end;\n\n\t\t\treturn new Range( rangeStart, rangeEnd );\n\t\t}\n\t}\n\n\tconst isStartInLimit = startLimitElement && !startLimitElement.is( 'rootElement' );\n\tconst isEndInLimit = endLimitElement && !endLimitElement.is( 'rootElement' );\n\n\t// At this point we eliminated valid positions on text nodes so if one of range positions is placed inside a limit element\n\t// then the range crossed limit element boundaries and needs to be fixed.\n\tif ( isStartInLimit || isEndInLimit ) {\n\t\tconst bothInSameParent = ( start.nodeAfter && end.nodeBefore ) && start.nodeAfter.parent === end.nodeBefore.parent;\n\n\t\tconst expandStart = isStartInLimit && ( !bothInSameParent || !isSelectable( start.nodeAfter, schema ) );\n\t\tconst expandEnd = isEndInLimit && ( !bothInSameParent || !isSelectable( end.nodeBefore, schema ) );\n\n\t\t// Although we've already found limit element on start/end positions we must find the outer-most limit element.\n\t\t// as limit elements might be nested directly inside (ie table > tableRow > tableCell).\n\t\tlet fixedStart = start;\n\t\tlet fixedEnd = end;\n\n\t\tif ( expandStart ) {\n\t\t\tfixedStart = Position._createBefore( findOutermostLimitAncestor( startLimitElement, schema ) );\n\t\t}\n\n\t\tif ( expandEnd ) {\n\t\t\tfixedEnd = Position._createAfter( findOutermostLimitAncestor( endLimitElement, schema ) );\n\t\t}\n\n\t\treturn new Range( fixedStart, fixedEnd );\n\t}\n\n\t// Range was not fixed at this point so it is valid - ie it was placed around limit element already.\n\treturn null;\n}\n\n/**\n * Finds the outer-most ancestor.\n */\nfunction findOutermostLimitAncestor( startingNode: Node, schema: Schema ): Node {\n\tlet isLimitNode = startingNode;\n\tlet parent: Node | DocumentFragment = isLimitNode;\n\n\t// Find outer most isLimit block as such blocks might be nested (ie. in tables).\n\twhile ( schema.isLimit( parent ) && parent.parent ) {\n\t\tisLimitNode = parent;\n\t\tparent = parent.parent;\n\t}\n\n\treturn isLimitNode;\n}\n\n/**\n * Checks whether any of range boundaries is placed around non-limit elements.\n */\nfunction checkSelectionOnNonLimitElements( start: Position, end: Position, schema: Schema ) {\n\tconst startIsOnBlock = ( start.nodeAfter && !schema.isLimit( start.nodeAfter ) ) || schema.checkChild( start, '$text' );\n\tconst endIsOnBlock = ( end.nodeBefore && !schema.isLimit( end.nodeBefore ) ) || schema.checkChild( end, '$text' );\n\n\t// We should fix such selection when one of those nodes needs fixing.\n\treturn startIsOnBlock || endIsOnBlock;\n}\n\n/**\n * Returns a minimal non-intersecting array of ranges without duplicates.\n *\n * @param ranges Ranges to merge.\n * @returns Array of unique and non-intersecting ranges.\n */\nexport function mergeIntersectingRanges( ranges: Array<Range> ): Array<Range> {\n\tconst rangesToMerge = [ ...ranges ];\n\tconst rangeIndexesToRemove = new Set();\n\tlet currentRangeIndex = 1;\n\n\twhile ( currentRangeIndex < rangesToMerge.length ) {\n\t\tconst currentRange = rangesToMerge[ currentRangeIndex ];\n\t\tconst previousRanges = rangesToMerge.slice( 0, currentRangeIndex );\n\n\t\tfor ( const [ previousRangeIndex, previousRange ] of previousRanges.entries() ) {\n\t\t\tif ( rangeIndexesToRemove.has( previousRangeIndex ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( currentRange.isEqual( previousRange ) ) {\n\t\t\t\trangeIndexesToRemove.add( previousRangeIndex );\n\t\t\t} else if ( currentRange.isIntersecting( previousRange ) ) {\n\t\t\t\trangeIndexesToRemove.add( previousRangeIndex );\n\t\t\t\trangeIndexesToRemove.add( currentRangeIndex );\n\n\t\t\t\tconst mergedRange = currentRange.getJoined( previousRange );\n\t\t\t\trangesToMerge.push( mergedRange! );\n\t\t\t}\n\t\t}\n\n\t\tcurrentRangeIndex++;\n\t}\n\n\tconst nonIntersectingRanges = rangesToMerge.filter( ( _, index ) => !rangeIndexesToRemove.has( index ) );\n\n\treturn nonIntersectingRanges;\n}\n\n/**\n * Checks if node exists and if it's a selectable.\n */\nfunction isSelectable( node: Node, schema: Schema ) {\n\treturn node && schema.isSelectable( node );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/controller/editingcontroller\n */\n\nimport {\n\tCKEditorError,\n\tObservableMixin,\n\tenv,\n\ttype GetCallback\n} from '@ckeditor/ckeditor5-utils';\n\nimport RootEditableElement from '../view/rooteditableelement.js';\nimport View from '../view/view.js';\nimport Mapper from '../conversion/mapper.js';\nimport DowncastDispatcher, {\n\ttype DowncastInsertEvent,\n\ttype DowncastRemoveEvent,\n\ttype DowncastSelectionEvent,\n\ttype DowncastCleanSelectionEvent\n} from '../conversion/downcastdispatcher.js';\nimport {\n\tcleanSelection,\n\tconvertCollapsedSelection,\n\tconvertRangeSelection,\n\tinsertAttributesAndChildren,\n\tinsertText,\n\tremove\n} from '../conversion/downcasthelpers.js';\n\nimport { convertSelectionChange } from '../conversion/upcasthelpers.js';\n\nimport { tryFixingRange } from '../model/utils/selection-post-fixer.js';\n\nimport type { default as Model, AfterChangesEvent, BeforeChangesEvent } from '../model/model.js';\nimport type ModelItem from '../model/item.js';\nimport type ModelText from '../model/text.js';\nimport type ModelTextProxy from '../model/textproxy.js';\nimport type Schema from '../model/schema.js';\nimport type { DocumentChangeEvent } from '../model/document.js';\nimport type { Marker } from '../model/markercollection.js';\nimport type { StylesProcessor } from '../view/stylesmap.js';\nimport type { ViewDocumentSelectionChangeEvent } from '../view/observer/selectionobserver.js';\nimport type { ViewDocumentInputEvent } from '../view/observer/inputobserver.js';\n\n// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' );\n\n/**\n * A controller for the editing pipeline. The editing pipeline controls the {@link ~EditingController#model model} rendering,\n * including selection handling. It also creates the {@link ~EditingController#view view} which builds a\n * browser-independent virtualization over the DOM elements. The editing controller also attaches default converters.\n */\nexport default class EditingController extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * Editor model.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * Editing view controller.\n\t */\n\tpublic readonly view: View;\n\n\t/**\n\t * A mapper that describes the model-view binding.\n\t */\n\tpublic readonly mapper: Mapper;\n\n\t/**\n\t * Downcast dispatcher that converts changes from the model to the {@link #view editing view}.\n\t */\n\tpublic readonly downcastDispatcher: DowncastDispatcher;\n\n\t/**\n\t * Creates an editing controller instance.\n\t *\n\t * @param model Editing model.\n\t * @param stylesProcessor The styles processor instance.\n\t */\n\tconstructor( model: Model, stylesProcessor: StylesProcessor ) {\n\t\tsuper();\n\n\t\tthis.model = model;\n\t\tthis.view = new View( stylesProcessor );\n\t\tthis.mapper = new Mapper();\n\n\t\tthis.downcastDispatcher = new DowncastDispatcher( {\n\t\t\tmapper: this.mapper,\n\t\t\tschema: model.schema\n\t\t} );\n\n\t\tconst doc = this.model.document;\n\t\tconst selection = doc.selection;\n\t\tconst markers = this.model.markers;\n\n\t\t// When plugins listen on model changes (on selection change, post fixers, etc.) and change the view as a result of\n\t\t// the model's change, they might trigger view rendering before the conversion is completed (e.g. before the selection\n\t\t// is converted). We disable rendering for the length of the outermost model change() block to prevent that.\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1528\n\t\tthis.listenTo<BeforeChangesEvent>( this.model, '_beforeChanges', () => {\n\t\t\tthis.view._disableRendering( true );\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo<AfterChangesEvent>( this.model, '_afterChanges', () => {\n\t\t\tthis.view._disableRendering( false );\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Whenever model document is changed, convert those changes to the view (using model.Document#differ).\n\t\t// Do it on 'low' priority, so changes are converted after other listeners did their job.\n\t\t// Also convert model selection.\n\t\tthis.listenTo<DocumentChangeEvent>( doc, 'change', () => {\n\t\t\tthis.view.change( writer => {\n\t\t\t\tthis.downcastDispatcher.convertChanges( doc.differ, markers, writer );\n\t\t\t\tthis.downcastDispatcher.convertSelection( selection, markers, writer );\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\n\t\t// Convert selection from the view to the model when it changes in the view.\n\t\tthis.listenTo<ViewDocumentSelectionChangeEvent>( this.view.document, 'selectionChange',\n\t\t\tconvertSelectionChange( this.model, this.mapper )\n\t\t);\n\n\t\t// Fix `beforeinput` target ranges so that they map to the valid model ranges.\n\t\tthis.listenTo<ViewDocumentInputEvent>( this.view.document, 'beforeinput',\n\t\t\tfixTargetRanges( this.mapper, this.model.schema, this.view ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\n\t\t// Attach default model converters.\n\t\tthis.downcastDispatcher.on<DowncastInsertEvent<ModelText | ModelTextProxy>>( 'insert:$text', insertText(), { priority: 'lowest' } );\n\t\tthis.downcastDispatcher.on<DowncastInsertEvent>( 'insert', insertAttributesAndChildren(), { priority: 'lowest' } );\n\t\tthis.downcastDispatcher.on<DowncastRemoveEvent>( 'remove', remove(), { priority: 'low' } );\n\n\t\t// Attach default model selection converters.\n\t\tthis.downcastDispatcher.on<DowncastCleanSelectionEvent>( 'cleanSelection', cleanSelection() );\n\t\tthis.downcastDispatcher.on<DowncastSelectionEvent>( 'selection', convertRangeSelection(), { priority: 'low' } );\n\t\tthis.downcastDispatcher.on<DowncastSelectionEvent>( 'selection', convertCollapsedSelection(), { priority: 'low' } );\n\n\t\t// Binds {@link module:engine/view/document~Document#roots view roots collection} to\n\t\t// {@link module:engine/model/document~Document#roots model roots collection} so creating\n\t\t// model root automatically creates corresponding view root.\n\t\tthis.view.document.roots.bindTo( this.model.document.roots ).using( root => {\n\t\t\t// $graveyard is a special root that has no reflection in the view.\n\t\t\tif ( root.rootName == '$graveyard' ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst viewRoot = new RootEditableElement( this.view.document, root.name );\n\n\t\t\tviewRoot.rootName = root.rootName;\n\t\t\tthis.mapper.bindElements( root, viewRoot );\n\n\t\t\treturn viewRoot;\n\t\t} );\n\n\t\t// @if CK_DEBUG_ENGINE // initDocumentDumping( this.model.document );\n\t\t// @if CK_DEBUG_ENGINE // initDocumentDumping( this.view.document );\n\n\t\t// @if CK_DEBUG_ENGINE // dumpTrees( this.model.document, this.model.document.version );\n\t\t// @if CK_DEBUG_ENGINE // dumpTrees( this.view.document, this.model.document.version );\n\n\t\t// @if CK_DEBUG_ENGINE // this.model.document.on( 'change', () => {\n\t\t// @if CK_DEBUG_ENGINE //\tdumpTrees( this.view.document, this.model.document.version );\n\t\t// @if CK_DEBUG_ENGINE // }, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Removes all event listeners attached to the `EditingController`. Destroys all objects created\n\t * by `EditingController` that need to be destroyed.\n\t */\n\tpublic destroy(): void {\n\t\tthis.view.destroy();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Calling this method will refresh the marker by triggering the downcast conversion for it.\n\t *\n\t * Reconverting the marker is useful when you want to change its {@link module:engine/view/element~Element view element}\n\t * without changing any marker data. For instance:\n\t *\n\t * ```ts\n\t * let isCommentActive = false;\n\t *\n\t * model.conversion.markerToHighlight( {\n\t * \tmodel: 'comment',\n\t * \tview: data => {\n\t * \t\tconst classes = [ 'comment-marker' ];\n\t *\n\t * \t\tif ( isCommentActive ) {\n\t * \t\t\tclasses.push( 'comment-marker--active' );\n\t * \t\t}\n\t *\n\t * \t\treturn { classes };\n\t * \t}\n\t * } );\n\t *\n\t * // ...\n\t *\n\t * // Change the property that indicates if marker is displayed as active or not.\n\t * isCommentActive = true;\n\t *\n\t * // Reconverting will downcast and synchronize the marker with the new isCommentActive state value.\n\t * editor.editing.reconvertMarker( 'comment' );\n\t * ```\n\t *\n\t * **Note**: If you want to reconvert a model item, use {@link #reconvertItem} instead.\n\t *\n\t * @param markerOrName Name of a marker to update, or a marker instance.\n\t */\n\tpublic reconvertMarker( markerOrName: Marker | string ): void {\n\t\tconst markerName = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n\t\tconst currentMarker = this.model.markers.get( markerName );\n\n\t\tif ( !currentMarker ) {\n\t\t\t/**\n\t\t\t * The marker with the provided name does not exist and cannot be reconverted.\n\t\t\t *\n\t\t\t * @error editingcontroller-reconvertmarker-marker-not-exist\n\t\t\t * @param {String} markerName The name of the reconverted marker.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'editingcontroller-reconvertmarker-marker-not-exist', this, { markerName } );\n\t\t}\n\n\t\tthis.model.change( () => {\n\t\t\tthis.model.markers._refresh( currentMarker );\n\t\t} );\n\t}\n\n\t/**\n\t * Calling this method will downcast a model item on demand (by requesting a refresh in the {@link module:engine/model/differ~Differ}).\n\t *\n\t * You can use it if you want the view representation of a specific item updated as a response to external modifications. For instance,\n\t * when the view structure depends not only on the associated model data but also on some external state.\n\t *\n\t * **Note**: If you want to reconvert a model marker, use {@link #reconvertMarker} instead.\n\t *\n\t * @param item Item to refresh.\n\t */\n\tpublic reconvertItem( item: ModelItem ): void {\n\t\tthis.model.change( () => {\n\t\t\tthis.model.document.differ._refreshItem( item );\n\t\t} );\n\t}\n}\n\n/**\n * Checks whether the target ranges provided by the `beforeInput` event can be properly mapped to model ranges and fixes them if needed.\n *\n * This is using the same logic as the selection post-fixer.\n */\nfunction fixTargetRanges( mapper: Mapper, schema: Schema, view: View ): GetCallback<ViewDocumentInputEvent> {\n\treturn ( evt, data ) => {\n\t\t// The Renderer is disabled while composing on non-android browsers, so we can't be sure that target ranges\n\t\t// could be properly mapped to view and model because the DOM and view tree drifted apart.\n\t\tif ( view.document.isComposing && !env.isAndroid ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( let i = 0; i < data.targetRanges.length; i++ ) {\n\t\t\tconst viewRange = data.targetRanges[ i ];\n\t\t\tconst modelRange = mapper.toModelRange( viewRange );\n\t\t\tconst correctedRange = tryFixingRange( modelRange, schema );\n\n\t\t\tif ( !correctedRange || correctedRange.isEqual( modelRange ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tdata.targetRanges[ i ] = mapper.toViewRange( correctedRange );\n\t\t}\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/conversion/viewconsumable\n */\n\nimport { CKEditorError, toArray, type ArrayOrItem } from '@ckeditor/ckeditor5-utils';\n\nimport type Element from '../view/element.js';\nimport type Node from '../view/node.js';\nimport type Text from '../view/text.js';\nimport type DocumentFragment from '../view/documentfragment.js';\nimport type { Match } from '../view/matcher.js';\n\n/**\n * Class used for handling consumption of view {@link module:engine/view/element~Element elements},\n * {@link module:engine/view/text~Text text nodes} and {@link module:engine/view/documentfragment~DocumentFragment document fragments}.\n * Element's name and its parts (attributes, classes and styles) can be consumed separately. Consuming an element's name\n * does not consume its attributes, classes and styles.\n * To add items for consumption use {@link module:engine/conversion/viewconsumable~ViewConsumable#add add method}.\n * To test items use {@link module:engine/conversion/viewconsumable~ViewConsumable#test test method}.\n * To consume items use {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consume method}.\n * To revert already consumed items use {@link module:engine/conversion/viewconsumable~ViewConsumable#revert revert method}.\n *\n * ```ts\n * viewConsumable.add( element, { name: true } ); // Adds element's name as ready to be consumed.\n * viewConsumable.add( textNode ); // Adds text node for consumption.\n * viewConsumable.add( docFragment ); // Adds document fragment for consumption.\n * viewConsumable.test( element, { name: true }  ); // Tests if element's name can be consumed.\n * viewConsumable.test( textNode ); // Tests if text node can be consumed.\n * viewConsumable.test( docFragment ); // Tests if document fragment can be consumed.\n * viewConsumable.consume( element, { name: true }  ); // Consume element's name.\n * viewConsumable.consume( textNode ); // Consume text node.\n * viewConsumable.consume( docFragment ); // Consume document fragment.\n * viewConsumable.revert( element, { name: true }  ); // Revert already consumed element's name.\n * viewConsumable.revert( textNode ); // Revert already consumed text node.\n * viewConsumable.revert( docFragment ); // Revert already consumed document fragment.\n * ```\n */\nexport default class ViewConsumable {\n\t/**\n\t * Map of consumable elements. If {@link module:engine/view/element~Element element} is used as a key,\n\t * {@link module:engine/conversion/viewconsumable~ViewElementConsumables ViewElementConsumables} instance is stored as value.\n\t * For {@link module:engine/view/text~Text text nodes} and\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragments} boolean value is stored as value.\n\t */\n\tprivate _consumables = new Map<Node | DocumentFragment, ViewElementConsumables | boolean>();\n\n\t/**\n\t * Adds {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} as ready to be consumed.\n\t *\n\t * ```ts\n\t * viewConsumable.add( textNode ); // Adds text node to consume.\n\t * viewConsumable.add( docFragment ); // Adds document fragment to consume.\n\t * ```\n\t *\n\t * See also: {@link #add:ELEMENT `add( element, consumables )`}.\n\t *\n\t * @label TEXT_OR_FRAGMENT\n\t */\n\tpublic add(\n\t\ttextOrDocumentFragment: Text | DocumentFragment\n\t): void;\n\n\t/**\n\t * Adds {@link module:engine/view/element~Element view element} as ready to be consumed.\n\t *\n\t * ```ts\n\t * viewConsumable.add( p, { name: true } ); // Adds element's name to consume.\n\t * viewConsumable.add( p, { attributes: 'name' } ); // Adds element's attribute.\n\t * viewConsumable.add( p, { classes: 'foobar' } ); // Adds element's class.\n\t * viewConsumable.add( p, { styles: 'color' } ); // Adds element's style\n\t * viewConsumable.add( p, { attributes: 'name', styles: 'color' } ); // Adds attribute and style.\n\t * viewConsumable.add( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be provided.\n\t * ```\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * attribute is provided - it should be handled separately by providing actual style/class.\n\t *\n\t * ```ts\n\t * viewConsumable.add( p, { attributes: 'style' } ); // This call will throw an exception.\n\t * viewConsumable.add( p, { styles: 'color' } ); // This is properly handled style.\n\t * ```\n\t *\n\t * See also: {@link #add:TEXT_OR_FRAGMENT `add( textOrDocumentFragment )`}.\n\t *\n\t * @label ELEMENT\n\t * @param consumables Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param consumables.name If set to true element's name will be included.\n\t * @param consumables.attributes Attribute name or array of attribute names.\n\t * @param consumables.classes Class name or array of class names.\n\t * @param consumables.styles Style name or array of style names.\n\t */\n\tpublic add(\n\t\telement: Element,\n\t\tconsumables: Consumables\n\t): void;\n\n\tpublic add(\n\t\telement: Node | DocumentFragment,\n\t\tconsumables?: Consumables\n\t): void {\n\t\tlet elementConsumables: ViewElementConsumables;\n\n\t\t// For text nodes and document fragments just mark them as consumable.\n\t\tif ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {\n\t\t\tthis._consumables.set( element, true );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// For elements create new ViewElementConsumables or update already existing one.\n\t\tif ( !this._consumables.has( element ) ) {\n\t\t\telementConsumables = new ViewElementConsumables( element );\n\t\t\tthis._consumables.set( element, elementConsumables );\n\t\t} else {\n\t\t\telementConsumables = this._consumables.get( element ) as any;\n\t\t}\n\n\t\telementConsumables.add( consumables! );\n\t}\n\n\t/**\n\t * Tests if {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} can be consumed.\n\t * It returns `true` when all items included in method's call can be consumed. Returns `false` when\n\t * first already consumed item is found and `null` when first non-consumable item is found.\n\t *\n\t * ```ts\n\t * viewConsumable.test( p, { name: true } ); // Tests element's name.\n\t * viewConsumable.test( p, { attributes: 'name' } ); // Tests attribute.\n\t * viewConsumable.test( p, { classes: 'foobar' } ); // Tests class.\n\t * viewConsumable.test( p, { styles: 'color' } ); // Tests style.\n\t * viewConsumable.test( p, { attributes: 'name', styles: 'color' } ); // Tests attribute and style.\n\t * viewConsumable.test( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be tested.\n\t * viewConsumable.test( textNode ); // Tests text node.\n\t * viewConsumable.test( docFragment ); // Tests document fragment.\n\t * ```\n\t *\n\t * Testing classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t * ```ts\n\t * viewConsumable.test( p, { attributes: 'class' } ); // Tests if all added classes can be consumed.\n\t * viewConsumable.test( p, { attributes: 'style' } ); // Tests if all added styles can be consumed.\n\t * ```\n\t *\n\t * @param consumables Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param consumables.name If set to true element's name will be included.\n\t * @param consumables.attributes Attribute name or array of attribute names.\n\t * @param consumables.classes Class name or array of class names.\n\t * @param consumables.styles Style name or array of style names.\n\t * @returns Returns `true` when all items included in method's call can be consumed. Returns `false`\n\t * when first already consumed item is found and `null` when first non-consumable item is found.\n\t */\n\tpublic test( element: Node | DocumentFragment, consumables?: Consumables | Match ): boolean | null {\n\t\tconst elementConsumables = this._consumables.get( element );\n\n\t\tif ( elementConsumables === undefined ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// For text nodes and document fragments return stored boolean value.\n\t\tif ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {\n\t\t\treturn elementConsumables as boolean;\n\t\t}\n\n\t\t// For elements test consumables object.\n\t\treturn ( elementConsumables as ViewElementConsumables ).test( consumables! );\n\t}\n\n\t/**\n\t * Consumes {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t * It returns `true` when all items included in method's call can be consumed, otherwise returns `false`.\n\t *\n\t * ```ts\n\t * viewConsumable.consume( p, { name: true } ); // Consumes element's name.\n\t * viewConsumable.consume( p, { attributes: 'name' } ); // Consumes element's attribute.\n\t * viewConsumable.consume( p, { classes: 'foobar' } ); // Consumes element's class.\n\t * viewConsumable.consume( p, { styles: 'color' } ); // Consumes element's style.\n\t * viewConsumable.consume( p, { attributes: 'name', styles: 'color' } ); // Consumes attribute and style.\n\t * viewConsumable.consume( p, { classes: [ 'baz', 'bar' ] } ); // Multiple consumables can be consumed.\n\t * viewConsumable.consume( textNode ); // Consumes text node.\n\t * viewConsumable.consume( docFragment ); // Consumes document fragment.\n\t * ```\n\t *\n\t * Consuming classes and styles as attribute will test if all added classes/styles can be consumed.\n\t *\n\t * ```ts\n\t * viewConsumable.consume( p, { attributes: 'class' } ); // Consume only if all added classes can be consumed.\n\t * viewConsumable.consume( p, { attributes: 'style' } ); // Consume only if all added styles can be consumed.\n\t * ```\n\t *\n\t * @param consumables Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param consumables.name If set to true element's name will be included.\n\t * @param consumables.attributes Attribute name or array of attribute names.\n\t * @param consumables.classes Class name or array of class names.\n\t * @param consumables.styles Style name or array of style names.\n\t * @returns Returns `true` when all items included in method's call can be consumed,\n\t * otherwise returns `false`.\n\t */\n\tpublic consume( element: Node | DocumentFragment, consumables?: Consumables | Match ): boolean {\n\t\tif ( this.test( element, consumables ) ) {\n\t\t\tif ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {\n\t\t\t\t// For text nodes and document fragments set value to false.\n\t\t\t\tthis._consumables.set( element, false );\n\t\t\t} else {\n\t\t\t\t// For elements - consume consumables object.\n\t\t\t\t( this._consumables.get( element ) as ViewElementConsumables ).consume( consumables! );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Reverts {@link module:engine/view/element~Element view element}, {@link module:engine/view/text~Text text node} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment document fragment} so they can be consumed once again.\n\t * Method does not revert items that were never previously added for consumption, even if they are included in\n\t * method's call.\n\t *\n\t * ```ts\n\t * viewConsumable.revert( p, { name: true } ); // Reverts element's name.\n\t * viewConsumable.revert( p, { attributes: 'name' } ); // Reverts element's attribute.\n\t * viewConsumable.revert( p, { classes: 'foobar' } ); // Reverts element's class.\n\t * viewConsumable.revert( p, { styles: 'color' } ); // Reverts element's style.\n\t * viewConsumable.revert( p, { attributes: 'name', styles: 'color' } ); // Reverts attribute and style.\n\t * viewConsumable.revert( p, { classes: [ 'baz', 'bar' ] } ); // Multiple names can be reverted.\n\t * viewConsumable.revert( textNode ); // Reverts text node.\n\t * viewConsumable.revert( docFragment ); // Reverts document fragment.\n\t * ```\n\t *\n\t * Reverting classes and styles as attribute will revert all classes/styles that were previously added for\n\t * consumption.\n\t *\n\t * ```ts\n\t * viewConsumable.revert( p, { attributes: 'class' } ); // Reverts all classes added for consumption.\n\t * viewConsumable.revert( p, { attributes: 'style' } ); // Reverts all styles added for consumption.\n\t * ```\n\t *\n\t * @param consumables Used only if first parameter is {@link module:engine/view/element~Element view element} instance.\n\t * @param consumables.name If set to true element's name will be included.\n\t * @param consumables.attributes Attribute name or array of attribute names.\n\t * @param consumables.classes Class name or array of class names.\n\t * @param consumables.styles Style name or array of style names.\n\t */\n\tpublic revert( element: Node, consumables: Consumables ): void {\n\t\tconst elementConsumables = this._consumables.get( element );\n\n\t\tif ( elementConsumables !== undefined ) {\n\t\t\tif ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {\n\t\t\t\t// For text nodes and document fragments - set consumable to true.\n\t\t\t\tthis._consumables.set( element, true );\n\t\t\t} else {\n\t\t\t\t// For elements - revert items from consumables object.\n\t\t\t\t( elementConsumables as ViewElementConsumables ).revert( consumables );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates consumable object from {@link module:engine/view/element~Element view element}. Consumable object will include\n\t * element's name and all its attributes, classes and styles.\n\t */\n\tpublic static consumablesFromElement( element: Element ): Consumables & { element: Element } {\n\t\tconst consumables = {\n\t\t\telement,\n\t\t\tname: true,\n\t\t\tattributes: [] as Array<string>,\n\t\t\tclasses: [] as Array<string>,\n\t\t\tstyles: [] as Array<string>\n\t\t};\n\n\t\tconst attributes = element.getAttributeKeys();\n\n\t\tfor ( const attribute of attributes ) {\n\t\t\t// Skip classes and styles - will be added separately.\n\t\t\tif ( attribute == 'style' || attribute == 'class' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconsumables.attributes.push( attribute );\n\t\t}\n\n\t\tconst classes = element.getClassNames();\n\n\t\tfor ( const className of classes ) {\n\t\t\tconsumables.classes.push( className );\n\t\t}\n\n\t\tconst styles = element.getStyleNames();\n\n\t\tfor ( const style of styles ) {\n\t\t\tconsumables.styles.push( style );\n\t\t}\n\n\t\treturn consumables;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/viewconsumable~ViewConsumable ViewConsumable} instance from\n\t * {@link module:engine/view/node~Node node} or {@link module:engine/view/documentfragment~DocumentFragment document fragment}.\n\t * Instance will contain all elements, child nodes, attributes, styles and classes added for consumption.\n\t *\n\t * @param from View node or document fragment from which `ViewConsumable` will be created.\n\t * @param instance If provided, given `ViewConsumable` instance will be used\n\t * to add all consumables. It will be returned instead of a new instance.\n\t */\n\tpublic static createFrom( from: Node | DocumentFragment, instance?: ViewConsumable ): ViewConsumable {\n\t\tif ( !instance ) {\n\t\t\tinstance = new ViewConsumable();\n\t\t}\n\n\t\tif ( from.is( '$text' ) ) {\n\t\t\tinstance.add( from );\n\n\t\t\treturn instance;\n\t\t}\n\n\t\t// Add `from` itself, if it is an element.\n\t\tif ( from.is( 'element' ) ) {\n\t\t\tinstance.add( from, ViewConsumable.consumablesFromElement( from ) );\n\t\t}\n\n\t\tif ( from.is( 'documentFragment' ) ) {\n\t\t\tinstance.add( from );\n\t\t}\n\n\t\tfor ( const child of ( from as Element | DocumentFragment ).getChildren() ) {\n\t\t\tinstance = ViewConsumable.createFrom( child, instance );\n\t\t}\n\n\t\treturn instance;\n\t}\n}\n\nexport interface Consumables {\n\n\t/**\n\t * If set to true element's name will be included.\n\t */\n\tname?: boolean;\n\n\t/**\n\t * Attribute name or array of attribute names.\n\t */\n\tattributes?: string | Array<string>;\n\n\t/**\n\t * Class name or array of class names.\n\t */\n\tclasses?: string | Array<string>;\n\n\t/**\n\t * Style name or array of style names.\n\t */\n\tstyles?: string | Array<string>;\n}\n\nconst CONSUMABLE_TYPES = [ 'attributes', 'classes', 'styles' ] as const;\n\ntype ConsumableType = ( typeof CONSUMABLE_TYPES )[ number ];\n\n/**\n * This is a private helper-class for {@link module:engine/conversion/viewconsumable~ViewConsumable}.\n * It represents and manipulates consumable parts of a single {@link module:engine/view/element~Element}.\n */\nexport class ViewElementConsumables {\n\tpublic readonly element: Node | DocumentFragment;\n\n\t/**\n\t * Flag indicating if name of the element can be consumed.\n\t */\n\tprivate _canConsumeName: boolean | null;\n\n\t/**\n\t * Contains maps of element's consumables: attributes, classes and styles.\n\t */\n\tprivate readonly _consumables: Record<ConsumableType, Map<string, boolean>>;\n\n\t/**\n\t * Creates ViewElementConsumables instance.\n\t *\n\t * @param from View node or document fragment from which `ViewElementConsumables` is being created.\n\t */\n\tconstructor( from: Node | DocumentFragment ) {\n\t\tthis.element = from;\n\t\tthis._canConsumeName = null;\n\t\tthis._consumables = {\n\t\t\tattributes: new Map(),\n\t\t\tstyles: new Map(),\n\t\t\tclasses: new Map()\n\t\t};\n\t}\n\n\t/**\n\t * Adds consumable parts of the {@link module:engine/view/element~Element view element}.\n\t * Element's name itself can be marked to be consumed (when element's name is consumed its attributes, classes and\n\t * styles still could be consumed):\n\t *\n\t * ```ts\n\t * consumables.add( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.add( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.add( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * attribute is provided - it should be handled separately by providing `style` and `class` in consumables object.\n\t *\n\t * @param consumables Object describing which parts of the element can be consumed.\n\t * @param consumables.name If set to `true` element's name will be added as consumable.\n\t * @param consumables.attributes Attribute name or array of attribute names to add as consumable.\n\t * @param consumables.classes Class name or array of class names to add as consumable.\n\t * @param consumables.styles Style name or array of style names to add as consumable.\n\t */\n\tpublic add( consumables: Consumables ): void {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = true;\n\t\t}\n\n\t\tfor ( const type of CONSUMABLE_TYPES ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._add( type, consumables[ type ]! );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Tests if parts of the {@link module:engine/view/node~Node view node} can be consumed.\n\t *\n\t * Element's name can be tested:\n\t *\n\t * ```ts\n\t * consumables.test( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.test( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.test( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * @param consumables Object describing which parts of the element should be tested.\n\t * @param consumables.name If set to `true` element's name will be tested.\n\t * @param consumables.attributes Attribute name or array of attribute names to test.\n\t * @param consumables.classes Class name or array of class names to test.\n\t * @param consumables.styles Style name or array of style names to test.\n\t * @returns `true` when all tested items can be consumed, `null` when even one of the items\n\t * was never marked for consumption and `false` when even one of the items was already consumed.\n\t */\n\tpublic test( consumables: Consumables | Match ): boolean | null {\n\t\t// Check if name can be consumed.\n\t\tif ( consumables.name && !this._canConsumeName ) {\n\t\t\treturn this._canConsumeName;\n\t\t}\n\n\t\tfor ( const type of CONSUMABLE_TYPES ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tconst value = this._test( type, consumables[ type ]! );\n\n\t\t\t\tif ( value !== true ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return true only if all can be consumed.\n\t\treturn true;\n\t}\n\n\t/**\n\t * Consumes parts of {@link module:engine/view/element~Element view element}. This function does not check if consumable item\n\t * is already consumed - it consumes all consumable items provided.\n\t * Element's name can be consumed:\n\t *\n\t * ```ts\n\t * consumables.consume( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.consume( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.consume( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * @param consumables Object describing which parts of the element should be consumed.\n\t * @param consumables.name If set to `true` element's name will be consumed.\n\t * @param consumables.attributes Attribute name or array of attribute names to consume.\n\t * @param consumables.classes Class name or array of class names to consume.\n\t * @param consumables.styles Style name or array of style names to consume.\n\t */\n\tpublic consume( consumables: Consumables | Match ): void {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = false;\n\t\t}\n\n\t\tfor ( const type of CONSUMABLE_TYPES ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._consume( type, consumables[ type ]! );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Revert already consumed parts of {@link module:engine/view/element~Element view Element}, so they can be consumed once again.\n\t * Element's name can be reverted:\n\t *\n\t * ```ts\n\t * consumables.revert( { name: true } );\n\t * ```\n\t *\n\t * Attributes classes and styles:\n\t *\n\t * ```ts\n\t * consumables.revert( { attributes: 'title', classes: 'foo', styles: 'color' } );\n\t * consumables.revert( { attributes: [ 'title', 'name' ], classes: [ 'foo', 'bar' ] );\n\t * ```\n\t *\n\t * @param consumables Object describing which parts of the element should be reverted.\n\t * @param consumables.name If set to `true` element's name will be reverted.\n\t * @param consumables.attributes Attribute name or array of attribute names to revert.\n\t * @param consumables.classes Class name or array of class names to revert.\n\t * @param consumables.styles Style name or array of style names to revert.\n\t */\n\tpublic revert( consumables: Consumables ): void {\n\t\tif ( consumables.name ) {\n\t\t\tthis._canConsumeName = true;\n\t\t}\n\n\t\tfor ( const type of CONSUMABLE_TYPES ) {\n\t\t\tif ( type in consumables ) {\n\t\t\t\tthis._revert( type, consumables[ type ]! );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that adds consumables of a given type: attribute, class or style.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `viewconsumable-invalid-attribute` when `class` or `style`\n\t * type is provided - it should be handled separately by providing actual style/class type.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param item Consumable item or array of items.\n\t */\n\tprivate _add( type: ConsumableType, item: ArrayOrItem<string> ) {\n\t\tconst items = toArray( item );\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\t/**\n\t\t\t\t * Class and style attributes should be handled separately in\n\t\t\t\t * {@link module:engine/conversion/viewconsumable~ViewConsumable#add `ViewConsumable#add()`}.\n\t\t\t\t *\n\t\t\t\t * What you have done is trying to use:\n\t\t\t\t *\n\t\t\t\t * ```ts\n\t\t\t\t * consumables.add( { attributes: [ 'class', 'style' ] } );\n\t\t\t\t * ```\n\t\t\t\t *\n\t\t\t\t * While each class and style should be registered separately:\n\t\t\t\t *\n\t\t\t\t * ```ts\n\t\t\t\t * consumables.add( { classes: 'some-class', styles: 'font-weight' } );\n\t\t\t\t * ```\n\t\t\t\t *\n\t\t\t\t * @error viewconsumable-invalid-attribute\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'viewconsumable-invalid-attribute', this );\n\t\t\t}\n\n\t\t\tconsumables.set( name, true );\n\n\t\t\tif ( type === 'styles' ) {\n\t\t\t\tfor ( const alsoName of this.element.document.stylesProcessor.getRelatedStyles( name ) ) {\n\t\t\t\t\tconsumables.set( alsoName, true );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that tests consumables of a given type: attribute, class or style.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param item Consumable item or array of items.\n\t * @returns Returns `true` if all items can be consumed, `null` when one of the items cannot be\n\t * consumed and `false` when one of the items is already consumed.\n\t */\n\tprivate _test( type: ConsumableType, item: ArrayOrItem<string> ): boolean | null {\n\t\tconst items = toArray( item );\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\tconst consumableName = name == 'class' ? 'classes' : 'styles';\n\n\t\t\t\t// Check all classes/styles if class/style attribute is tested.\n\t\t\t\tconst value = this._test( consumableName, [ ...this._consumables[ consumableName ].keys() ] );\n\n\t\t\t\tif ( value !== true ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst value = consumables.get( name );\n\t\t\t\t// Return null if attribute is not found.\n\t\t\t\tif ( value === undefined ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif ( !value ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Helper method that consumes items of a given type: attribute, class or style.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or `styles`.\n\t * @param item Consumable item or array of items.\n\t */\n\tprivate _consume( type: ConsumableType, item: ArrayOrItem<string> ) {\n\t\tconst items = toArray( item );\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\tconst consumableName = name == 'class' ? 'classes' : 'styles';\n\n\t\t\t\t// If class or style is provided for consumption - consume them all.\n\t\t\t\tthis._consume( consumableName, [ ...this._consumables[ consumableName ].keys() ] );\n\t\t\t} else {\n\t\t\t\tconsumables.set( name, false );\n\n\t\t\t\tif ( type == 'styles' ) {\n\t\t\t\t\tfor ( const toConsume of this.element.document.stylesProcessor.getRelatedStyles( name ) ) {\n\t\t\t\t\t\tconsumables.set( toConsume, false );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper method that reverts items of a given type: attribute, class or style.\n\t *\n\t * @param type Type of the consumable item: `attributes`, `classes` or , `styles`.\n\t * @param item Consumable item or array of items.\n\t */\n\tprivate _revert( type: ConsumableType, item: ArrayOrItem<string> ) {\n\t\tconst items = toArray( item );\n\t\tconst consumables = this._consumables[ type ];\n\n\t\tfor ( const name of items ) {\n\t\t\tif ( type === 'attributes' && ( name === 'class' || name === 'style' ) ) {\n\t\t\t\tconst consumableName = name == 'class' ? 'classes' : 'styles';\n\n\t\t\t\t// If class or style is provided for reverting - revert them all.\n\t\t\t\tthis._revert( consumableName, [ ...this._consumables[ consumableName ].keys() ] );\n\t\t\t} else {\n\t\t\t\tconst value = consumables.get( name );\n\n\t\t\t\tif ( value === false ) {\n\t\t\t\t\tconsumables.set( name, true );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/schema\n */\n\nimport Element from './element.js';\nimport Position from './position.js';\nimport Range from './range.js';\nimport Text from './text.js';\nimport TreeWalker from './treewalker.js';\n\nimport type DocumentFragment from './documentfragment.js';\nimport type DocumentSelection from './documentselection.js';\nimport type Item from './item.js';\nimport type Node from './node.js';\nimport type Selection from './selection.js';\nimport type Writer from './writer.js';\n\nimport { CKEditorError, first, ObservableMixin } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The model's schema. It defines the allowed and disallowed structures of nodes as well as nodes' attributes.\n * The schema is usually defined by the features and based on them, the editing framework and features\n * make decisions on how to change and process the model.\n *\n * The instance of schema is available in {@link module:engine/model/model~Model#schema `editor.model.schema`}.\n *\n * Read more about the schema in:\n *\n * * The {@glink framework/architecture/editing-engine#schema schema section} of the\n * {@glink framework/architecture/editing-engine Introduction to the Editing engine architecture} guide.\n * * The {@glink framework/deep-dive/schema Schema deep-dive} guide.\n */\nexport default class Schema extends /* #__PURE__ */ ObservableMixin() {\n\tprivate readonly _sourceDefinitions: Record<string, Array<SchemaItemDefinition>> = {};\n\n\t/**\n\t * A dictionary containing attribute properties.\n\t */\n\tprivate readonly _attributeProperties: Record<string, AttributeProperties> = Object.create( null );\n\n\t/**\n\t * Stores additional callbacks registered for schema items, which are evaluated when {@link ~Schema#checkChild} is called.\n\t *\n\t * Keys are schema item names for which the callbacks are registered. Values are arrays with the callbacks.\n\t *\n\t * Some checks are added under {@link ~Schema#_genericCheckSymbol} key, these are evaluated for every {@link ~Schema#checkChild} call.\n\t */\n\tprivate readonly _customChildChecks: Map<string | symbol, Array<SchemaChildCheckCallback>> = new Map();\n\n\t/**\n\t * Stores additional callbacks registered for attribute names, which are evaluated when {@link ~Schema#checkAttribute} is called.\n\t *\n\t * Keys are schema attribute names for which the callbacks are registered. Values are arrays with the callbacks.\n\t *\n\t * Some checks are added under {@link ~Schema#_genericCheckSymbol} key, these are evaluated for every\n\t * {@link ~Schema#checkAttribute} call.\n\t */\n\tprivate readonly _customAttributeChecks: Map<string | symbol, Array<SchemaAttributeCheckCallback>> = new Map();\n\n\tprivate readonly _genericCheckSymbol = Symbol( '$generic' );\n\n\tprivate _compiledDefinitions?: Record<string, SchemaCompiledItemDefinition> | null;\n\n\t/**\n\t * Creates a schema instance.\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.decorate( 'checkChild' );\n\t\tthis.decorate( 'checkAttribute' );\n\n\t\tthis.on( 'checkAttribute', ( evt, args ) => {\n\t\t\targs[ 0 ] = new SchemaContext( args[ 0 ] );\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.on( 'checkChild', ( evt, args ) => {\n\t\t\targs[ 0 ] = new SchemaContext( args[ 0 ] );\n\t\t\targs[ 1 ] = this.getDefinition( args[ 1 ] );\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Registers a schema item. Can only be called once for every item name.\n\t *\n\t * ```ts\n\t * schema.register( 'paragraph', {\n\t * \tinheritAllFrom: '$block'\n\t * } );\n\t * ```\n\t */\n\tpublic register( itemName: string, definition?: SchemaItemDefinition ): void {\n\t\tif ( this._sourceDefinitions[ itemName ] ) {\n\t\t\t/**\n\t\t\t * A single item cannot be registered twice in the schema.\n\t\t\t *\n\t\t\t * This situation may happen when:\n\t\t\t *\n\t\t\t * * Two or more plugins called {@link module:engine/model/schema~Schema#register `register()`} with the same name.\n\t\t\t * This will usually mean that there is a collision between plugins which try to use the same element in the model.\n\t\t\t * Unfortunately, the only way to solve this is by modifying one of these plugins to use a unique model element name.\n\t\t\t * * A single plugin was loaded twice. This happens when it is installed by npm/yarn in two versions\n\t\t\t * and usually means one or more of the following issues:\n\t\t\t *     * a version mismatch (two of your dependencies require two different versions of this plugin),\n\t\t\t *     * incorrect imports (this plugin is somehow imported twice in a way which confuses webpack),\n\t\t\t *     * mess in `node_modules/` (`rm -rf node_modules/` may help).\n\t\t\t *\n\t\t\t * **Note:** Check the logged `itemName` to better understand which plugin was duplicated/conflicting.\n\t\t\t *\n\t\t\t * @param itemName The name of the model element that is being registered twice.\n\t\t\t * @error schema-cannot-register-item-twice\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'schema-cannot-register-item-twice',\n\t\t\t\tthis,\n\t\t\t\t{\n\t\t\t\t\titemName\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tthis._sourceDefinitions[ itemName ] = [\n\t\t\tObject.assign( {}, definition )\n\t\t];\n\n\t\tthis._clearCache();\n\t}\n\n\t/**\n\t * Extends a {@link #register registered} item's definition.\n\t *\n\t * Extending properties such as `allowIn` will add more items to the existing properties,\n\t * while redefining properties such as `isBlock` will override the previously defined ones.\n\t *\n\t * ```ts\n\t * schema.register( 'foo', {\n\t * \tallowIn: '$root',\n\t * \tisBlock: true;\n\t * } );\n\t * schema.extend( 'foo', {\n\t * \tallowIn: 'blockQuote',\n\t * \tisBlock: false\n\t * } );\n\t *\n\t * schema.getDefinition( 'foo' );\n\t * //\t{\n\t * //\t\tallowIn: [ '$root', 'blockQuote' ],\n\t * // \t\tisBlock: false\n\t * //\t}\n\t * ```\n\t */\n\tpublic extend( itemName: string, definition: SchemaItemDefinition ): void {\n\t\tif ( !this._sourceDefinitions[ itemName ] ) {\n\t\t\t/**\n\t\t\t * Cannot extend an item which was not registered yet.\n\t\t\t *\n\t\t\t * This error happens when a plugin tries to extend the schema definition of an item which was not\n\t\t\t * {@link module:engine/model/schema~Schema#register registered} yet.\n\t\t\t *\n\t\t\t * @param itemName The name of the model element which is being extended.\n\t\t\t * @error schema-cannot-extend-missing-item\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'schema-cannot-extend-missing-item', this, {\n\t\t\t\titemName\n\t\t\t} );\n\t\t}\n\n\t\tthis._sourceDefinitions[ itemName ].push( Object.assign( {}, definition ) );\n\n\t\tthis._clearCache();\n\t}\n\n\t/**\n\t * Returns data of all registered items.\n\t *\n\t * This method should normally be used for reflection purposes (e.g. defining a clone of a certain element,\n\t * checking a list of all block elements, etc).\n\t * Use specific methods (such as {@link #checkChild `checkChild()`} or {@link #isLimit `isLimit()`})\n\t * in other cases.\n\t */\n\tpublic getDefinitions(): Record<string, SchemaCompiledItemDefinition> {\n\t\tif ( !this._compiledDefinitions ) {\n\t\t\tthis._compile();\n\t\t}\n\n\t\treturn this._compiledDefinitions!;\n\t}\n\n\t/**\n\t * Returns a definition of the given item or `undefined` if an item is not registered.\n\t *\n\t * This method should normally be used for reflection purposes (e.g. defining a clone of a certain element,\n\t * checking a list of all block elements, etc).\n\t * Use specific methods (such as {@link #checkChild `checkChild()`} or {@link #isLimit `isLimit()`})\n\t * in other cases.\n\t */\n\tpublic getDefinition( item: string | Item | DocumentFragment | SchemaContextItem ): SchemaCompiledItemDefinition | undefined {\n\t\tlet itemName: string;\n\n\t\tif ( typeof item == 'string' ) {\n\t\t\titemName = item;\n\t\t} else if ( 'is' in item && ( item.is( '$text' ) || item.is( '$textProxy' ) ) ) {\n\t\t\titemName = '$text';\n\t\t}\n\t\t// Element or module:engine/model/schema~SchemaContextItem.\n\t\telse {\n\t\t\titemName = ( item as any ).name;\n\t\t}\n\n\t\treturn this.getDefinitions()[ itemName ];\n\t}\n\n\t/**\n\t * Returns `true` if the given item is registered in the schema.\n\t *\n\t * ```ts\n\t * schema.isRegistered( 'paragraph' ); // -> true\n\t * schema.isRegistered( editor.model.document.getRoot() ); // -> true\n\t * schema.isRegistered( 'foo' ); // -> false\n\t * ```\n\t */\n\tpublic isRegistered( item: string | Item | DocumentFragment | SchemaContextItem ): boolean {\n\t\treturn !!this.getDefinition( item );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * a block by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isBlock` property.\n\t *\n\t * ```ts\n\t * schema.isBlock( 'paragraph' ); // -> true\n\t * schema.isBlock( '$root' ); // -> false\n\t *\n\t * const paragraphElement = writer.createElement( 'paragraph' );\n\t * schema.isBlock( paragraphElement ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#block-elements Block elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */\n\tpublic isBlock( item: string | Item | DocumentFragment | SchemaContextItem ): boolean {\n\t\tconst def = this.getDefinition( item );\n\n\t\treturn !!( def && def.isBlock );\n\t}\n\n\t/**\n\t * Returns `true` if the given item should be treated as a limit element.\n\t *\n\t * It considers an item to be a limit element if its\n\t * {@link module:engine/model/schema~SchemaItemDefinition}'s\n\t * {@link module:engine/model/schema~SchemaItemDefinition#isLimit `isLimit`} or\n\t * {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} property\n\t * was set to `true`.\n\t *\n\t * ```ts\n\t * schema.isLimit( 'paragraph' ); // -> false\n\t * schema.isLimit( '$root' ); // -> true\n\t * schema.isLimit( editor.model.document.getRoot() ); // -> true\n\t * schema.isLimit( 'imageBlock' ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#limit-elements Limit elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */\n\tpublic isLimit( item: string | Item | DocumentFragment | SchemaContextItem ): boolean {\n\t\tconst def = this.getDefinition( item );\n\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !!( def.isLimit || def.isObject );\n\t}\n\n\t/**\n\t * Returns `true` if the given item should be treated as an object element.\n\t *\n\t * It considers an item to be an object element if its\n\t * {@link module:engine/model/schema~SchemaItemDefinition}'s\n\t * {@link module:engine/model/schema~SchemaItemDefinition#isObject `isObject`} property\n\t * was set to `true`.\n\t *\n\t * ```ts\n\t * schema.isObject( 'paragraph' ); // -> false\n\t * schema.isObject( 'imageBlock' ); // -> true\n\t *\n\t * const imageElement = writer.createElement( 'imageBlock' );\n\t * schema.isObject( imageElement ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#object-elements Object elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */\n\tpublic isObject( item: string | Item | DocumentFragment | SchemaContextItem ): boolean {\n\t\tconst def = this.getDefinition( item );\n\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Note: Check out the implementation of #isLimit(), #isSelectable(), and #isContent()\n\t\t// to understand why these three constitute an object.\n\t\treturn !!( def.isObject || ( def.isLimit && def.isSelectable && def.isContent ) );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * an inline element by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isInline` property.\n\t *\n\t * ```ts\n\t * schema.isInline( 'paragraph' ); // -> false\n\t * schema.isInline( 'softBreak' ); // -> true\n\t *\n\t * const text = writer.createText( 'foo' );\n\t * schema.isInline( text ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#inline-elements Inline elements} section of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */\n\tpublic isInline( item: string | Item | DocumentFragment | SchemaContextItem ): boolean {\n\t\tconst def = this.getDefinition( item );\n\n\t\treturn !!( def && def.isInline );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * a selectable element by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isSelectable` property.\n\t *\n\t * ```ts\n\t * schema.isSelectable( 'paragraph' ); // -> false\n\t * schema.isSelectable( 'heading1' ); // -> false\n\t * schema.isSelectable( 'imageBlock' ); // -> true\n\t * schema.isSelectable( 'tableCell' ); // -> true\n\t *\n\t * const text = writer.createText( 'foo' );\n\t * schema.isSelectable( text ); // -> false\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#selectable-elements Selectable elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */\n\tpublic isSelectable( item: string | Item | DocumentFragment | SchemaContextItem ): boolean {\n\t\tconst def = this.getDefinition( item );\n\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !!( def.isSelectable || def.isObject );\n\t}\n\n\t/**\n\t * Returns `true` if the given item is defined to be\n\t * a content by the {@link module:engine/model/schema~SchemaItemDefinition}'s `isContent` property.\n\t *\n\t * ```ts\n\t * schema.isContent( 'paragraph' ); // -> false\n\t * schema.isContent( 'heading1' ); // -> false\n\t * schema.isContent( 'imageBlock' ); // -> true\n\t * schema.isContent( 'horizontalLine' ); // -> true\n\t *\n\t * const text = writer.createText( 'foo' );\n\t * schema.isContent( text ); // -> true\n\t * ```\n\t *\n\t * See the {@glink framework/deep-dive/schema#content-elements Content elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide for more details.\n\t */\n\tpublic isContent( item: string | Item | DocumentFragment | SchemaContextItem ): boolean {\n\t\tconst def = this.getDefinition( item );\n\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !!( def.isContent || def.isObject );\n\t}\n\n\t/**\n\t * Checks whether the given node can be a child of the given context.\n\t *\n\t * ```ts\n\t * schema.checkChild( model.document.getRoot(), paragraph ); // -> false\n\t *\n\t * schema.register( 'paragraph', {\n\t * \tallowIn: '$root'\n\t * } );\n\t *\n\t * schema.checkChild( model.document.getRoot(), paragraph ); // -> true\n\t * ```\n\t *\n\t * Both {@link module:engine/model/schema~Schema#addChildCheck callback checks} and declarative rules (added when\n\t * {@link module:engine/model/schema~Schema#register registering} and {@link module:engine/model/schema~Schema#extend extending} items)\n\t * are evaluated when this method is called.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * Note that when verifying whether the given node can be a child of the given context, the schema also verifies the entire\n\t * context &ndash; from its root to its last element. Therefore, it is possible for `checkChild()` to return `false` even though\n\t * the `context` last element can contain the checked child. It happens if one of the `context` elements does not allow its child.\n\t * When `context` is verified, {@link module:engine/model/schema~Schema#addChildCheck custom checks} are considered as well.\n\t *\n\t * @fires checkChild\n\t * @param context The context in which the child will be checked.\n\t * @param def The child to check.\n\t */\n\tpublic checkChild( context: SchemaContextDefinition, def: string | Node | DocumentFragment ): boolean {\n\t\t// Note: `context` and `def` are already normalized here to `SchemaContext` and `SchemaCompiledItemDefinition`.\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this._checkContextMatch( context as SchemaContext, def as unknown as SchemaCompiledItemDefinition );\n\t}\n\n\t/**\n\t * Checks whether the given attribute can be applied in the given context (on the last item of the context).\n\t *\n\t * ```ts\n\t * schema.checkAttribute( textNode, 'bold' ); // -> false\n\t *\n\t * schema.extend( '$text', {\n\t * \tallowAttributes: 'bold'\n\t * } );\n\t *\n\t * schema.checkAttribute( textNode, 'bold' ); // -> true\n\t * ```\n\t *\n\t * Both {@link module:engine/model/schema~Schema#addAttributeCheck callback checks} and declarative rules (added when\n\t * {@link module:engine/model/schema~Schema#register registering} and {@link module:engine/model/schema~Schema#extend extending} items)\n\t * are evaluated when this method is called.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * @fires checkAttribute\n\t * @param context The context in which the attribute will be checked.\n\t * @param attributeName Name of attribute to check in the given context.\n\t */\n\tpublic checkAttribute( context: SchemaContextDefinition, attributeName: string ): boolean {\n\t\t// Note: `context` is already normalized here to `SchemaContext`.\n\t\tconst def = this.getDefinition( ( context as SchemaContext ).last );\n\n\t\tif ( !def ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// First, check all attribute checks declared as callbacks.\n\t\t// Note that `_evaluateAttributeChecks()` will return `undefined` if neither child check was applicable (no decision was made).\n\t\tconst isAllowed = this._evaluateAttributeChecks( context as SchemaContext, attributeName );\n\n\t\t// If the decision was not made inside attribute check callbacks, then use declarative rules.\n\t\treturn isAllowed !== undefined ? isAllowed : def.allowAttributes.includes( attributeName );\n\t}\n\n\tpublic checkMerge( position: Position ): boolean;\n\tpublic checkMerge( baseElement: Element, elementToMerge: Element ): boolean;\n\n\t/**\n\t * Checks whether the given element (`elementToMerge`) can be merged with the specified base element (`positionOrBaseElement`).\n\t *\n\t * In other words &ndash; both elements are not a limit elements and whether `elementToMerge`'s children\n\t * {@link #checkChild are allowed} in the `positionOrBaseElement`.\n\t *\n\t * This check ensures that elements merged with {@link module:engine/model/writer~Writer#merge `Writer#merge()`}\n\t * will be valid.\n\t *\n\t * Instead of elements, you can pass the instance of the {@link module:engine/model/position~Position} class as the\n\t * `positionOrBaseElement`. It means that the elements before and after the position will be checked whether they can be merged.\n\t *\n\t * @param positionOrBaseElement The position or base element to which the `elementToMerge` will be merged.\n\t * @param elementToMerge The element to merge. Required if `positionOrBaseElement` is an element.\n\t */\n\tpublic checkMerge( positionOrBaseElement: Position | Element, elementToMerge?: Element ): boolean {\n\t\tif ( positionOrBaseElement instanceof Position ) {\n\t\t\tconst nodeBefore = positionOrBaseElement.nodeBefore;\n\t\t\tconst nodeAfter = positionOrBaseElement.nodeAfter;\n\n\t\t\tif ( !( nodeBefore instanceof Element ) ) {\n\t\t\t\t/**\n\t\t\t\t * The node before the merge position must be an element.\n\t\t\t\t *\n\t\t\t\t * @error schema-check-merge-no-element-before\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'schema-check-merge-no-element-before',\n\t\t\t\t\tthis\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( !( nodeAfter instanceof Element ) ) {\n\t\t\t\t/**\n\t\t\t\t * The node after the merge position must be an element.\n\t\t\t\t *\n\t\t\t\t * @error schema-check-merge-no-element-after\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'schema-check-merge-no-element-after',\n\t\t\t\t\tthis\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn this.checkMerge( nodeBefore, nodeAfter );\n\t\t}\n\n\t\tif ( this.isLimit( positionOrBaseElement ) || this.isLimit( elementToMerge! ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const child of elementToMerge!.getChildren() ) {\n\t\t\tif ( !this.checkChild( positionOrBaseElement, child ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Allows registering a callback to the {@link #checkChild} method calls.\n\t *\n\t * Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t * by using the declarative API of {@link module:engine/model/schema~SchemaItemDefinition}.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * For example, by using this method you can disallow elements in specific contexts:\n\t *\n\t * ```ts\n\t * // Disallow `heading1` inside a `blockQuote` that is inside a table.\n\t * schema.addChildCheck( ( context, childDefinition ) => {\n\t * \tif ( context.endsWith( 'tableCell blockQuote' ) ) {\n\t * \t\treturn false;\n\t * \t}\n\t * }, 'heading1' );\n\t * ```\n\t *\n\t * You can skip the optional `itemName` parameter to evaluate the callback for every `checkChild()` call.\n\t *\n\t * ```ts\n\t * // Inside specific custom element, allow only children, which allows for a specific attribute.\n\t * schema.addChildCheck( ( context, childDefinition ) => {\n\t * \tif ( context.endsWith( 'myElement' ) ) {\n\t * \t\treturn childDefinition.allowAttributes.includes( 'myAttribute' );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Please note that the generic callbacks may affect the editor performance and should be avoided if possible.\n\t *\n\t * When one of the callbacks makes a decision (returns `true` or `false`) the processing is finished and other callbacks are not fired.\n\t * Callbacks are fired in the order they were added, however generic callbacks are fired before callbacks added for a specified item.\n\t *\n\t * You can also use `checkChild` event, if you need even better control. The result from the example above could also be\n\t * achieved with following event callback:\n\t *\n\t * ```ts\n\t * schema.on( 'checkChild', ( evt, args ) => {\n\t * \tconst context = args[ 0 ];\n\t * \tconst childDefinition = args[ 1 ];\n\t *\n\t * \tif ( context.endsWith( 'myElement' ) ) {\n\t * \t\t// Prevent next listeners from being called.\n\t * \t\tevt.stop();\n\t * \t\t// Set the `checkChild()` return value.\n\t * \t\tevt.return = childDefinition.allowAttributes.includes( 'myAttribute' );\n\t * \t}\n\t * }, { priority: 'high' } );\n\t * ```\n\t *\n\t * Note that the callback checks and declarative rules checks are processed on `normal` priority.\n\t *\n\t * Adding callbacks this way can also negatively impact editor performance.\n\t *\n\t * @param callback The callback to be called. It is called with two parameters:\n\t * {@link module:engine/model/schema~SchemaContext} (context) instance and\n\t * {@link module:engine/model/schema~SchemaCompiledItemDefinition} (definition). The callback may return `true/false` to override\n\t * `checkChild()`'s return value. If it does not return a boolean value, the default algorithm (or other callbacks) will define\n\t * `checkChild()`'s return value.\n\t * @param itemName Name of the schema item for which the callback is registered. If specified, the callback will be run only for\n\t * `checkChild()` calls which `def` parameter matches the `itemName`. Otherwise, the callback will run for every `checkChild` call.\n\t */\n\tpublic addChildCheck( callback: SchemaChildCheckCallback, itemName?: string ): void {\n\t\tconst key = itemName !== undefined ? itemName : this._genericCheckSymbol;\n\n\t\tconst checks = this._customChildChecks.get( key ) || [];\n\t\tchecks.push( callback );\n\n\t\tthis._customChildChecks.set( key, checks );\n\t}\n\n\t/**\n\t * Allows registering a callback to the {@link #checkAttribute} method calls.\n\t *\n\t * Callbacks allow you to implement rules which are not otherwise possible to achieve\n\t * by using the declarative API of {@link module:engine/model/schema~SchemaItemDefinition}.\n\t *\n\t * Note that callback checks have bigger priority than declarative rules checks and may overwrite them.\n\t *\n\t * For example, by using this method you can disallow setting attributes on nodes in specific contexts:\n\t *\n\t * ```ts\n\t * // Disallow setting `bold` on text inside `heading1` element:\n\t * schema.addAttributeCheck( context => {\n\t * \tif ( context.endsWith( 'heading1 $text' ) ) {\n\t * \t\treturn false;\n\t * \t}\n\t * }, 'bold' );\n\t * ```\n\t *\n\t * You can skip the optional `attributeName` parameter to evaluate the callback for every `checkAttribute()` call.\n\t *\n\t * ```ts\n\t * // Disallow formatting attributes on text inside custom `myTitle` element:\n\t * schema.addAttributeCheck( ( context, attributeName ) => {\n\t * \tif ( context.endsWith( 'myTitle $text' ) && schema.getAttributeProperties( attributeName ).isFormatting ) {\n\t * \t\treturn false;\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Please note that the generic callbacks may affect the editor performance and should be avoided if possible.\n\t *\n\t * When one of the callbacks makes a decision (returns `true` or `false`) the processing is finished and other callbacks are not fired.\n\t * Callbacks are fired in the order they were added, however generic callbacks are fired before callbacks added for a specified item.\n\t *\n\t * You can also use {@link #event:checkAttribute} event, if you need even better control. The result from the example above could also\n\t * be achieved with following event callback:\n\t *\n\t * ```ts\n\t * schema.on( 'checkAttribute', ( evt, args ) => {\n\t * \tconst context = args[ 0 ];\n\t * \tconst attributeName = args[ 1 ];\n\t *\n\t * \tif ( context.endsWith( 'myTitle $text' ) && schema.getAttributeProperties( attributeName ).isFormatting ) {\n\t * \t\t// Prevent next listeners from being called.\n\t * \t\tevt.stop();\n\t * \t\t// Set the `checkAttribute()` return value.\n\t * \t\tevt.return = false;\n\t * \t}\n\t * }, { priority: 'high' } );\n\t * ```\n\t *\n\t * Note that the callback checks and declarative rules checks are processed on `normal` priority.\n\t *\n\t * Adding callbacks this way can also negatively impact editor performance.\n\t *\n\t * @param callback The callback to be called. It is called with two parameters:\n\t * {@link module:engine/model/schema~SchemaContext `context`} and attribute name. The callback may return `true` or `false`, to\n\t * override `checkAttribute()`'s return value. If it does not return a boolean value, the default algorithm (or other callbacks)\n\t * will define `checkAttribute()`'s return value.\n\t * @param attributeName Name of the attribute for which the callback is registered. If specified, the callback will be run only for\n\t * `checkAttribute()` calls with matching `attributeName`. Otherwise, the callback will run for every `checkAttribute()` call.\n\t */\n\tpublic addAttributeCheck( callback: SchemaAttributeCheckCallback, attributeName?: string ): void {\n\t\tconst key = attributeName !== undefined ? attributeName : this._genericCheckSymbol;\n\n\t\tconst checks = this._customAttributeChecks.get( key ) || [];\n\t\tchecks.push( callback );\n\n\t\tthis._customAttributeChecks.set( key, checks );\n\t}\n\n\t/**\n\t * This method allows assigning additional metadata to the model attributes. For example,\n\t * {@link module:engine/model/schema~AttributeProperties `AttributeProperties#isFormatting` property} is\n\t * used to mark formatting attributes (like `bold` or `italic`).\n\t *\n\t * ```ts\n\t * // Mark bold as a formatting attribute.\n\t * schema.setAttributeProperties( 'bold', {\n\t * \tisFormatting: true\n\t * } );\n\t *\n\t * // Override code not to be considered a formatting markup.\n\t * schema.setAttributeProperties( 'code', {\n\t * \tisFormatting: false\n\t * } );\n\t * ```\n\t *\n\t * Properties are not limited to members defined in the\n\t * {@link module:engine/model/schema~AttributeProperties `AttributeProperties` type} and you can also use custom properties:\n\t *\n\t * ```ts\n\t * schema.setAttributeProperties( 'blockQuote', {\n\t * \tcustomProperty: 'value'\n\t * } );\n\t * ```\n\t *\n\t * Subsequent calls with the same attribute will extend its custom properties:\n\t *\n\t * ```ts\n\t * schema.setAttributeProperties( 'blockQuote', {\n\t * \tone: 1\n\t * } );\n\t *\n\t * schema.setAttributeProperties( 'blockQuote', {\n\t * \ttwo: 2\n\t * } );\n\t *\n\t * console.log( schema.getAttributeProperties( 'blockQuote' ) );\n\t * // Logs: { one: 1, two: 2 }\n\t * ```\n\t *\n\t * @param attributeName A name of the attribute to receive the properties.\n\t * @param properties A dictionary of properties.\n\t */\n\tpublic setAttributeProperties( attributeName: string, properties: AttributeProperties ): void {\n\t\tthis._attributeProperties[ attributeName ] = Object.assign( this.getAttributeProperties( attributeName ), properties );\n\t}\n\n\t/**\n\t * Returns properties associated with a given model attribute. See {@link #setAttributeProperties `setAttributeProperties()`}.\n\t *\n\t * @param attributeName A name of the attribute.\n\t */\n\tpublic getAttributeProperties( attributeName: string ): AttributeProperties {\n\t\treturn this._attributeProperties[ attributeName ] || Object.create( null );\n\t}\n\n\t/**\n\t * Returns the lowest {@link module:engine/model/schema~Schema#isLimit limit element} containing the entire\n\t * selection/range/position or the root otherwise.\n\t *\n\t * @param selectionOrRangeOrPosition The selection/range/position to check.\n\t * @returns The lowest limit element containing the entire `selectionOrRangeOrPosition`.\n\t */\n\tpublic getLimitElement( selectionOrRangeOrPosition: Selection | DocumentSelection | Range | Position ): Element {\n\t\tlet element: Element;\n\n\t\tif ( selectionOrRangeOrPosition instanceof Position ) {\n\t\t\telement = selectionOrRangeOrPosition.parent as Element;\n\t\t} else {\n\t\t\tconst ranges = selectionOrRangeOrPosition instanceof Range ?\n\t\t\t\t[ selectionOrRangeOrPosition ] :\n\t\t\t\tArray.from( selectionOrRangeOrPosition.getRanges() );\n\n\t\t\t// Find the common ancestor for all selection's ranges.\n\t\t\telement = ranges\n\t\t\t\t.reduce<Element | null>( ( element, range ) => {\n\t\t\t\t\tconst rangeCommonAncestor = range.getCommonAncestor() as ( Element | null );\n\n\t\t\t\t\tif ( !element ) {\n\t\t\t\t\t\treturn rangeCommonAncestor;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn element.getCommonAncestor( rangeCommonAncestor as Element, { includeSelf: true } ) as Element;\n\t\t\t\t}, null )!;\n\t\t}\n\n\t\twhile ( !this.isLimit( element ) ) {\n\t\t\tif ( element.parent ) {\n\t\t\t\telement = element.parent as Element;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn element;\n\t}\n\n\t/**\n\t * Checks whether the attribute is allowed in selection:\n\t *\n\t * * if the selection is not collapsed, then checks if the attribute is allowed on any of nodes in that range,\n\t * * if the selection is collapsed, then checks if on the selection position there's a text with the\n\t * specified attribute allowed.\n\t *\n\t * @param selection Selection which will be checked.\n\t * @param attribute The name of the attribute to check.\n\t */\n\tpublic checkAttributeInSelection( selection: Selection | DocumentSelection, attribute: string ): boolean {\n\t\tif ( selection.isCollapsed ) {\n\t\t\tconst firstPosition = selection.getFirstPosition()!;\n\t\t\tconst context = [\n\t\t\t\t...firstPosition.getAncestors() as Array<Element>,\n\t\t\t\tnew Text( '', selection.getAttributes() )\n\t\t\t];\n\n\t\t\t// Check whether schema allows for a text with the attribute in the selection.\n\t\t\treturn this.checkAttribute( context, attribute );\n\t\t} else {\n\t\t\tconst ranges = selection.getRanges();\n\n\t\t\t// For all ranges, check nodes in them until you find a node that is allowed to have the attribute.\n\t\t\tfor ( const range of ranges ) {\n\t\t\t\tfor ( const value of range ) {\n\t\t\t\t\tif ( this.checkAttribute( value.item, attribute ) ) {\n\t\t\t\t\t\t// If we found a node that is allowed to have the attribute, return true.\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't found such node, return false.\n\t\treturn false;\n\t}\n\n\t/**\n\t * Transforms the given set of ranges into a set of ranges where the given attribute is allowed (and can be applied).\n\t *\n\t * @param ranges Ranges to be validated.\n\t * @param attribute The name of the attribute to check.\n\t * @returns Ranges in which the attribute is allowed.\n\t */\n\tpublic* getValidRanges( ranges: Iterable<Range>, attribute: string ): IterableIterator<Range> {\n\t\tranges = convertToMinimalFlatRanges( ranges );\n\n\t\tfor ( const range of ranges ) {\n\t\t\tyield* this._getValidRangesForRange( range, attribute );\n\t\t}\n\t}\n\n\t/**\n\t * Basing on given `position`, finds and returns a {@link module:engine/model/range~Range range} which is\n\t * nearest to that `position` and is a correct range for selection.\n\t *\n\t * The correct selection range might be collapsed when it is located in a position where the text node can be placed.\n\t * Non-collapsed range is returned when selection can be placed around element marked as an \"object\" in\n\t * the {@link module:engine/model/schema~Schema schema}.\n\t *\n\t * Direction of searching for the nearest correct selection range can be specified as:\n\t *\n\t * * `both` - searching will be performed in both ways,\n\t * * `forward` - searching will be performed only forward,\n\t * * `backward` - searching will be performed only backward.\n\t *\n\t * When valid selection range cannot be found, `null` is returned.\n\t *\n\t * @param position Reference position where new selection range should be looked for.\n\t * @param direction Search direction.\n\t * @returns Nearest selection range or `null` if one cannot be found.\n\t */\n\tpublic getNearestSelectionRange( position: Position, direction: 'both' | 'forward' | 'backward' = 'both' ): Range | null {\n\t\tif ( position.root.rootName == '$graveyard' ) {\n\t\t\t// No valid selection range in the graveyard.\n\t\t\t// This is important when getting the document selection default range.\n\t\t\treturn null;\n\t\t}\n\n\t\t// Return collapsed range if provided position is valid.\n\t\tif ( this.checkChild( position, '$text' ) ) {\n\t\t\treturn new Range( position );\n\t\t}\n\n\t\tlet backwardWalker, forwardWalker;\n\n\t\t// Never leave a limit element.\n\t\tconst limitElement = ( position.getAncestors() as Array<Element> ).reverse().find( item => this.isLimit( item ) ) ||\n\t\t\tposition.root as Element;\n\n\t\tif ( direction == 'both' || direction == 'backward' ) {\n\t\t\tbackwardWalker = new TreeWalker( {\n\t\t\t\tboundaries: Range._createIn( limitElement ),\n\t\t\t\tstartPosition: position,\n\t\t\t\tdirection: 'backward'\n\t\t\t} );\n\t\t}\n\n\t\tif ( direction == 'both' || direction == 'forward' ) {\n\t\t\tforwardWalker = new TreeWalker( {\n\t\t\t\tboundaries: Range._createIn( limitElement ),\n\t\t\t\tstartPosition: position\n\t\t\t} );\n\t\t}\n\n\t\tfor ( const data of combineWalkers( backwardWalker, forwardWalker ) ) {\n\t\t\tconst type = ( data.walker == backwardWalker ? 'elementEnd' : 'elementStart' );\n\t\t\tconst value = data.value;\n\n\t\t\tif ( value.type == type && this.isObject( value.item ) ) {\n\t\t\t\treturn Range._createOn( value.item );\n\t\t\t}\n\n\t\t\tif ( this.checkChild( value.nextPosition, '$text' ) ) {\n\t\t\t\treturn new Range( value.nextPosition );\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Tries to find position ancestors that allow to insert a given node.\n\t * It starts searching from the given position and goes node by node to the top of the model tree\n\t * as long as a {@link module:engine/model/schema~Schema#isLimit limit element}, an\n\t * {@link module:engine/model/schema~Schema#isObject object element} or a topmost ancestor is not reached.\n\t *\n\t * @param position The position that the search will start from.\n\t * @param node The node for which an allowed parent should be found or its name.\n\t * @returns Allowed parent or null if nothing was found.\n\t */\n\tpublic findAllowedParent( position: Position, node: Node | string ): Element | null {\n\t\tlet parent = position.parent as ( Element | null );\n\n\t\twhile ( parent ) {\n\t\t\tif ( this.checkChild( parent, node ) ) {\n\t\t\t\treturn parent;\n\t\t\t}\n\n\t\t\t// Do not split limit elements.\n\t\t\tif ( this.isLimit( parent ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tparent = parent.parent as ( Element | null );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Sets attributes allowed by the schema on a given node.\n\t *\n\t * @param node A node to set attributes on.\n\t * @param attributes Attributes keys and values.\n\t * @param writer An instance of the model writer.\n\t */\n\tpublic setAllowedAttributes(\n\t\tnode: Node,\n\t\tattributes: Record<string, unknown>,\n\t\twriter: Writer\n\t): void {\n\t\tconst model = writer.model;\n\n\t\tfor ( const [ attributeName, attributeValue ] of Object.entries( attributes ) ) {\n\t\t\tif ( model.schema.checkAttribute( node, attributeName ) ) {\n\t\t\t\twriter.setAttribute( attributeName, attributeValue, node );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes attributes disallowed by the schema.\n\t *\n\t * @param nodes Nodes that will be filtered.\n\t */\n\tpublic removeDisallowedAttributes( nodes: Iterable<Node>, writer: Writer ): void {\n\t\tfor ( const node of nodes ) {\n\t\t\t// When node is a `Text` it has no children, so just filter it out.\n\t\t\tif ( node.is( '$text' ) ) {\n\t\t\t\tremoveDisallowedAttributeFromNode( this, node, writer );\n\t\t\t}\n\t\t\t// In a case of `Element` iterates through positions between nodes inside this element\n\t\t\t// and filter out node before the current position, or position parent when position\n\t\t\t// is at start of an element. Using positions prevent from omitting merged nodes\n\t\t\t// see https://github.com/ckeditor/ckeditor5-engine/issues/1789.\n\t\t\telse {\n\t\t\t\tconst rangeInNode = Range._createIn( node as Element );\n\t\t\t\tconst positionsInRange = rangeInNode.getPositions();\n\n\t\t\t\tfor ( const position of positionsInRange ) {\n\t\t\t\t\tconst item = position.nodeBefore || position.parent;\n\n\t\t\t\t\tremoveDisallowedAttributeFromNode( this, item as any, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets attributes of a node that have a given property.\n\t *\n\t * @param node Node to get attributes from.\n\t * @param propertyName Name of the property that attribute must have to return it.\n\t * @param propertyValue Desired value of the property that we want to check.\n\t * When `undefined` attributes will be returned if they have set a given property no matter what the value is. If specified it will\n\t * return attributes which given property's value is equal to this parameter.\n\t * @returns Object with attributes' names as key and attributes' values as value.\n\t */\n\tpublic getAttributesWithProperty( node: Node, propertyName: string, propertyValue: unknown ): Record<string, unknown> {\n\t\tconst attributes: Record<string, unknown> = {};\n\n\t\tfor ( const [ attributeName, attributeValue ] of node.getAttributes() ) {\n\t\t\tconst attributeProperties = this.getAttributeProperties( attributeName );\n\n\t\t\tif ( attributeProperties[ propertyName ] === undefined ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( propertyValue === undefined || propertyValue === attributeProperties[ propertyName ] ) {\n\t\t\t\tattributes[ attributeName ] = attributeValue;\n\t\t\t}\n\t\t}\n\n\t\treturn attributes;\n\t}\n\n\t/**\n\t * Creates an instance of the schema context.\n\t */\n\tpublic createContext( context: SchemaContextDefinition ): SchemaContext {\n\t\treturn new SchemaContext( context );\n\t}\n\n\tprivate _clearCache(): void {\n\t\tthis._compiledDefinitions = null;\n\t}\n\n\tprivate _compile(): void {\n\t\tconst definitions: Record<string, SchemaCompiledItemDefinitionInternal> = {};\n\t\tconst sourceRules = this._sourceDefinitions;\n\t\tconst itemNames = Object.keys( sourceRules );\n\n\t\tfor ( const itemName of itemNames ) {\n\t\t\tdefinitions[ itemName ] = compileBaseItemRule( sourceRules[ itemName ], itemName );\n\t\t}\n\n\t\tconst items = Object.values( definitions );\n\n\t\t// Sometimes features add rules (allows, disallows) for items that has not been registered yet. We allow that, to make it easier\n\t\t// to put the schema together. However, sometimes these items are never registered. To prevent operating\n\t\t// removeUnregisteredEntries( definitions, items );\n\n\t\t// 1. Propagate `childItem.allowIn` to `parentItem.allowChildren` and vice versa, so that these properties are completely mirrored\n\t\t// for all children and parents. Do the same for `disallowIn` and `disallowChildren`.\n\t\tfor ( const item of items ) {\n\t\t\tpropagateAllowIn( definitions, item );\n\t\t\tpropagateAllowChildren( definitions, item );\n\t\t\tpropagateDisallowIn( definitions, item );\n\t\t\tpropagateDisallowChildren( definitions, item );\n\t\t}\n\n\t\t// 2. Remove from `allowIn` and `allowChildren` these items which where disallowed by `disallowIn` and `disallowChildren`.\n\t\t// Do the same for attributes. Now we have a clear situation where which item/attribute is allowed. Inheritance is in next steps.\n\t\tfor ( const item of items ) {\n\t\t\tresolveDisallows( definitions, item );\n\t\t}\n\n\t\t// 3. Compile `item.allowContentOf` property. For each entry in `allowContentOf`, we want to take `allowChildren` and rewrite\n\t\t// them into `item.allowChildren`. `item.disallowChildren` is used to filter out some entries. This way \"own rules\" have higher\n\t\t// priority than \"inherited rules\". Mirroring from step 1. is maintained.\n\t\tfor ( const item of items ) {\n\t\t\tcompileAllowContentOf( definitions, item );\n\t\t}\n\n\t\t// 4. Compile `item.allowWhere` property. For each entry in `allowWhere`, we want to take `allowIn` and rewrite them into\n\t\t// `item.allowIn`. `item.disallowIn` is used to filter out some entries. This way \"own rules\" have higher priority than\n\t\t// \"inherited rules\". Mirroring from step 1. is maintained.\n\t\tfor ( const item of items ) {\n\t\t\tcompileAllowWhere( definitions, item );\n\t\t}\n\n\t\t// 5. Compile `item.allowAttributesOf`. For each entry in `allowAttributesOf`, we want to take `allowAttributes` and rewrite them\n\t\t// into `item.allowAttributes`. `item.disallowAttributes` is used to filter out some entries. This way \"own rules\" have higher\n\t\t// priority than \"inherited rules\".\n\t\tfor ( const item of items ) {\n\t\t\tcompileAllowAttributesOf( definitions, item );\n\t\t}\n\n\t\t// 6. Compile `item.inheritTypesFrom` property. For each entry in `inheritTypesFrom`, we want to take `is*` properties and\n\t\t// set them on `item` (if they are not set yet).\n\t\tfor ( const item of items ) {\n\t\t\tcompileInheritPropertiesFrom( definitions, item );\n\t\t}\n\n\t\t// Compile final definitions. Unnecessary properties are removed and some additional cleaning is applied.\n\t\tthis._compiledDefinitions = compileDefinitions( definitions );\n\t}\n\n\tprivate _checkContextMatch( context: SchemaContext, def: SchemaCompiledItemDefinition ): boolean {\n\t\tconst parentItem = context.last;\n\n\t\t// First, check all child checks declared as callbacks.\n\t\t// Note that `_evaluateChildChecks()` will return `undefined` if neither child check was applicable (no decision was made).\n\t\tlet isAllowed = this._evaluateChildChecks( context, def );\n\n\t\t// If the decision was not made inside child check callbacks, then use declarative rules.\n\t\tisAllowed = isAllowed !== undefined ? isAllowed : def.allowIn.includes( parentItem.name );\n\n\t\t// If the item is not allowed in the `context`, return `false`.\n\t\tif ( !isAllowed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If the item is allowed, recursively verify the rest of the `context`.\n\t\tconst parentItemDefinition = this.getDefinition( parentItem );\n\t\tconst parentContext = context.trimLast();\n\n\t\t// One of the items in the original `context` did not have a definition specified. In this case, the whole context is disallowed.\n\t\tif ( !parentItemDefinition ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Whole `context` was verified and passed checks.\n\t\tif ( parentContext.length == 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Verify \"truncated\" parent context. The last item of the original context is now the definition to check.\n\t\treturn this._checkContextMatch( parentContext, parentItemDefinition );\n\t}\n\n\t/**\n\t * Calls child check callbacks to decide whether `def` is allowed in `context`. It uses both generic and specific (defined for `def`\n\t * item) callbacks. If neither callback makes a decision, `undefined` is returned.\n\t *\n\t * Note that the first callback that makes a decision \"wins\", i.e., if any callback returns `true` or `false`, then the processing\n\t * is over and that result is returned.\n\t */\n\tprivate _evaluateChildChecks( context: SchemaContext, def: SchemaCompiledItemDefinition ): boolean | undefined {\n\t\tconst genericChecks = this._customChildChecks.get( this._genericCheckSymbol ) || [];\n\t\tconst childChecks = this._customChildChecks.get( def.name ) || [];\n\n\t\tfor ( const check of [ ...genericChecks, ...childChecks ] ) {\n\t\t\tconst result = check( context, def );\n\n\t\t\tif ( result !== undefined ) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Calls attribute check callbacks to decide whether `attributeName` can be set on the last element of `context`. It uses both\n\t * generic and specific (defined for `attributeName`) callbacks. If neither callback makes a decision, `undefined` is returned.\n\t *\n\t * Note that the first callback that makes a decision \"wins\", i.e., if any callback returns `true` or `false`, then the processing\n\t * is over and that result is returned.\n\t */\n\tprivate _evaluateAttributeChecks( context: SchemaContext, attributeName: string ): boolean | undefined {\n\t\tconst genericChecks = this._customAttributeChecks.get( this._genericCheckSymbol ) || [];\n\t\tconst childChecks = this._customAttributeChecks.get( attributeName ) || [];\n\n\t\tfor ( const check of [ ...genericChecks, ...childChecks ] ) {\n\t\t\tconst result = check( context, attributeName );\n\n\t\t\tif ( result !== undefined ) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Takes a flat range and an attribute name. Traverses the range recursively and deeply to find and return all ranges\n\t * inside the given range on which the attribute can be applied.\n\t *\n\t * This is a helper function for {@link ~Schema#getValidRanges}.\n\t *\n\t * @param range The range to process.\n\t * @param attribute The name of the attribute to check.\n\t * @returns Ranges in which the attribute is allowed.\n\t */\n\tprivate* _getValidRangesForRange( range: Range, attribute: string ): Iterable<Range> {\n\t\tlet start = range.start;\n\t\tlet end = range.start;\n\n\t\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t\tif ( item.is( 'element' ) ) {\n\t\t\t\tyield* this._getValidRangesForRange( Range._createIn( item ), attribute );\n\t\t\t}\n\n\t\t\tif ( !this.checkAttribute( item, attribute ) ) {\n\t\t\t\tif ( !start.isEqual( end ) ) {\n\t\t\t\t\tyield new Range( start, end );\n\t\t\t\t}\n\n\t\t\t\tstart = Position._createAfter( item );\n\t\t\t}\n\n\t\t\tend = Position._createAfter( item );\n\t\t}\n\n\t\tif ( !start.isEqual( end ) ) {\n\t\t\tyield new Range( start, end );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a model range which is optimal (in terms of UX) for inserting a widget block.\n\t *\n\t * For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph\n\t * will be returned so that it is not split. If the selection is at the end of a paragraph,\n\t * the collapsed range after this paragraph will be returned.\n\t *\n\t * Note: If the selection is placed in an empty block, the range in that block will be returned. If that range\n\t * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced\n\t * by the inserted widget block.\n\t *\n\t * @internal\n\t * @param selection The selection based on which the insertion position should be calculated.\n\t * @param place The place where to look for optimal insertion range.\n\t * The `auto` value will determine itself the best position for insertion.\n\t * The `before` value will try to find a position before selection.\n\t * The `after` value will try to find a position after selection.\n\t * @returns The optimal range.\n\t */\n\tpublic findOptimalInsertionRange(\n\t\tselection: Selection | DocumentSelection,\n\t\tplace?: 'auto' | 'before' | 'after'\n\t): Range {\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\tif ( selectedElement && this.isObject( selectedElement ) && !this.isInline( selectedElement ) ) {\n\t\t\tif ( place == 'before' || place == 'after' ) {\n\t\t\t\treturn new Range( Position._createAt( selectedElement, place ) );\n\t\t\t}\n\n\t\t\treturn Range._createOn( selectedElement );\n\t\t}\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\t// There are no block elements within ancestors (in the current limit element).\n\t\tif ( !firstBlock ) {\n\t\t\treturn new Range( selection.focus! );\n\t\t}\n\n\t\t// If inserting into an empty block – return position in that block. It will get\n\t\t// replaced with the image by insertContent(). #42.\n\t\tif ( firstBlock.isEmpty ) {\n\t\t\treturn new Range( Position._createAt( firstBlock, 0 ) );\n\t\t}\n\n\t\tconst positionAfter = Position._createAfter( firstBlock );\n\n\t\t// If selection is at the end of the block - return position after the block.\n\t\tif ( selection.focus!.isTouching( positionAfter ) ) {\n\t\t\treturn new Range( positionAfter );\n\t\t}\n\n\t\t// Otherwise, return position before the block.\n\t\treturn new Range( Position._createBefore( firstBlock ) );\n\t}\n}\n\n/**\n * Event fired when the {@link ~Schema#checkChild} method is called. It allows plugging in\n * additional behavior, for example implementing rules which cannot be defined using the declarative\n * {@link module:engine/model/schema~SchemaItemDefinition} interface.\n *\n * **Note:** The {@link ~Schema#addChildCheck} method is a more handy way to register callbacks. Internally,\n * it registers a listener to this event but comes with a simpler API and it is the recommended choice\n * in most of the cases.\n *\n * The {@link ~Schema#checkChild} method fires an event because it is\n * {@link module:utils/observablemixin~Observable#decorate decorated} with it. Thanks to that you can\n * use this event in various ways, but the most important use case is overriding standard behavior of the\n * `checkChild()` method. Let's see a typical listener template:\n *\n * ```ts\n * schema.on( 'checkChild', ( evt, args ) => {\n * \tconst context = args[ 0 ];\n * \tconst childDefinition = args[ 1 ];\n * }, { priority: 'high' } );\n * ```\n *\n * The listener is added with a `high` priority to be executed before the default method is really called. The `args` callback\n * parameter contains arguments passed to `checkChild( context, child )`. However, the `context` parameter is already\n * normalized to a {@link module:engine/model/schema~SchemaContext} instance and `child` to a\n * {@link module:engine/model/schema~SchemaCompiledItemDefinition} instance, so you do not have to worry about\n * the various ways how `context` and `child` may be passed to `checkChild()`.\n *\n * **Note:** `childDefinition` may be `undefined` if `checkChild()` was called with a non-registered element.\n *\n * So, in order to implement a rule \"disallow `heading1` in `blockQuote`\", you can add such a listener:\n *\n * ```ts\n * schema.on( 'checkChild', ( evt, args ) => {\n * \tconst context = args[ 0 ];\n * \tconst childDefinition = args[ 1 ];\n *\n * \tif ( context.endsWith( 'blockQuote' ) && childDefinition && childDefinition.name == 'heading1' ) {\n * \t\t// Prevent next listeners from being called.\n * \t\tevt.stop();\n * \t\t// Set the checkChild()'s return value.\n * \t\tevt.return = false;\n * \t}\n * }, { priority: 'high' } );\n * ```\n *\n * Allowing elements in specific contexts will be a far less common use case, because it is normally handled by the\n * `allowIn` rule from {@link module:engine/model/schema~SchemaItemDefinition}. But if you have a complex scenario\n * where `listItem` should be allowed only in element `foo` which must be in element `bar`, then this would be the way:\n *\n * ```ts\n * schema.on( 'checkChild', ( evt, args ) => {\n * \tconst context = args[ 0 ];\n * \tconst childDefinition = args[ 1 ];\n *\n * \tif ( context.endsWith( 'bar foo' ) && childDefinition.name == 'listItem' ) {\n * \t\t// Prevent next listeners from being called.\n * \t\tevt.stop();\n * \t\t// Set the checkChild()'s return value.\n * \t\tevt.return = true;\n * \t}\n * }, { priority: 'high' } );\n * ```\n *\n * @eventName ~Schema#checkChild\n * @param args The `checkChild()`'s arguments.\n */\nexport type SchemaCheckChildEvent = {\n\tname: 'checkChild';\n\targs: [ [ context: SchemaContext, def: SchemaCompiledItemDefinition ] ];\n};\n\n/**\n * Event fired when the {@link ~Schema#checkAttribute} method is called. It allows plugging in\n * additional behavior, for example implementing rules which cannot be defined using the declarative\n * {@link module:engine/model/schema~SchemaItemDefinition} interface.\n *\n * **Note:** The {@link ~Schema#addAttributeCheck} method is a more handy way to register callbacks. Internally,\n * it registers a listener to this event but comes with a simpler API and it is the recommended choice\n * in most of the cases.\n *\n * The {@link ~Schema#checkAttribute} method fires an event because it is\n * {@link module:utils/observablemixin~Observable#decorate decorated} with it. Thanks to that you can\n * use this event in various ways, but the most important use case is overriding the standard behavior of the\n * `checkAttribute()` method. Let's see a typical listener template:\n *\n * ```ts\n * schema.on( 'checkAttribute', ( evt, args ) => {\n * \tconst context = args[ 0 ];\n * \tconst attributeName = args[ 1 ];\n * }, { priority: 'high' } );\n * ```\n *\n * The listener is added with a `high` priority to be executed before the default method is really called. The `args` callback\n * parameter contains arguments passed to `checkAttribute( context, attributeName )`. However, the `context` parameter is already\n * normalized to a {@link module:engine/model/schema~SchemaContext} instance, so you do not have to worry about\n * the various ways how `context` may be passed to `checkAttribute()`.\n *\n * So, in order to implement a rule \"disallow `bold` in a text which is in a `heading1`, you can add such a listener:\n *\n * ```ts\n * schema.on( 'checkAttribute', ( evt, args ) => {\n * \tconst context = args[ 0 ];\n * \tconst attributeName = args[ 1 ];\n *\n * \tif ( context.endsWith( 'heading1 $text' ) && attributeName == 'bold' ) {\n * \t\t// Prevent next listeners from being called.\n * \t\tevt.stop();\n * \t\t// Set the checkAttribute()'s return value.\n * \t\tevt.return = false;\n * \t}\n * }, { priority: 'high' } );\n * ```\n *\n * Allowing attributes in specific contexts will be a far less common use case, because it is normally handled by the\n * `allowAttributes` rule from {@link module:engine/model/schema~SchemaItemDefinition}. But if you have a complex scenario\n * where `bold` should be allowed only in element `foo` which must be in element `bar`, then this would be the way:\n *\n * ```ts\n * schema.on( 'checkAttribute', ( evt, args ) => {\n * \tconst context = args[ 0 ];\n * \tconst attributeName = args[ 1 ];\n *\n * \tif ( context.endsWith( 'bar foo $text' ) && attributeName == 'bold' ) {\n * \t\t// Prevent next listeners from being called.\n * \t\tevt.stop();\n * \t\t// Set the checkAttribute()'s return value.\n * \t\tevt.return = true;\n * \t}\n * }, { priority: 'high' } );\n * ```\n *\n * @eventName ~Schema#checkAttribute\n * @param args The `checkAttribute()`'s arguments.\n */\nexport type SchemaCheckAttributeEvent = {\n\tname: 'checkAttribute';\n\targs: [ [ context: SchemaContext, attributeName: string ] ];\n};\n\n/**\n * A definition of a {@link module:engine/model/schema~Schema schema} item.\n *\n * You can define the following rules:\n *\n * * {@link ~SchemaItemDefinition#allowIn `allowIn`} &ndash; Defines in which other items this item will be allowed.\n * * {@link ~SchemaItemDefinition#allowChildren `allowChildren`} &ndash; Defines which other items are allowed inside this item.\n * * {@link ~SchemaItemDefinition#allowAttributes `allowAttributes`} &ndash; Defines allowed attributes of the given item.\n * * {@link ~SchemaItemDefinition#disallowIn `disallowIn`} &ndash; Defines in which other items this item will be disallowed.\n * * {@link ~SchemaItemDefinition#disallowChildren `disallowChildren`} &ndash; Defines which other items are disallowed inside this item.\n * * {@link ~SchemaItemDefinition#disallowAttributes `disallowAttributes`} &ndash; Defines disallowed attributes of the given item.\n * * {@link ~SchemaItemDefinition#allowContentOf `allowContentOf`} &ndash; Makes this item allow children that are also allowed in the\n * specified items. This acknowledges disallow rules.\n * * {@link ~SchemaItemDefinition#allowWhere `allowWhere`} &ndash; Makes this item allowed where the specified items are allowed. This\n * acknowledges disallow rules.\n * * {@link ~SchemaItemDefinition#allowAttributesOf `allowAttributesOf`} &ndash; Inherits attributes from other items. This acknowledges\n * disallow rules.\n * * {@link ~SchemaItemDefinition#inheritTypesFrom `inheritTypesFrom`} &ndash; Inherits `is*` properties of other items.\n * * {@link ~SchemaItemDefinition#inheritAllFrom `inheritAllFrom`} &ndash;\n * A shorthand for `allowContentOf`, `allowWhere`, `allowAttributesOf`, `inheritTypesFrom`.\n *\n * # The `is*` properties\n *\n * There are a couple commonly used `is*` properties. Their role is to assign additional semantics to schema items.\n *\n * * {@link ~SchemaItemDefinition#isBlock `isBlock`} &ndash; Whether this item is paragraph-like.\n * Generally speaking, content is usually made out of blocks like paragraphs, list items, images, headings, etc.\n * * {@link ~SchemaItemDefinition#isInline `isInline`} &ndash; Whether an item is \"text-like\" and should be treated as an inline node.\n * Examples of inline elements: `$text`, `softBreak` (`<br>`), etc.\n * * {@link ~SchemaItemDefinition#isLimit `isLimit`} &ndash; It can be understood as whether this element\n * should not be split by <kbd>Enter</kbd>. Examples of limit elements: `$root`, table cell, image caption, etc.\n * In other words, all actions that happen inside a limit element are limited to its content.\n * All objects are treated as limit elements, too.\n * * {@link ~SchemaItemDefinition#isObject `isObject`} &ndash; Whether an item is \"self-contained\" and should be treated as a whole.\n * Examples of object elements: `imageBlock`, `table`, `video`, etc. An object is also a limit, so\n * {@link module:engine/model/schema~Schema#isLimit `isLimit()`} returns `true` for object elements automatically.\n *\n * Read more about the meaning of these types in the\n * {@glink framework/deep-dive/schema#defining-additional-semantics dedicated section of the Schema deep-dive} guide.\n *\n * # Generic items\n *\n * There are several generic items (classes of elements) available: `$root`, `$container`, `$block`, `$blockObject`,\n * `$inlineObject`, and `$text`. They are defined as follows:\n *\n * ```ts\n * schema.register( '$root', {\n * \tisLimit: true\n * } );\n *\n * schema.register( '$container', {\n * \tallowIn: [ '$root', '$container' ]\n * } );\n *\n * schema.register( '$block', {\n * \tallowIn: [ '$root', '$container' ],\n * \tisBlock: true\n * } );\n *\n * schema.register( '$blockObject', {\n * \tallowWhere: '$block',\n * \tisBlock: true,\n * \tisObject: true\n * } );\n *\n * schema.register( '$inlineObject', {\n * \tallowWhere: '$text',\n * \tallowAttributesOf: '$text',\n * \tisInline: true,\n * \tisObject: true\n * } );\n *\n * schema.register( '$text', {\n * \tallowIn: '$block',\n * \tisInline: true,\n * \tisContent: true\n * } );\n * ```\n *\n * They reflect typical editor content that is contained within one root, consists of several blocks\n * (paragraphs, lists items, headings, images) which, in turn, may contain text inside.\n *\n * By inheriting from the generic items you can define new items which will get extended by other editor features.\n * Read more about generic types in the {@glink framework/deep-dive/schema Schema deep-dive} guide.\n *\n * # Example definitions\n *\n * Allow `paragraph` in roots and block quotes:\n *\n * ```ts\n * schema.register( 'paragraph', {\n * \tallowIn: [ '$root', 'blockQuote' ],\n * \tisBlock: true\n * } );\n * ```\n *\n * Allow `paragraph` everywhere where `$block` is allowed (i.e. in `$root`):\n *\n * ```ts\n * schema.register( 'paragraph', {\n * \tallowWhere: '$block',\n * \tisBlock: true\n * } );\n * ```\n *\n * Allow `paragraph` inside a `$root` and allow `$text` as a `paragraph` child:\n *\n * ```ts\n * schema.register( 'paragraph', {\n * \tallowIn: '$root',\n * \tallowChildren: '$text',\n * \tisBlock: true\n * } );\n * ```\n *\n * The previous rule can be written in a shorter form using inheritance:\n *\n * ```ts\n * schema.register( 'paragraph', {\n * \tinheritAllFrom: '$block'\n * } );\n * ```\n *\n * Make `imageBlock` a block object, which is allowed everywhere where `$block` is.\n * Also, allow `src` and `alt` attributes in it:\n *\n * ```ts\n * schema.register( 'imageBlock', {\n * \tinheritAllFrom: '$blockObject',\n * \tallowAttributes: [ 'src', 'alt' ],\n * } );\n * ```\n *\n * Make `caption` allowed in `imageBlock` and make it allow all the content of `$block`s (usually, `$text`).\n * Also, mark it as a limit element so it cannot be split:\n *\n * ```ts\n * schema.register( 'caption', {\n * \tallowIn: 'imageBlock',\n * \tallowContentOf: '$block',\n * \tisLimit: true\n * } );\n * ```\n *\n * Register `inlineImage` as a kind of an inline object but disallow it inside captions:\n *\n * ```ts\n * schema.register( 'imageInline', {\n * \tinheritAllFrom: '$inlineObject',\n * \tdisallowIn: [ 'caption' ]\n * } );\n * ```\n *\n * Make `listItem` inherit all from `$block` but also allow additional attributes:\n *\n * ```ts\n * schema.register( 'listItem', {\n * \tinheritAllFrom: '$block',\n * \tallowAttributes: [ 'listType', 'listIndent' ]\n * } );\n * ```\n *\n * Which translates to:\n *\n * ```ts\n * schema.register( 'listItem', {\n * \tallowWhere: '$block',\n * \tallowContentOf: '$block',\n * \tallowAttributesOf: '$block',\n * \tinheritTypesFrom: '$block',\n * \tallowAttributes: [ 'listType', 'listIndent' ]\n * } );\n * ```\n *\n * # Tips\n *\n * * Check schema definitions of existing features to see how they are defined.\n * * If you want to publish your feature so other developers can use it, try to use\n * generic items as much as possible.\n * * Keep your model clean. Limit it to the actual data and store information in a normalized way.\n * * Remember about defining the `is*` properties. They do not affect the allowed structures, but they can\n * affect how the editor features treat your elements.\n */\nexport interface SchemaItemDefinition {\n\n\t/**\n\t * Defines in which other items this item will be allowed.\n\t */\n\tallowIn?: string | Array<string>;\n\n\t/**\n\t * Defines which other items are allowed inside this item.\n\t */\n\tallowChildren?: string | Array<string>;\n\n\t/**\n\t * Defines allowed attributes of the given item.\n\t */\n\tallowAttributes?: string | Array<string>;\n\n\t/**\n\t * Defines in which other items this item will be disallowed. Takes precedence over allow rules.\n\t */\n\tdisallowIn?: string | Array<string>;\n\n\t/**\n\t * Defines which other items are disallowed inside this item. Takes precedence over allow rules.\n\t */\n\tdisallowChildren?: string | Array<string>;\n\n\t/**\n\t * Defines disallowed attributes for this item. Takes precedence over allow rules.\n\t */\n\tdisallowAttributes?: string | Array<string>;\n\n\t/**\n\t * Inherits \"allowed children\" from other items.\n\t *\n\t * Note that the item's \"own\" rules take precedence over \"inherited\" rules and can overwrite them.\n\t */\n\tallowContentOf?: string | Array<string>;\n\n\t/**\n\t * Inherits \"allowed in\" from other items.\n\t *\n\t * Note that the item's \"own\" rules take precedence over \"inherited\" rules and can overwrite them.\n\t */\n\tallowWhere?: string | Array<string>;\n\n\t/**\n\t * Inherits \"allowed attributes\" from other items.\n\t *\n\t * Note that the item's \"own\" rules take precedence over \"inherited\" rules and can overwrite them.\n\t */\n\tallowAttributesOf?: string | Array<string>;\n\n\t/**\n\t * Inherits `is*` properties of other items.\n\t *\n\t * Note that the item's \"own\" rules take precedence over \"inherited\" rules and can overwrite them.\n\t */\n\tinheritTypesFrom?: string | Array<string>;\n\n\t/**\n\t * A shorthand for `allowContentOf`, `allowWhere`, `allowAttributesOf`, `inheritTypesFrom`.\n\t *\n\t * Note that the item's \"own\" rules take precedence over \"inherited\" rules and can overwrite them.\n\t */\n\tinheritAllFrom?: string;\n\n\t/**\n\t * Whether this item is paragraph-like. Generally speaking, content is usually made out of blocks\n\t * like paragraphs, list items, images, headings, etc. All these elements are marked as blocks. A block\n\t * should not allow another block inside. Note: There is also the `$block` generic item which has `isBlock` set to `true`.\n\t * Most block type items will inherit from `$block` (through `inheritAllFrom`).\n\t *\n\t * Read more about the block elements in the\n\t * {@glink framework/deep-dive/schema#block-elements Block elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide.\n\t */\n\tisBlock?: boolean;\n\n\t/**\n\t * Whether an item is \"text-like\" and should be treated as an inline node. Examples of inline elements:\n\t * `$text`, `softBreak` (`<br>`), etc.\n\t *\n\t * Read more about the inline elements in the\n\t * {@glink framework/deep-dive/schema#inline-elements Inline elements section} of the Schema deep-dive guide.\n\t */\n\tisInline?: boolean;\n\n\t/**\n\t * It can be understood as whether this element should not be split by <kbd>Enter</kbd>.\n\t * Examples of limit elements: `$root`, table cell, image caption, etc. In other words, all actions that happen inside\n\t * a limit element are limited to its content.\n\t *\n\t * Read more about the limit elements in the\n\t * {@glink framework/deep-dive/schema#limit-elements Limit elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide.\n\t */\n\tisLimit?: boolean;\n\n\t/**\n\t * Whether an item is \"self-contained\" and should be treated as a whole. Examples of object elements:\n\t * `imageBlock`, `table`, `video`, etc.\n\t *\n\t * **Note:** An object is also a limit, so\n\t * {@link module:engine/model/schema~Schema#isLimit `isLimit()`} returns `true` for object elements automatically.\n\t *\n\t * Read more about the object elements in the\n\t * {@glink framework/deep-dive/schema#object-elements Object elements section} of the Schema deep-dive guide.\n\t */\n\tisObject?: boolean;\n\n\t/**\n\t * `true` when an element should be selectable as a whole by the user.\n\t * Examples of selectable elements: `imageBlock`, `table`, `tableCell`, etc.\n\t *\n\t * **Note:** An object is also a selectable element, so\n\t * {@link module:engine/model/schema~Schema#isSelectable `isSelectable()`} returns `true` for object elements automatically.\n\t *\n\t * Read more about selectable elements in the\n\t * {@glink framework/deep-dive/schema#selectable-elements Selectable elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide.\n\t */\n\tisSelectable?: boolean;\n\n\t/**\n\t * An item is a content when it always finds its way to the editor data output regardless of the number and type of its descendants.\n\t * Examples of content elements: `$text`, `imageBlock`, `table`, etc. (but not `paragraph`, `heading1` or `tableCell`).\n\t *\n\t * **Note:** An object is also a content element, so\n\t * {@link module:engine/model/schema~Schema#isContent `isContent()`} returns `true` for object elements automatically.\n\t *\n\t * Read more about content elements in the\n\t * {@glink framework/deep-dive/schema#content-elements Content elements section} of\n\t * the {@glink framework/deep-dive/schema Schema deep-dive} guide.\n\t */\n\tisContent?: boolean;\n}\n\n/**\n * A simplified version of {@link module:engine/model/schema~SchemaItemDefinition} after\n * compilation by the {@link module:engine/model/schema~Schema schema}.\n * Rules fed to the schema by {@link module:engine/model/schema~Schema#register}\n * and {@link module:engine/model/schema~Schema#extend} methods are defined in the\n * {@link module:engine/model/schema~SchemaItemDefinition} format.\n * Later on, they are compiled to `SchemaCompiledItemDefinition` so when you use e.g.\n * the {@link module:engine/model/schema~Schema#getDefinition} method you get the compiled version.\n *\n * The compiled version contains only the following properties:\n *\n * * The `name` property,\n * * The `is*` properties,\n * * The `allowIn` array,\n * * The `allowChildren` array,\n * * The `allowAttributes` array.\n */\nexport interface SchemaCompiledItemDefinition {\n\tname: string;\n\n\tisBlock: boolean;\n\tisContent: boolean;\n\tisInline: boolean;\n\tisLimit: boolean;\n\tisObject: boolean;\n\tisSelectable: boolean;\n\n\tallowIn: Array<string>;\n\tallowChildren: Array<string>;\n\tallowAttributes: Array<string>;\n}\n\ninterface SchemaCompiledItemDefinitionInternal {\n\tname: string;\n\n\t// We need to distinguish `false` from `undefined` to allow inheritance.\n\tisBlock?: boolean;\n\tisContent?: boolean;\n\tisInline?: boolean;\n\tisLimit?: boolean;\n\tisObject?: boolean;\n\tisSelectable?: boolean;\n\n\tallowIn: Set<string>;\n\tallowChildren: Set<string>;\n\tallowAttributes: Set<string>;\n\n\tdisallowIn: Set<string>;\n\tdisallowChildren: Set<string>;\n\tdisallowAttributes: Set<string>;\n\n\tallowAttributesOf: Set<string>;\n\tallowContentOf: Set<string>;\n\tallowWhere: Set<string>;\n\n\tinheritTypesFrom: Set<string>;\n}\n\ntype TypeNames = Array<'isBlock' | 'isContent' | 'isInline' | 'isLimit' | 'isObject' | 'isSelectable'>;\n\n/**\n * A schema context &ndash; a list of ancestors of a given position in the document.\n *\n * Considering such position:\n *\n * ```xml\n * <$root>\n * \t<blockQuote>\n * \t\t<paragraph>\n * \t\t\t^\n * \t\t</paragraph>\n * \t</blockQuote>\n * </$root>\n * ```\n *\n * The context of this position is its {@link module:engine/model/position~Position#getAncestors lists of ancestors}:\n *\n *\t\t[ rootElement, blockQuoteElement, paragraphElement ]\n *\n * Contexts are used in the {@link module:engine/model/schema~Schema#event:checkChild `Schema#checkChild`} and\n * {@link module:engine/model/schema~Schema#event:checkAttribute `Schema#checkAttribute`} events as a definition\n * of a place in the document where the check occurs. The context instances are created based on the first arguments\n * of the {@link module:engine/model/schema~Schema#checkChild `Schema#checkChild()`} and\n * {@link module:engine/model/schema~Schema#checkAttribute `Schema#checkAttribute()`} methods so when\n * using these methods you need to use {@link module:engine/model/schema~SchemaContextDefinition}s.\n */\nexport class SchemaContext implements Iterable<SchemaContextItem> {\n\tprivate _items!: Array<SchemaContextItem>;\n\n\t/**\n\t * Creates an instance of the context.\n\t */\n\tconstructor( context: SchemaContextDefinition ) {\n\t\tif ( context instanceof SchemaContext ) {\n\t\t\treturn context;\n\t\t}\n\n\t\tlet items: Array<string | Item | DocumentFragment>;\n\n\t\tif ( typeof context == 'string' ) {\n\t\t\titems = [ context ];\n\t\t} else if ( !Array.isArray( context ) ) {\n\t\t\t// `context` is item or position.\n\t\t\t// Position#getAncestors() doesn't accept any parameters but it works just fine here.\n\t\t\titems = context.getAncestors( { includeSelf: true } );\n\t\t} else {\n\t\t\titems = context;\n\t\t}\n\n\t\tthis._items = items.map( mapContextItem );\n\t}\n\n\t/**\n\t * The number of items.\n\t */\n\tpublic get length(): number {\n\t\treturn this._items.length;\n\t}\n\n\t/**\n\t * The last item (the lowest node).\n\t */\n\tpublic get last(): SchemaContextItem {\n\t\treturn this._items[ this._items.length - 1 ]!;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all context items.\n\t */\n\tpublic [ Symbol.iterator ](): IterableIterator<SchemaContextItem> {\n\t\treturn this._items[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns a new schema context instance with an additional item.\n\t *\n\t * Item can be added as:\n\t *\n\t * ```ts\n\t * const context = new SchemaContext( [ '$root' ] );\n\t *\n\t * // An element.\n\t * const fooElement = writer.createElement( 'fooElement' );\n\t * const newContext = context.push( fooElement ); // [ '$root', 'fooElement' ]\n\t *\n\t * // A text node.\n\t * const text = writer.createText( 'foobar' );\n\t * const newContext = context.push( text ); // [ '$root', '$text' ]\n\t *\n\t * // A string (element name).\n\t * const newContext = context.push( 'barElement' ); // [ '$root', 'barElement' ]\n\t * ```\n\t *\n\t * **Note** {@link module:engine/model/node~Node} that is already in the model tree will be added as the only item\n\t * (without ancestors).\n\t *\n\t * @param item An item that will be added to the current context.\n\t * @returns A new schema context instance with an additional item.\n\t */\n\tpublic push( item: string | Node ): SchemaContext {\n\t\tconst ctx = new SchemaContext( [ item ] );\n\n\t\tctx._items = [ ...this._items, ...ctx._items ];\n\n\t\treturn ctx;\n\t}\n\n\t/**\n\t * Returns a new schema context that is based on this context but has the last item removed.\n\t *\n\t * ```ts\n\t * const ctxParagraph = new SchemaContext( [ '$root', 'blockQuote', 'paragraph' ] );\n\t * const ctxBlockQuote = ctxParagraph.trimLast(); // Items in `ctxBlockQuote` are: `$root` an `blockQuote`.\n\t * const ctxRoot = ctxBlockQuote.trimLast(); // Items in `ctxRoot` are: `$root`.\n\t * ```\n\t *\n\t * @returns A new reduced schema context instance.\n\t */\n\tpublic trimLast(): SchemaContext {\n\t\tconst ctx = new SchemaContext( [] );\n\n\t\tctx._items = this._items.slice( 0, -1 );\n\n\t\treturn ctx;\n\t}\n\n\t/**\n\t * Gets an item on the given index.\n\t */\n\tpublic getItem( index: number ): SchemaContextItem {\n\t\treturn this._items[ index ];\n\t}\n\n\t/**\n\t * Returns the names of items.\n\t */\n\tpublic* getNames(): IterableIterator<string> {\n\t\tyield* this._items.map( item => item.name );\n\t}\n\n\t/**\n\t * Checks whether the context ends with the given nodes.\n\t *\n\t * ```ts\n\t * const ctx = new SchemaContext( [ rootElement, paragraphElement, textNode ] );\n\t *\n\t * ctx.endsWith( '$text' ); // -> true\n\t * ctx.endsWith( 'paragraph $text' ); // -> true\n\t * ctx.endsWith( '$root' ); // -> false\n\t * ctx.endsWith( 'paragraph' ); // -> false\n\t * ```\n\t */\n\tpublic endsWith( query: string ): boolean {\n\t\treturn Array.from( this.getNames() ).join( ' ' ).endsWith( query );\n\t}\n\n\t/**\n\t * Checks whether the context starts with the given nodes.\n\t *\n\t * ```ts\n\t * const ctx = new SchemaContext( [ rootElement, paragraphElement, textNode ] );\n\t *\n\t * ctx.endsWith( '$root' ); // -> true\n\t * ctx.endsWith( '$root paragraph' ); // -> true\n\t * ctx.endsWith( '$text' ); // -> false\n\t * ctx.endsWith( 'paragraph' ); // -> false\n\t * ```\n\t */\n\tpublic startsWith( query: string ): boolean {\n\t\treturn Array.from( this.getNames() ).join( ' ' ).startsWith( query );\n\t}\n}\n\n/**\n * The definition of a {@link module:engine/model/schema~SchemaContext schema context}.\n *\n * Contexts can be created in multiple ways:\n *\n * * By defining a **node** – in this cases this node and all its ancestors will be used.\n * * By defining a **position** in the document – in this case all its ancestors will be used.\n * * By defining an **array of nodes** – in this case this array defines the entire context.\n * * By defining a **name of node** - in this case node will be \"mocked\". It is not recommended because context\n * will be unrealistic (e.g. attributes of these nodes are not specified). However, at times this may be the only\n * way to define the context (e.g. when checking some hypothetical situation).\n * * By defining an **array of node names** (potentially, mixed with real nodes) – The same as **name of node**\n * but it is possible to create a path.\n * * By defining a {@link module:engine/model/schema~SchemaContext} instance - in this case the same instance as provided\n * will be returned.\n *\n * Examples of context definitions passed to the {@link module:engine/model/schema~Schema#checkChild `Schema#checkChild()`}\n * method:\n *\n * ```ts\n * // Assuming that we have a $root > blockQuote > paragraph structure, the following code\n * // will check node 'foo' in the following context:\n * // [ rootElement, blockQuoteElement, paragraphElement ]\n * const contextDefinition = paragraphElement;\n * const childToCheck = 'foo';\n * schema.checkChild( contextDefinition, childToCheck );\n *\n * // Also check in [ rootElement, blockQuoteElement, paragraphElement ].\n * schema.checkChild( model.createPositionAt( paragraphElement, 0 ), 'foo' );\n *\n * // Check in [ rootElement, paragraphElement ].\n * schema.checkChild( [ rootElement, paragraphElement ], 'foo' );\n *\n * // Check only fakeParagraphElement.\n * schema.checkChild( 'paragraph', 'foo' );\n *\n * // Check in [ fakeRootElement, fakeBarElement, paragraphElement ].\n * schema.checkChild( [ '$root', 'bar', paragraphElement ], 'foo' );\n * ```\n *\n * All these `checkChild()` calls will fire {@link module:engine/model/schema~Schema#event:checkChild `Schema#checkChild`}\n * events in which `args[ 0 ]` is an instance of the context. Therefore, you can write a listener like this:\n *\n * ```ts\n * schema.on( 'checkChild', ( evt, args ) => {\n * \tconst ctx = args[ 0 ];\n *\n * \tconsole.log( Array.from( ctx.getNames() ) );\n * } );\n * ```\n *\n * Which will log the following:\n *\n * ```ts\n * [ '$root', 'blockQuote', 'paragraph' ]\n * [ '$root', 'paragraph' ]\n * [ '$root', 'bar', 'paragraph' ]\n * ```\n *\n * Note: When using the {@link module:engine/model/schema~Schema#checkAttribute `Schema#checkAttribute()`} method\n * you may want to check whether a text node may have an attribute. A {@link module:engine/model/text~Text} is a\n * correct way to define a context so you can do this:\n *\n * ```ts\n * schema.checkAttribute( textNode, 'bold' );\n * ```\n *\n * But sometimes you want to check whether a text at a given position might've had some attribute,\n * in which case you can create a context by mixing in an array of elements with a `'$text'` string:\n *\n * ```ts\n * // Check in [ rootElement, paragraphElement, textNode ].\n * schema.checkChild( [ ...positionInParagraph.getAncestors(), '$text' ], 'bold' );\n * ```\n */\nexport type SchemaContextDefinition = Item | Position | SchemaContext | string | Array<string | Item>;\n\n/**\n * An item of the {@link module:engine/model/schema~SchemaContext schema context}.\n *\n * It contains 3 properties:\n *\n * * `name` – the name of this item,\n * * `* getAttributeKeys()` – a generator of keys of item attributes,\n * * `getAttribute( keyName )` – a method to get attribute values.\n *\n * The context item interface is a highly simplified version of {@link module:engine/model/node~Node} and its role\n * is to expose only the information which schema checks are able to provide (which is the name of the node and\n * node's attributes).\n *\n * ```ts\n * schema.on( 'checkChild', ( evt, args ) => {\n * \tconst ctx = args[ 0 ];\n * \tconst firstItem = ctx.getItem( 0 );\n *\n * \tconsole.log( firstItem.name ); // -> '$root'\n * \tconsole.log( firstItem.getAttribute( 'foo' ) ); // -> 'bar'\n * \tconsole.log( Array.from( firstItem.getAttributeKeys() ) ); // -> [ 'foo', 'faa' ]\n * } );\n * ```\n */\nexport interface SchemaContextItem {\n\tname: string;\n\tgetAttributeKeys(): Generator<string>;\n\tgetAttribute( keyName: string ): unknown;\n}\n\n/**\n * A structure containing additional metadata describing the attribute.\n *\n * See {@link module:engine/model/schema~Schema#setAttributeProperties `Schema#setAttributeProperties()`} for usage examples.\n */\nexport interface AttributeProperties {\n\n\t/**\n\t * Indicates that the attribute should be considered as a visual formatting, like `bold`, `italic` or\n\t * `fontSize` rather than semantic attribute (such as `src`, `listType`, etc.). For example, it is used by the \"Remove format\" feature.\n\t */\n\tisFormatting?: boolean;\n\n\t/**\n\t * Indicates that given text attribute should be copied to the next block when enter is pressed.\n\t */\n\tcopyOnEnter?: boolean;\n\n\t/**\n\t * Indicates that given attribute should be preserved while replacing the element.\n\t */\n\tcopyOnReplace?: boolean;\n\n\t/**\n\t * Indicates that given text attribute should be copied from an inline object to the next inserted inline content.\n\t *\n\t * @default true\n\t */\n\tcopyFromObject?: boolean;\n\n\t[ name: string ]: unknown;\n}\n\nexport type SchemaAttributeCheckCallback = ( context: SchemaContext, attributeName: string ) => boolean | undefined;\n\nexport type SchemaChildCheckCallback = ( context: SchemaContext, definition: SchemaCompiledItemDefinition ) => boolean | undefined;\n\nfunction compileBaseItemRule( sourceItemRules: Array<SchemaItemDefinition>, itemName: string ): SchemaCompiledItemDefinitionInternal {\n\tconst itemRule: SchemaCompiledItemDefinitionInternal = {\n\t\tname: itemName,\n\n\t\tallowIn: new Set<string>(),\n\t\tallowChildren: new Set<string>(),\n\t\tdisallowIn: new Set<string>(),\n\t\tdisallowChildren: new Set<string>(),\n\n\t\tallowContentOf: new Set<string>(),\n\t\tallowWhere: new Set<string>(),\n\n\t\tallowAttributes: new Set<string>(),\n\t\tdisallowAttributes: new Set<string>(),\n\n\t\tallowAttributesOf: new Set<string>(),\n\n\t\tinheritTypesFrom: new Set<string>()\n\t};\n\n\tcopyTypes( sourceItemRules, itemRule );\n\n\tcopyProperty( sourceItemRules, itemRule, 'allowIn' );\n\tcopyProperty( sourceItemRules, itemRule, 'allowChildren' );\n\tcopyProperty( sourceItemRules, itemRule, 'disallowIn' );\n\tcopyProperty( sourceItemRules, itemRule, 'disallowChildren' );\n\n\tcopyProperty( sourceItemRules, itemRule, 'allowContentOf' );\n\tcopyProperty( sourceItemRules, itemRule, 'allowWhere' );\n\n\tcopyProperty( sourceItemRules, itemRule, 'allowAttributes' );\n\tcopyProperty( sourceItemRules, itemRule, 'disallowAttributes' );\n\n\tcopyProperty( sourceItemRules, itemRule, 'allowAttributesOf' );\n\n\tcopyProperty( sourceItemRules, itemRule, 'inheritTypesFrom' );\n\n\tresolveInheritAll( sourceItemRules, itemRule );\n\n\treturn itemRule;\n}\n\nfunction propagateAllowIn(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const parentName of item.allowIn ) {\n\t\tconst parentItem = definitions[ parentName ];\n\n\t\tif ( parentItem ) {\n\t\t\tparentItem.allowChildren.add( item.name );\n\t\t} else {\n\t\t\titem.allowIn.delete( parentName );\n\t\t}\n\t}\n}\n\nfunction propagateAllowChildren(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const childName of item.allowChildren ) {\n\t\tconst childItem = definitions[ childName ];\n\n\t\tif ( childItem ) {\n\t\t\tchildItem.allowIn.add( item.name );\n\t\t} else {\n\t\t\titem.allowChildren.delete( childName );\n\t\t}\n\t}\n}\n\nfunction propagateDisallowIn(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const parentName of item.disallowIn ) {\n\t\tconst parentItem = definitions[ parentName ];\n\n\t\tif ( parentItem ) {\n\t\t\tparentItem.disallowChildren.add( item.name );\n\t\t} else {\n\t\t\titem.disallowIn.delete( parentName );\n\t\t}\n\t}\n}\n\nfunction propagateDisallowChildren(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const childName of item.disallowChildren ) {\n\t\tconst childItem = definitions[ childName ];\n\n\t\tif ( childItem ) {\n\t\t\tchildItem.disallowIn.add( item.name );\n\t\t} else {\n\t\t\titem.disallowChildren.delete( childName );\n\t\t}\n\t}\n}\n\nfunction resolveDisallows(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const childName of item.disallowChildren ) {\n\t\titem.allowChildren.delete( childName );\n\t}\n\n\tfor ( const parentName of item.disallowIn ) {\n\t\titem.allowIn.delete( parentName );\n\t}\n\n\tfor ( const attributeName of item.disallowAttributes ) {\n\t\titem.allowAttributes.delete( attributeName );\n\t}\n}\n\nfunction compileAllowContentOf(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const allowContentOfItemName of item.allowContentOf ) {\n\t\tconst baseItem = definitions[ allowContentOfItemName ];\n\n\t\tif ( !baseItem ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Copy `disallowChildren` to propagate this \"knowledge\" down the inheritance chain. The inheritance may involve multiple items and\n\t\t// if this is not propagated, then items down the chain may start to allow for items that were disallowed by previous base items.\n\t\t//\n\t\t// The scenarios were it is important involves multiple inherits both on parent items side and on the child items side.\n\t\tbaseItem.disallowChildren.forEach( childName => {\n\t\t\t// Own item's rules takes precedence before inherited.\n\t\t\t// If the item directly allows for given child, ignore that base item disallowed that child.\n\t\t\tif ( item.allowChildren.has( childName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titem.disallowChildren.add( childName );\n\t\t\tdefinitions[ childName ].disallowIn.add( item.name );\n\t\t} );\n\n\t\t// Copy `allowChildren` from the base item to allow for the same items.\n\t\tbaseItem.allowChildren.forEach( childName => {\n\t\t\t// Own item's rules takes precedence before inherited.\n\t\t\t// Also, `item.disallowChildren` might get some new items during inheritance process.\n\t\t\tif ( item.disallowChildren.has( childName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titem.allowChildren.add( childName );\n\t\t\tdefinitions[ childName ].allowIn.add( item.name );\n\t\t} );\n\t}\n}\n\nfunction compileAllowWhere(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const allowWhereItemName of item.allowWhere ) {\n\t\tconst baseItem = definitions[ allowWhereItemName ];\n\n\t\tif ( !baseItem ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Copy `disallowIn` to propagate this \"knowledge\" down the inheritance chain. The inheritance may involve multiple items and\n\t\t// if this is not propagated, then items down the chain may start to be allowed in items in which they were disallowed previously.\n\t\t//\n\t\t// The scenarios were it is important involves multiple inherits both on parent items side and on the child items side.\n\t\tbaseItem.disallowIn.forEach( parentName => {\n\t\t\t// Own item's rules takes precedence before inherited.\n\t\t\t// If the item is directly allowed in given parent, ignore that base item was disallowed in it.\n\t\t\tif ( item.allowIn.has( parentName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titem.disallowIn.add( parentName );\n\t\t\tdefinitions[ parentName ].disallowChildren.add( item.name );\n\t\t} );\n\n\t\t// Copy `allowIn` from the base item to allow item in same parents.\n\t\tbaseItem.allowIn.forEach( parentName => {\n\t\t\t// Own item's rules takes precedence before inherited.\n\t\t\t// Also, `item.disallowIn` might get some new items during inheritance process.\n\t\t\tif ( item.disallowIn.has( parentName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titem.allowIn.add( parentName );\n\t\t\tdefinitions[ parentName ].allowChildren.add( item.name );\n\t\t} );\n\t}\n}\n\nfunction compileDefinitions( definitions: Record<string, SchemaCompiledItemDefinitionInternal> ) {\n\tconst finalDefinitions: Record<string, SchemaCompiledItemDefinition> = {};\n\n\tfor ( const item of Object.values( definitions ) ) {\n\t\tfinalDefinitions[ item.name ] = {\n\t\t\tname: item.name,\n\n\t\t\t// `is*` properties may not be set - convert `undefined` to `false`.\n\t\t\tisBlock: !!item.isBlock,\n\t\t\tisContent: !!item.isContent,\n\t\t\tisInline: !!item.isInline,\n\t\t\tisLimit: !!item.isLimit,\n\t\t\tisObject: !!item.isObject,\n\t\t\tisSelectable: !!item.isSelectable,\n\n\t\t\t// Filter out non-existing items.\n\t\t\tallowIn: Array.from( item.allowIn ).filter( name => !!definitions[ name ] ),\n\t\t\tallowChildren: Array.from( item.allowChildren ).filter( name => !!definitions[ name ] ),\n\t\t\tallowAttributes: Array.from( item.allowAttributes )\n\t\t};\n\t}\n\n\treturn finalDefinitions;\n}\n\nfunction compileAllowAttributesOf(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const allowAttributeOfItemName of item.allowAttributesOf ) {\n\t\tconst baseItem = definitions[ allowAttributeOfItemName ];\n\n\t\tif ( !baseItem ) {\n\t\t\treturn;\n\t\t}\n\n\t\tbaseItem.allowAttributes.forEach( attributeName => {\n\t\t\tif ( item.disallowAttributes.has( attributeName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titem.allowAttributes.add( attributeName );\n\t\t} );\n\t}\n}\n\nfunction compileInheritPropertiesFrom(\n\tdefinitions: Record<string, SchemaCompiledItemDefinitionInternal>,\n\titem: SchemaCompiledItemDefinitionInternal\n) {\n\tfor ( const inheritPropertiesOfItemName of item.inheritTypesFrom! ) {\n\t\tconst inheritFrom = definitions[ inheritPropertiesOfItemName ];\n\n\t\tif ( inheritFrom ) {\n\t\t\tconst typeNames = Object.keys( inheritFrom ).filter( name => name.startsWith( 'is' ) ) as TypeNames;\n\n\t\t\tfor ( const name of typeNames ) {\n\t\t\t\tif ( !( name in item ) ) {\n\t\t\t\t\titem[ name ] = inheritFrom[ name ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction copyTypes( sourceItemRules: Array<SchemaItemDefinition>, itemRule: SchemaCompiledItemDefinitionInternal ) {\n\tfor ( const sourceItemRule of sourceItemRules ) {\n\t\tconst typeNames = Object.keys( sourceItemRule ).filter( name => name.startsWith( 'is' ) ) as TypeNames;\n\n\t\tfor ( const name of typeNames ) {\n\t\t\titemRule[ name ] = !!sourceItemRule[ name ];\n\t\t}\n\t}\n}\n\nfunction copyProperty(\n\tsourceItemRules: Array<SchemaItemDefinition>,\n\titemRule: SchemaCompiledItemDefinitionInternal,\n\tpropertyName:\n\t\t'allowIn' |\n\t\t'allowChildren' |\n\t\t'disallowIn' |\n\t\t'disallowChildren' |\n\t\t'allowWhere' |\n\t\t'allowContentOf' |\n\t\t'allowAttributes' |\n\t\t'disallowAttributes' |\n\t\t'allowAttributesOf' |\n\t\t'inheritTypesFrom'\n) {\n\tfor ( const sourceItemRule of sourceItemRules ) {\n\t\tlet value = sourceItemRule[ propertyName ];\n\n\t\t// `value` can be a string, an array or undefined.\n\t\t// Convert a string to an array with one item, then handle an array. Skip undefined this way.\n\t\tif ( typeof value == 'string' ) {\n\t\t\tvalue = [ value ];\n\t\t}\n\n\t\tif ( Array.isArray( value ) ) {\n\t\t\tvalue.forEach( singleValue => itemRule[ propertyName ].add( singleValue ) );\n\t\t}\n\t}\n}\n\nfunction resolveInheritAll( sourceItemRules: Array<SchemaItemDefinition>, itemRule: SchemaCompiledItemDefinitionInternal ) {\n\tfor ( const sourceItemRule of sourceItemRules ) {\n\t\tconst inheritFrom = sourceItemRule.inheritAllFrom;\n\n\t\tif ( inheritFrom ) {\n\t\t\titemRule.allowContentOf.add( inheritFrom );\n\t\t\titemRule.allowWhere.add( inheritFrom );\n\t\t\titemRule.allowAttributesOf.add( inheritFrom );\n\t\t\titemRule.inheritTypesFrom.add( inheritFrom );\n\t\t}\n\t}\n}\n\nfunction mapContextItem( ctxItem: string | Item | DocumentFragment ): SchemaContextItem {\n\tif ( typeof ctxItem == 'string' || ctxItem.is( 'documentFragment' ) ) {\n\t\treturn {\n\t\t\tname: typeof ctxItem == 'string' ? ctxItem : '$documentFragment',\n\n\t\t\t* getAttributeKeys() {},\n\n\t\t\tgetAttribute() {}\n\t\t};\n\t} else {\n\t\treturn {\n\t\t\t// '$text' means text nodes and text proxies.\n\t\t\tname: ctxItem.is( 'element' ) ? ctxItem.name : '$text',\n\n\t\t\t* getAttributeKeys() {\n\t\t\t\tyield* ctxItem.getAttributeKeys();\n\t\t\t},\n\n\t\t\tgetAttribute( key ) {\n\t\t\t\treturn ctxItem.getAttribute( key );\n\t\t\t}\n\t\t};\n\t}\n}\n\n/**\n * Generator function returning values from provided walkers, switching between them at each iteration. If only one walker\n * is provided it will return data only from that walker.\n *\n * @param backward Walker iterating in backward direction.\n * @param forward Walker iterating in forward direction.\n * @returns Object returned at each iteration contains `value` and `walker` (informing which walker returned\n * given value) fields.\n */\nfunction* combineWalkers( backward: TreeWalker | undefined, forward: TreeWalker | undefined ) {\n\tlet done = false;\n\n\twhile ( !done ) {\n\t\tdone = true;\n\n\t\tif ( backward ) {\n\t\t\tconst step = backward.next();\n\n\t\t\tif ( !step.done ) {\n\t\t\t\tdone = false;\n\t\t\t\tyield {\n\t\t\t\t\twalker: backward,\n\t\t\t\t\tvalue: step.value\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( forward ) {\n\t\t\tconst step = forward.next();\n\n\t\t\tif ( !step.done ) {\n\t\t\t\tdone = false;\n\t\t\t\tyield {\n\t\t\t\t\twalker: forward,\n\t\t\t\t\tvalue: step.value\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Takes an array of non-intersecting ranges. For each of them gets minimal flat ranges covering that range and returns\n * all those minimal flat ranges.\n *\n * @param ranges Ranges to process.\n * @returns Minimal flat ranges of given `ranges`.\n */\nfunction* convertToMinimalFlatRanges( ranges: Iterable<Range> ): Iterable<Range> {\n\tfor ( const range of ranges ) {\n\t\tyield* range.getMinimalFlatRanges();\n\t}\n}\n\nfunction removeDisallowedAttributeFromNode( schema: Schema, node: Node, writer: Writer ) {\n\tfor ( const attribute of node.getAttributeKeys() ) {\n\t\tif ( !schema.checkAttribute( node, attribute ) ) {\n\t\t\twriter.removeAttribute( attribute, node );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/conversion/upcastdispatcher\n */\n\nimport ViewConsumable from './viewconsumable.js';\nimport ModelRange from '../model/range.js';\nimport ModelPosition from '../model/position.js';\nimport type ModelElement from '../model/element.js';\nimport type ModelNode from '../model/node.js';\nimport type ViewElement from '../view/element.js';\nimport type ViewText from '../view/text.js';\nimport type ViewDocumentFragment from '../view/documentfragment.js';\nimport type ModelDocumentFragment from '../model/documentfragment.js';\nimport type { default as Schema, SchemaContextDefinition } from '../model/schema.js';\nimport { SchemaContext } from '../model/schema.js'; // eslint-disable-line no-duplicate-imports\nimport type ModelWriter from '../model/writer.js';\nimport { isParagraphable, wrapInParagraph } from '../model/utils/autoparagraphing.js';\n\nimport type ViewItem from '../view/item.js';\n\nimport { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Upcast dispatcher is a central point of the view-to-model conversion, which is a process of\n * converting a given {@link module:engine/view/documentfragment~DocumentFragment view document fragment} or\n * {@link module:engine/view/element~Element view element} into a correct model structure.\n *\n * During the conversion process, the dispatcher fires events for all {@link module:engine/view/node~Node view nodes}\n * from the converted view document fragment.\n * Special callbacks called \"converters\" should listen to these events in order to convert the view nodes.\n *\n * The second parameter of the callback is the `data` object with the following properties:\n *\n * * `data.viewItem` contains a {@link module:engine/view/node~Node view node} or a\n * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}\n * that is converted at the moment and might be handled by the callback.\n * * `data.modelRange` is used to point to the result\n * of the current conversion (e.g. the element that is being inserted)\n * and is always a {@link module:engine/model/range~Range} when the conversion succeeds.\n * * `data.modelCursor` is a {@link module:engine/model/position~Position position} on which the converter should insert\n * the newly created items.\n *\n * The third parameter of the callback is an instance of {@link module:engine/conversion/upcastdispatcher~UpcastConversionApi}\n * which provides additional tools for converters.\n *\n * You can read more about conversion in the {@glink framework/deep-dive/conversion/upcast Upcast conversion} guide.\n *\n * Examples of event-based converters:\n *\n * ```ts\n * // A converter for links (<a>).\n * editor.data.upcastDispatcher.on( 'element:a', ( evt, data, conversionApi ) => {\n * \tif ( conversionApi.consumable.consume( data.viewItem, { name: true, attributes: [ 'href' ] } ) ) {\n * \t\t// The <a> element is inline and is represented by an attribute in the model.\n * \t\t// This is why you need to convert only children.\n * \t\tconst { modelRange } = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n *\n * \t\tfor ( let item of modelRange.getItems() ) {\n * \t\t\tif ( conversionApi.schema.checkAttribute( item, 'linkHref' ) ) {\n * \t\t\t\tconversionApi.writer.setAttribute( 'linkHref', data.viewItem.getAttribute( 'href' ), item );\n * \t\t\t}\n * \t\t}\n * \t}\n * } );\n *\n * // Convert <p> element's font-size style.\n * // Note: You should use a low-priority observer in order to ensure that\n * // it is executed after the element-to-element converter.\n * editor.data.upcastDispatcher.on( 'element:p', ( evt, data, conversionApi ) => {\n * \tconst { consumable, schema, writer } = conversionApi;\n *\n * \tif ( !consumable.consume( data.viewItem, { style: 'font-size' } ) ) {\n * \t\treturn;\n * \t}\n *\n * \tconst fontSize = data.viewItem.getStyle( 'font-size' );\n *\n * \t// Do not go for the model element after data.modelCursor because it might happen\n * \t// that a single view element was converted to multiple model elements. Get all of them.\n * \tfor ( const item of data.modelRange.getItems( { shallow: true } ) ) {\n * \t\tif ( schema.checkAttribute( item, 'fontSize' ) ) {\n * \t\t\twriter.setAttribute( 'fontSize', fontSize, item );\n * \t\t}\n * \t}\n * }, { priority: 'low' } );\n *\n * // Convert all elements which have no custom converter into a paragraph (autoparagraphing).\n * editor.data.upcastDispatcher.on( 'element', ( evt, data, conversionApi ) => {\n * \t// Check if an element can be converted.\n * \tif ( !conversionApi.consumable.test( data.viewItem, { name: data.viewItem.name } ) ) {\n * \t\t// When an element is already consumed by higher priority converters, do nothing.\n * \t\treturn;\n * \t}\n *\n * \tconst paragraph = conversionApi.writer.createElement( 'paragraph' );\n *\n * \t// Try to safely insert a paragraph at the model cursor - it will find an allowed parent for the current element.\n * \tif ( !conversionApi.safeInsert( paragraph, data.modelCursor ) ) {\n * \t\t// When an element was not inserted, it means that you cannot insert a paragraph at this position.\n * \t\treturn;\n * \t}\n *\n * \t// Consume the inserted element.\n * \tconversionApi.consumable.consume( data.viewItem, { name: data.viewItem.name } ) );\n *\n * \t// Convert the children to a paragraph.\n * \tconst { modelRange } = conversionApi.convertChildren( data.viewItem,  paragraph ) );\n *\n * \t// Update `modelRange` and `modelCursor` in the `data` as a conversion result.\n * \tconversionApi.updateConversionResult( paragraph, data );\n * }, { priority: 'low' } );\n * ```\n *\n * @fires viewCleanup\n * @fires element\n * @fires text\n * @fires documentFragment\n */\nexport default class UpcastDispatcher extends /* #__PURE__ */ EmitterMixin() {\n\t/**\n\t * An interface passed by the dispatcher to the event callbacks.\n\t */\n\tpublic conversionApi: UpcastConversionApi;\n\n\t/**\n\t * The list of elements that were created during splitting.\n\t *\n\t * After the conversion process, the list is cleared.\n\t */\n\tprivate _splitParts = new Map<ModelElement, Array<ModelElement>>();\n\n\t/**\n\t * The list of cursor parent elements that were created during splitting.\n\t *\n\t * After the conversion process the list is cleared.\n\t */\n\tprivate _cursorParents = new Map<ModelNode, ModelElement | ModelDocumentFragment>();\n\n\t/**\n\t * The position in the temporary structure where the converted content is inserted. The structure reflects the context of\n\t * the target position where the content will be inserted. This property is built based on the context parameter of the\n\t * convert method.\n\t */\n\tprivate _modelCursor: ModelPosition | null = null;\n\n\t/**\n\t * The list of elements that were created during the splitting but should not get removed on conversion end even if they are empty.\n\t *\n\t * The list is cleared after the conversion process.\n\t */\n\tprivate _emptyElementsToKeep = new Set<ModelElement>();\n\n\t/**\n\t * Creates an upcast dispatcher that operates using the passed API.\n\t *\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi\n\t * @param conversionApi Additional properties for an interface that will be passed to events fired\n\t * by the upcast dispatcher.\n\t */\n\tconstructor( conversionApi: Pick<UpcastConversionApi, 'schema'> ) {\n\t\tsuper();\n\n\t\tthis.conversionApi = {\n\t\t\t...conversionApi,\n\t\t\tconsumable: null as any,\n\t\t\twriter: null as any,\n\t\t\tstore: null,\n\t\t\tconvertItem: ( viewItem, modelCursor ) => this._convertItem( viewItem, modelCursor ),\n\t\t\tconvertChildren: ( viewElement, positionOrElement ) => this._convertChildren( viewElement, positionOrElement ),\n\t\t\tsafeInsert: ( modelNode, position ) => this._safeInsert( modelNode, position ),\n\t\t\tupdateConversionResult: ( modelElement, data ) => this._updateConversionResult( modelElement, data ),\n\t\t\t// Advanced API - use only if custom position handling is needed.\n\t\t\tsplitToAllowedParent: ( modelNode, modelCursor ) => this._splitToAllowedParent( modelNode, modelCursor ),\n\t\t\tgetSplitParts: modelElement => this._getSplitParts( modelElement ),\n\t\t\tkeepEmptyElement: modelElement => this._keepEmptyElement( modelElement )\n\t\t};\n\t}\n\n\t/**\n\t * Starts the conversion process. The entry point for the conversion.\n\t *\n\t * @fires element\n\t * @fires text\n\t * @fires documentFragment\n\t * @param viewElement The part of the view to be converted.\n\t * @param writer An instance of the model writer.\n\t * @param context Elements will be converted according to this context.\n\t * @returns Model data that is the result of the conversion process\n\t * wrapped in `DocumentFragment`. Converted marker elements will be set as the document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t */\n\tpublic convert(\n\t\tviewElement: ViewElement | ViewDocumentFragment,\n\t\twriter: ModelWriter,\n\t\tcontext: SchemaContextDefinition = [ '$root' ]\n\t): ModelDocumentFragment {\n\t\tthis.fire<UpcastViewCleanupEvent>( 'viewCleanup', viewElement );\n\n\t\t// Create context tree and set position in the top element.\n\t\t// Items will be converted according to this position.\n\t\tthis._modelCursor = createContextTree( context, writer )!;\n\n\t\t// Store writer in conversion as a conversion API\n\t\t// to be sure that conversion process will use the same batch.\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// Create consumable values list for conversion process.\n\t\tthis.conversionApi.consumable = ViewConsumable.createFrom( viewElement );\n\n\t\t// Custom data stored by converter for conversion process.\n\t\tthis.conversionApi.store = {};\n\n\t\t// Do the conversion.\n\t\tconst { modelRange } = this._convertItem( viewElement, this._modelCursor );\n\n\t\t// Conversion result is always a document fragment so let's create it.\n\t\tconst documentFragment = writer.createDocumentFragment();\n\n\t\t// When there is a conversion result.\n\t\tif ( modelRange ) {\n\t\t\t// Remove all empty elements that were created while splitting.\n\t\t\tthis._removeEmptyElements();\n\n\t\t\t// Move all items that were converted in context tree to the document fragment.\n\t\t\tfor ( const item of Array.from( this._modelCursor.parent.getChildren() ) ) {\n\t\t\t\twriter.append( item, documentFragment );\n\t\t\t}\n\n\t\t\t// Extract temporary markers elements from model and set as static markers collection.\n\t\t\t( documentFragment as any ).markers = extractMarkersFromModelFragment( documentFragment, writer );\n\t\t}\n\n\t\t// Clear context position.\n\t\tthis._modelCursor = null;\n\n\t\t// Clear split elements & parents lists.\n\t\tthis._splitParts.clear();\n\t\tthis._cursorParents.clear();\n\t\tthis._emptyElementsToKeep.clear();\n\n\t\t// Clear conversion API.\n\t\t( this.conversionApi as any ).writer = null;\n\t\tthis.conversionApi.store = null;\n\n\t\t// Return fragment as conversion result.\n\t\treturn documentFragment;\n\t}\n\n\t/**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertItem\n\t */\n\tprivate _convertItem( viewItem: ViewItem | ViewDocumentFragment, modelCursor: ModelPosition ): {\n\t\tmodelRange: ModelRange | null;\n\t\tmodelCursor: ModelPosition;\n\t} {\n\t\tconst data: UpcastConversionData = { viewItem, modelCursor, modelRange: null };\n\n\t\tif ( viewItem.is( 'element' ) ) {\n\t\t\tthis.fire<UpcastElementEvent>(\n\t\t\t\t`element:${ viewItem.name }`,\n\t\t\t\tdata as UpcastConversionData<ViewElement>,\n\t\t\t\tthis.conversionApi\n\t\t\t);\n\t\t} else if ( viewItem.is( '$text' ) ) {\n\t\t\tthis.fire<UpcastTextEvent>(\n\t\t\t\t'text',\n\t\t\t\tdata as UpcastConversionData<ViewText>,\n\t\t\t\tthis.conversionApi\n\t\t\t);\n\t\t} else {\n\t\t\tthis.fire<UpcastDocumentFragmentEvent>(\n\t\t\t\t'documentFragment',\n\t\t\t\tdata as UpcastConversionData<ViewDocumentFragment>,\n\t\t\t\tthis.conversionApi\n\t\t\t);\n\t\t}\n\n\t\t// Handle incorrect conversion result.\n\t\tif ( data.modelRange && !( data.modelRange instanceof ModelRange ) ) {\n\t\t\t/**\n\t\t\t * Incorrect conversion result was dropped.\n\t\t\t *\n\t\t\t * {@link module:engine/model/range~Range Model range} should be a conversion result.\n\t\t\t *\n\t\t\t * @error view-conversion-dispatcher-incorrect-result\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-conversion-dispatcher-incorrect-result', this );\n\t\t}\n\n\t\treturn { modelRange: data.modelRange, modelCursor: data.modelCursor };\n\t}\n\n\t/**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#convertChildren\n\t */\n\tprivate _convertChildren(\n\t\tviewItem: ViewElement | ViewDocumentFragment,\n\t\telementOrModelCursor: ModelPosition | ModelElement\n\t): {\n\t\tmodelRange: ModelRange;\n\t\tmodelCursor: ModelPosition;\n\t} {\n\t\tlet nextModelCursor = elementOrModelCursor.is( 'position' ) ?\n\t\t\telementOrModelCursor : ModelPosition._createAt( elementOrModelCursor, 0 );\n\n\t\tconst modelRange = new ModelRange( nextModelCursor );\n\n\t\tfor ( const viewChild of Array.from( viewItem.getChildren() ) ) {\n\t\t\tconst result = this._convertItem( viewChild, nextModelCursor );\n\n\t\t\tif ( result.modelRange instanceof ModelRange ) {\n\t\t\t\t( modelRange as any ).end = result.modelRange.end;\n\t\t\t\tnextModelCursor = result.modelCursor;\n\t\t\t}\n\t\t}\n\n\t\treturn { modelRange, modelCursor: nextModelCursor };\n\t}\n\n\t/**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#safeInsert\n\t */\n\tprivate _safeInsert(\n\t\tmodelNode: ModelNode,\n\t\tposition: ModelPosition\n\t): boolean {\n\t\t// Find allowed parent for element that we are going to insert.\n\t\t// If current parent does not allow to insert element but one of the ancestors does\n\t\t// then split nodes to allowed parent.\n\t\tconst splitResult = this._splitToAllowedParent( modelNode, position );\n\n\t\t// When there is no split result it means that we can't insert element to model tree, so let's skip it.\n\t\tif ( !splitResult ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Insert element on allowed position.\n\t\tthis.conversionApi.writer.insert( modelNode, splitResult.position );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#updateConversionResult\n\t */\n\tprivate _updateConversionResult( modelElement: ModelElement, data: UpcastConversionData ): void {\n\t\tconst parts = this._getSplitParts( modelElement );\n\n\t\tconst writer = this.conversionApi.writer!;\n\n\t\t// Set conversion result range - only if not set already.\n\t\tif ( !data.modelRange ) {\n\t\t\tdata.modelRange = writer.createRange(\n\t\t\t\twriter.createPositionBefore( modelElement ),\n\t\t\t\twriter.createPositionAfter( parts[ parts.length - 1 ] )\n\t\t\t);\n\t\t}\n\n\t\tconst savedCursorParent = this._cursorParents.get( modelElement );\n\n\t\t// Now we need to check where the `modelCursor` should be.\n\t\tif ( savedCursorParent ) {\n\t\t\t// If we split parent to insert our element then we want to continue conversion in the new part of the split parent.\n\t\t\t//\n\t\t\t// before: <allowed><notAllowed>foo[]</notAllowed></allowed>\n\t\t\t// after:  <allowed><notAllowed>foo</notAllowed> <converted></converted> <notAllowed>[]</notAllowed></allowed>\n\n\t\t\tdata.modelCursor = writer.createPositionAt( savedCursorParent, 0 );\n\t\t} else {\n\t\t\t// Otherwise just continue after inserted element.\n\n\t\t\tdata.modelCursor = data.modelRange.end;\n\t\t}\n\t}\n\n\t/**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#splitToAllowedParent\n\t */\n\tprivate _splitToAllowedParent( node: ModelNode, modelCursor: ModelPosition ): {\n\t\tposition: ModelPosition;\n\t\tcursorParent?: ModelElement | ModelDocumentFragment;\n\t} | null {\n\t\tconst { schema, writer } = this.conversionApi;\n\n\t\t// Try to find allowed parent.\n\t\tlet allowedParent = schema.findAllowedParent( modelCursor, node );\n\n\t\tif ( allowedParent ) {\n\t\t\t// When current position parent allows to insert node then return this position.\n\t\t\tif ( allowedParent === modelCursor.parent ) {\n\t\t\t\treturn { position: modelCursor };\n\t\t\t}\n\n\t\t\t// When allowed parent is in context tree (it's outside the converted tree).\n\t\t\tif ( this._modelCursor!.parent.getAncestors().includes( allowedParent ) ) {\n\t\t\t\tallowedParent = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( !allowedParent ) {\n\t\t\t// Check if the node wrapped with a paragraph would be accepted by the schema.\n\t\t\tif ( !isParagraphable( modelCursor, node, schema ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tposition: wrapInParagraph( modelCursor, writer! )\n\t\t\t};\n\t\t}\n\n\t\t// Split element to allowed parent.\n\t\tconst splitResult = this.conversionApi.writer!.split( modelCursor, allowedParent );\n\n\t\t// Using the range returned by `model.Writer#split`, we will pair original elements with their split parts.\n\t\t//\n\t\t// The range returned from the writer spans \"over the split\" or, precisely saying, from the end of the original element (the one\n\t\t// that got split) to the beginning of the other part of that element:\n\t\t//\n\t\t// <limit><a><b><c>X[]Y</c></b><a></limit> ->\n\t\t// <limit><a><b><c>X[</c></b></a><a><b><c>]Y</c></b></a>\n\t\t//\n\t\t// After the split there cannot be any full node between the positions in `splitRange`. The positions are touching.\n\t\t// Also, because of how splitting works, it is easy to notice, that \"closing tags\" are in the reverse order than \"opening tags\".\n\t\t// Also, since we split all those elements, each of them has to have the other part.\n\t\t//\n\t\t// With those observations in mind, we will pair the original elements with their split parts by saving \"closing tags\" and matching\n\t\t// them with \"opening tags\" in the reverse order. For that we can use a stack.\n\t\tconst stack: Array<ModelElement> = [];\n\n\t\tfor ( const treeWalkerValue of splitResult.range.getWalker() ) {\n\t\t\tif ( treeWalkerValue.type == 'elementEnd' ) {\n\t\t\t\tstack.push( treeWalkerValue.item as ModelElement );\n\t\t\t} else {\n\t\t\t\t// There should not be any text nodes after the element is split, so the only other value is `elementStart`.\n\t\t\t\tconst originalPart = stack.pop();\n\t\t\t\tconst splitPart = treeWalkerValue.item as ModelElement;\n\n\t\t\t\tthis._registerSplitPair( originalPart!, splitPart );\n\t\t\t}\n\t\t}\n\n\t\tconst cursorParent = splitResult.range.end.parent;\n\t\tthis._cursorParents.set( node, cursorParent );\n\n\t\treturn {\n\t\t\tposition: splitResult.position,\n\t\t\tcursorParent\n\t\t};\n\t}\n\n\t/**\n\t * Registers that a `splitPart` element is a split part of the `originalPart` element.\n\t *\n\t * The data set by this method is used by {@link #_getSplitParts} and {@link #_removeEmptyElements}.\n\t */\n\tprivate _registerSplitPair( originalPart: ModelElement, splitPart: ModelElement ): void {\n\t\tif ( !this._splitParts.has( originalPart ) ) {\n\t\t\tthis._splitParts.set( originalPart, [ originalPart ] );\n\t\t}\n\n\t\tconst list = this._splitParts.get( originalPart )!;\n\n\t\tthis._splitParts.set( splitPart, list );\n\t\tlist.push( splitPart );\n\t}\n\n\t/**\n\t * @see module:engine/conversion/upcastdispatcher~UpcastConversionApi#getSplitParts\n\t */\n\tprivate _getSplitParts( element: ModelElement ): Array<ModelElement> {\n\t\tlet parts: Array<ModelElement>;\n\n\t\tif ( !this._splitParts.has( element ) ) {\n\t\t\tparts = [ element ];\n\t\t} else {\n\t\t\tparts = this._splitParts.get( element )!;\n\t\t}\n\n\t\treturn parts;\n\t}\n\n\t/**\n\t * Mark an element that were created during the splitting to not get removed on conversion end even if it is empty.\n\t */\n\tprivate _keepEmptyElement( element: ModelElement ): void {\n\t\tthis._emptyElementsToKeep.add( element );\n\t}\n\n\t/**\n\t * Checks if there are any empty elements created while splitting and removes them.\n\t *\n\t * This method works recursively to re-check empty elements again after at least one element was removed in the initial call,\n\t * as some elements might have become empty after other empty elements were removed from them.\n\t */\n\tprivate _removeEmptyElements(): void {\n\t\tlet anyRemoved = false;\n\n\t\tfor ( const element of this._splitParts.keys() ) {\n\t\t\tif ( element.isEmpty && !this._emptyElementsToKeep.has( element ) ) {\n\t\t\t\tthis.conversionApi.writer.remove( element );\n\t\t\t\tthis._splitParts.delete( element );\n\n\t\t\t\tanyRemoved = true;\n\t\t\t}\n\t\t}\n\n\t\tif ( anyRemoved ) {\n\t\t\tthis._removeEmptyElements();\n\t\t}\n\t}\n}\n\n/**\n * Fired before the first conversion event, at the beginning of the upcast (view-to-model conversion) process.\n *\n * @eventName ~UpcastDispatcher#viewCleanup\n * @param viewItem A part of the view to be converted.\n */\nexport type UpcastViewCleanupEvent = {\n\tname: 'viewCleanup';\n\targs: [ ViewElement | ViewDocumentFragment ];\n};\n\nexport type UpcastEvent<TName extends string, TItem extends ViewItem | ViewDocumentFragment> = {\n\tname: TName | `${ TName }:${ string }`;\n\targs: [ data: UpcastConversionData<TItem>, conversionApi: UpcastConversionApi ];\n};\n\n/**\n * Conversion data.\n *\n * **Note:** Keep in mind that this object is shared by reference between all conversion callbacks that will be called.\n * This means that callbacks can override values if needed, and these values will be available in other callbacks.\n */\nexport interface UpcastConversionData<TItem extends ViewItem | ViewDocumentFragment = ViewItem | ViewDocumentFragment> {\n\n\t/**\n\t * The converted item.\n\t */\n\tviewItem: TItem;\n\n\t/**\n\t * The position where the converter should start changes.\n\t * Change this value for the next converter to tell where the conversion should continue.\n\t */\n\tmodelCursor: ModelPosition;\n\n\t/**\n\t * The current state of conversion result. Every change to\n\t * the converted element should be reflected by setting or modifying this property.\n\t */\n\tmodelRange: ModelRange | null;\n}\n\n/**\n * Fired when an {@link module:engine/view/element~Element} is converted.\n *\n * `element` is a namespace event for a class of events. Names of actually called events follow the pattern of\n * `element:<elementName>` where `elementName` is the name of the converted element. This way listeners may listen to\n * a conversion of all or just specific elements.\n *\n * @eventName ~UpcastDispatcher#element\n * @param data The conversion data. Keep in mind that this object is shared by reference between all callbacks\n * that will be called. This means that callbacks can override values if needed, and these values\n * will be available in other callbacks.\n * @param conversionApi Conversion utilities to be used by the callback.\n */\nexport type UpcastElementEvent = UpcastEvent<'element', ViewElement>;\n\n/**\n * Fired when a {@link module:engine/view/text~Text} is converted.\n *\n * @eventName ~UpcastDispatcher#text\n * @see ~UpcastDispatcher#event:element\n */\nexport type UpcastTextEvent = UpcastEvent<'text', ViewText>;\n\n/**\n * Fired when a {@link module:engine/view/documentfragment~DocumentFragment} is converted.\n *\n * @eventName ~UpcastDispatcher#documentFragment\n * @see ~UpcastDispatcher#event:element\n */\nexport type UpcastDocumentFragmentEvent = UpcastEvent<'documentFragment', ViewDocumentFragment>;\n\n/**\n * Traverses given model item and searches elements which marks marker range. Found element is removed from\n * DocumentFragment but path of this element is stored in a Map which is then returned.\n *\n * @param modelItem Fragment of model.\n * @returns List of static markers.\n */\nfunction extractMarkersFromModelFragment( modelItem: ModelDocumentFragment, writer: ModelWriter ): Map<string, ModelRange> {\n\tconst markerElements = new Set<ModelElement>();\n\tconst markers = new Map<string, ModelRange>();\n\n\t// Create ModelTreeWalker.\n\tconst range = ModelRange._createIn( modelItem ).getItems();\n\n\t// Walk through DocumentFragment and collect marker elements.\n\tfor ( const item of range ) {\n\t\t// Check if current element is a marker.\n\t\tif ( item.is( 'element', '$marker' ) ) {\n\t\t\tmarkerElements.add( item );\n\t\t}\n\t}\n\n\t// Walk through collected marker elements store its path and remove its from the DocumentFragment.\n\tfor ( const markerElement of markerElements ) {\n\t\tconst markerName = markerElement.getAttribute( 'data-name' ) as string;\n\t\tconst currentPosition = writer.createPositionBefore( markerElement );\n\n\t\t// When marker of given name is not stored it means that we have found the beginning of the range.\n\t\tif ( !markers.has( markerName ) ) {\n\t\t\tmarkers.set( markerName, new ModelRange( currentPosition.clone() ) );\n\t\t// Otherwise is means that we have found end of the marker range.\n\t\t} else {\n\t\t\t( markers.get( markerName ) as any ).end = currentPosition.clone();\n\t\t}\n\n\t\t// Remove marker element from DocumentFragment.\n\t\twriter.remove( markerElement );\n\t}\n\n\treturn markers;\n}\n\n/**\n * Creates model fragment according to given context and returns position in the bottom (the deepest) element.\n */\nfunction createContextTree(\n\tcontextDefinition: SchemaContextDefinition,\n\twriter: ModelWriter\n): ModelPosition | undefined {\n\tlet position: ModelPosition | undefined;\n\n\tfor ( const item of new SchemaContext( contextDefinition ) ) {\n\t\tconst attributes: Record<string, unknown> = {};\n\n\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\tattributes[ key ] = item.getAttribute( key );\n\t\t}\n\n\t\tconst current = writer.createElement( item.name, attributes );\n\n\t\tif ( position ) {\n\t\t\twriter.insert( current, position );\n\t\t}\n\n\t\tposition = ModelPosition._createAt( current, 0 );\n\t}\n\n\treturn position;\n}\n\n/**\n * A set of conversion utilities available as the third parameter of the\n * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher upcast dispatcher}'s events.\n */\nexport interface UpcastConversionApi {\n\n\t/**\n\t * Stores information about what parts of the processed view item are still waiting to be handled. After a piece of view item\n\t * was converted, an appropriate consumable value should be\n\t * {@link module:engine/conversion/viewconsumable~ViewConsumable#consume consumed}.\n\t */\n\tconsumable: ViewConsumable;\n\n\t/**\n\t * The model's schema instance.\n\t */\n\tschema: Schema;\n\n\t/**\n\t * The {@link module:engine/model/writer~Writer} instance used to manipulate the data during conversion.\n\t */\n\twriter: ModelWriter;\n\n\t/**\n\t * Custom data stored by converters for the conversion process. Custom properties of this object can be defined and use to\n\t * pass parameters between converters.\n\t *\n\t * The difference between this property and the `data` parameter of\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element} is that the `data` parameters allow you\n\t * to pass parameters within a single event and `store` within the whole conversion.\n\t */\n\tstore: unknown;\n\n\t/**\n\t * Starts the conversion of a given item by firing an appropriate event.\n\t *\n\t * Every fired event is passed (as the first parameter) an object with the `modelRange` property. Every event may set and/or\n\t * modify that property. When all callbacks are done, the final value of the `modelRange` property is returned by this method.\n\t * The `modelRange` must be a {@link module:engine/model/range~Range model range} or `null` (as set by default).\n\t *\n\t * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n\t * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:text\n\t * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:documentFragment\n\t * @param viewItem Item to convert.\n\t * @param modelCursor The conversion position.\n\t * @returns The conversion result:\n\t * * `result.modelRange` The model range containing the result of the item conversion,\n\t * created and modified by callbacks attached to the fired event, or `null` if the conversion result was incorrect.\n\t * * `result.modelCursor` The position where the conversion should be continued.\n\t */\n\tconvertItem( viewItem: ViewItem, modelCursor: ModelPosition ): {\n\t\tmodelRange: ModelRange | null;\n\t\tmodelCursor: ModelPosition;\n\t};\n\n\t/**\n\t * Starts the conversion of all children of a given item by firing appropriate events for all the children.\n\t *\n\t * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n\t * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:text\n\t * @fires module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:documentFragment\n\t * @param viewElement An element whose children should be converted.\n\t * @param positionOrElement A position or an element of\n\t * the conversion.\n\t * @returns The conversion result:\n\t * * `result.modelRange` The model range containing the results of the conversion of all children\n\t * of the given item. When no child was converted, the range is collapsed.\n\t * * `result.modelCursor` The position where the conversion should be continued.\n\t */\n\tconvertChildren( viewElement: ViewElement | ViewDocumentFragment, positionOrElement: ModelPosition | ModelElement ): {\n\t\tmodelRange: ModelRange | null;\n\t\tmodelCursor: ModelPosition;\n\t};\n\n\t/**\n\t * Safely inserts an element to the document, checking the {@link module:engine/model/schema~Schema schema} to find an allowed parent\n\t * for an element that you are going to insert, starting from the given position. If the current parent does not allow to insert\n\t * the element but one of the ancestors does, then splits the nodes to allowed parent.\n\t *\n\t * If the schema allows to insert the node in a given position, nothing is split.\n\t *\n\t * If it was not possible to find an allowed parent, `false` is returned and nothing is split.\n\t *\n\t * Otherwise, ancestors are split.\n\t *\n\t * For instance, if `<imageBlock>` is not allowed in `<paragraph>` but is allowed in `$root`:\n\t *\n\t * ```\n\t * <paragraph>foo[]bar</paragraph>\n\t *\n\t * -> safe insert for `<imageBlock>` will split ->\n\t *\n\t * <paragraph>foo</paragraph>[]<paragraph>bar</paragraph>\n\t *```\n\t *\n\t * Example usage:\n\t *\n\t * ```\n\t * const myElement = conversionApi.writer.createElement( 'myElement' );\n\t *\n\t * if ( !conversionApi.safeInsert( myElement, data.modelCursor ) ) {\n\t * \treturn;\n\t * }\n\t *```\n\t *\n\t * The split result is saved and {@link #updateConversionResult} should be used to update the\n\t * {@link module:engine/conversion/upcastdispatcher~UpcastConversionData conversion data}.\n\t *\n\t * @param modelNode The node to insert.\n\t * @param position The position where an element is going to be inserted.\n\t * @returns The split result. If it was not possible to find an allowed position, `false` is returned.\n\t */\n\tsafeInsert( modelNode: ModelNode, position: ModelPosition ): boolean;\n\n\t/**\n\t * Updates the conversion result and sets a proper {@link module:engine/conversion/upcastdispatcher~UpcastConversionData#modelRange} and\n\t * the next {@link module:engine/conversion/upcastdispatcher~UpcastConversionData#modelCursor} after the conversion.\n\t * Used together with {@link #safeInsert}, it enables you to easily convert elements without worrying if the node was split\n\t * during the conversion of its children.\n\t *\n\t * A usage example in converter code:\n\t *\n\t * ```ts\n\t * const myElement = conversionApi.writer.createElement( 'myElement' );\n\t *\n\t * if ( !conversionApi.safeInsert( myElement, data.modelCursor ) ) {\n\t * \treturn;\n\t * }\n\t *\n\t * // Children conversion may split `myElement`.\n\t * conversionApi.convertChildren( data.viewItem, myElement );\n\t *\n\t * conversionApi.updateConversionResult( myElement, data );\n\t * ```\n\t */\n\tupdateConversionResult( modelElement: ModelElement, data: UpcastConversionData ): void;\n\n\t/**\n\t * Checks the {@link module:engine/model/schema~Schema schema} to find an allowed parent for an element that is going to be inserted\n\t * starting from the given position. If the current parent does not allow inserting an element but one of the ancestors does, the method\n\t * splits nodes to allowed parent.\n\t *\n\t * If the schema allows inserting the node in the given position, nothing is split and an object with that position is returned.\n\t *\n\t * If it was not possible to find an allowed parent, `null` is returned and nothing is split.\n\t *\n\t * Otherwise, ancestors are split and an object with a position and the copy of the split element is returned.\n\t *\n\t * For instance, if `<imageBlock>` is not allowed in `<paragraph>` but is allowed in `$root`:\n\t *\n\t * ```\n\t * <paragraph>foo[]bar</paragraph>\n\t *\n\t * -> split for `<imageBlock>` ->\n\t *\n\t * <paragraph>foo</paragraph>[]<paragraph>bar</paragraph>\n\t * ```\n\t *\n\t * In the example above, the position between `<paragraph>` elements will be returned as `position` and the second `paragraph`\n\t * as `cursorParent`.\n\t *\n\t * **Note:** This is an advanced method. For most cases {@link #safeInsert} and {@link #updateConversionResult} should be used.\n\t *\n\t * @param modelNode The node to insert.\n\t * @param modelCursor The position where the element is going to be inserted.\n\t * @returns The split result. If it was not possible to find an allowed position, `null` is returned.\n\t * * `position` The position between split elements.\n\t * * `cursorParent` The element inside which the cursor should be placed to\n\t * continue the conversion. When the element is not defined it means that there was no split.\n\t */\n\tsplitToAllowedParent( modelNode: ModelNode, modelCursor: ModelPosition ): {\n\t\tposition: ModelPosition;\n\t\tcursorParent?: ModelElement | ModelDocumentFragment;\n\t} | null;\n\n\t/**\n\t * Returns all the split parts of the given `element` that were created during upcasting through using {@link #splitToAllowedParent}.\n\t * It enables you to easily track these elements and continue processing them after they are split during the conversion of their\n\t * children.\n\t *\n\t * ```\n\t * <paragraph>Foo<imageBlock />bar<imageBlock />baz</paragraph> ->\n\t * <paragraph>Foo</paragraph><imageBlock /><paragraph>bar</paragraph><imageBlock /><paragraph>baz</paragraph>\n\t * ```\n\t *\n\t * For a reference to any of above paragraphs, the function will return all three paragraphs (the original element included),\n\t * sorted in the order of their creation (the original element is the first one).\n\t *\n\t * If the given `element` was not split, an array with a single element is returned.\n\t *\n\t * A usage example in the converter code:\n\t *\n\t * ```ts\n\t * const myElement = conversionApi.writer.createElement( 'myElement' );\n\t *\n\t * // Children conversion may split `myElement`.\n\t * conversionApi.convertChildren( data.viewItem, data.modelCursor );\n\t *\n\t * const splitParts = conversionApi.getSplitParts( myElement );\n\t * const lastSplitPart = splitParts[ splitParts.length - 1 ];\n\t *\n\t * // Setting `data.modelRange` basing on split parts:\n\t * data.modelRange = conversionApi.writer.createRange(\n\t * \tconversionApi.writer.createPositionBefore( myElement ),\n\t * \tconversionApi.writer.createPositionAfter( lastSplitPart )\n\t * );\n\t *\n\t * // Setting `data.modelCursor` to continue after the last split element:\n\t * data.modelCursor = conversionApi.writer.createPositionAfter( lastSplitPart );\n\t * ```\n\t *\n\t * **Tip:** If you are unable to get a reference to the original element (for example because the code is split into multiple converters\n\t * or even classes) but it has already been converted, you may want to check the first element in `data.modelRange`. This is a common\n\t * situation if an attribute converter is separated from an element converter.\n\t *\n\t * **Note:** This is an advanced method. For most cases {@link #safeInsert} and {@link #updateConversionResult} should be used.\n\t */\n\tgetSplitParts( modelElement: ModelElement ): Array<ModelElement>;\n\n\t/**\n\t * Mark an element that was created during splitting to not get removed on conversion end even if it is empty.\n\t *\n\t * **Note:** This is an advanced method. For most cases you will not need to keep the split empty element.\n\t */\n\tkeepEmptyElement( modelElement: ModelElement ): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/dataprocessor/basichtmlwriter\n */\n\nimport type HtmlWriter from './htmlwriter.js';\nimport { global } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Basic HTML writer. It uses the native `innerHTML` property for basic conversion\n * from a document fragment to an HTML string.\n */\nexport default class BasicHtmlWriter implements HtmlWriter {\n\t/**\n\t * Returns an HTML string created from the document fragment.\n\t */\n\tpublic getHtml( fragment: DocumentFragment ): string {\n\t\tconst doc = global.document.implementation.createHTMLDocument( '' );\n\t\tconst container = doc.createElement( 'div' );\n\n\t\tcontainer.appendChild( fragment );\n\n\t\treturn container.innerHTML;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/dataprocessor/htmldataprocessor\n */\n\n/* globals DOMParser */\n\nimport BasicHtmlWriter from './basichtmlwriter.js';\nimport DomConverter from '../view/domconverter.js';\n\nimport type DataProcessor from './dataprocessor.js';\nimport type HtmlWriter from './htmlwriter.js';\nimport type ViewDocument from '../view/document.js';\nimport type ViewDocumentFragment from '../view/documentfragment.js';\nimport type { MatcherPattern } from '../view/matcher.js';\n\n/**\n * The HTML data processor class.\n * This data processor implementation uses HTML as input and output data.\n */\nexport default class HtmlDataProcessor implements DataProcessor {\n\t/**\n\t * A DOM parser instance used to parse an HTML string to an HTML document.\n\t */\n\tpublic domParser: DOMParser;\n\n\t/**\n\t * A DOM converter used to convert DOM elements to view elements.\n\t */\n\tpublic domConverter: DomConverter;\n\n\t/**\n\t * A basic HTML writer instance used to convert DOM elements to an HTML string.\n\t */\n\tpublic htmlWriter: HtmlWriter;\n\n\tpublic skipComments: boolean = true;\n\n\t/**\n\t * Creates a new instance of the HTML data processor class.\n\t *\n\t * @param document The view document instance.\n\t */\n\tconstructor( document: ViewDocument ) {\n\t\tthis.domParser = new DOMParser();\n\t\tthis.domConverter = new DomConverter( document, { renderingMode: 'data' } );\n\t\tthis.htmlWriter = new BasicHtmlWriter();\n\t}\n\n\t/**\n\t * Converts a provided {@link module:engine/view/documentfragment~DocumentFragment document fragment}\n\t * to data format &ndash; in this case to an HTML string.\n\t *\n\t * @returns HTML string.\n\t */\n\tpublic toData( viewFragment: ViewDocumentFragment ): string {\n\t\t// Convert view DocumentFragment to DOM DocumentFragment.\n\t\tconst domFragment = this.domConverter.viewToDom( viewFragment );\n\n\t\t// Convert DOM DocumentFragment to HTML output.\n\t\treturn this.htmlWriter.getHtml( domFragment );\n\t}\n\n\t/**\n\t * Converts the provided HTML string to a view tree.\n\t *\n\t * @param data An HTML string.\n\t * @returns A converted view element.\n\t */\n\tpublic toView( data: string ): ViewDocumentFragment {\n\t\t// Convert input HTML data to DOM DocumentFragment.\n\t\tconst domFragment = this._toDom( data );\n\n\t\t// Convert DOM DocumentFragment to view DocumentFragment.\n\t\treturn this.domConverter.domToView( domFragment, { skipComments: this.skipComments } ) as ViewDocumentFragment;\n\t}\n\n\t/**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from the DOM to the view elements.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching all view elements whose content should be treated as raw data.\n\t */\n\tpublic registerRawContentMatcher( pattern: MatcherPattern ): void {\n\t\tthis.domConverter.registerRawContentMatcher( pattern );\n\t}\n\n\t/**\n\t * If the processor is set to use marked fillers, it will insert `&nbsp;` fillers wrapped in `<span>` elements\n\t * (`<span data-cke-filler=\"true\">&nbsp;</span>`) instead of regular `&nbsp;` characters.\n\t *\n\t * This mode allows for a more precise handling of the block fillers (so they do not leak into the editor content) but\n\t * bloats the editor data with additional markup.\n\t *\n\t * This mode may be required by some features and will be turned on by them automatically.\n\t *\n\t * @param type Whether to use the default or the marked `&nbsp;` block fillers.\n\t */\n\tpublic useFillerType( type: 'default' | 'marked' ): void {\n\t\tthis.domConverter.blockFillerMode = type == 'marked' ? 'markedNbsp' : 'nbsp';\n\t}\n\n\t/**\n\t * Converts an HTML string to its DOM representation. Returns a document fragment containing nodes parsed from\n\t * the provided data.\n\t */\n\tprotected _toDom( data: string ): DocumentFragment {\n\t\t// Wrap data with a <body> tag so leading non-layout nodes (like <script>, <style>, HTML comment)\n\t\t// will be preserved in the body collection.\n\t\t// Do it only for data that is not a full HTML document.\n\t\tif ( !/<(?:html|body|head|meta)(?:\\s[^>]*)?>/i.test( data.trim().slice( 0, 10_000 ) ) ) {\n\t\t\tdata = `<body>${ data }</body>`;\n\t\t}\n\n\t\tconst document = this.domParser.parseFromString( data, 'text/html' );\n\t\tconst fragment = document.createDocumentFragment();\n\t\tconst bodyChildNodes = document.body.childNodes;\n\n\t\twhile ( bodyChildNodes.length > 0 ) {\n\t\t\tfragment.appendChild( bodyChildNodes[ 0 ] );\n\t\t}\n\n\t\treturn fragment;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/controller/datacontroller\n */\n\nimport {\n\tCKEditorError,\n\tEmitterMixin,\n\tObservableMixin,\n\tlogWarning\n} from '@ckeditor/ckeditor5-utils';\n\nimport Mapper from '../conversion/mapper.js';\n\nimport DowncastDispatcher, { type DowncastInsertEvent } from '../conversion/downcastdispatcher.js';\nimport { insertAttributesAndChildren, insertText } from '../conversion/downcasthelpers.js';\n\nimport UpcastDispatcher, {\n\ttype UpcastDocumentFragmentEvent,\n\ttype UpcastElementEvent,\n\ttype UpcastTextEvent\n} from '../conversion/upcastdispatcher.js';\nimport { convertText, convertToModelFragment } from '../conversion/upcasthelpers.js';\n\nimport ViewDocumentFragment from '../view/documentfragment.js';\nimport ViewDocument from '../view/document.js';\nimport ViewDowncastWriter from '../view/downcastwriter.js';\nimport type ViewElement from '../view/element.js';\nimport type { StylesProcessor } from '../view/stylesmap.js';\nimport type { MatcherPattern } from '../view/matcher.js';\n\nimport ModelRange from '../model/range.js';\nimport type Model from '../model/model.js';\nimport type ModelText from '../model/text.js';\nimport type ModelElement from '../model/element.js';\nimport type ModelTextProxy from '../model/textproxy.js';\nimport type ModelDocumentFragment from '../model/documentfragment.js';\nimport type { SchemaContextDefinition } from '../model/schema.js';\nimport type { BatchType } from '../model/batch.js';\nimport { autoParagraphEmptyRoots } from '../model/utils/autoparagraphing.js';\n\nimport HtmlDataProcessor from '../dataprocessor/htmldataprocessor.js';\nimport type DataProcessor from '../dataprocessor/dataprocessor.js';\n\n/**\n * Controller for the data pipeline. The data pipeline controls how data is retrieved from the document\n * and set inside it. Hence, the controller features two methods which allow to {@link ~DataController#get get}\n * and {@link ~DataController#set set} data of the {@link ~DataController#model model}\n * using the given:\n *\n * * {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor},\n * * downcast converters,\n * * upcast converters.\n *\n * An instance of the data controller is always available in the {@link module:core/editor/editor~Editor#data `editor.data`}\n * property:\n *\n * ```ts\n * editor.data.get( { rootName: 'customRoot' } ); // -> '<p>Hello!</p>'\n * ```\n */\nexport default class DataController extends /* #__PURE__ */ EmitterMixin() {\n\t/**\n\t * Data model.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * Mapper used for the conversion. It has no permanent bindings, because these are created while getting data and\n\t * are cleared directly after the data are converted. However, the mapper is defined as a class property, because\n\t * it needs to be passed to the `DowncastDispatcher` as a conversion API.\n\t */\n\tpublic readonly mapper: Mapper;\n\n\t/**\n\t * Downcast dispatcher used by the {@link #get get method}. Downcast converters should be attached to it.\n\t */\n\tpublic readonly downcastDispatcher: DowncastDispatcher;\n\n\t/**\n\t * Upcast dispatcher used by the {@link #set set method}. Upcast converters should be attached to it.\n\t */\n\tpublic readonly upcastDispatcher: UpcastDispatcher;\n\n\t/**\n\t * The view document used by the data controller.\n\t */\n\tpublic readonly viewDocument: ViewDocument;\n\n\t/**\n\t * Styles processor used during the conversion.\n\t */\n\tpublic readonly stylesProcessor: StylesProcessor;\n\n\t/**\n\t * Data processor used specifically for HTML conversion.\n\t */\n\tpublic readonly htmlProcessor: HtmlDataProcessor;\n\n\t/**\n\t * Data processor used during the conversion.\n\t * Same instance as {@link #htmlProcessor} by default. Can be replaced at run time to handle different format, e.g. XML or Markdown.\n\t */\n\tpublic processor: DataProcessor;\n\n\t/**\n\t * The view downcast writer just for data conversion purposes, i.e. to modify\n\t * the {@link #viewDocument}.\n\t */\n\tprivate readonly _viewWriter: ViewDowncastWriter;\n\n\t/**\n\t * Creates a data controller instance.\n\t *\n\t * @param model Data model.\n\t * @param stylesProcessor The styles processor instance.\n\t */\n\tconstructor( model: Model, stylesProcessor: StylesProcessor ) {\n\t\tsuper();\n\n\t\tthis.model = model;\n\t\tthis.mapper = new Mapper();\n\n\t\tthis.downcastDispatcher = new DowncastDispatcher( {\n\t\t\tmapper: this.mapper,\n\t\t\tschema: model.schema\n\t\t} );\n\t\tthis.downcastDispatcher.on<DowncastInsertEvent<ModelText | ModelTextProxy>>( 'insert:$text', insertText(), { priority: 'lowest' } );\n\t\tthis.downcastDispatcher.on<DowncastInsertEvent>( 'insert', insertAttributesAndChildren(), { priority: 'lowest' } );\n\n\t\tthis.upcastDispatcher = new UpcastDispatcher( {\n\t\t\tschema: model.schema\n\t\t} );\n\n\t\tthis.viewDocument = new ViewDocument( stylesProcessor );\n\t\tthis.stylesProcessor = stylesProcessor;\n\t\tthis.htmlProcessor = new HtmlDataProcessor( this.viewDocument );\n\t\tthis.processor = this.htmlProcessor;\n\t\tthis._viewWriter = new ViewDowncastWriter( this.viewDocument );\n\n\t\t// Define default converters for text and elements.\n\t\t//\n\t\t// Note that if there is no default converter for the element it will be skipped, for instance `<b>foo</b>` will be\n\t\t// converted to nothing. We therefore add `convertToModelFragment` as a last converter so it converts children of that\n\t\t// element to the document fragment so `<b>foo</b>` will still be converted to `foo` even if there is no converter for `<b>`.\n\t\tthis.upcastDispatcher.on<UpcastTextEvent>( 'text', convertText(), { priority: 'lowest' } );\n\t\tthis.upcastDispatcher.on<UpcastElementEvent>( 'element', convertToModelFragment(), { priority: 'lowest' } );\n\t\tthis.upcastDispatcher.on<UpcastDocumentFragmentEvent>( 'documentFragment', convertToModelFragment(), { priority: 'lowest' } );\n\n\t\tObservableMixin().prototype.decorate.call( this, 'init' as any );\n\t\tObservableMixin().prototype.decorate.call( this, 'set' as any );\n\t\tObservableMixin().prototype.decorate.call( this, 'get' as any );\n\t\tObservableMixin().prototype.decorate.call( this, 'toView' as any );\n\t\tObservableMixin().prototype.decorate.call( this, 'toModel' as any );\n\n\t\t// Fire the `ready` event when the initialization has completed. Such low-level listener offers the possibility\n\t\t// to plug into the initialization pipeline without interrupting the initialization flow.\n\t\tthis.on<DataControllerInitEvent>( 'init', () => {\n\t\t\tthis.fire<DataControllerReadyEvent>( 'ready' );\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Fix empty roots after DataController is 'ready' (note that the init method could be decorated and stopped).\n\t\t// We need to handle this event because initial data could be empty and the post-fixer would not get triggered.\n\t\tthis.on<DataControllerReadyEvent>( 'ready', () => {\n\t\t\tthis.model.enqueueChange( { isUndoable: false }, autoParagraphEmptyRoots );\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Returns the model's data converted by downcast dispatchers attached to {@link #downcastDispatcher} and\n\t * formatted by the {@link #processor data processor}.\n\t *\n\t * A warning is logged when you try to retrieve data for a detached root, as most probably this is a mistake. A detached root should\n\t * be treated like it is removed, and you should not save its data. Note, that the detached root data is always an empty string.\n\t *\n\t * @fires get\n\t * @param options Additional configuration for the retrieved data. `DataController` provides two optional\n\t * properties: `rootName` and `trim`. Other properties of this object are specified by various editor features.\n\t * @param options.rootName Root name. Default 'main'.\n\t * @param options.trim Whether returned data should be trimmed. This option is set to `empty` by default,\n\t * which means whenever editor content is considered empty, an empty string will be returned. To turn off trimming completely\n\t * use `'none'`. In such cases the exact content will be returned (for example a `<p>&nbsp;</p>` for an empty editor).\n\t * @returns Output data.\n\t */\n\tpublic get(\n\t\toptions: {\n\t\t\trootName?: string;\n\t\t\ttrim?: 'empty' | 'none';\n\t\t\t[ key: string ]: unknown;\n\t\t} = {}\n\t): string {\n\t\tconst { rootName = 'main', trim = 'empty' } = options;\n\n\t\tif ( !this._checkIfRootsExists( [ rootName ] ) ) {\n\t\t\t/**\n\t\t\t * Cannot get data from a non-existing root. This error is thrown when\n\t\t\t * {@link module:engine/controller/datacontroller~DataController#get `DataController#get()` method}\n\t\t\t * is called with a non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link module:engine/controller/datacontroller~DataController#get} like:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * data.get( { rootName: 'root2' } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-get-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-get-non-existent-root', this );\n\t\t}\n\n\t\tconst root = this.model.document.getRoot( rootName )!;\n\n\t\tif ( !root.isAttached() ) {\n\t\t\t/**\n\t\t\t * Retrieving document data for a detached root.\n\t\t\t *\n\t\t\t * This usually indicates an error as a detached root should be considered \"removed\" and should not be included in the\n\t\t\t * document data.\n\t\t\t *\n\t\t\t * @error datacontroller-get-detached-root\n\t\t\t */\n\t\t\tlogWarning( 'datacontroller-get-detached-root', this );\n\t\t}\n\n\t\tif ( trim === 'empty' && !this.model.hasContent( root, { ignoreWhitespaces: true } ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn this.stringify( root, options );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model's element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast converters\n\t * attached to the {@link #downcastDispatcher} and formatted by the {@link #processor data processor}.\n\t *\n\t * @param modelElementOrFragment The element whose content will be stringified.\n\t * @param options Additional configuration passed to the conversion process.\n\t * @returns Output data.\n\t */\n\tpublic stringify(\n\t\tmodelElementOrFragment: ModelElement | ModelDocumentFragment,\n\t\toptions: Record<string, unknown> = {}\n\t): string {\n\t\t// Model -> view.\n\t\tconst viewDocumentFragment = this.toView( modelElementOrFragment, options );\n\n\t\t// View -> data.\n\t\treturn this.processor.toData( viewDocumentFragment );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast\n\t * converters attached to {@link #downcastDispatcher} into a\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.\n\t *\n\t * @fires toView\n\t * @param modelElementOrFragment Element or document fragment whose content will be converted.\n\t * @param options Additional configuration that will be available through the\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi#options} during the conversion process.\n\t * @returns Output view DocumentFragment.\n\t */\n\tpublic toView(\n\t\tmodelElementOrFragment: ModelElement | ModelDocumentFragment,\n\t\toptions: Record<string, unknown> = {}\n\t): ViewDocumentFragment {\n\t\tconst viewDocument = this.viewDocument;\n\t\tconst viewWriter = this._viewWriter;\n\n\t\t// Clear bindings so the call to this method returns correct results.\n\t\tthis.mapper.clearBindings();\n\n\t\t// First, convert elements.\n\t\tconst modelRange = ModelRange._createIn( modelElementOrFragment );\n\t\tconst viewDocumentFragment = new ViewDocumentFragment( viewDocument );\n\n\t\tthis.mapper.bindElements( modelElementOrFragment, viewDocumentFragment );\n\n\t\t// Prepare list of markers.\n\t\t// For document fragment, simply take the markers assigned to this document fragment.\n\t\t// For model root, all markers in that root will be taken.\n\t\t// For model element, we need to check which markers are intersecting with this element and relatively modify the markers' ranges.\n\t\t// Collapsed markers at element boundary, although considered as not intersecting with the element, will also be returned.\n\t\tconst markers = modelElementOrFragment.is( 'documentFragment' ) ?\n\t\t\tmodelElementOrFragment.markers :\n\t\t\t_getMarkersRelativeToElement( modelElementOrFragment );\n\n\t\tthis.downcastDispatcher.convert( modelRange, markers, viewWriter, options );\n\n\t\treturn viewDocumentFragment;\n\t}\n\n\t/**\n\t * Sets the initial input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * Initial data can be only set to a document whose {@link module:engine/model/document~Document#version} is equal 0.\n\t *\n\t * **Note** This method is {@link module:utils/observablemixin~Observable#decorate decorated} which is\n\t * used by e.g. collaborative editing plugin that syncs remote data on init.\n\t *\n\t * When data is passed as a string, it is initialized on the default `main` root:\n\t *\n\t * ```ts\n\t * dataController.init( '<p>Foo</p>' ); // Initializes data on the `main` root only, as no other is specified.\n\t * ```\n\t *\n\t * To initialize data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:\n\t *\n\t * ```ts\n\t * dataController.init( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Initializes data on both the `main` and `title` roots.\n\t * ```\n\t *\n\t * @fires init\n\t * @param data Input data as a string or an object containing the `rootName` - `data`\n\t * pairs to initialize data on multiple roots at once.\n\t * @returns Promise that is resolved after the data is set on the editor.\n\t */\n\tpublic init( data: string | Record<string, string> ): Promise<void> {\n\t\tif ( this.model.document.version ) {\n\t\t\t/**\n\t\t\t * Cannot set initial data to a non-empty {@link module:engine/model/document~Document}.\n\t\t\t * Initial data should be set once, during the {@link module:core/editor/editor~Editor} initialization,\n\t\t\t * when the {@link module:engine/model/document~Document#version} is equal 0.\n\t\t\t *\n\t\t\t * @error datacontroller-init-document-not-empty\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-init-document-not-empty', this );\n\t\t}\n\n\t\tlet initialData: Record<string, string> = {};\n\n\t\tif ( typeof data === 'string' ) {\n\t\t\tinitialData.main = data; // Default root is 'main'. To initiate data on a different root, object should be passed.\n\t\t} else {\n\t\t\tinitialData = data;\n\t\t}\n\n\t\tif ( !this._checkIfRootsExists( Object.keys( initialData ) ) ) {\n\t\t\t/**\n\t\t\t * Cannot init data on a non-existent root. This error is thrown when\n\t\t\t * {@link module:engine/controller/datacontroller~DataController#init DataController#init() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link module:engine/controller/datacontroller~DataController#init} like:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * data.init( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-init-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-init-non-existent-root', this );\n\t\t}\n\n\t\tthis.model.enqueueChange( { isUndoable: false }, writer => {\n\t\t\tfor ( const rootName of Object.keys( initialData ) ) {\n\t\t\t\tconst modelRoot = this.model.document.getRoot( rootName )!;\n\n\t\t\t\twriter.insert( this.parse( initialData[ rootName ], modelRoot ), modelRoot, 0 );\n\t\t\t}\n\t\t} );\n\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Sets the input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * This method can be used any time to replace existing editor data with the new one without clearing the\n\t * {@link module:engine/model/document~Document#history document history}.\n\t *\n\t * This method also creates a batch with all the changes applied. If all you need is to parse data, use\n\t * the {@link #parse} method.\n\t *\n\t * When data is passed as a string it is set on the default `main` root:\n\t *\n\t * ```ts\n\t * dataController.set( '<p>Foo</p>' ); // Sets data on the `main` root, as no other is specified.\n\t * ```\n\t *\n\t * To set data on a different root or multiple roots at once, an object containing `rootName` - `data` pairs should be passed:\n\t *\n\t * ```ts\n\t * dataController.set( { main: '<p>Foo</p>', title: '<h1>Bar</h1>' } ); // Sets data on the `main` and `title` roots as specified.\n\t * ```\n\t *\n\t * To set the data with a preserved undo stack and add the change to the undo stack, set `{ isUndoable: true }` as a `batchType` option.\n\t *\n\t * ```ts\n\t * dataController.set( '<p>Foo</p>', { batchType: { isUndoable: true } } );\n\t * ```\n\t *\n\t * @fires set\n\t * @param data Input data as a string or an object containing the `rootName` - `data`\n\t * pairs to set data on multiple roots at once.\n\t * @param options Options for setting data.\n\t * @param options.batchType The batch type that will be used to create a batch for the changes applied by this method.\n\t * By default, the batch will be set as {@link module:engine/model/batch~Batch#isUndoable not undoable} and the undo stack will be\n\t * cleared after the new data is applied (all undo steps will be removed). If the batch type `isUndoable` flag is be set to `true`,\n\t * the undo stack will be preserved instead and not cleared when new data is applied.\n\t */\n\tpublic set(\n\t\tdata: string | Record<string, string>,\n\t\toptions: {\n\t\t\tbatchType?: BatchType;\n\t\t\t[ key: string ]: unknown;\n\t\t} = {}\n\t): void {\n\t\tlet newData: Record<string, string> = {};\n\n\t\tif ( typeof data === 'string' ) {\n\t\t\tnewData.main = data; // The default root is 'main'. To set data on a different root, an object should be passed.\n\t\t} else {\n\t\t\tnewData = data;\n\t\t}\n\n\t\tif ( !this._checkIfRootsExists( Object.keys( newData ) ) ) {\n\t\t\t/**\n\t\t\t * Cannot set data on a non-existent root. This error is thrown when the\n\t\t\t * {@link module:engine/controller/datacontroller~DataController#set DataController#set() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only the default `main` root,\n\t\t\t * calling {@link module:engine/controller/datacontroller~DataController#set} like:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * data.set( { main: '<p>Foo</p>', root2: '<p>Bar</p>' } );\n\t\t\t * ```\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-set-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-set-non-existent-root', this );\n\t\t}\n\n\t\tthis.model.enqueueChange( options.batchType || {}, writer => {\n\t\t\twriter.setSelection( null );\n\t\t\twriter.removeSelectionAttribute( this.model.document.selection.getAttributeKeys() );\n\n\t\t\tfor ( const rootName of Object.keys( newData ) ) {\n\t\t\t\t// Save to model.\n\t\t\t\tconst modelRoot = this.model.document.getRoot( rootName )!;\n\n\t\t\t\twriter.remove( writer.createRangeIn( modelRoot ) );\n\t\t\t\twriter.insert( this.parse( newData[ rootName ], modelRoot ), modelRoot, 0 );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the data parsed by the {@link #processor data processor} and then converted by upcast converters\n\t * attached to the {@link #upcastDispatcher}.\n\t *\n\t * @see #set\n\t * @param data Data to parse.\n\t * @param context Base context in which the view will be converted to the model.\n\t * See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns Parsed data.\n\t */\n\tpublic parse( data: string, context: SchemaContextDefinition = '$root' ): ModelDocumentFragment {\n\t\t// data -> view\n\t\tconst viewDocumentFragment = this.processor.toView( data );\n\n\t\t// view -> model\n\t\treturn this.toModel( viewDocumentFragment, context );\n\t}\n\n\t/**\n\t * Returns the result of the given {@link module:engine/view/element~Element view element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment} converted by the\n\t * {@link #upcastDispatcher view-to-model converters}, wrapped by {@link module:engine/model/documentfragment~DocumentFragment}.\n\t *\n\t * When marker elements were converted during the conversion process, it will be set as a document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t *\n\t * @fires toModel\n\t * @param viewElementOrFragment The element or document fragment whose content will be converted.\n\t * @param context Base context in which the view will be converted to the model.\n\t * See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns Output document fragment.\n\t */\n\tpublic toModel(\n\t\tviewElementOrFragment: ViewElement | ViewDocumentFragment,\n\t\tcontext: SchemaContextDefinition = '$root'\n\t): ModelDocumentFragment {\n\t\treturn this.model.change( writer => {\n\t\t\treturn this.upcastDispatcher.convert( viewElementOrFragment, writer, context );\n\t\t} );\n\t}\n\n\t/**\n\t * Adds the style processor normalization rules.\n\t *\n\t * You can implement your own rules as well as use one of the available processor rules:\n\t *\n\t * * background: {@link module:engine/view/styles/background~addBackgroundRules}\n\t * * border: {@link module:engine/view/styles/border~addBorderRules}\n\t * * margin: {@link module:engine/view/styles/margin~addMarginRules}\n\t * * padding: {@link module:engine/view/styles/padding~addPaddingRules}\n\t */\n\tpublic addStyleProcessorRules( callback: ( stylesProcessor: StylesProcessor ) => void ): void {\n\t\tcallback( this.stylesProcessor );\n\t}\n\n\t/**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} on an {@link #htmlProcessor htmlProcessor}\n\t * and a {@link #processor processor} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from DOM to view elements.\n\t *\n\t * The raw data can be later accessed by the {@link module:engine/view/element~Element#getCustomProperty view element custom property}\n\t * `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching all view elements whose content should be treated as a raw data.\n\t */\n\tpublic registerRawContentMatcher( pattern: MatcherPattern ): void {\n\t\t// No need to register the pattern if both the `htmlProcessor` and `processor` are the same instances.\n\t\tif ( this.processor && this.processor !== this.htmlProcessor ) {\n\t\t\tthis.processor.registerRawContentMatcher( pattern );\n\t\t}\n\n\t\tthis.htmlProcessor.registerRawContentMatcher( pattern );\n\t}\n\n\t/**\n\t * Removes all event listeners set by the DataController.\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Checks whether all provided root names are actually existing editor roots.\n\t *\n\t * @param rootNames Root names to check.\n\t * @returns Whether all provided root names are existing editor roots.\n\t */\n\tprivate _checkIfRootsExists( rootNames: Array<string> ): boolean {\n\t\tfor ( const rootName of rootNames ) {\n\t\t\tif ( !this.model.document.getRoot( rootName ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n}\n\n/**\n * Event fired once the data initialization has finished.\n *\n * @eventName ~DataController#ready\n */\nexport type DataControllerReadyEvent = {\n\tname: 'ready';\n\targs: [];\n};\n\n/**\n * An event fired after the {@link ~DataController#init `init()` method} was run. It can be {@link ~DataController#listenTo listened to} in\n * order to adjust or modify the initialization flow. However, if the `init` event is stopped or prevented,\n * the {@link ~DataController#event:ready `ready` event} should be fired manually.\n *\n * The `init` event is fired by the decorated {@link ~DataController#init} method.\n * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.\n *\n * @eventName ~DataController#init\n */\nexport type DataControllerInitEvent = {\n\tname: 'init';\n\targs: [ Parameters<DataController[ 'init' ]> ];\n\treturn: ReturnType<DataController[ 'init' ]>;\n};\n\n/**\n * An event fired after {@link ~DataController#set set() method} has been run.\n *\n * The `set` event is fired by the decorated {@link ~DataController#set} method.\n * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.\n *\n * @eventName ~DataController#set\n */\nexport type DataControllerSetEvent = {\n\tname: 'set';\n\targs: [ Parameters<DataController[ 'set' ]> ];\n\treturn: ReturnType<DataController[ 'set' ]>;\n};\n\n/**\n * Event fired after the {@link ~DataController#get get() method} has been run.\n *\n * The `get` event is fired by the decorated {@link ~DataController#get} method.\n * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.\n *\n * @eventName ~DataController#get\n */\nexport type DataControllerGetEvent = {\n\tname: 'get';\n\targs: [ Parameters<DataController[ 'get' ]> ];\n\treturn: ReturnType<DataController[ 'get' ]>;\n};\n\n/**\n * Event fired after the {@link ~DataController#toView toView() method} has been run.\n *\n * The `toView` event is fired by the decorated {@link ~DataController#toView} method.\n * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.\n *\n * @eventName ~DataController#toView\n */\nexport type DataControllerToViewEvent = {\n\tname: 'toView';\n\targs: [ Parameters<DataController[ 'toView' ]> ];\n\treturn: ReturnType<DataController[ 'toView' ]>;\n};\n\n/**\n * Event fired after the {@link ~DataController#toModel toModel() method} has been run.\n *\n * The `toModel` event is fired by the decorated {@link ~DataController#toModel} method.\n * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.\n *\n * @eventName ~DataController#toModel\n */\nexport type DataControllerToModelEvent = {\n\tname: 'toModel';\n\targs: [ Parameters<DataController[ 'toModel' ]> ];\n\treturn: ReturnType<DataController[ 'toModel' ]>;\n};\n\n/**\n * Helper function for downcast conversion.\n *\n * Takes a document element (element that is added to a model document) and checks which markers are inside it. If the marker is collapsed\n * at element boundary, it is considered as contained inside the element and marker range is returned. Otherwise, if the marker is\n * intersecting with the element, the intersection is returned.\n */\nfunction _getMarkersRelativeToElement( element: ModelElement ): Map<string, ModelRange> {\n\tconst result: Array<[ string, ModelRange ]> = [];\n\tconst doc = element.root.document;\n\n\tif ( !doc ) {\n\t\treturn new Map();\n\t}\n\n\tconst elementRange = ModelRange._createIn( element );\n\n\tfor ( const marker of doc.model.markers ) {\n\t\tconst markerRange = marker.getRange();\n\n\t\tconst isMarkerCollapsed = markerRange.isCollapsed;\n\t\tconst isMarkerAtElementBoundary = markerRange.start.isEqual( elementRange.start ) || markerRange.end.isEqual( elementRange.end );\n\n\t\tif ( isMarkerCollapsed && isMarkerAtElementBoundary ) {\n\t\t\tresult.push( [ marker.name, markerRange ] );\n\t\t} else {\n\t\t\tconst updatedMarkerRange = elementRange.getIntersection( markerRange );\n\n\t\t\tif ( updatedMarkerRange ) {\n\t\t\t\tresult.push( [ marker.name, updatedMarkerRange ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sort the markers in a stable fashion to ensure that the order in which they are\n\t// added to the model's marker collection does not affect how they are\n\t// downcast. One particular use case that we are targeting here, is one where\n\t// two markers are adjacent but not overlapping, such as an insertion/deletion\n\t// suggestion pair representing the replacement of a range of text. In this\n\t// case, putting the markers in DOM order causes the first marker's end to be\n\t// serialized right after the second marker's start, while putting the markers\n\t// in reverse DOM order causes it to be right before the second marker's\n\t// start. So, we sort these in a way that ensures non-intersecting ranges are in\n\t// reverse DOM order, and intersecting ranges are in something approximating\n\t// reverse DOM order (since reverse DOM order doesn't have a precise meaning\n\t// when working with intersecting ranges).\n\tresult.sort( ( [ n1, r1 ], [ n2, r2 ] ) => {\n\t\tif ( r1.end.compareWith( r2.start ) !== 'after' ) {\n\t\t\t// m1.end <= m2.start -- m1 is entirely <= m2\n\t\t\treturn 1;\n\t\t} else if ( r1.start.compareWith( r2.end ) !== 'before' ) {\n\t\t\t// m1.start >= m2.end -- m1 is entirely >= m2\n\t\t\treturn -1;\n\t\t} else {\n\t\t\t// they overlap, so use their start positions as the primary sort key and\n\t\t\t// end positions as the secondary sort key\n\t\t\tswitch ( r1.start.compareWith( r2.start ) ) {\n\t\t\t\tcase 'before':\n\t\t\t\t\treturn 1;\n\t\t\t\tcase 'after':\n\t\t\t\t\treturn -1;\n\t\t\t\tdefault:\n\t\t\t\t\tswitch ( r1.end.compareWith( r2.end ) ) {\n\t\t\t\t\t\tcase 'before':\n\t\t\t\t\t\t\treturn 1;\n\t\t\t\t\t\tcase 'after':\n\t\t\t\t\t\t\treturn -1;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn n2.localeCompare( n1 );\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n\n\treturn new Map( result );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/conversion/conversion\n */\n\nimport {\n\tCKEditorError,\n\ttoArray,\n\ttype ArrayOrItem,\n\ttype PriorityString\n} from '@ckeditor/ckeditor5-utils';\n\nimport UpcastHelpers from './upcasthelpers.js';\nimport DowncastHelpers, {\n\ttype AttributeCreatorFunction,\n\ttype AttributeDescriptor\n} from './downcasthelpers.js';\n\nimport type DowncastDispatcher from './downcastdispatcher.js';\nimport type UpcastDispatcher from './upcastdispatcher.js';\nimport type ElementDefinition from '../view/elementdefinition.js';\nimport type { MatcherPattern } from '../view/matcher.js';\n\n/**\n * A utility class that helps add converters to upcast and downcast dispatchers.\n *\n * We recommend reading the {@glink framework/deep-dive/conversion/intro editor conversion} guide first to\n * understand the core concepts of the conversion mechanisms.\n *\n * An instance of the conversion manager is available in the\n * {@link module:core/editor/editor~Editor#conversion `editor.conversion`} property\n * and by default has the following groups of dispatchers (i.e. directions of conversion):\n *\n * * `downcast` (editing and data downcasts)\n * * `editingDowncast`\n * * `dataDowncast`\n * * `upcast`\n *\n * # One-way converters\n *\n * To add a converter to a specific group, use the {@link module:engine/conversion/conversion~Conversion#for `for()`}\n * method:\n *\n * ```ts\n * // Add a converter to editing downcast and data downcast.\n * editor.conversion.for( 'downcast' ).elementToElement( config ) );\n *\n * // Add a converter to the data pipepline only:\n * editor.conversion.for( 'dataDowncast' ).elementToElement( dataConversionConfig ) );\n *\n * // And a slightly different one for the editing pipeline:\n * editor.conversion.for( 'editingDowncast' ).elementToElement( editingConversionConfig ) );\n * ```\n *\n * See {@link module:engine/conversion/conversion~Conversion#for `for()`} method documentation to learn more about\n * available conversion helpers and how to use your custom ones.\n *\n * # Two-way converters\n *\n * Besides using one-way converters via the `for()` method, you can also use other methods available in this\n * class to add two-way converters (upcast and downcast):\n *\n * * {@link module:engine/conversion/conversion~Conversion#elementToElement `elementToElement()`} &ndash;\n * Model element to view element and vice versa.\n * * {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement()`} &ndash;\n * Model attribute to view element and vice versa.\n * * {@link module:engine/conversion/conversion~Conversion#attributeToAttribute `attributeToAttribute()`} &ndash;\n * Model attribute to view attribute and vice versa.\n */\nexport default class Conversion {\n\t/**\n\t * Maps dispatchers group name to ConversionHelpers instances.\n\t */\n\tprivate readonly _helpers = new Map<string, DowncastHelpers | UpcastHelpers>();\n\n\tprivate readonly _downcast: Array<DowncastDispatcher>;\n\tprivate readonly _upcast: Array<UpcastDispatcher>;\n\n\t/**\n\t * Creates a new conversion instance.\n\t */\n\tconstructor(\n\t\tdowncastDispatchers: ArrayOrItem<DowncastDispatcher>,\n\t\tupcastDispatchers: ArrayOrItem<UpcastDispatcher>\n\t) {\n\t\t// Define default 'downcast' & 'upcast' dispatchers groups. Those groups are always available as two-way converters needs them.\n\t\tthis._downcast = toArray( downcastDispatchers );\n\t\tthis._createConversionHelpers( { name: 'downcast', dispatchers: this._downcast, isDowncast: true } );\n\n\t\tthis._upcast = toArray( upcastDispatchers );\n\t\tthis._createConversionHelpers( { name: 'upcast', dispatchers: this._upcast, isDowncast: false } );\n\t}\n\n\tpublic addAlias(\n\t\talias: `${ string }Downcast`,\n\t\tdispatcher: DowncastDispatcher\n\t): void;\n\tpublic addAlias(\n\t\talias: `${ string }Upcast`,\n\t\tdispatcher: UpcastDispatcher\n\t): void;\n\tpublic addAlias(\n\t\talias: string,\n\t\tdispatcher: DowncastDispatcher | UpcastDispatcher\n\t): void;\n\n\t/**\n\t * Define an alias for registered dispatcher.\n\t *\n\t * ```ts\n\t * const conversion = new Conversion(\n\t * \t[ dataDowncastDispatcher, editingDowncastDispatcher ],\n\t * \tupcastDispatcher\n\t * );\n\t *\n\t * conversion.addAlias( 'dataDowncast', dataDowncastDispatcher );\n\t * ```\n\t *\n\t * @param alias An alias of a dispatcher.\n\t * @param dispatcher Dispatcher which should have an alias.\n\t */\n\tpublic addAlias(\n\t\talias: string,\n\t\tdispatcher: DowncastDispatcher | UpcastDispatcher\n\t): void {\n\t\tconst isDowncast = this._downcast.includes( dispatcher as any );\n\t\tconst isUpcast = this._upcast.includes( dispatcher as any );\n\n\t\tif ( !isUpcast && !isDowncast ) {\n\t\t\t/**\n\t\t\t * Trying to register an alias for a dispatcher that nas not been registered.\n\t\t\t *\n\t\t\t * @error conversion-add-alias-dispatcher-not-registered\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'conversion-add-alias-dispatcher-not-registered',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tthis._createConversionHelpers( { name: alias, dispatchers: [ dispatcher ], isDowncast } );\n\t}\n\n\tpublic for( groupName: 'downcast' | 'dataDowncast' | 'editingDowncast' ): DowncastHelpers;\n\tpublic for( groupName: 'upcast' ): UpcastHelpers;\n\tpublic for<T extends string>( groupName: T ): ConversionType<T>;\n\n\t/**\n\t * Provides a chainable API to assign converters to a conversion dispatchers group.\n\t *\n\t * If the given group name has not been registered, the\n\t * {@link module:utils/ckeditorerror~CKEditorError `conversion-for-unknown-group` error} is thrown.\n\t *\n\t * You can use conversion helpers available directly in the `for()` chain or your custom ones via\n\t * the {@link module:engine/conversion/conversionhelpers~ConversionHelpers#add `add()`} method.\n\t *\n\t * # Using built-in conversion helpers\n\t *\n\t * The `for()` chain comes with a set of conversion helpers which you can use like this:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'downcast' )\n\t * \t.elementToElement( config1 )        // Adds an element-to-element downcast converter.\n\t * \t.attributeToElement( config2 );     // Adds an attribute-to-element downcast converter.\n\t *\n\t * editor.conversion.for( 'upcast' )\n\t * \t.elementToAttribute( config3 );     // Adds an element-to-attribute upcast converter.\n\t * ```\n\t *\n\t * Refer to the documentation of built-in conversion helpers to learn about their configuration options.\n\t *\n\t * * downcast (model-to-view) conversion helpers:\n\t *\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`},\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement `attributeToElement()`},\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToElement `markerToElement()`}.\n\t *\t* {@link module:engine/conversion/downcasthelpers~DowncastHelpers#markerToHighlight `markerToHighlight()`}.\n\t *\n\t * * upcast (view-to-model) conversion helpers:\n\t *\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToElement `elementToElement()`},\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToAttribute `elementToAttribute()`},\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#attributeToAttribute `attributeToAttribute()`}.\n\t *\t* {@link module:engine/conversion/upcasthelpers~UpcastHelpers#elementToMarker `elementToMarker()`}.\n\t *\n\t * # Using custom conversion helpers\n\t *\n\t * If you need to implement an atypical converter, you can do so by calling:\n\t *\n\t * ```ts\n\t * editor.conversion.for( direction ).add( customHelper );\n\t * ```\n\t *\n\t * The `.add()` method takes exactly one parameter, which is a function. This function should accept one parameter that\n\t * is a dispatcher instance. The function should add an actual converter to the passed dispatcher instance.\n\t *\n\t * Example:\n\t *\n\t * ```ts\n\t * editor.conversion.for( 'upcast' ).add( dispatcher => {\n\t * \tdispatcher.on( 'element:a',  ( evt, data, conversionApi ) => {\n\t * \t\t// Do something with a view <a> element.\n\t * \t} );\n\t * } );\n\t * ```\n\t *\n\t * Refer to the documentation of {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher}\n\t * and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} to learn how to write\n\t * custom converters.\n\t *\n\t * @param groupName The name of dispatchers group to add the converters to.\n\t */\n\tpublic for( groupName: string ): DowncastHelpers | UpcastHelpers {\n\t\tif ( !this._helpers.has( groupName ) ) {\n\t\t\t/**\n\t\t\t * Trying to add a converter to an unknown dispatchers group.\n\t\t\t *\n\t\t\t * @error conversion-for-unknown-group\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-for-unknown-group', this );\n\t\t}\n\n\t\treturn this._helpers.get( groupName )!;\n\t}\n\n\t/**\n\t * Sets up converters between the model and the view that convert a model element to a view element (and vice versa).\n\t * For example, the model `<paragraph>Foo</paragraph>` is turned into `<p>Foo</p>` in the view.\n\t *\n\t * ```ts\n\t * // A simple conversion from the `paragraph` model element to the `<p>` view element (and vice versa).\n\t * editor.conversion.elementToElement( { model: 'paragraph', view: 'p' } );\n\t *\n\t * // Override other converters by specifying a converter definition with a higher priority.\n\t * editor.conversion.elementToElement( { model: 'paragraph', view: 'div', converterPriority: 'high' } );\n\t *\n\t * // View specified as an object instead of a string.\n\t * editor.conversion.elementToElement( {\n\t * \tmodel: 'fancyParagraph',\n\t * \tview: {\n\t * \t\tname: 'p',\n\t * \t\tclasses: 'fancy'\n\t * \t}\n\t * } );\n\t *\n\t * // Use `upcastAlso` to define other view elements that should also be converted to a `paragraph` element.\n\t * editor.conversion.elementToElement( {\n\t * \tmodel: 'paragraph',\n\t * \tview: 'p',\n\t * \tupcastAlso: [\n\t * \t\t'div',\n\t * \t\t{\n\t * \t\t\t// Any element with the `display: block` style.\n\t * \t\t\tstyles: {\n\t * \t\t\t\tdisplay: 'block'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t]\n\t * } );\n\t *\n\t * // `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t * editor.conversion.elementToElement( {\n\t * \tmodel: 'heading',\n\t * \tview: 'h2',\n\t * \t// Convert \"heading-like\" paragraphs to headings.\n\t * \tupcastAlso: viewElement => {\n\t * \t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t * \t\tif ( !fontSize ) {\n\t * \t\t\treturn null;\n\t * \t\t}\n\t *\n\t * \t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t * \t\tif ( !match ) {\n\t * \t\t\treturn null;\n\t * \t\t}\n\t *\n\t * \t\tconst size = Number( match[ 1 ] );\n\t *\n\t * \t\tif ( size > 26 ) {\n\t * \t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t * \t\t}\n\t *\n\t * \t\treturn null;\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * `definition.model` is a `String` with a model element name to convert from or to.\n\t *\n\t * @param definition The converter definition.\n\t */\n\tpublic elementToElement( definition: {\n\t\tmodel: string;\n\t\tview: ElementDefinition;\n\t\tupcastAlso?: ArrayOrItem<ElementDefinition | MatcherPattern>;\n\t\tconverterPriority?: PriorityString;\n\t} ): void {\n\t\t// Set up downcast converter.\n\t\tthis.for( 'downcast' ).elementToElement( definition );\n\n\t\t// Set up upcast converter.\n\t\tfor ( const { model, view } of _getAllUpcastDefinitions( definition ) ) {\n\t\t\tthis.for( 'upcast' )\n\t\t\t\t.elementToElement( {\n\t\t\t\t\tmodel,\n\t\t\t\t\tview,\n\t\t\t\t\tconverterPriority: definition.converterPriority\n\t\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Sets up converters between the model and the view that convert a model attribute to a view element (and vice versa).\n\t * For example, a model text node with `\"Foo\"` as data and the `bold` attribute will be turned to `<strong>Foo</strong>` in the view.\n\t *\n\t * ```ts\n\t * // A simple conversion from the `bold=true` attribute to the `<strong>` view element (and vice versa).\n\t * editor.conversion.attributeToElement( { model: 'bold', view: 'strong' } );\n\t *\n\t * // Override other converters by specifying a converter definition with a higher priority.\n\t * editor.conversion.attributeToElement( { model: 'bold', view: 'b', converterPriority: 'high' } );\n\t *\n\t * // View specified as an object instead of a string.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: {\n\t * \t\tname: 'span',\n\t * \t\tclasses: 'bold'\n\t * \t}\n\t * } );\n\t *\n\t * // Use `config.model.name` to define the conversion only from a given node type, `$text` in this case.\n\t * // The same attribute on different elements may then be handled by a different converter.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'textDecoration',\n\t * \t\tvalues: [ 'underline', 'lineThrough' ],\n\t * \t\tname: '$text'\n\t * \t},\n\t * \tview: {\n\t * \t\tunderline: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-decoration': 'underline'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tlineThrough: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-decoration': 'line-through'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * // Use `upcastAlso` to define other view elements that should also be converted to the `bold` attribute.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: 'bold',\n\t * \tview: 'strong',\n\t * \tupcastAlso: [\n\t * \t\t'b',\n\t * \t\t{\n\t * \t\t\tname: 'span',\n\t * \t\t\tclasses: 'bold'\n\t * \t\t},\n\t * \t\t{\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-weight': 'bold'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tviewElement => {\n\t * \t\t\tconst fontWeight = viewElement.getStyle( 'font-weight' );\n\t *\n\t * \t\t\tif ( viewElement.is( 'element', 'span' ) && fontWeight && /\\d+/.test() && Number( fontWeight ) > 500 ) {\n\t * \t\t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\t\treturn {\n\t * \t\t\t\t\tname: true,\n\t * \t\t\t\t\tstyles: [ 'font-weight' ]\n\t * \t\t\t\t};\n\t * \t\t\t}\n\t * \t\t}\n\t * \t]\n\t * } );\n\t *\n\t * // Conversion from and to a model attribute key whose value is an enum (`fontSize=big|small`).\n\t * // `upcastAlso` set as callback enables a conversion of a wide range of different view elements.\n\t * editor.conversion.attributeToElement( {\n\t * \tmodel: {\n\t * \t\tkey: 'fontSize',\n\t * \t\tvalues: [ 'big', 'small' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tbig: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '1.2em'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tsmall: {\n\t * \t\t\tname: 'span',\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'font-size': '0.8em'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t},\n\t * \tupcastAlso: {\n\t * \t\tbig: viewElement => {\n\t * \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t * \t\t\tif ( !fontSize ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t * \t\t\tif ( !match ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst size = Number( match[ 1 ] );\n\t *\n\t * \t\t\tif ( viewElement.is( 'element', 'span' ) && size > 10 ) {\n\t * \t\t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t * \t\t\t}\n\t *\n\t * \t\t\treturn null;\n\t * \t\t},\n\t * \t\tsmall: viewElement => {\n\t * \t\t\tconst fontSize = viewElement.getStyle( 'font-size' );\n\t *\n\t * \t\t\tif ( !fontSize ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst match = fontSize.match( /(\\d+)\\s*px/ );\n\t *\n\t * \t\t\tif ( !match ) {\n\t * \t\t\t\treturn null;\n\t * \t\t\t}\n\t *\n\t * \t\t\tconst size = Number( match[ 1 ] );\n\t *\n\t * \t\t\tif ( viewElement.is( 'element', 'span' ) && size < 10 ) {\n\t * \t\t\t\t// Returned value can be an object with the matched properties.\n\t * \t\t\t\t// These properties will be \"consumed\" during the conversion.\n\t * \t\t\t\t// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.\n\t *\n\t * \t\t\t\treturn { name: true, styles: [ 'font-size' ] };\n\t * \t\t\t}\n\t *\n\t * \t\t\treturn null;\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * The `definition.model` parameter specifies which model attribute should be converted from or to. It can be a `{ key, value }` object\n\t * describing the attribute key and value to convert or a `String` specifying just the attribute key (in such a case\n\t * `value` is set to `true`).\n\t *\n\t * @param definition The converter definition.\n\t */\n\tpublic attributeToElement<TValues extends string>(\n\t\tdefinition: {\n\t\t\tmodel: string | {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t};\n\t\t\tview: ElementDefinition;\n\t\t\tupcastAlso?: ArrayOrItem<MatcherPattern>;\n\t\t\tconverterPriority?: PriorityString;\n\t\t} | {\n\t\t\tmodel: {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t\tvalues: Array<TValues>;\n\t\t\t};\n\t\t\tview: Record<TValues, ElementDefinition>;\n\t\t\tupcastAlso?: Record<TValues, ArrayOrItem<MatcherPattern>>;\n\t\t\tconverterPriority?: PriorityString;\n\t\t}\n\t): void {\n\t\t// Set up downcast converter.\n\t\tthis.for( 'downcast' ).attributeToElement( definition );\n\n\t\t// Set up upcast converter.\n\t\tfor ( const { model, view } of _getAllUpcastDefinitions( definition ) ) {\n\t\t\tthis.for( 'upcast' )\n\t\t\t\t.elementToAttribute( {\n\t\t\t\t\tview,\n\t\t\t\t\tmodel,\n\t\t\t\t\tconverterPriority: definition.converterPriority\n\t\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Sets up converters between the model and the view that convert a model attribute to a view attribute (and vice versa). For example,\n\t * `<imageBlock src='foo.jpg'></imageBlock>` is converted to `<img src='foo.jpg'></img>` (the same attribute key and value).\n\t * This type of converters is intended to be used with {@link module:engine/model/element~Element model element} nodes.\n\t * To convert the text attributes,\n\t * the {@link module:engine/conversion/conversion~Conversion#attributeToElement `attributeToElement converter`}should be set up.\n\t *\n\t * ```ts\n\t * // A simple conversion from the `source` model attribute to the `src` view attribute (and vice versa).\n\t * editor.conversion.attributeToAttribute( { model: 'source', view: 'src' } );\n\t *\n\t * // Attribute values are strictly specified.\n\t * editor.conversion.attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'imageInline',\n\t * \t\tkey: 'aside',\n\t * \t\tvalues: [ 'aside' ]\n\t * \t},\n\t * \tview: {\n\t * \t\taside: {\n\t * \t\t\tname: 'img',\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: [ 'aside', 'half-size' ]\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * // Set the style attribute.\n\t * editor.conversion.attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tname: 'imageInline',\n\t * \t\tkey: 'aside',\n\t * \t\tvalues: [ 'aside' ]\n\t * \t},\n\t * \tview: {\n\t * \t\taside: {\n\t * \t\t\tname: 'img',\n\t * \t\t\tkey: 'style',\n\t * \t\t\tvalue: {\n\t * \t\t\t\tfloat: 'right',\n\t * \t\t\t\twidth: '50%',\n\t * \t\t\t\tmargin: '5px'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t *\n\t * // Conversion from and to a model attribute key whose value is an enum (`align=right|center`).\n\t * // Use `upcastAlso` to define other view elements that should also be converted to the `align=right` attribute.\n\t * editor.conversion.attributeToAttribute( {\n\t * \tmodel: {\n\t * \t\tkey: 'align',\n\t * \t\tvalues: [ 'right', 'center' ]\n\t * \t},\n\t * \tview: {\n\t * \t\tright: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: 'align-right'\n\t * \t\t},\n\t * \t\tcenter: {\n\t * \t\t\tkey: 'class',\n\t * \t\t\tvalue: 'align-center'\n\t * \t\t}\n\t * \t},\n\t * \tupcastAlso: {\n\t * \t\tright: {\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-align': 'right'\n\t * \t\t\t}\n\t * \t\t},\n\t * \t\tcenter: {\n\t * \t\t\tstyles: {\n\t * \t\t\t\t'text-align': 'center'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * The `definition.model` parameter specifies which model attribute should be converted from and to.\n\t * It can be a `{ key, [ values ], [ name ] }` object or a `String`, which will be treated like `{ key: definition.model }`.\n\t * The `key` property is the model attribute key to convert from and to.\n\t * The `values` are the possible model attribute values. If the `values` parameter is not set, the model attribute value\n\t * will be the same as the view attribute value.\n\t * If `name` is set, the conversion will be set up only for model elements with the given name.\n\t *\n\t * The `definition.view` parameter specifies which view attribute should be converted from and to.\n\t * It can be a `{ key, value, [ name ] }` object or a `String`, which will be treated like `{ key: definition.view }`.\n\t * The `key` property is the view attribute key to convert from and to.\n\t * The `value` is the view attribute value to convert from and to. If `definition.value` is not set, the view attribute value will be\n\t * the same as the model attribute value.\n\t * If `key` is `'class'`, `value` can be a `String` or an array of `String`s.\n\t * If `key` is `'style'`, `value` is an object with key-value pairs.\n\t * In other cases, `value` is a `String`.\n\t * If `name` is set, the conversion will be set up only for model elements with the given name.\n\t * If `definition.model.values` is set, `definition.view` is an object that assigns values from `definition.model.values`\n\t * to `{ key, value, [ name ] }` objects.\n\t *\n\t * `definition.upcastAlso` specifies which other matching view elements should also be upcast to the given model configuration.\n\t * If `definition.model.values` is set, `definition.upcastAlso` should be an object assigning values from `definition.model.values`\n\t * to {@link module:engine/view/matcher~MatcherPattern}s or arrays of {@link module:engine/view/matcher~MatcherPattern}s.\n\t *\n\t * **Note:** `definition.model` and `definition.view` form should be mirrored, so the same types of parameters should\n\t * be given in both parameters.\n\t *\n\t * @param definition The converter definition.\n\t * @param definition.model The model attribute to convert from and to.\n\t * @param definition.view The view attribute to convert from and to.\n\t * @param definition.upcastAlso Any view element matching `definition.upcastAlso` will also be converted to the given model attribute.\n\t * `definition.upcastAlso` is used only if `config.model.values` is specified.\n\t */\n\tpublic attributeToAttribute<TValues extends string>(\n\t\tdefinition: {\n\t\t\tmodel: string | {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t};\n\t\t\tview: string | ( AttributeDescriptor & { name?: string } );\n\t\t\tupcastAlso?: ArrayOrItem<string | ( AttributeDescriptor & { name?: string } ) | AttributeCreatorFunction>;\n\t\t\tconverterPriority?: PriorityString;\n\t\t} | {\n\t\t\tmodel: {\n\t\t\t\tkey: string;\n\t\t\t\tname?: string;\n\t\t\t\tvalues: Array<TValues>;\n\t\t\t};\n\t\t\tview: Record<TValues, ( AttributeDescriptor & { name?: string } )>;\n\t\t\tupcastAlso?: Record<TValues, ( AttributeDescriptor & { name?: string } ) | AttributeCreatorFunction>;\n\t\t\tconverterPriority?: PriorityString;\n\t\t} ): void {\n\t\t// Set up downcast converter.\n\t\tthis.for( 'downcast' ).attributeToAttribute( definition );\n\n\t\t// Set up upcast converter.\n\t\tfor ( const { model, view } of _getAllUpcastDefinitions( definition ) ) {\n\t\t\tthis.for( 'upcast' )\n\t\t\t\t.attributeToAttribute( {\n\t\t\t\t\tview,\n\t\t\t\t\tmodel\n\t\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Creates and caches conversion helpers for given dispatchers group.\n\t *\n\t * @param options.name Group name.\n\t */\n\tprivate _createConversionHelpers(\n\t\t{ name, dispatchers, isDowncast }: {\n\t\t\tname: string;\n\t\t\tdispatchers: Array<DowncastDispatcher | UpcastDispatcher>;\n\t\t\tisDowncast: boolean;\n\t\t}\n\t): void {\n\t\tif ( this._helpers.has( name ) ) {\n\t\t\t/**\n\t\t\t * Trying to register a group name that has already been registered.\n\t\t\t *\n\t\t\t * @error conversion-group-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'conversion-group-exists', this );\n\t\t}\n\n\t\tconst helpers = isDowncast ?\n\t\t\tnew DowncastHelpers( dispatchers as Array<DowncastDispatcher> ) :\n\t\t\tnew UpcastHelpers( dispatchers as Array<UpcastDispatcher> );\n\n\t\tthis._helpers.set( name, helpers );\n\t}\n}\n\n/**\n * Helper function that creates a joint array out of an item passed in `definition.view` and items passed in\n * `definition.upcastAlso`.\n */\nfunction* _getAllUpcastDefinitions( definition: any ): IterableIterator<{ model: any; view: any }> {\n\tif ( definition.model.values ) {\n\t\tfor ( const value of definition.model.values ) {\n\t\t\tconst model = { key: definition.model.key, value };\n\t\t\tconst view = definition.view[ value ];\n\t\t\tconst upcastAlso = definition.upcastAlso ? definition.upcastAlso[ value ] : undefined;\n\n\t\t\tyield* _getUpcastDefinition( model, view, upcastAlso );\n\t\t}\n\t} else {\n\t\tyield* _getUpcastDefinition( definition.model, definition.view, definition.upcastAlso );\n\t}\n}\n\nfunction* _getUpcastDefinition( model: unknown, view: unknown, upcastAlso?: unknown ): any {\n\tyield { model, view };\n\n\tif ( upcastAlso ) {\n\t\tfor ( const upcastAlsoItem of toArray( upcastAlso ) ) {\n\t\t\tyield { model, view: upcastAlsoItem };\n\t\t}\n\t}\n}\n\ntype ConversionType<T extends string> = T extends `${ string }Downcast`\n\t? DowncastHelpers\n\t: T extends `${ string }Upcast`\n\t\t? UpcastHelpers\n\t\t: DowncastHelpers | UpcastHelpers;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/dataprocessor/xmldataprocessor\n */\n\n/* globals DOMParser */\n\nimport BasicHtmlWriter from './basichtmlwriter.js';\nimport DomConverter from '../view/domconverter.js';\n\nimport type DataProcessor from './dataprocessor.js';\nimport type HtmlWriter from './htmlwriter.js';\nimport type ViewDocument from '../view/document.js';\nimport type ViewDocumentFragment from '../view/documentfragment.js';\nimport type { MatcherPattern } from '../view/matcher.js';\n\n/**\n * The XML data processor class.\n * This data processor implementation uses XML as input and output data.\n * This class is needed because unlike HTML, XML allows to use any tag with any value.\n * For example, `<link>Text</link>` is a valid XML but invalid HTML.\n */\nexport default class XmlDataProcessor implements DataProcessor {\n\t/**\n\t * A list of namespaces allowed to use in the XML input.\n\t *\n\t * For example, registering namespaces [ 'attribute', 'container' ] allows to use `<attirbute:tagName></attribute:tagName>`\n\t * and `<container:tagName></container:tagName>` input. It is mainly for debugging.\n\t */\n\tpublic namespaces: Array<string>;\n\n\t/**\n\t * DOM parser instance used to parse an XML string to an XML document.\n\t */\n\tpublic domParser: DOMParser;\n\n\t/**\n\t * DOM converter used to convert DOM elements to view elements.\n\t */\n\tpublic domConverter: DomConverter;\n\n\t/**\n\t * A basic HTML writer instance used to convert DOM elements to an XML string.\n\t * There is no need to use a dedicated XML writer because the basic HTML writer works well in this case.\n\t */\n\tpublic htmlWriter: HtmlWriter;\n\n\tpublic skipComments: boolean = true;\n\n\t/**\n\t * Creates a new instance of the XML data processor class.\n\t *\n\t * @param document The view document instance.\n\t * @param options Configuration options.\n\t * @param options.namespaces A list of namespaces allowed to use in the XML input.\n\t */\n\tconstructor( document: ViewDocument, options: { namespaces?: Array<string> } = {} ) {\n\t\tthis.namespaces = options.namespaces || [];\n\t\tthis.domParser = new DOMParser();\n\t\tthis.domConverter = new DomConverter( document, { renderingMode: 'data' } );\n\t\tthis.htmlWriter = new BasicHtmlWriter();\n\t}\n\n\t/**\n\t * Converts the provided {@link module:engine/view/documentfragment~DocumentFragment document fragment}\n\t * to data format &ndash; in this case an XML string.\n\t *\n\t * @returns An XML string.\n\t */\n\tpublic toData( viewFragment: ViewDocumentFragment ): string {\n\t\t// Convert view DocumentFragment to DOM DocumentFragment.\n\t\tconst domFragment = this.domConverter.viewToDom( viewFragment );\n\n\t\t// Convert DOM DocumentFragment to XML output.\n\t\t// There is no need to use dedicated for XML serializing method because BasicHtmlWriter works well in this case.\n\t\treturn this.htmlWriter.getHtml( domFragment );\n\t}\n\n\t/**\n\t * Converts the provided XML string to a view tree.\n\t *\n\t * @param data An XML string.\n\t * @returns A converted view element.\n\t */\n\tpublic toView( data: string ): ViewDocumentFragment {\n\t\t// Convert input XML data to DOM DocumentFragment.\n\t\tconst domFragment = this._toDom( data );\n\n\t\t// Convert DOM DocumentFragment to view DocumentFragment.\n\t\treturn this.domConverter.domToView(\n\t\t\tdomFragment,\n\t\t\t{\n\t\t\t\tkeepOriginalCase: true,\n\t\t\t\tskipComments: this.skipComments\n\t\t\t}\n\t\t) as ViewDocumentFragment;\n\t}\n\n\t/**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from XML to view elements.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern Pattern matching all view elements whose content should be treated as raw data.\n\t */\n\tpublic registerRawContentMatcher( pattern: MatcherPattern ): void {\n\t\tthis.domConverter.registerRawContentMatcher( pattern );\n\t}\n\n\t/**\n\t * If the processor is set to use marked fillers, it will insert `&nbsp;` fillers wrapped in `<span>` elements\n\t * (`<span data-cke-filler=\"true\">&nbsp;</span>`) instead of regular `&nbsp;` characters.\n\t *\n\t * This mode allows for a more precise handling of block fillers (so they do not leak into editor content) but\n\t * bloats the editor data with additional markup.\n\t *\n\t * This mode may be required by some features and will be turned on by them automatically.\n\t *\n\t * @param type Whether to use the default or the marked `&nbsp;` block fillers.\n\t */\n\tpublic useFillerType( type: 'default' | 'marked' ): void {\n\t\tthis.domConverter.blockFillerMode = type == 'marked' ? 'markedNbsp' : 'nbsp';\n\t}\n\n\t/**\n\t * Converts an XML string to its DOM representation. Returns a document fragment containing nodes parsed from\n\t * the provided data.\n\t */\n\tprivate _toDom( data: string ): DocumentFragment {\n\t\t// Stringify namespaces.\n\t\tconst namespaces = this.namespaces.map( nsp => `xmlns:${ nsp }=\"nsp\"` ).join( ' ' );\n\n\t\t// Wrap data into root element with optional namespace definitions.\n\t\tdata = `<xml ${ namespaces }>${ data }</xml>`;\n\n\t\tconst parsedDocument = this.domParser.parseFromString( data, 'text/xml' );\n\n\t\t// Parse validation.\n\t\tconst parserError = parsedDocument.querySelector( 'parsererror' );\n\n\t\tif ( parserError ) {\n\t\t\tthrow new Error( 'Parse error - ' + parserError.textContent );\n\t\t}\n\n\t\tconst fragment = parsedDocument.createDocumentFragment();\n\t\tconst nodes = parsedDocument.documentElement.childNodes;\n\n\t\twhile ( nodes.length > 0 ) {\n\t\t\tfragment.appendChild( nodes[ 0 ] );\n\t\t}\n\n\t\treturn fragment;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/**\n * @module engine/model/operation/operation\n */\n\nimport type Batch from '../batch.js';\nimport type Document from '../document.js';\nimport type { Selectable } from '../selection.js';\n\n/**\n * Abstract base operation class.\n */\nexport default abstract class Operation {\n\t/**\n\t * {@link module:engine/model/document~Document#version} on which operation can be applied. If you try to\n\t * {@link module:engine/model/model~Model#applyOperation apply} operation with different base version than the\n\t * {@link module:engine/model/document~Document#version document version} the\n\t * {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.\n\t */\n\tpublic baseVersion: number | null;\n\n\t/**\n\t * Defines whether operation is executed on attached or detached {@link module:engine/model/item~Item items}.\n\t */\n\tpublic readonly isDocumentOperation: boolean;\n\n\t/**\n\t * {@link module:engine/model/batch~Batch Batch} to which the operation is added or `null` if the operation is not\n\t * added to any batch yet.\n\t */\n\tpublic batch: Batch | null;\n\n\t/**\n\t * Operation type.\n\t */\n\tpublic readonly abstract type: string;\n\n\t/**\n\t * Base operation constructor.\n\t *\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( baseVersion: number | null ) {\n\t\tthis.baseVersion = baseVersion;\n\t\tthis.isDocumentOperation = this.baseVersion !== null;\n\t\tthis.batch = null;\n\t}\n\n\t/**\n\t * A selectable that will be affected by the operation after it is executed.\n\t *\n\t * The exact returned parameter differs between operation types.\n\t */\n\tpublic abstract get affectedSelectable(): Selectable;\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns Clone of this operation.\n\t */\n\tpublic abstract clone(): Operation;\n\n\t/**\n\t * Creates and returns a reverse operation. Reverse operation when executed right after\n\t * the original operation will bring back tree model state to the point before the original\n\t * operation execution. In other words, it reverses changes done by the original operation.\n\t *\n\t * Keep in mind that tree model state may change since executing the original operation,\n\t * so reverse operation will be \"outdated\". In that case you will need to transform it by\n\t * all operations that were executed after the original operation.\n\t *\n\t * @returns Reversed operation.\n\t */\n\tpublic abstract getReversed(): Operation;\n\n\t/**\n\t * Executes the operation - modifications described by the operation properties will be applied to the model tree.\n\t *\n\t * @internal\n\t */\n\tpublic abstract _execute(): void;\n\n\t/**\n\t * Checks whether the operation's parameters are correct and the operation can be correctly executed. Throws\n\t * an error if operation is not valid.\n\t *\n\t * @internal\n\t */\n\tpublic _validate(): void {\n\t}\n\n\t/**\n\t * Custom toJSON method to solve child-parent circular dependencies.\n\t *\n\t * @returns Clone of this object with the operation property replaced with string.\n\t */\n\tpublic toJSON(): unknown {\n\t\t// This method creates only a shallow copy, all nested objects should be defined separately.\n\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1477.\n\t\tconst json: any = Object.assign( {}, this );\n\n\t\tjson.__className = ( this.constructor as any ).className;\n\n\t\t// Remove reference to the parent `Batch` to avoid circular dependencies.\n\t\tdelete json.batch;\n\n\t\t// Only document operations are shared with other clients so it is not necessary to keep this information.\n\t\tdelete json.isDocumentOperation;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Name of the operation class used for serialization.\n\t */\n\tpublic static get className(): string {\n\t\treturn 'Operation';\n\t}\n\n\t/**\n\t * Creates `Operation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param doc Document on which this operation will be applied.\n\t */\n\tpublic static fromJSON( json: any, document: Document ): Operation {\n\t\treturn new ( this as any )( json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // log() {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( this.toString() );\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/utils\n */\n\nimport Node from '../node.js';\nimport Range from '../range.js';\nimport Text from '../text.js';\nimport TextProxy from '../textproxy.js';\n\nimport type DocumentFragment from '../documentfragment.js';\nimport type Element from '../element.js';\nimport type Item from '../item.js';\nimport type NodeList from '../nodelist.js';\nimport type Position from '../position.js';\n\nimport { CKEditorError, isIterable } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Inserts given nodes at given position.\n *\n * @internal\n * @param position Position at which nodes should be inserted.\n * @param normalizedNodes Nodes to insert.\n * @returns Range spanning over inserted elements.\n */\nexport function _insert( position: Position, nodes: NodeSet ): Range {\n\tconst normalizedNodes = _normalizeNodes( nodes );\n\n\t// We have to count offset before inserting nodes because they can get merged and we would get wrong offsets.\n\tconst offset = normalizedNodes.reduce( ( sum, node ) => sum + node.offsetSize, 0 );\n\tconst parent = position.parent;\n\n\t// Insertion might be in a text node, we should split it if that's the case.\n\t_splitNodeAtPosition( position );\n\tconst index = position.index;\n\n\t// Insert nodes at given index. After splitting we have a proper index and insertion is between nodes,\n\t// using basic `Element` API.\n\tparent._insertChild( index, normalizedNodes );\n\n\t// Merge text nodes, if possible. Merging is needed only at points where inserted nodes \"touch\" \"old\" nodes.\n\t_mergeNodesAtIndex( parent, index + normalizedNodes.length );\n\t_mergeNodesAtIndex( parent, index );\n\n\treturn new Range( position, position.getShiftedBy( offset ) );\n}\n\n/**\n * Removed nodes in given range. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @internal\n * @param range Range containing nodes to remove.\n */\nexport function _remove( this: any, range: Range ): Array<Node> {\n\tif ( !range.isFlat ) {\n\t\t/**\n\t\t * Trying to remove a range which starts and ends in different element.\n\t\t *\n\t\t * @error operation-utils-remove-range-not-flat\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'operation-utils-remove-range-not-flat',\n\t\t\tthis\n\t\t);\n\t}\n\n\tconst parent = range.start.parent;\n\n\t// Range may be inside text nodes, we have to split them if that's the case.\n\t_splitNodeAtPosition( range.start );\n\t_splitNodeAtPosition( range.end );\n\n\t// Remove the text nodes using basic `Element` API.\n\tconst removed = parent._removeChildren( range.start.index, range.end.index - range.start.index );\n\n\t// Merge text nodes, if possible. After some nodes were removed, node before and after removed range will be\n\t// touching at the position equal to the removed range beginning. We check merging possibility there.\n\t_mergeNodesAtIndex( parent, range.start.index );\n\n\treturn removed;\n}\n\n/**\n * Moves nodes in given range to given target position. Only {@link module:engine/model/range~Range#isFlat flat} ranges are accepted.\n *\n * @internal\n * @param sourceRange Range containing nodes to move.\n * @param targetPosition Position to which nodes should be moved.\n * @returns Range containing moved nodes.\n */\nexport function _move( this: any, sourceRange: Range, targetPosition: Position ): Range {\n\tif ( !sourceRange.isFlat ) {\n\t\t/**\n\t\t * Trying to move a range which starts and ends in different element.\n\t\t *\n\t\t * @error operation-utils-move-range-not-flat\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'operation-utils-move-range-not-flat',\n\t\t\tthis\n\t\t);\n\t}\n\n\tconst nodes = _remove( sourceRange );\n\n\t// We have to fix `targetPosition` because model changed after nodes from `sourceRange` got removed and\n\t// that change might have an impact on `targetPosition`.\n\ttargetPosition = targetPosition._getTransformedByDeletion( sourceRange.start, sourceRange.end.offset - sourceRange.start.offset )!;\n\n\treturn _insert( targetPosition, nodes );\n}\n\n/**\n * Sets given attribute on nodes in given range. The attributes are only set on top-level nodes of the range, not on its children.\n *\n * @internal\n * @param range Range containing nodes that should have the attribute set. Must be a flat range.\n * @param key Key of attribute to set.\n * @param value Attribute value.\n */\nexport function _setAttribute( range: Range, key: string, value: unknown ): void {\n\t// Range might start or end in text nodes, so we have to split them.\n\t_splitNodeAtPosition( range.start );\n\t_splitNodeAtPosition( range.end );\n\n\t// Iterate over all items in the range.\n\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t// Iterator will return `TextProxy` instances but we know that those text proxies will\n\t\t// always represent full text nodes (this is guaranteed thanks to splitting we did before).\n\t\t// So, we can operate on those text proxies' text nodes.\n\t\tconst node = item.is( '$textProxy' ) ? item.textNode : item;\n\n\t\tif ( value !== null ) {\n\t\t\tnode._setAttribute( key, value );\n\t\t} else {\n\t\t\tnode._removeAttribute( key );\n\t\t}\n\n\t\t// After attributes changing it may happen that some text nodes can be merged. Try to merge with previous node.\n\t\t_mergeNodesAtIndex( node.parent!, node.index! );\n\t}\n\n\t// Try to merge last changed node with it's previous sibling (not covered by the loop above).\n\t_mergeNodesAtIndex( range.end.parent, range.end.index );\n}\n\n/**\n * Normalizes given object or an array of objects to an array of {@link module:engine/model/node~Node nodes}. See\n * {@link ~NodeSet NodeSet} for details on how normalization is performed.\n *\n * @internal\n * @param nodes Objects to normalize.\n * @returns Normalized nodes.\n */\nexport function _normalizeNodes( nodes: NodeSet ): Array<Node> {\n\tconst normalized: Array<Node> = [];\n\n\tfunction convert( nodes: NodeSet ) {\n\t\tif ( typeof nodes == 'string' ) {\n\t\t\tnormalized.push( new Text( nodes ) );\n\t\t} else if ( nodes instanceof TextProxy ) {\n\t\t\tnormalized.push( new Text( nodes.data, nodes.getAttributes() ) );\n\t\t} else if ( nodes instanceof Node ) {\n\t\t\tnormalized.push( nodes );\n\t\t} else if ( isIterable( nodes ) ) {\n\t\t\tfor ( const node of nodes ) {\n\t\t\t\tconvert( node );\n\t\t\t}\n\t\t} else {\n\t\t\t// Skip unrecognized type.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t\t\tconst unreachable: never = nodes;\n\t\t}\n\t}\n\n\tconvert( nodes );\n\n\t// Merge text nodes.\n\tfor ( let i = 1; i < normalized.length; i++ ) {\n\t\tconst node = normalized[ i ];\n\t\tconst prev = normalized[ i - 1 ];\n\n\t\tif ( node instanceof Text && prev instanceof Text && _haveSameAttributes( node, prev ) ) {\n\t\t\t// Doing this instead changing `prev.data` because `data` is readonly.\n\t\t\tnormalized.splice( i - 1, 2, new Text( prev.data + node.data, prev.getAttributes() ) );\n\t\t\ti--;\n\t\t}\n\t}\n\n\treturn normalized;\n}\n\n/**\n * Checks if nodes before and after given index in given element are {@link module:engine/model/text~Text text nodes} and\n * merges them into one node if they have same attributes.\n *\n * Merging is done by removing two text nodes and inserting a new text node containing data from both merged text nodes.\n *\n * @param element Parent element of nodes to merge.\n * @param index Index between nodes to merge.\n */\nfunction _mergeNodesAtIndex( element: Element | DocumentFragment, index: number ) {\n\tconst nodeBefore = element.getChild( index - 1 );\n\tconst nodeAfter = element.getChild( index );\n\n\t// Check if both of those nodes are text objects with same attributes.\n\tif ( nodeBefore && nodeAfter && nodeBefore.is( '$text' ) && nodeAfter.is( '$text' ) && _haveSameAttributes( nodeBefore, nodeAfter ) ) {\n\t\t// Append text of text node after index to the before one.\n\t\tconst mergedNode = new Text( nodeBefore.data + nodeAfter.data, nodeBefore.getAttributes() );\n\n\t\t// Remove separate text nodes.\n\t\telement._removeChildren( index - 1, 2 );\n\n\t\t// Insert merged text node.\n\t\telement._insertChild( index - 1, mergedNode );\n\t}\n}\n\n/**\n * Checks if given position is in a text node, and if so, splits the text node in two text nodes, each of them\n * containing a part of original text node.\n *\n * @param position Position at which node should be split.\n */\nfunction _splitNodeAtPosition( position: Position ): void {\n\tconst textNode = position.textNode;\n\tconst element = position.parent;\n\n\tif ( textNode ) {\n\t\tconst offsetDiff = position.offset - textNode.startOffset!;\n\t\tconst index = textNode.index!;\n\n\t\telement._removeChildren( index, 1 );\n\n\t\tconst firstPart = new Text( textNode.data.substr( 0, offsetDiff ), textNode.getAttributes() );\n\t\tconst secondPart = new Text( textNode.data.substr( offsetDiff ), textNode.getAttributes() );\n\n\t\telement._insertChild( index, [ firstPart, secondPart ] );\n\t}\n}\n\n/**\n * Checks whether two given nodes have same attributes.\n *\n * @param nodeA Node to check.\n * @param nodeB Node to check.\n * @returns `true` if nodes have same attributes, `false` otherwise.\n */\nfunction _haveSameAttributes( nodeA: Node, nodeB: Node ): boolean | undefined {\n\tconst iteratorA = nodeA.getAttributes();\n\tconst iteratorB = nodeB.getAttributes();\n\n\tfor ( const attr of iteratorA ) {\n\t\tif ( attr[ 1 ] !== nodeB.getAttribute( attr[ 0 ] ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\titeratorB.next();\n\t}\n\n\treturn iteratorB.next().done;\n}\n\n/**\n * Value that can be normalized to an array of {@link module:engine/model/node~Node nodes}.\n *\n * Non-arrays are normalized as follows:\n * * {@link module:engine/model/node~Node Node} is left as is,\n * * {@link module:engine/model/textproxy~TextProxy TextProxy} and `string` are normalized to {@link module:engine/model/text~Text Text},\n * * {@link module:engine/model/nodelist~NodeList NodeList} is normalized to an array containing all nodes that are in that node list,\n * * {@link module:engine/model/documentfragment~DocumentFragment DocumentFragment} is normalized to an array containing all of it's\n * * children.\n *\n * Arrays are processed item by item like non-array values and flattened to one array. Normalization always results in\n * a flat array of {@link module:engine/model/node~Node nodes}. Consecutive text nodes (or items normalized to text nodes) will be\n * merged if they have same attributes.\n */\nexport type NodeSet = Item | string | NodeList | DocumentFragment | Iterable<Item | string | NodeList | DocumentFragment>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/moveoperation\n */\n\nimport Operation from './operation.js';\nimport Position from '../position.js';\nimport Range from '../range.js';\nimport { _move } from './utils.js';\nimport type { Selectable } from '../selection.js';\n\nimport { CKEditorError, compareArrays } from '@ckeditor/ckeditor5-utils';\n\nimport type Document from '../document.js';\n\n// @if CK_DEBUG_ENGINE // const ModelRange = require( '../range' ).default;\n\n/**\n * Operation to move a range of {@link module:engine/model/item~Item model items}\n * to given {@link module:engine/model/position~Position target position}.\n */\nexport default class MoveOperation extends Operation {\n\t/**\n\t * Position before the first {@link module:engine/model/item~Item model item} to move.\n\t */\n\tpublic sourcePosition: Position;\n\n\t/**\n\t * Offset size of moved range.\n\t */\n\tpublic howMany: number;\n\n\t/**\n\t * Position at which moved nodes will be inserted.\n\t */\n\tpublic targetPosition: Position;\n\n\t/**\n\t * Creates a move operation.\n\t *\n\t * @param sourcePosition Position before the first {@link module:engine/model/item~Item model item} to move.\n\t * @param howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t * `sourcePosition` with offset shifted by `howMany`.\n\t * @param targetPosition Position at which moved nodes will be inserted.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( sourcePosition: Position, howMany: number, targetPosition: Position, baseVersion: number | null ) {\n\t\tsuper( baseVersion );\n\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\t// `'toNext'` because `sourcePosition` is a bit like a start of the moved range.\n\t\tthis.sourcePosition.stickiness = 'toNext';\n\n\t\tthis.howMany = howMany;\n\n\t\tthis.targetPosition = targetPosition.clone();\n\t\tthis.targetPosition.stickiness = 'toNone';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'move' | 'remove' | 'reinsert' {\n\t\tif ( this.targetPosition.root.rootName == '$graveyard' ) {\n\t\t\treturn 'remove';\n\t\t} else if ( this.sourcePosition.root.rootName == '$graveyard' ) {\n\t\t\treturn 'reinsert';\n\t\t}\n\n\t\treturn 'move';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn [\n\t\t\tRange._createFromPositionAndShift( this.sourcePosition, this.howMany ),\n\t\t\tRange._createFromPositionAndShift( this.targetPosition, 0 )\n\t\t];\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */\n\tpublic clone(): MoveOperation {\n\t\treturn new MoveOperation( this.sourcePosition, this.howMany, this.targetPosition, this.baseVersion );\n\t}\n\n\t/**\n\t * Returns the start position of the moved range after it got moved. This may be different than\n\t * {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition} in some cases, i.e. when a range is moved\n\t * inside the same parent but {@link module:engine/model/operation/moveoperation~MoveOperation#targetPosition targetPosition}\n\t * is after {@link module:engine/model/operation/moveoperation~MoveOperation#sourcePosition sourcePosition}.\n\t *\n\t * ```\n\t *  vv              vv\n\t * abcdefg ===> adefbcg\n\t *      ^          ^\n\t *      targetPos  movedRangeStart\n\t *      offset 6   offset 4\n\t *```\n\t */\n\tpublic getMovedRangeStart(): Position {\n\t\treturn this.targetPosition._getTransformedByDeletion( this.sourcePosition, this.howMany )!;\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\tconst newTargetPosition = this.sourcePosition._getTransformedByInsertion( this.targetPosition, this.howMany );\n\n\t\treturn new MoveOperation( this.getMovedRangeStart(), this.howMany, newTargetPosition, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tconst sourceElement = this.sourcePosition.parent;\n\t\tconst targetElement = this.targetPosition.parent;\n\t\tconst sourceOffset = this.sourcePosition.offset;\n\t\tconst targetOffset = this.targetPosition.offset;\n\n\t\t// Validate whether move operation has correct parameters.\n\t\t// Validation is pretty complex but move operation is one of the core ways to manipulate the document state.\n\t\t// We expect that many errors might be connected with one of scenarios described below.\n\t\tif ( sourceOffset + this.howMany > sourceElement.maxOffset ) {\n\t\t\t/**\n\t\t\t * The nodes which should be moved do not exist.\n\t\t\t *\n\t\t\t * @error move-operation-nodes-do-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-nodes-do-not-exist', this\n\t\t\t);\n\t\t} else if ( sourceElement === targetElement && sourceOffset < targetOffset && targetOffset < sourceOffset + this.howMany ) {\n\t\t\t/**\n\t\t\t * Trying to move a range of nodes into the middle of that range.\n\t\t\t *\n\t\t\t * @error move-operation-range-into-itself\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'move-operation-range-into-itself', this\n\t\t\t);\n\t\t} else if ( this.sourcePosition.root == this.targetPosition.root ) {\n\t\t\tif ( compareArrays( this.sourcePosition.getParentPath(), this.targetPosition.getParentPath() ) == 'prefix' ) {\n\t\t\t\tconst i = this.sourcePosition.path.length - 1;\n\n\t\t\t\tif ( this.targetPosition.path[ i ] >= sourceOffset && this.targetPosition.path[ i ] < sourceOffset + this.howMany ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Trying to move a range of nodes into one of nodes from that range.\n\t\t\t\t\t *\n\t\t\t\t\t * @error move-operation-node-into-itself\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t'move-operation-node-into-itself', this\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\t_move( Range._createFromPositionAndShift( this.sourcePosition, this.howMany ), this.targetPosition );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.sourcePosition = this.sourcePosition.toJSON();\n\t\tjson.targetPosition = this.targetPosition.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'MoveOperation';\n\t}\n\n\t/**\n\t * Creates `MoveOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): MoveOperation {\n\t\tconst sourcePosition = Position.fromJSON( json.sourcePosition, document );\n\t\tconst targetPosition = Position.fromJSON( json.targetPosition, document );\n\n\t\treturn new this( sourcePosition, json.howMany, targetPosition, json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \tconst range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );\n\n\t// @if CK_DEBUG_ENGINE // \treturn `MoveOperation( ${ this.baseVersion } ): ${ range } -> ${ this.targetPosition }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/insertoperation\n */\n\nimport Operation from './operation.js';\nimport Position from '../position.js';\nimport NodeList from '../nodelist.js';\nimport MoveOperation from './moveoperation.js';\nimport { _insert, _normalizeNodes, type NodeSet } from './utils.js';\nimport Text from '../text.js';\nimport Element from '../element.js';\nimport type { Selectable } from '../selection.js';\n\nimport type Document from '../document.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Operation to insert one or more nodes at given position in the model.\n */\nexport default class InsertOperation extends Operation {\n\t/**\n\t * Position of insertion.\n\t *\n\t * @readonly\n\t */\n\tpublic position: Position;\n\n\t/**\n\t * List of nodes to insert.\n\t *\n\t * @readonly\n\t */\n\tpublic nodes: NodeList;\n\n\t/**\n\t * Flag deciding how the operation should be transformed. If set to `true`, nodes might get additional attributes\n\t * during operational transformation. This happens when the operation insertion position is inside of a range\n\t * where attributes have changed.\n\t */\n\tpublic shouldReceiveAttributes: boolean;\n\n\t/**\n\t * Creates an insert operation.\n\t *\n\t * @param position Position of insertion.\n\t * @param nodes The list of nodes to be inserted.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( position: Position, nodes: NodeSet, baseVersion: number | null ) {\n\t\tsuper( baseVersion );\n\n\t\tthis.position = position.clone();\n\t\tthis.position.stickiness = 'toNone';\n\t\tthis.nodes = new NodeList( _normalizeNodes( nodes ) );\n\t\tthis.shouldReceiveAttributes = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'insert' {\n\t\treturn 'insert';\n\t}\n\n\t/**\n\t * Total offset size of inserted nodes.\n\t */\n\tpublic get howMany(): number {\n\t\treturn this.nodes.maxOffset;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn this.position.clone();\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */\n\tpublic clone(): InsertOperation {\n\t\tconst nodes = new NodeList( [ ...this.nodes ].map( node => node._clone( true ) ) );\n\t\tconst insert = new InsertOperation( this.position, nodes, this.baseVersion );\n\n\t\tinsert.shouldReceiveAttributes = this.shouldReceiveAttributes;\n\n\t\treturn insert;\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\tconst graveyard = this.position.root.document!.graveyard;\n\t\tconst gyPosition = new Position( graveyard, [ 0 ] );\n\n\t\treturn new MoveOperation( this.position, this.nodes.maxOffset, gyPosition, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tconst targetElement = this.position.parent;\n\n\t\tif ( !targetElement || targetElement.maxOffset < this.position.offset ) {\n\t\t\t/**\n\t\t\t * Insertion position is invalid.\n\t\t\t *\n\t\t\t * @error insert-operation-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'insert-operation-position-invalid',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\t// What happens here is that we want original nodes be passed to writer because we want original nodes\n\t\t// to be inserted to the model. But in InsertOperation, we want to keep those nodes as they were added\n\t\t// to the operation, not modified. For example, text nodes can get merged or cropped while Elements can\n\t\t// get children. It is important that InsertOperation has the copy of original nodes in intact state.\n\t\tconst originalNodes = this.nodes;\n\t\tthis.nodes = new NodeList( [ ...originalNodes ].map( node => node._clone( true ) ) );\n\n\t\t_insert( this.position, originalNodes );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.position = this.position.toJSON();\n\t\tjson.nodes = this.nodes.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'InsertOperation';\n\t}\n\n\t/**\n\t * Creates `InsertOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): InsertOperation {\n\t\tconst children = [];\n\n\t\tfor ( const child of json.nodes ) {\n\t\t\tif ( child.name ) {\n\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t} else {\n\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t}\n\t\t}\n\n\t\tconst insert = new InsertOperation( Position.fromJSON( json.position, document ), children, json.baseVersion );\n\t\tinsert.shouldReceiveAttributes = json.shouldReceiveAttributes;\n\n\t\treturn insert;\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \tconst nodeString = this.nodes.length > 1 ? `[ ${ this.nodes.length } ]` : this.nodes.getNode( 0 );\n\n\t// @if CK_DEBUG_ENGINE // \treturn `InsertOperation( ${ this.baseVersion } ): ${ nodeString } -> ${ this.position }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/splitoperation\n */\n\nimport Operation from './operation.js';\nimport MergeOperation from './mergeoperation.js';\nimport Position from '../position.js';\nimport Range from '../range.js';\nimport { _insert, _move } from './utils.js';\n\nimport type Document from '../document.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\nimport type { Selectable } from '../selection.js';\n\n/**\n * Operation to split {@link module:engine/model/element~Element an element} at given\n * {@link module:engine/model/operation/splitoperation~SplitOperation#splitPosition split position} into two elements,\n * both containing a part of the element's original content.\n */\nexport default class SplitOperation extends Operation {\n\t/**\n\t * Position at which an element should be split.\n\t */\n\tpublic splitPosition: Position;\n\n\t/**\n\t * Total offset size of elements that are in the split element after `position`.\n\t */\n\tpublic howMany: number;\n\n\t/**\n\t * Position at which the clone of split element (or element from graveyard) will be inserted.\n\t */\n\tpublic insertionPosition: Position;\n\n\t/**\n\t * Position in the graveyard root before the element which should be used as a parent of the nodes after `position`.\n\t * If it is not set, a copy of the the `position` parent will be used.\n\t *\n\t * The default behavior is to clone the split element. Element from graveyard is used during undo.\n\t */\n\tpublic graveyardPosition: Position | null;\n\n\t/**\n\t * Creates a split operation.\n\t *\n\t * @param splitPosition Position at which an element should be split.\n\t * @param howMany Total offset size of elements that are in the split element after `position`.\n\t * @param insertionPosition Position at which the clone of split element (or element from graveyard) will be inserted.\n\t * @param graveyardPosition Position in the graveyard root before the element which\n\t * should be used as a parent of the nodes after `position`. If it is not set, a copy of the the `position` parent will be used.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor(\n\t\tsplitPosition: Position,\n\t\thowMany: number,\n\t\tinsertionPosition: Position,\n\t\tgraveyardPosition: Position | null,\n\t\tbaseVersion: number | null\n\t) {\n\t\tsuper( baseVersion );\n\n\t\tthis.splitPosition = splitPosition.clone();\n\t\t// Keep position sticking to the next node. This way any new content added at the place where the element is split\n\t\t// will be left in the original element.\n\t\tthis.splitPosition.stickiness = 'toNext';\n\n\t\tthis.howMany = howMany;\n\t\tthis.insertionPosition = insertionPosition;\n\t\tthis.graveyardPosition = graveyardPosition ? graveyardPosition.clone() : null;\n\n\t\tif ( this.graveyardPosition ) {\n\t\t\tthis.graveyardPosition.stickiness = 'toNext';\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'split' {\n\t\treturn 'split';\n\t}\n\n\t/**\n\t * Position inside the new clone of a split element.\n\t *\n\t * This is a position where nodes that are after the split position will be moved to.\n\t */\n\tpublic get moveTargetPosition(): Position {\n\t\tconst path = this.insertionPosition.path.slice();\n\t\tpath.push( 0 );\n\n\t\treturn new Position( this.insertionPosition.root, path );\n\t}\n\n\t/**\n\t * Artificial range that contains all the nodes from the split element that will be moved to the new element.\n\t * The range starts at {@link #splitPosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t */\n\tpublic get movedRange(): Range {\n\t\tconst end = this.splitPosition.getShiftedBy( Number.POSITIVE_INFINITY );\n\n\t\treturn new Range( this.splitPosition, end );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\t// These could be positions but `Selectable` type only supports `Iterable<Range>`.\n\t\tconst ranges = [\n\t\t\tRange._createFromPositionAndShift( this.splitPosition, 0 ),\n\t\t\tRange._createFromPositionAndShift( this.insertionPosition, 0 )\n\t\t];\n\n\t\tif ( this.graveyardPosition ) {\n\t\t\tranges.push( Range._createFromPositionAndShift( this.graveyardPosition, 0 ) );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns Clone of this operation.\n\t */\n\tpublic clone(): SplitOperation {\n\t\treturn new SplitOperation( this.splitPosition, this.howMany, this.insertionPosition, this.graveyardPosition, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\tconst graveyard = this.splitPosition.root.document!.graveyard;\n\t\tconst graveyardPosition = new Position( graveyard, [ 0 ] );\n\n\t\treturn new MergeOperation( this.moveTargetPosition, this.howMany, this.splitPosition, graveyardPosition, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tconst element = this.splitPosition.parent;\n\t\tconst offset = this.splitPosition.offset;\n\n\t\t// Validate whether split operation has correct parameters.\n\t\tif ( !element || element.maxOffset < offset ) {\n\t\t\t/**\n\t\t\t * Split position is invalid.\n\t\t\t *\n\t\t\t * @error split-operation-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-position-invalid', this );\n\t\t} else if ( !element.parent ) {\n\t\t\t/**\n\t\t\t * Cannot split root element.\n\t\t\t *\n\t\t\t * @error split-operation-split-in-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-split-in-root', this );\n\t\t} else if ( this.howMany != element.maxOffset - this.splitPosition.offset ) {\n\t\t\t/**\n\t\t\t * Split operation specifies wrong number of nodes to move.\n\t\t\t *\n\t\t\t * @error split-operation-how-many-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-how-many-invalid', this );\n\t\t} else if ( this.graveyardPosition && !this.graveyardPosition.nodeAfter ) {\n\t\t\t/**\n\t\t\t * Graveyard position invalid.\n\t\t\t *\n\t\t\t * @error split-operation-graveyard-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'split-operation-graveyard-position-invalid', this );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\tconst splitElement = this.splitPosition.parent;\n\n\t\tif ( this.graveyardPosition ) {\n\t\t\t_move( Range._createFromPositionAndShift( this.graveyardPosition, 1 ), this.insertionPosition );\n\t\t} else {\n\t\t\tconst newElement = ( splitElement as any )._clone();\n\n\t\t\t_insert( this.insertionPosition, newElement );\n\t\t}\n\n\t\tconst sourceRange = new Range(\n\t\t\tPosition._createAt( splitElement, this.splitPosition.offset ),\n\t\t\tPosition._createAt( splitElement, splitElement.maxOffset )\n\t\t);\n\n\t\t_move( sourceRange, this.moveTargetPosition );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.splitPosition = this.splitPosition.toJSON();\n\t\tjson.insertionPosition = this.insertionPosition.toJSON();\n\n\t\tif ( this.graveyardPosition ) {\n\t\t\tjson.graveyardPosition = this.graveyardPosition.toJSON();\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'SplitOperation';\n\t}\n\n\t/**\n\t * Helper function that returns a default insertion position basing on given `splitPosition`. The default insertion\n\t * position is after the split element.\n\t */\n\tpublic static getInsertionPosition( splitPosition: Position ): Position {\n\t\tconst path = splitPosition.path.slice( 0, -1 );\n\t\tpath[ path.length - 1 ]++;\n\n\t\treturn new Position( splitPosition.root, path, 'toPrevious' );\n\t}\n\n\t/**\n\t * Creates `SplitOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): SplitOperation {\n\t\tconst splitPosition = Position.fromJSON( json.splitPosition, document );\n\t\tconst insertionPosition = Position.fromJSON( json.insertionPosition, document );\n\t\tconst graveyardPosition = json.graveyardPosition ? Position.fromJSON( json.graveyardPosition, document ) : null;\n\n\t\treturn new this( splitPosition, json.howMany, insertionPosition, graveyardPosition, json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `SplitOperation( ${ this.baseVersion } ): ${ this.splitPosition } ` +\n\t// @if CK_DEBUG_ENGINE // \t`( ${ this.howMany } ) -> ${ this.insertionPosition }` +\n\t// @if CK_DEBUG_ENGINE // \t`${ this.graveyardPosition ? ' with ' + this.graveyardPosition : '' }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/mergeoperation\n */\n\nimport Operation from './operation.js';\nimport SplitOperation from './splitoperation.js';\nimport Position from '../position.js';\nimport Range from '../range.js';\nimport { _move } from './utils.js';\n\nimport type Document from '../document.js';\nimport type Element from '../element.js';\nimport type { Selectable } from '../selection.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Operation to merge two {@link module:engine/model/element~Element elements}.\n *\n * The merged element is the parent of {@link ~MergeOperation#sourcePosition} and it is merged into the parent of\n * {@link ~MergeOperation#targetPosition}. All nodes from the merged element are moved to {@link ~MergeOperation#targetPosition}.\n *\n * The merged element is moved to the graveyard at {@link ~MergeOperation#graveyardPosition}.\n */\nexport default class MergeOperation extends Operation {\n\t/**\n\t * Position inside the merged element. All nodes from that element after that position will be moved to {@link #targetPosition}.\n\t */\n\tpublic sourcePosition: Position;\n\n\t/**\n\t * Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t */\n\tpublic howMany: number;\n\n\t/**\n\t * Position which the nodes from the merged elements will be moved to.\n\t */\n\tpublic targetPosition: Position;\n\n\t/**\n\t * Position in graveyard to which the merged element will be moved.\n\t */\n\tpublic graveyardPosition: Position;\n\n\t/**\n\t * Creates a merge operation.\n\t *\n\t * @param sourcePosition Position inside the merged element. All nodes from that\n\t * element after that position will be moved to {@link #targetPosition}.\n\t * @param howMany Summary offset size of nodes which will be moved from the merged element to the new parent.\n\t * @param targetPosition Position which the nodes from the merged elements will be moved to.\n\t * @param graveyardPosition Position in graveyard to which the merged element will be moved.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor(\n\t\tsourcePosition: Position,\n\t\thowMany: number,\n\t\ttargetPosition: Position,\n\t\tgraveyardPosition: Position,\n\t\tbaseVersion: number | null\n\t) {\n\t\tsuper( baseVersion );\n\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\t// This is, and should always remain, the first position in its parent.\n\t\tthis.sourcePosition.stickiness = 'toPrevious';\n\n\t\tthis.howMany = howMany;\n\t\tthis.targetPosition = targetPosition.clone();\n\n\t\t// Except of a rare scenario in `MergeOperation` x `MergeOperation` transformation,\n\t\t// this is, and should always remain, the last position in its parent.\n\t\tthis.targetPosition.stickiness = 'toNext';\n\t\tthis.graveyardPosition = graveyardPosition.clone();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'merge' {\n\t\treturn 'merge';\n\t}\n\n\t/**\n\t * Position before the merged element (which will be deleted).\n\t */\n\tpublic get deletionPosition(): Position {\n\t\treturn new Position( this.sourcePosition.root, this.sourcePosition.path.slice( 0, -1 ) );\n\t}\n\n\t/**\n\t * Artificial range that contains all the nodes from the merged element that will be moved to {@link ~MergeOperation#sourcePosition}.\n\t * The range starts at {@link ~MergeOperation#sourcePosition} and ends in the same parent, at `POSITIVE_INFINITY` offset.\n\t */\n\tpublic get movedRange(): Range {\n\t\tconst end = this.sourcePosition.getShiftedBy( Number.POSITIVE_INFINITY );\n\n\t\treturn new Range( this.sourcePosition, end );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\tconst mergedElement = this.sourcePosition.parent as Element;\n\n\t\treturn [\n\t\t\tRange._createOn( mergedElement ),\n\n\t\t\t// These could be positions but `Selectable` type only supports `Iterable<Range>`.\n\t\t\tRange._createFromPositionAndShift( this.targetPosition, 0 ),\n\t\t\tRange._createFromPositionAndShift( this.graveyardPosition, 0 )\n\t\t];\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */\n\tpublic clone(): MergeOperation {\n\t\treturn new MergeOperation( this.sourcePosition, this.howMany, this.targetPosition, this.graveyardPosition, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\t// Positions in this method are transformed by this merge operation because the split operation bases on\n\t\t// the context after this merge operation happened (because split operation reverses it).\n\t\t// So we need to acknowledge that the merge operation happened and those positions changed a little.\n\t\tconst targetPosition = this.targetPosition._getTransformedByMergeOperation( this );\n\n\t\tconst path = this.sourcePosition.path.slice( 0, -1 );\n\t\tconst insertionPosition = new Position( this.sourcePosition.root, path )._getTransformedByMergeOperation( this );\n\n\t\treturn new SplitOperation( targetPosition, this.howMany, insertionPosition, this.graveyardPosition, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tconst sourceElement = this.sourcePosition.parent;\n\t\tconst targetElement = this.targetPosition.parent;\n\n\t\t// Validate whether merge operation has correct parameters.\n\t\tif ( !sourceElement.parent ) {\n\t\t\t/**\n\t\t\t * Merge source position is invalid. The element to be merged must have a parent node.\n\t\t\t *\n\t\t\t * @error merge-operation-source-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'merge-operation-source-position-invalid', this );\n\t\t} else if ( !targetElement.parent ) {\n\t\t\t/**\n\t\t\t * Merge target position is invalid. The element to be merged must have a parent node.\n\t\t\t *\n\t\t\t * @error merge-operation-target-position-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'merge-operation-target-position-invalid', this );\n\t\t} else if ( this.howMany != sourceElement.maxOffset ) {\n\t\t\t/**\n\t\t\t * Merge operation specifies wrong number of nodes to move.\n\t\t\t *\n\t\t\t * @error merge-operation-how-many-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'merge-operation-how-many-invalid', this );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\tconst mergedElement = this.sourcePosition.parent as Element;\n\t\tconst sourceRange = Range._createIn( mergedElement );\n\n\t\t_move( sourceRange, this.targetPosition );\n\t\t_move( Range._createOn( mergedElement ), this.graveyardPosition );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.sourcePosition = json.sourcePosition.toJSON();\n\t\tjson.targetPosition = json.targetPosition.toJSON();\n\t\tjson.graveyardPosition = json.graveyardPosition.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'MergeOperation';\n\t}\n\n\t/**\n\t * Creates `MergeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): MergeOperation {\n\t\tconst sourcePosition = Position.fromJSON( json.sourcePosition, document );\n\t\tconst targetPosition = Position.fromJSON( json.targetPosition, document );\n\t\tconst graveyardPosition = Position.fromJSON( json.graveyardPosition, document );\n\n\t\treturn new this( sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `MergeOperation( ${ this.baseVersion } ): ` +\n\t// @if CK_DEBUG_ENGINE // \t\t`${ this.sourcePosition } -> ${ this.targetPosition }` +\n\t// @if CK_DEBUG_ENGINE // \t\t` ( ${ this.howMany } ), ${ this.graveyardPosition }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/markeroperation\n */\n\nimport Operation from './operation.js';\nimport Range from '../range.js';\n\nimport type Document from '../document.js';\nimport type MarkerCollection from '../markercollection.js';\nimport type { Selectable } from '../selection.js';\n\nexport default class MarkerOperation extends Operation {\n\t/**\n\t * Marker name.\n\t *\n\t * @readonly\n\t */\n\tpublic name: string;\n\n\t/**\n\t * Marker range before the change.\n\t *\n\t * @readonly\n\t */\n\tpublic oldRange: Range | null;\n\n\t/**\n\t * Marker range after the change.\n\t *\n\t * @readonly\n\t */\n\tpublic newRange: Range | null;\n\n\t/**\n\t * Specifies whether the marker operation affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t *\n\t * @readonly\n\t */\n\tpublic affectsData: boolean;\n\n\t/**\n\t * Marker collection on which change should be executed.\n\t */\n\tprivate readonly _markers: MarkerCollection;\n\n\t/**\n\t * @param name Marker name.\n\t * @param oldRange Marker range before the change.\n\t * @param newRange Marker range after the change.\n\t * @param markers Marker collection on which change should be executed.\n\t * @param affectsData Specifies whether the marker operation affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor(\n\t\tname: string,\n\t\toldRange: Range | null,\n\t\tnewRange: Range | null,\n\t\tmarkers: MarkerCollection,\n\t\taffectsData: boolean,\n\t\tbaseVersion: number | null\n\t) {\n\t\tsuper( baseVersion );\n\n\t\tthis.name = name;\n\t\tthis.oldRange = oldRange ? oldRange.clone() : null;\n\t\tthis.newRange = newRange ? newRange.clone() : null;\n\t\tthis.affectsData = affectsData;\n\n\t\tthis._markers = markers;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'marker' {\n\t\treturn 'marker';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\tconst ranges = [];\n\n\t\tif ( this.oldRange ) {\n\t\t\tranges.push( this.oldRange.clone() );\n\t\t}\n\n\t\tif ( this.newRange ) {\n\t\t\tif ( this.oldRange ) {\n\t\t\t\tranges.push( ...this.newRange.getDifference( this.oldRange ) );\n\t\t\t} else {\n\t\t\t\tranges.push( this.newRange.clone() );\n\t\t\t}\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */\n\tpublic clone(): MarkerOperation {\n\t\treturn new MarkerOperation( this.name, this.oldRange, this.newRange, this._markers, this.affectsData, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\treturn new MarkerOperation( this.name, this.newRange, this.oldRange, this._markers, this.affectsData, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\tif ( this.newRange ) {\n\t\t\tthis._markers._set( this.name, this.newRange, true, this.affectsData );\n\t\t} else {\n\t\t\tthis._markers._remove( this.name );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tif ( this.oldRange ) {\n\t\t\tjson.oldRange = this.oldRange.toJSON();\n\t\t}\n\n\t\tif ( this.newRange ) {\n\t\t\tjson.newRange = this.newRange.toJSON();\n\t\t}\n\n\t\tdelete json._markers;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'MarkerOperation';\n\t}\n\n\t/**\n\t * Creates `MarkerOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): MarkerOperation {\n\t\treturn new MarkerOperation(\n\t\t\tjson.name,\n\t\t\tjson.oldRange ? Range.fromJSON( json.oldRange, document ) : null,\n\t\t\tjson.newRange ? Range.fromJSON( json.newRange, document ) : null,\n\t\t\tdocument.model.markers,\n\t\t\tjson.affectsData,\n\t\t\tjson.baseVersion\n\t\t);\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `MarkerOperation( ${ this.baseVersion } ): ` +\n\t// @if CK_DEBUG_ENGINE //\t\t`\"${ this.name }\": ${ this.oldRange } -> ${ this.newRange }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/attributeoperation\n */\n\nimport Operation from './operation.js';\nimport { _setAttribute } from './utils.js';\nimport Range from '../range.js';\n\nimport type Document from '../document.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\nimport { isEqual } from 'lodash-es';\nimport type { Selectable } from '../selection.js';\n\n/**\n * Operation to change nodes' attribute.\n *\n * Using this class you can add, remove or change value of the attribute.\n */\nexport default class AttributeOperation extends Operation {\n\t/**\n\t * Range on which operation should be applied.\n\t *\n\t * @readonly\n\t */\n\tpublic range: Range;\n\n\t/**\n\t * Key of an attribute to change or remove.\n\t *\n\t * @readonly\n\t */\n\tpublic key: string;\n\n\t/**\n\t * Old value of the attribute with given key or `null`, if attribute was not set before.\n\t *\n\t * @readonly\n\t */\n\tpublic oldValue: unknown;\n\n\t/**\n\t * New value of the attribute with given key or `null`, if operation should remove attribute.\n\t *\n\t * @readonly\n\t */\n\tpublic newValue: unknown;\n\n\t/**\n\t * Creates an operation that changes, removes or adds attributes.\n\t *\n\t * If only `newValue` is set, attribute will be added on a node. Note that all nodes in operation's range must not\n\t * have an attribute with the same key as the added attribute.\n\t *\n\t * If only `oldValue` is set, then attribute with given key will be removed. Note that all nodes in operation's range\n\t * must have an attribute with that key added.\n\t *\n\t * If both `newValue` and `oldValue` are set, then the operation will change the attribute value. Note that all nodes in\n\t * operation's ranges must already have an attribute with given key and `oldValue` as value\n\t *\n\t * @param range Range on which the operation should be applied. Must be a flat range.\n\t * @param key Key of an attribute to change or remove.\n\t * @param oldValue Old value of the attribute with given key or `null`, if attribute was not set before.\n\t * @param newValue New value of the attribute with given key or `null`, if operation should remove attribute.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( range: Range, key: string, oldValue: unknown, newValue: unknown, baseVersion: number | null ) {\n\t\tsuper( baseVersion );\n\n\t\tthis.range = range.clone();\n\t\tthis.key = key;\n\t\tthis.oldValue = oldValue === undefined ? null : oldValue;\n\t\tthis.newValue = newValue === undefined ? null : newValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'addAttribute' | 'removeAttribute' | 'changeAttribute' {\n\t\tif ( this.oldValue === null ) {\n\t\t\treturn 'addAttribute';\n\t\t} else if ( this.newValue === null ) {\n\t\t\treturn 'removeAttribute';\n\t\t} else {\n\t\t\treturn 'changeAttribute';\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn this.range.clone();\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */\n\tpublic clone(): AttributeOperation {\n\t\treturn new AttributeOperation( this.range, this.key, this.oldValue, this.newValue, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\treturn new AttributeOperation( this.range, this.key, this.newValue, this.oldValue, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.range = this.range.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tif ( !this.range.isFlat ) {\n\t\t\t/**\n\t\t\t * The range to change is not flat.\n\t\t\t *\n\t\t\t * @error attribute-operation-range-not-flat\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'attribute-operation-range-not-flat', this );\n\t\t}\n\n\t\tfor ( const item of this.range.getItems( { shallow: true } ) ) {\n\t\t\tif ( this.oldValue !== null && !isEqual( item.getAttribute( this.key ), this.oldValue ) ) {\n\t\t\t\t/**\n\t\t\t\t * Changed node has different attribute value than operation's old attribute value.\n\t\t\t\t *\n\t\t\t\t * @error attribute-operation-wrong-old-value\n\t\t\t\t * @param item\n\t\t\t\t * @param key\n\t\t\t\t * @param value\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'attribute-operation-wrong-old-value',\n\t\t\t\t\tthis,\n\t\t\t\t\t{ item, key: this.key, value: this.oldValue }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( this.oldValue === null && this.newValue !== null && item.hasAttribute( this.key ) ) {\n\t\t\t\t/**\n\t\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t\t *\n\t\t\t\t * @error attribute-operation-attribute-exists\n\t\t\t\t * @param node\n\t\t\t\t * @param key\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'attribute-operation-attribute-exists',\n\t\t\t\t\tthis,\n\t\t\t\t\t{ node: item, key: this.key }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\t// If value to set is same as old value, don't do anything.\n\t\tif ( !isEqual( this.oldValue, this.newValue ) ) {\n\t\t\t// Execution.\n\t\t\t_setAttribute( this.range, this.key, this.newValue );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'AttributeOperation';\n\t}\n\n\t/**\n\t * Creates `AttributeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): AttributeOperation {\n\t\treturn new AttributeOperation( Range.fromJSON( json.range, document ), json.key, json.oldValue, json.newValue, json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `AttributeOperation( ${ this.baseVersion } ): ` +\n\t// @if CK_DEBUG_ENGINE // \t\t`\"${ this.key }\": ${ JSON.stringify( this.oldValue ) }` +\n\t// @if CK_DEBUG_ENGINE // \t\t` -> ${ JSON.stringify( this.newValue ) }, ${ this.range }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/nooperation\n */\n\nimport Operation from './operation.js';\nimport type { Selectable } from '../selection.js';\n\n/**\n * Operation which is doing nothing (\"empty operation\", \"do-nothing operation\", \"noop\"). This is an operation,\n * which when executed does not change the tree model. It still has some parameters defined for transformation purposes.\n *\n * In most cases this operation is a result of transforming operations. When transformation returns\n * {@link module:engine/model/operation/nooperation~NoOperation} it means that changes done by the transformed operation\n * have already been applied.\n */\nexport default class NoOperation extends Operation {\n\tpublic get type(): 'noop' {\n\t\treturn 'noop';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t */\n\tpublic clone(): NoOperation {\n\t\treturn new NoOperation( this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\treturn new NoOperation( this.baseVersion! + 1 );\n\t}\n\n\t/** @internal */\n\tpublic _execute(): void {\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'NoOperation';\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `NoOperation( ${ this.baseVersion } )`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/renameoperation\n */\n\nimport Operation from './operation.js';\nimport Element from '../element.js';\nimport Position from '../position.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type Document from '../document.js';\nimport type { Selectable } from '../selection.js';\n\n/**\n * Operation to change element's name.\n *\n * Using this class you can change element's name.\n */\nexport default class RenameOperation extends Operation {\n\t/**\n\t * Position before an element to change.\n\t */\n\tpublic position: Position;\n\n\t/**\n\t * Current name of the element.\n\t */\n\tpublic oldName: string;\n\n\t/**\n\t * New name for the element.\n\t */\n\tpublic newName: string;\n\n\t/**\n\t * Creates an operation that changes element's name.\n\t *\n\t * @param position Position before an element to change.\n\t * @param oldName Current name of the element.\n\t * @param newName New name for the element.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor( position: Position, oldName: string, newName: string, baseVersion: number | null ) {\n\t\tsuper( baseVersion );\n\n\t\tthis.position = position;\n\t\t// This position sticks to the next node because it is a position before the node that we want to change.\n\t\tthis.position.stickiness = 'toNext';\n\n\t\tthis.oldName = oldName;\n\t\tthis.newName = newName;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'rename' {\n\t\treturn 'rename';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn this.position.nodeAfter;\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns Clone of this operation.\n\t */\n\tpublic clone(): RenameOperation {\n\t\treturn new RenameOperation( this.position.clone(), this.oldName, this.newName, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\treturn new RenameOperation( this.position.clone(), this.newName, this.oldName, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tconst element = this.position.nodeAfter;\n\n\t\tif ( !( element instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Given position is invalid or node after it is not instance of Element.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-position\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rename-operation-wrong-position',\n\t\t\t\tthis\n\t\t\t);\n\t\t} else if ( element.name !== this.oldName ) {\n\t\t\t/**\n\t\t\t * Element to change has different name than operation's old name.\n\t\t\t *\n\t\t\t * @error rename-operation-wrong-name\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rename-operation-wrong-name',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\tconst element = this.position.nodeAfter;\n\n\t\t( element as any ).name = this.newName;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.position = this.position.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'RenameOperation';\n\t}\n\n\t/**\n\t * Creates `RenameOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): RenameOperation {\n\t\treturn new RenameOperation( Position.fromJSON( json.position, document ), json.oldName, json.newName, json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `RenameOperation( ${ this.baseVersion } ): ` +\n\t// @if CK_DEBUG_ENGINE // \t\t`${ this.position }: \"${ this.oldName }\" -> \"${ this.newName }\"`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/rootattributeoperation\n */\n\nimport Operation from './operation.js';\n\nimport type Document from '../document.js';\nimport type RootElement from '../rootelement.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\nimport type { Selectable } from '../selection.js';\n\n/**\n * Operation to change root element's attribute. Using this class you can add, remove or change value of the attribute.\n *\n * This operation is needed, because root elements can't be changed through\n * {@link module:engine/model/operation/attributeoperation~AttributeOperation}.\n * It is because {@link module:engine/model/operation/attributeoperation~AttributeOperation}\n * requires a range to change and root element can't\n * be a part of range because every {@link module:engine/model/position~Position} has to be inside a root.\n * {@link module:engine/model/position~Position} can't be created before a root element.\n */\nexport default class RootAttributeOperation extends Operation {\n\t/**\n\t * Root element to change.\n\t */\n\tpublic readonly root: RootElement;\n\n\t/**\n\t * Key of an attribute to change or remove.\n\t */\n\tpublic readonly key: string;\n\n\t/**\n\t * Old value of the attribute with given key or `null`, if attribute was not set before.\n\t *\n\t * @readonly\n\t */\n\tpublic oldValue: unknown;\n\n\t/**\n\t * New value of the attribute with given key or `null`, if operation should remove attribute.\n\t *\n\t * @readonly\n\t */\n\tpublic newValue: unknown;\n\n\t/**\n\t * Creates an operation that changes, removes or adds attributes on root element.\n\t *\n\t * @see module:engine/model/operation/attributeoperation~AttributeOperation\n\t * @param root Root element to change.\n\t * @param key Key of an attribute to change or remove.\n\t * @param oldValue Old value of the attribute with given key or `null`, if attribute was not set before.\n\t * @param newValue New value of the attribute with given key or `null`, if operation should remove attribute.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation\n\t * can be applied or `null` if the operation operates on detached (non-document) tree.\n\t */\n\tconstructor(\n\t\troot: RootElement,\n\t\tkey: string,\n\t\toldValue: unknown,\n\t\tnewValue: unknown,\n\t\tbaseVersion: number | null\n\t) {\n\t\tsuper( baseVersion );\n\n\t\tthis.root = root;\n\t\tthis.key = key;\n\t\tthis.oldValue = oldValue === undefined ? null : oldValue;\n\t\tthis.newValue = newValue === undefined ? null : newValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'addRootAttribute' | 'removeRootAttribute' | 'changeRootAttribute' {\n\t\tif ( this.oldValue === null ) {\n\t\t\treturn 'addRootAttribute';\n\t\t} else if ( this.newValue === null ) {\n\t\t\treturn 'removeRootAttribute';\n\t\t} else {\n\t\t\treturn 'changeRootAttribute';\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn this.root;\n\t}\n\n\t/**\n\t * Creates and returns an operation that has the same parameters as this operation.\n\t *\n\t * @returns Clone of this operation.\n\t */\n\tpublic clone(): RootAttributeOperation {\n\t\treturn new RootAttributeOperation( this.root, this.key, this.oldValue, this.newValue, this.baseVersion );\n\t}\n\n\t/**\n\t * See {@link module:engine/model/operation/operation~Operation#getReversed `Operation#getReversed()`}.\n\t */\n\tpublic getReversed(): Operation {\n\t\treturn new RootAttributeOperation( this.root, this.key, this.newValue, this.oldValue, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tif ( this.root != this.root.root || this.root.is( 'documentFragment' ) ) {\n\t\t\t/**\n\t\t\t * The element to change is not a root element.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-not-a-root\n\t\t\t * @param root\n\t\t\t * @param key\n\t\t\t * @param value\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-not-a-root',\n\t\t\t\tthis,\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\n\t\tif ( this.oldValue !== null && this.root.getAttribute( this.key ) !== this.oldValue ) {\n\t\t\t/**\n\t\t\t * The attribute which should be removed does not exist for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-wrong-old-value\n\t\t\t * @param root\n\t\t\t * @param key\n\t\t\t * @param value\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-wrong-old-value',\n\t\t\t\tthis,\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\n\t\tif ( this.oldValue === null && this.newValue !== null && this.root.hasAttribute( this.key ) ) {\n\t\t\t/**\n\t\t\t * The attribute with given key already exists for the given node.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-attribute-exists\n\t\t\t * @param root\n\t\t\t * @param key\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'rootattribute-operation-attribute-exists',\n\t\t\t\tthis,\n\t\t\t\t{ root: this.root, key: this.key }\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _execute(): void {\n\t\tif ( this.newValue !== null ) {\n\t\t\tthis.root._setAttribute( this.key, this.newValue );\n\t\t} else {\n\t\t\tthis.root._removeAttribute( this.key );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.root = this.root.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'RootAttributeOperation';\n\t}\n\n\t/**\n\t * Creates `RootAttributeOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): RootAttributeOperation {\n\t\tif ( !document.getRoot( json.root ) ) {\n\t\t\t/**\n\t\t\t * Cannot create RootAttributeOperation for document. Root with specified name does not exist.\n\t\t\t *\n\t\t\t * @error rootattribute-operation-fromjson-no-root\n\t\t\t * @param rootName\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'rootattribute-operation-fromjson-no-root', this, { rootName: json.root } );\n\t\t}\n\n\t\treturn new RootAttributeOperation( document.getRoot( json.root )!, json.key, json.oldValue, json.newValue, json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `RootAttributeOperation( ${ this.baseVersion } ): ` +\n\t// @if CK_DEBUG_ENGINE //\t\t`\"${ this.key }\": ${ JSON.stringify( this.oldValue ) }` +\n\t// @if CK_DEBUG_ENGINE //\t\t` -> ${ JSON.stringify( this.newValue ) }, ${ this.root.rootName }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/rootoperation\n */\n\nimport Operation from './operation.js';\n\nimport type Document from '../document.js';\nimport type { Selectable } from '../selection.js';\n\n/**\n * Operation that creates (or attaches) or detaches a root element.\n */\nexport default class RootOperation extends Operation {\n\t/**\n\t * Root name to create or detach.\n\t */\n\tpublic readonly rootName: string;\n\n\t/**\n\t * Root element name.\n\t */\n\tpublic readonly elementName: string;\n\n\t/**\n\t * Specifies whether the operation adds (`true`) or detaches the root (`false`).\n\t */\n\tpublic readonly isAdd: boolean;\n\n\t/**\n\t * Document which owns the root.\n\t */\n\tprivate readonly _document: Document;\n\n\t/**\n\t * Creates an operation that creates or removes a root element.\n\t *\n\t * @param rootName Root name to create or detach.\n\t * @param elementName Root element name.\n\t * @param isAdd Specifies whether the operation adds (`true`) or detaches the root (`false`).\n\t * @param document Document which owns the root.\n\t * @param baseVersion Document {@link module:engine/model/document~Document#version} on which operation can be applied.\n\t */\n\tconstructor(\n\t\trootName: string,\n\t\telementName: string,\n\t\tisAdd: boolean,\n\t\tdocument: Document,\n\t\tbaseVersion: number\n\t) {\n\t\tsuper( baseVersion );\n\n\t\tthis.rootName = rootName;\n\t\tthis.elementName = elementName;\n\t\tthis.isAdd = isAdd;\n\t\tthis._document = document;\n\n\t\t// Make sure that the root exists ASAP, this is important for RTC.\n\t\t// If the root was dynamically added, there will be more operations that operate on/in this root.\n\t\t// These operations will require root element instance (in operation property or in position instance).\n\t\t// If the root is not created ahead of time, instantiating such operations may fail.\n\t\tif ( !this._document.getRoot( this.rootName ) ) {\n\t\t\tconst root = this._document.createRoot( this.elementName, this.rootName );\n\n\t\t\troot._isAttached = false;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override get type(): 'addRoot' | 'detachRoot' {\n\t\treturn this.isAdd ? 'addRoot' : 'detachRoot';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn this._document.getRoot( this.rootName );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override clone(): RootOperation {\n\t\treturn new RootOperation( this.rootName, this.elementName, this.isAdd, this._document, this.baseVersion! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override getReversed(): RootOperation {\n\t\treturn new RootOperation( this.rootName, this.elementName, !this.isAdd, this._document, this.baseVersion! + 1 );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override _execute(): void {\n\t\tthis._document.getRoot( this.rootName )!._isAttached = this.isAdd;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tdelete json._document;\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'RootOperation';\n\t}\n\n\t/**\n\t * Creates `RootOperation` object from deserialized object, i.e. from parsed JSON string.\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static override fromJSON( json: any, document: Document ): RootOperation {\n\t\treturn new RootOperation( json.rootName, json.elementName, json.isAdd, document, json.baseVersion );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn `RootOperation( ${ this.baseVersion } ): ` +\n\t// @if CK_DEBUG_ENGINE //\t\t`${ this.type } -> \"${ this.rootName }\" (${ this.elementName })`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/operationfactory\n */\n\nimport AttributeOperation from './attributeoperation.js';\nimport InsertOperation from './insertoperation.js';\nimport MarkerOperation from './markeroperation.js';\nimport MoveOperation from './moveoperation.js';\nimport NoOperation from './nooperation.js';\nimport Operation from './operation.js';\nimport RenameOperation from './renameoperation.js';\nimport RootAttributeOperation from './rootattributeoperation.js';\nimport RootOperation from './rootoperation.js';\nimport SplitOperation from './splitoperation.js';\nimport MergeOperation from './mergeoperation.js';\n\nimport type Document from '../document.js';\n\nconst operations: {\n\t[ className: string ]: {\n\t\tfromJSON( json: any, document: Document ): Operation;\n\t};\n} = {};\n\noperations[ AttributeOperation.className ] = AttributeOperation;\noperations[ InsertOperation.className ] = InsertOperation;\noperations[ MarkerOperation.className ] = MarkerOperation;\noperations[ MoveOperation.className ] = MoveOperation;\noperations[ NoOperation.className ] = NoOperation;\noperations[ Operation.className ] = Operation;\noperations[ RenameOperation.className ] = RenameOperation;\noperations[ RootAttributeOperation.className ] = RootAttributeOperation;\noperations[ RootOperation.className ] = RootOperation;\noperations[ SplitOperation.className ] = SplitOperation;\noperations[ MergeOperation.className ] = MergeOperation;\n\n/**\n * A factory class for creating operations.\n */\nexport default abstract class OperationFactory {\n\t/**\n\t * Creates an operation instance from a JSON object (parsed JSON string).\n\t *\n\t * @param json Deserialized JSON object.\n\t * @param document Document on which this operation will be applied.\n\t */\n\tpublic static fromJSON( json: any, document: Document ): Operation {\n\t\treturn operations[ json.__className ].fromJSON( json, document );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/transform\n */\n\nimport InsertOperation from './insertoperation.js';\nimport AttributeOperation from './attributeoperation.js';\nimport RenameOperation from './renameoperation.js';\nimport MarkerOperation from './markeroperation.js';\nimport MoveOperation from './moveoperation.js';\nimport RootAttributeOperation from './rootattributeoperation.js';\nimport RootOperation from './rootoperation.js';\nimport MergeOperation from './mergeoperation.js';\nimport SplitOperation from './splitoperation.js';\nimport NoOperation from './nooperation.js';\nimport Range from '../range.js';\nimport Position from '../position.js';\n\nimport type Operation from './operation.js';\nimport type Document from '../document.js';\nimport type History from '../history.js';\n\nimport { compareArrays } from '@ckeditor/ckeditor5-utils';\n\ntype TransformationFunction = ( a: Operation, b: Operation, context: TransformationContext ) => Array<Operation>;\n\nconst transformations = new Map<Function, Map<Function, TransformationFunction>>();\n\n/**\n * Sets a transformation function to be be used to transform instances of class `OperationA` by instances of class `OperationB`.\n *\n * The `transformationFunction` is passed three parameters:\n *\n * * `a` - operation to be transformed, an instance of `OperationA`,\n * * `b` - operation to be transformed by, an instance of `OperationB`,\n * * {@link module:engine/model/operation/transform~TransformationContext `context`} - object with additional information about\n * transformation context.\n *\n * The `transformationFunction` should return transformation result, which is an array with one or multiple\n * {@link module:engine/model/operation/operation~Operation operation} instances.\n *\n * @param transformationFunction Function to use for transforming.\n */\nfunction setTransformation<\n\tClassA extends new ( ...args: Array<any> ) => Operation,\n\tClassB extends new ( ...args: Array<any> ) => Operation\n>(\n\tOperationA: ClassA,\n\tOperationB: ClassB,\n\ttransformationFunction: ( a: InstanceType<ClassA>, b: InstanceType<ClassB>, context: TransformationContext ) => Array<Operation>\n) {\n\tlet aGroup = transformations.get( OperationA );\n\n\tif ( !aGroup ) {\n\t\taGroup = new Map();\n\t\ttransformations.set( OperationA, aGroup );\n\t}\n\n\taGroup.set( OperationB, transformationFunction as TransformationFunction );\n}\n\n/**\n * Returns a previously set transformation function for transforming an instance of `OperationA` by an instance of `OperationB`.\n *\n * If no transformation was set for given pair of operations, {@link module:engine/model/operation/transform~noUpdateTransformation}\n * is returned. This means that if no transformation was set, the `OperationA` instance will not change when transformed\n * by the `OperationB` instance.\n *\n * @returns Function set to transform an instance of `OperationA` by an instance of `OperationB`.\n */\nfunction getTransformation( OperationA: Function, OperationB: Function ): TransformationFunction {\n\tconst aGroup = transformations.get( OperationA );\n\n\tif ( aGroup && aGroup.has( OperationB ) ) {\n\t\treturn aGroup.get( OperationB )!;\n\t}\n\n\treturn noUpdateTransformation;\n}\n\n/**\n * A transformation function that only clones operation to transform, without changing it.\n */\nfunction noUpdateTransformation( a: Operation ): Array<Operation> {\n\treturn [ a ];\n}\n\n/**\n * Transforms operation `a` by operation `b`.\n *\n * @param a Operation to be transformed.\n * @param b Operation to transform by.\n * @param context Transformation context for this transformation.\n * @returns Transformation result.\n */\nexport function transform( a: Operation, b: Operation, context: TransformationContext = {} ): Array<Operation> {\n\tconst transformationFunction = getTransformation( a.constructor, b.constructor );\n\n\t/* eslint-disable no-useless-catch */\n\ttry {\n\t\ta = a.clone();\n\n\t\treturn transformationFunction( a, b, context );\n\t} catch ( e: any ) {\n\t\t// @if CK_DEBUG // console.warn( 'Error during operation transformation!', e.message );\n\t\t// @if CK_DEBUG // console.warn( 'Transformed operation', a );\n\t\t// @if CK_DEBUG // console.warn( 'Operation transformed by', b );\n\t\t// @if CK_DEBUG // console.warn( 'context.aIsStrong', context.aIsStrong );\n\t\t// @if CK_DEBUG // console.warn( 'context.aWasUndone', context.aWasUndone );\n\t\t// @if CK_DEBUG // console.warn( 'context.bWasUndone', context.bWasUndone );\n\t\t// @if CK_DEBUG // console.warn( 'context.abRelation', context.abRelation );\n\t\t// @if CK_DEBUG // console.warn( 'context.baRelation', context.baRelation );\n\n\t\tthrow e;\n\t}\n\t/* eslint-enable no-useless-catch */\n}\n\n/**\n * Performs a transformation of two sets of operations - `operationsA` and `operationsB`. The transformation is two-way -\n * both transformed `operationsA` and transformed `operationsB` are returned.\n *\n * Note, that the first operation in each set should base on the same document state (\n * {@link module:engine/model/document~Document#version document version}).\n *\n * It is assumed that `operationsA` are \"more important\" during conflict resolution between two operations.\n *\n * New copies of both passed arrays and operations inside them are returned. Passed arguments are not altered.\n *\n * Base versions of the transformed operations sets are updated accordingly. For example, assume that base versions are `4`\n * and there are `3` operations in `operationsA` and `5` operations in `operationsB`. Then:\n *\n * * transformed `operationsA` will start from base version `9` (`4` base version + `5` operations B),\n * * transformed `operationsB` will start from base version `7` (`4` base version + `3` operations A).\n *\n * If no operation was broken into two during transformation, then both sets will end up with an operation that bases on version `11`:\n *\n * * transformed `operationsA` start from `9` and there are `3` of them, so the last will have `baseVersion` equal to `11`,\n * * transformed `operationsB` start from `7` and there are `5` of them, so the last will have `baseVersion` equal to `11`.\n *\n * @param operationsA\n * @param operationsB\n * @param options Additional transformation options.\n * @param options.document Document which the operations change.\n * @param options.useRelations Whether during transformation relations should be used (used during undo for better conflict resolution).\n * @param options.padWithNoOps Whether additional {@link module:engine/model/operation/nooperation~NoOperation}s\n * should be added to the transformation results to force the same last base version for both transformed sets (in case\n * if some operations got broken into multiple operations during transformation).\n * @param options.forceWeakRemove If set to `false`, remove operation will be always stronger than move operation,\n * so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.\n * @returns Transformation result.\n */\nexport function transformSets(\n\toperationsA: Array<Operation>,\n\toperationsB: Array<Operation>,\n\toptions: {\n\t\tdocument: Document;\n\t\tuseRelations?: boolean;\n\t\tpadWithNoOps?: boolean;\n\t\tforceWeakRemove?: boolean;\n\t}\n): TransformSetsResult {\n\t// Create new arrays so the originally passed arguments are not changed.\n\t// No need to clone operations, they are cloned as they are transformed.\n\toperationsA = operationsA.slice();\n\toperationsB = operationsB.slice();\n\n\tconst contextFactory = new ContextFactory( options.document, options.useRelations, options.forceWeakRemove );\n\tcontextFactory.setOriginalOperations( operationsA );\n\tcontextFactory.setOriginalOperations( operationsB );\n\n\tconst originalOperations = contextFactory.originalOperations;\n\n\t// If one of sets is empty there is simply nothing to transform, so return sets as they are.\n\tif ( operationsA.length == 0 || operationsB.length == 0 ) {\n\t\treturn { operationsA, operationsB, originalOperations };\n\t}\n\t//\n\t// Following is a description of transformation process:\n\t//\n\t// There are `operationsA` and `operationsB` to be transformed, both by both.\n\t//\n\t// So, suppose we have sets of two operations each: `operationsA` = `[ a1, a2 ]`, `operationsB` = `[ b1, b2 ]`.\n\t//\n\t// Remember, that we can only transform operations that base on the same context. We assert that `a1` and `b1` base on\n\t// the same context and we transform them. Then, we get `a1'` and `b1'`. `a2` bases on a context with `a1` -- `a2`\n\t// is an operation that followed `a1`. Similarly, `b2` bases on a context with `b1`.\n\t//\n\t// However, since `a1'` is a result of transformation by `b1`, `a1'` now also has a context with `b1`. This means that\n\t// we can safely transform `a1'` by `b2`. As we finish transforming `a1`, we also transformed all `operationsB`.\n\t// All `operationsB` also have context including `a1`. Now, we can properly transform `a2` by those operations.\n\t//\n\t// The transformation process can be visualized on a transformation diagram (\"diamond diagram\"):\n\t//\n\t//          [the initial state]\n\t//         [common for a1 and b1]\n\t//\n\t//                   *\n\t//                  / \\\n\t//                 /   \\\n\t//               b1     a1\n\t//               /       \\\n\t//              /         \\\n\t//             *           *\n\t//            / \\         / \\\n\t//           /   \\       /   \\\n\t//         b2    a1'   b1'    a2\n\t//         /       \\   /       \\\n\t//        /         \\ /         \\\n\t//       *           *           *\n\t//        \\         / \\         /\n\t//         \\       /   \\       /\n\t//        a1''   b2'   a2'   b1''\n\t//           \\   /       \\   /\n\t//            \\ /         \\ /\n\t//             *           *\n\t//              \\         /\n\t//               \\       /\n\t//              a2''   b2''\n\t//                 \\   /\n\t//                  \\ /\n\t//                   *\n\t//\n\t//           [the final state]\n\t//\n\t// The final state can be reached from the initial state by applying `a1`, `a2`, `b1''` and `b2''`, as well as by\n\t// applying `b1`, `b2`, `a1''`, `a2''`. Note how the operations get to a proper common state before each pair is\n\t// transformed.\n\t//\n\t// Another thing to consider is that an operation during transformation can be broken into multiple operations.\n\t// Suppose that `a1` * `b1` = `[ a11', a12' ]` (instead of `a1'` that we considered previously).\n\t//\n\t// In that case, we leave `a12'` for later and we continue transforming `a11'` until it is transformed by all `operationsB`\n\t// (in our case it is just `b2`). At this point, `b1` is transformed by \"whole\" `a1`, while `b2` is only transformed\n\t// by `a11'`. Similarly, `a12'` is only transformed by `b1`. This leads to a conclusion that we need to start transforming `a12'`\n\t// from the moment just after it was broken. So, `a12'` is transformed by `b2`. Now, \"the whole\" `a1` is transformed\n\t// by `operationsB`, while all `operationsB` are transformed by \"the whole\" `a1`. This means that we can continue with\n\t// following `operationsA` (in our case it is just `a2`).\n\t//\n\t// Of course, also `operationsB` can be broken. However, since we focus on transforming operation `a` to the end,\n\t// the only thing to do is to store both pieces of operation `b`, so that the next transformed operation `a` will\n\t// be transformed by both of them.\n\t//\n\t//                       *\n\t//                      / \\\n\t//                     /   \\\n\t//                    /     \\\n\t//                  b1       a1\n\t//                  /         \\\n\t//                 /           \\\n\t//                /             \\\n\t//               *               *\n\t//              / \\             / \\\n\t//             /  a11'         /   \\\n\t//            /     \\         /     \\\n\t//          b2       *      b1'      a2\n\t//          /       / \\     /         \\\n\t//         /       /  a12' /           \\\n\t//        /       /     \\ /             \\\n\t//       *       b2'     *               *\n\t//        \\     /       / \\             /\n\t//       a11'' /     b21'' \\           /\n\t//          \\ /       /     \\         /\n\t//           *       *      a2'     b1''\n\t//            \\     / \\       \\     /\n\t//          a12'' b22''\\       \\   /\n\t//              \\ /     \\       \\ /\n\t//               *      a2''     *\n\t//                \\       \\     /\n\t//                 \\       \\  b21'''\n\t//                  \\       \\ /\n\t//                a2'''      *\n\t//                    \\     /\n\t//                     \\  b22'''\n\t//                      \\ /\n\t//                       *\n\t//\n\t// Note, how `a1` is broken and transformed into `a11'` and `a12'`, while `b2'` got broken and transformed into `b21''` and `b22''`.\n\t//\n\t// Having all that on mind, here is an outline for the transformation process algorithm:\n\t//\n\t// 1. We have `operationsA` and `operationsB` array, which we dynamically update as the transformation process goes.\n\t//\n\t// 2. We take next (or first) operation from `operationsA` and check from which operation `b` we need to start transforming it.\n\t// All original `operationsA` are set to be transformed starting from the first operation `b`.\n\t//\n\t// 3. We take operations from `operationsB`, one by one, starting from the correct one, and transform operation `a`\n\t// by operation `b` (and vice versa). We update `operationsA` and `operationsB` by replacing the original operations\n\t// with the transformation results.\n\t//\n\t// 4. If operation is broken into multiple operations, we save all the new operations in the place of the\n\t// original operation.\n\t//\n\t// 5. Additionally, if operation `a` was broken, for the \"new\" operation, we remember from which operation `b` it should\n\t// be transformed by.\n\t//\n\t// 6. We continue transforming \"current\" operation `a` until it is transformed by all `operationsB`. Then, go to 2.\n\t// unless the last operation `a` was transformed.\n\t//\n\t// The actual implementation of the above algorithm is slightly different, as only one loop (while) is used.\n\t// The difference is that we have \"current\" `a` operation to transform and we store the index of the next `b` operation\n\t// to transform by. Each loop operates on two indexes then: index pointing to currently processed `a` operation and\n\t// index pointing to next `b` operation. Each loop is just one `a * b` + `b * a` transformation. After each loop\n\t// operation `b` index is updated. If all `b` operations were visited for the current `a` operation, we change\n\t// current `a` operation index to the next one.\n\t//\n\n\t// For each operation `a`, keeps information what is the index in `operationsB` from which the transformation should start.\n\tconst nextTransformIndex = new WeakMap<Operation, number>();\n\n\t// For all the original `operationsA`, set that they should be transformed starting from the first of `operationsB`.\n\tfor ( const op of operationsA ) {\n\t\tnextTransformIndex.set( op, 0 );\n\t}\n\n\t// Additional data that is used for some postprocessing after the main transformation process is done.\n\tconst data = {\n\t\tnextBaseVersionA: operationsA[ operationsA.length - 1 ].baseVersion! + 1,\n\t\tnextBaseVersionB: operationsB[ operationsB.length - 1 ].baseVersion! + 1,\n\t\toriginalOperationsACount: operationsA.length,\n\t\toriginalOperationsBCount: operationsB.length\n\t};\n\n\t// Index of currently transformed operation `a`.\n\tlet i = 0;\n\n\t// While not all `operationsA` are transformed...\n\twhile ( i < operationsA.length ) {\n\t\t// Get \"current\" operation `a`.\n\t\tconst opA = operationsA[ i ];\n\n\t\t// For the \"current\" operation `a`, get the index of the next operation `b` to transform by.\n\t\tconst indexB = nextTransformIndex.get( opA )!;\n\n\t\t// If operation `a` was already transformed by every operation `b`, change \"current\" operation `a` to the next one.\n\t\tif ( indexB == operationsB.length ) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst opB = operationsB[ indexB ];\n\n\t\t// Transform `a` by `b` and `b` by `a`.\n\t\tconst newOpsA = transform( opA, opB, contextFactory.getContext( opA, opB, true ) );\n\t\tconst newOpsB = transform( opB, opA, contextFactory.getContext( opB, opA, false ) );\n\t\t// As a result we get one or more `newOpsA` and one or more `newOpsB` operations.\n\n\t\t// Update contextual information about operations.\n\t\tcontextFactory.updateRelation( opA, opB );\n\n\t\tcontextFactory.setOriginalOperations( newOpsA, opA );\n\t\tcontextFactory.setOriginalOperations( newOpsB, opB );\n\n\t\t// For new `a` operations, update their index of the next operation `b` to transform them by.\n\t\t//\n\t\t// This is needed even if there was only one result (`a` was not broken) because that information is used\n\t\t// at the beginning of this loop every time.\n\t\tfor ( const newOpA of newOpsA ) {\n\t\t\t// Acknowledge, that operation `b` also might be broken into multiple operations.\n\t\t\t//\n\t\t\t// This is why we raise `indexB` not just by 1. If `newOpsB` are multiple operations, they will be\n\t\t\t// spliced in the place of `opB`. So we need to change `transformBy` accordingly, so that an operation won't\n\t\t\t// be transformed by the same operation (part of it) again.\n\t\t\tnextTransformIndex.set( newOpA, indexB + newOpsB.length );\n\t\t}\n\n\t\t// Update `operationsA` and `operationsB` with the transformed versions.\n\t\toperationsA.splice( i, 1, ...newOpsA );\n\t\toperationsB.splice( indexB, 1, ...newOpsB );\n\t}\n\n\thandlePartialMarkerOperations( operationsA );\n\thandlePartialMarkerOperations( operationsB );\n\n\tif ( options.padWithNoOps ) {\n\t\t// If no-operations padding is enabled, count how many extra `a` and `b` operations were generated.\n\t\tconst brokenOperationsACount = operationsA.length - data.originalOperationsACount;\n\t\tconst brokenOperationsBCount = operationsB.length - data.originalOperationsBCount;\n\n\t\t// Then, if that number is not the same, pad `operationsA` or `operationsB` with correct number of no-ops so\n\t\t// that the base versions are equalled.\n\t\t//\n\t\t// Note that only one array will be updated, as only one of those subtractions can be greater than zero.\n\t\tpadWithNoOps( operationsA, brokenOperationsBCount - brokenOperationsACount );\n\t\tpadWithNoOps( operationsB, brokenOperationsACount - brokenOperationsBCount );\n\t}\n\n\t// Finally, update base versions of transformed operations.\n\tupdateBaseVersions( operationsA, data.nextBaseVersionB );\n\tupdateBaseVersions( operationsB, data.nextBaseVersionA );\n\n\treturn { operationsA, operationsB, originalOperations };\n}\n\n/**\n * The result of {@link module:engine/model/operation/transform~transformSets}.\n */\nexport interface TransformSetsResult {\n\n\t/**\n\t * Transformed `operationsA`.\n\t */\n\toperationsA: Array<Operation>;\n\n\t/**\n\t * Transformed `operationsB`.\n\t */\n\toperationsB: Array<Operation>;\n\n\t/**\n\t * A map that links transformed operations to original operations. The keys are the transformed\n\t * operations and the values are the original operations from the input (`operationsA` and `operationsB`).\n\t */\n\toriginalOperations: Map<Operation, Operation>;\n}\n\n/**\n * Gathers additional data about operations processed during transformation. Can be used to obtain contextual information\n * about two operations that are about to be transformed. This contextual information can be used for better conflict resolution.\n */\nclass ContextFactory {\n\tpublic readonly originalOperations: Map<Operation, Operation>;\n\n\tprivate readonly _history: History;\n\tprivate readonly _useRelations?: boolean;\n\tprivate readonly _forceWeakRemove: boolean;\n\tprivate readonly _relations: Map<Operation, Map<Operation, any>>;\n\n\t/**\n\t * Creates `ContextFactory` instance.\n\t *\n\t * @param document Document which the operations change.\n\t * @param useRelations Whether during transformation relations should be used (used during undo for\n\t * better conflict resolution).\n\t * @param forceWeakRemove If set to `false`, remove operation will be always stronger than move operation,\n\t * so the removed nodes won't end up back in the document root. When set to `true`, context data will be used.\n\t */\n\tconstructor( document: Document, useRelations: boolean | undefined, forceWeakRemove = false ) {\n\t\t// For each operation that is created during transformation process, we keep a reference to the original operation\n\t\t// which it comes from. The original operation works as a kind of \"identifier\". Every contextual information\n\t\t// gathered during transformation that we want to save for given operation, is actually saved for the original operation.\n\t\t// This way no matter if operation `a` is cloned, then transformed, even breaks, we still have access to the previously\n\t\t// gathered data through original operation reference.\n\t\tthis.originalOperations = new Map();\n\n\t\t// `model.History` instance which information about undone operations will be taken from.\n\t\tthis._history = document.history;\n\n\t\t// Whether additional context should be used.\n\t\tthis._useRelations = useRelations;\n\n\t\tthis._forceWeakRemove = !!forceWeakRemove;\n\n\t\t// Relations is a double-map structure (maps in map) where for two operations we store how those operations were related\n\t\t// to each other. Those relations are evaluated during transformation process. For every transformated pair of operations\n\t\t// we keep relations between them.\n\t\tthis._relations = new Map();\n\t}\n\n\t/**\n\t * Sets \"original operation\" for given operations.\n\t *\n\t * During transformation process, operations are cloned, then changed, then processed again, sometimes broken into two\n\t * or multiple operations. When gathering additional data it is important that all operations can be somehow linked\n\t * so a cloned and transformed \"version\" still kept track of the data assigned earlier to it.\n\t *\n\t * The original operation object will be used as such an universal linking id. Throughout the transformation process\n\t * all cloned operations will refer to \"the original operation\" when storing and reading additional data.\n\t *\n\t * If `takeFrom` is not set, each operation from `operations` array will be assigned itself as \"the original operation\".\n\t * This should be used as an initialization step.\n\t *\n\t * If `takeFrom` is set, each operation from `operations` will be assigned the same original operation as assigned\n\t * for `takeFrom` operation. This should be used to update original operations. It should be used in a way that\n\t * `operations` are the result of `takeFrom` transformation to ensure proper \"original operation propagation\".\n\t */\n\tpublic setOriginalOperations( operations: Array<Operation>, takeFrom: Operation | null = null ): void {\n\t\tconst originalOperation = takeFrom ? this.originalOperations.get( takeFrom ) : null;\n\n\t\tfor ( const operation of operations ) {\n\t\t\tthis.originalOperations.set( operation, originalOperation || operation );\n\t\t}\n\t}\n\n\t/**\n\t * Saves a relation between operations `opA` and `opB`.\n\t *\n\t * Relations are then later used to help solve conflicts when operations are transformed.\n\t */\n\tpublic updateRelation( opA: Operation, opB: Operation ): void {\n\t\t// The use of relations is described in a bigger detail in transformation functions.\n\t\t//\n\t\t// In brief, this function, for specified pairs of operation types, checks how positions defined in those operations relate.\n\t\t// Then those relations are saved. For example, for two move operations, it is saved if one of those operations target\n\t\t// position is before the other operation source position. This kind of information gives contextual information when\n\t\t// transformation is used during undo. Similar checks are done for other pairs of operations.\n\t\t//\n\t\tif ( opA instanceof MoveOperation ) {\n\t\t\tif ( opB instanceof MergeOperation ) {\n\t\t\t\tif ( opA.targetPosition.isEqual( opB.sourcePosition ) || opB.movedRange.containsPosition( opA.targetPosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'insertAtSource' );\n\t\t\t\t} else if ( opA.targetPosition.isEqual( opB.deletionPosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'insertBetween' );\n\t\t\t\t} else if ( opA.targetPosition.isAfter( opB.sourcePosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'moveTargetAfter' );\n\t\t\t\t}\n\t\t\t} else if ( opB instanceof MoveOperation ) {\n\t\t\t\tif ( opA.targetPosition.isEqual( opB.sourcePosition ) || opA.targetPosition.isBefore( opB.sourcePosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'insertBefore' );\n\t\t\t\t} else {\n\t\t\t\t\tthis._setRelation( opA, opB, 'insertAfter' );\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( opA instanceof SplitOperation ) {\n\t\t\tif ( opB instanceof MergeOperation ) {\n\t\t\t\tif ( opA.splitPosition.isBefore( opB.sourcePosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'splitBefore' );\n\t\t\t\t}\n\t\t\t} else if ( opB instanceof MoveOperation ) {\n\t\t\t\tif ( opA.splitPosition.isEqual( opB.sourcePosition ) || opA.splitPosition.isBefore( opB.sourcePosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'splitBefore' );\n\t\t\t\t} else {\n\t\t\t\t\tconst range = Range._createFromPositionAndShift( opB.sourcePosition, opB.howMany );\n\n\t\t\t\t\tif ( opA.splitPosition.hasSameParentAs( opB.sourcePosition ) && range.containsPosition( opA.splitPosition ) ) {\n\t\t\t\t\t\t// TODO: Potential bug -- we are saving offset value directly and it is not later updated during OT.\n\t\t\t\t\t\t// TODO: This may cause a bug it here was an non-undone operation that may have impacted this offset.\n\t\t\t\t\t\t// TODO: Similar error was with MarkerOperation relations, where full path was saved and never updated.\n\t\t\t\t\t\tconst howMany = range.end.offset - opA.splitPosition.offset;\n\t\t\t\t\t\tconst offset = opA.splitPosition.offset - range.start.offset;\n\n\t\t\t\t\t\tthis._setRelation( opA, opB, { howMany, offset } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( opA instanceof MergeOperation ) {\n\t\t\tif ( opB instanceof MergeOperation ) {\n\t\t\t\tif ( !opA.targetPosition.isEqual( opB.sourcePosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'mergeTargetNotMoved' );\n\t\t\t\t}\n\n\t\t\t\tif ( opA.sourcePosition.isEqual( opB.targetPosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'mergeSourceNotMoved' );\n\t\t\t\t}\n\n\t\t\t\tif ( opA.sourcePosition.isEqual( opB.sourcePosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'mergeSameElement' );\n\t\t\t\t}\n\t\t\t} else if ( opB instanceof SplitOperation ) {\n\t\t\t\tif ( opA.sourcePosition.isEqual( opB.splitPosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'splitAtSource' );\n\t\t\t\t}\n\t\t\t} else if ( opB instanceof MoveOperation && opB.howMany > 0 ) {\n\t\t\t\tif ( opA.sourcePosition.isEqual( opB.sourcePosition.getShiftedBy( opB.howMany ) ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'mergeSourceAffected' );\n\t\t\t\t}\n\n\t\t\t\tif ( opA.targetPosition.isEqual( opB.sourcePosition ) ) {\n\t\t\t\t\tthis._setRelation( opA, opB, 'mergeTargetWasBefore' );\n\t\t\t\t}\n\t\t\t}\n\t\t} else if ( opA instanceof MarkerOperation ) {\n\t\t\tconst markerRange = opA.newRange;\n\n\t\t\tif ( !markerRange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( opB instanceof MergeOperation ) {\n\t\t\t\tconst wasInLeftElement = markerRange.start.isEqual( opB.targetPosition );\n\t\t\t\tconst wasStartBeforeMergedElement = markerRange.start.isEqual( opB.deletionPosition );\n\t\t\t\tconst wasEndBeforeMergedElement = markerRange.end.isEqual( opB.deletionPosition );\n\t\t\t\tconst wasInRightElement = markerRange.end.isEqual( opB.sourcePosition );\n\n\t\t\t\tif ( wasInLeftElement || wasStartBeforeMergedElement || wasEndBeforeMergedElement || wasInRightElement ) {\n\t\t\t\t\tthis._setRelation( opA, opB, {\n\t\t\t\t\t\twasInLeftElement,\n\t\t\t\t\t\twasStartBeforeMergedElement,\n\t\t\t\t\t\twasEndBeforeMergedElement,\n\t\t\t\t\t\twasInRightElement\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Evaluates and returns contextual information about two given operations `opA` and `opB` which are about to be transformed.\n\t */\n\tpublic getContext( opA: Operation, opB: Operation, aIsStrong: boolean ): TransformationContext {\n\t\treturn {\n\t\t\taIsStrong,\n\t\t\taWasUndone: this._wasUndone( opA ),\n\t\t\tbWasUndone: this._wasUndone( opB ),\n\t\t\tabRelation: this._useRelations ? this._getRelation( opA, opB ) : null,\n\t\t\tbaRelation: this._useRelations ? this._getRelation( opB, opA ) : null,\n\t\t\tforceWeakRemove: this._forceWeakRemove\n\t\t};\n\t}\n\n\t/**\n\t * Returns whether given operation `op` has already been undone.\n\t *\n\t * Information whether an operation was undone gives more context when making a decision when two operations are in conflict.\n\t */\n\tpublic _wasUndone( op: Operation ): boolean {\n\t\t// For `op`, get its original operation. After all, if `op` is a clone (or even transformed clone) of another\n\t\t// operation, literally `op` couldn't be undone. It was just generated. If anything, it was the operation it origins\n\t\t// from which was undone. So get that original operation.\n\t\tconst originalOp = this.originalOperations.get( op )!;\n\n\t\t// And check with the document if the original operation was undone.\n\t\treturn ( originalOp as any ).wasUndone || this._history.isUndoneOperation( originalOp );\n\t}\n\n\t/**\n\t * Returns a relation between `opA` and an operation which is undone by `opB`. This can be `String` value if a relation\n\t * was set earlier or `null` if there was no relation between those operations.\n\t *\n\t * This is a little tricky to understand, so let's compare it to `ContextFactory#_wasUndone`.\n\t *\n\t * When `wasUndone( opB )` is used, we check if the `opB` has already been undone. It is obvious, that the\n\t * undoing operation must happen after the undone operation. So, essentially, we have `opB`, we take document history,\n\t * we look forward in the future and ask if in that future `opB` was undone.\n\t *\n\t * Relations is a backward process to `wasUndone()`.\n\t *\n\t * Long story short - using relations is asking what happened in the past. Looking back. This time we have an undoing\n\t * operation `opB` which has undone some other operation. When there is a transformation `opA` x `opB` and there is\n\t * a conflict to solve and `opB` is an undoing operation, we can look back in the history and see what was a relation\n\t * between `opA` and the operation which `opB` undone. Basing on that relation from the past, we can now make\n\t * a better decision when resolving a conflict between two operations, because we know more about the context of\n\t * those two operations.\n\t *\n\t * This is why this function does not return a relation directly between `opA` and `opB` because we need to look\n\t * back to search for a meaningful contextual information.\n\t */\n\tpublic _getRelation( opA: Operation, opB: Operation ): any {\n\t\t// Get the original operation. Similarly as in `wasUndone()` it is used as an universal identifier for stored data.\n\t\tconst origB = this.originalOperations.get( opB )!;\n\t\tconst undoneB = this._history.getUndoneOperation( origB );\n\n\t\t// If `opB` is not undoing any operation, there is no relation.\n\t\tif ( !undoneB ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst origA = this.originalOperations.get( opA )!;\n\t\tconst relationsA = this._relations.get( origA );\n\n\t\t// Get all relations for `opA`, and check if there is a relation with `opB`-undone-counterpart. If so, return it.\n\t\tif ( relationsA ) {\n\t\t\treturn relationsA.get( undoneB ) || null;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Helper function for `ContextFactory#updateRelations`.\n\t */\n\tprivate _setRelation( opA: Operation, opB: Operation, relation: any ): void {\n\t\t// As always, setting is for original operations, not the clones/transformed operations.\n\t\tconst origA = this.originalOperations.get( opA )!;\n\t\tconst origB = this.originalOperations.get( opB )!;\n\n\t\tlet relationsA = this._relations.get( origA );\n\n\t\tif ( !relationsA ) {\n\t\t\trelationsA = new Map();\n\t\t\tthis._relations.set( origA, relationsA );\n\t\t}\n\n\t\trelationsA.set( origB, relation );\n\t}\n}\n\n/**\n * Holds additional contextual information about a transformed pair of operations (`a` and `b`). Those information\n * can be used for better conflict resolving.\n */\n\nexport type TransformationContext = {\n\n\t/**\n\t * Whether `a` is strong operation in this transformation, or weak.\n\t */\n\taIsStrong?: boolean;\n\n\t/**\n\t * Whether `a` operation was undone.\n\t */\n\taWasUndone?: boolean;\n\n\t/**\n\t * Whether `b` operation was undone.\n\t */\n\tbWasUndone?: boolean;\n\n\t/**\n\t * The relation between `a` operation and an operation undone by `b` operation.\n\t */\n\tabRelation?: any;\n\n\t/**\n\t * The relation between `b` operation and an operation undone by `a` operation.\n\t */\n\tbaRelation?: any;\n\n\tforceWeakRemove?: boolean;\n};\n\n/**\n * An utility function that updates {@link module:engine/model/operation/operation~Operation#baseVersion base versions}\n * of passed operations.\n *\n * The function simply sets `baseVersion` as a base version of the first passed operation and then increments it for\n * each following operation in `operations`.\n *\n * @param operations Operations to update.\n * @param baseVersion Base version to set for the first operation in `operations`.\n */\nfunction updateBaseVersions( operations: ReadonlyArray<Operation>, baseVersion: number ) {\n\tfor ( const operation of operations ) {\n\t\toperation.baseVersion = baseVersion++;\n\t}\n}\n\n/**\n * Adds `howMany` instances of {@link module:engine/model/operation/nooperation~NoOperation} to `operations` set.\n */\nfunction padWithNoOps( operations: Array<Operation>, howMany: number ) {\n\tfor ( let i = 0; i < howMany; i++ ) {\n\t\toperations.push( new NoOperation( 0 ) );\n\t}\n}\n\n/**\n * Transformed operations set may include marker operations which were broken into multiple marker operations during transformation.\n * It represents marker range being broken into multiple pieces as the transformation was processed. Each partial marker operation is\n * a piece of the original marker range.\n *\n * These partial marker operations (\"marker range pieces\") should be \"glued\" together if, after transformations, the ranges ended up\n * next to each other.\n *\n * If the ranges did not end up next to each other, then partial marker operations should be discarded, as the marker range cannot\n * be broken into two pieces.\n *\n * There is always one \"reference\" marker operation (the original operation) and there may be some partial marker operations. Partial\n * marker operations have base version set to `-1`. If the `operations` set includes partial marker operations, then they are always\n * after the original marker operation.\n *\n * See also `MarkerOperation` x `MoveOperation` transformation.\n * See also https://github.com/ckeditor/ckeditor5/pull/17071.\n */\nfunction handlePartialMarkerOperations( operations: Array<Operation> ) {\n\tconst markerOps: Map<string, { op: MarkerOperation; ranges: Array<Range> }> = new Map();\n\n\tfor ( let i = 0; i < operations.length; i++ ) {\n\t\tconst op = operations[ i ];\n\n\t\tif ( !( op instanceof MarkerOperation ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ( op.baseVersion !== -1 ) {\n\t\t\tmarkerOps.set( op.name, {\n\t\t\t\top,\n\t\t\t\tranges: op.newRange ? [ op.newRange ] : []\n\t\t\t} );\n\t\t} else {\n\t\t\tif ( op.newRange ) {\n\t\t\t\t// `markerOps.get( op.name )` must exist because original marker operation is always before partial marker operations.\n\t\t\t\t// If the original marker operation was changed to `NoOperation`, then the partial marker operations would be changed\n\t\t\t\t// to `NoOperation` as well, so this is not a case.\n\t\t\t\tmarkerOps.get( op.name )!.ranges.push( op.newRange );\n\t\t\t}\n\n\t\t\toperations.splice( i, 1 );\n\t\t\ti--;\n\t\t}\n\t}\n\n\tfor ( const { op, ranges } of markerOps.values() ) {\n\t\tif ( ranges.length ) {\n\t\t\top.newRange = Range._createFromRanges( ranges );\n\t\t} else {\n\t\t\top.newRange = null;\n\t\t}\n\t}\n}\n\n// -----------------------\n\nsetTransformation( AttributeOperation, AttributeOperation, ( a, b, context ) => {\n\t// If operations in conflict, check if their ranges intersect and manage them properly.\n\t//\n\t// Operations can be in conflict only if:\n\t//\n\t// * their key is the same (they change the same attribute), and\n\t// * they are in the same parent (operations for ranges [ 1 ] - [ 3 ] and [ 2, 0 ] - [ 2, 5 ] change different\n\t// elements and can't be in conflict).\n\tif ( a.key === b.key && a.range.start.hasSameParentAs( b.range.start ) ) {\n\t\t// First, we want to apply change to the part of a range that has not been changed by the other operation.\n\t\tconst operations = a.range.getDifference( b.range ).map( range => {\n\t\t\treturn new AttributeOperation( range, a.key, a.oldValue, a.newValue, 0 );\n\t\t} );\n\n\t\t// Then we take care of the common part of ranges.\n\t\tconst common = a.range.getIntersection( b.range );\n\n\t\tif ( common ) {\n\t\t\t// If this operation is more important, we also want to apply change to the part of the\n\t\t\t// original range that has already been changed by the other operation. Since that range\n\t\t\t// got changed we also have to update `oldValue`.\n\t\t\tif ( context.aIsStrong ) {\n\t\t\t\toperations.push( new AttributeOperation( common, b.key, b.newValue, a.newValue, 0 ) );\n\t\t\t}\n\t\t}\n\n\t\tif ( operations.length == 0 ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\n\t\treturn operations;\n\t} else {\n\t\t// If operations don't conflict, simply return an array containing just a clone of this operation.\n\t\treturn [ a ];\n\t}\n} );\n\nsetTransformation( AttributeOperation, InsertOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// The attribute operation range includes the position where nodes were inserted.\n\t// There are two possible scenarios: the inserted nodes were text and they should receive attributes or\n\t// the inserted nodes were elements and they should not receive attributes.\n\t//\n\tif ( a.range.start.hasSameParentAs( b.position ) && a.range.containsPosition( b.position ) ) {\n\t\t// If new nodes should not receive attributes, two separated ranges will be returned.\n\t\t// Otherwise, one expanded range will be returned.\n\t\tconst range = a.range._getTransformedByInsertion( b.position, b.howMany, !b.shouldReceiveAttributes );\n\t\tconst result = range.map( r => {\n\t\t\treturn new AttributeOperation( r, a.key, a.oldValue, a.newValue, a.baseVersion );\n\t\t} );\n\n\t\tif ( b.shouldReceiveAttributes ) {\n\t\t\t// `AttributeOperation#range` includes some newly inserted text.\n\t\t\t// The operation should also change the attribute of that text. An example:\n\t\t\t//\n\t\t\t// Bold should be applied on the following range:\n\t\t\t// <p>Fo[zb]ar</p>\n\t\t\t//\n\t\t\t// In meantime, new text is typed:\n\t\t\t// <p>Fozxxbar</p>\n\t\t\t//\n\t\t\t// Bold should be applied also on the new text:\n\t\t\t// <p>Fo[zxxb]ar</p>\n\t\t\t// <p>Fo<$text bold=\"true\">zxxb</$text>ar</p>\n\t\t\t//\n\t\t\t// There is a special case to consider here to consider.\n\t\t\t//\n\t\t\t// Consider setting an attribute with multiple possible values, for example `highlight`. The inserted text might\n\t\t\t// have already an attribute value applied and the `oldValue` property of the attribute operation might be wrong:\n\t\t\t//\n\t\t\t// Attribute `highlight=\"yellow\"` should be applied on the following range:\n\t\t\t// <p>Fo[zb]ar<p>\n\t\t\t//\n\t\t\t// In meantime, character `x` with `highlight=\"red\"` is typed:\n\t\t\t// <p>Fo[z<$text highlight=\"red\">x</$text>b]ar</p>\n\t\t\t//\n\t\t\t// In this case we cannot simply apply operation changing the attribute value from `null` to `\"yellow\"` for the whole range\n\t\t\t// because that would lead to an exception (`oldValue` is incorrect for `x`).\n\t\t\t//\n\t\t\t// We also cannot break the original range as this would mess up a scenario when there are multiple following\n\t\t\t// insert operations, because then only the first inserted character is included in those ranges:\n\t\t\t// <p>Fo[z][x][b]ar</p>   -->   <p>Fo[z][x]x[b]ar</p>   -->   <p>Fo[z][x]xx[b]ar</p>\n\t\t\t//\n\t\t\t// So, the attribute range needs be expanded, no matter what attributes are set on the inserted nodes:\n\t\t\t//\n\t\t\t// <p>Fo[z<$text highlight=\"red\">x</$text>b]ar</p>      <--- Change from `null` to `yellow`, throwing an exception.\n\t\t\t//\n\t\t\t// But before that operation would be applied, we will add an additional attribute operation that will change\n\t\t\t// attributes on the inserted nodes in a way which would make the original operation correct:\n\t\t\t//\n\t\t\t// <p>Fo[z{<$text highlight=\"red\">}x</$text>b]ar</p>    <--- Change range `{}` from `red` to `null`.\n\t\t\t// <p>Fo[zxb]ar</p>                                     <--- Now change from `null` to `yellow` is completely fine.\n\t\t\t//\n\n\t\t\t// Generate complementary attribute operation. Be sure to add it before the original operation.\n\t\t\tconst op = _getComplementaryAttributeOperations( b, a.key, a.oldValue );\n\n\t\t\tif ( op ) {\n\t\t\t\tresult.unshift( op );\n\t\t\t}\n\t\t}\n\n\t\t// If nodes should not receive new attribute, we are done here.\n\t\treturn result;\n\t}\n\n\t// If insert operation is not expanding the attribute operation range, simply transform the range.\n\ta.range = a.range._getTransformedByInsertion( b.position, b.howMany, false )[ 0 ];\n\n\treturn [ a ];\n} );\n\n/**\n * Helper function for `AttributeOperation` x `InsertOperation` (and reverse) transformation.\n *\n * For given `insertOperation` it checks the inserted node if it has an attribute `key` set to a value different\n * than `newValue`. If so, it generates an `AttributeOperation` which changes the value of `key` attribute to `newValue`.\n */\nfunction _getComplementaryAttributeOperations( insertOperation: InsertOperation, key: string, newValue: unknown ) {\n\tconst nodes = insertOperation.nodes;\n\n\t// At the beginning we store the attribute value from the first node.\n\tconst insertValue = nodes.getNode( 0 )!.getAttribute( key );\n\n\tif ( insertValue == newValue ) {\n\t\treturn null;\n\t}\n\n\tconst range = new Range( insertOperation.position, insertOperation.position.getShiftedBy( insertOperation.howMany ) );\n\n\treturn new AttributeOperation( range, key, insertValue, newValue, 0 );\n}\n\nsetTransformation( AttributeOperation, MergeOperation, ( a, b ) => {\n\tconst ranges = [];\n\n\t// Case 1:\n\t//\n\t// Attribute change on the merged element. In this case, the merged element was moved to the graveyard.\n\t// An additional attribute operation that will change the (re)moved element needs to be generated.\n\t//\n\tif ( a.range.start.hasSameParentAs( b.deletionPosition ) ) {\n\t\tif ( a.range.containsPosition( b.deletionPosition ) || a.range.start.isEqual( b.deletionPosition ) ) {\n\t\t\tranges.push( Range._createFromPositionAndShift( b.graveyardPosition, 1 ) );\n\t\t}\n\t}\n\n\tconst range = a.range._getTransformedByMergeOperation( b );\n\n\t// Do not add empty (collapsed) ranges to the result. `range` may be collapsed if it contained only the merged element.\n\tif ( !range.isCollapsed ) {\n\t\tranges.push( range );\n\t}\n\n\t// Create `AttributeOperation`s out of the ranges.\n\treturn ranges.map( range => {\n\t\treturn new AttributeOperation( range, a.key, a.oldValue, a.newValue, a.baseVersion );\n\t} );\n} );\n\nsetTransformation( AttributeOperation, MoveOperation, ( a, b ) => {\n\tconst ranges = _breakRangeByMoveOperation( a.range, b );\n\n\t// Create `AttributeOperation`s out of the ranges.\n\treturn ranges.map( range => new AttributeOperation( range, a.key, a.oldValue, a.newValue, a.baseVersion ) );\n} );\n\n/**\n * Helper function for `AttributeOperation` x `MoveOperation` transformation.\n *\n * Takes the passed `range` and transforms it by move operation `moveOp` in a specific way. Only top-level nodes of `range`\n * are considered to be in the range. If move operation moves nodes deep from inside of the range, those nodes won't\n * be included in the result. In other words, top-level nodes of the ranges from the result are exactly the same as\n * top-level nodes of the original `range`.\n *\n * This is important for `AttributeOperation` because, for its range, it changes only the top-level nodes. So we need to\n * track only how those nodes have been affected by `MoveOperation`.\n */\nfunction _breakRangeByMoveOperation( range: Range, moveOp: MoveOperation ) {\n\tconst moveRange = Range._createFromPositionAndShift( moveOp.sourcePosition, moveOp.howMany );\n\n\t// We are transforming `range` (original range) by `moveRange` (range moved by move operation). As usual when it comes to\n\t// transforming a ranges, we may have a common part of the ranges and we may have a difference part (zero to two ranges).\n\tlet common = null;\n\tlet difference: Array<Range> = [];\n\n\t// Let's compare the ranges.\n\tif ( moveRange.containsRange( range, true ) ) {\n\t\t// If the whole original range is moved, treat it whole as a common part. There's also no difference part.\n\t\tcommon = range;\n\t} else if ( range.start.hasSameParentAs( moveRange.start ) ) {\n\t\t// If the ranges are \"on the same level\" (in the same parent) then move operation may move exactly those nodes\n\t\t// that are changed by the attribute operation. In this case we get common part and difference part in the usual way.\n\t\tdifference = range.getDifference( moveRange );\n\t\tcommon = range.getIntersection( moveRange );\n\t} else {\n\t\t// In any other situation we assume that original range is different than move range, that is that move operation\n\t\t// moves other nodes that attribute operation change. Even if the moved range is deep inside in the original range.\n\t\t//\n\t\t// Note that this is different than in `.getIntersection` (we would get a common part in that case) and different\n\t\t// than `.getDifference` (we would get two ranges).\n\t\tdifference = [ range ];\n\t}\n\n\tconst result: Array<Range> = [];\n\n\t// The default behaviour of `_getTransformedByMove` might get wrong results for difference part, though, so\n\t// we do it by hand.\n\tfor ( let diff of difference ) {\n\t\t// First, transform the range by removing moved nodes. Since this is a difference, this is safe, `null` won't be returned\n\t\t// as the range is different than the moved range.\n\t\tdiff = diff._getTransformedByDeletion( moveOp.sourcePosition, moveOp.howMany )!;\n\n\t\t// Transform also `targetPosition`.\n\t\tconst targetPosition = moveOp.getMovedRangeStart();\n\n\t\t// Spread the range only if moved nodes are inserted only between the top-level nodes of the `diff` range.\n\t\tconst spread = diff.start.hasSameParentAs( targetPosition );\n\n\t\t// Transform by insertion of moved nodes.\n\t\tconst diffs = diff._getTransformedByInsertion( targetPosition, moveOp.howMany, spread );\n\n\t\tresult.push( ...diffs );\n\t}\n\n\t// Common part can be simply transformed by the move operation. This is because move operation will not target to\n\t// that common part (the operation would have to target inside its own moved range).\n\tif ( common ) {\n\t\tresult.push(\n\t\t\tcommon._getTransformedByMove( moveOp.sourcePosition, moveOp.targetPosition, moveOp.howMany, false )[ 0 ]\n\t\t);\n\t}\n\n\treturn result;\n}\n\nsetTransformation( AttributeOperation, SplitOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// Split node is the last node in `AttributeOperation#range`.\n\t// `AttributeOperation#range` needs to be expanded to include the new (split) node.\n\t//\n\t// Attribute `type` to be changed to `numbered` but the `listItem` is split.\n\t// <listItem type=\"bulleted\">foobar</listItem>\n\t//\n\t// After split:\n\t// <listItem type=\"bulleted\">foo</listItem><listItem type=\"bulleted\">bar</listItem>\n\t//\n\t// After attribute change:\n\t// <listItem type=\"numbered\">foo</listItem><listItem type=\"numbered\">foo</listItem>\n\t//\n\tif ( a.range.end.isEqual( b.insertionPosition ) ) {\n\t\tif ( !b.graveyardPosition ) {\n\t\t\ta.range.end.offset++;\n\t\t}\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 2:\n\t//\n\t// Split position is inside `AttributeOperation#range`, at the same level, so the nodes to change are\n\t// not going to make a flat range.\n\t//\n\t// Content with range-to-change and split position:\n\t// <p>Fo[zb^a]r</p>\n\t//\n\t// After split:\n\t// <p>Fozb</p><p>ar</p>\n\t//\n\t// Make two separate ranges containing all nodes to change:\n\t// <p>Fo[zb]</p><p>[a]r</p>\n\t//\n\tif ( a.range.start.hasSameParentAs( b.splitPosition ) && a.range.containsPosition( b.splitPosition ) ) {\n\t\tconst secondPart = a.clone();\n\n\t\tsecondPart.range = new Range(\n\t\t\tb.moveTargetPosition.clone(),\n\t\t\ta.range.end._getCombined( b.splitPosition, b.moveTargetPosition )\n\t\t);\n\n\t\t( a.range as any ).end = b.splitPosition.clone();\n\t\ta.range.end.stickiness = 'toPrevious';\n\n\t\treturn [ a, secondPart ];\n\t}\n\n\t// The default case.\n\t//\n\ta.range = a.range._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, AttributeOperation, ( a, b ) => {\n\tconst result: Array<Operation> = [ a ];\n\n\t// Case 1:\n\t//\n\t// The attribute operation range includes the position where nodes were inserted.\n\t// There are two possible scenarios: the inserted nodes were text and they should receive attributes or\n\t// the inserted nodes were elements and they should not receive attributes.\n\t//\n\t// This is a mirror scenario to the one described in `AttributeOperation` x `InsertOperation` transformation,\n\t// although this case is a little less complicated. In this case we simply need to change attributes of the\n\t// inserted nodes and that's it.\n\t//\n\tif ( a.shouldReceiveAttributes && a.position.hasSameParentAs( b.range.start ) && b.range.containsPosition( a.position ) ) {\n\t\tconst op = _getComplementaryAttributeOperations( a, b.key, b.newValue );\n\n\t\tif ( op ) {\n\t\t\tresult.push( op );\n\t\t}\n\t}\n\n\t// The default case is: do nothing.\n\t// `AttributeOperation` does not change the model tree structure so `InsertOperation` does not need to be changed.\n\t//\n\treturn result;\n} );\n\nsetTransformation( InsertOperation, InsertOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Two insert operations insert nodes at the same position. Since they are the same, it needs to be decided\n\t// what will be the order of inserted nodes. However, there is no additional information to help in that\n\t// decision. Also, when `b` will be transformed by `a`, the same order must be maintained.\n\t//\n\t// To achieve that, we will check if the operation is strong.\n\t// If it is, it won't get transformed. If it is not, it will be moved.\n\t//\n\tif ( a.position.isEqual( b.position ) && context.aIsStrong ) {\n\t\treturn [ a ];\n\t}\n\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedByInsertOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, MoveOperation, ( a, b ) => {\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedByMoveOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, SplitOperation, ( a, b ) => {\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( InsertOperation, MergeOperation, ( a, b ) => {\n\ta.position = a.position._getTransformedByMergeOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( MarkerOperation, InsertOperation, ( a, b ) => {\n\tif ( a.oldRange ) {\n\t\ta.oldRange = a.oldRange._getTransformedByInsertOperation( b )[ 0 ];\n\t}\n\n\tif ( a.newRange ) {\n\t\ta.newRange = a.newRange._getTransformedByInsertOperation( b )[ 0 ];\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MarkerOperation, MarkerOperation, ( a, b, context ) => {\n\tif ( a.name == b.name ) {\n\t\tif ( context.aIsStrong ) {\n\t\t\ta.oldRange = b.newRange ? b.newRange.clone() : null;\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MarkerOperation, MergeOperation, ( a, b ) => {\n\tif ( a.oldRange ) {\n\t\ta.oldRange = a.oldRange._getTransformedByMergeOperation( b );\n\t}\n\n\tif ( a.newRange ) {\n\t\ta.newRange = a.newRange._getTransformedByMergeOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MarkerOperation, MoveOperation, ( a, b ) => {\n\tconst result = [ a ];\n\n\tif ( a.oldRange ) {\n\t\ta.oldRange = Range._createFromRanges( a.oldRange._getTransformedByMoveOperation( b ) );\n\t}\n\n\tif ( a.newRange ) {\n\t\t// In many simple cases the marker range will be kept integral after the transformation. For example, if some nodes\n\t\t// were inserted before the range, or into the range, then the marker range is not broken into two.\n\t\t//\n\t\t// However, if some nodes are taken out of the range and moved somewhere else, or are moved into the range, then the marker\n\t\t// range is \"broken\" into two or three pieces, and these pieces must be transformed and updated separately.\n\t\t//\n\t\t// When the marker range is transformed by move operation, as a result we get an array with one (simple case) or multiple\n\t\t// (\"broken range\" case) ranges.\n\t\tconst ranges = a.newRange._getTransformedByMoveOperation( b );\n\n\t\ta.newRange = ranges[ 0 ];\n\n\t\t// If there are multiple ranges, we will create separate marker operations for each piece of the original marker range.\n\t\t// Since they will be marker operations, they will be processed through the transformation process.\n\t\t//\n\t\t// However, we cannot create multiple ranges for the same marker (for the same marker name). A marker has only one range.\n\t\t// So, we cannot really have multiple marker operations for the same marker. We will keep the track of the separate marker\n\t\t// operations to see, if after all transformations, the marker pieces are next to each other or not. If so, we will glue\n\t\t// them together to the original marker operation (`a`). If not, we will discard them. These extra operations will never\n\t\t// be executed, as they will only exist temporarily during the transformation process.\n\t\t//\n\t\t// We will call these additional marker operations \"partial marker operations\" and we will mark them with negative base version.\n\t\t//\n\t\t// See also `handlePartialMarkerOperations()`.\n\t\t// See also https://github.com/ckeditor/ckeditor5/pull/17071.\n\t\t//\n\t\tfor ( let i = 1; i < ranges.length; i++ ) {\n\t\t\tconst op = a.clone();\n\n\t\t\top.oldRange = null;\n\t\t\top.newRange = ranges[ i ];\n\t\t\top.baseVersion = -1;\n\n\t\t\tresult.push( op );\n\t\t}\n\t}\n\n\treturn result;\n} );\n\nsetTransformation( MarkerOperation, SplitOperation, ( a, b, context ) => {\n\tif ( a.oldRange ) {\n\t\ta.oldRange = a.oldRange._getTransformedBySplitOperation( b );\n\t}\n\n\tif ( a.newRange ) {\n\t\tif ( context.abRelation ) {\n\t\t\tconst aNewRange = a.newRange._getTransformedBySplitOperation( b );\n\n\t\t\tif ( a.newRange.start.isEqual( b.splitPosition ) && context.abRelation.wasStartBeforeMergedElement ) {\n\t\t\t\t( a.newRange as any ).start = Position._createAt( b.insertionPosition );\n\t\t\t} else if ( a.newRange.start.isEqual( b.splitPosition ) && !context.abRelation.wasInLeftElement ) {\n\t\t\t\t( a.newRange as any ).start = Position._createAt( b.moveTargetPosition );\n\t\t\t} else {\n\t\t\t\t( a.newRange as any ).start = aNewRange.start;\n\t\t\t}\n\n\t\t\tif ( a.newRange.end.isEqual( b.splitPosition ) && context.abRelation.wasInRightElement ) {\n\t\t\t\t( a.newRange as any ).end = Position._createAt( b.moveTargetPosition );\n\t\t\t} else if ( a.newRange.end.isEqual( b.splitPosition ) && context.abRelation.wasEndBeforeMergedElement ) {\n\t\t\t\t( a.newRange as any ).end = Position._createAt( b.insertionPosition );\n\t\t\t} else {\n\t\t\t\t( a.newRange as any ).end = aNewRange.end;\n\t\t\t}\n\n\t\t\treturn [ a ];\n\t\t}\n\n\t\ta.newRange = a.newRange._getTransformedBySplitOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( MergeOperation, InsertOperation, ( a, b ) => {\n\tif ( a.sourcePosition.hasSameParentAs( b.position ) ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedByInsertOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedByInsertOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( MergeOperation, MergeOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Same merge operations.\n\t//\n\t// Both operations have same source and target positions. So the element already got merged and there is\n\t// theoretically nothing to do.\n\t//\n\tif ( a.sourcePosition.isEqual( b.sourcePosition ) && a.targetPosition.isEqual( b.targetPosition ) ) {\n\t\t// There are two ways that we can provide a do-nothing operation.\n\t\t//\n\t\t// First is simply a NoOperation instance. We will use it if `b` operation was not undone.\n\t\t//\n\t\t// Second is a merge operation that has the source operation in the merged element - in the graveyard -\n\t\t// same target position and `howMany` equal to `0`. So it is basically merging an empty element from graveyard\n\t\t// which is almost the same as NoOperation.\n\t\t//\n\t\t// This way the merge operation can be later transformed by split operation\n\t\t// to provide correct undo. This will be used if `b` operation was undone (only then it is correct).\n\t\t//\n\t\tif ( !context.bWasUndone ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t} else {\n\t\t\tconst path = b.graveyardPosition.path.slice();\n\t\t\tpath.push( 0 );\n\n\t\t\ta.sourcePosition = new Position( b.graveyardPosition.root, path );\n\t\t\ta.howMany = 0;\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// Case 2:\n\t//\n\t// Same merge source position but different target position.\n\t//\n\t// This can happen during collaboration. For example, if one client merged a paragraph to the previous paragraph\n\t// and the other person removed that paragraph and merged the same paragraph to something before:\n\t//\n\t// Client A:\n\t// <p>Foo</p><p>Bar</p><p>[]Xyz</p>\n\t// <p>Foo</p><p>BarXyz</p>\n\t//\n\t// Client B:\n\t// <p>Foo</p>[<p>Bar</p>]<p>Xyz</p>\n\t// <p>Foo</p><p>[]Xyz</p>\n\t// <p>FooXyz</p>\n\t//\n\t// In this case we need to decide where finally \"Xyz\" will land:\n\t//\n\t// <p>FooXyz</p>               graveyard: <p>Bar</p>\n\t// <p>Foo</p>                  graveyard: <p>BarXyz</p>\n\t//\n\t// Let's move it in a way so that a merge operation that does not target to graveyard is more important so that\n\t// nodes does not end up in the graveyard. It makes sense. Both for Client A and for Client B \"Xyz\" finally did not\n\t// end up in the graveyard (see above).\n\t//\n\t// If neither or both operations point to graveyard, then let `aIsStrong` decide.\n\t//\n\tif (\n\t\ta.sourcePosition.isEqual( b.sourcePosition ) && !a.targetPosition.isEqual( b.targetPosition ) &&\n\t\t!context.bWasUndone && context.abRelation != 'splitAtSource'\n\t) {\n\t\tconst aToGraveyard = a.targetPosition.root.rootName == '$graveyard';\n\t\tconst bToGraveyard = b.targetPosition.root.rootName == '$graveyard';\n\n\t\t// If `aIsWeak` it means that `a` points to graveyard while `b` doesn't. Don't move nodes then.\n\t\tconst aIsWeak = aToGraveyard && !bToGraveyard;\n\n\t\t// If `bIsWeak` it means that `b` points to graveyard while `a` doesn't. Force moving nodes then.\n\t\tconst bIsWeak = bToGraveyard && !aToGraveyard;\n\n\t\t// Force move if `b` is weak or neither operation is weak but `a` is stronger through `context.aIsStrong`.\n\t\tconst forceMove = bIsWeak || ( !aIsWeak && context.aIsStrong );\n\n\t\tif ( forceMove ) {\n\t\t\tconst sourcePosition = b.targetPosition._getTransformedByMergeOperation( b );\n\t\t\tconst targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\t\t\treturn [ new MoveOperation( sourcePosition, a.howMany, targetPosition, 0 ) ];\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\t// The default case.\n\t// TODO: Possibly, there's a missing case for same `targetPosition` but different `sourcePosition`.\n\t//\n\tif ( a.sourcePosition.hasSameParentAs( b.targetPosition ) ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedByMergeOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\t// Handle positions in graveyard.\n\t// If graveyard positions are same and `a` operation is strong - do not transform.\n\tif ( !a.graveyardPosition.isEqual( b.graveyardPosition ) || !context.aIsStrong ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MergeOperation, MoveOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// The element to merge got removed.\n\t//\n\t// Merge operation does support merging elements which are not siblings. So it would not be a problem\n\t// from technical point of view. However, if the element was removed, the intention of the user deleting it\n\t// was to have it all deleted, together with its children. From user experience point of view, moving back the\n\t// removed nodes might be unexpected. This means that in this scenario we will block the merging.\n\t//\n\t// The exception to this rule would be if the remove operation was later undone.\n\t//\n\tconst removedRange = Range._createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\tif ( b.type == 'remove' && !context.bWasUndone ) {\n\t\tif ( a.deletionPosition.hasSameParentAs( b.sourcePosition ) && removedRange.containsPosition( a.sourcePosition ) ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\t// In most cases we want `sourcePosition` to stick to previous and `targetPosition` to stick to next.\n\t// Usually, `sourcePosition` is at the beginning of the merged element and `targetPosition` is at the end of the merge-target element.\n\t//\n\t// However, `sourcePosition` and `targetPosition` may end up in the middle of an element due to some OT magic that happens during undo.\n\t// It is expected and used in `MergeOperation` x `SplitOperation` transformation.\n\t//\n\t// But when these positions are in the middle, it messes up the regular `MergeOperation` x `MoveOperation` transformation because\n\t// these positions may \"follow\" some moved elements. And we want them stick in the original elements.\n\t//\n\t// This is why we add two extra cases: (1) and (2).\n\t//\n\t// But after this `MergeOperation` is transformed by \"this\" move (which is undone), we also need to define extra cases for\n\t// the operation undoing previous move. These are (3) and (4).\n\t//\n\t// (1). Note that this case is also added to `updateRelations()` and sets `mergeSourceAffected` relation.\n\t//\n\t// [] is move operation, } is merge source position (sticks to previous by default):\n\t// <p>A[b]}c</p>  ->  <p>A}c</p>\n\t//\n\tif ( b.sourcePosition.getShiftedBy( b.howMany ).isEqual( a.sourcePosition ) ) {\n\t\ta.sourcePosition.stickiness = 'toNone';\n\t}\n\n\t// (3). This is the transformation for undoing operation of the above case.\n\t//\n\t// [] is move operation, } is merge source position (sticks to previous by default):\n\t// <p>A}c</p>  ->  <p>A[b]}c</p>  (instead of <p>A}[b]c</p>)\n\t//\n\telse if ( b.targetPosition.isEqual( a.sourcePosition ) && context.abRelation == 'mergeSourceAffected' ) {\n\t\ta.sourcePosition.stickiness = 'toNext';\n\t}\n\n\t// (2). Note that this case is also added to `updateRelations()` and sets `mergeTargetWasBefore` relation.\n\t//\n\t// [] is move operation, { is merge target position (sticks to next by default):\n\t// <p>A{[b]c</p>  ->  <p>A{c</p>\n\t//\n\telse if ( b.sourcePosition.isEqual( a.targetPosition ) ) {\n\t\ta.targetPosition.stickiness = 'toNone';\n\t\ta.howMany -= b.howMany;\n\t}\n\n\t// (4). This is the transformation for undoing operation of the above case.\n\t//\n\t// [] is move operation, { is merge target position (sticks to next by default):\n\t// <p>A{c</p>  ->  <p>A{[b]c</p>  (instead of <p>A[b]{c</p>)\n\t//\n\telse if ( b.targetPosition.isEqual( a.targetPosition ) && context.abRelation == 'mergeTargetWasBefore' ) {\n\t\ta.targetPosition.stickiness = 'toPrevious';\n\t\ta.howMany += b.howMany;\n\t}\n\n\t// The default case.\n\telse {\n\t\tif ( a.sourcePosition.hasSameParentAs( b.targetPosition ) ) {\n\t\t\ta.howMany += b.howMany;\n\t\t}\n\n\t\tif ( a.sourcePosition.hasSameParentAs( b.sourcePosition ) ) {\n\t\t\ta.howMany -= b.howMany;\n\t\t}\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedByMoveOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedByMoveOperation( b );\n\n\t// After transformations are done, make sure to revert stickiness in case if (1) - (4) scenario happened.\n\ta.sourcePosition.stickiness = 'toPrevious';\n\ta.targetPosition.stickiness = 'toNext';\n\n\t// `MergeOperation` graveyard position is like `MoveOperation` target position. It is a position where element(s) will\n\t// be moved. Like in other similar cases, we need to consider the scenario when those positions are same.\n\t// Here, we will treat `MergeOperation` like it is always strong (see `InsertOperation` x `InsertOperation` for comparison).\n\t// This means that we won't transform graveyard position if it is equal to move operation target position.\n\tif ( !a.graveyardPosition.isEqual( b.targetPosition ) ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MergeOperation, SplitOperation, ( a, b, context ) => {\n\tif ( b.graveyardPosition ) {\n\t\t// If `b` operation defines graveyard position, a node from graveyard will be moved. This means that we need to\n\t\t// transform `a.graveyardPosition` accordingly.\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByDeletion( b.graveyardPosition, 1 )!;\n\n\t\t// This is a scenario foreseen in `MergeOperation` x `MergeOperation`, with two identical merge operations.\n\t\t//\n\t\t// So, there was `MergeOperation` x `MergeOperation` transformation earlier. Now, `a` is a merge operation which\n\t\t// source position is in graveyard. Interestingly, split operation wants to use the node to be merged by `a`. This\n\t\t// means that `b` is undoing that merge operation from earlier, which caused `a` to be in graveyard.\n\t\t//\n\t\t// If that's the case, at this point, we will only \"fix\" `a.howMany`. It was earlier set to `0` in\n\t\t// `MergeOperation` x `MergeOperation` transformation. Later transformations in this function will change other\n\t\t// properties.\n\t\t//\n\t\tif ( a.deletionPosition.isEqual( b.graveyardPosition ) ) {\n\t\t\ta.howMany = b.howMany;\n\t\t}\n\t}\n\n\t// Case 1:\n\t//\n\t// Merge operation moves nodes to the place where split happens.\n\t//\n\t// This is a classic situation when there are two paragraphs, and there is a split (enter) at the end of the first\n\t// paragraph and there is a merge (delete) at the beginning of the second paragraph:\n\t//\n\t// <p>Foo{}</p><p>[]Bar</p>.\n\t//\n\t// User A presses enter after `Foo`, while User B presses backspace before `Bar`. It is intuitive that after both operations, the\n\t// editor state should stay the same.\n\t//\n\t// State after split:\n\t// <p>Foo</p><p></p><p>[]Bar</p>\n\t//\n\t// When this happens, `Bar` should be merged to the newly created paragraph, to maintain the editor state:\n\t// <p>Foo</p><p>Bar</p>\n\t//\n\t// Another option is to merge into the original paragraph `Foo`, according to the `targetPosition`. This results in an incorrect state:\n\t// <p>FooBar</p><p></p>\n\t//\n\t// Also, consider an example where User A also writes something in the new paragraph:\n\t// <p>Foo</p><p>Xyz</p><p>[]Bar</p>\n\t//\n\t// In this case it is clear that merge should happen into `[ 1, 3 ]` not into `[ 0, 3 ]`. It first has to be transformed to `[ 1, 0 ]`,\n\t// and then transformed be insertion into `[ 1, 3 ]`.\n\t//\n\t// So, usually we want to move `targetPosition` to the new paragraph when it is same as split position. This is how it is handled\n\t// in the default transformation (`_getTransformedBySplitOperation()`). We don't need a special case for this.\n\t//\n\t// However, there are two exceptions, when we **do not** want to transform `targetPosition`, and we need a special case then.\n\t//\n\t// These exceptions happen only if undo is involved. During OT, above presented case (`<p>Foo{}</p><p>[]Bar</p>`) is the only way\n\t// how `SplitOperation#splitPosition` and `MergeOperation#targetPosition` can be the same.\n\t//\n\t// First exception is when the element to merge is in the graveyard and split operation uses it. In that case\n\t// if target position would be transformed, the merge operation would target at the source position:\n\t//\n\t// root: <p>Foo[]</p>\t\t\t\tgraveyard: <p></p>\n\t//\n\t// SplitOperation: root [ 0, 3 ] using graveyard [ 0 ] (howMany = 0)\n\t// MergeOperation: graveyard [ 0, 0 ] -> root [ 0, 3 ] (howMany = 0)\n\t//\n\t// Since split operation moves the graveyard element back to the root (to path `[ 1 ]`), the merge operation `sourcePosition` changes.\n\t// After split we have: `<p>Foo</p><p></p>`, so `sourcePosition` is `[ 1, 0 ]`. But if `targetPosition` is transformed, then it\n\t// also becomes `[ 1, 0 ]`. In this case, we want to keep the `targetPosition` as it was.\n\t//\n\t// Second exception is connected strictly with undo relations. If this `MergeOperation` was earlier transformed by\n\t// `MergeOperation` and we stored an information that earlier the target position was not affected, then here, when transforming by\n\t// `SplitOperation` we are not going to change it as well.\n\t//\n\t// For these two cases we will only transform `sourcePosition` and return early.\n\t//\n\t// Note, that earlier there was also third special case here. `targetPosition` was not transformed, if it pointed into the middle of\n\t// target element, not into its end (as usual). This can also happen only with undo involved. However, it wasn't always a correct\n\t// solution, as in some cases we actually wanted to transform `targetPosition`. Also, this case usually happens together with the second\n\t// case described above. There is only one scenario that we have in our unit tests, where this third case happened without second case.\n\t// However, this scenario went fine no matter if we transformed `targetPosition` or not. That's because this happened in the middle\n\t// of transformation process and the operation was correctly transformed later on.\n\t//\n\tif ( a.targetPosition.isEqual( b.splitPosition ) ) {\n\t\tconst mergeSplittingElement = b.graveyardPosition && a.deletionPosition.isEqual( b.graveyardPosition );\n\n\t\tif ( mergeSplittingElement || context.abRelation == 'mergeTargetNotMoved' ) {\n\t\t\ta.sourcePosition = a.sourcePosition._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// Case 2:\n\t//\n\t// Merge source is at the same position as split position. This sometimes happen, mostly during undo.\n\t// The decision here is mostly to choose whether merge source position should stay where it is (so it will be at the end of the\n\t// split element) or should be move to the beginning of the new element.\n\t//\n\tif ( a.sourcePosition.isEqual( b.splitPosition ) ) {\n\t\t// Use context to check if `SplitOperation` is not undoing a merge operation, that didn't change the `a` operation.\n\t\t// This scenario happens the undone merge operation moved nodes at the source position of `a` operation.\n\t\t// In that case `a` operation source position should stay where it is.\n\t\tif ( context.abRelation == 'mergeSourceNotMoved' ) {\n\t\t\ta.howMany = 0;\n\t\t\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\n\t\t// This merge operation might have been earlier transformed by a merge operation which both merged the same element.\n\t\t// See that case in `MergeOperation` x `MergeOperation` transformation. In that scenario, if the merge operation has been undone,\n\t\t// the special case is not applied.\n\t\t//\n\t\t// Now, the merge operation is transformed by the split which has undone that previous merge operation.\n\t\t// So now we are fixing situation which was skipped in `MergeOperation` x `MergeOperation` case.\n\t\t//\n\t\tif ( context.abRelation == 'mergeSameElement' || a.sourcePosition.offset > 0 ) {\n\t\t\ta.sourcePosition = b.moveTargetPosition.clone();\n\t\t\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.sourcePosition.hasSameParentAs( b.splitPosition ) ) {\n\t\ta.howMany = b.splitPosition.offset;\n\t}\n\n\ta.sourcePosition = a.sourcePosition._getTransformedBySplitOperation( b );\n\ta.targetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( MoveOperation, InsertOperation, ( a, b ) => {\n\tconst moveRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\tconst transformed = moveRange._getTransformedByInsertOperation( b, false )[ 0 ];\n\n\ta.sourcePosition = transformed.start;\n\ta.howMany = transformed.end.offset - transformed.start.offset;\n\n\t// See `InsertOperation` x `MoveOperation` transformation for details on this case.\n\t//\n\t// In summary, both operations point to the same place, so the order of nodes needs to be decided.\n\t// `MoveOperation` is considered weaker, so it is always transformed, unless there was a certain relation\n\t// between operations.\n\t//\n\tif ( !a.targetPosition.isEqual( b.position ) ) {\n\t\ta.targetPosition = a.targetPosition._getTransformedByInsertOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( MoveOperation, MoveOperation, ( a, b, context ) => {\n\t//\n\t// Setting and evaluating some variables that will be used in special cases and default algorithm.\n\t//\n\t// Create ranges from `MoveOperations` properties.\n\tconst rangeA = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\tconst rangeB = Range._createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\t// Assign `context.aIsStrong` to a different variable, because the value may change during execution of\n\t// this algorithm and we do not want to override original `context.aIsStrong` that will be used in later transformations.\n\tlet aIsStrong = context.aIsStrong;\n\n\t// This will be used to decide the order of nodes if both operations target at the same position.\n\t// By default, use strong/weak operation mechanism.\n\tlet insertBefore = !context.aIsStrong;\n\n\t// If the relation is set, then use it to decide nodes order.\n\tif ( context.abRelation == 'insertBefore' || context.baRelation == 'insertAfter' ) {\n\t\tinsertBefore = true;\n\t} else if ( context.abRelation == 'insertAfter' || context.baRelation == 'insertBefore' ) {\n\t\tinsertBefore = false;\n\t}\n\n\t// `a.targetPosition` could be affected by the `b` operation. We will transform it.\n\tlet newTargetPosition;\n\n\tif ( a.targetPosition.isEqual( b.targetPosition ) && insertBefore ) {\n\t\tnewTargetPosition = a.targetPosition._getTransformedByDeletion(\n\t\t\tb.sourcePosition,\n\t\t\tb.howMany\n\t\t);\n\t} else {\n\t\tnewTargetPosition = a.targetPosition._getTransformedByMove(\n\t\t\tb.sourcePosition,\n\t\t\tb.targetPosition,\n\t\t\tb.howMany\n\t\t);\n\t}\n\n\t//\n\t// Special case #1 + mirror.\n\t//\n\t// Special case when both move operations' target positions are inside nodes that are\n\t// being moved by the other move operation. So in other words, we move ranges into inside of each other.\n\t// This case can't be solved reasonably (on the other hand, it should not happen often).\n\tif ( _moveTargetIntoMovedRange( a, b ) && _moveTargetIntoMovedRange( b, a ) ) {\n\t\t// Instead of transforming operation, we return a reverse of the operation that we transform by.\n\t\t// So when the results of this \"transformation\" will be applied, `b` MoveOperation will get reversed.\n\t\treturn [ b.getReversed() ];\n\t}\n\t//\n\t// End of special case #1.\n\t//\n\n\t//\n\t// Special case #2.\n\t//\n\t// Check if `b` operation targets inside `rangeA`.\n\tconst bTargetsToA = rangeA.containsPosition( b.targetPosition );\n\n\t// If `b` targets to `rangeA` and `rangeA` contains `rangeB`, `b` operation has no influence on `a` operation.\n\t// You might say that operation `b` is captured inside operation `a`.\n\tif ( bTargetsToA && rangeA.containsRange( rangeB, true ) ) {\n\t\t// There is a mini-special case here, where `rangeB` is on other level than `rangeA`. That's why\n\t\t// we need to transform `a` operation anyway.\n\t\t( rangeA as any ).start = rangeA.start._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\t\t( rangeA as any ).end = rangeA.end._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\n\t\treturn _makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition! );\n\t}\n\n\t//\n\t// Special case #2 mirror.\n\t//\n\tconst aTargetsToB = rangeB.containsPosition( a.targetPosition );\n\n\tif ( aTargetsToB && rangeB.containsRange( rangeA, true ) ) {\n\t\t// `a` operation is \"moved together\" with `b` operation.\n\t\t// Here, just move `rangeA` \"inside\" `rangeB`.\n\t\t( rangeA as any ).start = rangeA.start._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\t\t( rangeA as any ).end = rangeA.end._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\n\t\treturn _makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition! );\n\t}\n\t//\n\t// End of special case #2.\n\t//\n\n\t//\n\t// Special case #3 + mirror.\n\t//\n\t// `rangeA` has a node which is an ancestor of `rangeB`. In other words, `rangeB` is inside `rangeA`\n\t// but not on the same tree level. In such case ranges have common part but we have to treat it\n\t// differently, because in such case those ranges are not really conflicting and should be treated like\n\t// two separate ranges. Also we have to discard two difference parts.\n\tconst aCompB = compareArrays( a.sourcePosition.getParentPath(), b.sourcePosition.getParentPath() );\n\n\tif ( aCompB == 'prefix' || aCompB == 'extension' ) {\n\t\t// Transform `rangeA` by `b` operation and make operation out of it, and that's all.\n\t\t// Note that this is a simplified version of default case, but here we treat the common part (whole `rangeA`)\n\t\t// like a one difference part.\n\t\t( rangeA as any ).start = rangeA.start._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\t\t( rangeA as any ).end = rangeA.end._getTransformedByMove( b.sourcePosition, b.targetPosition, b.howMany );\n\n\t\treturn _makeMoveOperationsFromRanges( [ rangeA ], newTargetPosition! );\n\t}\n\t//\n\t// End of special case #3.\n\t//\n\n\t//\n\t// Default case - ranges are on the same level or are not connected with each other.\n\t//\n\t// Modifier for default case.\n\t// Modifies `aIsStrong` flag in certain conditions.\n\t//\n\t// If only one of operations is a remove operation, we force remove operation to be the \"stronger\" one\n\t// to provide more expected results.\n\tif ( a.type == 'remove' && b.type != 'remove' && !context.aWasUndone && !context.forceWeakRemove ) {\n\t\taIsStrong = true;\n\t} else if ( a.type != 'remove' && b.type == 'remove' && !context.bWasUndone && !context.forceWeakRemove ) {\n\t\taIsStrong = false;\n\t}\n\n\t// Handle operation's source ranges - check how `rangeA` is affected by `b` operation.\n\t// This will aggregate transformed ranges.\n\tconst ranges = [];\n\n\t// Get the \"difference part\" of `a` operation source range.\n\t// This is an array with one or two ranges. Two ranges if `rangeB` is inside `rangeA`.\n\tconst difference = rangeA.getDifference( rangeB );\n\n\tfor ( const range of difference ) {\n\t\t// Transform those ranges by `b` operation. For example if `b` moved range from before those ranges, fix those ranges.\n\t\t( range as any ).start = range.start._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\t\t( range as any ).end = range.end._getTransformedByDeletion( b.sourcePosition, b.howMany );\n\n\t\t// If `b` operation targets into `rangeA` on the same level, spread `rangeA` into two ranges.\n\t\tconst shouldSpread = compareArrays( range.start.getParentPath(), b.getMovedRangeStart().getParentPath() ) == 'same';\n\t\tconst newRanges = range._getTransformedByInsertion( b.getMovedRangeStart(), b.howMany, shouldSpread );\n\n\t\tranges.push( ...newRanges );\n\t}\n\n\t// Then, we have to manage the \"common part\" of both move ranges.\n\tconst common = rangeA.getIntersection( rangeB );\n\n\tif ( common !== null && aIsStrong ) {\n\t\t// Calculate the new position of that part of original range.\n\t\t( common as any ).start = common.start._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\t\t( common as any ).end = common.end._getCombined( b.sourcePosition, b.getMovedRangeStart() );\n\n\t\t// Take care of proper range order.\n\t\t//\n\t\t// Put `common` at appropriate place. Keep in mind that we are interested in original order.\n\t\t// Basically there are only three cases: there is zero, one or two difference ranges.\n\t\t//\n\t\t// If there is zero difference ranges, just push `common` in the array.\n\t\tif ( ranges.length === 0 ) {\n\t\t\tranges.push( common );\n\t\t}\n\t\t// If there is one difference range, we need to check whether common part was before it or after it.\n\t\telse if ( ranges.length == 1 ) {\n\t\t\tif ( rangeB.start.isBefore( rangeA.start ) || rangeB.start.isEqual( rangeA.start ) ) {\n\t\t\t\tranges.unshift( common );\n\t\t\t} else {\n\t\t\t\tranges.push( common );\n\t\t\t}\n\t\t}\n\t\t// If there are more ranges (which means two), put common part between them. This is the only scenario\n\t\t// where there could be two difference ranges so we don't have to make any comparisons.\n\t\telse {\n\t\t\tranges.splice( 1, 0, common );\n\t\t}\n\t}\n\n\tif ( ranges.length === 0 ) {\n\t\t// If there are no \"source ranges\", nothing should be changed.\n\t\t// Note that this can happen only if `aIsStrong == false` and `rangeA.isEqual( rangeB )`.\n\t\treturn [ new NoOperation( a.baseVersion ) ];\n\t}\n\n\treturn _makeMoveOperationsFromRanges( ranges, newTargetPosition! );\n} );\n\nsetTransformation( MoveOperation, SplitOperation, ( a, b, context ) => {\n\tlet newTargetPosition = a.targetPosition.clone();\n\n\t// Do not transform if target position is same as split insertion position and this split comes from undo.\n\t// This should be done on relations but it is too much work for now as it would require relations working in collaboration.\n\t// We need to make a decision how we will resolve such conflict and this is less harmful way.\n\tif ( !a.targetPosition.isEqual( b.insertionPosition ) || !b.graveyardPosition || context.abRelation == 'moveTargetAfter' ) {\n\t\tnewTargetPosition = a.targetPosition._getTransformedBySplitOperation( b );\n\t}\n\n\t// Case 1:\n\t//\n\t// Last element in the moved range got split.\n\t//\n\t// In this case the default range transformation will not work correctly as the element created by\n\t// split operation would be outside the range. The range to move needs to be fixed manually.\n\t//\n\tconst moveRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\n\tif ( moveRange.end.isEqual( b.insertionPosition ) ) {\n\t\t// Do it only if this is a \"natural\" split, not a one that comes from undo.\n\t\t// If this is undo split, only `targetPosition` needs to be changed (if the move is a remove).\n\t\tif ( !b.graveyardPosition ) {\n\t\t\ta.howMany++;\n\t\t}\n\n\t\ta.targetPosition = newTargetPosition;\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 2:\n\t//\n\t// Split happened between the moved nodes. In this case two ranges to move need to be generated.\n\t//\n\t// Characters `ozba` are moved to the end of paragraph `Xyz` but split happened.\n\t// <p>F[oz|ba]r</p><p>Xyz</p>\n\t//\n\t// After split:\n\t// <p>F[oz</p><p>ba]r</p><p>Xyz</p>\n\t//\n\t// Correct ranges:\n\t// <p>F[oz]</p><p>[ba]r</p><p>Xyz</p>\n\t//\n\t// After move:\n\t// <p>F</p><p>r</p><p>Xyzozba</p>\n\t//\n\tif ( moveRange.start.hasSameParentAs( b.splitPosition ) && moveRange.containsPosition( b.splitPosition ) ) {\n\t\tlet rightRange = new Range( b.splitPosition, moveRange.end );\n\t\trightRange = rightRange._getTransformedBySplitOperation( b );\n\n\t\tconst ranges = [\n\t\t\tnew Range( moveRange.start, b.splitPosition ),\n\t\t\trightRange\n\t\t];\n\n\t\treturn _makeMoveOperationsFromRanges( ranges, newTargetPosition );\n\t}\n\n\t// Case 3:\n\t//\n\t// Move operation targets at the split position. We need to decide if the nodes should be inserted\n\t// at the end of the split element or at the beginning of the new element.\n\t//\n\tif ( a.targetPosition.isEqual( b.splitPosition ) && context.abRelation == 'insertAtSource' ) {\n\t\tnewTargetPosition = b.moveTargetPosition;\n\t}\n\n\t// Case 4:\n\t//\n\t// Move operation targets just after the split element. We need to decide if the nodes should be inserted\n\t// between two parts of split element, or after the new element.\n\t//\n\t// Split at `|`, while move operation moves `<p>Xyz</p>` and targets at `^`:\n\t// <p>Foo|bar</p>^<p>baz</p>\n\t// <p>Foo</p>^<p>bar</p><p>baz</p> or <p>Foo</p><p>bar</p>^<p>baz</p>?\n\t//\n\t// If there is no contextual information between operations (for example, they come from collaborative\n\t// editing), we don't want to put some unrelated content (move) between parts of related content (split parts).\n\t// However, if the split is from undo, in the past, the moved content might be targeting between the\n\t// split parts, meaning that was exactly user's intention:\n\t//\n\t// <p>Foo</p>^<p>bar</p>\t\t<--- original situation, in \"past\".\n\t// <p>Foobar</p>^\t\t\t\t<--- after merge target position is transformed.\n\t// <p>Foo|bar</p>^\t\t\t\t<--- then the merge is undone, and split happens, which leads us to current situation.\n\t//\n\t// In this case it is pretty clear that the intention was to put new paragraph between those nodes,\n\t// so we need to transform accordingly. We can detect this scenario thanks to relations.\n\t//\n\tif ( a.targetPosition.isEqual( b.insertionPosition ) && context.abRelation == 'insertBetween' ) {\n\t\tnewTargetPosition = a.targetPosition;\n\t}\n\n\t// The default case.\n\t//\n\tconst transformed = moveRange._getTransformedBySplitOperation( b );\n\tconst ranges = [ transformed ];\n\n\t// Case 5:\n\t//\n\t// Moved range contains graveyard element used by split operation. Add extra move operation to the result.\n\t//\n\tif ( b.graveyardPosition ) {\n\t\tconst movesGraveyardElement = moveRange.start.isEqual( b.graveyardPosition ) || moveRange.containsPosition( b.graveyardPosition );\n\n\t\tif ( a.howMany > 1 && movesGraveyardElement && !context.aWasUndone ) {\n\t\t\tranges.push( Range._createFromPositionAndShift( b.insertionPosition, 1 ) );\n\t\t}\n\t}\n\n\treturn _makeMoveOperationsFromRanges( ranges, newTargetPosition );\n} );\n\nsetTransformation( MoveOperation, MergeOperation, ( a, b, context ) => {\n\tconst movedRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\n\tif ( b.deletionPosition.hasSameParentAs( a.sourcePosition ) && movedRange.containsPosition( b.sourcePosition ) ) {\n\t\tif ( a.type == 'remove' && !context.forceWeakRemove ) {\n\t\t\t// Case 1:\n\t\t\t//\n\t\t\t// The element to remove got merged.\n\t\t\t//\n\t\t\t// Merge operation does support merging elements which are not siblings. So it would not be a problem\n\t\t\t// from technical point of view. However, if the element was removed, the intention of the user\n\t\t\t// deleting it was to have it all deleted. From user experience point of view, moving back the\n\t\t\t// removed nodes might be unexpected. This means that in this scenario we will reverse merging and remove the element.\n\t\t\t//\n\t\t\tif ( !context.aWasUndone ) {\n\t\t\t\tconst results = [];\n\n\t\t\t\tlet gyMoveSource = b.graveyardPosition.clone();\n\t\t\t\tlet splitNodesMoveSource = b.targetPosition._getTransformedByMergeOperation( b );\n\n\t\t\t\t// `a.targetPosition` points to graveyard, so it was probably affected by `b` (which moved merged element to the graveyard).\n\t\t\t\tconst aTarget = a.targetPosition.getTransformedByOperation( b );\n\n\t\t\t\tif ( a.howMany > 1 ) {\n\t\t\t\t\tresults.push( new MoveOperation( a.sourcePosition, a.howMany - 1, aTarget, 0 ) );\n\n\t\t\t\t\tgyMoveSource = gyMoveSource._getTransformedByMove( a.sourcePosition, aTarget, a.howMany - 1 );\n\t\t\t\t\tsplitNodesMoveSource = splitNodesMoveSource._getTransformedByMove( a.sourcePosition, aTarget, a.howMany - 1 );\n\t\t\t\t}\n\n\t\t\t\tconst gyMoveTarget = b.deletionPosition._getCombined( a.sourcePosition, aTarget );\n\t\t\t\tconst gyMove = new MoveOperation( gyMoveSource, 1, gyMoveTarget, 0 );\n\n\t\t\t\tconst splitNodesMoveTargetPath = gyMove.getMovedRangeStart().path.slice();\n\t\t\t\tsplitNodesMoveTargetPath.push( 0 );\n\n\t\t\t\tconst splitNodesMoveTarget = new Position( gyMove.targetPosition.root, splitNodesMoveTargetPath );\n\t\t\t\tsplitNodesMoveSource = splitNodesMoveSource._getTransformedByMove( gyMoveSource, gyMoveTarget, 1 );\n\t\t\t\tconst splitNodesMove = new MoveOperation( splitNodesMoveSource, b.howMany, splitNodesMoveTarget, 0 );\n\n\t\t\t\tresults.push( gyMove );\n\t\t\t\tresults.push( splitNodesMove );\n\n\t\t\t\treturn results;\n\t\t\t}\n\t\t} else {\n\t\t\t// Case 2:\n\t\t\t//\n\t\t\t// The element to move got merged and it was the only element to move.\n\t\t\t// In this case just don't do anything, leave the node in the graveyard. Without special case\n\t\t\t// it would be a move operation that moves 0 nodes, so maybe it is better just to return no-op.\n\t\t\t//\n\t\t\tif ( a.howMany == 1 ) {\n\t\t\t\tif ( !context.bWasUndone ) {\n\t\t\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t\t\t} else {\n\t\t\t\t\ta.sourcePosition = b.graveyardPosition.clone();\n\t\t\t\t\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\t\t\t\t\treturn [ a ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// The default case.\n\t//\n\tconst moveRange = Range._createFromPositionAndShift( a.sourcePosition, a.howMany );\n\tconst transformed = moveRange._getTransformedByMergeOperation( b );\n\n\ta.sourcePosition = transformed.start;\n\ta.howMany = transformed.end.offset - transformed.start.offset;\n\ta.targetPosition = a.targetPosition._getTransformedByMergeOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( RenameOperation, InsertOperation, ( a, b ) => {\n\ta.position = a.position._getTransformedByInsertOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, MergeOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// Element to rename got merged, so it was moved to `b.graveyardPosition`.\n\t//\n\tif ( a.position.isEqual( b.deletionPosition ) ) {\n\t\ta.position = b.graveyardPosition.clone();\n\t\ta.position.stickiness = 'toNext';\n\n\t\treturn [ a ];\n\t}\n\n\ta.position = a.position._getTransformedByMergeOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, MoveOperation, ( a, b ) => {\n\ta.position = a.position._getTransformedByMoveOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, RenameOperation, ( a, b, context ) => {\n\tif ( a.position.isEqual( b.position ) ) {\n\t\tif ( context.aIsStrong ) {\n\t\t\ta.oldName = b.newName;\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( RenameOperation, SplitOperation, ( a, b ) => {\n\t// Case 1:\n\t//\n\t// The element to rename has been split. In this case, the new element should be also renamed.\n\t//\n\t// User decides to change the paragraph to a list item:\n\t// <paragraph>Foobar</paragraph>\n\t//\n\t// However, in meantime, split happens:\n\t// <paragraph>Foo</paragraph><paragraph>bar</paragraph>\n\t//\n\t// As a result, rename both elements:\n\t// <listItem>Foo</listItem><listItem>bar</listItem>\n\t//\n\tconst renamePath = a.position.path;\n\tconst splitPath = b.splitPosition.getParentPath();\n\n\tif ( compareArrays( renamePath, splitPath ) == 'same' && !b.graveyardPosition ) {\n\t\tconst extraRename = new RenameOperation( a.position.getShiftedBy( 1 ), a.oldName, a.newName, 0 );\n\n\t\treturn [ a, extraRename ];\n\t}\n\n\t// The default case.\n\t//\n\ta.position = a.position._getTransformedBySplitOperation( b );\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( RootAttributeOperation, RootAttributeOperation, ( a, b, context ) => {\n\tif ( a.root === b.root && a.key === b.key ) {\n\t\tif ( !context.aIsStrong || a.newValue === b.newValue ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t} else {\n\t\t\ta.oldValue = b.newValue;\n\t\t}\n\t}\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( RootOperation, RootOperation, ( a, b ) => {\n\tif ( a.rootName === b.rootName && a.isAdd === b.isAdd ) {\n\t\treturn [ new NoOperation( 0 ) ];\n\t}\n\n\treturn [ a ];\n} );\n\n// -----------------------\n\nsetTransformation( SplitOperation, InsertOperation, ( a, b ) => {\n\t// The default case.\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.position ) && a.splitPosition.offset < b.position.offset ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.splitPosition = a.splitPosition._getTransformedByInsertOperation( b );\n\ta.insertionPosition = a.insertionPosition._getTransformedByInsertOperation( b );\n\n\treturn [ a ];\n} );\n\nsetTransformation( SplitOperation, MergeOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Split element got merged. If two different elements were merged, clients will have different content.\n\t//\n\t// Example. Merge at `{}`, split at `[]`:\n\t// <heading>Foo</heading>{}<paragraph>B[]ar</paragraph>\n\t//\n\t// On merge side it will look like this:\n\t// <heading>FooB[]ar</heading>\n\t// <heading>FooB</heading><heading>ar</heading>\n\t//\n\t// On split side it will look like this:\n\t// <heading>Foo</heading>{}<paragraph>B</paragraph><paragraph>ar</paragraph>\n\t// <heading>FooB</heading><paragraph>ar</paragraph>\n\t//\n\t// Clearly, the second element is different for both clients.\n\t//\n\t// We could use the removed merge element from graveyard as a split element but then clients would have a different\n\t// model state (in graveyard), because the split side client would still have an element in graveyard (removed by merge).\n\t//\n\t// To overcome this, in `SplitOperation` x `MergeOperation` transformation we will add additional `SplitOperation`\n\t// in the graveyard, which will actually clone the merged-and-deleted element. Then, that cloned element will be\n\t// used for splitting. Example below.\n\t//\n\t// Original state:\n\t// <heading>Foo</heading>{}<paragraph>B[]ar</paragraph>\n\t//\n\t// Merge side client:\n\t//\n\t// After merge:\n\t// <heading>FooB[]ar</heading>                                 graveyard: <paragraph></paragraph>\n\t//\n\t// Extra split:\n\t// <heading>FooB[]ar</heading>                                 graveyard: <paragraph></paragraph><paragraph></paragraph>\n\t//\n\t// Use the \"cloned\" element from graveyard:\n\t// <heading>FooB</heading><paragraph>ar</paragraph>            graveyard: <paragraph></paragraph>\n\t//\n\t// Split side client:\n\t//\n\t// After split:\n\t// <heading>Foo</heading>{}<paragraph>B</paragraph><paragraph>ar</paragraph>\n\t//\n\t// After merge:\n\t// <heading>FooB</heading><paragraph>ar</paragraph>            graveyard: <paragraph></paragraph>\n\t//\n\t// This special case scenario only applies if the original split operation clones the split element.\n\t// If the original split operation has `graveyardPosition` set, it all doesn't have sense because split operation\n\t// knows exactly which element it should use. So there would be no original problem with different contents.\n\t//\n\t// Additionally, the special case applies only if the merge wasn't already undone.\n\t//\n\tif ( !a.graveyardPosition && !context.bWasUndone && a.splitPosition.hasSameParentAs( b.sourcePosition ) ) {\n\t\tconst splitPath = b.graveyardPosition.path.slice();\n\t\tsplitPath.push( 0 );\n\n\t\tconst splitPosition = new Position( b.graveyardPosition.root, splitPath );\n\t\tconst insertionPosition = SplitOperation.getInsertionPosition( new Position( b.graveyardPosition.root, splitPath ) );\n\n\t\tconst additionalSplit = new SplitOperation( splitPosition, 0, insertionPosition, null, 0 );\n\n\t\ta.splitPosition = a.splitPosition._getTransformedByMergeOperation( b );\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\t\ta.graveyardPosition = additionalSplit.insertionPosition.clone();\n\t\ta.graveyardPosition.stickiness = 'toNext';\n\n\t\treturn [ additionalSplit, a ];\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.deletionPosition ) && !a.splitPosition.isAfter( b.deletionPosition ) ) {\n\t\ta.howMany--;\n\t}\n\n\tif ( a.splitPosition.hasSameParentAs( b.targetPosition ) ) {\n\t\ta.howMany += b.howMany;\n\t}\n\n\ta.splitPosition = a.splitPosition._getTransformedByMergeOperation( b );\n\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\tif ( a.graveyardPosition ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMergeOperation( b );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( SplitOperation, MoveOperation, ( a, b, context ) => {\n\tconst rangeToMove = Range._createFromPositionAndShift( b.sourcePosition, b.howMany );\n\n\tif ( a.graveyardPosition ) {\n\t\t// Case 1:\n\t\t//\n\t\t// Split operation graveyard node was moved. In this case move operation is stronger. Since graveyard element\n\t\t// is already moved to the correct position, we need to only move the nodes after the split position.\n\t\t// This will be done by `MoveOperation` instead of `SplitOperation`.\n\t\t//\n\t\tconst gyElementMoved = rangeToMove.start.isEqual( a.graveyardPosition ) || rangeToMove.containsPosition( a.graveyardPosition );\n\n\t\tif ( !context.bWasUndone && gyElementMoved ) {\n\t\t\tconst sourcePosition = a.splitPosition._getTransformedByMoveOperation( b );\n\n\t\t\tconst newParentPosition = a.graveyardPosition._getTransformedByMoveOperation( b );\n\t\t\tconst newTargetPath = newParentPosition.path.slice();\n\t\t\tnewTargetPath.push( 0 );\n\n\t\t\tconst newTargetPosition = new Position( newParentPosition.root, newTargetPath );\n\t\t\tconst moveOp = new MoveOperation( sourcePosition, a.howMany, newTargetPosition, 0 );\n\n\t\t\treturn [ moveOp ];\n\t\t}\n\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedByMoveOperation( b );\n\t}\n\n\t// Case 2:\n\t//\n\t// Split is at a position where nodes were moved.\n\t//\n\t// This is a scenario described in `MoveOperation` x `SplitOperation` transformation but from the\n\t// \"split operation point of view\".\n\t//\n\tconst splitAtTarget = a.splitPosition.isEqual( b.targetPosition );\n\n\tif ( splitAtTarget && ( context.baRelation == 'insertAtSource' || context.abRelation == 'splitBefore' ) ) {\n\t\ta.howMany += b.howMany;\n\t\ta.splitPosition = a.splitPosition._getTransformedByDeletion( b.sourcePosition, b.howMany )!;\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\t\treturn [ a ];\n\t}\n\n\tif ( splitAtTarget && context.abRelation && context.abRelation.howMany ) {\n\t\tconst { howMany, offset } = context.abRelation;\n\n\t\ta.howMany += howMany;\n\t\ta.splitPosition = a.splitPosition.getShiftedBy( offset );\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 3:\n\t//\n\t// If the split position is inside the moved range, we need to shift the split position to a proper place.\n\t// The position cannot be moved together with moved range because that would result in splitting of an incorrect element.\n\t//\n\t// Characters `bc` should be moved to the second paragraph while split position is between them:\n\t// <paragraph>A[b|c]d</paragraph><paragraph>Xyz</paragraph>\n\t//\n\t// After move, new split position is incorrect:\n\t// <paragraph>Ad</paragraph><paragraph>Xb|cyz</paragraph>\n\t//\n\t// Correct split position:\n\t// <paragraph>A|d</paragraph><paragraph>Xbcyz</paragraph>\n\t//\n\t// After split:\n\t// <paragraph>A</paragraph><paragraph>d</paragraph><paragraph>Xbcyz</paragraph>\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.sourcePosition ) && rangeToMove.containsPosition( a.splitPosition ) ) {\n\t\tconst howManyRemoved = b.howMany - ( a.splitPosition.offset - b.sourcePosition.offset );\n\t\ta.howMany -= howManyRemoved;\n\n\t\tif ( a.splitPosition.hasSameParentAs( b.targetPosition ) && a.splitPosition.offset < b.targetPosition.offset ) {\n\t\t\ta.howMany += b.howMany;\n\t\t}\n\n\t\ta.splitPosition = b.sourcePosition.clone();\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\t\treturn [ a ];\n\t}\n\n\t// The default case.\n\t// Don't change `howMany` if move operation does not really move anything.\n\t//\n\tif ( !b.sourcePosition.isEqual( b.targetPosition ) ) {\n\t\tif ( a.splitPosition.hasSameParentAs( b.sourcePosition ) && a.splitPosition.offset <= b.sourcePosition.offset ) {\n\t\t\ta.howMany -= b.howMany;\n\t\t}\n\n\t\tif ( a.splitPosition.hasSameParentAs( b.targetPosition ) && a.splitPosition.offset < b.targetPosition.offset ) {\n\t\t\ta.howMany += b.howMany;\n\t\t}\n\t}\n\n\t// Change position stickiness to force a correct transformation.\n\ta.splitPosition.stickiness = 'toNone';\n\ta.splitPosition = a.splitPosition._getTransformedByMoveOperation( b );\n\ta.splitPosition.stickiness = 'toNext';\n\n\tif ( a.graveyardPosition ) {\n\t\ta.insertionPosition = a.insertionPosition._getTransformedByMoveOperation( b );\n\t} else {\n\t\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\t}\n\n\treturn [ a ];\n} );\n\nsetTransformation( SplitOperation, SplitOperation, ( a, b, context ) => {\n\t// Case 1:\n\t//\n\t// Split at the same position.\n\t//\n\t// If there already was a split at the same position as in `a` operation, it means that the intention\n\t// conveyed by `a` operation has already been fulfilled and `a` should not do anything (to avoid double split).\n\t//\n\t// However, there is a difference if these are new splits or splits created by undo. These have different\n\t// intentions. Also splits moving back different elements from graveyard have different intentions. They\n\t// are just different operations.\n\t//\n\t// So we cancel split operation only if it was really identical.\n\t//\n\t// Also, there is additional case, where split operations aren't identical and should not be cancelled, however the\n\t// default transformation is incorrect too.\n\t//\n\tif ( a.splitPosition.isEqual( b.splitPosition ) ) {\n\t\tif ( !a.graveyardPosition && !b.graveyardPosition ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\n\t\tif ( a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual( b.graveyardPosition ) ) {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\n\t\t// Use context to know that the `a.splitPosition` should stay where it is.\n\t\t// This happens during undo when first a merge operation moved nodes to `a.splitPosition` and now `b` operation undoes that merge.\n\t\tif ( context.abRelation == 'splitBefore' ) {\n\t\t\t// Since split is at the same position, there are no nodes left to split.\n\t\t\ta.howMany = 0;\n\n\t\t\t// Note: there was `if ( a.graveyardPosition )` here but it was uncovered in tests and I couldn't find any scenarios for now.\n\t\t\t// That would have to be a `SplitOperation` that didn't come from undo but is transformed by operations that were undone.\n\t\t\t// It could happen if `context` is enabled in collaboration.\n\t\t\ta.graveyardPosition = a.graveyardPosition!._getTransformedBySplitOperation( b );\n\n\t\t\treturn [ a ];\n\t\t}\n\t}\n\n\t// Case 2:\n\t//\n\t// Same node is using to split different elements. This happens in undo when previously same element was merged to\n\t// two different elements. This is described in `MergeOperation` x `MergeOperation` transformation.\n\t//\n\t// In this case we will follow the same logic. We will assume that `insertionPosition` is same for both\n\t// split operations. This might not always be true but in the real cases that were experienced it was. After all,\n\t// if these splits are reverses of merge operations that were merging the same element, then the `insertionPosition`\n\t// should be same for both of those splits.\n\t//\n\t// Again, we will decide which operation is stronger by checking if split happens in graveyard or in non-graveyard root.\n\t//\n\tif ( a.graveyardPosition && b.graveyardPosition && a.graveyardPosition.isEqual( b.graveyardPosition ) ) {\n\t\tconst aInGraveyard = a.splitPosition.root.rootName == '$graveyard';\n\t\tconst bInGraveyard = b.splitPosition.root.rootName == '$graveyard';\n\n\t\t// If `aIsWeak` it means that `a` points to graveyard while `b` doesn't. Don't move nodes then.\n\t\tconst aIsWeak = aInGraveyard && !bInGraveyard;\n\n\t\t// If `bIsWeak` it means that `b` points to graveyard while `a` doesn't. Force moving nodes then.\n\t\tconst bIsWeak = bInGraveyard && !aInGraveyard;\n\n\t\t// Force move if `b` is weak or neither operation is weak but `a` is stronger through `context.aIsStrong`.\n\t\tconst forceMove = bIsWeak || ( !aIsWeak && context.aIsStrong );\n\n\t\tif ( forceMove ) {\n\t\t\tconst result = [];\n\n\t\t\t// First we need to move any nodes split by `b` back to where they were.\n\t\t\t// Do it only if `b` actually moved something.\n\t\t\tif ( b.howMany ) {\n\t\t\t\tresult.push( new MoveOperation( b.moveTargetPosition, b.howMany, b.splitPosition, 0 ) );\n\t\t\t}\n\n\t\t\t// Then we need to move nodes from `a` split position to their new element.\n\t\t\t// Do it only if `a` actually should move something.\n\t\t\tif ( a.howMany ) {\n\t\t\t\tresult.push( new MoveOperation( a.splitPosition, a.howMany, a.moveTargetPosition, 0 ) );\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} else {\n\t\t\treturn [ new NoOperation( 0 ) ];\n\t\t}\n\t}\n\n\tif ( a.graveyardPosition ) {\n\t\ta.graveyardPosition = a.graveyardPosition._getTransformedBySplitOperation( b );\n\t}\n\n\t// Case 3:\n\t//\n\t// Position where operation `b` inserted a new node after split is the same as the operation `a` split position.\n\t// As in similar cases, there is ambiguity if the split should be before the new node (created by `b`) or after.\n\t//\n\tif ( a.splitPosition.isEqual( b.insertionPosition ) && context.abRelation == 'splitBefore' ) {\n\t\ta.howMany++;\n\n\t\treturn [ a ];\n\t}\n\n\t// Case 4:\n\t//\n\t// This is a mirror to the case 2. above.\n\t//\n\tif ( b.splitPosition.isEqual( a.insertionPosition ) && context.baRelation == 'splitBefore' ) {\n\t\tconst newPositionPath = b.insertionPosition.path.slice();\n\t\tnewPositionPath.push( 0 );\n\n\t\tconst newPosition = new Position( b.insertionPosition.root, newPositionPath );\n\t\tconst moveOp = new MoveOperation( a.insertionPosition, 1, newPosition, 0 );\n\n\t\treturn [ a, moveOp ];\n\t}\n\n\t// The default case.\n\t//\n\tif ( a.splitPosition.hasSameParentAs( b.splitPosition ) && a.splitPosition.offset < b.splitPosition.offset ) {\n\t\ta.howMany -= b.howMany;\n\t}\n\n\ta.splitPosition = a.splitPosition._getTransformedBySplitOperation( b );\n\ta.insertionPosition = SplitOperation.getInsertionPosition( a.splitPosition );\n\n\treturn [ a ];\n} );\n\n/**\n * Checks whether `MoveOperation` `targetPosition` is inside a node from the moved range of the other `MoveOperation`.\n */\nfunction _moveTargetIntoMovedRange( a: MoveOperation, b: MoveOperation ) {\n\treturn a.targetPosition._getTransformedByDeletion( b.sourcePosition, b.howMany ) === null;\n}\n\n/**\n * Helper function for `MoveOperation` x `MoveOperation` transformation. Converts given ranges and target position to\n * move operations and returns them.\n *\n * Ranges and target position will be transformed on-the-fly when generating operations.\n *\n * Given `ranges` should be in the order of how they were in the original transformed operation.\n *\n * Given `targetPosition` is the target position of the first range from `ranges`.\n */\nfunction _makeMoveOperationsFromRanges( ranges: Array<Range>, targetPosition: Position ) {\n\t// At this moment we have some ranges and a target position, to which those ranges should be moved.\n\t// Order in `ranges` array is the go-to order of after transformation.\n\t//\n\t// We are almost done. We have `ranges` and `targetPosition` to make operations from.\n\t// Unfortunately, those operations may affect each other. Precisely, first operation after move\n\t// may affect source range and target position of second and third operation. Same with second\n\t// operation affecting third.\n\t//\n\t// We need to fix those source ranges and target positions once again, before converting `ranges` to operations.\n\tconst operations = [];\n\n\t// Keep in mind that nothing will be transformed if there is just one range in `ranges`.\n\tfor ( let i = 0; i < ranges.length; i++ ) {\n\t\t// Create new operation out of a range and target position.\n\t\tconst range = ranges[ i ];\n\t\tconst op = new MoveOperation(\n\t\t\trange.start,\n\t\t\trange.end.offset - range.start.offset,\n\t\t\ttargetPosition,\n\t\t\t0\n\t\t);\n\n\t\toperations.push( op );\n\n\t\t// Transform other ranges by the generated operation.\n\t\tfor ( let j = i + 1; j < ranges.length; j++ ) {\n\t\t\t// All ranges in `ranges` array should be:\n\t\t\t//\n\t\t\t// * non-intersecting (these are part of original operation source range), and\n\t\t\t// * `targetPosition` does not target into them (opposite would mean that transformed operation targets \"inside itself\").\n\t\t\t//\n\t\t\t// This means that the transformation will be \"clean\" and always return one result.\n\t\t\tranges[ j ] = ranges[ j ]._getTransformedByMove( op.sourcePosition, op.targetPosition, op.howMany )[ 0 ];\n\t\t}\n\n\t\ttargetPosition = targetPosition._getTransformedByMove( op.sourcePosition, op.targetPosition, op.howMany );\n\t}\n\n\treturn operations;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/liveposition\n */\n\nimport Position, { type PositionOffset, type PositionStickiness } from './position.js';\n\nimport type { ModelApplyOperationEvent } from './model.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Item from './item.js';\nimport type Operation from './operation/operation.js';\nimport type RootElement from './rootelement.js';\n\nimport { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';\n\n/**\n * `LivePosition` is a type of {@link module:engine/model/position~Position Position}\n * that updates itself as {@link module:engine/model/document~Document document}\n * is changed through operations. It may be used as a bookmark.\n *\n * **Note:** Contrary to {@link module:engine/model/position~Position}, `LivePosition` works only in roots that are\n * {@link module:engine/model/rootelement~RootElement}.\n * If {@link module:engine/model/documentfragment~DocumentFragment} is passed, error will be thrown.\n *\n * **Note:** Be very careful when dealing with `LivePosition`. Each `LivePosition` instance bind events that might\n * have to be unbound.\n * Use {@link module:engine/model/liveposition~LivePosition#detach} whenever you don't need `LivePosition` anymore.\n */\nexport default class LivePosition extends /* #__PURE__ */ EmitterMixin( Position ) {\n\t/**\n\t * Root of the position path.\n\t */\n\tdeclare public readonly root: RootElement;\n\n\t/**\n\t * Creates a live position.\n\t *\n\t * @see module:engine/model/position~Position\n\t */\n\tconstructor( root: RootElement, path: Array<number>, stickiness: PositionStickiness = 'toNone' ) {\n\t\tsuper( root, path, stickiness );\n\n\t\tif ( !this.root.is( 'rootElement' ) ) {\n\t\t\t/**\n\t\t\t * LivePosition's root has to be an instance of RootElement.\n\t\t\t *\n\t\t\t * @error model-liveposition-root-not-rootelement\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-liveposition-root-not-rootelement', root );\n\t\t}\n\n\t\tbindWithDocument.call( this );\n\t}\n\n\t/**\n\t * Unbinds all events previously bound by `LivePosition`. Use it whenever you don't need `LivePosition` instance\n\t * anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was\n\t * referring to it).\n\t */\n\tpublic detach(): void {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/position~Position position instance}, which is equal to this live position.\n\t */\n\tpublic toPosition(): Position {\n\t\treturn new Position( this.root, this.path.slice(), this.stickiness );\n\t}\n\n\t/**\n\t * Creates a `LivePosition` instance that is equal to position.\n\t */\n\tpublic static fromPosition( position: Position, stickiness?: PositionStickiness ): LivePosition {\n\t\treturn new this( position.root as RootElement, position.path.slice(), stickiness ? stickiness : position.stickiness );\n\t}\n\n\t/**\n\t * @internal\n\t * @see module:engine/model/position~Position._createAfter\n\t */\n\tdeclare public static readonly _createAfter: ( item: Item | DocumentFragment, stickiness?: PositionStickiness ) => LivePosition;\n\n\t/**\n\t * @internal\n\t * @see module:engine/model/position~Position._createBefore\n\t */\n\tdeclare public static readonly _createBefore: ( item: Item | DocumentFragment, stickiness?: PositionStickiness ) => LivePosition;\n\n\t/**\n\t * @internal\n\t * @see module:engine/model/position~Position._createAt\n\t */\n\tdeclare public static readonly _createAt: (\n\t\titemOrPosition: Item | Position | DocumentFragment,\n\t\toffset?: PositionOffset,\n\t\tstickiness?: PositionStickiness\n\t) => LivePosition;\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nLivePosition.prototype.is = function( type: string ): boolean {\n\treturn type === 'livePosition' || type === 'model:livePosition' ||\n\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\ttype == 'position' || type === 'model:position';\n};\n\n/**\n * Binds this `LivePosition` to the {@link module:engine/model/document~Document document} that owns\n * this position's {@link module:engine/model/position~Position#root root}.\n */\nfunction bindWithDocument( this: LivePosition ) {\n\tthis.listenTo<ModelApplyOperationEvent>(\n\t\tthis.root.document!.model,\n\t\t'applyOperation',\n\t\t( event, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( !operation.isDocumentOperation ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttransform.call( this, operation );\n\t\t},\n\t\t{ priority: 'low' }\n\t);\n}\n\n/**\n * Updates this position accordingly to the updates applied to the model. Bases on change events.\n */\nfunction transform( this: LivePosition, operation: Operation ) {\n\tconst result = this.getTransformedByOperation( operation );\n\n\tif ( !this.isEqual( result ) ) {\n\t\tconst oldPosition = this.toPosition();\n\n\t\t( this as any ).path = result.path;\n\t\t( this as any ).root = result.root;\n\n\t\tthis.fire<LivePositionChangeEvent>( 'change', oldPosition );\n\t}\n}\n\n/**\n * Fired when `LivePosition` instance is changed due to changes on {@link module:engine/model/document~Document}.\n *\n * @eventName ~LivePosition#change\n * @param oldPosition Position equal to this live position before it got changed.\n */\nexport type LivePositionChangeEvent = {\n\tname: 'change';\n\targs: [ oldPosition: Position ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/batch\n */\n\nimport { logWarning } from '@ckeditor/ckeditor5-utils';\nimport type Operation from './operation/operation.js';\n\n/**\n * A batch instance groups model changes ({@link module:engine/model/operation/operation~Operation operations}). All operations\n * grouped in a single batch can be reverted together, so you can also think about a batch as of a single undo step. If you want\n * to extend a given undo step, you can add more changes to the batch using {@link module:engine/model/model~Model#enqueueChange}:\n *\n * ```ts\n * model.enqueueChange( batch, writer => {\n * \twriter.insertText( 'foo', paragraph, 'end' );\n * } );\n * ```\n *\n * @see module:engine/model/model~Model#enqueueChange\n * @see module:engine/model/model~Model#change\n */\nexport default class Batch implements BatchType {\n\t/**\n\t * An array of operations that compose this batch.\n\t */\n\tpublic readonly operations: Array<Operation>;\n\n\t/**\n\t * Whether the batch can be undone through the undo feature.\n\t */\n\tpublic readonly isUndoable: boolean;\n\n\t/**\n\t * Whether the batch includes operations created locally (`true`) or operations created on other, remote editors (`false`).\n\t */\n\tpublic readonly isLocal: boolean;\n\n\t/**\n\t * Whether the batch was created by the undo feature and undoes other operations.\n\t */\n\tpublic readonly isUndo: boolean;\n\n\t/**\n\t * Whether the batch includes operations connected with typing.\n\t */\n\tpublic readonly isTyping: boolean;\n\n\t/**\n\t * Creates a batch instance.\n\t *\n\t * @see module:engine/model/model~Model#enqueueChange\n\t * @see module:engine/model/model~Model#change\n\t * @param type A set of flags that specify the type of the batch. Batch type can alter how some of the features work\n\t * when encountering a given `Batch` instance (for example, when a feature listens to applied operations).\n\t */\n\tconstructor( type: BatchType = {} ) {\n\t\tif ( typeof type === 'string' ) {\n\t\t\ttype = type === 'transparent' ? { isUndoable: false } : {};\n\n\t\t\t/**\n\t\t\t * The string value for a `type` property of the `Batch` constructor has been deprecated and will be removed in the near future.\n\t\t\t * Please refer to the {@link module:engine/model/batch~Batch#constructor `Batch` constructor API documentation} for more\n\t\t\t * information.\n\t\t\t *\n\t\t\t * @error batch-constructor-deprecated-string-type\n\t\t\t */\n\t\t\tlogWarning( 'batch-constructor-deprecated-string-type' );\n\t\t}\n\n\t\tconst { isUndoable = true, isLocal = true, isUndo = false, isTyping = false } = type;\n\n\t\tthis.operations = [];\n\t\tthis.isUndoable = isUndoable;\n\t\tthis.isLocal = isLocal;\n\t\tthis.isUndo = isUndo;\n\t\tthis.isTyping = isTyping;\n\t}\n\n\t/**\n\t * The type of the batch.\n\t *\n\t * **This property has been deprecated and is always set to the `'default'` value.**\n\t *\n\t * It can be one of the following values:\n\t * * `'default'` &ndash; All \"normal\" batches. This is the most commonly used type.\n\t * * `'transparent'` &ndash; A batch that should be ignored by other features, i.e. an initial batch or collaborative editing\n\t * changes.\n\t *\n\t * @deprecated\n\t */\n\tpublic get type(): 'default' {\n\t\t/**\n\t\t * The {@link module:engine/model/batch~Batch#type `Batch#type` } property has been deprecated and will be removed in the near\n\t\t * future. Use `Batch#isLocal`, `Batch#isUndoable`, `Batch#isUndo` and `Batch#isTyping` instead.\n\t\t *\n\t\t * @error batch-type-deprecated\n\t\t */\n\t\tlogWarning( 'batch-type-deprecated' );\n\n\t\treturn 'default';\n\t}\n\n\t/**\n\t * Returns the base version of this batch, which is equal to the base version of the first operation in the batch.\n\t * If there are no operations in the batch or neither operation has the base version set, it returns `null`.\n\t */\n\tpublic get baseVersion(): number | null {\n\t\tfor ( const op of this.operations ) {\n\t\t\tif ( op.baseVersion !== null ) {\n\t\t\t\treturn op.baseVersion;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Adds an operation to the batch instance.\n\t *\n\t * @param operation An operation to add.\n\t * @returns The added operation.\n\t */\n\tpublic addOperation( operation: Operation ): Operation {\n\t\toperation.batch = this;\n\t\tthis.operations.push( operation );\n\n\t\treturn operation;\n\t}\n}\n\n/**\n * A set of flags that specify the type of the batch. Batch type can alter how some of the features work\n * when encountering a given `Batch` instance (for example, when a feature listens to applied operations).\n */\nexport interface BatchType {\n\n\t/**\n\t * Whether a batch can be undone through undo feature.\n\t *\n\t * @default true\n\t */\n\tisUndoable?: boolean;\n\n\t/**\n\t * Whether a batch includes operations created locally (`true`) or operations created on\n\t * other, remote editors (`false`).\n\t *\n\t * @default true\n\t */\n\tisLocal?: boolean;\n\n\t/**\n\t * Whether a batch was created by the undo feature and undoes other operations.\n\t *\n\t * @default false\n\t */\n\tisUndo?: boolean;\n\n\t/**\n\t * Whether a batch includes operations connected with a typing action.\n\t *\n\t * @default false\n\t */\n\tisTyping?: boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/differ\n */\n\nimport Position from './position.js';\nimport Range from './range.js';\n\nimport type { default as MarkerCollection, MarkerData } from './markercollection.js';\nimport type AttributeOperation from './operation/attributeoperation.js';\nimport type DocumentFragment from './documentfragment.js';\nimport type Element from './element.js';\nimport type InsertOperation from './operation/insertoperation.js';\nimport type Item from './item.js';\nimport type MergeOperation from './operation/mergeoperation.js';\nimport type MoveOperation from './operation/moveoperation.js';\nimport type Node from './node.js';\nimport type RootElement from './rootelement.js';\nimport type Operation from './operation/operation.js';\nimport type RenameOperation from './operation/renameoperation.js';\nimport type SplitOperation from './operation/splitoperation.js';\nimport type RootOperation from './operation/rootoperation.js';\nimport type RootAttributeOperation from './operation/rootattributeoperation.js';\n\n/**\n * Calculates the difference between two model states.\n *\n * Receives operations that are to be applied on the model document. Marks parts of the model document tree which\n * are changed and saves the state of these elements before the change. Then, it compares saved elements with the\n * changed elements, after all changes are applied on the model document. Calculates the diff between saved\n * elements and new ones and returns a change set.\n */\nexport default class Differ {\n\t/**\n\t * Priority of the {@link ~Differ#_elementState element states}. States on higher indexes of the array can overwrite states on the lower\n\t * indexes.\n\t */\n\tprivate static readonly _statesPriority = [ undefined, 'refresh', 'rename', 'move' ];\n\n\t/**\n\t * Reference to the model's marker collection.\n\t */\n\tprivate readonly _markerCollection: MarkerCollection;\n\n\t/**\n\t * A map that stores changes that happened in a given element.\n\t *\n\t * The keys of the map are references to the model elements.\n\t * The values of the map are arrays with changes that were done on this element.\n\t */\n\tprivate readonly _changesInElement: Map<Element | DocumentFragment, Array<ChangeItem>> = new Map();\n\n\t/**\n\t * Stores a snapshot for these model nodes that might have changed.\n\t *\n\t * This complements {@link ~Differ#_elementChildrenSnapshots `_elementChildrenSnapshots`}.\n\t *\n\t * See also {@link ~DifferSnapshot}.\n\t */\n\tprivate readonly _elementsSnapshots: Map<Node, DifferSnapshot> = new Map();\n\n\t/**\n\t * For each element or document fragment inside which there was a change, it stores a snapshot of the child nodes list (an array\n\t * of children snapshots that represent the state in the element / fragment before any change has happened).\n\t *\n\t * This complements {@link ~Differ#_elementsSnapshots `_elementsSnapshots`}.\n\t *\n\t * See also {@link ~DifferSnapshot}.\n\t */\n\tprivate readonly _elementChildrenSnapshots: Map<Element | DocumentFragment, Array<DifferSnapshot>> = new Map();\n\n\t/**\n\t * Keeps the state for a given element, describing how the element was changed so far. It is used to evaluate the `action` property\n\t * of diff items returned by {@link ~Differ#getChanges}.\n\t *\n\t * Possible values, in the order from the lowest priority to the highest priority:\n\t *\n\t * * `'refresh'` - element was refreshed,\n\t * * `'rename'` - element was renamed,\n\t * * `'move'` - element was moved (or, usually, removed, that is moved to the graveyard).\n\t *\n\t * Element that was refreshed, may change its state to `'rename'` if it was later renamed, or to `'move'` if it was removed.\n\t * But the element cannot change its state from `'move'` to `'rename'`, or from `'rename'` to `'refresh'`.\n\t *\n\t * Only already existing elements are registered in `_elementState`. If a new element was inserted as a result of a buffered operation,\n\t * it is not be registered in `_elementState`.\n\t */\n\tprivate readonly _elementState: Map<Element, 'rename' | 'refresh' | 'move'> = new Map();\n\n\t/**\n\t * A map that stores all changed markers.\n\t *\n\t * The keys of the map are marker names.\n\t *\n\t * The values of the map are objects with the following properties:\n\t *\n\t * * `oldMarkerData`,\n\t * * `newMarkerData`.\n\t */\n\tprivate readonly _changedMarkers: Map<string, { newMarkerData: MarkerData; oldMarkerData: MarkerData }> = new Map();\n\n\t/**\n\t * A map that stores all roots that have been changed.\n\t *\n\t * The keys are the names of the roots while value represents the changes.\n\t */\n\tprivate readonly _changedRoots: Map<string, DiffItemRoot> = new Map();\n\n\t/**\n\t * Stores the number of changes that were processed. Used to order the changes chronologically. It is important\n\t * when changes are sorted.\n\t */\n\tprivate _changeCount: number = 0;\n\n\t/**\n\t * For efficiency purposes, `Differ` stores the change set returned by the differ after {@link #getChanges} call.\n\t * Cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t * return the cached value instead of calculating it again.\n\t *\n\t * This property stores those changes that did not take place in graveyard root.\n\t */\n\tprivate _cachedChanges: Array<DiffItem> | null = null;\n\n\t/**\n\t * For efficiency purposes, `Differ` stores the change set returned by the differ after the {@link #getChanges} call.\n\t * The cache is reset each time a new operation is buffered. If the cache has not been reset, {@link #getChanges} will\n\t * return the cached value instead of calculating it again.\n\t *\n\t * This property stores all changes evaluated by `Differ`, including those that took place in the graveyard.\n\t */\n\tprivate _cachedChangesWithGraveyard: Array<DiffItem> | null = null;\n\n\t/**\n\t * Set of model items that were marked to get refreshed in {@link #_refreshItem}.\n\t */\n\tprivate _refreshedItems: Set<Item> = new Set();\n\n\t/**\n\t * Creates a `Differ` instance.\n\t *\n\t * @param markerCollection Model's marker collection.\n\t */\n\tconstructor( markerCollection: MarkerCollection ) {\n\t\tthis._markerCollection = markerCollection;\n\t}\n\n\t/**\n\t * Informs whether there are any changes buffered in `Differ`.\n\t */\n\tpublic get isEmpty(): boolean {\n\t\treturn this._changesInElement.size == 0 && this._changedMarkers.size == 0 && this._changedRoots.size == 0;\n\t}\n\n\t/**\n\t * Buffers the given operation. **An operation has to be buffered before it is executed.**\n\t *\n\t * @param operationToBuffer An operation to buffer.\n\t */\n\tpublic bufferOperation( operationToBuffer: Operation ): void {\n\t\t// Below we take an operation, check its type, then use its parameters in marking (private) methods.\n\t\t// The general rule is to not mark elements inside inserted element. All inserted elements are re-rendered.\n\t\t// Marking changes in them would cause a \"double\" changing then.\n\t\t//\n\t\tconst operation = operationToBuffer as (\n\t\t\tInsertOperation |\n\t\t\tAttributeOperation |\n\t\t\tMoveOperation |\n\t\t\tRenameOperation |\n\t\t\tSplitOperation |\n\t\t\tMergeOperation |\n\t\t\tRootOperation |\n\t\t\tRootAttributeOperation\n\t\t);\n\n\t\t// Note: an operation that happens inside a non-loaded root will be ignored. If the operation happens partially inside\n\t\t// a non-loaded root, that part will be ignored (this may happen for move or marker operations).\n\t\t//\n\t\tswitch ( operation.type ) {\n\t\t\tcase 'insert': {\n\t\t\t\tif ( this._isInInsertedElement( operation.position.parent ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._markInsert( operation.position.parent, operation.position.offset, operation.nodes.maxOffset );\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'addAttribute':\n\t\t\tcase 'removeAttribute':\n\t\t\tcase 'changeAttribute': {\n\t\t\t\tfor ( const item of operation.range.getItems( { shallow: true } ) ) {\n\t\t\t\t\tif ( this._isInInsertedElement( item.parent! ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._markAttribute( item );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'remove':\n\t\t\tcase 'move':\n\t\t\tcase 'reinsert': {\n\t\t\t\t// When range is moved to the same position then not mark it as a change.\n\t\t\t\t// See: https://github.com/ckeditor/ckeditor5-engine/issues/1664.\n\t\t\t\tif (\n\t\t\t\t\toperation.sourcePosition.isEqual( operation.targetPosition ) ||\n\t\t\t\t\toperation.sourcePosition.getShiftedBy( operation.howMany ).isEqual( operation.targetPosition )\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst sourceParentInserted = this._isInInsertedElement( operation.sourcePosition.parent );\n\t\t\t\tconst targetParentInserted = this._isInInsertedElement( operation.targetPosition.parent );\n\n\t\t\t\tif ( !sourceParentInserted ) {\n\t\t\t\t\tthis._markRemove( operation.sourcePosition.parent, operation.sourcePosition.offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\tif ( !targetParentInserted ) {\n\t\t\t\t\tthis._markInsert( operation.targetPosition.parent, operation.getMovedRangeStart().offset, operation.howMany );\n\t\t\t\t}\n\n\t\t\t\t// Remember -- operation is buffered before it is executed. So, it was not executed yet.\n\t\t\t\tconst range = Range._createFromPositionAndShift( operation.sourcePosition, operation.howMany );\n\n\t\t\t\tfor ( const node of range.getItems( { shallow: true } ) ) {\n\t\t\t\t\tthis._setElementState( node, 'move' );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'rename': {\n\t\t\t\tif ( this._isInInsertedElement( operation.position.parent ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._markRemove( operation.position.parent, operation.position.offset, 1 );\n\t\t\t\tthis._markInsert( operation.position.parent, operation.position.offset, 1 );\n\n\t\t\t\tconst range = Range._createFromPositionAndShift( operation.position, 1 );\n\n\t\t\t\tfor ( const marker of this._markerCollection.getMarkersIntersectingRange( range ) ) {\n\t\t\t\t\tconst markerData = marker.getData();\n\n\t\t\t\t\tthis.bufferMarkerChange( marker.name, markerData, markerData );\n\t\t\t\t}\n\n\t\t\t\tthis._setElementState( operation.position.nodeAfter!, 'rename' );\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'split': {\n\t\t\t\tconst splitElement = operation.splitPosition.parent;\n\n\t\t\t\t// Mark that children of the split element were removed.\n\t\t\t\tif ( !this._isInInsertedElement( splitElement ) ) {\n\t\t\t\t\tthis._markRemove( splitElement, operation.splitPosition.offset, operation.howMany );\n\n\t\t\t\t\t// Remember -- operation is buffered before it is executed. So, it was not executed yet.\n\t\t\t\t\tconst range = Range._createFromPositionAndShift( operation.splitPosition, operation.howMany );\n\n\t\t\t\t\tfor ( const node of range.getItems( { shallow: true } ) ) {\n\t\t\t\t\t\tthis._setElementState( node, 'move' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Mark that the new element (split copy) was inserted.\n\t\t\t\tif ( !this._isInInsertedElement( operation.insertionPosition.parent ) ) {\n\t\t\t\t\tthis._markInsert( operation.insertionPosition.parent, operation.insertionPosition.offset, 1 );\n\t\t\t\t}\n\n\t\t\t\t// If the split took the element from the graveyard, mark that the element from the graveyard was removed.\n\t\t\t\tif ( operation.graveyardPosition ) {\n\t\t\t\t\tthis._markRemove( operation.graveyardPosition.parent, operation.graveyardPosition.offset, 1 );\n\n\t\t\t\t\tthis._setElementState( operation.graveyardPosition.nodeAfter!, 'move' );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'merge': {\n\t\t\t\t// Mark that the merged element was removed.\n\t\t\t\tconst mergedElement = operation.sourcePosition.parent as Element;\n\n\t\t\t\tif ( !this._isInInsertedElement( mergedElement.parent! ) ) {\n\t\t\t\t\tthis._markRemove( mergedElement.parent!, mergedElement.startOffset!, 1 );\n\t\t\t\t}\n\n\t\t\t\t// Mark that the merged element was inserted into graveyard.\n\t\t\t\tconst graveyardParent = operation.graveyardPosition.parent;\n\n\t\t\t\tthis._markInsert( graveyardParent, operation.graveyardPosition.offset, 1 );\n\n\t\t\t\tthis._setElementState( mergedElement, 'move' );\n\n\t\t\t\t// Mark that children of merged element were inserted at new parent.\n\t\t\t\tconst mergedIntoElement = operation.targetPosition.parent;\n\n\t\t\t\tif ( !this._isInInsertedElement( mergedIntoElement ) ) {\n\t\t\t\t\tthis._markInsert( mergedIntoElement, operation.targetPosition.offset, mergedElement.maxOffset );\n\n\t\t\t\t\t// Remember -- operation is buffered before it is executed. So, it was not executed yet.\n\t\t\t\t\tconst range = Range._createFromPositionAndShift( operation.sourcePosition, operation.howMany );\n\n\t\t\t\t\tfor ( const node of range.getItems( { shallow: true } ) ) {\n\t\t\t\t\t\tthis._setElementState( node, 'move' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'detachRoot':\n\t\t\tcase 'addRoot': {\n\t\t\t\tconst root = operation.affectedSelectable as RootElement;\n\n\t\t\t\tif ( !root._isLoaded ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Don't buffer if the root state does not change.\n\t\t\t\tif ( root.isAttached() == operation.isAdd ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._bufferRootStateChange( operation.rootName, operation.isAdd );\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'addRootAttribute':\n\t\t\tcase 'removeRootAttribute':\n\t\t\tcase 'changeRootAttribute': {\n\t\t\t\tif ( !operation.root._isLoaded ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst rootName = operation.root.rootName;\n\n\t\t\t\tthis._bufferRootAttributeChange( rootName, operation.key, operation.oldValue, operation.newValue );\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// Clear cache after each buffered operation as it is no longer valid.\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Buffers a marker change.\n\t *\n\t * @param markerName The name of the marker that changed.\n\t * @param oldMarkerData Marker data before the change.\n\t * @param newMarkerData Marker data after the change.\n\t */\n\tpublic bufferMarkerChange( markerName: string, oldMarkerData: MarkerData, newMarkerData: MarkerData ): void {\n\t\tif ( oldMarkerData.range && oldMarkerData.range.root.is( 'rootElement' ) && !oldMarkerData.range.root._isLoaded ) {\n\t\t\toldMarkerData.range = null;\n\t\t}\n\n\t\tif ( newMarkerData.range && newMarkerData.range.root.is( 'rootElement' ) && !newMarkerData.range.root._isLoaded ) {\n\t\t\tnewMarkerData.range = null;\n\t\t}\n\n\t\tlet buffered = this._changedMarkers.get( markerName );\n\n\t\tif ( !buffered ) {\n\t\t\tbuffered = { newMarkerData, oldMarkerData };\n\n\t\t\tthis._changedMarkers.set( markerName, buffered );\n\t\t} else {\n\t\t\tbuffered.newMarkerData = newMarkerData;\n\t\t}\n\n\t\tif ( buffered.oldMarkerData.range == null && newMarkerData.range == null ) {\n\t\t\t// The marker is going to be removed (`newMarkerData.range == null`) but it did not exist before the first buffered change\n\t\t\t// (`buffered.oldMarkerData.range == null`). In this case, do not keep the marker in buffer at all.\n\t\t\tthis._changedMarkers.delete( markerName );\n\t\t}\n\t}\n\n\t/**\n\t * Returns all markers that should be removed as a result of buffered changes.\n\t *\n\t * @returns Markers to remove. Each array item is an object containing the `name` and `range` properties.\n\t */\n\tpublic getMarkersToRemove(): Array<{ name: string; range: Range }> {\n\t\tconst result = [];\n\n\t\tfor ( const [ name, change ] of this._changedMarkers ) {\n\t\t\tif ( change.oldMarkerData.range != null ) {\n\t\t\t\tresult.push( { name, range: change.oldMarkerData.range } );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns all markers which should be added as a result of buffered changes.\n\t *\n\t * @returns Markers to add. Each array item is an object containing the `name` and `range` properties.\n\t */\n\tpublic getMarkersToAdd(): Array<{ name: string; range: Range }> {\n\t\tconst result = [];\n\n\t\tfor ( const [ name, change ] of this._changedMarkers ) {\n\t\t\tif ( change.newMarkerData.range != null ) {\n\t\t\t\tresult.push( { name, range: change.newMarkerData.range } );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Returns all markers which changed.\n\t */\n\tpublic getChangedMarkers(): Array<{\n\t\tname: string;\n\t\tdata: {\n\t\t\toldRange: Range | null;\n\t\t\tnewRange: Range | null;\n\t\t};\n\t}> {\n\t\treturn Array.from( this._changedMarkers ).map( ( [ name, change ] ) => (\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdata: {\n\t\t\t\t\toldRange: change.oldMarkerData.range,\n\t\t\t\t\tnewRange: change.newMarkerData.range\n\t\t\t\t}\n\t\t\t}\n\t\t) );\n\t}\n\n\t/**\n\t * Checks whether some of the buffered changes affect the editor data.\n\t *\n\t * Types of changes which affect the editor data:\n\t *\n\t * * model structure changes,\n\t * * attribute changes,\n\t * * a root is added or detached,\n\t * * changes of markers which were defined as `affectsData`,\n\t * * changes of markers' `affectsData` property.\n\t */\n\tpublic hasDataChanges(): boolean {\n\t\tif ( this.getChanges().length ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( this._changedRoots.size > 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tfor ( const { newMarkerData, oldMarkerData } of this._changedMarkers.values() ) {\n\t\t\tif ( newMarkerData.affectsData !== oldMarkerData.affectsData ) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif ( newMarkerData.affectsData ) {\n\t\t\t\tconst markerAdded = newMarkerData.range && !oldMarkerData.range;\n\t\t\t\tconst markerRemoved = !newMarkerData.range && oldMarkerData.range;\n\t\t\t\tconst markerChanged = newMarkerData.range && oldMarkerData.range && !newMarkerData.range.isEqual( oldMarkerData.range );\n\n\t\t\t\tif ( markerAdded || markerRemoved || markerChanged ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Calculates the diff between the old model tree state (the state before the first buffered operations since the last {@link #reset}\n\t * call) and the new model tree state (actual one). It should be called after all buffered operations are executed.\n\t *\n\t * The diff set is returned as an array of {@link module:engine/model/differ~DiffItem diff items}, each describing a change done\n\t * on the model. The items are sorted by the position on which the change happened. If a position\n\t * {@link module:engine/model/position~Position#isBefore is before} another one, it will be on an earlier index in the diff set.\n\t *\n\t * **Note**: Elements inside inserted element will not have a separate diff item, only the top most element change will be reported.\n\t *\n\t * Because calculating the diff is a costly operation, the result is cached. If no new operation was buffered since the\n\t * previous {@link #getChanges} call, the next call will return the cached value.\n\t *\n\t * @param options Additional options.\n\t * @param options.includeChangesInGraveyard If set to `true`, also changes that happened\n\t * in the graveyard root will be returned. By default, changes in the graveyard root are not returned.\n\t * @returns Diff between the old and the new model tree state.\n\t */\n\tpublic getChanges( options: { includeChangesInGraveyard?: boolean } = {} ): Array<DiffItem> {\n\t\t// If there are cached changes, just return them instead of calculating changes again.\n\t\tif ( this._cachedChanges ) {\n\t\t\tif ( options.includeChangesInGraveyard ) {\n\t\t\t\treturn this._cachedChangesWithGraveyard!.slice();\n\t\t\t} else {\n\t\t\t\treturn this._cachedChanges.slice();\n\t\t\t}\n\t\t}\n\n\t\t// Will contain returned results.\n\t\tlet diffSet: Array<DiffItem & DiffItemInternal> = [];\n\n\t\t// Check all changed elements/roots.\n\t\tfor ( const element of this._changesInElement.keys() ) {\n\t\t\t// Get changes inside this element/root and sort them.\n\t\t\tconst changes = this._changesInElement.get( element )!.sort( ( a, b ) => {\n\t\t\t\tif ( a.offset === b.offset ) {\n\t\t\t\t\tif ( a.type != b.type ) {\n\t\t\t\t\t\t// If there are multiple changes at the same position, \"remove\" change should be first.\n\t\t\t\t\t\t// If the order is different, for example, we would first add some nodes and then removed them\n\t\t\t\t\t\t// (instead of the nodes that we should remove).\n\t\t\t\t\t\treturn a.type == 'remove' ? -1 : 1;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn a.offset < b.offset ? -1 : 1;\n\t\t\t} );\n\n\t\t\t// Get children of this element before any change was applied on it.\n\t\t\tconst childrenBefore = this._elementChildrenSnapshots.get( element )!;\n\t\t\t// Get snapshot of current element's children.\n\t\t\tconst childrenAfter = _getChildrenSnapshots( element.getChildren() );\n\n\t\t\t// Generate diff instructions based on changes done in the element/root.\n\t\t\tconst diffInstructions = _generateDiffInstructionsFromChanges( childrenBefore.length, changes );\n\n\t\t\tlet i = 0; // Iterator in `childrenAfter` array -- iterates through current children of element.\n\t\t\tlet j = 0; // Iterator in `childrenBefore` array -- iterates through old children of element.\n\n\t\t\t// Process every action.\n\t\t\tfor ( const instruction of diffInstructions ) {\n\t\t\t\tif ( instruction === 'i' ) {\n\t\t\t\t\tconst action = this._getDiffActionForNode( childrenAfter[ i ].node, 'insert' );\n\t\t\t\t\tconst childSnapshotBefore = this._elementsSnapshots.get( childrenAfter[ i ].node );\n\t\t\t\t\tconst diffItem = this._getInsertDiff( element, i, action, childrenAfter[ i ], childSnapshotBefore );\n\n\t\t\t\t\tdiffSet.push( diffItem );\n\n\t\t\t\t\ti++;\n\t\t\t\t} else if ( instruction === 'r' ) {\n\t\t\t\t\tconst action = this._getDiffActionForNode( childrenBefore[ j ].node, 'remove' );\n\t\t\t\t\tconst diffItem = this._getRemoveDiff( element, i, action, childrenBefore[ j ] );\n\n\t\t\t\t\tdiffSet.push( diffItem );\n\n\t\t\t\t\tj++;\n\t\t\t\t} else if ( instruction === 'a' ) {\n\t\t\t\t\t// Take attributes from saved and current children.\n\t\t\t\t\tconst beforeAttributes = childrenBefore[ j ].attributes;\n\t\t\t\t\tconst afterAttributes = childrenAfter[ i ].attributes;\n\t\t\t\t\tlet range;\n\n\t\t\t\t\tif ( childrenAfter[ i ].name == '$text' ) {\n\t\t\t\t\t\trange = new Range( Position._createAt( element, i ), Position._createAt( element, i + 1 ) );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst index = element.offsetToIndex( i );\n\t\t\t\t\t\trange = new Range( Position._createAt( element, i ), Position._createAt( element.getChild( index )!, 0 ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Generate diff items for this change (there might be multiple attributes changed and\n\t\t\t\t\t// there is a single diff for each of them) and insert them into the diff set.\n\t\t\t\t\tconst diffItems = this._getAttributesDiff( range, beforeAttributes, afterAttributes );\n\n\t\t\t\t\tdiffSet.push( ...diffItems );\n\n\t\t\t\t\ti++;\n\t\t\t\t\tj++;\n\t\t\t\t} else {\n\t\t\t\t\t// `action` is 'equal'. Child not changed.\n\t\t\t\t\ti++;\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Then, sort the changes by the position (change at position before other changes is first).\n\t\tdiffSet.sort( ( a, b ) => {\n\t\t\t// If the change is in different root, we don't care much, but we'd like to have all changes in given\n\t\t\t// root \"together\" in the array. So let's just sort them by the root name. It does not matter which root\n\t\t\t// will be processed first.\n\t\t\tif ( a.position!.root != b.position!.root ) {\n\t\t\t\treturn a.position!.root.rootName! < b.position!.root.rootName! ? -1 : 1;\n\t\t\t}\n\n\t\t\t// If change happens at the same position...\n\t\t\tif ( a.position!.isEqual( b.position! ) ) {\n\t\t\t\t// Keep chronological order of operations.\n\t\t\t\treturn a.changeCount! - b.changeCount!;\n\t\t\t}\n\n\t\t\t// If positions differ, position \"on the left\" should be earlier in the result.\n\t\t\treturn a.position!.isBefore( b.position! ) ? -1 : 1;\n\t\t} );\n\n\t\t// Glue together multiple changes (mostly on text nodes).\n\t\tfor ( let i = 1, prevIndex = 0; i < diffSet.length; i++ ) {\n\t\t\tconst prevDiff = diffSet[ prevIndex ];\n\t\t\tconst thisDiff = diffSet[ i ];\n\n\t\t\t// Glue remove changes if they happen on text on same position.\n\t\t\tconst isConsecutiveTextRemove =\n\t\t\t\tprevDiff.type == 'remove' && thisDiff.type == 'remove' &&\n\t\t\t\tprevDiff.name == '$text' && thisDiff.name == '$text' &&\n\t\t\t\tprevDiff.position.isEqual( thisDiff.position );\n\n\t\t\t// Glue insert changes if they happen on text on consecutive fragments.\n\t\t\tconst isConsecutiveTextAdd =\n\t\t\t\tprevDiff.type == 'insert' && thisDiff.type == 'insert' &&\n\t\t\t\tprevDiff.name == '$text' && thisDiff.name == '$text' &&\n\t\t\t\tprevDiff.position.parent == thisDiff.position.parent &&\n\t\t\t\tprevDiff.position.offset + prevDiff.length == thisDiff.position.offset;\n\n\t\t\t// Glue attribute changes if they happen on consecutive fragments and have same key, old value and new value.\n\t\t\tconst isConsecutiveAttributeChange =\n\t\t\t\tprevDiff.type == 'attribute' && thisDiff.type == 'attribute' &&\n\t\t\t\tprevDiff.position!.parent == thisDiff.position!.parent &&\n\t\t\t\tprevDiff.range.isFlat && thisDiff.range.isFlat &&\n\t\t\t\t( prevDiff.position!.offset + prevDiff.length! ) == thisDiff.position!.offset &&\n\t\t\t\tprevDiff.attributeKey == thisDiff.attributeKey &&\n\t\t\t\tprevDiff.attributeOldValue == thisDiff.attributeOldValue &&\n\t\t\t\tprevDiff.attributeNewValue == thisDiff.attributeNewValue;\n\n\t\t\tif ( isConsecutiveTextRemove || isConsecutiveTextAdd || isConsecutiveAttributeChange ) {\n\t\t\t\tprevDiff.length!++;\n\n\t\t\t\tif ( isConsecutiveAttributeChange ) {\n\t\t\t\t\t( prevDiff.range as any ).end = prevDiff.range.end.getShiftedBy( 1 );\n\t\t\t\t}\n\n\t\t\t\tdiffSet[ i ] = null as any;\n\t\t\t} else {\n\t\t\t\tprevIndex = i;\n\t\t\t}\n\t\t}\n\n\t\tdiffSet = diffSet.filter( v => v );\n\n\t\t// Remove `changeCount` property from diff items. It is used only for sorting and is internal thing.\n\t\tfor ( const item of diffSet ) {\n\t\t\tdelete item.changeCount;\n\n\t\t\tif ( item.type == 'attribute' ) {\n\t\t\t\tdelete item.position;\n\t\t\t\tdelete item.length;\n\t\t\t}\n\t\t}\n\n\t\tthis._changeCount = 0;\n\n\t\t// Cache changes.\n\t\tthis._cachedChangesWithGraveyard = diffSet;\n\t\tthis._cachedChanges = diffSet.filter( _changesInGraveyardFilter );\n\n\t\tif ( options.includeChangesInGraveyard ) {\n\t\t\treturn this._cachedChangesWithGraveyard.slice();\n\t\t} else {\n\t\t\treturn this._cachedChanges.slice();\n\t\t}\n\t}\n\n\t/**\n\t * Returns all roots that have changed (either were attached, or detached, or their attributes changed).\n\t *\n\t * @returns Diff between the old and the new roots state.\n\t */\n\tpublic getChangedRoots(): Array<DiffItemRoot> {\n\t\treturn Array.from( this._changedRoots.values() ).map( diffItem => {\n\t\t\tconst entry = { ...diffItem };\n\n\t\t\tif ( entry.state !== undefined ) {\n\t\t\t\t// The root was attached or detached -- do not return its attributes changes.\n\t\t\t\t// If the root was attached, it should be handled as a whole, together with its attributes, the same way as model nodes.\n\t\t\t\t// If the root was detached, its attributes should be discarded anyway.\n\t\t\t\t//\n\t\t\t\t// Keep in mind that filtering must happen on this stage (when retrieving changes). If filtering happens on-the-fly as\n\t\t\t\t// the attributes change, it may lead to incorrect situation, e.g.: detach root, change attribute, re-attach root.\n\t\t\t\t// In this case, attribute change cannot be filtered. After the root is re-attached, the attribute change must be kept.\n\t\t\t\tdelete entry.attributes;\n\t\t\t}\n\n\t\t\treturn entry;\n\t\t} );\n\t}\n\n\t/**\n\t * Returns a set of model items that were marked to get refreshed.\n\t */\n\tpublic getRefreshedItems(): Set<Item> {\n\t\treturn new Set( this._refreshedItems );\n\t}\n\n\t/**\n\t * Resets `Differ`. Removes all buffered changes.\n\t */\n\tpublic reset(): void {\n\t\tthis._changesInElement.clear();\n\t\tthis._elementChildrenSnapshots.clear();\n\t\tthis._elementsSnapshots.clear();\n\t\tthis._elementState.clear();\n\t\tthis._changedMarkers.clear();\n\t\tthis._changedRoots.clear();\n\t\tthis._refreshedItems.clear();\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Marks the given `item` in differ to be \"refreshed\". It means that the item will be marked as removed and inserted\n\t * in the differ changes set, so it will be effectively re-converted when the differ changes are handled by a dispatcher.\n\t *\n\t * @internal\n\t * @param item Item to refresh.\n\t */\n\tpublic _refreshItem( item: Item ): void {\n\t\tif ( this._isInInsertedElement( item.parent! ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._markRemove( item.parent!, item.startOffset!, item.offsetSize );\n\t\tthis._markInsert( item.parent!, item.startOffset!, item.offsetSize );\n\n\t\tthis._refreshedItems.add( item );\n\t\tthis._setElementState( item, 'refresh' );\n\n\t\tconst range = Range._createOn( item );\n\n\t\tfor ( const marker of this._markerCollection.getMarkersIntersectingRange( range ) ) {\n\t\t\tconst markerData = marker.getData();\n\n\t\t\tthis.bufferMarkerChange( marker.name, markerData, markerData );\n\t\t}\n\n\t\t// Clear cache after each buffered operation as it is no longer valid.\n\t\tthis._cachedChanges = null;\n\t}\n\n\t/**\n\t * Buffers all the data related to given root like it was all just added to the editor.\n\t *\n\t * Following changes are buffered:\n\t *\n\t * * root is attached,\n\t * * all root content is inserted,\n\t * * all root attributes are added,\n\t * * all markers inside the root are added.\n\t *\n\t * @internal\n\t */\n\tpublic _bufferRootLoad( root: RootElement ): void {\n\t\tif ( !root.isAttached() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._bufferRootStateChange( root.rootName, true );\n\t\tthis._markInsert( root, 0, root.maxOffset );\n\n\t\t// Buffering root attribute changes makes sense and is actually needed, even though we buffer root state change above.\n\t\t// Because the root state change is buffered, the root attributes changes are not returned by the differ.\n\t\t// But, if the root attribute is removed in the same change block, or the root is detached, then the differ results would be wrong.\n\t\t//\n\t\tfor ( const key of root.getAttributeKeys() ) {\n\t\t\tthis._bufferRootAttributeChange( root.rootName, key, null, root.getAttribute( key ) );\n\t\t}\n\n\t\tfor ( const marker of this._markerCollection ) {\n\t\t\tif ( marker.getRange().root == root ) {\n\t\t\t\tconst markerData = marker.getData();\n\n\t\t\t\tthis.bufferMarkerChange( marker.name, { ...markerData, range: null }, markerData );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Buffers the root state change after the root was attached or detached\n\t */\n\tprivate _bufferRootStateChange( rootName: string, isAttached: boolean ): void {\n\t\tif ( !this._changedRoots.has( rootName ) ) {\n\t\t\tthis._changedRoots.set( rootName, { name: rootName, state: isAttached ? 'attached' : 'detached' } );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst diffItem = this._changedRoots.get( rootName )!;\n\n\t\tif ( diffItem.state !== undefined ) {\n\t\t\t// Root `state` can only toggle between one of the values and no value. It cannot be any other way,\n\t\t\t// because if the root was originally attached it can only become detached. Then, if it is re-attached in the same batch of\n\t\t\t// changes, it gets back to \"no change\" (which means no value). Same if the root was originally detached.\n\t\t\tdelete diffItem.state;\n\n\t\t\tif ( diffItem.attributes === undefined ) {\n\t\t\t\t// If there is no `state` change and no `attributes` change, remove the entry.\n\t\t\t\tthis._changedRoots.delete( rootName );\n\t\t\t}\n\t\t} else {\n\t\t\tdiffItem.state = isAttached ? 'attached' : 'detached';\n\t\t}\n\t}\n\n\t/**\n\t * Buffers a root attribute change.\n\t */\n\tprivate _bufferRootAttributeChange( rootName: string, key: string, oldValue: unknown, newValue: unknown ): void {\n\t\tconst diffItem: DiffItemRoot = this._changedRoots.get( rootName ) || { name: rootName };\n\t\tconst attrs: Record<string, { oldValue: unknown; newValue: unknown }> = diffItem.attributes || {};\n\n\t\tif ( attrs[ key ] ) {\n\t\t\t// If this attribute or metadata was already changed earlier and is changed again, check to what value it is changed.\n\t\t\tconst attrEntry = attrs[ key ];\n\n\t\t\tif ( newValue === attrEntry.oldValue ) {\n\t\t\t\t// If it was changed back to the old value, remove the entry.\n\t\t\t\tdelete attrs[ key ];\n\t\t\t} else {\n\t\t\t\t// If it was changed to a different value, update the entry.\n\t\t\t\tattrEntry.newValue = newValue;\n\t\t\t}\n\t\t} else {\n\t\t\t// If this attribute or metadata was not set earlier, add an entry.\n\t\t\tattrs[ key ] = { oldValue, newValue };\n\t\t}\n\n\t\tif ( Object.entries( attrs ).length === 0 ) {\n\t\t\t// If attributes or metadata changes set became empty, remove it from the diff item.\n\t\t\tdelete diffItem.attributes;\n\n\t\t\tif ( diffItem.state === undefined ) {\n\t\t\t\t// If there is no `state` change and no `attributes` change, remove the entry.\n\t\t\t\tthis._changedRoots.delete( rootName );\n\t\t\t}\n\t\t} else {\n\t\t\t// Make sure that, if a new object in the structure was created, it gets set.\n\t\t\tdiffItem.attributes = attrs;\n\n\t\t\tthis._changedRoots.set( rootName, diffItem );\n\t\t}\n\t}\n\n\t/**\n\t * Saves and handles an insert change.\n\t */\n\tprivate _markInsert( parent: Element | DocumentFragment, offset: number, howMany: number ) {\n\t\tif ( parent.root.is( 'rootElement' ) && !parent.root._isLoaded ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst changeItem = { type: 'insert', offset, howMany, count: this._changeCount++ } as const;\n\n\t\tthis._markChange( parent, changeItem );\n\t}\n\n\t/**\n\t * Saves and handles a remove change.\n\t */\n\tprivate _markRemove( parent: Element | DocumentFragment, offset: number, howMany: number ) {\n\t\tif ( parent.root.is( 'rootElement' ) && !parent.root._isLoaded ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst changeItem = { type: 'remove', offset, howMany, count: this._changeCount++ } as const;\n\n\t\tthis._markChange( parent, changeItem );\n\n\t\tthis._removeAllNestedChanges( parent, offset, howMany );\n\t}\n\n\t/**\n\t * Saves and handles an attribute change.\n\t */\n\tprivate _markAttribute( item: Item ): void {\n\t\tif ( item.root.is( 'rootElement' ) && !item.root._isLoaded ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst changeItem = { type: 'attribute', offset: item.startOffset!, howMany: item.offsetSize, count: this._changeCount++ } as const;\n\n\t\tthis._markChange( item.parent as Element, changeItem );\n\t}\n\n\t/**\n\t * Saves and handles a model change.\n\t */\n\tprivate _markChange( parent: Element | DocumentFragment, changeItem: ChangeItem ): void {\n\t\t// First, make a snapshot of the parent and its children (it will be made only if it was not made before).\n\t\tthis._makeSnapshots( parent );\n\n\t\t// Then, get all changes that already were done on the element (empty array if this is the first change).\n\t\tconst changes = this._getChangesForElement( parent );\n\n\t\t// Then, look through all the changes, and transform them or the new change.\n\t\tthis._handleChange( changeItem, changes );\n\n\t\t// Add the new change.\n\t\tchanges.push( changeItem );\n\n\t\t// Remove incorrect changes. During transformation some change might be, for example, included in another.\n\t\t// In that case, the change will have `howMany` property set to `0` or less. We need to remove those changes.\n\t\tfor ( let i = 0; i < changes.length; i++ ) {\n\t\t\tif ( changes[ i ].howMany < 1 ) {\n\t\t\t\tchanges.splice( i, 1 );\n\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Tries to set given state for given item.\n\t *\n\t * This method does simple validation (it sets the state only for model elements, not for text proxy nodes). It also follows state\n\t * setting rules, that is, `'refresh'` cannot overwrite `'rename'`, and `'rename'` cannot overwrite `'move'`.\n\t */\n\tprivate _setElementState( node: Item, state: 'refresh' | 'rename' | 'move' ) {\n\t\tif ( !node.is( 'element' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst currentStatePriority = Differ._statesPriority.indexOf( this._elementState.get( node ) );\n\t\tconst newStatePriority = Differ._statesPriority.indexOf( state );\n\n\t\tif ( newStatePriority > currentStatePriority ) {\n\t\t\tthis._elementState.set( node, state );\n\t\t}\n\t}\n\n\t/**\n\t * Returns a value for {@link ~DifferItemAction `action`} property for diff items returned by {@link ~Differ#getChanges}.\n\t * This method aims to return `'rename'` or `'refresh'` when it should, and `diffItemType` (\"default action\") in all other cases.\n\t *\n\t * It bases on a few factors:\n\t *\n\t * * for text nodes, the method always returns `diffItemType`,\n\t * * for newly inserted element, the method returns `diffItemType`,\n\t * * if {@link ~Differ#_elementState element state} was not recorded, the method returns `diffItemType`,\n\t * * if state was recorded, and it was `'move'` (default action), the method returns `diffItemType`,\n\t * * finally, if state was `'refresh'` or `'rename'`, the method returns the state value.\n\t */\n\tprivate _getDiffActionForNode( node: Node, diffItemType: 'insert' | 'remove' ): DifferItemAction {\n\t\tif ( !node.is( 'element' ) ) {\n\t\t\t// Text node.\n\t\t\treturn diffItemType;\n\t\t}\n\n\t\tif ( !this._elementsSnapshots.has( node ) ) {\n\t\t\t// Newly inserted element.\n\t\t\treturn diffItemType;\n\t\t}\n\n\t\tconst state = this._elementState.get( node );\n\n\t\tif ( !state || state == 'move' ) {\n\t\t\treturn diffItemType;\n\t\t}\n\n\t\treturn state;\n\t}\n\n\t/**\n\t * Gets an array of changes that have already been saved for a given element.\n\t */\n\tprivate _getChangesForElement( element: Element | DocumentFragment ): Array<ChangeItem> {\n\t\tlet changes: Array<ChangeItem>;\n\n\t\tif ( this._changesInElement.has( element ) ) {\n\t\t\tchanges = this._changesInElement.get( element )!;\n\t\t} else {\n\t\t\tchanges = [];\n\n\t\t\tthis._changesInElement.set( element, changes );\n\t\t}\n\n\t\treturn changes;\n\t}\n\n\t/**\n\t * Creates and saves a snapshot for all children of the given element.\n\t */\n\tprivate _makeSnapshots( element: Element | DocumentFragment ): void {\n\t\tif ( this._elementChildrenSnapshots.has( element ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst childrenSnapshots = _getChildrenSnapshots( element.getChildren() );\n\n\t\tthis._elementChildrenSnapshots.set( element, childrenSnapshots );\n\n\t\tfor ( const snapshot of childrenSnapshots ) {\n\t\t\tthis._elementsSnapshots.set( snapshot.node, snapshot );\n\t\t}\n\t}\n\n\t/**\n\t * For a given newly saved change, compares it with a change already done on the element and modifies the incoming\n\t * change and/or the old change.\n\t *\n\t * @param inc Incoming (new) change.\n\t * @param changes An array containing all the changes done on that element.\n\t */\n\tprivate _handleChange( inc: ChangeItem, changes: Array<ChangeItem> ): void {\n\t\t// We need a helper variable that will store how many nodes are to be still handled for this change item.\n\t\t// `nodesToHandle` (how many nodes still need to be handled) and `howMany` (how many nodes were affected)\n\t\t// needs to be differentiated.\n\t\t//\n\t\t// This comes up when there are multiple changes that are affected by `inc` change item.\n\t\t//\n\t\t// For example: assume two insert changes: `{ offset: 2, howMany: 1 }` and `{ offset: 5, howMany: 1 }`.\n\t\t// Assume that `inc` change is remove `{ offset: 2, howMany: 2, nodesToHandle: 2 }`.\n\t\t//\n\t\t// Then, we:\n\t\t// - \"forget\" about first insert change (it is \"eaten\" by remove),\n\t\t// - because of that, at the end we will want to remove only one node (`nodesToHandle = 1`),\n\t\t// - but still we have to change offset of the second insert change from `5` to `3`!\n\t\t//\n\t\t// So, `howMany` does not change throughout items transformation and keeps information about how many nodes were affected,\n\t\t// while `nodesToHandle` means how many nodes need to be handled after the change item is transformed by other changes.\n\t\tinc.nodesToHandle = inc.howMany;\n\n\t\tfor ( const old of changes ) {\n\t\t\tconst incEnd = inc.offset + inc.howMany;\n\t\t\tconst oldEnd = old.offset + old.howMany;\n\n\t\t\tif ( inc.type == 'insert' ) {\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\told.howMany += inc.nodesToHandle;\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\tif ( inc.offset < old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\told.offset += inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\t// This case is more complicated, because attribute change has to be split into two.\n\t\t\t\t\t\t// Example (assume that uppercase and lowercase letters mean different attributes):\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// initial state:\t\tabcxyz\n\t\t\t\t\t\t// attribute change:\taBCXYz\n\t\t\t\t\t\t// incoming insert:\t\taBCfooXYz\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// Change ranges cannot intersect because each item has to be described exactly (it was either\n\t\t\t\t\t\t// not changed, inserted, removed, or its attribute was changed). That's why old attribute\n\t\t\t\t\t\t// change has to be split and both parts has to be handled separately from now on.\n\t\t\t\t\t\tconst howMany = old.howMany;\n\n\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\n\t\t\t\t\t\t// Add the second part of attribute change to the beginning of processed array so it won't\n\t\t\t\t\t\t// be processed again in this loop.\n\t\t\t\t\t\tchanges.unshift( {\n\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\toffset: incEnd,\n\t\t\t\t\t\t\thowMany: howMany - old.howMany,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( inc.type == 'remove' ) {\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( incEnd <= oldEnd ) {\n\t\t\t\t\t\tif ( inc.offset < old.offset ) {\n\t\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\n\t\t\t\t\t\t\told.offset = inc.offset;\n\n\t\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\told.howMany -= inc.nodesToHandle;\n\t\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( inc.offset <= old.offset ) {\n\t\t\t\t\t\t\tinc.nodesToHandle -= old.howMany;\n\t\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\t\tconst intersectionLength = oldEnd - inc.offset;\n\n\t\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t\t\tinc.nodesToHandle -= intersectionLength;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < old.offset ) {\n\t\t\t\t\t\tinc.nodesToHandle += old.howMany;\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\tif ( incEnd <= old.offset ) {\n\t\t\t\t\t\told.offset -= inc.howMany;\n\t\t\t\t\t} else if ( inc.offset < old.offset ) {\n\t\t\t\t\t\tconst intersectionLength = incEnd - old.offset;\n\n\t\t\t\t\t\told.offset = inc.offset;\n\t\t\t\t\t\told.howMany -= intersectionLength;\n\t\t\t\t\t} else if ( inc.offset < oldEnd ) {\n\t\t\t\t\t\tif ( incEnd <= oldEnd ) {\n\t\t\t\t\t\t\t// On first sight in this case we don't need to split attribute operation into two.\n\t\t\t\t\t\t\t// However the changes set is later converted to actions (see `_generateActionsFromChanges`).\n\t\t\t\t\t\t\t// For that reason, no two changes may intersect.\n\t\t\t\t\t\t\t// So we cannot have an attribute change that \"contains\" remove change.\n\t\t\t\t\t\t\t// Attribute change needs to be split.\n\t\t\t\t\t\t\tconst howMany = old.howMany;\n\n\t\t\t\t\t\t\told.howMany = inc.offset - old.offset;\n\n\t\t\t\t\t\t\tconst howManyAfter = howMany - old.howMany - inc.nodesToHandle;\n\n\t\t\t\t\t\t\t// Add the second part of attribute change to the beginning of processed array so it won't\n\t\t\t\t\t\t\t// be processed again in this loop.\n\t\t\t\t\t\t\tchanges.unshift( {\n\t\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\t\toffset: inc.offset,\n\t\t\t\t\t\t\t\thowMany: howManyAfter,\n\t\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\told.howMany -= oldEnd - inc.offset;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( inc.type == 'attribute' ) {\n\t\t\t\t// In case of attribute change, `howMany` should be kept same as `nodesToHandle`. It's not an error.\n\t\t\t\tif ( old.type == 'insert' ) {\n\t\t\t\t\tif ( inc.offset < old.offset && incEnd > old.offset ) {\n\t\t\t\t\t\tif ( incEnd > oldEnd ) {\n\t\t\t\t\t\t\t// This case is similar to a case described when incoming change was insert and old change was attribute.\n\t\t\t\t\t\t\t// See comment above.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// This time incoming change is attribute. We need to split incoming change in this case too.\n\t\t\t\t\t\t\t// However this time, the second part of the attribute change needs to be processed further\n\t\t\t\t\t\t\t// because there might be other changes that it collides with.\n\t\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\t\toffset: oldEnd,\n\t\t\t\t\t\t\t\thowMany: incEnd - oldEnd,\n\t\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t\t} as const;\n\n\t\t\t\t\t\t\tthis._handleChange( attributePart, changes );\n\n\t\t\t\t\t\t\tchanges.push( attributePart );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t} else if ( inc.offset >= old.offset && inc.offset < oldEnd ) {\n\t\t\t\t\t\tif ( incEnd > oldEnd ) {\n\t\t\t\t\t\t\tinc.nodesToHandle = incEnd - oldEnd;\n\t\t\t\t\t\t\tinc.offset = oldEnd;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'remove' ) {\n\t\t\t\t\t// This is a case when attribute change \"contains\" remove change.\n\t\t\t\t\t// The attribute change needs to be split into two because changes cannot intersect.\n\t\t\t\t\tif ( inc.offset < old.offset && incEnd > old.offset ) {\n\t\t\t\t\t\tconst attributePart = {\n\t\t\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\t\t\toffset: old.offset,\n\t\t\t\t\t\t\thowMany: incEnd - old.offset,\n\t\t\t\t\t\t\tcount: this._changeCount++\n\t\t\t\t\t\t} as const;\n\n\t\t\t\t\t\tthis._handleChange( attributePart, changes );\n\n\t\t\t\t\t\tchanges.push( attributePart );\n\n\t\t\t\t\t\tinc.nodesToHandle = old.offset - inc.offset;\n\t\t\t\t\t\tinc.howMany = inc.nodesToHandle;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( old.type == 'attribute' ) {\n\t\t\t\t\t// There are only two conflicting scenarios possible here:\n\t\t\t\t\tif ( inc.offset >= old.offset && incEnd <= oldEnd ) {\n\t\t\t\t\t\t// `old` change includes `inc` change, or they are the same.\n\t\t\t\t\t\tinc.nodesToHandle = 0;\n\t\t\t\t\t\tinc.howMany = 0;\n\t\t\t\t\t\tinc.offset = 0;\n\t\t\t\t\t} else if ( inc.offset <= old.offset && incEnd >= oldEnd ) {\n\t\t\t\t\t\t// `inc` change includes `old` change.\n\t\t\t\t\t\told.howMany = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tinc.howMany = inc.nodesToHandle;\n\t\tdelete inc.nodesToHandle;\n\t}\n\n\t/**\n\t * Returns an object with a single insert change description.\n\t *\n\t * @param parent The element in which the change happened.\n\t * @param offset The offset at which change happened.\n\t * @param action Further specifies what kind of action led to generating this change.\n\t * @param elementSnapshot Snapshot of the inserted node after changes.\n\t * @param elementSnapshotBefore Snapshot of the inserted node before changes.\n\t * @returns The diff item.\n\t */\n\tprivate _getInsertDiff(\n\t\tparent: Element | DocumentFragment,\n\t\toffset: number,\n\t\taction: DifferItemAction,\n\t\telementSnapshot: DifferSnapshot,\n\t\telementSnapshotBefore?: DifferSnapshot\n\t): DiffItemInsert & DiffItemInternal {\n\t\tconst diffItem: DiffItemInsert & DiffItemInternal = {\n\t\t\ttype: 'insert',\n\t\t\tposition: Position._createAt( parent, offset ),\n\t\t\tname: elementSnapshot.name,\n\t\t\tattributes: new Map( elementSnapshot.attributes ),\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++,\n\t\t\taction\n\t\t};\n\n\t\tif ( action != 'insert' && elementSnapshotBefore ) {\n\t\t\tdiffItem.before = {\n\t\t\t\tname: elementSnapshotBefore.name,\n\t\t\t\tattributes: new Map( elementSnapshotBefore.attributes )\n\t\t\t};\n\t\t}\n\n\t\treturn diffItem;\n\t}\n\n\t/**\n\t * Returns an object with a single remove change description.\n\t *\n\t * @param parent The element in which change happened.\n\t * @param offset The offset at which change happened.\n\t * @param action Further specifies what kind of action led to generating this change.\n\t * @param elementSnapshot The snapshot of the removed node before changes.\n\t * @returns The diff item.\n\t */\n\tprivate _getRemoveDiff(\n\t\tparent: Element | DocumentFragment,\n\t\toffset: number,\n\t\taction: DifferItemAction,\n\t\telementSnapshot: DifferSnapshot\n\t): DiffItemRemove & DiffItemInternal {\n\t\treturn {\n\t\t\ttype: 'remove',\n\t\t\taction,\n\t\t\tposition: Position._createAt( parent, offset ),\n\t\t\tname: elementSnapshot.name,\n\t\t\tattributes: new Map( elementSnapshot.attributes ),\n\t\t\tlength: 1,\n\t\t\tchangeCount: this._changeCount++\n\t\t};\n\t}\n\n\t/**\n\t * Returns an array of objects where each one is a single attribute change description.\n\t *\n\t * @param range The range where the change happened.\n\t * @param oldAttributes A map, map iterator or compatible object that contains attributes before the change.\n\t * @param newAttributes A map, map iterator or compatible object that contains attributes after the change.\n\t * @returns An array containing one or more diff items.\n\t */\n\tprivate _getAttributesDiff(\n\t\trange: Range,\n\t\toldAttributes: Map<string, unknown>,\n\t\tnewAttributes: Map<string, unknown>\n\t): Array<DiffItemAttribute & DiffItemInternal> {\n\t\t// Results holder.\n\t\tconst diffs: Array<DiffItemAttribute & DiffItemInternal> = [];\n\n\t\t// Clone new attributes as we will be performing changes on this object.\n\t\tnewAttributes = new Map( newAttributes );\n\n\t\t// Look through old attributes.\n\t\tfor ( const [ key, oldValue ] of oldAttributes ) {\n\t\t\t// Check what is the new value of the attribute (or if it was removed).\n\t\t\tconst newValue = newAttributes.has( key ) ? newAttributes.get( key ) : null;\n\n\t\t\t// If values are different (or attribute was removed)...\n\t\t\tif ( newValue !== oldValue ) {\n\t\t\t\t// Add diff item.\n\t\t\t\tdiffs.push( {\n\t\t\t\t\ttype: 'attribute',\n\t\t\t\t\tposition: range.start,\n\t\t\t\t\trange: range.clone(),\n\t\t\t\t\tlength: 1,\n\t\t\t\t\tattributeKey: key,\n\t\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\t\tattributeNewValue: newValue,\n\t\t\t\t\tchangeCount: this._changeCount++\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Prevent returning two diff items for the same change.\n\t\t\tnewAttributes.delete( key );\n\t\t}\n\n\t\t// Look through new attributes that weren't handled above.\n\t\tfor ( const [ key, newValue ] of newAttributes ) {\n\t\t\t// Each of them is a new attribute. Add diff item.\n\t\t\tdiffs.push( {\n\t\t\t\ttype: 'attribute',\n\t\t\t\tposition: range.start,\n\t\t\t\trange: range.clone(),\n\t\t\t\tlength: 1,\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: null,\n\t\t\t\tattributeNewValue: newValue,\n\t\t\t\tchangeCount: this._changeCount++\n\t\t\t} );\n\t\t}\n\n\t\treturn diffs;\n\t}\n\n\t/**\n\t * Checks whether given element or any of its parents is an element that is buffered as an inserted element.\n\t */\n\tprivate _isInInsertedElement( element: Element | DocumentFragment ): boolean {\n\t\tconst parent = element.parent;\n\n\t\tif ( !parent ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst changes = this._changesInElement.get( parent );\n\t\tconst offset = element.startOffset;\n\n\t\tif ( changes ) {\n\t\t\tfor ( const change of changes ) {\n\t\t\t\tif ( change.type == 'insert' && offset! >= change.offset && offset! < change.offset + change.howMany ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this._isInInsertedElement( parent );\n\t}\n\n\t/**\n\t * Removes deeply all buffered changes that are registered in elements from range specified by `parent`, `offset`\n\t * and `howMany`.\n\t */\n\tprivate _removeAllNestedChanges( parent: Element | DocumentFragment, offset: number, howMany: number ) {\n\t\tconst range = new Range( Position._createAt( parent, offset ), Position._createAt( parent, offset + howMany ) );\n\n\t\tfor ( const item of range.getItems( { shallow: true } ) ) {\n\t\t\tif ( item.is( 'element' ) ) {\n\t\t\t\tthis._changesInElement.delete( item );\n\t\t\t\tthis._removeAllNestedChanges( item, 0, item.maxOffset );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Further specifies what kind of action led to generating a change:\n *\n * * `'insert'` if element was inserted,\n * * `'remove'` if element was removed,\n * * `'rename'` if element got renamed (e.g. `writer.rename()`),\n * * `'refresh'` if element got refreshed (e.g. `model.editing.reconvertItem()`).\n */\nexport type DifferItemAction = 'insert' | 'remove' | 'rename' | 'refresh';\n\ninterface ChangeItem {\n\ttype: 'insert' | 'remove' | 'attribute';\n\toffset: number;\n\thowMany: number;\n\tcount: number;\n\tnodesToHandle?: number;\n\taction?: DifferItemAction;\n}\n\n/**\n * Returns a snapshot for the specified child node. Text node snapshots have the `name` property set to `$text`.\n */\nfunction _getSingleNodeSnapshot( node: Node | Element ): DifferSnapshot {\n\treturn\t{\n\t\tnode,\n\t\tname: node.is( '$text' ) ? '$text' : ( node as Element ).name,\n\t\tattributes: new Map( node.getAttributes() )\n\t};\n}\n\n/**\n * Returns an array that is a copy of passed child list with the exception that text nodes are split to one or more\n * objects, each representing one character and attributes set on that character.\n */\nfunction _getChildrenSnapshots( children: Iterable<Node> ): Array<DifferSnapshot> {\n\tconst snapshots: Array<DifferSnapshot> = [];\n\n\tfor ( const child of children ) {\n\t\tif ( child.is( '$text' ) ) {\n\t\t\tfor ( let i = 0; i < child.data.length; ++i ) {\n\t\t\t\tsnapshots.push( _getSingleNodeSnapshot( child ) );\n\t\t\t}\n\t\t} else {\n\t\t\tsnapshots.push( _getSingleNodeSnapshot( child ) );\n\t\t}\n\t}\n\n\treturn snapshots;\n}\n\n/**\n * Generates array of diff instructions for given changes set.\n *\n * Generated actions are:\n *\n * - 'e' for 'equal' - when item at that position did not change,\n * - 'i' for 'insert' - when item at that position was inserted,\n * - 'r' for 'remove' - when item at that position was removed,\n * - 'a' for 'attribute' - when item at that position has it attributes changed.\n *\n * Example (assume that uppercase letters have bold attribute, compare with function code):\n *\n * children before:\tfooBAR\n * children after:\tfoxybAR\n *\n * changes: type: remove, offset: 1, howMany: 1\n *\t\t\ttype: insert, offset: 2, howMany: 2\n *\t\t\ttype: attribute, offset: 4, howMany: 1\n *\n * Expected actions: equal (f), remove (o), equal (o), insert (x), insert (y), attribute (b), equal (A), equal (R)\n *\n * Steps taken by the script:\n *\n * 1. change = \"type: remove, offset: 1, howMany: 1\"; offset = 0; oldChildrenHandled = 0\n *    1.1 between this change and the beginning is one not-changed node, fill with one equal action, one old child has been handled\n *    1.2 this change removes one node, add one remove action\n *    1.3 change last visited `offset` to 1\n *    1.4 since an old child has been removed, one more old child has been handled\n *    1.5 actions at this point are: equal, remove\n *\n * 2. change = \"type: insert, offset: 2, howMany: 2\"; offset = 1; oldChildrenHandled = 2\n *    2.1 between this change and previous change is one not-changed node, add equal action, another one old children has been handled\n *    2.2 this change inserts two nodes, add two insert actions\n *    2.3 change last visited offset to the end of the inserted range, that is 4\n *    2.4 actions at this point are: equal, remove, equal, insert, insert\n *\n * 3. change = \"type: attribute, offset: 4, howMany: 1\"; offset = 4, oldChildrenHandled = 3\n *    3.1 between this change and previous change are no not-changed nodes\n *    3.2 this change changes one node, add one attribute action\n *    3.3 change last visited `offset` to the end of change range, that is 5\n *    3.4 since an old child has been changed, one more old child has been handled\n *    3.5 actions at this point are: equal, remove, equal, insert, insert, attribute\n *\n * 4. after loop oldChildrenHandled = 4, oldChildrenLength = 6 (fooBAR is 6 characters)\n *    4.1 fill up with two equal actions\n *\n * The result actions are: equal, remove, equal, insert, insert, attribute, equal, equal.\n */\nfunction _generateDiffInstructionsFromChanges( oldChildrenLength: number, changes: Array<ChangeItem> ) {\n\tconst diff: Array<string> = [];\n\n\tlet offset = 0;\n\tlet oldChildrenHandled = 0;\n\n\t// Go through all buffered changes.\n\tfor ( const change of changes ) {\n\t\t// First, fill \"holes\" between changes with \"equal\" actions.\n\t\tif ( change.offset > offset ) {\n\t\t\tfor ( let i = 0; i < change.offset - offset; i++ ) {\n\t\t\t\tdiff.push( 'e' );\n\t\t\t}\n\n\t\t\toldChildrenHandled += change.offset - offset;\n\t\t}\n\n\t\t// Then, fill up actions accordingly to change type.\n\t\tif ( change.type == 'insert' ) {\n\t\t\tfor ( let i = 0; i < change.howMany; i++ ) {\n\t\t\t\tdiff.push( 'i' );\n\t\t\t}\n\n\t\t\t// The last handled offset is after inserted range.\n\t\t\toffset = change.offset + change.howMany;\n\t\t} else if ( change.type == 'remove' ) {\n\t\t\tfor ( let i = 0; i < change.howMany; i++ ) {\n\t\t\t\tdiff.push( 'r' );\n\t\t\t}\n\n\t\t\t// The last handled offset is at the position where the nodes were removed.\n\t\t\toffset = change.offset;\n\t\t\t// We removed `howMany` old nodes, update `oldChildrenHandled`.\n\t\t\toldChildrenHandled += change.howMany;\n\t\t} else {\n\t\t\t// Total maximum amount of arguments that can be passed to `Array.prototype.push` may be limited so we need to\n\t\t\t// add them manually one by one to avoid this limit. However loop might be a bit slower than `push` method on\n\t\t\t// smaller changesets so we need to decide which method to use based on the size of the change.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/16819\n\t\t\tif ( change.howMany > 1500 ) {\n\t\t\t\tfor ( let i = 0; i < change.howMany; i++ ) {\n\t\t\t\t\tdiff.push( 'a' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdiff.push( ...'a'.repeat( change.howMany ).split( '' ) );\n\t\t\t}\n\n\t\t\t// The last handled offset is at the position after the changed range.\n\t\t\toffset = change.offset + change.howMany;\n\t\t\t// We changed `howMany` old nodes, update `oldChildrenHandled`.\n\t\t\toldChildrenHandled += change.howMany;\n\t\t}\n\t}\n\n\t// Fill \"equal\" actions at the end of actions set. Use `oldChildrenHandled` to see how many children\n\t// has not been changed / removed at the end of their parent.\n\tif ( oldChildrenHandled < oldChildrenLength ) {\n\t\tfor ( let i = 0; i < oldChildrenLength - oldChildrenHandled - offset; i++ ) {\n\t\t\tdiff.push( 'e' );\n\t\t}\n\t}\n\n\treturn diff;\n}\n\n/**\n * Filter callback for `Array.filter` that filters out change entries that are in graveyard.\n */\nfunction _changesInGraveyardFilter( entry: DiffItem ) {\n\tconst posInGy = 'position' in entry && entry.position!.root.rootName == '$graveyard';\n\tconst rangeInGy = 'range' in entry && entry.range.root.rootName == '$graveyard';\n\n\treturn !posInGy && !rangeInGy;\n}\n\n/**\n * A snapshot is representing state of a given element before the first change was applied on that element.\n */\nexport interface DifferSnapshot {\n\n\t/**\n\t * Node for which was snapshot was made.\n\t */\n\tnode: Node;\n\n\t/**\n\t * Name of the element at the time when the snapshot was made. For text node snapshots, it is set to `'$text'`.\n\t */\n\tname: string;\n\n\t/**\n\t * Attributes of the node at the time when the snapshot was made.\n\t */\n\tattributes: Map<string, unknown>;\n}\n\n/**\n * The single diff item.\n *\n * Could be one of:\n *\n * * {@link module:engine/model/differ~DiffItemInsert `DiffItemInsert`},\n * * {@link module:engine/model/differ~DiffItemRemove `DiffItemRemove`},\n * * {@link module:engine/model/differ~DiffItemAttribute `DiffItemAttribute`}.\n */\nexport type DiffItem = DiffItemInsert | DiffItemRemove | DiffItemAttribute;\n\n/**\n * A single diff item for inserted nodes.\n */\nexport interface DiffItemInsert {\n\n\t/**\n\t * The type of diff item.\n\t */\n\ttype: 'insert';\n\n\t/**\n\t * Further specifies what kind of action led to generating this change.\n\t *\n\t * The action is set in relation to the document state before any change. It means that, for example, if an element was added and\n\t * then renamed (during the same {@link module:engine/model/batch~Batch batch}), the action will be set to `'insert'`, because when\n\t * compared to the document state before changes, a new element was inserted, and the renaming does not matter from this point of view.\n\t */\n\taction: DifferItemAction;\n\n\t/**\n\t * The name of the inserted elements or `'$text'` for a text node.\n\t */\n\tname: string;\n\n\t/**\n\t * Map of attributes of the inserted element.\n\t */\n\tattributes: Map<string, unknown>;\n\n\t/**\n\t * The position where the node was inserted.\n\t */\n\tposition: Position;\n\n\t/**\n\t * The length of an inserted text node. For elements, it is always 1 as each inserted element is counted as a one.\n\t */\n\tlength: number;\n\n\t/**\n\t * Holds information about the element state before all changes happened.\n\t *\n\t * For example, when `<paragraph textAlign=\"right\">` was changed to `<codeBlock language=\"plaintext\">`,\n\t * `before.name` will be equal to `'paragraph'` and `before.attributes` map will have one entry: `'textAlign' -> 'right'`.\n\t *\n\t * The property is available only if the insertion change was due to element rename or refresh (when `action` property is `'rename'`\n\t * or `'refresh'`). As such, `before` property is never available for text node changes.\n\t */\n\tbefore?: {\n\n\t\t/**\n\t\t * The name of the inserted element before all changes.\n\t\t */\n\t\tname: string;\n\n\t\t/**\n\t\t * Map of the attributes of the inserted element before all changes.\n\t\t */\n\t\tattributes: Map<string, unknown>;\n\t};\n}\n\n/**\n * A single diff item for removed nodes.\n */\nexport interface DiffItemRemove {\n\n\t/**\n\t * The type of diff item.\n\t */\n\ttype: 'remove';\n\n\t/**\n\t * Further specifies what kind of action led to generating this change.\n\t *\n\t * The action is set in relation to the document state before any change. It means that, for example, if an element was renamed and\n\t * then removed (during the same {@link module:engine/model/batch~Batch batch}), the action will be set to `'remove'`, because when\n\t * compared to the document state before changes, the element was removed, and it does not matter that it was also renamed at one point.\n\t */\n\taction: DifferItemAction;\n\n\t/**\n\t * The name of the removed element or `'$text'` for a text node.\n\t */\n\tname: string;\n\n\t/**\n\t * Map of attributes that were set on the item while it was removed.\n\t */\n\tattributes: Map<string, unknown>;\n\n\t/**\n\t * The position where the node was removed.\n\t */\n\tposition: Position;\n\n\t/**\n\t * The length of a removed text node. For elements, it is always 1, as each removed element is counted as a one.\n\t */\n\tlength: number;\n}\n\n/**\n * A single diff item for attribute change.\n */\nexport interface DiffItemAttribute {\n\n\t/**\n\t * The type of diff item.\n\t */\n\ttype: 'attribute';\n\n\t/**\n\t * The name of the changed attribute.\n\t */\n\tattributeKey: string;\n\n\t/**\n\t * An attribute previous value (before change).\n\t */\n\tattributeOldValue: unknown;\n\n\t/**\n\t * An attribute new value (after change).\n\t */\n\tattributeNewValue: unknown;\n\n\t/**\n\t * The range where the change happened.\n\t */\n\trange: Range;\n}\n\n/**\n * A single diff item for a changed root.\n */\nexport interface DiffItemRoot {\n\n\t/**\n\t * Name of the changed root.\n\t */\n\tname: string;\n\n\t/**\n\t * Set accordingly if the root got attached or detached. Otherwise, not set.\n\t */\n\tstate?: 'attached' | 'detached';\n\n\t/**\n\t * Keeps all attribute changes that happened on the root.\n\t *\n\t * The keys are keys of the changed attributes. The values are objects containing the attribute value before the change\n\t * (`oldValue`) and after the change (`newValue`).\n\t *\n\t * Note, that if the root state changed (`state` is set), then `attributes` property will not be set. All attributes should be\n\t * handled together with the root being attached or detached.\n\t */\n\tattributes?: Record<string, { oldValue: unknown; newValue: unknown }>;\n}\n\ninterface DiffItemInternal {\n\tchangeCount?: number;\n\tposition?: Position;\n\tlength?: number;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type Operation from './operation/operation.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\n/**\n * @module engine/model/history\n */\n\n/**\n * `History` keeps the track of all the operations applied to the {@link module:engine/model/document~Document document}.\n */\nexport default class History {\n\t/**\n\t * Operations added to the history.\n\t */\n\tprivate _operations: Array<Operation> = [];\n\n\t/**\n\t * Holds an information which {@link module:engine/model/operation/operation~Operation operation} undoes which\n\t * {@link module:engine/model/operation/operation~Operation operation}.\n\t *\n\t * Keys of the map are \"undoing operations\", that is operations that undone some other operations. For each key, the\n\t * value is an operation that has been undone by the \"undoing operation\".\n\t */\n\tprivate _undoPairs: Map<Operation, Operation> = new Map();\n\n\t/**\n\t * Holds all undone operations.\n\t */\n\tprivate _undoneOperations: Set<Operation> = new Set();\n\n\t/**\n\t * A map that allows retrieving the operations fast based on the given base version.\n\t */\n\tprivate _baseVersionToOperationIndex: Map<number, number> = new Map();\n\n\t/**\n\t * The history version.\n\t */\n\tprivate _version: number = 0;\n\n\t/**\n\t * The gap pairs kept in the <from,to> format.\n\t *\n\t * Anytime the `history.version` is set to a version larger than `history.version + 1`,\n\t * a new <lastHistoryVersion, newHistoryVersion> entry is added to the map.\n\t */\n\tprivate _gaps: Map<number, number> = new Map();\n\n\t/**\n\t * The version of the last operation in the history.\n\t *\n\t * The history version is incremented automatically when a new operation is added to the history.\n\t * Setting the version manually should be done only in rare circumstances when a gap is planned\n\t * between history versions. When doing so, a gap will be created and the history will accept adding\n\t * an operation with base version equal to the new history version.\n\t */\n\tpublic get version(): number {\n\t\treturn this._version;\n\t}\n\n\tpublic set version( version: number ) {\n\t\t// Store a gap if there are some operations already in the history and the\n\t\t// new version does not increment the latest one.\n\t\tif ( this._operations.length && version > this._version + 1 ) {\n\t\t\tthis._gaps.set( this._version, version );\n\t\t}\n\n\t\tthis._version = version;\n\t}\n\n\t/**\n\t * The last history operation.\n\t */\n\tpublic get lastOperation(): Operation | undefined {\n\t\treturn this._operations[ this._operations.length - 1 ];\n\t}\n\n\t/**\n\t * Adds an operation to the history and increments the history version.\n\t *\n\t * The operation's base version should be equal to the history version. Otherwise an error is thrown.\n\t */\n\tpublic addOperation( operation: Operation ): void {\n\t\tif ( operation.baseVersion !== this.version ) {\n\t\t\t/**\n\t\t\t * Only operations with matching versions can be added to the history.\n\t\t\t *\n\t\t\t * @error model-document-history-addoperation-incorrect-version\n\t\t\t * @param errorData The operation and the current document history version.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-document-history-addoperation-incorrect-version', this, {\n\t\t\t\toperation,\n\t\t\t\thistoryVersion: this.version\n\t\t\t} );\n\t\t}\n\n\t\tthis._operations.push( operation );\n\t\tthis._version++;\n\n\t\tthis._baseVersionToOperationIndex.set( operation.baseVersion, this._operations.length - 1 );\n\t}\n\n\t/**\n\t * Returns operations from the given range of operation base versions that were added to the history.\n\t *\n\t * Note that there may be gaps in operations base versions.\n\t *\n\t * @param fromBaseVersion Base version from which operations should be returned (inclusive).\n\t * @param toBaseVersion Base version up to which operations should be returned (exclusive).\n     * @returns History operations for the given range, in chronological order.\n\t */\n\tpublic getOperations( fromBaseVersion?: number, toBaseVersion: number = this.version ): Array<Operation> {\n\t\t// When there is no operation in the history, return an empty array.\n\t\t// After that we can be sure that `firstOperation`, `lastOperation` are not nullish.\n\t\tif ( !this._operations.length ) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst firstOperation = this._operations[ 0 ];\n\n\t\tif ( fromBaseVersion === undefined ) {\n\t\t\tfromBaseVersion = firstOperation.baseVersion!;\n\t\t}\n\n\t\t// Change exclusive `toBaseVersion` to inclusive, so it will refer to the actual index.\n\t\t// Thanks to that mapping from base versions to operation indexes are possible.\n\t\tlet inclusiveTo = toBaseVersion - 1;\n\n\t\t// Check if \"from\" or \"to\" point to a gap between versions.\n\t\t// If yes, then change the incorrect position to the proper side of the gap.\n\t\t// Thanks to it, it will be possible to get index of the operation.\n\t\tfor ( const [ gapFrom, gapTo ] of this._gaps ) {\n\t\t\tif ( fromBaseVersion > gapFrom && fromBaseVersion < gapTo ) {\n\t\t\t\tfromBaseVersion = gapTo;\n\t\t\t}\n\n\t\t\tif ( inclusiveTo > gapFrom && inclusiveTo < gapTo ) {\n\t\t\t\tinclusiveTo = gapFrom - 1;\n\t\t\t}\n\t\t}\n\n\t\t// If the whole range is outside of the operation versions, then return an empty array.\n\t\tif ( inclusiveTo < firstOperation.baseVersion! || fromBaseVersion > this.lastOperation!.baseVersion! ) {\n\t\t\treturn [];\n\t\t}\n\n\t\tlet fromIndex = this._baseVersionToOperationIndex.get( fromBaseVersion );\n\n\t\t// If the range starts before the first operation, then use the first operation as the range's start.\n\t\tif ( fromIndex === undefined ) {\n\t\t\tfromIndex = 0;\n\t\t}\n\n\t\tlet toIndex = this._baseVersionToOperationIndex.get( inclusiveTo );\n\n\t\t// If the range ends after the last operation, then use the last operation as the range's end.\n\t\tif ( toIndex === undefined ) {\n\t\t\ttoIndex = this._operations.length - 1;\n\t\t}\n\n\t\t// Return the part of the history operations based on the calculated start index and end index.\n\t\treturn this._operations.slice(\n\t\t\tfromIndex,\n\n\t\t\t// The `toIndex` should be included in the returned operations, so add `1`.\n\t\t\ttoIndex + 1\n\t\t);\n\t}\n\n\t/**\n\t * Returns operation from the history that bases on given `baseVersion`.\n\t *\n\t * @param baseVersion Base version of the operation to get.\n\t * @returns Operation with given base version or `undefined` if there is no such operation in history.\n\t */\n\tpublic getOperation( baseVersion: number ): Operation | undefined {\n\t\tconst operationIndex = this._baseVersionToOperationIndex.get( baseVersion );\n\n\t\tif ( operationIndex === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._operations[ operationIndex ];\n\t}\n\n\t/**\n\t * Marks in history that one operation is an operation that is undoing the other operation. By marking operation this way,\n\t * history is keeping more context information about operations, which helps in operational transformation.\n\t *\n\t * @param undoneOperation Operation which is undone by `undoingOperation`.\n\t * @param undoingOperation Operation which undoes `undoneOperation`.\n\t */\n\tpublic setOperationAsUndone( undoneOperation: Operation, undoingOperation: Operation ): void {\n\t\tthis._undoPairs.set( undoingOperation, undoneOperation );\n\t\tthis._undoneOperations.add( undoneOperation );\n\t}\n\n\t/**\n\t * Checks whether given `operation` is undoing any other operation.\n\t *\n\t * @param operation Operation to check.\n\t * @returns `true` if given `operation` is undoing any other operation, `false` otherwise.\n\t */\n\tpublic isUndoingOperation( operation: Operation ): boolean {\n\t\treturn this._undoPairs.has( operation );\n\t}\n\n\t/**\n\t * Checks whether given `operation` has been undone by any other operation.\n\t *\n\t * @param operation Operation to check.\n\t * @returns `true` if given `operation` has been undone any other operation, `false` otherwise.\n\t */\n\tpublic isUndoneOperation( operation: Operation ): boolean {\n\t\treturn this._undoneOperations.has( operation );\n\t}\n\n\t/**\n\t * For given `undoingOperation`, returns the operation which has been undone by it.\n\t *\n\t * @returns Operation that has been undone by given `undoingOperation` or `undefined`\n\t * if given `undoingOperation` is not undoing any other operation.\n\t */\n\tpublic getUndoneOperation( undoingOperation: Operation ): Operation | undefined {\n\t\treturn this._undoPairs.get( undoingOperation );\n\t}\n\n\t/**\n\t * Resets the history of operations.\n\t */\n\tpublic reset(): void {\n\t\tthis._version = 0;\n\t\tthis._undoPairs = new Map();\n\t\tthis._operations = [];\n\t\tthis._undoneOperations = new Set();\n\t\tthis._gaps = new Map();\n\t\tthis._baseVersionToOperationIndex = new Map();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/rootelement\n */\n\nimport Element from './element.js';\n\nimport type Document from './document.js';\n\n/**\n * Type of {@link module:engine/model/element~Element} that is a root of a model tree.\n */\nexport default class RootElement extends Element {\n\t/**\n\t * Unique root name used to identify this root element by {@link module:engine/model/document~Document}.\n\t */\n\tpublic override readonly rootName: string;\n\n\t/**\n\t * Document that is an owner of this root.\n\t */\n\tprivate readonly _document: Document;\n\n\t/**\n\t * @internal\n\t */\n\tpublic _isAttached = true;\n\n\t/**\n\t * Informs if the root element is loaded (default).\n\t *\n\t * @internal\n\t */\n\tpublic _isLoaded = true;\n\n\t/**\n\t * Creates root element.\n\t *\n\t * @param document Document that is an owner of this root.\n\t * @param name Node name.\n\t * @param rootName Unique root name used to identify this root element by {@link module:engine/model/document~Document}.\n\t */\n\tconstructor( document: Document, name: string, rootName: string = 'main' ) {\n\t\tsuper( name );\n\n\t\tthis._document = document;\n\t\tthis.rootName = rootName;\n\t}\n\n\t/**\n\t * {@link module:engine/model/document~Document Document} that owns this root element.\n\t */\n\tpublic override get document(): Document {\n\t\treturn this._document;\n\t}\n\n\t/**\n\t * Informs if the root element is currently attached to the document, or not.\n\t *\n\t * A detached root is equivalent to being removed and cannot contain any children or markers.\n\t *\n\t * By default, a newly added root is attached. It can be detached using\n\t * {@link module:engine/model/writer~Writer#detachRoot `Writer#detachRoot`}. A detached root can be re-attached again using\n\t * {@link module:engine/model/writer~Writer#addRoot `Writer#addRoot`}.\n\t */\n\tpublic override isAttached(): boolean {\n\t\treturn this._isAttached;\n\t}\n\n\t/**\n\t * Converts `RootElement` instance to `string` containing its name.\n\t *\n\t * @returns `RootElement` instance converted to `string`.\n\t */\n\tpublic override toJSON(): unknown {\n\t\treturn this.rootName;\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \treturn this.rootName;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public override log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ModelRootElement: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nRootElement.prototype.is = function( type: string, name?: string ): boolean {\n\tif ( !name ) {\n\t\treturn type === 'rootElement' || type === 'model:rootElement' ||\n\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\ttype === 'element' || type === 'model:element' ||\n\t\t\ttype === 'node' || type === 'model:node';\n\t}\n\n\treturn name === this.name && (\n\t\ttype === 'rootElement' || type === 'model:rootElement' ||\n\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\ttype === 'element' || type === 'model:element'\n\t);\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/document\n */\n\nimport Differ from './differ.js';\nimport DocumentSelection from './documentselection.js';\nimport History from './history.js';\nimport RootElement from './rootelement.js';\n\nimport type { SelectionChangeEvent } from './selection.js';\nimport type { default as Model, ModelApplyOperationEvent } from './model.js';\nimport type { MarkerCollectionUpdateEvent, MarkerChangeEvent } from './markercollection.js';\nimport type Batch from './batch.js';\nimport type Position from './position.js';\nimport type Range from './range.js';\nimport type Writer from './writer.js';\n\nimport {\n\tCKEditorError,\n\tCollection,\n\tEmitterMixin,\n\tisInsideSurrogatePair,\n\tisInsideCombinedSymbol\n} from '@ckeditor/ckeditor5-utils';\n\nimport { clone } from 'lodash-es';\n\n// @if CK_DEBUG_ENGINE // const { logDocument } = require( '../dev-utils/utils' );\n\nconst graveyardName = '$graveyard';\n\n/**\n * Data model's document. It contains the model's structure, its selection and the history of changes.\n *\n * Read more about working with the model in\n * {@glink framework/architecture/editing-engine#model introduction to the the editing engine's architecture}.\n *\n * Usually, the document contains just one {@link module:engine/model/document~Document#roots root element}, so\n * you can retrieve it by just calling {@link module:engine/model/document~Document#getRoot} without specifying its name:\n *\n * ```ts\n * model.document.getRoot(); // -> returns the main root\n * ```\n *\n * However, the document may contain multiple roots – e.g. when the editor has multiple editable areas\n * (e.g. a title and a body of a message).\n */\nexport default class Document extends /* #__PURE__ */ EmitterMixin() {\n\t/**\n\t * The {@link module:engine/model/model~Model model} that the document is a part of.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * The document's history.\n\t */\n\tpublic readonly history: History;\n\n\t/**\n\t * The selection in this document.\n\t */\n\tpublic readonly selection: DocumentSelection;\n\n\t/**\n\t * A list of roots that are owned and managed by this document. Use {@link #createRoot}, {@link #getRoot} and\n\t * {@link #getRootNames} to manipulate it.\n\t */\n\tpublic readonly roots: Collection<RootElement>;\n\n\t/**\n\t * The model differ object. Its role is to buffer changes done on the model document and then calculate a diff of those changes.\n\t */\n\tpublic readonly differ: Differ;\n\n\t/**\n\t * Defines whether the document is in a read-only mode.\n\t *\n\t * The user should not be able to change the data of a document that is read-only.\n\t *\n\t * @readonly\n\t */\n\tpublic isReadOnly: boolean;\n\n\t/**\n\t * Post-fixer callbacks registered to the model document.\n\t */\n\tprivate readonly _postFixers: Set<ModelPostFixer>;\n\n\t/**\n\t * A flag that indicates whether the selection has changed since last change block.\n\t */\n\tprivate _hasSelectionChangedFromTheLastChangeBlock: boolean;\n\n\t/**\n\t * Creates an empty document instance with no {@link #roots} (other than\n\t * the {@link #graveyard graveyard root}).\n\t */\n\tconstructor( model: Model ) {\n\t\tsuper();\n\n\t\tthis.model = model;\n\t\tthis.history = new History();\n\t\tthis.selection = new DocumentSelection( this );\n\t\tthis.roots = new Collection( { idProperty: 'rootName' } );\n\t\tthis.differ = new Differ( model.markers );\n\t\tthis.isReadOnly = false;\n\n\t\tthis._postFixers = new Set();\n\t\tthis._hasSelectionChangedFromTheLastChangeBlock = false;\n\n\t\t// Graveyard tree root. Document always have a graveyard root, which stores removed nodes.\n\t\tthis.createRoot( '$root', graveyardName );\n\n\t\t// Then, still before an operation is applied on model, buffer the change in differ.\n\t\tthis.listenTo<ModelApplyOperationEvent>( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( operation.isDocumentOperation ) {\n\t\t\t\tthis.differ.bufferOperation( operation );\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// After the operation is applied, bump document's version and add the operation to the history.\n\t\tthis.listenTo<ModelApplyOperationEvent>( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( operation.isDocumentOperation ) {\n\t\t\t\tthis.history.addOperation( operation );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// Listen to selection changes. If selection changed, mark it.\n\t\tthis.listenTo<SelectionChangeEvent>( this.selection, 'change', () => {\n\t\t\tthis._hasSelectionChangedFromTheLastChangeBlock = true;\n\t\t} );\n\n\t\t// Buffer marker changes.\n\t\t// This is not covered in buffering operations because markers may change outside of them (when they\n\t\t// are modified using `model.markers` collection, not through `MarkerOperation`).\n\t\tthis.listenTo<MarkerCollectionUpdateEvent>( model.markers, 'update', ( evt, marker, oldRange, newRange, oldMarkerData ) => {\n\t\t\t// Copy the `newRange` to the new marker data as during the marker removal the range is not updated.\n\t\t\tconst newMarkerData = { ...marker.getData(), range: newRange };\n\n\t\t\t// Whenever marker is updated, buffer that change.\n\t\t\tthis.differ.bufferMarkerChange( marker.name, oldMarkerData, newMarkerData );\n\n\t\t\tif ( oldRange === null ) {\n\t\t\t\t// If this is a new marker, add a listener that will buffer change whenever marker changes.\n\t\t\t\tmarker.on<MarkerChangeEvent>( 'change', ( evt, oldRange ) => {\n\t\t\t\t\tconst markerData = marker.getData();\n\n\t\t\t\t\tthis.differ.bufferMarkerChange(\n\t\t\t\t\t\tmarker.name,\n\t\t\t\t\t\t{ ...markerData, range: oldRange },\n\t\t\t\t\t\tmarkerData\n\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\t// This is a solution for a problem that may occur during real-time editing. If one client detached a root and another added\n\t\t// something there at the same moment, the OT does not solve this problem currently. In such situation, the added elements would\n\t\t// stay in the detached root.\n\t\t//\n\t\t// This is incorrect, a detached root should be empty and all elements from it should be removed. To solve this, the post-fixer will\n\t\t// remove any element that is left in a detached root.\n\t\t//\n\t\t// Similarly, markers that are created at the beginning or at the end of the detached root will not be removed as well.\n\t\t//\n\t\t// The drawback of this solution over the OT solution is that the elements removed by the post-fixer will never be brought back.\n\t\t// If the root detachment gets undone (and the root is brought back), the removed elements will not be there.\n\t\tthis.registerPostFixer( writer => {\n\t\t\tlet result = false;\n\n\t\t\tfor ( const root of this.roots ) {\n\t\t\t\tif ( !root.isAttached() && !root.isEmpty ) {\n\t\t\t\t\twriter.remove( writer.createRangeIn( root ) );\n\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( const marker of this.model.markers ) {\n\t\t\t\tif ( !marker.getRange().root.isAttached() ) {\n\t\t\t\t\twriter.removeMarker( marker );\n\n\t\t\t\t\tresult = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} );\n\t}\n\n\t/**\n\t * The document version. Every applied operation increases the version number. It is used to\n\t * ensure that operations are applied on a proper document version.\n\t *\n\t * This property is equal to {@link module:engine/model/history~History#version `model.Document#history#version`}.\n\t *\n\t * If the {@link module:engine/model/operation/operation~Operation#baseVersion base version} does not match the document version,\n\t * a {@link module:utils/ckeditorerror~CKEditorError model-document-applyoperation-wrong-version} error is thrown.\n\t */\n\tpublic get version(): number {\n\t\treturn this.history.version;\n\t}\n\n\tpublic set version( version: number ) {\n\t\tthis.history.version = version;\n\t}\n\n\t/**\n\t * The graveyard tree root. A document always has a graveyard root that stores removed nodes.\n\t */\n\tpublic get graveyard(): RootElement {\n\t\treturn this.getRoot( graveyardName )!;\n\t}\n\n\t/**\n\t * Creates a new root.\n\t *\n\t * **Note:** do not use this method after the editor has been initialized! If you want to dynamically add a root, use\n\t * {@link module:engine/model/writer~Writer#addRoot `model.Writer#addRoot`} instead.\n\t *\n\t * @param elementName The element name. Defaults to `'$root'` which also has some basic schema defined\n\t * (e.g. `$block` elements are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.\n\t * @param rootName A unique root name.\n\t * @returns The created root.\n\t */\n\tpublic createRoot( elementName: string = '$root', rootName: string = 'main' ): RootElement {\n\t\tif ( this.roots.get( rootName ) ) {\n\t\t\t/**\n\t\t\t * A root with the specified name already exists.\n\t\t\t *\n\t\t\t * @error model-document-createroot-name-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'model-document-createroot-name-exists', this, { name: rootName } );\n\t\t}\n\n\t\tconst root = new RootElement( this, elementName, rootName );\n\t\tthis.roots.add( root );\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * Removes all event listeners set by the document instance.\n\t */\n\tpublic destroy(): void {\n\t\tthis.selection.destroy();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Returns a root by its name.\n\t *\n\t * Detached roots are returned by this method. This is to be able to operate on the detached root (for example, to be able to create\n\t * a position inside such a root for undo feature purposes).\n\t *\n\t * @param name The root name of the root to return.\n\t * @returns The root registered under a given name or `null` when there is no root with the given name.\n\t */\n\tpublic getRoot( name: string = 'main' ): RootElement | null {\n\t\treturn this.roots.get( name );\n\t}\n\n\t/**\n\t * Returns an array with names of all roots added to the document (except the {@link #graveyard graveyard root}).\n\t *\n\t * Detached roots **are not** returned by this method by default. This is to make sure that all features or algorithms that operate\n\t * on the document data know which roots are still a part of the document and should be processed.\n\t *\n\t * @param includeDetached Specified whether detached roots should be returned as well.\n\t */\n\tpublic getRootNames( includeDetached = false ): Array<string> {\n\t\treturn this.getRoots( includeDetached ).map( root => root.rootName );\n\t}\n\n\t/**\n\t * Returns an array with all roots added to the document (except the {@link #graveyard graveyard root}).\n\t *\n\t * Detached roots **are not** returned by this method by default. This is to make sure that all features or algorithms that operate\n\t * on the document data know which roots are still a part of the document and should be processed.\n\t *\n\t * @param includeDetached Specified whether detached roots should be returned as well.\n\t */\n\tpublic getRoots( includeDetached = false ): Array<RootElement> {\n\t\treturn this.roots.filter( root => root != this.graveyard && ( includeDetached || root.isAttached() ) && root._isLoaded );\n\t}\n\n\t/**\n\t * Used to register a post-fixer callback. A post-fixer mechanism guarantees that the features\n\t * will operate on a correct model state.\n\t *\n\t * An execution of a feature may lead to an incorrect document tree state. The callbacks are used to fix the document tree after\n\t * it has changed. Post-fixers are fired just after all changes from the outermost change block were applied but\n\t * before the {@link module:engine/model/document~Document#event:change change event} is fired. If a post-fixer callback made\n\t * a change, it should return `true`. When this happens, all post-fixers are fired again to check if something else should\n\t * not be fixed in the new document tree state.\n\t *\n\t * As a parameter, a post-fixer callback receives a {@link module:engine/model/writer~Writer writer} instance connected with the\n\t * executed changes block. Thanks to that, all changes done by the callback will be added to the same\n\t * {@link module:engine/model/batch~Batch batch} (and undo step) as the original changes. This makes post-fixer changes transparent\n\t * for the user.\n\t *\n\t * An example of a post-fixer is a callback that checks if all the data were removed from the editor. If so, the\n\t * callback should add an empty paragraph so that the editor is never empty:\n\t *\n\t * ```ts\n\t * document.registerPostFixer( writer => {\n\t * \tconst changes = document.differ.getChanges();\n\t *\n\t * \t// Check if the changes lead to an empty root in the editor.\n\t * \tfor ( const entry of changes ) {\n\t * \t\tif ( entry.type == 'remove' && entry.position.root.isEmpty ) {\n\t * \t\t\twriter.insertElement( 'paragraph', entry.position.root, 0 );\n\t *\n\t * \t\t\t// It is fine to return early, even if multiple roots would need to be fixed.\n\t * \t\t\t// All post-fixers will be fired again, so if there are more empty roots, those will be fixed, too.\n\t * \t\t\treturn true;\n\t * \t\t}\n\t * \t}\n\t *\n\t * \treturn false;\n\t * } );\n\t * ```\n\t */\n\tpublic registerPostFixer( postFixer: ModelPostFixer ): void {\n\t\tthis._postFixers.add( postFixer );\n\t}\n\n\t/**\n\t * A custom `toJSON()` method to solve child-parent circular dependencies.\n\t *\n\t * @returns A clone of this object with the document property changed to a string.\n\t */\n\tpublic toJSON(): unknown {\n\t\tconst json: any = clone( this );\n\n\t\t// Due to circular references we need to remove parent reference.\n\t\tjson.selection = '[engine.model.DocumentSelection]';\n\t\tjson.model = '[engine.model.Model]';\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Check if there were any changes done on document, and if so, call post-fixers,\n\t * fire `change` event for features and conversion and then reset the differ.\n\t * Fire `change:data` event when at least one operation or buffered marker changes the data.\n\t *\n\t * @internal\n\t * @fires change\n\t * @fires change:data\n\t * @param writer The writer on which post-fixers will be called.\n\t */\n\tpublic _handleChangeBlock( writer: Writer ): void {\n\t\tif ( this._hasDocumentChangedFromTheLastChangeBlock() ) {\n\t\t\tthis._callPostFixers( writer );\n\n\t\t\t// Refresh selection attributes according to the final position in the model after the change.\n\t\t\tthis.selection.refresh();\n\n\t\t\tif ( this.differ.hasDataChanges() ) {\n\t\t\t\tthis.fire<DocumentChangeEvent>( 'change:data', writer.batch );\n\t\t\t} else {\n\t\t\t\tthis.fire<DocumentChangeEvent>( 'change', writer.batch );\n\t\t\t}\n\n\t\t\t// Theoretically, it is not necessary to refresh selection after change event because\n\t\t\t// post-fixers are the last who should change the model, but just in case...\n\t\t\tthis.selection.refresh();\n\n\t\t\tthis.differ.reset();\n\t\t}\n\n\t\tthis._hasSelectionChangedFromTheLastChangeBlock = false;\n\t}\n\n\t/**\n\t * Returns whether there is a buffered change or if the selection has changed from the last\n\t * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block}\n\t * or {@link module:engine/model/model~Model#change `change()` block}.\n\t *\n\t * @returns Returns `true` if document has changed from the last `change()` or `enqueueChange()` block.\n\t */\n\tprotected _hasDocumentChangedFromTheLastChangeBlock(): boolean {\n\t\treturn !this.differ.isEmpty || this._hasSelectionChangedFromTheLastChangeBlock;\n\t}\n\n\t/**\n\t * Returns the default root for this document which is either the first root that was added to the document using\n\t * {@link #createRoot} or the {@link #graveyard graveyard root} if no other roots were created.\n\t *\n\t * @returns The default root for this document.\n\t */\n\tprotected _getDefaultRoot(): RootElement {\n\t\tconst roots = this.getRoots();\n\n\t\treturn roots.length ? roots[ 0 ] : this.graveyard;\n\t}\n\n\t/**\n\t * Returns the default range for this selection. The default range is a collapsed range that starts and ends\n\t * at the beginning of this selection's document {@link #_getDefaultRoot default root}.\n\t *\n\t * @internal\n\t */\n\tpublic _getDefaultRange(): Range {\n\t\tconst defaultRoot = this._getDefaultRoot();\n\t\tconst model = this.model;\n\t\tconst schema = model.schema;\n\n\t\t// Find the first position where the selection can be put.\n\t\tconst position = model.createPositionFromPath( defaultRoot, [ 0 ] );\n\t\tconst nearestRange = schema.getNearestSelectionRange( position );\n\n\t\t// If valid selection range is not found - return range collapsed at the beginning of the root.\n\t\treturn nearestRange || model.createRange( position );\n\t}\n\n\t/**\n\t * Checks whether a given {@link module:engine/model/range~Range range} is a valid range for\n\t * the {@link #selection document's selection}.\n\t *\n\t * @internal\n\t * @param range A range to check.\n\t * @returns `true` if `range` is valid, `false` otherwise.\n\t */\n\tpublic _validateSelectionRange( range: Range ): boolean {\n\t\treturn range.start.isValid() && range.end.isValid() &&\n\t\t\tvalidateTextNodePosition( range.start ) && validateTextNodePosition( range.end );\n\t}\n\n\t/**\n\t * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.\n\t *\n\t * @param writer The writer on which post-fixer callbacks will be called.\n\t */\n\tprivate _callPostFixers( writer: Writer ) {\n\t\tlet wasFixed = false;\n\n\t\tdo {\n\t\t\tfor ( const callback of this._postFixers ) {\n\t\t\t\t// Ensure selection attributes are up to date before each post-fixer.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-engine/issues/1673.\n\t\t\t\t//\n\t\t\t\t// It might be good to refresh the selection after each operation but at the moment it leads\n\t\t\t\t// to losing attributes for composition or and spell checking\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-typing/issues/188\n\t\t\t\tthis.selection.refresh();\n\n\t\t\t\twasFixed = callback( writer );\n\n\t\t\t\tif ( wasFixed ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} while ( wasFixed );\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public log( version: any = null ): void {\n\t// @if CK_DEBUG_ENGINE // \tversion = version === null ? this.version : version;\n\t// @if CK_DEBUG_ENGINE // \tlogDocument( this, version );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n/**\n * Fired after each {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block} or the outermost\n * {@link module:engine/model/model~Model#change `change()` block} was executed and the document was changed\n * during that block's execution.\n *\n * The changes which this event will cover include:\n *\n * * document structure changes,\n * * selection changes,\n * * marker changes.\n *\n * If you want to be notified about all these changes, then simply listen to this event like this:\n *\n * ```ts\n * model.document.on( 'change', () => {\n * \tconsole.log( 'The document has changed!' );\n * } );\n * ```\n *\n * If, however, you only want to be notified about the data changes, then use `change:data` event,\n * which is fired for document structure changes and marker changes (which affects the data).\n *\n * ```ts\n * model.document.on( 'change:data', () => {\n * \tconsole.log( 'The data has changed!' );\n * } );\n * ```\n *\n * @eventName ~Document#change\n * @eventName ~Document#change:data\n * @param batch The batch that was used in the executed changes block.\n */\nexport type DocumentChangeEvent = {\n\tname: 'change' | 'change:data';\n\targs: [ batch: Batch ];\n};\n\n/**\n * Callback passed as an argument to the {@link module:engine/model/document~Document#registerPostFixer} method.\n */\nexport type ModelPostFixer = ( writer: Writer ) => boolean;\n\n/**\n * Checks whether given range boundary position is valid for document selection, meaning that is not between\n * unicode surrogate pairs or base character and combining marks.\n */\nfunction validateTextNodePosition( rangeBoundary: Position ) {\n\tconst textNode = rangeBoundary.textNode;\n\n\tif ( textNode ) {\n\t\tconst data = textNode.data;\n\t\tconst offset = rangeBoundary.offset - textNode.startOffset!;\n\n\t\treturn !isInsideSurrogatePair( data, offset ) && !isInsideCombinedSymbol( data, offset );\n\t}\n\n\treturn true;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/markercollection\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport LiveRange, {\n\ttype LiveRangeChangeContentEvent,\n\ttype LiveRangeChangeRangeEvent,\n\ttype LiveRangeChangeEvent\n} from './liverange.js';\n\nimport type Position from './position.js';\nimport type Range from './range.js';\n\nimport { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The collection of all {@link module:engine/model/markercollection~Marker markers} attached to the document.\n * It lets you {@link module:engine/model/markercollection~MarkerCollection#get get} markers or track them using\n * {@link module:engine/model/markercollection~MarkerCollection#event:update} event.\n *\n * To create, change or remove makers use {@link module:engine/model/writer~Writer model writers'} methods:\n * {@link module:engine/model/writer~Writer#addMarker} or {@link module:engine/model/writer~Writer#removeMarker}. Since\n * the writer is the only proper way to change the data model it is not possible to change markers directly using this\n * collection. All markers created by the writer will be automatically added to this collection.\n *\n * By default there is one marker collection available as {@link module:engine/model/model~Model#markers model property}.\n *\n * @see module:engine/model/markercollection~Marker\n */\nexport default class MarkerCollection extends /* #__PURE__ */ EmitterMixin() implements Iterable<Marker> {\n\t/**\n\t * Stores {@link ~Marker markers} added to the collection.\n\t */\n\tprivate _markers: Map<string, Marker> = new Map();\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Iterates over all {@link ~Marker markers} added to the collection.\n\t */\n\tpublic [ Symbol.iterator ](): IterableIterator<Marker> {\n\t\treturn this._markers.values();\n\t}\n\n\t/**\n\t * Checks if given {@link ~Marker marker} or marker name is in the collection.\n\t *\n\t * @param markerOrName Name of marker or marker instance to check.\n\t * @returns `true` if marker is in the collection, `false` otherwise.\n\t */\n\tpublic has( markerOrName: string | Marker ): boolean {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\n\t\treturn this._markers.has( markerName );\n\t}\n\n\t/**\n\t * Returns {@link ~Marker marker} with given `markerName`.\n\t *\n\t * @param markerName Name of marker to get.\n\t * @returns Marker with given name or `null` if such marker was\n\t * not added to the collection.\n\t */\n\tpublic get( markerName: string ): Marker | null {\n\t\treturn this._markers.get( markerName ) || null;\n\t}\n\n\t/**\n\t * Creates and adds a {@link ~Marker marker} to the `MarkerCollection` with given name on given\n\t * {@link module:engine/model/range~Range range}.\n\t *\n\t * If `MarkerCollection` already had a marker with given name (or {@link ~Marker marker} was passed), the marker in\n\t * collection is updated and {@link module:engine/model/markercollection~MarkerCollection#event:update} event is fired\n\t * but only if there was a change (marker range or {@link module:engine/model/markercollection~Marker#managedUsingOperations}\n\t * flag has changed.\n\t *\n\t * @internal\n\t * @fires update\n\t * @param markerOrName Name of marker to set or marker instance to update.\n\t * @param range Marker range.\n\t * @param managedUsingOperations Specifies whether the marker is managed using operations.\n\t * @param affectsData Specifies whether the marker affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t * @returns `Marker` instance which was added or updated.\n\t */\n\tpublic _set(\n\t\tmarkerOrName: string | Marker,\n\t\trange: Range,\n\t\tmanagedUsingOperations: boolean = false,\n\t\taffectsData: boolean = false\n\t): Marker {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\n\t\tif ( markerName.includes( ',' ) ) {\n\t\t\t/**\n\t\t\t * Marker name cannot contain the \",\" character.\n\t\t\t *\n\t\t\t * @error markercollection-incorrect-marker-name\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'markercollection-incorrect-marker-name', this );\n\t\t}\n\n\t\tconst oldMarker = this._markers.get( markerName );\n\n\t\tif ( oldMarker ) {\n\t\t\tconst oldMarkerData = oldMarker.getData();\n\n\t\t\tconst oldRange = oldMarker.getRange();\n\t\t\tlet hasChanged = false;\n\n\t\t\tif ( !oldRange.isEqual( range ) ) {\n\t\t\t\toldMarker._attachLiveRange( LiveRange.fromRange( range ) );\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tif ( managedUsingOperations != oldMarker.managedUsingOperations ) {\n\t\t\t\toldMarker._managedUsingOperations = managedUsingOperations;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tif ( typeof affectsData === 'boolean' && affectsData != oldMarker.affectsData ) {\n\t\t\t\toldMarker._affectsData = affectsData;\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tif ( hasChanged ) {\n\t\t\t\tthis.fire<MarkerCollectionUpdateEvent>( `update:${ markerName }`, oldMarker, oldRange, range, oldMarkerData );\n\t\t\t}\n\n\t\t\treturn oldMarker;\n\t\t}\n\n\t\tconst liveRange = LiveRange.fromRange( range );\n\t\tconst marker = new Marker( markerName, liveRange, managedUsingOperations, affectsData );\n\n\t\tthis._markers.set( markerName, marker );\n\t\tthis.fire<MarkerCollectionUpdateEvent>( `update:${ markerName }`, marker, null, range, { ...marker.getData(), range: null } );\n\n\t\treturn marker;\n\t}\n\n\t/**\n\t * Removes given {@link ~Marker marker} or a marker with given name from the `MarkerCollection`.\n\t *\n\t * @internal\n\t * @fires update\n\t * @param markerOrName Marker or name of a marker to remove.\n\t * @returns `true` if marker was found and removed, `false` otherwise.\n\t */\n\tpublic _remove( markerOrName: string | Marker ): boolean {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst oldMarker = this._markers.get( markerName );\n\n\t\tif ( oldMarker ) {\n\t\t\tthis._markers.delete( markerName );\n\t\t\tthis.fire<MarkerCollectionUpdateEvent>( `update:${ markerName }`, oldMarker, oldMarker.getRange(), null, oldMarker.getData() );\n\n\t\t\tthis._destroyMarker( oldMarker );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Fires an {@link module:engine/model/markercollection~MarkerCollection#event:update} event for the given {@link ~Marker marker}\n\t * but does not change the marker. Useful to force {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher downcast\n\t * conversion} for the marker.\n\t *\n\t * @internal\n\t * @fires update\n\t * @param markerOrName Marker or name of a marker to refresh.\n\t */\n\tpublic _refresh( markerOrName: string | Marker ): void {\n\t\tconst markerName = markerOrName instanceof Marker ? markerOrName.name : markerOrName;\n\t\tconst marker = this._markers.get( markerName );\n\n\t\tif ( !marker ) {\n\t\t\t/**\n\t\t\t * Marker with provided name does not exists.\n\t\t\t *\n\t\t\t * @error markercollection-refresh-marker-not-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'markercollection-refresh-marker-not-exists', this );\n\t\t}\n\n\t\tconst range = marker.getRange();\n\n\t\tthis.fire<MarkerCollectionUpdateEvent>( `update:${ markerName }`, marker, range, range, marker.getData() );\n\t}\n\n\t/**\n\t * Returns iterator that iterates over all markers, which ranges contain given {@link module:engine/model/position~Position position}.\n\t */\n\tpublic* getMarkersAtPosition( position: Position ): IterableIterator<Marker> {\n\t\tfor ( const marker of this ) {\n\t\t\tif ( marker.getRange().containsPosition( position ) ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns iterator that iterates over all markers, which intersects with given {@link module:engine/model/range~Range range}.\n\t */\n\tpublic* getMarkersIntersectingRange( range: Range ): Iterable<Marker> {\n\t\tfor ( const marker of this ) {\n\t\t\tif ( marker.getRange().getIntersection( range ) !== null ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys marker collection and all markers inside it.\n\t */\n\tpublic destroy(): void {\n\t\tfor ( const marker of this._markers.values() ) {\n\t\t\tthis._destroyMarker( marker );\n\t\t}\n\n\t\tthis._markers = null as any;\n\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Iterates over all markers that starts with given `prefix`.\n\t *\n\t * ```ts\n\t * const markerFooA = markersCollection._set( 'foo:a', rangeFooA );\n\t * const markerFooB = markersCollection._set( 'foo:b', rangeFooB );\n\t * const markerBarA = markersCollection._set( 'bar:a', rangeBarA );\n\t * const markerFooBarA = markersCollection._set( 'foobar:a', rangeFooBarA );\n\t * Array.from( markersCollection.getMarkersGroup( 'foo' ) ); // [ markerFooA, markerFooB ]\n\t * Array.from( markersCollection.getMarkersGroup( 'a' ) ); // []\n\t * ```\n\t */\n\tpublic* getMarkersGroup( prefix: string ): IterableIterator<Marker> {\n\t\tfor ( const marker of this._markers.values() ) {\n\t\t\tif ( marker.name.startsWith( prefix + ':' ) ) {\n\t\t\t\tyield marker;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the marker.\n\t */\n\tprivate _destroyMarker( marker: Marker ): void {\n\t\tmarker.stopListening();\n\t\tmarker._detachLiveRange();\n\t}\n}\n\nexport interface MarkerData {\n\n\t/**\n\t * Marker range. `null` if the marker was removed.\n\t */\n\trange: Range | null;\n\n\t/**\n\t * A property defining if the marker affects data.\n\t */\n\taffectsData: boolean;\n\n\t/**\n\t * A property defining if the marker is managed using operations.\n\t */\n\tmanagedUsingOperations: boolean;\n}\n\n/**\n * `Marker` is a continuous part of the model (like a range), is named and represents some kind of information about the\n * marked part of the model document. In contrary to {@link module:engine/model/node~Node nodes}, which are building blocks of\n * the model document tree, markers are not stored directly in the document tree but in the\n * {@link module:engine/model/model~Model#markers model markers' collection}. Still, they are document data, by giving\n * additional meaning to the part of a model document between marker start and marker end.\n *\n * In this sense, markers are similar to adding and converting attributes on nodes. The difference is that attribute is\n * connected with a given node (e.g. a character is bold no matter if it gets moved or content around it changes).\n * Markers on the other hand are continuous ranges and are characterized by their start and end position. This means that\n * any character in the marker is marked by the marker. For example, if a character is moved outside of marker it stops being\n * \"special\" and the marker is shrunk. Similarly, when a character is moved into the marker from other place in document\n * model, it starts being \"special\" and the marker is enlarged.\n *\n * Another upside of markers is that finding marked part of document is fast and easy. Using attributes to mark some nodes\n * and then trying to find that part of document would require traversing whole document tree. Marker gives instant access\n * to the range which it is marking at the moment.\n *\n * Markers are built from a name and a range.\n *\n * Range of the marker is updated automatically when document changes, using\n * {@link module:engine/model/liverange~LiveRange live range} mechanism.\n *\n * Name is used to group and identify markers. Names have to be unique, but markers can be grouped by\n * using common prefixes, separated with `:`, for example: `user:john` or `search:3`. That's useful in term of creating\n * namespaces for custom elements (e.g. comments, highlights). You can use this prefixes in\n * {@link module:engine/model/markercollection~MarkerCollection#event:update} listeners to listen on changes in a group of markers.\n * For instance: `model.markers.on( 'update:user', callback );` will be called whenever any `user:*` markers changes.\n *\n * There are two types of markers.\n *\n * 1. Markers managed directly, without using operations. They are added directly by {@link module:engine/model/writer~Writer}\n * to the {@link module:engine/model/markercollection~MarkerCollection} without any additional mechanism. They can be used\n * as bookmarks or visual markers. They are great for showing results of the find, or select link when the focus is in the input.\n *\n * 1. Markers managed using operations. These markers are also stored in {@link module:engine/model/markercollection~MarkerCollection}\n * but changes in these markers is managed the same way all other changes in the model structure - using operations.\n * Therefore, they are handled in the undo stack and synchronized between clients if the collaboration plugin is enabled.\n * This type of markers is useful for solutions like spell checking or comments.\n *\n * Both type of them should be added / updated by {@link module:engine/model/writer~Writer#addMarker}\n * and removed by {@link module:engine/model/writer~Writer#removeMarker} methods.\n *\n * ```ts\n * model.change( ( writer ) => {\n * \tconst marker = writer.addMarker( name, { range, usingOperation: true } );\n *\n * \t// ...\n *\n * \twriter.removeMarker( marker );\n * } );\n * ```\n *\n * See {@link module:engine/model/writer~Writer} to find more examples.\n *\n * Since markers need to track change in the document, for efficiency reasons, it is best to create and keep as little\n * markers as possible and remove them as soon as they are not needed anymore.\n *\n * Markers can be downcasted and upcasted.\n *\n * Markers downcast happens on {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker} and\n * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker} events.\n * Use {@link module:engine/conversion/downcasthelpers downcast converters} or attach a custom converter to mentioned events.\n * For {@link module:engine/controller/datacontroller~DataController data pipeline}, marker should be downcasted to an element.\n * Then, it can be upcasted back to a marker. Again, use {@link module:engine/conversion/upcasthelpers upcast converters} or\n * attach a custom converter to {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element}.\n *\n * `Marker` instances are created and destroyed only by {@link ~MarkerCollection MarkerCollection}.\n */\nclass Marker extends /* #__PURE__ */ EmitterMixin( TypeCheckable ) {\n\t/**\n\t * Marker's name.\n\t */\n\tpublic readonly name: string;\n\n\t/**\n\t * Flag indicates if the marker is managed using operations or not.\n\t *\n\t * @internal\n\t */\n\tpublic _managedUsingOperations: boolean;\n\n\t/**\n\t * Specifies whether the marker affects the data produced by the data pipeline\n\t * (is persisted in the editor's data).\n\t *\n\t * @internal\n\t */\n\tpublic _affectsData: boolean;\n\n\t/**\n\t * Range marked by the marker.\n\t */\n\tprivate _liveRange: LiveRange | null;\n\n\t/**\n\t * Creates a marker instance.\n\t *\n\t * @param name Marker name.\n\t * @param liveRange Range marked by the marker.\n\t * @param managedUsingOperations Specifies whether the marker is managed using operations.\n\t * @param affectsData Specifies whether the marker affects the data produced by the data pipeline (is persisted in the editor's data).\n\t */\n\tconstructor(\n\t\tname: string,\n\t\tliveRange: LiveRange,\n\t\tmanagedUsingOperations: boolean,\n\t\taffectsData: boolean\n\t) {\n\t\tsuper();\n\n\t\tthis.name = name;\n\t\tthis._liveRange = this._attachLiveRange( liveRange );\n\t\tthis._managedUsingOperations = managedUsingOperations;\n\t\tthis._affectsData = affectsData;\n\t}\n\n\t/**\n\t * A value indicating if the marker is managed using operations.\n\t * See {@link ~Marker marker class description} to learn more about marker types.\n\t * See {@link module:engine/model/writer~Writer#addMarker}.\n\t */\n\tpublic get managedUsingOperations(): boolean {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed', this );\n\t\t}\n\n\t\treturn this._managedUsingOperations;\n\t}\n\n\t/**\n\t * A value indicating if the marker changes the data.\n\t */\n\tpublic get affectsData(): boolean {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed', this );\n\t\t}\n\n\t\treturn this._affectsData;\n\t}\n\n\t/**\n\t * Returns the marker data (properties defining the marker).\n\t */\n\tpublic getData(): MarkerData {\n\t\treturn {\n\t\t\trange: this.getRange(),\n\t\t\taffectsData: this.affectsData,\n\t\t\tmanagedUsingOperations: this.managedUsingOperations\n\t\t};\n\t}\n\n\t/**\n\t * Returns current marker start position.\n\t */\n\tpublic getStart(): Position {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed', this );\n\t\t}\n\n\t\treturn this._liveRange.start.clone();\n\t}\n\n\t/**\n\t * Returns current marker end position.\n\t */\n\tpublic getEnd(): Position {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed', this );\n\t\t}\n\n\t\treturn this._liveRange.end.clone();\n\t}\n\n\t/**\n\t * Returns a range that represents the current state of the marker.\n\t *\n\t * Keep in mind that returned value is a {@link module:engine/model/range~Range Range}, not a\n\t * {@link module:engine/model/liverange~LiveRange LiveRange}. This means that it is up-to-date and relevant only\n\t * until next model document change. Do not store values returned by this method. Instead, store {@link ~Marker#name}\n\t * and get `Marker` instance from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection} every\n\t * time there is a need to read marker properties. This will guarantee that the marker has not been removed and\n\t * that it's data is up-to-date.\n\t */\n\tpublic getRange(): Range {\n\t\tif ( !this._liveRange ) {\n\t\t\tthrow new CKEditorError( 'marker-destroyed', this );\n\t\t}\n\n\t\treturn this._liveRange.toRange();\n\t}\n\n\t/**\n\t * Binds new live range to the marker and detach the old one if is attached.\n\t *\n\t * @internal\n\t * @param liveRange Live range to attach\n\t * @returns Attached live range.\n\t */\n\tpublic _attachLiveRange( liveRange: LiveRange ): LiveRange {\n\t\tif ( this._liveRange ) {\n\t\t\tthis._detachLiveRange();\n\t\t}\n\n\t\t// Delegating does not work with namespaces. Alternatively, we could delegate all events (using `*`).\n\t\tliveRange.delegate( 'change:range' ).to( this );\n\t\tliveRange.delegate( 'change:content' ).to( this );\n\n\t\tthis._liveRange = liveRange;\n\n\t\treturn liveRange;\n\t}\n\n\t/**\n\t * Unbinds and destroys currently attached live range.\n\t *\n\t * @internal\n\t */\n\tpublic _detachLiveRange(): void {\n\t\tthis._liveRange!.stopDelegating( 'change:range', this );\n\t\tthis._liveRange!.stopDelegating( 'change:content', this );\n\t\tthis._liveRange!.detach();\n\t\tthis._liveRange = null;\n\t}\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nMarker.prototype.is = function( type: string ): boolean {\n\treturn type === 'marker' || type === 'model:marker';\n};\n\nexport type { Marker };\n\n/**\n * Fired whenever {@link ~Marker#_liveRange marker range} is changed due to changes on {@link module:engine/model/document~Document}.\n * This is a delegated {@link module:engine/model/liverange~LiveRange#event:change:range LiveRange change:range event}.\n *\n * When marker is removed from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection},\n * all event listeners listening to it should be removed. It is best to do it on\n * {@link module:engine/model/markercollection~MarkerCollection#event:update MarkerCollection update event}.\n *\n * @see module:engine/model/liverange~LiveRange#event:change:range\n * @eventName ~Marker#change:range\n */\nexport type MarkerChangeRangeEvent = LiveRangeChangeRangeEvent;\n\n/**\n * Fired whenever change on {@link module:engine/model/document~Document} is done inside {@link ~Marker#_liveRange marker range}.\n * This is a delegated {@link module:engine/model/liverange~LiveRange#event:change:content LiveRange change:content event}.\n *\n * When marker is removed from {@link module:engine/model/markercollection~MarkerCollection MarkerCollection},\n * all event listeners listening to it should be removed. It is best to do it on\n * {@link module:engine/model/markercollection~MarkerCollection#event:update MarkerCollection update event}.\n *\n * @see module:engine/model/liverange~LiveRange#event:change:content\n * @eventName ~Marker#change:content\n */\nexport type MarkerCollectionChangeContentEvent = LiveRangeChangeContentEvent;\n\n/**\n * Describes `change:range` or `change:content` event.\n */\nexport type MarkerChangeEvent = LiveRangeChangeEvent;\n\n/**\n * Fired whenever marker is added, updated or removed from `MarkerCollection`.\n *\n * @eventName ~MarkerCollection#update\n * @param marker Updated Marker.\n * @param oldRange Marker range before the update. When is not defined it\n * means that marker is just added.\n * @param newRange Marker range after update. When is not defined it\n * means that marker is just removed.\n * @param oldMarkerData Data of the marker before the change.\n */\nexport type MarkerCollectionUpdateEvent = {\n\tname: 'update' | `update:${ string }`;\n\targs: [ marker: Marker, oldRange: Range | null, newRange: Range | null, oldMarkerData: MarkerData ];\n};\n\n/**\n * Cannot use a {@link module:engine/model/markercollection~MarkerCollection#destroy destroyed marker} instance.\n *\n * @error marker-destroyed\n */\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/operation/detachoperation\n */\n\nimport Operation from './operation.js';\nimport Range from '../range.js';\nimport { _remove } from './utils.js';\n\nimport type Position from '../position.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\nimport type { Selectable } from '../selection.js';\n\n// @if CK_DEBUG_ENGINE // const ModelRange = require( '../range' ).default;\n\n/**\n * Operation to permanently remove node from detached root.\n * Note this operation is only a local operation and won't be send to the other clients.\n */\nexport default class DetachOperation extends Operation {\n\t/**\n\t * Position before the first {@link module:engine/model/item~Item model item} to detach.\n\t */\n\tpublic sourcePosition: Position;\n\n\t/**\n\t * Offset size of moved range.\n\t */\n\tpublic howMany: number;\n\n\t// This class doesn't implement those abstract methods. Let's silence the compiler.\n\tdeclare public clone: never;\n\tdeclare public getReversed: never;\n\n\t/**\n\t * Creates an insert operation.\n\t *\n\t * @param sourcePosition Position before the first {@link module:engine/model/item~Item model item} to move.\n\t * @param howMany Offset size of moved range. Moved range will start from `sourcePosition` and end at\n\t * `sourcePosition` with offset shifted by `howMany`.\n\t */\n\tconstructor( sourcePosition: Position, howMany: number ) {\n\t\tsuper( null );\n\n\t\tthis.sourcePosition = sourcePosition.clone();\n\t\tthis.howMany = howMany;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get type(): 'detach' {\n\t\treturn 'detach';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic get affectedSelectable(): Selectable {\n\t\treturn null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override toJSON(): unknown {\n\t\tconst json: any = super.toJSON();\n\n\t\tjson.sourcePosition = this.sourcePosition.toJSON();\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic override _validate(): void {\n\t\tif ( this.sourcePosition.root.document ) {\n\t\t\t/**\n\t\t\t * Cannot detach document node.\n\t\t\t *\n\t\t\t * @error detach-operation-on-document-node\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'detach-operation-on-document-node', this );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t * @internal\n\t */\n\tpublic _execute(): void {\n\t\t_remove( Range._createFromPositionAndShift( this.sourcePosition, this.howMany ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get className(): string {\n\t\treturn 'DetachOperation';\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): string {\n\t// @if CK_DEBUG_ENGINE // \tconst range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );\n\t// @if CK_DEBUG_ENGINE // \tconst nodes = Array.from( range.getItems() );\n\t// @if CK_DEBUG_ENGINE // \tconst nodeString = nodes.length > 1 ? `[ ${ nodes.length } ]` : nodes[ 0 ];\n\n\t// @if CK_DEBUG_ENGINE // \treturn `DetachOperation( ${ this.baseVersion } ): ${ nodeString } -> ${ range }`;\n\t// @if CK_DEBUG_ENGINE // }\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/documentfragment\n */\n\nimport TypeCheckable from './typecheckable.js';\nimport Element from './element.js';\nimport NodeList from './nodelist.js';\nimport Text from './text.js';\nimport TextProxy from './textproxy.js';\n\nimport type Item from './item.js';\nimport type Node from './node.js';\nimport type Range from './range.js';\n\nimport { isIterable } from '@ckeditor/ckeditor5-utils';\n\n// @if CK_DEBUG_ENGINE // const { stringifyMap } = require( '../dev-utils/utils' );\n\n/**\n * DocumentFragment represents a part of model which does not have a common root but its top-level nodes\n * can be seen as siblings. In other words, it is a detached part of model tree, without a root.\n *\n * DocumentFragment has own {@link module:engine/model/markercollection~MarkerCollection}. Markers from this collection\n * will be set to the {@link module:engine/model/model~Model#markers model markers} by a\n * {@link module:engine/model/writer~Writer#insert} function.\n */\nexport default class DocumentFragment extends TypeCheckable implements Iterable<Node> {\n\t/**\n\t * DocumentFragment static markers map. This is a list of names and {@link module:engine/model/range~Range ranges}\n\t * which will be set as Markers to {@link module:engine/model/model~Model#markers model markers collection}\n\t * when DocumentFragment will be inserted to the document.\n\t */\n\tpublic readonly markers: Map<string, Range> = new Map();\n\n\t/**\n\t * Artificial element name. Returns `undefined`. Added for compatibility reasons.\n\t */\n\tdeclare public name?: undefined;\n\n\t/**\n\t * Artificial root name. Returns `undefined`. Added for compatibility reasons.\n\t */\n\tdeclare public rootName?: undefined;\n\n\t/**\n\t * List of nodes contained inside the document fragment.\n\t */\n\tprivate readonly _children: NodeList = new NodeList();\n\n\t/**\n\t * Creates an empty `DocumentFragment`.\n\t *\n\t * **Note:** Constructor of this class shouldn't be used directly in the code.\n\t * Use the {@link module:engine/model/writer~Writer#createDocumentFragment} method instead.\n\t *\n\t * @internal\n\t * @param children Nodes to be contained inside the `DocumentFragment`.\n\t */\n\tconstructor( children?: Node | Iterable<Node> ) {\n\t\tsuper();\n\n\t\tif ( children ) {\n\t\t\tthis._insertChild( 0, children );\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all nodes contained inside this document fragment.\n\t */\n\tpublic [ Symbol.iterator ](): IterableIterator<Node> {\n\t\treturn this.getChildren();\n\t}\n\n\t/**\n\t * Number of this document fragment's children.\n\t */\n\tpublic get childCount(): number {\n\t\treturn this._children.length;\n\t}\n\n\t/**\n\t * Sum of {@link module:engine/model/node~Node#offsetSize offset sizes} of all of this document fragment's children.\n\t */\n\tpublic get maxOffset(): number {\n\t\treturn this._children.maxOffset;\n\t}\n\n\t/**\n\t * Is `true` if there are no nodes inside this document fragment, `false` otherwise.\n\t */\n\tpublic get isEmpty(): boolean {\n\t\treturn this.childCount === 0;\n\t}\n\n\t/**\n\t * Artificial next sibling. Returns `null`. Added for compatibility reasons.\n\t */\n\tpublic get nextSibling(): null {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Artificial previous sibling. Returns `null`. Added for compatibility reasons.\n\t */\n\tpublic get previousSibling(): null {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Artificial root of `DocumentFragment`. Returns itself. Added for compatibility reasons.\n\t */\n\tpublic get root(): DocumentFragment {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Artificial parent of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t */\n\tpublic get parent(): null {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Artificial owner of `DocumentFragment`. Returns `null`. Added for compatibility reasons.\n\t */\n\tpublic get document(): null {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns `false` as `DocumentFragment` by definition is not attached to a document. Added for compatibility reasons.\n\t */\n\tpublic isAttached(): false {\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns empty array. Added for compatibility reasons.\n\t */\n\tpublic getAncestors(): Array<never> {\n\t\treturn [];\n\t}\n\n\t/**\n\t * Gets the child at the given index. Returns `null` if incorrect index was passed.\n\t *\n\t * @param index Index in this document fragment.\n\t * @returns Child node.\n\t */\n\tpublic getChild( index: number ): Node | null {\n\t\treturn this._children.getNode( index );\n\t}\n\n\t/**\n\t * Gets the child at the given offset. Returns `null` if incorrect index was passed.\n\t *\n\t * @param offset Offset in this document fragment.\n\t * @returns Child node.\n\t */\n\tpublic getChildAtOffset( offset: number ): Node | null {\n\t\treturn this._children.getNodeAtOffset( offset );\n\t}\n\n\t/**\n\t * Returns an iterator that iterates over all of this document fragment's children.\n\t */\n\tpublic getChildren(): IterableIterator<Node> {\n\t\treturn this._children[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Returns an index of the given child node. Returns `null` if given node is not a child of this document fragment.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's index.\n\t */\n\tpublic getChildIndex( node: Node ): number | null {\n\t\treturn this._children.getNodeIndex( node );\n\t}\n\n\t/**\n\t * Returns the starting offset of given child. Starting offset is equal to the sum of\n\t * {@link module:engine/model/node~Node#offsetSize offset sizes} of all node's siblings that are before it. Returns `null` if\n\t * given node is not a child of this document fragment.\n\t *\n\t * @param node Child node to look for.\n\t * @returns Child node's starting offset.\n\t */\n\tpublic getChildStartOffset( node: Node ): number | null {\n\t\treturn this._children.getNodeStartOffset( node );\n\t}\n\n\t/**\n\t * Returns path to a `DocumentFragment`, which is an empty array. Added for compatibility reasons.\n\t */\n\tpublic getPath(): Array<number> {\n\t\treturn [];\n\t}\n\n\t/**\n\t * Returns a descendant node by its path relative to this element.\n\t *\n\t * ```ts\n\t * // <this>a<b>c</b></this>\n\t * this.getNodeByPath( [ 0 ] );     // -> \"a\"\n\t * this.getNodeByPath( [ 1 ] );     // -> <b>\n\t * this.getNodeByPath( [ 1, 0 ] );  // -> \"c\"\n\t * ```\n\t *\n\t * @param relativePath Path of the node to find, relative to this element.\n\t */\n\tpublic getNodeByPath( relativePath: Array<number> ): Node | DocumentFragment {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias, consistent-this\n\t\tlet node: Node | DocumentFragment = this;\n\n\t\tfor ( const offset of relativePath ) {\n\t\t\tnode = ( node as Element | DocumentFragment ).getChildAtOffset( offset )!;\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Converts offset \"position\" to index \"position\".\n\t *\n\t * Returns index of a node that occupies given offset. If given offset is too low, returns `0`. If given offset is\n\t * too high, returns index after last child.\n\t *\n\t * ```ts\n\t * const textNode = new Text( 'foo' );\n\t * const pElement = new Element( 'p' );\n\t * const docFrag = new DocumentFragment( [ textNode, pElement ] );\n\t * docFrag.offsetToIndex( -1 ); // Returns 0, because offset is too low.\n\t * docFrag.offsetToIndex( 0 ); // Returns 0, because offset 0 is taken by `textNode` which is at index 0.\n\t * docFrag.offsetToIndex( 1 ); // Returns 0, because `textNode` has `offsetSize` equal to 3, so it occupies offset 1 too.\n\t * docFrag.offsetToIndex( 2 ); // Returns 0.\n\t * docFrag.offsetToIndex( 3 ); // Returns 1.\n\t * docFrag.offsetToIndex( 4 ); // Returns 2. There are no nodes at offset 4, so last available index is returned.\n\t * ```\n\t *\n\t * @param offset Offset to look for.\n\t * @returns Index of a node that occupies given offset.\n\t */\n\tpublic offsetToIndex( offset: number ): number {\n\t\treturn this._children.offsetToIndex( offset );\n\t}\n\n\t/**\n\t * Converts `DocumentFragment` instance to plain object and returns it.\n\t * Takes care of converting all of this document fragment's children.\n\t *\n\t * @returns `DocumentFragment` instance converted to plain object.\n\t */\n\tpublic toJSON(): unknown {\n\t\tconst json = [];\n\n\t\tfor ( const node of this._children ) {\n\t\t\tjson.push( node.toJSON() );\n\t\t}\n\n\t\treturn json;\n\t}\n\n\t/**\n\t * Creates a `DocumentFragment` instance from given plain object (i.e. parsed JSON string).\n\t * Converts `DocumentFragment` children to proper nodes.\n\t *\n\t * @param json Plain object to be converted to `DocumentFragment`.\n\t * @returns `DocumentFragment` instance created using given plain object.\n\t */\n\tpublic static fromJSON( json: any ): DocumentFragment {\n\t\tconst children = [];\n\n\t\tfor ( const child of json ) {\n\t\t\tif ( child.name ) {\n\t\t\t\t// If child has name property, it is an Element.\n\t\t\t\tchildren.push( Element.fromJSON( child ) );\n\t\t\t} else {\n\t\t\t\t// Otherwise, it is a Text node.\n\t\t\t\tchildren.push( Text.fromJSON( child ) );\n\t\t\t}\n\t\t}\n\n\t\treturn new DocumentFragment( children );\n\t}\n\n\t/**\n\t * {@link #_insertChild Inserts} one or more nodes at the end of this document fragment.\n\t *\n\t * @internal\n\t * @param items Items to be inserted.\n\t */\n\tpublic _appendChild( items: string | Item | Iterable<string | Item> ): void {\n\t\tthis._insertChild( this.childCount, items );\n\t}\n\n\t/**\n\t * Inserts one or more nodes at the given index and sets {@link module:engine/model/node~Node#parent parent} of these nodes\n\t * to this document fragment.\n\t *\n\t * @internal\n\t * @param index Index at which nodes should be inserted.\n\t * @param items Items to be inserted.\n\t */\n\tpublic _insertChild( index: number, items: string | Item | Iterable<string | Item> ): void {\n\t\tconst nodes = normalize( items );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t// If node that is being added to this element is already inside another element, first remove it from the old parent.\n\t\t\tif ( node.parent !== null ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\t( node as any ).parent = this;\n\t\t}\n\n\t\tthis._children._insertNodes( index, nodes );\n\t}\n\n\t/**\n\t * Removes one or more nodes starting at the given index\n\t * and sets {@link module:engine/model/node~Node#parent parent} of these nodes to `null`.\n\t *\n\t * @internal\n\t * @param index Index of the first node to remove.\n\t * @param howMany Number of nodes to remove.\n\t * @returns Array containing removed nodes.\n\t */\n\tpublic _removeChildren( index: number, howMany: number = 1 ): Array<Node> {\n\t\tconst nodes = this._children._removeNodes( index, howMany );\n\n\t\tfor ( const node of nodes ) {\n\t\t\t( node as any ).parent = null;\n\t\t}\n\n\t\treturn nodes;\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public override toString(): 'documentFragment' {\n\t// @if CK_DEBUG_ENGINE // \treturn 'documentFragment';\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public log(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( 'ModelDocumentFragment: ' + this );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public printTree(): string {\n\t// @if CK_DEBUG_ENGINE // \tlet string = 'ModelDocumentFragment: [';\n\n\t// @if CK_DEBUG_ENGINE // \tfor ( const child of this.getChildren() as any ) {\n\t// @if CK_DEBUG_ENGINE // \t\tstring += '\\n';\n\n\t// @if CK_DEBUG_ENGINE // \t\tif ( child.is( '$text' ) ) {\n\t// @if CK_DEBUG_ENGINE // \t\t\tconst textAttrs = stringifyMap( child._attrs );\n\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += '\\t'.repeat( 1 );\n\n\t// @if CK_DEBUG_ENGINE // \t\t\tif ( textAttrs !== '' ) {\n\t// @if CK_DEBUG_ENGINE // \t\t\t\tstring += `<$text${ textAttrs }>` + child.data + '</$text>';\n\t// @if CK_DEBUG_ENGINE // \t\t\t} else {\n\t// @if CK_DEBUG_ENGINE // \t\t\t\tstring += child.data;\n\t// @if CK_DEBUG_ENGINE // \t\t\t}\n\t// @if CK_DEBUG_ENGINE // \t\t} else {\n\t// @if CK_DEBUG_ENGINE // \t\t\tstring += child.printTree( 1 );\n\t// @if CK_DEBUG_ENGINE // \t\t}\n\t// @if CK_DEBUG_ENGINE // \t}\n\n\t// @if CK_DEBUG_ENGINE // \tstring += '\\n]';\n\n\t// @if CK_DEBUG_ENGINE // \treturn string;\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public logTree(): void {\n\t// @if CK_DEBUG_ENGINE // \tconsole.log( this.printTree() );\n\t// @if CK_DEBUG_ENGINE // }\n}\n\n// The magic of type inference using `is` method is centralized in `TypeCheckable` class.\n// Proper overload would interfere with that.\nDocumentFragment.prototype.is = function( type: string ): boolean {\n\treturn type === 'documentFragment' || type === 'model:documentFragment';\n};\n\n/**\n * Converts strings to Text and non-iterables to arrays.\n */\nfunction normalize( nodes: string | Item | Iterable<string | Item> ): Array<Node> {\n\t// Separate condition because string is iterable.\n\tif ( typeof nodes == 'string' ) {\n\t\treturn [ new Text( nodes ) ];\n\t}\n\n\tif ( !isIterable( nodes ) ) {\n\t\tnodes = [ nodes ];\n\t}\n\n\t// Array.from to enable .map() on non-arrays.\n\treturn Array.from( nodes )\n\t\t.map( node => {\n\t\t\tif ( typeof node == 'string' ) {\n\t\t\t\treturn new Text( node );\n\t\t\t}\n\n\t\t\tif ( node instanceof TextProxy ) {\n\t\t\t\treturn new Text( node.data, node.getAttributes() );\n\t\t\t}\n\n\t\t\treturn node;\n\t\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/writer\n */\n\nimport AttributeOperation from './operation/attributeoperation.js';\nimport DetachOperation from './operation/detachoperation.js';\nimport InsertOperation from './operation/insertoperation.js';\nimport MarkerOperation from './operation/markeroperation.js';\nimport MergeOperation from './operation/mergeoperation.js';\nimport MoveOperation from './operation/moveoperation.js';\nimport RenameOperation from './operation/renameoperation.js';\nimport RootAttributeOperation from './operation/rootattributeoperation.js';\nimport RootOperation from './operation/rootoperation.js';\nimport SplitOperation from './operation/splitoperation.js';\n\nimport DocumentFragment from './documentfragment.js';\nimport DocumentSelection from './documentselection.js';\nimport Element from './element.js';\nimport Position, { type PositionOffset, type PositionStickiness } from './position.js';\nimport Range from './range.js';\nimport RootElement from './rootelement.js';\nimport Text from './text.js';\n\nimport type { Marker } from './markercollection.js';\nimport type { default as Selection, PlaceOrOffset, Selectable } from './selection.js';\nimport type Batch from './batch.js';\nimport type Item from './item.js';\nimport type Model from './model.js';\nimport type { default as Node, NodeAttributes } from './node.js';\n\nimport { CKEditorError, logWarning, toMap } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The model can only be modified by using the writer. It should be used whenever you want to create a node, modify\n * child nodes, attributes or text, set the selection's position and its attributes.\n *\n * The instance of the writer is only available in the {@link module:engine/model/model~Model#change `change()`} or\n * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`}.\n *\n * ```ts\n * model.change( writer => {\n * \twriter.insertText( 'foo', paragraph, 'end' );\n * } );\n * ```\n *\n * Note that the writer should never be stored and used outside of the `change()` and\n * `enqueueChange()` blocks.\n *\n * Note that writer's methods do not check the {@link module:engine/model/schema~Schema}. It is possible\n * to create incorrect model structures by using the writer. Read more about in\n * {@glink framework/deep-dive/schema#who-checks-the-schema \"Who checks the schema?\"}.\n *\n * @see module:engine/model/model~Model#change\n * @see module:engine/model/model~Model#enqueueChange\n */\nexport default class Writer {\n\t/**\n\t * Instance of the model on which this writer operates.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * The batch to which this writer will add changes.\n\t */\n\tpublic readonly batch: Batch;\n\n\t/**\n\t * Creates a writer instance.\n\t *\n\t * **Note:** It is not recommended to use it directly. Use {@link module:engine/model/model~Model#change `Model#change()`} or\n\t * {@link module:engine/model/model~Model#enqueueChange `Model#enqueueChange()`} instead.\n\t *\n\t * @internal\n\t */\n\tconstructor( model: Model, batch: Batch ) {\n\t\tthis.model = model;\n\t\tthis.batch = batch;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/model/text~Text text node}.\n\t *\n\t * ```ts\n\t * writer.createText( 'foo' );\n\t * writer.createText( 'foo', { bold: true } );\n\t * ```\n\t *\n\t * @param data Text data.\n\t * @param attributes Text attributes.\n\t * @returns {module:engine/model/text~Text} Created text node.\n\t */\n\tpublic createText(\n\t\tdata: string,\n\t\tattributes?: NodeAttributes\n\t): Text {\n\t\treturn new Text( data, attributes );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/model/element~Element element}.\n\t *\n\t * ```ts\n\t * writer.createElement( 'paragraph' );\n\t * writer.createElement( 'paragraph', { alignment: 'center' } );\n\t * ```\n\t *\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @returns Created element.\n\t */\n\tpublic createElement(\n\t\tname: string,\n\t\tattributes?: NodeAttributes\n\t): Element {\n\t\treturn new Element( name, attributes );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/model/documentfragment~DocumentFragment document fragment}.\n\t *\n\t * @returns Created document fragment.\n\t */\n\tpublic createDocumentFragment(): DocumentFragment {\n\t\treturn new DocumentFragment();\n\t}\n\n\t/**\n\t * Creates a copy of the element and returns it. Created element has the same name and attributes as the original element.\n\t * If clone is deep, the original element's children are also cloned. If not, then empty element is returned.\n\t *\n\t * @param element The element to clone.\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any child.\n\t */\n\tpublic cloneElement( element: Element, deep: boolean = true ): Element {\n\t\treturn element._clone( deep );\n\t}\n\n\t/**\n\t * Inserts item on given position.\n\t *\n\t * ```ts\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * writer.insert( paragraph, position );\n\t * ```\n\t *\n\t * Instead of using position you can use parent and offset:\n\t *\n\t * ```ts\n\t * const text = writer.createText( 'foo' );\n\t * writer.insert( text, paragraph, 5 );\n\t * ```\n\t *\n\t * You can also use `end` instead of the offset to insert at the end:\n\t *\n\t * ```ts\n\t * const text = writer.createText( 'foo' );\n\t * writer.insert( text, paragraph, 'end' );\n\t * ```\n\t *\n\t * Or insert before or after another element:\n\t *\n\t * ```ts\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * writer.insert( paragraph, anotherParagraph, 'after' );\n\t * ```\n\t *\n\t * These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * Note that if the item already has parent it will be removed from the previous parent.\n\t *\n\t * Note that you cannot re-insert a node from a document to a different document or a document fragment. In this case,\n\t * `model-writer-insert-forbidden-move` is thrown.\n\t *\n\t * If you want to move {@link module:engine/model/range~Range range} instead of an\n\t * {@link module:engine/model/item~Item item} use {@link module:engine/model/writer~Writer#move `Writer#move()`}.\n\t *\n\t * **Note:** For a paste-like content insertion mechanism see\n\t * {@link module:engine/model/model~Model#insertContent `model.insertContent()`}.\n\t *\n\t * @param item Item or document fragment to insert.\n\t * @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic insert(\n\t\titem: Item | DocumentFragment,\n\t\titemOrPosition: Item | DocumentFragment | Position,\n\t\toffset: PositionOffset = 0\n\t): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( item instanceof Text && item.data == '' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = Position._createAt( itemOrPosition, offset );\n\n\t\t// If item has a parent already.\n\t\tif ( item.parent ) {\n\t\t\t// We need to check if item is going to be inserted within the same document.\n\t\t\tif ( isSameTree( item.root, position.root ) ) {\n\t\t\t\t// If it's we just need to move it.\n\t\t\t\tthis.move( Range._createOn( item ), position );\n\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// If it isn't the same root.\n\t\t\telse {\n\t\t\t\tif ( item.root.document ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Cannot move a node from a document to a different tree.\n\t\t\t\t\t * It is forbidden to move a node that was already in a document outside of it.\n\t\t\t\t\t *\n\t\t\t\t\t * @error model-writer-insert-forbidden-move\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t\t'model-writer-insert-forbidden-move',\n\t\t\t\t\t\tthis\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// Move between two different document fragments or from document fragment to a document is possible.\n\t\t\t\t\t// In that case, remove the item from it's original parent.\n\t\t\t\t\tthis.remove( item );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst version = position.root.document ? position.root.document.version : null;\n\n\t\tconst insert = new InsertOperation( position, item, version );\n\n\t\tif ( item instanceof Text ) {\n\t\t\tinsert.shouldReceiveAttributes = true;\n\t\t}\n\n\t\tthis.batch.addOperation( insert );\n\t\tthis.model.applyOperation( insert );\n\n\t\t// When element is a DocumentFragment we need to move its markers to Document#markers.\n\t\tif ( item instanceof DocumentFragment ) {\n\t\t\tfor ( const [ markerName, markerRange ] of item.markers ) {\n\t\t\t\t// We need to migrate marker range from DocumentFragment to Document.\n\t\t\t\tconst rangeRootPosition = Position._createAt( markerRange.root, 0 );\n\t\t\t\tconst range = new Range(\n\t\t\t\t\tmarkerRange.start._getCombined( rangeRootPosition, position ),\n\t\t\t\t\tmarkerRange.end._getCombined( rangeRootPosition, position )\n\t\t\t\t);\n\n\t\t\t\tconst options = { range, usingOperation: true, affectsData: true };\n\n\t\t\t\tif ( this.model.markers.has( markerName ) ) {\n\t\t\t\t\tthis.updateMarker( markerName, options );\n\t\t\t\t} else {\n\t\t\t\t\tthis.addMarker( markerName, options );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates and inserts text on given position.\n\t *\n\t * ```ts\n\t * writer.insertText( 'foo', position );\n\t * ```\n\t *\n\t * Instead of using position you can use parent and offset or define that text should be inserted at the end\n\t * or before or after other node:\n\t *\n\t * ```ts\n\t * // Inserts 'foo' in paragraph, at offset 5:\n\t * writer.insertText( 'foo', paragraph, 5 );\n\t * // Inserts 'foo' at the end of a paragraph:\n\t * writer.insertText( 'foo', paragraph, 'end' );\n\t * // Inserts 'foo' after an image:\n\t * writer.insertText( 'foo', image, 'after' );\n\t * ```\n\t *\n\t * These parameters work in the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * @label WITHOUT_ATTRIBUTES\n\t * @param text Text data.\n\t * @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic insertText(\n\t\ttext: string,\n\t\titemOrPosition?: Item | Position,\n\t\toffset?: PositionOffset\n\t): void;\n\n\t/**\n\t * Creates and inserts text with specified attributes on given position.\n\t *\n\t * ```ts\n\t * writer.insertText( 'foo', { bold: true }, position );\n\t * ```\n\t *\n\t * Instead of using position you can use parent and offset or define that text should be inserted at the end\n\t * or before or after other node:\n\t *\n\t * ```ts\n\t * // Inserts 'foo' in paragraph, at offset 5:\n\t * writer.insertText( 'foo', { bold: true }, paragraph, 5 );\n\t * // Inserts 'foo' at the end of a paragraph:\n\t * writer.insertText( 'foo', { bold: true }, paragraph, 'end' );\n\t * // Inserts 'foo' after an image:\n\t * writer.insertText( 'foo', { bold: true }, image, 'after' );\n\t * ```\n\t *\n\t * These parameters work in the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * @label WITH_ATTRIBUTES\n\t * @param text Text data.\n\t * @param attributes Text attributes.\n\t * @param offset Offset or one of the flags. Used only when third parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic insertText(\n\t\ttext: string,\n\t\tattributes?: NodeAttributes,\n\t\titemOrPosition?: Item | Position,\n\t\toffset?: PositionOffset\n\t): void;\n\n\tpublic insertText(\n\t\ttext: string,\n\t\tattributes?: any, // Too complicated when not using `any`.\n\t\titemOrPosition?: any, // Too complicated when not using `any`.\n\t\toffset?: any // Too complicated when not using `any`.\n\t): void {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element || attributes instanceof Position ) {\n\t\t\tthis.insert( this.createText( text ), attributes, itemOrPosition );\n\t\t} else {\n\t\t\tthis.insert( this.createText( text, attributes ), itemOrPosition, offset );\n\t\t}\n\t}\n\n\t/**\n\t * Creates and inserts element on given position. You can optionally set attributes:\n\t *\n\t * ```ts\n\t * writer.insertElement( 'paragraph', position );\n\t * ```\n\t *\n\t * Instead of using position you can use parent and offset or define that text should be inserted at the end\n\t * or before or after other node:\n\t *\n\t * ```ts\n\t * // Inserts paragraph in the root at offset 5:\n\t * writer.insertElement( 'paragraph', root, 5 );\n\t * // Inserts paragraph at the end of a blockquote:\n\t * writer.insertElement( 'paragraph', blockquote, 'end' );\n\t * // Inserts after an image:\n\t * writer.insertElement( 'paragraph', image, 'after' );\n\t * ```\n\t *\n\t * These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * @label WITHOUT_ATTRIBUTES\n\t * @param name Name of the element.\n\t * @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic insertElement(\n\t\tname: string,\n\t\titemOrPosition: Item | DocumentFragment | Position,\n\t\toffset?: PositionOffset\n\t): void;\n\n\t/**\n\t * Creates and inserts element with specified attributes on given position.\n\t *\n\t * ```ts\n\t * writer.insertElement( 'paragraph', { alignment: 'center' }, position );\n\t * ```\n\t *\n\t * Instead of using position you can use parent and offset or define that text should be inserted at the end\n\t * or before or after other node:\n\t *\n\t * ```ts\n\t * // Inserts paragraph in the root at offset 5:\n\t * writer.insertElement( 'paragraph', { alignment: 'center' }, root, 5 );\n\t * // Inserts paragraph at the end of a blockquote:\n\t * writer.insertElement( 'paragraph', { alignment: 'center' }, blockquote, 'end' );\n\t * // Inserts after an image:\n\t * writer.insertElement( 'paragraph', { alignment: 'center' }, image, 'after' );\n\t * ```\n\t *\n\t * These parameters works the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * @label WITH_ATTRIBUTES\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t * @param offset Offset or one of the flags. Used only when third parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic insertElement(\n\t\tname: string,\n\t\tattributes: NodeAttributes,\n\t\titemOrPosition: Item | DocumentFragment | Position,\n\t\toffset?: PositionOffset\n\t): void;\n\n\tpublic insertElement(\n\t\tname: string,\n\t\tattributes: any, // Too complicated when not using `any`.\n\t\titemOrPositionOrOffset?: any, // Too complicated when not using `any`.\n\t\toffset?: any // Too complicated when not using `any`.\n\t): void {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element || attributes instanceof Position ) {\n\t\t\tthis.insert( this.createElement( name ), attributes, itemOrPositionOrOffset );\n\t\t} else {\n\t\t\tthis.insert( this.createElement( name, attributes ), itemOrPositionOrOffset, offset );\n\t\t}\n\t}\n\n\t/**\n\t * Inserts item at the end of the given parent.\n\t *\n\t * ```ts\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * writer.append( paragraph, root );\n\t * ```\n\t *\n\t * Note that if the item already has parent it will be removed from the previous parent.\n\t *\n\t * If you want to move {@link module:engine/model/range~Range range} instead of an\n\t * {@link module:engine/model/item~Item item} use {@link module:engine/model/writer~Writer#move `Writer#move()`}.\n\t *\n\t * @param item Item or document fragment to insert.\n\t */\n\tpublic append( item: Item | DocumentFragment, parent: Element | DocumentFragment ): void {\n\t\tthis.insert( item, parent, 'end' );\n\t}\n\n\t/**\n\t * Creates text node and inserts it at the end of the parent.\n\t *\n\t * ```ts\n\t * writer.appendText( 'foo', paragraph );\n\t * ```\n\t *\n\t * @label WITHOUT_ATTRIBUTES\n\t * @param text Text data.\n\t */\n\tpublic appendText(\n\t\ttext: string,\n\t\tparent: Element | DocumentFragment\n\t): void;\n\n\t/**\n\t * Creates text node with specified attributes and inserts it at the end of the parent.\n\t *\n\t * ```ts\n\t * writer.appendText( 'foo', { bold: true }, paragraph );\n\t * ```\n\t *\n\t * @label WITH_ATTRIBUTES\n\t * @param text Text data.\n\t * @param attributes Text attributes.\n\t */\n\tpublic appendText(\n\t\ttext: string,\n\t\tattributes: NodeAttributes,\n\t\tparent: Element | DocumentFragment\n\t): void;\n\n\tpublic appendText(\n\t\ttext: string,\n\t\tattributes: NodeAttributes | Element | DocumentFragment,\n\t\tparent?: Element | DocumentFragment\n\t): void {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element ) {\n\t\t\tthis.insert( this.createText( text ), attributes, 'end' );\n\t\t} else {\n\t\t\tthis.insert( this.createText( text, attributes ), parent!, 'end' );\n\t\t}\n\t}\n\n\t/**\n\t * Creates element and inserts it at the end of the parent.\n\t *\n\t * ```ts\n\t * writer.appendElement( 'paragraph', root );\n\t * ```\n\t *\n\t * @label WITHOUT_ATTRIBUTES\n\t * @param name Name of the element.\n\t */\n\tpublic appendElement(\n\t\tname: string,\n\t\tparent: Element | DocumentFragment\n\t): void;\n\n\t/**\n\t * Creates element with specified attributes and inserts it at the end of the parent.\n\t *\n\t * ```ts\n\t * writer.appendElement( 'paragraph', { alignment: 'center' }, root );\n\t * ```\n\t *\n\t * @label WITH_ATTRIBUTES\n\t * @param name Name of the element.\n\t * @param attributes Elements attributes.\n\t */\n\tpublic appendElement(\n\t\tname: string,\n\t\tattributes: NodeAttributes,\n\t\tparent: Element | DocumentFragment\n\t): void;\n\n\tpublic appendElement(\n\t\tname: string,\n\t\tattributes: NodeAttributes | Element | DocumentFragment,\n\t\tparent?: Element | DocumentFragment\n\t): void {\n\t\tif ( attributes instanceof DocumentFragment || attributes instanceof Element ) {\n\t\t\tthis.insert( this.createElement( name ), attributes, 'end' );\n\t\t} else {\n\t\t\tthis.insert( this.createElement( name, attributes ), parent!, 'end' );\n\t\t}\n\t}\n\n\t/**\n\t * Sets value of the attribute with given key on a {@link module:engine/model/item~Item model item}\n\t * or on a {@link module:engine/model/range~Range range}.\n\t *\n\t * @param key Attribute key.\n\t * @param value Attribute new value.\n\t * @param itemOrRange Model item or range on which the attribute will be set.\n\t */\n\tpublic setAttribute( key: string, value: unknown, itemOrRange: Item | Range ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( itemOrRange instanceof Range ) {\n\t\t\tconst ranges = itemOrRange.getMinimalFlatRanges();\n\n\t\t\tfor ( const range of ranges ) {\n\t\t\t\tsetAttributeOnRange( this, key, value, range );\n\t\t\t}\n\t\t} else {\n\t\t\tsetAttributeOnItem( this, key, value, itemOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Sets values of attributes on a {@link module:engine/model/item~Item model item}\n\t * or on a {@link module:engine/model/range~Range range}.\n\t *\n\t * ```ts\n\t * writer.setAttributes( {\n\t * \tbold: true,\n\t * \titalic: true\n\t * }, range );\n\t * ```\n\t *\n\t * @param attributes Attributes keys and values.\n\t * @param itemOrRange Model item or range on which the attributes will be set.\n\t */\n\tpublic setAttributes(\n\t\tattributes: NodeAttributes,\n\t\titemOrRange: Item | Range\n\t): void {\n\t\tfor ( const [ key, val ] of toMap( attributes ) ) {\n\t\t\tthis.setAttribute( key, val, itemOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Removes an attribute with given key from a {@link module:engine/model/item~Item model item}\n\t * or from a {@link module:engine/model/range~Range range}.\n\t *\n\t * @param key Attribute key.\n\t * @param itemOrRange Model item or range from which the attribute will be removed.\n\t */\n\tpublic removeAttribute( key: string, itemOrRange: Item | Range ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( itemOrRange instanceof Range ) {\n\t\t\tconst ranges = itemOrRange.getMinimalFlatRanges();\n\n\t\t\tfor ( const range of ranges ) {\n\t\t\t\tsetAttributeOnRange( this, key, null, range );\n\t\t\t}\n\t\t} else {\n\t\t\tsetAttributeOnItem( this, key, null, itemOrRange );\n\t\t}\n\t}\n\n\t/**\n\t * Removes all attributes from all elements in the range or from the given item.\n\t *\n\t * @param itemOrRange Model item or range from which all attributes will be removed.\n\t */\n\tpublic clearAttributes( itemOrRange: Item | Range ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst removeAttributesFromItem = ( item: Item ) => {\n\t\t\tfor ( const attribute of item.getAttributeKeys() ) {\n\t\t\t\tthis.removeAttribute( attribute, item );\n\t\t\t}\n\t\t};\n\n\t\tif ( !( itemOrRange instanceof Range ) ) {\n\t\t\tremoveAttributesFromItem( itemOrRange );\n\t\t} else {\n\t\t\tfor ( const item of itemOrRange.getItems() ) {\n\t\t\t\tremoveAttributesFromItem( item );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Moves all items in the source range to the target position.\n\t *\n\t * ```ts\n\t * writer.move( sourceRange, targetPosition );\n\t * ```\n\t *\n\t * Instead of the target position you can use parent and offset or define that range should be moved to the end\n\t * or before or after chosen item:\n\t *\n\t * ```ts\n\t * // Moves all items in the range to the paragraph at offset 5:\n\t * writer.move( sourceRange, paragraph, 5 );\n\t * // Moves all items in the range to the end of a blockquote:\n\t * writer.move( sourceRange, blockquote, 'end' );\n\t * // Moves all items in the range to a position after an image:\n\t * writer.move( sourceRange, image, 'after' );\n\t * ```\n\t *\n\t * These parameters work the same way as {@link #createPositionAt `writer.createPositionAt()`}.\n\t *\n\t * Note that items can be moved only within the same tree. It means that you can move items within the same root\n\t * (element or document fragment) or between {@link module:engine/model/document~Document#roots documents roots},\n\t * but you can not move items from document fragment to the document or from one detached element to another. Use\n\t * {@link module:engine/model/writer~Writer#insert} in such cases.\n\t *\n\t * @param range Source range.\n\t * @param offset Offset or one of the flags. Used only when second parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic move(\n\t\trange: Range,\n\t\titemOrPosition: Item | Position,\n\t\toffset?: PositionOffset\n\t): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !( range instanceof Range ) ) {\n\t\t\t/**\n\t\t\t * Invalid range to move.\n\t\t\t *\n\t\t\t * @error writer-move-invalid-range\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-move-invalid-range', this );\n\t\t}\n\n\t\tif ( !range.isFlat ) {\n\t\t\t/**\n\t\t\t * Range to move is not flat.\n\t\t\t *\n\t\t\t * @error writer-move-range-not-flat\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-move-range-not-flat', this );\n\t\t}\n\n\t\tconst position = Position._createAt( itemOrPosition, offset );\n\n\t\t// Do not move anything if the move target is same as moved range start.\n\t\tif ( position.isEqual( range.start ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If part of the marker is removed, create additional marker operation for undo purposes.\n\t\tthis._addOperationForAffectedMarkers( 'move', range );\n\n\t\tif ( !isSameTree( range.root, position.root ) ) {\n\t\t\t/**\n\t\t\t * Range is going to be moved within not the same document. Please use\n\t\t\t * {@link module:engine/model/writer~Writer#insert insert} instead.\n\t\t\t *\n\t\t\t * @error writer-move-different-document\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-move-different-document', this );\n\t\t}\n\n\t\tconst version = range.root.document ? range.root.document.version : null;\n\t\tconst operation = new MoveOperation( range.start, range.end.offset - range.start.offset, position, version );\n\n\t\tthis.batch.addOperation( operation );\n\t\tthis.model.applyOperation( operation );\n\t}\n\n\t/**\n\t * Removes given model {@link module:engine/model/item~Item item} or {@link module:engine/model/range~Range range}.\n\t *\n\t * @param itemOrRange Model item or range to remove.\n\t */\n\tpublic remove( itemOrRange: Item | Range ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst rangeToRemove = itemOrRange instanceof Range ? itemOrRange : Range._createOn( itemOrRange );\n\t\tconst ranges = rangeToRemove.getMinimalFlatRanges().reverse();\n\n\t\tfor ( const flat of ranges ) {\n\t\t\t// If part of the marker is removed, create additional marker operation for undo purposes.\n\t\t\tthis._addOperationForAffectedMarkers( 'move', flat );\n\n\t\t\tapplyRemoveOperation( flat.start, flat.end.offset - flat.start.offset, this.batch, this.model );\n\t\t}\n\t}\n\n\t/**\n\t * Merges two siblings at the given position.\n\t *\n\t * Node before and after the position have to be an element. Otherwise `writer-merge-no-element-before` or\n\t * `writer-merge-no-element-after` error will be thrown.\n\t *\n\t * @param position Position between merged elements.\n\t */\n\tpublic merge( position: Position ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst nodeBefore = position.nodeBefore;\n\t\tconst nodeAfter = position.nodeAfter;\n\n\t\t// If part of the marker is removed, create additional marker operation for undo purposes.\n\t\tthis._addOperationForAffectedMarkers( 'merge', position );\n\n\t\tif ( !( nodeBefore instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Node before merge position must be an element.\n\t\t\t *\n\t\t\t * @error writer-merge-no-element-before\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-merge-no-element-before', this );\n\t\t}\n\n\t\tif ( !( nodeAfter instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Node after merge position must be an element.\n\t\t\t *\n\t\t\t * @error writer-merge-no-element-after\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-merge-no-element-after', this );\n\t\t}\n\n\t\tif ( !position.root.document ) {\n\t\t\tthis._mergeDetached( position );\n\t\t} else {\n\t\t\tthis._merge( position );\n\t\t}\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionFromPath `Model#createPositionFromPath()`}.\n\t *\n\t * @param root Root of the position.\n\t * @param path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param stickiness Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */\n\tpublic createPositionFromPath(\n\t\troot: Element | DocumentFragment,\n\t\tpath: ReadonlyArray<number>,\n\t\tstickiness?: PositionStickiness\n\t): Position {\n\t\treturn this.model.createPositionFromPath( root, path, stickiness );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionAt `Model#createPositionAt()`}.\n\t *\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic createPositionAt(\n\t\titemOrPosition: Item | Position | DocumentFragment,\n\t\toffset?: PositionOffset\n\t): Position {\n\t\treturn this.model.createPositionAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionAfter `Model#createPositionAfter()`}.\n\t *\n\t * @param item Item after which the position should be placed.\n\t */\n\tpublic createPositionAfter( item: Item ): Position {\n\t\treturn this.model.createPositionAfter( item );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createPositionBefore `Model#createPositionBefore()`}.\n\t *\n\t * @param item Item after which the position should be placed.\n\t */\n\tpublic createPositionBefore( item: Item ): Position {\n\t\treturn this.model.createPositionBefore( item );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createRange `Model#createRange()`}.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */\n\tpublic createRange( start: Position, end?: Position ): Range {\n\t\treturn this.model.createRange( start, end );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createRangeIn `Model#createRangeIn()`}.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic createRangeIn( element: Element | DocumentFragment ): Range {\n\t\treturn this.model.createRangeIn( element );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createRangeOn `Model#createRangeOn()`}.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic createRangeOn( element: Item ): Range {\n\t\treturn this.model.createRangeOn( element );\n\t}\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createSelection:NODE_OFFSET `Model#createSelection()`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic createSelection( selectable: Node, placeOrOffset: PlaceOrOffset, options?: { backward?: boolean } ): Selection;\n\n\t/**\n\t * Shortcut for {@link module:engine/model/model~Model#createSelection:SELECTABLE `Model#createSelection()`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic createSelection( selectable?: Exclude<Selectable, Node>, options?: { backward?: boolean } ): Selection;\n\n\tpublic createSelection( ...args: [ any?, any?, any? ] ): Selection {\n\t\treturn this.model.createSelection( ...args );\n\t}\n\n\t/**\n\t * Performs merge action in a detached tree.\n\t *\n\t * @param position Position between merged elements.\n\t */\n\tprivate _mergeDetached( position: Position ): void {\n\t\tconst nodeBefore = position.nodeBefore;\n\t\tconst nodeAfter = position.nodeAfter;\n\n\t\tthis.move( Range._createIn( nodeAfter as any ), Position._createAt( nodeBefore!, 'end' ) );\n\t\tthis.remove( nodeAfter! );\n\t}\n\n\t/**\n\t * Performs merge action in a non-detached tree.\n\t *\n\t * @param position Position between merged elements.\n\t */\n\tprivate _merge( position: Position ): void {\n\t\tconst targetPosition = Position._createAt( position.nodeBefore!, 'end' );\n\t\tconst sourcePosition = Position._createAt( position.nodeAfter!, 0 );\n\n\t\tconst graveyard = position.root.document!.graveyard;\n\t\tconst graveyardPosition = new Position( graveyard, [ 0 ] );\n\n\t\tconst version = position.root.document!.version;\n\n\t\tconst merge = new MergeOperation(\n\t\t\tsourcePosition,\n\t\t\t( position.nodeAfter as any ).maxOffset,\n\t\t\ttargetPosition,\n\t\t\tgraveyardPosition,\n\t\t\tversion\n\t\t);\n\n\t\tthis.batch.addOperation( merge );\n\t\tthis.model.applyOperation( merge );\n\t}\n\n\t/**\n\t * Renames the given element.\n\t *\n\t * @param element The element to rename.\n\t * @param newName New element name.\n\t */\n\tpublic rename( element: Element | DocumentFragment, newName: string ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !( element instanceof Element ) ) {\n\t\t\t/**\n\t\t\t * Trying to rename an object which is not an instance of Element.\n\t\t\t *\n\t\t\t * @error writer-rename-not-element-instance\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'writer-rename-not-element-instance',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tconst version = element.root.document ? element.root.document.version : null;\n\t\tconst renameOperation = new RenameOperation( Position._createBefore( element ), element.name, newName, version );\n\n\t\tthis.batch.addOperation( renameOperation );\n\t\tthis.model.applyOperation( renameOperation );\n\t}\n\n\t/**\n\t * Splits elements starting from the given position and going to the top of the model tree as long as given\n\t * `limitElement` is reached. When `limitElement` is not defined then only the parent of the given position will be split.\n\t *\n\t * The element needs to have a parent. It cannot be a root element nor a document fragment.\n\t * The `writer-split-element-no-parent` error will be thrown if you try to split an element with no parent.\n\t *\n\t * @param position Position of split.\n\t * @param limitElement Stop splitting when this element will be reached.\n\t * @returns Split result with properties:\n\t * * `position` - Position between split elements.\n\t * * `range` - Range that stars from the end of the first split element and ends at the beginning of the first copy element.\n\t */\n\tpublic split( position: Position, limitElement?: Node | DocumentFragment ): { position: Position; range: Range } {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tlet splitElement = position.parent;\n\n\t\tif ( !splitElement.parent ) {\n\t\t\t/**\n\t\t\t * Element with no parent can not be split.\n\t\t\t *\n\t\t\t * @error writer-split-element-no-parent\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-split-element-no-parent', this );\n\t\t}\n\n\t\t// When limit element is not defined lets set splitElement parent as limit.\n\t\tif ( !limitElement ) {\n\t\t\tlimitElement = splitElement.parent;\n\t\t}\n\n\t\tif ( !position.parent.getAncestors( { includeSelf: true } ).includes( limitElement! ) ) {\n\t\t\t/**\n\t\t\t * Limit element is not a position ancestor.\n\t\t\t *\n\t\t\t * @error writer-split-invalid-limit-element\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-split-invalid-limit-element', this );\n\t\t}\n\n\t\t// We need to cache elements that will be created as a result of the first split because\n\t\t// we need to create a range from the end of the first split element to the beginning of the\n\t\t// first copy element. This should be handled by LiveRange but it doesn't work on detached nodes.\n\t\tlet firstSplitElement: Element | DocumentFragment | undefined;\n\t\tlet firstCopyElement: Node | null | undefined;\n\n\t\tdo {\n\t\t\tconst version = splitElement.root.document ? splitElement.root.document.version : null;\n\t\t\tconst howMany = splitElement.maxOffset - position.offset;\n\n\t\t\tconst insertionPosition = SplitOperation.getInsertionPosition( position );\n\t\t\tconst split = new SplitOperation( position, howMany, insertionPosition, null, version );\n\n\t\t\tthis.batch.addOperation( split );\n\t\t\tthis.model.applyOperation( split );\n\n\t\t\t// Cache result of the first split.\n\t\t\tif ( !firstSplitElement && !firstCopyElement ) {\n\t\t\t\tfirstSplitElement = splitElement;\n\t\t\t\tfirstCopyElement = position.parent.nextSibling;\n\t\t\t}\n\n\t\t\tposition = this.createPositionAfter( position.parent as any );\n\t\t\tsplitElement = position.parent;\n\t\t} while ( splitElement !== limitElement );\n\n\t\treturn {\n\t\t\tposition,\n\t\t\trange: new Range( Position._createAt( firstSplitElement!, 'end' ), Position._createAt( firstCopyElement!, 0 ) )\n\t\t};\n\t}\n\n\t/**\n\t * Wraps the given range with the given element or with a new element (if a string was passed).\n\t *\n\t * **Note:** range to wrap should be a \"flat range\" (see {@link module:engine/model/range~Range#isFlat `Range#isFlat`}).\n\t * If not, an error will be thrown.\n\t *\n\t * @param range Range to wrap.\n\t * @param elementOrString Element or name of element to wrap the range with.\n\t */\n\tpublic wrap( range: Range, elementOrString: Element | string ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !range.isFlat ) {\n\t\t\t/**\n\t\t\t * Range to wrap is not flat.\n\t\t\t *\n\t\t\t * @error writer-wrap-range-not-flat\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-wrap-range-not-flat', this );\n\t\t}\n\n\t\tconst element = elementOrString instanceof Element ? elementOrString : new Element( elementOrString );\n\n\t\tif ( element.childCount > 0 ) {\n\t\t\t/**\n\t\t\t * Element to wrap with is not empty.\n\t\t\t *\n\t\t\t * @error writer-wrap-element-not-empty\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-wrap-element-not-empty', this );\n\t\t}\n\n\t\tif ( element.parent !== null ) {\n\t\t\t/**\n\t\t\t * Element to wrap with is already attached to a tree model.\n\t\t\t *\n\t\t\t * @error writer-wrap-element-attached\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-wrap-element-attached', this );\n\t\t}\n\n\t\tthis.insert( element, range.start );\n\n\t\t// Shift the range-to-wrap because we just inserted an element before that range.\n\t\tconst shiftedRange = new Range( range.start.getShiftedBy( 1 ), range.end.getShiftedBy( 1 ) );\n\n\t\tthis.move( shiftedRange, Position._createAt( element, 0 ) );\n\t}\n\n\t/**\n\t * Unwraps children of the given element – all its children are moved before it and then the element is removed.\n\t * Throws error if you try to unwrap an element which does not have a parent.\n\t *\n\t * @param element Element to unwrap.\n\t */\n\tpublic unwrap( element: Element ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( element.parent === null ) {\n\t\t\t/**\n\t\t\t * Trying to unwrap an element which has no parent.\n\t\t\t *\n\t\t\t * @error writer-unwrap-element-no-parent\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-unwrap-element-no-parent', this );\n\t\t}\n\n\t\tthis.move( Range._createIn( element ), this.createPositionAfter( element ) );\n\t\tthis.remove( element );\n\t}\n\n\t/**\n\t * Adds a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t * changes in the document and updates its range automatically, when model tree changes.\n\t *\n\t * As the first parameter you can set marker name.\n\t *\n\t * The required `options.usingOperation` parameter lets you decide if the marker should be managed by operations or not. See\n\t * {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t * markers managed by operations and not-managed by operations.\n\t *\n\t * The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t * `true` when the marker change changes the data returned by the\n\t * {@link module:core/editor/editor~Editor#getData `editor.getData()`} method.\n\t * When set to `true` it fires the {@link module:engine/model/document~Document#event:change:data `change:data`} event.\n\t * When set to `false` it fires the {@link module:engine/model/document~Document#event:change `change`} event.\n\t *\n\t * Create marker directly base on marker's name:\n\t *\n\t * ```ts\n\t * addMarker( markerName, { range, usingOperation: false } );\n\t * ```\n\t *\n\t * Create marker using operation:\n\t *\n\t * ```ts\n\t * addMarker( markerName, { range, usingOperation: true } );\n\t * ```\n\t *\n\t * Create marker that affects the editor data:\n\t *\n\t * ```ts\n\t * addMarker( markerName, { range, usingOperation: false, affectsData: true } );\n\t * ```\n\t *\n\t * Note: For efficiency reasons, it's best to create and keep as little markers as possible.\n\t *\n\t * @see module:engine/model/markercollection~Marker\n\t * @param name Name of a marker to create - must be unique.\n\t * @param options.usingOperation Flag indicating that the marker should be added by MarkerOperation.\n\t * See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t * @param options.range Marker range.\n\t * @param options.affectsData Flag indicating that the marker changes the editor data.\n\t * @returns Marker that was set.\n\t */\n\tpublic addMarker(\n\t\tname: string,\n\t\toptions: {\n\t\t\tusingOperation: boolean;\n\t\t\taffectsData?: boolean;\n\t\t\trange: Range;\n\t\t}\n\t): Marker {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( !options || typeof options.usingOperation != 'boolean' ) {\n\t\t\t/**\n\t\t\t * The `options.usingOperation` parameter is required when adding a new marker.\n\t\t\t *\n\t\t\t * @error writer-addmarker-no-usingoperation\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-addmarker-no-usingoperation', this );\n\t\t}\n\n\t\tconst usingOperation = options.usingOperation;\n\t\tconst range = options.range;\n\t\tconst affectsData = options.affectsData === undefined ? false : options.affectsData;\n\n\t\tif ( this.model.markers.has( name ) ) {\n\t\t\t/**\n\t\t\t * Marker with provided name already exists.\n\t\t\t *\n\t\t\t * @error writer-addmarker-marker-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-addmarker-marker-exists', this );\n\t\t}\n\n\t\tif ( !range ) {\n\t\t\t/**\n\t\t\t * Range parameter is required when adding a new marker.\n\t\t\t *\n\t\t\t * @error writer-addmarker-no-range\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-addmarker-no-range', this );\n\t\t}\n\n\t\tif ( !usingOperation ) {\n\t\t\treturn this.model.markers._set( name, range, usingOperation, affectsData );\n\t\t}\n\n\t\tapplyMarkerOperation( this, name, null, range, affectsData );\n\n\t\treturn this.model.markers.get( name )!;\n\t}\n\n\t/**\n\t * Adds, updates or refreshes a {@link module:engine/model/markercollection~Marker marker}. Marker is a named range, which tracks\n\t * changes in the document and updates its range automatically, when model tree changes. Still, it is possible to change the\n\t * marker's range directly using this method.\n\t *\n\t * As the first parameter you can set marker name or instance. If none of them is provided, new marker, with a unique\n\t * name is created and returned.\n\t *\n\t * **Note**: If you want to change the {@link module:engine/view/element~Element view element} of the marker while its data in the model\n\t * remains the same, use the dedicated {@link module:engine/controller/editingcontroller~EditingController#reconvertMarker} method.\n\t *\n\t * The `options.usingOperation` parameter lets you change if the marker should be managed by operations or not. See\n\t * {@link module:engine/model/markercollection~Marker marker class description} to learn about the difference between\n\t * markers managed by operations and not-managed by operations. It is possible to change this option for an existing marker.\n\t *\n\t * The `options.affectsData` parameter, which defaults to `false`, allows you to define if a marker affects the data. It should be\n\t * `true` when the marker change changes the data returned by\n\t * the {@link module:core/editor/editor~Editor#getData `editor.getData()`} method.\n\t * When set to `true` it fires the {@link module:engine/model/document~Document#event:change:data `change:data`} event.\n\t * When set to `false` it fires the {@link module:engine/model/document~Document#event:change `change`} event.\n\t *\n\t * Update marker directly base on marker's name:\n\t *\n\t * ```ts\n\t * updateMarker( markerName, { range } );\n\t * ```\n\t *\n\t * Update marker using operation:\n\t *\n\t * ```ts\n\t * updateMarker( marker, { range, usingOperation: true } );\n\t * updateMarker( markerName, { range, usingOperation: true } );\n\t * ```\n\t *\n\t * Change marker's option (start using operations to manage it):\n\t *\n\t * ```ts\n\t * updateMarker( marker, { usingOperation: true } );\n\t * ```\n\t *\n\t * Change marker's option (inform the engine, that the marker does not affect the data anymore):\n\t *\n\t * ```ts\n\t * updateMarker( markerName, { affectsData: false } );\n\t * ```\n\t *\n\t * @see module:engine/model/markercollection~Marker\n\t * @param markerOrName Name of a marker to update, or a marker instance.\n\t * @param options If options object is not defined then marker will be refreshed by triggering\n\t * downcast conversion for this marker with the same data.\n\t * @param options.range Marker range to update.\n\t * @param options.usingOperation Flag indicated whether the marker should be added by MarkerOperation.\n\t * See {@link module:engine/model/markercollection~Marker#managedUsingOperations}.\n\t * @param options.affectsData Flag indicating that the marker changes the editor data.\n\t */\n\tpublic updateMarker(\n\t\tmarkerOrName: string | Marker,\n\t\toptions?: {\n\t\t\trange?: Range;\n\t\t\tusingOperation?: boolean;\n\t\t\taffectsData?: boolean;\n\t\t}\n\t): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst markerName = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n\t\tconst currentMarker = this.model.markers.get( markerName );\n\n\t\tif ( !currentMarker ) {\n\t\t\t/**\n\t\t\t * Marker with provided name does not exist and will not be updated.\n\t\t\t *\n\t\t\t * @error writer-updatemarker-marker-not-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-updatemarker-marker-not-exists', this );\n\t\t}\n\n\t\tif ( !options ) {\n\t\t\t/**\n\t\t\t * The usage of `writer.updateMarker()` only to reconvert (refresh) a\n\t\t\t * {@link module:engine/model/markercollection~Marker model marker} was deprecated and may not work in the future.\n\t\t\t * Please update your code to use\n\t\t\t * {@link module:engine/controller/editingcontroller~EditingController#reconvertMarker `editor.editing.reconvertMarker()`}\n\t\t\t * instead.\n\t\t\t *\n\t\t\t * @error writer-updatemarker-reconvert-using-editingcontroller\n\t\t\t * @param markerName The name of the updated marker.\n\t\t\t */\n\t\t\tlogWarning( 'writer-updatemarker-reconvert-using-editingcontroller', { markerName } );\n\n\t\t\tthis.model.markers._refresh( currentMarker );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst hasUsingOperationDefined = typeof options.usingOperation == 'boolean';\n\t\tconst affectsDataDefined = typeof options.affectsData == 'boolean';\n\n\t\t// Use previously defined marker's affectsData if the property is not provided.\n\t\tconst affectsData = affectsDataDefined ? options.affectsData : currentMarker.affectsData;\n\n\t\tif ( !hasUsingOperationDefined && !options.range && !affectsDataDefined ) {\n\t\t\t/**\n\t\t\t * One of the options is required - provide range, usingOperations or affectsData.\n\t\t\t *\n\t\t\t * @error writer-updatemarker-wrong-options\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-updatemarker-wrong-options', this );\n\t\t}\n\n\t\tconst currentRange = currentMarker.getRange();\n\t\tconst updatedRange = options.range ? options.range : currentRange;\n\n\t\tif ( hasUsingOperationDefined && options.usingOperation !== currentMarker.managedUsingOperations ) {\n\t\t\t// The marker type is changed so it's necessary to create proper operations.\n\t\t\tif ( options.usingOperation ) {\n\t\t\t\t// If marker changes to a managed one treat this as synchronizing existing marker.\n\t\t\t\t// Create `MarkerOperation` with `oldRange` set to `null`, so reverse operation will remove the marker.\n\t\t\t\tapplyMarkerOperation( this, markerName, null, updatedRange, affectsData );\n\t\t\t} else {\n\t\t\t\t// If marker changes to a marker that do not use operations then we need to create additional operation\n\t\t\t\t// that removes that marker first.\n\t\t\t\tapplyMarkerOperation( this, markerName, currentRange, null, affectsData );\n\n\t\t\t\t// Although not managed the marker itself should stay in model and its range should be preserver or changed to passed range.\n\t\t\t\tthis.model.markers._set( markerName, updatedRange, undefined, affectsData );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Marker's type doesn't change so update it accordingly.\n\t\tif ( currentMarker.managedUsingOperations ) {\n\t\t\tapplyMarkerOperation( this, markerName, currentRange, updatedRange, affectsData );\n\t\t} else {\n\t\t\tthis.model.markers._set( markerName, updatedRange, undefined, affectsData );\n\t\t}\n\t}\n\n\t/**\n\t * Removes given {@link module:engine/model/markercollection~Marker marker} or marker with given name.\n\t * The marker is removed accordingly to how it has been created, so if the marker was created using operation,\n\t * it will be destroyed using operation.\n\t *\n\t * @param markerOrName Marker or marker name to remove.\n\t */\n\tpublic removeMarker( markerOrName: string | Marker ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst name = typeof markerOrName == 'string' ? markerOrName : markerOrName.name;\n\n\t\tif ( !this.model.markers.has( name ) ) {\n\t\t\t/**\n\t\t\t * Trying to remove marker which does not exist.\n\t\t\t *\n\t\t\t * @error writer-removemarker-no-marker\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-removemarker-no-marker', this );\n\t\t}\n\n\t\tconst marker = this.model.markers.get( name )!;\n\n\t\tif ( !marker.managedUsingOperations ) {\n\t\t\tthis.model.markers._remove( name );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst oldRange = marker.getRange();\n\n\t\tapplyMarkerOperation( this, name, oldRange, null, marker.affectsData );\n\t}\n\n\t/**\n\t * Adds a new root to the document (or re-attaches a {@link #detachRoot detached root}).\n\t *\n\t * Throws an error, if trying to add a root that is already added and attached.\n\t *\n\t * @param rootName Name of the added root.\n\t * @param elementName The element name. Defaults to `'$root'` which also has some basic schema defined\n\t * (e.g. `$block` elements are allowed inside the `$root`). Make sure to define a proper schema if you use a different name.\n\t * @returns The added root element.\n\t */\n\tpublic addRoot( rootName: string, elementName = '$root' ): RootElement {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst root = this.model.document.getRoot( rootName );\n\n\t\tif ( root && root.isAttached() ) {\n\t\t\t/**\n\t\t\t * Root with provided name already exists and is attached.\n\t\t\t *\n\t\t\t * @error writer-addroot-root-exists\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-addroot-root-exists', this );\n\t\t}\n\n\t\tconst document = this.model.document;\n\t\tconst operation = new RootOperation( rootName, elementName, true, document, document.version );\n\n\t\tthis.batch.addOperation( operation );\n\t\tthis.model.applyOperation( operation );\n\n\t\treturn this.model.document.getRoot( rootName )!;\n\t}\n\n\t/**\n\t * Detaches the root from the document.\n\t *\n\t * All content and markers are removed from the root upon detaching. New content and new markers cannot be added to the root, as long\n\t * as it is detached.\n\t *\n\t * A root cannot be fully removed from the document, it can be only detached. A root is permanently removed only after you\n\t * re-initialize the editor and do not specify the root in the initial data.\n\t *\n\t * A detached root can be re-attached using {@link #addRoot}.\n\t *\n\t * Throws an error if the root does not exist or the root is already detached.\n\t *\n\t * @param rootOrName Name of the detached root.\n\t */\n\tpublic detachRoot( rootOrName: string | RootElement ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tconst root = typeof rootOrName == 'string' ? this.model.document.getRoot( rootOrName ) : rootOrName;\n\n\t\tif ( !root || !root.isAttached() ) {\n\t\t\t/**\n\t\t\t * Root with provided name does not exist or is already detached.\n\t\t\t *\n\t\t\t * @error writer-detachroot-no-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'writer-detachroot-no-root', this );\n\t\t}\n\n\t\t// First, remove all markers from the root. It is better to do it before removing stuff for undo purposes.\n\t\t// However, looking through all the markers may not be the best performance wise. But there's no better solution for now.\n\t\tfor ( const marker of this.model.markers ) {\n\t\t\tif ( marker.getRange().root === root ) {\n\t\t\t\tthis.removeMarker( marker );\n\t\t\t}\n\t\t}\n\n\t\t// Remove all attributes from the root.\n\t\tfor ( const key of root.getAttributeKeys() ) {\n\t\t\tthis.removeAttribute( key, root );\n\t\t}\n\n\t\t// Remove all contents of the root.\n\t\tthis.remove( this.createRangeIn( root ) );\n\n\t\t// Finally, detach the root.\n\t\tconst document = this.model.document;\n\t\tconst operation = new RootOperation( root.rootName, root.name, false, document, document.version );\n\n\t\tthis.batch.addOperation( operation );\n\t\tthis.model.applyOperation( operation );\n\t}\n\n\t/**\n\t * Sets the document's selection (ranges and direction) to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable} or creates an empty selection if no arguments were passed.\n\t *\n\t * ```ts\n\t * // Sets collapsed selection at the position of the given node and an offset.\n\t * writer.setSelection( paragraph, offset );\n\t * ```\n\t *\n\t * Creates a range inside an {@link module:engine/model/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * ```ts\n\t * writer.setSelection( paragraph, 'in' );\n\t * ```\n\t *\n\t * Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends just after the item.\n\t *\n\t * ```ts\n\t * writer.setSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Writer#setSelection()` allow passing additional options (`backward`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * writer.setSelection( element, 'in', { backward: true } );\n\t * ```\n\t *\n\t * Throws `writer-incorrect-use` error when the writer is used outside the `change()` block.\n\t *\n\t * See also: {@link #setSelection:SELECTABLE `setSelection( selectable, options )`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic setSelection( selectable: Node, placeOrOffset: PlaceOrOffset, options?: { backward?: boolean } ): void;\n\n\t/**\n\t * Sets the document's selection (ranges and direction) to the specified location based on the given\n\t * {@link module:engine/model/selection~Selectable selectable} or creates an empty selection if no arguments were passed.\n\t *\n\t * ```ts\n\t * // Sets selection to the given range.\n\t * const range = writer.createRange( start, end );\n\t * writer.setSelection( range );\n\t *\n\t * // Sets selection to given ranges.\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * writer.setSelection( ranges );\n\t *\n\t * // Sets selection to other selection.\n\t * const otherSelection = writer.createSelection();\n\t * writer.setSelection( otherSelection );\n\t *\n\t * // Sets selection to the given document selection.\n\t * const documentSelection = model.document.selection;\n\t * writer.setSelection( documentSelection );\n\t *\n\t * // Sets collapsed selection at the given position.\n\t * const position = writer.createPosition( root, path );\n\t * writer.setSelection( position );\n\t *\n\t * // Removes all selection's ranges.\n\t * writer.setSelection( null );\n\t * ```\n\t *\n\t * `Writer#setSelection()` allow passing additional options (`backward`) as the last argument.\n\t *\n\t * ```ts\n\t * // Sets selection as backward.\n\t * writer.setSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * Throws `writer-incorrect-use` error when the writer is used outside the `change()` block.\n\t *\n\t * See also: {@link #setSelection:NODE_OFFSET `setSelection( node, placeOrOffset, options )`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic setSelection( selectable: Exclude<Selectable, Node>, options?: { backward?: boolean } ): void;\n\n\tpublic setSelection( ...args: Parameters<Selection[ 'setTo' ]> ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tthis.model.document.selection._setTo( ...args );\n\t}\n\n\t/**\n\t * Moves {@link module:engine/model/documentselection~DocumentSelection#focus} to the specified location.\n\t *\n\t * The location can be specified in the same form as\n\t * {@link #createPositionAt `writer.createPositionAt()`} parameters.\n\t *\n\t * @param itemOrPosition\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic setSelectionFocus(\n\t\titemOrPosition: Item | Position,\n\t\toffset?: PositionOffset\n\t): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tthis.model.document.selection._setFocus( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Sets attribute on the selection. If attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * ```ts\n\t * writer.setSelectionAttribute( 'italic', true );\n\t * ```\n\t *\n\t * @label KEY_VALUE\n\t * @param key Key of the attribute to set.\n\t * @param value Attribute value.\n\t */\n\tpublic setSelectionAttribute( key: string, value: unknown ): void;\n\n\t/**\n\t * Sets attributes on the selection. If any attribute with the same key already is set, it's value is overwritten.\n\t *\n\t * Using key-value object:\n\t *\n\t * ```ts\n\t * writer.setSelectionAttribute( { italic: true, bold: false } );\n\t * ```\n\t *\n\t * Using iterable object:\n\t *\n\t * ```ts\n\t * writer.setSelectionAttribute( new Map( [ [ 'italic', true ] ] ) );\n\t * ```\n\t *\n\t * @label OBJECT\n\t * @param objectOrIterable Object / iterable of key => value attribute pairs.\n\t */\n\tpublic setSelectionAttribute( objectOrIterable: NodeAttributes ): void;\n\n\tpublic setSelectionAttribute(\n\t\tkeyOrObjectOrIterable: string | NodeAttributes,\n\t\tvalue?: unknown\n\t): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( typeof keyOrObjectOrIterable === 'string' ) {\n\t\t\tthis._setSelectionAttribute( keyOrObjectOrIterable, value );\n\t\t} else {\n\t\t\tfor ( const [ key, value ] of toMap( keyOrObjectOrIterable ) ) {\n\t\t\t\tthis._setSelectionAttribute( key, value );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Removes attribute(s) with given key(s) from the selection.\n\t *\n\t * Remove one attribute:\n\t *\n\t * ```ts\n\t * writer.removeSelectionAttribute( 'italic' );\n\t * ```\n\t *\n\t * Remove multiple attributes:\n\t *\n\t * ```ts\n\t * writer.removeSelectionAttribute( [ 'italic', 'bold' ] );\n\t * ```\n\t *\n\t * @param keyOrIterableOfKeys Key of the attribute to remove or an iterable of attribute keys to remove.\n\t */\n\tpublic removeSelectionAttribute( keyOrIterableOfKeys: string | Iterable<string> ): void {\n\t\tthis._assertWriterUsedCorrectly();\n\n\t\tif ( typeof keyOrIterableOfKeys === 'string' ) {\n\t\t\tthis._removeSelectionAttribute( keyOrIterableOfKeys );\n\t\t} else {\n\t\t\tfor ( const key of keyOrIterableOfKeys ) {\n\t\t\t\tthis._removeSelectionAttribute( key );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Temporarily changes the {@link module:engine/model/documentselection~DocumentSelection#isGravityOverridden gravity}\n\t * of the selection from left to right.\n\t *\n\t * The gravity defines from which direction the selection inherits its attributes. If it's the default left gravity,\n\t * then the selection (after being moved by the user) inherits attributes from its left-hand side.\n\t * This method allows to temporarily override this behavior by forcing the gravity to the right.\n\t *\n\t * For the following model fragment:\n\t *\n\t * ```xml\n\t * <$text bold=\"true\" linkHref=\"url\">bar[]</$text><$text bold=\"true\">biz</$text>\n\t * ```\n\t *\n\t * * Default gravity: selection will have the `bold` and `linkHref` attributes.\n\t * * Overridden gravity: selection will have `bold` attribute.\n\t *\n\t * **Note**: It returns an unique identifier which is required to restore the gravity. It guarantees the symmetry\n\t * of the process.\n\t *\n\t * @returns The unique id which allows restoring the gravity.\n\t */\n\tpublic overrideSelectionGravity(): string {\n\t\treturn this.model.document.selection._overrideGravity();\n\t}\n\n\t/**\n\t * Restores {@link ~Writer#overrideSelectionGravity} gravity to default.\n\t *\n\t * Restoring the gravity is only possible using the unique identifier returned by\n\t * {@link ~Writer#overrideSelectionGravity}. Note that the gravity remains overridden as long as won't be restored\n\t * the same number of times it was overridden.\n\t *\n\t * @param uid The unique id returned by {@link ~Writer#overrideSelectionGravity}.\n\t */\n\tpublic restoreSelectionGravity( uid: string ): void {\n\t\tthis.model.document.selection._restoreGravity( uid );\n\t}\n\n\t/**\n\t * @param key Key of the attribute to remove.\n\t * @param value Attribute value.\n\t */\n\tprivate _setSelectionAttribute( key: string, value: unknown ): void {\n\t\tconst selection = this.model.document.selection;\n\n\t\t// Store attribute in parent element if the selection is collapsed in an empty node.\n\t\tif ( selection.isCollapsed && selection.anchor!.parent.isEmpty ) {\n\t\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( key );\n\n\t\t\tthis.setAttribute( storeKey, value, selection.anchor!.parent as any );\n\t\t}\n\n\t\tselection._setAttribute( key, value );\n\t}\n\n\t/**\n\t * @param key Key of the attribute to remove.\n\t */\n\tprivate _removeSelectionAttribute( key: string ): void {\n\t\tconst selection = this.model.document.selection;\n\n\t\t// Remove stored attribute from parent element if the selection is collapsed in an empty node.\n\t\tif ( selection.isCollapsed && selection.anchor!.parent.isEmpty ) {\n\t\t\tconst storeKey = DocumentSelection._getStoreAttributeKey( key );\n\n\t\t\tthis.removeAttribute( storeKey, selection.anchor!.parent as any );\n\t\t}\n\n\t\tselection._removeAttribute( key );\n\t}\n\n\t/**\n\t * Throws `writer-detached-writer-tries-to-modify-model` error when the writer is used outside of the `change()` block.\n\t */\n\tprivate _assertWriterUsedCorrectly(): void {\n\t\t/**\n\t\t * Trying to use a writer outside a {@link module:engine/model/model~Model#change `change()`} or\n\t\t * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()`} blocks.\n\t\t *\n\t\t * The writer can only be used inside these blocks which ensures that the model\n\t\t * can only be changed during such \"sessions\".\n\t\t *\n\t\t * @error writer-incorrect-use\n\t\t */\n\t\tif ( ( this.model as any )._currentWriter !== this ) {\n\t\t\tthrow new CKEditorError( 'writer-incorrect-use', this );\n\t\t}\n\t}\n\n\t/**\n\t * For given action `type` and `positionOrRange` where the action happens, this function finds all affected markers\n\t * and applies a marker operation with the new marker range equal to the current range. Thanks to this, the marker range\n\t * can be later correctly processed during undo.\n\t *\n\t * @param type Writer action type.\n\t * @param positionOrRange Position or range where the writer action happens.\n\t */\n\tprivate _addOperationForAffectedMarkers(\n\t\ttype: 'move' | 'merge',\n\t\tpositionOrRange: Position | Range\n\t): void {\n\t\tfor ( const marker of this.model.markers ) {\n\t\t\tif ( !marker.managedUsingOperations ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst markerRange = marker.getRange();\n\t\t\tlet isAffected = false;\n\n\t\t\tif ( type === 'move' ) {\n\t\t\t\tconst range = positionOrRange as Range;\n\t\t\t\tisAffected =\n\t\t\t\t\trange.containsPosition( markerRange.start ) ||\n\t\t\t\t\trange.start.isEqual( markerRange.start ) ||\n\t\t\t\t\trange.containsPosition( markerRange.end ) ||\n\t\t\t\t\trange.end.isEqual( markerRange.end );\n\t\t\t} else {\n\t\t\t\t// if type === 'merge'.\n\t\t\t\tconst position = positionOrRange as Position;\n\t\t\t\tconst elementBefore = position.nodeBefore;\n\t\t\t\tconst elementAfter = position.nodeAfter;\n\n\t\t\t\t//               Start:  <p>Foo[</p><p>Bar]</p>\n\t\t\t\t//         After merge:  <p>Foo[Bar]</p>\n\t\t\t\t// After undoing split:  <p>Foo</p><p>[Bar]</p>     <-- incorrect, needs remembering for undo.\n\t\t\t\t//\n\t\t\t\tconst affectedInLeftElement = markerRange.start.parent == elementBefore && markerRange.start.isAtEnd;\n\n\t\t\t\t//               Start:  <p>[Foo</p><p>]Bar</p>\n\t\t\t\t//         After merge:  <p>[Foo]Bar</p>\n\t\t\t\t// After undoing split:  <p>[Foo]</p><p>Bar</p>     <-- incorrect, needs remembering for undo.\n\t\t\t\t//\n\t\t\t\tconst affectedInRightElement = markerRange.end.parent == elementAfter && markerRange.end.offset == 0;\n\n\t\t\t\t//               Start:  <p>[Foo</p>]<p>Bar</p>\n\t\t\t\t//         After merge:  <p>[Foo]Bar</p>\n\t\t\t\t// After undoing split:  <p>[Foo]</p><p>Bar</p>     <-- incorrect, needs remembering for undo.\n\t\t\t\t//\n\t\t\t\tconst affectedAfterLeftElement = markerRange.end.nodeAfter == elementAfter;\n\n\t\t\t\t//               Start:  <p>Foo</p>[<p>Bar]</p>\n\t\t\t\t//         After merge:  <p>Foo[Bar]</p>\n\t\t\t\t// After undoing split:  <p>Foo</p><p>[Bar]</p>     <-- incorrect, needs remembering for undo.\n\t\t\t\t//\n\t\t\t\tconst affectedBeforeRightElement = markerRange.start.nodeAfter == elementAfter;\n\n\t\t\t\tisAffected = affectedInLeftElement || affectedInRightElement || affectedAfterLeftElement || affectedBeforeRightElement;\n\t\t\t}\n\n\t\t\tif ( isAffected ) {\n\t\t\t\tthis.updateMarker( marker.name, { range: markerRange } );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Sets given attribute to each node in given range. When attribute value is null then attribute will be removed.\n *\n * Because attribute operation needs to have the same attribute value on the whole range, this function splits\n * the range into smaller parts.\n *\n * Given `range` must be flat.\n */\nfunction setAttributeOnRange( writer: Writer, key: string, value: unknown, range: Range ) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\n\t// Position of the last split, the beginning of the new range.\n\tlet lastSplitPosition = range.start;\n\n\t// Currently position in the scanning range. Because we need value after the position, it is not a current\n\t// position of the iterator but the previous one (we need to iterate one more time to get the value after).\n\tlet position: Position | undefined;\n\n\t// Value before the currently position.\n\tlet valueBefore: unknown;\n\n\t// Value after the currently position.\n\tlet valueAfter;\n\n\tfor ( const val of range.getWalker( { shallow: true } ) ) {\n\t\tvalueAfter = val.item.getAttribute( key );\n\n\t\t// At the first run of the iterator the position in undefined. We also do not have a valueBefore, but\n\t\t// because valueAfter may be null, valueBefore may be equal valueAfter ( undefined == null ).\n\t\tif ( position && valueBefore != valueAfter ) {\n\t\t\t// if valueBefore == value there is nothing to change, so we add operation only if these values are different.\n\t\t\tif ( valueBefore != value ) {\n\t\t\t\taddOperation();\n\t\t\t}\n\n\t\t\tlastSplitPosition = position;\n\t\t}\n\n\t\tposition = val.nextPosition;\n\t\tvalueBefore = valueAfter;\n\t}\n\n\t// Because position in the loop is not the iterator position (see let position comment), the last position in\n\t// the while loop will be last but one position in the range. We need to check the last position manually.\n\tif ( position instanceof Position && position != lastSplitPosition && valueBefore != value ) {\n\t\taddOperation();\n\t}\n\n\tfunction addOperation() {\n\t\tconst range = new Range( lastSplitPosition, position );\n\t\tconst version = range.root.document ? doc.version : null;\n\t\tconst operation = new AttributeOperation( range, key, valueBefore, value, version );\n\n\t\twriter.batch.addOperation( operation );\n\t\tmodel.applyOperation( operation );\n\t}\n}\n\n/**\n * Sets given attribute to the given node. When attribute value is null then attribute will be removed.\n */\nfunction setAttributeOnItem( writer: Writer, key: string, value: unknown, item: Item ) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\tconst previousValue = item.getAttribute( key );\n\tlet range, operation;\n\n\tif ( previousValue != value ) {\n\t\tconst isRootChanged = item.root === item;\n\n\t\tif ( isRootChanged ) {\n\t\t\t// If we change attributes of root element, we have to use `RootAttributeOperation`.\n\t\t\tconst version = item.document ? doc.version : null;\n\n\t\t\toperation = new RootAttributeOperation( item as any, key, previousValue, value, version );\n\t\t} else {\n\t\t\trange = new Range( Position._createBefore( item ), writer.createPositionAfter( item ) );\n\n\t\t\tconst version = range.root.document ? doc.version : null;\n\n\t\t\toperation = new AttributeOperation( range, key, previousValue, value, version );\n\t\t}\n\n\t\twriter.batch.addOperation( operation );\n\t\tmodel.applyOperation( operation );\n\t}\n}\n\n/**\n * Creates and applies marker operation to {@link module:engine/model/operation/operation~Operation operation}.\n */\nfunction applyMarkerOperation(\n\twriter: Writer,\n\tname: string,\n\toldRange: Range | null,\n\tnewRange: Range | null,\n\taffectsData: boolean | undefined\n) {\n\tconst model = writer.model;\n\tconst doc = model.document;\n\n\tconst operation = new MarkerOperation( name, oldRange, newRange, model.markers, !!affectsData, doc.version );\n\n\twriter.batch.addOperation( operation );\n\tmodel.applyOperation( operation );\n}\n\n/**\n * Creates `MoveOperation` or `DetachOperation` that removes `howMany` nodes starting from `position`.\n * The operation will be applied on given model instance and added to given operation instance.\n *\n * @param position Position from which nodes are removed.\n * @param howMany Number of nodes to remove.\n * @param batch Batch to which the operation will be added.\n * @param model Model instance on which operation will be applied.\n */\nfunction applyRemoveOperation( position: Position, howMany: number, batch: Batch, model: Model ) {\n\tlet operation;\n\n\tif ( position.root.document ) {\n\t\tconst doc = model.document;\n\t\tconst graveyardPosition = new Position( doc.graveyard, [ 0 ] );\n\n\t\toperation = new MoveOperation( position, howMany, graveyardPosition, doc.version );\n\t} else {\n\t\toperation = new DetachOperation( position, howMany );\n\t}\n\n\tbatch.addOperation( operation );\n\tmodel.applyOperation( operation );\n}\n\n/**\n * Returns `true` if both root elements are the same element or both are documents root elements.\n *\n * Elements in the same tree can be moved (for instance you can move element form one documents root to another, or\n * within the same document fragment), but when element supposed to be moved from document fragment to the document, or\n * to another document it should be removed and inserted to avoid problems with OT. This is because features like undo or\n * collaboration may track changes on the document but ignore changes on detached fragments and should not get\n * unexpected `move` operation.\n */\nfunction isSameTree( rootA: Node | DocumentFragment, rootB: Node | DocumentFragment ): boolean {\n\t// If it is the same root this is the same tree.\n\tif ( rootA === rootB ) {\n\t\treturn true;\n\t}\n\n\t// If both roots are documents root it is operation within the document what we still treat as the same tree.\n\tif ( rootA instanceof RootElement && rootB instanceof RootElement ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/utils/deletecontent\n */\n\nimport DocumentSelection from '../documentselection.js';\nimport LivePosition from '../liveposition.js';\nimport Range from '../range.js';\n\nimport type DocumentFragment from '../documentfragment.js';\nimport type Element from '../element.js';\nimport type Model from '../model.js';\nimport type Position from '../position.js';\nimport type Schema from '../schema.js';\nimport type Selection from '../selection.js';\nimport type Writer from '../writer.js';\n\n/**\n * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n *\n * **Note:** Use {@link module:engine/model/model~Model#deleteContent} instead of this function.\n * This function is only exposed to be reusable in algorithms\n * which change the {@link module:engine/model/model~Model#deleteContent}\n * method's behavior.\n *\n * @param model The model in context of which the insertion should be performed.\n * @param selection Selection of which the content should be deleted.\n * @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.\n *\n * For example `<heading>x[x</heading><paragraph>y]y</paragraph>` will become:\n *\n * * `<heading>x^y</heading>` with the option disabled (`leaveUnmerged == false`)\n * * `<heading>x^</heading><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n *\n * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}\n * elements will not be merged.\n *\n * @param options.doNotResetEntireContent Whether to skip replacing the entire content with a\n * paragraph when the entire content was selected.\n *\n * For example `<heading>[x</heading><paragraph>y]</paragraph>` will become:\n *\n * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n * * `<heading>^</heading>` with enabled (`doNotResetEntireContent == true`).\n *\n * @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved\n * to a place where text cannot be inserted.\n *\n * For example `<paragraph>x</paragraph>[<imageBlock src=\"foo.jpg\"></imageBlock>]` will become:\n *\n * * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n * * `<paragraph>x</paragraph>[]` with the option enabled (`doNotAutoparagraph == true`).\n *\n * If you use this option you need to make sure to handle invalid selections yourself or leave\n * them to the selection post-fixer (may not always work).\n *\n * **Note:** If there is no valid position for the selection, the paragraph will always be created:\n *\n * `[<imageBlock src=\"foo.jpg\"></imageBlock>]` -> `<paragraph>[]</paragraph>`.\n */\nexport default function deleteContent(\n\tmodel: Model,\n\tselection: Selection | DocumentSelection,\n\toptions: {\n\t\tleaveUnmerged?: boolean;\n\t\tdoNotResetEntireContent?: boolean;\n\t\tdoNotAutoparagraph?: boolean;\n\t} = {}\n): void {\n\tif ( selection.isCollapsed ) {\n\t\treturn;\n\t}\n\n\tconst selRange = selection.getFirstRange()!;\n\n\t// If the selection is already removed, don't do anything.\n\tif ( selRange.root.rootName == '$graveyard' ) {\n\t\treturn;\n\t}\n\n\tconst schema = model.schema;\n\n\tmodel.change( writer => {\n\t\t// 1. Replace the entire content with paragraph.\n\t\t// See: https://github.com/ckeditor/ckeditor5-engine/issues/1012#issuecomment-315017594.\n\t\tif ( !options.doNotResetEntireContent && shouldEntireContentBeReplacedWithParagraph( schema, selection ) ) {\n\t\t\treplaceEntireContentWithParagraph( writer, selection );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Collect attributes to copy in case of autoparagraphing.\n\t\tconst attributesForAutoparagraph = {};\n\n\t\tif ( !options.doNotAutoparagraph ) {\n\t\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t\tif ( selectedElement ) {\n\t\t\t\tObject.assign( attributesForAutoparagraph, schema.getAttributesWithProperty( selectedElement, 'copyOnReplace', true ) );\n\t\t\t}\n\t\t}\n\n\t\t// Get the live positions for the range adjusted to span only blocks selected from the user perspective.\n\t\tconst [ startPosition, endPosition ] = getLivePositionsForSelectedBlocks( selRange );\n\n\t\t// 2. Remove the content if there is any.\n\t\tif ( !startPosition.isTouching( endPosition ) ) {\n\t\t\twriter.remove( writer.createRange( startPosition, endPosition ) );\n\t\t}\n\n\t\t// 3. Merge elements in the right branch to the elements in the left branch.\n\t\t// The only reasonable (in terms of data and selection correctness) case in which we need to do that is:\n\t\t//\n\t\t// <heading type=1>Fo[</heading><paragraph>]ar</paragraph> => <heading type=1>Fo^ar</heading>\n\t\t//\n\t\t// However, the algorithm supports also merging deeper structures (up to the depth of the shallower branch),\n\t\t// as it's hard to imagine what should actually be the default behavior. Usually, specific features will\n\t\t// want to override that behavior anyway.\n\t\tif ( !options.leaveUnmerged ) {\n\t\t\tmergeBranches( writer, startPosition, endPosition );\n\n\t\t\t// TMP this will be replaced with a postfixer.\n\t\t\t// We need to check and strip disallowed attributes in all nested nodes because after merge\n\t\t\t// some attributes could end up in a path where are disallowed.\n\t\t\t//\n\t\t\t// e.g. bold is disallowed for <H1>\n\t\t\t// <h1>Fo{o</h1><p>b}a<b>r</b><p> -> <h1>Fo{}a<b>r</b><h1> -> <h1>Fo{}ar<h1>.\n\t\t\tschema.removeDisallowedAttributes( startPosition.parent.getChildren(), writer );\n\t\t}\n\n\t\tcollapseSelectionAt( writer, selection, startPosition );\n\n\t\t// 4. Add a paragraph to set selection in it.\n\t\t// Check if a text is allowed in the new container. If not, try to create a new paragraph (if it's allowed here).\n\t\t// If autoparagraphing is off, we assume that you know what you do so we leave the selection wherever it was.\n\t\tif ( !options.doNotAutoparagraph && shouldAutoparagraph( schema, startPosition ) ) {\n\t\t\tinsertParagraph( writer, startPosition, selection, attributesForAutoparagraph );\n\t\t}\n\n\t\tstartPosition.detach();\n\t\tendPosition.detach();\n\t} );\n}\n\n/**\n * Returns the live positions for the range adjusted to span only blocks selected from the user perspective. Example:\n *\n * ```\n * <heading1>[foo</heading1>\n * <paragraph>bar</paragraph>\n * <heading1>]abc</heading1>  <-- this block is not considered as selected\n * ```\n *\n * This is the same behavior as in Selection#getSelectedBlocks() \"special case\".\n */\nfunction getLivePositionsForSelectedBlocks( range: Range ): [ startPosition: LivePosition, endPosition: LivePosition ] {\n\tconst model = range.root.document!.model;\n\n\tconst startPosition = range.start;\n\tlet endPosition = range.end;\n\n\t// If the end of selection is at the start position of last block in the selection, then\n\t// shrink it to not include that trailing block. Note that this should happen only for not empty selection.\n\tif ( model.hasContent( range, { ignoreMarkers: true } ) ) {\n\t\tconst endBlock = getParentBlock( endPosition );\n\n\t\tif ( endBlock && endPosition.isTouching( model.createPositionAt( endBlock, 0 ) ) ) {\n\t\t\t// Create forward selection as a probe to find a valid position after excluding last block from the range.\n\t\t\tconst selection = model.createSelection( range );\n\n\t\t\t// Modify the forward selection in backward direction to shrink it and remove first position of following block from it.\n\t\t\t// This is how modifySelection works and here we are making use of it.\n\t\t\tmodel.modifySelection( selection, { direction: 'backward' } );\n\n\t\t\tconst newEndPosition = selection.getLastPosition()!;\n\n\t\t\t// For such a model and selection:\n\t\t\t//     <paragraph>A[</paragraph><imageBlock></imageBlock><paragraph>]B</paragraph>\n\t\t\t//\n\t\t\t// After modifySelection(), we would end up with this:\n\t\t\t//     <paragraph>A[</paragraph>]<imageBlock></imageBlock><paragraph>B</paragraph>\n\t\t\t//\n\t\t\t// So we need to check if there is no content in the skipped range (because we want to include the <imageBlock>).\n\t\t\tconst skippedRange = model.createRange( newEndPosition, endPosition );\n\n\t\t\tif ( !model.hasContent( skippedRange, { ignoreMarkers: true } ) ) {\n\t\t\t\tendPosition = newEndPosition;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn [\n\t\tLivePosition.fromPosition( startPosition, 'toPrevious' ),\n\t\tLivePosition.fromPosition( endPosition, 'toNext' )\n\t];\n}\n\n/**\n * Finds the lowest element in position's ancestors which is a block.\n * Returns null if a limit element is encountered before reaching a block element.\n */\nfunction getParentBlock( position: Position ): Element | null | undefined {\n\tconst element = position.parent;\n\tconst schema = element.root.document!.model.schema;\n\tconst ancestors = element.getAncestors( { parentFirst: true, includeSelf: true } );\n\n\tfor ( const element of ancestors ) {\n\t\tif ( schema.isLimit( element ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( schema.isBlock( element ) ) {\n\t\t\treturn element as Element;\n\t\t}\n\t}\n}\n\n/**\n * This function is a result of reaching the Ballmer's peak for just the right amount of time.\n * Even I had troubles documenting it after a while and after reading it again I couldn't believe that it really works.\n */\nfunction mergeBranches( writer: Writer, startPosition: Position, endPosition: Position ) {\n\tconst model = writer.model;\n\n\t// Verify if there is a need and possibility to merge.\n\tif ( !checkShouldMerge( writer.model.schema, startPosition, endPosition ) ) {\n\t\treturn;\n\t}\n\n\t// If the start element on the common ancestor level is empty, and the end element on the same level is not empty\n\t// then merge those to the right element so that it's properties are preserved (name, attributes).\n\t// Because of OT merging is used instead of removing elements.\n\t//\n\t// Merge left:\n\t//     <heading1>foo[</heading1>    ->  <heading1>foo[]bar</heading1>\n\t//     <paragraph>]bar</paragraph>  ->               --^\n\t//\n\t// Merge right:\n\t//     <heading1>[</heading1>       ->\n\t//     <paragraph>]bar</paragraph>  ->  <paragraph>[]bar</paragraph>\n\t//\n\t// Merge left:\n\t//     <blockQuote>                     ->  <blockQuote>\n\t//         <heading1>foo[</heading1>    ->      <heading1>foo[]bar</heading1>\n\t//         <paragraph>]bar</paragraph>  ->                   --^\n\t//     </blockQuote>                    ->  </blockQuote>\n\t//\n\t// Merge right:\n\t//     <blockQuote>                     ->  <blockQuote>\n\t//         <heading1>[</heading1>       ->\n\t//         <paragraph>]bar</paragraph>  ->      <paragraph>[]bar</paragraph>\n\t//     </blockQuote>                    ->  </blockQuote>\n\n\t// Merging should not go deeper than common ancestor.\n\tconst [ startAncestor, endAncestor ] = getAncestorsJustBelowCommonAncestor( startPosition, endPosition );\n\n\t// Branches can't be merged if one of the positions is directly inside a common ancestor.\n\t//\n\t// Example:\n\t//     <blockQuote>\n\t//         <paragraph>[foo</paragraph>]\n\t//         <table> ... </table>\n\t//     <blockQuote>\n\t//\n\tif ( !startAncestor || !endAncestor ) {\n\t\treturn;\n\t}\n\n\tif ( !model.hasContent( startAncestor, { ignoreMarkers: true } ) && model.hasContent( endAncestor, { ignoreMarkers: true } ) ) {\n\t\tmergeBranchesRight( writer, startPosition, endPosition, startAncestor.parent );\n\t} else {\n\t\tmergeBranchesLeft( writer, startPosition, endPosition, startAncestor.parent );\n\t}\n}\n\n/**\n * Merging blocks to the left (properties of the left block are preserved).\n * Simple example:\n *\n * ```\n * <heading1>foo[</heading1>    ->  <heading1>foo[bar</heading1>]\n * <paragraph>]bar</paragraph>  ->              --^\n * ```\n *\n * Nested example:\n *\n * ```\n * <blockQuote>                     ->  <blockQuote>\n *     <heading1>foo[</heading1>    ->      <heading1>foo[bar</heading1>\n * </blockQuote>                    ->  </blockQuote>]    ^\n * <blockBlock>                     ->                    |\n *     <paragraph>]bar</paragraph>  ->                 ---\n * </blockBlock>                    ->\n * ```\n */\nfunction mergeBranchesLeft(\n\twriter: Writer,\n\tstartPosition: Position,\n\tendPosition: Position,\n\tcommonAncestor: Element | DocumentFragment | null\n) {\n\tconst startElement = startPosition.parent as Element;\n\tconst endElement = endPosition.parent as Element;\n\n\t// Merging reached the common ancestor element, stop here.\n\tif ( startElement == commonAncestor || endElement == commonAncestor ) {\n\t\treturn;\n\t}\n\n\t// Remember next positions to merge in next recursive step (also used as modification points pointers).\n\tstartPosition = writer.createPositionAfter( startElement );\n\tendPosition = writer.createPositionBefore( endElement );\n\n\t// Move endElement just after startElement if they aren't siblings.\n\tif ( !endPosition.isEqual( startPosition ) ) {\n\t\t//\n\t\t//     <blockQuote>                     ->  <blockQuote>\n\t\t//         <heading1>foo[</heading1>    ->      <heading1>foo</heading1>[<paragraph>bar</paragraph>\n\t\t//     </blockQuote>                    ->  </blockQuote>                ^\n\t\t//     <blockBlock>                     ->  <blockBlock>                 |\n\t\t//         <paragraph>]bar</paragraph>  ->      ]                     ---\n\t\t//     </blockBlock>                    ->  </blockBlock>\n\t\t//\n\t\twriter.insert( endElement, startPosition );\n\t}\n\n\t// Merge two siblings (nodes on sides of startPosition):\n\t//\n\t//     <blockQuote>                                             ->  <blockQuote>\n\t//         <heading1>foo</heading1>[<paragraph>bar</paragraph>  ->      <heading1>foo[bar</heading1>\n\t//     </blockQuote>                                            ->  </blockQuote>\n\t//     <blockBlock>                                             ->  <blockBlock>\n\t//         ]                                                    ->      ]\n\t//     </blockBlock>                                            ->  </blockBlock>\n\t//\n\t// Or in simple case (without moving elements in above if):\n\t//     <heading1>foo</heading1>[<paragraph>bar</paragraph>]  ->  <heading1>foo[bar</heading1>]\n\t//\n\twriter.merge( startPosition );\n\n\t// Remove empty end ancestors:\n\t//\n\t//     <blockQuote>                      ->  <blockQuote>\n\t//         <heading1>foo[bar</heading1>  ->      <heading1>foo[bar</heading1>\n\t//     </blockQuote>                     ->  </blockQuote>\n\t//     <blockBlock>                      ->\n\t//         ]                             ->  ]\n\t//     </blockBlock>                     ->\n\t//\n\twhile ( endPosition.parent.isEmpty ) {\n\t\tconst parentToRemove = endPosition.parent as Element;\n\n\t\tendPosition = writer.createPositionBefore( parentToRemove );\n\n\t\twriter.remove( parentToRemove );\n\t}\n\n\t// Verify if there is a need and possibility to merge next level.\n\tif ( !checkShouldMerge( writer.model.schema, startPosition, endPosition ) ) {\n\t\treturn;\n\t}\n\n\t// Continue merging next level (blockQuote with blockBlock in the examples above if it would not be empty and got removed).\n\tmergeBranchesLeft( writer, startPosition, endPosition, commonAncestor );\n}\n\n/**\n * Merging blocks to the right (properties of the right block are preserved).\n * Simple example:\n *\n * ```\n * <heading1>foo[</heading1>    ->            --v\n * <paragraph>]bar</paragraph>  ->  [<paragraph>foo]bar</paragraph>\n * ```\n *\n * Nested example:\n *\n * ```\n * <blockQuote>                     ->\n *     <heading1>foo[</heading1>    ->              ---\n * </blockQuote>                    ->                 |\n * <blockBlock>                     ->  [<blockBlock>  v\n *     <paragraph>]bar</paragraph>  ->      <paragraph>foo]bar</paragraph>\n * </blockBlock>                    ->  </blockBlock>\n * ```\n */\nfunction mergeBranchesRight(\n\twriter: Writer,\n\tstartPosition: Position,\n\tendPosition: Position,\n\tcommonAncestor: Element | DocumentFragment | null\n) {\n\tconst startElement = startPosition.parent as Element;\n\tconst endElement = endPosition.parent as Element;\n\n\t// Merging reached the common ancestor element, stop here.\n\tif ( startElement == commonAncestor || endElement == commonAncestor ) {\n\t\treturn;\n\t}\n\n\t// Remember next positions to merge in next recursive step (also used as modification points pointers).\n\tstartPosition = writer.createPositionAfter( startElement );\n\tendPosition = writer.createPositionBefore( endElement );\n\n\t// Move startElement just before endElement if they aren't siblings.\n\tif ( !endPosition.isEqual( startPosition ) ) {\n\t\t//\n\t\t//     <blockQuote>                     ->  <blockQuote>\n\t\t//         <heading1>foo[</heading1>    ->      [                   ---\n\t\t//     </blockQuote>                    ->  </blockQuote>              |\n\t\t//     <blockBlock>                     ->  <blockBlock>               v\n\t\t//         <paragraph>]bar</paragraph>  ->      <heading1>foo</heading1>]<paragraph>bar</paragraph>\n\t\t//     </blockBlock>                    ->  </blockBlock>\n\t\t//\n\t\twriter.insert( startElement, endPosition );\n\t}\n\n\t// Remove empty end ancestors:\n\t//\n\t//     <blockQuote>                                             ->\n\t//         [                                                    ->  [\n\t//     </blockQuote>                                            ->\n\t//     <blockBlock>                                             ->  <blockBlock>\n\t//         <heading1>foo</heading1>]<paragraph>bar</paragraph>  ->      <heading1>foo</heading1>]<paragraph>bar</paragraph>\n\t//     </blockBlock>                                            ->  </blockBlock>\n\t//\n\twhile ( startPosition.parent.isEmpty ) {\n\t\tconst parentToRemove = startPosition.parent as Element;\n\n\t\tstartPosition = writer.createPositionBefore( parentToRemove );\n\n\t\twriter.remove( parentToRemove );\n\t}\n\n\t// Update endPosition after inserting and removing elements.\n\tendPosition = writer.createPositionBefore( endElement );\n\n\t// Merge right two siblings (nodes on sides of endPosition):\n\t//                                                              ->\n\t//     [                                                        ->  [\n\t//                                                              ->\n\t//     <blockBlock>                                             ->  <blockBlock>\n\t//         <heading1>foo</heading1>]<paragraph>bar</paragraph>  ->      <paragraph>foo]bar</paragraph>\n\t//     </blockBlock>                                            ->  </blockBlock>\n\t//\n\t// Or in simple case (without moving elements in above if):\n\t//     [<heading1>foo</heading1>]<paragraph>bar</paragraph>  ->  [<heading1>foo]bar</heading1>\n\t//\n\tmergeRight( writer, endPosition );\n\n\t// Verify if there is a need and possibility to merge next level.\n\tif ( !checkShouldMerge( writer.model.schema, startPosition, endPosition ) ) {\n\t\treturn;\n\t}\n\n\t// Continue merging next level (blockQuote with blockBlock in the examples above if it would not be empty and got removed).\n\tmergeBranchesRight( writer, startPosition, endPosition, commonAncestor );\n}\n\n/**\n * There is no right merge operation so we need to simulate it.\n */\nfunction mergeRight( writer: Writer, position: Position ) {\n\tconst startElement: any = position.nodeBefore;\n\tconst endElement: any = position.nodeAfter;\n\n\tif ( startElement.name != endElement.name ) {\n\t\twriter.rename( startElement, endElement.name );\n\t}\n\n\twriter.clearAttributes( startElement );\n\twriter.setAttributes( Object.fromEntries( endElement.getAttributes() ), startElement );\n\n\twriter.merge( position );\n}\n\n/**\n * Verifies if merging is needed and possible. It's not needed if both positions are in the same element\n * and it's not possible if some element is a limit or the range crosses a limit element.\n */\nfunction checkShouldMerge( schema: Schema, startPosition: Position, endPosition: Position ): boolean {\n\tconst startElement = startPosition.parent;\n\tconst endElement = endPosition.parent;\n\n\t// If both positions ended up in the same parent, then there's nothing more to merge:\n\t// <$root><p>x[</p><p>]y</p></$root> => <$root><p>xy</p>[]</$root>\n\tif ( startElement == endElement ) {\n\t\treturn false;\n\t}\n\n\t// If one of the positions is a limit element, then there's nothing to merge because we don't want to cross the limit boundaries.\n\tif ( schema.isLimit( startElement ) || schema.isLimit( endElement ) ) {\n\t\treturn false;\n\t}\n\n\t// Check if operations we'll need to do won't need to cross object or limit boundaries.\n\t// E.g., we can't merge endElement into startElement in this case:\n\t// <limit><startElement>x[</startElement></limit><endElement>]</endElement>\n\treturn isCrossingLimitElement( startPosition, endPosition, schema );\n}\n\n/**\n * Returns the elements that are the ancestors of the provided positions that are direct children of the common ancestor.\n */\nfunction getAncestorsJustBelowCommonAncestor( positionA: Position, positionB: Position ) {\n\tconst ancestorsA = positionA.getAncestors();\n\tconst ancestorsB = positionB.getAncestors();\n\n\tlet i = 0;\n\n\twhile ( ancestorsA[ i ] && ancestorsA[ i ] == ancestorsB[ i ] ) {\n\t\ti++;\n\t}\n\n\treturn [ ancestorsA[ i ], ancestorsB[ i ] ];\n}\n\nfunction shouldAutoparagraph( schema: Schema, position: Position ) {\n\tconst isTextAllowed = schema.checkChild( position, '$text' );\n\tconst isParagraphAllowed = schema.checkChild( position, 'paragraph' );\n\n\treturn !isTextAllowed && isParagraphAllowed;\n}\n\n/**\n * Check if parents of two positions can be merged by checking if there are no limit/object\n * boundaries between those two positions.\n *\n * E.g. in <bQ><p>x[]</p></bQ><widget><caption>{}</caption></widget>\n * we'll check <p>, <bQ>, <widget> and <caption>.\n * Usually, widget and caption are marked as objects/limits in the schema, so in this case merging will be blocked.\n */\nfunction isCrossingLimitElement( leftPos: Position, rightPos: Position, schema: Schema ) {\n\tconst rangeToCheck = new Range( leftPos, rightPos );\n\n\tfor ( const value of rangeToCheck.getWalker() ) {\n\t\tif ( schema.isLimit( value.item ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction insertParagraph(\n\twriter: Writer,\n\tposition: Position,\n\tselection: Selection | DocumentSelection,\n\tattributes = {}\n) {\n\tconst paragraph = writer.createElement( 'paragraph' );\n\n\twriter.model.schema.setAllowedAttributes( paragraph, attributes, writer );\n\n\twriter.insert( paragraph, position );\n\n\tcollapseSelectionAt( writer, selection, writer.createPositionAt( paragraph, 0 ) );\n}\n\nfunction replaceEntireContentWithParagraph( writer: Writer, selection: Selection | DocumentSelection ) {\n\tconst limitElement = writer.model.schema.getLimitElement( selection );\n\n\twriter.remove( writer.createRangeIn( limitElement ) );\n\tinsertParagraph( writer, writer.createPositionAt( limitElement, 0 ), selection );\n}\n\n/**\n * We want to replace the entire content with a paragraph when:\n * * the entire content is selected,\n * * selection contains at least two elements,\n * * whether the paragraph is allowed in schema in the common ancestor.\n */\nfunction shouldEntireContentBeReplacedWithParagraph( schema: Schema, selection: Selection | DocumentSelection ) {\n\tconst limitElement = schema.getLimitElement( selection );\n\n\tif ( !selection.containsEntireContent( limitElement ) ) {\n\t\treturn false;\n\t}\n\n\tconst range = selection.getFirstRange()!;\n\n\tif ( range.start.parent == range.end.parent ) {\n\t\treturn false;\n\t}\n\n\treturn schema.checkChild( limitElement, 'paragraph' );\n}\n\n/**\n * Helper function that sets the selection. Depending whether given `selection` is a document selection or not,\n * uses a different method to set it.\n */\nfunction collapseSelectionAt(\n\twriter: Writer,\n\tselection: Selection | DocumentSelection,\n\tpositionOrRange: Position | Range\n) {\n\tif ( selection instanceof DocumentSelection ) {\n\t\twriter.setSelection( positionOrRange );\n\t} else {\n\t\tselection.setTo( positionOrRange );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type DocumentFragment from '../documentfragment.js';\nimport type DocumentSelection from '../documentselection.js';\nimport type Element from '../element.js';\nimport type Model from '../model.js';\nimport type Range from '../range.js';\nimport type Selection from '../selection.js';\nimport type Writer from '../writer.js';\n\n/**\n * @module engine/model/utils/getselectedcontent\n */\n\n/**\n * Gets a clone of the selected content.\n *\n * For example, for the following selection:\n *\n * ```html\n * <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n * ```\n *\n * It will return a document fragment with such a content:\n *\n * ```html\n * <quote><h>st</h></quote><p>se</p>\n * ```\n *\n * @param model The model in context of which the selection modification should be performed.\n * @param selection The selection of which content will be returned.\n */\nexport default function getSelectedContent(\n\tmodel: Model,\n\tselection: Selection | DocumentSelection\n): DocumentFragment {\n\treturn model.change( writer => {\n\t\tconst frag = writer.createDocumentFragment();\n\t\tconst range = selection.getFirstRange();\n\n\t\tif ( !range || range.isCollapsed ) {\n\t\t\treturn frag;\n\t\t}\n\n\t\tconst root = range.start.root;\n\t\tconst commonPath = range.start.getCommonPath( range.end );\n\t\tconst commonParent = root.getNodeByPath( commonPath );\n\n\t\t// ## 1st step\n\t\t//\n\t\t// First, we'll clone a fragment represented by a minimal flat range\n\t\t// containing the original range to be cloned.\n\t\t// E.g. let's consider such a range:\n\t\t//\n\t\t// <p>x</p><quote><p>y</p><h>fir[st</h></quote><p>se]cond</p><p>z</p>\n\t\t//\n\t\t// A minimal flat range containing this one is:\n\t\t//\n\t\t// <p>x</p>[<quote><p>y</p><h>first</h></quote><p>second</p>]<p>z</p>\n\t\t//\n\t\t// We can easily clone this structure, preserving e.g. the <quote> element.\n\t\tlet flatSubtreeRange: Range;\n\n\t\tif ( range.start.parent == range.end.parent ) {\n\t\t\t// The original range is flat, so take it.\n\t\t\tflatSubtreeRange = range;\n\t\t} else {\n\t\t\tflatSubtreeRange = writer.createRange(\n\t\t\t\twriter.createPositionAt( commonParent, range.start.path[ commonPath.length ] ),\n\t\t\t\twriter.createPositionAt( commonParent, range.end.path[ commonPath.length ] + 1 )\n\t\t\t);\n\t\t}\n\n\t\tconst howMany = flatSubtreeRange.end.offset - flatSubtreeRange.start.offset;\n\n\t\t// Clone the whole contents.\n\t\tfor ( const item of flatSubtreeRange.getItems( { shallow: true } ) ) {\n\t\t\tif ( item.is( '$textProxy' ) ) {\n\t\t\t\twriter.appendText( item.data, item.getAttributes(), frag );\n\t\t\t} else {\n\t\t\t\twriter.append( writer.cloneElement( item as Element, true ), frag );\n\t\t\t}\n\t\t}\n\n\t\t// ## 2nd step\n\t\t//\n\t\t// If the original range wasn't flat, then we need to remove the excess nodes from the both ends of the cloned fragment.\n\t\t//\n\t\t// For example, for the range shown in the 1st step comment, we need to remove these pieces:\n\t\t//\n\t\t// <quote>[<p>y</p>]<h>[fir]st</h></quote><p>se[cond]</p>\n\t\t//\n\t\t// So this will be the final copied content:\n\t\t//\n\t\t// <quote><h>st</h></quote><p>se</p>\n\t\t//\n\t\t// In order to do that, we remove content from these two ranges:\n\t\t//\n\t\t// [<quote><p>y</p><h>fir]st</h></quote><p>se[cond</p>]\n\t\tif ( flatSubtreeRange != range ) {\n\t\t\t// Find the position of the original range in the cloned fragment.\n\t\t\tconst newRange = range._getTransformedByMove( flatSubtreeRange.start, writer.createPositionAt( frag, 0 ), howMany )[ 0 ];\n\n\t\t\tconst leftExcessRange = writer.createRange( writer.createPositionAt( frag, 0 ), newRange.start );\n\t\t\tconst rightExcessRange = writer.createRange( newRange.end, writer.createPositionAt( frag, 'end' ) );\n\n\t\t\tremoveRangeContent( rightExcessRange, writer );\n\t\t\tremoveRangeContent( leftExcessRange, writer );\n\t\t}\n\n\t\treturn frag;\n\t} );\n}\n\n// After https://github.com/ckeditor/ckeditor5-engine/issues/690 is fixed,\n// this function will, most likely, be able to rewritten using getMinimalFlatRanges().\nfunction removeRangeContent( range: Range, writer: Writer ) {\n\tconst parentsToCheck: Array<Element | DocumentFragment> = [];\n\n\tArray.from( range.getItems( { direction: 'backward' } ) )\n\t\t// We should better store ranges because text proxies will lose integrity\n\t\t// with the text nodes when we'll start removing content.\n\t\t.map( item => writer.createRangeOn( item ) )\n\t\t// Filter only these items which are fully contained in the passed range.\n\t\t//\n\t\t// E.g. for the following range: [<quote><p>y</p><h>fir]st</h>\n\t\t// the walker will return the entire <h> element, when only the \"fir\" item inside it is fully contained.\n\t\t.filter( itemRange => {\n\t\t\t// We should be able to use Range.containsRange, but https://github.com/ckeditor/ckeditor5-engine/issues/691.\n\t\t\tconst contained =\n\t\t\t\t( itemRange.start.isAfter( range.start ) || itemRange.start.isEqual( range.start ) ) &&\n\t\t\t\t( itemRange.end.isBefore( range.end ) || itemRange.end.isEqual( range.end ) );\n\n\t\t\treturn contained;\n\t\t} )\n\t\t.forEach( itemRange => {\n\t\t\tparentsToCheck.push( itemRange.start.parent );\n\n\t\t\twriter.remove( itemRange );\n\t\t} );\n\n\t// Remove ancestors of the removed items if they turned to be empty now\n\t// (their whole content was contained in the range).\n\tparentsToCheck.forEach( parentToCheck => {\n\t\tlet parent = parentToCheck;\n\n\t\twhile ( parent.parent && parent.isEmpty ) {\n\t\t\tconst removeRange = writer.createRangeOn( parent );\n\n\t\t\tparent = parent.parent;\n\n\t\t\twriter.remove( removeRange );\n\t\t}\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/utils/insertcontent\n */\n\nimport DocumentSelection from '../documentselection.js';\nimport Element from '../element.js';\nimport LivePosition from '../liveposition.js';\nimport LiveRange from '../liverange.js';\nimport Position from '../position.js';\nimport Range from '../range.js';\n\nimport type DocumentFragment from '../documentfragment.js';\nimport type Item from '../item.js';\nimport type Model from '../model.js';\nimport type Schema from '../schema.js';\nimport type Writer from '../writer.js';\nimport type Node from '../node.js';\nimport type Selection from '../selection.js';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Inserts content into the editor (specified selection) as one would expect the paste functionality to work.\n *\n * It takes care of removing the selected content, splitting elements (if needed), inserting elements and merging elements appropriately.\n *\n * Some examples:\n *\n * ```html\n * <p>x^</p> + <p>y</p> => <p>x</p><p>y</p> => <p>xy[]</p>\n * <p>x^y</p> + <p>z</p> => <p>x</p>^<p>y</p> + <p>z</p> => <p>x</p><p>z</p><p>y</p> => <p>xz[]y</p>\n * <p>x^y</p> + <img /> => <p>x</p>^<p>y</p> + <img /> => <p>x</p><img /><p>y</p>\n * <p>x</p><p>^</p><p>z</p> + <p>y</p> => <p>x</p><p>y[]</p><p>z</p> (no merging)\n * <p>x</p>[<img />]<p>z</p> + <p>y</p> => <p>x</p>^<p>z</p> + <p>y</p> => <p>x</p><p>y[]</p><p>z</p>\n * ```\n *\n * If an instance of {@link module:engine/model/selection~Selection} is passed as `selectable` it will be modified\n * to the insertion selection (equal to a range to be selected after insertion).\n *\n * If `selectable` is not passed, the content will be inserted using the current selection of the model document.\n *\n * **Note:** Use {@link module:engine/model/model~Model#insertContent} instead of this function.\n * This function is only exposed to be reusable in algorithms which change the {@link module:engine/model/model~Model#insertContent}\n * method's behavior.\n *\n * @param model The model in context of which the insertion should be performed.\n * @param content The content to insert.\n * @param selectable Selection into which the content should be inserted.\n * @param placeOrOffset Sets place or offset of the selection.\n * @returns Range which contains all the performed changes. This is a range that, if removed,\n * would return the model to the state before the insertion. If no changes were preformed by `insertContent`, returns a range collapsed\n * at the insertion position.\n */\nexport default function insertContent(\n\tmodel: Model,\n\tcontent: Item | DocumentFragment,\n\tselectable?: Selection | DocumentSelection\n): Range {\n\treturn model.change( writer => {\n\t\tconst selection: Selection | DocumentSelection = selectable ? selectable : model.document.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\tmodel.deleteContent( selection, { doNotAutoparagraph: true } );\n\t\t}\n\n\t\tconst insertion = new Insertion( model, writer, selection.anchor! );\n\t\tconst fakeMarkerElements = [];\n\n\t\tlet nodesToInsert: any;\n\n\t\tif ( content.is( 'documentFragment' ) ) {\n\t\t\t// If document fragment has any markers, these markers should be inserted into the model as well.\n\t\t\tif ( content.markers.size ) {\n\t\t\t\tconst markersPosition = [];\n\n\t\t\t\tfor ( const [ name, range ] of content.markers ) {\n\t\t\t\t\tconst { start, end } = range;\n\t\t\t\t\tconst isCollapsed = start.isEqual( end );\n\n\t\t\t\t\tmarkersPosition.push(\n\t\t\t\t\t\t{ position: start, name, isCollapsed },\n\t\t\t\t\t\t{ position: end, name, isCollapsed }\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Markers position is sorted backwards to ensure that the insertion of fake markers will not change\n\t\t\t\t// the position of the next markers.\n\t\t\t\tmarkersPosition.sort( ( { position: posA }, { position: posB } ) => posA.isBefore( posB ) ? 1 : -1 );\n\n\t\t\t\tfor ( const { position, name, isCollapsed } of markersPosition ) {\n\t\t\t\t\tlet fakeElement = null;\n\t\t\t\t\tlet collapsed = null;\n\t\t\t\t\tconst isAtBeginning = position.parent === content && position.isAtStart;\n\t\t\t\t\tconst isAtEnd = position.parent === content && position.isAtEnd;\n\n\t\t\t\t\t// We have two ways of handling markers. In general, we want to add temporary <$marker> model elements to\n\t\t\t\t\t// represent marker boundaries. These elements will be inserted into content together with the rest\n\t\t\t\t\t// of the document fragment. After insertion is done, positions for these elements will be read\n\t\t\t\t\t// and proper, actual markers will be created in the model and fake elements will be removed.\n\t\t\t\t\t//\n\t\t\t\t\t// However, if the <$marker> element is at the beginning or at the end of the document fragment,\n\t\t\t\t\t// it may affect how the inserted content is merged with current model, impacting the insertion\n\t\t\t\t\t// result. To avoid that, we don't add <$marker> elements at these positions. Instead, we will use\n\t\t\t\t\t// `Insertion#getAffectedRange()` to figure out new positions for these marker boundaries.\n\t\t\t\t\tif ( !isAtBeginning && !isAtEnd ) {\n\t\t\t\t\t\tfakeElement = writer.createElement( '$marker' );\n\t\t\t\t\t\twriter.insert( fakeElement, position );\n\t\t\t\t\t} else if ( isCollapsed ) {\n\t\t\t\t\t\t// Save whether the collapsed marker was at the beginning or at the end of document fragment\n\t\t\t\t\t\t// to know where to create it after the insertion is done.\n\t\t\t\t\t\tcollapsed = isAtBeginning ? 'start' as const : 'end' as const;\n\t\t\t\t\t}\n\n\t\t\t\t\tfakeMarkerElements.push( {\n\t\t\t\t\t\tname,\n\t\t\t\t\t\telement: fakeElement,\n\t\t\t\t\t\tcollapsed\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnodesToInsert = content.getChildren();\n\t\t} else {\n\t\t\tnodesToInsert = [ content ];\n\t\t}\n\n\t\tinsertion.handleNodes( nodesToInsert );\n\n\t\tlet newRange = insertion.getSelectionRange();\n\n\t\tif ( content.is( 'documentFragment' ) && fakeMarkerElements.length ) {\n\t\t\t// After insertion was done, the selection was set but the model contains fake <$marker> elements.\n\t\t\t// These <$marker> elements will be now removed. Because of that, we will need to fix the selection.\n\t\t\t// We will create a live range that will automatically be update as <$marker> elements are removed.\n\t\t\tconst selectionLiveRange = newRange ? LiveRange.fromRange( newRange ) : null;\n\n\t\t\t// Marker name -> [ start position, end position ].\n\t\t\tconst markersData: Record<string, Array<Position>> = {};\n\n\t\t\t// Note: `fakeMarkerElements` are sorted backwards. However, now, we want to handle the markers\n\t\t\t// from the beginning, so that existing <$marker> elements do not affect markers positions.\n\t\t\t// This is why we iterate from the end to the start.\n\t\t\tfor ( let i = fakeMarkerElements.length - 1; i >= 0; i-- ) {\n\t\t\t\tconst { name, element, collapsed } = fakeMarkerElements[ i ];\n\t\t\t\tconst isStartBoundary = !markersData[ name ];\n\n\t\t\t\tif ( isStartBoundary ) {\n\t\t\t\t\tmarkersData[ name ] = [];\n\t\t\t\t}\n\n\t\t\t\tif ( element ) {\n\t\t\t\t\t// Read fake marker element position to learn where the marker should be created.\n\t\t\t\t\tconst elementPosition = writer.createPositionAt( element, 'before' );\n\n\t\t\t\t\tmarkersData[ name ].push( elementPosition );\n\n\t\t\t\t\twriter.remove( element );\n\t\t\t\t} else {\n\t\t\t\t\t// If the fake marker element does not exist, it means that the marker boundary was at the beginning or at the end.\n\t\t\t\t\tconst rangeOnInsertion = insertion.getAffectedRange();\n\n\t\t\t\t\tif ( !rangeOnInsertion ) {\n\t\t\t\t\t\t// If affected range is `null` it means that nothing was in the document fragment or all content was filtered out.\n\t\t\t\t\t\t// Some markers that were in the filtered content may be removed (partially or totally).\n\t\t\t\t\t\t// Let's handle only those markers that were at the beginning or at the end of the document fragment.\n\t\t\t\t\t\tif ( collapsed ) {\n\t\t\t\t\t\t\tmarkersData[ name ].push( insertion.position );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( collapsed ) {\n\t\t\t\t\t\t// If the marker was collapsed at the beginning or at the end of the document fragment,\n\t\t\t\t\t\t// put both boundaries at the beginning or at the end of inserted range (to keep the marker collapsed).\n\t\t\t\t\t\tmarkersData[ name ].push( rangeOnInsertion[ collapsed ] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmarkersData[ name ].push( isStartBoundary ? rangeOnInsertion.start : rangeOnInsertion.end );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( const [ name, [ start, end ] ] of Object.entries( markersData ) ) {\n\t\t\t\t// For now, we ignore markers if they are included in the filtered-out content.\n\t\t\t\t// In the future implementation we will improve that case to create markers that are not filtered out completely.\n\t\t\t\tif ( start && end && start.root === end.root && start.root.document && !writer.model.markers.has( name ) ) {\n\t\t\t\t\twriter.addMarker( name, {\n\t\t\t\t\t\tusingOperation: true,\n\t\t\t\t\t\taffectsData: true,\n\t\t\t\t\t\trange: new Range( start, end )\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( selectionLiveRange ) {\n\t\t\t\tnewRange = selectionLiveRange.toRange();\n\t\t\t\tselectionLiveRange.detach();\n\t\t\t}\n\t\t}\n\n\t\t/* istanbul ignore else -- @preserve */\n\t\tif ( newRange ) {\n\t\t\tif ( selection instanceof DocumentSelection ) {\n\t\t\t\twriter.setSelection( newRange );\n\t\t\t} else {\n\t\t\t\tselection.setTo( newRange );\n\t\t\t}\n\t\t} else {\n\t\t\t// We are not testing else because it's a safe check for unpredictable edge cases:\n\t\t\t// an insertion without proper range to select.\n\t\t\t//\n\t\t\t// @if CK_DEBUG // console.warn( 'Cannot determine a proper selection range after insertion.' );\n\t\t}\n\n\t\tconst affectedRange = insertion.getAffectedRange() || model.createRange( selection.anchor! );\n\n\t\tinsertion.destroy();\n\n\t\treturn affectedRange;\n\t} );\n}\n\n/**\n * Utility class for performing content insertion.\n */\nclass Insertion {\n\t/**\n\t * The model in context of which the insertion should be performed.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * Batch to which operations will be added.\n\t */\n\tpublic readonly writer: Writer;\n\n\t/**\n\t * The position at which (or near which) the next node will be inserted.\n\t */\n\tpublic position: Position;\n\n\t/**\n\t * Elements with which the inserted elements can be merged.\n\t *\n\t * ```html\n\t * <p>x^</p><p>y</p> + <p>z</p> (can merge to <p>x</p>)\n\t * <p>x</p><p>^y</p> + <p>z</p> (can merge to <p>y</p>)\n\t * <p>x^y</p> + <p>z</p> (can merge to <p>xy</p> which will be split during the action,\n\t * \t\t\t\t\t\tso both its pieces will be added to this set)\n\t * ```\n\t */\n\tpublic readonly canMergeWith: Set<Node | DocumentFragment | null>;\n\n\t/**\n\t * Schema of the model.\n\t */\n\tpublic readonly schema: Schema;\n\n\t/**\n\t * The temporary DocumentFragment used for grouping multiple nodes for single insert operation.\n\t */\n\tprivate readonly _documentFragment: DocumentFragment;\n\n\t/**\n\t * The current position in the temporary DocumentFragment.\n\t */\n\tprivate _documentFragmentPosition: Position;\n\n\t/**\n\t * The reference to the first inserted node.\n\t */\n\tprivate _firstNode: Node | null = null;\n\n\t/**\n\t * The reference to the last inserted node.\n\t */\n\tprivate _lastNode: Node | null = null;\n\n\t/**\n\t * The reference to the last auto paragraph node.\n\t */\n\tprivate _lastAutoParagraph: Element | null = null;\n\n\t/**\n\t * The array of nodes that should be cleaned of not allowed attributes.\n\t */\n\tprivate _filterAttributesOf: Array<Node> = [];\n\n\t/**\n\t * Beginning of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t */\n\tprivate _affectedStart: LivePosition | null = null;\n\n\t/**\n\t * End of the affected range. See {@link module:engine/model/utils/insertcontent~Insertion#getAffectedRange}.\n\t */\n\tprivate _affectedEnd: LivePosition | null = null;\n\n\tprivate _nodeToSelect: Node | null = null;\n\n\tconstructor( model: Model, writer: Writer, position: Position ) {\n\t\tthis.model = model;\n\t\tthis.writer = writer;\n\t\tthis.position = position;\n\t\tthis.canMergeWith = new Set( [ this.position.parent ] );\n\t\tthis.schema = model.schema;\n\n\t\tthis._documentFragment = writer.createDocumentFragment();\n\t\tthis._documentFragmentPosition = writer.createPositionAt( this._documentFragment, 0 );\n\t}\n\n\t/**\n\t * Handles insertion of a set of nodes.\n\t *\n\t * @param nodes Nodes to insert.\n\t */\n\tpublic handleNodes( nodes: Iterable<Node> ): void {\n\t\tfor ( const node of Array.from( nodes ) ) {\n\t\t\tthis._handleNode( node );\n\t\t}\n\n\t\t// Insert nodes collected in temporary DocumentFragment.\n\t\tthis._insertPartialFragment();\n\n\t\t// If there was an auto paragraph then we might need to adjust the end of insertion.\n\t\tif ( this._lastAutoParagraph ) {\n\t\t\tthis._updateLastNodeFromAutoParagraph( this._lastAutoParagraph );\n\t\t}\n\n\t\t// After the content was inserted we may try to merge it with its next sibling if the selection was in it initially.\n\t\t// Merging with the previous sibling was performed just after inserting the first node to the document.\n\t\tthis._mergeOnRight();\n\n\t\t// TMP this will become a post-fixer.\n\t\tthis.schema.removeDisallowedAttributes( this._filterAttributesOf, this.writer );\n\t\tthis._filterAttributesOf = [];\n\t}\n\n\t/**\n\t * Updates the last node after the auto paragraphing.\n\t *\n\t * @param node The last auto paragraphing node.\n\t */\n\tprivate _updateLastNodeFromAutoParagraph( node: Node ): void {\n\t\tconst positionAfterLastNode = this.writer.createPositionAfter( this._lastNode! );\n\t\tconst positionAfterNode = this.writer.createPositionAfter( node );\n\n\t\t// If the real end was after the last auto paragraph then update relevant properties.\n\t\tif ( positionAfterNode.isAfter( positionAfterLastNode ) ) {\n\t\t\tthis._lastNode = node;\n\n\t\t\t/* istanbul ignore if -- @preserve */\n\t\t\tif ( this.position.parent != node || !this.position.isAtEnd ) {\n\t\t\t\t// Algorithm's correctness check. We should never end up here but it's good to know that we did.\n\t\t\t\t// At this point the insertion position should be at the end of the last auto paragraph.\n\t\t\t\t// Note: This error is documented in other place in this file.\n\t\t\t\tthrow new CKEditorError( 'insertcontent-invalid-insertion-position', this );\n\t\t\t}\n\n\t\t\tthis.position = positionAfterNode;\n\t\t\tthis._setAffectedBoundaries( this.position );\n\t\t}\n\t}\n\n\t/**\n\t * Returns range to be selected after insertion.\n\t * Returns `null` if there is no valid range to select after insertion.\n\t */\n\tpublic getSelectionRange(): Range | null {\n\t\tif ( this._nodeToSelect ) {\n\t\t\treturn Range._createOn( this._nodeToSelect );\n\t\t}\n\n\t\treturn this.model.schema.getNearestSelectionRange( this.position );\n\t}\n\n\t/**\n\t * Returns a range which contains all the performed changes. This is a range that, if removed, would return the model to the state\n\t * before the insertion. Returns `null` if no changes were done.\n\t */\n\tpublic getAffectedRange(): Range | null {\n\t\tif ( !this._affectedStart ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn new Range( this._affectedStart, this._affectedEnd );\n\t}\n\n\t/**\n\t * Destroys `Insertion` instance.\n\t */\n\tpublic destroy(): void {\n\t\tif ( this._affectedStart ) {\n\t\t\tthis._affectedStart.detach();\n\t\t}\n\n\t\tif ( this._affectedEnd ) {\n\t\t\tthis._affectedEnd.detach();\n\t\t}\n\t}\n\n\t/**\n\t * Handles insertion of a single node.\n\t */\n\tprivate _handleNode( node: Node ): void {\n\t\t// Split the position.parent's branch up to a point where the node can be inserted.\n\t\t// If it isn't allowed in the whole branch, then of course don't split anything.\n\t\tif ( !this._checkAndSplitToAllowedPosition( node ) ) {\n\t\t\t// Handle element children if it's not an object (strip container).\n\t\t\tif ( !this.schema.isObject( node ) ) {\n\t\t\t\tthis._handleDisallowedNode( node );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Add node to the current temporary DocumentFragment.\n\t\tthis._appendToFragment( node );\n\n\t\t// Store the first and last nodes for easy access for merging with sibling nodes.\n\t\tif ( !this._firstNode ) {\n\t\t\tthis._firstNode = node;\n\t\t}\n\n\t\tthis._lastNode = node;\n\t}\n\n\t/**\n\t * Inserts the temporary DocumentFragment into the model.\n\t */\n\tprivate _insertPartialFragment(): void {\n\t\tif ( this._documentFragment.isEmpty ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst livePosition = LivePosition.fromPosition( this.position, 'toNext' );\n\n\t\tthis._setAffectedBoundaries( this.position );\n\n\t\t// If the very first node of the whole insertion process is inserted, insert it separately for OT reasons (undo).\n\t\t// Note: there can be multiple calls to `_insertPartialFragment()` during one insertion process.\n\t\t// Note: only the very first node can be merged so we have to do separate operation only for it.\n\t\tif ( this._documentFragment.getChild( 0 ) == this._firstNode ) {\n\t\t\tthis.writer.insert( this._firstNode!, this.position );\n\n\t\t\t// We must merge the first node just after inserting it to avoid problems with OT.\n\t\t\t// (See: https://github.com/ckeditor/ckeditor5/pull/8773#issuecomment-760945652).\n\t\t\tthis._mergeOnLeft();\n\n\t\t\tthis.position = livePosition.toPosition();\n\t\t}\n\n\t\t// Insert the remaining nodes from document fragment.\n\t\tif ( !this._documentFragment.isEmpty ) {\n\t\t\tthis.writer.insert( this._documentFragment, this.position );\n\t\t}\n\n\t\tthis._documentFragmentPosition = this.writer.createPositionAt( this._documentFragment, 0 );\n\n\t\tthis.position = livePosition.toPosition();\n\t\tlivePosition.detach();\n\t}\n\n\t/**\n\t * @param node The disallowed node which needs to be handled.\n\t */\n\tprivate _handleDisallowedNode( node: Node ): void {\n\t\t// If the node is an element, try inserting its children (strip the parent).\n\t\tif ( node.is( 'element' ) ) {\n\t\t\tthis.handleNodes( node.getChildren() );\n\t\t}\n\t}\n\n\t/**\n\t * Append a node to the temporary DocumentFragment.\n\t *\n\t * @param node The node to insert.\n\t */\n\tprivate _appendToFragment( node: Node ): void {\n\t\t/* istanbul ignore if -- @preserve */\n\t\tif ( !this.schema.checkChild( this.position, node ) ) {\n\t\t\t// Algorithm's correctness check. We should never end up here but it's good to know that we did.\n\t\t\t// Note that it would often be a silent issue if we insert node in a place where it's not allowed.\n\n\t\t\t/**\n\t\t\t * Given node cannot be inserted on the given position.\n\t\t\t *\n\t\t\t * @error insertcontent-wrong-position\n\t\t\t * @param node Node to insert.\n\t\t\t * @param position Position to insert the node at.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'insertcontent-wrong-position',\n\t\t\t\tthis,\n\t\t\t\t{ node, position: this.position }\n\t\t\t);\n\t\t}\n\n\t\tthis.writer.insert( node, this._documentFragmentPosition );\n\t\tthis._documentFragmentPosition = this._documentFragmentPosition.getShiftedBy( node.offsetSize );\n\n\t\t// The last inserted object should be selected because we can't put a collapsed selection after it.\n\t\tif ( this.schema.isObject( node ) && !this.schema.checkChild( this.position, '$text' ) ) {\n\t\t\tthis._nodeToSelect = node;\n\t\t} else {\n\t\t\tthis._nodeToSelect = null;\n\t\t}\n\n\t\tthis._filterAttributesOf.push( node );\n\t}\n\n\t/**\n\t * Sets `_affectedStart` and `_affectedEnd` to the given `position`. Should be used before a change is done during insertion process to\n\t * mark the affected range.\n\t *\n\t * This method is used before inserting a node or splitting a parent node. `_affectedStart` and `_affectedEnd` are also changed\n\t * during merging, but the logic there is more complicated so it is left out of this function.\n\t */\n\tprivate _setAffectedBoundaries( position: Position ): void {\n\t\t// Set affected boundaries stickiness so that those position will \"expand\" when something is inserted in between them:\n\t\t// <paragraph>Foo][bar</paragraph> -> <paragraph>Foo]xx[bar</paragraph>\n\t\t// This is why it cannot be a range but two separate positions.\n\t\tif ( !this._affectedStart ) {\n\t\t\tthis._affectedStart = LivePosition.fromPosition( position, 'toPrevious' );\n\t\t}\n\n\t\t// If `_affectedEnd` is before the new boundary position, expand `_affectedEnd`. This can happen if first inserted node was\n\t\t// inserted into the parent but the next node is moved-out of that parent:\n\t\t// (1) <paragraph>Foo][</paragraph> -> <paragraph>Foo]xx[</paragraph>\n\t\t// (2) <paragraph>Foo]xx[</paragraph> -> <paragraph>Foo]xx</paragraph><widget></widget>[\n\t\tif ( !this._affectedEnd || this._affectedEnd.isBefore( position ) ) {\n\t\t\tif ( this._affectedEnd ) {\n\t\t\t\tthis._affectedEnd.detach();\n\t\t\t}\n\n\t\t\tthis._affectedEnd = LivePosition.fromPosition( position, 'toNext' );\n\t\t}\n\t}\n\n\t/**\n\t * Merges the previous sibling of the first node if it should be merged.\n\t *\n\t * After the content was inserted we may try to merge it with its siblings.\n\t * This should happen only if the selection was in those elements initially.\n\t */\n\tprivate _mergeOnLeft(): void {\n\t\tconst node = this._firstNode;\n\n\t\tif ( !( node instanceof Element ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this._canMergeLeft( node ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mergePosLeft = LivePosition._createBefore( node );\n\t\tmergePosLeft.stickiness = 'toNext';\n\n\t\tconst livePosition = LivePosition.fromPosition( this.position, 'toNext' );\n\n\t\t// If `_affectedStart` is sames as merge position, it means that the element \"marked\" by `_affectedStart` is going to be\n\t\t// removed and its contents will be moved. This won't transform `LivePosition` so `_affectedStart` needs to be moved\n\t\t// by hand to properly reflect affected range. (Due to `_affectedStart` and `_affectedEnd` stickiness, the \"range\" is\n\t\t// shown as `][`).\n\t\t//\n\t\t// Example - insert `<paragraph>Abc</paragraph><paragraph>Xyz</paragraph>` at the end of `<paragraph>Foo^</paragraph>`:\n\t\t//\n\t\t// <paragraph>Foo</paragraph><paragraph>Bar</paragraph>   -->\n\t\t// <paragraph>Foo</paragraph>]<paragraph>Abc</paragraph><paragraph>Xyz</paragraph>[<paragraph>Bar</paragraph>   -->\n\t\t// <paragraph>Foo]Abc</paragraph><paragraph>Xyz</paragraph>[<paragraph>Bar</paragraph>\n\t\t//\n\t\t// Note, that if we are here then something must have been inserted, so `_affectedStart` and `_affectedEnd` have to be set.\n\t\tif ( this._affectedStart!.isEqual( mergePosLeft ) ) {\n\t\t\tthis._affectedStart!.detach();\n\t\t\tthis._affectedStart = LivePosition._createAt( mergePosLeft.nodeBefore!, 'end', 'toPrevious' );\n\t\t}\n\n\t\t// We need to update the references to the first and last nodes if they will be merged into the previous sibling node\n\t\t// because the reference would point to the removed node.\n\t\t//\n\t\t// <p>A^A</p> + <p>X</p>\n\t\t//\n\t\t// <p>A</p>^<p>A</p>\n\t\t// <p>A</p><p>X</p><p>A</p>\n\t\t// <p>AX</p><p>A</p>\n\t\t// <p>AXA</p>\n\t\tif ( this._firstNode === this._lastNode ) {\n\t\t\tthis._firstNode = mergePosLeft.nodeBefore;\n\t\t\tthis._lastNode = mergePosLeft.nodeBefore;\n\t\t}\n\n\t\tthis.writer.merge( mergePosLeft );\n\n\t\t// If only one element (the merged one) is in the \"affected range\", also move the affected range end appropriately.\n\t\t//\n\t\t// Example - insert `<paragraph>Abc</paragraph>` at the of `<paragraph>Foo^</paragraph>`:\n\t\t//\n\t\t// <paragraph>Foo</paragraph><paragraph>Bar</paragraph>   -->\n\t\t// <paragraph>Foo</paragraph>]<paragraph>Abc</paragraph>[<paragraph>Bar</paragraph>   -->\n\t\t// <paragraph>Foo]Abc</paragraph>[<paragraph>Bar</paragraph>   -->\n\t\t// <paragraph>Foo]Abc[</paragraph><paragraph>Bar</paragraph>\n\t\tif ( mergePosLeft.isEqual( this._affectedEnd! ) && this._firstNode === this._lastNode ) {\n\t\t\tthis._affectedEnd!.detach();\n\t\t\tthis._affectedEnd = LivePosition._createAt( mergePosLeft.nodeBefore!, 'end', 'toNext' );\n\t\t}\n\n\t\tthis.position = livePosition.toPosition();\n\t\tlivePosition.detach();\n\n\t\t// After merge elements that were marked by _insert() to be filtered might be gone so\n\t\t// we need to mark the new container.\n\t\tthis._filterAttributesOf.push( this.position.parent as any );\n\n\t\tmergePosLeft.detach();\n\t}\n\n\t/**\n\t * Merges the next sibling of the last node if it should be merged.\n\t *\n\t * After the content was inserted we may try to merge it with its siblings.\n\t * This should happen only if the selection was in those elements initially.\n\t */\n\tprivate _mergeOnRight(): void {\n\t\tconst node = this._lastNode;\n\n\t\tif ( !( node instanceof Element ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this._canMergeRight( node ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mergePosRight = LivePosition._createAfter( node );\n\t\tmergePosRight.stickiness = 'toNext';\n\n\t\t/* istanbul ignore if -- @preserve */\n\t\tif ( !this.position.isEqual( mergePosRight ) ) {\n\t\t\t// Algorithm's correctness check. We should never end up here but it's good to know that we did.\n\t\t\t// At this point the insertion position should be after the node we'll merge. If it isn't,\n\t\t\t// it should need to be secured as in the left merge case.\n\t\t\t/**\n\t\t\t * An internal error occurred when merging inserted content with its siblings.\n\t\t\t * The insertion position should equal the merge position.\n\t\t\t *\n\t\t\t * If you encountered this error, report it back to the CKEditor 5 team\n\t\t\t * with as many details as possible regarding the content being inserted and the insertion position.\n\t\t\t *\n\t\t\t * @error insertcontent-invalid-insertion-position\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'insertcontent-invalid-insertion-position', this );\n\t\t}\n\n\t\t// Move the position to the previous node, so it isn't moved to the graveyard on merge.\n\t\t// <p>x</p>[]<p>y</p> => <p>x[]</p><p>y</p>\n\t\tthis.position = Position._createAt( mergePosRight.nodeBefore!, 'end' );\n\n\t\t// Explanation of setting position stickiness to `'toPrevious'`:\n\t\t// OK:  <p>xx[]</p> + <p>yy</p> => <p>xx[]yy</p> (when sticks to previous)\n\t\t// NOK: <p>xx[]</p> + <p>yy</p> => <p>xxyy[]</p> (when sticks to next)\n\t\tconst livePosition = LivePosition.fromPosition( this.position, 'toPrevious' );\n\n\t\t// See comment in `_mergeOnLeft()` on moving `_affectedStart`.\n\t\tif ( this._affectedEnd!.isEqual( mergePosRight ) ) {\n\t\t\tthis._affectedEnd!.detach();\n\t\t\tthis._affectedEnd = LivePosition._createAt( mergePosRight.nodeBefore!, 'end', 'toNext' );\n\t\t}\n\n\t\t// We need to update the references to the first and last nodes if they will be merged into the previous sibling node\n\t\t// because the reference would point to the removed node.\n\t\t//\n\t\t// <p>A^A</p> + <p>X</p>\n\t\t//\n\t\t// <p>A</p>^<p>A</p>\n\t\t// <p>A</p><p>X</p><p>A</p>\n\t\t// <p>AX</p><p>A</p>\n\t\t// <p>AXA</p>\n\t\tif ( this._firstNode === this._lastNode ) {\n\t\t\tthis._firstNode = mergePosRight.nodeBefore;\n\t\t\tthis._lastNode = mergePosRight.nodeBefore;\n\t\t}\n\n\t\tthis.writer.merge( mergePosRight );\n\n\t\t// See comment in `_mergeOnLeft()` on moving `_affectedStart`.\n\t\tif ( mergePosRight.getShiftedBy( -1 ).isEqual( this._affectedStart! ) && this._firstNode === this._lastNode ) {\n\t\t\tthis._affectedStart!.detach();\n\t\t\tthis._affectedStart = LivePosition._createAt( mergePosRight.nodeBefore!, 0, 'toPrevious' );\n\t\t}\n\n\t\tthis.position = livePosition.toPosition();\n\t\tlivePosition.detach();\n\n\t\t// After merge elements that were marked by _insert() to be filtered might be gone so\n\t\t// we need to mark the new container.\n\t\tthis._filterAttributesOf.push( this.position.parent as any );\n\n\t\tmergePosRight.detach();\n\t}\n\n\t/**\n\t * Checks whether specified node can be merged with previous sibling element.\n\t *\n\t * @param node The node which could potentially be merged.\n\t */\n\tprivate _canMergeLeft( node: Element ): boolean {\n\t\tconst previousSibling = node.previousSibling;\n\n\t\treturn ( previousSibling instanceof Element ) &&\n\t\t\tthis.canMergeWith.has( previousSibling ) &&\n\t\t\tthis.model.schema.checkMerge( previousSibling, node );\n\t}\n\n\t/**\n\t * Checks whether specified node can be merged with next sibling element.\n\t *\n\t * @param node The node which could potentially be merged.\n\t */\n\tprivate _canMergeRight( node: Element ): boolean {\n\t\tconst nextSibling = node.nextSibling;\n\n\t\treturn ( nextSibling instanceof Element ) &&\n\t\t\tthis.canMergeWith.has( nextSibling ) &&\n\t\t\tthis.model.schema.checkMerge( node, nextSibling );\n\t}\n\n\t/**\n\t * Inserts a paragraph and moves the insertion position into it.\n\t */\n\tprivate _insertAutoParagraph(): void {\n\t\t// Insert nodes collected in temporary DocumentFragment if the position parent needs change to process further nodes.\n\t\tthis._insertPartialFragment();\n\n\t\t// Insert a paragraph and move insertion position to it.\n\t\tconst paragraph = this.writer.createElement( 'paragraph' );\n\n\t\tthis.writer.insert( paragraph, this.position );\n\t\tthis._setAffectedBoundaries( this.position );\n\n\t\tthis._lastAutoParagraph = paragraph;\n\t\tthis.position = this.writer.createPositionAt( paragraph, 0 );\n\t}\n\n\t/**\n\t * @returns Whether an allowed position was found.\n\t * `false` is returned if the node isn't allowed at any position up in the tree, `true` if was.\n\t */\n\tprivate _checkAndSplitToAllowedPosition( node: Node ): boolean {\n\t\tconst allowedIn = this._getAllowedIn( this.position.parent as any, node );\n\n\t\tif ( !allowedIn ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Insert nodes collected in temporary DocumentFragment if the position parent needs change to process further nodes.\n\t\tif ( allowedIn != this.position.parent ) {\n\t\t\tthis._insertPartialFragment();\n\t\t}\n\n\t\twhile ( allowedIn != this.position.parent ) {\n\t\t\tif ( this.position.isAtStart ) {\n\t\t\t\t// If insertion position is at the beginning of the parent, move it out instead of splitting.\n\t\t\t\t// <p>^Foo</p> -> ^<p>Foo</p>\n\t\t\t\tconst parent: Element = this.position.parent as Element;\n\n\t\t\t\tthis.position = this.writer.createPositionBefore( parent );\n\n\t\t\t\t// Special case – parent is empty (<p>^</p>).\n\t\t\t\t//\n\t\t\t\t// 1. parent.isEmpty\n\t\t\t\t// We can remove the element after moving insertion position out of it.\n\t\t\t\t//\n\t\t\t\t// 2. parent.parent === allowedIn\n\t\t\t\t// However parent should remain in place when allowed element is above limit element in document tree.\n\t\t\t\t// For example there shouldn't be allowed to remove empty paragraph from tableCell, when is pasted\n\t\t\t\t// content allowed in $root.\n\t\t\t\tif ( parent.isEmpty && parent.parent === allowedIn ) {\n\t\t\t\t\tthis.writer.remove( parent );\n\t\t\t\t}\n\t\t\t} else if ( this.position.isAtEnd ) {\n\t\t\t\t// If insertion position is at the end of the parent, move it out instead of splitting.\n\t\t\t\t// <p>Foo^</p> -> <p>Foo</p>^\n\t\t\t\tthis.position = this.writer.createPositionAfter( this.position.parent as Element );\n\t\t\t} else {\n\t\t\t\tconst tempPos = this.writer.createPositionAfter( this.position.parent as Element );\n\n\t\t\t\tthis._setAffectedBoundaries( this.position );\n\t\t\t\tthis.writer.split( this.position );\n\n\t\t\t\tthis.position = tempPos;\n\n\t\t\t\tthis.canMergeWith.add( this.position.nodeAfter );\n\t\t\t}\n\t\t}\n\n\t\t// At this point, we split elements up to the parent in which `node` is allowed.\n\t\t// Note that `_getAllowedIn()` checks if the `node` is allowed either directly, or when auto-paragraphed.\n\t\t// So, let's check if the `node` is allowed directly. If not, we need to auto-paragraph it.\n\t\tif ( !this.schema.checkChild( this.position.parent, node ) ) {\n\t\t\tthis._insertAutoParagraph();\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Gets the element in which the given node is allowed. It checks the passed element and all its ancestors.\n\t *\n\t * It also verifies if auto-paragraphing could help.\n\t *\n\t * @param contextElement The element in which context the node should be checked.\n\t * @param childNode The node to check.\n\t */\n\tprivate _getAllowedIn( contextElement: Element, childNode: Node ): Element | null {\n\t\t// Check if a node can be inserted in the given context...\n\t\tif ( this.schema.checkChild( contextElement, childNode ) ) {\n\t\t\treturn contextElement;\n\t\t}\n\n\t\t// ...or it would be accepted if a paragraph would be inserted.\n\t\tif ( this.schema.checkChild( contextElement, 'paragraph' ) && this.schema.checkChild( 'paragraph', childNode ) ) {\n\t\t\treturn contextElement;\n\t\t}\n\n\t\t// If the child wasn't allowed in the context element and the element is a limit there's no point in\n\t\t// checking any further towards the root. This is it: the limit is unsplittable and there's nothing\n\t\t// we can do about it. Without this check, the algorithm will analyze parent of the limit and may create\n\t\t// an illusion of the child being allowed. There's no way to insert it down there, though. It results in\n\t\t// infinite loops.\n\t\tif ( this.schema.isLimit( contextElement ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this._getAllowedIn( contextElement.parent as any, childNode );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/utils/insertobject\n */\n\nimport type DocumentSelection from '../documentselection.js';\nimport type Selection from '../selection.js';\n\nimport type Element from '../element.js';\nimport type Model from '../model.js';\nimport type Range from '../range.js';\nimport type Writer from '../writer.js';\n\nimport { CKEditorError, first } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Inserts an {@glink framework/deep-dive/schema#object-elements object element} at a specific position in the editor content.\n *\n * **Note:** Use {@link module:engine/model/model~Model#insertObject} instead of this function.\n * This function is only exposed to be reusable in algorithms which change the {@link module:engine/model/model~Model#insertObject}\n * method's behavior.\n *\n * **Note**: For more documentation and examples, see {@link module:engine/model/model~Model#insertObject}.\n *\n * @param model The model in context of which the insertion should be performed.\n * @param object An object to be inserted into the model document.\n * @param selectable A selectable where the content should be inserted. If not specified, the current\n * {@link module:engine/model/document~Document#selection document selection} will be used instead.\n * @param placeOrOffset Specifies the exact place or offset for the insertion to take place, relative to `selectable`.\n * @param options Additional options.\n * @param options.findOptimalPosition An option that, when set, adjusts the insertion position (relative to\n * `selectable` and `placeOrOffset`) so that the content of `selectable` is not split upon insertion (a.k.a. non-destructive insertion).\n * * When `'auto'`, the algorithm will decide whether to insert the object before or after `selectable` to avoid content splitting.\n * * When `'before'`, the closest position before `selectable` will be used that will not result in content splitting.\n * * When `'after'`, the closest position after `selectable` will be used that will not result in content splitting.\n *\n * Note that this option works only for block objects. Inline objects are inserted into text and do not split blocks.\n * @param options.setSelection An option that, when set, moves the\n * {@link module:engine/model/document~Document#selection document selection} after inserting the object.\n * * When `'on'`, the document selection will be set on the inserted object.\n * * When `'after'`, the document selection will move to the closest text node after the inserted object. If there is no\n * such text node, a paragraph will be created and the document selection will be moved inside it.\n * @returns A range which contains all the performed changes. This is a range that, if removed,\n * would return the model to the state before the insertion. If no changes were preformed by `insertObject()`, returns a range collapsed\n * at the insertion position.\n */\nexport default function insertObject(\n\tmodel: Model,\n\tobject: Element,\n\tselectable?: Selection | DocumentSelection | null,\n\toptions: {\n\t\tfindOptimalPosition?: 'auto' | 'before' | 'after';\n\t\tsetSelection?: 'on' | 'after';\n\t} = {}\n): Range {\n\tif ( !model.schema.isObject( object ) ) {\n\t\t/**\n\t\t * Tried to insert an element with {@link module:engine/model/utils/insertobject insertObject()} function\n\t\t * that is not defined as an object in schema.\n\t\t * See {@link module:engine/model/schema~SchemaItemDefinition#isObject `SchemaItemDefinition`}.\n\t\t * If you want to insert content that is not an object you might want to use\n\t\t * {@link module:engine/model/utils/insertcontent insertContent()} function.\n\t\t * @error insertobject-element-not-an-object\n\t\t */\n\t\tthrow new CKEditorError( 'insertobject-element-not-an-object', model, { object } );\n\t}\n\n\t// Normalize selectable to a selection instance.\n\tconst originalSelection: Selection | DocumentSelection = selectable ? selectable : model.document.selection;\n\n\t// Adjust the insertion selection.\n\tlet insertionSelection = originalSelection;\n\n\tif ( options.findOptimalPosition && model.schema.isBlock( object ) ) {\n\t\tinsertionSelection = model.createSelection(\n\t\t\tmodel.schema.findOptimalInsertionRange( originalSelection, options.findOptimalPosition )\n\t\t);\n\t}\n\n\t// Collect attributes to be copied on the inserted object.\n\tconst firstSelectedBlock = first( originalSelection.getSelectedBlocks() );\n\tconst attributesToCopy = {};\n\n\tif ( firstSelectedBlock ) {\n\t\tObject.assign( attributesToCopy, model.schema.getAttributesWithProperty( firstSelectedBlock, 'copyOnReplace', true ) );\n\t}\n\n\treturn model.change( writer => {\n\t\t// Remove the selected content to find out what the parent of the inserted object would be.\n\t\t// It would be removed inside model.insertContent() anyway.\n\t\tif ( !insertionSelection.isCollapsed ) {\n\t\t\tmodel.deleteContent( insertionSelection, { doNotAutoparagraph: true } );\n\t\t}\n\n\t\tlet elementToInsert = object;\n\t\tconst insertionPositionParent = insertionSelection.anchor!.parent;\n\n\t\t// Autoparagraphing of an inline objects.\n\t\tif (\n\t\t\t!model.schema.checkChild( insertionPositionParent as any, object ) &&\n\t\t\tmodel.schema.checkChild( insertionPositionParent as any, 'paragraph' ) &&\n\t\t\tmodel.schema.checkChild( 'paragraph', object )\n\t\t) {\n\t\t\telementToInsert = writer.createElement( 'paragraph' );\n\n\t\t\twriter.insert( object, elementToInsert );\n\t\t}\n\n\t\t// Apply attributes that are allowed on the inserted object (or paragraph if autoparagraphed).\n\t\tmodel.schema.setAllowedAttributes( elementToInsert, attributesToCopy, writer );\n\n\t\t// Insert the prepared content at the optionally adjusted selection.\n\t\tconst affectedRange = model.insertContent( elementToInsert, insertionSelection );\n\n\t\t// Nothing got inserted.\n\t\tif ( affectedRange.isCollapsed ) {\n\t\t\treturn affectedRange;\n\t\t}\n\n\t\tif ( options.setSelection ) {\n\t\t\tupdateSelection( writer, object, options.setSelection, attributesToCopy );\n\t\t}\n\n\t\treturn affectedRange;\n\t} );\n}\n\n/**\n * Updates document selection based on given `place` parameter in relation to `contextElement` element.\n *\n * @param writer An instance of the model writer.\n * @param contextElement An element to set the attributes on.\n * @param place The place where selection should be set in relation to the `contextElement` element.\n * Value `on` will set selection on the passed `contextElement`. Value `after` will set selection after `contextElement`.\n * @param attributes Attributes keys and values to set on a paragraph that this function can create when\n * `place` parameter is equal to `after` but there is no element with `$text` node to set selection in.\n */\nfunction updateSelection(\n\twriter: Writer,\n\tcontextElement: Element,\n\tplace: 'after' | 'on',\n\tparagraphAttributes: Record<string, unknown>\n) {\n\tconst model = writer.model;\n\n\tif ( place == 'on' ) {\n\t\twriter.setSelection( contextElement, 'on' );\n\n\t\treturn;\n\t}\n\n\tif ( place != 'after' ) {\n\t\t/**\n\t\t * The unsupported `options.setSelection` parameter was passed\n\t\t * to the {@link module:engine/model/utils/insertobject insertObject()} function.\n\t\t * Check the {@link module:engine/model/utils/insertobject insertObject()} API documentation for allowed\n\t\t * `options.setSelection` parameter values.\n\t\t *\n\t\t * @error insertobject-invalid-place-parameter-value\n\t\t */\n\t\tthrow new CKEditorError( 'insertobject-invalid-place-parameter-value', model );\n\t}\n\n\tlet nextElement = contextElement.nextSibling;\n\n\tif ( model.schema.isInline( contextElement ) ) {\n\t\twriter.setSelection( contextElement, 'after' );\n\n\t\treturn;\n\t}\n\n\t// Check whether an element next to the inserted element is defined and can contain a text.\n\tconst canSetSelection = nextElement && model.schema.checkChild( nextElement, '$text' );\n\n\t// If the element is missing, but a paragraph could be inserted next to the element, let's add it.\n\tif ( !canSetSelection && model.schema.checkChild( contextElement.parent as any, 'paragraph' ) ) {\n\t\tnextElement = writer.createElement( 'paragraph' );\n\n\t\tmodel.schema.setAllowedAttributes( nextElement, paragraphAttributes, writer );\n\t\tmodel.insertContent( nextElement, writer.createPositionAfter( contextElement ) );\n\t}\n\n\t// Put the selection inside the element, at the beginning.\n\tif ( nextElement ) {\n\t\twriter.setSelection( nextElement, 0 );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/utils/modifyselection\n */\n\nimport DocumentSelection from '../documentselection.js';\nimport Position from '../position.js';\nimport Range from '../range.js';\nimport TreeWalker, { type TreeWalkerValue } from '../treewalker.js';\n\nimport type Model from '../model.js';\nimport type Schema from '../schema.js';\nimport type Selection from '../selection.js';\nimport type Text from '../text.js';\nimport type Node from '../node.js';\n\nimport { isInsideSurrogatePair, isInsideCombinedSymbol, isInsideEmojiSequence } from '@ckeditor/ckeditor5-utils';\n\nconst wordBoundaryCharacters = ' ,.?!:;\"-()';\n\n/**\n * Modifies the selection. Currently, the supported modifications are:\n *\n * * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n * Possible values for `unit` are:\n *  * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n *  character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n *  with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n *  letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n *  selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n *  why `'character'` value is most natural and common method of modifying selection.\n *  * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n *  selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n *  However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n *  two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n *  For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n *  outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n *  extension will include whole \"surrogate pair\".\n *  * `'word'` - moves selection by a whole word.\n *\n * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n *\n * **Note:** Use {@link module:engine/model/model~Model#modifySelection} instead of this function.\n * This function is only exposed to be reusable in algorithms\n * which change the {@link module:engine/model/model~Model#modifySelection}\n * method's behavior.\n *\n * @param model The model in context of which the selection modification should be performed.\n * @param selection The selection to modify.\n * @param options.direction The direction in which the selection should be modified. Default 'forward'.\n * @param options.unit The unit by which selection should be modified. Default 'character'.\n * @param options.treatEmojiAsSingleUnit Whether multi-characer emoji sequences should be handled as single unit.\n */\nexport default function modifySelection(\n\tmodel: Model,\n\tselection: Selection | DocumentSelection,\n\toptions: {\n\t\tdirection?: 'forward' | 'backward';\n\t\tunit?: 'character' | 'codePoint' | 'word';\n\t\ttreatEmojiAsSingleUnit?: boolean;\n\t} = {}\n): void {\n\tconst schema = model.schema;\n\tconst isForward = options.direction != 'backward';\n\tconst unit = options.unit ? options.unit : 'character';\n\tconst treatEmojiAsSingleUnit = !!options.treatEmojiAsSingleUnit;\n\n\tconst focus = selection.focus!;\n\n\tconst walker = new TreeWalker( {\n\t\tboundaries: getSearchRange( focus, isForward ),\n\t\tsingleCharacters: true,\n\t\tdirection: isForward ? 'forward' : 'backward'\n\t} );\n\n\tconst data = { walker, schema, isForward, unit, treatEmojiAsSingleUnit };\n\n\tlet next;\n\n\twhile ( ( next = walker.next() ) ) {\n\t\tif ( next.done ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = tryExtendingTo( data, next.value );\n\n\t\tif ( position ) {\n\t\t\tif ( selection instanceof DocumentSelection ) {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\twriter.setSelectionFocus( position );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tselection.setFocus( position );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * Checks whether the selection can be extended to the the walker's next value (next position).\n */\nfunction tryExtendingTo(\n\tdata: {\n\t\twalker: TreeWalker;\n\t\tschema: Schema;\n\t\tisForward: boolean;\n\t\tunit: 'character' | 'codePoint' | 'word';\n\t\ttreatEmojiAsSingleUnit: boolean;\n\t},\n\tvalue: TreeWalkerValue\n): Position | undefined {\n\tconst { isForward, walker, unit, schema, treatEmojiAsSingleUnit } = data;\n\tconst { type, item, nextPosition } = value;\n\n\t// If found text, we can certainly put the focus in it. Let's just find a correct position\n\t// based on the unit.\n\tif ( type == 'text' ) {\n\t\tif ( data.unit === 'word' ) {\n\t\t\treturn getCorrectWordBreakPosition( walker, isForward );\n\t\t}\n\n\t\treturn getCorrectPosition( walker, unit, treatEmojiAsSingleUnit );\n\t}\n\n\t// Entering an element.\n\tif ( type == ( isForward ? 'elementStart' : 'elementEnd' ) ) {\n\t\t// If it's a selectable, we can select it now.\n\t\tif ( schema.isSelectable( item ) ) {\n\t\t\treturn Position._createAt( item, isForward ? 'after' : 'before' );\n\t\t}\n\n\t\t// If text allowed on this position, extend to this place.\n\t\tif ( schema.checkChild( nextPosition, '$text' ) ) {\n\t\t\treturn nextPosition;\n\t\t}\n\t}\n\t// Leaving an element.\n\telse {\n\t\t// If leaving a limit element, stop.\n\t\tif ( schema.isLimit( item ) ) {\n\t\t\t// NOTE: Fast-forward the walker until the end.\n\t\t\twalker.skip( () => true );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If text allowed on this position, extend to this place.\n\t\tif ( schema.checkChild( nextPosition, '$text' ) ) {\n\t\t\treturn nextPosition;\n\t\t}\n\t}\n}\n\n/**\n * Finds a correct position by walking in a text node and checking whether selection can be extended to given position\n * or should be extended further.\n */\nfunction getCorrectPosition(\n\twalker: TreeWalker,\n\tunit: 'character' | 'codePoint' | 'word',\n\ttreatEmojiAsSingleUnit: boolean\n): Position {\n\tconst textNode = walker.position.textNode;\n\n\tif ( textNode ) {\n\t\tconst data = textNode.data;\n\t\tlet offset = walker.position.offset - textNode.startOffset!;\n\n\t\twhile (\n\t\t\tisInsideSurrogatePair( data, offset ) ||\n\t\t\t( unit == 'character' && isInsideCombinedSymbol( data, offset ) ) ||\n\t\t\t( treatEmojiAsSingleUnit && isInsideEmojiSequence( data, offset ) )\n\t\t) {\n\t\t\twalker.next();\n\n\t\t\toffset = walker.position.offset - textNode.startOffset!;\n\t\t}\n\t}\n\n\treturn walker.position;\n}\n\n/**\n * Finds a correct position of a word break by walking in a text node and checking whether selection can be extended to given position\n * or should be extended further.\n */\nfunction getCorrectWordBreakPosition( walker: TreeWalker, isForward: boolean ): Position {\n\tlet textNode: Node | null = walker.position.textNode;\n\n\tif ( !textNode ) {\n\t\ttextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;\n\t}\n\n\twhile ( textNode && textNode.is( '$text' ) ) {\n\t\tconst offset = walker.position.offset - textNode.startOffset!;\n\n\t\t// Check of adjacent text nodes with different attributes (like BOLD).\n\t\t// Example          : 'foofoo []bar<$text bold=\"true\">bar</$text> bazbaz'\n\t\t// should expand to : 'foofoo [bar<$text bold=\"true\">bar</$text>] bazbaz'.\n\t\tif ( isAtNodeBoundary( textNode, offset, isForward ) ) {\n\t\t\ttextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;\n\t\t}\n\t\t// Check if this is a word boundary.\n\t\telse if ( isAtWordBoundary( textNode.data, offset, isForward ) ) {\n\t\t\tbreak;\n\t\t}\n\t\t// Maybe one more character.\n\t\telse {\n\t\t\twalker.next();\n\t\t}\n\t}\n\n\treturn walker.position;\n}\n\nfunction getSearchRange( start: Position, isForward: boolean ) {\n\tconst root = start.root;\n\tconst searchEnd = Position._createAt( root, isForward ? 'end' : 0 );\n\n\tif ( isForward ) {\n\t\treturn new Range( start, searchEnd );\n\t} else {\n\t\treturn new Range( searchEnd, start );\n\t}\n}\n\n/**\n * Checks if selection is on word boundary.\n */\nfunction isAtWordBoundary( data: string, offset: number, isForward: boolean ) {\n\t// The offset to check depends on direction.\n\tconst offsetToCheck = offset + ( isForward ? 0 : -1 );\n\n\treturn wordBoundaryCharacters.includes( data.charAt( offsetToCheck ) );\n}\n\n/**\n * Checks if selection is on node boundary.\n */\nfunction isAtNodeBoundary( textNode: Text, offset: number, isForward: boolean ) {\n\treturn offset === ( isForward ? textNode.offsetSize : 0 );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/model/model\n */\n\nimport Batch, { type BatchType } from './batch.js';\nimport Document from './document.js';\nimport MarkerCollection from './markercollection.js';\nimport ModelPosition, { type PositionOffset, type PositionStickiness } from './position.js';\nimport ModelRange from './range.js';\nimport ModelSelection, { type PlaceOrOffset, type Selectable } from './selection.js';\nimport OperationFactory from './operation/operationfactory.js';\nimport DocumentSelection from './documentselection.js';\nimport Schema from './schema.js';\nimport Writer from './writer.js';\nimport Node from './node.js';\n\nimport { autoParagraphEmptyRoots } from './utils/autoparagraphing.js';\nimport { injectSelectionPostFixer } from './utils/selection-post-fixer.js';\nimport deleteContent from './utils/deletecontent.js';\nimport getSelectedContent from './utils/getselectedcontent.js';\nimport insertContent from './utils/insertcontent.js';\nimport insertObject from './utils/insertobject.js';\nimport modifySelection from './utils/modifyselection.js';\n\nimport type ModelDocumentFragment from './documentfragment.js';\nimport type Item from './item.js';\nimport type ModelElement from './element.js';\nimport type Operation from './operation/operation.js';\n\nimport {\n\tCKEditorError,\n\tObservableMixin,\n\ttype DecoratedMethodEvent\n} from '@ckeditor/ckeditor5-utils';\n\n// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' );\n// @if CK_DEBUG_ENGINE // const { OperationReplayer } = require( '../dev-utils/operationreplayer' ).default;\n\n/**\n * Editor's data model. Read about the model in the\n * {@glink framework/architecture/editing-engine engine architecture} guide.\n */\nexport default class Model extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * Model's marker collection.\n\t */\n\tpublic readonly markers: MarkerCollection;\n\n\t/**\n\t * Model's document.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * Model's schema.\n\t */\n\tpublic readonly schema: Schema;\n\n\t/**\n\t * All callbacks added by {@link module:engine/model/model~Model#change} or\n\t * {@link module:engine/model/model~Model#enqueueChange} methods waiting to be executed.\n\t */\n\tprivate readonly _pendingChanges: Array<{ batch: Batch; callback: ( writer: Writer ) => any }>;\n\n\t/**\n\t * The last created and currently used writer instance.\n\t */\n\tprivate _currentWriter: Writer | null;\n\n\t// @if CK_DEBUG_ENGINE // private _operationLogs: Array<string>;\n\t// @if CK_DEBUG_ENGINE // private _appliedOperations: Array<Operation>;\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.markers = new MarkerCollection();\n\t\tthis.document = new Document( this );\n\t\tthis.schema = new Schema();\n\n\t\tthis._pendingChanges = [];\n\t\tthis._currentWriter = null;\n\n\t\t( [ 'deleteContent', 'modifySelection', 'getSelectedContent', 'applyOperation' ] as const )\n\t\t\t.forEach( methodName => this.decorate( methodName ) );\n\n\t\t// Adding operation validation with `highest` priority, so it is called before any other feature would like\n\t\t// to do anything with the operation. If the operation has incorrect parameters it should throw on the earliest occasion.\n\t\tthis.on<ModelApplyOperationEvent>( 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\toperation._validate();\n\t\t}, { priority: 'highest' } );\n\n\t\t// Register some default abstract entities.\n\t\tthis.schema.register( '$root', {\n\t\t\tisLimit: true\n\t\t} );\n\n\t\tthis.schema.register( '$container', {\n\t\t\tallowIn: [ '$root', '$container' ]\n\t\t} );\n\n\t\tthis.schema.register( '$block', {\n\t\t\tallowIn: [ '$root', '$container' ],\n\t\t\tisBlock: true\n\t\t} );\n\n\t\tthis.schema.register( '$blockObject', {\n\t\t\tallowWhere: '$block',\n\t\t\tisBlock: true,\n\t\t\tisObject: true\n\t\t} );\n\n\t\tthis.schema.register( '$inlineObject', {\n\t\t\tallowWhere: '$text',\n\t\t\tallowAttributesOf: '$text',\n\t\t\tisInline: true,\n\t\t\tisObject: true\n\t\t} );\n\n\t\tthis.schema.register( '$text', {\n\t\t\tallowIn: '$block',\n\t\t\tisInline: true,\n\t\t\tisContent: true\n\t\t} );\n\n\t\tthis.schema.register( '$clipboardHolder', {\n\t\t\tallowContentOf: '$root',\n\t\t\tallowChildren: '$text',\n\t\t\tisLimit: true\n\t\t} );\n\n\t\tthis.schema.register( '$documentFragment', {\n\t\t\tallowContentOf: '$root',\n\t\t\tallowChildren: '$text',\n\t\t\tisLimit: true\n\t\t} );\n\n\t\t// An element needed by the `upcastElementToMarker` converter.\n\t\t// This element temporarily represents a marker boundary during the conversion process and is removed\n\t\t// at the end of the conversion. `UpcastDispatcher` or at least `Conversion` class looks like a\n\t\t// better place for this registration but both know nothing about `Schema`.\n\t\tthis.schema.register( '$marker' );\n\t\tthis.schema.addChildCheck( () => true, '$marker' ); // Allow everywhere.\n\n\t\tinjectSelectionPostFixer( this );\n\n\t\t// Post-fixer which takes care of adding empty paragraph elements to the empty roots.\n\t\tthis.document.registerPostFixer( autoParagraphEmptyRoots );\n\n\t\t// The base implementation for \"decorated\" method with remapped arguments.\n\t\tthis.on<ModelInsertContentEvent>( 'insertContent', ( evt, [ content, selectable ] ) => {\n\t\t\tevt.return = insertContent( this, content, selectable );\n\t\t} );\n\n\t\t// The base implementation for \"decorated\" method with remapped arguments.\n\t\tthis.on<ModelInsertObjectEvent>( 'insertObject', ( evt, [ element, selection, options ] ) => {\n\t\t\tevt.return = insertObject( this, element, selection, options );\n\t\t} );\n\n\t\t// The base implementation for \"decorated\" method with remapped arguments.\n\t\tthis.on<ModelCanEditAtEvent>( 'canEditAt', evt => {\n\t\t\tconst canEditAt = !this.document.isReadOnly;\n\n\t\t\tevt.return = canEditAt;\n\n\t\t\tif ( !canEditAt ) {\n\t\t\t\t// Prevent further processing if the selection is at non-editable place.\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// @if CK_DEBUG_ENGINE // initDocumentDumping( this.document );\n\t\t// @if CK_DEBUG_ENGINE // this.on( 'applyOperation', () => {\n\t\t// @if CK_DEBUG_ENGINE // \tdumpTrees( this.document, this.document.version );\n\t\t// @if CK_DEBUG_ENGINE // }, { priority: 'lowest' } );\n\n\t\t// @if CK_DEBUG_ENGINE // this._operationLogs = [];\n\t\t// @if CK_DEBUG_ENGINE // this._appliedOperations = [];\n\t}\n\n\t/**\n\t * The `change()` method is the primary way of changing the model. You should use it to modify all document nodes\n\t * (including detached nodes – i.e. nodes not added to the {@link module:engine/model/model~Model#document model document}),\n\t * the {@link module:engine/model/document~Document#selection document's selection}, and\n\t * {@link module:engine/model/model~Model#markers model markers}.\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \twriter.insertText( 'foo', paragraph, 'end' );\n\t * } );\n\t * ```\n\t *\n\t * All changes inside the change block use the same {@link module:engine/model/batch~Batch} so they are combined\n\t * into a single undo step.\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \twriter.insertText( 'foo', paragraph, 'end' ); // foo.\n\t *\n\t * \tmodel.change( writer => {\n\t * \t\twriter.insertText( 'bar', paragraph, 'end' ); // foobar.\n\t * \t} );\n\t *\n\t * \twriter.insertText( 'bom', paragraph, 'end' ); // foobarbom.\n\t * } );\n\t * ```\n\t *\n\t * The callback of the `change()` block is executed synchronously.\n\t *\n\t * You can also return a value from the change block.\n\t *\n\t * ```ts\n\t * const img = model.change( writer => {\n\t * \treturn writer.createElement( 'img' );\n\t * } );\n\t * ```\n\t *\n\t * @see #enqueueChange\n\t * @typeParam TReturn The return type of the provided callback.\n\t * @param callback Callback function which may modify the model.\n\t */\n\tpublic change<TReturn>( callback: ( writer: Writer ) => TReturn ): TReturn {\n\t\ttry {\n\t\t\tif ( this._pendingChanges.length === 0 ) {\n\t\t\t\t// If this is the outermost block, create a new batch and start `_runPendingChanges` execution flow.\n\t\t\t\tthis._pendingChanges.push( { batch: new Batch(), callback } );\n\n\t\t\t\treturn this._runPendingChanges()[ 0 ];\n\t\t\t} else {\n\t\t\t\t// If this is not the outermost block, just execute the callback.\n\t\t\t\treturn callback( this._currentWriter! );\n\t\t\t}\n\t\t} catch ( err: any ) {\n\t\t\t// @if CK_DEBUG // throw err;\n\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\tCKEditorError.rethrowUnexpectedError( err, this );\n\t\t}\n\t}\n\n\t/**\n\t * The `enqueueChange()` method performs similar task as the {@link #change `change()` method}, with two major differences.\n\t *\n\t * First, the callback of `enqueueChange()` is executed when all other enqueued changes are done. It might be executed\n\t * immediately if it is not nested in any other change block, but if it is nested in another (enqueue)change block,\n\t * it will be delayed and executed after the outermost block.\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \tconsole.log( 1 );\n\t *\n\t * \tmodel.enqueueChange( writer => {\n\t * \t\tconsole.log( 2 );\n\t * \t} );\n\t *\n\t * \tconsole.log( 3 );\n\t * } ); // Will log: 1, 3, 2.\n\t * ```\n\t *\n\t * In addition to that, the changes enqueued with `enqueueChange()` will be converted separately from the changes\n\t * done in the outer `change()` block.\n\t *\n\t * By default, a new batch with the default {@link module:engine/model/batch~Batch#constructor batch type} is created.\n\t * To define the {@link module:engine/model/batch~Batch} into which you want to add your changes,\n\t * use {@link #enqueueChange:CUSTOM_BATCH `enqueueChange( batchOrType, callback )`}.\n\t *\n\t * @label DEFAULT_BATCH\n\t * @param callback Callback function which may modify the model.\n\t */\n\tpublic enqueueChange(\n\t\tcallback: ( writer: Writer ) => unknown\n\t): void;\n\n\t/**\n\t * The `enqueueChange()` method performs similar task as the {@link #change `change()` method}, with two major differences.\n\t *\n\t * First, the callback of `enqueueChange()` is executed when all other enqueued changes are done. It might be executed\n\t * immediately if it is not nested in any other change block, but if it is nested in another (enqueue)change block,\n\t * it will be delayed and executed after the outermost block.\n\t *\n\t * ```ts\n\t * model.change( new Batch(), writer => {\n\t * \tconsole.log( 1 );\n\t *\n\t * \tmodel.enqueueChange( new Batch(), writer => {\n\t * \t\tconsole.log( 2 );\n\t * \t} );\n\t *\n\t * \tconsole.log( 3 );\n\t * } ); // Will log: 1, 3, 2.\n\t * ```\n\t *\n\t * In addition to that, the changes enqueued with `enqueueChange()` will be converted separately from the changes\n\t * done in the outer `change()` block.\n\t *\n\t * Second, it lets you define the {@link module:engine/model/batch~Batch} into which you want to add your changes.\n\t * If you want to use default {@link module:engine/model/batch~Batch#constructor batch type}, use\n\t * {@link #enqueueChange:DEFAULT_BATCH `enqueueChange( callback )`}.\n\t *\n\t * ```ts\n\t * model.enqueueChange( { isUndoable: false }, writer => {\n\t * \twriter.insertText( 'foo', paragraph, 'end' );\n\t * } );\n\t * ```\n\t *\n\t * When using the `enqueueChange()` block you can also add some changes to the batch you used before.\n\t *\n\t * ```ts\n\t * model.enqueueChange( batch, writer => {\n\t * \twriter.insertText( 'foo', paragraph, 'end' );\n\t * } );\n\t * ```\n\t *\n\t * In order to make a nested `enqueueChange()` create a single undo step together with the changes done in the outer `change()`\n\t * block, you can obtain the batch instance from the  {@link module:engine/model/writer~Writer#batch writer} of the outer block.\n\t *\n\t * @label CUSTOM_BATCH\n\t * @param batchOrType A batch or a {@link module:engine/model/batch~Batch#constructor batch type} that should be used in the callback.\n\t * If not defined, a new batch with the default type will be created.\n\t * @param callback Callback function which may modify the model.\n\t */\n\tpublic enqueueChange(\n\t\tbatchOrType: Batch | BatchType | undefined,\n\t\tcallback: ( writer: Writer ) => unknown\n\t): void;\n\n\tpublic enqueueChange(\n\t\tbatchOrType: Batch | BatchType | ( ( writer: Writer ) => unknown ) | undefined,\n\t\tcallback?: ( writer: Writer ) => unknown\n\t): void {\n\t\ttry {\n\t\t\tif ( !batchOrType ) {\n\t\t\t\tbatchOrType = new Batch();\n\t\t\t} else if ( typeof batchOrType === 'function' ) {\n\t\t\t\tcallback = batchOrType;\n\t\t\t\tbatchOrType = new Batch();\n\t\t\t} else if ( !( batchOrType instanceof Batch ) ) {\n\t\t\t\tbatchOrType = new Batch( batchOrType );\n\t\t\t}\n\n\t\t\tthis._pendingChanges.push( { batch: batchOrType, callback } as any );\n\n\t\t\tif ( this._pendingChanges.length == 1 ) {\n\t\t\t\tthis._runPendingChanges();\n\t\t\t}\n\t\t} catch ( err: any ) {\n\t\t\t// @if CK_DEBUG // throw err;\n\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\tCKEditorError.rethrowUnexpectedError( err, this );\n\t\t}\n\t}\n\n\t/**\n\t * {@link module:utils/observablemixin~Observable#decorate Decorated} function for applying\n\t * {@link module:engine/model/operation/operation~Operation operations} to the model.\n\t *\n\t * This is a low-level way of changing the model. It is exposed for very specific use cases (like the undo feature).\n\t * Normally, to modify the model, you will want to use {@link module:engine/model/writer~Writer `Writer`}.\n\t * See also {@glink framework/architecture/editing-engine#changing-the-model Changing the model} section\n\t * of the {@glink framework/architecture/editing-engine Editing architecture} guide.\n\t *\n\t * @param operation The operation to apply.\n\t */\n\tpublic applyOperation( operation: Operation ): void {\n\t\t// @if CK_DEBUG_ENGINE // console.log( 'Applying ' + operation );\n\n\t\t// @if CK_DEBUG_ENGINE // this._operationLogs.push( JSON.stringify( operation ) );\n\t\t// @if CK_DEBUG_ENGINE // this._appliedOperations.push( operation );\n\n\t\toperation._execute();\n\t}\n\n\t// @if CK_DEBUG_ENGINE // public getAppliedOperation(): string {\n\t// @if CK_DEBUG_ENGINE // \tif ( !this._appliedOperations ) {\n\t// @if CK_DEBUG_ENGINE // \t\treturn '';\n\t// @if CK_DEBUG_ENGINE // \t}\n\n\t// @if CK_DEBUG_ENGINE // \treturn this._appliedOperations.map( operation => JSON.stringify( operation ) ).join( '-------' );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t// @if CK_DEBUG_ENGINE // public createReplayer( stringifiedOperations: string ): typeof OperationReplayer {\n\t// @if CK_DEBUG_ENGINE // \treturn new OperationReplayer( this, '-------', stringifiedOperations );\n\t// @if CK_DEBUG_ENGINE // }\n\n\t/**\n\t * Inserts content at the position in the editor specified by the selection, as one would expect the paste\n\t * functionality to work.\n\t *\n\t * **Note**: If you want to insert an {@glink framework/deep-dive/schema#object-elements object element}\n\t * (e.g. a {@link module:widget/utils~toWidget widget}), see {@link #insertObject} instead.\n\t *\n\t * This is a high-level method. It takes the {@link #schema schema} into consideration when inserting\n\t * the content, clears the given selection's content before inserting nodes and moves the selection\n\t * to its target position at the end of the process.\n\t * It can split elements, merge them, wrap bare text nodes with paragraphs, etc. &ndash; just like the\n\t * pasting feature should do.\n\t *\n\t * For lower-level methods see {@link module:engine/model/writer~Writer `Writer`}.\n\t *\n\t * This method, unlike {@link module:engine/model/writer~Writer `Writer`}'s methods, does not have to be used\n\t * inside a {@link #change `change()` block}.\n\t *\n\t * # Conversion and schema\n\t *\n\t * Inserting elements and text nodes into the model is not enough to make CKEditor 5 render that content\n\t * to the user. CKEditor 5 implements a model-view-controller architecture and what `model.insertContent()` does\n\t * is only adding nodes to the model. Additionally, you need to define\n\t * {@glink framework/architecture/editing-engine#conversion converters} between the model and view\n\t * and define those nodes in the {@glink framework/architecture/editing-engine#schema schema}.\n\t *\n\t * So, while this method may seem similar to CKEditor 4 `editor.insertHtml()` (in fact, both methods\n\t * are used for paste-like content insertion), the CKEditor 5 method cannot be use to insert arbitrary HTML\n\t * unless converters are defined for all elements and attributes in that HTML.\n\t *\n\t * # Examples\n\t *\n\t * Using `insertContent()` with a manually created model structure:\n\t *\n\t * ```ts\n\t * // Let's create a document fragment containing such content as:\n\t * //\n\t * // <paragraph>foo</paragraph>\n\t * // <blockQuote>\n\t * //    <paragraph>bar</paragraph>\n\t * // </blockQuote>\n\t * const docFrag = editor.model.change( writer => {\n\t * \tconst p1 = writer.createElement( 'paragraph' );\n\t * \tconst p2 = writer.createElement( 'paragraph' );\n\t * \tconst blockQuote = writer.createElement( 'blockQuote' );\n\t * \tconst docFrag = writer.createDocumentFragment();\n\t *\n\t * \twriter.append( p1, docFrag );\n\t * \twriter.append( blockQuote, docFrag );\n\t * \twriter.append( p2, blockQuote );\n\t * \twriter.insertText( 'foo', p1 );\n\t * \twriter.insertText( 'bar', p2 );\n\t *\n\t * \treturn docFrag;\n\t * } );\n\t *\n\t * // insertContent() does not have to be used in a change() block. It can, though,\n\t * // so this code could be moved to the callback defined above.\n\t * editor.model.insertContent( docFrag );\n\t * ```\n\t *\n\t * Using `insertContent()` with an HTML string converted to a model document fragment (similar to the pasting mechanism):\n\t *\n\t * ```ts\n\t * // You can create your own HtmlDataProcessor instance or use editor.data.processor\n\t * // if you have not overridden the default one (which is the HtmlDataProcessor instance).\n\t * const htmlDP = new HtmlDataProcessor( viewDocument );\n\t *\n\t * // Convert an HTML string to a view document fragment:\n\t * const viewFragment = htmlDP.toView( htmlString );\n\t *\n\t * // Convert the view document fragment to a model document fragment\n\t * // in the context of $root. This conversion takes the schema into\n\t * // account so if, for example, the view document fragment contained a bare text node,\n\t * // this text node cannot be a child of $root, so it will be automatically\n\t * // wrapped with a <paragraph>. You can define the context yourself (in the second parameter),\n\t * // and e.g. convert the content like it would happen in a <paragraph>.\n\t * // Note: The clipboard feature uses a custom context called $clipboardHolder\n\t * // which has a loosened schema.\n\t * const modelFragment = editor.data.toModel( viewFragment );\n\t *\n\t * editor.model.insertContent( modelFragment );\n\t * ```\n\t *\n\t * By default this method will use the document selection but it can also be used with a position, range or selection instance.\n\t *\n\t * ```ts\n\t * // Insert text at the current document selection position.\n\t * editor.model.change( writer => {\n\t * \teditor.model.insertContent( writer.createText( 'x' ) );\n\t * } );\n\t *\n\t * // Insert text at a given position - the document selection will not be modified.\n\t * editor.model.change( writer => {\n\t * \teditor.model.insertContent( writer.createText( 'x' ), doc.getRoot(), 2 );\n\t *\n\t * \t// Which is a shorthand for:\n\t * \teditor.model.insertContent( writer.createText( 'x' ), writer.createPositionAt( doc.getRoot(), 2 ) );\n\t * } );\n\t * ```\n\t *\n\t * If you want the document selection to be moved to the inserted content, use the\n\t * {@link module:engine/model/writer~Writer#setSelection `setSelection()`} method of the writer after inserting\n\t * the content:\n\t *\n\t * ```ts\n\t * editor.model.change( writer => {\n\t * \tconst paragraph = writer.createElement( 'paragraph' );\n\t *\n\t * \t// Insert an empty paragraph at the beginning of the root.\n\t * \teditor.model.insertContent( paragraph, writer.createPositionAt( editor.model.document.getRoot(), 0 ) );\n\t *\n\t * \t// Move the document selection to the inserted paragraph.\n\t * \twriter.setSelection( paragraph, 'in' );\n\t * } );\n\t * ```\n\t *\n\t * If an instance of the {@link module:engine/model/selection~Selection model selection} is passed as `selectable`,\n\t * the new content will be inserted at the passed selection (instead of document selection):\n\t *\n\t * ```ts\n\t * editor.model.change( writer => {\n\t * \t// Create a selection in a paragraph that will be used as a place of insertion.\n\t * \tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * \t// Insert the new text at the created selection.\n\t * \teditor.model.insertContent( writer.createText( 'x' ), selection );\n\t *\n\t * \t// insertContent() modifies the passed selection instance so it can be used to set the document selection.\n\t * \t// Note: This is not necessary when you passed the document selection to insertContent().\n\t * \twriter.setSelection( selection );\n\t * } );\n\t * ```\n\t *\n\t * @fires insertContent\n\t * @param content The content to insert.\n\t * @param selectable The selection into which the content should be inserted.\n\t * If not provided the current model document selection will be used.\n\t * @param placeOrOffset To be used when a model item was passed as `selectable`.\n\t * This param defines a position in relation to that item.\n\t * at the insertion position.\n\t */\n\tpublic insertContent(\n\t\tcontent: Item | ModelDocumentFragment,\n\t\tselectable?: Selectable,\n\t\tplaceOrOffset?: PlaceOrOffset,\n\t\t...rest: Array<unknown>\n\t): ModelRange {\n\t\tconst selection = normalizeSelectable( selectable, placeOrOffset );\n\n\t\t// Passing all call arguments so it acts like decorated method.\n\t\treturn this.fire<ModelInsertContentEvent>( 'insertContent', [ content, selection, placeOrOffset, ...rest ] )!;\n\t}\n\n\t/**\n\t * Inserts an {@glink framework/deep-dive/schema#object-elements object element} at a specific position in the editor content.\n\t *\n\t * This is a high-level API:\n\t * * It takes the {@link #schema schema} into consideration,\n\t * * It clears the content of passed `selectable` before inserting,\n\t * * It can move the selection at the end of the process,\n\t * * It will copy the selected block's attributes to preserve them upon insertion,\n\t * * It can split elements or wrap inline objects with paragraphs if they are not allowed in target position,\n\t * * etc.\n\t *\n\t * # Notes\n\t *\n\t * * If you want to insert a non-object content, see {@link #insertContent} instead.\n\t * * For lower-level API, see {@link module:engine/model/writer~Writer `Writer`}.\n\t * * Unlike {@link module:engine/model/writer~Writer `Writer`}, this method does not have to be used inside\n\t * a {@link #change `change()` block}.\n\t * * Inserting object into the model is not enough to make CKEditor 5 render that content to the user.\n\t * CKEditor 5 implements a model-view-controller architecture and what `model.insertObject()` does\n\t * is only adding nodes to the model. Additionally, you need to define\n\t * {@glink framework/architecture/editing-engine#conversion converters} between the model and view\n\t * and define those nodes in the {@glink framework/architecture/editing-engine#schema schema}.\n\t *\n\t * # Examples\n\t *\n\t * Use the following code to insert an object at the current selection and keep the selection on the inserted element:\n\t *\n\t * ```ts\n\t * const rawHtmlEmbedElement = writer.createElement( 'rawHtml' );\n\t *\n\t * model.insertObject( rawHtmlEmbedElement, null, null, {\n\t * \tsetSelection: 'on'\n\t * } );\n\t * ```\n\t *\n\t * Use the following code to insert an object at the current selection and nudge the selection after the inserted object:\n\t *\n\t * ```ts\n\t * const pageBreakElement = writer.createElement( 'pageBreak' );\n \t *\n\t * model.insertObject( pageBreakElement, null, null, {\n\t * \tsetSelection: 'after'\n\t * } );\n\t * ```\n\t *\n\t * Use the following code to insert an object at the current selection and avoid splitting the content (non-destructive insertion):\n\t *\n\t * ```ts\n\t * const tableElement = writer.createElement( 'table' );\n \t *\n\t * model.insertObject( tableElement, null, null, {\n\t * \tfindOptimalPosition: 'auto'\n\t * } );\n\t * ```\n\t *\n\t * Use the following code to insert an object at the specific range (also: replace the content of the range):\n\t *\n\t * ```ts\n\t * const tableElement = writer.createElement( 'table' );\n\t * const range = model.createRangeOn( model.document.getRoot().getChild( 1 ) );\n \t *\n\t * model.insertObject( tableElement, range );\n\t * ```\n\t *\n\t * @param element An object to be inserted into the model document.\n\t * @param selectable A selectable where the content should be inserted. If not specified, the current\n\t * {@link module:engine/model/document~Document#selection document selection} will be used instead.\n\t * @param placeOrOffset Specifies the exact place or offset for the insertion to take place, relative to `selectable`.\n\t * @param options Additional options.\n\t * @param options.findOptimalPosition An option that, when set, adjusts the insertion position (relative to\n\t * `selectable` and `placeOrOffset`) so that the content of `selectable` is not split upon insertion (a.k.a. non-destructive insertion).\n\t * * When `'auto'`, the algorithm will decide whether to insert the object before or after `selectable` to avoid content splitting.\n\t * * When `'before'`, the closest position before `selectable` will be used that will not result in content splitting.\n\t * * When `'after'`, the closest position after `selectable` will be used that will not result in content splitting.\n\t *\n\t * Note that this option only works for block objects. Inline objects are inserted into text and do not split blocks.\n\t * @param options.setSelection An option that, when set, moves the\n\t * {@link module:engine/model/document~Document#selection document selection} after inserting the object.\n\t * * When `'on'`, the document selection will be set on the inserted object.\n\t * * When `'after'`, the document selection will move to the closest text node after the inserted object. If there is no\n\t * such text node, a paragraph will be created and the document selection will be moved inside it.\n\t * at the insertion position.\n\t */\n\tpublic insertObject(\n\t\telement: ModelElement,\n\t\tselectable?: Selectable,\n\t\tplaceOrOffset?: PlaceOrOffset | null,\n\t\toptions?: {\n\t\t\tfindOptimalPosition?: 'auto' | 'before' | 'after';\n\t\t\tsetSelection?: 'on' | 'after';\n\t\t},\n\t\t...rest: Array<unknown>\n\t): ModelRange {\n\t\tconst selection = normalizeSelectable( selectable, placeOrOffset );\n\n\t\t// Note that options are fired as 2 arguments for backward compatibility with the decorated method.\n\t\t// Passing all call arguments so it acts like decorated method.\n\t\treturn this.fire<ModelInsertObjectEvent>( 'insertObject', [ element, selection, options, options, ...rest ] )!;\n\t}\n\n\t/**\n\t * Deletes content of the selection and merge siblings. The resulting selection is always collapsed.\n\t *\n\t * **Note:** For the sake of predictability, the resulting selection should always be collapsed.\n\t * In cases where a feature wants to modify deleting behavior so selection isn't collapsed\n\t * (e.g. a table feature may want to keep row selection after pressing <kbd>Backspace</kbd>),\n\t * then that behavior should be implemented in the view's listener. At the same time, the table feature\n\t * will need to modify this method's behavior too, e.g. to \"delete contents and then collapse\n\t * the selection inside the last selected cell\" or \"delete the row and collapse selection somewhere near\".\n\t * That needs to be done in order to ensure that other features which use `deleteContent()` will work well with tables.\n\t *\n\t * @fires deleteContent\n\t * @param selection Selection of which the content should be deleted.\n\t * @param options.leaveUnmerged Whether to merge elements after removing the content of the selection.\n\t *\n\t * For example `<heading1>x[x</heading1><paragraph>y]y</paragraph>` will become:\n\t *\n\t * * `<heading1>x^y</heading1>` with the option disabled (`leaveUnmerged == false`)\n\t * * `<heading1>x^</heading1><paragraph>y</paragraph>` with enabled (`leaveUnmerged == true`).\n\t *\n\t * Note: {@link module:engine/model/schema~Schema#isObject object} and {@link module:engine/model/schema~Schema#isLimit limit}\n\t * elements will not be merged.\n\t *\n\t * @param options.doNotResetEntireContent Whether to skip replacing the entire content with a\n\t * paragraph when the entire content was selected.\n\t *\n\t * For example `<heading1>[x</heading1><paragraph>y]</paragraph>` will become:\n\t *\n\t * * `<paragraph>^</paragraph>` with the option disabled (`doNotResetEntireContent == false`)\n\t * * `<heading1>^</heading1>` with enabled (`doNotResetEntireContent == true`)\n\t *\n\t * @param options.doNotAutoparagraph Whether to create a paragraph if after content deletion selection is moved\n\t * to a place where text cannot be inserted.\n\t *\n\t * For example `<paragraph>x</paragraph>[<imageBlock src=\"foo.jpg\"></imageBlock>]` will become:\n\t *\n\t * * `<paragraph>x</paragraph><paragraph>[]</paragraph>` with the option disabled (`doNotAutoparagraph == false`)\n\t * * `<paragraph>x[]</paragraph>` with the option enabled (`doNotAutoparagraph == true`).\n\t *\n\t * **Note:** if there is no valid position for the selection, the paragraph will always be created:\n\t *\n\t * `[<imageBlock src=\"foo.jpg\"></imageBlock>]` -> `<paragraph>[]</paragraph>`.\n\t *\n\t * @param options.direction The direction in which the content is being consumed.\n\t * Deleting backward corresponds to using the <kbd>Backspace</kbd> key, while deleting content forward corresponds to\n\t * the <kbd>Shift</kbd>+<kbd>Backspace</kbd> keystroke.\n\t */\n\tpublic deleteContent(\n\t\tselection: ModelSelection | DocumentSelection,\n\t\toptions?: {\n\t\t\tleaveUnmerged?: boolean;\n\t\t\tdoNotResetEntireContent?: boolean;\n\t\t\tdoNotAutoparagraph?: boolean;\n\t\t\tdirection?: 'forward' | 'backward';\n\t\t\t[ i: string ]: unknown;\n\t\t}\n\t): void {\n\t\tdeleteContent( this, selection, options );\n\t}\n\n\t/**\n\t * Modifies the selection. Currently, the supported modifications are:\n\t *\n\t * * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`.\n\t * Possible values for `unit` are:\n\t *  * `'character'` (default) - moves selection by one user-perceived character. In most cases this means moving by one\n\t *  character in `String` sense. However, unicode also defines \"combing marks\". These are special symbols, that combines\n\t *  with a symbol before it (\"base character\") to create one user-perceived character. For example, `q̣̇` is a normal\n\t *  letter `q` with two \"combining marks\": upper dot (`Ux0307`) and lower dot (`Ux0323`). For most actions, i.e. extending\n\t *  selection by one position, it is correct to include both \"base character\" and all of it's \"combining marks\". That is\n\t *  why `'character'` value is most natural and common method of modifying selection.\n\t *  * `'codePoint'` - moves selection by one unicode code point. In contrary to, `'character'` unit, this will insert\n\t *  selection between \"base character\" and \"combining mark\", because \"combining marks\" have their own unicode code points.\n\t *  However, for technical reasons, unicode code points with values above `UxFFFF` are represented in native `String` by\n\t *  two characters, called \"surrogate pairs\". Halves of \"surrogate pairs\" have a meaning only when placed next to each other.\n\t *  For example `𨭎` is represented in `String` by `\\uD862\\uDF4E`. Both `\\uD862` and `\\uDF4E` do not have any meaning\n\t *  outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection\n\t *  extension will include whole \"surrogate pair\".\n\t *  * `'word'` - moves selection by a whole word.\n\t *\n\t * **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.\n\t *\n\t * @fires modifySelection\n\t * @param selection The selection to modify.\n\t * @param options.direction The direction in which the selection should be modified.\n\t * @param options.unit The unit by which selection should be modified.\n\t * @param options.treatEmojiAsSingleUnit Whether multi-characer emoji sequences should be handled as single unit.\n\t */\n\tpublic modifySelection(\n\t\tselection: ModelSelection | DocumentSelection,\n\t\toptions?: {\n\t\t\tdirection?: 'forward' | 'backward';\n\t\t\tunit?: 'character' | 'codePoint' | 'word';\n\t\t\ttreatEmojiAsSingleUnit?: boolean;\n\t\t}\n\t): void {\n\t\tmodifySelection( this, selection, options );\n\t}\n\n\t/**\n\t * Gets a clone of the selected content.\n\t *\n\t * For example, for the following selection:\n\t *\n\t * ```html\n\t * <paragraph>x</paragraph>\n\t * <blockQuote>\n\t * \t<paragraph>y</paragraph>\n\t * \t<heading1>fir[st</heading1>\n\t * </blockQuote>\n\t * <paragraph>se]cond</paragraph>\n\t * <paragraph>z</paragraph>\n\t * ```\n\t *\n\t * It will return a document fragment with such a content:\n\t *\n\t * ```html\n\t * <blockQuote>\n\t * \t<heading1>st</heading1>\n\t * </blockQuote>\n\t * <paragraph>se</paragraph>\n\t * ```\n\t *\n\t * @fires getSelectedContent\n\t * @param selection The selection of which content will be returned.\n\t */\n\tpublic getSelectedContent( selection: ModelSelection | DocumentSelection ): ModelDocumentFragment {\n\t\treturn getSelectedContent( this, selection );\n\t}\n\n\t/**\n\t * Checks whether the given {@link module:engine/model/range~Range range} or\n\t * {@link module:engine/model/element~Element element} has any meaningful content.\n\t *\n\t * Meaningful content is:\n\t *\n\t * * any text node (`options.ignoreWhitespaces` allows controlling whether this text node must also contain\n\t * any non-whitespace characters),\n\t * * or any {@link module:engine/model/schema~Schema#isContent content element},\n\t * * or any {@link module:engine/model/markercollection~Marker marker} which\n\t * {@link module:engine/model/markercollection~Marker#_affectsData affects data}.\n\t *\n\t * This means that a range containing an empty `<paragraph></paragraph>` is not considered to have a meaningful content.\n\t * However, a range containing an `<imageBlock></imageBlock>` (which would normally be marked in the schema as an object element)\n\t * is considered non-empty.\n\t *\n\t * @param rangeOrElement Range or element to check.\n\t * @param options.ignoreWhitespaces Whether text node with whitespaces only should be considered empty.\n\t * @param options.ignoreMarkers Whether markers should be ignored.\n\t */\n\tpublic hasContent(\n\t\trangeOrElement: ModelRange | ModelElement | ModelDocumentFragment,\n\t\toptions: {\n\t\t\tignoreWhitespaces?: boolean;\n\t\t\tignoreMarkers?: boolean;\n\t\t} = {}\n\t): boolean {\n\t\tconst range = rangeOrElement instanceof ModelRange ? rangeOrElement : ModelRange._createIn( rangeOrElement );\n\n\t\tif ( range.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst { ignoreWhitespaces = false, ignoreMarkers = false } = options;\n\n\t\t// Check if there are any markers which affects data in this given range.\n\t\tif ( !ignoreMarkers ) {\n\t\t\tfor ( const intersectingMarker of this.markers.getMarkersIntersectingRange( range ) ) {\n\t\t\t\tif ( intersectingMarker.affectsData ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const item of range.getItems() ) {\n\t\t\tif ( this.schema.isContent( item ) ) {\n\t\t\t\tif ( item.is( '$textProxy' ) ) {\n\t\t\t\t\tif ( !ignoreWhitespaces ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else if ( item.data.search( /\\S/ ) !== -1 ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Check whether given selectable is at a place in the model where it can be edited (returns `true`) or not (returns `false`).\n\t *\n\t * Should be used instead of {@link module:core/editor/editor~Editor#isReadOnly} to check whether a user action can happen at\n\t * given selectable. It may be decorated and used differently in different environment (e.g. multi-root editor can disable\n\t * a particular root).\n\t *\n\t * This method is decorated. Although this method accepts any parameter of `Selectable` type, the\n\t * {@link ~Model#event:canEditAt `canEditAt` event} is fired with `selectable` normalized to an instance of\n\t * {@link module:engine/model/selection~Selection} or {@link module:engine/model/documentselection~DocumentSelection}\n\t *\n\t * @fires canEditAt\n\t */\n\tpublic canEditAt( selectable: Selectable ): boolean {\n\t\tconst selection = normalizeSelectable( selectable );\n\n\t\treturn this.fire<ModelCanEditAtEvent>( 'canEditAt', [ selection ] )!;\n\t}\n\n\t/**\n\t * Creates a position from the given root and path in that root.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionFromPath `Writer#createPositionFromPath()`}.\n\t *\n\t * @param root Root of the position.\n\t * @param path Position path. See {@link module:engine/model/position~Position#path}.\n\t * @param stickiness Position stickiness. See {@link module:engine/model/position~PositionStickiness}.\n\t */\n\tpublic createPositionFromPath(\n\t\troot: ModelElement | ModelDocumentFragment,\n\t\tpath: ReadonlyArray<number>,\n\t\tstickiness?: PositionStickiness\n\t): ModelPosition {\n\t\treturn new ModelPosition( root, path, stickiness );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/model/position~Position position},\n\t * * a parent element and offset in that element,\n\t * * a parent element and `'end'` (the position will be set at the end of that element),\n\t * * a {@link module:engine/model/item~Item model item} and `'before'` or `'after'`\n\t * (the position will be set before or after the given model item).\n\t *\n\t * This method is a shortcut to other factory methods such as:\n\t *\n\t * * {@link module:engine/model/model~Model#createPositionBefore `createPositionBefore()`},\n\t * * {@link module:engine/model/model~Model#createPositionAfter `createPositionAfter()`}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionAt `Writer#createPositionAt()`},\n\t *\n\t * @param itemOrPosition\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/model/item~Item model item}.\n\t */\n\tpublic createPositionAt(\n\t\titemOrPosition: Item | ModelPosition | ModelDocumentFragment,\n\t\toffset?: PositionOffset\n\t): ModelPosition {\n\t\treturn ModelPosition._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionAfter `Writer#createPositionAfter()`}.\n\t *\n\t * @param item Item after which the position should be placed.\n\t */\n\tpublic createPositionAfter( item: Item ): ModelPosition {\n\t\treturn ModelPosition._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before the given {@link module:engine/model/item~Item model item}.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createPositionBefore `Writer#createPositionBefore()`}.\n\t *\n\t * @param item Item before which the position should be placed.\n\t */\n\tpublic createPositionBefore( item: Item ): ModelPosition {\n\t\treturn ModelPosition._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from the `start` position to the `end` position.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createRange `Writer#createRange()`}:\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \tconst range = writer.createRange( start, end );\n\t * } );\n\t * ```\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, the range will be collapsed to the `start` position.\n\t */\n\tpublic createRange( start: ModelPosition, end?: ModelPosition ): ModelRange {\n\t\treturn new ModelRange( start, end );\n\t}\n\n\t/**\n\t * Creates a range inside the given element which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createRangeIn `Writer#createRangeIn()`}:\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \tconst range = writer.createRangeIn( paragraph );\n\t * } );\n\t * ```\n\t *\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic createRangeIn( element: ModelElement | ModelDocumentFragment ): ModelRange {\n\t\treturn ModelRange._createIn( element );\n\t}\n\n\t/**\n\t * Creates a range that starts before the given {@link module:engine/model/item~Item model item} and ends after it.\n\t *\n\t * Note: This method is also available on `writer` instance as\n\t * {@link module:engine/model/writer~Writer#createRangeOn `Writer.createRangeOn()`}:\n\t *\n\t * ```ts\n\t * model.change( writer => {\n\t * \tconst range = writer.createRangeOn( paragraph );\n\t * } );\n\t * ```\n\t *\n\t * @param item\n\t */\n\tpublic createRangeOn( item: Item ): ModelRange {\n\t\treturn ModelRange._createOn( item );\n\t}\n\n\t/**\n\t * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}\n\t * or creates an empty selection if no arguments were passed.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createSelection `Writer#createSelection()`}.\n\t *\n\t * ```ts\n\t * // Creates selection at the given offset in the given element.\n\t * const paragraph = writer.createElement( 'paragraph' );\n\t * const selection = writer.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/model/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/model/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t * // Additional options (`'backward'`) can be specified as the last argument.\n\t *\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( element, 'in', { backward: true } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:SELECTABLE `createSelection( selectable, options )`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic createSelection( selectable: Node, placeOrOffset: PlaceOrOffset, options?: { backward?: boolean } ): ModelSelection;\n\n\t/**\n\t * Creates a new selection instance based on the given {@link module:engine/model/selection~Selectable selectable}\n\t * or creates an empty selection if no arguments were passed.\n\t *\n\t * Note: This method is also available as\n\t * {@link module:engine/model/writer~Writer#createSelection `Writer#createSelection()`}.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = writer.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = writer.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * const selection = writer.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * // Note: It doesn't copies selection attributes.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = writer.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the given document selection.\n\t * // Note: It doesn't copies selection attributes.\n\t * const documentSelection = model.document.selection;\n\t * const selection = writer.createSelection( documentSelection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * const selection = writer.createSelection( position );\n\t *\n\t * // Additional options (`'backward'`) can be specified as the last argument.\n\t *\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:NODE_OFFSET `createSelection( node, placeOrOffset, options )`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic createSelection( selectable?: Exclude<Selectable, Node>, options?: { backward?: boolean } ): ModelSelection;\n\n\tpublic createSelection( ...args: ConstructorParameters<typeof ModelSelection> ): ModelSelection {\n\t\treturn new ModelSelection( ...args );\n\t}\n\n\t/**\n\t * Creates a {@link module:engine/model/batch~Batch} instance.\n\t *\n\t * **Note:** In most cases creating a batch instance is not necessary as they are created when using:\n\t *\n\t * * {@link #change `change()`},\n\t * * {@link #enqueueChange `enqueueChange()`}.\n\t *\n\t * @param type {@link module:engine/model/batch~Batch#constructor The type} of the batch.\n\t */\n\tpublic createBatch( type?: BatchType ): Batch {\n\t\treturn new Batch( type );\n\t}\n\n\t/**\n\t * Creates an operation instance from a JSON object (parsed JSON string).\n\t *\n\t * This is an alias for {@link module:engine/model/operation/operationfactory~OperationFactory.fromJSON `OperationFactory.fromJSON()`}.\n\t *\n\t * @param json Deserialized JSON object.\n\t */\n\tpublic createOperationFromJSON( json: unknown ): Operation {\n\t\treturn OperationFactory.fromJSON( json, this.document );\n\t}\n\n\t/**\n\t * Removes all events listeners set by model instance and destroys {@link module:engine/model/document~Document}.\n\t */\n\tpublic destroy(): void {\n\t\tthis.document.destroy();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Common part of {@link module:engine/model/model~Model#change} and {@link module:engine/model/model~Model#enqueueChange}\n\t * which calls callbacks and returns array of values returned by these callbacks.\n\t */\n\tprivate _runPendingChanges() {\n\t\tconst ret = [];\n\n\t\tthis.fire( '_beforeChanges' );\n\n\t\ttry {\n\t\t\twhile ( this._pendingChanges.length ) {\n\t\t\t\t// Create a new writer using batch instance created for this chain of changes.\n\t\t\t\tconst currentBatch = this._pendingChanges[ 0 ].batch;\n\t\t\t\tthis._currentWriter = new Writer( this, currentBatch );\n\n\t\t\t\t// Execute changes callback and gather the returned value.\n\t\t\t\tconst callbackReturnValue = this._pendingChanges[ 0 ].callback( this._currentWriter );\n\t\t\t\tret.push( callbackReturnValue );\n\n\t\t\t\tthis.document._handleChangeBlock( this._currentWriter );\n\n\t\t\t\tthis._pendingChanges.shift();\n\t\t\t\tthis._currentWriter = null;\n\t\t\t}\n\t\t} finally {\n\t\t\tthis._pendingChanges.length = 0;\n\t\t\tthis._currentWriter = null;\n\n\t\t\tthis.fire( '_afterChanges' );\n\t\t}\n\n\t\treturn ret;\n\t}\n}\n\n/**\n * Normalizes a selectable to a Selection or DocumentSelection.\n */\nfunction normalizeSelectable(\n\tselectable?: Selectable,\n\tplaceOrOffset?: PlaceOrOffset | null\n): ModelSelection | DocumentSelection | undefined {\n\tif ( !selectable ) {\n\t\treturn;\n\t}\n\n\tif ( selectable instanceof ModelSelection || selectable instanceof DocumentSelection ) {\n\t\treturn selectable;\n\t}\n\n\tif ( selectable instanceof Node ) {\n\t\tif ( placeOrOffset || placeOrOffset === 0 ) {\n\t\t\treturn new ModelSelection( selectable, placeOrOffset );\n\t\t} else if ( selectable.is( 'rootElement' ) ) {\n\t\t\treturn new ModelSelection( selectable, 'in' );\n\t\t} else {\n\t\t\treturn new ModelSelection( selectable, 'on' );\n\t\t}\n\t}\n\n\treturn new ModelSelection( selectable );\n}\n\n/**\n * Fired when entering the outermost {@link module:engine/model/model~Model#enqueueChange} or\n * {@link module:engine/model/model~Model#change} block.\n *\n * @internal\n * @eventName ~Model#_beforeChanges\n */\nexport type BeforeChangesEvent = {\n\tname: '_beforeChanges';\n\targs: [];\n};\n\n/**\n * Fired when leaving the outermost {@link module:engine/model/model~Model#enqueueChange} or\n * {@link module:engine/model/model~Model#change} block.\n *\n * @internal\n * @eventName ~Model#_afterChanges\n */\nexport type AfterChangesEvent = {\n\tname: '_afterChanges';\n\targs: [];\n};\n\n/**\n * Fired every time any {@link module:engine/model/operation/operation~Operation operation} is applied on the model\n * using {@link ~Model#applyOperation}.\n *\n * Note that this event is suitable only for very specific use-cases. Use it if you need to listen to every single operation\n * applied on the document. However, in most cases {@link module:engine/model/document~Document#event:change} should\n * be used.\n *\n * A few callbacks are already added to this event by engine internal classes:\n *\n * * with `highest` priority operation is validated,\n * * with `normal` priority operation is executed,\n * * with `low` priority the {@link module:engine/model/document~Document} updates its version,\n * * with `low` priority {@link module:engine/model/liveposition~LivePosition} and {@link module:engine/model/liverange~LiveRange}\n * update themselves.\n *\n * @eventName ~Model#applyOperation\n * @param args Arguments of the `applyOperation` which is an array with a single element - applied\n * {@link module:engine/model/operation/operation~Operation operation}.\n */\nexport type ModelApplyOperationEvent = DecoratedMethodEvent<Model, 'applyOperation'>;\n\n/**\n * Event fired when {@link ~Model#insertContent} method is called.\n *\n * The {@link ~Model#insertContent default action of that method} is implemented as a\n * listener to this event so it can be fully customized by the features.\n *\n * **Note** The `selectable` parameter for the {@link ~Model#insertContent} is optional. When `undefined` value is passed the method uses\n * {@link module:engine/model/document~Document#selection document selection}.\n *\n * @eventName ~Model#insertContent\n * @param args The arguments passed to the original method.\n */\nexport type ModelInsertContentEvent = {\n\tname: 'insertContent';\n\targs: [ [\n\t\tcontent: Item | ModelDocumentFragment,\n\t\tselectable?: ModelSelection | DocumentSelection,\n\t\t...rest: Array<unknown>\n\t] ];\n\treturn: ModelRange;\n};\n\n/**\n * Event fired when the {@link ~Model#insertObject} method is called.\n *\n * The {@link ~Model#insertObject default action of that method} is implemented as a\n * listener to this event so it can be fully customized by the features.\n *\n * **Note** The `selectable` parameter for the {@link ~Model#insertObject} is optional. When `undefined` value is passed the method uses\n * {@link module:engine/model/document~Document#selection document selection}.\n *\n * @eventName ~Model#insertObject\n * @param args The arguments passed to the original method.\n */\nexport type ModelInsertObjectEvent = {\n\tname: 'insertObject';\n\targs: [ [\n\t\telement: ModelElement,\n\t\tselectable?: ModelSelection | DocumentSelection | null,\n\t\toptions?: {\n\t\t\tfindOptimalPosition?: 'auto' | 'before' | 'after';\n\t\t\tsetSelection?: 'on' | 'after';\n\t\t},\n\t\t...rest: Array<unknown>\n\t] ];\n\treturn: ModelRange;\n};\n\n/**\n * Event fired when {@link ~Model#deleteContent} method is called.\n *\n * The {@link ~Model#deleteContent default action of that method} is implemented as a\n * listener to this event, so it can be fully customized by the features.\n *\n * @eventName ~Model#deleteContent\n * @param args The arguments passed to the original method.\n */\nexport type ModelDeleteContentEvent = DecoratedMethodEvent<Model, 'deleteContent'>;\n\n/**\n * Event fired when {@link ~Model#modifySelection} method is called.\n *\n * The {@link ~Model#modifySelection default action of that method} is implemented as a\n * listener to this event, so it can be fully customized by the features.\n *\n * @eventName ~Model#modifySelection\n * @param args The arguments passed to the original method.\n */\nexport type ModelModifySelectionEvent = DecoratedMethodEvent<Model, 'modifySelection'>;\n\n/**\n * Event fired when {@link ~Model#getSelectedContent} method is called.\n *\n * The {@link ~Model#getSelectedContent default action of that method} is implemented as a\n * listener to this event, so it can be fully customized by the features.\n *\n * @eventName ~Model#getSelectedContent\n * @param args The arguments passed to the original method.\n */\nexport type ModelGetSelectedContentEvent = DecoratedMethodEvent<Model, 'getSelectedContent'>;\n\n/**\n * Event fired when {@link ~Model#canEditAt} method is called.\n *\n * The {@link ~Model#canEditAt default action of that method} is implemented as a\n * listener to this event, so it can be fully customized by the features.\n *\n * Although the original method accepts any parameter of `Selectable` type, this event is fired with `selectable` normalized\n * to an instance of {@link module:engine/model/selection~Selection} or {@link module:engine/model/documentselection~DocumentSelection}.\n *\n * @eventName ~Model#canEditAt\n * @param args The arguments passed to the original method.\n */\nexport type ModelCanEditAtEvent = {\n\tname: 'canEditAt';\n\targs: [ [\n\t\tselectable?: ModelSelection | DocumentSelection\n\t] ];\n\treturn: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/clickobserver\n */\n\nimport DomEventObserver from './domeventobserver.js';\nimport type DomEventData from './domeventdata.js';\nimport type { BubblingEvent } from './bubblingemittermixin.js';\n\n/**\n * {@link module:engine/view/document~Document#event:click Click} event observer.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View view controller} by a {@link module:engine/view/view~View#addObserver} method.\n */\nexport default class ClickObserver extends DomEventObserver<'click'> {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly domEventType = 'click' as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvent: MouseEvent ): void {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when one of the editables has been clicked.\n *\n * Introduced by {@link module:engine/view/observer/clickobserver~ClickObserver}.\n *\n * Note that this event is not available by default. To make it available\n * {@link module:engine/view/observer/clickobserver~ClickObserver} needs to be added\n * to {@link module:engine/view/view~View} by a {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:engine/view/observer/clickobserver~ClickObserver\n * @eventName module:engine/view/document~Document#click\n * @param data Event data.\n */\nexport type ViewDocumentClickEvent = BubblingEvent<{\n\tname: 'click';\n\targs: [ data: DomEventData<MouseEvent> ];\n}>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/observer/mouseobserver\n */\n\nimport DomEventObserver from './domeventobserver.js';\nimport type DomEventData from './domeventdata.js';\n\n/**\n * Mouse events observer.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View} by {@link module:engine/view/view~View#addObserver} method.\n */\nexport default class MouseObserver extends DomEventObserver<'mousedown' | 'mouseup' | 'mouseover' | 'mouseout'> {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly domEventType = [ 'mousedown', 'mouseup', 'mouseover', 'mouseout' ] as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvent: MouseEvent ): void {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when the mouse button is pressed down on one of the editing roots of the editor.\n *\n * Introduced by {@link module:engine/view/observer/mouseobserver~MouseObserver}.\n *\n * Note that this event is not available by default. To make it available, {@link module:engine/view/observer/mouseobserver~MouseObserver}\n * needs to be added to {@link module:engine/view/view~View} by the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:engine/view/observer/mouseobserver~MouseObserver\n * @eventName module:engine/view/document~Document#mousedown\n * @param data The event data.\n */\nexport type ViewDocumentMouseDownEvent = {\n\tname: 'mousedown';\n\targs: [ data: DomEventData<MouseEvent> ];\n};\n\n/**\n * Fired when the mouse button is released over one of the editing roots of the editor.\n *\n * Introduced by {@link module:engine/view/observer/mouseobserver~MouseObserver}.\n *\n * Note that this event is not available by default. To make it available, {@link module:engine/view/observer/mouseobserver~MouseObserver}\n * needs to be added to {@link module:engine/view/view~View} by the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:engine/view/observer/mouseobserver~MouseObserver\n * @eventName module:engine/view/document~Document#mouseup\n * @param  data The event data.\n */\nexport type ViewDocumentMouseUpEvent = {\n\tname: 'mouseup';\n\targs: [ data: DomEventData<MouseEvent> ];\n};\n\n/**\n * Fired when the mouse is over one of the editing roots of the editor.\n *\n * Introduced by {@link module:engine/view/observer/mouseobserver~MouseObserver}.\n *\n * Note that this event is not available by default. To make it available, {@link module:engine/view/observer/mouseobserver~MouseObserver}\n * needs to be added to {@link module:engine/view/view~View} by the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:engine/view/observer/mouseobserver~MouseObserver\n * @eventName module:engine/view/document~Document#mouseover\n * @param  data The event data.\n */\nexport type ViewDocumentMouseOverEvent = {\n\tname: 'mouseover';\n\targs: [ data: DomEventData<MouseEvent> ];\n};\n\n/**\n * Fired when the mouse is moved out of the one of the editing roots of the editor.\n *\n * Introduced by {@link module:engine/view/observer/mouseobserver~MouseObserver}.\n *\n * Note that this event is not available by default. To make it available, {@link module:engine/view/observer/mouseobserver~MouseObserver}\n * needs to be added to {@link module:engine/view/view~View} by the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:engine/view/observer/mouseobserver~MouseObserver\n * @eventName module:engine/view/document~Document#mouseout\n * @param  data The event data.\n */\nexport type ViewDocumentMouseOutEvent = {\n\tname: 'mouseout';\n\targs: [ data: DomEventData<MouseEvent> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/upcastwriter\n */\n\nimport DocumentFragment from './documentfragment.js';\nimport Element, { type ElementAttributes } from './element.js';\nimport Text from './text.js';\nimport { isPlainObject } from 'lodash-es';\nimport Position, { type PositionOffset } from './position.js';\nimport Range from './range.js';\nimport Selection, {\n\ttype PlaceOrOffset,\n\ttype Selectable,\n\ttype SelectionOptions\n} from './selection.js';\n\nimport type Document from './document.js';\nimport type Item from './item.js';\nimport type Node from './node.js';\n\n/**\n * View upcast writer. It provides a set of methods used to manipulate non-semantic view trees.\n *\n * It should be used only while working on a non-semantic view\n * (e.g. a view created from HTML string on paste).\n * To manipulate a view which was or is being downcasted from the the model use the\n * {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}.\n *\n * Read more about changing the view in the {@glink framework/architecture/editing-engine#changing-the-view Changing the view}\n * section of the {@glink framework/architecture/editing-engine Editing engine architecture} guide.\n *\n * Unlike `DowncastWriter`, which is available in the {@link module:engine/view/view~View#change `View#change()`} block,\n * `UpcastWriter` can be created wherever you need it:\n *\n * ```ts\n * const writer = new UpcastWriter( viewDocument );\n * const text = writer.createText( 'foo!' );\n *\n * writer.appendChild( text, someViewElement );\n * ```\n */\nexport default class UpcastWriter {\n\t/**\n\t * The view document instance in which this upcast writer operates.\n\t */\n\tpublic readonly document: Document;\n\n\t/**\n\t * @param document The view document instance in which this upcast writer operates.\n\t */\n\tconstructor( document: Document ) {\n\t\tthis.document = document;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance.\n\t *\n\t * @param children A list of nodes to be inserted into the created document fragment.\n\t * @returns The created document fragment.\n\t */\n\tpublic createDocumentFragment( children?: Node | Iterable<Node> ): DocumentFragment {\n\t\treturn new DocumentFragment( this.document, children );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/element~Element} instance.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t * ```ts\n\t * upcastWriter.createElement( 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t * upcastWriter.createElement( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t * upcastWriter.createElement( 'div', mapOfAttributes ); // map\n\t * ```\n\t *\n\t * @param name Node name.\n\t * @param attrs Collection of attributes.\n\t * @param children A list of nodes to be inserted into created element.\n\t * @returns Created element.\n\t */\n\tpublic createElement(\n\t\tname: string,\n\t\tattrs?: ElementAttributes,\n\t\tchildren?: Node | Iterable<Node>\n\t): Element {\n\t\treturn new Element( this.document, name, attrs, children );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/text~Text} instance.\n\t *\n\t * @param data The text's data.\n\t * @returns The created text node.\n\t */\n\tpublic createText( data: string ): Text {\n\t\treturn new Text( this.document, data );\n\t}\n\n\t/**\n\t * Clones the provided element.\n\t *\n\t * @see module:engine/view/element~Element#_clone\n\t * @param element Element to be cloned.\n\t * @param deep If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns Clone of this element.\n\t */\n\tpublic clone( element: Element, deep: boolean = false ): Element {\n\t\treturn element._clone( deep );\n\t}\n\n\t/**\n\t * Appends a child node or a list of child nodes at the end of this node\n\t * and sets the parent of these nodes to this element.\n\t *\n\t * @see module:engine/view/element~Element#_appendChild\n\t * @param items Items to be inserted.\n\t * @param element Element to which items will be appended.\n\t * @returns Number of appended nodes.\n\t */\n\tpublic appendChild( items: Item | string | Iterable<Item | string>, element: Element | DocumentFragment ): number {\n\t\treturn element._appendChild( items );\n\t}\n\n\t/**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this element.\n\t *\n\t * @see module:engine/view/element~Element#_insertChild\n\t * @param index Offset at which nodes should be inserted.\n\t * @param items Items to be inserted.\n\t * @param element Element to which items will be inserted.\n\t * @returns Number of inserted nodes.\n\t */\n\tpublic insertChild( index: number, items: Item | Iterable<Item>, element: Element | DocumentFragment ): number {\n\t\treturn element._insertChild( index, items );\n\t}\n\n\t/**\n\t * Removes the given number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @see module:engine/view/element~Element#_removeChildren\n\t * @param index Offset from which nodes will be removed.\n\t * @param howMany Number of nodes to remove.\n\t * @param element Element which children will be removed.\n\t * @returns The array containing removed nodes.\n\t */\n\tpublic removeChildren( index: number, howMany: number, element: Element | DocumentFragment ): Array<Node> {\n\t\treturn element._removeChildren( index, howMany );\n\t}\n\n\t/**\n\t * Removes given element from the view structure. Will not have effect on detached elements.\n\t *\n\t * @param element Element which will be removed.\n\t * @returns The array containing removed nodes.\n\t */\n\tpublic remove( element: Node ): Array<Node> {\n\t\tconst parent = element.parent;\n\n\t\tif ( parent ) {\n\t\t\treturn this.removeChildren( parent.getChildIndex( element ), 1, parent );\n\t\t}\n\n\t\treturn [];\n\t}\n\n\t/**\n\t * Replaces given element with the new one in the view structure. Will not have effect on detached elements.\n\t *\n\t * @param oldElement Element which will be replaced.\n\t * @param newElement Element which will be inserted in the place of the old element.\n\t * @returns Whether old element was successfully replaced.\n\t */\n\tpublic replace( oldElement: Element, newElement: Element ): boolean {\n\t\tconst parent = oldElement.parent;\n\n\t\tif ( parent ) {\n\t\t\tconst index = parent.getChildIndex( oldElement )!;\n\n\t\t\tthis.removeChildren( index, 1, parent );\n\t\t\tthis.insertChild( index, newElement, parent );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Removes given element from view structure and places its children in its position.\n\t * It does nothing if element has no parent.\n\t *\n\t * @param element Element to unwrap.\n\t */\n\tpublic unwrapElement( element: Element ): void {\n\t\tconst parent = element.parent;\n\n\t\tif ( parent ) {\n\t\t\tconst index = parent.getChildIndex( element )!;\n\n\t\t\tthis.remove( element );\n\t\t\tthis.insertChild( index, element.getChildren(), parent );\n\t\t}\n\t}\n\n\t/**\n\t * Renames element by creating a copy of a given element but with its name changed and then moving contents of the\n\t * old element to the new one.\n\t *\n\t * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t *\n\t * @param newName New element name.\n\t * @param  element Element to be renamed.\n\t * @returns New element or null if the old element was not replaced (happens for detached elements).\n\t */\n\tpublic rename( newName: string, element: Element ): Element | null {\n\t\tconst newElement = new Element( this.document, newName, element.getAttributes(), element.getChildren() );\n\n\t\treturn this.replace( element, newElement ) ? newElement : null;\n\t}\n\n\t/**\n\t * Adds or overwrites element's attribute with a specified key and value.\n\t *\n\t * ```ts\n\t * writer.setAttribute( 'href', 'http://ckeditor.com', linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_setAttribute\n\t * @param key Attribute key.\n\t * @param value Attribute value.\n\t * @param element Element for which attribute will be set.\n\t */\n\tpublic setAttribute( key: string, value: unknown, element: Element ): void {\n\t\telement._setAttribute( key, value );\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t * ```ts\n\t * writer.removeAttribute( 'href', linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_removeAttribute\n\t * @param key Attribute key.\n\t * @param element Element from which attribute will be removed.\n\t */\n\tpublic removeAttribute( key: string, element: Element ): void {\n\t\telement._removeAttribute( key );\n\t}\n\n\t/**\n\t * Adds specified class to the element.\n\t *\n\t * ```ts\n\t * writer.addClass( 'foo', linkElement );\n\t * writer.addClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_addClass\n\t * @param className Single class name or array of class names which will be added.\n\t * @param element Element for which class will be added.\n\t */\n\tpublic addClass( className: string | Array<string>, element: Element ): void {\n\t\telement._addClass( className );\n\t}\n\n\t/**\n\t * Removes specified class from the element.\n\t *\n\t * ```ts\n\t * writer.removeClass( 'foo', linkElement );\n\t * writer.removeClass( [ 'foo', 'bar' ], linkElement );\n\t * ```\n\t *\n\t * @see module:engine/view/element~Element#_removeClass\n\t * @param className Single class name or array of class names which will be removed.\n\t * @param element Element from which class will be removed.\n\t */\n\tpublic removeClass( className: string | Array<string>, element: Element ): void {\n\t\telement._removeClass( className );\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t * ```ts\n\t * writer.setStyle( 'color', 'red', element );\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details.\n\t *\n\t * @see module:engine/view/element~Element#_setStyle\n\t * @label KEY_VALUE\n\t * @param property Property name.\n\t * @param value Value to set.\n\t * @param element Element for which style will be added.\n\t */\n\tpublic setStyle( property: string, value: string, element: Element ): void;\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t * ```ts\n\t * writer.setStyle( {\n\t * \tcolor: 'red',\n\t * \tposition: 'fixed'\n\t * }, element );\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details.\n\t *\n\t * @see module:engine/view/element~Element#_setStyle\n\t * @label OBJECT\n\t * @param properties Object with key - value pairs.\n\t * @param element Element for which style will be added.\n\t */\n\tpublic setStyle( properties: Record<string, string>, element: Element ): void;\n\n\tpublic setStyle( property: string | Record<string, string>, valueOrElement: string | Element, element?: Element ): void {\n\t\tif ( isPlainObject( property ) && element === undefined ) {\n\t\t\t( valueOrElement as Element )._setStyle( property as Record<string, string> );\n\t\t} else {\n\t\t\telement!._setStyle( property as string, valueOrElement as string );\n\t\t}\n\t}\n\n\t/**\n\t * Removes specified style from the element.\n\t *\n\t * ```ts\n\t * writer.removeStyle( 'color', element );  // Removes 'color' style.\n\t * writer.removeStyle( [ 'color', 'border-top' ], element ); // Removes both 'color' and 'border-top' styles.\n\t * ```\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t *\n\t * @see module:engine/view/element~Element#_removeStyle\n\t * @param property Style property name or names to be removed.\n\t * @param element Element from which style will be removed.\n\t */\n\tpublic removeStyle( property: string | Array<string>, element: Element ): void {\n\t\telement._removeStyle( property );\n\t}\n\n\t/**\n\t * Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/element~Element#_setCustomProperty\n\t * @param key Custom property name/key.\n\t * @param value Custom property value to be stored.\n\t * @param element Element for which custom property will be set.\n\t */\n\tpublic setCustomProperty( key: string | symbol, value: unknown, element: Element | DocumentFragment ): void {\n\t\telement._setCustomProperty( key, value );\n\t}\n\n\t/**\n\t * Removes a custom property stored under the given key.\n\t *\n\t * @see module:engine/view/element~Element#_removeCustomProperty\n\t * @param key Name/key of the custom property to be removed.\n\t * @param element Element from which the custom property will be removed.\n\t * @returns Returns true if property was removed.\n\t */\n\tpublic removeCustomProperty( key: string | symbol, element: Element | DocumentFragment ): boolean {\n\t\treturn element._removeCustomProperty( key );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param offset Offset or one of the flags. Used only when first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tpublic createPositionAt( itemOrPosition: Item | Position, offset?: PositionOffset ): Position {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param item View item after which the position should be located.\n\t */\n\tpublic createPositionAfter( item: Item ): Position {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param item View item before which the position should be located.\n\t */\n\tpublic createPositionBefore( item: Item ): Position {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param start Start position.\n\t * @param end End position. If not set, range will be collapsed at `start` position.\n\t */\n\tpublic createRange( start: Position, end: Position ): Range {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t */\n\tpublic createRangeOn( item: Item ): Range {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param element Element which is a parent for the range.\n\t */\n\tpublic createRangeIn( element: Element | DocumentFragment ): Range {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * ```ts\n\t * // Creates collapsed selection at the position of given item and offset.\n\t * const paragraph = writer.createContainerElement( 'paragraph' );\n\t * const selection = writer.createSelection( paragraph, offset );\n\t *\n\t * // Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t * // first child of that element and ends after the last child of that element.\n\t * const selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t * // Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t * // just after the item.\n\t * const selection = writer.createSelection( paragraph, 'on' );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( element, 'in', { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = writer.createSelection( element, 'in', { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:SELECTABLE `createSelection( selectable, options )`}.\n\t *\n\t * @label NODE_OFFSET\n\t */\n\tpublic createSelection( selectable: Node, placeOrOffset: PlaceOrOffset, options?: SelectionOptions ): Selection;\n\n\t/**\n\t * Creates a new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * ```ts\n\t * // Creates empty selection without ranges.\n\t * const selection = writer.createSelection();\n\t *\n\t * // Creates selection at the given range.\n\t * const range = writer.createRange( start, end );\n\t * const selection = writer.createSelection( range );\n\t *\n\t * // Creates selection at the given ranges\n\t * const ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t * const selection = writer.createSelection( ranges );\n\t *\n\t * // Creates selection from the other selection.\n\t * const otherSelection = writer.createSelection();\n\t * const selection = writer.createSelection( otherSelection );\n\t *\n\t * // Creates selection from the document selection.\n\t * const selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * // Creates selection at the given position.\n\t * const position = writer.createPositionFromPath( root, path );\n\t * const selection = writer.createSelection( position );\n\t * ```\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t * ```ts\n\t * // Creates backward selection.\n\t * const selection = writer.createSelection( range, { backward: true } );\n\t * ```\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be  properly handled by screen readers).\n\t *\n\t * ```ts\n\t * // Creates fake selection with label.\n\t * const selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t * ```\n\t *\n\t * See also: {@link #createSelection:NODE_OFFSET `createSelection( node, placeOrOffset, options )`}.\n\t *\n\t * @label SELECTABLE\n\t */\n\tpublic createSelection( selectable?: Exclude<Selectable, Node>, options?: SelectionOptions ): Selection;\n\n\tpublic createSelection( ...args: ConstructorParameters<typeof Selection> ): Selection {\n\t\treturn new Selection( ...args );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/styles/utils\n */\n\nimport type { BoxSides, PropertyDescriptor, StyleValue } from '../stylesmap.js';\n\nconst HEX_COLOR_REGEXP = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;\nconst RGB_COLOR_REGEXP = /^rgb\\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}[0-9]{1,3}[ %]?\\)$/i;\nconst RGBA_COLOR_REGEXP = /^rgba\\([ ]?([0-9]{1,3}[ %]?,[ ]?){3}(1|[0-9]+%|[0]?\\.?[0-9]+)\\)$/i;\nconst HSL_COLOR_REGEXP = /^hsl\\([ ]?([0-9]{1,3}[ %]?[,]?[ ]*){3}(1|[0-9]+%|[0]?\\.?[0-9]+)?\\)$/i;\nconst HSLA_COLOR_REGEXP = /^hsla\\([ ]?([0-9]{1,3}[ %]?,[ ]?){2,3}(1|[0-9]+%|[0]?\\.?[0-9]+)\\)$/i;\n\n// Note: This regexp hardcodes a single level of nested () for values such as `calc( var( ...) + ...)`.\n// If this gets more complex, a proper parser should be used instead.\nconst CSS_SHORTHAND_VALUE_REGEXP = /\\w+\\((?:[^()]|\\([^()]*\\))*\\)|\\S+/gi;\n\nconst COLOR_NAMES = new Set( [\n\t// CSS Level 1\n\t'black', 'silver', 'gray', 'white', 'maroon', 'red', 'purple', 'fuchsia',\n\t'green', 'lime', 'olive', 'yellow', 'navy', 'blue', 'teal', 'aqua',\n\t// CSS Level 2 (Revision 1)\n\t'orange',\n\t// CSS Color Module Level 3\n\t'aliceblue', 'antiquewhite', 'aquamarine', 'azure', 'beige', 'bisque', 'blanchedalmond', 'blueviolet', 'brown',\n\t'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan',\n\t'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta',\n\t'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue',\n\t'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey',\n\t'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod',\n\t'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush',\n\t'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray',\n\t'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray',\n\t'lightslategrey', 'lightsteelblue', 'lightyellow', 'limegreen', 'linen', 'magenta', 'mediumaquamarine',\n\t'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen',\n\t'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite',\n\t'oldlace', 'olivedrab', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred',\n\t'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon',\n\t'sandybrown', 'seagreen', 'seashell', 'sienna', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow',\n\t'springgreen', 'steelblue', 'tan', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'whitesmoke', 'yellowgreen',\n\t// CSS Color Module Level 3 (System Colors)\n\t'activeborder', 'activecaption', 'appworkspace', 'background', 'buttonface', 'buttonhighlight', 'buttonshadow',\n\t'buttontext', 'captiontext', 'graytext', 'highlight', 'highlighttext', 'inactiveborder', 'inactivecaption',\n\t'inactivecaptiontext', 'infobackground', 'infotext', 'menu', 'menutext', 'scrollbar', 'threeddarkshadow',\n\t'threedface', 'threedhighlight', 'threedlightshadow', 'threedshadow', 'window', 'windowframe', 'windowtext',\n\t// CSS Color Module Level 4\n\t'rebeccapurple',\n\t// Keywords\n\t'currentcolor', 'transparent'\n] );\n\n/**\n * Checks if string contains [color](https://developer.mozilla.org/en-US/docs/Web/CSS/color) CSS value.\n *\n * ```ts\n * isColor( '#f00' );\t\t\t\t\t\t// true\n * isColor( '#AA00BB33' );\t\t\t\t\t// true\n * isColor( 'rgb(0, 0, 250)' );\t\t\t\t// true\n * isColor( 'hsla(240, 100%, 50%, .7)' );\t// true\n * isColor( 'deepskyblue' );\t\t\t\t// true\n * ```\n *\n * **Note**: It does not support CSS Level 4 whitespace syntax, system colors and radius values for HSL colors.\n */\nexport function isColor( string: string ): boolean {\n\t// As far as I was able to test checking some pre-conditions is faster than joining each test with ||.\n\tif ( string.startsWith( '#' ) ) {\n\t\treturn HEX_COLOR_REGEXP.test( string );\n\t}\n\n\tif ( string.startsWith( 'rgb' ) ) {\n\t\treturn RGB_COLOR_REGEXP.test( string ) || RGBA_COLOR_REGEXP.test( string );\n\t}\n\n\tif ( string.startsWith( 'hsl' ) ) {\n\t\treturn HSL_COLOR_REGEXP.test( string ) || HSLA_COLOR_REGEXP.test( string );\n\t}\n\n\t// Array check > RegExp test.\n\treturn COLOR_NAMES.has( string.toLowerCase() );\n}\n\nconst lineStyleValues = [ 'none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset' ];\n\n/**\n * Checks if string contains [line style](https://developer.mozilla.org/en-US/docs/Web/CSS/border-style) CSS value.\n */\nexport function isLineStyle( string: string ): boolean {\n\treturn lineStyleValues.includes( string );\n}\n\nconst lengthRegExp = /^([+-]?[0-9]*([.][0-9]+)?(px|cm|mm|in|pc|pt|ch|em|ex|rem|vh|vw|vmin|vmax)|0)$/;\n\n/**\n * Checks if string contains [length](https://developer.mozilla.org/en-US/docs/Web/CSS/length) CSS value.\n */\nexport function isLength( string: string ): boolean {\n\treturn lengthRegExp.test( string );\n}\n\nconst PERCENTAGE_VALUE_REGEXP = /^[+-]?[0-9]*([.][0-9]+)?%$/;\n\n/**\n * Checks if string contains [percentage](https://developer.mozilla.org/en-US/docs/Web/CSS/percentage) CSS value.\n */\nexport function isPercentage( string: string ): boolean {\n\treturn PERCENTAGE_VALUE_REGEXP.test( string );\n}\n\nconst repeatValues = [ 'repeat-x', 'repeat-y', 'repeat', 'space', 'round', 'no-repeat' ];\n\n/**\n * Checks if string contains [background repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/background-repeat) CSS value.\n */\nexport function isRepeat( string: string ): boolean {\n\treturn repeatValues.includes( string );\n}\n\nconst positionValues = [ 'center', 'top', 'bottom', 'left', 'right' ];\n\n/**\n * Checks if string contains [background position](https://developer.mozilla.org/en-US/docs/Web/CSS/background-position) CSS value.\n */\nexport function isPosition( string: string ): boolean {\n\treturn positionValues.includes( string );\n}\n\nconst attachmentValues = [ 'fixed', 'scroll', 'local' ];\n\n/**\n * Checks if string contains [background attachment](https://developer.mozilla.org/en-US/docs/Web/CSS/background-attachment) CSS value.\n */\nexport function isAttachment( string: string ): boolean {\n\treturn attachmentValues.includes( string );\n}\n\nconst urlRegExp = /^url\\(/;\n\n/**\n * Checks if string contains [URL](https://developer.mozilla.org/en-US/docs/Web/CSS/url) CSS value.\n */\nexport function isURL( string: string ): boolean {\n\treturn urlRegExp.test( string );\n}\n\n/**\n * Parses box sides as individual values.\n */\nexport function getBoxSidesValues( value: string = '' ): BoxSides {\n\tif ( value === '' ) {\n\t\treturn { top: undefined, right: undefined, bottom: undefined, left: undefined };\n\t}\n\n\tconst values = getShorthandValues( value );\n\n\tconst top = values[ 0 ];\n\tconst bottom = values[ 2 ] || top;\n\tconst right = values[ 1 ] || top;\n\tconst left = values[ 3 ] || right;\n\n\treturn { top, bottom, right, left };\n}\n\n/**\n * Default reducer for CSS properties that concerns edges of a box\n * [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) notations:\n *\n * ```ts\n * stylesProcessor.setReducer( 'padding', getBoxSidesValueReducer( 'padding' ) );\n * ```\n */\nexport function getBoxSidesValueReducer( styleShorthand: string ) {\n\treturn ( value: StyleValue ): Array<PropertyDescriptor> => {\n\t\tconst { top, right, bottom, left } = value as BoxSides;\n\n\t\tconst reduced: Array<PropertyDescriptor> = [];\n\n\t\tif ( ![ top, right, left, bottom ].every( value => !!value ) ) {\n\t\t\tif ( top ) {\n\t\t\t\treduced.push( [ styleShorthand + '-top', top ] );\n\t\t\t}\n\n\t\t\tif ( right ) {\n\t\t\t\treduced.push( [ styleShorthand + '-right', right ] );\n\t\t\t}\n\n\t\t\tif ( bottom ) {\n\t\t\t\treduced.push( [ styleShorthand + '-bottom', bottom ] );\n\t\t\t}\n\n\t\t\tif ( left ) {\n\t\t\t\treduced.push( [ styleShorthand + '-left', left ] );\n\t\t\t}\n\t\t} else {\n\t\t\treduced.push( [ styleShorthand, getBoxSidesShorthandValue( value as BoxSides ) ] );\n\t\t}\n\n\t\treturn reduced;\n\t};\n}\n\n/**\n * Returns a [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) notation\n * of a CSS property value.\n *\n * ```ts\n * getBoxSidesShorthandValue( { top: '1px', right: '1px', bottom: '2px', left: '1px' } );\n * // will return '1px 1px 2px'\n * ```\n */\nexport function getBoxSidesShorthandValue( { top, right, bottom, left }: BoxSides ): string {\n\tconst out = [];\n\n\tif ( left !== right ) {\n\t\tout.push( top, right, bottom, left );\n\t} else if ( bottom !== top ) {\n\t\tout.push( top, right, bottom );\n\t} else if ( right !== top ) {\n\t\tout.push( top, right );\n\t} else {\n\t\tout.push( top );\n\t}\n\n\treturn out.join( ' ' );\n}\n\n/**\n * Creates a normalizer for a [shorthand](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties) 1-to-4 value.\n *\n * ```ts\n * stylesProcessor.setNormalizer( 'margin', getPositionShorthandNormalizer( 'margin' ) );\n * ```\n */\nexport function getPositionShorthandNormalizer( shorthand: string ) {\n\treturn ( value: string ): { path: string; value: BoxSides } => {\n\t\treturn {\n\t\t\tpath: shorthand,\n\t\t\tvalue: getBoxSidesValues( value )\n\t\t};\n\t};\n}\n\n/**\n * Parses parts of a 1-to-4 value notation - handles some CSS values with spaces (like RGB()).\n *\n * ```ts\n * getShorthandValues( 'red blue RGB(0, 0, 0)');\n * // will return [ 'red', 'blue', 'RGB(0, 0, 0)' ]\n * ```\n */\nexport function getShorthandValues( string: string ): Array<string> {\n\tconst matches = string.trim().slice( 0, 1500 ).matchAll( CSS_SHORTHAND_VALUE_REGEXP );\n\n\treturn Array.from( matches ).map( i => i[ 0 ] );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/styles/background\n */\n\nimport type { StylesProcessor, PropertyDescriptor, Styles, Normalizer, Reducer } from '../stylesmap.js';\nimport { getShorthandValues, isAttachment, isColor, isPosition, isRepeat, isURL } from './utils.js';\n\n/**\n * Adds a background CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addBackgroundRules );\n * ```\n *\n * The normalized value is stored as:\n *\n * ```ts\n * const styles = {\n * \tbackground: {\n * \t\tcolor,\n * \t\trepeat,\n * \t\tposition,\n * \t\tattachment,\n * \t\timage\n * \t}\n * };\n * ````\n *\n * **Note**: Currently only `'background-color'` longhand value is parsed besides `'background'` shorthand. The reducer also supports only\n * `'background-color'` value.\n */\nexport function addBackgroundRules( stylesProcessor: StylesProcessor ): void {\n\tstylesProcessor.setNormalizer( 'background', getBackgroundNormalizer() );\n\tstylesProcessor.setNormalizer( 'background-color', getBackgroundColorNormalizer() );\n\tstylesProcessor.setReducer( 'background', getBackgroundReducer() );\n\n\tstylesProcessor.setStyleRelation( 'background', [ 'background-color' ] );\n}\n\nfunction getBackgroundNormalizer(): Normalizer {\n\treturn value => {\n\t\tconst background: {\n\t\t\trepeat?: Array<string>;\n\t\t\tposition?: Array<string>;\n\t\t\tattachment?: string;\n\t\t\tcolor?: string;\n\t\t\timage?: string;\n\t\t} = {};\n\n\t\tconst parts = getShorthandValues( value );\n\n\t\tfor ( const part of parts ) {\n\t\t\tif ( isRepeat( part ) ) {\n\t\t\t\tbackground.repeat = background.repeat || [];\n\n\t\t\t\tbackground.repeat.push( part );\n\t\t\t} else if ( isPosition( part ) ) {\n\t\t\t\tbackground.position = background.position || [];\n\n\t\t\t\tbackground.position.push( part );\n\t\t\t} else if ( isAttachment( part ) ) {\n\t\t\t\tbackground.attachment = part;\n\t\t\t} else if ( isColor( part ) ) {\n\t\t\t\tbackground.color = part;\n\t\t\t} else if ( isURL( part ) ) {\n\t\t\t\tbackground.image = part;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tpath: 'background',\n\t\t\tvalue: background\n\t\t};\n\t};\n}\n\nfunction getBackgroundColorNormalizer(): Normalizer {\n\treturn value => ( { path: 'background.color', value } );\n}\n\nfunction getBackgroundReducer(): Reducer {\n\treturn value => {\n\t\tconst ret: Array<PropertyDescriptor> = [];\n\n\t\tret.push( [ 'background-color', ( value as Styles ).color as string ] );\n\n\t\treturn ret;\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/styles/border\n */\n\nimport type { BoxSides, Extractor, Normalizer, Reducer, StylesProcessor, Styles, StyleValue, PropertyDescriptor } from '../stylesmap.js';\nimport { getShorthandValues, getBoxSidesValueReducer, getBoxSidesValues, isLength, isLineStyle } from './utils.js';\n\n/**\n * Adds a border CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addBorderRules );\n * ```\n *\n * This rules merges all [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border) styles notation shorthands:\n *\n * - border\n * - border-top\n * - border-right\n * - border-bottom\n * - border-left\n * - border-color\n * - border-style\n * - border-width\n *\n * and all corresponding longhand forms (like `border-top-color`, `border-top-style`, etc).\n *\n * It does not handle other shorthands (like `border-radius` or `border-image`).\n *\n * The normalized model stores border values as:\n *\n * ```ts\n * const styles = {\n * \tborder: {\n * \t\tcolor: { top, right, bottom, left },\n * \t\tstyle: { top, right, bottom, left },\n * \t\twidth: { top, right, bottom, left },\n * \t}\n * };\n * ```\n */\nexport function addBorderRules( stylesProcessor: StylesProcessor ): void {\n\tstylesProcessor.setNormalizer( 'border', getBorderNormalizer() );\n\n\t// Border-position shorthands.\n\tstylesProcessor.setNormalizer( 'border-top', getBorderPositionNormalizer( 'top' ) );\n\tstylesProcessor.setNormalizer( 'border-right', getBorderPositionNormalizer( 'right' ) );\n\tstylesProcessor.setNormalizer( 'border-bottom', getBorderPositionNormalizer( 'bottom' ) );\n\tstylesProcessor.setNormalizer( 'border-left', getBorderPositionNormalizer( 'left' ) );\n\n\t// Border-property shorthands.\n\tstylesProcessor.setNormalizer( 'border-color', getBorderPropertyNormalizer( 'color' ) );\n\tstylesProcessor.setNormalizer( 'border-width', getBorderPropertyNormalizer( 'width' ) );\n\tstylesProcessor.setNormalizer( 'border-style', getBorderPropertyNormalizer( 'style' ) );\n\n\t// Border longhands.\n\tstylesProcessor.setNormalizer( 'border-top-color', getBorderPropertyPositionNormalizer( 'color', 'top' ) );\n\tstylesProcessor.setNormalizer( 'border-top-style', getBorderPropertyPositionNormalizer( 'style', 'top' ) );\n\tstylesProcessor.setNormalizer( 'border-top-width', getBorderPropertyPositionNormalizer( 'width', 'top' ) );\n\n\tstylesProcessor.setNormalizer( 'border-right-color', getBorderPropertyPositionNormalizer( 'color', 'right' ) );\n\tstylesProcessor.setNormalizer( 'border-right-style', getBorderPropertyPositionNormalizer( 'style', 'right' ) );\n\tstylesProcessor.setNormalizer( 'border-right-width', getBorderPropertyPositionNormalizer( 'width', 'right' ) );\n\n\tstylesProcessor.setNormalizer( 'border-bottom-color', getBorderPropertyPositionNormalizer( 'color', 'bottom' ) );\n\tstylesProcessor.setNormalizer( 'border-bottom-style', getBorderPropertyPositionNormalizer( 'style', 'bottom' ) );\n\tstylesProcessor.setNormalizer( 'border-bottom-width', getBorderPropertyPositionNormalizer( 'width', 'bottom' ) );\n\n\tstylesProcessor.setNormalizer( 'border-left-color', getBorderPropertyPositionNormalizer( 'color', 'left' ) );\n\tstylesProcessor.setNormalizer( 'border-left-style', getBorderPropertyPositionNormalizer( 'style', 'left' ) );\n\tstylesProcessor.setNormalizer( 'border-left-width', getBorderPropertyPositionNormalizer( 'width', 'left' ) );\n\n\tstylesProcessor.setExtractor( 'border-top', getBorderPositionExtractor( 'top' ) );\n\tstylesProcessor.setExtractor( 'border-right', getBorderPositionExtractor( 'right' ) );\n\tstylesProcessor.setExtractor( 'border-bottom', getBorderPositionExtractor( 'bottom' ) );\n\tstylesProcessor.setExtractor( 'border-left', getBorderPositionExtractor( 'left' ) );\n\n\tstylesProcessor.setExtractor( 'border-top-color', 'border.color.top' );\n\tstylesProcessor.setExtractor( 'border-right-color', 'border.color.right' );\n\tstylesProcessor.setExtractor( 'border-bottom-color', 'border.color.bottom' );\n\tstylesProcessor.setExtractor( 'border-left-color', 'border.color.left' );\n\n\tstylesProcessor.setExtractor( 'border-top-width', 'border.width.top' );\n\tstylesProcessor.setExtractor( 'border-right-width', 'border.width.right' );\n\tstylesProcessor.setExtractor( 'border-bottom-width', 'border.width.bottom' );\n\tstylesProcessor.setExtractor( 'border-left-width', 'border.width.left' );\n\n\tstylesProcessor.setExtractor( 'border-top-style', 'border.style.top' );\n\tstylesProcessor.setExtractor( 'border-right-style', 'border.style.right' );\n\tstylesProcessor.setExtractor( 'border-bottom-style', 'border.style.bottom' );\n\tstylesProcessor.setExtractor( 'border-left-style', 'border.style.left' );\n\n\tstylesProcessor.setReducer( 'border-color', getBoxSidesValueReducer( 'border-color' ) );\n\tstylesProcessor.setReducer( 'border-style', getBoxSidesValueReducer( 'border-style' ) );\n\tstylesProcessor.setReducer( 'border-width', getBoxSidesValueReducer( 'border-width' ) );\n\tstylesProcessor.setReducer( 'border-top', getBorderPositionReducer( 'top' ) );\n\tstylesProcessor.setReducer( 'border-right', getBorderPositionReducer( 'right' ) );\n\tstylesProcessor.setReducer( 'border-bottom', getBorderPositionReducer( 'bottom' ) );\n\tstylesProcessor.setReducer( 'border-left', getBorderPositionReducer( 'left' ) );\n\tstylesProcessor.setReducer( 'border', getBorderReducer() );\n\n\tstylesProcessor.setStyleRelation( 'border', [\n\t\t'border-color', 'border-style', 'border-width',\n\t\t'border-top', 'border-right', 'border-bottom', 'border-left',\n\t\t'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color',\n\t\t'border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style',\n\t\t'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'\n\t] );\n\n\tstylesProcessor.setStyleRelation( 'border-color', [\n\t\t'border-top-color', 'border-right-color', 'border-bottom-color', 'border-left-color'\n\t] );\n\tstylesProcessor.setStyleRelation( 'border-style', [\n\t\t'border-top-style', 'border-right-style', 'border-bottom-style', 'border-left-style'\n\t] );\n\tstylesProcessor.setStyleRelation( 'border-width', [\n\t\t'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'\n\t] );\n\n\tstylesProcessor.setStyleRelation( 'border-top', [ 'border-top-color', 'border-top-style', 'border-top-width' ] );\n\tstylesProcessor.setStyleRelation( 'border-right', [ 'border-right-color', 'border-right-style', 'border-right-width' ] );\n\tstylesProcessor.setStyleRelation( 'border-bottom', [ 'border-bottom-color', 'border-bottom-style', 'border-bottom-width' ] );\n\tstylesProcessor.setStyleRelation( 'border-left', [ 'border-left-color', 'border-left-style', 'border-left-width' ] );\n}\n\nfunction getBorderNormalizer(): Normalizer {\n\treturn value => {\n\t\tconst { color, style, width } = normalizeBorderShorthand( value );\n\n\t\treturn {\n\t\t\tpath: 'border',\n\t\t\tvalue: {\n\t\t\t\tcolor: getBoxSidesValues( color ),\n\t\t\t\tstyle: getBoxSidesValues( style ),\n\t\t\t\twidth: getBoxSidesValues( width )\n\t\t\t}\n\t\t};\n\t};\n}\n\nfunction getBorderPositionNormalizer( side: string ): Normalizer {\n\treturn value => {\n\t\tconst { color, style, width } = normalizeBorderShorthand( value );\n\n\t\tconst border: Record<string, StyleValue> = {};\n\n\t\tif ( color !== undefined ) {\n\t\t\tborder.color = { [ side ]: color };\n\t\t}\n\n\t\tif ( style !== undefined ) {\n\t\t\tborder.style = { [ side ]: style };\n\t\t}\n\n\t\tif ( width !== undefined ) {\n\t\t\tborder.width = { [ side ]: width };\n\t\t}\n\n\t\treturn {\n\t\t\tpath: 'border',\n\t\t\tvalue: border\n\t\t};\n\t};\n}\n\nfunction getBorderPropertyNormalizer( propertyName: string ): Normalizer {\n\treturn value => {\n\t\treturn {\n\t\t\tpath: 'border',\n\t\t\tvalue: toBorderPropertyShorthand( value, propertyName )\n\t\t};\n\t};\n}\n\nfunction toBorderPropertyShorthand( value: string, property: string ): Record<string, BoxSides> {\n\treturn {\n\t\t[ property ]: getBoxSidesValues( value )\n\t};\n}\n\nfunction getBorderPropertyPositionNormalizer( property: string, side: keyof BoxSides ): Normalizer {\n\treturn value => {\n\t\treturn {\n\t\t\tpath: 'border',\n\t\t\tvalue: {\n\t\t\t\t[ property ]: {\n\t\t\t\t\t[ side ]: value\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t};\n}\n\nfunction getBorderPositionExtractor( which: string ): Extractor {\n\treturn ( name, styles ) => {\n\t\tif ( styles.border ) {\n\t\t\treturn extractBorderPosition( styles.border, which );\n\t\t}\n\t};\n}\n\nfunction extractBorderPosition( border: any, which: string ) {\n\tconst value: StyleValue = {};\n\n\tif ( border.width && border.width[ which ] ) {\n\t\tvalue.width = border.width[ which ];\n\t}\n\n\tif ( border.style && border.style[ which ] ) {\n\t\tvalue.style = border.style[ which ];\n\t}\n\n\tif ( border.color && border.color[ which ] ) {\n\t\tvalue.color = border.color[ which ];\n\t}\n\n\treturn value;\n}\n\nfunction normalizeBorderShorthand( string: string ) {\n\tconst result: {\n\t\twidth?: string;\n\t\tstyle?: string;\n\t\tcolor?: string;\n\t} = {};\n\n\tconst parts = getShorthandValues( string );\n\n\tfor ( const part of parts ) {\n\t\tif ( isLength( part ) || /thin|medium|thick/.test( part ) ) {\n\t\t\tresult.width = part;\n\t\t} else if ( isLineStyle( part ) ) {\n\t\t\tresult.style = part;\n\t\t} else {\n\t\t\tresult.color = part;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * The border reducer factory.\n *\n * It tries to produce the most optimal output for the specified styles.\n *\n * For a border style:\n *\n * ```css\n * style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n * ```\n *\n * It will produce: `border-style: solid`.\n * For a border style and color:\n *\n * ```css\n * color: {top: \"#ff0\", bottom: \"#ff0\", right: \"#ff0\", left: \"#ff0\"}\n * style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n * ```\n *\n * It will produce: `border-color: #ff0; border-style: solid`.\n * If all border parameters are specified:\n *\n * ```css\n * color: {top: \"#ff0\", bottom: \"#ff0\", right: \"#ff0\", left: \"#ff0\"}\n * style: {top: \"solid\", bottom: \"solid\", right: \"solid\", left: \"solid\"}\n * width: {top: \"2px\", bottom: \"2px\", right: \"2px\", left: \"2px\"}\n * ```\n *\n * It will combine everything into a single property: `border: 2px solid #ff0`.\n *\n * The definitions are merged only if all border selectors have the same values.\n */\nfunction getBorderReducer(): Reducer {\n\treturn value => {\n\t\tconst topStyles = extractBorderPosition( value, 'top' );\n\t\tconst rightStyles = extractBorderPosition( value, 'right' );\n\t\tconst bottomStyles = extractBorderPosition( value, 'bottom' );\n\t\tconst leftStyles = extractBorderPosition( value, 'left' );\n\n\t\tconst borderStyles = [ topStyles, rightStyles, bottomStyles, leftStyles ];\n\n\t\tconst borderStylesByType = {\n\t\t\twidth: getReducedStyleValueForType( borderStyles, 'width' ),\n\t\t\tstyle: getReducedStyleValueForType( borderStyles, 'style' ),\n\t\t\tcolor: getReducedStyleValueForType( borderStyles, 'color' )\n\t\t};\n\n\t\t// Try reducing to a single `border:` property.\n\t\tconst reducedBorderStyle = reduceBorderPosition( borderStylesByType, 'all' );\n\n\t\tif ( reducedBorderStyle.length ) {\n\t\t\treturn reducedBorderStyle;\n\t\t}\n\n\t\t// Try reducing to `border-style:`, `border-width:`, `border-color:` properties.\n\t\tconst reducedStyleTypes = Object.entries( borderStylesByType ).reduce( ( reducedStyleTypes, [ type, value ] ) => {\n\t\t\tif ( value ) {\n\t\t\t\treducedStyleTypes.push( [ `border-${ type }`, value ] );\n\n\t\t\t\t// Remove it from the full set to not include it in the most specific properties later.\n\t\t\t\tborderStyles.forEach( style => delete style[ type ] );\n\t\t\t}\n\n\t\t\treturn reducedStyleTypes;\n\t\t}, [] as Array<PropertyDescriptor> );\n\n\t\t// The reduced properties (by type) and all that remains that could not be reduced.\n\t\treturn [\n\t\t\t...reducedStyleTypes,\n\t\t\t...reduceBorderPosition( topStyles, 'top' ),\n\t\t\t...reduceBorderPosition( rightStyles, 'right' ),\n\t\t\t...reduceBorderPosition( bottomStyles, 'bottom' ),\n\t\t\t...reduceBorderPosition( leftStyles, 'left' )\n\t\t];\n\t};\n\n\t/**\n\t * @param styles The array of objects with `style`, `color`, `width` properties.\n\t */\n\tfunction getReducedStyleValueForType( styles: Array<Styles>, type: 'width' | 'style' | 'color' ) {\n\t\treturn styles\n\t\t\t.map( style => style[ type ] as any )\n\t\t\t.reduce( ( result, style ) => result == style ? result : null );\n\t}\n}\n\nfunction getBorderPositionReducer( which: keyof BoxSides | 'all' ): Reducer {\n\treturn value => reduceBorderPosition( value, which );\n}\n\n/**\n * Returns an array with reduced border styles depending on the specified values.\n *\n * If all border properties (width, style, color) are specified, the returned selector will be\n * merged into a group: `border-*: [width] [style] [color]`.\n *\n * Otherwise, the specific definitions will be returned: `border-(width|style|color)-*: [value]`.\n *\n * @param value Styles if defined.\n * @param which The border position.\n */\nfunction reduceBorderPosition( value: any, which: keyof BoxSides | 'all' ): Array<PropertyDescriptor> {\n\tconst borderTypes = [];\n\n\tif ( value && ( value.width ) ) {\n\t\tborderTypes.push( 'width' );\n\t}\n\n\tif ( value && ( value.style ) ) {\n\t\tborderTypes.push( 'style' );\n\t}\n\n\tif ( value && ( value.color ) ) {\n\t\tborderTypes.push( 'color' );\n\t}\n\n\tif ( borderTypes.length == 3 ) {\n\t\tconst borderValue = borderTypes.map( item => value[ item ] ).join( ' ' );\n\n\t\treturn [\n\t\t\twhich == 'all' ? [ 'border', borderValue ] : [ `border-${ which }`, borderValue ]\n\t\t];\n\t}\n\n\t// We are unable to reduce to a single `border:` property.\n\tif ( which == 'all' ) {\n\t\treturn [];\n\t}\n\n\treturn borderTypes.map( type => {\n\t\treturn [ `border-${ which }-${ type }`, value[ type ] as string ];\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/styles/margin\n */\n\nimport type { StylesProcessor } from '../stylesmap.js';\nimport { getPositionShorthandNormalizer, getBoxSidesValueReducer } from './utils.js';\n\n/**\n * Adds a margin CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addMarginRules );\n * ```\n *\n * The normalized value is stored as:\n *\n * ```ts\n * const styles = {\n * \tmargin: {\n * \t\ttop,\n * \t\tright,\n * \t\tbottom,\n * \t\tleft\n * \t}\n * };\n * ```\n */\nexport function addMarginRules( stylesProcessor: StylesProcessor ): void {\n\tstylesProcessor.setNormalizer( 'margin', getPositionShorthandNormalizer( 'margin' ) );\n\n\tstylesProcessor.setNormalizer( 'margin-top', value => ( { path: 'margin.top', value } ) );\n\tstylesProcessor.setNormalizer( 'margin-right', value => ( { path: 'margin.right', value } ) );\n\tstylesProcessor.setNormalizer( 'margin-bottom', value => ( { path: 'margin.bottom', value } ) );\n\tstylesProcessor.setNormalizer( 'margin-left', value => ( { path: 'margin.left', value } ) );\n\n\tstylesProcessor.setReducer( 'margin', getBoxSidesValueReducer( 'margin' ) );\n\n\tstylesProcessor.setStyleRelation( 'margin', [ 'margin-top', 'margin-right', 'margin-bottom', 'margin-left' ] );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/view/styles/padding\n */\n\nimport type { StylesProcessor } from '../stylesmap.js';\nimport { getPositionShorthandNormalizer, getBoxSidesValueReducer } from './utils.js';\n\n/**\n * Adds a padding CSS styles processing rules.\n *\n * ```ts\n * editor.data.addStyleProcessorRules( addPaddingRules );\n * ```\n *\n * The normalized value is stored as:\n *\n * ```ts\n * const styles = {\n * \tpadding: {\n * \t\ttop,\n * \t\tright,\n * \t\tbottom,\n * \t\tleft\n * \t}\n * };\n * ```\n */\nexport function addPaddingRules( stylesProcessor: StylesProcessor ): void {\n\tstylesProcessor.setNormalizer( 'padding', getPositionShorthandNormalizer( 'padding' ) );\n\tstylesProcessor.setNormalizer( 'padding-top', value => ( { path: 'padding.top', value } ) );\n\tstylesProcessor.setNormalizer( 'padding-right', value => ( { path: 'padding.right', value } ) );\n\tstylesProcessor.setNormalizer( 'padding-bottom', value => ( { path: 'padding.bottom', value } ) );\n\tstylesProcessor.setNormalizer( 'padding-left', value => ( { path: 'padding.left', value } ) );\n\n\tstylesProcessor.setReducer( 'padding', getBoxSidesValueReducer( 'padding' ) );\n\n\tstylesProcessor.setStyleRelation( 'padding', [ 'padding-top', 'padding-right', 'padding-bottom', 'padding-left' ] );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/dev-utils/view\n */\n\n/* globals document */\n\n/**\n * Collection of methods for manipulating the {@link module:engine/view/view view} for testing purposes.\n */\n\nimport View from '../view/view.js';\nimport ViewDocument from '../view/document.js';\nimport ViewDocumentFragment from '../view/documentfragment.js';\nimport XmlDataProcessor from '../dataprocessor/xmldataprocessor.js';\nimport ViewElement from '../view/element.js';\nimport DocumentSelection from '../view/documentselection.js';\nimport Range from '../view/range.js';\nimport Position from '../view/position.js';\nimport AttributeElement from '../view/attributeelement.js';\nimport ContainerElement from '../view/containerelement.js';\nimport EmptyElement from '../view/emptyelement.js';\nimport UIElement from '../view/uielement.js';\nimport RawElement from '../view/rawelement.js';\nimport { StylesProcessor } from '../view/stylesmap.js';\n\nimport type ViewNode from '../view/node.js';\nimport type ViewText from '../view/text.js';\nimport type DomConverter from '../view/domconverter.js';\n\nconst ELEMENT_RANGE_START_TOKEN = '[';\nconst ELEMENT_RANGE_END_TOKEN = ']';\nconst TEXT_RANGE_START_TOKEN = '{';\nconst TEXT_RANGE_END_TOKEN = '}';\nconst allowedTypes = {\n\t'container': ContainerElement,\n\t'attribute': AttributeElement,\n\t'empty': EmptyElement,\n\t'ui': UIElement,\n\t'raw': RawElement\n};\n// Returns simplified implementation of {@link module:engine/view/domconverter~DomConverter#setContentOf DomConverter.setContentOf} method.\n// Used to render UIElement and RawElement.\nconst domConverterStub: DomConverter = {\n\tsetContentOf: ( node: any, html: string ) => {\n\t\tnode.innerHTML = html;\n\t}\n} as any;\n\n/**\n * Writes the content of the {@link module:engine/view/document~Document document} to an HTML-like string.\n *\n * @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will\n * not be included in the returned string.\n * @param options.rootName The name of the root from which the data should be stringified. If not provided,\n * the default `main` name will be used.\n * @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n * instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n * @param options.showPriority When set to `true`, the attribute element's priority will be printed\n * (`<span view-priority=\"12\">`, `<b view-priority=\"10\">`).\n * @param options.showAttributeElementId When set to `true`, the attribute element's ID will be printed\n * (`<span id=\"marker:foo\">`).\n * @param options.renderUIElements When set to `true`, the inner content of each\n * {@link module:engine/view/uielement~UIElement} will be printed.\n * @param options.renderRawElements When set to `true`, the inner content of each\n * {@link module:engine/view/rawelement~RawElement} will be printed.\n * @param options.domConverter When set to an actual {@link module:engine/view/domconverter~DomConverter DomConverter}\n * instance, it lets the conversion go through exactly the same flow the editing view is going through,\n * i.e. with view data filtering. Otherwise the simple stub is used.\n * @returns The stringified data.\n */\nexport function getData(\n\tview: View,\n\toptions: {\n\t\twithoutSelection?: boolean;\n\t\trootName?: string;\n\t\tshowType?: boolean;\n\t\tshowPriority?: boolean;\n\t\trenderUIElements?: boolean;\n\t\trenderRawElements?: boolean;\n\t\tdomConverter?: DomConverter;\n\t} = {}\n): string {\n\tif ( !( view instanceof View ) ) {\n\t\tthrow new TypeError( 'View needs to be an instance of module:engine/view/view~View.' );\n\t}\n\n\tconst document = view.document;\n\tconst withoutSelection = !!options.withoutSelection;\n\tconst rootName = options.rootName || 'main';\n\tconst root = document.getRoot( rootName )!;\n\tconst stringifyOptions = {\n\t\tshowType: options.showType,\n\t\tshowPriority: options.showPriority,\n\t\trenderUIElements: options.renderUIElements,\n\t\trenderRawElements: options.renderRawElements,\n\t\tignoreRoot: true,\n\t\tdomConverter: options.domConverter\n\t};\n\n\treturn withoutSelection ?\n\t\tgetData._stringify( root, null, stringifyOptions ) :\n\t\tgetData._stringify( root, document.selection, stringifyOptions );\n}\n\n// Set stringify as getData private method - needed for testing/spying.\ngetData._stringify = stringify;\n\n/**\n * Sets the content of a view {@link module:engine/view/document~Document document} provided as an HTML-like string.\n *\n * @param data An HTML-like string to write into the document.\n * @param options.rootName The root name where parsed data will be stored. If not provided,\n * the default `main` name will be used.\n */\nexport function setData(\n\tview: View,\n\tdata: string,\n\toptions: { rootName?: string } = {}\n): void {\n\tif ( !( view instanceof View ) ) {\n\t\tthrow new TypeError( 'View needs to be an instance of module:engine/view/view~View.' );\n\t}\n\n\tconst document = view.document;\n\tconst rootName = options.rootName || 'main';\n\tconst root = document.getRoot( rootName )!;\n\n\tview.change( writer => {\n\t\tconst result: any = setData._parse( data, { rootElement: root } );\n\n\t\tif ( result.view && result.selection ) {\n\t\t\twriter.setSelection( result.selection );\n\t\t}\n\t} );\n}\n\n// Set parse as setData private method - needed for testing/spying.\nsetData._parse = parse;\n\n/**\n * Converts view elements to HTML-like string representation.\n *\n * A root element can be provided as {@link module:engine/view/text~Text text}:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * stringify( text ); // 'foobar'\n * ```\n *\n * or as an {@link module:engine/view/element~Element element}:\n *\n * ```ts\n * const element = downcastWriter.createElement( 'p', null, downcastWriter.createText( 'foobar' ) );\n * stringify( element ); // '<p>foobar</p>'\n * ```\n *\n * or as a {@link module:engine/view/documentfragment~DocumentFragment document fragment}:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const b = downcastWriter.createElement( 'b', { name: 'test' }, text );\n * const p = downcastWriter.createElement( 'p', { style: 'color:red;' } );\n * const fragment = downcastWriter.createDocumentFragment( [ p, b ] );\n *\n * stringify( fragment ); // '<p style=\"color:red;\"></p><b name=\"test\">foobar</b>'\n * ```\n *\n * Additionally, a {@link module:engine/view/documentselection~DocumentSelection selection} instance can be provided.\n * Ranges from the selection will then be included in the output data.\n * If a range position is placed inside the element node, it will be represented with `[` and `]`:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const b = downcastWriter.createElement( 'b', null, text );\n * const p = downcastWriter.createElement( 'p', null, b );\n * const selection = downcastWriter.createSelection(\n * \tdowncastWriter.createRangeIn( p )\n * );\n *\n * stringify( p, selection ); // '<p>[<b>foobar</b>]</p>'\n * ```\n *\n * If a range is placed inside the text node, it will be represented with `{` and `}`:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const b = downcastWriter.createElement( 'b', null, text );\n * const p = downcastWriter.createElement( 'p', null, b );\n * const selection = downcastWriter.createSelection(\n * \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 1 ), downcastWriter.createPositionAt( text, 5 ) )\n * );\n *\n * stringify( p, selection ); // '<p><b>f{ooba}r</b></p>'\n * ```\n *\n * ** Note: **\n * It is possible to unify selection markers to `[` and `]` for both (inside and outside text)\n * by setting the `sameSelectionCharacters=true` option. It is mainly used when the view stringify option is used by\n * model utilities.\n *\n * Multiple ranges are supported:\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const selection = downcastWriter.createSelection( [\n * \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) ),\n * \tdowncastWriter.createRange( downcastWriter.createPositionAt( text, 3 ), downcastWriter.createPositionAt( text, 5 ) )\n * ] );\n *\n * stringify( text, selection ); // '{f}oo{ba}r'\n * ```\n *\n * A {@link module:engine/view/range~Range range} or {@link module:engine/view/position~Position position} instance can be provided\n * instead of the {@link module:engine/view/documentselection~DocumentSelection selection} instance. If a range instance\n * is provided, it will be converted to a selection containing this range. If a position instance is provided, it will\n * be converted to a selection containing one range collapsed at this position.\n *\n * ```ts\n * const text = downcastWriter.createText( 'foobar' );\n * const range = downcastWriter.createRange( downcastWriter.createPositionAt( text, 0 ), downcastWriter.createPositionAt( text, 1 ) );\n * const position = downcastWriter.createPositionAt( text, 3 );\n *\n * stringify( text, range ); // '{f}oobar'\n * stringify( text, position ); // 'foo{}bar'\n * ```\n *\n * An additional `options` object can be provided.\n * If `options.showType` is set to `true`, element's types will be\n * presented for {@link module:engine/view/attributeelement~AttributeElement attribute elements},\n * {@link module:engine/view/containerelement~ContainerElement container elements}\n * {@link module:engine/view/emptyelement~EmptyElement empty elements}\n * and {@link module:engine/view/uielement~UIElement UI elements}:\n *\n * ```ts\n * const attribute = downcastWriter.createAttributeElement( 'b' );\n * const container = downcastWriter.createContainerElement( 'p' );\n * const empty = downcastWriter.createEmptyElement( 'img' );\n * const ui = downcastWriter.createUIElement( 'span' );\n * getData( attribute, null, { showType: true } ); // '<attribute:b></attribute:b>'\n * getData( container, null, { showType: true } ); // '<container:p></container:p>'\n * getData( empty, null, { showType: true } ); // '<empty:img></empty:img>'\n * getData( ui, null, { showType: true } ); // '<ui:span></ui:span>'\n * ```\n *\n * If `options.showPriority` is set to `true`, a priority will be displayed for all\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements}.\n *\n * ```ts\n * const attribute = downcastWriter.createAttributeElement( 'b' );\n * attribute._priority = 20;\n * getData( attribute, null, { showPriority: true } ); // <b view-priority=\"20\"></b>\n * ```\n *\n * If `options.showAttributeElementId` is set to `true`, the attribute element's id will be displayed for all\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements} that have it set.\n *\n * ```ts\n * const attribute = downcastWriter.createAttributeElement( 'span' );\n * attribute._id = 'marker:foo';\n * getData( attribute, null, { showAttributeElementId: true } ); // <span view-id=\"marker:foo\"></span>\n * ```\n *\n * @param node The node to stringify.\n * @param selectionOrPositionOrRange A selection instance whose ranges will be included in the returned string data.\n * If a range instance is provided, it will be converted to a selection containing this range. If a position instance\n * is provided, it will be converted to a selection containing one range collapsed at this position.\n * @param options An object with additional options.\n * @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n * instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n * @param options.showPriority When set to `true`,  the attribute element's priority will be printed\n * (`<span view-priority=\"12\">`, `<b view-priority=\"10\">`).\n * @param options.showAttributeElementId When set to `true`, attribute element's id will be printed\n * (`<span id=\"marker:foo\">`).\n * @param options.ignoreRoot When set to `true`, the root's element opening and closing will not be printed.\n * Mainly used by the `getData` function to ignore the {@link module:engine/view/document~Document document's} root element.\n * @param options.sameSelectionCharacters When set to `true`, the selection inside the text will be marked as\n *  `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both will be marked as `[` and `]` only.\n * @param options.renderUIElements When set to `true`, the inner content of each\n * {@link module:engine/view/uielement~UIElement} will be printed.\n * @param options.renderRawElements When set to `true`, the inner content of each\n * {@link module:engine/view/rawelement~RawElement} will be printed.\n * @param options.domConverter When set to an actual {@link module:engine/view/domconverter~DomConverter DomConverter}\n * instance, it lets the conversion go through exactly the same flow the editing view is going through,\n * i.e. with view data filtering. Otherwise the simple stub is used.\n * @returns An HTML-like string representing the view.\n */\nexport function stringify(\n\tnode: ViewNode | ViewDocumentFragment,\n\tselectionOrPositionOrRange: DocumentSelection | Position | Range | null = null,\n\toptions: {\n\t\tshowType?: boolean;\n\t\tshowPriority?: boolean;\n\t\tshowAttributeElementId?: boolean;\n\t\tignoreRoot?: boolean;\n\t\tsameSelectionCharacters?: boolean;\n\t\trenderUIElements?: boolean;\n\t\trenderRawElements?: boolean;\n\t\tdomConverter?: DomConverter;\n\t} = {}\n): string {\n\tlet selection;\n\n\tif (\n\t\tselectionOrPositionOrRange instanceof Position ||\n\t\tselectionOrPositionOrRange instanceof Range\n\t) {\n\t\tselection = new DocumentSelection( selectionOrPositionOrRange );\n\t} else {\n\t\tselection = selectionOrPositionOrRange;\n\t}\n\n\tconst viewStringify = new ViewStringify( node, selection, options );\n\n\treturn viewStringify.stringify();\n}\n\n/**\n * Parses an HTML-like string and returns a view tree.\n * A simple string will be converted to a {@link module:engine/view/text~Text text} node:\n *\n * ```ts\n * parse( 'foobar' ); // Returns an instance of text.\n * ```\n *\n * {@link module:engine/view/element~Element Elements} will be parsed with attributes as children:\n *\n * ```ts\n * parse( '<b name=\"baz\">foobar</b>' ); // Returns an instance of element with the `baz` attribute and a text child node.\n * ```\n *\n * Multiple nodes provided on root level will be converted to a\n * {@link module:engine/view/documentfragment~DocumentFragment document fragment}:\n *\n * ```ts\n * parse( '<b>foo</b><i>bar</i>' ); // Returns a document fragment with two child elements.\n * ```\n *\n * The method can parse multiple {@link module:engine/view/range~Range ranges} provided in string data and return a\n * {@link module:engine/view/documentselection~DocumentSelection selection} instance containing these ranges. Ranges placed inside\n * {@link module:engine/view/text~Text text} nodes should be marked using `{` and `}` brackets:\n *\n * ```ts\n * const { text, selection } = parse( 'f{ooba}r' );\n * ```\n *\n * Ranges placed outside text nodes should be marked using `[` and `]` brackets:\n *\n * ```ts\n * const { root, selection } = parse( '<p>[<b>foobar</b>]</p>' );\n * ```\n *\n * ** Note: **\n * It is possible to unify selection markers to `[` and `]` for both (inside and outside text)\n * by setting `sameSelectionCharacters=true` option. It is mainly used when the view parse option is used by model utilities.\n *\n * Sometimes there is a need for defining the order of ranges inside the created selection. This can be achieved by providing\n * the range order array as an additional parameter:\n *\n * ```ts\n * const { root, selection } = parse( '{fo}ob{ar}{ba}z', { order: [ 2, 3, 1 ] } );\n * ```\n *\n * In the example above, the first range (`{fo}`) will be added to the selection as the second one, the second range (`{ar}`) will be\n * added as the third and the third range (`{ba}`) will be added as the first one.\n *\n * If the selection's last range should be added as a backward one\n * (so the {@link module:engine/view/documentselection~DocumentSelection#anchor selection anchor} is represented\n * by the `end` position and {@link module:engine/view/documentselection~DocumentSelection#focus selection focus} is\n * represented by the `start` position), use the `lastRangeBackward` flag:\n *\n * ```ts\n * const { root, selection } = parse( `{foo}bar{baz}`, { lastRangeBackward: true } );\n * ```\n *\n * Some more examples and edge cases:\n *\n * ```ts\n * // Returns an empty document fragment.\n * parse( '' );\n *\n * // Returns an empty document fragment and a collapsed selection.\n * const { root, selection } = parse( '[]' );\n *\n * // Returns an element and a selection that is placed inside the document fragment containing that element.\n * const { root, selection } = parse( '[<a></a>]' );\n * ```\n *\n * @param data An HTML-like string to be parsed.\n * @param options.order An array with the order of parsed ranges added to the returned\n * {@link module:engine/view/documentselection~DocumentSelection Selection} instance. Each element should represent the\n * desired position of each range in the selection instance. For example: `[2, 3, 1]` means that the first range will be\n * placed as the second, the second as the third and the third as the first.\n * @param options.lastRangeBackward If set to `true`, the last range will be added as backward to the returned\n * {@link module:engine/view/documentselection~DocumentSelection selection} instance.\n * @param options.rootElement The default root to use when parsing elements.\n * When set to `null`, the root element will be created automatically. If set to\n * {@link module:engine/view/element~Element Element} or {@link module:engine/view/documentfragment~DocumentFragment DocumentFragment},\n * this node will be used as the root for all parsed nodes.\n * @param options.sameSelectionCharacters When set to `false`, the selection inside the text should be marked using\n * `{` and `}` and the selection outside the ext using `[` and `]`. When set to `true`, both should be marked with `[` and `]` only.\n * @param options.stylesProcessor Styles processor.\n * @returns Returns the parsed view node or an object with two fields: `view` and `selection` when selection ranges were included in the\n * data to parse.\n */\nexport function parse(\n\tdata: string,\n\toptions: {\n\t\torder?: Array<number>;\n\t\tlastRangeBackward?: boolean;\n\t\trootElement?: ViewElement | ViewDocumentFragment;\n\t\tsameSelectionCharacters?: boolean;\n\t\tinlineObjectElements?: Array<string>;\n\t} = {}\n): ViewNode | ViewDocumentFragment | { view: ViewNode | ViewDocumentFragment; selection: DocumentSelection } {\n\tconst viewDocument = new ViewDocument( new StylesProcessor() );\n\n\toptions.order = options.order || [];\n\tconst rangeParser = new RangeParser( {\n\t\tsameSelectionCharacters: options.sameSelectionCharacters\n\t} );\n\tconst processor = new XmlDataProcessor( viewDocument, {\n\t\tnamespaces: Object.keys( allowedTypes )\n\t} );\n\n\tif ( options.inlineObjectElements ) {\n\t\tprocessor.domConverter.inlineObjectElements.push( ...options.inlineObjectElements );\n\t}\n\n\t// Convert data to view.\n\tlet view: ViewDocumentFragment | ViewNode = processor.toView( data )!;\n\n\t// At this point we have a view tree with Elements that could have names like `attribute:b:1`. In the next step\n\t// we need to parse Element's names and convert them to AttributeElements and ContainerElements.\n\tview = _convertViewElements( view );\n\n\t// If custom root is provided - move all nodes there.\n\tif ( options.rootElement ) {\n\t\tconst root = options.rootElement;\n\t\tconst nodes = ( view as any )._removeChildren( 0, ( view as any ).childCount );\n\n\t\troot._removeChildren( 0, root.childCount );\n\t\troot._appendChild( nodes );\n\n\t\tview = root;\n\t}\n\n\t// Parse ranges included in view text nodes.\n\tconst ranges = rangeParser.parse( view, options.order );\n\n\t// If only one element is returned inside DocumentFragment - return that element.\n\tif ( view.is( 'documentFragment' ) && view.childCount === 1 ) {\n\t\tview = view.getChild( 0 );\n\t}\n\n\t// When ranges are present - return object containing view, and selection.\n\tif ( ranges.length ) {\n\t\tconst selection = new DocumentSelection( ranges, { backward: !!options.lastRangeBackward } );\n\n\t\treturn {\n\t\t\tview,\n\t\t\tselection\n\t\t};\n\t}\n\n\t// If single element is returned without selection - remove it from parent and return detached element.\n\tif ( view.parent ) {\n\t\tview._remove();\n\t}\n\n\treturn view;\n}\n\n/**\n * Private helper class used for converting ranges represented as text inside view {@link module:engine/view/text~Text text nodes}.\n */\nclass RangeParser {\n\tpublic sameSelectionCharacters: boolean;\n\tprivate _positions!: Array<{ bracket: string; position: Position }>;\n\n\t/**\n\t * Creates a range parser instance.\n\t *\n\t * @param options The range parser configuration.\n\t * @param options.sameSelectionCharacters When set to `true`, the selection inside the text is marked as\n\t * `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both are marked as `[` and `]`.\n\t */\n\tconstructor( options: { sameSelectionCharacters?: boolean } ) {\n\t\tthis.sameSelectionCharacters = !!options.sameSelectionCharacters;\n\t}\n\n\t/**\n\t * Parses the view and returns ranges represented inside {@link module:engine/view/text~Text text nodes}.\n\t * The method will remove all occurrences of `{`, `}`, `[` and `]` from found text nodes. If a text node is empty after\n\t * the process, it will be removed, too.\n\t *\n\t * @param node The starting node.\n\t * @param order The order of ranges. Each element should represent the desired position of the range after\n\t * sorting. For example: `[2, 3, 1]` means that the first range will be placed as the second, the second as the third and the third\n\t * as the first.\n\t * @returns An array with ranges found.\n\t */\n\tpublic parse( node: ViewNode | ViewDocumentFragment, order: Array<number> ): Array<Range> {\n\t\tthis._positions = [];\n\n\t\t// Remove all range brackets from view nodes and save their positions.\n\t\tthis._getPositions( node );\n\n\t\t// Create ranges using gathered positions.\n\t\tlet ranges = this._createRanges();\n\n\t\t// Sort ranges if needed.\n\t\tif ( order.length ) {\n\t\t\tif ( order.length != ranges.length ) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Parse error - there are ${ ranges.length } ranges found, but ranges order array contains ${ order.length } elements.`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tranges = this._sortRanges( ranges, order );\n\t\t}\n\n\t\treturn ranges;\n\t}\n\n\t/**\n\t * Gathers positions of brackets inside the view tree starting from the provided node. The method will remove all occurrences of\n\t * `{`, `}`, `[` and `]` from found text nodes. If a text node is empty after the process, it will be removed, too.\n\t *\n\t * @param node Staring node.\n\t */\n\tprivate _getPositions( node: ViewNode | ViewDocumentFragment ): void {\n\t\tif ( node.is( 'documentFragment' ) || node.is( 'element' ) ) {\n\t\t\t// Copy elements into the array, when nodes will be removed from parent node this array will still have all the\n\t\t\t// items needed for iteration.\n\t\t\tconst children = [ ...node.getChildren() ];\n\n\t\t\tfor ( const child of children ) {\n\t\t\t\tthis._getPositions( child );\n\t\t\t}\n\t\t}\n\n\t\tif ( node.is( '$text' ) ) {\n\t\t\tconst regexp = new RegExp(\n\t\t\t\t`[${ TEXT_RANGE_START_TOKEN }${ TEXT_RANGE_END_TOKEN }\\\\${ ELEMENT_RANGE_END_TOKEN }\\\\${ ELEMENT_RANGE_START_TOKEN }]`,\n\t\t\t\t'g'\n\t\t\t);\n\t\t\tlet text = node.data;\n\t\t\tlet match;\n\t\t\tlet offset = 0;\n\t\t\tconst brackets = [];\n\n\t\t\t// Remove brackets from text and store info about offset inside text node.\n\t\t\twhile ( ( match = regexp.exec( text ) ) ) {\n\t\t\t\tconst index = match.index;\n\t\t\t\tconst bracket = match[ 0 ];\n\n\t\t\t\tbrackets.push( {\n\t\t\t\t\tbracket,\n\t\t\t\t\ttextOffset: index - offset\n\t\t\t\t} );\n\n\t\t\t\toffset++;\n\t\t\t}\n\n\t\t\ttext = text.replace( regexp, '' );\n\t\t\tnode._data = text;\n\t\t\tconst index = node.index!;\n\t\t\tconst parent = node.parent!;\n\n\t\t\t// Remove empty text nodes.\n\t\t\tif ( !text ) {\n\t\t\t\tnode._remove();\n\t\t\t}\n\n\t\t\tfor ( const item of brackets ) {\n\t\t\t\t// Non-empty text node.\n\t\t\t\tif ( text ) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.sameSelectionCharacters ||\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t!this.sameSelectionCharacters &&\n\t\t\t\t\t\t\t( item.bracket == TEXT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN )\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Store information about text range delimiter.\n\t\t\t\t\t\tthis._positions.push( {\n\t\t\t\t\t\t\tbracket: item.bracket,\n\t\t\t\t\t\t\tposition: new Position( node, item.textOffset )\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Check if element range delimiter is not placed inside text node.\n\t\t\t\t\t\tif ( !this.sameSelectionCharacters && item.textOffset !== 0 && item.textOffset !== text.length ) {\n\t\t\t\t\t\t\tthrow new Error( `Parse error - range delimiter '${ item.bracket }' is placed inside text node.` );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If bracket is placed at the end of the text node - it should be positioned after it.\n\t\t\t\t\t\tconst offset = ( item.textOffset === 0 ? index : index + 1 );\n\n\t\t\t\t\t\t// Store information about element range delimiter.\n\t\t\t\t\t\tthis._positions.push( {\n\t\t\t\t\t\t\tbracket: item.bracket,\n\t\t\t\t\t\t\tposition: new Position( parent, offset )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( !this.sameSelectionCharacters &&\n\t\t\t\t\t\titem.bracket == TEXT_RANGE_START_TOKEN ||\n\t\t\t\t\t\titem.bracket == TEXT_RANGE_END_TOKEN\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error( `Parse error - text range delimiter '${ item.bracket }' is placed inside empty text node. ` );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store information about element range delimiter.\n\t\t\t\t\tthis._positions.push( {\n\t\t\t\t\t\tbracket: item.bracket,\n\t\t\t\t\t\tposition: new Position( parent, index )\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sorts ranges in a given order. Range order should be an array and each element should represent the desired position\n\t * of the range after sorting.\n\t * For example: `[2, 3, 1]` means that the first range will be placed as the second, the second as the third and the third\n\t * as the first.\n\t *\n\t * @param ranges Ranges to sort.\n\t * @param rangesOrder An array with new range order.\n\t * @returns Sorted ranges array.\n\t */\n\tprivate _sortRanges( ranges: Array<Range>, rangesOrder: Array<number> ): Array<Range> {\n\t\tconst sortedRanges = [];\n\t\tlet index = 0;\n\n\t\tfor ( const newPosition of rangesOrder ) {\n\t\t\tif ( ranges[ newPosition - 1 ] === undefined ) {\n\t\t\t\tthrow new Error( 'Parse error - provided ranges order is invalid.' );\n\t\t\t}\n\n\t\t\tsortedRanges[ newPosition - 1 ] = ranges[ index ];\n\t\t\tindex++;\n\t\t}\n\n\t\treturn sortedRanges;\n\t}\n\n\t/**\n\t * Uses all found bracket positions to create ranges from them.\n\t */\n\tprivate _createRanges(): Array<Range> {\n\t\tconst ranges = [];\n\t\tlet range = null;\n\n\t\tfor ( const item of this._positions ) {\n\t\t\t// When end of range is found without opening.\n\t\t\tif ( !range && ( item.bracket == ELEMENT_RANGE_END_TOKEN || item.bracket == TEXT_RANGE_END_TOKEN ) ) {\n\t\t\t\tthrow new Error( `Parse error - end of range was found '${ item.bracket }' but range was not started before.` );\n\t\t\t}\n\n\t\t\t// When second start of range is found when one is already opened - selection does not allow intersecting\n\t\t\t// ranges.\n\t\t\tif ( range && ( item.bracket == ELEMENT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_START_TOKEN ) ) {\n\t\t\t\tthrow new Error( `Parse error - start of range was found '${ item.bracket }' but one range is already started.` );\n\t\t\t}\n\n\t\t\tif ( item.bracket == ELEMENT_RANGE_START_TOKEN || item.bracket == TEXT_RANGE_START_TOKEN ) {\n\t\t\t\trange = new Range( item.position, item.position );\n\t\t\t} else {\n\t\t\t\t( range as any ).end = item.position;\n\t\t\t\tranges.push( range! );\n\t\t\t\trange = null;\n\t\t\t}\n\t\t}\n\n\t\t// Check if all ranges have proper ending.\n\t\tif ( range !== null ) {\n\t\t\tthrow new Error( 'Parse error - range was started but no end delimiter was found.' );\n\t\t}\n\n\t\treturn ranges;\n\t}\n}\n\n/**\n * Private helper class used for converting the view tree to a string.\n */\nclass ViewStringify {\n\tpublic root: ViewNode | ViewDocumentFragment;\n\tpublic selection: DocumentSelection | null;\n\tpublic ranges: Array<Range>;\n\tpublic showType: boolean;\n\tpublic showPriority: boolean;\n\tpublic showAttributeElementId: boolean;\n\tpublic ignoreRoot: boolean;\n\tpublic sameSelectionCharacters: boolean;\n\tpublic renderUIElements: boolean;\n\tpublic renderRawElements: boolean;\n\tpublic domConverter: DomConverter;\n\n\t/**\n\t * Creates a view stringify instance.\n\t *\n\t * @param selection A selection whose ranges should also be converted to a string.\n\t * @param options An options object.\n\t * @param options.showType When set to `true`, the type of elements will be printed (`<container:p>`\n\t * instead of `<p>`, `<attribute:b>` instead of `<b>` and `<empty:img>` instead of `<img>`).\n\t * @param options.showPriority When set to `true`, the attribute element's priority will be printed.\n\t * @param options.ignoreRoot When set to `true`, the root's element opening and closing tag will not\n\t * be outputted.\n\t * @param options.sameSelectionCharacters When set to `true`, the selection inside the text is marked as\n\t * `{` and `}` and the selection outside the text as `[` and `]`. When set to `false`, both are marked as `[` and `]`.\n\t * @param options.renderUIElements When set to `true`, the inner content of each\n\t * {@link module:engine/view/uielement~UIElement} will be printed.\n\t * @param options.renderRawElements When set to `true`, the inner content of each\n\t * @param options.domConverter When set to an actual {@link module:engine/view/domconverter~DomConverter DomConverter}\n\t * instance, it lets the conversion go through exactly the same flow the editing view is going through,\n\t * i.e. with view data filtering. Otherwise the simple stub is used.\n\t * {@link module:engine/view/rawelement~RawElement} will be printed.\n\t */\n\tconstructor(\n\t\troot: ViewNode | ViewDocumentFragment,\n\t\tselection: DocumentSelection | null,\n\t\toptions: {\n\t\t\tshowType?: boolean;\n\t\t\tshowPriority?: boolean;\n\t\t\tshowAttributeElementId?: boolean;\n\t\t\tignoreRoot?: boolean;\n\t\t\tsameSelectionCharacters?: boolean;\n\t\t\trenderUIElements?: boolean;\n\t\t\trenderRawElements?: boolean;\n\t\t\tdomConverter?: DomConverter;\n\t\t}\n\t) {\n\t\tthis.root = root;\n\t\tthis.selection = selection;\n\t\tthis.ranges = [];\n\n\t\tif ( selection ) {\n\t\t\tthis.ranges = [ ...selection.getRanges() ];\n\t\t}\n\n\t\tthis.showType = !!options.showType;\n\t\tthis.showPriority = !!options.showPriority;\n\t\tthis.showAttributeElementId = !!options.showAttributeElementId;\n\t\tthis.ignoreRoot = !!options.ignoreRoot;\n\t\tthis.sameSelectionCharacters = !!options.sameSelectionCharacters;\n\t\tthis.renderUIElements = !!options.renderUIElements;\n\t\tthis.renderRawElements = !!options.renderRawElements;\n\t\tthis.domConverter = options.domConverter || domConverterStub;\n\t}\n\n\t/**\n\t * Converts the view to a string.\n\t *\n\t * @returns String representation of the view elements.\n\t */\n\tpublic stringify(): string {\n\t\tlet result = '';\n\t\tthis._walkView( this.root, chunk => {\n\t\t\tresult += chunk;\n\t\t} );\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Executes a simple walker that iterates over all elements in the view tree starting from the root element.\n\t * Calls the `callback` with parsed chunks of string data.\n\t */\n\tprivate _walkView(\n\t\troot: ViewNode | ViewDocumentFragment,\n\t\tcallback: ( chunk: string ) => void\n\t): void {\n\t\tconst ignore = this.ignoreRoot && this.root === root;\n\n\t\tif ( root.is( 'element' ) || root.is( 'documentFragment' ) ) {\n\t\t\tif ( root.is( 'element' ) && !ignore ) {\n\t\t\t\tcallback( this._stringifyElementOpen( root ) );\n\t\t\t}\n\n\t\t\tif ( ( this.renderUIElements && root.is( 'uiElement' ) ) ) {\n\t\t\t\tcallback( root.render( document, this.domConverter ).innerHTML );\n\t\t\t} else if ( this.renderRawElements && root.is( 'rawElement' ) ) {\n\t\t\t\t// There's no DOM element for \"root\" to pass to render(). Creating\n\t\t\t\t// a surrogate container to render the children instead.\n\t\t\t\tconst rawContentContainer = document.createElement( 'div' );\n\t\t\t\troot.render( rawContentContainer, this.domConverter );\n\n\t\t\t\tcallback( rawContentContainer.innerHTML );\n\t\t\t} else {\n\t\t\t\tlet offset = 0;\n\t\t\t\tcallback( this._stringifyElementRanges( root, offset ) );\n\n\t\t\t\tfor ( const child of root.getChildren() ) {\n\t\t\t\t\tthis._walkView( child, callback );\n\t\t\t\t\toffset++;\n\t\t\t\t\tcallback( this._stringifyElementRanges( root, offset ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( root.is( 'element' ) && !ignore ) {\n\t\t\t\tcallback( this._stringifyElementClose( root ) );\n\t\t\t}\n\t\t}\n\n\t\tif ( root.is( '$text' ) ) {\n\t\t\tcallback( this._stringifyTextRanges( root ) );\n\t\t}\n\t}\n\n\t/**\n\t * Checks if a given {@link module:engine/view/element~Element element} has a {@link module:engine/view/range~Range#start range start}\n\t * or a {@link module:engine/view/range~Range#start range end} placed at a given offset and returns its string representation.\n\t */\n\tprivate _stringifyElementRanges( element: ViewElement | ViewDocumentFragment, offset: number ): string {\n\t\tlet start = '';\n\t\tlet end = '';\n\t\tlet collapsed = '';\n\n\t\tfor ( const range of this.ranges ) {\n\t\t\tif ( range.start.parent == element && range.start.offset === offset ) {\n\t\t\t\tif ( range.isCollapsed ) {\n\t\t\t\t\tcollapsed += ELEMENT_RANGE_START_TOKEN + ELEMENT_RANGE_END_TOKEN;\n\t\t\t\t} else {\n\t\t\t\t\tstart += ELEMENT_RANGE_START_TOKEN;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( range.end.parent === element && range.end.offset === offset && !range.isCollapsed ) {\n\t\t\t\tend += ELEMENT_RANGE_END_TOKEN;\n\t\t\t}\n\t\t}\n\n\t\treturn end + collapsed + start;\n\t}\n\n\t/**\n\t * Checks if a given {@link module:engine/view/element~Element Text node} has a\n\t * {@link module:engine/view/range~Range#start range start} or a\n\t * {@link module:engine/view/range~Range#start range end} placed somewhere inside. Returns a string representation of text\n\t * with range delimiters placed inside.\n\t */\n\tprivate _stringifyTextRanges( node: ViewText ): string {\n\t\tconst length = node.data.length;\n\t\tconst data = node.data.split( '' );\n\t\tlet rangeStartToken, rangeEndToken;\n\n\t\tif ( this.sameSelectionCharacters ) {\n\t\t\trangeStartToken = ELEMENT_RANGE_START_TOKEN;\n\t\t\trangeEndToken = ELEMENT_RANGE_END_TOKEN;\n\t\t} else {\n\t\t\trangeStartToken = TEXT_RANGE_START_TOKEN;\n\t\t\trangeEndToken = TEXT_RANGE_END_TOKEN;\n\t\t}\n\n\t\t// Add one more element for ranges ending after last character in text.\n\t\tdata[ length ] = '';\n\n\t\t// Represent each letter as object with information about opening/closing ranges at each offset.\n\t\tconst result = data.map( letter => {\n\t\t\treturn {\n\t\t\t\tletter,\n\t\t\t\tstart: '',\n\t\t\t\tend: '',\n\t\t\t\tcollapsed: ''\n\t\t\t};\n\t\t} );\n\n\t\tfor ( const range of this.ranges ) {\n\t\t\tconst start = range.start;\n\t\t\tconst end = range.end;\n\n\t\t\tif ( start.parent == node && start.offset >= 0 && start.offset <= length ) {\n\t\t\t\tif ( range.isCollapsed ) {\n\t\t\t\t\tresult[ end.offset ].collapsed += rangeStartToken + rangeEndToken;\n\t\t\t\t} else {\n\t\t\t\t\tresult[ start.offset ].start += rangeStartToken;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( end.parent == node && end.offset >= 0 && end.offset <= length && !range.isCollapsed ) {\n\t\t\t\tresult[ end.offset ].end += rangeEndToken;\n\t\t\t}\n\t\t}\n\n\t\treturn result.map( item => item.end + item.collapsed + item.start + item.letter ).join( '' );\n\t}\n\n\t/**\n\t * Converts the passed {@link module:engine/view/element~Element element} to an opening tag.\n\t *\n\t * Depending on the current configuration, the opening tag can be simple (`<a>`), contain a type prefix (`<container:p>`,\n\t * `<attribute:a>` or `<empty:img>`), contain priority information ( `<attribute:a view-priority=\"20\">` ),\n\t * or contain element id ( `<attribute:span view-id=\"foo\">` ). Element attributes will also be included\n\t * (`<a href=\"https://ckeditor.com\" name=\"foobar\">`).\n\t */\n\tprivate _stringifyElementOpen( element: ViewElement ): string {\n\t\tconst priority = this._stringifyElementPriority( element );\n\t\tconst id = this._stringifyElementId( element );\n\n\t\tconst type = this._stringifyElementType( element );\n\t\tconst name = [ type, element.name ].filter( i => i !== '' ).join( ':' );\n\t\tconst attributes = this._stringifyElementAttributes( element );\n\t\tconst parts = [ name, priority, id, attributes ];\n\n\t\treturn `<${ parts.filter( i => i !== '' ).join( ' ' ) }>`;\n\t}\n\n\t/**\n\t * Converts the passed {@link module:engine/view/element~Element element} to a closing tag.\n\t * Depending on the current configuration, the closing tag can be simple (`</a>`) or contain a type prefix (`</container:p>`,\n\t * `</attribute:a>` or `</empty:img>`).\n\t */\n\tprivate _stringifyElementClose( element: ViewElement ): string {\n\t\tconst type = this._stringifyElementType( element );\n\t\tconst name = [ type, element.name ].filter( i => i !== '' ).join( ':' );\n\n\t\treturn `</${ name }>`;\n\t}\n\n\t/**\n\t * Converts the passed {@link module:engine/view/element~Element element's} type to its string representation\n\t *\n\t * Returns:\n\t * * 'attribute' for {@link module:engine/view/attributeelement~AttributeElement attribute elements},\n\t * * 'container' for {@link module:engine/view/containerelement~ContainerElement container elements},\n\t * * 'empty' for {@link module:engine/view/emptyelement~EmptyElement empty elements},\n\t * * 'ui' for {@link module:engine/view/uielement~UIElement UI elements},\n\t * * 'raw' for {@link module:engine/view/rawelement~RawElement raw elements},\n\t * * an empty string when the current configuration is preventing showing elements' types.\n\t */\n\tprivate _stringifyElementType( element: ViewElement ): string {\n\t\tif ( this.showType ) {\n\t\t\tfor ( const type in allowedTypes ) {\n\t\t\t\tif ( element instanceof allowedTypes[ type as keyof typeof allowedTypes ] ) {\n\t\t\t\t\treturn type;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Converts the passed {@link module:engine/view/element~Element element} to its priority representation.\n\t *\n\t * The priority string representation will be returned when the passed element is an instance of\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute element} and the current configuration allows to show the\n\t * priority. Otherwise returns an empty string.\n\t */\n\tprivate _stringifyElementPriority( element: ViewElement ): string {\n\t\tif ( this.showPriority && element.is( 'attributeElement' ) ) {\n\t\t\treturn `view-priority=\"${ element.priority }\"`;\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Converts the passed {@link module:engine/view/element~Element element} to its id representation.\n\t *\n\t * The id string representation will be returned when the passed element is an instance of\n\t * {@link module:engine/view/attributeelement~AttributeElement attribute element}, the element has an id\n\t * and the current configuration allows to show the id. Otherwise returns an empty string.\n\t */\n\tprivate _stringifyElementId( element: ViewElement ): string {\n\t\tif ( this.showAttributeElementId && element.is( 'attributeElement' ) && element.id ) {\n\t\t\treturn `view-id=\"${ element.id }\"`;\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Converts the passed {@link module:engine/view/element~Element element} attributes to their string representation.\n\t * If an element has no attributes, an empty string is returned.\n\t */\n\tprivate _stringifyElementAttributes( element: ViewElement ): string {\n\t\tconst attributes = [];\n\t\tconst keys = [ ...element.getAttributeKeys() ].sort();\n\n\t\tfor ( const attribute of keys ) {\n\t\t\tlet attributeValue;\n\n\t\t\tif ( attribute === 'class' ) {\n\t\t\t\tattributeValue = [ ...element.getClassNames() ]\n\t\t\t\t\t.sort()\n\t\t\t\t\t.join( ' ' );\n\t\t\t} else if ( attribute === 'style' ) {\n\t\t\t\tattributeValue = [ ...element.getStyleNames() ]\n\t\t\t\t\t.sort()\n\t\t\t\t\t.map( style => `${ style }:${ element.getStyle( style )!.replace( /\"/g, '&quot;' ) }` )\n\t\t\t\t\t.join( ';' );\n\t\t\t} else {\n\t\t\t\tattributeValue = element.getAttribute( attribute );\n\t\t\t}\n\n\t\t\tattributes.push( `${ attribute }=\"${ attributeValue }\"` );\n\t\t}\n\n\t\treturn attributes.join( ' ' );\n\t}\n}\n\n/**\n * Converts {@link module:engine/view/element~Element elements} to\n * {@link module:engine/view/attributeelement~AttributeElement attribute elements},\n * {@link module:engine/view/containerelement~ContainerElement container elements},\n * {@link module:engine/view/emptyelement~EmptyElement empty elements} or\n * {@link module:engine/view/uielement~UIElement UI elements}.\n * It converts the whole tree starting from the `rootNode`. The conversion is based on element names.\n * See the `_convertElement` method for more details.\n *\n * @param rootNode The root node to convert.\n * @returns The root node of converted elements.\n */\nfunction _convertViewElements( rootNode: ViewNode | ViewDocumentFragment ) {\n\tif ( rootNode.is( 'element' ) || rootNode.is( 'documentFragment' ) ) {\n\t\t// Convert element or leave document fragment.\n\n\t\tconst convertedElement = rootNode.is( 'documentFragment' ) ?\n\t\t\tnew ViewDocumentFragment( rootNode.document ) :\n\t\t\t_convertElement( rootNode.document, rootNode );\n\n\t\t// Convert all child nodes.\n\t\t// Cache the nodes in array. Otherwise, we would skip some nodes because during iteration we move nodes\n\t\t// from `rootNode` to `convertedElement`. This would interfere with iteration.\n\t\tfor ( const child of [ ...rootNode.getChildren() ] ) {\n\t\t\tif ( convertedElement.is( 'emptyElement' ) ) {\n\t\t\t\tthrow new Error( 'Parse error - cannot parse inside EmptyElement.' );\n\t\t\t} else if ( convertedElement.is( 'uiElement' ) ) {\n\t\t\t\tthrow new Error( 'Parse error - cannot parse inside UIElement.' );\n\t\t\t} else if ( convertedElement.is( 'rawElement' ) ) {\n\t\t\t\tthrow new Error( 'Parse error - cannot parse inside RawElement.' );\n\t\t\t}\n\n\t\t\tconvertedElement._appendChild( _convertViewElements( child ) );\n\t\t}\n\n\t\treturn convertedElement;\n\t}\n\n\treturn rootNode;\n}\n\n/**\n * Converts an {@link module:engine/view/element~Element element} to\n * {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/containerelement~ContainerElement container element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element} or\n * {@link module:engine/view/uielement~UIElement UI element}.\n * If the element's name is in the format of `attribute:b`, it will be converted to\n * an {@link module:engine/view/attributeelement~AttributeElement attribute element} with a priority of 11.\n * Additionally, attribute elements may have specified priority (for example `view-priority=\"11\"`) and/or\n * id (for example `view-id=\"foo\"`).\n * If the element's name is in the format of `container:p`, it will be converted to\n * a {@link module:engine/view/containerelement~ContainerElement container element}.\n * If the element's name is in the format of `empty:img`, it will be converted to\n * an {@link module:engine/view/emptyelement~EmptyElement empty element}.\n * If the element's name is in the format of `ui:span`, it will be converted to\n * a {@link module:engine/view/uielement~UIElement UI element}.\n * If the element's name does not contain any additional information, a {@link module:engine/view/element~Element view Element} will be\n * returned.\n *\n * @param viewElement A view element to convert.\n * @returns A tree view element converted according to its name.\n */\nfunction _convertElement( viewDocument: ViewDocument, viewElement: ViewElement ) {\n\tconst info = _convertElementNameAndInfo( viewElement );\n\tconst ElementConstructor = allowedTypes[ info.type! ];\n\tconst newElement = ElementConstructor ? new ElementConstructor( viewDocument, info.name ) : new ViewElement( viewDocument, info.name );\n\n\tif ( newElement.is( 'attributeElement' ) ) {\n\t\tif ( info.priority !== null ) {\n\t\t\t( newElement as any )._priority = info.priority;\n\t\t}\n\n\t\tif ( info.id !== null ) {\n\t\t\t( newElement as any )._id = info.id;\n\t\t}\n\t}\n\n\t// Move attributes.\n\tfor ( const attributeKey of viewElement.getAttributeKeys() ) {\n\t\tnewElement._setAttribute( attributeKey, viewElement.getAttribute( attributeKey )! );\n\t}\n\n\treturn newElement;\n}\n\n/**\n * Converts the `view-priority` attribute and the {@link module:engine/view/element~Element#name element's name} information needed for\n * creating {@link module:engine/view/attributeelement~AttributeElement attribute element},\n * {@link module:engine/view/containerelement~ContainerElement container element},\n * {@link module:engine/view/emptyelement~EmptyElement empty element} or\n * {@link module:engine/view/uielement~UIElement UI element}.\n * The name can be provided in two formats: as a simple element's name (`div`), or as a type and name (`container:div`,\n * `attribute:span`, `empty:img`, `ui:span`);\n *\n * @param viewElement The element whose name should be converted.\n * @returns An object with parsed information:\n * * `name` The parsed name of the element.\n * * `type` The parsed type of the element. It can be `attribute`, `container` or `empty`.\n * * `priority` The parsed priority of the element.\n */\nfunction _convertElementNameAndInfo( viewElement: ViewElement ) {\n\tconst parts = viewElement.name.split( ':' );\n\n\tconst priority = _convertPriority( viewElement.getAttribute( 'view-priority' )! );\n\tconst id = viewElement.hasAttribute( 'view-id' ) ? viewElement.getAttribute( 'view-id' ) : null;\n\n\tviewElement._removeAttribute( 'view-priority' );\n\tviewElement._removeAttribute( 'view-id' );\n\n\tif ( parts.length == 1 ) {\n\t\treturn {\n\t\t\tname: parts[ 0 ],\n\t\t\ttype: priority !== null ? 'attribute' : null,\n\t\t\tpriority,\n\t\t\tid\n\t\t} as const;\n\t}\n\n\t// Check if type and name: container:div.\n\tconst type = _convertType( parts[ 0 ] );\n\n\tif ( type ) {\n\t\treturn {\n\t\t\tname: parts[ 1 ],\n\t\t\ttype,\n\t\t\tpriority,\n\t\t\tid\n\t\t} as const;\n\t}\n\n\tthrow new Error( `Parse error - cannot parse element's name: ${ viewElement.name }.` );\n}\n\n/**\n * Checks if the element's type is allowed. Returns `attribute`, `container`, `empty` or `null`.\n */\nfunction _convertType( type: string ): keyof typeof allowedTypes | null {\n\treturn type in allowedTypes ? type as any : null;\n}\n\n/**\n * Checks if a given priority is allowed. Returns null if the priority cannot be converted.\n */\nfunction _convertPriority( priorityString: string ) {\n\tconst priority = parseInt( priorityString, 10 );\n\n\tif ( !isNaN( priority ) ) {\n\t\treturn priority;\n\t}\n\n\treturn null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module engine/dev-utils/model\n */\n\n/**\n * Collection of methods for manipulating the {@link module:engine/model/model model} for testing purposes.\n */\n\nimport RootElement from '../model/rootelement.js';\nimport Model from '../model/model.js';\nimport ModelRange from '../model/range.js';\nimport ModelPosition from '../model/position.js';\nimport ModelSelection from '../model/selection.js';\nimport ModelDocumentFragment from '../model/documentfragment.js';\nimport DocumentSelection from '../model/documentselection.js';\n\nimport View from '../view/view.js';\nimport ViewContainerElement from '../view/containerelement.js';\nimport ViewRootEditableElement from '../view/rooteditableelement.js';\n\nimport { parse as viewParse, stringify as viewStringify } from '../../src/dev-utils/view.js';\n\nimport Mapper from '../conversion/mapper.js';\nimport {\n\tconvertCollapsedSelection,\n\tconvertRangeSelection,\n\tinsertAttributesAndChildren,\n\tinsertElement,\n\tinsertText,\n\tinsertUIElement,\n\twrap\n} from '../conversion/downcasthelpers.js';\n\nimport { StylesProcessor } from '../view/stylesmap.js';\n\nimport DowncastDispatcher, {\n\ttype DowncastAddMarkerEvent,\n\ttype DowncastAttributeEvent,\n\ttype DowncastInsertEvent,\n\ttype DowncastSelectionEvent\n} from '../conversion/downcastdispatcher.js';\nimport UpcastDispatcher, {\n\ttype UpcastDocumentFragmentEvent,\n\ttype UpcastElementEvent,\n\ttype UpcastTextEvent,\n\ttype UpcastConversionApi,\n\ttype UpcastConversionData\n} from '../conversion/upcastdispatcher.js';\nimport type ViewDocumentSelection from '../view/documentselection.js';\nimport type { BatchType } from '../model/batch.js';\nimport type MarkerCollection from '../model/markercollection.js';\nimport type ModelText from '../model/text.js';\nimport type ModelTextProxy from '../model/textproxy.js';\nimport type DowncastWriter from '../view/downcastwriter.js';\nimport type { default as Schema, SchemaContextDefinition } from '../model/schema.js';\nimport type { ViewDocumentFragment, ViewElement } from '../index.js';\nimport type ViewNode from '../view/node.js';\nimport type ViewText from '../view/text.js';\nimport type Writer from '../model/writer.js';\nimport type ModelNode from '../model/node.js';\nimport type ModelElement from '../model/element.js';\n\nimport { toMap, type EventInfo } from '@ckeditor/ckeditor5-utils';\n\nimport { isPlainObject } from 'lodash-es';\n\n/**\n * Writes the content of a model {@link module:engine/model/document~Document document} to an HTML-like string.\n *\n * ```ts\n * getData( editor.model ); // -> '<paragraph>Foo![]</paragraph>'\n * ```\n *\n * **Note:** A {@link module:engine/model/text~Text text} node that contains attributes will be represented as:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * **Note:** Using this tool in production-grade code is not recommended. It was designed for development, prototyping,\n * debugging and testing.\n *\n * @param options.withoutSelection Whether to write the selection. When set to `true`, the selection will\n * not be included in the returned string.\n * @param options.rootName The name of the root from which the data should be stringified. If not provided,\n * the default `main` name will be used.\n * @param options.convertMarkers Whether to include markers in the returned string.\n * @returns The stringified data.\n */\nexport function getData(\n\tmodel: Model,\n\toptions: {\n\t\twithoutSelection?: boolean;\n\t\trootName?: string;\n\t\tconvertMarkers?: boolean;\n\t} = {}\n): string {\n\tif ( !( model instanceof Model ) ) {\n\t\tthrow new TypeError( 'Model needs to be an instance of module:engine/model/model~Model.' );\n\t}\n\n\tconst rootName = options.rootName || 'main';\n\tconst root = model.document.getRoot( rootName )!;\n\n\treturn getData._stringify(\n\t\troot,\n\t\toptions.withoutSelection ? null : model.document.selection,\n\t\toptions.convertMarkers ? model.markers : null\n\t);\n}\n\n// Set stringify as getData private method - needed for testing/spying.\ngetData._stringify = stringify;\n\n/**\n * Sets the content of a model {@link module:engine/model/document~Document document} provided as an HTML-like string.\n *\n * ```ts\n * setData( editor.model, '<paragraph>Foo![]</paragraph>' );\n * ```\n *\n * **Note:** Remember to register elements in the {@link module:engine/model/model~Model#schema model's schema} before\n * trying to use them.\n *\n * **Note:** To create a {@link module:engine/model/text~Text text} node that contains attributes use:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * **Note:** Using this tool in production-grade code is not recommended. It was designed for development, prototyping,\n * debugging and testing.\n *\n * @param data HTML-like string to write into the document.\n * @param options.rootName Root name where parsed data will be stored. If not provided, the default `main`\n * name will be used.\n * @param options.selectionAttributes A list of attributes which will be passed to the selection.\n * @param options.lastRangeBackward If set to `true`, the last range will be added as backward.\n * @param options.batchType Batch type used for inserting elements. See {@link module:engine/model/batch~Batch#constructor}.\n * See {@link module:engine/model/batch~Batch#type}.\n */\nexport function setData(\n\tmodel: Model,\n\tdata: string,\n\toptions: {\n\t\trootName?: string;\n\t\tselectionAttributes?: Record<string, unknown>;\n\t\tlastRangeBackward?: boolean;\n\t\tbatchType?: BatchType;\n\t\tinlineObjectElements?: Array<string>;\n\t} = {}\n): void {\n\tif ( !( model instanceof Model ) ) {\n\t\tthrow new TypeError( 'Model needs to be an instance of module:engine/model/model~Model.' );\n\t}\n\n\tlet modelDocumentFragment: ModelNode | ModelDocumentFragment;\n\tlet selection: ModelSelection | null = null;\n\tconst modelRoot = model.document.getRoot( options.rootName || 'main' )!;\n\n\t// Parse data string to model.\n\tconst parsedResult = setData._parse( data, model.schema, {\n\t\tlastRangeBackward: options.lastRangeBackward,\n\t\tselectionAttributes: options.selectionAttributes,\n\t\tcontext: [ modelRoot.name ],\n\t\tinlineObjectElements: options.inlineObjectElements\n\t} );\n\n\t// Retrieve DocumentFragment and Selection from parsed model.\n\tif ( 'model' in parsedResult ) {\n\t\tmodelDocumentFragment = parsedResult.model;\n\t\tselection = parsedResult.selection;\n\t} else {\n\t\tmodelDocumentFragment = parsedResult;\n\t}\n\n\tif ( options.batchType !== undefined ) {\n\t\tmodel.enqueueChange( options.batchType, writeToModel );\n\t} else {\n\t\tmodel.change( writeToModel );\n\t}\n\n\tfunction writeToModel( writer: Writer ) {\n\t\t// Replace existing model in document by new one.\n\t\twriter.remove( writer.createRangeIn( modelRoot ) );\n\t\twriter.insert( modelDocumentFragment, modelRoot );\n\n\t\t// Clean up previous document selection.\n\t\twriter.setSelection( null );\n\t\twriter.removeSelectionAttribute( model.document.selection.getAttributeKeys() );\n\n\t\t// Update document selection if specified.\n\t\tif ( selection ) {\n\t\t\tconst ranges: Array<ModelRange> = [];\n\n\t\t\tfor ( const range of selection.getRanges() ) {\n\t\t\t\tconst start = new ModelPosition( modelRoot, range.start.path );\n\t\t\t\tconst end = new ModelPosition( modelRoot, range.end.path );\n\n\t\t\t\tranges.push( new ModelRange( start, end ) );\n\t\t\t}\n\n\t\t\twriter.setSelection( ranges, { backward: selection.isBackward } );\n\n\t\t\tif ( options.selectionAttributes ) {\n\t\t\t\twriter.setSelectionAttribute( selection.getAttributes() );\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Set parse as setData private method - needed for testing/spying.\nsetData._parse = parse;\n\n/**\n * Converts model nodes to HTML-like string representation.\n *\n * **Note:** A {@link module:engine/model/text~Text text} node that contains attributes will be represented as:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * @param node A node to stringify.\n * @param selectionOrPositionOrRange A selection instance whose ranges will be included in the returned string data.\n * If a range instance is provided, it will be converted to a selection containing this range. If a position instance\n * is provided, it will be converted to a selection containing one range collapsed at this position.\n * @param markers Markers to include.\n * @returns An HTML-like string representing the model.\n */\nexport function stringify(\n\tnode: ModelNode | ModelDocumentFragment,\n\tselectionOrPositionOrRange: ModelSelection | DocumentSelection | ModelPosition | ModelRange | null = null,\n\tmarkers: MarkerCollection | null = null\n): string {\n\tconst model = new Model();\n\tconst mapper = new Mapper();\n\tlet selection: ModelSelection | DocumentSelection | null = null;\n\tlet range: ModelRange;\n\n\t// Create a range witch wraps passed node.\n\tif ( node instanceof RootElement || node instanceof ModelDocumentFragment ) {\n\t\trange = model.createRangeIn( node );\n\t} else {\n\t\t// Node is detached - create new document fragment.\n\t\tif ( !node.parent ) {\n\t\t\tconst fragment = new ModelDocumentFragment( node );\n\t\t\trange = model.createRangeIn( fragment );\n\t\t} else {\n\t\t\trange = new ModelRange(\n\t\t\t\tmodel.createPositionBefore( node ),\n\t\t\t\tmodel.createPositionAfter( node )\n\t\t\t);\n\t\t}\n\t}\n\n\t// Get selection from passed selection or position or range if at least one is specified.\n\tif ( selectionOrPositionOrRange instanceof ModelSelection ) {\n\t\tselection = selectionOrPositionOrRange;\n\t} else if ( selectionOrPositionOrRange instanceof DocumentSelection ) {\n\t\tselection = selectionOrPositionOrRange;\n\t} else if ( selectionOrPositionOrRange instanceof ModelRange ) {\n\t\tselection = new ModelSelection( selectionOrPositionOrRange );\n\t} else if ( selectionOrPositionOrRange instanceof ModelPosition ) {\n\t\tselection = new ModelSelection( selectionOrPositionOrRange );\n\t}\n\n\t// Set up conversion.\n\t// Create a temporary view controller.\n\tconst stylesProcessor = new StylesProcessor();\n\tconst view = new View( stylesProcessor );\n\tconst viewDocument = view.document;\n\tconst viewRoot = new ViewRootEditableElement( viewDocument, 'div' );\n\n\t// Create a temporary root element in view document.\n\tviewRoot.rootName = 'main';\n\tviewDocument.roots.add( viewRoot );\n\n\t// Create and setup downcast dispatcher.\n\tconst downcastDispatcher = new DowncastDispatcher( { mapper, schema: model.schema } );\n\n\t// Bind root elements.\n\tmapper.bindElements( node.root as ModelElement | ModelDocumentFragment, viewRoot );\n\n\tdowncastDispatcher.on<DowncastInsertEvent<ModelText | ModelTextProxy>>( 'insert:$text', insertText() );\n\tdowncastDispatcher.on<DowncastInsertEvent<ModelElement>>( 'insert', insertAttributesAndChildren(), { priority: 'lowest' } );\n\tdowncastDispatcher.on<DowncastAttributeEvent>( 'attribute', ( evt, data, conversionApi ) => {\n\t\tif ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection || data.item.is( '$textProxy' ) ) {\n\t\t\tconst converter = wrap( ( modelAttributeValue, { writer } ) => {\n\t\t\t\treturn writer.createAttributeElement(\n\t\t\t\t\t'model-text-with-attributes',\n\t\t\t\t\t{ [ data.attributeKey ]: stringifyAttributeValue( modelAttributeValue ) }\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\tconverter( evt, data, conversionApi );\n\t\t}\n\t} );\n\tdowncastDispatcher.on<DowncastInsertEvent<ModelElement>>( 'insert', insertElement( modelItem => {\n\t\t// Stringify object types values for properly display as an output string.\n\t\tconst attributes = convertAttributes( modelItem.getAttributes(), stringifyAttributeValue );\n\n\t\treturn new ViewContainerElement( viewDocument, modelItem.name, attributes );\n\t} ) );\n\n\tdowncastDispatcher.on<DowncastSelectionEvent>( 'selection', convertRangeSelection() );\n\tdowncastDispatcher.on<DowncastSelectionEvent>( 'selection', convertCollapsedSelection() );\n\tdowncastDispatcher.on<DowncastAddMarkerEvent>( 'addMarker', insertUIElement( ( data, { writer } ) => {\n\t\tconst name = data.markerName + ':' + ( data.isOpening ? 'start' : 'end' );\n\n\t\treturn writer.createUIElement( name );\n\t} ) );\n\n\tconst markersMap: Map<string, ModelRange> = new Map();\n\n\tif ( markers ) {\n\t\t// To provide stable results, sort markers by name.\n\t\tfor ( const marker of Array.from( markers ).sort( ( a, b ) => a.name < b.name ? 1 : -1 ) ) {\n\t\t\tmarkersMap.set( marker.name, marker.getRange() );\n\t\t}\n\t}\n\n\t// Convert model to view.\n\tconst writer: DowncastWriter = ( view as any )._writer;\n\tdowncastDispatcher.convert( range, markersMap, writer );\n\n\t// Convert model selection to view selection.\n\tif ( selection ) {\n\t\tdowncastDispatcher.convertSelection( selection, markers || model.markers, writer );\n\t}\n\n\t// Parse view to data string.\n\tlet data = viewStringify( viewRoot, viewDocument.selection, { sameSelectionCharacters: true } );\n\n\t// Removing unnecessary <div> and </div> added because `viewRoot` was also stringified alongside input data.\n\tdata = data.substr( 5, data.length - 11 );\n\n\tview.destroy();\n\n\t// Replace valid XML `model-text-with-attributes` element name to `$text`.\n\treturn data.replace( new RegExp( 'model-text-with-attributes', 'g' ), '$text' );\n}\n\n/**\n * Parses an HTML-like string and returns the model {@link module:engine/model/rootelement~RootElement rootElement}.\n *\n * **Note:** To create a {@link module:engine/model/text~Text text} node that contains attributes use:\n *\n * ```xml\n * <$text attribute=\"value\">Text data</$text>\n * ```\n *\n * @param data HTML-like string to be parsed.\n * @param schema A schema instance used by converters for element validation.\n * @param options Additional configuration.\n * @param options.selectionAttributes A list of attributes which will be passed to the selection.\n * @param options.lastRangeBackward If set to `true`, the last range will be added as backward.\n * @param options.context The conversion context. If not provided, the default `'$root'` will be used.\n * @returns Returns the parsed model node or an object with two fields: `model` and `selection`,\n * when selection ranges were included in the data to parse.\n */\nexport function parse(\n\tdata: string,\n\tschema: Schema,\n\toptions: {\n\t\tselectionAttributes?: Record<string, unknown> | Iterable<[ string, unknown ]>;\n\t\tlastRangeBackward?: boolean;\n\t\tcontext?: SchemaContextDefinition;\n\t\tinlineObjectElements?: Array<string>;\n\t} = {}\n): ModelNode | ModelDocumentFragment | {\n\tmodel: ModelNode | ModelDocumentFragment;\n\tselection: ModelSelection;\n} {\n\tconst mapper = new Mapper();\n\n\t// Replace not accepted by XML `$text` tag name by valid one `model-text-with-attributes`.\n\tdata = data.replace( new RegExp( '\\\\$text', 'g' ), 'model-text-with-attributes' );\n\n\t// Parse data to view using view utils.\n\tconst parsedResult = viewParse( data, {\n\t\tsameSelectionCharacters: true,\n\t\tlastRangeBackward: !!options.lastRangeBackward,\n\t\tinlineObjectElements: options.inlineObjectElements\n\t} );\n\n\t// Retrieve DocumentFragment and Selection from parsed view.\n\tlet viewDocumentFragment: ViewNode | ViewDocumentFragment;\n\tlet viewSelection: ViewDocumentSelection | null = null;\n\tlet selection: ModelSelection | null = null;\n\n\tif ( 'view' in parsedResult && 'selection' in parsedResult ) {\n\t\tviewDocumentFragment = parsedResult.view;\n\t\tviewSelection = parsedResult.selection;\n\t} else {\n\t\tviewDocumentFragment = parsedResult;\n\t}\n\n\t// Set up upcast dispatcher.\n\tconst modelController = new Model();\n\tconst upcastDispatcher = new UpcastDispatcher( { schema } );\n\n\tupcastDispatcher.on<UpcastDocumentFragmentEvent>( 'documentFragment', convertToModelFragment( mapper ) );\n\tupcastDispatcher.on<UpcastElementEvent>( 'element:model-text-with-attributes', convertToModelText() );\n\tupcastDispatcher.on<UpcastElementEvent>( 'element', convertToModelElement( mapper ) );\n\tupcastDispatcher.on<UpcastTextEvent>( 'text', convertToModelText() );\n\n\t// Convert view to model.\n\tlet model: ModelDocumentFragment | ModelNode = modelController.change(\n\t\twriter => upcastDispatcher.convert( viewDocumentFragment.root, writer, options.context || '$root' )\n\t);\n\n\tmapper.bindElements( model, viewDocumentFragment.root );\n\n\t// If root DocumentFragment contains only one element - return that element.\n\tif ( model.childCount == 1 ) {\n\t\tmodel = model.getChild( 0 )!;\n\t}\n\n\t// Convert view selection to model selection.\n\n\tif ( viewSelection ) {\n\t\tconst ranges: Array<ModelRange> = [];\n\n\t\t// Convert ranges.\n\t\tfor ( const viewRange of viewSelection.getRanges() ) {\n\t\t\tranges.push( mapper.toModelRange( viewRange ) );\n\t\t}\n\n\t\t// Create new selection.\n\t\tselection = new ModelSelection( ranges, { backward: viewSelection.isBackward } );\n\n\t\t// Set attributes to selection if specified.\n\t\tfor ( const [ key, value ] of toMap( options.selectionAttributes || [] ) ) {\n\t\t\tselection.setAttribute( key, value );\n\t\t}\n\t}\n\n\t// Return model end selection when selection was specified.\n\tif ( selection ) {\n\t\treturn { model, selection };\n\t}\n\n\t// Otherwise return model only.\n\treturn model;\n}\n\n// -- Converters view -> model -----------------------------------------------------\n\nfunction convertToModelFragment( mapper: Mapper ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewDocumentFragment>,\n\t\tconversionApi: UpcastConversionApi\n\t) => {\n\t\tconst childrenResult = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n\n\t\tmapper.bindElements( data.modelCursor.parent, data.viewItem );\n\n\t\tdata = Object.assign( data, childrenResult );\n\n\t\tevt.stop();\n\t};\n}\n\nfunction convertToModelElement( mapper: Mapper ) {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewElement>,\n\t\tconversionApi: UpcastConversionApi\n\t) => {\n\t\tconst elementName = data.viewItem.name;\n\n\t\tif ( !conversionApi.schema.checkChild( data.modelCursor, elementName ) ) {\n\t\t\tthrow new Error( `Element '${ elementName }' was not allowed in given position.` );\n\t\t}\n\n\t\t// View attribute value is a string so we want to typecast it to the original type.\n\t\t// E.g. `bold=\"true\"` - value will be parsed from string `\"true\"` to boolean `true`.\n\t\tconst attributes = convertAttributes( data.viewItem.getAttributes(), parseAttributeValue );\n\t\tconst element = conversionApi.writer.createElement( data.viewItem.name, attributes );\n\n\t\tconversionApi.writer.insert( element, data.modelCursor );\n\n\t\tmapper.bindElements( element, data.viewItem );\n\n\t\tconversionApi.convertChildren( data.viewItem, element );\n\n\t\tdata.modelRange = ModelRange._createOn( element );\n\t\tdata.modelCursor = data.modelRange.end;\n\n\t\tevt.stop();\n\t};\n}\n\nfunction convertToModelText() {\n\treturn (\n\t\tevt: EventInfo,\n\t\tdata: UpcastConversionData<ViewElement | ViewText >,\n\t\tconversionApi: UpcastConversionApi\n\t) => {\n\t\tif ( !conversionApi.schema.checkChild( data.modelCursor, '$text' ) ) {\n\t\t\tthrow new Error( 'Text was not allowed in given position.' );\n\t\t}\n\n\t\tlet node;\n\n\t\tif ( data.viewItem.is( 'element' ) ) {\n\t\t\t// View attribute value is a string so we want to typecast it to the original type.\n\t\t\t// E.g. `bold=\"true\"` - value will be parsed from string `\"true\"` to boolean `true`.\n\t\t\tconst attributes = convertAttributes( data.viewItem.getAttributes(), parseAttributeValue );\n\t\t\tconst viewText = data.viewItem.getChild( 0 ) as ViewText;\n\n\t\t\tnode = conversionApi.writer.createText( viewText.data, attributes );\n\t\t} else {\n\t\t\tnode = conversionApi.writer.createText( data.viewItem.data );\n\t\t}\n\n\t\tconversionApi.writer.insert( node, data.modelCursor );\n\n\t\tdata.modelRange = ModelRange._createFromPositionAndShift( data.modelCursor, node.offsetSize );\n\t\tdata.modelCursor = data.modelRange.end;\n\n\t\tevt.stop();\n\t};\n}\n\n// Tries to get original type of attribute value using JSON parsing:\n//\n//\t\t`'true'` => `true`\n//\t\t`'1'` => `1`\n//\t\t`'{\"x\":1,\"y\":2}'` => `{ x: 1, y: 2 }`\n//\n// Parse error means that value should be a string:\n//\n//\t\t`'foobar'` => `'foobar'`\nfunction parseAttributeValue( attribute: string ): any {\n\ttry {\n\t\treturn JSON.parse( attribute );\n\t} catch ( e ) {\n\t\treturn attribute;\n\t}\n}\n\n// When value is an Object stringify it.\nfunction stringifyAttributeValue( data: any ): string {\n\tif ( isPlainObject( data ) ) {\n\t\treturn JSON.stringify( data );\n\t}\n\n\treturn data;\n}\n\n// Loop trough attributes map and converts each value by passed converter.\nfunction* convertAttributes(\n\tattributes: IterableIterator<[ string, unknown ]>,\n\tconverter: ( data: any ) => string\n): IterableIterator<[ string, string ]> {\n\tfor ( const [ key, value ] of attributes ) {\n\t\tyield [ key, converter( value ) ];\n\t}\n}\n", "import { throttle, isElement, cloneDeepWith } from 'lodash-es';\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module watchdog/watchdog\n */ /* globals window */ // eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\n/**\n * An abstract watchdog class that handles most of the error handling process and the state of the underlying component.\n *\n * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and how to use it.\n *\n * @internal\n */ class Watchdog {\n    /**\n\t * An array of crashes saved as an object with the following properties:\n\t *\n\t * * `message`: `String`,\n\t * * `stack`: `String`,\n\t * * `date`: `Number`,\n\t * * `filename`: `String | undefined`,\n\t * * `lineno`: `Number | undefined`,\n\t * * `colno`: `Number | undefined`,\n\t */ crashes = [];\n    /**\n\t * Specifies the state of the item watched by the watchdog. The state can be one of the following values:\n\t *\n\t * * `initializing` &ndash; Before the first initialization, and after crashes, before the item is ready.\n\t * * `ready` &ndash; A state when the user can interact with the item.\n\t * * `crashed` &ndash; A state when an error occurs. It quickly changes to `initializing` or `crashedPermanently`\n\t * depending on how many and how frequent errors have been caught recently.\n\t * * `crashedPermanently` &ndash; A state when the watchdog stops reacting to errors and keeps the item it is watching crashed,\n\t * * `destroyed` &ndash; A state when the item is manually destroyed by the user after calling `watchdog.destroy()`.\n\t */ state = 'initializing';\n    /**\n\t * @see module:watchdog/watchdog~WatchdogConfig\n\t */ _crashNumberLimit;\n    /**\n\t * Returns the result of the `Date.now()` call. It can be overridden in tests to mock time as some popular\n\t * approaches like `sinon.useFakeTimers()` do not work well with error handling.\n\t */ _now = Date.now;\n    /**\n\t * @see module:watchdog/watchdog~WatchdogConfig\n\t */ _minimumNonErrorTimePeriod;\n    /**\n\t * Checks if the event error comes from the underlying item and restarts the item.\n\t */ _boundErrorHandler;\n    /**\n\t * A dictionary of event emitter listeners.\n\t */ _listeners;\n    /**\n\t * @param {module:watchdog/watchdog~WatchdogConfig} config The watchdog plugin configuration.\n\t */ constructor(config){\n        this.crashes = [];\n        this._crashNumberLimit = typeof config.crashNumberLimit === 'number' ? config.crashNumberLimit : 3;\n        this._minimumNonErrorTimePeriod = typeof config.minimumNonErrorTimePeriod === 'number' ? config.minimumNonErrorTimePeriod : 5000;\n        this._boundErrorHandler = (evt)=>{\n            // `evt.error` is exposed by EventError while `evt.reason` is available in PromiseRejectionEvent.\n            const error = 'error' in evt ? evt.error : evt.reason;\n            // Note that `evt.reason` might be everything that is in the promise rejection.\n            // Similarly everything that is thrown lands in `evt.error`.\n            if (error instanceof Error) {\n                this._handleError(error, evt);\n            }\n        };\n        this._listeners = {};\n        if (!this._restart) {\n            throw new Error('The Watchdog class was split into the abstract `Watchdog` class and the `EditorWatchdog` class. ' + 'Please, use `EditorWatchdog` if you have used the `Watchdog` class previously.');\n        }\n    }\n    /**\n\t * Destroys the watchdog and releases the resources.\n\t */ destroy() {\n        this._stopErrorHandling();\n        this._listeners = {};\n    }\n    /**\n\t * Starts listening to a specific event name by registering a callback that will be executed\n\t * whenever an event with a given name fires.\n\t *\n\t * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.\n\t *\n\t * @param eventName The event name.\n\t * @param callback A callback which will be added to event listeners.\n\t */ on(eventName, callback) {\n        if (!this._listeners[eventName]) {\n            this._listeners[eventName] = [];\n        }\n        this._listeners[eventName].push(callback);\n    }\n    /**\n\t * Stops listening to the specified event name by removing the callback from event listeners.\n\t *\n\t * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.\n\t *\n\t * @param eventName The event name.\n\t * @param callback A callback which will be removed from event listeners.\n\t */ off(eventName, callback) {\n        this._listeners[eventName] = this._listeners[eventName].filter((cb)=>cb !== callback);\n    }\n    /**\n\t * Fires an event with a given event name and arguments.\n\t *\n\t * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.\n\t */ _fire(eventName, ...args) {\n        const callbacks = this._listeners[eventName] || [];\n        for (const callback of callbacks){\n            callback.apply(this, [\n                null,\n                ...args\n            ]);\n        }\n    }\n    /**\n\t * Starts error handling by attaching global error handlers.\n\t */ _startErrorHandling() {\n        window.addEventListener('error', this._boundErrorHandler);\n        window.addEventListener('unhandledrejection', this._boundErrorHandler);\n    }\n    /**\n\t * Stops error handling by detaching global error handlers.\n\t */ _stopErrorHandling() {\n        window.removeEventListener('error', this._boundErrorHandler);\n        window.removeEventListener('unhandledrejection', this._boundErrorHandler);\n    }\n    /**\n\t * Checks if an error comes from the watched item and restarts it.\n\t * It reacts to {@link module:utils/ckeditorerror~CKEditorError `CKEditorError` errors} only.\n\t *\n\t * @fires error\n\t * @param error Error.\n\t * @param evt An error event.\n\t */ _handleError(error, evt) {\n        // @if CK_DEBUG // const err = error as CKEditorError;\n        // @if CK_DEBUG // if ( err.is && err.is( 'CKEditorError' ) && err.context === undefined ) {\n        // @if CK_DEBUG // console.warn( 'The error is missing its context and Watchdog cannot restart the proper item.' );\n        // @if CK_DEBUG // }\n        if (this._shouldReactToError(error)) {\n            this.crashes.push({\n                message: error.message,\n                stack: error.stack,\n                // `evt.filename`, `evt.lineno` and `evt.colno` are available only in ErrorEvent events\n                filename: evt instanceof ErrorEvent ? evt.filename : undefined,\n                lineno: evt instanceof ErrorEvent ? evt.lineno : undefined,\n                colno: evt instanceof ErrorEvent ? evt.colno : undefined,\n                date: this._now()\n            });\n            const causesRestart = this._shouldRestart();\n            this.state = 'crashed';\n            this._fire('stateChange');\n            this._fire('error', {\n                error,\n                causesRestart\n            });\n            if (causesRestart) {\n                this._restart();\n            } else {\n                this.state = 'crashedPermanently';\n                this._fire('stateChange');\n            }\n        }\n    }\n    /**\n\t * Checks whether an error should be handled by the watchdog.\n\t *\n\t * @param error An error that was caught by the error handling process.\n\t */ _shouldReactToError(error) {\n        return error.is && error.is('CKEditorError') && error.context !== undefined && // In some cases the watched item should not be restarted - e.g. during the item initialization.\n        // That's why the `null` was introduced as a correct error context which does cause restarting.\n        error.context !== null && // Do not react to errors if the watchdog is in states other than `ready`.\n        this.state === 'ready' && this._isErrorComingFromThisItem(error);\n    }\n    /**\n\t * Checks if the watchdog should restart the underlying item.\n\t */ _shouldRestart() {\n        if (this.crashes.length <= this._crashNumberLimit) {\n            return true;\n        }\n        const lastErrorTime = this.crashes[this.crashes.length - 1].date;\n        const firstMeaningfulErrorTime = this.crashes[this.crashes.length - 1 - this._crashNumberLimit].date;\n        const averageNonErrorTimePeriod = (lastErrorTime - firstMeaningfulErrorTime) / this._crashNumberLimit;\n        return averageNonErrorTimePeriod > this._minimumNonErrorTimePeriod;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module watchdog/utils/getsubnodes\n */ /* globals EventTarget, Event */ function getSubNodes(head, excludedProperties = new Set()) {\n    const nodes = [\n        head\n    ];\n    // @if CK_DEBUG_WATCHDOG // const prevNodeMap = new Map();\n    // Nodes are stored to prevent infinite looping.\n    const subNodes = new Set();\n    let nodeIndex = 0;\n    while(nodes.length > nodeIndex){\n        // Incrementing the iterator is much faster than changing size of the array with Array.prototype.shift().\n        const node = nodes[nodeIndex++];\n        if (subNodes.has(node) || !shouldNodeBeIncluded(node) || excludedProperties.has(node)) {\n            continue;\n        }\n        subNodes.add(node);\n        // Handle arrays, maps, sets, custom collections that implements `[ Symbol.iterator ]()`, etc.\n        if (Symbol.iterator in node) {\n            // The custom editor iterators might cause some problems if the editor is crashed.\n            try {\n                for (const n of node){\n                    nodes.push(n);\n                // @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( n ) ) {\n                // @if CK_DEBUG_WATCHDOG // \tprevNodeMap.set( n, node );\n                // @if CK_DEBUG_WATCHDOG // }\n                }\n            } catch (err) {\n            // Do not log errors for broken structures\n            // since we are in the error handling process already.\n            // eslint-disable-line no-empty\n            }\n        } else {\n            for(const key in node){\n                // We share a reference via the protobuf library within the editors,\n                // hence the shared value should be skipped. Although, it's not a perfect\n                // solution since new places like that might occur in the future.\n                if (key === 'defaultValue') {\n                    continue;\n                }\n                nodes.push(node[key]);\n            // @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( node[ key ] ) ) {\n            // @if CK_DEBUG_WATCHDOG // \tprevNodeMap.set( node[ key ], node );\n            // @if CK_DEBUG_WATCHDOG // }\n            }\n        }\n    }\n    // @if CK_DEBUG_WATCHDOG // return { subNodes, prevNodeMap } as any;\n    return subNodes;\n}\nfunction shouldNodeBeIncluded(node) {\n    const type = Object.prototype.toString.call(node);\n    const typeOfNode = typeof node;\n    return !(typeOfNode === 'number' || typeOfNode === 'boolean' || typeOfNode === 'string' || typeOfNode === 'symbol' || typeOfNode === 'function' || type === '[object Date]' || type === '[object RegExp]' || type === '[object Module]' || node === undefined || node === null || // This flag is meant to exclude singletons shared across editor instances. So when an error is thrown in one editor,\n    // the other editors connected through the reference to the same singleton are not restarted. This is a temporary workaround\n    // until a better solution is found.\n    // More in https://github.com/ckeditor/ckeditor5/issues/12292.\n    node._watchdogExcluded || // Skip native DOM objects, e.g. Window, nodes, events, etc.\n    node instanceof EventTarget || node instanceof Event);\n}\n\n/**\n * Traverses both structures to find out whether there is a reference that is shared between both structures.\n */ function areConnectedThroughProperties(target1, target2, excludedNodes = new Set()) {\n    if (target1 === target2 && isObject(target1)) {\n        return true;\n    }\n    // @if CK_DEBUG_WATCHDOG // return checkConnectionBetweenProps( target1, target2, excludedNodes );\n    const subNodes1 = getSubNodes(target1, excludedNodes);\n    const subNodes2 = getSubNodes(target2, excludedNodes);\n    for (const node of subNodes1){\n        if (subNodes2.has(node)) {\n            return true;\n        }\n    }\n    return false;\n}\nfunction isObject(structure) {\n    return typeof structure === 'object' && structure !== null;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module watchdog/editorwatchdog\n */ /* globals console */ // eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\n/**\n * A watchdog for CKEditor 5 editors.\n *\n * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and\n * how to use it.\n */ class EditorWatchdog extends Watchdog {\n    /**\n\t * The current editor instance.\n\t */ _editor = null;\n    /**\n\t * A promise associated with the life cycle of the editor (creation or destruction processes).\n\t *\n\t * It is used to prevent the initialization of the editor if the previous instance has not been destroyed yet,\n\t * and conversely, to prevent the destruction of the editor if it has not been initialized.\n\t */ _lifecyclePromise = null;\n    /**\n\t * Throttled save method. The `save()` method is called the specified `saveInterval` after `throttledSave()` is called,\n\t * unless a new action happens in the meantime.\n\t */ _throttledSave;\n    /**\n\t * The latest saved editor data represented as a root name -> root data object.\n\t */ _data;\n    /**\n\t * The last document version.\n\t */ _lastDocumentVersion;\n    /**\n\t * The editor source element or data.\n\t */ _elementOrData;\n    /**\n\t * Specifies whether the editor was initialized using document data (`true`) or HTML elements (`false`).\n\t */ _initUsingData = true;\n    /**\n\t * The latest record of the editor editable elements. Used to restart the editor.\n\t */ _editables = {};\n    /**\n\t * The editor configuration.\n\t */ _config;\n    _excludedProps;\n    /**\n\t * @param Editor The editor class.\n\t * @param watchdogConfig The watchdog plugin configuration.\n\t */ constructor(Editor, watchdogConfig = {}){\n        super(watchdogConfig);\n        // this._editorClass = Editor;\n        this._throttledSave = throttle(this._save.bind(this), typeof watchdogConfig.saveInterval === 'number' ? watchdogConfig.saveInterval : 5000);\n        // Set default creator and destructor functions:\n        if (Editor) {\n            this._creator = (elementOrData, config)=>Editor.create(elementOrData, config);\n        }\n        this._destructor = (editor)=>editor.destroy();\n    }\n    /**\n\t * The current editor instance.\n\t */ get editor() {\n        return this._editor;\n    }\n    /**\n\t * @internal\n\t */ get _item() {\n        return this._editor;\n    }\n    /**\n\t * Sets the function that is responsible for the editor creation.\n\t * It expects a function that should return a promise.\n\t *\n\t * ```ts\n\t * watchdog.setCreator( ( element, config ) => ClassicEditor.create( element, config ) );\n\t * ```\n\t */ setCreator(creator) {\n        this._creator = creator;\n    }\n    /**\n\t * Sets the function that is responsible for the editor destruction.\n\t * Overrides the default destruction function, which destroys only the editor instance.\n\t * It expects a function that should return a promise or `undefined`.\n\t *\n\t * ```ts\n\t * watchdog.setDestructor( editor => {\n\t * \t// Do something before the editor is destroyed.\n\t *\n\t * \treturn editor\n\t * \t\t.destroy()\n\t * \t\t.then( () => {\n\t * \t\t\t// Do something after the editor is destroyed.\n\t * \t\t} );\n\t * } );\n\t * ```\n\t */ setDestructor(destructor) {\n        this._destructor = destructor;\n    }\n    /**\n\t * Restarts the editor instance. This method is called whenever an editor error occurs. It fires the `restart` event and changes\n\t * the state to `initializing`.\n\t *\n\t * @fires restart\n\t */ _restart() {\n        return Promise.resolve().then(()=>{\n            this.state = 'initializing';\n            this._fire('stateChange');\n            return this._destroy();\n        }).catch((err)=>{\n            console.error('An error happened during the editor destroying.', err);\n        }).then(()=>{\n            // Pre-process some data from the original editor config.\n            // Our goal here is to make sure that the restarted editor will be reinitialized with correct set of roots.\n            // We are not interested in any data set in config or in `.create()` first parameter. It will be replaced anyway.\n            // But we need to set them correctly to make sure that proper roots are created.\n            //\n            // Since a different set of roots will be created, `lazyRoots` and `rootsAttributes` properties must be managed too.\n            // Keys are root names, values are ''. Used when the editor was initialized by setting the first parameter to document data.\n            const existingRoots = {};\n            // Keeps lazy roots. They may be different when compared to initial config if some of the roots were loaded.\n            const lazyRoots = [];\n            // Roots attributes from the old config. Will be referred when setting new attributes.\n            const oldRootsAttributes = this._config.rootsAttributes || {};\n            // New attributes to be set. Is filled only for roots that still exist in the document.\n            const rootsAttributes = {};\n            // Traverse through the roots saved when the editor crashed and set up the discussed values.\n            for (const [rootName, rootData] of Object.entries(this._data.roots)){\n                if (rootData.isLoaded) {\n                    existingRoots[rootName] = '';\n                    rootsAttributes[rootName] = oldRootsAttributes[rootName] || {};\n                } else {\n                    lazyRoots.push(rootName);\n                }\n            }\n            const updatedConfig = {\n                ...this._config,\n                extraPlugins: this._config.extraPlugins || [],\n                lazyRoots,\n                rootsAttributes,\n                _watchdogInitialData: this._data\n            };\n            // Delete `initialData` as it is not needed. Data will be set by the watchdog based on `_watchdogInitialData`.\n            // First parameter of the editor `.create()` will be used to set up initial roots.\n            delete updatedConfig.initialData;\n            updatedConfig.extraPlugins.push(EditorWatchdogInitPlugin);\n            if (this._initUsingData) {\n                return this.create(existingRoots, updatedConfig, updatedConfig.context);\n            } else {\n                // Set correct editables to make sure that proper roots are created and linked with DOM elements.\n                // No need to set initial data, as it would be discarded anyway.\n                //\n                // If one element was initially set in `elementOrData`, then use that original element to restart the editor.\n                // This is for compatibility purposes with single-root editor types.\n                if (isElement(this._elementOrData)) {\n                    return this.create(this._elementOrData, updatedConfig, updatedConfig.context);\n                } else {\n                    return this.create(this._editables, updatedConfig, updatedConfig.context);\n                }\n            }\n        }).then(()=>{\n            this._fire('restart');\n        });\n    }\n    /**\n\t * Creates the editor instance and keeps it running, using the defined creator and destructor.\n\t *\n\t * @param elementOrData The editor source element or the editor data.\n\t * @param config The editor configuration.\n\t * @param context A context for the editor.\n\t */ create(elementOrData = this._elementOrData, config = this._config, context) {\n        this._lifecyclePromise = Promise.resolve(this._lifecyclePromise).then(()=>{\n            super._startErrorHandling();\n            this._elementOrData = elementOrData;\n            // Use document data in the first parameter of the editor `.create()` call only if it was used like this originally.\n            // Use document data if a string or object with strings was passed.\n            this._initUsingData = typeof elementOrData == 'string' || Object.keys(elementOrData).length > 0 && typeof Object.values(elementOrData)[0] == 'string';\n            // Clone configuration because it might be shared within multiple watchdog instances. Otherwise,\n            // when an error occurs in one of these editors, the watchdog will restart all of them.\n            this._config = this._cloneEditorConfiguration(config) || {};\n            this._config.context = context;\n            return this._creator(elementOrData, this._config);\n        }).then((editor)=>{\n            this._editor = editor;\n            editor.model.document.on('change:data', this._throttledSave);\n            this._lastDocumentVersion = editor.model.document.version;\n            this._data = this._getData();\n            if (!this._initUsingData) {\n                this._editables = this._getEditables();\n            }\n            this.state = 'ready';\n            this._fire('stateChange');\n        }).finally(()=>{\n            this._lifecyclePromise = null;\n        });\n        return this._lifecyclePromise;\n    }\n    /**\n\t * Destroys the watchdog and the current editor instance. It fires the callback\n\t * registered in {@link #setDestructor `setDestructor()`} and uses it to destroy the editor instance.\n\t * It also sets the state to `destroyed`.\n\t */ destroy() {\n        this._lifecyclePromise = Promise.resolve(this._lifecyclePromise).then(()=>{\n            this.state = 'destroyed';\n            this._fire('stateChange');\n            super.destroy();\n            return this._destroy();\n        }).finally(()=>{\n            this._lifecyclePromise = null;\n        });\n        return this._lifecyclePromise;\n    }\n    _destroy() {\n        return Promise.resolve().then(()=>{\n            this._stopErrorHandling();\n            this._throttledSave.cancel();\n            const editor = this._editor;\n            this._editor = null;\n            // Remove the `change:data` listener before destroying the editor.\n            // Incorrectly written plugins may trigger firing `change:data` events during the editor destruction phase\n            // causing the watchdog to call `editor.getData()` when some parts of editor are already destroyed.\n            editor.model.document.off('change:data', this._throttledSave);\n            return this._destructor(editor);\n        });\n    }\n    /**\n\t * Saves the editor data, so it can be restored after the crash even if the data cannot be fetched at\n\t * the moment of the crash.\n\t */ _save() {\n        const version = this._editor.model.document.version;\n        try {\n            this._data = this._getData();\n            if (!this._initUsingData) {\n                this._editables = this._getEditables();\n            }\n            this._lastDocumentVersion = version;\n        } catch (err) {\n            console.error(err, 'An error happened during restoring editor data. ' + 'Editor will be restored from the previously saved data.');\n        }\n    }\n    /**\n\t * @internal\n\t */ _setExcludedProperties(props) {\n        this._excludedProps = props;\n    }\n    /**\n\t * Gets all data that is required to reinitialize editor instance.\n\t */ _getData() {\n        const editor = this._editor;\n        const roots = editor.model.document.roots.filter((root)=>root.isAttached() && root.rootName != '$graveyard');\n        const { plugins } = editor;\n        // `as any` to avoid linking from external private repo.\n        const commentsRepository = plugins.has('CommentsRepository') && plugins.get('CommentsRepository');\n        const trackChanges = plugins.has('TrackChanges') && plugins.get('TrackChanges');\n        const data = {\n            roots: {},\n            markers: {},\n            commentThreads: JSON.stringify([]),\n            suggestions: JSON.stringify([])\n        };\n        roots.forEach((root)=>{\n            data.roots[root.rootName] = {\n                content: JSON.stringify(Array.from(root.getChildren())),\n                attributes: JSON.stringify(Array.from(root.getAttributes())),\n                isLoaded: root._isLoaded\n            };\n        });\n        for (const marker of editor.model.markers){\n            if (!marker._affectsData) {\n                continue;\n            }\n            data.markers[marker.name] = {\n                rangeJSON: marker.getRange().toJSON(),\n                usingOperation: marker._managedUsingOperations,\n                affectsData: marker._affectsData\n            };\n        }\n        if (commentsRepository) {\n            data.commentThreads = JSON.stringify(commentsRepository.getCommentThreads({\n                toJSON: true,\n                skipNotAttached: true\n            }));\n        }\n        if (trackChanges) {\n            data.suggestions = JSON.stringify(trackChanges.getSuggestions({\n                toJSON: true,\n                skipNotAttached: true\n            }));\n        }\n        return data;\n    }\n    /**\n\t * For each attached model root, returns its HTML editable element (if available).\n\t */ _getEditables() {\n        const editables = {};\n        for (const rootName of this.editor.model.document.getRootNames()){\n            const editable = this.editor.ui.getEditableElement(rootName);\n            if (editable) {\n                editables[rootName] = editable;\n            }\n        }\n        return editables;\n    }\n    /**\n\t * Traverses the error context and the current editor to find out whether these structures are connected\n\t * to each other via properties.\n\t *\n\t * @internal\n\t */ _isErrorComingFromThisItem(error) {\n        return areConnectedThroughProperties(this._editor, error.context, this._excludedProps);\n    }\n    /**\n\t * Clones the editor configuration.\n\t */ _cloneEditorConfiguration(config) {\n        return cloneDeepWith(config, (value, key)=>{\n            // Leave DOM references.\n            if (isElement(value)) {\n                return value;\n            }\n            if (key === 'context') {\n                return value;\n            }\n        });\n    }\n}\n/**\n * Internal plugin that is used to stop the default editor initialization and restoring the editor state\n * based on the `editor.config._watchdogInitialData` data.\n */ class EditorWatchdogInitPlugin {\n    editor;\n    _data;\n    constructor(editor){\n        this.editor = editor;\n        this._data = editor.config.get('_watchdogInitialData');\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        // Stops the default editor initialization and use the saved data to restore the editor state.\n        // Some of data could not be initialize as a config properties. It is important to keep the data\n        // in the same form as it was before the restarting.\n        this.editor.data.on('init', (evt)=>{\n            evt.stop();\n            this.editor.model.enqueueChange({\n                isUndoable: false\n            }, (writer)=>{\n                this._restoreCollaborationData();\n                this._restoreEditorData(writer);\n            });\n            this.editor.data.fire('ready');\n        // Keep priority `'high' - 1` to be sure that RTC initialization will be first.\n        }, {\n            priority: 1000 - 1\n        });\n    }\n    /**\n\t * Creates a model node (element or text) based on provided JSON.\n\t */ _createNode(writer, jsonNode) {\n        if ('name' in jsonNode) {\n            // If child has name property, it is an Element.\n            const element = writer.createElement(jsonNode.name, jsonNode.attributes);\n            if (jsonNode.children) {\n                for (const child of jsonNode.children){\n                    element._appendChild(this._createNode(writer, child));\n                }\n            }\n            return element;\n        } else {\n            // Otherwise, it is a Text node.\n            return writer.createText(jsonNode.data, jsonNode.attributes);\n        }\n    }\n    /**\n\t * Restores the editor by setting the document data, roots attributes and markers.\n\t */ _restoreEditorData(writer) {\n        const editor = this.editor;\n        Object.entries(this._data.roots).forEach(([rootName, { content, attributes }])=>{\n            const parsedNodes = JSON.parse(content);\n            const parsedAttributes = JSON.parse(attributes);\n            const rootElement = editor.model.document.getRoot(rootName);\n            for (const [key, value] of parsedAttributes){\n                writer.setAttribute(key, value, rootElement);\n            }\n            for (const child of parsedNodes){\n                const node = this._createNode(writer, child);\n                writer.insert(node, rootElement, 'end');\n            }\n        });\n        Object.entries(this._data.markers).forEach(([markerName, markerOptions])=>{\n            const { document } = editor.model;\n            const { rangeJSON: { start, end }, ...options } = markerOptions;\n            const root = document.getRoot(start.root);\n            const startPosition = writer.createPositionFromPath(root, start.path, start.stickiness);\n            const endPosition = writer.createPositionFromPath(root, end.path, end.stickiness);\n            const range = writer.createRange(startPosition, endPosition);\n            writer.addMarker(markerName, {\n                range,\n                ...options\n            });\n        });\n    }\n    /**\n\t * Restores the editor collaboration data - comment threads and suggestions.\n\t */ _restoreCollaborationData() {\n        // `as any` to avoid linking from external private repo.\n        const parsedCommentThreads = JSON.parse(this._data.commentThreads);\n        const parsedSuggestions = JSON.parse(this._data.suggestions);\n        parsedCommentThreads.forEach((commentThreadData)=>{\n            const channelId = this.editor.config.get('collaboration.channelId');\n            const commentsRepository = this.editor.plugins.get('CommentsRepository');\n            if (commentsRepository.hasCommentThread(commentThreadData.threadId)) {\n                const commentThread = commentsRepository.getCommentThread(commentThreadData.threadId);\n                commentThread.remove();\n            }\n            commentsRepository.addCommentThread({\n                channelId,\n                ...commentThreadData\n            });\n        });\n        parsedSuggestions.forEach((suggestionData)=>{\n            const trackChangesEditing = this.editor.plugins.get('TrackChangesEditing');\n            if (trackChangesEditing.hasSuggestion(suggestionData.id)) {\n                const suggestion = trackChangesEditing.getSuggestion(suggestionData.id);\n                suggestion.attributes = suggestionData.attributes;\n            } else {\n                trackChangesEditing.addSuggestionData(suggestionData);\n            }\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module watchdog/contextwatchdog\n */ /* globals console */ // eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nconst mainQueueId = Symbol('MainQueueId');\n/**\n * A watchdog for the {@link module:core/context~Context} class.\n *\n * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and\n * how to use it.\n */ class ContextWatchdog extends Watchdog {\n    /**\n\t * A map of internal watchdogs for added items.\n\t */ _watchdogs = new Map();\n    /**\n\t * The watchdog configuration.\n\t */ _watchdogConfig;\n    /**\n\t * The current context instance.\n\t */ _context = null;\n    /**\n\t * Context properties (nodes/references) that are gathered during the initial context creation\n\t * and are used to distinguish the origin of an error.\n\t */ _contextProps = new Set();\n    /**\n\t * An action queue, which is used to handle async functions queuing.\n\t */ _actionQueues = new ActionQueues();\n    /**\n\t * The configuration for the {@link module:core/context~Context}.\n\t */ _contextConfig;\n    /**\n\t * The watched item.\n\t */ _item;\n    /**\n\t * The context watchdog class constructor.\n\t *\n\t * ```ts\n\t * const watchdog = new ContextWatchdog( Context );\n\t *\n\t * await watchdog.create( contextConfiguration );\n\t *\n\t * await watchdog.add( item );\n\t * ```\n\t *\n\t * See the {@glink features/watchdog Watchdog feature guide} to learn more how to use this feature.\n\t *\n\t * @param Context The {@link module:core/context~Context} class.\n\t * @param watchdogConfig The watchdog configuration.\n\t */ constructor(Context, watchdogConfig = {}){\n        super(watchdogConfig);\n        this._watchdogConfig = watchdogConfig;\n        // Default creator and destructor.\n        this._creator = (contextConfig)=>Context.create(contextConfig);\n        this._destructor = (context)=>context.destroy();\n        this._actionQueues.onEmpty(()=>{\n            if (this.state === 'initializing') {\n                this.state = 'ready';\n                this._fire('stateChange');\n            }\n        });\n    }\n    /**\n\t * Sets the function that is responsible for the context creation.\n\t * It expects a function that should return a promise (or `undefined`).\n\t *\n\t * ```ts\n\t * watchdog.setCreator( config => Context.create( config ) );\n\t * ```\n\t */ setCreator(creator) {\n        this._creator = creator;\n    }\n    /**\n\t * Sets the function that is responsible for the context destruction.\n\t * Overrides the default destruction function, which destroys only the context instance.\n\t * It expects a function that should return a promise (or `undefined`).\n\t *\n\t * ```ts\n\t * watchdog.setDestructor( context => {\n\t * \t// Do something before the context is destroyed.\n\t *\n\t * \treturn context\n\t * \t\t.destroy()\n\t * \t\t.then( () => {\n\t * \t\t\t// Do something after the context is destroyed.\n\t * \t\t} );\n\t * } );\n\t * ```\n\t */ setDestructor(destructor) {\n        this._destructor = destructor;\n    }\n    /**\n\t * The context instance. Keep in mind that this property might be changed when the context watchdog restarts,\n\t * so do not keep this instance internally. Always operate on the `ContextWatchdog#context` property.\n\t */ get context() {\n        return this._context;\n    }\n    /**\n\t * Initializes the context watchdog. Once it is created, the watchdog takes care about\n\t * recreating the context and the provided items, and starts the error handling mechanism.\n\t *\n\t * ```ts\n\t * await watchdog.create( {\n\t * \tplugins: []\n\t * } );\n\t * ```\n\t *\n\t * @param contextConfig The context configuration. See {@link module:core/context~Context}.\n\t */ create(contextConfig = {}) {\n        return this._actionQueues.enqueue(mainQueueId, ()=>{\n            this._contextConfig = contextConfig;\n            return this._create();\n        });\n    }\n    /**\n\t * Returns an item instance with the given `itemId`.\n\t *\n\t * ```ts\n\t * const editor1 = watchdog.getItem( 'editor1' );\n\t * ```\n\t *\n\t * @param itemId The item ID.\n\t * @returns The item instance or `undefined` if an item with a given ID has not been found.\n\t */ getItem(itemId) {\n        const watchdog = this._getWatchdog(itemId);\n        return watchdog._item;\n    }\n    /**\n\t * Gets the state of the given item. See {@link #state} for a list of available states.\n\t *\n\t * ```ts\n\t * const editor1State = watchdog.getItemState( 'editor1' );\n\t * ```\n\t *\n\t * @param itemId Item ID.\n\t * @returns The state of the item.\n\t */ getItemState(itemId) {\n        const watchdog = this._getWatchdog(itemId);\n        return watchdog.state;\n    }\n    /**\n\t * Adds items to the watchdog. Once created, instances of these items will be available using the {@link #getItem} method.\n\t *\n\t * Items can be passed together as an array of objects:\n\t *\n\t * ```ts\n\t * await watchdog.add( [ {\n\t * \tid: 'editor1',\n\t * \ttype: 'editor',\n\t * \tsourceElementOrData: document.querySelector( '#editor' ),\n\t * \tconfig: {\n\t * \t\tplugins: [ Essentials, Paragraph, Bold, Italic ],\n\t * \t\ttoolbar: [ 'bold', 'italic', 'alignment' ]\n\t * \t},\n\t * \tcreator: ( element, config ) => ClassicEditor.create( element, config )\n\t * } ] );\n\t * ```\n\t *\n\t * Or one by one as objects:\n\t *\n\t * ```ts\n\t * await watchdog.add( {\n\t * \tid: 'editor1',\n\t * \ttype: 'editor',\n\t * \tsourceElementOrData: document.querySelector( '#editor' ),\n\t * \tconfig: {\n\t * \t\tplugins: [ Essentials, Paragraph, Bold, Italic ],\n\t * \t\ttoolbar: [ 'bold', 'italic', 'alignment' ]\n\t * \t},\n\t * \tcreator: ( element, config ) => ClassicEditor.create( element, config )\n\t * ] );\n\t * ```\n\t *\n\t * Then an instance can be retrieved using the {@link #getItem} method:\n\t *\n\t * ```ts\n\t * const editor1 = watchdog.getItem( 'editor1' );\n\t * ```\n\t *\n\t * Note that this method can be called multiple times, but for performance reasons it is better\n\t * to pass all items together.\n\t *\n\t * @param itemConfigurationOrItemConfigurations An item configuration object or an array of item configurations.\n\t */ add(itemConfigurationOrItemConfigurations) {\n        const itemConfigurations = toArray(itemConfigurationOrItemConfigurations);\n        return Promise.all(itemConfigurations.map((item)=>{\n            return this._actionQueues.enqueue(item.id, ()=>{\n                if (this.state === 'destroyed') {\n                    throw new Error('Cannot add items to destroyed watchdog.');\n                }\n                if (!this._context) {\n                    throw new Error('Context was not created yet. You should call the `ContextWatchdog#create()` method first.');\n                }\n                let watchdog;\n                if (this._watchdogs.has(item.id)) {\n                    throw new Error(`Item with the given id is already added: '${item.id}'.`);\n                }\n                if (item.type === 'editor') {\n                    watchdog = new EditorWatchdog(null, this._watchdogConfig);\n                    watchdog.setCreator(item.creator);\n                    watchdog._setExcludedProperties(this._contextProps);\n                    if (item.destructor) {\n                        watchdog.setDestructor(item.destructor);\n                    }\n                    this._watchdogs.set(item.id, watchdog);\n                    // Enqueue the internal watchdog errors within the main queue.\n                    // And propagate the internal `error` events as `itemError` event.\n                    watchdog.on('error', (evt, { error, causesRestart })=>{\n                        this._fire('itemError', {\n                            itemId: item.id,\n                            error\n                        });\n                        // Do not enqueue the item restart action if the item will not restart.\n                        if (!causesRestart) {\n                            return;\n                        }\n                        this._actionQueues.enqueue(item.id, ()=>new Promise((res)=>{\n                                const rethrowRestartEventOnce = ()=>{\n                                    watchdog.off('restart', rethrowRestartEventOnce);\n                                    this._fire('itemRestart', {\n                                        itemId: item.id\n                                    });\n                                    res();\n                                };\n                                watchdog.on('restart', rethrowRestartEventOnce);\n                            }));\n                    });\n                    return watchdog.create(item.sourceElementOrData, item.config, this._context);\n                } else {\n                    throw new Error(`Not supported item type: '${item.type}'.`);\n                }\n            });\n        }));\n    }\n    /**\n\t * Removes and destroys item(s) with given ID(s).\n\t *\n\t * ```ts\n\t * await watchdog.remove( 'editor1' );\n\t * ```\n\t *\n\t * Or\n\t *\n\t * ```ts\n\t * await watchdog.remove( [ 'editor1', 'editor2' ] );\n\t * ```\n\t *\n\t * @param itemIdOrItemIds Item ID or an array of item IDs.\n\t */ remove(itemIdOrItemIds) {\n        const itemIds = toArray(itemIdOrItemIds);\n        return Promise.all(itemIds.map((itemId)=>{\n            return this._actionQueues.enqueue(itemId, ()=>{\n                const watchdog = this._getWatchdog(itemId);\n                this._watchdogs.delete(itemId);\n                return watchdog.destroy();\n            });\n        }));\n    }\n    /**\n\t * Destroys the context watchdog and all added items.\n\t * Once the context watchdog is destroyed, new items cannot be added.\n\t *\n\t * ```ts\n\t * await watchdog.destroy();\n\t * ```\n\t */ destroy() {\n        return this._actionQueues.enqueue(mainQueueId, ()=>{\n            this.state = 'destroyed';\n            this._fire('stateChange');\n            super.destroy();\n            return this._destroy();\n        });\n    }\n    /**\n\t * Restarts the context watchdog.\n\t */ _restart() {\n        return this._actionQueues.enqueue(mainQueueId, ()=>{\n            this.state = 'initializing';\n            this._fire('stateChange');\n            return this._destroy().catch((err)=>{\n                console.error('An error happened during destroying the context or items.', err);\n            }).then(()=>this._create()).then(()=>this._fire('restart'));\n        });\n    }\n    /**\n\t * Initializes the context watchdog.\n\t */ _create() {\n        return Promise.resolve().then(()=>{\n            this._startErrorHandling();\n            return this._creator(this._contextConfig);\n        }).then((context)=>{\n            this._context = context;\n            this._contextProps = getSubNodes(this._context);\n            return Promise.all(Array.from(this._watchdogs.values()).map((watchdog)=>{\n                watchdog._setExcludedProperties(this._contextProps);\n                return watchdog.create(undefined, undefined, this._context);\n            }));\n        });\n    }\n    /**\n\t * Destroys the context instance and all added items.\n\t */ _destroy() {\n        return Promise.resolve().then(()=>{\n            this._stopErrorHandling();\n            const context = this._context;\n            this._context = null;\n            this._contextProps = new Set();\n            return Promise.all(Array.from(this._watchdogs.values()).map((watchdog)=>watchdog.destroy()))// Context destructor destroys each editor.\n            .then(()=>this._destructor(context));\n        });\n    }\n    /**\n\t * Returns the watchdog for a given item ID.\n\t *\n\t * @param itemId Item ID.\n\t */ _getWatchdog(itemId) {\n        const watchdog = this._watchdogs.get(itemId);\n        if (!watchdog) {\n            throw new Error(`Item with the given id was not registered: ${itemId}.`);\n        }\n        return watchdog;\n    }\n    /**\n\t * Checks whether an error comes from the context instance and not from the item instances.\n\t *\n\t * @internal\n\t */ _isErrorComingFromThisItem(error) {\n        for (const watchdog of this._watchdogs.values()){\n            if (watchdog._isErrorComingFromThisItem(error)) {\n                return false;\n            }\n        }\n        return areConnectedThroughProperties(this._context, error.context);\n    }\n}\n/**\n * Manager of action queues that allows queuing async functions.\n */ class ActionQueues {\n    _onEmptyCallbacks = [];\n    _queues = new Map();\n    _activeActions = 0;\n    /**\n\t * Used to register callbacks that will be run when the queue becomes empty.\n\t *\n\t * @param onEmptyCallback A callback that will be run whenever the queue becomes empty.\n\t */ onEmpty(onEmptyCallback) {\n        this._onEmptyCallbacks.push(onEmptyCallback);\n    }\n    /**\n\t * It adds asynchronous actions (functions) to the proper queue and runs them one by one.\n\t *\n\t * @param queueId The action queue ID.\n\t * @param action A function that should be enqueued.\n\t */ enqueue(queueId, action) {\n        const isMainAction = queueId === mainQueueId;\n        this._activeActions++;\n        if (!this._queues.get(queueId)) {\n            this._queues.set(queueId, Promise.resolve());\n        }\n        // List all sources of actions that the current action needs to await for.\n        // For the main action wait for all other actions.\n        // For the item action wait only for the item queue and the main queue.\n        const awaitedActions = isMainAction ? Promise.all(this._queues.values()) : Promise.all([\n            this._queues.get(mainQueueId),\n            this._queues.get(queueId)\n        ]);\n        const queueWithAction = awaitedActions.then(action);\n        // Catch all errors in the main queue to stack promises even if an error occurred in the past.\n        const nonErrorQueue = queueWithAction.catch(()=>{});\n        this._queues.set(queueId, nonErrorQueue);\n        return queueWithAction.finally(()=>{\n            this._activeActions--;\n            if (this._queues.get(queueId) === nonErrorQueue && this._activeActions === 0) {\n                this._onEmptyCallbacks.forEach((cb)=>cb());\n            }\n        });\n    }\n}\n/**\n * Transforms any value to an array. If the provided value is already an array, it is returned unchanged.\n *\n * @param elementOrArray The value to transform to an array.\n * @returns An array created from data.\n */ function toArray(elementOrArray) {\n    return Array.isArray(elementOrArray) ? elementOrArray : [\n        elementOrArray\n    ];\n}\n\nexport { ContextWatchdog, EditorWatchdog, Watchdog };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module watchdog/watchdog\n */\n\n/* globals window */\n\n// eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nimport type { CKEditorError } from 'ckeditor5/src/utils.js';\nimport type { EditorWatchdogRestartEvent } from './editorwatchdog.js';\nimport type { ContextWatchdogItemErrorEvent, ContextWatchdogItemRestartEvent } from './contextwatchdog.js';\n\n/**\n * An abstract watchdog class that handles most of the error handling process and the state of the underlying component.\n *\n * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and how to use it.\n *\n * @internal\n */\nexport default abstract class Watchdog {\n\t/**\n\t * An array of crashes saved as an object with the following properties:\n\t *\n\t * * `message`: `String`,\n\t * * `stack`: `String`,\n\t * * `date`: `Number`,\n\t * * `filename`: `String | undefined`,\n\t * * `lineno`: `Number | undefined`,\n\t * * `colno`: `Number | undefined`,\n\t */\n\tpublic readonly crashes: Array<{\n\t\tmessage: string;\n\t\tstack?: string;\n\t\tdate: number;\n\n\t\t// `evt.filename`, `evt.lineno` and `evt.colno` are available only in ErrorEvent events\n\t\tfilename?: string;\n\t\tlineno?: number;\n\t\tcolno?: number;\n\t}> = [];\n\n\t/**\n\t * Specifies the state of the item watched by the watchdog. The state can be one of the following values:\n\t *\n\t * * `initializing` &ndash; Before the first initialization, and after crashes, before the item is ready.\n\t * * `ready` &ndash; A state when the user can interact with the item.\n\t * * `crashed` &ndash; A state when an error occurs. It quickly changes to `initializing` or `crashedPermanently`\n\t * depending on how many and how frequent errors have been caught recently.\n\t * * `crashedPermanently` &ndash; A state when the watchdog stops reacting to errors and keeps the item it is watching crashed,\n\t * * `destroyed` &ndash; A state when the item is manually destroyed by the user after calling `watchdog.destroy()`.\n\t */\n\tpublic state: WatchdogState = 'initializing';\n\n\t/**\n\t * @see module:watchdog/watchdog~WatchdogConfig\n\t */\n\tprivate _crashNumberLimit: number;\n\n\t/**\n\t * Returns the result of the `Date.now()` call. It can be overridden in tests to mock time as some popular\n\t * approaches like `sinon.useFakeTimers()` do not work well with error handling.\n\t */\n\tprivate _now = Date.now;\n\n\t/**\n\t * @see module:watchdog/watchdog~WatchdogConfig\n\t */\n\tprivate _minimumNonErrorTimePeriod: number;\n\n\t/**\n\t * Checks if the event error comes from the underlying item and restarts the item.\n\t */\n\tprivate _boundErrorHandler: ( evt: ErrorEvent | PromiseRejectionEvent ) => void;\n\n\t/**\n\t * The method responsible for restarting the watched item.\n\t */\n\tprotected abstract _restart(): Promise<unknown>;\n\n\t/**\n\t * Traverses the error context and the watched item to find out whether the error should\n\t * be handled by the given item.\n\t *\n\t * @internal\n\t */\n\tpublic abstract _isErrorComingFromThisItem( error: CKEditorError ): boolean;\n\n\t/**\n\t * The watched item.\n\t *\n\t * @internal\n\t */\n\tpublic abstract get _item(): unknown;\n\n\t/**\n\t * A dictionary of event emitter listeners.\n\t */\n\tprivate _listeners: Record<string, Array<( ...args: any ) => void>>;\n\n\t/**\n\t * @param {module:watchdog/watchdog~WatchdogConfig} config The watchdog plugin configuration.\n\t */\n\tconstructor( config: WatchdogConfig ) {\n\t\tthis.crashes = [];\n\t\tthis._crashNumberLimit = typeof config.crashNumberLimit === 'number' ? config.crashNumberLimit : 3;\n\t\tthis._minimumNonErrorTimePeriod = typeof config.minimumNonErrorTimePeriod === 'number' ? config.minimumNonErrorTimePeriod : 5000;\n\n\t\tthis._boundErrorHandler = evt => {\n\t\t\t// `evt.error` is exposed by EventError while `evt.reason` is available in PromiseRejectionEvent.\n\t\t\tconst error = 'error' in evt ? evt.error : evt.reason;\n\n\t\t\t// Note that `evt.reason` might be everything that is in the promise rejection.\n\t\t\t// Similarly everything that is thrown lands in `evt.error`.\n\t\t\tif ( error instanceof Error ) {\n\t\t\t\tthis._handleError( error, evt );\n\t\t\t}\n\t\t};\n\n\t\tthis._listeners = {};\n\n\t\tif ( !( this as any )._restart ) {\n\t\t\tthrow new Error(\n\t\t\t\t'The Watchdog class was split into the abstract `Watchdog` class and the `EditorWatchdog` class. ' +\n\t\t\t\t'Please, use `EditorWatchdog` if you have used the `Watchdog` class previously.'\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the watchdog and releases the resources.\n\t */\n\tpublic destroy(): void {\n\t\tthis._stopErrorHandling();\n\n\t\tthis._listeners = {};\n\t}\n\n\t/**\n\t * Starts listening to a specific event name by registering a callback that will be executed\n\t * whenever an event with a given name fires.\n\t *\n\t * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.\n\t *\n\t * @param eventName The event name.\n\t * @param callback A callback which will be added to event listeners.\n\t */\n\tpublic on<K extends keyof EventMap>( eventName: K, callback: EventCallback<K> ): void {\n\t\tif ( !this._listeners[ eventName ] ) {\n\t\t\tthis._listeners[ eventName ] = [];\n\t\t}\n\n\t\tthis._listeners[ eventName ].push( callback );\n\t}\n\n\t/**\n\t * Stops listening to the specified event name by removing the callback from event listeners.\n\t *\n\t * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.\n\t *\n\t * @param eventName The event name.\n\t * @param callback A callback which will be removed from event listeners.\n\t */\n\tpublic off( eventName: keyof EventMap, callback: unknown ): void {\n\t\tthis._listeners[ eventName ] = this._listeners[ eventName ]\n\t\t\t.filter( cb => cb !== callback );\n\t}\n\n\t/**\n\t * Fires an event with a given event name and arguments.\n\t *\n\t * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.\n\t */\n\tprotected _fire<K extends keyof EventMap>( eventName: K, ...args: EventArgs<K> ): void {\n\t\tconst callbacks = this._listeners[ eventName ] || [];\n\n\t\tfor ( const callback of callbacks ) {\n\t\t\tcallback.apply( this, [ null, ...args ] );\n\t\t}\n\t}\n\n\t/**\n\t * Starts error handling by attaching global error handlers.\n\t */\n\tprotected _startErrorHandling(): void {\n\t\twindow.addEventListener( 'error', this._boundErrorHandler );\n\t\twindow.addEventListener( 'unhandledrejection', this._boundErrorHandler );\n\t}\n\n\t/**\n\t * Stops error handling by detaching global error handlers.\n\t */\n\tprotected _stopErrorHandling(): void {\n\t\twindow.removeEventListener( 'error', this._boundErrorHandler );\n\t\twindow.removeEventListener( 'unhandledrejection', this._boundErrorHandler );\n\t}\n\n\t/**\n\t * Checks if an error comes from the watched item and restarts it.\n\t * It reacts to {@link module:utils/ckeditorerror~CKEditorError `CKEditorError` errors} only.\n\t *\n\t * @fires error\n\t * @param error Error.\n\t * @param evt An error event.\n\t */\n\tprivate _handleError( error: Error, evt: ErrorEvent | PromiseRejectionEvent ): void {\n\t\t// @if CK_DEBUG // const err = error as CKEditorError;\n\t\t// @if CK_DEBUG // if ( err.is && err.is( 'CKEditorError' ) && err.context === undefined ) {\n\t\t// @if CK_DEBUG // console.warn( 'The error is missing its context and Watchdog cannot restart the proper item.' );\n\t\t// @if CK_DEBUG // }\n\n\t\tif ( this._shouldReactToError( error ) ) {\n\t\t\tthis.crashes.push( {\n\t\t\t\tmessage: error.message,\n\t\t\t\tstack: error.stack,\n\n\t\t\t\t// `evt.filename`, `evt.lineno` and `evt.colno` are available only in ErrorEvent events\n\t\t\t\tfilename: evt instanceof ErrorEvent ? evt.filename : undefined,\n\t\t\t\tlineno: evt instanceof ErrorEvent ? evt.lineno : undefined,\n\t\t\t\tcolno: evt instanceof ErrorEvent ? evt.colno : undefined,\n\t\t\t\tdate: this._now()\n\t\t\t} );\n\n\t\t\tconst causesRestart = this._shouldRestart();\n\n\t\t\tthis.state = 'crashed';\n\t\t\tthis._fire( 'stateChange' );\n\t\t\tthis._fire( 'error', { error, causesRestart } );\n\n\t\t\tif ( causesRestart ) {\n\t\t\t\tthis._restart();\n\t\t\t} else {\n\t\t\t\tthis.state = 'crashedPermanently';\n\t\t\t\tthis._fire( 'stateChange' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks whether an error should be handled by the watchdog.\n\t *\n\t * @param error An error that was caught by the error handling process.\n\t */\n\tprivate _shouldReactToError( error: Error ): boolean {\n\t\treturn (\n\t\t\t( error as any ).is &&\n\t\t\t( error as any ).is( 'CKEditorError' ) &&\n\t\t\t( error as CKEditorError ).context !== undefined &&\n\n\t\t\t// In some cases the watched item should not be restarted - e.g. during the item initialization.\n\t\t\t// That's why the `null` was introduced as a correct error context which does cause restarting.\n\t\t\t( error as CKEditorError ).context !== null &&\n\n\t\t\t// Do not react to errors if the watchdog is in states other than `ready`.\n\t\t\tthis.state === 'ready' &&\n\n\t\t\tthis._isErrorComingFromThisItem( error as CKEditorError )\n\t\t);\n\t}\n\n\t/**\n\t * Checks if the watchdog should restart the underlying item.\n\t */\n\tprivate _shouldRestart(): boolean {\n\t\tif ( this.crashes.length <= this._crashNumberLimit ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst lastErrorTime = this.crashes[ this.crashes.length - 1 ].date;\n\t\tconst firstMeaningfulErrorTime = this.crashes[ this.crashes.length - 1 - this._crashNumberLimit ].date;\n\n\t\tconst averageNonErrorTimePeriod = ( lastErrorTime - firstMeaningfulErrorTime ) / this._crashNumberLimit;\n\n\t\treturn averageNonErrorTimePeriod > this._minimumNonErrorTimePeriod;\n\t}\n}\n\n/**\n * Fired when a new {@link module:utils/ckeditorerror~CKEditorError `CKEditorError`} error connected to the watchdog instance occurs\n * and the watchdog will react to it.\n *\n * ```ts\n * watchdog.on( 'error', ( evt, { error, causesRestart } ) => {\n * \tconsole.log( 'An error occurred.' );\n * } );\n * ```\n *\n * @eventName ~Watchdog#error\n */\nexport type WatchdogErrorEvent = {\n\tname: 'error';\n\targs: [ WatchdogErrorEventData ];\n};\n\n/**\n * The `error` event data.\n */\nexport type WatchdogErrorEventData = {\n\terror: Error;\n\tcausesRestart: boolean;\n};\n\n/**\n * Fired when the watchdog state changed.\n *\n * @eventName ~Watchdog#stateChange\n */\nexport type WatchdogStateChangeEvent = {\n\tname: 'stateChange';\n\targs: [];\n};\n\n/**\n * The map of watchdog events.\n */\nexport interface EventMap {\n\tstateChange: WatchdogStateChangeEvent;\n\terror: WatchdogErrorEvent;\n\trestart: EditorWatchdogRestartEvent;\n\titemError: ContextWatchdogItemErrorEvent;\n\titemRestart: ContextWatchdogItemRestartEvent;\n}\n\n/**\n * Utility type that gets the arguments type for the given event.\n */\nexport type EventArgs<K extends keyof EventMap> = EventMap[ K ][ 'args' ];\n\n/**\n * Utility type that gets the callback type for the given event.\n */\nexport type EventCallback<K extends keyof EventMap> = ( evt: null, ...args: EventArgs<K> ) => void;\n\n/**\n * The watchdog plugin configuration.\n */\nexport interface WatchdogConfig {\n\n\t/**\n\t * A threshold specifying the number of watched item crashes\n\t * when the watchdog stops restarting the item in case of errors.\n\t * After this limit is reached and the time between the last errors is shorter than `minimumNonErrorTimePeriod`,\n\t * the watchdog changes its state to `crashedPermanently` and it stops restarting the item. This prevents an infinite restart loop.\n\t *\n\t * @default 3\n\t */\n\tcrashNumberLimit?: number;\n\n\t/**\n\t * An average number of milliseconds between the last watched item errors\n\t * (defaults to 5000). When the period of time between errors is lower than that and the `crashNumberLimit` is also reached,\n\t * the watchdog changes its state to `crashedPermanently` and it stops restarting the item. This prevents an infinite restart loop.\n\t *\n\t * @default 5000\n\t */\n\tminimumNonErrorTimePeriod?: number;\n\n\t/**\n\t * A minimum number of milliseconds between saving the editor data internally (defaults to 5000).\n\t * Note that for large documents this might impact the editor performance.\n\t *\n\t * @default 5000\n\t */\n\tsaveInterval?: number;\n}\n\n/**\n * Specifies the state of the item watched by the watchdog.\n */\nexport type WatchdogState = 'initializing' | 'ready' | 'crashed' | 'crashedPermanently' | 'destroyed';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module watchdog/utils/getsubnodes\n */\n\n/* globals EventTarget, Event */\n\nexport default function getSubNodes( head: unknown, excludedProperties = new Set() ): Set<unknown> {\n\tconst nodes = [ head ];\n\n\t// @if CK_DEBUG_WATCHDOG // const prevNodeMap = new Map();\n\n\t// Nodes are stored to prevent infinite looping.\n\tconst subNodes = new Set();\n\tlet nodeIndex = 0;\n\n\twhile ( nodes.length > nodeIndex ) {\n\t\t// Incrementing the iterator is much faster than changing size of the array with Array.prototype.shift().\n\t\tconst node = nodes[ nodeIndex++ ];\n\n\t\tif ( subNodes.has( node ) || !shouldNodeBeIncluded( node ) || excludedProperties.has( node ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tsubNodes.add( node );\n\n\t\t// Handle arrays, maps, sets, custom collections that implements `[ Symbol.iterator ]()`, etc.\n\t\tif ( Symbol.iterator in node ) {\n\t\t\t// The custom editor iterators might cause some problems if the editor is crashed.\n\t\t\ttry {\n\t\t\t\tfor ( const n of node as Iterable<unknown> ) {\n\t\t\t\t\tnodes.push( n );\n\n\t\t\t\t\t// @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( n ) ) {\n\t\t\t\t\t// @if CK_DEBUG_WATCHDOG // \tprevNodeMap.set( n, node );\n\t\t\t\t\t// @if CK_DEBUG_WATCHDOG // }\n\t\t\t\t}\n\t\t\t} catch ( err ) {\n\t\t\t\t// Do not log errors for broken structures\n\t\t\t\t// since we are in the error handling process already.\n\t\t\t\t// eslint-disable-line no-empty\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( const key in node ) {\n\t\t\t\t// We share a reference via the protobuf library within the editors,\n\t\t\t\t// hence the shared value should be skipped. Although, it's not a perfect\n\t\t\t\t// solution since new places like that might occur in the future.\n\t\t\t\tif ( key === 'defaultValue' ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tnodes.push( node[ key ] );\n\n\t\t\t\t// @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( node[ key ] ) ) {\n\t\t\t\t// @if CK_DEBUG_WATCHDOG // \tprevNodeMap.set( node[ key ], node );\n\t\t\t\t// @if CK_DEBUG_WATCHDOG // }\n\t\t\t}\n\t\t}\n\t}\n\n\t// @if CK_DEBUG_WATCHDOG // return { subNodes, prevNodeMap } as any;\n\n\treturn subNodes;\n}\n\nfunction shouldNodeBeIncluded( node: unknown ): node is Record<string, unknown> | Iterable<unknown> {\n\tconst type = Object.prototype.toString.call( node );\n\tconst typeOfNode = typeof node;\n\n\treturn !(\n\t\ttypeOfNode === 'number' ||\n\t\ttypeOfNode === 'boolean' ||\n\t\ttypeOfNode === 'string' ||\n\t\ttypeOfNode === 'symbol' ||\n\t\ttypeOfNode === 'function' ||\n\t\ttype === '[object Date]' ||\n\t\ttype === '[object RegExp]' ||\n\t\ttype === '[object Module]' ||\n\n\t\tnode === undefined ||\n\t\tnode === null ||\n\n\t\t// This flag is meant to exclude singletons shared across editor instances. So when an error is thrown in one editor,\n\t\t// the other editors connected through the reference to the same singleton are not restarted. This is a temporary workaround\n\t\t// until a better solution is found.\n\t\t// More in https://github.com/ckeditor/ckeditor5/issues/12292.\n\t\t( node as any )._watchdogExcluded ||\n\n\t\t// Skip native DOM objects, e.g. Window, nodes, events, etc.\n\t\tnode instanceof EventTarget ||\n\t\tnode instanceof Event\n\t);\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module watchdog/utils/areconnectedthroughproperties\n */\n\n/* globals console */\n\nimport getSubNodes from './getsubnodes.js';\n\n/**\n * Traverses both structures to find out whether there is a reference that is shared between both structures.\n */\nexport default function areConnectedThroughProperties( target1: unknown, target2: unknown, excludedNodes = new Set() ): boolean {\n\tif ( target1 === target2 && isObject( target1 ) ) {\n\t\treturn true;\n\t}\n\n\t// @if CK_DEBUG_WATCHDOG // return checkConnectionBetweenProps( target1, target2, excludedNodes );\n\n\tconst subNodes1 = getSubNodes( target1, excludedNodes );\n\tconst subNodes2 = getSubNodes( target2, excludedNodes );\n\n\tfor ( const node of subNodes1 ) {\n\t\tif ( subNodes2.has( node ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/* istanbul ignore next -- @preserve */\n// eslint-disable-next-line\nfunction checkConnectionBetweenProps( target1: unknown, target2: unknown, excludedNodes: any ) {\n\tconst { subNodes: subNodes1, prevNodeMap: prevNodeMap1 } = getSubNodes( target1, excludedNodes.subNodes ) as any;\n\tconst { subNodes: subNodes2, prevNodeMap: prevNodeMap2 } = getSubNodes( target2, excludedNodes.subNodes ) as any;\n\n\tfor ( const sharedNode of subNodes1 ) {\n\t\tif ( subNodes2.has( sharedNode ) ) {\n\t\t\tconst connection = [];\n\n\t\t\tconnection.push( sharedNode );\n\n\t\t\tlet node = prevNodeMap1.get( sharedNode );\n\n\t\t\twhile ( node && node !== target1 ) {\n\t\t\t\tconnection.push( node );\n\t\t\t\tnode = prevNodeMap1.get( node );\n\t\t\t}\n\n\t\t\tnode = prevNodeMap2.get( sharedNode );\n\n\t\t\twhile ( node && node !== target2 ) {\n\t\t\t\tconnection.unshift( node );\n\t\t\t\tnode = prevNodeMap2.get( node );\n\t\t\t}\n\n\t\t\tconsole.log( '--------' );\n\t\t\tconsole.log( { target1 } );\n\t\t\tconsole.log( { sharedNode } );\n\t\t\tconsole.log( { target2 } );\n\t\t\tconsole.log( { connection } );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nfunction isObject( structure: unknown ): boolean {\n\treturn typeof structure === 'object' && structure !== null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module watchdog/editorwatchdog\n */\n\n/* globals console */\n\n// eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nimport type { CKEditorError } from 'ckeditor5/src/utils.js';\n\n// eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nimport type { Editor, EditorConfig, Context, EditorReadyEvent } from 'ckeditor5/src/core.js';\n\n// eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nimport type { RootAttributes } from '@ckeditor/ckeditor5-editor-multi-root';\n\nimport areConnectedThroughProperties from './utils/areconnectedthroughproperties.js';\nimport Watchdog, { type WatchdogConfig } from './watchdog.js';\n\nimport { throttle, cloneDeepWith, isElement, type DebouncedFunc } from 'lodash-es';\n\n// eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nimport type { Node, Text, Element, Writer } from 'ckeditor5/src/engine.js';\n\n/**\n * A watchdog for CKEditor 5 editors.\n *\n * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and\n * how to use it.\n */\nexport default class EditorWatchdog<TEditor extends Editor = Editor> extends Watchdog {\n\t/**\n\t * The current editor instance.\n\t */\n\tprivate _editor: TEditor | null = null;\n\n\t/**\n\t * A promise associated with the life cycle of the editor (creation or destruction processes).\n\t *\n\t * It is used to prevent the initialization of the editor if the previous instance has not been destroyed yet,\n\t * and conversely, to prevent the destruction of the editor if it has not been initialized.\n\t */\n\tprivate _lifecyclePromise: Promise<unknown> | null = null;\n\n\t/**\n\t * Throttled save method. The `save()` method is called the specified `saveInterval` after `throttledSave()` is called,\n\t * unless a new action happens in the meantime.\n\t */\n\tprivate _throttledSave: DebouncedFunc<() => void>;\n\n\t/**\n\t * The latest saved editor data represented as a root name -> root data object.\n\t */\n\tprivate _data?: EditorData;\n\n\t/**\n\t * The last document version.\n\t */\n\tprivate _lastDocumentVersion?: number;\n\n\t/**\n\t * The editor source element or data.\n\t */\n\tprivate _elementOrData?: HTMLElement | string | Record<string, string> | Record<string, HTMLElement>;\n\n\t/**\n\t * Specifies whether the editor was initialized using document data (`true`) or HTML elements (`false`).\n\t */\n\tprivate _initUsingData = true;\n\n\t/**\n\t * The latest record of the editor editable elements. Used to restart the editor.\n\t */\n\tprivate _editables: Record<string, HTMLElement> = {};\n\n\t/**\n\t * The editor configuration.\n\t */\n\tprivate _config?: EditorConfig;\n\n\t/**\n\t * The creation method.\n\t *\n\t * @see #setCreator\n\t */\n\tdeclare protected _creator: EditorCreatorFunction<TEditor>;\n\n\t/**\n\t * The destruction method.\n\t *\n\t * @see #setDestructor\n\t */\n\tdeclare protected _destructor: ( editor: Editor ) => Promise<unknown>;\n\n\tprivate _excludedProps?: Set<unknown>;\n\n\t/**\n\t * @param Editor The editor class.\n\t * @param watchdogConfig The watchdog plugin configuration.\n\t */\n\tconstructor( Editor: { create( ...args: any ): Promise<TEditor> } | null, watchdogConfig: WatchdogConfig = {} ) {\n\t\tsuper( watchdogConfig );\n\n\t\t// this._editorClass = Editor;\n\n\t\tthis._throttledSave = throttle(\n\t\t\tthis._save.bind( this ),\n\t\t\ttypeof watchdogConfig.saveInterval === 'number' ? watchdogConfig.saveInterval : 5000\n\t\t);\n\n\t\t// Set default creator and destructor functions:\n\t\tif ( Editor ) {\n\t\t\tthis._creator = ( ( elementOrData, config ) => Editor.create( elementOrData, config ) );\n\t\t}\n\n\t\tthis._destructor = editor => editor.destroy();\n\t}\n\n\t/**\n\t * The current editor instance.\n\t */\n\tpublic get editor(): TEditor | null {\n\t\treturn this._editor;\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tpublic get _item(): TEditor | null {\n\t\treturn this._editor;\n\t}\n\n\t/**\n\t * Sets the function that is responsible for the editor creation.\n\t * It expects a function that should return a promise.\n\t *\n\t * ```ts\n\t * watchdog.setCreator( ( element, config ) => ClassicEditor.create( element, config ) );\n\t * ```\n\t */\n\tpublic setCreator( creator: EditorCreatorFunction<TEditor> ): void {\n\t\tthis._creator = creator;\n\t}\n\n\t/**\n\t * Sets the function that is responsible for the editor destruction.\n\t * Overrides the default destruction function, which destroys only the editor instance.\n\t * It expects a function that should return a promise or `undefined`.\n\t *\n\t * ```ts\n\t * watchdog.setDestructor( editor => {\n\t * \t// Do something before the editor is destroyed.\n\t *\n\t * \treturn editor\n\t * \t\t.destroy()\n\t * \t\t.then( () => {\n\t * \t\t\t// Do something after the editor is destroyed.\n\t * \t\t} );\n\t * } );\n\t * ```\n\t */\n\tpublic setDestructor( destructor: ( editor: Editor ) => Promise<unknown> ): void {\n\t\tthis._destructor = destructor;\n\t}\n\n\t/**\n\t * Restarts the editor instance. This method is called whenever an editor error occurs. It fires the `restart` event and changes\n\t * the state to `initializing`.\n\t *\n\t * @fires restart\n\t */\n\tprotected override _restart(): Promise<unknown> {\n\t\treturn Promise.resolve()\n\t\t\t.then( () => {\n\t\t\t\tthis.state = 'initializing';\n\t\t\t\tthis._fire( 'stateChange' );\n\n\t\t\t\treturn this._destroy();\n\t\t\t} )\n\t\t\t.catch( err => {\n\t\t\t\tconsole.error( 'An error happened during the editor destroying.', err );\n\t\t\t} )\n\t\t\t.then( () => {\n\t\t\t\t// Pre-process some data from the original editor config.\n\t\t\t\t// Our goal here is to make sure that the restarted editor will be reinitialized with correct set of roots.\n\t\t\t\t// We are not interested in any data set in config or in `.create()` first parameter. It will be replaced anyway.\n\t\t\t\t// But we need to set them correctly to make sure that proper roots are created.\n\t\t\t\t//\n\t\t\t\t// Since a different set of roots will be created, `lazyRoots` and `rootsAttributes` properties must be managed too.\n\n\t\t\t\t// Keys are root names, values are ''. Used when the editor was initialized by setting the first parameter to document data.\n\t\t\t\tconst existingRoots: Record<string, string> = {};\n\t\t\t\t// Keeps lazy roots. They may be different when compared to initial config if some of the roots were loaded.\n\t\t\t\tconst lazyRoots: Array<string> = [];\n\t\t\t\t// Roots attributes from the old config. Will be referred when setting new attributes.\n\t\t\t\tconst oldRootsAttributes: Record<string, RootAttributes> = this._config!.rootsAttributes || {};\n\t\t\t\t// New attributes to be set. Is filled only for roots that still exist in the document.\n\t\t\t\tconst rootsAttributes: Record<string, RootAttributes> = {};\n\n\t\t\t\t// Traverse through the roots saved when the editor crashed and set up the discussed values.\n\t\t\t\tfor ( const [ rootName, rootData ] of Object.entries( this._data!.roots ) ) {\n\t\t\t\t\tif ( rootData.isLoaded ) {\n\t\t\t\t\t\texistingRoots[ rootName ] = '';\n\t\t\t\t\t\trootsAttributes[ rootName ] = oldRootsAttributes[ rootName ] || {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlazyRoots.push( rootName );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst updatedConfig: EditorConfig = {\n\t\t\t\t\t...this._config,\n\t\t\t\t\textraPlugins: this._config!.extraPlugins || [],\n\t\t\t\t\tlazyRoots,\n\t\t\t\t\trootsAttributes,\n\t\t\t\t\t_watchdogInitialData: this._data\n\t\t\t\t};\n\n\t\t\t\t// Delete `initialData` as it is not needed. Data will be set by the watchdog based on `_watchdogInitialData`.\n\t\t\t\t// First parameter of the editor `.create()` will be used to set up initial roots.\n\t\t\t\tdelete updatedConfig.initialData;\n\n\t\t\t\tupdatedConfig.extraPlugins!.push( EditorWatchdogInitPlugin as any );\n\n\t\t\t\tif ( this._initUsingData ) {\n\t\t\t\t\treturn this.create( existingRoots, updatedConfig, updatedConfig.context );\n\t\t\t\t} else {\n\t\t\t\t\t// Set correct editables to make sure that proper roots are created and linked with DOM elements.\n\t\t\t\t\t// No need to set initial data, as it would be discarded anyway.\n\t\t\t\t\t//\n\t\t\t\t\t// If one element was initially set in `elementOrData`, then use that original element to restart the editor.\n\t\t\t\t\t// This is for compatibility purposes with single-root editor types.\n\t\t\t\t\tif ( isElement( this._elementOrData ) ) {\n\t\t\t\t\t\treturn this.create( this._elementOrData, updatedConfig, updatedConfig.context );\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn this.create( this._editables, updatedConfig, updatedConfig.context );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.then( () => {\n\t\t\t\tthis._fire( 'restart' );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Creates the editor instance and keeps it running, using the defined creator and destructor.\n\t *\n\t * @param elementOrData The editor source element or the editor data.\n\t * @param config The editor configuration.\n\t * @param context A context for the editor.\n\t */\n\tpublic create(\n\t\telementOrData: HTMLElement | string | Record<string, string> | Record<string, HTMLElement> = this._elementOrData!,\n\t\tconfig: EditorConfig = this._config!,\n\t\tcontext?: Context\n\t): Promise<unknown> {\n\t\tthis._lifecyclePromise = Promise.resolve( this._lifecyclePromise )\n\t\t\t.then( () => {\n\t\t\t\tsuper._startErrorHandling();\n\n\t\t\t\tthis._elementOrData = elementOrData;\n\n\t\t\t\t// Use document data in the first parameter of the editor `.create()` call only if it was used like this originally.\n\t\t\t\t// Use document data if a string or object with strings was passed.\n\t\t\t\tthis._initUsingData = typeof elementOrData == 'string' ||\n\t\t\t\t\t( Object.keys( elementOrData ).length > 0 && typeof Object.values( elementOrData )[ 0 ] == 'string' );\n\n\t\t\t\t// Clone configuration because it might be shared within multiple watchdog instances. Otherwise,\n\t\t\t\t// when an error occurs in one of these editors, the watchdog will restart all of them.\n\t\t\t\tthis._config = this._cloneEditorConfiguration( config ) || {};\n\n\t\t\t\tthis._config!.context = context;\n\n\t\t\t\treturn this._creator( elementOrData, this._config! );\n\t\t\t} )\n\t\t\t.then( editor => {\n\t\t\t\tthis._editor = editor;\n\n\t\t\t\teditor.model.document.on( 'change:data', this._throttledSave );\n\n\t\t\t\tthis._lastDocumentVersion = editor.model.document.version;\n\t\t\t\tthis._data = this._getData();\n\n\t\t\t\tif ( !this._initUsingData ) {\n\t\t\t\t\tthis._editables = this._getEditables();\n\t\t\t\t}\n\n\t\t\t\tthis.state = 'ready';\n\t\t\t\tthis._fire( 'stateChange' );\n\t\t\t} ).finally( () => {\n\t\t\t\tthis._lifecyclePromise = null;\n\t\t\t} );\n\n\t\treturn this._lifecyclePromise;\n\t}\n\n\t/**\n\t * Destroys the watchdog and the current editor instance. It fires the callback\n\t * registered in {@link #setDestructor `setDestructor()`} and uses it to destroy the editor instance.\n\t * It also sets the state to `destroyed`.\n\t */\n\tpublic override destroy(): Promise<unknown> {\n\t\tthis._lifecyclePromise = Promise.resolve( this._lifecyclePromise )\n\t\t\t.then( () => {\n\t\t\t\tthis.state = 'destroyed';\n\t\t\t\tthis._fire( 'stateChange' );\n\n\t\t\t\tsuper.destroy();\n\n\t\t\t\treturn this._destroy();\n\t\t\t} ).finally( () => {\n\t\t\t\tthis._lifecyclePromise = null;\n\t\t\t} );\n\n\t\treturn this._lifecyclePromise;\n\t}\n\n\tprivate _destroy(): Promise<unknown> {\n\t\treturn Promise.resolve()\n\t\t\t.then( () => {\n\t\t\t\tthis._stopErrorHandling();\n\n\t\t\t\tthis._throttledSave.cancel();\n\n\t\t\t\tconst editor = this._editor;\n\n\t\t\t\tthis._editor = null;\n\n\t\t\t\t// Remove the `change:data` listener before destroying the editor.\n\t\t\t\t// Incorrectly written plugins may trigger firing `change:data` events during the editor destruction phase\n\t\t\t\t// causing the watchdog to call `editor.getData()` when some parts of editor are already destroyed.\n\t\t\t\teditor!.model.document.off( 'change:data', this._throttledSave );\n\n\t\t\t\treturn this._destructor( editor! );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Saves the editor data, so it can be restored after the crash even if the data cannot be fetched at\n\t * the moment of the crash.\n\t */\n\tprivate _save(): void {\n\t\tconst version = this._editor!.model.document.version;\n\n\t\ttry {\n\t\t\tthis._data = this._getData();\n\n\t\t\tif ( !this._initUsingData ) {\n\t\t\t\tthis._editables = this._getEditables();\n\t\t\t}\n\n\t\t\tthis._lastDocumentVersion = version;\n\t\t} catch ( err ) {\n\t\t\tconsole.error(\n\t\t\t\terr,\n\t\t\t\t'An error happened during restoring editor data. ' +\n\t\t\t\t'Editor will be restored from the previously saved data.'\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tpublic _setExcludedProperties( props: Set<unknown> ): void {\n\t\tthis._excludedProps = props;\n\t}\n\n\t/**\n\t * Gets all data that is required to reinitialize editor instance.\n\t */\n\tprivate _getData(): EditorData {\n\t\tconst editor = this._editor!;\n\t\tconst roots = editor.model.document.roots.filter( root => root.isAttached() && root.rootName != '$graveyard' );\n\n\t\tconst { plugins } = editor;\n\t\t// `as any` to avoid linking from external private repo.\n\t\tconst commentsRepository = plugins.has( 'CommentsRepository' ) && plugins.get( 'CommentsRepository' ) as any;\n\t\tconst trackChanges = plugins.has( 'TrackChanges' ) && plugins.get( 'TrackChanges' ) as any;\n\n\t\tconst data: EditorData = {\n\t\t\troots: {},\n\t\t\tmarkers: {},\n\t\t\tcommentThreads: JSON.stringify( [] ),\n\t\t\tsuggestions: JSON.stringify( [] )\n\t\t};\n\n\t\troots.forEach( root => {\n\t\t\tdata.roots[ root.rootName ] = {\n\t\t\t\tcontent: JSON.stringify( Array.from( root.getChildren() ) ),\n\t\t\t\tattributes: JSON.stringify( Array.from( root.getAttributes() ) ),\n\t\t\t\tisLoaded: root._isLoaded\n\t\t\t};\n\t\t} );\n\n\t\tfor ( const marker of editor.model.markers ) {\n\t\t\tif ( !marker._affectsData ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tdata.markers[ marker.name ] = {\n\t\t\t\trangeJSON: marker.getRange().toJSON() as any,\n\t\t\t\tusingOperation: marker._managedUsingOperations,\n\t\t\t\taffectsData: marker._affectsData\n\t\t\t};\n\t\t}\n\n\t\tif ( commentsRepository ) {\n\t\t\tdata.commentThreads = JSON.stringify( commentsRepository.getCommentThreads( { toJSON: true, skipNotAttached: true } ) );\n\t\t}\n\n\t\tif ( trackChanges ) {\n\t\t\tdata.suggestions = JSON.stringify( trackChanges.getSuggestions( { toJSON: true, skipNotAttached: true } ) );\n\t\t}\n\n\t\treturn data;\n\t}\n\n\t/**\n\t * For each attached model root, returns its HTML editable element (if available).\n\t */\n\tprivate _getEditables(): Record<string, HTMLElement> {\n\t\tconst editables: Record<string, HTMLElement> = {};\n\n\t\tfor ( const rootName of this.editor!.model.document.getRootNames() ) {\n\t\t\tconst editable = this.editor!.ui.getEditableElement( rootName );\n\n\t\t\tif ( editable ) {\n\t\t\t\teditables[ rootName ] = editable;\n\t\t\t}\n\t\t}\n\n\t\treturn editables;\n\t}\n\n\t/**\n\t * Traverses the error context and the current editor to find out whether these structures are connected\n\t * to each other via properties.\n\t *\n\t * @internal\n\t */\n\tpublic _isErrorComingFromThisItem( error: CKEditorError ): boolean {\n\t\treturn areConnectedThroughProperties( this._editor, error.context, this._excludedProps );\n\t}\n\n\t/**\n\t * Clones the editor configuration.\n\t */\n\tprivate _cloneEditorConfiguration( config: EditorConfig ): EditorConfig {\n\t\treturn cloneDeepWith( config, ( value, key ) => {\n\t\t\t// Leave DOM references.\n\t\t\tif ( isElement( value ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\tif ( key === 'context' ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Internal plugin that is used to stop the default editor initialization and restoring the editor state\n * based on the `editor.config._watchdogInitialData` data.\n */\nclass EditorWatchdogInitPlugin {\n\tpublic editor: Editor;\n\n\tprivate _data: EditorData;\n\n\tconstructor( editor: Editor ) {\n\t\tthis.editor = editor;\n\n\t\tthis._data = editor.config.get( '_watchdogInitialData' )!;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\t// Stops the default editor initialization and use the saved data to restore the editor state.\n\t\t// Some of data could not be initialize as a config properties. It is important to keep the data\n\t\t// in the same form as it was before the restarting.\n\t\tthis.editor.data.on( 'init', evt => {\n\t\t\tevt.stop();\n\n\t\t\tthis.editor.model.enqueueChange( { isUndoable: false }, writer => {\n\t\t\t\tthis._restoreCollaborationData();\n\t\t\t\tthis._restoreEditorData( writer );\n\t\t\t} );\n\n\t\t\tthis.editor.data.fire<EditorReadyEvent>( 'ready' );\n\n\t\t\t// Keep priority `'high' - 1` to be sure that RTC initialization will be first.\n\t\t}, { priority: 1000 - 1 } );\n\t}\n\n\t/**\n\t * Creates a model node (element or text) based on provided JSON.\n\t */\n\tprivate _createNode( writer: Writer, jsonNode: any ): Text | Element {\n\t\tif ( 'name' in jsonNode ) {\n\t\t\t// If child has name property, it is an Element.\n\t\t\tconst element = writer.createElement( jsonNode.name, jsonNode.attributes );\n\n\t\t\tif ( jsonNode.children ) {\n\t\t\t\tfor ( const child of jsonNode.children ) {\n\t\t\t\t\telement._appendChild( this._createNode( writer, child ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn element;\n\t\t} else {\n\t\t\t// Otherwise, it is a Text node.\n\t\t\treturn writer.createText( jsonNode.data, jsonNode.attributes );\n\t\t}\n\t}\n\n\t/**\n\t * Restores the editor by setting the document data, roots attributes and markers.\n\t */\n\tprivate _restoreEditorData( writer: Writer ): void {\n\t\tconst editor = this.editor!;\n\n\t\tObject.entries( this._data!.roots ).forEach( ( [ rootName, { content, attributes } ] ) => {\n\t\t\tconst parsedNodes: Array<Node | Element> = JSON.parse( content );\n\t\t\tconst parsedAttributes: Array<[ string, unknown ]> = JSON.parse( attributes );\n\n\t\t\tconst rootElement = editor.model.document.getRoot( rootName )!;\n\n\t\t\tfor ( const [ key, value ] of parsedAttributes ) {\n\t\t\t\twriter.setAttribute( key, value, rootElement );\n\t\t\t}\n\n\t\t\tfor ( const child of parsedNodes ) {\n\t\t\t\tconst node = this._createNode( writer, child );\n\n\t\t\t\twriter.insert( node, rootElement, 'end' );\n\t\t\t}\n\t\t} );\n\n\t\tObject.entries( this._data!.markers ).forEach( ( [ markerName, markerOptions ] ) => {\n\t\t\tconst { document } = editor.model;\n\t\t\tconst {\n\t\t\t\trangeJSON: { start, end },\n\t\t\t\t...options\n\t\t\t} = markerOptions;\n\n\t\t\tconst root = document.getRoot( start.root )!;\n\t\t\tconst startPosition = writer.createPositionFromPath( root, start.path, start.stickiness );\n\t\t\tconst endPosition = writer.createPositionFromPath( root, end.path, end.stickiness );\n\n\t\t\tconst range = writer.createRange( startPosition, endPosition );\n\n\t\t\twriter.addMarker( markerName, {\n\t\t\t\trange,\n\t\t\t\t...options\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Restores the editor collaboration data - comment threads and suggestions.\n\t */\n\tprivate _restoreCollaborationData() {\n\t\t// `as any` to avoid linking from external private repo.\n\t\tconst parsedCommentThreads: Array<any> = JSON.parse( this._data.commentThreads );\n\t\tconst parsedSuggestions: Array<any> = JSON.parse( this._data.suggestions );\n\n\t\tparsedCommentThreads.forEach( commentThreadData => {\n\t\t\tconst channelId = this.editor.config.get( 'collaboration.channelId' )!;\n\t\t\tconst commentsRepository = this.editor!.plugins.get( 'CommentsRepository' ) as any;\n\n\t\t\tif ( commentsRepository.hasCommentThread( commentThreadData.threadId ) ) {\n\t\t\t\tconst commentThread = commentsRepository.getCommentThread( commentThreadData.threadId )!;\n\n\t\t\t\tcommentThread.remove();\n\t\t\t}\n\n\t\t\tcommentsRepository.addCommentThread( { channelId, ...commentThreadData } );\n\t\t} );\n\n\t\tparsedSuggestions.forEach( suggestionData => {\n\t\t\tconst trackChangesEditing = this.editor!.plugins.get( 'TrackChangesEditing' ) as any;\n\n\t\t\tif ( trackChangesEditing.hasSuggestion( suggestionData.id ) ) {\n\t\t\t\tconst suggestion = trackChangesEditing.getSuggestion( suggestionData.id );\n\n\t\t\t\tsuggestion.attributes = suggestionData.attributes;\n\t\t\t} else {\n\t\t\t\ttrackChangesEditing.addSuggestionData( suggestionData );\n\t\t\t}\n\t\t} );\n\t}\n}\n\nexport type EditorData = {\n\troots: Record<string, {\n\t\tcontent: string;\n\t\tattributes: string;\n\t\tisLoaded: boolean;\n\t}>;\n\tmarkers: Record<string, {\n\t\trangeJSON: { start: any; end: any };\n\t\tusingOperation: boolean;\n\t\taffectsData: boolean;\n\t}>;\n\tcommentThreads: string;\n\tsuggestions: string;\n};\n\n/**\n * Fired after the watchdog restarts the error in case of a crash.\n *\n * @eventName ~EditorWatchdog#restart\n */\nexport type EditorWatchdogRestartEvent = {\n\tname: 'restart';\n\targs: [];\n\treturn: undefined;\n};\n\nexport type EditorCreatorFunction<TEditor = Editor> = (\n\telementOrData: HTMLElement | string | Record<string, string> | Record<string, HTMLElement>,\n\tconfig: EditorConfig\n) => Promise<TEditor>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module watchdog/contextwatchdog\n */\n\n/* globals console */\n\n// eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nimport type {\n\tContext,\n\tEditor,\n\tEditorConfig,\n\tContextConfig\n} from 'ckeditor5/src/core.js';\n\n// eslint-disable-next-line ckeditor5-rules/no-cross-package-imports\nimport type {\n\tArrayOrItem,\n\tCKEditorError\n} from 'ckeditor5/src/utils.js';\n\nimport Watchdog, { type WatchdogConfig, type WatchdogState } from './watchdog.js';\nimport EditorWatchdog, { type EditorCreatorFunction } from './editorwatchdog.js';\nimport areConnectedThroughProperties from './utils/areconnectedthroughproperties.js';\nimport getSubNodes from './utils/getsubnodes.js';\n\nconst mainQueueId = Symbol( 'MainQueueId' );\n\n/**\n * A watchdog for the {@link module:core/context~Context} class.\n *\n * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and\n * how to use it.\n */\nexport default class ContextWatchdog<TContext extends Context = Context> extends Watchdog {\n\t/**\n\t * A map of internal watchdogs for added items.\n\t */\n\tprotected _watchdogs = new Map<string, EditorWatchdog>();\n\n\t/**\n\t * The watchdog configuration.\n\t */\n\tprivate readonly _watchdogConfig: WatchdogConfig;\n\n\t/**\n\t * The current context instance.\n\t */\n\tprivate _context: TContext | null = null;\n\n\t/**\n\t * Context properties (nodes/references) that are gathered during the initial context creation\n\t * and are used to distinguish the origin of an error.\n\t */\n\tprivate _contextProps = new Set<unknown>();\n\n\t/**\n\t * An action queue, which is used to handle async functions queuing.\n\t */\n\tprivate _actionQueues = new ActionQueues();\n\n\t/**\n\t * The configuration for the {@link module:core/context~Context}.\n\t */\n\tprivate _contextConfig?: ContextConfig;\n\n\t/**\n\t * The creation method.\n\t *\n\t * @see #setCreator\n\t */\n\tdeclare protected _creator: ( config: ContextConfig ) => Promise<TContext>;\n\n\t/**\n\t * The destruction method.\n\t *\n\t * @see #setDestructor\n\t */\n\tdeclare protected _destructor: ( context: Context ) => Promise<unknown>;\n\n\t/**\n\t * The watched item.\n\t */\n\tpublic _item: unknown;\n\n\t/**\n\t * The context watchdog class constructor.\n\t *\n\t * ```ts\n\t * const watchdog = new ContextWatchdog( Context );\n\t *\n\t * await watchdog.create( contextConfiguration );\n\t *\n\t * await watchdog.add( item );\n\t * ```\n\t *\n\t * See the {@glink features/watchdog Watchdog feature guide} to learn more how to use this feature.\n\t *\n\t * @param Context The {@link module:core/context~Context} class.\n\t * @param watchdogConfig The watchdog configuration.\n\t */\n\tconstructor(\n\t\tContext: { create( ...args: any ): Promise<TContext> },\n\t\twatchdogConfig: WatchdogConfig = {}\n\t) {\n\t\tsuper( watchdogConfig );\n\n\t\tthis._watchdogConfig = watchdogConfig;\n\n\t\t// Default creator and destructor.\n\t\tthis._creator = contextConfig => Context.create( contextConfig );\n\t\tthis._destructor = context => context.destroy();\n\n\t\tthis._actionQueues.onEmpty( () => {\n\t\t\tif ( this.state === 'initializing' ) {\n\t\t\t\tthis.state = 'ready';\n\t\t\t\tthis._fire( 'stateChange' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Sets the function that is responsible for the context creation.\n\t * It expects a function that should return a promise (or `undefined`).\n\t *\n\t * ```ts\n\t * watchdog.setCreator( config => Context.create( config ) );\n\t * ```\n\t */\n\tpublic setCreator( creator: ( config: ContextConfig ) => Promise<TContext> ): void {\n\t\tthis._creator = creator;\n\t}\n\n\t/**\n\t * Sets the function that is responsible for the context destruction.\n\t * Overrides the default destruction function, which destroys only the context instance.\n\t * It expects a function that should return a promise (or `undefined`).\n\t *\n\t * ```ts\n\t * watchdog.setDestructor( context => {\n\t * \t// Do something before the context is destroyed.\n\t *\n\t * \treturn context\n\t * \t\t.destroy()\n\t * \t\t.then( () => {\n\t * \t\t\t// Do something after the context is destroyed.\n\t * \t\t} );\n\t * } );\n\t * ```\n\t */\n\tpublic setDestructor( destructor: ( context: Context ) => Promise<unknown> ): void {\n\t\tthis._destructor = destructor;\n\t}\n\n\t/**\n\t * The context instance. Keep in mind that this property might be changed when the context watchdog restarts,\n\t * so do not keep this instance internally. Always operate on the `ContextWatchdog#context` property.\n\t */\n\tpublic get context(): Context | null {\n\t\treturn this._context;\n\t}\n\n\t/**\n\t * Initializes the context watchdog. Once it is created, the watchdog takes care about\n\t * recreating the context and the provided items, and starts the error handling mechanism.\n\t *\n\t * ```ts\n\t * await watchdog.create( {\n\t * \tplugins: []\n\t * } );\n\t * ```\n\t *\n\t * @param contextConfig The context configuration. See {@link module:core/context~Context}.\n\t */\n\tpublic create( contextConfig: ContextConfig = {} ): Promise<unknown> {\n\t\treturn this._actionQueues.enqueue( mainQueueId, () => {\n\t\t\tthis._contextConfig = contextConfig;\n\n\t\t\treturn this._create();\n\t\t} );\n\t}\n\n\t/**\n\t * Returns an item instance with the given `itemId`.\n\t *\n\t * ```ts\n\t * const editor1 = watchdog.getItem( 'editor1' );\n\t * ```\n\t *\n\t * @param itemId The item ID.\n\t * @returns The item instance or `undefined` if an item with a given ID has not been found.\n\t */\n\tpublic getItem( itemId: string ): unknown {\n\t\tconst watchdog = this._getWatchdog( itemId );\n\n\t\treturn watchdog._item;\n\t}\n\n\t/**\n\t * Gets the state of the given item. See {@link #state} for a list of available states.\n\t *\n\t * ```ts\n\t * const editor1State = watchdog.getItemState( 'editor1' );\n\t * ```\n\t *\n\t * @param itemId Item ID.\n\t * @returns The state of the item.\n\t */\n\tpublic getItemState( itemId: string ): WatchdogState {\n\t\tconst watchdog = this._getWatchdog( itemId );\n\n\t\treturn watchdog.state;\n\t}\n\n\t/**\n\t * Adds items to the watchdog. Once created, instances of these items will be available using the {@link #getItem} method.\n\t *\n\t * Items can be passed together as an array of objects:\n\t *\n\t * ```ts\n\t * await watchdog.add( [ {\n\t * \tid: 'editor1',\n\t * \ttype: 'editor',\n\t * \tsourceElementOrData: document.querySelector( '#editor' ),\n\t * \tconfig: {\n\t * \t\tplugins: [ Essentials, Paragraph, Bold, Italic ],\n\t * \t\ttoolbar: [ 'bold', 'italic', 'alignment' ]\n\t * \t},\n\t * \tcreator: ( element, config ) => ClassicEditor.create( element, config )\n\t * } ] );\n\t * ```\n\t *\n\t * Or one by one as objects:\n\t *\n\t * ```ts\n\t * await watchdog.add( {\n\t * \tid: 'editor1',\n\t * \ttype: 'editor',\n\t * \tsourceElementOrData: document.querySelector( '#editor' ),\n\t * \tconfig: {\n\t * \t\tplugins: [ Essentials, Paragraph, Bold, Italic ],\n\t * \t\ttoolbar: [ 'bold', 'italic', 'alignment' ]\n\t * \t},\n\t * \tcreator: ( element, config ) => ClassicEditor.create( element, config )\n\t * ] );\n\t * ```\n\t *\n\t * Then an instance can be retrieved using the {@link #getItem} method:\n\t *\n\t * ```ts\n\t * const editor1 = watchdog.getItem( 'editor1' );\n\t * ```\n\t *\n\t * Note that this method can be called multiple times, but for performance reasons it is better\n\t * to pass all items together.\n\t *\n\t * @param itemConfigurationOrItemConfigurations An item configuration object or an array of item configurations.\n\t */\n\tpublic add( itemConfigurationOrItemConfigurations: ArrayOrItem<WatchdogItemConfiguration> ): Promise<unknown> {\n\t\tconst itemConfigurations = toArray( itemConfigurationOrItemConfigurations );\n\n\t\treturn Promise.all( itemConfigurations.map( item => {\n\t\t\treturn this._actionQueues.enqueue( item.id, () => {\n\t\t\t\tif ( this.state === 'destroyed' ) {\n\t\t\t\t\tthrow new Error( 'Cannot add items to destroyed watchdog.' );\n\t\t\t\t}\n\n\t\t\t\tif ( !this._context ) {\n\t\t\t\t\tthrow new Error( 'Context was not created yet. You should call the `ContextWatchdog#create()` method first.' );\n\t\t\t\t}\n\n\t\t\t\tlet watchdog: EditorWatchdog;\n\n\t\t\t\tif ( this._watchdogs.has( item.id ) ) {\n\t\t\t\t\tthrow new Error( `Item with the given id is already added: '${ item.id }'.` );\n\t\t\t\t}\n\n\t\t\t\tif ( item.type === 'editor' ) {\n\t\t\t\t\twatchdog = new EditorWatchdog( null, this._watchdogConfig );\n\t\t\t\t\twatchdog.setCreator( item.creator );\n\t\t\t\t\twatchdog._setExcludedProperties( this._contextProps );\n\n\t\t\t\t\tif ( item.destructor ) {\n\t\t\t\t\t\twatchdog.setDestructor( item.destructor );\n\t\t\t\t\t}\n\n\t\t\t\t\tthis._watchdogs.set( item.id, watchdog );\n\n\t\t\t\t\t// Enqueue the internal watchdog errors within the main queue.\n\t\t\t\t\t// And propagate the internal `error` events as `itemError` event.\n\t\t\t\t\twatchdog.on( 'error', ( evt, { error, causesRestart } ) => {\n\t\t\t\t\t\tthis._fire( 'itemError', { itemId: item.id, error } );\n\n\t\t\t\t\t\t// Do not enqueue the item restart action if the item will not restart.\n\t\t\t\t\t\tif ( !causesRestart ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis._actionQueues.enqueue( item.id, () => new Promise<void>( res => {\n\t\t\t\t\t\t\tconst rethrowRestartEventOnce = () => {\n\t\t\t\t\t\t\t\twatchdog.off( 'restart', rethrowRestartEventOnce );\n\n\t\t\t\t\t\t\t\tthis._fire( 'itemRestart', { itemId: item.id } );\n\n\t\t\t\t\t\t\t\tres();\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\twatchdog.on( 'restart', rethrowRestartEventOnce );\n\t\t\t\t\t\t} ) );\n\t\t\t\t\t} );\n\n\t\t\t\t\treturn watchdog.create( item.sourceElementOrData, item.config, this._context );\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error( `Not supported item type: '${ item.type }'.` );\n\t\t\t\t}\n\t\t\t} );\n\t\t} ) );\n\t}\n\n\t/**\n\t * Removes and destroys item(s) with given ID(s).\n\t *\n\t * ```ts\n\t * await watchdog.remove( 'editor1' );\n\t * ```\n\t *\n\t * Or\n\t *\n\t * ```ts\n\t * await watchdog.remove( [ 'editor1', 'editor2' ] );\n\t * ```\n\t *\n\t * @param itemIdOrItemIds Item ID or an array of item IDs.\n\t */\n\tpublic remove( itemIdOrItemIds: ArrayOrItem<string> ): Promise<unknown> {\n\t\tconst itemIds = toArray( itemIdOrItemIds );\n\n\t\treturn Promise.all( itemIds.map( itemId => {\n\t\t\treturn this._actionQueues.enqueue( itemId, () => {\n\t\t\t\tconst watchdog = this._getWatchdog( itemId );\n\n\t\t\t\tthis._watchdogs.delete( itemId );\n\n\t\t\t\treturn watchdog.destroy();\n\t\t\t} );\n\t\t} ) );\n\t}\n\n\t/**\n\t * Destroys the context watchdog and all added items.\n\t * Once the context watchdog is destroyed, new items cannot be added.\n\t *\n\t * ```ts\n\t * await watchdog.destroy();\n\t * ```\n\t */\n\tpublic override destroy(): Promise<unknown> {\n\t\treturn this._actionQueues.enqueue( mainQueueId, () => {\n\t\t\tthis.state = 'destroyed';\n\t\t\tthis._fire( 'stateChange' );\n\n\t\t\tsuper.destroy();\n\n\t\t\treturn this._destroy();\n\t\t} );\n\t}\n\n\t/**\n\t * Restarts the context watchdog.\n\t */\n\tprotected _restart(): Promise<unknown> {\n\t\treturn this._actionQueues.enqueue( mainQueueId, () => {\n\t\t\tthis.state = 'initializing';\n\t\t\tthis._fire( 'stateChange' );\n\n\t\t\treturn this._destroy()\n\t\t\t\t.catch( err => {\n\t\t\t\t\tconsole.error( 'An error happened during destroying the context or items.', err );\n\t\t\t\t} )\n\t\t\t\t.then( () => this._create() )\n\t\t\t\t.then( () => this._fire( 'restart' ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Initializes the context watchdog.\n\t */\n\tprivate _create(): Promise<unknown> {\n\t\treturn Promise.resolve()\n\t\t\t.then( () => {\n\t\t\t\tthis._startErrorHandling();\n\n\t\t\t\treturn this._creator( this._contextConfig! );\n\t\t\t} )\n\t\t\t.then( context => {\n\t\t\t\tthis._context = context;\n\t\t\t\tthis._contextProps = getSubNodes( this._context );\n\n\t\t\t\treturn Promise.all(\n\t\t\t\t\tArray.from( this._watchdogs.values() )\n\t\t\t\t\t\t.map( watchdog => {\n\t\t\t\t\t\t\twatchdog._setExcludedProperties( this._contextProps );\n\n\t\t\t\t\t\t\treturn watchdog.create( undefined, undefined, this._context! );\n\t\t\t\t\t\t} )\n\t\t\t\t);\n\t\t\t} );\n\t}\n\n\t/**\n\t * Destroys the context instance and all added items.\n\t */\n\tprivate _destroy(): Promise<unknown> {\n\t\treturn Promise.resolve()\n\t\t\t.then( () => {\n\t\t\t\tthis._stopErrorHandling();\n\n\t\t\t\tconst context = this._context!;\n\n\t\t\t\tthis._context = null;\n\t\t\t\tthis._contextProps = new Set();\n\n\t\t\t\treturn Promise.all(\n\t\t\t\t\tArray.from( this._watchdogs.values() )\n\t\t\t\t\t\t.map( watchdog => watchdog.destroy() )\n\t\t\t\t)\n\t\t\t\t\t// Context destructor destroys each editor.\n\t\t\t\t\t.then( () => this._destructor( context ) );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Returns the watchdog for a given item ID.\n\t *\n\t * @param itemId Item ID.\n\t */\n\tprotected _getWatchdog( itemId: string ): Watchdog {\n\t\tconst watchdog = this._watchdogs.get( itemId );\n\n\t\tif ( !watchdog ) {\n\t\t\tthrow new Error( `Item with the given id was not registered: ${ itemId }.` );\n\t\t}\n\n\t\treturn watchdog;\n\t}\n\n\t/**\n\t * Checks whether an error comes from the context instance and not from the item instances.\n\t *\n\t * @internal\n\t */\n\tpublic _isErrorComingFromThisItem( error: CKEditorError ): boolean {\n\t\tfor ( const watchdog of this._watchdogs.values() ) {\n\t\t\tif ( watchdog._isErrorComingFromThisItem( error ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn areConnectedThroughProperties( this._context, error.context );\n\t}\n}\n\n/**\n * Fired after the watchdog restarts the context and the added items because of a crash.\n *\n * ```ts\n * watchdog.on( 'restart', () => {\n * \tconsole.log( 'The context has been restarted.' );\n * } );\n * ```\n *\n * @eventName ~ContextWatchdog#restart\n */\nexport type ContextWatchdogRestartEvent = {\n\tname: 'restart';\n\targs: [];\n\treturn: undefined;\n};\n\n/**\n * Fired when a new error occurred in one of the added items.\n *\n * ```ts\n * watchdog.on( 'itemError', ( evt, { error, itemId } ) => {\n * \tconsole.log( `An error occurred in an item with the '${ itemId }' ID.` );\n * } );\n * ```\n *\n * @eventName ~ContextWatchdog#itemError\n */\nexport type ContextWatchdogItemErrorEvent = {\n\tname: 'itemError';\n\targs: [ ContextWatchdogItemErrorEventData ];\n\treturn: undefined;\n};\n\n/**\n * The `itemError` event data.\n */\nexport type ContextWatchdogItemErrorEventData = {\n\titemId: string;\n\terror: Error;\n};\n\n/**\n * Fired after an item has been restarted.\n *\n * ```ts\n * \twatchdog.on( 'itemRestart', ( evt, { itemId } ) => {\n *\t\tconsole.log( 'An item with with the '${ itemId }' ID has been restarted.' );\n * \t} );\n * ```\n *\n * @eventName ~ContextWatchdog#itemRestart\n */\nexport type ContextWatchdogItemRestartEvent = {\n\tname: 'itemRestart';\n\targs: [ ContextWatchdogItemRestartEventData ];\n\treturn: undefined;\n};\n\n/**\n * The `itemRestart` event data.\n */\nexport type ContextWatchdogItemRestartEventData = {\n\titemId: string;\n};\n\n/**\n * Manager of action queues that allows queuing async functions.\n */\nclass ActionQueues {\n\tpublic _onEmptyCallbacks: Array<() => void> = [];\n\tpublic _queues = new Map<symbol | string | number, Promise<unknown>>();\n\tpublic _activeActions = 0;\n\n\t/**\n\t * Used to register callbacks that will be run when the queue becomes empty.\n\t *\n\t * @param onEmptyCallback A callback that will be run whenever the queue becomes empty.\n\t */\n\tpublic onEmpty( onEmptyCallback: () => void ): void {\n\t\tthis._onEmptyCallbacks.push( onEmptyCallback );\n\t}\n\n\t/**\n\t * It adds asynchronous actions (functions) to the proper queue and runs them one by one.\n\t *\n\t * @param queueId The action queue ID.\n\t * @param action A function that should be enqueued.\n\t */\n\tpublic enqueue( queueId: symbol | string | number, action: () => unknown ): Promise<unknown> {\n\t\tconst isMainAction = queueId === mainQueueId;\n\n\t\tthis._activeActions++;\n\n\t\tif ( !this._queues.get( queueId ) ) {\n\t\t\tthis._queues.set( queueId, Promise.resolve() );\n\t\t}\n\n\t\t// List all sources of actions that the current action needs to await for.\n\t\t// For the main action wait for all other actions.\n\t\t// For the item action wait only for the item queue and the main queue.\n\t\tconst awaitedActions = isMainAction ?\n\t\t\tPromise.all( this._queues.values() ) :\n\t\t\tPromise.all( [ this._queues.get( mainQueueId ), this._queues.get( queueId ) ] );\n\n\t\tconst queueWithAction = awaitedActions.then( action );\n\n\t\t// Catch all errors in the main queue to stack promises even if an error occurred in the past.\n\t\tconst nonErrorQueue = queueWithAction.catch( () => {} );\n\n\t\tthis._queues.set( queueId, nonErrorQueue );\n\n\t\treturn queueWithAction.finally( () => {\n\t\t\tthis._activeActions--;\n\n\t\t\tif ( this._queues.get( queueId ) === nonErrorQueue && this._activeActions === 0 ) {\n\t\t\t\tthis._onEmptyCallbacks.forEach( cb => cb() );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Transforms any value to an array. If the provided value is already an array, it is returned unchanged.\n *\n * @param elementOrArray The value to transform to an array.\n * @returns An array created from data.\n */\nfunction toArray<T>( elementOrArray: ArrayOrItem<T> ): Array<T> {\n\treturn Array.isArray( elementOrArray ) ? elementOrArray : [ elementOrArray ];\n}\n\n/**\n * The watchdog item configuration interface.\n */\nexport interface WatchdogItemConfiguration {\n\n\t/**\n\t * id A unique item identificator.\n\t */\n\tid: string;\n\n\t/**\n\t * The type of the item to create. At the moment, only `'editor'` is supported.\n\t */\n\ttype: 'editor';\n\n\t/**\n\t * A function that initializes the item (the editor). The function takes editor initialization arguments\n\t * and should return a promise. For example: `( el, config ) => ClassicEditor.create( el, config )`.\n\t */\n\tcreator: EditorCreatorFunction;\n\n\t/**\n\t * A function that destroys the item instance (the editor). The function\n\t * takes an item and should return a promise. For example: `editor => editor.destroy()`\n\t */\n\tdestructor?: ( editor: Editor ) => Promise<unknown>;\n\n\t/**\n\t * The source element or data that will be passed\n\t * as the first argument to the `Editor.create()` method.\n\t */\n\tsourceElementOrData: string | HTMLElement;\n\n\t/**\n\t * An editor configuration.\n \t */\n\tconfig: EditorConfig;\n}\n", "import { ObservableMixin, insertToPriorityArray, EmitterMixin, CKEditorError, Config, Locale, Collection, KeystrokeHandler, setDataInElement } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { Model, StylesProcessor, DataController, EditingController, Conversion } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { EditorWatchdog, ContextWatchdog } from '@ckeditor/ckeditor5-watchdog/dist/index.js';\nimport { isFunction } from 'lodash-es';\n\n/**\n * The base class for CKEditor plugin classes.\n */ class Plugin extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * The editor instance.\n\t *\n\t * Note that most editors implement the {@link module:core/editor/editor~Editor#ui} property.\n\t * However, editors with an external UI (i.e. Bootstrap-based) or a headless editor may not have this property or\n\t * throw an error when accessing it.\n\t *\n\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t *  - The \"editing\" part that uses the {@link module:core/editor/editor~Editor} class without `ui` property.\n\t *  - The \"UI\" part that uses the {@link module:core/editor/editor~Editor} class and accesses `ui` property.\n\t */ editor;\n    /**\n\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t */ _disableStack = new Set();\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super();\n        this.editor = editor;\n        this.set('isEnabled', true);\n    }\n    /**\n\t * Disables the plugin.\n\t *\n\t * Plugin may be disabled by multiple features or algorithms (at once). When disabling a plugin, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the plugin.\n\t * The plugin becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a plugin:\n\t *\n\t * ```ts\n\t * plugin.isEnabled; // -> true\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> false\n\t * plugin.clearForceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> true\n\t * ```\n\t *\n\t * Plugin disabled by multiple features:\n\t *\n\t * ```ts\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.forceDisabled( 'OtherFeature' );\n\t * plugin.clearForceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> false\n\t * plugin.clearForceDisabled( 'OtherFeature' );\n\t * plugin.isEnabled; // -> true\n\t * ```\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t * ```ts\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.clearForceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> true\n\t * ```\n\t *\n\t * **Note:** some plugins or algorithms may have more complex logic when it comes to enabling or disabling certain plugins,\n\t * so the plugin might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the plugin.\n\t */ forceDisabled(id) {\n        this._disableStack.add(id);\n        if (this._disableStack.size == 1) {\n            this.on('set:isEnabled', forceDisable$1, {\n                priority: 'highest'\n            });\n            this.isEnabled = false;\n        }\n    }\n    /**\n\t * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}.\n\t *\n\t * @param id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */ clearForceDisabled(id) {\n        this._disableStack.delete(id);\n        if (this._disableStack.size == 0) {\n            this.off('set:isEnabled', forceDisable$1);\n            this.isEnabled = true;\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this.stopListening();\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isContextPlugin() {\n        return false;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return false;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isPremiumPlugin() {\n        return false;\n    }\n}\n/**\n * Helper function that forces plugin to be disabled.\n */ function forceDisable$1(evt) {\n    evt.return = false;\n    evt.stop();\n}\n\n/**\n * Base class for the CKEditor commands.\n *\n * Commands are the main way to manipulate the editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of the code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default, commands are disabled when the editor is in the {@link module:core/editor/editor~Editor#isReadOnly read-only} mode\n * but commands with the {@link module:core/command~Command#affectsData `affectsData`} flag set to `false` will not be disabled.\n */ class Command extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * The editor on which this command will be used.\n\t */ editor;\n    /**\n\t * A flag indicating whether a command's `isEnabled` state should be changed depending on where the document\n\t * selection is placed.\n\t *\n\t * By default, it is set to `true`. If the document selection is placed in a\n\t * {@link module:engine/model/model~Model#canEditAt non-editable} place (such as non-editable root), the command becomes disabled.\n\t *\n\t * The flag should be changed to `false` in a concrete command's constructor if the command should not change its `isEnabled`\n\t * accordingly to the document selection.\n\t */ _isEnabledBasedOnSelection;\n    /**\n\t * A flag indicating whether a command execution changes the editor data or not.\n\t *\n\t * @see #affectsData\n\t */ _affectsData;\n    /**\n\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t */ _disableStack;\n    /**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t */ constructor(editor){\n        super();\n        this.editor = editor;\n        this.set('value', undefined);\n        this.set('isEnabled', false);\n        this._affectsData = true;\n        this._isEnabledBasedOnSelection = true;\n        this._disableStack = new Set();\n        this.decorate('execute');\n        // By default, every command is refreshed when changes are applied to the model.\n        this.listenTo(this.editor.model.document, 'change', ()=>{\n            this.refresh();\n        });\n        this.listenTo(editor, 'change:isReadOnly', ()=>{\n            this.refresh();\n        });\n        // By default, commands are disabled if the selection is in non-editable place or editor is in read-only mode.\n        this.on('set:isEnabled', (evt)=>{\n            if (!this.affectsData) {\n                return;\n            }\n            const selection = editor.model.document.selection;\n            const selectionInGraveyard = selection.getFirstPosition().root.rootName == '$graveyard';\n            const canEditAtSelection = !selectionInGraveyard && editor.model.canEditAt(selection);\n            // Disable if editor is read only, or when selection is in a place which cannot be edited.\n            //\n            // Checking `editor.isReadOnly` is needed for all commands that have `_isEnabledBasedOnSelection == false`.\n            // E.g. undo does not base on selection, but affects data and should be disabled when the editor is in read-only mode.\n            if (editor.isReadOnly || this._isEnabledBasedOnSelection && !canEditAtSelection) {\n                evt.return = false;\n                evt.stop();\n            }\n        }, {\n            priority: 'highest'\n        });\n        this.on('execute', (evt)=>{\n            if (!this.isEnabled) {\n                evt.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * A flag indicating whether a command execution changes the editor data or not.\n\t *\n\t * Commands with `affectsData` set to `false` will not be automatically disabled in\n\t * the {@link module:core/editor/editor~Editor#isReadOnly read-only mode} and\n\t * {@glink features/read-only#related-features other editor modes} with restricted user write permissions.\n\t *\n\t * **Note:** You do not have to set it for your every command. It is `true` by default.\n\t *\n\t * @default true\n\t */ get affectsData() {\n        return this._affectsData;\n    }\n    set affectsData(affectsData) {\n        this._affectsData = affectsData;\n    }\n    /**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */ refresh() {\n        this.isEnabled = true;\n    }\n    /**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. the feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t * ```ts\n\t * command.isEnabled; // -> true\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> false\n\t * command.clearForceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> true\n\t * ```\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t * ```ts\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.forceDisabled( 'OtherFeature' );\n\t * command.clearForceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> false\n\t * command.clearForceDisabled( 'OtherFeature' );\n\t * command.isEnabled; // -> true\n\t * ```\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t * ```ts\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.clearForceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> true\n\t * ```\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */ forceDisabled(id) {\n        this._disableStack.add(id);\n        if (this._disableStack.size == 1) {\n            this.on('set:isEnabled', forceDisable, {\n                priority: 'highest'\n            });\n            this.isEnabled = false;\n        }\n    }\n    /**\n\t * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}.\n\t *\n\t * @param id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */ clearForceDisabled(id) {\n        this._disableStack.delete(id);\n        if (this._disableStack.size == 0) {\n            this.off('set:isEnabled', forceDisable);\n            this.refresh();\n        }\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * This method may return a value, which would be forwarded all the way down to the\n\t * {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n\t *\n\t * @fires execute\n\t */ execute(...args) {\n        return undefined;\n    }\n    /**\n\t * Destroys the command.\n\t */ destroy() {\n        this.stopListening();\n    }\n}\n/**\n * Helper function that forces command to be disabled.\n */ function forceDisable(evt) {\n    evt.return = false;\n    evt.stop();\n}\n\n/**\n * A CKEditor command that aggregates other commands.\n *\n * This command is used to proxy multiple commands. The multi-command is enabled when\n * at least one of its registered child commands is enabled.\n * When executing a multi-command, the first enabled command with highest priority will be executed.\n *\n * ```ts\n * const multiCommand = new MultiCommand( editor );\n *\n * const commandFoo = new Command( editor );\n * const commandBar = new Command( editor );\n *\n * // Register a child command.\n * multiCommand.registerChildCommand( commandFoo );\n * // Register a child command with a low priority.\n * multiCommand.registerChildCommand( commandBar, { priority: 'low' } );\n *\n * // Enable one of the commands.\n * commandBar.isEnabled = true;\n *\n * multiCommand.execute(); // Will execute commandBar.\n * ```\n */ class MultiCommand extends Command {\n    /**\n\t * Registered child commands definitions.\n\t */ _childCommandsDefinitions = [];\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n    // Override base command refresh(): the command's state is changed when one of child commands changes states.\n    }\n    /**\n\t * Executes the first enabled command which has the highest priority of all registered child commands.\n\t *\n\t * @returns The value returned by the {@link module:core/command~Command#execute `command.execute()`}.\n\t */ execute(...args) {\n        const command = this._getFirstEnabledCommand();\n        return !!command && command.execute(args);\n    }\n    /**\n\t * Registers a child command.\n\t *\n\t * @param options An object with configuration options.\n\t * @param options.priority Priority of a command to register.\n\t */ registerChildCommand(command, options = {}) {\n        insertToPriorityArray(this._childCommandsDefinitions, {\n            command,\n            priority: options.priority || 'normal'\n        });\n        // Change multi-command enabled state when one of registered commands changes state.\n        command.on('change:isEnabled', ()=>this._checkEnabled());\n        this._checkEnabled();\n    }\n    /**\n\t * Checks if any of child commands is enabled.\n\t */ _checkEnabled() {\n        this.isEnabled = !!this._getFirstEnabledCommand();\n    }\n    /**\n\t * Returns a first enabled command with the highest priority or `undefined` if none of them is enabled.\n\t */ _getFirstEnabledCommand() {\n        const commandDefinition = this._childCommandsDefinitions.find(({ command })=>command.isEnabled);\n        return commandDefinition && commandDefinition.command;\n    }\n}\n\n/**\n * Manages a list of CKEditor plugins, including loading, resolving dependencies and initialization.\n */ class PluginCollection extends /* #__PURE__ */ EmitterMixin() {\n    _context;\n    _plugins = new Map();\n    /**\n\t * A map of plugin constructors that can be retrieved by their names.\n\t */ _availablePlugins;\n    /**\n\t * Map of {@link module:core/contextplugin~ContextPlugin context plugins} which can be retrieved by their constructors or instances.\n\t */ _contextPlugins;\n    /**\n\t * Creates an instance of the plugin collection class.\n\t * Allows loading and initializing plugins and their dependencies.\n\t * Allows providing a list of already loaded plugins. These plugins will not be destroyed along with this collection.\n\t *\n\t * @param availablePlugins Plugins (constructors) which the collection will be able to use\n\t * when {@link module:core/plugincollection~PluginCollection#init} is used with the plugin names (strings, instead of constructors).\n\t * Usually, the editor will pass its built-in plugins to the collection so they can later be\n\t * used in `config.plugins` or `config.removePlugins` by names.\n\t * @param contextPlugins A list of already initialized plugins represented by a `[ PluginConstructor, pluginInstance ]` pair.\n\t */ constructor(context, availablePlugins = [], contextPlugins = []){\n        super();\n        this._context = context;\n        this._availablePlugins = new Map();\n        for (const PluginConstructor of availablePlugins){\n            if (PluginConstructor.pluginName) {\n                this._availablePlugins.set(PluginConstructor.pluginName, PluginConstructor);\n            }\n        }\n        this._contextPlugins = new Map();\n        for (const [PluginConstructor, pluginInstance] of contextPlugins){\n            this._contextPlugins.set(PluginConstructor, pluginInstance);\n            this._contextPlugins.set(pluginInstance, PluginConstructor);\n            // To make it possible to require a plugin by its name.\n            if (PluginConstructor.pluginName) {\n                this._availablePlugins.set(PluginConstructor.pluginName, PluginConstructor);\n            }\n        }\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * Returns `[ PluginConstructor, pluginInstance ]` pairs.\n\t */ *[Symbol.iterator]() {\n        for (const entry of this._plugins){\n            if (typeof entry[0] == 'function') {\n                yield entry;\n            }\n        }\n    }\n    /**\n\t * Gets the plugin instance by its constructor or name.\n\t *\n\t * ```ts\n\t * // Check if 'Clipboard' plugin was loaded.\n\t * if ( editor.plugins.has( 'ClipboardPipeline' ) ) {\n\t * \t// Get clipboard plugin instance\n\t * \tconst clipboard = editor.plugins.get( 'ClipboardPipeline' );\n\t *\n\t * \tthis.listenTo( clipboard, 'inputTransformation', ( evt, data ) => {\n\t * \t\t// Do something on clipboard input.\n\t * \t} );\n\t * }\n\t * ```\n\t *\n\t * **Note**: This method will throw an error if a plugin is not loaded. Use `{@link #has editor.plugins.has()}`\n\t * to check if a plugin is available.\n\t *\n\t * @param key The plugin constructor or {@link module:core/plugin~PluginStaticMembers#pluginName name}.\n\t */ get(key) {\n        const plugin = this._plugins.get(key);\n        if (!plugin) {\n            let pluginName = key;\n            if (typeof key == 'function') {\n                pluginName = key.pluginName || key.name;\n            }\n            /**\n\t\t\t * The plugin is not loaded and could not be obtained.\n\t\t\t *\n\t\t\t * Plugin classes (constructors) need to be provided to the editor and must be loaded before they can be obtained from\n\t\t\t * the plugin collection.\n\t\t\t *\n\t\t\t * **Note**: You can use `{@link module:core/plugincollection~PluginCollection#has editor.plugins.has()}`\n\t\t\t * to check if a plugin was loaded.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-not-loaded\n\t\t\t * @param plugin The name of the plugin which is not loaded.\n\t\t\t */ throw new CKEditorError('plugincollection-plugin-not-loaded', this._context, {\n                plugin: pluginName\n            });\n        }\n        return plugin;\n    }\n    /**\n\t * Checks if a plugin is loaded.\n\t *\n\t * ```ts\n\t * // Check if the 'Clipboard' plugin was loaded.\n\t * if ( editor.plugins.has( 'ClipboardPipeline' ) ) {\n\t * \t// Now use the clipboard plugin instance:\n\t * \tconst clipboard = editor.plugins.get( 'ClipboardPipeline' );\n\t *\n\t * \t// ...\n\t * }\n\t * ```\n\t *\n\t * @param key The plugin constructor or {@link module:core/plugin~PluginStaticMembers#pluginName name}.\n\t */ has(key) {\n        return this._plugins.has(key);\n    }\n    /**\n\t * Initializes a set of plugins and adds them to the collection.\n\t *\n\t * @param plugins An array of {@link module:core/plugin~PluginInterface plugin constructors}\n\t * or {@link module:core/plugin~PluginStaticMembers#pluginName plugin names}.\n\t * @param pluginsToRemove Names of the plugins or plugin constructors\n\t * that should not be loaded (despite being specified in the `plugins` array).\n\t * @param pluginsSubstitutions An array of {@link module:core/plugin~PluginInterface plugin constructors}\n\t * that will be used to replace plugins of the same names that were passed in `plugins` or that are in their dependency tree.\n\t * A useful option for replacing built-in plugins while creating tests (for mocking their APIs). Plugins that will be replaced\n\t * must follow these rules:\n\t *   * The new plugin must be a class.\n\t *   * The new plugin must be named.\n\t *   * Both plugins must not depend on other plugins.\n\t * @returns A promise which gets resolved once all plugins are loaded and available in the collection.\n\t */ init(plugins, pluginsToRemove = [], pluginsSubstitutions = []) {\n        // Plugin initialization procedure consists of 2 main steps:\n        // 1) collecting all available plugin constructors,\n        // 2) verification whether all required plugins can be instantiated.\n        //\n        // In the first step, all plugin constructors, available in the provided `plugins` array and inside\n        // plugin's dependencies (from the `Plugin.requires` array), are recursively collected and added to the existing\n        // `this._availablePlugins` map, but without any verification at the given moment. Performing the verification\n        // at this point (during the plugin constructor searching) would cause false errors to occur, that some plugin\n        // is missing but in fact it may be defined further in the array as the dependency of other plugin. After\n        // traversing the entire dependency tree, it will be checked if all required \"top level\" plugins are available.\n        //\n        // In the second step, the list of plugins that have not been explicitly removed is traversed to get all the\n        // plugin constructors to be instantiated in the correct order and to validate against some rules. Finally, if\n        // no plugin is missing and no other error has been found, they all will be instantiated.\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\n        const that = this;\n        const context = this._context;\n        findAvailablePluginConstructors(plugins);\n        validatePlugins(plugins);\n        const pluginsToLoad = plugins.filter((plugin)=>!isPluginRemoved(plugin, pluginsToRemove));\n        const pluginConstructors = [\n            ...getPluginConstructors(pluginsToLoad)\n        ];\n        substitutePlugins(pluginConstructors, pluginsSubstitutions);\n        const pluginInstances = loadPlugins(pluginConstructors);\n        return initPlugins(pluginInstances, 'init').then(()=>initPlugins(pluginInstances, 'afterInit')).then(()=>pluginInstances);\n        function isPluginConstructor(plugin) {\n            return typeof plugin === 'function';\n        }\n        function isContextPlugin(plugin) {\n            return isPluginConstructor(plugin) && !!plugin.isContextPlugin;\n        }\n        function isPluginRemoved(plugin, pluginsToRemove) {\n            return pluginsToRemove.some((removedPlugin)=>{\n                if (removedPlugin === plugin) {\n                    return true;\n                }\n                if (getPluginName(plugin) === removedPlugin) {\n                    return true;\n                }\n                if (getPluginName(removedPlugin) === plugin) {\n                    return true;\n                }\n                return false;\n            });\n        }\n        function getPluginName(plugin) {\n            return isPluginConstructor(plugin) ? plugin.pluginName || plugin.name : plugin;\n        }\n        function findAvailablePluginConstructors(plugins, processed = new Set()) {\n            plugins.forEach((plugin)=>{\n                if (!isPluginConstructor(plugin)) {\n                    return;\n                }\n                if (processed.has(plugin)) {\n                    return;\n                }\n                processed.add(plugin);\n                if (plugin.pluginName && !that._availablePlugins.has(plugin.pluginName)) {\n                    that._availablePlugins.set(plugin.pluginName, plugin);\n                }\n                if (plugin.requires) {\n                    findAvailablePluginConstructors(plugin.requires, processed);\n                }\n            });\n        }\n        function getPluginConstructors(plugins, processed = new Set()) {\n            return plugins.map((plugin)=>{\n                return isPluginConstructor(plugin) ? plugin : that._availablePlugins.get(plugin);\n            }).reduce((result, plugin)=>{\n                if (processed.has(plugin)) {\n                    return result;\n                }\n                processed.add(plugin);\n                if (plugin.requires) {\n                    validatePlugins(plugin.requires, plugin);\n                    getPluginConstructors(plugin.requires, processed).forEach((plugin)=>result.add(plugin));\n                }\n                return result.add(plugin);\n            }, new Set());\n        }\n        function validatePlugins(plugins, parentPluginConstructor = null) {\n            plugins.map((plugin)=>{\n                return isPluginConstructor(plugin) ? plugin : that._availablePlugins.get(plugin) || plugin;\n            }).forEach((plugin)=>{\n                checkMissingPlugin(plugin, parentPluginConstructor);\n                checkContextPlugin(plugin, parentPluginConstructor);\n                checkRemovedPlugin(plugin, parentPluginConstructor);\n            });\n        }\n        function checkMissingPlugin(plugin, parentPluginConstructor) {\n            if (isPluginConstructor(plugin)) {\n                return;\n            }\n            if (parentPluginConstructor) {\n                /**\n\t\t\t\t * A required \"soft\" dependency was not found on the plugin list.\n\t\t\t\t *\n\t\t\t\t * When configuring the editor, either prior to building (via\n\t\t\t\t * {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}) or when\n\t\t\t\t * creating a new instance of the editor (e.g. via\n\t\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#plugins `config.plugins`}), you need to provide\n\t\t\t\t * some of the dependencies for other plugins that you used.\n\t\t\t\t *\n\t\t\t\t * This error is thrown when one of these dependencies was not provided. The name of the missing plugin\n\t\t\t\t * can be found in `missingPlugin` and the plugin that required it in `requiredBy`.\n\t\t\t\t *\n\t\t\t\t * In order to resolve it, you need to import the missing plugin and add it to the\n\t\t\t\t * current list of plugins (`Editor.builtinPlugins` or `config.plugins`/`config.extraPlugins`).\n\t\t\t\t *\n\t\t\t\t * Soft requirements were introduced in version 26.0.0. If you happen to stumble upon this error\n\t\t\t\t * when upgrading to version 26.0.0, read also the\n\t\t\t\t * {@glink updating/guides/update-to-26 Migration to 26.0.0} guide.\n\t\t\t\t *\n\t\t\t\t * @error plugincollection-soft-required\n\t\t\t\t * @param missingPlugin The name of the required plugin.\n\t\t\t\t * @param requiredBy The name of the plugin that requires the other plugin.\n\t\t\t\t */ throw new CKEditorError('plugincollection-soft-required', context, {\n                    missingPlugin: plugin,\n                    requiredBy: getPluginName(parentPluginConstructor)\n                });\n            }\n            /**\n\t\t\t * A plugin is not available and could not be loaded.\n\t\t\t *\n\t\t\t * Plugin classes (constructors) need to be provided to the editor before they can be loaded by name.\n\t\t\t * This is usually done in CKEditor 5 builds by setting the {@link module:core/editor/editor~Editor.builtinPlugins}\n\t\t\t * property.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the CKEditor 5 Builds},\n\t\t\t * it means that you try to enable a plugin which was not included in that build. This may be due to a typo\n\t\t\t * in the plugin name or simply because that plugin is not a part of this build.\n\t\t\t *\n\t\t\t * Predefined builds are a deprecated solution and we strongly advise\n\t\t\t * {@glink updating/nim-migration/migration-to-new-installation-methods migrating to new installation methods}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the editor creators directly** (not a build), then it means\n\t\t\t * that you tried loading plugins by name. However, unlike CKEditor 4, CKEditor 5 does not implement a \"plugin loader\".\n\t\t\t * This means that CKEditor 5 does not know where to load the plugin modules from. Therefore, you need to\n\t\t\t * provide each plugin through a reference (as a constructor function). Check out the examples in the\n\t\t\t * {@glink getting-started/installation/quick-start Quick start} guide.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-not-found\n\t\t\t * @param plugin The name of the plugin which could not be loaded.\n\t\t\t */ throw new CKEditorError('plugincollection-plugin-not-found', context, {\n                plugin\n            });\n        }\n        function checkContextPlugin(plugin, parentPluginConstructor) {\n            if (!isContextPlugin(parentPluginConstructor)) {\n                return;\n            }\n            if (isContextPlugin(plugin)) {\n                return;\n            }\n            /**\n\t\t\t * If a plugin is a context plugin, all plugins it requires should also be context plugins\n\t\t\t * instead of plugins. In other words, if one plugin can be used in the context,\n\t\t\t * all its requirements should also be ready to be used in the context. Note that the context\n\t\t\t * provides only a part of the API provided by the editor. If one plugin needs a full\n\t\t\t * editor API, all plugins which require it are considered as plugins that need a full\n\t\t\t * editor API.\n\t\t\t *\n\t\t\t * @error plugincollection-context-required\n\t\t\t * @param plugin The name of the required plugin.\n\t\t\t * @param requiredBy The name of the parent plugin.\n\t\t\t */ throw new CKEditorError('plugincollection-context-required', context, {\n                plugin: getPluginName(plugin),\n                requiredBy: getPluginName(parentPluginConstructor)\n            });\n        }\n        function checkRemovedPlugin(plugin, parentPluginConstructor) {\n            if (!parentPluginConstructor) {\n                return;\n            }\n            if (!isPluginRemoved(plugin, pluginsToRemove)) {\n                return;\n            }\n            /**\n\t\t\t * Cannot load a plugin because one of its dependencies is listed in the `removePlugins` option.\n\t\t\t *\n\t\t\t * @error plugincollection-required\n\t\t\t * @param plugin The name of the required plugin.\n\t\t\t * @param requiredBy The name of the parent plugin.\n\t\t\t */ throw new CKEditorError('plugincollection-required', context, {\n                plugin: getPluginName(plugin),\n                requiredBy: getPluginName(parentPluginConstructor)\n            });\n        }\n        function loadPlugins(pluginConstructors) {\n            return pluginConstructors.map((PluginConstructor)=>{\n                let pluginInstance = that._contextPlugins.get(PluginConstructor);\n                pluginInstance = pluginInstance || new PluginConstructor(context);\n                that._add(PluginConstructor, pluginInstance);\n                return pluginInstance;\n            });\n        }\n        function initPlugins(pluginInstances, method) {\n            return pluginInstances.reduce((promise, plugin)=>{\n                if (!plugin[method]) {\n                    return promise;\n                }\n                if (that._contextPlugins.has(plugin)) {\n                    return promise;\n                }\n                return promise.then(plugin[method].bind(plugin));\n            }, Promise.resolve());\n        }\n        /**\n\t\t * Replaces plugin constructors with the specified set of plugins.\n\t\t */ function substitutePlugins(pluginConstructors, pluginsSubstitutions) {\n            for (const pluginItem of pluginsSubstitutions){\n                if (typeof pluginItem != 'function') {\n                    /**\n\t\t\t\t\t * The plugin replacing an existing plugin must be a function.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-replace-plugin-invalid-type\n\t\t\t\t\t */ throw new CKEditorError('plugincollection-replace-plugin-invalid-type', null, {\n                        pluginItem\n                    });\n                }\n                const pluginName = pluginItem.pluginName;\n                if (!pluginName) {\n                    /**\n\t\t\t\t\t * The plugin replacing an existing plugin must have a name.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-replace-plugin-missing-name\n\t\t\t\t\t */ throw new CKEditorError('plugincollection-replace-plugin-missing-name', null, {\n                        pluginItem\n                    });\n                }\n                if (pluginItem.requires && pluginItem.requires.length) {\n                    /**\n\t\t\t\t\t * The plugin replacing an existing plugin cannot depend on other plugins.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-plugin-for-replacing-cannot-have-dependencies\n\t\t\t\t\t */ throw new CKEditorError('plugincollection-plugin-for-replacing-cannot-have-dependencies', null, {\n                        pluginName\n                    });\n                }\n                const pluginToReplace = that._availablePlugins.get(pluginName);\n                if (!pluginToReplace) {\n                    /**\n\t\t\t\t\t * The replaced plugin does not exist in the\n\t\t\t\t\t * {@link module:core/plugincollection~PluginCollection available plugins} collection.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-plugin-for-replacing-not-exist\n\t\t\t\t\t */ throw new CKEditorError('plugincollection-plugin-for-replacing-not-exist', null, {\n                        pluginName\n                    });\n                }\n                const indexInPluginConstructors = pluginConstructors.indexOf(pluginToReplace);\n                if (indexInPluginConstructors === -1) {\n                    // The Context feature can substitute plugins as well.\n                    // It may happen that the editor will be created with the given context, where the plugin for substitute\n                    // was already replaced. In such a case, we don't want to do it again.\n                    if (that._contextPlugins.has(pluginToReplace)) {\n                        return;\n                    }\n                    /**\n\t\t\t\t\t * The replaced plugin will not be loaded so it cannot be replaced.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-plugin-for-replacing-not-loaded\n\t\t\t\t\t */ throw new CKEditorError('plugincollection-plugin-for-replacing-not-loaded', null, {\n                        pluginName\n                    });\n                }\n                if (pluginToReplace.requires && pluginToReplace.requires.length) {\n                    /**\n\t\t\t\t\t * The replaced plugin cannot depend on other plugins.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-replaced-plugin-cannot-have-dependencies\n\t\t\t\t\t */ throw new CKEditorError('plugincollection-replaced-plugin-cannot-have-dependencies', null, {\n                        pluginName\n                    });\n                }\n                pluginConstructors.splice(indexInPluginConstructors, 1, pluginItem);\n                that._availablePlugins.set(pluginName, pluginItem);\n            }\n        }\n    }\n    /**\n\t * Destroys all loaded plugins.\n\t */ destroy() {\n        const promises = [];\n        for (const [, pluginInstance] of this){\n            if (typeof pluginInstance.destroy == 'function' && !this._contextPlugins.has(pluginInstance)) {\n                promises.push(pluginInstance.destroy());\n            }\n        }\n        return Promise.all(promises);\n    }\n    /**\n\t * Adds the plugin to the collection. Exposed mainly for testing purposes.\n\t *\n\t * @param PluginConstructor The plugin constructor.\n\t * @param plugin The instance of the plugin.\n\t */ _add(PluginConstructor, plugin) {\n        this._plugins.set(PluginConstructor, plugin);\n        const pluginName = PluginConstructor.pluginName;\n        if (!pluginName) {\n            return;\n        }\n        if (this._plugins.has(pluginName)) {\n            /**\n\t\t\t * Two plugins with the same {@link module:core/plugin~PluginStaticMembers#pluginName} were loaded.\n\t\t\t * This will lead to runtime conflicts between these plugins.\n\t\t\t *\n\t\t\t * In practice, this warning usually means that new plugins were added to an existing CKEditor 5 build.\n\t\t\t * Plugins should always be added to a source version of the editor (`@ckeditor/ckeditor5-editor-*`),\n\t\t\t * not to an editor imported from one of the `@ckeditor/ckeditor5-build-*` packages.\n\t\t\t *\n\t\t\t * Check your import paths and the list of plugins passed to\n\t\t\t * {@link module:core/editor/editor~Editor.create `Editor.create()`}\n\t\t\t * or specified in {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}.\n\t\t\t *\n\t\t\t * Predefined builds are a deprecated solution and we strongly advise\n\t\t\t * {@glink updating/nim-migration/migration-to-new-installation-methods migrating to new installation methods}.\n\t\t\t *\n\t\t\t * The second option is that your `node_modules/` directory contains duplicated versions of the same\n\t\t\t * CKEditor 5 packages. Normally, on clean installations, npm deduplicates packages in `node_modules/`, so\n\t\t\t * it may be enough to call `rm -rf node_modules && npm i`. However, if you installed conflicting versions\n\t\t\t * of some packages, their dependencies may need to be installed in more than one version which may lead to this\n\t\t\t * warning.\n\t\t\t *\n\t\t\t * Technically speaking, this error occurs because after adding a plugin to an existing editor build\n\t\t\t * the dependencies of this plugin are being duplicated.\n\t\t\t * They are already built into that editor build and now get added for the second time as dependencies\n\t\t\t * of the plugin you are installing.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-name-conflict\n\t\t\t * @param pluginName The duplicated plugin name.\n\t\t\t * @param plugin1 The first plugin constructor.\n\t\t\t * @param plugin2 The second plugin constructor.\n\t\t\t */ throw new CKEditorError('plugincollection-plugin-name-conflict', null, {\n                pluginName,\n                plugin1: this._plugins.get(pluginName).constructor,\n                plugin2: PluginConstructor\n            });\n        }\n        this._plugins.set(pluginName, plugin);\n    }\n}\n\n/**\n * Provides a common, higher-level environment for solutions that use multiple {@link module:core/editor/editor~Editor editors}\n * or plugins that work outside the editor. Use it instead of {@link module:core/editor/editor~Editor.create `Editor.create()`}\n * in advanced application integrations.\n *\n * All configuration options passed to a context will be used as default options for the editor instances initialized in that context.\n *\n * {@link module:core/contextplugin~ContextPlugin Context plugins} passed to a context instance will be shared among all\n * editor instances initialized in this context. These will be the same plugin instances for all the editors.\n *\n * **Note:** The context can only be initialized with {@link module:core/contextplugin~ContextPlugin context plugins}\n * (e.g. [comments](https://ckeditor.com/collaboration/comments/)). Regular {@link module:core/plugin~Plugin plugins} require an\n * editor instance to work and cannot be added to a context.\n *\n * **Note:** You can add a context plugin to an editor instance, though.\n *\n * If you are using multiple editor instances on one page and use any context plugins, create a context to share the configuration and\n * plugins among these editors. Some plugins will use the information about all existing editors to better integrate between them.\n *\n * If you are using plugins that do not require an editor to work (e.g. [comments](https://ckeditor.com/collaboration/comments/)),\n * enable and configure them using the context.\n *\n * If you are using only a single editor on each page, use {@link module:core/editor/editor~Editor.create `Editor.create()`} instead.\n * In such a case, a context instance will be created by the editor instance in a transparent way.\n *\n * See {@link ~Context.create `Context.create()`} for usage examples.\n */ class Context {\n    /**\n\t * Stores all the configurations specific to this context instance.\n\t */ config;\n    /**\n\t * The plugins loaded and in use by this context instance.\n\t */ plugins;\n    locale;\n    /**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t */ t;\n    /**\n\t * A list of editors that this context instance is injected to.\n\t */ editors;\n    /**\n\t * The default configuration which is built into the `Context` class.\n\t *\n\t * It is used in CKEditor 5 builds featuring `Context` to provide the default configuration options which are later used during the\n\t * context initialization.\n\t *\n\t * ```ts\n\t * Context.defaultConfig = {\n\t * \tfoo: 1,\n\t * \tbar: 2\n\t * };\n\t *\n\t * Context\n\t * \t.create()\n\t * \t.then( context => {\n\t * \t\tcontext.config.get( 'foo' ); // -> 1\n\t * \t\tcontext.config.get( 'bar' ); // -> 2\n\t * \t} );\n\t *\n\t * // The default options can be overridden by the configuration passed to create().\n\t * Context\n\t * \t.create( { bar: 3 } )\n\t * \t.then( context => {\n\t * \t\tcontext.config.get( 'foo' ); // -> 1\n\t * \t\tcontext.config.get( 'bar' ); // -> 3\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/context~Context.builtinPlugins `Context.builtinPlugins`}\n\t * and {@link module:core/editor/editor~Editor.defaultConfig `Editor.defaultConfig`}.\n\t */ static defaultConfig;\n    /**\n\t * An array of plugins built into the `Context` class.\n\t *\n\t * It is used in CKEditor 5 builds featuring `Context` to provide a list of context plugins which are later automatically initialized\n\t * during the context initialization.\n\t *\n\t * They will be automatically initialized by `Context` unless `config.plugins` is passed.\n\t *\n\t * ```ts\n\t * // Build some context plugins into the Context class first.\n\t * Context.builtinPlugins = [ FooPlugin, BarPlugin ];\n\t *\n\t * // Normally, you need to define config.plugins, but since Context.builtinPlugins was\n\t * // defined, now you can call create() without any configuration.\n\t * Context\n\t * \t.create()\n\t * \t.then( context => {\n\t * \t\tcontext.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.\n\t * \t\tcontext.plugins.get( BarPlugin ); // -> An instance of the Bar plugin.\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/context~Context.defaultConfig `Context.defaultConfig`}\n\t * and {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}.\n\t */ static builtinPlugins;\n    /**\n\t * Reference to the editor which created the context.\n\t * Null when the context was created outside of the editor.\n\t *\n\t * It is used to destroy the context when removing the editor that has created the context.\n\t */ _contextOwner = null;\n    /**\n\t * Creates a context instance with a given configuration.\n\t *\n\t * Usually not to be used directly. See the static {@link module:core/context~Context.create `create()`} method.\n\t *\n\t * @param config The context configuration.\n\t */ constructor(config){\n        // We don't pass translations to the config, because its behavior of splitting keys\n        // with dots (e.g. `resize.width` => `resize: { width }`) breaks the translations.\n        const { translations, ...rest } = config || {};\n        this.config = new Config(rest, this.constructor.defaultConfig);\n        const availablePlugins = this.constructor.builtinPlugins;\n        this.config.define('plugins', availablePlugins);\n        this.plugins = new PluginCollection(this, availablePlugins);\n        const languageConfig = this.config.get('language') || {};\n        this.locale = new Locale({\n            uiLanguage: typeof languageConfig === 'string' ? languageConfig : languageConfig.ui,\n            contentLanguage: this.config.get('language.content'),\n            translations\n        });\n        this.t = this.locale.t;\n        this.editors = new Collection();\n    }\n    /**\n\t * Loads and initializes plugins specified in the configuration.\n\t *\n\t * @returns A promise which resolves once the initialization is completed, providing an array of loaded plugins.\n\t */ initPlugins() {\n        const plugins = this.config.get('plugins') || [];\n        const substitutePlugins = this.config.get('substitutePlugins') || [];\n        // Plugins for substitution should be checked as well.\n        for (const Plugin of plugins.concat(substitutePlugins)){\n            if (typeof Plugin != 'function') {\n                /**\n\t\t\t\t * Only a constructor function is allowed as a {@link module:core/contextplugin~ContextPlugin context plugin}.\n\t\t\t\t *\n\t\t\t\t * @error context-initplugins-constructor-only\n\t\t\t\t */ throw new CKEditorError('context-initplugins-constructor-only', null, {\n                    Plugin\n                });\n            }\n            if (Plugin.isContextPlugin !== true) {\n                /**\n\t\t\t\t * Only a plugin marked as a {@link module:core/contextplugin~ContextPlugin.isContextPlugin context plugin}\n\t\t\t\t * is allowed to be used with a context.\n\t\t\t\t *\n\t\t\t\t * @error context-initplugins-invalid-plugin\n\t\t\t\t */ throw new CKEditorError('context-initplugins-invalid-plugin', null, {\n                    Plugin\n                });\n            }\n        }\n        return this.plugins.init(plugins, [], substitutePlugins);\n    }\n    /**\n\t * Destroys the context instance and all editors used with the context,\n\t * releasing all resources used by the context.\n\t *\n\t * @returns A promise that resolves once the context instance is fully destroyed.\n\t */ destroy() {\n        return Promise.all(Array.from(this.editors, (editor)=>editor.destroy())).then(()=>this.plugins.destroy());\n    }\n    /**\n\t * Adds a reference to the editor which is used with this context.\n\t *\n\t * When the given editor has created the context, the reference to this editor will be stored\n\t * as a {@link ~Context#_contextOwner}.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @internal\n\t * @param isContextOwner Stores the given editor as a context owner.\n\t */ _addEditor(editor, isContextOwner) {\n        if (this._contextOwner) {\n            /**\n\t\t\t * Cannot add multiple editors to the context which is created by the editor.\n\t\t\t *\n\t\t\t * @error context-addeditor-private-context\n\t\t\t */ throw new CKEditorError('context-addeditor-private-context');\n        }\n        this.editors.add(editor);\n        if (isContextOwner) {\n            this._contextOwner = editor;\n        }\n    }\n    /**\n\t * Removes a reference to the editor which was used with this context.\n\t * When the context was created by the given editor, the context will be destroyed.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @internal\n\t * @return A promise that resolves once the editor is removed from the context or when the context was destroyed.\n\t */ _removeEditor(editor) {\n        if (this.editors.has(editor)) {\n            this.editors.remove(editor);\n        }\n        if (this._contextOwner === editor) {\n            return this.destroy();\n        }\n        return Promise.resolve();\n    }\n    /**\n\t * Returns the context configuration which will be copied to the editors created using this context.\n\t *\n\t * The configuration returned by this method has the plugins configuration removed &ndash; plugins are shared with all editors\n\t * through another mechanism.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @internal\n\t * @returns Configuration as a plain object.\n\t */ _getEditorConfig() {\n        const result = {};\n        for (const name of this.config.names()){\n            if (![\n                'plugins',\n                'removePlugins',\n                'extraPlugins'\n            ].includes(name)) {\n                result[name] = this.config.get(name);\n            }\n        }\n        return result;\n    }\n    /**\n\t * Creates and initializes a new context instance.\n\t *\n\t * ```ts\n\t * const commonConfig = { ... }; // Configuration for all the plugins and editors.\n\t * const editorPlugins = [ ... ]; // Regular plugins here.\n\t *\n\t * Context\n\t * \t.create( {\n\t * \t\t// Only context plugins here.\n\t * \t\tplugins: [ ... ],\n\t *\n\t * \t\t// Configure the language for all the editors (it cannot be overwritten).\n\t * \t\tlanguage: { ... },\n\t *\n\t * \t\t// Configuration for context plugins.\n\t * \t\tcomments: { ... },\n\t * \t\t...\n\t *\n\t * \t\t// Default configuration for editor plugins.\n\t * \t\ttoolbar: { ... },\n\t * \t\timage: { ... },\n\t * \t\t...\n\t * \t} )\n\t * \t.then( context => {\n\t * \t\tconst promises = [];\n\t *\n\t * \t\tpromises.push( ClassicEditor.create(\n\t * \t\t\tdocument.getElementById( 'editor1' ),\n\t * \t\t\t{\n\t * \t\t\t\teditorPlugins,\n\t * \t\t\t\tcontext\n\t * \t\t\t}\n\t * \t\t) );\n\t *\n\t * \t\tpromises.push( ClassicEditor.create(\n\t * \t\t\tdocument.getElementById( 'editor2' ),\n\t * \t\t\t{\n\t * \t\t\t\teditorPlugins,\n\t * \t\t\t\tcontext,\n\t * \t\t\t\ttoolbar: { ... } // You can overwrite the configuration of the context.\n\t * \t\t\t}\n\t * \t\t) );\n\t *\n\t * \t\treturn Promise.all( promises );\n\t * \t} );\n\t * ```\n\t *\n\t * @param config The context configuration.\n\t * @returns A promise resolved once the context is ready. The promise resolves with the created context instance.\n\t */ static create(config) {\n        return new Promise((resolve)=>{\n            const context = new this(config);\n            resolve(context.initPlugins().then(()=>context));\n        });\n    }\n}\n\n/**\n * The base class for {@link module:core/context~Context} plugin classes.\n *\n * A context plugin can either be initialized for an {@link module:core/editor/editor~Editor editor} or for\n * a {@link module:core/context~Context context}. In other words, it can either\n * work within one editor instance or with one or more editor instances that use a single context.\n * It is the context plugin's role to implement handling for both modes.\n *\n * There are a few rules for interaction between the editor plugins and context plugins:\n *\n * * A context plugin can require another context plugin.\n * * An {@link module:core/plugin~Plugin editor plugin} can require a context plugin.\n * * A context plugin MUST NOT require an {@link module:core/plugin~Plugin editor plugin}.\n */ class ContextPlugin extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * The context or editor instance.\n\t */ context;\n    /**\n\t * Creates a new plugin instance.\n\t */ constructor(context){\n        super();\n        this.context = context;\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this.stopListening();\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isContextPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return false;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isPremiumPlugin() {\n        return false;\n    }\n}\n\n/**\n * Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n */ class CommandCollection {\n    /**\n\t * Command map.\n\t */ _commands;\n    /**\n\t * Creates collection instance.\n\t */ constructor(){\n        this._commands = new Map();\n    }\n    /**\n\t * Registers a new command.\n\t *\n\t * @param commandName The name of the command.\n\t */ add(commandName, command) {\n        this._commands.set(commandName, command);\n    }\n    /**\n\t * Retrieves a command from the collection.\n\t *\n\t * @param commandName The name of the command.\n\t */ get(commandName) {\n        return this._commands.get(commandName);\n    }\n    /**\n\t * Executes a command.\n\t *\n\t * @param commandName The name of the command.\n\t * @param commandParams Command parameters.\n\t * @returns The value returned by the {@link module:core/command~Command#execute `command.execute()`}.\n\t */ execute(commandName, ...commandParams) {\n        const command = this.get(commandName);\n        if (!command) {\n            /**\n\t\t\t * Command does not exist.\n\t\t\t *\n\t\t\t * @error commandcollection-command-not-found\n\t\t\t * @param commandName Name of the command.\n\t\t\t */ throw new CKEditorError('commandcollection-command-not-found', this, {\n                commandName\n            });\n        }\n        return command.execute(...commandParams);\n    }\n    /**\n\t * Returns iterator of command names.\n\t */ *names() {\n        yield* this._commands.keys();\n    }\n    /**\n\t * Returns iterator of command instances.\n\t */ *commands() {\n        yield* this._commands.values();\n    }\n    /**\n\t * Iterable interface.\n\t *\n\t * Returns `[ commandName, commandInstance ]` pairs.\n\t */ [Symbol.iterator]() {\n        return this._commands[Symbol.iterator]();\n    }\n    /**\n\t * Destroys all collection commands.\n\t */ destroy() {\n        for (const command of this.commands()){\n            command.destroy();\n        }\n    }\n}\n\n/**\n * A keystroke handler for editor editing. Its instance is available\n * in {@link module:core/editor/editor~Editor#keystrokes} so plugins\n * can register their keystrokes.\n *\n * E.g. an undo plugin would do this:\n *\n * ```ts\n * editor.keystrokes.set( 'Ctrl+Z', 'undo' );\n * editor.keystrokes.set( 'Ctrl+Shift+Z', 'redo' );\n * editor.keystrokes.set( 'Ctrl+Y', 'redo' );\n * ```\n */ class EditingKeystrokeHandler extends KeystrokeHandler {\n    /**\n\t * The editor instance.\n\t */ editor;\n    /**\n\t * Creates an instance of the keystroke handler.\n\t */ constructor(editor){\n        super();\n        this.editor = editor;\n    }\n    /**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * The handler can be specified as a command name or a callback.\n\t *\n\t * @param keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param callback If a string is passed, then the keystroke will\n\t * {@link module:core/editor/editor~Editor#execute execute a command}.\n\t * If a function, then it will be called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a `cancel()` helper to both `preventDefault()` and `stopPropagation()` of the event.\n\t * @param options Additional options.\n\t * @param options.priority The priority of the keystroke callback. The higher the priority value\n\t * the sooner the callback will be executed. Keystrokes having the same priority\n\t * are called in the order they were added.\n\t */ set(keystroke, callback, options = {}) {\n        if (typeof callback == 'string') {\n            const commandName = callback;\n            callback = (evtData, cancel)=>{\n                this.editor.execute(commandName);\n                cancel();\n            };\n        }\n        super.set(keystroke, callback, options);\n    }\n}\n\nconst DEFAULT_CATEGORY_ID = 'contentEditing';\nconst DEFAULT_GROUP_ID = 'common';\n/**\n * A common namespace for various accessibility features of the editor.\n *\n * **Information about editor keystrokes**\n *\n * * The information about keystrokes available in the editor is stored in the {@link #keystrokeInfos} property.\n * * New info entries can be added using the {@link #addKeystrokeInfoCategory}, {@link #addKeystrokeInfoGroup},\n * and {@link #addKeystrokeInfos} methods.\n */ class Accessibility {\n    /**\n\t * Stores information about keystrokes brought by editor features for the users to interact with the editor, mainly\n\t * keystroke combinations and their accessible labels.\n\t *\n\t * This information is particularly useful for screen reader and other assistive technology users. It gets displayed\n\t * by the {@link module:ui/editorui/accessibilityhelp/accessibilityhelp~AccessibilityHelp Accessibility help} dialog.\n\t *\n\t * Keystrokes are organized in categories and groups. They can be added using ({@link #addKeystrokeInfoCategory},\n\t * {@link #addKeystrokeInfoGroup}, and {@link #addKeystrokeInfos}) methods.\n\t *\n\t * Please note that:\n\t * * two categories are always available:\n\t *   * `'contentEditing'` for keystrokes related to content creation,\n\t *   * `'navigation'` for keystrokes related to navigation in the UI and the content.\n\t * * unless specified otherwise, new keystrokes are added into the `'contentEditing'` category and the `'common'`\n\t * keystroke group within that category while using the {@link #addKeystrokeInfos} method.\n\t */ keystrokeInfos = new Map();\n    /**\n\t * The editor instance.\n\t */ _editor;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        this._editor = editor;\n        const isMenuBarVisible = editor.config.get('menuBar.isVisible');\n        const t = editor.locale.t;\n        this.addKeystrokeInfoCategory({\n            id: DEFAULT_CATEGORY_ID,\n            label: t('Content editing keystrokes'),\n            description: t('These keyboard shortcuts allow for quick access to content editing features.')\n        });\n        const navigationKeystrokes = [\n            {\n                label: t('Close contextual balloons, dropdowns, and dialogs'),\n                keystroke: 'Esc'\n            },\n            {\n                label: t('Open the accessibility help dialog'),\n                keystroke: 'Alt+0'\n            },\n            {\n                label: t('Move focus between form fields (inputs, buttons, etc.)'),\n                keystroke: [\n                    [\n                        'Tab'\n                    ],\n                    [\n                        'Shift+Tab'\n                    ]\n                ]\n            },\n            {\n                label: t('Move focus to the toolbar, navigate between toolbars'),\n                keystroke: 'Alt+F10',\n                mayRequireFn: true\n            },\n            {\n                label: t('Navigate through the toolbar or menu bar'),\n                keystroke: [\n                    [\n                        'arrowup'\n                    ],\n                    [\n                        'arrowright'\n                    ],\n                    [\n                        'arrowdown'\n                    ],\n                    [\n                        'arrowleft'\n                    ]\n                ]\n            },\n            {\n                // eslint-disable-next-line max-len\n                label: t('Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.'),\n                keystroke: [\n                    [\n                        'Enter'\n                    ],\n                    [\n                        'Space'\n                    ]\n                ]\n            }\n        ];\n        if (isMenuBarVisible) {\n            navigationKeystrokes.push({\n                label: t('Move focus to the menu bar, navigate between menu bars'),\n                keystroke: 'Alt+F9',\n                mayRequireFn: true\n            });\n        }\n        this.addKeystrokeInfoCategory({\n            id: 'navigation',\n            label: t('User interface and content navigation keystrokes'),\n            description: t('Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.'),\n            groups: [\n                {\n                    id: 'common',\n                    keystrokes: navigationKeystrokes\n                }\n            ]\n        });\n    }\n    /**\n\t * Adds a top-level category in the {@link #keystrokeInfos keystroke information database} with a label and optional description.\n\t *\n\t * Categories organize keystrokes and help users to find the right keystroke. Each category can have multiple groups\n\t * of keystrokes that narrow down the context in which the keystrokes are available. Every keystroke category comes\n\t * with a `'common'` group by default.\n\t *\n\t * By default, two categories are available:\n\t * * `'contentEditing'` for keystrokes related to content creation,\n\t * * `'navigation'` for keystrokes related to navigation in the UI and the content.\n\t *\n\t * To create a new keystroke category with new groups, use the following code:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfoCategory( {\n\t * \t\t\tid: 'myCategory',\n\t * \t\t\tlabel: t( 'My category' ),\n\t * \t\t\tdescription: t( 'My category description.' ),\n\t * \t\t\tgroups: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tid: 'myGroup',\n\t * \t\t\t\t\tlabel: t( 'My keystroke group' ),\n\t * \t\t\t\t\tkeystrokes: [\n\t * \t\t\t\t\t\t{\n\t * \t\t\t\t\t\t\tlabel: t( 'Keystroke label 1' ),\n\t * \t\t\t\t\t\t\tkeystroke: 'Ctrl+Shift+N'\n\t * \t\t\t\t\t\t},\n\t * \t\t\t\t\t\t{\n\t * \t\t\t\t\t\t\tlabel: t( 'Keystroke label 2' ),\n\t * \t\t\t\t\t\t\tkeystroke: 'Ctrl+Shift+M'\n\t * \t\t\t\t\t\t}\n\t * \t\t\t\t\t]\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t};\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * See {@link #keystrokeInfos}, {@link #addKeystrokeInfoGroup}, and {@link #addKeystrokeInfos}.\n\t */ addKeystrokeInfoCategory({ id, label, description, groups }) {\n        this.keystrokeInfos.set(id, {\n            id,\n            label,\n            description,\n            groups: new Map()\n        });\n        this.addKeystrokeInfoGroup({\n            categoryId: id,\n            id: DEFAULT_GROUP_ID\n        });\n        if (groups) {\n            groups.forEach((group)=>{\n                this.addKeystrokeInfoGroup({\n                    categoryId: id,\n                    ...group\n                });\n            });\n        }\n    }\n    /**\n\t * Adds a group of keystrokes in a specific category to the {@link #keystrokeInfos keystroke information database}.\n\t *\n\t * Groups narrow down the context in which the keystrokes are available. When `categoryId` is not specified,\n\t * the group goes to the `'contentEditing'` category (default).\n\t *\n\t * To create a new group within an existing category, use the following code:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfoGroup( {\n\t * \t\t\tid: 'myGroup',\n\t * \t\t\tcategoryId: 'navigation',\n\t * \t\t\tlabel: t( 'My keystroke group' ),\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label 1' ),\n\t * \t\t\t\t\tkeystroke: 'Ctrl+Shift+N'\n\t * \t\t\t\t},\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label 2' ),\n\t * \t\t\t\t\tkeystroke: 'Ctrl+Shift+M'\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * See {@link #keystrokeInfos}, {@link #addKeystrokeInfoCategory}, and {@link #addKeystrokeInfos}.\n\t */ addKeystrokeInfoGroup({ categoryId = DEFAULT_CATEGORY_ID, id, label, keystrokes }) {\n        const category = this.keystrokeInfos.get(categoryId);\n        if (!category) {\n            throw new CKEditorError('accessibility-unknown-keystroke-info-category', this._editor, {\n                groupId: id,\n                categoryId\n            });\n        }\n        category.groups.set(id, {\n            id,\n            label,\n            keystrokes: keystrokes || []\n        });\n    }\n    /**\n\t * Adds information about keystrokes to the {@link #keystrokeInfos keystroke information database}.\n\t *\n\t * Keystrokes without specified `groupId` or `categoryId` go to the `'common'` group in the `'contentEditing'` category (default).\n\t *\n\t * To add a keystroke brought by your plugin (using default group and category), use the following code:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfos( {\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label' ),\n\t * \t\t\t\t\tkeystroke: 'CTRL+B'\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t * To add a keystroke in a specific existing `'widget'` group in the default `'contentEditing'` category:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfos( {\n\t * \t\t\t// Add a keystroke to the existing \"widget\" group.\n\t * \t\t\tgroupId: 'widget',\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'A an action on a selected widget' ),\n\t * \t\t\t\t\tkeystroke: 'Ctrl+D',\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * To add a keystroke to another existing category (using default group):\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfos( {\n\t * \t\t\t// Add keystrokes to the \"navigation\" category (one of defaults).\n\t * \t\t\tcategoryId: 'navigation',\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label' ),\n\t * \t\t\t\t\tkeystroke: 'CTRL+B'\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * See {@link #keystrokeInfos}, {@link #addKeystrokeInfoGroup}, and {@link #addKeystrokeInfoCategory}.\n\t */ addKeystrokeInfos({ categoryId = DEFAULT_CATEGORY_ID, groupId = DEFAULT_GROUP_ID, keystrokes }) {\n        if (!this.keystrokeInfos.has(categoryId)) {\n            /**\n\t\t\t * Cannot add keystrokes in an unknown category. Use\n\t\t\t * {@link module:core/accessibility~Accessibility#addKeystrokeInfoCategory}\n\t\t\t * to add a new category or make sure the specified category exists.\n\t\t\t *\n\t\t\t * @error accessibility-unknown-keystroke-info-category\n\t\t\t * @param categoryId The id of the unknown keystroke category.\n\t\t\t * @param keystrokes Keystroke definitions about to be added.\n\t\t\t */ throw new CKEditorError('accessibility-unknown-keystroke-info-category', this._editor, {\n                categoryId,\n                keystrokes\n            });\n        }\n        const category = this.keystrokeInfos.get(categoryId);\n        if (!category.groups.has(groupId)) {\n            /**\n\t\t\t * Cannot add keystrokes to an unknown group.\n\t\t\t *\n\t\t\t * Use {@link module:core/accessibility~Accessibility#addKeystrokeInfoGroup}\n\t\t\t * to add a new group or make sure the specified group exists.\n\t\t\t *\n\t\t\t * @error accessibility-unknown-keystroke-info-group\n\t\t\t * @param groupId The id of the unknown keystroke group.\n\t\t\t * @param categoryId The id of category the unknown group should belong to.\n\t\t\t * @param keystrokes Keystroke definitions about to be added.\n\t\t\t */ throw new CKEditorError('accessibility-unknown-keystroke-info-group', this._editor, {\n                groupId,\n                categoryId,\n                keystrokes\n            });\n        }\n        category.groups.get(groupId).keystrokes.push(...keystrokes);\n    }\n}\n\n/**\n * The class representing a basic, generic editor.\n *\n * Check out the list of its subclasses to learn about specific editor implementations.\n *\n * All editor implementations (like {@link module:editor-classic/classiceditor~ClassicEditor} or\n * {@link module:editor-inline/inlineeditor~InlineEditor}) should extend this class. They can add their\n * own methods and properties.\n *\n * When you are implementing a plugin, this editor represents the API\n * which your plugin can expect to get when using its {@link module:core/plugin~Plugin#editor} property.\n *\n * This API should be sufficient in order to implement the \"editing\" part of your feature\n * (schema definition, conversion, commands, keystrokes, etc.).\n * It does not define the editor UI, which is available only if\n * the specific editor implements also the {@link ~Editor#ui} property\n * (as most editor implementations do).\n */ class Editor extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * A namespace for the accessibility features of the editor.\n\t */ accessibility;\n    /**\n\t * Commands registered to the editor.\n\t *\n\t * Use the shorthand {@link #execute `editor.execute()`} method to execute commands:\n\t *\n\t * ```ts\n\t * // Execute the bold command:\n\t * editor.execute( 'bold' );\n\t *\n\t * // Check the state of the bold command:\n\t * editor.commands.get( 'bold' ).value;\n\t * ```\n\t */ commands;\n    /**\n\t * Stores all configurations specific to this editor instance.\n\t *\n\t * ```ts\n\t * editor.config.get( 'image.toolbar' );\n\t * // -> [ 'imageStyle:block', 'imageStyle:side', '|', 'toggleImageCaption', 'imageTextAlternative' ]\n\t * ```\n\t */ config;\n    /**\n\t * Conversion manager through which you can register model-to-view and view-to-model converters.\n\t *\n\t * See the {@link module:engine/conversion/conversion~Conversion} documentation to learn how to add converters.\n\t */ conversion;\n    /**\n\t * The {@link module:engine/controller/datacontroller~DataController data controller}.\n\t * Used e.g. for setting and retrieving the editor data.\n\t */ data;\n    /**\n\t * The {@link module:engine/controller/editingcontroller~EditingController editing controller}.\n\t * Controls user input and rendering the content for editing.\n\t */ editing;\n    /**\n\t * The locale instance.\n\t */ locale;\n    /**\n\t * The editor's model.\n\t *\n\t * The central point of the editor's abstract data model.\n\t */ model;\n    /**\n\t * The plugins loaded and in use by this editor instance.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'ClipboardPipeline' ); // -> An instance of the clipboard pipeline plugin.\n\t * ```\n\t */ plugins;\n    /**\n\t * An instance of the {@link module:core/editingkeystrokehandler~EditingKeystrokeHandler}.\n\t *\n\t * It allows setting simple keystrokes:\n\t *\n\t * ```ts\n\t * // Execute the bold command on Ctrl+E:\n\t * editor.keystrokes.set( 'Ctrl+E', 'bold' );\n\t *\n\t * // Execute your own callback:\n\t * editor.keystrokes.set( 'Ctrl+E', ( data, cancel ) => {\n\t * \tconsole.log( data.keyCode );\n\t *\n\t * \t// Prevent the default (native) action and stop the underlying keydown event\n\t * \t// so no other editor feature will interfere.\n\t * \tcancel();\n\t * } );\n\t * ```\n\t *\n\t * Note: Certain typing-oriented keystrokes (like <kbd>Backspace</kbd> or <kbd>Enter</kbd>) are handled\n\t * by a low-level mechanism and trying to listen to them via the keystroke handler will not work reliably.\n\t * To handle these specific keystrokes, see the events fired by the\n\t * {@link module:engine/view/document~Document editing view document} (`editor.editing.view.document`).\n\t */ keystrokes;\n    /**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t *\n\t * @see module:utils/locale~Locale#t\n\t */ t;\n    /**\n\t * The default configuration which is built into the editor class.\n\t *\n\t * It is used in CKEditor 5 builds to provide the default configuration options which are later used during the editor initialization.\n\t *\n\t * ```ts\n\t * ClassicEditor.defaultConfig = {\n\t * \tfoo: 1,\n\t * \tbar: 2\n\t * };\n\t *\n\t * ClassicEditor\n\t * \t.create( sourceElement )\n\t * \t.then( editor => {\n\t * \t\teditor.config.get( 'foo' ); // -> 1\n\t * \t\teditor.config.get( 'bar' ); // -> 2\n\t * \t} );\n\t *\n\t * // The default options can be overridden by the configuration passed to create().\n\t * ClassicEditor\n\t * \t.create( sourceElement, { bar: 3 } )\n\t * \t.then( editor => {\n\t * \t\teditor.config.get( 'foo' ); // -> 1\n\t * \t\teditor.config.get( 'bar' ); // -> 3\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/editor/editor~Editor.builtinPlugins}.\n\t */ static defaultConfig;\n    /**\n\t * An array of plugins built into this editor class.\n\t *\n\t * It is used in CKEditor 5 builds to provide a list of plugins which are later automatically initialized\n\t * during the editor initialization.\n\t *\n\t * They will be automatically initialized by the editor, unless listed in `config.removePlugins` and\n\t * unless `config.plugins` is passed.\n\t *\n\t * ```ts\n\t * // Build some plugins into the editor class first.\n\t * ClassicEditor.builtinPlugins = [ FooPlugin, BarPlugin ];\n\t *\n\t * // Normally, you need to define config.plugins, but since ClassicEditor.builtinPlugins was\n\t * // defined, now you can call create() without any configuration.\n\t * ClassicEditor\n\t * \t.create( sourceElement )\n\t * \t.then( editor => {\n\t * \t\teditor.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.\n\t * \t\teditor.plugins.get( BarPlugin ); // -> An instance of the Bar plugin.\n\t * \t} );\n\t *\n\t * ClassicEditor\n\t * \t.create( sourceElement, {\n\t * \t\t// Do not initialize these plugins (note: it is defined by a string):\n\t * \t\tremovePlugins: [ 'Foo' ]\n\t * \t} )\n\t * \t.then( editor => {\n\t * \t\teditor.plugins.get( FooPlugin ); // -> Undefined.\n\t * \t\teditor.config.get( BarPlugin ); // -> An instance of the Bar plugin.\n\t * \t} );\n\t *\n\t * ClassicEditor\n\t * \t.create( sourceElement, {\n\t * \t\t// Load only this plugin. It can also be defined by a string if\n\t * \t\t// this plugin was built into the editor class.\n\t * \t\tplugins: [ FooPlugin ]\n\t * \t} )\n\t * \t.then( editor => {\n\t * \t\teditor.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.\n\t * \t\teditor.config.get( BarPlugin ); // -> Undefined.\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/editor/editor~Editor.defaultConfig}.\n\t */ static builtinPlugins;\n    /**\n\t * The editor context.\n\t * When it is not provided through the configuration, the editor creates it.\n\t */ _context;\n    /**\n\t * A set of lock IDs for the {@link #isReadOnly} getter.\n\t */ _readOnlyLocks;\n    /**\n\t * Creates a new instance of the editor class.\n\t *\n\t * Usually, not to be used directly. See the static {@link module:core/editor/editor~Editor.create `create()`} method.\n\t *\n\t * @param config The editor configuration.\n\t */ constructor(config = {}){\n        super();\n        if ('sanitizeHtml' in config) {\n            /**\n\t\t\t * Configuration property `config.sanitizeHtml` was removed in CKEditor version 43.1.0 and is no longer supported.\n\t\t\t *\n\t\t\t * Please use `config.htmlEmbed.sanitizeHtml` and/or `config.mergeFields.sanitizeHtml` instead.\n\t\t\t *\n\t\t\t * @error editor-config-sanitizehtml-not-supported\n\t\t\t */ throw new CKEditorError('editor-config-sanitizehtml-not-supported');\n        }\n        const constructor = this.constructor;\n        // We don't pass translations to the config, because its behavior of splitting keys\n        // with dots (e.g. `resize.width` => `resize: { width }`) breaks the translations.\n        const { translations: defaultTranslations, ...defaultConfig } = constructor.defaultConfig || {};\n        const { translations = defaultTranslations, ...rest } = config;\n        // Prefer the language passed as the argument to the constructor instead of the constructor's `defaultConfig`, if both are set.\n        const language = config.language || defaultConfig.language;\n        this._context = config.context || new Context({\n            language,\n            translations\n        });\n        this._context._addEditor(this, !config.context);\n        // Clone the plugins to make sure that the plugin array will not be shared\n        // between editors and make the watchdog feature work correctly.\n        const availablePlugins = Array.from(constructor.builtinPlugins || []);\n        this.config = new Config(rest, defaultConfig);\n        this.config.define('plugins', availablePlugins);\n        this.config.define(this._context._getEditorConfig());\n        this.plugins = new PluginCollection(this, availablePlugins, this._context.plugins);\n        this.locale = this._context.locale;\n        this.t = this.locale.t;\n        this._readOnlyLocks = new Set();\n        this.commands = new CommandCollection();\n        this.set('state', 'initializing');\n        this.once('ready', ()=>this.state = 'ready', {\n            priority: 'high'\n        });\n        this.once('destroy', ()=>this.state = 'destroyed', {\n            priority: 'high'\n        });\n        this.model = new Model();\n        this.on('change:isReadOnly', ()=>{\n            this.model.document.isReadOnly = this.isReadOnly;\n        });\n        const stylesProcessor = new StylesProcessor();\n        this.data = new DataController(this.model, stylesProcessor);\n        this.editing = new EditingController(this.model, stylesProcessor);\n        this.editing.view.document.bind('isReadOnly').to(this);\n        this.conversion = new Conversion([\n            this.editing.downcastDispatcher,\n            this.data.downcastDispatcher\n        ], this.data.upcastDispatcher);\n        this.conversion.addAlias('dataDowncast', this.data.downcastDispatcher);\n        this.conversion.addAlias('editingDowncast', this.editing.downcastDispatcher);\n        this.keystrokes = new EditingKeystrokeHandler(this);\n        this.keystrokes.listenTo(this.editing.view.document);\n        this.accessibility = new Accessibility(this);\n    }\n    /**\n\t * Defines whether the editor is in the read-only mode.\n\t *\n\t * In read-only mode the editor {@link #commands commands} are disabled so it is not possible\n\t * to modify the document by using them. Also, the editable element(s) become non-editable.\n\t *\n\t * In order to make the editor read-only, you need to call the {@link #enableReadOnlyMode} method:\n\t *\n\t * ```ts\n\t * editor.enableReadOnlyMode( 'feature-id' );\n\t * ```\n\t *\n     * Later, to turn off the read-only mode, call {@link #disableReadOnlyMode}:\n\t *\n\t * ```ts\n\t * editor.disableReadOnlyMode( 'feature-id' );\n\t * ```\n\t *\n\t * @readonly\n\t * @observable\n\t */ get isReadOnly() {\n        return this._readOnlyLocks.size > 0;\n    }\n    set isReadOnly(value) {\n        /**\n\t\t * The {@link module:core/editor/editor~Editor#isReadOnly Editor#isReadOnly} property is read-only since version `34.0.0`\n\t\t * and can be set only using {@link module:core/editor/editor~Editor#enableReadOnlyMode `Editor#enableReadOnlyMode( lockId )`} and\n\t\t * {@link module:core/editor/editor~Editor#disableReadOnlyMode `Editor#disableReadOnlyMode( lockId )`}.\n\t\t *\n\t\t * Usage before version `34.0.0`:\n\t\t *\n\t\t * ```ts\n\t\t * editor.isReadOnly = true;\n\t\t * editor.isReadOnly = false;\n\t\t * ```\n\t\t *\n\t\t * Usage since version `34.0.0`:\n\t\t *\n\t\t * ```ts\n\t\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t\t * editor.disableReadOnlyMode( 'my-feature-id' );\n\t\t * ```\n\t\t *\n\t\t * @error editor-isreadonly-has-no-setter\n\t\t */ throw new CKEditorError('editor-isreadonly-has-no-setter');\n    }\n    /**\n\t * Turns on the read-only mode in the editor.\n\t *\n\t * Editor can be switched to or out of the read-only mode by many features, under various circumstances. The editor supports locking\n\t * mechanism for the read-only mode. It enables easy control over the read-only mode when many features wants to turn it on or off at\n\t * the same time, without conflicting with each other. It guarantees that you will not make the editor editable accidentally (which\n\t * could lead to errors).\n\t *\n\t * Each read-only mode request is identified by a unique id (also called \"lock\"). If multiple plugins requested to turn on the\n\t * read-only mode, then, the editor will become editable only after all these plugins turn the read-only mode off (using the same ids).\n\t *\n\t * Note, that you cannot force the editor to disable the read-only mode if other plugins set it.\n\t *\n\t * After the first `enableReadOnlyMode()` call, the {@link #isReadOnly `isReadOnly` property} will be set to `true`:\n\t *\n\t * ```ts\n\t * editor.isReadOnly; // `false`.\n\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t * editor.isReadOnly; // `true`.\n\t * ```\n\t *\n\t * You can turn off the read-only mode (\"clear the lock\") using the {@link #disableReadOnlyMode `disableReadOnlyMode()`} method:\n\t *\n\t * ```ts\n\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t * // ...\n\t * editor.disableReadOnlyMode( 'my-feature-id' );\n\t * editor.isReadOnly; // `false`.\n\t * ```\n\t *\n\t * All \"locks\" need to be removed to enable editing:\n\t *\n\t * ```ts\n\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t * editor.enableReadOnlyMode( 'my-other-feature-id' );\n\t * // ...\n\t * editor.disableReadOnlyMode( 'my-feature-id' );\n\t * editor.isReadOnly; // `true`.\n\t * editor.disableReadOnlyMode( 'my-other-feature-id' );\n\t * editor.isReadOnly; // `false`.\n\t * ```\n\t *\n\t * @param lockId A unique ID for setting the editor to the read-only state.\n\t */ enableReadOnlyMode(lockId) {\n        if (typeof lockId !== 'string' && typeof lockId !== 'symbol') {\n            /**\n\t\t\t * The lock ID is missing or it is not a string or symbol.\n\t\t\t *\n\t\t\t * @error editor-read-only-lock-id-invalid\n\t\t\t */ throw new CKEditorError('editor-read-only-lock-id-invalid', null, {\n                lockId\n            });\n        }\n        if (this._readOnlyLocks.has(lockId)) {\n            return;\n        }\n        this._readOnlyLocks.add(lockId);\n        if (this._readOnlyLocks.size === 1) {\n            // Manually fire the `change:isReadOnly` event as only getter is provided.\n            this.fire('change:isReadOnly', 'isReadOnly', true, false);\n        }\n    }\n    /**\n\t * Removes the read-only lock from the editor with given lock ID.\n\t *\n\t * When no lock is present on the editor anymore, then the {@link #isReadOnly `isReadOnly` property} will be set to `false`.\n\t *\n\t * @param lockId The lock ID for setting the editor to the read-only state.\n\t */ disableReadOnlyMode(lockId) {\n        if (typeof lockId !== 'string' && typeof lockId !== 'symbol') {\n            throw new CKEditorError('editor-read-only-lock-id-invalid', null, {\n                lockId\n            });\n        }\n        if (!this._readOnlyLocks.has(lockId)) {\n            return;\n        }\n        this._readOnlyLocks.delete(lockId);\n        if (this._readOnlyLocks.size === 0) {\n            // Manually fire the `change:isReadOnly` event as only getter is provided.\n            this.fire('change:isReadOnly', 'isReadOnly', false, true);\n        }\n    }\n    /**\n\t * Sets the data in the editor.\n\t *\n\t * ```ts\n\t * editor.setData( '<p>This is editor!</p>' );\n\t * ```\n\t *\n\t * If your editor implementation uses multiple roots, you should pass an object with keys corresponding\n\t * to the editor root names and values equal to the data that should be set in each root:\n\t *\n\t * ```ts\n\t * editor.setData( {\n\t *     header: '<p>Content for header part.</p>',\n\t *     content: '<p>Content for main part.</p>',\n\t *     footer: '<p>Content for footer part.</p>'\n\t * } );\n\t * ```\n\t *\n\t * By default the editor accepts HTML. This can be controlled by injecting a different data processor.\n\t * See the {@glink features/markdown Markdown output} guide for more details.\n\t *\n\t * @param data Input data.\n\t */ setData(data) {\n        this.data.set(data);\n    }\n    /**\n\t * Gets the data from the editor.\n\t *\n\t * ```ts\n\t * editor.getData(); // -> '<p>This is editor!</p>'\n\t * ```\n\t *\n\t * If your editor implementation uses multiple roots, you should pass root name as one of the options:\n\t *\n\t * ```ts\n\t * editor.getData( { rootName: 'header' } ); // -> '<p>Content for header part.</p>'\n\t * ```\n\t *\n\t * By default, the editor outputs HTML. This can be controlled by injecting a different data processor.\n\t * See the {@glink features/markdown Markdown output} guide for more details.\n\t *\n\t * A warning is logged when you try to retrieve data for a detached root, as most probably this is a mistake. A detached root should\n\t * be treated like it is removed, and you should not save its data. Note, that the detached root data is always an empty string.\n\t *\n\t * @param options Additional configuration for the retrieved data.\n\t * Editor features may introduce more configuration options that can be set through this parameter.\n\t * @param options.rootName Root name. Defaults to `'main'`.\n\t * @param options.trim Whether returned data should be trimmed. This option is set to `'empty'` by default,\n\t * which means that whenever editor content is considered empty, an empty string is returned. To turn off trimming\n\t * use `'none'`. In such cases exact content will be returned (for example `'<p>&nbsp;</p>'` for an empty editor).\n\t * @returns Output data.\n\t */ getData(options) {\n        return this.data.get(options);\n    }\n    /**\n\t * Loads and initializes plugins specified in the configuration.\n\t *\n\t * @returns A promise which resolves once the initialization is completed, providing an array of loaded plugins.\n\t */ initPlugins() {\n        const config = this.config;\n        const plugins = config.get('plugins');\n        const removePlugins = config.get('removePlugins') || [];\n        const extraPlugins = config.get('extraPlugins') || [];\n        const substitutePlugins = config.get('substitutePlugins') || [];\n        return this.plugins.init(plugins.concat(extraPlugins), removePlugins, substitutePlugins);\n    }\n    /**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * **Note** The editor cannot be destroyed during the initialization phase so if it is called\n\t * while the editor {@link #state is being initialized}, it will wait for the editor initialization before destroying it.\n\t *\n\t * @fires destroy\n\t * @returns A promise that resolves once the editor instance is fully destroyed.\n\t */ destroy() {\n        let readyPromise = Promise.resolve();\n        if (this.state == 'initializing') {\n            readyPromise = new Promise((resolve)=>this.once('ready', resolve));\n        }\n        return readyPromise.then(()=>{\n            this.fire('destroy');\n            this.stopListening();\n            this.commands.destroy();\n        }).then(()=>this.plugins.destroy()).then(()=>{\n            this.model.destroy();\n            this.data.destroy();\n            this.editing.destroy();\n            this.keystrokes.destroy();\n        })// Remove the editor from the context.\n        // When the context was created by this editor, the context will be destroyed.\n        .then(()=>this._context._removeEditor(this));\n    }\n    /**\n\t * Executes the specified command with given parameters.\n\t *\n\t * Shorthand for:\n\t *\n\t * ```ts\n\t * editor.commands.get( commandName ).execute( ... );\n\t * ```\n\t *\n\t * @param commandName The name of the command to execute.\n\t * @param commandParams Command parameters.\n\t * @returns The value returned by the {@link module:core/commandcollection~CommandCollection#execute `commands.execute()`}.\n\t */ execute(commandName, ...commandParams) {\n        try {\n            return this.commands.execute(commandName, ...commandParams);\n        } catch (err) {\n            // @if CK_DEBUG // throw err;\n            /* istanbul ignore next -- @preserve */ CKEditorError.rethrowUnexpectedError(err, this);\n        }\n    }\n    /**\n\t * Focuses the editor.\n\t *\n\t * **Note** To explicitly focus the editing area of the editor, use the\n\t * {@link module:engine/view/view~View#focus `editor.editing.view.focus()`} method of the editing view.\n\t *\n\t * Check out the {@glink framework/deep-dive/ui/focus-tracking#focus-in-the-editor-ui Focus in the editor UI} section\n\t * of the {@glink framework/deep-dive/ui/focus-tracking Deep dive into focus tracking} guide to learn more.\n\t */ focus() {\n        this.editing.view.focus();\n    }\n    /* istanbul ignore next -- @preserve */ /**\n\t * Creates and initializes a new editor instance.\n\t *\n\t * This is an abstract method. Every editor type needs to implement its own initialization logic.\n\t *\n\t * See the `create()` methods of the existing editor types to learn how to use them:\n\t *\n\t * * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}\n\t * * {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`}\n\t * * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`}\n\t * * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`}\n\t */ static create(...args) {\n        throw new Error('This is an abstract method.');\n    }\n    /**\n\t * The {@link module:core/context~Context} class.\n\t *\n\t * Exposed as static editor field for easier access in editor builds.\n\t */ static Context = Context;\n    /**\n\t * The {@link module:watchdog/editorwatchdog~EditorWatchdog} class.\n\t *\n\t * Exposed as static editor field for easier access in editor builds.\n\t */ static EditorWatchdog = EditorWatchdog;\n    /**\n\t * The {@link module:watchdog/contextwatchdog~ContextWatchdog} class.\n\t *\n\t * Exposed as static editor field for easier access in editor builds.\n\t */ static ContextWatchdog = ContextWatchdog;\n}\n /**\n * This error is thrown when trying to pass a `<textarea>` element to a `create()` function of an editor class.\n *\n * The only editor type which can be initialized on `<textarea>` elements is\n * the {@glink getting-started/setup/editor-types#classic-editor classic editor}.\n * This editor hides the passed element and inserts its own UI next to it. Other types of editors reuse the passed element as their root\n * editable element and therefore `<textarea>` is not appropriate for them. Use a `<div>` or another text container instead:\n *\n * ```html\n * <div id=\"editor\">\n * \t<p>Initial content.</p>\n * </div>\n * ```\n *\n * @error editor-wrong-element\n */\n\n/**\n * Checks if the editor is initialized on a `<textarea>` element that belongs to a form. If yes, it updates the editor's element\n * content before submitting the form.\n *\n * This helper requires the {@link module:core/editor/utils/elementapimixin~ElementApi ElementApi interface}.\n *\n * @param editor Editor instance.\n */ function attachToForm(editor) {\n    if (!isFunction(editor.updateSourceElement)) {\n        /**\n\t\t * The editor passed to `attachToForm()` must implement the\n\t\t * {@link module:core/editor/utils/elementapimixin~ElementApi} interface.\n\t\t *\n\t\t * @error attachtoform-missing-elementapi-interface\n\t\t */ throw new CKEditorError('attachtoform-missing-elementapi-interface', editor);\n    }\n    const sourceElement = editor.sourceElement;\n    // Only when replacing a textarea which is inside of a form element.\n    if (isTextArea(sourceElement) && sourceElement.form) {\n        let originalSubmit;\n        const form = sourceElement.form;\n        const onSubmit = ()=>editor.updateSourceElement();\n        // Replace the original form#submit() to call a custom submit function first.\n        // Check if #submit is a function because the form might have an input named \"submit\".\n        if (isFunction(form.submit)) {\n            originalSubmit = form.submit;\n            form.submit = ()=>{\n                onSubmit();\n                originalSubmit.apply(form);\n            };\n        }\n        // Update the replaced textarea with data before each form#submit event.\n        form.addEventListener('submit', onSubmit);\n        // Remove the submit listener and revert the original submit method on\n        // editor#destroy.\n        editor.on('destroy', ()=>{\n            form.removeEventListener('submit', onSubmit);\n            if (originalSubmit) {\n                form.submit = originalSubmit;\n            }\n        });\n    }\n}\nfunction isTextArea(sourceElement) {\n    return !!sourceElement && sourceElement.tagName.toLowerCase() === 'textarea';\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module core/editor/utils/dataapimixin\n */ /**\n * Implementation of the {@link module:core/editor/utils/dataapimixin~DataApi}.\n *\n * @deprecated This functionality is already implemented by the `Editor` class.\n */ function DataApiMixin(base) {\n    return base;\n}\n\n/**\n * Implementation of the {@link module:core/editor/utils/elementapimixin~ElementApi}.\n */ function ElementApiMixin(base) {\n    class Mixin extends base {\n        sourceElement;\n        updateSourceElement(data) {\n            if (!this.sourceElement) {\n                /**\n\t\t\t\t * Cannot update the source element of a detached editor.\n\t\t\t\t *\n\t\t\t\t * The {@link module:core/editor/utils/elementapimixin~ElementApi#updateSourceElement `updateSourceElement()`}\n\t\t\t\t * method cannot be called if you did not pass an element to `Editor.create()`.\n\t\t\t\t *\n\t\t\t\t * @error editor-missing-sourceelement\n\t\t\t\t */ throw new CKEditorError('editor-missing-sourceelement', this);\n            }\n            const shouldUpdateSourceElement = this.config.get('updateSourceElementOnDestroy');\n            const isSourceElementTextArea = this.sourceElement instanceof HTMLTextAreaElement;\n            // The data returned by the editor might be unsafe, so we want to prevent rendering\n            // unsafe content inside the source element different than <textarea>, which is considered\n            // secure. This behavior could be changed by setting the `updateSourceElementOnDestroy`\n            // configuration option to `true`.\n            if (!shouldUpdateSourceElement && !isSourceElementTextArea) {\n                setDataInElement(this.sourceElement, '');\n                return;\n            }\n            const dataToSet = typeof data === 'string' ? data : this.data.get();\n            setDataInElement(this.sourceElement, dataToSet);\n        }\n    }\n    return Mixin;\n}\n// Backward compatibility with `mix`.\nElementApiMixin.updateSourceElement = ElementApiMixin(Object).prototype.updateSourceElement;\n\n/**\n * Marks the source element on which the editor was initialized. This prevents other editor instances from using this element.\n *\n * Running multiple editor instances on the same source element causes various issues and it is\n * crucial this helper is called as soon as the source element is known to prevent collisions.\n *\n * @param editor Editor instance.\n * @param sourceElement Element to bind with the editor instance.\n */ function secureSourceElement(editor, sourceElement) {\n    if (sourceElement.ckeditorInstance) {\n        /**\n\t\t * A DOM element used to create the editor (e.g.\n\t\t * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`})\n\t\t * has already been used to create another editor instance. Make sure each editor is\n\t\t * created with an unique DOM element.\n\t\t *\n\t\t * @error editor-source-element-already-used\n\t\t * @param element DOM element that caused the collision.\n\t\t */ throw new CKEditorError('editor-source-element-already-used', editor);\n    }\n    sourceElement.ckeditorInstance = editor;\n    editor.once('destroy', ()=>{\n        delete sourceElement.ckeditorInstance;\n    });\n}\n\n/**\n * The list of pending editor actions.\n *\n * This plugin should be used to synchronise plugins that execute long-lasting actions\n * (e.g. file upload) with the editor integration. It gives the developer who integrates the editor\n * an easy way to check if there are any actions pending whenever such information is needed.\n * All plugins that register a pending action also provide a message about the action that is ongoing\n * which can be displayed to the user. This lets them decide if they want to interrupt the action or wait.\n *\n * Adding and updating a pending action:\n *\n * ```ts\n * const pendingActions = editor.plugins.get( 'PendingActions' );\n * const action = pendingActions.add( 'Upload in progress: 0%.' );\n *\n * // You can update the message:\n * action.message = 'Upload in progress: 10%.';\n * ```\n *\n * Removing a pending action:\n *\n * ```ts\n * const pendingActions = editor.plugins.get( 'PendingActions' );\n * const action = pendingActions.add( 'Unsaved changes.' );\n *\n * pendingActions.remove( action );\n * ```\n *\n * Getting pending actions:\n *\n * ```ts\n * const pendingActions = editor.plugins.get( 'PendingActions' );\n *\n * const action1 = pendingActions.add( 'Action 1' );\n * const action2 = pendingActions.add( 'Action 2' );\n *\n * pendingActions.first; // Returns action1\n * Array.from( pendingActions ); // Returns [ action1, action2 ]\n * ```\n *\n * This plugin is used by features like {@link module:upload/filerepository~FileRepository} to register their ongoing actions\n * and by features like {@link module:autosave/autosave~Autosave} to detect whether there are any ongoing actions.\n * Read more about saving the data in the\n * {@glink getting-started/setup/getting-and-setting-data Saving and getting data} guide.\n */ class PendingActions extends ContextPlugin {\n    /**\n\t * A list of pending actions.\n\t */ _actions;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'PendingActions';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        this.set('hasAny', false);\n        this._actions = new Collection({\n            idProperty: '_id'\n        });\n        this._actions.delegate('add', 'remove').to(this);\n    }\n    /**\n\t * Adds an action to the list of pending actions.\n\t *\n\t * This method returns an action object with an observable message property.\n\t * The action object can be later used in the {@link #remove} method. It also allows you to change the message.\n\t *\n\t * @param message The action message.\n\t * @returns An observable object that represents a pending action.\n\t */ add(message) {\n        if (typeof message !== 'string') {\n            /**\n\t\t\t * The message must be a string.\n\t\t\t *\n\t\t\t * @error pendingactions-add-invalid-message\n\t\t\t */ throw new CKEditorError('pendingactions-add-invalid-message', this);\n        }\n        const action = new (ObservableMixin())();\n        action.set('message', message);\n        this._actions.add(action);\n        this.hasAny = true;\n        return action;\n    }\n    /**\n\t * Removes an action from the list of pending actions.\n\t *\n\t * @param action An action object.\n\t */ remove(action) {\n        this._actions.remove(action);\n        this.hasAny = !!this._actions.length;\n    }\n    /**\n\t * Returns the first action from the list or null if the list is empty\n\t *\n\t * @returns The pending action object.\n\t */ get first() {\n        return this._actions.get(0);\n    }\n    /**\n\t * Iterable interface.\n\t */ [Symbol.iterator]() {\n        return this._actions[Symbol.iterator]();\n    }\n}\n\nvar cancel = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m11.591 10.177 4.243 4.242a1 1 0 0 1-1.415 1.415l-4.242-4.243-4.243 4.243a1 1 0 0 1-1.414-1.415l4.243-4.242L4.52 5.934A1 1 0 0 1 5.934 4.52l4.243 4.243 4.242-4.243a1 1 0 1 1 1.415 1.414l-4.243 4.243z\\\"/></svg>\";\n\nvar caption = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 16h9a1 1 0 0 1 0 2H2a1 1 0 0 1 0-2z\\\"/><path d=\\\"M17 1a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h14zm0 1.5H3a.5.5 0 0 0-.492.41L2.5 3v9a.5.5 0 0 0 .41.492L3 12.5h14a.5.5 0 0 0 .492-.41L17.5 12V3a.5.5 0 0 0-.41-.492L17 2.5z\\\" fill-opacity=\\\".6\\\"/></svg>\";\n\nvar check = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M6.972 16.615a.997.997 0 0 1-.744-.292l-4.596-4.596a1 1 0 1 1 1.414-1.414l3.926 3.926 9.937-9.937a1 1 0 0 1 1.414 1.415L7.717 16.323a.997.997 0 0 1-.745.292z\\\"/></svg>\";\n\nvar cog = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m11.333 2 .19 2.263a5.899 5.899 0 0 1 1.458.604L14.714 3.4 16.6 5.286l-1.467 1.733c.263.452.468.942.605 1.46L18 8.666v2.666l-2.263.19a5.899 5.899 0 0 1-.604 1.458l1.467 1.733-1.886 1.886-1.733-1.467a5.899 5.899 0 0 1-1.46.605L11.334 18H8.667l-.19-2.263a5.899 5.899 0 0 1-1.458-.604L5.286 16.6 3.4 14.714l1.467-1.733a5.899 5.899 0 0 1-.604-1.458L2 11.333V8.667l2.262-.189a5.899 5.899 0 0 1 .605-1.459L3.4 5.286 5.286 3.4l1.733 1.467a5.899 5.899 0 0 1 1.46-.605L8.666 2h2.666zM10 6.267a3.733 3.733 0 1 0 0 7.466 3.733 3.733 0 0 0 0-7.466z\\\"/></svg>\";\n\nvar colorPalette = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M10.209 18.717A8.5 8.5 0 1 1 18.686 9.6h-.008l.002.12a3 3 0 0 1-2.866 2.997h-.268l-.046-.002v.002h-4.791a2 2 0 1 0 0 4 1 1 0 1 1-.128 1.992 8.665 8.665 0 0 1-.372.008Zm-3.918-7.01a1.25 1.25 0 1 0-2.415-.648 1.25 1.25 0 0 0 2.415.647ZM5.723 8.18a1.25 1.25 0 1 0 .647-2.414 1.25 1.25 0 0 0-.647 2.414ZM9.76 6.155a1.25 1.25 0 1 0 .647-2.415 1.25 1.25 0 0 0-.647 2.415Zm4.028 1.759a1.25 1.25 0 1 0 .647-2.415 1.25 1.25 0 0 0-.647 2.415Z\\\"/></svg>\";\n\nvar eraser = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m8.636 9.531-2.758 3.94a.5.5 0 0 0 .122.696l3.224 2.284h1.314l2.636-3.736L8.636 9.53zm.288 8.451L5.14 15.396a2 2 0 0 1-.491-2.786l6.673-9.53a2 2 0 0 1 2.785-.49l3.742 2.62a2 2 0 0 1 .491 2.785l-7.269 10.053-2.147-.066z\\\"/><path d=\\\"M4 18h5.523v-1H4zm-2 0h1v-1H2z\\\"/></svg>\";\n\nvar history = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M11 1a9 9 0 1 1-8.027 13.075l1.128-1.129A7.502 7.502 0 0 0 18.5 10a7.5 7.5 0 1 0-14.962.759l-.745-.746-.76.76A9 9 0 0 1 11 1z\\\"/><path d=\\\"M.475 8.17a.75.75 0 0 1 .978.047l.075.082 1.284 1.643 1.681-1.284a.75.75 0 0 1 .978.057l.073.083a.75.75 0 0 1-.057.978l-.083.073-2.27 1.737a.75.75 0 0 1-.973-.052l-.074-.082-1.741-2.23a.75.75 0 0 1 .13-1.052z\\\"/><path d=\\\"M11.5 5v4.999l3.196 3.196-1.06 1.06L10.1 10.72l-.1-.113V5z\\\"/></svg>\";\n\nvar lowVision = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M5.085 6.22 2.943 4.078a.75.75 0 1 1 1.06-1.06l2.592 2.59A11.094 11.094 0 0 1 10 5.068c4.738 0 8.578 3.101 8.578 5.083 0 1.197-1.401 2.803-3.555 3.887l1.714 1.713a.75.75 0 0 1-.09 1.138.488.488 0 0 1-.15.084.75.75 0 0 1-.821-.16L6.17 7.304c-.258.11-.51.233-.757.365l6.239 6.24-.006.005.78.78c-.388.094-.78.166-1.174.215l-1.11-1.11h.011L4.55 8.197a7.2 7.2 0 0 0-.665.514l-.112.098 4.897 4.897-.005.006 1.276 1.276a10.164 10.164 0 0 1-1.477-.117l-.479-.479-.009.009-4.863-4.863-.022.031a2.563 2.563 0 0 0-.124.2c-.043.077-.08.158-.108.241a.534.534 0 0 0-.028.133.29.29 0 0 0 .008.072.927.927 0 0 0 .082.226c.067.133.145.26.234.379l3.242 3.365.025.01.59.623c-3.265-.918-5.59-3.155-5.59-4.668 0-1.194 1.448-2.838 3.663-3.93zm7.07.531a4.632 4.632 0 0 1 1.108 5.992l.345.344.046-.018a9.313 9.313 0 0 0 2-1.112c.256-.187.5-.392.727-.613.137-.134.27-.277.392-.431.072-.091.141-.185.203-.286.057-.093.107-.19.148-.292a.72.72 0 0 0 .036-.12.29.29 0 0 0 .008-.072.492.492 0 0 0-.028-.133.999.999 0 0 0-.036-.096 2.165 2.165 0 0 0-.071-.145 2.917 2.917 0 0 0-.125-.2 3.592 3.592 0 0 0-.263-.335 5.444 5.444 0 0 0-.53-.523 7.955 7.955 0 0 0-1.054-.768 9.766 9.766 0 0 0-1.879-.891c-.337-.118-.68-.219-1.027-.301zm-2.85.21-.069.002a.508.508 0 0 0-.254.097.496.496 0 0 0-.104.679.498.498 0 0 0 .326.199l.045.005c.091.003.181.003.272.012a2.45 2.45 0 0 1 2.017 1.513c.024.061.043.125.069.185a.494.494 0 0 0 .45.287h.008a.496.496 0 0 0 .35-.158.482.482 0 0 0 .13-.335.638.638 0 0 0-.048-.219 3.379 3.379 0 0 0-.36-.723 3.438 3.438 0 0 0-2.791-1.543l-.028-.001h-.013z\\\"/></svg>\";\n\nvar textAlternative = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3.035 1C2.446 1 2 1.54 2 2.098V10.5h1.5v-8h13v8H18V2.098C18 1.539 17.48 1 16.9 1H3.035Zm10.453 2.61a1.885 1.885 0 0 0-1.442.736 1.89 1.89 0 0 0 1.011 2.976 1.903 1.903 0 0 0 2.253-1.114 1.887 1.887 0 0 0-1.822-2.598ZM7.463 8.163a.611.611 0 0 0-.432.154L5.071 10.5h5.119L7.88 8.348a.628.628 0 0 0-.417-.185Zm6.236 1.059a.62.62 0 0 0-.42.164L12.07 10.5h2.969l-.92-1.113a.618.618 0 0 0-.42-.165ZM.91 11.5a.91.91 0 0 0-.91.912v6.877c0 .505.405.91.91.91h18.178a.91.91 0 0 0 .912-.91v-6.877a.908.908 0 0 0-.912-.912H.91ZM3.668 13h1.947l2.135 5.7H5.898l-.28-.946H3.601l-.278.945H1.516L3.668 13Zm4.947 0h1.801v4.3h2.7v1.4h-4.5V13h-.001Zm4.5 0h5.4v1.4h-1.798v4.3h-1.701v-4.3h-1.9V13h-.001Zm-8.517 1.457-.614 2.059h1.262l-.648-2.059Z\\\"/></svg>\";\n\nvar loupe = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M12.68 13.74h-.001l4.209 4.208a1 1 0 1 0 1.414-1.414l-4.267-4.268a6 6 0 1 0-1.355 1.474ZM13 9a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z\\\"/></svg>\";\n\nvar previousArrow = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M11.463 5.187a.888.888 0 1 1 1.254 1.255L9.16 10l3.557 3.557a.888.888 0 1 1-1.254 1.255L7.26 10.61a.888.888 0 0 1 .16-1.382l4.043-4.042z\\\"/></svg>\";\n\nvar nextArrow = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M8.537 14.813a.888.888 0 1 1-1.254-1.255L10.84 10 7.283 6.442a.888.888 0 1 1 1.254-1.255L12.74 9.39a.888.888 0 0 1-.16 1.382l-4.043 4.042z\\\"/></svg>\";\n\nvar image = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M6.66 9.118a.693.693 0 0 1 .956.032l3.65 3.411 2.422-2.238a.695.695 0 0 1 .945 0L17.5 13.6V2.5h-15v11.1l4.16-4.482ZM17.8 1c.652 0 1.2.47 1.2 1.1v14.362c0 .64-.532 1.038-1.184 1.038H2.184C1.532 17.5 1 17.103 1 16.462V2.1C1 1.47 1.537 1 2.2 1h15.6Zm-5.655 6a2.128 2.128 0 0 1 .157-2.364A2.133 2.133 0 1 1 12.145 7Z\\\"/></svg>\";\n\nvar imageUpload = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M1.201 1C.538 1 0 1.47 0 2.1v14.363c0 .64.534 1.037 1.186 1.037h9.494a2.97 2.97 0 0 1-.414-.287 2.998 2.998 0 0 1-1.055-2.03 3.003 3.003 0 0 1 .693-2.185l.383-.455-.02.018-3.65-3.41a.695.695 0 0 0-.957-.034L1.5 13.6V2.5h15v5.535a2.97 2.97 0 0 1 1.412.932l.088.105V2.1c0-.63-.547-1.1-1.2-1.1H1.202Zm11.713 2.803a2.146 2.146 0 0 0-2.049 1.992 2.14 2.14 0 0 0 1.28 2.096 2.13 2.13 0 0 0 2.644-3.11 2.134 2.134 0 0 0-1.875-.978Z\\\"/><path d=\\\"M15.522 19.1a.79.79 0 0 0 .79-.79v-5.373l2.059 2.455a.79.79 0 1 0 1.211-1.015l-3.352-3.995a.79.79 0 0 0-.995-.179.784.784 0 0 0-.299.221l-3.35 3.99a.79.79 0 1 0 1.21 1.017l1.936-2.306v5.185c0 .436.353.79.79.79Z\\\"/><path d=\\\"M15.522 19.1a.79.79 0 0 0 .79-.79v-5.373l2.059 2.455a.79.79 0 1 0 1.211-1.015l-3.352-3.995a.79.79 0 0 0-.995-.179.784.784 0 0 0-.299.221l-3.35 3.99a.79.79 0 1 0 1.21 1.017l1.936-2.306v5.185c0 .436.353.79.79.79Z\\\"/></svg>\";\n\nvar imageAssetManager = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M1.201 1c-.662 0-1.2.47-1.2 1.1v14.248c0 .64.533 1.152 1.185 1.152h6.623v-7.236L6.617 9.15a.694.694 0 0 0-.957-.033L1.602 13.55V2.553l14.798.003V9.7H18V2.1c0-.63-.547-1.1-1.2-1.1H1.202Zm11.723 2.805a2.094 2.094 0 0 0-1.621.832 2.127 2.127 0 0 0 1.136 3.357 2.13 2.13 0 0 0 2.611-1.506 2.133 2.133 0 0 0-.76-2.244 2.13 2.13 0 0 0-1.366-.44Z\\\"/><path clip-rule=\\\"evenodd\\\" d=\\\"M19.898 12.369v6.187a.844.844 0 0 1-.844.844h-8.719a.844.844 0 0 1-.843-.844v-7.312a.844.844 0 0 1 .843-.844h2.531a.843.843 0 0 1 .597.248l.838.852h4.75c.223 0 .441.114.6.272a.844.844 0 0 1 .247.597Zm-1.52.654-4.377.02-1.1-1.143H11v6h7.4l-.023-4.877Z\\\"/></svg>\";\n\nvar imageUrl = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M1.201 1C.538 1 0 1.47 0 2.1v14.363c0 .64.534 1.037 1.186 1.037h7.029a5.401 5.401 0 0 1 .615-4.338l.762-1.232-2.975-2.78a.696.696 0 0 0-.957-.033L1.5 13.6V2.5h15v6.023c.449.131.887.32 1.307.573l.058.033c.046.028.09.057.135.086V2.1c0-.63-.547-1.1-1.2-1.1H1.202Zm11.713 2.803a2.15 2.15 0 0 0-1.611.834 2.118 2.118 0 0 0-.438 1.158 2.14 2.14 0 0 0 1.277 2.096 2.132 2.132 0 0 0 2.645-3.11 2.13 2.13 0 0 0-1.873-.978Z\\\"/><path d=\\\"M16.63 10.294a3.003 3.003 0 0 0-4.142.887l-.117.177a.647.647 0 0 0-.096.492.664.664 0 0 0 .278.418.7.7 0 0 0 .944-.234 1.741 1.741 0 0 1 2.478-.463 1.869 1.869 0 0 1 .476 2.55.637.637 0 0 0-.071.5.646.646 0 0 0 .309.396.627.627 0 0 0 .869-.19l.027-.041a3.226 3.226 0 0 0-.956-4.492Zm-6.061 3.78-.044.066a3.228 3.228 0 0 0 .82 4.403 3.005 3.005 0 0 0 4.275-.798l.13-.197a.626.626 0 0 0 .092-.475.638.638 0 0 0-.268-.402.713.713 0 0 0-.99.26l-.018.029a1.741 1.741 0 0 1-2.477.461 1.87 1.87 0 0 1-.475-2.55l.029-.047a.647.647 0 0 0 .086-.485.66.66 0 0 0-.275-.408l-.04-.027a.609.609 0 0 0-.845.17Z\\\"/><path d=\\\"M15.312 13.925c.24-.36.154-.838-.19-1.067-.346-.23-.82-.124-1.059.236l-1.268 1.907c-.239.36-.153.838.192 1.067.345.23.818.123 1.057-.236l1.268-1.907Z\\\"/></svg>\";\n\nvar alignBottom = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m9.239 13.938-2.88-1.663a.75.75 0 0 1 .75-1.3L9 12.067V4.75a.75.75 0 1 1 1.5 0v7.318l1.89-1.093a.75.75 0 0 1 .75 1.3l-2.879 1.663a.752.752 0 0 1-.511.187.752.752 0 0 1-.511-.187zM4.25 17a.75.75 0 1 1 0-1.5h10.5a.75.75 0 0 1 0 1.5H4.25z\\\"/></svg>\";\n\nvar alignMiddle = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M9.75 11.875a.752.752 0 0 1 .508.184l2.883 1.666a.75.75 0 0 1-.659 1.344l-.091-.044-1.892-1.093.001 4.318a.75.75 0 1 1-1.5 0v-4.317l-1.89 1.092a.75.75 0 0 1-.75-1.3l2.879-1.663a.752.752 0 0 1 .51-.187zM15.25 9a.75.75 0 1 1 0 1.5H4.75a.75.75 0 1 1 0-1.5h10.5zM9.75.375a.75.75 0 0 1 .75.75v4.318l1.89-1.093.092-.045a.75.75 0 0 1 .659 1.344l-2.883 1.667a.752.752 0 0 1-.508.184.752.752 0 0 1-.511-.187L6.359 5.65a.75.75 0 0 1 .75-1.299L9 5.442V1.125a.75.75 0 0 1 .75-.75z\\\"/></svg>\";\n\nvar alignTop = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m10.261 7.062 2.88 1.663a.75.75 0 0 1-.75 1.3L10.5 8.933v7.317a.75.75 0 1 1-1.5 0V8.932l-1.89 1.093a.75.75 0 0 1-.75-1.3l2.879-1.663a.752.752 0 0 1 .511-.187.752.752 0 0 1 .511.187zM15.25 4a.75.75 0 1 1 0 1.5H4.75a.75.75 0 0 1 0-1.5h10.5z\\\"/></svg>\";\n\nvar alignLeft = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 3.75c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm0 8c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm0 4c0 .414.336.75.75.75h9.929a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm0-8c0 .414.336.75.75.75h9.929a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75z\\\"/></svg>\";\n\nvar alignCenter = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 3.75c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm0 8c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm2.286 4c0 .414.336.75.75.75h9.928a.75.75 0 1 0 0-1.5H5.036a.75.75 0 0 0-.75.75zm0-8c0 .414.336.75.75.75h9.928a.75.75 0 1 0 0-1.5H5.036a.75.75 0 0 0-.75.75z\\\"/></svg>\";\n\nvar alignRight = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M18 3.75a.75.75 0 0 1-.75.75H2.75a.75.75 0 1 1 0-1.5h14.5a.75.75 0 0 1 .75.75zm0 8a.75.75 0 0 1-.75.75H2.75a.75.75 0 1 1 0-1.5h14.5a.75.75 0 0 1 .75.75zm0 4a.75.75 0 0 1-.75.75H7.321a.75.75 0 1 1 0-1.5h9.929a.75.75 0 0 1 .75.75zm0-8a.75.75 0 0 1-.75.75H7.321a.75.75 0 1 1 0-1.5h9.929a.75.75 0 0 1 .75.75z\\\"/></svg>\";\n\nvar alignJustify = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 3.75c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm0 8c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm0 4c0 .414.336.75.75.75h9.929a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm0-8c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75z\\\"/></svg>\";\n\nvar objectBlockLeft = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path opacity=\\\".5\\\" d=\\\"M2 3h16v1.5H2zm0 12h16v1.5H2z\\\"/><path d=\\\"M12.003 7v5.5a1 1 0 0 1-1 1H2.996a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h8.007a1 1 0 0 1 1 1zm-1.506.5H3.5V12h6.997V7.5z\\\"/></svg>\";\n\nvar objectCenter = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path opacity=\\\".5\\\" d=\\\"M2 3h16v1.5H2zm0 12h16v1.5H2z\\\"/><path d=\\\"M15.003 7v5.5a1 1 0 0 1-1 1H5.996a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h8.007a1 1 0 0 1 1 1zm-1.506.5H6.5V12h6.997V7.5z\\\"/></svg>\";\n\nvar objectBlockRight = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path opacity=\\\".5\\\" d=\\\"M2 3h16v1.5H2zm0 12h16v1.5H2z\\\"/><path d=\\\"M18.003 7v5.5a1 1 0 0 1-1 1H8.996a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h8.007a1 1 0 0 1 1 1zm-1.506.5H9.5V12h6.997V7.5z\\\"/></svg>\";\n\nvar objectFullWidth = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path opacity=\\\".5\\\" d=\\\"M2 3h16v1.5H2zm0 12h16v1.5H2z\\\"/><path d=\\\"M18 7v5.5a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1zm-1.505.5H3.504V12h12.991V7.5z\\\"/></svg>\";\n\nvar objectInline = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path opacity=\\\".5\\\" d=\\\"M2 3h16v1.5H2zm11.5 9H18v1.5h-4.5zM2 15h16v1.5H2z\\\"/><path d=\\\"M12.003 7v5.5a1 1 0 0 1-1 1H2.996a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h8.007a1 1 0 0 1 1 1zm-1.506.5H3.5V12h6.997V7.5z\\\"/></svg>\";\n\nvar objectLeft = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path opacity=\\\".5\\\" d=\\\"M2 3h16v1.5H2zm11.5 9H18v1.5h-4.5zm0-3H18v1.5h-4.5zm0-3H18v1.5h-4.5zM2 15h16v1.5H2z\\\"/><path d=\\\"M12.003 7v5.5a1 1 0 0 1-1 1H2.996a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h8.007a1 1 0 0 1 1 1zm-1.506.5H3.5V12h6.997V7.5z\\\"/></svg>\";\n\nvar objectRight = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path opacity=\\\".5\\\" d=\\\"M2 3h16v1.5H2zm0 12h16v1.5H2zm0-9h5v1.5H2zm0 3h5v1.5H2zm0 3h5v1.5H2z\\\"/><path d=\\\"M18.003 7v5.5a1 1 0 0 1-1 1H8.996a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h8.007a1 1 0 0 1 1 1zm-1.506.5H9.5V12h6.997V7.5z\\\"/></svg>\";\n\nvar objectSizeFull = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 20 20\\\"><path d=\\\"M2.5 17v1h-1v-1h1zm2 0v1h-1v-1h1zm2 0v1h-1v-1h1zm2 0v1h-1v-1h1zm2 0v1h-1v-1h1zm2 0v1h-1v-1h1zm2 0v1h-1v-1h1zm2 0v1h-1v-1h1zm2 0v1h-1v-1h1zM1 15.5v1H0v-1h1zm19 0v1h-1v-1h1zm-19-2v1H0v-1h1zm19 0v1h-1v-1h1zm-19-2v1H0v-1h1zm19 0v1h-1v-1h1zm-19-2v1H0v-1h1zm19 0v1h-1v-1h1zm-19-2v1H0v-1h1zm19 0v1h-1v-1h1zm-19-2v1H0v-1h1zm19 0v1h-1v-1h1zm0-2v1h-1v-1h1zm-19 0v1H0v-1h1zM14.5 2v1h-1V2h1zm2 0v1h-1V2h1zm2 0v1h-1V2h1zm-8 0v1h-1V2h1zm-2 0v1h-1V2h1zm-2 0v1h-1V2h1zm-2 0v1h-1V2h1zm8 0v1h-1V2h1zm-10 0v1h-1V2h1z\\\"/><path d=\\\"M18.095 2H1.905C.853 2 0 2.895 0 4v12c0 1.105.853 2 1.905 2h16.19C19.147 18 20 17.105 20 16V4c0-1.105-.853-2-1.905-2zm0 1.5c.263 0 .476.224.476.5v12c0 .276-.213.5-.476.5H1.905a.489.489 0 0 1-.476-.5V4c0-.276.213-.5.476-.5h16.19z\\\"/></svg>\";\n\nvar objectSizeCustom = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" xmlns:v=\\\"https://vecta.io/nano\\\" viewBox=\\\"0 0 20 20\\\"><path d=\\\"M.95 1.43a.95.95 0 0 0-.95.95v3.1a.95.95 0 0 0 .95.95h.75v6.3H.95a.95.95 0 0 0-.95.95v3.1a.95.95 0 0 0 .95.95h3.1a.95.95 0 0 0 .95-.95v-.65h1.932l1.539-1.5H5v-.95a.95.95 0 0 0-.95-.95H3.2v-6.3h.85A.95.95 0 0 0 5 5.48v-.55h10v.55a.95.95 0 0 0 .95.95h3.1a.95.95 0 0 0 .95-.95v-3.1a.95.95 0 0 0-.95-.95h-3.1a.95.95 0 0 0-.95.95v1.05H5V2.38a.95.95 0 0 0-.95-.95H.95zm.55 3.5v-2h2v2h-2zm0 9.3v2h2v-2h-2zm15-11.3v2h2v-2h-2z\\\"/><path d=\\\"M8.139 20.004v-2.388l7.045-7.048 2.391 2.391-7.046 7.046h-2.39zm11.421-9.101a.64.64 0 0 1-.138.206l-1.165 1.168-2.391-2.391 1.167-1.163a.63.63 0 0 1 .206-.138.635.635 0 0 1 .243-.049.63.63 0 0 1 .449.187l1.491 1.488c.059.059.108.129.138.206s.049.16.049.243a.6.6 0 0 1-.049.243z\\\"/></svg>\";\n\nvar objectSizeLarge = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 16.5v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1ZM1 15v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 13v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 11v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 9v1H0V9h1Zm19 0v1h-1V9h1ZM1 7v1H0V7h1Zm19 0v1h-1V7h1ZM1 5v1H0V5h1Zm19 0v1h-1V5h1Zm0-2v1h-1V3h1ZM1 3v1H0V3h1Zm13.5-1.5v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm-8 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm8 0v1h-1v-1h1Zm-10 0v1h-1v-1h1Z\\\"/><path d=\\\"M13 5.5H2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2ZM13 7a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5v-8A.5.5 0 0 1 2 7h11Z\\\"/></svg>\";\n\nvar objectSizeSmall = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 16.5v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1ZM1 15v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 13v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 11v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 9v1H0V9h1Zm19 0v1h-1V9h1ZM1 7v1H0V7h1Zm19 0v1h-1V7h1ZM1 5v1H0V5h1Zm19 0v1h-1V5h1Zm0-2v1h-1V3h1ZM1 3v1H0V3h1Zm13.5-1.5v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm-8 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm8 0v1h-1v-1h1Zm-10 0v1h-1v-1h1Z\\\"/><path d=\\\"M7 9.5H2a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h5a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2ZM7 11a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5v-4A.5.5 0 0 1 2 11h5Z\\\"/></svg>\";\n\nvar objectSizeMedium = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 16.5v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1ZM1 15v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 13v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 11v1H0v-1h1Zm19 0v1h-1v-1h1ZM1 9v1H0V9h1Zm19 0v1h-1V9h1ZM1 7v1H0V7h1Zm19 0v1h-1V7h1ZM1 5v1H0V5h1Zm19 0v1h-1V5h1Zm0-2v1h-1V3h1ZM1 3v1H0V3h1Zm13.5-1.5v1h-1v-1h1Zm2 0v1h-1v-1h1Zm2 0v1h-1v-1h1Zm-8 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm-2 0v1h-1v-1h1Zm8 0v1h-1v-1h1Zm-10 0v1h-1v-1h1Z\\\"/><path d=\\\"M10 7.5H2a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2ZM10 9a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5v-6A.5.5 0 0 1 2 9h8Z\\\"/></svg>\";\n\nvar pencil = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m7.3 17.37-.061.088a1.518 1.518 0 0 1-.934.535l-4.178.663-.806-4.153a1.495 1.495 0 0 1 .187-1.058l.056-.086L8.77 2.639c.958-1.351 2.803-1.076 4.296-.03 1.497 1.047 2.387 2.693 1.433 4.055L7.3 17.37zM9.14 4.728l-5.545 8.346 3.277 2.294 5.544-8.346L9.14 4.728zM6.07 16.512l-3.276-2.295.53 2.73 2.746-.435zM9.994 3.506 13.271 5.8c.316-.452-.16-1.333-1.065-1.966-.905-.634-1.895-.78-2.212-.328zM8 18.5 9.375 17H19v1.5H8z\\\"/></svg>\";\n\nvar pilcrow = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M6.999 2H15a1 1 0 0 1 0 2h-1.004v13a1 1 0 1 1-2 0V4H8.999v13a1 1 0 1 1-2 0v-7A4 4 0 0 1 3 6a4 4 0 0 1 3.999-4z\\\"/></svg>\";\n\nvar quote = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 10.423a6.5 6.5 0 0 1 6.056-6.408l.038.67C6.448 5.423 5.354 7.663 5.22 10H9c.552 0 .5.432.5.986v4.511c0 .554-.448.503-1 .503h-5c-.552 0-.5-.449-.5-1.003v-4.574zm8 0a6.5 6.5 0 0 1 6.056-6.408l.038.67c-2.646.739-3.74 2.979-3.873 5.315H17c.552 0 .5.432.5.986v4.511c0 .554-.448.503-1 .503h-5c-.552 0-.5-.449-.5-1.003v-4.574z\\\"/></svg>\";\n\nvar threeVerticalDots = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><circle cx=\\\"9.5\\\" cy=\\\"4.5\\\" r=\\\"1.5\\\"/><circle cx=\\\"9.5\\\" cy=\\\"10.5\\\" r=\\\"1.5\\\"/><circle cx=\\\"9.5\\\" cy=\\\"16.5\\\" r=\\\"1.5\\\"/></svg>\";\n\nvar dragIndicator = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M5 3.25a1.5 1.5 0 1 0 3 0 1.5 1.5 0 1 0-3 0\\\"/><path d=\\\"M12 3.25a1.5 1.5 0 1 0 3 0 1.5 1.5 0 1 0-3 0\\\"/><path d=\\\"M5 10a1.5 1.5 0 1 0 3 0 1.5 1.5 0 1 0-3 0\\\"/><path d=\\\"M12 10a1.5 1.5 0 1 0 3 0 1.5 1.5 0 1 0-3 0\\\"/><path d=\\\"M5 16.75a1.5 1.5 0 1 0 3 0 1.5 1.5 0 1 0-3 0\\\"/><path d=\\\"M12 16.75a1.5 1.5 0 1 0 3 0 1.5 1.5 0 1 0-3 0\\\"/></svg>\";\n\nvar bold = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M10.187 17H5.773c-.637 0-1.092-.138-1.364-.415-.273-.277-.409-.718-.409-1.323V4.738c0-.617.14-1.062.419-1.332.279-.27.73-.406 1.354-.406h4.68c.69 0 1.288.041 1.793.124.506.083.96.242 1.36.478.341.197.644.447.906.75a3.262 3.262 0 0 1 .808 2.162c0 1.401-.722 2.426-2.167 3.075C15.05 10.175 16 11.315 16 13.01a3.756 3.756 0 0 1-2.296 3.504 6.1 6.1 0 0 1-1.517.377c-.571.073-1.238.11-2 .11zm-.217-6.217H7v4.087h3.069c1.977 0 2.965-.69 2.965-2.072 0-.707-.256-1.22-.768-1.537-.512-.319-1.277-.478-2.296-.478zM7 5.13v3.619h2.606c.729 0 1.292-.067 1.69-.2a1.6 1.6 0 0 0 .91-.765c.165-.267.247-.566.247-.897 0-.707-.26-1.176-.778-1.409-.519-.232-1.31-.348-2.375-.348H7z\\\"/></svg>\";\n\nvar paragraph = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M10.5 5.5H7v5h3.5a2.5 2.5 0 1 0 0-5zM5 3h6.5v.025a5 5 0 0 1 0 9.95V13H7v4a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z\\\"/></svg>\";\n\nvar plus = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M10 2a1 1 0 0 0-1 1v6H3a1 1 0 1 0 0 2h6v6a1 1 0 1 0 2 0v-6h6a1 1 0 1 0 0-2h-6V3a1 1 0 0 0-1-1Z\\\"/></svg>\";\n\nvar text = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M9.816 11.5 7.038 4.785 4.261 11.5h5.555Zm.62 1.5H3.641l-1.666 4.028H.312l5.789-14h1.875l5.789 14h-1.663L10.436 13Z\\\"/><path d=\\\"m12.09 17-.534-1.292.848-1.971.545 1.319L12.113 17h-.023Zm1.142-5.187.545 1.319L15.5 9.13l1.858 4.316h-3.45l.398.965h3.467L18.887 17H20l-3.873-9h-1.254l-1.641 3.813Z\\\"/></svg>\";\n\nvar importExport = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M19 4.5 14 0H3v12.673l.868-1.041c.185-.222.4-.402.632-.54V1.5h8v5h5v7.626a2.24 2.24 0 0 1 1.5.822V4.5ZM14 5V2l3.3 3H14Zm-3.692 12.5c.062.105.133.206.213.303L11.52 19H8v-.876a2.243 2.243 0 0 0 1.82-.624h.488Zm7.518-.657a.75.75 0 0 0-1.152-.96L15.5 17.29V12H14v5.29l-1.174-1.408a.75.75 0 0 0-1.152.96l2.346 2.816a.95.95 0 0 0 1.46 0l2.346-2.815Zm-15.056-.38a.75.75 0 0 1-.096-1.056l2.346-2.815a.95.95 0 0 1 1.46 0l2.346 2.815a.75.75 0 1 1-1.152.96L6.5 14.96V20H5v-5.04l-1.174 1.408a.75.75 0 0 1-1.056.096Z\\\"/></svg>\";\n\nvar redo = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m14.958 9.367-2.189 1.837a.75.75 0 0 0 .965 1.149l3.788-3.18a.747.747 0 0 0 .21-.284.75.75 0 0 0-.17-.945L13.77 4.762a.75.75 0 1 0-.964 1.15l2.331 1.955H6.22A.75.75 0 0 0 6 7.9a4 4 0 1 0 1.477 7.718l-.344-1.489A2.5 2.5 0 1 1 6.039 9.4l-.008-.032h8.927z\\\"/></svg>\";\n\nvar undo = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m5.042 9.367 2.189 1.837a.75.75 0 0 1-.965 1.149l-3.788-3.18a.747.747 0 0 1-.21-.284.75.75 0 0 1 .17-.945L6.23 4.762a.75.75 0 1 1 .964 1.15L4.863 7.866h8.917A.75.75 0 0 1 14 7.9a4 4 0 1 1-1.477 7.718l.344-1.489a2.5 2.5 0 1 0 1.094-4.73l.008-.032H5.042z\\\"/></svg>\";\n\nvar bulletedList = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0C1 4.784 1.777 4 2.75 4c.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75C1.784 7.5 1 6.723 1 5.75zm6 9c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0c0-.966.777-1.75 1.75-1.75.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75-.966 0-1.75-.777-1.75-1.75z\\\"/></svg>\";\n\nvar numberedList = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zM3.5 3v5H2V3.7H1v-1h2.5V3zM.343 17.857l2.59-3.257H2.92a.6.6 0 1 0-1.04 0H.302a2 2 0 1 1 3.995 0h-.001c-.048.405-.16.734-.333.988-.175.254-.59.692-1.244 1.312H4.3v1h-4l.043-.043zM7 14.75a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z\\\"/></svg>\";\n\nvar todoList = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m2.315 14.705 2.224-2.24a.689.689 0 0 1 .963 0 .664.664 0 0 1 0 .949L2.865 16.07a.682.682 0 0 1-.112.089.647.647 0 0 1-.852-.051L.688 14.886a.635.635 0 0 1 0-.903.647.647 0 0 1 .91 0l.717.722zm5.185.045a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75zM2.329 5.745l2.21-2.226a.689.689 0 0 1 .963 0 .664.664 0 0 1 0 .95L2.865 7.125a.685.685 0 0 1-.496.196.644.644 0 0 1-.468-.187L.688 5.912a.635.635 0 0 1 0-.903.647.647 0 0 1 .91 0l.73.736zM7.5 5.75A.75.75 0 0 1 8.25 5h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z\\\"/></svg>\";\n\nvar codeBlock = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M12.87 12.61a.75.75 0 0 1-.089.976l-.085.07-3.154 2.254 3.412 2.414a.75.75 0 0 1 .237.95l-.057.095a.75.75 0 0 1-.95.237l-.096-.058-4.272-3.022-.003-1.223 4.01-2.867a.75.75 0 0 1 1.047.174zm2.795-.231.095.057 4.011 2.867-.003 1.223-4.272 3.022-.095.058a.75.75 0 0 1-.88-.151l-.07-.086-.058-.095a.75.75 0 0 1 .15-.88l.087-.07 3.412-2.414-3.154-2.253-.085-.071a.75.75 0 0 1 .862-1.207zM16 0a2 2 0 0 1 2 2v9.354l-.663-.492-.837-.001V2a.5.5 0 0 0-.5-.5H2a.5.5 0 0 0-.5.5v15a.5.5 0 0 0 .5.5h3.118L7.156 19H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h14zM5.009 15l.003 1H3v-1h2.009zm2.188-2-1.471 1H5v-1h2.197zM10 11v.095L8.668 12H7v-1h3zm4-2v1H7V9h7zm0-2v1H7V7h7zm-4-2v1H5V5h5zM6 3v1H3V3h3z\\\"/></svg>\";\n\nvar browseFiles = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M11.627 16.5zm5.873-.196zm0-7.001V8h-13v8.5h4.341c.191.54.457 1.044.785 1.5H2a1.5 1.5 0 0 1-1.5-1.5v-13A1.5 1.5 0 0 1 2 2h4.5a1.5 1.5 0 0 1 1.06.44L9.122 4H16a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 19 8v2.531a6.027 6.027 0 0 0-1.5-1.228zM16 6.5v-1H8.5l-2-2H2v13h1V8a1.5 1.5 0 0 1 1.5-1.5H16z\\\"/><path d=\\\"M14.5 19.5a5 5 0 1 1 0-10 5 5 0 0 1 0 10zM15 14v-2h-1v2h-2v1h2v2h1v-2h2v-1h-2z\\\"/></svg>\";\n\nvar heading1 = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M19 9v10h-2v-8h-2V9h4zM4 8.5h5V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v11.5a1 1 0 0 1-1 1H10a1 1 0 0 1-1-1V11H4v4.5a1 1 0 0 1-1 1h-.5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1H3a1 1 0 0 1 1 1v4.5z\\\"/></svg>\";\n\nvar heading2 = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 8.5h5V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v11.5a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V11H3v4.5a1 1 0 0 1-1 1h-.5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1H2a1 1 0 0 1 1 1v4.5zm16.076 8.343V18.5h-6.252c.067-.626.27-1.22.61-1.78.338-.561 1.006-1.305 2.005-2.232.804-.749 1.297-1.257 1.479-1.523.245-.368.368-.732.368-1.092 0-.398-.107-.703-.32-.917-.214-.214-.51-.32-.886-.32-.372 0-.669.111-.889.336-.22.224-.347.596-.38 1.117l-1.778-.178c.106-.982.438-1.686.997-2.114.558-.427 1.257-.64 2.095-.64.918 0 1.64.247 2.164.742.525.495.787 1.11.787 1.847 0 .419-.075.818-.225 1.197-.15.378-.388.775-.714 1.19-.216.275-.605.67-1.168 1.187-.563.516-.92.859-1.07 1.028a3.11 3.11 0 0 0-.365.495h3.542z\\\"/></svg>\";\n\nvar heading3 = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 8.5h5V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v11.5a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V11H3v4.5a1 1 0 0 1-1 1h-.5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1H2a1 1 0 0 1 1 1v4.5zm9.989 7.53 1.726-.209c.055.44.203.777.445 1.01.24.232.533.349.876.349.368 0 .678-.14.93-.42.251-.279.377-.655.377-1.13 0-.448-.12-.803-.362-1.066a1.153 1.153 0 0 0-.882-.393c-.228 0-.501.044-.819.133l.197-1.453c.482.012.85-.092 1.105-.315.253-.222.38-.517.38-.885 0-.313-.093-.563-.279-.75-.186-.185-.434-.278-.743-.278a1.07 1.07 0 0 0-.78.317c-.216.212-.347.52-.394.927l-1.644-.28c.114-.562.287-1.012.517-1.348.231-.337.553-.601.965-.794a3.24 3.24 0 0 1 1.387-.289c.876 0 1.579.28 2.108.838.436.457.653.973.653 1.549 0 .817-.446 1.468-1.339 1.955.533.114.96.37 1.28.768.319.398.478.878.478 1.441 0 .817-.298 1.513-.895 2.088-.596.576-1.339.864-2.228.864-.842 0-1.54-.243-2.094-.727-.555-.485-.876-1.118-.965-1.901z\\\"/></svg>\";\n\nvar heading4 = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3.5 8.5h5V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v11.5a1 1 0 0 1-1 1h-.5a1 1 0 0 1-1-1V11h-5v4.5a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v4.5zm13.55 10v-1.873h-3.81v-1.561l4.037-5.91h1.498v5.904h1.156v1.567h-1.156V18.5H17.05zm0-3.44v-3.18l-2.14 3.18h2.14z\\\"/></svg>\";\n\nvar heading5 = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3.5 8.5h5V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v11.5a1 1 0 0 1-1 1h-.5a1 1 0 0 1-1-1V11h-5v4.5a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v4.5zm9.578 7.607 1.777-.184c.05.402.201.72.45.955a1.223 1.223 0 0 0 1.81-.101c.258-.303.387-.759.387-1.368 0-.572-.128-1-.384-1.286-.256-.285-.59-.428-1-.428-.512 0-.971.226-1.377.679l-1.448-.21.915-4.843h4.716v1.67H15.56l-.28 1.58a2.697 2.697 0 0 1 1.219-.298 2.68 2.68 0 0 1 2.012.863c.55.576.825 1.323.825 2.241a3.36 3.36 0 0 1-.666 2.05c-.605.821-1.445 1.232-2.52 1.232-.86 0-1.56-.23-2.101-.692-.542-.461-.866-1.081-.971-1.86z\\\"/></svg>\";\n\nvar heading6 = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3.5 8.5h5V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v11.5a1 1 0 0 1-1 1h-.5a1 1 0 0 1-1-1V11h-5v4.5a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h.5a1 1 0 0 1 1 1v4.5zm15.595 2.973-1.726.19c-.043-.355-.153-.617-.33-.787-.178-.169-.409-.253-.692-.253-.377 0-.695.169-.956.507-.26.339-.424 1.043-.492 2.114.445-.525.997-.787 1.657-.787.745 0 1.383.284 1.914.85.531.568.797 1.3.797 2.197 0 .952-.28 1.716-.838 2.291-.559.576-1.276.864-2.152.864-.94 0-1.712-.365-2.317-1.095-.605-.73-.908-1.927-.908-3.59 0-1.705.316-2.935.946-3.688.63-.753 1.45-1.13 2.457-1.13.706 0 1.291.198 1.755.594.463.395.758.97.885 1.723zm-4.043 3.891c0 .58.133 1.028.4 1.343.266.315.57.473.914.473.33 0 .605-.13.825-.388.22-.258.33-.68.33-1.27 0-.604-.118-1.047-.355-1.329a1.115 1.115 0 0 0-.89-.422c-.342 0-.632.134-.869.403s-.355.666-.355 1.19z\\\"/></svg>\";\n\nvar horizontalLine = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 9h16v2H2z\\\"/></svg>\";\n\nvar html = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M17 0a2 2 0 0 1 2 2v7a1 1 0 0 1 1 1v5a1 1 0 0 1-.883.993l-.118.006L19 17a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2l-.001-1.001-.116-.006A1 1 0 0 1 0 15v-5a1 1 0 0 1 .999-1L1 2a2 2 0 0 1 2-2h14zm.499 15.999h-15L2.5 17a.5.5 0 0 0 .5.5h14a.5.5 0 0 0 .5-.5l-.001-1.001zm-3.478-6.013-.014.014H14v.007l-1.525 1.525-1.46-1.46-.015.013V10h-1v5h1v-3.53l1.428 1.43.048.043.131-.129L14 11.421V15h1v-5h-.965l-.014-.014zM2 10H1v5h1v-2h2v2h1v-5H4v2H2v-2zm7 0H6v1h1v4h1v-4h1v-1zm8 0h-1v5h3v-1h-2v-4zm0-8.5H3a.5.5 0 0 0-.5.5l-.001 6.999h15L17.5 2a.5.5 0 0 0-.5-.5zM10 7v1H4V7h6zm3-2v1H4V5h9zm-3-2v1H4V3h6z\\\"/></svg>\";\n\nvar indent = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 3.75c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm5 6c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zM2.75 16.5h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 1 0 0 1.5zM1.632 6.95 5.02 9.358a.4.4 0 0 1-.013.661l-3.39 2.207A.4.4 0 0 1 1 11.892V7.275a.4.4 0 0 1 .632-.326z\\\"/></svg>\";\n\nvar outdent = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2 3.75c0 .414.336.75.75.75h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 0 0-.75.75zm5 6c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zM2.75 16.5h14.5a.75.75 0 1 0 0-1.5H2.75a.75.75 0 1 0 0 1.5zm1.618-9.55L.98 9.358a.4.4 0 0 0 .013.661l3.39 2.207A.4.4 0 0 0 5 11.892V7.275a.4.4 0 0 0-.632-.326z\\\"/></svg>\";\n\nvar table = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 5.5v3h4v-3H3Zm0 4v3h4v-3H3Zm0 4v3h4v-3H3Zm5 3h4v-3H8v3Zm5 0h4v-3h-4v3Zm4-4v-3h-4v3h4Zm0-4v-3h-4v3h4Zm1.5 8A1.5 1.5 0 0 1 17 18H3a1.5 1.5 0 0 1-1.5-1.5V3c.222-.863 1.068-1.5 2-1.5h13c.932 0 1.778.637 2 1.5v13.5Zm-6.5-4v-3H8v3h4Zm0-4v-3H8v3h4Z\\\"/></svg>\";\n\nconst icons = {\n    bold,\n    cancel,\n    caption,\n    check,\n    cog,\n    colorPalette,\n    eraser,\n    history,\n    image,\n    imageUpload,\n    imageAssetManager,\n    imageUrl,\n    lowVision,\n    textAlternative,\n    loupe,\n    previousArrow,\n    nextArrow,\n    importExport,\n    paragraph,\n    plus,\n    text,\n    alignBottom,\n    alignMiddle,\n    alignTop,\n    alignLeft,\n    alignCenter,\n    alignRight,\n    alignJustify,\n    objectLeft,\n    objectCenter,\n    objectRight,\n    objectFullWidth,\n    objectInline,\n    objectBlockLeft,\n    objectBlockRight,\n    objectSizeCustom,\n    objectSizeFull,\n    objectSizeLarge,\n    objectSizeSmall,\n    objectSizeMedium,\n    pencil,\n    pilcrow,\n    quote,\n    threeVerticalDots,\n    dragIndicator,\n    redo,\n    undo,\n    bulletedList,\n    numberedList,\n    todoList,\n    codeBlock,\n    browseFiles,\n    heading1,\n    heading2,\n    heading3,\n    heading4,\n    heading5,\n    heading6,\n    horizontalLine,\n    html,\n    indent,\n    outdent,\n    table\n};\n\nexport { Command, Context, ContextPlugin, DataApiMixin, Editor, ElementApiMixin, MultiCommand, PendingActions, Plugin, attachToForm, icons, secureSourceElement };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/plugin\n */\n\n/* eslint-disable @typescript-eslint/no-invalid-void-type */\n\nimport { ObservableMixin, type ObservableSetEvent, type EventInfo } from '@ckeditor/ckeditor5-utils';\n\nimport type Editor from './editor/editor.js';\n\n/**\n * The base class for CKEditor plugin classes.\n */\nexport default class Plugin extends /* #__PURE__ */ ObservableMixin() implements PluginInterface {\n\t/**\n\t * The editor instance.\n\t *\n\t * Note that most editors implement the {@link module:core/editor/editor~Editor#ui} property.\n\t * However, editors with an external UI (i.e. Bootstrap-based) or a headless editor may not have this property or\n\t * throw an error when accessing it.\n\t *\n\t * Because of above, to make plugins more universal, it is recommended to split features into:\n\t *  - The \"editing\" part that uses the {@link module:core/editor/editor~Editor} class without `ui` property.\n\t *  - The \"UI\" part that uses the {@link module:core/editor/editor~Editor} class and accesses `ui` property.\n\t */\n\tpublic readonly editor: Editor;\n\n\t/**\n\t * Flag indicating whether a plugin is enabled or disabled.\n\t * A disabled plugin will not transform text.\n\t *\n\t * Plugin can be simply disabled like that:\n\t *\n\t * ```ts\n\t * // Disable the plugin so that no toolbars are visible.\n\t * editor.plugins.get( 'TextTransformation' ).isEnabled = false;\n\t * ```\n\t *\n\t * You can also use {@link #forceDisabled} method.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tpublic declare isEnabled: boolean;\n\n\t/**\n\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t */\n\tprivate _disableStack = new Set<string>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper();\n\n\t\tthis.editor = editor;\n\n\t\tthis.set( 'isEnabled', true );\n\t}\n\n\t/**\n\t * Disables the plugin.\n\t *\n\t * Plugin may be disabled by multiple features or algorithms (at once). When disabling a plugin, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the plugin.\n\t * The plugin becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a plugin:\n\t *\n\t * ```ts\n\t * plugin.isEnabled; // -> true\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> false\n\t * plugin.clearForceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> true\n\t * ```\n\t *\n\t * Plugin disabled by multiple features:\n\t *\n\t * ```ts\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.forceDisabled( 'OtherFeature' );\n\t * plugin.clearForceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> false\n\t * plugin.clearForceDisabled( 'OtherFeature' );\n\t * plugin.isEnabled; // -> true\n\t * ```\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t * ```ts\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.forceDisabled( 'MyFeature' );\n\t * plugin.clearForceDisabled( 'MyFeature' );\n\t * plugin.isEnabled; // -> true\n\t * ```\n\t *\n\t * **Note:** some plugins or algorithms may have more complex logic when it comes to enabling or disabling certain plugins,\n\t * so the plugin might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the plugin.\n\t */\n\tpublic forceDisabled( id: string ): void {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on<ObservableSetEvent<boolean>>( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}.\n\t *\n\t * @param id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tpublic clearForceDisabled( id: string ): void {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.isEnabled = true;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get isContextPlugin(): false {\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get isOfficialPlugin(): boolean {\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get isPremiumPlugin(): boolean {\n\t\treturn false;\n\t}\n}\n\n/**\n * The base interface for CKEditor plugins.\n *\n * In its minimal form a plugin can be a simple function that accepts {@link module:core/editor/editor~Editor the editor}\n * as a parameter:\n *\n * ```ts\n * // A simple plugin that enables a data processor.\n * function MyPlugin( editor ) {\n * \teditor.data.processor = new MyDataProcessor();\n * }\n * ```\n *\n * In most cases however, you will want to inherit from the {@link ~Plugin} class which implements the\n * {@link module:utils/observablemixin~Observable} and is, therefore, more convenient:\n *\n * ```ts\n * class MyPlugin extends Plugin {\n * \tinit() {\n * \t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n * \t\t// By using `listenTo()` you will ensure that the listener is removed when\n * \t\t// the plugin is destroyed.\n * \t\tthis.listenTo( this.editor.data, 'ready', () => {\n * \t\t\t// Do something when the data is ready.\n * \t\t} );\n * \t}\n * }\n * ```\n *\n * The plugin class can have `pluginName` and `requires` static members. See {@link ~PluginStaticMembers} for more details.\n *\n * The plugin can also implement methods (e.g. {@link ~PluginInterface#init `init()`} or\n * {@link ~PluginInterface#destroy `destroy()`}) which, when present, will be used to properly\n * initialize and destroy the plugin.\n *\n * **Note:** When defined as a plain function, the plugin acts as a constructor and will be\n * called in parallel with other plugins' {@link ~PluginConstructor constructors}.\n * This means the code of that plugin will be executed **before** {@link ~PluginInterface#init `init()`} and\n * {@link ~PluginInterface#afterInit `afterInit()`} methods of other plugins and, for instance,\n * you cannot use it to extend other plugins' {@glink framework/architecture/editing-engine#schema schema}\n * rules as they are defined later on during the `init()` stage.\n */\nexport interface PluginInterface {\n\n\t/**\n\t * The second stage (after plugin constructor) of the plugin initialization.\n\t * Unlike the plugin constructor this method can be asynchronous.\n\t *\n\t * A plugin's `init()` method is called after its {@link ~PluginStaticMembers#requires dependencies} are initialized,\n\t * so in the same order as the constructors of these plugins.\n\t *\n\t * **Note:** This method is optional. A plugin instance does not need to have it defined.\n\t */\n\tinit?(): Promise<unknown> | null | undefined | void;\n\n\t/**\n\t * The third (and last) stage of the plugin initialization. See also {@link ~PluginConstructor} and {@link ~PluginInterface#init}.\n\t *\n\t * **Note:** This method is optional. A plugin instance does not need to have it defined.\n\t */\n\tafterInit?(): Promise<unknown> | null | undefined | void;\n\n\t/**\n\t * Destroys the plugin.\n\t *\n\t * **Note:** This method is optional. A plugin instance does not need to have it defined.\n\t */\n\tdestroy?(): Promise<unknown> | null | undefined | void;\n}\n\n/**\n * Creates a new plugin instance. This is the first step of the plugin initialization.\n * See also {@link ~PluginInterface#init} and {@link ~PluginInterface#afterInit}.\n *\n * The plugin static properties should conform to {@link ~PluginStaticMembers `PluginStaticMembers` interface}.\n *\n * A plugin is always instantiated after its {@link ~PluginStaticMembers#requires dependencies} and the\n * {@link ~PluginInterface#init} and {@link ~PluginInterface#afterInit} methods are called in the same order.\n *\n * Usually, you will want to put your plugin's initialization code in the {@link ~PluginInterface#init} method.\n * The constructor can be understood as \"before init\" and used in special cases, just like\n * {@link ~PluginInterface#afterInit} serves the special \"after init\" scenarios (e.g.the code which depends on other\n * plugins, but which does not {@link ~PluginStaticMembers#requires explicitly require} them).\n */\nexport type PluginConstructor<TContext = Editor> =\n\t( PluginClassConstructor<TContext> | PluginFunctionConstructor<TContext> ) & PluginStaticMembers<TContext>;\n\n/**\n * In most cases, you will want to inherit from the {@link ~Plugin} class which implements the\n * {@link module:utils/observablemixin~Observable} and is, therefore, more convenient:\n *\n * ```ts\n * class MyPlugin extends Plugin {\n * \tinit() {\n * \t\t// `listenTo()` and `editor` are available thanks to `Plugin`.\n * \t\t// By using `listenTo()` you will ensure that the listener is removed when\n * \t\t// the plugin is destroyed.\n * \t\tthis.listenTo( this.editor.data, 'ready', () => {\n * \t\t\t// Do something when the data is ready.\n * \t\t} );\n * \t}\n * }\n * ```\n */\nexport type PluginClassConstructor<TContext = Editor> = new ( editor: TContext ) => PluginInterface;\n\n/**\n * In its minimal form a plugin can be a simple function that accepts {@link module:core/editor/editor~Editor the editor}\n * as a parameter:\n *\n * ```ts\n * // A simple plugin that enables a data processor.\n * function MyPlugin( editor ) {\n * \teditor.data.processor = new MyDataProcessor();\n * }\n * ```\n */\nexport type PluginFunctionConstructor<TContext = Editor> = ( editor: TContext ) => void;\n\n/**\n * Static properties of a plugin.\n */\nexport interface PluginStaticMembers<TContext = Editor> {\n\n\t/**\n\t * An array of plugins required by this plugin.\n\t *\n\t * To keep the plugin class definition tight it is recommended to define this property as a static getter:\n\t *\n\t * ```ts\n\t * import Image from './image.js';\n\t *\n\t * export default class ImageCaption {\n\t * \tstatic get requires() {\n\t * \t\treturn [ Image ];\n\t * \t}\n\t * }\n\t * ```\n\t */\n\treadonly requires?: PluginDependencies<TContext>;\n\n\t/**\n\t * An optional name of the plugin. If set, the plugin will be available in\n\t * {@link module:core/plugincollection~PluginCollection#get} by its\n\t * name and its constructor. If not, then only by its constructor.\n\t *\n\t * The name should reflect the constructor name.\n\t *\n\t * To keep the plugin class definition tight, it is recommended to define this property as a static getter:\n\t *\n\t * ```ts\n\t * export default class ImageCaption {\n\t * \tstatic get pluginName() {\n\t * \t\treturn 'ImageCaption';\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * Note: The native `Function.name` property could not be used to keep the plugin name because\n\t * it will be mangled during code minification.\n\t *\n\t * Naming a plugin is necessary to enable removing it through the\n\t * {@link module:core/editor/editorconfig~EditorConfig#removePlugins `config.removePlugins`} option.\n\t */\n\treadonly pluginName?: string;\n\n\t/**\n\t * A flag which defines if a plugin is allowed or not allowed to be used directly by a {@link module:core/context~Context}.\n\t */\n\treadonly isContextPlugin?: boolean;\n\n\t/**\n\t * A flag which defines if a plugin is an official CKEditor 5 plugin.\n\t */\n\treadonly isOfficialPlugin?: boolean;\n\n\t/**\n\t * A flag which defines if a plugin is a premium CKEditor 5 plugin.\n\t */\n\treadonly isPremiumPlugin?: boolean;\n}\n\nexport type PluginDependencies<TContext = Editor> = ReadonlyArray<PluginConstructor<TContext> | string>;\n\n/**\n * An array of loaded plugins.\n */\nexport type LoadedPlugins = Array<PluginInterface>;\n\n/**\n * Helper function that forces plugin to be disabled.\n */\nfunction forceDisable( evt: EventInfo<string, boolean> ) {\n\tevt.return = false;\n\tevt.stop();\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/command\n */\n\nimport {\n\tObservableMixin,\n\ttype EventInfo,\n\ttype ObservableChangeEvent,\n\ttype DecoratedMethodEvent,\n\ttype ObservableSetEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport type Editor from './editor/editor.js';\n\n/**\n * Base class for the CKEditor commands.\n *\n * Commands are the main way to manipulate the editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of the code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default, commands are disabled when the editor is in the {@link module:core/editor/editor~Editor#isReadOnly read-only} mode\n * but commands with the {@link module:core/command~Command#affectsData `affectsData`} flag set to `false` will not be disabled.\n */\nexport default class Command extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * The editor on which this command will be used.\n\t */\n\tpublic readonly editor: Editor;\n\n\t/**\n\t * The value of the command. A given command class should define what it represents for it.\n\t *\n\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t * And the value of the `'link'` command may be an object with link details.\n\t *\n\t * It is possible for a command to have no value (e.g. for stateless actions such as `'uploadImage'`).\n\t *\n\t * A given command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public value: unknown;\n\n\t/**\n\t * Flag indicating whether a command is enabled or disabled.\n\t * A disabled command will do nothing when executed.\n\t *\n\t * A given command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t *\n\t * It is possible to disable a command \"from outside\" using {@link #forceDisabled} method.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * A flag indicating whether a command's `isEnabled` state should be changed depending on where the document\n\t * selection is placed.\n\t *\n\t * By default, it is set to `true`. If the document selection is placed in a\n\t * {@link module:engine/model/model~Model#canEditAt non-editable} place (such as non-editable root), the command becomes disabled.\n\t *\n\t * The flag should be changed to `false` in a concrete command's constructor if the command should not change its `isEnabled`\n\t * accordingly to the document selection.\n\t */\n\tprotected _isEnabledBasedOnSelection: boolean;\n\n\t/**\n\t * A flag indicating whether a command execution changes the editor data or not.\n\t *\n\t * @see #affectsData\n\t */\n\tprivate _affectsData: boolean;\n\n\t/**\n\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t */\n\tprivate readonly _disableStack: Set<string>;\n\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper();\n\n\t\tthis.editor = editor;\n\t\tthis.set( 'value', undefined );\n\t\tthis.set( 'isEnabled', false );\n\n\t\tthis._affectsData = true;\n\t\tthis._isEnabledBasedOnSelection = true;\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default, every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.listenTo<ObservableChangeEvent<boolean>>( editor, 'change:isReadOnly', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\t// By default, commands are disabled if the selection is in non-editable place or editor is in read-only mode.\n\t\tthis.on<ObservableSetEvent<boolean>>( 'set:isEnabled', evt => {\n\t\t\tif ( !this.affectsData ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selection = editor.model.document.selection;\n\t\t\tconst selectionInGraveyard = selection.getFirstPosition()!.root.rootName == '$graveyard';\n\t\t\tconst canEditAtSelection = !selectionInGraveyard && editor.model.canEditAt( selection );\n\n\t\t\t// Disable if editor is read only, or when selection is in a place which cannot be edited.\n\t\t\t//\n\t\t\t// Checking `editor.isReadOnly` is needed for all commands that have `_isEnabledBasedOnSelection == false`.\n\t\t\t// E.g. undo does not base on selection, but affects data and should be disabled when the editor is in read-only mode.\n\t\t\tif ( editor.isReadOnly || this._isEnabledBasedOnSelection && !canEditAtSelection ) {\n\t\t\t\tevt.return = false;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.on<CommandExecuteEvent>( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * A flag indicating whether a command execution changes the editor data or not.\n\t *\n\t * Commands with `affectsData` set to `false` will not be automatically disabled in\n\t * the {@link module:core/editor/editor~Editor#isReadOnly read-only mode} and\n\t * {@glink features/read-only#related-features other editor modes} with restricted user write permissions.\n\t *\n\t * **Note:** You do not have to set it for your every command. It is `true` by default.\n\t *\n\t * @default true\n\t */\n\tpublic get affectsData(): boolean {\n\t\treturn this._affectsData;\n\t}\n\n\tprotected set affectsData( affectsData: boolean ) {\n\t\tthis._affectsData = affectsData;\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\tpublic refresh(): void {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. the feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t * ```ts\n\t * command.isEnabled; // -> true\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> false\n\t * command.clearForceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> true\n\t * ```\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t * ```ts\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.forceDisabled( 'OtherFeature' );\n\t * command.clearForceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> false\n\t * command.clearForceDisabled( 'OtherFeature' );\n\t * command.isEnabled; // -> true\n\t * ```\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t * ```ts\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.forceDisabled( 'MyFeature' );\n\t * command.clearForceDisabled( 'MyFeature' );\n\t * command.isEnabled; // -> true\n\t * ```\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tpublic forceDisabled( id: string ): void {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on<ObservableSetEvent<boolean>>( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}.\n\t *\n\t * @param id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tpublic clearForceDisabled( id: string ): void {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * This method may return a value, which would be forwarded all the way down to the\n\t * {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n\t *\n\t * @fires execute\n\t */\n\tpublic execute( ...args: Array<unknown> ): unknown { return undefined; } // eslint-disable-line @typescript-eslint/no-unused-vars\n\n\t/**\n\t * Destroys the command.\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\t}\n}\n\n/**\n * Helper function that forces command to be disabled.\n */\nfunction forceDisable( evt: EventInfo<string, boolean> ) {\n\tevt.return = false;\n\tevt.stop();\n}\n\n/**\n * Event fired by the {@link module:core/command~Command#execute} method. The command action is a listener to this event so it's\n * possible to change/cancel the behavior of the command by listening to this event.\n *\n * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.\n *\n * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n * by a high priority listener in order to prevent command execution.\n *\n * @eventName ~Command#execute\n */\nexport type CommandExecuteEvent = DecoratedMethodEvent<Command, 'execute'>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/multicommand\n */\n\nimport Command from './command.js';\n\nimport {\n\tinsertToPriorityArray,\n\ttype PriorityString,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\n/**\n * A CKEditor command that aggregates other commands.\n *\n * This command is used to proxy multiple commands. The multi-command is enabled when\n * at least one of its registered child commands is enabled.\n * When executing a multi-command, the first enabled command with highest priority will be executed.\n *\n * ```ts\n * const multiCommand = new MultiCommand( editor );\n *\n * const commandFoo = new Command( editor );\n * const commandBar = new Command( editor );\n *\n * // Register a child command.\n * multiCommand.registerChildCommand( commandFoo );\n * // Register a child command with a low priority.\n * multiCommand.registerChildCommand( commandBar, { priority: 'low' } );\n *\n * // Enable one of the commands.\n * commandBar.isEnabled = true;\n *\n * multiCommand.execute(); // Will execute commandBar.\n * ```\n */\nexport default class MultiCommand extends Command {\n\t/**\n\t * Registered child commands definitions.\n\t */\n\tprivate _childCommandsDefinitions: Array<{ command: Command; priority: PriorityString }> = [];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\t// Override base command refresh(): the command's state is changed when one of child commands changes states.\n\t}\n\n\t/**\n\t * Executes the first enabled command which has the highest priority of all registered child commands.\n\t *\n\t * @returns The value returned by the {@link module:core/command~Command#execute `command.execute()`}.\n\t */\n\tpublic override execute( ...args: Array<unknown> ): unknown {\n\t\tconst command = this._getFirstEnabledCommand();\n\n\t\treturn !!command && command.execute( args );\n\t}\n\n\t/**\n\t * Registers a child command.\n\t *\n\t * @param options An object with configuration options.\n\t * @param options.priority Priority of a command to register.\n\t */\n\tpublic registerChildCommand(\n\t\tcommand: Command,\n\t\toptions: { priority?: PriorityString } = {}\n\t): void {\n\t\tinsertToPriorityArray( this._childCommandsDefinitions, { command, priority: options.priority || 'normal' } );\n\n\t\t// Change multi-command enabled state when one of registered commands changes state.\n\t\tcommand.on<ObservableChangeEvent<boolean>>( 'change:isEnabled', () => this._checkEnabled() );\n\n\t\tthis._checkEnabled();\n\t}\n\n\t/**\n\t * Checks if any of child commands is enabled.\n\t */\n\tprivate _checkEnabled(): void {\n\t\tthis.isEnabled = !!this._getFirstEnabledCommand();\n\t}\n\n\t/**\n\t * Returns a first enabled command with the highest priority or `undefined` if none of them is enabled.\n\t */\n\tprivate _getFirstEnabledCommand(): Command | undefined {\n\t\tconst commandDefinition = this._childCommandsDefinitions.find( ( { command } ) => command.isEnabled );\n\n\t\treturn commandDefinition && commandDefinition.command;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/plugincollection\n */\n\nimport { CKEditorError, EmitterMixin } from '@ckeditor/ckeditor5-utils';\nimport type { LoadedPlugins, PluginClassConstructor, PluginConstructor, PluginInterface } from './plugin.js';\n\n/**\n * Manages a list of CKEditor plugins, including loading, resolving dependencies and initialization.\n */\nexport default class PluginCollection<TContext extends object>\n\textends /* #__PURE__ */ EmitterMixin()\n\timplements Iterable<PluginEntry<TContext>> {\n\tprivate _context: TContext;\n\n\tprivate _plugins = new Map<PluginConstructor<TContext> | string, PluginInterface>();\n\n\t/**\n\t * A map of plugin constructors that can be retrieved by their names.\n\t */\n\tprivate _availablePlugins: Map<string, PluginConstructor<TContext>>;\n\n\t/**\n\t * Map of {@link module:core/contextplugin~ContextPlugin context plugins} which can be retrieved by their constructors or instances.\n\t */\n\tprivate _contextPlugins: Map<PluginConstructor<TContext> | PluginInterface, PluginConstructor<TContext> | PluginInterface>;\n\n\t/**\n\t * Creates an instance of the plugin collection class.\n\t * Allows loading and initializing plugins and their dependencies.\n\t * Allows providing a list of already loaded plugins. These plugins will not be destroyed along with this collection.\n\t *\n\t * @param availablePlugins Plugins (constructors) which the collection will be able to use\n\t * when {@link module:core/plugincollection~PluginCollection#init} is used with the plugin names (strings, instead of constructors).\n\t * Usually, the editor will pass its built-in plugins to the collection so they can later be\n\t * used in `config.plugins` or `config.removePlugins` by names.\n\t * @param contextPlugins A list of already initialized plugins represented by a `[ PluginConstructor, pluginInstance ]` pair.\n\t */\n\tconstructor(\n\t\tcontext: TContext,\n\t\tavailablePlugins: Iterable<PluginConstructor<TContext>> = [],\n\t\tcontextPlugins: Iterable<PluginEntry<TContext>> = []\n\t) {\n\t\tsuper();\n\n\t\tthis._context = context;\n\t\tthis._availablePlugins = new Map();\n\n\t\tfor ( const PluginConstructor of availablePlugins ) {\n\t\t\tif ( PluginConstructor.pluginName ) {\n\t\t\t\tthis._availablePlugins.set( PluginConstructor.pluginName, PluginConstructor );\n\t\t\t}\n\t\t}\n\n\t\tthis._contextPlugins = new Map();\n\n\t\tfor ( const [ PluginConstructor, pluginInstance ] of contextPlugins ) {\n\t\t\tthis._contextPlugins.set( PluginConstructor, pluginInstance );\n\t\t\tthis._contextPlugins.set( pluginInstance, PluginConstructor );\n\n\t\t\t// To make it possible to require a plugin by its name.\n\t\t\tif ( PluginConstructor.pluginName ) {\n\t\t\t\tthis._availablePlugins.set( PluginConstructor.pluginName, PluginConstructor );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Returns `[ PluginConstructor, pluginInstance ]` pairs.\n\t */\n\tpublic* [ Symbol.iterator ](): IterableIterator<PluginEntry<TContext>> {\n\t\tfor ( const entry of this._plugins ) {\n\t\t\tif ( typeof entry[ 0 ] == 'function' ) {\n\t\t\t\tyield entry as any;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic get<TConstructor extends PluginClassConstructor<TContext>>( key: TConstructor ): InstanceType<TConstructor>;\n\tpublic get<TName extends string>( key: TName ): PluginsMap[ TName ];\n\n\t/**\n\t * Gets the plugin instance by its constructor or name.\n\t *\n\t * ```ts\n\t * // Check if 'Clipboard' plugin was loaded.\n\t * if ( editor.plugins.has( 'ClipboardPipeline' ) ) {\n\t * \t// Get clipboard plugin instance\n\t * \tconst clipboard = editor.plugins.get( 'ClipboardPipeline' );\n\t *\n\t * \tthis.listenTo( clipboard, 'inputTransformation', ( evt, data ) => {\n\t * \t\t// Do something on clipboard input.\n\t * \t} );\n\t * }\n\t * ```\n\t *\n\t * **Note**: This method will throw an error if a plugin is not loaded. Use `{@link #has editor.plugins.has()}`\n\t * to check if a plugin is available.\n\t *\n\t * @param key The plugin constructor or {@link module:core/plugin~PluginStaticMembers#pluginName name}.\n\t */\n\tpublic get( key: PluginConstructor<TContext> | string ): PluginInterface {\n\t\tconst plugin = this._plugins.get( key );\n\n\t\tif ( !plugin ) {\n\t\t\tlet pluginName = key;\n\n\t\t\tif ( typeof key == 'function' ) {\n\t\t\t\tpluginName = key.pluginName || key.name;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * The plugin is not loaded and could not be obtained.\n\t\t\t *\n\t\t\t * Plugin classes (constructors) need to be provided to the editor and must be loaded before they can be obtained from\n\t\t\t * the plugin collection.\n\t\t\t *\n\t\t\t * **Note**: You can use `{@link module:core/plugincollection~PluginCollection#has editor.plugins.has()}`\n\t\t\t * to check if a plugin was loaded.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-not-loaded\n\t\t\t * @param plugin The name of the plugin which is not loaded.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'plugincollection-plugin-not-loaded', this._context, { plugin: pluginName } );\n\t\t}\n\n\t\treturn plugin;\n\t}\n\n\t/**\n\t * Checks if a plugin is loaded.\n\t *\n\t * ```ts\n\t * // Check if the 'Clipboard' plugin was loaded.\n\t * if ( editor.plugins.has( 'ClipboardPipeline' ) ) {\n\t * \t// Now use the clipboard plugin instance:\n\t * \tconst clipboard = editor.plugins.get( 'ClipboardPipeline' );\n\t *\n\t * \t// ...\n\t * }\n\t * ```\n\t *\n\t * @param key The plugin constructor or {@link module:core/plugin~PluginStaticMembers#pluginName name}.\n\t */\n\tpublic has( key: PluginConstructor<TContext> | string ): boolean {\n\t\treturn this._plugins.has( key );\n\t}\n\n\t/**\n\t * Initializes a set of plugins and adds them to the collection.\n\t *\n\t * @param plugins An array of {@link module:core/plugin~PluginInterface plugin constructors}\n\t * or {@link module:core/plugin~PluginStaticMembers#pluginName plugin names}.\n\t * @param pluginsToRemove Names of the plugins or plugin constructors\n\t * that should not be loaded (despite being specified in the `plugins` array).\n\t * @param pluginsSubstitutions An array of {@link module:core/plugin~PluginInterface plugin constructors}\n\t * that will be used to replace plugins of the same names that were passed in `plugins` or that are in their dependency tree.\n\t * A useful option for replacing built-in plugins while creating tests (for mocking their APIs). Plugins that will be replaced\n\t * must follow these rules:\n\t *   * The new plugin must be a class.\n\t *   * The new plugin must be named.\n\t *   * Both plugins must not depend on other plugins.\n\t * @returns A promise which gets resolved once all plugins are loaded and available in the collection.\n\t */\n\tpublic init(\n\t\tplugins: ReadonlyArray<PluginConstructor<TContext> | string>,\n\t\tpluginsToRemove: ReadonlyArray<PluginConstructor<TContext> | string> = [],\n\t\tpluginsSubstitutions: ReadonlyArray<PluginConstructor<TContext>> = []\n\t): Promise<LoadedPlugins> {\n\t\t// Plugin initialization procedure consists of 2 main steps:\n\t\t// 1) collecting all available plugin constructors,\n\t\t// 2) verification whether all required plugins can be instantiated.\n\t\t//\n\t\t// In the first step, all plugin constructors, available in the provided `plugins` array and inside\n\t\t// plugin's dependencies (from the `Plugin.requires` array), are recursively collected and added to the existing\n\t\t// `this._availablePlugins` map, but without any verification at the given moment. Performing the verification\n\t\t// at this point (during the plugin constructor searching) would cause false errors to occur, that some plugin\n\t\t// is missing but in fact it may be defined further in the array as the dependency of other plugin. After\n\t\t// traversing the entire dependency tree, it will be checked if all required \"top level\" plugins are available.\n\t\t//\n\t\t// In the second step, the list of plugins that have not been explicitly removed is traversed to get all the\n\t\t// plugin constructors to be instantiated in the correct order and to validate against some rules. Finally, if\n\t\t// no plugin is missing and no other error has been found, they all will be instantiated.\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst that = this;\n\t\tconst context = this._context;\n\n\t\tfindAvailablePluginConstructors( plugins );\n\n\t\tvalidatePlugins( plugins );\n\n\t\tconst pluginsToLoad = plugins.filter( plugin => !isPluginRemoved( plugin, pluginsToRemove ) );\n\n\t\tconst pluginConstructors = [ ...getPluginConstructors( pluginsToLoad ) ];\n\n\t\tsubstitutePlugins( pluginConstructors, pluginsSubstitutions );\n\n\t\tconst pluginInstances = loadPlugins( pluginConstructors );\n\n\t\treturn initPlugins( pluginInstances, 'init' )\n\t\t\t.then( () => initPlugins( pluginInstances, 'afterInit' ) )\n\t\t\t.then( () => pluginInstances );\n\n\t\tfunction isPluginConstructor( plugin: PluginConstructor<TContext> | string | null ): plugin is PluginConstructor<TContext> {\n\t\t\treturn typeof plugin === 'function';\n\t\t}\n\n\t\tfunction isContextPlugin(\n\t\t\tplugin: PluginConstructor<TContext> | string | null\n\t\t): plugin is PluginConstructor<TContext> & { isContextPlugin: true } {\n\t\t\treturn isPluginConstructor( plugin ) && !!plugin.isContextPlugin;\n\t\t}\n\n\t\tfunction isPluginRemoved(\n\t\t\tplugin: PluginConstructor<TContext> | string,\n\t\t\tpluginsToRemove: ReadonlyArray<PluginConstructor<TContext> | string>\n\t\t) {\n\t\t\treturn pluginsToRemove.some( removedPlugin => {\n\t\t\t\tif ( removedPlugin === plugin ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tif ( getPluginName( plugin ) === removedPlugin ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tif ( getPluginName( removedPlugin ) === plugin ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t} );\n\t\t}\n\n\t\tfunction getPluginName( plugin: PluginConstructor<TContext> | string ) {\n\t\t\treturn isPluginConstructor( plugin ) ?\n\t\t\t\tplugin.pluginName || plugin.name :\n\t\t\t\tplugin;\n\t\t}\n\n\t\tfunction findAvailablePluginConstructors(\n\t\t\tplugins: ReadonlyArray<PluginConstructor<TContext> | string>,\n\t\t\tprocessed = new Set<PluginConstructor<TContext>>()\n\t\t) {\n\t\t\tplugins.forEach( plugin => {\n\t\t\t\tif ( !isPluginConstructor( plugin ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( processed.has( plugin ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tprocessed.add( plugin );\n\n\t\t\t\tif ( plugin.pluginName && !that._availablePlugins.has( plugin.pluginName ) ) {\n\t\t\t\t\tthat._availablePlugins.set( plugin.pluginName, plugin );\n\t\t\t\t}\n\n\t\t\t\tif ( plugin.requires ) {\n\t\t\t\t\tfindAvailablePluginConstructors( plugin.requires, processed );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tfunction getPluginConstructors(\n\t\t\tplugins: ReadonlyArray<PluginConstructor<TContext> | string>,\n\t\t\tprocessed = new Set<PluginConstructor<TContext>>()\n\t\t) {\n\t\t\treturn plugins\n\t\t\t\t.map( plugin => {\n\t\t\t\t\treturn isPluginConstructor( plugin ) ?\n\t\t\t\t\t\tplugin :\n\t\t\t\t\t\tthat._availablePlugins.get( plugin )!;\n\t\t\t\t} )\n\t\t\t\t.reduce( ( result, plugin ) => {\n\t\t\t\t\tif ( processed.has( plugin ) ) {\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\n\t\t\t\t\tprocessed.add( plugin );\n\n\t\t\t\t\tif ( plugin.requires ) {\n\t\t\t\t\t\tvalidatePlugins( plugin.requires, plugin );\n\n\t\t\t\t\t\tgetPluginConstructors( plugin.requires, processed ).forEach( plugin => result.add( plugin ) );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn result.add( plugin );\n\t\t\t\t}, new Set<PluginConstructor<TContext>>() );\n\t\t}\n\n\t\tfunction validatePlugins(\n\t\t\tplugins: ReadonlyArray<PluginConstructor<TContext> | string>,\n\t\t\tparentPluginConstructor: PluginConstructor<TContext> | null = null\n\t\t) {\n\t\t\tplugins\n\t\t\t\t.map( plugin => {\n\t\t\t\t\treturn isPluginConstructor( plugin ) ?\n\t\t\t\t\t\tplugin :\n\t\t\t\t\t\tthat._availablePlugins.get( plugin ) || plugin;\n\t\t\t\t} )\n\t\t\t\t.forEach( plugin => {\n\t\t\t\t\tcheckMissingPlugin( plugin, parentPluginConstructor );\n\t\t\t\t\tcheckContextPlugin( plugin, parentPluginConstructor );\n\t\t\t\t\tcheckRemovedPlugin( plugin, parentPluginConstructor );\n\t\t\t\t} );\n\t\t}\n\n\t\tfunction checkMissingPlugin(\n\t\t\tplugin: PluginConstructor<TContext> | string,\n\t\t\tparentPluginConstructor: PluginConstructor<TContext> | null\n\t\t) {\n\t\t\tif ( isPluginConstructor( plugin ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( parentPluginConstructor ) {\n\t\t\t\t/**\n\t\t\t\t * A required \"soft\" dependency was not found on the plugin list.\n\t\t\t\t *\n\t\t\t\t * When configuring the editor, either prior to building (via\n\t\t\t\t * {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}) or when\n\t\t\t\t * creating a new instance of the editor (e.g. via\n\t\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#plugins `config.plugins`}), you need to provide\n\t\t\t\t * some of the dependencies for other plugins that you used.\n\t\t\t\t *\n\t\t\t\t * This error is thrown when one of these dependencies was not provided. The name of the missing plugin\n\t\t\t\t * can be found in `missingPlugin` and the plugin that required it in `requiredBy`.\n\t\t\t\t *\n\t\t\t\t * In order to resolve it, you need to import the missing plugin and add it to the\n\t\t\t\t * current list of plugins (`Editor.builtinPlugins` or `config.plugins`/`config.extraPlugins`).\n\t\t\t\t *\n\t\t\t\t * Soft requirements were introduced in version 26.0.0. If you happen to stumble upon this error\n\t\t\t\t * when upgrading to version 26.0.0, read also the\n\t\t\t\t * {@glink updating/guides/update-to-26 Migration to 26.0.0} guide.\n\t\t\t\t *\n\t\t\t\t * @error plugincollection-soft-required\n\t\t\t\t * @param missingPlugin The name of the required plugin.\n\t\t\t\t * @param requiredBy The name of the plugin that requires the other plugin.\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'plugincollection-soft-required',\n\t\t\t\t\tcontext,\n\t\t\t\t\t{ missingPlugin: plugin, requiredBy: getPluginName( parentPluginConstructor ) }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * A plugin is not available and could not be loaded.\n\t\t\t *\n\t\t\t * Plugin classes (constructors) need to be provided to the editor before they can be loaded by name.\n\t\t\t * This is usually done in CKEditor 5 builds by setting the {@link module:core/editor/editor~Editor.builtinPlugins}\n\t\t\t * property.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the CKEditor 5 Builds},\n\t\t\t * it means that you try to enable a plugin which was not included in that build. This may be due to a typo\n\t\t\t * in the plugin name or simply because that plugin is not a part of this build.\n\t\t\t *\n\t\t\t * Predefined builds are a deprecated solution and we strongly advise\n\t\t\t * {@glink updating/nim-migration/migration-to-new-installation-methods migrating to new installation methods}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the editor creators directly** (not a build), then it means\n\t\t\t * that you tried loading plugins by name. However, unlike CKEditor 4, CKEditor 5 does not implement a \"plugin loader\".\n\t\t\t * This means that CKEditor 5 does not know where to load the plugin modules from. Therefore, you need to\n\t\t\t * provide each plugin through a reference (as a constructor function). Check out the examples in the\n\t\t\t * {@glink getting-started/installation/quick-start Quick start} guide.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-not-found\n\t\t\t * @param plugin The name of the plugin which could not be loaded.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'plugincollection-plugin-not-found',\n\t\t\t\tcontext,\n\t\t\t\t{ plugin }\n\t\t\t);\n\t\t}\n\n\t\tfunction checkContextPlugin(\n\t\t\tplugin: PluginConstructor<TContext> | string,\n\t\t\tparentPluginConstructor: PluginConstructor<TContext> | null\n\t\t) {\n\t\t\tif ( !isContextPlugin( parentPluginConstructor ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isContextPlugin( plugin ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * If a plugin is a context plugin, all plugins it requires should also be context plugins\n\t\t\t * instead of plugins. In other words, if one plugin can be used in the context,\n\t\t\t * all its requirements should also be ready to be used in the context. Note that the context\n\t\t\t * provides only a part of the API provided by the editor. If one plugin needs a full\n\t\t\t * editor API, all plugins which require it are considered as plugins that need a full\n\t\t\t * editor API.\n\t\t\t *\n\t\t\t * @error plugincollection-context-required\n\t\t\t * @param plugin The name of the required plugin.\n\t\t\t * @param requiredBy The name of the parent plugin.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'plugincollection-context-required',\n\t\t\t\tcontext,\n\t\t\t\t{ plugin: getPluginName( plugin ), requiredBy: getPluginName( parentPluginConstructor ) }\n\t\t\t);\n\t\t}\n\n\t\tfunction checkRemovedPlugin(\n\t\t\tplugin: PluginConstructor<TContext> | string,\n\t\t\tparentPluginConstructor: PluginConstructor<TContext> | null\n\t\t) {\n\t\t\tif ( !parentPluginConstructor ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !isPluginRemoved( plugin, pluginsToRemove ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Cannot load a plugin because one of its dependencies is listed in the `removePlugins` option.\n\t\t\t *\n\t\t\t * @error plugincollection-required\n\t\t\t * @param plugin The name of the required plugin.\n\t\t\t * @param requiredBy The name of the parent plugin.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'plugincollection-required',\n\t\t\t\tcontext,\n\t\t\t\t{ plugin: getPluginName( plugin ), requiredBy: getPluginName( parentPluginConstructor ) }\n\t\t\t);\n\t\t}\n\n\t\tfunction loadPlugins( pluginConstructors: ReadonlyArray<PluginConstructor<TContext>> ) {\n\t\t\treturn pluginConstructors.map( PluginConstructor => {\n\t\t\t\tlet pluginInstance = that._contextPlugins.get( PluginConstructor ) as ( PluginInterface | undefined );\n\n\t\t\t\tpluginInstance = pluginInstance || new ( PluginConstructor as PluginClassConstructor<TContext> )( context );\n\n\t\t\t\tthat._add( PluginConstructor, pluginInstance );\n\n\t\t\t\treturn pluginInstance;\n\t\t\t} );\n\t\t}\n\n\t\tfunction initPlugins( pluginInstances: ReadonlyArray<PluginInterface>, method: 'init' | 'afterInit' ) {\n\t\t\treturn pluginInstances.reduce<Promise<unknown>>( ( promise, plugin ) => {\n\t\t\t\tif ( !plugin[ method ] ) {\n\t\t\t\t\treturn promise;\n\t\t\t\t}\n\n\t\t\t\tif ( that._contextPlugins.has( plugin ) ) {\n\t\t\t\t\treturn promise;\n\t\t\t\t}\n\n\t\t\t\treturn promise.then( plugin[ method ]!.bind( plugin ) );\n\t\t\t}, Promise.resolve() );\n\t\t}\n\n\t\t/**\n\t\t * Replaces plugin constructors with the specified set of plugins.\n\t\t */\n\t\tfunction substitutePlugins(\n\t\t\tpluginConstructors: Array<PluginConstructor<TContext>>,\n\t\t\tpluginsSubstitutions: ReadonlyArray<PluginConstructor<TContext>>\n\t\t) {\n\t\t\tfor ( const pluginItem of pluginsSubstitutions ) {\n\t\t\t\tif ( typeof pluginItem != 'function' ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The plugin replacing an existing plugin must be a function.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-replace-plugin-invalid-type\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'plugincollection-replace-plugin-invalid-type', null, { pluginItem } );\n\t\t\t\t}\n\n\t\t\t\tconst pluginName = pluginItem.pluginName;\n\n\t\t\t\tif ( !pluginName ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The plugin replacing an existing plugin must have a name.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-replace-plugin-missing-name\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'plugincollection-replace-plugin-missing-name', null, { pluginItem } );\n\t\t\t\t}\n\n\t\t\t\tif ( pluginItem.requires && pluginItem.requires.length ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The plugin replacing an existing plugin cannot depend on other plugins.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-plugin-for-replacing-cannot-have-dependencies\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'plugincollection-plugin-for-replacing-cannot-have-dependencies', null, { pluginName } );\n\t\t\t\t}\n\n\t\t\t\tconst pluginToReplace = that._availablePlugins.get( pluginName );\n\n\t\t\t\tif ( !pluginToReplace ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The replaced plugin does not exist in the\n\t\t\t\t\t * {@link module:core/plugincollection~PluginCollection available plugins} collection.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-plugin-for-replacing-not-exist\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'plugincollection-plugin-for-replacing-not-exist', null, { pluginName } );\n\t\t\t\t}\n\n\t\t\t\tconst indexInPluginConstructors = pluginConstructors.indexOf( pluginToReplace );\n\n\t\t\t\tif ( indexInPluginConstructors === -1 ) {\n\t\t\t\t\t// The Context feature can substitute plugins as well.\n\t\t\t\t\t// It may happen that the editor will be created with the given context, where the plugin for substitute\n\t\t\t\t\t// was already replaced. In such a case, we don't want to do it again.\n\t\t\t\t\tif ( that._contextPlugins.has( pluginToReplace ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * The replaced plugin will not be loaded so it cannot be replaced.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-plugin-for-replacing-not-loaded\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'plugincollection-plugin-for-replacing-not-loaded', null, { pluginName } );\n\t\t\t\t}\n\n\t\t\t\tif ( pluginToReplace.requires && pluginToReplace.requires.length ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The replaced plugin cannot depend on other plugins.\n\t\t\t\t\t *\n\t\t\t\t\t * @error plugincollection-replaced-plugin-cannot-have-dependencies\n\t\t\t\t\t */\n\t\t\t\t\tthrow new CKEditorError( 'plugincollection-replaced-plugin-cannot-have-dependencies', null, { pluginName } );\n\t\t\t\t}\n\n\t\t\t\tpluginConstructors.splice( indexInPluginConstructors, 1, pluginItem );\n\t\t\t\tthat._availablePlugins.set( pluginName, pluginItem );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Destroys all loaded plugins.\n\t */\n\tpublic destroy(): Promise<unknown> {\n\t\tconst promises: Array<unknown> = [];\n\n\t\tfor ( const [ , pluginInstance ] of this ) {\n\t\t\tif ( typeof pluginInstance.destroy == 'function' && !this._contextPlugins.has( pluginInstance ) ) {\n\t\t\t\tpromises.push( pluginInstance.destroy() );\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.all( promises );\n\t}\n\n\t/**\n\t * Adds the plugin to the collection. Exposed mainly for testing purposes.\n\t *\n\t * @param PluginConstructor The plugin constructor.\n\t * @param plugin The instance of the plugin.\n\t */\n\tprivate _add( PluginConstructor: PluginConstructor<TContext>, plugin: PluginInterface ) {\n\t\tthis._plugins.set( PluginConstructor, plugin );\n\n\t\tconst pluginName = PluginConstructor.pluginName;\n\n\t\tif ( !pluginName ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this._plugins.has( pluginName ) ) {\n\t\t\t/**\n\t\t\t * Two plugins with the same {@link module:core/plugin~PluginStaticMembers#pluginName} were loaded.\n\t\t\t * This will lead to runtime conflicts between these plugins.\n\t\t\t *\n\t\t\t * In practice, this warning usually means that new plugins were added to an existing CKEditor 5 build.\n\t\t\t * Plugins should always be added to a source version of the editor (`@ckeditor/ckeditor5-editor-*`),\n\t\t\t * not to an editor imported from one of the `@ckeditor/ckeditor5-build-*` packages.\n\t\t\t *\n\t\t\t * Check your import paths and the list of plugins passed to\n\t\t\t * {@link module:core/editor/editor~Editor.create `Editor.create()`}\n\t\t\t * or specified in {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}.\n\t\t\t *\n\t\t\t * Predefined builds are a deprecated solution and we strongly advise\n\t\t\t * {@glink updating/nim-migration/migration-to-new-installation-methods migrating to new installation methods}.\n\t\t\t *\n\t\t\t * The second option is that your `node_modules/` directory contains duplicated versions of the same\n\t\t\t * CKEditor 5 packages. Normally, on clean installations, npm deduplicates packages in `node_modules/`, so\n\t\t\t * it may be enough to call `rm -rf node_modules && npm i`. However, if you installed conflicting versions\n\t\t\t * of some packages, their dependencies may need to be installed in more than one version which may lead to this\n\t\t\t * warning.\n\t\t\t *\n\t\t\t * Technically speaking, this error occurs because after adding a plugin to an existing editor build\n\t\t\t * the dependencies of this plugin are being duplicated.\n\t\t\t * They are already built into that editor build and now get added for the second time as dependencies\n\t\t\t * of the plugin you are installing.\n\t\t\t *\n\t\t\t * @error plugincollection-plugin-name-conflict\n\t\t\t * @param pluginName The duplicated plugin name.\n\t\t\t * @param plugin1 The first plugin constructor.\n\t\t\t * @param plugin2 The second plugin constructor.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'plugincollection-plugin-name-conflict',\n\t\t\t\tnull,\n\t\t\t\t{ pluginName, plugin1: this._plugins.get( pluginName )!.constructor, plugin2: PluginConstructor }\n\t\t\t);\n\t\t}\n\n\t\tthis._plugins.set( pluginName, plugin );\n\t}\n}\n\n/**\n * A `[ PluginConstructor, pluginInstance ]` pair.\n */\nexport type PluginEntry<TContext> = [ PluginConstructor<TContext>, PluginInterface ];\n\n/**\n * Helper type that maps plugin names to their types.\n * It is meant to be extended with module augmentation.\n *\n * ```ts\n * class MyPlugin extends Plugin {\n * \tpublic static pluginName() {\n * \t\treturn 'MyPlugin' as const;\n * \t}\n * }\n *\n * declare module '@ckeditor/ckeditor5-core' {\n * \tinterface PluginsMap {\n * \t\t[ MyPlugin.pluginName ]: MyPlugin;\n * \t}\n * }\n *\n * // Returns `MyPlugin`.\n * const myPlugin = editor.plugins.get( 'MyPlugin' );\n * ```\n */\nexport interface PluginsMap {\n\t[ name: string ]: PluginInterface;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/context\n */\n\nimport {\n\tConfig,\n\tCollection,\n\tCKEditorError,\n\tLocale,\n\ttype LocaleTranslate\n} from '@ckeditor/ckeditor5-utils';\n\nimport PluginCollection from './plugincollection.js';\nimport type Editor from './editor/editor.js';\nimport type { LoadedPlugins, PluginConstructor } from './plugin.js';\nimport type { EditorConfig } from './editor/editorconfig.js';\n\n/**\n * Provides a common, higher-level environment for solutions that use multiple {@link module:core/editor/editor~Editor editors}\n * or plugins that work outside the editor. Use it instead of {@link module:core/editor/editor~Editor.create `Editor.create()`}\n * in advanced application integrations.\n *\n * All configuration options passed to a context will be used as default options for the editor instances initialized in that context.\n *\n * {@link module:core/contextplugin~ContextPlugin Context plugins} passed to a context instance will be shared among all\n * editor instances initialized in this context. These will be the same plugin instances for all the editors.\n *\n * **Note:** The context can only be initialized with {@link module:core/contextplugin~ContextPlugin context plugins}\n * (e.g. [comments](https://ckeditor.com/collaboration/comments/)). Regular {@link module:core/plugin~Plugin plugins} require an\n * editor instance to work and cannot be added to a context.\n *\n * **Note:** You can add a context plugin to an editor instance, though.\n *\n * If you are using multiple editor instances on one page and use any context plugins, create a context to share the configuration and\n * plugins among these editors. Some plugins will use the information about all existing editors to better integrate between them.\n *\n * If you are using plugins that do not require an editor to work (e.g. [comments](https://ckeditor.com/collaboration/comments/)),\n * enable and configure them using the context.\n *\n * If you are using only a single editor on each page, use {@link module:core/editor/editor~Editor.create `Editor.create()`} instead.\n * In such a case, a context instance will be created by the editor instance in a transparent way.\n *\n * See {@link ~Context.create `Context.create()`} for usage examples.\n */\nexport default class Context {\n\t/**\n\t * Stores all the configurations specific to this context instance.\n\t */\n\tpublic readonly config: Config<ContextConfig>;\n\n\t/**\n\t * The plugins loaded and in use by this context instance.\n\t */\n\tpublic readonly plugins: PluginCollection<Context | Editor>;\n\n\tpublic readonly locale: Locale;\n\n\t/**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t */\n\tpublic readonly t: LocaleTranslate;\n\n\t/**\n\t * A list of editors that this context instance is injected to.\n\t */\n\tpublic readonly editors: Collection<Editor>;\n\n\t/**\n\t * The default configuration which is built into the `Context` class.\n\t *\n\t * It is used in CKEditor 5 builds featuring `Context` to provide the default configuration options which are later used during the\n\t * context initialization.\n\t *\n\t * ```ts\n\t * Context.defaultConfig = {\n\t * \tfoo: 1,\n\t * \tbar: 2\n\t * };\n\t *\n\t * Context\n\t * \t.create()\n\t * \t.then( context => {\n\t * \t\tcontext.config.get( 'foo' ); // -> 1\n\t * \t\tcontext.config.get( 'bar' ); // -> 2\n\t * \t} );\n\t *\n\t * // The default options can be overridden by the configuration passed to create().\n\t * Context\n\t * \t.create( { bar: 3 } )\n\t * \t.then( context => {\n\t * \t\tcontext.config.get( 'foo' ); // -> 1\n\t * \t\tcontext.config.get( 'bar' ); // -> 3\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/context~Context.builtinPlugins `Context.builtinPlugins`}\n\t * and {@link module:core/editor/editor~Editor.defaultConfig `Editor.defaultConfig`}.\n\t */\n\tpublic static defaultConfig: ContextConfig;\n\n\t/**\n\t * An array of plugins built into the `Context` class.\n\t *\n\t * It is used in CKEditor 5 builds featuring `Context` to provide a list of context plugins which are later automatically initialized\n\t * during the context initialization.\n\t *\n\t * They will be automatically initialized by `Context` unless `config.plugins` is passed.\n\t *\n\t * ```ts\n\t * // Build some context plugins into the Context class first.\n\t * Context.builtinPlugins = [ FooPlugin, BarPlugin ];\n\t *\n\t * // Normally, you need to define config.plugins, but since Context.builtinPlugins was\n\t * // defined, now you can call create() without any configuration.\n\t * Context\n\t * \t.create()\n\t * \t.then( context => {\n\t * \t\tcontext.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.\n\t * \t\tcontext.plugins.get( BarPlugin ); // -> An instance of the Bar plugin.\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/context~Context.defaultConfig `Context.defaultConfig`}\n\t * and {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}.\n\t */\n\tpublic static builtinPlugins: Array<PluginConstructor<Context | Editor>>;\n\n\t/**\n\t * Reference to the editor which created the context.\n\t * Null when the context was created outside of the editor.\n\t *\n\t * It is used to destroy the context when removing the editor that has created the context.\n\t */\n\tprivate _contextOwner: Editor | null = null;\n\n\t/**\n\t * Creates a context instance with a given configuration.\n\t *\n\t * Usually not to be used directly. See the static {@link module:core/context~Context.create `create()`} method.\n\t *\n\t * @param config The context configuration.\n\t */\n\tconstructor( config?: ContextConfig ) {\n\t\t// We don't pass translations to the config, because its behavior of splitting keys\n\t\t// with dots (e.g. `resize.width` => `resize: { width }`) breaks the translations.\n\t\tconst { translations, ...rest } = config || {};\n\n\t\tthis.config = new Config<ContextConfig>( rest, ( this.constructor as typeof Context ).defaultConfig );\n\n\t\tconst availablePlugins = ( this.constructor as typeof Context ).builtinPlugins;\n\n\t\tthis.config.define( 'plugins', availablePlugins );\n\n\t\tthis.plugins = new PluginCollection<Context | Editor>( this, availablePlugins );\n\n\t\tconst languageConfig = this.config.get( 'language' ) || {};\n\n\t\tthis.locale = new Locale( {\n\t\t\tuiLanguage: typeof languageConfig === 'string' ? languageConfig : languageConfig.ui,\n\t\t\tcontentLanguage: this.config.get( 'language.content' ),\n\t\t\ttranslations\n\t\t} );\n\n\t\tthis.t = this.locale.t;\n\n\t\tthis.editors = new Collection<Editor>();\n\t}\n\n\t/**\n\t * Loads and initializes plugins specified in the configuration.\n\t *\n\t * @returns A promise which resolves once the initialization is completed, providing an array of loaded plugins.\n\t */\n\tpublic initPlugins(): Promise<LoadedPlugins> {\n\t\tconst plugins = this.config.get( 'plugins' ) || [];\n\t\tconst substitutePlugins = this.config.get( 'substitutePlugins' ) || [];\n\n\t\t// Plugins for substitution should be checked as well.\n\t\tfor ( const Plugin of plugins.concat( substitutePlugins ) ) {\n\t\t\tif ( typeof Plugin != 'function' ) {\n\t\t\t\t/**\n\t\t\t\t * Only a constructor function is allowed as a {@link module:core/contextplugin~ContextPlugin context plugin}.\n\t\t\t\t *\n\t\t\t\t * @error context-initplugins-constructor-only\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'context-initplugins-constructor-only',\n\t\t\t\t\tnull,\n\t\t\t\t\t{ Plugin }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( Plugin.isContextPlugin !== true ) {\n\t\t\t\t/**\n\t\t\t\t * Only a plugin marked as a {@link module:core/contextplugin~ContextPlugin.isContextPlugin context plugin}\n\t\t\t\t * is allowed to be used with a context.\n\t\t\t\t *\n\t\t\t\t * @error context-initplugins-invalid-plugin\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'context-initplugins-invalid-plugin',\n\t\t\t\t\tnull,\n\t\t\t\t\t{ Plugin }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn this.plugins.init( plugins, [], substitutePlugins );\n\t}\n\n\t/**\n\t * Destroys the context instance and all editors used with the context,\n\t * releasing all resources used by the context.\n\t *\n\t * @returns A promise that resolves once the context instance is fully destroyed.\n\t */\n\tpublic destroy(): Promise<unknown> {\n\t\treturn Promise.all( Array.from( this.editors, editor => editor.destroy() ) )\n\t\t\t.then( () => this.plugins.destroy() );\n\t}\n\n\t/**\n\t * Adds a reference to the editor which is used with this context.\n\t *\n\t * When the given editor has created the context, the reference to this editor will be stored\n\t * as a {@link ~Context#_contextOwner}.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @internal\n\t * @param isContextOwner Stores the given editor as a context owner.\n\t */\n\tpublic _addEditor( editor: Editor, isContextOwner: boolean ): void {\n\t\tif ( this._contextOwner ) {\n\t\t\t/**\n\t\t\t * Cannot add multiple editors to the context which is created by the editor.\n\t\t\t *\n\t\t\t * @error context-addeditor-private-context\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'context-addeditor-private-context' );\n\t\t}\n\n\t\tthis.editors.add( editor );\n\n\t\tif ( isContextOwner ) {\n\t\t\tthis._contextOwner = editor;\n\t\t}\n\t}\n\n\t/**\n\t * Removes a reference to the editor which was used with this context.\n\t * When the context was created by the given editor, the context will be destroyed.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @internal\n\t * @return A promise that resolves once the editor is removed from the context or when the context was destroyed.\n\t */\n\tpublic _removeEditor( editor: Editor ): Promise<unknown> {\n\t\tif ( this.editors.has( editor ) ) {\n\t\t\tthis.editors.remove( editor );\n\t\t}\n\n\t\tif ( this._contextOwner === editor ) {\n\t\t\treturn this.destroy();\n\t\t}\n\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Returns the context configuration which will be copied to the editors created using this context.\n\t *\n\t * The configuration returned by this method has the plugins configuration removed &ndash; plugins are shared with all editors\n\t * through another mechanism.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @internal\n\t * @returns Configuration as a plain object.\n\t */\n\tpublic _getEditorConfig(): Partial<EditorConfig> {\n\t\tconst result: Record<string, unknown> = {};\n\n\t\tfor ( const name of this.config.names() ) {\n\t\t\tif ( ![ 'plugins', 'removePlugins', 'extraPlugins' ].includes( name ) ) {\n\t\t\t\tresult[ name ] = this.config.get( name );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Creates and initializes a new context instance.\n\t *\n\t * ```ts\n\t * const commonConfig = { ... }; // Configuration for all the plugins and editors.\n\t * const editorPlugins = [ ... ]; // Regular plugins here.\n\t *\n\t * Context\n\t * \t.create( {\n\t * \t\t// Only context plugins here.\n\t * \t\tplugins: [ ... ],\n\t *\n\t * \t\t// Configure the language for all the editors (it cannot be overwritten).\n\t * \t\tlanguage: { ... },\n\t *\n\t * \t\t// Configuration for context plugins.\n\t * \t\tcomments: { ... },\n\t * \t\t...\n\t *\n\t * \t\t// Default configuration for editor plugins.\n\t * \t\ttoolbar: { ... },\n\t * \t\timage: { ... },\n\t * \t\t...\n\t * \t} )\n\t * \t.then( context => {\n\t * \t\tconst promises = [];\n\t *\n\t * \t\tpromises.push( ClassicEditor.create(\n\t * \t\t\tdocument.getElementById( 'editor1' ),\n\t * \t\t\t{\n\t * \t\t\t\teditorPlugins,\n\t * \t\t\t\tcontext\n\t * \t\t\t}\n\t * \t\t) );\n\t *\n\t * \t\tpromises.push( ClassicEditor.create(\n\t * \t\t\tdocument.getElementById( 'editor2' ),\n\t * \t\t\t{\n\t * \t\t\t\teditorPlugins,\n\t * \t\t\t\tcontext,\n\t * \t\t\t\ttoolbar: { ... } // You can overwrite the configuration of the context.\n\t * \t\t\t}\n\t * \t\t) );\n\t *\n\t * \t\treturn Promise.all( promises );\n\t * \t} );\n\t * ```\n\t *\n\t * @param config The context configuration.\n\t * @returns A promise resolved once the context is ready. The promise resolves with the created context instance.\n\t */\n\tpublic static create( config?: ContextConfig ): Promise<Context> {\n\t\treturn new Promise( resolve => {\n\t\t\tconst context = new this( config );\n\n\t\t\tresolve( context.initPlugins().then( () => context ) );\n\t\t} );\n\t}\n}\n\n/**\n * The context configuration.\n */\nexport type ContextConfig = {\n\tplugins?: Array<PluginConstructor<Context | Editor>>;\n\tsubstitutePlugins?: Array<PluginConstructor<Context | Editor>>;\n} & Omit<EditorConfig, 'plugins' | 'substitutePlugins' | 'removePlugins' | 'extraPlugins'>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/contextplugin\n */\n\nimport {\n\tObservableMixin,\n\ttype Collection,\n\ttype Config,\n\ttype Locale,\n\ttype LocaleTranslate\n} from '@ckeditor/ckeditor5-utils';\n\nimport type Editor from './editor/editor.js';\nimport type { EditorConfig } from './editor/editorconfig.js';\nimport type Context from './context.js';\nimport type { PluginDependencies, PluginInterface } from './plugin.js';\nimport type PluginCollection from './plugincollection.js';\n\n/**\n * The base class for {@link module:core/context~Context} plugin classes.\n *\n * A context plugin can either be initialized for an {@link module:core/editor/editor~Editor editor} or for\n * a {@link module:core/context~Context context}. In other words, it can either\n * work within one editor instance or with one or more editor instances that use a single context.\n * It is the context plugin's role to implement handling for both modes.\n *\n * There are a few rules for interaction between the editor plugins and context plugins:\n *\n * * A context plugin can require another context plugin.\n * * An {@link module:core/plugin~Plugin editor plugin} can require a context plugin.\n * * A context plugin MUST NOT require an {@link module:core/plugin~Plugin editor plugin}.\n */\nexport default class ContextPlugin extends /* #__PURE__ */ ObservableMixin() implements PluginInterface {\n\t/**\n\t * The context or editor instance.\n\t */\n\tpublic readonly context: ContextInterface;\n\n\t/**\n\t * Creates a new plugin instance.\n\t */\n\tconstructor( context: Context | Editor ) {\n\t\tsuper();\n\n\t\tthis.context = context as ContextInterface;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get isContextPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get isOfficialPlugin(): boolean {\n\t\treturn false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get isPremiumPlugin(): boolean {\n\t\treturn false;\n\t}\n}\n\n/**\n * The common interface of {@link module:core/context~Context} and {@link module:core/editor/editor~Editor}.\n */\nexport interface ContextInterface {\n\tconfig: Config<Omit<EditorConfig, 'plugins' | 'substitutePlugins' | 'removePlugins' | 'extraPlugins'>>;\n\tplugins: PluginCollection<Context | Editor>;\n\tlocale: Locale;\n\tt: LocaleTranslate;\n\teditors?: Collection<Editor>;\n}\n\nexport type ContextPluginDependencies = PluginDependencies<Context | Editor>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/commandcollection\n */\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\nimport type Command from './command.js';\n\n/**\n * Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n */\nexport default class CommandCollection implements Iterable<[ string, Command ]> {\n\t/**\n\t * Command map.\n\t */\n\tprivate _commands: Map<string, Command>;\n\n\t/**\n\t * Creates collection instance.\n\t */\n\tconstructor() {\n\t\tthis._commands = new Map();\n\t}\n\n\t/**\n\t * Registers a new command.\n\t *\n\t * @param commandName The name of the command.\n\t */\n\tpublic add<TName extends string>(\n\t\tcommandName: TName,\n\t\tcommand: CommandsMap[ TName ]\n\t): void {\n\t\tthis._commands.set( commandName, command );\n\t}\n\n\t/**\n\t * Retrieves a command from the collection.\n\t *\n\t * @param commandName The name of the command.\n\t */\n\tpublic get<TName extends string>( commandName: TName ): CommandsMap[ TName ] | undefined {\n\t\treturn this._commands.get( commandName );\n\t}\n\n\t/**\n\t * Executes a command.\n\t *\n\t * @param commandName The name of the command.\n\t * @param commandParams Command parameters.\n\t * @returns The value returned by the {@link module:core/command~Command#execute `command.execute()`}.\n\t */\n\tpublic execute<TName extends string>(\n\t\tcommandName: TName,\n\t\t...commandParams: Parameters<CommandsMap[ TName ][ 'execute' ]>\n\t): ReturnType<CommandsMap[ TName ][ 'execute' ]> {\n\t\tconst command = this.get( commandName );\n\n\t\tif ( !command ) {\n\t\t\t/**\n\t\t\t * Command does not exist.\n\t\t\t *\n\t\t\t * @error commandcollection-command-not-found\n\t\t\t * @param commandName Name of the command.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'commandcollection-command-not-found', this, { commandName } );\n\t\t}\n\n\t\treturn command.execute( ...commandParams ) as any;\n\t}\n\n\t/**\n\t * Returns iterator of command names.\n\t */\n\tpublic* names(): IterableIterator<string> {\n\t\tyield* this._commands.keys();\n\t}\n\n\t/**\n\t * Returns iterator of command instances.\n\t */\n\tpublic* commands(): IterableIterator<Command> {\n\t\tyield* this._commands.values();\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Returns `[ commandName, commandInstance ]` pairs.\n\t */\n\tpublic [ Symbol.iterator ](): Iterator<[ string, Command ]> {\n\t\treturn this._commands[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Destroys all collection commands.\n\t */\n\tpublic destroy(): void {\n\t\tfor ( const command of this.commands() ) {\n\t\t\tcommand.destroy();\n\t\t}\n\t}\n}\n\n/**\n * Helper type that maps command names to their types.\n * It is meant to be extended with module augmentation.\n *\n * ```ts\n * class MyCommand extends Command {\n * \tpublic execute( parameter: A ): B {\n * \t\t// ...\n * \t}\n * }\n *\n * declare module '@ckeditor/ckeditor5-core' {\n * \tinterface CommandsMap {\n * \t\tmyCommand: MyCommand;\n * \t}\n * }\n *\n * // Returns `MyCommand | undefined`.\n * const myCommand = editor.commands.get( 'myCommand' );\n *\n * // Expects `A` type as parameter and returns `B`.\n * const value = editor.commands.execute( 'myCommand', new A() );\n * ```\n */\nexport interface CommandsMap {\n\t[ name: string ]: Command;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editingkeystrokehandler\n */\n\nimport { KeystrokeHandler, type PriorityString } from '@ckeditor/ckeditor5-utils';\n\nimport type Editor from './editor/editor.js';\n\n/**\n * A keystroke handler for editor editing. Its instance is available\n * in {@link module:core/editor/editor~Editor#keystrokes} so plugins\n * can register their keystrokes.\n *\n * E.g. an undo plugin would do this:\n *\n * ```ts\n * editor.keystrokes.set( 'Ctrl+Z', 'undo' );\n * editor.keystrokes.set( 'Ctrl+Shift+Z', 'redo' );\n * editor.keystrokes.set( 'Ctrl+Y', 'redo' );\n * ```\n */\nexport default class EditingKeystrokeHandler extends KeystrokeHandler {\n\t/**\n\t * The editor instance.\n\t */\n\tpublic readonly editor: Editor;\n\n\t/**\n\t * Creates an instance of the keystroke handler.\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper();\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * The handler can be specified as a command name or a callback.\n\t *\n\t * @param keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param callback If a string is passed, then the keystroke will\n\t * {@link module:core/editor/editor~Editor#execute execute a command}.\n\t * If a function, then it will be called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a `cancel()` helper to both `preventDefault()` and `stopPropagation()` of the event.\n\t * @param options Additional options.\n\t * @param options.priority The priority of the keystroke callback. The higher the priority value\n\t * the sooner the callback will be executed. Keystrokes having the same priority\n\t * are called in the order they were added.\n\t */\n\tpublic override set(\n\t\tkeystroke: string | Array<string | number>,\n\t\tcallback: EditingKeystrokeCallback,\n\t\toptions: { readonly priority?: PriorityString } = {}\n\t): void {\n\t\tif ( typeof callback == 'string' ) {\n\t\t\tconst commandName = callback;\n\n\t\t\tcallback = ( evtData, cancel ) => {\n\t\t\t\tthis.editor.execute( commandName );\n\t\t\t\tcancel();\n\t\t\t};\n\t\t}\n\n\t\tsuper.set( keystroke, callback, options );\n\t}\n}\n\n/**\n * Command name or a callback to be executed when a given keystroke is pressed.\n */\nexport type EditingKeystrokeCallback = string | ( ( ev: KeyboardEvent, cancel: () => void ) => void );\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/accessibility\n */\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\nimport type Editor from './editor/editor.js';\n\nconst DEFAULT_CATEGORY_ID = 'contentEditing' as const;\nexport const DEFAULT_GROUP_ID = 'common' as const;\n\n/**\n * A common namespace for various accessibility features of the editor.\n *\n * **Information about editor keystrokes**\n *\n * * The information about keystrokes available in the editor is stored in the {@link #keystrokeInfos} property.\n * * New info entries can be added using the {@link #addKeystrokeInfoCategory}, {@link #addKeystrokeInfoGroup},\n * and {@link #addKeystrokeInfos} methods.\n */\nexport default class Accessibility {\n\t/**\n\t * Stores information about keystrokes brought by editor features for the users to interact with the editor, mainly\n\t * keystroke combinations and their accessible labels.\n\t *\n\t * This information is particularly useful for screen reader and other assistive technology users. It gets displayed\n\t * by the {@link module:ui/editorui/accessibilityhelp/accessibilityhelp~AccessibilityHelp Accessibility help} dialog.\n\t *\n\t * Keystrokes are organized in categories and groups. They can be added using ({@link #addKeystrokeInfoCategory},\n\t * {@link #addKeystrokeInfoGroup}, and {@link #addKeystrokeInfos}) methods.\n\t *\n\t * Please note that:\n\t * * two categories are always available:\n\t *   * `'contentEditing'` for keystrokes related to content creation,\n\t *   * `'navigation'` for keystrokes related to navigation in the UI and the content.\n\t * * unless specified otherwise, new keystrokes are added into the `'contentEditing'` category and the `'common'`\n\t * keystroke group within that category while using the {@link #addKeystrokeInfos} method.\n\t */\n\tpublic readonly keystrokeInfos: KeystrokeInfos = new Map();\n\n\t/**\n\t * The editor instance.\n\t */\n\tprivate readonly _editor: Editor;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tthis._editor = editor;\n\t\tconst isMenuBarVisible = editor.config.get( 'menuBar.isVisible' );\n\n\t\tconst t = editor.locale.t;\n\n\t\tthis.addKeystrokeInfoCategory( {\n\t\t\tid: DEFAULT_CATEGORY_ID,\n\t\t\tlabel: t( 'Content editing keystrokes' ),\n\t\t\tdescription: t( 'These keyboard shortcuts allow for quick access to content editing features.' )\n\t\t} );\n\n\t\tconst navigationKeystrokes = [\n\t\t\t{\n\t\t\t\tlabel: t( 'Close contextual balloons, dropdowns, and dialogs' ),\n\t\t\t\tkeystroke: 'Esc'\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: t( 'Open the accessibility help dialog' ),\n\t\t\t\tkeystroke: 'Alt+0'\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: t( 'Move focus between form fields (inputs, buttons, etc.)' ),\n\t\t\t\tkeystroke: [ [ 'Tab' ], [ 'Shift+Tab' ] ]\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: t( 'Move focus to the toolbar, navigate between toolbars' ),\n\t\t\t\tkeystroke: 'Alt+F10',\n\t\t\t\tmayRequireFn: true\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: t( 'Navigate through the toolbar or menu bar' ),\n\t\t\t\tkeystroke: [ [ 'arrowup' ], [ 'arrowright' ], [ 'arrowdown' ], [ 'arrowleft' ] ]\n\t\t\t},\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line max-len\n\t\t\t\tlabel: t( 'Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.' ),\n\t\t\t\tkeystroke: [ [ 'Enter' ], [ 'Space' ] ]\n\t\t\t}\n\t\t];\n\n\t\tif ( isMenuBarVisible ) {\n\t\t\tnavigationKeystrokes.push(\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move focus to the menu bar, navigate between menu bars' ),\n\t\t\t\t\tkeystroke: 'Alt+F9',\n\t\t\t\t\tmayRequireFn: true\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tthis.addKeystrokeInfoCategory( {\n\t\t\tid: 'navigation',\n\t\t\tlabel: t( 'User interface and content navigation keystrokes' ),\n\t\t\tdescription: t( 'Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.' ),\n\t\t\tgroups: [\n\t\t\t\t{\n\t\t\t\t\tid: 'common',\n\t\t\t\t\tkeystrokes: navigationKeystrokes\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Adds a top-level category in the {@link #keystrokeInfos keystroke information database} with a label and optional description.\n\t *\n\t * Categories organize keystrokes and help users to find the right keystroke. Each category can have multiple groups\n\t * of keystrokes that narrow down the context in which the keystrokes are available. Every keystroke category comes\n\t * with a `'common'` group by default.\n\t *\n\t * By default, two categories are available:\n\t * * `'contentEditing'` for keystrokes related to content creation,\n\t * * `'navigation'` for keystrokes related to navigation in the UI and the content.\n\t *\n\t * To create a new keystroke category with new groups, use the following code:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfoCategory( {\n\t * \t\t\tid: 'myCategory',\n\t * \t\t\tlabel: t( 'My category' ),\n\t * \t\t\tdescription: t( 'My category description.' ),\n\t * \t\t\tgroups: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tid: 'myGroup',\n\t * \t\t\t\t\tlabel: t( 'My keystroke group' ),\n\t * \t\t\t\t\tkeystrokes: [\n\t * \t\t\t\t\t\t{\n\t * \t\t\t\t\t\t\tlabel: t( 'Keystroke label 1' ),\n\t * \t\t\t\t\t\t\tkeystroke: 'Ctrl+Shift+N'\n\t * \t\t\t\t\t\t},\n\t * \t\t\t\t\t\t{\n\t * \t\t\t\t\t\t\tlabel: t( 'Keystroke label 2' ),\n\t * \t\t\t\t\t\t\tkeystroke: 'Ctrl+Shift+M'\n\t * \t\t\t\t\t\t}\n\t * \t\t\t\t\t]\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t};\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * See {@link #keystrokeInfos}, {@link #addKeystrokeInfoGroup}, and {@link #addKeystrokeInfos}.\n\t */\n\tpublic addKeystrokeInfoCategory( { id, label, description, groups }: AddKeystrokeInfoCategoryData ): void {\n\t\tthis.keystrokeInfos.set( id, {\n\t\t\tid,\n\t\t\tlabel,\n\t\t\tdescription,\n\t\t\tgroups: new Map()\n\t\t} );\n\n\t\tthis.addKeystrokeInfoGroup( {\n\t\t\tcategoryId: id,\n\t\t\tid: DEFAULT_GROUP_ID\n\t\t} );\n\n\t\tif ( groups ) {\n\t\t\tgroups.forEach( group => {\n\t\t\t\tthis.addKeystrokeInfoGroup( {\n\t\t\t\t\tcategoryId: id,\n\t\t\t\t\t...group\n\t\t\t\t} );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Adds a group of keystrokes in a specific category to the {@link #keystrokeInfos keystroke information database}.\n\t *\n\t * Groups narrow down the context in which the keystrokes are available. When `categoryId` is not specified,\n\t * the group goes to the `'contentEditing'` category (default).\n\t *\n\t * To create a new group within an existing category, use the following code:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfoGroup( {\n\t * \t\t\tid: 'myGroup',\n\t * \t\t\tcategoryId: 'navigation',\n\t * \t\t\tlabel: t( 'My keystroke group' ),\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label 1' ),\n\t * \t\t\t\t\tkeystroke: 'Ctrl+Shift+N'\n\t * \t\t\t\t},\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label 2' ),\n\t * \t\t\t\t\tkeystroke: 'Ctrl+Shift+M'\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * See {@link #keystrokeInfos}, {@link #addKeystrokeInfoCategory}, and {@link #addKeystrokeInfos}.\n\t */\n\tpublic addKeystrokeInfoGroup( {\n\t\tcategoryId = DEFAULT_CATEGORY_ID,\n\t\tid,\n\t\tlabel,\n\t\tkeystrokes\n\t}: AddKeystrokeInfoGroupData ): void {\n\t\tconst category = this.keystrokeInfos.get( categoryId );\n\n\t\tif ( !category ) {\n\t\t\tthrow new CKEditorError( 'accessibility-unknown-keystroke-info-category', this._editor, { groupId: id, categoryId } );\n\t\t}\n\n\t\tcategory.groups.set( id, {\n\t\t\tid,\n\t\t\tlabel,\n\t\t\tkeystrokes: keystrokes || []\n\t\t} );\n\t}\n\n\t/**\n\t * Adds information about keystrokes to the {@link #keystrokeInfos keystroke information database}.\n\t *\n\t * Keystrokes without specified `groupId` or `categoryId` go to the `'common'` group in the `'contentEditing'` category (default).\n\t *\n\t * To add a keystroke brought by your plugin (using default group and category), use the following code:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfos( {\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label' ),\n\t * \t\t\t\t\tkeystroke: 'CTRL+B'\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t * To add a keystroke in a specific existing `'widget'` group in the default `'contentEditing'` category:\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfos( {\n\t * \t\t\t// Add a keystroke to the existing \"widget\" group.\n\t * \t\t\tgroupId: 'widget',\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'A an action on a selected widget' ),\n\t * \t\t\t\t\tkeystroke: 'Ctrl+D',\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * To add a keystroke to another existing category (using default group):\n\t *\n\t * ```js\n\t * class MyPlugin extends Plugin {\n\t * \t// ...\n\t * \tinit() {\n\t * \t\tconst editor = this.editor;\n\t * \t\tconst t = editor.t;\n\t *\n\t * \t\t// ...\n\t *\n\t * \t\teditor.accessibility.addKeystrokeInfos( {\n\t * \t\t\t// Add keystrokes to the \"navigation\" category (one of defaults).\n\t * \t\t\tcategoryId: 'navigation',\n\t * \t\t\tkeystrokes: [\n\t * \t\t\t\t{\n\t * \t\t\t\t\tlabel: t( 'Keystroke label' ),\n\t * \t\t\t\t\tkeystroke: 'CTRL+B'\n\t * \t\t\t\t}\n\t * \t\t\t]\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * See {@link #keystrokeInfos}, {@link #addKeystrokeInfoGroup}, and {@link #addKeystrokeInfoCategory}.\n\t */\n\tpublic addKeystrokeInfos( {\n\t\tcategoryId = DEFAULT_CATEGORY_ID,\n\t\tgroupId = DEFAULT_GROUP_ID,\n\t\tkeystrokes\n\t}: AddKeystrokeInfosData ): void {\n\t\tif ( !this.keystrokeInfos.has( categoryId ) ) {\n\t\t\t/**\n\t\t\t * Cannot add keystrokes in an unknown category. Use\n\t\t\t * {@link module:core/accessibility~Accessibility#addKeystrokeInfoCategory}\n\t\t\t * to add a new category or make sure the specified category exists.\n\t\t\t *\n\t\t\t * @error accessibility-unknown-keystroke-info-category\n\t\t\t * @param categoryId The id of the unknown keystroke category.\n\t\t\t * @param keystrokes Keystroke definitions about to be added.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'accessibility-unknown-keystroke-info-category', this._editor, { categoryId, keystrokes } );\n\t\t}\n\n\t\tconst category = this.keystrokeInfos.get( categoryId )!;\n\n\t\tif ( !category.groups.has( groupId ) ) {\n\t\t\t/**\n\t\t\t * Cannot add keystrokes to an unknown group.\n\t\t\t *\n\t\t\t * Use {@link module:core/accessibility~Accessibility#addKeystrokeInfoGroup}\n\t\t\t * to add a new group or make sure the specified group exists.\n\t\t\t *\n\t\t\t * @error accessibility-unknown-keystroke-info-group\n\t\t\t * @param groupId The id of the unknown keystroke group.\n\t\t\t * @param categoryId The id of category the unknown group should belong to.\n\t\t\t * @param keystrokes Keystroke definitions about to be added.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'accessibility-unknown-keystroke-info-group', this._editor, { groupId, categoryId, keystrokes } );\n\t\t}\n\n\t\tcategory.groups.get( groupId )!.keystrokes.push( ...keystrokes );\n\t}\n}\n\n/**\n * A description of category of keystrokes accepted by the {@link module:core/accessibility~Accessibility#addKeystrokeInfoCategory} method.\n *\n * Top-level categories organize keystrokes and help users to find the right keystroke. Each category can have multiple groups of\n * keystrokes that narrow down the context in which the keystrokes are available.\n *\n * See {@link module:core/accessibility~Accessibility#addKeystrokeInfoGroup} and\n * {@link module:core/accessibility~Accessibility#addKeystrokeInfos}.\n */\nexport interface AddKeystrokeInfoCategoryData {\n\n\t/**\n\t * The unique id of the category.\n\t */\n\tid: string;\n\n\t/**\n\t * The label of the category.\n\t */\n\tlabel: string;\n\n\t/**\n\t * The description of the category (optional).\n\t */\n\tdescription?: string;\n\n\t/**\n\t * Groups of keystrokes within the category.\n\t */\n\tgroups?: Array<AddKeystrokeInfoGroupData>;\n}\n\n/**\n * A description of keystroke group accepted by the {@link module:core/accessibility~Accessibility#addKeystrokeInfoGroup} method.\n *\n * Groups narrow down the context in which the keystrokes are available. When `categoryId` is not specified, the group goes\n * to the `'contentEditing'` category (default).\n *\n * See {@link module:core/accessibility~Accessibility#addKeystrokeInfoCategory} and\n * {@link module:core/accessibility~Accessibility#addKeystrokeInfos}.\n */\nexport interface AddKeystrokeInfoGroupData {\n\n\t/**\n\t * The category id the group belongs to.\n\t */\n\tcategoryId?: string;\n\n\t/**\n\t * The unique id of the group.\n\t */\n\tid: string;\n\n\t/**\n\t * The label of the group (optional).\n\t */\n\tlabel?: string;\n\n\t/**\n\t * Keystroke definitions within the group.\n\t */\n\tkeystrokes?: Array<KeystrokeInfoDefinition>;\n}\n\n/**\n * Description of keystrokes accepted by the {@link module:core/accessibility~Accessibility#addKeystrokeInfos} method.\n *\n * Keystrokes without specified `groupId` or `categoryId` go to the `'common'` group in the `'contentEditing'` category (default).\n *\n * See {@link module:core/accessibility~Accessibility#addKeystrokeInfoCategory} and\n * {@link module:core/accessibility~Accessibility#addKeystrokeInfoGroup}.\n */\nexport interface AddKeystrokeInfosData {\n\n\t/**\n\t * The category id the keystrokes belong to.\n\t */\n\tcategoryId?: string;\n\n\t/**\n\t * The group id the keystrokes belong to.\n\t */\n\tgroupId?: string;\n\n\t/**\n\t * An array of keystroke definitions.\n\t */\n\tkeystrokes: Array<KeystrokeInfoDefinition>;\n}\n\nexport type KeystrokeInfos = Map<string, KeystrokeInfoCategory>;\n\n/**\n * A category of keystrokes in {@link module:core/accessibility~Accessibility#keystrokeInfos}.\n */\nexport type KeystrokeInfoCategory = {\n\n\t/**\n\t * The unique id of the category.\n\t */\n\tid: string;\n\n\t/**\n\t * The label of the category.\n\t */\n\tlabel: string;\n\n\t/**\n\t * The description of the category (optional).\n\t */\n\tdescription?: string;\n\n\t/**\n\t * Groups of keystrokes within the category.\n\t */\n\tgroups: Map<string, KeystrokeInfoGroup>;\n};\n\n/**\n * A group of keystrokes in {@link module:core/accessibility~Accessibility#keystrokeInfos}.\n */\nexport type KeystrokeInfoGroup = {\n\n\t/**\n\t * The unique id of the group.\n\t */\n\tid: string;\n\n\t/**\n\t * The label of the group (optional).\n\t */\n\tlabel?: string;\n\n\t/**\n\t * Keystroke definitions within the group.\n\t */\n\tkeystrokes: Array<KeystrokeInfoDefinition>;\n};\n\n/**\n * A keystroke info definition in {@link module:core/accessibility~Accessibility#keystrokeInfos}\n */\nexport interface KeystrokeInfoDefinition {\n\n\t/**\n\t * The label of the keystroke. It should briefly describe the action that the keystroke performs. It may contain HTML.\n\t */\n\tlabel: string;\n\n\t/**\n\t * The keystroke string. In its basic form, it must be a combination of {@link module:utils/keyboard#keyCodes known key names}\n\t * joined by the `+` sign, the same as the keystroke format accepted by the\n\t * {@link module:utils/keystrokehandler~KeystrokeHandler#set `KeystrokeHandler#set()`} method used to register most of the\n\t * keystroke interactions in the editor.\n\t *\n\t * * The keystroke string can represent a single keystroke, for instance: `keystroke: 'Ctrl+B'`, `keystroke: 'Shift+Enter'`,\n\t * `keystroke: 'Alt+F10'`, etc.\n\t * * The keystroke can be activated by successive press of multiple keys. For instance `keystroke: [ [ 'arrowleft', 'arrowleft' ] ]`\n\t * will indicate that a specific action will be performed by pressing <kbd>←</kbd> twice in a row.\n\t * * Keystrokes can have alternatives. For instance `keystroke: [ [ 'Ctrl+Y' ], [ 'Ctrl+Shift+Z' ] ]` will indicate that\n\t * a specific action can be performed by pressing either <kbd>Ctrl</kbd> + <kbd>Y</kbd> or\n\t * <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Z</kbd>.\n\t *\n\t * Please note that the keystrokes are automatically translated to the environment-specific form. For example, `Ctrl+A`\n\t * will be rendered as `⌘A` in the {@link module:utils/env~EnvType#isMac Mac environment}. Always use the IBM PC keyboard\n\t * syntax, for instance `Ctrl` instead of `⌘`, `Alt` instead of `⌥`, etc.\n\t */\n\tkeystroke: string | Array<string> | Array<Array<string>>;\n\n\t/**\n\t * This (optional) flag suggests that the keystroke(s) may require a function (<kbd>Fn</kbd>) key to be pressed\n\t * in order to work in the {@link module:utils/env~EnvType#isMac Mac environment}. If set `true`, an additional\n\t * information will be displayed next to the keystroke.\n\t */\n\tmayRequireFn?: boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editor/editor\n */\n\nimport {\n\tConfig,\n\tCKEditorError,\n\tObservableMixin,\n\ttype Locale,\n\ttype LocaleTranslate,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport {\n\tConversion,\n\tDataController,\n\tEditingController,\n\tModel,\n\tStylesProcessor\n} from '@ckeditor/ckeditor5-engine';\n\nimport type { EditorUI } from '@ckeditor/ckeditor5-ui';\nimport { ContextWatchdog, EditorWatchdog } from '@ckeditor/ckeditor5-watchdog';\n\nimport Context from '../context.js';\nimport PluginCollection from '../plugincollection.js';\nimport CommandCollection, { type CommandsMap } from '../commandcollection.js';\nimport EditingKeystrokeHandler from '../editingkeystrokehandler.js';\nimport Accessibility from '../accessibility.js';\n\nimport type { LoadedPlugins, PluginConstructor } from '../plugin.js';\nimport type { EditorConfig } from './editorconfig.js';\n\n/**\n * The class representing a basic, generic editor.\n *\n * Check out the list of its subclasses to learn about specific editor implementations.\n *\n * All editor implementations (like {@link module:editor-classic/classiceditor~ClassicEditor} or\n * {@link module:editor-inline/inlineeditor~InlineEditor}) should extend this class. They can add their\n * own methods and properties.\n *\n * When you are implementing a plugin, this editor represents the API\n * which your plugin can expect to get when using its {@link module:core/plugin~Plugin#editor} property.\n *\n * This API should be sufficient in order to implement the \"editing\" part of your feature\n * (schema definition, conversion, commands, keystrokes, etc.).\n * It does not define the editor UI, which is available only if\n * the specific editor implements also the {@link ~Editor#ui} property\n * (as most editor implementations do).\n */\nexport default abstract class Editor extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * A namespace for the accessibility features of the editor.\n\t */\n\tpublic readonly accessibility: Accessibility;\n\n\t/**\n\t * Commands registered to the editor.\n\t *\n\t * Use the shorthand {@link #execute `editor.execute()`} method to execute commands:\n\t *\n\t * ```ts\n\t * // Execute the bold command:\n\t * editor.execute( 'bold' );\n\t *\n\t * // Check the state of the bold command:\n\t * editor.commands.get( 'bold' ).value;\n\t * ```\n\t */\n\tpublic readonly commands: CommandCollection;\n\n\t/**\n\t * Stores all configurations specific to this editor instance.\n\t *\n\t * ```ts\n\t * editor.config.get( 'image.toolbar' );\n\t * // -> [ 'imageStyle:block', 'imageStyle:side', '|', 'toggleImageCaption', 'imageTextAlternative' ]\n\t * ```\n\t */\n\tpublic readonly config: Config<EditorConfig>;\n\n\t/**\n\t * Conversion manager through which you can register model-to-view and view-to-model converters.\n\t *\n\t * See the {@link module:engine/conversion/conversion~Conversion} documentation to learn how to add converters.\n\t */\n\tpublic readonly conversion: Conversion;\n\n\t/**\n\t * The {@link module:engine/controller/datacontroller~DataController data controller}.\n\t * Used e.g. for setting and retrieving the editor data.\n\t */\n\tpublic readonly data: DataController;\n\n\t/**\n\t * The {@link module:engine/controller/editingcontroller~EditingController editing controller}.\n\t * Controls user input and rendering the content for editing.\n\t */\n\tpublic readonly editing: EditingController;\n\n\t/**\n\t * The locale instance.\n\t */\n\tpublic readonly locale: Locale;\n\n\t/**\n\t * The editor's model.\n\t *\n\t * The central point of the editor's abstract data model.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * The plugins loaded and in use by this editor instance.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'ClipboardPipeline' ); // -> An instance of the clipboard pipeline plugin.\n\t * ```\n\t */\n\tpublic readonly plugins: PluginCollection<Editor>;\n\n\t/**\n\t * An instance of the {@link module:core/editingkeystrokehandler~EditingKeystrokeHandler}.\n\t *\n\t * It allows setting simple keystrokes:\n\t *\n\t * ```ts\n\t * // Execute the bold command on Ctrl+E:\n\t * editor.keystrokes.set( 'Ctrl+E', 'bold' );\n\t *\n\t * // Execute your own callback:\n\t * editor.keystrokes.set( 'Ctrl+E', ( data, cancel ) => {\n\t * \tconsole.log( data.keyCode );\n\t *\n\t * \t// Prevent the default (native) action and stop the underlying keydown event\n\t * \t// so no other editor feature will interfere.\n\t * \tcancel();\n\t * } );\n\t * ```\n\t *\n\t * Note: Certain typing-oriented keystrokes (like <kbd>Backspace</kbd> or <kbd>Enter</kbd>) are handled\n\t * by a low-level mechanism and trying to listen to them via the keystroke handler will not work reliably.\n\t * To handle these specific keystrokes, see the events fired by the\n\t * {@link module:engine/view/document~Document editing view document} (`editor.editing.view.document`).\n\t */\n\tpublic readonly keystrokes: EditingKeystrokeHandler;\n\n\t/**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t *\n\t * @see module:utils/locale~Locale#t\n\t */\n\tpublic readonly t: LocaleTranslate;\n\n\tpublic declare readonly id: string;\n\n\t/**\n\t * Indicates the editor life-cycle state.\n\t *\n\t * The editor is in one of the following states:\n\t *\n\t * * `initializing` &ndash; During the editor initialization (before\n\t * {@link module:core/editor/editor~Editor.create `Editor.create()`}) finished its job.\n\t * * `ready` &ndash; After the promise returned by the {@link module:core/editor/editor~Editor.create `Editor.create()`}\n\t * method is resolved.\n\t * * `destroyed` &ndash; Once the {@link #destroy `editor.destroy()`} method was called.\n\t *\n\t * @observable\n\t */\n\tpublic declare state: 'initializing' | 'ready' | 'destroyed';\n\n\t/**\n\t * The default configuration which is built into the editor class.\n\t *\n\t * It is used in CKEditor 5 builds to provide the default configuration options which are later used during the editor initialization.\n\t *\n\t * ```ts\n\t * ClassicEditor.defaultConfig = {\n\t * \tfoo: 1,\n\t * \tbar: 2\n\t * };\n\t *\n\t * ClassicEditor\n\t * \t.create( sourceElement )\n\t * \t.then( editor => {\n\t * \t\teditor.config.get( 'foo' ); // -> 1\n\t * \t\teditor.config.get( 'bar' ); // -> 2\n\t * \t} );\n\t *\n\t * // The default options can be overridden by the configuration passed to create().\n\t * ClassicEditor\n\t * \t.create( sourceElement, { bar: 3 } )\n\t * \t.then( editor => {\n\t * \t\teditor.config.get( 'foo' ); // -> 1\n\t * \t\teditor.config.get( 'bar' ); // -> 3\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/editor/editor~Editor.builtinPlugins}.\n\t */\n\tpublic static defaultConfig?: EditorConfig;\n\n\t/**\n\t * An array of plugins built into this editor class.\n\t *\n\t * It is used in CKEditor 5 builds to provide a list of plugins which are later automatically initialized\n\t * during the editor initialization.\n\t *\n\t * They will be automatically initialized by the editor, unless listed in `config.removePlugins` and\n\t * unless `config.plugins` is passed.\n\t *\n\t * ```ts\n\t * // Build some plugins into the editor class first.\n\t * ClassicEditor.builtinPlugins = [ FooPlugin, BarPlugin ];\n\t *\n\t * // Normally, you need to define config.plugins, but since ClassicEditor.builtinPlugins was\n\t * // defined, now you can call create() without any configuration.\n\t * ClassicEditor\n\t * \t.create( sourceElement )\n\t * \t.then( editor => {\n\t * \t\teditor.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.\n\t * \t\teditor.plugins.get( BarPlugin ); // -> An instance of the Bar plugin.\n\t * \t} );\n\t *\n\t * ClassicEditor\n\t * \t.create( sourceElement, {\n\t * \t\t// Do not initialize these plugins (note: it is defined by a string):\n\t * \t\tremovePlugins: [ 'Foo' ]\n\t * \t} )\n\t * \t.then( editor => {\n\t * \t\teditor.plugins.get( FooPlugin ); // -> Undefined.\n\t * \t\teditor.config.get( BarPlugin ); // -> An instance of the Bar plugin.\n\t * \t} );\n\t *\n\t * ClassicEditor\n\t * \t.create( sourceElement, {\n\t * \t\t// Load only this plugin. It can also be defined by a string if\n\t * \t\t// this plugin was built into the editor class.\n\t * \t\tplugins: [ FooPlugin ]\n\t * \t} )\n\t * \t.then( editor => {\n\t * \t\teditor.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.\n\t * \t\teditor.config.get( BarPlugin ); // -> Undefined.\n\t * \t} );\n\t * ```\n\t *\n\t * See also {@link module:core/editor/editor~Editor.defaultConfig}.\n\t */\n\tpublic static builtinPlugins?: Array<PluginConstructor<Editor>>;\n\n\t/**\n\t * The editor UI instance.\n\t */\n\tpublic abstract get ui(): EditorUI;\n\n\t/**\n\t * The editor context.\n\t * When it is not provided through the configuration, the editor creates it.\n\t */\n\tprotected readonly _context: Context;\n\n\t/**\n\t * A set of lock IDs for the {@link #isReadOnly} getter.\n\t */\n\tprotected readonly _readOnlyLocks: Set<symbol | string>;\n\n\t/**\n\t * Creates a new instance of the editor class.\n\t *\n\t * Usually, not to be used directly. See the static {@link module:core/editor/editor~Editor.create `create()`} method.\n\t *\n\t * @param config The editor configuration.\n\t */\n\tconstructor( config: EditorConfig = {} ) {\n\t\tsuper();\n\n\t\tif ( 'sanitizeHtml' in config ) {\n\t\t\t/**\n\t\t\t * Configuration property `config.sanitizeHtml` was removed in CKEditor version 43.1.0 and is no longer supported.\n\t\t\t *\n\t\t\t * Please use `config.htmlEmbed.sanitizeHtml` and/or `config.mergeFields.sanitizeHtml` instead.\n\t\t\t *\n\t\t\t * @error editor-config-sanitizehtml-not-supported\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'editor-config-sanitizehtml-not-supported' );\n\t\t}\n\n\t\tconst constructor = this.constructor as typeof Editor;\n\n\t\t// We don't pass translations to the config, because its behavior of splitting keys\n\t\t// with dots (e.g. `resize.width` => `resize: { width }`) breaks the translations.\n\t\tconst { translations: defaultTranslations, ...defaultConfig } = constructor.defaultConfig || {};\n\t\tconst { translations = defaultTranslations, ...rest } = config;\n\n\t\t// Prefer the language passed as the argument to the constructor instead of the constructor's `defaultConfig`, if both are set.\n\t\tconst language = config.language || defaultConfig.language;\n\n\t\tthis._context = config.context || new Context( { language, translations } );\n\t\tthis._context._addEditor( this, !config.context );\n\n\t\t// Clone the plugins to make sure that the plugin array will not be shared\n\t\t// between editors and make the watchdog feature work correctly.\n\t\tconst availablePlugins = Array.from( constructor.builtinPlugins || [] );\n\n\t\tthis.config = new Config<EditorConfig>( rest, defaultConfig );\n\t\tthis.config.define( 'plugins', availablePlugins );\n\t\tthis.config.define( this._context._getEditorConfig() );\n\n\t\tthis.plugins = new PluginCollection<Editor>( this, availablePlugins, this._context.plugins );\n\n\t\tthis.locale = this._context.locale;\n\t\tthis.t = this.locale.t;\n\n\t\tthis._readOnlyLocks = new Set();\n\n\t\tthis.commands = new CommandCollection();\n\n\t\tthis.set( 'state', 'initializing' );\n\t\tthis.once<EditorReadyEvent>( 'ready', () => ( this.state = 'ready' ), { priority: 'high' } );\n\t\tthis.once<EditorDestroyEvent>( 'destroy', () => ( this.state = 'destroyed' ), { priority: 'high' } );\n\n\t\tthis.model = new Model();\n\n\t\tthis.on( 'change:isReadOnly', () => {\n\t\t\tthis.model.document.isReadOnly = this.isReadOnly;\n\t\t} );\n\n\t\tconst stylesProcessor = new StylesProcessor();\n\n\t\tthis.data = new DataController( this.model, stylesProcessor );\n\n\t\tthis.editing = new EditingController( this.model, stylesProcessor );\n\t\tthis.editing.view.document.bind( 'isReadOnly' ).to( this );\n\n\t\tthis.conversion = new Conversion( [ this.editing.downcastDispatcher, this.data.downcastDispatcher ], this.data.upcastDispatcher );\n\t\tthis.conversion.addAlias( 'dataDowncast', this.data.downcastDispatcher );\n\t\tthis.conversion.addAlias( 'editingDowncast', this.editing.downcastDispatcher );\n\n\t\tthis.keystrokes = new EditingKeystrokeHandler( this );\n\t\tthis.keystrokes.listenTo( this.editing.view.document );\n\n\t\tthis.accessibility = new Accessibility( this );\n\t}\n\n\t/**\n\t * Defines whether the editor is in the read-only mode.\n\t *\n\t * In read-only mode the editor {@link #commands commands} are disabled so it is not possible\n\t * to modify the document by using them. Also, the editable element(s) become non-editable.\n\t *\n\t * In order to make the editor read-only, you need to call the {@link #enableReadOnlyMode} method:\n\t *\n\t * ```ts\n\t * editor.enableReadOnlyMode( 'feature-id' );\n\t * ```\n\t *\n     * Later, to turn off the read-only mode, call {@link #disableReadOnlyMode}:\n\t *\n\t * ```ts\n\t * editor.disableReadOnlyMode( 'feature-id' );\n\t * ```\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tpublic get isReadOnly(): boolean {\n\t\treturn this._readOnlyLocks.size > 0;\n\t}\n\n\tpublic set isReadOnly( value: boolean ) {\n\t\t/**\n\t\t * The {@link module:core/editor/editor~Editor#isReadOnly Editor#isReadOnly} property is read-only since version `34.0.0`\n\t\t * and can be set only using {@link module:core/editor/editor~Editor#enableReadOnlyMode `Editor#enableReadOnlyMode( lockId )`} and\n\t\t * {@link module:core/editor/editor~Editor#disableReadOnlyMode `Editor#disableReadOnlyMode( lockId )`}.\n\t\t *\n\t\t * Usage before version `34.0.0`:\n\t\t *\n\t\t * ```ts\n\t\t * editor.isReadOnly = true;\n\t\t * editor.isReadOnly = false;\n\t\t * ```\n\t\t *\n\t\t * Usage since version `34.0.0`:\n\t\t *\n\t\t * ```ts\n\t\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t\t * editor.disableReadOnlyMode( 'my-feature-id' );\n\t\t * ```\n\t\t *\n\t\t * @error editor-isreadonly-has-no-setter\n\t\t */\n\t\tthrow new CKEditorError( 'editor-isreadonly-has-no-setter' );\n\t}\n\n\t/**\n\t * Turns on the read-only mode in the editor.\n\t *\n\t * Editor can be switched to or out of the read-only mode by many features, under various circumstances. The editor supports locking\n\t * mechanism for the read-only mode. It enables easy control over the read-only mode when many features wants to turn it on or off at\n\t * the same time, without conflicting with each other. It guarantees that you will not make the editor editable accidentally (which\n\t * could lead to errors).\n\t *\n\t * Each read-only mode request is identified by a unique id (also called \"lock\"). If multiple plugins requested to turn on the\n\t * read-only mode, then, the editor will become editable only after all these plugins turn the read-only mode off (using the same ids).\n\t *\n\t * Note, that you cannot force the editor to disable the read-only mode if other plugins set it.\n\t *\n\t * After the first `enableReadOnlyMode()` call, the {@link #isReadOnly `isReadOnly` property} will be set to `true`:\n\t *\n\t * ```ts\n\t * editor.isReadOnly; // `false`.\n\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t * editor.isReadOnly; // `true`.\n\t * ```\n\t *\n\t * You can turn off the read-only mode (\"clear the lock\") using the {@link #disableReadOnlyMode `disableReadOnlyMode()`} method:\n\t *\n\t * ```ts\n\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t * // ...\n\t * editor.disableReadOnlyMode( 'my-feature-id' );\n\t * editor.isReadOnly; // `false`.\n\t * ```\n\t *\n\t * All \"locks\" need to be removed to enable editing:\n\t *\n\t * ```ts\n\t * editor.enableReadOnlyMode( 'my-feature-id' );\n\t * editor.enableReadOnlyMode( 'my-other-feature-id' );\n\t * // ...\n\t * editor.disableReadOnlyMode( 'my-feature-id' );\n\t * editor.isReadOnly; // `true`.\n\t * editor.disableReadOnlyMode( 'my-other-feature-id' );\n\t * editor.isReadOnly; // `false`.\n\t * ```\n\t *\n\t * @param lockId A unique ID for setting the editor to the read-only state.\n\t */\n\tpublic enableReadOnlyMode( lockId: string | symbol ): void {\n\t\tif ( typeof lockId !== 'string' && typeof lockId !== 'symbol' ) {\n\t\t\t/**\n\t\t\t * The lock ID is missing or it is not a string or symbol.\n\t\t\t *\n\t\t\t * @error editor-read-only-lock-id-invalid\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'editor-read-only-lock-id-invalid', null, { lockId } );\n\t\t}\n\n\t\tif ( this._readOnlyLocks.has( lockId ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._readOnlyLocks.add( lockId );\n\n\t\tif ( this._readOnlyLocks.size === 1 ) {\n\t\t\t// Manually fire the `change:isReadOnly` event as only getter is provided.\n\t\t\tthis.fire<ObservableChangeEvent<boolean>>( 'change:isReadOnly', 'isReadOnly', true, false );\n\t\t}\n\t}\n\n\t/**\n\t * Removes the read-only lock from the editor with given lock ID.\n\t *\n\t * When no lock is present on the editor anymore, then the {@link #isReadOnly `isReadOnly` property} will be set to `false`.\n\t *\n\t * @param lockId The lock ID for setting the editor to the read-only state.\n\t */\n\tpublic disableReadOnlyMode( lockId: string | symbol ): void {\n\t\tif ( typeof lockId !== 'string' && typeof lockId !== 'symbol' ) {\n\t\t\tthrow new CKEditorError( 'editor-read-only-lock-id-invalid', null, { lockId } );\n\t\t}\n\n\t\tif ( !this._readOnlyLocks.has( lockId ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._readOnlyLocks.delete( lockId );\n\n\t\tif ( this._readOnlyLocks.size === 0 ) {\n\t\t\t// Manually fire the `change:isReadOnly` event as only getter is provided.\n\t\t\tthis.fire<ObservableChangeEvent<boolean>>( 'change:isReadOnly', 'isReadOnly', false, true );\n\t\t}\n\t}\n\n\t/**\n\t * Sets the data in the editor.\n\t *\n\t * ```ts\n\t * editor.setData( '<p>This is editor!</p>' );\n\t * ```\n\t *\n\t * If your editor implementation uses multiple roots, you should pass an object with keys corresponding\n\t * to the editor root names and values equal to the data that should be set in each root:\n\t *\n\t * ```ts\n\t * editor.setData( {\n\t *     header: '<p>Content for header part.</p>',\n\t *     content: '<p>Content for main part.</p>',\n\t *     footer: '<p>Content for footer part.</p>'\n\t * } );\n\t * ```\n\t *\n\t * By default the editor accepts HTML. This can be controlled by injecting a different data processor.\n\t * See the {@glink features/markdown Markdown output} guide for more details.\n\t *\n\t * @param data Input data.\n\t */\n\tpublic setData( data: string | Record<string, string> ): void {\n\t\tthis.data.set( data );\n\t}\n\n\t/**\n\t * Gets the data from the editor.\n\t *\n\t * ```ts\n\t * editor.getData(); // -> '<p>This is editor!</p>'\n\t * ```\n\t *\n\t * If your editor implementation uses multiple roots, you should pass root name as one of the options:\n\t *\n\t * ```ts\n\t * editor.getData( { rootName: 'header' } ); // -> '<p>Content for header part.</p>'\n\t * ```\n\t *\n\t * By default, the editor outputs HTML. This can be controlled by injecting a different data processor.\n\t * See the {@glink features/markdown Markdown output} guide for more details.\n\t *\n\t * A warning is logged when you try to retrieve data for a detached root, as most probably this is a mistake. A detached root should\n\t * be treated like it is removed, and you should not save its data. Note, that the detached root data is always an empty string.\n\t *\n\t * @param options Additional configuration for the retrieved data.\n\t * Editor features may introduce more configuration options that can be set through this parameter.\n\t * @param options.rootName Root name. Defaults to `'main'`.\n\t * @param options.trim Whether returned data should be trimmed. This option is set to `'empty'` by default,\n\t * which means that whenever editor content is considered empty, an empty string is returned. To turn off trimming\n\t * use `'none'`. In such cases exact content will be returned (for example `'<p>&nbsp;</p>'` for an empty editor).\n\t * @returns Output data.\n\t */\n\tpublic getData( options?: {\n\t\trootName?: string;\n\t\ttrim?: 'empty' | 'none';\n\t\t[ key: string ]: unknown;\n\t} ): string {\n\t\treturn this.data.get( options );\n\t}\n\n\t/**\n\t * Loads and initializes plugins specified in the configuration.\n\t *\n\t * @returns A promise which resolves once the initialization is completed, providing an array of loaded plugins.\n\t */\n\tpublic initPlugins(): Promise<LoadedPlugins> {\n\t\tconst config = this.config;\n\t\tconst plugins = config.get( 'plugins' )!;\n\t\tconst removePlugins = config.get( 'removePlugins' ) || [];\n\t\tconst extraPlugins = config.get( 'extraPlugins' ) || [];\n\t\tconst substitutePlugins = config.get( 'substitutePlugins' ) || [];\n\n\t\treturn this.plugins.init( plugins.concat( extraPlugins ), removePlugins, substitutePlugins );\n\t}\n\n\t/**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * **Note** The editor cannot be destroyed during the initialization phase so if it is called\n\t * while the editor {@link #state is being initialized}, it will wait for the editor initialization before destroying it.\n\t *\n\t * @fires destroy\n\t * @returns A promise that resolves once the editor instance is fully destroyed.\n\t */\n\tpublic destroy(): Promise<unknown> {\n\t\tlet readyPromise: Promise<unknown> = Promise.resolve();\n\n\t\tif ( this.state == 'initializing' ) {\n\t\t\treadyPromise = new Promise( resolve => this.once<EditorReadyEvent>( 'ready', resolve ) );\n\t\t}\n\n\t\treturn readyPromise\n\t\t\t.then( () => {\n\t\t\t\tthis.fire<EditorDestroyEvent>( 'destroy' );\n\t\t\t\tthis.stopListening();\n\t\t\t\tthis.commands.destroy();\n\t\t\t} )\n\t\t\t.then( () => this.plugins.destroy() )\n\t\t\t.then( () => {\n\t\t\t\tthis.model.destroy();\n\t\t\t\tthis.data.destroy();\n\t\t\t\tthis.editing.destroy();\n\t\t\t\tthis.keystrokes.destroy();\n\t\t\t} )\n\t\t\t// Remove the editor from the context.\n\t\t\t// When the context was created by this editor, the context will be destroyed.\n\t\t\t.then( () => this._context._removeEditor( this ) );\n\t}\n\n\t/**\n\t * Executes the specified command with given parameters.\n\t *\n\t * Shorthand for:\n\t *\n\t * ```ts\n\t * editor.commands.get( commandName ).execute( ... );\n\t * ```\n\t *\n\t * @param commandName The name of the command to execute.\n\t * @param commandParams Command parameters.\n\t * @returns The value returned by the {@link module:core/commandcollection~CommandCollection#execute `commands.execute()`}.\n\t */\n\tpublic execute<TName extends string>(\n\t\tcommandName: TName,\n\t\t...commandParams: Parameters<CommandsMap[ TName ][ 'execute' ]>\n\t): ReturnType<CommandsMap[ TName ][ 'execute' ]> {\n\t\ttry {\n\t\t\treturn this.commands.execute( commandName, ...commandParams );\n\t\t} catch ( err: any ) {\n\t\t\t// @if CK_DEBUG // throw err;\n\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\tCKEditorError.rethrowUnexpectedError( err, this );\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the editor.\n\t *\n\t * **Note** To explicitly focus the editing area of the editor, use the\n\t * {@link module:engine/view/view~View#focus `editor.editing.view.focus()`} method of the editing view.\n\t *\n\t * Check out the {@glink framework/deep-dive/ui/focus-tracking#focus-in-the-editor-ui Focus in the editor UI} section\n\t * of the {@glink framework/deep-dive/ui/focus-tracking Deep dive into focus tracking} guide to learn more.\n\t */\n\tpublic focus(): void {\n\t\tthis.editing.view.focus();\n\t}\n\n\t/* istanbul ignore next -- @preserve */\n\t/**\n\t * Creates and initializes a new editor instance.\n\t *\n\t * This is an abstract method. Every editor type needs to implement its own initialization logic.\n\t *\n\t * See the `create()` methods of the existing editor types to learn how to use them:\n\t *\n\t * * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}\n\t * * {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`}\n\t * * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`}\n\t * * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`}\n\t */\n\tpublic static create( ...args: Array<unknown> ): void { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tthrow new Error( 'This is an abstract method.' );\n\t}\n\n\t/**\n\t * The {@link module:core/context~Context} class.\n\t *\n\t * Exposed as static editor field for easier access in editor builds.\n\t */\n\tpublic static Context = Context;\n\n\t/**\n\t * The {@link module:watchdog/editorwatchdog~EditorWatchdog} class.\n\t *\n\t * Exposed as static editor field for easier access in editor builds.\n\t */\n\tpublic static EditorWatchdog = EditorWatchdog;\n\n\t/**\n\t * The {@link module:watchdog/contextwatchdog~ContextWatchdog} class.\n\t *\n\t * Exposed as static editor field for easier access in editor builds.\n\t */\n\tpublic static ContextWatchdog = ContextWatchdog;\n}\n\n/**\n * Fired when the {@link module:engine/controller/datacontroller~DataController#event:ready data} and all additional\n * editor components are ready.\n *\n * Note: This event is most useful for plugin developers. When integrating the editor with your website or\n * application, you do not have to listen to `editor#ready` because when the promise returned by the static\n * {@link module:core/editor/editor~Editor.create `Editor.create()`} event is resolved, the editor is already ready.\n * In fact, since the first moment when the editor instance is available to you is inside `then()`'s callback,\n * you cannot even add a listener to the `editor#ready` event.\n *\n * See also the {@link module:core/editor/editor~Editor#state `editor.state`} property.\n *\n * @eventName ~Editor#ready\n */\nexport type EditorReadyEvent = {\n\tname: 'ready';\n\targs: [];\n};\n\n/**\n * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to\n * perform the clean-up in any plugin.\n *\n * See also the {@link module:core/editor/editor~Editor#state `editor.state`} property.\n *\n * @eventName ~Editor#destroy\n */\nexport type EditorDestroyEvent = {\n\tname: 'destroy';\n\targs: [];\n};\n\n/**\n * This error is thrown when trying to pass a `<textarea>` element to a `create()` function of an editor class.\n *\n * The only editor type which can be initialized on `<textarea>` elements is\n * the {@glink getting-started/setup/editor-types#classic-editor classic editor}.\n * This editor hides the passed element and inserts its own UI next to it. Other types of editors reuse the passed element as their root\n * editable element and therefore `<textarea>` is not appropriate for them. Use a `<div>` or another text container instead:\n *\n * ```html\n * <div id=\"editor\">\n * \t<p>Initial content.</p>\n * </div>\n * ```\n *\n * @error editor-wrong-element\n */\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editor/utils/attachtoform\n */\n\nimport { isFunction } from 'lodash-es';\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type { default as Editor, EditorDestroyEvent } from '../editor.js';\nimport type { ElementApi } from './elementapimixin.js';\n\n/**\n * Checks if the editor is initialized on a `<textarea>` element that belongs to a form. If yes, it updates the editor's element\n * content before submitting the form.\n *\n * This helper requires the {@link module:core/editor/utils/elementapimixin~ElementApi ElementApi interface}.\n *\n * @param editor Editor instance.\n */\nexport default function attachToForm( editor: Editor & ElementApi ): void {\n\tif ( !isFunction( editor.updateSourceElement ) ) {\n\t\t/**\n\t\t * The editor passed to `attachToForm()` must implement the\n\t\t * {@link module:core/editor/utils/elementapimixin~ElementApi} interface.\n\t\t *\n\t\t * @error attachtoform-missing-elementapi-interface\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'attachtoform-missing-elementapi-interface',\n\t\t\teditor\n\t\t);\n\t}\n\n\tconst sourceElement = editor.sourceElement;\n\n\t// Only when replacing a textarea which is inside of a form element.\n\tif ( isTextArea( sourceElement ) && sourceElement.form ) {\n\t\tlet originalSubmit: () => void;\n\t\tconst form = sourceElement.form;\n\t\tconst onSubmit = () => editor.updateSourceElement();\n\n\t\t// Replace the original form#submit() to call a custom submit function first.\n\t\t// Check if #submit is a function because the form might have an input named \"submit\".\n\t\tif ( isFunction( form.submit ) ) {\n\t\t\toriginalSubmit = form.submit;\n\n\t\t\tform.submit = () => {\n\t\t\t\tonSubmit();\n\t\t\t\toriginalSubmit.apply( form );\n\t\t\t};\n\t\t}\n\n\t\t// Update the replaced textarea with data before each form#submit event.\n\t\tform.addEventListener( 'submit', onSubmit );\n\n\t\t// Remove the submit listener and revert the original submit method on\n\t\t// editor#destroy.\n\t\teditor.on<EditorDestroyEvent>( 'destroy', () => {\n\t\t\tform.removeEventListener( 'submit', onSubmit );\n\n\t\t\tif ( originalSubmit ) {\n\t\t\t\tform.submit = originalSubmit;\n\t\t\t}\n\t\t} );\n\t}\n}\n\nfunction isTextArea( sourceElement: HTMLElement | undefined ): sourceElement is HTMLTextAreaElement {\n\treturn !!sourceElement && sourceElement.tagName.toLowerCase() === 'textarea';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editor/utils/dataapimixin\n */\n\nimport type Editor from '../editor.js';\n\nimport type { Constructor } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Implementation of the {@link module:core/editor/utils/dataapimixin~DataApi}.\n *\n * @deprecated This functionality is already implemented by the `Editor` class.\n */\nexport default function DataApiMixin<Base extends Constructor<Editor>>( base: Base ): Base {\n\treturn base;\n}\n\n/**\n * Interface defining editor methods for setting and getting data to and from the editor's main root element\n * using the {@link module:core/editor/editor~Editor#data data pipeline}.\n *\n * This interface is not a part of the {@link module:core/editor/editor~Editor} class because one may want to implement\n * an editor with multiple root elements, in which case the methods for setting and getting data will need to be implemented\n * differently.\n *\n * @deprecated This interface is implemented by all `Editor` instances by default.\n */\nexport interface DataApi {\n\n\t/**\n\t * Sets the data in the editor.\n\t *\n\t * ```ts\n\t * editor.setData( '<p>This is editor!</p>' );\n\t * ```\n\t *\n\t * If your editor implementation uses multiple roots, you should pass an object with keys corresponding\n\t * to the editor root names and values equal to the data that should be set in each root:\n\t *\n\t * ```ts\n\t * editor.setData( {\n\t *     header: '<p>Content for header part.</p>',\n\t *     content: '<p>Content for main part.</p>',\n\t *     footer: '<p>Content for footer part.</p>'\n\t * } );\n\t * ```\n\t *\n\t * By default the editor accepts HTML. This can be controlled by injecting a different data processor.\n\t * See the {@glink features/markdown Markdown output} guide for more details.\n\t *\n\t * @param data Input data.\n\t */\n\tsetData( data: string | Record<string, string> ): void;\n\n\t/**\n\t * Gets the data from the editor.\n\t *\n\t * ```ts\n\t * editor.getData(); // -> '<p>This is editor!</p>'\n\t * ```\n\t *\n\t * If your editor implementation uses multiple roots, you should pass root name as one of the options:\n\t *\n\t * ```ts\n\t * editor.getData( { rootName: 'header' } ); // -> '<p>Content for header part.</p>'\n\t * ```\n\t *\n\t * By default, the editor outputs HTML. This can be controlled by injecting a different data processor.\n\t * See the {@glink features/markdown Markdown output} guide for more details.\n\t *\n\t * A warning is logged when you try to retrieve data for a detached root, as most probably this is a mistake. A detached root should\n\t * be treated like it is removed, and you should not save its data. Note, that the detached root data is always an empty string.\n\t *\n\t * @param options Additional configuration for the retrieved data.\n\t * Editor features may introduce more configuration options that can be set through this parameter.\n\t * @param options.rootName Root name. Default to `'main'`.\n\t * @param options.trim Whether returned data should be trimmed. This option is set to `'empty'` by default,\n\t * which means that whenever editor content is considered empty, an empty string is returned. To turn off trimming\n\t * use `'none'`. In such cases exact content will be returned (for example `'<p>&nbsp;</p>'` for an empty editor).\n\t * @returns Output data.\n\t */\n\tgetData( options?: Record<string, unknown> ): string;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editor/utils/elementapimixin\n */\n\nimport {\n\tCKEditorError,\n\tsetDataInElement,\n\ttype Constructor,\n\ttype Mixed\n} from '@ckeditor/ckeditor5-utils';\n\nimport type Editor from '../editor.js';\n\n/**\n * Implementation of the {@link module:core/editor/utils/elementapimixin~ElementApi}.\n */\nexport default function ElementApiMixin<Base extends Constructor<Editor>>( base: Base ): Mixed<Base, ElementApi> {\n\tabstract class Mixin extends base implements ElementApi {\n\t\tpublic sourceElement: HTMLElement | undefined;\n\n\t\tpublic updateSourceElement( data?: string ): void {\n\t\t\tif ( !this.sourceElement ) {\n\t\t\t\t/**\n\t\t\t\t * Cannot update the source element of a detached editor.\n\t\t\t\t *\n\t\t\t\t * The {@link module:core/editor/utils/elementapimixin~ElementApi#updateSourceElement `updateSourceElement()`}\n\t\t\t\t * method cannot be called if you did not pass an element to `Editor.create()`.\n\t\t\t\t *\n\t\t\t\t * @error editor-missing-sourceelement\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'editor-missing-sourceelement',\n\t\t\t\t\tthis\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst shouldUpdateSourceElement = this.config.get( 'updateSourceElementOnDestroy' );\n\t\t\tconst isSourceElementTextArea = this.sourceElement instanceof HTMLTextAreaElement;\n\n\t\t\t// The data returned by the editor might be unsafe, so we want to prevent rendering\n\t\t\t// unsafe content inside the source element different than <textarea>, which is considered\n\t\t\t// secure. This behavior could be changed by setting the `updateSourceElementOnDestroy`\n\t\t\t// configuration option to `true`.\n\t\t\tif ( !shouldUpdateSourceElement && !isSourceElementTextArea ) {\n\t\t\t\tsetDataInElement( this.sourceElement, '' );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst dataToSet = typeof data === 'string' ? data : this.data.get();\n\n\t\t\tsetDataInElement( this.sourceElement, dataToSet );\n\t\t}\n\t}\n\n\treturn Mixin as any;\n}\n\n// Backward compatibility with `mix`.\n( ElementApiMixin as any ).updateSourceElement = ( ElementApiMixin as any )( Object ).prototype.updateSourceElement;\n\n/**\n * Interface describing an editor that replaced a DOM element (was \"initialized on an element\").\n *\n * Such an editor should provide a method to\n * {@link module:core/editor/utils/elementapimixin~ElementApi#updateSourceElement update the replaced element with the current data}.\n */\nexport interface ElementApi {\n\n\t/**\n\t * The element on which the editor has been initialized.\n\t *\n\t * @readonly\n\t */\n\tsourceElement: HTMLElement | undefined;\n\n\t/**\n\t * Updates the {@link #sourceElement editor source element}'s content with the data if the\n\t * {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy `updateSourceElementOnDestroy`}\n\t * configuration option is set to `true`.\n\t *\n\t * @param data Data that the {@link #sourceElement editor source element} should be updated with.\n\t */\n\tupdateSourceElement( data?: string ): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editor/utils/securesourceelement\n */\n\nimport { CKEditorError } from '@ckeditor/ckeditor5-utils';\n\nimport type { default as Editor, EditorDestroyEvent } from '../editor.js';\n\n/**\n * Marks the source element on which the editor was initialized. This prevents other editor instances from using this element.\n *\n * Running multiple editor instances on the same source element causes various issues and it is\n * crucial this helper is called as soon as the source element is known to prevent collisions.\n *\n * @param editor Editor instance.\n * @param sourceElement Element to bind with the editor instance.\n */\nexport default function secureSourceElement( editor: Editor, sourceElement: HTMLElement & { ckeditorInstance?: Editor } ): void {\n\tif ( sourceElement.ckeditorInstance ) {\n\t\t/**\n\t\t * A DOM element used to create the editor (e.g.\n\t\t * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`})\n\t\t * has already been used to create another editor instance. Make sure each editor is\n\t\t * created with an unique DOM element.\n\t\t *\n\t\t * @error editor-source-element-already-used\n\t\t * @param element DOM element that caused the collision.\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'editor-source-element-already-used',\n\t\t\teditor\n\t\t);\n\t}\n\n\tsourceElement.ckeditorInstance = editor;\n\n\teditor.once<EditorDestroyEvent>( 'destroy', () => {\n\t\tdelete sourceElement.ckeditorInstance;\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/pendingactions\n */\n\nimport ContextPlugin from './contextplugin.js';\n\nimport {\n\tCKEditorError,\n\tCollection,\n\tObservableMixin,\n\ttype CollectionAddEvent,\n\ttype CollectionRemoveEvent,\n\ttype Observable\n} from '@ckeditor/ckeditor5-utils';\n\n/**\n * The list of pending editor actions.\n *\n * This plugin should be used to synchronise plugins that execute long-lasting actions\n * (e.g. file upload) with the editor integration. It gives the developer who integrates the editor\n * an easy way to check if there are any actions pending whenever such information is needed.\n * All plugins that register a pending action also provide a message about the action that is ongoing\n * which can be displayed to the user. This lets them decide if they want to interrupt the action or wait.\n *\n * Adding and updating a pending action:\n *\n * ```ts\n * const pendingActions = editor.plugins.get( 'PendingActions' );\n * const action = pendingActions.add( 'Upload in progress: 0%.' );\n *\n * // You can update the message:\n * action.message = 'Upload in progress: 10%.';\n * ```\n *\n * Removing a pending action:\n *\n * ```ts\n * const pendingActions = editor.plugins.get( 'PendingActions' );\n * const action = pendingActions.add( 'Unsaved changes.' );\n *\n * pendingActions.remove( action );\n * ```\n *\n * Getting pending actions:\n *\n * ```ts\n * const pendingActions = editor.plugins.get( 'PendingActions' );\n *\n * const action1 = pendingActions.add( 'Action 1' );\n * const action2 = pendingActions.add( 'Action 2' );\n *\n * pendingActions.first; // Returns action1\n * Array.from( pendingActions ); // Returns [ action1, action2 ]\n * ```\n *\n * This plugin is used by features like {@link module:upload/filerepository~FileRepository} to register their ongoing actions\n * and by features like {@link module:autosave/autosave~Autosave} to detect whether there are any ongoing actions.\n * Read more about saving the data in the\n * {@glink getting-started/setup/getting-and-setting-data Saving and getting data} guide.\n */\nexport default class PendingActions extends ContextPlugin implements Iterable<PendingAction> {\n\t/**\n\t * Defines whether there is any registered pending action.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public hasAny: boolean;\n\n\t/**\n\t * A list of pending actions.\n\t */\n\tprivate _actions!: Collection<PendingAction>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'PendingActions' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tthis.set( 'hasAny', false );\n\n\t\tthis._actions = new Collection( { idProperty: '_id' } );\n\t\tthis._actions.delegate( 'add', 'remove' ).to( this );\n\t}\n\n\t/**\n\t * Adds an action to the list of pending actions.\n\t *\n\t * This method returns an action object with an observable message property.\n\t * The action object can be later used in the {@link #remove} method. It also allows you to change the message.\n\t *\n\t * @param message The action message.\n\t * @returns An observable object that represents a pending action.\n\t */\n\tpublic add( message: string ): PendingAction {\n\t\tif ( typeof message !== 'string' ) {\n\t\t\t/**\n\t\t\t * The message must be a string.\n\t\t\t *\n\t\t\t * @error pendingactions-add-invalid-message\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'pendingactions-add-invalid-message', this );\n\t\t}\n\n\t\tconst action = new ( ObservableMixin() )() as PendingAction;\n\n\t\taction.set( 'message', message );\n\t\tthis._actions.add( action );\n\t\tthis.hasAny = true;\n\n\t\treturn action;\n\t}\n\n\t/**\n\t * Removes an action from the list of pending actions.\n\t *\n\t * @param action An action object.\n\t */\n\tpublic remove( action: PendingAction ): void {\n\t\tthis._actions.remove( action );\n\t\tthis.hasAny = !!this._actions.length;\n\t}\n\n\t/**\n\t * Returns the first action from the list or null if the list is empty\n\t *\n\t * @returns The pending action object.\n\t */\n\tpublic get first(): PendingAction | null {\n\t\treturn this._actions.get( 0 );\n\t}\n\n\t/**\n\t * Iterable interface.\n\t */\n\tpublic [ Symbol.iterator ](): Iterator<PendingAction> {\n\t\treturn this._actions[ Symbol.iterator ]();\n\t}\n}\n\nexport interface PendingAction extends Observable {\n\tmessage: string;\n}\n\n/**\n * Fired when an action is added to the list.\n *\n * @eventName ~PendingActions#add\n * @param action The added action.\n */\nexport type PendingActionsAddEvent = CollectionAddEvent<PendingAction>;\n\n/**\n * Fired when an action is removed from the list.\n *\n * @eventName ~PendingActions#remove\n * @param action The removed action.\n */\nexport type PendingActionsRemoveEvent = CollectionRemoveEvent<PendingAction>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core\n */\n\nexport { default as Plugin, type PluginDependencies, type PluginConstructor } from './plugin.js';\nexport { default as Command, type CommandExecuteEvent } from './command.js';\nexport { default as MultiCommand } from './multicommand.js';\nexport type { CommandsMap } from './commandcollection.js';\nexport type { PluginsMap, default as PluginCollection } from './plugincollection.js';\n\nexport { default as Context, type ContextConfig } from './context.js';\nexport { default as ContextPlugin, type ContextPluginDependencies } from './contextplugin.js';\nexport { type EditingKeystrokeCallback } from './editingkeystrokehandler.js';\n\nexport type { PartialBy, NonEmptyArray, HexColor } from './typings.js';\n\nexport { default as Editor, type EditorReadyEvent, type EditorDestroyEvent } from './editor/editor.js';\nexport type {\n\tEditorConfig,\n\tLanguageConfig,\n\tToolbarConfig,\n\tToolbarConfigItem,\n\tUiConfig\n} from './editor/editorconfig.js';\n\nexport { default as attachToForm } from './editor/utils/attachtoform.js';\nexport { default as DataApiMixin, type DataApi } from './editor/utils/dataapimixin.js';\nexport { default as ElementApiMixin, type ElementApi } from './editor/utils/elementapimixin.js';\nexport { default as secureSourceElement } from './editor/utils/securesourceelement.js';\n\nexport { default as PendingActions, type PendingAction } from './pendingactions.js';\n\nexport type {\n\tKeystrokeInfos as KeystrokeInfoDefinitions,\n\tKeystrokeInfoGroup as KeystrokeInfoGroupDefinition,\n\tKeystrokeInfoCategory as KeystrokeInfoCategoryDefinition,\n\tKeystrokeInfoDefinition as KeystrokeInfoDefinition\n} from './accessibility.js';\n\nimport cancel from './../theme/icons/cancel.svg';\nimport caption from './../theme/icons/caption.svg';\nimport check from './../theme/icons/check.svg';\nimport cog from './../theme/icons/cog.svg';\nimport colorPalette from './../theme/icons/color-palette.svg';\nimport eraser from './../theme/icons/eraser.svg';\nimport history from './../theme/icons/history.svg';\nimport lowVision from './../theme/icons/low-vision.svg';\nimport textAlternative from './../theme/icons/text-alternative.svg';\nimport loupe from './../theme/icons/loupe.svg';\nimport previousArrow from './../theme/icons/previous-arrow.svg';\nimport nextArrow from './../theme/icons/next-arrow.svg';\nimport image from './../theme/icons/image.svg';\nimport imageUpload from './../theme/icons/image-upload.svg';\nimport imageAssetManager from './../theme/icons/image-asset-manager.svg';\nimport imageUrl from './../theme/icons/image-url.svg';\n\nimport alignBottom from './../theme/icons/align-bottom.svg';\nimport alignMiddle from './../theme/icons/align-middle.svg';\nimport alignTop from './../theme/icons/align-top.svg';\nimport alignLeft from './../theme/icons/align-left.svg';\nimport alignCenter from './../theme/icons/align-center.svg';\nimport alignRight from './../theme/icons/align-right.svg';\nimport alignJustify from './../theme/icons/align-justify.svg';\n\nimport objectBlockLeft from './../theme/icons/object-left.svg';\nimport objectCenter from './../theme/icons/object-center.svg';\nimport objectBlockRight from './../theme/icons/object-right.svg';\nimport objectFullWidth from './../theme/icons/object-full-width.svg';\nimport objectInline from './../theme/icons/object-inline.svg';\nimport objectLeft from './../theme/icons/object-inline-left.svg';\nimport objectRight from './../theme/icons/object-inline-right.svg';\n\nimport objectSizeFull from './../theme/icons/object-size-full.svg';\nimport objectSizeCustom from './../theme/icons/object-size-custom.svg';\nimport objectSizeLarge from './../theme/icons/object-size-large.svg';\nimport objectSizeSmall from './../theme/icons/object-size-small.svg';\nimport objectSizeMedium from './../theme/icons/object-size-medium.svg';\n\nimport pencil from './../theme/icons/pencil.svg';\nimport pilcrow from './../theme/icons/pilcrow.svg';\nimport quote from './../theme/icons/quote.svg';\nimport threeVerticalDots from './../theme/icons/three-vertical-dots.svg';\nimport dragIndicator from './../theme/icons/drag-indicator.svg';\n\nimport bold from './../theme/icons/bold.svg';\nimport paragraph from './../theme/icons/paragraph.svg';\nimport plus from './../theme/icons/plus.svg';\nimport text from './../theme/icons/text.svg';\nimport importExport from './../theme/icons/importexport.svg';\n\nimport redo from './../theme/icons/redo.svg';\nimport undo from './../theme/icons/undo.svg';\n\nimport bulletedList from './../theme/icons/bulletedlist.svg';\nimport numberedList from './../theme/icons/numberedlist.svg';\nimport todoList from './../theme/icons/todolist.svg';\n\nimport codeBlock from './../theme/icons/codeblock.svg';\n\nimport browseFiles from './../theme/icons/browse-files.svg';\n\nimport heading1 from './../theme/icons/heading1.svg';\nimport heading2 from './../theme/icons/heading2.svg';\nimport heading3 from './../theme/icons/heading3.svg';\nimport heading4 from './../theme/icons/heading4.svg';\nimport heading5 from './../theme/icons/heading5.svg';\nimport heading6 from './../theme/icons/heading6.svg';\n\nimport horizontalLine from './../theme/icons/horizontalline.svg';\n\nimport html from './../theme/icons/html.svg';\n\nimport indent from './../theme/icons/indent.svg';\nimport outdent from './../theme/icons/outdent.svg';\n\nimport table from './../theme/icons/table.svg';\n\nexport const icons = {\n\tbold,\n\tcancel,\n\tcaption,\n\tcheck,\n\tcog,\n\tcolorPalette,\n\teraser,\n\thistory,\n\timage,\n\timageUpload,\n\timageAssetManager,\n\timageUrl,\n\tlowVision,\n\ttextAlternative,\n\tloupe,\n\tpreviousArrow,\n\tnextArrow,\n\timportExport,\n\tparagraph,\n\tplus,\n\ttext,\n\n\talignBottom,\n\talignMiddle,\n\talignTop,\n\talignLeft,\n\talignCenter,\n\talignRight,\n\talignJustify,\n\n\tobjectLeft,\n\tobjectCenter,\n\tobjectRight,\n\tobjectFullWidth,\n\tobjectInline,\n\tobjectBlockLeft,\n\tobjectBlockRight,\n\n\tobjectSizeCustom,\n\tobjectSizeFull,\n\tobjectSizeLarge,\n\tobjectSizeSmall,\n\tobjectSizeMedium,\n\n\tpencil,\n\tpilcrow,\n\tquote,\n\tthreeVerticalDots,\n\tdragIndicator,\n\n\tredo,\n\tundo,\n\n\tbulletedList,\n\tnumberedList,\n\ttodoList,\n\n\tcodeBlock,\n\n\tbrowseFiles,\n\n\theading1,\n\theading2,\n\theading3,\n\theading4,\n\theading5,\n\theading6,\n\n\thorizontalLine,\n\n\thtml,\n\n\tindent,\n\toutdent,\n\n\ttable\n};\n\nimport './augmentation.js';\n", "import { Plugin, PendingActions } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { ObservableMixin, Collection, logWarning, uid, CKEditorError } from '@ckeditor/ckeditor5-utils/dist/index.js';\n\n/**\n * Wrapper over the native `FileReader`.\n */ class FileReader extends /* #__PURE__ */ ObservableMixin() {\n    total;\n    /**\n\t * Instance of native FileReader.\n\t */ _reader;\n    /**\n\t * Holds the data of an already loaded file. The file must be first loaded\n\t * by using {@link module:upload/filereader~FileReader#read `read()`}.\n\t */ _data;\n    /**\n\t * Creates an instance of the FileReader.\n\t */ constructor(){\n        super();\n        const reader = new window.FileReader();\n        this._reader = reader;\n        this._data = undefined;\n        this.set('loaded', 0);\n        reader.onprogress = (evt)=>{\n            this.loaded = evt.loaded;\n        };\n    }\n    /**\n\t * Returns error that occurred during file reading.\n\t */ get error() {\n        return this._reader.error;\n    }\n    /**\n\t * Holds the data of an already loaded file. The file must be first loaded\n\t * by using {@link module:upload/filereader~FileReader#read `read()`}.\n\t */ get data() {\n        return this._data;\n    }\n    /**\n\t * Reads the provided file.\n\t *\n\t * @param file Native File object.\n\t * @returns Returns a promise that will be resolved with file's content.\n\t * The promise will be rejected in case of an error or when the reading process is aborted.\n\t */ read(file) {\n        const reader = this._reader;\n        this.total = file.size;\n        return new Promise((resolve, reject)=>{\n            reader.onload = ()=>{\n                const result = reader.result;\n                this._data = result;\n                resolve(result);\n            };\n            reader.onerror = ()=>{\n                reject('error');\n            };\n            reader.onabort = ()=>{\n                reject('aborted');\n            };\n            this._reader.readAsDataURL(file);\n        });\n    }\n    /**\n\t * Aborts file reader.\n\t */ abort() {\n        this._reader.abort();\n    }\n}\n\n/**\n * File repository plugin. A central point for managing file upload.\n *\n * To use it, first you need an upload adapter. Upload adapter's job is to handle communication with the server\n * (sending the file and handling server's response). You can use one of the existing plugins introducing upload adapters\n * (e.g. {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter} or\n * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}) or write your own one – see\n * the {@glink framework/deep-dive/upload-adapter Custom image upload adapter deep-dive} guide.\n *\n * Then, you can use {@link module:upload/filerepository~FileRepository#createLoader `createLoader()`} and the returned\n * {@link module:upload/filerepository~FileLoader} instance to load and upload files.\n */ class FileRepository extends Plugin {\n    /**\n\t * Collection of loaders associated with this repository.\n\t */ loaders = new Collection();\n    /**\n\t * Loaders mappings used to retrieve loaders references.\n\t */ _loadersMap = new Map();\n    /**\n\t * Reference to a pending action registered in a {@link module:core/pendingactions~PendingActions} plugin\n\t * while upload is in progress. When there is no upload then value is `null`.\n\t */ _pendingAction = null;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'FileRepository';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            PendingActions\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        // Keeps upload in a sync with pending actions.\n        this.loaders.on('change', ()=>this._updatePendingAction());\n        this.set('uploaded', 0);\n        this.set('uploadTotal', null);\n        this.bind('uploadedPercent').to(this, 'uploaded', this, 'uploadTotal', (uploaded, total)=>{\n            return total ? uploaded / total * 100 : 0;\n        });\n    }\n    /**\n\t * Returns the loader associated with specified file or promise.\n\t *\n\t * To get loader by id use `fileRepository.loaders.get( id )`.\n\t *\n\t * @param fileOrPromise Native file or promise handle.\n\t */ getLoader(fileOrPromise) {\n        return this._loadersMap.get(fileOrPromise) || null;\n    }\n    /**\n\t * Creates a loader instance for the given file.\n\t *\n\t * Requires {@link #createUploadAdapter} factory to be defined.\n\t *\n\t * @param fileOrPromise Native File object or native Promise object which resolves to a File.\n\t */ createLoader(fileOrPromise) {\n        if (!this.createUploadAdapter) {\n            /**\n\t\t\t * You need to enable an upload adapter in order to be able to upload files.\n\t\t\t *\n\t\t\t * This warning shows up when {@link module:upload/filerepository~FileRepository} is being used\n\t\t\t * without {@link module:upload/filerepository~FileRepository#createUploadAdapter defining an upload adapter}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the {@glink getting-started/legacy/installation-methods/predefined-builds\n\t\t\t * CKEditor 5 Builds}**\n\t\t\t * it means that you did not configure any of the upload adapters available by default in those builds.\n\t\t\t *\n\t\t\t * Predefined builds are a deprecated solution and we strongly advise\n\t\t\t * {@glink updating/nim-migration/migration-to-new-installation-methods migrating to new installation methods}.\n\t\t\t *\n\t\t\t * See the {@glink features/images/image-upload/image-upload comprehensive \"Image upload overview\"} to learn which upload\n\t\t\t * adapters are available in the builds and how to configure them.\n\t\t\t *\n\t\t\t * Otherwise, if you see this warning, there is a chance that you enabled\n\t\t\t * a feature like {@link module:image/imageupload~ImageUpload},\n\t\t\t * or {@link module:image/imageupload/imageuploadui~ImageUploadUI} but you did not enable any upload adapter.\n\t\t\t * You can choose one of the existing upload adapters listed in the\n\t\t\t * {@glink features/images/image-upload/image-upload \"Image upload overview\"}.\n\t\t\t *\n\t\t\t * You can also implement your {@glink framework/deep-dive/upload-adapter own image upload adapter}.\n\t\t\t *\n\t\t\t * @error filerepository-no-upload-adapter\n\t\t\t */ logWarning('filerepository-no-upload-adapter');\n            return null;\n        }\n        const loader = new FileLoader(Promise.resolve(fileOrPromise), this.createUploadAdapter);\n        this.loaders.add(loader);\n        this._loadersMap.set(fileOrPromise, loader);\n        // Store also file => loader mapping so loader can be retrieved by file instance returned upon Promise resolution.\n        if (fileOrPromise instanceof Promise) {\n            loader.file.then((file)=>{\n                this._loadersMap.set(file, loader);\n            })// Every then() must have a catch().\n            // File loader state (and rejections) are handled in read() and upload().\n            // Also, see the \"does not swallow the file promise rejection\" test.\n            .catch(()=>{});\n        }\n        loader.on('change:uploaded', ()=>{\n            let aggregatedUploaded = 0;\n            for (const loader of this.loaders){\n                aggregatedUploaded += loader.uploaded;\n            }\n            this.uploaded = aggregatedUploaded;\n        });\n        loader.on('change:uploadTotal', ()=>{\n            let aggregatedTotal = 0;\n            for (const loader of this.loaders){\n                if (loader.uploadTotal) {\n                    aggregatedTotal += loader.uploadTotal;\n                }\n            }\n            this.uploadTotal = aggregatedTotal;\n        });\n        return loader;\n    }\n    /**\n\t * Destroys the given loader.\n\t *\n\t * @param fileOrPromiseOrLoader File or Promise associated with that loader or loader itself.\n\t */ destroyLoader(fileOrPromiseOrLoader) {\n        const loader = fileOrPromiseOrLoader instanceof FileLoader ? fileOrPromiseOrLoader : this.getLoader(fileOrPromiseOrLoader);\n        loader._destroy();\n        this.loaders.remove(loader);\n        this._loadersMap.forEach((value, key)=>{\n            if (value === loader) {\n                this._loadersMap.delete(key);\n            }\n        });\n    }\n    /**\n\t * Registers or deregisters pending action bound with upload progress.\n\t */ _updatePendingAction() {\n        const pendingActions = this.editor.plugins.get(PendingActions);\n        if (this.loaders.length) {\n            if (!this._pendingAction) {\n                const t = this.editor.t;\n                const getMessage = (value)=>`${t('Upload in progress')} ${parseInt(value)}%.`;\n                this._pendingAction = pendingActions.add(getMessage(this.uploadedPercent));\n                this._pendingAction.bind('message').to(this, 'uploadedPercent', getMessage);\n            }\n        } else {\n            pendingActions.remove(this._pendingAction);\n            this._pendingAction = null;\n        }\n    }\n}\n/**\n * File loader class.\n *\n * It is used to control the process of reading the file and uploading it using the specified upload adapter.\n */ class FileLoader extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * Unique id of FileLoader instance.\n\t *\n\t * @readonly\n\t */ id;\n    /**\n\t * Additional wrapper over the initial file promise passed to this loader.\n\t */ _filePromiseWrapper;\n    /**\n\t * Adapter instance associated with this file loader.\n\t */ _adapter;\n    /**\n\t * FileReader used by FileLoader.\n\t */ _reader;\n    /**\n\t * Creates a new instance of `FileLoader`.\n\t *\n\t * @param filePromise A promise which resolves to a file instance.\n\t * @param uploadAdapterCreator The function which returns {@link module:upload/filerepository~UploadAdapter} instance.\n\t */ constructor(filePromise, uploadAdapterCreator){\n        super();\n        this.id = uid();\n        this._filePromiseWrapper = this._createFilePromiseWrapper(filePromise);\n        this._adapter = uploadAdapterCreator(this);\n        this._reader = new FileReader();\n        this.set('status', 'idle');\n        this.set('uploaded', 0);\n        this.set('uploadTotal', null);\n        this.bind('uploadedPercent').to(this, 'uploaded', this, 'uploadTotal', (uploaded, total)=>{\n            return total ? uploaded / total * 100 : 0;\n        });\n        this.set('uploadResponse', null);\n    }\n    /**\n\t * A `Promise` which resolves to a `File` instance associated with this file loader.\n\t */ get file() {\n        if (!this._filePromiseWrapper) {\n            // Loader was destroyed, return promise which resolves to null.\n            return Promise.resolve(null);\n        } else {\n            // The `this._filePromiseWrapper.promise` is chained and not simply returned to handle a case when:\n            //\n            //\t\t* The `loader.file.then( ... )` is called by external code (returned promise is pending).\n            //\t\t* Then `loader._destroy()` is called (call is synchronous) which destroys the `loader`.\n            //\t\t* Promise returned by the first `loader.file.then( ... )` call is resolved.\n            //\n            // Returning `this._filePromiseWrapper.promise` will still resolve to a `File` instance so there\n            // is an additional check needed in the chain to see if `loader` was destroyed in the meantime.\n            return this._filePromiseWrapper.promise.then((file)=>this._filePromiseWrapper ? file : null);\n        }\n    }\n    /**\n\t * Returns the file data. To read its data, you need for first load the file\n\t * by using the {@link module:upload/filerepository~FileLoader#read `read()`} method.\n\t */ get data() {\n        return this._reader.data;\n    }\n    /**\n\t * Reads file using {@link module:upload/filereader~FileReader}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-read-wrong-status` when status\n\t * is different than `idle`.\n\t *\n\t * Example usage:\n\t *\n\t * ```ts\n\t * fileLoader.read()\n\t * \t.then( data => { ... } )\n\t * \t.catch( err => {\n\t * \t\tif ( err === 'aborted' ) {\n\t * \t\t\tconsole.log( 'Reading aborted.' );\n\t * \t\t} else {\n\t * \t\t\tconsole.log( 'Reading error.', err );\n\t * \t\t}\n\t * \t} );\n\t * ```\n\t *\n\t * @returns Returns promise that will be resolved with read data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */ read() {\n        if (this.status != 'idle') {\n            /**\n\t\t\t * You cannot call read if the status is different than idle.\n\t\t\t *\n\t\t\t * @error filerepository-read-wrong-status\n\t\t\t */ throw new CKEditorError('filerepository-read-wrong-status', this);\n        }\n        this.status = 'reading';\n        return this.file.then((file)=>this._reader.read(file)).then((data)=>{\n            // Edge case: reader was aborted after file was read - double check for proper status.\n            // It can happen when image was deleted during its upload.\n            if (this.status !== 'reading') {\n                throw this.status;\n            }\n            this.status = 'idle';\n            return data;\n        }).catch((err)=>{\n            if (err === 'aborted') {\n                this.status = 'aborted';\n                throw 'aborted';\n            }\n            this.status = 'error';\n            throw this._reader.error ? this._reader.error : err;\n        });\n    }\n    /**\n\t * Reads file using the provided {@link module:upload/filerepository~UploadAdapter}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-upload-wrong-status` when status\n\t * is different than `idle`.\n\t * Example usage:\n\t *\n\t * ```ts\n\t * fileLoader.upload()\n\t * \t.then( data => { ... } )\n\t * \t.catch( e => {\n\t * \t\tif ( e === 'aborted' ) {\n\t * \t\t\tconsole.log( 'Uploading aborted.' );\n\t * \t\t} else {\n\t * \t\t\tconsole.log( 'Uploading error.', e );\n\t * \t\t}\n\t * \t} );\n\t * ```\n\t *\n\t * @returns Returns promise that will be resolved with response data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */ upload() {\n        if (this.status != 'idle') {\n            /**\n\t\t\t * You cannot call upload if the status is different than idle.\n\t\t\t *\n\t\t\t * @error filerepository-upload-wrong-status\n\t\t\t */ throw new CKEditorError('filerepository-upload-wrong-status', this);\n        }\n        this.status = 'uploading';\n        return this.file.then(()=>this._adapter.upload()).then((data)=>{\n            this.uploadResponse = data;\n            this.status = 'idle';\n            return data;\n        }).catch((err)=>{\n            if (this.status === 'aborted') {\n                throw 'aborted';\n            }\n            this.status = 'error';\n            throw err;\n        });\n    }\n    /**\n\t * Aborts loading process.\n\t */ abort() {\n        const status = this.status;\n        this.status = 'aborted';\n        if (!this._filePromiseWrapper.isFulfilled) {\n            // Edge case: file loader is aborted before read() is called\n            // so it might happen that no one handled the rejection of this promise.\n            // See https://github.com/ckeditor/ckeditor5-upload/pull/100\n            this._filePromiseWrapper.promise.catch(()=>{});\n            this._filePromiseWrapper.rejecter('aborted');\n        } else if (status == 'reading') {\n            this._reader.abort();\n        } else if (status == 'uploading' && this._adapter.abort) {\n            this._adapter.abort();\n        }\n        this._destroy();\n    }\n    /**\n\t * Performs cleanup.\n\t *\n\t * @internal\n\t */ _destroy() {\n        this._filePromiseWrapper = undefined;\n        this._reader = undefined;\n        this._adapter = undefined;\n        this.uploadResponse = undefined;\n    }\n    /**\n\t * Wraps a given file promise into another promise giving additional\n\t * control (resolving, rejecting, checking if fulfilled) over it.\n\t *\n\t * @param filePromise The initial file promise to be wrapped.\n\t */ _createFilePromiseWrapper(filePromise) {\n        const wrapper = {};\n        wrapper.promise = new Promise((resolve, reject)=>{\n            wrapper.rejecter = reject;\n            wrapper.isFulfilled = false;\n            filePromise.then((file)=>{\n                wrapper.isFulfilled = true;\n                resolve(file);\n            }).catch((err)=>{\n                wrapper.isFulfilled = true;\n                reject(err);\n            });\n        });\n        return wrapper;\n    }\n}\n\n/**\n * A plugin that converts images inserted into the editor into [Base64 strings](https://en.wikipedia.org/wiki/Base64)\n * in the {@glink getting-started/setup/getting-and-setting-data editor output}.\n *\n * This kind of image upload does not require server processing – images are stored with the rest of the text and\n * displayed by the web browser without additional requests.\n *\n * Check out the {@glink features/images/image-upload/image-upload comprehensive \"Image upload overview\"} to learn about\n * other ways to upload images into CKEditor 5.\n */ class Base64UploadAdapter extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            FileRepository\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Base64UploadAdapter';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        this.editor.plugins.get(FileRepository).createUploadAdapter = (loader)=>new Adapter$1(loader);\n    }\n}\n/**\n * The upload adapter that converts images inserted into the editor into Base64 strings.\n */ let Adapter$1 = class Adapter {\n    /**\n\t * `FileLoader` instance to use during the upload.\n\t */ loader;\n    reader;\n    /**\n\t * Creates a new adapter instance.\n\t */ constructor(loader){\n        this.loader = loader;\n    }\n    /**\n\t * Starts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#upload\n\t */ upload() {\n        return new Promise((resolve, reject)=>{\n            const reader = this.reader = new window.FileReader();\n            reader.addEventListener('load', ()=>{\n                resolve({\n                    default: reader.result\n                });\n            });\n            reader.addEventListener('error', (err)=>{\n                reject(err);\n            });\n            reader.addEventListener('abort', ()=>{\n                reject();\n            });\n            this.loader.file.then((file)=>{\n                reader.readAsDataURL(file);\n            });\n        });\n    }\n    /**\n\t * Aborts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#abort\n\t */ abort() {\n        this.reader.abort();\n    }\n};\n\n/**\n * The Simple upload adapter allows uploading images to an application running on your server using\n * the [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) API with a\n * minimal {@link module:upload/uploadconfig~SimpleUploadConfig editor configuration}.\n *\n * ```ts\n * ClassicEditor\n * \t.create( document.querySelector( '#editor' ), {\n * \t\tsimpleUpload: {\n * \t\t\tuploadUrl: 'http://example.com',\n * \t\t\theaders: {\n * \t\t\t\t...\n * \t\t\t}\n * \t\t}\n * \t} )\n * \t.then( ... )\n * \t.catch( ... );\n * ```\n *\n * See the {@glink features/images/image-upload/simple-upload-adapter \"Simple upload adapter\"} guide to learn how to\n * learn more about the feature (configuration, server–side requirements, etc.).\n *\n * Check out the {@glink features/images/image-upload/image-upload comprehensive \"Image upload overview\"} to learn about\n * other ways to upload images into CKEditor 5.\n */ class SimpleUploadAdapter extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            FileRepository\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SimpleUploadAdapter';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const options = this.editor.config.get('simpleUpload');\n        if (!options) {\n            return;\n        }\n        if (!options.uploadUrl) {\n            /**\n\t\t\t * The {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `config.simpleUpload.uploadUrl`}\n\t\t\t * configuration required by the {@link module:upload/adapters/simpleuploadadapter~SimpleUploadAdapter `SimpleUploadAdapter`}\n\t\t\t * is missing. Make sure the correct URL is specified for the image upload to work properly.\n\t\t\t *\n\t\t\t * @error simple-upload-adapter-missing-uploadurl\n\t\t\t */ logWarning('simple-upload-adapter-missing-uploadurl');\n            return;\n        }\n        this.editor.plugins.get(FileRepository).createUploadAdapter = (loader)=>{\n            return new Adapter(loader, options);\n        };\n    }\n}\n/**\n * Upload adapter.\n */ class Adapter {\n    /**\n\t * FileLoader instance to use during the upload.\n\t */ loader;\n    /**\n\t * The configuration of the adapter.\n\t */ options;\n    xhr;\n    /**\n\t * Creates a new adapter instance.\n\t */ constructor(loader, options){\n        this.loader = loader;\n        this.options = options;\n    }\n    /**\n\t * Starts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#upload\n\t */ upload() {\n        return this.loader.file.then((file)=>new Promise((resolve, reject)=>{\n                this._initRequest();\n                this._initListeners(resolve, reject, file);\n                this._sendRequest(file);\n            }));\n    }\n    /**\n\t * Aborts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#abort\n\t */ abort() {\n        if (this.xhr) {\n            this.xhr.abort();\n        }\n    }\n    /**\n\t * Initializes the `XMLHttpRequest` object using the URL specified as\n\t * {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `simpleUpload.uploadUrl`} in the editor's\n\t * configuration.\n\t */ _initRequest() {\n        const xhr = this.xhr = new XMLHttpRequest();\n        xhr.open('POST', this.options.uploadUrl, true);\n        xhr.responseType = 'json';\n    }\n    /**\n\t * Initializes XMLHttpRequest listeners\n\t *\n\t * @param resolve Callback function to be called when the request is successful.\n\t * @param reject Callback function to be called when the request cannot be completed.\n\t * @param file Native File object.\n\t */ _initListeners(resolve, reject, file) {\n        const xhr = this.xhr;\n        const loader = this.loader;\n        const genericErrorText = `Couldn't upload file: ${file.name}.`;\n        xhr.addEventListener('error', ()=>reject(genericErrorText));\n        xhr.addEventListener('abort', ()=>reject());\n        xhr.addEventListener('load', ()=>{\n            const response = xhr.response;\n            if (!response || response.error) {\n                return reject(response && response.error && response.error.message ? response.error.message : genericErrorText);\n            }\n            const urls = response.url ? {\n                default: response.url\n            } : response.urls;\n            // Resolve with the normalized `urls` property and pass the rest of the response\n            // to allow customizing the behavior of features relying on the upload adapters.\n            resolve({\n                ...response,\n                urls\n            });\n        });\n        // Upload progress when it is supported.\n        /* istanbul ignore else -- @preserve */ if (xhr.upload) {\n            xhr.upload.addEventListener('progress', (evt)=>{\n                if (evt.lengthComputable) {\n                    loader.uploadTotal = evt.total;\n                    loader.uploaded = evt.loaded;\n                }\n            });\n        }\n    }\n    /**\n\t * Prepares the data and sends the request.\n\t *\n\t * @param file File instance to be uploaded.\n\t */ _sendRequest(file) {\n        // Set headers if specified.\n        const headers = this.options.headers || {};\n        // Use the withCredentials flag if specified.\n        const withCredentials = this.options.withCredentials || false;\n        for (const headerName of Object.keys(headers)){\n            this.xhr.setRequestHeader(headerName, headers[headerName]);\n        }\n        this.xhr.withCredentials = withCredentials;\n        // Prepare the form data.\n        const data = new FormData();\n        data.append('upload', file);\n        // Send the request.\n        this.xhr.send(data);\n    }\n}\n\nexport { Base64UploadAdapter, FileRepository, SimpleUploadAdapter };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module upload/filereader\n */\n\n/* globals window */\n\nimport { ObservableMixin } from '@ckeditor/ckeditor5-utils';\n\ntype DomFileReader = globalThis.FileReader;\n\n/**\n * Wrapper over the native `FileReader`.\n */\nexport default class FileReader extends /* #__PURE__ */ ObservableMixin() {\n\tpublic total!: number;\n\n\t/**\n\t * Instance of native FileReader.\n\t */\n\tprivate readonly _reader: DomFileReader;\n\n\t/**\n\t * Holds the data of an already loaded file. The file must be first loaded\n\t * by using {@link module:upload/filereader~FileReader#read `read()`}.\n\t */\n\tprivate _data?: string;\n\n\t/**\n\t * Number of bytes loaded.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public loaded: number;\n\n\t/**\n\t * Creates an instance of the FileReader.\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst reader = new window.FileReader();\n\n\t\tthis._reader = reader;\n\t\tthis._data = undefined;\n\n\t\tthis.set( 'loaded', 0 );\n\n\t\treader.onprogress = evt => {\n\t\t\tthis.loaded = evt.loaded;\n\t\t};\n\t}\n\n\t/**\n\t * Returns error that occurred during file reading.\n\t */\n\tpublic get error(): DOMException | null {\n\t\treturn this._reader.error;\n\t}\n\n\t/**\n\t * Holds the data of an already loaded file. The file must be first loaded\n\t * by using {@link module:upload/filereader~FileReader#read `read()`}.\n\t */\n\tpublic get data(): string | undefined {\n\t\treturn this._data;\n\t}\n\n\t/**\n\t * Reads the provided file.\n\t *\n\t * @param file Native File object.\n\t * @returns Returns a promise that will be resolved with file's content.\n\t * The promise will be rejected in case of an error or when the reading process is aborted.\n\t */\n\tpublic read( file: File ): Promise<string> {\n\t\tconst reader = this._reader;\n\t\tthis.total = file.size;\n\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\treader.onload = () => {\n\t\t\t\tconst result = reader.result as string;\n\n\t\t\t\tthis._data = result;\n\n\t\t\t\tresolve( result );\n\t\t\t};\n\n\t\t\treader.onerror = () => {\n\t\t\t\treject( 'error' );\n\t\t\t};\n\n\t\t\treader.onabort = () => {\n\t\t\t\treject( 'aborted' );\n\t\t\t};\n\n\t\t\tthis._reader.readAsDataURL( file );\n\t\t} );\n\t}\n\n\t/**\n\t * Aborts file reader.\n\t */\n\tpublic abort(): void {\n\t\tthis._reader.abort();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module upload/filerepository\n */\n\nimport {\n\tPlugin,\n\tPendingActions,\n\ttype PendingAction\n} from '@ckeditor/ckeditor5-core';\n\nimport {\n\tCKEditorError,\n\tCollection,\n\tObservableMixin,\n\tlogWarning,\n\tuid,\n\ttype ObservableChangeEvent,\n\ttype CollectionChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport FileReader from './filereader.js';\n\n/**\n * File repository plugin. A central point for managing file upload.\n *\n * To use it, first you need an upload adapter. Upload adapter's job is to handle communication with the server\n * (sending the file and handling server's response). You can use one of the existing plugins introducing upload adapters\n * (e.g. {@link module:easy-image/cloudservicesuploadadapter~CloudServicesUploadAdapter} or\n * {@link module:adapter-ckfinder/uploadadapter~CKFinderUploadAdapter}) or write your own one – see\n * the {@glink framework/deep-dive/upload-adapter Custom image upload adapter deep-dive} guide.\n *\n * Then, you can use {@link module:upload/filerepository~FileRepository#createLoader `createLoader()`} and the returned\n * {@link module:upload/filerepository~FileLoader} instance to load and upload files.\n */\nexport default class FileRepository extends Plugin {\n\t/**\n\t * Collection of loaders associated with this repository.\n\t */\n\tpublic loaders = new Collection<FileLoader>();\n\n\t/**\n\t * A factory function which should be defined before using `FileRepository`.\n\t *\n\t * It should return a new instance of {@link module:upload/filerepository~UploadAdapter} that will be used to upload files.\n\t * {@link module:upload/filerepository~FileLoader} instance associated with the adapter\n\t * will be passed to that function.\n\t *\n\t * For more information and example see {@link module:upload/filerepository~UploadAdapter}.\n\t */\n\tpublic declare createUploadAdapter?: ( loader: FileLoader ) => UploadAdapter;\n\n\t/**\n\t * Loaders mappings used to retrieve loaders references.\n\t */\n\tprivate _loadersMap = new Map<File | Promise<File>, FileLoader>();\n\n\t/**\n\t * Reference to a pending action registered in a {@link module:core/pendingactions~PendingActions} plugin\n\t * while upload is in progress. When there is no upload then value is `null`.\n\t */\n\tprivate _pendingAction: PendingAction | null = null;\n\n\t/**\n\t * Number of bytes uploaded.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public uploaded: number;\n\n\t/**\n\t * Number of total bytes to upload.\n\t *\n\t * It might be different than the file size because of headers and additional data.\n\t * It contains `null` if value is not available yet, so it's better to use {@link #uploadedPercent} to monitor\n\t * the progress.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public uploadTotal: number | null;\n\n\t/**\n\t * Upload progress in percents.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public uploadedPercent: number;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'FileRepository' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ PendingActions ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\t// Keeps upload in a sync with pending actions.\n\t\tthis.loaders.on<CollectionChangeEvent>( 'change', () => this._updatePendingAction() );\n\n\t\tthis.set( 'uploaded', 0 );\n\t\tthis.set( 'uploadTotal', null );\n\n\t\tthis.bind( 'uploadedPercent' ).to( this, 'uploaded', this, 'uploadTotal', ( uploaded, total ) => {\n\t\t\treturn total ? ( uploaded / total * 100 ) : 0;\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the loader associated with specified file or promise.\n\t *\n\t * To get loader by id use `fileRepository.loaders.get( id )`.\n\t *\n\t * @param fileOrPromise Native file or promise handle.\n\t */\n\tpublic getLoader( fileOrPromise: File | Promise<File> ): FileLoader | null {\n\t\treturn this._loadersMap.get( fileOrPromise ) || null;\n\t}\n\n\t/**\n\t * Creates a loader instance for the given file.\n\t *\n\t * Requires {@link #createUploadAdapter} factory to be defined.\n\t *\n\t * @param fileOrPromise Native File object or native Promise object which resolves to a File.\n\t */\n\tpublic createLoader( fileOrPromise: File | Promise<File> ): FileLoader | null {\n\t\tif ( !this.createUploadAdapter ) {\n\t\t\t/**\n\t\t\t * You need to enable an upload adapter in order to be able to upload files.\n\t\t\t *\n\t\t\t * This warning shows up when {@link module:upload/filerepository~FileRepository} is being used\n\t\t\t * without {@link module:upload/filerepository~FileRepository#createUploadAdapter defining an upload adapter}.\n\t\t\t *\n\t\t\t * **If you see this warning when using one of the {@glink getting-started/legacy/installation-methods/predefined-builds\n\t\t\t * CKEditor 5 Builds}**\n\t\t\t * it means that you did not configure any of the upload adapters available by default in those builds.\n\t\t\t *\n\t\t\t * Predefined builds are a deprecated solution and we strongly advise\n\t\t\t * {@glink updating/nim-migration/migration-to-new-installation-methods migrating to new installation methods}.\n\t\t\t *\n\t\t\t * See the {@glink features/images/image-upload/image-upload comprehensive \"Image upload overview\"} to learn which upload\n\t\t\t * adapters are available in the builds and how to configure them.\n\t\t\t *\n\t\t\t * Otherwise, if you see this warning, there is a chance that you enabled\n\t\t\t * a feature like {@link module:image/imageupload~ImageUpload},\n\t\t\t * or {@link module:image/imageupload/imageuploadui~ImageUploadUI} but you did not enable any upload adapter.\n\t\t\t * You can choose one of the existing upload adapters listed in the\n\t\t\t * {@glink features/images/image-upload/image-upload \"Image upload overview\"}.\n\t\t\t *\n\t\t\t * You can also implement your {@glink framework/deep-dive/upload-adapter own image upload adapter}.\n\t\t\t *\n\t\t\t * @error filerepository-no-upload-adapter\n\t\t\t */\n\t\t\tlogWarning( 'filerepository-no-upload-adapter' );\n\n\t\t\treturn null;\n\t\t}\n\n\t\tconst loader = new FileLoader( Promise.resolve( fileOrPromise ), this.createUploadAdapter );\n\n\t\tthis.loaders.add( loader );\n\t\tthis._loadersMap.set( fileOrPromise, loader );\n\n\t\t// Store also file => loader mapping so loader can be retrieved by file instance returned upon Promise resolution.\n\t\tif ( fileOrPromise instanceof Promise ) {\n\t\t\tloader.file\n\t\t\t\t.then( file => {\n\t\t\t\t\tthis._loadersMap.set( file!, loader );\n\t\t\t\t} )\n\t\t\t\t// Every then() must have a catch().\n\t\t\t\t// File loader state (and rejections) are handled in read() and upload().\n\t\t\t\t// Also, see the \"does not swallow the file promise rejection\" test.\n\t\t\t\t.catch( () => {} );\n\t\t}\n\n\t\tloader.on<ObservableChangeEvent>( 'change:uploaded', () => {\n\t\t\tlet aggregatedUploaded = 0;\n\n\t\t\tfor ( const loader of this.loaders ) {\n\t\t\t\taggregatedUploaded += loader.uploaded;\n\t\t\t}\n\n\t\t\tthis.uploaded = aggregatedUploaded;\n\t\t} );\n\n\t\tloader.on<ObservableChangeEvent>( 'change:uploadTotal', () => {\n\t\t\tlet aggregatedTotal = 0;\n\n\t\t\tfor ( const loader of this.loaders ) {\n\t\t\t\tif ( loader.uploadTotal ) {\n\t\t\t\t\taggregatedTotal += loader.uploadTotal;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.uploadTotal = aggregatedTotal;\n\t\t} );\n\n\t\treturn loader;\n\t}\n\n\t/**\n\t * Destroys the given loader.\n\t *\n\t * @param fileOrPromiseOrLoader File or Promise associated with that loader or loader itself.\n\t */\n\tpublic destroyLoader( fileOrPromiseOrLoader: File | Promise<File> | FileLoader ): void {\n\t\tconst loader = fileOrPromiseOrLoader instanceof FileLoader ? fileOrPromiseOrLoader : this.getLoader( fileOrPromiseOrLoader )!;\n\n\t\tloader._destroy();\n\n\t\tthis.loaders.remove( loader );\n\n\t\tthis._loadersMap.forEach( ( value, key ) => {\n\t\t\tif ( value === loader ) {\n\t\t\t\tthis._loadersMap.delete( key );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Registers or deregisters pending action bound with upload progress.\n\t */\n\tprivate _updatePendingAction(): void {\n\t\tconst pendingActions = this.editor.plugins.get( PendingActions );\n\n\t\tif ( this.loaders.length ) {\n\t\t\tif ( !this._pendingAction ) {\n\t\t\t\tconst t = this.editor.t;\n\t\t\t\tconst getMessage = ( value: number ) => `${ t( 'Upload in progress' ) } ${ parseInt( value as any ) }%.`;\n\n\t\t\t\tthis._pendingAction = pendingActions.add( getMessage( this.uploadedPercent ) );\n\t\t\t\tthis._pendingAction.bind( 'message' ).to( this, 'uploadedPercent', getMessage );\n\t\t\t}\n\t\t} else {\n\t\t\tpendingActions.remove( this._pendingAction! );\n\t\t\tthis._pendingAction = null;\n\t\t}\n\t}\n}\n\n/**\n * File loader class.\n *\n * It is used to control the process of reading the file and uploading it using the specified upload adapter.\n */\nclass FileLoader extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * Unique id of FileLoader instance.\n\t *\n\t * @readonly\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * Additional wrapper over the initial file promise passed to this loader.\n\t */\n\tprivate _filePromiseWrapper: FilePromiseWrapper;\n\n\t/**\n\t * Adapter instance associated with this file loader.\n\t */\n\tprivate _adapter: UploadAdapter;\n\n\t/**\n\t * FileReader used by FileLoader.\n\t */\n\tprivate _reader: FileReader;\n\n\t/**\n\t * Current status of FileLoader. It can be one of the following:\n\t *\n\t * * 'idle',\n\t * * 'reading',\n\t * * 'uploading',\n\t * * 'aborted',\n\t * * 'error'.\n\t *\n\t * When reading status can change in a following way:\n\t *\n\t * `idle` -> `reading` -> `idle`\n\t * `idle` -> `reading -> `aborted`\n\t * `idle` -> `reading -> `error`\n\t *\n\t * When uploading status can change in a following way:\n\t *\n\t * `idle` -> `uploading` -> `idle`\n\t * `idle` -> `uploading` -> `aborted`\n\t * `idle` -> `uploading` -> `error`\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public status: 'idle' | 'reading' | 'uploading' | 'aborted' | 'error';\n\n\t/**\n\t * Number of bytes uploaded.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public uploaded: number;\n\n\t/**\n\t * Number of total bytes to upload.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public uploadTotal: number | null;\n\n\t/**\n\t * Upload progress in percents.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public uploadedPercent: number;\n\n\t/**\n\t * Response of the upload.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public uploadResponse?: UploadResponse | null;\n\n\t/**\n\t * Creates a new instance of `FileLoader`.\n\t *\n\t * @param filePromise A promise which resolves to a file instance.\n\t * @param uploadAdapterCreator The function which returns {@link module:upload/filerepository~UploadAdapter} instance.\n\t */\n\tconstructor( filePromise: Promise<File>, uploadAdapterCreator: ( loader: FileLoader ) => UploadAdapter ) {\n\t\tsuper();\n\n\t\tthis.id = uid();\n\t\tthis._filePromiseWrapper = this._createFilePromiseWrapper( filePromise );\n\t\tthis._adapter = uploadAdapterCreator( this );\n\t\tthis._reader = new FileReader();\n\n\t\tthis.set( 'status', 'idle' );\n\t\tthis.set( 'uploaded', 0 );\n\t\tthis.set( 'uploadTotal', null );\n\n\t\tthis.bind( 'uploadedPercent' ).to( this, 'uploaded', this, 'uploadTotal', ( uploaded, total ) => {\n\t\t\treturn total ? ( uploaded / total * 100 ) : 0;\n\t\t} );\n\n\t\tthis.set( 'uploadResponse', null );\n\t}\n\n\t/**\n\t * A `Promise` which resolves to a `File` instance associated with this file loader.\n\t */\n\tpublic get file(): Promise<File | null> {\n\t\tif ( !this._filePromiseWrapper ) {\n\t\t\t// Loader was destroyed, return promise which resolves to null.\n\t\t\treturn Promise.resolve( null );\n\t\t} else {\n\t\t\t// The `this._filePromiseWrapper.promise` is chained and not simply returned to handle a case when:\n\t\t\t//\n\t\t\t//\t\t* The `loader.file.then( ... )` is called by external code (returned promise is pending).\n\t\t\t//\t\t* Then `loader._destroy()` is called (call is synchronous) which destroys the `loader`.\n\t\t\t//\t\t* Promise returned by the first `loader.file.then( ... )` call is resolved.\n\t\t\t//\n\t\t\t// Returning `this._filePromiseWrapper.promise` will still resolve to a `File` instance so there\n\t\t\t// is an additional check needed in the chain to see if `loader` was destroyed in the meantime.\n\t\t\treturn this._filePromiseWrapper.promise.then( file => this._filePromiseWrapper ? file : null );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the file data. To read its data, you need for first load the file\n\t * by using the {@link module:upload/filerepository~FileLoader#read `read()`} method.\n\t */\n\tpublic get data(): string | undefined {\n\t\treturn this._reader.data;\n\t}\n\n\t/**\n\t * Reads file using {@link module:upload/filereader~FileReader}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-read-wrong-status` when status\n\t * is different than `idle`.\n\t *\n\t * Example usage:\n\t *\n\t * ```ts\n\t * fileLoader.read()\n\t * \t.then( data => { ... } )\n\t * \t.catch( err => {\n\t * \t\tif ( err === 'aborted' ) {\n\t * \t\t\tconsole.log( 'Reading aborted.' );\n\t * \t\t} else {\n\t * \t\t\tconsole.log( 'Reading error.', err );\n\t * \t\t}\n\t * \t} );\n\t * ```\n\t *\n\t * @returns Returns promise that will be resolved with read data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */\n\tpublic read(): Promise<string> {\n\t\tif ( this.status != 'idle' ) {\n\t\t\t/**\n\t\t\t * You cannot call read if the status is different than idle.\n\t\t\t *\n\t\t\t * @error filerepository-read-wrong-status\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'filerepository-read-wrong-status', this );\n\t\t}\n\n\t\tthis.status = 'reading';\n\n\t\treturn this.file\n\t\t\t.then( file => this._reader.read( file! ) )\n\t\t\t.then( data => {\n\t\t\t\t// Edge case: reader was aborted after file was read - double check for proper status.\n\t\t\t\t// It can happen when image was deleted during its upload.\n\t\t\t\tif ( this.status !== 'reading' ) {\n\t\t\t\t\tthrow this.status;\n\t\t\t\t}\n\n\t\t\t\tthis.status = 'idle';\n\n\t\t\t\treturn data;\n\t\t\t} )\n\t\t\t.catch( err => {\n\t\t\t\tif ( err === 'aborted' ) {\n\t\t\t\t\tthis.status = 'aborted';\n\t\t\t\t\tthrow 'aborted';\n\t\t\t\t}\n\n\t\t\t\tthis.status = 'error';\n\t\t\t\tthrow this._reader.error ? this._reader.error : err;\n\t\t\t} );\n\t}\n\n\t/**\n\t * Reads file using the provided {@link module:upload/filerepository~UploadAdapter}.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `filerepository-upload-wrong-status` when status\n\t * is different than `idle`.\n\t * Example usage:\n\t *\n\t * ```ts\n\t * fileLoader.upload()\n\t * \t.then( data => { ... } )\n\t * \t.catch( e => {\n\t * \t\tif ( e === 'aborted' ) {\n\t * \t\t\tconsole.log( 'Uploading aborted.' );\n\t * \t\t} else {\n\t * \t\t\tconsole.log( 'Uploading error.', e );\n\t * \t\t}\n\t * \t} );\n\t * ```\n\t *\n\t * @returns Returns promise that will be resolved with response data. Promise will be rejected if error\n\t * occurs or if read process is aborted.\n\t */\n\tpublic upload(): Promise<UploadResponse> {\n\t\tif ( this.status != 'idle' ) {\n\t\t\t/**\n\t\t\t * You cannot call upload if the status is different than idle.\n\t\t\t *\n\t\t\t * @error filerepository-upload-wrong-status\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'filerepository-upload-wrong-status', this );\n\t\t}\n\n\t\tthis.status = 'uploading';\n\n\t\treturn this.file\n\t\t\t.then( () => this._adapter.upload() )\n\t\t\t.then( data => {\n\t\t\t\tthis.uploadResponse = data;\n\t\t\t\tthis.status = 'idle';\n\n\t\t\t\treturn data;\n\t\t\t} )\n\t\t\t.catch( err => {\n\t\t\t\tif ( this.status === 'aborted' ) {\n\t\t\t\t\tthrow 'aborted';\n\t\t\t\t}\n\n\t\t\t\tthis.status = 'error';\n\t\t\t\tthrow err;\n\t\t\t} );\n\t}\n\n\t/**\n\t * Aborts loading process.\n\t */\n\tpublic abort(): void {\n\t\tconst status = this.status;\n\t\tthis.status = 'aborted';\n\n\t\tif ( !this._filePromiseWrapper.isFulfilled ) {\n\t\t\t// Edge case: file loader is aborted before read() is called\n\t\t\t// so it might happen that no one handled the rejection of this promise.\n\t\t\t// See https://github.com/ckeditor/ckeditor5-upload/pull/100\n\t\t\tthis._filePromiseWrapper.promise.catch( () => {} );\n\n\t\t\tthis._filePromiseWrapper.rejecter( 'aborted' );\n\t\t} else if ( status == 'reading' ) {\n\t\t\tthis._reader.abort();\n\t\t} else if ( status == 'uploading' && this._adapter.abort ) {\n\t\t\tthis._adapter.abort();\n\t\t}\n\n\t\tthis._destroy();\n\t}\n\n\t/**\n\t * Performs cleanup.\n\t *\n\t * @internal\n\t */\n\tpublic _destroy(): void {\n\t\tthis._filePromiseWrapper = undefined as any;\n\t\tthis._reader = undefined as any;\n\t\tthis._adapter = undefined as any;\n\t\tthis.uploadResponse = undefined;\n\t}\n\n\t/**\n\t * Wraps a given file promise into another promise giving additional\n\t * control (resolving, rejecting, checking if fulfilled) over it.\n\t *\n\t * @param filePromise The initial file promise to be wrapped.\n\t */\n\tprivate _createFilePromiseWrapper( filePromise: Promise<File> ): FilePromiseWrapper {\n\t\tconst wrapper: Partial<FilePromiseWrapper> = {};\n\n\t\twrapper.promise = new Promise<File>( ( resolve, reject ) => {\n\t\t\twrapper.rejecter = reject;\n\t\t\twrapper.isFulfilled = false;\n\n\t\t\tfilePromise\n\t\t\t\t.then( file => {\n\t\t\t\t\twrapper.isFulfilled = true;\n\t\t\t\t\tresolve( file );\n\t\t\t\t} )\n\t\t\t\t.catch( err => {\n\t\t\t\t\twrapper.isFulfilled = true;\n\t\t\t\t\treject( err );\n\t\t\t\t} );\n\t\t} );\n\n\t\treturn wrapper as FilePromiseWrapper;\n\t}\n}\n\nexport type { FileLoader };\n\n/**\n * Upload adapter interface used by the {@link module:upload/filerepository~FileRepository file repository}\n * to handle file upload. An upload adapter is a bridge between the editor and server that handles file uploads.\n * It should contain a logic necessary to initiate an upload process and monitor its progress.\n *\n * Learn how to develop your own upload adapter for CKEditor 5 in the\n * {@glink framework/deep-dive/upload-adapter \"Custom upload adapter\"} guide.\n *\n * @interface UploadAdapter\n */\nexport interface UploadAdapter {\n\n\t/**\n\t * Executes the upload process.\n\t * This method should return a promise that will resolve when data will be uploaded to server. Promise should be\n\t * resolved with an object containing information about uploaded file:\n\t *\n\t * ```json\n\t * {\n\t * \tdefault: 'http://server/default-size.image.png'\n\t * }\n\t * ```\n\t *\n\t * Additionally, other image sizes can be provided:\n\t *\n\t * ```json\n\t * {\n\t * \tdefault: 'http://server/default-size.image.png',\n\t * \t'160': 'http://server/size-160.image.png',\n\t * \t'500': 'http://server/size-500.image.png',\n\t * \t'1000': 'http://server/size-1000.image.png',\n\t * \t'1052': 'http://server/default-size.image.png'\n\t * }\n\t * ```\n\t *\n\t * You can also pass additional properties from the server. In this case you need to wrap URLs\n\t * in the `urls` object and pass additional properties along the `urls` property.\n\t *\n\t * ```json\n\t * {\n\t * \tmyCustomProperty: 'foo',\n\t * \turls: {\n\t * \t\tdefault: 'http://server/default-size.image.png',\n\t * \t\t'160': 'http://server/size-160.image.png',\n\t * \t\t'500': 'http://server/size-500.image.png',\n\t * \t\t'1000': 'http://server/size-1000.image.png',\n\t * \t\t'1052': 'http://server/default-size.image.png'\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * NOTE: When returning multiple images, the widest returned one should equal the default one. It is essential to\n\t * correctly set `width` attribute of the image. See this discussion:\n\t * https://github.com/ckeditor/ckeditor5-easy-image/issues/4 for more information.\n\t *\n\t * Take a look at {@link module:upload/filerepository~UploadAdapter example Adapter implementation} and\n\t * {@link module:upload/filerepository~FileRepository#createUploadAdapter createUploadAdapter method}.\n\t *\n\t * @returns Promise that should be resolved when data is uploaded.\n\t */\n\tupload(): Promise<UploadResponse>;\n\n\t/**\n\t * Aborts the upload process.\n\t * After aborting it should reject promise returned from {@link #upload upload()}.\n\t *\n\t * Take a look at {@link module:upload/filerepository~UploadAdapter example Adapter implementation} and\n\t * {@link module:upload/filerepository~FileRepository#createUploadAdapter createUploadAdapter method}.\n\t */\n\tabort?(): void;\n}\n\nexport type UploadResponse = Record<string, unknown>;\n\n/**\n * Object returned by {@link module:upload/filerepository~FileLoader#_createFilePromiseWrapper} method\n * to add more control over the initial file promise passed to {@link module:upload/filerepository~FileLoader}.\n */\ntype FilePromiseWrapper = {\n\n\t/**\n\t * Wrapper promise which can be chained for further processing.\n\t */\n\tpromise: Promise<File>;\n\n\t/**\n\t * Rejects the promise when called.\n\t */\n\trejecter: ( reason?: unknown ) => void;\n\n\t/**\n\t * Whether original promise is already fulfilled.\n\t */\n\tisFulfilled: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module upload/adapters/base64uploadadapter\n */\n\n/* globals window */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport FileRepository, { type UploadResponse, type FileLoader, type UploadAdapter } from '../filerepository.js';\n\ntype DomFileReader = globalThis.FileReader;\n\n/**\n * A plugin that converts images inserted into the editor into [Base64 strings](https://en.wikipedia.org/wiki/Base64)\n * in the {@glink getting-started/setup/getting-and-setting-data editor output}.\n *\n * This kind of image upload does not require server processing – images are stored with the rest of the text and\n * displayed by the web browser without additional requests.\n *\n * Check out the {@glink features/images/image-upload/image-upload comprehensive \"Image upload overview\"} to learn about\n * other ways to upload images into CKEditor 5.\n */\nexport default class Base64UploadAdapter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ FileRepository ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Base64UploadAdapter' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tthis.editor.plugins.get( FileRepository ).createUploadAdapter = loader => new Adapter( loader );\n\t}\n}\n\n/**\n * The upload adapter that converts images inserted into the editor into Base64 strings.\n */\nclass Adapter implements UploadAdapter {\n\t/**\n\t * `FileLoader` instance to use during the upload.\n\t */\n\tpublic loader: FileLoader;\n\n\tpublic reader?: DomFileReader;\n\n\t/**\n\t * Creates a new adapter instance.\n\t */\n\tconstructor( loader: FileLoader ) {\n\t\tthis.loader = loader;\n\t}\n\n\t/**\n\t * Starts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#upload\n\t */\n\tpublic upload(): Promise<UploadResponse> {\n\t\treturn new Promise( ( resolve, reject ) => {\n\t\t\tconst reader = this.reader = new window.FileReader();\n\n\t\t\treader.addEventListener( 'load', () => {\n\t\t\t\tresolve( { default: reader.result } );\n\t\t\t} );\n\n\t\t\treader.addEventListener( 'error', err => {\n\t\t\t\treject( err );\n\t\t\t} );\n\n\t\t\treader.addEventListener( 'abort', () => {\n\t\t\t\treject();\n\t\t\t} );\n\n\t\t\tthis.loader.file.then( file => {\n\t\t\t\treader.readAsDataURL( file! );\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Aborts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#abort\n\t */\n\tpublic abort(): void {\n\t\tthis.reader!.abort();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module upload/adapters/simpleuploadadapter\n */\n\n/* globals XMLHttpRequest, FormData */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport FileRepository, { type UploadResponse, type FileLoader, type UploadAdapter } from '../filerepository.js';\nimport type { SimpleUploadConfig } from '../uploadconfig.js';\nimport { logWarning } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The Simple upload adapter allows uploading images to an application running on your server using\n * the [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) API with a\n * minimal {@link module:upload/uploadconfig~SimpleUploadConfig editor configuration}.\n *\n * ```ts\n * ClassicEditor\n * \t.create( document.querySelector( '#editor' ), {\n * \t\tsimpleUpload: {\n * \t\t\tuploadUrl: 'http://example.com',\n * \t\t\theaders: {\n * \t\t\t\t...\n * \t\t\t}\n * \t\t}\n * \t} )\n * \t.then( ... )\n * \t.catch( ... );\n * ```\n *\n * See the {@glink features/images/image-upload/simple-upload-adapter \"Simple upload adapter\"} guide to learn how to\n * learn more about the feature (configuration, server–side requirements, etc.).\n *\n * Check out the {@glink features/images/image-upload/image-upload comprehensive \"Image upload overview\"} to learn about\n * other ways to upload images into CKEditor 5.\n */\nexport default class SimpleUploadAdapter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ FileRepository ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SimpleUploadAdapter' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst options = this.editor.config.get( 'simpleUpload' );\n\n\t\tif ( !options ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !options.uploadUrl ) {\n\t\t\t/**\n\t\t\t * The {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `config.simpleUpload.uploadUrl`}\n\t\t\t * configuration required by the {@link module:upload/adapters/simpleuploadadapter~SimpleUploadAdapter `SimpleUploadAdapter`}\n\t\t\t * is missing. Make sure the correct URL is specified for the image upload to work properly.\n\t\t\t *\n\t\t\t * @error simple-upload-adapter-missing-uploadurl\n\t\t\t */\n\t\t\tlogWarning( 'simple-upload-adapter-missing-uploadurl' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.editor.plugins.get( FileRepository ).createUploadAdapter = loader => {\n\t\t\treturn new Adapter( loader, options );\n\t\t};\n\t}\n}\n\n/**\n * Upload adapter.\n */\nclass Adapter implements UploadAdapter {\n\t/**\n\t * FileLoader instance to use during the upload.\n\t */\n\tpublic loader: FileLoader;\n\n\t/**\n\t * The configuration of the adapter.\n\t */\n\tpublic options: SimpleUploadConfig;\n\n\tprivate xhr?: XMLHttpRequest;\n\n\t/**\n\t * Creates a new adapter instance.\n\t */\n\tconstructor( loader: FileLoader, options: SimpleUploadConfig ) {\n\t\tthis.loader = loader;\n\t\tthis.options = options;\n\t}\n\n\t/**\n\t * Starts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#upload\n\t */\n\tpublic upload(): Promise<UploadResponse> {\n\t\treturn this.loader.file\n\t\t\t.then( file => new Promise( ( resolve, reject ) => {\n\t\t\t\tthis._initRequest();\n\t\t\t\tthis._initListeners( resolve, reject, file! );\n\t\t\t\tthis._sendRequest( file! );\n\t\t\t} ) );\n\t}\n\n\t/**\n\t * Aborts the upload process.\n\t *\n\t * @see module:upload/filerepository~UploadAdapter#abort\n\t */\n\tpublic abort(): void {\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\t}\n\n\t/**\n\t * Initializes the `XMLHttpRequest` object using the URL specified as\n\t * {@link module:upload/uploadconfig~SimpleUploadConfig#uploadUrl `simpleUpload.uploadUrl`} in the editor's\n\t * configuration.\n\t */\n\tprivate _initRequest(): void {\n\t\tconst xhr = this.xhr = new XMLHttpRequest();\n\n\t\txhr.open( 'POST', this.options.uploadUrl, true );\n\t\txhr.responseType = 'json';\n\t}\n\n\t/**\n\t * Initializes XMLHttpRequest listeners\n\t *\n\t * @param resolve Callback function to be called when the request is successful.\n\t * @param reject Callback function to be called when the request cannot be completed.\n\t * @param file Native File object.\n\t */\n\tprivate _initListeners(\n\t\tresolve: ( result: UploadResponse ) => void,\n\t\treject: ( message?: string ) => void,\n\t\tfile: File\n\t): void {\n\t\tconst xhr = this.xhr!;\n\t\tconst loader = this.loader;\n\t\tconst genericErrorText = `Couldn't upload file: ${ file.name }.`;\n\n\t\txhr.addEventListener( 'error', () => reject( genericErrorText ) );\n\t\txhr.addEventListener( 'abort', () => reject() );\n\t\txhr.addEventListener( 'load', () => {\n\t\t\tconst response = xhr.response;\n\n\t\t\tif ( !response || response.error ) {\n\t\t\t\treturn reject( response && response.error && response.error.message ? response.error.message : genericErrorText );\n\t\t\t}\n\n\t\t\tconst urls = response.url ? { default: response.url } : response.urls;\n\n\t\t\t// Resolve with the normalized `urls` property and pass the rest of the response\n\t\t\t// to allow customizing the behavior of features relying on the upload adapters.\n\t\t\tresolve( {\n\t\t\t\t...response,\n\t\t\t\turls\n\t\t\t} );\n\t\t} );\n\n\t\t// Upload progress when it is supported.\n\t\t/* istanbul ignore else -- @preserve */\n\t\tif ( xhr.upload ) {\n\t\t\txhr.upload.addEventListener( 'progress', evt => {\n\t\t\t\tif ( evt.lengthComputable ) {\n\t\t\t\t\tloader.uploadTotal = evt.total;\n\t\t\t\t\tloader.uploaded = evt.loaded;\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Prepares the data and sends the request.\n\t *\n\t * @param file File instance to be uploaded.\n\t */\n\tprivate _sendRequest( file: File ): void {\n\t\t// Set headers if specified.\n\t\tconst headers = this.options.headers || {};\n\n\t\t// Use the withCredentials flag if specified.\n\t\tconst withCredentials = this.options.withCredentials || false;\n\n\t\tfor ( const headerName of Object.keys( headers ) ) {\n\t\t\tthis.xhr!.setRequestHeader( headerName, headers[ headerName ] );\n\t\t}\n\n\t\tthis.xhr!.withCredentials = withCredentials;\n\n\t\t// Prepare the form data.\n\t\tconst data = new FormData();\n\n\t\tdata.append( 'upload', file );\n\n\t\t// Send the request.\n\t\tthis.xhr!.send( data );\n\t}\n}\n", "/**\r\n * @module color-parse\r\n */\r\nimport names from 'color-name'\r\n\r\nexport default parse\r\n\r\n/**\r\n * Base hues\r\n * http://dev.w3.org/csswg/css-color/#typedef-named-hue\r\n */\r\n//FIXME: use external hue detector\r\nvar baseHues = {\r\n\tred: 0,\r\n\torange: 60,\r\n\tyellow: 120,\r\n\tgreen: 180,\r\n\tblue: 240,\r\n\tpurple: 300\r\n}\r\n\r\n/**\r\n * Parse color from the string passed\r\n *\r\n * @return {Object} A space indicator `space`, an array `values` and `alpha`\r\n */\r\nfunction parse (cstr) {\r\n\tvar m, parts = [], alpha = 1, space\r\n\r\n\tif (typeof cstr === 'string') {\r\n\t\t//keyword\r\n\t\tif (names[cstr]) {\r\n\t\t\tparts = names[cstr].slice()\r\n\t\t\tspace = 'rgb'\r\n\t\t}\r\n\r\n\t\t//reserved words\r\n\t\telse if (cstr === 'transparent') {\r\n\t\t\talpha = 0\r\n\t\t\tspace = 'rgb'\r\n\t\t\tparts = [0,0,0]\r\n\t\t}\r\n\r\n\t\t//hex\r\n\t\telse if (/^#[A-Fa-f0-9]+$/.test(cstr)) {\r\n\t\t\tvar base = cstr.slice(1)\r\n\t\t\tvar size = base.length\r\n\t\t\tvar isShort = size <= 4\r\n\t\t\talpha = 1\r\n\r\n\t\t\tif (isShort) {\r\n\t\t\t\tparts = [\r\n\t\t\t\t\tparseInt(base[0] + base[0], 16),\r\n\t\t\t\t\tparseInt(base[1] + base[1], 16),\r\n\t\t\t\t\tparseInt(base[2] + base[2], 16)\r\n\t\t\t\t]\r\n\t\t\t\tif (size === 4) {\r\n\t\t\t\t\talpha = parseInt(base[3] + base[3], 16) / 255\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tparts = [\r\n\t\t\t\t\tparseInt(base[0] + base[1], 16),\r\n\t\t\t\t\tparseInt(base[2] + base[3], 16),\r\n\t\t\t\t\tparseInt(base[4] + base[5], 16)\r\n\t\t\t\t]\r\n\t\t\t\tif (size === 8) {\r\n\t\t\t\t\talpha = parseInt(base[6] + base[7], 16) / 255\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (!parts[0]) parts[0] = 0\r\n\t\t\tif (!parts[1]) parts[1] = 0\r\n\t\t\tif (!parts[2]) parts[2] = 0\r\n\r\n\t\t\tspace = 'rgb'\r\n\t\t}\r\n\r\n\t\t//color space\r\n\t\telse if (m = /^((?:rgb|hs[lvb]|hwb|cmyk?|xy[zy]|gray|lab|lchu?v?|[ly]uv|lms)a?)\\s*\\(([^\\)]*)\\)/.exec(cstr)) {\r\n\t\t\tvar name = m[1]\r\n\t\t\tvar isRGB = name === 'rgb'\r\n\t\t\tvar base = name.replace(/a$/, '')\r\n\t\t\tspace = base\r\n\t\t\tvar size = base === 'cmyk' ? 4 : base === 'gray' ? 1 : 3\r\n\t\t\tparts = m[2].trim()\r\n\t\t\t\t.split(/\\s*[,\\/]\\s*|\\s+/)\r\n\t\t\t\t.map(function (x, i) {\r\n\t\t\t\t\t//<percentage>\r\n\t\t\t\t\tif (/%$/.test(x)) {\r\n\t\t\t\t\t\t//alpha\r\n\t\t\t\t\t\tif (i === size)\treturn parseFloat(x) / 100\r\n\t\t\t\t\t\t//rgb\r\n\t\t\t\t\t\tif (base === 'rgb') return parseFloat(x) * 255 / 100\r\n\t\t\t\t\t\treturn parseFloat(x)\r\n\t\t\t\t\t}\r\n\t\t\t\t\t//hue\r\n\t\t\t\t\telse if (base[i] === 'h') {\r\n\t\t\t\t\t\t//<deg>\r\n\t\t\t\t\t\tif (/deg$/.test(x)) {\r\n\t\t\t\t\t\t\treturn parseFloat(x)\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t//<base-hue>\r\n\t\t\t\t\t\telse if (baseHues[x] !== undefined) {\r\n\t\t\t\t\t\t\treturn baseHues[x]\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn parseFloat(x)\r\n\t\t\t\t})\r\n\r\n\t\t\tif (name === base) parts.push(1)\r\n\t\t\talpha = (isRGB) ? 1 : (parts[size] === undefined) ? 1 : parts[size]\r\n\t\t\tparts = parts.slice(0, size)\r\n\t\t}\r\n\r\n\t\t//named channels case\r\n\t\telse if (cstr.length > 10 && /[0-9](?:\\s|\\/)/.test(cstr)) {\r\n\t\t\tparts = cstr.match(/([0-9]+)/g).map(function (value) {\r\n\t\t\t\treturn parseFloat(value)\r\n\t\t\t})\r\n\r\n\t\t\tspace = cstr.match(/([a-z])/ig).join('').toLowerCase()\r\n\t\t}\r\n\t}\r\n\r\n\t//numeric case\r\n\telse if (!isNaN(cstr)) {\r\n\t\tspace = 'rgb'\r\n\t\tparts = [cstr >>> 16, (cstr & 0x00ff00) >>> 8, cstr & 0x0000ff]\r\n\t}\r\n\r\n\t//array-like\r\n\telse if (Array.isArray(cstr) || cstr.length) {\r\n\t\tparts = [cstr[0], cstr[1], cstr[2]]\r\n\t\tspace = 'rgb'\r\n\t\talpha = cstr.length === 4 ? cstr[3] : 1\r\n\t}\r\n\r\n\t//object case - detects css cases of rgb and hsl\r\n\telse if (cstr instanceof Object) {\r\n\t\tif (cstr.r != null || cstr.red != null || cstr.R != null) {\r\n\t\t\tspace = 'rgb'\r\n\t\t\tparts = [\r\n\t\t\t\tcstr.r || cstr.red || cstr.R || 0,\r\n\t\t\t\tcstr.g || cstr.green || cstr.G || 0,\r\n\t\t\t\tcstr.b || cstr.blue || cstr.B || 0\r\n\t\t\t]\r\n\t\t}\r\n\t\telse {\r\n\t\t\tspace = 'hsl'\r\n\t\t\tparts = [\r\n\t\t\t\tcstr.h || cstr.hue || cstr.H || 0,\r\n\t\t\t\tcstr.s || cstr.saturation || cstr.S || 0,\r\n\t\t\t\tcstr.l || cstr.lightness || cstr.L || cstr.b || cstr.brightness\r\n\t\t\t]\r\n\t\t}\r\n\r\n\t\talpha = cstr.a || cstr.alpha || cstr.opacity || 1\r\n\r\n\t\tif (cstr.opacity != null) alpha /= 100\r\n\t}\r\n\r\n\treturn {\r\n\t\tspace: space,\r\n\t\tvalues: parts,\r\n\t\talpha: alpha\r\n\t}\r\n}\r\n", "import { Collection, CKEditorError, EmitterMixin, isNode, toArray, DomEmitterMixin, ObservableMixin, isIterable, uid, env, delay, getEnvKeystrokeText, isVisible, global, KeystrokeHandler, FocusTracker, Rect, toUnit, createElement, ResizeObserver, getBorderWidths, logWarning, getOptimalPosition, isText, isRange, priorities, first, verifyLicense, getAncestors } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { cloneDeepWith, isObject, isElement, debounce, throttle, cloneDeep, extend, escapeRegExp, escape } from 'lodash-es';\nimport { icons, Plugin, ContextPlugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport parse from 'color-parse';\nimport * as convert from 'color-convert';\nimport { HexBase } from 'vanilla-colorful/lib/entrypoints/hex';\nimport { Observer } from '@ckeditor/ckeditor5-engine/dist/index.js';\n\n/**\n * Collects {@link module:ui/view~View} instances.\n *\n * ```ts\n * const parentView = new ParentView( locale );\n * const collection = new ViewCollection( locale );\n *\n * collection.setParent( parentView.element );\n *\n * const viewA = new ChildView( locale );\n * const viewB = new ChildView( locale );\n * ```\n *\n * View collection renders and manages view {@link module:ui/view~View#element elements}:\n *\n * ```ts\n * collection.add( viewA );\n * collection.add( viewB );\n *\n * console.log( parentView.element.firsChild ); // -> viewA.element\n * console.log( parentView.element.lastChild ); // -> viewB.element\n * ```\n *\n * It {@link module:ui/viewcollection~ViewCollection#delegate propagates} DOM events too:\n *\n * ```ts\n * // Delegate #click and #keydown events from viewA and viewB to the parentView.\n * collection.delegate( 'click' ).to( parentView );\n *\n * parentView.on( 'click', ( evt ) => {\n * \tconsole.log( `${ evt.source } has been clicked.` );\n * } );\n *\n * // This event will be delegated to the parentView.\n * viewB.fire( 'click' );\n * ```\n *\n * **Note**: A view collection can be used directly in the {@link module:ui/template~TemplateDefinition definition}\n * of a {@link module:ui/template~Template template}.\n */ class ViewCollection extends Collection {\n    /**\n\t * A parent element within which child views are rendered and managed in DOM.\n\t */ _parentElement;\n    /**\n\t * Creates a new instance of the {@link module:ui/viewcollection~ViewCollection}.\n\t *\n\t * @param initialItems The initial items of the collection.\n\t */ constructor(initialItems = []){\n        super(initialItems, {\n            // An #id Number attribute should be legal and not break the `ViewCollection` instance.\n            // https://github.com/ckeditor/ckeditor5-ui/issues/93\n            idProperty: 'viewUid'\n        });\n        // Handle {@link module:ui/view~View#element} in DOM when a new view is added to the collection.\n        this.on('add', (evt, view, index)=>{\n            this._renderViewIntoCollectionParent(view, index);\n        });\n        // Handle {@link module:ui/view~View#element} in DOM when a view is removed from the collection.\n        this.on('remove', (evt, view)=>{\n            if (view.element && this._parentElement) {\n                view.element.remove();\n            }\n        });\n        this._parentElement = null;\n    }\n    /**\n\t * Destroys the view collection along with child views.\n\t * See the view {@link module:ui/view~View#destroy} method.\n\t */ destroy() {\n        this.map((view)=>view.destroy());\n    }\n    /**\n\t * Sets the parent HTML element of this collection. When parent is set, {@link #add adding} and\n\t * {@link #remove removing} views in the collection synchronizes their\n\t * {@link module:ui/view~View#element elements} in the parent element.\n\t *\n\t * @param element A new parent element.\n\t */ setParent(elementOrDocFragment) {\n        this._parentElement = elementOrDocFragment;\n        // Take care of the initial collection items passed to the constructor.\n        for (const view of this){\n            this._renderViewIntoCollectionParent(view);\n        }\n    }\n    /**\n\t * Delegates selected events coming from within views in the collection to any\n\t * {@link module:utils/emittermixin~Emitter}.\n\t *\n\t * For the following views and collection:\n\t *\n\t * ```ts\n\t * const viewA = new View();\n\t * const viewB = new View();\n\t * const viewC = new View();\n\t *\n\t * const views = parentView.createCollection();\n\t *\n\t * views.delegate( 'eventX' ).to( viewB );\n\t * views.delegate( 'eventX', 'eventY' ).to( viewC );\n\t *\n\t * views.add( viewA );\n\t * ```\n\t *\n\t * the `eventX` is delegated (fired by) `viewB` and `viewC` along with `customData`:\n\t *\n\t * ```ts\n\t * viewA.fire( 'eventX', customData );\n\t * ```\n\t *\n\t * and `eventY` is delegated (fired by) `viewC` along with `customData`:\n\t *\n\t * ```ts\n\t * viewA.fire( 'eventY', customData );\n\t * ```\n\t *\n\t * See {@link module:utils/emittermixin~Emitter#delegate}.\n\t *\n\t * @param events {@link module:ui/view~View} event names to be delegated to another\n\t * {@link module:utils/emittermixin~Emitter}.\n\t * @returns Object with `to` property, a function which accepts the destination\n\t * of {@link module:utils/emittermixin~Emitter#delegate delegated} events.\n\t */ delegate(...events) {\n        if (!events.length || !isStringArray(events)) {\n            /**\n\t\t\t * All event names must be strings.\n\t\t\t *\n\t\t\t * @error ui-viewcollection-delegate-wrong-events\n\t\t\t */ throw new CKEditorError('ui-viewcollection-delegate-wrong-events', this);\n        }\n        return {\n            to: (dest)=>{\n                // Activate delegating on existing views in this collection.\n                for (const view of this){\n                    for (const evtName of events){\n                        view.delegate(evtName).to(dest);\n                    }\n                }\n                // Activate delegating on future views in this collection.\n                this.on('add', (evt, view)=>{\n                    for (const evtName of events){\n                        view.delegate(evtName).to(dest);\n                    }\n                });\n                // Deactivate delegating when view is removed from this collection.\n                this.on('remove', (evt, view)=>{\n                    for (const evtName of events){\n                        view.stopDelegating(evtName, dest);\n                    }\n                });\n            }\n        };\n    }\n    /**\n\t * This method {@link module:ui/view~View#render renders} a new view added to the collection.\n\t *\n\t * If the {@link #_parentElement parent element} of the collection is set, this method also adds\n\t * the view's {@link module:ui/view~View#element} as a child of the parent in DOM at a specified index.\n\t *\n\t * **Note**: If index is not specified, the view's element is pushed as the last child\n\t * of the parent element.\n\t *\n\t * @param view A new view added to the collection.\n\t * @param index An index the view holds in the collection. When not specified,\n\t * the view is added at the end.\n\t */ _renderViewIntoCollectionParent(view, index) {\n        if (!view.isRendered) {\n            view.render();\n        }\n        if (view.element && this._parentElement) {\n            this._parentElement.insertBefore(view.element, this._parentElement.children[index]);\n        }\n    }\n    /**\n\t * Removes a child view from the collection. If the {@link #setParent parent element} of the\n\t * collection has been set, the {@link module:ui/view~View#element element} of the view is also removed\n\t * in DOM, reflecting the order of the collection.\n\t *\n\t * See the {@link #add} method.\n\t *\n\t * @param subject The view to remove, its id or index in the collection.\n\t * @returns The removed view.\n\t */ remove(subject) {\n        return super.remove(subject);\n    }\n}\n/**\n * Check if all entries of the array are of `String` type.\n *\n * @param arr An array to be checked.\n */ function isStringArray(arr) {\n    return arr.every((a)=>typeof a == 'string');\n}\n\nconst xhtmlNs = 'http://www.w3.org/1999/xhtml';\n/**\n * A basic Template class. It renders a DOM HTML element or text from a\n * {@link module:ui/template~TemplateDefinition definition} and supports element attributes, children,\n * bindings to {@link module:utils/observablemixin~Observable observables} and DOM event propagation.\n *\n * A simple template can look like this:\n *\n * ```ts\n * const bind = Template.bind( observable, emitter );\n *\n * new Template( {\n * \ttag: 'p',\n * \tattributes: {\n * \t\tclass: 'foo',\n * \t\tstyle: {\n * \t\t\tbackgroundColor: 'yellow'\n * \t\t}\n * \t},\n * \ton: {\n * \t\tclick: bind.to( 'clicked' )\n * \t},\n * \tchildren: [\n * \t\t'A paragraph.'\n * \t]\n * } ).render();\n * ```\n *\n * and it will render the following HTML element:\n *\n * ```html\n * <p class=\"foo\" style=\"background-color: yellow;\">A paragraph.</p>\n * ```\n *\n * Additionally, the `observable` will always fire `clicked` upon clicking `<p>` in the DOM.\n *\n * See {@link module:ui/template~TemplateDefinition} to know more about templates and complex\n * template definitions.\n */ class Template extends /* #__PURE__ */ EmitterMixin() {\n    ns;\n    /**\n\t * The tag (`tagName`) of this template, e.g. `div`. It also indicates that the template\n\t * renders to an HTML element.\n\t */ tag;\n    /**\n\t * The text of the template. It also indicates that the template renders to a DOM text node.\n\t */ text;\n    /**\n\t * The attributes of the template, e.g. `{ id: [ 'ck-id' ] }`, corresponding with\n\t * the attributes of an HTML element.\n\t *\n\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t */ attributes;\n    /**\n\t * The children of the template. They can be either:\n\t * * independent instances of {@link ~Template} (sub–templates),\n\t * * native DOM Nodes.\n\t *\n\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t */ children;\n    /**\n\t * The DOM event listeners of the template.\n\t */ eventListeners;\n    /**\n\t * Indicates whether this particular Template instance has been\n\t * {@link #render rendered}.\n\t */ _isRendered;\n    /**\n\t * The data used by the {@link #revert} method to restore a node to its original state.\n\t *\n\t * See: {@link #apply}.\n\t */ _revertData;\n    /**\n\t * Creates an instance of the {@link ~Template} class.\n\t *\n\t * @param def The definition of the template.\n\t */ constructor(def){\n        super();\n        Object.assign(this, normalize(clone(def)));\n        this._isRendered = false;\n        this._revertData = null;\n    }\n    /**\n\t * Renders a DOM Node (an HTML element or text) out of the template.\n\t *\n\t * ```ts\n\t * const domNode = new Template( { ... } ).render();\n\t * ```\n\t *\n\t * See: {@link #apply}.\n\t */ render() {\n        const node = this._renderNode({\n            intoFragment: true\n        });\n        this._isRendered = true;\n        return node;\n    }\n    /**\n\t * Applies the template to an existing DOM Node, either HTML element or text.\n\t *\n\t * **Note:** No new DOM nodes will be created. Applying extends:\n\t *\n\t * {@link module:ui/template~TemplateDefinition attributes},\n\t * {@link module:ui/template~TemplateDefinition event listeners}, and\n\t * `textContent` of {@link module:ui/template~TemplateDefinition children} only.\n\t *\n\t * **Note:** Existing `class` and `style` attributes are extended when a template\n\t * is applied to an HTML element, while other attributes and `textContent` are overridden.\n\t *\n\t * **Note:** The process of applying a template can be easily reverted using the\n\t * {@link module:ui/template~Template#revert} method.\n\t *\n\t * ```ts\n\t * const element = document.createElement( 'div' );\n\t * const observable = new Model( { divClass: 'my-div' } );\n\t * const emitter = Object.create( EmitterMixin );\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \tattributes: {\n\t * \t\tid: 'first-div',\n\t * \t\tclass: bind.to( 'divClass' )\n\t * \t},\n\t * \ton: {\n\t * \t\tclick: bind( 'elementClicked' ) // Will be fired by the observable.\n\t * \t},\n\t * \tchildren: [\n\t * \t\t'Div text.'\n\t * \t]\n\t * } ).apply( element );\n\t *\n\t * console.log( element.outerHTML ); // -> '<div id=\"first-div\" class=\"my-div\"></div>'\n\t * ```\n\t *\n\t * @see module:ui/template~Template#render\n\t * @see module:ui/template~Template#revert\n\t * @param node Root node for the template to apply.\n\t */ apply(node) {\n        this._revertData = getEmptyRevertData();\n        this._renderNode({\n            node,\n            intoFragment: false,\n            isApplying: true,\n            revertData: this._revertData\n        });\n        return node;\n    }\n    /**\n\t * Reverts a template {@link module:ui/template~Template#apply applied} to a DOM node.\n\t *\n\t * @param node The root node for the template to revert. In most of the cases, it is the\n\t * same node used by {@link module:ui/template~Template#apply}.\n\t */ revert(node) {\n        if (!this._revertData) {\n            /**\n\t\t\t * Attempting to revert a template which has not been applied yet.\n\t\t\t *\n\t\t\t * @error ui-template-revert-not-applied\n\t\t\t */ throw new CKEditorError('ui-template-revert-not-applied', [\n                this,\n                node\n            ]);\n        }\n        this._revertTemplateFromNode(node, this._revertData);\n    }\n    /**\n\t * Returns an iterator which traverses the template in search of {@link module:ui/view~View}\n\t * instances and returns them one by one.\n\t *\n\t * ```ts\n\t * const viewFoo = new View();\n\t * const viewBar = new View();\n\t * const viewBaz = new View();\n\t * const template = new Template( {\n\t * \ttag: 'div',\n\t * \tchildren: [\n\t * \t\tviewFoo,\n\t * \t\t{\n\t * \t\t\ttag: 'div',\n\t * \t\t\tchildren: [\n\t * \t\t\t\tviewBar\n\t * \t\t\t]\n\t * \t\t},\n\t * \t\tviewBaz\n\t * \t]\n\t * } );\n\t *\n\t * // Logs: viewFoo, viewBar, viewBaz\n\t * for ( const view of template.getViews() ) {\n\t * \tconsole.log( view );\n\t * }\n\t * ```\n\t */ *getViews() {\n        function* search(def) {\n            if (def.children) {\n                for (const child of def.children){\n                    if (isView(child)) {\n                        yield child;\n                    } else if (isTemplate(child)) {\n                        yield* search(child);\n                    }\n                }\n            }\n        }\n        yield* search(this);\n    }\n    /**\n\t * An entry point to the interface which binds DOM nodes to\n\t * {@link module:utils/observablemixin~Observable observables}.\n\t * There are two types of bindings:\n\t *\n\t * * HTML element attributes or text `textContent` synchronized with attributes of an\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}\n\t * and {@link module:ui/template~BindChain#if}.\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \tattributes: {\n\t * \t\t// Binds the element \"class\" attribute to observable#classAttribute.\n\t * \t\tclass: bind.to( 'classAttribute' )\n\t * \t}\n\t * } ).render();\n\t * ```\n\t *\n\t * * DOM events fired on HTML element propagated through\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}.\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \ton: {\n\t * \t\t// Will be fired by the observable.\n\t * \t\tclick: bind( 'elementClicked' )\n\t * \t}\n\t * } ).render();\n\t * ```\n\t *\n\t * Also see {@link module:ui/view~View#bindTemplate}.\n\t *\n\t * @param observable An observable which provides boundable attributes.\n\t * @param emitter An emitter that listens to observable attribute\n\t * changes or DOM Events (depending on the kind of the binding). Usually, a {@link module:ui/view~View} instance.\n\t */ static bind(observable, emitter) {\n        return {\n            to (eventNameOrFunctionOrAttribute, callback) {\n                return new TemplateToBinding({\n                    eventNameOrFunction: eventNameOrFunctionOrAttribute,\n                    attribute: eventNameOrFunctionOrAttribute,\n                    observable,\n                    emitter,\n                    callback\n                });\n            },\n            if (attribute, valueIfTrue, callback) {\n                return new TemplateIfBinding({\n                    observable,\n                    emitter,\n                    attribute,\n                    valueIfTrue,\n                    callback\n                });\n            }\n        };\n    }\n    /**\n\t * Extends an existing {@link module:ui/template~Template} instance with some additional content\n\t * from another {@link module:ui/template~TemplateDefinition}.\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * const template = new Template( {\n\t * \ttag: 'p',\n\t * \tattributes: {\n\t * \t\tclass: 'a',\n\t * \t\tdata-x: bind.to( 'foo' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t{\n\t * \t\t\ttag: 'span',\n\t * \t\t\tattributes: {\n\t * \t\t\t\tclass: 'b'\n\t * \t\t\t},\n\t * \t\t\tchildren: [\n\t * \t\t\t\t'Span'\n\t * \t\t\t]\n\t * \t\t}\n\t * \t]\n\t *  } );\n\t *\n\t * // Instance-level extension.\n\t * Template.extend( template, {\n\t * \tattributes: {\n\t * \t\tclass: 'b',\n\t * \t\tdata-x: bind.to( 'bar' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t{\n\t * \t\t\tattributes: {\n\t * \t\t\t\tclass: 'c'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t]\n\t * } );\n\t *\n\t * // Child extension.\n\t * Template.extend( template.children[ 0 ], {\n\t * \tattributes: {\n\t * \t\tclass: 'd'\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * the `outerHTML` of `template.render()` is:\n\t *\n\t * ```html\n\t * <p class=\"a b\" data-x=\"{ observable.foo } { observable.bar }\">\n\t * \t<span class=\"b c d\">Span</span>\n\t * </p>\n\t * ```\n\t *\n\t * @param template An existing template instance to be extended.\n\t * @param def Additional definition to be applied to a template.\n\t */ static extend(template, def) {\n        if (template._isRendered) {\n            /**\n\t\t\t * Extending a template after rendering may not work as expected. To make sure\n\t\t\t * the {@link module:ui/template~Template.extend extending} works for an element,\n\t\t\t * make sure it happens before {@link module:ui/template~Template#render} is called.\n\t\t\t *\n\t\t\t * @error template-extend-render\n\t\t\t */ throw new CKEditorError('template-extend-render', [\n                this,\n                template\n            ]);\n        }\n        extendTemplate(template, normalize(clone(def)));\n    }\n    /**\n\t * Renders a DOM Node (either an HTML element or text) out of the template.\n\t *\n\t * @param data Rendering data.\n\t */ _renderNode(data) {\n        let isInvalid;\n        if (data.node) {\n            // When applying, a definition cannot have \"tag\" and \"text\" at the same time.\n            isInvalid = this.tag && this.text;\n        } else {\n            // When rendering, a definition must have either \"tag\" or \"text\": XOR( this.tag, this.text ).\n            isInvalid = this.tag ? this.text : !this.text;\n        }\n        if (isInvalid) {\n            /**\n\t\t\t * Node definition cannot have the \"tag\" and \"text\" properties at the same time.\n\t\t\t * Node definition must have either \"tag\" or \"text\" when rendering a new Node.\n\t\t\t *\n\t\t\t * @error ui-template-wrong-syntax\n\t\t\t */ throw new CKEditorError('ui-template-wrong-syntax', this);\n        }\n        if (this.text) {\n            return this._renderText(data);\n        } else {\n            return this._renderElement(data);\n        }\n    }\n    /**\n\t * Renders an HTML element out of the template.\n\t *\n\t * @param data Rendering data.\n\t */ _renderElement(data) {\n        let node = data.node;\n        if (!node) {\n            node = data.node = document.createElementNS(this.ns || xhtmlNs, this.tag);\n        }\n        this._renderAttributes(data);\n        this._renderElementChildren(data);\n        this._setUpListeners(data);\n        return node;\n    }\n    /**\n\t * Renders a text node out of {@link module:ui/template~Template#text}.\n\t *\n\t * @param data Rendering data.\n\t */ _renderText(data) {\n        let node = data.node;\n        // Save the original textContent to revert it in #revert().\n        if (node) {\n            data.revertData.text = node.textContent;\n        } else {\n            node = data.node = document.createTextNode('');\n        }\n        // Check if this Text Node is bound to Observable. Cases:\n        //\n        //\t\ttext: [ Template.bind( ... ).to( ... ) ]\n        //\n        //\t\ttext: [\n        //\t\t\t'foo',\n        //\t\t\tTemplate.bind( ... ).to( ... ),\n        //\t\t\t...\n        //\t\t]\n        //\n        if (hasTemplateBinding(this.text)) {\n            this._bindToObservable({\n                schema: this.text,\n                updater: getTextUpdater(node),\n                data\n            });\n        } else {\n            node.textContent = this.text.join('');\n        }\n        return node;\n    }\n    /**\n\t * Renders HTML element attributes out of {@link module:ui/template~Template#attributes}.\n\t *\n\t * @param data Rendering data.\n\t */ _renderAttributes(data) {\n        if (!this.attributes) {\n            return;\n        }\n        const node = data.node;\n        const revertData = data.revertData;\n        for(const attrName in this.attributes){\n            // Current attribute value in DOM.\n            const domAttrValue = node.getAttribute(attrName);\n            // The value to be set.\n            const attrValue = this.attributes[attrName];\n            // Save revert data.\n            if (revertData) {\n                revertData.attributes[attrName] = domAttrValue;\n            }\n            // Detect custom namespace:\n            //\n            //\t\tclass: {\n            //\t\t\tns: 'abc',\n            //\t\t\tvalue: Template.bind( ... ).to( ... )\n            //\t\t}\n            //\n            const attrNs = isNamespaced(attrValue) ? attrValue[0].ns : null;\n            // Activate binding if one is found. Cases:\n            //\n            //\t\tclass: [\n            //\t\t\tTemplate.bind( ... ).to( ... )\n            //\t\t]\n            //\n            //\t\tclass: [\n            //\t\t\t'bar',\n            //\t\t\tTemplate.bind( ... ).to( ... ),\n            //\t\t\t'baz'\n            //\t\t]\n            //\n            //\t\tclass: {\n            //\t\t\tns: 'abc',\n            //\t\t\tvalue: Template.bind( ... ).to( ... )\n            //\t\t}\n            //\n            if (hasTemplateBinding(attrValue)) {\n                // Normalize attributes with additional data like namespace:\n                //\n                //\t\tclass: {\n                //\t\t\tns: 'abc',\n                //\t\t\tvalue: [ ... ]\n                //\t\t}\n                //\n                const valueToBind = isNamespaced(attrValue) ? attrValue[0].value : attrValue;\n                // Extend the original value of attributes like \"style\" and \"class\",\n                // don't override them.\n                if (revertData && shouldExtend(attrName)) {\n                    valueToBind.unshift(domAttrValue);\n                }\n                this._bindToObservable({\n                    schema: valueToBind,\n                    updater: getAttributeUpdater(node, attrName, attrNs),\n                    data\n                });\n            } else if (attrName == 'style' && typeof attrValue[0] !== 'string') {\n                this._renderStyleAttribute(attrValue[0], data);\n            } else {\n                // Extend the original value of attributes like \"style\" and \"class\",\n                // don't override them.\n                if (revertData && domAttrValue && shouldExtend(attrName)) {\n                    attrValue.unshift(domAttrValue);\n                }\n                const value = attrValue// Retrieve \"values\" from:\n                //\n                //\t\tclass: [\n                //\t\t\t{\n                //\t\t\t\tns: 'abc',\n                //\t\t\t\tvalue: [ ... ]\n                //\t\t\t}\n                //\t\t]\n                //\n                .map((val)=>val ? val.value || val : val)// Flatten the array.\n                .reduce((prev, next)=>prev.concat(next), [])// Convert into string.\n                .reduce(arrayValueReducer, '');\n                if (!isFalsy(value)) {\n                    node.setAttributeNS(attrNs, attrName, value);\n                }\n            }\n        }\n    }\n    /**\n\t * Renders the `style` attribute of an HTML element based on\n\t * {@link module:ui/template~Template#attributes}.\n\t *\n\t * A style attribute is an object with static values:\n\t *\n\t * ```ts\n\t * attributes: {\n\t * \tstyle: {\n\t * \t\tcolor: 'red'\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * or values bound to {@link module:ui/model~Model} properties:\n\t *\n\t * ```ts\n\t * attributes: {\n\t * \tstyle: {\n\t * \t\tcolor: bind.to( ... )\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * Note: The `style` attribute is rendered without setting the namespace. It does not seem to be\n\t * needed.\n\t *\n\t * @param styles Styles located in `attributes.style` of {@link module:ui/template~TemplateDefinition}.\n\t * @param data Rendering data.\n\t */ _renderStyleAttribute(styles, data) {\n        const node = data.node;\n        for(const styleName in styles){\n            const styleValue = styles[styleName];\n            // Cases:\n            //\n            //\t\tstyle: {\n            //\t\t\tcolor: bind.to( 'attribute' )\n            //\t\t}\n            //\n            if (hasTemplateBinding(styleValue)) {\n                this._bindToObservable({\n                    schema: [\n                        styleValue\n                    ],\n                    updater: getStyleUpdater(node, styleName),\n                    data\n                });\n            } else {\n                node.style[styleName] = styleValue;\n            }\n        }\n    }\n    /**\n\t * Recursively renders HTML element's children from {@link module:ui/template~Template#children}.\n\t *\n\t * @param data Rendering data.\n\t */ _renderElementChildren(data) {\n        const node = data.node;\n        const container = data.intoFragment ? document.createDocumentFragment() : node;\n        const isApplying = data.isApplying;\n        let childIndex = 0;\n        for (const child of this.children){\n            if (isViewCollection(child)) {\n                if (!isApplying) {\n                    child.setParent(node);\n                    // Note: ViewCollection renders its children.\n                    for (const view of child){\n                        container.appendChild(view.element);\n                    }\n                }\n            } else if (isView(child)) {\n                if (!isApplying) {\n                    if (!child.isRendered) {\n                        child.render();\n                    }\n                    container.appendChild(child.element);\n                }\n            } else if (isNode(child)) {\n                container.appendChild(child);\n            } else {\n                if (isApplying) {\n                    const revertData = data.revertData;\n                    const childRevertData = getEmptyRevertData();\n                    revertData.children.push(childRevertData);\n                    child._renderNode({\n                        intoFragment: false,\n                        node: container.childNodes[childIndex++],\n                        isApplying: true,\n                        revertData: childRevertData\n                    });\n                } else {\n                    container.appendChild(child.render());\n                }\n            }\n        }\n        if (data.intoFragment) {\n            node.appendChild(container);\n        }\n    }\n    /**\n\t * Activates `on` event listeners from the {@link module:ui/template~TemplateDefinition}\n\t * on an HTML element.\n\t *\n\t * @param data Rendering data.\n\t */ _setUpListeners(data) {\n        if (!this.eventListeners) {\n            return;\n        }\n        for(const key in this.eventListeners){\n            const revertBindings = this.eventListeners[key].map((schemaItem)=>{\n                const [domEvtName, domSelector] = key.split('@');\n                return schemaItem.activateDomEventListener(domEvtName, domSelector, data);\n            });\n            if (data.revertData) {\n                data.revertData.bindings.push(revertBindings);\n            }\n        }\n    }\n    /**\n\t * For a given {@link module:ui/template~TemplateValueSchema} containing {@link module:ui/template~TemplateBinding}\n\t * activates the binding and sets its initial value.\n\t *\n\t * Note: {@link module:ui/template~TemplateValueSchema} can be for HTML element attributes or\n\t * text node `textContent`.\n\t *\n\t * @param options Binding options.\n\t * @param options.updater A function which updates the DOM (like attribute or text).\n\t * @param options.data Rendering data.\n\t */ _bindToObservable({ schema, updater, data }) {\n        const revertData = data.revertData;\n        // Set initial values.\n        syncValueSchemaValue(schema, updater, data);\n        const revertBindings = schema// Filter \"falsy\" (false, undefined, null, '') value schema components out.\n        .filter((item)=>!isFalsy(item))// Filter inactive bindings from schema, like static strings ('foo'), numbers (42), etc.\n        .filter((item)=>item.observable)// Once only the actual binding are left, let the emitter listen to observable change:attribute event.\n        // TODO: Reduce the number of listeners attached as many bindings may listen\n        // to the same observable attribute.\n        .map((templateBinding)=>templateBinding.activateAttributeListener(schema, updater, data));\n        if (revertData) {\n            revertData.bindings.push(revertBindings);\n        }\n    }\n    /**\n\t * Reverts {@link module:ui/template~RenderData#revertData template data} from a node to\n\t * return it to the original state.\n\t *\n\t * @param node A node to be reverted.\n\t * @param revertData An object that stores information about what changes have been made by\n\t * {@link #apply} to the node. See {@link module:ui/template~RenderData#revertData} for more information.\n\t */ _revertTemplateFromNode(node, revertData) {\n        for (const binding of revertData.bindings){\n            // Each binding may consist of several observable+observable#attribute.\n            // like the following has 2:\n            //\n            //\t\tclass: [\n            //\t\t\t'x',\n            //\t\t\tbind.to( 'foo' ),\n            //\t\t\t'y',\n            //\t\t\tbind.to( 'bar' )\n            //\t\t]\n            //\n            for (const revertBinding of binding){\n                revertBinding();\n            }\n        }\n        if (revertData.text) {\n            node.textContent = revertData.text;\n            return;\n        }\n        const element = node;\n        for(const attrName in revertData.attributes){\n            const attrValue = revertData.attributes[attrName];\n            // When the attribute has **not** been set before #apply().\n            if (attrValue === null) {\n                element.removeAttribute(attrName);\n            } else {\n                element.setAttribute(attrName, attrValue);\n            }\n        }\n        for(let i = 0; i < revertData.children.length; ++i){\n            this._revertTemplateFromNode(element.childNodes[i], revertData.children[i]);\n        }\n    }\n}\n/**\n * Describes a binding created by the {@link module:ui/template~Template.bind} interface.\n *\n * @internal\n */ class TemplateBinding {\n    /**\n\t * The name of the {@link module:ui/template~TemplateBinding#observable observed attribute}.\n\t */ attribute;\n    /**\n\t * An observable instance of the binding. It either:\n\t *\n\t * * provides the attribute with the value,\n\t * * or passes the event when a corresponding DOM event is fired.\n\t */ observable;\n    /**\n\t * An {@link module:utils/emittermixin~Emitter} used by the binding to:\n\t *\n\t * * listen to the attribute change in the {@link module:ui/template~TemplateBinding#observable},\n\t * * or listen to the event in the DOM.\n\t */ emitter;\n    /**\n\t * A custom function to process the value of the {@link module:ui/template~TemplateBinding#attribute}.\n\t */ callback;\n    /**\n\t * Creates an instance of the {@link module:ui/template~TemplateBinding} class.\n\t *\n\t * @param def The definition of the binding.\n\t */ constructor(def){\n        this.attribute = def.attribute;\n        this.observable = def.observable;\n        this.emitter = def.emitter;\n        this.callback = def.callback;\n    }\n    /**\n\t * Returns the value of the binding. It is the value of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}. The value may be processed by the\n\t * {@link module:ui/template~TemplateBinding#callback}, if such has been passed to the binding.\n\t *\n\t * @param node A native DOM node, passed to the custom {@link module:ui/template~TemplateBinding#callback}.\n\t * @returns The value of {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}.\n\t */ getValue(node) {\n        const value = this.observable[this.attribute];\n        return this.callback ? this.callback(value, node) : value;\n    }\n    /**\n\t * Activates the listener which waits for changes of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}, then updates the DOM with the aggregated\n\t * value of {@link module:ui/template~TemplateValueSchema}.\n\t *\n\t * @param schema A full schema to generate an attribute or text in the DOM.\n\t * @param updater A DOM updater function used to update the native DOM attribute or text.\n\t * @param data Rendering data.\n\t * @returns A function to sever the listener binding.\n\t */ activateAttributeListener(schema, updater, data) {\n        const callback = ()=>syncValueSchemaValue(schema, updater, data);\n        this.emitter.listenTo(this.observable, `change:${this.attribute}`, callback);\n        // Allows revert of the listener.\n        return ()=>{\n            this.emitter.stopListening(this.observable, `change:${this.attribute}`, callback);\n        };\n    }\n}\n/**\n * Describes either:\n *\n * * a binding to an {@link module:utils/observablemixin~Observable},\n * * or a native DOM event binding.\n *\n * It is created by the {@link module:ui/template~BindChain#to} method.\n *\n * @internal\n */ class TemplateToBinding extends TemplateBinding {\n    eventNameOrFunction;\n    constructor(def){\n        super(def);\n        this.eventNameOrFunction = def.eventNameOrFunction;\n    }\n    /**\n\t * Activates the listener for the native DOM event, which when fired, is propagated by\n\t * the {@link module:ui/template~TemplateBinding#emitter}.\n\t *\n\t * @param domEvtName The name of the native DOM event.\n\t * @param domSelector The selector in the DOM to filter delegated events.\n\t * @param data Rendering data.\n\t * @returns A function to sever the listener binding.\n\t */ activateDomEventListener(domEvtName, domSelector, data) {\n        const callback = (evt, domEvt)=>{\n            if (!domSelector || domEvt.target.matches(domSelector)) {\n                if (typeof this.eventNameOrFunction == 'function') {\n                    this.eventNameOrFunction(domEvt);\n                } else {\n                    this.observable.fire(this.eventNameOrFunction, domEvt);\n                }\n            }\n        };\n        this.emitter.listenTo(data.node, domEvtName, callback);\n        // Allows revert of the listener.\n        return ()=>{\n            this.emitter.stopListening(data.node, domEvtName, callback);\n        };\n    }\n}\n/**\n * Describes a binding to {@link module:utils/observablemixin~Observable} created by the {@link module:ui/template~BindChain#if}\n * method.\n *\n * @internal\n */ class TemplateIfBinding extends TemplateBinding {\n    /**\n\t * The value of the DOM attribute or text to be set if the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable} is `true`.\n\t */ valueIfTrue;\n    constructor(def){\n        super(def);\n        this.valueIfTrue = def.valueIfTrue;\n    }\n    /**\n\t * @inheritDoc\n\t */ getValue(node) {\n        const value = super.getValue(node);\n        return isFalsy(value) ? false : this.valueIfTrue || true;\n    }\n}\n/**\n * Checks whether given {@link module:ui/template~TemplateValueSchema} contains a\n * {@link module:ui/template~TemplateBinding}.\n */ function hasTemplateBinding(schema) {\n    if (!schema) {\n        return false;\n    }\n    // Normalize attributes with additional data like namespace:\n    //\n    //\t\tclass: {\n    //\t\t\tns: 'abc',\n    //\t\t\tvalue: [ ... ]\n    //\t\t}\n    //\n    if (schema.value) {\n        schema = schema.value;\n    }\n    if (Array.isArray(schema)) {\n        return schema.some(hasTemplateBinding);\n    } else if (schema instanceof TemplateBinding) {\n        return true;\n    }\n    return false;\n}\n/**\n * Assembles the value using {@link module:ui/template~TemplateValueSchema} and stores it in a form of\n * an Array. Each entry of the Array corresponds to one of {@link module:ui/template~TemplateValueSchema}\n * items.\n *\n * @param node DOM Node updated when {@link module:utils/observablemixin~Observable} changes.\n */ function getValueSchemaValue(schema, node) {\n    return schema.map((schemaItem)=>{\n        // Process {@link module:ui/template~TemplateBinding} bindings.\n        if (schemaItem instanceof TemplateBinding) {\n            return schemaItem.getValue(node);\n        }\n        // All static values like strings, numbers, and \"falsy\" values (false, null, undefined, '', etc.) just pass.\n        return schemaItem;\n    });\n}\n/**\n * A function executed each time the bound Observable attribute changes, which updates the DOM with a value\n * constructed from {@link module:ui/template~TemplateValueSchema}.\n *\n * @param updater A function which updates the DOM (like attribute or text).\n * @param node DOM Node updated when {@link module:utils/observablemixin~Observable} changes.\n */ function syncValueSchemaValue(schema, updater, { node }) {\n    const values = getValueSchemaValue(schema, node);\n    let value;\n    // Check if schema is a single Template.bind.if, like:\n    //\n    //\t\tclass: Template.bind.if( 'foo' )\n    //\n    if (schema.length == 1 && schema[0] instanceof TemplateIfBinding) {\n        value = values[0];\n    } else {\n        value = values.reduce(arrayValueReducer, '');\n    }\n    if (isFalsy(value)) {\n        updater.remove();\n    } else {\n        updater.set(value);\n    }\n}\n/**\n * Returns an object consisting of `set` and `remove` functions, which\n * can be used in the context of DOM Node to set or reset `textContent`.\n * @see module:ui/view~View#_bindToObservable\n *\n * @param node DOM Node to be modified.\n */ function getTextUpdater(node) {\n    return {\n        set (value) {\n            node.textContent = value;\n        },\n        remove () {\n            node.textContent = '';\n        }\n    };\n}\n/**\n * Returns an object consisting of `set` and `remove` functions, which\n * can be used in the context of DOM Node to set or reset an attribute.\n * @see module:ui/view~View#_bindToObservable\n *\n * @param el DOM Node to be modified.\n * @param attrName Name of the attribute to be modified.\n * @param ns Namespace to use.\n */ function getAttributeUpdater(el, attrName, ns) {\n    return {\n        set (value) {\n            el.setAttributeNS(ns, attrName, value);\n        },\n        remove () {\n            el.removeAttributeNS(ns, attrName);\n        }\n    };\n}\n/**\n * Returns an object consisting of `set` and `remove` functions, which\n * can be used in the context of CSSStyleDeclaration to set or remove a style.\n * @see module:ui/view~View#_bindToObservable\n *\n * @param el DOM Node to be modified.\n * @param styleName Name of the style to be modified.\n */ function getStyleUpdater(el, styleName) {\n    return {\n        set (value) {\n            el.style[styleName] = value;\n        },\n        remove () {\n            el.style[styleName] = null;\n        }\n    };\n}\n/**\n * Clones definition of the template.\n */ function clone(def) {\n    const clone = cloneDeepWith(def, (value)=>{\n        // Don't clone the `Template.bind`* bindings because of the references to Observable\n        // and DomEmitterMixin instances inside, which would also be traversed and cloned by greedy\n        // cloneDeepWith algorithm. There's no point in cloning Observable/DomEmitterMixins\n        // along with the definition.\n        //\n        // Don't clone Template instances if provided as a child. They're simply #render()ed\n        // and nothing should interfere.\n        //\n        // Also don't clone View instances if provided as a child of the Template. The template\n        // instance will be extracted from the View during the normalization and there's no need\n        // to clone it.\n        if (value && (value instanceof TemplateBinding || isTemplate(value) || isView(value) || isViewCollection(value))) {\n            return value;\n        }\n    });\n    return clone;\n}\n/**\n * Normalizes given {@link module:ui/template~TemplateDefinition}.\n *\n * See:\n *  * {@link normalizeAttributes}\n *  * {@link normalizeListeners}\n *  * {@link normalizePlainTextDefinition}\n *  * {@link normalizeTextDefinition}\n *\n * @param def A template definition.\n * @returns Normalized definition.\n */ function normalize(def) {\n    if (typeof def == 'string') {\n        def = normalizePlainTextDefinition(def);\n    } else if (def.text) {\n        normalizeTextDefinition(def);\n    }\n    if (def.on) {\n        def.eventListeners = normalizeListeners(def.on);\n        // Template mixes EmitterMixin, so delete #on to avoid collision.\n        delete def.on;\n    }\n    if (!def.text) {\n        if (def.attributes) {\n            normalizeAttributes(def.attributes);\n        }\n        const children = [];\n        if (def.children) {\n            if (isViewCollection(def.children)) {\n                children.push(def.children);\n            } else {\n                for (const child of def.children){\n                    if (isTemplate(child) || isView(child) || isNode(child)) {\n                        children.push(child);\n                    } else {\n                        children.push(new Template(child));\n                    }\n                }\n            }\n        }\n        def.children = children;\n    }\n    return def;\n}\n/**\n * Normalizes \"attributes\" section of {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * attributes: {\n * \ta: 'bar',\n * \tb: {@link module:ui/template~TemplateBinding},\n * \tc: {\n * \t\tvalue: 'bar'\n * \t}\n * }\n * ```\n *\n * becomes\n *\n * ```\n * attributes: {\n * \ta: [ 'bar' ],\n * \tb: [ {@link module:ui/template~TemplateBinding} ],\n * \tc: {\n * \t\tvalue: [ 'bar' ]\n * \t}\n * }\n * ```\n */ function normalizeAttributes(attributes) {\n    for(const a in attributes){\n        if (attributes[a].value) {\n            attributes[a].value = toArray(attributes[a].value);\n        }\n        arrayify(attributes, a);\n    }\n}\n/**\n * Normalizes \"on\" section of {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * on: {\n * \ta: 'bar',\n * \tb: {@link module:ui/template~TemplateBinding},\n * \tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n * }\n * ```\n *\n * becomes\n *\n * ```\n * on: {\n * \ta: [ 'bar' ],\n * \tb: [ {@link module:ui/template~TemplateBinding} ],\n * \tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n * }\n * ```\n *\n * @returns Object containing normalized listeners.\n */ function normalizeListeners(listeners) {\n    for(const l in listeners){\n        arrayify(listeners, l);\n    }\n    return listeners;\n}\n/**\n * Normalizes \"string\" {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * \"foo\"\n * ```\n *\n * becomes\n *\n * ```\n * { text: [ 'foo' ] },\n * ```\n *\n * @returns Normalized template definition.\n */ function normalizePlainTextDefinition(def) {\n    return {\n        text: [\n            def\n        ]\n    };\n}\n/**\n * Normalizes text {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * children: [\n * \t{ text: 'def' },\n * \t{ text: {@link module:ui/template~TemplateBinding} }\n * ]\n * ```\n *\n * becomes\n *\n * ```\n * children: [\n * \t{ text: [ 'def' ] },\n * \t{ text: [ {@link module:ui/template~TemplateBinding} ] }\n * ]\n * ```\n */ function normalizeTextDefinition(def) {\n    def.text = toArray(def.text);\n}\n/**\n * Wraps an entry in Object in an Array, if not already one.\n *\n * ```\n * {\n * \tx: 'y',\n * \ta: [ 'b' ]\n * }\n * ```\n *\n * becomes\n *\n * ```\n * {\n * \tx: [ 'y' ],\n * \ta: [ 'b' ]\n * }\n * ```\n */ function arrayify(obj, key) {\n    obj[key] = toArray(obj[key]);\n}\n/**\n * A helper which concatenates the value avoiding unwanted\n * leading white spaces.\n */ function arrayValueReducer(prev, cur) {\n    if (isFalsy(cur)) {\n        return prev;\n    } else if (isFalsy(prev)) {\n        return cur;\n    } else {\n        return `${prev} ${cur}`;\n    }\n}\n/**\n * Extends one object defined in the following format:\n *\n * ```\n * {\n * \tkey1: [Array1],\n * \tkey2: [Array2],\n * \t...\n * \tkeyN: [ArrayN]\n * }\n * ```\n *\n * with another object of the same data format.\n *\n * @param obj Base object.\n * @param ext Object extending base.\n */ function extendObjectValueArray(obj, ext) {\n    for(const a in ext){\n        if (obj[a]) {\n            obj[a].push(...ext[a]);\n        } else {\n            obj[a] = ext[a];\n        }\n    }\n}\n/**\n * A helper for {@link module:ui/template~Template#extend}. Recursively extends {@link module:ui/template~Template} instance\n * with content from {@link module:ui/template~TemplateDefinition}. See {@link module:ui/template~Template#extend} to learn more.\n *\n * @param def A template instance to be extended.\n * @param def A definition which is to extend the template instance.\n * @param Error context.\n */ function extendTemplate(template, def) {\n    if (def.attributes) {\n        if (!template.attributes) {\n            template.attributes = {};\n        }\n        extendObjectValueArray(template.attributes, def.attributes);\n    }\n    if (def.eventListeners) {\n        if (!template.eventListeners) {\n            template.eventListeners = {};\n        }\n        extendObjectValueArray(template.eventListeners, def.eventListeners);\n    }\n    if (def.text) {\n        template.text.push(...def.text);\n    }\n    if (def.children && def.children.length) {\n        if (template.children.length != def.children.length) {\n            /**\n\t\t\t * The number of children in extended definition does not match.\n\t\t\t *\n\t\t\t * @error ui-template-extend-children-mismatch\n\t\t\t */ throw new CKEditorError('ui-template-extend-children-mismatch', template);\n        }\n        let childIndex = 0;\n        for (const childDef of def.children){\n            extendTemplate(template.children[childIndex++], childDef);\n        }\n    }\n}\n/**\n * Checks if value is \"falsy\".\n * Note: 0 (Number) is not \"falsy\" in this context.\n *\n * @param value Value to be checked.\n */ function isFalsy(value) {\n    return !value && value !== 0;\n}\n/**\n * Checks if the item is an instance of {@link module:ui/view~View}\n *\n * @param value Value to be checked.\n */ function isView(item) {\n    return item instanceof View;\n}\n/**\n * Checks if the item is an instance of {@link module:ui/template~Template}\n *\n * @param value Value to be checked.\n */ function isTemplate(item) {\n    return item instanceof Template;\n}\n/**\n * Checks if the item is an instance of {@link module:ui/viewcollection~ViewCollection}\n *\n * @param value Value to be checked.\n */ function isViewCollection(item) {\n    return item instanceof ViewCollection;\n}\n/**\n * Checks if value array contains the one with namespace.\n */ function isNamespaced(attrValue) {\n    return isObject(attrValue[0]) && attrValue[0].ns;\n}\n/**\n * Creates an empty skeleton for {@link module:ui/template~Template#revert}\n * data.\n */ function getEmptyRevertData() {\n    return {\n        children: [],\n        bindings: [],\n        attributes: {}\n    };\n}\n/**\n * Checks whether an attribute should be extended when\n * {@link module:ui/template~Template#apply} is called.\n *\n * @param attrName Attribute name to check.\n */ function shouldExtend(attrName) {\n    return attrName == 'class' || attrName == 'style';\n}\n\n/**\n * The basic view class, which represents an HTML element created out of a\n * {@link module:ui/view~View#template}. Views are building blocks of the user interface and handle\n * interaction\n *\n * Views {@link module:ui/view~View#registerChild aggregate} children in\n * {@link module:ui/view~View#createCollection collections} and manage the life cycle of DOM\n * listeners e.g. by handling rendering and destruction.\n *\n * See the {@link module:ui/template~TemplateDefinition} syntax to learn more about shaping view\n * elements, attributes and listeners.\n *\n * ```ts\n * class SampleView extends View {\n * \tconstructor( locale ) {\n * \t\tsuper( locale );\n *\n * \t\tconst bind = this.bindTemplate;\n *\n * \t\t// Views define their interface (state) using observable attributes.\n * \t\tthis.set( 'elementClass', 'bar' );\n *\n * \t\tthis.setTemplate( {\n * \t\t\ttag: 'p',\n *\n * \t\t\t// The element of the view can be defined with its children.\n * \t\t\tchildren: [\n * \t\t\t\t'Hello',\n * \t\t\t\t{\n * \t\t\t\t\ttag: 'b',\n * \t\t\t\t\tchildren: [ 'world!' ]\n * \t\t\t\t}\n * \t\t\t],\n * \t\t\tattributes: {\n * \t\t\t\tclass: [\n * \t\t\t\t\t'foo',\n *\n * \t\t\t\t\t// Observable attributes control the state of the view in DOM.\n * \t\t\t\t\tbind.to( 'elementClass' )\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\ton: {\n * \t\t\t\t// Views listen to DOM events and propagate them.\n * \t\t\t\tclick: bind.to( 'clicked' )\n * \t\t\t}\n * \t\t} );\n * \t}\n * }\n *\n * const view = new SampleView( locale );\n *\n * view.render();\n *\n * // Append <p class=\"foo bar\">Hello<b>world</b></p> to the <body>\n * document.body.appendChild( view.element );\n *\n * // Change the class attribute to <p class=\"foo baz\">Hello<b>world</b></p>\n * view.elementClass = 'baz';\n *\n * // Respond to the \"click\" event in DOM by executing a custom action.\n * view.on( 'clicked', () => {\n * \tconsole.log( 'The view has been clicked!' );\n * } );\n * ```\n */ class View extends /* #__PURE__ */ DomEmitterMixin(/* #__PURE__ */ ObservableMixin()) {\n    /**\n\t * An HTML element of the view. `null` until {@link #render rendered}\n\t * from the {@link #template}.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor() {\n\t * \t\tsuper();\n\t *\n\t * \t\t// A template instance the #element will be created from.\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p'\n\t *\n\t * \t\t\t// ...\n\t * \t\t} );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView();\n\t *\n\t * // Renders the #template.\n\t * view.render();\n\t *\n\t * // Append the HTML element of the view to <body>.\n\t * document.body.appendChild( view.element );\n\t * ```\n\t *\n\t * **Note**: The element of the view can also be assigned directly:\n\t *\n\t * ```ts\n\t * view.element = document.querySelector( '#my-container' );\n\t * ```\n\t */ element;\n    /**\n\t * Set `true` when the view has already been {@link module:ui/view~View#render rendered}.\n\t *\n\t * @readonly\n\t */ isRendered;\n    /**\n\t * A set of tools to localize the user interface.\n\t *\n\t * Also see {@link module:core/editor/editor~Editor#locale}.\n\t *\n\t * @readonly\n\t */ locale;\n    /**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t *\n\t * Note: If {@link #locale} instance hasn't been passed to the view this method may not\n\t * be available.\n\t *\n\t * @see module:utils/locale~Locale#t\n\t */ t;\n    /**\n\t * Template of this view. It provides the {@link #element} representing\n\t * the view in DOM, which is {@link #render rendered}.\n\t */ template;\n    /**\n\t * Collections registered with {@link #createCollection}.\n\t */ _viewCollections;\n    /**\n\t * A collection of view instances, which have been added directly\n\t * into the {@link module:ui/template~Template#children}.\n\t */ _unboundChildren;\n    /**\n\t * Cached {@link module:ui/template~BindChain bind chain} object created by the\n\t * {@link #template}. See {@link #bindTemplate}.\n\t */ _bindTemplate;\n    /**\n\t * Creates an instance of the {@link module:ui/view~View} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super();\n        this.element = null;\n        this.isRendered = false;\n        this.locale = locale;\n        this.t = locale && locale.t;\n        this._viewCollections = new Collection();\n        this._unboundChildren = this.createCollection();\n        // Pass parent locale to its children.\n        this._viewCollections.on('add', (evt, collection)=>{\n            collection.locale = locale;\n            collection.t = locale && locale.t;\n        });\n        this.decorate('render');\n    }\n    /**\n\t * Shorthand for {@link module:ui/template~Template.bind}, a binding\n\t * {@link module:ui/template~BindChain interface} pre–configured for the view instance.\n\t *\n\t * It provides {@link module:ui/template~BindChain#to `to()`} and\n\t * {@link module:ui/template~BindChain#if `if()`} methods that initialize bindings with\n\t * observable attributes and attach DOM listeners.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tconst bind = this.bindTemplate;\n\t *\n\t * \t\t// These {@link module:utils/observablemixin~Observable observable} attributes will control\n\t * \t\t// the state of the view in DOM.\n\t * \t\tthis.set( {\n\t * \t\t\telementClass: 'foo',\n\t * \t\t \tisEnabled: true\n\t * \t\t } );\n\t *\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p',\n\t *\n\t * \t\t\tattributes: {\n\t * \t\t\t\t// The class HTML attribute will follow elementClass\n\t * \t\t\t\t// and isEnabled view attributes.\n\t * \t\t\t\tclass: [\n\t * \t\t\t\t\tbind.to( 'elementClass' )\n\t * \t\t\t\t\tbind.if( 'isEnabled', 'present-when-enabled' )\n\t * \t\t\t\t]\n\t * \t\t\t},\n\t *\n\t * \t\t\ton: {\n\t * \t\t\t\t// The view will fire the \"clicked\" event upon clicking <p> in DOM.\n\t * \t\t\t\tclick: bind.to( 'clicked' )\n\t * \t\t\t}\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t */ get bindTemplate() {\n        if (this._bindTemplate) {\n            return this._bindTemplate;\n        }\n        return this._bindTemplate = Template.bind(this, this);\n    }\n    /**\n\t * Creates a new collection of views, which can be used as\n\t * {@link module:ui/template~Template#children} of this view.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tconst child = new ChildView( locale );\n\t * \t\tthis.items = this.createCollection( [ child ] );\n \t *\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p',\n\t *\n\t * \t\t\t// `items` collection will render here.\n\t * \t\t\tchildren: this.items\n\t * \t\t} );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView( locale );\n\t * view.render();\n\t *\n\t * // It will append <p><child#element></p> to the <body>.\n\t * document.body.appendChild( view.element );\n\t * ```\n\t *\n\t * @param views Initial views of the collection.\n\t * @returns A new collection of view instances.\n\t */ createCollection(views) {\n        const collection = new ViewCollection(views);\n        this._viewCollections.add(collection);\n        return collection;\n    }\n    /**\n\t * Registers a new child view under the view instance. Once registered, a child\n\t * view is managed by its parent, including {@link #render rendering}\n\t * and {@link #destroy destruction}.\n\t *\n\t * To revert this, use {@link #deregisterChild}.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tthis.childA = new SomeChildView( locale );\n\t * \t\tthis.childB = new SomeChildView( locale );\n\t *\n\t * \t\tthis.setTemplate( { tag: 'p' } );\n\t *\n\t * \t\t// Register the children.\n\t * \t\tthis.registerChild( [ this.childA, this.childB ] );\n\t * \t}\n\t *\n\t * \trender() {\n\t * \t\tsuper.render();\n\t *\n\t * \t\tthis.element.appendChild( this.childA.element );\n\t * \t\tthis.element.appendChild( this.childB.element );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView( locale );\n\t *\n\t * view.render();\n\t *\n\t * // Will append <p><childA#element><b></b><childB#element></p>.\n\t * document.body.appendChild( view.element );\n\t * ```\n\t *\n\t * **Note**: There's no need to add child views if they're already referenced in the\n\t * {@link #template}:\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tthis.childA = new SomeChildView( locale );\n\t * \t\tthis.childB = new SomeChildView( locale );\n\t *\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p',\n\t *\n \t * \t\t\t// These children will be added automatically. There's no\n \t * \t\t\t// need to call {@link #registerChild} for any of them.\n\t * \t\t\tchildren: [ this.childA, this.childB ]\n\t * \t\t} );\n\t * \t}\n\t *\n\t * \t// ...\n\t * }\n\t * ```\n\t *\n\t * @param children Children views to be registered.\n\t */ registerChild(children) {\n        if (!isIterable(children)) {\n            children = [\n                children\n            ];\n        }\n        for (const child of children){\n            this._unboundChildren.add(child);\n        }\n    }\n    /**\n\t * The opposite of {@link #registerChild}. Removes a child view from this view instance.\n\t * Once removed, the child is no longer managed by its parent, e.g. it can safely\n\t * become a child of another parent view.\n\t *\n\t * @see #registerChild\n\t * @param children Child views to be removed.\n\t */ deregisterChild(children) {\n        if (!isIterable(children)) {\n            children = [\n                children\n            ];\n        }\n        for (const child of children){\n            this._unboundChildren.remove(child);\n        }\n    }\n    /**\n\t * Sets the {@link #template} of the view with with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t * ```ts\n\t * view.setTemplate( definition );\n\t * ```\n\t *\n\t * @param definition Definition of view's template.\n\t */ setTemplate(definition) {\n        this.template = new Template(definition);\n    }\n    /**\n\t * {@link module:ui/template~Template.extend Extends} the {@link #template} of the view with\n\t * with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t * ```ts\n\t * Template.extend( view.template, definition );\n\t * ```\n\t *\n\t * **Note**: Is requires the {@link #template} to be already set. See {@link #setTemplate}.\n\t *\n\t * @param definition Definition which extends the {@link #template}.\n\t */ extendTemplate(definition) {\n        Template.extend(this.template, definition);\n    }\n    /**\n\t * Recursively renders the view.\n\t *\n\t * Once the view is rendered:\n\t * * the {@link #element} becomes an HTML element out of {@link #template},\n\t * * the {@link #isRendered} flag is set `true`.\n\t *\n\t * **Note**: The children of the view:\n\t * * defined directly in the {@link #template}\n\t * * residing in collections created by the {@link #createCollection} method,\n\t * * and added by {@link #registerChild}\n\t * are also rendered in the process.\n\t *\n\t * In general, `render()` method is the right place to keep the code which refers to the\n\t * {@link #element} and should be executed at the very beginning of the view's life cycle.\n\t *\n\t * It is possible to {@link module:ui/template~Template.extend} the {@link #template} before\n\t * the view is rendered. To allow an early customization of the view (e.g. by its parent),\n\t * such references should be done in `render()`.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor() {\n\t * \t\tthis.setTemplate( {\n\t * \t\t\t// ...\n\t * \t\t} );\n\t * \t},\n\t *\n\t * \trender() {\n\t * \t\t// View#element becomes available.\n\t * \t\tsuper.render();\n\t *\n\t * \t\t// The \"scroll\" listener depends on #element.\n\t * \t\tthis.listenTo( window, 'scroll', () => {\n\t * \t\t\t// A reference to #element would render the #template and make it non-extendable.\n\t * \t\t\tif ( window.scrollY > 0 ) {\n\t * \t\t\t\tthis.element.scrollLeft = 100;\n\t * \t\t\t} else {\n\t * \t\t\t\tthis.element.scrollLeft = 0;\n\t * \t\t\t}\n\t * \t\t} );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView();\n\t *\n\t * // Let's customize the view before it gets rendered.\n\t * view.extendTemplate( {\n\t * \tattributes: {\n\t * \t\tclass: [\n\t * \t\t\t'additional-class'\n\t * \t\t]\n\t * \t}\n\t * } );\n\t *\n\t * // Late rendering allows customization of the view.\n\t * view.render();\n\t * ```\n\t */ render() {\n        if (this.isRendered) {\n            /**\n\t\t\t * This View has already been rendered.\n\t\t\t *\n\t\t\t * @error ui-view-render-already-rendered\n\t\t\t */ throw new CKEditorError('ui-view-render-already-rendered', this);\n        }\n        // Render #element of the view.\n        if (this.template) {\n            this.element = this.template.render();\n            // Auto–register view children from #template.\n            this.registerChild(this.template.getViews());\n        }\n        this.isRendered = true;\n    }\n    /**\n\t * Recursively destroys the view instance and child views added by {@link #registerChild} and\n\t * residing in collections created by the {@link #createCollection}.\n\t *\n\t * Destruction disables all event listeners:\n\t * * created on the view, e.g. `view.on( 'event', () => {} )`,\n\t * * defined in the {@link #template} for DOM events.\n\t */ destroy() {\n        this.stopListening();\n        this._viewCollections.map((c)=>c.destroy());\n        // Template isn't obligatory for views.\n        if (this.template && this.template._revertData) {\n            this.template.revert(this.element);\n        }\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/bindings/clickoutsidehandler\n */ /* global document */ /**\n * Handles clicking **outside** of a specified set of elements, then fires an action.\n *\n * **Note**: Actually, the action is executed upon `mousedown`, not `click`. It prevents\n * certain issues when the user keeps holding the mouse button and the UI cannot react\n * properly.\n *\n * @param options Configuration options.\n * @param options.emitter The emitter to which this behavior should be added.\n * @param options.activator Function returning a `Boolean`, to determine whether the handler is active.\n * @param options.contextElements Array of HTML elements or a callback returning an array of HTML elements\n * that determine the scope of the handler. Clicking any of them or their descendants will **not** fire the callback.\n * @param options.callback An action executed by the handler.\n * @param options.listenerOptions Additional options for the listener (like priority).\n */ function clickOutsideHandler({ emitter, activator, callback, contextElements, listenerOptions }) {\n    emitter.listenTo(document, 'mousedown', (evt, domEvt)=>{\n        if (!activator()) {\n            return;\n        }\n        // Check if `composedPath` is `undefined` in case the browser does not support native shadow DOM.\n        // Can be removed when all supported browsers support native shadow DOM.\n        const path = typeof domEvt.composedPath == 'function' ? domEvt.composedPath() : [];\n        const contextElementsList = typeof contextElements == 'function' ? contextElements() : contextElements;\n        for (const contextElement of contextElementsList){\n            if (contextElement.contains(domEvt.target) || path.includes(contextElement)) {\n                return;\n            }\n        }\n        callback();\n    }, listenerOptions);\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/bindings/injectcsstransitiondisabler\n */ /**\n * A decorator that brings the possibility to temporarily disable CSS transitions using\n * {@link module:ui/view~View} methods. It is helpful when, for instance, the transitions should not happen\n * when the view is first displayed but they should work normal in other cases.\n *\n * The methods to control the CSS transitions are:\n * * `disableCssTransitions()` – Adds the `.ck-transitions-disabled` class to the\n * {@link module:ui/view~View#element view element}.\n * * `enableCssTransitions()` – Removes the `.ck-transitions-disabled` class from the\n * {@link module:ui/view~View#element view element}.\n *\n * **Note**: This helper extends the {@link module:ui/view~View#template template} and must be used **after**\n * {@link module:ui/view~View#setTemplate} is called:\n *\n * ```ts\n * import injectCssTransitionDisabler from '@ckeditor/ckeditor5-ui/src/bindings/injectcsstransitiondisabler';\n *\n * class MyView extends View {\n * \tconstructor() {\n * \t\tsuper();\n *\n * \t\t// ...\n *\n * \t\tthis.setTemplate( { ... } );\n *\n * \t\t// ...\n *\n * \t\tinjectCssTransitionDisabler( this );\n *\n * \t\t// ...\n * \t}\n * }\n * ```\n *\n * The usage comes down to:\n *\n * ```ts\n * const view = new MyView();\n *\n * // ...\n *\n * view.disableCssTransitions();\n * view.show();\n * view.enableCssTransitions();\n * ```\n *\n * @deprecated\n * @see module:ui/bindings/csstransitiondisablermixin~CssTransitionDisablerMixin\n * @param view View instance that should get this functionality.\n */ function injectCssTransitionDisabler(view) {\n    const decorated = view;\n    decorated.set('_isCssTransitionsDisabled', false);\n    decorated.disableCssTransitions = ()=>{\n        decorated._isCssTransitionsDisabled = true;\n    };\n    decorated.enableCssTransitions = ()=>{\n        decorated._isCssTransitionsDisabled = false;\n    };\n    decorated.extendTemplate({\n        attributes: {\n            class: [\n                decorated.bindTemplate.if('_isCssTransitionsDisabled', 'ck-transitions-disabled')\n            ]\n        }\n    });\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/bindings/csstransitiondisablermixin\n */ /**\n * A mixin that brings the possibility to temporarily disable CSS transitions using\n * {@link module:ui/view~View} methods. It is helpful when, for instance, the transitions should not happen\n * when the view is first displayed but they should work normal in other cases.\n *\n * The methods to control the CSS transitions are:\n * * `disableCssTransitions()` – Adds the `.ck-transitions-disabled` class to the\n * {@link module:ui/view~View#element view element}.\n * * `enableCssTransitions()` – Removes the `.ck-transitions-disabled` class from the\n * {@link module:ui/view~View#element view element}.\n *\n * The usage comes down to:\n *\n * ```ts\n * const MyViewWithCssTransitionDisabler = CssTransitionDisablerMixin( MyView );\n * const view = new MyViewWithCssTransitionDisabler();\n *\n * // ...\n *\n * view.disableCssTransitions();\n * view.show();\n * view.enableCssTransitions();\n * ```\n *\n * @param view View instance that should get this functionality.\n */ function CssTransitionDisablerMixin(view) {\n    class Mixin extends view {\n        disableCssTransitions() {\n            this._isCssTransitionsDisabled = true;\n        }\n        enableCssTransitions() {\n            this._isCssTransitionsDisabled = false;\n        }\n        constructor(...args){\n            super(...args);\n            this.set('_isCssTransitionsDisabled', false);\n            this.initializeCssTransitionDisablerMixin();\n        }\n        initializeCssTransitionDisablerMixin() {\n            this.extendTemplate({\n                attributes: {\n                    class: [\n                        this.bindTemplate.if('_isCssTransitionsDisabled', 'ck-transitions-disabled')\n                    ]\n                }\n            });\n        }\n    }\n    return Mixin;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/bindings/submithandler\n */ /**\n * A handler useful for {@link module:ui/view~View views} working as HTML forms. It intercepts a native DOM\n * `submit` event, prevents the default web browser behavior (navigation and page reload) and\n * fires the `submit` event on a view instead. Such a custom event can be then used by any\n * {@link module:utils/dom/emittermixin~DomEmitter emitter}, e.g. to serialize the form data.\n *\n * ```ts\n * import submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\n *\n * // ...\n *\n * class AnyFormView extends View {\n * \tconstructor() {\n * \t\tsuper();\n *\n * \t\t// ...\n *\n * \t\tsubmitHandler( {\n * \t\t\tview: this\n * \t\t} );\n * \t}\n * }\n *\n * // ...\n *\n * const view = new AnyFormView();\n *\n * // A sample listener attached by an emitter working with the view.\n * this.listenTo( view, 'submit', () => {\n * \tsaveTheFormData();\n * \thideTheForm();\n * } );\n * ```\n *\n * @param options Configuration options.\n * @param options.view The view which DOM `submit` events should be handled.\n */ function submitHandler({ view }) {\n    view.listenTo(view.element, 'submit', (evt, domEvt)=>{\n        domEvt.preventDefault();\n        view.fire('submit');\n    }, {\n        useCapture: true\n    });\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/bindings/addkeyboardhandlingforgrid\n */ /**\n * A helper that adds a keyboard navigation support (arrow up/down/left/right) for grids.\n *\n * @param options Configuration options.\n * @param options.keystrokeHandler Keystroke handler to register navigation with arrow keys.\n * @param options.focusTracker A focus tracker for grid elements.\n * @param options.gridItems A collection of grid items.\n * @param options.numberOfColumns Number of columns in the grid. Can be specified as a function that returns\n * the number (e.g. for responsive grids).\n * @param options.uiLanguageDirection String of ui language direction.\n */ function addKeyboardHandlingForGrid({ keystrokeHandler, focusTracker, gridItems, numberOfColumns, uiLanguageDirection }) {\n    const getNumberOfColumns = typeof numberOfColumns === 'number' ? ()=>numberOfColumns : numberOfColumns;\n    keystrokeHandler.set('arrowright', getGridItemFocuser((focusedElementIndex, gridItems)=>{\n        return uiLanguageDirection === 'rtl' ? getLeftElementIndex(focusedElementIndex, gridItems.length) : getRightElementIndex(focusedElementIndex, gridItems.length);\n    }));\n    keystrokeHandler.set('arrowleft', getGridItemFocuser((focusedElementIndex, gridItems)=>{\n        return uiLanguageDirection === 'rtl' ? getRightElementIndex(focusedElementIndex, gridItems.length) : getLeftElementIndex(focusedElementIndex, gridItems.length);\n    }));\n    keystrokeHandler.set('arrowup', getGridItemFocuser((focusedElementIndex, gridItems)=>{\n        let nextIndex = focusedElementIndex - getNumberOfColumns();\n        if (nextIndex < 0) {\n            nextIndex = focusedElementIndex + getNumberOfColumns() * Math.floor(gridItems.length / getNumberOfColumns());\n            if (nextIndex > gridItems.length - 1) {\n                nextIndex -= getNumberOfColumns();\n            }\n        }\n        return nextIndex;\n    }));\n    keystrokeHandler.set('arrowdown', getGridItemFocuser((focusedElementIndex, gridItems)=>{\n        let nextIndex = focusedElementIndex + getNumberOfColumns();\n        if (nextIndex > gridItems.length - 1) {\n            nextIndex = focusedElementIndex % getNumberOfColumns();\n        }\n        return nextIndex;\n    }));\n    function getGridItemFocuser(getIndexToFocus) {\n        return (evt)=>{\n            const focusedElement = gridItems.find((item)=>item.element === focusTracker.focusedElement);\n            const focusedElementIndex = gridItems.getIndex(focusedElement);\n            const nextIndexToFocus = getIndexToFocus(focusedElementIndex, gridItems);\n            gridItems.get(nextIndexToFocus).focus();\n            evt.stopPropagation();\n            evt.preventDefault();\n        };\n    }\n    /**\n\t * Function returning the next index.\n\t *\n\t * ```\n\t * before: [ ][x][ ]\tafter: [ ][ ][x]\n\t * index = 1            index = 2\n\t * ```\n\t *\n\t * If current index is last, function returns first index.\n\t *\n\t * ```\n\t * before: [ ][ ][x]\tafter: [x][ ][ ]\n\t * index = 2            index = 0\n\t * ```\n\t *\n\t * @param elementIndex Number of current index.\n\t * @param collectionLength A count of collection items.\n\t */ function getRightElementIndex(elementIndex, collectionLength) {\n        if (elementIndex === collectionLength - 1) {\n            return 0;\n        } else {\n            return elementIndex + 1;\n        }\n    }\n    /**\n\t * Function returning the previous index.\n\t *\n\t * ```\n\t * before: [ ][x][ ]\tafter: [x][ ][ ]\n\t * index = 1            index = 0\n\t * ```\n\t *\n\t * If current index is first, function returns last index.\n\t *\n\t * ```\n\t * before: [x][ ][ ]\tafter: [ ][ ][x]\n\t * index = 0            index = 2\n\t * ```\n\t *\n\t * @param elementIndex Number of current index.\n\t * @param collectionLength A count of collection items.\n\t */ function getLeftElementIndex(elementIndex, collectionLength) {\n        if (elementIndex === 0) {\n            return collectionLength - 1;\n        } else {\n            return elementIndex - 1;\n        }\n    }\n}\n\n/**\n * The icon view class.\n */ class IconView extends View {\n    /**\n\t * A list of presentational attributes that can be set on the `<svg>` element and should be preserved\n\t * when the icon {@link module:ui/icon/iconview~IconView#content content} is loaded.\n\t *\n\t * See the [specification](https://www.w3.org/TR/SVG/styling.html#TermPresentationAttribute) to learn more.\n\t */ static presentationalAttributeNames = [\n        'alignment-baseline',\n        'baseline-shift',\n        'clip-path',\n        'clip-rule',\n        'color',\n        'color-interpolation',\n        'color-interpolation-filters',\n        'color-rendering',\n        'cursor',\n        'direction',\n        'display',\n        'dominant-baseline',\n        'fill',\n        'fill-opacity',\n        'fill-rule',\n        'filter',\n        'flood-color',\n        'flood-opacity',\n        'font-family',\n        'font-size',\n        'font-size-adjust',\n        'font-stretch',\n        'font-style',\n        'font-variant',\n        'font-weight',\n        'image-rendering',\n        'letter-spacing',\n        'lighting-color',\n        'marker-end',\n        'marker-mid',\n        'marker-start',\n        'mask',\n        'opacity',\n        'overflow',\n        'paint-order',\n        'pointer-events',\n        'shape-rendering',\n        'stop-color',\n        'stop-opacity',\n        'stroke',\n        'stroke-dasharray',\n        'stroke-dashoffset',\n        'stroke-linecap',\n        'stroke-linejoin',\n        'stroke-miterlimit',\n        'stroke-opacity',\n        'stroke-width',\n        'text-anchor',\n        'text-decoration',\n        'text-overflow',\n        'text-rendering',\n        'transform',\n        'unicode-bidi',\n        'vector-effect',\n        'visibility',\n        'white-space',\n        'word-spacing',\n        'writing-mode'\n    ];\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        const bind = this.bindTemplate;\n        this.set('content', '');\n        this.set('viewBox', '0 0 20 20');\n        this.set('fillColor', '');\n        this.set('isColorInherited', true);\n        this.set('isVisible', true);\n        this.setTemplate({\n            tag: 'svg',\n            ns: 'http://www.w3.org/2000/svg',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-icon',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value),\n                    // Exclude icon internals from the CSS reset to allow rich (non-monochromatic) icons\n                    // (https://github.com/ckeditor/ckeditor5/issues/12599).\n                    'ck-reset_all-excluded',\n                    // The class to remove the dynamic color inheritance is toggleable\n                    // (https://github.com/ckeditor/ckeditor5/issues/12599).\n                    bind.if('isColorInherited', 'ck-icon_inherit-color')\n                ],\n                viewBox: bind.to('viewBox')\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this._updateXMLContent();\n        this._colorFillPaths();\n        // This is a hack for lack of innerHTML binding.\n        // See: https://github.com/ckeditor/ckeditor5-ui/issues/99.\n        this.on('change:content', ()=>{\n            this._updateXMLContent();\n            this._colorFillPaths();\n        });\n        this.on('change:fillColor', ()=>{\n            this._colorFillPaths();\n        });\n    }\n    /**\n\t * Updates the {@link #element} with the value of {@link #content}.\n\t */ _updateXMLContent() {\n        if (this.content) {\n            const parsed = new DOMParser().parseFromString(this.content.trim(), 'image/svg+xml');\n            const svg = parsed.querySelector('svg');\n            const viewBox = svg.getAttribute('viewBox');\n            if (viewBox) {\n                this.viewBox = viewBox;\n            }\n            // Preserve presentational attributes of the <svg> element from the source.\n            // They can affect rendering of the entire icon (https://github.com/ckeditor/ckeditor5/issues/12597).\n            for (const { name, value } of Array.from(svg.attributes)){\n                if (IconView.presentationalAttributeNames.includes(name)) {\n                    this.element.setAttribute(name, value);\n                }\n            }\n            while(this.element.firstChild){\n                this.element.removeChild(this.element.firstChild);\n            }\n            while(svg.childNodes.length > 0){\n                this.element.appendChild(svg.childNodes[0]);\n            }\n        }\n    }\n    /**\n\t * Fills all child `path.ck-icon__fill` with the `#fillColor`.\n\t */ _colorFillPaths() {\n        if (this.fillColor) {\n            this.element.querySelectorAll('.ck-icon__fill').forEach((path)=>{\n                path.style.fill = this.fillColor;\n            });\n        }\n    }\n}\n\n/**\n * A default implementation of the button view's label. It comes with a dynamic text support\n * via {@link module:ui/button/buttonlabelview~ButtonLabelView#text} property.\n */ class ButtonLabelView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        this.set({\n            style: undefined,\n            text: undefined,\n            id: undefined\n        });\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-button__label'\n                ],\n                style: bind.to('style'),\n                id: bind.to('id')\n            },\n            children: [\n                {\n                    text: bind.to('text')\n                }\n            ]\n        });\n    }\n}\n\n/**\n * The button view class.\n *\n * ```ts\n * const view = new ButtonView();\n *\n * view.set( {\n * \tlabel: 'A button',\n * \tkeystroke: 'Ctrl+B',\n * \ttooltip: true,\n * \twithText: true\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n */ class ButtonView extends View {\n    /**\n\t * Collection of the child views inside of the button {@link #element}.\n\t */ children;\n    /**\n\t * Label of the button view. Its text is configurable using the {@link #label label attribute}.\n\t *\n\t * If not configured otherwise in the `constructor()`, by default the label is an instance\n\t * of {@link module:ui/button/buttonlabelview~ButtonLabelView}.\n\t */ labelView;\n    /**\n\t * The icon view of the button. Will be added to {@link #children} when the\n\t * {@link #icon icon attribute} is defined.\n\t */ iconView;\n    /**\n\t * A view displaying the keystroke of the button next to the {@link #labelView label}.\n\t * Added to {@link #children} when the {@link #withKeystroke `withKeystroke` attribute}\n\t * is defined.\n\t */ keystrokeView;\n    /**\n\t * Delayed focus function for focus handling in Safari.\n\t */ _focusDelayed = null;\n    /**\n\t * Creates an instance of the button view class.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param labelView The instance of the button's label. If not provided, an instance of\n\t * {@link module:ui/button/buttonlabelview~ButtonLabelView} is used.\n\t */ constructor(locale, labelView = new ButtonLabelView()){\n        super(locale);\n        const bind = this.bindTemplate;\n        const ariaLabelUid = uid();\n        // Implement the Button interface.\n        this.set('_ariaPressed', false);\n        this.set('_ariaChecked', false);\n        this.set('ariaLabel', undefined);\n        this.set('ariaLabelledBy', `ck-editor__aria-label_${ariaLabelUid}`);\n        this.set('class', undefined);\n        this.set('labelStyle', undefined);\n        this.set('icon', undefined);\n        this.set('isEnabled', true);\n        this.set('isOn', false);\n        this.set('isVisible', true);\n        this.set('isToggleable', false);\n        this.set('keystroke', undefined);\n        this.set('label', undefined);\n        this.set('role', undefined);\n        this.set('tabindex', -1);\n        this.set('tooltip', false);\n        this.set('tooltipPosition', 's');\n        this.set('type', 'button');\n        this.set('withText', false);\n        this.set('withKeystroke', false);\n        this.children = this.createCollection();\n        this.labelView = this._setupLabelView(labelView);\n        this.iconView = new IconView();\n        this.iconView.extendTemplate({\n            attributes: {\n                class: 'ck-button__icon'\n            }\n        });\n        this.keystrokeView = this._createKeystrokeView();\n        this.bind('_tooltipString').to(this, 'tooltip', this, 'label', this, 'keystroke', this._getTooltipString.bind(this));\n        const template = {\n            tag: 'button',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-button',\n                    bind.to('class'),\n                    bind.if('isEnabled', 'ck-disabled', (value)=>!value),\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value),\n                    bind.to('isOn', (value)=>value ? 'ck-on' : 'ck-off'),\n                    bind.if('withText', 'ck-button_with-text'),\n                    bind.if('withKeystroke', 'ck-button_with-keystroke')\n                ],\n                role: bind.to('role'),\n                type: bind.to('type', (value)=>value ? value : 'button'),\n                tabindex: bind.to('tabindex'),\n                'aria-checked': bind.to('_ariaChecked'),\n                'aria-pressed': bind.to('_ariaPressed'),\n                'aria-label': bind.to('ariaLabel'),\n                'aria-labelledby': bind.to('ariaLabelledBy'),\n                'aria-disabled': bind.if('isEnabled', true, (value)=>!value),\n                'data-cke-tooltip-text': bind.to('_tooltipString'),\n                'data-cke-tooltip-position': bind.to('tooltipPosition')\n            },\n            children: this.children,\n            on: {\n                click: bind.to((evt)=>{\n                    // We can't make the button disabled using the disabled attribute, because it won't be focusable.\n                    // Though, shouldn't this condition be moved to the button controller?\n                    if (this.isEnabled) {\n                        this.fire('execute');\n                    } else {\n                        // Prevent the default when button is disabled, to block e.g.\n                        // automatic form submitting. See ckeditor/ckeditor5-link#74.\n                        evt.preventDefault();\n                    }\n                })\n            }\n        };\n        this.bind('_ariaPressed').to(this, 'isOn', this, 'isToggleable', this, 'role', (isOn, isToggleable, role)=>{\n            if (!isToggleable || isCheckableRole(role)) {\n                return false;\n            }\n            return String(!!isOn);\n        });\n        this.bind('_ariaChecked').to(this, 'isOn', this, 'isToggleable', this, 'role', (isOn, isToggleable, role)=>{\n            if (!isToggleable || !isCheckableRole(role)) {\n                return false;\n            }\n            return String(!!isOn);\n        });\n        // On Safari we have to force the focus on a button on click as it's the only browser\n        // that doesn't do that automatically. See #12115.\n        if (env.isSafari) {\n            if (!this._focusDelayed) {\n                this._focusDelayed = delay(()=>this.focus(), 0);\n            }\n            template.on.mousedown = bind.to(()=>{\n                this._focusDelayed();\n            });\n            template.on.mouseup = bind.to(()=>{\n                this._focusDelayed.cancel();\n            });\n        }\n        this.setTemplate(template);\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        if (this.icon) {\n            this.iconView.bind('content').to(this, 'icon');\n            this.children.add(this.iconView);\n        }\n        this.children.add(this.labelView);\n        if (this.withKeystroke && this.keystroke) {\n            this.children.add(this.keystrokeView);\n        }\n    }\n    /**\n\t * Focuses the {@link #element} of the button.\n\t */ focus() {\n        this.element.focus();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        if (this._focusDelayed) {\n            this._focusDelayed.cancel();\n        }\n        super.destroy();\n    }\n    /**\n\t * Binds the label view instance it with button attributes.\n\t */ _setupLabelView(labelView) {\n        labelView.bind('text', 'style', 'id').to(this, 'label', 'labelStyle', 'ariaLabelledBy');\n        return labelView;\n    }\n    /**\n\t * Creates a view that displays a keystroke next to a {@link #labelView label }\n\t * and binds it with button attributes.\n\t */ _createKeystrokeView() {\n        const keystrokeView = new View();\n        keystrokeView.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-button__keystroke'\n                ]\n            },\n            children: [\n                {\n                    text: this.bindTemplate.to('keystroke', (text)=>getEnvKeystrokeText(text))\n                }\n            ]\n        });\n        return keystrokeView;\n    }\n    /**\n\t * Gets the text for the tooltip from the combination of\n\t * {@link #tooltip}, {@link #label} and {@link #keystroke} attributes.\n\t *\n\t * @see #tooltip\n\t * @see #_tooltipString\n\t * @param tooltip Button tooltip.\n\t * @param label Button label.\n\t * @param keystroke Button keystroke.\n\t */ _getTooltipString(tooltip, label, keystroke) {\n        if (tooltip) {\n            if (typeof tooltip == 'string') {\n                return tooltip;\n            } else {\n                if (keystroke) {\n                    keystroke = getEnvKeystrokeText(keystroke);\n                }\n                if (tooltip instanceof Function) {\n                    return tooltip(label, keystroke);\n                } else {\n                    return `${label}${keystroke ? ` (${keystroke})` : ''}`;\n                }\n            }\n        }\n        return '';\n    }\n}\n/**\n * Checks if `aria-checkbox` can be used with specified role.\n */ function isCheckableRole(role) {\n    switch(role){\n        case 'radio':\n        case 'checkbox':\n        case 'option':\n        case 'switch':\n        case 'menuitemcheckbox':\n        case 'menuitemradio':\n            return true;\n        default:\n            return false;\n    }\n}\n\n/**\n * The class component representing a form header view. It should be used in more advanced forms to\n * describe the main purpose of the form.\n *\n * By default the component contains a bolded label view that has to be set. The label is usually a short (at most 3-word) string.\n * The component can also be extended by any other elements, like: icons, dropdowns, etc.\n *\n * It is used i.a.\n * by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}.\n *\n * The latter is an example, where the component has been extended by {@link module:ui/dropdown/dropdownview~DropdownView} view.\n */ class FormHeaderView extends View {\n    /**\n\t * A collection of header items.\n\t */ children;\n    /**\n\t * The icon view instance. Defined only if icon was passed in the constructor's options.\n\t */ iconView;\n    /**\n\t * Creates an instance of the form header class.\n\t *\n\t * @param locale The locale instance.\n\t * @param options.label A label.\n\t * @param options.class An additional class.\n\t */ constructor(locale, options = {}){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('label', options.label || '');\n        this.set('class', options.class || null);\n        this.children = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-form__header',\n                    bind.to('class')\n                ]\n            },\n            children: this.children\n        });\n        if (options.icon) {\n            this.iconView = new IconView();\n            this.iconView.content = options.icon;\n            this.children.add(this.iconView);\n        }\n        const label = new View(locale);\n        label.setTemplate({\n            tag: 'h2',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-form__header__label'\n                ],\n                role: 'presentation'\n            },\n            children: [\n                {\n                    text: bind.to('label')\n                }\n            ]\n        });\n        this.children.add(label);\n    }\n}\n\n/**\n * A utility class that helps cycling over {@link module:ui/focuscycler~FocusableView focusable views} in a\n * {@link module:ui/viewcollection~ViewCollection} when the focus is tracked by the\n * {@link module:utils/focustracker~FocusTracker} instance. It helps implementing keyboard\n * navigation in HTML forms, toolbars, lists and the like.\n *\n * To work properly it requires:\n * * a collection of focusable (HTML `tabindex` attribute) views that implement the `focus()` method,\n * * an associated focus tracker to determine which view is focused.\n *\n * A simple cycler setup can look like this:\n *\n * ```ts\n * const focusables = new ViewCollection<FocusableView>();\n * const focusTracker = new FocusTracker();\n *\n * // Add focusable views to the focus tracker.\n * focusTracker.add( ... );\n * ```\n *\n * Then, the cycler can be used manually:\n *\n * ```ts\n * const cycler = new FocusCycler( { focusables, focusTracker } );\n *\n * // Will focus the first focusable view in #focusables.\n * cycler.focusFirst();\n *\n * // Will log the next focusable item in #focusables.\n * console.log( cycler.next );\n * ```\n *\n * Alternatively, it can work side by side with the {@link module:utils/keystrokehandler~KeystrokeHandler}:\n *\n * ```ts\n * const keystrokeHandler = new KeystrokeHandler();\n *\n * // Activate the keystroke handler.\n * keystrokeHandler.listenTo( sourceOfEvents );\n *\n * const cycler = new FocusCycler( {\n * \tfocusables, focusTracker, keystrokeHandler,\n * \tactions: {\n * \t\t// When arrowup of arrowleft is detected by the #keystrokeHandler,\n * \t\t// focusPrevious() will be called on the cycler.\n * \t\tfocusPrevious: [ 'arrowup', 'arrowleft' ],\n * \t}\n * } );\n * ```\n *\n * Check out the {@glink framework/deep-dive/ui/focus-tracking \"Deep dive into focus tracking\"} guide to learn more.\n */ class FocusCycler extends /* #__PURE__ */ EmitterMixin() {\n    /**\n\t * A {@link module:ui/focuscycler~FocusableView focusable views} collection that the cycler operates on.\n\t */ focusables;\n    /**\n\t * A focus tracker instance that the cycler uses to determine the current focus\n\t * state in {@link #focusables}.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}\n\t * which can respond to certain keystrokes and cycle the focus.\n\t */ keystrokeHandler;\n    /**\n\t * Actions that the cycler can take when a keystroke is pressed. Requires\n\t * `options.keystrokeHandler` to be passed and working. When an action is\n\t * performed, `preventDefault` and `stopPropagation` will be called on the event\n\t * the keystroke fired in the DOM.\n\t *\n\t * ```ts\n\t * actions: {\n\t * \t// Will call #focusPrevious() when arrowleft or arrowup is pressed.\n\t * \tfocusPrevious: [ 'arrowleft', 'arrowup' ],\n\t *\n\t * \t// Will call #focusNext() when arrowdown is pressed.\n\t * \tfocusNext: 'arrowdown'\n\t * }\n\t * ```\n\t */ actions;\n    /**\n\t * Creates an instance of the focus cycler utility.\n\t *\n\t * @param options Configuration options.\n\t */ constructor(options){\n        super();\n        this.focusables = options.focusables;\n        this.focusTracker = options.focusTracker;\n        this.keystrokeHandler = options.keystrokeHandler;\n        this.actions = options.actions;\n        if (options.actions && options.keystrokeHandler) {\n            for(const methodName in options.actions){\n                let actions = options.actions[methodName];\n                if (typeof actions == 'string') {\n                    actions = [\n                        actions\n                    ];\n                }\n                for (const keystroke of actions){\n                    options.keystrokeHandler.set(keystroke, (data, cancel)=>{\n                        this[methodName]();\n                        cancel();\n                    }, options.keystrokeHandlerOptions);\n                }\n            }\n        }\n        this.on('forwardCycle', ()=>this.focusFirst(), {\n            priority: 'low'\n        });\n        this.on('backwardCycle', ()=>this.focusLast(), {\n            priority: 'low'\n        });\n    }\n    /**\n\t * Returns the first focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ get first() {\n        return this.focusables.find(isDomFocusable) || null;\n    }\n    /**\n\t * Returns the last focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ get last() {\n        return this.focusables.filter(isDomFocusable).slice(-1)[0] || null;\n    }\n    /**\n\t * Returns the next focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ get next() {\n        return this._getDomFocusableItem(1);\n    }\n    /**\n\t * Returns the previous focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ get previous() {\n        return this._getDomFocusableItem(-1);\n    }\n    /**\n\t * An index of the view in the {@link #focusables} which is focused according\n\t * to {@link #focusTracker}. Returns `null` when there is no such view.\n\t */ get current() {\n        let index = null;\n        // There's no focused view in the focusables.\n        if (this.focusTracker.focusedElement === null) {\n            return null;\n        }\n        this.focusables.find((view, viewIndex)=>{\n            const focused = view.element === this.focusTracker.focusedElement;\n            if (focused) {\n                index = viewIndex;\n            }\n            return focused;\n        });\n        return index;\n    }\n    /**\n\t * Focuses the {@link #first} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ focusFirst() {\n        this._focus(this.first, 1);\n    }\n    /**\n\t * Focuses the {@link #last} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ focusLast() {\n        this._focus(this.last, -1);\n    }\n    /**\n\t * Focuses the {@link #next} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ focusNext() {\n        const next = this.next;\n        // If there's only one focusable item, we need to let the outside world know\n        // that the next cycle is about to happen. This may be useful\n        // e.g. if you want to move the focus to the parent focus cycler.\n        // Note that the focus is not actually moved in this case.\n        if (next && this.focusables.getIndex(next) === this.current) {\n            this.fire('forwardCycle');\n            return;\n        }\n        if (next === this.first) {\n            this.fire('forwardCycle');\n        } else {\n            this._focus(next, 1);\n        }\n    }\n    /**\n\t * Focuses the {@link #previous} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */ focusPrevious() {\n        const previous = this.previous;\n        if (previous && this.focusables.getIndex(previous) === this.current) {\n            this.fire('backwardCycle');\n            return;\n        }\n        if (previous === this.last) {\n            this.fire('backwardCycle');\n        } else {\n            this._focus(previous, -1);\n        }\n    }\n    /**\n\t * Allows for creating continuous focus cycling across multiple focus cyclers and their collections of {@link #focusables}.\n\t *\n\t * It starts listening to the {@link module:ui/focuscycler~FocusCyclerForwardCycleEvent} and\n\t * {@link module:ui/focuscycler~FocusCyclerBackwardCycleEvent} events of the chained focus cycler and engages,\n\t * whenever the user reaches the last (forwards navigation) or first (backwards navigation) focusable view\n\t * and would normally start over. Instead, the navigation continues on the higher level (flattens).\n\t *\n\t * For instance, for the following nested focus navigation structure, the focus would get stuck the moment\n\t * the AB gets focused and its focus cycler starts managing it:\n\t *\n\t *\t   ┌────────────┐   ┌──────────────────────────────────┐   ┌────────────┐\n\t *\t   │ AA         │   │ AB                               │   │ AC         │\n\t *\t   │            │   │                                  │   │            │\n\t *\t   │            │   │    ┌─────┐  ┌─────┐  ┌─────┐     │   │            │\n\t *\t   │            │   │ ┌──► ABA ├──► ABB ├──► ABC ├───┐ │   │            │\n\t *\t   │            ├───► │  └─────┘  └─────┘  └─────┘   │ │   │            │\n\t *\t   │            │   │ │                              │ │   │            │\n\t *\t   │            │   │ │                              │ │   │            │\n\t *\t   │            │   │ └──────────────────────────────┘ │   │            │\n\t *\t   │            │   │                                  │   │            │\n\t *\t   └────────────┘   └──────────────────────────────────┘   └────────────┘\n\t *\n\t * Chaining a focus tracker that manages AA, AB, and AC with the focus tracker that manages ABA, ABB, and ABC\n\t * creates a seamless navigation experience instead:\n\t *\n\t *\t   ┌────────────┐   ┌──────────────────────────────────┐   ┌────────────┐\n\t *\t   │ AA         │   │ AB                               │   │ AC         │\n\t *\t   │            │   │                                  │   │            │\n\t *\t   │            │   │    ┌─────┐  ┌─────┐  ┌─────┐     │   │            │\n\t *\t   │            │   │ ┌──► ABA ├──► ABB ├──► ABC ├──┐  │   │            │\n\t *\t┌──►            ├───┼─┘  └─────┘  └─────┘  └─────┘  └──┼───►            ├──┐\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  └────────────┘   └──────────────────────────────────┘   └────────────┘  │\n\t *\t│                                                                          │\n\t *\t│                                                                          │\n\t *\t└──────────────────────────────────────────────────────────────────────────┘\n\t *\n\t * See {@link #unchain} to reverse the chaining.\n\t */ chain(chainedFocusCycler) {\n        const getCurrentFocusedView = ()=>{\n            // This may happen when one focus cycler does not include focusables of the other (horizontal case).\n            if (this.current === null) {\n                return null;\n            }\n            return this.focusables.get(this.current);\n        };\n        this.listenTo(chainedFocusCycler, 'forwardCycle', (evt)=>{\n            const oldCurrent = getCurrentFocusedView();\n            this.focusNext();\n            // Stop the event propagation only if an attempt at focusing the view actually moved the focus.\n            // If not, let the otherFocusCycler handle the event.\n            if (oldCurrent !== getCurrentFocusedView()) {\n                evt.stop();\n            }\n        // The priority is critical for cycling across multiple chain levels when there's a single view at some of them only.\n        }, {\n            priority: 'low'\n        });\n        this.listenTo(chainedFocusCycler, 'backwardCycle', (evt)=>{\n            const oldCurrent = getCurrentFocusedView();\n            this.focusPrevious();\n            // Stop the event propagation only if an attempt at focusing the view actually moved the focus.\n            // If not, let the otherFocusCycler handle the event.\n            if (oldCurrent !== getCurrentFocusedView()) {\n                evt.stop();\n            }\n        // The priority is critical for cycling across multiple chain levels when there's a single view at some of them only.\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * Reverses a chaining made by {@link #chain}.\n\t */ unchain(otherFocusCycler) {\n        this.stopListening(otherFocusCycler);\n    }\n    /**\n\t * Focuses the given view if it exists.\n\t *\n\t * @param view The view to be focused\n\t * @param direction The direction of the focus if the view has focusable children.\n\t * @returns\n\t */ _focus(view, direction) {\n        // Don't fire focus events if the view is already focused.\n        // Such attempt may occur when cycling with only one focusable item:\n        // even though `focusNext()` method returns without changing focus,\n        // the `forwardCycle` event is fired, triggering the `focusFirst()` method.\n        if (view && this.focusTracker.focusedElement !== view.element) {\n            view.focus(direction);\n        }\n    }\n    /**\n\t * Returns the next or previous focusable view in {@link #focusables} with respect\n\t * to {@link #current}.\n\t *\n\t * @param step Either `1` for checking forward from {@link #current} or `-1` for checking backwards.\n\t */ _getDomFocusableItem(step) {\n        // Cache for speed.\n        const collectionLength = this.focusables.length;\n        if (!collectionLength) {\n            return null;\n        }\n        const current = this.current;\n        // Start from the beginning if no view is focused.\n        // https://github.com/ckeditor/ckeditor5-ui/issues/206\n        if (current === null) {\n            return this[step === 1 ? 'first' : 'last'];\n        }\n        // Note: If current is the only focusable view, it will also be returned for the given step.\n        let focusableItem = this.focusables.get(current);\n        // Cycle in both directions.\n        let index = (current + collectionLength + step) % collectionLength;\n        do {\n            const focusableItemCandidate = this.focusables.get(index);\n            if (isDomFocusable(focusableItemCandidate)) {\n                focusableItem = focusableItemCandidate;\n                break;\n            }\n            // Cycle in both directions.\n            index = (index + collectionLength + step) % collectionLength;\n        }while (index !== current)\n        return focusableItem;\n    }\n}\n/**\n * Checks whether a view can be focused (has `focus()` method and is visible).\n *\n * @param view A view to be checked.\n */ function isDomFocusable(view) {\n    return isFocusable(view) && isVisible(view.element);\n}\n/**\n * Checks whether a view is {@link ~FocusableView}.\n *\n * @param view A view to be checked.\n */ function isFocusable(view) {\n    return !!('focus' in view && typeof view.focus == 'function');\n}\n/**\n * Checks whether a view is an instance of {@link ~ViewWithFocusCycler}.\n *\n * @param view A view to be checked.\n */ function isViewWithFocusCycler(view) {\n    return isFocusable(view) && 'focusCycler' in view && view.focusCycler instanceof FocusCycler;\n}\n\n/**\n * A mixin that brings the possibility to observe dragging of the view element.\n * The view has to implement the {@link ~DraggableView} interface to use it:\n *\n * ```js\n * export default class MyDraggableView extends DraggableViewMixin( View ) implements DraggableView {\n * \t\t// ...\n * }\n * ```\n *\n * Creating a class extending it attaches a set of mouse and touch listeners allowing to observe dragging of the view element:\n * * `mousedown` and `touchstart` on the view element - starting the dragging.\n * * `mousemove` and `touchmove` on the document - updating the view coordinates.\n * * `mouseup` and `touchend` on the document - stopping the dragging.\n *\n * The mixin itself does not provide a visual feedback (that is, the dragged element does not change its position) -\n * it is up to the developer to implement it.\n */ function DraggableViewMixin(view) {\n    class DraggableMixin extends view {\n        /**\n\t\t * A bound version of {@link #_onDrag}.\n\t\t */ _onDragBound = this._onDrag.bind(this);\n        /**\n\t\t * A bound version of {@link #_onDragEnd}.\n\t\t */ _onDragEndBound = this._onDragEnd.bind(this);\n        /**\n\t\t * The last coordinates of the view. It is updated on every mouse move.\n\t\t */ _lastDraggingCoordinates = {\n            x: 0,\n            y: 0\n        };\n        /**\n\t\t * @inheritDoc\n\t\t */ constructor(...args){\n            super(...args);\n            this.on('render', ()=>{\n                this._attachListeners();\n            });\n            this.set('isDragging', false);\n        }\n        /**\n\t\t * Attaches the listeners for the drag start.\n\t\t */ _attachListeners() {\n            this.listenTo(this.element, 'mousedown', this._onDragStart.bind(this));\n            this.listenTo(this.element, 'touchstart', this._onDragStart.bind(this));\n        }\n        /**\n\t\t * Attaches the listeners for the dragging and drag end.\n\t\t */ _attachDragListeners() {\n            this.listenTo(global.document, 'mouseup', this._onDragEndBound);\n            this.listenTo(global.document, 'touchend', this._onDragEndBound);\n            this.listenTo(global.document, 'mousemove', this._onDragBound);\n            this.listenTo(global.document, 'touchmove', this._onDragBound);\n        }\n        /**\n\t\t * Detaches the listeners after the drag end.\n\t\t */ _detachDragListeners() {\n            this.stopListening(global.document, 'mouseup', this._onDragEndBound);\n            this.stopListening(global.document, 'touchend', this._onDragEndBound);\n            this.stopListening(global.document, 'mousemove', this._onDragBound);\n            this.stopListening(global.document, 'touchmove', this._onDragBound);\n        }\n        /**\n\t\t * Starts the dragging listeners and sets the initial view coordinates.\n\t\t */ _onDragStart(evt, domEvt) {\n            if (!this._isHandleElementPressed(domEvt)) {\n                return;\n            }\n            this._attachDragListeners();\n            let x = 0;\n            let y = 0;\n            // If dragging is performed with a mouse, there is only one set of coordinates available.\n            // But when using a touch device, there may be many of them, so use the coordinates from the first touch.\n            if (domEvt instanceof MouseEvent) {\n                x = domEvt.clientX;\n                y = domEvt.clientY;\n            } else {\n                x = domEvt.touches[0].clientX;\n                y = domEvt.touches[0].clientY;\n            }\n            this._lastDraggingCoordinates = {\n                x,\n                y\n            };\n            this.isDragging = true;\n        }\n        /**\n\t\t * Updates the view coordinates and fires the `drag` event.\n\t\t */ _onDrag(evt, domEvt) {\n            // If dragging was stopped by some external intervention, stop listening.\n            if (!this.isDragging) {\n                this._detachDragListeners();\n                return;\n            }\n            let newX = 0;\n            let newY = 0;\n            // If dragging is performed with a mouse, there is only one set of coordinates available.\n            // But when using a touch device, there may be many of them, so use the coordinates from the first touch.\n            if (domEvt instanceof MouseEvent) {\n                newX = domEvt.clientX;\n                newY = domEvt.clientY;\n            } else {\n                newX = domEvt.touches[0].clientX;\n                newY = domEvt.touches[0].clientY;\n            }\n            // Prevents selection of text while dragging on Safari.\n            domEvt.preventDefault();\n            this.fire('drag', {\n                deltaX: Math.round(newX - this._lastDraggingCoordinates.x),\n                deltaY: Math.round(newY - this._lastDraggingCoordinates.y)\n            });\n            this._lastDraggingCoordinates = {\n                x: newX,\n                y: newY\n            };\n        }\n        /**\n\t\t * Stops the dragging and detaches the listeners.\n\t\t */ _onDragEnd() {\n            this._detachDragListeners();\n            this.isDragging = false;\n        }\n        /**\n\t\t * Checks if the drag handle element was pressed.\n\t\t */ _isHandleElementPressed(domEvt) {\n            if (!this.dragHandleElement) {\n                return false;\n            }\n            return this.dragHandleElement === domEvt.target || domEvt.target instanceof HTMLElement && this.dragHandleElement.contains(domEvt.target);\n        }\n    }\n    return DraggableMixin;\n}\n\n/**\n * A dialog actions view class. It contains button views which are used to execute dialog actions.\n */ class DialogActionsView extends View {\n    /**\n\t * A collection of button views.\n\t */ children;\n    /**\n\t * A keystroke handler instance.\n\t */ keystrokes;\n    /**\n\t * A focus cycler instance.\n\t */ focusCycler;\n    /**\n\t * A focus tracker instance.\n\t */ _focusTracker;\n    /**\n\t * A collection of focusable views.\n\t */ _focusables;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.children = this.createCollection();\n        this.keystrokes = new KeystrokeHandler();\n        this._focusTracker = new FocusTracker();\n        this._focusables = new ViewCollection();\n        this.focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this._focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-dialog__actions'\n                ]\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * Creates the button views based on the given definitions.\n\t * Then adds them to the {@link #children} collection and to the focus cycler.\n\t */ setButtons(definitions) {\n        for (const definition of definitions){\n            const button = new ButtonView(this.locale);\n            let property;\n            button.on('execute', ()=>definition.onExecute());\n            if (definition.onCreate) {\n                definition.onCreate(button);\n            }\n            for(property in definition){\n                if (property != 'onExecute' && property != 'onCreate') {\n                    button.set(property, definition[property]);\n                }\n            }\n            this.children.add(button);\n        }\n        this._updateFocusCyclableItems();\n    }\n    /**\n\t * @inheritDoc\n\t */ focus(direction) {\n        if (direction === -1) {\n            this.focusCycler.focusLast();\n        } else {\n            this.focusCycler.focusFirst();\n        }\n    }\n    /**\n\t * Adds all elements from the {@link #children} collection to the {@link #_focusables} collection\n\t * and to the {@link #_focusTracker} instance.\n\t */ _updateFocusCyclableItems() {\n        Array.from(this.children).forEach((v)=>{\n            this._focusables.add(v);\n            this._focusTracker.add(v.element);\n        });\n    }\n}\n\n/**\n * A dialog content view class.\n */ class DialogContentView extends View {\n    /**\n\t * A collection of content items.\n\t */ children;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.children = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-dialog__content'\n                ]\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * Removes all the child views.\n\t */ reset() {\n        while(this.children.length){\n            this.children.remove(0);\n        }\n    }\n}\n\n// @if CK_DEBUG_DIALOG // const RectDrawer = require( '@ckeditor/ckeditor5-utils/tests/_utils/rectdrawer' ).default;\n/**\n * Available dialog view positions:\n *\n * * `DialogViewPosition.SCREEN_CENTER` &ndash; A fixed position in the center of the screen.\n * * `DialogViewPosition.EDITOR_CENTER` &ndash; A dynamic position in the center of the editor editable area.\n * * `DialogViewPosition.EDITOR_TOP_SIDE` &ndash; A dynamic position at the top-right (for the left-to-right languages)\n * or top-left (for right-to-left languages) corner of the editor editable area.\n * * `DialogViewPosition.EDITOR_TOP_CENTER` &ndash; A dynamic position at the top-center of the editor editable area.\n * * `DialogViewPosition.EDITOR_BOTTOM_CENTER` &ndash; A dynamic position at the bottom-center of the editor editable area.\n * * `DialogViewPosition.EDITOR_ABOVE_CENTER` &ndash; A dynamic position centered above the editor editable area.\n * * `DialogViewPosition.EDITOR_BELOW_CENTER` &ndash; A dynamic position centered below the editor editable area.\n *\n * The position of a dialog is specified by a {@link module:ui/dialog/dialog~DialogDefinition#position `position` property} of a\n * definition passed to the {@link module:ui/dialog/dialog~Dialog#show} method.\n */ const DialogViewPosition = {\n    SCREEN_CENTER: 'screen-center',\n    EDITOR_CENTER: 'editor-center',\n    EDITOR_TOP_SIDE: 'editor-top-side',\n    EDITOR_TOP_CENTER: 'editor-top-center',\n    EDITOR_BOTTOM_CENTER: 'editor-bottom-center',\n    EDITOR_ABOVE_CENTER: 'editor-above-center',\n    EDITOR_BELOW_CENTER: 'editor-below-center'\n};\nconst toPx$6 = /* #__PURE__ */ toUnit('px');\n/**\n * A dialog view class.\n */ class DialogView extends /* #__PURE__ */ DraggableViewMixin(View) {\n    /**\n\t * A collection of the child views inside of the dialog.\n\t * A dialog can have 3 optional parts: header, content, and actions.\n\t */ parts;\n    /**\n\t * A header view of the dialog. It is also a drag handle of the dialog.\n\t */ headerView;\n    /**\n\t * A close button view. It is automatically added to the header view if present.\n\t */ closeButtonView;\n    /**\n\t * A view with the action buttons available to the user.\n\t */ actionsView;\n    /**\n\t * A default dialog element offset from the reference element (e.g. editor editable area).\n\t */ static defaultOffset = 15;\n    /**\n\t * A view with the dialog content.\n\t */ contentView;\n    /**\n\t * A keystroke handler instance.\n\t */ keystrokes;\n    /**\n\t * A focus tracker instance.\n\t */ focusTracker;\n    /**\n\t * A flag indicating if the dialog was moved manually. If so, its position\n\t * will not be updated automatically upon window resize or document scroll.\n\t */ wasMoved = false;\n    /**\n\t * A callback returning the DOM root that requested the dialog.\n\t */ _getCurrentDomRoot;\n    /**\n\t * A callback returning the configured editor viewport offset.\n\t */ _getViewportOffset;\n    /**\n\t * The list of the focusable elements inside the dialog view.\n\t */ _focusables;\n    /**\n\t * The focus cycler instance.\n\t */ _focusCycler;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, { getCurrentDomRoot, getViewportOffset }){\n        super(locale);\n        const bind = this.bindTemplate;\n        const t = locale.t;\n        this.set('className', '');\n        this.set('ariaLabel', t('Editor dialog'));\n        this.set('isModal', false);\n        this.set('position', DialogViewPosition.SCREEN_CENTER);\n        this.set('_isVisible', false);\n        this.set('_isTransparent', false);\n        this.set('_top', 0);\n        this.set('_left', 0);\n        this._getCurrentDomRoot = getCurrentDomRoot;\n        this._getViewportOffset = getViewportOffset;\n        this.decorate('moveTo');\n        this.parts = this.createCollection();\n        this.keystrokes = new KeystrokeHandler();\n        this.focusTracker = new FocusTracker();\n        this._focusables = new ViewCollection();\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-dialog-overlay',\n                    bind.if('isModal', 'ck-dialog-overlay__transparent', (isModal)=>!isModal),\n                    bind.if('_isVisible', 'ck-hidden', (value)=>!value)\n                ],\n                // Prevent from editor losing focus when clicking on the modal overlay.\n                tabindex: '-1'\n            },\n            children: [\n                {\n                    tag: 'div',\n                    attributes: {\n                        tabindex: '-1',\n                        class: [\n                            'ck',\n                            'ck-dialog',\n                            bind.if('isModal', 'ck-dialog_modal'),\n                            bind.to('className')\n                        ],\n                        role: 'dialog',\n                        'aria-label': bind.to('ariaLabel'),\n                        style: {\n                            top: bind.to('_top', (top)=>toPx$6(top)),\n                            left: bind.to('_left', (left)=>toPx$6(left)),\n                            visibility: bind.if('_isTransparent', 'hidden')\n                        }\n                    },\n                    children: this.parts\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.keystrokes.set('Esc', (data, cancel)=>{\n            this.fire('close', {\n                source: 'escKeyPress'\n            });\n            cancel();\n        });\n        // Support for dragging the modal.\n        this.on('drag', (evt, { deltaX, deltaY })=>{\n            this.wasMoved = true;\n            this.moveBy(deltaX, deltaY);\n        });\n        // Update dialog position upon window resize, if the position was not changed manually.\n        this.listenTo(global.window, 'resize', ()=>{\n            if (this._isVisible && !this.wasMoved) {\n                this.updatePosition();\n            }\n        });\n        // Update dialog position upon document scroll, if the position was not changed manually.\n        this.listenTo(global.document, 'scroll', ()=>{\n            if (this._isVisible && !this.wasMoved) {\n                this.updatePosition();\n            }\n        });\n        this.on('change:_isVisible', (evt, name, isVisible)=>{\n            if (isVisible) {\n                // Let the content render first, then apply the position. Otherwise, the calculated DOM Rects\n                // will not reflect the final look of the dialog. Note that we're not using #_moveOffScreen() here because\n                // it causes a violent movement of the viewport on iOS (because the dialog still keeps the DOM focus).\n                this._isTransparent = true;\n                // FYI: RAF is too short. We need to wait a bit longer.\n                setTimeout(()=>{\n                    this.updatePosition();\n                    this._isTransparent = false;\n                    // The view must get the focus after it gets visible. But this is only possible\n                    // after the dialog is no longer transparent.\n                    this.focus();\n                }, 10);\n            }\n        });\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * Returns the element that should be used as a drag handle.\n\t */ get dragHandleElement() {\n        // Modals should not be draggable.\n        if (this.headerView && !this.isModal) {\n            return this.headerView.element;\n        } else {\n            return null;\n        }\n    }\n    /**\n\t * Creates the dialog parts. Which of them are created depends on the arguments passed to the method.\n\t * There are no rules regarding the dialog construction, that is, no part is mandatory.\n\t * Each part can only be created once.\n\t *\n\t * @internal\n\t */ setupParts({ icon, title, hasCloseButton = true, content, actionButtons }) {\n        if (title) {\n            this.headerView = new FormHeaderView(this.locale, {\n                icon\n            });\n            if (hasCloseButton) {\n                this.closeButtonView = this._createCloseButton();\n                this.headerView.children.add(this.closeButtonView);\n            }\n            this.headerView.label = title;\n            this.ariaLabel = title;\n            this.parts.add(this.headerView, 0);\n        }\n        if (content) {\n            // Normalize the content specified in the arguments.\n            if (content instanceof View) {\n                content = [\n                    content\n                ];\n            }\n            this.contentView = new DialogContentView(this.locale);\n            this.contentView.children.addMany(content);\n            this.parts.add(this.contentView);\n        }\n        if (actionButtons) {\n            this.actionsView = new DialogActionsView(this.locale);\n            this.actionsView.setButtons(actionButtons);\n            this.parts.add(this.actionsView);\n        }\n        this._updateFocusCyclableItems();\n    }\n    /**\n\t * Focuses the first focusable element inside the dialog.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Normalizes the passed coordinates to make sure the dialog view\n\t * is displayed within the visible viewport and moves it there.\n\t *\n\t * @internal\n\t */ moveTo(left, top) {\n        const viewportRect = this._getViewportRect();\n        const dialogRect = this._getDialogRect();\n        // Don't let the dialog go beyond the right edge of the viewport.\n        if (left + dialogRect.width > viewportRect.right) {\n            left = viewportRect.right - dialogRect.width;\n        }\n        // Don't let the dialog go beyond the left edge of the viewport.\n        if (left < viewportRect.left) {\n            left = viewportRect.left;\n        }\n        // Don't let the dialog go beyond the top edge of the viewport.\n        if (top < viewportRect.top) {\n            top = viewportRect.top;\n        }\n        // Note: We don't do the same for the bottom edge to allow users to resize the window vertically\n        // and let the dialog to stay put instead of covering the editing root.\n        this._moveTo(left, top);\n    }\n    /**\n\t * Moves the dialog to the specified coordinates.\n\t */ _moveTo(left, top) {\n        this._left = left;\n        this._top = top;\n    }\n    /**\n\t * Moves the dialog by the specified offset.\n\t *\n\t * @internal\n\t */ moveBy(left, top) {\n        this.moveTo(this._left + left, this._top + top);\n    }\n    /**\n\t * Moves the dialog view to the off-screen position.\n\t * Used when there is no space to display the dialog.\n\t */ _moveOffScreen() {\n        this._moveTo(-9999, -9999);\n    }\n    /**\n\t * Recalculates the dialog according to the set position and viewport,\n\t * and moves it to the new position.\n\t */ updatePosition() {\n        if (!this.element || !this.element.parentNode) {\n            return;\n        }\n        const viewportRect = this._getViewportRect();\n        // Actual position may be different from the configured one if there's no DOM root.\n        let configuredPosition = this.position;\n        let domRootRect;\n        if (!this._getCurrentDomRoot()) {\n            configuredPosition = DialogViewPosition.SCREEN_CENTER;\n        } else {\n            domRootRect = this._getVisibleDomRootRect(viewportRect);\n        }\n        const defaultOffset = DialogView.defaultOffset;\n        const dialogRect = this._getDialogRect();\n        // @if CK_DEBUG_DIALOG // RectDrawer.clear();\n        // @if CK_DEBUG_DIALOG // RectDrawer.draw( viewportRect, { outlineColor: 'blue' }, 'Viewport' );\n        switch(configuredPosition){\n            case DialogViewPosition.EDITOR_TOP_SIDE:\n                {\n                    // @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n                    // @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n                    // @if CK_DEBUG_DIALOG // }\n                    if (domRootRect) {\n                        const leftCoordinate = this.locale.contentLanguageDirection === 'ltr' ? domRootRect.right - dialogRect.width - defaultOffset : domRootRect.left + defaultOffset;\n                        this.moveTo(leftCoordinate, domRootRect.top + defaultOffset);\n                    } else {\n                        this._moveOffScreen();\n                    }\n                    break;\n                }\n            case DialogViewPosition.EDITOR_CENTER:\n                {\n                    if (domRootRect) {\n                        this.moveTo(Math.round(domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2), Math.round(domRootRect.top + domRootRect.height / 2 - dialogRect.height / 2));\n                    } else {\n                        this._moveOffScreen();\n                    }\n                    break;\n                }\n            case DialogViewPosition.SCREEN_CENTER:\n                {\n                    this.moveTo(Math.round((viewportRect.width - dialogRect.width) / 2), Math.round((viewportRect.height - dialogRect.height) / 2));\n                    break;\n                }\n            case DialogViewPosition.EDITOR_TOP_CENTER:\n                {\n                    // @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n                    // @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n                    // @if CK_DEBUG_DIALOG // }\n                    if (domRootRect) {\n                        this.moveTo(Math.round(domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2), domRootRect.top + defaultOffset);\n                    } else {\n                        this._moveOffScreen();\n                    }\n                    break;\n                }\n            case DialogViewPosition.EDITOR_BOTTOM_CENTER:\n                {\n                    // @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n                    // @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n                    // @if CK_DEBUG_DIALOG // }\n                    if (domRootRect) {\n                        this.moveTo(Math.round(domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2), domRootRect.bottom - dialogRect.height - defaultOffset);\n                    } else {\n                        this._moveOffScreen();\n                    }\n                    break;\n                }\n            case DialogViewPosition.EDITOR_ABOVE_CENTER:\n                {\n                    // @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n                    // @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n                    // @if CK_DEBUG_DIALOG // }\n                    if (domRootRect) {\n                        this.moveTo(Math.round(domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2), domRootRect.top - dialogRect.height - defaultOffset);\n                    } else {\n                        this._moveOffScreen();\n                    }\n                    break;\n                }\n            case DialogViewPosition.EDITOR_BELOW_CENTER:\n                {\n                    // @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n                    // @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n                    // @if CK_DEBUG_DIALOG // }\n                    if (domRootRect) {\n                        this.moveTo(Math.round(domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2), domRootRect.bottom + defaultOffset);\n                    } else {\n                        this._moveOffScreen();\n                    }\n                    break;\n                }\n        }\n    }\n    /**\n\t * Calculates the visible DOM root part.\n\t */ _getVisibleDomRootRect(viewportRect) {\n        let visibleDomRootRect = new Rect(this._getCurrentDomRoot()).getVisible();\n        if (!visibleDomRootRect) {\n            return null;\n        } else {\n            visibleDomRootRect = viewportRect.getIntersection(visibleDomRootRect);\n            if (!visibleDomRootRect) {\n                return null;\n            }\n        }\n        return visibleDomRootRect;\n    }\n    /**\n\t * Calculates the dialog element rect.\n\t */ _getDialogRect() {\n        return new Rect(this.element.firstElementChild);\n    }\n    /**\n\t * Returns a viewport `Rect` shrunk by the viewport offset config from all sides.\n\t *\n\t * TODO: This is a duplicate from position.ts module. It should either be exported there or land somewhere in utils.\n\t */ _getViewportRect() {\n        const viewportRect = new Rect(global.window);\n        // Modals should not be restricted by the viewport offsets as they are always displayed on top of the page.\n        if (this.isModal) {\n            return viewportRect;\n        }\n        const viewportOffset = {\n            top: 0,\n            bottom: 0,\n            left: 0,\n            right: 0,\n            ...this._getViewportOffset()\n        };\n        viewportRect.top += viewportOffset.top;\n        viewportRect.height -= viewportOffset.top;\n        viewportRect.bottom -= viewportOffset.bottom;\n        viewportRect.height -= viewportOffset.bottom;\n        viewportRect.left += viewportOffset.left;\n        viewportRect.right -= viewportOffset.right;\n        viewportRect.width -= viewportOffset.left + viewportOffset.right;\n        return viewportRect;\n    }\n    /**\n\t * Collects all focusable elements inside the dialog parts\n\t * and adds them to the focus tracker and focus cycler.\n\t */ _updateFocusCyclableItems() {\n        const focusables = [];\n        if (this.contentView) {\n            for (const child of this.contentView.children){\n                if (isFocusable(child)) {\n                    focusables.push(child);\n                }\n            }\n        }\n        if (this.actionsView) {\n            focusables.push(this.actionsView);\n        }\n        if (this.closeButtonView) {\n            focusables.push(this.closeButtonView);\n        }\n        focusables.forEach((focusable)=>{\n            this._focusables.add(focusable);\n            this.focusTracker.add(focusable.element);\n            if (isViewWithFocusCycler(focusable)) {\n                this._focusCycler.chain(focusable.focusCycler);\n            }\n        });\n    }\n    /**\n\t * Creates the close button view that is displayed in the header view corner.\n\t */ _createCloseButton() {\n        const buttonView = new ButtonView(this.locale);\n        const t = this.locale.t;\n        buttonView.set({\n            label: t('Close'),\n            tooltip: true,\n            icon: icons.cancel\n        });\n        buttonView.on('execute', ()=>this.fire('close', {\n                source: 'closeButton'\n            }));\n        return buttonView;\n    }\n}\n\n/**\n * The dialog controller class. It is used to show and hide the {@link module:ui/dialog/dialogview~DialogView}.\n */ class Dialog extends Plugin {\n    /**\n\t * The currently visible dialog view instance.\n\t */ view;\n    /**\n\t * The `Dialog` plugin instance which most recently showed the dialog.\n\t *\n\t * Only one dialog can be visible at once, even if there are many editor instances on the page.\n\t * If an editor wants to show a dialog, it should first hide the dialog that is already opened.\n\t * But only the `Dialog` instance that showed the dialog is able able to properly hide it.\n\t * This is why we need to store it in a globally available space (static property).\n\t * This way every `Dialog` plugin in every editor is able to correctly close any open dialog window.\n\t */ static _visibleDialogPlugin;\n    /**\n\t * A configurable callback called when the dialog is hidden.\n\t */ _onHide;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Dialog';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        const t = editor.t;\n        this._initShowHideListeners();\n        this._initFocusToggler();\n        this._initMultiRootIntegration();\n        this.set({\n            id: null,\n            isOpen: false\n        });\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            categoryId: 'navigation',\n            keystrokes: [\n                {\n                    label: t('Move focus in and out of an active dialog window'),\n                    keystroke: 'Ctrl+F6',\n                    mayRequireFn: true\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this._unlockBodyScroll();\n    }\n    /**\n\t * Initiates listeners for the `show` and `hide` events emitted by this plugin.\n\t *\n\t * We could not simply decorate the {@link #show} and {@link #hide} methods to fire events,\n\t * because they would be fired in the wrong order &ndash; first would be `show` and then `hide`\n\t * (because showing the dialog actually starts with hiding the previously visible one).\n\t * Hence, we added private methods {@link #_show} and {@link #_hide} which are called on events\n\t * in the desired sequence.\n\t */ _initShowHideListeners() {\n        this.on('show', (evt, args)=>{\n            this._show(args);\n        });\n        // 'low' priority allows to add custom callback between `_show()` and `onShow()`.\n        this.on('show', (evt, args)=>{\n            if (args.onShow) {\n                args.onShow(this);\n            }\n        }, {\n            priority: 'low'\n        });\n        this.on('hide', ()=>{\n            if (Dialog._visibleDialogPlugin) {\n                Dialog._visibleDialogPlugin._hide();\n            }\n        });\n        // 'low' priority allows to add custom callback between `_hide()` and `onHide()`.\n        this.on('hide', ()=>{\n            if (this._onHide) {\n                this._onHide(this);\n                this._onHide = undefined;\n            }\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * Initiates keystroke handler for toggling the focus between the editor and the dialog view.\n\t */ _initFocusToggler() {\n        const editor = this.editor;\n        editor.keystrokes.set('Ctrl+F6', (data, cancel)=>{\n            if (!this.isOpen || this.view.isModal) {\n                return;\n            }\n            if (this.view.focusTracker.isFocused) {\n                editor.editing.view.focus();\n            } else {\n                this.view.focus();\n            }\n            cancel();\n        });\n    }\n    /**\n\t * Provides an integration between the root attaching and detaching and positioning of the view.\n\t */ _initMultiRootIntegration() {\n        const model = this.editor.model;\n        model.document.on('change:data', ()=>{\n            if (!this.view) {\n                return;\n            }\n            const changedRoots = model.document.differ.getChangedRoots();\n            for (const changes of changedRoots){\n                if (changes.state) {\n                    this.view.updatePosition();\n                }\n            }\n        });\n    }\n    /**\n\t * Displays a dialog window.\n\t *\n\t * This method requires a {@link ~DialogDefinition} that defines the dialog's content, title, icon, action buttons, etc.\n\t *\n\t * For example, the following definition will create a dialog with:\n\t * * A header consisting of an icon, a title, and a \"Close\" button (it is added by default).\n\t * * A content consisting of a view with a single paragraph.\n\t * * A footer consisting of two buttons: \"Yes\" and \"No\".\n\t *\n\t * ```js\n\t * // Create the view that will be used as the dialog's content.\n\t * const textView = new View( locale );\n\t *\n\t * textView.setTemplate( {\n\t * \ttag: 'div',\n\t * \tattributes: {\n\t * \t\tstyle: {\n\t * \t\t\tpadding: 'var(--ck-spacing-large)',\n\t * \t\t\twhiteSpace: 'initial',\n\t * \t\t\twidth: '100%',\n\t * \t\t\tmaxWidth: '500px'\n\t * \t\t},\n\t * \t\ttabindex: -1\n\t * \t},\n\t * \tchildren: [\n\t * \t\t'Lorem ipsum dolor sit amet...'\n\t * \t]\n\t * } );\n\t *\n\t * // Show the dialog.\n\t * editor.plugins.get( 'Dialog' ).show( {\n\t *\tid: 'myDialog',\n\t * \ticon: 'myIcon', // This should be an SVG string.\n\t * \ttitle: 'My dialog',\n\t * \tcontent: textView,\n\t * \tactionButtons: [\n\t *\t\t{\n\t *\t\t\tlabel: t( 'Yes' ),\n\t *\t\t\tclass: 'ck-button-action',\n\t *\t\t\twithText: true,\n\t *\t\t\tonExecute: () => dialog.hide()\n\t *\t\t},\n\t *\t\t{\n\t *\t\t\tlabel: t( 'No' ),\n\t *\t\t\twithText: true,\n\t *\t\t\tonExecute: () => dialog.hide()\n\t *\t\t}\n\t *\t]\n\t * } );\n\t * ```\n\t *\n\t * By specifying the {@link ~DialogDefinition#onShow} and {@link ~DialogDefinition#onHide} callbacks\n\t * it is also possible to add callbacks that will be called when the dialog is shown or hidden.\n\t *\n\t * For example, the callbacks in the following definition:\n\t * * Disable the default behavior of the <kbd>Esc</kbd> key.\n\t * * Fire a custom event when the dialog gets hidden.\n\t *\n\t * ```js\n\t * editor.plugins.get( 'Dialog' ).show( {\n\t * \t// ...\n\t * \tonShow: dialog => {\n\t * \t\tdialog.view.on( 'close', ( evt, data ) => {\n\t * \t\t\t// Only prevent the event from the \"Esc\" key - do not affect the other ways of closing the dialog.\n\t * \t\t\tif ( data.source === 'escKeyPress' ) {\n\t * \t\t\t\tevt.stop();\n\t * \t\t\t}\n\t * \t\t} );\n\t * \t},\n\t * \tonHide: dialog => {\n\t * \t\tdialog.fire( 'dialogDestroyed' );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Internally, calling this method:\n\t * 1. Hides the currently visible dialog (if any) calling the {@link #hide} method\n\t * (fires the {@link ~DialogHideEvent hide event}).\n\t * 2. Fires the {@link ~DialogShowEvent show event} which allows for adding callbacks that customize the\n\t * behavior of the dialog.\n\t * 3. Shows the dialog.\n\t */ show(dialogDefinition) {\n        this.hide();\n        this.fire(`show:${dialogDefinition.id}`, dialogDefinition);\n    }\n    /**\n\t * Handles creating the {@link module:ui/dialog/dialogview~DialogView} instance and making it visible.\n\t */ _show({ id, icon, title, hasCloseButton = true, content, actionButtons, className, isModal, position, onHide }) {\n        const editor = this.editor;\n        this.view = new DialogView(editor.locale, {\n            getCurrentDomRoot: ()=>{\n                return editor.editing.view.getDomRoot(editor.model.document.selection.anchor.root.rootName);\n            },\n            getViewportOffset: ()=>{\n                return editor.ui.viewportOffset;\n            }\n        });\n        const view = this.view;\n        view.on('close', ()=>{\n            this.hide();\n        });\n        editor.ui.view.body.add(view);\n        editor.keystrokes.listenTo(view.element);\n        // Unless the user specified a position, modals should always be centered on the screen.\n        // Otherwise, let's keep dialogs centered in the editing root by default.\n        if (!position) {\n            position = isModal ? DialogViewPosition.SCREEN_CENTER : DialogViewPosition.EDITOR_CENTER;\n        }\n        if (isModal) {\n            this._lockBodyScroll();\n        }\n        view.set({\n            position,\n            _isVisible: true,\n            className,\n            isModal\n        });\n        view.setupParts({\n            icon,\n            title,\n            hasCloseButton,\n            content,\n            actionButtons\n        });\n        this.id = id;\n        if (onHide) {\n            this._onHide = onHide;\n        }\n        this.isOpen = true;\n        Dialog._visibleDialogPlugin = this;\n    }\n    /**\n\t * Hides the dialog. This method is decorated to enable interacting on the {@link ~DialogHideEvent hide event}.\n\t *\n\t * See {@link #show}.\n\t */ hide() {\n        if (Dialog._visibleDialogPlugin) {\n            Dialog._visibleDialogPlugin.fire(`hide:${Dialog._visibleDialogPlugin.id}`);\n        }\n    }\n    /**\n\t * Destroys the {@link module:ui/dialog/dialogview~DialogView} and cleans up the stored dialog state.\n\t */ _hide() {\n        if (!this.view) {\n            return;\n        }\n        const editor = this.editor;\n        const view = this.view;\n        if (view.isModal) {\n            this._unlockBodyScroll();\n        }\n        // Reset the content view to prevent its children from being destroyed in the standard\n        // View#destroy() (and collections) chain. If the content children were left in there,\n        // they would have to be re-created by the feature using the dialog every time the dialog\n        // shows up.\n        if (view.contentView) {\n            view.contentView.reset();\n        }\n        editor.ui.view.body.remove(view);\n        editor.ui.focusTracker.remove(view.element);\n        editor.keystrokes.stopListening(view.element);\n        view.destroy();\n        editor.editing.view.focus();\n        this.id = null;\n        this.isOpen = false;\n        Dialog._visibleDialogPlugin = null;\n    }\n    /**\n\t * Makes the <body> unscrollable (e.g. when the modal shows up).\n\t */ _lockBodyScroll() {\n        document.documentElement.classList.add('ck-dialog-scroll-locked');\n    }\n    /**\n\t * Makes the <body> scrollable again (e.g. once the modal hides).\n\t */ _unlockBodyScroll() {\n        document.documentElement.classList.remove('ck-dialog-scroll-locked');\n    }\n}\n\n/**\n * Button that is used as dropdown list item entry.\n */ class ListItemButtonView extends ButtonView {\n    /**\n\t * Holds the view for the check icon of a button list item.\n\t */ _checkIconHolderView = new CheckIconHolderView();\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, labelView = new ButtonLabelView()){\n        super(locale, labelView);\n        this.set({\n            hasCheckSpace: false,\n            _hasCheck: this.isToggleable\n        });\n        const bind = this.bindTemplate;\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-list-item-button',\n                    bind.if('isToggleable', 'ck-list-item-button_toggleable')\n                ]\n            }\n        });\n        this.bind('_hasCheck').to(this, 'hasCheckSpace', this, 'isToggleable', (hasCheckSpace, isToggleable)=>hasCheckSpace || isToggleable);\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        if (this._hasCheck) {\n            this.children.add(this._checkIconHolderView, 0);\n        }\n        this._watchCheckIconHolderMount();\n    }\n    /**\n\t * Renders the check icon if the button is toggleable.\n\t */ _watchCheckIconHolderMount() {\n        this._checkIconHolderView.bind('isOn').to(this, 'isOn', (value)=>this.isToggleable && value);\n        this.on('change:_hasCheck', (evt, propertyName, hasCheck)=>{\n            const { children, _checkIconHolderView } = this;\n            if (hasCheck) {\n                children.add(_checkIconHolderView, 0);\n            } else {\n                children.remove(_checkIconHolderView);\n            }\n        });\n    }\n}\nclass CheckIconHolderView extends View {\n    /**\n\t * Collection of child views.\n\t */ children;\n    /**\n\t * The view for the check icon of the button list item.\n\t */ _checkIconView = this._createCheckIconView();\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        const bind = this.bindTemplate;\n        this.children = this.createCollection();\n        this.set('isOn', false);\n        this.setTemplate({\n            tag: 'span',\n            children: this.children,\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-list-item-button__check-holder',\n                    bind.to('isOn', (isOn)=>isOn ? 'ck-on' : 'ck-off')\n                ]\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        if (this.isOn) {\n            this.children.add(this._checkIconView, 0);\n        }\n        this._watchCheckIconMount();\n    }\n    /**\n\t * Renders the check icon if the button is toggleable.\n\t */ _watchCheckIconMount() {\n        this.on('change:isOn', (evt, propertyName, isOn)=>{\n            const { children, _checkIconView } = this;\n            if (isOn && !children.has(_checkIconView)) {\n                children.add(_checkIconView);\n            } else if (!isOn && children.has(_checkIconView)) {\n                children.remove(_checkIconView);\n            }\n        });\n    }\n    /**\n\t * Creates a check icon view.\n\t */ _createCheckIconView() {\n        const iconView = new IconView();\n        iconView.content = icons.check;\n        iconView.extendTemplate({\n            attributes: {\n                class: 'ck-list-item-button__check-icon'\n            }\n        });\n        return iconView;\n    }\n}\n\n/**\n * A menu bar list button view. Buttons like this one execute user actions.\n */ class MenuBarMenuListItemButtonView extends ListItemButtonView {\n    /**\n\t * Creates an instance of the menu bar list button view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        this.set({\n            withText: true,\n            withKeystroke: true,\n            tooltip: false,\n            role: 'menuitem'\n        });\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-menu-bar__menu__item__button'\n                ]\n            }\n        });\n    }\n}\n\n/**\n * The label view class.\n */ class LabelView extends View {\n    /**\n\t * An unique id of the label. It can be used by other UI components to reference\n\t * the label, for instance, using the `aria-describedby` DOM attribute.\n\t */ id;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.set('text', undefined);\n        this.set('for', undefined);\n        this.id = `ck-editor__label_${uid()}`;\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'label',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-label'\n                ],\n                id: this.id,\n                for: bind.to('for')\n            },\n            children: [\n                {\n                    text: bind.to('text')\n                }\n            ]\n        });\n    }\n}\n\n/**\n * The view displaying keystrokes in the Accessibility help dialog.\n */ class AccessibilityHelpContentView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, keystrokes){\n        super(locale);\n        const t = locale.t;\n        const helpLabel = new LabelView();\n        helpLabel.text = t('Help Contents. To close this dialog press ESC.');\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-accessibility-help-dialog__content'\n                ],\n                'aria-labelledby': helpLabel.id,\n                role: 'document',\n                tabindex: -1\n            },\n            children: [\n                createElement(document, 'p', {}, t('Below, you can find a list of keyboard shortcuts that can be used in the editor.')),\n                ...this._createCategories(Array.from(keystrokes.values())),\n                helpLabel\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ focus() {\n        this.element.focus();\n    }\n    /**\n\t * Creates `<section><h3>Category label</h3>...</section>` elements for each category of keystrokes.\n\t */ _createCategories(categories) {\n        return categories.map((categoryDefinition)=>{\n            const elements = [\n                // Category header.\n                createElement(document, 'h3', {}, categoryDefinition.label),\n                // Category definitions (<dl>) and their optional headers (<h4>).\n                ...Array.from(categoryDefinition.groups.values()).map((groupDefinition)=>this._createGroup(groupDefinition)).flat()\n            ];\n            // Category description (<p>).\n            if (categoryDefinition.description) {\n                elements.splice(1, 0, createElement(document, 'p', {}, categoryDefinition.description));\n            }\n            return createElement(document, 'section', {}, elements);\n        });\n    }\n    /**\n\t * Creates `[<h4>Optional label</h4>]<dl>...</dl>` elements for each group of keystrokes in a category.\n\t */ _createGroup(groupDefinition) {\n        const definitionAndDescriptionElements = groupDefinition.keystrokes.sort((a, b)=>a.label.localeCompare(b.label)).map((keystrokeDefinition)=>this._createGroupRow(keystrokeDefinition)).flat();\n        const elements = [\n            createElement(document, 'dl', {}, definitionAndDescriptionElements)\n        ];\n        if (groupDefinition.label) {\n            elements.unshift(createElement(document, 'h4', {}, groupDefinition.label));\n        }\n        return elements;\n    }\n    /**\n\t * Creates `<dt>Keystroke label</dt><dd>Keystroke definition</dd>` elements for each keystroke in a group.\n\t */ _createGroupRow(keystrokeDefinition) {\n        const t = this.locale.t;\n        const dt = createElement(document, 'dt');\n        const dd = createElement(document, 'dd');\n        const normalizedKeystrokeDefinition = normalizeKeystrokeDefinition(keystrokeDefinition.keystroke);\n        const keystrokeAlternativeHTMLs = [];\n        for (const keystrokeAlternative of normalizedKeystrokeDefinition){\n            keystrokeAlternativeHTMLs.push(keystrokeAlternative.map(keystrokeToEnvKbd).join(''));\n        }\n        dt.innerHTML = keystrokeDefinition.label;\n        dd.innerHTML = keystrokeAlternativeHTMLs.join(', ') + (keystrokeDefinition.mayRequireFn && env.isMac ? ` ${t('(may require <kbd>Fn</kbd>)')}` : '');\n        return [\n            dt,\n            dd\n        ];\n    }\n}\nfunction keystrokeToEnvKbd(keystroke) {\n    return getEnvKeystrokeText(keystroke).split('+').map((part)=>`<kbd>${part}</kbd>`).join('+');\n}\nfunction normalizeKeystrokeDefinition(definition) {\n    if (typeof definition === 'string') {\n        return [\n            [\n                definition\n            ]\n        ];\n    }\n    if (typeof definition[0] === 'string') {\n        return [\n            definition\n        ];\n    }\n    return definition;\n}\n\nvar accessibilityIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M10 6.628a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z\\\"/><path d=\\\"M8.5 9.125a.3.3 0 0 0-.253-.296L5.11 8.327a.75.75 0 1 1 .388-1.449l4.04.716c.267.072.624.08.893.009l4.066-.724a.75.75 0 1 1 .388 1.45l-3.132.5a.3.3 0 0 0-.253.296v1.357a.3.3 0 0 0 .018.102l1.615 4.438a.75.75 0 0 1-1.41.513l-1.35-3.71a.3.3 0 0 0-.281-.197h-.209a.3.3 0 0 0-.282.198l-1.35 3.711a.75.75 0 0 1-1.41-.513l1.64-4.509a.3.3 0 0 0 .019-.103V9.125Z\\\"/><path clip-rule=\\\"evenodd\\\" d=\\\"M10 18.5a8.5 8.5 0 1 1 0-17 8.5 8.5 0 0 1 0 17Zm0 1.5c5.523 0 10-4.477 10-10S15.523 0 10 0 0 4.477 0 10s4.477 10 10 10Z\\\"/></svg>\";\n\n/**\n * A plugin that brings the accessibility help dialog to the editor available under the <kbd>Alt</kbd>+<kbd>0</kbd>\n * keystroke and via the \"Accessibility help\" toolbar button. The dialog displays a list of keystrokes that can be used\n * by the user to perform various actions in the editor.\n *\n * Keystroke information is loaded from {@link module:core/accessibility~Accessibility#keystrokeInfos}. New entries can be\n * added using the API provided by the {@link module:core/accessibility~Accessibility} class.\n */ class AccessibilityHelp extends Plugin {\n    /**\n\t * The view that displays the dialog content (list of keystrokes).\n\t * Created when the dialog is opened for the first time.\n\t */ contentView = null;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Dialog\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'AccessibilityHelp';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        editor.ui.componentFactory.add('accessibilityHelp', ()=>{\n            const button = this._createButton(ButtonView);\n            button.set({\n                tooltip: true,\n                withText: false,\n                label: t('Accessibility help')\n            });\n            return button;\n        });\n        editor.ui.componentFactory.add('menuBar:accessibilityHelp', ()=>{\n            const button = this._createButton(MenuBarMenuListItemButtonView);\n            button.label = t('Accessibility');\n            return button;\n        });\n        editor.keystrokes.set('Alt+0', (evt, cancel)=>{\n            this._toggleDialog();\n            cancel();\n        });\n        this._setupRootLabels();\n    }\n    /**\n\t * Creates a button to show accessibility help dialog, for use either in toolbar or in menu bar.\n\t */ _createButton(ButtonClass) {\n        const editor = this.editor;\n        const dialog = editor.plugins.get('Dialog');\n        const locale = editor.locale;\n        const view = new ButtonClass(locale);\n        view.set({\n            keystroke: 'Alt+0',\n            icon: accessibilityIcon,\n            isToggleable: true\n        });\n        view.on('execute', ()=>this._toggleDialog());\n        view.bind('isOn').to(dialog, 'id', (id)=>id === 'accessibilityHelp');\n        return view;\n    }\n    /**\n\t * Injects a help text into each editing root's `aria-label` attribute allowing assistive technology users\n\t * to discover the availability of the Accessibility help dialog.\n\t */ _setupRootLabels() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const t = editor.t;\n        editor.ui.on('ready', ()=>{\n            editingView.change((writer)=>{\n                for (const root of editingView.document.roots){\n                    addAriaLabelTextToRoot(writer, root);\n                }\n            });\n            editor.on('addRoot', (evt, modelRoot)=>{\n                const viewRoot = editor.editing.view.document.getRoot(modelRoot.rootName);\n                editingView.change((writer)=>addAriaLabelTextToRoot(writer, viewRoot));\n            }, {\n                priority: 'low'\n            });\n        });\n        function addAriaLabelTextToRoot(writer, viewRoot) {\n            const currentAriaLabel = viewRoot.getAttribute('aria-label');\n            const newAriaLabel = [\n                currentAriaLabel,\n                t('Press %0 for help.', [\n                    getEnvKeystrokeText('Alt+0')\n                ])\n            ].filter((segment)=>segment).join('. ');\n            writer.setAttribute('aria-label', newAriaLabel, viewRoot);\n        }\n    }\n    /**\n\t * Shows the accessibility help dialog. Also, creates {@link #contentView} on demand.\n\t */ _toggleDialog() {\n        const editor = this.editor;\n        const dialog = editor.plugins.get('Dialog');\n        const t = editor.locale.t;\n        if (!this.contentView) {\n            this.contentView = new AccessibilityHelpContentView(editor.locale, editor.accessibility.keystrokeInfos);\n        }\n        if (dialog.id === 'accessibilityHelp') {\n            dialog.hide();\n        } else {\n            dialog.show({\n                id: 'accessibilityHelp',\n                className: 'ck-accessibility-help-dialog',\n                title: t('Accessibility help'),\n                icon: accessibilityIcon,\n                hasCloseButton: true,\n                content: this.contentView\n            });\n        }\n    }\n}\n\n/**\n * This is a special {@link module:ui/viewcollection~ViewCollection} dedicated to elements that are detached\n * from the DOM structure of the editor, like panels, icons, etc.\n *\n * The body collection is available in the {@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`} property.\n * Any plugin can add a {@link module:ui/view~View view} to this collection.\n * These views will render in a container placed directly in the `<body>` element.\n * The editor will detach and destroy this collection when the editor will be {@link module:core/editor/editor~Editor#destroy destroyed}.\n *\n * If you need to control the life cycle of the body collection on your own, you can create your own instance of this class.\n *\n * A body collection will render itself automatically in the DOM body element as soon as you call {@link ~BodyCollection#attachToDom}.\n * If you create multiple body collections, this class will create a special wrapper element in the DOM to limit the number of\n * elements created directly in the body and remove it when the last body collection will be\n * {@link ~BodyCollection#detachFromDom detached}.\n */ class BodyCollection extends ViewCollection {\n    /**\n\t * The {@link module:core/editor/editor~Editor#locale editor's locale} instance.\n\t * See the view {@link module:ui/view~View#locale locale} property.\n\t */ locale;\n    /**\n\t * The element holding elements of the body region.\n\t */ _bodyCollectionContainer;\n    /**\n\t * Creates a new instance of the {@link module:ui/editorui/bodycollection~BodyCollection}.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor editor's locale} instance.\n\t * @param initialItems The initial items of the collection.\n\t */ constructor(locale, initialItems = []){\n        super(initialItems);\n        this.locale = locale;\n    }\n    /**\n\t * The element holding elements of the body region.\n\t */ get bodyCollectionContainer() {\n        return this._bodyCollectionContainer;\n    }\n    /**\n\t * Attaches the body collection to the DOM body element. You need to execute this method to render the content of\n\t * the body collection.\n\t */ attachToDom() {\n        this._bodyCollectionContainer = new Template({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-reset_all',\n                    'ck-body',\n                    'ck-rounded-corners'\n                ],\n                dir: this.locale.uiLanguageDirection,\n                role: 'application'\n            },\n            children: this\n        }).render();\n        let wrapper = document.querySelector('.ck-body-wrapper');\n        if (!wrapper) {\n            wrapper = createElement(document, 'div', {\n                class: 'ck-body-wrapper'\n            });\n            document.body.appendChild(wrapper);\n        }\n        wrapper.appendChild(this._bodyCollectionContainer);\n    }\n    /**\n\t * Detaches the collection from the DOM structure. Use this method when you do not need to use the body collection\n\t * anymore to clean-up the DOM structure.\n\t */ detachFromDom() {\n        super.destroy();\n        if (this._bodyCollectionContainer) {\n            this._bodyCollectionContainer.remove();\n        }\n        const wrapper = document.querySelector('.ck-body-wrapper');\n        if (wrapper && wrapper.childElementCount == 0) {\n            wrapper.remove();\n        }\n    }\n}\n\n/**\n * The switch button view class.\n *\n * ```ts\n * const view = new SwitchButtonView();\n *\n * view.set( {\n * \twithText: true,\n * \tlabel: 'Switch me!'\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n */ class SwitchButtonView extends ButtonView {\n    /**\n\t * The toggle switch of the button.\n\t */ toggleSwitchView;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.isToggleable = true;\n        this.toggleSwitchView = this._createToggleView();\n        this.extendTemplate({\n            attributes: {\n                class: 'ck-switchbutton'\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.children.add(this.toggleSwitchView);\n    }\n    /**\n\t * Creates a toggle child view.\n\t */ _createToggleView() {\n        const toggleSwitchView = new View();\n        toggleSwitchView.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-button__toggle'\n                ]\n            },\n            children: [\n                {\n                    tag: 'span',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-button__toggle__inner'\n                        ]\n                    }\n                }\n            ]\n        });\n        return toggleSwitchView;\n    }\n}\n\n/**\n * The file dialog button view.\n *\n * This component provides a button that opens the native file selection dialog.\n * It can be used to implement the UI of a file upload feature.\n *\n * ```ts\n * const view = new FileDialogButtonView( locale );\n *\n * view.set( {\n * \tacceptedType: 'image/*',\n * \tallowMultipleFiles: true\n * \tlabel: t( 'Insert image' ),\n * \ticon: imageIcon,\n * \ttooltip: true\n * } );\n *\n * view.on( 'done', ( evt, files ) => {\n * \tfor ( const file of Array.from( files ) ) {\n * \t\tconsole.log( 'Selected file', file );\n * \t}\n * } );\n * ```\n */ class FileDialogButtonView extends /* #__PURE__ */ FileDialogViewMixin(ButtonView) {\n}\n/**\n * The file dialog button view used in a lists.\n *\n * This component provides a button that opens the native file selection dialog.\n * It can be used to implement the UI of a file upload feature.\n *\n* ```ts\n * const view = new FileDialogListItemButtonView( locale );\n *\n * view.set( {\n * \tacceptedType: 'image/*',\n * \tallowMultipleFiles: true\n * \tlabel: t( 'Insert image' ),\n * \ticon: imageIcon,\n * \ttooltip: true\n * } );\n *\n * view.on( 'done', ( evt, files ) => {\n * \tfor ( const file of Array.from( files ) ) {\n * \t\tconsole.log( 'Selected file', file );\n * \t}\n * } );\n * ```\n */ class FileDialogListItemButtonView extends /* #__PURE__ */ FileDialogViewMixin(ListItemButtonView) {\n}\n/**\n * Mixin function that enhances a base button view class with file dialog functionality. It is used\n * to create a button view class that opens the native select file dialog when clicked.\n *\n * The enhanced view includes a button and a hidden file input. When the button is clicked, the file dialog is opened.\n * The mixin adds properties and methods to the base class to handle the file selection.\n *\n * @param view The base class to be enhanced with file dialog functionality.\n * @returns A new class that extends the base class and includes the file dialog functionality.\n */ function FileDialogViewMixin(view) {\n    class FileDialogView extends view {\n        /**\n\t\t * The button view of the component.\n\t\t *\n\t\t * @deprecated\n\t\t */ buttonView;\n        /**\n\t\t * A hidden `<input>` view used to execute file dialog.\n\t\t */ _fileInputView;\n        /**\n\t\t * @inheritDoc\n\t\t */ constructor(...args){\n            super(...args);\n            // For backward compatibility.\n            this.buttonView = this;\n            this._fileInputView = new FileInputView(this.locale);\n            this._fileInputView.bind('acceptedType').to(this);\n            this._fileInputView.bind('allowMultipleFiles').to(this);\n            this._fileInputView.delegate('done').to(this);\n            this.on('execute', ()=>{\n                this._fileInputView.open();\n            });\n            this.extendTemplate({\n                attributes: {\n                    class: 'ck-file-dialog-button'\n                }\n            });\n        }\n        /**\n\t\t * @inheritDoc\n\t\t */ render() {\n            super.render();\n            this.children.add(this._fileInputView);\n        }\n    }\n    return FileDialogView;\n}\n/**\n * The hidden file input view class.\n */ class FileInputView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.set('acceptedType', undefined);\n        this.set('allowMultipleFiles', false);\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'input',\n            attributes: {\n                class: [\n                    'ck-hidden'\n                ],\n                type: 'file',\n                tabindex: '-1',\n                accept: bind.to('acceptedType'),\n                multiple: bind.to('allowMultipleFiles')\n            },\n            on: {\n                // Removing from code coverage since we cannot programmatically set input element files.\n                change: bind.to(/* istanbul ignore next -- @preserve */ ()=>{\n                    if (this.element && this.element.files && this.element.files.length) {\n                        this.fire('done', this.element.files);\n                    }\n                    this.element.value = '';\n                })\n            }\n        });\n    }\n    /**\n\t * Opens file dialog.\n\t */ open() {\n        this.element.click();\n    }\n}\n\nvar dropdownArrowIcon = \"<svg viewBox=\\\"0 0 10 10\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M.941 4.523a.75.75 0 1 1 1.06-1.06l3.006 3.005 3.005-3.005a.75.75 0 1 1 1.06 1.06l-3.549 3.55a.75.75 0 0 1-1.168-.136L.941 4.523z\\\"/></svg>\";\n\n/**\n * A collapsible UI component. Consists of a labeled button and a container which can be collapsed\n * by clicking the button. The collapsible container can be a host to other UI views.\n *\n * @internal\n */ class CollapsibleView extends View {\n    /**\n\t * The main button that, when clicked, collapses or expands the container with {@link #children}.\n\t */ buttonView;\n    /**\n\t * A collection of the child views that can be collapsed by clicking the {@link #buttonView}.\n\t */ children;\n    /**\n\t * Creates an instance of the collapsible view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param childViews An optional array of initial child views to be inserted into the collapsible.\n\t */ constructor(locale, childViews){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('isCollapsed', false);\n        this.set('label', '');\n        this.buttonView = this._createButtonView();\n        this.children = this.createCollection();\n        this.set('_collapsibleAriaLabelUid', undefined);\n        if (childViews) {\n            this.children.addMany(childViews);\n        }\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-collapsible',\n                    bind.if('isCollapsed', 'ck-collapsible_collapsed')\n                ]\n            },\n            children: [\n                this.buttonView,\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-collapsible__children'\n                        ],\n                        role: 'region',\n                        hidden: bind.if('isCollapsed', 'hidden'),\n                        'aria-labelledby': bind.to('_collapsibleAriaLabelUid')\n                    },\n                    children: this.children\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this._collapsibleAriaLabelUid = this.buttonView.labelView.element.id;\n    }\n    /**\n\t * Focuses the first focusable.\n\t */ focus() {\n        this.buttonView.focus();\n    }\n    /**\n\t * Creates the main {@link #buttonView} of the collapsible.\n\t */ _createButtonView() {\n        const buttonView = new ButtonView(this.locale);\n        const bind = buttonView.bindTemplate;\n        buttonView.set({\n            withText: true,\n            icon: dropdownArrowIcon\n        });\n        buttonView.extendTemplate({\n            attributes: {\n                'aria-expanded': bind.to('isOn', (value)=>String(value))\n            }\n        });\n        buttonView.bind('label').to(this);\n        buttonView.bind('isOn').to(this, 'isCollapsed', (isCollapsed)=>!isCollapsed);\n        buttonView.on('execute', ()=>{\n            this.isCollapsed = !this.isCollapsed;\n        });\n        return buttonView;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/colorgrid/utils\n */ /**\n * Returns color configuration options as defined in `editor.config.(fontColor|fontBackgroundColor).colors` or\n * `editor.config.table.(tableProperties|tableCellProperties).(background|border).colors\n * but processed to account for editor localization in the correct language.\n *\n * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t}\n * when the user configuration is defined because the editor does not exist yet.\n *\n * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n */ function getLocalizedColorOptions(locale, options) {\n    const t = locale.t;\n    const localizedColorNames = {\n        Black: t('Black'),\n        'Dim grey': t('Dim grey'),\n        Grey: t('Grey'),\n        'Light grey': t('Light grey'),\n        White: t('White'),\n        Red: t('Red'),\n        Orange: t('Orange'),\n        Yellow: t('Yellow'),\n        'Light green': t('Light green'),\n        Green: t('Green'),\n        Aquamarine: t('Aquamarine'),\n        Turquoise: t('Turquoise'),\n        'Light blue': t('Light blue'),\n        Blue: t('Blue'),\n        Purple: t('Purple')\n    };\n    return options.map((colorOption)=>{\n        const label = localizedColorNames[colorOption.label];\n        if (label && label != colorOption.label) {\n            colorOption.label = label;\n        }\n        return colorOption;\n    });\n}\n/**\n * Creates a unified color definition object from color configuration options.\n * The object contains the information necessary to both render the UI and initialize the conversion.\n */ function normalizeColorOptions(options) {\n    return options.map(normalizeSingleColorDefinition).filter((option)=>!!option);\n}\n/**\n * Creates a normalized color definition from the user-defined configuration.\n * The \"normalization\" means it will create full\n * {@link module:ui/colorgrid/colorgridview~ColorDefinition `ColorDefinition-like`}\n * object for string values, and add a `view` property, for each definition.\n */ function normalizeSingleColorDefinition(color) {\n    if (typeof color === 'string') {\n        return {\n            model: color,\n            label: color,\n            hasBorder: false,\n            view: {\n                name: 'span',\n                styles: {\n                    color\n                }\n            }\n        };\n    } else {\n        return {\n            model: color.color,\n            label: color.label || color.color,\n            hasBorder: color.hasBorder === undefined ? false : color.hasBorder,\n            view: {\n                name: 'span',\n                styles: {\n                    color: `${color.color}`\n                }\n            }\n        };\n    }\n}\n\nvar checkIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path class=\\\"ck-icon__fill\\\" d=\\\"M16.935 5.328a2 2 0 0 1 0 2.829l-7.778 7.778a2 2 0 0 1-2.829 0L3.5 13.107a1.999 1.999 0 1 1 2.828-2.829l.707.707a1 1 0 0 0 1.414 0l5.658-5.657a2 2 0 0 1 2.828 0z\\\"/><path d=\\\"M14.814 6.035 8.448 12.4a1 1 0 0 1-1.414 0l-1.413-1.415A1 1 0 1 0 4.207 12.4l2.829 2.829a1 1 0 0 0 1.414 0l7.778-7.778a1 1 0 1 0-1.414-1.415z\\\"/></svg>\";\n\n/**\n * This class represents a single color tile in the {@link module:ui/colorgrid/colorgridview~ColorGridView}.\n */ class ColorTileView extends ButtonView {\n    constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('color', undefined);\n        this.set('hasBorder', false);\n        this.icon = checkIcon;\n        this.extendTemplate({\n            attributes: {\n                style: {\n                    // https://github.com/ckeditor/ckeditor5/issues/14907\n                    backgroundColor: bind.to('color', (color)=>env.isMediaForcedColors ? null : color)\n                },\n                class: [\n                    'ck',\n                    'ck-color-grid__tile',\n                    bind.if('hasBorder', 'ck-color-selector__color-tile_bordered')\n                ]\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.iconView.fillColor = 'hsl(0, 0%, 100%)';\n    }\n}\n\n/**\n * A grid of {@link module:ui/colorgrid/colortileview~ColorTileView color tiles}.\n */ class ColorGridView extends View {\n    /**\n\t * A number of columns for the tiles grid.\n\t */ columns;\n    /**\n\t * Collection of the child tile views.\n\t */ items;\n    /**\n\t * Tracks information about DOM focus in the grid.\n\t */ focusTracker;\n    /**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * Creates an instance of a color grid containing {@link module:ui/colorgrid/colortileview~ColorTileView tiles}.\n\t *\n\t * @fires execute\n\t * @param locale The localization services instance.\n\t * @param options Component configuration\n\t * @param options.colorDefinitions Array with definitions\n\t * required to create the {@link module:ui/colorgrid/colortileview~ColorTileView tiles}.\n\t * @param options.columns A number of columns to display the tiles.\n\t */ constructor(locale, options){\n        super(locale);\n        const colorDefinitions = options && options.colorDefinitions ? options.colorDefinitions : [];\n        this.columns = options && options.columns ? options.columns : 5;\n        const viewStyleAttribute = {\n            gridTemplateColumns: `repeat( ${this.columns}, 1fr)`\n        };\n        this.set('selectedColor', undefined);\n        this.items = this.createCollection();\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.items.on('add', (evt, colorTile)=>{\n            colorTile.isOn = colorTile.color === this.selectedColor;\n        });\n        colorDefinitions.forEach((color)=>{\n            const colorTile = new ColorTileView();\n            colorTile.set({\n                color: color.color,\n                label: color.label,\n                tooltip: true,\n                hasBorder: color.options.hasBorder\n            });\n            colorTile.on('execute', ()=>{\n                this.fire('execute', {\n                    value: color.color,\n                    hasBorder: color.options.hasBorder,\n                    label: color.label\n                });\n            });\n            this.items.add(colorTile);\n        });\n        this.setTemplate({\n            tag: 'div',\n            children: this.items,\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-color-grid'\n                ],\n                style: viewStyleAttribute\n            }\n        });\n        this.on('change:selectedColor', (evt, name, selectedColor)=>{\n            for (const item of this.items){\n                item.isOn = item.color === selectedColor;\n            }\n        });\n    }\n    /**\n\t * Focuses the first focusable in {@link #items}.\n\t */ focus() {\n        if (this.items.length) {\n            this.items.first.focus();\n        }\n    }\n    /**\n\t * Focuses the last focusable in {@link #items}.\n\t */ focusLast() {\n        if (this.items.length) {\n            this.items.last.focus();\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        // Items added before rendering should be known to the #focusTracker.\n        for (const item of this.items){\n            this.focusTracker.add(item.element);\n        }\n        this.items.on('add', (evt, item)=>{\n            this.focusTracker.add(item.element);\n        });\n        this.items.on('remove', (evt, item)=>{\n            this.focusTracker.remove(item.element);\n        });\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n        addKeyboardHandlingForGrid({\n            keystrokeHandler: this.keystrokes,\n            focusTracker: this.focusTracker,\n            gridItems: this.items,\n            numberOfColumns: this.columns,\n            uiLanguageDirection: this.locale && this.locale.uiLanguageDirection\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/colorpicker/utils\n */ /* eslint-disable @typescript-eslint/ban-ts-comment */ // There are no available types for 'color-parse' module.\n// @ts-ignore\n/**\n * Parses and converts the color string to requested format. Handles variety of color spaces\n * like `hsl`, `hex` or `rgb`.\n *\n * @param color\n * @returns A color string.\n */ function convertColor(color, outputFormat) {\n    if (!color) {\n        return '';\n    }\n    const colorObject = parseColorString(color);\n    if (!colorObject) {\n        return '';\n    }\n    if (colorObject.space === outputFormat) {\n        return color;\n    }\n    if (!canConvertParsedColor(colorObject)) {\n        return '';\n    }\n    const fromColorSpace = convert[colorObject.space];\n    const toColorSpace = fromColorSpace[outputFormat];\n    if (!toColorSpace) {\n        return '';\n    }\n    const convertedColorChannels = toColorSpace(colorObject.space === 'hex' ? colorObject.hexValue : colorObject.values);\n    return formatColorOutput(convertedColorChannels, outputFormat);\n}\n/**\n * Converts a color string to hex format.\n *\n * @param color\n * @returns A color string.\n */ function convertToHex(color) {\n    if (!color) {\n        return '';\n    }\n    const colorObject = parseColorString(color);\n    if (!colorObject) {\n        return '#000';\n    }\n    if (colorObject.space === 'hex') {\n        return colorObject.hexValue;\n    }\n    return convertColor(color, 'hex');\n}\n/**\n * Registers the custom element in the\n * [CustomElementsRegistry](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry).\n */ function registerCustomElement(elementName, constructor) {\n    if (customElements.get(elementName) === undefined) {\n        customElements.define(elementName, constructor);\n    }\n}\n/**\n * Formats the passed color channels according to the requested format.\n *\n * @param values\n * @param format\n * @returns A color string.\n */ function formatColorOutput(values, format) {\n    switch(format){\n        case 'hex':\n            return `#${values}`;\n        case 'rgb':\n            return `rgb( ${values[0]}, ${values[1]}, ${values[2]} )`;\n        case 'hsl':\n            return `hsl( ${values[0]}, ${values[1]}%, ${values[2]}% )`;\n        case 'hwb':\n            return `hwb( ${values[0]}, ${values[1]}, ${values[2]} )`;\n        case 'lab':\n            return `lab( ${values[0]}% ${values[1]} ${values[2]} )`;\n        case 'lch':\n            return `lch( ${values[0]}% ${values[1]} ${values[2]} )`;\n        default:\n            return '';\n    }\n}\nfunction parseColorString(colorString) {\n    // Parser library treats `hex` format as belonging to `rgb` space | which messes up further conversion.\n    // Let's parse such strings on our own.\n    if (colorString.startsWith('#')) {\n        const parsedHex = parse(colorString);\n        return {\n            space: 'hex',\n            values: parsedHex.values,\n            hexValue: colorString,\n            alpha: parsedHex.alpha\n        };\n    }\n    const parsed = parse(colorString);\n    if (!parsed.space) {\n        return null;\n    }\n    return parsed;\n}\nfunction canConvertParsedColor(parsedColor) {\n    return Object.keys(convert).includes(parsedColor.space);\n}\n\n/**\n * The labeled field view class. It can be used to enhance any view with the following features:\n *\n * * a label,\n * * (optional) an error message,\n * * (optional) an info (status) text,\n *\n * all bound logically by proper DOM attributes for UX and accessibility.  It also provides an interface\n * (e.g. observable properties) that allows controlling those additional features.\n *\n * The constructor of this class requires a callback that returns a view to be labeled. The callback\n * is called with unique ids that allow binding of DOM properties:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, ( labeledFieldView, viewUid, statusUid ) => {\n * \tconst inputView = new InputTextView( labeledFieldView.locale );\n *\n * \tinputView.set( {\n * \t\tid: viewUid,\n * \t\tariaDescribedById: statusUid\n * \t} );\n *\n * \tinputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );\n * \tinputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );\n *\n * \treturn inputView;\n * } );\n *\n * labeledInputView.label = 'User name';\n * labeledInputView.infoText = 'Full name like for instance, John Doe.';\n * labeledInputView.render();\n *\n * document.body.append( labeledInputView.element );\n * ```\n *\n * See {@link module:ui/labeledfield/utils} to discover ready–to–use labeled input helpers for common\n * UI components.\n */ class LabeledFieldView extends View {\n    /**\n\t * The field view that gets labeled.\n\t */ fieldView;\n    /**\n\t * The label view instance that describes the entire view.\n\t */ labelView;\n    /**\n\t * The status view for the {@link #fieldView}. It displays {@link #errorText} and\n\t * {@link #infoText}.\n\t */ statusView;\n    /**\n\t * A collection of children of the internal wrapper element. Allows inserting additional DOM elements (views) next to\n\t * the {@link #fieldView} for easy styling (e.g. positioning).\n\t *\n\t * By default, the collection contains {@link #fieldView} and {@link #labelView}.\n\t */ fieldWrapperChildren;\n    /**\n\t * Creates an instance of the labeled field view class using a provided creator function\n\t * that provides the view to be labeled.\n\t *\n\t * @param locale The locale instance.\n\t * @param viewCreator A function that returns a {@link module:ui/view~View}\n\t * that will be labeled. The following arguments are passed to the creator function:\n\t *\n\t * * an instance of the `LabeledFieldView` to allow binding observable properties,\n\t * * an UID string that connects the {@link #labelView label} and the labeled field view in DOM,\n\t * * an UID string that connects the {@link #statusView status} and the labeled field view in DOM.\n\t */ constructor(locale, viewCreator){\n        super(locale);\n        const viewUid = `ck-labeled-field-view-${uid()}`;\n        const statusUid = `ck-labeled-field-view-status-${uid()}`;\n        this.fieldView = viewCreator(this, viewUid, statusUid);\n        this.set('label', undefined);\n        this.set('isEnabled', true);\n        this.set('isEmpty', true);\n        this.set('isFocused', false);\n        this.set('errorText', null);\n        this.set('infoText', null);\n        this.set('class', undefined);\n        this.set('placeholder', undefined);\n        this.labelView = this._createLabelView(viewUid);\n        this.statusView = this._createStatusView(statusUid);\n        this.fieldWrapperChildren = this.createCollection([\n            this.fieldView,\n            this.labelView\n        ]);\n        this.bind('_statusText').to(this, 'errorText', this, 'infoText', (errorText, infoText)=>errorText || infoText);\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-labeled-field-view',\n                    bind.to('class'),\n                    bind.if('isEnabled', 'ck-disabled', (value)=>!value),\n                    bind.if('isEmpty', 'ck-labeled-field-view_empty'),\n                    bind.if('isFocused', 'ck-labeled-field-view_focused'),\n                    bind.if('placeholder', 'ck-labeled-field-view_placeholder'),\n                    bind.if('errorText', 'ck-error')\n                ]\n            },\n            children: [\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-labeled-field-view__input-wrapper'\n                        ]\n                    },\n                    children: this.fieldWrapperChildren\n                },\n                this.statusView\n            ]\n        });\n    }\n    /**\n\t * Creates label view class instance and bind with view.\n\t *\n\t * @param id Unique id to set as labelView#for attribute.\n\t */ _createLabelView(id) {\n        const labelView = new LabelView(this.locale);\n        labelView.for = id;\n        labelView.bind('text').to(this, 'label');\n        return labelView;\n    }\n    /**\n\t * Creates the status view instance. It displays {@link #errorText} and {@link #infoText}\n\t * next to the {@link #fieldView}. See {@link #_statusText}.\n\t *\n\t * @param statusUid Unique id of the status, shared with the {@link #fieldView view's}\n\t * `aria-describedby` attribute.\n\t */ _createStatusView(statusUid) {\n        const statusView = new View(this.locale);\n        const bind = this.bindTemplate;\n        statusView.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-labeled-field-view__status',\n                    bind.if('errorText', 'ck-labeled-field-view__status_error'),\n                    bind.if('_statusText', 'ck-hidden', (value)=>!value)\n                ],\n                id: statusUid,\n                role: bind.if('errorText', 'alert')\n            },\n            children: [\n                {\n                    text: bind.to('_statusText')\n                }\n            ]\n        });\n        return statusView;\n    }\n    /**\n\t * Focuses the {@link #fieldView}.\n\t */ focus(direction) {\n        this.fieldView.focus(direction);\n    }\n}\n\n/**\n * The base input view class.\n */ class InputBase extends View {\n    /**\n\t * Stores information about the editor UI focus and propagates it so various plugins and components\n\t * are unified as a focus group.\n\t */ focusTracker;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.set('value', undefined);\n        this.set('id', undefined);\n        this.set('placeholder', undefined);\n        this.set('tabIndex', undefined);\n        this.set('isReadOnly', false);\n        this.set('hasError', false);\n        this.set('ariaDescribedById', undefined);\n        this.set('ariaLabel', undefined);\n        this.focusTracker = new FocusTracker();\n        this.bind('isFocused').to(this.focusTracker);\n        this.set('isEmpty', true);\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'input',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-input',\n                    bind.if('isFocused', 'ck-input_focused'),\n                    bind.if('isEmpty', 'ck-input-text_empty'),\n                    bind.if('hasError', 'ck-error')\n                ],\n                id: bind.to('id'),\n                placeholder: bind.to('placeholder'),\n                tabindex: bind.to('tabIndex'),\n                readonly: bind.to('isReadOnly'),\n                'aria-invalid': bind.if('hasError', true),\n                'aria-describedby': bind.to('ariaDescribedById'),\n                'aria-label': bind.to('ariaLabel')\n            },\n            on: {\n                input: bind.to((...args)=>{\n                    this.fire('input', ...args);\n                    this._updateIsEmpty();\n                }),\n                change: bind.to(this._updateIsEmpty.bind(this))\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.focusTracker.add(this.element);\n        this._setDomElementValue(this.value);\n        this._updateIsEmpty();\n        // Bind `this.value` to the DOM element's value.\n        // We cannot use `value` DOM attribute because removing it on Edge does not clear the DOM element's value property.\n        this.on('change:value', (evt, name, value)=>{\n            this._setDomElementValue(value);\n            this._updateIsEmpty();\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n    }\n    /**\n\t * Moves the focus to the input and selects the value.\n\t */ select() {\n        this.element.select();\n    }\n    /**\n\t * Focuses the input.\n\t */ focus() {\n        this.element.focus();\n    }\n    /**\n\t * Resets the value of the input\n\t */ reset() {\n        this.value = this.element.value = '';\n        this._updateIsEmpty();\n    }\n    /**\n\t * Updates the {@link #isEmpty} property value on demand.\n\t */ _updateIsEmpty() {\n        this.isEmpty = isInputElementEmpty(this.element);\n    }\n    /**\n\t * Sets the `value` property of the {@link #element DOM element} on demand.\n\t */ _setDomElementValue(value) {\n        this.element.value = !value && value !== 0 ? '' : value;\n    }\n}\nfunction isInputElementEmpty(domElement) {\n    return !domElement.value;\n}\n\n/**\n * The input view class.\n */ class InputView extends InputBase {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.set('inputMode', 'text');\n        const bind = this.bindTemplate;\n        this.extendTemplate({\n            attributes: {\n                inputmode: bind.to('inputMode')\n            }\n        });\n    }\n}\n\n/**\n * The text input view class.\n */ class InputTextView extends InputView {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.extendTemplate({\n            attributes: {\n                type: 'text',\n                class: [\n                    'ck-input-text'\n                ]\n            }\n        });\n    }\n}\n\n/**\n * The number input view class.\n */ class InputNumberView extends InputView {\n    /**\n\t * Creates an instance of the input number view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options The options of the input.\n\t * @param options.min The value of the `min` DOM attribute (the lowest accepted value).\n\t * @param options.max The value of the `max` DOM attribute (the highest accepted value).\n\t * @param options.step The value of the `step` DOM attribute.\n\t */ constructor(locale, { min, max, step } = {}){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('min', min);\n        this.set('max', max);\n        this.set('step', step);\n        this.extendTemplate({\n            attributes: {\n                type: 'number',\n                class: [\n                    'ck-input-number'\n                ],\n                min: bind.to('min'),\n                max: bind.to('max'),\n                step: bind.to('step')\n            }\n        });\n    }\n}\n\n/**\n * The textarea view class.\n *\n * ```ts\n * const textareaView = new TextareaView();\n *\n * textareaView.minRows = 2;\n * textareaView.maxRows = 10;\n *\n * textareaView.render();\n *\n * document.body.append( textareaView.element );\n * ```\n */ class TextareaView extends InputBase {\n    /**\n\t * An instance of the resize observer used to detect when the view is visible or not and update\n\t * its height if any changes that affect it were made while it was invisible.\n\t *\n\t * **Note:** Created in {@link #render}.\n\t */ _resizeObserver;\n    /**\n\t * A flag that indicates whether the {@link #_updateAutoGrowHeight} method should be called when the view becomes\n\t * visible again. See {@link #_resizeObserver}.\n\t */ _isUpdateAutoGrowHeightPending = false;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const toPx = toUnit('px');\n        this.set('minRows', 2);\n        this.set('maxRows', 5);\n        this.set('_height', null);\n        this.set('resize', 'none');\n        this._resizeObserver = null;\n        this.on('change:minRows', this._validateMinMaxRows.bind(this));\n        this.on('change:maxRows', this._validateMinMaxRows.bind(this));\n        const bind = this.bindTemplate;\n        this.template.tag = 'textarea';\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-textarea'\n                ],\n                style: {\n                    height: bind.to('_height', (height)=>height ? toPx(height) : null),\n                    resize: bind.to('resize')\n                },\n                rows: bind.to('minRows')\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        let wasVisible = false;\n        this.on('input', ()=>{\n            this._updateAutoGrowHeight(true);\n            this.fire('update');\n        });\n        this.on('change:value', ()=>{\n            // The content needs to be updated by the browser after the value is changed. It takes a few ms.\n            global.window.requestAnimationFrame(()=>{\n                if (!isVisible(this.element)) {\n                    this._isUpdateAutoGrowHeightPending = true;\n                    return;\n                }\n                this._updateAutoGrowHeight();\n                this.fire('update');\n            });\n        });\n        // It may occur that the Textarea size needs to be updated (e.g. because it's content was changed)\n        // when it is not visible or detached from DOM.\n        // In such case, we need to detect the moment when it becomes visible again and update its height then.\n        // We're using ResizeObserver for that as it is the most reliable way to detect when the element becomes visible.\n        // IntersectionObserver didn't work well with the absolute positioned containers.\n        this._resizeObserver = new ResizeObserver(this.element, (evt)=>{\n            const isVisible = !!evt.contentRect.width && !!evt.contentRect.height;\n            if (!wasVisible && isVisible && this._isUpdateAutoGrowHeightPending) {\n                // We're wrapping the auto-grow logic in RAF because otherwise there is an error thrown\n                // by the browser about recursive calls to the ResizeObserver. It used to happen in unit\n                // tests only, though. Since there is no risk of infinite loop here, it can stay here.\n                global.window.requestAnimationFrame(()=>{\n                    this._updateAutoGrowHeight();\n                    this.fire('update');\n                });\n            }\n            wasVisible = isVisible;\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        if (this._resizeObserver) {\n            this._resizeObserver.destroy();\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ reset() {\n        super.reset();\n        this._updateAutoGrowHeight();\n        this.fire('update');\n    }\n    /**\n\t * Updates the {@link #_height} of the view depending on {@link #minRows}, {@link #maxRows}, and the current content size.\n\t *\n\t * **Note**: This method overrides manual resize done by the user using a handle. It's a known bug.\n\t */ _updateAutoGrowHeight(shouldScroll) {\n        const viewElement = this.element;\n        if (!viewElement.offsetParent) {\n            this._isUpdateAutoGrowHeightPending = true;\n            return;\n        }\n        this._isUpdateAutoGrowHeightPending = false;\n        const singleLineContentClone = getTextareaElementClone(viewElement, '1');\n        const fullTextValueClone = getTextareaElementClone(viewElement, viewElement.value);\n        const singleLineContentStyles = singleLineContentClone.ownerDocument.defaultView.getComputedStyle(singleLineContentClone);\n        const verticalPaddings = parseFloat(singleLineContentStyles.paddingTop) + parseFloat(singleLineContentStyles.paddingBottom);\n        const borders = getBorderWidths(singleLineContentClone);\n        const lineHeight = parseFloat(singleLineContentStyles.lineHeight);\n        const verticalBorder = borders.top + borders.bottom;\n        const singleLineAreaDefaultHeight = new Rect(singleLineContentClone).height;\n        const numberOfLines = Math.round((fullTextValueClone.scrollHeight - verticalPaddings) / lineHeight);\n        const maxHeight = this.maxRows * lineHeight + verticalPaddings + verticalBorder;\n        // There's a --ck-ui-component-min-height CSS custom property that enforces min height of the component.\n        // This min-height is relevant only when there's one line of text. Other than that, we can rely on line-height.\n        const minHeight = numberOfLines === 1 ? singleLineAreaDefaultHeight : this.minRows * lineHeight + verticalPaddings + verticalBorder;\n        // The size of textarea is controlled by height style instead of rows attribute because event though it is\n        // a more complex solution, it is immune to the layout textarea has been rendered in (gird, flex).\n        this._height = Math.min(Math.max(Math.max(numberOfLines, this.minRows) * lineHeight + verticalPaddings + verticalBorder, minHeight), maxHeight);\n        if (shouldScroll) {\n            viewElement.scrollTop = viewElement.scrollHeight;\n        }\n        singleLineContentClone.remove();\n        fullTextValueClone.remove();\n    }\n    /**\n\t * Validates the {@link #minRows} and {@link #maxRows} properties and warns in the console if the configuration is incorrect.\n\t */ _validateMinMaxRows() {\n        if (this.minRows > this.maxRows) {\n            /**\n\t\t\t * The minimum number of rows is greater than the maximum number of rows.\n\t\t\t *\n\t\t\t * @error ui-textarea-view-min-rows-greater-than-max-rows\n\t\t\t * @param textareaView The misconfigured textarea view instance.\n\t\t\t * @param minRows The value of `minRows` property.\n\t\t\t * @param maxRows The value of `maxRows` property.\n\t\t\t */ throw new CKEditorError('ui-textarea-view-min-rows-greater-than-max-rows', {\n                textareaView: this,\n                minRows: this.minRows,\n                maxRows: this.maxRows\n            });\n        }\n    }\n}\nfunction getTextareaElementClone(element, value) {\n    const clone = element.cloneNode();\n    clone.style.position = 'absolute';\n    clone.style.top = '-99999px';\n    clone.style.left = '-99999px';\n    clone.style.height = 'auto';\n    clone.style.overflow = 'hidden';\n    clone.style.width = element.ownerDocument.defaultView.getComputedStyle(element).width;\n    clone.tabIndex = -1;\n    clone.rows = 1;\n    clone.value = value;\n    element.parentNode.insertBefore(clone, element);\n    return clone;\n}\n\n/**\n * The dropdown panel view class.\n *\n * See {@link module:ui/dropdown/dropdownview~DropdownView} to learn about the common usage.\n */ class DropdownPanelView extends View {\n    /**\n\t * Collection of the child views in this panel.\n\t *\n\t * A common child type is the {@link module:ui/list/listview~ListView} and {@link module:ui/toolbar/toolbarview~ToolbarView}.\n\t * See {@link module:ui/dropdown/utils~addListToDropdown} and\n\t * {@link module:ui/dropdown/utils~addToolbarToDropdown} to learn more about child views of dropdowns.\n\t */ children;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('isVisible', false);\n        this.set('position', 'se');\n        this.children = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-reset',\n                    'ck-dropdown__panel',\n                    bind.to('position', (value)=>`ck-dropdown__panel_${value}`),\n                    bind.if('isVisible', 'ck-dropdown__panel-visible')\n                ],\n                tabindex: '-1'\n            },\n            children: this.children,\n            on: {\n                // Drag and drop in the panel should not break the selection in the editor.\n                // https://github.com/ckeditor/ckeditor5-ui/issues/228\n                selectstart: bind.to((evt)=>{\n                    if (evt.target.tagName.toLocaleLowerCase() === 'input') {\n                        return;\n                    }\n                    evt.preventDefault();\n                })\n            }\n        });\n    }\n    /**\n\t * Focuses the first view in the {@link #children} collection.\n\t *\n\t * See also {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable}.\n\t */ focus() {\n        if (this.children.length) {\n            const firstChild = this.children.first;\n            if (typeof firstChild.focus === 'function') {\n                firstChild.focus();\n            } else {\n                /**\n\t\t\t\t * The child view of a dropdown could not be focused because it is missing the `focus()` method.\n\t\t\t\t *\n\t\t\t\t * This warning appears when a dropdown {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open} and it\n\t\t\t\t * attempts to focus the {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#children first child} of its panel\n\t\t\t\t * but the child does not implement the\n\t\t\t\t * {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable focusable interface}.\n\t\t\t\t *\n\t\t\t\t * Focusing the content of a dropdown on open greatly improves the accessibility. Please make sure the view instance\n\t\t\t\t * provides the `focus()` method for the best user experience.\n\t\t\t\t *\n\t\t\t\t * @error ui-dropdown-panel-focus-child-missing-focus\n\t\t\t\t * @param childView\n\t\t\t\t * @param dropdownPanel\n\t\t\t\t */ logWarning('ui-dropdown-panel-focus-child-missing-focus', {\n                    childView: this.children.first,\n                    dropdownPanel: this\n                });\n            }\n        }\n    }\n    /**\n\t * Focuses the view element or last item in view collection on opening dropdown's panel.\n\t *\n\t * See also {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable}.\n\t */ focusLast() {\n        if (this.children.length) {\n            const lastChild = this.children.last;\n            if (typeof lastChild.focusLast === 'function') {\n                lastChild.focusLast();\n            } else {\n                lastChild.focus();\n            }\n        }\n    }\n}\n\n/**\n * The dropdown view class. It manages the dropdown button and dropdown panel.\n *\n * In most cases, the easiest way to create a dropdown is by using the {@link module:ui/dropdown/utils~createDropdown}\n * util:\n *\n * ```ts\n * const dropdown = createDropdown( locale );\n *\n * // Configure dropdown's button properties:\n * dropdown.buttonView.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.render();\n *\n * dropdown.panelView.element.textContent = 'Content of the panel';\n *\n * // Will render a dropdown with a panel containing a \"Content of the panel\" text.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * If you want to add a richer content to the dropdown panel, you can use the {@link module:ui/dropdown/utils~addListToDropdown}\n * and {@link module:ui/dropdown/utils~addToolbarToDropdown} helpers. See more examples in\n * {@link module:ui/dropdown/utils~createDropdown} documentation.\n *\n * If you want to create a completely custom dropdown, then you can compose it manually:\n *\n * ```ts\n * const button = new DropdownButtonView( locale );\n * const panel = new DropdownPanelView( locale );\n * const dropdown = new DropdownView( locale, button, panel );\n *\n * button.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.render();\n *\n * panel.element.textContent = 'Content of the panel';\n *\n * // Will render a dropdown with a panel containing a \"Content of the panel\" text.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * However, dropdown created this way will contain little behavior. You will need to implement handlers for actions\n * such as {@link module:ui/bindings/clickoutsidehandler~clickOutsideHandler clicking outside an open dropdown}\n * (which should close it) and support for arrow keys inside the panel. Therefore, unless you really know what\n * you do and you really need to do it, it is recommended to use the {@link module:ui/dropdown/utils~createDropdown} helper.\n */ class DropdownView extends View {\n    /**\n\t * Button of the dropdown view. Clicking the button opens the {@link #panelView}.\n\t */ buttonView;\n    /**\n\t * Panel of the dropdown. It opens when the {@link #buttonView} is\n\t * {@link module:ui/button/button~Button#event:execute executed} (i.e. clicked).\n\t *\n\t * Child views can be added to the panel's `children` collection:\n\t *\n\t * ```ts\n\t * dropdown.panelView.children.add( childView );\n\t * ```\n\t *\n\t * See {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#children} and\n\t * {@link module:ui/viewcollection~ViewCollection#add}.\n\t */ panelView;\n    /**\n\t * Tracks information about the DOM focus in the dropdown.\n\t */ focusTracker;\n    /**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the dropdown:\n\t *\n\t * * <kbd>▼</kbd> opens the dropdown,\n\t * * <kbd>◀</kbd> and <kbd>Esc</kbd> closes the dropdown.\n\t */ keystrokes;\n    /**\n\t * A child {@link module:ui/list/listview~ListView list view} of the dropdown located\n\t * in its {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t *\n\t * **Note**: Only supported when dropdown has list view added using {@link module:ui/dropdown/utils~addListToDropdown}.\n\t */ listView;\n    /**\n\t * A child toolbar of the dropdown located in the\n\t * {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t *\n\t * **Note**: Only supported when dropdown has a toolbar added using {@link module:ui/dropdown/utils~addToolbarToDropdown}.\n\t */ toolbarView;\n    /**\n\t * A child menu component of the dropdown located\n\t * in its {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t *\n\t * **Note**: Only supported when dropdown has a menu added using {@link module:ui/dropdown/utils~addMenuToDropdown}.\n\t */ menuView;\n    /**\n\t * Creates an instance of the dropdown.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale, buttonView, panelView){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.buttonView = buttonView;\n        this.panelView = panelView;\n        this.set('isOpen', false);\n        this.set('isEnabled', true);\n        this.set('class', undefined);\n        this.set('id', undefined);\n        this.set('panelPosition', 'auto');\n        // Toggle the visibility of the panel when the dropdown becomes open.\n        this.panelView.bind('isVisible').to(this, 'isOpen');\n        this.keystrokes = new KeystrokeHandler();\n        this.focusTracker = new FocusTracker();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-dropdown',\n                    bind.to('class'),\n                    bind.if('isEnabled', 'ck-disabled', (value)=>!value)\n                ],\n                id: bind.to('id'),\n                'aria-describedby': bind.to('ariaDescribedById')\n            },\n            children: [\n                buttonView,\n                panelView\n            ]\n        });\n        buttonView.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-dropdown__button'\n                ],\n                'data-cke-tooltip-disabled': bind.to('isOpen')\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.focusTracker.add(this.buttonView.element);\n        this.focusTracker.add(this.panelView.element);\n        // Toggle the dropdown when its button has been clicked.\n        this.listenTo(this.buttonView, 'open', ()=>{\n            this.isOpen = !this.isOpen;\n        });\n        // Let the dropdown control the position of the panel. The position must\n        // be updated every time the dropdown is open.\n        this.on('change:isOpen', (evt, name, isOpen)=>{\n            if (!isOpen) {\n                return;\n            }\n            // If \"auto\", find the best position of the panel to fit into the viewport.\n            // Otherwise, simply assign the static position.\n            if (this.panelPosition === 'auto') {\n                const optimalPanelPosition = DropdownView._getOptimalPosition({\n                    element: this.panelView.element,\n                    target: this.buttonView.element,\n                    fitInViewport: true,\n                    positions: this._panelPositions\n                });\n                this.panelView.position = optimalPanelPosition ? optimalPanelPosition.name : this._panelPositions[0].name;\n            } else {\n                this.panelView.position = this.panelPosition;\n            }\n        });\n        // Listen for keystrokes coming from within #element.\n        this.keystrokes.listenTo(this.element);\n        const closeDropdown = (data, cancel)=>{\n            if (this.isOpen) {\n                this.isOpen = false;\n                cancel();\n            }\n        };\n        // Open the dropdown panel using the arrow down key, just like with return or space.\n        this.keystrokes.set('arrowdown', (data, cancel)=>{\n            // Don't open if the dropdown is disabled or already open.\n            if (this.buttonView.isEnabled && !this.isOpen) {\n                this.isOpen = true;\n                cancel();\n            }\n        });\n        // Block the right arrow key (until nested dropdowns are implemented).\n        this.keystrokes.set('arrowright', (data, cancel)=>{\n            if (this.isOpen) {\n                cancel();\n            }\n        });\n        // Close the dropdown using the arrow left/escape key.\n        this.keystrokes.set('arrowleft', closeDropdown);\n        this.keystrokes.set('esc', closeDropdown);\n    }\n    /**\n\t * Focuses the {@link #buttonView}.\n\t */ focus() {\n        this.buttonView.focus();\n    }\n    /**\n\t * Returns {@link #panelView panel} positions to be used by the\n\t * {@link module:utils/dom/position~getOptimalPosition `getOptimalPosition()`}\n\t * utility considering the direction of the language the UI of the editor is displayed in.\n\t */ get _panelPositions() {\n        const { south, north, southEast, southWest, northEast, northWest, southMiddleEast, southMiddleWest, northMiddleEast, northMiddleWest } = DropdownView.defaultPanelPositions;\n        if (this.locale.uiLanguageDirection !== 'rtl') {\n            return [\n                southEast,\n                southWest,\n                southMiddleEast,\n                southMiddleWest,\n                south,\n                northEast,\n                northWest,\n                northMiddleEast,\n                northMiddleWest,\n                north\n            ];\n        } else {\n            return [\n                southWest,\n                southEast,\n                southMiddleWest,\n                southMiddleEast,\n                south,\n                northWest,\n                northEast,\n                northMiddleWest,\n                northMiddleEast,\n                north\n            ];\n        }\n    }\n    /**\n\t * A set of positioning functions used by the dropdown view to determine\n\t * the optimal position (i.e. fitting into the browser viewport) of its\n\t * {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel} when\n\t * {@link module:ui/dropdown/dropdownview~DropdownView#panelPosition} is set to 'auto'`.\n\t *\n\t * The available positioning functions are as follow:\n\t *\n\t * **South**\n\t *\n\t * * `south`\n\t *\n\t * ```\n\t *\t\t\t[ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southEast`\n\t *\n\t * ```\n\t *\t\t[ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWest`\n\t *\n\t * ```\n\t *\t\t         [ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southMiddleEast`\n\t *\n\t * ```\n\t *\t\t  [ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southMiddleWest`\n\t *\n\t * ```\n\t *\t\t       [ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **North**\n\t *\n\t * * `north`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t    [ Button ]\n\t * ```\n\t *\n\t * * `northEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t[ Button ]\n\t * ```\n\t *\n\t * * `northWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t         [ Button ]\n\t * ```\n\t *\n\t * * `northMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t  [ Button ]\n\t * ```\n\t *\n\t * * `northMiddleWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t       [ Button ]\n\t * ```\n\t *\n\t * Positioning functions are compatible with {@link module:utils/dom/position~DomPoint}.\n\t *\n\t * The name that position function returns will be reflected in dropdown panel's class that\n\t * controls its placement. See {@link module:ui/dropdown/dropdownview~DropdownView#panelPosition}\n\t * to learn more.\n\t */ static defaultPanelPositions = {\n        south: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.bottom,\n                left: buttonRect.left - (panelRect.width - buttonRect.width) / 2,\n                name: 's'\n            };\n        },\n        southEast: (buttonRect)=>{\n            return {\n                top: buttonRect.bottom,\n                left: buttonRect.left,\n                name: 'se'\n            };\n        },\n        southWest: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.bottom,\n                left: buttonRect.left - panelRect.width + buttonRect.width,\n                name: 'sw'\n            };\n        },\n        southMiddleEast: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.bottom,\n                left: buttonRect.left - (panelRect.width - buttonRect.width) / 4,\n                name: 'sme'\n            };\n        },\n        southMiddleWest: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.bottom,\n                left: buttonRect.left - (panelRect.width - buttonRect.width) * 3 / 4,\n                name: 'smw'\n            };\n        },\n        north: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.top - panelRect.height,\n                left: buttonRect.left - (panelRect.width - buttonRect.width) / 2,\n                name: 'n'\n            };\n        },\n        northEast: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.top - panelRect.height,\n                left: buttonRect.left,\n                name: 'ne'\n            };\n        },\n        northWest: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.top - panelRect.height,\n                left: buttonRect.left - panelRect.width + buttonRect.width,\n                name: 'nw'\n            };\n        },\n        northMiddleEast: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.top - panelRect.height,\n                left: buttonRect.left - (panelRect.width - buttonRect.width) / 4,\n                name: 'nme'\n            };\n        },\n        northMiddleWest: (buttonRect, panelRect)=>{\n            return {\n                top: buttonRect.top - panelRect.height,\n                left: buttonRect.left - (panelRect.width - buttonRect.width) * 3 / 4,\n                name: 'nmw'\n            };\n        }\n    };\n    /**\n\t * A function used to calculate the optimal position for the dropdown panel.\n\t */ static _getOptimalPosition = getOptimalPosition;\n}\n\n/**\n * The default dropdown button view class.\n *\n * ```ts\n * const view = new DropdownButtonView();\n *\n * view.set( {\n * \tlabel: 'A button',\n * \tkeystroke: 'Ctrl+B',\n * \ttooltip: true\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n *\n * Also see the {@link module:ui/dropdown/utils~createDropdown `createDropdown()` util}.\n */ class DropdownButtonView extends ButtonView {\n    /**\n\t * An icon that displays arrow to indicate a dropdown button.\n\t */ arrowView;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.arrowView = this._createArrowView();\n        this.extendTemplate({\n            attributes: {\n                'aria-haspopup': true,\n                'aria-expanded': this.bindTemplate.to('isOn', (value)=>String(value))\n            }\n        });\n        // The DropdownButton interface expects the open event upon which will open the dropdown.\n        this.delegate('execute').to(this, 'open');\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.children.add(this.arrowView);\n    }\n    /**\n\t * Creates a {@link module:ui/icon/iconview~IconView} instance as {@link #arrowView}.\n\t */ _createArrowView() {\n        const arrowView = new IconView();\n        arrowView.content = dropdownArrowIcon;\n        arrowView.extendTemplate({\n            attributes: {\n                class: 'ck-dropdown__arrow'\n            }\n        });\n        return arrowView;\n    }\n}\n\n/**\n * Represents a view for a button in a dropdown menu list item.\n */ class DropdownMenuListItemButtonView extends ButtonView {\n    id;\n    constructor(locale, id, label){\n        super(locale);\n        this.id = id;\n        this.set({\n            withText: true,\n            withKeystroke: true,\n            tooltip: false,\n            role: 'menuitem',\n            label\n        });\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-dropdown-menu-list__nested-menu__item__button'\n                ]\n            }\n        });\n    }\n}\n\n/**\n * Represents a view for a dropdown menu button.\n */ class DropdownMenuButtonView extends ListItemButtonView {\n    /**\n\t * An icon that displays an arrow to indicate a direction of the menu.\n\t */ arrowView;\n    /**\n\t * Creates an instance of the dropdown menu button view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set({\n            withText: true,\n            role: 'menuitem'\n        });\n        this.arrowView = this._createArrowView();\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-dropdown-menu-list__nested-menu__button'\n                ],\n                'aria-haspopup': true,\n                'aria-expanded': this.bindTemplate.to('isOn', (value)=>String(value)),\n                'data-cke-tooltip-disabled': bind.to('isOn')\n            },\n            on: {\n                'mouseenter': bind.to('mouseenter')\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.children.add(this.arrowView);\n    }\n    /**\n\t * Creates the arrow view instance.\n\t *\n\t * @private\n\t */ _createArrowView() {\n        const arrowView = new IconView();\n        arrowView.content = dropdownArrowIcon;\n        arrowView.extendTemplate({\n            attributes: {\n                class: 'ck-dropdown-menu-list__nested-menu__button__arrow'\n            }\n        });\n        return arrowView;\n    }\n}\n\n/**\n * The list item view class.\n */ class ListItemView extends View {\n    /**\n\t * Collection of the child views inside of the list item {@link #element}.\n\t */ children;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('isVisible', true);\n        this.children = this.createCollection();\n        this.setTemplate({\n            tag: 'li',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-list__item',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ],\n                role: 'presentation'\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * Focuses the list item.\n\t */ focus() {\n        if (this.children.first) {\n            this.children.first.focus();\n        }\n    }\n}\n\n/**\n * The list separator view class.\n */ class ListSeparatorView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.setTemplate({\n            tag: 'li',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-list__separator'\n                ]\n            }\n        });\n    }\n}\n\n/**\n * The list item group view class.\n */ class ListItemGroupView extends View {\n    /**\n\t * Label of the group view. Its text is configurable using the {@link #label label attribute}.\n\t *\n\t * If a custom label view is not passed in `ListItemGroupView` constructor, the label is an instance\n\t * of {@link module:ui/label/labelview~LabelView}.\n\t */ labelView;\n    /**\n\t * Collection of the child list items inside this group.\n\t */ items;\n    /**\n\t * Collection of the child elements of the group.\n\t */ children;\n    /**\n\t * Creates an instance of the list item group view class.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param labelView The instance of the group's label. If not provided, an instance of\n\t * {@link module:ui/label/labelview~LabelView} is used.\n\t */ constructor(locale, labelView = new LabelView()){\n        super(locale);\n        const bind = this.bindTemplate;\n        const nestedList = new ListView(locale);\n        this.set({\n            label: '',\n            isVisible: true\n        });\n        this.labelView = labelView;\n        this.labelView.bind('text').to(this, 'label');\n        this.children = this.createCollection();\n        this.children.addMany([\n            this.labelView,\n            nestedList\n        ]);\n        nestedList.set({\n            role: 'group',\n            ariaLabelledBy: labelView.id\n        });\n        // Disable focus tracking and accessible navigation in the child list.\n        nestedList.focusTracker.destroy();\n        nestedList.keystrokes.destroy();\n        this.items = nestedList.items;\n        this.setTemplate({\n            tag: 'li',\n            attributes: {\n                role: 'presentation',\n                class: [\n                    'ck',\n                    'ck-list__group',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ]\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * Focuses the list item (which is not a separator).\n\t */ focus() {\n        if (this.items) {\n            const firstListItem = this.items.find((item)=>!(item instanceof ListSeparatorView));\n            if (firstListItem) {\n                firstListItem.focus();\n            }\n        }\n    }\n}\n\n/**\n * The list view class.\n */ class ListView extends View {\n    /**\n\t * The collection of focusable views in the list. It is used to determine accessible navigation\n\t * between the {@link module:ui/list/listitemview~ListItemView list items} and\n\t * {@link module:ui/list/listitemgroupview~ListItemGroupView list groups}.\n\t */ focusables;\n    /**\n\t * Collection of the child list views.\n\t */ items;\n    /**\n\t * Tracks information about DOM focus in the list.\n\t */ focusTracker;\n    /**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * Helps cycling over focusable {@link #items} in the list.\n\t */ _focusCycler;\n    /**\n\t * A cached map of {@link module:ui/list/listitemgroupview~ListItemGroupView} to `change` event listeners for their `items`.\n\t * Used for accessibility and keyboard navigation purposes.\n\t */ _listItemGroupToChangeListeners = new WeakMap();\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.focusables = new ViewCollection();\n        this.items = this.createCollection();\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this._focusCycler = new FocusCycler({\n            focusables: this.focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate list items backwards using the arrowup key.\n                focusPrevious: 'arrowup',\n                // Navigate toolbar items forwards using the arrowdown key.\n                focusNext: 'arrowdown'\n            }\n        });\n        this.set('ariaLabel', undefined);\n        this.set('ariaLabelledBy', undefined);\n        this.set('role', undefined);\n        this.setTemplate({\n            tag: 'ul',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-reset',\n                    'ck-list'\n                ],\n                role: bind.to('role'),\n                'aria-label': bind.to('ariaLabel'),\n                'aria-labelledby': bind.to('ariaLabelledBy')\n            },\n            children: this.items\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        // Items added before rendering should be known to the #focusTracker.\n        for (const item of this.items){\n            if (item instanceof ListItemGroupView) {\n                this._registerFocusableItemsGroup(item);\n            } else if (item instanceof ListItemView) {\n                this._registerFocusableListItem(item);\n            }\n        }\n        this.items.on('change', (evt, data)=>{\n            for (const removed of data.removed){\n                if (removed instanceof ListItemGroupView) {\n                    this._deregisterFocusableItemsGroup(removed);\n                } else if (removed instanceof ListItemView) {\n                    this._deregisterFocusableListItem(removed);\n                }\n            }\n            for (const added of Array.from(data.added).reverse()){\n                if (added instanceof ListItemGroupView) {\n                    this._registerFocusableItemsGroup(added, data.index);\n                } else {\n                    this._registerFocusableListItem(added, data.index);\n                }\n            }\n        });\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the first focusable in {@link #items}.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Focuses the first focusable in {@link #items}.\n\t */ focusFirst() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Focuses the last focusable in {@link #items}.\n\t */ focusLast() {\n        this._focusCycler.focusLast();\n    }\n    /**\n\t * Registers a list item view in the focus tracker.\n\t *\n\t * @param item The list item view to be registered.\n\t * @param index Index of the list item view in the {@link #items} collection. If not specified, the item will be added at the end.\n\t */ _registerFocusableListItem(item, index) {\n        this.focusTracker.add(item.element);\n        this.focusables.add(item, index);\n    }\n    /**\n\t * Removes a list item view from the focus tracker.\n\t *\n\t * @param item The list item view to be removed.\n\t */ _deregisterFocusableListItem(item) {\n        this.focusTracker.remove(item.element);\n        this.focusables.remove(item);\n    }\n    /**\n\t * Gets a callback that will be called when the `items` collection of a {@link module:ui/list/listitemgroupview~ListItemGroupView}\n\t * change.\n\t *\n\t * @param groupView The group view for which the callback will be created.\n\t * @returns The callback function to be used for the items `change` event listener in a group.\n\t */ _getOnGroupItemsChangeCallback(groupView) {\n        return (evt, data)=>{\n            for (const removed of data.removed){\n                this._deregisterFocusableListItem(removed);\n            }\n            for (const added of Array.from(data.added).reverse()){\n                this._registerFocusableListItem(added, this.items.getIndex(groupView) + data.index);\n            }\n        };\n    }\n    /**\n\t * Registers a list item group view (and its children) in the focus tracker.\n\t *\n\t * @param groupView A group view to be registered.\n\t * @param groupIndex Index of the group view in the {@link #items} collection. If not specified, the group will be added at the end.\n\t */ _registerFocusableItemsGroup(groupView, groupIndex) {\n        Array.from(groupView.items).forEach((child, childIndex)=>{\n            const registeredChildIndex = typeof groupIndex !== 'undefined' ? groupIndex + childIndex : undefined;\n            this._registerFocusableListItem(child, registeredChildIndex);\n        });\n        const groupItemsChangeCallback = this._getOnGroupItemsChangeCallback(groupView);\n        // Cache the reference to the callback in case the group is removed (see _deregisterFocusableItemsGroup()).\n        this._listItemGroupToChangeListeners.set(groupView, groupItemsChangeCallback);\n        groupView.items.on('change', groupItemsChangeCallback);\n    }\n    /**\n\t * Removes a list item group view (and its children) from the focus tracker.\n\t *\n\t * @param groupView The group view to be removed.\n\t */ _deregisterFocusableItemsGroup(groupView) {\n        for (const child of groupView.items){\n            this._deregisterFocusableListItem(child);\n        }\n        groupView.items.off('change', this._listItemGroupToChangeListeners.get(groupView));\n        this._listItemGroupToChangeListeners.delete(groupView);\n    }\n}\n\n/**\n * Represents a dropdown menu list view.\n */ class DropdownMenuListView extends ListView {\n    /**\n\t * Creates an instance of the dropdown menu list view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.role = 'menu';\n        this.set('isVisible', true);\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-dropdown-menu-list',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ]\n            }\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/dropdown/menu/utils\n */ const NESTED_PANEL_HORIZONTAL_OFFSET$1 = 5;\n/**\n * Contains every positioning function used by {@link module:ui/dropdown/menu/dropdownmenunestedmenuview~DropdownMenuNestedMenuView} that\n * decides where the {@link module:ui/dropdown/menu/dropdownmenunestedmenuview~DropdownMenuNestedMenuView#panelView} should be placed.\n *\n * Positioning functions:\n *\n *\t┌──────┬───────────────┐\n *\t│      │               │\n *\t└──────┤               │\n *\t       │               │\n *\t       │            ES │\n *\t       └───────────────┘\n *\n *\t┌───────────────┬──────┐\n *\t│               │      │\n *\t│               ├──────┘\n *\t│               │\n *\t│ WS            │\n *\t└───────────────┘\n *\n *\t       ┌───────────────┐\n *\t       │            EN │\n *\t       │               │\n *\t┌──────┤               │\n *\t│      │               │\n *\t└──────┴───────────────┘\n *\n *\t┌───────────────┐\n *\t│ WN            │\n *\t│               │\n *\t│               ├──────┐\n *\t│               │      │\n *\t└───────────────┴──────┘\n */ const DropdownMenuPanelPositioningFunctions = {\n    eastSouth: (buttonRect)=>({\n            top: buttonRect.top,\n            left: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET$1,\n            name: 'es'\n        }),\n    eastNorth: (buttonRect, panelRect)=>({\n            top: buttonRect.top - panelRect.height + buttonRect.height,\n            left: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET$1,\n            name: 'en'\n        }),\n    westSouth: (buttonRect, panelRect)=>({\n            top: buttonRect.top,\n            left: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET$1,\n            name: 'ws'\n        }),\n    westNorth: (buttonRect, panelRect)=>({\n            top: buttonRect.top - panelRect.height + buttonRect.height,\n            left: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET$1,\n            name: 'wn'\n        })\n};\n\n/**\n * Represents a view for a single item in a dropdown menu list.\n */ class DropdownMenuListItemView extends ListItemView {\n    /**\n\t * The view representing either a flat item or a nested menu in a dropdown menu list item.\n\t */ childView;\n    constructor(locale, parentMenuView, childView){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.childView = childView;\n        this.children.add(childView);\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-dropdown-menu-list__nested-menu__item'\n                ]\n            },\n            on: {\n                'mouseenter': bind.to('mouseenter')\n            }\n        });\n        if (parentMenuView) {\n            this.delegate('mouseenter').to(parentMenuView);\n            if (childView instanceof DropdownMenuListItemButtonView) {\n                childView.delegate('execute').to(parentMenuView);\n            }\n        }\n    }\n}\n\nconst DropdownRootMenuBehaviors = {\n    /**\n\t * Move focus to a menu item on mouse hover. If it is a button to open a nested menu, open that menu.\n\t */ toggleMenusAndFocusItemsOnHover (rootList) {\n        rootList.on('menu:mouseenter', (evt)=>{\n            const [pathLeaf] = evt.path;\n            evt.source.focus();\n            for (const menuView of rootList.menus){\n                const isListItemContainingMenu = pathLeaf instanceof DropdownMenuListItemView && pathLeaf.childView === menuView;\n                menuView.isOpen = (evt.path.includes(menuView) || isListItemContainingMenu) && menuView.isEnabled;\n            }\n        });\n    },\n    /**\n\t * Handles the following case:\n\t *\n\t * 1. Hover to open a sub-menu (A). The button has focus.\n\t * 2. Press arrow up/down to move focus to another sub-menu (B) button.\n\t * 3. Press arrow right to open the sub-menu (B).\n\t * 4. The sub-menu (A) should close (if not, there are two open menus).\n\t */ closeMenuWhenAnotherOnTheSameLevelOpens (rootList) {\n        rootList.on('menu:change:isOpen', (evt, name, isOpen)=>{\n            if (!isOpen) {\n                return;\n            }\n            const evtMenu = evt.source;\n            for (const menuView of rootList.menus){\n                if (evtMenu.parentMenuView === menuView.parentMenuView && evtMenu !== menuView) {\n                    menuView.isOpen = false;\n                }\n            }\n        });\n    }\n};\nconst DropdownMenuBehaviors = {\n    /**\n\t * Open the menu on the right arrow key press (left, in RTL mode). This allows for navigating to sub-menus using the keyboard.\n\t */ openOnArrowRightKey (menuView) {\n        const keystroke = menuView.locale.uiLanguageDirection === 'rtl' ? 'arrowleft' : 'arrowright';\n        menuView.keystrokes.set(keystroke, (data, cancel)=>{\n            if (menuView.focusTracker.focusedElement !== menuView.buttonView.element || !menuView.isEnabled) {\n                return;\n            }\n            if (!menuView.isOpen) {\n                menuView.isOpen = true;\n            }\n            menuView.panelView.focus();\n            cancel();\n        });\n    },\n    /**\n\t * Opens the menu on its button click as well as enter and space keys press (if the button is focused).\n\t */ openOnButtonClick (menuView) {\n        menuView.buttonView.on('execute', ()=>{\n            if (menuView.isEnabled) {\n                menuView.isOpen = true;\n            }\n        });\n    },\n    /**\n\t * Opens the menu and focuses the panel content upon pressing the Enter key.\n\t */ openAndFocusOnEnterKeyPress (menuView) {\n        menuView.keystrokes.set('enter', (data, cancel)=>{\n            // Engage only for Enter key press when the button is focused. The panel can contain\n            // other UI components and features that rely on the Enter key press.\n            if (menuView.focusTracker.focusedElement !== menuView.buttonView.element) {\n                return;\n            }\n            menuView.isOpen = true;\n            menuView.panelView.focus();\n            cancel();\n        });\n    },\n    /**\n\t * Closes the menu on the left key press (right, in RTL mode). This allows for navigating to sub-menus using the keyboard.\n\t */ closeOnArrowLeftKey (menuView) {\n        const keystroke = menuView.locale.uiLanguageDirection === 'rtl' ? 'arrowright' : 'arrowleft';\n        menuView.keystrokes.set(keystroke, (data, cancel)=>{\n            if (menuView.isOpen) {\n                // Focus first, then close the panel. Otherwise, Safari won't send blur events for detached DOM elements, leading to errors.\n                menuView.focus();\n                menuView.isOpen = false;\n                cancel();\n            }\n        });\n    },\n    closeOnEscKey (menuView) {\n        menuView.keystrokes.set('esc', (data, cancel)=>{\n            if (menuView.isOpen) {\n                // Focus first, then close the panel. Otherwise, Safari won't send blur events for detached DOM elements, leading to errors.\n                menuView.focus();\n                menuView.isOpen = false;\n                cancel();\n            }\n        });\n    },\n    /**\n\t * Closes the menu when its parent menu closes. This prevents from leaving orphaned open menus.\n\t */ closeOnParentClose (menuView, parentMenuView) {\n        parentMenuView.on('change:isOpen', (evt, name, isOpen)=>{\n            // TODO: Remove checking `evt.source` if `change:isOpen` is no longer delegated.\n            if (!isOpen && evt.source === parentMenuView) {\n                menuView.isOpen = false;\n            }\n        });\n    }\n};\n\nconst toPx$5 = /* #__PURE__ */ toUnit('px');\n// A static balloon panel positioning function that moves the balloon far off the viewport.\n// It is used as a fallback when there is no way to position the balloon using provided\n// positioning functions (see: `getOptimalPosition()`), for instance, when the target the\n// balloon should be attached to gets obscured by scrollable containers or the viewport.\n//\n// It prevents the balloon from being attached to the void and possible degradation of the UX.\n// At the same time, it keeps the balloon physically visible in the DOM so the focus remains\n// uninterrupted.\nconst POSITION_OFF_SCREEN = {\n    top: -99999,\n    left: -99999,\n    name: 'arrowless',\n    config: {\n        withArrow: false\n    }\n};\n/**\n * The balloon panel view class.\n *\n * A floating container which can\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#pin pin} to any\n * {@link module:utils/dom/position~Options#target target} in the DOM and remain in that position\n * e.g. when the web page is scrolled.\n *\n * The balloon panel can be used to display contextual, non-blocking UI like forms, toolbars and\n * the like in its {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#content} view\n * collection.\n *\n * There is a number of {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}\n * that the balloon can use, automatically switching from one to another when the viewport space becomes\n * scarce to keep the balloon visible to the user as long as it is possible. The balloon will also\n * accept any custom position set provided by the user compatible with the\n * {@link module:utils/dom/position~Options options}.\n *\n * ```ts\n * const panel = new BalloonPanelView( locale );\n * const childView = new ChildView();\n * const positions = BalloonPanelView.defaultPositions;\n *\n * panel.render();\n *\n * // Add a child view to the panel's content collection.\n * panel.content.add( childView );\n *\n * // Start pinning the panel to an element with the \"target\" id DOM.\n * // The balloon will remain pinned until unpin() is called.\n * panel.pin( {\n * \ttarget: document.querySelector( '#target' ),\n * \tpositions: [\n * \t\tpositions.northArrowSouth,\n * \t\tpositions.southArrowNorth\n * \t]\n * } );\n * ```\n */ class BalloonPanelView extends View {\n    /**\n\t * A collection of the child views that creates the balloon panel contents.\n\t */ content;\n    /**\n\t * A callback that starts pinning the panel when {@link #isVisible} gets\n\t * `true`. Used by {@link #pin}.\n\t *\n\t * @private\n\t */ _pinWhenIsVisibleCallback;\n    /**\n\t * An instance of resize observer used to detect if target element is still visible.\n\t */ _resizeObserver;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('top', 0);\n        this.set('left', 0);\n        this.set('position', 'arrow_nw');\n        this.set('isVisible', false);\n        this.set('withArrow', true);\n        this.set('class', undefined);\n        this._pinWhenIsVisibleCallback = null;\n        this._resizeObserver = null;\n        this.content = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-balloon-panel',\n                    bind.to('position', (value)=>`ck-balloon-panel_${value}`),\n                    bind.if('isVisible', 'ck-balloon-panel_visible'),\n                    bind.if('withArrow', 'ck-balloon-panel_with-arrow'),\n                    bind.to('class')\n                ],\n                style: {\n                    top: bind.to('top', toPx$5),\n                    left: bind.to('left', toPx$5)\n                }\n            },\n            children: this.content\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this.hide();\n        super.destroy();\n    }\n    /**\n\t * Shows the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */ show() {\n        this.isVisible = true;\n    }\n    /**\n\t * Hides the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */ hide() {\n        this.isVisible = false;\n    }\n    /**\n\t * Attaches the panel to a specified {@link module:utils/dom/position~Options#target} with a\n\t * smart positioning heuristics that chooses from available positions to make sure the panel\n\t * is visible to the user i.e. within the limits of the viewport.\n\t *\n\t * This method accepts configuration {@link module:utils/dom/position~Options options}\n\t * to set the `target`, optional `limiter` and `positions` the balloon should choose from.\n\t *\n\t * ```ts\n\t * const panel = new BalloonPanelView( locale );\n\t * const positions = BalloonPanelView.defaultPositions;\n\t *\n\t * panel.render();\n\t *\n\t * // Attach the panel to an element with the \"target\" id DOM.\n\t * panel.attachTo( {\n\t * \ttarget: document.querySelector( '#target' ),\n\t * \tpositions: [\n\t * \t\tpositions.northArrowSouth,\n\t * \t\tpositions.southArrowNorth\n\t * \t]\n\t * } );\n\t * ```\n\t *\n\t * **Note**: Attaching the panel will also automatically {@link #show} it.\n\t *\n\t * **Note**: An attached panel will not follow its target when the window is scrolled or resized.\n\t * See the {@link #pin} method for a more permanent positioning strategy.\n\t *\n\t * @param options Positioning options compatible with {@link module:utils/dom/position~getOptimalPosition}.\n\t * Default `positions` array is {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t * @returns Whether the balloon was shown and successfully attached or not. Attaching can fail if the target\n\t * provided in the options is invisible (e.g. element detached from DOM).\n\t */ attachTo(options) {\n        const target = getDomElement(options.target);\n        if (target && !isVisible(target)) {\n            return false;\n        }\n        this.show();\n        const defaultPositions = BalloonPanelView.defaultPositions;\n        const positionOptions = Object.assign({}, {\n            element: this.element,\n            positions: [\n                defaultPositions.southArrowNorth,\n                defaultPositions.southArrowNorthMiddleWest,\n                defaultPositions.southArrowNorthMiddleEast,\n                defaultPositions.southArrowNorthWest,\n                defaultPositions.southArrowNorthEast,\n                defaultPositions.northArrowSouth,\n                defaultPositions.northArrowSouthMiddleWest,\n                defaultPositions.northArrowSouthMiddleEast,\n                defaultPositions.northArrowSouthWest,\n                defaultPositions.northArrowSouthEast,\n                defaultPositions.viewportStickyNorth\n            ],\n            limiter: global.document.body,\n            fitInViewport: true\n        }, options);\n        const optimalPosition = BalloonPanelView._getOptimalPosition(positionOptions) || POSITION_OFF_SCREEN;\n        // Usually browsers make some problems with super accurate values like 104.345px\n        // so it is better to use int values.\n        const left = parseInt(optimalPosition.left);\n        const top = parseInt(optimalPosition.top);\n        const position = optimalPosition.name;\n        const config = optimalPosition.config || {};\n        const { withArrow = true } = config;\n        this.top = top;\n        this.left = left;\n        this.position = position;\n        this.withArrow = withArrow;\n        return true;\n    }\n    /**\n\t * Works the same way as the {@link #attachTo} method except that the position of the panel is\n\t * continuously updated when:\n\t *\n\t * * any ancestor of the {@link module:utils/dom/position~Options#target}\n\t * or {@link module:utils/dom/position~Options#limiter} is scrolled,\n\t * * the browser window gets resized or scrolled.\n\t *\n\t * Thanks to that, the panel always sticks to the {@link module:utils/dom/position~Options#target}\n\t * and is immune to the changing environment.\n\t *\n\t * ```ts\n\t * const panel = new BalloonPanelView( locale );\n\t * const positions = BalloonPanelView.defaultPositions;\n\t *\n\t * panel.render();\n\t *\n\t * // Pin the panel to an element with the \"target\" id DOM.\n\t * panel.pin( {\n\t * \ttarget: document.querySelector( '#target' ),\n\t * \tpositions: [\n\t * \t\tpositions.northArrowSouth,\n\t * \t\tpositions.southArrowNorth\n\t * \t]\n\t * } );\n\t * ```\n\t *\n\t * To leave the pinned state, use the {@link #unpin} method.\n\t *\n\t * **Note**: Pinning the panel will also automatically {@link #show} it.\n\t *\n\t * @param options Positioning options compatible with {@link module:utils/dom/position~getOptimalPosition}.\n\t * Default `positions` array is {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t */ pin(options) {\n        this.unpin();\n        if (!this._startPinning(options)) {\n            return;\n        }\n        this._pinWhenIsVisibleCallback = ()=>{\n            if (this.isVisible) {\n                this._startPinning(options);\n            } else {\n                this._stopPinning();\n            }\n        };\n        // Control the state of the listeners depending on whether the panel is visible\n        // or not.\n        // TODO: Use on() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n        this.listenTo(this, 'change:isVisible', this._pinWhenIsVisibleCallback);\n    }\n    /**\n\t * Stops pinning the panel, as set up by {@link #pin}.\n\t */ unpin() {\n        if (this._pinWhenIsVisibleCallback) {\n            // Deactivate listeners attached by pin().\n            this._stopPinning();\n            // Deactivate the panel pin() control logic.\n            // TODO: Use off() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n            this.stopListening(this, 'change:isVisible', this._pinWhenIsVisibleCallback);\n            this._pinWhenIsVisibleCallback = null;\n            this.hide();\n        }\n    }\n    /**\n\t * Starts managing the pinned state of the panel. See {@link #pin}.\n\t *\n\t * @param options Positioning options compatible with {@link module:utils/dom/position~getOptimalPosition}.\n\t * @returns Whether the balloon was shown and successfully attached or not. Attaching can fail if the target\n\t * provided in the options is invisible (e.g. element detached from DOM).\n\t */ _startPinning(options) {\n        if (!this.attachTo(options)) {\n            return false;\n        }\n        let targetElement = getDomElement(options.target);\n        const limiterElement = options.limiter ? getDomElement(options.limiter) : global.document.body;\n        // Then we need to listen on scroll event of eny element in the document.\n        this.listenTo(global.document, 'scroll', (evt, domEvt)=>{\n            const scrollTarget = domEvt.target;\n            // The position needs to be updated if the positioning target is within the scrolled element.\n            const isWithinScrollTarget = targetElement && scrollTarget.contains(targetElement);\n            // The position needs to be updated if the positioning limiter is within the scrolled element.\n            const isLimiterWithinScrollTarget = limiterElement && scrollTarget.contains(limiterElement);\n            // The positioning target and/or limiter can be a Rect, object etc..\n            // There's no way to optimize the listener then.\n            if (isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement || !limiterElement) {\n                this.attachTo(options);\n            }\n        }, {\n            useCapture: true\n        });\n        // We need to listen on window resize event and update position.\n        this.listenTo(global.window, 'resize', ()=>{\n            this.attachTo(options);\n        });\n        // Hide the panel if the target element is no longer visible.\n        if (!this._resizeObserver) {\n            // If the target element is a text node, we need to check the parent element.\n            // It's because `ResizeObserver` accept only elements, not text nodes.\n            if (targetElement && isText(targetElement)) {\n                targetElement = targetElement.parentElement;\n            }\n            if (targetElement) {\n                const checkVisibility = ()=>{\n                    // If the target element is no longer visible, hide the panel.\n                    if (!isVisible(targetElement)) {\n                        this.unpin();\n                    }\n                };\n                // Element is being resized to 0x0 after it's parent became hidden,\n                // so we need to check size in order to determine if it's visible or not.\n                this._resizeObserver = new ResizeObserver(targetElement, checkVisibility);\n            }\n        }\n        return true;\n    }\n    /**\n\t * Stops managing the pinned state of the panel. See {@link #pin}.\n\t */ _stopPinning() {\n        this.stopListening(global.document, 'scroll');\n        this.stopListening(global.window, 'resize');\n        if (this._resizeObserver) {\n            this._resizeObserver.destroy();\n            this._resizeObserver = null;\n        }\n    }\n    /**\n\t * Returns available {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n\t * {@link module:utils/dom/position~PositioningFunction positioning functions} adjusted by the specific offsets.\n\t *\n\t * @internal\n\t * @param options Options to generate positions. If not specified, this helper will simply return\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t * @param options.sideOffset A custom side offset (in pixels) of each position. If\n\t * not specified, {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowSideOffset the default value}\n\t * will be used.\n\t * @param options.heightOffset A custom height offset (in pixels) of each position. If\n\t * not specified, {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowHeightOffset the default value}\n\t * will be used.\n\t * @param options.stickyVerticalOffset A custom offset (in pixels) of the `viewportStickyNorth` positioning function.\n\t * If not specified, {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.stickyVerticalOffset the default value}\n\t * will be used.\n\t * @param options.config Additional configuration of the balloon balloon panel view.\n\t * Currently only {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#withArrow} is supported. Learn more\n\t * about {@link module:utils/dom/position~PositioningFunction positioning functions}.\n\t */ static generatePositions(options = {}) {\n        const { sideOffset = BalloonPanelView.arrowSideOffset, heightOffset = BalloonPanelView.arrowHeightOffset, stickyVerticalOffset = BalloonPanelView.stickyVerticalOffset, config } = options;\n        return {\n            // ------- North west\n            northWestArrowSouthWest: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left - sideOffset,\n                    name: 'arrow_sw',\n                    ...config && {\n                        config\n                    }\n                }),\n            northWestArrowSouthMiddleWest: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left - balloonRect.width * .25 - sideOffset,\n                    name: 'arrow_smw',\n                    ...config && {\n                        config\n                    }\n                }),\n            northWestArrowSouth: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left - balloonRect.width / 2,\n                    name: 'arrow_s',\n                    ...config && {\n                        config\n                    }\n                }),\n            northWestArrowSouthMiddleEast: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left - balloonRect.width * .75 + sideOffset,\n                    name: 'arrow_sme',\n                    ...config && {\n                        config\n                    }\n                }),\n            northWestArrowSouthEast: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left - balloonRect.width + sideOffset,\n                    name: 'arrow_se',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- North\n            northArrowSouthWest: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left + targetRect.width / 2 - sideOffset,\n                    name: 'arrow_sw',\n                    ...config && {\n                        config\n                    }\n                }),\n            northArrowSouthMiddleWest: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width * .25 - sideOffset,\n                    name: 'arrow_smw',\n                    ...config && {\n                        config\n                    }\n                }),\n            northArrowSouth: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n                    name: 'arrow_s',\n                    ...config && {\n                        config\n                    }\n                }),\n            northArrowSouthMiddleEast: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width * .75 + sideOffset,\n                    name: 'arrow_sme',\n                    ...config && {\n                        config\n                    }\n                }),\n            northArrowSouthEast: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width + sideOffset,\n                    name: 'arrow_se',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- North east\n            northEastArrowSouthWest: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.right - sideOffset,\n                    name: 'arrow_sw',\n                    ...config && {\n                        config\n                    }\n                }),\n            northEastArrowSouthMiddleWest: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.right - balloonRect.width * .25 - sideOffset,\n                    name: 'arrow_smw',\n                    ...config && {\n                        config\n                    }\n                }),\n            northEastArrowSouth: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.right - balloonRect.width / 2,\n                    name: 'arrow_s',\n                    ...config && {\n                        config\n                    }\n                }),\n            northEastArrowSouthMiddleEast: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.right - balloonRect.width * .75 + sideOffset,\n                    name: 'arrow_sme',\n                    ...config && {\n                        config\n                    }\n                }),\n            northEastArrowSouthEast: (targetRect, balloonRect)=>({\n                    top: getNorthTop(targetRect, balloonRect),\n                    left: targetRect.right - balloonRect.width + sideOffset,\n                    name: 'arrow_se',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- South west\n            southWestArrowNorthWest: (targetRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left - sideOffset,\n                    name: 'arrow_nw',\n                    ...config && {\n                        config\n                    }\n                }),\n            southWestArrowNorthMiddleWest: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left - balloonRect.width * .25 - sideOffset,\n                    name: 'arrow_nmw',\n                    ...config && {\n                        config\n                    }\n                }),\n            southWestArrowNorth: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left - balloonRect.width / 2,\n                    name: 'arrow_n',\n                    ...config && {\n                        config\n                    }\n                }),\n            southWestArrowNorthMiddleEast: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left - balloonRect.width * .75 + sideOffset,\n                    name: 'arrow_nme',\n                    ...config && {\n                        config\n                    }\n                }),\n            southWestArrowNorthEast: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left - balloonRect.width + sideOffset,\n                    name: 'arrow_ne',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- South\n            southArrowNorthWest: (targetRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left + targetRect.width / 2 - sideOffset,\n                    name: 'arrow_nw',\n                    ...config && {\n                        config\n                    }\n                }),\n            southArrowNorthMiddleWest: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width * 0.25 - sideOffset,\n                    name: 'arrow_nmw',\n                    ...config && {\n                        config\n                    }\n                }),\n            southArrowNorth: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n                    name: 'arrow_n',\n                    ...config && {\n                        config\n                    }\n                }),\n            southArrowNorthMiddleEast: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width * 0.75 + sideOffset,\n                    name: 'arrow_nme',\n                    ...config && {\n                        config\n                    }\n                }),\n            southArrowNorthEast: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width + sideOffset,\n                    name: 'arrow_ne',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- South east\n            southEastArrowNorthWest: (targetRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.right - sideOffset,\n                    name: 'arrow_nw',\n                    ...config && {\n                        config\n                    }\n                }),\n            southEastArrowNorthMiddleWest: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.right - balloonRect.width * .25 - sideOffset,\n                    name: 'arrow_nmw',\n                    ...config && {\n                        config\n                    }\n                }),\n            southEastArrowNorth: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.right - balloonRect.width / 2,\n                    name: 'arrow_n',\n                    ...config && {\n                        config\n                    }\n                }),\n            southEastArrowNorthMiddleEast: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.right - balloonRect.width * .75 + sideOffset,\n                    name: 'arrow_nme',\n                    ...config && {\n                        config\n                    }\n                }),\n            southEastArrowNorthEast: (targetRect, balloonRect)=>({\n                    top: getSouthTop(targetRect),\n                    left: targetRect.right - balloonRect.width + sideOffset,\n                    name: 'arrow_ne',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- West\n            westArrowEast: (targetRect, balloonRect)=>({\n                    top: targetRect.top + targetRect.height / 2 - balloonRect.height / 2,\n                    left: targetRect.left - balloonRect.width - heightOffset,\n                    name: 'arrow_e',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- East\n            eastArrowWest: (targetRect, balloonRect)=>({\n                    top: targetRect.top + targetRect.height / 2 - balloonRect.height / 2,\n                    left: targetRect.right + heightOffset,\n                    name: 'arrow_w',\n                    ...config && {\n                        config\n                    }\n                }),\n            // ------- Sticky\n            viewportStickyNorth: (targetRect, balloonRect, viewportRect, limiterRect)=>{\n                const boundaryRect = limiterRect || viewportRect;\n                if (!targetRect.getIntersection(boundaryRect)) {\n                    return null;\n                }\n                // Engage when the target top and bottom edges are close or off the boundary.\n                // By close, it means there's not enough space for the balloon arrow (offset).\n                if (boundaryRect.height - targetRect.height > stickyVerticalOffset) {\n                    return null;\n                }\n                return {\n                    top: boundaryRect.top + stickyVerticalOffset,\n                    left: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n                    name: 'arrowless',\n                    config: {\n                        withArrow: false,\n                        ...config\n                    }\n                };\n            }\n        };\n        /**\n\t\t * Returns the top coordinate for positions starting with `north*`.\n\t\t *\n\t\t * @param targetRect A rect of the target.\n\t\t * @param balloonRect A rect of the balloon.\n\t\t */ function getNorthTop(targetRect, balloonRect) {\n            return targetRect.top - balloonRect.height - heightOffset;\n        }\n        /**\n\t\t * Returns the top coordinate for positions starting with `south*`.\n\t\t *\n\t\t * @param targetRect A rect of the target.\n\t\t */ function getSouthTop(targetRect) {\n            return targetRect.bottom + heightOffset;\n        }\n    }\n    /**\n\t * A side offset of the arrow tip from the edge of the balloon. Controlled by CSS.\n\t *\n\t * ```\n\t *\t\t ┌───────────────────────┐\n\t *\t\t │                       │\n\t *\t\t │         Balloon       │\n\t *\t\t │         Content       │\n\t *\t\t │                       │\n\t *\t\t └──+    +───────────────┘\n\t *\t\t |   \\  /\n\t *\t\t |    \\/\n\t *\t\t>┼─────┼< ─────────────────────── side offset\n\t *\n\t * ```\n\t *\n\t * @default 25\n\t */ static arrowSideOffset = 25;\n    /**\n\t * A height offset of the arrow from the edge of the balloon. Controlled by CSS.\n\t *\n\t * ```\n\t *\t\t ┌───────────────────────┐\n\t *\t\t │                       │\n\t *\t\t │         Balloon       │\n\t *\t\t │         Content       │      ╱-- arrow height offset\n\t *\t\t │                       │      V\n\t *\t\t └──+    +───────────────┘ --- ─┼───────\n\t *\t\t     \\  /                       │\n\t *\t\t      \\/                        │\n\t *\t\t────────────────────────────────┼───────\n\t *\t\t                                ^\n\t *\n\t *\n\t *\t\t>┼────┼<  arrow height offset\n\t *\t\t │    │\n\t *\t\t │    ┌────────────────────────┐\n\t *\t\t │    │                        │\n\t *\t\t │   ╱                         │\n\t *\t\t │ ╱            Balloon        │\n\t *\t\t │ ╲            Content        │\n\t *\t\t │   ╲                         │\n\t *\t\t │    │                        │\n\t *\t\t │    └────────────────────────┘\n\t * ```\n\t *\n\t * @default 10\n\t*/ static arrowHeightOffset = 10;\n    /**\n\t * A vertical offset of the balloon panel from the edge of the viewport if sticky.\n\t * It helps in accessing toolbar buttons underneath the balloon panel.\n\t *\n\t * ```\n\t *\t\t  ┌───────────────────────────────────────────────────┐\n\t *\t\t  │                      Target                       │\n\t *\t\t  │                                                   │\n\t *\t\t  │                            /── vertical offset    │\n\t *\t\t┌─────────────────────────────V─────────────────────────┐\n\t *\t\t│ Toolbar            ┌─────────────┐                    │\n\t *\t\t├────────────────────│   Balloon   │────────────────────┤\n\t *\t\t│ │                  └─────────────┘                  │ │\n\t *\t\t│ │                                                   │ │\n\t *\t\t│ │                                                   │ │\n\t *\t\t│ │                                                   │ │\n\t *\t\t│ └───────────────────────────────────────────────────┘ │\n\t *\t\t│                        Viewport                       │\n\t *\t\t└───────────────────────────────────────────────────────┘\n\t * ```\n\t *\n\t * @default 20\n\t */ static stickyVerticalOffset = 20;\n    /**\n\t * Function used to calculate the optimal position for the balloon.\n\t */ static _getOptimalPosition = getOptimalPosition;\n    /**\n\t * A default set of positioning functions used by the balloon panel view\n\t * when attaching using the {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo} method.\n\t *\n\t * The available positioning functions are as follows:\n\t *\n\t * **North west**\n\t *\n\t * * `northWestArrowSouthWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t V\n\t *\t\t [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouthMiddleWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t    V\n\t *\t\t    [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouth`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t         V\n\t *\t\t         [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouthMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t             V\n\t *\t\t             [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouthEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t                 V\n\t *\t\t                 [ Target ]\n\t * ```\n\t *\n\t * **North**\n\t *\n\t * * `northArrowSouthWest`\n\t *\n\t * ```\n\t *\t\t    +-----------------+\n\t *\t\t    |     Balloon     |\n\t *\t\t    +-----------------+\n\t *\t\t     V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northArrowSouthMiddleWest`\n\t *\n\t * ```\n\t *\t\t +-----------------+\n\t *\t\t |     Balloon     |\n\t *\t\t +-----------------+\n\t *\t\t     V\n\t *\t\t[ Target ]\n\t * ```\n\t * * `northArrowSouth`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t         V\n\t *\t\t    [ Target ]\n\t * ```\n\t *\n\t * * `northArrowSouthMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t             V\n\t *\t\t        [ Target ]\n\t * ```\n\t *\n\t * * `northArrowSouthEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t                V\n\t *\t\t           [ Target ]\n\t * ```\n\t *\n\t * **North east**\n\t *\n\t * * `northEastArrowSouthWest`\n\t *\n\t * ```\n\t *\t\t        +-----------------+\n\t *\t\t        |     Balloon     |\n\t *\t\t        +-----------------+\n\t *\t\t         V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouthMiddleWest`\n\t *\n\t * ```\n\t *\t\t     +-----------------+\n\t *\t\t     |     Balloon     |\n\t *\t\t     +-----------------+\n\t *\t\t         V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouth`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t         V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouthMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t             V\n\t *\t\t    [ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouthEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t                 V\n\t *\t\t        [ Target ]\n\t * ```\n\t *\n\t * **South**\n\t *\n\t * * `southArrowNorthWest`\n\t *\n\t * ```\n\t *\t\t[ Target ]\n\t *\t\t     ^\n\t *\t\t    +-----------------+\n\t *\t\t    |     Balloon     |\n\t *\t\t    +-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorthMiddleWest`\n\t *\n\t * ```\n\t *\t\t   [ Target ]\n\t *\t\t        ^\n\t *\t\t    +-----------------+\n\t *\t\t    |     Balloon     |\n\t *\t\t    +-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorth`\n\t *\n\t * ```\n\t *\t\t    [ Target ]\n\t *\t\t         ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorthMiddleEast`\n\t *\n\t * ```\n\t *\t\t            [ Target ]\n\t *\t\t                 ^\n\t *\t\t   +-----------------+\n\t *\t\t   |     Balloon     |\n\t *\t\t   +-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorthEast`\n\t *\n\t * ```\n\t *\t\t            [ Target ]\n\t *\t\t                 ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **South west**\n\t *\n\t * * `southWestArrowNorthWest`\n\t *\n\t *\n\t * ```\n\t *\t\t [ Target ]\n\t *\t\t ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorthMiddleWest`\n\t *\n\t * ```\n\t *\t\t     [ Target ]\n\t *\t\t     ^\n\t *\t\t +-----------------+\n\t *\t\t |     Balloon     |\n\t *\t\t +-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorth`\n\t *\n\t * ```\n\t *\t\t         [ Target ]\n\t *\t\t         ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorthMiddleEast`\n\t *\n\t * ```\n\t *\t\t              [ Target ]\n\t *\t\t              ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorthEast`\n\t *\n\t * ```\n\t *\t\t                 [ Target ]\n\t *\t\t                 ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **South east**\n\t *\n\t * * `southEastArrowNorthWest`\n\t *\n\t * ```\n\t *\t\t[ Target ]\n\t *\t\t         ^\n\t *\t\t        +-----------------+\n\t *\t\t        |     Balloon     |\n\t *\t\t        +-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorthMiddleWest`\n\t *\n\t * ```\n\t *\t\t   [ Target ]\n\t *\t\t            ^\n\t *\t\t        +-----------------+\n\t *\t\t        |     Balloon     |\n\t *\t\t        +-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorth`\n\t *\n\t * ```\n\t *\t\t[ Target ]\n\t *\t\t         ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorthMiddleEast`\n\t *\n\t * ```\n\t *\t\t     [ Target ]\n\t *\t\t              ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorthEast`\n\t *\n\t * ```\n\t *\t\t        [ Target ]\n\t *\t\t                 ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **West**\n\t *\n\t * * `westArrowEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |>[ Target ]\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **East**\n\t *\n\t * * `eastArrowWest`\n\t *\n\t * ```\n\t *\t\t           +-----------------+\n\t *\t\t[ Target ]<|     Balloon     |\n\t *\t\t           +-----------------+\n\t * ```\n\t *\n\t * **Sticky**\n\t *\n\t * * `viewportStickyNorth`\n\t *\n\t * ```\n\t *\t\t    +---------------------------+\n\t *\t\t    |        [ Target ]         |\n\t *\t\t    |                           |\n\t *\t\t+-----------------------------------+\n\t *\t\t|   |    +-----------------+    |   |\n\t *\t\t|   |    |     Balloon     |    |   |\n\t *\t\t|   |    +-----------------+    |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   +---------------------------+   |\n\t *\t\t|             Viewport              |\n\t *\t\t+-----------------------------------+\n\t * ```\n\t *\n\t * See {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo}.\n\t *\n\t * Positioning functions must be compatible with {@link module:utils/dom/position~DomPoint}.\n\t *\n\t * Default positioning functions with customized offsets can be generated using\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.generatePositions}.\n\t *\n\t * The name that the position function returns will be reflected in the balloon panel's class that\n\t * controls the placement of the \"arrow\". See {@link #position} to learn more.\n\t */ static defaultPositions = /* #__PURE__ */ BalloonPanelView.generatePositions();\n}\n/**\n * Returns the DOM element for given object or null, if there is none,\n * e.g. when the passed object is a Rect instance or so.\n */ function getDomElement(object) {\n    if (isElement(object)) {\n        return object;\n    }\n    if (isRange(object)) {\n        return object.commonAncestorContainer;\n    }\n    if (typeof object == 'function') {\n        return getDomElement(object());\n    }\n    return null;\n}\n\n/**\n * Represents the view for the dropdown menu panel.\n */ class DropdownMenuNestedMenuPanelView extends BalloonPanelView {\n    /**\n\t * Creates an instance of the menu panel view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set({\n            isVisible: false,\n            position: 'se',\n            class: null,\n            top: 0,\n            left: 0\n        });\n        this.extendTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck-reset',\n                    'ck-dropdown-menu__nested-menu__panel'\n                ],\n                tabindex: '-1'\n            },\n            on: {\n                // Drag and drop in the panel should not break the selection in the editor.\n                // https://github.com/ckeditor/ckeditor5-ui/issues/228\n                selectstart: bind.to((evt)=>{\n                    if (evt.target.tagName.toLocaleLowerCase() === 'input') {\n                        return;\n                    }\n                    evt.preventDefault();\n                })\n            }\n        });\n    }\n    /**\n\t * Focuses the first child of the panel (default) or the last one if the `direction` is `-1`.\n\t *\n\t * @param direction The direction to focus. Default is `1`.\n\t */ focus(direction = 1) {\n        const { content } = this;\n        if (content.length) {\n            if (direction === 1) {\n                content.first.focus();\n            } else {\n                content.last.focus();\n            }\n        }\n    }\n}\n\n/**\n * Represents a nested menu view.\n */ class DropdownMenuNestedMenuView extends View {\n    /**\n\t * An array of delegated events for the dropdown menu definition controller.\n\t * These events are delegated to the dropdown menu element.\n\t */ // Due to some spaghetti code we need to delegate `change:isOpen`.\n    static DELEGATED_EVENTS = [\n        'mouseenter',\n        'execute',\n        'change:isOpen'\n    ];\n    id;\n    /**\n\t * Button of the menu view.\n\t */ buttonView;\n    /**\n\t * Panel of the menu. It hosts children of the menu.\n\t */ panelView;\n    /**\n\t * List of nested menu entries.\n\t */ listView;\n    /**\n\t * Tracks information about the DOM focus in the menu.\n\t */ focusTracker;\n    /**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the menu.\n\t */ keystrokes;\n    _bodyCollection;\n    /**\n\t * Creates a new instance of the DropdownMenuView class.\n\t *\n\t * @param locale\n\t * @param bodyCollection\n\t * @param id\n\t * @param label The label for the dropdown menu button.\n\t * @param parentMenuView The parent dropdown menu view, if any.\n\t */ constructor(locale, bodyCollection, id, label, parentMenuView){\n        super(locale);\n        this._bodyCollection = bodyCollection;\n        this.id = id;\n        this.set({\n            isOpen: false,\n            isEnabled: true,\n            panelPosition: 'w',\n            class: undefined,\n            parentMenuView: null\n        });\n        this.keystrokes = new KeystrokeHandler();\n        this.focusTracker = new FocusTracker();\n        this.buttonView = new DropdownMenuButtonView(locale);\n        this.buttonView.delegate('mouseenter').to(this);\n        this.buttonView.bind('isOn', 'isEnabled').to(this, 'isOpen', 'isEnabled');\n        this.buttonView.label = label;\n        this.panelView = new DropdownMenuNestedMenuPanelView(locale);\n        this.panelView.isVisible = true;\n        this.listView = new DropdownMenuListView(locale);\n        this.listView.bind('ariaLabel').to(this.buttonView, 'label');\n        this.panelView.content.add(this.listView);\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-dropdown-menu-list__nested-menu',\n                    bind.to('class'),\n                    bind.if('isEnabled', 'ck-disabled', (value)=>!value)\n                ],\n                role: 'presentation'\n            },\n            children: [\n                this.buttonView\n            ]\n        });\n        this.parentMenuView = parentMenuView;\n        if (this.parentMenuView) {\n            this._handleParentMenuView();\n        }\n        this._attachBehaviors();\n    }\n    /**\n\t * An array of positioning functions used to determine the position of the dropdown menu panel.\n\t * The order of the functions in the array determines the priority of the positions to be tried.\n\t * The first function that returns a valid position will be used.\n\t *\n\t * @returns {Array<PositioningFunction>} An array of positioning functions.\n\t * @internal\n\t */ get _panelPositions() {\n        const { westSouth, eastSouth, westNorth, eastNorth } = DropdownMenuPanelPositioningFunctions;\n        if (this.locale.uiLanguageDirection === 'ltr') {\n            return [\n                eastSouth,\n                eastNorth,\n                westSouth,\n                westNorth\n            ];\n        } else {\n            return [\n                westSouth,\n                westNorth,\n                eastSouth,\n                eastNorth\n            ];\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.panelView.render();\n        this.focusTracker.add(this.buttonView.element);\n        this.focusTracker.add(this.panelView.element);\n        this.focusTracker.add(this.listView);\n        // Listen for keystrokes coming from within #element.\n        this.keystrokes.listenTo(this.element);\n        this._mountPanelOnOpen();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this._removePanelFromBody();\n        this.panelView.destroy();\n        super.destroy();\n    }\n    /**\n\t * @inheritDoc\n\t */ focus() {\n        this.buttonView.focus();\n    }\n    _handleParentMenuView() {\n        // Propagate events from this component to parent-menu.\n        this.delegate(...DropdownMenuNestedMenuView.DELEGATED_EVENTS).to(this.parentMenuView);\n        // Close this menu if its parent closes.\n        DropdownMenuBehaviors.closeOnParentClose(this, this.parentMenuView);\n    }\n    /**\n\t * Attach all keyboard behaviors for the menu view.\n\t */ _attachBehaviors() {\n        DropdownMenuBehaviors.openOnButtonClick(this);\n        DropdownMenuBehaviors.openAndFocusOnEnterKeyPress(this);\n        DropdownMenuBehaviors.openOnArrowRightKey(this);\n        DropdownMenuBehaviors.closeOnEscKey(this);\n        DropdownMenuBehaviors.closeOnArrowLeftKey(this);\n    }\n    /**\n\t * Mounts the portal view in the body when the menu is open and removes it when the menu is closed.\n\t * Binds keystrokes to the portal view when the menu is open.\n\t */ _mountPanelOnOpen() {\n        const { panelView } = this;\n        this.on('change:isOpen', (evt, name, isOpen)=>{\n            // Ensure that the event was triggered by this instance.\n            // TODO: Remove checking `evt.source` if `change:isOpen` is no longer delegated.\n            if (evt.source !== this) {\n                return;\n            }\n            // Removes the panel view from the body when the menu is closed.\n            if (!isOpen && this._bodyCollection.has(panelView)) {\n                this._removePanelFromBody();\n                return;\n            }\n            // Adds the panel view to the body when the menu is open.\n            if (isOpen && !this._bodyCollection.has(panelView)) {\n                this._addPanelToBody();\n            }\n        });\n    }\n    /**\n\t * Removes the panel view from the editor's body and removes it from the focus tracker.\n\t */ _removePanelFromBody() {\n        const { panelView, keystrokes } = this;\n        if (this._bodyCollection.has(panelView)) {\n            this._bodyCollection.remove(panelView);\n            keystrokes.stopListening(panelView.element);\n        }\n    }\n    /**\n\t * Adds the panel view to the editor's body and sets up event listeners.\n\t */ _addPanelToBody() {\n        const { panelView, buttonView, keystrokes } = this;\n        if (!this._bodyCollection.has(panelView)) {\n            this._bodyCollection.add(panelView);\n            keystrokes.listenTo(panelView.element);\n            panelView.pin({\n                positions: this._panelPositions,\n                limiter: global.document.body,\n                element: panelView.element,\n                target: buttonView.element,\n                fitInViewport: true\n            });\n        }\n    }\n}\n\n/**\n * Creates and manages a multi-level menu UI structure, suitable to be used inside dropdown components.\n *\n * This class creates a menu structure based on {@link module:ui/dropdown/menu/utils~DropdownMenuDefinition declarative definition}\n * passed in the constructor.\n *\n * Below is an example of a simple definition, that describes a menu with two sub-menus (Menu 1, Menu 2) and four buttons in total (Item A,\n * Item B, Item C, Item D):\n *\n * ```js\n * [\n * \t{\n * \t\tid: 'menu_1',\n * \t\tmenu: 'Menu 1',\n * \t\tchildren: [\n * \t\t\t{ id: 'menu_1_a', label: 'Item A' },\n * \t\t\t{ id: 'menu_1_b', label: 'Item B' }\n * \t\t]\n * \t},\n * \t{\n * \t\tid: 'menu_2',\n * \t\tmenu: 'Menu 2',\n * \t\tchildren: [\n * \t\t\t{ id: 'menu_2_c', label: 'Item C' },\n * \t\t]\n * \t},\n * \t{ id: 'item_d', label: 'Item D' }\n * ]\n * ```\n *\n * The menu is build using multiple view classes. The most important are:\n *\n * * {@link module:ui/dropdown/menu/dropdownmenunestedmenuview~DropdownMenuNestedMenuView `DropdownMenuNestedMenuView`} - \"menu\" - provides\n * a panel with a nested menu, and a button which opens the panel,\n * * {@link module:ui/dropdown/menu/dropdownmenulistitembuttonview~DropdownMenuListItemButtonView `DropdownMenuListItemButtonView`} -\n * \"button\" or \"leaf button\" (as opposed to buttons provided by `DropdownMenuNestedMenuView`) - should trigger some action when pressed.\n *\n * Instances of these two classes are created based on the data provided in definitions. They are assigned proper IDs and labels.\n * Other view classes build a proper DOM structure around menus and buttons.\n *\n * The `DropdownMenuNestedMenuView` instances provides panels, which may include further menus or buttons. These panels are added to\n * a `BodyCollection` view, which means they are appended outside the DOM editor and UI structure.\n *\n * When \"leaf button\" is pressed, it fires `execute` event which is delegated to `DropdownMenuRootListView` as `menu:execute` event. You\n * can listen to this event to perform an action:\n *\n * ```js\n * rootListView.on( 'menu:execute', evt => {\n * \tconsole.log( evt.source.id ); // E.g. will print 'menu_1_a' when 'Item A' is pressed.\n * } );\n * ```\n *\n * All menus and \"leaf\" buttons created from the definition can be easily accessed through {@link ~DropdownMenuRootListView#menus `menus`}\n * and {@link ~DropdownMenuRootListView#buttons `buttons`} properties.\n *\n * For performance reasons, the whole menu structure is created only when `DropdownMenuRootListView` is rendered for the first time.\n *\n * It is recommended to use this class together with {@link module:ui/dropdown/utils~addMenuToDropdown `addMenuToDropdown()` helper}.\n */ class DropdownMenuRootListView extends DropdownMenuListView {\n    /**\n\t * The definitions object used to create the whole menu structure.\n\t */ _definition;\n    /**\n\t * Cached array of all menus in the dropdown menu (including nested menus).\n\t */ _cachedMenus = [];\n    /**\n\t * Cached array of all buttons in the dropdown menu (including buttons in nested menus).\n\t */ _cachedButtons = [];\n    /**\n\t * Editor body collection into which nested menus panels will be appended.\n\t */ _bodyCollection;\n    /**\n\t * Creates an instance of the DropdownMenuRootListView class.\n\t *\n\t * @param locale\n\t * @param bodyCollection\n\t * @param definition The definition object used to create the menu structure.\n\t */ constructor(locale, bodyCollection, definition){\n        super(locale);\n        this._bodyCollection = bodyCollection;\n        this._definition = definition;\n        this.set('menuPanelClass', undefined);\n    }\n    /**\n\t * Returns the array of all menus in the dropdown menu (including nested menus).\n\t */ get menus() {\n        return Array.from(this._cachedMenus.values());\n    }\n    /**\n\t * Returns the array of all buttons in the dropdown menu (including buttons in nested menus).\n\t *\n\t * Note, that this includes only \"leaf\" buttons, as specified in the definition passed in constructor. Buttons created as a part of\n\t * the nested menus, that open nested menus when hovered or pressed, are not included.\n\t */ get buttons() {\n        return Array.from(this._cachedButtons.values());\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        this._createStructure(this._definition, null);\n        super.render();\n        DropdownRootMenuBehaviors.toggleMenusAndFocusItemsOnHover(this);\n        DropdownRootMenuBehaviors.closeMenuWhenAnotherOnTheSameLevelOpens(this);\n    }\n    /**\n\t * Closes all nested menus.\n\t */ closeMenus() {\n        this.menus.forEach((menu)=>{\n            menu.isOpen = false;\n        });\n    }\n    /**\n\t * Recursively creates the whole view tree structure for the dropdown menu, according to the passed `definitions`.\n\t *\n\t * @private\n\t */ _createStructure(definitions, parentMenuView) {\n        const items = [];\n        for (const def of definitions){\n            let createdView;\n            if ('menu' in def) {\n                createdView = new DropdownMenuNestedMenuView(this.locale, this._bodyCollection, def.id, def.menu, parentMenuView);\n                createdView.panelView.bind('class').to(this, 'menuPanelClass');\n                if (!parentMenuView) {\n                    createdView.delegate(...DropdownMenuNestedMenuView.DELEGATED_EVENTS).to(this, (name)=>`menu:${name}`);\n                }\n                this._cachedMenus.push(createdView);\n                this._createStructure(def.children, createdView);\n            } else {\n                createdView = new DropdownMenuListItemButtonView(this.locale, def.id, def.label);\n                if (!parentMenuView) {\n                    createdView.delegate('execute').to(this, 'menu:execute');\n                }\n                this._cachedButtons.push(createdView);\n            }\n            const listItemView = new DropdownMenuListItemView(this.locale, parentMenuView, createdView);\n            if (!parentMenuView) {\n                listItemView.delegate('mouseenter').to(this, 'menu:mouseenter');\n            }\n            items.push(listItemView);\n        }\n        const targetListView = parentMenuView ? parentMenuView.listView : this;\n        targetListView.items.addMany(items);\n    }\n}\n\n/**\n * The toolbar separator view class.\n */ class ToolbarSeparatorView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-toolbar__separator'\n                ]\n            }\n        });\n    }\n}\n\n/**\n * The toolbar line break view class.\n */ class ToolbarLineBreakView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-toolbar__line-break'\n                ]\n            }\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/bindings/preventdefault\n */ /**\n * A helper which executes a native `Event.preventDefault()` if the target of an event equals the\n * {@link module:ui/view~View#element element of the view}. It shortens the definition of a\n * {@link module:ui/view~View#template template}.\n *\n * ```ts\n * // In a class extending View.\n * import preventDefault from '@ckeditor/ckeditor5-ui/src/bindings/preventdefault';\n *\n * // ...\n *\n * this.setTemplate( {\n * \ttag: 'div',\n *\n * \ton: {\n * \t\t// Prevent the default mousedown action on this view.\n * \t\tmousedown: preventDefault( this )\n * \t}\n * } );\n * ```\n *\n * @param view View instance that defines the template.\n */ function preventDefault(view) {\n    return view.bindTemplate.to((evt)=>{\n        if (evt.target === view.element) {\n            evt.preventDefault();\n        }\n    });\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/toolbar/normalizetoolbarconfig\n */ /**\n * Normalizes the toolbar configuration (`config.toolbar`), which:\n *\n * * may be defined as an `Array`:\n *\n * ```\n * toolbar: [ 'heading', 'bold', 'italic', 'link', ... ]\n * ```\n *\n * * or an `Object`:\n *\n * ```\n * toolbar: {\n * \titems: [ 'heading', 'bold', 'italic', 'link', ... ],\n * \tremoveItems: [ 'bold' ],\n * \t...\n * }\n * ```\n *\n * * or may not be defined at all (`undefined`)\n *\n * and returns it in the object form.\n *\n * @param config The value of `config.toolbar`.\n * @returns A normalized toolbar config object.\n */ function normalizeToolbarConfig(config) {\n    if (Array.isArray(config)) {\n        return {\n            items: config,\n            removeItems: []\n        };\n    }\n    const predefinedConfigOptions = {\n        items: [],\n        removeItems: []\n    };\n    if (!config) {\n        return predefinedConfigOptions;\n    }\n    return {\n        ...predefinedConfigOptions,\n        ...config\n    };\n}\n\nconst NESTED_TOOLBAR_ICONS = /* #__PURE__ */ (()=>({\n        alignLeft: icons.alignLeft,\n        bold: icons.bold,\n        importExport: icons.importExport,\n        paragraph: icons.paragraph,\n        plus: icons.plus,\n        text: icons.text,\n        threeVerticalDots: icons.threeVerticalDots,\n        pilcrow: icons.pilcrow,\n        dragIndicator: icons.dragIndicator\n    }))();\n/**\n * The toolbar view class.\n */ class ToolbarView extends View {\n    /**\n\t * A reference to the options object passed to the constructor.\n\t */ options;\n    /**\n\t * A collection of toolbar items (buttons, dropdowns, etc.).\n\t */ items;\n    /**\n\t * Tracks information about the DOM focus in the toolbar.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}\n\t * to handle keyboard navigation in the toolbar.\n\t */ keystrokes;\n    /**\n\t * A (child) view containing {@link #items toolbar items}.\n\t */ itemsView;\n    /**\n\t * A top–level collection aggregating building blocks of the toolbar.\n\t *\n\t *\t┌───────────────── ToolbarView ─────────────────┐\n\t *\t| ┌──────────────── #children ────────────────┐ |\n\t *\t| |   ┌──────────── #itemsView ───────────┐   | |\n\t *\t| |   | [ item1 ] [ item2 ] ... [ itemN ] |   | |\n\t *\t| |   └──────────────────────────────────-┘   | |\n\t *\t| └───────────────────────────────────────────┘ |\n\t *\t└───────────────────────────────────────────────┘\n\t *\n\t * By default, it contains the {@link #itemsView} but it can be extended with additional\n\t * UI elements when necessary.\n\t */ children;\n    /**\n\t * A collection of {@link #items} that take part in the focus cycling\n\t * (i.e. navigation using the keyboard). Usually, it contains a subset of {@link #items} with\n\t * some optional UI elements that also belong to the toolbar and should be focusable\n\t * by the user.\n\t */ focusables;\n    /**\n\t * Helps cycling over {@link #focusables focusable items} in the toolbar.\n\t */ _focusCycler;\n    /**\n\t * An instance of the active toolbar behavior that shapes its look and functionality.\n\t *\n\t * See {@link module:ui/toolbar/toolbarview~ToolbarBehavior} to learn more.\n\t */ _behavior;\n    /**\n\t * Creates an instance of the {@link module:ui/toolbar/toolbarview~ToolbarView} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param options Configuration options of the toolbar.\n\t */ constructor(locale, options){\n        super(locale);\n        const bind = this.bindTemplate;\n        const t = this.t;\n        this.options = options || {};\n        this.set('ariaLabel', t('Editor toolbar'));\n        this.set('maxWidth', 'auto');\n        this.items = this.createCollection();\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.set('class', undefined);\n        this.set('isCompact', false);\n        this.itemsView = new ItemsView(locale);\n        this.children = this.createCollection();\n        this.children.add(this.itemsView);\n        this.focusables = this.createCollection();\n        const isRtl = locale.uiLanguageDirection === 'rtl';\n        this._focusCycler = new FocusCycler({\n            focusables: this.focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate toolbar items backwards using the arrow[left,up] keys.\n                focusPrevious: [\n                    isRtl ? 'arrowright' : 'arrowleft',\n                    'arrowup'\n                ],\n                // Navigate toolbar items forwards using the arrow[right,down] keys.\n                focusNext: [\n                    isRtl ? 'arrowleft' : 'arrowright',\n                    'arrowdown'\n                ]\n            }\n        });\n        const classes = [\n            'ck',\n            'ck-toolbar',\n            bind.to('class'),\n            bind.if('isCompact', 'ck-toolbar_compact')\n        ];\n        if (this.options.shouldGroupWhenFull && this.options.isFloating) {\n            classes.push('ck-toolbar_floating');\n        }\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: classes,\n                role: 'toolbar',\n                'aria-label': bind.to('ariaLabel'),\n                style: {\n                    maxWidth: bind.to('maxWidth')\n                },\n                tabindex: -1\n            },\n            children: this.children,\n            on: {\n                // https://github.com/ckeditor/ckeditor5-ui/issues/206\n                mousedown: preventDefault(this)\n            }\n        });\n        this._behavior = this.options.shouldGroupWhenFull ? new DynamicGrouping(this) : new StaticLayout(this);\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.focusTracker.add(this.element);\n        // Children added before rendering should be known to the #focusTracker.\n        for (const item of this.items){\n            this.focusTracker.add(item);\n        }\n        this.items.on('add', (evt, item)=>{\n            this.focusTracker.add(item);\n        });\n        this.items.on('remove', (evt, item)=>{\n            this.focusTracker.remove(item);\n        });\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n        this._behavior.render(this);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this._behavior.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n        return super.destroy();\n    }\n    /**\n\t * Focuses the first focusable in {@link #focusables}.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Focuses the last focusable in {@link #focusables}.\n\t */ focusLast() {\n        this._focusCycler.focusLast();\n    }\n    /**\n\t * A utility that expands the plain toolbar configuration into\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.\n\t *\n\t * @param itemsOrConfig The toolbar items or the entire toolbar configuration object.\n\t * @param factory A factory producing toolbar items.\n\t * @param removeItems An array of items names to be removed from the configuration. When present, applies\n\t * to this toolbar and all nested ones as well.\n\t */ fillFromConfig(itemsOrConfig, factory, removeItems) {\n        this.items.addMany(this._buildItemsFromConfig(itemsOrConfig, factory, removeItems));\n    }\n    /**\n\t * A utility that expands the plain toolbar configuration into a list of view items using a given component factory.\n\t *\n\t * @param itemsOrConfig The toolbar items or the entire toolbar configuration object.\n\t * @param factory A factory producing toolbar items.\n\t * @param removeItems An array of items names to be removed from the configuration. When present, applies\n\t * to this toolbar and all nested ones as well.\n\t */ _buildItemsFromConfig(itemsOrConfig, factory, removeItems) {\n        const config = normalizeToolbarConfig(itemsOrConfig);\n        const normalizedRemoveItems = removeItems || config.removeItems;\n        const itemsToAdd = this._cleanItemsConfiguration(config.items, factory, normalizedRemoveItems).map((item)=>{\n            if (isObject(item)) {\n                return this._createNestedToolbarDropdown(item, factory, normalizedRemoveItems);\n            } else if (item === '|') {\n                return new ToolbarSeparatorView();\n            } else if (item === '-') {\n                return new ToolbarLineBreakView();\n            }\n            return factory.create(item);\n        }).filter((item)=>!!item);\n        return itemsToAdd;\n    }\n    /**\n\t * Cleans up the {@link module:ui/toolbar/toolbarview~ToolbarView#items} of the toolbar by removing unwanted items and\n\t * duplicated (obsolete) separators or line breaks.\n\t *\n\t * @param items The toolbar items configuration.\n\t * @param factory A factory producing toolbar items.\n\t * @param removeItems An array of items names to be removed from the configuration.\n\t * @returns Items after the clean-up.\n\t */ _cleanItemsConfiguration(items, factory, removeItems) {\n        const filteredItems = items.filter((item, idx, items)=>{\n            if (item === '|') {\n                return true;\n            }\n            // Items listed in `config.removeItems` should not be added to the toolbar.\n            if (removeItems.indexOf(item) !== -1) {\n                return false;\n            }\n            if (item === '-') {\n                // The toolbar line breaks must not be rendered when toolbar grouping is enabled.\n                // (https://github.com/ckeditor/ckeditor5/issues/8582)\n                if (this.options.shouldGroupWhenFull) {\n                    /**\n\t\t\t\t\t\t * The toolbar multiline breaks (`-` items) only work when the automatic button grouping\n\t\t\t\t\t\t * is disabled in the toolbar configuration.\n\t\t\t\t\t\t * To do this, set the `shouldNotGroupWhenFull` option to `true` in the editor configuration:\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * ```ts\n\t\t\t\t\t\t * const config = {\n\t\t\t\t\t\t * \ttoolbar: {\n\t\t\t\t\t\t * \t\titems: [ ... ],\n\t\t\t\t\t\t * \t\tshouldNotGroupWhenFull: true\n\t\t\t\t\t\t * \t}\n\t\t\t\t\t\t * }\n\t\t\t\t\t\t * ```\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Learn more about {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * @error toolbarview-line-break-ignored-when-grouping-items\n\t\t\t\t\t\t */ logWarning('toolbarview-line-break-ignored-when-grouping-items', items);\n                    return false;\n                }\n                return true;\n            }\n            // For the items that cannot be instantiated we are sending warning message. We also filter them out.\n            if (!isObject(item) && !factory.has(item)) {\n                /**\n\t\t\t\t\t * There was a problem processing the configuration of the toolbar. The item with the given\n\t\t\t\t\t * name does not exist so it was omitted when rendering the toolbar.\n\t\t\t\t\t *\n\t\t\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t\t\t * to provide a toolbar item has not been loaded or there is a typo in the\n\t\t\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.\n\t\t\t\t\t *\n\t\t\t\t\t * Make sure the plugin responsible for this toolbar item is loaded and the toolbar configuration\n\t\t\t\t\t * is correct, e.g. {@link module:basic-styles/bold~Bold} is loaded for the `'bold'` toolbar item.\n\t\t\t\t\t *\n\t\t\t\t\t * You can use the following snippet to retrieve all available toolbar items:\n\t\t\t\t\t *\n\t\t\t\t\t * ```ts\n\t\t\t\t\t * Array.from( editor.ui.componentFactory.names() );\n\t\t\t\t\t * ```\n\t\t\t\t\t *\n\t\t\t\t\t * @error toolbarview-item-unavailable\n\t\t\t\t\t * @param item The name of the component or nested toolbar definition.\n\t\t\t\t\t */ logWarning('toolbarview-item-unavailable', {\n                    item\n                });\n                return false;\n            }\n            return true;\n        });\n        return this._cleanSeparatorsAndLineBreaks(filteredItems);\n    }\n    /**\n\t * Remove leading, trailing, and duplicated separators (`-` and `|`).\n\t *\n\t * @returns Toolbar items after the separator and line break clean-up.\n\t */ _cleanSeparatorsAndLineBreaks(items) {\n        const nonSeparatorPredicate = (item)=>item !== '-' && item !== '|';\n        const count = items.length;\n        // Find an index of the first item that is not a separator.\n        const firstCommandItemIndex = items.findIndex(nonSeparatorPredicate);\n        // Items include separators only. There is no point in displaying them.\n        if (firstCommandItemIndex === -1) {\n            return [];\n        }\n        // Search from the end of the list, then convert found index back to the original direction.\n        const lastCommandItemIndex = count - items.slice().reverse().findIndex(nonSeparatorPredicate);\n        return items// Return items without the leading and trailing separators.\n        .slice(firstCommandItemIndex, lastCommandItemIndex)// Remove duplicated separators.\n        .filter((name, idx, items)=>{\n            // Filter only separators.\n            if (nonSeparatorPredicate(name)) {\n                return true;\n            }\n            const isDuplicated = idx > 0 && items[idx - 1] === name;\n            return !isDuplicated;\n        });\n    }\n    /**\n\t * Creates a user-defined dropdown containing a toolbar with items.\n\t *\n\t * @param definition A definition of the nested toolbar dropdown.\n\t * @param definition.label A label of the dropdown.\n\t * @param definition.icon An icon of the drop-down. One of 'bold', 'plus', 'text', 'importExport', 'alignLeft',\n\t * 'paragraph' or an SVG string. When `false` is passed, no icon will be used.\n\t * @param definition.withText When set `true`, the label of the dropdown will be visible. See\n\t * {@link module:ui/button/buttonview~ButtonView#withText} to learn more.\n\t * @param definition.tooltip A tooltip of the dropdown button. See\n\t * {@link module:ui/button/buttonview~ButtonView#tooltip} to learn more. Defaults to `true`.\n\t * @param componentFactory Component factory used to create items\n\t * of the nested toolbar.\n\t */ _createNestedToolbarDropdown(definition, componentFactory, removeItems) {\n        let { label, icon, items, tooltip = true, withText = false } = definition;\n        items = this._cleanItemsConfiguration(items, componentFactory, removeItems);\n        // There is no point in rendering a dropdown without items.\n        if (!items.length) {\n            return null;\n        }\n        const locale = this.locale;\n        const dropdownView = createDropdown(locale);\n        if (!label) {\n            /**\n\t\t\t * A dropdown definition in the toolbar configuration is missing a text label.\n\t\t\t *\n\t\t\t * Without a label, the dropdown becomes inaccessible to users relying on assistive technologies.\n\t\t\t * Make sure the `label` property is set in your drop-down configuration:\n\t\t\t *\n\t\t\t * ```json\n \t\t\t * {\n \t\t\t * \tlabel: 'A human-readable label',\n\t\t\t * \ticon: '...',\n\t\t\t * \titems: [ ... ]\n \t\t\t * },\n\t\t\t * ```\n\t\t\t *\n\t\t\t * Learn more about {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.\n\t\t\t *\n\t\t\t * @error toolbarview-nested-toolbar-dropdown-missing-label\n\t\t\t */ logWarning('toolbarview-nested-toolbar-dropdown-missing-label', definition);\n        }\n        dropdownView.class = 'ck-toolbar__nested-toolbar-dropdown';\n        dropdownView.buttonView.set({\n            label,\n            tooltip,\n            withText: !!withText\n        });\n        // Allow disabling icon by passing false.\n        if (icon !== false) {\n            // A pre-defined icon picked by name, SVG string, a fallback (default) icon.\n            dropdownView.buttonView.icon = NESTED_TOOLBAR_ICONS[icon] || icon || icons.threeVerticalDots;\n        } else {\n            dropdownView.buttonView.withText = true;\n        }\n        addToolbarToDropdown(dropdownView, ()=>dropdownView.toolbarView._buildItemsFromConfig(items, componentFactory, removeItems));\n        return dropdownView;\n    }\n}\n/**\n * An inner block of the {@link module:ui/toolbar/toolbarview~ToolbarView} hosting its\n * {@link module:ui/toolbar/toolbarview~ToolbarView#items}.\n */ class ItemsView extends View {\n    /**\n\t * A collection of items (buttons, dropdowns, etc.).\n\t */ children;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.children = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-toolbar__items'\n                ]\n            },\n            children: this.children\n        });\n    }\n}\n/**\n * A toolbar behavior that makes it static and unresponsive to the changes of the environment.\n * At the same time, it also makes it possible to display a toolbar with a vertical layout\n * using the {@link module:ui/toolbar/toolbarview~ToolbarView#isVertical} property.\n */ class StaticLayout {\n    /**\n\t * Creates an instance of the {@link module:ui/toolbar/toolbarview~StaticLayout} toolbar\n\t * behavior.\n\t *\n\t * @param view An instance of the toolbar that this behavior is added to.\n\t */ constructor(view){\n        const bind = view.bindTemplate;\n        // Static toolbar can be vertical when needed.\n        view.set('isVertical', false);\n        // 1:1 pass–through binding, all ToolbarView#items are visible.\n        view.itemsView.children.bindTo(view.items).using((item)=>item);\n        // 1:1 pass–through binding, all ToolbarView#items are focusable.\n        view.focusables.bindTo(view.items).using((item)=>isFocusable(item) ? item : null);\n        view.extendTemplate({\n            attributes: {\n                class: [\n                    // When vertical, the toolbar has an additional CSS class.\n                    bind.if('isVertical', 'ck-toolbar_vertical')\n                ]\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {}\n    /**\n\t * @inheritDoc\n\t */ destroy() {}\n}\n/**\n * A toolbar behavior that makes the items respond to changes in the geometry.\n *\n * In a nutshell, it groups {@link module:ui/toolbar/toolbarview~ToolbarView#items}\n * that do not fit visually into a single row of the toolbar (due to limited space).\n * Items that do not fit are aggregated in a dropdown displayed at the end of the toolbar.\n *\n * ```\n *\t┌──────────────────────────────────────── ToolbarView ──────────────────────────────────────────┐\n *\t| ┌─────────────────────────────────────── #children ─────────────────────────────────────────┐ |\n *\t| |   ┌─────── #itemsView ────────┐ ┌──────────────────────┐ ┌── #groupedItemsDropdown ───┐   | |\n *\t| |   |       #ungroupedItems     | | ToolbarSeparatorView | |        #groupedItems       |   | |\n *\t| |   └──────────────────────────-┘ └──────────────────────┘ └────────────────────────────┘   | |\n *\t| |                                  \\---------- only when toolbar items overflow -------/    | |\n *\t| └───────────────────────────────────────────────────────────────────────────────────────────┘ |\n *\t└───────────────────────────────────────────────────────────────────────────────────────────────┘\n * ```\n */ class DynamicGrouping {\n    /**\n\t * A toolbar view this behavior belongs to.\n\t */ view;\n    /**\n\t * A collection of toolbar children.\n\t */ viewChildren;\n    /**\n\t * A collection of focusable toolbar elements.\n\t */ viewFocusables;\n    /**\n\t * A view containing toolbar items.\n\t */ viewItemsView;\n    /**\n\t * Toolbar focus tracker.\n\t */ viewFocusTracker;\n    /**\n\t * Toolbar locale.\n\t */ viewLocale;\n    /**\n\t * A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.\n\t * Aggregates items that fit into a single row of the toolbar and were not {@link #groupedItems grouped}\n\t * into a {@link #groupedItemsDropdown dropdown}. Items of this collection are displayed in the\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#itemsView}.\n\t *\n\t * When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped, it\n\t * matches the {@link module:ui/toolbar/toolbarview~ToolbarView#items} collection in size and order.\n\t */ ungroupedItems;\n    /**\n\t * A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.\n\t * A collection of the toolbar items that do not fit into a single row of the toolbar.\n\t * Grouped items are displayed in a dedicated {@link #groupedItemsDropdown dropdown}.\n\t *\n\t * When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped,\n\t * this collection is empty.\n\t */ groupedItems;\n    /**\n\t * The dropdown that aggregates {@link #groupedItems grouped items} that do not fit into a single\n\t * row of the toolbar. It is displayed on demand as the last of\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#children toolbar children} and offers another\n\t * (nested) toolbar which displays items that would normally overflow.\n\t */ groupedItemsDropdown;\n    /**\n\t * An instance of the resize observer that helps dynamically determine the geometry of the toolbar\n\t * and manage items that do not fit into a single row.\n\t *\n\t * **Note:** Created in {@link #_enableGroupingOnResize}.\n\t *\n\t * @readonly\n\t */ resizeObserver = null;\n    /**\n\t * A cached value of the horizontal padding style used by {@link #_updateGrouping}\n\t * to manage the {@link module:ui/toolbar/toolbarview~ToolbarView#items} that do not fit into\n\t * a single toolbar line. This value can be reused between updates because it is unlikely that\n\t * the padding will change and re–using `Window.getComputedStyle()` is expensive.\n\t *\n\t * @readonly\n\t */ cachedPadding = null;\n    /**\n\t * A flag indicating that an items grouping update has been queued (e.g. due to the toolbar being visible)\n\t * and should be executed immediately the next time the toolbar shows up.\n\t *\n\t * @readonly\n\t */ shouldUpdateGroupingOnNextResize = false;\n    /**\n\t * Toolbar element.\n\t *\n\t * @readonly\n\t */ viewElement;\n    /**\n\t * Creates an instance of the {@link module:ui/toolbar/toolbarview~DynamicGrouping} toolbar\n\t * behavior.\n\t *\n\t * @param view An instance of the toolbar that this behavior is added to.\n\t */ constructor(view){\n        this.view = view;\n        this.viewChildren = view.children;\n        this.viewFocusables = view.focusables;\n        this.viewItemsView = view.itemsView;\n        this.viewFocusTracker = view.focusTracker;\n        this.viewLocale = view.locale;\n        this.ungroupedItems = view.createCollection();\n        this.groupedItems = view.createCollection();\n        this.groupedItemsDropdown = this._createGroupedItemsDropdown();\n        // Only those items that were not grouped are visible to the user.\n        view.itemsView.children.bindTo(this.ungroupedItems).using((item)=>item);\n        // Make sure all #items visible in the main space of the toolbar are \"focuscyclable\".\n        this.ungroupedItems.on('change', this._updateFocusCyclableItems.bind(this));\n        // Make sure the #groupedItemsDropdown is also included in cycling when it appears.\n        view.children.on('change', this._updateFocusCyclableItems.bind(this));\n        // ToolbarView#items is dynamic. When an item is added or removed, it should be automatically\n        // represented in either grouped or ungrouped items at the right index.\n        // In other words #items == concat( #ungroupedItems, #groupedItems )\n        // (in length and order).\n        view.items.on('change', (evt, changeData)=>{\n            const index = changeData.index;\n            const added = Array.from(changeData.added);\n            // Removing.\n            for (const removedItem of changeData.removed){\n                if (index >= this.ungroupedItems.length) {\n                    this.groupedItems.remove(removedItem);\n                } else {\n                    this.ungroupedItems.remove(removedItem);\n                }\n            }\n            // Adding.\n            for(let currentIndex = index; currentIndex < index + added.length; currentIndex++){\n                const addedItem = added[currentIndex - index];\n                if (currentIndex > this.ungroupedItems.length) {\n                    this.groupedItems.add(addedItem, currentIndex - this.ungroupedItems.length);\n                } else {\n                    this.ungroupedItems.add(addedItem, currentIndex);\n                }\n            }\n            // When new ungrouped items join in and land in #ungroupedItems, there's a chance it causes\n            // the toolbar to overflow.\n            // Consequently if removed from grouped or ungrouped items, there is a chance\n            // some new space is available and we could do some ungrouping.\n            this._updateGrouping();\n        });\n        view.extendTemplate({\n            attributes: {\n                class: [\n                    // To group items dynamically, the toolbar needs a dedicated CSS class.\n                    'ck-toolbar_grouping'\n                ]\n            }\n        });\n    }\n    /**\n\t * Enables dynamic items grouping based on the dimensions of the toolbar.\n\t *\n\t * @param view An instance of the toolbar that this behavior is added to.\n\t */ render(view) {\n        this.viewElement = view.element;\n        this._enableGroupingOnResize();\n        this._enableGroupingOnMaxWidthChange(view);\n    }\n    /**\n\t * Cleans up the internals used by this behavior.\n\t */ destroy() {\n        // The dropdown may not be in ToolbarView#children at the moment of toolbar destruction\n        // so let's make sure it's actually destroyed along with the toolbar.\n        this.groupedItemsDropdown.destroy();\n        this.resizeObserver.destroy();\n    }\n    /**\n\t * When called, it will check if any of the {@link #ungroupedItems} do not fit into a single row of the toolbar,\n\t * and it will move them to the {@link #groupedItems} when it happens.\n\t *\n\t * At the same time, it will also check if there is enough space in the toolbar for the first of the\n\t * {@link #groupedItems} to be returned back to {@link #ungroupedItems} and still fit into a single row\n\t * without the toolbar wrapping.\n\t */ _updateGrouping() {\n        // Do no grouping–related geometry analysis when the toolbar is detached from visible DOM,\n        // for instance before #render(), or after render but without a parent or a parent detached\n        // from DOM. DOMRects won't work anyway and there will be tons of warning in the console and\n        // nothing else. This happens, for instance, when the toolbar is detached from DOM and\n        // some logic adds or removes its #items.\n        if (!this.viewElement.ownerDocument.body.contains(this.viewElement)) {\n            return;\n        }\n        // Do not update grouping when the element is invisible. Such toolbar has DOMRect filled with zeros\n        // and that would cause all items to be grouped. Instead, queue the grouping so it runs next time\n        // the toolbar is visible (the next ResizeObserver callback execution). This is handy because\n        // the grouping could be caused by increasing the #maxWidth when the toolbar was invisible and the next\n        // time it shows up, some items could actually be ungrouped (https://github.com/ckeditor/ckeditor5/issues/6575).\n        if (!isVisible(this.viewElement)) {\n            this.shouldUpdateGroupingOnNextResize = true;\n            return;\n        }\n        // Remember how many items were initially grouped so at the it is possible to figure out if the number\n        // of grouped items has changed. If the number has changed, geometry of the toolbar has also changed.\n        const initialGroupedItemsCount = this.groupedItems.length;\n        let wereItemsGrouped;\n        // Group #items as long as some wrap to the next row. This will happen, for instance,\n        // when the toolbar is getting narrow and there is not enough space to display all items in\n        // a single row.\n        while(this._areItemsOverflowing){\n            this._groupLastItem();\n            wereItemsGrouped = true;\n        }\n        // If none were grouped now but there were some items already grouped before,\n        // then, what the hell, maybe let's see if some of them can be ungrouped. This happens when,\n        // for instance, the toolbar is stretching and there's more space in it than before.\n        if (!wereItemsGrouped && this.groupedItems.length) {\n            // Ungroup items as long as none are overflowing or there are none to ungroup left.\n            while(this.groupedItems.length && !this._areItemsOverflowing){\n                this._ungroupFirstItem();\n            }\n            // If the ungrouping ended up with some item wrapping to the next row,\n            // put it back to the group toolbar (\"undo the last ungroup\"). We don't know whether\n            // an item will wrap or not until we ungroup it (that's a DOM/CSS thing) so this\n            // clean–up is vital for the algorithm.\n            if (this._areItemsOverflowing) {\n                this._groupLastItem();\n            }\n        }\n        if (this.groupedItems.length !== initialGroupedItemsCount) {\n            this.view.fire('groupedItemsUpdate');\n        }\n    }\n    /**\n\t * Returns `true` when {@link module:ui/toolbar/toolbarview~ToolbarView#element} children visually overflow,\n\t * for instance if the toolbar is narrower than its members. Returns `false` otherwise.\n\t */ get _areItemsOverflowing() {\n        // An empty toolbar cannot overflow.\n        if (!this.ungroupedItems.length) {\n            return false;\n        }\n        const element = this.viewElement;\n        const uiLanguageDirection = this.viewLocale.uiLanguageDirection;\n        const lastChildRect = new Rect(element.lastChild);\n        const toolbarRect = new Rect(element);\n        if (!this.cachedPadding) {\n            const computedStyle = global.window.getComputedStyle(element);\n            const paddingProperty = uiLanguageDirection === 'ltr' ? 'paddingRight' : 'paddingLeft';\n            // parseInt() is essential because of quirky floating point numbers logic and DOM.\n            // If the padding turned out too big because of that, the grouped items dropdown would\n            // always look (from the Rect perspective) like it overflows (while it's not).\n            this.cachedPadding = Number.parseInt(computedStyle[paddingProperty]);\n        }\n        if (uiLanguageDirection === 'ltr') {\n            return lastChildRect.right > toolbarRect.right - this.cachedPadding;\n        } else {\n            return lastChildRect.left < toolbarRect.left + this.cachedPadding;\n        }\n    }\n    /**\n\t * Enables the functionality that prevents {@link #ungroupedItems} from overflowing (wrapping to the next row)\n\t * upon resize when there is little space available. Instead, the toolbar items are moved to the\n\t * {@link #groupedItems} collection and displayed in a dropdown at the end of the row (which has its own nested toolbar).\n\t *\n\t * When called, the toolbar will automatically analyze the location of its {@link #ungroupedItems} and \"group\"\n\t * them in the dropdown if necessary. It will also observe the browser window for size changes in\n\t * the future and respond to them by grouping more items or reverting already grouped back, depending\n\t * on the visual space available.\n\t */ _enableGroupingOnResize() {\n        let previousWidth;\n        // TODO: Consider debounce.\n        this.resizeObserver = new ResizeObserver(this.viewElement, (entry)=>{\n            if (!previousWidth || previousWidth !== entry.contentRect.width || this.shouldUpdateGroupingOnNextResize) {\n                this.shouldUpdateGroupingOnNextResize = false;\n                this._updateGrouping();\n                previousWidth = entry.contentRect.width;\n            }\n        });\n        this._updateGrouping();\n    }\n    /**\n\t * Enables the grouping functionality, just like {@link #_enableGroupingOnResize} but the difference is that\n\t * it listens to the changes of {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth} instead.\n\t */ _enableGroupingOnMaxWidthChange(view) {\n        view.on('change:maxWidth', ()=>{\n            this._updateGrouping();\n        });\n    }\n    /**\n\t * When called, it will remove the last item from {@link #ungroupedItems} and move it back\n\t * to the {@link #groupedItems} collection.\n\t *\n\t * The opposite of {@link #_ungroupFirstItem}.\n\t */ _groupLastItem() {\n        if (!this.groupedItems.length) {\n            this.viewChildren.add(new ToolbarSeparatorView());\n            this.viewChildren.add(this.groupedItemsDropdown);\n            this.viewFocusTracker.add(this.groupedItemsDropdown.element);\n        }\n        this.groupedItems.add(this.ungroupedItems.remove(this.ungroupedItems.last), 0);\n    }\n    /**\n\t * Moves the very first item belonging to {@link #groupedItems} back\n\t * to the {@link #ungroupedItems} collection.\n\t *\n\t * The opposite of {@link #_groupLastItem}.\n\t */ _ungroupFirstItem() {\n        this.ungroupedItems.add(this.groupedItems.remove(this.groupedItems.first));\n        if (!this.groupedItems.length) {\n            this.viewChildren.remove(this.groupedItemsDropdown);\n            this.viewChildren.remove(this.viewChildren.last);\n            this.viewFocusTracker.remove(this.groupedItemsDropdown.element);\n        }\n    }\n    /**\n\t * Creates the {@link #groupedItemsDropdown} that hosts the members of the {@link #groupedItems}\n\t * collection when there is not enough space in the toolbar to display all items in a single row.\n\t */ _createGroupedItemsDropdown() {\n        const locale = this.viewLocale;\n        const t = locale.t;\n        const dropdown = createDropdown(locale);\n        dropdown.class = 'ck-toolbar__grouped-dropdown';\n        // Make sure the dropdown never sticks out to the left/right. It should be under the main toolbar.\n        // (https://github.com/ckeditor/ckeditor5/issues/5608)\n        dropdown.panelPosition = locale.uiLanguageDirection === 'ltr' ? 'sw' : 'se';\n        addToolbarToDropdown(dropdown, this.groupedItems);\n        dropdown.buttonView.set({\n            label: t('Show more items'),\n            tooltip: true,\n            tooltipPosition: locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw',\n            icon: icons.threeVerticalDots\n        });\n        return dropdown;\n    }\n    /**\n\t * Updates the {@link module:ui/toolbar/toolbarview~ToolbarView#focusables focus–cyclable items}\n\t * collection so it represents the up–to–date state of the UI from the perspective of the user.\n\t *\n\t * For instance, the {@link #groupedItemsDropdown} can show up and hide but when it is visible,\n\t * it must be subject to focus cycling in the toolbar.\n\t *\n\t * See the {@link module:ui/toolbar/toolbarview~ToolbarView#focusables collection} documentation\n\t * to learn more about the purpose of this method.\n\t */ _updateFocusCyclableItems() {\n        this.viewFocusables.clear();\n        this.ungroupedItems.map((item)=>{\n            if (isFocusable(item)) {\n                this.viewFocusables.add(item);\n            }\n        });\n        if (this.groupedItems.length) {\n            this.viewFocusables.add(this.groupedItemsDropdown);\n        }\n    }\n}\n\n/**\n * The split button view class.\n *\n * ```ts\n * const view = new SplitButtonView();\n *\n * view.set( {\n * \tlabel: 'A button',\n * \tkeystroke: 'Ctrl+B',\n * \ttooltip: true\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n *\n * Also see the {@link module:ui/dropdown/utils~createDropdown `createDropdown()` util}.\n */ class SplitButtonView extends View {\n    /**\n\t * Collection of the child views inside of the split button {@link #element}.\n\t */ children;\n    /**\n\t * A main button of split button.\n\t */ actionView;\n    /**\n\t * A secondary button of split button that opens dropdown.\n\t */ arrowView;\n    /**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the split button:\n\t *\n\t * * <kbd>▶</kbd> moves focus to arrow view when action view is focused,\n\t * * <kbd>◀</kbd> moves focus to action view when arrow view is focused.\n\t */ keystrokes;\n    /**\n\t * Tracks information about DOM focus in the dropdown.\n\t */ focusTracker;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, actionButton){\n        super(locale);\n        const bind = this.bindTemplate;\n        // Implement the Button interface.\n        this.set('class', undefined);\n        this.set('labelStyle', undefined);\n        this.set('icon', undefined);\n        this.set('isEnabled', true);\n        this.set('isOn', false);\n        this.set('isToggleable', false);\n        this.set('isVisible', true);\n        this.set('keystroke', undefined);\n        this.set('withKeystroke', false);\n        this.set('label', undefined);\n        this.set('tabindex', -1);\n        this.set('tooltip', false);\n        this.set('tooltipPosition', 's');\n        this.set('type', 'button');\n        this.set('withText', false);\n        this.children = this.createCollection();\n        this.actionView = this._createActionView(actionButton);\n        this.arrowView = this._createArrowView();\n        this.keystrokes = new KeystrokeHandler();\n        this.focusTracker = new FocusTracker();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-splitbutton',\n                    bind.to('class'),\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value),\n                    this.arrowView.bindTemplate.if('isOn', 'ck-splitbutton_open')\n                ]\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.children.add(this.actionView);\n        this.children.add(this.arrowView);\n        this.focusTracker.add(this.actionView.element);\n        this.focusTracker.add(this.arrowView.element);\n        this.keystrokes.listenTo(this.element);\n        // Overrides toolbar focus cycling behavior.\n        this.keystrokes.set('arrowright', (evt, cancel)=>{\n            if (this.focusTracker.focusedElement === this.actionView.element) {\n                this.arrowView.focus();\n                cancel();\n            }\n        });\n        // Overrides toolbar focus cycling behavior.\n        this.keystrokes.set('arrowleft', (evt, cancel)=>{\n            if (this.focusTracker.focusedElement === this.arrowView.element) {\n                this.actionView.focus();\n                cancel();\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the {@link module:ui/button/buttonview~ButtonView#element} of the action part of split button.\n\t */ focus() {\n        this.actionView.focus();\n    }\n    /**\n\t * Creates a {@link module:ui/button/buttonview~ButtonView} instance as {@link #actionView} and binds it with main split button\n\t * attributes.\n\t */ _createActionView(actionButton) {\n        const actionView = actionButton || new ButtonView();\n        if (!actionButton) {\n            actionView.bind('icon', 'isEnabled', 'isOn', 'isToggleable', 'keystroke', 'label', 'tabindex', 'tooltip', 'tooltipPosition', 'type', 'withText').to(this);\n        }\n        actionView.extendTemplate({\n            attributes: {\n                class: 'ck-splitbutton__action'\n            }\n        });\n        actionView.delegate('execute').to(this);\n        return actionView;\n    }\n    /**\n\t * Creates a {@link module:ui/button/buttonview~ButtonView} instance as {@link #arrowView} and binds it with main split button\n\t * attributes.\n\t */ _createArrowView() {\n        const arrowView = new ButtonView();\n        const bind = arrowView.bindTemplate;\n        arrowView.icon = dropdownArrowIcon;\n        arrowView.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-splitbutton__arrow'\n                ],\n                'data-cke-tooltip-disabled': bind.to('isOn'),\n                'aria-haspopup': true,\n                'aria-expanded': bind.to('isOn', (value)=>String(value))\n            }\n        });\n        arrowView.bind('isEnabled').to(this);\n        arrowView.bind('label').to(this);\n        arrowView.bind('tooltip').to(this);\n        arrowView.delegate('execute').to(this, 'open');\n        return arrowView;\n    }\n}\n\n/**\n * A helper for creating dropdowns. It creates an instance of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown},\n * with a {@link module:ui/dropdown/button/dropdownbutton~DropdownButton button},\n * {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView panel} and all standard dropdown's behaviors.\n *\n * # Creating dropdowns\n *\n * By default, the default {@link module:ui/dropdown/button/dropdownbuttonview~DropdownButtonView} class is used as\n * definition of the button:\n *\n * ```ts\n * const dropdown = createDropdown( model );\n *\n * // Configure dropdown's button properties:\n * dropdown.buttonView.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.render();\n *\n * // Will render a dropdown labeled \"A dropdown\" with an empty panel.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * You can also provide other button views (they need to implement the\n * {@link module:ui/dropdown/button/dropdownbutton~DropdownButton} interface). For instance, you can use\n * {@link module:ui/dropdown/button/splitbuttonview~SplitButtonView} to create a dropdown with a split button.\n *\n * ```ts\n * const dropdown = createDropdown( locale, SplitButtonView );\n *\n * // Configure dropdown's button properties:\n * dropdown.buttonView.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.buttonView.on( 'execute', () => {\n * \t// Add the behavior of the \"action part\" of the split button.\n * \t// Split button consists of the \"action part\" and \"arrow part\".\n * \t// The arrow opens the dropdown while the action part can have some other behavior.\n * } );\n *\n * dropdown.render();\n *\n * // Will render a dropdown labeled \"A dropdown\" with an empty panel.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * # Adding content to the dropdown's panel\n *\n * The content of the panel can be inserted directly into the `dropdown.panelView.element`:\n *\n * ```ts\n * dropdown.panelView.element.textContent = 'Content of the panel';\n * ```\n *\n * However, most of the time you will want to add there either a {@link module:ui/list/listview~ListView list of options}\n * or a list of buttons (i.e. a {@link module:ui/toolbar/toolbarview~ToolbarView toolbar}).\n * To simplify the task, you can use, respectively, {@link module:ui/dropdown/utils~addListToDropdown} or\n * {@link module:ui/dropdown/utils~addToolbarToDropdown} utils.\n *\n * @param locale The locale instance.\n * @param ButtonClassOrInstance The dropdown button view class. Needs to implement the\n * @param behaviorOptions Attributes for the default behavior of the dropdown.\n *\n * {@link module:ui/dropdown/button/dropdownbutton~DropdownButton} interface.\n * @returns The dropdown view instance.\n */ function createDropdown(locale, ButtonClassOrInstance = DropdownButtonView) {\n    const buttonView = typeof ButtonClassOrInstance == 'function' ? new ButtonClassOrInstance(locale) : ButtonClassOrInstance;\n    const panelView = new DropdownPanelView(locale);\n    const dropdownView = new DropdownView(locale, buttonView, panelView);\n    buttonView.bind('isEnabled').to(dropdownView);\n    if (buttonView instanceof SplitButtonView) {\n        buttonView.arrowView.bind('isOn').to(dropdownView, 'isOpen');\n    } else {\n        buttonView.bind('isOn').to(dropdownView, 'isOpen');\n    }\n    addDefaultBehaviors(dropdownView);\n    return dropdownView;\n}\n/**\n * Adds a menu UI component to a dropdown and sets all common behaviors and interactions between the dropdown and the menu.\n *\n * Use this helper to create multi-level dropdown menus that are displayed in a toolbar.\n *\n * Internally, it creates an instance of {@link module:ui/dropdown/menu/dropdownmenurootlistview~DropdownMenuRootListView}.\n *\n * Example:\n *\n * ```ts\n * const definitions = [\n * \t{\n * \t\tid: 'menu_1',\n * \t\tmenu: 'Menu 1',\n * \t\tchildren: [\n * \t\t\t{\n * \t\t\t\tid: 'menu_1_a',\n * \t\t\t\tlabel: 'Item A'\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tid: 'menu_1_b',\n * \t\t\t\tlabel: 'Item B'\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tid: 'top_a',\n * \t\tlabel: 'Top Item A'\n * \t},\n * \t{\n * \t\tid: 'top_b',\n * \t\tlabel: 'Top Item B'\n * \t}\n * ];\n *\n * const dropdownView = createDropdown( editor.locale );\n *\n * addMenuToDropdown( dropdownView, editor.ui.view.body, definitions );\n * ```\n *\n * After using this helper, the `dropdown` will fire {@link module:ui/dropdown/dropdownview~DropdownViewEvent `execute`} event when\n * a nested menu button is pressed.\n *\n * The helper will make sure that the `dropdownMenuRootListView` is lazy loaded, i.e., the menu component structure will be initialized\n * and rendered only after the `dropdown` is opened for the first time.\n *\n * @param dropdownView A dropdown instance to which the menu component will be added.\n * @param body Body collection to which floating menu panels will be added.\n * @param definition The menu component definition.\n * @param options.ariaLabel Label used by assistive technologies to describe the top-level menu.\n */ function addMenuToDropdown(dropdownView, body, definition, options = {}) {\n    dropdownView.menuView = new DropdownMenuRootListView(dropdownView.locale, body, definition);\n    dropdownView.focusTracker.add(dropdownView.menuView);\n    if (dropdownView.isOpen) {\n        addMenuToOpenDropdown(dropdownView, options);\n    } else {\n        // Load the UI elements only after the dropdown is opened for the first time - lazy loading.\n        dropdownView.once('change:isOpen', ()=>{\n            addMenuToOpenDropdown(dropdownView, options);\n        }, {\n            priority: 'highest'\n        });\n    }\n}\nfunction addMenuToOpenDropdown(dropdownView, options) {\n    const dropdownMenuRootListView = dropdownView.menuView;\n    const t = dropdownView.locale.t;\n    dropdownMenuRootListView.delegate('menu:execute').to(dropdownView, 'execute');\n    dropdownMenuRootListView.listenTo(dropdownView, 'change:isOpen', (evt, name, isOpen)=>{\n        if (!isOpen) {\n            dropdownMenuRootListView.closeMenus();\n        }\n    }, {\n        priority: 'low'\n    }); // Make sure this is fired after `focusDropdownButtonOnClose` behavior.\n    // When `dropdownMenuRootListView` is added as a `panelView` child, it becomes rendered (`panelView` is rendered at this point).\n    dropdownView.panelView.children.add(dropdownMenuRootListView);\n    // Nested menu panels are added to body collection, so they are not children of the `dropdownView` from DOM perspective.\n    // Add these panels to `dropdownView` focus tracker, so they are treated like part of the `dropdownView` for focus-related purposes.\n    for (const menu of dropdownMenuRootListView.menus){\n        dropdownView.focusTracker.add(menu);\n    }\n    dropdownMenuRootListView.ariaLabel = options.ariaLabel || t('Dropdown menu');\n}\n/**\n * Adds an instance of {@link module:ui/toolbar/toolbarview~ToolbarView} to a dropdown.\n *\n * ```ts\n * const buttonsCreator = () => {\n * \tconst buttons = [];\n *\n * \t// Either create a new ButtonView instance or create existing.\n * \tbuttons.push( new ButtonView() );\n * \tbuttons.push( editor.ui.componentFactory.create( 'someButton' ) );\n * };\n *\n * const dropdown = createDropdown( locale );\n *\n * addToolbarToDropdown( dropdown, buttonsCreator, { isVertical: true } );\n *\n * // Will render a vertical button dropdown labeled \"A button dropdown\"\n * // with a button group in the panel containing two buttons.\n * // Buttons inside the dropdown will be created on first dropdown panel open.\n * dropdown.render()\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * **Note:** To improve the accessibility, you can tell the dropdown to focus the first active button of the toolbar when the dropdown\n * {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open}. See the documentation of `options` to learn more.\n *\n * **Note:** Toolbar view will be created on first open of the dropdown.\n *\n * See {@link module:ui/dropdown/utils~createDropdown} and {@link module:ui/toolbar/toolbarview~ToolbarView}.\n *\n * @param dropdownView A dropdown instance to which `ToolbarView` will be added.\n * @param options.enableActiveItemFocusOnDropdownOpen When set `true`, the focus will automatically move to the first\n * active {@link module:ui/toolbar/toolbarview~ToolbarView#items item} of the toolbar upon\n * {@link module:ui/dropdown/dropdownview~DropdownView#isOpen opening} the dropdown. Active items are those with the `isOn` property set\n * `true` (for instance {@link module:ui/button/buttonview~ButtonView buttons}). If no active items is found, the toolbar will be focused\n * as a whole resulting in the focus moving to its first focusable item (default behavior of\n * {@link module:ui/dropdown/dropdownview~DropdownView}).\n * @param options.ariaLabel Label used by assistive technologies to describe toolbar element.\n * @param options.maxWidth The maximum width of the toolbar element.\n * Details: {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth}.\n * @param options.class An additional CSS class added to the toolbar element.\n * @param options.isCompact When set true, makes the toolbar look compact with toolbar element.\n * @param options.isVertical Controls the orientation of toolbar items.\n */ function addToolbarToDropdown(dropdownView, buttonsOrCallback, options = {}) {\n    dropdownView.extendTemplate({\n        attributes: {\n            class: [\n                'ck-toolbar-dropdown'\n            ]\n        }\n    });\n    if (dropdownView.isOpen) {\n        addToolbarToOpenDropdown(dropdownView, buttonsOrCallback, options);\n    } else {\n        dropdownView.once('change:isOpen', ()=>addToolbarToOpenDropdown(dropdownView, buttonsOrCallback, options), {\n            priority: 'highest'\n        });\n    }\n    if (options.enableActiveItemFocusOnDropdownOpen) {\n        // Accessibility: Focus the first active button in the toolbar when the dropdown gets open.\n        focusChildOnDropdownOpen(dropdownView, ()=>dropdownView.toolbarView.items.find((item)=>item.isOn));\n    }\n}\n/**\n * Adds an instance of {@link module:ui/toolbar/toolbarview~ToolbarView} to a dropdown.\n */ function addToolbarToOpenDropdown(dropdownView, buttonsOrCallback, options) {\n    const locale = dropdownView.locale;\n    const t = locale.t;\n    const toolbarView = dropdownView.toolbarView = new ToolbarView(locale);\n    const buttons = typeof buttonsOrCallback == 'function' ? buttonsOrCallback() : buttonsOrCallback;\n    toolbarView.ariaLabel = options.ariaLabel || t('Dropdown toolbar');\n    if (options.maxWidth) {\n        toolbarView.maxWidth = options.maxWidth;\n    }\n    if (options.class) {\n        toolbarView.class = options.class;\n    }\n    if (options.isCompact) {\n        toolbarView.isCompact = options.isCompact;\n    }\n    if (options.isVertical) {\n        toolbarView.isVertical = true;\n    }\n    if (buttons instanceof ViewCollection) {\n        toolbarView.items.bindTo(buttons).using((item)=>item);\n    } else {\n        toolbarView.items.addMany(buttons);\n    }\n    dropdownView.panelView.children.add(toolbarView);\n    dropdownView.focusTracker.add(toolbarView);\n    toolbarView.items.delegate('execute').to(dropdownView);\n}\n/**\n * Adds an instance of {@link module:ui/list/listview~ListView} to a dropdown.\n *\n * ```ts\n * const items = new Collection<ListDropdownItemDefinition>();\n *\n * items.add( {\n * \ttype: 'button',\n * \tmodel: new Model( {\n * \t\twithText: true,\n * \t\tlabel: 'First item',\n * \t\tlabelStyle: 'color: red'\n * \t} )\n * } );\n *\n * items.add( {\n * \t type: 'button',\n * \t model: new Model( {\n * \t\twithText: true,\n * \t\tlabel: 'Second item',\n * \t\tlabelStyle: 'color: green',\n * \t\tclass: 'foo'\n * \t} )\n * } );\n *\n * const dropdown = createDropdown( locale );\n *\n * addListToDropdown( dropdown, items );\n *\n * // Will render a dropdown with a list in the panel containing two items.\n * dropdown.render()\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * The `items` collection passed to this methods controls the presence and attributes of respective\n * {@link module:ui/list/listitemview~ListItemView list items}.\n *\n * **Note:** To improve the accessibility, when a list is added to the dropdown using this helper the dropdown will automatically attempt\n * to focus the first active item (a host to a {@link module:ui/button/buttonview~ButtonView} with\n * {@link module:ui/button/buttonview~ButtonView#isOn} set `true`) or the very first item when none are active.\n *\n * **Note:** List view will be created on first open of the dropdown.\n *\n * See {@link module:ui/dropdown/utils~createDropdown} and {@link module:list/list~List}.\n *\n * @param dropdownView A dropdown instance to which `ListVIew` will be added.\n * @param itemsOrCallback A collection of the list item definitions or a callback returning a list item definitions to populate the list.\n * @param options.ariaLabel Label used by assistive technologies to describe list element.\n * @param options.role Will be reflected by the `role` DOM attribute in `ListVIew` and used by assistive technologies.\n */ function addListToDropdown(dropdownView, itemsOrCallback, options = {}) {\n    if (dropdownView.isOpen) {\n        addListToOpenDropdown(dropdownView, itemsOrCallback, options);\n    } else {\n        dropdownView.once('change:isOpen', ()=>addListToOpenDropdown(dropdownView, itemsOrCallback, options), {\n            priority: 'highest'\n        });\n    }\n    // Accessibility: Focus the first active button in the list when the dropdown gets open.\n    focusChildOnDropdownOpen(dropdownView, ()=>dropdownView.listView.items.find((item)=>{\n            if (item instanceof ListItemView) {\n                return item.children.first.isOn;\n            }\n            return false;\n        }));\n}\n/**\n * Adds an instance of {@link module:ui/list/listview~ListView} to a dropdown.\n */ function addListToOpenDropdown(dropdownView, itemsOrCallback, options) {\n    const locale = dropdownView.locale;\n    const listView = dropdownView.listView = new ListView(locale);\n    const items = typeof itemsOrCallback == 'function' ? itemsOrCallback() : itemsOrCallback;\n    listView.ariaLabel = options.ariaLabel;\n    listView.role = options.role;\n    bindViewCollectionItemsToDefinitions(dropdownView, listView.items, items, locale);\n    dropdownView.panelView.children.add(listView);\n    listView.items.delegate('execute').to(dropdownView);\n}\n/**\n * A helper to be used on an existing {@link module:ui/dropdown/dropdownview~DropdownView} that focuses\n * a specific child in DOM when the dropdown {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open}.\n *\n * @param dropdownView A dropdown instance to which the focus behavior will be added.\n * @param childSelectorCallback A callback executed when the dropdown gets open. It should return a {@link module:ui/view~View}\n * instance (child of {@link module:ui/dropdown/dropdownview~DropdownView#panelView}) that will get focused or a falsy value.\n * If falsy value is returned, a default behavior of the dropdown will engage focusing the first focusable child in\n * the {@link module:ui/dropdown/dropdownview~DropdownView#panelView}.\n */ function focusChildOnDropdownOpen(dropdownView, childSelectorCallback) {\n    dropdownView.on('change:isOpen', ()=>{\n        if (!dropdownView.isOpen) {\n            return;\n        }\n        const childToFocus = childSelectorCallback();\n        if (!childToFocus) {\n            return;\n        }\n        if (typeof childToFocus.focus === 'function') {\n            childToFocus.focus();\n        } else {\n            /**\n\t\t\t * The child view of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown} is missing the `focus()` method\n\t\t\t * and could not be focused when the dropdown got {@link module:ui/dropdown/dropdownview~DropdownView#isOpen open}.\n\t\t\t *\n\t\t\t * Making the content of a dropdown focusable in this case greatly improves the accessibility. Please make the view instance\n\t\t\t * implements the {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable focusable interface} for the best user\n\t\t\t * experience.\n\t\t\t *\n\t\t\t * @error ui-dropdown-focus-child-on-open-child-missing-focus\n\t\t\t * @param {module:ui/view~View} view\n\t\t\t */ logWarning('ui-dropdown-focus-child-on-open-child-missing-focus', {\n                view: childToFocus\n            });\n        }\n    // * Let the panel show up first (do not focus an invisible element).\n    // * Execute after focusDropdownPanelOnOpen(). See focusDropdownPanelOnOpen() to learn more.\n    }, {\n        priority: priorities.low - 10\n    });\n}\n/**\n * Add a set of default behaviors to dropdown view.\n */ function addDefaultBehaviors(dropdownView) {\n    closeDropdownOnClickOutside(dropdownView);\n    closeDropdownOnExecute(dropdownView);\n    closeDropdownOnBlur(dropdownView);\n    focusDropdownContentsOnArrows(dropdownView);\n    focusDropdownButtonOnClose(dropdownView);\n    focusDropdownPanelOnOpen(dropdownView);\n}\n/**\n * Adds a behavior to a dropdownView that closes opened dropdown when user clicks outside the dropdown.\n */ function closeDropdownOnClickOutside(dropdownView) {\n    clickOutsideHandler({\n        emitter: dropdownView,\n        activator: ()=>dropdownView.isRendered && dropdownView.isOpen,\n        callback: ()=>{\n            dropdownView.isOpen = false;\n        },\n        contextElements: ()=>[\n                dropdownView.element,\n                // Include all elements connected to the dropdown's focus tracker, but exclude those that are direct children\n                // of DropdownView#element. They would be identified as descendants of #element anyway upon clicking and would\n                // not contribute to the logic.\n                ...getFocusTrackerTreeElements(dropdownView.focusTracker).filter((element)=>!dropdownView.element.contains(element))\n            ]\n    });\n}\n/**\n * Returns all DOM elements connected to a DropdownView's focus tracker, either directly (same DOM sub-tree)\n * or indirectly (external views registered in the focus tracker).\n */ function getFocusTrackerTreeElements(focusTracker) {\n    return [\n        ...focusTracker.elements,\n        ...focusTracker.externalViews.flatMap((view)=>getFocusTrackerTreeElements(view.focusTracker))\n    ];\n}\n/**\n * Adds a behavior to a dropdownView that closes the dropdown view on \"execute\" event.\n */ function closeDropdownOnExecute(dropdownView) {\n    // Close the dropdown when one of the list items has been executed.\n    dropdownView.on('execute', (evt)=>{\n        // Toggling a switch button view should not close the dropdown.\n        if (evt.source instanceof SwitchButtonView) {\n            return;\n        }\n        dropdownView.isOpen = false;\n    });\n}\n/**\n * Adds a behavior to a dropdown view that closes opened dropdown when it loses focus.\n */ function closeDropdownOnBlur(dropdownView) {\n    dropdownView.focusTracker.on('change:isFocused', (evt, name, isFocused)=>{\n        if (isFocused || !dropdownView.isOpen) {\n            return;\n        }\n        dropdownView.isOpen = false;\n    });\n}\n/**\n * Adds a behavior to a dropdownView that focuses the dropdown's panel view contents on keystrokes.\n */ function focusDropdownContentsOnArrows(dropdownView) {\n    // If the dropdown panel is already open, the arrow down key should focus the first child of the #panelView.\n    dropdownView.keystrokes.set('arrowdown', (data, cancel)=>{\n        if (dropdownView.isOpen) {\n            dropdownView.panelView.focus();\n            cancel();\n        }\n    });\n    // If the dropdown panel is already open, the arrow up key should focus the last child of the #panelView.\n    dropdownView.keystrokes.set('arrowup', (data, cancel)=>{\n        if (dropdownView.isOpen) {\n            dropdownView.panelView.focusLast();\n            cancel();\n        }\n    });\n}\n/**\n * Adds a behavior that focuses the #buttonView when the dropdown was closed but focus was within the #panelView element.\n * This makes sure the focus is never lost.\n */ function focusDropdownButtonOnClose(dropdownView) {\n    dropdownView.on('change:isOpen', (evt, name, isOpen)=>{\n        if (isOpen) {\n            return;\n        }\n        const elements = dropdownView.focusTracker.elements;\n        // If the dropdown was closed, move the focus back to the button (#12125).\n        // Don't touch the focus, if it moved somewhere else (e.g. moved to the editing root on #execute) (#12178).\n        // Note: Don't use the state of the DropdownView#focusTracker here. It fires #blur with the timeout.\n        if (elements.some((element)=>element.contains(global.document.activeElement))) {\n            dropdownView.buttonView.focus();\n        }\n    });\n}\n/**\n * Adds a behavior that focuses the #panelView when dropdown gets open (accessibility).\n */ function focusDropdownPanelOnOpen(dropdownView) {\n    dropdownView.on('change:isOpen', (evt, name, isOpen)=>{\n        if (!isOpen) {\n            return;\n        }\n        // Focus the first item in the dropdown when the dropdown opened.\n        dropdownView.panelView.focus();\n    // * Let the panel show up first (do not focus an invisible element).\n    // * Also, execute before focusChildOnDropdownOpen() to make sure this helper does not break the\n    //   focus of a specific child by kicking in too late and resetting the focus in the panel.\n    }, {\n        priority: 'low'\n    });\n}\n/**\n * This helper populates a dropdown list with items and groups according to the\n * collection of item definitions. A permanent binding is created in this process allowing\n * dynamic management of the dropdown list content.\n *\n * @param dropdownView\n * @param listItems\n * @param definitions\n * @param locale\n */ function bindViewCollectionItemsToDefinitions(dropdownView, listItems, definitions, locale) {\n    // List item checkboxes have a reserved space for the check icon, so we need to know if there are any checkboxes in the list\n    // to adjust the layout accordingly. It'd look weird if the items on the list were not aligned horizontally.\n    //\n    // Possible theoretical performance problem if many items are added one by one, as this will be called for each item.\n    listItems.on('change', ()=>{\n        // Filter-map. Check all items, leave only these that have buttons and return the buttons.\n        const listItemButtons = [\n            ...listItems\n        ].reduce((acc, item)=>{\n            if (item instanceof ListItemView && item.children.first instanceof ListItemButtonView) {\n                acc.push(item.children.first);\n            }\n            return acc;\n        }, []);\n        const hasAnyCheckboxOnList = listItemButtons.some((button)=>button.isToggleable);\n        listItemButtons.forEach((item)=>{\n            item.hasCheckSpace = hasAnyCheckboxOnList;\n        });\n    });\n    listItems.bindTo(definitions).using((def)=>{\n        if (def.type === 'separator') {\n            return new ListSeparatorView(locale);\n        } else if (def.type === 'group') {\n            const groupView = new ListItemGroupView(locale);\n            groupView.set({\n                label: def.label\n            });\n            bindViewCollectionItemsToDefinitions(dropdownView, groupView.items, def.items, locale);\n            groupView.items.delegate('execute').to(dropdownView);\n            return groupView;\n        } else if (def.type === 'button' || def.type === 'switchbutton') {\n            const isToggleable = def.model.role === 'menuitemcheckbox' || def.model.role === 'menuitemradio';\n            const listItemView = new ListItemView(locale);\n            let buttonView;\n            if (def.type === 'button') {\n                buttonView = new ListItemButtonView(locale);\n                buttonView.set({\n                    isToggleable\n                });\n            } else {\n                buttonView = new SwitchButtonView(locale);\n            }\n            // Bind all model properties to the button view.\n            buttonView.bind(...Object.keys(def.model)).to(def.model);\n            buttonView.delegate('execute').to(listItemView);\n            listItemView.children.add(buttonView);\n            return listItemView;\n        }\n        return null;\n    });\n}\n\n/**\n * A helper for creating labeled inputs.\n *\n * It creates an instance of a {@link module:ui/inputtext/inputtextview~InputTextView input text} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in DOM.\n *\n * The helper does the following:\n *\n * * It sets input's `id` and `ariaDescribedById` attributes.\n * * It binds input's `isReadOnly` to the labeled view.\n * * It binds input's `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when user starts typing in the input.\n *\n * Usage:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, createLabeledInputText );\n * console.log( labeledInputView.fieldView ); // A text input instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view's label} and the input.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view's status} and the input.\n * @returns The input text view instance.\n */ const createLabeledInputText = (labeledFieldView, viewUid, statusUid)=>{\n    const inputView = new InputTextView(labeledFieldView.locale);\n    inputView.set({\n        id: viewUid,\n        ariaDescribedById: statusUid\n    });\n    inputView.bind('isReadOnly').to(labeledFieldView, 'isEnabled', (value)=>!value);\n    inputView.bind('hasError').to(labeledFieldView, 'errorText', (value)=>!!value);\n    inputView.on('input', ()=>{\n        // UX: Make the error text disappear and disable the error indicator as the user\n        // starts fixing the errors.\n        labeledFieldView.errorText = null;\n    });\n    labeledFieldView.bind('isEmpty', 'isFocused', 'placeholder').to(inputView);\n    return inputView;\n};\n/**\n * A helper for creating labeled number inputs.\n *\n * It creates an instance of a {@link module:ui/inputnumber/inputnumberview~InputNumberView input number} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in DOM.\n *\n * The helper does the following:\n *\n * * It sets input's `id` and `ariaDescribedById` attributes.\n * * It binds input's `isReadOnly` to the labeled view.\n * * It binds input's `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when user starts typing in the input.\n *\n * Usage:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, createLabeledInputNumber );\n * console.log( labeledInputView.fieldView ); // A number input instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view's label} and the input.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view's status} and the input.\n * @returns The input number view instance.\n */ const createLabeledInputNumber = (labeledFieldView, viewUid, statusUid)=>{\n    const inputView = new InputNumberView(labeledFieldView.locale);\n    inputView.set({\n        id: viewUid,\n        ariaDescribedById: statusUid,\n        inputMode: 'numeric'\n    });\n    inputView.bind('isReadOnly').to(labeledFieldView, 'isEnabled', (value)=>!value);\n    inputView.bind('hasError').to(labeledFieldView, 'errorText', (value)=>!!value);\n    inputView.on('input', ()=>{\n        // UX: Make the error text disappear and disable the error indicator as the user\n        // starts fixing the errors.\n        labeledFieldView.errorText = null;\n    });\n    labeledFieldView.bind('isEmpty', 'isFocused', 'placeholder').to(inputView);\n    return inputView;\n};\n/**\n * A helper for creating labeled textarea.\n *\n * It creates an instance of a {@link module:ui/textarea/textareaview~TextareaView textarea} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in DOM.\n *\n * The helper does the following:\n *\n * * It sets textarea's `id` and `ariaDescribedById` attributes.\n * * It binds textarea's `isReadOnly` to the labeled view.\n * * It binds textarea's `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when user starts typing in the textarea.\n *\n * Usage:\n *\n * ```ts\n * const labeledTextarea = new LabeledFieldView( locale, createLabeledTextarea );\n * console.log( labeledTextarea.fieldView ); // A textarea instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view's label} and the textarea.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view's status} and the textarea.\n * @returns The textarea view instance.\n */ const createLabeledTextarea = (labeledFieldView, viewUid, statusUid)=>{\n    const textareaView = new TextareaView(labeledFieldView.locale);\n    textareaView.set({\n        id: viewUid,\n        ariaDescribedById: statusUid\n    });\n    textareaView.bind('isReadOnly').to(labeledFieldView, 'isEnabled', (value)=>!value);\n    textareaView.bind('hasError').to(labeledFieldView, 'errorText', (value)=>!!value);\n    textareaView.on('input', ()=>{\n        // UX: Make the error text disappear and disable the error indicator as the user\n        // starts fixing the errors.\n        labeledFieldView.errorText = null;\n    });\n    labeledFieldView.bind('isEmpty', 'isFocused', 'placeholder').to(textareaView);\n    return textareaView;\n};\n/**\n * A helper for creating labeled dropdowns.\n *\n * It creates an instance of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled field view}.\n *\n * The helper does the following:\n *\n * * It sets dropdown's `id` and `ariaDescribedById` attributes.\n * * It binds input's `isEnabled` to the labeled view.\n *\n * Usage:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, createLabeledDropdown );\n * console.log( labeledInputView.fieldView ); // A dropdown instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view label} and the dropdown.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view status} and the dropdown.\n * @returns The dropdown view instance.\n */ const createLabeledDropdown = (labeledFieldView, viewUid, statusUid)=>{\n    const dropdownView = createDropdown(labeledFieldView.locale);\n    dropdownView.set({\n        id: viewUid,\n        ariaDescribedById: statusUid\n    });\n    dropdownView.bind('isEnabled').to(labeledFieldView);\n    return dropdownView;\n};\n\nconst waitingTime = 150;\n/**\n * A class which represents a color picker with an input field for defining custom colors.\n */ class ColorPickerView extends View {\n    /**\n\t * Container for a `#` sign prefix and an input for displaying and defining custom colors\n\t * in HEX format.\n\t */ hexInputRow;\n    /**\n\t * Debounced function updating the `color` property in the component\n\t * and firing the `ColorPickerColorSelectedEvent`. Executed whenever color in component\n\t * is changed by the user interaction (through the palette or input).\n\t *\n\t * @private\n\t */ _debounceColorPickerEvent;\n    /**\n\t * A reference to the configuration of the color picker specified in the constructor.\n\t *\n\t * @private\n\t */ _config;\n    /**\n\t * Creates a view of color picker.\n\t *\n\t * @param locale\n\t * @param config\n\t */ constructor(locale, config = {}){\n        super(locale);\n        this.set({\n            color: '',\n            _hexColor: ''\n        });\n        this.hexInputRow = this._createInputRow();\n        const children = this.createCollection();\n        if (!config.hideInput) {\n            children.add(this.hexInputRow);\n        }\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-color-picker'\n                ],\n                tabindex: -1\n            },\n            children\n        });\n        this._config = config;\n        this._debounceColorPickerEvent = debounce((color)=>{\n            // At first, set the color internally in the component. It's converted to the configured output format.\n            this.set('color', color);\n            // Then let the outside world know that the user changed the color.\n            this.fire('colorSelected', {\n                color: this.color\n            });\n        }, waitingTime, {\n            leading: true\n        });\n        // The `color` property holds the color in the configured output format.\n        // Ensure it before actually setting the value.\n        this.on('set:color', (evt, propertyName, newValue)=>{\n            evt.return = convertColor(newValue, this._config.format || 'hsl');\n        });\n        // The `_hexColor` property is bound to the `color` one, but requires conversion.\n        this.on('change:color', ()=>{\n            this._hexColor = convertColorToCommonHexFormat(this.color);\n        });\n        this.on('change:_hexColor', ()=>{\n            // Update the selected color in the color picker palette when it's not focused.\n            // It means the user typed the color in the input.\n            if (document.activeElement !== this.picker) {\n                this.picker.setAttribute('color', this._hexColor);\n            }\n            // There has to be two way binding between properties.\n            // Extra precaution has to be taken to trigger change back only when the color really changes.\n            if (convertColorToCommonHexFormat(this.color) != convertColorToCommonHexFormat(this._hexColor)) {\n                this.color = this._hexColor;\n            }\n        });\n    }\n    /**\n\t * Renders color picker in the view.\n\t */ render() {\n        super.render();\n        // Extracted to the helper to make it testable.\n        registerCustomElement('hex-color-picker', HexBase);\n        this.picker = global.document.createElement('hex-color-picker');\n        this.picker.setAttribute('class', 'hex-color-picker');\n        this.picker.setAttribute('tabindex', '-1');\n        this._createSlidersView();\n        if (this.element) {\n            if (this.hexInputRow.element) {\n                this.element.insertBefore(this.picker, this.hexInputRow.element);\n            } else {\n                this.element.appendChild(this.picker);\n            }\n            // Create custom stylesheet with a look of focused pointer in color picker and append it into the color picker shadowDom\n            const styleSheetForFocusedColorPicker = document.createElement('style');\n            styleSheetForFocusedColorPicker.textContent = '[role=\"slider\"]:focus [part$=\"pointer\"] {' + 'border: 1px solid #fff;' + 'outline: 1px solid var(--ck-color-focus-border);' + 'box-shadow: 0 0 0 2px #fff;' + '}';\n            this.picker.shadowRoot.appendChild(styleSheetForFocusedColorPicker);\n        }\n        this.picker.addEventListener('color-changed', (event)=>{\n            const color = event.detail.value;\n            this._debounceColorPickerEvent(color);\n        });\n    }\n    /**\n\t * Focuses the first pointer in color picker.\n\t *\n\t */ focus() {\n        // In some browsers we need to move the focus to the input first.\n        // Otherwise, the color picker doesn't behave as expected.\n        // In FF, after selecting the color via slider, it instantly moves back to the previous color.\n        // In all iOS browsers and desktop Safari, once the saturation slider is moved for the first time,\n        // editor collapses the selection and doesn't apply the color change.\n        // See: https://github.com/cksource/ckeditor5-internal/issues/3245, https://github.com/ckeditor/ckeditor5/issues/14119,\n        // https://github.com/cksource/ckeditor5-internal/issues/3268.\n        /* istanbul ignore next -- @preserve */ if (!this._config.hideInput && (env.isGecko || env.isiOS || env.isSafari)) {\n            const input = this.hexInputRow.children.get(1);\n            input.focus();\n        }\n        const firstSlider = this.slidersView.first;\n        firstSlider.focus();\n    }\n    /**\n\t * Creates collection of sliders in color picker.\n\t *\n\t * @private\n\t */ _createSlidersView() {\n        const colorPickersChildren = [\n            ...this.picker.shadowRoot.children\n        ];\n        const sliders = colorPickersChildren.filter((item)=>item.getAttribute('role') === 'slider');\n        const slidersView = sliders.map((slider)=>{\n            const view = new SliderView(slider);\n            return view;\n        });\n        this.slidersView = this.createCollection();\n        slidersView.forEach((item)=>{\n            this.slidersView.add(item);\n        });\n    }\n    /**\n\t * Creates input row for defining custom colors in color picker.\n\t *\n\t * @private\n\t */ _createInputRow() {\n        const colorInput = this._createColorInput();\n        return new ColorPickerInputRowView(this.locale, colorInput);\n    }\n    /**\n\t * Creates the input where user can type or paste the color in hex format.\n\t *\n\t * @private\n\t */ _createColorInput() {\n        const labeledInput = new LabeledFieldView(this.locale, createLabeledInputText);\n        const { t } = this.locale;\n        labeledInput.set({\n            label: t('HEX'),\n            class: 'color-picker-hex-input'\n        });\n        labeledInput.fieldView.bind('value').to(this, '_hexColor', (pickerColor)=>{\n            if (labeledInput.isFocused) {\n                // Text field shouldn't be updated with color change if the text field is focused.\n                // Imagine user typing hex code and getting the value of field changed.\n                return labeledInput.fieldView.value;\n            } else {\n                return pickerColor.startsWith('#') ? pickerColor.substring(1) : pickerColor;\n            }\n        });\n        // Only accept valid hex colors as input.\n        labeledInput.fieldView.on('input', ()=>{\n            const inputValue = labeledInput.fieldView.element.value;\n            if (inputValue) {\n                const maybeHexColor = tryParseHexColor(inputValue);\n                if (maybeHexColor) {\n                    // If so, set the color.\n                    // Otherwise, do nothing.\n                    this._debounceColorPickerEvent(maybeHexColor);\n                }\n            }\n        });\n        return labeledInput;\n    }\n    /**\n\t * Validates the view and returns `false` when some fields are invalid.\n\t */ isValid() {\n        const { t } = this.locale;\n        // If the input is hidden, it's always valid, because there is no way to select\n        // invalid color value using diagram color picker.\n        if (this._config.hideInput) {\n            return true;\n        }\n        this.resetValidationStatus();\n        // One error per field is enough.\n        if (!this.hexInputRow.getParsedColor()) {\n            // Apply updated error.\n            this.hexInputRow.inputView.errorText = t('Please enter a valid color (e.g. \"ff0000\").');\n            return false;\n        }\n        return true;\n    }\n    /**\n\t * Cleans up the supplementary error and information text of input inside the {@link #hexInputRow}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */ resetValidationStatus() {\n        this.hexInputRow.inputView.errorText = null;\n    }\n}\n// Converts any color format to a unified hex format.\n//\n// @param inputColor\n// @returns An unified hex string.\nfunction convertColorToCommonHexFormat(inputColor) {\n    let ret = convertToHex(inputColor);\n    if (!ret) {\n        ret = '#000';\n    }\n    if (ret.length === 4) {\n        // Unfold shortcut format.\n        ret = '#' + [\n            ret[1],\n            ret[1],\n            ret[2],\n            ret[2],\n            ret[3],\n            ret[3]\n        ].join('');\n    }\n    return ret.toLowerCase();\n}\n// View abstraction over pointer in color picker.\nclass SliderView extends View {\n    /**\n\t * @param element HTML element of slider in color picker.\n\t */ constructor(element){\n        super();\n        this.element = element;\n    }\n    /**\n\t * Focuses element.\n\t */ focus() {\n        this.element.focus();\n    }\n}\n// View abstraction over the `#` character before color input.\nclass HashView extends View {\n    constructor(locale){\n        super(locale);\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-color-picker__hash-view'\n                ]\n            },\n            children: '#'\n        });\n    }\n}\n// The class representing a row containing hex color input field.\n// **Note**: For now this class is private. When more use cases appear (beyond `ckeditor5-table` and `ckeditor5-image`),\n// it will become a component in `ckeditor5-ui`.\n//\n// @private\nclass ColorPickerInputRowView extends View {\n    /**\n\t * A collection of row items (buttons, dropdowns, etc.).\n\t */ children;\n    /**\n\t * Hex input view element.\n\t */ inputView;\n    /**\n\t * Creates an instance of the form row class.\n\t *\n\t * @param locale The locale instance.\n\t * @param inputView Hex color input element.\n\t */ constructor(locale, inputView){\n        super(locale);\n        this.inputView = inputView;\n        this.children = this.createCollection([\n            new HashView(),\n            this.inputView\n        ]);\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-color-picker__row'\n                ]\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * Returns false if color input value is not in hex format.\n\t */ getParsedColor() {\n        return tryParseHexColor(this.inputView.fieldView.element.value);\n    }\n}\n/**\n * Trim spaces from provided color and check if hex is valid.\n *\n * @param color Unsafe color string.\n * @returns Null if provided color is not hex value.\n * @export\n */ function tryParseHexColor(color) {\n    if (!color) {\n        return null;\n    }\n    const hashLessColor = color.trim().replace(/^#/, '');\n    // Incorrect length.\n    if (![\n        3,\n        4,\n        6,\n        8\n    ].includes(hashLessColor.length)) {\n        return null;\n    }\n    // Incorrect characters.\n    if (!/^(([0-9a-fA-F]{2}){3,4}|([0-9a-fA-F]){3,4})$/.test(hashLessColor)) {\n        return null;\n    }\n    return `#${hashLessColor}`;\n}\n\n/**\n * A collection to store document colors. It enforces colors to be unique.\n */ class DocumentColorCollection extends /* #__PURE__ */ ObservableMixin(Collection) {\n    constructor(options){\n        super(options);\n        this.set('isEmpty', true);\n        this.on('change', ()=>{\n            this.set('isEmpty', this.length === 0);\n        });\n    }\n    /**\n\t * Adds a color to the document color collection.\n\t *\n\t * This method ensures that no color duplicates are inserted (compared using\n\t * the color value of the {@link module:ui/colorgrid/colorgridview~ColorDefinition}).\n\t *\n\t * If the item does not have an ID, it will be automatically generated and set on the item.\n\t *\n\t * @param index The position of the item in the collection. The item is pushed to the collection when `index` is not specified.\n\t * @fires add\n\t * @fires change\n\t */ add(item, index) {\n        if (this.find((element)=>element.color === item.color)) {\n            // No duplicates are allowed.\n            return this;\n        }\n        return super.add(item, index);\n    }\n    /**\n\t * Checks if an object with given colors is present in the document color collection.\n\t */ hasColor(color) {\n        return !!this.find((item)=>item.color === color);\n    }\n}\n\n/**\n * One of the fragments of {@link module:ui/colorselector/colorselectorview~ColorSelectorView}.\n *\n * It provides a UI that allows users to select colors from the a predefined set and from existing document colors.\n *\n * It consists of the following sub–components:\n *\n * * A \"Remove color\" button,\n * * A static {@link module:ui/colorgrid/colorgridview~ColorGridView} of colors defined in the configuration,\n * * A dynamic {@link module:ui/colorgrid/colorgridview~ColorGridView} of colors used in the document.\n * * If color picker is configured, the \"Color Picker\" button is visible too.\n */ class ColorGridsFragmentView extends View {\n    /**\n\t * A collection of the children of the table.\n\t */ items;\n    /**\n\t * An array with objects representing colors to be displayed in the grid.\n\t */ colorDefinitions;\n    /**\n\t * Tracks information about the DOM focus in the list.\n\t */ focusTracker;\n    /**\n\t * The number of columns in the color grid.\n\t */ columns;\n    /**\n\t * Preserves the reference to {@link module:ui/colorselector/documentcolorcollection~DocumentColorCollection} used to collect\n\t * definitions that store the document colors.\n\t *\n\t * @readonly\n\t */ documentColors;\n    /**\n\t * The maximum number of colors in the document colors section.\n\t * If it equals 0, the document colors section is not added.\n\t *\n\t * @readonly\n\t */ documentColorsCount;\n    /**\n\t * Preserves the reference to {@link module:ui/colorgrid/colorgridview~ColorGridView} used to create\n\t * the default (static) color set.\n\t *\n\t * The property is loaded once the the parent dropdown is opened the first time.\n\t *\n\t * @readonly\n\t */ staticColorsGrid;\n    /**\n\t * Preserves the reference to {@link module:ui/colorgrid/colorgridview~ColorGridView} used to create\n\t * the document colors. It remains undefined if the document colors feature is disabled.\n\t *\n\t * The property is loaded once the the parent dropdown is opened the first time.\n\t *\n\t * @readonly\n\t */ documentColorsGrid;\n    /**\n\t * The \"Color picker\" button view.\n\t */ colorPickerButtonView;\n    /**\n\t * The \"Remove color\" button view.\n\t */ removeColorButtonView;\n    /**\n\t * A collection of views that can be focused in the view.\n\t *\n\t * @readonly\n\t */ _focusables;\n    /**\n\t * Document color section's label.\n\t *\n\t * @readonly\n\t */ _documentColorsLabel;\n    /**\n\t * The label of the button responsible for removing color attributes.\n\t */ _removeButtonLabel;\n    /**\n\t * The label of the button responsible for switching to the color picker component.\n\t */ _colorPickerLabel;\n    /**\n\t * Creates an instance of the view.\n\t *\n\t * @param locale The localization services instance.\n\t * @param colors An array with definitions of colors to be displayed in the table.\n\t * @param columns The number of columns in the color grid.\n\t * @param removeButtonLabel The label of the button responsible for removing the color.\n\t * @param colorPickerLabel The label of the button responsible for color picker appearing.\n\t * @param documentColorsLabel The label for the section with the document colors.\n\t * @param documentColorsCount The number of colors in the document colors section inside the color dropdown.\n\t * @param focusTracker Tracks information about the DOM focus in the list.\n\t * @param focusables A collection of views that can be focused in the view.\n\t */ constructor(locale, { colors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount, colorPickerLabel, focusTracker, focusables }){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('isVisible', true);\n        this.focusTracker = focusTracker;\n        this.items = this.createCollection();\n        this.colorDefinitions = colors;\n        this.columns = columns;\n        this.documentColors = new DocumentColorCollection();\n        this.documentColorsCount = documentColorsCount;\n        this._focusables = focusables;\n        this._removeButtonLabel = removeButtonLabel;\n        this._colorPickerLabel = colorPickerLabel;\n        this._documentColorsLabel = documentColorsLabel;\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck-color-grids-fragment',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ]\n            },\n            children: this.items\n        });\n        this.removeColorButtonView = this._createRemoveColorButton();\n        this.items.add(this.removeColorButtonView);\n    }\n    /**\n\t * Scans through the editor model and searches for text node attributes with the given attribute name.\n\t * Found entries are set as document colors.\n\t *\n\t * All the previously stored document colors will be lost in the process.\n\t *\n\t * @param model The model used as a source to obtain the document colors.\n\t * @param attributeName Determines the name of the related model's attribute for a given dropdown.\n\t */ updateDocumentColors(model, attributeName) {\n        const document = model.document;\n        const maxCount = this.documentColorsCount;\n        this.documentColors.clear();\n        for (const root of document.getRoots()){\n            const range = model.createRangeIn(root);\n            for (const node of range.getItems()){\n                if (node.is('$textProxy') && node.hasAttribute(attributeName)) {\n                    this._addColorToDocumentColors(node.getAttribute(attributeName));\n                    if (this.documentColors.length >= maxCount) {\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    /**\n\t * Refreshes the state of the selected color in one or both {@link module:ui/colorgrid/colorgridview~ColorGridView}s\n\t * available in the {@link module:ui/colorselector/colorselectorview~ColorSelectorView}. It guarantees that the selection will\n\t * occur only in one of them.\n\t */ updateSelectedColors() {\n        const documentColorsGrid = this.documentColorsGrid;\n        const staticColorsGrid = this.staticColorsGrid;\n        const selectedColor = this.selectedColor;\n        staticColorsGrid.selectedColor = selectedColor;\n        if (documentColorsGrid) {\n            documentColorsGrid.selectedColor = selectedColor;\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.staticColorsGrid = this._createStaticColorsGrid();\n        this.items.add(this.staticColorsGrid);\n        if (this.documentColorsCount) {\n            // Create a label for document colors.\n            const bind = Template.bind(this.documentColors, this.documentColors);\n            const label = new View(this.locale);\n            label.setTemplate({\n                tag: 'span',\n                attributes: {\n                    class: [\n                        'ck',\n                        'ck-color-grid__label',\n                        bind.if('isEmpty', 'ck-hidden')\n                    ]\n                },\n                children: [\n                    {\n                        text: this._documentColorsLabel\n                    }\n                ]\n            });\n            this.items.add(label);\n            this.documentColorsGrid = this._createDocumentColorsGrid();\n            this.items.add(this.documentColorsGrid);\n        }\n        this._createColorPickerButton();\n        this._addColorSelectorElementsToFocusTracker();\n    }\n    /**\n\t * Focuses the component.\n\t */ focus() {\n        this.removeColorButtonView.focus();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n    }\n    /**\n\t * Handles displaying the color picker button (if it was previously created) and making it focusable.\n\t */ addColorPickerButton() {\n        if (this.colorPickerButtonView) {\n            this.items.add(this.colorPickerButtonView);\n            this.focusTracker.add(this.colorPickerButtonView.element);\n            this._focusables.add(this.colorPickerButtonView);\n        }\n    }\n    /**\n\t * Adds color selector elements to focus tracker.\n\t */ _addColorSelectorElementsToFocusTracker() {\n        this.focusTracker.add(this.removeColorButtonView.element);\n        this._focusables.add(this.removeColorButtonView);\n        if (this.staticColorsGrid) {\n            this.focusTracker.add(this.staticColorsGrid.element);\n            this._focusables.add(this.staticColorsGrid);\n        }\n        if (this.documentColorsGrid) {\n            this.focusTracker.add(this.documentColorsGrid.element);\n            this._focusables.add(this.documentColorsGrid);\n        }\n    }\n    /**\n\t * Creates the button responsible for displaying the color picker component.\n\t */ _createColorPickerButton() {\n        this.colorPickerButtonView = new ButtonView();\n        this.colorPickerButtonView.set({\n            label: this._colorPickerLabel,\n            withText: true,\n            icon: icons.colorPalette,\n            class: 'ck-color-selector__color-picker'\n        });\n        this.colorPickerButtonView.on('execute', ()=>{\n            this.fire('colorPicker:show');\n        });\n    }\n    /**\n\t * Adds the remove color button as a child of the current view.\n\t */ _createRemoveColorButton() {\n        const buttonView = new ButtonView();\n        buttonView.set({\n            withText: true,\n            icon: icons.eraser,\n            label: this._removeButtonLabel\n        });\n        buttonView.class = 'ck-color-selector__remove-color';\n        buttonView.on('execute', ()=>{\n            this.fire('execute', {\n                value: null,\n                source: 'removeColorButton'\n            });\n        });\n        buttonView.render();\n        return buttonView;\n    }\n    /**\n\t * Creates a static color grid based on the editor configuration.\n\t */ _createStaticColorsGrid() {\n        const colorGrid = new ColorGridView(this.locale, {\n            colorDefinitions: this.colorDefinitions,\n            columns: this.columns\n        });\n        colorGrid.on('execute', (evt, data)=>{\n            this.fire('execute', {\n                value: data.value,\n                source: 'staticColorsGrid'\n            });\n        });\n        return colorGrid;\n    }\n    /**\n\t * Creates the document colors section view and binds it to {@link #documentColors}.\n\t */ _createDocumentColorsGrid() {\n        const bind = Template.bind(this.documentColors, this.documentColors);\n        const documentColorsGrid = new ColorGridView(this.locale, {\n            columns: this.columns\n        });\n        documentColorsGrid.extendTemplate({\n            attributes: {\n                class: bind.if('isEmpty', 'ck-hidden')\n            }\n        });\n        documentColorsGrid.items.bindTo(this.documentColors).using((colorObj)=>{\n            const colorTile = new ColorTileView();\n            colorTile.set({\n                color: colorObj.color,\n                hasBorder: colorObj.options && colorObj.options.hasBorder\n            });\n            if (colorObj.label) {\n                colorTile.set({\n                    label: colorObj.label,\n                    tooltip: true\n                });\n            }\n            colorTile.on('execute', ()=>{\n                this.fire('execute', {\n                    value: colorObj.color,\n                    source: 'documentColorsGrid'\n                });\n            });\n            return colorTile;\n        });\n        // Selected color should be cleared when document colors became empty.\n        this.documentColors.on('change:isEmpty', (evt, name, val)=>{\n            if (val) {\n                documentColorsGrid.selectedColor = null;\n            }\n        });\n        return documentColorsGrid;\n    }\n    /**\n\t * Adds a given color to the document colors list. If possible, the method will attempt to use\n\t * data from the {@link #colorDefinitions} (label, color options).\n\t *\n\t * @param color A string that stores the value of the recently applied color.\n\t */ _addColorToDocumentColors(color) {\n        const predefinedColor = this.colorDefinitions.find((definition)=>definition.color === color);\n        if (!predefinedColor) {\n            this.documentColors.add({\n                color,\n                label: color,\n                options: {\n                    hasBorder: false\n                }\n            });\n        } else {\n            this.documentColors.add(Object.assign({}, predefinedColor));\n        }\n    }\n}\n\n/**\n * One of the fragments of {@link module:ui/colorselector/colorselectorview~ColorSelectorView}.\n *\n * It allows users to select a color from a color picker.\n *\n * It consists of the following sub–components:\n *\n * * A color picker saturation and hue sliders,\n * * A text input accepting colors in HEX format,\n * * \"Save\" and \"Cancel\" action buttons.\n */ class ColorPickerFragmentView extends View {\n    /**\n\t * A collection of component's children.\n\t */ items;\n    /**\n\t * A view with saturation and hue sliders and color input.\n\t */ colorPickerView;\n    /**\n\t * The \"Save\" button view.\n\t */ saveButtonView;\n    /**\n\t * The \"Cancel\" button view.\n\t */ cancelButtonView;\n    /**\n\t * The action bar where are \"Save\" button and \"Cancel\" button.\n\t */ actionBarView;\n    /**\n\t * Tracks information about the DOM focus in the list.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * A collection of views that can be focused in the view.\n\t *\n\t * @readonly\n\t */ _focusables;\n    /**\n\t * A reference to the configuration of {@link #colorPickerView}. `false` when the view was\n\t * configured without a color picker.\n\t *\n\t * @readonly\n\t */ _colorPickerViewConfig;\n    /**\n\t * Creates an instance of the view.\n\t *\n\t * @param locale The localization services instance.\n\t * @param focusTracker Tracks information about the DOM focus in the list.\n\t * @param focusables A collection of views that can be focused in the view..\n\t * @param keystrokes An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t * @param colorPickerViewConfig The configuration of color picker feature. If set to `false`, the color picker\n\t * will not be rendered.\n\t */ constructor(locale, { focusTracker, focusables, keystrokes, colorPickerViewConfig }){\n        super(locale);\n        this.items = this.createCollection();\n        this.focusTracker = focusTracker;\n        this.keystrokes = keystrokes;\n        this.set('isVisible', false);\n        this.set('selectedColor', undefined);\n        this._focusables = focusables;\n        this._colorPickerViewConfig = colorPickerViewConfig;\n        const bind = this.bindTemplate;\n        const { saveButtonView, cancelButtonView } = this._createActionButtons();\n        this.saveButtonView = saveButtonView;\n        this.cancelButtonView = cancelButtonView;\n        this.actionBarView = this._createActionBarView({\n            saveButtonView,\n            cancelButtonView\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck-color-picker-fragment',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ]\n            },\n            children: this.items\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        const colorPickerView = new ColorPickerView(this.locale, {\n            ...this._colorPickerViewConfig\n        });\n        this.colorPickerView = colorPickerView;\n        this.colorPickerView.render();\n        if (this.selectedColor) {\n            colorPickerView.color = this.selectedColor;\n        }\n        this.listenTo(this, 'change:selectedColor', (evt, name, value)=>{\n            colorPickerView.color = value;\n        });\n        this.items.add(this.colorPickerView);\n        this.items.add(this.actionBarView);\n        this._addColorPickersElementsToFocusTracker();\n        this._stopPropagationOnArrowsKeys();\n        this._executeOnEnterPress();\n        this._executeUponColorChange();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n    }\n    /**\n\t * Focuses the color picker.\n\t */ focus() {\n        this.colorPickerView.focus();\n    }\n    /**\n\t * Reset validation messages.\n\t */ resetValidationStatus() {\n        this.colorPickerView.resetValidationStatus();\n    }\n    /**\n\t * When color picker is focused and \"enter\" is pressed it executes command.\n\t */ _executeOnEnterPress() {\n        this.keystrokes.set('enter', (evt)=>{\n            if (this.isVisible && this.focusTracker.focusedElement !== this.cancelButtonView.element && this.colorPickerView.isValid()) {\n                this.fire('execute', {\n                    value: this.selectedColor\n                });\n                evt.stopPropagation();\n                evt.preventDefault();\n            }\n        });\n    }\n    /**\n\t * Removes default behavior of arrow keys in dropdown.\n\t */ _stopPropagationOnArrowsKeys() {\n        const stopPropagation = (data)=>data.stopPropagation();\n        this.keystrokes.set('arrowright', stopPropagation);\n        this.keystrokes.set('arrowleft', stopPropagation);\n        this.keystrokes.set('arrowup', stopPropagation);\n        this.keystrokes.set('arrowdown', stopPropagation);\n    }\n    /**\n\t * Adds color picker elements to focus tracker.\n\t */ _addColorPickersElementsToFocusTracker() {\n        for (const slider of this.colorPickerView.slidersView){\n            this.focusTracker.add(slider.element);\n            this._focusables.add(slider);\n        }\n        const input = this.colorPickerView.hexInputRow.children.get(1);\n        if (input.element) {\n            this.focusTracker.add(input.element);\n            this._focusables.add(input);\n        }\n        this.focusTracker.add(this.saveButtonView.element);\n        this._focusables.add(this.saveButtonView);\n        this.focusTracker.add(this.cancelButtonView.element);\n        this._focusables.add(this.cancelButtonView);\n    }\n    /**\n\t * Creates bar containing \"Save\" and \"Cancel\" buttons.\n\t */ _createActionBarView({ saveButtonView, cancelButtonView }) {\n        const actionBarRow = new View();\n        const children = this.createCollection();\n        children.add(saveButtonView);\n        children.add(cancelButtonView);\n        actionBarRow.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-color-selector_action-bar'\n                ]\n            },\n            children\n        });\n        return actionBarRow;\n    }\n    /**\n\t * Creates \"Save\" and \"Cancel\" buttons.\n\t */ _createActionButtons() {\n        const locale = this.locale;\n        const t = locale.t;\n        const saveButtonView = new ButtonView(locale);\n        const cancelButtonView = new ButtonView(locale);\n        saveButtonView.set({\n            icon: icons.check,\n            class: 'ck-button-save',\n            type: 'button',\n            withText: false,\n            label: t('Accept')\n        });\n        cancelButtonView.set({\n            icon: icons.cancel,\n            class: 'ck-button-cancel',\n            type: 'button',\n            withText: false,\n            label: t('Cancel')\n        });\n        saveButtonView.on('execute', ()=>{\n            if (this.colorPickerView.isValid()) {\n                this.fire('execute', {\n                    source: 'colorPickerSaveButton',\n                    value: this.selectedColor\n                });\n            }\n        });\n        cancelButtonView.on('execute', ()=>{\n            this.fire('colorPicker:cancel');\n        });\n        return {\n            saveButtonView,\n            cancelButtonView\n        };\n    }\n    /**\n\t * Fires the `execute` event if color in color picker has been changed\n\t * by the user.\n\t */ _executeUponColorChange() {\n        this.colorPickerView.on('colorSelected', (evt, data)=>{\n            this.fire('execute', {\n                value: data.color,\n                source: 'colorPicker'\n            });\n            this.set('selectedColor', data.color);\n        });\n    }\n}\n\n/**\n * The configurable color selector view class. It allows users to select colors from a predefined set of colors as well as from\n * a color picker.\n *\n * This meta-view is is made of two components (fragments):\n *\n * * {@link module:ui/colorselector/colorselectorview~ColorSelectorView#colorGridsFragmentView},\n * * {@link module:ui/colorselector/colorselectorview~ColorSelectorView#colorPickerFragmentView}.\n *\n * ```ts\n * const colorDefinitions = [\n * \t{ color: '#000', label: 'Black', options: { hasBorder: false } },\n * \t{ color: 'rgb(255, 255, 255)', label: 'White', options: { hasBorder: true } },\n * \t{ color: 'red', label: 'Red', options: { hasBorder: false } }\n * ];\n *\n * const selectorView = new ColorSelectorView( locale, {\n * \tcolors: colorDefinitions,\n * \tcolumns: 5,\n * \tremoveButtonLabel: 'Remove color',\n * \tdocumentColorsLabel: 'Document colors',\n * \tdocumentColorsCount: 4,\n * \tcolorPickerViewConfig: {\n * \t\tformat: 'hsl'\n * \t}\n * } );\n *\n * selectorView.appendUI();\n * selectorView.selectedColor = 'red';\n * selectorView.updateSelectedColors();\n *\n * selectorView.on<ColorSelectorExecuteEvent>( 'execute', ( evt, data ) => {\n * \tconsole.log( 'Color changed', data.value, data.source );\n * } );\n *\n * selectorView.on<ColorSelectorColorPickerShowEvent>( 'colorPicker:show', ( evt ) => {\n * \tconsole.log( 'Color picker showed up', evt );\n * } );\n *\n * selectorView.on<ColorSelectorColorPickerCancelEvent>( 'colorPicker:cancel', ( evt ) => {\n * \tconsole.log( 'Color picker cancel', evt );\n * } );\n *\n * selectorView.render();\n *\n * document.body.appendChild( selectorView.element );\n * ```\n */ class ColorSelectorView extends View {\n    /**\n\t * Tracks information about the DOM focus in the list.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * A collection of components.\n\t */ items;\n    /**\n\t * A fragment that allows users to select colors from the a predefined set and from existing document colors.\n\t */ colorGridsFragmentView;\n    /**\n\t * A fragment that allows users to select a color from a color picker.\n\t */ colorPickerFragmentView;\n    /**\n\t * Helps cycling over focusable {@link #items} in the list.\n\t *\n\t * @readonly\n\t */ _focusCycler;\n    /**\n\t * A collection of views that can be focused in the view.\n\t *\n\t * @readonly\n\t */ _focusables;\n    /**\n\t * The configuration of color picker sub-component.\n\t */ _colorPickerViewConfig;\n    /**\n\t * Creates a view to be inserted as a child of {@link module:ui/dropdown/dropdownview~DropdownView}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param colors An array with definitions of colors to be displayed in the table.\n\t * @param columns The number of columns in the color grid.\n\t * @param removeButtonLabel The label of the button responsible for removing the color.\n\t * @param colorPickerLabel The label of the button responsible for color picker appearing.\n\t * @param documentColorsLabel The label for the section with the document colors.\n\t * @param documentColorsCount The number of colors in the document colors section inside the color dropdown.\n\t * @param colorPickerViewConfig The configuration of color picker feature. If set to `false`, the color picker will be hidden.\n\t */ constructor(locale, { colors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount, colorPickerLabel, colorPickerViewConfig }){\n        super(locale);\n        this.items = this.createCollection();\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this._focusables = new ViewCollection();\n        this._colorPickerViewConfig = colorPickerViewConfig;\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate list items backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate list items forwards using the <kbd>Tab</kbd> key.\n                focusNext: 'tab'\n            }\n        });\n        this.colorGridsFragmentView = new ColorGridsFragmentView(locale, {\n            colors,\n            columns,\n            removeButtonLabel,\n            documentColorsLabel,\n            documentColorsCount,\n            colorPickerLabel,\n            focusTracker: this.focusTracker,\n            focusables: this._focusables\n        });\n        this.colorPickerFragmentView = new ColorPickerFragmentView(locale, {\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokes: this.keystrokes,\n            colorPickerViewConfig\n        });\n        this.set('_isColorGridsFragmentVisible', true);\n        this.set('_isColorPickerFragmentVisible', false);\n        this.set('selectedColor', undefined);\n        this.colorGridsFragmentView.bind('isVisible').to(this, '_isColorGridsFragmentVisible');\n        this.colorPickerFragmentView.bind('isVisible').to(this, '_isColorPickerFragmentVisible');\n        /**\n\t\t * This is kind of bindings. Unfortunately we could not use this.bind() method because the same property\n\t\t * can not be bound twice. So this is work around how to bind 'selectedColor' property between components.\n\t\t */ this.on('change:selectedColor', (evt, evtName, data)=>{\n            this.colorGridsFragmentView.set('selectedColor', data);\n            this.colorPickerFragmentView.set('selectedColor', data);\n        });\n        this.colorGridsFragmentView.on('change:selectedColor', (evt, evtName, data)=>{\n            this.set('selectedColor', data);\n        });\n        this.colorPickerFragmentView.on('change:selectedColor', (evt, evtName, data)=>{\n            this.set('selectedColor', data);\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-color-selector'\n                ]\n            },\n            children: this.items\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Renders the internals of the component on demand:\n\t * * {@link #colorPickerFragmentView},\n\t * * {@link #colorGridsFragmentView}.\n\t *\n\t * It allows for deferring component initialization to improve the performance.\n\t *\n\t * See {@link #showColorPickerFragment}, {@link #showColorGridsFragment}.\n\t */ appendUI() {\n        this._appendColorGridsFragment();\n        if (this._colorPickerViewConfig) {\n            this._appendColorPickerFragment();\n        }\n    }\n    /**\n\t * Shows the {@link #colorPickerFragmentView} and hides the {@link #colorGridsFragmentView}.\n\t *\n\t * **Note**: It requires {@link #appendUI} to be called first.\n\t *\n\t * See {@link #showColorGridsFragment}, {@link ~ColorSelectorView#event:colorPicker:show}.\n\t */ showColorPickerFragment() {\n        if (!this.colorPickerFragmentView.colorPickerView || this._isColorPickerFragmentVisible) {\n            return;\n        }\n        this._isColorPickerFragmentVisible = true;\n        this.colorPickerFragmentView.focus();\n        this.colorPickerFragmentView.resetValidationStatus();\n        this._isColorGridsFragmentVisible = false;\n    }\n    /**\n\t * Shows the {@link #colorGridsFragmentView} and hides the {@link #colorPickerFragmentView}.\n\t *\n\t * See {@link #showColorPickerFragment}.\n\t *\n\t * **Note**: It requires {@link #appendUI} to be called first.\n\t */ showColorGridsFragment() {\n        if (this._isColorGridsFragmentVisible) {\n            return;\n        }\n        this._isColorGridsFragmentVisible = true;\n        this.colorGridsFragmentView.focus();\n        this._isColorPickerFragmentVisible = false;\n    }\n    /**\n\t * Focuses the first focusable element in {@link #items}.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Focuses the last focusable element in {@link #items}.\n\t */ focusLast() {\n        this._focusCycler.focusLast();\n    }\n    /**\n\t * Scans through the editor model and searches for text node attributes with the given `attributeName`.\n\t * Found entries are set as document colors in {@link #colorGridsFragmentView}.\n\t *\n\t * All the previously stored document colors will be lost in the process.\n\t *\n\t * @param model The model used as a source to obtain the document colors.\n\t * @param attributeName Determines the name of the related model's attribute for a given dropdown.\n\t */ updateDocumentColors(model, attributeName) {\n        this.colorGridsFragmentView.updateDocumentColors(model, attributeName);\n    }\n    /**\n\t * Refreshes the state of the selected color in one or both grids located in {@link #colorGridsFragmentView}.\n\t *\n\t * It guarantees that the selection will occur only in one of them.\n\t */ updateSelectedColors() {\n        this.colorGridsFragmentView.updateSelectedColors();\n    }\n    /**\n\t * Appends the view containing static and document color grid views.\n\t */ _appendColorGridsFragment() {\n        if (this.items.length) {\n            return;\n        }\n        this.items.add(this.colorGridsFragmentView);\n        this.colorGridsFragmentView.delegate('execute').to(this);\n        this.colorGridsFragmentView.delegate('colorPicker:show').to(this);\n    }\n    /**\n\t * Appends the view with the color picker.\n\t */ _appendColorPickerFragment() {\n        if (this.items.length === 2) {\n            return;\n        }\n        this.items.add(this.colorPickerFragmentView);\n        if (this.colorGridsFragmentView.colorPickerButtonView) {\n            this.colorGridsFragmentView.colorPickerButtonView.on('execute', ()=>{\n                this.showColorPickerFragment();\n            });\n        }\n        this.colorGridsFragmentView.addColorPickerButton();\n        this.colorPickerFragmentView.delegate('execute').to(this);\n        this.colorPickerFragmentView.delegate('colorPicker:cancel').to(this);\n    }\n}\n\n/**\n * A helper class implementing the UI component ({@link module:ui/view~View view}) factory.\n *\n * It allows functions producing specific UI components to be registered under their unique names\n * in the factory. A registered component can be then instantiated by providing its name.\n * Note that the names are case insensitive.\n *\n * ```ts\n * // The editor provides localization tools for the factory.\n * const factory = new ComponentFactory( editor );\n *\n * factory.add( 'foo', locale => new FooView( locale ) );\n * factory.add( 'bar', locale => new BarView( locale ) );\n *\n * // An instance of FooView.\n * const fooInstance = factory.create( 'foo' );\n *\n * // Names are case insensitive so this is also allowed:\n * const barInstance = factory.create( 'Bar' );\n * ```\n *\n * The {@link module:core/editor/editor~Editor#locale editor locale} is passed to the factory\n * function when {@link module:ui/componentfactory~ComponentFactory#create} is called.\n */ class ComponentFactory {\n    /**\n\t * The editor instance that the factory belongs to.\n\t */ editor;\n    /**\n\t * Registered component factories.\n\t */ _components = new Map();\n    /**\n\t * Creates an instance of the factory.\n\t *\n\t * @param editor The editor instance.\n\t */ constructor(editor){\n        this.editor = editor;\n    }\n    /**\n\t * Returns an iterator of registered component names. Names are returned in lower case.\n\t */ *names() {\n        for (const value of this._components.values()){\n            yield value.originalName;\n        }\n    }\n    /**\n\t * Registers a component factory function that will be used by the\n\t * {@link #create create} method and called with the\n\t * {@link module:core/editor/editor~Editor#locale editor locale} as an argument,\n\t * allowing localization of the {@link module:ui/view~View view}.\n\t *\n\t * @param name The name of the component.\n\t * @param callback The callback that returns the component.\n\t */ add(name, callback) {\n        this._components.set(getNormalized(name), {\n            callback,\n            originalName: name\n        });\n    }\n    /**\n\t * Creates an instance of a component registered in the factory under a specific name.\n\t *\n\t * When called, the {@link module:core/editor/editor~Editor#locale editor locale} is passed to\n\t * the previously {@link #add added} factory function, allowing localization of the\n\t * {@link module:ui/view~View view}.\n\t *\n\t * @param name The name of the component.\n\t * @returns The instantiated component view.\n\t */ create(name) {\n        if (!this.has(name)) {\n            /**\n\t\t\t * The required component is not registered in the component factory. Please make sure\n\t\t\t * the provided name is correct and the component has been correctly\n\t\t\t * {@link module:ui/componentfactory~ComponentFactory#add added} to the factory.\n\t\t\t *\n\t\t\t * @error componentfactory-item-missing\n\t\t\t * @param name The name of the missing component.\n\t\t\t */ throw new CKEditorError('componentfactory-item-missing', this, {\n                name\n            });\n        }\n        return this._components.get(getNormalized(name)).callback(this.editor.locale);\n    }\n    /**\n\t * Checks if a component of a given name is registered in the factory.\n\t *\n\t * @param name The name of the component.\n\t */ has(name) {\n        return this._components.has(getNormalized(name));\n    }\n}\n/**\n * Ensures that the component name used as the key in the internal map is in lower case.\n */ function getNormalized(name) {\n    return String(name).toLowerCase();\n}\n\nconst BALLOON_CLASS = 'ck-tooltip';\n/**\n * A tooltip manager class for the UI of the editor.\n *\n * **Note**: Most likely you do not have to use the `TooltipManager` API listed below in order to display tooltips. Popular\n * {@glink framework/architecture/ui-library UI components} support tooltips out-of-the-box via observable properties\n * (see {@link module:ui/button/buttonview~ButtonView#tooltip} and {@link module:ui/button/buttonview~ButtonView#tooltipPosition}).\n *\n * # Displaying tooltips\n *\n * To display a tooltip, set `data-cke-tooltip-text` attribute on any DOM element:\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'My tooltip';\n * ```\n *\n * The tooltip will show up whenever the user moves the mouse over the element or the element gets focus in DOM.\n *\n * # Positioning tooltips\n *\n * To change the position of the tooltip, use the `data-cke-tooltip-position` attribute (`s`, `se`, `sw`, `n`, `e`, or `w`):\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'Tooltip to the north';\n * domElement.dataset.ckeTooltipPosition = 'n';\n * ```\n *\n * # Disabling tooltips\n *\n * In order to disable the tooltip  temporarily, use the `data-cke-tooltip-disabled` attribute:\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'Disabled. For now.';\n * domElement.dataset.ckeTooltipDisabled = 'true';\n * ```\n *\n * # Styling tooltips\n *\n * By default, the tooltip has `.ck-tooltip` class and its text inner `.ck-tooltip__text`.\n *\n * If your tooltip requires custom styling, using `data-cke-tooltip-class` attribute will add additional class to the balloon\n * displaying the tooltip:\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'Tooltip with a red text';\n * domElement.dataset.ckeTooltipClass = 'my-class';\n * ```\n *\n * ```css\n * .ck.ck-tooltip.my-class { color: red }\n * ```\n *\n * **Note**: This class is a singleton. All editor instances re-use the same instance loaded by\n * {@link module:ui/editorui/editorui~EditorUI} of the first editor.\n */ class TooltipManager extends /* #__PURE__ */ DomEmitterMixin() {\n    /**\n\t * The view rendering text of the tooltip.\n\t */ tooltipTextView;\n    /**\n\t * The instance of the balloon panel that renders and positions the tooltip.\n\t */ balloonPanelView;\n    /**\n\t * A set of default {@link module:utils/dom/position~PositioningFunction positioning functions} used by the `TooltipManager`\n\t * to pin tooltips in different positions.\n\t */ static defaultBalloonPositions = /* #__PURE__ */ BalloonPanelView.generatePositions({\n        heightOffset: 5,\n        sideOffset: 13\n    });\n    /**\n\t * Stores the reference to the DOM element the tooltip is attached to. `null` when there's no tooltip\n\t * in the UI.\n\t */ _currentElementWithTooltip = null;\n    /**\n\t * Stores the current tooltip position. `null` when there's no tooltip in the UI.\n\t */ _currentTooltipPosition = null;\n    /**\n\t * An instance of the mutation observer that keeps track on target element attributes changes.\n\t */ _mutationObserver = null;\n    /**\n\t * A debounced version of {@link #_pinTooltip}. Tooltips show with a delay to avoid flashing and\n\t * to improve the UX.\n\t */ _pinTooltipDebounced;\n    /**\n\t * A debounced version of {@link #_unpinTooltip}. Tooltips hide with a delay to allow hovering of their titles.\n\t */ _unpinTooltipDebounced;\n    _watchdogExcluded;\n    /**\n\t * A set of editors the single tooltip manager instance must listen to.\n\t * This is mostly to handle `EditorUI#update` listeners from individual editors.\n\t */ static _editors = new Set();\n    /**\n\t * A reference to the `TooltipManager` instance. The class is a singleton and as such,\n\t * successive attempts at creating instances should return this instance.\n\t */ static _instance = null;\n    /**\n\t * Creates an instance of the tooltip manager.\n\t */ constructor(editor){\n        super();\n        TooltipManager._editors.add(editor);\n        // TooltipManager must be a singleton. Multiple instances would mean multiple tooltips attached\n        // to the same DOM element with data-cke-tooltip-* attributes.\n        if (TooltipManager._instance) {\n            return TooltipManager._instance;\n        }\n        TooltipManager._instance = this;\n        this.tooltipTextView = new View(editor.locale);\n        this.tooltipTextView.set('text', '');\n        this.tooltipTextView.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-tooltip__text'\n                ]\n            },\n            children: [\n                {\n                    text: this.tooltipTextView.bindTemplate.to('text')\n                }\n            ]\n        });\n        this.balloonPanelView = new BalloonPanelView(editor.locale);\n        this.balloonPanelView.class = BALLOON_CLASS;\n        this.balloonPanelView.content.add(this.tooltipTextView);\n        this._mutationObserver = createMutationObserver(()=>{\n            this._updateTooltipPosition();\n        });\n        this._pinTooltipDebounced = debounce(this._pinTooltip, 600);\n        this._unpinTooltipDebounced = debounce(this._unpinTooltip, 400);\n        this.listenTo(global.document, 'keydown', this._onKeyDown.bind(this), {\n            useCapture: true\n        });\n        this.listenTo(global.document, 'mouseenter', this._onEnterOrFocus.bind(this), {\n            useCapture: true\n        });\n        this.listenTo(global.document, 'mouseleave', this._onLeaveOrBlur.bind(this), {\n            useCapture: true\n        });\n        this.listenTo(global.document, 'focus', this._onEnterOrFocus.bind(this), {\n            useCapture: true\n        });\n        this.listenTo(global.document, 'blur', this._onLeaveOrBlur.bind(this), {\n            useCapture: true\n        });\n        this.listenTo(global.document, 'scroll', this._onScroll.bind(this), {\n            useCapture: true\n        });\n        // Because this class is a singleton, its only instance is shared across all editors and connects them through the reference.\n        // This causes issues with the ContextWatchdog. When an error is thrown in one editor, the watchdog traverses the references\n        // and (because of shared tooltip manager) figures that the error affects all editors and restarts them all.\n        // This flag, excludes tooltip manager instance from the traversal and brings ContextWatchdog back to normal.\n        // More in https://github.com/ckeditor/ckeditor5/issues/12292.\n        this._watchdogExcluded = true;\n    }\n    /**\n\t * Destroys the tooltip manager.\n\t *\n\t * **Note**: The manager singleton cannot be destroyed until all editors that use it are destroyed.\n\t *\n\t * @param editor The editor the manager was created for.\n\t */ destroy(editor) {\n        const editorBodyViewCollection = editor.ui.view && editor.ui.view.body;\n        TooltipManager._editors.delete(editor);\n        this.stopListening(editor.ui);\n        // Prevent the balloon panel from being destroyed in the EditorUI#destroy() cascade. It should be destroyed along\n        // with the last editor only (https://github.com/ckeditor/ckeditor5/issues/12602).\n        if (editorBodyViewCollection && editorBodyViewCollection.has(this.balloonPanelView)) {\n            editorBodyViewCollection.remove(this.balloonPanelView);\n        }\n        if (!TooltipManager._editors.size) {\n            this._unpinTooltip();\n            this.balloonPanelView.destroy();\n            this.stopListening();\n            TooltipManager._instance = null;\n        }\n    }\n    /**\n\t * Returns {@link #balloonPanelView} {@link module:utils/dom/position~PositioningFunction positioning functions} for a given position\n\t * name.\n\t *\n\t * @param position Name of the position (`s`, `se`, `sw`, `n`, `e`, or `w`).\n\t * @returns Positioning functions to be used by the {@link #balloonPanelView}.\n\t */ static getPositioningFunctions(position) {\n        const defaultPositions = TooltipManager.defaultBalloonPositions;\n        return ({\n            // South is most popular. We can use positioning heuristics to avoid clipping by the viewport with the sane fallback.\n            s: [\n                defaultPositions.southArrowNorth,\n                defaultPositions.southArrowNorthEast,\n                defaultPositions.southArrowNorthWest\n            ],\n            n: [\n                defaultPositions.northArrowSouth\n            ],\n            e: [\n                defaultPositions.eastArrowWest\n            ],\n            w: [\n                defaultPositions.westArrowEast\n            ],\n            sw: [\n                defaultPositions.southArrowNorthEast\n            ],\n            se: [\n                defaultPositions.southArrowNorthWest\n            ]\n        })[position];\n    }\n    /**\n\t * Handles hiding tooltips on `keydown` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */ _onKeyDown(evt, domEvent) {\n        if (domEvent.key === 'Escape' && this._currentElementWithTooltip) {\n            this._unpinTooltip();\n            domEvent.stopPropagation();\n        }\n    }\n    /**\n\t * Handles displaying tooltips on `mouseenter` and `focus` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */ _onEnterOrFocus(evt, { target }) {\n        const elementWithTooltipAttribute = getDescendantWithTooltip(target);\n        // Abort when there's no descendant needing tooltip.\n        if (!elementWithTooltipAttribute) {\n            // Unpin if element is focused, regardless of whether it contains a label or not.\n            // It also prevents tooltips from overlapping the menu bar\n            if (evt.name === 'focus') {\n                this._unpinTooltip();\n            }\n            return;\n        }\n        // Abort to avoid flashing when, for instance:\n        // * a tooltip is displayed for a focused element, then the same element gets mouseentered,\n        // * a tooltip is displayed for an element via mouseenter, then the focus moves to the same element.\n        if (elementWithTooltipAttribute === this._currentElementWithTooltip) {\n            return;\n        }\n        this._unpinTooltip();\n        // The tooltip should be pinned immediately when the element gets focused using keyboard.\n        // If it is focused using the mouse, the tooltip should be pinned after a delay to prevent flashing.\n        // See https://github.com/ckeditor/ckeditor5/issues/16383\n        if (evt.name === 'focus' && !elementWithTooltipAttribute.matches(':hover')) {\n            this._pinTooltip(elementWithTooltipAttribute, getTooltipData(elementWithTooltipAttribute));\n        } else {\n            this._pinTooltipDebounced(elementWithTooltipAttribute, getTooltipData(elementWithTooltipAttribute));\n        }\n    }\n    /**\n\t * Handles hiding tooltips on `mouseleave` and `blur` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */ _onLeaveOrBlur(evt, { target, relatedTarget }) {\n        if (evt.name === 'mouseleave') {\n            // Don't act when the event does not concern a DOM element (e.g. a mouseleave out of an entire document),\n            if (!isElement(target)) {\n                return;\n            }\n            const balloonElement = this.balloonPanelView.element;\n            const isEnteringBalloon = balloonElement && (balloonElement === relatedTarget || balloonElement.contains(relatedTarget));\n            const isLeavingBalloon = !isEnteringBalloon && target === balloonElement;\n            // Do not hide the tooltip when the user moves the cursor over it.\n            if (isEnteringBalloon) {\n                this._unpinTooltipDebounced.cancel();\n                return;\n            }\n            // If a tooltip is currently visible, don't act for a targets other than the one it is attached to.\n            // The only exception is leaving balloon, in this scenario tooltip should be closed.\n            // For instance, a random mouseleave far away in the page should not unpin the tooltip that was pinned because\n            // of a previous focus. Only leaving the same element should hide the tooltip.\n            if (!isLeavingBalloon && this._currentElementWithTooltip && target !== this._currentElementWithTooltip) {\n                return;\n            }\n            const descendantWithTooltip = getDescendantWithTooltip(target);\n            const relatedDescendantWithTooltip = getDescendantWithTooltip(relatedTarget);\n            // Unpin when the mouse was leaving element with a tooltip to a place which does not have or has a different tooltip.\n            // Note that this should happen whether the tooltip is already visible or not, for instance,\n            // it could be invisible but queued (debounced): it should get canceled.\n            if (isLeavingBalloon || descendantWithTooltip && descendantWithTooltip !== relatedDescendantWithTooltip) {\n                this._unpinTooltipDebounced();\n            }\n        } else {\n            // If a tooltip is currently visible, don't act for a targets other than the one it is attached to.\n            // For instance, a random blur in the web page should not unpin the tooltip that was pinned because of a previous mouseenter.\n            if (this._currentElementWithTooltip && target !== this._currentElementWithTooltip) {\n                return;\n            }\n            // Note that unpinning should happen whether the tooltip is already visible or not, for instance, it could be invisible but\n            // queued (debounced): it should get canceled (e.g. quick focus then quick blur using the keyboard).\n            this._unpinTooltipDebounced();\n        }\n    }\n    /**\n\t * Handles hiding tooltips on `scroll` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */ _onScroll(evt, { target }) {\n        // No tooltip, no reason to react on scroll.\n        if (!this._currentElementWithTooltip) {\n            return;\n        }\n        // When scrolling a container that has both the balloon and the current element (common ancestor), the balloon can remain\n        // visible (e.g. scrolling ≤body>). Otherwise, to avoid glitches (clipping, lagging) better just hide the tooltip.\n        // Also, don't do anything when scrolling an unrelated DOM element that has nothing to do with the current element and the balloon.\n        if (target.contains(this.balloonPanelView.element) && target.contains(this._currentElementWithTooltip)) {\n            return;\n        }\n        this._unpinTooltip();\n    }\n    /**\n\t * Pins the tooltip to a specific DOM element.\n\t *\n\t * @param options.text Text of the tooltip to display.\n\t * @param options.position The position of the tooltip.\n\t * @param options.cssClass Additional CSS class of the balloon with the tooltip.\n\t */ _pinTooltip(targetDomElement, { text, position, cssClass }) {\n        this._unpinTooltip();\n        // Use the body collection of the first editor.\n        const bodyViewCollection = first(TooltipManager._editors.values()).ui.view.body;\n        if (!bodyViewCollection.has(this.balloonPanelView)) {\n            bodyViewCollection.add(this.balloonPanelView);\n        }\n        this.tooltipTextView.text = text;\n        this.balloonPanelView.class = [\n            BALLOON_CLASS,\n            cssClass\n        ].filter((className)=>className).join(' ');\n        // Ensure that all changes to the tooltip are set before pinning it.\n        // Setting class or text after pinning can cause the tooltip to be pinned in the wrong position.\n        // It happens especially often when tooltip has class modified (like adding `ck-tooltip_multi-line`).\n        // See https://github.com/ckeditor/ckeditor5/issues/16365\n        this.balloonPanelView.pin({\n            target: targetDomElement,\n            positions: TooltipManager.getPositioningFunctions(position)\n        });\n        this._mutationObserver.attach(targetDomElement);\n        // Start responding to changes in editor UI or content layout. For instance, when collaborators change content\n        // and a contextual toolbar attached to a content starts to move (and so should move the tooltip).\n        // Note: Using low priority to let other listeners that position contextual toolbars etc. to react first.\n        for (const editor of TooltipManager._editors){\n            this.listenTo(editor.ui, 'update', this._updateTooltipPosition.bind(this), {\n                priority: 'low'\n            });\n        }\n        this._currentElementWithTooltip = targetDomElement;\n        this._currentTooltipPosition = position;\n    }\n    /**\n\t * Unpins the tooltip and cancels all queued pinning.\n\t */ _unpinTooltip() {\n        this._unpinTooltipDebounced.cancel();\n        this._pinTooltipDebounced.cancel();\n        this.balloonPanelView.unpin();\n        for (const editor of TooltipManager._editors){\n            this.stopListening(editor.ui, 'update');\n        }\n        this._currentElementWithTooltip = null;\n        this._currentTooltipPosition = null;\n        this.tooltipTextView.text = '';\n        this._mutationObserver.detach();\n    }\n    /**\n\t * Updates the position of the tooltip so it stays in sync with the element it is pinned to.\n\t *\n\t * Hides the tooltip when the element is no longer visible in DOM or the tooltip text was removed.\n\t */ _updateTooltipPosition() {\n        // The tooltip might get removed by focus listener triggered by the same UI `update` event.\n        // See https://github.com/ckeditor/ckeditor5/pull/16363.\n        if (!this._currentElementWithTooltip) {\n            return;\n        }\n        const tooltipData = getTooltipData(this._currentElementWithTooltip);\n        // This could happen if the tooltip was attached somewhere in a contextual content toolbar and the toolbar\n        // disappeared (e.g. removed an image), or the tooltip text was removed.\n        if (!isVisible(this._currentElementWithTooltip) || !tooltipData.text) {\n            this._unpinTooltip();\n            return;\n        }\n        this.balloonPanelView.pin({\n            target: this._currentElementWithTooltip,\n            positions: TooltipManager.getPositioningFunctions(tooltipData.position)\n        });\n    }\n}\nfunction getDescendantWithTooltip(element) {\n    if (!isElement(element)) {\n        return null;\n    }\n    return element.closest('[data-cke-tooltip-text]:not([data-cke-tooltip-disabled])');\n}\nfunction getTooltipData(element) {\n    return {\n        text: element.dataset.ckeTooltipText,\n        position: element.dataset.ckeTooltipPosition || 's',\n        cssClass: element.dataset.ckeTooltipClass || ''\n    };\n}\n// Creates a simple `MutationObserver` instance wrapper that observes changes in the tooltip-related attributes of the given element.\n// Used instead of the `MutationObserver` from the engine for simplicity.\nfunction createMutationObserver(callback) {\n    const mutationObserver = new MutationObserver(()=>{\n        callback();\n    });\n    return {\n        attach (element) {\n            mutationObserver.observe(element, {\n                attributes: true,\n                attributeFilter: [\n                    'data-cke-tooltip-text',\n                    'data-cke-tooltip-position'\n                ]\n            });\n        },\n        detach () {\n            mutationObserver.disconnect();\n        }\n    };\n}\n\nvar poweredByIcon = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" width=\\\"53\\\" height=\\\"10\\\" viewBox=\\\"0 0 53 10\\\"><path fill=\\\"#1C2331\\\" d=\\\"M31.724 1.492a15.139 15.139 0 0 0 .045 1.16 2.434 2.434 0 0 0-.687-.34 3.68 3.68 0 0 0-1.103-.166 2.332 2.332 0 0 0-1.14.255 1.549 1.549 0 0 0-.686.87c-.15.41-.225.98-.225 1.712 0 .939.148 1.659.444 2.161.297.503.792.754 1.487.754.452.015.9-.094 1.294-.316.296-.174.557-.4.771-.669l.14.852h1.282V.007h-1.623v1.485ZM31 6.496a1.77 1.77 0 0 1-.494.061.964.964 0 0 1-.521-.127.758.758 0 0 1-.296-.466 3.984 3.984 0 0 1-.093-.992 4.208 4.208 0 0 1 .098-1.052.753.753 0 0 1 .307-.477 1.08 1.08 0 0 1 .55-.122c.233-.004.466.026.69.089l.483.144v2.553c-.11.076-.213.143-.307.2a1.73 1.73 0 0 1-.417.189ZM35.68 0l-.702.004c-.322.002-.482.168-.48.497l.004.581c.002.33.164.493.486.49l.702-.004c.322-.002.481-.167.48-.496L36.165.49c-.002-.33-.164-.493-.486-.491ZM36.145 2.313l-1.612.01.034 5.482 1.613-.01-.035-5.482ZM39.623.79 37.989.8 38 2.306l-.946.056.006 1.009.949-.006.024 2.983c.003.476.143.844.419 1.106.275.26.658.39 1.148.387.132 0 .293-.01.483-.03.19-.02.38-.046.57-.08.163-.028.324-.068.482-.119l-.183-1.095-.702.004a.664.664 0 0 1-.456-.123.553.553 0 0 1-.14-.422l-.016-2.621 1.513-.01-.006-1.064-1.514.01-.01-1.503ZM46.226 2.388c-.41-.184-.956-.274-1.636-.27-.673.004-1.215.101-1.627.29-.402.179-.72.505-.888.91-.18.419-.268.979-.264 1.68.004.688.1 1.24.285 1.655.172.404.495.724.9.894.414.18.957.268 1.63.264.68-.004 1.224-.099 1.632-.284.4-.176.714-.501.878-.905.176-.418.263-.971.258-1.658-.004-.702-.097-1.261-.28-1.677a1.696 1.696 0 0 0-.888-.9Zm-.613 3.607a.77.77 0 0 1-.337.501 1.649 1.649 0 0 1-1.317.009.776.776 0 0 1-.343-.497 4.066 4.066 0 0 1-.105-1.02 4.136 4.136 0 0 1 .092-1.03.786.786 0 0 1 .337-.507 1.59 1.59 0 0 1 1.316-.008.79.79 0 0 1 .344.502c.078.337.113.683.105 1.03.012.343-.019.685-.092 1.02ZM52.114 2.07a2.67 2.67 0 0 0-1.128.278c-.39.191-.752.437-1.072.73l-.157-.846-1.273.008.036 5.572 1.623-.01-.024-3.78c.35-.124.646-.22.887-.286.26-.075.53-.114.8-.118l.45-.003.144-1.546-.286.001ZM22.083 7.426l-1.576-2.532a2.137 2.137 0 0 0-.172-.253 1.95 1.95 0 0 0-.304-.29.138.138 0 0 1 .042-.04 1.7 1.7 0 0 0 .328-.374l1.75-2.71c.01-.015.025-.028.024-.048-.01-.01-.021-.007-.031-.007L20.49 1.17a.078.078 0 0 0-.075.045l-.868 1.384c-.23.366-.46.732-.688 1.099a.108.108 0 0 1-.112.06c-.098-.005-.196-.001-.294-.002-.018 0-.038.006-.055-.007.002-.02.002-.039.005-.058a4.6 4.6 0 0 0 .046-.701V1.203c0-.02-.009-.032-.03-.03h-.033L16.93 1.17c-.084 0-.073-.01-.073.076v6.491c-.001.018.006.028.025.027h1.494c.083 0 .072.007.072-.071v-2.19c0-.055-.003-.11-.004-.166a3.366 3.366 0 0 0-.05-.417h.06c.104 0 .209.002.313-.002a.082.082 0 0 1 .084.05c.535.913 1.07 1.824 1.607 2.736a.104.104 0 0 0 .103.062c.554-.003 1.107-.002 1.66-.002l.069-.003-.019-.032-.188-.304ZM27.112 6.555c-.005-.08-.004-.08-.082-.08h-2.414c-.053 0-.106-.003-.159-.011a.279.279 0 0 1-.246-.209.558.558 0 0 1-.022-.15c0-.382 0-.762-.002-1.143 0-.032.007-.049.042-.044h2.504c.029.003.037-.012.034-.038V3.814c0-.089.013-.078-.076-.078h-2.44c-.07 0-.062.003-.062-.06v-.837c0-.047.004-.093.013-.14a.283.283 0 0 1 .241-.246.717.717 0 0 1 .146-.011h2.484c.024.002.035-.009.036-.033l.003-.038.03-.496c.01-.183.024-.365.034-.548.005-.085.003-.087-.082-.094-.218-.018-.437-.038-.655-.05a17.845 17.845 0 0 0-.657-.026 72.994 72.994 0 0 0-1.756-.016 1.7 1.7 0 0 0-.471.064 1.286 1.286 0 0 0-.817.655c-.099.196-.149.413-.145.633v3.875c0 .072.003.144.011.216a1.27 1.27 0 0 0 .711 1.029c.228.113.48.167.734.158.757-.005 1.515.002 2.272-.042.274-.016.548-.034.82-.053.03-.002.043-.008.04-.041-.008-.104-.012-.208-.019-.312a69.964 69.964 0 0 1-.05-.768ZM16.14 7.415l-.127-1.075c-.004-.03-.014-.04-.044-.037a13.125 13.125 0 0 1-.998.073c-.336.01-.672.02-1.008.016-.116-.001-.233-.014-.347-.039a.746.746 0 0 1-.45-.262c-.075-.1-.132-.211-.167-.33a3.324 3.324 0 0 1-.126-.773 9.113 9.113 0 0 1-.015-.749c0-.285.022-.57.065-.852.023-.158.066-.312.127-.46a.728.728 0 0 1 .518-.443 1.64 1.64 0 0 1 .397-.048c.628-.001 1.255.003 1.882.05.022.001.033-.006.036-.026l.003-.031.06-.55c.019-.177.036-.355.057-.532.004-.034-.005-.046-.04-.056a5.595 5.595 0 0 0-1.213-.21 10.783 10.783 0 0 0-.708-.02c-.24-.003-.48.01-.719.041a3.477 3.477 0 0 0-.625.14 1.912 1.912 0 0 0-.807.497c-.185.2-.33.433-.424.688a4.311 4.311 0 0 0-.24 1.096c-.031.286-.045.572-.042.86-.006.43.024.86.091 1.286.04.25.104.497.193.734.098.279.26.53.473.734.214.205.473.358.756.446.344.11.702.17 1.063.177a8.505 8.505 0 0 0 1.578-.083 6.11 6.11 0 0 0 .766-.18c.03-.008.047-.023.037-.057a.157.157 0 0 1-.003-.025Z\\\"/><path fill=\\\"#AFE229\\\" d=\\\"M6.016 6.69a1.592 1.592 0 0 0-.614.21c-.23.132-.422.32-.56.546-.044.072-.287.539-.287.539l-.836 1.528.009.006c.038.025.08.046.123.063.127.046.26.07.395.073.505.023 1.011-.007 1.517-.003.29.009.58.002.869-.022a.886.886 0 0 0 .395-.116.962.962 0 0 0 .312-.286c.056-.083.114-.163.164-.249.24-.408.48-.816.718-1.226.075-.128.148-.257.222-.386l.112-.192a1.07 1.07 0 0 0 .153-.518l-1.304.023s-1.258-.005-1.388.01Z\\\"/><path fill=\\\"#771BFF\\\" d=\\\"m2.848 9.044.76-1.39.184-.352c-.124-.067-.245-.14-.367-.21-.346-.204-.706-.384-1.045-.6a.984.984 0 0 1-.244-.207c-.108-.134-.136-.294-.144-.46-.021-.409-.002-.818-.009-1.227-.003-.195 0-.39.003-.585.004-.322.153-.553.427-.713l.833-.488c.22-.13.44-.257.662-.385.05-.029.105-.052.158-.077.272-.128.519-.047.76.085l.044.028c.123.06.242.125.358.196.318.178.635.357.952.537.095.056.187.117.275.184.194.144.254.35.266.578.016.284.007.569.006.853-.001.28.004.558 0 .838.592-.003 1.259 0 1.259 0l.723-.013c-.003-.292-.007-.584-.007-.876 0-.524.015-1.048-.016-1.571-.024-.42-.135-.8-.492-1.067a5.02 5.02 0 0 0-.506-.339A400.52 400.52 0 0 0 5.94.787C5.722.664 5.513.524 5.282.423 5.255.406 5.228.388 5.2.373 4.758.126 4.305-.026 3.807.21c-.097.046-.197.087-.29.14A699.896 699.896 0 0 0 .783 1.948c-.501.294-.773.717-.778 1.31-.004.36-.009.718-.001 1.077.016.754-.017 1.508.024 2.261.016.304.07.6.269.848.127.15.279.28.448.382.622.4 1.283.734 1.92 1.11l.183.109Z\\\"/></svg>\\n\";\n\nconst ICON_WIDTH = 53;\nconst ICON_HEIGHT = 10;\n// ⚠ Note, whenever changing the threshold, make sure to update the docs/support/managing-ckeditor-logo.md docs\n// as this information is also mentioned there ⚠.\nconst NARROW_ROOT_HEIGHT_THRESHOLD = 50;\nconst NARROW_ROOT_WIDTH_THRESHOLD = 350;\nconst DEFAULT_LABEL = 'Powered by';\n/**\n * A helper that enables the \"powered by\" feature in the editor and renders a link to the project's\n * webpage next to the bottom of the editable element (editor root, source editing area, etc.) when the editor is focused.\n *\n * @private\n */ class PoweredBy extends /* #__PURE__ */ DomEmitterMixin() {\n    /**\n\t * Editor instance the helper was created for.\n\t */ editor;\n    /**\n\t * A reference to the balloon panel hosting and positioning the \"powered by\" link and logo.\n\t */ _balloonView;\n    /**\n\t * A throttled version of the {@link #_showBalloon} method meant for frequent use to avoid performance loss.\n\t */ _showBalloonThrottled;\n    /**\n\t * A reference to the last editable element (root, source editing area, etc.) focused by the user.\n\t * Since the focus can move to other focusable elements in the UI, this reference allows positioning the balloon over the\n\t * right element whether the user is typing or using the UI.\n\t */ _lastFocusedEditableElement;\n    /**\n\t * Creates a \"powered by\" helper for a given editor. The feature is initialized on Editor#ready\n\t * event.\n\t *\n\t * @param editor\n\t */ constructor(editor){\n        super();\n        this.editor = editor;\n        this._balloonView = null;\n        this._lastFocusedEditableElement = null;\n        this._showBalloonThrottled = throttle(this._showBalloon.bind(this), 50, {\n            leading: true\n        });\n        editor.on('ready', this._handleEditorReady.bind(this));\n    }\n    /**\n\t * Destroys the \"powered by\" helper along with its view.\n\t */ destroy() {\n        const balloon = this._balloonView;\n        if (balloon) {\n            // Balloon gets destroyed by the body collection.\n            // The powered by view gets destroyed by the balloon.\n            balloon.unpin();\n            this._balloonView = null;\n        }\n        this._showBalloonThrottled.cancel();\n        this.stopListening();\n    }\n    /**\n\t * Enables \"powered by\" label once the editor (ui) is ready.\n\t */ _handleEditorReady() {\n        const editor = this.editor;\n        const forceVisible = !!editor.config.get('ui.poweredBy.forceVisible');\n        /* istanbul ignore next -- @preserve */ if (!forceVisible && verifyLicense(editor.config.get('licenseKey')) === 'VALID') {\n            return;\n        }\n        // No view means no body collection to append the powered by balloon to.\n        if (!editor.ui.view) {\n            return;\n        }\n        editor.ui.focusTracker.on('change:isFocused', (evt, data, isFocused)=>{\n            this._updateLastFocusedEditableElement();\n            if (isFocused) {\n                this._showBalloon();\n            } else {\n                this._hideBalloon();\n            }\n        });\n        editor.ui.focusTracker.on('change:focusedElement', (evt, data, focusedElement)=>{\n            this._updateLastFocusedEditableElement();\n            if (focusedElement) {\n                this._showBalloon();\n            }\n        });\n        editor.ui.on('update', ()=>{\n            this._showBalloonThrottled();\n        });\n    }\n    /**\n\t * Creates an instance of the {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView balloon panel}\n\t * with the \"powered by\" view inside ready for positioning.\n\t */ _createBalloonView() {\n        const editor = this.editor;\n        const balloon = this._balloonView = new BalloonPanelView();\n        const poweredByConfig = getNormalizedConfig(editor);\n        const view = new PoweredByView(editor.locale, poweredByConfig.label);\n        balloon.content.add(view);\n        balloon.set({\n            class: 'ck-powered-by-balloon'\n        });\n        editor.ui.view.body.add(balloon);\n        this._balloonView = balloon;\n    }\n    /**\n\t * Attempts to display the balloon with the \"powered by\" view.\n\t */ _showBalloon() {\n        if (!this._lastFocusedEditableElement) {\n            return;\n        }\n        const attachOptions = getBalloonAttachOptions(this.editor, this._lastFocusedEditableElement);\n        if (attachOptions) {\n            if (!this._balloonView) {\n                this._createBalloonView();\n            }\n            this._balloonView.pin(attachOptions);\n        }\n    }\n    /**\n\t * Hides the \"powered by\" balloon if already visible.\n\t */ _hideBalloon() {\n        if (this._balloonView) {\n            this._balloonView.unpin();\n        }\n    }\n    /**\n\t * Updates the {@link #_lastFocusedEditableElement} based on the state of the global focus tracker.\n\t */ _updateLastFocusedEditableElement() {\n        const editor = this.editor;\n        const isFocused = editor.ui.focusTracker.isFocused;\n        const focusedElement = editor.ui.focusTracker.focusedElement;\n        if (!isFocused || !focusedElement) {\n            this._lastFocusedEditableElement = null;\n            return;\n        }\n        const editableEditorElements = Array.from(editor.ui.getEditableElementsNames()).map((name)=>{\n            return editor.ui.getEditableElement(name);\n        });\n        if (editableEditorElements.includes(focusedElement)) {\n            this._lastFocusedEditableElement = focusedElement;\n        } else {\n            // If it's none of the editable element, then the focus is somewhere in the UI. Let's display powered by\n            // over the first element then.\n            this._lastFocusedEditableElement = editableEditorElements[0];\n        }\n    }\n}\n/**\n * A view displaying a \"powered by\" label and project logo wrapped in a link.\n */ class PoweredByView extends View {\n    /**\n\t * Created an instance of the \"powered by\" view.\n\t *\n\t * @param locale The localization services instance.\n\t * @param label The label text.\n\t */ constructor(locale, label){\n        super(locale);\n        const iconView = new IconView();\n        const bind = this.bindTemplate;\n        iconView.set({\n            content: poweredByIcon,\n            isColorInherited: false\n        });\n        iconView.extendTemplate({\n            attributes: {\n                style: {\n                    width: ICON_WIDTH + 'px',\n                    height: ICON_HEIGHT + 'px'\n                }\n            }\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-powered-by'\n                ],\n                'aria-hidden': true\n            },\n            children: [\n                {\n                    tag: 'a',\n                    attributes: {\n                        href: 'https://ckeditor.com/powered-by-ckeditor/?utm_source=ckeditor&' + 'utm_medium=referral&utm_campaign=701Dn000000hVgmIAE_powered_by_ckeditor_logo',\n                        target: '_blank',\n                        tabindex: '-1'\n                    },\n                    children: [\n                        ...label ? [\n                            {\n                                tag: 'span',\n                                attributes: {\n                                    class: [\n                                        'ck',\n                                        'ck-powered-by__label'\n                                    ]\n                                },\n                                children: [\n                                    label\n                                ]\n                            }\n                        ] : [],\n                        iconView\n                    ],\n                    on: {\n                        dragstart: bind.to((evt)=>evt.preventDefault())\n                    }\n                }\n            ]\n        });\n    }\n}\nfunction getBalloonAttachOptions(editor, focusedEditableElement) {\n    const poweredByConfig = getNormalizedConfig(editor);\n    const positioningFunction = poweredByConfig.side === 'right' ? getLowerRightCornerPosition(focusedEditableElement, poweredByConfig) : getLowerLeftCornerPosition(focusedEditableElement, poweredByConfig);\n    return {\n        target: focusedEditableElement,\n        positions: [\n            positioningFunction\n        ]\n    };\n}\nfunction getLowerRightCornerPosition(focusedEditableElement, config) {\n    return getLowerCornerPosition(focusedEditableElement, config, (rootRect, balloonRect)=>{\n        return rootRect.left + rootRect.width - balloonRect.width - config.horizontalOffset;\n    });\n}\nfunction getLowerLeftCornerPosition(focusedEditableElement, config) {\n    return getLowerCornerPosition(focusedEditableElement, config, (rootRect)=>rootRect.left + config.horizontalOffset);\n}\nfunction getLowerCornerPosition(focusedEditableElement, config, getBalloonLeft) {\n    return (visibleEditableElementRect, balloonRect)=>{\n        const editableElementRect = new Rect(focusedEditableElement);\n        if (editableElementRect.width < NARROW_ROOT_WIDTH_THRESHOLD || editableElementRect.height < NARROW_ROOT_HEIGHT_THRESHOLD) {\n            return null;\n        }\n        let balloonTop;\n        if (config.position === 'inside') {\n            balloonTop = editableElementRect.bottom - balloonRect.height;\n        } else {\n            balloonTop = editableElementRect.bottom - balloonRect.height / 2;\n        }\n        balloonTop -= config.verticalOffset;\n        const balloonLeft = getBalloonLeft(editableElementRect, balloonRect);\n        // Clone the editable element rect and place it where the balloon would be placed.\n        // This will allow getVisible() to work from editable element's perspective (rect source).\n        // and yield a result as if the balloon was on the same (scrollable) layer as the editable element.\n        const newBalloonPositionRect = visibleEditableElementRect.clone().moveTo(balloonLeft, balloonTop).getIntersection(balloonRect.clone().moveTo(balloonLeft, balloonTop));\n        const newBalloonPositionVisibleRect = newBalloonPositionRect.getVisible();\n        if (!newBalloonPositionVisibleRect || newBalloonPositionVisibleRect.getArea() < balloonRect.getArea()) {\n            return null;\n        }\n        return {\n            top: balloonTop,\n            left: balloonLeft,\n            name: `position_${config.position}-side_${config.side}`,\n            config: {\n                withArrow: false\n            }\n        };\n    };\n}\nfunction getNormalizedConfig(editor) {\n    const userConfig = editor.config.get('ui.poweredBy');\n    const position = userConfig && userConfig.position || 'border';\n    return {\n        position,\n        label: DEFAULT_LABEL,\n        verticalOffset: position === 'inside' ? 5 : 0,\n        horizontalOffset: 5,\n        side: editor.locale.contentLanguageDirection === 'ltr' ? 'right' : 'left',\n        ...userConfig\n    };\n}\n\n/**\n * The politeness level of an `aria-live` announcement.\n *\n * Available keys are:\n * * `AriaLiveAnnouncerPoliteness.POLITE`,\n * * `AriaLiveAnnouncerPoliteness.ASSERTIVE`\n *\n * [Learn more](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions#Politeness_levels).\n */ const AriaLiveAnnouncerPoliteness = {\n    POLITE: 'polite',\n    ASSERTIVE: 'assertive'\n};\n/**\n * An accessibility helper that manages all ARIA live regions associated with an editor instance. ARIA live regions announce changes\n * to the state of the editor features.\n *\n * These announcements are consumed and propagated by screen readers and give users a better understanding of the current\n * state of the editor.\n *\n * To announce a state change to an editor use the {@link #announce} method:\n *\n * ```ts\n * editor.ui.ariaLiveAnnouncer.announce( 'Text of an announcement.' );\n * ```\n */ class AriaLiveAnnouncer {\n    /**\n\t * The editor instance.\n\t */ editor;\n    /**\n\t * The view that aggregates all `aria-live` regions.\n\t */ view;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        this.editor = editor;\n        /**\n\t\t * Some screen readers only look at changes in the aria-live region.\n\t\t * They might not read a region that already has content when it is added.\n\t\t * To stop this problem, make sure to set up regions for all politeness settings when the editor starts.\n\t\t */ editor.once('ready', ()=>{\n            for (const politeness of Object.values(AriaLiveAnnouncerPoliteness)){\n                this.announce('', politeness);\n            }\n        });\n    }\n    /**\n\t * Sets an announcement text to an aria region that is then announced by a screen reader to the user.\n\t *\n\t * If the aria region of a specified politeness does not exist, it will be created and can be re-used later.\n\t *\n\t * The default announcement politeness level is `'polite'`.\n\t *\n\t * ```ts\n\t * // Most screen readers will queue announcements from multiple aria-live regions and read them out in the order they were emitted.\n \t * editor.ui.ariaLiveAnnouncer.announce( 'Image uploaded.' );\n \t * editor.ui.ariaLiveAnnouncer.announce( 'Connection lost. Reconnecting.' );\n \t * ```\n\t */ announce(announcement, attributes = AriaLiveAnnouncerPoliteness.POLITE) {\n        const editor = this.editor;\n        if (!editor.ui.view) {\n            return;\n        }\n        if (!this.view) {\n            this.view = new AriaLiveAnnouncerView(editor.locale);\n            editor.ui.view.body.add(this.view);\n        }\n        const { politeness, isUnsafeHTML } = typeof attributes === 'string' ? {\n            politeness: attributes\n        } : attributes;\n        let politenessRegionView = this.view.regionViews.find((view)=>view.politeness === politeness);\n        if (!politenessRegionView) {\n            politenessRegionView = new AriaLiveAnnouncerRegionView(editor, politeness);\n            this.view.regionViews.add(politenessRegionView);\n        }\n        politenessRegionView.announce({\n            announcement,\n            isUnsafeHTML\n        });\n    }\n}\n/**\n * The view that aggregates all `aria-live` regions.\n */ class AriaLiveAnnouncerView extends View {\n    /**\n\t * A collection of all views that represent individual `aria-live` regions.\n\t */ regionViews;\n    constructor(locale){\n        super(locale);\n        this.regionViews = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-aria-live-announcer'\n                ]\n            },\n            children: this.regionViews\n        });\n    }\n}\n/**\n * The view that represents a single `aria-live`.\n */ class AriaLiveAnnouncerRegionView extends View {\n    /**\n\t * Current politeness level of the region.\n\t */ politeness;\n    /**\n\t * DOM converter used to sanitize unsafe HTML passed to {@link #announce} method.\n\t */ _domConverter;\n    /**\n\t * Interval used to remove additions. It prevents accumulation of added nodes in region.\n\t */ _pruneAnnouncementsInterval;\n    constructor(editor, politeness){\n        super(editor.locale);\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                'aria-live': politeness,\n                'aria-relevant': 'additions'\n            },\n            children: [\n                {\n                    tag: 'ul',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-aria-live-region-list'\n                        ]\n                    }\n                }\n            ]\n        });\n        editor.on('destroy', ()=>{\n            if (this._pruneAnnouncementsInterval !== null) {\n                clearInterval(this._pruneAnnouncementsInterval);\n                this._pruneAnnouncementsInterval = null;\n            }\n        });\n        this.politeness = politeness;\n        this._domConverter = editor.data.htmlProcessor.domConverter;\n        this._pruneAnnouncementsInterval = setInterval(()=>{\n            if (this.element && this._listElement.firstChild) {\n                this._listElement.firstChild.remove();\n            }\n        }, 5000);\n    }\n    /**\n\t * Appends new announcement to region.\n\t */ announce({ announcement, isUnsafeHTML }) {\n        if (!announcement.trim().length) {\n            return;\n        }\n        const messageListItem = document.createElement('li');\n        if (isUnsafeHTML) {\n            this._domConverter.setContentOf(messageListItem, announcement);\n        } else {\n            messageListItem.innerText = announcement;\n        }\n        this._listElement.appendChild(messageListItem);\n    }\n    /**\n\t * Return current announcements list HTML element.\n\t */ get _listElement() {\n        return this.element.querySelector('ul');\n    }\n}\n\n/**\n * A menu bar list item view, a child of {@link module:ui/menubar/menubarmenulistview~MenuBarMenuListView}.\n *\n * Populate this item with a {@link module:ui/menubar/menubarmenulistitembuttonview~MenuBarMenuListItemButtonView} instance\n * or a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} instance to create a sub-menu.\n */ class MenuBarMenuListItemView extends ListItemView {\n    /**\n\t * Creates an instance of the list item view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale, parentMenuView){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-menu-bar__menu__item'\n                ]\n            },\n            on: {\n                'mouseenter': bind.to('mouseenter')\n            }\n        });\n        this.delegate('mouseenter').to(parentMenuView);\n    }\n}\n\nconst NESTED_PANEL_HORIZONTAL_OFFSET = 5;\n/**\n * Behaviors of the {@link module:ui/menubar/menubarview~MenuBarView} component.\n */ const MenuBarBehaviors = {\n    /**\n\t * When the bar is already open:\n\t * * Opens the menu when the user hovers over its button.\n\t * * Closes open menu when another menu's button gets hovered.\n\t */ toggleMenusAndFocusItemsOnHover (menuBarView) {\n        menuBarView.on('menu:mouseenter', (evt)=>{\n            // This behavior should be activated when one of condition is present:\n            // 1. The user opened any submenu of menubar and hover over items in the menu bar.\n            // 2. The user focused whole menubar using keyboard interaction and enabled focus borders and hover over items in the menu bar.\n            if (!menuBarView.isFocusBorderEnabled && !menuBarView.isOpen) {\n                return;\n            }\n            if (menuBarView.isOpen) {\n                for (const menuView of menuBarView.menus){\n                    // @if CK_DEBUG_MENU_BAR // const wasOpen = menuView.isOpen;\n                    const pathLeaf = evt.path[0];\n                    const isListItemContainingMenu = pathLeaf instanceof MenuBarMenuListItemView && pathLeaf.children.first === menuView;\n                    menuView.isOpen = (evt.path.includes(menuView) || isListItemContainingMenu) && menuView.isEnabled;\n                // @if CK_DEBUG_MENU_BAR // if ( wasOpen !== menuView.isOpen ) {\n                // @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] toggleMenusAndFocusItemsOnHover(): Toggle',\n                // @if CK_DEBUG_MENU_BAR // \tlogMenu( menuView ), 'isOpen', menuView.isOpen\n                // @if CK_DEBUG_MENU_BAR // );\n                // @if CK_DEBUG_MENU_BAR // }\n                }\n            }\n            evt.source.focus();\n        });\n    },\n    /**\n\t * Moves between top-level menus using the arrow left and right keys.\n\t *\n\t * If the menubar has already been open, the arrow keys move focus between top-level menu buttons and open them.\n\t * If the menubar is closed, the arrow keys only move focus between top-level menu buttons.\n\t */ focusCycleMenusOnArrows (menuBarView) {\n        const isContentRTL = menuBarView.locale.uiLanguageDirection === 'rtl';\n        menuBarView.on('menu:arrowright', (evt)=>{\n            cycleTopLevelMenus(evt.source, isContentRTL ? -1 : 1);\n        });\n        menuBarView.on('menu:arrowleft', (evt)=>{\n            cycleTopLevelMenus(evt.source, isContentRTL ? 1 : -1);\n        });\n        function cycleTopLevelMenus(currentMenuView, step) {\n            const currentIndex = menuBarView.children.getIndex(currentMenuView);\n            const isCurrentMenuViewOpen = currentMenuView.isOpen;\n            const menusCount = menuBarView.children.length;\n            const menuViewToOpen = menuBarView.children.get((currentIndex + menusCount + step) % menusCount);\n            currentMenuView.isOpen = false;\n            if (isCurrentMenuViewOpen) {\n                menuViewToOpen.isOpen = true;\n            }\n            menuViewToOpen.buttonView.focus();\n        }\n    },\n    /**\n\t * Closes the entire sub-menu structure when the bar is closed. This prevents sub-menus from being open if the user\n\t * closes the entire bar, and then re-opens some top-level menu.\n\t */ closeMenusWhenTheBarCloses (menuBarView) {\n        menuBarView.on('change:isOpen', ()=>{\n            if (!menuBarView.isOpen) {\n                menuBarView.menus.forEach((menuView)=>{\n                    menuView.isOpen = false;\n                // @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] closeMenusWhenTheBarCloses(): Closing', logMenu( menuView ) );\n                });\n            }\n        });\n    },\n    /**\n\t * Handles the following case:\n\t * 1. Hover to open a sub-menu (A). The button has focus.\n\t * 2. Press arrow up/down to move focus to another sub-menu (B) button.\n\t * 3. Press arrow right to open the sub-menu (B).\n\t * 4. The sub-menu (A) should close as it would with `toggleMenusAndFocusItemsOnHover()`.\n\t */ closeMenuWhenAnotherOnTheSameLevelOpens (menuBarView) {\n        menuBarView.on('menu:change:isOpen', (evt, name, isOpen)=>{\n            if (isOpen) {\n                menuBarView.menus.filter((menuView)=>{\n                    return evt.source.parentMenuView === menuView.parentMenuView && evt.source !== menuView && menuView.isOpen;\n                }).forEach((menuView)=>{\n                    menuView.isOpen = false;\n                // @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] closeMenuWhenAnotherOpens(): Closing', logMenu( menuView ) );\n                });\n            }\n        });\n    },\n    /**\n\t * Closes the bar when the user clicked outside of it (page body, editor root, etc.).\n\t */ closeOnClickOutside (menuBarView) {\n        clickOutsideHandler({\n            emitter: menuBarView,\n            activator: ()=>menuBarView.isOpen,\n            callback: ()=>menuBarView.close(),\n            contextElements: ()=>menuBarView.children.map((child)=>child.element)\n        });\n    },\n    /**\n\t * Tracks the keyboard focus interaction on the menu bar view. It is used to determine if the nested items\n\t * of the menu bar should render focus rings after first interaction with the keyboard.\n\t */ enableFocusHighlightOnInteraction (menuBarView) {\n        let isKeyPressed = false;\n        menuBarView.on('change:isOpen', (_, evt, isOpen)=>{\n            if (!isOpen) {\n                // Keep the focus border if the menu bar was closed by a keyboard interaction (Esc key).\n                // The user remains in the keyboard navigation mode and can traverse the main categories.\n                // See https://github.com/ckeditor/ckeditor5/issues/16719.\n                if (!isKeyPressed) {\n                    menuBarView.isFocusBorderEnabled = false;\n                }\n                // Reset the flag when the menu bar is closed, menu items tend to intercept `keyup` event\n                // and sometimes, after pressing `enter` on focused item, `isKeyPressed` stuck in `true` state.\n                isKeyPressed = false;\n            }\n        });\n        menuBarView.listenTo(menuBarView.element, 'keydown', ()=>{\n            isKeyPressed = true;\n        }, {\n            useCapture: true\n        });\n        menuBarView.listenTo(menuBarView.element, 'keyup', ()=>{\n            isKeyPressed = false;\n        }, {\n            useCapture: true\n        });\n        menuBarView.listenTo(menuBarView.element, 'focus', ()=>{\n            if (isKeyPressed) {\n                menuBarView.isFocusBorderEnabled = true;\n            }\n        }, {\n            useCapture: true\n        });\n    }\n};\n/**\n * Behaviors of the {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} component.\n */ const MenuBarMenuBehaviors = {\n    /**\n\t * If the button of the menu is focused, pressing the arrow down key should open the panel and focus it.\n\t * This is analogous to the {@link module:ui/dropdown/dropdownview~DropdownView}.\n\t */ openAndFocusPanelOnArrowDownKey (menuView) {\n        menuView.keystrokes.set('arrowdown', (data, cancel)=>{\n            if (menuView.focusTracker.focusedElement === menuView.buttonView.element) {\n                if (!menuView.isOpen) {\n                    menuView.isOpen = true;\n                }\n                menuView.panelView.focus();\n                cancel();\n            }\n        });\n    },\n    /**\n\t * Open the menu on the right arrow key press. This allows for navigating to sub-menus using the keyboard.\n\t */ openOnArrowRightKey (menuView) {\n        const keystroke = menuView.locale.uiLanguageDirection === 'rtl' ? 'arrowleft' : 'arrowright';\n        menuView.keystrokes.set(keystroke, (data, cancel)=>{\n            if (menuView.focusTracker.focusedElement !== menuView.buttonView.element || !menuView.isEnabled) {\n                return;\n            }\n            // @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] openOnArrowRightKey(): Opening', logMenu( menuView ) );\n            if (!menuView.isOpen) {\n                menuView.isOpen = true;\n            }\n            menuView.panelView.focus();\n            cancel();\n        });\n    },\n    /**\n\t * Opens the menu on its button click. Note that this behavior only opens but never closes the menu (unlike\n\t * {@link module:ui/dropdown/dropdownview~DropdownView}).\n\t */ openOnButtonClick (menuView) {\n        menuView.buttonView.on('execute', ()=>{\n            menuView.isOpen = true;\n        });\n    },\n    /**\n\t * Toggles the menu on its button click. This behavior is analogous to {@link module:ui/dropdown/dropdownview~DropdownView}.\n\t */ toggleOnButtonClick (menuView) {\n        menuView.buttonView.on('execute', ()=>{\n            menuView.isOpen = !menuView.isOpen;\n        });\n    },\n    /**\n\t * Opens the menu and focuses the panel content upon pressing the Enter key.\n\t */ openAndFocusOnEnterKeyPress (menuView) {\n        menuView.keystrokes.set('enter', (data, cancel)=>{\n            // Engage only for Enter key press when the button is focused. The panel can contain\n            // other UI components and features that rely on the Enter key press.\n            if (menuView.focusTracker.focusedElement !== menuView.buttonView.element) {\n                return;\n            }\n            menuView.isOpen = true;\n            menuView.panelView.focus();\n            cancel();\n        });\n    },\n    /**\n\t * Closes the menu on the right left key press. This allows for navigating to sub-menus using the keyboard.\n\t */ closeOnArrowLeftKey (menuView) {\n        const keystroke = menuView.locale.uiLanguageDirection === 'rtl' ? 'arrowright' : 'arrowleft';\n        menuView.keystrokes.set(keystroke, (data, cancel)=>{\n            if (menuView.isOpen) {\n                menuView.isOpen = false;\n                menuView.focus();\n                cancel();\n            }\n        });\n    },\n    /**\n\t * Closes the menu on the esc key press. This allows for navigating to sub-menus using the keyboard.\n\t */ closeOnEscKey (menuView) {\n        menuView.keystrokes.set('esc', (data, cancel)=>{\n            if (menuView.isOpen) {\n                menuView.isOpen = false;\n                menuView.focus();\n                cancel();\n            }\n        });\n    },\n    /**\n\t * Closes the menu when its parent menu also closed. This prevents from orphaned open menus when the parent menu re-opens.\n\t */ closeOnParentClose (menuView) {\n        menuView.parentMenuView.on('change:isOpen', (evt, name, isOpen)=>{\n            if (!isOpen && evt.source === menuView.parentMenuView) {\n                // @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] closeOnParentClose(): Closing', logMenu( menuView ) );\n                menuView.isOpen = false;\n            }\n        });\n    }\n};\n// @if CK_DEBUG_MENU_BAR // function logMenu( menuView: MenuBarMenuView ) {\n// @if CK_DEBUG_MENU_BAR //\treturn `\"${ menuView.buttonView.label }\"`;\n// @if CK_DEBUG_MENU_BAR // }\n/**\n * Contains every positioning function used by {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} that decides where the\n * {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#panelView} should be placed.\n *\n * Top-level menu positioning functions:\n *\n *\t┌──────┐\n *\t│      │\n *\t├──────┴────────┐\n *\t│               │\n *\t│               │\n *\t│               │\n *\t│            SE │\n *\t└───────────────┘\n *\n *\t         ┌──────┐\n *\t         │      │\n *\t┌────────┴──────┤\n *\t│               │\n *\t│               │\n *\t│               │\n *\t│ SW            │\n *\t└───────────────┘\n *\n *\t┌───────────────┐\n *\t│ NW            │\n *\t│               │\n *\t│               │\n *\t│               │\n *\t└────────┬──────┤\n *\t         │      │\n *\t         └──────┘\n *\n *\t┌───────────────┐\n *\t│            NE │\n *\t│               │\n *\t│               │\n *\t│               │\n *\t├──────┬────────┘\n *\t│      │\n *\t└──────┘\n *\n * Sub-menu positioning functions:\n *\n *\t┌──────┬───────────────┐\n *\t│      │               │\n *\t└──────┤               │\n *\t       │               │\n *\t       │            ES │\n *\t       └───────────────┘\n *\n *\t┌───────────────┬──────┐\n *\t│               │      │\n *\t│               ├──────┘\n *\t│               │\n *\t│ WS            │\n *\t└───────────────┘\n *\n *\t       ┌───────────────┐\n *\t       │            EN │\n *\t       │               │\n *\t┌──────┤               │\n *\t│      │               │\n *\t└──────┴───────────────┘\n *\n *\t┌───────────────┐\n *\t│ WN            │\n *\t│               │\n *\t│               ├──────┐\n *\t│               │      │\n *\t└───────────────┴──────┘\n */ const MenuBarMenuViewPanelPositioningFunctions = {\n    southEast: (buttonRect)=>{\n        return {\n            top: buttonRect.bottom,\n            left: buttonRect.left,\n            name: 'se'\n        };\n    },\n    southWest: (buttonRect, panelRect)=>{\n        return {\n            top: buttonRect.bottom,\n            left: buttonRect.left - panelRect.width + buttonRect.width,\n            name: 'sw'\n        };\n    },\n    northEast: (buttonRect, panelRect)=>{\n        return {\n            top: buttonRect.top - panelRect.height,\n            left: buttonRect.left,\n            name: 'ne'\n        };\n    },\n    northWest: (buttonRect, panelRect)=>{\n        return {\n            top: buttonRect.top - panelRect.height,\n            left: buttonRect.left - panelRect.width + buttonRect.width,\n            name: 'nw'\n        };\n    },\n    eastSouth: (buttonRect)=>{\n        return {\n            top: buttonRect.top,\n            left: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET,\n            name: 'es'\n        };\n    },\n    eastNorth: (buttonRect, panelRect)=>{\n        return {\n            top: buttonRect.top - panelRect.height,\n            left: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET,\n            name: 'en'\n        };\n    },\n    westSouth: (buttonRect, panelRect)=>{\n        return {\n            top: buttonRect.top,\n            left: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET,\n            name: 'ws'\n        };\n    },\n    westNorth: (buttonRect, panelRect)=>{\n        return {\n            top: buttonRect.top - panelRect.height,\n            left: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET,\n            name: 'wn'\n        };\n    }\n};\n/**\n * The default items {@link module:core/editor/editorconfig~EditorConfig#menuBar configuration} of the\n * {@link module:ui/menubar/menubarview~MenuBarView} component. It contains names of all menu bar components\n * registered in the {@link module:ui/componentfactory~ComponentFactory component factory} (available in the project).\n *\n * **Note**: Menu bar component names provided by core editor features are prefixed with `menuBar:` in order to distinguish\n * them from components referenced by the {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}, for instance,\n * `'menuBar:bold'` is a menu bar button but `'bold'` is a toolbar button.\n *\n * Below is the preset menu bar structure (the default value of `config.menuBar.items` property):\n *\n * ```ts\n * [\n * \t{\n * \t\tmenuId: 'file',\n * \t\tlabel: 'File',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'export',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:exportPdf',\n * \t\t\t\t\t'menuBar:exportWord'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'import',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:importWord'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'revisionHistory',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:revisionHistory'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'edit',\n * \t\tlabel: 'Edit',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'undo',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:undo',\n * \t\t\t\t\t'menuBar:redo'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'selectAll',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:selectAll'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'findAndReplace',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:findAndReplace'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'view',\n * \t\tlabel: 'View',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'sourceEditing',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:sourceEditing'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'showBlocks',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:showBlocks'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'previewMergeFields',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:previewMergeFields'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'restrictedEditingException',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:restrictedEditingException'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'insert',\n * \t\tlabel: 'Insert',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertMainWidgets',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:insertImage',\n * \t\t\t\t\t'menuBar:ckbox',\n * \t\t\t\t\t'menuBar:ckfinder',\n * \t\t\t\t\t'menuBar:insertTable'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertInline',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:link',\n * \t\t\t\t\t'menuBar:comment',\n * \t\t\t\t\t'menuBar:insertMergeField'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertMinorWidgets',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:mediaEmbed',\n * \t\t\t\t\t'menuBar:insertTemplate',\n * \t\t\t\t\t'menuBar:blockQuote',\n * \t\t\t\t\t'menuBar:codeBlock',\n * \t\t\t\t\t'menuBar:htmlEmbed'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertStructureWidgets',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:horizontalLine',\n * \t\t\t\t\t'menuBar:pageBreak',\n * \t\t\t\t\t'menuBar:tableOfContents'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'restrictedEditing',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:restrictedEditing'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'format',\n * \t\tlabel: 'Format',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'textAndFont',\n * \t\t\t\titems: [\n * \t\t\t\t\t{\n * \t\t\t\t\t\tmenuId: 'text',\n * \t\t\t\t\t\tlabel: 'Text',\n * \t\t\t\t\t\tgroups: [\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'basicStyles',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:bold',\n * \t\t\t\t\t\t\t\t\t'menuBar:italic',\n * \t\t\t\t\t\t\t\t\t'menuBar:underline',\n * \t\t\t\t\t\t\t\t\t'menuBar:strikethrough',\n * \t\t\t\t\t\t\t\t\t'menuBar:superscript',\n * \t\t\t\t\t\t\t\t\t'menuBar:subscript',\n * \t\t\t\t\t\t\t\t\t'menuBar:code'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t},\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'textPartLanguage',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:textPartLanguage'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t}\n * \t\t\t\t\t\t]\n * \t\t\t\t\t},\n * \t\t\t\t\t{\n * \t\t\t\t\t\tmenuId: 'font',\n * \t\t\t\t\t\tlabel: 'Font',\n * \t\t\t\t\t\tgroups: [\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'fontProperties',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:fontSize',\n * \t\t\t\t\t\t\t\t\t'menuBar:fontFamily'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t},\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'fontColors',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:fontColor',\n * \t\t\t\t\t\t\t\t\t'menuBar:fontBackgroundColor'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t},\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'highlight',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:highlight'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t}\n * \t\t\t\t\t\t]\n * \t\t\t\t\t},\n * \t\t\t\t\t'menuBar:heading'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'list',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:bulletedList',\n * \t\t\t\t\t'menuBar:numberedList',\n * \t\t\t\t\t'menuBar:multiLevelList',\n * \t\t\t\t\t'menuBar:todoList'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'indent',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:alignment',\n * \t\t\t\t\t'menuBar:indent',\n * \t\t\t\t\t'menuBar:outdent'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'caseChange',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:caseChange'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'removeFormat',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:removeFormat'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'tools',\n * \t\tlabel: 'Tools',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'aiTools',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:aiAssistant',\n * \t\t\t\t\t'menuBar:aiCommands'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'tools',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:trackChanges',\n * \t\t\t\t\t'menuBar:commentsArchive'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'help',\n * \t\tlabel: 'Help',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'help',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:accessibilityHelp'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t}\n * ];\n * ```\n *\n * The menu bar can be customized using the `config.menuBar.removeItems` and `config.menuBar.addItems` properties.\n */ // **NOTE: Whenever you make changes to this value, reflect it in the documentation above!**\nconst DefaultMenuBarItems = [\n    {\n        menuId: 'file',\n        label: 'File',\n        groups: [\n            {\n                groupId: 'export',\n                items: [\n                    'menuBar:exportPdf',\n                    'menuBar:exportWord'\n                ]\n            },\n            {\n                groupId: 'import',\n                items: [\n                    'menuBar:importWord'\n                ]\n            },\n            {\n                groupId: 'revisionHistory',\n                items: [\n                    'menuBar:revisionHistory'\n                ]\n            }\n        ]\n    },\n    {\n        menuId: 'edit',\n        label: 'Edit',\n        groups: [\n            {\n                groupId: 'undo',\n                items: [\n                    'menuBar:undo',\n                    'menuBar:redo'\n                ]\n            },\n            {\n                groupId: 'selectAll',\n                items: [\n                    'menuBar:selectAll'\n                ]\n            },\n            {\n                groupId: 'findAndReplace',\n                items: [\n                    'menuBar:findAndReplace'\n                ]\n            }\n        ]\n    },\n    {\n        menuId: 'view',\n        label: 'View',\n        groups: [\n            {\n                groupId: 'sourceEditing',\n                items: [\n                    'menuBar:sourceEditing'\n                ]\n            },\n            {\n                groupId: 'showBlocks',\n                items: [\n                    'menuBar:showBlocks'\n                ]\n            },\n            {\n                groupId: 'previewMergeFields',\n                items: [\n                    'menuBar:previewMergeFields'\n                ]\n            },\n            {\n                groupId: 'restrictedEditing',\n                items: [\n                    'menuBar:restrictedEditing'\n                ]\n            }\n        ]\n    },\n    {\n        menuId: 'insert',\n        label: 'Insert',\n        groups: [\n            {\n                groupId: 'insertMainWidgets',\n                items: [\n                    'menuBar:insertImage',\n                    'menuBar:ckbox',\n                    'menuBar:ckfinder',\n                    'menuBar:insertTable'\n                ]\n            },\n            {\n                groupId: 'insertInline',\n                items: [\n                    'menuBar:link',\n                    'menuBar:comment',\n                    'menuBar:insertMergeField'\n                ]\n            },\n            {\n                groupId: 'insertMinorWidgets',\n                items: [\n                    'menuBar:mediaEmbed',\n                    'menuBar:insertTemplate',\n                    'menuBar:specialCharacters',\n                    'menuBar:blockQuote',\n                    'menuBar:codeBlock',\n                    'menuBar:htmlEmbed'\n                ]\n            },\n            {\n                groupId: 'insertStructureWidgets',\n                items: [\n                    'menuBar:horizontalLine',\n                    'menuBar:pageBreak',\n                    'menuBar:tableOfContents'\n                ]\n            },\n            {\n                groupId: 'restrictedEditingException',\n                items: [\n                    'menuBar:restrictedEditingException'\n                ]\n            }\n        ]\n    },\n    {\n        menuId: 'format',\n        label: 'Format',\n        groups: [\n            {\n                groupId: 'textAndFont',\n                items: [\n                    {\n                        menuId: 'text',\n                        label: 'Text',\n                        groups: [\n                            {\n                                groupId: 'basicStyles',\n                                items: [\n                                    'menuBar:bold',\n                                    'menuBar:italic',\n                                    'menuBar:underline',\n                                    'menuBar:strikethrough',\n                                    'menuBar:superscript',\n                                    'menuBar:subscript',\n                                    'menuBar:code'\n                                ]\n                            },\n                            {\n                                groupId: 'textPartLanguage',\n                                items: [\n                                    'menuBar:textPartLanguage'\n                                ]\n                            }\n                        ]\n                    },\n                    {\n                        menuId: 'font',\n                        label: 'Font',\n                        groups: [\n                            {\n                                groupId: 'fontProperties',\n                                items: [\n                                    'menuBar:fontSize',\n                                    'menuBar:fontFamily'\n                                ]\n                            },\n                            {\n                                groupId: 'fontColors',\n                                items: [\n                                    'menuBar:fontColor',\n                                    'menuBar:fontBackgroundColor'\n                                ]\n                            },\n                            {\n                                groupId: 'highlight',\n                                items: [\n                                    'menuBar:highlight'\n                                ]\n                            }\n                        ]\n                    },\n                    'menuBar:heading'\n                ]\n            },\n            {\n                groupId: 'list',\n                items: [\n                    'menuBar:bulletedList',\n                    'menuBar:numberedList',\n                    'menuBar:multiLevelList',\n                    'menuBar:todoList'\n                ]\n            },\n            {\n                groupId: 'indent',\n                items: [\n                    'menuBar:alignment',\n                    'menuBar:indent',\n                    'menuBar:outdent'\n                ]\n            },\n            {\n                groupId: 'caseChange',\n                items: [\n                    'menuBar:caseChange'\n                ]\n            },\n            {\n                groupId: 'removeFormat',\n                items: [\n                    'menuBar:removeFormat'\n                ]\n            }\n        ]\n    },\n    {\n        menuId: 'tools',\n        label: 'Tools',\n        groups: [\n            {\n                groupId: 'aiTools',\n                items: [\n                    'menuBar:aiAssistant',\n                    'menuBar:aiCommands'\n                ]\n            },\n            {\n                groupId: 'tools',\n                items: [\n                    'menuBar:trackChanges',\n                    'menuBar:commentsArchive'\n                ]\n            }\n        ]\n    },\n    {\n        menuId: 'help',\n        label: 'Help',\n        groups: [\n            {\n                groupId: 'help',\n                items: [\n                    'menuBar:accessibilityHelp'\n                ]\n            }\n        ]\n    }\n];\n/**\n * Performs a cleanup and normalization of the menu bar configuration.\n */ function normalizeMenuBarConfig(config) {\n    let configObject;\n    // The integrator specified the config as an object but without items. Let's give them defaults but respect their\n    // additions and removals.\n    if (!('items' in config) || !config.items) {\n        configObject = {\n            items: cloneDeep(DefaultMenuBarItems),\n            addItems: [],\n            removeItems: [],\n            isVisible: true,\n            isUsingDefaultConfig: true,\n            ...config\n        };\n    } else {\n        configObject = {\n            items: config.items,\n            removeItems: [],\n            addItems: [],\n            isVisible: true,\n            isUsingDefaultConfig: false,\n            ...config\n        };\n    }\n    return configObject;\n}\n/**\n * Processes a normalized menu bar config and returns a config clone with the following modifications:\n *\n * * Removed components that are not available in the component factory,\n * * Removed obsolete separators,\n * * Purged empty menus,\n * * Localized top-level menu labels.\n */ function processMenuBarConfig({ normalizedConfig, locale, componentFactory, extraItems }) {\n    const configClone = cloneDeep(normalizedConfig);\n    handleAdditions(normalizedConfig, configClone, extraItems);\n    handleRemovals(normalizedConfig, configClone);\n    handleAdditions(normalizedConfig, configClone, configClone.addItems);\n    purgeUnavailableComponents(normalizedConfig, configClone, componentFactory);\n    purgeEmptyMenus(normalizedConfig, configClone);\n    localizeMenuLabels(configClone, locale);\n    return configClone;\n}\n/**\n * Removes items from the menu bar config based on user `removeItems` configuration. Users can remove\n * individual items, groups, or entire menus. For each removed item, a warning is logged if the item\n * was not found in the configuration.\n */ function handleRemovals(originalConfig, config) {\n    const itemsToBeRemoved = config.removeItems;\n    const successfullyRemovedItems = [];\n    // Remove top-level menus.\n    config.items = config.items.filter(({ menuId })=>{\n        if (itemsToBeRemoved.includes(menuId)) {\n            successfullyRemovedItems.push(menuId);\n            return false;\n        }\n        return true;\n    });\n    walkConfigMenus(config.items, (menuDefinition)=>{\n        // Remove groups from menus.\n        menuDefinition.groups = menuDefinition.groups.filter(({ groupId })=>{\n            if (itemsToBeRemoved.includes(groupId)) {\n                successfullyRemovedItems.push(groupId);\n                return false;\n            }\n            return true;\n        });\n        // Remove sub-menus and items from groups.\n        for (const groupDefinition of menuDefinition.groups){\n            groupDefinition.items = groupDefinition.items.filter((item)=>{\n                const itemId = getIdFromGroupItem(item);\n                if (itemsToBeRemoved.includes(itemId)) {\n                    successfullyRemovedItems.push(itemId);\n                    return false;\n                }\n                return true;\n            });\n        }\n    });\n    for (const itemName of itemsToBeRemoved){\n        if (!successfullyRemovedItems.includes(itemName)) {\n            /**\n\t\t\t * There was a problem processing the configuration of the menu bar. The item with the given\n\t\t\t * name does could not be removed from the menu bar configuration.\n\t\t\t *\n\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t * to provide a menu bar item has not been loaded or there is a typo in the\n\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration}.\n\t\t\t *\n\t\t\t * @error menu-bar-item-could-not-be-removed\n\t\t\t * @param menuBarConfig The full configuration of the menu bar.\n\t\t\t * @param itemName The name of the item that was not removed from the menu bar.\n\t\t\t */ logWarning('menu-bar-item-could-not-be-removed', {\n                menuBarConfig: originalConfig,\n                itemName\n            });\n        }\n    }\n}\n/**\n * Adds provided items to config. It allows for adding menus, groups, and items at arbitrary\n * positions in the menu bar. If the position does not exist, a warning is logged.\n */ function handleAdditions(originalConfig, config, items) {\n    const successFullyAddedItems = [];\n    if (items.length == 0) {\n        return;\n    }\n    for (const itemToAdd of items){\n        const relation = getRelationFromPosition(itemToAdd.position);\n        const relativeId = getRelativeIdFromPosition(itemToAdd.position);\n        // Adding a menu.\n        if (isMenuBarMenuAddition(itemToAdd)) {\n            if (!relativeId) {\n                // Adding a top-level menu at the beginning of the menu bar.\n                if (relation === 'start') {\n                    config.items.unshift(itemToAdd.menu);\n                    successFullyAddedItems.push(itemToAdd);\n                } else if (relation === 'end') {\n                    config.items.push(itemToAdd.menu);\n                    successFullyAddedItems.push(itemToAdd);\n                }\n            } else {\n                const topLevelMenuDefinitionIndex = config.items.findIndex((menuDefinition)=>menuDefinition.menuId === relativeId);\n                // Adding a top-level menu somewhere between existing menu bar menus.\n                if (topLevelMenuDefinitionIndex != -1) {\n                    if (relation === 'before') {\n                        config.items.splice(topLevelMenuDefinitionIndex, 0, itemToAdd.menu);\n                        successFullyAddedItems.push(itemToAdd);\n                    } else if (relation === 'after') {\n                        config.items.splice(topLevelMenuDefinitionIndex + 1, 0, itemToAdd.menu);\n                        successFullyAddedItems.push(itemToAdd);\n                    }\n                } else {\n                    const wasAdded = addMenuOrItemToGroup(config, itemToAdd.menu, relativeId, relation);\n                    if (wasAdded) {\n                        successFullyAddedItems.push(itemToAdd);\n                    }\n                }\n            }\n        } else if (isMenuBarMenuGroupAddition(itemToAdd)) {\n            walkConfigMenus(config.items, (menuDefinition)=>{\n                if (menuDefinition.menuId === relativeId) {\n                    // Add a group at the start of a menu.\n                    if (relation === 'start') {\n                        menuDefinition.groups.unshift(itemToAdd.group);\n                        successFullyAddedItems.push(itemToAdd);\n                    } else if (relation === 'end') {\n                        menuDefinition.groups.push(itemToAdd.group);\n                        successFullyAddedItems.push(itemToAdd);\n                    }\n                } else {\n                    const relativeGroupIndex = menuDefinition.groups.findIndex((group)=>group.groupId === relativeId);\n                    if (relativeGroupIndex !== -1) {\n                        // Add a group before an existing group in a menu.\n                        if (relation === 'before') {\n                            menuDefinition.groups.splice(relativeGroupIndex, 0, itemToAdd.group);\n                            successFullyAddedItems.push(itemToAdd);\n                        } else if (relation === 'after') {\n                            menuDefinition.groups.splice(relativeGroupIndex + 1, 0, itemToAdd.group);\n                            successFullyAddedItems.push(itemToAdd);\n                        }\n                    }\n                }\n            });\n        } else {\n            const wasAdded = addMenuOrItemToGroup(config, itemToAdd.item, relativeId, relation);\n            if (wasAdded) {\n                successFullyAddedItems.push(itemToAdd);\n            }\n        }\n    }\n    for (const addedItemConfig of items){\n        if (!successFullyAddedItems.includes(addedItemConfig)) {\n            /**\n\t\t\t * There was a problem processing the configuration of the menu bar. The configured item could not be added\n\t\t\t * because the position it was supposed to be added to does not exist.\n\t\t\t *\n\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t * to provide a menu bar item has not been loaded or there is a typo in the\n\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration}.\n\t\t\t *\n\t\t\t * @error menu-bar-item-could-not-be-removed\n\t\t\t * @param menuBarConfig The full configuration of the menu bar.\n\t\t\t * @param itemName The name of the item that was not removed from the menu bar.\n\t\t\t */ logWarning('menu-bar-item-could-not-be-added', {\n                menuBarConfig: originalConfig,\n                addedItemConfig\n            });\n        }\n    }\n}\n/**\n * Handles adding a sub-menu or an item into a group. The logic is the same for both cases.\n */ function addMenuOrItemToGroup(config, itemOrMenuToAdd, relativeId, relation) {\n    let wasAdded = false;\n    walkConfigMenus(config.items, (menuDefinition)=>{\n        for (const { groupId, items: groupItems } of menuDefinition.groups){\n            // Avoid infinite loops.\n            if (wasAdded) {\n                return;\n            }\n            if (groupId === relativeId) {\n                // Adding an item/menu at the beginning of a group.\n                if (relation === 'start') {\n                    groupItems.unshift(itemOrMenuToAdd);\n                    wasAdded = true;\n                } else if (relation === 'end') {\n                    groupItems.push(itemOrMenuToAdd);\n                    wasAdded = true;\n                }\n            } else {\n                // Adding an item/menu relative to an existing item/menu.\n                const relativeItemIndex = groupItems.findIndex((groupItem)=>{\n                    return getIdFromGroupItem(groupItem) === relativeId;\n                });\n                if (relativeItemIndex !== -1) {\n                    if (relation === 'before') {\n                        groupItems.splice(relativeItemIndex, 0, itemOrMenuToAdd);\n                        wasAdded = true;\n                    } else if (relation === 'after') {\n                        groupItems.splice(relativeItemIndex + 1, 0, itemOrMenuToAdd);\n                        wasAdded = true;\n                    }\n                }\n            }\n        }\n    });\n    return wasAdded;\n}\n/**\n * Removes components from the menu bar configuration that are not available in the factory and would\n * not be instantiated. Warns about missing components if the menu bar configuration was specified by the user.\n */ function purgeUnavailableComponents(originalConfig, config, componentFactory) {\n    walkConfigMenus(config.items, (menuDefinition)=>{\n        for (const groupDefinition of menuDefinition.groups){\n            groupDefinition.items = groupDefinition.items.filter((item)=>{\n                const isItemUnavailable = typeof item === 'string' && !componentFactory.has(item);\n                // The default configuration contains all possible editor features. But integrators' editors rarely load\n                // every possible feature. This is why we do not want to log warnings about unavailable items for the default config\n                // because they would show up in almost every integration. If the configuration has been provided by\n                // the integrator, on the other hand, then these warnings bring value.\n                if (isItemUnavailable && !config.isUsingDefaultConfig) {\n                    /**\n\t\t\t\t\t * There was a problem processing the configuration of the menu bar. The item with the given\n\t\t\t\t\t * name does not exist so it was omitted when rendering the menu bar.\n\t\t\t\t\t *\n\t\t\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t\t\t * to provide a menu bar item has not been loaded or there is a typo in the\n\t\t\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration}.\n\t\t\t\t\t *\n\t\t\t\t\t * Make sure the plugin responsible for this menu bar item is loaded and the menu bar configuration\n\t\t\t\t\t * is correct, e.g. {@link module:basic-styles/bold/boldui~BoldUI} is loaded for the `'menuBar:bold'`\n\t\t\t\t\t * menu bar item.\n\t\t\t\t\t *\n\t\t\t\t\t * @error menu-bar-item-unavailable\n\t\t\t\t\t * @param menuBarConfig The full configuration of the menu bar.\n\t\t\t\t\t * @param parentMenuConfig The config of the menu the unavailable component was defined in.\n\t\t\t\t\t * @param componentName The name of the unavailable component.\n\t\t\t\t\t */ logWarning('menu-bar-item-unavailable', {\n                        menuBarConfig: originalConfig,\n                        parentMenuConfig: cloneDeep(menuDefinition),\n                        componentName: item\n                    });\n                }\n                return !isItemUnavailable;\n            });\n        }\n    });\n}\n/**\n * Removes empty menus from the menu bar configuration to improve the visual UX. Such menus can occur\n * when some plugins responsible for providing menu bar items have not been loaded and some part of\n * the configuration populated menus using these components exclusively.\n */ function purgeEmptyMenus(originalConfig, config) {\n    const isUsingDefaultConfig = config.isUsingDefaultConfig;\n    let wasSubMenuPurged = false;\n    // Purge top-level menus.\n    config.items = config.items.filter((menuDefinition)=>{\n        if (!menuDefinition.groups.length) {\n            warnAboutEmptyMenu(originalConfig, menuDefinition, isUsingDefaultConfig);\n            return false;\n        }\n        return true;\n    });\n    // Warn if there were no top-level menus left in the menu bar after purging.\n    if (!config.items.length) {\n        warnAboutEmptyMenu(originalConfig, originalConfig, isUsingDefaultConfig);\n        return;\n    }\n    // Purge sub-menus and groups.\n    walkConfigMenus(config.items, (menuDefinition)=>{\n        // Get rid of empty groups.\n        menuDefinition.groups = menuDefinition.groups.filter((groupDefinition)=>{\n            if (!groupDefinition.items.length) {\n                wasSubMenuPurged = true;\n                return false;\n            }\n            return true;\n        });\n        // Get rid of empty sub-menus.\n        for (const groupDefinition of menuDefinition.groups){\n            groupDefinition.items = groupDefinition.items.filter((item)=>{\n                // If no groups were left after removing empty ones.\n                if (isMenuDefinition(item) && !item.groups.length) {\n                    warnAboutEmptyMenu(originalConfig, item, isUsingDefaultConfig);\n                    wasSubMenuPurged = true;\n                    return false;\n                }\n                return true;\n            });\n        }\n    });\n    if (wasSubMenuPurged) {\n        // The config is walked from the root to the leaves so if anything gets removed, we need to re-run the\n        // whole process because it could've affected parents.\n        purgeEmptyMenus(originalConfig, config);\n    }\n}\nfunction warnAboutEmptyMenu(originalConfig, emptyMenuConfig, isUsingDefaultConfig) {\n    if (isUsingDefaultConfig) {\n        return;\n    }\n    /**\n\t * There was a problem processing the configuration of the menu bar. One of the menus\n\t * is empty so it was omitted when rendering the menu bar.\n\t *\n\t * This warning usually shows up when some {@link module:core/plugin~Plugin plugins} responsible for\n\t * providing menu bar items have not been loaded and the\n\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration} was not updated.\n\t *\n\t * Make sure all necessary editor plugins are loaded and/or update the menu bar configuration\n\t * to account for the missing menu items.\n\t *\n\t * @error menu-bar-menu-empty\n\t * @param menuBarConfig The full configuration of the menu bar.\n\t * @param emptyMenuConfig The definition of the menu that has no child items.\n\t */ logWarning('menu-bar-menu-empty', {\n        menuBarConfig: originalConfig,\n        emptyMenuConfig\n    });\n}\n/**\n * Localizes the user-config using pre-defined localized category labels.\n */ function localizeMenuLabels(config, locale) {\n    const t = locale.t;\n    const localizedCategoryLabels = {\n        // Top-level categories.\n        'File': t({\n            string: 'File',\n            id: 'MENU_BAR_MENU_FILE'\n        }),\n        'Edit': t({\n            string: 'Edit',\n            id: 'MENU_BAR_MENU_EDIT'\n        }),\n        'View': t({\n            string: 'View',\n            id: 'MENU_BAR_MENU_VIEW'\n        }),\n        'Insert': t({\n            string: 'Insert',\n            id: 'MENU_BAR_MENU_INSERT'\n        }),\n        'Format': t({\n            string: 'Format',\n            id: 'MENU_BAR_MENU_FORMAT'\n        }),\n        'Tools': t({\n            string: 'Tools',\n            id: 'MENU_BAR_MENU_TOOLS'\n        }),\n        'Help': t({\n            string: 'Help',\n            id: 'MENU_BAR_MENU_HELP'\n        }),\n        // Sub-menus.\n        'Text': t({\n            string: 'Text',\n            id: 'MENU_BAR_MENU_TEXT'\n        }),\n        'Font': t({\n            string: 'Font',\n            id: 'MENU_BAR_MENU_FONT'\n        })\n    };\n    walkConfigMenus(config.items, (definition)=>{\n        if (definition.label in localizedCategoryLabels) {\n            definition.label = localizedCategoryLabels[definition.label];\n        }\n    });\n}\n/**\n * Recursively visits all menu definitions in the config and calls the callback for each of them.\n */ function walkConfigMenus(definition, callback) {\n    if (Array.isArray(definition)) {\n        for (const topLevelMenuDefinition of definition){\n            walk(topLevelMenuDefinition);\n        }\n    }\n    function walk(menuDefinition) {\n        callback(menuDefinition);\n        for (const groupDefinition of menuDefinition.groups){\n            for (const groupItem of groupDefinition.items){\n                if (isMenuDefinition(groupItem)) {\n                    walk(groupItem);\n                }\n            }\n        }\n    }\n}\nfunction isMenuBarMenuAddition(definition) {\n    return typeof definition === 'object' && 'menu' in definition;\n}\nfunction isMenuBarMenuGroupAddition(definition) {\n    return typeof definition === 'object' && 'group' in definition;\n}\nfunction getRelationFromPosition(position) {\n    if (position.startsWith('start')) {\n        return 'start';\n    } else if (position.startsWith('end')) {\n        return 'end';\n    } else if (position.startsWith('after')) {\n        return 'after';\n    } else {\n        return 'before';\n    }\n}\nfunction getRelativeIdFromPosition(position) {\n    const match = position.match(/^[^:]+:(.+)/);\n    if (match) {\n        return match[1];\n    }\n    return null;\n}\nfunction getIdFromGroupItem(item) {\n    return typeof item === 'string' ? item : item.menuId;\n}\nfunction isMenuDefinition(definition) {\n    return typeof definition === 'object' && 'menuId' in definition;\n}\n\n/**\n * A class providing the minimal interface that is required to successfully bootstrap any editor UI.\n */ class EditorUI extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * The editor that the UI belongs to.\n\t */ editor;\n    /**\n\t * An instance of the {@link module:ui/componentfactory~ComponentFactory}, a registry used by plugins\n\t * to register factories of specific UI components.\n\t */ componentFactory;\n    /**\n\t * Stores the information about the editor UI focus and propagates it so various plugins and components\n\t * are unified as a focus group.\n\t */ focusTracker;\n    /**\n\t * Manages the tooltips displayed on mouseover and focus across the UI.\n\t */ tooltipManager;\n    /**\n\t * A helper that enables the \"powered by\" feature in the editor and renders a link to the project's webpage.\n\t */ poweredBy;\n    /**\n\t * A helper that manages the content of an `aria-live` regions used by editor features to announce status changes\n\t * to screen readers.\n\t */ ariaLiveAnnouncer;\n    /**\n\t * Indicates the UI is ready. Set `true` after {@link #event:ready} event is fired.\n\t *\n\t * @readonly\n\t * @default false\n\t */ isReady = false;\n    /**\n\t * Stores all editable elements used by the editor instance.\n\t */ _editableElementsMap = new Map();\n    /**\n\t * All available & focusable toolbars.\n\t */ _focusableToolbarDefinitions = [];\n    /**\n\t * All additional menu bar items, groups or menus that have their default location defined.\n\t */ _extraMenuBarElements = [];\n    /**\n\t * The last focused element to which focus should return on `Esc` press.\n\t */ _lastFocusedForeignElement = null;\n    /**\n\t * Creates an instance of the editor UI class.\n\t *\n\t * @param editor The editor instance.\n\t */ constructor(editor){\n        super();\n        const editingView = editor.editing.view;\n        this.editor = editor;\n        this.componentFactory = new ComponentFactory(editor);\n        this.focusTracker = new FocusTracker();\n        this.tooltipManager = new TooltipManager(editor);\n        this.poweredBy = new PoweredBy(editor);\n        this.ariaLiveAnnouncer = new AriaLiveAnnouncer(editor);\n        this.set('viewportOffset', this._readViewportOffsetFromConfig());\n        this.once('ready', ()=>{\n            this._bindBodyCollectionWithFocusTracker();\n            this.isReady = true;\n        });\n        // Informs UI components that should be refreshed after layout change.\n        this.listenTo(editingView.document, 'layoutChanged', this.update.bind(this));\n        this.listenTo(editingView, 'scrollToTheSelection', this._handleScrollToTheSelection.bind(this));\n        this._initFocusTracking();\n    }\n    /**\n\t * The main (outermost) DOM element of the editor UI.\n\t *\n\t * For example, in {@link module:editor-classic/classiceditor~ClassicEditor} it is a `<div>` which\n\t * wraps the editable element and the toolbar. In {@link module:editor-inline/inlineeditor~InlineEditor}\n\t * it is the editable element itself (as there is no other wrapper). However, in\n\t * {@link module:editor-decoupled/decouplededitor~DecoupledEditor} it is set to `null` because this editor does not\n\t * come with a single \"main\" HTML element (its editable element and toolbar are separate).\n\t *\n\t * This property can be understood as a shorthand for retrieving the element that a specific editor integration\n\t * considers to be its main DOM element.\n\t */ get element() {\n        return null;\n    }\n    /**\n\t * Fires the {@link module:ui/editorui/editorui~EditorUI#event:update `update`} event.\n\t *\n\t * This method should be called when the editor UI (e.g. positions of its balloons) needs to be updated due to\n\t * some environmental change which CKEditor 5 is not aware of (e.g. resize of a container in which it is used).\n\t */ update() {\n        this.fire('update');\n    }\n    /**\n\t * Destroys the UI.\n\t */ destroy() {\n        this.stopListening();\n        this.focusTracker.destroy();\n        this.tooltipManager.destroy(this.editor);\n        this.poweredBy.destroy();\n        // Clean–up the references to the CKEditor instance stored in the native editable DOM elements.\n        for (const domElement of this._editableElementsMap.values()){\n            domElement.ckeditorInstance = null;\n            this.editor.keystrokes.stopListening(domElement);\n        }\n        this._editableElementsMap = new Map();\n        this._focusableToolbarDefinitions = [];\n    }\n    /**\n\t * Stores the native DOM editable element used by the editor under a unique name.\n\t *\n\t * Also, registers the element in the editor to maintain the accessibility of the UI. When the user is editing text in a focusable\n\t * editable area, they can use the <kbd>Alt</kbd> + <kbd>F10</kbd> keystroke to navigate over editor toolbars. See {@link #addToolbar}.\n\t *\n\t * @param rootName The unique name of the editable element.\n\t * @param domElement The native DOM editable element.\n\t */ setEditableElement(rootName, domElement) {\n        this._editableElementsMap.set(rootName, domElement);\n        // Put a reference to the CKEditor instance in the editable native DOM element.\n        // It helps 3rd–party software (browser extensions, other libraries) access and recognize\n        // CKEditor 5 instances (editing roots) and use their API (there is no global editor\n        // instance registry).\n        if (!domElement.ckeditorInstance) {\n            domElement.ckeditorInstance = this.editor;\n        }\n        // Register the element, so it becomes available for Alt+F10 and Esc navigation.\n        this.focusTracker.add(domElement);\n        const setUpKeystrokeHandler = ()=>{\n            // The editing view of the editor is already listening to keystrokes from DOM roots (see: KeyObserver).\n            // Do not duplicate listeners.\n            if (this.editor.editing.view.getDomRoot(rootName)) {\n                return;\n            }\n            this.editor.keystrokes.listenTo(domElement);\n        };\n        // For editable elements set by features after EditorUI is ready (e.g. source editing).\n        if (this.isReady) {\n            setUpKeystrokeHandler();\n        } else {\n            this.once('ready', setUpKeystrokeHandler);\n        }\n    }\n    /**\n\t * Removes the editable from the editor UI. Removes all handlers added by {@link #setEditableElement}.\n\t *\n\t * @param rootName The name of the editable element to remove.\n\t */ removeEditableElement(rootName) {\n        const domElement = this._editableElementsMap.get(rootName);\n        if (!domElement) {\n            return;\n        }\n        this._editableElementsMap.delete(rootName);\n        this.editor.keystrokes.stopListening(domElement);\n        this.focusTracker.remove(domElement);\n        domElement.ckeditorInstance = null;\n    }\n    /**\n\t * Returns the editable editor element with the given name or null if editable does not exist.\n\t *\n\t * @param rootName The editable name.\n\t */ getEditableElement(rootName = 'main') {\n        return this._editableElementsMap.get(rootName);\n    }\n    /**\n\t * Returns array of names of all editor editable elements.\n\t */ getEditableElementsNames() {\n        return this._editableElementsMap.keys();\n    }\n    /**\n\t * Adds a toolbar to the editor UI. Used primarily to maintain the accessibility of the UI.\n\t *\n\t * Focusable toolbars can be accessed (focused) by users by pressing the <kbd>Alt</kbd> + <kbd>F10</kbd> keystroke.\n\t * Successive keystroke presses navigate over available toolbars.\n\t *\n\t * @param toolbarView A instance of the toolbar to be registered.\n\t */ addToolbar(toolbarView, options = {}) {\n        if (toolbarView.isRendered) {\n            this.focusTracker.add(toolbarView);\n            this.editor.keystrokes.listenTo(toolbarView.element);\n        } else {\n            toolbarView.once('render', ()=>{\n                this.focusTracker.add(toolbarView);\n                this.editor.keystrokes.listenTo(toolbarView.element);\n            });\n        }\n        this._focusableToolbarDefinitions.push({\n            toolbarView,\n            options\n        });\n    }\n    /**\n\t * Registers an extra menu bar element, which could be a single item, a group of items, or a menu containing groups.\n\t *\n\t * ```ts\n\t * // Register a new menu bar item.\n\t * editor.ui.extendMenuBar( {\n\t *   item: 'menuBar:customFunctionButton',\n\t *   position: 'after:menuBar:bold'\n\t * } );\n\t *\n\t * // Register a new menu bar group.\n\t * editor.ui.extendMenuBar( {\n\t *   group: {\n\t *     groupId: 'customGroup',\n\t *     items: [\n\t *       'menuBar:customFunctionButton'\n\t *     ]\n\t *   },\n\t *   position: 'start:help'\n\t * } );\n\t *\n\t * // Register a new menu bar menu.\n\t * editor.ui.extendMenuBar( {\n\t *   menu: {\n\t *     menuId: 'customMenu',\n\t *     label: 'customMenu',\n\t *     groups: [\n\t *       {\n\t *         groupId: 'customGroup',\n\t *         items: [\n\t *           'menuBar:customFunctionButton'\n\t *         ]\n\t *       }\n\t *     ]\n\t *   },\n\t *   position: 'after:help'\n\t * } );\n\t * ```\n\t */ extendMenuBar(config) {\n        this._extraMenuBarElements.push(config);\n    }\n    /**\n\t * Stores all editable elements used by the editor instance.\n\t *\n\t * @deprecated\n\t */ get _editableElements() {\n        /**\n\t\t * The {@link module:ui/editorui/editorui~EditorUI#_editableElements `EditorUI#_editableElements`} property has been\n\t\t * deprecated and will be removed in the near future. Please use\n\t\t * {@link module:ui/editorui/editorui~EditorUI#setEditableElement `setEditableElement()`} and\n\t\t * {@link module:ui/editorui/editorui~EditorUI#getEditableElement `getEditableElement()`} methods instead.\n\t\t *\n\t\t * @error editor-ui-deprecated-editable-elements\n\t\t * @param editorUI Editor UI instance the deprecated property belongs to.\n\t\t */ console.warn('editor-ui-deprecated-editable-elements: ' + 'The EditorUI#_editableElements property has been deprecated and will be removed in the near future.', {\n            editorUI: this\n        });\n        return this._editableElementsMap;\n    }\n    /**\n\t * Initializes menu bar.\n\t */ _initMenuBar(menuBarView) {\n        const menuBarViewElement = menuBarView.element;\n        this.focusTracker.add(menuBarViewElement);\n        this.editor.keystrokes.listenTo(menuBarViewElement);\n        const normalizedMenuBarConfig = normalizeMenuBarConfig(this.editor.config.get('menuBar') || {});\n        menuBarView.fillFromConfig(normalizedMenuBarConfig, this.componentFactory, this._extraMenuBarElements);\n        this.editor.keystrokes.set('Esc', (data, cancel)=>{\n            if (!menuBarViewElement.contains(this.editor.ui.focusTracker.focusedElement)) {\n                return;\n            }\n            // Bring focus back to where it came from before focusing the toolbar:\n            // If it came from outside the engine view (e.g. source editing), move it there.\n            if (this._lastFocusedForeignElement) {\n                this._lastFocusedForeignElement.focus();\n                this._lastFocusedForeignElement = null;\n            } else {\n                this.editor.editing.view.focus();\n            }\n            cancel();\n        });\n        this.editor.keystrokes.set('Alt+F9', (data, cancel)=>{\n            // If menu bar is already focused do nothing.\n            if (menuBarViewElement.contains(this.editor.ui.focusTracker.focusedElement)) {\n                return;\n            }\n            this._saveLastFocusedForeignElement();\n            menuBarView.isFocusBorderEnabled = true;\n            menuBarView.focus();\n            cancel();\n        });\n    }\n    /**\n\t * Returns viewport offsets object:\n\t *\n\t * ```js\n\t * {\n\t * \ttop: Number,\n\t * \tright: Number,\n\t * \tbottom: Number,\n\t * \tleft: Number\n\t * }\n\t * ```\n\t *\n\t * Only top property is currently supported.\n\t */ _readViewportOffsetFromConfig() {\n        const editor = this.editor;\n        const viewportOffsetConfig = editor.config.get('ui.viewportOffset');\n        if (viewportOffsetConfig) {\n            return viewportOffsetConfig;\n        }\n        // Not present in EditorConfig type, because it's legacy. Hence the `as` expression.\n        const legacyOffsetConfig = editor.config.get('toolbar.viewportTopOffset');\n        // Fall back to deprecated toolbar config.\n        if (legacyOffsetConfig) {\n            /**\n\t\t\t * The {@link module:core/editor/editorconfig~EditorConfig#toolbar `EditorConfig#toolbar.viewportTopOffset`}\n\t\t\t * property has been deprecated and will be removed in the near future. Please use\n\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#ui `EditorConfig#ui.viewportOffset`} instead.\n\t\t\t *\n\t\t\t * @error editor-ui-deprecated-viewport-offset-config\n\t\t\t */ console.warn('editor-ui-deprecated-viewport-offset-config: ' + 'The `toolbar.vieportTopOffset` configuration option is deprecated. ' + 'It will be removed from future CKEditor versions. Use `ui.viewportOffset.top` instead.');\n            return {\n                top: legacyOffsetConfig\n            };\n        }\n        // More keys to come in the future.\n        return {\n            top: 0\n        };\n    }\n    /**\n\t * Starts listening for <kbd>Alt</kbd> + <kbd>F10</kbd> and <kbd>Esc</kbd> keystrokes in the context of focusable\n\t * {@link #setEditableElement editable elements} and {@link #addToolbar toolbars}\n\t * to allow users navigate across the UI.\n\t */ _initFocusTracking() {\n        const editor = this.editor;\n        let candidateDefinitions;\n        // Focus the next focusable toolbar on <kbd>Alt</kbd> + <kbd>F10</kbd>.\n        editor.keystrokes.set('Alt+F10', (data, cancel)=>{\n            this._saveLastFocusedForeignElement();\n            const currentFocusedToolbarDefinition = this._getCurrentFocusedToolbarDefinition();\n            // * When focusing a toolbar for the first time, set the array of definitions for successive presses of Alt+F10.\n            // This ensures, the navigation works always the same and no pair of toolbars takes over\n            // (e.g. image and table toolbars when a selected image is inside a cell).\n            // * It could be that the focus went to the toolbar by clicking a toolbar item (e.g. a dropdown). In this case,\n            // there were no candidates so they must be obtained (#12339).\n            if (!currentFocusedToolbarDefinition || !candidateDefinitions) {\n                candidateDefinitions = this._getFocusableCandidateToolbarDefinitions();\n            }\n            // In a single Alt+F10 press, check all candidates but if none were focused, don't go any further.\n            // This prevents an infinite loop.\n            for(let i = 0; i < candidateDefinitions.length; i++){\n                const candidateDefinition = candidateDefinitions.shift();\n                // Put the first definition to the back of the array. This allows circular navigation over all toolbars\n                // on successive presses of Alt+F10.\n                candidateDefinitions.push(candidateDefinition);\n                // Don't focus the same toolbar again. If you did, this would move focus from the nth focused toolbar item back to the\n                // first item as per ToolbarView#focus() if the user navigated inside the toolbar.\n                if (candidateDefinition !== currentFocusedToolbarDefinition && this._focusFocusableCandidateToolbar(candidateDefinition)) {\n                    // Clean up after a current visible toolbar when switching to the next one.\n                    if (currentFocusedToolbarDefinition && currentFocusedToolbarDefinition.options.afterBlur) {\n                        currentFocusedToolbarDefinition.options.afterBlur();\n                    }\n                    break;\n                }\n            }\n            cancel();\n        });\n        // Blur the focused toolbar on <kbd>Esc</kbd> and bring the focus back to its origin.\n        editor.keystrokes.set('Esc', (data, cancel)=>{\n            const focusedToolbarDef = this._getCurrentFocusedToolbarDefinition();\n            if (!focusedToolbarDef) {\n                return;\n            }\n            // Bring focus back to where it came from before focusing the toolbar:\n            // 1. If it came from outside the engine view (e.g. source editing), move it there.\n            if (this._lastFocusedForeignElement) {\n                this._lastFocusedForeignElement.focus();\n                this._lastFocusedForeignElement = null;\n            } else {\n                editor.editing.view.focus();\n            }\n            // Clean up after the toolbar if there is anything to do there.\n            if (focusedToolbarDef.options.afterBlur) {\n                focusedToolbarDef.options.afterBlur();\n            }\n            cancel();\n        });\n    }\n    /**\n\t * Saves last focused element that doen not belong to editing view to restore focus on `Esc`.\n\t */ _saveLastFocusedForeignElement() {\n        const focusedElement = this.focusTracker.focusedElement;\n        // Focus moved out of a DOM element that\n        // * is not a toolbar,\n        // * does not belong to the editing view (e.g. source editing).\n        if (Array.from(this._editableElementsMap.values()).includes(focusedElement) && !Array.from(this.editor.editing.view.domRoots.values()).includes(focusedElement)) {\n            this._lastFocusedForeignElement = focusedElement;\n        }\n    }\n    /**\n\t * Returns definitions of toolbars that could potentially be focused, sorted by their importance for the user.\n\t *\n\t * Focusable toolbars candidates are either:\n\t * * already visible,\n\t * * have `beforeFocus()` set in their {@link module:ui/editorui/editorui~FocusableToolbarDefinition definition} that suggests that\n\t * they might show up when called. Keep in mind that determining whether a toolbar will show up (and become focusable) is impossible\n\t * at this stage because it depends on its implementation, that in turn depends on the editing context (selection).\n\t *\n\t * **Note**: Contextual toolbars take precedence over regular toolbars.\n\t */ _getFocusableCandidateToolbarDefinitions() {\n        const definitions = [];\n        for (const toolbarDef of this._focusableToolbarDefinitions){\n            const { toolbarView, options } = toolbarDef;\n            if (isVisible(toolbarView.element) || options.beforeFocus) {\n                definitions.push(toolbarDef);\n            }\n        }\n        // Contextual and already visible toolbars have higher priority. If both are true, the toolbar will always focus first.\n        // For instance, a selected widget toolbar vs inline editor toolbar: both are visible but the widget toolbar is contextual.\n        definitions.sort((defA, defB)=>getToolbarDefinitionWeight(defA) - getToolbarDefinitionWeight(defB));\n        return definitions;\n    }\n    /**\n\t * Returns a definition of the toolbar that is currently visible and focused (one of its children has focus).\n\t *\n\t * `null` is returned when no toolbar is currently focused.\n\t */ _getCurrentFocusedToolbarDefinition() {\n        for (const definition of this._focusableToolbarDefinitions){\n            if (definition.toolbarView.element && definition.toolbarView.element.contains(this.focusTracker.focusedElement)) {\n                return definition;\n            }\n        }\n        return null;\n    }\n    /**\n\t * Focuses a focusable toolbar candidate using its definition.\n\t *\n\t * @param candidateToolbarDefinition A definition of the toolbar to focus.\n\t * @returns `true` when the toolbar candidate was focused. `false` otherwise.\n\t */ _focusFocusableCandidateToolbar(candidateToolbarDefinition) {\n        const { toolbarView, options: { beforeFocus } } = candidateToolbarDefinition;\n        if (beforeFocus) {\n            beforeFocus();\n        }\n        // If it didn't show up after beforeFocus(), it's not focusable at all.\n        if (!isVisible(toolbarView.element)) {\n            return false;\n        }\n        toolbarView.focus();\n        return true;\n    }\n    /**\n\t * Provides an integration between {@link #viewportOffset} and {@link module:utils/dom/scroll~scrollViewportToShowTarget}.\n\t * It allows the UI-agnostic engine method to consider user-configured viewport offsets specific for the integration.\n\t *\n\t * @param evt The `scrollToTheSelection` event info.\n\t * @param data The payload carried by the `scrollToTheSelection` event.\n\t */ _handleScrollToTheSelection(evt, data) {\n        const configuredViewportOffset = {\n            top: 0,\n            bottom: 0,\n            left: 0,\n            right: 0,\n            ...this.viewportOffset\n        };\n        data.viewportOffset.top += configuredViewportOffset.top;\n        data.viewportOffset.bottom += configuredViewportOffset.bottom;\n        data.viewportOffset.left += configuredViewportOffset.left;\n        data.viewportOffset.right += configuredViewportOffset.right;\n    }\n    /**\n\t * Ensures that the focus tracker is aware of all views' DOM elements in the body collection.\n\t */ _bindBodyCollectionWithFocusTracker() {\n        const body = this.view.body;\n        for (const view of body){\n            this.focusTracker.add(view.element);\n        }\n        body.on('add', (evt, view)=>{\n            this.focusTracker.add(view.element);\n        });\n        body.on('remove', (evt, view)=>{\n            this.focusTracker.remove(view.element);\n        });\n    }\n}\n/**\n * Returns a number (weight) for a toolbar definition. Visible toolbars have a higher priority and so do\n * contextual toolbars (displayed in the context of a content, for instance, an image toolbar).\n *\n * A standard invisible toolbar is the heaviest. A visible contextual toolbar is the lightest.\n *\n * @param toolbarDef A toolbar definition to be weighted.\n */ function getToolbarDefinitionWeight(toolbarDef) {\n    const { toolbarView, options } = toolbarDef;\n    let weight = 10;\n    // Prioritize already visible toolbars. They should get focused first.\n    if (isVisible(toolbarView.element)) {\n        weight--;\n    }\n    // Prioritize contextual toolbars. They are displayed at the selection.\n    if (options.isContextual) {\n        weight--;\n    }\n    return weight;\n}\n\n/**\n * The editor UI view class. Base class for the editor main views.\n */ class EditorUIView extends View {\n    /**\n\t * Collection of the child views, detached from the DOM\n\t * structure of the editor, like panels, icons etc.\n\t */ body;\n    /**\n\t * Menu bar view instance. May not be initialized in some editor types.\n\t */ menuBarView;\n    /**\n\t * Creates an instance of the editor UI view class.\n\t *\n\t * @param locale The locale instance.\n\t */ constructor(locale){\n        super(locale);\n        this.body = new BodyCollection(locale);\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.body.attachToDom();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this.body.detachFromDom();\n        return super.destroy();\n    }\n}\n\n/**\n * The boxed editor UI view class. This class represents an editor interface\n * consisting of a toolbar and an editable area, enclosed within a box.\n */ class BoxedEditorUIView extends EditorUIView {\n    /**\n\t * Collection of the child views located in the top (`.ck-editor__top`)\n\t * area of the UI.\n\t */ top;\n    /**\n\t * Collection of the child views located in the main (`.ck-editor__main`)\n\t * area of the UI.\n\t */ main;\n    /**\n\t * Voice label of the UI.\n\t */ _voiceLabelView;\n    /**\n\t * Creates an instance of the boxed editor UI view class.\n\t *\n\t * @param locale The locale instance..\n\t */ constructor(locale){\n        super(locale);\n        this.top = this.createCollection();\n        this.main = this.createCollection();\n        this._voiceLabelView = this._createVoiceLabel();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-reset',\n                    'ck-editor',\n                    'ck-rounded-corners'\n                ],\n                role: 'application',\n                dir: locale.uiLanguageDirection,\n                lang: locale.uiLanguage,\n                'aria-labelledby': this._voiceLabelView.id\n            },\n            children: [\n                this._voiceLabelView,\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-editor__top',\n                            'ck-reset_all'\n                        ],\n                        role: 'presentation'\n                    },\n                    children: this.top\n                },\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-editor__main'\n                        ],\n                        role: 'presentation'\n                    },\n                    children: this.main\n                }\n            ]\n        });\n    }\n    /**\n\t * Creates a voice label view instance.\n\t */ _createVoiceLabel() {\n        const t = this.t;\n        const voiceLabel = new LabelView();\n        voiceLabel.text = t('Rich Text Editor');\n        voiceLabel.extendTemplate({\n            attributes: {\n                class: 'ck-voice-label'\n            }\n        });\n        return voiceLabel;\n    }\n}\n\n/**\n * The editable UI view class.\n */ class EditableUIView extends View {\n    /**\n\t * The name of the editable UI view.\n\t */ name = null;\n    /**\n\t * The editing view instance the editable is related to. Editable uses the editing\n\t * view to dynamically modify its certain DOM attributes after {@link #render rendering}.\n\t *\n\t * **Note**: The DOM attributes are performed by the editing view and not UI\n\t * {@link module:ui/view~View#bindTemplate template bindings} because once rendered,\n\t * the editable DOM element must remain under the full control of the engine to work properly.\n\t */ _editingView;\n    /**\n\t * The element which is the main editable element (usually the one with `contentEditable=\"true\"`).\n\t */ _editableElement;\n    /**\n\t * Whether an external {@link #_editableElement} was passed into the constructor, which also means\n\t * the view will not render its {@link #template}.\n\t */ _hasExternalElement;\n    /**\n\t * Creates an instance of EditableUIView class.\n\t *\n\t * @param locale The locale instance.\n\t * @param editingView The editing view instance the editable is related to.\n\t * @param editableElement The editable element. If not specified, this view\n\t * should create it. Otherwise, the existing element should be used.\n\t */ constructor(locale, editingView, editableElement){\n        super(locale);\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-content',\n                    'ck-editor__editable',\n                    'ck-rounded-corners'\n                ],\n                lang: locale.contentLanguage,\n                dir: locale.contentLanguageDirection\n            }\n        });\n        this.set('isFocused', false);\n        this._editableElement = editableElement;\n        this._hasExternalElement = !!this._editableElement;\n        this._editingView = editingView;\n    }\n    /**\n\t * Renders the view by either applying the {@link #template} to the existing\n\t * {@link module:ui/editableui/editableuiview~EditableUIView#_editableElement} or assigning {@link #element}\n\t * as {@link module:ui/editableui/editableuiview~EditableUIView#_editableElement}.\n\t */ render() {\n        super.render();\n        if (this._hasExternalElement) {\n            this.template.apply(this.element = this._editableElement);\n        } else {\n            this._editableElement = this.element;\n        }\n        this.on('change:isFocused', ()=>this._updateIsFocusedClasses());\n        this._updateIsFocusedClasses();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        if (this._hasExternalElement) {\n            this.template.revert(this._editableElement);\n        }\n        super.destroy();\n    }\n    /**\n\t * Whether an external {@link #_editableElement} was passed into the constructor, which also means\n\t * the view will not render its {@link #template}.\n\t */ get hasExternalElement() {\n        return this._hasExternalElement;\n    }\n    /**\n\t * Updates the `ck-focused` and `ck-blurred` CSS classes on the {@link #element} according to\n\t * the {@link #isFocused} property value using the {@link #_editingView editing view} API.\n\t */ _updateIsFocusedClasses() {\n        const editingView = this._editingView;\n        if (editingView.isRenderingInProgress) {\n            updateAfterRender(this);\n        } else {\n            update(this);\n        }\n        function update(view) {\n            editingView.change((writer)=>{\n                const viewRoot = editingView.document.getRoot(view.name);\n                writer.addClass(view.isFocused ? 'ck-focused' : 'ck-blurred', viewRoot);\n                writer.removeClass(view.isFocused ? 'ck-blurred' : 'ck-focused', viewRoot);\n            });\n        }\n        // In a case of a multi-root editor, a callback will be attached more than once (one callback for each root).\n        // While executing one callback the `isRenderingInProgress` observable is changing what causes executing another\n        // callback and render is called inside the already pending render.\n        // We need to be sure that callback is executed only when the value has changed from `true` to `false`.\n        // See https://github.com/ckeditor/ckeditor5/issues/1676.\n        function updateAfterRender(view) {\n            editingView.once('change:isRenderingInProgress', (evt, name, value)=>{\n                if (!value) {\n                    update(view);\n                } else {\n                    updateAfterRender(view);\n                }\n            });\n        }\n    }\n}\n\n/**\n * The inline editable UI class implementing an inline {@link module:ui/editableui/editableuiview~EditableUIView}.\n */ class InlineEditableUIView extends EditableUIView {\n    /**\n\t * The cached options object passed to the constructor.\n\t */ _options;\n    /**\n\t * Creates an instance of the InlineEditableUIView class.\n\t *\n\t * @param locale The locale instance.\n\t * @param editingView The editing view instance the editable is related to.\n\t * @param editableElement The editable element. If not specified, the\n\t * {@link module:ui/editableui/editableuiview~EditableUIView}\n\t * will create it. Otherwise, the existing element will be used.\n\t * @param options Additional configuration of the view.\n\t * @param options.label The label of the editable for assistive technologies. If not provided, a default label is used or,\n\t * the existing `aria-label` attribute value from the specified `editableElement` is preserved.\n\t */ constructor(locale, editingView, editableElement, options = {}){\n        super(locale, editingView, editableElement);\n        this._options = options;\n        this.extendTemplate({\n            attributes: {\n                role: 'textbox',\n                class: 'ck-editor__editable_inline'\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        const editingView = this._editingView;\n        editingView.change((writer)=>{\n            const viewRoot = editingView.document.getRoot(this.name);\n            writer.setAttribute('aria-label', this.getEditableAriaLabel(), viewRoot);\n        });\n    }\n    /**\n\t * Returns a normalized label for the editable view based on the environment.\n\t */ getEditableAriaLabel() {\n        const t = this.locale.t;\n        const label = this._options.label;\n        const editableElement = this._editableElement;\n        const editableName = this.name;\n        if (typeof label == 'string') {\n            return label;\n        } else if (typeof label === 'object') {\n            return label[editableName];\n        } else if (typeof label === 'function') {\n            return label(this);\n        } else if (editableElement) {\n            const existingLabel = editableElement.getAttribute('aria-label');\n            if (existingLabel) {\n                return existingLabel;\n            }\n        }\n        return t('Rich Text Editor. Editing area: %0', editableName);\n    }\n}\n\n/**\n * The iframe view class.\n *\n * ```ts\n * const iframe = new IframeView();\n *\n * iframe.render();\n * document.body.appendChild( iframe.element );\n *\n * iframe.on( 'loaded', () => {\n * \tconsole.log( 'The iframe has loaded', iframe.element.contentWindow );\n * } );\n *\n * iframe.element.src = 'https://ckeditor.com';\n * ```\n */ class IframeView extends View {\n    /**\n\t * Creates a new instance of the iframe view.\n\t *\n\t * @param locale The locale instance.\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'iframe',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-reset_all'\n                ],\n                // It seems that we need to allow scripts in order to be able to listen to events.\n                // TODO: Research that. Perhaps the src must be set?\n                sandbox: 'allow-same-origin allow-scripts'\n            },\n            on: {\n                load: bind.to('loaded')\n            }\n        });\n    }\n    /**\n\t * Renders the iframe's {@link #element} and returns a `Promise` for asynchronous\n\t * child `contentDocument` loading process.\n\t *\n\t * @returns A promise which resolves once the iframe `contentDocument` has\n\t * been {@link #event:loaded}.\n\t */ render() {\n        return new Promise((resolve)=>{\n            this.on('loaded', resolve);\n            return super.render();\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module ui/search/filtergroupanditemnames\n */ /**\n * A filter function that returns matching item and group names in the list view.\n */ function filterGroupAndItemNames(regExp, items) {\n    let totalItemsCount = 0;\n    let resultsCount = 0;\n    for (const groupView of items){\n        const group = groupView;\n        const groupItems = group.items;\n        const isGroupLabelMatching = regExp && !!group.label.match(regExp);\n        group.labelView.highlightText(isGroupLabelMatching ? regExp : null);\n        for (const listItemView of groupItems){\n            const buttonView = listItemView.children.first;\n            const labelView = buttonView.labelView;\n            if (!regExp) {\n                listItemView.isVisible = true;\n                labelView.highlightText(null);\n            } else {\n                const isItemLabelMatching = !!buttonView.label.match(regExp);\n                labelView.highlightText(isItemLabelMatching ? regExp : null);\n                listItemView.isVisible = isGroupLabelMatching || isItemLabelMatching;\n            }\n        }\n        const visibleInGroupCount = groupItems.filter((listItemView)=>listItemView.isVisible).length;\n        totalItemsCount += group.items.length;\n        resultsCount += isGroupLabelMatching ? group.items.length : visibleInGroupCount;\n        group.isVisible = isGroupLabelMatching || !!visibleInGroupCount;\n    }\n    return {\n        resultsCount,\n        totalItemsCount\n    };\n}\n\n/**\n * The Notification plugin.\n *\n * This plugin sends a few types of notifications: `success`, `info` and `warning`. The notifications need to be\n * handled and displayed by a plugin responsible for showing the UI of the notifications. Using this plugin for dispatching\n * notifications makes it possible to switch the notifications UI.\n *\n * Note that every unhandled and not stopped `warning` notification will be displayed as a system alert.\n * See {@link module:ui/notification/notification~Notification#showWarning}.\n */ class Notification extends ContextPlugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Notification';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        // Each unhandled and not stopped `show:warning` event is displayed as a system alert.\n        this.on('show:warning', (evt, data)=>{\n            window.alert(data.message); // eslint-disable-line no-alert\n        }, {\n            priority: 'lowest'\n        });\n    }\n    /**\n\t * Shows a success notification.\n\t *\n\t * By default, it fires the {@link #event:show:success `show:success` event} with the given `data`. The event namespace can be extended\n\t * using the `data.namespace` option. For example:\n\t *\n\t * ```ts\n\t * showSuccess( 'Image is uploaded.', {\n\t * \tnamespace: 'upload:image'\n\t * } );\n\t * ```\n\t *\n\t * will fire the `show:success:upload:image` event.\n\t *\n\t * You can provide the title of the notification:\n\t *\n\t * ```ts\n\t * showSuccess( 'Image is uploaded.', {\n\t * \ttitle: 'Image upload success'\n\t * } );\n\t * ```\n\t *\n\t * @param message The content of the notification.\n\t * @param data Additional data.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */ showSuccess(message, data = {}) {\n        this._showNotification({\n            message,\n            type: 'success',\n            namespace: data.namespace,\n            title: data.title\n        });\n    }\n    /**\n\t * Shows an information notification.\n\t *\n\t * By default, it fires the {@link #event:show:info `show:info` event} with the given `data`. The event namespace can be extended\n\t * using the `data.namespace` option. For example:\n\t *\n\t * ```ts\n\t * showInfo( 'Editor is offline.', {\n\t * \tnamespace: 'editor:status'\n\t * } );\n\t * ```\n\t *\n\t * will fire the `show:info:editor:status` event.\n\t *\n\t * You can provide the title of the notification:\n\t *\n\t * ```ts\n\t * showInfo( 'Editor is offline.', {\n\t * \ttitle: 'Network information'\n\t * } );\n\t * ```\n\t *\n\t * @param message The content of the notification.\n\t * @param data Additional data.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */ showInfo(message, data = {}) {\n        this._showNotification({\n            message,\n            type: 'info',\n            namespace: data.namespace,\n            title: data.title\n        });\n    }\n    /**\n\t * Shows a warning notification.\n\t *\n\t * By default, it fires the {@link #event:show:warning `show:warning` event}\n\t * with the given `data`. The event namespace can be extended using the `data.namespace` option. For example:\n\t *\n\t * ```ts\n\t * showWarning( 'Image upload error.', {\n\t * \tnamespace: 'upload:image'\n\t * } );\n\t * ```\n\t *\n\t * will fire the `show:warning:upload:image` event.\n\t *\n\t * You can provide the title of the notification:\n\t *\n\t * ```ts\n\t * showWarning( 'Image upload error.', {\n\t * \ttitle: 'Upload failed'\n\t * } );\n\t * ```\n\t *\n\t * Note that each unhandled and not stopped `warning` notification will be displayed as a system alert.\n\t * The plugin responsible for displaying warnings should `stop()` the event to prevent displaying it as an alert:\n\t *\n\t * ```ts\n\t * notifications.on( 'show:warning', ( evt, data ) => {\n\t * \t// Do something with the data.\n\t *\n\t * \t// Stop this event to prevent displaying it as an alert.\n\t * \tevt.stop();\n\t * } );\n\t * ```\n\t *\n\t * You can attach many listeners to the same event and `stop()` this event in a listener with a low priority:\n\t *\n\t * ```ts\n\t * notifications.on( 'show:warning', ( evt, data ) => {\n\t * \t// Show the warning in the UI, but do not stop it.\n\t * } );\n\t *\n\t * notifications.on( 'show:warning', ( evt, data ) => {\n\t * \t// Log the warning to some error tracker.\n\t *\n\t * \t// Stop this event to prevent displaying it as an alert.\n\t * \tevt.stop();\n\t * }, { priority: 'low' } );\n\t * ```\n\t *\n\t * @param message The content of the notification.\n\t * @param data Additional data.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */ showWarning(message, data = {}) {\n        this._showNotification({\n            message,\n            type: 'warning',\n            namespace: data.namespace,\n            title: data.title\n        });\n    }\n    /**\n\t * Fires the `show` event with the specified type, namespace and message.\n\t *\n\t * @param data The message data.\n\t * @param data.message The content of the notification.\n\t * @param data.type The type of the message.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */ _showNotification(data) {\n        const event = data.namespace ? `show:${data.type}:${data.namespace}` : `show:${data.type}`;\n        this.fire(event, {\n            message: data.message,\n            type: data.type,\n            title: data.title || ''\n        });\n    }\n}\n\n/**\n * The base MVC model class.\n */ class Model extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * Creates a new Model instance.\n\t *\n\t * @param attributes The model state attributes to be defined during the instance creation.\n\t * @param properties The (out of state) properties to be appended to the instance during creation.\n\t */ constructor(attributes, properties){\n        super();\n        // Extend this instance with the additional (out of state) properties.\n        if (properties) {\n            extend(this, properties);\n        }\n        // Initialize the attributes.\n        if (attributes) {\n            this.set(attributes);\n        }\n    }\n}\n\nconst toPx$4 = /* #__PURE__ */ toUnit('px');\n/**\n * Provides the common contextual balloon for the editor.\n *\n * The role of this plugin is to unify the contextual balloons logic, simplify views management and help\n * avoid the unnecessary complexity of handling multiple {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n * instances in the editor.\n *\n * This plugin allows for creating single or multiple panel stacks.\n *\n * Each stack may have multiple views, with the one on the top being visible. When the visible view is removed from the stack,\n * the previous view becomes visible.\n *\n * It might be useful to implement nested navigation in a balloon. For instance, a toolbar view may contain a link button.\n * When you click it, a link view (which lets you set the URL) is created and put on top of the toolbar view, so the link panel\n * is displayed. When you finish editing the link and close (remove) the link view, the toolbar view is visible again.\n *\n * However, there are cases when there are multiple independent balloons to be displayed, for instance, if the selection\n * is inside two inline comments at the same time. For such cases, you can create two independent panel stacks.\n * The contextual balloon plugin will create a navigation bar to let the users switch between these panel stacks using the \"Next\"\n * and \"Previous\" buttons.\n *\n * If there are no views in the current stack, the balloon panel will try to switch to the next stack. If there are no\n * panels in any stack, the balloon panel will be hidden.\n *\n * **Note**: To force the balloon panel to show only one view, even if there are other stacks, use the `singleViewMode=true` option\n * when {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon#add adding} a view to a panel.\n *\n * From the implementation point of view, the contextual ballon plugin is reusing a single\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance to display multiple contextual balloon\n * panels in the editor. It also creates a special {@link module:ui/panel/balloon/contextualballoon~RotatorView rotator view},\n * used to manage multiple panel stacks. Rotator view is a child of the balloon panel view and the parent of the specific\n * view you want to display. If there is more than one panel stack to be displayed, the rotator view will add a\n * navigation bar. If there is only one stack, the rotator view is transparent (it does not add any UI elements).\n */ class ContextualBalloon extends Plugin {\n    /**\n\t * The {@link module:utils/dom/position~Options#limiter position limiter}\n\t * for the {@link #view balloon}, used when no `limiter` has been passed into {@link #add}\n\t * or {@link #updatePosition}.\n\t *\n\t * By default, a function that obtains the farthest DOM\n\t * {@link module:engine/view/rooteditableelement~RootEditableElement}\n\t * of the {@link module:engine/view/document~Document#selection}.\n\t */ positionLimiter;\n    visibleStack;\n    /**\n\t * The map of views and their stacks.\n\t */ _viewToStack = new Map();\n    /**\n\t * The map of IDs and stacks.\n\t */ _idToStack = new Map();\n    /**\n\t * The common balloon panel view.\n\t */ _view = null;\n    /**\n\t * Rotator view embedded in the contextual balloon.\n\t * Displays the currently visible view in the balloon and provides navigation for switching stacks.\n\t */ _rotatorView = null;\n    /**\n\t * Displays fake panels under the balloon panel view when multiple stacks are added to the balloon.\n\t */ _fakePanelsView = null;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ContextualBalloon';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this.positionLimiter = ()=>{\n            const view = this.editor.editing.view;\n            const viewDocument = view.document;\n            const editableElement = viewDocument.selection.editableElement;\n            if (editableElement) {\n                return view.domConverter.mapViewToDom(editableElement.root);\n            }\n            return null;\n        };\n        this.decorate('getPositionOptions');\n        this.set('visibleView', null);\n        this.set('_numberOfStacks', 0);\n        this.set('_singleViewMode', false);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        if (this._view) {\n            this._view.destroy();\n        }\n        if (this._rotatorView) {\n            this._rotatorView.destroy();\n        }\n        if (this._fakePanelsView) {\n            this._fakePanelsView.destroy();\n        }\n    }\n    /**\n\t * The common balloon panel view.\n\t */ get view() {\n        if (!this._view) {\n            this._createPanelView();\n        }\n        return this._view;\n    }\n    /**\n\t * Returns `true` when the given view is in one of the stacks. Otherwise returns `false`.\n\t */ hasView(view) {\n        return Array.from(this._viewToStack.keys()).includes(view);\n    }\n    /**\n\t * Adds a new view to the stack and makes it visible if the current stack is visible\n\t * or it is the first view in the balloon.\n\t *\n\t * @param data The configuration of the view.\n\t * @param data.stackId The ID of the stack that the view is added to. Defaults to `'main'`.\n\t * @param data.view The content of the balloon.\n\t * @param data.position Positioning options.\n\t * @param data.balloonClassName An additional CSS class added to the {@link #view balloon} when visible.\n\t * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow. Defaults to `true`.\n\t * @param data.singleViewMode Whether the view should be the only visible view even if other stacks were added. Defaults to `false`.\n\t */ add(data) {\n        if (!this._view) {\n            this._createPanelView();\n        }\n        if (this.hasView(data.view)) {\n            /**\n\t\t\t * Trying to add configuration of the same view more than once.\n\t\t\t *\n\t\t\t * @error contextualballoon-add-view-exist\n\t\t\t */ throw new CKEditorError('contextualballoon-add-view-exist', [\n                this,\n                data\n            ]);\n        }\n        const stackId = data.stackId || 'main';\n        // If new stack is added, creates it and show view from this stack.\n        if (!this._idToStack.has(stackId)) {\n            this._idToStack.set(stackId, new Map([\n                [\n                    data.view,\n                    data\n                ]\n            ]));\n            this._viewToStack.set(data.view, this._idToStack.get(stackId));\n            this._numberOfStacks = this._idToStack.size;\n            if (!this._visibleStack || data.singleViewMode) {\n                this.showStack(stackId);\n            }\n            return;\n        }\n        const stack = this._idToStack.get(stackId);\n        if (data.singleViewMode) {\n            this.showStack(stackId);\n        }\n        // Add new view to the stack.\n        stack.set(data.view, data);\n        this._viewToStack.set(data.view, stack);\n        // And display it if is added to the currently visible stack.\n        if (stack === this._visibleStack) {\n            this._showView(data);\n        }\n    }\n    /**\n\t * Removes the given view from the stack. If the removed view was visible,\n\t * the view preceding it in the stack will become visible instead.\n\t * When there is no view in the stack, the next stack will be displayed.\n\t * When there are no more stacks, the balloon will hide.\n\t *\n\t * @param view A view to be removed from the balloon.\n\t */ remove(view) {\n        if (!this.hasView(view)) {\n            /**\n\t\t\t * Trying to remove the configuration of the view not defined in the stack.\n\t\t\t *\n\t\t\t * @error contextualballoon-remove-view-not-exist\n\t\t\t */ throw new CKEditorError('contextualballoon-remove-view-not-exist', [\n                this,\n                view\n            ]);\n        }\n        const stack = this._viewToStack.get(view);\n        if (this._singleViewMode && this.visibleView === view) {\n            this._singleViewMode = false;\n        }\n        // When visible view will be removed we need to show a preceding view or next stack\n        // if a view is the only view in the stack.\n        if (this.visibleView === view) {\n            if (stack.size === 1) {\n                if (this._idToStack.size > 1) {\n                    this._showNextStack();\n                } else {\n                    this.view.hide();\n                    this.visibleView = null;\n                    this._rotatorView.hideView();\n                }\n            } else {\n                this._showView(Array.from(stack.values())[stack.size - 2]);\n            }\n        }\n        if (stack.size === 1) {\n            this._idToStack.delete(this._getStackId(stack));\n            this._numberOfStacks = this._idToStack.size;\n        } else {\n            stack.delete(view);\n        }\n        this._viewToStack.delete(view);\n    }\n    /**\n\t * Updates the position of the balloon using the position data of the first visible view in the stack.\n\t * When new position data is given, the position data of the currently visible view will be updated.\n\t *\n\t * @param position Position options.\n\t */ updatePosition(position) {\n        if (position) {\n            this._visibleStack.get(this.visibleView).position = position;\n        }\n        this.view.pin(this.getPositionOptions());\n        this._fakePanelsView.updatePosition();\n    }\n    /**\n\t * Returns position options of the last view in the stack.\n\t * This keeps the balloon in the same position when the view is changed.\n\t */ getPositionOptions() {\n        let position = Array.from(this._visibleStack.values()).pop().position;\n        if (position) {\n            // Use the default limiter if none has been specified.\n            if (!position.limiter) {\n                // Don't modify the original options object.\n                position = Object.assign({}, position, {\n                    limiter: this.positionLimiter\n                });\n            }\n            // Don't modify the original options object.\n            position = Object.assign({}, position, {\n                viewportOffsetConfig: this.editor.ui.viewportOffset\n            });\n        }\n        return position;\n    }\n    /**\n\t * Shows the last view from the stack of a given ID.\n\t */ showStack(id) {\n        this.visibleStack = id;\n        const stack = this._idToStack.get(id);\n        if (!stack) {\n            /**\n\t\t\t * Trying to show a stack that does not exist.\n\t\t\t *\n\t\t\t * @error contextualballoon-showstack-stack-not-exist\n\t\t\t */ throw new CKEditorError('contextualballoon-showstack-stack-not-exist', this);\n        }\n        if (this._visibleStack === stack) {\n            return;\n        }\n        this._showView(Array.from(stack.values()).pop());\n    }\n    /**\n\t * Initializes view instances.\n\t */ _createPanelView() {\n        this._view = new BalloonPanelView(this.editor.locale);\n        this.editor.ui.view.body.add(this._view);\n        this._rotatorView = this._createRotatorView();\n        this._fakePanelsView = this._createFakePanelsView();\n    }\n    /**\n\t * Returns the stack of the currently visible view.\n\t */ get _visibleStack() {\n        return this._viewToStack.get(this.visibleView);\n    }\n    /**\n\t * Returns the ID of the given stack.\n\t */ _getStackId(stack) {\n        const entry = Array.from(this._idToStack.entries()).find((entry)=>entry[1] === stack);\n        return entry[0];\n    }\n    /**\n\t * Shows the last view from the next stack.\n\t */ _showNextStack() {\n        const stacks = Array.from(this._idToStack.values());\n        let nextIndex = stacks.indexOf(this._visibleStack) + 1;\n        if (!stacks[nextIndex]) {\n            nextIndex = 0;\n        }\n        this.showStack(this._getStackId(stacks[nextIndex]));\n    }\n    /**\n\t * Shows the last view from the previous stack.\n\t */ _showPrevStack() {\n        const stacks = Array.from(this._idToStack.values());\n        let nextIndex = stacks.indexOf(this._visibleStack) - 1;\n        if (!stacks[nextIndex]) {\n            nextIndex = stacks.length - 1;\n        }\n        this.showStack(this._getStackId(stacks[nextIndex]));\n    }\n    /**\n\t * Creates a rotator view.\n\t */ _createRotatorView() {\n        const view = new RotatorView(this.editor.locale);\n        const t = this.editor.locale.t;\n        this.view.content.add(view);\n        // Hide navigation when there is only a one stack & not in single view mode.\n        view.bind('isNavigationVisible').to(this, '_numberOfStacks', this, '_singleViewMode', (value, isSingleViewMode)=>{\n            return !isSingleViewMode && value > 1;\n        });\n        // Update balloon position after toggling navigation.\n        view.on('change:isNavigationVisible', ()=>this.updatePosition(), {\n            priority: 'low'\n        });\n        // Update stacks counter value.\n        view.bind('counter').to(this, 'visibleView', this, '_numberOfStacks', (visibleView, numberOfStacks)=>{\n            if (numberOfStacks < 2) {\n                return '';\n            }\n            const current = Array.from(this._idToStack.values()).indexOf(this._visibleStack) + 1;\n            return t('%0 of %1', [\n                current,\n                numberOfStacks\n            ]);\n        });\n        view.buttonNextView.on('execute', ()=>{\n            // When current view has a focus then move focus to the editable before removing it,\n            // otherwise editor will lost focus.\n            if (view.focusTracker.isFocused) {\n                this.editor.editing.view.focus();\n            }\n            this._showNextStack();\n        });\n        view.buttonPrevView.on('execute', ()=>{\n            // When current view has a focus then move focus to the editable before removing it,\n            // otherwise editor will lost focus.\n            if (view.focusTracker.isFocused) {\n                this.editor.editing.view.focus();\n            }\n            this._showPrevStack();\n        });\n        return view;\n    }\n    /**\n\t * Creates a fake panels view.\n\t */ _createFakePanelsView() {\n        const view = new FakePanelsView(this.editor.locale, this.view);\n        view.bind('numberOfPanels').to(this, '_numberOfStacks', this, '_singleViewMode', (number, isSingleViewMode)=>{\n            const showPanels = !isSingleViewMode && number >= 2;\n            return showPanels ? Math.min(number - 1, 2) : 0;\n        });\n        view.listenTo(this.view, 'change:top', ()=>view.updatePosition());\n        view.listenTo(this.view, 'change:left', ()=>view.updatePosition());\n        this.editor.ui.view.body.add(view);\n        return view;\n    }\n    /**\n\t * Sets the view as the content of the balloon and attaches the balloon using position\n\t * options of the first view.\n\t *\n\t * @param data Configuration.\n\t * @param data.view The view to show in the balloon.\n\t * @param data.balloonClassName Additional class name which will be added to the {@link #view balloon}.\n\t * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow.\n\t */ _showView({ view, balloonClassName = '', withArrow = true, singleViewMode = false }) {\n        this.view.class = balloonClassName;\n        this.view.withArrow = withArrow;\n        this._rotatorView.showView(view);\n        this.visibleView = view;\n        this.view.pin(this.getPositionOptions());\n        this._fakePanelsView.updatePosition();\n        if (singleViewMode) {\n            this._singleViewMode = true;\n        }\n    }\n}\n/**\n * Rotator view is a helper class for the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon}.\n * It is used for displaying the last view from the current stack and providing navigation buttons for switching stacks.\n * See the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon} documentation to learn more.\n */ class RotatorView extends View {\n    /**\n\t * Used for checking if a view is focused or not.\n\t */ focusTracker;\n    /**\n\t * Navigation button for switching the stack to the previous one.\n\t */ buttonPrevView;\n    /**\n\t * Navigation button for switching the stack to the next one.\n\t */ buttonNextView;\n    /**\n\t * A collection of the child views that creates the rotator content.\n\t */ content;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const t = locale.t;\n        const bind = this.bindTemplate;\n        this.set('isNavigationVisible', true);\n        this.focusTracker = new FocusTracker();\n        this.buttonPrevView = this._createButtonView(t('Previous'), icons.previousArrow);\n        this.buttonNextView = this._createButtonView(t('Next'), icons.nextArrow);\n        this.content = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-balloon-rotator'\n                ],\n                'z-index': '-1'\n            },\n            children: [\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck-balloon-rotator__navigation',\n                            bind.to('isNavigationVisible', (value)=>value ? '' : 'ck-hidden')\n                        ]\n                    },\n                    children: [\n                        this.buttonPrevView,\n                        {\n                            tag: 'span',\n                            attributes: {\n                                class: [\n                                    'ck-balloon-rotator__counter'\n                                ]\n                            },\n                            children: [\n                                {\n                                    text: bind.to('counter')\n                                }\n                            ]\n                        },\n                        this.buttonNextView\n                    ]\n                },\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: 'ck-balloon-rotator__content'\n                    },\n                    children: this.content\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.focusTracker.add(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n    }\n    /**\n\t * Shows a given view.\n\t *\n\t * @param view The view to show.\n\t */ showView(view) {\n        this.hideView();\n        this.content.add(view);\n    }\n    /**\n\t * Hides the currently displayed view.\n\t */ hideView() {\n        this.content.clear();\n    }\n    /**\n\t * Creates a navigation button view.\n\t *\n\t * @param label The button label.\n\t * @param icon The button icon.\n\t */ _createButtonView(label, icon) {\n        const view = new ButtonView(this.locale);\n        view.set({\n            label,\n            icon,\n            tooltip: true\n        });\n        return view;\n    }\n}\n/**\n * Displays additional layers under the balloon when multiple stacks are added to the balloon.\n */ class FakePanelsView extends View {\n    /**\n\t * Collection of the child views which creates fake panel content.\n\t */ content;\n    /**\n\t * Context.\n\t */ _balloonPanelView;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, balloonPanelView){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('top', 0);\n        this.set('left', 0);\n        this.set('height', 0);\n        this.set('width', 0);\n        this.set('numberOfPanels', 0);\n        this.content = this.createCollection();\n        this._balloonPanelView = balloonPanelView;\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck-fake-panel',\n                    bind.to('numberOfPanels', (number)=>number ? '' : 'ck-hidden')\n                ],\n                style: {\n                    top: bind.to('top', toPx$4),\n                    left: bind.to('left', toPx$4),\n                    width: bind.to('width', toPx$4),\n                    height: bind.to('height', toPx$4)\n                }\n            },\n            children: this.content\n        });\n        this.on('change:numberOfPanels', (evt, name, next, prev)=>{\n            if (next > prev) {\n                this._addPanels(next - prev);\n            } else {\n                this._removePanels(prev - next);\n            }\n            this.updatePosition();\n        });\n    }\n    _addPanels(number) {\n        while(number--){\n            const view = new View();\n            view.setTemplate({\n                tag: 'div'\n            });\n            this.content.add(view);\n            this.registerChild(view);\n        }\n    }\n    _removePanels(number) {\n        while(number--){\n            const view = this.content.last;\n            this.content.remove(view);\n            this.deregisterChild(view);\n            view.destroy();\n        }\n    }\n    /**\n\t * Updates coordinates of fake panels.\n\t */ updatePosition() {\n        if (this.numberOfPanels) {\n            const { top, left } = this._balloonPanelView;\n            const { width, height } = new Rect(this._balloonPanelView.element);\n            Object.assign(this, {\n                top,\n                left,\n                width,\n                height\n            });\n        }\n    }\n}\n\nconst toPx$3 = /* #__PURE__ */ toUnit('px');\n/**\n * The sticky panel view class.\n */ class StickyPanelView extends View {\n    /**\n\t * Collection of the child views which creates balloon panel contents.\n\t */ content;\n    /**\n\t * The panel which accepts children into {@link #content} collection.\n\t * Also an element which is positioned when {@link #isSticky}.\n\t */ contentPanelElement;\n    /**\n\t * A dummy element which visually fills the space as long as the\n\t * actual panel is sticky. It prevents flickering of the UI.\n\t */ _contentPanelPlaceholder;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('isActive', false);\n        this.set('isSticky', false);\n        this.set('limiterElement', null);\n        this.set('limiterBottomOffset', 50);\n        this.set('viewportTopOffset', 0);\n        this.set('_marginLeft', null);\n        this.set('_isStickyToTheBottomOfLimiter', false);\n        this.set('_stickyTopOffset', null);\n        this.set('_stickyBottomOffset', null);\n        this.content = this.createCollection();\n        this._contentPanelPlaceholder = new Template({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-sticky-panel__placeholder'\n                ],\n                style: {\n                    display: bind.to('isSticky', (isSticky)=>isSticky ? 'block' : 'none'),\n                    height: bind.to('isSticky', (isSticky)=>{\n                        return isSticky ? toPx$3(this._contentPanelRect.height) : null;\n                    })\n                }\n            }\n        }).render();\n        this.contentPanelElement = new Template({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-sticky-panel__content',\n                    // Toggle class of the panel when \"sticky\" state changes in the view.\n                    bind.if('isSticky', 'ck-sticky-panel__content_sticky'),\n                    bind.if('_isStickyToTheBottomOfLimiter', 'ck-sticky-panel__content_sticky_bottom-limit')\n                ],\n                style: {\n                    width: bind.to('isSticky', (isSticky)=>{\n                        return isSticky ? toPx$3(this._contentPanelPlaceholder.getBoundingClientRect().width) : null;\n                    }),\n                    top: bind.to('_stickyTopOffset', (value)=>value ? toPx$3(value) : value),\n                    bottom: bind.to('_stickyBottomOffset', (value)=>value ? toPx$3(value) : value),\n                    marginLeft: bind.to('_marginLeft')\n                }\n            },\n            children: this.content\n        }).render();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-sticky-panel'\n                ]\n            },\n            children: [\n                this._contentPanelPlaceholder,\n                this.contentPanelElement\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        // Check if the panel should go into the sticky state immediately.\n        this.checkIfShouldBeSticky();\n        // Update sticky state of the panel as the window and ancestors are being scrolled.\n        this.listenTo(global.document, 'scroll', ()=>{\n            this.checkIfShouldBeSticky();\n        }, {\n            useCapture: true\n        });\n        // Synchronize with `model.isActive` because sticking an inactive panel is pointless.\n        this.listenTo(this, 'change:isActive', ()=>{\n            this.checkIfShouldBeSticky();\n        });\n    }\n    /**\n\t * Analyzes the environment to decide whether the panel should be sticky or not.\n\t * Then handles the positioning of the panel.\n\t */ checkIfShouldBeSticky() {\n        // @if CK_DEBUG_STICKYPANEL // RectDrawer.clear();\n        if (!this.limiterElement || !this.isActive) {\n            this._unstick();\n            return;\n        }\n        const limiterRect = new Rect(this.limiterElement);\n        let visibleLimiterRect = limiterRect.getVisible();\n        if (visibleLimiterRect) {\n            const windowRect = new Rect(global.window);\n            windowRect.top += this.viewportTopOffset;\n            windowRect.height -= this.viewportTopOffset;\n            visibleLimiterRect = visibleLimiterRect.getIntersection(windowRect);\n        }\n        // @if CK_DEBUG_STICKYPANEL // if ( visibleLimiterRect ) {\n        // @if CK_DEBUG_STICKYPANEL // \tRectDrawer.draw( visibleLimiterRect,\n        // @if CK_DEBUG_STICKYPANEL // \t\t{ outlineWidth: '3px', opacity: '.8', outlineColor: 'red', outlineOffset: '-3px' },\n        // @if CK_DEBUG_STICKYPANEL // \t\t'Visible anc'\n        // @if CK_DEBUG_STICKYPANEL // \t);\n        // @if CK_DEBUG_STICKYPANEL // }\n        // @if CK_DEBUG_STICKYPANEL //\n        // @if CK_DEBUG_STICKYPANEL // RectDrawer.draw( limiterRect,\n        // @if CK_DEBUG_STICKYPANEL // \t{ outlineWidth: '3px', opacity: '.8', outlineColor: 'green', outlineOffset: '-3px' },\n        // @if CK_DEBUG_STICKYPANEL // \t'Limiter'\n        // @if CK_DEBUG_STICKYPANEL // );\n        // Stick the panel only if\n        // * the limiter's ancestors are intersecting with each other so that some of their rects are visible,\n        // * and the limiter's top edge is above the visible ancestors' top edge.\n        if (visibleLimiterRect && limiterRect.top < visibleLimiterRect.top) {\n            // @if CK_DEBUG_STICKYPANEL // RectDrawer.draw( visibleLimiterRect,\n            // @if CK_DEBUG_STICKYPANEL // \t{ outlineWidth: '3px', opacity: '.8', outlineColor: 'fuchsia', outlineOffset: '-3px',\n            // @if CK_DEBUG_STICKYPANEL // \t\tbackgroundColor: 'rgba(255, 0, 255, .3)' },\n            // @if CK_DEBUG_STICKYPANEL // \t'Visible limiter'\n            // @if CK_DEBUG_STICKYPANEL // );\n            const visibleLimiterTop = visibleLimiterRect.top;\n            // Check if there's a change the panel can be sticky to the bottom of the limiter.\n            if (visibleLimiterTop + this._contentPanelRect.height + this.limiterBottomOffset > visibleLimiterRect.bottom) {\n                const stickyBottomOffset = Math.max(limiterRect.bottom - visibleLimiterRect.bottom, 0) + this.limiterBottomOffset;\n                // @if CK_DEBUG_STICKYPANEL // const stickyBottomOffsetRect = new Rect( {\n                // @if CK_DEBUG_STICKYPANEL // \ttop: limiterRect.bottom - stickyBottomOffset, left: 0, right: 2000,\n                // @if CK_DEBUG_STICKYPANEL // \tbottom: limiterRect.bottom - stickyBottomOffset, width: 2000, height: 1\n                // @if CK_DEBUG_STICKYPANEL // } );\n                // @if CK_DEBUG_STICKYPANEL // RectDrawer.draw( stickyBottomOffsetRect,\n                // @if CK_DEBUG_STICKYPANEL // \t{ outlineWidth: '1px', opacity: '.8', outlineColor: 'black' },\n                // @if CK_DEBUG_STICKYPANEL // \t'Sticky bottom offset'\n                // @if CK_DEBUG_STICKYPANEL // );\n                // Check if sticking the panel to the bottom of the limiter does not cause it to suddenly\n                // move upwards if there's not enough space for it.\n                if (limiterRect.bottom - stickyBottomOffset > limiterRect.top + this._contentPanelRect.height) {\n                    this._stickToBottomOfLimiter(stickyBottomOffset);\n                } else {\n                    this._unstick();\n                }\n            } else {\n                if (this._contentPanelRect.height + this.limiterBottomOffset < limiterRect.height) {\n                    this._stickToTopOfAncestors(visibleLimiterTop);\n                } else {\n                    this._unstick();\n                }\n            }\n        } else {\n            this._unstick();\n        }\n    // @if CK_DEBUG_STICKYPANEL // console.clear();\n    // @if CK_DEBUG_STICKYPANEL // console.log( 'isSticky', this.isSticky );\n    // @if CK_DEBUG_STICKYPANEL // console.log( '_isStickyToTheBottomOfLimiter', this._isStickyToTheBottomOfLimiter );\n    // @if CK_DEBUG_STICKYPANEL // console.log( '_stickyTopOffset', this._stickyTopOffset );\n    // @if CK_DEBUG_STICKYPANEL // console.log( '_stickyBottomOffset', this._stickyBottomOffset );\n    // @if CK_DEBUG_STICKYPANEL // if ( visibleLimiterRect ) {\n    // @if CK_DEBUG_STICKYPANEL // \tRectDrawer.draw( visibleLimiterRect,\n    // @if CK_DEBUG_STICKYPANEL // \t\t{ ...diagonalStylesBlack,\n    // @if CK_DEBUG_STICKYPANEL // \t\t\toutlineWidth: '3px', opacity: '.8', outlineColor: 'orange', outlineOffset: '-3px',\n    // @if CK_DEBUG_STICKYPANEL // \t\t\tbackgroundColor: 'rgba(0, 0, 255, .2)' },\n    // @if CK_DEBUG_STICKYPANEL // \t\t'visibleLimiterRect'\n    // @if CK_DEBUG_STICKYPANEL // \t);\n    // @if CK_DEBUG_STICKYPANEL // }\n    }\n    /**\n\t * Sticks the panel at the given CSS `top` offset.\n\t *\n\t * @private\n\t * @param topOffset\n\t */ _stickToTopOfAncestors(topOffset) {\n        this.isSticky = true;\n        this._isStickyToTheBottomOfLimiter = false;\n        this._stickyTopOffset = topOffset;\n        this._stickyBottomOffset = null;\n        this._marginLeft = toPx$3(-global.window.scrollX);\n    }\n    /**\n\t * Sticks the panel at the bottom of the limiter with a given CSS `bottom` offset.\n\t *\n\t * @private\n\t * @param stickyBottomOffset\n\t */ _stickToBottomOfLimiter(stickyBottomOffset) {\n        this.isSticky = true;\n        this._isStickyToTheBottomOfLimiter = true;\n        this._stickyTopOffset = null;\n        this._stickyBottomOffset = stickyBottomOffset;\n        this._marginLeft = toPx$3(-global.window.scrollX);\n    }\n    /**\n\t * Unsticks the panel putting it back to its original position.\n\t *\n\t * @private\n\t */ _unstick() {\n        this.isSticky = false;\n        this._isStickyToTheBottomOfLimiter = false;\n        this._stickyTopOffset = null;\n        this._stickyBottomOffset = null;\n        this._marginLeft = null;\n    }\n    /**\n\t * Returns the bounding rect of the {@link #contentPanelElement}.\n\t *\n\t * @private\n\t */ get _contentPanelRect() {\n        return new Rect(this.contentPanelElement);\n    }\n}\n\n/**\n * A search input field for the {@link module:ui/search/text/searchtextview~SearchTextView} component.\n *\n * @internal\n * @extends module:ui/labeledfield/labeledfieldview~LabeledFieldView\n */ class SearchTextQueryView extends LabeledFieldView {\n    /**\n\t * The loupe icon displayed next to the {@link #fieldView}.\n\t */ iconView;\n    /**\n\t * The button that clears and focuses the {@link #fieldView}.\n\t */ resetButtonView;\n    /**\n\t * A reference to the view configuration.\n\t */ _viewConfig;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, config){\n        const t = locale.t;\n        const viewConfig = Object.assign({}, {\n            showResetButton: true,\n            showIcon: true,\n            creator: createLabeledInputText\n        }, config);\n        super(locale, viewConfig.creator);\n        this.label = config.label;\n        this._viewConfig = viewConfig;\n        if (this._viewConfig.showIcon) {\n            this.iconView = new IconView();\n            this.iconView.content = icons.loupe;\n            this.fieldWrapperChildren.add(this.iconView, 0);\n            this.extendTemplate({\n                attributes: {\n                    class: 'ck-search__query_with-icon'\n                }\n            });\n        }\n        if (this._viewConfig.showResetButton) {\n            this.resetButtonView = new ButtonView(locale);\n            this.resetButtonView.set({\n                label: t('Clear'),\n                icon: icons.cancel,\n                class: 'ck-search__reset',\n                isVisible: false,\n                tooltip: true\n            });\n            this.resetButtonView.on('execute', ()=>{\n                this.reset();\n                this.focus();\n                this.fire('reset');\n            });\n            this.resetButtonView.bind('isVisible').to(this.fieldView, 'isEmpty', (isEmpty)=>!isEmpty);\n            this.fieldWrapperChildren.add(this.resetButtonView);\n            this.extendTemplate({\n                attributes: {\n                    class: 'ck-search__query_with-reset'\n                }\n            });\n        }\n    }\n    /**\n\t * Resets the search field to its default state.\n\t */ reset() {\n        this.fieldView.reset();\n        if (this._viewConfig.showResetButton) {\n            this.resetButtonView.isVisible = false;\n        }\n    }\n}\n\n/**\n * A view displaying an information text related to different states of {@link module:ui/search/text/searchtextview~SearchTextView}.\n *\n * @internal\n */ class SearchInfoView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        const bind = this.bindTemplate;\n        this.set({\n            isVisible: false,\n            primaryText: '',\n            secondaryText: ''\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-search__info',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ],\n                tabindex: -1\n            },\n            children: [\n                {\n                    tag: 'span',\n                    children: [\n                        {\n                            text: [\n                                bind.to('primaryText')\n                            ]\n                        }\n                    ]\n                },\n                {\n                    tag: 'span',\n                    children: [\n                        {\n                            text: [\n                                bind.to('secondaryText')\n                            ]\n                        }\n                    ]\n                }\n            ]\n        });\n    }\n    /**\n\t * Focuses the view\n\t */ focus() {\n        this.element.focus();\n    }\n}\n\n/**\n * A sub-component of {@link module:ui/search/text/searchtextview~SearchTextView}. It hosts the filtered and the information views.\n */ class SearchResultsView extends View {\n    /**\n\t * Tracks information about the DOM focus in the view.\n\t *\n\t * @readonly\n\t */ focusTracker;\n    /**\n\t * The collection of the child views inside of the list item {@link #element}.\n\t *\n\t * @readonly\n\t */ children;\n    /**\n\t * Provides the focus management (keyboard navigation) in the view.\n\t *\n\t * @readonly\n\t */ _focusCycler;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.children = this.createCollection();\n        this.focusTracker = new FocusTracker();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-search__results'\n                ],\n                tabindex: -1\n            },\n            children: this.children\n        });\n        this._focusCycler = new FocusCycler({\n            focusables: this.children,\n            focusTracker: this.focusTracker\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        for (const child of this.children){\n            this.focusTracker.add(child.element);\n        }\n    }\n    /**\n\t * Focuses the view.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Focuses the first child view.\n\t */ focusFirst() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Focuses the last child view.\n\t */ focusLast() {\n        this._focusCycler.focusLast();\n    }\n}\n\n/**\n * A search component that allows filtering of an arbitrary view based on a search query\n * specified by the user in a text field.\n *\n *```ts\n * // This view must specify the `filter()` and `focus()` methods.\n * const filteredView = ...;\n *\n * const searchView = new SearchTextView( locale, {\n * \tsearchFieldLabel: 'Search list items',\n * \tfilteredView\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n */ class SearchTextView extends View {\n    /**\n\t * Tracks information about the DOM focus in the view.\n\t *\n\t * @readonly\n\t */ focusTracker;\n    /**\n\t * An instance of the keystroke handler managing user interaction and accessibility.\n\t *\n\t * @readonly\n\t */ keystrokes;\n    /**\n\t * A view hosting the {@link #filteredView} passed in the configuration and the {@link #infoView}.\n\t */ resultsView;\n    /**\n\t * The view that is filtered by the search query.\n\t */ filteredView;\n    /**\n\t * The view that displays the information about the search results.\n\t */ infoView;\n    /**\n\t * The view that allows the user to enter the search query.\n\t */ queryView;\n    /**\n\t * Provides the focus management (keyboard navigation) between {@link #queryView} and {@link #filteredView}.\n\t *\n\t * @readonly\n\t */ focusCycler;\n    /**\n\t * The cached configuration object.\n\t *\n\t * @internal\n\t */ _config;\n    /**\n\t * Creates an instance of the {@link module:ui/search/text/searchtextview~SearchTextView} class.\n\t *\n\t * @param locale The localization services instance.\n\t * @param config Configuration of the view.\n\t */ constructor(locale, config){\n        super(locale);\n        this._config = config;\n        this.filteredView = config.filteredView;\n        this.queryView = this._createSearchTextQueryView();\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.resultsView = new SearchResultsView(locale);\n        this.children = this.createCollection();\n        this.focusableChildren = this.createCollection([\n            this.queryView,\n            this.resultsView\n        ]);\n        this.set('isEnabled', true);\n        this.set('resultsCount', 0);\n        this.set('totalItemsCount', 0);\n        if (config.infoView && config.infoView.instance) {\n            this.infoView = config.infoView.instance;\n        } else {\n            this.infoView = new SearchInfoView();\n            this._enableDefaultInfoViewBehavior();\n            this.on('render', ()=>{\n                // Initial search that determines if there are any searchable items\n                // and displays the corresponding info text.\n                this.search('');\n            });\n        }\n        this.resultsView.children.addMany([\n            this.infoView,\n            this.filteredView\n        ]);\n        this.focusCycler = new FocusCycler({\n            focusables: this.focusableChildren,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        this.on('search', (evt, { resultsCount, totalItemsCount })=>{\n            this.resultsCount = resultsCount;\n            this.totalItemsCount = totalItemsCount;\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-search',\n                    config.class || null\n                ],\n                tabindex: '-1'\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.children.addMany([\n            this.queryView,\n            this.resultsView\n        ]);\n        const stopPropagation = (data)=>data.stopPropagation();\n        for (const focusableChild of this.focusableChildren){\n            this.focusTracker.add(focusableChild.element);\n        }\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n        // Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n        // keystroke handler would take over the key management in the URL input. We need to prevent\n        // this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n        this.keystrokes.set('arrowright', stopPropagation);\n        this.keystrokes.set('arrowleft', stopPropagation);\n        this.keystrokes.set('arrowup', stopPropagation);\n        this.keystrokes.set('arrowdown', stopPropagation);\n    }\n    /**\n\t * Focuses the {@link #queryView}.\n\t */ focus() {\n        this.queryView.focus();\n    }\n    /**\n\t * Resets the component to its initial state.\n\t */ reset() {\n        this.queryView.reset();\n        this.search('');\n        this.filteredView.element.scrollTo(0, 0);\n    }\n    /**\n\t * Searches the {@link #filteredView} for the given query.\n\t *\n\t * @internal\n\t * @param query The search query string.\n\t */ search(query) {\n        const regExp = query ? new RegExp(escapeRegExp(query), 'ig') : null;\n        const filteringResults = this.filteredView.filter(regExp);\n        this.fire('search', {\n            query,\n            ...filteringResults\n        });\n    }\n    /**\n\t * Creates a search field view based on configured creator..\n\t */ _createSearchTextQueryView() {\n        const queryView = new SearchTextQueryView(this.locale, this._config.queryView);\n        this.listenTo(queryView.fieldView, 'input', ()=>{\n            this.search(queryView.fieldView.element.value);\n        });\n        queryView.on('reset', ()=>this.reset());\n        queryView.bind('isEnabled').to(this);\n        return queryView;\n    }\n    /**\n\t * Initializes the default {@link #infoView} behavior with default text labels when no custom info view\n\t * was specified in the view config.\n\t */ _enableDefaultInfoViewBehavior() {\n        const t = this.locale.t;\n        const infoView = this.infoView;\n        this.on('search', (evt, data)=>{\n            if (!data.resultsCount) {\n                const defaultTextConfig = this._config.infoView && this._config.infoView.text;\n                let primaryText, secondaryText;\n                if (data.totalItemsCount) {\n                    if (defaultTextConfig && defaultTextConfig.notFound) {\n                        primaryText = defaultTextConfig.notFound.primary;\n                        secondaryText = defaultTextConfig.notFound.secondary;\n                    } else {\n                        primaryText = t('No results found');\n                        secondaryText = '';\n                    }\n                } else {\n                    if (defaultTextConfig && defaultTextConfig.noSearchableItems) {\n                        primaryText = defaultTextConfig.noSearchableItems.primary;\n                        secondaryText = defaultTextConfig.noSearchableItems.secondary;\n                    } else {\n                        primaryText = t('No searchable items');\n                        secondaryText = '';\n                    }\n                }\n                infoView.set({\n                    primaryText: normalizeInfoText(primaryText, data),\n                    secondaryText: normalizeInfoText(secondaryText, data),\n                    isVisible: true\n                });\n            } else {\n                infoView.set({\n                    isVisible: false\n                });\n            }\n        });\n        function normalizeInfoText(text, { query, resultsCount, totalItemsCount }) {\n            return typeof text === 'function' ? text(query, resultsCount, totalItemsCount) : text;\n        }\n    }\n}\n\n/**\n * The autocomplete component's view class. It extends the {@link module:ui/search/text/searchtextview~SearchTextView} class\n * with a floating {@link #resultsView} that shows up when the user starts typing and hides when they blur\n * the component.\n */ class AutocompleteView extends SearchTextView {\n    /**\n\t * The configuration of the autocomplete view.\n\t */ _config;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, config){\n        super(locale, config);\n        this._config = config;\n        const toPx = toUnit('px');\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-autocomplete'\n                ]\n            }\n        });\n        const bindResultsView = this.resultsView.bindTemplate;\n        this.resultsView.set('isVisible', false);\n        this.resultsView.set('_position', 's');\n        this.resultsView.set('_width', 0);\n        this.resultsView.extendTemplate({\n            attributes: {\n                class: [\n                    bindResultsView.if('isVisible', 'ck-hidden', (value)=>!value),\n                    bindResultsView.to('_position', (value)=>`ck-search__results_${value}`)\n                ],\n                style: {\n                    width: bindResultsView.to('_width', toPx)\n                }\n            }\n        });\n        // Update the visibility of the results view when the user focuses or blurs the component.\n        // This is also integration for the `resetOnBlur` configuration.\n        this.focusTracker.on('change:isFocused', (evt, name, isFocused)=>{\n            this._updateResultsVisibility();\n            if (isFocused) {\n                // Reset the scroll position of the results view whenever the autocomplete reopens.\n                this.resultsView.element.scrollTop = 0;\n            } else if (config.resetOnBlur) {\n                this.queryView.reset();\n            }\n        });\n        // Update the visibility of the results view when the user types in the query field.\n        // This is an integration for `queryMinChars` configuration.\n        // This is an integration for search results changing length and the #resultsView requiring to be repositioned.\n        this.on('search', ()=>{\n            this._updateResultsVisibility();\n            this._updateResultsViewWidthAndPosition();\n        });\n        // Hide the results view when the user presses the ESC key.\n        this.keystrokes.set('esc', (evt, cancel)=>{\n            // Let the DOM event pass through if the focus is in the query view.\n            if (!this.resultsView.isVisible) {\n                return;\n            }\n            // Focus the query view first and only then close the results view. Otherwise, if the focus\n            // was in the results view, it will get lost.\n            this.queryView.focus();\n            this.resultsView.isVisible = false;\n            cancel();\n        });\n        // Update the position of the results view when the user scrolls the page.\n        // TODO: This needs to be debounced down the road.\n        this.listenTo(global.document, 'scroll', ()=>{\n            this._updateResultsViewWidthAndPosition();\n        });\n        // Hide the results when the component becomes disabled.\n        this.on('change:isEnabled', ()=>{\n            this._updateResultsVisibility();\n        });\n        // Update the value of the query field when the user selects a result.\n        this.filteredView.on('execute', (evt, { value })=>{\n            // Focus the query view first to avoid losing the focus.\n            this.focus();\n            // Resetting the view will ensure that the #queryView will update its empty state correctly.\n            // This prevents bugs related to dynamic labels or auto-grow when re-setting the same value\n            // to #queryView.fieldView.value (which does not trigger empty state change) to an\n            // #queryView.fieldView.element that has been changed by the user.\n            this.reset();\n            // Update the value of the query field.\n            this.queryView.fieldView.value = this.queryView.fieldView.element.value = value;\n            // Finally, hide the results view. The focus has been moved earlier so this is safe.\n            this.resultsView.isVisible = false;\n        });\n        // Update the position and width of the results view when it becomes visible.\n        this.resultsView.on('change:isVisible', ()=>{\n            this._updateResultsViewWidthAndPosition();\n        });\n    }\n    /**\n\t * Updates the position of the results view on demand.\n\t */ _updateResultsViewWidthAndPosition() {\n        if (!this.resultsView.isVisible) {\n            return;\n        }\n        this.resultsView._width = new Rect(this.queryView.fieldView.element).width;\n        const optimalResultsPosition = AutocompleteView._getOptimalPosition({\n            element: this.resultsView.element,\n            target: this.queryView.element,\n            fitInViewport: true,\n            positions: AutocompleteView.defaultResultsPositions\n        });\n        // _getOptimalPosition will return null if there is no optimal position found (e.g. target is off the viewport).\n        this.resultsView._position = optimalResultsPosition ? optimalResultsPosition.name : 's';\n    }\n    /**\n\t * Updates the visibility of the results view on demand.\n\t */ _updateResultsVisibility() {\n        const queryMinChars = typeof this._config.queryMinChars === 'undefined' ? 0 : this._config.queryMinChars;\n        const queryLength = this.queryView.fieldView.element.value.length;\n        this.resultsView.isVisible = this.focusTracker.isFocused && this.isEnabled && queryLength >= queryMinChars;\n    }\n    /**\n\t * Positions for the autocomplete results view. Two positions are defined by default:\n\t * * `s` - below the search field,\n\t * * `n` - above the search field.\n\t */ static defaultResultsPositions = [\n        (fieldRect)=>{\n            return {\n                top: fieldRect.bottom,\n                left: fieldRect.left,\n                name: 's'\n            };\n        },\n        (fieldRect, resultsRect)=>{\n            return {\n                top: fieldRect.top - resultsRect.height,\n                left: fieldRect.left,\n                name: 'n'\n            };\n        }\n    ];\n    /**\n\t * A function used to calculate the optimal position for the dropdown panel.\n\t */ static _getOptimalPosition = getOptimalPosition;\n}\n\n/**\n * A class representing a view that displays a text which subset can be highlighted using the\n * {@link #highlightText} method.\n */ class HighlightedTextView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        this.set('text', undefined);\n        this.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-highlighted-text'\n                ]\n            }\n        });\n        this.on('render', ()=>{\n            // Classic setTemplate binding for #text will not work because highlightText() replaces the\n            // pre-rendered DOM text node new a new one (and <mark> elements).\n            this.on('change:text', ()=>{\n                this._updateInnerHTML(this.text);\n            });\n            this._updateInnerHTML(this.text);\n        });\n    }\n    /**\n\t * Highlights view's {@link #text} according to the specified `RegExp`. If the passed RegExp is `null`, the\n\t * highlighting is removed\n\t *\n\t * @param regExp\n\t */ highlightText(regExp) {\n        this._updateInnerHTML(markText(this.text || '', regExp));\n    }\n    /**\n\t * Updates element's `innerHTML` with the passed content.\n\t */ _updateInnerHTML(newInnerHTML) {\n        this.element.innerHTML = newInnerHTML || '';\n    }\n}\n/**\n * Replaces `regExp` occurrences with `<mark>` tags in a text.\n *\n * @param text A text to get marked.\n * @param regExp An optional `RegExp`. If not passed, this is a pass-through function.\n * @returns A text with `RegExp` occurrences marked by `<mark>`.\n */ function markText(text, regExp) {\n    if (!regExp) {\n        return escape(text);\n    }\n    const textParts = [];\n    let lastMatchEnd = 0;\n    let matchInfo = regExp.exec(text);\n    // Iterate over all matches and create an array of text parts. The idea is to mark which parts are query matches\n    // so that later on they can be highlighted.\n    while(matchInfo !== null){\n        const curMatchStart = matchInfo.index;\n        // Detect if there was something between last match and this one.\n        if (curMatchStart !== lastMatchEnd) {\n            textParts.push({\n                text: text.substring(lastMatchEnd, curMatchStart),\n                isMatch: false\n            });\n        }\n        textParts.push({\n            text: matchInfo[0],\n            isMatch: true\n        });\n        lastMatchEnd = regExp.lastIndex;\n        matchInfo = regExp.exec(text);\n    }\n    // Your match might not be the last part of a string. Be sure to add any plain text following the last match.\n    if (lastMatchEnd !== text.length) {\n        textParts.push({\n            text: text.substring(lastMatchEnd),\n            isMatch: false\n        });\n    }\n    const outputHtml = textParts// The entire text should be escaped.\n    .map((part)=>{\n        part.text = escape(part.text);\n        return part;\n    })// Only matched text should be wrapped with HTML mark element.\n    .map((part)=>part.isMatch ? `<mark>${part.text}</mark>` : part.text).join('');\n    return outputHtml;\n}\n\n/**\n * A button label view that can highlight a text fragment.\n */ class ButtonLabelWithHighlightView extends HighlightedTextView {\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        this.set({\n            style: undefined,\n            text: undefined,\n            id: undefined\n        });\n        const bind = this.bindTemplate;\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-button__label'\n                ],\n                style: bind.to('style'),\n                id: bind.to('id')\n            }\n        });\n    }\n}\n\n/**\n * A label view that can highlight a text fragment.\n */ class LabelWithHighlightView extends HighlightedTextView {\n    /**\n\t * @inheritDoc\n\t */ id;\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        this.set('for', undefined);\n        const bind = this.bindTemplate;\n        this.id = `ck-editor__label_${uid()}`;\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-label'\n                ],\n                id: this.id,\n                for: bind.to('for')\n            }\n        });\n    }\n}\n\n/**\n * The spinner view class.\n */ class SpinnerView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        this.set('isVisible', false);\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-spinner-container',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ]\n            },\n            children: [\n                {\n                    tag: 'span',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-spinner'\n                        ]\n                    }\n                }\n            ]\n        });\n    }\n}\n\nconst toPx$2 = /* #__PURE__ */ toUnit('px');\n/**\n * The contextual toolbar.\n *\n * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */ class BalloonToolbar extends Plugin {\n    /**\n\t * The toolbar view displayed in the balloon.\n\t */ toolbarView;\n    /**\n\t * Tracks the focus of the {@link module:ui/editorui/editorui~EditorUI#getEditableElement editable element}\n\t * and the {@link #toolbarView}. When both are blurred then the toolbar should hide.\n\t */ focusTracker;\n    /**\n\t * A cached and normalized `config.balloonToolbar` object.\n\t */ _balloonConfig;\n    /**\n\t * An instance of the resize observer that allows to respond to changes in editable's geometry\n\t * so the toolbar can stay within its boundaries (and group toolbar items that do not fit).\n\t *\n\t * **Note**: Used only when `shouldNotGroupWhenFull` was **not** set in the\n\t * {@link module:core/editor/editorconfig~EditorConfig#balloonToolbar configuration}.\n\t *\n\t * **Note:** Created in {@link #init}.\n\t */ _resizeObserver = null;\n    /**\n\t * The contextual balloon plugin instance.\n\t */ _balloon;\n    /**\n\t * Fires `_selectionChangeDebounced` event using `lodash#debounce`.\n\t *\n\t * This event is an internal plugin event which is fired 200 ms after model selection last change.\n\t * This is to makes easy test debounced action without need to use `setTimeout`.\n\t *\n\t * This function is stored as a plugin property to make possible to cancel\n\t * trailing debounced invocation on destroy.\n\t */ _fireSelectionChangeDebounced;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'BalloonToolbar';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._balloonConfig = normalizeToolbarConfig(editor.config.get('balloonToolbar'));\n        this.toolbarView = this._createToolbarView();\n        this.focusTracker = new FocusTracker();\n        // Track focusable elements in the toolbar and the editable elements.\n        this._trackFocusableEditableElements();\n        this.focusTracker.add(this.toolbarView);\n        // Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n        editor.ui.addToolbar(this.toolbarView, {\n            beforeFocus: ()=>this.show(true),\n            afterBlur: ()=>this.hide(),\n            isContextual: true\n        });\n        this._balloon = editor.plugins.get(ContextualBalloon);\n        this._fireSelectionChangeDebounced = debounce(()=>this.fire('_selectionChangeDebounced'), 200);\n        // The appearance of the BalloonToolbar method is event–driven.\n        // It is possible to stop the #show event and this prevent the toolbar from showing up.\n        this.decorate('show');\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        // Show/hide the toolbar on editable focus/blur.\n        this.listenTo(this.focusTracker, 'change:isFocused', (evt, name, isFocused)=>{\n            const isToolbarVisible = this._balloon.visibleView === this.toolbarView;\n            if (!isFocused && isToolbarVisible) {\n                this.hide();\n            } else if (isFocused) {\n                this.show();\n            }\n        });\n        // Hide the toolbar when the selection is changed by a direct change or has changed to collapsed.\n        this.listenTo(selection, 'change:range', (evt, data)=>{\n            if (data.directChange || selection.isCollapsed) {\n                this.hide();\n            }\n            // Fire internal `_selectionChangeDebounced` event to use it for showing\n            // the toolbar after the selection stops changing.\n            this._fireSelectionChangeDebounced();\n        });\n        // Show the toolbar when the selection stops changing.\n        this.listenTo(this, '_selectionChangeDebounced', ()=>{\n            if (this.editor.editing.view.document.isFocused) {\n                this.show();\n            }\n        });\n        if (!this._balloonConfig.shouldNotGroupWhenFull) {\n            this.listenTo(editor, 'ready', ()=>{\n                const editableElement = editor.ui.view.editable.element;\n                // Set #toolbarView's max-width on the initialization and update it on the editable resize.\n                this._resizeObserver = new ResizeObserver(editableElement, (entry)=>{\n                    // The max-width equals 90% of the editable's width for the best user experience.\n                    // The value keeps the balloon very close to the boundaries of the editable and limits the cases\n                    // when the balloon juts out from the editable element it belongs to.\n                    this.toolbarView.maxWidth = toPx$2(entry.contentRect.width * .9);\n                });\n            });\n        }\n        // Listen to the toolbar view and whenever it changes its geometry due to some items being\n        // grouped or ungrouped, update the position of the balloon because a shorter/longer toolbar\n        // means the balloon could be pointing at the wrong place. Once updated, the balloon will point\n        // at the right selection in the content again.\n        // https://github.com/ckeditor/ckeditor5/issues/6444\n        this.listenTo(this.toolbarView, 'groupedItemsUpdate', ()=>{\n            this._updatePosition();\n        });\n        // Creates toolbar components based on given configuration.\n        // This needs to be done when all plugins are ready.\n        editor.ui.once('ready', ()=>{\n            this.toolbarView.fillFromConfig(this._balloonConfig, this.editor.ui.componentFactory);\n        });\n    }\n    /**\n\t * Creates the toolbar view instance.\n\t */ _createToolbarView() {\n        const t = this.editor.locale.t;\n        const shouldGroupWhenFull = !this._balloonConfig.shouldNotGroupWhenFull;\n        const toolbarView = new ToolbarView(this.editor.locale, {\n            shouldGroupWhenFull,\n            isFloating: true\n        });\n        toolbarView.ariaLabel = t('Editor contextual toolbar');\n        toolbarView.render();\n        return toolbarView;\n    }\n    /**\n\t * Shows the toolbar and attaches it to the selection.\n\t *\n\t * Fires {@link #event:show} event which can be stopped to prevent the toolbar from showing up.\n\t *\n\t * @param showForCollapsedSelection When set `true`, the toolbar will show despite collapsed selection in the\n\t * editing view.\n\t */ show(showForCollapsedSelection = false) {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const schema = editor.model.schema;\n        // Do not add the toolbar to the balloon stack twice.\n        if (this._balloon.hasView(this.toolbarView)) {\n            return;\n        }\n        // Do not show the toolbar when the selection is collapsed.\n        if (selection.isCollapsed && !showForCollapsedSelection) {\n            return;\n        }\n        // Do not show the toolbar when there is more than one range in the selection and they fully contain selectable elements.\n        // See https://github.com/ckeditor/ckeditor5/issues/6443.\n        if (selectionContainsOnlyMultipleSelectables(selection, schema)) {\n            return;\n        }\n        // Do not show the toolbar when all components inside are disabled\n        // see https://github.com/ckeditor/ckeditor5-ui/issues/269.\n        if (Array.from(this.toolbarView.items).every((item)=>item.isEnabled !== undefined && !item.isEnabled)) {\n            return;\n        }\n        // Update the toolbar position when the editor ui should be refreshed.\n        this.listenTo(this.editor.ui, 'update', ()=>{\n            this._updatePosition();\n        });\n        // Add the toolbar to the common editor contextual balloon.\n        this._balloon.add({\n            view: this.toolbarView,\n            position: this._getBalloonPositionData(),\n            balloonClassName: 'ck-toolbar-container'\n        });\n    }\n    /**\n\t * Hides the toolbar.\n\t */ hide() {\n        if (this._balloon.hasView(this.toolbarView)) {\n            this.stopListening(this.editor.ui, 'update');\n            this._balloon.remove(this.toolbarView);\n        }\n    }\n    /**\n\t * Add or remove editable elements to the focus tracker. It watches added and removed roots\n\t * and adds or removes their editable elements to the focus tracker.\n\t */ _trackFocusableEditableElements() {\n        const { editor, focusTracker } = this;\n        const { editing } = editor;\n        editing.view.addObserver(class TrackEditableElements extends Observer {\n            /**\n\t\t\t * @inheritDoc\n\t\t\t */ observe(domElement) {\n                focusTracker.add(domElement);\n            }\n            /**\n\t\t\t * @inheritDoc\n\t\t\t */ stopObserving(domElement) {\n                focusTracker.remove(domElement);\n            }\n        });\n    }\n    /**\n\t * Returns positioning options for the {@link #_balloon}. They control the way balloon is attached\n\t * to the selection.\n\t */ _getBalloonPositionData() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const viewSelection = viewDocument.selection;\n        // Get direction of the selection.\n        const isBackward = viewDocument.selection.isBackward;\n        return {\n            // Because the target for BalloonPanelView is a Rect (not DOMRange), it's geometry will stay fixed\n            // as the window scrolls. To let the BalloonPanelView follow such Rect, is must be continuously\n            // computed and hence, the target is defined as a function instead of a static value.\n            // https://github.com/ckeditor/ckeditor5-ui/issues/195\n            target: ()=>{\n                const range = isBackward ? viewSelection.getFirstRange() : viewSelection.getLastRange();\n                const rangeRects = Rect.getDomRangeRects(view.domConverter.viewRangeToDom(range));\n                // Select the proper range rect depending on the direction of the selection.\n                if (isBackward) {\n                    return rangeRects[0];\n                } else {\n                    // Ditch the zero-width \"orphan\" rect in the next line for the forward selection if there's\n                    // another one preceding it. It is not rendered as a selection by the web browser anyway.\n                    // https://github.com/ckeditor/ckeditor5-ui/issues/308\n                    if (rangeRects.length > 1 && rangeRects[rangeRects.length - 1].width === 0) {\n                        rangeRects.pop();\n                    }\n                    return rangeRects[rangeRects.length - 1];\n                }\n            },\n            positions: this._getBalloonPositions(isBackward)\n        };\n    }\n    /**\n\t * Updates the position of the {@link #_balloon} to make up for changes:\n\t *\n\t * * in the geometry of the selection it is attached to (e.g. the selection moved in the viewport or expanded or shrunk),\n\t * * or the geometry of the balloon toolbar itself (e.g. the toolbar has grouped or ungrouped some items and it is shorter or longer).\n\t */ _updatePosition() {\n        this._balloon.updatePosition(this._getBalloonPositionData());\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.stopListening();\n        this._fireSelectionChangeDebounced.cancel();\n        this.toolbarView.destroy();\n        this.focusTracker.destroy();\n        if (this._resizeObserver) {\n            this._resizeObserver.destroy();\n        }\n    }\n    /**\n\t * Returns toolbar positions for the given direction of the selection.\n\t */ _getBalloonPositions(isBackward) {\n        const isSafariIniOS = env.isSafari && env.isiOS;\n        // https://github.com/ckeditor/ckeditor5/issues/7707\n        const positions = isSafariIniOS ? BalloonPanelView.generatePositions({\n            // 20px when zoomed out. Less then 20px when zoomed in; the \"radius\" of the native selection handle gets\n            // smaller as the user zooms in. No less than the default v-offset, though.\n            heightOffset: Math.max(BalloonPanelView.arrowHeightOffset, Math.round(20 / global.window.visualViewport.scale))\n        }) : BalloonPanelView.defaultPositions;\n        return isBackward ? [\n            positions.northWestArrowSouth,\n            positions.northWestArrowSouthWest,\n            positions.northWestArrowSouthEast,\n            positions.northWestArrowSouthMiddleEast,\n            positions.northWestArrowSouthMiddleWest,\n            positions.southWestArrowNorth,\n            positions.southWestArrowNorthWest,\n            positions.southWestArrowNorthEast,\n            positions.southWestArrowNorthMiddleWest,\n            positions.southWestArrowNorthMiddleEast\n        ] : [\n            positions.southEastArrowNorth,\n            positions.southEastArrowNorthEast,\n            positions.southEastArrowNorthWest,\n            positions.southEastArrowNorthMiddleEast,\n            positions.southEastArrowNorthMiddleWest,\n            positions.northEastArrowSouth,\n            positions.northEastArrowSouthEast,\n            positions.northEastArrowSouthWest,\n            positions.northEastArrowSouthMiddleEast,\n            positions.northEastArrowSouthMiddleWest\n        ];\n    }\n}\n/**\n * Returns \"true\" when the selection has multiple ranges and each range contains a selectable element\n * and nothing else.\n */ function selectionContainsOnlyMultipleSelectables(selection, schema) {\n    // It doesn't contain multiple objects if there is only one range.\n    if (selection.rangeCount === 1) {\n        return false;\n    }\n    return [\n        ...selection.getRanges()\n    ].every((range)=>{\n        const element = range.getContainedElement();\n        return element && schema.isSelectable(element);\n    });\n}\n\nconst toPx$1 = /* #__PURE__ */ toUnit('px');\n/**\n * The block button view class.\n *\n * This view represents a button attached next to block element where the selection is anchored.\n *\n * See {@link module:ui/toolbar/block/blocktoolbar~BlockToolbar}.\n */ class BlockButtonView extends ButtonView {\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        // Hide button on init.\n        this.isVisible = false;\n        this.isToggleable = true;\n        this.set('top', 0);\n        this.set('left', 0);\n        this.extendTemplate({\n            attributes: {\n                class: 'ck-block-toolbar-button',\n                style: {\n                    top: bind.to('top', (val)=>toPx$1(val)),\n                    left: bind.to('left', (val)=>toPx$1(val))\n                }\n            }\n        });\n    }\n}\n\nconst toPx = /* #__PURE__ */ toUnit('px');\n/**\n * The block toolbar plugin.\n *\n * This plugin provides a button positioned next to the block of content where the selection is anchored.\n * Upon clicking the button, a dropdown providing access to editor features shows up, as configured in\n * {@link module:core/editor/editorconfig~EditorConfig#blockToolbar}.\n *\n * By default, the button is displayed next to all elements marked in {@link module:engine/model/schema~Schema}\n * as `$block` for which the toolbar provides at least one option.\n *\n * By default, the button is attached so its right boundary is touching the\n * {@link module:engine/view/editableelement~EditableElement}:\n *\n * ```\n *  __ |\n * |  ||  This is a block of content that the\n *  ¯¯ |  button is attached to. This is a\n *     |  block of content that the button is\n *     |  attached to.\n * ```\n *\n * The position of the button can be adjusted using the CSS `transform` property:\n *\n * ```css\n * .ck-block-toolbar-button {\n * \ttransform: translateX( -10px );\n * }\n * ```\n *\n * ```\n *  __   |\n * |  |  |  This is a block of content that the\n *  ¯¯   |  button is attached to. This is a\n *       |  block of content that the button is\n *       |  attached to.\n * ```\n *\n * **Note**: If you plan to run the editor in a right–to–left (RTL) language, keep in mind the button\n * will be attached to the **right** boundary of the editable area. In that case, make sure the\n * CSS position adjustment works properly by adding the following styles:\n *\n * ```css\n * .ck[dir=\"rtl\"] .ck-block-toolbar-button {\n * \ttransform: translateX( 10px );\n * }\n * ```\n */ class BlockToolbar extends Plugin {\n    /**\n\t * The toolbar view.\n\t */ toolbarView;\n    /**\n\t * The balloon panel view, containing the {@link #toolbarView}.\n\t */ panelView;\n    /**\n\t * The button view that opens the {@link #toolbarView}.\n\t */ buttonView;\n    /**\n\t * An instance of the resize observer that allows to respond to changes in editable's geometry\n\t * so the toolbar can stay within its boundaries (and group toolbar items that do not fit).\n\t *\n\t * **Note**: Used only when `shouldNotGroupWhenFull` was **not** set in the\n\t * {@link module:core/editor/editorconfig~EditorConfig#blockToolbar configuration}.\n\t */ _resizeObserver = null;\n    /**\n\t * A cached and normalized `config.blockToolbar` object.\n\t */ _blockToolbarConfig;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'BlockToolbar';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._blockToolbarConfig = normalizeToolbarConfig(this.editor.config.get('blockToolbar'));\n        this.toolbarView = this._createToolbarView();\n        this.panelView = this._createPanelView();\n        this.buttonView = this._createButtonView();\n        // Close the #panelView upon clicking outside of the plugin UI.\n        clickOutsideHandler({\n            emitter: this.panelView,\n            contextElements: [\n                this.panelView.element,\n                this.buttonView.element\n            ],\n            activator: ()=>this.panelView.isVisible,\n            callback: ()=>this._hidePanel()\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.t;\n        const editBlockText = t('Click to edit block');\n        const dragToMoveText = t('Drag to move');\n        const editBlockLabel = t('Edit block');\n        const isDragDropBlockToolbarPluginLoaded = editor.plugins.has('DragDropBlockToolbar');\n        const label = isDragDropBlockToolbarPluginLoaded ? `${editBlockText}\\n${dragToMoveText}` : editBlockLabel;\n        this.buttonView.label = label;\n        if (isDragDropBlockToolbarPluginLoaded) {\n            this.buttonView.element.dataset.ckeTooltipClass = 'ck-tooltip_multi-line';\n        }\n        // Hides panel on a direct selection change.\n        this.listenTo(editor.model.document.selection, 'change:range', (evt, data)=>{\n            if (data.directChange) {\n                this._hidePanel();\n            }\n        });\n        this.listenTo(editor.ui, 'update', ()=>this._updateButton());\n        // `low` priority is used because of https://github.com/ckeditor/ckeditor5-core/issues/133.\n        this.listenTo(editor, 'change:isReadOnly', ()=>this._updateButton(), {\n            priority: 'low'\n        });\n        this.listenTo(editor.ui.focusTracker, 'change:isFocused', ()=>this._updateButton());\n        // Reposition button on resize.\n        this.listenTo(this.buttonView, 'change:isVisible', (evt, name, isVisible)=>{\n            if (isVisible) {\n                // Keep correct position of button and panel on window#resize.\n                this.buttonView.listenTo(window, 'resize', ()=>this._updateButton());\n            } else {\n                // Stop repositioning button when is hidden.\n                this.buttonView.stopListening(window, 'resize');\n                // Hide the panel when the button disappears.\n                this._hidePanel();\n            }\n        });\n        // Reposition button on scroll.\n        this._repositionButtonOnScroll();\n        // Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n        editor.ui.addToolbar(this.toolbarView, {\n            beforeFocus: ()=>this._showPanel(),\n            afterBlur: ()=>this._hidePanel()\n        });\n        // Fills the toolbar with its items based on the configuration.\n        // This needs to be done after all plugins are ready.\n        editor.ui.once('ready', ()=>{\n            this.toolbarView.fillFromConfig(this._blockToolbarConfig, this.editor.ui.componentFactory);\n            // Hide panel before executing each button in the panel.\n            for (const item of this.toolbarView.items){\n                item.on('execute', ()=>this._hidePanel(true), {\n                    priority: 'high'\n                });\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n        this.panelView.destroy();\n        this.buttonView.destroy();\n        this.toolbarView.destroy();\n        if (this._resizeObserver) {\n            this._resizeObserver.destroy();\n        }\n    }\n    /**\n\t * Creates the {@link #toolbarView}.\n\t */ _createToolbarView() {\n        const t = this.editor.locale.t;\n        const shouldGroupWhenFull = !this._blockToolbarConfig.shouldNotGroupWhenFull;\n        const toolbarView = new ToolbarView(this.editor.locale, {\n            shouldGroupWhenFull,\n            isFloating: true\n        });\n        toolbarView.ariaLabel = t('Editor block content toolbar');\n        return toolbarView;\n    }\n    /**\n\t * Creates the {@link #panelView}.\n\t */ _createPanelView() {\n        const editor = this.editor;\n        const panelView = new BalloonPanelView(editor.locale);\n        panelView.content.add(this.toolbarView);\n        panelView.class = 'ck-toolbar-container';\n        editor.ui.view.body.add(panelView);\n        // Close #panelView on `Esc` press.\n        this.toolbarView.keystrokes.set('Esc', (evt, cancel)=>{\n            this._hidePanel(true);\n            cancel();\n        });\n        return panelView;\n    }\n    /**\n\t * Creates the {@link #buttonView}.\n\t */ _createButtonView() {\n        const editor = this.editor;\n        const t = editor.t;\n        const buttonView = new BlockButtonView(editor.locale);\n        const iconFromConfig = this._blockToolbarConfig.icon;\n        const icon = NESTED_TOOLBAR_ICONS[iconFromConfig] || iconFromConfig || NESTED_TOOLBAR_ICONS.dragIndicator;\n        buttonView.set({\n            label: t('Edit block'),\n            icon,\n            withText: false\n        });\n        // Bind the panelView observable properties to the buttonView.\n        buttonView.bind('isOn').to(this.panelView, 'isVisible');\n        buttonView.bind('tooltip').to(this.panelView, 'isVisible', (isVisible)=>!isVisible);\n        // Toggle the panelView upon buttonView#execute.\n        this.listenTo(buttonView, 'execute', ()=>{\n            if (!this.panelView.isVisible) {\n                this._showPanel();\n            } else {\n                this._hidePanel(true);\n            }\n        });\n        // Hide the panelView when the buttonView is disabled. `isEnabled` flag might be changed when\n        // user scrolls the viewport and the button is no longer visible. In such case, the panel should be hidden\n        // otherwise it will be displayed in the wrong place.\n        this.listenTo(buttonView, 'change:isEnabled', (evt, name, isEnabled)=>{\n            if (!isEnabled && this.panelView.isVisible) {\n                this._hidePanel(false);\n            }\n        });\n        editor.ui.view.body.add(buttonView);\n        return buttonView;\n    }\n    /**\n\t * Shows or hides the button.\n\t * When all the conditions for displaying the button are matched, it shows the button. Hides otherwise.\n\t */ _updateButton() {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        // Hides the button when the editor is not focused.\n        if (!editor.ui.focusTracker.isFocused) {\n            this._hideButton();\n            return;\n        }\n        // Hides the button when the selection is in non-editable place.\n        if (!editor.model.canEditAt(editor.model.document.selection)) {\n            this._hideButton();\n            return;\n        }\n        // Get the first selected block, button will be attached to this element.\n        const modelTarget = Array.from(model.document.selection.getSelectedBlocks())[0];\n        // Hides the button when there is no enabled item in toolbar for the current block element.\n        if (!modelTarget || Array.from(this.toolbarView.items).every((item)=>!item.isEnabled)) {\n            this._hideButton();\n            return;\n        }\n        // Get DOM target element.\n        const domTarget = view.domConverter.mapViewToDom(editor.editing.mapper.toViewElement(modelTarget));\n        // Show block button.\n        this.buttonView.isVisible = true;\n        // Make sure that the block toolbar panel is resized properly.\n        this._setupToolbarResize();\n        // Attach block button to target DOM element.\n        this._attachButtonToElement(domTarget);\n        // When panel is opened then refresh it position to be properly aligned with block button.\n        if (this.panelView.isVisible) {\n            this._showPanel();\n        }\n    }\n    /**\n\t * Hides the button.\n\t */ _hideButton() {\n        this.buttonView.isVisible = false;\n    }\n    /**\n\t * Shows the {@link #toolbarView} attached to the {@link #buttonView}.\n\t * If the toolbar is already visible, then it simply repositions it.\n\t */ _showPanel() {\n        // Usually, the only way to show the toolbar is by pressing the block button. It makes it impossible for\n        // the toolbar to show up when the button is invisible (feature does not make sense for the selection then).\n        // The toolbar navigation using Alt+F10 does not access the button but shows the panel directly using this method.\n        // So we need to check whether this is possible first.\n        if (!this.buttonView.isVisible) {\n            return;\n        }\n        const wasVisible = this.panelView.isVisible;\n        // So here's the thing: If there was no initial panelView#show() or these two were in different order, the toolbar\n        // positioning will break in RTL editors. Weird, right? What you show know is that the toolbar\n        // grouping works thanks to:\n        //\n        // * the ResizeObserver, which kicks in as soon as the toolbar shows up in DOM (becomes visible again).\n        // * the observable ToolbarView#maxWidth, which triggers re-grouping when changed.\n        //\n        // Here are the possible scenarios:\n        //\n        // 1. (WRONG ❌) If the #maxWidth is set when the toolbar is invisible, it won't affect item grouping (no DOMRects, no grouping).\n        //    Then, when panelView.pin() is called, the position of the toolbar will be calculated for the old\n        //    items grouping state, and when finally ResizeObserver kicks in (hey, the toolbar is visible now, right?)\n        //    it will group/ungroup some items and the length of the toolbar will change. But since in RTL the toolbar\n        //    is attached on the right side and the positioning uses CSS \"left\", it will result in the toolbar shifting\n        //    to the left and being displayed in the wrong place.\n        // 2. (WRONG ❌) If the panelView.pin() is called first and #maxWidth set next, then basically the story repeats. The balloon\n        //    calculates the position for the old toolbar grouping state, then the toolbar re-groups items and because\n        //    it is positioned using CSS \"left\" it will move.\n        // 3. (RIGHT ✅) We show the panel first (the toolbar does re-grouping but it does not matter), then the #maxWidth\n        //    is set allowing the toolbar to re-group again and finally panelView.pin() does the positioning when the\n        //    items grouping state is stable and final.\n        //\n        // https://github.com/ckeditor/ckeditor5/issues/6449, https://github.com/ckeditor/ckeditor5/issues/6575\n        this.panelView.show();\n        const editableElement = this._getSelectedEditableElement();\n        this.toolbarView.maxWidth = this._getToolbarMaxWidth(editableElement);\n        this.panelView.pin({\n            target: this.buttonView.element,\n            limiter: editableElement\n        });\n        if (!wasVisible) {\n            this.toolbarView.items.get(0).focus();\n        }\n    }\n    /**\n\t * Returns currently selected editable, based on the model selection.\n\t */ _getSelectedEditableElement() {\n        const selectedModelRootName = this.editor.model.document.selection.getFirstRange().root.rootName;\n        return this.editor.ui.getEditableElement(selectedModelRootName);\n    }\n    /**\n\t * Hides the {@link #toolbarView}.\n\t *\n\t * @param focusEditable When `true`, the editable will be focused after hiding the panel.\n\t */ _hidePanel(focusEditable) {\n        this.panelView.isVisible = false;\n        if (focusEditable) {\n            this.editor.editing.view.focus();\n        }\n    }\n    /**\n\t * Repositions the button on scroll.\n\t */ _repositionButtonOnScroll() {\n        const { buttonView } = this;\n        let pendingAnimationFrame = false;\n        // Reposition the button on scroll, but do it only once per animation frame to avoid performance issues.\n        const repositionOnScroll = (evt, domEvt)=>{\n            if (pendingAnimationFrame) {\n                return;\n            }\n            // It makes no sense to reposition the button when the user scrolls the dropdown or any other\n            // nested scrollable element. The button should be repositioned only when the user scrolls the\n            // editable or any other scrollable parent of the editable. Leaving it as it is buggy on Chrome\n            // where scrolling nested scrollables is not properly handled.\n            // See more: https://github.com/ckeditor/ckeditor5/issues/17067\n            const editableElement = this._getSelectedEditableElement();\n            if (domEvt.target !== global.document && !getAncestors(editableElement).includes(domEvt.target)) {\n                return;\n            }\n            pendingAnimationFrame = true;\n            global.window.requestAnimationFrame(()=>{\n                this._updateButton();\n                pendingAnimationFrame = false;\n            });\n        };\n        // Watch scroll event only when the button is visible, it prevents attaching the scroll event listener\n        // to the document when the button is not visible.\n        buttonView.on('change:isVisible', (evt, name, isVisible)=>{\n            if (isVisible) {\n                buttonView.listenTo(global.document, 'scroll', repositionOnScroll, {\n                    useCapture: true,\n                    usePassive: true\n                });\n            } else {\n                buttonView.stopListening(global.document, 'scroll', repositionOnScroll);\n            }\n        });\n    }\n    /**\n\t * Attaches the {@link #buttonView} to the target block of content.\n\t *\n\t * @param targetElement Target element.\n\t */ _attachButtonToElement(targetElement) {\n        const buttonElement = this.buttonView.element;\n        const editableElement = this._getSelectedEditableElement();\n        const contentStyles = window.getComputedStyle(targetElement);\n        const editableRect = new Rect(editableElement);\n        const contentPaddingTop = parseInt(contentStyles.paddingTop, 10);\n        // When line height is not an integer then treat it as \"normal\".\n        // MDN says that 'normal' == ~1.2 on desktop browsers.\n        const contentLineHeight = parseInt(contentStyles.lineHeight, 10) || parseInt(contentStyles.fontSize, 10) * 1.2;\n        const buttonRect = new Rect(buttonElement);\n        const contentRect = new Rect(targetElement);\n        let positionLeft;\n        if (this.editor.locale.uiLanguageDirection === 'ltr') {\n            positionLeft = editableRect.left - buttonRect.width;\n        } else {\n            positionLeft = editableRect.right;\n        }\n        const positionTop = contentRect.top + contentPaddingTop + (contentLineHeight - buttonRect.height) / 2;\n        buttonRect.moveTo(positionLeft, positionTop);\n        const absoluteButtonRect = buttonRect.toAbsoluteRect();\n        this.buttonView.top = absoluteButtonRect.top;\n        this.buttonView.left = absoluteButtonRect.left;\n        this._clipButtonToViewport(this.buttonView, editableElement);\n    }\n    /**\n\t * Clips the button element to the viewport of the editable element.\n\t *\n\t * \t* If the button overflows the editable viewport, it is clipped to make it look like it's cut off by the editable scrollable region.\n\t * \t* If the button is fully hidden by the top of the editable, it is not clickable but still visible in the DOM.\n\t *\n\t * @param buttonView The button view to clip.\n\t * @param editableElement The editable element whose viewport is used for clipping.\n\t */ _clipButtonToViewport(buttonView, editableElement) {\n        const absoluteButtonRect = new Rect(buttonView.element);\n        const scrollViewportRect = new Rect(editableElement).getVisible();\n        // Sets polygon clip path for the button element, if there is no argument provided, the clip path is removed.\n        const setButtonClipping = (...paths)=>{\n            buttonView.element.style.clipPath = paths.length ? `polygon(${paths.join(',')})` : '';\n        };\n        // Hide the button if it's fully hidden by the top of the editable.\n        // Note that the button is still visible in the DOM, but it's not clickable. It's because we don't\n        // want to hide the button completely, as there are plenty of `isVisible` watchers which toggles\n        // the button scroll listeners.\n        const markAsHidden = (isHidden)=>{\n            buttonView.isEnabled = !isHidden;\n            buttonView.element.style.pointerEvents = isHidden ? 'none' : '';\n        };\n        if (scrollViewportRect && scrollViewportRect.bottom < absoluteButtonRect.bottom) {\n            // Calculate the delta between the button bottom and the editable bottom, and clip the button\n            // to make it look like it's cut off by the editable scrollable region.\n            const delta = Math.min(absoluteButtonRect.height, absoluteButtonRect.bottom - scrollViewportRect.bottom);\n            markAsHidden(delta >= absoluteButtonRect.height);\n            setButtonClipping('0 0', '100% 0', `100% calc(100% - ${toPx(delta)})`, `0 calc(100% - ${toPx(delta)}`);\n        } else if (scrollViewportRect && scrollViewportRect.top > absoluteButtonRect.top) {\n            // Calculate the delta between the button top and the editable top, and clip the button\n            // to make it look like it's cut off by the editable scrollable region.\n            const delta = Math.min(absoluteButtonRect.height, scrollViewportRect.top - absoluteButtonRect.top);\n            markAsHidden(delta >= absoluteButtonRect.height);\n            setButtonClipping(`0 ${toPx(delta)}`, `100% ${toPx(delta)}`, '100% 100%', '0 100%');\n        } else {\n            // Reset the clip path if button is fully visible.\n            markAsHidden(false);\n            setButtonClipping();\n        }\n    }\n    /**\n\t * Creates a resize observer that observes selected editable and resizes the toolbar panel accordingly.\n\t */ _setupToolbarResize() {\n        const editableElement = this._getSelectedEditableElement();\n        // Do this only if the automatic grouping is turned on.\n        if (!this._blockToolbarConfig.shouldNotGroupWhenFull) {\n            // If resize observer is attached to a different editable than currently selected editable, re-attach it.\n            if (this._resizeObserver && this._resizeObserver.element !== editableElement) {\n                this._resizeObserver.destroy();\n                this._resizeObserver = null;\n            }\n            if (!this._resizeObserver) {\n                this._resizeObserver = new ResizeObserver(editableElement, ()=>{\n                    this.toolbarView.maxWidth = this._getToolbarMaxWidth(editableElement);\n                });\n            }\n        }\n    }\n    /**\n\t * Gets the {@link #toolbarView} max-width, based on given `editableElement` width plus the distance between the farthest\n\t * edge of the {@link #buttonView} and the editable.\n\t *\n\t * @returns A maximum width that toolbar can have, in pixels.\n\t */ _getToolbarMaxWidth(editableElement) {\n        const editableRect = new Rect(editableElement);\n        const buttonRect = new Rect(this.buttonView.element);\n        const isRTL = this.editor.locale.uiLanguageDirection === 'rtl';\n        const offset = isRTL ? buttonRect.left - editableRect.right + buttonRect.width : editableRect.left - buttonRect.left;\n        return toPx(editableRect.width + offset);\n    }\n}\n\n/**\n * A menu {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#buttonView} class. Buttons like this one\n * open both top-level bar menus as well as sub-menus.\n */ class MenuBarMenuButtonView extends ListItemButtonView {\n    /**\n\t * An icon that displays an arrow to indicate a direction of the menu.\n\t */ arrowView;\n    /**\n\t * Creates an instance of the menu bar button view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set({\n            withText: true,\n            role: 'menuitem'\n        });\n        this.arrowView = this._createArrowView();\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-menu-bar__menu__button'\n                ],\n                'aria-haspopup': true,\n                'aria-expanded': this.bindTemplate.to('isOn', (value)=>String(value)),\n                'data-cke-tooltip-disabled': bind.to('isOn')\n            },\n            on: {\n                'mouseenter': bind.to('mouseenter')\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.children.add(this.arrowView);\n    }\n    /**\n\t * Creates the {@link #arrowView} instance.\n\t */ _createArrowView() {\n        const arrowView = new IconView();\n        arrowView.content = dropdownArrowIcon;\n        arrowView.extendTemplate({\n            attributes: {\n                class: 'ck-menu-bar__menu__button__arrow'\n            }\n        });\n        return arrowView;\n    }\n}\n\n/**\n * A view representing a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#panelView} of a menu.\n */ class MenuBarMenuPanelView extends View {\n    /**\n\t * Collection of the child views in this panel.\n\t */ children;\n    /**\n\t * Creates an instance of the menu panel view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('isVisible', false);\n        this.set('position', 'se');\n        this.children = this.createCollection();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-reset',\n                    'ck-menu-bar__menu__panel',\n                    bind.to('position', (value)=>`ck-menu-bar__menu__panel_position_${value}`),\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ],\n                tabindex: '-1'\n            },\n            children: this.children,\n            on: {\n                // Drag and drop in the panel should not break the selection in the editor.\n                // https://github.com/ckeditor/ckeditor5-ui/issues/228\n                selectstart: bind.to((evt)=>{\n                    if (evt.target.tagName.toLocaleLowerCase() === 'input') {\n                        return;\n                    }\n                    evt.preventDefault();\n                })\n            }\n        });\n    }\n    /**\n\t * Focuses the first child of the panel (default) or the last one if the `direction` is `-1`.\n\t */ focus(direction = 1) {\n        if (this.children.length) {\n            if (direction === 1) {\n                this.children.first.focus();\n            } else {\n                this.children.last.focus();\n            }\n        }\n    }\n}\n\n/**\n * A menu view for the {@link module:ui/menubar/menubarview~MenuBarView}. Menus are building blocks of the menu bar,\n * they host other sub-menus and menu items (buttons) that users can interact with.\n */ class MenuBarMenuView extends View {\n    /**\n\t * Button of the menu view.\n\t */ buttonView;\n    /**\n\t * Panel of the menu. It hosts children of the menu.\n\t */ panelView;\n    /**\n\t * Tracks information about the DOM focus in the menu.\n\t */ focusTracker;\n    /**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the menu.\n\t */ keystrokes;\n    /**\n\t * Creates an instance of the menu view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.buttonView = new MenuBarMenuButtonView(locale);\n        this.buttonView.delegate('mouseenter').to(this);\n        this.buttonView.bind('isOn', 'isEnabled').to(this, 'isOpen', 'isEnabled');\n        this.panelView = new MenuBarMenuPanelView(locale);\n        this.panelView.bind('isVisible').to(this, 'isOpen');\n        this.keystrokes = new KeystrokeHandler();\n        this.focusTracker = new FocusTracker();\n        this.set('isOpen', false);\n        this.set('isEnabled', true);\n        this.set('panelPosition', 'w');\n        this.set('class', undefined);\n        this.set('parentMenuView', null);\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-menu-bar__menu',\n                    bind.to('class'),\n                    bind.if('isEnabled', 'ck-disabled', (value)=>!value),\n                    bind.if('parentMenuView', 'ck-menu-bar__menu_top-level', (value)=>!value)\n                ]\n            },\n            children: [\n                this.buttonView,\n                this.panelView\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.focusTracker.add(this.buttonView.element);\n        this.focusTracker.add(this.panelView.element);\n        // Listen for keystrokes coming from within #element.\n        this.keystrokes.listenTo(this.element);\n        MenuBarMenuBehaviors.closeOnEscKey(this);\n        this._repositionPanelOnOpen();\n    }\n    // For now, this method cannot be called in the render process because the `parentMenuView` may be assigned\n    // after the rendering process.\n    //\n    // TODO: We should reconsider the way we handle this logic.\n    /**\n\t * Attach all keyboard behaviors for the menu bar view.\n\t *\n\t * @internal\n\t */ _attachBehaviors() {\n        // Top-level menus.\n        if (!this.parentMenuView) {\n            this._propagateArrowKeystrokeEvents();\n            MenuBarMenuBehaviors.openAndFocusPanelOnArrowDownKey(this);\n            MenuBarMenuBehaviors.toggleOnButtonClick(this);\n        } else {\n            MenuBarMenuBehaviors.openOnButtonClick(this);\n            MenuBarMenuBehaviors.openOnArrowRightKey(this);\n            MenuBarMenuBehaviors.closeOnArrowLeftKey(this);\n            MenuBarMenuBehaviors.openAndFocusOnEnterKeyPress(this);\n            MenuBarMenuBehaviors.closeOnParentClose(this);\n        }\n    }\n    /**\n\t * Fires `arrowright` and `arrowleft` events when the user pressed corresponding arrow keys.\n\t */ _propagateArrowKeystrokeEvents() {\n        this.keystrokes.set('arrowright', (data, cancel)=>{\n            this.fire('arrowright');\n            cancel();\n        });\n        this.keystrokes.set('arrowleft', (data, cancel)=>{\n            this.fire('arrowleft');\n            cancel();\n        });\n    }\n    /**\n\t * Sets the position of the panel when the menu opens. The panel is positioned\n\t * so that it optimally uses the available space in the viewport.\n\t */ _repositionPanelOnOpen() {\n        // Let the menu control the position of the panel. The position must be updated every time the menu is open.\n        this.on('change:isOpen', (evt, name, isOpen)=>{\n            if (!isOpen) {\n                return;\n            }\n            const optimalPanelPosition = MenuBarMenuView._getOptimalPosition({\n                element: this.panelView.element,\n                target: this.buttonView.element,\n                fitInViewport: true,\n                positions: this._panelPositions\n            });\n            this.panelView.position = optimalPanelPosition ? optimalPanelPosition.name : this._panelPositions[0].name;\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ focus() {\n        this.buttonView.focus();\n    }\n    /**\n\t * Positioning functions for the {@link #panelView} . They change depending on the role of the menu (top-level vs sub-menu) in\n\t * the {@link module:ui/menubar/menubarview~MenuBarView menu bar} and the UI language direction.\n\t */ get _panelPositions() {\n        const { southEast, southWest, northEast, northWest, westSouth, eastSouth, westNorth, eastNorth } = MenuBarMenuViewPanelPositioningFunctions;\n        if (this.locale.uiLanguageDirection === 'ltr') {\n            if (this.parentMenuView) {\n                return [\n                    eastSouth,\n                    eastNorth,\n                    westSouth,\n                    westNorth\n                ];\n            } else {\n                return [\n                    southEast,\n                    southWest,\n                    northEast,\n                    northWest\n                ];\n            }\n        } else {\n            if (this.parentMenuView) {\n                return [\n                    westSouth,\n                    westNorth,\n                    eastSouth,\n                    eastNorth\n                ];\n            } else {\n                return [\n                    southWest,\n                    southEast,\n                    northWest,\n                    northEast\n                ];\n            }\n        }\n    }\n    /**\n\t * A function used to calculate the optimal position for the dropdown panel.\n\t *\n\t * Referenced for unit testing purposes.\n\t */ static _getOptimalPosition = getOptimalPosition;\n}\n\n/**\n * A list of menu bar items, a child of {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#panelView}.\n *\n * Use this class to create a list of items (options, buttons) to be displayed in a menu bar.\n *\n * To populate this list, use {@link module:ui/menubar/menubarmenulistitemview~MenuBarMenuListItemView} instances.\n */ class MenuBarMenuListView extends ListView {\n    /**\n\t * Creates an instance of the list view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        this.role = 'menu';\n        this.items.on('change', this._setItemsCheckSpace.bind(this));\n    }\n    /**\n\t * This method adds empty space if there is any toggleable item in the list.\n\t * It makes the list properly aligned.\n\t */ _setItemsCheckSpace() {\n        const hasAnyToggleableItem = Array.from(this.items).some((item)=>{\n            const listButtonView = pickListButtonMenuViewIfPresent(item);\n            return listButtonView && listButtonView.isToggleable;\n        });\n        this.items.forEach((item)=>{\n            const listButtonView = pickListButtonMenuViewIfPresent(item);\n            if (listButtonView) {\n                listButtonView.hasCheckSpace = hasAnyToggleableItem;\n            }\n        });\n    }\n}\n/**\n * Picks the first button menu view from the given item if present.\n *\n * @param item The item to check for a button menu view.\n * @returns The first button menu view found in the item, or `null` if not found.\n */ function pickListButtonMenuViewIfPresent(item) {\n    if (!(item instanceof ListItemView)) {\n        return null;\n    }\n    return item.children.map((child)=>isNestedMenuLikeView(child) ? child.buttonView : child).find((item)=>item instanceof ListItemButtonView);\n}\n/**\n * Checks if the given item is a nested menu-like view. `MenuBarMenuView` imports this file\n * so to avoid circular dependencies, this function is defined in more generic way.\n *\n * @param item The item to check.\n * @returns `true` if the item is a nested menu-like view, `false` otherwise.\n */ function isNestedMenuLikeView(item) {\n    return typeof item === 'object' && 'buttonView' in item && item.buttonView instanceof ButtonView;\n}\n\n/**\n * A menu bar list file dialog button view. Buttons like this one execute user actions.\n *\n * This component provides a button that opens the native file selection dialog.\n */ class MenuBarMenuListItemFileDialogButtonView extends FileDialogListItemButtonView {\n    /**\n\t * Creates an instance of the menu bar list button view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        this.set({\n            withText: true,\n            withKeystroke: true,\n            tooltip: false,\n            role: 'menuitem'\n        });\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-menu-bar__menu__item__button'\n                ]\n            }\n        });\n    }\n}\n\nconst EVENT_NAME_DELEGATES = [\n    'mouseenter',\n    'arrowleft',\n    'arrowright',\n    'change:isOpen'\n];\n/**\n * The application menu bar component. It brings a set of top-level menus (and sub-menus) that can be used\n * to organize and access a large number of buttons.\n */ class MenuBarView extends View {\n    /**\n\t * Collection of the child views inside the {@link #element}.\n\t */ children;\n    /**\n\t * A list of {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} instances registered in the menu bar.\n\t *\n\t * @observable\n\t */ menus = [];\n    /**\n\t * Creates an instance of the menu bar view.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        const t = locale.t;\n        const bind = this.bindTemplate;\n        this.set({\n            isOpen: false,\n            isFocusBorderEnabled: false\n        });\n        this._setupIsOpenUpdater();\n        this.children = this.createCollection();\n        // @if CK_DEBUG_MENU_BAR // // Logs events in the main event bus of the component.\n        // @if CK_DEBUG_MENU_BAR // this.on( 'menu', ( evt, data ) => {\n        // @if CK_DEBUG_MENU_BAR // \tconsole.log( `MenuBarView:${ evt.name }`, evt.path.map( view => view.element ) );\n        // @if CK_DEBUG_MENU_BAR // } );\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-menu-bar',\n                    bind.if('isFocusBorderEnabled', 'ck-menu-bar_focus-border-enabled')\n                ],\n                'aria-label': t('Editor menu bar'),\n                role: 'menubar'\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * A utility that expands a plain menu bar configuration into a structure of menus (also: sub-menus)\n\t * and items using a given {@link module:ui/componentfactory~ComponentFactory component factory}.\n\t *\n\t * See the {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar} in the editor\n\t * configuration reference to learn how to configure the menu bar.\n\t */ fillFromConfig(config, componentFactory, extraItems = []) {\n        const locale = this.locale;\n        const processedConfig = processMenuBarConfig({\n            normalizedConfig: config,\n            locale,\n            componentFactory,\n            extraItems\n        });\n        const topLevelCategoryMenuViews = processedConfig.items.map((menuDefinition)=>this._createMenu({\n                componentFactory,\n                menuDefinition\n            }));\n        this.children.addMany(topLevelCategoryMenuViews);\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        MenuBarBehaviors.toggleMenusAndFocusItemsOnHover(this);\n        MenuBarBehaviors.closeMenusWhenTheBarCloses(this);\n        MenuBarBehaviors.closeMenuWhenAnotherOnTheSameLevelOpens(this);\n        MenuBarBehaviors.focusCycleMenusOnArrows(this);\n        MenuBarBehaviors.closeOnClickOutside(this);\n        MenuBarBehaviors.enableFocusHighlightOnInteraction(this);\n    }\n    /**\n\t * Focuses the menu bar.\n\t */ focus() {\n        if (this.children.first) {\n            this.children.first.focus();\n        }\n    }\n    /**\n\t * Closes all menus in the bar.\n\t */ close() {\n        for (const topLevelCategoryMenuView of this.children){\n            topLevelCategoryMenuView.isOpen = false;\n        }\n    }\n    /**\n\t * Registers a menu view in the menu bar. Every {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} instance must be registered\n\t * in the menu bar to be properly managed.\n\t */ registerMenu(menuView, parentMenuView = null) {\n        if (parentMenuView) {\n            menuView.delegate(...EVENT_NAME_DELEGATES).to(parentMenuView);\n            menuView.parentMenuView = parentMenuView;\n        } else {\n            menuView.delegate(...EVENT_NAME_DELEGATES).to(this, (name)=>'menu:' + name);\n        }\n        menuView._attachBehaviors();\n        this.menus.push(menuView);\n    }\n    /**\n\t * Creates a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} based on the given definition.\n\t */ _createMenu({ componentFactory, menuDefinition, parentMenuView }) {\n        const locale = this.locale;\n        const menuView = new MenuBarMenuView(locale);\n        this.registerMenu(menuView, parentMenuView);\n        menuView.buttonView.set({\n            label: menuDefinition.label\n        });\n        // Defer the creation of the menu structure until it gets open. This is a performance optimization\n        // that shortens the time needed to create the editor.\n        menuView.once('change:isOpen', ()=>{\n            const listView = new MenuBarMenuListView(locale);\n            listView.ariaLabel = menuDefinition.label;\n            menuView.panelView.children.add(listView);\n            listView.items.addMany(this._createMenuItems({\n                menuDefinition,\n                parentMenuView: menuView,\n                componentFactory\n            }));\n        });\n        return menuView;\n    }\n    /**\n\t * Creates a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} items based on the given definition.\n\t */ _createMenuItems({ menuDefinition, parentMenuView, componentFactory }) {\n        const locale = this.locale;\n        const items = [];\n        for (const menuGroupDefinition of menuDefinition.groups){\n            for (const itemDefinition of menuGroupDefinition.items){\n                const menuItemView = new MenuBarMenuListItemView(locale, parentMenuView);\n                if (isObject(itemDefinition)) {\n                    menuItemView.children.add(this._createMenu({\n                        componentFactory,\n                        menuDefinition: itemDefinition,\n                        parentMenuView\n                    }));\n                } else {\n                    const componentView = this._createMenuItemContentFromFactory({\n                        componentName: itemDefinition,\n                        componentFactory,\n                        parentMenuView\n                    });\n                    if (!componentView) {\n                        continue;\n                    }\n                    menuItemView.children.add(componentView);\n                }\n                items.push(menuItemView);\n            }\n            // Separate groups with a separator.\n            if (menuGroupDefinition !== menuDefinition.groups[menuDefinition.groups.length - 1]) {\n                items.push(new ListSeparatorView(locale));\n            }\n        }\n        return items;\n    }\n    /**\n\t * Uses the component factory to create a content of the menu item (a button or a sub-menu).\n\t */ _createMenuItemContentFromFactory({ componentName, parentMenuView, componentFactory }) {\n        const componentView = componentFactory.create(componentName);\n        if (!(componentView instanceof MenuBarMenuView || componentView instanceof MenuBarMenuListItemButtonView || componentView instanceof MenuBarMenuListItemFileDialogButtonView)) {\n            /**\n\t\t\t * Adding unsupported components to the {@link module:ui/menubar/menubarview~MenuBarView} is not possible.\n\t\t\t *\n\t\t\t * A component should be either a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} (sub-menu) or a\n\t\t\t * {@link module:ui/menubar/menubarmenulistitembuttonview~MenuBarMenuListItemButtonView} (button).\n\t\t\t *\n\t\t\t * @error menu-bar-component-unsupported\n\t\t\t * @param componentName A name of the unsupported component used in the configuration.\n\t\t\t * @param componentView An unsupported component view.\n\t\t\t */ logWarning('menu-bar-component-unsupported', {\n                componentName,\n                componentView\n            });\n            return null;\n        }\n        this._registerMenuTree(componentView, parentMenuView);\n        // Close the whole menu bar when a component is executed.\n        componentView.on('execute', ()=>{\n            this.close();\n        });\n        return componentView;\n    }\n    /**\n\t * Checks component and its children recursively and calls {@link #registerMenu}\n\t * for each item that is {@link module:ui/menubar/menubarmenuview~MenuBarMenuView}.\n\t *\n\t * @internal\n\t */ _registerMenuTree(componentView, parentMenuView) {\n        if (!(componentView instanceof MenuBarMenuView)) {\n            componentView.delegate('mouseenter').to(parentMenuView);\n            return;\n        }\n        this.registerMenu(componentView, parentMenuView);\n        const menuBarItemsList = componentView.panelView.children.filter((child)=>child instanceof MenuBarMenuListView)[0];\n        if (!menuBarItemsList) {\n            componentView.delegate('mouseenter').to(parentMenuView);\n            return;\n        }\n        const nonSeparatorItems = menuBarItemsList.items.filter((item)=>item instanceof ListItemView);\n        for (const item of nonSeparatorItems){\n            this._registerMenuTree(item.children.get(0), componentView);\n        }\n    }\n    /**\n\t * Manages the state of the {@link #isOpen} property of the menu bar. Because the state is a sum of individual\n\t * top-level menus' states, it's necessary to listen to their changes and update the state accordingly.\n\t *\n\t * Additionally, it prevents from unnecessary changes of `isOpen` when one top-level menu opens and another closes\n\t * (regardless of in which order), maintaining a stable `isOpen === true` in that situation.\n\t */ _setupIsOpenUpdater() {\n        let closeTimeout;\n        // TODO: This is not the prettiest approach but at least it's simple.\n        this.on('menu:change:isOpen', (evt, name, isOpen)=>{\n            clearTimeout(closeTimeout);\n            if (isOpen) {\n                this.isOpen = true;\n            } else {\n                closeTimeout = setTimeout(()=>{\n                    this.isOpen = Array.from(this.children).some((menuView)=>menuView.isOpen);\n                }, 0);\n            }\n        });\n    }\n}\n\nexport { AccessibilityHelp, AutocompleteView, BalloonPanelView, BalloonToolbar, BlockToolbar, BodyCollection, BoxedEditorUIView, ButtonLabelView, ButtonLabelWithHighlightView, ButtonView, CollapsibleView, ColorGridView, ColorPickerView, ColorSelectorView, ColorTileView, ComponentFactory, ContextualBalloon, CssTransitionDisablerMixin, DefaultMenuBarItems, Dialog, DialogView, DialogViewPosition, DropdownButtonView, DropdownMenuListItemButtonView, DropdownMenuListItemView, DropdownMenuListView, DropdownMenuNestedMenuView, DropdownMenuPanelPositioningFunctions, DropdownMenuRootListView, DropdownPanelView, DropdownView, EditorUI, EditorUIView, FileDialogButtonView, FileDialogListItemButtonView, FocusCycler, FormHeaderView, HighlightedTextView, IconView, IframeView, InlineEditableUIView, InputNumberView, InputTextView, InputView, LabelView, LabelWithHighlightView, LabeledFieldView, ListItemButtonView, ListItemGroupView, ListItemView, ListSeparatorView, ListView, MenuBarMenuListItemButtonView, MenuBarMenuListItemFileDialogButtonView, MenuBarMenuListItemView, MenuBarMenuListView, MenuBarMenuView, MenuBarView, Notification, SearchInfoView, SearchTextView, SpinnerView, SplitButtonView, StickyPanelView, SwitchButtonView, Template, TextareaView, ToolbarLineBreakView, ToolbarSeparatorView, ToolbarView, TooltipManager, View, ViewCollection, Model as ViewModel, addKeyboardHandlingForGrid, addListToDropdown, addMenuToDropdown, addToolbarToDropdown, clickOutsideHandler, createDropdown, createLabeledDropdown, createLabeledInputNumber, createLabeledInputText, createLabeledTextarea, filterGroupAndItemNames, focusChildOnDropdownOpen, getLocalizedColorOptions, injectCssTransitionDisabler, isFocusable, isViewWithFocusCycler, normalizeColorOptions, normalizeMenuBarConfig, normalizeSingleColorDefinition, normalizeToolbarConfig, submitHandler };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/viewcollection\n */\n\nimport {\n\tCKEditorError,\n\tCollection,\n\ttype CollectionAddEvent,\n\ttype CollectionRemoveEvent,\n\ttype EmitterMixinDelegateChain\n} from '@ckeditor/ckeditor5-utils';\n\nimport type View from './view.js';\n\n/**\n * Collects {@link module:ui/view~View} instances.\n *\n * ```ts\n * const parentView = new ParentView( locale );\n * const collection = new ViewCollection( locale );\n *\n * collection.setParent( parentView.element );\n *\n * const viewA = new ChildView( locale );\n * const viewB = new ChildView( locale );\n * ```\n *\n * View collection renders and manages view {@link module:ui/view~View#element elements}:\n *\n * ```ts\n * collection.add( viewA );\n * collection.add( viewB );\n *\n * console.log( parentView.element.firsChild ); // -> viewA.element\n * console.log( parentView.element.lastChild ); // -> viewB.element\n * ```\n *\n * It {@link module:ui/viewcollection~ViewCollection#delegate propagates} DOM events too:\n *\n * ```ts\n * // Delegate #click and #keydown events from viewA and viewB to the parentView.\n * collection.delegate( 'click' ).to( parentView );\n *\n * parentView.on( 'click', ( evt ) => {\n * \tconsole.log( `${ evt.source } has been clicked.` );\n * } );\n *\n * // This event will be delegated to the parentView.\n * viewB.fire( 'click' );\n * ```\n *\n * **Note**: A view collection can be used directly in the {@link module:ui/template~TemplateDefinition definition}\n * of a {@link module:ui/template~Template template}.\n */\nexport default class ViewCollection<TView extends View = View> extends Collection<TView> {\n\tpublic declare id?: string;\n\n\t/**\n\t * A parent element within which child views are rendered and managed in DOM.\n\t */\n\tprivate _parentElement: DocumentFragment | HTMLElement | null;\n\n\t/**\n\t * Creates a new instance of the {@link module:ui/viewcollection~ViewCollection}.\n\t *\n\t * @param initialItems The initial items of the collection.\n\t */\n\tconstructor( initialItems: Iterable<TView> = [] ) {\n\t\tsuper( initialItems, {\n\t\t\t// An #id Number attribute should be legal and not break the `ViewCollection` instance.\n\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/93\n\t\t\tidProperty: 'viewUid'\n\t\t} );\n\n\t\t// Handle {@link module:ui/view~View#element} in DOM when a new view is added to the collection.\n\t\tthis.on<CollectionAddEvent<TView>>( 'add', ( evt, view, index ) => {\n\t\t\tthis._renderViewIntoCollectionParent( view, index );\n\t\t} );\n\n\t\t// Handle {@link module:ui/view~View#element} in DOM when a view is removed from the collection.\n\t\tthis.on<CollectionRemoveEvent<TView>>( 'remove', ( evt, view ) => {\n\t\t\tif ( view.element && this._parentElement ) {\n\t\t\t\tview.element.remove();\n\t\t\t}\n\t\t} );\n\n\t\tthis._parentElement = null;\n\t}\n\n\t/**\n\t * Destroys the view collection along with child views.\n\t * See the view {@link module:ui/view~View#destroy} method.\n\t */\n\tpublic destroy(): void {\n\t\tthis.map( view => view.destroy() );\n\t}\n\n\t/**\n\t * Sets the parent HTML element of this collection. When parent is set, {@link #add adding} and\n\t * {@link #remove removing} views in the collection synchronizes their\n\t * {@link module:ui/view~View#element elements} in the parent element.\n\t *\n\t * @param element A new parent element.\n\t */\n\tpublic setParent( elementOrDocFragment: DocumentFragment | HTMLElement ): void {\n\t\tthis._parentElement = elementOrDocFragment;\n\n\t\t// Take care of the initial collection items passed to the constructor.\n\t\tfor ( const view of this ) {\n\t\t\tthis._renderViewIntoCollectionParent( view );\n\t\t}\n\t}\n\n\t/**\n\t * Delegates selected events coming from within views in the collection to any\n\t * {@link module:utils/emittermixin~Emitter}.\n\t *\n\t * For the following views and collection:\n\t *\n\t * ```ts\n\t * const viewA = new View();\n\t * const viewB = new View();\n\t * const viewC = new View();\n\t *\n\t * const views = parentView.createCollection();\n\t *\n\t * views.delegate( 'eventX' ).to( viewB );\n\t * views.delegate( 'eventX', 'eventY' ).to( viewC );\n\t *\n\t * views.add( viewA );\n\t * ```\n\t *\n\t * the `eventX` is delegated (fired by) `viewB` and `viewC` along with `customData`:\n\t *\n\t * ```ts\n\t * viewA.fire( 'eventX', customData );\n\t * ```\n\t *\n\t * and `eventY` is delegated (fired by) `viewC` along with `customData`:\n\t *\n\t * ```ts\n\t * viewA.fire( 'eventY', customData );\n\t * ```\n\t *\n\t * See {@link module:utils/emittermixin~Emitter#delegate}.\n\t *\n\t * @param events {@link module:ui/view~View} event names to be delegated to another\n\t * {@link module:utils/emittermixin~Emitter}.\n\t * @returns Object with `to` property, a function which accepts the destination\n\t * of {@link module:utils/emittermixin~Emitter#delegate delegated} events.\n\t */\n\tpublic override delegate( ...events: Array<string> ): EmitterMixinDelegateChain {\n\t\tif ( !events.length || !isStringArray( events ) ) {\n\t\t\t/**\n\t\t\t * All event names must be strings.\n\t\t\t *\n\t\t\t * @error ui-viewcollection-delegate-wrong-events\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-viewcollection-delegate-wrong-events',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tto: dest => {\n\t\t\t\t// Activate delegating on existing views in this collection.\n\t\t\t\tfor ( const view of this ) {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.delegate( evtName ).to( dest );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Activate delegating on future views in this collection.\n\t\t\t\tthis.on<CollectionAddEvent<View>>( 'add', ( evt, view ) => {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.delegate( evtName ).to( dest );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\t// Deactivate delegating when view is removed from this collection.\n\t\t\t\tthis.on<CollectionRemoveEvent<View>>( 'remove', ( evt, view ) => {\n\t\t\t\t\tfor ( const evtName of events ) {\n\t\t\t\t\t\tview.stopDelegating( evtName, dest );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * This method {@link module:ui/view~View#render renders} a new view added to the collection.\n\t *\n\t * If the {@link #_parentElement parent element} of the collection is set, this method also adds\n\t * the view's {@link module:ui/view~View#element} as a child of the parent in DOM at a specified index.\n\t *\n\t * **Note**: If index is not specified, the view's element is pushed as the last child\n\t * of the parent element.\n\t *\n\t * @param view A new view added to the collection.\n\t * @param index An index the view holds in the collection. When not specified,\n\t * the view is added at the end.\n\t */\n\tprivate _renderViewIntoCollectionParent( view: View, index?: number ): void {\n\t\tif ( !view.isRendered ) {\n\t\t\tview.render();\n\t\t}\n\n\t\tif ( view.element && this._parentElement ) {\n\t\t\tthis._parentElement.insertBefore( view.element, this._parentElement.children[ index! ] );\n\t\t}\n\t}\n\n\t/**\n\t * Removes a child view from the collection. If the {@link #setParent parent element} of the\n\t * collection has been set, the {@link module:ui/view~View#element element} of the view is also removed\n\t * in DOM, reflecting the order of the collection.\n\t *\n\t * See the {@link #add} method.\n\t *\n\t * @param subject The view to remove, its id or index in the collection.\n\t * @returns The removed view.\n\t */\n\tpublic override remove( subject: TView | number | string ): TView {\n\t\treturn super.remove( subject );\n\t}\n}\n\n/**\n * Check if all entries of the array are of `String` type.\n *\n * @param arr An array to be checked.\n */\nfunction isStringArray( arr: Array<unknown> ): arr is Array<string> {\n\treturn arr.every( a => typeof a == 'string' );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/template\n */\n\n/* global document */\n\nimport View from './view.js';\nimport ViewCollection from './viewcollection.js';\n\nimport {\n\tCKEditorError,\n\tEmitterMixin,\n\tisNode,\n\ttoArray,\n\ttype ArrayOrItem,\n\ttype Emitter,\n\ttype Observable,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport { isObject, cloneDeepWith } from 'lodash-es';\n\nconst xhtmlNs = 'http://www.w3.org/1999/xhtml';\n\n/**\n * A basic Template class. It renders a DOM HTML element or text from a\n * {@link module:ui/template~TemplateDefinition definition} and supports element attributes, children,\n * bindings to {@link module:utils/observablemixin~Observable observables} and DOM event propagation.\n *\n * A simple template can look like this:\n *\n * ```ts\n * const bind = Template.bind( observable, emitter );\n *\n * new Template( {\n * \ttag: 'p',\n * \tattributes: {\n * \t\tclass: 'foo',\n * \t\tstyle: {\n * \t\t\tbackgroundColor: 'yellow'\n * \t\t}\n * \t},\n * \ton: {\n * \t\tclick: bind.to( 'clicked' )\n * \t},\n * \tchildren: [\n * \t\t'A paragraph.'\n * \t]\n * } ).render();\n * ```\n *\n * and it will render the following HTML element:\n *\n * ```html\n * <p class=\"foo\" style=\"background-color: yellow;\">A paragraph.</p>\n * ```\n *\n * Additionally, the `observable` will always fire `clicked` upon clicking `<p>` in the DOM.\n *\n * See {@link module:ui/template~TemplateDefinition} to know more about templates and complex\n * template definitions.\n */\nexport default class Template extends /* #__PURE__ */ EmitterMixin() {\n\tpublic ns?: string;\n\n\t/**\n\t * The tag (`tagName`) of this template, e.g. `div`. It also indicates that the template\n\t * renders to an HTML element.\n\t */\n\tpublic tag?: string;\n\n\t/**\n\t * The text of the template. It also indicates that the template renders to a DOM text node.\n\t */\n\tpublic text?: Array<TemplateSimpleValue | TemplateBinding>;\n\n\t/**\n\t * The attributes of the template, e.g. `{ id: [ 'ck-id' ] }`, corresponding with\n\t * the attributes of an HTML element.\n\t *\n\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t */\n\tpublic attributes?: Record<string, AttributeValues>;\n\n\t/**\n\t * The children of the template. They can be either:\n\t * * independent instances of {@link ~Template} (sub–templates),\n\t * * native DOM Nodes.\n\t *\n\t * **Note**: This property only makes sense when {@link #tag} is defined.\n\t */\n\tpublic children?: Array<ViewCollection | View | Node | Template>;\n\n\t/**\n\t * The DOM event listeners of the template.\n\t */\n\tpublic eventListeners?: Record<string, Array<TemplateToBinding>>;\n\n\t/**\n\t * Indicates whether this particular Template instance has been\n\t * {@link #render rendered}.\n\t */\n\tprivate _isRendered: boolean;\n\n\t/**\n\t * The data used by the {@link #revert} method to restore a node to its original state.\n\t *\n\t * See: {@link #apply}.\n\t */\n\tprivate _revertData: RevertData | null;\n\n\t/**\n\t * Creates an instance of the {@link ~Template} class.\n\t *\n\t * @param def The definition of the template.\n\t */\n\tconstructor( def: TemplateDefinition ) {\n\t\tsuper();\n\n\t\tObject.assign( this, normalize( clone( def ) ) );\n\n\t\tthis._isRendered = false;\n\t\tthis._revertData = null;\n\t}\n\n\t/**\n\t * Renders a DOM Node (an HTML element or text) out of the template.\n\t *\n\t * ```ts\n\t * const domNode = new Template( { ... } ).render();\n\t * ```\n\t *\n\t * See: {@link #apply}.\n\t */\n\tpublic render(): HTMLElement | Text {\n\t\tconst node = this._renderNode( {\n\t\t\tintoFragment: true\n\t\t} as any );\n\n\t\tthis._isRendered = true;\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Applies the template to an existing DOM Node, either HTML element or text.\n\t *\n\t * **Note:** No new DOM nodes will be created. Applying extends:\n\t *\n\t * {@link module:ui/template~TemplateDefinition attributes},\n\t * {@link module:ui/template~TemplateDefinition event listeners}, and\n\t * `textContent` of {@link module:ui/template~TemplateDefinition children} only.\n\t *\n\t * **Note:** Existing `class` and `style` attributes are extended when a template\n\t * is applied to an HTML element, while other attributes and `textContent` are overridden.\n\t *\n\t * **Note:** The process of applying a template can be easily reverted using the\n\t * {@link module:ui/template~Template#revert} method.\n\t *\n\t * ```ts\n\t * const element = document.createElement( 'div' );\n\t * const observable = new Model( { divClass: 'my-div' } );\n\t * const emitter = Object.create( EmitterMixin );\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \tattributes: {\n\t * \t\tid: 'first-div',\n\t * \t\tclass: bind.to( 'divClass' )\n\t * \t},\n\t * \ton: {\n\t * \t\tclick: bind( 'elementClicked' ) // Will be fired by the observable.\n\t * \t},\n\t * \tchildren: [\n\t * \t\t'Div text.'\n\t * \t]\n\t * } ).apply( element );\n\t *\n\t * console.log( element.outerHTML ); // -> '<div id=\"first-div\" class=\"my-div\"></div>'\n\t * ```\n\t *\n\t * @see module:ui/template~Template#render\n\t * @see module:ui/template~Template#revert\n\t * @param node Root node for the template to apply.\n\t */\n\tpublic apply( node: HTMLElement | Text ): HTMLElement | Text {\n\t\tthis._revertData = getEmptyRevertData();\n\n\t\tthis._renderNode( {\n\t\t\tnode,\n\t\t\tintoFragment: false,\n\t\t\tisApplying: true,\n\t\t\trevertData: this._revertData\n\t\t} );\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Reverts a template {@link module:ui/template~Template#apply applied} to a DOM node.\n\t *\n\t * @param node The root node for the template to revert. In most of the cases, it is the\n\t * same node used by {@link module:ui/template~Template#apply}.\n\t */\n\tpublic revert( node: HTMLElement | Text ): void {\n\t\tif ( !this._revertData ) {\n\t\t\t/**\n\t\t\t * Attempting to revert a template which has not been applied yet.\n\t\t\t *\n\t\t\t * @error ui-template-revert-not-applied\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-template-revert-not-applied',\n\t\t\t\t[ this, node ]\n\t\t\t);\n\t\t}\n\n\t\tthis._revertTemplateFromNode( node, this._revertData );\n\t}\n\n\t/**\n\t * Returns an iterator which traverses the template in search of {@link module:ui/view~View}\n\t * instances and returns them one by one.\n\t *\n\t * ```ts\n\t * const viewFoo = new View();\n\t * const viewBar = new View();\n\t * const viewBaz = new View();\n\t * const template = new Template( {\n\t * \ttag: 'div',\n\t * \tchildren: [\n\t * \t\tviewFoo,\n\t * \t\t{\n\t * \t\t\ttag: 'div',\n\t * \t\t\tchildren: [\n\t * \t\t\t\tviewBar\n\t * \t\t\t]\n\t * \t\t},\n\t * \t\tviewBaz\n\t * \t]\n\t * } );\n\t *\n\t * // Logs: viewFoo, viewBar, viewBaz\n\t * for ( const view of template.getViews() ) {\n\t * \tconsole.log( view );\n\t * }\n\t * ```\n\t */\n\tpublic* getViews(): IterableIterator<View> {\n\t\tfunction* search( def: Template ): Iterable<View> {\n\t\t\tif ( def.children ) {\n\t\t\t\tfor ( const child of def.children ) {\n\t\t\t\t\tif ( isView( child ) ) {\n\t\t\t\t\t\tyield child;\n\t\t\t\t\t} else if ( isTemplate( child ) ) {\n\t\t\t\t\t\tyield* search( child );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tyield* search( this );\n\t}\n\n\t/**\n\t * An entry point to the interface which binds DOM nodes to\n\t * {@link module:utils/observablemixin~Observable observables}.\n\t * There are two types of bindings:\n\t *\n\t * * HTML element attributes or text `textContent` synchronized with attributes of an\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}\n\t * and {@link module:ui/template~BindChain#if}.\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \tattributes: {\n\t * \t\t// Binds the element \"class\" attribute to observable#classAttribute.\n\t * \t\tclass: bind.to( 'classAttribute' )\n\t * \t}\n\t * } ).render();\n\t * ```\n\t *\n\t * * DOM events fired on HTML element propagated through\n\t * {@link module:utils/observablemixin~Observable}. Learn more about {@link module:ui/template~BindChain#to}.\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \ton: {\n\t * \t\t// Will be fired by the observable.\n\t * \t\tclick: bind( 'elementClicked' )\n\t * \t}\n\t * } ).render();\n\t * ```\n\t *\n\t * Also see {@link module:ui/view~View#bindTemplate}.\n\t *\n\t * @param observable An observable which provides boundable attributes.\n\t * @param emitter An emitter that listens to observable attribute\n\t * changes or DOM Events (depending on the kind of the binding). Usually, a {@link module:ui/view~View} instance.\n\t */\n\tpublic static override bind<TObservable extends Observable>(\n\t\tobservable: TObservable,\n\t\temitter: Emitter\n\t): BindChain<TObservable> {\n\t\treturn {\n\t\t\tto( eventNameOrFunctionOrAttribute: any, callback?: any ) {\n\t\t\t\treturn new TemplateToBinding( {\n\t\t\t\t\teventNameOrFunction: eventNameOrFunctionOrAttribute,\n\t\t\t\t\tattribute: eventNameOrFunctionOrAttribute,\n\t\t\t\t\tobservable, emitter, callback\n\t\t\t\t} );\n\t\t\t},\n\n\t\t\tif( attribute: string, valueIfTrue?: string, callback?: any ) {\n\t\t\t\treturn new TemplateIfBinding( {\n\t\t\t\t\tobservable, emitter, attribute, valueIfTrue, callback\n\t\t\t\t} );\n\t\t\t}\n\t\t} as any;\n\t}\n\n\t/**\n\t * Extends an existing {@link module:ui/template~Template} instance with some additional content\n\t * from another {@link module:ui/template~TemplateDefinition}.\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * const template = new Template( {\n\t * \ttag: 'p',\n\t * \tattributes: {\n\t * \t\tclass: 'a',\n\t * \t\tdata-x: bind.to( 'foo' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t{\n\t * \t\t\ttag: 'span',\n\t * \t\t\tattributes: {\n\t * \t\t\t\tclass: 'b'\n\t * \t\t\t},\n\t * \t\t\tchildren: [\n\t * \t\t\t\t'Span'\n\t * \t\t\t]\n\t * \t\t}\n\t * \t]\n\t *  } );\n\t *\n\t * // Instance-level extension.\n\t * Template.extend( template, {\n\t * \tattributes: {\n\t * \t\tclass: 'b',\n\t * \t\tdata-x: bind.to( 'bar' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t{\n\t * \t\t\tattributes: {\n\t * \t\t\t\tclass: 'c'\n\t * \t\t\t}\n\t * \t\t}\n\t * \t]\n\t * } );\n\t *\n\t * // Child extension.\n\t * Template.extend( template.children[ 0 ], {\n\t * \tattributes: {\n\t * \t\tclass: 'd'\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * the `outerHTML` of `template.render()` is:\n\t *\n\t * ```html\n\t * <p class=\"a b\" data-x=\"{ observable.foo } { observable.bar }\">\n\t * \t<span class=\"b c d\">Span</span>\n\t * </p>\n\t * ```\n\t *\n\t * @param template An existing template instance to be extended.\n\t * @param def Additional definition to be applied to a template.\n\t */\n\tpublic static extend( template: Template, def: Partial<TemplateDefinition> ): void {\n\t\tif ( template._isRendered ) {\n\t\t\t/**\n\t\t\t * Extending a template after rendering may not work as expected. To make sure\n\t\t\t * the {@link module:ui/template~Template.extend extending} works for an element,\n\t\t\t * make sure it happens before {@link module:ui/template~Template#render} is called.\n\t\t\t *\n\t\t\t * @error template-extend-render\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'template-extend-render',\n\t\t\t\t[ this, template ]\n\t\t\t);\n\t\t}\n\n\t\textendTemplate( template, normalize( clone( def ) ) );\n\t}\n\n\t/**\n\t * Renders a DOM Node (either an HTML element or text) out of the template.\n\t *\n\t * @param data Rendering data.\n\t */\n\tprivate _renderNode( data: RenderData ) {\n\t\tlet isInvalid;\n\n\t\tif ( data.node ) {\n\t\t\t// When applying, a definition cannot have \"tag\" and \"text\" at the same time.\n\t\t\tisInvalid = this.tag && this.text;\n\t\t} else {\n\t\t\t// When rendering, a definition must have either \"tag\" or \"text\": XOR( this.tag, this.text ).\n\t\t\tisInvalid = this.tag ? this.text : !this.text;\n\t\t}\n\n\t\tif ( isInvalid ) {\n\t\t\t/**\n\t\t\t * Node definition cannot have the \"tag\" and \"text\" properties at the same time.\n\t\t\t * Node definition must have either \"tag\" or \"text\" when rendering a new Node.\n\t\t\t *\n\t\t\t * @error ui-template-wrong-syntax\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-template-wrong-syntax',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tif ( this.text ) {\n\t\t\treturn this._renderText( data );\n\t\t} else {\n\t\t\treturn this._renderElement( data );\n\t\t}\n\t}\n\n\t/**\n\t * Renders an HTML element out of the template.\n\t *\n\t * @param data Rendering data.\n\t */\n\tprivate _renderElement( data: RenderData ) {\n\t\tlet node = data.node;\n\n\t\tif ( !node ) {\n\t\t\tnode = data.node = document.createElementNS( this.ns || xhtmlNs, this.tag! ) as any;\n\t\t}\n\n\t\tthis._renderAttributes( data );\n\t\tthis._renderElementChildren( data );\n\t\tthis._setUpListeners( data );\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Renders a text node out of {@link module:ui/template~Template#text}.\n\t *\n\t * @param data Rendering data.\n\t */\n\tprivate _renderText( data: RenderData ) {\n\t\tlet node = data.node;\n\n\t\t// Save the original textContent to revert it in #revert().\n\t\tif ( node ) {\n\t\t\tdata.revertData!.text = node.textContent;\n\t\t} else {\n\t\t\tnode = data.node = document.createTextNode( '' );\n\t\t}\n\n\t\t// Check if this Text Node is bound to Observable. Cases:\n\t\t//\n\t\t//\t\ttext: [ Template.bind( ... ).to( ... ) ]\n\t\t//\n\t\t//\t\ttext: [\n\t\t//\t\t\t'foo',\n\t\t//\t\t\tTemplate.bind( ... ).to( ... ),\n\t\t//\t\t\t...\n\t\t//\t\t]\n\t\t//\n\t\tif ( hasTemplateBinding( this.text ) ) {\n\t\t\tthis._bindToObservable( {\n\t\t\t\tschema: this.text!,\n\t\t\t\tupdater: getTextUpdater( node ),\n\t\t\t\tdata\n\t\t\t} );\n\t\t}\n\t\t// Simply set text. Cases:\n\t\t//\n\t\t//\t\ttext: [ 'all', 'are', 'static' ]\n\t\t//\n\t\t//\t\ttext: [ 'foo' ]\n\t\t//\n\t\telse {\n\t\t\tnode.textContent = this.text!.join( '' );\n\t\t}\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Renders HTML element attributes out of {@link module:ui/template~Template#attributes}.\n\t *\n\t * @param data Rendering data.\n\t */\n\tprivate _renderAttributes( data: RenderData ) {\n\t\tif ( !this.attributes ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst node = data.node as HTMLElement;\n\t\tconst revertData = data.revertData;\n\n\t\tfor ( const attrName in this.attributes ) {\n\t\t\t// Current attribute value in DOM.\n\t\t\tconst domAttrValue = node.getAttribute( attrName );\n\n\t\t\t// The value to be set.\n\t\t\tconst attrValue = this.attributes[ attrName ];\n\n\t\t\t// Save revert data.\n\t\t\tif ( revertData ) {\n\t\t\t\trevertData.attributes[ attrName ] = domAttrValue;\n\t\t\t}\n\n\t\t\t// Detect custom namespace:\n\t\t\t//\n\t\t\t//\t\tclass: {\n\t\t\t//\t\t\tns: 'abc',\n\t\t\t//\t\t\tvalue: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tconst attrNs = isNamespaced( attrValue ) ? attrValue[ 0 ].ns : null;\n\n\t\t\t// Activate binding if one is found. Cases:\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\tTemplate.bind( ... ).to( ... )\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t'bar',\n\t\t\t//\t\t\tTemplate.bind( ... ).to( ... ),\n\t\t\t//\t\t\t'baz'\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\t//\t\tclass: {\n\t\t\t//\t\t\tns: 'abc',\n\t\t\t//\t\t\tvalue: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tif ( hasTemplateBinding( attrValue ) ) {\n\t\t\t\t// Normalize attributes with additional data like namespace:\n\t\t\t\t//\n\t\t\t\t//\t\tclass: {\n\t\t\t\t//\t\t\tns: 'abc',\n\t\t\t\t//\t\t\tvalue: [ ... ]\n\t\t\t\t//\t\t}\n\t\t\t\t//\n\t\t\t\tconst valueToBind = isNamespaced( attrValue ) ? attrValue[ 0 ].value : attrValue;\n\n\t\t\t\t// Extend the original value of attributes like \"style\" and \"class\",\n\t\t\t\t// don't override them.\n\t\t\t\tif ( revertData && shouldExtend( attrName ) ) {\n\t\t\t\t\tvalueToBind.unshift( domAttrValue );\n\t\t\t\t}\n\n\t\t\t\tthis._bindToObservable( {\n\t\t\t\t\tschema: valueToBind,\n\t\t\t\t\tupdater: getAttributeUpdater( node, attrName, attrNs ),\n\t\t\t\t\tdata\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Style attribute could be an Object so it needs to be parsed in a specific way.\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\twidth: '100px',\n\t\t\t//\t\t\theight: Template.bind( ... ).to( ... )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\telse if ( attrName == 'style' && typeof attrValue[ 0 ] !== 'string' ) {\n\t\t\t\tthis._renderStyleAttribute( attrValue[ 0 ] as any, data );\n\t\t\t}\n\n\t\t\t// Otherwise simply set the static attribute:\n\t\t\t//\n\t\t\t//\t\tclass: [ 'foo' ]\n\t\t\t//\n\t\t\t//\t\tclass: [ 'all', 'are', 'static' ]\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t{\n\t\t\t//\t\t\t\tns: 'abc',\n\t\t\t//\t\t\t\tvalue: [ 'foo' ]\n\t\t\t//\t\t\t}\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\telse {\n\t\t\t\t// Extend the original value of attributes like \"style\" and \"class\",\n\t\t\t\t// don't override them.\n\t\t\t\tif ( revertData && domAttrValue && shouldExtend( attrName ) ) {\n\t\t\t\t\tattrValue.unshift( domAttrValue as any );\n\t\t\t\t}\n\n\t\t\t\tconst value: any = attrValue\n\t\t\t\t\t// Retrieve \"values\" from:\n\t\t\t\t\t//\n\t\t\t\t\t//\t\tclass: [\n\t\t\t\t\t//\t\t\t{\n\t\t\t\t\t//\t\t\t\tns: 'abc',\n\t\t\t\t\t//\t\t\t\tvalue: [ ... ]\n\t\t\t\t\t//\t\t\t}\n\t\t\t\t\t//\t\t]\n\t\t\t\t\t//\n\t\t\t\t\t.map( ( val: any ) => val ? ( val.value || val ) : val )\n\t\t\t\t\t// Flatten the array.\n\t\t\t\t\t.reduce( ( prev, next ) => prev.concat( next ), [] )\n\t\t\t\t\t// Convert into string.\n\t\t\t\t\t.reduce( arrayValueReducer, '' );\n\n\t\t\t\tif ( !isFalsy( value ) ) {\n\t\t\t\t\tnode.setAttributeNS( attrNs, attrName, value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Renders the `style` attribute of an HTML element based on\n\t * {@link module:ui/template~Template#attributes}.\n\t *\n\t * A style attribute is an object with static values:\n\t *\n\t * ```ts\n\t * attributes: {\n\t * \tstyle: {\n\t * \t\tcolor: 'red'\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * or values bound to {@link module:ui/model~Model} properties:\n\t *\n\t * ```ts\n\t * attributes: {\n\t * \tstyle: {\n\t * \t\tcolor: bind.to( ... )\n\t * \t}\n\t * }\n\t * ```\n\t *\n\t * Note: The `style` attribute is rendered without setting the namespace. It does not seem to be\n\t * needed.\n\t *\n\t * @param styles Styles located in `attributes.style` of {@link module:ui/template~TemplateDefinition}.\n\t * @param data Rendering data.\n\t */\n\tprivate _renderStyleAttribute( styles: Record<string, TemplateSimpleValue | TemplateBinding>, data: RenderData ) {\n\t\tconst node = data.node;\n\n\t\tfor ( const styleName in styles ) {\n\t\t\tconst styleValue = styles[ styleName ];\n\n\t\t\t// Cases:\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\tcolor: bind.to( 'attribute' )\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\tif ( hasTemplateBinding( styleValue ) ) {\n\t\t\t\tthis._bindToObservable( {\n\t\t\t\t\tschema: [ styleValue ],\n\t\t\t\t\tupdater: getStyleUpdater( node, styleName ),\n\t\t\t\t\tdata\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Cases:\n\t\t\t//\n\t\t\t//\t\tstyle: {\n\t\t\t//\t\t\tcolor: 'red'\n\t\t\t//\t\t}\n\t\t\t//\n\t\t\telse {\n\t\t\t\t( node as any ).style[ styleName ] = styleValue;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Recursively renders HTML element's children from {@link module:ui/template~Template#children}.\n\t *\n\t * @param data Rendering data.\n\t */\n\tprivate _renderElementChildren( data: RenderData ) {\n\t\tconst node = data.node as HTMLElement;\n\t\tconst container = data.intoFragment ? document.createDocumentFragment() : node;\n\t\tconst isApplying = data.isApplying;\n\t\tlet childIndex = 0;\n\n\t\tfor ( const child of this.children! ) {\n\t\t\tif ( isViewCollection( child ) ) {\n\t\t\t\tif ( !isApplying ) {\n\t\t\t\t\tchild.setParent( node );\n\n\t\t\t\t\t// Note: ViewCollection renders its children.\n\t\t\t\t\tfor ( const view of child ) {\n\t\t\t\t\t\tcontainer.appendChild( view.element! );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ( isView( child ) ) {\n\t\t\t\tif ( !isApplying ) {\n\t\t\t\t\tif ( !child.isRendered ) {\n\t\t\t\t\t\tchild.render();\n\t\t\t\t\t}\n\n\t\t\t\t\tcontainer.appendChild( child.element! );\n\t\t\t\t}\n\t\t\t} else if ( isNode( child ) ) {\n\t\t\t\tcontainer.appendChild( child );\n\t\t\t} else {\n\t\t\t\tif ( isApplying ) {\n\t\t\t\t\tconst revertData = data.revertData!;\n\t\t\t\t\tconst childRevertData = getEmptyRevertData();\n\n\t\t\t\t\trevertData.children.push( childRevertData );\n\n\t\t\t\t\tchild._renderNode( {\n\t\t\t\t\t\tintoFragment: false,\n\t\t\t\t\t\tnode: container.childNodes[ childIndex++ ] as any,\n\t\t\t\t\t\tisApplying: true,\n\t\t\t\t\t\trevertData: childRevertData\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\tcontainer.appendChild( child.render() );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( data.intoFragment ) {\n\t\t\tnode.appendChild( container );\n\t\t}\n\t}\n\n\t/**\n\t * Activates `on` event listeners from the {@link module:ui/template~TemplateDefinition}\n\t * on an HTML element.\n\t *\n\t * @param data Rendering data.\n\t */\n\tprivate _setUpListeners( data: RenderData ) {\n\t\tif ( !this.eventListeners ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const key in this.eventListeners ) {\n\t\t\tconst revertBindings = this.eventListeners[ key ].map( schemaItem => {\n\t\t\t\tconst [ domEvtName, domSelector ] = key.split( '@' );\n\n\t\t\t\treturn schemaItem.activateDomEventListener( domEvtName, domSelector, data );\n\t\t\t} );\n\n\t\t\tif ( data.revertData ) {\n\t\t\t\tdata.revertData.bindings.push( revertBindings );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * For a given {@link module:ui/template~TemplateValueSchema} containing {@link module:ui/template~TemplateBinding}\n\t * activates the binding and sets its initial value.\n\t *\n\t * Note: {@link module:ui/template~TemplateValueSchema} can be for HTML element attributes or\n\t * text node `textContent`.\n\t *\n\t * @param options Binding options.\n\t * @param options.updater A function which updates the DOM (like attribute or text).\n\t * @param options.data Rendering data.\n\t */\n\tprivate _bindToObservable( { schema, updater, data }: {\n\t\tschema: Array<TemplateSimpleValue | TemplateBinding>;\n\t\tupdater: Updater;\n\t\tdata: RenderData;\n\t} ) {\n\t\tconst revertData = data.revertData;\n\n\t\t// Set initial values.\n\t\tsyncValueSchemaValue( schema, updater, data );\n\n\t\tconst revertBindings = schema\n\t\t\t// Filter \"falsy\" (false, undefined, null, '') value schema components out.\n\t\t\t.filter( item => !isFalsy( item ) )\n\t\t\t// Filter inactive bindings from schema, like static strings ('foo'), numbers (42), etc.\n\t\t\t.filter( ( item: any ): item is TemplateBinding => item.observable )\n\t\t\t// Once only the actual binding are left, let the emitter listen to observable change:attribute event.\n\t\t\t// TODO: Reduce the number of listeners attached as many bindings may listen\n\t\t\t// to the same observable attribute.\n\t\t\t.map( templateBinding => templateBinding.activateAttributeListener( schema, updater, data ) );\n\n\t\tif ( revertData ) {\n\t\t\trevertData.bindings.push( revertBindings );\n\t\t}\n\t}\n\n\t/**\n\t * Reverts {@link module:ui/template~RenderData#revertData template data} from a node to\n\t * return it to the original state.\n\t *\n\t * @param node A node to be reverted.\n\t * @param revertData An object that stores information about what changes have been made by\n\t * {@link #apply} to the node. See {@link module:ui/template~RenderData#revertData} for more information.\n\t */\n\tprivate _revertTemplateFromNode( node: HTMLElement | Text, revertData: RevertData ) {\n\t\tfor ( const binding of revertData.bindings ) {\n\t\t\t// Each binding may consist of several observable+observable#attribute.\n\t\t\t// like the following has 2:\n\t\t\t//\n\t\t\t//\t\tclass: [\n\t\t\t//\t\t\t'x',\n\t\t\t//\t\t\tbind.to( 'foo' ),\n\t\t\t//\t\t\t'y',\n\t\t\t//\t\t\tbind.to( 'bar' )\n\t\t\t//\t\t]\n\t\t\t//\n\t\t\tfor ( const revertBinding of binding ) {\n\t\t\t\trevertBinding();\n\t\t\t}\n\t\t}\n\n\t\tif ( revertData.text ) {\n\t\t\tnode.textContent = revertData.text;\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst element = node as HTMLElement;\n\n\t\tfor ( const attrName in revertData.attributes ) {\n\t\t\tconst attrValue = revertData.attributes[ attrName ];\n\n\t\t\t// When the attribute has **not** been set before #apply().\n\t\t\tif ( attrValue === null ) {\n\t\t\t\telement.removeAttribute( attrName );\n\t\t\t} else {\n\t\t\t\telement.setAttribute( attrName, attrValue );\n\t\t\t}\n\t\t}\n\n\t\tfor ( let i = 0; i < revertData.children.length; ++i ) {\n\t\t\tthis._revertTemplateFromNode( element.childNodes[ i ] as any, revertData.children[ i ] );\n\t\t}\n\t}\n}\n\ntype AttributeValues = Array<TemplateSimpleValue | TemplateBinding> |\n\t[ NamespacedValue<Array<TemplateSimpleValue | TemplateBinding>> ];\n\n/**\n * Describes a binding created by the {@link module:ui/template~Template.bind} interface.\n *\n * @internal\n */\nexport abstract class TemplateBinding {\n\t/**\n\t * The name of the {@link module:ui/template~TemplateBinding#observable observed attribute}.\n\t */\n\tpublic readonly attribute: string;\n\n\t/**\n\t * An observable instance of the binding. It either:\n\t *\n\t * * provides the attribute with the value,\n\t * * or passes the event when a corresponding DOM event is fired.\n\t */\n\tpublic readonly observable: Observable;\n\n\t/**\n\t * An {@link module:utils/emittermixin~Emitter} used by the binding to:\n\t *\n\t * * listen to the attribute change in the {@link module:ui/template~TemplateBinding#observable},\n\t * * or listen to the event in the DOM.\n\t */\n\tpublic readonly emitter: Emitter;\n\n\t/**\n\t * A custom function to process the value of the {@link module:ui/template~TemplateBinding#attribute}.\n\t */\n\tpublic readonly callback?: ( value: any, node: Node ) => TemplateSimpleValue;\n\n\t/**\n\t * Creates an instance of the {@link module:ui/template~TemplateBinding} class.\n\t *\n\t * @param def The definition of the binding.\n\t */\n\tconstructor( def: {\n\t\tattribute: string;\n\t\tobservable: Observable;\n\t\temitter: Emitter;\n\t\tcallback?: ( value: any, node: Node ) => TemplateSimpleValue;\n\t} ) {\n\t\tthis.attribute = def.attribute;\n\t\tthis.observable = def.observable;\n\t\tthis.emitter = def.emitter;\n\t\tthis.callback = def.callback;\n\t}\n\n\t/**\n\t * Returns the value of the binding. It is the value of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}. The value may be processed by the\n\t * {@link module:ui/template~TemplateBinding#callback}, if such has been passed to the binding.\n\t *\n\t * @param node A native DOM node, passed to the custom {@link module:ui/template~TemplateBinding#callback}.\n\t * @returns The value of {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}.\n\t */\n\tpublic getValue( node: Node ): TemplateSimpleValue {\n\t\tconst value = ( this.observable as any )[ this.attribute ];\n\n\t\treturn this.callback ? this.callback( value, node ) : value;\n\t}\n\n\t/**\n\t * Activates the listener which waits for changes of the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable}, then updates the DOM with the aggregated\n\t * value of {@link module:ui/template~TemplateValueSchema}.\n\t *\n\t * @param schema A full schema to generate an attribute or text in the DOM.\n\t * @param updater A DOM updater function used to update the native DOM attribute or text.\n\t * @param data Rendering data.\n\t * @returns A function to sever the listener binding.\n\t */\n\tpublic activateAttributeListener(\n\t\tschema: Array<TemplateSimpleValue | TemplateBinding>,\n\t\tupdater: Updater,\n\t\tdata: RenderData\n\t): () => void {\n\t\tconst callback = () => syncValueSchemaValue( schema, updater, data );\n\n\t\tthis.emitter.listenTo<ObservableChangeEvent>( this.observable, `change:${ this.attribute }`, callback );\n\n\t\t// Allows revert of the listener.\n\t\treturn () => {\n\t\t\tthis.emitter.stopListening( this.observable, `change:${ this.attribute }`, callback );\n\t\t};\n\t}\n}\n\n/**\n * Describes either:\n *\n * * a binding to an {@link module:utils/observablemixin~Observable},\n * * or a native DOM event binding.\n *\n * It is created by the {@link module:ui/template~BindChain#to} method.\n *\n * @internal\n */\nexport class TemplateToBinding extends TemplateBinding {\n\tpublic readonly eventNameOrFunction: string | ( ( domEvent: Event ) => void );\n\n\tconstructor( def: ConstructorParameters<typeof TemplateBinding>[ 0 ] & {\n\t\teventNameOrFunction: string | ( ( domEvent: Event ) => void );\n\t} ) {\n\t\tsuper( def );\n\n\t\tthis.eventNameOrFunction = def.eventNameOrFunction;\n\t}\n\n\t/**\n\t * Activates the listener for the native DOM event, which when fired, is propagated by\n\t * the {@link module:ui/template~TemplateBinding#emitter}.\n\t *\n\t * @param domEvtName The name of the native DOM event.\n\t * @param domSelector The selector in the DOM to filter delegated events.\n\t * @param data Rendering data.\n\t * @returns A function to sever the listener binding.\n\t */\n\tpublic activateDomEventListener(\n\t\tdomEvtName: string,\n\t\tdomSelector: string,\n\t\tdata: { node: any }\n\t): () => void {\n\t\tconst callback = ( evt: unknown, domEvt: Event ) => {\n\t\t\tif ( !domSelector || ( domEvt.target as Element ).matches( domSelector ) ) {\n\t\t\t\tif ( typeof this.eventNameOrFunction == 'function' ) {\n\t\t\t\t\tthis.eventNameOrFunction( domEvt );\n\t\t\t\t} else {\n\t\t\t\t\tthis.observable.fire( this.eventNameOrFunction, domEvt );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tthis.emitter.listenTo( data.node, domEvtName, callback );\n\n\t\t// Allows revert of the listener.\n\t\treturn () => {\n\t\t\tthis.emitter.stopListening( data.node, domEvtName, callback );\n\t\t};\n\t}\n}\n\n/**\n * Describes a binding to {@link module:utils/observablemixin~Observable} created by the {@link module:ui/template~BindChain#if}\n * method.\n *\n * @internal\n */\nexport class TemplateIfBinding extends TemplateBinding {\n\t/**\n\t * The value of the DOM attribute or text to be set if the {@link module:ui/template~TemplateBinding#attribute} in\n\t * {@link module:ui/template~TemplateBinding#observable} is `true`.\n\t */\n\tpublic readonly valueIfTrue?: string;\n\n\tconstructor( def: ConstructorParameters<typeof TemplateBinding>[ 0 ] & {\n\t\tvalueIfTrue?: string;\n\t} ) {\n\t\tsuper( def );\n\n\t\tthis.valueIfTrue = def.valueIfTrue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override getValue( node: Node ): TemplateSimpleValue {\n\t\tconst value = super.getValue( node );\n\n\t\treturn isFalsy( value ) ? false : ( this.valueIfTrue || true ) as any;\n\t}\n}\n\n/**\n * Checks whether given {@link module:ui/template~TemplateValueSchema} contains a\n * {@link module:ui/template~TemplateBinding}.\n */\nfunction hasTemplateBinding( schema: any ) {\n\tif ( !schema ) {\n\t\treturn false;\n\t}\n\n\t// Normalize attributes with additional data like namespace:\n\t//\n\t//\t\tclass: {\n\t//\t\t\tns: 'abc',\n\t//\t\t\tvalue: [ ... ]\n\t//\t\t}\n\t//\n\tif ( schema.value ) {\n\t\tschema = schema.value;\n\t}\n\n\tif ( Array.isArray( schema ) ) {\n\t\treturn schema.some( hasTemplateBinding );\n\t} else if ( schema instanceof TemplateBinding ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Assembles the value using {@link module:ui/template~TemplateValueSchema} and stores it in a form of\n * an Array. Each entry of the Array corresponds to one of {@link module:ui/template~TemplateValueSchema}\n * items.\n *\n * @param node DOM Node updated when {@link module:utils/observablemixin~Observable} changes.\n */\nfunction getValueSchemaValue( schema: Array<TemplateSimpleValue | TemplateBinding>, node: Node ) {\n\treturn schema.map( schemaItem => {\n\t\t// Process {@link module:ui/template~TemplateBinding} bindings.\n\t\tif ( schemaItem instanceof TemplateBinding ) {\n\t\t\treturn schemaItem.getValue( node );\n\t\t}\n\n\t\t// All static values like strings, numbers, and \"falsy\" values (false, null, undefined, '', etc.) just pass.\n\t\treturn schemaItem;\n\t} );\n}\n\n/**\n * A function executed each time the bound Observable attribute changes, which updates the DOM with a value\n * constructed from {@link module:ui/template~TemplateValueSchema}.\n *\n * @param updater A function which updates the DOM (like attribute or text).\n * @param node DOM Node updated when {@link module:utils/observablemixin~Observable} changes.\n */\nfunction syncValueSchemaValue(\n\tschema: Array<TemplateSimpleValue | TemplateBinding>,\n\tupdater: Updater,\n\t{ node }: { node: Node }\n) {\n\tconst values = getValueSchemaValue( schema, node );\n\tlet value: TemplateSimpleValue;\n\n\t// Check if schema is a single Template.bind.if, like:\n\t//\n\t//\t\tclass: Template.bind.if( 'foo' )\n\t//\n\tif ( schema.length == 1 && schema[ 0 ] instanceof TemplateIfBinding ) {\n\t\tvalue = values[ 0 ];\n\t} else {\n\t\tvalue = values.reduce( arrayValueReducer, '' );\n\t}\n\n\tif ( isFalsy( value ) ) {\n\t\tupdater.remove();\n\t} else {\n\t\tupdater.set( value );\n\t}\n}\n\ninterface Updater {\n\tset( value: any ): void;\n\tremove(): void;\n}\n\n/**\n * Returns an object consisting of `set` and `remove` functions, which\n * can be used in the context of DOM Node to set or reset `textContent`.\n * @see module:ui/view~View#_bindToObservable\n *\n * @param node DOM Node to be modified.\n */\nfunction getTextUpdater( node: Node ): Updater {\n\treturn {\n\t\tset( value ) {\n\t\t\tnode.textContent = value;\n\t\t},\n\n\t\tremove() {\n\t\t\tnode.textContent = '';\n\t\t}\n\t};\n}\n\n/**\n * Returns an object consisting of `set` and `remove` functions, which\n * can be used in the context of DOM Node to set or reset an attribute.\n * @see module:ui/view~View#_bindToObservable\n *\n * @param el DOM Node to be modified.\n * @param attrName Name of the attribute to be modified.\n * @param ns Namespace to use.\n */\nfunction getAttributeUpdater( el: Element, attrName: string, ns: string | null ): Updater {\n\treturn {\n\t\tset( value ) {\n\t\t\tel.setAttributeNS( ns, attrName, value );\n\t\t},\n\n\t\tremove() {\n\t\t\tel.removeAttributeNS( ns, attrName );\n\t\t}\n\t};\n}\n\n/**\n * Returns an object consisting of `set` and `remove` functions, which\n * can be used in the context of CSSStyleDeclaration to set or remove a style.\n * @see module:ui/view~View#_bindToObservable\n *\n * @param el DOM Node to be modified.\n * @param styleName Name of the style to be modified.\n */\nfunction getStyleUpdater( el: any, styleName: string ): Updater {\n\treturn {\n\t\tset( value ) {\n\t\t\tel.style[ styleName ] = value;\n\t\t},\n\n\t\tremove() {\n\t\t\tel.style[ styleName ] = null;\n\t\t}\n\t};\n}\n\n/**\n * Clones definition of the template.\n */\nfunction clone( def: unknown ) {\n\tconst clone = cloneDeepWith( def, value => {\n\t\t// Don't clone the `Template.bind`* bindings because of the references to Observable\n\t\t// and DomEmitterMixin instances inside, which would also be traversed and cloned by greedy\n\t\t// cloneDeepWith algorithm. There's no point in cloning Observable/DomEmitterMixins\n\t\t// along with the definition.\n\t\t//\n\t\t// Don't clone Template instances if provided as a child. They're simply #render()ed\n\t\t// and nothing should interfere.\n\t\t//\n\t\t// Also don't clone View instances if provided as a child of the Template. The template\n\t\t// instance will be extracted from the View during the normalization and there's no need\n\t\t// to clone it.\n\t\tif ( value && ( value instanceof TemplateBinding || isTemplate( value ) || isView( value ) || isViewCollection( value ) ) ) {\n\t\t\treturn value;\n\t\t}\n\t} );\n\n\treturn clone;\n}\n\n/**\n * Normalizes given {@link module:ui/template~TemplateDefinition}.\n *\n * See:\n *  * {@link normalizeAttributes}\n *  * {@link normalizeListeners}\n *  * {@link normalizePlainTextDefinition}\n *  * {@link normalizeTextDefinition}\n *\n * @param def A template definition.\n * @returns Normalized definition.\n */\nfunction normalize( def: any ) {\n\tif ( typeof def == 'string' ) {\n\t\tdef = normalizePlainTextDefinition( def );\n\t} else if ( def.text ) {\n\t\tnormalizeTextDefinition( def );\n\t}\n\n\tif ( def.on ) {\n\t\tdef.eventListeners = normalizeListeners( def.on );\n\n\t\t// Template mixes EmitterMixin, so delete #on to avoid collision.\n\t\tdelete def.on;\n\t}\n\n\tif ( !def.text ) {\n\t\tif ( def.attributes ) {\n\t\t\tnormalizeAttributes( def.attributes );\n\t\t}\n\n\t\tconst children = [];\n\n\t\tif ( def.children ) {\n\t\t\tif ( isViewCollection( def.children ) ) {\n\t\t\t\tchildren.push( def.children );\n\t\t\t} else {\n\t\t\t\tfor ( const child of def.children ) {\n\t\t\t\t\tif ( isTemplate( child ) || isView( child ) || isNode( child ) ) {\n\t\t\t\t\t\tchildren.push( child );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchildren.push( new Template( child ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdef.children = children;\n\t}\n\n\treturn def;\n}\n\n/**\n * Normalizes \"attributes\" section of {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * attributes: {\n * \ta: 'bar',\n * \tb: {@link module:ui/template~TemplateBinding},\n * \tc: {\n * \t\tvalue: 'bar'\n * \t}\n * }\n * ```\n *\n * becomes\n *\n * ```\n * attributes: {\n * \ta: [ 'bar' ],\n * \tb: [ {@link module:ui/template~TemplateBinding} ],\n * \tc: {\n * \t\tvalue: [ 'bar' ]\n * \t}\n * }\n * ```\n */\nfunction normalizeAttributes( attributes: any ) {\n\tfor ( const a in attributes ) {\n\t\tif ( attributes[ a ].value ) {\n\t\t\tattributes[ a ].value = toArray( attributes[ a ].value );\n\t\t}\n\n\t\tarrayify( attributes, a );\n\t}\n}\n\n/**\n * Normalizes \"on\" section of {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * on: {\n * \ta: 'bar',\n * \tb: {@link module:ui/template~TemplateBinding},\n * \tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n * }\n * ```\n *\n * becomes\n *\n * ```\n * on: {\n * \ta: [ 'bar' ],\n * \tb: [ {@link module:ui/template~TemplateBinding} ],\n * \tc: [ {@link module:ui/template~TemplateBinding}, () => { ... } ]\n * }\n * ```\n *\n * @returns Object containing normalized listeners.\n */\nfunction normalizeListeners( listeners: any ) {\n\tfor ( const l in listeners ) {\n\t\tarrayify( listeners, l );\n\t}\n\n\treturn listeners;\n}\n\n/**\n * Normalizes \"string\" {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * \"foo\"\n * ```\n *\n * becomes\n *\n * ```\n * { text: [ 'foo' ] },\n * ```\n *\n * @returns Normalized template definition.\n */\nfunction normalizePlainTextDefinition( def: string ) {\n\treturn {\n\t\ttext: [ def ]\n\t};\n}\n\n/**\n * Normalizes text {@link module:ui/template~TemplateDefinition}.\n *\n * ```\n * children: [\n * \t{ text: 'def' },\n * \t{ text: {@link module:ui/template~TemplateBinding} }\n * ]\n * ```\n *\n * becomes\n *\n * ```\n * children: [\n * \t{ text: [ 'def' ] },\n * \t{ text: [ {@link module:ui/template~TemplateBinding} ] }\n * ]\n * ```\n */\nfunction normalizeTextDefinition( def: any ) {\n\tdef.text = toArray( def.text );\n}\n\n/**\n * Wraps an entry in Object in an Array, if not already one.\n *\n * ```\n * {\n * \tx: 'y',\n * \ta: [ 'b' ]\n * }\n * ```\n *\n * becomes\n *\n * ```\n * {\n * \tx: [ 'y' ],\n * \ta: [ 'b' ]\n * }\n * ```\n */\nfunction arrayify( obj: any, key: string ) {\n\tobj[ key ] = toArray( obj[ key ] );\n}\n\n/**\n * A helper which concatenates the value avoiding unwanted\n * leading white spaces.\n */\nfunction arrayValueReducer( prev: TemplateSimpleValue, cur: TemplateSimpleValue ) {\n\tif ( isFalsy( cur ) ) {\n\t\treturn prev;\n\t} else if ( isFalsy( prev ) ) {\n\t\treturn cur;\n\t} else {\n\t\treturn `${ prev } ${ cur }`;\n\t}\n}\n\n/**\n * Extends one object defined in the following format:\n *\n * ```\n * {\n * \tkey1: [Array1],\n * \tkey2: [Array2],\n * \t...\n * \tkeyN: [ArrayN]\n * }\n * ```\n *\n * with another object of the same data format.\n *\n * @param obj Base object.\n * @param ext Object extending base.\n */\nfunction extendObjectValueArray( obj: any, ext: any ) {\n\tfor ( const a in ext ) {\n\t\tif ( obj[ a ] ) {\n\t\t\tobj[ a ].push( ...ext[ a ] );\n\t\t} else {\n\t\t\tobj[ a ] = ext[ a ];\n\t\t}\n\t}\n}\n\n/**\n * A helper for {@link module:ui/template~Template#extend}. Recursively extends {@link module:ui/template~Template} instance\n * with content from {@link module:ui/template~TemplateDefinition}. See {@link module:ui/template~Template#extend} to learn more.\n *\n * @param def A template instance to be extended.\n * @param def A definition which is to extend the template instance.\n * @param Error context.\n */\nfunction extendTemplate( template: Template, def: any ) {\n\tif ( def.attributes ) {\n\t\tif ( !template.attributes ) {\n\t\t\ttemplate.attributes = {};\n\t\t}\n\n\t\textendObjectValueArray( template.attributes, def.attributes );\n\t}\n\n\tif ( def.eventListeners ) {\n\t\tif ( !template.eventListeners ) {\n\t\t\ttemplate.eventListeners = {};\n\t\t}\n\n\t\textendObjectValueArray( template.eventListeners, def.eventListeners );\n\t}\n\n\tif ( def.text ) {\n\t\ttemplate.text!.push( ...def.text );\n\t}\n\n\tif ( def.children && def.children.length ) {\n\t\tif ( template.children!.length != def.children.length ) {\n\t\t\t/**\n\t\t\t * The number of children in extended definition does not match.\n\t\t\t *\n\t\t\t * @error ui-template-extend-children-mismatch\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'ui-template-extend-children-mismatch',\n\t\t\t\ttemplate\n\t\t\t);\n\t\t}\n\n\t\tlet childIndex = 0;\n\n\t\tfor ( const childDef of def.children ) {\n\t\t\textendTemplate( template.children![ childIndex++ ] as any, childDef );\n\t\t}\n\t}\n}\n\n/**\n * Checks if value is \"falsy\".\n * Note: 0 (Number) is not \"falsy\" in this context.\n *\n * @param value Value to be checked.\n */\nfunction isFalsy( value: unknown ): value is FalsyValue {\n\treturn !value && value !== 0;\n}\n\n/**\n * Checks if the item is an instance of {@link module:ui/view~View}\n *\n * @param value Value to be checked.\n */\nfunction isView( item: unknown ): item is View {\n\treturn item instanceof View;\n}\n\n/**\n * Checks if the item is an instance of {@link module:ui/template~Template}\n *\n * @param value Value to be checked.\n */\nfunction isTemplate( item: unknown ): item is Template {\n\treturn item instanceof Template;\n}\n\n/**\n * Checks if the item is an instance of {@link module:ui/viewcollection~ViewCollection}\n *\n * @param value Value to be checked.\n */\nfunction isViewCollection( item: unknown ): item is ViewCollection {\n\treturn item instanceof ViewCollection;\n}\n\n/**\n * Checks if value array contains the one with namespace.\n */\nfunction isNamespaced(\n\tattrValue: AttributeValues\n): attrValue is [ NamespacedValue<Array<TemplateSimpleValue | TemplateBinding>> ] {\n\treturn isObject( attrValue[ 0 ] ) && ( attrValue[ 0 ] as any ).ns;\n}\n\n/**\n * Creates an empty skeleton for {@link module:ui/template~Template#revert}\n * data.\n */\nfunction getEmptyRevertData(): RevertData {\n\treturn {\n\t\tchildren: [],\n\t\tbindings: [],\n\t\tattributes: {}\n\t};\n}\n\n/**\n * Checks whether an attribute should be extended when\n * {@link module:ui/template~Template#apply} is called.\n *\n * @param attrName Attribute name to check.\n */\nfunction shouldExtend( attrName: string ) {\n\treturn attrName == 'class' || attrName == 'style';\n}\n\n/**\n * A definition of the {@link module:ui/template~Template}. It describes what kind of\n * node a template will render (HTML element or text), attributes of an element, DOM event\n * listeners and children.\n *\n * Also see:\n * * {@link module:ui/template~TemplateValueSchema} to learn about HTML element attributes,\n * * {@link module:ui/template~TemplateListenerSchema} to learn about DOM event listeners.\n *\n * A sample definition on an HTML element can look like this:\n *\n * ```ts\n * new Template( {\n * \ttag: 'p',\n * \tchildren: [\n * \t\t{\n * \t\t\ttag: 'span',\n * \t\t\tattributes: { ... },\n * \t\t\tchildren: [ ... ],\n * \t\t},\n * \t\t{\n * \t\t\ttext: 'static–text'\n * \t\t},\n * \t\t'also-static–text',\n * \t],\n * \tattributes: {\n * \t\tclass: {@link module:ui/template~TemplateValueSchema},\n * \t\tid: {@link module:ui/template~TemplateValueSchema},\n * \t\tstyle: {@link module:ui/template~TemplateValueSchema}\n *\n * \t\t// ...\n * \t},\n * \ton: {\n * \t\t'click': {@link module:ui/template~TemplateListenerSchema}\n *\n * \t\t// Document.querySelector format is also accepted.\n * \t\t'keyup@a.some-class': {@link module:ui/template~TemplateListenerSchema}\n *\n * \t\t// ...\n * \t}\n * } );\n * ```\n *\n * A {@link module:ui/view~View}, another {@link module:ui/template~Template} or a native DOM node\n * can also become a child of a template. When a view is passed, its {@link module:ui/view~View#element} is used:\n *\n * ```ts\n * const view = new SomeView();\n * const childTemplate = new Template( { ... } );\n * const childNode = document.createElement( 'b' );\n *\n * new Template( {\n * \ttag: 'p',\n *\n * \tchildren: [\n * \t\t// view#element will be added as a child of this <p>.\n * \t\tview,\n *\n * \t\t// The output of childTemplate.render() will be added here.\n * \t\tchildTemplate,\n *\n * \t\t// Native DOM nodes are included directly in the rendered output.\n * \t\tchildNode\n * \t]\n * } );\n * ```\n *\n * An entire {@link module:ui/viewcollection~ViewCollection} can be used as a child in the definition:\n *\n * ```ts\n * const collection = new ViewCollection();\n * collection.add( someView );\n *\n * new Template( {\n * \ttag: 'p',\n *\n * \tchildren: collection\n * } );\n * ```\n */\nexport type TemplateDefinition = string |\n\tTemplate |\n\tTemplateElementDefinition |\n\tTemplateTextDefinition;\n\nexport type TemplateElementDefinition = {\n\n\t/**\n\t * See the template {@link module:ui/template~Template#tag} property.\n\t */\n\ttag: string;\n\n\t/**\n\t * See the template {@link module:ui/template~Template#attributes} property.\n\t */\n\tattributes?: Record<string, TemplateValueSchema>;\n\n\t/**\n\t * See the template {@link module:ui/template~Template#children} property.\n\t */\n\tchildren?: Iterable<View | Node | Template | TemplateDefinition>;\n\n\t/**\n\t * See the template {@link module:ui/template~Template#eventListeners} property.\n\t */\n\ton?: Record<string, TemplateListenerSchema>;\n};\n\nexport type TemplateTextDefinition = {\n\n\t/**\n\t * See the template {@link module:ui/template~Template#text} property.\n\t */\n\ttext: ArrayOrItem<TemplateSimpleValueSchema>;\n};\n\nexport type FalsyValue = false | null | undefined | '';\n\nexport type NamespacedValue<T> = { ns: string; value: T };\n\nexport type TemplateSimpleValue = string | boolean | number | null | undefined;\n\nexport type TemplateSimpleValueSchema = TemplateSimpleValue | AttributeBinding;\n\n/**\n * Describes a value of an HTML element attribute or `textContent`. It allows combining multiple\n * data sources like static values and {@link module:utils/observablemixin~Observable} attributes.\n *\n * Also see:\n * * {@link module:ui/template~TemplateDefinition} to learn where to use it,\n * * {@link module:ui/template~Template.bind} to learn how to configure\n * {@link module:utils/observablemixin~Observable} attribute bindings,\n * * {@link module:ui/template~Template#render} to learn how to render a template,\n * * {@link module:ui/template~BindChain#to `to()`} and {@link module:ui/template~BindChain#if `if()`}\n * methods to learn more about bindings.\n *\n * Attribute values can be described in many different ways:\n *\n * ```ts\n * // Bind helper will create bindings to attributes of the observable.\n * const bind = Template.bind( observable, emitter );\n *\n * new Template( {\n * \ttag: 'p',\n * \tattributes: {\n * \t\t// A plain string schema.\n * \t\t'class': 'static-text',\n *\n * \t\t// An object schema, binds to the \"foo\" attribute of the\n * \t\t// observable and follows its value.\n * \t\t'class': bind.to( 'foo' ),\n *\n * \t\t// An array schema, combines the above.\n * \t\t'class': [\n * \t\t\t'static-text',\n * \t\t\tbind.to( 'bar', () => { ... } ),\n *\n * \t\t\t// Bindings can also be conditional.\n * \t\t\tbind.if( 'baz', 'class-when-baz-is-true' )\n * \t\t],\n *\n * \t\t// An array schema, with a custom namespace, e.g. useful for creating SVGs.\n * \t\t'class': {\n * \t\t\tns: 'http://ns.url',\n * \t\t\tvalue: [\n * \t\t\t\tbind.if( 'baz', 'value-when-true' ),\n * \t\t\t\t'static-text'\n * \t\t\t]\n * \t\t},\n *\n * \t\t// An object schema, specific for styles.\n * \t\tstyle: {\n * \t\t\tcolor: 'red',\n * \t\t\tbackgroundColor: bind.to( 'qux', () => { ... } )\n * \t\t}\n * \t}\n * } );\n * ```\n *\n * Text nodes can also have complex values:\n *\n * ```ts\n * const bind = Template.bind( observable, emitter );\n *\n * // Will render a \"foo\" text node.\n * new Template( {\n * \ttext: 'foo'\n * } );\n *\n * // Will render a \"static text: {observable.foo}\" text node.\n * // The text of the node will be updated as the \"foo\" attribute changes.\n * new Template( {\n * \ttext: [\n * \t\t'static text: ',\n * \t\tbind.to( 'foo', () => { ... } )\n * \t]\n * } );\n * ```\n */\nexport type TemplateValueSchema = ArrayOrItem<\n\tTemplateSimpleValueSchema |\n\tNamespacedValue<TemplateSimpleValueSchema>\n> |\n\tRecord<string, TemplateSimpleValueSchema>;\n\n/**\n * Describes an event listener attached to an HTML element. Such listener can propagate DOM events\n * through an {@link module:utils/observablemixin~Observable} instance, execute custom callbacks\n * or both, if necessary.\n *\n * Also see:\n * * {@link module:ui/template~TemplateDefinition} to learn more about template definitions,\n * * {@link module:ui/template~BindChain#to `to()`} method to learn more about bindings.\n *\n * Check out different ways of attaching event listeners below:\n *\n * ```ts\n * // Bind helper will propagate events through the observable.\n * const bind = Template.bind( observable, emitter );\n *\n * new Template( {\n * \ttag: 'p',\n * \ton: {\n * \t\t// An object schema. The observable will fire the \"clicked\" event upon DOM \"click\".\n * \t\tclick: bind.to( 'clicked' )\n *\n * \t\t// An object schema. It will work for \"click\" event on \"a.foo\" children only.\n * \t\t'click@a.foo': bind.to( 'clicked' )\n *\n * \t\t// An array schema, makes the observable propagate multiple events.\n * \t\tclick: [\n * \t\t\tbind.to( 'clicked' ),\n * \t\t\tbind.to( 'executed' )\n * \t\t],\n *\n * \t\t// An array schema with a custom callback.\n * \t\t'click@a.foo': {\n * \t\t\tbind.to( 'clicked' ),\n * \t\t\tbind.to( evt => {\n * \t\t\t\tconsole.log( `${ evt.target } has been clicked!` );\n * \t\t\t} }\n * \t\t}\n * \t}\n * } );\n * ```\n */\nexport type TemplateListenerSchema = ArrayOrItem<ListenerBinding>;\n\n// `Template.bind( observable, emitter ).to( name )` is used in two different contexts:\n// - in `attribute` (or `text`) section of the `TemplateDefinition` - `name` is an observed property of the provided `observable`, or\n// - in `on` section - `name` is the event to be fired.\n//\n// In both cases, the returned type is `TemplateToBinding` which can be misleading.\n// Moreover, some forms of `to()` can be used in specific context only:\n// - `to( name, callback )` can only be used in `attribute` or `text`\n// - `to( callback )` can only be used in `on`.\n//\n// But note, that the fact it's `Template{To,If}Binding` is not relevant to the user.\n// The instances are both produced and consumed by this file only.\n// So let's invent some opaque types for outside use and only keep using `TemplateBinding` internally. They can be different for\n// `attribute` and `on` contexts.\n// To make them opaque, a non-exported symbol is used, so it's not possible to accidentally create an instance outside.\ndeclare const AttributeBindingSymbol: unique symbol;\ndeclare const ListenerBindingSymbol: unique symbol;\n\nexport interface AttributeBinding { _opaqueAttributeBinding: typeof AttributeBindingSymbol }\nexport interface ListenerBinding { _opaqueListenerBinding: typeof ListenerBindingSymbol }\n\n/**\n * The return value of {@link ~Template.bind `Template.bind()`}. It provides `to()` and `if()`\n * methods to create the {@link module:utils/observablemixin~Observable observable} attribute and event bindings.\n */\nexport interface BindChain<TObservable> {\n\n\t/**\n\t * Binds an {@link module:utils/observablemixin~Observable observable} to either:\n\t *\n\t * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable\n\t * attribute as it changes,\n\t * * or an HTML element DOM event, so the DOM events are propagated through an observable.\n\t *\n\t * Some common use cases of `to()` bindings are presented below:\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \ttag: 'p',\n\t * \tattributes: {\n\t * \t\t// class=\"...\" attribute gets bound to `observable#a`\n\t * \t\tclass: bind.to( 'a' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t// <p>...</p> gets bound to observable#b; always `toUpperCase()`.\n\t * \t\t{\n\t * \t\t\ttext: bind.to( 'b', ( value, node ) => value.toUpperCase() )\n\t * \t\t}\n\t * \t],\n\t * \ton: {\n\t * \t\tclick: [\n\t * \t\t\t// An observable will fire \"clicked\" upon \"click\" in the DOM.\n\t * \t\t\tbind.to( 'clicked' ),\n\t *\n\t * \t\t\t// A custom callback will be executed upon \"click\" in the DOM.\n\t * \t\t\tbind.to( () => {\n\t * \t\t\t\t...\n\t * \t\t\t} )\n\t * \t\t]\n\t * \t}\n\t * } ).render();\n\t * ```\n\t *\n\t * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and\n\t * {@link module:ui/template~TemplateListenerSchema}.\n\t *\n\t * @label ATTRIBUTE\n\t * @param attribute An attribute name of {@link module:utils/observablemixin~Observable}.\n\t */\n\tto<TAttribute extends keyof TObservable & string>(\n\t\tattribute: TAttribute\n\t): AttributeBinding & ListenerBinding;\n\n\t/**\n\t * Binds an {@link module:utils/observablemixin~Observable observable} to either:\n\t *\n\t * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable\n\t * attribute as it changes,\n\t * * or an HTML element DOM event, so the DOM events are propagated through an observable.\n\t *\n\t * Some common use cases of `to()` bindings are presented below:\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \ttag: 'p',\n\t * \tattributes: {\n\t * \t\t// class=\"...\" attribute gets bound to `observable#a`\n\t * \t\tclass: bind.to( 'a' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t// <p>...</p> gets bound to observable#b; always `toUpperCase()`.\n\t * \t\t{\n\t * \t\t\ttext: bind.to( 'b', ( value, node ) => value.toUpperCase() )\n\t * \t\t}\n\t * \t],\n\t * \ton: {\n\t * \t\tclick: [\n\t * \t\t\t// An observable will fire \"clicked\" upon \"click\" in the DOM.\n\t * \t\t\tbind.to( 'clicked' ),\n\t *\n\t * \t\t\t// A custom callback will be executed upon \"click\" in the DOM.\n\t * \t\t\tbind.to( () => {\n\t * \t\t\t\t...\n\t * \t\t\t} )\n\t * \t\t]\n\t * \t}\n\t * } ).render();\n\t * ```\n\t *\n\t * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and\n\t * {@link module:ui/template~TemplateListenerSchema}.\n\t *\n\t * @label ATTRIBUTE_CALLBACK\n\t * @param attribute An attribute name of {@link module:utils/observablemixin~Observable}.\n\t * @param callback Allows for processing of the value. Accepts `Node` and `value` as arguments.\n\t */\n\tto<TAttribute extends keyof TObservable & string>(\n\t\tattribute: TAttribute,\n\t\tcallback: ( value: TObservable[ TAttribute ], node: Node ) => ( TemplateSimpleValue )\n\t): AttributeBinding;\n\n\t/**\n\t * Binds an {@link module:utils/observablemixin~Observable observable} to either:\n\t *\n\t * * an HTML element attribute or a text node `textContent`, so it remains in sync with the observable\n\t * attribute as it changes,\n\t * * or an HTML element DOM event, so the DOM events are propagated through an observable.\n\t *\n\t * Some common use cases of `to()` bindings are presented below:\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \ttag: 'p',\n\t * \tattributes: {\n\t * \t\t// class=\"...\" attribute gets bound to `observable#a`\n\t * \t\tclass: bind.to( 'a' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t// <p>...</p> gets bound to observable#b; always `toUpperCase()`.\n\t * \t\t{\n\t * \t\t\ttext: bind.to( 'b', ( value, node ) => value.toUpperCase() )\n\t * \t\t}\n\t * \t],\n\t * \ton: {\n\t * \t\tclick: [\n\t * \t\t\t// An observable will fire \"clicked\" upon \"click\" in the DOM.\n\t * \t\t\tbind.to( 'clicked' ),\n\t *\n\t * \t\t\t// A custom callback will be executed upon \"click\" in the DOM.\n\t * \t\t\tbind.to( () => {\n\t * \t\t\t\t...\n\t * \t\t\t} )\n\t * \t\t]\n\t * \t}\n\t * } ).render();\n\t * ```\n\t *\n\t * Learn more about using `to()` in the {@link module:ui/template~TemplateValueSchema} and\n\t * {@link module:ui/template~TemplateListenerSchema}.\n\t *\n\t * @label EVENT\n\t * @param eventNameOrCallback A DOM event name or an event callback.\n\t */\n\tto( eventNameOrCallback: string | ( ( domEvent: Event ) => void ) ): ListenerBinding;\n\n\t/**\n\t * Binds an {@link module:utils/observablemixin~Observable observable} to an HTML element attribute or a text\n\t * node `textContent` so it remains in sync with the observable attribute as it changes.\n\t *\n\t * Unlike {@link module:ui/template~BindChain#to}, it controls the presence of the attribute or `textContent`\n\t * depending on the \"falseness\" of an {@link module:utils/observablemixin~Observable} attribute.\n\t *\n\t * ```ts\n\t * const bind = Template.bind( observable, emitter );\n\t *\n\t * new Template( {\n\t * \ttag: 'input',\n\t * \tattributes: {\n\t * \t\t// <input checked> when `observable#a` is not undefined/null/false/''\n\t * \t\t// <input> when `observable#a` is undefined/null/false\n\t * \t\tchecked: bind.if( 'a' )\n\t * \t},\n\t * \tchildren: [\n\t * \t\t{\n\t * \t\t\t// <input>\"b-is-not-set\"</input> when `observable#b` is undefined/null/false/''\n\t * \t\t\t// <input></input> when `observable#b` is not \"falsy\"\n\t * \t\t\ttext: bind.if( 'b', 'b-is-not-set', ( value, node ) => !value )\n\t * \t\t}\n\t * \t]\n\t * } ).render();\n\t * ```\n\t *\n\t * Learn more about using `if()` in the {@link module:ui/template~TemplateValueSchema}.\n\t *\n\t * @param attribute An attribute name of {@link module:utils/observablemixin~Observable} used in the binding.\n\t * @param valueIfTrue Value set when the {@link module:utils/observablemixin~Observable} attribute is not\n\t * undefined/null/false/'' (empty string).\n\t * @param callback Allows for processing of the value. Accepts `Node` and `value` as arguments.\n\t */\n\tif<TAttribute extends keyof TObservable & string>(\n\t\tattribute: TAttribute,\n\t\tvalueIfTrue?: unknown,\n\t\tcallback?: ( value: TObservable[ TAttribute ], node: Node ) => ( boolean | FalsyValue )\n\t): AttributeBinding;\n}\n\n/**\n * The {@link module:ui/template~Template#_renderNode} configuration.\n */\nexport interface RenderData {\n\n\t/**\n\t * A node which is being rendered.\n\t */\n\tnode: HTMLElement | Text;\n\n\t/**\n\t * Tells {@link module:ui/template~Template#_renderNode} to render\n\t * children into `DocumentFragment` first and then append the fragment\n\t * to the parent element. It is a speed optimization.\n\t */\n\tintoFragment: boolean;\n\n\t/**\n\t * Indicates whether the {@link #node} has been provided by {@link module:ui/template~Template#apply}.\n\t */\n\tisApplying: boolean;\n\n\t/**\n\t * An object storing the data that helps {@link module:ui/template~Template#revert}\n\t * bringing back an element to its initial state, i.e. before\n\t * {@link module:ui/template~Template#apply} was called.\n\t */\n\trevertData?: RevertData;\n}\n\ninterface RevertData {\n\ttext?: string | null;\n\tchildren: Array<RevertData>;\n\tbindings: Array<Array<() => void>>;\n\tattributes: Record<string, string | null>;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* eslint-disable @typescript-eslint/no-invalid-void-type */\n\n/**\n * @module ui/view\n */\n\nimport ViewCollection from './viewcollection.js';\nimport Template, { type BindChain, type TemplateDefinition } from './template.js';\n\nimport {\n\tCKEditorError,\n\tCollection,\n\tDomEmitterMixin,\n\tObservableMixin,\n\tisIterable,\n\ttype CollectionAddEvent,\n\ttype DecoratedMethodEvent,\n\ttype Locale,\n\ttype LocaleTranslate\n} from '@ckeditor/ckeditor5-utils';\n\nimport '../theme/globals/globals.css';\n\n/**\n * The basic view class, which represents an HTML element created out of a\n * {@link module:ui/view~View#template}. Views are building blocks of the user interface and handle\n * interaction\n *\n * Views {@link module:ui/view~View#registerChild aggregate} children in\n * {@link module:ui/view~View#createCollection collections} and manage the life cycle of DOM\n * listeners e.g. by handling rendering and destruction.\n *\n * See the {@link module:ui/template~TemplateDefinition} syntax to learn more about shaping view\n * elements, attributes and listeners.\n *\n * ```ts\n * class SampleView extends View {\n * \tconstructor( locale ) {\n * \t\tsuper( locale );\n *\n * \t\tconst bind = this.bindTemplate;\n *\n * \t\t// Views define their interface (state) using observable attributes.\n * \t\tthis.set( 'elementClass', 'bar' );\n *\n * \t\tthis.setTemplate( {\n * \t\t\ttag: 'p',\n *\n * \t\t\t// The element of the view can be defined with its children.\n * \t\t\tchildren: [\n * \t\t\t\t'Hello',\n * \t\t\t\t{\n * \t\t\t\t\ttag: 'b',\n * \t\t\t\t\tchildren: [ 'world!' ]\n * \t\t\t\t}\n * \t\t\t],\n * \t\t\tattributes: {\n * \t\t\t\tclass: [\n * \t\t\t\t\t'foo',\n *\n * \t\t\t\t\t// Observable attributes control the state of the view in DOM.\n * \t\t\t\t\tbind.to( 'elementClass' )\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\ton: {\n * \t\t\t\t// Views listen to DOM events and propagate them.\n * \t\t\t\tclick: bind.to( 'clicked' )\n * \t\t\t}\n * \t\t} );\n * \t}\n * }\n *\n * const view = new SampleView( locale );\n *\n * view.render();\n *\n * // Append <p class=\"foo bar\">Hello<b>world</b></p> to the <body>\n * document.body.appendChild( view.element );\n *\n * // Change the class attribute to <p class=\"foo baz\">Hello<b>world</b></p>\n * view.elementClass = 'baz';\n *\n * // Respond to the \"click\" event in DOM by executing a custom action.\n * view.on( 'clicked', () => {\n * \tconsole.log( 'The view has been clicked!' );\n * } );\n * ```\n */\nexport default class View<TElement extends HTMLElement = HTMLElement>\n\textends /* #__PURE__ */ DomEmitterMixin( /* #__PURE__ */ ObservableMixin() )\n{\n\t/**\n\t * An HTML element of the view. `null` until {@link #render rendered}\n\t * from the {@link #template}.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor() {\n\t * \t\tsuper();\n\t *\n\t * \t\t// A template instance the #element will be created from.\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p'\n\t *\n\t * \t\t\t// ...\n\t * \t\t} );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView();\n\t *\n\t * // Renders the #template.\n\t * view.render();\n\t *\n\t * // Append the HTML element of the view to <body>.\n\t * document.body.appendChild( view.element );\n\t * ```\n\t *\n\t * **Note**: The element of the view can also be assigned directly:\n\t *\n\t * ```ts\n\t * view.element = document.querySelector( '#my-container' );\n\t * ```\n\t */\n\tpublic element: TElement | null;\n\n\t/**\n\t * Set `true` when the view has already been {@link module:ui/view~View#render rendered}.\n\t *\n\t * @readonly\n\t */\n\tpublic isRendered: boolean;\n\n\t/**\n\t * A set of tools to localize the user interface.\n\t *\n\t * Also see {@link module:core/editor/editor~Editor#locale}.\n\t *\n\t * @readonly\n\t */\n\tpublic locale: Locale | undefined;\n\n\t/**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t *\n\t * Note: If {@link #locale} instance hasn't been passed to the view this method may not\n\t * be available.\n\t *\n\t * @see module:utils/locale~Locale#t\n\t */\n\tpublic t: LocaleTranslate | undefined;\n\n\t/**\n\t * Template of this view. It provides the {@link #element} representing\n\t * the view in DOM, which is {@link #render rendered}.\n\t */\n\tpublic template?: Template;\n\n\tpublic declare viewUid?: string;\n\n\t/**\n\t * Collections registered with {@link #createCollection}.\n\t */\n\tprotected _viewCollections: Collection<ViewCollection>;\n\n\t/**\n\t * A collection of view instances, which have been added directly\n\t * into the {@link module:ui/template~Template#children}.\n\t */\n\tprotected _unboundChildren: ViewCollection;\n\n\t/**\n\t * Cached {@link module:ui/template~BindChain bind chain} object created by the\n\t * {@link #template}. See {@link #bindTemplate}.\n\t */\n\tprivate _bindTemplate?: BindChain<this>;\n\n\t/**\n\t * Creates an instance of the {@link module:ui/view~View} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper();\n\n\t\tthis.element = null;\n\t\tthis.isRendered = false;\n\n\t\tthis.locale = locale;\n\t\tthis.t = locale && locale.t;\n\n\t\tthis._viewCollections = new Collection();\n\t\tthis._unboundChildren = this.createCollection();\n\n\t\t// Pass parent locale to its children.\n\t\tthis._viewCollections.on<CollectionAddEvent<View>>( 'add', ( evt, collection ) => {\n\t\t\tcollection.locale = locale;\n\t\t\tcollection.t = locale && locale.t;\n\t\t} );\n\n\t\tthis.decorate( 'render' );\n\t}\n\n\t/**\n\t * Shorthand for {@link module:ui/template~Template.bind}, a binding\n\t * {@link module:ui/template~BindChain interface} pre–configured for the view instance.\n\t *\n\t * It provides {@link module:ui/template~BindChain#to `to()`} and\n\t * {@link module:ui/template~BindChain#if `if()`} methods that initialize bindings with\n\t * observable attributes and attach DOM listeners.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tconst bind = this.bindTemplate;\n\t *\n\t * \t\t// These {@link module:utils/observablemixin~Observable observable} attributes will control\n\t * \t\t// the state of the view in DOM.\n\t * \t\tthis.set( {\n\t * \t\t\telementClass: 'foo',\n\t * \t\t \tisEnabled: true\n\t * \t\t } );\n\t *\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p',\n\t *\n\t * \t\t\tattributes: {\n\t * \t\t\t\t// The class HTML attribute will follow elementClass\n\t * \t\t\t\t// and isEnabled view attributes.\n\t * \t\t\t\tclass: [\n\t * \t\t\t\t\tbind.to( 'elementClass' )\n\t * \t\t\t\t\tbind.if( 'isEnabled', 'present-when-enabled' )\n\t * \t\t\t\t]\n\t * \t\t\t},\n\t *\n\t * \t\t\ton: {\n\t * \t\t\t\t// The view will fire the \"clicked\" event upon clicking <p> in DOM.\n\t * \t\t\t\tclick: bind.to( 'clicked' )\n\t * \t\t\t}\n\t * \t\t} );\n\t * \t}\n\t * }\n\t * ```\n\t */\n\tpublic get bindTemplate(): BindChain<this> {\n\t\tif ( this._bindTemplate ) {\n\t\t\treturn this._bindTemplate;\n\t\t}\n\n\t\treturn ( this._bindTemplate = Template.bind( this, this ) );\n\t}\n\n\t/**\n\t * Creates a new collection of views, which can be used as\n\t * {@link module:ui/template~Template#children} of this view.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tconst child = new ChildView( locale );\n\t * \t\tthis.items = this.createCollection( [ child ] );\n \t *\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p',\n\t *\n\t * \t\t\t// `items` collection will render here.\n\t * \t\t\tchildren: this.items\n\t * \t\t} );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView( locale );\n\t * view.render();\n\t *\n\t * // It will append <p><child#element></p> to the <body>.\n\t * document.body.appendChild( view.element );\n\t * ```\n\t *\n\t * @param views Initial views of the collection.\n\t * @returns A new collection of view instances.\n\t */\n\tpublic createCollection<T extends View = View>( views?: Iterable<T> ): ViewCollection<T> {\n\t\tconst collection = new ViewCollection<T>( views );\n\n\t\tthis._viewCollections.add( collection );\n\n\t\treturn collection;\n\t}\n\n\t/**\n\t * Registers a new child view under the view instance. Once registered, a child\n\t * view is managed by its parent, including {@link #render rendering}\n\t * and {@link #destroy destruction}.\n\t *\n\t * To revert this, use {@link #deregisterChild}.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tthis.childA = new SomeChildView( locale );\n\t * \t\tthis.childB = new SomeChildView( locale );\n\t *\n\t * \t\tthis.setTemplate( { tag: 'p' } );\n\t *\n\t * \t\t// Register the children.\n\t * \t\tthis.registerChild( [ this.childA, this.childB ] );\n\t * \t}\n\t *\n\t * \trender() {\n\t * \t\tsuper.render();\n\t *\n\t * \t\tthis.element.appendChild( this.childA.element );\n\t * \t\tthis.element.appendChild( this.childB.element );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView( locale );\n\t *\n\t * view.render();\n\t *\n\t * // Will append <p><childA#element><b></b><childB#element></p>.\n\t * document.body.appendChild( view.element );\n\t * ```\n\t *\n\t * **Note**: There's no need to add child views if they're already referenced in the\n\t * {@link #template}:\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor( locale ) {\n\t * \t\tsuper( locale );\n\t *\n\t * \t\tthis.childA = new SomeChildView( locale );\n\t * \t\tthis.childB = new SomeChildView( locale );\n\t *\n\t * \t\tthis.setTemplate( {\n\t * \t\t\ttag: 'p',\n\t *\n \t * \t\t\t// These children will be added automatically. There's no\n \t * \t\t\t// need to call {@link #registerChild} for any of them.\n\t * \t\t\tchildren: [ this.childA, this.childB ]\n\t * \t\t} );\n\t * \t}\n\t *\n\t * \t// ...\n\t * }\n\t * ```\n\t *\n\t * @param children Children views to be registered.\n\t */\n\tpublic registerChild( children: View | Iterable<View> ): void {\n\t\tif ( !isIterable( children ) ) {\n\t\t\tchildren = [ children ];\n\t\t}\n\n\t\tfor ( const child of children ) {\n\t\t\tthis._unboundChildren.add( child );\n\t\t}\n\t}\n\n\t/**\n\t * The opposite of {@link #registerChild}. Removes a child view from this view instance.\n\t * Once removed, the child is no longer managed by its parent, e.g. it can safely\n\t * become a child of another parent view.\n\t *\n\t * @see #registerChild\n\t * @param children Child views to be removed.\n\t */\n\tpublic deregisterChild( children: View | Iterable<View> ): void {\n\t\tif ( !isIterable( children ) ) {\n\t\t\tchildren = [ children ];\n\t\t}\n\n\t\tfor ( const child of children ) {\n\t\t\tthis._unboundChildren.remove( child );\n\t\t}\n\t}\n\n\t/**\n\t * Sets the {@link #template} of the view with with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t * ```ts\n\t * view.setTemplate( definition );\n\t * ```\n\t *\n\t * @param definition Definition of view's template.\n\t */\n\tpublic setTemplate( definition: TemplateDefinition ): void {\n\t\tthis.template = new Template( definition );\n\t}\n\n\t/**\n\t * {@link module:ui/template~Template.extend Extends} the {@link #template} of the view with\n\t * with given definition.\n\t *\n\t * A shorthand for:\n\t *\n\t * ```ts\n\t * Template.extend( view.template, definition );\n\t * ```\n\t *\n\t * **Note**: Is requires the {@link #template} to be already set. See {@link #setTemplate}.\n\t *\n\t * @param definition Definition which extends the {@link #template}.\n\t */\n\tpublic extendTemplate( definition: Partial<TemplateDefinition> ): void {\n\t\tTemplate.extend( this.template!, definition );\n\t}\n\n\t/**\n\t * Recursively renders the view.\n\t *\n\t * Once the view is rendered:\n\t * * the {@link #element} becomes an HTML element out of {@link #template},\n\t * * the {@link #isRendered} flag is set `true`.\n\t *\n\t * **Note**: The children of the view:\n\t * * defined directly in the {@link #template}\n\t * * residing in collections created by the {@link #createCollection} method,\n\t * * and added by {@link #registerChild}\n\t * are also rendered in the process.\n\t *\n\t * In general, `render()` method is the right place to keep the code which refers to the\n\t * {@link #element} and should be executed at the very beginning of the view's life cycle.\n\t *\n\t * It is possible to {@link module:ui/template~Template.extend} the {@link #template} before\n\t * the view is rendered. To allow an early customization of the view (e.g. by its parent),\n\t * such references should be done in `render()`.\n\t *\n\t * ```ts\n\t * class SampleView extends View {\n\t * \tconstructor() {\n\t * \t\tthis.setTemplate( {\n\t * \t\t\t// ...\n\t * \t\t} );\n\t * \t},\n\t *\n\t * \trender() {\n\t * \t\t// View#element becomes available.\n\t * \t\tsuper.render();\n\t *\n\t * \t\t// The \"scroll\" listener depends on #element.\n\t * \t\tthis.listenTo( window, 'scroll', () => {\n\t * \t\t\t// A reference to #element would render the #template and make it non-extendable.\n\t * \t\t\tif ( window.scrollY > 0 ) {\n\t * \t\t\t\tthis.element.scrollLeft = 100;\n\t * \t\t\t} else {\n\t * \t\t\t\tthis.element.scrollLeft = 0;\n\t * \t\t\t}\n\t * \t\t} );\n\t * \t}\n\t * }\n\t *\n\t * const view = new SampleView();\n\t *\n\t * // Let's customize the view before it gets rendered.\n\t * view.extendTemplate( {\n\t * \tattributes: {\n\t * \t\tclass: [\n\t * \t\t\t'additional-class'\n\t * \t\t]\n\t * \t}\n\t * } );\n\t *\n\t * // Late rendering allows customization of the view.\n\t * view.render();\n\t * ```\n\t */\n\tpublic render(): void {\n\t\tif ( this.isRendered ) {\n\t\t\t/**\n\t\t\t * This View has already been rendered.\n\t\t\t *\n\t\t\t * @error ui-view-render-already-rendered\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-view-render-already-rendered', this );\n\t\t}\n\n\t\t// Render #element of the view.\n\t\tif ( this.template ) {\n\t\t\tthis.element = this.template.render() as TElement;\n\n\t\t\t// Auto–register view children from #template.\n\t\t\tthis.registerChild( this.template.getViews() );\n\t\t}\n\n\t\tthis.isRendered = true;\n\t}\n\n\t/**\n\t * Recursively destroys the view instance and child views added by {@link #registerChild} and\n\t * residing in collections created by the {@link #createCollection}.\n\t *\n\t * Destruction disables all event listeners:\n\t * * created on the view, e.g. `view.on( 'event', () => {} )`,\n\t * * defined in the {@link #template} for DOM events.\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\n\t\tthis._viewCollections.map( c => c.destroy() );\n\n\t\t// Template isn't obligatory for views.\n\t\tif ( this.template && ( this.template as any )._revertData ) {\n\t\t\tthis.template.revert( this.element! );\n\t\t}\n\t}\n}\n\n/**\n * Event fired by the {@link module:ui/view~View#render} method. Actual rendering is executed as a listener to\n * this event with the default priority.\n *\n * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.\n *\n * @eventName ~View#render\n */\nexport type UIViewRenderEvent = DecoratedMethodEvent<View, 'render'>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/bindings/clickoutsidehandler\n */\n\nimport type { CallbackOptions, DomEmitter } from '@ckeditor/ckeditor5-utils';\n\n/* global document */\n\n/**\n * Handles clicking **outside** of a specified set of elements, then fires an action.\n *\n * **Note**: Actually, the action is executed upon `mousedown`, not `click`. It prevents\n * certain issues when the user keeps holding the mouse button and the UI cannot react\n * properly.\n *\n * @param options Configuration options.\n * @param options.emitter The emitter to which this behavior should be added.\n * @param options.activator Function returning a `Boolean`, to determine whether the handler is active.\n * @param options.contextElements Array of HTML elements or a callback returning an array of HTML elements\n * that determine the scope of the handler. Clicking any of them or their descendants will **not** fire the callback.\n * @param options.callback An action executed by the handler.\n * @param options.listenerOptions Additional options for the listener (like priority).\n */\nexport default function clickOutsideHandler(\n\t{ emitter, activator, callback, contextElements, listenerOptions }: {\n\t\temitter: DomEmitter;\n\t\tactivator: () => boolean;\n\t\tcontextElements: Array<Element> | ( () => Array<Element> );\n\t\tcallback: () => void;\n\t\tlistenerOptions?: CallbackOptions;\n\t}\n): void {\n\temitter.listenTo( document, 'mousedown', ( evt, domEvt ) => {\n\t\tif ( !activator() ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if `composedPath` is `undefined` in case the browser does not support native shadow DOM.\n\t\t// Can be removed when all supported browsers support native shadow DOM.\n\t\tconst path = typeof domEvt.composedPath == 'function' ? domEvt.composedPath() : [];\n\n\t\tconst contextElementsList = typeof contextElements == 'function' ? contextElements() : contextElements;\n\n\t\tfor ( const contextElement of contextElementsList ) {\n\t\t\tif ( contextElement.contains( domEvt.target as Node ) || path.includes( contextElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tcallback();\n\t}, listenerOptions );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/bindings/injectcsstransitiondisabler\n */\n\nimport type View from '../view.js';\nimport type { ViewWithCssTransitionDisabler } from './csstransitiondisablermixin.js';\n\n/**\n * A decorator that brings the possibility to temporarily disable CSS transitions using\n * {@link module:ui/view~View} methods. It is helpful when, for instance, the transitions should not happen\n * when the view is first displayed but they should work normal in other cases.\n *\n * The methods to control the CSS transitions are:\n * * `disableCssTransitions()` – Adds the `.ck-transitions-disabled` class to the\n * {@link module:ui/view~View#element view element}.\n * * `enableCssTransitions()` – Removes the `.ck-transitions-disabled` class from the\n * {@link module:ui/view~View#element view element}.\n *\n * **Note**: This helper extends the {@link module:ui/view~View#template template} and must be used **after**\n * {@link module:ui/view~View#setTemplate} is called:\n *\n * ```ts\n * import injectCssTransitionDisabler from '@ckeditor/ckeditor5-ui/src/bindings/injectcsstransitiondisabler';\n *\n * class MyView extends View {\n * \tconstructor() {\n * \t\tsuper();\n *\n * \t\t// ...\n *\n * \t\tthis.setTemplate( { ... } );\n *\n * \t\t// ...\n *\n * \t\tinjectCssTransitionDisabler( this );\n *\n * \t\t// ...\n * \t}\n * }\n * ```\n *\n * The usage comes down to:\n *\n * ```ts\n * const view = new MyView();\n *\n * // ...\n *\n * view.disableCssTransitions();\n * view.show();\n * view.enableCssTransitions();\n * ```\n *\n * @deprecated\n * @see module:ui/bindings/csstransitiondisablermixin~CssTransitionDisablerMixin\n * @param view View instance that should get this functionality.\n */\nexport default function injectCssTransitionDisabler( view: View ): void {\n\tconst decorated = view as ViewWithCssTransitionDisabler & { _isCssTransitionsDisabled: boolean };\n\n\tdecorated.set( '_isCssTransitionsDisabled', false );\n\n\tdecorated.disableCssTransitions = () => {\n\t\tdecorated._isCssTransitionsDisabled = true;\n\t};\n\n\tdecorated.enableCssTransitions = () => {\n\t\tdecorated._isCssTransitionsDisabled = false;\n\t};\n\n\tdecorated.extendTemplate( {\n\t\tattributes: {\n\t\t\tclass: [\n\t\t\t\tdecorated.bindTemplate.if( '_isCssTransitionsDisabled', 'ck-transitions-disabled' )\n\t\t\t]\n\t\t}\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/bindings/csstransitiondisablermixin\n */\n\nimport type { Constructor, Mixed } from '@ckeditor/ckeditor5-utils';\n\nimport type View from '../view.js';\n\n/**\n * A mixin that brings the possibility to temporarily disable CSS transitions using\n * {@link module:ui/view~View} methods. It is helpful when, for instance, the transitions should not happen\n * when the view is first displayed but they should work normal in other cases.\n *\n * The methods to control the CSS transitions are:\n * * `disableCssTransitions()` – Adds the `.ck-transitions-disabled` class to the\n * {@link module:ui/view~View#element view element}.\n * * `enableCssTransitions()` – Removes the `.ck-transitions-disabled` class from the\n * {@link module:ui/view~View#element view element}.\n *\n * The usage comes down to:\n *\n * ```ts\n * const MyViewWithCssTransitionDisabler = CssTransitionDisablerMixin( MyView );\n * const view = new MyViewWithCssTransitionDisabler();\n *\n * // ...\n *\n * view.disableCssTransitions();\n * view.show();\n * view.enableCssTransitions();\n * ```\n *\n * @param view View instance that should get this functionality.\n */\nexport default function CssTransitionDisablerMixin<Base extends Constructor<View>>( view: Base ): Mixed<Base, ViewWithCssTransitionDisabler>\n{\n\tabstract class Mixin extends view {\n\t\tdeclare public _isCssTransitionsDisabled: boolean;\n\n\t\tpublic disableCssTransitions() {\n\t\t\tthis._isCssTransitionsDisabled = true;\n\t\t}\n\n\t\tpublic enableCssTransitions() {\n\t\t\tthis._isCssTransitionsDisabled = false;\n\t\t}\n\n\t\tconstructor( ...args: Array<any> ) {\n\t\t\tsuper( ...args );\n\n\t\t\tthis.set( '_isCssTransitionsDisabled', false );\n\t\t\tthis.initializeCssTransitionDisablerMixin();\n\t\t}\n\n\t\tprotected initializeCssTransitionDisablerMixin(): void {\n\t\t\tthis.extendTemplate( {\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: [\n\t\t\t\t\t\tthis.bindTemplate.if( '_isCssTransitionsDisabled', 'ck-transitions-disabled' )\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\treturn Mixin as any;\n}\n\nexport type ViewWithCssTransitionDisabler = View & {\n\tdisableCssTransitions(): void;\n\tenableCssTransitions(): void;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/bindings/submithandler\n */\n\nimport type View from '../view.js';\n\n/**\n * A handler useful for {@link module:ui/view~View views} working as HTML forms. It intercepts a native DOM\n * `submit` event, prevents the default web browser behavior (navigation and page reload) and\n * fires the `submit` event on a view instead. Such a custom event can be then used by any\n * {@link module:utils/dom/emittermixin~DomEmitter emitter}, e.g. to serialize the form data.\n *\n * ```ts\n * import submitHandler from '@ckeditor/ckeditor5-ui/src/bindings/submithandler';\n *\n * // ...\n *\n * class AnyFormView extends View {\n * \tconstructor() {\n * \t\tsuper();\n *\n * \t\t// ...\n *\n * \t\tsubmitHandler( {\n * \t\t\tview: this\n * \t\t} );\n * \t}\n * }\n *\n * // ...\n *\n * const view = new AnyFormView();\n *\n * // A sample listener attached by an emitter working with the view.\n * this.listenTo( view, 'submit', () => {\n * \tsaveTheFormData();\n * \thideTheForm();\n * } );\n * ```\n *\n * @param options Configuration options.\n * @param options.view The view which DOM `submit` events should be handled.\n */\nexport default function submitHandler( { view }: { view: View } ): void {\n\tview.listenTo( view.element!, 'submit', ( evt, domEvt ) => {\n\t\tdomEvt.preventDefault();\n\t\tview.fire<SubmitHandlerEvent>( 'submit' );\n\t}, { useCapture: true } );\n}\n\n/**\n * Fired by {@link module:ui/bindings/submithandler~submitHandler} helper.\n *\n * @eventName module:ui/view~View#submit\n */\nexport type SubmitHandlerEvent = {\n\tname: 'submit';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/bindings/addkeyboardhandlingforgrid\n */\n\nimport type { FocusTracker, KeystrokeHandler } from '@ckeditor/ckeditor5-utils';\nimport type { FocusableView } from '../focuscycler.js';\nimport type ViewCollection from '../viewcollection.js';\n\n/**\n * A helper that adds a keyboard navigation support (arrow up/down/left/right) for grids.\n *\n * @param options Configuration options.\n * @param options.keystrokeHandler Keystroke handler to register navigation with arrow keys.\n * @param options.focusTracker A focus tracker for grid elements.\n * @param options.gridItems A collection of grid items.\n * @param options.numberOfColumns Number of columns in the grid. Can be specified as a function that returns\n * the number (e.g. for responsive grids).\n * @param options.uiLanguageDirection String of ui language direction.\n */\nexport default function addKeyboardHandlingForGrid(\n\t{ keystrokeHandler, focusTracker, gridItems, numberOfColumns, uiLanguageDirection }: {\n\t\tkeystrokeHandler: KeystrokeHandler;\n\t\tfocusTracker: FocusTracker;\n\t\tgridItems: ViewCollection;\n\t\tnumberOfColumns: number | ( () => number );\n\t\tuiLanguageDirection?: string;\n\t}\n): void {\n\tconst getNumberOfColumns = typeof numberOfColumns === 'number' ? () => numberOfColumns : numberOfColumns;\n\n\tkeystrokeHandler.set( 'arrowright', getGridItemFocuser( ( focusedElementIndex, gridItems ) => {\n\t\treturn uiLanguageDirection === 'rtl' ?\n\t\t\tgetLeftElementIndex( focusedElementIndex, gridItems.length ) :\n\t\t\tgetRightElementIndex( focusedElementIndex, gridItems.length );\n\t} ) );\n\n\tkeystrokeHandler.set( 'arrowleft', getGridItemFocuser( ( focusedElementIndex, gridItems ) => {\n\t\treturn uiLanguageDirection === 'rtl' ?\n\t\t\tgetRightElementIndex( focusedElementIndex, gridItems.length ) :\n\t\t\tgetLeftElementIndex( focusedElementIndex, gridItems.length );\n\t} ) );\n\n\tkeystrokeHandler.set( 'arrowup', getGridItemFocuser( ( focusedElementIndex, gridItems ) => {\n\t\tlet nextIndex = focusedElementIndex - getNumberOfColumns();\n\n\t\tif ( nextIndex < 0 ) {\n\t\t\tnextIndex = focusedElementIndex + getNumberOfColumns() * Math.floor( gridItems.length / getNumberOfColumns() );\n\n\t\t\tif ( nextIndex > gridItems.length - 1 ) {\n\t\t\t\tnextIndex -= getNumberOfColumns();\n\t\t\t}\n\t\t}\n\n\t\treturn nextIndex;\n\t} ) );\n\n\tkeystrokeHandler.set( 'arrowdown', getGridItemFocuser( ( focusedElementIndex, gridItems ) => {\n\t\tlet nextIndex = focusedElementIndex + getNumberOfColumns();\n\n\t\tif ( nextIndex > gridItems.length - 1 ) {\n\t\t\tnextIndex = focusedElementIndex % getNumberOfColumns();\n\t\t}\n\n\t\treturn nextIndex;\n\t} ) );\n\n\tfunction getGridItemFocuser( getIndexToFocus: ( focusedElementIndex: number, gridItems: ViewCollection ) => number ) {\n\t\treturn ( evt: KeyboardEvent ) => {\n\t\t\tconst focusedElement = gridItems.find( item => item.element === focusTracker.focusedElement );\n\t\t\tconst focusedElementIndex = gridItems.getIndex( focusedElement! );\n\t\t\tconst nextIndexToFocus = getIndexToFocus( focusedElementIndex, gridItems );\n\n\t\t\t( gridItems.get( nextIndexToFocus ) as FocusableView ).focus();\n\n\t\t\tevt.stopPropagation();\n\t\t\tevt.preventDefault();\n\t\t};\n\t}\n\n\t/**\n\t * Function returning the next index.\n\t *\n\t * ```\n\t * before: [ ][x][ ]\tafter: [ ][ ][x]\n\t * index = 1            index = 2\n\t * ```\n\t *\n\t * If current index is last, function returns first index.\n\t *\n\t * ```\n\t * before: [ ][ ][x]\tafter: [x][ ][ ]\n\t * index = 2            index = 0\n\t * ```\n\t *\n\t * @param elementIndex Number of current index.\n\t * @param collectionLength A count of collection items.\n\t */\n\tfunction getRightElementIndex( elementIndex: number, collectionLength: number ) {\n\t\tif ( elementIndex === collectionLength - 1 ) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn elementIndex + 1;\n\t\t}\n\t}\n\n\t/**\n\t * Function returning the previous index.\n\t *\n\t * ```\n\t * before: [ ][x][ ]\tafter: [x][ ][ ]\n\t * index = 1            index = 0\n\t * ```\n\t *\n\t * If current index is first, function returns last index.\n\t *\n\t * ```\n\t * before: [x][ ][ ]\tafter: [ ][ ][x]\n\t * index = 0            index = 2\n\t * ```\n\t *\n\t * @param elementIndex Number of current index.\n\t * @param collectionLength A count of collection items.\n\t */\n\tfunction getLeftElementIndex( elementIndex: number, collectionLength: number ) {\n\t\tif ( elementIndex === 0 ) {\n\t\t\treturn collectionLength - 1;\n\t\t} else {\n\t\t\treturn elementIndex - 1;\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* global DOMParser */\n\n/**\n * @module ui/icon/iconview\n */\n\nimport View from '../view.js';\n\nimport type { ObservableChangeEvent } from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/icon/icon.css';\n\n/**\n * The icon view class.\n */\nexport default class IconView extends View {\n\t/**\n\t * The SVG source of the icon.\n\t *\n\t * The user must provide the entire XML string, not just the path. See the\n\t * {@glink framework/architecture/ui-library#setting-label-icon-and-tooltip UI library} guide for details.\n\t *\n\t * @observable\n\t */\n\tdeclare public content: string | undefined;\n\n\t/**\n\t * This attribute specifies the boundaries to which the\n\t * icon content should stretch.\n\t *\n\t * @observable\n\t * @default '0 0 20 20'\n\t */\n\tdeclare public viewBox: string;\n\n\t/**\n\t * The fill color of the child `path.ck-icon__fill`.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public fillColor: string;\n\n\t/**\n\t * When set true (default), all parts of the icon inherit the fill color from the CSS `color` property of the\n\t * icon's DOM parent.\n\t *\n\t * This effectively makes the icon monochromatic and allows it to change its fill color dynamically, for instance,\n\t * when a {@link module:ui/button/buttonview~ButtonView} displays an icon and it switches between different states\n\t * (pushed, hovered, etc.) the icon will follow along.\n\t *\n\t * **Note**: For the monochromatic icon to render properly, it must be made up of shapes that can be filled\n\t * with color instead of, for instance, paths with strokes. Be sure to use the *outline stroke* tool\n\t * (the name could be different in your vector graphics editor) before exporting your icon. Also, remove any\n\t * excess `fill=\"...\"` attributes that could break the color inheritance.\n\t *\n\t * **Note**: If you want to preserve the original look of your icon and disable dynamic color inheritance,\n\t * set this flag to `false`.\n\t *\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public isColorInherited: boolean;\n\n\t/**\n\t * Controls whether the icon is visible.\n\t *\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * A list of presentational attributes that can be set on the `<svg>` element and should be preserved\n\t * when the icon {@link module:ui/icon/iconview~IconView#content content} is loaded.\n\t *\n\t * See the [specification](https://www.w3.org/TR/SVG/styling.html#TermPresentationAttribute) to learn more.\n\t */\n\tprivate static presentationalAttributeNames: Array<string> = [\n\t\t'alignment-baseline', 'baseline-shift', 'clip-path', 'clip-rule', 'color', 'color-interpolation',\n\t\t'color-interpolation-filters', 'color-rendering', 'cursor', 'direction', 'display', 'dominant-baseline', 'fill', 'fill-opacity',\n\t\t'fill-rule', 'filter', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style',\n\t\t'font-variant', 'font-weight', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start',\n\t\t'mask', 'opacity', 'overflow', 'paint-order', 'pointer-events', 'shape-rendering', 'stop-color', 'stop-opacity', 'stroke',\n\t\t'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width',\n\t\t'text-anchor', 'text-decoration', 'text-overflow', 'text-rendering', 'transform', 'unicode-bidi', 'vector-effect',\n\t\t'visibility', 'white-space', 'word-spacing', 'writing-mode'\n\t];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'content', '' );\n\t\tthis.set( 'viewBox', '0 0 20 20' );\n\t\tthis.set( 'fillColor', '' );\n\t\tthis.set( 'isColorInherited', true );\n\t\tthis.set( 'isVisible', true );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'svg',\n\t\t\tns: 'http://www.w3.org/2000/svg',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-icon',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value ),\n\n\t\t\t\t\t// Exclude icon internals from the CSS reset to allow rich (non-monochromatic) icons\n\t\t\t\t\t// (https://github.com/ckeditor/ckeditor5/issues/12599).\n\t\t\t\t\t'ck-reset_all-excluded',\n\n\t\t\t\t\t// The class to remove the dynamic color inheritance is toggleable\n\t\t\t\t\t// (https://github.com/ckeditor/ckeditor5/issues/12599).\n\t\t\t\t\tbind.if( 'isColorInherited', 'ck-icon_inherit-color' )\n\t\t\t\t],\n\t\t\t\tviewBox: bind.to( 'viewBox' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis._updateXMLContent();\n\t\tthis._colorFillPaths();\n\n\t\t// This is a hack for lack of innerHTML binding.\n\t\t// See: https://github.com/ckeditor/ckeditor5-ui/issues/99.\n\t\tthis.on<ObservableChangeEvent>( 'change:content', () => {\n\t\t\tthis._updateXMLContent();\n\t\t\tthis._colorFillPaths();\n\t\t} );\n\n\t\tthis.on<ObservableChangeEvent>( 'change:fillColor', () => {\n\t\t\tthis._colorFillPaths();\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the {@link #element} with the value of {@link #content}.\n\t */\n\tprivate _updateXMLContent() {\n\t\tif ( this.content ) {\n\t\t\tconst parsed = new DOMParser().parseFromString( this.content.trim(), 'image/svg+xml' );\n\t\t\tconst svg = parsed.querySelector( 'svg' )!;\n\t\t\tconst viewBox = svg.getAttribute( 'viewBox' );\n\n\t\t\tif ( viewBox ) {\n\t\t\t\tthis.viewBox = viewBox;\n\t\t\t}\n\n\t\t\t// Preserve presentational attributes of the <svg> element from the source.\n\t\t\t// They can affect rendering of the entire icon (https://github.com/ckeditor/ckeditor5/issues/12597).\n\t\t\tfor ( const { name, value } of Array.from( svg.attributes ) ) {\n\t\t\t\tif ( IconView.presentationalAttributeNames.includes( name ) ) {\n\t\t\t\t\tthis.element!.setAttribute( name, value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhile ( this.element!.firstChild ) {\n\t\t\t\tthis.element!.removeChild( this.element!.firstChild );\n\t\t\t}\n\n\t\t\twhile ( svg.childNodes.length > 0 ) {\n\t\t\t\tthis.element!.appendChild( svg.childNodes[ 0 ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Fills all child `path.ck-icon__fill` with the `#fillColor`.\n\t */\n\tprivate _colorFillPaths() {\n\t\tif ( this.fillColor ) {\n\t\t\tthis.element!.querySelectorAll( '.ck-icon__fill' ).forEach( path => {\n\t\t\t\t( path as HTMLElement ).style.fill = this.fillColor;\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/button/buttonlabelview\n */\n\nimport View from '../view.js';\nimport type ButtonLabel from './buttonlabel.js';\n\n/**\n * A default implementation of the button view's label. It comes with a dynamic text support\n * via {@link module:ui/button/buttonlabelview~ButtonLabelView#text} property.\n */\nexport default class ButtonLabelView extends View implements ButtonLabel {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public id: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public style: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public text: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.set( {\n\t\t\tstyle: undefined,\n\t\t\ttext: undefined,\n\t\t\tid: undefined\n\t\t} );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-button__label'\n\t\t\t\t],\n\t\t\t\tstyle: bind.to( 'style' ),\n\t\t\t\tid: bind.to( 'id' )\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: bind.to( 'text' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/button/buttonview\n */\n\nimport View from '../view.js';\nimport IconView from '../icon/iconview.js';\n\nimport type { TemplateDefinition } from '../template.js';\nimport type ViewCollection from '../viewcollection.js';\nimport type { default as Button, ButtonExecuteEvent } from './button.js';\nimport type ButtonLabel from './buttonlabel.js';\nimport ButtonLabelView from './buttonlabelview.js';\n\nimport {\n\tenv,\n\tgetEnvKeystrokeText,\n\tuid,\n\tdelay,\n\ttype Locale,\n\ttype DelayedFunc\n} from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/button/button.css';\n\n/**\n * The button view class.\n *\n * ```ts\n * const view = new ButtonView();\n *\n * view.set( {\n * \tlabel: 'A button',\n * \tkeystroke: 'Ctrl+B',\n * \ttooltip: true,\n * \twithText: true\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n */\nexport default class ButtonView extends View<HTMLButtonElement> implements Button {\n\t/**\n\t * Collection of the child views inside of the button {@link #element}.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * Label of the button view. Its text is configurable using the {@link #label label attribute}.\n\t *\n\t * If not configured otherwise in the `constructor()`, by default the label is an instance\n\t * of {@link module:ui/button/buttonlabelview~ButtonLabelView}.\n\t */\n\tpublic readonly labelView: ButtonLabel;\n\n\t/**\n\t * The icon view of the button. Will be added to {@link #children} when the\n\t * {@link #icon icon attribute} is defined.\n\t */\n\tpublic readonly iconView: IconView;\n\n\t/**\n\t * A view displaying the keystroke of the button next to the {@link #labelView label}.\n\t * Added to {@link #children} when the {@link #withKeystroke `withKeystroke` attribute}\n\t * is defined.\n\t */\n\tpublic readonly keystrokeView: View;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public labelStyle: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public icon: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isOn: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isToggleable: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public keystroke: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public label: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public tabindex: number;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public tooltip: Button[ 'tooltip' ];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public tooltipPosition: Button[ 'tooltipPosition' ];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public type: Button[ 'type' ];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public withText: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public withKeystroke: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public role: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public ariaLabel?: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public ariaLabelledBy: string | undefined;\n\n\t/**\n\t * Aria-pressed attribute of element. It is calculated based on {@link #isToggleable isToggleable} and {@link #role}.\n\t * It's set to true if the button is on and the role is not checkable.\n\t *\n\t * @readonly\n\t * @internal\n\t */\n\tdeclare public _ariaPressed: string | false;\n\n\t/**\n\t * Aria-checked attribute of element. It is calculated based on {@link #isToggleable isToggleable} and {@link #role}.\n\t * It's set to true if the button is on and the role is checkable.\n\t *\n\t * @readonly\n\t * @internal\n\t */\n\tdeclare public _ariaChecked: string | false;\n\n\t/**\n\t * Tooltip of the button bound to the template.\n\t *\n\t * @see #tooltip\n\t * @see module:ui/button/buttonview~ButtonView#_getTooltipString\n\t * @internal\n\t * @observable\n\t */\n\tdeclare public _tooltipString: string;\n\n\t/**\n\t * Delayed focus function for focus handling in Safari.\n\t */\n\tprivate _focusDelayed: DelayedFunc<() => void> | null = null;\n\n\t/**\n\t * Creates an instance of the button view class.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param labelView The instance of the button's label. If not provided, an instance of\n\t * {@link module:ui/button/buttonlabelview~ButtonLabelView} is used.\n\t */\n\tconstructor( locale?: Locale, labelView: ButtonLabel = new ButtonLabelView() ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\t\tconst ariaLabelUid = uid();\n\n\t\t// Implement the Button interface.\n\t\tthis.set( '_ariaPressed', false );\n\t\tthis.set( '_ariaChecked', false );\n\t\tthis.set( 'ariaLabel', undefined );\n\t\tthis.set( 'ariaLabelledBy', `ck-editor__aria-label_${ ariaLabelUid }` );\n\t\tthis.set( 'class', undefined );\n\t\tthis.set( 'labelStyle', undefined );\n\t\tthis.set( 'icon', undefined );\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'isOn', false );\n\t\tthis.set( 'isVisible', true );\n\t\tthis.set( 'isToggleable', false );\n\t\tthis.set( 'keystroke', undefined );\n\t\tthis.set( 'label', undefined );\n\t\tthis.set( 'role', undefined );\n\t\tthis.set( 'tabindex', -1 );\n\t\tthis.set( 'tooltip', false );\n\t\tthis.set( 'tooltipPosition', 's' );\n\t\tthis.set( 'type', 'button' );\n\t\tthis.set( 'withText', false );\n\t\tthis.set( 'withKeystroke', false );\n\n\t\tthis.children = this.createCollection();\n\t\tthis.labelView = this._setupLabelView( labelView );\n\n\t\tthis.iconView = new IconView();\n\t\tthis.iconView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-button__icon'\n\t\t\t}\n\t\t} );\n\n\t\tthis.keystrokeView = this._createKeystrokeView();\n\n\t\tthis.bind( '_tooltipString' ).to(\n\t\t\tthis, 'tooltip',\n\t\t\tthis, 'label',\n\t\t\tthis, 'keystroke',\n\t\t\tthis._getTooltipString.bind( this )\n\t\t);\n\n\t\tconst template: TemplateDefinition & { on: object } = {\n\t\t\ttag: 'button',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-button',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isEnabled', 'ck-disabled', value => !value ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value ),\n\t\t\t\t\tbind.to( 'isOn', value => value ? 'ck-on' : 'ck-off' ),\n\t\t\t\t\tbind.if( 'withText', 'ck-button_with-text' ),\n\t\t\t\t\tbind.if( 'withKeystroke', 'ck-button_with-keystroke' )\n\t\t\t\t],\n\t\t\t\trole: bind.to( 'role' ),\n\t\t\t\ttype: bind.to( 'type', value => value ? value : 'button' ),\n\t\t\t\ttabindex: bind.to( 'tabindex' ),\n\t\t\t\t'aria-checked': bind.to( '_ariaChecked' ),\n\t\t\t\t'aria-pressed': bind.to( '_ariaPressed' ),\n\t\t\t\t'aria-label': bind.to( 'ariaLabel' ),\n\t\t\t\t'aria-labelledby': bind.to( 'ariaLabelledBy' ),\n\t\t\t\t'aria-disabled': bind.if( 'isEnabled', true, value => !value ),\n\t\t\t\t'data-cke-tooltip-text': bind.to( '_tooltipString' ),\n\t\t\t\t'data-cke-tooltip-position': bind.to( 'tooltipPosition' )\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\tclick: bind.to( evt => {\n\t\t\t\t\t// We can't make the button disabled using the disabled attribute, because it won't be focusable.\n\t\t\t\t\t// Though, shouldn't this condition be moved to the button controller?\n\t\t\t\t\tif ( this.isEnabled ) {\n\t\t\t\t\t\tthis.fire<ButtonExecuteEvent>( 'execute' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Prevent the default when button is disabled, to block e.g.\n\t\t\t\t\t\t// automatic form submitting. See ckeditor/ckeditor5-link#74.\n\t\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t}\n\t\t};\n\n\t\tthis.bind( '_ariaPressed' ).to(\n\t\t\tthis, 'isOn', this, 'isToggleable', this, 'role',\n\t\t\t( isOn, isToggleable, role ) => {\n\t\t\t\tif ( !isToggleable || isCheckableRole( role ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn String( !!isOn );\n\t\t\t}\n\t\t);\n\n\t\tthis.bind( '_ariaChecked' ).to(\n\t\t\tthis, 'isOn', this, 'isToggleable', this, 'role',\n\t\t\t( isOn, isToggleable, role ) => {\n\t\t\t\tif ( !isToggleable || !isCheckableRole( role ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn String( !!isOn );\n\t\t\t}\n\t\t);\n\n\t\t// On Safari we have to force the focus on a button on click as it's the only browser\n\t\t// that doesn't do that automatically. See #12115.\n\t\tif ( env.isSafari ) {\n\t\t\tif ( !this._focusDelayed ) {\n\t\t\t\tthis._focusDelayed = delay( () => this.focus(), 0 );\n\t\t\t}\n\n\t\t\ttemplate.on.mousedown = bind.to( () => {\n\t\t\t\tthis._focusDelayed!();\n\t\t\t} );\n\n\t\t\ttemplate.on.mouseup = bind.to( () => {\n\t\t\t\tthis._focusDelayed!.cancel();\n\t\t\t} );\n\t\t}\n\n\t\tthis.setTemplate( template );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tif ( this.icon ) {\n\t\t\tthis.iconView.bind( 'content' ).to( this, 'icon' );\n\t\t\tthis.children.add( this.iconView );\n\t\t}\n\n\t\tthis.children.add( this.labelView );\n\n\t\tif ( this.withKeystroke && this.keystroke ) {\n\t\t\tthis.children.add( this.keystrokeView );\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the {@link #element} of the button.\n\t */\n\tpublic focus(): void {\n\t\tthis.element!.focus();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tif ( this._focusDelayed ) {\n\t\t\tthis._focusDelayed.cancel();\n\t\t}\n\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Binds the label view instance it with button attributes.\n\t */\n\tprivate _setupLabelView( labelView: ButtonLabelView ) {\n\t\tlabelView.bind( 'text', 'style', 'id' ).to( this, 'label', 'labelStyle', 'ariaLabelledBy' );\n\n\t\treturn labelView;\n\t}\n\n\t/**\n\t * Creates a view that displays a keystroke next to a {@link #labelView label }\n\t * and binds it with button attributes.\n\t */\n\tprivate _createKeystrokeView() {\n\t\tconst keystrokeView = new View();\n\n\t\tkeystrokeView.setTemplate( {\n\t\t\ttag: 'span',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-button__keystroke'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: this.bindTemplate.to( 'keystroke', text => getEnvKeystrokeText( text! ) )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\treturn keystrokeView;\n\t}\n\n\t/**\n\t * Gets the text for the tooltip from the combination of\n\t * {@link #tooltip}, {@link #label} and {@link #keystroke} attributes.\n\t *\n\t * @see #tooltip\n\t * @see #_tooltipString\n\t * @param tooltip Button tooltip.\n\t * @param label Button label.\n\t * @param keystroke Button keystroke.\n\t */\n\tprivate _getTooltipString(\n\t\ttooltip: Button[ 'tooltip' ],\n\t\tlabel: string | undefined,\n\t\tkeystroke: string | undefined\n\t): string {\n\t\tif ( tooltip ) {\n\t\t\tif ( typeof tooltip == 'string' ) {\n\t\t\t\treturn tooltip;\n\t\t\t} else {\n\t\t\t\tif ( keystroke ) {\n\t\t\t\t\tkeystroke = getEnvKeystrokeText( keystroke );\n\t\t\t\t}\n\n\t\t\t\tif ( tooltip instanceof Function ) {\n\t\t\t\t\treturn tooltip( label!, keystroke );\n\t\t\t\t} else {\n\t\t\t\t\treturn `${ label }${ keystroke ? ` (${ keystroke })` : '' }`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn '';\n\t}\n}\n\n/**\n * Checks if `aria-checkbox` can be used with specified role.\n */\nfunction isCheckableRole( role: string | undefined ) {\n\tswitch ( role ) {\n\t\tcase 'radio':\n\t\tcase 'checkbox':\n\t\tcase 'option':\n\t\tcase 'switch':\n\t\tcase 'menuitemcheckbox':\n\t\tcase 'menuitemradio':\n\t\t\treturn true;\n\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/formheader/formheaderview\n */\n\nimport View from '../view.js';\nimport type ViewCollection from '../viewcollection.js';\nimport IconView from '../icon/iconview.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/formheader/formheader.css';\n\n/**\n * The class component representing a form header view. It should be used in more advanced forms to\n * describe the main purpose of the form.\n *\n * By default the component contains a bolded label view that has to be set. The label is usually a short (at most 3-word) string.\n * The component can also be extended by any other elements, like: icons, dropdowns, etc.\n *\n * It is used i.a.\n * by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}.\n *\n * The latter is an example, where the component has been extended by {@link module:ui/dropdown/dropdownview~DropdownView} view.\n */\nexport default class FormHeaderView extends View {\n\t/**\n\t * A collection of header items.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * The label of the header.\n\t *\n\t * @observable\n\t */\n\tpublic declare label: string;\n\n\t/**\n\t * An additional CSS class added to the {@link #element}.\n\t *\n\t * @observable\n\t */\n\tpublic declare class: string | null;\n\n\t/**\n\t * The icon view instance. Defined only if icon was passed in the constructor's options.\n\t */\n\tpublic readonly iconView?: IconView;\n\n\t/**\n\t * Creates an instance of the form header class.\n\t *\n\t * @param locale The locale instance.\n\t * @param options.label A label.\n\t * @param options.class An additional class.\n\t */\n\tconstructor(\n\t\tlocale: Locale | undefined,\n\t\toptions: {\n\t\t\tlabel?: string | null;\n\t\t\tclass?: string | null;\n\t\t\ticon?: string | null;\n\t\t} = {}\n\t) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'label', options.label || '' );\n\t\tthis.set( 'class', options.class || null );\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form__header',\n\t\t\t\t\tbind.to( 'class' )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\n\t\tif ( options.icon ) {\n\t\t\tthis.iconView = new IconView();\n\t\t\tthis.iconView.content = options.icon;\n\n\t\t\tthis.children.add( this.iconView );\n\t\t}\n\n\t\tconst label = new View( locale );\n\n\t\tlabel.setTemplate( {\n\t\t\ttag: 'h2',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form__header__label'\n\t\t\t\t],\n\t\t\t\trole: 'presentation'\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{ text: bind.to( 'label' ) }\n\t\t\t]\n\t\t} );\n\n\t\tthis.children.add( label );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/focuscycler\n */\n\nimport {\n\tisVisible,\n\tEmitterMixin,\n\ttype ArrayOrItem,\n\ttype FocusTracker,\n\ttype KeystrokeHandler,\n\ttype KeystrokeHandlerOptions\n} from '@ckeditor/ckeditor5-utils';\n\nimport type View from './view.js';\nimport type ViewCollection from './viewcollection.js';\n\n/**\n * A utility class that helps cycling over {@link module:ui/focuscycler~FocusableView focusable views} in a\n * {@link module:ui/viewcollection~ViewCollection} when the focus is tracked by the\n * {@link module:utils/focustracker~FocusTracker} instance. It helps implementing keyboard\n * navigation in HTML forms, toolbars, lists and the like.\n *\n * To work properly it requires:\n * * a collection of focusable (HTML `tabindex` attribute) views that implement the `focus()` method,\n * * an associated focus tracker to determine which view is focused.\n *\n * A simple cycler setup can look like this:\n *\n * ```ts\n * const focusables = new ViewCollection<FocusableView>();\n * const focusTracker = new FocusTracker();\n *\n * // Add focusable views to the focus tracker.\n * focusTracker.add( ... );\n * ```\n *\n * Then, the cycler can be used manually:\n *\n * ```ts\n * const cycler = new FocusCycler( { focusables, focusTracker } );\n *\n * // Will focus the first focusable view in #focusables.\n * cycler.focusFirst();\n *\n * // Will log the next focusable item in #focusables.\n * console.log( cycler.next );\n * ```\n *\n * Alternatively, it can work side by side with the {@link module:utils/keystrokehandler~KeystrokeHandler}:\n *\n * ```ts\n * const keystrokeHandler = new KeystrokeHandler();\n *\n * // Activate the keystroke handler.\n * keystrokeHandler.listenTo( sourceOfEvents );\n *\n * const cycler = new FocusCycler( {\n * \tfocusables, focusTracker, keystrokeHandler,\n * \tactions: {\n * \t\t// When arrowup of arrowleft is detected by the #keystrokeHandler,\n * \t\t// focusPrevious() will be called on the cycler.\n * \t\tfocusPrevious: [ 'arrowup', 'arrowleft' ],\n * \t}\n * } );\n * ```\n *\n * Check out the {@glink framework/deep-dive/ui/focus-tracking \"Deep dive into focus tracking\"} guide to learn more.\n */\nexport default class FocusCycler extends /* #__PURE__ */ EmitterMixin() {\n\t/**\n\t * A {@link module:ui/focuscycler~FocusableView focusable views} collection that the cycler operates on.\n\t */\n\tpublic readonly focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * A focus tracker instance that the cycler uses to determine the current focus\n\t * state in {@link #focusables}.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}\n\t * which can respond to certain keystrokes and cycle the focus.\n\t */\n\tpublic readonly keystrokeHandler?: KeystrokeHandler;\n\n\t/**\n\t * Actions that the cycler can take when a keystroke is pressed. Requires\n\t * `options.keystrokeHandler` to be passed and working. When an action is\n\t * performed, `preventDefault` and `stopPropagation` will be called on the event\n\t * the keystroke fired in the DOM.\n\t *\n\t * ```ts\n\t * actions: {\n\t * \t// Will call #focusPrevious() when arrowleft or arrowup is pressed.\n\t * \tfocusPrevious: [ 'arrowleft', 'arrowup' ],\n\t *\n\t * \t// Will call #focusNext() when arrowdown is pressed.\n\t * \tfocusNext: 'arrowdown'\n\t * }\n\t * ```\n\t */\n\tpublic readonly actions?: FocusCyclerActions;\n\n\t/**\n\t * Creates an instance of the focus cycler utility.\n\t *\n\t * @param options Configuration options.\n\t */\n\tconstructor( options: {\n\t\tfocusables: ViewCollection<FocusableView>;\n\t\tfocusTracker: FocusTracker;\n\t\tkeystrokeHandler?: KeystrokeHandler;\n\t\tkeystrokeHandlerOptions?: KeystrokeHandlerOptions;\n\t\tactions?: FocusCyclerActions;\n\t} ) {\n\t\tsuper();\n\n\t\tthis.focusables = options.focusables;\n\t\tthis.focusTracker = options.focusTracker;\n\t\tthis.keystrokeHandler = options.keystrokeHandler;\n\t\tthis.actions = options.actions;\n\n\t\tif ( options.actions && options.keystrokeHandler ) {\n\t\t\tfor ( const methodName in options.actions ) {\n\t\t\t\tlet actions = options.actions[ methodName as keyof FocusCyclerActions ]!;\n\n\t\t\t\tif ( typeof actions == 'string' ) {\n\t\t\t\t\tactions = [ actions ];\n\t\t\t\t}\n\n\t\t\t\tfor ( const keystroke of actions ) {\n\t\t\t\t\toptions.keystrokeHandler.set( keystroke, ( data, cancel ) => {\n\t\t\t\t\t\tthis[ methodName as keyof FocusCyclerActions ]();\n\t\t\t\t\t\tcancel();\n\t\t\t\t\t}, options.keystrokeHandlerOptions );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.on<FocusCyclerForwardCycleEvent>( 'forwardCycle', () => this.focusFirst(), { priority: 'low' } );\n\t\tthis.on<FocusCyclerBackwardCycleEvent>( 'backwardCycle', () => this.focusLast(), { priority: 'low' } );\n\t}\n\n\t/**\n\t * Returns the first focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic get first(): FocusableView | null {\n\t\treturn ( this.focusables.find( isDomFocusable ) || null ) as FocusableView | null;\n\t}\n\n\t/**\n\t * Returns the last focusable view in {@link #focusables}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic get last(): FocusableView | null {\n\t\treturn ( this.focusables.filter( isDomFocusable ).slice( -1 )[ 0 ] || null ) as FocusableView | null;\n\t}\n\n\t/**\n\t * Returns the next focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic get next(): FocusableView | null {\n\t\treturn this._getDomFocusableItem( 1 );\n\t}\n\n\t/**\n\t * Returns the previous focusable view in {@link #focusables} based on {@link #current}.\n\t * Returns `null` if there is none.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic get previous(): FocusableView | null {\n\t\treturn this._getDomFocusableItem( -1 );\n\t}\n\n\t/**\n\t * An index of the view in the {@link #focusables} which is focused according\n\t * to {@link #focusTracker}. Returns `null` when there is no such view.\n\t */\n\tpublic get current(): number | null {\n\t\tlet index: number | null = null;\n\n\t\t// There's no focused view in the focusables.\n\t\tif ( this.focusTracker.focusedElement === null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.focusables.find( ( view, viewIndex ) => {\n\t\t\tconst focused = view.element === this.focusTracker.focusedElement;\n\n\t\t\tif ( focused ) {\n\t\t\t\tindex = viewIndex;\n\t\t\t}\n\n\t\t\treturn focused;\n\t\t} );\n\n\t\treturn index;\n\t}\n\n\t/**\n\t * Focuses the {@link #first} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic focusFirst(): void {\n\t\tthis._focus( this.first, 1 );\n\t}\n\n\t/**\n\t * Focuses the {@link #last} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic focusLast(): void {\n\t\tthis._focus( this.last, -1 );\n\t}\n\n\t/**\n\t * Focuses the {@link #next} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic focusNext(): void {\n\t\tconst next = this.next;\n\n\t\t// If there's only one focusable item, we need to let the outside world know\n\t\t// that the next cycle is about to happen. This may be useful\n\t\t// e.g. if you want to move the focus to the parent focus cycler.\n\t\t// Note that the focus is not actually moved in this case.\n\t\tif ( next && this.focusables.getIndex( next ) === this.current ) {\n\t\t\tthis.fire<FocusCyclerForwardCycleEvent>( 'forwardCycle' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( next === this.first ) {\n\t\t\tthis.fire<FocusCyclerForwardCycleEvent>( 'forwardCycle' );\n\t\t} else {\n\t\t\tthis._focus( next, 1 );\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the {@link #previous} item in {@link #focusables}.\n\t *\n\t * **Note**: Hidden views (e.g. with `display: none`) are ignored.\n\t */\n\tpublic focusPrevious(): void {\n\t\tconst previous = this.previous;\n\n\t\tif ( previous && this.focusables.getIndex( previous ) === this.current ) {\n\t\t\tthis.fire<FocusCyclerBackwardCycleEvent>( 'backwardCycle' );\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( previous === this.last ) {\n\t\t\tthis.fire<FocusCyclerBackwardCycleEvent>( 'backwardCycle' );\n\t\t} else {\n\t\t\tthis._focus( previous, -1 );\n\t\t}\n\t}\n\n\t/**\n\t * Allows for creating continuous focus cycling across multiple focus cyclers and their collections of {@link #focusables}.\n\t *\n\t * It starts listening to the {@link module:ui/focuscycler~FocusCyclerForwardCycleEvent} and\n\t * {@link module:ui/focuscycler~FocusCyclerBackwardCycleEvent} events of the chained focus cycler and engages,\n\t * whenever the user reaches the last (forwards navigation) or first (backwards navigation) focusable view\n\t * and would normally start over. Instead, the navigation continues on the higher level (flattens).\n\t *\n\t * For instance, for the following nested focus navigation structure, the focus would get stuck the moment\n\t * the AB gets focused and its focus cycler starts managing it:\n\t *\n\t *\t   ┌────────────┐   ┌──────────────────────────────────┐   ┌────────────┐\n\t *\t   │ AA         │   │ AB                               │   │ AC         │\n\t *\t   │            │   │                                  │   │            │\n\t *\t   │            │   │    ┌─────┐  ┌─────┐  ┌─────┐     │   │            │\n\t *\t   │            │   │ ┌──► ABA ├──► ABB ├──► ABC ├───┐ │   │            │\n\t *\t   │            ├───► │  └─────┘  └─────┘  └─────┘   │ │   │            │\n\t *\t   │            │   │ │                              │ │   │            │\n\t *\t   │            │   │ │                              │ │   │            │\n\t *\t   │            │   │ └──────────────────────────────┘ │   │            │\n\t *\t   │            │   │                                  │   │            │\n\t *\t   └────────────┘   └──────────────────────────────────┘   └────────────┘\n\t *\n\t * Chaining a focus tracker that manages AA, AB, and AC with the focus tracker that manages ABA, ABB, and ABC\n\t * creates a seamless navigation experience instead:\n\t *\n\t *\t   ┌────────────┐   ┌──────────────────────────────────┐   ┌────────────┐\n\t *\t   │ AA         │   │ AB                               │   │ AC         │\n\t *\t   │            │   │                                  │   │            │\n\t *\t   │            │   │    ┌─────┐  ┌─────┐  ┌─────┐     │   │            │\n\t *\t   │            │   │ ┌──► ABA ├──► ABB ├──► ABC ├──┐  │   │            │\n\t *\t┌──►            ├───┼─┘  └─────┘  └─────┘  └─────┘  └──┼───►            ├──┐\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  │            │   │                                  │   │            │  │\n\t *\t│  └────────────┘   └──────────────────────────────────┘   └────────────┘  │\n\t *\t│                                                                          │\n\t *\t│                                                                          │\n\t *\t└──────────────────────────────────────────────────────────────────────────┘\n\t *\n\t * See {@link #unchain} to reverse the chaining.\n\t */\n\tpublic chain( chainedFocusCycler: FocusCycler ): void {\n\t\tconst getCurrentFocusedView = () => {\n\t\t\t// This may happen when one focus cycler does not include focusables of the other (horizontal case).\n\t\t\tif ( this.current === null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn this.focusables.get( this.current );\n\t\t};\n\n\t\tthis.listenTo<FocusCyclerForwardCycleEvent>( chainedFocusCycler, 'forwardCycle', evt => {\n\t\t\tconst oldCurrent = getCurrentFocusedView();\n\n\t\t\tthis.focusNext();\n\n\t\t\t// Stop the event propagation only if an attempt at focusing the view actually moved the focus.\n\t\t\t// If not, let the otherFocusCycler handle the event.\n\t\t\tif ( oldCurrent !== getCurrentFocusedView() ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\n\t\t// The priority is critical for cycling across multiple chain levels when there's a single view at some of them only.\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo<FocusCyclerBackwardCycleEvent>( chainedFocusCycler, 'backwardCycle', evt => {\n\t\t\tconst oldCurrent = getCurrentFocusedView();\n\n\t\t\tthis.focusPrevious();\n\n\t\t\t// Stop the event propagation only if an attempt at focusing the view actually moved the focus.\n\t\t\t// If not, let the otherFocusCycler handle the event.\n\t\t\tif ( oldCurrent !== getCurrentFocusedView() ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\n\t\t// The priority is critical for cycling across multiple chain levels when there's a single view at some of them only.\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Reverses a chaining made by {@link #chain}.\n\t */\n\tpublic unchain( otherFocusCycler: FocusCycler ): void {\n\t\tthis.stopListening( otherFocusCycler );\n\t}\n\n\t/**\n\t * Focuses the given view if it exists.\n\t *\n\t * @param view The view to be focused\n\t * @param direction The direction of the focus if the view has focusable children.\n\t * @returns\n\t */\n\tprivate _focus( view: FocusableView | null, direction: 1 | -1 ) {\n\t\t// Don't fire focus events if the view is already focused.\n\t\t// Such attempt may occur when cycling with only one focusable item:\n\t\t// even though `focusNext()` method returns without changing focus,\n\t\t// the `forwardCycle` event is fired, triggering the `focusFirst()` method.\n\t\tif ( view && this.focusTracker.focusedElement !== view.element ) {\n\t\t\tview.focus( direction );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the next or previous focusable view in {@link #focusables} with respect\n\t * to {@link #current}.\n\t *\n\t * @param step Either `1` for checking forward from {@link #current} or `-1` for checking backwards.\n\t */\n\tprivate _getDomFocusableItem( step: 1 | -1 ): FocusableView | null {\n\t\t// Cache for speed.\n\t\tconst collectionLength = this.focusables.length;\n\n\t\tif ( !collectionLength ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst current = this.current;\n\n\t\t// Start from the beginning if no view is focused.\n\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/206\n\t\tif ( current === null ) {\n\t\t\treturn this[ step === 1 ? 'first' : 'last' ];\n\t\t}\n\n\t\t// Note: If current is the only focusable view, it will also be returned for the given step.\n\t\tlet focusableItem = this.focusables.get( current )!;\n\n\t\t// Cycle in both directions.\n\t\tlet index = ( current + collectionLength + step ) % collectionLength;\n\n\t\tdo {\n\t\t\tconst focusableItemCandidate = this.focusables.get( index )!;\n\n\t\t\tif ( isDomFocusable( focusableItemCandidate ) ) {\n\t\t\t\tfocusableItem = focusableItemCandidate;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Cycle in both directions.\n\t\t\tindex = ( index + collectionLength + step ) % collectionLength;\n\t\t} while ( index !== current );\n\n\t\treturn focusableItem;\n\t}\n}\n\n/**\n * A {@link module:ui/view~View} that can be focused (e.g. has `focus()` method).\n */\nexport type FocusableView = View & {\n\n\t/**\n\t * Focuses the view.\n\t *\n\t * @param direction This optional parameter helps improve the UX by providing additional information about the direction the focus moved\n\t * (e.g. in a complex view or a form). It is useful for views that host multiple focusable children (e.g. lists, toolbars):\n\t * * `1` indicates that the focus moved forward and, in most cases, the first child of the focused view should get focused,\n\t * * `-1` indicates that the focus moved backwards, and the last focusable child should get focused\n\t *\n\t * See {@link module:ui/focuscycler~FocusCycler#event:forwardCycle} and {@link module:ui/focuscycler~FocusCycler#event:backwardCycle}\n\t * to learn more.\n\t */\n\tfocus( direction?: 1 | -1 ): void;\n};\n\n/**\n * A {@link module:ui/view~View} that hosts one or more of focusable children being managed by a {@link module:ui/focuscycler~FocusCycler}\n * instance exposed under `focusCycler` property.\n */\nexport type ViewWithFocusCycler = FocusableView & {\n\tfocusCycler: FocusCycler;\n};\n\nexport type FocusCyclerActions = {\n\t[ key in 'focusFirst' | 'focusLast' | 'focusPrevious' | 'focusNext' ]?: ArrayOrItem<string>\n};\n\n/**\n * Fired when the focus cycler is about to move the focus from the last focusable item\n * to the first one.\n *\n * @eventName ~FocusCycler#forwardCycle\n */\nexport type FocusCyclerForwardCycleEvent = {\n\tname: 'forwardCycle';\n\targs: [];\n};\n\n/**\n * Fired when the focus cycler is about to move the focus from the first focusable item\n * to the last one.\n *\n * @eventName ~FocusCycler#backwardCycle\n */\nexport type FocusCyclerBackwardCycleEvent = {\n\tname: 'backwardCycle';\n\targs: [];\n};\n\n/**\n * Checks whether a view can be focused (has `focus()` method and is visible).\n *\n * @param view A view to be checked.\n */\nfunction isDomFocusable( view: View ) {\n\treturn isFocusable( view ) && isVisible( view.element );\n}\n\n/**\n * Checks whether a view is {@link ~FocusableView}.\n *\n * @param view A view to be checked.\n */\nexport function isFocusable( view: View ): view is FocusableView {\n\treturn !!( 'focus' in view && typeof view.focus == 'function' );\n}\n\n/**\n * Checks whether a view is an instance of {@link ~ViewWithFocusCycler}.\n *\n * @param view A view to be checked.\n */\nexport function isViewWithFocusCycler( view: View ): view is ViewWithFocusCycler {\n\treturn isFocusable( view ) && 'focusCycler' in view && view.focusCycler instanceof FocusCycler;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/bindings/draggableviewmixin\n */\n\nimport type View from '../view.js';\nimport { global, type Constructor, type Mixed, type EventInfo } from '@ckeditor/ckeditor5-utils';\n\n/**\n * A mixin that brings the possibility to observe dragging of the view element.\n * The view has to implement the {@link ~DraggableView} interface to use it:\n *\n * ```js\n * export default class MyDraggableView extends DraggableViewMixin( View ) implements DraggableView {\n * \t\t// ...\n * }\n * ```\n *\n * Creating a class extending it attaches a set of mouse and touch listeners allowing to observe dragging of the view element:\n * * `mousedown` and `touchstart` on the view element - starting the dragging.\n * * `mousemove` and `touchmove` on the document - updating the view coordinates.\n * * `mouseup` and `touchend` on the document - stopping the dragging.\n *\n * The mixin itself does not provide a visual feedback (that is, the dragged element does not change its position) -\n * it is up to the developer to implement it.\n */\nexport default function DraggableViewMixin<Base extends Constructor<View>>( view: Base ): Mixed<Base, DraggableView> {\n\tabstract class DraggableMixin extends view implements DraggableView {\n\t\t/**\n\t\t * A flag indicating whether the view is currently being dragged.\n\t\t *\n\t\t * @observable\n\t\t */\n\t\tdeclare public isDragging: boolean;\n\n\t\t/**\n\t\t * A bound version of {@link #_onDrag}.\n\t\t */\n\t\tprivate _onDragBound = this._onDrag.bind( this );\n\n\t\t/**\n\t\t * A bound version of {@link #_onDragEnd}.\n\t\t */\n\t\tprivate _onDragEndBound = this._onDragEnd.bind( this );\n\n\t\t/**\n\t\t * The last coordinates of the view. It is updated on every mouse move.\n\t\t */\n\t\tprivate _lastDraggingCoordinates: { x: number; y: number } = { x: 0, y: 0 };\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tconstructor( ...args: Array<any> ) {\n\t\t\tsuper( ...args );\n\n\t\t\tthis.on( 'render', () => {\n\t\t\t\tthis._attachListeners();\n\t\t\t} );\n\n\t\t\tthis.set( 'isDragging', false );\n\t\t}\n\n\t\t/**\n\t\t * Attaches the listeners for the drag start.\n\t\t */\n\t\tprivate _attachListeners() {\n\t\t\tthis.listenTo( this.element!, 'mousedown', this._onDragStart.bind( this ) );\n\t\t\tthis.listenTo( this.element!, 'touchstart', this._onDragStart.bind( this ) );\n\t\t}\n\n\t\t/**\n\t\t * Attaches the listeners for the dragging and drag end.\n\t\t */\n\t\tprivate _attachDragListeners() {\n\t\t\tthis.listenTo( global.document, 'mouseup', this._onDragEndBound );\n\t\t\tthis.listenTo( global.document, 'touchend', this._onDragEndBound );\n\t\t\tthis.listenTo( global.document, 'mousemove', this._onDragBound );\n\t\t\tthis.listenTo( global.document, 'touchmove', this._onDragBound );\n\t\t}\n\n\t\t/**\n\t\t * Detaches the listeners after the drag end.\n\t\t */\n\t\tprivate _detachDragListeners() {\n\t\t\tthis.stopListening( global.document, 'mouseup', this._onDragEndBound );\n\t\t\tthis.stopListening( global.document, 'touchend', this._onDragEndBound );\n\t\t\tthis.stopListening( global.document, 'mousemove', this._onDragBound );\n\t\t\tthis.stopListening( global.document, 'touchmove', this._onDragBound );\n\t\t}\n\n\t\t/**\n\t\t * Starts the dragging listeners and sets the initial view coordinates.\n\t\t */\n\t\tprivate _onDragStart( evt: EventInfo, domEvt: MouseEvent | TouchEvent ) {\n\t\t\tif ( !this._isHandleElementPressed( domEvt ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._attachDragListeners();\n\n\t\t\tlet x = 0;\n\t\t\tlet y = 0;\n\n\t\t\t// If dragging is performed with a mouse, there is only one set of coordinates available.\n\t\t\t// But when using a touch device, there may be many of them, so use the coordinates from the first touch.\n\t\t\tif ( domEvt instanceof MouseEvent ) {\n\t\t\t\tx = domEvt.clientX;\n\t\t\t\ty = domEvt.clientY;\n\t\t\t} else {\n\t\t\t\tx = domEvt.touches[ 0 ].clientX;\n\t\t\t\ty = domEvt.touches[ 0 ].clientY;\n\t\t\t}\n\n\t\t\tthis._lastDraggingCoordinates = { x, y };\n\n\t\t\tthis.isDragging = true;\n\t\t}\n\n\t\t/**\n\t\t * Updates the view coordinates and fires the `drag` event.\n\t\t */\n\t\tprivate _onDrag( evt: EventInfo, domEvt: MouseEvent | TouchEvent ) {\n\t\t\t// If dragging was stopped by some external intervention, stop listening.\n\t\t\tif ( !this.isDragging ) {\n\t\t\t\tthis._detachDragListeners();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet newX = 0;\n\t\t\tlet newY = 0;\n\n\t\t\t// If dragging is performed with a mouse, there is only one set of coordinates available.\n\t\t\t// But when using a touch device, there may be many of them, so use the coordinates from the first touch.\n\t\t\tif ( domEvt instanceof MouseEvent ) {\n\t\t\t\tnewX = domEvt.clientX;\n\t\t\t\tnewY = domEvt.clientY;\n\t\t\t} else {\n\t\t\t\tnewX = domEvt.touches[ 0 ].clientX;\n\t\t\t\tnewY = domEvt.touches[ 0 ].clientY;\n\t\t\t}\n\n\t\t\t// Prevents selection of text while dragging on Safari.\n\t\t\tdomEvt.preventDefault();\n\n\t\t\tthis.fire<DraggableViewDragEvent>( 'drag', {\n\t\t\t\tdeltaX: Math.round( newX - this._lastDraggingCoordinates.x ),\n\t\t\t\tdeltaY: Math.round( newY - this._lastDraggingCoordinates.y )\n\t\t\t} );\n\n\t\t\tthis._lastDraggingCoordinates = { x: newX, y: newY };\n\t\t}\n\n\t\t/**\n\t\t * Stops the dragging and detaches the listeners.\n\t\t */\n\t\tprivate _onDragEnd() {\n\t\t\tthis._detachDragListeners();\n\n\t\t\tthis.isDragging = false;\n\t\t}\n\n\t\t/**\n\t\t * Checks if the drag handle element was pressed.\n\t\t */\n\t\tprivate _isHandleElementPressed( domEvt: MouseEvent | TouchEvent ) {\n\t\t\tif ( !this.dragHandleElement ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn this.dragHandleElement === domEvt.target ||\n\t\t\t\t( domEvt.target instanceof HTMLElement && this.dragHandleElement.contains( domEvt.target ) );\n\t\t}\n\n\t\tpublic abstract get dragHandleElement(): HTMLElement | null;\n\t}\n\n\treturn DraggableMixin as any;\n}\n\n/**\n * An interface that should be implemented by views that want to be draggable.\n */\nexport interface DraggableView extends View {\n\tget dragHandleElement(): HTMLElement | null;\n}\n\n/**\n * An event data object for the {@link ~DraggableView} `drag` event. Fired when the view is dragged.\n */\nexport type DraggableViewDragEvent = {\n\tname: 'drag';\n\targs: [ {\n\t\tdeltaX: number;\n\t\tdeltaY: number;\n\t} ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dialog/dialogactionsview\n */\n\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\ttype Locale\n} from '@ckeditor/ckeditor5-utils';\nimport type { default as Button, ButtonExecuteEvent } from '../button/button.js';\nimport ButtonView from '../button/buttonview.js';\nimport View from '../view.js';\nimport ViewCollection from '../viewcollection.js';\nimport FocusCycler, { type FocusableView } from '../focuscycler.js';\n\nimport '../../theme/components/dialog/dialogactions.css';\n\n/**\n * A dialog actions view class. It contains button views which are used to execute dialog actions.\n */\nexport default class DialogActionsView extends View {\n\t/**\n\t * A collection of button views.\n\t */\n\tpublic readonly children: ViewCollection<FocusableView>;\n\n\t/**\n\t * A keystroke handler instance.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A focus cycler instance.\n\t */\n\tpublic readonly focusCycler: FocusCycler;\n\n\t/**\n\t * A focus tracker instance.\n\t */\n\tprivate readonly _focusTracker: FocusTracker;\n\n\t/**\n\t * A collection of focusable views.\n\t */\n\tprivate readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.children = this.createCollection<ButtonView>();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis._focusTracker = new FocusTracker();\n\t\tthis._focusables = new ViewCollection();\n\t\tthis.focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this._focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-dialog__actions'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * Creates the button views based on the given definitions.\n\t * Then adds them to the {@link #children} collection and to the focus cycler.\n\t */\n\tpublic setButtons( definitions: Array<DialogActionButtonDefinition> ): void {\n\t\tfor ( const definition of definitions ) {\n\t\t\tconst button = new ButtonView( this.locale );\n\n\t\t\tlet property: keyof DialogActionButtonDefinition;\n\t\t\tbutton.on<ButtonExecuteEvent>( 'execute', () => definition.onExecute() );\n\n\t\t\tif ( definition.onCreate ) {\n\t\t\t\tdefinition.onCreate( button );\n\t\t\t}\n\n\t\t\tfor ( property in definition ) {\n\t\t\t\tif ( property != 'onExecute' && property != 'onCreate' ) {\n\t\t\t\t\tbutton.set( property, definition[ property ] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.children.add( button );\n\t\t}\n\n\t\tthis._updateFocusCyclableItems();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focus( direction?: 1 | -1 ): void {\n\t\tif ( direction === -1 ) {\n\t\t\tthis.focusCycler.focusLast();\n\t\t} else {\n\t\t\tthis.focusCycler.focusFirst();\n\t\t}\n\t}\n\n\t/**\n\t * Adds all elements from the {@link #children} collection to the {@link #_focusables} collection\n\t * and to the {@link #_focusTracker} instance.\n\t */\n\tprivate _updateFocusCyclableItems() {\n\t\tArray.from( this.children ).forEach( v => {\n\t\t\tthis._focusables.add( v );\n\t\t\tthis._focusTracker.add( v.element! );\n\t\t} );\n\t}\n}\n\n/**\n * A dialog action button definition. It is a slightly modified version\n * of the {@link module:ui/button/button~Button} definition.\n */\nexport type DialogActionButtonDefinition =\n\tPick<Button, 'label'> &\n\tPartial<Pick<Button, 'withText' | 'class' | 'icon'>> &\n\t{\n\t\tonExecute: Function;\n\t\tonCreate?: ( button: ButtonView ) => void;\n\t};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dialog/dialogcontentview\n */\n\nimport View from '../view.js';\nimport type ViewCollection from '../viewcollection.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * A dialog content view class.\n */\nexport default class DialogContentView extends View {\n\t/**\n\t * A collection of content items.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor(\n\t\tlocale: Locale | undefined\n\t) {\n\t\tsuper( locale );\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck', 'ck-dialog__content' ]\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * Removes all the child views.\n\t */\n\tpublic reset(): void {\n\t\twhile ( this.children.length ) {\n\t\t\tthis.children.remove( 0 );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dialog/dialogview\n */\n\nimport {\n\tKeystrokeHandler,\n\tFocusTracker,\n\tRect,\n\tglobal,\n\ttoUnit,\n\ttype EventInfo,\n\ttype Locale,\n\ttype DecoratedMethodEvent\n} from '@ckeditor/ckeditor5-utils';\nimport { icons } from '@ckeditor/ckeditor5-core';\nimport ViewCollection from '../viewcollection.js';\nimport View from '../view.js';\nimport FormHeaderView from '../formheader/formheaderview.js';\nimport ButtonView from '../button/buttonview.js';\nimport { type ButtonExecuteEvent } from '../button/button.js';\nimport FocusCycler, { isViewWithFocusCycler,\n\ttype FocusableView,\n\tisFocusable\n}\n\tfrom '../focuscycler.js';\nimport DraggableViewMixin, { type DraggableView, type DraggableViewDragEvent } from '../bindings/draggableviewmixin.js';\nimport DialogActionsView, { type DialogActionButtonDefinition } from './dialogactionsview.js';\nimport DialogContentView from './dialogcontentview.js';\nimport type EditorUI from '../editorui/editorui.js';\n\nimport '../../theme/components/dialog/dialog.css';\n// @if CK_DEBUG_DIALOG // const RectDrawer = require( '@ckeditor/ckeditor5-utils/tests/_utils/rectdrawer' ).default;\n\n/**\n * Available dialog view positions:\n *\n * * `DialogViewPosition.SCREEN_CENTER` &ndash; A fixed position in the center of the screen.\n * * `DialogViewPosition.EDITOR_CENTER` &ndash; A dynamic position in the center of the editor editable area.\n * * `DialogViewPosition.EDITOR_TOP_SIDE` &ndash; A dynamic position at the top-right (for the left-to-right languages)\n * or top-left (for right-to-left languages) corner of the editor editable area.\n * * `DialogViewPosition.EDITOR_TOP_CENTER` &ndash; A dynamic position at the top-center of the editor editable area.\n * * `DialogViewPosition.EDITOR_BOTTOM_CENTER` &ndash; A dynamic position at the bottom-center of the editor editable area.\n * * `DialogViewPosition.EDITOR_ABOVE_CENTER` &ndash; A dynamic position centered above the editor editable area.\n * * `DialogViewPosition.EDITOR_BELOW_CENTER` &ndash; A dynamic position centered below the editor editable area.\n *\n * The position of a dialog is specified by a {@link module:ui/dialog/dialog~DialogDefinition#position `position` property} of a\n * definition passed to the {@link module:ui/dialog/dialog~Dialog#show} method.\n */\nexport const DialogViewPosition = {\n\tSCREEN_CENTER: 'screen-center',\n\tEDITOR_CENTER: 'editor-center',\n\tEDITOR_TOP_SIDE: 'editor-top-side',\n\tEDITOR_TOP_CENTER: 'editor-top-center',\n\tEDITOR_BOTTOM_CENTER: 'editor-bottom-center',\n\tEDITOR_ABOVE_CENTER: 'editor-above-center',\n\tEDITOR_BELOW_CENTER: 'editor-below-center'\n} as const;\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n/**\n * A dialog view class.\n */\nexport default class DialogView extends /* #__PURE__ */ DraggableViewMixin( View ) implements DraggableView {\n\t/**\n\t * A collection of the child views inside of the dialog.\n\t * A dialog can have 3 optional parts: header, content, and actions.\n\t */\n\tpublic readonly parts: ViewCollection;\n\n\t/**\n\t * A header view of the dialog. It is also a drag handle of the dialog.\n\t */\n\tpublic headerView?: FormHeaderView;\n\n\t/**\n\t * A close button view. It is automatically added to the header view if present.\n\t */\n\tpublic closeButtonView?: ButtonView;\n\n\t/**\n\t * A view with the action buttons available to the user.\n\t */\n\tpublic actionsView?: DialogActionsView;\n\n\t/**\n\t * A default dialog element offset from the reference element (e.g. editor editable area).\n\t */\n\tpublic static defaultOffset: number = 15;\n\n\t/**\n\t * A view with the dialog content.\n\t */\n\tpublic contentView?: DialogContentView;\n\n\t/**\n\t * A keystroke handler instance.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A focus tracker instance.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * A flag indicating if the dialog was moved manually. If so, its position\n\t * will not be updated automatically upon window resize or document scroll.\n\t */\n\tpublic wasMoved: boolean = false;\n\n\t/**\n\t * A flag indicating if this dialog view is a modal.\n\t *\n\t * @observable\n\t */\n\tdeclare public isModal: boolean;\n\n\t/**\n\t * A label for the view dialog element to be used by the assistive technologies.\n\t *\n\t * @observable\n\t */\n\tdeclare public ariaLabel: string;\n\n\t/**\n\t * A custom class name to be added to the dialog element.\n\t *\n\t * @observable\n\t */\n\tdeclare public className: string | undefined;\n\n\t/**\n\t * The position of the dialog view.\n\t *\n\t * @observable\n\t */\n\tdeclare public position: typeof DialogViewPosition[ keyof typeof DialogViewPosition ];\n\n\t/**\n\t * A flag indicating that the dialog should be shown. Once set to `true`, the dialog will be shown\n\t * after its position is calculated. Until then, the dialog is transparent and not visible.\n\t *\n\t * See {@link #_isTransparent} property.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tdeclare public _isVisible: boolean;\n\n\t/**\n\t * A flag indicating if a dialog is transparent. It is used to prevent the dialog from being visible\n\t * before its position is calculated.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tdeclare public _isTransparent: boolean;\n\n\t/**\n\t * The calculated dialog `top` CSS property used for positioning.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tdeclare public _top: number;\n\n\t/**\n\t * The calculated dialog `left` CSS property used for positioning.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tdeclare public _left: number;\n\n\t/**\n\t * A callback returning the DOM root that requested the dialog.\n\t */\n\tprivate _getCurrentDomRoot: () => HTMLElement;\n\n\t/**\n\t * A callback returning the configured editor viewport offset.\n\t */\n\tprivate _getViewportOffset: () => EditorUI[ 'viewportOffset' ];\n\n\t/**\n\t * The list of the focusable elements inside the dialog view.\n\t */\n\tprivate readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * The focus cycler instance.\n\t */\n\tprivate readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale,\n\t\t{\n\t\t\tgetCurrentDomRoot,\n\t\t\tgetViewportOffset\n\t\t}: {\n\t\t\tgetCurrentDomRoot: () => HTMLElement;\n\t\t\tgetViewportOffset: () => EditorUI[ 'viewportOffset' ];\n\t\t}\n\t) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\t\tconst t = locale.t;\n\n\t\tthis.set( 'className', '' );\n\t\tthis.set( 'ariaLabel', t( 'Editor dialog' ) );\n\t\tthis.set( 'isModal', false );\n\t\tthis.set( 'position', DialogViewPosition.SCREEN_CENTER );\n\t\tthis.set( '_isVisible', false );\n\t\tthis.set( '_isTransparent', false );\n\t\tthis.set( '_top', 0 );\n\t\tthis.set( '_left', 0 );\n\t\tthis._getCurrentDomRoot = getCurrentDomRoot;\n\t\tthis._getViewportOffset = getViewportOffset;\n\n\t\tthis.decorate( 'moveTo' );\n\n\t\tthis.parts = this.createCollection();\n\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis._focusables = new ViewCollection();\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-dialog-overlay',\n\t\t\t\t\tbind.if( 'isModal', 'ck-dialog-overlay__transparent', isModal => !isModal ),\n\t\t\t\t\tbind.if( '_isVisible', 'ck-hidden', value => !value )\n\t\t\t\t],\n\t\t\t\t// Prevent from editor losing focus when clicking on the modal overlay.\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\ttabindex: '-1',\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-dialog',\n\t\t\t\t\t\t\tbind.if( 'isModal', 'ck-dialog_modal' ),\n\t\t\t\t\t\t\tbind.to( 'className' )\n\t\t\t\t\t\t],\n\t\t\t\t\t\trole: 'dialog',\n\t\t\t\t\t\t'aria-label': bind.to( 'ariaLabel' ),\n\t\t\t\t\t\tstyle: {\n\t\t\t\t\t\t\ttop: bind.to( '_top', top => toPx( top ) ),\n\t\t\t\t\t\t\tleft: bind.to( '_left', left => toPx( left ) ),\n\t\t\t\t\t\t\tvisibility: bind.if( '_isTransparent', 'hidden' )\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.parts\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis.fire<DialogViewCloseEvent>( 'close', { source: 'escKeyPress' } );\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Support for dragging the modal.\n\t\tthis.on<DraggableViewDragEvent>( 'drag', ( evt: EventInfo, { deltaX, deltaY } ) => {\n\t\t\tthis.wasMoved = true;\n\t\t\tthis.moveBy( deltaX, deltaY );\n\t\t} );\n\n\t\t// Update dialog position upon window resize, if the position was not changed manually.\n\t\tthis.listenTo( global.window, 'resize', () => {\n\t\t\tif ( this._isVisible && !this.wasMoved ) {\n\t\t\t\tthis.updatePosition();\n\t\t\t}\n\t\t} );\n\n\t\t// Update dialog position upon document scroll, if the position was not changed manually.\n\t\tthis.listenTo( global.document, 'scroll', () => {\n\t\t\tif ( this._isVisible && !this.wasMoved ) {\n\t\t\t\tthis.updatePosition();\n\t\t\t}\n\t\t} );\n\n\t\tthis.on( 'change:_isVisible', ( evt, name, isVisible ) => {\n\t\t\tif ( isVisible ) {\n\t\t\t\t// Let the content render first, then apply the position. Otherwise, the calculated DOM Rects\n\t\t\t\t// will not reflect the final look of the dialog. Note that we're not using #_moveOffScreen() here because\n\t\t\t\t// it causes a violent movement of the viewport on iOS (because the dialog still keeps the DOM focus).\n\t\t\t\tthis._isTransparent = true;\n\n\t\t\t\t// FYI: RAF is too short. We need to wait a bit longer.\n\t\t\t\tsetTimeout( () => {\n\t\t\t\t\tthis.updatePosition();\n\n\t\t\t\t\tthis._isTransparent = false;\n\n\t\t\t\t\t// The view must get the focus after it gets visible. But this is only possible\n\t\t\t\t\t// after the dialog is no longer transparent.\n\t\t\t\t\tthis.focus();\n\t\t\t\t}, 10 );\n\t\t\t}\n\t\t} );\n\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * Returns the element that should be used as a drag handle.\n\t */\n\tpublic override get dragHandleElement(): HTMLElement | null {\n\t\t// Modals should not be draggable.\n\t\tif ( this.headerView && !this.isModal ) {\n\t\t\treturn this.headerView.element;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Creates the dialog parts. Which of them are created depends on the arguments passed to the method.\n\t * There are no rules regarding the dialog construction, that is, no part is mandatory.\n\t * Each part can only be created once.\n\t *\n\t * @internal\n\t */\n\tpublic setupParts( { icon, title, hasCloseButton = true, content, actionButtons }: {\n\t\ticon?: string;\n\t\ttitle?: string;\n\t\thasCloseButton?: boolean;\n\t\tcontent?: View | Array<View>;\n\t\tactionButtons?: Array<DialogActionButtonDefinition>;\n\t} ): void {\n\t\tif ( title ) {\n\t\t\tthis.headerView = new FormHeaderView( this.locale, { icon } );\n\n\t\t\tif ( hasCloseButton ) {\n\t\t\t\tthis.closeButtonView = this._createCloseButton();\n\t\t\t\tthis.headerView.children.add( this.closeButtonView );\n\t\t\t}\n\n\t\t\tthis.headerView.label = title;\n\t\t\tthis.ariaLabel = title;\n\t\t\tthis.parts.add( this.headerView, 0 );\n\t\t}\n\n\t\tif ( content ) {\n\t\t\t// Normalize the content specified in the arguments.\n\t\t\tif ( content instanceof View ) {\n\t\t\t\tcontent = [ content ];\n\t\t\t}\n\n\t\t\tthis.contentView = new DialogContentView( this.locale );\n\t\t\tthis.contentView.children.addMany( content );\n\t\t\tthis.parts.add( this.contentView );\n\t\t}\n\n\t\tif ( actionButtons ) {\n\t\t\tthis.actionsView = new DialogActionsView( this.locale );\n\t\t\tthis.actionsView.setButtons( actionButtons );\n\t\t\tthis.parts.add( this.actionsView );\n\t\t}\n\n\t\tthis._updateFocusCyclableItems();\n\t}\n\n\t/**\n\t * Focuses the first focusable element inside the dialog.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Normalizes the passed coordinates to make sure the dialog view\n\t * is displayed within the visible viewport and moves it there.\n\t *\n\t * @internal\n\t */\n\tpublic moveTo( left: number, top: number ): void {\n\t\tconst viewportRect = this._getViewportRect();\n\t\tconst dialogRect = this._getDialogRect();\n\n\t\t// Don't let the dialog go beyond the right edge of the viewport.\n\t\tif ( left + dialogRect.width > viewportRect.right ) {\n\t\t\tleft = viewportRect.right - dialogRect.width;\n\t\t}\n\n\t\t// Don't let the dialog go beyond the left edge of the viewport.\n\t\tif ( left < viewportRect.left ) {\n\t\t\tleft = viewportRect.left;\n\t\t}\n\n\t\t// Don't let the dialog go beyond the top edge of the viewport.\n\t\tif ( top < viewportRect.top ) {\n\t\t\ttop = viewportRect.top;\n\t\t}\n\n\t\t// Note: We don't do the same for the bottom edge to allow users to resize the window vertically\n\t\t// and let the dialog to stay put instead of covering the editing root.\n\n\t\tthis._moveTo( left, top );\n\t}\n\n\t/**\n\t * Moves the dialog to the specified coordinates.\n\t */\n\tprivate _moveTo( left: number, top: number ): void {\n\t\tthis._left = left;\n\t\tthis._top = top;\n\t}\n\n\t/**\n\t * Moves the dialog by the specified offset.\n\t *\n\t * @internal\n\t */\n\tpublic moveBy( left: number, top: number ): void {\n\t\tthis.moveTo( this._left + left, this._top + top );\n\t}\n\n\t/**\n\t * Moves the dialog view to the off-screen position.\n\t * Used when there is no space to display the dialog.\n\t */\n\tprivate _moveOffScreen(): void {\n\t\tthis._moveTo( -9999, -9999 );\n\t}\n\n\t/**\n\t * Recalculates the dialog according to the set position and viewport,\n\t * and moves it to the new position.\n\t */\n\tpublic updatePosition(): void {\n\t\tif ( !this.element || !this.element.parentNode ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewportRect = this._getViewportRect();\n\n\t\t// Actual position may be different from the configured one if there's no DOM root.\n\t\tlet configuredPosition = this.position;\n\t\tlet domRootRect;\n\n\t\tif ( !this._getCurrentDomRoot() ) {\n\t\t\tconfiguredPosition = DialogViewPosition.SCREEN_CENTER;\n\t\t} else {\n\t\t\tdomRootRect = this._getVisibleDomRootRect( viewportRect );\n\t\t}\n\n\t\tconst defaultOffset = DialogView.defaultOffset;\n\t\tconst dialogRect = this._getDialogRect();\n\n\t\t// @if CK_DEBUG_DIALOG // RectDrawer.clear();\n\t\t// @if CK_DEBUG_DIALOG // RectDrawer.draw( viewportRect, { outlineColor: 'blue' }, 'Viewport' );\n\n\t\tswitch ( configuredPosition ) {\n\t\t\tcase DialogViewPosition.EDITOR_TOP_SIDE: {\n\t\t\t\t// @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n\t\t\t\t// @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n\t\t\t\t// @if CK_DEBUG_DIALOG // }\n\n\t\t\t\tif ( domRootRect ) {\n\t\t\t\t\tconst leftCoordinate = this.locale!.contentLanguageDirection === 'ltr' ?\n\t\t\t\t\t\tdomRootRect.right - dialogRect.width - defaultOffset :\n\t\t\t\t\t\tdomRootRect.left + defaultOffset;\n\n\t\t\t\t\tthis.moveTo( leftCoordinate, domRootRect.top + defaultOffset );\n\t\t\t\t} else {\n\t\t\t\t\tthis._moveOffScreen();\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DialogViewPosition.EDITOR_CENTER: {\n\t\t\t\tif ( domRootRect ) {\n\t\t\t\t\tthis.moveTo(\n\t\t\t\t\t\tMath.round( domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2 ),\n\t\t\t\t\t\tMath.round( domRootRect.top + domRootRect.height / 2 - dialogRect.height / 2 )\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis._moveOffScreen();\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DialogViewPosition.SCREEN_CENTER: {\n\t\t\t\tthis.moveTo(\n\t\t\t\t\tMath.round( ( viewportRect.width - dialogRect.width ) / 2 ),\n\t\t\t\t\tMath.round( ( viewportRect.height - dialogRect.height ) / 2 )\n\t\t\t\t);\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DialogViewPosition.EDITOR_TOP_CENTER: {\n\t\t\t\t// @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n\t\t\t\t// @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n\t\t\t\t// @if CK_DEBUG_DIALOG // }\n\n\t\t\t\tif ( domRootRect ) {\n\t\t\t\t\tthis.moveTo(\n\t\t\t\t\t\tMath.round( domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2 ),\n\t\t\t\t\t\tdomRootRect.top + defaultOffset\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis._moveOffScreen();\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DialogViewPosition.EDITOR_BOTTOM_CENTER: {\n\t\t\t\t// @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n\t\t\t\t// @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n\t\t\t\t// @if CK_DEBUG_DIALOG // }\n\n\t\t\t\tif ( domRootRect ) {\n\t\t\t\t\tthis.moveTo(\n\t\t\t\t\t\tMath.round( domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2 ),\n\t\t\t\t\t\tdomRootRect.bottom - dialogRect.height - defaultOffset\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis._moveOffScreen();\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DialogViewPosition.EDITOR_ABOVE_CENTER: {\n\t\t\t\t// @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n\t\t\t\t// @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n\t\t\t\t// @if CK_DEBUG_DIALOG // }\n\n\t\t\t\tif ( domRootRect ) {\n\t\t\t\t\tthis.moveTo(\n\t\t\t\t\t\tMath.round( domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2 ),\n\t\t\t\t\t\tdomRootRect.top - dialogRect.height - defaultOffset\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis._moveOffScreen();\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DialogViewPosition.EDITOR_BELOW_CENTER: {\n\t\t\t\t// @if CK_DEBUG_DIALOG // if ( domRootRect ) {\n\t\t\t\t// @if CK_DEBUG_DIALOG // \tRectDrawer.draw( domRootRect, { outlineColor: 'red', zIndex: 9999999 }, 'DOM ROOT' );\n\t\t\t\t// @if CK_DEBUG_DIALOG // }\n\n\t\t\t\tif ( domRootRect ) {\n\t\t\t\t\tthis.moveTo(\n\t\t\t\t\t\tMath.round( domRootRect.left + domRootRect.width / 2 - dialogRect.width / 2 ),\n\t\t\t\t\t\tdomRootRect.bottom + defaultOffset\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis._moveOffScreen();\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Calculates the visible DOM root part.\n\t */\n\tprivate _getVisibleDomRootRect( viewportRect: Rect ): Rect | null {\n\t\tlet visibleDomRootRect = new Rect( this._getCurrentDomRoot() ).getVisible();\n\n\t\tif ( !visibleDomRootRect ) {\n\t\t\treturn null;\n\t\t} else {\n\t\t\tvisibleDomRootRect = viewportRect.getIntersection( visibleDomRootRect );\n\n\t\t\tif ( !visibleDomRootRect ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\treturn visibleDomRootRect;\n\t}\n\n\t/**\n\t * Calculates the dialog element rect.\n\t */\n\tprivate _getDialogRect() {\n\t\treturn new Rect( this.element!.firstElementChild as HTMLElement );\n\t}\n\n\t/**\n\t * Returns a viewport `Rect` shrunk by the viewport offset config from all sides.\n\t *\n\t * TODO: This is a duplicate from position.ts module. It should either be exported there or land somewhere in utils.\n\t */\n\tprivate _getViewportRect(): Rect {\n\t\tconst viewportRect = new Rect( global.window );\n\n\t\t// Modals should not be restricted by the viewport offsets as they are always displayed on top of the page.\n\t\tif ( this.isModal ) {\n\t\t\treturn viewportRect;\n\t\t}\n\n\t\tconst viewportOffset = {\n\t\t\ttop: 0,\n\t\t\tbottom: 0,\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\t...this._getViewportOffset()\n\t\t};\n\n\t\tviewportRect.top += viewportOffset.top!;\n\t\tviewportRect.height -= viewportOffset.top!;\n\t\tviewportRect.bottom -= viewportOffset.bottom!;\n\t\tviewportRect.height -= viewportOffset.bottom!;\n\t\tviewportRect.left += viewportOffset.left!;\n\t\tviewportRect.right -= viewportOffset.right!;\n\t\tviewportRect.width -= viewportOffset.left! + viewportOffset.right!;\n\n\t\treturn viewportRect;\n\t}\n\n\t/**\n\t * Collects all focusable elements inside the dialog parts\n\t * and adds them to the focus tracker and focus cycler.\n\t */\n\tprivate _updateFocusCyclableItems() {\n\t\tconst focusables: Array<FocusableView> = [];\n\n\t\tif ( this.contentView ) {\n\t\t\tfor ( const child of this.contentView.children ) {\n\t\t\t\tif ( isFocusable( child ) ) {\n\t\t\t\t\tfocusables.push( child );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( this.actionsView ) {\n\t\t\tfocusables.push( this.actionsView );\n\t\t}\n\n\t\tif ( this.closeButtonView ) {\n\t\t\tfocusables.push( this.closeButtonView );\n\t\t}\n\n\t\tfocusables.forEach( focusable => {\n\t\t\tthis._focusables.add( focusable );\n\t\t\tthis.focusTracker.add( focusable.element! );\n\n\t\t\tif ( isViewWithFocusCycler( focusable ) ) {\n\t\t\t\tthis._focusCycler.chain( focusable.focusCycler );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the close button view that is displayed in the header view corner.\n\t */\n\tprivate _createCloseButton(): ButtonView {\n\t\tconst buttonView = new ButtonView( this.locale );\n\t\tconst t = this.locale!.t;\n\n\t\tbuttonView.set( {\n\t\t\tlabel: t( 'Close' ),\n\t\t\ttooltip: true,\n\t\t\ticon: icons.cancel\n\t\t} );\n\n\t\tbuttonView.on<ButtonExecuteEvent>( 'execute', () => this.fire<DialogViewCloseEvent>( 'close', { source: 'closeButton' } ) );\n\n\t\treturn buttonView;\n\t}\n}\n\n/**\n * An event fired when the dialog is closed.\n *\n * @eventName ~DialogView#close\n */\nexport type DialogViewCloseEvent = {\n\tname: 'close';\n\targs: [ { source: 'closeButton' | 'escKeyPress' } ];\n};\n\n/**\n * An event fired when the dialog is moved.\n *\n * @eventName ~DialogView#moveTo\n */\nexport type DialogViewMoveToEvent = DecoratedMethodEvent<DialogView, 'moveTo'>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dialog/dialog\n */\n\nimport type View from '../view.js';\nimport { type Editor, Plugin } from '@ckeditor/ckeditor5-core';\nimport DialogView, { type DialogViewCloseEvent, DialogViewPosition } from './dialogview.js';\nimport type { DialogActionButtonDefinition } from './dialogactionsview.js';\nimport type { DocumentChangeEvent } from '@ckeditor/ckeditor5-engine';\n\n/**\n * The dialog controller class. It is used to show and hide the {@link module:ui/dialog/dialogview~DialogView}.\n */\nexport default class Dialog extends Plugin {\n\t/**\n\t * The name of the currently visible dialog view instance.\n\t *\n\t * @observable\n\t */\n\tdeclare public id: string | null;\n\n\t/**\n\t * The currently visible dialog view instance.\n\t */\n\tpublic view?: DialogView;\n\n\t/**\n\t * The `Dialog` plugin instance which most recently showed the dialog.\n\t *\n\t * Only one dialog can be visible at once, even if there are many editor instances on the page.\n\t * If an editor wants to show a dialog, it should first hide the dialog that is already opened.\n\t * But only the `Dialog` instance that showed the dialog is able able to properly hide it.\n\t * This is why we need to store it in a globally available space (static property).\n\t * This way every `Dialog` plugin in every editor is able to correctly close any open dialog window.\n\t */\n\tprivate static _visibleDialogPlugin: Dialog | null;\n\n\t/**\n\t * A flag indicating whether the dialog is currently visible.\n\t *\n\t * @observable\n\t */\n\tdeclare public isOpen: boolean;\n\n\t/**\n\t * A configurable callback called when the dialog is hidden.\n\t */\n\tprivate _onHide: ( ( dialog: Dialog ) => void ) | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Dialog' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tconst t = editor.t;\n\n\t\tthis._initShowHideListeners();\n\t\tthis._initFocusToggler();\n\t\tthis._initMultiRootIntegration();\n\n\t\tthis.set( {\n\t\t\tid: null,\n\t\t\tisOpen: false\n\t\t} );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tcategoryId: 'navigation',\n\t\t\tkeystrokes: [ {\n\t\t\t\tlabel: t( 'Move focus in and out of an active dialog window' ),\n\t\t\t\tkeystroke: 'Ctrl+F6',\n\t\t\t\tmayRequireFn: true\n\t\t\t} ]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis._unlockBodyScroll();\n\t}\n\n\t/**\n\t * Initiates listeners for the `show` and `hide` events emitted by this plugin.\n\t *\n\t * We could not simply decorate the {@link #show} and {@link #hide} methods to fire events,\n\t * because they would be fired in the wrong order &ndash; first would be `show` and then `hide`\n\t * (because showing the dialog actually starts with hiding the previously visible one).\n\t * Hence, we added private methods {@link #_show} and {@link #_hide} which are called on events\n\t * in the desired sequence.\n\t */\n\tprivate _initShowHideListeners() {\n\t\tthis.on<DialogShowEvent>( 'show', ( evt, args ) => {\n\t\t\tthis._show( args );\n\t\t} );\n\n\t\t// 'low' priority allows to add custom callback between `_show()` and `onShow()`.\n\t\tthis.on<DialogShowEvent>( 'show', ( evt, args ) => {\n\t\t\tif ( args.onShow ) {\n\t\t\t\targs.onShow( this );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\tthis.on<DialogHideEvent>( 'hide', () => {\n\t\t\tif ( Dialog._visibleDialogPlugin ) {\n\t\t\t\tDialog._visibleDialogPlugin._hide();\n\t\t\t}\n\t\t} );\n\n\t\t// 'low' priority allows to add custom callback between `_hide()` and `onHide()`.\n\t\tthis.on<DialogHideEvent>( 'hide', () => {\n\t\t\tif ( this._onHide ) {\n\t\t\t\tthis._onHide( this );\n\t\t\t\tthis._onHide = undefined;\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Initiates keystroke handler for toggling the focus between the editor and the dialog view.\n\t */\n\tprivate _initFocusToggler() {\n\t\tconst editor = this.editor;\n\n\t\teditor.keystrokes.set( 'Ctrl+F6', ( data, cancel ) => {\n\t\t\tif ( !this.isOpen || this.view!.isModal ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this.view!.focusTracker.isFocused ) {\n\t\t\t\teditor.editing.view.focus();\n\t\t\t} else {\n\t\t\t\tthis.view!.focus();\n\t\t\t}\n\n\t\t\tcancel();\n\t\t} );\n\t}\n\n\t/**\n\t * Provides an integration between the root attaching and detaching and positioning of the view.\n\t */\n\tprivate _initMultiRootIntegration() {\n\t\tconst model = this.editor.model;\n\n\t\tmodel.document.on<DocumentChangeEvent>( 'change:data', () => {\n\t\t\tif ( !this.view ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst changedRoots = model.document.differ.getChangedRoots();\n\n\t\t\tfor ( const changes of changedRoots ) {\n\t\t\t\tif ( changes.state ) {\n\t\t\t\t\tthis.view.updatePosition();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Displays a dialog window.\n\t *\n\t * This method requires a {@link ~DialogDefinition} that defines the dialog's content, title, icon, action buttons, etc.\n\t *\n\t * For example, the following definition will create a dialog with:\n\t * * A header consisting of an icon, a title, and a \"Close\" button (it is added by default).\n\t * * A content consisting of a view with a single paragraph.\n\t * * A footer consisting of two buttons: \"Yes\" and \"No\".\n\t *\n\t * ```js\n\t * // Create the view that will be used as the dialog's content.\n\t * const textView = new View( locale );\n\t *\n\t * textView.setTemplate( {\n\t * \ttag: 'div',\n\t * \tattributes: {\n\t * \t\tstyle: {\n\t * \t\t\tpadding: 'var(--ck-spacing-large)',\n\t * \t\t\twhiteSpace: 'initial',\n\t * \t\t\twidth: '100%',\n\t * \t\t\tmaxWidth: '500px'\n\t * \t\t},\n\t * \t\ttabindex: -1\n\t * \t},\n\t * \tchildren: [\n\t * \t\t'Lorem ipsum dolor sit amet...'\n\t * \t]\n\t * } );\n\t *\n\t * // Show the dialog.\n\t * editor.plugins.get( 'Dialog' ).show( {\n\t *\tid: 'myDialog',\n\t * \ticon: 'myIcon', // This should be an SVG string.\n\t * \ttitle: 'My dialog',\n\t * \tcontent: textView,\n\t * \tactionButtons: [\n\t *\t\t{\n\t *\t\t\tlabel: t( 'Yes' ),\n\t *\t\t\tclass: 'ck-button-action',\n\t *\t\t\twithText: true,\n\t *\t\t\tonExecute: () => dialog.hide()\n\t *\t\t},\n\t *\t\t{\n\t *\t\t\tlabel: t( 'No' ),\n\t *\t\t\twithText: true,\n\t *\t\t\tonExecute: () => dialog.hide()\n\t *\t\t}\n\t *\t]\n\t * } );\n\t * ```\n\t *\n\t * By specifying the {@link ~DialogDefinition#onShow} and {@link ~DialogDefinition#onHide} callbacks\n\t * it is also possible to add callbacks that will be called when the dialog is shown or hidden.\n\t *\n\t * For example, the callbacks in the following definition:\n\t * * Disable the default behavior of the <kbd>Esc</kbd> key.\n\t * * Fire a custom event when the dialog gets hidden.\n\t *\n\t * ```js\n\t * editor.plugins.get( 'Dialog' ).show( {\n\t * \t// ...\n\t * \tonShow: dialog => {\n\t * \t\tdialog.view.on( 'close', ( evt, data ) => {\n\t * \t\t\t// Only prevent the event from the \"Esc\" key - do not affect the other ways of closing the dialog.\n\t * \t\t\tif ( data.source === 'escKeyPress' ) {\n\t * \t\t\t\tevt.stop();\n\t * \t\t\t}\n\t * \t\t} );\n\t * \t},\n\t * \tonHide: dialog => {\n\t * \t\tdialog.fire( 'dialogDestroyed' );\n\t * \t}\n\t * } );\n\t * ```\n\t *\n\t * Internally, calling this method:\n\t * 1. Hides the currently visible dialog (if any) calling the {@link #hide} method\n\t * (fires the {@link ~DialogHideEvent hide event}).\n\t * 2. Fires the {@link ~DialogShowEvent show event} which allows for adding callbacks that customize the\n\t * behavior of the dialog.\n\t * 3. Shows the dialog.\n\t */\n\tpublic show( dialogDefinition: DialogDefinition ): void {\n\t\tthis.hide();\n\n\t\tthis.fire<DialogShowEvent>( `show:${ dialogDefinition.id }`, dialogDefinition );\n\t}\n\n\t/**\n\t * Handles creating the {@link module:ui/dialog/dialogview~DialogView} instance and making it visible.\n\t */\n\tprivate _show( {\n\t\tid,\n\t\ticon,\n\t\ttitle,\n\t\thasCloseButton = true,\n\t\tcontent,\n\t\tactionButtons,\n\t\tclassName,\n\t\tisModal,\n\t\tposition,\n\t\tonHide\n\t}: DialogDefinition ) {\n\t\tconst editor = this.editor;\n\n\t\tthis.view = new DialogView( editor.locale, {\n\t\t\tgetCurrentDomRoot: () => {\n\t\t\t\treturn editor.editing.view.getDomRoot( editor.model.document.selection.anchor!.root.rootName )!;\n\t\t\t},\n\t\t\tgetViewportOffset: () => {\n\t\t\t\treturn editor.ui.viewportOffset;\n\t\t\t}\n\t\t} );\n\n\t\tconst view = this.view;\n\n\t\tview.on<DialogViewCloseEvent>( 'close', () => {\n\t\t\tthis.hide();\n\t\t} );\n\n\t\teditor.ui.view.body.add( view );\n\t\teditor.keystrokes.listenTo( view.element! );\n\n\t\t// Unless the user specified a position, modals should always be centered on the screen.\n\t\t// Otherwise, let's keep dialogs centered in the editing root by default.\n\t\tif ( !position ) {\n\t\t\tposition = isModal ? DialogViewPosition.SCREEN_CENTER : DialogViewPosition.EDITOR_CENTER;\n\t\t}\n\n\t\tif ( isModal ) {\n\t\t\tthis._lockBodyScroll();\n\t\t}\n\n\t\tview.set( {\n\t\t\tposition,\n\t\t\t_isVisible: true,\n\t\t\tclassName,\n\t\t\tisModal\n\t\t} );\n\n\t\tview.setupParts( {\n\t\t\ticon,\n\t\t\ttitle,\n\t\t\thasCloseButton,\n\t\t\tcontent,\n\t\t\tactionButtons\n\t\t} );\n\n\t\tthis.id = id;\n\n\t\tif ( onHide ) {\n\t\t\tthis._onHide = onHide;\n\t\t}\n\n\t\tthis.isOpen = true;\n\t\tDialog._visibleDialogPlugin = this;\n\t}\n\n\t/**\n\t * Hides the dialog. This method is decorated to enable interacting on the {@link ~DialogHideEvent hide event}.\n\t *\n\t * See {@link #show}.\n\t */\n\tpublic hide(): void {\n\t\tif ( Dialog._visibleDialogPlugin ) {\n\t\t\tDialog._visibleDialogPlugin.fire<DialogHideEvent>( `hide:${ Dialog._visibleDialogPlugin.id }` );\n\t\t}\n\t}\n\n\t/**\n\t * Destroys the {@link module:ui/dialog/dialogview~DialogView} and cleans up the stored dialog state.\n\t */\n\tprivate _hide(): void {\n\t\tif ( !this.view ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst view = this.view;\n\n\t\tif ( view.isModal ) {\n\t\t\tthis._unlockBodyScroll();\n\t\t}\n\n\t\t// Reset the content view to prevent its children from being destroyed in the standard\n\t\t// View#destroy() (and collections) chain. If the content children were left in there,\n\t\t// they would have to be re-created by the feature using the dialog every time the dialog\n\t\t// shows up.\n\t\tif ( view.contentView ) {\n\t\t\tview.contentView.reset();\n\t\t}\n\n\t\teditor.ui.view.body.remove( view );\n\t\teditor.ui.focusTracker.remove( view.element! );\n\t\teditor.keystrokes.stopListening( view.element! );\n\n\t\tview.destroy();\n\t\teditor.editing.view.focus();\n\n\t\tthis.id = null;\n\t\tthis.isOpen = false;\n\t\tDialog._visibleDialogPlugin = null;\n\t}\n\n\t/**\n\t * Makes the <body> unscrollable (e.g. when the modal shows up).\n\t */\n\tprivate _lockBodyScroll(): void {\n\t\tdocument.documentElement.classList.add( 'ck-dialog-scroll-locked' );\n\t}\n\n\t/**\n\t * Makes the <body> scrollable again (e.g. once the modal hides).\n\t */\n\tprivate _unlockBodyScroll(): void {\n\t\tdocument.documentElement.classList.remove( 'ck-dialog-scroll-locked' );\n\t}\n}\n\n/**\n * The definition that describes a dialog window and its content. Passed to the {@link module:ui/dialog/dialog~Dialog#show} method.\n */\nexport interface DialogDefinition {\n\n\t/**\n\t * A unique identifier of the dialog. It allows for distinguishing between different dialogs and their visibility.\n\t * For instance, when open, the ID of the currently visible dialog is stored in {@link module:ui/dialog/dialog~Dialog#id}.\n\t *\n\t * The `id` is also passed along the {@link module:ui/dialog/dialog~DialogShowEvent} and {@link module:ui/dialog/dialog~DialogHideEvent}\n\t * events.\n\t */\n\tid: string;\n\n\t/**\n\t * The SVG string of an icon displayed in dialogs's header. Used only when {@link #title} is also set\n\t * and the header is displayed.\n\t *\n\t * See more in {@link module:ui/icon/iconview~IconView#content}.\n\t */\n\ticon?: string;\n\n\t/**\n\t * A title displayed in the dialogs's header. It also works as an accessible name of the dialog used by assistive technologies.\n\t *\n\t * When not set, the header is not displayed. Affects {@link #icon} and {@link #hasCloseButton}.\n\t */\n\ttitle?: string;\n\n\t/**\n\t * A flag indicating whether the dialog should have a close button in the header.\n\t * `true` by default. Works when {@link #title} is also set and the header is displayed.\n\t *\n\t * **Note**: If you hide the close button, make sure that the dialog can be closed in another way.\n\t */\n\thasCloseButton?: boolean;\n\n\t/**\n\t * The content of the dialog. It can be a single {@link module:ui/view~View} or an array of views.\n\t */\n\tcontent?: View | Array<View>;\n\n\t/**\n\t * The action buttons displayed in the dialog's footer.\n\t */\n\tactionButtons?: Array<DialogActionButtonDefinition>;\n\n\t/**\n\t * An additional CSS class set on the outermost (`.ck.ck-dialog`) container element allowing for visual customization.\n\t */\n\tclassName?: string;\n\n\t/**\n\t * When set to `true`, the dialog will become a modal, that is, it will block the UI until it is closed.\n\t */\n\tisModal?: boolean;\n\n\t/**\n\t * Available dialog positions. By default `DialogViewPosition.EDITOR_CENTER` is used for {@link #isModal non-modals}\n\t * and `DialogViewPosition.SCREEN_CENTER` for modals.\n\t *\n\t * {@link module:ui/dialog/dialogview#DialogViewPosition Learn more} about available positions.\n\t */\n\tposition?: typeof DialogViewPosition[ keyof typeof DialogViewPosition ];\n\n\t/**\n\t * A callback called when the dialog shows up with a `low` priority. It allows for setting up the dialog's {@link #content}.\n\t */\n\tonShow?: ( dialog: Dialog ) => void;\n\n\t/**\n\t * A callback called when the dialog hides with a `low` priority.\n\t * It allows for cleaning up (for example, resetting) the dialog's {@link #content}.\n\t */\n\tonHide?: ( dialog: Dialog ) => void;\n}\n\n/**\n * An event fired after {@link module:ui/dialog/dialog~Dialog#show} is called. You can use it to customize the behavior\n * of any dialog.\n *\n * ```js\n * import { DialogViewPosition } from 'ckeditor5/src/ui.js';\n *\n * // ...\n *\n * // Changes the position of the \"Find and Replace\" dialog.\n * editor.plugins.get( 'Dialog' ).on( 'show:findAndReplace', ( evt, data ) => {\n * \tObject.assign( data, { position: DialogViewPosition.EDITOR_BOTTOM_CENTER } );\n * }, { priority: 'high' } );\n * ```\n *\n * @eventName ~Dialog#show\n */\nexport type DialogShowEvent = {\n\tname: 'show' | `show:${ string }`;\n\targs: [ dialogDefinition: DialogDefinition ];\n};\n\n/**\n * An event fired after {@link module:ui/dialog/dialog~Dialog#hide} is called. You can use it to customize the behavior\n * of any dialog.\n *\n * ```js\n * // Logs after the \"Find and Replace\" dialog gets hidden\n * editor.plugins.get( 'Dialog' ).on( 'hide:findAndReplace', () => {\n * \tconsole.log( 'The \"Find and Replace\" dialog was hidden.' );\n * } );\n * ```\n *\n * @eventName ~Dialog#hide\n */\nexport type DialogHideEvent = {\n\tname: 'hide' | `hide:${ string }`;\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/button/listitembuttonview\n */\n\nimport type { ObservableChangeEvent, Locale } from '@ckeditor/ckeditor5-utils';\nimport type ButtonLabel from './buttonlabel.js';\nimport type ViewCollection from '../viewcollection.js';\n\nimport { icons } from '@ckeditor/ckeditor5-core';\nimport ButtonView from './buttonview.js';\nimport ButtonLabelView from './buttonlabelview.js';\nimport IconView from '../icon/iconview.js';\nimport View from '../view.js';\n\nimport '../../theme/components/button/listitembutton.css';\n\n/**\n * Button that is used as dropdown list item entry.\n */\nexport default class ListItemButtonView extends ButtonView {\n\t/**\n\t * Indicates whether the button view has reserved space for a check holder.\n\t *\n\t * @observable\n\t */\n\tdeclare public hasCheckSpace: boolean;\n\n\t/**\n\t * The flag that indicates if the button should render a check holder.\n\t *\n\t * @internal\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _hasCheck: boolean;\n\n\t/**\n\t * Holds the view for the check icon of a button list item.\n\t */\n\tprivate readonly _checkIconHolderView = new CheckIconHolderView();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale, labelView: ButtonLabel = new ButtonLabelView() ) {\n\t\tsuper( locale, labelView );\n\n\t\tthis.set( {\n\t\t\thasCheckSpace: false,\n\t\t\t_hasCheck: this.isToggleable\n\t\t} );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-list-item-button',\n\t\t\t\t\tbind.if( 'isToggleable', 'ck-list-item-button_toggleable' )\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\n\t\tthis.bind( '_hasCheck' ).to(\n\t\t\tthis, 'hasCheckSpace',\n\t\t\tthis, 'isToggleable',\n\t\t\t( hasCheckSpace, isToggleable ) => hasCheckSpace || isToggleable\n\t\t);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tif ( this._hasCheck ) {\n\t\t\tthis.children.add( this._checkIconHolderView, 0 );\n\t\t}\n\n\t\tthis._watchCheckIconHolderMount();\n\t}\n\n\t/**\n\t * Renders the check icon if the button is toggleable.\n\t */\n\tprivate _watchCheckIconHolderMount() {\n\t\tthis._checkIconHolderView\n\t\t\t.bind( 'isOn' )\n\t\t\t.to( this, 'isOn', value => this.isToggleable && value );\n\n\t\tthis.on<ObservableChangeEvent<boolean>>(\n\t\t\t'change:_hasCheck',\n\t\t\t( evt, propertyName, hasCheck ) => {\n\t\t\t\tconst { children, _checkIconHolderView } = this;\n\n\t\t\t\tif ( hasCheck ) {\n\t\t\t\t\tchildren.add( _checkIconHolderView, 0 );\n\t\t\t\t} else {\n\t\t\t\t\tchildren.remove( _checkIconHolderView );\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n}\n\nexport class CheckIconHolderView extends View {\n\t/**\n\t * Collection of child views.\n\t */\n\tpublic readonly children: ViewCollection<View>;\n\n\t/**\n\t * Indicates whether the button is in the \"on\" state.\n\t */\n\tdeclare public isOn: boolean;\n\n\t/**\n\t * The view for the check icon of the button list item.\n\t */\n\tprivate readonly _checkIconView: IconView = this._createCheckIconView();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.set( 'isOn', false );\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tchildren: this.children,\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list-item-button__check-holder',\n\t\t\t\t\tbind.to( 'isOn', isOn => isOn ? 'ck-on' : 'ck-off' )\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tif ( this.isOn ) {\n\t\t\tthis.children.add( this._checkIconView, 0 );\n\t\t}\n\n\t\tthis._watchCheckIconMount();\n\t}\n\n\t/**\n\t * Renders the check icon if the button is toggleable.\n\t */\n\tprivate _watchCheckIconMount() {\n\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:isOn', ( evt, propertyName, isOn ) => {\n\t\t\tconst { children, _checkIconView } = this;\n\n\t\t\tif ( isOn && !children.has( _checkIconView ) ) {\n\t\t\t\tchildren.add( _checkIconView );\n\t\t\t} else if ( !isOn && children.has( _checkIconView ) ) {\n\t\t\t\tchildren.remove( _checkIconView );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a check icon view.\n\t */\n\tprivate _createCheckIconView() {\n\t\tconst iconView = new IconView();\n\n\t\ticonView.content = icons.check;\n\t\ticonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-list-item-button__check-icon'\n\t\t\t}\n\t\t} );\n\n\t\treturn iconView;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarmenulistitembuttonview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport ListItemButtonView from '../button/listitembuttonview.js';\n\nimport '../../theme/components/menubar/menubarmenulistitembutton.css';\n\n/**\n * A menu bar list button view. Buttons like this one execute user actions.\n */\nexport default class MenuBarMenuListItemButtonView extends ListItemButtonView {\n\t/**\n\t * Creates an instance of the menu bar list button view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.set( {\n\t\t\twithText: true,\n\t\t\twithKeystroke: true,\n\t\t\ttooltip: false,\n\t\t\trole: 'menuitem'\n\t\t} );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck-menu-bar__menu__item__button' ]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/label/labelview\n */\n\nimport View from '../view.js';\n\nimport { uid, type Locale } from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/label/label.css';\n\n/**\n * The label view class.\n */\nexport default class LabelView extends View {\n\t/**\n\t * An unique id of the label. It can be used by other UI components to reference\n\t * the label, for instance, using the `aria-describedby` DOM attribute.\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * The text of the label.\n\t *\n\t * @observable\n\t */\n\tdeclare public text: string | undefined;\n\n\t/**\n\t * The `for` attribute of the label (i.e. to pair with an `<input>` element).\n\t *\n\t * @observable\n\t */\n\tdeclare public for: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.set( 'text', undefined );\n\t\tthis.set( 'for', undefined );\n\n\t\tthis.id = `ck-editor__label_${ uid() }`;\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'label',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-label'\n\t\t\t\t],\n\t\t\t\tid: this.id,\n\t\t\t\tfor: bind.to( 'for' )\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: bind.to( 'text' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editorui/accessibilityhelp/accessibilityhelpcontentview\n */\n\nimport {\n\tcreateElement,\n\tenv,\n\tgetEnvKeystrokeText,\n\ttype Locale\n} from '@ckeditor/ckeditor5-utils';\n\nimport View from '../../view.js';\nimport LabelView from '../../label/labelview.js';\nimport type {\n\tKeystrokeInfoCategoryDefinition,\n\tKeystrokeInfoDefinition,\n\tKeystrokeInfoDefinitions,\n\tKeystrokeInfoGroupDefinition\n} from '@ckeditor/ckeditor5-core';\n\n/**\n * The view displaying keystrokes in the Accessibility help dialog.\n */\nexport default class AccessibilityHelpContentView extends View<HTMLDivElement> {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale, keystrokes: KeystrokeInfoDefinitions ) {\n\t\tsuper( locale );\n\n\t\tconst t = locale.t;\n\t\tconst helpLabel = new LabelView();\n\n\t\thelpLabel.text = t( 'Help Contents. To close this dialog press ESC.' );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck', 'ck-accessibility-help-dialog__content' ],\n\t\t\t\t'aria-labelledby': helpLabel.id,\n\t\t\t\trole: 'document',\n\t\t\t\ttabindex: -1\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tcreateElement( document, 'p', {}, t( 'Below, you can find a list of keyboard shortcuts that can be used in the editor.' ) ),\n\t\t\t\t...this._createCategories( Array.from( keystrokes.values() ) ),\n\t\t\t\thelpLabel\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focus(): void {\n\t\tthis.element!.focus();\n\t}\n\n\t/**\n\t * Creates `<section><h3>Category label</h3>...</section>` elements for each category of keystrokes.\n\t */\n\tprivate _createCategories( categories: Array<KeystrokeInfoCategoryDefinition> ): Array<HTMLElement> {\n\t\treturn categories.map( categoryDefinition => {\n\t\t\tconst elements: Array<HTMLElement> = [\n\t\t\t\t// Category header.\n\t\t\t\tcreateElement( document, 'h3', {}, categoryDefinition.label ),\n\n\t\t\t\t// Category definitions (<dl>) and their optional headers (<h4>).\n\t\t\t\t...Array.from( categoryDefinition.groups.values() )\n\t\t\t\t\t.map( groupDefinition => this._createGroup( groupDefinition ) )\n\t\t\t\t\t.flat()\n\t\t\t];\n\n\t\t\t// Category description (<p>).\n\t\t\tif ( categoryDefinition.description ) {\n\t\t\t\telements.splice( 1, 0, createElement( document, 'p', {}, categoryDefinition.description ) );\n\t\t\t}\n\n\t\t\treturn createElement( document, 'section', {}, elements );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates `[<h4>Optional label</h4>]<dl>...</dl>` elements for each group of keystrokes in a category.\n\t */\n\tprivate _createGroup( groupDefinition: KeystrokeInfoGroupDefinition ): Array<HTMLElement> {\n\t\tconst definitionAndDescriptionElements = groupDefinition.keystrokes\n\t\t\t.sort( ( a, b ) => a.label.localeCompare( b.label ) )\n\t\t\t.map( keystrokeDefinition => this._createGroupRow( keystrokeDefinition ) )\n\t\t\t.flat();\n\n\t\tconst elements: Array<HTMLElement> = [\n\t\t\tcreateElement( document, 'dl', {}, definitionAndDescriptionElements )\n\t\t];\n\n\t\tif ( groupDefinition.label ) {\n\t\t\telements.unshift( createElement( document, 'h4', {}, groupDefinition.label ) );\n\t\t}\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Creates `<dt>Keystroke label</dt><dd>Keystroke definition</dd>` elements for each keystroke in a group.\n\t */\n\tprivate _createGroupRow( keystrokeDefinition: KeystrokeInfoDefinition ): [ HTMLElement, HTMLElement ] {\n\t\tconst t = this.locale!.t;\n\t\tconst dt = createElement( document, 'dt' );\n\t\tconst dd = createElement( document, 'dd' );\n\t\tconst normalizedKeystrokeDefinition = normalizeKeystrokeDefinition( keystrokeDefinition.keystroke );\n\t\tconst keystrokeAlternativeHTMLs = [];\n\n\t\tfor ( const keystrokeAlternative of normalizedKeystrokeDefinition ) {\n\t\t\tkeystrokeAlternativeHTMLs.push( keystrokeAlternative.map( keystrokeToEnvKbd ).join( '' ) );\n\t\t}\n\n\t\tdt.innerHTML = keystrokeDefinition.label;\n\t\tdd.innerHTML = keystrokeAlternativeHTMLs.join( ', ' ) +\n\t\t\t( keystrokeDefinition.mayRequireFn && env.isMac ? ` ${ t( '(may require <kbd>Fn</kbd>)' ) }` : '' );\n\n\t\treturn [ dt, dd ];\n\t}\n}\n\nfunction keystrokeToEnvKbd( keystroke: string ): string {\n\treturn getEnvKeystrokeText( keystroke )\n\t\t.split( '+' )\n\t\t.map( part => `<kbd>${ part }</kbd>` )\n\t\t.join( '+' );\n}\n\nfunction normalizeKeystrokeDefinition( definition: KeystrokeInfoDefinition[ 'keystroke' ] ): Array<Array<string>> {\n\tif ( typeof definition === 'string' ) {\n\t\treturn [ [ definition ] ];\n\t}\n\n\tif ( typeof definition[ 0 ] === 'string' ) {\n\t\treturn [ definition as Array<string> ];\n\t}\n\n\treturn definition as Array<Array<string>>;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editorui/accessibilityhelp/accessibilityhelp\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport ButtonView from '../../button/buttonview.js';\nimport Dialog from '../../dialog/dialog.js';\nimport MenuBarMenuListItemButtonView from '../../menubar/menubarmenulistitembuttonview.js';\nimport AccessibilityHelpContentView from './accessibilityhelpcontentview.js';\nimport { getEnvKeystrokeText } from '@ckeditor/ckeditor5-utils';\nimport type { EditorUIReadyEvent } from '../../editorui/editorui.js';\nimport type { AddRootEvent } from '@ckeditor/ckeditor5-editor-multi-root';\nimport type { DowncastWriter, ViewRootEditableElement } from '@ckeditor/ckeditor5-engine';\n\nimport accessibilityIcon from '../../../theme/icons/accessibility.svg';\nimport '../../../theme/components/editorui/accessibilityhelp.css';\n\n/**\n * A plugin that brings the accessibility help dialog to the editor available under the <kbd>Alt</kbd>+<kbd>0</kbd>\n * keystroke and via the \"Accessibility help\" toolbar button. The dialog displays a list of keystrokes that can be used\n * by the user to perform various actions in the editor.\n *\n * Keystroke information is loaded from {@link module:core/accessibility~Accessibility#keystrokeInfos}. New entries can be\n * added using the API provided by the {@link module:core/accessibility~Accessibility} class.\n */\nexport default class AccessibilityHelp extends Plugin {\n\t/**\n\t * The view that displays the dialog content (list of keystrokes).\n\t * Created when the dialog is opened for the first time.\n\t */\n\tpublic contentView: AccessibilityHelpContentView | null = null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Dialog ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'AccessibilityHelp' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\n\t\teditor.ui.componentFactory.add( 'accessibilityHelp', () => {\n\t\t\tconst button = this._createButton( ButtonView );\n\n\t\t\tbutton.set( {\n\t\t\t\ttooltip: true,\n\t\t\t\twithText: false,\n\t\t\t\tlabel: t( 'Accessibility help' )\n\t\t\t} );\n\n\t\t\treturn button;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:accessibilityHelp', () => {\n\t\t\tconst button = this._createButton( MenuBarMenuListItemButtonView );\n\n\t\t\tbutton.label = t( 'Accessibility' );\n\n\t\t\treturn button;\n\t\t} );\n\n\t\teditor.keystrokes.set( 'Alt+0', ( evt, cancel ) => {\n\t\t\tthis._toggleDialog();\n\t\t\tcancel();\n\t\t} );\n\n\t\tthis._setupRootLabels();\n\t}\n\n\t/**\n\t * Creates a button to show accessibility help dialog, for use either in toolbar or in menu bar.\n\t */\n\tprivate _createButton<T extends typeof ButtonView>( ButtonClass: T ): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst dialog = editor.plugins.get( 'Dialog' );\n\t\tconst locale = editor.locale;\n\t\tconst view = new ButtonClass( locale ) as InstanceType<T>;\n\n\t\tview.set( {\n\t\t\tkeystroke: 'Alt+0',\n\t\t\ticon: accessibilityIcon,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\tview.on( 'execute', () => this._toggleDialog() );\n\t\tview.bind( 'isOn' ).to( dialog, 'id', id => id === 'accessibilityHelp' );\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Injects a help text into each editing root's `aria-label` attribute allowing assistive technology users\n\t * to discover the availability of the Accessibility help dialog.\n\t */\n\tprivate _setupRootLabels(): void {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.on<EditorUIReadyEvent>( 'ready', () => {\n\t\t\teditingView.change( writer => {\n\t\t\t\tfor ( const root of editingView.document.roots ) {\n\t\t\t\t\taddAriaLabelTextToRoot( writer, root );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\teditor.on<AddRootEvent>( 'addRoot', ( evt, modelRoot ) => {\n\t\t\t\tconst viewRoot = editor.editing.view.document.getRoot( modelRoot.rootName )!;\n\n\t\t\t\teditingView.change( writer => addAriaLabelTextToRoot( writer, viewRoot ) );\n\t\t\t}, { priority: 'low' } );\n\t\t} );\n\n\t\tfunction addAriaLabelTextToRoot( writer: DowncastWriter, viewRoot: ViewRootEditableElement ) {\n\t\t\tconst currentAriaLabel = viewRoot.getAttribute( 'aria-label' );\n\t\t\tconst newAriaLabel = [ currentAriaLabel, t( 'Press %0 for help.', [ getEnvKeystrokeText( 'Alt+0' ) ] ) ]\n\t\t\t\t.filter( segment => segment )\n\t\t\t\t.join( '. ' );\n\n\t\t\twriter.setAttribute( 'aria-label', newAriaLabel, viewRoot );\n\t\t}\n\t}\n\n\t/**\n\t * Shows the accessibility help dialog. Also, creates {@link #contentView} on demand.\n\t */\n\tprivate _toggleDialog(): void {\n\t\tconst editor = this.editor;\n\t\tconst dialog = editor.plugins.get( 'Dialog' );\n\t\tconst t = editor.locale.t;\n\n\t\tif ( !this.contentView ) {\n\t\t\tthis.contentView = new AccessibilityHelpContentView( editor.locale, editor.accessibility.keystrokeInfos );\n\t\t}\n\n\t\tif ( dialog.id === 'accessibilityHelp' ) {\n\t\t\tdialog.hide();\n\t\t} else {\n\t\t\tdialog.show( {\n\t\t\t\tid: 'accessibilityHelp',\n\t\t\t\tclassName: 'ck-accessibility-help-dialog',\n\t\t\t\ttitle: t( 'Accessibility help' ),\n\t\t\t\ticon: accessibilityIcon,\n\t\t\t\thasCloseButton: true,\n\t\t\t\tcontent: this.contentView\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editorui/bodycollection\n */\n\n/* globals document */\n\nimport Template from '../template.js';\nimport ViewCollection from '../viewcollection.js';\nimport type View from '../view.js';\n\nimport { createElement, type Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * This is a special {@link module:ui/viewcollection~ViewCollection} dedicated to elements that are detached\n * from the DOM structure of the editor, like panels, icons, etc.\n *\n * The body collection is available in the {@link module:ui/editorui/editoruiview~EditorUIView#body `editor.ui.view.body`} property.\n * Any plugin can add a {@link module:ui/view~View view} to this collection.\n * These views will render in a container placed directly in the `<body>` element.\n * The editor will detach and destroy this collection when the editor will be {@link module:core/editor/editor~Editor#destroy destroyed}.\n *\n * If you need to control the life cycle of the body collection on your own, you can create your own instance of this class.\n *\n * A body collection will render itself automatically in the DOM body element as soon as you call {@link ~BodyCollection#attachToDom}.\n * If you create multiple body collections, this class will create a special wrapper element in the DOM to limit the number of\n * elements created directly in the body and remove it when the last body collection will be\n * {@link ~BodyCollection#detachFromDom detached}.\n */\nexport default class BodyCollection extends ViewCollection {\n\t/**\n\t * The {@link module:core/editor/editor~Editor#locale editor's locale} instance.\n\t * See the view {@link module:ui/view~View#locale locale} property.\n\t */\n\tpublic readonly locale: Locale;\n\n\t/**\n\t * The element holding elements of the body region.\n\t */\n\tprivate _bodyCollectionContainer?: HTMLElement;\n\n\t/**\n\t * Creates a new instance of the {@link module:ui/editorui/bodycollection~BodyCollection}.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor editor's locale} instance.\n\t * @param initialItems The initial items of the collection.\n\t */\n\tconstructor( locale: Locale, initialItems: Iterable<View> = [] ) {\n\t\tsuper( initialItems );\n\n\t\tthis.locale = locale;\n\t}\n\n\t/**\n\t * The element holding elements of the body region.\n\t */\n\tpublic get bodyCollectionContainer(): HTMLElement | undefined {\n\t\treturn this._bodyCollectionContainer;\n\t}\n\n\t/**\n\t * Attaches the body collection to the DOM body element. You need to execute this method to render the content of\n\t * the body collection.\n\t */\n\tpublic attachToDom(): void {\n\t\tthis._bodyCollectionContainer = new Template( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset_all',\n\t\t\t\t\t'ck-body',\n\t\t\t\t\t'ck-rounded-corners'\n\t\t\t\t],\n\t\t\t\tdir: this.locale.uiLanguageDirection,\n\t\t\t\trole: 'application'\n\t\t\t},\n\t\t\tchildren: this\n\t\t} ).render() as HTMLElement;\n\n\t\tlet wrapper = document.querySelector( '.ck-body-wrapper' );\n\n\t\tif ( !wrapper ) {\n\t\t\twrapper = createElement( document, 'div', { class: 'ck-body-wrapper' } );\n\t\t\tdocument.body.appendChild( wrapper );\n\t\t}\n\n\t\twrapper.appendChild( this._bodyCollectionContainer );\n\t}\n\n\t/**\n\t * Detaches the collection from the DOM structure. Use this method when you do not need to use the body collection\n\t * anymore to clean-up the DOM structure.\n\t */\n\tpublic detachFromDom(): void {\n\t\tsuper.destroy();\n\n\t\tif ( this._bodyCollectionContainer ) {\n\t\t\tthis._bodyCollectionContainer.remove();\n\t\t}\n\n\t\tconst wrapper = document.querySelector( '.ck-body-wrapper' );\n\n\t\tif ( wrapper && wrapper.childElementCount == 0 ) {\n\t\t\twrapper.remove();\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/button/switchbuttonview\n */\n\nimport View from '../view.js';\nimport ButtonView from './buttonview.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/button/switchbutton.css';\n\n/**\n * The switch button view class.\n *\n * ```ts\n * const view = new SwitchButtonView();\n *\n * view.set( {\n * \twithText: true,\n * \tlabel: 'Switch me!'\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n */\nexport default class SwitchButtonView extends ButtonView {\n\t/**\n\t * The toggle switch of the button.\n\t */\n\tpublic readonly toggleSwitchView: View;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.isToggleable = true;\n\t\tthis.toggleSwitchView = this._createToggleView();\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-switchbutton'\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.children.add( this.toggleSwitchView );\n\t}\n\n\t/**\n\t * Creates a toggle child view.\n\t */\n\tprivate _createToggleView() {\n\t\tconst toggleSwitchView = new View();\n\n\t\ttoggleSwitchView.setTemplate( {\n\t\t\ttag: 'span',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-button__toggle'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-button__toggle__inner'\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\treturn toggleSwitchView;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/button/filedialogbuttonview\n */\n\nimport View from '../view.js';\nimport ButtonView from './buttonview.js';\nimport type { ButtonExecuteEvent } from './button.js';\n\nimport type { Constructor, Locale, Mixed } from '@ckeditor/ckeditor5-utils';\nimport ListItemButtonView from './listitembuttonview.js';\n\n/**\n * The file dialog button view.\n *\n * This component provides a button that opens the native file selection dialog.\n * It can be used to implement the UI of a file upload feature.\n *\n * ```ts\n * const view = new FileDialogButtonView( locale );\n *\n * view.set( {\n * \tacceptedType: 'image/*',\n * \tallowMultipleFiles: true\n * \tlabel: t( 'Insert image' ),\n * \ticon: imageIcon,\n * \ttooltip: true\n * } );\n *\n * view.on( 'done', ( evt, files ) => {\n * \tfor ( const file of Array.from( files ) ) {\n * \t\tconsole.log( 'Selected file', file );\n * \t}\n * } );\n * ```\n */\nexport default class FileDialogButtonView extends /* #__PURE__ */ FileDialogViewMixin( ButtonView ) {}\n\n/**\n * The file dialog button view used in a lists.\n *\n * This component provides a button that opens the native file selection dialog.\n * It can be used to implement the UI of a file upload feature.\n *\n* ```ts\n * const view = new FileDialogListItemButtonView( locale );\n *\n * view.set( {\n * \tacceptedType: 'image/*',\n * \tallowMultipleFiles: true\n * \tlabel: t( 'Insert image' ),\n * \ticon: imageIcon,\n * \ttooltip: true\n * } );\n *\n * view.on( 'done', ( evt, files ) => {\n * \tfor ( const file of Array.from( files ) ) {\n * \t\tconsole.log( 'Selected file', file );\n * \t}\n * } );\n * ```\n */\nexport class FileDialogListItemButtonView extends /* #__PURE__ */ FileDialogViewMixin( ListItemButtonView ) {}\n\n/**\n * Mixin function that enhances a base button view class with file dialog functionality. It is used\n * to create a button view class that opens the native select file dialog when clicked.\n *\n * The enhanced view includes a button and a hidden file input. When the button is clicked, the file dialog is opened.\n * The mixin adds properties and methods to the base class to handle the file selection.\n *\n * @param view The base class to be enhanced with file dialog functionality.\n * @returns A new class that extends the base class and includes the file dialog functionality.\n */\nfunction FileDialogViewMixin<Base extends Constructor<ButtonView>>( view: Base ): Mixed<Base, FileDialogButtonViewBase> {\n\tabstract class FileDialogView extends view implements FileDialogButtonViewBase {\n\t\t/**\n\t\t * The button view of the component.\n\t\t *\n\t\t * @deprecated\n\t\t */\n\t\tpublic buttonView: ButtonView;\n\n\t\t/**\n\t\t * A hidden `<input>` view used to execute file dialog.\n\t\t */\n\t\tprivate _fileInputView: FileInputView;\n\n\t\t/**\n\t\t * Accepted file types. Can be provided in form of file extensions, media type or one of:\n\t\t * * `audio/*`,\n\t\t * * `video/*`,\n\t\t * * `image/*`.\n\t\t *\n\t\t * @observable\n\t\t */\n\t\tdeclare public acceptedType: string;\n\n\t\t/**\n\t\t * Indicates if multiple files can be selected. Defaults to `true`.\n\t\t *\n\t\t * @observable\n\t\t */\n\t\tdeclare public allowMultipleFiles: boolean;\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tconstructor( ...args: Array<any> ) {\n\t\t\tsuper( ...args );\n\n\t\t\t// For backward compatibility.\n\t\t\tthis.buttonView = this;\n\n\t\t\tthis._fileInputView = new FileInputView( this.locale );\n\t\t\tthis._fileInputView.bind( 'acceptedType' ).to( this );\n\t\t\tthis._fileInputView.bind( 'allowMultipleFiles' ).to( this );\n\n\t\t\tthis._fileInputView.delegate( 'done' ).to( this );\n\n\t\t\tthis.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\t\tthis._fileInputView.open();\n\t\t\t} );\n\n\t\t\tthis.extendTemplate( {\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: 'ck-file-dialog-button'\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t/**\n\t\t * @inheritDoc\n\t\t */\n\t\tpublic override render(): void {\n\t\t\tsuper.render();\n\n\t\t\tthis.children.add( this._fileInputView );\n\t\t}\n\t}\n\n\treturn FileDialogView as any;\n}\n\n/**\n * Represents the base view for a file dialog button component.\n */\ntype FileDialogButtonViewBase = View & {\n\n\t/**\n\t * The button view of the component.\n\t *\n\t * @deprecated\n\t */\n\tbuttonView: ButtonView;\n\n\t/**\n\t * Accepted file types. Can be provided in form of file extensions, media type or one of:\n\t * * `audio/*`,\n\t * * `video/*`,\n\t * * `image/*`.\n\t *\n\t * @observable\n\t */\n\tacceptedType: string;\n\n\t/**\n\t * Indicates if multiple files can be selected. Defaults to `true`.\n\t *\n\t * @observable\n\t */\n\tallowMultipleFiles: boolean;\n};\n\n/**\n * The hidden file input view class.\n */\nclass FileInputView extends View<HTMLInputElement> {\n\t/**\n\t * Accepted file types. Can be provided in form of file extensions, media type or one of:\n\t * * `audio/*`,\n\t * * `video/*`,\n\t * * `image/*`.\n\t *\n\t * @observable\n\t */\n\tdeclare public acceptedType?: string;\n\n\t/**\n\t * Indicates if multiple files can be selected. Defaults to `false`.\n\t *\n\t * @observable\n\t */\n\tdeclare public allowMultipleFiles: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.set( 'acceptedType', undefined );\n\t\tthis.set( 'allowMultipleFiles', false );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'input',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-hidden'\n\t\t\t\t],\n\t\t\t\ttype: 'file',\n\t\t\t\ttabindex: '-1',\n\t\t\t\taccept: bind.to( 'acceptedType' ),\n\t\t\t\tmultiple: bind.to( 'allowMultipleFiles' )\n\t\t\t},\n\n\t\t\ton: {\n\t\t\t\t// Removing from code coverage since we cannot programmatically set input element files.\n\t\t\t\tchange: bind.to( /* istanbul ignore next -- @preserve */ () => {\n\t\t\t\t\tif ( this.element && this.element.files && this.element.files.length ) {\n\t\t\t\t\t\tthis.fire<FileInputViewDoneEvent>( 'done', this.element.files );\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.element!.value = '';\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Opens file dialog.\n\t */\n\tpublic open(): void {\n\t\tthis.element!.click();\n\t}\n}\n\n/**\n * Fired when file dialog is closed with file selected.\n *\n * ```ts\n * view.on( 'done', ( evt, files ) => {\n * \tfor ( const file of files ) {\n * \t\tconsole.log( 'Selected file', file );\n * \t}\n * }\n * ```\n */\nexport type FileInputViewDoneEvent = {\n\tname: 'done';\n\targs: [ files: FileList ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/collapsible/collapsibleview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport View from '../view.js';\nimport ButtonView from '../button/buttonview.js';\nimport type ViewCollection from '../viewcollection.js';\nimport type { FocusableView } from '../focuscycler.js';\n\nimport dropdownArrowIcon from '../../theme/icons/dropdown-arrow.svg';\n\nimport '../../theme/components/collapsible/collapsible.css';\n\n/**\n * A collapsible UI component. Consists of a labeled button and a container which can be collapsed\n * by clicking the button. The collapsible container can be a host to other UI views.\n *\n * @internal\n */\nexport default class CollapsibleView extends View {\n\t/**\n\t * `true` when the container with {@link #children} is collapsed. `false` otherwise.\n\t *\n\t * @observable\n\t */\n\tdeclare public isCollapsed: boolean;\n\n\t/**\n\t * The text label of the {@link #buttonView}.\n\t *\n\t * @observable\n\t * @default 'Show more'\n\t */\n\tdeclare public label: string;\n\n\t/**\n\t * The ID of the label inside the {@link #buttonView} that describes the collapsible\n\t * container for assistive technologies. Set after the button was {@link #render rendered}.\n\t *\n\t * @internal\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _collapsibleAriaLabelUid: string | undefined;\n\n\t/**\n\t * The main button that, when clicked, collapses or expands the container with {@link #children}.\n\t */\n\tpublic readonly buttonView: ButtonView;\n\n\t/**\n\t * A collection of the child views that can be collapsed by clicking the {@link #buttonView}.\n\t */\n\tpublic readonly children: ViewCollection<FocusableView>;\n\n\t/**\n\t * Creates an instance of the collapsible view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param childViews An optional array of initial child views to be inserted into the collapsible.\n\t */\n\tconstructor( locale: Locale, childViews?: Array<FocusableView> ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'isCollapsed', false );\n\t\tthis.set( 'label', '' );\n\n\t\tthis.buttonView = this._createButtonView();\n\t\tthis.children = this.createCollection();\n\n\t\tthis.set( '_collapsibleAriaLabelUid', undefined );\n\n\t\tif ( childViews ) {\n\t\t\tthis.children.addMany( childViews );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-collapsible',\n\t\t\t\t\tbind.if( 'isCollapsed', 'ck-collapsible_collapsed' )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.buttonView,\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-collapsible__children'\n\t\t\t\t\t\t],\n\t\t\t\t\t\trole: 'region',\n\t\t\t\t\t\thidden: bind.if( 'isCollapsed', 'hidden' ),\n\t\t\t\t\t\t'aria-labelledby': bind.to( '_collapsibleAriaLabelUid' )\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.children\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis._collapsibleAriaLabelUid = this.buttonView.labelView.element!.id;\n\t}\n\n\t/**\n\t * Focuses the first focusable.\n\t */\n\tpublic focus(): void {\n\t\tthis.buttonView.focus();\n\t}\n\n\t/**\n\t * Creates the main {@link #buttonView} of the collapsible.\n\t */\n\tprivate _createButtonView() {\n\t\tconst buttonView = new ButtonView( this.locale );\n\t\tconst bind = buttonView.bindTemplate;\n\n\t\tbuttonView.set( {\n\t\t\twithText: true,\n\t\t\ticon: dropdownArrowIcon\n\t\t} );\n\n\t\tbuttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\t'aria-expanded': bind.to( 'isOn', value => String( value ) )\n\t\t\t}\n\t\t} );\n\n\t\tbuttonView.bind( 'label' ).to( this );\n\t\tbuttonView.bind( 'isOn' ).to( this, 'isCollapsed', isCollapsed => !isCollapsed );\n\n\t\tbuttonView.on( 'execute', () => {\n\t\t\tthis.isCollapsed = !this.isCollapsed;\n\t\t} );\n\n\t\treturn buttonView;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorgrid/utils\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nexport type ColorOption = string | {\n\tcolor: string;\n\tlabel?: string;\n\thasBorder?: boolean;\n};\n\nexport interface NormalizedColorOption {\n\tmodel: string;\n\tlabel: string;\n\thasBorder: boolean;\n\tview: {\n\t\tname: string;\n\t\tstyles: {\n\t\t\tcolor: string;\n\t\t};\n\t};\n}\n\n/**\n * Returns color configuration options as defined in `editor.config.(fontColor|fontBackgroundColor).colors` or\n * `editor.config.table.(tableProperties|tableCellProperties).(background|border).colors\n * but processed to account for editor localization in the correct language.\n *\n * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t}\n * when the user configuration is defined because the editor does not exist yet.\n *\n * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n */\nexport function getLocalizedColorOptions(\n\tlocale: Locale,\n\toptions: Array<NormalizedColorOption>\n): Array<NormalizedColorOption> {\n\tconst t = locale.t;\n\tconst localizedColorNames: Record<string, string | undefined> = {\n\t\tBlack: t( 'Black' ),\n\t\t'Dim grey': t( 'Dim grey' ),\n\t\tGrey: t( 'Grey' ),\n\t\t'Light grey': t( 'Light grey' ),\n\t\tWhite: t( 'White' ),\n\t\tRed: t( 'Red' ),\n\t\tOrange: t( 'Orange' ),\n\t\tYellow: t( 'Yellow' ),\n\t\t'Light green': t( 'Light green' ),\n\t\tGreen: t( 'Green' ),\n\t\tAquamarine: t( 'Aquamarine' ),\n\t\tTurquoise: t( 'Turquoise' ),\n\t\t'Light blue': t( 'Light blue' ),\n\t\tBlue: t( 'Blue' ),\n\t\tPurple: t( 'Purple' )\n\t};\n\n\treturn options.map( colorOption => {\n\t\tconst label = localizedColorNames[ colorOption.label ];\n\n\t\tif ( label && label != colorOption.label ) {\n\t\t\tcolorOption.label = label;\n\t\t}\n\n\t\treturn colorOption;\n\t} );\n}\n\n/**\n * Creates a unified color definition object from color configuration options.\n * The object contains the information necessary to both render the UI and initialize the conversion.\n */\nexport function normalizeColorOptions( options: Array<ColorOption> ): Array<NormalizedColorOption> {\n\treturn options\n\t\t.map( normalizeSingleColorDefinition )\n\t\t.filter( option => !!option );\n}\n\n/**\n * Creates a normalized color definition from the user-defined configuration.\n * The \"normalization\" means it will create full\n * {@link module:ui/colorgrid/colorgridview~ColorDefinition `ColorDefinition-like`}\n * object for string values, and add a `view` property, for each definition.\n */\nexport function normalizeSingleColorDefinition( color: ColorOption ): NormalizedColorOption {\n\tif ( typeof color === 'string' ) {\n\t\treturn {\n\t\t\tmodel: color,\n\t\t\tlabel: color,\n\t\t\thasBorder: false,\n\t\t\tview: {\n\t\t\t\tname: 'span',\n\t\t\t\tstyles: {\n\t\t\t\t\tcolor\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} else {\n\t\treturn {\n\t\t\tmodel: color.color,\n\t\t\tlabel: color.label || color.color,\n\t\t\thasBorder: color.hasBorder === undefined ? false : color.hasBorder,\n\t\t\tview: {\n\t\t\t\tname: 'span',\n\t\t\t\tstyles: {\n\t\t\t\t\tcolor: `${ color.color }`\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorgrid/colortileview\n */\n\nimport ButtonView from '../button/buttonview.js';\n\nimport { env, type Locale } from '@ckeditor/ckeditor5-utils';\n\nimport checkIcon from '../../theme/icons/color-tile-check.svg';\n\n/**\n * This class represents a single color tile in the {@link module:ui/colorgrid/colorgridview~ColorGridView}.\n */\nexport default class ColorTileView extends ButtonView {\n\t/**\n\t * String representing a color shown as tile's background.\n\t */\n\tdeclare public color: string | undefined;\n\n\t/**\n\t * A flag that toggles a special CSS class responsible for displaying\n\t * a border around the button.\n\t */\n\tdeclare public hasBorder: boolean;\n\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'color', undefined );\n\t\tthis.set( 'hasBorder', false );\n\n\t\tthis.icon = checkIcon;\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tstyle: {\n\t\t\t\t\t// https://github.com/ckeditor/ckeditor5/issues/14907\n\t\t\t\t\tbackgroundColor: bind.to( 'color', color => env.isMediaForcedColors ? null : color )\n\t\t\t\t},\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-color-grid__tile',\n\t\t\t\t\tbind.if( 'hasBorder', 'ck-color-selector__color-tile_bordered' )\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.iconView.fillColor = 'hsl(0, 0%, 100%)';\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorgrid/colorgridview\n */\n\nimport View from '../view.js';\nimport ColorTileView from './colortileview.js';\nimport addKeyboardHandlingForGrid from '../bindings/addkeyboardhandlingforgrid.js';\n\nimport type { ButtonExecuteEvent } from '../button/button.js';\nimport type DropdownPanelFocusable from '../dropdown/dropdownpanelfocusable.js';\nimport type ViewCollection from '../viewcollection.js';\n\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\ttype CollectionAddEvent,\n\ttype CollectionRemoveEvent,\n\ttype Locale,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/colorgrid/colorgrid.css';\n\n/**\n * A grid of {@link module:ui/colorgrid/colortileview~ColorTileView color tiles}.\n */\nexport default class ColorGridView extends View implements DropdownPanelFocusable {\n\t/**\n\t * A number of columns for the tiles grid.\n\t */\n\tpublic readonly columns: number;\n\n\t/**\n\t * Collection of the child tile views.\n\t */\n\tpublic readonly items: ViewCollection<ColorTileView>;\n\n\t/**\n\t * Tracks information about DOM focus in the grid.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * The color of the currently selected color tile in {@link #items}.\n\t *\n\t * @observable\n\t */\n\tdeclare public selectedColor: string | undefined | null;\n\n\t/**\n\t * Creates an instance of a color grid containing {@link module:ui/colorgrid/colortileview~ColorTileView tiles}.\n\t *\n\t * @fires execute\n\t * @param locale The localization services instance.\n\t * @param options Component configuration\n\t * @param options.colorDefinitions Array with definitions\n\t * required to create the {@link module:ui/colorgrid/colortileview~ColorTileView tiles}.\n\t * @param options.columns A number of columns to display the tiles.\n\t */\n\tconstructor(\n\t\tlocale?: Locale,\n\t\toptions?: {\n\t\t\tcolorDefinitions?: Array<ColorDefinition>;\n\t\t\tcolumns?: number;\n\t\t}\n\t) {\n\t\tsuper( locale );\n\n\t\tconst colorDefinitions = options && options.colorDefinitions ? options.colorDefinitions : [];\n\n\t\tthis.columns = options && options.columns ? options.columns : 5;\n\n\t\tconst viewStyleAttribute = {\n\t\t\tgridTemplateColumns: `repeat( ${ this.columns }, 1fr)`\n\t\t};\n\n\t\tthis.set( 'selectedColor', undefined );\n\n\t\tthis.items = this.createCollection();\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis.items.on<CollectionAddEvent<ColorTileView>>( 'add', ( evt, colorTile ) => {\n\t\t\tcolorTile.isOn = colorTile.color === this.selectedColor;\n\t\t} );\n\n\t\tcolorDefinitions.forEach( color => {\n\t\t\tconst colorTile = new ColorTileView();\n\n\t\t\tcolorTile.set( {\n\t\t\t\tcolor: color.color,\n\t\t\t\tlabel: color.label,\n\t\t\t\ttooltip: true,\n\t\t\t\thasBorder: color.options.hasBorder\n\t\t\t} );\n\n\t\t\tcolorTile.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\t\tthis.fire<ColorGridViewExecuteEvent>( 'execute', {\n\t\t\t\t\tvalue: color.color,\n\t\t\t\t\thasBorder: color.options.hasBorder,\n\t\t\t\t\tlabel: color.label\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\tthis.items.add( colorTile );\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tchildren: this.items,\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-color-grid'\n\t\t\t\t],\n\t\t\t\tstyle: viewStyleAttribute\n\t\t\t}\n\t\t} );\n\n\t\tthis.on<ObservableChangeEvent<string | undefined>>( 'change:selectedColor', ( evt, name, selectedColor ) => {\n\t\t\tfor ( const item of this.items ) {\n\t\t\t\titem.isOn = item.color === selectedColor;\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #items}.\n\t */\n\tpublic focus(): void {\n\t\tif ( this.items.length ) {\n\t\t\tthis.items.first!.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the last focusable in {@link #items}.\n\t */\n\tpublic focusLast(): void {\n\t\tif ( this.items.length ) {\n\t\t\tthis.items.last!.focus();\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Items added before rendering should be known to the #focusTracker.\n\t\tfor ( const item of this.items ) {\n\t\t\tthis.focusTracker.add( item.element! );\n\t\t}\n\n\t\tthis.items.on<CollectionAddEvent<ColorTileView>>( 'add', ( evt, item ) => {\n\t\t\tthis.focusTracker.add( item.element! );\n\t\t} );\n\n\t\tthis.items.on<CollectionRemoveEvent<ColorTileView>>( 'remove', ( evt, item ) => {\n\t\t\tthis.focusTracker.remove( item.element! );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\taddKeyboardHandlingForGrid( {\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tgridItems: this.items,\n\t\t\tnumberOfColumns: this.columns,\n\t\t\tuiLanguageDirection: this.locale && this.locale.uiLanguageDirection\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n}\n\n/**\n * A color definition used to create a {@link module:ui/colorgrid/colortileview~ColorTileView}.\n *\n * ```json\n * {\n * \tcolor: 'hsl(0, 0%, 75%)',\n * \tlabel: 'Light Grey',\n * \toptions: {\n * \t\thasBorder: true\n * \t}\n * }\n * ```\n */\nexport interface ColorDefinition {\n\n\t/**\n\t * String representing a color.\n\t * It is used as value of background-color style in {@link module:ui/colorgrid/colortileview~ColorTileView}.\n\t */\n\tcolor: string;\n\n\t/**\n\t * String used as label for {@link module:ui/colorgrid/colortileview~ColorTileView}.\n\t */\n\tlabel: string;\n\n\t/**\n\t * Additional options passed to create a {@link module:ui/colorgrid/colortileview~ColorTileView}.\n\t */\n\toptions: {\n\n\t\t/**\n\t\t * A flag that indicates if special a CSS class should be added\n\t\t * to {@link module:ui/colorgrid/colortileview~ColorTileView}, which renders a border around it.\n\t\t */\n\t\thasBorder: boolean;\n\t};\n}\n\n/**\n * Fired when the `ColorTileView` for the picked item is executed.\n *\n * @eventName ~ColorGridView#execute\n * @param data Additional information about the event.\n*/\nexport type ColorGridViewExecuteEvent = {\n\tname: 'execute';\n\targs: [ data: ColorGridViewExecuteEventData ];\n};\n\n/**\n * The data of {@link ~ColorGridViewExecuteEvent execute event}.\n */\nexport interface ColorGridViewExecuteEventData {\n\n\t/**\n\t * The value of the selected color ({@link module:ui/colorgrid/colorgridview~ColorDefinition#color `color.color`}).\n\t */\n\tvalue: string;\n\n\t/**\n\t * The `hasBorder` property of the selected color\n\t * ({@link module:ui/colorgrid/colorgridview~ColorDefinition#options `color.options.hasBorder`}).\n\t */\n\thasBorder: boolean;\n\n\t/**\n\t * The label of the selected color ({@link module:ui/colorgrid/colorgridview~ColorDefinition#label `color.label`})\n\t */\n\tlabel: string;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorpicker/utils\n */\n\n/* eslint-disable @typescript-eslint/ban-ts-comment */\n\n// There are no available types for 'color-parse' module.\n// @ts-ignore\nimport { default as parse } from 'color-parse';\nimport * as convert from 'color-convert';\nimport type {\n\tRGB, HSL, HSV, HWB, CMYK, XYZ, LAB, LCH, HEX, KEYWORD, ANSI16, ANSI256, HCG, APPLE, GRAY\n} from 'color-convert/conversions.js';\n\n/**\n * Color formats handled by color converter.\n */\nexport type ColorPickerOutputFormat = 'hex' | 'rgb' | 'hsl' | 'hwb' | 'lab' | 'lch';\n\n/**\n * Configuration of the color picker feature.\n *\n * It can be forced to apply colors in the editor in a particular format.\n *\n * @default `{\n * \tformat: 'hsl'\n * }`\n */\nexport type ColorPickerConfig = {\n\tformat?: ColorPickerOutputFormat;\n};\n\n/**\n * Configuration of the color picker view.\n *\n * It can be used to enforce a particular color format or hide the color input.\n */\nexport type ColorPickerViewConfig = ColorPickerConfig & {\n\thideInput?: boolean;\n};\n\n/**\n * Parses and converts the color string to requested format. Handles variety of color spaces\n * like `hsl`, `hex` or `rgb`.\n *\n * @param color\n * @returns A color string.\n */\nexport function convertColor( color: string, outputFormat: ColorPickerOutputFormat ): string {\n\tif ( !color ) {\n\t\treturn '';\n\t}\n\n\tconst colorObject = parseColorString( color );\n\n\tif ( !colorObject ) {\n\t\treturn '';\n\t}\n\n\tif ( colorObject.space === outputFormat ) {\n\t\treturn color;\n\t}\n\n\tif ( !canConvertParsedColor( colorObject ) ) {\n\t\treturn '';\n\t}\n\n\tconst fromColorSpace = ( convert as Conversion )[ colorObject.space ];\n\tconst toColorSpace = fromColorSpace[ outputFormat ];\n\n\tif ( !toColorSpace ) {\n\t\treturn '';\n\t}\n\n\tconst convertedColorChannels = toColorSpace( colorObject.space === 'hex' ? colorObject.hexValue : colorObject.values );\n\n\treturn formatColorOutput( convertedColorChannels, outputFormat );\n}\n\n/**\n * Converts a color string to hex format.\n *\n * @param color\n * @returns A color string.\n */\nexport function convertToHex( color: string ): string {\n\tif ( !color ) {\n\t\treturn '';\n\t}\n\n\tconst colorObject = parseColorString( color );\n\n\tif ( !colorObject ) {\n\t\treturn '#000';\n\t}\n\n\tif ( colorObject.space === 'hex' ) {\n\t\treturn colorObject.hexValue;\n\t}\n\n\treturn convertColor( color, 'hex' );\n}\n\n/**\n * Registers the custom element in the\n * [CustomElementsRegistry](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry).\n */\nexport function registerCustomElement( elementName: string, constructor: CustomElementConstructor ): void {\n\tif ( customElements.get( elementName ) === undefined ) {\n\t\tcustomElements.define( elementName, constructor );\n\t}\n}\n\n/**\n * Formats the passed color channels according to the requested format.\n *\n * @param values\n * @param format\n * @returns A color string.\n */\nfunction formatColorOutput( values: FormatTableColor, format: ColorPickerOutputFormat ): string {\n\tswitch ( format ) {\n\t\tcase 'hex': return `#${ values }`;\n\t\tcase 'rgb': return `rgb( ${ values[ 0 ] }, ${ values[ 1 ] }, ${ values[ 2 ] } )`;\n\t\tcase 'hsl': return `hsl( ${ values[ 0 ] }, ${ values[ 1 ] }%, ${ values[ 2 ] }% )`;\n\t\tcase 'hwb': return `hwb( ${ values[ 0 ] }, ${ values[ 1 ] }, ${ values[ 2 ] } )`;\n\t\tcase 'lab': return `lab( ${ values[ 0 ] }% ${ values[ 1 ] } ${ values[ 2 ] } )`;\n\t\tcase 'lch': return `lch( ${ values[ 0 ] }% ${ values[ 1 ] } ${ values[ 2 ] } )`;\n\n\t\tdefault: return '';\n\t}\n}\n\ntype FormatTableColor = HEX | RGB | HSL | HWB | LAB | LCH;\ntype ConversionFunctionInput = RGB | HSL | HSV | HWB | CMYK | XYZ | LAB | LCH | HEX | KEYWORD | ANSI16 | ANSI256 | HCG | APPLE | GRAY;\ntype ConversionInputSpaces = typeof convert;\ntype ConversionFunction = ( value: ConversionFunctionInput ) => FormatTableColor;\ntype Conversion = Record<keyof ConversionInputSpaces, Partial<Record<ColorPickerOutputFormat, ConversionFunction>>>;\n\ntype ParserColorSpaces =\n\t'rgb' | 'hsl' | 'hsv' | 'hsb' | 'hwb' | 'cmy' | 'cmyk' | 'xyz' | 'xyy' | 'gray' | 'lab' | 'lch' | 'lchu' | 'lchv' | 'lchuv' |\n\t'luv' | 'yuv' | 'lms' | 'hex';\n\ntype ParsedColor<T extends ParserColorSpaces> = {\n\treadonly space: T;\n\treadonly alpha: number;\n\treadonly values: T extends 'cmyk' ? [ number, number, number, number ] : [ number, number, number ];\n\treadonly hexValue: T extends 'hex' ? string : never;\n};\n\ntype ConvertableParsedColor = ParsedColor<ParserColorSpaces> & {\n\treadonly space: keyof ConversionInputSpaces;\n};\n\nfunction parseColorString( colorString: string ): ParsedColor<ParserColorSpaces> | null {\n\t// Parser library treats `hex` format as belonging to `rgb` space | which messes up further conversion.\n\t// Let's parse such strings on our own.\n\tif ( colorString.startsWith( '#' ) ) {\n\t\tconst parsedHex = parse( colorString );\n\n\t\treturn {\n\t\t\tspace: 'hex',\n\t\t\tvalues: parsedHex.values,\n\t\t\thexValue: colorString,\n\t\t\talpha: parsedHex.alpha\n\t\t};\n\t}\n\n\tconst parsed = parse( colorString );\n\n\tif ( !parsed.space ) {\n\t\treturn null;\n\t}\n\n\treturn parsed;\n}\n\nfunction canConvertParsedColor( parsedColor: ParsedColor<ParserColorSpaces> ): parsedColor is ConvertableParsedColor {\n\treturn Object.keys( convert ).includes( parsedColor.space );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/labeledfield/labeledfieldview\n */\n\nimport View from '../view.js';\nimport LabelView from '../label/labelview.js';\n\nimport type { FocusableView } from '../focuscycler.js';\nimport type ViewCollection from '../viewcollection.js';\n\nimport { uid, type Locale } from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/labeledfield/labeledfieldview.css';\n\n/**\n * The labeled field view class. It can be used to enhance any view with the following features:\n *\n * * a label,\n * * (optional) an error message,\n * * (optional) an info (status) text,\n *\n * all bound logically by proper DOM attributes for UX and accessibility.  It also provides an interface\n * (e.g. observable properties) that allows controlling those additional features.\n *\n * The constructor of this class requires a callback that returns a view to be labeled. The callback\n * is called with unique ids that allow binding of DOM properties:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, ( labeledFieldView, viewUid, statusUid ) => {\n * \tconst inputView = new InputTextView( labeledFieldView.locale );\n *\n * \tinputView.set( {\n * \t\tid: viewUid,\n * \t\tariaDescribedById: statusUid\n * \t} );\n *\n * \tinputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );\n * \tinputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );\n *\n * \treturn inputView;\n * } );\n *\n * labeledInputView.label = 'User name';\n * labeledInputView.infoText = 'Full name like for instance, John Doe.';\n * labeledInputView.render();\n *\n * document.body.append( labeledInputView.element );\n * ```\n *\n * See {@link module:ui/labeledfield/utils} to discover ready–to–use labeled input helpers for common\n * UI components.\n */\nexport default class LabeledFieldView<TFieldView extends FocusableView = FocusableView> extends View {\n\t/**\n\t * The field view that gets labeled.\n\t */\n\tpublic readonly fieldView: TFieldView;\n\n\t/**\n\t * The label view instance that describes the entire view.\n\t */\n\tpublic readonly labelView: LabelView;\n\n\t/**\n\t * The status view for the {@link #fieldView}. It displays {@link #errorText} and\n\t * {@link #infoText}.\n\t */\n\tpublic readonly statusView: View;\n\n\t/**\n\t * A collection of children of the internal wrapper element. Allows inserting additional DOM elements (views) next to\n\t * the {@link #fieldView} for easy styling (e.g. positioning).\n\t *\n\t * By default, the collection contains {@link #fieldView} and {@link #labelView}.\n\t */\n\tpublic readonly fieldWrapperChildren: ViewCollection;\n\n\t/**\n\t * The text of the label.\n\t *\n\t * @observable\n\t */\n\tdeclare public label: string | undefined;\n\n\t/**\n\t * Controls whether the component is in read-only mode.\n\t *\n\t * @observable\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * An observable flag set to `true` when {@link #fieldView} is empty (`false` otherwise).\n\t *\n\t * @readonly\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public isEmpty: boolean;\n\n\t/**\n\t * An observable flag set to `true` when {@link #fieldView} is currently focused by\n\t * the user (`false` otherwise).\n\t *\n\t * @readonly\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isFocused: boolean;\n\n\t/**\n\t * The validation error text. When set, it will be displayed\n\t * next to the {@link #fieldView} as a typical validation error message.\n\t * Set it to `null` to hide the message.\n\t *\n\t * **Note:** Setting this property to anything but `null` will automatically\n\t * make the `hasError` of the {@link #fieldView} `true`.\n\t *\n\t * @observable\n\t */\n\tdeclare public errorText: string | null;\n\n\t/**\n\t * The additional information text displayed next to the {@link #fieldView} which can\n\t * be used to inform the user about its purpose, provide help or hints.\n\t *\n\t * Set it to `null` to hide the message.\n\t *\n\t * **Note:** This text will be displayed in the same place as {@link #errorText} but the\n\t * latter always takes precedence: if the {@link #errorText} is set, it replaces\n\t * {@link #infoText}.\n\t *\n\t * @observable\n\t * @default null\n\t */\n\tdeclare public infoText: string | null;\n\n\t/**\n\t * (Optional) The additional CSS class set on the dropdown {@link #element}.\n\t *\n\t * @observable\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * The content of the `placeholder` attribute of the {@link #fieldView}.\n\t *\n\t * @observable\n\t */\n\tdeclare public placeholder: string | undefined;\n\n\t/**\n\t * The combined status text made of {@link #errorText} and {@link #infoText}.\n\t * Note that when present, {@link #errorText} always takes precedence in the\n\t * status.\n\t *\n\t * @see #errorText\n\t * @see #infoText\n\t * @see #statusView\n\t * @private\n\t * @observable\n\t */\n\tdeclare public _statusText: string | null;\n\n\t/**\n\t * Creates an instance of the labeled field view class using a provided creator function\n\t * that provides the view to be labeled.\n\t *\n\t * @param locale The locale instance.\n\t * @param viewCreator A function that returns a {@link module:ui/view~View}\n\t * that will be labeled. The following arguments are passed to the creator function:\n\t *\n\t * * an instance of the `LabeledFieldView` to allow binding observable properties,\n\t * * an UID string that connects the {@link #labelView label} and the labeled field view in DOM,\n\t * * an UID string that connects the {@link #statusView status} and the labeled field view in DOM.\n\t */\n\tconstructor(\n\t\tlocale: Locale | undefined,\n\t\tviewCreator: LabeledFieldViewCreator<TFieldView>\n\t) {\n\t\tsuper( locale );\n\n\t\tconst viewUid = `ck-labeled-field-view-${ uid() }`;\n\t\tconst statusUid = `ck-labeled-field-view-status-${ uid() }`;\n\n\t\tthis.fieldView = viewCreator( this, viewUid, statusUid );\n\n\t\tthis.set( 'label', undefined );\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'isEmpty', true );\n\t\tthis.set( 'isFocused', false );\n\t\tthis.set( 'errorText', null );\n\t\tthis.set( 'infoText', null );\n\t\tthis.set( 'class', undefined );\n\t\tthis.set( 'placeholder', undefined );\n\n\t\tthis.labelView = this._createLabelView( viewUid );\n\t\tthis.statusView = this._createStatusView( statusUid );\n\t\tthis.fieldWrapperChildren = this.createCollection( [ this.fieldView, this.labelView ] );\n\n\t\tthis.bind( '_statusText' ).to(\n\t\t\tthis, 'errorText',\n\t\t\tthis, 'infoText',\n\t\t\t( errorText, infoText ) => errorText || infoText\n\t\t);\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-labeled-field-view',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isEnabled', 'ck-disabled', value => !value ),\n\t\t\t\t\tbind.if( 'isEmpty', 'ck-labeled-field-view_empty' ),\n\t\t\t\t\tbind.if( 'isFocused', 'ck-labeled-field-view_focused' ),\n\t\t\t\t\tbind.if( 'placeholder', 'ck-labeled-field-view_placeholder' ),\n\t\t\t\t\tbind.if( 'errorText', 'ck-error' )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-labeled-field-view__input-wrapper'\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.fieldWrapperChildren\n\t\t\t\t},\n\t\t\t\tthis.statusView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Creates label view class instance and bind with view.\n\t *\n\t * @param id Unique id to set as labelView#for attribute.\n\t */\n\tprivate _createLabelView( id: string ): LabelView {\n\t\tconst labelView = new LabelView( this.locale );\n\n\t\tlabelView.for = id;\n\t\tlabelView.bind( 'text' ).to( this, 'label' );\n\n\t\treturn labelView;\n\t}\n\n\t/**\n\t * Creates the status view instance. It displays {@link #errorText} and {@link #infoText}\n\t * next to the {@link #fieldView}. See {@link #_statusText}.\n\t *\n\t * @param statusUid Unique id of the status, shared with the {@link #fieldView view's}\n\t * `aria-describedby` attribute.\n\t */\n\tprivate _createStatusView( statusUid: string ): View {\n\t\tconst statusView = new View( this.locale );\n\t\tconst bind = this.bindTemplate;\n\n\t\tstatusView.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-labeled-field-view__status',\n\t\t\t\t\tbind.if( 'errorText', 'ck-labeled-field-view__status_error' ),\n\t\t\t\t\tbind.if( '_statusText', 'ck-hidden', value => !value )\n\t\t\t\t],\n\t\t\t\tid: statusUid,\n\t\t\t\trole: bind.if( 'errorText', 'alert' )\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: bind.to( '_statusText' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\treturn statusView;\n\t}\n\n\t/**\n\t * Focuses the {@link #fieldView}.\n\t */\n\tpublic focus( direction?: 1 | -1 ): void {\n\t\tthis.fieldView.focus( direction );\n\t}\n}\n\n/**\n * A creator function that returns a focusable view to be labeled by a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView}\n * instance.\n */\nexport type LabeledFieldViewCreator<TFieldView extends FocusableView> =\n\t( labeledFieldView: LabeledFieldView, viewUid: string, statusUid: string ) => TFieldView;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/input/inputbase\n */\n\nimport View from '../view.js';\n\nimport {\n\tFocusTracker,\n\ttype Locale,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\n/**\n * The base input view class.\n */\nexport default abstract class InputBase<TElement extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> extends View<TElement> {\n\t/**\n\t * Stores information about the editor UI focus and propagates it so various plugins and components\n\t * are unified as a focus group.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * The value of the input.\n\t *\n\t * @observable\n\t */\n\tdeclare public value: string | undefined;\n\n\t/**\n\t * The `id` attribute of the input (i.e. to pair with a `<label>` element).\n\t *\n\t * @observable\n\t */\n\tdeclare public id: string | undefined;\n\n\t/**\n\t * The `placeholder` attribute of the input.\n\t *\n\t * @observable\n\t */\n\tdeclare public placeholder: string | undefined;\n\n\t/**\n\t * The `tabindex` attribute of the input.\n\t *\n\t * @observable\n\t */\n\tdeclare public tabIndex: number | undefined;\n\n\t/**\n\t * The `aria-label` attribute of the input.\n\t *\n\t * @observable\n\t */\n\tdeclare public ariaLabel: string | undefined;\n\n\t/**\n\t * Controls whether the input view is in read-only mode.\n\t *\n\t * @observable\n\t */\n\tdeclare public isReadOnly: boolean;\n\n\t/**\n\t * Set to `true` when the field has some error. Usually controlled via\n\t * {@link module:ui/labeledinput/labeledinputview~LabeledInputView#errorText}.\n\t *\n\t * @observable\n\t */\n\tdeclare public hasError: boolean;\n\n\t/**\n\t * The `id` of the element describing this field, e.g. when it has\n\t * some error; it helps screen readers read the error text.\n\t *\n\t * @observable\n\t */\n\tdeclare public ariaDescribedById: string | undefined;\n\n\t/**\n\t * An observable flag set to `true` when the input is currently focused by the user.\n\t * Set to `false` otherwise.\n\t *\n\t * @readonly\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isFocused: boolean;\n\n\t/**\n\t * An observable flag set to `true` when the input contains no text, i.e.\n\t * when {@link #value} is `''`, `null`, or `false`.\n\t *\n\t * @readonly\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public isEmpty: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.set( 'value', undefined );\n\t\tthis.set( 'id', undefined );\n\t\tthis.set( 'placeholder', undefined );\n\t\tthis.set( 'tabIndex', undefined );\n\t\tthis.set( 'isReadOnly', false );\n\t\tthis.set( 'hasError', false );\n\t\tthis.set( 'ariaDescribedById', undefined );\n\t\tthis.set( 'ariaLabel', undefined );\n\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\tthis.bind( 'isFocused' ).to( this.focusTracker );\n\t\tthis.set( 'isEmpty', true );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'input',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-input',\n\t\t\t\t\tbind.if( 'isFocused', 'ck-input_focused' ),\n\t\t\t\t\tbind.if( 'isEmpty', 'ck-input-text_empty' ),\n\t\t\t\t\tbind.if( 'hasError', 'ck-error' )\n\t\t\t\t],\n\t\t\t\tid: bind.to( 'id' ),\n\t\t\t\tplaceholder: bind.to( 'placeholder' ),\n\t\t\t\ttabindex: bind.to( 'tabIndex' ),\n\t\t\t\treadonly: bind.to( 'isReadOnly' ),\n\t\t\t\t'aria-invalid': bind.if( 'hasError', true ),\n\t\t\t\t'aria-describedby': bind.to( 'ariaDescribedById' ),\n\t\t\t\t'aria-label': bind.to( 'ariaLabel' )\n\t\t\t},\n\t\t\ton: {\n\t\t\t\tinput: bind.to( ( ...args ) => {\n\t\t\t\t\tthis.fire( 'input', ...args );\n\t\t\t\t\tthis._updateIsEmpty();\n\t\t\t\t} ),\n\t\t\t\tchange: bind.to( this._updateIsEmpty.bind( this ) )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.focusTracker.add( this.element! );\n\n\t\tthis._setDomElementValue( this.value );\n\t\tthis._updateIsEmpty();\n\n\t\t// Bind `this.value` to the DOM element's value.\n\t\t// We cannot use `value` DOM attribute because removing it on Edge does not clear the DOM element's value property.\n\t\tthis.on<ObservableChangeEvent>( 'change:value', ( evt, name, value ) => {\n\t\t\tthis._setDomElementValue( value );\n\t\t\tthis._updateIsEmpty();\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t}\n\n\t/**\n\t * Moves the focus to the input and selects the value.\n\t */\n\tpublic select(): void {\n\t\tthis.element!.select();\n\t}\n\n\t/**\n\t * Focuses the input.\n\t */\n\tpublic focus(): void {\n\t\tthis.element!.focus();\n\t}\n\n\t/**\n\t * Resets the value of the input\n\t */\n\tpublic reset(): void {\n\t\tthis.value = this.element!.value = '';\n\t\tthis._updateIsEmpty();\n\t}\n\n\t/**\n\t * Updates the {@link #isEmpty} property value on demand.\n\t */\n\tprotected _updateIsEmpty(): void {\n\t\tthis.isEmpty = isInputElementEmpty( this.element! );\n\t}\n\n\t/**\n\t * Sets the `value` property of the {@link #element DOM element} on demand.\n\t */\n\tprivate _setDomElementValue( value: any ) {\n\t\tthis.element!.value = ( !value && value !== 0 ) ? '' : value;\n\t}\n}\n\nfunction isInputElementEmpty( domElement: HTMLInputElement | HTMLTextAreaElement ) {\n\treturn !domElement.value;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/input/inputview\n */\n\nimport { type Locale } from '@ckeditor/ckeditor5-utils';\nimport InputBase from './inputbase.js';\n\nimport '../../theme/components/input/input.css';\n\n/**\n * The input view class.\n */\nexport default class InputView extends InputBase {\n\t/**\n\t * Corresponds to the `inputmode` DOM attribute. Can be `text`, `numeric`, `decimal`, etc.\n\t *\n\t * @observable\n\t * @default 'text'\n\t */\n\tdeclare public inputMode: string;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.set( 'inputMode', 'text' );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tinputmode: bind.to( 'inputMode' )\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Fired when the user types in the input. Corresponds to the native\n * DOM `input` event.\n *\n * @eventName ~InputView#input\n */\nexport type InputViewInputEvent = {\n\tname: 'input';\n\targs: [ InputEvent ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/inputtext/inputtextview\n */\n\nimport InputView from '../input/inputview.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The text input view class.\n */\nexport default class InputTextView extends InputView {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\ttype: 'text',\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-input-text'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/inputnumber/inputnumberview\n */\n\nimport InputView from '../input/inputview.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The number input view class.\n */\nexport default class InputNumberView extends InputView {\n\t/**\n\t * The value of the `min` DOM attribute (the lowest accepted value) set on the {@link #element}.\n\t *\n\t * @observable\n\t * @default undefined\n\t */\n\tdeclare public min: number | undefined;\n\n\t/**\n\t * The value of the `max` DOM attribute (the highest accepted value) set on the {@link #element}.\n\t *\n\t * @observable\n\t * @default undefined\n\t */\n\tdeclare public max: number | undefined;\n\n\t/**\n\t * The value of the `step` DOM attribute set on the {@link #element}.\n\t *\n\t * @observable\n\t * @default undefined\n\t */\n\tdeclare public step: number | undefined;\n\n\t/**\n\t * Creates an instance of the input number view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options The options of the input.\n\t * @param options.min The value of the `min` DOM attribute (the lowest accepted value).\n\t * @param options.max The value of the `max` DOM attribute (the highest accepted value).\n\t * @param options.step The value of the `step` DOM attribute.\n\t */\n\tconstructor(\n\t\tlocale?: Locale,\n\t\t{ min, max, step }: {\n\t\t\tmin?: number;\n\t\t\tmax?: number;\n\t\t\tstep?: number;\n\t\t} = {}\n\t) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'min', min );\n\t\tthis.set( 'max', max );\n\t\tthis.set( 'step', step );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\ttype: 'number',\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-input-number'\n\t\t\t\t],\n\t\t\t\tmin: bind.to( 'min' ),\n\t\t\t\tmax: bind.to( 'max' ),\n\t\t\t\tstep: bind.to( 'step' )\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/textarea/textareaview\n */\n\nimport { Rect, type Locale, toUnit, getBorderWidths, global, CKEditorError, isVisible, ResizeObserver } from '@ckeditor/ckeditor5-utils';\nimport InputBase from '../input/inputbase.js';\n\nimport '../../theme/components/input/input.css';\nimport '../../theme/components/textarea/textarea.css';\n\n/**\n * The textarea view class.\n *\n * ```ts\n * const textareaView = new TextareaView();\n *\n * textareaView.minRows = 2;\n * textareaView.maxRows = 10;\n *\n * textareaView.render();\n *\n * document.body.append( textareaView.element );\n * ```\n */\nexport default class TextareaView extends InputBase<HTMLTextAreaElement> {\n\t/**\n\t * Specifies the visible height of a text area, in lines.\n\t *\n\t * @observable\n\t * @default 2\n\t */\n\tdeclare public minRows: number;\n\n\t/**\n\t * Specifies the maximum number of rows.\n\t *\n\t * @observable\n\t * @default 5\n\t */\n\tdeclare public maxRows: number;\n\n\t/**\n\t * Specifies the value of HTML attribute that indicates whether the user can resize the element.\n\t *\n\t * @observable\n\t * @default 'none'\n\t*/\n\tdeclare public resize: 'both' | 'horizontal' | 'vertical' | 'none';\n\n\t/**\n\t * An internal property that stores the current height of the textarea. Used for the DOM binding.\n\t *\n\t * @observable\n\t * @default null\n\t * @internal\n\t */\n\tdeclare public _height: number | null;\n\n\t/**\n\t * An instance of the resize observer used to detect when the view is visible or not and update\n\t * its height if any changes that affect it were made while it was invisible.\n\t *\n\t * **Note:** Created in {@link #render}.\n\t */\n\tprivate _resizeObserver: ResizeObserver | null;\n\n\t/**\n\t * A flag that indicates whether the {@link #_updateAutoGrowHeight} method should be called when the view becomes\n\t * visible again. See {@link #_resizeObserver}.\n\t */\n\tprivate _isUpdateAutoGrowHeightPending: boolean = false;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst toPx = toUnit( 'px' );\n\n\t\tthis.set( 'minRows', 2 );\n\t\tthis.set( 'maxRows', 5 );\n\t\tthis.set( '_height', null );\n\t\tthis.set( 'resize', 'none' );\n\t\tthis._resizeObserver = null;\n\n\t\tthis.on( 'change:minRows', this._validateMinMaxRows.bind( this ) );\n\t\tthis.on( 'change:maxRows', this._validateMinMaxRows.bind( this ) );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.template!.tag = 'textarea';\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck-textarea' ],\n\t\t\t\tstyle: {\n\t\t\t\t\theight: bind.to( '_height', height => height ? toPx( height ) : null ),\n\t\t\t\t\tresize: bind.to( 'resize' )\n\t\t\t\t},\n\t\t\t\trows: bind.to( 'minRows' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tlet wasVisible: boolean = false;\n\n\t\tthis.on( 'input', () => {\n\t\t\tthis._updateAutoGrowHeight( true );\n\t\t\tthis.fire<TextareaViewUpdateEvent>( 'update' );\n\t\t} );\n\n\t\tthis.on( 'change:value', () => {\n\t\t\t// The content needs to be updated by the browser after the value is changed. It takes a few ms.\n\t\t\tglobal.window.requestAnimationFrame( () => {\n\t\t\t\tif ( !isVisible( this.element ) ) {\n\t\t\t\t\tthis._isUpdateAutoGrowHeightPending = true;\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._updateAutoGrowHeight();\n\t\t\t\tthis.fire<TextareaViewUpdateEvent>( 'update' );\n\t\t\t} );\n\t\t} );\n\n\t\t// It may occur that the Textarea size needs to be updated (e.g. because it's content was changed)\n\t\t// when it is not visible or detached from DOM.\n\t\t// In such case, we need to detect the moment when it becomes visible again and update its height then.\n\t\t// We're using ResizeObserver for that as it is the most reliable way to detect when the element becomes visible.\n\t\t// IntersectionObserver didn't work well with the absolute positioned containers.\n\t\tthis._resizeObserver = new ResizeObserver( this.element!, evt => {\n\t\t\tconst isVisible = !!evt.contentRect.width && !!evt.contentRect.height;\n\n\t\t\tif ( !wasVisible && isVisible && this._isUpdateAutoGrowHeightPending ) {\n\t\t\t\t// We're wrapping the auto-grow logic in RAF because otherwise there is an error thrown\n\t\t\t\t// by the browser about recursive calls to the ResizeObserver. It used to happen in unit\n\t\t\t\t// tests only, though. Since there is no risk of infinite loop here, it can stay here.\n\t\t\t\tglobal.window.requestAnimationFrame( () => {\n\t\t\t\t\tthis._updateAutoGrowHeight();\n\t\t\t\t\tthis.fire<TextareaViewUpdateEvent>( 'update' );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\twasVisible = isVisible;\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tif ( this._resizeObserver ) {\n\t\t\tthis._resizeObserver.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override reset(): void {\n\t\tsuper.reset();\n\n\t\tthis._updateAutoGrowHeight();\n\t\tthis.fire<TextareaViewUpdateEvent>( 'update' );\n\t}\n\n\t/**\n\t * Updates the {@link #_height} of the view depending on {@link #minRows}, {@link #maxRows}, and the current content size.\n\t *\n\t * **Note**: This method overrides manual resize done by the user using a handle. It's a known bug.\n\t */\n\tprivate _updateAutoGrowHeight( shouldScroll?: boolean ): void {\n\t\tconst viewElement = this.element!;\n\n\t\tif ( !viewElement.offsetParent ) {\n\t\t\tthis._isUpdateAutoGrowHeightPending = true;\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isUpdateAutoGrowHeightPending = false;\n\n\t\tconst singleLineContentClone = getTextareaElementClone( viewElement, '1' );\n\t\tconst fullTextValueClone = getTextareaElementClone( viewElement, viewElement.value );\n\t\tconst singleLineContentStyles = singleLineContentClone.ownerDocument.defaultView!.getComputedStyle( singleLineContentClone );\n\n\t\tconst verticalPaddings = parseFloat( singleLineContentStyles.paddingTop ) + parseFloat( singleLineContentStyles.paddingBottom );\n\t\tconst borders = getBorderWidths( singleLineContentClone );\n\t\tconst lineHeight = parseFloat( singleLineContentStyles.lineHeight );\n\t\tconst verticalBorder = borders.top + borders.bottom;\n\n\t\tconst singleLineAreaDefaultHeight = new Rect( singleLineContentClone ).height;\n\t\tconst numberOfLines = Math.round( ( fullTextValueClone.scrollHeight - verticalPaddings ) / lineHeight );\n\n\t\tconst maxHeight = this.maxRows * lineHeight + verticalPaddings + verticalBorder;\n\n\t\t// There's a --ck-ui-component-min-height CSS custom property that enforces min height of the component.\n\t\t// This min-height is relevant only when there's one line of text. Other than that, we can rely on line-height.\n\t\tconst minHeight = numberOfLines === 1 ? singleLineAreaDefaultHeight : this.minRows * lineHeight + verticalPaddings + verticalBorder;\n\n\t\t// The size of textarea is controlled by height style instead of rows attribute because event though it is\n\t\t// a more complex solution, it is immune to the layout textarea has been rendered in (gird, flex).\n\t\tthis._height = Math.min(\n\t\t\tMath.max(\n\t\t\t\tMath.max( numberOfLines, this.minRows ) * lineHeight + verticalPaddings + verticalBorder,\n\t\t\t\tminHeight\n\t\t\t),\n\t\t\tmaxHeight\n\t\t);\n\n\t\tif ( shouldScroll ) {\n\t\t\tviewElement.scrollTop = viewElement.scrollHeight;\n\t\t}\n\n\t\tsingleLineContentClone.remove();\n\t\tfullTextValueClone.remove();\n\t}\n\n\t/**\n\t * Validates the {@link #minRows} and {@link #maxRows} properties and warns in the console if the configuration is incorrect.\n\t */\n\tprivate _validateMinMaxRows() {\n\t\tif ( this.minRows > this.maxRows ) {\n\t\t\t/**\n\t\t\t * The minimum number of rows is greater than the maximum number of rows.\n\t\t\t *\n\t\t\t * @error ui-textarea-view-min-rows-greater-than-max-rows\n\t\t\t * @param textareaView The misconfigured textarea view instance.\n\t\t\t * @param minRows The value of `minRows` property.\n\t\t\t * @param maxRows The value of `maxRows` property.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'ui-textarea-view-min-rows-greater-than-max-rows', {\n\t\t\t\ttextareaView: this,\n\t\t\t\tminRows: this.minRows,\n\t\t\t\tmaxRows: this.maxRows\n\t\t\t} );\n\t\t}\n\t}\n}\n\nfunction getTextareaElementClone( element: HTMLTextAreaElement, value: string ): HTMLTextAreaElement {\n\tconst clone = element.cloneNode() as HTMLTextAreaElement;\n\n\tclone.style.position = 'absolute';\n\tclone.style.top = '-99999px';\n\tclone.style.left = '-99999px';\n\tclone.style.height = 'auto';\n\tclone.style.overflow = 'hidden';\n\tclone.style.width = element.ownerDocument.defaultView!.getComputedStyle( element ).width;\n\tclone.tabIndex = -1;\n\tclone.rows = 1;\n\tclone.value = value;\n\n\telement.parentNode!.insertBefore( clone, element );\n\n\treturn clone;\n}\n\n/**\n * Fired every time the layout of the {@link module:ui/textarea/textareaview~TextareaView} possibly changed as a result\n * of the user input or the value change via {@link module:ui/textarea/textareaview~TextareaView#value}.\n *\n * @eventName ~TextareaView#update\n */\nexport type TextareaViewUpdateEvent = {\n\tname: 'update';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/dropdownpanelview\n */\n\nimport View from '../view.js';\nimport type ViewCollection from '../viewcollection.js';\nimport type DropdownPanelFocusable from './dropdownpanelfocusable.js';\n\nimport { logWarning, type Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The dropdown panel view class.\n *\n * See {@link module:ui/dropdown/dropdownview~DropdownView} to learn about the common usage.\n */\nexport default class DropdownPanelView extends View implements DropdownPanelFocusable {\n\t/**\n\t * Collection of the child views in this panel.\n\t *\n\t * A common child type is the {@link module:ui/list/listview~ListView} and {@link module:ui/toolbar/toolbarview~ToolbarView}.\n\t * See {@link module:ui/dropdown/utils~addListToDropdown} and\n\t * {@link module:ui/dropdown/utils~addToolbarToDropdown} to learn more about child views of dropdowns.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * Controls whether the panel is visible.\n\t *\n\t * @observable\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * The position of the panel, relative to the parent.\n\t *\n\t * This property is reflected in the CSS class set to {@link #element} that controls\n\t * the position of the panel.\n\t *\n\t * @observable\n\t * @default 'se'\n\t */\n\tdeclare public position: PanelPosition;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'isVisible', false );\n\t\tthis.set( 'position', 'se' );\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-dropdown__panel',\n\t\t\t\t\tbind.to( 'position', value => `ck-dropdown__panel_${ value }` ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-dropdown__panel-visible' )\n\t\t\t\t],\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\t// Drag and drop in the panel should not break the selection in the editor.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/228\n\t\t\t\tselectstart: bind.to( evt => {\n\t\t\t\t\tif ( ( evt.target as HTMLElement ).tagName.toLocaleLowerCase() === 'input' ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the first view in the {@link #children} collection.\n\t *\n\t * See also {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable}.\n\t */\n\tpublic focus(): void {\n\t\tif ( this.children.length ) {\n\t\t\tconst firstChild: any = this.children.first;\n\n\t\t\tif ( typeof firstChild.focus === 'function' ) {\n\t\t\t\tfirstChild.focus();\n\t\t\t} else {\n\t\t\t\t/**\n\t\t\t\t * The child view of a dropdown could not be focused because it is missing the `focus()` method.\n\t\t\t\t *\n\t\t\t\t * This warning appears when a dropdown {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open} and it\n\t\t\t\t * attempts to focus the {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#children first child} of its panel\n\t\t\t\t * but the child does not implement the\n\t\t\t\t * {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable focusable interface}.\n\t\t\t\t *\n\t\t\t\t * Focusing the content of a dropdown on open greatly improves the accessibility. Please make sure the view instance\n\t\t\t\t * provides the `focus()` method for the best user experience.\n\t\t\t\t *\n\t\t\t\t * @error ui-dropdown-panel-focus-child-missing-focus\n\t\t\t\t * @param childView\n\t\t\t\t * @param dropdownPanel\n\t\t\t\t */\n\t\t\t\tlogWarning( 'ui-dropdown-panel-focus-child-missing-focus', { childView: this.children.first, dropdownPanel: this } );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the view element or last item in view collection on opening dropdown's panel.\n\t *\n\t * See also {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable}.\n\t */\n\tpublic focusLast(): void {\n\t\tif ( this.children.length ) {\n\t\t\tconst lastChild: any = this.children.last;\n\n\t\t\tif ( typeof lastChild.focusLast === 'function' ) {\n\t\t\t\tlastChild.focusLast();\n\t\t\t} else {\n\t\t\t\tlastChild.focus();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The position of the panel, relative to the parent.\n */\nexport type PanelPosition = 's' | 'se' | 'sw' | 'sme' | 'smw' | 'n' | 'ne' | 'nw' | 'nme' | 'nmw';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/dropdownview\n */\n\nimport View from '../view.js';\n\nimport type { default as DropdownButton, DropdownButtonOpenEvent } from './button/dropdownbutton.js';\nimport type { default as DropdownPanelView, PanelPosition } from './dropdownpanelview.js';\nimport type { FocusableView } from '../focuscycler.js';\nimport type ListView from '../list/listview.js';\nimport type ToolbarView from '../toolbar/toolbarview.js';\nimport type DropdownMenuRootListView from './menu/dropdownmenurootlistview.js';\n\nimport {\n\tKeystrokeHandler,\n\tFocusTracker,\n\tgetOptimalPosition,\n\ttype Locale,\n\ttype ObservableChangeEvent,\n\ttype PositioningFunction\n} from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/dropdown/dropdown.css';\n\n/**\n * The dropdown view class. It manages the dropdown button and dropdown panel.\n *\n * In most cases, the easiest way to create a dropdown is by using the {@link module:ui/dropdown/utils~createDropdown}\n * util:\n *\n * ```ts\n * const dropdown = createDropdown( locale );\n *\n * // Configure dropdown's button properties:\n * dropdown.buttonView.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.render();\n *\n * dropdown.panelView.element.textContent = 'Content of the panel';\n *\n * // Will render a dropdown with a panel containing a \"Content of the panel\" text.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * If you want to add a richer content to the dropdown panel, you can use the {@link module:ui/dropdown/utils~addListToDropdown}\n * and {@link module:ui/dropdown/utils~addToolbarToDropdown} helpers. See more examples in\n * {@link module:ui/dropdown/utils~createDropdown} documentation.\n *\n * If you want to create a completely custom dropdown, then you can compose it manually:\n *\n * ```ts\n * const button = new DropdownButtonView( locale );\n * const panel = new DropdownPanelView( locale );\n * const dropdown = new DropdownView( locale, button, panel );\n *\n * button.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.render();\n *\n * panel.element.textContent = 'Content of the panel';\n *\n * // Will render a dropdown with a panel containing a \"Content of the panel\" text.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * However, dropdown created this way will contain little behavior. You will need to implement handlers for actions\n * such as {@link module:ui/bindings/clickoutsidehandler~clickOutsideHandler clicking outside an open dropdown}\n * (which should close it) and support for arrow keys inside the panel. Therefore, unless you really know what\n * you do and you really need to do it, it is recommended to use the {@link module:ui/dropdown/utils~createDropdown} helper.\n */\nexport default class DropdownView extends View<HTMLDivElement> {\n\t/**\n\t * Button of the dropdown view. Clicking the button opens the {@link #panelView}.\n\t */\n\tpublic readonly buttonView: DropdownButton & FocusableView;\n\n\t/**\n\t * Panel of the dropdown. It opens when the {@link #buttonView} is\n\t * {@link module:ui/button/button~Button#event:execute executed} (i.e. clicked).\n\t *\n\t * Child views can be added to the panel's `children` collection:\n\t *\n\t * ```ts\n\t * dropdown.panelView.children.add( childView );\n\t * ```\n\t *\n\t * See {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#children} and\n\t * {@link module:ui/viewcollection~ViewCollection#add}.\n\t */\n\tpublic readonly panelView: DropdownPanelView;\n\n\t/**\n\t * Tracks information about the DOM focus in the dropdown.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the dropdown:\n\t *\n\t * * <kbd>▼</kbd> opens the dropdown,\n\t * * <kbd>◀</kbd> and <kbd>Esc</kbd> closes the dropdown.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A child {@link module:ui/list/listview~ListView list view} of the dropdown located\n\t * in its {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t *\n\t * **Note**: Only supported when dropdown has list view added using {@link module:ui/dropdown/utils~addListToDropdown}.\n\t */\n\tpublic listView?: ListView;\n\n\t/**\n\t * A child toolbar of the dropdown located in the\n\t * {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t *\n\t * **Note**: Only supported when dropdown has a toolbar added using {@link module:ui/dropdown/utils~addToolbarToDropdown}.\n\t */\n\tpublic toolbarView?: ToolbarView;\n\n\t/**\n\t * A child menu component of the dropdown located\n\t * in its {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel}.\n\t *\n\t * **Note**: Only supported when dropdown has a menu added using {@link module:ui/dropdown/utils~addMenuToDropdown}.\n\t */\n\tpublic menuView?: DropdownMenuRootListView;\n\n\t/**\n\t * Controls whether the dropdown view is open, i.e. shows or hides the {@link #panelView panel}.\n\t *\n\t * **Note**: When the dropdown gets open, it will attempt to call `focus()` on the first child of its {@link #panelView}.\n\t * See {@link module:ui/dropdown/utils~addToolbarToDropdown}, {@link module:ui/dropdown/utils~addListToDropdown}, and\n\t * {@link module:ui/dropdown/utils~focusChildOnDropdownOpen} to learn more about focus management in dropdowns.\n\t *\n\t * @observable\n\t */\n\tdeclare public isOpen: boolean;\n\n\t/**\n\t * Controls whether the dropdown is enabled, i.e. it can be clicked and execute an action.\n\t *\n\t * See {@link module:ui/button/buttonview~ButtonView#isEnabled}.\n\t *\n\t * @observable\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * (Optional) The additional CSS class set on the dropdown {@link #element}.\n\t *\n\t * @observable\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * (Optional) The `id` attribute of the dropdown (i.e. to pair with a `<label>` element).\n\t *\n\t * @observable\n\t */\n\tdeclare public id: string | undefined;\n\n\t/**\n\t * The position of the panel, relative to the dropdown.\n\t *\n\t * **Note**: When `'auto'`, the panel will use one of the remaining positions to stay\n\t * in the viewport, visible to the user. The positions correspond directly to\n\t * {@link module:ui/dropdown/dropdownview~DropdownView.defaultPanelPositions default panel positions}.\n\t *\n\t * **Note**: This value has an impact on the\n\t * {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView#position} property\n\t * each time the panel becomes {@link #isOpen open}.\n\t *\n\t * @observable\n\t * @default 'auto'\n\t */\n\tdeclare public panelPosition: PanelPosition | 'auto';\n\n\t/**\n\t * @observable\n\t */\n\tdeclare public ariaDescribedById: string | undefined;\n\n\t/**\n\t * Creates an instance of the dropdown.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor(\n\t\tlocale: Locale | undefined,\n\t\tbuttonView: DropdownButton & FocusableView,\n\t\tpanelView: DropdownPanelView\n\t) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.buttonView = buttonView;\n\t\tthis.panelView = panelView;\n\n\t\tthis.set( 'isOpen', false );\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'class', undefined );\n\t\tthis.set( 'id', undefined );\n\t\tthis.set( 'panelPosition', 'auto' );\n\n\t\t// Toggle the visibility of the panel when the dropdown becomes open.\n\t\tthis.panelView.bind( 'isVisible' ).to( this, 'isOpen' );\n\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-dropdown',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isEnabled', 'ck-disabled', value => !value )\n\t\t\t\t],\n\t\t\t\tid: bind.to( 'id' ),\n\t\t\t\t'aria-describedby': bind.to( 'ariaDescribedById' )\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tbuttonView,\n\t\t\t\tpanelView\n\t\t\t]\n\t\t} );\n\n\t\tbuttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown__button'\n\t\t\t\t],\n\t\t\t\t'data-cke-tooltip-disabled': bind.to( 'isOpen' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.focusTracker.add( this.buttonView.element! );\n\t\tthis.focusTracker.add( this.panelView.element! );\n\n\t\t// Toggle the dropdown when its button has been clicked.\n\t\tthis.listenTo<DropdownButtonOpenEvent>( this.buttonView, 'open', () => {\n\t\t\tthis.isOpen = !this.isOpen;\n\t\t} );\n\n\t\t// Let the dropdown control the position of the panel. The position must\n\t\t// be updated every time the dropdown is open.\n\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( evt, name, isOpen ) => {\n\t\t\tif ( !isOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If \"auto\", find the best position of the panel to fit into the viewport.\n\t\t\t// Otherwise, simply assign the static position.\n\t\t\tif ( this.panelPosition === 'auto' ) {\n\t\t\t\tconst optimalPanelPosition = DropdownView._getOptimalPosition( {\n\t\t\t\t\telement: this.panelView.element!,\n\t\t\t\t\ttarget: this.buttonView.element!,\n\t\t\t\t\tfitInViewport: true,\n\t\t\t\t\tpositions: this._panelPositions\n\t\t\t\t} );\n\n\t\t\t\tthis.panelView.position = (\n\t\t\t\t\toptimalPanelPosition ? optimalPanelPosition.name : this._panelPositions[ 0 ].name\n\t\t\t\t) as PanelPosition;\n\t\t\t} else {\n\t\t\t\tthis.panelView.position = this.panelPosition;\n\t\t\t}\n\t\t} );\n\n\t\t// Listen for keystrokes coming from within #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\tconst closeDropdown = ( data: unknown, cancel: () => void ) => {\n\t\t\tif ( this.isOpen ) {\n\t\t\t\tthis.isOpen = false;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t};\n\n\t\t// Open the dropdown panel using the arrow down key, just like with return or space.\n\t\tthis.keystrokes.set( 'arrowdown', ( data, cancel ) => {\n\t\t\t// Don't open if the dropdown is disabled or already open.\n\t\t\tif ( this.buttonView.isEnabled && !this.isOpen ) {\n\t\t\t\tthis.isOpen = true;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Block the right arrow key (until nested dropdowns are implemented).\n\t\tthis.keystrokes.set( 'arrowright', ( data, cancel ) => {\n\t\t\tif ( this.isOpen ) {\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Close the dropdown using the arrow left/escape key.\n\t\tthis.keystrokes.set( 'arrowleft', closeDropdown );\n\t\tthis.keystrokes.set( 'esc', closeDropdown );\n\t}\n\n\t/**\n\t * Focuses the {@link #buttonView}.\n\t */\n\tpublic focus(): void {\n\t\tthis.buttonView.focus();\n\t}\n\n\t/**\n\t * Returns {@link #panelView panel} positions to be used by the\n\t * {@link module:utils/dom/position~getOptimalPosition `getOptimalPosition()`}\n\t * utility considering the direction of the language the UI of the editor is displayed in.\n\t */\n\tprivate get _panelPositions(): Array<PositioningFunction> {\n\t\tconst {\n\t\t\tsouth, north,\n\t\t\tsouthEast, southWest,\n\t\t\tnorthEast, northWest,\n\t\t\tsouthMiddleEast, southMiddleWest,\n\t\t\tnorthMiddleEast, northMiddleWest\n\t\t} = DropdownView.defaultPanelPositions;\n\n\t\tif ( this.locale!.uiLanguageDirection !== 'rtl' ) {\n\t\t\treturn [\n\t\t\t\tsouthEast, southWest, southMiddleEast, southMiddleWest, south,\n\t\t\t\tnorthEast, northWest, northMiddleEast, northMiddleWest, north\n\t\t\t];\n\t\t} else {\n\t\t\treturn [\n\t\t\t\tsouthWest, southEast, southMiddleWest, southMiddleEast, south,\n\t\t\t\tnorthWest, northEast, northMiddleWest, northMiddleEast, north\n\t\t\t];\n\t\t}\n\t}\n\n\t/**\n\t * A set of positioning functions used by the dropdown view to determine\n\t * the optimal position (i.e. fitting into the browser viewport) of its\n\t * {@link module:ui/dropdown/dropdownview~DropdownView#panelView panel} when\n\t * {@link module:ui/dropdown/dropdownview~DropdownView#panelPosition} is set to 'auto'`.\n\t *\n\t * The available positioning functions are as follow:\n\t *\n\t * **South**\n\t *\n\t * * `south`\n\t *\n\t * ```\n\t *\t\t\t[ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southEast`\n\t *\n\t * ```\n\t *\t\t[ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWest`\n\t *\n\t * ```\n\t *\t\t         [ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southMiddleEast`\n\t *\n\t * ```\n\t *\t\t  [ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southMiddleWest`\n\t *\n\t * ```\n\t *\t\t       [ Button ]\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **North**\n\t *\n\t * * `north`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t    [ Button ]\n\t * ```\n\t *\n\t * * `northEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t[ Button ]\n\t * ```\n\t *\n\t * * `northWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t         [ Button ]\n\t * ```\n\t *\n\t * * `northMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t  [ Button ]\n\t * ```\n\t *\n\t * * `northMiddleWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|      Panel      |\n\t *\t\t+-----------------+\n\t *\t\t       [ Button ]\n\t * ```\n\t *\n\t * Positioning functions are compatible with {@link module:utils/dom/position~DomPoint}.\n\t *\n\t * The name that position function returns will be reflected in dropdown panel's class that\n\t * controls its placement. See {@link module:ui/dropdown/dropdownview~DropdownView#panelPosition}\n\t * to learn more.\n\t */\n\tpublic static defaultPanelPositions: Record<string, PositioningFunction> = {\n\t\tsouth: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.bottom,\n\t\t\t\tleft: buttonRect.left - ( panelRect.width - buttonRect.width ) / 2,\n\t\t\t\tname: 's'\n\t\t\t};\n\t\t},\n\t\tsouthEast: buttonRect => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.bottom,\n\t\t\t\tleft: buttonRect.left,\n\t\t\t\tname: 'se'\n\t\t\t};\n\t\t},\n\t\tsouthWest: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.bottom,\n\t\t\t\tleft: buttonRect.left - panelRect.width + buttonRect.width,\n\t\t\t\tname: 'sw'\n\t\t\t};\n\t\t},\n\t\tsouthMiddleEast: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.bottom,\n\t\t\t\tleft: buttonRect.left - ( panelRect.width - buttonRect.width ) / 4,\n\t\t\t\tname: 'sme'\n\t\t\t};\n\t\t},\n\t\tsouthMiddleWest: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.bottom,\n\t\t\t\tleft: buttonRect.left - ( panelRect.width - buttonRect.width ) * 3 / 4,\n\t\t\t\tname: 'smw'\n\t\t\t};\n\t\t},\n\t\tnorth: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\t\tleft: buttonRect.left - ( panelRect.width - buttonRect.width ) / 2,\n\t\t\t\tname: 'n'\n\t\t\t};\n\t\t},\n\t\tnorthEast: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\t\tleft: buttonRect.left,\n\t\t\t\tname: 'ne'\n\t\t\t};\n\t\t},\n\t\tnorthWest: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\t\tleft: buttonRect.left - panelRect.width + buttonRect.width,\n\t\t\t\tname: 'nw'\n\t\t\t};\n\t\t},\n\t\tnorthMiddleEast: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\t\tleft: buttonRect.left - ( panelRect.width - buttonRect.width ) / 4,\n\t\t\t\tname: 'nme'\n\t\t\t};\n\t\t},\n\t\tnorthMiddleWest: ( buttonRect, panelRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\t\tleft: buttonRect.left - ( panelRect.width - buttonRect.width ) * 3 / 4,\n\t\t\t\tname: 'nmw'\n\t\t\t};\n\t\t}\n\t};\n\n\t/**\n\t * A function used to calculate the optimal position for the dropdown panel.\n\t */\n\tprivate static _getOptimalPosition = getOptimalPosition;\n}\n\n/**\n * Fired when an item inside the dropdown is executed.\n *\n * **Note**: Only supported when dropdown was integrated with its child view using one of the helper functions:\n * {@link module:ui/dropdown/utils~addListToDropdown}, {@link module:ui/dropdown/utils~addToolbarToDropdown}, or\n * {@link module:ui/dropdown/utils~addMenuToDropdown}.\n *\n * When integrated with a list, it fires when a child of one of {@link module:ui/list/listitemview~ListItemView}s\n * fired `execute` event.\n *\n * When integrated with a toolbar, it fires when one of the buttons has been {@link module:ui/button/button~Button#event:execute executed}.\n *\n * When integrated with a nested menu, it fires when one of the menu buttons has been executed.\n *\n * In each case, the event is delegated from the component which fired it. It does not have additional parameters and `event.source` is the\n * original component.\n *\n * @eventName ~DropdownView#execute\n */\nexport type DropdownViewEvent = {\n\tname: 'execute';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/button/dropdownbuttonview\n */\n\nimport ButtonView from '../../button/buttonview.js';\nimport type DropdownButton from './dropdownbutton.js';\nimport IconView from '../../icon/iconview.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport dropdownArrowIcon from '../../../theme/icons/dropdown-arrow.svg';\n\n/**\n * The default dropdown button view class.\n *\n * ```ts\n * const view = new DropdownButtonView();\n *\n * view.set( {\n * \tlabel: 'A button',\n * \tkeystroke: 'Ctrl+B',\n * \ttooltip: true\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n *\n * Also see the {@link module:ui/dropdown/utils~createDropdown `createDropdown()` util}.\n */\nexport default class DropdownButtonView extends ButtonView implements DropdownButton {\n\t/**\n\t * An icon that displays arrow to indicate a dropdown button.\n\t */\n\tpublic readonly arrowView: IconView;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.arrowView = this._createArrowView();\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\t'aria-haspopup': true,\n\t\t\t\t'aria-expanded': this.bindTemplate.to( 'isOn', value => String( value ) )\n\t\t\t}\n\t\t} );\n\n\t\t// The DropdownButton interface expects the open event upon which will open the dropdown.\n\t\tthis.delegate( 'execute' ).to( this, 'open' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.children.add( this.arrowView );\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/icon/iconview~IconView} instance as {@link #arrowView}.\n\t */\n\tprivate _createArrowView() {\n\t\tconst arrowView = new IconView();\n\n\t\tarrowView.content = dropdownArrowIcon;\n\n\t\tarrowView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-dropdown__arrow'\n\t\t\t}\n\t\t} );\n\n\t\treturn arrowView;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenulistitembuttonview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport ButtonView from '../../button/buttonview.js';\n\nimport '../../../theme/components/dropdown/menu/dropdownmenulistitembutton.css';\n\n/**\n * Represents a view for a button in a dropdown menu list item.\n */\nexport default class DropdownMenuListItemButtonView extends ButtonView {\n\tpublic readonly id: string;\n\n\tconstructor( locale: Locale, id: string, label: string ) {\n\t\tsuper( locale );\n\n\t\tthis.id = id;\n\n\t\tthis.set( {\n\t\t\twithText: true,\n\t\t\twithKeystroke: true,\n\t\t\ttooltip: false,\n\t\t\trole: 'menuitem',\n\t\t\tlabel\n\t\t} );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown-menu-list__nested-menu__item__button'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenubuttonview\n */\n\nimport IconView from '../../icon/iconview.js';\nimport ListItemButtonView from '../../button/listitembuttonview.js';\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport dropdownArrowIcon from '../../../theme/icons/dropdown-arrow.svg';\n\nimport '../../../theme/components/dropdown/menu/dropdownmenubutton.css';\n\n/**\n * Represents a view for a dropdown menu button.\n */\nexport default class DropdownMenuButtonView extends ListItemButtonView {\n\t/**\n\t * An icon that displays an arrow to indicate a direction of the menu.\n\t */\n\tpublic readonly arrowView: IconView;\n\n\t/**\n\t * Creates an instance of the dropdown menu button view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( {\n\t\t\twithText: true,\n\t\t\trole: 'menuitem'\n\t\t} );\n\n\t\tthis.arrowView = this._createArrowView();\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown-menu-list__nested-menu__button'\n\t\t\t\t],\n\t\t\t\t'aria-haspopup': true,\n\t\t\t\t'aria-expanded': this.bindTemplate.to( 'isOn', value => String( value ) ),\n\t\t\t\t'data-cke-tooltip-disabled': bind.to( 'isOn' )\n\t\t\t},\n\t\t\ton: {\n\t\t\t\t'mouseenter': bind.to( 'mouseenter' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.children.add( this.arrowView );\n\t}\n\n\t/**\n\t * Creates the arrow view instance.\n\t *\n\t * @private\n\t */\n\tprivate _createArrowView() {\n\t\tconst arrowView = new IconView();\n\n\t\tarrowView.content = dropdownArrowIcon;\n\t\tarrowView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-dropdown-menu-list__nested-menu__button__arrow'\n\t\t\t}\n\t\t} );\n\n\t\treturn arrowView;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/list/listitemview\n */\n\nimport View from '../view.js';\n\nimport type { FocusableView } from '../focuscycler.js';\nimport type ViewCollection from '../viewcollection.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The list item view class.\n */\nexport default class ListItemView extends View {\n\t/**\n\t * Collection of the child views inside of the list item {@link #element}.\n\t */\n\tpublic readonly children: ViewCollection<FocusableView>;\n\n\t/**\n\t * Controls whether the item view is visible. Visible by default, list items are hidden\n\t * using a CSS class.\n\t *\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'isVisible', true );\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'li',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list__item',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t],\n\t\t\t\trole: 'presentation'\n\t\t\t},\n\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the list item.\n\t */\n\tpublic focus(): void {\n\t\tif ( this.children.first ) {\n\t\t\tthis.children.first.focus();\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/list/listseparatorview\n */\n\nimport View from '../view.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The list separator view class.\n */\nexport default class ListSeparatorView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'li',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list__separator'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/list/listitemgroupview\n */\n\nimport View from '../view.js';\nimport type ViewCollection from '../viewcollection.js';\nimport ListView from './listview.js';\nimport type ListItemView from './listitemview.js';\nimport LabelView from '../label/labelview.js';\nimport ListSeparatorView from './listseparatorview.js';\n\nimport { type Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The list item group view class.\n */\nexport default class ListItemGroupView extends View {\n\t/**\n\t * The visible label of the group.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public label: string;\n\n\t/**\n\t * Label of the group view. Its text is configurable using the {@link #label label attribute}.\n\t *\n\t * If a custom label view is not passed in `ListItemGroupView` constructor, the label is an instance\n\t * of {@link module:ui/label/labelview~LabelView}.\n\t */\n\tpublic readonly labelView: LabelView;\n\n\t/**\n\t * Collection of the child list items inside this group.\n\t */\n\tpublic readonly items: ListView[ 'items' ];\n\n\t/**\n\t * Collection of the child elements of the group.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * Controls whether the item view is visible. Visible by default, list items are hidden\n\t * using a CSS class.\n\t *\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * Creates an instance of the list item group view class.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param labelView The instance of the group's label. If not provided, an instance of\n\t * {@link module:ui/label/labelview~LabelView} is used.\n\t */\n\tconstructor( locale?: Locale, labelView: LabelView = new LabelView() ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\t\tconst nestedList = new ListView( locale );\n\n\t\tthis.set( {\n\t\t\tlabel: '',\n\t\t\tisVisible: true\n\t\t} );\n\n\t\tthis.labelView = labelView;\n\t\tthis.labelView.bind( 'text' ).to( this, 'label' );\n\n\t\tthis.children = this.createCollection();\n\t\tthis.children.addMany( [ this.labelView, nestedList ] );\n\n\t\tnestedList.set( {\n\t\t\trole: 'group',\n\t\t\tariaLabelledBy: labelView.id\n\t\t} );\n\n\t\t// Disable focus tracking and accessible navigation in the child list.\n\t\tnestedList.focusTracker.destroy();\n\t\tnestedList.keystrokes.destroy();\n\n\t\tthis.items = nestedList.items;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'li',\n\n\t\t\tattributes: {\n\t\t\t\trole: 'presentation',\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list__group',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the list item (which is not a separator).\n\t */\n\tpublic focus(): void {\n\t\tif ( this.items ) {\n\t\t\tconst firstListItem = this.items.find( item => !( item instanceof ListSeparatorView ) ) as ListItemView | ListItemGroupView;\n\t\t\tif ( firstListItem ) {\n\t\t\t\tfirstListItem.focus();\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/list/listview\n */\n\nimport View from '../view.js';\nimport FocusCycler, { type FocusableView } from '../focuscycler.js';\n\nimport ListItemView from './listitemview.js';\nimport ListItemGroupView from './listitemgroupview.js';\nimport type ListSeparatorView from './listseparatorview.js';\nimport type DropdownPanelFocusable from '../dropdown/dropdownpanelfocusable.js';\nimport ViewCollection from '../viewcollection.js';\n\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\ttype Locale,\n\ttype GetCallback,\n\ttype CollectionChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/list/list.css';\n\n/**\n * The list view class.\n */\nexport default class ListView extends View<HTMLUListElement> implements DropdownPanelFocusable {\n\t/**\n\t * The collection of focusable views in the list. It is used to determine accessible navigation\n\t * between the {@link module:ui/list/listitemview~ListItemView list items} and\n\t * {@link module:ui/list/listitemgroupview~ListItemGroupView list groups}.\n\t */\n\tpublic readonly focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * Collection of the child list views.\n\t */\n\tpublic readonly items: ViewCollection<ListItemView | ListItemGroupView | ListSeparatorView>;\n\n\t/**\n\t * Tracks information about DOM focus in the list.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Label used by assistive technologies to describe this list element.\n\t *\n\t * @observable\n\t */\n\tdeclare public ariaLabel: string | undefined;\n\n\t/**\n\t * (Optional) The ARIA property reflected by the `aria-ariaLabelledBy` DOM attribute used by assistive technologies.\n\t *\n\t * @observable\n\t */\n\tdeclare public ariaLabelledBy?: string | undefined;\n\n\t/**\n\t * The property reflected by the `role` DOM attribute to be used by assistive technologies.\n\t *\n\t * @observable\n\t */\n\tdeclare public role: string | undefined;\n\n\t/**\n\t * Helps cycling over focusable {@link #items} in the list.\n\t */\n\tprivate readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * A cached map of {@link module:ui/list/listitemgroupview~ListItemGroupView} to `change` event listeners for their `items`.\n\t * Used for accessibility and keyboard navigation purposes.\n\t */\n\tprivate readonly _listItemGroupToChangeListeners: WeakMap<ListItemGroupView, GetCallback<ListItemsChangeEvent>> = new WeakMap();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.focusables = new ViewCollection();\n\t\tthis.items = this.createCollection();\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate list items backwards using the arrowup key.\n\t\t\t\tfocusPrevious: 'arrowup',\n\n\t\t\t\t// Navigate toolbar items forwards using the arrowdown key.\n\t\t\t\tfocusNext: 'arrowdown'\n\t\t\t}\n\t\t} );\n\n\t\tthis.set( 'ariaLabel', undefined );\n\t\tthis.set( 'ariaLabelledBy', undefined );\n\t\tthis.set( 'role', undefined );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'ul',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-list'\n\t\t\t\t],\n\t\t\t\trole: bind.to( 'role' ),\n\t\t\t\t'aria-label': bind.to( 'ariaLabel' ),\n\t\t\t\t'aria-labelledby': bind.to( 'ariaLabelledBy' )\n\t\t\t},\n\n\t\t\tchildren: this.items\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Items added before rendering should be known to the #focusTracker.\n\t\tfor ( const item of this.items ) {\n\t\t\tif ( item instanceof ListItemGroupView ) {\n\t\t\t\tthis._registerFocusableItemsGroup( item );\n\t\t\t} else if ( item instanceof ListItemView ) {\n\t\t\t\tthis._registerFocusableListItem( item );\n\t\t\t}\n\t\t}\n\n\t\tthis.items.on<ListItemsChangeEvent>( 'change', ( evt, data ) => {\n\t\t\tfor ( const removed of data.removed ) {\n\t\t\t\tif ( removed instanceof ListItemGroupView ) {\n\t\t\t\t\tthis._deregisterFocusableItemsGroup( removed );\n\t\t\t\t} else if ( removed instanceof ListItemView ) {\n\t\t\t\t\tthis._deregisterFocusableListItem( removed );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( const added of Array.from( data.added ).reverse() ) {\n\t\t\t\tif ( added instanceof ListItemGroupView ) {\n\t\t\t\t\tthis._registerFocusableItemsGroup( added, data.index );\n\t\t\t\t} else {\n\t\t\t\t\tthis._registerFocusableListItem( added, data.index );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #items}.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #items}.\n\t */\n\tpublic focusFirst(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the last focusable in {@link #items}.\n\t */\n\tpublic focusLast(): void {\n\t\tthis._focusCycler.focusLast();\n\t}\n\n\t/**\n\t * Registers a list item view in the focus tracker.\n\t *\n\t * @param item The list item view to be registered.\n\t * @param index Index of the list item view in the {@link #items} collection. If not specified, the item will be added at the end.\n\t */\n\tprivate _registerFocusableListItem( item: ListItemView, index?: number ) {\n\t\tthis.focusTracker.add( item.element! );\n\t\tthis.focusables.add( item, index );\n\t}\n\n\t/**\n\t * Removes a list item view from the focus tracker.\n\t *\n\t * @param item The list item view to be removed.\n\t */\n\tprivate _deregisterFocusableListItem( item: ListItemView ) {\n\t\tthis.focusTracker.remove( item.element! );\n\t\tthis.focusables.remove( item );\n\t}\n\n\t/**\n\t * Gets a callback that will be called when the `items` collection of a {@link module:ui/list/listitemgroupview~ListItemGroupView}\n\t * change.\n\t *\n\t * @param groupView The group view for which the callback will be created.\n\t * @returns The callback function to be used for the items `change` event listener in a group.\n\t */\n\tprivate _getOnGroupItemsChangeCallback( groupView: ListItemGroupView ): GetCallback<ListItemsChangeEvent> {\n\t\treturn ( evt, data ) => {\n\t\t\tfor ( const removed of data.removed ) {\n\t\t\t\tthis._deregisterFocusableListItem( removed );\n\t\t\t}\n\n\t\t\tfor ( const added of Array.from( data.added ).reverse() ) {\n\t\t\t\tthis._registerFocusableListItem( added, this.items.getIndex( groupView ) + data.index );\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Registers a list item group view (and its children) in the focus tracker.\n\t *\n\t * @param groupView A group view to be registered.\n\t * @param groupIndex Index of the group view in the {@link #items} collection. If not specified, the group will be added at the end.\n\t */\n\tprivate _registerFocusableItemsGroup( groupView: ListItemGroupView, groupIndex?: number ) {\n\t\tArray.from( groupView.items ).forEach( ( child, childIndex ) => {\n\t\t\tconst registeredChildIndex = typeof groupIndex !== 'undefined' ? groupIndex + childIndex : undefined;\n\n\t\t\tthis._registerFocusableListItem( child as ListItemView, registeredChildIndex );\n\t\t} );\n\n\t\tconst groupItemsChangeCallback = this._getOnGroupItemsChangeCallback( groupView );\n\n\t\t// Cache the reference to the callback in case the group is removed (see _deregisterFocusableItemsGroup()).\n\t\tthis._listItemGroupToChangeListeners.set( groupView, groupItemsChangeCallback );\n\n\t\tgroupView.items.on<ListItemsChangeEvent>( 'change', groupItemsChangeCallback );\n\t}\n\n\t/**\n\t * Removes a list item group view (and its children) from the focus tracker.\n\t *\n\t * @param groupView The group view to be removed.\n\t */\n\tprivate _deregisterFocusableItemsGroup( groupView: ListItemGroupView ) {\n\t\tfor ( const child of groupView.items ) {\n\t\t\tthis._deregisterFocusableListItem( child as ListItemView );\n\t\t}\n\n\t\tgroupView.items.off( 'change', this._listItemGroupToChangeListeners.get( groupView )! );\n\t\tthis._listItemGroupToChangeListeners.delete( groupView );\n\t}\n}\n\n// There's no support for nested groups yet.\ntype ListItemsChangeEvent = CollectionChangeEvent<ListItemView>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenulistview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport ListView from '../../list/listview.js';\n\n/**\n * Represents a dropdown menu list view.\n */\nexport default class DropdownMenuListView extends ListView {\n\t/**\n\t * Represents whether the dropdown menu list view is visible or not.\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * Creates an instance of the dropdown menu list view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.role = 'menu';\n\t\tthis.set( 'isVisible', true );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown-menu-list',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/utils\n */\n\nimport type { PositioningFunction } from '@ckeditor/ckeditor5-utils';\n\nconst NESTED_PANEL_HORIZONTAL_OFFSET = 5;\n\n/**\n * Contains every positioning function used by {@link module:ui/dropdown/menu/dropdownmenunestedmenuview~DropdownMenuNestedMenuView} that\n * decides where the {@link module:ui/dropdown/menu/dropdownmenunestedmenuview~DropdownMenuNestedMenuView#panelView} should be placed.\n *\n * Positioning functions:\n *\n *\t┌──────┬───────────────┐\n *\t│      │               │\n *\t└──────┤               │\n *\t       │               │\n *\t       │            ES │\n *\t       └───────────────┘\n *\n *\t┌───────────────┬──────┐\n *\t│               │      │\n *\t│               ├──────┘\n *\t│               │\n *\t│ WS            │\n *\t└───────────────┘\n *\n *\t       ┌───────────────┐\n *\t       │            EN │\n *\t       │               │\n *\t┌──────┤               │\n *\t│      │               │\n *\t└──────┴───────────────┘\n *\n *\t┌───────────────┐\n *\t│ WN            │\n *\t│               │\n *\t│               ├──────┐\n *\t│               │      │\n *\t└───────────────┴──────┘\n */\nexport const DropdownMenuPanelPositioningFunctions: Record<string, PositioningFunction> = {\n\teastSouth: buttonRect => ( {\n\t\ttop: buttonRect.top,\n\t\tleft: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\tname: 'es'\n\t} ),\n\n\teastNorth: ( buttonRect, panelRect ) => ( {\n\t\ttop: buttonRect.top - panelRect.height + buttonRect.height,\n\t\tleft: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\tname: 'en'\n\t} ),\n\n\twestSouth: ( buttonRect, panelRect ) => ( {\n\t\ttop: buttonRect.top,\n\t\tleft: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\tname: 'ws'\n\t} ),\n\n\twestNorth: ( buttonRect, panelRect ) => ( {\n\t\ttop: buttonRect.top - panelRect.height + buttonRect.height,\n\t\tleft: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\tname: 'wn'\n\t} )\n} as const;\n\n/**\n * Represents the definition of a dropdown menu.\n */\nexport type DropdownNestedMenuDefinition = {\n\n\t/**\n\t * Unique ID for the menu.\n\t */\n\tid: string;\n\n\t/**\n\t * The menu name. It is used as a label for the button which opens the menu list.\n\t */\n\tmenu: string;\n\n\t/**\n\t * The children of the dropdown menu.\n\t */\n\tchildren: DropdownMenuDefinition;\n};\n\n/**\n * Represents the definition of a dropdown menu item.\n */\nexport type DropdownMenuButtonDefinition = {\n\n\t/**\n\t * Unique ID for the button.\n\t */\n\tid: string;\n\n\t/**\n\t * The label for the button.\n\t */\n\tlabel: string;\n};\n\n/**\n * A definition for a nestable menu component.\n *\n * The menu can be flat and include only top-level items, or it can include multiple levels of nested sub-menus.\n *\n * Example:\n *\n * ```ts\n * [\n * \t{\n * \t\tid: 'menu_1',\n * \t\tmenu: 'Menu 1',\n * \t\tchildren: [\n * \t\t\t{\n * \t\t\t\tid: 'menu_1_1',\n * \t\t\t\tmenu: 'Nested menu 1',\n * \t\t\t\tchildren: [\n * \t\t\t\t\t{\n * \t\t\t\t\t\tid: 'item_x',\n * \t\t\t\t\t\tlabel: 'Item X'\n * \t\t\t\t\t}\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tid: 'menu_1_2',\n * \t\t\t\tmenu: 'Nested menu 2',\n * \t\t\t\tchildren: [\n * \t\t\t\t\t{\n * \t\t\t\t\t\tid: 'item_y',\n * \t\t\t\t\t\tlabel: 'Item Y'\n * \t\t\t\t\t},\n * \t\t\t\t\t{\n * \t\t\t\t\t\tid: 'item_z',\n * \t\t\t\t\t\tlabel: 'Item Z'\n * \t\t\t\t\t}\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tid: 'top_a',\n * \t\tlabel: 'Top Item A'\n * \t},\n * \t{\n * \t\tid: 'top_b',\n * \t\tlabel: 'Top Item B'\n * \t}\n * ];\n * ```\n */\nexport type DropdownMenuDefinition = Array<DropdownNestedMenuDefinition | DropdownMenuButtonDefinition>;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenulistitemview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport type DropdownMenuNestedMenuView from './dropdownmenunestedmenuview.js';\n\nimport ListItemView from '../../list/listitemview.js';\nimport DropdownMenuListItemButtonView from './dropdownmenulistitembuttonview.js';\n\nimport '../../../theme/components/dropdown/menu/dropdownmenulistitem.css';\n\n/**\n * Represents a view for a single item in a dropdown menu list.\n */\nexport default class DropdownMenuListItemView extends ListItemView {\n\t/**\n\t * The view representing either a flat item or a nested menu in a dropdown menu list item.\n\t */\n\tpublic readonly childView: DropdownMenuNestedMenuView | DropdownMenuListItemButtonView;\n\n\tconstructor(\n\t\tlocale: Locale,\n\t\tparentMenuView: DropdownMenuNestedMenuView | null,\n\t\tchildView: DropdownMenuNestedMenuView | DropdownMenuListItemButtonView\n\t) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.childView = childView;\n\t\tthis.children.add( childView );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-dropdown-menu-list__nested-menu__item'\n\t\t\t\t]\n\t\t\t},\n\t\t\ton: {\n\t\t\t\t'mouseenter': bind.to( 'mouseenter' )\n\t\t\t}\n\t\t} );\n\n\t\tif ( parentMenuView ) {\n\t\t\tthis.delegate( 'mouseenter' ).to( parentMenuView );\n\n\t\t\tif ( childView instanceof DropdownMenuListItemButtonView ) {\n\t\t\t\tchildView.delegate( 'execute' ).to( parentMenuView );\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenubehaviors\n */\n\nimport type { BaseEvent, ObservableChangeEvent } from '@ckeditor/ckeditor5-utils';\nimport type DropdownMenuNestedMenuView from './dropdownmenunestedmenuview.js';\nimport type { FocusableView } from '../../focuscycler.js';\n\nimport type { ButtonExecuteEvent } from '../../button/button.js';\nimport type DropdownMenuRootListView from './dropdownmenurootlistview.js';\n\nimport DropdownMenuListItemView from './dropdownmenulistitemview.js';\n\nexport const DropdownRootMenuBehaviors = {\n\t/**\n\t * Move focus to a menu item on mouse hover. If it is a button to open a nested menu, open that menu.\n\t */\n\ttoggleMenusAndFocusItemsOnHover( rootList: DropdownMenuRootListView ): void {\n\t\trootList.on<DropdownMenuMouseEnterEvent>( 'menu:mouseenter', evt => {\n\t\t\tconst [ pathLeaf ] = evt.path;\n\n\t\t\t( evt.source as FocusableView ).focus();\n\n\t\t\tfor ( const menuView of rootList.menus ) {\n\t\t\t\tconst isListItemContainingMenu = pathLeaf instanceof DropdownMenuListItemView && pathLeaf.childView === menuView;\n\n\t\t\t\tmenuView.isOpen = ( evt.path.includes( menuView ) || isListItemContainingMenu ) && menuView.isEnabled;\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Handles the following case:\n\t *\n\t * 1. Hover to open a sub-menu (A). The button has focus.\n\t * 2. Press arrow up/down to move focus to another sub-menu (B) button.\n\t * 3. Press arrow right to open the sub-menu (B).\n\t * 4. The sub-menu (A) should close (if not, there are two open menus).\n\t */\n\tcloseMenuWhenAnotherOnTheSameLevelOpens( rootList: DropdownMenuRootListView ): void {\n\t\trootList.on<DropdownMenuChangeIsOpenEvent>( 'menu:change:isOpen', ( evt, name, isOpen ) => {\n\t\t\tif ( !isOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst evtMenu = evt.source as DropdownMenuNestedMenuView;\n\n\t\t\tfor ( const menuView of rootList.menus ) {\n\t\t\t\tif ( evtMenu.parentMenuView === menuView.parentMenuView && evtMenu !== menuView ) {\n\t\t\t\t\tmenuView.isOpen = false;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n};\n\nexport const DropdownMenuBehaviors = {\n\t/**\n\t * Open the menu on the right arrow key press (left, in RTL mode). This allows for navigating to sub-menus using the keyboard.\n\t */\n\topenOnArrowRightKey( menuView: DropdownMenuNestedMenuView ): void {\n\t\tconst keystroke = menuView.locale!.uiLanguageDirection === 'rtl' ? 'arrowleft' : 'arrowright';\n\n\t\tmenuView.keystrokes.set( keystroke, ( data, cancel ) => {\n\t\t\tif ( menuView.focusTracker.focusedElement !== menuView.buttonView.element || !menuView.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !menuView.isOpen ) {\n\t\t\t\tmenuView.isOpen = true;\n\t\t\t}\n\n\t\t\tmenuView.panelView.focus();\n\t\t\tcancel();\n\t\t} );\n\t},\n\n\t/**\n\t * Opens the menu on its button click as well as enter and space keys press (if the button is focused).\n\t */\n\topenOnButtonClick( menuView: DropdownMenuNestedMenuView ): void {\n\t\tmenuView.buttonView.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\tif ( menuView.isEnabled ) {\n\t\t\t\tmenuView.isOpen = true;\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Opens the menu and focuses the panel content upon pressing the Enter key.\n\t */\n\topenAndFocusOnEnterKeyPress( menuView: DropdownMenuNestedMenuView ): void {\n\t\tmenuView.keystrokes.set( 'enter', ( data, cancel ) => {\n\t\t\t// Engage only for Enter key press when the button is focused. The panel can contain\n\t\t\t// other UI components and features that rely on the Enter key press.\n\t\t\tif ( menuView.focusTracker.focusedElement !== menuView.buttonView.element ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmenuView.isOpen = true;\n\t\t\tmenuView.panelView.focus();\n\t\t\tcancel();\n\t\t} );\n\t},\n\n\t/**\n\t * Closes the menu on the left key press (right, in RTL mode). This allows for navigating to sub-menus using the keyboard.\n\t */\n\tcloseOnArrowLeftKey( menuView: DropdownMenuNestedMenuView ): void {\n\t\tconst keystroke = menuView.locale!.uiLanguageDirection === 'rtl' ? 'arrowright' : 'arrowleft';\n\n\t\tmenuView.keystrokes.set( keystroke, ( data, cancel ) => {\n\t\t\tif ( menuView.isOpen ) {\n\t\t\t\t// Focus first, then close the panel. Otherwise, Safari won't send blur events for detached DOM elements, leading to errors.\n\t\t\t\tmenuView.focus();\n\t\t\t\tmenuView.isOpen = false;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\t},\n\n\tcloseOnEscKey( menuView: DropdownMenuNestedMenuView ): void {\n\t\tmenuView.keystrokes.set( 'esc', ( data, cancel ) => {\n\t\t\tif ( menuView.isOpen ) {\n\t\t\t\t// Focus first, then close the panel. Otherwise, Safari won't send blur events for detached DOM elements, leading to errors.\n\t\t\t\tmenuView.focus();\n\t\t\t\tmenuView.isOpen = false;\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Closes the menu when its parent menu closes. This prevents from leaving orphaned open menus.\n\t */\n\tcloseOnParentClose( menuView: DropdownMenuNestedMenuView, parentMenuView: DropdownMenuNestedMenuView ): void {\n\t\tparentMenuView.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( evt, name, isOpen ) => {\n\t\t\t// TODO: Remove checking `evt.source` if `change:isOpen` is no longer delegated.\n\t\t\tif ( !isOpen && evt.source === parentMenuView ) {\n\t\t\t\tmenuView.isOpen = false;\n\t\t\t}\n\t\t} );\n\t}\n};\n\n/**\n * Represents a dropdown menu mouse enter event.\n */\ninterface DropdownMenuMouseEnterEvent extends BaseEvent {\n\n\t/**\n\t * The name of the event.\n\t */\n\tname: 'menu:mouseenter';\n}\n\n/**\n * Represents a dropdown menu change is open event.\n */\ninterface DropdownMenuChangeIsOpenEvent extends BaseEvent {\n\n\t/**\n\t * The name of the event.\n\t */\n\tname: 'menu:change:isOpen';\n\n\t/**\n\t * The arguments of the event.\n\t */\n\targs: [ name: string, value: boolean, oldValue: boolean ];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/panel/balloon/balloonpanelview\n */\n\nimport View from '../../view.js';\nimport type ViewCollection from '../../viewcollection.js';\n\nimport {\n\tgetOptimalPosition,\n\tglobal,\n\tisRange,\n\ttoUnit,\n\tisVisible,\n\tisText,\n\tResizeObserver,\n\ttype Locale,\n\ttype ObservableChangeEvent,\n\ttype DomPoint,\n\ttype PositionOptions,\n\ttype Rect,\n\ttype PositioningFunction\n} from '@ckeditor/ckeditor5-utils';\n\nimport { isElement } from 'lodash-es';\nimport '../../../theme/components/panel/balloonpanel.css';\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n// A static balloon panel positioning function that moves the balloon far off the viewport.\n// It is used as a fallback when there is no way to position the balloon using provided\n// positioning functions (see: `getOptimalPosition()`), for instance, when the target the\n// balloon should be attached to gets obscured by scrollable containers or the viewport.\n//\n// It prevents the balloon from being attached to the void and possible degradation of the UX.\n// At the same time, it keeps the balloon physically visible in the DOM so the focus remains\n// uninterrupted.\nconst POSITION_OFF_SCREEN: DomPoint = {\n\ttop: -99999,\n\tleft: -99999,\n\tname: 'arrowless',\n\tconfig: {\n\t\twithArrow: false\n\t}\n};\n\n/**\n * The balloon panel view class.\n *\n * A floating container which can\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#pin pin} to any\n * {@link module:utils/dom/position~Options#target target} in the DOM and remain in that position\n * e.g. when the web page is scrolled.\n *\n * The balloon panel can be used to display contextual, non-blocking UI like forms, toolbars and\n * the like in its {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#content} view\n * collection.\n *\n * There is a number of {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}\n * that the balloon can use, automatically switching from one to another when the viewport space becomes\n * scarce to keep the balloon visible to the user as long as it is possible. The balloon will also\n * accept any custom position set provided by the user compatible with the\n * {@link module:utils/dom/position~Options options}.\n *\n * ```ts\n * const panel = new BalloonPanelView( locale );\n * const childView = new ChildView();\n * const positions = BalloonPanelView.defaultPositions;\n *\n * panel.render();\n *\n * // Add a child view to the panel's content collection.\n * panel.content.add( childView );\n *\n * // Start pinning the panel to an element with the \"target\" id DOM.\n * // The balloon will remain pinned until unpin() is called.\n * panel.pin( {\n * \ttarget: document.querySelector( '#target' ),\n * \tpositions: [\n * \t\tpositions.northArrowSouth,\n * \t\tpositions.southArrowNorth\n * \t]\n * } );\n * ```\n */\nexport default class BalloonPanelView extends View {\n\t/**\n\t * A collection of the child views that creates the balloon panel contents.\n\t */\n\tpublic readonly content: ViewCollection;\n\n\t/**\n\t * The absolute top position of the balloon panel in pixels.\n\t *\n\t * @observable\n\t * @default 0\n\t */\n\tdeclare public top: number;\n\n\t/**\n\t * The absolute left position of the balloon panel in pixels.\n\t *\n\t * @observable\n\t * @default 0\n\t */\n\tdeclare public left: number;\n\n\t/**\n\t * The balloon panel's current position. The position name is reflected in the CSS class set\n\t * to the balloon, i.e. `.ck-balloon-panel_arrow_nw` for the \"arrow_nw\" position. The class\n\t * controls the minor aspects of the balloon's visual appearance like the placement\n\t * of an {@link #withArrow arrow}. To support a new position, an additional CSS must be created.\n\t *\n\t * Default position names correspond with\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t *\n\t * See the {@link #attachTo} and {@link #pin} methods to learn about custom balloon positions.\n\t *\n\t * @observable\n\t * @default 'arrow_nw'\n\t */\n\tdeclare public position: 'arrow_nw' | 'arrow_ne' | 'arrow_sw' | 'arrow_se';\n\n\t/**\n\t * Controls whether the balloon panel is visible or not.\n\t *\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * Controls whether the balloon panel has an arrow. The presence of the arrow\n\t * is reflected in the `ck-balloon-panel_with-arrow` CSS class.\n\t *\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public withArrow: boolean;\n\n\t/**\n\t * An additional CSS class added to the {@link #element}.\n\t *\n\t * @observable\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * A callback that starts pinning the panel when {@link #isVisible} gets\n\t * `true`. Used by {@link #pin}.\n\t *\n\t * @private\n\t */\n\tprivate _pinWhenIsVisibleCallback: ( () => void ) | null;\n\n\t/**\n\t * An instance of resize observer used to detect if target element is still visible.\n\t */\n\tprivate _resizeObserver: ResizeObserver | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'top', 0 );\n\t\tthis.set( 'left', 0 );\n\t\tthis.set( 'position', 'arrow_nw' );\n\t\tthis.set( 'isVisible', false );\n\t\tthis.set( 'withArrow', true );\n\t\tthis.set( 'class', undefined );\n\n\t\tthis._pinWhenIsVisibleCallback = null;\n\t\tthis._resizeObserver = null;\n\n\t\tthis.content = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-balloon-panel',\n\t\t\t\t\tbind.to( 'position', value => `ck-balloon-panel_${ value }` ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-balloon-panel_visible' ),\n\t\t\t\t\tbind.if( 'withArrow', 'ck-balloon-panel_with-arrow' ),\n\t\t\t\t\tbind.to( 'class' )\n\t\t\t\t],\n\n\t\t\t\tstyle: {\n\t\t\t\t\ttop: bind.to( 'top', toPx ),\n\t\t\t\t\tleft: bind.to( 'left', toPx )\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tchildren: this.content\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis.hide();\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Shows the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */\n\tpublic show(): void {\n\t\tthis.isVisible = true;\n\t}\n\n\t/**\n\t * Hides the panel.\n\t *\n\t * See {@link #isVisible}.\n\t */\n\tpublic hide(): void {\n\t\tthis.isVisible = false;\n\t}\n\n\t/**\n\t * Attaches the panel to a specified {@link module:utils/dom/position~Options#target} with a\n\t * smart positioning heuristics that chooses from available positions to make sure the panel\n\t * is visible to the user i.e. within the limits of the viewport.\n\t *\n\t * This method accepts configuration {@link module:utils/dom/position~Options options}\n\t * to set the `target`, optional `limiter` and `positions` the balloon should choose from.\n\t *\n\t * ```ts\n\t * const panel = new BalloonPanelView( locale );\n\t * const positions = BalloonPanelView.defaultPositions;\n\t *\n\t * panel.render();\n\t *\n\t * // Attach the panel to an element with the \"target\" id DOM.\n\t * panel.attachTo( {\n\t * \ttarget: document.querySelector( '#target' ),\n\t * \tpositions: [\n\t * \t\tpositions.northArrowSouth,\n\t * \t\tpositions.southArrowNorth\n\t * \t]\n\t * } );\n\t * ```\n\t *\n\t * **Note**: Attaching the panel will also automatically {@link #show} it.\n\t *\n\t * **Note**: An attached panel will not follow its target when the window is scrolled or resized.\n\t * See the {@link #pin} method for a more permanent positioning strategy.\n\t *\n\t * @param options Positioning options compatible with {@link module:utils/dom/position~getOptimalPosition}.\n\t * Default `positions` array is {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t * @returns Whether the balloon was shown and successfully attached or not. Attaching can fail if the target\n\t * provided in the options is invisible (e.g. element detached from DOM).\n\t */\n\tpublic attachTo( options: Partial<PositionOptions> ): boolean {\n\t\tconst target = getDomElement( options.target );\n\n\t\tif ( target && !isVisible( target ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.show();\n\n\t\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\t\tconst positionOptions = Object.assign( {}, {\n\t\t\telement: this.element,\n\t\t\tpositions: [\n\t\t\t\tdefaultPositions.southArrowNorth,\n\t\t\t\tdefaultPositions.southArrowNorthMiddleWest,\n\t\t\t\tdefaultPositions.southArrowNorthMiddleEast,\n\t\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\t\tdefaultPositions.southArrowNorthEast,\n\t\t\t\tdefaultPositions.northArrowSouth,\n\t\t\t\tdefaultPositions.northArrowSouthMiddleWest,\n\t\t\t\tdefaultPositions.northArrowSouthMiddleEast,\n\t\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\t\tdefaultPositions.northArrowSouthEast,\n\t\t\t\tdefaultPositions.viewportStickyNorth\n\t\t\t],\n\t\t\tlimiter: global.document.body,\n\t\t\tfitInViewport: true\n\t\t}, options ) as PositionOptions;\n\n\t\tconst optimalPosition = BalloonPanelView._getOptimalPosition( positionOptions ) || POSITION_OFF_SCREEN;\n\n\t\t// Usually browsers make some problems with super accurate values like 104.345px\n\t\t// so it is better to use int values.\n\t\tconst left = parseInt( optimalPosition.left as any );\n\t\tconst top = parseInt( optimalPosition.top as any );\n\n\t\tconst position = optimalPosition.name as this[ 'position' ];\n\t\tconst config: { withArrow?: boolean } = optimalPosition.config || {};\n\t\tconst { withArrow = true } = config;\n\n\t\tthis.top = top;\n\t\tthis.left = left;\n\t\tthis.position = position;\n\t\tthis.withArrow = withArrow;\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Works the same way as the {@link #attachTo} method except that the position of the panel is\n\t * continuously updated when:\n\t *\n\t * * any ancestor of the {@link module:utils/dom/position~Options#target}\n\t * or {@link module:utils/dom/position~Options#limiter} is scrolled,\n\t * * the browser window gets resized or scrolled.\n\t *\n\t * Thanks to that, the panel always sticks to the {@link module:utils/dom/position~Options#target}\n\t * and is immune to the changing environment.\n\t *\n\t * ```ts\n\t * const panel = new BalloonPanelView( locale );\n\t * const positions = BalloonPanelView.defaultPositions;\n\t *\n\t * panel.render();\n\t *\n\t * // Pin the panel to an element with the \"target\" id DOM.\n\t * panel.pin( {\n\t * \ttarget: document.querySelector( '#target' ),\n\t * \tpositions: [\n\t * \t\tpositions.northArrowSouth,\n\t * \t\tpositions.southArrowNorth\n\t * \t]\n\t * } );\n\t * ```\n\t *\n\t * To leave the pinned state, use the {@link #unpin} method.\n\t *\n\t * **Note**: Pinning the panel will also automatically {@link #show} it.\n\t *\n\t * @param options Positioning options compatible with {@link module:utils/dom/position~getOptimalPosition}.\n\t * Default `positions` array is {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t */\n\tpublic pin( options: Partial<PositionOptions> ): void {\n\t\tthis.unpin();\n\n\t\tif ( !this._startPinning( options ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._pinWhenIsVisibleCallback = () => {\n\t\t\tif ( this.isVisible ) {\n\t\t\t\tthis._startPinning( options );\n\t\t\t} else {\n\t\t\t\tthis._stopPinning();\n\t\t\t}\n\t\t};\n\n\t\t// Control the state of the listeners depending on whether the panel is visible\n\t\t// or not.\n\t\t// TODO: Use on() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n\t\tthis.listenTo<ObservableChangeEvent>( this, 'change:isVisible', this._pinWhenIsVisibleCallback );\n\t}\n\n\t/**\n\t * Stops pinning the panel, as set up by {@link #pin}.\n\t */\n\tpublic unpin(): void {\n\t\tif ( this._pinWhenIsVisibleCallback ) {\n\t\t\t// Deactivate listeners attached by pin().\n\t\t\tthis._stopPinning();\n\n\t\t\t// Deactivate the panel pin() control logic.\n\t\t\t// TODO: Use off() (https://github.com/ckeditor/ckeditor5-utils/issues/144).\n\t\t\tthis.stopListening( this, 'change:isVisible', this._pinWhenIsVisibleCallback );\n\n\t\t\tthis._pinWhenIsVisibleCallback = null;\n\n\t\t\tthis.hide();\n\t\t}\n\t}\n\n\t/**\n\t * Starts managing the pinned state of the panel. See {@link #pin}.\n\t *\n\t * @param options Positioning options compatible with {@link module:utils/dom/position~getOptimalPosition}.\n\t * @returns Whether the balloon was shown and successfully attached or not. Attaching can fail if the target\n\t * provided in the options is invisible (e.g. element detached from DOM).\n\t */\n\tprivate _startPinning( options: Partial<PositionOptions> ): boolean {\n\t\tif ( !this.attachTo( options ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet targetElement = getDomElement( options.target );\n\t\tconst limiterElement = options.limiter ? getDomElement( options.limiter ) : global.document.body;\n\n\t\t// Then we need to listen on scroll event of eny element in the document.\n\t\tthis.listenTo( global.document, 'scroll', ( evt, domEvt ) => {\n\t\t\tconst scrollTarget = domEvt.target as Element;\n\n\t\t\t// The position needs to be updated if the positioning target is within the scrolled element.\n\t\t\tconst isWithinScrollTarget = targetElement && scrollTarget.contains( targetElement );\n\n\t\t\t// The position needs to be updated if the positioning limiter is within the scrolled element.\n\t\t\tconst isLimiterWithinScrollTarget = limiterElement && scrollTarget.contains( limiterElement );\n\n\t\t\t// The positioning target and/or limiter can be a Rect, object etc..\n\t\t\t// There's no way to optimize the listener then.\n\t\t\tif ( isWithinScrollTarget || isLimiterWithinScrollTarget || !targetElement || !limiterElement ) {\n\t\t\t\tthis.attachTo( options );\n\t\t\t}\n\t\t}, { useCapture: true } );\n\n\t\t// We need to listen on window resize event and update position.\n\t\tthis.listenTo( global.window, 'resize', () => {\n\t\t\tthis.attachTo( options );\n\t\t} );\n\n\t\t// Hide the panel if the target element is no longer visible.\n\t\tif ( !this._resizeObserver ) {\n\t\t\t// If the target element is a text node, we need to check the parent element.\n\t\t\t// It's because `ResizeObserver` accept only elements, not text nodes.\n\t\t\tif ( targetElement && isText( targetElement ) ) {\n\t\t\t\ttargetElement = targetElement.parentElement;\n\t\t\t}\n\n\t\t\tif ( targetElement ) {\n\t\t\t\tconst checkVisibility = () => {\n\t\t\t\t\t// If the target element is no longer visible, hide the panel.\n\t\t\t\t\tif ( !isVisible( targetElement ) ) {\n\t\t\t\t\t\tthis.unpin();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Element is being resized to 0x0 after it's parent became hidden,\n\t\t\t\t// so we need to check size in order to determine if it's visible or not.\n\t\t\t\tthis._resizeObserver = new ResizeObserver( targetElement, checkVisibility );\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Stops managing the pinned state of the panel. See {@link #pin}.\n\t */\n\tprivate _stopPinning(): void {\n\t\tthis.stopListening( global.document, 'scroll' );\n\t\tthis.stopListening( global.window, 'resize' );\n\n\t\tif ( this._resizeObserver ) {\n\t\t\tthis._resizeObserver.destroy();\n\t\t\tthis._resizeObserver = null;\n\t\t}\n\t}\n\n\t/**\n\t * Returns available {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n\t * {@link module:utils/dom/position~PositioningFunction positioning functions} adjusted by the specific offsets.\n\t *\n\t * @internal\n\t * @param options Options to generate positions. If not specified, this helper will simply return\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.defaultPositions}.\n\t * @param options.sideOffset A custom side offset (in pixels) of each position. If\n\t * not specified, {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowSideOffset the default value}\n\t * will be used.\n\t * @param options.heightOffset A custom height offset (in pixels) of each position. If\n\t * not specified, {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.arrowHeightOffset the default value}\n\t * will be used.\n\t * @param options.stickyVerticalOffset A custom offset (in pixels) of the `viewportStickyNorth` positioning function.\n\t * If not specified, {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.stickyVerticalOffset the default value}\n\t * will be used.\n\t * @param options.config Additional configuration of the balloon balloon panel view.\n\t * Currently only {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#withArrow} is supported. Learn more\n\t * about {@link module:utils/dom/position~PositioningFunction positioning functions}.\n\t */\n\tpublic static generatePositions( options: {\n\t\tsideOffset?: number;\n\t\theightOffset?: number;\n\t\tstickyVerticalOffset?: number;\n\t\tconfig?: object;\n\t} = {} ): Record<string, PositioningFunction> {\n\t\tconst {\n\t\t\tsideOffset = BalloonPanelView.arrowSideOffset,\n\t\t\theightOffset = BalloonPanelView.arrowHeightOffset,\n\t\t\tstickyVerticalOffset = BalloonPanelView.stickyVerticalOffset,\n\t\t\tconfig\n\t\t} = options;\n\n\t\treturn {\n\t\t\t// ------- North west\n\n\t\t\tnorthWestArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left - sideOffset,\n\t\t\t\tname: 'arrow_sw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthWestArrowSouthMiddleWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left - ( balloonRect.width * .25 ) - sideOffset,\n\t\t\t\tname: 'arrow_smw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthWestArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left - balloonRect.width / 2,\n\t\t\t\tname: 'arrow_s',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthWestArrowSouthMiddleEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left - ( balloonRect.width * .75 ) + sideOffset,\n\t\t\t\tname: 'arrow_sme',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthWestArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left - balloonRect.width + sideOffset,\n\t\t\t\tname: 'arrow_se',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- North\n\n\t\t\tnorthArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - sideOffset,\n\t\t\t\tname: 'arrow_sw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthArrowSouthMiddleWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - ( balloonRect.width * .25 ) - sideOffset,\n\t\t\t\tname: 'arrow_smw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n\t\t\t\tname: 'arrow_s',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthArrowSouthMiddleEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - ( balloonRect.width * .75 ) + sideOffset,\n\t\t\t\tname: 'arrow_sme',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width + sideOffset,\n\t\t\t\tname: 'arrow_se',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- North east\n\n\t\t\tnorthEastArrowSouthWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.right - sideOffset,\n\t\t\t\tname: 'arrow_sw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthEastArrowSouthMiddleWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.right - ( balloonRect.width * .25 ) - sideOffset,\n\t\t\t\tname: 'arrow_smw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthEastArrowSouth: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.right - balloonRect.width / 2,\n\t\t\t\tname: 'arrow_s',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthEastArrowSouthMiddleEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.right - ( balloonRect.width * .75 ) + sideOffset,\n\t\t\t\tname: 'arrow_sme',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tnorthEastArrowSouthEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getNorthTop( targetRect, balloonRect ),\n\t\t\t\tleft: targetRect.right - balloonRect.width + sideOffset,\n\t\t\t\tname: 'arrow_se',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- South west\n\n\t\t\tsouthWestArrowNorthWest: targetRect => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left - sideOffset,\n\t\t\t\tname: 'arrow_nw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthWestArrowNorthMiddleWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left - ( balloonRect.width * .25 ) - sideOffset,\n\t\t\t\tname: 'arrow_nmw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthWestArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left - balloonRect.width / 2,\n\t\t\t\tname: 'arrow_n',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthWestArrowNorthMiddleEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left - ( balloonRect.width * .75 ) + sideOffset,\n\t\t\t\tname: 'arrow_nme',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthWestArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left - balloonRect.width + sideOffset,\n\t\t\t\tname: 'arrow_ne',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- South\n\n\t\t\tsouthArrowNorthWest: targetRect => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - sideOffset,\n\t\t\t\tname: 'arrow_nw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthArrowNorthMiddleWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - ( balloonRect.width * 0.25 ) - sideOffset,\n\t\t\t\tname: 'arrow_nmw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n\t\t\t\tname: 'arrow_n',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthArrowNorthMiddleEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - ( balloonRect.width * 0.75 ) + sideOffset,\n\t\t\t\tname: 'arrow_nme',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width + sideOffset,\n\t\t\t\tname: 'arrow_ne',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- South east\n\n\t\t\tsouthEastArrowNorthWest: targetRect => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.right - sideOffset,\n\t\t\t\tname: 'arrow_nw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthEastArrowNorthMiddleWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.right - ( balloonRect.width * .25 ) - sideOffset,\n\t\t\t\tname: 'arrow_nmw',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthEastArrowNorth: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.right - balloonRect.width / 2,\n\t\t\t\tname: 'arrow_n',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthEastArrowNorthMiddleEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.right - ( balloonRect.width * .75 ) + sideOffset,\n\t\t\t\tname: 'arrow_nme',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\tsouthEastArrowNorthEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: getSouthTop( targetRect ),\n\t\t\t\tleft: targetRect.right - balloonRect.width + sideOffset,\n\t\t\t\tname: 'arrow_ne',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- West\n\n\t\t\twestArrowEast: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: targetRect.top + targetRect.height / 2 - balloonRect.height / 2,\n\t\t\t\tleft: targetRect.left - balloonRect.width - heightOffset,\n\t\t\t\tname: 'arrow_e',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- East\n\n\t\t\teastArrowWest: ( targetRect, balloonRect ) => ( {\n\t\t\t\ttop: targetRect.top + targetRect.height / 2 - balloonRect.height / 2,\n\t\t\t\tleft: targetRect.right + heightOffset,\n\t\t\t\tname: 'arrow_w',\n\t\t\t\t...( config && { config } )\n\t\t\t} ),\n\n\t\t\t// ------- Sticky\n\n\t\t\tviewportStickyNorth: ( targetRect, balloonRect, viewportRect, limiterRect ) => {\n\t\t\t\tconst boundaryRect = limiterRect || viewportRect;\n\n\t\t\t\tif ( !targetRect.getIntersection( boundaryRect ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// Engage when the target top and bottom edges are close or off the boundary.\n\t\t\t\t// By close, it means there's not enough space for the balloon arrow (offset).\n\t\t\t\tif ( boundaryRect.height - targetRect.height > stickyVerticalOffset ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttop: boundaryRect.top + stickyVerticalOffset,\n\t\t\t\t\tleft: targetRect.left + targetRect.width / 2 - balloonRect.width / 2,\n\t\t\t\t\tname: 'arrowless',\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\twithArrow: false,\n\t\t\t\t\t\t...config\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t\t/**\n\t\t * Returns the top coordinate for positions starting with `north*`.\n\t\t *\n\t\t * @param targetRect A rect of the target.\n\t\t * @param balloonRect A rect of the balloon.\n\t\t */\n\t\tfunction getNorthTop( targetRect: Rect, balloonRect: Rect ) {\n\t\t\treturn targetRect.top - balloonRect.height - heightOffset;\n\t\t}\n\n\t\t/**\n\t\t * Returns the top coordinate for positions starting with `south*`.\n\t\t *\n\t\t * @param targetRect A rect of the target.\n\t\t */\n\t\tfunction getSouthTop( targetRect: Rect ) {\n\t\t\treturn targetRect.bottom + heightOffset;\n\t\t}\n\t}\n\n\t/**\n\t * A side offset of the arrow tip from the edge of the balloon. Controlled by CSS.\n\t *\n\t * ```\n\t *\t\t ┌───────────────────────┐\n\t *\t\t │                       │\n\t *\t\t │         Balloon       │\n\t *\t\t │         Content       │\n\t *\t\t │                       │\n\t *\t\t └──+    +───────────────┘\n\t *\t\t |   \\  /\n\t *\t\t |    \\/\n\t *\t\t>┼─────┼< ─────────────────────── side offset\n\t *\n\t * ```\n\t *\n\t * @default 25\n\t */\n\tpublic static arrowSideOffset = 25;\n\n\t/**\n\t * A height offset of the arrow from the edge of the balloon. Controlled by CSS.\n\t *\n\t * ```\n\t *\t\t ┌───────────────────────┐\n\t *\t\t │                       │\n\t *\t\t │         Balloon       │\n\t *\t\t │         Content       │      ╱-- arrow height offset\n\t *\t\t │                       │      V\n\t *\t\t └──+    +───────────────┘ --- ─┼───────\n\t *\t\t     \\  /                       │\n\t *\t\t      \\/                        │\n\t *\t\t────────────────────────────────┼───────\n\t *\t\t                                ^\n\t *\n\t *\n\t *\t\t>┼────┼<  arrow height offset\n\t *\t\t │    │\n\t *\t\t │    ┌────────────────────────┐\n\t *\t\t │    │                        │\n\t *\t\t │   ╱                         │\n\t *\t\t │ ╱            Balloon        │\n\t *\t\t │ ╲            Content        │\n\t *\t\t │   ╲                         │\n\t *\t\t │    │                        │\n\t *\t\t │    └────────────────────────┘\n\t * ```\n\t *\n\t * @default 10\n\t*/\n\tpublic static arrowHeightOffset = 10;\n\n\t/**\n\t * A vertical offset of the balloon panel from the edge of the viewport if sticky.\n\t * It helps in accessing toolbar buttons underneath the balloon panel.\n\t *\n\t * ```\n\t *\t\t  ┌───────────────────────────────────────────────────┐\n\t *\t\t  │                      Target                       │\n\t *\t\t  │                                                   │\n\t *\t\t  │                            /── vertical offset    │\n\t *\t\t┌─────────────────────────────V─────────────────────────┐\n\t *\t\t│ Toolbar            ┌─────────────┐                    │\n\t *\t\t├────────────────────│   Balloon   │────────────────────┤\n\t *\t\t│ │                  └─────────────┘                  │ │\n\t *\t\t│ │                                                   │ │\n\t *\t\t│ │                                                   │ │\n\t *\t\t│ │                                                   │ │\n\t *\t\t│ └───────────────────────────────────────────────────┘ │\n\t *\t\t│                        Viewport                       │\n\t *\t\t└───────────────────────────────────────────────────────┘\n\t * ```\n\t *\n\t * @default 20\n\t */\n\tpublic static stickyVerticalOffset = 20;\n\n\t/**\n\t * Function used to calculate the optimal position for the balloon.\n\t */\n\tprivate static _getOptimalPosition = getOptimalPosition;\n\n\t/**\n\t * A default set of positioning functions used by the balloon panel view\n\t * when attaching using the {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo} method.\n\t *\n\t * The available positioning functions are as follows:\n\t *\n\t * **North west**\n\t *\n\t * * `northWestArrowSouthWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t V\n\t *\t\t [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouthMiddleWest`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t    V\n\t *\t\t    [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouth`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t         V\n\t *\t\t         [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouthMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t             V\n\t *\t\t             [ Target ]\n\t * ```\n\t *\n\t * * `northWestArrowSouthEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t                 V\n\t *\t\t                 [ Target ]\n\t * ```\n\t *\n\t * **North**\n\t *\n\t * * `northArrowSouthWest`\n\t *\n\t * ```\n\t *\t\t    +-----------------+\n\t *\t\t    |     Balloon     |\n\t *\t\t    +-----------------+\n\t *\t\t     V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northArrowSouthMiddleWest`\n\t *\n\t * ```\n\t *\t\t +-----------------+\n\t *\t\t |     Balloon     |\n\t *\t\t +-----------------+\n\t *\t\t     V\n\t *\t\t[ Target ]\n\t * ```\n\t * * `northArrowSouth`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t         V\n\t *\t\t    [ Target ]\n\t * ```\n\t *\n\t * * `northArrowSouthMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t             V\n\t *\t\t        [ Target ]\n\t * ```\n\t *\n\t * * `northArrowSouthEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t                V\n\t *\t\t           [ Target ]\n\t * ```\n\t *\n\t * **North east**\n\t *\n\t * * `northEastArrowSouthWest`\n\t *\n\t * ```\n\t *\t\t        +-----------------+\n\t *\t\t        |     Balloon     |\n\t *\t\t        +-----------------+\n\t *\t\t         V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouthMiddleWest`\n\t *\n\t * ```\n\t *\t\t     +-----------------+\n\t *\t\t     |     Balloon     |\n\t *\t\t     +-----------------+\n\t *\t\t         V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouth`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t         V\n\t *\t\t[ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouthMiddleEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t             V\n\t *\t\t    [ Target ]\n\t * ```\n\t *\n\t * * `northEastArrowSouthEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t *\t\t                 V\n\t *\t\t        [ Target ]\n\t * ```\n\t *\n\t * **South**\n\t *\n\t * * `southArrowNorthWest`\n\t *\n\t * ```\n\t *\t\t[ Target ]\n\t *\t\t     ^\n\t *\t\t    +-----------------+\n\t *\t\t    |     Balloon     |\n\t *\t\t    +-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorthMiddleWest`\n\t *\n\t * ```\n\t *\t\t   [ Target ]\n\t *\t\t        ^\n\t *\t\t    +-----------------+\n\t *\t\t    |     Balloon     |\n\t *\t\t    +-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorth`\n\t *\n\t * ```\n\t *\t\t    [ Target ]\n\t *\t\t         ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorthMiddleEast`\n\t *\n\t * ```\n\t *\t\t            [ Target ]\n\t *\t\t                 ^\n\t *\t\t   +-----------------+\n\t *\t\t   |     Balloon     |\n\t *\t\t   +-----------------+\n\t * ```\n\t *\n\t * * `southArrowNorthEast`\n\t *\n\t * ```\n\t *\t\t            [ Target ]\n\t *\t\t                 ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **South west**\n\t *\n\t * * `southWestArrowNorthWest`\n\t *\n\t *\n\t * ```\n\t *\t\t [ Target ]\n\t *\t\t ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorthMiddleWest`\n\t *\n\t * ```\n\t *\t\t     [ Target ]\n\t *\t\t     ^\n\t *\t\t +-----------------+\n\t *\t\t |     Balloon     |\n\t *\t\t +-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorth`\n\t *\n\t * ```\n\t *\t\t         [ Target ]\n\t *\t\t         ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorthMiddleEast`\n\t *\n\t * ```\n\t *\t\t              [ Target ]\n\t *\t\t              ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southWestArrowNorthEast`\n\t *\n\t * ```\n\t *\t\t                 [ Target ]\n\t *\t\t                 ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **South east**\n\t *\n\t * * `southEastArrowNorthWest`\n\t *\n\t * ```\n\t *\t\t[ Target ]\n\t *\t\t         ^\n\t *\t\t        +-----------------+\n\t *\t\t        |     Balloon     |\n\t *\t\t        +-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorthMiddleWest`\n\t *\n\t * ```\n\t *\t\t   [ Target ]\n\t *\t\t            ^\n\t *\t\t        +-----------------+\n\t *\t\t        |     Balloon     |\n\t *\t\t        +-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorth`\n\t *\n\t * ```\n\t *\t\t[ Target ]\n\t *\t\t         ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorthMiddleEast`\n\t *\n\t * ```\n\t *\t\t     [ Target ]\n\t *\t\t              ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * * `southEastArrowNorthEast`\n\t *\n\t * ```\n\t *\t\t        [ Target ]\n\t *\t\t                 ^\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **West**\n\t *\n\t * * `westArrowEast`\n\t *\n\t * ```\n\t *\t\t+-----------------+\n\t *\t\t|     Balloon     |>[ Target ]\n\t *\t\t+-----------------+\n\t * ```\n\t *\n\t * **East**\n\t *\n\t * * `eastArrowWest`\n\t *\n\t * ```\n\t *\t\t           +-----------------+\n\t *\t\t[ Target ]<|     Balloon     |\n\t *\t\t           +-----------------+\n\t * ```\n\t *\n\t * **Sticky**\n\t *\n\t * * `viewportStickyNorth`\n\t *\n\t * ```\n\t *\t\t    +---------------------------+\n\t *\t\t    |        [ Target ]         |\n\t *\t\t    |                           |\n\t *\t\t+-----------------------------------+\n\t *\t\t|   |    +-----------------+    |   |\n\t *\t\t|   |    |     Balloon     |    |   |\n\t *\t\t|   |    +-----------------+    |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   |                           |   |\n\t *\t\t|   +---------------------------+   |\n\t *\t\t|             Viewport              |\n\t *\t\t+-----------------------------------+\n\t * ```\n\t *\n\t * See {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView#attachTo}.\n\t *\n\t * Positioning functions must be compatible with {@link module:utils/dom/position~DomPoint}.\n\t *\n\t * Default positioning functions with customized offsets can be generated using\n\t * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView.generatePositions}.\n\t *\n\t * The name that the position function returns will be reflected in the balloon panel's class that\n\t * controls the placement of the \"arrow\". See {@link #position} to learn more.\n\t */\n\tpublic static defaultPositions = /* #__PURE__ */ BalloonPanelView.generatePositions();\n}\n\n/**\n * Returns the DOM element for given object or null, if there is none,\n * e.g. when the passed object is a Rect instance or so.\n */\nfunction getDomElement( object: any ): HTMLElement | null {\n\tif ( isElement( object ) ) {\n\t\treturn object;\n\t}\n\n\tif ( isRange( object ) ) {\n\t\treturn object.commonAncestorContainer as any;\n\t}\n\n\tif ( typeof object == 'function' ) {\n\t\treturn getDomElement( object() );\n\t}\n\n\treturn null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenunestedmenupanelview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport type { FocusableView } from '../../focuscycler.js';\n\nimport BalloonPanelView from '../../panel/balloon/balloonpanelview.js';\n\nimport '../../../theme/components/dropdown/menu/dropdownmenupanel.css';\n\n/**\n * Represents the view for the dropdown menu panel.\n */\nexport default class DropdownMenuNestedMenuPanelView extends BalloonPanelView implements FocusableView {\n\t/**\n\t * Creates an instance of the menu panel view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( {\n\t\t\tisVisible: false,\n\t\t\tposition: 'se',\n\t\t\tclass: null,\n\t\t\ttop: 0,\n\t\t\tleft: 0\n\t\t} );\n\n\t\tthis.extendTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-dropdown-menu__nested-menu__panel'\n\t\t\t\t],\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\ton: {\n\t\t\t\t// Drag and drop in the panel should not break the selection in the editor.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/228\n\t\t\t\tselectstart: bind.to( evt => {\n\t\t\t\t\tif ( ( evt.target as HTMLElement ).tagName.toLocaleLowerCase() === 'input' ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the first child of the panel (default) or the last one if the `direction` is `-1`.\n\t *\n\t * @param direction The direction to focus. Default is `1`.\n\t */\n\tpublic focus( direction: -1 | 1 = 1 ): void {\n\t\tconst { content } = this;\n\n\t\tif ( content.length ) {\n\t\t\tif ( direction === 1 ) {\n\t\t\t\t( content.first as FocusableView ).focus();\n\t\t\t} else {\n\t\t\t\t( content.last as FocusableView ).focus();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The names of the positions of the {@link module:ui/dropdown/menu/dropdownmenunestedmenupanelview~DropdownMenuNestedMenuPanelView}.\n *\n * They are reflected as CSS class suffixes on the panel view element.\n */\nexport type DropdownMenuNestedMenuPanelPosition = 'es' | 'ws' | 'en' | 'wn' | 'w' | 'e';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenunestedmenuview\n */\n\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\tglobal,\n\ttype PositioningFunction,\n\ttype ObservableChangeEvent,\n\ttype Locale\n} from '@ckeditor/ckeditor5-utils';\n\nimport type { FocusableView } from '../../focuscycler.js';\nimport type BodyCollection from '../../editorui/bodycollection.js';\n\nimport DropdownMenuButtonView from './dropdownmenubuttonview.js';\nimport DropdownMenuListView from './dropdownmenulistview.js';\nimport { DropdownMenuPanelPositioningFunctions } from './utils.js';\nimport { DropdownMenuBehaviors } from './dropdownmenubehaviors.js';\n\nimport View from '../../view.js';\nimport DropdownMenuNestedMenuPanelView, { type DropdownMenuNestedMenuPanelPosition } from './dropdownmenunestedmenupanelview.js';\n\nimport '../../../theme/components/dropdown/menu/dropdownmenu.css';\n\n/**\n * Represents a nested menu view.\n */\nexport default class DropdownMenuNestedMenuView extends View implements FocusableView {\n\t/**\n\t * An array of delegated events for the dropdown menu definition controller.\n\t * These events are delegated to the dropdown menu element.\n\t */\n\t// Due to some spaghetti code we need to delegate `change:isOpen`.\n\tpublic static readonly DELEGATED_EVENTS = [\n\t\t'mouseenter', 'execute', 'change:isOpen'\n\t] as const;\n\n\tpublic readonly id: string;\n\n\t/**\n\t * Button of the menu view.\n\t */\n\tpublic readonly buttonView: DropdownMenuButtonView;\n\n\t/**\n\t * Panel of the menu. It hosts children of the menu.\n\t */\n\tpublic readonly panelView: DropdownMenuNestedMenuPanelView;\n\n\t/**\n\t * List of nested menu entries.\n\t */\n\tpublic readonly listView: DropdownMenuListView;\n\n\t/**\n\t * Tracks information about the DOM focus in the menu.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the menu.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Controls whether the menu is open, i.e. shows or hides the {@link #panelView panel}.\n\t *\n\t * @observable\n\t */\n\tdeclare public isOpen: boolean;\n\n\t/**\n\t * Controls whether the menu is enabled, i.e. its {@link #buttonView} can be clicked.\n\t *\n\t * @observable\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * (Optional) The additional CSS class set on the menu {@link #element}.\n\t *\n\t * @observable\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * The name of the position of the {@link #panelView}, relative to the menu.\n\t *\n\t * **Note**: The value is updated each time the panel gets {@link #isOpen open}.\n\t *\n\t * @observable\n\t * @default 'w'\n\t */\n\tdeclare public panelPosition: DropdownMenuNestedMenuPanelPosition;\n\n\t/**\n\t * The parent menu view of the menu. It is `null` for top-level menus.\n\t *\n\t * @observable\n\t * @default null\n\t */\n\tdeclare public readonly parentMenuView: DropdownMenuNestedMenuView | null;\n\n\tprivate _bodyCollection: BodyCollection;\n\n\t/**\n\t * Creates a new instance of the DropdownMenuView class.\n\t *\n\t * @param locale\n\t * @param bodyCollection\n\t * @param id\n\t * @param label The label for the dropdown menu button.\n\t * @param parentMenuView The parent dropdown menu view, if any.\n\t */\n\tconstructor(\n\t\tlocale: Locale, bodyCollection: BodyCollection, id: string, label: string, parentMenuView: DropdownMenuNestedMenuView | null\n\t) {\n\t\tsuper( locale );\n\n\t\tthis._bodyCollection = bodyCollection;\n\t\tthis.id = id;\n\n\t\tthis.set( {\n\t\t\tisOpen: false,\n\t\t\tisEnabled: true,\n\t\t\tpanelPosition: 'w',\n\t\t\tclass: undefined,\n\t\t\tparentMenuView: null\n\t\t} );\n\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\tthis.buttonView = new DropdownMenuButtonView( locale );\n\t\tthis.buttonView.delegate( 'mouseenter' ).to( this );\n\t\tthis.buttonView.bind( 'isOn', 'isEnabled' ).to( this, 'isOpen', 'isEnabled' );\n\t\tthis.buttonView.label = label;\n\n\t\tthis.panelView = new DropdownMenuNestedMenuPanelView( locale );\n\t\tthis.panelView.isVisible = true;\n\n\t\tthis.listView = new DropdownMenuListView( locale );\n\t\tthis.listView.bind( 'ariaLabel' ).to( this.buttonView, 'label' );\n\n\t\tthis.panelView.content.add( this.listView );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-dropdown-menu-list__nested-menu',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isEnabled', 'ck-disabled', value => !value )\n\t\t\t\t],\n\t\t\t\trole: 'presentation'\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.buttonView\n\t\t\t]\n\t\t} );\n\n\t\tthis.parentMenuView = parentMenuView;\n\n\t\tif ( this.parentMenuView ) {\n\t\t\tthis._handleParentMenuView();\n\t\t}\n\n\t\tthis._attachBehaviors();\n\t}\n\n\t/**\n\t * An array of positioning functions used to determine the position of the dropdown menu panel.\n\t * The order of the functions in the array determines the priority of the positions to be tried.\n\t * The first function that returns a valid position will be used.\n\t *\n\t * @returns {Array<PositioningFunction>} An array of positioning functions.\n\t * @internal\n\t */\n\tpublic get _panelPositions(): Array<PositioningFunction> {\n\t\tconst { westSouth, eastSouth, westNorth, eastNorth } = DropdownMenuPanelPositioningFunctions;\n\n\t\tif ( this.locale!.uiLanguageDirection === 'ltr' ) {\n\t\t\treturn [ eastSouth, eastNorth, westSouth, westNorth ];\n\t\t} else {\n\t\t\treturn [ westSouth, westNorth, eastSouth, eastNorth ];\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.panelView.render();\n\n\t\tthis.focusTracker.add( this.buttonView.element! );\n\t\tthis.focusTracker.add( this.panelView.element! );\n\t\tthis.focusTracker.add( this.listView );\n\n\t\t// Listen for keystrokes coming from within #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\tthis._mountPanelOnOpen();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis._removePanelFromBody();\n\t\tthis.panelView.destroy();\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focus(): void {\n\t\tthis.buttonView.focus();\n\t}\n\n\tprivate _handleParentMenuView(): void {\n\t\t// Propagate events from this component to parent-menu.\n\t\tthis.delegate( ...DropdownMenuNestedMenuView.DELEGATED_EVENTS ).to( this.parentMenuView! );\n\n\t\t// Close this menu if its parent closes.\n\t\tDropdownMenuBehaviors.closeOnParentClose( this, this.parentMenuView! );\n\t}\n\n\t/**\n\t * Attach all keyboard behaviors for the menu view.\n\t */\n\tprivate _attachBehaviors(): void {\n\t\tDropdownMenuBehaviors.openOnButtonClick( this );\n\t\tDropdownMenuBehaviors.openAndFocusOnEnterKeyPress( this );\n\t\tDropdownMenuBehaviors.openOnArrowRightKey( this );\n\t\tDropdownMenuBehaviors.closeOnEscKey( this );\n\t\tDropdownMenuBehaviors.closeOnArrowLeftKey( this );\n\t}\n\n\t/**\n\t * Mounts the portal view in the body when the menu is open and removes it when the menu is closed.\n\t * Binds keystrokes to the portal view when the menu is open.\n\t */\n\tprivate _mountPanelOnOpen(): void {\n\t\tconst { panelView } = this;\n\n\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( evt, name, isOpen ) => {\n\t\t\t// Ensure that the event was triggered by this instance.\n\t\t\t// TODO: Remove checking `evt.source` if `change:isOpen` is no longer delegated.\n\t\t\tif ( evt.source !== this ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Removes the panel view from the body when the menu is closed.\n\t\t\tif ( !isOpen && this._bodyCollection.has( panelView ) ) {\n\t\t\t\tthis._removePanelFromBody();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Adds the panel view to the body when the menu is open.\n\t\t\tif ( isOpen && !this._bodyCollection.has( panelView ) ) {\n\t\t\t\tthis._addPanelToBody();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes the panel view from the editor's body and removes it from the focus tracker.\n\t */\n\tprivate _removePanelFromBody(): void {\n\t\tconst { panelView, keystrokes } = this;\n\n\t\tif ( this._bodyCollection.has( panelView ) ) {\n\t\t\tthis._bodyCollection.remove( panelView );\n\n\t\t\tkeystrokes.stopListening( panelView.element! );\n\t\t}\n\t}\n\n\t/**\n\t * Adds the panel view to the editor's body and sets up event listeners.\n\t */\n\tprivate _addPanelToBody() {\n\t\tconst { panelView, buttonView, keystrokes } = this;\n\n\t\tif ( !this._bodyCollection.has( panelView ) ) {\n\t\t\tthis._bodyCollection.add( panelView );\n\n\t\t\tkeystrokes.listenTo( panelView.element! );\n\t\t\tpanelView.pin( {\n\t\t\t\tpositions: this._panelPositions,\n\t\t\t\tlimiter: global.document.body,\n\t\t\t\telement: panelView.element!,\n\t\t\t\ttarget: buttonView.element!,\n\t\t\t\tfitInViewport: true\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/menu/dropdownmenurootlistview\n */\n\nimport DropdownMenuListItemButtonView from './dropdownmenulistitembuttonview.js';\nimport DropdownMenuNestedMenuView from './dropdownmenunestedmenuview.js';\nimport DropdownMenuListView from './dropdownmenulistview.js';\nimport DropdownMenuListItemView from './dropdownmenulistitemview.js';\nimport { DropdownRootMenuBehaviors } from './dropdownmenubehaviors.js';\n\nimport type BodyCollection from '../../editorui/bodycollection.js';\nimport type { DropdownMenuDefinition } from './utils.js';\n\nimport type { Locale, BaseEvent } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Creates and manages a multi-level menu UI structure, suitable to be used inside dropdown components.\n *\n * This class creates a menu structure based on {@link module:ui/dropdown/menu/utils~DropdownMenuDefinition declarative definition}\n * passed in the constructor.\n *\n * Below is an example of a simple definition, that describes a menu with two sub-menus (Menu 1, Menu 2) and four buttons in total (Item A,\n * Item B, Item C, Item D):\n *\n * ```js\n * [\n * \t{\n * \t\tid: 'menu_1',\n * \t\tmenu: 'Menu 1',\n * \t\tchildren: [\n * \t\t\t{ id: 'menu_1_a', label: 'Item A' },\n * \t\t\t{ id: 'menu_1_b', label: 'Item B' }\n * \t\t]\n * \t},\n * \t{\n * \t\tid: 'menu_2',\n * \t\tmenu: 'Menu 2',\n * \t\tchildren: [\n * \t\t\t{ id: 'menu_2_c', label: 'Item C' },\n * \t\t]\n * \t},\n * \t{ id: 'item_d', label: 'Item D' }\n * ]\n * ```\n *\n * The menu is build using multiple view classes. The most important are:\n *\n * * {@link module:ui/dropdown/menu/dropdownmenunestedmenuview~DropdownMenuNestedMenuView `DropdownMenuNestedMenuView`} - \"menu\" - provides\n * a panel with a nested menu, and a button which opens the panel,\n * * {@link module:ui/dropdown/menu/dropdownmenulistitembuttonview~DropdownMenuListItemButtonView `DropdownMenuListItemButtonView`} -\n * \"button\" or \"leaf button\" (as opposed to buttons provided by `DropdownMenuNestedMenuView`) - should trigger some action when pressed.\n *\n * Instances of these two classes are created based on the data provided in definitions. They are assigned proper IDs and labels.\n * Other view classes build a proper DOM structure around menus and buttons.\n *\n * The `DropdownMenuNestedMenuView` instances provides panels, which may include further menus or buttons. These panels are added to\n * a `BodyCollection` view, which means they are appended outside the DOM editor and UI structure.\n *\n * When \"leaf button\" is pressed, it fires `execute` event which is delegated to `DropdownMenuRootListView` as `menu:execute` event. You\n * can listen to this event to perform an action:\n *\n * ```js\n * rootListView.on( 'menu:execute', evt => {\n * \tconsole.log( evt.source.id ); // E.g. will print 'menu_1_a' when 'Item A' is pressed.\n * } );\n * ```\n *\n * All menus and \"leaf\" buttons created from the definition can be easily accessed through {@link ~DropdownMenuRootListView#menus `menus`}\n * and {@link ~DropdownMenuRootListView#buttons `buttons`} properties.\n *\n * For performance reasons, the whole menu structure is created only when `DropdownMenuRootListView` is rendered for the first time.\n *\n * It is recommended to use this class together with {@link module:ui/dropdown/utils~addMenuToDropdown `addMenuToDropdown()` helper}.\n */\nexport default class DropdownMenuRootListView extends DropdownMenuListView {\n\t/**\n\t * The CSS class to be applied to nested menu panels in this dropdown menu.\n\t *\n\t * It is necessary, as the panels are created in body collection, outside editor and UI structure.\n\t */\n\tdeclare public menuPanelClass: string | undefined;\n\n\t/**\n\t * The definitions object used to create the whole menu structure.\n\t */\n\tprivate readonly _definition: DropdownMenuDefinition;\n\n\t/**\n\t * Cached array of all menus in the dropdown menu (including nested menus).\n\t */\n\tprivate _cachedMenus: Array<DropdownMenuNestedMenuView> = [];\n\n\t/**\n\t * Cached array of all buttons in the dropdown menu (including buttons in nested menus).\n\t */\n\tprivate _cachedButtons: Array<DropdownMenuListItemButtonView> = [];\n\n\t/**\n\t * Editor body collection into which nested menus panels will be appended.\n\t */\n\tprivate _bodyCollection: BodyCollection;\n\n\t/**\n\t * Creates an instance of the DropdownMenuRootListView class.\n\t *\n\t * @param locale\n\t * @param bodyCollection\n\t * @param definition The definition object used to create the menu structure.\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\tbodyCollection: BodyCollection,\n\t\tdefinition: DropdownMenuDefinition\n\t) {\n\t\tsuper( locale );\n\n\t\tthis._bodyCollection = bodyCollection;\n\t\tthis._definition = definition;\n\n\t\tthis.set( 'menuPanelClass', undefined );\n\t}\n\n\t/**\n\t * Returns the array of all menus in the dropdown menu (including nested menus).\n\t */\n\tpublic get menus(): Array<DropdownMenuNestedMenuView> {\n\t\treturn Array.from( this._cachedMenus.values() );\n\t}\n\n\t/**\n\t * Returns the array of all buttons in the dropdown menu (including buttons in nested menus).\n\t *\n\t * Note, that this includes only \"leaf\" buttons, as specified in the definition passed in constructor. Buttons created as a part of\n\t * the nested menus, that open nested menus when hovered or pressed, are not included.\n\t */\n\tpublic get buttons(): Array<DropdownMenuListItemButtonView> {\n\t\treturn Array.from( this._cachedButtons.values() );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tthis._createStructure( this._definition, null );\n\n\t\tsuper.render();\n\n\t\tDropdownRootMenuBehaviors.toggleMenusAndFocusItemsOnHover( this );\n\t\tDropdownRootMenuBehaviors.closeMenuWhenAnotherOnTheSameLevelOpens( this );\n\t}\n\n\t/**\n\t * Closes all nested menus.\n\t */\n\tpublic closeMenus(): void {\n\t\tthis.menus.forEach( menu => {\n\t\t\tmenu.isOpen = false;\n\t\t} );\n\t}\n\n\t/**\n\t * Recursively creates the whole view tree structure for the dropdown menu, according to the passed `definitions`.\n\t *\n\t * @private\n\t */\n\tprivate _createStructure( definitions: DropdownMenuDefinition, parentMenuView: DropdownMenuNestedMenuView | null ): void {\n\t\tconst items: Array<DropdownMenuListItemView> = [];\n\n\t\tfor ( const def of definitions ) {\n\t\t\tlet createdView: DropdownMenuNestedMenuView | DropdownMenuListItemButtonView;\n\n\t\t\tif ( 'menu' in def ) {\n\t\t\t\tcreatedView = new DropdownMenuNestedMenuView( this.locale!, this._bodyCollection, def.id, def.menu, parentMenuView );\n\t\t\t\tcreatedView.panelView.bind( 'class' ).to( this, 'menuPanelClass' );\n\n\t\t\t\tif ( !parentMenuView ) {\n\t\t\t\t\tcreatedView.delegate( ...DropdownMenuNestedMenuView.DELEGATED_EVENTS ).to( this, ( name: string ) => `menu:${ name }` );\n\t\t\t\t}\n\n\t\t\t\tthis._cachedMenus.push( createdView );\n\t\t\t\tthis._createStructure( def.children, createdView );\n\t\t\t} else {\n\t\t\t\tcreatedView = new DropdownMenuListItemButtonView( this.locale!, def.id, def.label );\n\n\t\t\t\tif ( !parentMenuView ) {\n\t\t\t\t\tcreatedView.delegate( 'execute' ).to( this, 'menu:execute' );\n\t\t\t\t}\n\n\t\t\t\tthis._cachedButtons.push( createdView );\n\t\t\t}\n\n\t\t\tconst listItemView = new DropdownMenuListItemView( this.locale!, parentMenuView, createdView );\n\n\t\t\tif ( !parentMenuView ) {\n\t\t\t\tlistItemView.delegate( 'mouseenter' ).to( this, 'menu:mouseenter' );\n\t\t\t}\n\n\t\t\titems.push( listItemView );\n\t\t}\n\n\t\tconst targetListView = parentMenuView ? parentMenuView.listView : this;\n\n\t\ttargetListView.items.addMany( items );\n\t}\n}\n\n/**\n * Fired when one of the menu buttons is executed (through mouse click or keyboard).\n *\n * This event is a delegated `execute` event fired by the pressed button. The `event.source` is the button which was executed.\n *\n * @eventName ~DropdownMenuRootListView#menu:execute\n */\nexport interface DropdownMenuRootListViewExecuteEvent extends BaseEvent {\n\tname: 'menu:execute';\n\targs: [];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/toolbar/toolbarseparatorview\n */\n\nimport View from '../view.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The toolbar separator view class.\n */\nexport default class ToolbarSeparatorView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-toolbar__separator'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/toolbar/toolbarlinebreakview\n */\n\nimport View from '../view.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The toolbar line break view class.\n */\nexport default class ToolbarLineBreakView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-toolbar__line-break'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/bindings/preventdefault\n */\n\nimport type { ListenerBinding } from '../template.js';\nimport type View from '../view.js';\n\n/**\n * A helper which executes a native `Event.preventDefault()` if the target of an event equals the\n * {@link module:ui/view~View#element element of the view}. It shortens the definition of a\n * {@link module:ui/view~View#template template}.\n *\n * ```ts\n * // In a class extending View.\n * import preventDefault from '@ckeditor/ckeditor5-ui/src/bindings/preventdefault';\n *\n * // ...\n *\n * this.setTemplate( {\n * \ttag: 'div',\n *\n * \ton: {\n * \t\t// Prevent the default mousedown action on this view.\n * \t\tmousedown: preventDefault( this )\n * \t}\n * } );\n * ```\n *\n * @param view View instance that defines the template.\n */\nexport default function preventDefault( view: View ): ListenerBinding {\n\treturn view.bindTemplate.to( evt => {\n\t\tif ( evt.target === view.element ) {\n\t\t\tevt.preventDefault();\n\t\t}\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type { ToolbarConfig, ToolbarConfigItem } from '@ckeditor/ckeditor5-core';\n\n/**\n * @module ui/toolbar/normalizetoolbarconfig\n */\n\n/**\n * Normalizes the toolbar configuration (`config.toolbar`), which:\n *\n * * may be defined as an `Array`:\n *\n * ```\n * toolbar: [ 'heading', 'bold', 'italic', 'link', ... ]\n * ```\n *\n * * or an `Object`:\n *\n * ```\n * toolbar: {\n * \titems: [ 'heading', 'bold', 'italic', 'link', ... ],\n * \tremoveItems: [ 'bold' ],\n * \t...\n * }\n * ```\n *\n * * or may not be defined at all (`undefined`)\n *\n * and returns it in the object form.\n *\n * @param config The value of `config.toolbar`.\n * @returns A normalized toolbar config object.\n */\nexport default function normalizeToolbarConfig(\n\tconfig: ToolbarConfig | undefined\n): {\n\titems: Array<ToolbarConfigItem>;\n\tremoveItems: Array<string>;\n\tshouldNotGroupWhenFull?: boolean;\n\ticon?: string;\n} {\n\tif ( Array.isArray( config ) ) {\n\t\treturn {\n\t\t\titems: config,\n\t\t\tremoveItems: []\n\t\t};\n\t}\n\n\tconst predefinedConfigOptions = {\n\t\titems: [],\n\t\tremoveItems: []\n\t};\n\n\tif ( !config ) {\n\t\treturn predefinedConfigOptions;\n\t}\n\n\treturn {\n\t\t...predefinedConfigOptions,\n\t\t...config\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/toolbar/toolbarview\n */\n\nimport View from '../view.js';\nimport FocusCycler, { isFocusable, type FocusableView } from '../focuscycler.js';\nimport ToolbarSeparatorView from './toolbarseparatorview.js';\nimport ToolbarLineBreakView from './toolbarlinebreakview.js';\nimport preventDefault from '../bindings/preventdefault.js';\nimport { createDropdown, addToolbarToDropdown } from '../dropdown/utils.js';\nimport normalizeToolbarConfig from './normalizetoolbarconfig.js';\n\nimport type ComponentFactory from '../componentfactory.js';\nimport type ViewCollection from '../viewcollection.js';\nimport type DropdownView from '../dropdown/dropdownview.js';\nimport type DropdownPanelFocusable from '../dropdown/dropdownpanelfocusable.js';\n\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\tRect,\n\tResizeObserver,\n\tglobal,\n\tisVisible,\n\tlogWarning,\n\ttype CollectionAddEvent,\n\ttype CollectionChangeEvent,\n\ttype CollectionRemoveEvent,\n\ttype Locale,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport {\n\ticons,\n\ttype ToolbarConfig,\n\ttype ToolbarConfigItem\n} from '@ckeditor/ckeditor5-core';\n\nimport { isObject } from 'lodash-es';\n\nimport '../../theme/components/toolbar/toolbar.css';\n\nexport const NESTED_TOOLBAR_ICONS: Record<string, string | undefined> = /* #__PURE__ */ ( () => ( {\n\talignLeft: icons.alignLeft,\n\tbold: icons.bold,\n\timportExport: icons.importExport,\n\tparagraph: icons.paragraph,\n\tplus: icons.plus,\n\ttext: icons.text,\n\tthreeVerticalDots: icons.threeVerticalDots,\n\tpilcrow: icons.pilcrow,\n\tdragIndicator: icons.dragIndicator\n} ) )();\n\n/**\n * The toolbar view class.\n */\nexport default class ToolbarView extends View implements DropdownPanelFocusable {\n\t/**\n\t * A reference to the options object passed to the constructor.\n\t */\n\tpublic readonly options: ToolbarOptions;\n\n\t/**\n\t * A collection of toolbar items (buttons, dropdowns, etc.).\n\t */\n\tpublic readonly items: ViewCollection;\n\n\t/**\n\t * Tracks information about the DOM focus in the toolbar.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}\n\t * to handle keyboard navigation in the toolbar.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A (child) view containing {@link #items toolbar items}.\n\t */\n\tpublic readonly itemsView: ItemsView;\n\n\t/**\n\t * A top–level collection aggregating building blocks of the toolbar.\n\t *\n\t *\t┌───────────────── ToolbarView ─────────────────┐\n\t *\t| ┌──────────────── #children ────────────────┐ |\n\t *\t| |   ┌──────────── #itemsView ───────────┐   | |\n\t *\t| |   | [ item1 ] [ item2 ] ... [ itemN ] |   | |\n\t *\t| |   └──────────────────────────────────-┘   | |\n\t *\t| └───────────────────────────────────────────┘ |\n\t *\t└───────────────────────────────────────────────┘\n\t *\n\t * By default, it contains the {@link #itemsView} but it can be extended with additional\n\t * UI elements when necessary.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * A collection of {@link #items} that take part in the focus cycling\n\t * (i.e. navigation using the keyboard). Usually, it contains a subset of {@link #items} with\n\t * some optional UI elements that also belong to the toolbar and should be focusable\n\t * by the user.\n\t */\n\tpublic readonly focusables: ViewCollection<FocusableView>;\n\n\tdeclare public locale: Locale;\n\n\t/**\n\t * Label used by assistive technologies to describe this toolbar element.\n\t *\n\t * @observable\n\t * @default 'Editor toolbar'\n\t */\n\tdeclare public ariaLabel: string;\n\n\t/**\n\t * The maximum width of the toolbar element.\n\t *\n\t * **Note**: When set to a specific value (e.g. `'200px'`), the value will affect the behavior of the\n\t * {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull}\n\t * option by changing the number of {@link #items} that will be displayed in the toolbar at a time.\n\t *\n\t * @observable\n\t * @default 'auto'\n\t */\n\tdeclare public maxWidth: string;\n\n\t/**\n\t * An additional CSS class added to the {@link #element}.\n\t *\n\t * @observable\n\t * @member {String} #class\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * When set true, makes the toolbar look compact with {@link #element}.\n\t *\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isCompact: boolean;\n\n\t/**\n\t * Controls the orientation of toolbar items. Only available when\n\t * {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull dynamic items grouping}\n\t * is **disabled**.\n\t *\n\t * @observable\n\t */\n\tdeclare public isVertical: boolean;\n\n\t/**\n\t * Helps cycling over {@link #focusables focusable items} in the toolbar.\n\t */\n\tprivate readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * An instance of the active toolbar behavior that shapes its look and functionality.\n\t *\n\t * See {@link module:ui/toolbar/toolbarview~ToolbarBehavior} to learn more.\n\t */\n\tprivate readonly _behavior: ToolbarBehavior;\n\n\t/**\n\t * Creates an instance of the {@link module:ui/toolbar/toolbarview~ToolbarView} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param options Configuration options of the toolbar.\n\t */\n\tconstructor( locale: Locale, options?: ToolbarOptions ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\t\tconst t = this.t!;\n\n\t\tthis.options = options || {};\n\n\t\tthis.set( 'ariaLabel', t( 'Editor toolbar' ) );\n\t\tthis.set( 'maxWidth', 'auto' );\n\n\t\tthis.items = this.createCollection();\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis.set( 'class', undefined );\n\t\tthis.set( 'isCompact', false );\n\n\t\tthis.itemsView = new ItemsView( locale );\n\t\tthis.children = this.createCollection();\n\t\tthis.children.add( this.itemsView );\n\t\tthis.focusables = this.createCollection();\n\n\t\tconst isRtl = locale.uiLanguageDirection === 'rtl';\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate toolbar items backwards using the arrow[left,up] keys.\n\t\t\t\tfocusPrevious: [ isRtl ? 'arrowright' : 'arrowleft', 'arrowup' ],\n\n\t\t\t\t// Navigate toolbar items forwards using the arrow[right,down] keys.\n\t\t\t\tfocusNext: [ isRtl ? 'arrowleft' : 'arrowright', 'arrowdown' ]\n\t\t\t}\n\t\t} );\n\n\t\tconst classes = [\n\t\t\t'ck',\n\t\t\t'ck-toolbar',\n\t\t\tbind.to( 'class' ),\n\t\t\tbind.if( 'isCompact', 'ck-toolbar_compact' )\n\t\t];\n\n\t\tif ( this.options.shouldGroupWhenFull && this.options.isFloating ) {\n\t\t\tclasses.push( 'ck-toolbar_floating' );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: classes,\n\t\t\t\trole: 'toolbar',\n\t\t\t\t'aria-label': bind.to( 'ariaLabel' ),\n\t\t\t\tstyle: {\n\t\t\t\t\tmaxWidth: bind.to( 'maxWidth' )\n\t\t\t\t},\n\t\t\t\ttabindex: -1\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/206\n\t\t\t\tmousedown: preventDefault( this )\n\t\t\t}\n\t\t} );\n\n\t\tthis._behavior = this.options.shouldGroupWhenFull ? new DynamicGrouping( this ) : new StaticLayout( this );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.focusTracker.add( this.element! );\n\n\t\t// Children added before rendering should be known to the #focusTracker.\n\t\tfor ( const item of this.items ) {\n\t\t\tthis.focusTracker.add( item );\n\t\t}\n\n\t\tthis.items.on<CollectionAddEvent<View>>( 'add', ( evt, item ) => {\n\t\t\tthis.focusTracker.add( item );\n\t\t} );\n\n\t\tthis.items.on<CollectionRemoveEvent<View>>( 'remove', ( evt, item ) => {\n\t\t\tthis.focusTracker.remove( item );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\tthis._behavior.render( this );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis._behavior.destroy();\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Focuses the first focusable in {@link #focusables}.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the last focusable in {@link #focusables}.\n\t */\n\tpublic focusLast(): void {\n\t\tthis._focusCycler.focusLast();\n\t}\n\n\t/**\n\t * A utility that expands the plain toolbar configuration into\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.\n\t *\n\t * @param itemsOrConfig The toolbar items or the entire toolbar configuration object.\n\t * @param factory A factory producing toolbar items.\n\t * @param removeItems An array of items names to be removed from the configuration. When present, applies\n\t * to this toolbar and all nested ones as well.\n\t */\n\tpublic fillFromConfig(\n\t\titemsOrConfig: ToolbarConfig | undefined,\n\t\tfactory: ComponentFactory,\n\t\tremoveItems?: Array<string>\n\t): void {\n\t\tthis.items.addMany( this._buildItemsFromConfig( itemsOrConfig, factory, removeItems ) );\n\t}\n\n\t/**\n\t * A utility that expands the plain toolbar configuration into a list of view items using a given component factory.\n\t *\n\t * @param itemsOrConfig The toolbar items or the entire toolbar configuration object.\n\t * @param factory A factory producing toolbar items.\n\t * @param removeItems An array of items names to be removed from the configuration. When present, applies\n\t * to this toolbar and all nested ones as well.\n\t */\n\tprivate _buildItemsFromConfig(\n\t\titemsOrConfig: ToolbarConfig | undefined,\n\t\tfactory: ComponentFactory,\n\t\tremoveItems?: Array<string>\n\t): Array<View> {\n\t\tconst config = normalizeToolbarConfig( itemsOrConfig );\n\t\tconst normalizedRemoveItems = removeItems || config.removeItems;\n\t\tconst itemsToAdd = this._cleanItemsConfiguration( config.items, factory, normalizedRemoveItems )\n\t\t\t.map( item => {\n\t\t\t\tif ( isObject( item ) ) {\n\t\t\t\t\treturn this._createNestedToolbarDropdown( item, factory, normalizedRemoveItems );\n\t\t\t\t} else if ( item === '|' ) {\n\t\t\t\t\treturn new ToolbarSeparatorView();\n\t\t\t\t} else if ( item === '-' ) {\n\t\t\t\t\treturn new ToolbarLineBreakView();\n\t\t\t\t}\n\n\t\t\t\treturn factory.create( item );\n\t\t\t} )\n\t\t\t.filter( ( item ): item is View => !!item );\n\n\t\treturn itemsToAdd;\n\t}\n\n\t/**\n\t * Cleans up the {@link module:ui/toolbar/toolbarview~ToolbarView#items} of the toolbar by removing unwanted items and\n\t * duplicated (obsolete) separators or line breaks.\n\t *\n\t * @param items The toolbar items configuration.\n\t * @param factory A factory producing toolbar items.\n\t * @param removeItems An array of items names to be removed from the configuration.\n\t * @returns Items after the clean-up.\n\t */\n\tprivate _cleanItemsConfiguration(\n\t\titems: Array<ToolbarConfigItem>,\n\t\tfactory: ComponentFactory,\n\t\tremoveItems: Array<string>\n\t) {\n\t\tconst filteredItems = items\n\t\t\t.filter( ( item, idx, items ) => {\n\t\t\t\tif ( item === '|' ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// Items listed in `config.removeItems` should not be added to the toolbar.\n\t\t\t\tif ( removeItems.indexOf( item as any ) !== -1 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif ( item === '-' ) {\n\t\t\t\t\t// The toolbar line breaks must not be rendered when toolbar grouping is enabled.\n\t\t\t\t\t// (https://github.com/ckeditor/ckeditor5/issues/8582)\n\t\t\t\t\tif ( this.options.shouldGroupWhenFull ) {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * The toolbar multiline breaks (`-` items) only work when the automatic button grouping\n\t\t\t\t\t\t * is disabled in the toolbar configuration.\n\t\t\t\t\t\t * To do this, set the `shouldNotGroupWhenFull` option to `true` in the editor configuration:\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * ```ts\n\t\t\t\t\t\t * const config = {\n\t\t\t\t\t\t * \ttoolbar: {\n\t\t\t\t\t\t * \t\titems: [ ... ],\n\t\t\t\t\t\t * \t\tshouldNotGroupWhenFull: true\n\t\t\t\t\t\t * \t}\n\t\t\t\t\t\t * }\n\t\t\t\t\t\t * ```\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Learn more about {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * @error toolbarview-line-break-ignored-when-grouping-items\n\t\t\t\t\t\t */\n\t\t\t\t\t\tlogWarning( 'toolbarview-line-break-ignored-when-grouping-items', items );\n\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// For the items that cannot be instantiated we are sending warning message. We also filter them out.\n\t\t\t\tif ( !isObject( item ) && !factory.has( item ) ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * There was a problem processing the configuration of the toolbar. The item with the given\n\t\t\t\t\t * name does not exist so it was omitted when rendering the toolbar.\n\t\t\t\t\t *\n\t\t\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t\t\t * to provide a toolbar item has not been loaded or there is a typo in the\n\t\t\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.\n\t\t\t\t\t *\n\t\t\t\t\t * Make sure the plugin responsible for this toolbar item is loaded and the toolbar configuration\n\t\t\t\t\t * is correct, e.g. {@link module:basic-styles/bold~Bold} is loaded for the `'bold'` toolbar item.\n\t\t\t\t\t *\n\t\t\t\t\t * You can use the following snippet to retrieve all available toolbar items:\n\t\t\t\t\t *\n\t\t\t\t\t * ```ts\n\t\t\t\t\t * Array.from( editor.ui.componentFactory.names() );\n\t\t\t\t\t * ```\n\t\t\t\t\t *\n\t\t\t\t\t * @error toolbarview-item-unavailable\n\t\t\t\t\t * @param item The name of the component or nested toolbar definition.\n\t\t\t\t\t */\n\t\t\t\t\tlogWarning( 'toolbarview-item-unavailable', { item } );\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} );\n\n\t\treturn this._cleanSeparatorsAndLineBreaks( filteredItems );\n\t}\n\n\t/**\n\t * Remove leading, trailing, and duplicated separators (`-` and `|`).\n\t *\n\t * @returns Toolbar items after the separator and line break clean-up.\n\t */\n\tprivate _cleanSeparatorsAndLineBreaks( items: Array<ToolbarConfigItem> ) {\n\t\tconst nonSeparatorPredicate = ( item: ToolbarConfigItem ) => ( item !== '-' && item !== '|' );\n\t\tconst count = items.length;\n\n\t\t// Find an index of the first item that is not a separator.\n\t\tconst firstCommandItemIndex = items.findIndex( nonSeparatorPredicate );\n\n\t\t// Items include separators only. There is no point in displaying them.\n\t\tif ( firstCommandItemIndex === -1 ) {\n\t\t\treturn [];\n\t\t}\n\n\t\t// Search from the end of the list, then convert found index back to the original direction.\n\t\tconst lastCommandItemIndex = count - items\n\t\t\t.slice()\n\t\t\t.reverse()\n\t\t\t.findIndex( nonSeparatorPredicate );\n\n\t\treturn items\n\t\t\t// Return items without the leading and trailing separators.\n\t\t\t.slice( firstCommandItemIndex, lastCommandItemIndex )\n\t\t\t// Remove duplicated separators.\n\t\t\t.filter( ( name, idx, items ) => {\n\t\t\t\t// Filter only separators.\n\t\t\t\tif ( nonSeparatorPredicate( name ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tconst isDuplicated = idx > 0 && items[ idx - 1 ] === name;\n\n\t\t\t\treturn !isDuplicated;\n\t\t\t} );\n\t}\n\n\t/**\n\t * Creates a user-defined dropdown containing a toolbar with items.\n\t *\n\t * @param definition A definition of the nested toolbar dropdown.\n\t * @param definition.label A label of the dropdown.\n\t * @param definition.icon An icon of the drop-down. One of 'bold', 'plus', 'text', 'importExport', 'alignLeft',\n\t * 'paragraph' or an SVG string. When `false` is passed, no icon will be used.\n\t * @param definition.withText When set `true`, the label of the dropdown will be visible. See\n\t * {@link module:ui/button/buttonview~ButtonView#withText} to learn more.\n\t * @param definition.tooltip A tooltip of the dropdown button. See\n\t * {@link module:ui/button/buttonview~ButtonView#tooltip} to learn more. Defaults to `true`.\n\t * @param componentFactory Component factory used to create items\n\t * of the nested toolbar.\n\t */\n\tprivate _createNestedToolbarDropdown(\n\t\tdefinition: Exclude<ToolbarConfigItem, string>,\n\t\tcomponentFactory: ComponentFactory,\n\t\tremoveItems: Array<string>\n\t) {\n\t\tlet { label, icon, items, tooltip = true, withText = false } = definition;\n\n\t\titems = this._cleanItemsConfiguration( items, componentFactory, removeItems );\n\n\t\t// There is no point in rendering a dropdown without items.\n\t\tif ( !items.length ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst locale = this.locale;\n\t\tconst dropdownView = createDropdown( locale );\n\n\t\tif ( !label ) {\n\t\t\t/**\n\t\t\t * A dropdown definition in the toolbar configuration is missing a text label.\n\t\t\t *\n\t\t\t * Without a label, the dropdown becomes inaccessible to users relying on assistive technologies.\n\t\t\t * Make sure the `label` property is set in your drop-down configuration:\n\t\t\t *\n\t\t\t * ```json\n \t\t\t * {\n \t\t\t * \tlabel: 'A human-readable label',\n\t\t\t * \ticon: '...',\n\t\t\t * \titems: [ ... ]\n \t\t\t * },\n\t\t\t * ```\n\t\t\t *\n\t\t\t * Learn more about {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}.\n\t\t\t *\n\t\t\t * @error toolbarview-nested-toolbar-dropdown-missing-label\n\t\t\t */\n\t\t\tlogWarning( 'toolbarview-nested-toolbar-dropdown-missing-label', definition );\n\t\t}\n\n\t\tdropdownView.class = 'ck-toolbar__nested-toolbar-dropdown';\n\t\tdropdownView.buttonView.set( {\n\t\t\tlabel,\n\t\t\ttooltip,\n\t\t\twithText: !!withText\n\t\t} );\n\n\t\t// Allow disabling icon by passing false.\n\t\tif ( icon !== false ) {\n\t\t\t// A pre-defined icon picked by name, SVG string, a fallback (default) icon.\n\t\t\tdropdownView.buttonView.icon = NESTED_TOOLBAR_ICONS[ icon! ] || icon || icons.threeVerticalDots;\n\t\t}\n\t\t// If the icon is disabled, display the label automatically.\n\t\telse {\n\t\t\tdropdownView.buttonView.withText = true;\n\t\t}\n\n\t\taddToolbarToDropdown( dropdownView, () => (\n\t\t\tdropdownView.toolbarView!._buildItemsFromConfig( items, componentFactory, removeItems )\n\t\t) );\n\n\t\treturn dropdownView;\n\t}\n}\n\n/**\n * Fired when some toolbar {@link ~ToolbarView#items} were grouped or ungrouped as a result of some change\n * in the toolbar geometry.\n *\n * **Note**: This event is always fired **once** regardless of the number of items that were be\n * grouped or ungrouped at a time.\n *\n * **Note**: This event is fired only if the items grouping functionality was enabled in\n * the first place (see {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull}).\n *\n * @eventName ~ToolbarView#groupedItemsUpdate\n */\nexport type ToolbarViewGroupedItemsUpdateEvent = {\n\tname: 'groupedItemsUpdate';\n\targs: [];\n};\n\n/**\n * An inner block of the {@link module:ui/toolbar/toolbarview~ToolbarView} hosting its\n * {@link module:ui/toolbar/toolbarview~ToolbarView#items}.\n */\nclass ItemsView extends View {\n\t/**\n\t * A collection of items (buttons, dropdowns, etc.).\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-toolbar__items'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n}\n\n/**\n * A toolbar behavior that makes it static and unresponsive to the changes of the environment.\n * At the same time, it also makes it possible to display a toolbar with a vertical layout\n * using the {@link module:ui/toolbar/toolbarview~ToolbarView#isVertical} property.\n */\nclass StaticLayout implements ToolbarBehavior {\n\t/**\n\t * Creates an instance of the {@link module:ui/toolbar/toolbarview~StaticLayout} toolbar\n\t * behavior.\n\t *\n\t * @param view An instance of the toolbar that this behavior is added to.\n\t */\n\tconstructor( view: ToolbarView ) {\n\t\tconst bind = view.bindTemplate;\n\n\t\t// Static toolbar can be vertical when needed.\n\t\tview.set( 'isVertical', false );\n\n\t\t// 1:1 pass–through binding, all ToolbarView#items are visible.\n\t\tview.itemsView.children.bindTo( view.items ).using( item => item );\n\n\t\t// 1:1 pass–through binding, all ToolbarView#items are focusable.\n\t\tview.focusables.bindTo( view.items ).using( item => isFocusable( item ) ? item : null );\n\n\t\tview.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t// When vertical, the toolbar has an additional CSS class.\n\t\t\t\t\tbind.if( 'isVertical', 'ck-toolbar_vertical' )\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic render(): void {}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic destroy(): void {}\n}\n\n/**\n * A toolbar behavior that makes the items respond to changes in the geometry.\n *\n * In a nutshell, it groups {@link module:ui/toolbar/toolbarview~ToolbarView#items}\n * that do not fit visually into a single row of the toolbar (due to limited space).\n * Items that do not fit are aggregated in a dropdown displayed at the end of the toolbar.\n *\n * ```\n *\t┌──────────────────────────────────────── ToolbarView ──────────────────────────────────────────┐\n *\t| ┌─────────────────────────────────────── #children ─────────────────────────────────────────┐ |\n *\t| |   ┌─────── #itemsView ────────┐ ┌──────────────────────┐ ┌── #groupedItemsDropdown ───┐   | |\n *\t| |   |       #ungroupedItems     | | ToolbarSeparatorView | |        #groupedItems       |   | |\n *\t| |   └──────────────────────────-┘ └──────────────────────┘ └────────────────────────────┘   | |\n *\t| |                                  \\---------- only when toolbar items overflow -------/    | |\n *\t| └───────────────────────────────────────────────────────────────────────────────────────────┘ |\n *\t└───────────────────────────────────────────────────────────────────────────────────────────────┘\n * ```\n */\nclass DynamicGrouping implements ToolbarBehavior {\n\t/**\n\t * A toolbar view this behavior belongs to.\n\t */\n\tpublic readonly view: ToolbarView;\n\n\t/**\n\t * A collection of toolbar children.\n\t */\n\tpublic readonly viewChildren: ViewCollection;\n\n\t/**\n\t * A collection of focusable toolbar elements.\n\t */\n\tpublic readonly viewFocusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * A view containing toolbar items.\n\t */\n\tpublic readonly viewItemsView: ItemsView;\n\n\t/**\n\t * Toolbar focus tracker.\n\t */\n\tpublic readonly viewFocusTracker: FocusTracker;\n\n\t/**\n\t * Toolbar locale.\n\t */\n\tpublic readonly viewLocale: Locale;\n\n\t/**\n\t * A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.\n\t * Aggregates items that fit into a single row of the toolbar and were not {@link #groupedItems grouped}\n\t * into a {@link #groupedItemsDropdown dropdown}. Items of this collection are displayed in the\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#itemsView}.\n\t *\n\t * When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped, it\n\t * matches the {@link module:ui/toolbar/toolbarview~ToolbarView#items} collection in size and order.\n\t */\n\tpublic readonly ungroupedItems: ViewCollection;\n\n\t/**\n\t * A subset of toolbar {@link module:ui/toolbar/toolbarview~ToolbarView#items}.\n\t * A collection of the toolbar items that do not fit into a single row of the toolbar.\n\t * Grouped items are displayed in a dedicated {@link #groupedItemsDropdown dropdown}.\n\t *\n\t * When none of the {@link module:ui/toolbar/toolbarview~ToolbarView#items} were grouped,\n\t * this collection is empty.\n\t */\n\tpublic readonly groupedItems: ViewCollection;\n\n\t/**\n\t * The dropdown that aggregates {@link #groupedItems grouped items} that do not fit into a single\n\t * row of the toolbar. It is displayed on demand as the last of\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#children toolbar children} and offers another\n\t * (nested) toolbar which displays items that would normally overflow.\n\t */\n\tpublic readonly groupedItemsDropdown: DropdownView;\n\n\t/**\n\t * An instance of the resize observer that helps dynamically determine the geometry of the toolbar\n\t * and manage items that do not fit into a single row.\n\t *\n\t * **Note:** Created in {@link #_enableGroupingOnResize}.\n\t *\n\t * @readonly\n\t */\n\tpublic resizeObserver: ResizeObserver | null = null;\n\n\t/**\n\t * A cached value of the horizontal padding style used by {@link #_updateGrouping}\n\t * to manage the {@link module:ui/toolbar/toolbarview~ToolbarView#items} that do not fit into\n\t * a single toolbar line. This value can be reused between updates because it is unlikely that\n\t * the padding will change and re–using `Window.getComputedStyle()` is expensive.\n\t *\n\t * @readonly\n\t */\n\tpublic cachedPadding: number | null = null;\n\n\t/**\n\t * A flag indicating that an items grouping update has been queued (e.g. due to the toolbar being visible)\n\t * and should be executed immediately the next time the toolbar shows up.\n\t *\n\t * @readonly\n\t */\n\tpublic shouldUpdateGroupingOnNextResize: boolean = false;\n\n\t/**\n\t * Toolbar element.\n\t *\n\t * @readonly\n\t */\n\tpublic viewElement: HTMLElement | null | undefined;\n\n\t/**\n\t * Creates an instance of the {@link module:ui/toolbar/toolbarview~DynamicGrouping} toolbar\n\t * behavior.\n\t *\n\t * @param view An instance of the toolbar that this behavior is added to.\n\t */\n\tconstructor( view: ToolbarView ) {\n\t\tthis.view = view;\n\n\t\tthis.viewChildren = view.children;\n\t\tthis.viewFocusables = view.focusables;\n\t\tthis.viewItemsView = view.itemsView;\n\t\tthis.viewFocusTracker = view.focusTracker;\n\t\tthis.viewLocale = view.locale;\n\n\t\tthis.ungroupedItems = view.createCollection();\n\t\tthis.groupedItems = view.createCollection();\n\t\tthis.groupedItemsDropdown = this._createGroupedItemsDropdown();\n\n\t\t// Only those items that were not grouped are visible to the user.\n\t\tview.itemsView.children.bindTo( this.ungroupedItems ).using( item => item );\n\n\t\t// Make sure all #items visible in the main space of the toolbar are \"focuscyclable\".\n\t\tthis.ungroupedItems.on<CollectionChangeEvent>( 'change', this._updateFocusCyclableItems.bind( this ) );\n\n\t\t// Make sure the #groupedItemsDropdown is also included in cycling when it appears.\n\t\tview.children.on<CollectionChangeEvent>( 'change', this._updateFocusCyclableItems.bind( this ) );\n\n\t\t// ToolbarView#items is dynamic. When an item is added or removed, it should be automatically\n\t\t// represented in either grouped or ungrouped items at the right index.\n\t\t// In other words #items == concat( #ungroupedItems, #groupedItems )\n\t\t// (in length and order).\n\t\tview.items.on<CollectionChangeEvent<View>>( 'change', ( evt, changeData ) => {\n\t\t\tconst index = changeData.index;\n\t\t\tconst added = Array.from( changeData.added );\n\n\t\t\t// Removing.\n\t\t\tfor ( const removedItem of changeData.removed ) {\n\t\t\t\tif ( index >= this.ungroupedItems.length ) {\n\t\t\t\t\tthis.groupedItems.remove( removedItem );\n\t\t\t\t} else {\n\t\t\t\t\tthis.ungroupedItems.remove( removedItem );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Adding.\n\t\t\tfor ( let currentIndex = index; currentIndex < index + added.length; currentIndex++ ) {\n\t\t\t\tconst addedItem = added[ currentIndex - index ];\n\n\t\t\t\tif ( currentIndex > this.ungroupedItems.length ) {\n\t\t\t\t\tthis.groupedItems.add( addedItem, currentIndex - this.ungroupedItems.length );\n\t\t\t\t} else {\n\t\t\t\t\tthis.ungroupedItems.add( addedItem, currentIndex );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// When new ungrouped items join in and land in #ungroupedItems, there's a chance it causes\n\t\t\t// the toolbar to overflow.\n\t\t\t// Consequently if removed from grouped or ungrouped items, there is a chance\n\t\t\t// some new space is available and we could do some ungrouping.\n\t\t\tthis._updateGrouping();\n\t\t} );\n\n\t\tview.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t// To group items dynamically, the toolbar needs a dedicated CSS class.\n\t\t\t\t\t'ck-toolbar_grouping'\n\t\t\t\t]\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Enables dynamic items grouping based on the dimensions of the toolbar.\n\t *\n\t * @param view An instance of the toolbar that this behavior is added to.\n\t */\n\tpublic render( view: ToolbarView ): void {\n\t\tthis.viewElement = view.element;\n\n\t\tthis._enableGroupingOnResize();\n\t\tthis._enableGroupingOnMaxWidthChange( view );\n\t}\n\n\t/**\n\t * Cleans up the internals used by this behavior.\n\t */\n\tpublic destroy(): void {\n\t\t// The dropdown may not be in ToolbarView#children at the moment of toolbar destruction\n\t\t// so let's make sure it's actually destroyed along with the toolbar.\n\t\tthis.groupedItemsDropdown.destroy();\n\n\t\tthis.resizeObserver!.destroy();\n\t}\n\n\t/**\n\t * When called, it will check if any of the {@link #ungroupedItems} do not fit into a single row of the toolbar,\n\t * and it will move them to the {@link #groupedItems} when it happens.\n\t *\n\t * At the same time, it will also check if there is enough space in the toolbar for the first of the\n\t * {@link #groupedItems} to be returned back to {@link #ungroupedItems} and still fit into a single row\n\t * without the toolbar wrapping.\n\t */\n\tprivate _updateGrouping() {\n\t\t// Do no grouping–related geometry analysis when the toolbar is detached from visible DOM,\n\t\t// for instance before #render(), or after render but without a parent or a parent detached\n\t\t// from DOM. DOMRects won't work anyway and there will be tons of warning in the console and\n\t\t// nothing else. This happens, for instance, when the toolbar is detached from DOM and\n\t\t// some logic adds or removes its #items.\n\t\tif ( !this.viewElement!.ownerDocument.body.contains( this.viewElement! ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not update grouping when the element is invisible. Such toolbar has DOMRect filled with zeros\n\t\t// and that would cause all items to be grouped. Instead, queue the grouping so it runs next time\n\t\t// the toolbar is visible (the next ResizeObserver callback execution). This is handy because\n\t\t// the grouping could be caused by increasing the #maxWidth when the toolbar was invisible and the next\n\t\t// time it shows up, some items could actually be ungrouped (https://github.com/ckeditor/ckeditor5/issues/6575).\n\t\tif ( !isVisible( this.viewElement ) ) {\n\t\t\tthis.shouldUpdateGroupingOnNextResize = true;\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember how many items were initially grouped so at the it is possible to figure out if the number\n\t\t// of grouped items has changed. If the number has changed, geometry of the toolbar has also changed.\n\t\tconst initialGroupedItemsCount = this.groupedItems.length;\n\t\tlet wereItemsGrouped;\n\n\t\t// Group #items as long as some wrap to the next row. This will happen, for instance,\n\t\t// when the toolbar is getting narrow and there is not enough space to display all items in\n\t\t// a single row.\n\t\twhile ( this._areItemsOverflowing ) {\n\t\t\tthis._groupLastItem();\n\n\t\t\twereItemsGrouped = true;\n\t\t}\n\n\t\t// If none were grouped now but there were some items already grouped before,\n\t\t// then, what the hell, maybe let's see if some of them can be ungrouped. This happens when,\n\t\t// for instance, the toolbar is stretching and there's more space in it than before.\n\t\tif ( !wereItemsGrouped && this.groupedItems.length ) {\n\t\t\t// Ungroup items as long as none are overflowing or there are none to ungroup left.\n\t\t\twhile ( this.groupedItems.length && !this._areItemsOverflowing ) {\n\t\t\t\tthis._ungroupFirstItem();\n\t\t\t}\n\n\t\t\t// If the ungrouping ended up with some item wrapping to the next row,\n\t\t\t// put it back to the group toolbar (\"undo the last ungroup\"). We don't know whether\n\t\t\t// an item will wrap or not until we ungroup it (that's a DOM/CSS thing) so this\n\t\t\t// clean–up is vital for the algorithm.\n\t\t\tif ( this._areItemsOverflowing ) {\n\t\t\t\tthis._groupLastItem();\n\t\t\t}\n\t\t}\n\n\t\tif ( this.groupedItems.length !== initialGroupedItemsCount ) {\n\t\t\tthis.view.fire<ToolbarViewGroupedItemsUpdateEvent>( 'groupedItemsUpdate' );\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when {@link module:ui/toolbar/toolbarview~ToolbarView#element} children visually overflow,\n\t * for instance if the toolbar is narrower than its members. Returns `false` otherwise.\n\t */\n\tprivate get _areItemsOverflowing() {\n\t\t// An empty toolbar cannot overflow.\n\t\tif ( !this.ungroupedItems.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst element = this.viewElement;\n\t\tconst uiLanguageDirection = this.viewLocale.uiLanguageDirection;\n\t\tconst lastChildRect = new Rect( element!.lastChild as any );\n\t\tconst toolbarRect = new Rect( element! );\n\n\t\tif ( !this.cachedPadding ) {\n\t\t\tconst computedStyle = global.window.getComputedStyle( element! );\n\t\t\tconst paddingProperty = uiLanguageDirection === 'ltr' ? 'paddingRight' : 'paddingLeft';\n\n\t\t\t// parseInt() is essential because of quirky floating point numbers logic and DOM.\n\t\t\t// If the padding turned out too big because of that, the grouped items dropdown would\n\t\t\t// always look (from the Rect perspective) like it overflows (while it's not).\n\t\t\tthis.cachedPadding = Number.parseInt( computedStyle[ paddingProperty ] );\n\t\t}\n\n\t\tif ( uiLanguageDirection === 'ltr' ) {\n\t\t\treturn lastChildRect.right > toolbarRect.right - this.cachedPadding;\n\t\t} else {\n\t\t\treturn lastChildRect.left < toolbarRect.left + this.cachedPadding;\n\t\t}\n\t}\n\n\t/**\n\t * Enables the functionality that prevents {@link #ungroupedItems} from overflowing (wrapping to the next row)\n\t * upon resize when there is little space available. Instead, the toolbar items are moved to the\n\t * {@link #groupedItems} collection and displayed in a dropdown at the end of the row (which has its own nested toolbar).\n\t *\n\t * When called, the toolbar will automatically analyze the location of its {@link #ungroupedItems} and \"group\"\n\t * them in the dropdown if necessary. It will also observe the browser window for size changes in\n\t * the future and respond to them by grouping more items or reverting already grouped back, depending\n\t * on the visual space available.\n\t */\n\tprivate _enableGroupingOnResize() {\n\t\tlet previousWidth: number | undefined;\n\n\t\t// TODO: Consider debounce.\n\t\tthis.resizeObserver = new ResizeObserver( this.viewElement!, entry => {\n\t\t\tif ( !previousWidth || previousWidth !== entry.contentRect.width || this.shouldUpdateGroupingOnNextResize ) {\n\t\t\t\tthis.shouldUpdateGroupingOnNextResize = false;\n\n\t\t\t\tthis._updateGrouping();\n\n\t\t\t\tpreviousWidth = entry.contentRect.width;\n\t\t\t}\n\t\t} );\n\n\t\tthis._updateGrouping();\n\t}\n\n\t/**\n\t * Enables the grouping functionality, just like {@link #_enableGroupingOnResize} but the difference is that\n\t * it listens to the changes of {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth} instead.\n\t */\n\tprivate _enableGroupingOnMaxWidthChange( view: View ) {\n\t\tview.on<ObservableChangeEvent>( 'change:maxWidth', () => {\n\t\t\tthis._updateGrouping();\n\t\t} );\n\t}\n\n\t/**\n\t * When called, it will remove the last item from {@link #ungroupedItems} and move it back\n\t * to the {@link #groupedItems} collection.\n\t *\n\t * The opposite of {@link #_ungroupFirstItem}.\n\t */\n\tprivate _groupLastItem() {\n\t\tif ( !this.groupedItems.length ) {\n\t\t\tthis.viewChildren.add( new ToolbarSeparatorView() );\n\t\t\tthis.viewChildren.add( this.groupedItemsDropdown );\n\t\t\tthis.viewFocusTracker.add( this.groupedItemsDropdown.element! );\n\t\t}\n\n\t\tthis.groupedItems.add( this.ungroupedItems.remove( this.ungroupedItems.last! ), 0 );\n\t}\n\n\t/**\n\t * Moves the very first item belonging to {@link #groupedItems} back\n\t * to the {@link #ungroupedItems} collection.\n\t *\n\t * The opposite of {@link #_groupLastItem}.\n\t */\n\tprivate _ungroupFirstItem() {\n\t\tthis.ungroupedItems.add( this.groupedItems.remove( this.groupedItems.first! ) );\n\n\t\tif ( !this.groupedItems.length ) {\n\t\t\tthis.viewChildren.remove( this.groupedItemsDropdown );\n\t\t\tthis.viewChildren.remove( this.viewChildren.last! );\n\t\t\tthis.viewFocusTracker.remove( this.groupedItemsDropdown.element! );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the {@link #groupedItemsDropdown} that hosts the members of the {@link #groupedItems}\n\t * collection when there is not enough space in the toolbar to display all items in a single row.\n\t */\n\tprivate _createGroupedItemsDropdown() {\n\t\tconst locale = this.viewLocale;\n\t\tconst t = locale.t;\n\t\tconst dropdown = createDropdown( locale );\n\n\t\tdropdown.class = 'ck-toolbar__grouped-dropdown';\n\n\t\t// Make sure the dropdown never sticks out to the left/right. It should be under the main toolbar.\n\t\t// (https://github.com/ckeditor/ckeditor5/issues/5608)\n\t\tdropdown.panelPosition = locale.uiLanguageDirection === 'ltr' ? 'sw' : 'se';\n\n\t\taddToolbarToDropdown( dropdown, this.groupedItems );\n\n\t\tdropdown.buttonView.set( {\n\t\t\tlabel: t( 'Show more items' ),\n\t\t\ttooltip: true,\n\t\t\ttooltipPosition: locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw',\n\t\t\ticon: icons.threeVerticalDots\n\t\t} );\n\n\t\treturn dropdown;\n\t}\n\n\t/**\n\t * Updates the {@link module:ui/toolbar/toolbarview~ToolbarView#focusables focus–cyclable items}\n\t * collection so it represents the up–to–date state of the UI from the perspective of the user.\n\t *\n\t * For instance, the {@link #groupedItemsDropdown} can show up and hide but when it is visible,\n\t * it must be subject to focus cycling in the toolbar.\n\t *\n\t * See the {@link module:ui/toolbar/toolbarview~ToolbarView#focusables collection} documentation\n\t * to learn more about the purpose of this method.\n\t */\n\tprivate _updateFocusCyclableItems() {\n\t\tthis.viewFocusables.clear();\n\n\t\tthis.ungroupedItems.map( item => {\n\t\t\tif ( isFocusable( item ) ) {\n\t\t\t\tthis.viewFocusables.add( item );\n\t\t\t}\n\t\t} );\n\n\t\tif ( this.groupedItems.length ) {\n\t\t\tthis.viewFocusables.add( this.groupedItemsDropdown );\n\t\t}\n\t}\n}\n\n/**\n * Options passed to the {@link module:ui/toolbar/toolbarview~ToolbarView#constructor} of the toolbar.\n */\nexport interface ToolbarOptions {\n\n\t/**\n\t * When set to `true`, the toolbar will automatically group {@link module:ui/toolbar/toolbarview~ToolbarView#items} that\n\t * would normally wrap to the next line when there is not enough space to display them in a single row, for\n\t * instance, if the parent container of the toolbar is narrow. For toolbars in absolutely positioned containers\n\t * without width restrictions also the {@link module:ui/toolbar/toolbarview~ToolbarOptions#isFloating} option is required to be `true`.\n\t *\n\t * See also: {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth}.\n\t */\n\tshouldGroupWhenFull?: boolean;\n\n\t/**\n\t * This option should be enabled for toolbars in absolutely positioned containers without width restrictions\n\t * to enable automatic {@link module:ui/toolbar/toolbarview~ToolbarView#items} grouping.\n\t * When this option is set to `true`, the items will stop wrapping to the next line\n\t * and together with {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull},\n\t * this will allow grouping them when there is not enough space in a single row.\n\t */\n\tisFloating?: boolean;\n}\n\n/**\n * A class interface defining the behavior of the {@link module:ui/toolbar/toolbarview~ToolbarView}.\n *\n * Toolbar behaviors extend its look and functionality and have an impact on the\n * {@link module:ui/toolbar/toolbarview~ToolbarView#element} template or\n * {@link module:ui/toolbar/toolbarview~ToolbarView#render rendering}. They can be enabled\n * conditionally, e.g. depending on the configuration of the toolbar.\n */\nexport interface ToolbarBehavior {\n\n\t/**\n\t * A method called after the toolbar has been {@link module:ui/toolbar/toolbarview~ToolbarView#render rendered}.\n\t * It can be used to, for example, customize the behavior of the toolbar when its\n\t * {@link module:ui/toolbar/toolbarview~ToolbarView#element} is available.\n\t *\n\t * @param view An instance of the toolbar being rendered.\n\t */\n\trender( view: ToolbarView ): void;\n\n\t/**\n\t * A method called after the toolbar has been {@link module:ui/toolbar/toolbarview~ToolbarView#destroy destroyed}.\n\t * It allows cleaning up after the toolbar behavior, for instance, this is the right place to detach\n\t * event listeners, free up references, etc.\n\t */\n\tdestroy(): void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/button/splitbuttonview\n */\n\nimport View from '../../view.js';\nimport ButtonView from '../../button/buttonview.js';\nimport type ViewCollection from '../../viewcollection.js';\nimport type Button from '../../button/button.js';\nimport type DropdownButton from './dropdownbutton.js';\nimport type { FocusableView } from '../../focuscycler.js';\n\nimport {\n\tKeystrokeHandler,\n\tFocusTracker,\n\ttype Locale\n} from '@ckeditor/ckeditor5-utils';\n\nimport dropdownArrowIcon from '../../../theme/icons/dropdown-arrow.svg';\n\nimport '../../../theme/components/dropdown/splitbutton.css';\n\n/**\n * The split button view class.\n *\n * ```ts\n * const view = new SplitButtonView();\n *\n * view.set( {\n * \tlabel: 'A button',\n * \tkeystroke: 'Ctrl+B',\n * \ttooltip: true\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n *\n * Also see the {@link module:ui/dropdown/utils~createDropdown `createDropdown()` util}.\n */\nexport default class SplitButtonView extends View<HTMLDivElement> implements DropdownButton {\n\t/**\n\t * Collection of the child views inside of the split button {@link #element}.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * A main button of split button.\n\t */\n\tpublic readonly actionView: ButtonView;\n\n\t/**\n\t * A secondary button of split button that opens dropdown.\n\t */\n\tpublic readonly arrowView: ButtonView;\n\n\t/**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the split button:\n\t *\n\t * * <kbd>▶</kbd> moves focus to arrow view when action view is focused,\n\t * * <kbd>◀</kbd> moves focus to action view when arrow view is focused.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Tracks information about DOM focus in the dropdown.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public label: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public keystroke: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public tooltip: Button[ 'tooltip' ];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public tooltipPosition: Button[ 'tooltipPosition' ];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public type: Button[ 'type' ];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isOn: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public isToggleable: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public withText: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public withKeystroke: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public icon: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public tabindex: number;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public labelStyle: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public role: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public ariaChecked: boolean | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public ariaLabel?: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public ariaLabelledBy: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale, actionButton?: ButtonView & FocusableView ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t// Implement the Button interface.\n\t\tthis.set( 'class', undefined );\n\t\tthis.set( 'labelStyle', undefined );\n\t\tthis.set( 'icon', undefined );\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'isOn', false );\n\t\tthis.set( 'isToggleable', false );\n\t\tthis.set( 'isVisible', true );\n\t\tthis.set( 'keystroke', undefined );\n\t\tthis.set( 'withKeystroke', false );\n\t\tthis.set( 'label', undefined );\n\t\tthis.set( 'tabindex', -1 );\n\t\tthis.set( 'tooltip', false );\n\t\tthis.set( 'tooltipPosition', 's' );\n\t\tthis.set( 'type', 'button' );\n\t\tthis.set( 'withText', false );\n\n\t\tthis.children = this.createCollection();\n\t\tthis.actionView = this._createActionView( actionButton );\n\t\tthis.arrowView = this._createArrowView();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-splitbutton',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value ),\n\t\t\t\t\tthis.arrowView.bindTemplate.if( 'isOn', 'ck-splitbutton_open' )\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.children.add( this.actionView );\n\t\tthis.children.add( this.arrowView );\n\n\t\tthis.focusTracker.add( this.actionView.element! );\n\t\tthis.focusTracker.add( this.arrowView.element! );\n\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\t// Overrides toolbar focus cycling behavior.\n\t\tthis.keystrokes.set( 'arrowright', ( evt, cancel ) => {\n\t\t\tif ( this.focusTracker.focusedElement === this.actionView.element ) {\n\t\t\t\tthis.arrowView.focus();\n\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Overrides toolbar focus cycling behavior.\n\t\tthis.keystrokes.set( 'arrowleft', ( evt, cancel ) => {\n\t\t\tif ( this.focusTracker.focusedElement === this.arrowView.element ) {\n\t\t\t\tthis.actionView.focus();\n\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the {@link module:ui/button/buttonview~ButtonView#element} of the action part of split button.\n\t */\n\tpublic focus(): void {\n\t\tthis.actionView.focus();\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/button/buttonview~ButtonView} instance as {@link #actionView} and binds it with main split button\n\t * attributes.\n\t */\n\tprivate _createActionView( actionButton?: ButtonView & FocusableView ) {\n\t\tconst actionView = actionButton || new ButtonView();\n\n\t\tif ( !actionButton ) {\n\t\t\tactionView.bind(\n\t\t\t\t'icon',\n\t\t\t\t'isEnabled',\n\t\t\t\t'isOn',\n\t\t\t\t'isToggleable',\n\t\t\t\t'keystroke',\n\t\t\t\t'label',\n\t\t\t\t'tabindex',\n\t\t\t\t'tooltip',\n\t\t\t\t'tooltipPosition',\n\t\t\t\t'type',\n\t\t\t\t'withText'\n\t\t\t).to( this );\n\t\t}\n\n\t\tactionView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-splitbutton__action'\n\t\t\t}\n\t\t} );\n\n\t\tactionView.delegate( 'execute' ).to( this );\n\n\t\treturn actionView;\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/button/buttonview~ButtonView} instance as {@link #arrowView} and binds it with main split button\n\t * attributes.\n\t */\n\tprivate _createArrowView() {\n\t\tconst arrowView = new ButtonView();\n\t\tconst bind = arrowView.bindTemplate;\n\n\t\tarrowView.icon = dropdownArrowIcon;\n\n\t\tarrowView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-splitbutton__arrow'\n\t\t\t\t],\n\t\t\t\t'data-cke-tooltip-disabled': bind.to( 'isOn' ),\n\t\t\t\t'aria-haspopup': true,\n\t\t\t\t'aria-expanded': bind.to( 'isOn', value => String( value ) )\n\t\t\t}\n\t\t} );\n\n\t\tarrowView.bind( 'isEnabled' ).to( this );\n\t\tarrowView.bind( 'label' ).to( this );\n\t\tarrowView.bind( 'tooltip' ).to( this );\n\n\t\tarrowView.delegate( 'execute' ).to( this, 'open' );\n\n\t\treturn arrowView;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/dropdown/utils\n */\n\nimport DropdownPanelView from './dropdownpanelview.js';\nimport DropdownView from './dropdownview.js';\nimport DropdownButtonView from './button/dropdownbuttonview.js';\nimport DropdownMenuRootListView from './menu/dropdownmenurootlistview.js';\nimport ToolbarView from '../toolbar/toolbarview.js';\nimport ListView from '../list/listview.js';\nimport ListItemView from '../list/listitemview.js';\nimport ListSeparatorView from '../list/listseparatorview.js';\nimport SplitButtonView from './button/splitbuttonview.js';\nimport SwitchButtonView from '../button/switchbuttonview.js';\nimport ViewCollection from '../viewcollection.js';\n\nimport clickOutsideHandler from '../bindings/clickoutsidehandler.js';\n\nimport type { default as View } from '../view.js';\nimport type { ButtonExecuteEvent } from '../button/button.js';\nimport type Model from '../model.js';\nimport type DropdownButton from './button/dropdownbutton.js';\nimport type ButtonView from '../button/buttonview.js';\nimport type { FocusableView } from '../focuscycler.js';\nimport type { FalsyValue } from '../template.js';\nimport type BodyCollection from '../editorui/bodycollection.js';\n\nimport {\n\tglobal,\n\tpriorities,\n\tlogWarning,\n\ttype FocusTracker,\n\ttype Collection,\n\ttype Locale,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/dropdown/toolbardropdown.css';\nimport '../../theme/components/dropdown/listdropdown.css';\n\nimport ListItemGroupView from '../list/listitemgroupview.js';\nimport ListItemButtonView from '../button/listitembuttonview.js';\nimport type { DropdownMenuDefinition } from './menu/utils.js';\n\n/**\n * A helper for creating dropdowns. It creates an instance of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown},\n * with a {@link module:ui/dropdown/button/dropdownbutton~DropdownButton button},\n * {@link module:ui/dropdown/dropdownpanelview~DropdownPanelView panel} and all standard dropdown's behaviors.\n *\n * # Creating dropdowns\n *\n * By default, the default {@link module:ui/dropdown/button/dropdownbuttonview~DropdownButtonView} class is used as\n * definition of the button:\n *\n * ```ts\n * const dropdown = createDropdown( model );\n *\n * // Configure dropdown's button properties:\n * dropdown.buttonView.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.render();\n *\n * // Will render a dropdown labeled \"A dropdown\" with an empty panel.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * You can also provide other button views (they need to implement the\n * {@link module:ui/dropdown/button/dropdownbutton~DropdownButton} interface). For instance, you can use\n * {@link module:ui/dropdown/button/splitbuttonview~SplitButtonView} to create a dropdown with a split button.\n *\n * ```ts\n * const dropdown = createDropdown( locale, SplitButtonView );\n *\n * // Configure dropdown's button properties:\n * dropdown.buttonView.set( {\n * \tlabel: 'A dropdown',\n * \twithText: true\n * } );\n *\n * dropdown.buttonView.on( 'execute', () => {\n * \t// Add the behavior of the \"action part\" of the split button.\n * \t// Split button consists of the \"action part\" and \"arrow part\".\n * \t// The arrow opens the dropdown while the action part can have some other behavior.\n * } );\n *\n * dropdown.render();\n *\n * // Will render a dropdown labeled \"A dropdown\" with an empty panel.\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * # Adding content to the dropdown's panel\n *\n * The content of the panel can be inserted directly into the `dropdown.panelView.element`:\n *\n * ```ts\n * dropdown.panelView.element.textContent = 'Content of the panel';\n * ```\n *\n * However, most of the time you will want to add there either a {@link module:ui/list/listview~ListView list of options}\n * or a list of buttons (i.e. a {@link module:ui/toolbar/toolbarview~ToolbarView toolbar}).\n * To simplify the task, you can use, respectively, {@link module:ui/dropdown/utils~addListToDropdown} or\n * {@link module:ui/dropdown/utils~addToolbarToDropdown} utils.\n *\n * @param locale The locale instance.\n * @param ButtonClassOrInstance The dropdown button view class. Needs to implement the\n * @param behaviorOptions Attributes for the default behavior of the dropdown.\n *\n * {@link module:ui/dropdown/button/dropdownbutton~DropdownButton} interface.\n * @returns The dropdown view instance.\n */\nexport function createDropdown(\n\tlocale: Locale | undefined,\n\tButtonClassOrInstance:\n\t\t( new ( locale?: Locale ) => DropdownButton & FocusableView ) | DropdownButton & FocusableView = DropdownButtonView\n): DropdownView {\n\tconst buttonView = typeof ButtonClassOrInstance == 'function' ? new ButtonClassOrInstance( locale ) : ButtonClassOrInstance;\n\n\tconst panelView = new DropdownPanelView( locale );\n\tconst dropdownView = new DropdownView( locale, buttonView, panelView );\n\n\tbuttonView.bind( 'isEnabled' ).to( dropdownView );\n\n\tif ( buttonView instanceof SplitButtonView ) {\n\t\tbuttonView.arrowView.bind( 'isOn' ).to( dropdownView, 'isOpen' );\n\t} else {\n\t\tbuttonView.bind( 'isOn' ).to( dropdownView, 'isOpen' );\n\t}\n\n\taddDefaultBehaviors( dropdownView );\n\n\treturn dropdownView;\n}\n\n/**\n * Adds a menu UI component to a dropdown and sets all common behaviors and interactions between the dropdown and the menu.\n *\n * Use this helper to create multi-level dropdown menus that are displayed in a toolbar.\n *\n * Internally, it creates an instance of {@link module:ui/dropdown/menu/dropdownmenurootlistview~DropdownMenuRootListView}.\n *\n * Example:\n *\n * ```ts\n * const definitions = [\n * \t{\n * \t\tid: 'menu_1',\n * \t\tmenu: 'Menu 1',\n * \t\tchildren: [\n * \t\t\t{\n * \t\t\t\tid: 'menu_1_a',\n * \t\t\t\tlabel: 'Item A'\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tid: 'menu_1_b',\n * \t\t\t\tlabel: 'Item B'\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tid: 'top_a',\n * \t\tlabel: 'Top Item A'\n * \t},\n * \t{\n * \t\tid: 'top_b',\n * \t\tlabel: 'Top Item B'\n * \t}\n * ];\n *\n * const dropdownView = createDropdown( editor.locale );\n *\n * addMenuToDropdown( dropdownView, editor.ui.view.body, definitions );\n * ```\n *\n * After using this helper, the `dropdown` will fire {@link module:ui/dropdown/dropdownview~DropdownViewEvent `execute`} event when\n * a nested menu button is pressed.\n *\n * The helper will make sure that the `dropdownMenuRootListView` is lazy loaded, i.e., the menu component structure will be initialized\n * and rendered only after the `dropdown` is opened for the first time.\n *\n * @param dropdownView A dropdown instance to which the menu component will be added.\n * @param body Body collection to which floating menu panels will be added.\n * @param definition The menu component definition.\n * @param options.ariaLabel Label used by assistive technologies to describe the top-level menu.\n */\nexport function addMenuToDropdown(\n\tdropdownView: DropdownView,\n\tbody: BodyCollection,\n\tdefinition: DropdownMenuDefinition,\n\toptions: {\n\t\tariaLabel?: string;\n\t} = {} ): void {\n\tdropdownView.menuView = new DropdownMenuRootListView( dropdownView.locale!, body, definition );\n\tdropdownView.focusTracker.add( dropdownView.menuView );\n\n\tif ( dropdownView.isOpen ) {\n\t\taddMenuToOpenDropdown( dropdownView, options );\n\t} else {\n\t\t// Load the UI elements only after the dropdown is opened for the first time - lazy loading.\n\t\tdropdownView.once( 'change:isOpen', () => {\n\t\t\taddMenuToOpenDropdown( dropdownView, options );\n\t\t}, { priority: 'highest' } );\n\t}\n}\n\nfunction addMenuToOpenDropdown(\n\tdropdownView: DropdownView,\n\toptions: {\n\t\tariaLabel?: string;\n\t}\n): void {\n\tconst dropdownMenuRootListView = dropdownView.menuView!;\n\tconst t = dropdownView.locale!.t;\n\n\tdropdownMenuRootListView.delegate( 'menu:execute' ).to( dropdownView, 'execute' );\n\tdropdownMenuRootListView.listenTo( dropdownView, 'change:isOpen', ( evt, name, isOpen ) => {\n\t\tif ( !isOpen ) {\n\t\t\tdropdownMenuRootListView.closeMenus();\n\t\t}\n\t}, { priority: 'low' } ); // Make sure this is fired after `focusDropdownButtonOnClose` behavior.\n\n\t// When `dropdownMenuRootListView` is added as a `panelView` child, it becomes rendered (`panelView` is rendered at this point).\n\tdropdownView.panelView.children.add( dropdownMenuRootListView );\n\n\t// Nested menu panels are added to body collection, so they are not children of the `dropdownView` from DOM perspective.\n\t// Add these panels to `dropdownView` focus tracker, so they are treated like part of the `dropdownView` for focus-related purposes.\n\tfor ( const menu of dropdownMenuRootListView.menus ) {\n\t\tdropdownView.focusTracker.add( menu );\n\t}\n\n\tdropdownMenuRootListView.ariaLabel = options.ariaLabel || t( 'Dropdown menu' );\n}\n\n/**\n * Adds an instance of {@link module:ui/toolbar/toolbarview~ToolbarView} to a dropdown.\n *\n * ```ts\n * const buttonsCreator = () => {\n * \tconst buttons = [];\n *\n * \t// Either create a new ButtonView instance or create existing.\n * \tbuttons.push( new ButtonView() );\n * \tbuttons.push( editor.ui.componentFactory.create( 'someButton' ) );\n * };\n *\n * const dropdown = createDropdown( locale );\n *\n * addToolbarToDropdown( dropdown, buttonsCreator, { isVertical: true } );\n *\n * // Will render a vertical button dropdown labeled \"A button dropdown\"\n * // with a button group in the panel containing two buttons.\n * // Buttons inside the dropdown will be created on first dropdown panel open.\n * dropdown.render()\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * **Note:** To improve the accessibility, you can tell the dropdown to focus the first active button of the toolbar when the dropdown\n * {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open}. See the documentation of `options` to learn more.\n *\n * **Note:** Toolbar view will be created on first open of the dropdown.\n *\n * See {@link module:ui/dropdown/utils~createDropdown} and {@link module:ui/toolbar/toolbarview~ToolbarView}.\n *\n * @param dropdownView A dropdown instance to which `ToolbarView` will be added.\n * @param options.enableActiveItemFocusOnDropdownOpen When set `true`, the focus will automatically move to the first\n * active {@link module:ui/toolbar/toolbarview~ToolbarView#items item} of the toolbar upon\n * {@link module:ui/dropdown/dropdownview~DropdownView#isOpen opening} the dropdown. Active items are those with the `isOn` property set\n * `true` (for instance {@link module:ui/button/buttonview~ButtonView buttons}). If no active items is found, the toolbar will be focused\n * as a whole resulting in the focus moving to its first focusable item (default behavior of\n * {@link module:ui/dropdown/dropdownview~DropdownView}).\n * @param options.ariaLabel Label used by assistive technologies to describe toolbar element.\n * @param options.maxWidth The maximum width of the toolbar element.\n * Details: {@link module:ui/toolbar/toolbarview~ToolbarView#maxWidth}.\n * @param options.class An additional CSS class added to the toolbar element.\n * @param options.isCompact When set true, makes the toolbar look compact with toolbar element.\n * @param options.isVertical Controls the orientation of toolbar items.\n */\nexport function addToolbarToDropdown(\n\tdropdownView: DropdownView,\n\tbuttonsOrCallback: Array<View> | ViewCollection | ( () => Array<View> | ViewCollection ),\n\toptions: {\n\t\tenableActiveItemFocusOnDropdownOpen?: boolean;\n\t\tariaLabel?: string;\n\t\tmaxWidth?: string;\n\t\tclass?: string;\n\t\tisCompact?: boolean;\n\t\tisVertical?: boolean;\n\t} = {}\n): void {\n\tdropdownView.extendTemplate( {\n\t\tattributes: {\n\t\t\tclass: [ 'ck-toolbar-dropdown' ]\n\t\t}\n\t} );\n\n\tif ( dropdownView.isOpen ) {\n\t\taddToolbarToOpenDropdown( dropdownView, buttonsOrCallback, options );\n\t} else {\n\t\tdropdownView.once(\n\t\t\t'change:isOpen',\n\t\t\t() => addToolbarToOpenDropdown( dropdownView, buttonsOrCallback, options ),\n\t\t\t{ priority: 'highest' }\n\t\t);\n\t}\n\n\tif ( options.enableActiveItemFocusOnDropdownOpen ) {\n\t\t// Accessibility: Focus the first active button in the toolbar when the dropdown gets open.\n\t\tfocusChildOnDropdownOpen( dropdownView, () => dropdownView.toolbarView!.items.find( ( item: any ) => item.isOn ) );\n\t}\n}\n\n/**\n * Adds an instance of {@link module:ui/toolbar/toolbarview~ToolbarView} to a dropdown.\n */\nfunction addToolbarToOpenDropdown(\n\tdropdownView: DropdownView,\n\tbuttonsOrCallback: Array<View> | ViewCollection | ( () => Array<View> | ViewCollection ),\n\toptions: {\n\t\tariaLabel?: string;\n\t\tmaxWidth?: string;\n\t\tclass?: string;\n\t\tisCompact?: boolean;\n\t\tisVertical?: boolean;\n\t}\n): void {\n\tconst locale = dropdownView.locale!;\n\tconst t = locale.t;\n\n\tconst toolbarView = dropdownView.toolbarView = new ToolbarView( locale );\n\tconst buttons = typeof buttonsOrCallback == 'function' ? buttonsOrCallback() : buttonsOrCallback;\n\n\ttoolbarView.ariaLabel = options.ariaLabel || t( 'Dropdown toolbar' );\n\n\tif ( options.maxWidth ) {\n\t\ttoolbarView.maxWidth = options.maxWidth;\n\t}\n\n\tif ( options.class ) {\n\t\ttoolbarView.class = options.class;\n\t}\n\n\tif ( options.isCompact ) {\n\t\ttoolbarView.isCompact = options.isCompact;\n\t}\n\n\tif ( options.isVertical ) {\n\t\ttoolbarView.isVertical = true;\n\t}\n\n\tif ( buttons instanceof ViewCollection ) {\n\t\ttoolbarView.items.bindTo( buttons ).using( item => item );\n\t} else {\n\t\ttoolbarView.items.addMany( buttons );\n\t}\n\n\tdropdownView.panelView.children.add( toolbarView );\n\tdropdownView.focusTracker.add( toolbarView );\n\ttoolbarView.items.delegate( 'execute' ).to( dropdownView );\n}\n\n/**\n * Adds an instance of {@link module:ui/list/listview~ListView} to a dropdown.\n *\n * ```ts\n * const items = new Collection<ListDropdownItemDefinition>();\n *\n * items.add( {\n * \ttype: 'button',\n * \tmodel: new Model( {\n * \t\twithText: true,\n * \t\tlabel: 'First item',\n * \t\tlabelStyle: 'color: red'\n * \t} )\n * } );\n *\n * items.add( {\n * \t type: 'button',\n * \t model: new Model( {\n * \t\twithText: true,\n * \t\tlabel: 'Second item',\n * \t\tlabelStyle: 'color: green',\n * \t\tclass: 'foo'\n * \t} )\n * } );\n *\n * const dropdown = createDropdown( locale );\n *\n * addListToDropdown( dropdown, items );\n *\n * // Will render a dropdown with a list in the panel containing two items.\n * dropdown.render()\n * document.body.appendChild( dropdown.element );\n * ```\n *\n * The `items` collection passed to this methods controls the presence and attributes of respective\n * {@link module:ui/list/listitemview~ListItemView list items}.\n *\n * **Note:** To improve the accessibility, when a list is added to the dropdown using this helper the dropdown will automatically attempt\n * to focus the first active item (a host to a {@link module:ui/button/buttonview~ButtonView} with\n * {@link module:ui/button/buttonview~ButtonView#isOn} set `true`) or the very first item when none are active.\n *\n * **Note:** List view will be created on first open of the dropdown.\n *\n * See {@link module:ui/dropdown/utils~createDropdown} and {@link module:list/list~List}.\n *\n * @param dropdownView A dropdown instance to which `ListVIew` will be added.\n * @param itemsOrCallback A collection of the list item definitions or a callback returning a list item definitions to populate the list.\n * @param options.ariaLabel Label used by assistive technologies to describe list element.\n * @param options.role Will be reflected by the `role` DOM attribute in `ListVIew` and used by assistive technologies.\n */\nexport function addListToDropdown(\n\tdropdownView: DropdownView,\n\titemsOrCallback: Collection<ListDropdownItemDefinition> | ( () => Collection<ListDropdownItemDefinition> ),\n\toptions: {\n\t\tariaLabel?: string;\n\t\trole?: string;\n\t} = {}\n): void {\n\tif ( dropdownView.isOpen ) {\n\t\taddListToOpenDropdown( dropdownView, itemsOrCallback, options );\n\t} else {\n\t\tdropdownView.once(\n\t\t\t'change:isOpen',\n\t\t\t() => addListToOpenDropdown( dropdownView, itemsOrCallback, options ),\n\t\t\t{ priority: 'highest' }\n\t\t);\n\t}\n\n\t// Accessibility: Focus the first active button in the list when the dropdown gets open.\n\tfocusChildOnDropdownOpen( dropdownView, () => dropdownView.listView!.items.find( item => {\n\t\tif ( item instanceof ListItemView ) {\n\t\t\treturn ( item.children.first as any ).isOn;\n\t\t}\n\n\t\treturn false;\n\t} ) );\n}\n\n/**\n * Adds an instance of {@link module:ui/list/listview~ListView} to a dropdown.\n */\nfunction addListToOpenDropdown(\n\tdropdownView: DropdownView,\n\titemsOrCallback: Collection<ListDropdownItemDefinition> | ( () => Collection<ListDropdownItemDefinition> ),\n\toptions: {\n\t\tariaLabel?: string;\n\t\trole?: string;\n\t}\n): void {\n\tconst locale = dropdownView.locale!;\n\tconst listView = dropdownView.listView = new ListView( locale );\n\tconst items = typeof itemsOrCallback == 'function' ? itemsOrCallback() : itemsOrCallback;\n\n\tlistView.ariaLabel = options.ariaLabel;\n\tlistView.role = options.role;\n\n\tbindViewCollectionItemsToDefinitions( dropdownView, listView.items, items, locale );\n\n\tdropdownView.panelView.children.add( listView );\n\n\tlistView.items.delegate( 'execute' ).to( dropdownView );\n}\n\n/**\n * A helper to be used on an existing {@link module:ui/dropdown/dropdownview~DropdownView} that focuses\n * a specific child in DOM when the dropdown {@link module:ui/dropdown/dropdownview~DropdownView#isOpen gets open}.\n *\n * @param dropdownView A dropdown instance to which the focus behavior will be added.\n * @param childSelectorCallback A callback executed when the dropdown gets open. It should return a {@link module:ui/view~View}\n * instance (child of {@link module:ui/dropdown/dropdownview~DropdownView#panelView}) that will get focused or a falsy value.\n * If falsy value is returned, a default behavior of the dropdown will engage focusing the first focusable child in\n * the {@link module:ui/dropdown/dropdownview~DropdownView#panelView}.\n */\nexport function focusChildOnDropdownOpen(\n\tdropdownView: DropdownView,\n\tchildSelectorCallback: () => View | FalsyValue\n): void {\n\tdropdownView.on<ObservableChangeEvent>( 'change:isOpen', () => {\n\t\tif ( !dropdownView.isOpen ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst childToFocus: ( View & { focus?: () => void } ) | FalsyValue = childSelectorCallback();\n\n\t\tif ( !childToFocus ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( typeof childToFocus.focus === 'function' ) {\n\t\t\tchildToFocus.focus();\n\t\t} else {\n\t\t\t/**\n\t\t\t * The child view of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown} is missing the `focus()` method\n\t\t\t * and could not be focused when the dropdown got {@link module:ui/dropdown/dropdownview~DropdownView#isOpen open}.\n\t\t\t *\n\t\t\t * Making the content of a dropdown focusable in this case greatly improves the accessibility. Please make the view instance\n\t\t\t * implements the {@link module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable focusable interface} for the best user\n\t\t\t * experience.\n\t\t\t *\n\t\t\t * @error ui-dropdown-focus-child-on-open-child-missing-focus\n\t\t\t * @param {module:ui/view~View} view\n\t\t\t */\n\t\t\tlogWarning( 'ui-dropdown-focus-child-on-open-child-missing-focus', { view: childToFocus } );\n\t\t}\n\n\t// * Let the panel show up first (do not focus an invisible element).\n\t// * Execute after focusDropdownPanelOnOpen(). See focusDropdownPanelOnOpen() to learn more.\n\t}, { priority: priorities.low - 10 } );\n}\n\n/**\n * Add a set of default behaviors to dropdown view.\n */\nfunction addDefaultBehaviors( dropdownView: DropdownView ) {\n\tcloseDropdownOnClickOutside( dropdownView );\n\tcloseDropdownOnExecute( dropdownView );\n\tcloseDropdownOnBlur( dropdownView );\n\tfocusDropdownContentsOnArrows( dropdownView );\n\tfocusDropdownButtonOnClose( dropdownView );\n\tfocusDropdownPanelOnOpen( dropdownView );\n}\n\n/**\n * Adds a behavior to a dropdownView that closes opened dropdown when user clicks outside the dropdown.\n */\nfunction closeDropdownOnClickOutside( dropdownView: DropdownView ) {\n\tclickOutsideHandler( {\n\t\temitter: dropdownView,\n\t\tactivator: () => dropdownView.isRendered && dropdownView.isOpen,\n\t\tcallback: () => {\n\t\t\tdropdownView.isOpen = false;\n\t\t},\n\t\tcontextElements: () => [\n\t\t\tdropdownView.element!,\n\t\t\t// Include all elements connected to the dropdown's focus tracker, but exclude those that are direct children\n\t\t\t// of DropdownView#element. They would be identified as descendants of #element anyway upon clicking and would\n\t\t\t// not contribute to the logic.\n\t\t\t...getFocusTrackerTreeElements( dropdownView.focusTracker ).filter( element => !dropdownView.element!.contains( element ) )\n\t\t]\n\t} );\n}\n\n/**\n * Returns all DOM elements connected to a DropdownView's focus tracker, either directly (same DOM sub-tree)\n * or indirectly (external views registered in the focus tracker).\n */\nfunction getFocusTrackerTreeElements( focusTracker: FocusTracker ): Array<Element> {\n\treturn [\n\t\t...focusTracker.elements,\n\t\t...focusTracker.externalViews.flatMap( view => getFocusTrackerTreeElements( view.focusTracker ) )\n\t];\n}\n\n/**\n * Adds a behavior to a dropdownView that closes the dropdown view on \"execute\" event.\n */\nfunction closeDropdownOnExecute( dropdownView: DropdownView ) {\n\t// Close the dropdown when one of the list items has been executed.\n\tdropdownView.on<ButtonExecuteEvent>( 'execute', evt => {\n\t\t// Toggling a switch button view should not close the dropdown.\n\t\tif ( evt.source instanceof SwitchButtonView ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdropdownView.isOpen = false;\n\t} );\n}\n\n/**\n * Adds a behavior to a dropdown view that closes opened dropdown when it loses focus.\n */\nfunction closeDropdownOnBlur( dropdownView: DropdownView ) {\n\tdropdownView.focusTracker.on<ObservableChangeEvent<boolean>>( 'change:isFocused', ( evt, name, isFocused ) => {\n\t\tif ( isFocused || !dropdownView.isOpen ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdropdownView.isOpen = false;\n\t} );\n}\n\n/**\n * Adds a behavior to a dropdownView that focuses the dropdown's panel view contents on keystrokes.\n */\nfunction focusDropdownContentsOnArrows( dropdownView: DropdownView ) {\n\t// If the dropdown panel is already open, the arrow down key should focus the first child of the #panelView.\n\tdropdownView.keystrokes.set( 'arrowdown', ( data, cancel ) => {\n\t\tif ( dropdownView.isOpen ) {\n\t\t\tdropdownView.panelView.focus();\n\t\t\tcancel();\n\t\t}\n\t} );\n\n\t// If the dropdown panel is already open, the arrow up key should focus the last child of the #panelView.\n\tdropdownView.keystrokes.set( 'arrowup', ( data, cancel ) => {\n\t\tif ( dropdownView.isOpen ) {\n\t\t\tdropdownView.panelView.focusLast();\n\t\t\tcancel();\n\t\t}\n\t} );\n}\n\n/**\n * Adds a behavior that focuses the #buttonView when the dropdown was closed but focus was within the #panelView element.\n * This makes sure the focus is never lost.\n */\nfunction focusDropdownButtonOnClose( dropdownView: DropdownView ) {\n\tdropdownView.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( evt, name, isOpen ) => {\n\t\tif ( isOpen ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst elements = dropdownView.focusTracker.elements;\n\n\t\t// If the dropdown was closed, move the focus back to the button (#12125).\n\t\t// Don't touch the focus, if it moved somewhere else (e.g. moved to the editing root on #execute) (#12178).\n\t\t// Note: Don't use the state of the DropdownView#focusTracker here. It fires #blur with the timeout.\n\t\tif ( elements.some( element => element.contains( global.document.activeElement ) ) ) {\n\t\t\tdropdownView.buttonView.focus();\n\t\t}\n\t} );\n}\n\n/**\n * Adds a behavior that focuses the #panelView when dropdown gets open (accessibility).\n */\nfunction focusDropdownPanelOnOpen( dropdownView: DropdownView ) {\n\tdropdownView.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( evt, name, isOpen ) => {\n\t\tif ( !isOpen ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Focus the first item in the dropdown when the dropdown opened.\n\t\tdropdownView.panelView.focus();\n\n\t// * Let the panel show up first (do not focus an invisible element).\n\t// * Also, execute before focusChildOnDropdownOpen() to make sure this helper does not break the\n\t//   focus of a specific child by kicking in too late and resetting the focus in the panel.\n\t}, { priority: 'low' } );\n}\n\n/**\n * This helper populates a dropdown list with items and groups according to the\n * collection of item definitions. A permanent binding is created in this process allowing\n * dynamic management of the dropdown list content.\n *\n * @param dropdownView\n * @param listItems\n * @param definitions\n * @param locale\n */\nfunction bindViewCollectionItemsToDefinitions(\n\tdropdownView: DropdownView,\n\tlistItems: ViewCollection,\n\tdefinitions: Collection<ListDropdownItemDefinition>,\n\tlocale: Locale\n) {\n\t// List item checkboxes have a reserved space for the check icon, so we need to know if there are any checkboxes in the list\n\t// to adjust the layout accordingly. It'd look weird if the items on the list were not aligned horizontally.\n\t//\n\t// Possible theoretical performance problem if many items are added one by one, as this will be called for each item.\n\tlistItems.on( 'change', () => {\n\t\t// Filter-map. Check all items, leave only these that have buttons and return the buttons.\n\t\tconst listItemButtons = [ ...listItems ].reduce<Array<ListItemButtonView>>( ( acc, item ) => {\n\t\t\tif ( item instanceof ListItemView && item.children.first instanceof ListItemButtonView ) {\n\t\t\t\tacc.push( item.children.first );\n\t\t\t}\n\n\t\t\treturn acc;\n\t\t}, [] );\n\n\t\tconst hasAnyCheckboxOnList = listItemButtons.some( button => button.isToggleable );\n\n\t\tlistItemButtons.forEach( item => {\n\t\t\titem.hasCheckSpace = hasAnyCheckboxOnList;\n\t\t} );\n\t} );\n\n\tlistItems.bindTo( definitions ).using( def => {\n\t\tif ( def.type === 'separator' ) {\n\t\t\treturn new ListSeparatorView( locale );\n\t\t} else if ( def.type === 'group' ) {\n\t\t\tconst groupView = new ListItemGroupView( locale );\n\n\t\t\tgroupView.set( { label: def.label } );\n\n\t\t\tbindViewCollectionItemsToDefinitions( dropdownView, groupView.items, def.items, locale );\n\n\t\t\tgroupView.items.delegate( 'execute' ).to( dropdownView );\n\n\t\t\treturn groupView;\n\t\t} else if ( def.type === 'button' || def.type === 'switchbutton' ) {\n\t\t\tconst isToggleable = def.model.role === 'menuitemcheckbox' || def.model.role === 'menuitemradio';\n\t\t\tconst listItemView = new ListItemView( locale );\n\n\t\t\tlet buttonView: ButtonView;\n\n\t\t\tif ( def.type === 'button' ) {\n\t\t\t\tbuttonView = new ListItemButtonView( locale );\n\t\t\t\tbuttonView.set( {\n\t\t\t\t\tisToggleable\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tbuttonView = new SwitchButtonView( locale );\n\t\t\t}\n\n\t\t\t// Bind all model properties to the button view.\n\t\t\tbuttonView.bind( ...Object.keys( def.model ) as Array<keyof ButtonView> ).to( def.model );\n\t\t\tbuttonView.delegate( 'execute' ).to( listItemView );\n\n\t\t\tlistItemView.children.add( buttonView );\n\n\t\t\treturn listItemView;\n\t\t}\n\n\t\treturn null;\n\t} );\n}\n\n/**\n * A definition of the list item used by the {@link module:ui/dropdown/utils~addListToDropdown}\n * utility.\n */\nexport type ListDropdownItemDefinition = ListDropdownSeparatorDefinition | ListDropdownButtonDefinition | ListDropdownGroupDefinition;\n\n/**\n * A definition of the 'separator' list item.\n */\nexport type ListDropdownSeparatorDefinition = {\n\ttype: 'separator';\n};\n\n/**\n * A definition of the 'button' or 'switchbutton' list item.\n */\nexport type ListDropdownButtonDefinition = {\n\ttype: 'button' | 'switchbutton';\n\n\t/**\n\t * Model of the item. Its properties fuel the newly created list item (or its children, depending on the `type`).\n\t */\n\tmodel: Model;\n};\n\n/**\n * A definition of the group inside the list. A group can contain one or more list items (buttons).\n */\nexport type ListDropdownGroupDefinition = {\n\ttype: 'group';\n\n\t/**\n\t * The visible label of the group.\n\t */\n\tlabel: string;\n\n\t/**\n\t * The collection of the child list items inside this group.\n\t */\n\titems: Collection<ListDropdownButtonDefinition>;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/labeledfield/utils\n */\n\nimport InputTextView from '../inputtext/inputtextview.js';\nimport InputNumberView from '../inputnumber/inputnumberview.js';\nimport TextareaView from '../textarea/textareaview.js';\nimport { createDropdown } from '../dropdown/utils.js';\n\nimport type DropdownView from '../dropdown/dropdownview.js';\nimport type { InputViewInputEvent } from '../input/inputview.js';\nimport type { LabeledFieldViewCreator } from './labeledfieldview.js';\n\n/**\n * A helper for creating labeled inputs.\n *\n * It creates an instance of a {@link module:ui/inputtext/inputtextview~InputTextView input text} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in DOM.\n *\n * The helper does the following:\n *\n * * It sets input's `id` and `ariaDescribedById` attributes.\n * * It binds input's `isReadOnly` to the labeled view.\n * * It binds input's `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when user starts typing in the input.\n *\n * Usage:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, createLabeledInputText );\n * console.log( labeledInputView.fieldView ); // A text input instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view's label} and the input.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view's status} and the input.\n * @returns The input text view instance.\n */\nconst createLabeledInputText: LabeledFieldViewCreator<InputTextView> = ( labeledFieldView, viewUid, statusUid ) => {\n\tconst inputView = new InputTextView( labeledFieldView.locale );\n\n\tinputView.set( {\n\t\tid: viewUid,\n\t\tariaDescribedById: statusUid\n\t} );\n\n\tinputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );\n\tinputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );\n\n\tinputView.on<InputViewInputEvent>( 'input', () => {\n\t\t// UX: Make the error text disappear and disable the error indicator as the user\n\t\t// starts fixing the errors.\n\t\tlabeledFieldView.errorText = null;\n\t} );\n\n\tlabeledFieldView.bind( 'isEmpty', 'isFocused', 'placeholder' ).to( inputView );\n\n\treturn inputView;\n};\n\n/**\n * A helper for creating labeled number inputs.\n *\n * It creates an instance of a {@link module:ui/inputnumber/inputnumberview~InputNumberView input number} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in DOM.\n *\n * The helper does the following:\n *\n * * It sets input's `id` and `ariaDescribedById` attributes.\n * * It binds input's `isReadOnly` to the labeled view.\n * * It binds input's `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when user starts typing in the input.\n *\n * Usage:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, createLabeledInputNumber );\n * console.log( labeledInputView.fieldView ); // A number input instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view's label} and the input.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view's status} and the input.\n * @returns The input number view instance.\n */\nconst createLabeledInputNumber: LabeledFieldViewCreator<InputNumberView> = ( labeledFieldView, viewUid, statusUid ) => {\n\tconst inputView = new InputNumberView( labeledFieldView.locale );\n\n\tinputView.set( {\n\t\tid: viewUid,\n\t\tariaDescribedById: statusUid,\n\t\tinputMode: 'numeric'\n\t} );\n\n\tinputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );\n\tinputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );\n\n\tinputView.on<InputViewInputEvent>( 'input', () => {\n\t\t// UX: Make the error text disappear and disable the error indicator as the user\n\t\t// starts fixing the errors.\n\t\tlabeledFieldView.errorText = null;\n\t} );\n\n\tlabeledFieldView.bind( 'isEmpty', 'isFocused', 'placeholder' ).to( inputView );\n\n\treturn inputView;\n};\n\n/**\n * A helper for creating labeled textarea.\n *\n * It creates an instance of a {@link module:ui/textarea/textareaview~TextareaView textarea} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in DOM.\n *\n * The helper does the following:\n *\n * * It sets textarea's `id` and `ariaDescribedById` attributes.\n * * It binds textarea's `isReadOnly` to the labeled view.\n * * It binds textarea's `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when user starts typing in the textarea.\n *\n * Usage:\n *\n * ```ts\n * const labeledTextarea = new LabeledFieldView( locale, createLabeledTextarea );\n * console.log( labeledTextarea.fieldView ); // A textarea instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view's label} and the textarea.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view's status} and the textarea.\n * @returns The textarea view instance.\n */\nconst createLabeledTextarea: LabeledFieldViewCreator<TextareaView> = ( labeledFieldView, viewUid, statusUid ) => {\n\tconst textareaView = new TextareaView( labeledFieldView.locale );\n\n\ttextareaView.set( {\n\t\tid: viewUid,\n\t\tariaDescribedById: statusUid\n\t} );\n\n\ttextareaView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );\n\ttextareaView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );\n\n\ttextareaView.on<InputViewInputEvent>( 'input', () => {\n\t\t// UX: Make the error text disappear and disable the error indicator as the user\n\t\t// starts fixing the errors.\n\t\tlabeledFieldView.errorText = null;\n\t} );\n\n\tlabeledFieldView.bind( 'isEmpty', 'isFocused', 'placeholder' ).to( textareaView );\n\n\treturn textareaView;\n};\n\n/**\n * A helper for creating labeled dropdowns.\n *\n * It creates an instance of a {@link module:ui/dropdown/dropdownview~DropdownView dropdown} that is\n * logically related to a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled field view}.\n *\n * The helper does the following:\n *\n * * It sets dropdown's `id` and `ariaDescribedById` attributes.\n * * It binds input's `isEnabled` to the labeled view.\n *\n * Usage:\n *\n * ```ts\n * const labeledInputView = new LabeledFieldView( locale, createLabeledDropdown );\n * console.log( labeledInputView.fieldView ); // A dropdown instance.\n * ```\n *\n * @param labeledFieldView The instance of the labeled field view.\n * @param viewUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#labelView labeled view label} and the dropdown.\n * @param statusUid A UID string that allows DOM logical connection between the\n * {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView#statusView labeled view status} and the dropdown.\n * @returns The dropdown view instance.\n */\nconst createLabeledDropdown: LabeledFieldViewCreator<DropdownView> = ( labeledFieldView, viewUid, statusUid ) => {\n\tconst dropdownView = createDropdown( labeledFieldView.locale );\n\n\tdropdownView.set( {\n\t\tid: viewUid,\n\t\tariaDescribedById: statusUid\n\t} );\n\n\tdropdownView.bind( 'isEnabled' ).to( labeledFieldView );\n\n\treturn dropdownView;\n};\n\nexport {\n\tcreateLabeledInputNumber,\n\tcreateLabeledInputText,\n\tcreateLabeledTextarea,\n\tcreateLabeledDropdown\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorpicker/colorpickerview\n */\n\nimport { convertColor, convertToHex, registerCustomElement, type ColorPickerViewConfig } from './utils.js';\n\nimport type { HexColor } from '@ckeditor/ckeditor5-core';\nimport { type Locale, global, env } from '@ckeditor/ckeditor5-utils';\nimport { debounce, type DebouncedFunc } from 'lodash-es';\nimport View from '../view.js';\nimport type InputTextView from '../inputtext/inputtextview.js';\nimport type ViewCollection from '../viewcollection.js';\nimport LabeledFieldView from '../labeledfield/labeledfieldview.js';\nimport { createLabeledInputText } from '../labeledfield/utils.js';\n\n// Custom export due to https://github.com/ckeditor/ckeditor5/issues/15698.\nimport { HexBase } from 'vanilla-colorful/lib/entrypoints/hex';\nimport '../../theme/components/colorpicker/colorpicker.css';\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'hex-color-picker': HexBase;\n\t}\n}\n\nconst waitingTime = 150;\n\n/**\n * A class which represents a color picker with an input field for defining custom colors.\n */\nexport default class ColorPickerView extends View {\n\t/**\n\t * Element with saturation and hue sliders.\n\t */\n\tdeclare public picker: HexBase;\n\n\t/**\n\t * Container for a `#` sign prefix and an input for displaying and defining custom colors\n\t * in HEX format.\n\t */\n\tpublic hexInputRow: ColorPickerInputRowView;\n\n\t/**\n\t * Current color selected in the color picker. It can be set by the component itself\n\t * (through the palette or input) or from the outside (e.g. to reflect the current selection color).\n\t */\n\tdeclare public color: string;\n\n\t/**\n\t * List of slider views of the color picker.\n\t */\n\tdeclare public slidersView: ViewCollection<SliderView>;\n\n\t/**\n\t * An internal representation of a color.\n\t *\n\t * Since the picker uses a hex format, that's how we store it.\n\t *\n\t * Since this is unified color format it won't fire a change event if color is changed\n\t * from `#f00` to `#ff0000` (same value, different format).\n\t *\n\t * @observable\n\t * @private\n\t */\n\tdeclare public _hexColor: string;\n\n\t/**\n\t * Debounced function updating the `color` property in the component\n\t * and firing the `ColorPickerColorSelectedEvent`. Executed whenever color in component\n\t * is changed by the user interaction (through the palette or input).\n\t *\n\t * @private\n\t */\n\tprivate _debounceColorPickerEvent: DebouncedFunc<( arg: string ) => void>;\n\n\t/**\n\t * A reference to the configuration of the color picker specified in the constructor.\n\t *\n\t * @private\n\t */\n\tprivate _config: ColorPickerViewConfig;\n\n\t/**\n\t * Creates a view of color picker.\n\t *\n\t * @param locale\n\t * @param config\n\t */\n\tconstructor( locale: Locale | undefined, config: ColorPickerViewConfig = {} ) {\n\t\tsuper( locale );\n\n\t\tthis.set( {\n\t\t\tcolor: '',\n\t\t\t_hexColor: ''\n\t\t} );\n\n\t\tthis.hexInputRow = this._createInputRow();\n\t\tconst children = this.createCollection();\n\n\t\tif ( !config.hideInput ) {\n\t\t\tchildren.add( this.hexInputRow );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck', 'ck-color-picker' ],\n\t\t\t\ttabindex: -1\n\t\t\t},\n\t\t\tchildren\n\t\t} );\n\n\t\tthis._config = config;\n\n\t\tthis._debounceColorPickerEvent = debounce( ( color: string ) => {\n\t\t\t// At first, set the color internally in the component. It's converted to the configured output format.\n\t\t\tthis.set( 'color', color );\n\n\t\t\t// Then let the outside world know that the user changed the color.\n\t\t\tthis.fire<ColorPickerColorSelectedEvent>( 'colorSelected', { color: this.color } );\n\t\t}, waitingTime, {\n\t\t\tleading: true\n\t\t} );\n\n\t\t// The `color` property holds the color in the configured output format.\n\t\t// Ensure it before actually setting the value.\n\t\tthis.on( 'set:color', ( evt, propertyName, newValue ) => {\n\t\t\tevt.return = convertColor( newValue, this._config.format || 'hsl' );\n\t\t} );\n\n\t\t// The `_hexColor` property is bound to the `color` one, but requires conversion.\n\t\tthis.on( 'change:color', () => {\n\t\t\tthis._hexColor = convertColorToCommonHexFormat( this.color );\n\t\t} );\n\n\t\tthis.on( 'change:_hexColor', () => {\n\t\t\t// Update the selected color in the color picker palette when it's not focused.\n\t\t\t// It means the user typed the color in the input.\n\t\t\tif ( document.activeElement !== this.picker ) {\n\t\t\t\tthis.picker.setAttribute( 'color', this._hexColor );\n\t\t\t}\n\n\t\t\t// There has to be two way binding between properties.\n\t\t\t// Extra precaution has to be taken to trigger change back only when the color really changes.\n\t\t\tif ( convertColorToCommonHexFormat( this.color ) != convertColorToCommonHexFormat( this._hexColor ) ) {\n\t\t\t\tthis.color = this._hexColor;\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Renders color picker in the view.\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Extracted to the helper to make it testable.\n\t\tregisterCustomElement( 'hex-color-picker', HexBase );\n\n\t\tthis.picker = global.document.createElement( 'hex-color-picker' );\n\t\tthis.picker.setAttribute( 'class', 'hex-color-picker' );\n\t\tthis.picker.setAttribute( 'tabindex', '-1' );\n\n\t\tthis._createSlidersView();\n\n\t\tif ( this.element ) {\n\t\t\tif ( this.hexInputRow.element ) {\n\t\t\t\tthis.element.insertBefore( this.picker, this.hexInputRow.element );\n\t\t\t} else {\n\t\t\t\tthis.element.appendChild( this.picker );\n\t\t\t}\n\n\t\t\t// Create custom stylesheet with a look of focused pointer in color picker and append it into the color picker shadowDom\n\t\t\tconst styleSheetForFocusedColorPicker = document.createElement( 'style' );\n\n\t\t\tstyleSheetForFocusedColorPicker.textContent = '[role=\"slider\"]:focus [part$=\"pointer\"] {' +\n\t\t\t\t'border: 1px solid #fff;' +\n\t\t\t\t'outline: 1px solid var(--ck-color-focus-border);' +\n\t\t\t\t'box-shadow: 0 0 0 2px #fff;' +\n\t\t\t\t'}';\n\t\t\tthis.picker.shadowRoot!.appendChild( styleSheetForFocusedColorPicker );\n\t\t}\n\n\t\tthis.picker.addEventListener( 'color-changed', event => {\n\t\t\tconst color = event.detail.value;\n\t\t\tthis._debounceColorPickerEvent( color );\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the first pointer in color picker.\n\t *\n\t */\n\tpublic focus(): void {\n\t\t// In some browsers we need to move the focus to the input first.\n\t\t// Otherwise, the color picker doesn't behave as expected.\n\t\t// In FF, after selecting the color via slider, it instantly moves back to the previous color.\n\t\t// In all iOS browsers and desktop Safari, once the saturation slider is moved for the first time,\n\t\t// editor collapses the selection and doesn't apply the color change.\n\t\t// See: https://github.com/cksource/ckeditor5-internal/issues/3245, https://github.com/ckeditor/ckeditor5/issues/14119,\n\t\t// https://github.com/cksource/ckeditor5-internal/issues/3268.\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif ( !this._config.hideInput && ( env.isGecko || env.isiOS || env.isSafari ) ) {\n\t\t\tconst input: LabeledFieldView<InputTextView> = this.hexInputRow!.children.get( 1 )! as LabeledFieldView<InputTextView>;\n\n\t\t\tinput.focus();\n\t\t}\n\n\t\tconst firstSlider = this.slidersView.first!;\n\n\t\tfirstSlider.focus();\n\t}\n\n\t/**\n\t * Creates collection of sliders in color picker.\n\t *\n\t * @private\n\t */\n\tprivate _createSlidersView(): void {\n\t\tconst colorPickersChildren = [ ...this.picker.shadowRoot!.children ] as Array<HTMLElement>;\n\t\tconst sliders = colorPickersChildren.filter( item => item.getAttribute( 'role' ) === 'slider' );\n\n\t\tconst slidersView = sliders.map( slider => {\n\t\t\tconst view = new SliderView( slider );\n\n\t\t\treturn view;\n\t\t} );\n\n\t\tthis.slidersView = this.createCollection();\n\n\t\tslidersView.forEach( item => {\n\t\t\tthis.slidersView.add( item );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates input row for defining custom colors in color picker.\n\t *\n\t * @private\n\t */\n\tprivate _createInputRow(): ColorPickerInputRowView {\n\t\tconst colorInput = this._createColorInput();\n\n\t\treturn new ColorPickerInputRowView( this.locale!, colorInput );\n\t}\n\n\t/**\n\t * Creates the input where user can type or paste the color in hex format.\n\t *\n\t * @private\n\t */\n\tprivate _createColorInput(): LabeledFieldView<InputTextView> {\n\t\tconst labeledInput = new LabeledFieldView( this.locale, createLabeledInputText );\n\t\tconst { t } = this.locale!;\n\n\t\tlabeledInput.set( {\n\t\t\tlabel: t( 'HEX' ),\n\t\t\tclass: 'color-picker-hex-input'\n\t\t} );\n\n\t\tlabeledInput.fieldView.bind( 'value' ).to( this, '_hexColor', pickerColor => {\n\t\t\tif ( labeledInput.isFocused ) {\n\t\t\t\t// Text field shouldn't be updated with color change if the text field is focused.\n\t\t\t\t// Imagine user typing hex code and getting the value of field changed.\n\t\t\t\treturn labeledInput.fieldView.value;\n\t\t\t} else {\n\t\t\t\treturn pickerColor.startsWith( '#' ) ? pickerColor.substring( 1 ) : pickerColor;\n\t\t\t}\n\t\t} );\n\n\t\t// Only accept valid hex colors as input.\n\t\tlabeledInput.fieldView.on( 'input', () => {\n\t\t\tconst inputValue = labeledInput.fieldView.element!.value;\n\n\t\t\tif ( inputValue ) {\n\t\t\t\tconst maybeHexColor = tryParseHexColor( inputValue );\n\n\t\t\t\tif ( maybeHexColor ) {\n\t\t\t\t\t// If so, set the color.\n\t\t\t\t\t// Otherwise, do nothing.\n\t\t\t\t\tthis._debounceColorPickerEvent( maybeHexColor );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\treturn labeledInput;\n\t}\n\n\t/**\n\t * Validates the view and returns `false` when some fields are invalid.\n\t */\n\tpublic isValid(): boolean {\n\t\tconst { t } = this.locale!;\n\n\t\t// If the input is hidden, it's always valid, because there is no way to select\n\t\t// invalid color value using diagram color picker.\n\t\tif ( this._config.hideInput ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.resetValidationStatus();\n\n\t\t// One error per field is enough.\n\t\tif ( !this.hexInputRow.getParsedColor() ) {\n\t\t\t// Apply updated error.\n\t\t\tthis.hexInputRow.inputView.errorText = t( 'Please enter a valid color (e.g. \"ff0000\").' );\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Cleans up the supplementary error and information text of input inside the {@link #hexInputRow}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */\n\tpublic resetValidationStatus(): void {\n\t\tthis.hexInputRow.inputView.errorText = null;\n\t}\n}\n\n// Converts any color format to a unified hex format.\n//\n// @param inputColor\n// @returns An unified hex string.\nfunction convertColorToCommonHexFormat( inputColor: string ): string {\n\tlet ret = convertToHex( inputColor );\n\n\tif ( !ret ) {\n\t\tret = '#000';\n\t}\n\n\tif ( ret.length === 4 ) {\n\t\t// Unfold shortcut format.\n\t\tret = '#' + [ ret[ 1 ], ret[ 1 ], ret[ 2 ], ret[ 2 ], ret[ 3 ], ret[ 3 ] ].join( '' );\n\t}\n\n\treturn ret.toLowerCase();\n}\n\n// View abstraction over pointer in color picker.\nclass SliderView extends View {\n\t/**\n\t * @param element HTML element of slider in color picker.\n\t */\n\tconstructor( element: HTMLElement ) {\n\t\tsuper();\n\t\tthis.element = element;\n\t}\n\n\t/**\n\t * Focuses element.\n\t */\n\tpublic focus(): void {\n\t\tthis.element!.focus();\n\t}\n}\n\n// View abstraction over the `#` character before color input.\nclass HashView extends View {\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-color-picker__hash-view'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: '#'\n\t\t} );\n\t}\n}\n\n// The class representing a row containing hex color input field.\n// **Note**: For now this class is private. When more use cases appear (beyond `ckeditor5-table` and `ckeditor5-image`),\n// it will become a component in `ckeditor5-ui`.\n//\n// @private\nclass ColorPickerInputRowView extends View {\n\t/**\n\t * A collection of row items (buttons, dropdowns, etc.).\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * Hex input view element.\n\t */\n\tpublic readonly inputView: LabeledFieldView<InputTextView>;\n\n\t/**\n\t * Creates an instance of the form row class.\n\t *\n\t * @param locale The locale instance.\n\t * @param inputView Hex color input element.\n\t */\n\tconstructor( locale: Locale, inputView: LabeledFieldView<InputTextView> ) {\n\t\tsuper( locale );\n\n\t\tthis.inputView = inputView;\n\t\tthis.children = this.createCollection( [\n\t\t\tnew HashView(),\n\t\t\tthis.inputView\n\t\t] );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-color-picker__row'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * Returns false if color input value is not in hex format.\n\t */\n\tpublic getParsedColor(): HexColor | null {\n\t\treturn tryParseHexColor( this.inputView.fieldView.element!.value );\n\t}\n}\n\n/**\n * An event fired whenever the color was selected through the color picker palette\n * or the color picker input.\n *\n * This even fires only when the user changes the color. It does not fire when the color\n * is changed programmatically, e.g. via\n * {@link module:ui/colorpicker/colorpickerview~ColorPickerView#color}.\n *\n * @eventName ~ColorPickerView#colorSelected\n */\nexport type ColorPickerColorSelectedEvent = {\n\tname: 'colorSelected';\n\targs: [ {\n\t\tcolor: string;\n\t} ];\n};\n\n/**\n * Trim spaces from provided color and check if hex is valid.\n *\n * @param color Unsafe color string.\n * @returns Null if provided color is not hex value.\n * @export\n */\nexport function tryParseHexColor<S extends string>( color: S | null | undefined ): HexColor<S> | null {\n\tif ( !color ) {\n\t\treturn null;\n\t}\n\n\tconst hashLessColor = color.trim().replace( /^#/, '' );\n\n\t// Incorrect length.\n\tif ( ![ 3, 4, 6, 8 ].includes( hashLessColor.length ) ) {\n\t\treturn null;\n\t}\n\n\t// Incorrect characters.\n\tif ( !/^(([0-9a-fA-F]{2}){3,4}|([0-9a-fA-F]){3,4})$/.test( hashLessColor ) ) {\n\t\treturn null;\n\t}\n\n\treturn `#${ hashLessColor }` as `#${ S }`;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorselector/documentcolorcollection\n */\n\nimport type { ColorDefinition } from '../colorgrid/colorgridview.js';\nimport {\n\tCollection,\n\tObservableMixin,\n\ttype CollectionAddEvent,\n\ttype CollectionRemoveEvent,\n\ttype CollectionChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\n/**\n * A collection to store document colors. It enforces colors to be unique.\n */\nexport default class DocumentColorCollection extends /* #__PURE__ */ ObservableMixin( Collection<ColorDefinition> ) {\n\t/**\n\t * Indicates whether the document color collection is empty.\n\t *\n\t * @observable\n\t */\n\tdeclare public readonly isEmpty: boolean;\n\n\tconstructor( options?: any ) {\n\t\tsuper( options );\n\n\t\tthis.set( 'isEmpty', true );\n\n\t\tthis.on( 'change', () => {\n\t\t\tthis.set( 'isEmpty', this.length === 0 );\n\t\t} );\n\t}\n\n\t/**\n\t * Adds a color to the document color collection.\n\t *\n\t * This method ensures that no color duplicates are inserted (compared using\n\t * the color value of the {@link module:ui/colorgrid/colorgridview~ColorDefinition}).\n\t *\n\t * If the item does not have an ID, it will be automatically generated and set on the item.\n\t *\n\t * @param index The position of the item in the collection. The item is pushed to the collection when `index` is not specified.\n\t * @fires add\n\t * @fires change\n\t */\n\tpublic override add( item: ColorDefinition, index?: number ): this {\n\t\tif ( this.find( element => element.color === item.color ) ) {\n\t\t\t// No duplicates are allowed.\n\t\t\treturn this;\n\t\t}\n\n\t\treturn super.add( item, index );\n\t}\n\n\t/**\n\t * Checks if an object with given colors is present in the document color collection.\n\t */\n\tpublic hasColor( color: string ): boolean {\n\t\treturn !!this.find( item => item.color === color );\n\t}\n}\n\n/**\n * Fired when the collection was changed due to adding or removing items.\n *\n * @eventName ~DocumentColorCollection#change\n * @param data Changed items.\n */\nexport type DocumentColorCollectionChangeEvent = CollectionChangeEvent;\n\n/**\n * Fired when an item is added to the collection.\n *\n * @eventName ~DocumentColorCollection#add\n * @param item The added item.\n * @param index An index where the addition occurred.\n */\nexport type DocumentColorCollectionAddEvent = CollectionAddEvent;\n\n/**\n * Fired when an item is removed from the collection.\n *\n * @eventName ~DocumentColorCollection#remove\n * @param item The removed item.\n * @param index Index from which item was removed.\n */\nexport type DocumentColorCollectionRemoveEvent = CollectionRemoveEvent;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorselector/colorgridsfragmentview\n */\n\nimport View from '../view.js';\nimport ButtonView from '../button/buttonview.js';\nimport ColorGridView, { type ColorDefinition } from '../colorgrid/colorgridview.js';\nimport ColorTileView from '../colorgrid/colortileview.js';\nimport Template from '../template.js';\n\nimport DocumentColorCollection from './documentcolorcollection.js';\n\nimport type { Model } from '@ckeditor/ckeditor5-engine';\nimport type { FocusTracker, Locale } from '@ckeditor/ckeditor5-utils';\nimport type ViewCollection from '../viewcollection.js';\nimport type { FocusableView } from '../focuscycler.js';\nimport type { ColorSelectorExecuteEvent, ColorSelectorColorPickerShowEvent } from './colorselectorview.js';\nimport { icons } from '@ckeditor/ckeditor5-core';\n\n/**\n * One of the fragments of {@link module:ui/colorselector/colorselectorview~ColorSelectorView}.\n *\n * It provides a UI that allows users to select colors from the a predefined set and from existing document colors.\n *\n * It consists of the following sub–components:\n *\n * * A \"Remove color\" button,\n * * A static {@link module:ui/colorgrid/colorgridview~ColorGridView} of colors defined in the configuration,\n * * A dynamic {@link module:ui/colorgrid/colorgridview~ColorGridView} of colors used in the document.\n * * If color picker is configured, the \"Color Picker\" button is visible too.\n */\nexport default class ColorGridsFragmentView extends View {\n\t/**\n\t * A collection of the children of the table.\n\t */\n\tpublic readonly items: ViewCollection;\n\n\t/**\n\t * An array with objects representing colors to be displayed in the grid.\n\t */\n\tpublic colorDefinitions: Array<ColorDefinition>;\n\n\t/**\n\t * Tracks information about the DOM focus in the list.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * The number of columns in the color grid.\n\t */\n\tpublic columns: number;\n\n\t/**\n\t * Preserves the reference to {@link module:ui/colorselector/documentcolorcollection~DocumentColorCollection} used to collect\n\t * definitions that store the document colors.\n\t *\n\t * @readonly\n\t */\n\tpublic documentColors: DocumentColorCollection;\n\n\t/**\n\t * The maximum number of colors in the document colors section.\n\t * If it equals 0, the document colors section is not added.\n\t *\n\t * @readonly\n\t */\n\tpublic documentColorsCount?: number;\n\n\t/**\n\t * Keeps the value of the command associated with the table for the current selection.\n\t */\n\tdeclare public selectedColor: string;\n\n\t/**\n\t * Preserves the reference to {@link module:ui/colorgrid/colorgridview~ColorGridView} used to create\n\t * the default (static) color set.\n\t *\n\t * The property is loaded once the the parent dropdown is opened the first time.\n\t *\n\t * @readonly\n\t */\n\tpublic staticColorsGrid: ColorGridView | undefined;\n\n\t/**\n\t * Preserves the reference to {@link module:ui/colorgrid/colorgridview~ColorGridView} used to create\n\t * the document colors. It remains undefined if the document colors feature is disabled.\n\t *\n\t * The property is loaded once the the parent dropdown is opened the first time.\n\t *\n\t * @readonly\n\t */\n\tpublic documentColorsGrid: ColorGridView | undefined;\n\n\t/**\n\t * The \"Color picker\" button view.\n\t */\n\tpublic colorPickerButtonView?: ButtonView;\n\n\t/**\n\t * The \"Remove color\" button view.\n\t */\n\tpublic removeColorButtonView: ButtonView;\n\n\t/**\n\t * The property which is responsible for is component visible or not.\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * A collection of views that can be focused in the view.\n\t *\n\t * @readonly\n\t */\n\tprotected _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * Document color section's label.\n\t *\n\t * @readonly\n\t */\n\tprivate _documentColorsLabel?: string;\n\n\t/**\n\t * The label of the button responsible for removing color attributes.\n\t */\n\tprivate _removeButtonLabel: string;\n\n\t/**\n\t * The label of the button responsible for switching to the color picker component.\n\t */\n\tprivate _colorPickerLabel: string;\n\n\t/**\n\t * Creates an instance of the view.\n\t *\n\t * @param locale The localization services instance.\n\t * @param colors An array with definitions of colors to be displayed in the table.\n\t * @param columns The number of columns in the color grid.\n\t * @param removeButtonLabel The label of the button responsible for removing the color.\n\t * @param colorPickerLabel The label of the button responsible for color picker appearing.\n\t * @param documentColorsLabel The label for the section with the document colors.\n\t * @param documentColorsCount The number of colors in the document colors section inside the color dropdown.\n\t * @param focusTracker Tracks information about the DOM focus in the list.\n\t * @param focusables A collection of views that can be focused in the view.\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\t{\n\t\t\tcolors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount,\n\t\t\tcolorPickerLabel, focusTracker, focusables\n\t\t}: {\n\t\t\tcolors: Array<ColorDefinition>;\n\t\t\tcolumns: number;\n\t\t\tremoveButtonLabel: string;\n\t\t\tcolorPickerLabel: string;\n\t\t\tdocumentColorsLabel?: string;\n\t\t\tdocumentColorsCount?: number;\n\t\t\tfocusTracker: FocusTracker;\n\t\t\tfocusables: ViewCollection<FocusableView>;\n\t\t}\n\t) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'isVisible', true );\n\n\t\tthis.focusTracker = focusTracker;\n\t\tthis.items = this.createCollection();\n\t\tthis.colorDefinitions = colors;\n\t\tthis.columns = columns;\n\t\tthis.documentColors = new DocumentColorCollection();\n\t\tthis.documentColorsCount = documentColorsCount;\n\n\t\tthis._focusables = focusables;\n\t\tthis._removeButtonLabel = removeButtonLabel;\n\t\tthis._colorPickerLabel = colorPickerLabel;\n\t\tthis._documentColorsLabel = documentColorsLabel;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-color-grids-fragment',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.items\n\t\t} );\n\n\t\tthis.removeColorButtonView = this._createRemoveColorButton();\n\n\t\tthis.items.add( this.removeColorButtonView );\n\t}\n\n\t/**\n\t * Scans through the editor model and searches for text node attributes with the given attribute name.\n\t * Found entries are set as document colors.\n\t *\n\t * All the previously stored document colors will be lost in the process.\n\t *\n\t * @param model The model used as a source to obtain the document colors.\n\t * @param attributeName Determines the name of the related model's attribute for a given dropdown.\n\t */\n\tpublic updateDocumentColors( model: Model, attributeName: string ): void {\n\t\tconst document = model.document;\n\t\tconst maxCount = this.documentColorsCount;\n\n\t\tthis.documentColors.clear();\n\n\t\tfor ( const root of document.getRoots() ) {\n\t\t\tconst range = model.createRangeIn( root );\n\n\t\t\tfor ( const node of range.getItems() ) {\n\t\t\t\tif ( node.is( '$textProxy' ) && node.hasAttribute( attributeName ) ) {\n\t\t\t\t\tthis._addColorToDocumentColors( node.getAttribute( attributeName ) as string );\n\n\t\t\t\t\tif ( this.documentColors.length >= maxCount! ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Refreshes the state of the selected color in one or both {@link module:ui/colorgrid/colorgridview~ColorGridView}s\n\t * available in the {@link module:ui/colorselector/colorselectorview~ColorSelectorView}. It guarantees that the selection will\n\t * occur only in one of them.\n\t */\n\tpublic updateSelectedColors(): void {\n\t\tconst documentColorsGrid = this.documentColorsGrid;\n\t\tconst staticColorsGrid = this.staticColorsGrid!;\n\t\tconst selectedColor = this.selectedColor;\n\n\t\tstaticColorsGrid.selectedColor = selectedColor;\n\n\t\tif ( documentColorsGrid ) {\n\t\t\tdocumentColorsGrid.selectedColor = selectedColor;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.staticColorsGrid = this._createStaticColorsGrid();\n\n\t\tthis.items.add( this.staticColorsGrid );\n\n\t\tif ( this.documentColorsCount ) {\n\t\t\t// Create a label for document colors.\n\t\t\tconst bind = Template.bind( this.documentColors, this.documentColors );\n\t\t\tconst label = new View( this.locale );\n\t\t\tlabel.setTemplate( {\n\t\t\t\ttag: 'span',\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: [\n\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t'ck-color-grid__label',\n\t\t\t\t\t\tbind.if( 'isEmpty', 'ck-hidden' )\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\tchildren: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttext: this._documentColorsLabel\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t} );\n\t\t\tthis.items.add( label );\n\t\t\tthis.documentColorsGrid = this._createDocumentColorsGrid();\n\n\t\t\tthis.items.add( this.documentColorsGrid );\n\t\t}\n\t\tthis._createColorPickerButton();\n\n\t\tthis._addColorSelectorElementsToFocusTracker();\n\t}\n\n\t/**\n\t * Focuses the component.\n\t */\n\tpublic focus(): void {\n\t\tthis.removeColorButtonView.focus();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Handles displaying the color picker button (if it was previously created) and making it focusable.\n\t */\n\tpublic addColorPickerButton(): void {\n\t\tif ( this.colorPickerButtonView ) {\n\t\t\tthis.items.add( this.colorPickerButtonView );\n\t\t\tthis.focusTracker.add( this.colorPickerButtonView.element! );\n\t\t\tthis._focusables.add( this.colorPickerButtonView );\n\t\t}\n\t}\n\n\t/**\n\t * Adds color selector elements to focus tracker.\n\t */\n\tprivate _addColorSelectorElementsToFocusTracker(): void {\n\t\tthis.focusTracker.add( this.removeColorButtonView.element! );\n\t\tthis._focusables.add( this.removeColorButtonView );\n\n\t\tif ( this.staticColorsGrid ) {\n\t\t\tthis.focusTracker.add( this.staticColorsGrid.element! );\n\t\t\tthis._focusables.add( this.staticColorsGrid );\n\t\t}\n\n\t\tif ( this.documentColorsGrid ) {\n\t\t\tthis.focusTracker.add( this.documentColorsGrid.element! );\n\t\t\tthis._focusables.add( this.documentColorsGrid );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the button responsible for displaying the color picker component.\n\t */\n\tprivate _createColorPickerButton(): void {\n\t\tthis.colorPickerButtonView = new ButtonView();\n\n\t\tthis.colorPickerButtonView.set( {\n\t\t\tlabel: this._colorPickerLabel,\n\t\t\twithText: true,\n\t\t\ticon: icons.colorPalette,\n\t\t\tclass: 'ck-color-selector__color-picker'\n\t\t} );\n\n\t\tthis.colorPickerButtonView.on( 'execute', () => {\n\t\t\tthis.fire<ColorSelectorColorPickerShowEvent>( 'colorPicker:show' );\n\t\t} );\n\t}\n\n\t/**\n\t * Adds the remove color button as a child of the current view.\n\t */\n\tprivate _createRemoveColorButton(): ButtonView {\n\t\tconst buttonView = new ButtonView();\n\n\t\tbuttonView.set( {\n\t\t\twithText: true,\n\t\t\ticon: icons.eraser,\n\t\t\tlabel: this._removeButtonLabel\n\t\t} );\n\n\t\tbuttonView.class = 'ck-color-selector__remove-color';\n\t\tbuttonView.on( 'execute', () => {\n\t\t\tthis.fire( 'execute', {\n\t\t\t\tvalue: null,\n\t\t\t\tsource: 'removeColorButton'\n\t\t\t} );\n\t\t} );\n\n\t\tbuttonView.render();\n\n\t\treturn buttonView;\n\t}\n\n\t/**\n\t * Creates a static color grid based on the editor configuration.\n\t */\n\tprivate _createStaticColorsGrid(): ColorGridView {\n\t\tconst colorGrid = new ColorGridView( this.locale, {\n\t\t\tcolorDefinitions: this.colorDefinitions,\n\t\t\tcolumns: this.columns\n\t\t} );\n\n\t\tcolorGrid.on( 'execute', ( evt, data ) => {\n\t\t\tthis.fire<ColorSelectorExecuteEvent>( 'execute', {\n\t\t\t\tvalue: data.value,\n\t\t\t\tsource: 'staticColorsGrid'\n\t\t\t} );\n\t\t} );\n\n\t\treturn colorGrid;\n\t}\n\n\t/**\n\t * Creates the document colors section view and binds it to {@link #documentColors}.\n\t */\n\tprivate _createDocumentColorsGrid(): ColorGridView {\n\t\tconst bind = Template.bind( this.documentColors, this.documentColors );\n\t\tconst documentColorsGrid = new ColorGridView( this.locale, {\n\t\t\tcolumns: this.columns\n\t\t} );\n\n\t\tdocumentColorsGrid.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: bind.if( 'isEmpty', 'ck-hidden' )\n\t\t\t}\n\t\t} );\n\n\t\tdocumentColorsGrid.items.bindTo( this.documentColors ).using(\n\t\t\tcolorObj => {\n\t\t\t\tconst colorTile = new ColorTileView();\n\n\t\t\t\tcolorTile.set( {\n\t\t\t\t\tcolor: colorObj.color,\n\t\t\t\t\thasBorder: colorObj.options && colorObj.options.hasBorder\n\t\t\t\t} );\n\n\t\t\t\tif ( colorObj.label ) {\n\t\t\t\t\tcolorTile.set( {\n\t\t\t\t\t\tlabel: colorObj.label,\n\t\t\t\t\t\ttooltip: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tcolorTile.on( 'execute', () => {\n\t\t\t\t\tthis.fire<ColorSelectorExecuteEvent>( 'execute', {\n\t\t\t\t\t\tvalue: colorObj.color,\n\t\t\t\t\t\tsource: 'documentColorsGrid'\n\t\t\t\t\t} );\n\t\t\t\t} );\n\n\t\t\t\treturn colorTile;\n\t\t\t}\n\t\t);\n\n\t\t// Selected color should be cleared when document colors became empty.\n\t\tthis.documentColors.on( 'change:isEmpty', ( evt, name, val ) => {\n\t\t\tif ( val ) {\n\t\t\t\tdocumentColorsGrid.selectedColor = null;\n\t\t\t}\n\t\t} );\n\n\t\treturn documentColorsGrid;\n\t}\n\n\t/**\n\t * Adds a given color to the document colors list. If possible, the method will attempt to use\n\t * data from the {@link #colorDefinitions} (label, color options).\n\t *\n\t * @param color A string that stores the value of the recently applied color.\n\t */\n\tprivate _addColorToDocumentColors( color: string ): void {\n\t\tconst predefinedColor = this.colorDefinitions\n\t\t\t.find( definition => definition.color === color );\n\n\t\tif ( !predefinedColor ) {\n\t\t\tthis.documentColors.add( {\n\t\t\t\tcolor,\n\t\t\t\tlabel: color,\n\t\t\t\toptions: {\n\t\t\t\t\thasBorder: false\n\t\t\t\t}\n\t\t\t} );\n\t\t} else {\n\t\t\tthis.documentColors.add( Object.assign( {}, predefinedColor ) );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorselector/colorpickerfragmentview\n */\n\nimport View from '../view.js';\nimport ButtonView from '../button/buttonview.js';\nimport type ViewCollection from '../viewcollection.js';\nimport type { FocusableView } from '../focuscycler.js';\nimport type LabeledFieldView from '../labeledfield/labeledfieldview.js';\nimport type InputTextView from '../inputtext/inputtextview.js';\nimport {\n\tdefault as ColorPickerView,\n\ttype ColorPickerColorSelectedEvent\n} from '../colorpicker/colorpickerview.js';\n\nimport type { FocusTracker, KeystrokeHandler, Locale } from '@ckeditor/ckeditor5-utils';\nimport type { ColorPickerViewConfig } from '../colorpicker/utils.js';\nimport type { ColorSelectorColorPickerCancelEvent, ColorSelectorExecuteEvent } from './colorselectorview.js';\n\nimport { icons } from '@ckeditor/ckeditor5-core';\n\n/**\n * One of the fragments of {@link module:ui/colorselector/colorselectorview~ColorSelectorView}.\n *\n * It allows users to select a color from a color picker.\n *\n * It consists of the following sub–components:\n *\n * * A color picker saturation and hue sliders,\n * * A text input accepting colors in HEX format,\n * * \"Save\" and \"Cancel\" action buttons.\n */\nexport default class ColorPickerFragmentView extends View {\n\t/**\n\t * A collection of component's children.\n\t */\n\tpublic readonly items: ViewCollection;\n\n\t/**\n\t * A view with saturation and hue sliders and color input.\n\t */\n\tpublic colorPickerView?: ColorPickerView;\n\n\t/**\n\t * The \"Save\" button view.\n\t */\n\tpublic saveButtonView: ButtonView;\n\n\t/**\n\t * The \"Cancel\" button view.\n\t */\n\tpublic cancelButtonView: ButtonView;\n\n\t/**\n\t * The action bar where are \"Save\" button and \"Cancel\" button.\n\t */\n\tpublic actionBarView: View;\n\n\t/**\n\t * Tracks information about the DOM focus in the list.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Indicates whether the component is visible or not.\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * Keeps the value of the command associated with the component for the current selection.\n\t */\n\tdeclare public selectedColor?: string;\n\n\t/**\n\t * A collection of views that can be focused in the view.\n\t *\n\t * @readonly\n\t */\n\tprotected _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * A reference to the configuration of {@link #colorPickerView}. `false` when the view was\n\t * configured without a color picker.\n\t *\n\t * @readonly\n\t */\n\tprivate _colorPickerViewConfig: ColorPickerViewConfig | false;\n\n\t/**\n\t * Creates an instance of the view.\n\t *\n\t * @param locale The localization services instance.\n\t * @param focusTracker Tracks information about the DOM focus in the list.\n\t * @param focusables A collection of views that can be focused in the view..\n\t * @param keystrokes An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t * @param colorPickerViewConfig The configuration of color picker feature. If set to `false`, the color picker\n\t * will not be rendered.\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\t{\n\t\t\tfocusTracker,\n\t\t\tfocusables,\n\t\t\tkeystrokes,\n\t\t\tcolorPickerViewConfig\n\t\t}:\n\t\t{\n\t\t\tfocusTracker: FocusTracker;\n\t\t\tfocusables: ViewCollection<FocusableView>;\n\t\t\tkeystrokes: KeystrokeHandler;\n\t\t\tcolorPickerViewConfig: ColorPickerViewConfig | false;\n\t\t}\n\t) {\n\t\tsuper( locale );\n\n\t\tthis.items = this.createCollection();\n\t\tthis.focusTracker = focusTracker;\n\t\tthis.keystrokes = keystrokes;\n\n\t\tthis.set( 'isVisible', false );\n\t\tthis.set( 'selectedColor', undefined );\n\n\t\tthis._focusables = focusables;\n\t\tthis._colorPickerViewConfig = colorPickerViewConfig;\n\n\t\tconst bind = this.bindTemplate;\n\t\tconst { saveButtonView, cancelButtonView } = this._createActionButtons();\n\n\t\tthis.saveButtonView = saveButtonView;\n\t\tthis.cancelButtonView = cancelButtonView;\n\t\tthis.actionBarView = this._createActionBarView( { saveButtonView, cancelButtonView } );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-color-picker-fragment',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.items\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tconst colorPickerView = new ColorPickerView( this.locale, {\n\t\t\t...this._colorPickerViewConfig\n\t\t} as ColorPickerViewConfig );\n\n\t\tthis.colorPickerView = colorPickerView;\n\t\tthis.colorPickerView.render();\n\n\t\tif ( this.selectedColor ) {\n\t\t\tcolorPickerView.color = this.selectedColor;\n\t\t}\n\n\t\tthis.listenTo( this, 'change:selectedColor', ( evt, name, value ) => {\n\t\t\tcolorPickerView.color = value;\n\t\t} );\n\n\t\tthis.items.add( this.colorPickerView );\n\t\tthis.items.add( this.actionBarView );\n\n\t\tthis._addColorPickersElementsToFocusTracker();\n\t\tthis._stopPropagationOnArrowsKeys();\n\t\tthis._executeOnEnterPress();\n\t\tthis._executeUponColorChange();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Focuses the color picker.\n\t */\n\tpublic focus(): void {\n\t\tthis.colorPickerView!.focus();\n\t}\n\n\t/**\n\t * Reset validation messages.\n\t */\n\tpublic resetValidationStatus(): void {\n\t\tthis.colorPickerView!.resetValidationStatus();\n\t}\n\n\t/**\n\t * When color picker is focused and \"enter\" is pressed it executes command.\n\t */\n\tprivate _executeOnEnterPress(): void {\n\t\tthis.keystrokes.set( 'enter', evt => {\n\t\t\tif ( this.isVisible && this.focusTracker.focusedElement !== this.cancelButtonView.element && this.colorPickerView!.isValid() ) {\n\t\t\t\tthis.fire( 'execute', {\n\t\t\t\t\tvalue: this.selectedColor!\n\t\t\t\t} );\n\n\t\t\t\tevt.stopPropagation();\n\t\t\t\tevt.preventDefault();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes default behavior of arrow keys in dropdown.\n\t */\n\tprivate _stopPropagationOnArrowsKeys(): void {\n\t\tconst stopPropagation = ( data: KeyboardEvent ) => data.stopPropagation();\n\n\t\tthis.keystrokes.set( 'arrowright', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowleft', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowup', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowdown', stopPropagation );\n\t}\n\n\t/**\n\t * Adds color picker elements to focus tracker.\n\t */\n\tprivate _addColorPickersElementsToFocusTracker(): void {\n\t\tfor ( const slider of this.colorPickerView!.slidersView ) {\n\t\t\tthis.focusTracker.add( slider.element! );\n\t\t\tthis._focusables.add( slider );\n\t\t}\n\n\t\tconst input = this.colorPickerView!.hexInputRow.children.get( 1 ) as LabeledFieldView<InputTextView>;\n\n\t\tif ( input.element! ) {\n\t\t\tthis.focusTracker.add( input.element );\n\t\t\tthis._focusables.add( input );\n\t\t}\n\n\t\tthis.focusTracker.add( this.saveButtonView.element! );\n\t\tthis._focusables.add( this.saveButtonView );\n\n\t\tthis.focusTracker.add( this.cancelButtonView.element! );\n\t\tthis._focusables.add( this.cancelButtonView );\n\t}\n\n\t/**\n\t * Creates bar containing \"Save\" and \"Cancel\" buttons.\n\t */\n\tprivate _createActionBarView( { saveButtonView, cancelButtonView }: {\n\t\tsaveButtonView: ButtonView;\n\t\tcancelButtonView: ButtonView;\n\t} ): View {\n\t\tconst actionBarRow = new View();\n\t\tconst children = this.createCollection();\n\n\t\tchildren.add( saveButtonView );\n\t\tchildren.add( cancelButtonView );\n\n\t\tactionBarRow.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-color-selector_action-bar'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren\n\t\t} );\n\n\t\treturn actionBarRow;\n\t}\n\n\t/**\n\t * Creates \"Save\" and \"Cancel\" buttons.\n\t */\n\tprivate _createActionButtons() {\n\t\tconst locale = this.locale;\n\t\tconst t = locale!.t;\n\t\tconst saveButtonView = new ButtonView( locale );\n\t\tconst cancelButtonView = new ButtonView( locale );\n\n\t\tsaveButtonView.set( {\n\t\t\ticon: icons.check,\n\t\t\tclass: 'ck-button-save',\n\t\t\ttype: 'button',\n\t\t\twithText: false,\n\t\t\tlabel: t( 'Accept' )\n\t\t} );\n\n\t\tcancelButtonView.set( {\n\t\t\ticon: icons.cancel,\n\t\t\tclass: 'ck-button-cancel',\n\t\t\ttype: 'button',\n\t\t\twithText: false,\n\t\t\tlabel: t( 'Cancel' )\n\t\t} );\n\n\t\tsaveButtonView.on( 'execute', () => {\n\t\t\tif ( this.colorPickerView!.isValid() ) {\n\t\t\t\tthis.fire<ColorSelectorExecuteEvent>( 'execute', {\n\t\t\t\t\tsource: 'colorPickerSaveButton',\n\t\t\t\t\tvalue: this.selectedColor!\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tcancelButtonView.on( 'execute', () => {\n\t\t\tthis.fire<ColorSelectorColorPickerCancelEvent>( 'colorPicker:cancel' );\n\t\t} );\n\n\t\treturn {\n\t\t\tsaveButtonView, cancelButtonView\n\t\t};\n\t}\n\n\t/**\n\t * Fires the `execute` event if color in color picker has been changed\n\t * by the user.\n\t */\n\tprivate _executeUponColorChange() {\n\t\tthis.colorPickerView!.on<ColorPickerColorSelectedEvent>( 'colorSelected', ( evt, data ) => {\n\t\t\tthis.fire<ColorSelectorExecuteEvent>( 'execute', {\n\t\t\t\tvalue: data.color,\n\t\t\t\tsource: 'colorPicker'\n\t\t\t} );\n\t\t\tthis.set( 'selectedColor', data.color );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/colorselector/colorselectorview\n */\n\nimport FocusCycler, { type FocusableView } from '../focuscycler.js';\nimport View from '../view.js';\nimport ViewCollection from '../viewcollection.js';\nimport { FocusTracker, KeystrokeHandler, type Locale } from '@ckeditor/ckeditor5-utils';\n\nimport type { ColorPickerViewConfig } from '../colorpicker/utils.js';\nimport type { ColorDefinition } from '../colorgrid/colorgridview.js';\nimport type { Model } from '@ckeditor/ckeditor5-engine';\n\nimport ColorGridsFragmentView from './colorgridsfragmentview.js';\nimport ColorPickerFragmentView from './colorpickerfragmentview.js';\n\nimport '../../theme/components/colorselector/colorselector.css';\n\n/**\n * The configurable color selector view class. It allows users to select colors from a predefined set of colors as well as from\n * a color picker.\n *\n * This meta-view is is made of two components (fragments):\n *\n * * {@link module:ui/colorselector/colorselectorview~ColorSelectorView#colorGridsFragmentView},\n * * {@link module:ui/colorselector/colorselectorview~ColorSelectorView#colorPickerFragmentView}.\n *\n * ```ts\n * const colorDefinitions = [\n * \t{ color: '#000', label: 'Black', options: { hasBorder: false } },\n * \t{ color: 'rgb(255, 255, 255)', label: 'White', options: { hasBorder: true } },\n * \t{ color: 'red', label: 'Red', options: { hasBorder: false } }\n * ];\n *\n * const selectorView = new ColorSelectorView( locale, {\n * \tcolors: colorDefinitions,\n * \tcolumns: 5,\n * \tremoveButtonLabel: 'Remove color',\n * \tdocumentColorsLabel: 'Document colors',\n * \tdocumentColorsCount: 4,\n * \tcolorPickerViewConfig: {\n * \t\tformat: 'hsl'\n * \t}\n * } );\n *\n * selectorView.appendUI();\n * selectorView.selectedColor = 'red';\n * selectorView.updateSelectedColors();\n *\n * selectorView.on<ColorSelectorExecuteEvent>( 'execute', ( evt, data ) => {\n * \tconsole.log( 'Color changed', data.value, data.source );\n * } );\n *\n * selectorView.on<ColorSelectorColorPickerShowEvent>( 'colorPicker:show', ( evt ) => {\n * \tconsole.log( 'Color picker showed up', evt );\n * } );\n *\n * selectorView.on<ColorSelectorColorPickerCancelEvent>( 'colorPicker:cancel', ( evt ) => {\n * \tconsole.log( 'Color picker cancel', evt );\n * } );\n *\n * selectorView.render();\n *\n * document.body.appendChild( selectorView.element );\n * ```\n */\nexport default class ColorSelectorView extends View {\n\t/**\n\t * Tracks information about the DOM focus in the list.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A collection of components.\n\t */\n\tpublic readonly items: ViewCollection;\n\n\t/**\n\t * A fragment that allows users to select colors from the a predefined set and from existing document colors.\n\t */\n\tpublic readonly colorGridsFragmentView: ColorGridsFragmentView;\n\n\t/**\n\t * A fragment that allows users to select a color from a color picker.\n\t */\n\tpublic readonly colorPickerFragmentView: ColorPickerFragmentView;\n\n\t/**\n\t * Keeps the value of the command associated with the component for the current selection.\n\t */\n\tdeclare public selectedColor?: string;\n\n\t/**\n\t * Reflects the visibility state of the color grids fragment.\n\t *\n\t * @internal\n\t */\n\tdeclare public _isColorGridsFragmentVisible: boolean;\n\n\t/**\n\t * Reflects the visibility state of the color picker fragment.\n\t *\n\t * @internal\n\t */\n\tdeclare public _isColorPickerFragmentVisible: boolean;\n\n\t/**\n\t * Helps cycling over focusable {@link #items} in the list.\n\t *\n\t * @readonly\n\t */\n\tprotected _focusCycler: FocusCycler;\n\n\t/**\n\t * A collection of views that can be focused in the view.\n\t *\n\t * @readonly\n\t */\n\tprotected _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * The configuration of color picker sub-component.\n\t */\n\tprivate _colorPickerViewConfig: ColorPickerViewConfig | false;\n\n\t/**\n\t * Creates a view to be inserted as a child of {@link module:ui/dropdown/dropdownview~DropdownView}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param colors An array with definitions of colors to be displayed in the table.\n\t * @param columns The number of columns in the color grid.\n\t * @param removeButtonLabel The label of the button responsible for removing the color.\n\t * @param colorPickerLabel The label of the button responsible for color picker appearing.\n\t * @param documentColorsLabel The label for the section with the document colors.\n\t * @param documentColorsCount The number of colors in the document colors section inside the color dropdown.\n\t * @param colorPickerViewConfig The configuration of color picker feature. If set to `false`, the color picker will be hidden.\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\t{\n\t\t\tcolors,\n\t\t\tcolumns,\n\t\t\tremoveButtonLabel,\n\t\t\tdocumentColorsLabel,\n\t\t\tdocumentColorsCount,\n\t\t\tcolorPickerLabel,\n\t\t\tcolorPickerViewConfig\n\t\t}: {\n\t\t\tcolors: Array<ColorDefinition>;\n\t\t\tcolumns: number;\n\t\t\tremoveButtonLabel: string;\n\t\t\tdocumentColorsLabel?: string;\n\t\t\tdocumentColorsCount?: number;\n\t\t\tcolorPickerLabel: string;\n\t\t\tcolorPickerViewConfig: ColorPickerViewConfig | false;\n\t\t}\n\t) {\n\t\tsuper( locale );\n\t\tthis.items = this.createCollection();\n\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis._focusables = new ViewCollection();\n\t\tthis._colorPickerViewConfig = colorPickerViewConfig;\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate list items backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate list items forwards using the <kbd>Tab</kbd> key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.colorGridsFragmentView = new ColorGridsFragmentView( locale, {\n\t\t\tcolors, columns, removeButtonLabel, documentColorsLabel, documentColorsCount, colorPickerLabel,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tfocusables: this._focusables\n\t\t} );\n\n\t\tthis.colorPickerFragmentView = new ColorPickerFragmentView( locale, {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokes: this.keystrokes,\n\t\t\tcolorPickerViewConfig\n\t\t} );\n\n\t\tthis.set( '_isColorGridsFragmentVisible', true );\n\t\tthis.set( '_isColorPickerFragmentVisible', false );\n\n\t\tthis.set( 'selectedColor', undefined );\n\n\t\tthis.colorGridsFragmentView.bind( 'isVisible' ).to( this, '_isColorGridsFragmentVisible' );\n\t\tthis.colorPickerFragmentView.bind( 'isVisible' ).to( this, '_isColorPickerFragmentVisible' );\n\n\t\t/**\n\t\t * This is kind of bindings. Unfortunately we could not use this.bind() method because the same property\n\t\t * can not be bound twice. So this is work around how to bind 'selectedColor' property between components.\n\t\t */\n\t\tthis.on( 'change:selectedColor', ( evt, evtName, data ) => {\n\t\t\tthis.colorGridsFragmentView.set( 'selectedColor', data );\n\t\t\tthis.colorPickerFragmentView.set( 'selectedColor', data );\n\t\t} );\n\n\t\tthis.colorGridsFragmentView.on( 'change:selectedColor', ( evt, evtName, data ) => {\n\t\t\tthis.set( 'selectedColor', data );\n\t\t} );\n\n\t\tthis.colorPickerFragmentView.on( 'change:selectedColor', ( evt, evtName, data ) => {\n\t\t\tthis.set( 'selectedColor', data );\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-color-selector'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.items\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Renders the internals of the component on demand:\n\t * * {@link #colorPickerFragmentView},\n\t * * {@link #colorGridsFragmentView}.\n\t *\n\t * It allows for deferring component initialization to improve the performance.\n\t *\n\t * See {@link #showColorPickerFragment}, {@link #showColorGridsFragment}.\n\t */\n\tpublic appendUI(): void {\n\t\tthis._appendColorGridsFragment();\n\n\t\tif ( this._colorPickerViewConfig ) {\n\t\t\tthis._appendColorPickerFragment();\n\t\t}\n\t}\n\n\t/**\n\t * Shows the {@link #colorPickerFragmentView} and hides the {@link #colorGridsFragmentView}.\n\t *\n\t * **Note**: It requires {@link #appendUI} to be called first.\n\t *\n\t * See {@link #showColorGridsFragment}, {@link ~ColorSelectorView#event:colorPicker:show}.\n\t */\n\tpublic showColorPickerFragment(): void {\n\t\tif ( !this.colorPickerFragmentView.colorPickerView || this._isColorPickerFragmentVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isColorPickerFragmentVisible = true;\n\t\tthis.colorPickerFragmentView.focus();\n\t\tthis.colorPickerFragmentView.resetValidationStatus();\n\t\tthis._isColorGridsFragmentVisible = false;\n\t}\n\n\t/**\n\t * Shows the {@link #colorGridsFragmentView} and hides the {@link #colorPickerFragmentView}.\n\t *\n\t * See {@link #showColorPickerFragment}.\n\t *\n\t * **Note**: It requires {@link #appendUI} to be called first.\n\t */\n\tpublic showColorGridsFragment(): void {\n\t\tif ( this._isColorGridsFragmentVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isColorGridsFragmentVisible = true;\n\t\tthis.colorGridsFragmentView.focus();\n\t\tthis._isColorPickerFragmentVisible = false;\n\t}\n\n\t/**\n\t * Focuses the first focusable element in {@link #items}.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the last focusable element in {@link #items}.\n\t */\n\tpublic focusLast(): void {\n\t\tthis._focusCycler.focusLast();\n\t}\n\n\t/**\n\t * Scans through the editor model and searches for text node attributes with the given `attributeName`.\n\t * Found entries are set as document colors in {@link #colorGridsFragmentView}.\n\t *\n\t * All the previously stored document colors will be lost in the process.\n\t *\n\t * @param model The model used as a source to obtain the document colors.\n\t * @param attributeName Determines the name of the related model's attribute for a given dropdown.\n\t */\n\tpublic updateDocumentColors( model: Model, attributeName: string ): void {\n\t\tthis.colorGridsFragmentView.updateDocumentColors( model, attributeName );\n\t}\n\n\t/**\n\t * Refreshes the state of the selected color in one or both grids located in {@link #colorGridsFragmentView}.\n\t *\n\t * It guarantees that the selection will occur only in one of them.\n\t */\n\tpublic updateSelectedColors(): void {\n\t\tthis.colorGridsFragmentView.updateSelectedColors();\n\t}\n\n\t/**\n\t * Appends the view containing static and document color grid views.\n\t */\n\tprivate _appendColorGridsFragment(): void {\n\t\tif ( this.items.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.items.add( this.colorGridsFragmentView );\n\t\tthis.colorGridsFragmentView.delegate( 'execute' ).to( this );\n\t\tthis.colorGridsFragmentView.delegate( 'colorPicker:show' ).to( this );\n\t}\n\n\t/**\n\t * Appends the view with the color picker.\n\t */\n\tprivate _appendColorPickerFragment(): void {\n\t\tif ( this.items.length === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.items.add( this.colorPickerFragmentView );\n\n\t\tif ( this.colorGridsFragmentView.colorPickerButtonView ) {\n\t\t\tthis.colorGridsFragmentView.colorPickerButtonView.on( 'execute', () => {\n\t\t\t\tthis.showColorPickerFragment();\n\t\t\t} );\n\t\t}\n\n\t\tthis.colorGridsFragmentView.addColorPickerButton();\n\t\tthis.colorPickerFragmentView.delegate( 'execute' ).to( this );\n\t\tthis.colorPickerFragmentView.delegate( 'colorPicker:cancel' ).to( this );\n\t}\n}\n\n/**\n * Fired whenever the color was changed. There are multiple sources of this event and you can distinguish them\n * using the `source` property passed along this event.\n *\n * @eventName ~ColorSelectorView#execute\n */\nexport type ColorSelectorExecuteEvent = {\n\tname: 'execute';\n\targs: [ {\n\t\tvalue: string;\n\t\tsource: 'staticColorsGrid' | 'documentColorsGrid' | 'removeColorButton' | 'colorPicker' | 'colorPickerSaveButton';\n\t} ];\n};\n\n/**\n * Fired when the user pressed the \"Cancel\" button in the\n * {@link module:ui/colorselector/colorselectorview~ColorSelectorView#colorPickerFragmentView}.\n *\n * @eventName ~ColorSelectorView#colorPicker:cancel\n */\nexport type ColorSelectorColorPickerCancelEvent = {\n\tname: 'colorPicker:cancel';\n\targs: [];\n};\n\n/**\n * Fired whenever {@link module:ui/colorselector/colorselectorview~ColorSelectorView#colorPickerFragmentView} is shown.\n *\n * See {@link ~ColorSelectorView#showColorPickerFragment}.\n *\n * @eventName ~ColorSelectorView#colorPicker:show\n */\nexport type ColorSelectorColorPickerShowEvent = {\n\tname: 'colorPicker:show';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/componentfactory\n */\n\nimport { CKEditorError, type Locale } from '@ckeditor/ckeditor5-utils';\nimport type { Editor } from '@ckeditor/ckeditor5-core';\n\nimport type View from './view.js';\n\n/**\n * A helper class implementing the UI component ({@link module:ui/view~View view}) factory.\n *\n * It allows functions producing specific UI components to be registered under their unique names\n * in the factory. A registered component can be then instantiated by providing its name.\n * Note that the names are case insensitive.\n *\n * ```ts\n * // The editor provides localization tools for the factory.\n * const factory = new ComponentFactory( editor );\n *\n * factory.add( 'foo', locale => new FooView( locale ) );\n * factory.add( 'bar', locale => new BarView( locale ) );\n *\n * // An instance of FooView.\n * const fooInstance = factory.create( 'foo' );\n *\n * // Names are case insensitive so this is also allowed:\n * const barInstance = factory.create( 'Bar' );\n * ```\n *\n * The {@link module:core/editor/editor~Editor#locale editor locale} is passed to the factory\n * function when {@link module:ui/componentfactory~ComponentFactory#create} is called.\n */\nexport default class ComponentFactory {\n\t/**\n\t * The editor instance that the factory belongs to.\n\t */\n\tpublic readonly editor: Editor;\n\n\t/**\n\t * Registered component factories.\n\t */\n\tprivate readonly _components = new Map<string, { originalName: string; callback: ( locale: Locale ) => View }>();\n\n\t/**\n\t * Creates an instance of the factory.\n\t *\n\t * @param editor The editor instance.\n\t */\n\tconstructor( editor: Editor ) {\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * Returns an iterator of registered component names. Names are returned in lower case.\n\t */\n\tpublic* names(): IterableIterator<string> {\n\t\tfor ( const value of this._components.values() ) {\n\t\t\tyield value.originalName;\n\t\t}\n\t}\n\n\t/**\n\t * Registers a component factory function that will be used by the\n\t * {@link #create create} method and called with the\n\t * {@link module:core/editor/editor~Editor#locale editor locale} as an argument,\n\t * allowing localization of the {@link module:ui/view~View view}.\n\t *\n\t * @param name The name of the component.\n\t * @param callback The callback that returns the component.\n\t */\n\tpublic add( name: string, callback: ( locale: Locale ) => View ): void {\n\t\tthis._components.set( getNormalized( name ), { callback, originalName: name } );\n\t}\n\n\t/**\n\t * Creates an instance of a component registered in the factory under a specific name.\n\t *\n\t * When called, the {@link module:core/editor/editor~Editor#locale editor locale} is passed to\n\t * the previously {@link #add added} factory function, allowing localization of the\n\t * {@link module:ui/view~View view}.\n\t *\n\t * @param name The name of the component.\n\t * @returns The instantiated component view.\n\t */\n\tpublic create( name: string ): View {\n\t\tif ( !this.has( name ) ) {\n\t\t\t/**\n\t\t\t * The required component is not registered in the component factory. Please make sure\n\t\t\t * the provided name is correct and the component has been correctly\n\t\t\t * {@link module:ui/componentfactory~ComponentFactory#add added} to the factory.\n\t\t\t *\n\t\t\t * @error componentfactory-item-missing\n\t\t\t * @param name The name of the missing component.\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'componentfactory-item-missing',\n\t\t\t\tthis,\n\t\t\t\t{ name }\n\t\t\t);\n\t\t}\n\n\t\treturn this._components.get( getNormalized( name ) )!.callback( this.editor.locale );\n\t}\n\n\t/**\n\t * Checks if a component of a given name is registered in the factory.\n\t *\n\t * @param name The name of the component.\n\t */\n\tpublic has( name: string ): boolean {\n\t\treturn this._components.has( getNormalized( name ) );\n\t}\n}\n\n/**\n * Ensures that the component name used as the key in the internal map is in lower case.\n */\nfunction getNormalized( name: unknown ) {\n\treturn String( name ).toLowerCase();\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/tooltipmanager\n */\n\nimport View from './view.js';\nimport BalloonPanelView from './panel/balloon/balloonpanelview.js';\nimport type { EditorUIUpdateEvent } from './editorui/editorui.js';\n\nimport {\n\tDomEmitterMixin,\n\tfirst,\n\tglobal,\n\tisVisible,\n\ttype EventInfo,\n\ttype PositioningFunction\n} from '@ckeditor/ckeditor5-utils';\n\nimport type { Editor } from '@ckeditor/ckeditor5-core';\n\nimport { isElement, debounce, type DebouncedFunc } from 'lodash-es';\n\nimport '../theme/components/tooltip/tooltip.css';\n\nconst BALLOON_CLASS = 'ck-tooltip';\n\n/**\n * A tooltip manager class for the UI of the editor.\n *\n * **Note**: Most likely you do not have to use the `TooltipManager` API listed below in order to display tooltips. Popular\n * {@glink framework/architecture/ui-library UI components} support tooltips out-of-the-box via observable properties\n * (see {@link module:ui/button/buttonview~ButtonView#tooltip} and {@link module:ui/button/buttonview~ButtonView#tooltipPosition}).\n *\n * # Displaying tooltips\n *\n * To display a tooltip, set `data-cke-tooltip-text` attribute on any DOM element:\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'My tooltip';\n * ```\n *\n * The tooltip will show up whenever the user moves the mouse over the element or the element gets focus in DOM.\n *\n * # Positioning tooltips\n *\n * To change the position of the tooltip, use the `data-cke-tooltip-position` attribute (`s`, `se`, `sw`, `n`, `e`, or `w`):\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'Tooltip to the north';\n * domElement.dataset.ckeTooltipPosition = 'n';\n * ```\n *\n * # Disabling tooltips\n *\n * In order to disable the tooltip  temporarily, use the `data-cke-tooltip-disabled` attribute:\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'Disabled. For now.';\n * domElement.dataset.ckeTooltipDisabled = 'true';\n * ```\n *\n * # Styling tooltips\n *\n * By default, the tooltip has `.ck-tooltip` class and its text inner `.ck-tooltip__text`.\n *\n * If your tooltip requires custom styling, using `data-cke-tooltip-class` attribute will add additional class to the balloon\n * displaying the tooltip:\n *\n * ```ts\n * domElement.dataset.ckeTooltipText = 'Tooltip with a red text';\n * domElement.dataset.ckeTooltipClass = 'my-class';\n * ```\n *\n * ```css\n * .ck.ck-tooltip.my-class { color: red }\n * ```\n *\n * **Note**: This class is a singleton. All editor instances re-use the same instance loaded by\n * {@link module:ui/editorui/editorui~EditorUI} of the first editor.\n */\nexport default class TooltipManager extends /* #__PURE__ */ DomEmitterMixin() {\n\t/**\n\t * The view rendering text of the tooltip.\n\t */\n\tpublic readonly tooltipTextView!: View & { text: string };\n\n\t/**\n\t * The instance of the balloon panel that renders and positions the tooltip.\n\t */\n\tpublic readonly balloonPanelView!: BalloonPanelView;\n\n\t/**\n\t * A set of default {@link module:utils/dom/position~PositioningFunction positioning functions} used by the `TooltipManager`\n\t * to pin tooltips in different positions.\n\t */\n\tpublic static defaultBalloonPositions = /* #__PURE__ */ BalloonPanelView.generatePositions( {\n\t\theightOffset: 5,\n\t\tsideOffset: 13\n\t} );\n\n\t/**\n\t * Stores the reference to the DOM element the tooltip is attached to. `null` when there's no tooltip\n\t * in the UI.\n\t */\n\tprivate _currentElementWithTooltip: HTMLElement | null = null;\n\n\t/**\n\t * Stores the current tooltip position. `null` when there's no tooltip in the UI.\n\t */\n\tprivate _currentTooltipPosition: TooltipPosition | null = null;\n\n\t/**\n\t * An instance of the mutation observer that keeps track on target element attributes changes.\n\t */\n\tprivate _mutationObserver: MutationObserverWrapper | null = null;\n\n\t/**\n\t * A debounced version of {@link #_pinTooltip}. Tooltips show with a delay to avoid flashing and\n\t * to improve the UX.\n\t */\n\tprivate _pinTooltipDebounced!: DebouncedFunc<( targetDomElement: HTMLElement, data: TooltipData ) => void>;\n\n\t/**\n\t * A debounced version of {@link #_unpinTooltip}. Tooltips hide with a delay to allow hovering of their titles.\n\t */\n\tprivate _unpinTooltipDebounced!: DebouncedFunc<VoidFunction>;\n\n\tprivate readonly _watchdogExcluded!: true;\n\n\t/**\n\t * A set of editors the single tooltip manager instance must listen to.\n\t * This is mostly to handle `EditorUI#update` listeners from individual editors.\n\t */\n\tprivate static _editors = new Set<Editor>();\n\n\t/**\n\t * A reference to the `TooltipManager` instance. The class is a singleton and as such,\n\t * successive attempts at creating instances should return this instance.\n\t */\n\tprivate static _instance: TooltipManager | null = null;\n\n\t/**\n\t * Creates an instance of the tooltip manager.\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper();\n\n\t\tTooltipManager._editors.add( editor );\n\n\t\t// TooltipManager must be a singleton. Multiple instances would mean multiple tooltips attached\n\t\t// to the same DOM element with data-cke-tooltip-* attributes.\n\t\tif ( TooltipManager._instance ) {\n\t\t\treturn TooltipManager._instance;\n\t\t}\n\n\t\tTooltipManager._instance = this;\n\n\t\tthis.tooltipTextView = new View( editor.locale ) as any;\n\t\tthis.tooltipTextView.set( 'text', '' );\n\t\tthis.tooltipTextView.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-tooltip__text'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttext: this.tooltipTextView.bindTemplate.to( 'text' )\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\tthis.balloonPanelView = new BalloonPanelView( editor.locale );\n\t\tthis.balloonPanelView.class = BALLOON_CLASS;\n\t\tthis.balloonPanelView.content.add( this.tooltipTextView );\n\n\t\tthis._mutationObserver = createMutationObserver( () => {\n\t\t\tthis._updateTooltipPosition();\n\t\t} );\n\n\t\tthis._pinTooltipDebounced = debounce( this._pinTooltip, 600 );\n\t\tthis._unpinTooltipDebounced = debounce( this._unpinTooltip, 400 );\n\n\t\tthis.listenTo( global.document, 'keydown', this._onKeyDown.bind( this ), { useCapture: true } );\n\t\tthis.listenTo( global.document, 'mouseenter', this._onEnterOrFocus.bind( this ), { useCapture: true } );\n\t\tthis.listenTo( global.document, 'mouseleave', this._onLeaveOrBlur.bind( this ), { useCapture: true } );\n\n\t\tthis.listenTo( global.document, 'focus', this._onEnterOrFocus.bind( this ), { useCapture: true } );\n\t\tthis.listenTo( global.document, 'blur', this._onLeaveOrBlur.bind( this ), { useCapture: true } );\n\n\t\tthis.listenTo( global.document, 'scroll', this._onScroll.bind( this ), { useCapture: true } );\n\n\t\t// Because this class is a singleton, its only instance is shared across all editors and connects them through the reference.\n\t\t// This causes issues with the ContextWatchdog. When an error is thrown in one editor, the watchdog traverses the references\n\t\t// and (because of shared tooltip manager) figures that the error affects all editors and restarts them all.\n\t\t// This flag, excludes tooltip manager instance from the traversal and brings ContextWatchdog back to normal.\n\t\t// More in https://github.com/ckeditor/ckeditor5/issues/12292.\n\t\tthis._watchdogExcluded = true;\n\t}\n\n\t/**\n\t * Destroys the tooltip manager.\n\t *\n\t * **Note**: The manager singleton cannot be destroyed until all editors that use it are destroyed.\n\t *\n\t * @param editor The editor the manager was created for.\n\t */\n\tpublic destroy( editor: Editor ): void {\n\t\tconst editorBodyViewCollection = editor.ui.view && editor.ui.view.body;\n\n\t\tTooltipManager._editors.delete( editor );\n\t\tthis.stopListening( editor.ui );\n\n\t\t// Prevent the balloon panel from being destroyed in the EditorUI#destroy() cascade. It should be destroyed along\n\t\t// with the last editor only (https://github.com/ckeditor/ckeditor5/issues/12602).\n\t\tif ( editorBodyViewCollection && editorBodyViewCollection.has( this.balloonPanelView ) ) {\n\t\t\teditorBodyViewCollection.remove( this.balloonPanelView );\n\t\t}\n\n\t\tif ( !TooltipManager._editors.size ) {\n\t\t\tthis._unpinTooltip();\n\t\t\tthis.balloonPanelView.destroy();\n\t\t\tthis.stopListening();\n\n\t\t\tTooltipManager._instance = null;\n\t\t}\n\t}\n\n\t/**\n\t * Returns {@link #balloonPanelView} {@link module:utils/dom/position~PositioningFunction positioning functions} for a given position\n\t * name.\n\t *\n\t * @param position Name of the position (`s`, `se`, `sw`, `n`, `e`, or `w`).\n\t * @returns Positioning functions to be used by the {@link #balloonPanelView}.\n\t */\n\tpublic static getPositioningFunctions( position: TooltipPosition ): Array<PositioningFunction> {\n\t\tconst defaultPositions = TooltipManager.defaultBalloonPositions;\n\n\t\treturn {\n\t\t\t// South is most popular. We can use positioning heuristics to avoid clipping by the viewport with the sane fallback.\n\t\t\ts: [\n\t\t\t\tdefaultPositions.southArrowNorth,\n\t\t\t\tdefaultPositions.southArrowNorthEast,\n\t\t\t\tdefaultPositions.southArrowNorthWest\n\t\t\t],\n\t\t\tn: [ defaultPositions.northArrowSouth ],\n\t\t\te: [ defaultPositions.eastArrowWest ],\n\t\t\tw: [ defaultPositions.westArrowEast ],\n\t\t\tsw: [ defaultPositions.southArrowNorthEast ],\n\t\t\tse: [ defaultPositions.southArrowNorthWest ]\n\t\t}[ position ];\n\t}\n\n\t/**\n\t * Handles hiding tooltips on `keydown` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */\n\tprivate _onKeyDown( evt: EventInfo, domEvent: KeyboardEvent ) {\n\t\tif ( domEvent.key === 'Escape' && this._currentElementWithTooltip ) {\n\t\t\tthis._unpinTooltip();\n\t\t\tdomEvent.stopPropagation();\n\t\t}\n\t}\n\n\t/**\n\t * Handles displaying tooltips on `mouseenter` and `focus` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */\n\tprivate _onEnterOrFocus( evt: EventInfo, { target }: any ) {\n\t\tconst elementWithTooltipAttribute = getDescendantWithTooltip( target );\n\n\t\t// Abort when there's no descendant needing tooltip.\n\t\tif ( !elementWithTooltipAttribute ) {\n\t\t\t// Unpin if element is focused, regardless of whether it contains a label or not.\n\t\t\t// It also prevents tooltips from overlapping the menu bar\n\t\t\tif ( evt.name === 'focus' ) {\n\t\t\t\tthis._unpinTooltip();\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Abort to avoid flashing when, for instance:\n\t\t// * a tooltip is displayed for a focused element, then the same element gets mouseentered,\n\t\t// * a tooltip is displayed for an element via mouseenter, then the focus moves to the same element.\n\t\tif ( elementWithTooltipAttribute === this._currentElementWithTooltip ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._unpinTooltip();\n\n\t\t// The tooltip should be pinned immediately when the element gets focused using keyboard.\n\t\t// If it is focused using the mouse, the tooltip should be pinned after a delay to prevent flashing.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/16383\n\t\tif ( evt.name === 'focus' && !elementWithTooltipAttribute.matches( ':hover' ) ) {\n\t\t\tthis._pinTooltip( elementWithTooltipAttribute, getTooltipData( elementWithTooltipAttribute ) );\n\t\t} else {\n\t\t\tthis._pinTooltipDebounced( elementWithTooltipAttribute, getTooltipData( elementWithTooltipAttribute ) );\n\t\t}\n\t}\n\n\t/**\n\t * Handles hiding tooltips on `mouseleave` and `blur` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */\n\tprivate _onLeaveOrBlur( evt: EventInfo, { target, relatedTarget }: any ) {\n\t\tif ( evt.name === 'mouseleave' ) {\n\t\t\t// Don't act when the event does not concern a DOM element (e.g. a mouseleave out of an entire document),\n\t\t\tif ( !isElement( target ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst balloonElement = this.balloonPanelView.element;\n\t\t\tconst isEnteringBalloon = balloonElement && ( balloonElement === relatedTarget || balloonElement.contains( relatedTarget ) );\n\t\t\tconst isLeavingBalloon = !isEnteringBalloon && target === balloonElement;\n\n\t\t\t// Do not hide the tooltip when the user moves the cursor over it.\n\t\t\tif ( isEnteringBalloon ) {\n\t\t\t\tthis._unpinTooltipDebounced.cancel();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a tooltip is currently visible, don't act for a targets other than the one it is attached to.\n\t\t\t// The only exception is leaving balloon, in this scenario tooltip should be closed.\n\t\t\t// For instance, a random mouseleave far away in the page should not unpin the tooltip that was pinned because\n\t\t\t// of a previous focus. Only leaving the same element should hide the tooltip.\n\t\t\tif ( !isLeavingBalloon && this._currentElementWithTooltip && target !== this._currentElementWithTooltip ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst descendantWithTooltip = getDescendantWithTooltip( target );\n\t\t\tconst relatedDescendantWithTooltip = getDescendantWithTooltip( relatedTarget );\n\n\t\t\t// Unpin when the mouse was leaving element with a tooltip to a place which does not have or has a different tooltip.\n\t\t\t// Note that this should happen whether the tooltip is already visible or not, for instance,\n\t\t\t// it could be invisible but queued (debounced): it should get canceled.\n\t\t\tif ( isLeavingBalloon || ( descendantWithTooltip && descendantWithTooltip !== relatedDescendantWithTooltip ) ) {\n\t\t\t\tthis._unpinTooltipDebounced();\n\t\t\t}\n\t\t} else {\n\t\t\t// If a tooltip is currently visible, don't act for a targets other than the one it is attached to.\n\t\t\t// For instance, a random blur in the web page should not unpin the tooltip that was pinned because of a previous mouseenter.\n\t\t\tif ( this._currentElementWithTooltip && target !== this._currentElementWithTooltip ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Note that unpinning should happen whether the tooltip is already visible or not, for instance, it could be invisible but\n\t\t\t// queued (debounced): it should get canceled (e.g. quick focus then quick blur using the keyboard).\n\t\t\tthis._unpinTooltipDebounced();\n\t\t}\n\t}\n\n\t/**\n\t * Handles hiding tooltips on `scroll` in DOM.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param domEvent The DOM event.\n\t */\n\tprivate _onScroll( evt: unknown, { target }: any ) {\n\t\t// No tooltip, no reason to react on scroll.\n\t\tif ( !this._currentElementWithTooltip ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// When scrolling a container that has both the balloon and the current element (common ancestor), the balloon can remain\n\t\t// visible (e.g. scrolling ≤body>). Otherwise, to avoid glitches (clipping, lagging) better just hide the tooltip.\n\t\t// Also, don't do anything when scrolling an unrelated DOM element that has nothing to do with the current element and the balloon.\n\t\tif ( target.contains( this.balloonPanelView.element ) && target.contains( this._currentElementWithTooltip ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._unpinTooltip();\n\t}\n\n\t/**\n\t * Pins the tooltip to a specific DOM element.\n\t *\n\t * @param options.text Text of the tooltip to display.\n\t * @param options.position The position of the tooltip.\n\t * @param options.cssClass Additional CSS class of the balloon with the tooltip.\n\t */\n\tprivate _pinTooltip(\n\t\ttargetDomElement: HTMLElement,\n\t\t{ text, position, cssClass }: TooltipData\n\t): void {\n\t\tthis._unpinTooltip();\n\n\t\t// Use the body collection of the first editor.\n\t\tconst bodyViewCollection = first( TooltipManager._editors.values() )!.ui.view.body;\n\n\t\tif ( !bodyViewCollection.has( this.balloonPanelView ) ) {\n\t\t\tbodyViewCollection.add( this.balloonPanelView );\n\t\t}\n\n\t\tthis.tooltipTextView.text = text;\n\n\t\tthis.balloonPanelView.class = [ BALLOON_CLASS, cssClass ]\n\t\t\t.filter( className => className )\n\t\t\t.join( ' ' );\n\n\t\t// Ensure that all changes to the tooltip are set before pinning it.\n\t\t// Setting class or text after pinning can cause the tooltip to be pinned in the wrong position.\n\t\t// It happens especially often when tooltip has class modified (like adding `ck-tooltip_multi-line`).\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/16365\n\t\tthis.balloonPanelView.pin( {\n\t\t\ttarget: targetDomElement,\n\t\t\tpositions: TooltipManager.getPositioningFunctions( position )\n\t\t} );\n\n\t\tthis._mutationObserver!.attach( targetDomElement );\n\n\t\t// Start responding to changes in editor UI or content layout. For instance, when collaborators change content\n\t\t// and a contextual toolbar attached to a content starts to move (and so should move the tooltip).\n\t\t// Note: Using low priority to let other listeners that position contextual toolbars etc. to react first.\n\t\tfor ( const editor of TooltipManager._editors ) {\n\t\t\tthis.listenTo<EditorUIUpdateEvent>( editor.ui, 'update', this._updateTooltipPosition.bind( this ), { priority: 'low' } );\n\t\t}\n\n\t\tthis._currentElementWithTooltip = targetDomElement;\n\t\tthis._currentTooltipPosition = position;\n\t}\n\n\t/**\n\t * Unpins the tooltip and cancels all queued pinning.\n\t */\n\tprivate _unpinTooltip() {\n\t\tthis._unpinTooltipDebounced.cancel();\n\t\tthis._pinTooltipDebounced.cancel();\n\n\t\tthis.balloonPanelView.unpin();\n\n\t\tfor ( const editor of TooltipManager._editors ) {\n\t\t\tthis.stopListening( editor.ui, 'update' );\n\t\t}\n\n\t\tthis._currentElementWithTooltip = null;\n\t\tthis._currentTooltipPosition = null;\n\t\tthis.tooltipTextView.text = '';\n\n\t\tthis._mutationObserver!.detach();\n\t}\n\n\t/**\n\t * Updates the position of the tooltip so it stays in sync with the element it is pinned to.\n\t *\n\t * Hides the tooltip when the element is no longer visible in DOM or the tooltip text was removed.\n\t */\n\tprivate _updateTooltipPosition() {\n\t\t// The tooltip might get removed by focus listener triggered by the same UI `update` event.\n\t\t// See https://github.com/ckeditor/ckeditor5/pull/16363.\n\t\tif ( !this._currentElementWithTooltip ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tooltipData = getTooltipData( this._currentElementWithTooltip );\n\n\t\t// This could happen if the tooltip was attached somewhere in a contextual content toolbar and the toolbar\n\t\t// disappeared (e.g. removed an image), or the tooltip text was removed.\n\t\tif ( !isVisible( this._currentElementWithTooltip ) || !tooltipData.text ) {\n\t\t\tthis._unpinTooltip();\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.balloonPanelView.pin( {\n\t\t\ttarget: this._currentElementWithTooltip,\n\t\t\tpositions: TooltipManager.getPositioningFunctions( tooltipData.position )\n\t\t} );\n\t}\n}\n\nexport type TooltipPosition = 's' | 'n' | 'e' | 'w' | 'sw' | 'se';\n\nfunction getDescendantWithTooltip( element: HTMLElement ) {\n\tif ( !isElement( element ) ) {\n\t\treturn null;\n\t}\n\n\treturn element.closest( '[data-cke-tooltip-text]:not([data-cke-tooltip-disabled])' ) as HTMLElement;\n}\n\ninterface TooltipData {\n\ttext: string;\n\tposition: TooltipPosition;\n\tcssClass: string;\n}\n\nfunction getTooltipData( element: HTMLElement ): TooltipData {\n\treturn {\n\t\ttext: element.dataset.ckeTooltipText!,\n\t\tposition: ( element.dataset.ckeTooltipPosition || 's' ) as TooltipPosition,\n\t\tcssClass: element.dataset.ckeTooltipClass || ''\n\t};\n}\n\n// Creates a simple `MutationObserver` instance wrapper that observes changes in the tooltip-related attributes of the given element.\n// Used instead of the `MutationObserver` from the engine for simplicity.\nfunction createMutationObserver( callback: ( ...args: Array<any> ) => unknown ): MutationObserverWrapper {\n\tconst mutationObserver = new MutationObserver( () => {\n\t\tcallback();\n\t} );\n\n\treturn {\n\t\tattach( element ) {\n\t\t\tmutationObserver.observe( element, {\n\t\t\t\tattributes: true,\n\t\t\t\tattributeFilter: [ 'data-cke-tooltip-text', 'data-cke-tooltip-position' ]\n\t\t\t} );\n\t\t},\n\n\t\tdetach() {\n\t\t\tmutationObserver.disconnect();\n\t\t}\n\t};\n}\n\ninterface MutationObserverWrapper {\n\tattach: ( element: Node ) => void;\n\tdetach: () => void;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editorui/poweredby\n */\n\nimport type { Editor, UiConfig } from '@ckeditor/ckeditor5-core';\nimport {\n\tDomEmitterMixin,\n\tRect,\n\tverifyLicense,\n\ttype PositionOptions,\n\ttype Locale\n} from '@ckeditor/ckeditor5-utils';\nimport BalloonPanelView from '../panel/balloon/balloonpanelview.js';\nimport IconView from '../icon/iconview.js';\nimport View from '../view.js';\nimport { throttle, type DebouncedFunc } from 'lodash-es';\n\nimport poweredByIcon from '../../theme/icons/project-logo.svg';\n\nconst ICON_WIDTH = 53;\nconst ICON_HEIGHT = 10;\n// ⚠ Note, whenever changing the threshold, make sure to update the docs/support/managing-ckeditor-logo.md docs\n// as this information is also mentioned there ⚠.\nconst NARROW_ROOT_HEIGHT_THRESHOLD = 50;\nconst NARROW_ROOT_WIDTH_THRESHOLD = 350;\nconst DEFAULT_LABEL = 'Powered by';\n\ntype PoweredByConfig = Required<UiConfig>[ 'poweredBy' ];\n\n/**\n * A helper that enables the \"powered by\" feature in the editor and renders a link to the project's\n * webpage next to the bottom of the editable element (editor root, source editing area, etc.) when the editor is focused.\n *\n * @private\n */\nexport default class PoweredBy extends /* #__PURE__ */ DomEmitterMixin() {\n\t/**\n\t * Editor instance the helper was created for.\n\t */\n\tprivate readonly editor: Editor;\n\n\t/**\n\t * A reference to the balloon panel hosting and positioning the \"powered by\" link and logo.\n\t */\n\tprivate _balloonView: BalloonPanelView | null;\n\n\t/**\n\t * A throttled version of the {@link #_showBalloon} method meant for frequent use to avoid performance loss.\n\t */\n\tprivate _showBalloonThrottled: DebouncedFunc<() => void>;\n\n\t/**\n\t * A reference to the last editable element (root, source editing area, etc.) focused by the user.\n\t * Since the focus can move to other focusable elements in the UI, this reference allows positioning the balloon over the\n\t * right element whether the user is typing or using the UI.\n\t */\n\tprivate _lastFocusedEditableElement: HTMLElement | null;\n\n\t/**\n\t * Creates a \"powered by\" helper for a given editor. The feature is initialized on Editor#ready\n\t * event.\n\t *\n\t * @param editor\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper();\n\n\t\tthis.editor = editor;\n\t\tthis._balloonView = null;\n\t\tthis._lastFocusedEditableElement = null;\n\t\tthis._showBalloonThrottled = throttle( this._showBalloon.bind( this ), 50, { leading: true } );\n\n\t\teditor.on( 'ready', this._handleEditorReady.bind( this ) );\n\t}\n\n\t/**\n\t * Destroys the \"powered by\" helper along with its view.\n\t */\n\tpublic destroy(): void {\n\t\tconst balloon = this._balloonView;\n\n\t\tif ( balloon ) {\n\t\t\t// Balloon gets destroyed by the body collection.\n\t\t\t// The powered by view gets destroyed by the balloon.\n\t\t\tballoon.unpin();\n\t\t\tthis._balloonView = null;\n\t\t}\n\n\t\tthis._showBalloonThrottled.cancel();\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Enables \"powered by\" label once the editor (ui) is ready.\n\t */\n\tprivate _handleEditorReady(): void {\n\t\tconst editor = this.editor;\n\t\tconst forceVisible = !!editor.config.get( 'ui.poweredBy.forceVisible' );\n\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif ( !forceVisible && verifyLicense( editor.config.get( 'licenseKey' ) ) === 'VALID' ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// No view means no body collection to append the powered by balloon to.\n\t\tif ( !editor.ui.view ) {\n\t\t\treturn;\n\t\t}\n\n\t\teditor.ui.focusTracker.on( 'change:isFocused', ( evt, data, isFocused ) => {\n\t\t\tthis._updateLastFocusedEditableElement();\n\n\t\t\tif ( isFocused ) {\n\t\t\t\tthis._showBalloon();\n\t\t\t} else {\n\t\t\t\tthis._hideBalloon();\n\t\t\t}\n\t\t} );\n\n\t\teditor.ui.focusTracker.on( 'change:focusedElement', ( evt, data, focusedElement ) => {\n\t\t\tthis._updateLastFocusedEditableElement();\n\n\t\t\tif ( focusedElement ) {\n\t\t\t\tthis._showBalloon();\n\t\t\t}\n\t\t} );\n\n\t\teditor.ui.on( 'update', () => {\n\t\t\tthis._showBalloonThrottled();\n\t\t} );\n\t}\n\n\t/**\n\t * Creates an instance of the {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView balloon panel}\n\t * with the \"powered by\" view inside ready for positioning.\n\t */\n\tprivate _createBalloonView(): void {\n\t\tconst editor = this.editor;\n\t\tconst balloon = this._balloonView = new BalloonPanelView();\n\t\tconst poweredByConfig = getNormalizedConfig( editor );\n\t\tconst view = new PoweredByView( editor.locale, poweredByConfig.label );\n\n\t\tballoon.content.add( view );\n\t\tballoon.set( {\n\t\t\tclass: 'ck-powered-by-balloon'\n\t\t} );\n\n\t\teditor.ui.view.body.add( balloon );\n\n\t\tthis._balloonView = balloon;\n\t}\n\n\t/**\n\t * Attempts to display the balloon with the \"powered by\" view.\n\t */\n\tprivate _showBalloon(): void {\n\t\tif ( !this._lastFocusedEditableElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst attachOptions = getBalloonAttachOptions( this.editor, this._lastFocusedEditableElement );\n\n\t\tif ( attachOptions ) {\n\t\t\tif ( !this._balloonView ) {\n\t\t\t\tthis._createBalloonView();\n\t\t\t}\n\n\t\t\tthis._balloonView!.pin( attachOptions );\n\t\t}\n\t}\n\n\t/**\n\t * Hides the \"powered by\" balloon if already visible.\n\t */\n\tprivate _hideBalloon(): void {\n\t\tif ( this._balloonView ) {\n\t\t\tthis._balloonView!.unpin();\n\t\t}\n\t}\n\n\t/**\n\t * Updates the {@link #_lastFocusedEditableElement} based on the state of the global focus tracker.\n\t */\n\tprivate _updateLastFocusedEditableElement(): void {\n\t\tconst editor = this.editor;\n\t\tconst isFocused = editor.ui.focusTracker.isFocused;\n\t\tconst focusedElement = editor.ui.focusTracker.focusedElement! as HTMLElement;\n\n\t\tif ( !isFocused || !focusedElement ) {\n\t\t\tthis._lastFocusedEditableElement = null;\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst editableEditorElements = Array.from( editor.ui.getEditableElementsNames() ).map( name => {\n\t\t\treturn editor.ui.getEditableElement( name );\n\t\t} );\n\n\t\tif ( editableEditorElements.includes( focusedElement ) ) {\n\t\t\tthis._lastFocusedEditableElement = focusedElement;\n\t\t} else {\n\t\t\t// If it's none of the editable element, then the focus is somewhere in the UI. Let's display powered by\n\t\t\t// over the first element then.\n\t\t\tthis._lastFocusedEditableElement = editableEditorElements[ 0 ]!;\n\t\t}\n\t}\n}\n\n/**\n * A view displaying a \"powered by\" label and project logo wrapped in a link.\n */\nclass PoweredByView extends View<HTMLDivElement> {\n\t/**\n\t * Created an instance of the \"powered by\" view.\n\t *\n\t * @param locale The localization services instance.\n\t * @param label The label text.\n\t */\n\tconstructor( locale: Locale, label: string | null ) {\n\t\tsuper( locale );\n\n\t\tconst iconView = new IconView();\n\t\tconst bind = this.bindTemplate;\n\n\t\ticonView.set( {\n\t\t\tcontent: poweredByIcon,\n\t\t\tisColorInherited: false\n\t\t} );\n\n\t\ticonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tstyle: {\n\t\t\t\t\twidth: ICON_WIDTH + 'px',\n\t\t\t\t\theight: ICON_HEIGHT + 'px'\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck', 'ck-powered-by' ],\n\t\t\t\t'aria-hidden': true\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'a',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\thref: 'https://ckeditor.com/powered-by-ckeditor/?utm_source=ckeditor&' +\n\t\t\t\t\t\t\t'utm_medium=referral&utm_campaign=701Dn000000hVgmIAE_powered_by_ckeditor_logo',\n\t\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\t\ttabindex: '-1'\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t...label ? [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttag: 'span',\n\t\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\t\tclass: [ 'ck', 'ck-powered-by__label' ]\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tchildren: [ label ]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t] : [],\n\t\t\t\t\t\ticonView\n\t\t\t\t\t],\n\t\t\t\t\ton: {\n\t\t\t\t\t\tdragstart: bind.to( evt => evt.preventDefault() )\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n\nfunction getBalloonAttachOptions( editor: Editor, focusedEditableElement: HTMLElement ): Partial<PositionOptions> | null {\n\tconst poweredByConfig = getNormalizedConfig( editor )!;\n\tconst positioningFunction = poweredByConfig.side === 'right' ?\n\t\tgetLowerRightCornerPosition( focusedEditableElement, poweredByConfig ) :\n\t\tgetLowerLeftCornerPosition( focusedEditableElement, poweredByConfig );\n\n\treturn {\n\t\ttarget: focusedEditableElement,\n\t\tpositions: [ positioningFunction ]\n\t};\n}\n\nfunction getLowerRightCornerPosition( focusedEditableElement: HTMLElement, config: PoweredByConfig ) {\n\treturn getLowerCornerPosition( focusedEditableElement, config, ( rootRect, balloonRect ) => {\n\t\treturn rootRect.left + rootRect.width - balloonRect.width - config.horizontalOffset;\n\t} );\n}\n\nfunction getLowerLeftCornerPosition( focusedEditableElement: HTMLElement, config: PoweredByConfig ) {\n\treturn getLowerCornerPosition( focusedEditableElement, config, rootRect => rootRect.left + config.horizontalOffset );\n}\n\nfunction getLowerCornerPosition(\n\tfocusedEditableElement: HTMLElement,\n\tconfig: PoweredByConfig,\n\tgetBalloonLeft: ( visibleEditableElementRect: Rect, balloonRect: Rect ) => number\n) {\n\treturn ( visibleEditableElementRect: Rect, balloonRect: Rect ) => {\n\t\tconst editableElementRect = new Rect( focusedEditableElement );\n\n\t\tif ( editableElementRect.width < NARROW_ROOT_WIDTH_THRESHOLD || editableElementRect.height < NARROW_ROOT_HEIGHT_THRESHOLD ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet balloonTop;\n\n\t\tif ( config.position === 'inside' ) {\n\t\t\tballoonTop = editableElementRect.bottom - balloonRect.height;\n\t\t}\n\t\telse {\n\t\t\tballoonTop = editableElementRect.bottom - balloonRect.height / 2;\n\t\t}\n\n\t\tballoonTop -= config.verticalOffset;\n\n\t\tconst balloonLeft = getBalloonLeft( editableElementRect, balloonRect );\n\n\t\t// Clone the editable element rect and place it where the balloon would be placed.\n\t\t// This will allow getVisible() to work from editable element's perspective (rect source).\n\t\t// and yield a result as if the balloon was on the same (scrollable) layer as the editable element.\n\t\tconst newBalloonPositionRect = visibleEditableElementRect\n\t\t\t.clone()\n\t\t\t.moveTo( balloonLeft, balloonTop )\n\t\t\t.getIntersection( balloonRect.clone().moveTo( balloonLeft, balloonTop ) )!;\n\n\t\tconst newBalloonPositionVisibleRect = newBalloonPositionRect.getVisible();\n\n\t\tif ( !newBalloonPositionVisibleRect || newBalloonPositionVisibleRect.getArea() < balloonRect.getArea() ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn {\n\t\t\ttop: balloonTop,\n\t\t\tleft: balloonLeft,\n\t\t\tname: `position_${ config.position }-side_${ config.side }`,\n\t\t\tconfig: {\n\t\t\t\twithArrow: false\n\t\t\t}\n\t\t};\n\t};\n}\n\nfunction getNormalizedConfig( editor: Editor ): PoweredByConfig {\n\tconst userConfig = editor.config.get( 'ui.poweredBy' );\n\tconst position = userConfig && userConfig.position || 'border';\n\n\treturn {\n\t\tposition,\n\t\tlabel: DEFAULT_LABEL,\n\t\tverticalOffset: position === 'inside' ? 5 : 0,\n\t\thorizontalOffset: 5,\n\n\t\tside: editor.locale.contentLanguageDirection === 'ltr' ? 'right' : 'left',\n\t\t...userConfig\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/arialiveannouncer\n */\n\nimport type { DomConverter } from '@ckeditor/ckeditor5-engine';\nimport type { Editor } from '@ckeditor/ckeditor5-core';\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport type ViewCollection from './viewcollection.js';\nimport View from './view.js';\n\nimport '../theme/components/arialiveannouncer/arialiveannouncer.css';\n\n/**\n * The politeness level of an `aria-live` announcement.\n *\n * Available keys are:\n * * `AriaLiveAnnouncerPoliteness.POLITE`,\n * * `AriaLiveAnnouncerPoliteness.ASSERTIVE`\n *\n * [Learn more](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions#Politeness_levels).\n */\nexport const AriaLiveAnnouncerPoliteness = {\n\tPOLITE: 'polite',\n\tASSERTIVE: 'assertive'\n} as const;\n\n/**\n * An accessibility helper that manages all ARIA live regions associated with an editor instance. ARIA live regions announce changes\n * to the state of the editor features.\n *\n * These announcements are consumed and propagated by screen readers and give users a better understanding of the current\n * state of the editor.\n *\n * To announce a state change to an editor use the {@link #announce} method:\n *\n * ```ts\n * editor.ui.ariaLiveAnnouncer.announce( 'Text of an announcement.' );\n * ```\n */\nexport default class AriaLiveAnnouncer {\n\t/**\n\t * The editor instance.\n\t */\n\tpublic readonly editor: Editor;\n\n\t/**\n\t * The view that aggregates all `aria-live` regions.\n\t */\n\tpublic view?: AriaLiveAnnouncerView;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * Some screen readers only look at changes in the aria-live region.\n\t\t * They might not read a region that already has content when it is added.\n\t\t * To stop this problem, make sure to set up regions for all politeness settings when the editor starts.\n\t\t */\n\t\teditor.once( 'ready', () => {\n\t\t\tfor ( const politeness of Object.values( AriaLiveAnnouncerPoliteness ) ) {\n\t\t\t\tthis.announce( '', politeness );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Sets an announcement text to an aria region that is then announced by a screen reader to the user.\n\t *\n\t * If the aria region of a specified politeness does not exist, it will be created and can be re-used later.\n\t *\n\t * The default announcement politeness level is `'polite'`.\n\t *\n\t * ```ts\n\t * // Most screen readers will queue announcements from multiple aria-live regions and read them out in the order they were emitted.\n \t * editor.ui.ariaLiveAnnouncer.announce( 'Image uploaded.' );\n \t * editor.ui.ariaLiveAnnouncer.announce( 'Connection lost. Reconnecting.' );\n \t * ```\n\t */\n\tpublic announce(\n\t\tannouncement: string,\n\t\tattributes: AriaLiveAnnouncerPolitenessValue | AriaLiveAnnounceConfig = AriaLiveAnnouncerPoliteness.POLITE\n\t): void {\n\t\tconst editor = this.editor;\n\n\t\tif ( !editor.ui.view ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this.view ) {\n\t\t\tthis.view = new AriaLiveAnnouncerView( editor.locale );\n\t\t\teditor.ui.view.body.add( this.view );\n\t\t}\n\n\t\tconst { politeness, isUnsafeHTML }: AriaLiveAnnounceConfig = typeof attributes === 'string' ? {\n\t\t\tpoliteness: attributes\n\t\t} : attributes;\n\n\t\tlet politenessRegionView = this.view.regionViews.find( view => view.politeness === politeness );\n\n\t\tif ( !politenessRegionView ) {\n\t\t\tpolitenessRegionView = new AriaLiveAnnouncerRegionView( editor, politeness );\n\t\t\tthis.view.regionViews.add( politenessRegionView );\n\t\t}\n\n\t\tpolitenessRegionView.announce( {\n\t\t\tannouncement,\n\t\t\tisUnsafeHTML\n\t\t} );\n\t}\n}\n\n/**\n * The view that aggregates all `aria-live` regions.\n */\nexport class AriaLiveAnnouncerView extends View {\n\t/**\n\t * A collection of all views that represent individual `aria-live` regions.\n\t */\n\tpublic readonly regionViews: ViewCollection<AriaLiveAnnouncerRegionView>;\n\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.regionViews = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-aria-live-announcer'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: this.regionViews\n\t\t} );\n\t}\n}\n\n/**\n * The view that represents a single `aria-live`.\n */\nexport class AriaLiveAnnouncerRegionView extends View {\n\t/**\n\t * Current politeness level of the region.\n\t */\n\tpublic readonly politeness: AriaLiveAnnouncerPolitenessValue;\n\n\t/**\n\t * DOM converter used to sanitize unsafe HTML passed to {@link #announce} method.\n\t */\n\tprivate _domConverter: DomConverter;\n\n\t/**\n\t * Interval used to remove additions. It prevents accumulation of added nodes in region.\n\t */\n\tprivate _pruneAnnouncementsInterval: ReturnType<typeof setInterval> | null;\n\n\tconstructor( editor: Editor, politeness: AriaLiveAnnouncerPolitenessValue ) {\n\t\tsuper( editor.locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\t'aria-live': politeness,\n\t\t\t\t'aria-relevant': 'additions'\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'ul',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-aria-live-region-list'\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\teditor.on( 'destroy', () => {\n\t\t\tif ( this._pruneAnnouncementsInterval !== null ) {\n\t\t\t\tclearInterval( this._pruneAnnouncementsInterval! );\n\t\t\t\tthis._pruneAnnouncementsInterval = null;\n\t\t\t}\n\t\t} );\n\n\t\tthis.politeness = politeness;\n\t\tthis._domConverter = editor.data.htmlProcessor.domConverter;\n\t\tthis._pruneAnnouncementsInterval = setInterval( () => {\n\t\t\tif ( this.element && this._listElement!.firstChild ) {\n\t\t\t\tthis._listElement!.firstChild!.remove();\n\t\t\t}\n\t\t}, 5000 );\n\t}\n\n\t/**\n\t * Appends new announcement to region.\n\t */\n\tpublic announce( { announcement, isUnsafeHTML }: AriaLiveAppendContentAttributes ): void {\n\t\tif ( !announcement.trim().length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst messageListItem = document.createElement( 'li' );\n\n\t\tif ( isUnsafeHTML ) {\n\t\t\tthis._domConverter.setContentOf( messageListItem, announcement );\n\t\t} else {\n\t\t\tmessageListItem.innerText = announcement;\n\t\t}\n\n\t\tthis._listElement!.appendChild( messageListItem );\n\t}\n\n\t/**\n\t * Return current announcements list HTML element.\n\t */\n\tprivate get _listElement(): HTMLElement | null {\n\t\treturn this.element!.querySelector( 'ul' )!;\n\t}\n}\n\ntype AriaLiveAnnouncerPolitenessValue = typeof AriaLiveAnnouncerPoliteness[ keyof typeof AriaLiveAnnouncerPoliteness ];\n\ntype AriaLiveAppendContentAttributes = {\n\tannouncement: string;\n\tisUnsafeHTML?: boolean;\n};\n\ntype AriaLiveAnnounceConfig = {\n\tpoliteness: AriaLiveAnnouncerPolitenessValue;\n\tisUnsafeHTML?: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarmenulistitemview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport ListItemView from '../list/listitemview.js';\nimport type MenuBarMenuView from './menubarmenuview.js';\n\nimport '../../theme/components/menubar/menubarmenulistitem.css';\n\n/**\n * A menu bar list item view, a child of {@link module:ui/menubar/menubarmenulistview~MenuBarMenuListView}.\n *\n * Populate this item with a {@link module:ui/menubar/menubarmenulistitembuttonview~MenuBarMenuListItemButtonView} instance\n * or a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} instance to create a sub-menu.\n */\nexport default class MenuBarMenuListItemView extends ListItemView {\n\t/**\n\t * Creates an instance of the list item view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale, parentMenuView: MenuBarMenuView ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-menu-bar__menu__item'\n\t\t\t\t]\n\t\t\t},\n\t\t\ton: {\n\t\t\t\t'mouseenter': bind.to( 'mouseenter' )\n\t\t\t}\n\t\t} );\n\n\t\tthis.delegate( 'mouseenter' ).to( parentMenuView );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/utils\n */\n\nimport MenuBarMenuListItemView from './menubarmenulistitemview.js';\nimport type MenuBarMenuView from './menubarmenuview.js';\nimport type {\n\tdefault as MenuBarView,\n\tMenuBarConfig,\n\tMenuBarMenuMouseEnterEvent,\n\tMenuBarMenuChangeIsOpenEvent,\n\tMenuBarMenuArrowRightEvent,\n\tMenuBarMenuArrowLeftEvent,\n\tMenuBarMenuDefinition,\n\tMenuBarConfigObject,\n\tMenuBarConfigAddedGroup,\n\tMenuBarConfigAddedMenu,\n\tMenuBarConfigAddedPosition,\n\tNormalizedMenuBarConfigObject,\n\tMenuBarConfigAddedItem\n} from './menubarview.js';\nimport clickOutsideHandler from '../bindings/clickoutsidehandler.js';\nimport type { ButtonExecuteEvent } from '../button/button.js';\nimport type ComponentFactory from '../componentfactory.js';\nimport type { FocusableView } from '../focuscycler.js';\nimport {\n\tlogWarning,\n\ttype Locale,\n\ttype ObservableChangeEvent,\n\ttype PositioningFunction\n} from '@ckeditor/ckeditor5-utils';\nimport { cloneDeep } from 'lodash-es';\n\nconst NESTED_PANEL_HORIZONTAL_OFFSET = 5;\n\n/**\n * Behaviors of the {@link module:ui/menubar/menubarview~MenuBarView} component.\n */\nexport const MenuBarBehaviors = {\n\t/**\n\t * When the bar is already open:\n\t * * Opens the menu when the user hovers over its button.\n\t * * Closes open menu when another menu's button gets hovered.\n\t */\n\ttoggleMenusAndFocusItemsOnHover( menuBarView: MenuBarView ): void {\n\t\tmenuBarView.on<MenuBarMenuMouseEnterEvent>( 'menu:mouseenter', evt => {\n\t\t\t// This behavior should be activated when one of condition is present:\n\t\t\t// 1. The user opened any submenu of menubar and hover over items in the menu bar.\n\t\t\t// 2. The user focused whole menubar using keyboard interaction and enabled focus borders and hover over items in the menu bar.\n\t\t\tif ( !menuBarView.isFocusBorderEnabled && !menuBarView.isOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( menuBarView.isOpen ) {\n\t\t\t\tfor ( const menuView of menuBarView.menus ) {\n\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // const wasOpen = menuView.isOpen;\n\n\t\t\t\t\tconst pathLeaf = evt.path[ 0 ];\n\t\t\t\t\tconst isListItemContainingMenu = pathLeaf instanceof MenuBarMenuListItemView && pathLeaf.children.first === menuView;\n\n\t\t\t\t\tmenuView.isOpen = ( evt.path.includes( menuView ) || isListItemContainingMenu ) && menuView.isEnabled;\n\n\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // if ( wasOpen !== menuView.isOpen ) {\n\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] toggleMenusAndFocusItemsOnHover(): Toggle',\n\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // \tlogMenu( menuView ), 'isOpen', menuView.isOpen\n\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // );\n\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t( evt.source as FocusableView ).focus();\n\t\t} );\n\t},\n\n\t/**\n\t * Moves between top-level menus using the arrow left and right keys.\n\t *\n\t * If the menubar has already been open, the arrow keys move focus between top-level menu buttons and open them.\n\t * If the menubar is closed, the arrow keys only move focus between top-level menu buttons.\n\t */\n\tfocusCycleMenusOnArrows( menuBarView: MenuBarView ): void {\n\t\tconst isContentRTL = menuBarView.locale!.uiLanguageDirection === 'rtl';\n\n\t\tmenuBarView.on<MenuBarMenuArrowRightEvent>( 'menu:arrowright', evt => {\n\t\t\tcycleTopLevelMenus( evt.source as MenuBarMenuView, isContentRTL ? -1 : 1 );\n\t\t} );\n\n\t\tmenuBarView.on<MenuBarMenuArrowLeftEvent>( 'menu:arrowleft', evt => {\n\t\t\tcycleTopLevelMenus( evt.source as MenuBarMenuView, isContentRTL ? 1 : -1 );\n\t\t} );\n\n\t\tfunction cycleTopLevelMenus( currentMenuView: MenuBarMenuView, step: number ) {\n\t\t\tconst currentIndex = menuBarView.children.getIndex( currentMenuView );\n\t\t\tconst isCurrentMenuViewOpen = currentMenuView.isOpen;\n\t\t\tconst menusCount = menuBarView.children.length;\n\t\t\tconst menuViewToOpen = menuBarView.children.get( ( currentIndex + menusCount + step ) % menusCount )!;\n\n\t\t\tcurrentMenuView.isOpen = false;\n\n\t\t\tif ( isCurrentMenuViewOpen ) {\n\t\t\t\tmenuViewToOpen.isOpen = true;\n\t\t\t}\n\n\t\t\tmenuViewToOpen.buttonView.focus();\n\t\t}\n\t},\n\n\t/**\n\t * Closes the entire sub-menu structure when the bar is closed. This prevents sub-menus from being open if the user\n\t * closes the entire bar, and then re-opens some top-level menu.\n\t */\n\tcloseMenusWhenTheBarCloses( menuBarView: MenuBarView ): void {\n\t\tmenuBarView.on<ObservableChangeEvent<boolean>>( 'change:isOpen', () => {\n\t\t\tif ( !menuBarView.isOpen ) {\n\t\t\t\tmenuBarView.menus.forEach( menuView => {\n\t\t\t\t\tmenuView.isOpen = false;\n\n\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] closeMenusWhenTheBarCloses(): Closing', logMenu( menuView ) );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Handles the following case:\n\t * 1. Hover to open a sub-menu (A). The button has focus.\n\t * 2. Press arrow up/down to move focus to another sub-menu (B) button.\n\t * 3. Press arrow right to open the sub-menu (B).\n\t * 4. The sub-menu (A) should close as it would with `toggleMenusAndFocusItemsOnHover()`.\n\t */\n\tcloseMenuWhenAnotherOnTheSameLevelOpens( menuBarView: MenuBarView ): void {\n\t\tmenuBarView.on<MenuBarMenuChangeIsOpenEvent>( 'menu:change:isOpen', ( evt, name, isOpen ) => {\n\t\t\tif ( isOpen ) {\n\t\t\t\tmenuBarView.menus\n\t\t\t\t\t.filter( menuView => {\n\t\t\t\t\t\treturn ( evt.source as any ).parentMenuView === menuView.parentMenuView &&\n\t\t\t\t\t\t\tevt.source !== menuView &&\n\t\t\t\t\t\t\tmenuView.isOpen;\n\t\t\t\t\t} ).forEach( menuView => {\n\t\t\t\t\t\tmenuView.isOpen = false;\n\n\t\t\t\t\t\t// @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] closeMenuWhenAnotherOpens(): Closing', logMenu( menuView ) );\n\t\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Closes the bar when the user clicked outside of it (page body, editor root, etc.).\n\t */\n\tcloseOnClickOutside( menuBarView: MenuBarView ): void {\n\t\tclickOutsideHandler( {\n\t\t\temitter: menuBarView,\n\t\t\tactivator: () => menuBarView.isOpen,\n\t\t\tcallback: () => menuBarView.close(),\n\t\t\tcontextElements: () => menuBarView.children.map( child => child.element! )\n\t\t} );\n\t},\n\n\t/**\n\t * Tracks the keyboard focus interaction on the menu bar view. It is used to determine if the nested items\n\t * of the menu bar should render focus rings after first interaction with the keyboard.\n\t */\n\tenableFocusHighlightOnInteraction( menuBarView: MenuBarView ): void {\n\t\tlet isKeyPressed: boolean = false;\n\n\t\tmenuBarView.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( _, evt, isOpen ) => {\n\t\t\tif ( !isOpen ) {\n\t\t\t\t// Keep the focus border if the menu bar was closed by a keyboard interaction (Esc key).\n\t\t\t\t// The user remains in the keyboard navigation mode and can traverse the main categories.\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/16719.\n\t\t\t\tif ( !isKeyPressed ) {\n\t\t\t\t\tmenuBarView.isFocusBorderEnabled = false;\n\t\t\t\t}\n\n\t\t\t\t// Reset the flag when the menu bar is closed, menu items tend to intercept `keyup` event\n\t\t\t\t// and sometimes, after pressing `enter` on focused item, `isKeyPressed` stuck in `true` state.\n\t\t\t\tisKeyPressed = false;\n\t\t\t}\n\t\t} );\n\n\t\tmenuBarView.listenTo( menuBarView.element!, 'keydown', () => {\n\t\t\tisKeyPressed = true;\n\t\t}, { useCapture: true } );\n\n\t\tmenuBarView.listenTo( menuBarView.element!, 'keyup', () => {\n\t\t\tisKeyPressed = false;\n\t\t}, { useCapture: true } );\n\n\t\tmenuBarView.listenTo( menuBarView.element!, 'focus', () => {\n\t\t\tif ( isKeyPressed ) {\n\t\t\t\tmenuBarView.isFocusBorderEnabled = true;\n\t\t\t}\n\t\t}, { useCapture: true } );\n\t}\n};\n\n/**\n * Behaviors of the {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} component.\n */\nexport const MenuBarMenuBehaviors = {\n\t/**\n\t * If the button of the menu is focused, pressing the arrow down key should open the panel and focus it.\n\t * This is analogous to the {@link module:ui/dropdown/dropdownview~DropdownView}.\n\t */\n\topenAndFocusPanelOnArrowDownKey( menuView: MenuBarMenuView ): void {\n\t\tmenuView.keystrokes.set( 'arrowdown', ( data, cancel ) => {\n\t\t\tif ( menuView.focusTracker.focusedElement === menuView.buttonView.element ) {\n\t\t\t\tif ( !menuView.isOpen ) {\n\t\t\t\t\tmenuView.isOpen = true;\n\t\t\t\t}\n\n\t\t\t\tmenuView.panelView.focus();\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Open the menu on the right arrow key press. This allows for navigating to sub-menus using the keyboard.\n\t */\n\topenOnArrowRightKey( menuView: MenuBarMenuView ): void {\n\t\tconst keystroke = menuView.locale!.uiLanguageDirection === 'rtl' ? 'arrowleft' : 'arrowright';\n\n\t\tmenuView.keystrokes.set( keystroke, ( data, cancel ) => {\n\t\t\tif ( menuView.focusTracker.focusedElement !== menuView.buttonView.element || !menuView.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] openOnArrowRightKey(): Opening', logMenu( menuView ) );\n\n\t\t\tif ( !menuView.isOpen ) {\n\t\t\t\tmenuView.isOpen = true;\n\t\t\t}\n\n\t\t\tmenuView.panelView.focus();\n\t\t\tcancel();\n\t\t} );\n\t},\n\n\t/**\n\t * Opens the menu on its button click. Note that this behavior only opens but never closes the menu (unlike\n\t * {@link module:ui/dropdown/dropdownview~DropdownView}).\n\t */\n\topenOnButtonClick( menuView: MenuBarMenuView ): void {\n\t\tmenuView.buttonView.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\tmenuView.isOpen = true;\n\t\t} );\n\t},\n\n\t/**\n\t * Toggles the menu on its button click. This behavior is analogous to {@link module:ui/dropdown/dropdownview~DropdownView}.\n\t */\n\ttoggleOnButtonClick( menuView: MenuBarMenuView ): void {\n\t\tmenuView.buttonView.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\tmenuView.isOpen = !menuView.isOpen;\n\t\t} );\n\t},\n\n\t/**\n\t * Opens the menu and focuses the panel content upon pressing the Enter key.\n\t */\n\topenAndFocusOnEnterKeyPress( menuView: MenuBarMenuView ): void {\n\t\tmenuView.keystrokes.set( 'enter', ( data, cancel ) => {\n\t\t\t// Engage only for Enter key press when the button is focused. The panel can contain\n\t\t\t// other UI components and features that rely on the Enter key press.\n\t\t\tif ( menuView.focusTracker.focusedElement !== menuView.buttonView.element ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmenuView.isOpen = true;\n\t\t\tmenuView.panelView.focus();\n\t\t\tcancel();\n\t\t} );\n\t},\n\n\t/**\n\t * Closes the menu on the right left key press. This allows for navigating to sub-menus using the keyboard.\n\t */\n\tcloseOnArrowLeftKey( menuView: MenuBarMenuView ): void {\n\t\tconst keystroke = menuView.locale!.uiLanguageDirection === 'rtl' ? 'arrowright' : 'arrowleft';\n\n\t\tmenuView.keystrokes.set( keystroke, ( data, cancel ) => {\n\t\t\tif ( menuView.isOpen ) {\n\t\t\t\tmenuView.isOpen = false;\n\t\t\t\tmenuView.focus();\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Closes the menu on the esc key press. This allows for navigating to sub-menus using the keyboard.\n\t */\n\tcloseOnEscKey( menuView: MenuBarMenuView ): void {\n\t\tmenuView.keystrokes.set( 'esc', ( data, cancel ) => {\n\t\t\tif ( menuView.isOpen ) {\n\t\t\t\tmenuView.isOpen = false;\n\t\t\t\tmenuView.focus();\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\t},\n\n\t/**\n\t * Closes the menu when its parent menu also closed. This prevents from orphaned open menus when the parent menu re-opens.\n\t */\n\tcloseOnParentClose( menuView: MenuBarMenuView ): void {\n\t\tmenuView.parentMenuView!.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( evt, name, isOpen ) => {\n\t\t\tif ( !isOpen && evt.source === menuView.parentMenuView ) {\n\t\t\t\t// @if CK_DEBUG_MENU_BAR // console.log( '[BEHAVIOR] closeOnParentClose(): Closing', logMenu( menuView ) );\n\n\t\t\t\tmenuView.isOpen = false;\n\t\t\t}\n\t\t} );\n\t}\n};\n\n// @if CK_DEBUG_MENU_BAR // function logMenu( menuView: MenuBarMenuView ) {\n// @if CK_DEBUG_MENU_BAR //\treturn `\"${ menuView.buttonView.label }\"`;\n// @if CK_DEBUG_MENU_BAR // }\n\n/**\n * Contains every positioning function used by {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} that decides where the\n * {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#panelView} should be placed.\n *\n * Top-level menu positioning functions:\n *\n *\t┌──────┐\n *\t│      │\n *\t├──────┴────────┐\n *\t│               │\n *\t│               │\n *\t│               │\n *\t│            SE │\n *\t└───────────────┘\n *\n *\t         ┌──────┐\n *\t         │      │\n *\t┌────────┴──────┤\n *\t│               │\n *\t│               │\n *\t│               │\n *\t│ SW            │\n *\t└───────────────┘\n *\n *\t┌───────────────┐\n *\t│ NW            │\n *\t│               │\n *\t│               │\n *\t│               │\n *\t└────────┬──────┤\n *\t         │      │\n *\t         └──────┘\n *\n *\t┌───────────────┐\n *\t│            NE │\n *\t│               │\n *\t│               │\n *\t│               │\n *\t├──────┬────────┘\n *\t│      │\n *\t└──────┘\n *\n * Sub-menu positioning functions:\n *\n *\t┌──────┬───────────────┐\n *\t│      │               │\n *\t└──────┤               │\n *\t       │               │\n *\t       │            ES │\n *\t       └───────────────┘\n *\n *\t┌───────────────┬──────┐\n *\t│               │      │\n *\t│               ├──────┘\n *\t│               │\n *\t│ WS            │\n *\t└───────────────┘\n *\n *\t       ┌───────────────┐\n *\t       │            EN │\n *\t       │               │\n *\t┌──────┤               │\n *\t│      │               │\n *\t└──────┴───────────────┘\n *\n *\t┌───────────────┐\n *\t│ WN            │\n *\t│               │\n *\t│               ├──────┐\n *\t│               │      │\n *\t└───────────────┴──────┘\n */\nexport const MenuBarMenuViewPanelPositioningFunctions: Record<string, PositioningFunction> = {\n\tsouthEast: buttonRect => {\n\t\treturn {\n\t\t\ttop: buttonRect.bottom,\n\t\t\tleft: buttonRect.left,\n\t\t\tname: 'se'\n\t\t};\n\t},\n\tsouthWest: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.bottom,\n\t\t\tleft: buttonRect.left - panelRect.width + buttonRect.width,\n\t\t\tname: 'sw'\n\t\t};\n\t},\n\tnorthEast: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\tleft: buttonRect.left,\n\t\t\tname: 'ne'\n\t\t};\n\t},\n\tnorthWest: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\tleft: buttonRect.left - panelRect.width + buttonRect.width,\n\t\t\tname: 'nw'\n\t\t};\n\t},\n\teastSouth: buttonRect => {\n\t\treturn {\n\t\t\ttop: buttonRect.top,\n\t\t\tleft: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\t\tname: 'es'\n\t\t};\n\t},\n\teastNorth: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\tleft: buttonRect.right - NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\t\tname: 'en'\n\t\t};\n\t},\n\twestSouth: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.top,\n\t\t\tleft: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\t\tname: 'ws'\n\t\t};\n\t},\n\twestNorth: ( buttonRect, panelRect ) => {\n\t\treturn {\n\t\t\ttop: buttonRect.top - panelRect.height,\n\t\t\tleft: buttonRect.left - panelRect.width + NESTED_PANEL_HORIZONTAL_OFFSET,\n\t\t\tname: 'wn'\n\t\t};\n\t}\n} as const;\n\n/**\n * The default items {@link module:core/editor/editorconfig~EditorConfig#menuBar configuration} of the\n * {@link module:ui/menubar/menubarview~MenuBarView} component. It contains names of all menu bar components\n * registered in the {@link module:ui/componentfactory~ComponentFactory component factory} (available in the project).\n *\n * **Note**: Menu bar component names provided by core editor features are prefixed with `menuBar:` in order to distinguish\n * them from components referenced by the {@link module:core/editor/editorconfig~EditorConfig#toolbar toolbar configuration}, for instance,\n * `'menuBar:bold'` is a menu bar button but `'bold'` is a toolbar button.\n *\n * Below is the preset menu bar structure (the default value of `config.menuBar.items` property):\n *\n * ```ts\n * [\n * \t{\n * \t\tmenuId: 'file',\n * \t\tlabel: 'File',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'export',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:exportPdf',\n * \t\t\t\t\t'menuBar:exportWord'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'import',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:importWord'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'revisionHistory',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:revisionHistory'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'edit',\n * \t\tlabel: 'Edit',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'undo',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:undo',\n * \t\t\t\t\t'menuBar:redo'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'selectAll',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:selectAll'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'findAndReplace',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:findAndReplace'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'view',\n * \t\tlabel: 'View',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'sourceEditing',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:sourceEditing'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'showBlocks',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:showBlocks'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'previewMergeFields',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:previewMergeFields'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'restrictedEditingException',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:restrictedEditingException'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'insert',\n * \t\tlabel: 'Insert',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertMainWidgets',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:insertImage',\n * \t\t\t\t\t'menuBar:ckbox',\n * \t\t\t\t\t'menuBar:ckfinder',\n * \t\t\t\t\t'menuBar:insertTable'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertInline',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:link',\n * \t\t\t\t\t'menuBar:comment',\n * \t\t\t\t\t'menuBar:insertMergeField'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertMinorWidgets',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:mediaEmbed',\n * \t\t\t\t\t'menuBar:insertTemplate',\n * \t\t\t\t\t'menuBar:blockQuote',\n * \t\t\t\t\t'menuBar:codeBlock',\n * \t\t\t\t\t'menuBar:htmlEmbed'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'insertStructureWidgets',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:horizontalLine',\n * \t\t\t\t\t'menuBar:pageBreak',\n * \t\t\t\t\t'menuBar:tableOfContents'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'restrictedEditing',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:restrictedEditing'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'format',\n * \t\tlabel: 'Format',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'textAndFont',\n * \t\t\t\titems: [\n * \t\t\t\t\t{\n * \t\t\t\t\t\tmenuId: 'text',\n * \t\t\t\t\t\tlabel: 'Text',\n * \t\t\t\t\t\tgroups: [\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'basicStyles',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:bold',\n * \t\t\t\t\t\t\t\t\t'menuBar:italic',\n * \t\t\t\t\t\t\t\t\t'menuBar:underline',\n * \t\t\t\t\t\t\t\t\t'menuBar:strikethrough',\n * \t\t\t\t\t\t\t\t\t'menuBar:superscript',\n * \t\t\t\t\t\t\t\t\t'menuBar:subscript',\n * \t\t\t\t\t\t\t\t\t'menuBar:code'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t},\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'textPartLanguage',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:textPartLanguage'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t}\n * \t\t\t\t\t\t]\n * \t\t\t\t\t},\n * \t\t\t\t\t{\n * \t\t\t\t\t\tmenuId: 'font',\n * \t\t\t\t\t\tlabel: 'Font',\n * \t\t\t\t\t\tgroups: [\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'fontProperties',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:fontSize',\n * \t\t\t\t\t\t\t\t\t'menuBar:fontFamily'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t},\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'fontColors',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:fontColor',\n * \t\t\t\t\t\t\t\t\t'menuBar:fontBackgroundColor'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t},\n * \t\t\t\t\t\t\t{\n * \t\t\t\t\t\t\t\tgroupId: 'highlight',\n * \t\t\t\t\t\t\t\titems: [\n * \t\t\t\t\t\t\t\t\t'menuBar:highlight'\n * \t\t\t\t\t\t\t\t]\n * \t\t\t\t\t\t\t}\n * \t\t\t\t\t\t]\n * \t\t\t\t\t},\n * \t\t\t\t\t'menuBar:heading'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'list',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:bulletedList',\n * \t\t\t\t\t'menuBar:numberedList',\n * \t\t\t\t\t'menuBar:multiLevelList',\n * \t\t\t\t\t'menuBar:todoList'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'indent',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:alignment',\n * \t\t\t\t\t'menuBar:indent',\n * \t\t\t\t\t'menuBar:outdent'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'caseChange',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:caseChange'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'removeFormat',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:removeFormat'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'tools',\n * \t\tlabel: 'Tools',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'aiTools',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:aiAssistant',\n * \t\t\t\t\t'menuBar:aiCommands'\n * \t\t\t\t]\n * \t\t\t},\n * \t\t\t{\n * \t\t\t\tgroupId: 'tools',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:trackChanges',\n * \t\t\t\t\t'menuBar:commentsArchive'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t},\n * \t{\n * \t\tmenuId: 'help',\n * \t\tlabel: 'Help',\n * \t\tgroups: [\n * \t\t\t{\n * \t\t\t\tgroupId: 'help',\n * \t\t\t\titems: [\n * \t\t\t\t\t'menuBar:accessibilityHelp'\n * \t\t\t\t]\n * \t\t\t}\n * \t\t]\n * \t}\n * ];\n * ```\n *\n * The menu bar can be customized using the `config.menuBar.removeItems` and `config.menuBar.addItems` properties.\n */\n// **NOTE: Whenever you make changes to this value, reflect it in the documentation above!**\nexport const DefaultMenuBarItems: MenuBarConfigObject[ 'items' ] = [\n\t{\n\t\tmenuId: 'file',\n\t\tlabel: 'File',\n\t\tgroups: [\n\t\t\t{\n\t\t\t\tgroupId: 'export',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:exportPdf',\n\t\t\t\t\t'menuBar:exportWord'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'import',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:importWord'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'revisionHistory',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:revisionHistory'\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\tmenuId: 'edit',\n\t\tlabel: 'Edit',\n\t\tgroups: [\n\t\t\t{\n\t\t\t\tgroupId: 'undo',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:undo',\n\t\t\t\t\t'menuBar:redo'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'selectAll',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:selectAll'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'findAndReplace',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:findAndReplace'\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\tmenuId: 'view',\n\t\tlabel: 'View',\n\t\tgroups: [\n\t\t\t{\n\t\t\t\tgroupId: 'sourceEditing',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:sourceEditing'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'showBlocks',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:showBlocks'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'previewMergeFields',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:previewMergeFields'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'restrictedEditing',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:restrictedEditing'\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\tmenuId: 'insert',\n\t\tlabel: 'Insert',\n\t\tgroups: [\n\t\t\t{\n\t\t\t\tgroupId: 'insertMainWidgets',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:insertImage',\n\t\t\t\t\t'menuBar:ckbox',\n\t\t\t\t\t'menuBar:ckfinder',\n\t\t\t\t\t'menuBar:insertTable'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'insertInline',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:link',\n\t\t\t\t\t'menuBar:comment',\n\t\t\t\t\t'menuBar:insertMergeField'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'insertMinorWidgets',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:mediaEmbed',\n\t\t\t\t\t'menuBar:insertTemplate',\n\t\t\t\t\t'menuBar:specialCharacters',\n\t\t\t\t\t'menuBar:blockQuote',\n\t\t\t\t\t'menuBar:codeBlock',\n\t\t\t\t\t'menuBar:htmlEmbed'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'insertStructureWidgets',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:horizontalLine',\n\t\t\t\t\t'menuBar:pageBreak',\n\t\t\t\t\t'menuBar:tableOfContents'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'restrictedEditingException',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:restrictedEditingException'\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\tmenuId: 'format',\n\t\tlabel: 'Format',\n\t\tgroups: [\n\t\t\t{\n\t\t\t\tgroupId: 'textAndFont',\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tmenuId: 'text',\n\t\t\t\t\t\tlabel: 'Text',\n\t\t\t\t\t\tgroups: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tgroupId: 'basicStyles',\n\t\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\t'menuBar:bold',\n\t\t\t\t\t\t\t\t\t'menuBar:italic',\n\t\t\t\t\t\t\t\t\t'menuBar:underline',\n\t\t\t\t\t\t\t\t\t'menuBar:strikethrough',\n\t\t\t\t\t\t\t\t\t'menuBar:superscript',\n\t\t\t\t\t\t\t\t\t'menuBar:subscript',\n\t\t\t\t\t\t\t\t\t'menuBar:code'\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tgroupId: 'textPartLanguage',\n\t\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\t'menuBar:textPartLanguage'\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmenuId: 'font',\n\t\t\t\t\t\tlabel: 'Font',\n\t\t\t\t\t\tgroups: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tgroupId: 'fontProperties',\n\t\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\t'menuBar:fontSize',\n\t\t\t\t\t\t\t\t\t'menuBar:fontFamily'\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tgroupId: 'fontColors',\n\t\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\t'menuBar:fontColor',\n\t\t\t\t\t\t\t\t\t'menuBar:fontBackgroundColor'\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tgroupId: 'highlight',\n\t\t\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t\t\t'menuBar:highlight'\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t'menuBar:heading'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'list',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:bulletedList',\n\t\t\t\t\t'menuBar:numberedList',\n\t\t\t\t\t'menuBar:multiLevelList',\n\t\t\t\t\t'menuBar:todoList'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'indent',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:alignment',\n\t\t\t\t\t'menuBar:indent',\n\t\t\t\t\t'menuBar:outdent'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'caseChange',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:caseChange'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'removeFormat',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:removeFormat'\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\tmenuId: 'tools',\n\t\tlabel: 'Tools',\n\t\tgroups: [\n\t\t\t{\n\t\t\t\tgroupId: 'aiTools',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:aiAssistant',\n\t\t\t\t\t'menuBar:aiCommands'\n\t\t\t\t]\n\t\t\t},\n\t\t\t{\n\t\t\t\tgroupId: 'tools',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:trackChanges',\n\t\t\t\t\t'menuBar:commentsArchive'\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\tmenuId: 'help',\n\t\tlabel: 'Help',\n\t\tgroups: [\n\t\t\t{\n\t\t\t\tgroupId: 'help',\n\t\t\t\titems: [\n\t\t\t\t\t'menuBar:accessibilityHelp'\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t}\n];\n\n/**\n * Performs a cleanup and normalization of the menu bar configuration.\n */\nexport function normalizeMenuBarConfig( config: Readonly<MenuBarConfig> ): NormalizedMenuBarConfigObject {\n\tlet configObject: NormalizedMenuBarConfigObject;\n\n\t// The integrator specified the config as an object but without items. Let's give them defaults but respect their\n\t// additions and removals.\n\tif ( !( 'items' in config ) || !config.items ) {\n\t\tconfigObject = {\n\t\t\titems: cloneDeep( DefaultMenuBarItems ) as Array<MenuBarMenuDefinition>,\n\t\t\taddItems: [],\n\t\t\tremoveItems: [],\n\t\t\tisVisible: true,\n\t\t\tisUsingDefaultConfig: true,\n\t\t\t...config\n\t\t};\n\t}\n\t// The integrator specified the config as an object and there are items there. Let's take it as it is.\n\telse {\n\t\tconfigObject = {\n\t\t\titems: config.items,\n\t\t\tremoveItems: [],\n\t\t\taddItems: [],\n\t\t\tisVisible: true,\n\t\t\tisUsingDefaultConfig: false,\n\t\t\t...config\n\t\t};\n\t}\n\n\treturn configObject;\n}\n\n/**\n * Processes a normalized menu bar config and returns a config clone with the following modifications:\n *\n * * Removed components that are not available in the component factory,\n * * Removed obsolete separators,\n * * Purged empty menus,\n * * Localized top-level menu labels.\n */\nexport function processMenuBarConfig( {\n\tnormalizedConfig,\n\tlocale,\n\tcomponentFactory,\n\textraItems\n}: {\n\tnormalizedConfig: NormalizedMenuBarConfigObject;\n\tlocale: Locale;\n\tcomponentFactory: ComponentFactory;\n\textraItems: Array<MenuBarConfigAddedItem | MenuBarConfigAddedGroup | MenuBarConfigAddedMenu>;\n} ): NormalizedMenuBarConfigObject {\n\tconst configClone = cloneDeep( normalizedConfig ) as NormalizedMenuBarConfigObject;\n\n\thandleAdditions( normalizedConfig, configClone, extraItems );\n\thandleRemovals( normalizedConfig, configClone );\n\thandleAdditions( normalizedConfig, configClone, configClone.addItems );\n\tpurgeUnavailableComponents( normalizedConfig, configClone, componentFactory );\n\tpurgeEmptyMenus( normalizedConfig, configClone );\n\tlocalizeMenuLabels( configClone, locale );\n\n\treturn configClone;\n}\n\n/**\n * Removes items from the menu bar config based on user `removeItems` configuration. Users can remove\n * individual items, groups, or entire menus. For each removed item, a warning is logged if the item\n * was not found in the configuration.\n */\nfunction handleRemovals(\n\toriginalConfig: NormalizedMenuBarConfigObject,\n\tconfig: NormalizedMenuBarConfigObject\n) {\n\tconst itemsToBeRemoved = config.removeItems;\n\tconst successfullyRemovedItems: Array<string> = [];\n\n\t// Remove top-level menus.\n\tconfig.items = config.items.filter( ( { menuId } ) => {\n\t\tif ( itemsToBeRemoved.includes( menuId ) ) {\n\t\t\tsuccessfullyRemovedItems.push( menuId );\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} );\n\n\twalkConfigMenus( config.items, menuDefinition => {\n\t\t// Remove groups from menus.\n\t\tmenuDefinition.groups = menuDefinition.groups.filter( ( { groupId } ) => {\n\t\t\tif ( itemsToBeRemoved.includes( groupId ) ) {\n\t\t\t\tsuccessfullyRemovedItems.push( groupId );\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} );\n\n\t\t// Remove sub-menus and items from groups.\n\t\tfor ( const groupDefinition of menuDefinition.groups ) {\n\t\t\tgroupDefinition.items = groupDefinition.items.filter( item => {\n\t\t\t\tconst itemId = getIdFromGroupItem( item );\n\n\t\t\t\tif ( itemsToBeRemoved.includes( itemId ) ) {\n\t\t\t\t\tsuccessfullyRemovedItems.push( itemId );\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} );\n\t\t}\n\t} );\n\n\tfor ( const itemName of itemsToBeRemoved ) {\n\t\tif ( !successfullyRemovedItems.includes( itemName ) ) {\n\t\t\t/**\n\t\t\t * There was a problem processing the configuration of the menu bar. The item with the given\n\t\t\t * name does could not be removed from the menu bar configuration.\n\t\t\t *\n\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t * to provide a menu bar item has not been loaded or there is a typo in the\n\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration}.\n\t\t\t *\n\t\t\t * @error menu-bar-item-could-not-be-removed\n\t\t\t * @param menuBarConfig The full configuration of the menu bar.\n\t\t\t * @param itemName The name of the item that was not removed from the menu bar.\n\t\t\t */\n\t\t\tlogWarning( 'menu-bar-item-could-not-be-removed', {\n\t\t\t\tmenuBarConfig: originalConfig,\n\t\t\t\titemName\n\t\t\t} );\n\t\t}\n\t}\n}\n\n/**\n * Adds provided items to config. It allows for adding menus, groups, and items at arbitrary\n * positions in the menu bar. If the position does not exist, a warning is logged.\n */\nfunction handleAdditions(\n\toriginalConfig: NormalizedMenuBarConfigObject,\n\tconfig: NormalizedMenuBarConfigObject,\n\titems: Array<MenuBarConfigAddedItem | MenuBarConfigAddedGroup | MenuBarConfigAddedMenu>\n) {\n\tconst successFullyAddedItems: typeof items = [];\n\n\tif ( items.length == 0 ) {\n\t\treturn;\n\t}\n\n\tfor ( const itemToAdd of items ) {\n\t\tconst relation = getRelationFromPosition( itemToAdd.position );\n\t\tconst relativeId = getRelativeIdFromPosition( itemToAdd.position );\n\n\t\t// Adding a menu.\n\t\tif ( isMenuBarMenuAddition( itemToAdd ) ) {\n\t\t\tif ( !relativeId ) {\n\t\t\t\t// Adding a top-level menu at the beginning of the menu bar.\n\t\t\t\tif ( relation === 'start' ) {\n\t\t\t\t\tconfig.items.unshift( itemToAdd.menu );\n\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t}\n\t\t\t\t// Adding a top-level menu at the end of the menu bar.\n\t\t\t\telse if ( relation === 'end' ) {\n\t\t\t\t\tconfig.items.push( itemToAdd.menu );\n\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst topLevelMenuDefinitionIndex = config.items.findIndex( menuDefinition => menuDefinition.menuId === relativeId );\n\n\t\t\t\t// Adding a top-level menu somewhere between existing menu bar menus.\n\t\t\t\tif ( topLevelMenuDefinitionIndex != -1 ) {\n\t\t\t\t\tif ( relation === 'before' ) {\n\t\t\t\t\t\tconfig.items.splice( topLevelMenuDefinitionIndex, 0, itemToAdd.menu );\n\t\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t\t} else if ( relation === 'after' ) {\n\t\t\t\t\t\tconfig.items.splice( topLevelMenuDefinitionIndex + 1, 0, itemToAdd.menu );\n\t\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Adding a sub-menu to an existing items group.\n\t\t\t\telse {\n\t\t\t\t\tconst wasAdded = addMenuOrItemToGroup( config, itemToAdd.menu, relativeId, relation );\n\n\t\t\t\t\tif ( wasAdded ) {\n\t\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Adding a group.\n\t\telse if ( isMenuBarMenuGroupAddition( itemToAdd ) ) {\n\t\t\twalkConfigMenus( config.items, menuDefinition => {\n\t\t\t\tif ( menuDefinition.menuId === relativeId ) {\n\t\t\t\t\t// Add a group at the start of a menu.\n\t\t\t\t\tif ( relation === 'start' ) {\n\t\t\t\t\t\tmenuDefinition.groups.unshift( itemToAdd.group );\n\t\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t\t}\n\t\t\t\t\t// Add a group at the end of a menu.\n\t\t\t\t\telse if ( relation === 'end' ) {\n\t\t\t\t\t\tmenuDefinition.groups.push( itemToAdd.group );\n\t\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst relativeGroupIndex = menuDefinition.groups.findIndex( group => group.groupId === relativeId );\n\n\t\t\t\t\tif ( relativeGroupIndex !== -1 ) {\n\t\t\t\t\t\t// Add a group before an existing group in a menu.\n\t\t\t\t\t\tif ( relation === 'before' ) {\n\t\t\t\t\t\t\tmenuDefinition.groups.splice( relativeGroupIndex, 0, itemToAdd.group );\n\t\t\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Add a group after an existing group in a menu.\n\t\t\t\t\t\telse if ( relation === 'after' ) {\n\t\t\t\t\t\t\tmenuDefinition.groups.splice( relativeGroupIndex + 1, 0, itemToAdd.group );\n\t\t\t\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\t// Adding an item to an existing items group.\n\t\telse {\n\t\t\tconst wasAdded = addMenuOrItemToGroup( config, itemToAdd.item, relativeId, relation );\n\n\t\t\tif ( wasAdded ) {\n\t\t\t\tsuccessFullyAddedItems.push( itemToAdd );\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( const addedItemConfig of items ) {\n\t\tif ( !successFullyAddedItems.includes( addedItemConfig ) ) {\n\t\t\t/**\n\t\t\t * There was a problem processing the configuration of the menu bar. The configured item could not be added\n\t\t\t * because the position it was supposed to be added to does not exist.\n\t\t\t *\n\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t * to provide a menu bar item has not been loaded or there is a typo in the\n\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration}.\n\t\t\t *\n\t\t\t * @error menu-bar-item-could-not-be-removed\n\t\t\t * @param menuBarConfig The full configuration of the menu bar.\n\t\t\t * @param itemName The name of the item that was not removed from the menu bar.\n\t\t\t */\n\t\t\tlogWarning( 'menu-bar-item-could-not-be-added', {\n\t\t\t\tmenuBarConfig: originalConfig,\n\t\t\t\taddedItemConfig\n\t\t\t} );\n\t\t}\n\t}\n}\n\n/**\n * Handles adding a sub-menu or an item into a group. The logic is the same for both cases.\n */\nfunction addMenuOrItemToGroup(\n\tconfig: NormalizedMenuBarConfigObject,\n\titemOrMenuToAdd: string | MenuBarMenuDefinition,\n\trelativeId: string | null,\n\trelation: 'start' | 'end' | 'before' | 'after'\n): boolean {\n\tlet wasAdded = false;\n\n\twalkConfigMenus( config.items, menuDefinition => {\n\t\tfor ( const { groupId, items: groupItems } of menuDefinition.groups ) {\n\t\t\t// Avoid infinite loops.\n\t\t\tif ( wasAdded ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( groupId === relativeId ) {\n\t\t\t\t// Adding an item/menu at the beginning of a group.\n\t\t\t\tif ( relation === 'start' ) {\n\t\t\t\t\tgroupItems.unshift( itemOrMenuToAdd );\n\t\t\t\t\twasAdded = true;\n\t\t\t\t}\n\t\t\t\t// Adding an item/menu at the end of a group.\n\t\t\t\telse if ( relation === 'end' ) {\n\t\t\t\t\tgroupItems.push( itemOrMenuToAdd );\n\t\t\t\t\twasAdded = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Adding an item/menu relative to an existing item/menu.\n\t\t\t\tconst relativeItemIndex = groupItems.findIndex( groupItem => {\n\t\t\t\t\treturn getIdFromGroupItem( groupItem ) === relativeId;\n\t\t\t\t} );\n\n\t\t\t\tif ( relativeItemIndex !== -1 ) {\n\t\t\t\t\tif ( relation === 'before' ) {\n\t\t\t\t\t\tgroupItems.splice( relativeItemIndex, 0, itemOrMenuToAdd );\n\t\t\t\t\t\twasAdded = true;\n\t\t\t\t\t} else if ( relation === 'after' ) {\n\t\t\t\t\t\tgroupItems.splice( relativeItemIndex + 1, 0, itemOrMenuToAdd );\n\t\t\t\t\t\twasAdded = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n\n\treturn wasAdded;\n}\n\n/**\n * Removes components from the menu bar configuration that are not available in the factory and would\n * not be instantiated. Warns about missing components if the menu bar configuration was specified by the user.\n */\nfunction purgeUnavailableComponents(\n\toriginalConfig: NormalizedMenuBarConfigObject,\n\tconfig: NormalizedMenuBarConfigObject,\n\tcomponentFactory: ComponentFactory\n) {\n\twalkConfigMenus( config.items, menuDefinition => {\n\t\tfor ( const groupDefinition of menuDefinition.groups ) {\n\t\t\tgroupDefinition.items = groupDefinition.items.filter( item => {\n\t\t\t\tconst isItemUnavailable = typeof item === 'string' && !componentFactory.has( item );\n\n\t\t\t\t// The default configuration contains all possible editor features. But integrators' editors rarely load\n\t\t\t\t// every possible feature. This is why we do not want to log warnings about unavailable items for the default config\n\t\t\t\t// because they would show up in almost every integration. If the configuration has been provided by\n\t\t\t\t// the integrator, on the other hand, then these warnings bring value.\n\t\t\t\tif ( isItemUnavailable && !config.isUsingDefaultConfig ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * There was a problem processing the configuration of the menu bar. The item with the given\n\t\t\t\t\t * name does not exist so it was omitted when rendering the menu bar.\n\t\t\t\t\t *\n\t\t\t\t\t * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed\n\t\t\t\t\t * to provide a menu bar item has not been loaded or there is a typo in the\n\t\t\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration}.\n\t\t\t\t\t *\n\t\t\t\t\t * Make sure the plugin responsible for this menu bar item is loaded and the menu bar configuration\n\t\t\t\t\t * is correct, e.g. {@link module:basic-styles/bold/boldui~BoldUI} is loaded for the `'menuBar:bold'`\n\t\t\t\t\t * menu bar item.\n\t\t\t\t\t *\n\t\t\t\t\t * @error menu-bar-item-unavailable\n\t\t\t\t\t * @param menuBarConfig The full configuration of the menu bar.\n\t\t\t\t\t * @param parentMenuConfig The config of the menu the unavailable component was defined in.\n\t\t\t\t\t * @param componentName The name of the unavailable component.\n\t\t\t\t\t */\n\t\t\t\t\tlogWarning( 'menu-bar-item-unavailable', {\n\t\t\t\t\t\tmenuBarConfig: originalConfig,\n\t\t\t\t\t\tparentMenuConfig: cloneDeep( menuDefinition ),\n\t\t\t\t\t\tcomponentName: item\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\treturn !isItemUnavailable;\n\t\t\t} );\n\t\t}\n\t} );\n}\n\n/**\n * Removes empty menus from the menu bar configuration to improve the visual UX. Such menus can occur\n * when some plugins responsible for providing menu bar items have not been loaded and some part of\n * the configuration populated menus using these components exclusively.\n */\nfunction purgeEmptyMenus(\n\toriginalConfig: NormalizedMenuBarConfigObject,\n\tconfig: NormalizedMenuBarConfigObject\n) {\n\tconst isUsingDefaultConfig = config.isUsingDefaultConfig;\n\tlet wasSubMenuPurged = false;\n\n\t// Purge top-level menus.\n\tconfig.items = config.items.filter( menuDefinition => {\n\t\tif ( !menuDefinition.groups.length ) {\n\t\t\twarnAboutEmptyMenu( originalConfig, menuDefinition, isUsingDefaultConfig );\n\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} );\n\n\t// Warn if there were no top-level menus left in the menu bar after purging.\n\tif ( !config.items.length ) {\n\t\twarnAboutEmptyMenu( originalConfig, originalConfig, isUsingDefaultConfig );\n\n\t\treturn;\n\t}\n\n\t// Purge sub-menus and groups.\n\twalkConfigMenus( config.items, menuDefinition => {\n\t\t// Get rid of empty groups.\n\t\tmenuDefinition.groups = menuDefinition.groups.filter( groupDefinition => {\n\t\t\tif ( !groupDefinition.items.length ) {\n\t\t\t\twasSubMenuPurged = true;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} );\n\n\t\t// Get rid of empty sub-menus.\n\t\tfor ( const groupDefinition of menuDefinition.groups ) {\n\t\t\tgroupDefinition.items = groupDefinition.items.filter( item => {\n\t\t\t\t// If no groups were left after removing empty ones.\n\t\t\t\tif ( isMenuDefinition( item ) && !item.groups.length ) {\n\t\t\t\t\twarnAboutEmptyMenu( originalConfig, item, isUsingDefaultConfig );\n\t\t\t\t\twasSubMenuPurged = true;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} );\n\t\t}\n\t} );\n\n\tif ( wasSubMenuPurged ) {\n\t\t// The config is walked from the root to the leaves so if anything gets removed, we need to re-run the\n\t\t// whole process because it could've affected parents.\n\t\tpurgeEmptyMenus( originalConfig, config );\n\t}\n}\n\nfunction warnAboutEmptyMenu(\n\toriginalConfig: NormalizedMenuBarConfigObject,\n\temptyMenuConfig: MenuBarMenuDefinition | NormalizedMenuBarConfigObject,\n\tisUsingDefaultConfig: boolean\n) {\n\tif ( isUsingDefaultConfig ) {\n\t\treturn;\n\t}\n\n\t/**\n\t * There was a problem processing the configuration of the menu bar. One of the menus\n\t * is empty so it was omitted when rendering the menu bar.\n\t *\n\t * This warning usually shows up when some {@link module:core/plugin~Plugin plugins} responsible for\n\t * providing menu bar items have not been loaded and the\n\t * {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar configuration} was not updated.\n\t *\n\t * Make sure all necessary editor plugins are loaded and/or update the menu bar configuration\n\t * to account for the missing menu items.\n\t *\n\t * @error menu-bar-menu-empty\n\t * @param menuBarConfig The full configuration of the menu bar.\n\t * @param emptyMenuConfig The definition of the menu that has no child items.\n\t */\n\tlogWarning( 'menu-bar-menu-empty', {\n\t\tmenuBarConfig: originalConfig,\n\t\temptyMenuConfig\n\t} );\n}\n\n/**\n * Localizes the user-config using pre-defined localized category labels.\n */\nfunction localizeMenuLabels( config: NormalizedMenuBarConfigObject, locale: Locale ) {\n\tconst t = locale.t;\n\tconst localizedCategoryLabels: Record<string, string> = {\n\t\t// Top-level categories.\n\t\t'File': t( {\n\t\t\tstring: 'File',\n\t\t\tid: 'MENU_BAR_MENU_FILE'\n\t\t} ),\n\t\t'Edit': t( {\n\t\t\tstring: 'Edit',\n\t\t\tid: 'MENU_BAR_MENU_EDIT'\n\t\t} ),\n\t\t'View': t( {\n\t\t\tstring: 'View',\n\t\t\tid: 'MENU_BAR_MENU_VIEW'\n\t\t} ),\n\t\t'Insert': t( {\n\t\t\tstring: 'Insert',\n\t\t\tid: 'MENU_BAR_MENU_INSERT'\n\t\t} ),\n\t\t'Format': t( {\n\t\t\tstring: 'Format',\n\t\t\tid: 'MENU_BAR_MENU_FORMAT'\n\t\t} ),\n\t\t'Tools': t( {\n\t\t\tstring: 'Tools',\n\t\t\tid: 'MENU_BAR_MENU_TOOLS'\n\t\t} ),\n\t\t'Help': t( {\n\t\t\tstring: 'Help',\n\t\t\tid: 'MENU_BAR_MENU_HELP'\n\t\t} ),\n\n\t\t// Sub-menus.\n\t\t'Text': t( {\n\t\t\tstring: 'Text',\n\t\t\tid: 'MENU_BAR_MENU_TEXT'\n\t\t} ),\n\t\t'Font': t( {\n\t\t\tstring: 'Font',\n\t\t\tid: 'MENU_BAR_MENU_FONT'\n\t\t} )\n\t};\n\n\twalkConfigMenus( config.items, definition => {\n\t\tif ( definition.label in localizedCategoryLabels ) {\n\t\t\tdefinition.label = localizedCategoryLabels[ definition.label ];\n\t\t}\n\t} );\n}\n\n/**\n * Recursively visits all menu definitions in the config and calls the callback for each of them.\n */\nfunction walkConfigMenus(\n\tdefinition: NormalizedMenuBarConfigObject[ 'items' ] | MenuBarMenuDefinition,\n\tcallback: ( definition: MenuBarMenuDefinition ) => void\n) {\n\tif ( Array.isArray( definition ) ) {\n\t\tfor ( const topLevelMenuDefinition of definition ) {\n\t\t\twalk( topLevelMenuDefinition );\n\t\t}\n\t}\n\n\tfunction walk( menuDefinition: MenuBarMenuDefinition ) {\n\t\tcallback( menuDefinition );\n\n\t\tfor ( const groupDefinition of menuDefinition.groups ) {\n\t\t\tfor ( const groupItem of groupDefinition.items ) {\n\t\t\t\tif ( isMenuDefinition( groupItem ) ) {\n\t\t\t\t\twalk( groupItem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction isMenuBarMenuAddition( definition: any ): definition is MenuBarConfigAddedMenu {\n\treturn typeof definition === 'object' && 'menu' in definition;\n}\n\nfunction isMenuBarMenuGroupAddition( definition: any ): definition is MenuBarConfigAddedGroup {\n\treturn typeof definition === 'object' && 'group' in definition;\n}\n\nfunction getRelationFromPosition( position: MenuBarConfigAddedPosition ): 'start' | 'end' | 'before' | 'after' {\n\tif ( position.startsWith( 'start' ) ) {\n\t\treturn 'start';\n\t} else if ( position.startsWith( 'end' ) ) {\n\t\treturn 'end';\n\t} else if ( position.startsWith( 'after' ) ) {\n\t\treturn 'after';\n\t} else {\n\t\treturn 'before';\n\t}\n}\n\nfunction getRelativeIdFromPosition( position: MenuBarConfigAddedPosition ): string | null {\n\tconst match = position.match( /^[^:]+:(.+)/ );\n\n\tif ( match ) {\n\t\treturn match[ 1 ];\n\t}\n\n\treturn null;\n}\n\nfunction getIdFromGroupItem( item: string | MenuBarMenuDefinition ): string {\n\treturn typeof item === 'string' ? item : item.menuId;\n}\n\nfunction isMenuDefinition( definition: any ): definition is MenuBarMenuDefinition {\n\treturn typeof definition === 'object' && 'menuId' in definition;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editorui/editorui\n */\n\n/* globals console */\n\nimport ComponentFactory from '../componentfactory.js';\nimport TooltipManager from '../tooltipmanager.js';\nimport PoweredBy from './poweredby.js';\nimport AriaLiveAnnouncer from '../arialiveannouncer.js';\n\nimport type EditorUIView from './editoruiview.js';\nimport type ToolbarView from '../toolbar/toolbarview.js';\nimport type { default as View, UIViewRenderEvent } from '../view.js';\n\nimport {\n\tObservableMixin,\n\tisVisible,\n\tFocusTracker,\n\ttype EventInfo, type CollectionAddEvent, type CollectionRemoveEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport type { Editor } from '@ckeditor/ckeditor5-core';\nimport type { ViewDocumentLayoutChangedEvent, ViewScrollToTheSelectionEvent } from '@ckeditor/ckeditor5-engine';\nimport type {\n\tdefault as MenuBarView,\n\tMenuBarConfigAddedGroup,\n\tMenuBarConfigAddedItem,\n\tMenuBarConfigAddedMenu\n} from '../menubar/menubarview.js';\nimport { normalizeMenuBarConfig } from '../menubar/utils.js';\n\n/**\n * A class providing the minimal interface that is required to successfully bootstrap any editor UI.\n */\nexport default abstract class EditorUI extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * The editor that the UI belongs to.\n\t */\n\tpublic readonly editor: Editor;\n\n\t/**\n\t * An instance of the {@link module:ui/componentfactory~ComponentFactory}, a registry used by plugins\n\t * to register factories of specific UI components.\n\t */\n\tpublic readonly componentFactory: ComponentFactory;\n\n\t/**\n\t * Stores the information about the editor UI focus and propagates it so various plugins and components\n\t * are unified as a focus group.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Manages the tooltips displayed on mouseover and focus across the UI.\n\t */\n\tpublic readonly tooltipManager: TooltipManager;\n\n\t/**\n\t * A helper that enables the \"powered by\" feature in the editor and renders a link to the project's webpage.\n\t */\n\tpublic readonly poweredBy: PoweredBy;\n\n\t/**\n\t * A helper that manages the content of an `aria-live` regions used by editor features to announce status changes\n\t * to screen readers.\n\t */\n\tpublic readonly ariaLiveAnnouncer: AriaLiveAnnouncer;\n\n\t/**\n\t * Indicates the UI is ready. Set `true` after {@link #event:ready} event is fired.\n\t *\n\t * @readonly\n\t * @default false\n\t */\n\tpublic isReady: boolean = false;\n\n\tpublic abstract get view(): EditorUIView;\n\n\t/**\n\t * Stores viewport offsets from every direction.\n\t *\n\t * Viewport offset can be used to constrain balloons or other UI elements into an element smaller than the viewport.\n\t * This can be useful if there are any other absolutely positioned elements that may interfere with editor UI.\n\t *\n\t * Example `editor.ui.viewportOffset` returns:\n\t *\n\t * ```js\n\t * {\n\t * \ttop: 50,\n\t * \tright: 50,\n\t * \tbottom: 50,\n\t * \tleft: 50\n\t * }\n\t * ```\n\t *\n\t * This property can be overriden after editor already being initialized:\n\t *\n\t * ```js\n\t * editor.ui.viewportOffset = {\n\t * \ttop: 100,\n\t * \tright: 0,\n\t * \tbottom: 0,\n\t * \tleft: 0\n\t * };\n\t * ```\n\t *\n\t * @observable\n\t */\n\tpublic declare viewportOffset: {\n\t\tleft?: number;\n\t\tright?: number;\n\t\ttop?: number;\n\t\tbottom?: number;\n\t};\n\n\t/**\n\t * Stores all editable elements used by the editor instance.\n\t */\n\tprivate _editableElementsMap = new Map<string, HTMLElement>();\n\n\t/**\n\t * All available & focusable toolbars.\n\t */\n\tprivate _focusableToolbarDefinitions: Array<FocusableToolbarDefinition> = [];\n\n\t/**\n\t * All additional menu bar items, groups or menus that have their default location defined.\n\t */\n\tprivate _extraMenuBarElements: Array<MenuBarConfigAddedItem | MenuBarConfigAddedGroup | MenuBarConfigAddedMenu> = [];\n\n\t/**\n\t * The last focused element to which focus should return on `Esc` press.\n\t */\n\tprivate _lastFocusedForeignElement: HTMLElement | null = null;\n\n\t/**\n\t * Creates an instance of the editor UI class.\n\t *\n\t * @param editor The editor instance.\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper();\n\n\t\tconst editingView = editor.editing.view;\n\n\t\tthis.editor = editor;\n\t\tthis.componentFactory = new ComponentFactory( editor );\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.tooltipManager = new TooltipManager( editor );\n\t\tthis.poweredBy = new PoweredBy( editor );\n\t\tthis.ariaLiveAnnouncer = new AriaLiveAnnouncer( editor );\n\n\t\tthis.set( 'viewportOffset', this._readViewportOffsetFromConfig() );\n\n\t\tthis.once<EditorUIReadyEvent>( 'ready', () => {\n\t\t\tthis._bindBodyCollectionWithFocusTracker();\n\n\t\t\tthis.isReady = true;\n\t\t} );\n\n\t\t// Informs UI components that should be refreshed after layout change.\n\t\tthis.listenTo<ViewDocumentLayoutChangedEvent>( editingView.document, 'layoutChanged', this.update.bind( this ) );\n\t\tthis.listenTo<ViewScrollToTheSelectionEvent>( editingView, 'scrollToTheSelection', this._handleScrollToTheSelection.bind( this ) );\n\n\t\tthis._initFocusTracking();\n\t}\n\n\t/**\n\t * The main (outermost) DOM element of the editor UI.\n\t *\n\t * For example, in {@link module:editor-classic/classiceditor~ClassicEditor} it is a `<div>` which\n\t * wraps the editable element and the toolbar. In {@link module:editor-inline/inlineeditor~InlineEditor}\n\t * it is the editable element itself (as there is no other wrapper). However, in\n\t * {@link module:editor-decoupled/decouplededitor~DecoupledEditor} it is set to `null` because this editor does not\n\t * come with a single \"main\" HTML element (its editable element and toolbar are separate).\n\t *\n\t * This property can be understood as a shorthand for retrieving the element that a specific editor integration\n\t * considers to be its main DOM element.\n\t */\n\tpublic get element(): HTMLElement | null {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Fires the {@link module:ui/editorui/editorui~EditorUI#event:update `update`} event.\n\t *\n\t * This method should be called when the editor UI (e.g. positions of its balloons) needs to be updated due to\n\t * some environmental change which CKEditor 5 is not aware of (e.g. resize of a container in which it is used).\n\t */\n\tpublic update(): void {\n\t\tthis.fire<EditorUIUpdateEvent>( 'update' );\n\t}\n\n\t/**\n\t * Destroys the UI.\n\t */\n\tpublic destroy(): void {\n\t\tthis.stopListening();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.tooltipManager.destroy( this.editor );\n\t\tthis.poweredBy.destroy();\n\n\t\t// Clean–up the references to the CKEditor instance stored in the native editable DOM elements.\n\t\tfor ( const domElement of this._editableElementsMap.values() ) {\n\t\t\t( domElement as any ).ckeditorInstance = null;\n\t\t\tthis.editor.keystrokes.stopListening( domElement );\n\t\t}\n\n\t\tthis._editableElementsMap = new Map();\n\t\tthis._focusableToolbarDefinitions = [];\n\t}\n\n\t/**\n\t * Stores the native DOM editable element used by the editor under a unique name.\n\t *\n\t * Also, registers the element in the editor to maintain the accessibility of the UI. When the user is editing text in a focusable\n\t * editable area, they can use the <kbd>Alt</kbd> + <kbd>F10</kbd> keystroke to navigate over editor toolbars. See {@link #addToolbar}.\n\t *\n\t * @param rootName The unique name of the editable element.\n\t * @param domElement The native DOM editable element.\n\t */\n\tpublic setEditableElement( rootName: string, domElement: HTMLElement ): void {\n\t\tthis._editableElementsMap.set( rootName, domElement );\n\n\t\t// Put a reference to the CKEditor instance in the editable native DOM element.\n\t\t// It helps 3rd–party software (browser extensions, other libraries) access and recognize\n\t\t// CKEditor 5 instances (editing roots) and use their API (there is no global editor\n\t\t// instance registry).\n\t\tif ( !( domElement as any ).ckeditorInstance ) {\n\t\t\t( domElement as any ).ckeditorInstance = this.editor;\n\t\t}\n\n\t\t// Register the element, so it becomes available for Alt+F10 and Esc navigation.\n\t\tthis.focusTracker.add( domElement );\n\n\t\tconst setUpKeystrokeHandler = () => {\n\t\t\t// The editing view of the editor is already listening to keystrokes from DOM roots (see: KeyObserver).\n\t\t\t// Do not duplicate listeners.\n\t\t\tif ( this.editor.editing.view.getDomRoot( rootName ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.keystrokes.listenTo( domElement );\n\t\t};\n\n\t\t// For editable elements set by features after EditorUI is ready (e.g. source editing).\n\t\tif ( this.isReady ) {\n\t\t\tsetUpKeystrokeHandler();\n\t\t}\n\t\t// For editable elements set while the editor is being created (e.g. DOM roots).\n\t\telse {\n\t\t\tthis.once<EditorUIReadyEvent>( 'ready', setUpKeystrokeHandler );\n\t\t}\n\t}\n\n\t/**\n\t * Removes the editable from the editor UI. Removes all handlers added by {@link #setEditableElement}.\n\t *\n\t * @param rootName The name of the editable element to remove.\n\t */\n\tpublic removeEditableElement( rootName: string ): void {\n\t\tconst domElement = this._editableElementsMap.get( rootName );\n\n\t\tif ( !domElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._editableElementsMap.delete( rootName );\n\n\t\tthis.editor.keystrokes.stopListening( domElement );\n\t\tthis.focusTracker.remove( domElement );\n\n\t\t( domElement as any ).ckeditorInstance = null;\n\t}\n\n\t/**\n\t * Returns the editable editor element with the given name or null if editable does not exist.\n\t *\n\t * @param rootName The editable name.\n\t */\n\tpublic getEditableElement( rootName: string = 'main' ): HTMLElement | undefined {\n\t\treturn this._editableElementsMap.get( rootName );\n\t}\n\n\t/**\n\t * Returns array of names of all editor editable elements.\n\t */\n\tpublic getEditableElementsNames(): IterableIterator<string> {\n\t\treturn this._editableElementsMap.keys();\n\t}\n\n\t/**\n\t * Adds a toolbar to the editor UI. Used primarily to maintain the accessibility of the UI.\n\t *\n\t * Focusable toolbars can be accessed (focused) by users by pressing the <kbd>Alt</kbd> + <kbd>F10</kbd> keystroke.\n\t * Successive keystroke presses navigate over available toolbars.\n\t *\n\t * @param toolbarView A instance of the toolbar to be registered.\n\t */\n\tpublic addToolbar( toolbarView: ToolbarView, options: FocusableToolbarOptions = {} ): void {\n\t\tif ( toolbarView.isRendered ) {\n\t\t\tthis.focusTracker.add( toolbarView );\n\t\t\tthis.editor.keystrokes.listenTo( toolbarView.element! );\n\t\t} else {\n\t\t\ttoolbarView.once<UIViewRenderEvent>( 'render', () => {\n\t\t\t\tthis.focusTracker.add( toolbarView );\n\t\t\t\tthis.editor.keystrokes.listenTo( toolbarView.element! );\n\t\t\t} );\n\t\t}\n\n\t\tthis._focusableToolbarDefinitions.push( { toolbarView, options } );\n\t}\n\n\t/**\n\t * Registers an extra menu bar element, which could be a single item, a group of items, or a menu containing groups.\n\t *\n\t * ```ts\n\t * // Register a new menu bar item.\n\t * editor.ui.extendMenuBar( {\n\t *   item: 'menuBar:customFunctionButton',\n\t *   position: 'after:menuBar:bold'\n\t * } );\n\t *\n\t * // Register a new menu bar group.\n\t * editor.ui.extendMenuBar( {\n\t *   group: {\n\t *     groupId: 'customGroup',\n\t *     items: [\n\t *       'menuBar:customFunctionButton'\n\t *     ]\n\t *   },\n\t *   position: 'start:help'\n\t * } );\n\t *\n\t * // Register a new menu bar menu.\n\t * editor.ui.extendMenuBar( {\n\t *   menu: {\n\t *     menuId: 'customMenu',\n\t *     label: 'customMenu',\n\t *     groups: [\n\t *       {\n\t *         groupId: 'customGroup',\n\t *         items: [\n\t *           'menuBar:customFunctionButton'\n\t *         ]\n\t *       }\n\t *     ]\n\t *   },\n\t *   position: 'after:help'\n\t * } );\n\t * ```\n\t */\n\tpublic extendMenuBar(\n\t\tconfig: MenuBarConfigAddedItem | MenuBarConfigAddedGroup | MenuBarConfigAddedMenu\n\t): void {\n\t\tthis._extraMenuBarElements.push( config );\n\t}\n\n\t/**\n\t * Stores all editable elements used by the editor instance.\n\t *\n\t * @deprecated\n\t */\n\tprotected get _editableElements(): unknown {\n\t\t/**\n\t\t * The {@link module:ui/editorui/editorui~EditorUI#_editableElements `EditorUI#_editableElements`} property has been\n\t\t * deprecated and will be removed in the near future. Please use\n\t\t * {@link module:ui/editorui/editorui~EditorUI#setEditableElement `setEditableElement()`} and\n\t\t * {@link module:ui/editorui/editorui~EditorUI#getEditableElement `getEditableElement()`} methods instead.\n\t\t *\n\t\t * @error editor-ui-deprecated-editable-elements\n\t\t * @param editorUI Editor UI instance the deprecated property belongs to.\n\t\t */\n\t\tconsole.warn(\n\t\t\t'editor-ui-deprecated-editable-elements: ' +\n\t\t\t'The EditorUI#_editableElements property has been deprecated and will be removed in the near future.',\n\t\t\t{ editorUI: this } );\n\n\t\treturn this._editableElementsMap;\n\t}\n\n\t/**\n\t * Initializes menu bar.\n\t */\n\tprotected _initMenuBar( menuBarView: MenuBarView ): void {\n\t\tconst menuBarViewElement = menuBarView.element!;\n\n\t\tthis.focusTracker.add( menuBarViewElement );\n\t\tthis.editor.keystrokes.listenTo( menuBarViewElement );\n\n\t\tconst normalizedMenuBarConfig = normalizeMenuBarConfig( this.editor.config.get( 'menuBar' ) || {} );\n\n\t\tmenuBarView.fillFromConfig( normalizedMenuBarConfig, this.componentFactory, this._extraMenuBarElements );\n\n\t\tthis.editor.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tif ( !menuBarViewElement.contains( this.editor.ui.focusTracker.focusedElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Bring focus back to where it came from before focusing the toolbar:\n\t\t\t// If it came from outside the engine view (e.g. source editing), move it there.\n\t\t\tif ( this._lastFocusedForeignElement ) {\n\t\t\t\tthis._lastFocusedForeignElement.focus();\n\t\t\t\tthis._lastFocusedForeignElement = null;\n\t\t\t}\n\t\t\t// Else just focus the view editing.\n\t\t\telse {\n\t\t\t\tthis.editor.editing.view.focus();\n\t\t\t}\n\n\t\t\tcancel();\n\t\t} );\n\n\t\tthis.editor.keystrokes.set( 'Alt+F9', ( data, cancel ) => {\n\t\t\t// If menu bar is already focused do nothing.\n\t\t\tif ( menuBarViewElement.contains( this.editor.ui.focusTracker.focusedElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._saveLastFocusedForeignElement();\n\n\t\t\tmenuBarView.isFocusBorderEnabled = true;\n\t\t\tmenuBarView.focus();\n\t\t\tcancel();\n\t\t} );\n\t}\n\n\t/**\n\t * Returns viewport offsets object:\n\t *\n\t * ```js\n\t * {\n\t * \ttop: Number,\n\t * \tright: Number,\n\t * \tbottom: Number,\n\t * \tleft: Number\n\t * }\n\t * ```\n\t *\n\t * Only top property is currently supported.\n\t */\n\tprivate _readViewportOffsetFromConfig() {\n\t\tconst editor = this.editor;\n\t\tconst viewportOffsetConfig = editor.config.get( 'ui.viewportOffset' );\n\n\t\tif ( viewportOffsetConfig ) {\n\t\t\treturn viewportOffsetConfig;\n\t\t}\n\n\t\t// Not present in EditorConfig type, because it's legacy. Hence the `as` expression.\n\t\tconst legacyOffsetConfig = editor.config.get( 'toolbar.viewportTopOffset' ) as number | undefined;\n\n\t\t// Fall back to deprecated toolbar config.\n\t\tif ( legacyOffsetConfig ) {\n\t\t\t/**\n\t\t\t * The {@link module:core/editor/editorconfig~EditorConfig#toolbar `EditorConfig#toolbar.viewportTopOffset`}\n\t\t\t * property has been deprecated and will be removed in the near future. Please use\n\t\t\t * {@link module:core/editor/editorconfig~EditorConfig#ui `EditorConfig#ui.viewportOffset`} instead.\n\t\t\t *\n\t\t\t * @error editor-ui-deprecated-viewport-offset-config\n\t\t\t */\n\t\t\tconsole.warn(\n\t\t\t\t'editor-ui-deprecated-viewport-offset-config: ' +\n\t\t\t\t'The `toolbar.vieportTopOffset` configuration option is deprecated. ' +\n\t\t\t\t'It will be removed from future CKEditor versions. Use `ui.viewportOffset.top` instead.'\n\t\t\t);\n\n\t\t\treturn { top: legacyOffsetConfig };\n\t\t}\n\n\t\t// More keys to come in the future.\n\t\treturn { top: 0 };\n\t}\n\n\t/**\n\t * Starts listening for <kbd>Alt</kbd> + <kbd>F10</kbd> and <kbd>Esc</kbd> keystrokes in the context of focusable\n\t * {@link #setEditableElement editable elements} and {@link #addToolbar toolbars}\n\t * to allow users navigate across the UI.\n\t */\n\tprivate _initFocusTracking(): void {\n\t\tconst editor = this.editor;\n\n\t\tlet candidateDefinitions: Array<FocusableToolbarDefinition>;\n\n\t\t// Focus the next focusable toolbar on <kbd>Alt</kbd> + <kbd>F10</kbd>.\n\t\teditor.keystrokes.set( 'Alt+F10', ( data, cancel ) => {\n\t\t\tthis._saveLastFocusedForeignElement();\n\n\t\t\tconst currentFocusedToolbarDefinition = this._getCurrentFocusedToolbarDefinition();\n\n\t\t\t// * When focusing a toolbar for the first time, set the array of definitions for successive presses of Alt+F10.\n\t\t\t// This ensures, the navigation works always the same and no pair of toolbars takes over\n\t\t\t// (e.g. image and table toolbars when a selected image is inside a cell).\n\t\t\t// * It could be that the focus went to the toolbar by clicking a toolbar item (e.g. a dropdown). In this case,\n\t\t\t// there were no candidates so they must be obtained (#12339).\n\t\t\tif ( !currentFocusedToolbarDefinition || !candidateDefinitions ) {\n\t\t\t\tcandidateDefinitions = this._getFocusableCandidateToolbarDefinitions();\n\t\t\t}\n\n\t\t\t// In a single Alt+F10 press, check all candidates but if none were focused, don't go any further.\n\t\t\t// This prevents an infinite loop.\n\t\t\tfor ( let i = 0; i < candidateDefinitions.length; i++ ) {\n\t\t\t\tconst candidateDefinition = candidateDefinitions.shift()!;\n\n\t\t\t\t// Put the first definition to the back of the array. This allows circular navigation over all toolbars\n\t\t\t\t// on successive presses of Alt+F10.\n\t\t\t\tcandidateDefinitions.push( candidateDefinition );\n\n\t\t\t\t// Don't focus the same toolbar again. If you did, this would move focus from the nth focused toolbar item back to the\n\t\t\t\t// first item as per ToolbarView#focus() if the user navigated inside the toolbar.\n\t\t\t\tif (\n\t\t\t\t\tcandidateDefinition !== currentFocusedToolbarDefinition &&\n\t\t\t\t\tthis._focusFocusableCandidateToolbar( candidateDefinition )\n\t\t\t\t) {\n\t\t\t\t\t// Clean up after a current visible toolbar when switching to the next one.\n\t\t\t\t\tif ( currentFocusedToolbarDefinition && currentFocusedToolbarDefinition.options.afterBlur ) {\n\t\t\t\t\t\tcurrentFocusedToolbarDefinition.options.afterBlur();\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Blur the focused toolbar on <kbd>Esc</kbd> and bring the focus back to its origin.\n\t\teditor.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tconst focusedToolbarDef = this._getCurrentFocusedToolbarDefinition();\n\n\t\t\tif ( !focusedToolbarDef ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Bring focus back to where it came from before focusing the toolbar:\n\t\t\t// 1. If it came from outside the engine view (e.g. source editing), move it there.\n\t\t\tif ( this._lastFocusedForeignElement ) {\n\t\t\t\tthis._lastFocusedForeignElement.focus();\n\t\t\t\tthis._lastFocusedForeignElement = null;\n\t\t\t}\n\t\t\t// 2. There are two possibilities left:\n\t\t\t//   2.1. It could be that the focus went from an editable element in the view (root or nested).\n\t\t\t//   2.2. It could be the focus went straight to the toolbar before even focusing the editing area.\n\t\t\t// In either case, just focus the view editing. The focus will land where it belongs.\n\t\t\telse {\n\t\t\t\teditor.editing.view.focus();\n\t\t\t}\n\n\t\t\t// Clean up after the toolbar if there is anything to do there.\n\t\t\tif ( focusedToolbarDef.options.afterBlur ) {\n\t\t\t\tfocusedToolbarDef.options.afterBlur();\n\t\t\t}\n\n\t\t\tcancel();\n\t\t} );\n\t}\n\n\t/**\n\t * Saves last focused element that doen not belong to editing view to restore focus on `Esc`.\n\t */\n\tprivate _saveLastFocusedForeignElement() {\n\t\tconst focusedElement = this.focusTracker.focusedElement as HTMLElement;\n\n\t\t// Focus moved out of a DOM element that\n\t\t// * is not a toolbar,\n\t\t// * does not belong to the editing view (e.g. source editing).\n\t\tif (\n\t\t\tArray.from( this._editableElementsMap.values() ).includes( focusedElement ) &&\n\t\t\t!Array.from( this.editor.editing.view.domRoots.values() ).includes( focusedElement )\n\t\t) {\n\t\t\tthis._lastFocusedForeignElement = focusedElement;\n\t\t}\n\t}\n\n\t/**\n\t * Returns definitions of toolbars that could potentially be focused, sorted by their importance for the user.\n\t *\n\t * Focusable toolbars candidates are either:\n\t * * already visible,\n\t * * have `beforeFocus()` set in their {@link module:ui/editorui/editorui~FocusableToolbarDefinition definition} that suggests that\n\t * they might show up when called. Keep in mind that determining whether a toolbar will show up (and become focusable) is impossible\n\t * at this stage because it depends on its implementation, that in turn depends on the editing context (selection).\n\t *\n\t * **Note**: Contextual toolbars take precedence over regular toolbars.\n\t */\n\tprivate _getFocusableCandidateToolbarDefinitions(): Array<FocusableToolbarDefinition> {\n\t\tconst definitions: Array<FocusableToolbarDefinition> = [];\n\n\t\tfor ( const toolbarDef of this._focusableToolbarDefinitions ) {\n\t\t\tconst { toolbarView, options } = toolbarDef;\n\n\t\t\tif ( isVisible( toolbarView.element ) || options.beforeFocus ) {\n\t\t\t\tdefinitions.push( toolbarDef );\n\t\t\t}\n\t\t}\n\n\t\t// Contextual and already visible toolbars have higher priority. If both are true, the toolbar will always focus first.\n\t\t// For instance, a selected widget toolbar vs inline editor toolbar: both are visible but the widget toolbar is contextual.\n\t\tdefinitions.sort( ( defA, defB ) => getToolbarDefinitionWeight( defA ) - getToolbarDefinitionWeight( defB ) );\n\n\t\treturn definitions;\n\t}\n\n\t/**\n\t * Returns a definition of the toolbar that is currently visible and focused (one of its children has focus).\n\t *\n\t * `null` is returned when no toolbar is currently focused.\n\t */\n\tprivate _getCurrentFocusedToolbarDefinition(): FocusableToolbarDefinition | null {\n\t\tfor ( const definition of this._focusableToolbarDefinitions ) {\n\t\t\tif ( definition.toolbarView.element && definition.toolbarView.element.contains( this.focusTracker.focusedElement ) ) {\n\t\t\t\treturn definition;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Focuses a focusable toolbar candidate using its definition.\n\t *\n\t * @param candidateToolbarDefinition A definition of the toolbar to focus.\n\t * @returns `true` when the toolbar candidate was focused. `false` otherwise.\n\t */\n\tprivate _focusFocusableCandidateToolbar( candidateToolbarDefinition: FocusableToolbarDefinition ): boolean {\n\t\tconst { toolbarView, options: { beforeFocus } } = candidateToolbarDefinition;\n\n\t\tif ( beforeFocus ) {\n\t\t\tbeforeFocus();\n\t\t}\n\n\t\t// If it didn't show up after beforeFocus(), it's not focusable at all.\n\t\tif ( !isVisible( toolbarView.element ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttoolbarView.focus();\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Provides an integration between {@link #viewportOffset} and {@link module:utils/dom/scroll~scrollViewportToShowTarget}.\n\t * It allows the UI-agnostic engine method to consider user-configured viewport offsets specific for the integration.\n\t *\n\t * @param evt The `scrollToTheSelection` event info.\n\t * @param data The payload carried by the `scrollToTheSelection` event.\n\t */\n\tprivate _handleScrollToTheSelection(\n\t\tevt: EventInfo<'scrollToTheSelection'>,\n\t\tdata: ViewScrollToTheSelectionEvent[ 'args' ][ 0 ]\n\t): void {\n\t\tconst configuredViewportOffset = {\n\t\t\ttop: 0,\n\t\t\tbottom: 0,\n\t\t\tleft: 0,\n\t\t\tright: 0,\n\t\t\t...this.viewportOffset\n\t\t};\n\n\t\tdata.viewportOffset.top += configuredViewportOffset.top;\n\t\tdata.viewportOffset.bottom += configuredViewportOffset.bottom;\n\t\tdata.viewportOffset.left += configuredViewportOffset.left;\n\t\tdata.viewportOffset.right += configuredViewportOffset.right;\n\t}\n\n\t/**\n\t * Ensures that the focus tracker is aware of all views' DOM elements in the body collection.\n\t */\n\tprivate _bindBodyCollectionWithFocusTracker() {\n\t\tconst body = this.view.body;\n\n\t\tfor ( const view of body ) {\n\t\t\tthis.focusTracker.add( view.element! );\n\t\t}\n\n\t\tbody.on<CollectionAddEvent<View>>( 'add', ( evt, view ) => {\n\t\t\tthis.focusTracker.add( view.element! );\n\t\t} );\n\n\t\tbody.on<CollectionRemoveEvent<View>>( 'remove', ( evt, view ) => {\n\t\t\tthis.focusTracker.remove( view.element! );\n\t\t} );\n\t}\n}\n\n/**\n * Fired when the editor UI is ready.\n *\n * Fired before {@link module:engine/controller/datacontroller~DataController#event:ready}.\n *\n * @eventName ~EditorUI#ready\n */\nexport type EditorUIReadyEvent = {\n\tname: 'ready';\n\targs: [];\n};\n\n/**\n * Fired whenever the UI (all related components) should be refreshed.\n *\n * **Note:**: The event is fired after each {@link module:engine/view/document~Document#event:layoutChanged}.\n * It can also be fired manually via the {@link module:ui/editorui/editorui~EditorUI#update} method.\n *\n * @eventName ~EditorUI#update\n */\nexport type EditorUIUpdateEvent = {\n\tname: 'update';\n\targs: [];\n};\n\n/**\n * A definition of a focusable toolbar. Used by {@link module:ui/editorui/editorui~EditorUI#addToolbar}.\n */\nexport interface FocusableToolbarDefinition {\n\n\t/**\n\t * An instance of a focusable toolbar view.\n\t */\n\ttoolbarView: ToolbarView;\n\n\t/**\n\t * Options of a focusable toolbar view:\n\t *\n\t * * `isContextual`: Marks the higher priority toolbar. For example when there are 2 visible toolbars,\n\t * it allows to distinguish which toolbar should be focused first after the `alt+f10` keystroke\n\t * * `beforeFocus`: A callback executed before the `ToolbarView` gains focus upon the `Alt+F10` keystroke.\n\t * * `afterBlur`: A callback executed after `ToolbarView` loses focus upon `Esc` keystroke but before\n\t * the focus goes back to the `origin`.\n\t */\n\toptions: FocusableToolbarOptions;\n}\n\nexport interface FocusableToolbarOptions {\n\n\t/**\n\t * Set `true` if the toolbar is attached to the content of the editor. Such toolbar takes\n\t * a precedence over other toolbars when a user pressed <kbd>Alt</kbd> + <kbd>F10</kbd>.\n\t */\n\tisContextual?: boolean;\n\n\t/**\n\t * Specify a callback executed before the toolbar instance DOM element gains focus\n\t * upon the <kbd>Alt</kbd> + <kbd>F10</kbd> keystroke.\n\t */\n\tbeforeFocus?: () => void;\n\n\t/**\n\t * Specify a callback executed after the toolbar instance DOM element loses focus upon\n\t * <kbd>Esc</kbd> keystroke but before the focus goes back to the {@link ~EditorUI#setEditableElement editable element}.\n\t */\n\tafterBlur?: () => void;\n}\n\n/**\n * Returns a number (weight) for a toolbar definition. Visible toolbars have a higher priority and so do\n * contextual toolbars (displayed in the context of a content, for instance, an image toolbar).\n *\n * A standard invisible toolbar is the heaviest. A visible contextual toolbar is the lightest.\n *\n * @param toolbarDef A toolbar definition to be weighted.\n */\nfunction getToolbarDefinitionWeight( toolbarDef: FocusableToolbarDefinition ): number {\n\tconst { toolbarView, options } = toolbarDef;\n\tlet weight = 10;\n\n\t// Prioritize already visible toolbars. They should get focused first.\n\tif ( isVisible( toolbarView.element ) ) {\n\t\tweight--;\n\t}\n\n\t// Prioritize contextual toolbars. They are displayed at the selection.\n\tif ( options.isContextual ) {\n\t\tweight--;\n\t}\n\n\treturn weight;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editorui/editoruiview\n */\n\nimport View from '../view.js';\nimport BodyCollection from './bodycollection.js';\nimport type EditableUIView from '../editableui/editableuiview.js';\n\nimport type { Locale, LocaleTranslate } from '@ckeditor/ckeditor5-utils';\n\nimport '../../theme/components/editorui/editorui.css';\nimport type MenuBarView from '../menubar/menubarview.js';\n\n/**\n * The editor UI view class. Base class for the editor main views.\n */\nexport default abstract class EditorUIView extends View {\n\t/**\n\t * Collection of the child views, detached from the DOM\n\t * structure of the editor, like panels, icons etc.\n\t */\n\tpublic readonly body: BodyCollection;\n\n\tdeclare public locale: Locale;\n\tdeclare public t: LocaleTranslate;\n\n\tpublic abstract get editable(): EditableUIView;\n\n\t/**\n\t * Menu bar view instance. May not be initialized in some editor types.\n\t */\n\tpublic menuBarView?: MenuBarView;\n\n\t/**\n\t * Creates an instance of the editor UI view class.\n\t *\n\t * @param locale The locale instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.body = new BodyCollection( locale );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.body.attachToDom();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis.body.detachFromDom();\n\n\t\treturn super.destroy();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editorui/boxed/boxededitoruiview\n */\n\nimport EditorUIView from '../editoruiview.js';\nimport LabelView from '../../label/labelview.js';\nimport type ViewCollection from '../../viewcollection.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The boxed editor UI view class. This class represents an editor interface\n * consisting of a toolbar and an editable area, enclosed within a box.\n */\nexport default abstract class BoxedEditorUIView extends EditorUIView {\n\t/**\n\t * Collection of the child views located in the top (`.ck-editor__top`)\n\t * area of the UI.\n\t */\n\tpublic readonly top: ViewCollection;\n\n\t/**\n\t * Collection of the child views located in the main (`.ck-editor__main`)\n\t * area of the UI.\n\t */\n\tpublic readonly main: ViewCollection;\n\n\t/**\n\t * Voice label of the UI.\n\t */\n\tprivate readonly _voiceLabelView: LabelView;\n\n\t/**\n\t * Creates an instance of the boxed editor UI view class.\n\t *\n\t * @param locale The locale instance..\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.top = this.createCollection();\n\t\tthis.main = this.createCollection();\n\t\tthis._voiceLabelView = this._createVoiceLabel();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-editor',\n\t\t\t\t\t'ck-rounded-corners'\n\t\t\t\t],\n\t\t\t\trole: 'application',\n\t\t\t\tdir: locale.uiLanguageDirection,\n\t\t\t\tlang: locale.uiLanguage,\n\t\t\t\t'aria-labelledby': this._voiceLabelView.id\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis._voiceLabelView,\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-editor__top',\n\t\t\t\t\t\t\t'ck-reset_all'\n\t\t\t\t\t\t],\n\t\t\t\t\t\trole: 'presentation'\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.top\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-editor__main'\n\t\t\t\t\t\t],\n\t\t\t\t\t\trole: 'presentation'\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.main\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a voice label view instance.\n\t */\n\tprivate _createVoiceLabel() {\n\t\tconst t = this.t;\n\t\tconst voiceLabel = new LabelView();\n\n\t\tvoiceLabel.text = t( 'Rich Text Editor' );\n\n\t\tvoiceLabel.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-voice-label'\n\t\t\t}\n\t\t} );\n\n\t\treturn voiceLabel;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editableui/editableuiview\n */\n\nimport View from '../view.js';\n\nimport type { EditingView } from '@ckeditor/ckeditor5-engine';\nimport type { Locale, ObservableChangeEvent } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The editable UI view class.\n */\nexport default class EditableUIView extends View {\n\t/**\n\t * The name of the editable UI view.\n\t */\n\tpublic name: string | null = null;\n\n\t/**\n\t * Controls whether the editable is focused, i.e. the user is typing in it.\n\t *\n\t * @observable\n\t */\n\tdeclare public isFocused: boolean;\n\n\t/**\n\t * The editing view instance the editable is related to. Editable uses the editing\n\t * view to dynamically modify its certain DOM attributes after {@link #render rendering}.\n\t *\n\t * **Note**: The DOM attributes are performed by the editing view and not UI\n\t * {@link module:ui/view~View#bindTemplate template bindings} because once rendered,\n\t * the editable DOM element must remain under the full control of the engine to work properly.\n\t */\n\tprotected _editingView: EditingView;\n\n\t/**\n\t * The element which is the main editable element (usually the one with `contentEditable=\"true\"`).\n\t */\n\tprotected _editableElement: HTMLElement | null | undefined;\n\n\t/**\n\t * Whether an external {@link #_editableElement} was passed into the constructor, which also means\n\t * the view will not render its {@link #template}.\n\t */\n\tprivate _hasExternalElement: boolean;\n\n\t/**\n\t * Creates an instance of EditableUIView class.\n\t *\n\t * @param locale The locale instance.\n\t * @param editingView The editing view instance the editable is related to.\n\t * @param editableElement The editable element. If not specified, this view\n\t * should create it. Otherwise, the existing element should be used.\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\teditingView: EditingView,\n\t\teditableElement?: HTMLElement\n\t) {\n\t\tsuper( locale );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-content',\n\t\t\t\t\t'ck-editor__editable',\n\t\t\t\t\t'ck-rounded-corners'\n\t\t\t\t],\n\t\t\t\tlang: locale.contentLanguage,\n\t\t\t\tdir: locale.contentLanguageDirection\n\t\t\t}\n\t\t} );\n\n\t\tthis.set( 'isFocused', false );\n\n\t\tthis._editableElement = editableElement;\n\t\tthis._hasExternalElement = !!this._editableElement;\n\t\tthis._editingView = editingView;\n\t}\n\n\t/**\n\t * Renders the view by either applying the {@link #template} to the existing\n\t * {@link module:ui/editableui/editableuiview~EditableUIView#_editableElement} or assigning {@link #element}\n\t * as {@link module:ui/editableui/editableuiview~EditableUIView#_editableElement}.\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tif ( this._hasExternalElement ) {\n\t\t\tthis.template!.apply( this.element = this._editableElement! );\n\t\t} else {\n\t\t\tthis._editableElement = this.element;\n\t\t}\n\n\t\tthis.on<ObservableChangeEvent>( 'change:isFocused', () => this._updateIsFocusedClasses() );\n\t\tthis._updateIsFocusedClasses();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tif ( this._hasExternalElement ) {\n\t\t\tthis.template!.revert( this._editableElement! );\n\t\t}\n\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Whether an external {@link #_editableElement} was passed into the constructor, which also means\n\t * the view will not render its {@link #template}.\n\t */\n\tpublic get hasExternalElement(): boolean {\n\t\treturn this._hasExternalElement;\n\t}\n\n\t/**\n\t * Updates the `ck-focused` and `ck-blurred` CSS classes on the {@link #element} according to\n\t * the {@link #isFocused} property value using the {@link #_editingView editing view} API.\n\t */\n\tprivate _updateIsFocusedClasses() {\n\t\tconst editingView = this._editingView;\n\n\t\tif ( editingView.isRenderingInProgress ) {\n\t\t\tupdateAfterRender( this );\n\t\t} else {\n\t\t\tupdate( this );\n\t\t}\n\n\t\tfunction update( view: EditableUIView ) {\n\t\t\teditingView.change( writer => {\n\t\t\t\tconst viewRoot = editingView.document.getRoot( view.name! )!;\n\n\t\t\t\twriter.addClass( view.isFocused ? 'ck-focused' : 'ck-blurred', viewRoot );\n\t\t\t\twriter.removeClass( view.isFocused ? 'ck-blurred' : 'ck-focused', viewRoot );\n\t\t\t} );\n\t\t}\n\n\t\t// In a case of a multi-root editor, a callback will be attached more than once (one callback for each root).\n\t\t// While executing one callback the `isRenderingInProgress` observable is changing what causes executing another\n\t\t// callback and render is called inside the already pending render.\n\t\t// We need to be sure that callback is executed only when the value has changed from `true` to `false`.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1676.\n\t\tfunction updateAfterRender( view: EditableUIView ) {\n\t\t\teditingView.once<ObservableChangeEvent<boolean>>( 'change:isRenderingInProgress', ( evt, name, value ) => {\n\t\t\t\tif ( !value ) {\n\t\t\t\t\tupdate( view );\n\t\t\t\t} else {\n\t\t\t\t\tupdateAfterRender( view );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/editableui/inline/inlineeditableuiview\n */\n\nimport EditableUIView from '../editableuiview.js';\n\nimport type { EditingView } from '@ckeditor/ckeditor5-engine';\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The inline editable UI class implementing an inline {@link module:ui/editableui/editableuiview~EditableUIView}.\n */\nexport default class InlineEditableUIView extends EditableUIView {\n\t/**\n\t * The cached options object passed to the constructor.\n\t */\n\tprivate readonly _options: InlineEditableUIViewOptions;\n\n\t/**\n\t * Creates an instance of the InlineEditableUIView class.\n\t *\n\t * @param locale The locale instance.\n\t * @param editingView The editing view instance the editable is related to.\n\t * @param editableElement The editable element. If not specified, the\n\t * {@link module:ui/editableui/editableuiview~EditableUIView}\n\t * will create it. Otherwise, the existing element will be used.\n\t * @param options Additional configuration of the view.\n\t * @param options.label The label of the editable for assistive technologies. If not provided, a default label is used or,\n\t * the existing `aria-label` attribute value from the specified `editableElement` is preserved.\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\teditingView: EditingView,\n\t\teditableElement?: HTMLElement,\n\t\toptions: InlineEditableUIViewOptions = {}\n\t) {\n\t\tsuper( locale, editingView, editableElement );\n\n\t\tthis._options = options;\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\trole: 'textbox',\n\t\t\t\tclass: 'ck-editor__editable_inline'\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tconst editingView = this._editingView;\n\n\t\teditingView.change( writer => {\n\t\t\tconst viewRoot = editingView.document.getRoot( this.name! );\n\n\t\t\twriter.setAttribute( 'aria-label', this.getEditableAriaLabel(), viewRoot! );\n\t\t} );\n\t}\n\n\t/**\n\t * Returns a normalized label for the editable view based on the environment.\n\t */\n\tpublic getEditableAriaLabel(): string {\n\t\tconst t = this.locale!.t;\n\t\tconst label = this._options.label;\n\t\tconst editableElement = this._editableElement;\n\t\tconst editableName = this.name!;\n\n\t\tif ( typeof label == 'string' ) {\n\t\t\treturn label;\n\t\t} else if ( typeof label === 'object' ) {\n\t\t\treturn label[ editableName ];\n\t\t} else if ( typeof label === 'function' ) {\n\t\t\treturn label( this );\n\t\t} else if ( editableElement ) {\n\t\t\tconst existingLabel = editableElement.getAttribute( 'aria-label' );\n\n\t\t\tif ( existingLabel ) {\n\t\t\t\treturn existingLabel;\n\t\t\t}\n\t\t}\n\n\t\treturn t( 'Rich Text Editor. Editing area: %0', editableName );\n\t}\n}\n\ntype InlineEditableUIViewOptions = {\n\tlabel?: ( ( view: InlineEditableUIView ) => string ) | string | Record<string, string>;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/iframe/iframeview\n */\n\nimport View from '../view.js';\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\n/**\n * The iframe view class.\n *\n * ```ts\n * const iframe = new IframeView();\n *\n * iframe.render();\n * document.body.appendChild( iframe.element );\n *\n * iframe.on( 'loaded', () => {\n * \tconsole.log( 'The iframe has loaded', iframe.element.contentWindow );\n * } );\n *\n * iframe.element.src = 'https://ckeditor.com';\n * ```\n */\nexport default class IframeView extends View<HTMLIFrameElement> {\n\t/**\n\t * Creates a new instance of the iframe view.\n\t *\n\t * @param locale The locale instance.\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'iframe',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset_all'\n\t\t\t\t],\n\t\t\t\t// It seems that we need to allow scripts in order to be able to listen to events.\n\t\t\t\t// TODO: Research that. Perhaps the src must be set?\n\t\t\t\tsandbox: 'allow-same-origin allow-scripts'\n\t\t\t},\n\t\t\ton: {\n\t\t\t\tload: bind.to( 'loaded' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Renders the iframe's {@link #element} and returns a `Promise` for asynchronous\n\t * child `contentDocument` loading process.\n\t *\n\t * @returns A promise which resolves once the iframe `contentDocument` has\n\t * been {@link #event:loaded}.\n\t */\n\tpublic override render(): Promise<unknown> {\n\t\treturn new Promise( resolve => {\n\t\t\tthis.on<IframeViewLoadedEvent>( 'loaded', resolve );\n\n\t\t\treturn super.render();\n\t\t} );\n\t}\n}\n\n/**\n * Fired when the DOM iframe's `contentDocument` finished loading.\n *\n * @eventName ~IframeView#loaded\n */\nexport type IframeViewLoadedEvent = {\n\tname: 'loaded';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/search/filtergroupanditemnames\n */\n\nimport type ButtonView from '../button/buttonview.js';\nimport type ButtonLabelWithHighlightView from '../highlightedtext/buttonlabelwithhighlightview.js';\nimport type LabelWithHighlightView from '../highlightedtext/labelwithhighlightview.js';\nimport type ViewCollection from '../viewcollection.js';\nimport type ListItemGroupView from '../list/listitemgroupview.js';\nimport type ListItemView from '../list/listitemview.js';\nimport type ListSeparatorView from '../list/listseparatorview.js';\n\n/**\n * A filter function that returns matching item and group names in the list view.\n */\nexport default function filterGroupAndItemNames(\n\tregExp: RegExp | null,\n\titems: ViewCollection<ListItemGroupView | ListItemView | ListSeparatorView>\n): {\n\tresultsCount: number;\n\ttotalItemsCount: number;\n} {\n\tlet totalItemsCount = 0;\n\tlet resultsCount = 0;\n\n\tfor ( const groupView of items ) {\n\t\tconst group = groupView as ListItemGroupView;\n\t\tconst groupItems = group.items as ViewCollection<ListItemView>;\n\t\tconst isGroupLabelMatching = regExp && !!group.label.match( regExp );\n\n\t\t( group.labelView as LabelWithHighlightView ).highlightText( isGroupLabelMatching ? regExp : null );\n\n\t\tfor ( const listItemView of groupItems ) {\n\t\t\tconst buttonView = listItemView.children.first as ButtonView;\n\t\t\tconst labelView = buttonView.labelView as ButtonLabelWithHighlightView;\n\n\t\t\tif ( !regExp ) {\n\t\t\t\tlistItemView.isVisible = true;\n\t\t\t\tlabelView.highlightText( null );\n\t\t\t} else {\n\t\t\t\tconst isItemLabelMatching = !!buttonView.label!.match( regExp );\n\n\t\t\t\tlabelView.highlightText( isItemLabelMatching ? regExp : null );\n\n\t\t\t\tlistItemView.isVisible = isGroupLabelMatching || isItemLabelMatching;\n\t\t\t}\n\t\t}\n\n\t\tconst visibleInGroupCount = groupItems.filter( listItemView => listItemView.isVisible ).length;\n\n\t\ttotalItemsCount += group.items.length;\n\t\tresultsCount += isGroupLabelMatching ? group.items.length : visibleInGroupCount;\n\t\tgroup.isVisible = isGroupLabelMatching || !!visibleInGroupCount;\n\t}\n\n\treturn {\n\t\tresultsCount,\n\t\ttotalItemsCount\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/notification/notification\n */\n\n/* globals window */\n\nimport { ContextPlugin } from '@ckeditor/ckeditor5-core';\n\n/**\n * The Notification plugin.\n *\n * This plugin sends a few types of notifications: `success`, `info` and `warning`. The notifications need to be\n * handled and displayed by a plugin responsible for showing the UI of the notifications. Using this plugin for dispatching\n * notifications makes it possible to switch the notifications UI.\n *\n * Note that every unhandled and not stopped `warning` notification will be displayed as a system alert.\n * See {@link module:ui/notification/notification~Notification#showWarning}.\n */\nexport default class Notification extends ContextPlugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Notification' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\t// Each unhandled and not stopped `show:warning` event is displayed as a system alert.\n\t\tthis.on<NotificationShowWarningEvent>( 'show:warning', ( evt, data ) => {\n\t\t\twindow.alert( data.message ); // eslint-disable-line no-alert\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Shows a success notification.\n\t *\n\t * By default, it fires the {@link #event:show:success `show:success` event} with the given `data`. The event namespace can be extended\n\t * using the `data.namespace` option. For example:\n\t *\n\t * ```ts\n\t * showSuccess( 'Image is uploaded.', {\n\t * \tnamespace: 'upload:image'\n\t * } );\n\t * ```\n\t *\n\t * will fire the `show:success:upload:image` event.\n\t *\n\t * You can provide the title of the notification:\n\t *\n\t * ```ts\n\t * showSuccess( 'Image is uploaded.', {\n\t * \ttitle: 'Image upload success'\n\t * } );\n\t * ```\n\t *\n\t * @param message The content of the notification.\n\t * @param data Additional data.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */\n\tpublic showSuccess(\n\t\tmessage: string,\n\t\tdata: { namespace?: string; title?: string } = {}\n\t): void {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'success',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Shows an information notification.\n\t *\n\t * By default, it fires the {@link #event:show:info `show:info` event} with the given `data`. The event namespace can be extended\n\t * using the `data.namespace` option. For example:\n\t *\n\t * ```ts\n\t * showInfo( 'Editor is offline.', {\n\t * \tnamespace: 'editor:status'\n\t * } );\n\t * ```\n\t *\n\t * will fire the `show:info:editor:status` event.\n\t *\n\t * You can provide the title of the notification:\n\t *\n\t * ```ts\n\t * showInfo( 'Editor is offline.', {\n\t * \ttitle: 'Network information'\n\t * } );\n\t * ```\n\t *\n\t * @param message The content of the notification.\n\t * @param data Additional data.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */\n\tpublic showInfo(\n\t\tmessage: string,\n\t\tdata: { namespace?: string; title?: string } = {}\n\t): void {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'info',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Shows a warning notification.\n\t *\n\t * By default, it fires the {@link #event:show:warning `show:warning` event}\n\t * with the given `data`. The event namespace can be extended using the `data.namespace` option. For example:\n\t *\n\t * ```ts\n\t * showWarning( 'Image upload error.', {\n\t * \tnamespace: 'upload:image'\n\t * } );\n\t * ```\n\t *\n\t * will fire the `show:warning:upload:image` event.\n\t *\n\t * You can provide the title of the notification:\n\t *\n\t * ```ts\n\t * showWarning( 'Image upload error.', {\n\t * \ttitle: 'Upload failed'\n\t * } );\n\t * ```\n\t *\n\t * Note that each unhandled and not stopped `warning` notification will be displayed as a system alert.\n\t * The plugin responsible for displaying warnings should `stop()` the event to prevent displaying it as an alert:\n\t *\n\t * ```ts\n\t * notifications.on( 'show:warning', ( evt, data ) => {\n\t * \t// Do something with the data.\n\t *\n\t * \t// Stop this event to prevent displaying it as an alert.\n\t * \tevt.stop();\n\t * } );\n\t * ```\n\t *\n\t * You can attach many listeners to the same event and `stop()` this event in a listener with a low priority:\n\t *\n\t * ```ts\n\t * notifications.on( 'show:warning', ( evt, data ) => {\n\t * \t// Show the warning in the UI, but do not stop it.\n\t * } );\n\t *\n\t * notifications.on( 'show:warning', ( evt, data ) => {\n\t * \t// Log the warning to some error tracker.\n\t *\n\t * \t// Stop this event to prevent displaying it as an alert.\n\t * \tevt.stop();\n\t * }, { priority: 'low' } );\n\t * ```\n\t *\n\t * @param message The content of the notification.\n\t * @param data Additional data.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */\n\tpublic showWarning(\n\t\tmessage: string,\n\t\tdata: { namespace?: string; title?: string } = {}\n\t): void {\n\t\tthis._showNotification( {\n\t\t\tmessage,\n\t\t\ttype: 'warning',\n\t\t\tnamespace: data.namespace,\n\t\t\ttitle: data.title\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `show` event with the specified type, namespace and message.\n\t *\n\t * @param data The message data.\n\t * @param data.message The content of the notification.\n\t * @param data.type The type of the message.\n\t * @param data.namespace Additional event namespace.\n\t * @param data.title The title of the notification.\n\t */\n\tprivate _showNotification( data: {\n\t\tmessage: string;\n\t\ttype: NotificationEventType;\n\t\tnamespace?: string;\n\t\ttitle?: string;\n\t} ): void {\n\t\tconst event = data.namespace ?\n\t\t\t`show:${ data.type }:${ data.namespace }` as const :\n\t\t\t`show:${ data.type }` as const;\n\n\t\tthis.fire<NotificationShowTypeEvent<typeof data.type>>( event, {\n\t\t\tmessage: data.message,\n\t\t\ttype: data.type,\n\t\t\ttitle: data.title || ''\n\t\t} );\n\t}\n}\n\nexport type NotificationEventType = 'success' | 'info' | 'warning';\n\n/**\n * Fired when one of the `showSuccess()`, `showInfo()`, `showWarning()` methods is called.\n *\n * @eventName ~Notification#show\n * @param data The notification data.\n */\nexport type NotificationShowEvent = {\n\tname: 'show';\n\targs: [ data: NotificationShowEventData ];\n};\n\n/**\n * Fired when the `showSuccess()` method is called.\n *\n * @eventName ~Notification#show:success\n * @param data The notification data.\n */\nexport type NotificationShowSuccessEvent = NotificationShowTypeEvent<'success'>;\n\n/**\n * Fired when the `showInfo()` method is called.\n *\n * @eventName ~Notification#show:info\n * @param data The notification data.\n */\nexport type NotificationShowInfoEvent = NotificationShowTypeEvent<'info'>;\n\n/**\n * Fired when the `showWarning()` method is called.\n *\n * When this event is not handled or stopped by `event.stop()`, the `data.message` of this event will\n * be automatically displayed as a system alert.\n *\n * @eventName ~Notification#show:warning\n * @param data The notification data.\n */\nexport type NotificationShowWarningEvent = NotificationShowTypeEvent<'warning'>;\n\nexport type NotificationShowTypeEvent<NotificationType extends NotificationEventType> = {\n\tname: `show:${ NotificationType }` | `show:${ NotificationType }:${ string }`;\n\targs: [ data: NotificationShowEventData<NotificationType> ];\n};\n\nexport type NotificationShowEventData<NotificationType extends NotificationEventType = NotificationEventType> = {\n\n\t/**\n\t * The content of the notification.\n\t */\n\tmessage: string;\n\n\t/**\n\t * The title of the notification.\n\t */\n\ttitle: string;\n\n\t/**\n\t * The type of the notification.\n\t */\n\ttype: NotificationType;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/model\n */\n\nimport { ObservableMixin } from '@ckeditor/ckeditor5-utils';\nimport { extend } from 'lodash-es';\n\n/**\n * The base MVC model class.\n */\nexport default class Model extends /* #__PURE__ */ ObservableMixin() {\n\t[ x: string ]: unknown;\n\n\t/**\n\t * Creates a new Model instance.\n\t *\n\t * @param attributes The model state attributes to be defined during the instance creation.\n\t * @param properties The (out of state) properties to be appended to the instance during creation.\n\t */\n\tconstructor( attributes?: Record<string, unknown>, properties?: Record<string, unknown> ) {\n\t\tsuper();\n\n\t\t// Extend this instance with the additional (out of state) properties.\n\t\tif ( properties ) {\n\t\t\textend( this, properties );\n\t\t}\n\n\t\t// Initialize the attributes.\n\t\tif ( attributes ) {\n\t\t\tthis.set( attributes );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/panel/balloon/contextualballoon\n */\n\nimport BalloonPanelView from './balloonpanelview.js';\nimport View from '../../view.js';\nimport ButtonView from '../../button/buttonview.js';\nimport type { ButtonExecuteEvent } from '../../button/button.js';\nimport type ViewCollection from '../../viewcollection.js';\n\nimport { Plugin, icons, type Editor } from '@ckeditor/ckeditor5-core';\nimport {\n\tCKEditorError,\n\tFocusTracker,\n\tRect,\n\ttoUnit,\n\ttype Locale,\n\ttype ObservableChangeEvent,\n\ttype PositionOptions,\n\ttype DecoratedMethodEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport '../../../theme/components/panel/balloonrotator.css';\nimport '../../../theme/components/panel/fakepanel.css';\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n/**\n * Provides the common contextual balloon for the editor.\n *\n * The role of this plugin is to unify the contextual balloons logic, simplify views management and help\n * avoid the unnecessary complexity of handling multiple {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView}\n * instances in the editor.\n *\n * This plugin allows for creating single or multiple panel stacks.\n *\n * Each stack may have multiple views, with the one on the top being visible. When the visible view is removed from the stack,\n * the previous view becomes visible.\n *\n * It might be useful to implement nested navigation in a balloon. For instance, a toolbar view may contain a link button.\n * When you click it, a link view (which lets you set the URL) is created and put on top of the toolbar view, so the link panel\n * is displayed. When you finish editing the link and close (remove) the link view, the toolbar view is visible again.\n *\n * However, there are cases when there are multiple independent balloons to be displayed, for instance, if the selection\n * is inside two inline comments at the same time. For such cases, you can create two independent panel stacks.\n * The contextual balloon plugin will create a navigation bar to let the users switch between these panel stacks using the \"Next\"\n * and \"Previous\" buttons.\n *\n * If there are no views in the current stack, the balloon panel will try to switch to the next stack. If there are no\n * panels in any stack, the balloon panel will be hidden.\n *\n * **Note**: To force the balloon panel to show only one view, even if there are other stacks, use the `singleViewMode=true` option\n * when {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon#add adding} a view to a panel.\n *\n * From the implementation point of view, the contextual ballon plugin is reusing a single\n * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance to display multiple contextual balloon\n * panels in the editor. It also creates a special {@link module:ui/panel/balloon/contextualballoon~RotatorView rotator view},\n * used to manage multiple panel stacks. Rotator view is a child of the balloon panel view and the parent of the specific\n * view you want to display. If there is more than one panel stack to be displayed, the rotator view will add a\n * navigation bar. If there is only one stack, the rotator view is transparent (it does not add any UI elements).\n */\nexport default class ContextualBalloon extends Plugin {\n\t/**\n\t * The {@link module:utils/dom/position~Options#limiter position limiter}\n\t * for the {@link #view balloon}, used when no `limiter` has been passed into {@link #add}\n\t * or {@link #updatePosition}.\n\t *\n\t * By default, a function that obtains the farthest DOM\n\t * {@link module:engine/view/rooteditableelement~RootEditableElement}\n\t * of the {@link module:engine/view/document~Document#selection}.\n\t */\n\tpublic positionLimiter: PositionOptions[ 'limiter' ];\n\n\tpublic visibleStack?: string;\n\n\t/**\n\t * The currently visible view or `null` when there are no views in any stack.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public visibleView: View | null;\n\n\t/**\n\t * A total number of all stacks in the balloon.\n\t *\n\t * @private\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _numberOfStacks: number;\n\n\t/**\n\t * A flag that controls the single view mode.\n\t *\n\t * @private\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _singleViewMode: boolean;\n\n\t/**\n\t * The map of views and their stacks.\n\t */\n\tprivate _viewToStack = new Map<View, Stack>();\n\n\t/**\n\t * The map of IDs and stacks.\n\t */\n\tprivate _idToStack = new Map<string, Stack>();\n\n\t/**\n\t * The common balloon panel view.\n\t */\n\tprivate _view: BalloonPanelView | null = null;\n\n\t/**\n\t * Rotator view embedded in the contextual balloon.\n\t * Displays the currently visible view in the balloon and provides navigation for switching stacks.\n\t */\n\tprivate _rotatorView: RotatorView | null = null;\n\n\t/**\n\t * Displays fake panels under the balloon panel view when multiple stacks are added to the balloon.\n\t */\n\tprivate _fakePanelsView: FakePanelsView | null = null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ContextualBalloon' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis.positionLimiter = () => {\n\t\t\tconst view = this.editor.editing.view;\n\t\t\tconst viewDocument = view.document;\n\t\t\tconst editableElement = viewDocument.selection.editableElement;\n\n\t\t\tif ( editableElement ) {\n\t\t\t\treturn view.domConverter.mapViewToDom( editableElement.root ) as HTMLElement;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t};\n\n\t\tthis.decorate( 'getPositionOptions' );\n\n\t\tthis.set( 'visibleView', null );\n\t\tthis.set( '_numberOfStacks', 0 );\n\t\tthis.set( '_singleViewMode', false );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tif ( this._view ) {\n\t\t\tthis._view.destroy();\n\t\t}\n\n\t\tif ( this._rotatorView ) {\n\t\t\tthis._rotatorView.destroy();\n\t\t}\n\n\t\tif ( this._fakePanelsView ) {\n\t\t\tthis._fakePanelsView.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * The common balloon panel view.\n\t */\n\tpublic get view(): BalloonPanelView {\n\t\tif ( !this._view ) {\n\t\t\tthis._createPanelView();\n\t\t}\n\n\t\treturn this._view!;\n\t}\n\n\t/**\n\t * Returns `true` when the given view is in one of the stacks. Otherwise returns `false`.\n\t */\n\tpublic hasView( view: View ): boolean {\n\t\treturn Array.from( this._viewToStack.keys() ).includes( view );\n\t}\n\n\t/**\n\t * Adds a new view to the stack and makes it visible if the current stack is visible\n\t * or it is the first view in the balloon.\n\t *\n\t * @param data The configuration of the view.\n\t * @param data.stackId The ID of the stack that the view is added to. Defaults to `'main'`.\n\t * @param data.view The content of the balloon.\n\t * @param data.position Positioning options.\n\t * @param data.balloonClassName An additional CSS class added to the {@link #view balloon} when visible.\n\t * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow. Defaults to `true`.\n\t * @param data.singleViewMode Whether the view should be the only visible view even if other stacks were added. Defaults to `false`.\n\t */\n\tpublic add( data: ViewConfiguration ): void {\n\t\tif ( !this._view ) {\n\t\t\tthis._createPanelView();\n\t\t}\n\n\t\tif ( this.hasView( data.view ) ) {\n\t\t\t/**\n\t\t\t * Trying to add configuration of the same view more than once.\n\t\t\t *\n\t\t\t * @error contextualballoon-add-view-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'contextualballoon-add-view-exist',\n\t\t\t\t[ this, data ]\n\t\t\t);\n\t\t}\n\n\t\tconst stackId = data.stackId || 'main';\n\n\t\t// If new stack is added, creates it and show view from this stack.\n\t\tif ( !this._idToStack.has( stackId ) ) {\n\t\t\tthis._idToStack.set( stackId, new Map( [ [ data.view, data ] ] ) );\n\t\t\tthis._viewToStack.set( data.view, this._idToStack.get( stackId )! );\n\t\t\tthis._numberOfStacks = this._idToStack.size;\n\n\t\t\tif ( !this._visibleStack || data.singleViewMode ) {\n\t\t\t\tthis.showStack( stackId );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst stack = this._idToStack.get( stackId )!;\n\n\t\tif ( data.singleViewMode ) {\n\t\t\tthis.showStack( stackId );\n\t\t}\n\n\t\t// Add new view to the stack.\n\t\tstack.set( data.view, data );\n\t\tthis._viewToStack.set( data.view, stack );\n\n\t\t// And display it if is added to the currently visible stack.\n\t\tif ( stack === this._visibleStack ) {\n\t\t\tthis._showView( data );\n\t\t}\n\t}\n\n\t/**\n\t * Removes the given view from the stack. If the removed view was visible,\n\t * the view preceding it in the stack will become visible instead.\n\t * When there is no view in the stack, the next stack will be displayed.\n\t * When there are no more stacks, the balloon will hide.\n\t *\n\t * @param view A view to be removed from the balloon.\n\t */\n\tpublic remove( view: View ): void {\n\t\tif ( !this.hasView( view ) ) {\n\t\t\t/**\n\t\t\t * Trying to remove the configuration of the view not defined in the stack.\n\t\t\t *\n\t\t\t * @error contextualballoon-remove-view-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'contextualballoon-remove-view-not-exist',\n\t\t\t\t[ this, view ]\n\t\t\t);\n\t\t}\n\n\t\tconst stack = this._viewToStack.get( view )!;\n\n\t\tif ( this._singleViewMode && this.visibleView === view ) {\n\t\t\tthis._singleViewMode = false;\n\t\t}\n\n\t\t// When visible view will be removed we need to show a preceding view or next stack\n\t\t// if a view is the only view in the stack.\n\t\tif ( this.visibleView === view ) {\n\t\t\tif ( stack.size === 1 ) {\n\t\t\t\tif ( this._idToStack.size > 1 ) {\n\t\t\t\t\tthis._showNextStack();\n\t\t\t\t} else {\n\t\t\t\t\tthis.view.hide();\n\t\t\t\t\tthis.visibleView = null;\n\t\t\t\t\tthis._rotatorView!.hideView();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._showView( Array.from( stack.values() )[ stack.size - 2 ] );\n\t\t\t}\n\t\t}\n\n\t\tif ( stack.size === 1 ) {\n\t\t\tthis._idToStack.delete( this._getStackId( stack ) );\n\t\t\tthis._numberOfStacks = this._idToStack.size;\n\t\t} else {\n\t\t\tstack.delete( view );\n\t\t}\n\n\t\tthis._viewToStack.delete( view );\n\t}\n\n\t/**\n\t * Updates the position of the balloon using the position data of the first visible view in the stack.\n\t * When new position data is given, the position data of the currently visible view will be updated.\n\t *\n\t * @param position Position options.\n\t */\n\tpublic updatePosition( position?: Partial<PositionOptions> ): void {\n\t\tif ( position ) {\n\t\t\tthis._visibleStack.get( this.visibleView! )!.position = position;\n\t\t}\n\n\t\tthis.view.pin( this.getPositionOptions()! );\n\t\tthis._fakePanelsView!.updatePosition();\n\t}\n\n\t/**\n\t * Returns position options of the last view in the stack.\n\t * This keeps the balloon in the same position when the view is changed.\n\t */\n\tpublic getPositionOptions(): Partial<PositionOptions> | undefined {\n\t\tlet position = Array.from( this._visibleStack.values() ).pop()!.position;\n\n\t\tif ( position ) {\n\t\t\t// Use the default limiter if none has been specified.\n\t\t\tif ( !position.limiter ) {\n\t\t\t\t// Don't modify the original options object.\n\t\t\t\tposition = Object.assign( {}, position, {\n\t\t\t\t\tlimiter: this.positionLimiter\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Don't modify the original options object.\n\t\t\tposition = Object.assign( {}, position, {\n\t\t\t\tviewportOffsetConfig: this.editor.ui.viewportOffset\n\t\t\t} );\n\t\t}\n\n\t\treturn position;\n\t}\n\n\t/**\n\t * Shows the last view from the stack of a given ID.\n\t */\n\tpublic showStack( id: string ): void {\n\t\tthis.visibleStack = id;\n\t\tconst stack = this._idToStack.get( id );\n\n\t\tif ( !stack ) {\n\t\t\t/**\n\t\t\t * Trying to show a stack that does not exist.\n\t\t\t *\n\t\t\t * @error contextualballoon-showstack-stack-not-exist\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'contextualballoon-showstack-stack-not-exist',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tif ( this._visibleStack === stack ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._showView( Array.from( stack.values() ).pop()! );\n\t}\n\n\t/**\n\t * Initializes view instances.\n\t */\n\tprivate _createPanelView(): void {\n\t\tthis._view = new BalloonPanelView( this.editor.locale );\n\n\t\tthis.editor.ui.view.body.add( this._view );\n\n\t\tthis._rotatorView = this._createRotatorView();\n\t\tthis._fakePanelsView = this._createFakePanelsView();\n\t}\n\n\t/**\n\t * Returns the stack of the currently visible view.\n\t */\n\tprivate get _visibleStack() {\n\t\treturn this._viewToStack.get( this.visibleView! )!;\n\t}\n\n\t/**\n\t * Returns the ID of the given stack.\n\t */\n\tprivate _getStackId( stack: Stack ) {\n\t\tconst entry = Array.from( this._idToStack.entries() ).find( entry => entry[ 1 ] === stack )!;\n\n\t\treturn entry[ 0 ];\n\t}\n\n\t/**\n\t * Shows the last view from the next stack.\n\t */\n\tprivate _showNextStack() {\n\t\tconst stacks = Array.from( this._idToStack.values() );\n\n\t\tlet nextIndex = stacks.indexOf( this._visibleStack ) + 1;\n\n\t\tif ( !stacks[ nextIndex ] ) {\n\t\t\tnextIndex = 0;\n\t\t}\n\n\t\tthis.showStack( this._getStackId( stacks[ nextIndex ] ) );\n\t}\n\n\t/**\n\t * Shows the last view from the previous stack.\n\t */\n\tprivate _showPrevStack() {\n\t\tconst stacks = Array.from( this._idToStack.values() );\n\n\t\tlet nextIndex = stacks.indexOf( this._visibleStack ) - 1;\n\n\t\tif ( !stacks[ nextIndex ] ) {\n\t\t\tnextIndex = stacks.length - 1;\n\t\t}\n\n\t\tthis.showStack( this._getStackId( stacks[ nextIndex ] ) );\n\t}\n\n\t/**\n\t * Creates a rotator view.\n\t */\n\tprivate _createRotatorView() {\n\t\tconst view = new RotatorView( this.editor.locale );\n\t\tconst t = this.editor.locale.t;\n\n\t\tthis.view.content.add( view );\n\n\t\t// Hide navigation when there is only a one stack & not in single view mode.\n\t\tview.bind( 'isNavigationVisible' ).to( this, '_numberOfStacks', this, '_singleViewMode', ( value, isSingleViewMode ) => {\n\t\t\treturn !isSingleViewMode && value > 1;\n\t\t} );\n\n\t\t// Update balloon position after toggling navigation.\n\t\tview.on<ObservableChangeEvent>( 'change:isNavigationVisible', () => ( this.updatePosition() ), { priority: 'low' } );\n\n\t\t// Update stacks counter value.\n\t\tview.bind( 'counter' ).to( this, 'visibleView', this, '_numberOfStacks', ( visibleView, numberOfStacks ) => {\n\t\t\tif ( numberOfStacks < 2 ) {\n\t\t\t\treturn '';\n\t\t\t}\n\n\t\t\tconst current = Array.from( this._idToStack.values() ).indexOf( this._visibleStack ) + 1;\n\n\t\t\treturn t( '%0 of %1', [ current, numberOfStacks ] );\n\t\t} );\n\n\t\tview.buttonNextView.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\t// When current view has a focus then move focus to the editable before removing it,\n\t\t\t// otherwise editor will lost focus.\n\t\t\tif ( view.focusTracker.isFocused ) {\n\t\t\t\tthis.editor.editing.view.focus();\n\t\t\t}\n\n\t\t\tthis._showNextStack();\n\t\t} );\n\n\t\tview.buttonPrevView.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\t// When current view has a focus then move focus to the editable before removing it,\n\t\t\t// otherwise editor will lost focus.\n\t\t\tif ( view.focusTracker.isFocused ) {\n\t\t\t\tthis.editor.editing.view.focus();\n\t\t\t}\n\n\t\t\tthis._showPrevStack();\n\t\t} );\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Creates a fake panels view.\n\t */\n\tprivate _createFakePanelsView() {\n\t\tconst view = new FakePanelsView( this.editor.locale, this.view );\n\n\t\tview.bind( 'numberOfPanels' ).to( this, '_numberOfStacks', this, '_singleViewMode', ( number, isSingleViewMode ) => {\n\t\t\tconst showPanels = !isSingleViewMode && number >= 2;\n\n\t\t\treturn showPanels ? Math.min( number - 1, 2 ) : 0;\n\t\t} );\n\n\t\tview.listenTo<ObservableChangeEvent>( this.view, 'change:top', () => view.updatePosition() );\n\t\tview.listenTo<ObservableChangeEvent>( this.view, 'change:left', () => view.updatePosition() );\n\n\t\tthis.editor.ui.view.body.add( view );\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Sets the view as the content of the balloon and attaches the balloon using position\n\t * options of the first view.\n\t *\n\t * @param data Configuration.\n\t * @param data.view The view to show in the balloon.\n\t * @param data.balloonClassName Additional class name which will be added to the {@link #view balloon}.\n\t * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow.\n\t */\n\tprivate _showView( { view, balloonClassName = '', withArrow = true, singleViewMode = false }: ViewConfiguration ) {\n\t\tthis.view.class = balloonClassName;\n\t\tthis.view.withArrow = withArrow;\n\n\t\tthis._rotatorView!.showView( view );\n\t\tthis.visibleView = view;\n\t\tthis.view.pin( this.getPositionOptions()! );\n\t\tthis._fakePanelsView!.updatePosition();\n\n\t\tif ( singleViewMode ) {\n\t\t\tthis._singleViewMode = true;\n\t\t}\n\t}\n}\n\n/**\n * An event fired when the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} is about to get the position of the balloon.\n *\n * @eventName ~ContextualBalloon#getPositionOptions\n */\nexport type ContextualBalloonGetPositionOptionsEvent = DecoratedMethodEvent<ContextualBalloon, 'getPositionOptions'>;\n\n/**\n * The configuration of the view.\n */\nexport interface ViewConfiguration {\n\n\t/**\n\t * The ID of the stack that the view is added to.\n\t *\n\t * @default 'main'\n\t */\n\tstackId?: string;\n\n\t/**\n\t * The content of the balloon.\n\t */\n\tview: View;\n\n\t/**\n\t * Positioning options.\n\t */\n\tposition?: Partial<PositionOptions>;\n\n\t/**\n\t * An additional CSS class added to the {@link #view balloon} when visible.\n\t */\n\tballoonClassName?: string;\n\n\t/**\n\t * Whether the {@link #view balloon} should be rendered with an arrow.\n\t *\n\t * @default true\n\t */\n\twithArrow?: boolean;\n\n\t/**\n\t * Whether the view should be the only visible view even if other stacks were added.\n\t *\n\t * @default false\n\t */\n\tsingleViewMode?: boolean;\n}\n\ntype Stack = Map<View, ViewConfiguration>;\n\n/**\n * Rotator view is a helper class for the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon}.\n * It is used for displaying the last view from the current stack and providing navigation buttons for switching stacks.\n * See the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon} documentation to learn more.\n */\nexport class RotatorView extends View {\n\t/**\n\t * Used for checking if a view is focused or not.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Navigation button for switching the stack to the previous one.\n\t */\n\tpublic readonly buttonPrevView: ButtonView;\n\n\t/**\n\t * Navigation button for switching the stack to the next one.\n\t */\n\tpublic readonly buttonNextView: ButtonView;\n\n\t/**\n\t * A collection of the child views that creates the rotator content.\n\t */\n\tpublic readonly content: ViewCollection;\n\n\t/**\n\t * Defines whether navigation is visible or not.\n\t *\n\t * @observable\n\t */\n\tdeclare public isNavigationVisible: boolean;\n\n\t/**\n\t * @observable\n\t */\n\tdeclare public counter: string;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst t = locale.t;\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'isNavigationVisible', true );\n\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.buttonPrevView = this._createButtonView( t( 'Previous' ), icons.previousArrow );\n\t\tthis.buttonNextView = this._createButtonView( t( 'Next' ), icons.nextArrow );\n\t\tthis.content = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-balloon-rotator'\n\t\t\t\t],\n\t\t\t\t'z-index': '-1'\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck-balloon-rotator__navigation',\n\t\t\t\t\t\t\tbind.to( 'isNavigationVisible', value => value ? '' : 'ck-hidden' )\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tthis.buttonPrevView,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttag: 'span',\n\n\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t\t\t'ck-balloon-rotator__counter'\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttext: bind.to( 'counter' )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tthis.buttonNextView\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: 'ck-balloon-rotator__content'\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.content\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.focusTracker.add( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t}\n\n\t/**\n\t * Shows a given view.\n\t *\n\t * @param view The view to show.\n\t */\n\tpublic showView( view: View ): void {\n\t\tthis.hideView();\n\t\tthis.content.add( view );\n\t}\n\n\t/**\n\t * Hides the currently displayed view.\n\t */\n\tpublic hideView(): void {\n\t\tthis.content.clear();\n\t}\n\n\t/**\n\t * Creates a navigation button view.\n\t *\n\t * @param label The button label.\n\t * @param icon The button icon.\n\t */\n\tprivate _createButtonView( label: string, icon: string ) {\n\t\tconst view = new ButtonView( this.locale );\n\n\t\tview.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\treturn view;\n\t}\n}\n\n/**\n * Displays additional layers under the balloon when multiple stacks are added to the balloon.\n */\nclass FakePanelsView extends View {\n\t/**\n\t * Collection of the child views which creates fake panel content.\n\t */\n\tpublic readonly content: ViewCollection;\n\n\t/**\n\t * Fake panels top offset.\n\t *\n\t * @observable\n\t */\n\tdeclare public top: number;\n\n\t/**\n\t * Fake panels left offset.\n\t *\n\t * @observable\n\t */\n\tdeclare public left: number;\n\n\t/**\n\t * Fake panels height.\n\t *\n\t * @observable\n\t */\n\tdeclare public height: number;\n\n\t/**\n\t * Fake panels width.\n\t *\n\t * @observable\n\t */\n\tdeclare public width: number;\n\n\t/**\n\t * Number of rendered fake panels.\n\t *\n\t * @observable\n\t */\n\tdeclare public numberOfPanels: number;\n\n\t/**\n\t * Context.\n\t */\n\tprivate readonly _balloonPanelView: BalloonPanelView;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale, balloonPanelView: BalloonPanelView ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'top', 0 );\n\t\tthis.set( 'left', 0 );\n\t\tthis.set( 'height', 0 );\n\t\tthis.set( 'width', 0 );\n\t\tthis.set( 'numberOfPanels', 0 );\n\n\t\tthis.content = this.createCollection();\n\t\tthis._balloonPanelView = balloonPanelView;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-fake-panel',\n\t\t\t\t\tbind.to( 'numberOfPanels', number => number ? '' : 'ck-hidden' )\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\ttop: bind.to( 'top', toPx ),\n\t\t\t\t\tleft: bind.to( 'left', toPx ),\n\t\t\t\t\twidth: bind.to( 'width', toPx ),\n\t\t\t\t\theight: bind.to( 'height', toPx )\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: this.content\n\t\t} );\n\n\t\tthis.on<ObservableChangeEvent<number>>( 'change:numberOfPanels', ( evt, name, next, prev ) => {\n\t\t\tif ( next > prev ) {\n\t\t\t\tthis._addPanels( next - prev );\n\t\t\t} else {\n\t\t\t\tthis._removePanels( prev - next );\n\t\t\t}\n\n\t\t\tthis.updatePosition();\n\t\t} );\n\t}\n\n\tprivate _addPanels( number: number ) {\n\t\twhile ( number-- ) {\n\t\t\tconst view = new View();\n\n\t\t\tview.setTemplate( { tag: 'div' } );\n\n\t\t\tthis.content.add( view );\n\t\t\tthis.registerChild( view );\n\t\t}\n\t}\n\n\tprivate _removePanels( number: number ) {\n\t\twhile ( number-- ) {\n\t\t\tconst view = this.content.last!;\n\n\t\t\tthis.content.remove( view );\n\t\t\tthis.deregisterChild( view );\n\t\t\tview.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Updates coordinates of fake panels.\n\t */\n\tpublic updatePosition() {\n\t\tif ( this.numberOfPanels ) {\n\t\t\tconst { top, left } = this._balloonPanelView;\n\t\t\tconst { width, height } = new Rect( this._balloonPanelView.element! );\n\n\t\t\tObject.assign( this, { top, left, width, height } );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/panel/sticky/stickypanelview\n */\n\nimport View from '../../view.js';\nimport Template from '../../template.js';\n\nimport type ViewCollection from '../../viewcollection.js';\n\nimport {\n\ttype Locale,\n\ttype ObservableChangeEvent,\n\tglobal,\n\ttoUnit,\n\tRect\n} from '@ckeditor/ckeditor5-utils';\n\n// @if CK_DEBUG_STICKYPANEL // const {\n// @if CK_DEBUG_STICKYPANEL // \tdefault: RectDrawer,\n// @if CK_DEBUG_STICKYPANEL // \tdiagonalStylesBlack\n// @if CK_DEBUG_STICKYPANEL // } = require( '@ckeditor/ckeditor5-utils/tests/_utils/rectdrawer' );\n\nimport '../../../theme/components/panel/stickypanel.css';\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n/**\n * The sticky panel view class.\n */\nexport default class StickyPanelView extends View {\n\t/**\n\t * Collection of the child views which creates balloon panel contents.\n\t */\n\tpublic readonly content: ViewCollection;\n\n\t/**\n\t * Controls whether the sticky panel should be active.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isActive: boolean;\n\n\t/**\n\t * Controls whether the sticky panel is in the \"sticky\" state.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isSticky: boolean;\n\n\t/**\n\t * The limiter element for the sticky panel instance. Its bounding rect limits\n\t * the \"stickyness\" of the panel, i.e. when the panel reaches the bottom\n\t * edge of the limiter, it becomes sticky to that edge and does not float\n\t * off the limiter. It is mandatory for the panel to work properly and once\n\t * set, it cannot be changed.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public limiterElement: HTMLElement | null;\n\n\t/**\n\t * The offset from the bottom edge of {@link #limiterElement}\n\t * which stops the panel from stickying any further to prevent limiter's content\n\t * from being completely covered.\n\t *\n\t * @readonly\n\t * @observable\n\t * @default 50\n\t */\n\tdeclare public limiterBottomOffset: number;\n\n\t/**\n\t * The offset from the top edge of the web browser's viewport which makes the\n\t * panel become sticky. The default value is `0`, which means the panel becomes\n\t * sticky when it's upper edge touches the top of the page viewport.\n\t *\n\t * This attribute is useful when the web page has UI elements positioned to the top\n\t * either using `position: fixed` or `position: sticky`, which would cover the\n\t * sticky panel or vice–versa (depending on the `z-index` hierarchy).\n\t *\n\t * Bound to {@link module:ui/editorui/editorui~EditorUI#viewportOffset `EditorUI#viewportOffset`}.\n\t *\n\t * If {@link module:core/editor/editorconfig~EditorConfig#ui `EditorConfig#ui.viewportOffset.top`} is defined, then\n\t * it will override the default value.\n\t *\n\t * @observable\n\t * @default 0\n\t */\n\tdeclare public viewportTopOffset: number;\n\n\t/**\n\t * The panel which accepts children into {@link #content} collection.\n\t * Also an element which is positioned when {@link #isSticky}.\n\t */\n\tpublic contentPanelElement: HTMLElement;\n\n\t/**\n\t * Controls the `margin-left` CSS style of the panel.\n\t *\n\t * @private\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _marginLeft: string | null;\n\n\t/**\n\t * Set `true` if the sticky panel reached the bottom edge of the\n\t * {@link #limiterElement}.\n\t *\n\t * @private\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _isStickyToTheBottomOfLimiter: boolean;\n\n\t/**\n\t * The `top` CSS position of the panel when it is sticky to the top of the viewport or scrollable\n\t * ancestors of the {@link #limiterElement}.\n\t *\n\t * @private\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _stickyTopOffset: number | null;\n\n\t/**\n\t * The `bottom` CSS position of the panel when it is sticky to the bottom of the {@link #limiterElement}.\n\t *\n\t * @private\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public _stickyBottomOffset: number | null;\n\n\t/**\n\t * A dummy element which visually fills the space as long as the\n\t * actual panel is sticky. It prevents flickering of the UI.\n\t */\n\tprivate _contentPanelPlaceholder: HTMLElement;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'isActive', false );\n\t\tthis.set( 'isSticky', false );\n\t\tthis.set( 'limiterElement', null );\n\t\tthis.set( 'limiterBottomOffset', 50 );\n\t\tthis.set( 'viewportTopOffset', 0 );\n\n\t\tthis.set( '_marginLeft', null );\n\t\tthis.set( '_isStickyToTheBottomOfLimiter', false );\n\n\t\tthis.set( '_stickyTopOffset', null );\n\t\tthis.set( '_stickyBottomOffset', null );\n\n\t\tthis.content = this.createCollection();\n\n\t\tthis._contentPanelPlaceholder = new Template( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-sticky-panel__placeholder'\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\tdisplay: bind.to( 'isSticky', isSticky => isSticky ? 'block' : 'none' ),\n\t\t\t\t\theight: bind.to( 'isSticky', isSticky => {\n\t\t\t\t\t\treturn isSticky ? toPx( this._contentPanelRect.height ) : null;\n\t\t\t\t\t} )\n\t\t\t\t}\n\t\t\t}\n\t\t} ).render() as HTMLElement;\n\n\t\tthis.contentPanelElement = new Template( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-sticky-panel__content',\n\t\t\t\t\t// Toggle class of the panel when \"sticky\" state changes in the view.\n\t\t\t\t\tbind.if( 'isSticky', 'ck-sticky-panel__content_sticky' ),\n\t\t\t\t\tbind.if( '_isStickyToTheBottomOfLimiter', 'ck-sticky-panel__content_sticky_bottom-limit' )\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\twidth: bind.to( 'isSticky', isSticky => {\n\t\t\t\t\t\treturn isSticky ? toPx( this._contentPanelPlaceholder.getBoundingClientRect().width ) : null;\n\t\t\t\t\t} ),\n\n\t\t\t\t\ttop: bind.to( '_stickyTopOffset', value => value ? toPx( value ) : value ),\n\t\t\t\t\tbottom: bind.to( '_stickyBottomOffset', value => value ? toPx( value ) : value ),\n\n\t\t\t\t\tmarginLeft: bind.to( '_marginLeft' )\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tchildren: this.content\n\t\t} ).render() as HTMLElement;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-sticky-panel'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis._contentPanelPlaceholder,\n\t\t\t\tthis.contentPanelElement\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Check if the panel should go into the sticky state immediately.\n\t\tthis.checkIfShouldBeSticky();\n\n\t\t// Update sticky state of the panel as the window and ancestors are being scrolled.\n\t\tthis.listenTo( global.document, 'scroll', () => {\n\t\t\tthis.checkIfShouldBeSticky();\n\t\t}, { useCapture: true } );\n\n\t\t// Synchronize with `model.isActive` because sticking an inactive panel is pointless.\n\t\tthis.listenTo<ObservableChangeEvent>( this, 'change:isActive', () => {\n\t\t\tthis.checkIfShouldBeSticky();\n\t\t} );\n\t}\n\n\t/**\n\t * Analyzes the environment to decide whether the panel should be sticky or not.\n\t * Then handles the positioning of the panel.\n\t */\n\tpublic checkIfShouldBeSticky(): void {\n\t\t// @if CK_DEBUG_STICKYPANEL // RectDrawer.clear();\n\n\t\tif ( !this.limiterElement || !this.isActive ) {\n\t\t\tthis._unstick();\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst limiterRect = new Rect( this.limiterElement );\n\n\t\tlet visibleLimiterRect = limiterRect.getVisible();\n\n\t\tif ( visibleLimiterRect ) {\n\t\t\tconst windowRect = new Rect( global.window );\n\n\t\t\twindowRect.top += this.viewportTopOffset;\n\t\t\twindowRect.height -= this.viewportTopOffset;\n\n\t\t\tvisibleLimiterRect = visibleLimiterRect.getIntersection( windowRect );\n\t\t}\n\n\t\t// @if CK_DEBUG_STICKYPANEL // if ( visibleLimiterRect ) {\n\t\t// @if CK_DEBUG_STICKYPANEL // \tRectDrawer.draw( visibleLimiterRect,\n\t\t// @if CK_DEBUG_STICKYPANEL // \t\t{ outlineWidth: '3px', opacity: '.8', outlineColor: 'red', outlineOffset: '-3px' },\n\t\t// @if CK_DEBUG_STICKYPANEL // \t\t'Visible anc'\n\t\t// @if CK_DEBUG_STICKYPANEL // \t);\n\t\t// @if CK_DEBUG_STICKYPANEL // }\n\t\t// @if CK_DEBUG_STICKYPANEL //\n\t\t// @if CK_DEBUG_STICKYPANEL // RectDrawer.draw( limiterRect,\n\t\t// @if CK_DEBUG_STICKYPANEL // \t{ outlineWidth: '3px', opacity: '.8', outlineColor: 'green', outlineOffset: '-3px' },\n\t\t// @if CK_DEBUG_STICKYPANEL // \t'Limiter'\n\t\t// @if CK_DEBUG_STICKYPANEL // );\n\n\t\t// Stick the panel only if\n\t\t// * the limiter's ancestors are intersecting with each other so that some of their rects are visible,\n\t\t// * and the limiter's top edge is above the visible ancestors' top edge.\n\t\tif ( visibleLimiterRect && limiterRect.top < visibleLimiterRect.top ) {\n\t\t\t// @if CK_DEBUG_STICKYPANEL // RectDrawer.draw( visibleLimiterRect,\n\t\t\t// @if CK_DEBUG_STICKYPANEL // \t{ outlineWidth: '3px', opacity: '.8', outlineColor: 'fuchsia', outlineOffset: '-3px',\n\t\t\t// @if CK_DEBUG_STICKYPANEL // \t\tbackgroundColor: 'rgba(255, 0, 255, .3)' },\n\t\t\t// @if CK_DEBUG_STICKYPANEL // \t'Visible limiter'\n\t\t\t// @if CK_DEBUG_STICKYPANEL // );\n\n\t\t\tconst visibleLimiterTop = visibleLimiterRect.top;\n\n\t\t\t// Check if there's a change the panel can be sticky to the bottom of the limiter.\n\t\t\tif ( visibleLimiterTop + this._contentPanelRect.height + this.limiterBottomOffset > visibleLimiterRect.bottom ) {\n\t\t\t\tconst stickyBottomOffset = Math.max( limiterRect.bottom - visibleLimiterRect.bottom, 0 ) + this.limiterBottomOffset;\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // const stickyBottomOffsetRect = new Rect( {\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // \ttop: limiterRect.bottom - stickyBottomOffset, left: 0, right: 2000,\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // \tbottom: limiterRect.bottom - stickyBottomOffset, width: 2000, height: 1\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // } );\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // RectDrawer.draw( stickyBottomOffsetRect,\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // \t{ outlineWidth: '1px', opacity: '.8', outlineColor: 'black' },\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // \t'Sticky bottom offset'\n\t\t\t\t// @if CK_DEBUG_STICKYPANEL // );\n\n\t\t\t\t// Check if sticking the panel to the bottom of the limiter does not cause it to suddenly\n\t\t\t\t// move upwards if there's not enough space for it.\n\t\t\t\tif ( limiterRect.bottom - stickyBottomOffset > limiterRect.top + this._contentPanelRect.height ) {\n\t\t\t\t\tthis._stickToBottomOfLimiter( stickyBottomOffset );\n\t\t\t\t} else {\n\t\t\t\t\tthis._unstick();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( this._contentPanelRect.height + this.limiterBottomOffset < limiterRect.height ) {\n\t\t\t\t\tthis._stickToTopOfAncestors( visibleLimiterTop );\n\t\t\t\t} else {\n\t\t\t\t\tthis._unstick();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis._unstick();\n\t\t}\n\n\t\t// @if CK_DEBUG_STICKYPANEL // console.clear();\n\t\t// @if CK_DEBUG_STICKYPANEL // console.log( 'isSticky', this.isSticky );\n\t\t// @if CK_DEBUG_STICKYPANEL // console.log( '_isStickyToTheBottomOfLimiter', this._isStickyToTheBottomOfLimiter );\n\t\t// @if CK_DEBUG_STICKYPANEL // console.log( '_stickyTopOffset', this._stickyTopOffset );\n\t\t// @if CK_DEBUG_STICKYPANEL // console.log( '_stickyBottomOffset', this._stickyBottomOffset );\n\t\t// @if CK_DEBUG_STICKYPANEL // if ( visibleLimiterRect ) {\n\t\t// @if CK_DEBUG_STICKYPANEL // \tRectDrawer.draw( visibleLimiterRect,\n\t\t// @if CK_DEBUG_STICKYPANEL // \t\t{ ...diagonalStylesBlack,\n\t\t// @if CK_DEBUG_STICKYPANEL // \t\t\toutlineWidth: '3px', opacity: '.8', outlineColor: 'orange', outlineOffset: '-3px',\n\t\t// @if CK_DEBUG_STICKYPANEL // \t\t\tbackgroundColor: 'rgba(0, 0, 255, .2)' },\n\t\t// @if CK_DEBUG_STICKYPANEL // \t\t'visibleLimiterRect'\n\t\t// @if CK_DEBUG_STICKYPANEL // \t);\n\t\t// @if CK_DEBUG_STICKYPANEL // }\n\t}\n\n\t/**\n\t * Sticks the panel at the given CSS `top` offset.\n\t *\n\t * @private\n\t * @param topOffset\n\t */\n\tprivate _stickToTopOfAncestors( topOffset: number ) {\n\t\tthis.isSticky = true;\n\t\tthis._isStickyToTheBottomOfLimiter = false;\n\t\tthis._stickyTopOffset = topOffset;\n\t\tthis._stickyBottomOffset = null;\n\t\tthis._marginLeft = toPx( -global.window.scrollX );\n\t}\n\n\t/**\n\t * Sticks the panel at the bottom of the limiter with a given CSS `bottom` offset.\n\t *\n\t * @private\n\t * @param stickyBottomOffset\n\t */\n\tprivate _stickToBottomOfLimiter( stickyBottomOffset: number ) {\n\t\tthis.isSticky = true;\n\t\tthis._isStickyToTheBottomOfLimiter = true;\n\t\tthis._stickyTopOffset = null;\n\t\tthis._stickyBottomOffset = stickyBottomOffset;\n\t\tthis._marginLeft = toPx( -global.window.scrollX );\n\t}\n\n\t/**\n\t * Unsticks the panel putting it back to its original position.\n\t *\n\t * @private\n\t */\n\tprivate _unstick() {\n\t\tthis.isSticky = false;\n\t\tthis._isStickyToTheBottomOfLimiter = false;\n\t\tthis._stickyTopOffset = null;\n\t\tthis._stickyBottomOffset = null;\n\t\tthis._marginLeft = null;\n\t}\n\n\t/**\n\t * Returns the bounding rect of the {@link #contentPanelElement}.\n\t *\n\t * @private\n\t */\n\tprivate get _contentPanelRect(): Rect {\n\t\treturn new Rect( this.contentPanelElement );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/search/text/searchtextqueryview\n */\n\nimport ButtonView from '../../button/buttonview.js';\nimport IconView from '../../icon/iconview.js';\nimport LabeledFieldView, { type LabeledFieldViewCreator } from '../../labeledfield/labeledfieldview.js';\nimport { createLabeledInputText } from '../../labeledfield/utils.js';\nimport type InputBase from '../../input/inputbase.js';\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport { icons } from '@ckeditor/ckeditor5-core';\n\n/**\n * A search input field for the {@link module:ui/search/text/searchtextview~SearchTextView} component.\n *\n * @internal\n * @extends module:ui/labeledfield/labeledfieldview~LabeledFieldView\n */\nexport default class SearchTextQueryView<\n\tTQueryFieldView extends InputBase<HTMLInputElement | HTMLTextAreaElement>\n> extends LabeledFieldView<TQueryFieldView> {\n\t/**\n\t * The loupe icon displayed next to the {@link #fieldView}.\n\t */\n\tpublic iconView?: IconView;\n\n\t/**\n\t * The button that clears and focuses the {@link #fieldView}.\n\t */\n\tpublic resetButtonView?: ButtonView;\n\n\t/**\n\t * A reference to the view configuration.\n\t */\n\tprivate readonly _viewConfig: SearchTextQueryViewConfig<TQueryFieldView>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale, config: SearchTextQueryViewConfig<TQueryFieldView> ) {\n\t\tconst t = locale.t;\n\t\tconst viewConfig = Object.assign( {}, {\n\t\t\tshowResetButton: true,\n\t\t\tshowIcon: true,\n\t\t\tcreator: createLabeledInputText\n\t\t}, config );\n\n\t\tsuper( locale, viewConfig.creator as any );\n\n\t\tthis.label = config.label;\n\t\tthis._viewConfig = viewConfig;\n\n\t\tif ( this._viewConfig.showIcon ) {\n\t\t\tthis.iconView = new IconView();\n\t\t\tthis.iconView.content = icons.loupe;\n\t\t\tthis.fieldWrapperChildren.add( this.iconView, 0 );\n\n\t\t\tthis.extendTemplate( {\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: 'ck-search__query_with-icon'\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tif ( this._viewConfig.showResetButton ) {\n\t\t\tthis.resetButtonView = new ButtonView( locale );\n\t\t\tthis.resetButtonView.set( {\n\t\t\t\tlabel: t( 'Clear' ),\n\t\t\t\ticon: icons.cancel,\n\t\t\t\tclass: 'ck-search__reset',\n\t\t\t\tisVisible: false,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tthis.resetButtonView.on( 'execute', () => {\n\t\t\t\tthis.reset();\n\t\t\t\tthis.focus();\n\t\t\t\tthis.fire<SearchTextQueryViewResetEvent>( 'reset' );\n\t\t\t} );\n\n\t\t\tthis.resetButtonView.bind( 'isVisible' ).to( this.fieldView, 'isEmpty', isEmpty => !isEmpty );\n\n\t\t\tthis.fieldWrapperChildren.add( this.resetButtonView );\n\n\t\t\tthis.extendTemplate( {\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: 'ck-search__query_with-reset'\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Resets the search field to its default state.\n\t */\n\tpublic reset(): void {\n\t\tthis.fieldView.reset();\n\n\t\tif ( this._viewConfig.showResetButton ) {\n\t\t\tthis.resetButtonView!.isVisible = false;\n\t\t}\n\t}\n}\n\n/**\n * An event fired when the field is reset using the\n * {@link module:ui/search/text/searchtextqueryview~SearchTextQueryView#resetButtonView}.\n *\n * @eventName ~SearchTextQueryView#reset\n */\nexport type SearchTextQueryViewResetEvent = {\n\tname: 'reset';\n\targs: [];\n};\n\n/**\n * The configuration of the {@link module:ui/search/text/searchtextqueryview~SearchTextQueryView} view.\n */\nexport interface SearchTextQueryViewConfig<TConfigSearchField extends InputBase<HTMLInputElement | HTMLTextAreaElement>> {\n\n\t/**\n\t * The human-readable label of the search field.\n\t */\n\tlabel: string;\n\n\t/**\n\t * Determines whether the button that resets the search should be visible.\n\t *\n\t * @default true\n\t */\n\tshowResetButton?: boolean;\n\n\t/**\n\t * Determines whether the loupe icon should be visible.\n\t *\n\t * @default true\n\t */\n\tshowIcon?: boolean;\n\n\t/**\n\t * The function that creates the search field input view. By default, a plain\n\t * {@link module:ui/inputtext/inputtextview~InputTextView} is used for this purpose.\n\t */\n\tcreator?: LabeledFieldViewCreator<TConfigSearchField>;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/search/searchinfoview\n*/\n\nimport type { FocusableView } from '../focuscycler.js';\nimport View from '../view.js';\n\n/**\n * A view displaying an information text related to different states of {@link module:ui/search/text/searchtextview~SearchTextView}.\n *\n * @internal\n */\nexport default class SearchInfoView extends View implements FocusableView {\n\t/**\n\t * Controls whether the view is visible.\n\t *\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * Controls the primary line of text in the info.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public primaryText: string;\n\n\t/**\n\t * Controls the secondary line of text in the info.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public secondaryText: string;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( {\n\t\t\tisVisible: false,\n\t\t\tprimaryText: '',\n\t\t\tsecondaryText: ''\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-search__info',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t],\n\t\t\t\ttabindex: -1\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttext: [ bind.to( 'primaryText' ) ]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttext: [ bind.to( 'secondaryText' ) ]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the view\n\t */\n\tpublic focus(): void {\n\t\tthis.element!.focus();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/search/searchresultsview\n */\n\nimport View from '../view.js';\nimport type ViewCollection from '../viewcollection.js';\nimport { FocusTracker, type Locale } from '@ckeditor/ckeditor5-utils';\nimport { default as FocusCycler, type FocusableView } from '../focuscycler.js';\n\n/**\n * A sub-component of {@link module:ui/search/text/searchtextview~SearchTextView}. It hosts the filtered and the information views.\n */\nexport default class SearchResultsView extends View implements FocusableView {\n\t/**\n\t * Tracks information about the DOM focus in the view.\n\t *\n\t * @readonly\n\t */\n\tpublic focusTracker: FocusTracker;\n\n\t/**\n\t * The collection of the child views inside of the list item {@link #element}.\n\t *\n\t * @readonly\n\t */\n\tpublic children: ViewCollection<FocusableView>;\n\n\t/**\n\t * Provides the focus management (keyboard navigation) in the view.\n\t *\n\t * @readonly\n\t */\n\tprotected _focusCycler: FocusCycler;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.children = this.createCollection();\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-search__results'\n\t\t\t\t],\n\t\t\t\ttabindex: -1\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.children,\n\t\t\tfocusTracker: this.focusTracker\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tfor ( const child of this.children ) {\n\t\t\tthis.focusTracker.add( child.element! );\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the view.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the first child view.\n\t */\n\tpublic focusFirst(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Focuses the last child view.\n\t */\n\tpublic focusLast(): void {\n\t\tthis._focusCycler.focusLast();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/search/text/searchtextview\n*/\n\nimport { FocusTracker, KeystrokeHandler, type Locale } from '@ckeditor/ckeditor5-utils';\nimport View from '../../view.js';\nimport { default as SearchTextQueryView, type SearchTextQueryViewConfig } from './searchtextqueryview.js';\nimport SearchInfoView from '../searchinfoview.js';\nimport SearchResultsView from '../searchresultsview.js';\nimport FocusCycler, { type FocusableView } from '../../focuscycler.js';\nimport { escapeRegExp } from 'lodash-es';\n\nimport type FilteredView from '../filteredview.js';\nimport type ViewCollection from '../../viewcollection.js';\nimport type InputBase from '../../input/inputbase.js';\nimport type InputTextView from '../../inputtext/inputtextview.js';\n\nimport '../../../theme/components/search/search.css';\n\n/**\n * A search component that allows filtering of an arbitrary view based on a search query\n * specified by the user in a text field.\n *\n *```ts\n * // This view must specify the `filter()` and `focus()` methods.\n * const filteredView = ...;\n *\n * const searchView = new SearchTextView( locale, {\n * \tsearchFieldLabel: 'Search list items',\n * \tfilteredView\n * } );\n *\n * view.render();\n *\n * document.body.append( view.element );\n * ```\n */\nexport default class SearchTextView<\n\tTQueryFieldView extends InputBase<HTMLInputElement | HTMLTextAreaElement> = InputTextView\n> extends View {\n\t/**\n\t * Tracks information about the DOM focus in the view.\n\t *\n\t * @readonly\n\t */\n\tpublic focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the keystroke handler managing user interaction and accessibility.\n\t *\n\t * @readonly\n\t */\n\tpublic keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A view hosting the {@link #filteredView} passed in the configuration and the {@link #infoView}.\n\t */\n\tpublic resultsView: SearchResultsView;\n\n\t/**\n\t * The view that is filtered by the search query.\n\t */\n\tpublic filteredView: FilteredView;\n\n\t/**\n\t * The view that displays the information about the search results.\n\t */\n\tpublic infoView: FocusableView | undefined;\n\n\t/**\n\t * The view that allows the user to enter the search query.\n\t */\n\tpublic queryView: SearchTextQueryView<TQueryFieldView>;\n\n\t/**\n\t * Controls whether the component is in read-only mode.\n\t *\n\t * @default true\n\t * @observable\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * The number of results found for the current search query. Updated upon the {@link #search} event.\n\t *\n\t * @default 0\n\t * @observable\n\t */\n\tdeclare public resultsCount: number;\n\n\t/**\n\t * The number of the items that can be searched in the {@link #filteredView}. Updated upon the {@link #search} event.\n\t *\n\t * @default 0\n\t * @observable\n\t */\n\tdeclare public totalItemsCount: number;\n\n\t/**\n\t * The collection of children of the view.\n\t *\n\t * @readonly\n\t */\n\tdeclare public readonly children: ViewCollection;\n\n\t/**\n\t * The collection of focusable children of the view. Used by the focus management logic.\n\t *\n\t * @readonly\n\t */\n\tdeclare public readonly focusableChildren: ViewCollection<FocusableView>;\n\n\tpublic declare locale: Locale;\n\n\t/**\n\t * Provides the focus management (keyboard navigation) between {@link #queryView} and {@link #filteredView}.\n\t *\n\t * @readonly\n\t */\n\tpublic focusCycler: FocusCycler;\n\n\t/**\n\t * The cached configuration object.\n\t *\n\t * @internal\n\t */\n\tprotected _config: SearchTextViewConfig<TQueryFieldView>;\n\n\t/**\n\t * Creates an instance of the {@link module:ui/search/text/searchtextview~SearchTextView} class.\n\t *\n\t * @param locale The localization services instance.\n\t * @param config Configuration of the view.\n\t */\n\tconstructor( locale: Locale, config: SearchTextViewConfig<TQueryFieldView> ) {\n\t\tsuper( locale );\n\n\t\tthis._config = config;\n\n\t\tthis.filteredView = config.filteredView;\n\t\tthis.queryView = this._createSearchTextQueryView();\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.resultsView = new SearchResultsView( locale );\n\t\tthis.children = this.createCollection();\n\t\tthis.focusableChildren = this.createCollection( [ this.queryView, this.resultsView ] );\n\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'resultsCount', 0 );\n\t\tthis.set( 'totalItemsCount', 0 );\n\n\t\tif ( config.infoView && config.infoView.instance ) {\n\t\t\tthis.infoView = config.infoView.instance;\n\t\t} else {\n\t\t\tthis.infoView = new SearchInfoView();\n\t\t\tthis._enableDefaultInfoViewBehavior();\n\n\t\t\tthis.on( 'render', () => {\n\t\t\t\t// Initial search that determines if there are any searchable items\n\t\t\t\t// and displays the corresponding info text.\n\t\t\t\tthis.search( '' );\n\t\t\t} );\n\t\t}\n\n\t\tthis.resultsView.children.addMany( [ this.infoView, this.filteredView ] );\n\n\t\tthis.focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.focusableChildren,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.on<SearchTextViewSearchEvent>( 'search', ( evt, { resultsCount, totalItemsCount } ) => {\n\t\t\tthis.resultsCount = resultsCount;\n\t\t\tthis.totalItemsCount = totalItemsCount;\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-search',\n\t\t\t\t\tconfig.class || null\n\t\t\t\t],\n\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.children.addMany( [\n\t\t\tthis.queryView,\n\t\t\tthis.resultsView\n\t\t] );\n\n\t\tconst stopPropagation = ( data: Event ) => data.stopPropagation();\n\n\t\tfor ( const focusableChild of this.focusableChildren ) {\n\t\t\tthis.focusTracker.add( focusableChild.element as HTMLElement );\n\t\t}\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element as HTMLElement );\n\n\t\t// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n\t\t// keystroke handler would take over the key management in the URL input. We need to prevent\n\t\t// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n\t\tthis.keystrokes.set( 'arrowright', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowleft', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowup', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowdown', stopPropagation );\n\t}\n\n\t/**\n\t * Focuses the {@link #queryView}.\n\t */\n\tpublic focus(): void {\n\t\tthis.queryView.focus();\n\t}\n\n\t/**\n\t * Resets the component to its initial state.\n\t */\n\tpublic reset(): void {\n\t\tthis.queryView.reset();\n\t\tthis.search( '' );\n\t\tthis.filteredView.element!.scrollTo( 0, 0 );\n\t}\n\n\t/**\n\t * Searches the {@link #filteredView} for the given query.\n\t *\n\t * @internal\n\t * @param query The search query string.\n\t */\n\tpublic search( query: string ): void {\n\t\tconst regExp = query ? new RegExp( escapeRegExp( query ), 'ig' ) : null;\n\t\tconst filteringResults = this.filteredView.filter( regExp );\n\n\t\tthis.fire<SearchTextViewSearchEvent>( 'search', { query, ...filteringResults } );\n\t}\n\n\t/**\n\t * Creates a search field view based on configured creator..\n\t */\n\tprivate _createSearchTextQueryView(): SearchTextQueryView<TQueryFieldView> {\n\t\tconst queryView = new SearchTextQueryView<TQueryFieldView>( this.locale, this._config.queryView );\n\n\t\tthis.listenTo( queryView.fieldView, 'input', () => {\n\t\t\tthis.search( queryView.fieldView.element!.value );\n\t\t} );\n\n\t\tqueryView.on( 'reset', () => this.reset() );\n\t\tqueryView.bind( 'isEnabled' ).to( this );\n\n\t\treturn queryView;\n\t}\n\n\t/**\n\t * Initializes the default {@link #infoView} behavior with default text labels when no custom info view\n\t * was specified in the view config.\n\t */\n\tprivate _enableDefaultInfoViewBehavior(): void {\n\t\tconst t = this.locale.t;\n\t\tconst infoView = this.infoView as SearchInfoView;\n\n\t\tthis.on<SearchTextViewSearchEvent>( 'search', ( evt, data ) => {\n\t\t\tif ( !data.resultsCount ) {\n\t\t\t\tconst defaultTextConfig = this._config.infoView && this._config.infoView.text;\n\t\t\t\tlet primaryText, secondaryText;\n\n\t\t\t\tif ( data.totalItemsCount ) {\n\t\t\t\t\tif ( defaultTextConfig && defaultTextConfig.notFound ) {\n\t\t\t\t\t\tprimaryText = defaultTextConfig.notFound.primary;\n\t\t\t\t\t\tsecondaryText = defaultTextConfig.notFound.secondary;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprimaryText = t( 'No results found' );\n\t\t\t\t\t\tsecondaryText = '';\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( defaultTextConfig && defaultTextConfig.noSearchableItems ) {\n\t\t\t\t\t\tprimaryText = defaultTextConfig.noSearchableItems.primary;\n\t\t\t\t\t\tsecondaryText = defaultTextConfig.noSearchableItems.secondary;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprimaryText = t( 'No searchable items' );\n\t\t\t\t\t\tsecondaryText = '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tinfoView.set( {\n\t\t\t\t\tprimaryText: normalizeInfoText( primaryText, data ),\n\t\t\t\t\tsecondaryText: normalizeInfoText( secondaryText!, data ),\n\t\t\t\t\tisVisible: true\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tinfoView.set( {\n\t\t\t\t\tisVisible: false\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tfunction normalizeInfoText(\n\t\t\ttext: SearchTextViewDefaultInfoText,\n\t\t\t{ query, resultsCount, totalItemsCount }: SearchTextViewSearchEvent[ 'args' ][ 0 ]\n\t\t) {\n\t\t\treturn typeof text === 'function' ? text( query, resultsCount, totalItemsCount ) : text;\n\t\t}\n\t}\n}\n\n/**\n * The configuration of the {@link module:ui/search/text/searchtextview~SearchTextView} class.\n */\nexport interface SearchTextViewConfig<TConfigSearchField extends InputBase<HTMLInputElement | HTMLTextAreaElement>> {\n\n\t/**\n\t * The configuration of the view's query field.\n\t */\n\tqueryView: SearchTextQueryViewConfig<TConfigSearchField>;\n\n\t/**\n\t * The view that is filtered by the search query.\n\t */\n\tfilteredView: FilteredView;\n\n\t/**\n\t * The view that displays the information about the search results.\n\t */\n\tinfoView?: {\n\n\t\t/**\n\t\t * The view that displays the information about the search results. If not specified,\n\t\t * {@link module:ui/search/searchinfoview~SearchInfoView} is used.\n\t\t */\n\t\tinstance?: FocusableView;\n\n\t\t/**\n\t\t * The configuration of text labels displayed in the {@link #infoView} in different states\n\t\t * of the search component.\n\t\t *\n\t\t * **Note**: This configuration is only used when the {@link #infoView} is **not** specified.\n\t\t * In other cases, please use the {@link module:ui/search/searchview~SearchTextViewSearchEvent} to bring about\n\t\t * your own info text logic.\n\t\t */\n\t\ttext?: {\n\t\t\tnotFound?: {\n\t\t\t\tprimary: SearchTextViewDefaultInfoText;\n\t\t\t\tsecondary?: SearchTextViewDefaultInfoText;\n\t\t\t};\n\t\t\tnoSearchableItems?: {\n\t\t\t\tprimary: SearchTextViewDefaultInfoText;\n\t\t\t\tsecondary?: SearchTextViewDefaultInfoText;\n\t\t\t};\n\t\t};\n\t};\n\n\t/**\n\t * The custom CSS class name to be added to the search view element.\n\t */\n\tclass?: string;\n}\n\n/**\n * Describes value of a info text configuration in {@link module:ui/search/text/searchtextview~SearchTextViewConfig}.\n * A string or a function that returns a string with the information about the search results.\n */\nexport type SearchTextViewDefaultInfoText = string | ( ( query: string, resultsCount: number, totalItemsCount: number ) => string );\n\n/**\n * An event fired when the search query changes fired by {@link module:ui/search/text/searchtextview~SearchTextView#search}.\n *\n * @eventName ~SearchTextView#search\n */\nexport type SearchTextViewSearchEvent = {\n\tname: 'search';\n\targs: [ SearchTextViewSearchEventData ];\n};\n\nexport type SearchTextViewSearchEventData = {\n\n\t/**\n\t * The search query string.\n\t */\n\tquery: string;\n\n\t/**\n\t * The number of results found for the current search query.\n\t */\n\tresultsCount: number;\n\n\t/**\n\t * The number of the items that can be searched.\n\t */\n\ttotalItemsCount: number;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/autocomplete/autocompleteview\n*/\n\nimport { getOptimalPosition, type PositioningFunction, type Locale, global, toUnit, Rect } from '@ckeditor/ckeditor5-utils';\nimport SearchTextView, { type SearchTextViewConfig } from '../search/text/searchtextview.js';\nimport type SearchResultsView from '../search/searchresultsview.js';\nimport type InputBase from '../input/inputbase.js';\nimport type { FilteredViewExecuteEvent } from '../search/filteredview.js';\n\nimport '../../theme/components/autocomplete/autocomplete.css';\n\n/**\n * The autocomplete component's view class. It extends the {@link module:ui/search/text/searchtextview~SearchTextView} class\n * with a floating {@link #resultsView} that shows up when the user starts typing and hides when they blur\n * the component.\n */\nexport default class AutocompleteView<\n\tTQueryFieldView extends InputBase<HTMLInputElement | HTMLTextAreaElement>\n> extends SearchTextView<TQueryFieldView> {\n\t/**\n\t * The configuration of the autocomplete view.\n\t */\n\tprotected override _config: AutocompleteViewConfig<TQueryFieldView>;\n\n\tdeclare public resultsView: AutocompleteResultsView;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale, config: AutocompleteViewConfig<TQueryFieldView> ) {\n\t\tsuper( locale, config );\n\n\t\tthis._config = config;\n\n\t\tconst toPx = toUnit( 'px' );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck-autocomplete' ]\n\t\t\t}\n\t\t} );\n\n\t\tconst bindResultsView = this.resultsView.bindTemplate;\n\n\t\tthis.resultsView.set( 'isVisible', false );\n\t\tthis.resultsView.set( '_position', 's' );\n\t\tthis.resultsView.set( '_width', 0 );\n\n\t\tthis.resultsView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\tbindResultsView.if( 'isVisible', 'ck-hidden', value => !value ),\n\t\t\t\t\tbindResultsView.to( '_position', value => `ck-search__results_${ value }` )\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\twidth: bindResultsView.to( '_width', toPx )\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Update the visibility of the results view when the user focuses or blurs the component.\n\t\t// This is also integration for the `resetOnBlur` configuration.\n\t\tthis.focusTracker.on( 'change:isFocused', ( evt, name, isFocused ) => {\n\t\t\tthis._updateResultsVisibility();\n\n\t\t\tif ( isFocused ) {\n\t\t\t\t// Reset the scroll position of the results view whenever the autocomplete reopens.\n\t\t\t\tthis.resultsView.element!.scrollTop = 0;\n\t\t\t} else if ( config.resetOnBlur ) {\n\t\t\t\tthis.queryView.reset();\n\t\t\t}\n\t\t} );\n\n\t\t// Update the visibility of the results view when the user types in the query field.\n\t\t// This is an integration for `queryMinChars` configuration.\n\t\t// This is an integration for search results changing length and the #resultsView requiring to be repositioned.\n\t\tthis.on( 'search', () => {\n\t\t\tthis._updateResultsVisibility();\n\t\t\tthis._updateResultsViewWidthAndPosition();\n\t\t} );\n\n\t\t// Hide the results view when the user presses the ESC key.\n\t\tthis.keystrokes.set( 'esc', ( evt, cancel ) => {\n\t\t\t// Let the DOM event pass through if the focus is in the query view.\n\t\t\tif ( !this.resultsView.isVisible ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Focus the query view first and only then close the results view. Otherwise, if the focus\n\t\t\t// was in the results view, it will get lost.\n\t\t\tthis.queryView.focus();\n\t\t\tthis.resultsView.isVisible = false;\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Update the position of the results view when the user scrolls the page.\n\t\t// TODO: This needs to be debounced down the road.\n\t\tthis.listenTo( global.document, 'scroll', () => {\n\t\t\tthis._updateResultsViewWidthAndPosition();\n\t\t} );\n\n\t\t// Hide the results when the component becomes disabled.\n\t\tthis.on( 'change:isEnabled', () => {\n\t\t\tthis._updateResultsVisibility();\n\t\t} );\n\n\t\t// Update the value of the query field when the user selects a result.\n\t\tthis.filteredView.on<FilteredViewExecuteEvent>( 'execute', ( evt, { value } ) => {\n\t\t\t// Focus the query view first to avoid losing the focus.\n\t\t\tthis.focus();\n\n\t\t\t// Resetting the view will ensure that the #queryView will update its empty state correctly.\n\t\t\t// This prevents bugs related to dynamic labels or auto-grow when re-setting the same value\n\t\t\t// to #queryView.fieldView.value (which does not trigger empty state change) to an\n\t\t\t// #queryView.fieldView.element that has been changed by the user.\n\t\t\tthis.reset();\n\n\t\t\t// Update the value of the query field.\n\t\t\tthis.queryView.fieldView.value = this.queryView.fieldView.element!.value = value;\n\n\t\t\t// Finally, hide the results view. The focus has been moved earlier so this is safe.\n\t\t\tthis.resultsView.isVisible = false;\n\t\t} );\n\n\t\t// Update the position and width of the results view when it becomes visible.\n\t\tthis.resultsView.on( 'change:isVisible', () => {\n\t\t\tthis._updateResultsViewWidthAndPosition();\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the position of the results view on demand.\n\t */\n\tprivate _updateResultsViewWidthAndPosition() {\n\t\tif ( !this.resultsView.isVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.resultsView._width = new Rect( this.queryView.fieldView.element! ).width;\n\n\t\tconst optimalResultsPosition = AutocompleteView._getOptimalPosition( {\n\t\t\telement: this.resultsView.element!,\n\t\t\ttarget: this.queryView.element!,\n\t\t\tfitInViewport: true,\n\t\t\tpositions: AutocompleteView.defaultResultsPositions\n\t\t} );\n\n\t\t// _getOptimalPosition will return null if there is no optimal position found (e.g. target is off the viewport).\n\t\tthis.resultsView._position = optimalResultsPosition ? optimalResultsPosition.name : 's';\n\t}\n\n\t/**\n\t * Updates the visibility of the results view on demand.\n\t */\n\tprivate _updateResultsVisibility() {\n\t\tconst queryMinChars = typeof this._config.queryMinChars === 'undefined' ? 0 : this._config.queryMinChars;\n\t\tconst queryLength = this.queryView.fieldView.element!.value.length;\n\n\t\tthis.resultsView.isVisible = this.focusTracker.isFocused && this.isEnabled && queryLength >= queryMinChars;\n\t}\n\n\t/**\n\t * Positions for the autocomplete results view. Two positions are defined by default:\n\t * * `s` - below the search field,\n\t * * `n` - above the search field.\n\t */\n\tpublic static defaultResultsPositions: Array<PositioningFunction> = [\n\t\t( fieldRect => {\n\t\t\treturn {\n\t\t\t\ttop: fieldRect.bottom,\n\t\t\t\tleft: fieldRect.left,\n\t\t\t\tname: 's'\n\t\t\t};\n\t\t} ) as PositioningFunction,\n\t\t( ( fieldRect, resultsRect ) => {\n\t\t\treturn {\n\t\t\t\ttop: fieldRect.top - resultsRect.height,\n\t\t\t\tleft: fieldRect.left,\n\t\t\t\tname: 'n'\n\t\t\t};\n\t\t} ) as PositioningFunction\n\t];\n\n\t/**\n\t * A function used to calculate the optimal position for the dropdown panel.\n\t */\n\tprivate static _getOptimalPosition = getOptimalPosition;\n}\n\n/**\n * An interface describing additional properties of the floating search results view used by the autocomplete plugin.\n */\nexport interface AutocompleteResultsView extends SearchResultsView {\n\n\t/**\n\t * Controls the visibility of the results view.\n\t *\n\t * @observable\n\t */\n\tisVisible: boolean;\n\n\t/**\n\t * Controls the position (CSS class suffix) of the results view.\n\t *\n\t * @internal\n\t*/\n\t_position?: string;\n\n\t/**\n\t * The observable property determining the CSS width of the results view.\n\t *\n\t * @internal\n\t */\n\t_width: number;\n}\n\nexport interface AutocompleteViewConfig<\n\tTConfigInputCreator extends InputBase<HTMLInputElement | HTMLTextAreaElement>\n> extends SearchTextViewConfig<TConfigInputCreator> {\n\n\t/**\n\t * When set `true`, the query view will be reset when the autocomplete view loses focus.\n\t */\n\tresetOnBlur?: boolean;\n\n\t/**\n\t * Minimum number of characters that need to be typed before the search is performed.\n\t *\n\t * @default 0\n\t */\n\tqueryMinChars?: number;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/highlightedtext/highlightedtextview\n */\n\nimport View from '../view.js';\nimport { escape } from 'lodash-es';\n\nimport '../../theme/components/highlightedtext/highlightedtext.css';\n\n/**\n * A class representing a view that displays a text which subset can be highlighted using the\n * {@link #highlightText} method.\n */\nexport default class HighlightedTextView extends View {\n\t/**\n\t * The text that can be highlighted using the {@link #highlightText} method.\n\t *\n\t * **Note:** When this property changes, the previous highlighting is removed.\n\t *\n\t * @observable\n\t */\n\tdeclare public text: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.set( 'text', undefined );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck', 'ck-highlighted-text' ]\n\t\t\t}\n\t\t} );\n\n\t\tthis.on( 'render', () => {\n\t\t\t// Classic setTemplate binding for #text will not work because highlightText() replaces the\n\t\t\t// pre-rendered DOM text node new a new one (and <mark> elements).\n\t\t\tthis.on( 'change:text', () => {\n\t\t\t\tthis._updateInnerHTML( this.text );\n\t\t\t} );\n\n\t\t\tthis._updateInnerHTML( this.text );\n\t\t} );\n\t}\n\n\t/**\n\t * Highlights view's {@link #text} according to the specified `RegExp`. If the passed RegExp is `null`, the\n\t * highlighting is removed\n\t *\n\t * @param regExp\n\t */\n\tpublic highlightText( regExp: RegExp | null ): void {\n\t\tthis._updateInnerHTML( markText( this.text || '', regExp ) );\n\t}\n\n\t/**\n\t * Updates element's `innerHTML` with the passed content.\n\t */\n\tprivate _updateInnerHTML( newInnerHTML: string | undefined ) {\n\t\tthis.element!.innerHTML = newInnerHTML || '';\n\t}\n}\n\n/**\n * Replaces `regExp` occurrences with `<mark>` tags in a text.\n *\n * @param text A text to get marked.\n * @param regExp An optional `RegExp`. If not passed, this is a pass-through function.\n * @returns A text with `RegExp` occurrences marked by `<mark>`.\n */\nfunction markText( text: string, regExp?: RegExp | null ) {\n\tif ( !regExp ) {\n\t\treturn escape( text );\n\t}\n\n\tconst textParts: Array<{ text: string; isMatch: boolean }> = [];\n\tlet lastMatchEnd = 0;\n\tlet matchInfo = regExp.exec( text );\n\n\t// Iterate over all matches and create an array of text parts. The idea is to mark which parts are query matches\n\t// so that later on they can be highlighted.\n\twhile ( matchInfo !== null ) {\n\t\tconst curMatchStart = matchInfo.index;\n\t\t// Detect if there was something between last match and this one.\n\t\tif ( curMatchStart !== lastMatchEnd ) {\n\t\t\ttextParts.push( {\n\t\t\t\ttext: text.substring( lastMatchEnd, curMatchStart ),\n\t\t\t\tisMatch: false\n\t\t\t} );\n\t\t}\n\n\t\ttextParts.push( {\n\t\t\ttext: matchInfo[ 0 ],\n\t\t\tisMatch: true\n\t\t} );\n\n\t\tlastMatchEnd = regExp.lastIndex;\n\t\tmatchInfo = regExp.exec( text );\n\t}\n\n\t// Your match might not be the last part of a string. Be sure to add any plain text following the last match.\n\tif ( lastMatchEnd !== text.length ) {\n\t\ttextParts.push( {\n\t\t\ttext: text.substring( lastMatchEnd ),\n\t\t\tisMatch: false\n\t\t} );\n\t}\n\n\tconst outputHtml = textParts\n\t\t// The entire text should be escaped.\n\t\t.map( part => {\n\t\t\tpart.text = escape( part.text );\n\t\t\treturn part;\n\t\t} )\n\t\t// Only matched text should be wrapped with HTML mark element.\n\t\t.map( part => part.isMatch ? `<mark>${ part.text }</mark>` : part.text )\n\t\t.join( '' );\n\n\treturn outputHtml;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/highlightedtext/buttonlabelwithhighlightview\n */\n\nimport type ButtonLabel from '../button/buttonlabel.js';\nimport HighlightedTextView from './highlightedtextview.js';\n\n/**\n * A button label view that can highlight a text fragment.\n */\nexport default class ButtonLabelWithHighlightView extends HighlightedTextView implements ButtonLabel {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public style: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public text: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public id: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.set( {\n\t\t\tstyle: undefined,\n\t\t\ttext: undefined,\n\t\t\tid: undefined\n\t\t} );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-button__label'\n\t\t\t\t],\n\t\t\t\tstyle: bind.to( 'style' ),\n\t\t\t\tid: bind.to( 'id' )\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/highlightedtext/labelwithhighlightview\n */\n\nimport HighlightedTextView from './highlightedtextview.js';\nimport type LabelView from '../label/labelview.js';\nimport { uid } from '@ckeditor/ckeditor5-utils';\n\n/**\n * A label view that can highlight a text fragment.\n */\nexport default class LabelWithHighlightView extends HighlightedTextView implements LabelView {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly id: string;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public for: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.set( 'for', undefined );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.id = `ck-editor__label_${ uid() }`;\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-label'\n\t\t\t\t],\n\t\t\t\tid: this.id,\n\t\t\t\tfor: bind.to( 'for' )\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/spinner/spinnerview\n */\n\nimport View from '../view.js';\n\nimport '../../theme/components/spinner/spinner.css';\n\n/**\n * The spinner view class.\n */\nexport default class SpinnerView extends View {\n\t/**\n\t * Controls whether the spinner is visible.\n\t *\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tthis.set( 'isVisible', false );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-spinner-container',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [ {\n\t\t\t\ttag: 'span',\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: [ 'ck', 'ck-spinner' ]\n\t\t\t\t}\n\t\t\t} ]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/toolbar/balloon/balloontoolbar\n */\n\nimport ContextualBalloon from '../../panel/balloon/contextualballoon.js';\nimport ToolbarView, { type ToolbarViewGroupedItemsUpdateEvent } from '../toolbarview.js';\nimport BalloonPanelView from '../../panel/balloon/balloonpanelview.js';\nimport normalizeToolbarConfig from '../normalizetoolbarconfig.js';\n\nimport type {\n\tEditorUIReadyEvent,\n\tEditorUIUpdateEvent\n} from '../../editorui/editorui.js';\n\nimport {\n\tPlugin,\n\ttype Editor,\n\ttype EditorReadyEvent\n} from '@ckeditor/ckeditor5-core';\n\nimport {\n\tFocusTracker,\n\tRect,\n\tResizeObserver,\n\tenv,\n\tglobal,\n\ttoUnit,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport {\n\tObserver,\n\ttype DocumentSelection,\n\ttype DocumentSelectionChangeRangeEvent,\n\ttype Schema\n} from '@ckeditor/ckeditor5-engine';\n\nimport { debounce, type DebouncedFunc } from 'lodash-es';\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n/**\n * The contextual toolbar.\n *\n * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */\nexport default class BalloonToolbar extends Plugin {\n\t/**\n\t * The toolbar view displayed in the balloon.\n\t */\n\tpublic readonly toolbarView: ToolbarView;\n\n\t/**\n\t * Tracks the focus of the {@link module:ui/editorui/editorui~EditorUI#getEditableElement editable element}\n\t * and the {@link #toolbarView}. When both are blurred then the toolbar should hide.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * A cached and normalized `config.balloonToolbar` object.\n\t */\n\tprivate _balloonConfig: ReturnType<typeof normalizeToolbarConfig>;\n\n\t/**\n\t * An instance of the resize observer that allows to respond to changes in editable's geometry\n\t * so the toolbar can stay within its boundaries (and group toolbar items that do not fit).\n\t *\n\t * **Note**: Used only when `shouldNotGroupWhenFull` was **not** set in the\n\t * {@link module:core/editor/editorconfig~EditorConfig#balloonToolbar configuration}.\n\t *\n\t * **Note:** Created in {@link #init}.\n\t */\n\tprivate _resizeObserver: ResizeObserver | null = null;\n\n\t/**\n\t * The contextual balloon plugin instance.\n\t */\n\tprivate readonly _balloon: ContextualBalloon;\n\n\t/**\n\t * Fires `_selectionChangeDebounced` event using `lodash#debounce`.\n\t *\n\t * This event is an internal plugin event which is fired 200 ms after model selection last change.\n\t * This is to makes easy test debounced action without need to use `setTimeout`.\n\t *\n\t * This function is stored as a plugin property to make possible to cancel\n\t * trailing debounced invocation on destroy.\n\t */\n\tprivate readonly _fireSelectionChangeDebounced: DebouncedFunc<() => void>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'BalloonToolbar' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._balloonConfig = normalizeToolbarConfig( editor.config.get( 'balloonToolbar' ) );\n\t\tthis.toolbarView = this._createToolbarView();\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t// Track focusable elements in the toolbar and the editable elements.\n\t\tthis._trackFocusableEditableElements();\n\t\tthis.focusTracker.add( this.toolbarView );\n\n\t\t// Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n\t\teditor.ui.addToolbar( this.toolbarView, {\n\t\t\tbeforeFocus: () => this.show( true ),\n\t\t\tafterBlur: () => this.hide(),\n\t\t\tisContextual: true\n\t\t} );\n\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\t\tthis._fireSelectionChangeDebounced = debounce( () => this.fire( '_selectionChangeDebounced' ), 200 );\n\n\t\t// The appearance of the BalloonToolbar method is event–driven.\n\t\t// It is possible to stop the #show event and this prevent the toolbar from showing up.\n\t\tthis.decorate( 'show' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\n\t\t// Show/hide the toolbar on editable focus/blur.\n\t\tthis.listenTo<ObservableChangeEvent<boolean>>( this.focusTracker, 'change:isFocused', ( evt, name, isFocused ) => {\n\t\t\tconst isToolbarVisible = this._balloon.visibleView === this.toolbarView;\n\n\t\t\tif ( !isFocused && isToolbarVisible ) {\n\t\t\t\tthis.hide();\n\t\t\t} else if ( isFocused ) {\n\t\t\t\tthis.show();\n\t\t\t}\n\t\t} );\n\n\t\t// Hide the toolbar when the selection is changed by a direct change or has changed to collapsed.\n\t\tthis.listenTo<DocumentSelectionChangeRangeEvent>( selection, 'change:range', ( evt, data ) => {\n\t\t\tif ( data.directChange || selection.isCollapsed ) {\n\t\t\t\tthis.hide();\n\t\t\t}\n\n\t\t\t// Fire internal `_selectionChangeDebounced` event to use it for showing\n\t\t\t// the toolbar after the selection stops changing.\n\t\t\tthis._fireSelectionChangeDebounced();\n\t\t} );\n\n\t\t// Show the toolbar when the selection stops changing.\n\t\tthis.listenTo( this, '_selectionChangeDebounced', () => {\n\t\t\tif ( this.editor.editing.view.document.isFocused ) {\n\t\t\t\tthis.show();\n\t\t\t}\n\t\t} );\n\n\t\tif ( !this._balloonConfig.shouldNotGroupWhenFull ) {\n\t\t\tthis.listenTo<EditorReadyEvent>( editor, 'ready', () => {\n\t\t\t\tconst editableElement = editor.ui.view.editable.element!;\n\n\t\t\t\t// Set #toolbarView's max-width on the initialization and update it on the editable resize.\n\t\t\t\tthis._resizeObserver = new ResizeObserver( editableElement, entry => {\n\t\t\t\t\t// The max-width equals 90% of the editable's width for the best user experience.\n\t\t\t\t\t// The value keeps the balloon very close to the boundaries of the editable and limits the cases\n\t\t\t\t\t// when the balloon juts out from the editable element it belongs to.\n\t\t\t\t\tthis.toolbarView.maxWidth = toPx( entry.contentRect.width * .9 );\n\t\t\t\t} );\n\t\t\t} );\n\t\t}\n\n\t\t// Listen to the toolbar view and whenever it changes its geometry due to some items being\n\t\t// grouped or ungrouped, update the position of the balloon because a shorter/longer toolbar\n\t\t// means the balloon could be pointing at the wrong place. Once updated, the balloon will point\n\t\t// at the right selection in the content again.\n\t\t// https://github.com/ckeditor/ckeditor5/issues/6444\n\t\tthis.listenTo<ToolbarViewGroupedItemsUpdateEvent>( this.toolbarView, 'groupedItemsUpdate', () => {\n\t\t\tthis._updatePosition();\n\t\t} );\n\n\t\t// Creates toolbar components based on given configuration.\n\t\t// This needs to be done when all plugins are ready.\n\t\teditor.ui.once<EditorUIReadyEvent>( 'ready', () => {\n\t\t\tthis.toolbarView.fillFromConfig( this._balloonConfig, this.editor.ui.componentFactory );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the toolbar view instance.\n\t */\n\tprivate _createToolbarView() {\n\t\tconst t = this.editor.locale.t;\n\t\tconst shouldGroupWhenFull = !this._balloonConfig.shouldNotGroupWhenFull;\n\t\tconst toolbarView = new ToolbarView( this.editor.locale, {\n\t\t\tshouldGroupWhenFull,\n\t\t\tisFloating: true\n\t\t} );\n\n\t\ttoolbarView.ariaLabel = t( 'Editor contextual toolbar' );\n\t\ttoolbarView.render();\n\n\t\treturn toolbarView;\n\t}\n\n\t/**\n\t * Shows the toolbar and attaches it to the selection.\n\t *\n\t * Fires {@link #event:show} event which can be stopped to prevent the toolbar from showing up.\n\t *\n\t * @param showForCollapsedSelection When set `true`, the toolbar will show despite collapsed selection in the\n\t * editing view.\n\t */\n\tpublic show( showForCollapsedSelection: boolean = false ): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst schema = editor.model.schema;\n\n\t\t// Do not add the toolbar to the balloon stack twice.\n\t\tif ( this._balloon.hasView( this.toolbarView ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not show the toolbar when the selection is collapsed.\n\t\tif ( selection.isCollapsed && !showForCollapsedSelection ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not show the toolbar when there is more than one range in the selection and they fully contain selectable elements.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/6443.\n\t\tif ( selectionContainsOnlyMultipleSelectables( selection, schema ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not show the toolbar when all components inside are disabled\n\t\t// see https://github.com/ckeditor/ckeditor5-ui/issues/269.\n\t\tif ( Array.from( this.toolbarView.items ).every( ( item: any ) => item.isEnabled !== undefined && !item.isEnabled ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Update the toolbar position when the editor ui should be refreshed.\n\t\tthis.listenTo<EditorUIUpdateEvent>( this.editor.ui, 'update', () => {\n\t\t\tthis._updatePosition();\n\t\t} );\n\n\t\t// Add the toolbar to the common editor contextual balloon.\n\t\tthis._balloon.add( {\n\t\t\tview: this.toolbarView,\n\t\t\tposition: this._getBalloonPositionData(),\n\t\t\tballoonClassName: 'ck-toolbar-container'\n\t\t} );\n\t}\n\n\t/**\n\t * Hides the toolbar.\n\t */\n\tpublic hide(): void {\n\t\tif ( this._balloon.hasView( this.toolbarView ) ) {\n\t\t\tthis.stopListening( this.editor.ui, 'update' );\n\t\t\tthis._balloon.remove( this.toolbarView );\n\t\t}\n\t}\n\n\t/**\n\t * Add or remove editable elements to the focus tracker. It watches added and removed roots\n\t * and adds or removes their editable elements to the focus tracker.\n\t */\n\tprivate _trackFocusableEditableElements() {\n\t\tconst { editor, focusTracker } = this;\n\t\tconst { editing } = editor;\n\n\t\tediting.view.addObserver( class TrackEditableElements extends Observer {\n\t\t\t/**\n\t\t\t * @inheritDoc\n\t\t\t */\n\t\t\tpublic observe( domElement: HTMLElement ) {\n\t\t\t\tfocusTracker.add( domElement );\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * @inheritDoc\n\t\t\t */\n\t\t\tpublic stopObserving( domElement: HTMLElement ) {\n\t\t\t\tfocusTracker.remove( domElement );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns positioning options for the {@link #_balloon}. They control the way balloon is attached\n\t * to the selection.\n\t */\n\tprivate _getBalloonPositionData() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst viewSelection = viewDocument.selection;\n\n\t\t// Get direction of the selection.\n\t\tconst isBackward = viewDocument.selection.isBackward;\n\n\t\treturn {\n\t\t\t// Because the target for BalloonPanelView is a Rect (not DOMRange), it's geometry will stay fixed\n\t\t\t// as the window scrolls. To let the BalloonPanelView follow such Rect, is must be continuously\n\t\t\t// computed and hence, the target is defined as a function instead of a static value.\n\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/195\n\t\t\ttarget: () => {\n\t\t\t\tconst range = isBackward ? viewSelection.getFirstRange() : viewSelection.getLastRange();\n\t\t\t\tconst rangeRects = Rect.getDomRangeRects( view.domConverter.viewRangeToDom( range! ) );\n\n\t\t\t\t// Select the proper range rect depending on the direction of the selection.\n\t\t\t\tif ( isBackward ) {\n\t\t\t\t\treturn rangeRects[ 0 ];\n\t\t\t\t} else {\n\t\t\t\t\t// Ditch the zero-width \"orphan\" rect in the next line for the forward selection if there's\n\t\t\t\t\t// another one preceding it. It is not rendered as a selection by the web browser anyway.\n\t\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/308\n\t\t\t\t\tif ( rangeRects.length > 1 && rangeRects[ rangeRects.length - 1 ].width === 0 ) {\n\t\t\t\t\t\trangeRects.pop();\n\t\t\t\t\t}\n\n\t\t\t\t\treturn rangeRects[ rangeRects.length - 1 ];\n\t\t\t\t}\n\t\t\t},\n\t\t\tpositions: this._getBalloonPositions( isBackward )\n\t\t};\n\t}\n\n\t/**\n\t * Updates the position of the {@link #_balloon} to make up for changes:\n\t *\n\t * * in the geometry of the selection it is attached to (e.g. the selection moved in the viewport or expanded or shrunk),\n\t * * or the geometry of the balloon toolbar itself (e.g. the toolbar has grouped or ungrouped some items and it is shorter or longer).\n\t */\n\tprivate _updatePosition() {\n\t\tthis._balloon.updatePosition( this._getBalloonPositionData() );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.stopListening();\n\t\tthis._fireSelectionChangeDebounced.cancel();\n\t\tthis.toolbarView.destroy();\n\t\tthis.focusTracker.destroy();\n\n\t\tif ( this._resizeObserver ) {\n\t\t\tthis._resizeObserver.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Returns toolbar positions for the given direction of the selection.\n\t */\n\tprivate _getBalloonPositions( isBackward: boolean ) {\n\t\tconst isSafariIniOS = env.isSafari && env.isiOS;\n\n\t\t// https://github.com/ckeditor/ckeditor5/issues/7707\n\t\tconst positions = isSafariIniOS ? BalloonPanelView.generatePositions( {\n\t\t\t// 20px when zoomed out. Less then 20px when zoomed in; the \"radius\" of the native selection handle gets\n\t\t\t// smaller as the user zooms in. No less than the default v-offset, though.\n\t\t\theightOffset: Math.max(\n\t\t\t\tBalloonPanelView.arrowHeightOffset,\n\t\t\t\tMath.round( 20 / global.window.visualViewport!.scale )\n\t\t\t)\n\t\t} ) : BalloonPanelView.defaultPositions;\n\n\t\treturn isBackward ? [\n\t\t\tpositions.northWestArrowSouth,\n\t\t\tpositions.northWestArrowSouthWest,\n\t\t\tpositions.northWestArrowSouthEast,\n\t\t\tpositions.northWestArrowSouthMiddleEast,\n\t\t\tpositions.northWestArrowSouthMiddleWest,\n\t\t\tpositions.southWestArrowNorth,\n\t\t\tpositions.southWestArrowNorthWest,\n\t\t\tpositions.southWestArrowNorthEast,\n\t\t\tpositions.southWestArrowNorthMiddleWest,\n\t\t\tpositions.southWestArrowNorthMiddleEast\n\t\t] : [\n\t\t\tpositions.southEastArrowNorth,\n\t\t\tpositions.southEastArrowNorthEast,\n\t\t\tpositions.southEastArrowNorthWest,\n\t\t\tpositions.southEastArrowNorthMiddleEast,\n\t\t\tpositions.southEastArrowNorthMiddleWest,\n\t\t\tpositions.northEastArrowSouth,\n\t\t\tpositions.northEastArrowSouthEast,\n\t\t\tpositions.northEastArrowSouthWest,\n\t\t\tpositions.northEastArrowSouthMiddleEast,\n\t\t\tpositions.northEastArrowSouthMiddleWest\n\t\t];\n\t}\n}\n\n/**\n * Returns \"true\" when the selection has multiple ranges and each range contains a selectable element\n * and nothing else.\n */\nfunction selectionContainsOnlyMultipleSelectables( selection: DocumentSelection, schema: Schema ) {\n\t// It doesn't contain multiple objects if there is only one range.\n\tif ( selection.rangeCount === 1 ) {\n\t\treturn false;\n\t}\n\n\treturn [ ...selection.getRanges() ].every( range => {\n\t\tconst element = range.getContainedElement();\n\n\t\treturn element && schema.isSelectable( element );\n\t} );\n}\n\n/**\n * This event is fired just before the toolbar shows up. Stopping this event will prevent this.\n *\n * @eventName ~BalloonToolbar#show\n */\nexport type BalloonToolbarShowEvent = {\n\tname: 'show';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/toolbar/block/blockbuttonview\n */\n\nimport ButtonView from '../../button/buttonview.js';\n\nimport { toUnit, type Locale } from '@ckeditor/ckeditor5-utils';\n\nimport '../../../theme/components/toolbar/blocktoolbar.css';\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n/**\n * The block button view class.\n *\n * This view represents a button attached next to block element where the selection is anchored.\n *\n * See {@link module:ui/toolbar/block/blocktoolbar~BlockToolbar}.\n */\nexport default class BlockButtonView extends ButtonView {\n\t/**\n\t * Top offset.\n\t *\n\t * @observable\n\t */\n\tdeclare public top: number;\n\n\t/**\n\t * Left offset.\n\t *\n\t * @observable\n\t */\n\tdeclare public left: number;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t// Hide button on init.\n\t\tthis.isVisible = false;\n\n\t\tthis.isToggleable = true;\n\n\t\tthis.set( 'top', 0 );\n\t\tthis.set( 'left', 0 );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-block-toolbar-button',\n\t\t\t\tstyle: {\n\t\t\t\t\ttop: bind.to( 'top', val => toPx( val ) ),\n\t\t\t\t\tleft: bind.to( 'left', val => toPx( val ) )\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/toolbar/block/blocktoolbar\n */\n\n/* global window */\n\nimport {\n\tPlugin,\n\ttype Editor\n} from '@ckeditor/ckeditor5-core';\n\nimport {\n\ttype EventInfo,\n\tgetAncestors,\n\tglobal,\n\tRect,\n\tResizeObserver,\n\ttoUnit,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport type { DocumentSelectionChangeRangeEvent } from '@ckeditor/ckeditor5-engine';\n\nimport BlockButtonView from './blockbuttonview.js';\nimport BalloonPanelView from '../../panel/balloon/balloonpanelview.js';\nimport ToolbarView, { NESTED_TOOLBAR_ICONS } from '../toolbarview.js';\nimport clickOutsideHandler from '../../bindings/clickoutsidehandler.js';\nimport normalizeToolbarConfig from '../normalizetoolbarconfig.js';\n\nimport type ButtonView from '../../button/buttonview.js';\nimport type { ButtonExecuteEvent } from '../../button/button.js';\nimport type { EditorUIReadyEvent, EditorUIUpdateEvent } from '../../editorui/editorui.js';\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n/**\n * The block toolbar plugin.\n *\n * This plugin provides a button positioned next to the block of content where the selection is anchored.\n * Upon clicking the button, a dropdown providing access to editor features shows up, as configured in\n * {@link module:core/editor/editorconfig~EditorConfig#blockToolbar}.\n *\n * By default, the button is displayed next to all elements marked in {@link module:engine/model/schema~Schema}\n * as `$block` for which the toolbar provides at least one option.\n *\n * By default, the button is attached so its right boundary is touching the\n * {@link module:engine/view/editableelement~EditableElement}:\n *\n * ```\n *  __ |\n * |  ||  This is a block of content that the\n *  ¯¯ |  button is attached to. This is a\n *     |  block of content that the button is\n *     |  attached to.\n * ```\n *\n * The position of the button can be adjusted using the CSS `transform` property:\n *\n * ```css\n * .ck-block-toolbar-button {\n * \ttransform: translateX( -10px );\n * }\n * ```\n *\n * ```\n *  __   |\n * |  |  |  This is a block of content that the\n *  ¯¯   |  button is attached to. This is a\n *       |  block of content that the button is\n *       |  attached to.\n * ```\n *\n * **Note**: If you plan to run the editor in a right–to–left (RTL) language, keep in mind the button\n * will be attached to the **right** boundary of the editable area. In that case, make sure the\n * CSS position adjustment works properly by adding the following styles:\n *\n * ```css\n * .ck[dir=\"rtl\"] .ck-block-toolbar-button {\n * \ttransform: translateX( 10px );\n * }\n * ```\n */\nexport default class BlockToolbar extends Plugin {\n\t/**\n\t * The toolbar view.\n\t */\n\tpublic readonly toolbarView: ToolbarView;\n\n\t/**\n\t * The balloon panel view, containing the {@link #toolbarView}.\n\t */\n\tpublic readonly panelView: BalloonPanelView;\n\n\t/**\n\t * The button view that opens the {@link #toolbarView}.\n\t */\n\tpublic readonly buttonView: BlockButtonView;\n\n\t/**\n\t * An instance of the resize observer that allows to respond to changes in editable's geometry\n\t * so the toolbar can stay within its boundaries (and group toolbar items that do not fit).\n\t *\n\t * **Note**: Used only when `shouldNotGroupWhenFull` was **not** set in the\n\t * {@link module:core/editor/editorconfig~EditorConfig#blockToolbar configuration}.\n\t */\n\tprivate _resizeObserver: ResizeObserver | null = null;\n\n\t/**\n\t * A cached and normalized `config.blockToolbar` object.\n\t */\n\tprivate _blockToolbarConfig: ReturnType<typeof normalizeToolbarConfig>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'BlockToolbar' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._blockToolbarConfig = normalizeToolbarConfig( this.editor.config.get( 'blockToolbar' ) );\n\t\tthis.toolbarView = this._createToolbarView();\n\t\tthis.panelView = this._createPanelView();\n\t\tthis.buttonView = this._createButtonView();\n\n\t\t// Close the #panelView upon clicking outside of the plugin UI.\n\t\tclickOutsideHandler( {\n\t\t\temitter: this.panelView,\n\t\t\tcontextElements: [ this.panelView.element!, this.buttonView.element! ],\n\t\t\tactivator: () => this.panelView.isVisible,\n\t\t\tcallback: () => this._hidePanel()\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\tconst editBlockText = t( 'Click to edit block' );\n\t\tconst dragToMoveText = t( 'Drag to move' );\n\t\tconst editBlockLabel = t( 'Edit block' );\n\n\t\tconst isDragDropBlockToolbarPluginLoaded = editor.plugins.has( 'DragDropBlockToolbar' );\n\t\tconst label = isDragDropBlockToolbarPluginLoaded ? `${ editBlockText }\\n${ dragToMoveText }` : editBlockLabel;\n\n\t\tthis.buttonView.label = label;\n\n\t\tif ( isDragDropBlockToolbarPluginLoaded ) {\n\t\t\tthis.buttonView.element!.dataset.ckeTooltipClass = 'ck-tooltip_multi-line';\n\t\t}\n\n\t\t// Hides panel on a direct selection change.\n\t\tthis.listenTo<DocumentSelectionChangeRangeEvent>( editor.model.document.selection, 'change:range', ( evt, data ) => {\n\t\t\tif ( data.directChange ) {\n\t\t\t\tthis._hidePanel();\n\t\t\t}\n\t\t} );\n\n\t\tthis.listenTo<EditorUIUpdateEvent>( editor.ui, 'update', () => this._updateButton() );\n\t\t// `low` priority is used because of https://github.com/ckeditor/ckeditor5-core/issues/133.\n\t\tthis.listenTo<ObservableChangeEvent>( editor, 'change:isReadOnly', () => this._updateButton(), { priority: 'low' } );\n\t\tthis.listenTo<ObservableChangeEvent>( editor.ui.focusTracker, 'change:isFocused', () => this._updateButton() );\n\n\t\t// Reposition button on resize.\n\t\tthis.listenTo<ObservableChangeEvent<boolean>>( this.buttonView, 'change:isVisible', ( evt, name, isVisible ) => {\n\t\t\tif ( isVisible ) {\n\t\t\t\t// Keep correct position of button and panel on window#resize.\n\t\t\t\tthis.buttonView.listenTo( window, 'resize', () => this._updateButton() );\n\t\t\t} else {\n\t\t\t\t// Stop repositioning button when is hidden.\n\t\t\t\tthis.buttonView.stopListening( window, 'resize' );\n\n\t\t\t\t// Hide the panel when the button disappears.\n\t\t\t\tthis._hidePanel();\n\t\t\t}\n\t\t} );\n\n\t\t// Reposition button on scroll.\n\t\tthis._repositionButtonOnScroll();\n\n\t\t// Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n\t\teditor.ui.addToolbar( this.toolbarView, {\n\t\t\tbeforeFocus: () => this._showPanel(),\n\t\t\tafterBlur: () => this._hidePanel()\n\t\t} );\n\n\t\t// Fills the toolbar with its items based on the configuration.\n\t\t// This needs to be done after all plugins are ready.\n\t\teditor.ui.once<EditorUIReadyEvent>( 'ready', () => {\n\t\t\tthis.toolbarView.fillFromConfig( this._blockToolbarConfig, this.editor.ui.componentFactory );\n\n\t\t\t// Hide panel before executing each button in the panel.\n\t\t\tfor ( const item of this.toolbarView.items ) {\n\t\t\t\titem.on<ButtonExecuteEvent>( 'execute', () => this._hidePanel( true ), { priority: 'high' } );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n\t\tthis.panelView.destroy();\n\t\tthis.buttonView.destroy();\n\t\tthis.toolbarView.destroy();\n\n\t\tif ( this._resizeObserver ) {\n\t\t\tthis._resizeObserver.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Creates the {@link #toolbarView}.\n\t */\n\tprivate _createToolbarView(): ToolbarView {\n\t\tconst t = this.editor.locale.t;\n\t\tconst shouldGroupWhenFull = !this._blockToolbarConfig.shouldNotGroupWhenFull;\n\t\tconst toolbarView = new ToolbarView( this.editor.locale, {\n\t\t\tshouldGroupWhenFull,\n\t\t\tisFloating: true\n\t\t} );\n\n\t\ttoolbarView.ariaLabel = t( 'Editor block content toolbar' );\n\n\t\treturn toolbarView;\n\t}\n\n\t/**\n\t * Creates the {@link #panelView}.\n\t */\n\tprivate _createPanelView(): BalloonPanelView {\n\t\tconst editor = this.editor;\n\t\tconst panelView = new BalloonPanelView( editor.locale );\n\n\t\tpanelView.content.add( this.toolbarView );\n\t\tpanelView.class = 'ck-toolbar-container';\n\t\teditor.ui.view.body.add( panelView );\n\n\t\t// Close #panelView on `Esc` press.\n\t\tthis.toolbarView.keystrokes.set( 'Esc', ( evt, cancel ) => {\n\t\t\tthis._hidePanel( true );\n\t\t\tcancel();\n\t\t} );\n\n\t\treturn panelView;\n\t}\n\n\t/**\n\t * Creates the {@link #buttonView}.\n\t */\n\tprivate _createButtonView(): BlockButtonView {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst buttonView = new BlockButtonView( editor.locale );\n\t\tconst iconFromConfig = this._blockToolbarConfig.icon;\n\n\t\tconst icon = NESTED_TOOLBAR_ICONS[ iconFromConfig! ] || iconFromConfig || NESTED_TOOLBAR_ICONS.dragIndicator;\n\n\t\tbuttonView.set( {\n\t\t\tlabel: t( 'Edit block' ),\n\t\t\ticon,\n\t\t\twithText: false\n\t\t} );\n\n\t\t// Bind the panelView observable properties to the buttonView.\n\t\tbuttonView.bind( 'isOn' ).to( this.panelView, 'isVisible' );\n\t\tbuttonView.bind( 'tooltip' ).to( this.panelView, 'isVisible', isVisible => !isVisible );\n\n\t\t// Toggle the panelView upon buttonView#execute.\n\t\tthis.listenTo<ButtonExecuteEvent>( buttonView, 'execute', () => {\n\t\t\tif ( !this.panelView.isVisible ) {\n\t\t\t\tthis._showPanel();\n\t\t\t} else {\n\t\t\t\tthis._hidePanel( true );\n\t\t\t}\n\t\t} );\n\n\t\t// Hide the panelView when the buttonView is disabled. `isEnabled` flag might be changed when\n\t\t// user scrolls the viewport and the button is no longer visible. In such case, the panel should be hidden\n\t\t// otherwise it will be displayed in the wrong place.\n\t\tthis.listenTo<ObservableChangeEvent<boolean>>( buttonView, 'change:isEnabled', ( evt, name, isEnabled ) => {\n\t\t\tif ( !isEnabled && this.panelView.isVisible ) {\n\t\t\t\tthis._hidePanel( false );\n\t\t\t}\n\t\t} );\n\n\t\teditor.ui.view.body.add( buttonView );\n\n\t\treturn buttonView;\n\t}\n\n\t/**\n\t * Shows or hides the button.\n\t * When all the conditions for displaying the button are matched, it shows the button. Hides otherwise.\n\t */\n\tprivate _updateButton() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\n\t\t// Hides the button when the editor is not focused.\n\t\tif ( !editor.ui.focusTracker.isFocused ) {\n\t\t\tthis._hideButton();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Hides the button when the selection is in non-editable place.\n\t\tif ( !editor.model.canEditAt( editor.model.document.selection ) ) {\n\t\t\tthis._hideButton();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the first selected block, button will be attached to this element.\n\t\tconst modelTarget = Array.from( model.document.selection.getSelectedBlocks() )[ 0 ];\n\n\t\t// Hides the button when there is no enabled item in toolbar for the current block element.\n\t\tif ( !modelTarget || Array.from( this.toolbarView.items ).every( ( item: any ) => !item.isEnabled ) ) {\n\t\t\tthis._hideButton();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Get DOM target element.\n\t\tconst domTarget = view.domConverter.mapViewToDom( editor.editing.mapper.toViewElement( modelTarget )! );\n\n\t\t// Show block button.\n\t\tthis.buttonView.isVisible = true;\n\n\t\t// Make sure that the block toolbar panel is resized properly.\n\t\tthis._setupToolbarResize();\n\n\t\t// Attach block button to target DOM element.\n\t\tthis._attachButtonToElement( domTarget as any );\n\n\t\t// When panel is opened then refresh it position to be properly aligned with block button.\n\t\tif ( this.panelView.isVisible ) {\n\t\t\tthis._showPanel();\n\t\t}\n\t}\n\n\t/**\n\t * Hides the button.\n\t */\n\tprivate _hideButton() {\n\t\tthis.buttonView.isVisible = false;\n\t}\n\n\t/**\n\t * Shows the {@link #toolbarView} attached to the {@link #buttonView}.\n\t * If the toolbar is already visible, then it simply repositions it.\n\t */\n\tprivate _showPanel() {\n\t\t// Usually, the only way to show the toolbar is by pressing the block button. It makes it impossible for\n\t\t// the toolbar to show up when the button is invisible (feature does not make sense for the selection then).\n\t\t// The toolbar navigation using Alt+F10 does not access the button but shows the panel directly using this method.\n\t\t// So we need to check whether this is possible first.\n\t\tif ( !this.buttonView.isVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst wasVisible = this.panelView.isVisible;\n\n\t\t// So here's the thing: If there was no initial panelView#show() or these two were in different order, the toolbar\n\t\t// positioning will break in RTL editors. Weird, right? What you show know is that the toolbar\n\t\t// grouping works thanks to:\n\t\t//\n\t\t// * the ResizeObserver, which kicks in as soon as the toolbar shows up in DOM (becomes visible again).\n\t\t// * the observable ToolbarView#maxWidth, which triggers re-grouping when changed.\n\t\t//\n\t\t// Here are the possible scenarios:\n\t\t//\n\t\t// 1. (WRONG ❌) If the #maxWidth is set when the toolbar is invisible, it won't affect item grouping (no DOMRects, no grouping).\n\t\t//    Then, when panelView.pin() is called, the position of the toolbar will be calculated for the old\n\t\t//    items grouping state, and when finally ResizeObserver kicks in (hey, the toolbar is visible now, right?)\n\t\t//    it will group/ungroup some items and the length of the toolbar will change. But since in RTL the toolbar\n\t\t//    is attached on the right side and the positioning uses CSS \"left\", it will result in the toolbar shifting\n\t\t//    to the left and being displayed in the wrong place.\n\t\t// 2. (WRONG ❌) If the panelView.pin() is called first and #maxWidth set next, then basically the story repeats. The balloon\n\t\t//    calculates the position for the old toolbar grouping state, then the toolbar re-groups items and because\n\t\t//    it is positioned using CSS \"left\" it will move.\n\t\t// 3. (RIGHT ✅) We show the panel first (the toolbar does re-grouping but it does not matter), then the #maxWidth\n\t\t//    is set allowing the toolbar to re-group again and finally panelView.pin() does the positioning when the\n\t\t//    items grouping state is stable and final.\n\t\t//\n\t\t// https://github.com/ckeditor/ckeditor5/issues/6449, https://github.com/ckeditor/ckeditor5/issues/6575\n\t\tthis.panelView.show();\n\n\t\tconst editableElement = this._getSelectedEditableElement();\n\n\t\tthis.toolbarView.maxWidth = this._getToolbarMaxWidth( editableElement );\n\n\t\tthis.panelView.pin( {\n\t\t\ttarget: this.buttonView.element!,\n\t\t\tlimiter: editableElement\n\t\t} );\n\n\t\tif ( !wasVisible ) {\n\t\t\t( this.toolbarView.items.get( 0 ) as any ).focus();\n\t\t}\n\t}\n\n\t/**\n\t * Returns currently selected editable, based on the model selection.\n\t */\n\tprivate _getSelectedEditableElement(): HTMLElement {\n\t\tconst selectedModelRootName = this.editor.model.document.selection.getFirstRange()!.root.rootName!;\n\n\t\treturn this.editor.ui.getEditableElement( selectedModelRootName )!;\n\t}\n\n\t/**\n\t * Hides the {@link #toolbarView}.\n\t *\n\t * @param focusEditable When `true`, the editable will be focused after hiding the panel.\n\t */\n\tprivate _hidePanel( focusEditable?: boolean ) {\n\t\tthis.panelView.isVisible = false;\n\n\t\tif ( focusEditable ) {\n\t\t\tthis.editor.editing.view.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Repositions the button on scroll.\n\t */\n\tprivate _repositionButtonOnScroll() {\n\t\tconst { buttonView } = this;\n\n\t\tlet pendingAnimationFrame = false;\n\n\t\t// Reposition the button on scroll, but do it only once per animation frame to avoid performance issues.\n\t\tconst repositionOnScroll = ( evt: EventInfo, domEvt: Event ) => {\n\t\t\tif ( pendingAnimationFrame ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// It makes no sense to reposition the button when the user scrolls the dropdown or any other\n\t\t\t// nested scrollable element. The button should be repositioned only when the user scrolls the\n\t\t\t// editable or any other scrollable parent of the editable. Leaving it as it is buggy on Chrome\n\t\t\t// where scrolling nested scrollables is not properly handled.\n\t\t\t// See more: https://github.com/ckeditor/ckeditor5/issues/17067\n\t\t\tconst editableElement = this._getSelectedEditableElement();\n\n\t\t\tif (\n\t\t\t\tdomEvt.target !== global.document &&\n\t\t\t\t!getAncestors( editableElement ).includes( domEvt.target as HTMLElement )\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingAnimationFrame = true;\n\t\t\tglobal.window.requestAnimationFrame( () => {\n\t\t\t\tthis._updateButton();\n\t\t\t\tpendingAnimationFrame = false;\n\t\t\t} );\n\t\t};\n\n\t\t// Watch scroll event only when the button is visible, it prevents attaching the scroll event listener\n\t\t// to the document when the button is not visible.\n\t\tbuttonView.on<ObservableChangeEvent<boolean>>( 'change:isVisible', ( evt, name, isVisible ) => {\n\t\t\tif ( isVisible ) {\n\t\t\t\tbuttonView.listenTo( global.document, 'scroll', repositionOnScroll, {\n\t\t\t\t\tuseCapture: true,\n\t\t\t\t\tusePassive: true\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tbuttonView.stopListening( global.document, 'scroll', repositionOnScroll );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches the {@link #buttonView} to the target block of content.\n\t *\n\t * @param targetElement Target element.\n\t */\n\tprivate _attachButtonToElement( targetElement: HTMLElement ) {\n\t\tconst buttonElement = this.buttonView.element!;\n\t\tconst editableElement = this._getSelectedEditableElement();\n\n\t\tconst contentStyles = window.getComputedStyle( targetElement );\n\n\t\tconst editableRect = new Rect( editableElement );\n\t\tconst contentPaddingTop = parseInt( contentStyles.paddingTop, 10 );\n\t\t// When line height is not an integer then treat it as \"normal\".\n\t\t// MDN says that 'normal' == ~1.2 on desktop browsers.\n\t\tconst contentLineHeight = parseInt( contentStyles.lineHeight, 10 ) || parseInt( contentStyles.fontSize, 10 ) * 1.2;\n\n\t\tconst buttonRect = new Rect( buttonElement );\n\t\tconst contentRect = new Rect( targetElement );\n\n\t\tlet positionLeft;\n\n\t\tif ( this.editor.locale.uiLanguageDirection === 'ltr' ) {\n\t\t\tpositionLeft = editableRect.left - buttonRect.width;\n\t\t} else {\n\t\t\tpositionLeft = editableRect.right;\n\t\t}\n\n\t\tconst positionTop = contentRect.top + contentPaddingTop + ( contentLineHeight - buttonRect.height ) / 2;\n\n\t\tbuttonRect.moveTo( positionLeft, positionTop );\n\n\t\tconst absoluteButtonRect = buttonRect.toAbsoluteRect();\n\n\t\tthis.buttonView.top = absoluteButtonRect.top;\n\t\tthis.buttonView.left = absoluteButtonRect.left;\n\n\t\tthis._clipButtonToViewport( this.buttonView, editableElement );\n\t}\n\n\t/**\n\t * Clips the button element to the viewport of the editable element.\n\t *\n\t * \t* If the button overflows the editable viewport, it is clipped to make it look like it's cut off by the editable scrollable region.\n\t * \t* If the button is fully hidden by the top of the editable, it is not clickable but still visible in the DOM.\n\t *\n\t * @param buttonView The button view to clip.\n\t * @param editableElement The editable element whose viewport is used for clipping.\n\t */\n\tprivate _clipButtonToViewport(\n\t\tbuttonView: ButtonView,\n\t\teditableElement: HTMLElement\n\t) {\n\t\tconst absoluteButtonRect = new Rect( buttonView.element! );\n\t\tconst scrollViewportRect = new Rect( editableElement ).getVisible();\n\n\t\t// Sets polygon clip path for the button element, if there is no argument provided, the clip path is removed.\n\t\tconst setButtonClipping = ( ...paths: Array<string> ) => {\n\t\t\tbuttonView.element!.style.clipPath = paths.length ? `polygon(${ paths.join( ',' ) })` : '';\n\t\t};\n\n\t\t// Hide the button if it's fully hidden by the top of the editable.\n\t\t// Note that the button is still visible in the DOM, but it's not clickable. It's because we don't\n\t\t// want to hide the button completely, as there are plenty of `isVisible` watchers which toggles\n\t\t// the button scroll listeners.\n\t\tconst markAsHidden = ( isHidden: boolean ) => {\n\t\t\tbuttonView.isEnabled = !isHidden;\n\t\t\tbuttonView.element!.style.pointerEvents = isHidden ? 'none' : '';\n\t\t};\n\n\t\tif ( scrollViewportRect && scrollViewportRect.bottom < absoluteButtonRect.bottom ) {\n\t\t\t// Calculate the delta between the button bottom and the editable bottom, and clip the button\n\t\t\t// to make it look like it's cut off by the editable scrollable region.\n\t\t\tconst delta = Math.min(\n\t\t\t\tabsoluteButtonRect.height,\n\t\t\t\tabsoluteButtonRect.bottom - scrollViewportRect.bottom\n\t\t\t);\n\n\t\t\tmarkAsHidden( delta >= absoluteButtonRect.height );\n\t\t\tsetButtonClipping(\n\t\t\t\t'0 0',\n\t\t\t\t'100% 0',\n\t\t\t\t`100% calc(100% - ${ toPx( delta ) })`,\n\t\t\t\t`0 calc(100% - ${ toPx( delta ) }`\n\t\t\t);\n\t\t} else if ( scrollViewportRect && scrollViewportRect.top > absoluteButtonRect.top ) {\n\t\t\t// Calculate the delta between the button top and the editable top, and clip the button\n\t\t\t// to make it look like it's cut off by the editable scrollable region.\n\t\t\tconst delta = Math.min(\n\t\t\t\tabsoluteButtonRect.height,\n\t\t\t\tscrollViewportRect.top - absoluteButtonRect.top\n\t\t\t);\n\n\t\t\tmarkAsHidden( delta >= absoluteButtonRect.height );\n\t\t\tsetButtonClipping(\n\t\t\t\t`0 ${ toPx( delta ) }`,\n\t\t\t\t`100% ${ toPx( delta ) }`,\n\t\t\t\t'100% 100%',\n\t\t\t\t'0 100%'\n\t\t\t);\n\t\t} else {\n\t\t\t// Reset the clip path if button is fully visible.\n\t\t\tmarkAsHidden( false );\n\t\t\tsetButtonClipping();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a resize observer that observes selected editable and resizes the toolbar panel accordingly.\n\t */\n\tprivate _setupToolbarResize() {\n\t\tconst editableElement = this._getSelectedEditableElement();\n\n\t\t// Do this only if the automatic grouping is turned on.\n\t\tif ( !this._blockToolbarConfig.shouldNotGroupWhenFull ) {\n\t\t\t// If resize observer is attached to a different editable than currently selected editable, re-attach it.\n\t\t\tif ( this._resizeObserver && this._resizeObserver.element !== editableElement ) {\n\t\t\t\tthis._resizeObserver.destroy();\n\t\t\t\tthis._resizeObserver = null;\n\t\t\t}\n\n\t\t\tif ( !this._resizeObserver ) {\n\t\t\t\tthis._resizeObserver = new ResizeObserver( editableElement, () => {\n\t\t\t\t\tthis.toolbarView.maxWidth = this._getToolbarMaxWidth( editableElement );\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Gets the {@link #toolbarView} max-width, based on given `editableElement` width plus the distance between the farthest\n\t * edge of the {@link #buttonView} and the editable.\n\t *\n\t * @returns A maximum width that toolbar can have, in pixels.\n\t */\n\tprivate _getToolbarMaxWidth( editableElement: HTMLElement ) {\n\t\tconst editableRect = new Rect( editableElement );\n\t\tconst buttonRect = new Rect( this.buttonView.element! );\n\t\tconst isRTL = this.editor.locale.uiLanguageDirection === 'rtl';\n\t\tconst offset = isRTL ? ( buttonRect.left - editableRect.right ) + buttonRect.width : editableRect.left - buttonRect.left;\n\n\t\treturn toPx( editableRect.width + offset );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarmenubuttonview\n */\n\nimport IconView from '../icon/iconview.js';\nimport ListItemButtonView from '../button/listitembuttonview.js';\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\n\nimport dropdownArrowIcon from '../../theme/icons/dropdown-arrow.svg';\n\nimport '../../theme/components/menubar/menubarmenubutton.css';\n\n/**\n * A menu {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#buttonView} class. Buttons like this one\n * open both top-level bar menus as well as sub-menus.\n */\nexport default class MenuBarMenuButtonView extends ListItemButtonView {\n\t/**\n\t * An icon that displays an arrow to indicate a direction of the menu.\n\t */\n\tpublic readonly arrowView: IconView;\n\n\t/**\n\t * Creates an instance of the menu bar button view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( {\n\t\t\twithText: true,\n\t\t\trole: 'menuitem'\n\t\t} );\n\n\t\tthis.arrowView = this._createArrowView();\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-menu-bar__menu__button'\n\t\t\t\t],\n\t\t\t\t'aria-haspopup': true,\n\t\t\t\t'aria-expanded': this.bindTemplate.to( 'isOn', value => String( value ) ),\n\t\t\t\t'data-cke-tooltip-disabled': bind.to( 'isOn' )\n\t\t\t},\n\t\t\ton: {\n\t\t\t\t'mouseenter': bind.to( 'mouseenter' )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.children.add( this.arrowView );\n\t}\n\n\t/**\n\t * Creates the {@link #arrowView} instance.\n\t */\n\tprivate _createArrowView() {\n\t\tconst arrowView = new IconView();\n\n\t\tarrowView.content = dropdownArrowIcon;\n\t\tarrowView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-menu-bar__menu__button__arrow'\n\t\t\t}\n\t\t} );\n\n\t\treturn arrowView;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarmenupanelview\n */\n\nimport { type Locale } from '@ckeditor/ckeditor5-utils';\nimport type { FocusableView } from '../focuscycler.js';\nimport type ViewCollection from '../viewcollection.js';\nimport View from '../view.js';\n\nimport '../../theme/components/menubar/menubarmenupanel.css';\n\n/**\n * A view representing a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#panelView} of a menu.\n */\nexport default class MenuBarMenuPanelView extends View implements FocusableView {\n\t/**\n\t * Collection of the child views in this panel.\n\t */\n\tpublic readonly children: ViewCollection<FocusableView>;\n\n\t/**\n\t * Controls whether the panel is visible.\n\t *\n\t * @observable\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * The name of the position of the panel, relative to the parent.\n\t *\n\t * This property is reflected in the CSS class suffix set to {@link #element} that controls\n\t * the position of the panel.\n\t *\n\t * @observable\n\t * @default 'se'\n\t */\n\tdeclare public position: MenuBarMenuPanelPosition;\n\n\t/**\n\t * Creates an instance of the menu panel view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale?: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'isVisible', false );\n\t\tthis.set( 'position', 'se' );\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-reset',\n\t\t\t\t\t'ck-menu-bar__menu__panel',\n\t\t\t\t\tbind.to( 'position', value => `ck-menu-bar__menu__panel_position_${ value }` ),\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t],\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: this.children,\n\n\t\t\ton: {\n\t\t\t\t// Drag and drop in the panel should not break the selection in the editor.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-ui/issues/228\n\t\t\t\tselectstart: bind.to( evt => {\n\t\t\t\t\tif ( ( evt.target as HTMLElement ).tagName.toLocaleLowerCase() === 'input' ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Focuses the first child of the panel (default) or the last one if the `direction` is `-1`.\n\t */\n\tpublic focus( direction: -1 | 1 = 1 ): void {\n\t\tif ( this.children.length ) {\n\t\t\tif ( direction === 1 ) {\n\t\t\t\tthis.children.first!.focus();\n\t\t\t} else {\n\t\t\t\tthis.children.last!.focus();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * The names of the positions of the {@link module:ui/menubar/menubarmenupanelview~MenuBarMenuPanelView}.\n *\n * They are reflected as CSS class suffixes on the panel view element.\n */\nexport type MenuBarMenuPanelPosition = 'se' | 'sw' | 'ne' | 'nw' | 'w' | 'e';\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarmenuview\n */\n\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\tgetOptimalPosition,\n\ttype Locale,\n\ttype PositioningFunction,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\nimport MenuBarMenuButtonView from './menubarmenubuttonview.js';\nimport { MenuBarMenuBehaviors, MenuBarMenuViewPanelPositioningFunctions } from './utils.js';\nimport type { FocusableView } from '../focuscycler.js';\nimport View from '../view.js';\nimport {\n\tdefault as MenuBarMenuPanelView,\n\ttype MenuBarMenuPanelPosition\n} from './menubarmenupanelview.js';\n\nimport '../../theme/components/menubar/menubarmenu.css';\n\n/**\n * A menu view for the {@link module:ui/menubar/menubarview~MenuBarView}. Menus are building blocks of the menu bar,\n * they host other sub-menus and menu items (buttons) that users can interact with.\n */\nexport default class MenuBarMenuView extends View implements FocusableView {\n\t/**\n\t * Button of the menu view.\n\t */\n\tpublic readonly buttonView: MenuBarMenuButtonView;\n\n\t/**\n\t * Panel of the menu. It hosts children of the menu.\n\t */\n\tpublic readonly panelView: MenuBarMenuPanelView;\n\n\t/**\n\t * Tracks information about the DOM focus in the menu.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}. It manages\n\t * keystrokes of the menu.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Controls whether the menu is open, i.e. shows or hides the {@link #panelView panel}.\n\t *\n\t * @observable\n\t */\n\tdeclare public isOpen: boolean;\n\n\t/**\n\t * Controls whether the menu is enabled, i.e. its {@link #buttonView} can be clicked.\n\t *\n\t * @observable\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * (Optional) The additional CSS class set on the menu {@link #element}.\n\t *\n\t * @observable\n\t */\n\tdeclare public class: string | undefined;\n\n\t/**\n\t * The name of the position of the {@link #panelView}, relative to the menu.\n\t *\n\t * **Note**: The value is updated each time the panel gets {@link #isOpen open}.\n\t *\n\t * @observable\n\t * @default 'w'\n\t */\n\tdeclare public panelPosition: MenuBarMenuPanelPosition;\n\n\t/**\n\t * The parent menu view of the menu. It is `null` for top-level menus.\n\t *\n\t * See {@link module:ui/menubar/menubarview~MenuBarView#registerMenu}.\n\t */\n\tdeclare public parentMenuView: MenuBarMenuView | null;\n\n\t/**\n\t * Creates an instance of the menu view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.buttonView = new MenuBarMenuButtonView( locale );\n\t\tthis.buttonView.delegate( 'mouseenter' ).to( this );\n\t\tthis.buttonView.bind( 'isOn', 'isEnabled' ).to( this, 'isOpen', 'isEnabled' );\n\n\t\tthis.panelView = new MenuBarMenuPanelView( locale );\n\t\tthis.panelView.bind( 'isVisible' ).to( this, 'isOpen' );\n\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\tthis.set( 'isOpen', false );\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'panelPosition', 'w' );\n\t\tthis.set( 'class', undefined );\n\t\tthis.set( 'parentMenuView', null );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-menu-bar__menu',\n\t\t\t\t\tbind.to( 'class' ),\n\t\t\t\t\tbind.if( 'isEnabled', 'ck-disabled', value => !value ),\n\t\t\t\t\tbind.if( 'parentMenuView', 'ck-menu-bar__menu_top-level', value => !value )\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.buttonView,\n\t\t\t\tthis.panelView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.focusTracker.add( this.buttonView.element! );\n\t\tthis.focusTracker.add( this.panelView.element! );\n\n\t\t// Listen for keystrokes coming from within #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\tMenuBarMenuBehaviors.closeOnEscKey( this );\n\n\t\tthis._repositionPanelOnOpen();\n\t}\n\n\t// For now, this method cannot be called in the render process because the `parentMenuView` may be assigned\n\t// after the rendering process.\n\t//\n\t// TODO: We should reconsider the way we handle this logic.\n\t/**\n\t * Attach all keyboard behaviors for the menu bar view.\n\t *\n\t * @internal\n\t */\n\tpublic _attachBehaviors(): void {\n\t\t// Top-level menus.\n\t\tif ( !this.parentMenuView ) {\n\t\t\tthis._propagateArrowKeystrokeEvents();\n\n\t\t\tMenuBarMenuBehaviors.openAndFocusPanelOnArrowDownKey( this );\n\t\t\tMenuBarMenuBehaviors.toggleOnButtonClick( this );\n\t\t} else {\n\t\t\tMenuBarMenuBehaviors.openOnButtonClick( this );\n\t\t\tMenuBarMenuBehaviors.openOnArrowRightKey( this );\n\t\t\tMenuBarMenuBehaviors.closeOnArrowLeftKey( this );\n\t\t\tMenuBarMenuBehaviors.openAndFocusOnEnterKeyPress( this );\n\t\t\tMenuBarMenuBehaviors.closeOnParentClose( this );\n\t\t}\n\t}\n\n\t/**\n\t * Fires `arrowright` and `arrowleft` events when the user pressed corresponding arrow keys.\n\t */\n\tprivate _propagateArrowKeystrokeEvents(): void {\n\t\tthis.keystrokes.set( 'arrowright', ( data, cancel ) => {\n\t\t\tthis.fire( 'arrowright' );\n\t\t\tcancel();\n\t\t} );\n\n\t\tthis.keystrokes.set( 'arrowleft', ( data, cancel ) => {\n\t\t\tthis.fire( 'arrowleft' );\n\t\t\tcancel();\n\t\t} );\n\t}\n\n\t/**\n\t * Sets the position of the panel when the menu opens. The panel is positioned\n\t * so that it optimally uses the available space in the viewport.\n\t */\n\tprivate _repositionPanelOnOpen(): void {\n\t\t// Let the menu control the position of the panel. The position must be updated every time the menu is open.\n\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( evt, name, isOpen ) => {\n\t\t\tif ( !isOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst optimalPanelPosition = MenuBarMenuView._getOptimalPosition( {\n\t\t\t\telement: this.panelView.element!,\n\t\t\t\ttarget: this.buttonView.element!,\n\t\t\t\tfitInViewport: true,\n\t\t\t\tpositions: this._panelPositions\n\t\t\t} );\n\n\t\t\tthis.panelView.position = (\n\t\t\t\toptimalPanelPosition ? optimalPanelPosition.name : this._panelPositions[ 0 ].name\n\t\t\t) as MenuBarMenuPanelPosition;\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focus(): void {\n\t\tthis.buttonView.focus();\n\t}\n\n\t/**\n\t * Positioning functions for the {@link #panelView} . They change depending on the role of the menu (top-level vs sub-menu) in\n\t * the {@link module:ui/menubar/menubarview~MenuBarView menu bar} and the UI language direction.\n\t */\n\tpublic get _panelPositions(): Array<PositioningFunction> {\n\t\tconst {\n\t\t\tsouthEast, southWest, northEast, northWest,\n\t\t\twestSouth, eastSouth, westNorth, eastNorth\n\t\t} = MenuBarMenuViewPanelPositioningFunctions;\n\n\t\tif ( this.locale!.uiLanguageDirection === 'ltr' ) {\n\t\t\tif ( this.parentMenuView ) {\n\t\t\t\treturn [ eastSouth, eastNorth, westSouth, westNorth ];\n\t\t\t} else {\n\t\t\t\treturn [ southEast, southWest, northEast, northWest ];\n\t\t\t}\n\t\t} else {\n\t\t\tif ( this.parentMenuView ) {\n\t\t\t\treturn [ westSouth, westNorth, eastSouth, eastNorth ];\n\t\t\t} else {\n\t\t\t\treturn [ southWest, southEast, northWest, northEast ];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A function used to calculate the optimal position for the dropdown panel.\n\t *\n\t * Referenced for unit testing purposes.\n\t */\n\tprivate static _getOptimalPosition = getOptimalPosition;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarmenulistview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport type View from '../view.js';\n\nimport ListItemView from '../list/listitemview.js';\nimport ListView from '../list/listview.js';\nimport ListItemButtonView from '../button/listitembuttonview.js';\nimport ButtonView from '../button/buttonview.js';\n\n/**\n * A list of menu bar items, a child of {@link module:ui/menubar/menubarmenuview~MenuBarMenuView#panelView}.\n *\n * Use this class to create a list of items (options, buttons) to be displayed in a menu bar.\n *\n * To populate this list, use {@link module:ui/menubar/menubarmenulistitemview~MenuBarMenuListItemView} instances.\n */\nexport default class MenuBarMenuListView extends ListView {\n\t/**\n\t * Creates an instance of the list view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.role = 'menu';\n\t\tthis.items.on( 'change', this._setItemsCheckSpace.bind( this ) );\n\t}\n\n\t/**\n\t * This method adds empty space if there is any toggleable item in the list.\n\t * It makes the list properly aligned.\n\t */\n\tprivate _setItemsCheckSpace() {\n\t\tconst hasAnyToggleableItem = (\n\t\t\tArray\n\t\t\t\t.from( this.items )\n\t\t\t\t.some( item => {\n\t\t\t\t\tconst listButtonView = pickListButtonMenuViewIfPresent( item );\n\n\t\t\t\t\treturn listButtonView && listButtonView.isToggleable;\n\t\t\t\t} )\n\t\t);\n\n\t\tthis.items.forEach( item => {\n\t\t\tconst listButtonView = pickListButtonMenuViewIfPresent( item );\n\n\t\t\tif ( listButtonView ) {\n\t\t\t\tlistButtonView.hasCheckSpace = hasAnyToggleableItem;\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Picks the first button menu view from the given item if present.\n *\n * @param item The item to check for a button menu view.\n * @returns The first button menu view found in the item, or `null` if not found.\n */\nfunction pickListButtonMenuViewIfPresent( item: View ) {\n\tif ( !( item instanceof ListItemView ) ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\titem\n\t\t\t.children\n\t\t\t.map( child => isNestedMenuLikeView( child ) ? child.buttonView : child )\n\t\t\t.find( item => item instanceof ListItemButtonView ) as ListItemButtonView | undefined\n\t);\n}\n\n/**\n * Checks if the given item is a nested menu-like view. `MenuBarMenuView` imports this file\n * so to avoid circular dependencies, this function is defined in more generic way.\n *\n * @param item The item to check.\n * @returns `true` if the item is a nested menu-like view, `false` otherwise.\n */\nfunction isNestedMenuLikeView( item: any ): item is { buttonView: ButtonView } {\n\treturn (\n\t\ttypeof item === 'object' &&\n\t\t\t'buttonView' in item &&\n\t\t\titem.buttonView instanceof ButtonView\n\t);\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarmenulistitemfiledialogbuttonview\n */\n\nimport type { Locale } from '@ckeditor/ckeditor5-utils';\nimport { FileDialogListItemButtonView } from '../button/filedialogbuttonview.js';\n\nimport '../../theme/components/menubar/menubarmenulistitembutton.css';\n\n/**\n * A menu bar list file dialog button view. Buttons like this one execute user actions.\n *\n * This component provides a button that opens the native file selection dialog.\n */\nexport default class MenuBarMenuListItemFileDialogButtonView extends FileDialogListItemButtonView {\n\t/**\n\t * Creates an instance of the menu bar list button view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.set( {\n\t\t\twithText: true,\n\t\t\twithKeystroke: true,\n\t\t\ttooltip: false,\n\t\t\trole: 'menuitem'\n\t\t} );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck-menu-bar__menu__item__button' ]\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module ui/menubar/menubarview\n */\n\nimport {\n\tlogWarning,\n\ttype BaseEvent,\n\ttype Locale,\n\ttype ObservableChangeEvent\n} from '@ckeditor/ckeditor5-utils';\nimport { type FocusableView } from '../focuscycler.js';\nimport View from '../view.js';\nimport { isObject } from 'lodash-es';\nimport ListItemView from '../list/listitemview.js';\nimport ListSeparatorView from '../list/listseparatorview.js';\nimport type ViewCollection from '../viewcollection.js';\nimport type ComponentFactory from '../componentfactory.js';\n\nimport MenuBarMenuView from './menubarmenuview.js';\nimport MenuBarMenuListView from './menubarmenulistview.js';\nimport MenuBarMenuListItemView from './menubarmenulistitemview.js';\nimport MenuBarMenuListItemButtonView from './menubarmenulistitembuttonview.js';\nimport MenuBarMenuListItemFileDialogButtonView from './menubarmenulistitemfiledialogbuttonview.js';\nimport {\n\tMenuBarBehaviors,\n\tprocessMenuBarConfig\n} from './utils.js';\n\nconst EVENT_NAME_DELEGATES = [ 'mouseenter', 'arrowleft', 'arrowright', 'change:isOpen' ] as const;\n\nimport '../../theme/components/menubar/menubar.css';\n\n/**\n * The application menu bar component. It brings a set of top-level menus (and sub-menus) that can be used\n * to organize and access a large number of buttons.\n */\nexport default class MenuBarView extends View implements FocusableView {\n\t/**\n\t * Collection of the child views inside the {@link #element}.\n\t */\n\tpublic children: ViewCollection<MenuBarMenuView>;\n\n\t/**\n\t * Indicates whether any of top-level menus are open in the menu bar. To close\n\t * the menu bar use the {@link #close} method.\n\t *\n\t * @observable\n\t */\n\tdeclare public isOpen: boolean;\n\n\t/**\n\t * Indicates whether the menu bar has been interacted with using the keyboard.\n\t *\n\t * It is useful for showing focus outlines while hovering over the menu bar when\n\t * interaction with the keyboard was detected.\n\t *\n\t * @observable\n\t */\n\tdeclare public isFocusBorderEnabled: boolean;\n\n\t/**\n\t * A list of {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} instances registered in the menu bar.\n\t *\n\t * @observable\n\t */\n\tpublic menus: Array<MenuBarMenuView> = [];\n\n\t/**\n\t * Creates an instance of the menu bar view.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst t = locale.t;\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( {\n\t\t\tisOpen: false,\n\t\t\tisFocusBorderEnabled: false\n\t\t} );\n\n\t\tthis._setupIsOpenUpdater();\n\n\t\tthis.children = this.createCollection();\n\n\t\t// @if CK_DEBUG_MENU_BAR // // Logs events in the main event bus of the component.\n\t\t// @if CK_DEBUG_MENU_BAR // this.on( 'menu', ( evt, data ) => {\n\t\t// @if CK_DEBUG_MENU_BAR // \tconsole.log( `MenuBarView:${ evt.name }`, evt.path.map( view => view.element ) );\n\t\t// @if CK_DEBUG_MENU_BAR // } );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-menu-bar',\n\t\t\t\t\tbind.if( 'isFocusBorderEnabled', 'ck-menu-bar_focus-border-enabled' )\n\t\t\t\t],\n\t\t\t\t'aria-label': t( 'Editor menu bar' ),\n\t\t\t\trole: 'menubar'\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * A utility that expands a plain menu bar configuration into a structure of menus (also: sub-menus)\n\t * and items using a given {@link module:ui/componentfactory~ComponentFactory component factory}.\n\t *\n\t * See the {@link module:core/editor/editorconfig~EditorConfig#menuBar menu bar} in the editor\n\t * configuration reference to learn how to configure the menu bar.\n\t */\n\tpublic fillFromConfig(\n\t\tconfig: NormalizedMenuBarConfigObject,\n\t\tcomponentFactory: ComponentFactory,\n\t\textraItems: Array<MenuBarConfigAddedItem | MenuBarConfigAddedGroup | MenuBarConfigAddedMenu> = []\n\t): void {\n\t\tconst locale = this.locale!;\n\t\tconst processedConfig = processMenuBarConfig( {\n\t\t\tnormalizedConfig: config,\n\t\t\tlocale,\n\t\t\tcomponentFactory,\n\t\t\textraItems\n\t\t} );\n\n\t\tconst topLevelCategoryMenuViews = processedConfig.items.map( menuDefinition => this._createMenu( {\n\t\t\tcomponentFactory,\n\t\t\tmenuDefinition\n\t\t} ) );\n\n\t\tthis.children.addMany( topLevelCategoryMenuViews );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tMenuBarBehaviors.toggleMenusAndFocusItemsOnHover( this );\n\t\tMenuBarBehaviors.closeMenusWhenTheBarCloses( this );\n\t\tMenuBarBehaviors.closeMenuWhenAnotherOnTheSameLevelOpens( this );\n\t\tMenuBarBehaviors.focusCycleMenusOnArrows( this );\n\t\tMenuBarBehaviors.closeOnClickOutside( this );\n\t\tMenuBarBehaviors.enableFocusHighlightOnInteraction( this );\n\t}\n\n\t/**\n\t * Focuses the menu bar.\n\t */\n\tpublic focus(): void {\n\t\tif ( this.children.first ) {\n\t\t\tthis.children.first.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Closes all menus in the bar.\n\t */\n\tpublic close(): void {\n\t\tfor ( const topLevelCategoryMenuView of this.children ) {\n\t\t\ttopLevelCategoryMenuView.isOpen = false;\n\t\t}\n\t}\n\n\t/**\n\t * Registers a menu view in the menu bar. Every {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} instance must be registered\n\t * in the menu bar to be properly managed.\n\t */\n\tpublic registerMenu( menuView: MenuBarMenuView, parentMenuView: MenuBarMenuView | null = null ): void {\n\t\tif ( parentMenuView ) {\n\t\t\tmenuView.delegate( ...EVENT_NAME_DELEGATES ).to( parentMenuView );\n\t\t\tmenuView.parentMenuView = parentMenuView;\n\t\t} else {\n\t\t\tmenuView.delegate( ...EVENT_NAME_DELEGATES ).to( this, name => 'menu:' + name );\n\t\t}\n\n\t\tmenuView._attachBehaviors();\n\n\t\tthis.menus.push( menuView );\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} based on the given definition.\n\t */\n\tprivate _createMenu( { componentFactory, menuDefinition, parentMenuView }: {\n\t\tcomponentFactory: ComponentFactory;\n\t\tmenuDefinition: MenuBarMenuDefinition;\n\t\tparentMenuView?: MenuBarMenuView;\n\t} ) {\n\t\tconst locale = this.locale!;\n\t\tconst menuView = new MenuBarMenuView( locale );\n\n\t\tthis.registerMenu( menuView, parentMenuView );\n\n\t\tmenuView.buttonView.set( {\n\t\t\tlabel: menuDefinition.label\n\t\t} );\n\n\t\t// Defer the creation of the menu structure until it gets open. This is a performance optimization\n\t\t// that shortens the time needed to create the editor.\n\t\tmenuView.once<ObservableChangeEvent<boolean>>( 'change:isOpen', () => {\n\t\t\tconst listView = new MenuBarMenuListView( locale );\n\t\t\tlistView.ariaLabel = menuDefinition.label;\n\t\t\tmenuView.panelView.children.add( listView );\n\n\t\t\tlistView.items.addMany( this._createMenuItems( { menuDefinition, parentMenuView: menuView, componentFactory } ) );\n\t\t} );\n\n\t\treturn menuView;\n\t}\n\n\t/**\n\t * Creates a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} items based on the given definition.\n\t */\n\tprivate _createMenuItems( { menuDefinition, parentMenuView, componentFactory }: {\n\t\tmenuDefinition: MenuBarMenuDefinition;\n\t\tcomponentFactory: ComponentFactory;\n\t\tparentMenuView: MenuBarMenuView;\n\t} ): Array<MenuBarMenuListItemView | ListSeparatorView> {\n\t\tconst locale = this.locale!;\n\t\tconst items = [];\n\n\t\tfor ( const menuGroupDefinition of menuDefinition.groups ) {\n\t\t\tfor ( const itemDefinition of menuGroupDefinition.items ) {\n\t\t\t\tconst menuItemView = new MenuBarMenuListItemView( locale, parentMenuView );\n\n\t\t\t\tif ( isObject( itemDefinition ) ) {\n\t\t\t\t\tmenuItemView.children.add( this._createMenu( {\n\t\t\t\t\t\tcomponentFactory,\n\t\t\t\t\t\tmenuDefinition: itemDefinition,\n\t\t\t\t\t\tparentMenuView\n\t\t\t\t\t} ) );\n\t\t\t\t} else {\n\t\t\t\t\tconst componentView = this._createMenuItemContentFromFactory( {\n\t\t\t\t\t\tcomponentName: itemDefinition,\n\t\t\t\t\t\tcomponentFactory,\n\t\t\t\t\t\tparentMenuView\n\t\t\t\t\t} );\n\n\t\t\t\t\tif ( !componentView ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tmenuItemView.children.add( componentView );\n\t\t\t\t}\n\n\t\t\t\titems.push( menuItemView );\n\t\t\t}\n\n\t\t\t// Separate groups with a separator.\n\t\t\tif ( menuGroupDefinition !== menuDefinition.groups[ menuDefinition.groups.length - 1 ] ) {\n\t\t\t\titems.push( new ListSeparatorView( locale ) );\n\t\t\t}\n\t\t}\n\n\t\treturn items;\n\t}\n\n\t/**\n\t * Uses the component factory to create a content of the menu item (a button or a sub-menu).\n\t */\n\tprivate _createMenuItemContentFromFactory( { componentName, parentMenuView, componentFactory }: {\n\t\tcomponentName: string;\n\t\tcomponentFactory: ComponentFactory;\n\t\tparentMenuView: MenuBarMenuView;\n\t} ): MenuBarMenuView | MenuBarMenuListItemButtonView | null {\n\t\tconst componentView = componentFactory.create( componentName );\n\n\t\tif ( !(\n\t\t\tcomponentView instanceof MenuBarMenuView ||\n\t\t\tcomponentView instanceof MenuBarMenuListItemButtonView ||\n\t\t\tcomponentView instanceof MenuBarMenuListItemFileDialogButtonView\n\t\t) ) {\n\t\t\t/**\n\t\t\t * Adding unsupported components to the {@link module:ui/menubar/menubarview~MenuBarView} is not possible.\n\t\t\t *\n\t\t\t * A component should be either a {@link module:ui/menubar/menubarmenuview~MenuBarMenuView} (sub-menu) or a\n\t\t\t * {@link module:ui/menubar/menubarmenulistitembuttonview~MenuBarMenuListItemButtonView} (button).\n\t\t\t *\n\t\t\t * @error menu-bar-component-unsupported\n\t\t\t * @param componentName A name of the unsupported component used in the configuration.\n\t\t\t * @param componentView An unsupported component view.\n\t\t\t */\n\t\t\tlogWarning( 'menu-bar-component-unsupported', {\n\t\t\t\tcomponentName,\n\t\t\t\tcomponentView\n\t\t\t} );\n\n\t\t\treturn null;\n\t\t}\n\n\t\tthis._registerMenuTree( componentView, parentMenuView );\n\n\t\t// Close the whole menu bar when a component is executed.\n\t\tcomponentView.on( 'execute', () => {\n\t\t\tthis.close();\n\t\t} );\n\n\t\treturn componentView;\n\t}\n\n\t/**\n\t * Checks component and its children recursively and calls {@link #registerMenu}\n\t * for each item that is {@link module:ui/menubar/menubarmenuview~MenuBarMenuView}.\n\t *\n\t * @internal\n\t */\n\tprivate _registerMenuTree( componentView: MenuBarMenuView | MenuBarMenuListItemButtonView, parentMenuView: MenuBarMenuView ) {\n\t\tif ( !( componentView instanceof MenuBarMenuView ) ) {\n\t\t\tcomponentView.delegate( 'mouseenter' ).to( parentMenuView );\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.registerMenu( componentView, parentMenuView );\n\n\t\tconst menuBarItemsList = componentView.panelView.children\n\t\t\t.filter( child => child instanceof MenuBarMenuListView )[ 0 ] as MenuBarMenuListView | undefined;\n\n\t\tif ( !menuBarItemsList ) {\n\t\t\tcomponentView.delegate( 'mouseenter' ).to( parentMenuView );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst nonSeparatorItems = menuBarItemsList.items.filter( item => item instanceof ListItemView ) as Array<ListItemView>;\n\n\t\tfor ( const item of nonSeparatorItems ) {\n\t\t\tthis._registerMenuTree(\n\t\t\t\titem.children.get( 0 ) as MenuBarMenuView | MenuBarMenuListItemButtonView,\n\t\t\t\tcomponentView\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Manages the state of the {@link #isOpen} property of the menu bar. Because the state is a sum of individual\n\t * top-level menus' states, it's necessary to listen to their changes and update the state accordingly.\n\t *\n\t * Additionally, it prevents from unnecessary changes of `isOpen` when one top-level menu opens and another closes\n\t * (regardless of in which order), maintaining a stable `isOpen === true` in that situation.\n\t */\n\tprivate _setupIsOpenUpdater() {\n\t\tlet closeTimeout: ReturnType<typeof setTimeout>;\n\n\t\t// TODO: This is not the prettiest approach but at least it's simple.\n\t\tthis.on<MenuBarMenuChangeIsOpenEvent>( 'menu:change:isOpen', ( evt, name, isOpen ) => {\n\t\t\tclearTimeout( closeTimeout );\n\n\t\t\tif ( isOpen ) {\n\t\t\t\tthis.isOpen = true;\n\t\t\t} else {\n\t\t\t\tcloseTimeout = setTimeout( () => {\n\t\t\t\t\tthis.isOpen = Array.from( this.children ).some( menuView => menuView.isOpen );\n\t\t\t\t}, 0 );\n\t\t\t}\n\t\t} );\n\t}\n}\n\nexport type MenuBarConfig = MenuBarConfigObject;\n\nexport type MenuBarConfigObject = {\n\titems?: Array<MenuBarMenuDefinition>;\n\tremoveItems?: Array<string>;\n\taddItems?: Array<MenuBarConfigAddedItem | MenuBarConfigAddedGroup | MenuBarConfigAddedMenu>;\n\tisVisible?: boolean;\n};\n\nexport type NormalizedMenuBarConfigObject = Required<MenuBarConfigObject> & {\n\tisUsingDefaultConfig: boolean;\n};\n\nexport type MenuBarMenuGroupDefinition = {\n\tgroupId: string;\n\titems: Array<MenuBarMenuDefinition | string>;\n};\n\nexport type MenuBarMenuDefinition = {\n\tmenuId: string;\n\tlabel: string;\n\tgroups: Array<MenuBarMenuGroupDefinition>;\n};\n\nexport type MenuBarConfigAddedPosition =\n\t`start:${ string }` | `end:${ string }` | 'start' | 'end' | `after:${ string }` | `before:${ string }`;\n\nexport type MenuBarConfigAddedItem = {\n\titem: string;\n\tposition: MenuBarConfigAddedPosition;\n};\n\nexport type MenuBarConfigAddedGroup = {\n\tgroup: MenuBarMenuGroupDefinition;\n\tposition: MenuBarConfigAddedPosition;\n};\n\nexport type MenuBarConfigAddedMenu = {\n\tmenu: MenuBarMenuDefinition;\n\tposition: MenuBarConfigAddedPosition;\n};\n\n/**\n * Any namespaced event fired by menu a {@link module:ui/menubar/menubarview~MenuBarView#menus menu view instance} of the\n * {@link module:ui/menubar/menubarview~MenuBarView menu bar}.\n */\ninterface MenuBarMenuEvent extends BaseEvent {\n\tname: `menu:${ string }` | `menu:change:${ string }`;\n}\n\n/**\n * A `mouseenter` event originating from a {@link module:ui/menubar/menubarview~MenuBarView#menus menu view instance} of the\n * {@link module:ui/menubar/menubarview~MenuBarView menu bar}.\n */\nexport interface MenuBarMenuMouseEnterEvent extends MenuBarMenuEvent {\n\tname: 'menu:mouseenter';\n}\n\n/**\n * An `arrowleft` event originating from a {@link module:ui/menubar/menubarview~MenuBarView#menus menu view instance} of the\n * {@link module:ui/menubar/menubarview~MenuBarView menu bar}.\n */\nexport interface MenuBarMenuArrowLeftEvent extends MenuBarMenuEvent {\n\tname: 'menu:arrowleft';\n}\n\n/**\n * An `arrowright` event originating from a {@link module:ui/menubar/menubarview~MenuBarView#menus menu view instance} of the\n * {@link module:ui/menubar/menubarview~MenuBarView menu bar}.\n */\nexport interface MenuBarMenuArrowRightEvent extends MenuBarMenuEvent {\n\tname: 'menu:arrowright';\n}\n\n/**\n * A `change:isOpen` event originating from a {@link module:ui/menubar/menubarview~MenuBarView#menus menu view instance} of the\n * {@link module:ui/menubar/menubarview~MenuBarView menu bar}.\n */\nexport interface MenuBarMenuChangeIsOpenEvent extends MenuBarMenuEvent {\n\tname: 'menu:change:isOpen';\n\targs: [ name: string, value: boolean, oldValue: boolean ];\n}\n", "// Clamps a value between an upper and lower bound.\n// We use ternary operators because it makes the minified code\n// 2 times shorter then `Math.min(Math.max(a,b),c)`\nexport const clamp = (number: number, min = 0, max = 1): number => {\n  return number > max ? max : number < min ? min : number;\n};\n\nexport const round = (number: number, digits = 0, base = Math.pow(10, digits)): number => {\n  return Math.round(base * number) / base;\n};\n", "import { RgbaColor, RgbColor, HslaColor, HslColor, HsvaColor, HsvColor } from '../types';\nimport { round } from './math.js';\n\n/**\n * Valid CSS <angle> units.\n * https://developer.mozilla.org/en-US/docs/Web/CSS/angle\n */\nconst angleUnits: Record<string, number> = {\n  grad: 360 / 400,\n  turn: 360,\n  rad: 360 / (Math.PI * 2)\n};\n\nexport const hexToHsva = (hex: string): HsvaColor => rgbaToHsva(hexToRgba(hex));\n\nexport const hexToRgba = (hex: string): RgbaColor => {\n  if (hex[0] === '#') hex = hex.substring(1);\n\n  if (hex.length < 6) {\n    return {\n      r: parseInt(hex[0] + hex[0], 16),\n      g: parseInt(hex[1] + hex[1], 16),\n      b: parseInt(hex[2] + hex[2], 16),\n      a: hex.length === 4 ? round(parseInt(hex[3] + hex[3], 16) / 255, 2) : 1\n    };\n  }\n\n  return {\n    r: parseInt(hex.substring(0, 2), 16),\n    g: parseInt(hex.substring(2, 4), 16),\n    b: parseInt(hex.substring(4, 6), 16),\n    a: hex.length === 8 ? round(parseInt(hex.substring(6, 8), 16) / 255, 2) : 1\n  };\n};\n\nexport const parseHue = (value: string, unit = 'deg'): number => {\n  return Number(value) * (angleUnits[unit] || 1);\n};\n\nexport const hslaStringToHsva = (hslString: string): HsvaColor => {\n  const matcher =\n    /hsla?\\(?\\s*(-?\\d*\\.?\\d+)(deg|rad|grad|turn)?[,\\s]+(-?\\d*\\.?\\d+)%?[,\\s]+(-?\\d*\\.?\\d+)%?,?\\s*[/\\s]*(-?\\d*\\.?\\d+)?(%)?\\s*\\)?/i;\n  const match = matcher.exec(hslString);\n\n  if (!match) return { h: 0, s: 0, v: 0, a: 1 };\n\n  return hslaToHsva({\n    h: parseHue(match[1], match[2]),\n    s: Number(match[3]),\n    l: Number(match[4]),\n    a: match[5] === undefined ? 1 : Number(match[5]) / (match[6] ? 100 : 1)\n  });\n};\n\nexport const hslStringToHsva = hslaStringToHsva;\n\nexport const hslaToHsva = ({ h, s, l, a }: HslaColor): HsvaColor => {\n  s *= (l < 50 ? l : 100 - l) / 100;\n\n  return {\n    h: h,\n    s: s > 0 ? ((2 * s) / (l + s)) * 100 : 0,\n    v: l + s,\n    a\n  };\n};\n\nexport const hsvaToHex = (hsva: HsvaColor): string => rgbaToHex(hsvaToRgba(hsva));\n\nexport const hsvaToHsla = ({ h, s, v, a }: HsvaColor): HslaColor => {\n  const hh = ((200 - s) * v) / 100;\n\n  return {\n    h: round(h),\n    s: round(hh > 0 && hh < 200 ? ((s * v) / 100 / (hh <= 100 ? hh : 200 - hh)) * 100 : 0),\n    l: round(hh / 2),\n    a: round(a, 2)\n  };\n};\n\nexport const hsvaToHsvString = (hsva: HsvaColor): string => {\n  const { h, s, v } = roundHsva(hsva);\n  return `hsv(${h}, ${s}%, ${v}%)`;\n};\n\nexport const hsvaToHsvaString = (hsva: HsvaColor): string => {\n  const { h, s, v, a } = roundHsva(hsva);\n  return `hsva(${h}, ${s}%, ${v}%, ${a})`;\n};\n\nexport const hsvaToHslString = (hsva: HsvaColor): string => {\n  const { h, s, l } = hsvaToHsla(hsva);\n  return `hsl(${h}, ${s}%, ${l}%)`;\n};\n\nexport const hsvaToHslaString = (hsva: HsvaColor): string => {\n  const { h, s, l, a } = hsvaToHsla(hsva);\n  return `hsla(${h}, ${s}%, ${l}%, ${a})`;\n};\n\nexport const hsvaToRgba = ({ h, s, v, a }: HsvaColor): RgbaColor => {\n  h = (h / 360) * 6;\n  s = s / 100;\n  v = v / 100;\n\n  const hh = Math.floor(h),\n    b = v * (1 - s),\n    c = v * (1 - (h - hh) * s),\n    d = v * (1 - (1 - h + hh) * s),\n    module = hh % 6;\n\n  return {\n    r: round([v, c, b, b, d, v][module] * 255),\n    g: round([d, v, v, c, b, b][module] * 255),\n    b: round([b, b, d, v, v, c][module] * 255),\n    a: round(a, 2)\n  };\n};\n\nexport const hsvaToRgbString = (hsva: HsvaColor): string => {\n  const { r, g, b } = hsvaToRgba(hsva);\n  return `rgb(${r}, ${g}, ${b})`;\n};\n\nexport const hsvaToRgbaString = (hsva: HsvaColor): string => {\n  const { r, g, b, a } = hsvaToRgba(hsva);\n  return `rgba(${r}, ${g}, ${b}, ${a})`;\n};\n\nexport const hsvaStringToHsva = (hsvString: string): HsvaColor => {\n  const matcher =\n    /hsva?\\(?\\s*(-?\\d*\\.?\\d+)(deg|rad|grad|turn)?[,\\s]+(-?\\d*\\.?\\d+)%?[,\\s]+(-?\\d*\\.?\\d+)%?,?\\s*[/\\s]*(-?\\d*\\.?\\d+)?(%)?\\s*\\)?/i;\n  const match = matcher.exec(hsvString);\n\n  if (!match) return { h: 0, s: 0, v: 0, a: 1 };\n\n  return roundHsva({\n    h: parseHue(match[1], match[2]),\n    s: Number(match[3]),\n    v: Number(match[4]),\n    a: match[5] === undefined ? 1 : Number(match[5]) / (match[6] ? 100 : 1)\n  });\n};\n\nexport const hsvStringToHsva = hsvaStringToHsva;\n\nexport const rgbaStringToHsva = (rgbaString: string): HsvaColor => {\n  const matcher =\n    /rgba?\\(?\\s*(-?\\d*\\.?\\d+)(%)?[,\\s]+(-?\\d*\\.?\\d+)(%)?[,\\s]+(-?\\d*\\.?\\d+)(%)?,?\\s*[/\\s]*(-?\\d*\\.?\\d+)?(%)?\\s*\\)?/i;\n  const match = matcher.exec(rgbaString);\n\n  if (!match) return { h: 0, s: 0, v: 0, a: 1 };\n\n  return rgbaToHsva({\n    r: Number(match[1]) / (match[2] ? 100 / 255 : 1),\n    g: Number(match[3]) / (match[4] ? 100 / 255 : 1),\n    b: Number(match[5]) / (match[6] ? 100 / 255 : 1),\n    a: match[7] === undefined ? 1 : Number(match[7]) / (match[8] ? 100 : 1)\n  });\n};\n\nexport const rgbStringToHsva = rgbaStringToHsva;\n\nconst format = (number: number) => {\n  const hex = number.toString(16);\n  return hex.length < 2 ? '0' + hex : hex;\n};\n\nexport const rgbaToHex = ({ r, g, b, a }: RgbaColor): string => {\n  const alphaHex = a < 1 ? format(round(a * 255)) : '';\n  return '#' + format(r) + format(g) + format(b) + alphaHex;\n};\n\nexport const rgbaToHsva = ({ r, g, b, a }: RgbaColor): HsvaColor => {\n  const max = Math.max(r, g, b);\n  const delta = max - Math.min(r, g, b);\n\n  // prettier-ignore\n  const hh = delta\n    ? max === r\n      ? (g - b) / delta\n      : max === g\n        ? 2 + (b - r) / delta\n        : 4 + (r - g) / delta\n    : 0;\n\n  return {\n    h: round(60 * (hh < 0 ? hh + 6 : hh)),\n    s: round(max ? (delta / max) * 100 : 0),\n    v: round((max / 255) * 100),\n    a\n  };\n};\n\nexport const roundHsva = (hsva: HsvaColor): HsvaColor => ({\n  h: round(hsva.h),\n  s: round(hsva.s),\n  v: round(hsva.v),\n  a: round(hsva.a, 2)\n});\n\nexport const rgbaToRgb = ({ r, g, b }: RgbaColor): RgbColor => ({ r, g, b });\n\nexport const hslaToHsl = ({ h, s, l }: HslaColor): HslColor => ({ h, s, l });\n\nexport const hsvaToHsv = (hsva: HsvaColor): HsvColor => {\n  const { h, s, v } = roundHsva(hsva);\n  return { h, s, v };\n};\n", "import { hexToRgba } from './convert.js';\nimport type { ObjectColor } from '../types';\n\nexport const equalColorObjects = (first: ObjectColor, second: ObjectColor): boolean => {\n  if (first === second) return true;\n\n  for (const prop in first) {\n    // The following allows for a type-safe calling of this function (first & second have to be HSL, HSV, or RGB)\n    // with type-unsafe iterating over object keys. TS does not allow this without an index (`[key: string]: number`)\n    // on an object to define how iteration is normally done. To ensure extra keys are not allowed on our types,\n    // we must cast our object to unknown (as RGB demands `r` be a key, while `Record<string, x>` does not care if\n    // there is or not), and then as a type TS can iterate over.\n    if (\n      (first as unknown as Record<string, number>)[prop] !==\n      (second as unknown as Record<string, number>)[prop]\n    )\n      return false;\n  }\n\n  return true;\n};\n\nexport const equalColorString = (first: string, second: string): boolean => {\n  return first.replace(/\\s/g, '') === second.replace(/\\s/g, '');\n};\n\nexport const equalHex = (first: string, second: string): boolean => {\n  if (first.toLowerCase() === second.toLowerCase()) return true;\n\n  // To compare colors like `#FFF` and `ffffff` we convert them into RGB objects\n  return equalColorObjects(hexToRgba(first), hexToRgba(second));\n};\n", "const cache: Record<string, HTMLTemplateElement> = {};\n\nexport const tpl = (html: string): HTMLTemplateElement => {\n  let template = cache[html];\n  if (!template) {\n    template = document.createElement('template');\n    template.innerHTML = html;\n    cache[html] = template;\n  }\n  return template;\n};\n\nexport const fire = (target: HTMLElement, type: string, detail: Record<string, unknown>): void => {\n  target.dispatchEvent(\n    new CustomEvent(type, {\n      bubbles: true,\n      detail\n    })\n  );\n};\n", "import type { HsvaColor } from '../types.js';\nimport { fire, tpl } from '../utils/dom.js';\nimport { clamp } from '../utils/math.js';\n\nexport interface Offset {\n  x: number;\n  y: number;\n}\n\nlet hasTouched = false;\n\n// Check if an event was triggered by touch\nconst isTouch = (e: Event): e is TouchEvent => 'touches' in e;\n\n// Prevent mobile browsers from handling mouse events (conflicting with touch ones).\n// If we detected a touch interaction before, we prefer reacting to touch events only.\nconst isValid = (event: Event): boolean => {\n  if (hasTouched && !isTouch(event)) return false;\n  if (!hasTouched) hasTouched = isTouch(event);\n  return true;\n};\n\nconst pointerMove = (target: Slider, event: Event): void => {\n  const pointer = isTouch(event) ? event.touches[0] : (event as MouseEvent);\n  const rect = target.el.getBoundingClientRect();\n\n  fire(\n    target.el,\n    'move',\n    target.getMove({\n      x: clamp((pointer.pageX - (rect.left + window.pageXOffset)) / rect.width),\n      y: clamp((pointer.pageY - (rect.top + window.pageYOffset)) / rect.height)\n    })\n  );\n};\n\nconst keyMove = (target: Slider, event: KeyboardEvent): void => {\n  // We use `keyCode` instead of `key` to reduce the size of the library.\n  const keyCode = event.keyCode;\n  // Ignore all keys except arrow ones, Page Up, Page Down, Home and End.\n  if (keyCode > 40 || (target.xy && keyCode < 37) || keyCode < 33) return;\n  // Do not scroll page by keys when color picker element has focus.\n  event.preventDefault();\n  // Send relative offset to the parent component.\n  fire(\n    target.el,\n    'move',\n    target.getMove(\n      {\n        x:\n          keyCode === 39 // Arrow Right\n            ? 0.01\n            : keyCode === 37 // Arrow Left\n            ? -0.01\n            : keyCode === 34 // Page Down\n            ? 0.05\n            : keyCode === 33 // Page Up\n            ? -0.05\n            : keyCode === 35 // End\n            ? 1\n            : keyCode === 36 // Home\n            ? -1\n            : 0,\n        y:\n          keyCode === 40 // Arrow down\n            ? 0.01\n            : keyCode === 38 // Arrow Up\n            ? -0.01\n            : 0\n      },\n      true\n    )\n  );\n};\n\nexport abstract class Slider {\n  declare nodes: HTMLElement[];\n\n  declare el: HTMLElement;\n\n  declare xy: boolean;\n\n  constructor(root: ShadowRoot, part: string, aria: string, xy: boolean) {\n    const template = tpl(\n      `<div role=\"slider\" tabindex=\"0\" part=\"${part}\" ${aria}><div part=\"${part}-pointer\"></div></div>`\n    );\n    root.appendChild(template.content.cloneNode(true));\n\n    const el = root.querySelector(`[part=${part}]`) as HTMLElement;\n    el.addEventListener('mousedown', this);\n    el.addEventListener('touchstart', this);\n    el.addEventListener('keydown', this);\n    this.el = el;\n\n    this.xy = xy;\n    this.nodes = [el.firstChild as HTMLElement, el];\n  }\n\n  set dragging(state: boolean) {\n    const toggleEvent = state ? document.addEventListener : document.removeEventListener;\n    toggleEvent(hasTouched ? 'touchmove' : 'mousemove', this);\n    toggleEvent(hasTouched ? 'touchend' : 'mouseup', this);\n  }\n\n  handleEvent(event: Event): void {\n    switch (event.type) {\n      case 'mousedown':\n      case 'touchstart':\n        event.preventDefault();\n        // event.button is 0 in mousedown for left button activation\n        if (!isValid(event) || (!hasTouched && (event as MouseEvent).button != 0)) return;\n        this.el.focus();\n        pointerMove(this, event);\n        this.dragging = true;\n        break;\n      case 'mousemove':\n      case 'touchmove':\n        event.preventDefault();\n        pointerMove(this, event);\n        break;\n      case 'mouseup':\n      case 'touchend':\n        this.dragging = false;\n        break;\n      case 'keydown':\n        keyMove(this, event as KeyboardEvent);\n        break;\n    }\n  }\n\n  abstract getMove(offset: Offset, key?: boolean): Record<string, number>;\n\n  abstract update(hsva: HsvaColor): void;\n\n  style(styles: Array<Record<string, string>>): void {\n    styles.forEach((style, i) => {\n      for (const p in style) {\n        this.nodes[i].style.setProperty(p, style[p]);\n      }\n    });\n  }\n}\n", "import { Slider, Offset } from './slider.js';\nimport { hsvaToHslString } from '../utils/convert.js';\nimport { clamp, round } from '../utils/math.js';\nimport type { HsvaColor } from '../types';\n\nexport class Hue extends Slider {\n  declare h: number;\n\n  constructor(root: ShadowRoot) {\n    super(root, 'hue', 'aria-label=\"Hue\" aria-valuemin=\"0\" aria-valuemax=\"360\"', false);\n  }\n\n  update({ h }: HsvaColor): void {\n    this.h = h;\n    this.style([\n      {\n        left: `${(h / 360) * 100}%`,\n        color: hsvaToHslString({ h, s: 100, v: 100, a: 1 })\n      }\n    ]);\n    this.el.setAttribute('aria-valuenow', `${round(h)}`);\n  }\n\n  getMove(offset: Offset, key?: boolean): Record<string, number> {\n    // Hue measured in degrees of the color circle ranging from 0 to 360\n    return { h: key ? clamp(this.h + offset.x * 360, 0, 360) : 360 * offset.x };\n  }\n}\n", "import { Slider, Offset } from './slider.js';\nimport { hsvaToHslString } from '../utils/convert.js';\nimport { clamp, round } from '../utils/math.js';\nimport type { HsvaColor } from '../types';\n\nexport class Saturation extends Slider {\n  declare hsva: HsvaColor;\n\n  constructor(root: ShadowRoot) {\n    super(root, 'saturation', 'aria-label=\"Color\"', true);\n  }\n\n  update(hsva: HsvaColor): void {\n    this.hsva = hsva;\n    this.style([\n      {\n        top: `${100 - hsva.v}%`,\n        left: `${hsva.s}%`,\n        color: hsvaToHslString(hsva)\n      },\n      {\n        'background-color': hsvaToHslString({ h: hsva.h, s: 100, v: 100, a: 1 })\n      }\n    ]);\n    this.el.setAttribute(\n      'aria-valuetext',\n      `Saturation ${round(hsva.s)}%, Brightness ${round(hsva.v)}%`\n    );\n  }\n\n  getMove(offset: Offset, key?: boolean): Record<string, number> {\n    // Saturation and brightness always fit into [0, 100] range\n    return {\n      s: key ? clamp(this.hsva.s + offset.x * 100, 0, 100) : offset.x * 100,\n      v: key ? clamp(this.hsva.v - offset.y * 100, 0, 100) : Math.round(100 - offset.y * 100)\n    };\n  }\n}\n", "export default `:host{display:flex;flex-direction:column;position:relative;width:200px;height:200px;user-select:none;-webkit-user-select:none;cursor:default}:host([hidden]){display:none!important}[role=slider]{position:relative;touch-action:none;user-select:none;-webkit-user-select:none;outline:0}[role=slider]:last-child{border-radius:0 0 8px 8px}[part$=pointer]{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;display:flex;place-content:center center;transform:translate(-50%,-50%);background-color:#fff;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2)}[part$=pointer]::after{content:\"\";width:100%;height:100%;border-radius:inherit;background-color:currentColor}[role=slider]:focus [part$=pointer]{transform:translate(-50%,-50%) scale(1.1)}`;\n", "export default `[part=hue]{flex:0 0 24px;background:linear-gradient(to right,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}[part=hue-pointer]{top:50%;z-index:2}`;\n", "export default `[part=saturation]{flex-grow:1;border-color:transparent;border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(to top,#000,transparent),linear-gradient(to right,#fff,rgba(255,255,255,0));box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}[part=saturation-pointer]{z-index:3}`;\n", "import { equalColorObjects } from '../utils/compare.js';\nimport { fire, tpl } from '../utils/dom.js';\nimport type { AnyColor, ColorModel, HsvaColor } from '../types';\nimport { Hue } from './hue.js';\nimport { Saturation } from './saturation.js';\nimport type { Slider } from './slider.js';\nimport css from '../styles/color-picker.js';\nimport hueCss from '../styles/hue.js';\nimport saturationCss from '../styles/saturation.js';\n\nconst $isSame = Symbol('same');\nconst $color = Symbol('color');\nconst $hsva = Symbol('hsva');\nconst $update = Symbol('update');\nconst $parts = Symbol('parts');\n\nexport const $css = Symbol('css');\nexport const $sliders = Symbol('sliders');\n\nexport type Sliders = Array<new (root: ShadowRoot) => Slider>;\n\nexport abstract class ColorPicker<C extends AnyColor> extends HTMLElement {\n  static get observedAttributes(): string[] {\n    return ['color'];\n  }\n\n  protected get [$css](): string[] {\n    return [css, hueCss, saturationCss];\n  }\n\n  protected get [$sliders](): Sliders {\n    return [Saturation, Hue];\n  }\n\n  protected abstract get colorModel(): ColorModel<C>;\n\n  private declare [$hsva]: HsvaColor;\n\n  private declare [$color]: C;\n\n  private declare [$parts]: Slider[];\n\n  get color(): C {\n    return this[$color];\n  }\n\n  set color(newColor: C) {\n    if (!this[$isSame](newColor)) {\n      const newHsva = this.colorModel.toHsva(newColor);\n      this[$update](newHsva);\n      this[$color] = newColor;\n    }\n  }\n\n  constructor() {\n    super();\n    const template = tpl(`<style>${this[$css].join('')}</style>`);\n    const root = this.attachShadow({ mode: 'open' });\n    root.appendChild(template.content.cloneNode(true));\n    root.addEventListener('move', this);\n    this[$parts] = this[$sliders].map((slider) => new slider(root));\n  }\n\n  connectedCallback(): void {\n    // A user may set a property on an _instance_ of an element,\n    // before its prototype has been connected to this class.\n    // If so, we need to run it through the proper class setter.\n    if (this.hasOwnProperty('color')) {\n      const value = this.color;\n      delete this['color' as keyof this];\n      this.color = value;\n    } else if (!this.color) {\n      this.color = this.colorModel.defaultColor;\n    }\n  }\n\n  attributeChangedCallback(_attr: string, _oldVal: string, newVal: string): void {\n    const color = this.colorModel.fromAttr(newVal);\n    if (!this[$isSame](color)) {\n      this.color = color;\n    }\n  }\n\n  handleEvent(event: CustomEvent): void {\n    // Merge the current HSV color object with updated params.\n    const oldHsva = this[$hsva];\n    const newHsva = { ...oldHsva, ...event.detail };\n    this[$update](newHsva);\n    let newColor;\n    if (\n      !equalColorObjects(newHsva, oldHsva) &&\n      !this[$isSame]((newColor = this.colorModel.fromHsva(newHsva)))\n    ) {\n      this[$color] = newColor;\n      fire(this, 'color-changed', { value: newColor });\n    }\n  }\n\n  private [$isSame](color: C): boolean {\n    return this.color && this.colorModel.equal(color, this.color);\n  }\n\n  private [$update](hsva: HsvaColor): void {\n    this[$hsva] = hsva;\n    this[$parts].forEach((part) => part.update(hsva));\n  }\n}\n", "import type { ColorModel, ColorPickerEventListener, ColorPickerEventMap } from '../types';\nimport { ColorPicker } from '../components/color-picker.js';\nimport { hexToHsva, hsvaToHex } from '../utils/convert.js';\nimport { equalHex } from '../utils/compare.js';\n\nconst colorModel: ColorModel<string> = {\n  defaultColor: '#000',\n  toHsva: hexToHsva,\n  fromHsva: ({ h, s, v }) => hsvaToHex({ h, s, v, a: 1 }),\n  equal: equalHex,\n  fromAttr: (color) => color\n};\n\nexport interface HexBase {\n  addEventListener<T extends keyof ColorPickerEventMap<string>>(\n    type: T,\n    listener: ColorPickerEventListener<ColorPickerEventMap<string>[T]>,\n    options?: boolean | AddEventListenerOptions\n  ): void;\n\n  removeEventListener<T extends keyof ColorPickerEventMap<string>>(\n    type: T,\n    listener: ColorPickerEventListener<ColorPickerEventMap<string>[T]>,\n    options?: boolean | EventListenerOptions\n  ): void;\n}\n\nexport class HexBase extends ColorPicker<string> {\n  protected get colorModel(): ColorModel<string> {\n    return colorModel;\n  }\n}\n", "import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { env, EventInfo, count, keyCodes, isInsideSurrogatePair, isInsideCombinedSymbol, isInsideEmojiSequence, ObservableMixin } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { Observer, FocusObserver, DomEventData, LiveRange, BubblingEventInfo, MouseObserver } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { debounce, escapeRegExp } from 'lodash-es';\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module typing/utils/changebuffer\n */ /**\n * Change buffer allows to group atomic changes (like characters that have been typed) into\n * {@link module:engine/model/batch~Batch batches}.\n *\n * Batches represent single undo steps, hence changes added to one single batch are undone together.\n *\n * The buffer has a configurable limit of atomic changes that it can accommodate. After the limit was\n * exceeded (see {@link ~ChangeBuffer#input}), a new batch is created in {@link ~ChangeBuffer#batch}.\n *\n * To use the change buffer you need to let it know about the number of changes that were added to the batch:\n *\n * ```ts\n * const buffer = new ChangeBuffer( model, LIMIT );\n *\n * // Later on in your feature:\n * buffer.batch.insert( pos, insertedCharacters );\n * buffer.input( insertedCharacters.length );\n * ```\n */ class ChangeBuffer {\n    /**\n\t * The model instance.\n\t */ model;\n    /**\n\t * The maximum number of atomic changes which can be contained in one batch.\n\t */ limit;\n    /**\n\t * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.\n\t */ _isLocked;\n    /**\n\t * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},\n\t * the {@link #batch batch} is set to a new one.\n\t */ _size;\n    /**\n\t * The current batch instance.\n\t */ _batch = null;\n    /**\n\t * The callback to document the change event which later needs to be removed.\n\t */ _changeCallback;\n    /**\n\t * The callback to document selection `change:attribute` and `change:range` events which resets the buffer.\n\t */ _selectionChangeCallback;\n    /**\n\t * Creates a new instance of the change buffer.\n\t *\n\t * @param limit The maximum number of atomic changes which can be contained in one batch.\n\t */ constructor(model, limit = 20){\n        this.model = model;\n        this._size = 0;\n        this.limit = limit;\n        this._isLocked = false;\n        // The function to be called in order to notify the buffer about batches which appeared in the document.\n        // The callback will check whether it is a new batch and in that case the buffer will be flushed.\n        //\n        // The reason why the buffer needs to be flushed whenever a new batch appears is that the changes added afterwards\n        // should be added to a new batch. For instance, when the user types, then inserts an image, and then types again,\n        // the characters typed after inserting the image should be added to a different batch than the characters typed before.\n        this._changeCallback = (evt, batch)=>{\n            if (batch.isLocal && batch.isUndoable && batch !== this._batch) {\n                this._reset(true);\n            }\n        };\n        this._selectionChangeCallback = ()=>{\n            this._reset();\n        };\n        this.model.document.on('change', this._changeCallback);\n        this.model.document.selection.on('change:range', this._selectionChangeCallback);\n        this.model.document.selection.on('change:attribute', this._selectionChangeCallback);\n    }\n    /**\n\t * The current batch to which a feature should add its operations. Once the {@link #size}\n\t * is reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t */ get batch() {\n        if (!this._batch) {\n            this._batch = this.model.createBatch({\n                isTyping: true\n            });\n        }\n        return this._batch;\n    }\n    /**\n\t * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},\n\t * the {@link #batch batch} is set to a new one.\n\t */ get size() {\n        return this._size;\n    }\n    /**\n\t * The input number of changes into the buffer. Once the {@link #size} is\n\t * reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t *\n\t * @param changeCount The number of atomic changes to input.\n\t */ input(changeCount) {\n        this._size += changeCount;\n        if (this._size >= this.limit) {\n            this._reset(true);\n        }\n    }\n    /**\n\t * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.\n\t */ get isLocked() {\n        return this._isLocked;\n    }\n    /**\n\t * Locks the buffer.\n\t */ lock() {\n        this._isLocked = true;\n    }\n    /**\n\t * Unlocks the buffer.\n\t */ unlock() {\n        this._isLocked = false;\n    }\n    /**\n\t * Destroys the buffer.\n\t */ destroy() {\n        this.model.document.off('change', this._changeCallback);\n        this.model.document.selection.off('change:range', this._selectionChangeCallback);\n        this.model.document.selection.off('change:attribute', this._selectionChangeCallback);\n    }\n    /**\n\t * Resets the change buffer.\n\t *\n\t * @param ignoreLock Whether internal lock {@link #isLocked} should be ignored.\n\t */ _reset(ignoreLock = false) {\n        if (!this.isLocked || ignoreLock) {\n            this._batch = null;\n            this._size = 0;\n        }\n    }\n}\n\n/**\n * The insert text command. Used by the {@link module:typing/input~Input input feature} to handle typing.\n */ class InsertTextCommand extends Command {\n    /**\n\t * Typing's change buffer used to group subsequent changes into batches.\n\t */ _buffer;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param undoStepSize The maximum number of atomic changes\n\t * which can be contained in one batch in the command buffer.\n\t */ constructor(editor, undoStepSize){\n        super(editor);\n        this._buffer = new ChangeBuffer(editor.model, undoStepSize);\n        // Since this command may execute on different selectable than selection, it should be checked directly in execute block.\n        this._isEnabledBasedOnSelection = false;\n    }\n    /**\n\t * The current change buffer.\n\t */ get buffer() {\n        return this._buffer;\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this._buffer.destroy();\n    }\n    /**\n\t * Executes the input command. It replaces the content within the given range with the given text.\n\t * Replacing is a two step process, first the content within the range is removed and then the new text is inserted\n\t * at the beginning of the range (which after the removal is a collapsed range).\n\t *\n\t * @fires execute\n\t * @param options The command options.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const doc = model.document;\n        const text = options.text || '';\n        const textInsertions = text.length;\n        let selection = doc.selection;\n        if (options.selection) {\n            selection = options.selection;\n        } else if (options.range) {\n            selection = model.createSelection(options.range);\n        }\n        // Stop executing if selectable is in non-editable place.\n        if (!model.canEditAt(selection)) {\n            return;\n        }\n        const resultRange = options.resultRange;\n        model.enqueueChange(this._buffer.batch, (writer)=>{\n            this._buffer.lock();\n            // Store selection attributes before deleting old content to preserve formatting and link.\n            // This unifies the behavior between DocumentSelection and Selection provided as input option.\n            const selectionAttributes = Array.from(doc.selection.getAttributes());\n            model.deleteContent(selection);\n            if (text) {\n                model.insertContent(writer.createText(text, selectionAttributes), selection);\n            }\n            if (resultRange) {\n                writer.setSelection(resultRange);\n            } else if (!selection.is('documentSelection')) {\n                writer.setSelection(selection);\n            }\n            this._buffer.unlock();\n            this._buffer.input(textInsertions);\n        });\n    }\n}\n\nconst TYPING_INPUT_TYPES = [\n    // For collapsed range:\n    //\t- This one is a regular typing (all browsers, all systems).\n    //\t- This one is used by Chrome when typing accented letter – 2nd step when the user selects the accent (Mac).\n    // For non-collapsed range:\n    //\t- This one is used by Chrome when typing accented letter – when the selection box first appears (Mac).\n    //\t- This one is used by Safari when accepting spell check suggestions from the context menu (Mac).\n    'insertText',\n    // This one is used by Safari when typing accented letter (Mac).\n    // This one is used by Safari when accepting spell check suggestions from the autocorrection pop-up (Mac).\n    'insertReplacementText'\n];\nconst TYPING_INPUT_TYPES_ANDROID = [\n    ...TYPING_INPUT_TYPES,\n    'insertCompositionText'\n];\n/**\n * Text insertion observer introduces the {@link module:engine/view/document~Document#event:insertText} event.\n */ class InsertTextObserver extends Observer {\n    /**\n\t * Instance of the focus observer. Insert text observer calls\n\t * {@link module:engine/view/observer/focusobserver~FocusObserver#flush} to mark the latest focus change as complete.\n\t */ focusObserver;\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        this.focusObserver = view.getObserver(FocusObserver);\n        // On Android composition events should immediately be applied to the model. Rendering is not disabled.\n        // On non-Android the model is updated only on composition end.\n        // On Android we can't rely on composition start/end to update model.\n        const typingInputTypes = env.isAndroid ? TYPING_INPUT_TYPES_ANDROID : TYPING_INPUT_TYPES;\n        const viewDocument = view.document;\n        viewDocument.on('beforeinput', (evt, data)=>{\n            if (!this.isEnabled) {\n                return;\n            }\n            const { data: text, targetRanges, inputType, domEvent } = data;\n            if (!typingInputTypes.includes(inputType)) {\n                return;\n            }\n            // Mark the latest focus change as complete (we are typing in editable after the focus\n            // so the selection is in the focused element).\n            this.focusObserver.flush();\n            const eventInfo = new EventInfo(viewDocument, 'insertText');\n            viewDocument.fire(eventInfo, new DomEventData(view, domEvent, {\n                text,\n                selection: view.createSelection(targetRanges)\n            }));\n            // Stop the beforeinput event if `delete` event was stopped.\n            // https://github.com/ckeditor/ckeditor5/issues/753\n            if (eventInfo.stop.called) {\n                evt.stop();\n            }\n        });\n        // On Android composition events are immediately applied to the model.\n        // On non-Android the model is updated only on composition end.\n        // On Android we can't rely on composition start/end to update model.\n        if (!env.isAndroid) {\n            // Note: The priority must be lower than the CompositionObserver handler to call it after the renderer is unblocked.\n            // This is important for view to DOM position mapping.\n            // This causes the effect of first remove composed DOM and then reapply it after model modification.\n            viewDocument.on('compositionend', (evt, { data, domEvent })=>{\n                if (!this.isEnabled) {\n                    return;\n                }\n                // In case of aborted composition.\n                if (!data) {\n                    return;\n                }\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconsole.log( `%c[InsertTextObserver]%c Fire insertText event, %c${ JSON.stringify( data ) }`,\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue'\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // }\n                // How do we know where to insert the composed text?\n                // 1. The SelectionObserver is blocked and the view is not updated with the composition changes.\n                // 2. The last moment before it's locked is the `compositionstart` event.\n                // 3. The `SelectionObserver` is listening for `compositionstart` event and immediately converts\n                //    the selection. Handles this at the lowest priority so after the rendering is blocked.\n                viewDocument.fire('insertText', new DomEventData(view, domEvent, {\n                    text: data\n                }));\n            }, {\n                priority: 'lowest'\n            });\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ observe() {}\n    /**\n\t * @inheritDoc\n\t */ stopObserving() {}\n}\n\n/**\n * Handles text input coming from the keyboard or other input methods.\n */ class Input extends Plugin {\n    /**\n\t * The queue of `insertText` command executions that are waiting for the DOM to get updated after beforeinput event.\n\t */ _compositionQueue;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Input';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        const mapper = editor.editing.mapper;\n        const modelSelection = model.document.selection;\n        this._compositionQueue = new CompositionQueue(editor);\n        view.addObserver(InsertTextObserver);\n        // TODO The above default configuration value should be defined using editor.config.define() once it's fixed.\n        const insertTextCommand = new InsertTextCommand(editor, editor.config.get('typing.undoStep') || 20);\n        // Register `insertText` command and add `input` command as an alias for backward compatibility.\n        editor.commands.add('insertText', insertTextCommand);\n        editor.commands.add('input', insertTextCommand);\n        this.listenTo(view.document, 'insertText', (evt, data)=>{\n            // Rendering is disabled while composing so prevent events that will be rendered by the engine\n            // and should not be applied by the browser.\n            if (!view.document.isComposing) {\n                data.preventDefault();\n            }\n            // Flush queue on the next beforeinput event because it could happen\n            // that the mutation observer does not notice the DOM change in time.\n            if (env.isAndroid && view.document.isComposing) {\n                this._compositionQueue.flush('next beforeinput');\n            }\n            const { text, selection: viewSelection } = data;\n            let modelRanges;\n            // If view selection was specified, translate it to model selection.\n            if (viewSelection) {\n                modelRanges = Array.from(viewSelection.getRanges()).map((viewRange)=>mapper.toModelRange(viewRange));\n            } else {\n                modelRanges = Array.from(modelSelection.getRanges());\n            }\n            let insertText = text;\n            // Typing in English on Android is firing composition events for the whole typed word.\n            // We need to check the target range text to only apply the difference.\n            if (env.isAndroid) {\n                const selectedText = Array.from(modelRanges[0].getItems()).reduce((rangeText, node)=>{\n                    return rangeText + (node.is('$textProxy') ? node.data : '');\n                }, '');\n                if (selectedText) {\n                    if (selectedText.length <= insertText.length) {\n                        if (insertText.startsWith(selectedText)) {\n                            insertText = insertText.substring(selectedText.length);\n                            modelRanges[0].start = modelRanges[0].start.getShiftedBy(selectedText.length);\n                        }\n                    } else {\n                        if (selectedText.startsWith(insertText)) {\n                            // TODO this should be mapped as delete?\n                            modelRanges[0].start = modelRanges[0].start.getShiftedBy(insertText.length);\n                            insertText = '';\n                        }\n                    }\n                }\n                if (insertText.length == 0 && modelRanges[0].isCollapsed) {\n                    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                    // @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Ignore insertion of an empty data to the collapsed range.',\n                    // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-style: italic'\n                    // @if CK_DEBUG_TYPING // \t);\n                    // @if CK_DEBUG_TYPING // }\n                    return;\n                }\n            }\n            const commandData = {\n                text: insertText,\n                selection: model.createSelection(modelRanges)\n            };\n            // This is a composition event and those are not cancellable, so we need to wait until browser updates the DOM\n            // and we could apply changes to the model and verify if the DOM is valid.\n            // The browser applies changes to the DOM not immediately on beforeinput event.\n            // We just wait for mutation observer to notice changes or as a fallback a timeout.\n            if (env.isAndroid && view.document.isComposing) {\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconsole.log( `%c[Input]%c Queue insertText:%c \"${ commandData.text }\"%c ` +\n                // @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getFirstPosition().path }]-` +\n                // @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getLastPosition().path }]` +\n                // @if CK_DEBUG_TYPING // \t\t` queue size: ${ this._compositionQueue.length + 1 }`,\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue', ''\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // }\n                this._compositionQueue.push(commandData);\n            } else {\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconsole.log( `%c[Input]%c Execute insertText:%c \"${ commandData.text }\"%c ` +\n                // @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getFirstPosition().path }]-` +\n                // @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getLastPosition().path }]`,\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue', ''\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // }\n                editor.execute('insertText', commandData);\n                view.scrollToTheSelection();\n            }\n        });\n        // Delete selected content on composition start.\n        if (env.isAndroid) {\n            // On Android with English keyboard, the composition starts just by putting caret\n            // at the word end or by selecting a table column. This is not a real composition started.\n            // Trigger delete content on first composition key pressed.\n            this.listenTo(view.document, 'keydown', (evt, data)=>{\n                if (modelSelection.isCollapsed || data.keyCode != 229 || !view.document.isComposing) {\n                    return;\n                }\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconst firstPositionPath = modelSelection.getFirstPosition()!.path;\n                // @if CK_DEBUG_TYPING // \tconst lastPositionPath = modelSelection.getLastPosition()!.path;\n                // @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c KeyDown 229%c -> model.deleteContent() ' +\n                // @if CK_DEBUG_TYPING // \t\t`[${ firstPositionPath }]-[${ lastPositionPath }]`,\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', '',\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // }\n                deleteSelectionContent(model, insertTextCommand);\n            });\n        } else {\n            // Note: The priority must precede the CompositionObserver handler to call it before\n            // the renderer is blocked, because we want to render this change.\n            this.listenTo(view.document, 'compositionstart', ()=>{\n                if (modelSelection.isCollapsed) {\n                    return;\n                }\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconst firstPositionPath = modelSelection.getFirstPosition()!.path;\n                // @if CK_DEBUG_TYPING // \tconst lastPositionPath = modelSelection.getLastPosition()!.path;\n                // @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Composition start%c -> model.deleteContent() ' +\n                // @if CK_DEBUG_TYPING // \t\t`[${ firstPositionPath }]-[${ lastPositionPath }]`,\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', '',\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // }\n                deleteSelectionContent(model, insertTextCommand);\n            });\n        }\n        // Apply composed changes to the model.\n        if (env.isAndroid) {\n            // Apply changes to the model as they are applied to the DOM by the browser.\n            // On beforeinput event, the DOM is not yet modified. We wait for detected mutations to apply model changes.\n            this.listenTo(view.document, 'mutations', (evt, { mutations })=>{\n                if (!view.document.isComposing) {\n                    return;\n                }\n                // Check if mutations are relevant for queued changes.\n                for (const { node } of mutations){\n                    const viewElement = findMappedViewAncestor(node, mapper);\n                    const modelElement = mapper.toModelElement(viewElement);\n                    if (this._compositionQueue.isComposedElement(modelElement)) {\n                        this._compositionQueue.flush('mutations');\n                        return;\n                    }\n                }\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Mutations not related to the composition.',\n            // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-style: italic'\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            });\n            // Make sure that all changes are applied to the model before the end of composition.\n            this.listenTo(view.document, 'compositionend', ()=>{\n                this._compositionQueue.flush('composition end');\n            });\n            // Trigger mutations check after the composition completes to fix all DOM changes that got ignored during composition.\n            // On Android the Renderer is not disabled while composing. While updating DOM nodes we ignore some changes\n            // that are not that important (like NBSP vs plain space character) and could break the composition flow.\n            // After composition is completed we trigger additional `mutations` event for elements affected by the composition\n            // so the Renderer can adjust the DOM to the expected structure without breaking the composition.\n            this.listenTo(view.document, 'compositionend', ()=>{\n                const mutations = [];\n                for (const element of this._compositionQueue.flushComposedElements()){\n                    const viewElement = mapper.toViewElement(element);\n                    if (!viewElement) {\n                        continue;\n                    }\n                    mutations.push({\n                        type: 'children',\n                        node: viewElement\n                    });\n                }\n                if (mutations.length) {\n                    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                    // @if CK_DEBUG_TYPING // \tconsole.group( '%c[Input]%c Fire post-composition mutation fixes.',\n                    // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', 'font-weight: bold', ''\n                    // @if CK_DEBUG_TYPING // \t);\n                    // @if CK_DEBUG_TYPING // }\n                    view.document.fire('mutations', {\n                        mutations\n                    });\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n                // @if CK_DEBUG_TYPING // }\n                }\n            }, {\n                priority: 'lowest'\n            });\n        } else {\n            // After composition end we need to verify if there are no left-overs.\n            // Listening at the lowest priority so after the `InsertTextObserver` added above (all composed text\n            // should already be applied to the model, view, and DOM).\n            // On non-Android the `Renderer` is blocked while user is composing but the `MutationObserver` still collects\n            // mutated nodes and fires `mutations` events.\n            // Those events are recorded by the `Renderer` but not applied to the DOM while composing.\n            // We need to trigger those checks (and fixes) once again but this time without specifying the exact mutations\n            // since they are already recorded by the `Renderer`.\n            // It in the most cases just clears the internal record of mutated text nodes\n            // since all changes should already be applied to the DOM.\n            // This is especially needed when user cancels composition, so we can clear nodes marked to sync.\n            this.listenTo(view.document, 'compositionend', ()=>{\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconsole.group( '%c[Input]%c Force render after composition end.',\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', 'font-weight: bold', ''\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // }\n                view.document.fire('mutations', {\n                    mutations: []\n                });\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n            // @if CK_DEBUG_TYPING // }\n            }, {\n                priority: 'lowest'\n            });\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this._compositionQueue.destroy();\n    }\n}\n/**\n * The queue of `insertText` command executions that are waiting for the DOM to get updated after beforeinput event.\n */ class CompositionQueue {\n    /**\n\t * The editor instance.\n\t */ editor;\n    /**\n\t * Debounced queue flush as a safety mechanism for cases of mutation observer not triggering.\n\t */ flushDebounced = debounce(()=>this.flush('timeout'), 50);\n    /**\n\t * The queue of `insertText` command executions that are waiting for the DOM to get updated after beforeinput event.\n\t */ _queue = [];\n    /**\n\t * A set of model elements. The composition happened in those elements. It's used for mutations check.\n\t */ _compositionElements = new Set();\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        this.editor = editor;\n    }\n    /**\n\t * Destroys the helper object.\n\t */ destroy() {\n        this.flushDebounced.cancel();\n        this._compositionElements.clear();\n        while(this._queue.length){\n            this.shift();\n        }\n    }\n    /**\n\t * Returns the size of the queue.\n\t */ get length() {\n        return this._queue.length;\n    }\n    /**\n\t * Push next insertText command data to the queue.\n\t */ push(commandData) {\n        const commandLiveData = {\n            text: commandData.text\n        };\n        if (commandData.selection) {\n            commandLiveData.selectionRanges = [];\n            for (const range of commandData.selection.getRanges()){\n                commandLiveData.selectionRanges.push(LiveRange.fromRange(range));\n                // Keep reference to the model element for later mutation checks.\n                this._compositionElements.add(range.start.parent);\n            }\n        }\n        this._queue.push(commandLiveData);\n        this.flushDebounced();\n    }\n    /**\n\t * Shift the first item from the insertText command data queue.\n\t */ shift() {\n        const commandLiveData = this._queue.shift();\n        const commandData = {\n            text: commandLiveData.text\n        };\n        if (commandLiveData.selectionRanges) {\n            const ranges = commandLiveData.selectionRanges.map((liveRange)=>detachLiveRange(liveRange)).filter((range)=>!!range);\n            if (ranges.length) {\n                commandData.selection = this.editor.model.createSelection(ranges);\n            }\n        }\n        return commandData;\n    }\n    /**\n\t * Applies all queued insertText command executions.\n\t *\n\t * @param reason Used only for debugging.\n\t */ flush(reason) {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        this.flushDebounced.cancel();\n        if (!this._queue.length) {\n            return;\n        }\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.group( `%c[Input]%c Flush insertText queue on ${ reason }.`,\n        // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold'\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        const insertTextCommand = editor.commands.get('insertText');\n        const buffer = insertTextCommand.buffer;\n        model.enqueueChange(buffer.batch, ()=>{\n            buffer.lock();\n            while(this._queue.length){\n                const commandData = this.shift();\n                // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n                // @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Execute queued insertText:%c ' +\n                // @if CK_DEBUG_TYPING // \t\t`\"${ commandData.text }\"%c ` +\n                // @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getFirstPosition().path }]-` +\n                // @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getLastPosition().path }]`,\n                // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue', ''\n                // @if CK_DEBUG_TYPING // \t);\n                // @if CK_DEBUG_TYPING // }\n                editor.execute('insertText', commandData);\n            }\n            buffer.unlock();\n        });\n        view.scrollToTheSelection();\n    // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n    // @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n    // @if CK_DEBUG_TYPING // }\n    }\n    /**\n\t * Returns `true` if the given model element is related to recent composition.\n\t */ isComposedElement(element) {\n        return this._compositionElements.has(element);\n    }\n    /**\n\t * Returns an array of composition-related elements and clears the internal list.\n\t */ flushComposedElements() {\n        const result = Array.from(this._compositionElements);\n        this._compositionElements.clear();\n        return result;\n    }\n}\n/**\n * Deletes the content selected by the document selection at the start of composition.\n */ function deleteSelectionContent(model, insertTextCommand) {\n    // By relying on the state of the input command we allow disabling the entire input easily\n    // by just disabling the input command. We could’ve used here the delete command but that\n    // would mean requiring the delete feature which would block loading one without the other.\n    // We could also check the editor.isReadOnly property, but that wouldn't allow to block\n    // the input without blocking other features.\n    if (!insertTextCommand.isEnabled) {\n        return;\n    }\n    const buffer = insertTextCommand.buffer;\n    buffer.lock();\n    model.enqueueChange(buffer.batch, ()=>{\n        model.deleteContent(model.document.selection);\n    });\n    buffer.unlock();\n}\n/**\n * Detaches a LiveRange and returns the static range from it.\n */ function detachLiveRange(liveRange) {\n    const range = liveRange.toRange();\n    liveRange.detach();\n    if (range.root.rootName == '$graveyard') {\n        return null;\n    }\n    return range;\n}\n/**\n * For the given `viewNode`, finds and returns the closest ancestor of this node that has a mapping to the model.\n */ function findMappedViewAncestor(viewNode, mapper) {\n    let node = viewNode.is('$text') ? viewNode.parent : viewNode;\n    while(!mapper.toModelElement(node)){\n        node = node.parent;\n    }\n    return node;\n}\n\n/**\n * The delete command. Used by the {@link module:typing/delete~Delete delete feature} to handle the <kbd>Delete</kbd> and\n * <kbd>Backspace</kbd> keys.\n */ class DeleteCommand extends Command {\n    /**\n\t * The directionality of the delete describing in what direction it should\n\t * consume the content when the selection is collapsed.\n\t */ direction;\n    /**\n\t * Delete's change buffer used to group subsequent changes into batches.\n\t */ _buffer;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param direction The directionality of the delete describing in what direction it\n\t * should consume the content when the selection is collapsed.\n\t */ constructor(editor, direction){\n        super(editor);\n        this.direction = direction;\n        this._buffer = new ChangeBuffer(editor.model, editor.config.get('typing.undoStep'));\n        // Since this command may execute on different selectable than selection, it should be checked directly in execute block.\n        this._isEnabledBasedOnSelection = false;\n    }\n    /**\n\t * The current change buffer.\n\t */ get buffer() {\n        return this._buffer;\n    }\n    /**\n\t * Executes the delete command. Depending on whether the selection is collapsed or not, deletes its content\n\t * or a piece of content in the {@link #direction defined direction}.\n\t *\n\t * @fires execute\n\t * @param options The command options.\n\t * @param options.unit See {@link module:engine/model/utils/modifyselection~modifySelection}'s options.\n\t * @param options.sequence A number describing which subsequent delete event it is without the key being released.\n\t * See the {@link module:engine/view/document~Document#event:delete} event data.\n\t * @param options.selection Selection to remove. If not set, current model selection will be used.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const doc = model.document;\n        model.enqueueChange(this._buffer.batch, (writer)=>{\n            this._buffer.lock();\n            const selection = writer.createSelection(options.selection || doc.selection);\n            // Don't execute command when selection is in non-editable place.\n            if (!model.canEditAt(selection)) {\n                return;\n            }\n            const sequence = options.sequence || 1;\n            // Do not replace the whole selected content if selection was collapsed.\n            // This prevents such situation:\n            //\n            // <h1></h1><p>[]</p>\t-->  <h1>[</h1><p>]</p> \t\t-->  <p></p>\n            // starting content\t\t-->   after `modifySelection`\t-->  after `deleteContent`.\n            const doNotResetEntireContent = selection.isCollapsed;\n            // Try to extend the selection in the specified direction.\n            if (selection.isCollapsed) {\n                model.modifySelection(selection, {\n                    direction: this.direction,\n                    unit: options.unit,\n                    treatEmojiAsSingleUnit: true\n                });\n            }\n            // Check if deleting in an empty editor. See #61.\n            if (this._shouldEntireContentBeReplacedWithParagraph(sequence)) {\n                this._replaceEntireContentWithParagraph(writer);\n                return;\n            }\n            // Check if deleting in the first empty block.\n            // See https://github.com/ckeditor/ckeditor5/issues/8137.\n            if (this._shouldReplaceFirstBlockWithParagraph(selection, sequence)) {\n                this.editor.execute('paragraph', {\n                    selection\n                });\n                return;\n            }\n            // If selection is still collapsed, then there's nothing to delete.\n            if (selection.isCollapsed) {\n                return;\n            }\n            let changeCount = 0;\n            selection.getFirstRange().getMinimalFlatRanges().forEach((range)=>{\n                changeCount += count(range.getWalker({\n                    singleCharacters: true,\n                    ignoreElementEnd: true,\n                    shallow: true\n                }));\n            });\n            // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n            // @if CK_DEBUG_TYPING // \tconsole.log( '%c[DeleteCommand]%c Delete content',\n            // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', '',\n            // @if CK_DEBUG_TYPING // \t\t`[${ selection.getFirstPosition()!.path }]-[${ selection.getLastPosition()!.path }]`, options\n            // @if CK_DEBUG_TYPING // \t);\n            // @if CK_DEBUG_TYPING // }\n            model.deleteContent(selection, {\n                doNotResetEntireContent,\n                direction: this.direction\n            });\n            this._buffer.input(changeCount);\n            writer.setSelection(selection);\n            this._buffer.unlock();\n        });\n    }\n    /**\n\t * If the user keeps <kbd>Backspace</kbd> or <kbd>Delete</kbd> key pressed, the content of the current\n\t * editable will be cleared. However, this will not yet lead to resetting the remaining block to a paragraph\n\t * (which happens e.g. when the user does <kbd>Ctrl</kbd> + <kbd>A</kbd>, <kbd>Backspace</kbd>).\n\t *\n\t * But, if the user pressed the key in an empty editable for the first time,\n\t * we want to replace the entire content with a paragraph if:\n\t *\n\t * * the current limit element is empty,\n\t * * the paragraph is allowed in the limit element,\n\t * * the limit doesn't already have a paragraph inside.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5-typing/issues/61.\n\t *\n\t * @param sequence A number describing which subsequent delete event it is without the key being released.\n\t */ _shouldEntireContentBeReplacedWithParagraph(sequence) {\n        // Does nothing if user pressed and held the \"Backspace\" or \"Delete\" key.\n        if (sequence > 1) {\n            return false;\n        }\n        const model = this.editor.model;\n        const doc = model.document;\n        const selection = doc.selection;\n        const limitElement = model.schema.getLimitElement(selection);\n        // If a collapsed selection contains the whole content it means that the content is empty\n        // (from the user perspective).\n        const limitElementIsEmpty = selection.isCollapsed && selection.containsEntireContent(limitElement);\n        if (!limitElementIsEmpty) {\n            return false;\n        }\n        if (!model.schema.checkChild(limitElement, 'paragraph')) {\n            return false;\n        }\n        const limitElementFirstChild = limitElement.getChild(0);\n        // Does nothing if the limit element already contains only a paragraph.\n        // We ignore the case when paragraph might have some inline elements (<p><inlineWidget>[]</inlineWidget></p>)\n        // because we don't support such cases yet and it's unclear whether inlineWidget shouldn't be a limit itself.\n        if (limitElementFirstChild && limitElementFirstChild.is('element', 'paragraph')) {\n            return false;\n        }\n        return true;\n    }\n    /**\n\t * The entire content is replaced with the paragraph. Selection is moved inside the paragraph.\n\t *\n\t * @param writer The model writer.\n\t */ _replaceEntireContentWithParagraph(writer) {\n        const model = this.editor.model;\n        const doc = model.document;\n        const selection = doc.selection;\n        const limitElement = model.schema.getLimitElement(selection);\n        const paragraph = writer.createElement('paragraph');\n        writer.remove(writer.createRangeIn(limitElement));\n        writer.insert(paragraph, limitElement);\n        writer.setSelection(paragraph, 0);\n    }\n    /**\n\t * Checks if the selection is inside an empty element that is the first child of the limit element\n\t * and should be replaced with a paragraph.\n\t *\n\t * @param selection The selection.\n\t * @param sequence A number describing which subsequent delete event it is without the key being released.\n\t */ _shouldReplaceFirstBlockWithParagraph(selection, sequence) {\n        const model = this.editor.model;\n        // Does nothing if user pressed and held the \"Backspace\" key or it was a \"Delete\" button.\n        if (sequence > 1 || this.direction != 'backward') {\n            return false;\n        }\n        if (!selection.isCollapsed) {\n            return false;\n        }\n        const position = selection.getFirstPosition();\n        const limitElement = model.schema.getLimitElement(position);\n        const limitElementFirstChild = limitElement.getChild(0);\n        // Only elements that are direct children of the limit element can be replaced.\n        // Unwrapping from a block quote should be handled in a dedicated feature.\n        if (position.parent != limitElementFirstChild) {\n            return false;\n        }\n        // A block should be replaced only if it was empty.\n        if (!selection.containsEntireContent(limitElementFirstChild)) {\n            return false;\n        }\n        // Replace with a paragraph only if it's allowed there.\n        if (!model.schema.checkChild(limitElement, 'paragraph')) {\n            return false;\n        }\n        // Does nothing if the limit element already contains only a paragraph.\n        if (limitElementFirstChild.name == 'paragraph') {\n            return false;\n        }\n        return true;\n    }\n}\n\nconst DELETE_CHARACTER = 'character';\nconst DELETE_WORD = 'word';\nconst DELETE_CODE_POINT = 'codePoint';\nconst DELETE_SELECTION = 'selection';\nconst DELETE_BACKWARD = 'backward';\nconst DELETE_FORWARD = 'forward';\nconst DELETE_EVENT_TYPES = {\n    // --------------------------------------- Backward delete types -----------------------------------------------------\n    // This happens in Safari on Mac when some content is selected and Ctrl + K is pressed.\n    deleteContent: {\n        unit: DELETE_SELECTION,\n        // According to the Input Events Level 2 spec, this delete type has no direction\n        // but to keep things simple, let's default to backward.\n        direction: DELETE_BACKWARD\n    },\n    // Chrome and Safari on Mac: Backspace or Ctrl + H\n    deleteContentBackward: {\n        // This kind of deletions must be done on the code point-level instead of target range provided by the DOM beforeinput event.\n        // Take for instance \"👨‍👩‍👧‍👧\", it equals:\n        //\n        //\t* [ \"👨\", \"ZERO WIDTH JOINER\", \"👩\", \"ZERO WIDTH JOINER\", \"👧\", \"ZERO WIDTH JOINER\", \"👧\" ]\n        //\t* or simply \"\\u{1F468}\\u200D\\u{1F469}\\u200D\\u{1F467}\\u200D\\u{1F467}\"\n        //\n        // The range provided by the browser would cause the entire multi-byte grapheme to disappear while the user\n        // intention when deleting backwards (\"👨‍👩‍👧‍👧[]\", then backspace) is gradual \"decomposition\" (first to \"👨‍👩‍👧‍[]\",\n        // then to \"👨‍👩‍[]\", etc.).\n        //\n        //\t* \"👨‍👩‍👧‍👧[]\" + backward delete (by code point)  -> results in \"👨‍👩‍👧[]\", removed the last \"👧\" 👍\n        //\t* \"👨‍👩‍👧‍👧[]\" + backward delete (by character)  -> results in \"[]\", removed the whole grapheme 👎\n        //\n        // Deleting by code-point is simply a better UX. See \"deleteContentForward\" to learn more.\n        unit: DELETE_CODE_POINT,\n        direction: DELETE_BACKWARD\n    },\n    // On Mac: Option + Backspace.\n    // On iOS: Hold the backspace for a while and the whole words will start to disappear.\n    deleteWordBackward: {\n        unit: DELETE_WORD,\n        direction: DELETE_BACKWARD\n    },\n    // Safari on Mac: Cmd + Backspace\n    deleteHardLineBackward: {\n        unit: DELETE_SELECTION,\n        direction: DELETE_BACKWARD\n    },\n    // Chrome on Mac: Cmd + Backspace.\n    deleteSoftLineBackward: {\n        unit: DELETE_SELECTION,\n        direction: DELETE_BACKWARD\n    },\n    // --------------------------------------- Forward delete types -----------------------------------------------------\n    // Chrome on Mac: Fn + Backspace or Ctrl + D\n    // Safari on Mac: Ctrl + K or Ctrl + D\n    deleteContentForward: {\n        // Unlike backward delete, this delete must be performed by character instead of by code point, which\n        // provides the best UX for working with accented letters.\n        // Take, for example \"b̂\" (\"\\u0062\\u0302\", or [ \"LATIN SMALL LETTER B\", \"COMBINING CIRCUMFLEX ACCENT\" ]):\n        //\n        //\t* \"b̂[]\" + backward delete (by code point)  -> results in \"b[]\", removed the combining mark 👍\n        //\t* \"[]b̂\" + forward delete (by code point)   -> results in \"[]^\", a bare combining mark does that not make sense when alone 👎\n        //\t* \"[]b̂\" + forward delete (by character)    -> results in \"[]\", removed both \"b\" and the combining mark 👍\n        //\n        // See: \"deleteContentBackward\" to learn more.\n        unit: DELETE_CHARACTER,\n        direction: DELETE_FORWARD\n    },\n    // On Mac: Fn + Option + Backspace.\n    deleteWordForward: {\n        unit: DELETE_WORD,\n        direction: DELETE_FORWARD\n    },\n    // Chrome on Mac: Ctrl + K (you have to disable the Link plugin first, though, because it uses the same keystroke)\n    // This is weird that it does not work in Safari on Mac despite being listed in the official shortcuts listing\n    // on Apple's webpage.\n    deleteHardLineForward: {\n        unit: DELETE_SELECTION,\n        direction: DELETE_FORWARD\n    },\n    // At this moment there is no known way to trigger this event type but let's keep it for the symmetry with\n    // deleteSoftLineBackward.\n    deleteSoftLineForward: {\n        unit: DELETE_SELECTION,\n        direction: DELETE_FORWARD\n    }\n};\n/**\n * Delete observer introduces the {@link module:engine/view/document~Document#event:delete} event.\n */ class DeleteObserver extends Observer {\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        const document = view.document;\n        // It matters how many subsequent deletions were made, e.g. when the backspace key was pressed and held\n        // by the user for some time. For instance, if such scenario ocurred and the heading the selection was\n        // anchored to was the only content of the editor, it will not be converted into a paragraph (the user\n        // wanted to clean it up, not remove it, it's about UX). Check out the DeleteCommand implementation to learn more.\n        //\n        // Fun fact: Safari on Mac won't fire beforeinput for backspace in an empty heading (only content).\n        let sequence = 0;\n        document.on('keydown', ()=>{\n            sequence++;\n        });\n        document.on('keyup', ()=>{\n            sequence = 0;\n        });\n        document.on('beforeinput', (evt, data)=>{\n            if (!this.isEnabled) {\n                return;\n            }\n            const { targetRanges, domEvent, inputType } = data;\n            const deleteEventSpec = DELETE_EVENT_TYPES[inputType];\n            if (!deleteEventSpec) {\n                return;\n            }\n            const deleteData = {\n                direction: deleteEventSpec.direction,\n                unit: deleteEventSpec.unit,\n                sequence\n            };\n            if (deleteData.unit == DELETE_SELECTION) {\n                deleteData.selectionToRemove = view.createSelection(targetRanges[0]);\n            }\n            // The default deletion unit for deleteContentBackward is a single code point\n            // but if the browser provides a wider target range then we should use it.\n            if (inputType === 'deleteContentBackward') {\n                // On Android, deleteContentBackward has sequence 1 by default.\n                if (env.isAndroid) {\n                    deleteData.sequence = 1;\n                }\n                // The beforeInput event wants more than a single character to be removed.\n                if (shouldUseTargetRanges(targetRanges)) {\n                    deleteData.unit = DELETE_SELECTION;\n                    deleteData.selectionToRemove = view.createSelection(targetRanges);\n                }\n            }\n            const eventInfo = new BubblingEventInfo(document, 'delete', targetRanges[0]);\n            document.fire(eventInfo, new DomEventData(view, domEvent, deleteData));\n            // Stop the beforeinput event if `delete` event was stopped.\n            // https://github.com/ckeditor/ckeditor5/issues/753\n            if (eventInfo.stop.called) {\n                evt.stop();\n            }\n        });\n        // TODO: to be removed when https://bugs.chromium.org/p/chromium/issues/detail?id=1365311 is solved.\n        if (env.isBlink) {\n            enableChromeWorkaround(this);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ observe() {}\n    /**\n\t * @inheritDoc\n\t */ stopObserving() {}\n}\n/**\n * Enables workaround for the issue https://github.com/ckeditor/ckeditor5/issues/11904.\n */ function enableChromeWorkaround(observer) {\n    const view = observer.view;\n    const document = view.document;\n    let pressedKeyCode = null;\n    let beforeInputReceived = false;\n    document.on('keydown', (evt, { keyCode })=>{\n        pressedKeyCode = keyCode;\n        beforeInputReceived = false;\n    });\n    document.on('keyup', (evt, { keyCode, domEvent })=>{\n        const selection = document.selection;\n        const shouldFireDeleteEvent = observer.isEnabled && keyCode == pressedKeyCode && isDeleteKeyCode(keyCode) && !selection.isCollapsed && !beforeInputReceived;\n        pressedKeyCode = null;\n        if (shouldFireDeleteEvent) {\n            const targetRange = selection.getFirstRange();\n            const eventInfo = new BubblingEventInfo(document, 'delete', targetRange);\n            const deleteData = {\n                unit: DELETE_SELECTION,\n                direction: getDeleteDirection(keyCode),\n                selectionToRemove: selection\n            };\n            document.fire(eventInfo, new DomEventData(view, domEvent, deleteData));\n        }\n    });\n    document.on('beforeinput', (evt, { inputType })=>{\n        const deleteEventSpec = DELETE_EVENT_TYPES[inputType];\n        const isMatchingBeforeInput = isDeleteKeyCode(pressedKeyCode) && deleteEventSpec && deleteEventSpec.direction == getDeleteDirection(pressedKeyCode);\n        if (isMatchingBeforeInput) {\n            beforeInputReceived = true;\n        }\n    }, {\n        priority: 'high'\n    });\n    document.on('beforeinput', (evt, { inputType, data })=>{\n        const shouldIgnoreBeforeInput = pressedKeyCode == keyCodes.delete && inputType == 'insertText' && data == '\\x7f'; // Delete character :P\n        if (shouldIgnoreBeforeInput) {\n            evt.stop();\n        }\n    }, {\n        priority: 'high'\n    });\n    function isDeleteKeyCode(keyCode) {\n        return keyCode == keyCodes.backspace || keyCode == keyCodes.delete;\n    }\n    function getDeleteDirection(keyCode) {\n        return keyCode == keyCodes.backspace ? DELETE_BACKWARD : DELETE_FORWARD;\n    }\n}\n/**\n * Verifies whether the given target ranges cover more than a single character and should be used instead of a single code-point deletion.\n */ function shouldUseTargetRanges(targetRanges) {\n    // The collapsed target range could happen for example while deleting inside an inline filler\n    // (it's mapped to collapsed position before an inline filler).\n    if (targetRanges.length != 1 || targetRanges[0].isCollapsed) {\n        return false;\n    }\n    const walker = targetRanges[0].getWalker({\n        direction: 'backward',\n        singleCharacters: true,\n        ignoreElementEnd: true\n    });\n    let count = 0;\n    for (const { nextPosition, item } of walker){\n        if (nextPosition.parent.is('$text')) {\n            const data = nextPosition.parent.data;\n            const offset = nextPosition.offset;\n            // Count combined symbols and emoji sequences as a single character.\n            if (isInsideSurrogatePair(data, offset) || isInsideCombinedSymbol(data, offset) || isInsideEmojiSequence(data, offset)) {\n                continue;\n            }\n            count++;\n        } else if (item.is('containerElement') || item.is('emptyElement')) {\n            count++;\n        }\n        if (count > 1) {\n            return true;\n        }\n    }\n    return false;\n}\n\n/**\n * The delete and backspace feature. Handles keys such as <kbd>Delete</kbd> and <kbd>Backspace</kbd>, other\n * keystrokes and user actions that result in deleting content in the editor.\n */ class Delete extends Plugin {\n    /**\n\t * Whether pressing backspace should trigger undo action\n\t */ _undoOnBackspace;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Delete';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const modelDocument = editor.model.document;\n        view.addObserver(DeleteObserver);\n        this._undoOnBackspace = false;\n        const deleteForwardCommand = new DeleteCommand(editor, 'forward');\n        // Register `deleteForward` command and add `forwardDelete` command as an alias for backward compatibility.\n        editor.commands.add('deleteForward', deleteForwardCommand);\n        editor.commands.add('forwardDelete', deleteForwardCommand);\n        editor.commands.add('delete', new DeleteCommand(editor, 'backward'));\n        this.listenTo(viewDocument, 'delete', (evt, data)=>{\n            // When not in composition, we handle the action, so prevent the default one.\n            // When in composition, it's the browser who modify the DOM (renderer is disabled).\n            if (!viewDocument.isComposing) {\n                data.preventDefault();\n            }\n            const { direction, sequence, selectionToRemove, unit } = data;\n            const commandName = direction === 'forward' ? 'deleteForward' : 'delete';\n            const commandData = {\n                sequence\n            };\n            if (unit == 'selection') {\n                const modelRanges = Array.from(selectionToRemove.getRanges()).map((viewRange)=>{\n                    return editor.editing.mapper.toModelRange(viewRange);\n                });\n                commandData.selection = editor.model.createSelection(modelRanges);\n            } else {\n                commandData.unit = unit;\n            }\n            editor.execute(commandName, commandData);\n            view.scrollToTheSelection();\n        }, {\n            priority: 'low'\n        });\n        if (this.editor.plugins.has('UndoEditing')) {\n            this.listenTo(viewDocument, 'delete', (evt, data)=>{\n                if (this._undoOnBackspace && data.direction == 'backward' && data.sequence == 1 && data.unit == 'codePoint') {\n                    this._undoOnBackspace = false;\n                    editor.execute('undo');\n                    data.preventDefault();\n                    evt.stop();\n                }\n            }, {\n                context: '$capture'\n            });\n            this.listenTo(modelDocument, 'change', ()=>{\n                this._undoOnBackspace = false;\n            });\n        }\n    }\n    /**\n\t * If the next user action after calling this method is pressing backspace, it would undo the last change.\n\t *\n\t * Requires {@link module:undo/undoediting~UndoEditing} plugin. If not loaded, does nothing.\n\t */ requestUndoOnBackspace() {\n        if (this.editor.plugins.has('UndoEditing')) {\n            this._undoOnBackspace = true;\n        }\n    }\n}\n\n/**\n * The typing feature. It handles typing.\n *\n * This is a \"glue\" plugin which loads the {@link module:typing/input~Input} and {@link module:typing/delete~Delete}\n * plugins.\n */ class Typing extends Plugin {\n    static get requires() {\n        return [\n            Input,\n            Delete\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Typing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module typing/utils/getlasttextline\n */ /**\n * Returns the last text line from the given range.\n *\n * \"The last text line\" is understood as text (from one or more text nodes) which is limited either by a parent block\n * or by inline elements (e.g. `<softBreak>`).\n *\n * ```ts\n * const rangeToCheck = model.createRange(\n * \tmodel.createPositionAt( paragraph, 0 ),\n * \tmodel.createPositionAt( paragraph, 'end' )\n * );\n *\n * const { text, range } = getLastTextLine( rangeToCheck, model );\n * ```\n *\n * For model below, the returned `text` will be \"Foo bar baz\" and `range` will be set on whole `<paragraph>` content:\n *\n * ```xml\n * <paragraph>Foo bar baz<paragraph>\n * ```\n *\n * However, in below case, `text` will be set to \"baz\" and `range` will be set only on \"baz\".\n *\n * ```xml\n * <paragraph>Foo<softBreak></softBreak>bar<softBreak></softBreak>baz<paragraph>\n * ```\n */ function getLastTextLine(range, model) {\n    let start = range.start;\n    const text = Array.from(range.getWalker({\n        ignoreElementEnd: false\n    })).reduce((rangeText, { item })=>{\n        // Trim text to a last occurrence of an inline element and update range start.\n        if (!(item.is('$text') || item.is('$textProxy'))) {\n            start = model.createPositionAfter(item);\n            return '';\n        }\n        return rangeText + item.data;\n    }, '');\n    return {\n        text,\n        range: model.createRange(start, range.end)\n    };\n}\n\n/**\n * The text watcher feature.\n *\n * Fires the {@link module:typing/textwatcher~TextWatcher#event:matched:data `matched:data`},\n * {@link module:typing/textwatcher~TextWatcher#event:matched:selection `matched:selection`} and\n * {@link module:typing/textwatcher~TextWatcher#event:unmatched `unmatched`} events on typing or selection changes.\n */ class TextWatcher extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * The editor's model.\n\t */ model;\n    /**\n\t * The function used to match the text.\n\t *\n\t * The test callback can return 3 values:\n\t *\n\t * * `false` if there is no match,\n\t * * `true` if there is a match,\n\t * * an object if there is a match and we want to pass some additional information to the {@link #event:matched:data} event.\n\t */ testCallback;\n    /**\n\t * Whether there is a match currently.\n\t */ _hasMatch;\n    /**\n\t * Creates a text watcher instance.\n\t *\n\t * @param testCallback See {@link module:typing/textwatcher~TextWatcher#testCallback}.\n\t */ constructor(model, testCallback){\n        super();\n        this.model = model;\n        this.testCallback = testCallback;\n        this._hasMatch = false;\n        this.set('isEnabled', true);\n        // Toggle text watching on isEnabled state change.\n        this.on('change:isEnabled', ()=>{\n            if (this.isEnabled) {\n                this._startListening();\n            } else {\n                this.stopListening(model.document.selection);\n                this.stopListening(model.document);\n            }\n        });\n        this._startListening();\n    }\n    /**\n\t * Flag indicating whether there is a match currently.\n\t */ get hasMatch() {\n        return this._hasMatch;\n    }\n    /**\n\t * Starts listening to the editor for typing and selection events.\n\t */ _startListening() {\n        const model = this.model;\n        const document = model.document;\n        this.listenTo(document.selection, 'change:range', (evt, { directChange })=>{\n            // Indirect changes (i.e. when the user types or external changes are applied) are handled in the document's change event.\n            if (!directChange) {\n                return;\n            }\n            // Act only on collapsed selection.\n            if (!document.selection.isCollapsed) {\n                if (this.hasMatch) {\n                    this.fire('unmatched');\n                    this._hasMatch = false;\n                }\n                return;\n            }\n            this._evaluateTextBeforeSelection('selection');\n        });\n        this.listenTo(document, 'change:data', (evt, batch)=>{\n            if (batch.isUndo || !batch.isLocal) {\n                return;\n            }\n            this._evaluateTextBeforeSelection('data', {\n                batch\n            });\n        });\n    }\n    /**\n\t * Checks the editor content for matched text.\n\t *\n\t * @fires matched:data\n\t * @fires matched:selection\n\t * @fires unmatched\n\t *\n\t * @param suffix A suffix used for generating the event name.\n\t * @param data Data object for event.\n\t */ _evaluateTextBeforeSelection(suffix, data = {}) {\n        const model = this.model;\n        const document = model.document;\n        const selection = document.selection;\n        const rangeBeforeSelection = model.createRange(model.createPositionAt(selection.focus.parent, 0), selection.focus);\n        const { text, range } = getLastTextLine(rangeBeforeSelection, model);\n        const testResult = this.testCallback(text);\n        if (!testResult && this.hasMatch) {\n            this.fire('unmatched');\n        }\n        this._hasMatch = !!testResult;\n        if (testResult) {\n            const eventData = Object.assign(data, {\n                text,\n                range\n            });\n            // If the test callback returns an object with additional data, assign the data as well.\n            if (typeof testResult == 'object') {\n                Object.assign(eventData, testResult);\n            }\n            this.fire(`matched:${suffix}`, eventData);\n        }\n    }\n}\n\n/**\n * This plugin enables the two-step caret (phantom) movement behavior for\n * {@link module:typing/twostepcaretmovement~TwoStepCaretMovement#registerAttribute registered attributes}\n * on arrow right (<kbd>→</kbd>) and left (<kbd>←</kbd>) key press.\n *\n * Thanks to this (phantom) caret movement the user is able to type before/after as well as at the\n * beginning/end of an attribute.\n *\n * **Note:** This plugin support right–to–left (Arabic, Hebrew, etc.) content by mirroring its behavior\n * but for the sake of simplicity examples showcase only left–to–right use–cases.\n *\n * # Forward movement\n *\n * ## \"Entering\" an attribute:\n *\n * When this plugin is enabled and registered for the `a` attribute and the selection is right before it\n * (at the attribute boundary), pressing the right arrow key will not move the selection but update its\n * attributes accordingly:\n *\n * * When enabled:\n *\n * ```xml\n * foo{}<$text a=\"true\">bar</$text>\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * foo<$text a=\"true\">{}bar</$text>\n * ```\n *\n * * When disabled:\n *\n * ```xml\n * foo{}<$text a=\"true\">bar</$text>\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * foo<$text a=\"true\">b{}ar</$text>\n * ```\n *\n *\n * ## \"Leaving\" an attribute:\n *\n * * When enabled:\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text>baz\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar</$text>{}baz\n * ```\n *\n * * When disabled:\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text>baz\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar</$text>b{}az\n * ```\n *\n * # Backward movement\n *\n * * When enabled:\n *\n * ```xml\n * <$text a=\"true\">bar</$text>{}baz\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text>baz\n * ```\n *\n * * When disabled:\n *\n * ```xml\n * <$text a=\"true\">bar</$text>{}baz\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\">ba{}r</$text>b{}az\n * ```\n *\n * # Multiple attributes\n *\n * * When enabled and many attributes starts or ends at the same position:\n *\n * ```xml\n * <$text a=\"true\" b=\"true\">bar</$text>{}baz\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\" b=\"true\">bar{}</$text>baz\n * ```\n *\n * * When enabled and one procedes another:\n *\n * ```xml\n * <$text a=\"true\">bar</$text><$text b=\"true\">{}bar</$text>\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text><$text b=\"true\">bar</$text>\n * ```\n *\n */ class TwoStepCaretMovement extends Plugin {\n    /**\n\t * A set of attributes to handle.\n\t */ attributes;\n    /**\n\t * The current UID of the overridden gravity, as returned by\n\t * {@link module:engine/model/writer~Writer#overrideSelectionGravity}.\n\t */ _overrideUid;\n    /**\n\t * A flag indicating that the automatic gravity restoration should not happen upon the next\n\t * gravity restoration.\n\t * {@link module:engine/model/selection~Selection#event:change:range} event.\n\t */ _isNextGravityRestorationSkipped = false;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TwoStepCaretMovement';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this.attributes = new Set();\n        this._overrideUid = null;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        const locale = editor.locale;\n        const modelSelection = model.document.selection;\n        // Listen to keyboard events and handle the caret movement according to the 2-step caret logic.\n        this.listenTo(view.document, 'arrowKey', (evt, data)=>{\n            // This implementation works only for collapsed selection.\n            if (!modelSelection.isCollapsed) {\n                return;\n            }\n            // When user tries to expand the selection or jump over the whole word or to the beginning/end then\n            // two-steps movement is not necessary.\n            if (data.shiftKey || data.altKey || data.ctrlKey) {\n                return;\n            }\n            const arrowRightPressed = data.keyCode == keyCodes.arrowright;\n            const arrowLeftPressed = data.keyCode == keyCodes.arrowleft;\n            // When neither left or right arrow has been pressed then do noting.\n            if (!arrowRightPressed && !arrowLeftPressed) {\n                return;\n            }\n            const contentDirection = locale.contentLanguageDirection;\n            let isMovementHandled = false;\n            if (contentDirection === 'ltr' && arrowRightPressed || contentDirection === 'rtl' && arrowLeftPressed) {\n                isMovementHandled = this._handleForwardMovement(data);\n            } else {\n                isMovementHandled = this._handleBackwardMovement(data);\n            }\n            // Stop the keydown event if the two-step caret movement handled it. Avoid collisions\n            // with other features which may also take over the caret movement (e.g. Widget).\n            if (isMovementHandled === true) {\n                evt.stop();\n            }\n        }, {\n            context: '$text',\n            priority: 'highest'\n        });\n        // The automatic gravity restoration logic.\n        this.listenTo(modelSelection, 'change:range', (evt, data)=>{\n            // Skipping the automatic restoration is needed if the selection should change\n            // but the gravity must remain overridden afterwards. See the #handleBackwardMovement\n            // to learn more.\n            if (this._isNextGravityRestorationSkipped) {\n                this._isNextGravityRestorationSkipped = false;\n                return;\n            }\n            // Skip automatic restore when the gravity is not overridden — simply, there's nothing to restore\n            // at this moment.\n            if (!this._isGravityOverridden) {\n                return;\n            }\n            // Skip automatic restore when the change is indirect AND the selection is at the attribute boundary.\n            // It means that e.g. if the change was external (collaboration) and the user had their\n            // selection around the link, its gravity should remain intact in this change:range event.\n            if (!data.directChange && isBetweenDifferentAttributes(modelSelection.getFirstPosition(), this.attributes)) {\n                return;\n            }\n            this._restoreGravity();\n        });\n        // Handle a click at the beginning/end of a two-step element.\n        this._enableClickingAfterNode();\n        // Change the attributes of the selection in certain situations after the two-step node was inserted into the document.\n        this._enableInsertContentSelectionAttributesFixer();\n        // Handle removing the content after the two-step node.\n        this._handleDeleteContentAfterNode();\n    }\n    /**\n\t * Registers a given attribute for the two-step caret movement.\n\t *\n\t * @param attribute Name of the attribute to handle.\n\t */ registerAttribute(attribute) {\n        this.attributes.add(attribute);\n    }\n    /**\n\t * Updates the document selection and the view according to the two–step caret movement state\n\t * when moving **forwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.\n\t *\n\t * @param data Data of the key press.\n\t * @returns `true` when the handler prevented caret movement.\n\t */ _handleForwardMovement(data) {\n        const attributes = this.attributes;\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const position = selection.getFirstPosition();\n        // DON'T ENGAGE 2-SCM if gravity is already overridden. It means that we just entered\n        //\n        // \t\t<paragraph>foo<$text attribute>{}bar</$text>baz</paragraph>\n        //\n        // or left the attribute\n        //\n        // \t\t<paragraph>foo<$text attribute>bar</$text>{}baz</paragraph>\n        //\n        // and the gravity will be restored automatically.\n        if (this._isGravityOverridden) {\n            return false;\n        }\n        // DON'T ENGAGE 2-SCM when the selection is at the beginning of the block AND already has the\n        // attribute:\n        // * when the selection was initially set there using the mouse,\n        // * when the editor has just started\n        //\n        //\t\t<paragraph><$text attribute>{}bar</$text>baz</paragraph>\n        //\n        if (position.isAtStart && hasAnyAttribute(selection, attributes)) {\n            return false;\n        }\n        // ENGAGE 2-SCM When at least one of the observed attributes changes its value (incl. starts, ends).\n        //\n        //\t\t<paragraph>foo<$text attribute>bar{}</$text>baz</paragraph>\n        //\t\t<paragraph>foo<$text attribute>bar{}</$text><$text otherAttribute>baz</$text></paragraph>\n        //\t\t<paragraph>foo<$text attribute=1>bar{}</$text><$text attribute=2>baz</$text></paragraph>\n        //\t\t<paragraph>foo{}<$text attribute>bar</$text>baz</paragraph>\n        //\n        if (isBetweenDifferentAttributes(position, attributes)) {\n            preventCaretMovement(data);\n            // CLEAR 2-SCM attributes if we are at the end of one 2-SCM and before\n            // the next one with a different value of the same attribute.\n            //\n            //\t\t<paragraph>foo<$text attribute=1>bar{}</$text><$text attribute=2>bar</$text>baz</paragraph>\n            //\n            if (hasAnyAttribute(selection, attributes) && isBetweenDifferentAttributes(position, attributes, true)) {\n                clearSelectionAttributes(model, attributes);\n            } else {\n                this._overrideGravity();\n            }\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Updates the document selection and the view according to the two–step caret movement state\n\t * when moving **backwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.\n\t *\n\t * @param data Data of the key press.\n\t * @returns `true` when the handler prevented caret movement\n\t */ _handleBackwardMovement(data) {\n        const attributes = this.attributes;\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const position = selection.getFirstPosition();\n        // When the gravity is already overridden (by this plugin), it means we are on the two-step position.\n        // Prevent the movement, restore the gravity and update selection attributes.\n        //\n        //\t\t<paragraph>foo<$text attribute=1>bar</$text><$text attribute=2>{}baz</$text></paragraph>\n        //\t\t<paragraph>foo<$text attribute>bar</$text><$text otherAttribute>{}baz</$text></paragraph>\n        //\t\t<paragraph>foo<$text attribute>{}bar</$text>baz</paragraph>\n        //\t\t<paragraph>foo<$text attribute>bar</$text>{}baz</paragraph>\n        //\n        if (this._isGravityOverridden) {\n            preventCaretMovement(data);\n            this._restoreGravity();\n            // CLEAR 2-SCM attributes if we are at the end of one 2-SCM and before\n            // the next one with a different value of the same attribute.\n            //\n            //\t\t<paragraph>foo<$text attribute=1>bar</$text><$text attribute=2>{}bar</$text>baz</paragraph>\n            //\n            if (isBetweenDifferentAttributes(position, attributes, true)) {\n                clearSelectionAttributes(model, attributes);\n            } else {\n                setSelectionAttributesFromTheNodeBefore(model, attributes, position);\n            }\n            return true;\n        } else {\n            // REMOVE SELECTION ATTRIBUTE when restoring gravity towards a non-existent content at the\n            // beginning of the block.\n            //\n            // \t\t<paragraph>{}<$text attribute>bar</$text></paragraph>\n            //\n            if (position.isAtStart) {\n                if (hasAnyAttribute(selection, attributes)) {\n                    preventCaretMovement(data);\n                    setSelectionAttributesFromTheNodeBefore(model, attributes, position);\n                    return true;\n                }\n                return false;\n            }\n            // SET 2-SCM attributes if we are between nodes with the same attribute but with different values.\n            //\n            //\t\t<paragraph>foo<$text attribute=1>bar</$text>[]<$text attribute=2>bar</$text>baz</paragraph>\n            //\n            if (!hasAnyAttribute(selection, attributes) && isBetweenDifferentAttributes(position, attributes, true)) {\n                preventCaretMovement(data);\n                setSelectionAttributesFromTheNodeBefore(model, attributes, position);\n                return true;\n            }\n            // When we are moving from natural gravity, to the position of the 2SCM, we need to override the gravity,\n            // and make sure it won't be restored. Unless it's at the end of the block and an observed attribute.\n            // We need to check if the caret is a one position before the attribute boundary:\n            //\n            //\t\t<paragraph>foo<$text attribute=1>bar</$text><$text attribute=2>b{}az</$text></paragraph>\n            //\t\t<paragraph>foo<$text attribute>bar</$text><$text otherAttribute>b{}az</$text></paragraph>\n            //\t\t<paragraph>foo<$text attribute>b{}ar</$text>baz</paragraph>\n            //\t\t<paragraph>foo<$text attribute>bar</$text>b{}az</paragraph>\n            //\n            if (isStepAfterAnyAttributeBoundary(position, attributes)) {\n                // ENGAGE 2-SCM if the selection has no attribute. This may happen when the user\n                // left the attribute using a FORWARD 2-SCM.\n                //\n                // \t\t<paragraph><$text attribute>bar</$text>{}</paragraph>\n                //\n                if (position.isAtEnd && !hasAnyAttribute(selection, attributes) && isBetweenDifferentAttributes(position, attributes)) {\n                    preventCaretMovement(data);\n                    setSelectionAttributesFromTheNodeBefore(model, attributes, position);\n                    return true;\n                }\n                // Skip the automatic gravity restore upon the next selection#change:range event.\n                // If not skipped, it would automatically restore the gravity, which should remain\n                // overridden.\n                this._isNextGravityRestorationSkipped = true;\n                this._overrideGravity();\n                // Don't return \"true\" here because we didn't call _preventCaretMovement.\n                // Returning here will destabilize the filler logic, which also listens to\n                // keydown (and the event would be stopped).\n                return false;\n            }\n        }\n        return false;\n    }\n    /**\n\t * Starts listening to {@link module:engine/view/document~Document#event:mousedown} and\n\t * {@link module:engine/view/document~Document#event:selectionChange} and puts the selection before/after a 2-step node\n\t * if clicked at the beginning/ending of the 2-step node.\n\t *\n\t * The purpose of this action is to allow typing around the 2-step node directly after a click.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/1016.\n\t */ _enableClickingAfterNode() {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        const document = editor.editing.view.document;\n        editor.editing.view.addObserver(MouseObserver);\n        let clicked = false;\n        // Detect the click.\n        this.listenTo(document, 'mousedown', ()=>{\n            clicked = true;\n        });\n        // When the selection has changed...\n        this.listenTo(document, 'selectionChange', ()=>{\n            const attributes = this.attributes;\n            if (!clicked) {\n                return;\n            }\n            // ...and it was caused by the click...\n            clicked = false;\n            // ...and no text is selected...\n            if (!selection.isCollapsed) {\n                return;\n            }\n            // ...and clicked text is the 2-step node...\n            if (!hasAnyAttribute(selection, attributes)) {\n                return;\n            }\n            const position = selection.getFirstPosition();\n            if (!isBetweenDifferentAttributes(position, attributes)) {\n                return;\n            }\n            // The selection at the start of a block would use surrounding attributes\n            // from text after the selection so just clear 2-SCM attributes.\n            //\n            // Also, clear attributes for selection between same attribute with different values.\n            if (position.isAtStart || isBetweenDifferentAttributes(position, attributes, true)) {\n                clearSelectionAttributes(model, attributes);\n            } else if (!this._isGravityOverridden) {\n                this._overrideGravity();\n            }\n        });\n    }\n    /**\n\t * Starts listening to {@link module:engine/model/model~Model#event:insertContent} and corrects the model\n\t * selection attributes if the selection is at the end of a two-step node after inserting the content.\n\t *\n\t * The purpose of this action is to improve the overall UX because the user is no longer \"trapped\" by the\n\t * two-step attribute of the selection, and they can type a \"clean\" (`linkHref`–less) text right away.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/6053.\n\t */ _enableInsertContentSelectionAttributesFixer() {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        const attributes = this.attributes;\n        this.listenTo(model, 'insertContent', ()=>{\n            const position = selection.getFirstPosition();\n            if (hasAnyAttribute(selection, attributes) && isBetweenDifferentAttributes(position, attributes)) {\n                clearSelectionAttributes(model, attributes);\n            }\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether\n\t * removing a content right after the tow-step attribute.\n\t *\n\t * If so, the selection should not preserve the two-step attribute. However, if\n\t * the {@link module:typing/twostepcaretmovement~TwoStepCaretMovement} plugin is active and\n\t * the selection has the two-step attribute due to overridden gravity (at the end), the two-step attribute should stay untouched.\n\t *\n\t * The purpose of this action is to allow removing the link text and keep the selection outside the link.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/7521.\n\t */ _handleDeleteContentAfterNode() {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        const view = editor.editing.view;\n        let isBackspace = false;\n        let shouldPreserveAttributes = false;\n        // Detect pressing `Backspace`.\n        this.listenTo(view.document, 'delete', (evt, data)=>{\n            isBackspace = data.direction === 'backward';\n        }, {\n            priority: 'high'\n        });\n        // Before removing the content, check whether the selection is inside a two-step attribute.\n        // If so, we want to preserve those attributes.\n        this.listenTo(model, 'deleteContent', ()=>{\n            if (!isBackspace) {\n                return;\n            }\n            const position = selection.getFirstPosition();\n            shouldPreserveAttributes = hasAnyAttribute(selection, this.attributes) && !isStepAfterAnyAttributeBoundary(position, this.attributes);\n        }, {\n            priority: 'high'\n        });\n        // After removing the content, check whether the current selection should preserve the `linkHref` attribute.\n        this.listenTo(model, 'deleteContent', ()=>{\n            if (!isBackspace) {\n                return;\n            }\n            isBackspace = false;\n            // Do not escape two-step attribute if it was inside it before content deletion.\n            if (shouldPreserveAttributes) {\n                return;\n            }\n            // Use `model.enqueueChange()` in order to execute the callback at the end of the changes process.\n            editor.model.enqueueChange(()=>{\n                const position = selection.getFirstPosition();\n                if (hasAnyAttribute(selection, this.attributes) && isBetweenDifferentAttributes(position, this.attributes)) {\n                    if (position.isAtStart || isBetweenDifferentAttributes(position, this.attributes, true)) {\n                        clearSelectionAttributes(model, this.attributes);\n                    } else if (!this._isGravityOverridden) {\n                        this._overrideGravity();\n                    }\n                }\n            });\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * `true` when the gravity is overridden for the plugin.\n\t */ get _isGravityOverridden() {\n        return !!this._overrideUid;\n    }\n    /**\n\t * Overrides the gravity using the {@link module:engine/model/writer~Writer model writer}\n\t * and stores the information about this fact in the {@link #_overrideUid}.\n\t *\n\t * A shorthand for {@link module:engine/model/writer~Writer#overrideSelectionGravity}.\n\t */ _overrideGravity() {\n        this._overrideUid = this.editor.model.change((writer)=>{\n            return writer.overrideSelectionGravity();\n        });\n    }\n    /**\n\t * Restores the gravity using the {@link module:engine/model/writer~Writer model writer}.\n\t *\n\t * A shorthand for {@link module:engine/model/writer~Writer#restoreSelectionGravity}.\n\t */ _restoreGravity() {\n        this.editor.model.change((writer)=>{\n            writer.restoreSelectionGravity(this._overrideUid);\n            this._overrideUid = null;\n        });\n    }\n}\n/**\n * Checks whether the selection has any of given attributes.\n */ function hasAnyAttribute(selection, attributes) {\n    for (const observedAttribute of attributes){\n        if (selection.hasAttribute(observedAttribute)) {\n            return true;\n        }\n    }\n    return false;\n}\n/**\n * Applies the given attributes to the current selection using using the\n * values from the node before the current position. Uses\n * the {@link module:engine/model/writer~Writer model writer}.\n */ function setSelectionAttributesFromTheNodeBefore(model, attributes, position) {\n    const nodeBefore = position.nodeBefore;\n    model.change((writer)=>{\n        if (nodeBefore) {\n            const attributes = [];\n            const isInlineObject = model.schema.isObject(nodeBefore) && model.schema.isInline(nodeBefore);\n            for (const [key, value] of nodeBefore.getAttributes()){\n                if (model.schema.checkAttribute('$text', key) && (!isInlineObject || model.schema.getAttributeProperties(key).copyFromObject !== false)) {\n                    attributes.push([\n                        key,\n                        value\n                    ]);\n                }\n            }\n            writer.setSelectionAttribute(attributes);\n        } else {\n            writer.removeSelectionAttribute(attributes);\n        }\n    });\n}\n/**\n * Removes 2-SCM attributes from the selection.\n */ function clearSelectionAttributes(model, attributes) {\n    model.change((writer)=>{\n        writer.removeSelectionAttribute(attributes);\n    });\n}\n/**\n * Prevents the caret movement in the view by calling `preventDefault` on the event data.\n *\n * @alias data.preventDefault\n */ function preventCaretMovement(data) {\n    data.preventDefault();\n}\n/**\n * Checks whether the step before `isBetweenDifferentAttributes()`.\n */ function isStepAfterAnyAttributeBoundary(position, attributes) {\n    const positionBefore = position.getShiftedBy(-1);\n    return isBetweenDifferentAttributes(positionBefore, attributes);\n}\n/**\n * Checks whether the given position is between different values of given attributes.\n */ function isBetweenDifferentAttributes(position, attributes, isStrict = false) {\n    const { nodeBefore, nodeAfter } = position;\n    for (const observedAttribute of attributes){\n        const attrBefore = nodeBefore ? nodeBefore.getAttribute(observedAttribute) : undefined;\n        const attrAfter = nodeAfter ? nodeAfter.getAttribute(observedAttribute) : undefined;\n        if (isStrict && (attrBefore === undefined || attrAfter === undefined)) {\n            continue;\n        }\n        if (attrAfter !== attrBefore) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// All named transformations.\nconst TRANSFORMATIONS = {\n    // Common symbols:\n    copyright: {\n        from: '(c)',\n        to: '©'\n    },\n    registeredTrademark: {\n        from: '(r)',\n        to: '®'\n    },\n    trademark: {\n        from: '(tm)',\n        to: '™'\n    },\n    // Mathematical:\n    oneHalf: {\n        from: /(^|[^/a-z0-9])(1\\/2)([^/a-z0-9])$/i,\n        to: [\n            null,\n            '½',\n            null\n        ]\n    },\n    oneThird: {\n        from: /(^|[^/a-z0-9])(1\\/3)([^/a-z0-9])$/i,\n        to: [\n            null,\n            '⅓',\n            null\n        ]\n    },\n    twoThirds: {\n        from: /(^|[^/a-z0-9])(2\\/3)([^/a-z0-9])$/i,\n        to: [\n            null,\n            '⅔',\n            null\n        ]\n    },\n    oneForth: {\n        from: /(^|[^/a-z0-9])(1\\/4)([^/a-z0-9])$/i,\n        to: [\n            null,\n            '¼',\n            null\n        ]\n    },\n    threeQuarters: {\n        from: /(^|[^/a-z0-9])(3\\/4)([^/a-z0-9])$/i,\n        to: [\n            null,\n            '¾',\n            null\n        ]\n    },\n    lessThanOrEqual: {\n        from: '<=',\n        to: '≤'\n    },\n    greaterThanOrEqual: {\n        from: '>=',\n        to: '≥'\n    },\n    notEqual: {\n        from: '!=',\n        to: '≠'\n    },\n    arrowLeft: {\n        from: '<-',\n        to: '←'\n    },\n    arrowRight: {\n        from: '->',\n        to: '→'\n    },\n    // Typography:\n    horizontalEllipsis: {\n        from: '...',\n        to: '…'\n    },\n    enDash: {\n        from: /(^| )(--)( )$/,\n        to: [\n            null,\n            '–',\n            null\n        ]\n    },\n    emDash: {\n        from: /(^| )(---)( )$/,\n        to: [\n            null,\n            '—',\n            null\n        ]\n    },\n    // Quotations:\n    // English, US\n    quotesPrimary: {\n        from: buildQuotesRegExp('\"'),\n        to: [\n            null,\n            '“',\n            null,\n            '”'\n        ]\n    },\n    quotesSecondary: {\n        from: buildQuotesRegExp('\\''),\n        to: [\n            null,\n            '‘',\n            null,\n            '’'\n        ]\n    },\n    // English, UK\n    quotesPrimaryEnGb: {\n        from: buildQuotesRegExp('\\''),\n        to: [\n            null,\n            '‘',\n            null,\n            '’'\n        ]\n    },\n    quotesSecondaryEnGb: {\n        from: buildQuotesRegExp('\"'),\n        to: [\n            null,\n            '“',\n            null,\n            '”'\n        ]\n    },\n    // Polish\n    quotesPrimaryPl: {\n        from: buildQuotesRegExp('\"'),\n        to: [\n            null,\n            '„',\n            null,\n            '”'\n        ]\n    },\n    quotesSecondaryPl: {\n        from: buildQuotesRegExp('\\''),\n        to: [\n            null,\n            '‚',\n            null,\n            '’'\n        ]\n    }\n};\n// Transformation groups.\nconst TRANSFORMATION_GROUPS = {\n    symbols: [\n        'copyright',\n        'registeredTrademark',\n        'trademark'\n    ],\n    mathematical: [\n        'oneHalf',\n        'oneThird',\n        'twoThirds',\n        'oneForth',\n        'threeQuarters',\n        'lessThanOrEqual',\n        'greaterThanOrEqual',\n        'notEqual',\n        'arrowLeft',\n        'arrowRight'\n    ],\n    typography: [\n        'horizontalEllipsis',\n        'enDash',\n        'emDash'\n    ],\n    quotes: [\n        'quotesPrimary',\n        'quotesSecondary'\n    ]\n};\n// A set of default transformations provided by the feature.\nconst DEFAULT_TRANSFORMATIONS = [\n    'symbols',\n    'mathematical',\n    'typography',\n    'quotes'\n];\n/**\n * The text transformation plugin.\n */ class TextTransformation extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            'Delete',\n            'Input'\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TextTransformation';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('typing', {\n            transformations: {\n                include: DEFAULT_TRANSFORMATIONS\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const model = this.editor.model;\n        const modelSelection = model.document.selection;\n        modelSelection.on('change:range', ()=>{\n            // Disable plugin when selection is inside a code block.\n            this.isEnabled = !modelSelection.anchor.parent.is('element', 'codeBlock');\n        });\n        this._enableTransformationWatchers();\n    }\n    /**\n\t * Create new TextWatcher listening to the editor for typing and selection events.\n\t */ _enableTransformationWatchers() {\n        const editor = this.editor;\n        const model = editor.model;\n        const deletePlugin = editor.plugins.get('Delete');\n        const normalizedTransformations = normalizeTransformations(editor.config.get('typing.transformations'));\n        const testCallback = (text)=>{\n            for (const normalizedTransformation of normalizedTransformations){\n                const from = normalizedTransformation.from;\n                const match = from.test(text);\n                if (match) {\n                    return {\n                        normalizedTransformation\n                    };\n                }\n            }\n        };\n        const watcher = new TextWatcher(editor.model, testCallback);\n        watcher.on('matched:data', (evt, data)=>{\n            if (!data.batch.isTyping) {\n                return;\n            }\n            const { from, to } = data.normalizedTransformation;\n            const matches = from.exec(data.text);\n            const replaces = to(matches.slice(1));\n            const matchedRange = data.range;\n            let changeIndex = matches.index;\n            model.enqueueChange((writer)=>{\n                for(let i = 1; i < matches.length; i++){\n                    const match = matches[i];\n                    const replaceWith = replaces[i - 1];\n                    if (replaceWith == null) {\n                        changeIndex += match.length;\n                        continue;\n                    }\n                    const replacePosition = matchedRange.start.getShiftedBy(changeIndex);\n                    const replaceRange = model.createRange(replacePosition, replacePosition.getShiftedBy(match.length));\n                    const attributes = getTextAttributesAfterPosition(replacePosition);\n                    model.insertContent(writer.createText(replaceWith, attributes), replaceRange);\n                    changeIndex += replaceWith.length;\n                }\n                model.enqueueChange(()=>{\n                    deletePlugin.requestUndoOnBackspace();\n                });\n            });\n        });\n        watcher.bind('isEnabled').to(this);\n    }\n}\n/**\n * Normalizes the configuration `from` parameter value.\n * The normalized value for the `from` parameter is a RegExp instance. If the passed `from` is already a RegExp instance,\n * it is returned unchanged.\n */ function normalizeFrom(from) {\n    if (typeof from == 'string') {\n        return new RegExp(`(${escapeRegExp(from)})$`);\n    }\n    // `from` is already a regular expression.\n    return from;\n}\n/**\n * Normalizes the configuration `to` parameter value.\n * The normalized value for the `to` parameter is a function that takes an array and returns an array. See more in the\n * configuration description. If the passed `to` is already a function, it is returned unchanged.\n */ function normalizeTo(to) {\n    if (typeof to == 'string') {\n        return ()=>[\n                to\n            ];\n    } else if (to instanceof Array) {\n        return ()=>to;\n    }\n    // `to` is already a function.\n    return to;\n}\n/**\n * For given `position` returns attributes for the text that is after that position.\n * The text can be in the same text node as the position (`foo[]bar`) or in the next text node (`foo[]<$text bold=\"true\">bar</$text>`).\n */ function getTextAttributesAfterPosition(position) {\n    const textNode = position.textNode ? position.textNode : position.nodeAfter;\n    return textNode.getAttributes();\n}\n/**\n * Returns a RegExp pattern string that detects a sentence inside a quote.\n *\n * @param quoteCharacter The character to create a pattern for.\n */ function buildQuotesRegExp(quoteCharacter) {\n    return new RegExp(`(^|\\\\s)(${quoteCharacter})([^${quoteCharacter}]*)(${quoteCharacter})$`);\n}\n/**\n * Reads text transformation config and returns normalized array of transformations objects.\n */ function normalizeTransformations(config) {\n    const extra = config.extra || [];\n    const remove = config.remove || [];\n    const isNotRemoved = (transformation)=>!remove.includes(transformation);\n    const configured = config.include.concat(extra).filter(isNotRemoved);\n    return expandGroupsAndRemoveDuplicates(configured).filter(isNotRemoved) // Filter out 'remove' transformations as they might be set in group.\n    .map((transformation)=>typeof transformation == 'string' && TRANSFORMATIONS[transformation] ? TRANSFORMATIONS[transformation] : transformation)// Filter out transformations set as string that has not been found.\n    .filter((transformation)=>typeof transformation === 'object').map((transformation)=>({\n            from: normalizeFrom(transformation.from),\n            to: normalizeTo(transformation.to)\n        }));\n}\n/**\n * Reads definitions and expands named groups if needed to transformation names.\n * This method also removes duplicated named transformations if any.\n */ function expandGroupsAndRemoveDuplicates(definitions) {\n    // Set is using to make sure that transformation names are not duplicated.\n    const definedTransformations = new Set();\n    for (const transformationOrGroup of definitions){\n        if (typeof transformationOrGroup == 'string' && TRANSFORMATION_GROUPS[transformationOrGroup]) {\n            for (const transformation of TRANSFORMATION_GROUPS[transformationOrGroup]){\n                definedTransformations.add(transformation);\n            }\n        } else {\n            definedTransformations.add(transformationOrGroup);\n        }\n    }\n    return Array.from(definedTransformations);\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module typing/utils/findattributerange\n */ /**\n * Returns a model range that covers all consecutive nodes with the same `attributeName` and its `value`\n * that intersect the given `position`.\n *\n * It can be used e.g. to get the entire range on which the `linkHref` attribute needs to be changed when having a\n * selection inside a link.\n *\n * @param position The start position.\n * @param attributeName The attribute name.\n * @param value The attribute value.\n * @param model The model instance.\n * @returns The link range.\n */ function findAttributeRange(position, attributeName, value, model) {\n    return model.createRange(findAttributeRangeBound(position, attributeName, value, true, model), findAttributeRangeBound(position, attributeName, value, false, model));\n}\n/**\n * Walks forward or backward (depends on the `lookBack` flag), node by node, as long as they have the same attribute value\n * and returns a position just before or after (depends on the `lookBack` flag) the last matched node.\n *\n * @param position The start position.\n * @param attributeName The attribute name.\n * @param value The attribute value.\n * @param lookBack Whether the walk direction is forward (`false`) or backward (`true`).\n * @returns The position just before the last matched node.\n */ function findAttributeRangeBound(position, attributeName, value, lookBack, model) {\n    // Get node before or after position (depends on `lookBack` flag).\n    // When position is inside text node then start searching from text node.\n    let node = position.textNode || (lookBack ? position.nodeBefore : position.nodeAfter);\n    let lastNode = null;\n    while(node && node.getAttribute(attributeName) == value){\n        lastNode = node;\n        node = lookBack ? node.previousSibling : node.nextSibling;\n    }\n    return lastNode ? model.createPositionAt(lastNode, lookBack ? 'before' : 'after') : position;\n}\n\n/**\n * Adds a visual highlight style to an attribute element in which the selection is anchored.\n * Together with two-step caret movement, they indicate that the user is typing inside the element.\n *\n * Highlight is turned on by adding the given class to the attribute element in the view:\n *\n * * The class is removed before the conversion has started, as callbacks added with the `'highest'` priority\n * to {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} events.\n * * The class is added in the view post fixer, after other changes in the model tree were converted to the view.\n *\n * This way, adding and removing the highlight does not interfere with conversion.\n *\n * Usage:\n *\n * ```ts\n * import inlineHighlight from '@ckeditor/ckeditor5-typing/src/utils/inlinehighlight';\n *\n * // Make `ck-link_selected` class be applied on an `a` element\n * // whenever the corresponding `linkHref` attribute element is selected.\n * inlineHighlight( editor, 'linkHref', 'a', 'ck-link_selected' );\n * ```\n *\n * @param editor The editor instance.\n * @param attributeName The attribute name to check.\n * @param tagName The tagName of a view item.\n * @param className The class name to apply in the view.\n */ function inlineHighlight(editor, attributeName, tagName, className) {\n    const view = editor.editing.view;\n    const highlightedElements = new Set();\n    // Adding the class.\n    view.document.registerPostFixer((writer)=>{\n        const selection = editor.model.document.selection;\n        let changed = false;\n        if (selection.hasAttribute(attributeName)) {\n            const modelRange = findAttributeRange(selection.getFirstPosition(), attributeName, selection.getAttribute(attributeName), editor.model);\n            const viewRange = editor.editing.mapper.toViewRange(modelRange);\n            // There might be multiple view elements in the `viewRange`, for example, when the `a` element is\n            // broken by a UIElement.\n            for (const item of viewRange.getItems()){\n                if (item.is('element', tagName) && !item.hasClass(className)) {\n                    writer.addClass(className, item);\n                    highlightedElements.add(item);\n                    changed = true;\n                }\n            }\n        }\n        return changed;\n    });\n    // Removing the class.\n    editor.conversion.for('editingDowncast').add((dispatcher)=>{\n        // Make sure the highlight is removed on every possible event, before conversion is started.\n        dispatcher.on('insert', removeHighlight, {\n            priority: 'highest'\n        });\n        dispatcher.on('remove', removeHighlight, {\n            priority: 'highest'\n        });\n        dispatcher.on('attribute', removeHighlight, {\n            priority: 'highest'\n        });\n        dispatcher.on('selection', removeHighlight, {\n            priority: 'highest'\n        });\n        function removeHighlight() {\n            view.change((writer)=>{\n                for (const item of highlightedElements.values()){\n                    writer.removeClass(className, item);\n                    highlightedElements.delete(item);\n                }\n            });\n        }\n    });\n}\n\nexport { Delete, Input, InsertTextCommand, TextTransformation, TextWatcher, TwoStepCaretMovement, Typing, findAttributeRange, findAttributeRangeBound, getLastTextLine, inlineHighlight };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/utils/changebuffer\n */\n\nimport type {\n\tModel,\n\tBatch,\n\tDocumentChangeEvent,\n\tDocumentSelectionChangeEvent\n} from '@ckeditor/ckeditor5-engine';\n\nimport type { EventInfo } from '@ckeditor/ckeditor5-utils';\n\n/**\n * Change buffer allows to group atomic changes (like characters that have been typed) into\n * {@link module:engine/model/batch~Batch batches}.\n *\n * Batches represent single undo steps, hence changes added to one single batch are undone together.\n *\n * The buffer has a configurable limit of atomic changes that it can accommodate. After the limit was\n * exceeded (see {@link ~ChangeBuffer#input}), a new batch is created in {@link ~ChangeBuffer#batch}.\n *\n * To use the change buffer you need to let it know about the number of changes that were added to the batch:\n *\n * ```ts\n * const buffer = new ChangeBuffer( model, LIMIT );\n *\n * // Later on in your feature:\n * buffer.batch.insert( pos, insertedCharacters );\n * buffer.input( insertedCharacters.length );\n * ```\n */\nexport default class ChangeBuffer {\n\t/**\n\t * The model instance.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * The maximum number of atomic changes which can be contained in one batch.\n\t */\n\tpublic readonly limit: number;\n\n\t/**\n\t * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.\n\t */\n\tprivate _isLocked: boolean;\n\n\t/**\n\t * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},\n\t * the {@link #batch batch} is set to a new one.\n\t */\n\tprivate _size: number;\n\n\t/**\n\t * The current batch instance.\n\t */\n\tprivate _batch: Batch | null = null;\n\n\t/**\n\t * The callback to document the change event which later needs to be removed.\n\t */\n\tprivate readonly _changeCallback: ( evt: EventInfo, batch: Batch ) => void;\n\n\t/**\n\t * The callback to document selection `change:attribute` and `change:range` events which resets the buffer.\n\t */\n\tprivate readonly _selectionChangeCallback: () => void;\n\n\t/**\n\t * Creates a new instance of the change buffer.\n\t *\n\t * @param limit The maximum number of atomic changes which can be contained in one batch.\n\t */\n\tconstructor( model: Model, limit: number = 20 ) {\n\t\tthis.model = model;\n\t\tthis._size = 0;\n\t\tthis.limit = limit;\n\t\tthis._isLocked = false;\n\n\t\t// The function to be called in order to notify the buffer about batches which appeared in the document.\n\t\t// The callback will check whether it is a new batch and in that case the buffer will be flushed.\n\t\t//\n\t\t// The reason why the buffer needs to be flushed whenever a new batch appears is that the changes added afterwards\n\t\t// should be added to a new batch. For instance, when the user types, then inserts an image, and then types again,\n\t\t// the characters typed after inserting the image should be added to a different batch than the characters typed before.\n\t\tthis._changeCallback = ( evt, batch ) => {\n\t\t\tif ( batch.isLocal && batch.isUndoable && batch !== this._batch ) {\n\t\t\t\tthis._reset( true );\n\t\t\t}\n\t\t};\n\n\t\tthis._selectionChangeCallback = () => {\n\t\t\tthis._reset();\n\t\t};\n\n\t\tthis.model.document.on<DocumentChangeEvent>( 'change', this._changeCallback );\n\n\t\tthis.model.document.selection.on<DocumentSelectionChangeEvent>( 'change:range', this._selectionChangeCallback );\n\t\tthis.model.document.selection.on<DocumentSelectionChangeEvent>( 'change:attribute', this._selectionChangeCallback );\n\t}\n\n\t/**\n\t * The current batch to which a feature should add its operations. Once the {@link #size}\n\t * is reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t */\n\tpublic get batch(): Batch {\n\t\tif ( !this._batch ) {\n\t\t\tthis._batch = this.model.createBatch( { isTyping: true } );\n\t\t}\n\n\t\treturn this._batch;\n\t}\n\n\t/**\n\t * The number of atomic changes in the buffer. Once it exceeds the {@link #limit},\n\t * the {@link #batch batch} is set to a new one.\n\t */\n\tpublic get size(): number {\n\t\treturn this._size;\n\t}\n\n\t/**\n\t * The input number of changes into the buffer. Once the {@link #size} is\n\t * reached or exceeds the {@link #limit}, the batch is set to a new instance and the size is reset.\n\t *\n\t * @param changeCount The number of atomic changes to input.\n\t */\n\tpublic input( changeCount: number ): void {\n\t\tthis._size += changeCount;\n\n\t\tif ( this._size >= this.limit ) {\n\t\t\tthis._reset( true );\n\t\t}\n\t}\n\n\t/**\n\t * Whether the buffer is locked. A locked buffer cannot be reset unless it gets unlocked.\n\t */\n\tpublic get isLocked(): boolean {\n\t\treturn this._isLocked;\n\t}\n\n\t/**\n\t * Locks the buffer.\n\t */\n\tpublic lock(): void {\n\t\tthis._isLocked = true;\n\t}\n\n\t/**\n\t * Unlocks the buffer.\n\t */\n\tpublic unlock(): void {\n\t\tthis._isLocked = false;\n\t}\n\n\t/**\n\t * Destroys the buffer.\n\t */\n\tpublic destroy(): void {\n\t\tthis.model.document.off( 'change', this._changeCallback );\n\t\tthis.model.document.selection.off( 'change:range', this._selectionChangeCallback );\n\t\tthis.model.document.selection.off( 'change:attribute', this._selectionChangeCallback );\n\t}\n\n\t/**\n\t * Resets the change buffer.\n\t *\n\t * @param ignoreLock Whether internal lock {@link #isLocked} should be ignored.\n\t */\n\tprivate _reset( ignoreLock: boolean = false ): void {\n\t\tif ( !this.isLocked || ignoreLock ) {\n\t\t\tthis._batch = null;\n\t\t\tthis._size = 0;\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/inserttextcommand\n */\n\nimport { Command, type Editor } from '@ckeditor/ckeditor5-core';\n\nimport ChangeBuffer from './utils/changebuffer.js';\n\nimport type { DocumentSelection, Range, Selection } from '@ckeditor/ckeditor5-engine';\n\n/**\n * The insert text command. Used by the {@link module:typing/input~Input input feature} to handle typing.\n */\nexport default class InsertTextCommand extends Command {\n\t/**\n\t * Typing's change buffer used to group subsequent changes into batches.\n\t */\n\tprivate readonly _buffer: ChangeBuffer;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param undoStepSize The maximum number of atomic changes\n\t * which can be contained in one batch in the command buffer.\n\t */\n\tconstructor( editor: Editor, undoStepSize: number ) {\n\t\tsuper( editor );\n\n\t\tthis._buffer = new ChangeBuffer( editor.model, undoStepSize );\n\n\t\t// Since this command may execute on different selectable than selection, it should be checked directly in execute block.\n\t\tthis._isEnabledBasedOnSelection = false;\n\t}\n\n\t/**\n\t * The current change buffer.\n\t */\n\tpublic get buffer(): ChangeBuffer {\n\t\treturn this._buffer;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis._buffer.destroy();\n\t}\n\n\t/**\n\t * Executes the input command. It replaces the content within the given range with the given text.\n\t * Replacing is a two step process, first the content within the range is removed and then the new text is inserted\n\t * at the beginning of the range (which after the removal is a collapsed range).\n\t *\n\t * @fires execute\n\t * @param options The command options.\n\t */\n\tpublic override execute( options: InsertTextCommandOptions = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst text = options.text || '';\n\t\tconst textInsertions = text.length;\n\n\t\tlet selection: Selection | DocumentSelection = doc.selection;\n\n\t\tif ( options.selection ) {\n\t\t\tselection = options.selection;\n\t\t} else if ( options.range ) {\n\t\t\tselection = model.createSelection( options.range );\n\t\t}\n\n\t\t// Stop executing if selectable is in non-editable place.\n\t\tif ( !model.canEditAt( selection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst resultRange = options.resultRange;\n\n\t\tmodel.enqueueChange( this._buffer.batch, writer => {\n\t\t\tthis._buffer.lock();\n\n\t\t\t// Store selection attributes before deleting old content to preserve formatting and link.\n\t\t\t// This unifies the behavior between DocumentSelection and Selection provided as input option.\n\t\t\tconst selectionAttributes = Array.from( doc.selection.getAttributes() );\n\n\t\t\tmodel.deleteContent( selection );\n\n\t\t\tif ( text ) {\n\t\t\t\tmodel.insertContent( writer.createText( text, selectionAttributes ), selection );\n\t\t\t}\n\n\t\t\tif ( resultRange ) {\n\t\t\t\twriter.setSelection( resultRange );\n\t\t\t} else if ( !selection.is( 'documentSelection' ) ) {\n\t\t\t\twriter.setSelection( selection );\n\t\t\t}\n\n\t\t\tthis._buffer.unlock();\n\n\t\t\tthis._buffer.input( textInsertions );\n\t\t} );\n\t}\n}\n\n/**\n * Interface with parameters for executing InsertTextCommand.\n *\n * Both `range` and `selection` parameters are used for defining selection but should not be used together.\n * If both are defined, only `selection` will be considered.\n */\nexport interface InsertTextCommandOptions {\n\n\t/**\n\t * The text to be inserted.\n\t */\n\ttext?: string;\n\n\t/**\n\t * The selection in which the text is inserted.\n\t * Inserting a text into a selection deletes the current content within selection ranges. If the selection is not specified,\n\t * the current selection in the model will be used instead.\n\t */\n\tselection?: Selection | DocumentSelection;\n\n\t/**\n\t * The range in which the text is inserted. Defaults to the first range in the current selection.\n\t */\n\trange?: Range;\n\n\t/**\n\t * The range where the selection should be placed after the insertion.\n\t * If not specified, the selection will be placed right after the inserted text.\n\t */\n\tresultRange?: Range;\n}\n\nexport interface InsertTextCommandExecuteEvent {\n\tname: 'execute';\n\targs: [\n\t\tdata: [ options: InsertTextCommandOptions ]\n\t];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/inserttextobserver\n */\n\nimport { env, EventInfo } from '@ckeditor/ckeditor5-utils';\n\nimport {\n\tDomEventData,\n\tObserver,\n\tFocusObserver,\n\ttype EditingView,\n\ttype ViewDocumentCompositionEndEvent,\n\ttype ViewDocumentInputEvent,\n\ttype ViewDocumentSelection,\n\ttype ViewSelection\n} from '@ckeditor/ckeditor5-engine';\n\nconst TYPING_INPUT_TYPES = [\n\t// For collapsed range:\n\t//\t- This one is a regular typing (all browsers, all systems).\n\t//\t- This one is used by Chrome when typing accented letter – 2nd step when the user selects the accent (Mac).\n\t// For non-collapsed range:\n\t//\t- This one is used by Chrome when typing accented letter – when the selection box first appears (Mac).\n\t//\t- This one is used by Safari when accepting spell check suggestions from the context menu (Mac).\n\t'insertText',\n\n\t// This one is used by Safari when typing accented letter (Mac).\n\t// This one is used by Safari when accepting spell check suggestions from the autocorrection pop-up (Mac).\n\t'insertReplacementText'\n];\n\nconst TYPING_INPUT_TYPES_ANDROID = [\n\t...TYPING_INPUT_TYPES,\n\t'insertCompositionText'\n];\n\n/**\n * Text insertion observer introduces the {@link module:engine/view/document~Document#event:insertText} event.\n */\nexport default class InsertTextObserver extends Observer {\n\t/**\n\t * Instance of the focus observer. Insert text observer calls\n\t * {@link module:engine/view/observer/focusobserver~FocusObserver#flush} to mark the latest focus change as complete.\n\t */\n\tpublic readonly focusObserver: FocusObserver;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: EditingView ) {\n\t\tsuper( view );\n\n\t\tthis.focusObserver = view.getObserver( FocusObserver );\n\n\t\t// On Android composition events should immediately be applied to the model. Rendering is not disabled.\n\t\t// On non-Android the model is updated only on composition end.\n\t\t// On Android we can't rely on composition start/end to update model.\n\t\tconst typingInputTypes = env.isAndroid ? TYPING_INPUT_TYPES_ANDROID : TYPING_INPUT_TYPES;\n\n\t\tconst viewDocument = view.document;\n\n\t\tviewDocument.on<ViewDocumentInputEvent>( 'beforeinput', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { data: text, targetRanges, inputType, domEvent } = data;\n\n\t\t\tif ( !typingInputTypes.includes( inputType ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Mark the latest focus change as complete (we are typing in editable after the focus\n\t\t\t// so the selection is in the focused element).\n\t\t\tthis.focusObserver.flush();\n\n\t\t\tconst eventInfo = new EventInfo( viewDocument, 'insertText' );\n\n\t\t\tviewDocument.fire( eventInfo, new DomEventData( view, domEvent, {\n\t\t\t\ttext,\n\t\t\t\tselection: view.createSelection( targetRanges )\n\t\t\t} ) );\n\n\t\t\t// Stop the beforeinput event if `delete` event was stopped.\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/753\n\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// On Android composition events are immediately applied to the model.\n\t\t// On non-Android the model is updated only on composition end.\n\t\t// On Android we can't rely on composition start/end to update model.\n\t\tif ( !env.isAndroid ) {\n\t\t\t// Note: The priority must be lower than the CompositionObserver handler to call it after the renderer is unblocked.\n\t\t\t// This is important for view to DOM position mapping.\n\t\t\t// This causes the effect of first remove composed DOM and then reapply it after model modification.\n\t\t\tviewDocument.on<ViewDocumentCompositionEndEvent>( 'compositionend', ( evt, { data, domEvent } ) => {\n\t\t\t\tif ( !this.isEnabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// In case of aborted composition.\n\t\t\t\tif ( !data ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( `%c[InsertTextObserver]%c Fire insertText event, %c${ JSON.stringify( data ) }`,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue'\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\t// How do we know where to insert the composed text?\n\t\t\t\t// 1. The SelectionObserver is blocked and the view is not updated with the composition changes.\n\t\t\t\t// 2. The last moment before it's locked is the `compositionstart` event.\n\t\t\t\t// 3. The `SelectionObserver` is listening for `compositionstart` event and immediately converts\n\t\t\t\t//    the selection. Handles this at the lowest priority so after the rendering is blocked.\n\t\t\t\tviewDocument.fire( 'insertText', new DomEventData( view, domEvent, {\n\t\t\t\t\ttext: data\n\t\t\t\t} ) );\n\t\t\t}, { priority: 'lowest' } );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic observe(): void {}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic stopObserving(): void {}\n}\n\n/**\n * Event fired when the user types text, for instance presses <kbd>A</kbd> or <kbd>?</kbd> in the\n * editing view document.\n *\n * **Note**: This event will **not** fire for keystrokes such as <kbd>Delete</kbd> or <kbd>Enter</kbd>.\n * They have dedicated events, see {@link module:engine/view/document~Document#event:delete} and\n * {@link module:engine/view/document~Document#event:enter} to learn more.\n *\n * **Note**: This event is fired by the {@link module:typing/inserttextobserver~InsertTextObserver input feature}.\n *\n * @eventName module:engine/view/document~Document#insertText\n * @param data The event data.\n */\nexport type ViewDocumentInsertTextEvent = {\n\tname: 'insertText';\n\targs: [ data: InsertTextEventData ];\n};\n\nexport interface InsertTextEventData extends DomEventData {\n\n\t/**\n\t *  The text to be inserted.\n\t */\n\ttext: string;\n\n\t/**\n\t * The selection into which the text should be inserted.\n\t * If not specified, the insertion should occur at the current view selection.\n\t */\n\tselection?: ViewSelection | ViewDocumentSelection;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/input\n */\n\nimport { Plugin, type Editor } from '@ckeditor/ckeditor5-core';\nimport { env } from '@ckeditor/ckeditor5-utils';\n\nimport InsertTextCommand, { type InsertTextCommandOptions } from './inserttextcommand.js';\nimport InsertTextObserver, { type ViewDocumentInsertTextEvent } from './inserttextobserver.js';\n\nimport {\n\tLiveRange,\n\ttype Model,\n\ttype Mapper,\n\ttype Element,\n\ttype Range,\n\ttype ViewNode,\n\ttype ViewElement,\n\ttype MutationData,\n\ttype ViewDocumentCompositionStartEvent,\n\ttype ViewDocumentCompositionEndEvent,\n\ttype ViewDocumentKeyDownEvent,\n\ttype ViewDocumentMutationsEvent\n} from '@ckeditor/ckeditor5-engine';\n\nimport { debounce } from 'lodash-es';\n\n/**\n * Handles text input coming from the keyboard or other input methods.\n */\nexport default class Input extends Plugin {\n\t/**\n\t * The queue of `insertText` command executions that are waiting for the DOM to get updated after beforeinput event.\n\t */\n\tprivate _compositionQueue!: CompositionQueue;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Input' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\t\tconst mapper = editor.editing.mapper;\n\t\tconst modelSelection = model.document.selection;\n\n\t\tthis._compositionQueue = new CompositionQueue( editor );\n\n\t\tview.addObserver( InsertTextObserver );\n\n\t\t// TODO The above default configuration value should be defined using editor.config.define() once it's fixed.\n\t\tconst insertTextCommand = new InsertTextCommand( editor, editor.config.get( 'typing.undoStep' ) || 20 );\n\n\t\t// Register `insertText` command and add `input` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'insertText', insertTextCommand );\n\t\teditor.commands.add( 'input', insertTextCommand );\n\n\t\tthis.listenTo<ViewDocumentInsertTextEvent>( view.document, 'insertText', ( evt, data ) => {\n\t\t\t// Rendering is disabled while composing so prevent events that will be rendered by the engine\n\t\t\t// and should not be applied by the browser.\n\t\t\tif ( !view.document.isComposing ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t}\n\n\t\t\t// Flush queue on the next beforeinput event because it could happen\n\t\t\t// that the mutation observer does not notice the DOM change in time.\n\t\t\tif ( env.isAndroid && view.document.isComposing ) {\n\t\t\t\tthis._compositionQueue.flush( 'next beforeinput' );\n\t\t\t}\n\n\t\t\tconst { text, selection: viewSelection } = data;\n\n\t\t\tlet modelRanges;\n\n\t\t\t// If view selection was specified, translate it to model selection.\n\t\t\tif ( viewSelection ) {\n\t\t\t\tmodelRanges = Array.from( viewSelection.getRanges() ).map( viewRange => mapper.toModelRange( viewRange ) );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tmodelRanges = Array.from( modelSelection.getRanges() );\n\t\t\t}\n\n\t\t\tlet insertText = text;\n\n\t\t\t// Typing in English on Android is firing composition events for the whole typed word.\n\t\t\t// We need to check the target range text to only apply the difference.\n\t\t\tif ( env.isAndroid ) {\n\t\t\t\tconst selectedText = Array.from( modelRanges[ 0 ].getItems() ).reduce( ( rangeText, node ) => {\n\t\t\t\t\treturn rangeText + ( node.is( '$textProxy' ) ? node.data : '' );\n\t\t\t\t}, '' );\n\n\t\t\t\tif ( selectedText ) {\n\t\t\t\t\tif ( selectedText.length <= insertText.length ) {\n\t\t\t\t\t\tif ( insertText.startsWith( selectedText ) ) {\n\t\t\t\t\t\t\tinsertText = insertText.substring( selectedText.length );\n\t\t\t\t\t\t\t( modelRanges[ 0 ] as any ).start = modelRanges[ 0 ].start.getShiftedBy( selectedText.length );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( selectedText.startsWith( insertText ) ) {\n\t\t\t\t\t\t\t// TODO this should be mapped as delete?\n\t\t\t\t\t\t\t( modelRanges[ 0 ] as any ).start = modelRanges[ 0 ].start.getShiftedBy( insertText.length );\n\t\t\t\t\t\t\tinsertText = '';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( insertText.length == 0 && modelRanges[ 0 ].isCollapsed ) {\n\t\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Ignore insertion of an empty data to the collapsed range.',\n\t\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-style: italic'\n\t\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst commandData: InsertTextCommandOptions = {\n\t\t\t\ttext: insertText,\n\t\t\t\tselection: model.createSelection( modelRanges )\n\t\t\t};\n\n\t\t\t// This is a composition event and those are not cancellable, so we need to wait until browser updates the DOM\n\t\t\t// and we could apply changes to the model and verify if the DOM is valid.\n\t\t\t// The browser applies changes to the DOM not immediately on beforeinput event.\n\t\t\t// We just wait for mutation observer to notice changes or as a fallback a timeout.\n\t\t\tif ( env.isAndroid && view.document.isComposing ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( `%c[Input]%c Queue insertText:%c \"${ commandData.text }\"%c ` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getFirstPosition().path }]-` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getLastPosition().path }]` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t` queue size: ${ this._compositionQueue.length + 1 }`,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue', ''\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\tthis._compositionQueue.push( commandData );\n\t\t\t} else {\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( `%c[Input]%c Execute insertText:%c \"${ commandData.text }\"%c ` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getFirstPosition().path }]-` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getLastPosition().path }]`,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue', ''\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\teditor.execute( 'insertText', commandData );\n\t\t\t\tview.scrollToTheSelection();\n\t\t\t}\n\t\t} );\n\n\t\t// Delete selected content on composition start.\n\t\tif ( env.isAndroid ) {\n\t\t\t// On Android with English keyboard, the composition starts just by putting caret\n\t\t\t// at the word end or by selecting a table column. This is not a real composition started.\n\t\t\t// Trigger delete content on first composition key pressed.\n\t\t\tthis.listenTo<ViewDocumentKeyDownEvent>( view.document, 'keydown', ( evt, data ) => {\n\t\t\t\tif ( modelSelection.isCollapsed || data.keyCode != 229 || !view.document.isComposing ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconst firstPositionPath = modelSelection.getFirstPosition()!.path;\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconst lastPositionPath = modelSelection.getLastPosition()!.path;\n\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c KeyDown 229%c -> model.deleteContent() ' +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ firstPositionPath }]-[${ lastPositionPath }]`,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', '',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\tdeleteSelectionContent( model, insertTextCommand );\n\t\t\t} );\n\t\t} else {\n\t\t\t// Note: The priority must precede the CompositionObserver handler to call it before\n\t\t\t// the renderer is blocked, because we want to render this change.\n\t\t\tthis.listenTo<ViewDocumentCompositionStartEvent>( view.document, 'compositionstart', () => {\n\t\t\t\tif ( modelSelection.isCollapsed ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconst firstPositionPath = modelSelection.getFirstPosition()!.path;\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconst lastPositionPath = modelSelection.getLastPosition()!.path;\n\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Composition start%c -> model.deleteContent() ' +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ firstPositionPath }]-[${ lastPositionPath }]`,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', '',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\tdeleteSelectionContent( model, insertTextCommand );\n\t\t\t} );\n\t\t}\n\n\t\t// Apply composed changes to the model.\n\t\tif ( env.isAndroid ) {\n\t\t\t// Apply changes to the model as they are applied to the DOM by the browser.\n\t\t\t// On beforeinput event, the DOM is not yet modified. We wait for detected mutations to apply model changes.\n\t\t\tthis.listenTo<ViewDocumentMutationsEvent>( view.document, 'mutations', ( evt, { mutations } ) => {\n\t\t\t\tif ( !view.document.isComposing ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Check if mutations are relevant for queued changes.\n\t\t\t\tfor ( const { node } of mutations ) {\n\t\t\t\t\tconst viewElement = findMappedViewAncestor( node, mapper );\n\t\t\t\t\tconst modelElement = mapper.toModelElement( viewElement )!;\n\n\t\t\t\t\tif ( this._compositionQueue.isComposedElement( modelElement ) ) {\n\t\t\t\t\t\tthis._compositionQueue.flush( 'mutations' );\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Mutations not related to the composition.',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-style: italic'\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t\t} );\n\n\t\t\t// Make sure that all changes are applied to the model before the end of composition.\n\t\t\tthis.listenTo<ViewDocumentCompositionEndEvent>( view.document, 'compositionend', () => {\n\t\t\t\tthis._compositionQueue.flush( 'composition end' );\n\t\t\t} );\n\n\t\t\t// Trigger mutations check after the composition completes to fix all DOM changes that got ignored during composition.\n\t\t\t// On Android the Renderer is not disabled while composing. While updating DOM nodes we ignore some changes\n\t\t\t// that are not that important (like NBSP vs plain space character) and could break the composition flow.\n\t\t\t// After composition is completed we trigger additional `mutations` event for elements affected by the composition\n\t\t\t// so the Renderer can adjust the DOM to the expected structure without breaking the composition.\n\t\t\tthis.listenTo<ViewDocumentCompositionEndEvent>( view.document, 'compositionend', () => {\n\t\t\t\tconst mutations: Array<MutationData> = [];\n\n\t\t\t\tfor ( const element of this._compositionQueue.flushComposedElements() ) {\n\t\t\t\t\tconst viewElement = mapper.toViewElement( element );\n\n\t\t\t\t\tif ( !viewElement ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tmutations.push( { type: 'children', node: viewElement } );\n\t\t\t\t}\n\n\t\t\t\tif ( mutations.length ) {\n\t\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[Input]%c Fire post-composition mutation fixes.',\n\t\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', 'font-weight: bold', ''\n\t\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\t\tview.document.fire<ViewDocumentMutationsEvent>( 'mutations', { mutations } );\n\n\t\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t\t\t}\n\t\t\t}, { priority: 'lowest' } );\n\t\t} else {\n\t\t\t// After composition end we need to verify if there are no left-overs.\n\t\t\t// Listening at the lowest priority so after the `InsertTextObserver` added above (all composed text\n\t\t\t// should already be applied to the model, view, and DOM).\n\t\t\t// On non-Android the `Renderer` is blocked while user is composing but the `MutationObserver` still collects\n\t\t\t// mutated nodes and fires `mutations` events.\n\t\t\t// Those events are recorded by the `Renderer` but not applied to the DOM while composing.\n\t\t\t// We need to trigger those checks (and fixes) once again but this time without specifying the exact mutations\n\t\t\t// since they are already recorded by the `Renderer`.\n\t\t\t// It in the most cases just clears the internal record of mutated text nodes\n\t\t\t// since all changes should already be applied to the DOM.\n\t\t\t// This is especially needed when user cancels composition, so we can clear nodes marked to sync.\n\t\t\tthis.listenTo<ViewDocumentCompositionEndEvent>( view.document, 'compositionend', () => {\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.group( '%c[Input]%c Force render after composition end.',\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', 'font-weight: bold', ''\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\tview.document.fire<ViewDocumentMutationsEvent>( 'mutations', { mutations: [] } );\n\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\t\t\t}, { priority: 'lowest' } );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis._compositionQueue.destroy();\n\t}\n}\n\n/**\n * The queue of `insertText` command executions that are waiting for the DOM to get updated after beforeinput event.\n */\nclass CompositionQueue {\n\t/**\n\t * The editor instance.\n\t */\n\tpublic editor: Editor;\n\n\t/**\n\t * Debounced queue flush as a safety mechanism for cases of mutation observer not triggering.\n\t */\n\tpublic flushDebounced = debounce( () => this.flush( 'timeout' ), 50 );\n\n\t/**\n\t * The queue of `insertText` command executions that are waiting for the DOM to get updated after beforeinput event.\n\t */\n\tprivate _queue: Array<InsertTextCommandLiveOptions> = [];\n\n\t/**\n\t * A set of model elements. The composition happened in those elements. It's used for mutations check.\n\t */\n\tprivate _compositionElements = new Set<Element>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * Destroys the helper object.\n\t */\n\tpublic destroy(): void {\n\t\tthis.flushDebounced.cancel();\n\t\tthis._compositionElements.clear();\n\n\t\twhile ( this._queue.length ) {\n\t\t\tthis.shift();\n\t\t}\n\t}\n\n\t/**\n\t * Returns the size of the queue.\n\t */\n\tpublic get length(): number {\n\t\treturn this._queue.length;\n\t}\n\n\t/**\n\t * Push next insertText command data to the queue.\n\t */\n\tpublic push( commandData: InsertTextCommandOptions ): void {\n\t\tconst commandLiveData: InsertTextCommandLiveOptions = {\n\t\t\ttext: commandData.text\n\t\t};\n\n\t\tif ( commandData.selection ) {\n\t\t\tcommandLiveData.selectionRanges = [];\n\n\t\t\tfor ( const range of commandData.selection.getRanges() ) {\n\t\t\t\tcommandLiveData.selectionRanges.push( LiveRange.fromRange( range ) );\n\n\t\t\t\t// Keep reference to the model element for later mutation checks.\n\t\t\t\tthis._compositionElements.add( range.start.parent as Element );\n\t\t\t}\n\t\t}\n\n\t\tthis._queue.push( commandLiveData );\n\t\tthis.flushDebounced();\n\t}\n\n\t/**\n\t * Shift the first item from the insertText command data queue.\n\t */\n\tpublic shift(): InsertTextCommandOptions {\n\t\tconst commandLiveData = this._queue.shift()!;\n\t\tconst commandData: InsertTextCommandOptions = {\n\t\t\ttext: commandLiveData.text\n\t\t};\n\n\t\tif ( commandLiveData.selectionRanges ) {\n\t\t\tconst ranges = commandLiveData.selectionRanges\n\t\t\t\t.map( liveRange => detachLiveRange( liveRange ) )\n\t\t\t\t.filter( ( range ): range is Range => !!range );\n\n\t\t\tif ( ranges.length ) {\n\t\t\t\tcommandData.selection = this.editor.model.createSelection( ranges );\n\t\t\t}\n\t\t}\n\n\t\treturn commandData;\n\t}\n\n\t/**\n\t * Applies all queued insertText command executions.\n\t *\n\t * @param reason Used only for debugging.\n\t */\n\tpublic flush( reason: string ): void { // eslint-disable-line @typescript-eslint/no-unused-vars\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\n\t\tthis.flushDebounced.cancel();\n\n\t\tif ( !this._queue.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.group( `%c[Input]%c Flush insertText queue on ${ reason }.`,\n\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold'\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tconst insertTextCommand = editor.commands.get( 'insertText' )!;\n\t\tconst buffer = insertTextCommand.buffer;\n\n\t\tmodel.enqueueChange( buffer.batch, () => {\n\t\t\tbuffer.lock();\n\n\t\t\twhile ( this._queue.length ) {\n\t\t\t\tconst commandData = this.shift();\n\n\t\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[Input]%c Execute queued insertText:%c ' +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`\"${ commandData.text }\"%c ` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getFirstPosition().path }]-` +\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ commandData.selection.getLastPosition().path }]`,\n\t\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', 'font-weight: bold', 'color: blue', ''\n\t\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\t\teditor.execute( 'insertText', commandData );\n\t\t\t}\n\n\t\t\tbuffer.unlock();\n\t\t} );\n\n\t\tview.scrollToTheSelection();\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.groupEnd();\n\t\t// @if CK_DEBUG_TYPING // }\n\t}\n\n\t/**\n\t * Returns `true` if the given model element is related to recent composition.\n\t */\n\tpublic isComposedElement( element: Element ): boolean {\n\t\treturn this._compositionElements.has( element );\n\t}\n\n\t/**\n\t * Returns an array of composition-related elements and clears the internal list.\n\t */\n\tpublic flushComposedElements(): Array<Element> {\n\t\tconst result = Array.from( this._compositionElements );\n\n\t\tthis._compositionElements.clear();\n\n\t\treturn result;\n\t}\n}\n\n/**\n * Deletes the content selected by the document selection at the start of composition.\n */\nfunction deleteSelectionContent( model: Model, insertTextCommand: InsertTextCommand ): void {\n\t// By relying on the state of the input command we allow disabling the entire input easily\n\t// by just disabling the input command. We could’ve used here the delete command but that\n\t// would mean requiring the delete feature which would block loading one without the other.\n\t// We could also check the editor.isReadOnly property, but that wouldn't allow to block\n\t// the input without blocking other features.\n\tif ( !insertTextCommand.isEnabled ) {\n\t\treturn;\n\t}\n\n\tconst buffer = insertTextCommand.buffer;\n\n\tbuffer.lock();\n\n\tmodel.enqueueChange( buffer.batch, () => {\n\t\tmodel.deleteContent( model.document.selection );\n\t} );\n\n\tbuffer.unlock();\n}\n\n/**\n * Detaches a LiveRange and returns the static range from it.\n */\nfunction detachLiveRange( liveRange: LiveRange ): Range | null {\n\tconst range = liveRange.toRange();\n\n\tliveRange.detach();\n\n\tif ( range.root.rootName == '$graveyard' ) {\n\t\treturn null;\n\t}\n\n\treturn range;\n}\n\n/**\n * For the given `viewNode`, finds and returns the closest ancestor of this node that has a mapping to the model.\n */\nfunction findMappedViewAncestor( viewNode: ViewNode, mapper: Mapper ): ViewElement {\n\tlet node = ( viewNode.is( '$text' ) ? viewNode.parent : viewNode ) as ViewElement;\n\n\twhile ( !mapper.toModelElement( node ) ) {\n\t\tnode = node.parent as ViewElement;\n\t}\n\n\treturn node;\n}\n\n/**\n * The insertText command data stored as LiveRange-s.\n */\ntype InsertTextCommandLiveOptions = {\n\ttext?: string;\n\tselectionRanges?: Array<LiveRange>;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/deletecommand\n */\n\nimport { Command, type Editor } from '@ckeditor/ckeditor5-core';\nimport { count } from '@ckeditor/ckeditor5-utils';\nimport type { DocumentSelection, Element, Selection, Writer } from '@ckeditor/ckeditor5-engine';\n\nimport ChangeBuffer from './utils/changebuffer.js';\n\n/**\n * The delete command. Used by the {@link module:typing/delete~Delete delete feature} to handle the <kbd>Delete</kbd> and\n * <kbd>Backspace</kbd> keys.\n */\nexport default class DeleteCommand extends Command {\n\t/**\n\t * The directionality of the delete describing in what direction it should\n\t * consume the content when the selection is collapsed.\n\t */\n\tpublic readonly direction: 'forward' | 'backward';\n\n\t/**\n\t * Delete's change buffer used to group subsequent changes into batches.\n\t */\n\tprivate readonly _buffer: ChangeBuffer;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param direction The directionality of the delete describing in what direction it\n\t * should consume the content when the selection is collapsed.\n\t */\n\tconstructor( editor: Editor, direction: 'forward' | 'backward' ) {\n\t\tsuper( editor );\n\n\t\tthis.direction = direction;\n\t\tthis._buffer = new ChangeBuffer( editor.model, editor.config.get( 'typing.undoStep' ) );\n\n\t\t// Since this command may execute on different selectable than selection, it should be checked directly in execute block.\n\t\tthis._isEnabledBasedOnSelection = false;\n\t}\n\n\t/**\n\t * The current change buffer.\n\t */\n\tpublic get buffer(): ChangeBuffer {\n\t\treturn this._buffer;\n\t}\n\n\t/**\n\t * Executes the delete command. Depending on whether the selection is collapsed or not, deletes its content\n\t * or a piece of content in the {@link #direction defined direction}.\n\t *\n\t * @fires execute\n\t * @param options The command options.\n\t * @param options.unit See {@link module:engine/model/utils/modifyselection~modifySelection}'s options.\n\t * @param options.sequence A number describing which subsequent delete event it is without the key being released.\n\t * See the {@link module:engine/view/document~Document#event:delete} event data.\n\t * @param options.selection Selection to remove. If not set, current model selection will be used.\n\t */\n\tpublic override execute( options: {\n\t\tunit?: 'character' | 'codePoint' | 'word';\n\t\tsequence?: number;\n\t\tselection?: Selection | DocumentSelection;\n\t} = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tmodel.enqueueChange( this._buffer.batch, writer => {\n\t\t\tthis._buffer.lock();\n\n\t\t\tconst selection = writer.createSelection( options.selection || doc.selection );\n\n\t\t\t// Don't execute command when selection is in non-editable place.\n\t\t\tif ( !model.canEditAt( selection ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst sequence = options.sequence || 1;\n\n\t\t\t// Do not replace the whole selected content if selection was collapsed.\n\t\t\t// This prevents such situation:\n\t\t\t//\n\t\t\t// <h1></h1><p>[]</p>\t-->  <h1>[</h1><p>]</p> \t\t-->  <p></p>\n\t\t\t// starting content\t\t-->   after `modifySelection`\t-->  after `deleteContent`.\n\t\t\tconst doNotResetEntireContent = selection.isCollapsed;\n\n\t\t\t// Try to extend the selection in the specified direction.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tmodel.modifySelection( selection, {\n\t\t\t\t\tdirection: this.direction,\n\t\t\t\t\tunit: options.unit,\n\t\t\t\t\ttreatEmojiAsSingleUnit: true\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Check if deleting in an empty editor. See #61.\n\t\t\tif ( this._shouldEntireContentBeReplacedWithParagraph( sequence ) ) {\n\t\t\t\tthis._replaceEntireContentWithParagraph( writer );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check if deleting in the first empty block.\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/8137.\n\t\t\tif ( this._shouldReplaceFirstBlockWithParagraph( selection, sequence ) ) {\n\t\t\t\tthis.editor.execute( 'paragraph', { selection } );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If selection is still collapsed, then there's nothing to delete.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet changeCount = 0;\n\n\t\t\tselection.getFirstRange()!.getMinimalFlatRanges().forEach( range => {\n\t\t\t\tchangeCount += count(\n\t\t\t\t\trange.getWalker( { singleCharacters: true, ignoreElementEnd: true, shallow: true } )\n\t\t\t\t);\n\t\t\t} );\n\n\t\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t\t// @if CK_DEBUG_TYPING // \tconsole.log( '%c[DeleteCommand]%c Delete content',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green;', '',\n\t\t\t// @if CK_DEBUG_TYPING // \t\t`[${ selection.getFirstPosition()!.path }]-[${ selection.getLastPosition()!.path }]`, options\n\t\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t\t// @if CK_DEBUG_TYPING // }\n\n\t\t\tmodel.deleteContent( selection, {\n\t\t\t\tdoNotResetEntireContent,\n\t\t\t\tdirection: this.direction\n\t\t\t} );\n\n\t\t\tthis._buffer.input( changeCount );\n\n\t\t\twriter.setSelection( selection );\n\n\t\t\tthis._buffer.unlock();\n\t\t} );\n\t}\n\n\t/**\n\t * If the user keeps <kbd>Backspace</kbd> or <kbd>Delete</kbd> key pressed, the content of the current\n\t * editable will be cleared. However, this will not yet lead to resetting the remaining block to a paragraph\n\t * (which happens e.g. when the user does <kbd>Ctrl</kbd> + <kbd>A</kbd>, <kbd>Backspace</kbd>).\n\t *\n\t * But, if the user pressed the key in an empty editable for the first time,\n\t * we want to replace the entire content with a paragraph if:\n\t *\n\t * * the current limit element is empty,\n\t * * the paragraph is allowed in the limit element,\n\t * * the limit doesn't already have a paragraph inside.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5-typing/issues/61.\n\t *\n\t * @param sequence A number describing which subsequent delete event it is without the key being released.\n\t */\n\tprivate _shouldEntireContentBeReplacedWithParagraph( sequence: number ): boolean {\n\t\t// Does nothing if user pressed and held the \"Backspace\" or \"Delete\" key.\n\t\tif ( sequence > 1 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\t\tconst limitElement = model.schema.getLimitElement( selection );\n\n\t\t// If a collapsed selection contains the whole content it means that the content is empty\n\t\t// (from the user perspective).\n\t\tconst limitElementIsEmpty = selection.isCollapsed && selection.containsEntireContent( limitElement );\n\n\t\tif ( !limitElementIsEmpty ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !model.schema.checkChild( limitElement, 'paragraph' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst limitElementFirstChild = limitElement.getChild( 0 );\n\n\t\t// Does nothing if the limit element already contains only a paragraph.\n\t\t// We ignore the case when paragraph might have some inline elements (<p><inlineWidget>[]</inlineWidget></p>)\n\t\t// because we don't support such cases yet and it's unclear whether inlineWidget shouldn't be a limit itself.\n\t\tif ( limitElementFirstChild && limitElementFirstChild.is( 'element', 'paragraph' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * The entire content is replaced with the paragraph. Selection is moved inside the paragraph.\n\t *\n\t * @param writer The model writer.\n\t */\n\tprivate _replaceEntireContentWithParagraph( writer: Writer ): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\t\tconst limitElement = model.schema.getLimitElement( selection );\n\t\tconst paragraph = writer.createElement( 'paragraph' );\n\n\t\twriter.remove( writer.createRangeIn( limitElement ) );\n\t\twriter.insert( paragraph, limitElement );\n\n\t\twriter.setSelection( paragraph, 0 );\n\t}\n\n\t/**\n\t * Checks if the selection is inside an empty element that is the first child of the limit element\n\t * and should be replaced with a paragraph.\n\t *\n\t * @param selection The selection.\n\t * @param sequence A number describing which subsequent delete event it is without the key being released.\n\t */\n\tprivate _shouldReplaceFirstBlockWithParagraph( selection: Selection, sequence: number ): boolean {\n\t\tconst model = this.editor.model;\n\n\t\t// Does nothing if user pressed and held the \"Backspace\" key or it was a \"Delete\" button.\n\t\tif ( sequence > 1 || this.direction != 'backward' ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst position = selection.getFirstPosition()!;\n\t\tconst limitElement = model.schema.getLimitElement( position );\n\t\tconst limitElementFirstChild = limitElement.getChild( 0 ) as Element;\n\n\t\t// Only elements that are direct children of the limit element can be replaced.\n\t\t// Unwrapping from a block quote should be handled in a dedicated feature.\n\t\tif ( position.parent != limitElementFirstChild ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// A block should be replaced only if it was empty.\n\t\tif ( !selection.containsEntireContent( limitElementFirstChild ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Replace with a paragraph only if it's allowed there.\n\t\tif ( !model.schema.checkChild( limitElement, 'paragraph' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Does nothing if the limit element already contains only a paragraph.\n\t\tif ( limitElementFirstChild.name == 'paragraph' ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/deleteobserver\n */\n\nimport {\n\tenv,\n\tkeyCodes,\n\tisInsideCombinedSymbol,\n\tisInsideEmojiSequence,\n\tisInsideSurrogatePair\n} from '@ckeditor/ckeditor5-utils';\nimport {\n\tBubblingEventInfo,\n\tDomEventData,\n\tObserver,\n\ttype BubblingEvent,\n\ttype ViewDocumentInputEvent,\n\ttype ViewDocumentKeyDownEvent,\n\ttype ViewDocumentKeyUpEvent,\n\ttype ViewDocumentSelection,\n\ttype ViewSelection,\n\ttype ViewRange,\n\ttype EditingView\n} from '@ckeditor/ckeditor5-engine';\n\nconst DELETE_CHARACTER = 'character';\nconst DELETE_WORD = 'word';\nconst DELETE_CODE_POINT = 'codePoint';\nconst DELETE_SELECTION = 'selection';\nconst DELETE_BACKWARD = 'backward';\nconst DELETE_FORWARD = 'forward';\n\ntype DeleteEventSpec = {\n\tunit: 'selection' | 'codePoint' | 'character' | 'word';\n\tdirection: 'backward' | 'forward';\n};\n\nconst DELETE_EVENT_TYPES: Record<string, DeleteEventSpec> = {\n\t// --------------------------------------- Backward delete types -----------------------------------------------------\n\n\t// This happens in Safari on Mac when some content is selected and Ctrl + K is pressed.\n\tdeleteContent: {\n\t\tunit: DELETE_SELECTION,\n\n\t\t// According to the Input Events Level 2 spec, this delete type has no direction\n\t\t// but to keep things simple, let's default to backward.\n\t\tdirection: DELETE_BACKWARD\n\t},\n\t// Chrome and Safari on Mac: Backspace or Ctrl + H\n\tdeleteContentBackward: {\n\t\t// This kind of deletions must be done on the code point-level instead of target range provided by the DOM beforeinput event.\n\t\t// Take for instance \"👨‍👩‍👧‍👧\", it equals:\n\t\t//\n\t\t//\t* [ \"👨\", \"ZERO WIDTH JOINER\", \"👩\", \"ZERO WIDTH JOINER\", \"👧\", \"ZERO WIDTH JOINER\", \"👧\" ]\n\t\t//\t* or simply \"\\u{1F468}\\u200D\\u{1F469}\\u200D\\u{1F467}\\u200D\\u{1F467}\"\n\t\t//\n\t\t// The range provided by the browser would cause the entire multi-byte grapheme to disappear while the user\n\t\t// intention when deleting backwards (\"👨‍👩‍👧‍👧[]\", then backspace) is gradual \"decomposition\" (first to \"👨‍👩‍👧‍[]\",\n\t\t// then to \"👨‍👩‍[]\", etc.).\n\t\t//\n\t\t//\t* \"👨‍👩‍👧‍👧[]\" + backward delete (by code point)  -> results in \"👨‍👩‍👧[]\", removed the last \"👧\" 👍\n\t\t//\t* \"👨‍👩‍👧‍👧[]\" + backward delete (by character)  -> results in \"[]\", removed the whole grapheme 👎\n\t\t//\n\t\t// Deleting by code-point is simply a better UX. See \"deleteContentForward\" to learn more.\n\t\tunit: DELETE_CODE_POINT,\n\t\tdirection: DELETE_BACKWARD\n\t},\n\t// On Mac: Option + Backspace.\n\t// On iOS: Hold the backspace for a while and the whole words will start to disappear.\n\tdeleteWordBackward: {\n\t\tunit: DELETE_WORD,\n\t\tdirection: DELETE_BACKWARD\n\t},\n\t// Safari on Mac: Cmd + Backspace\n\tdeleteHardLineBackward: {\n\t\tunit: DELETE_SELECTION,\n\t\tdirection: DELETE_BACKWARD\n\t},\n\t// Chrome on Mac: Cmd + Backspace.\n\tdeleteSoftLineBackward: {\n\t\tunit: DELETE_SELECTION,\n\t\tdirection: DELETE_BACKWARD\n\t},\n\n\t// --------------------------------------- Forward delete types -----------------------------------------------------\n\n\t// Chrome on Mac: Fn + Backspace or Ctrl + D\n\t// Safari on Mac: Ctrl + K or Ctrl + D\n\tdeleteContentForward: {\n\t\t// Unlike backward delete, this delete must be performed by character instead of by code point, which\n\t\t// provides the best UX for working with accented letters.\n\t\t// Take, for example \"b̂\" (\"\\u0062\\u0302\", or [ \"LATIN SMALL LETTER B\", \"COMBINING CIRCUMFLEX ACCENT\" ]):\n\t\t//\n\t\t//\t* \"b̂[]\" + backward delete (by code point)  -> results in \"b[]\", removed the combining mark 👍\n\t\t//\t* \"[]b̂\" + forward delete (by code point)   -> results in \"[]^\", a bare combining mark does that not make sense when alone 👎\n\t\t//\t* \"[]b̂\" + forward delete (by character)    -> results in \"[]\", removed both \"b\" and the combining mark 👍\n\t\t//\n\t\t// See: \"deleteContentBackward\" to learn more.\n\t\tunit: DELETE_CHARACTER,\n\t\tdirection: DELETE_FORWARD\n\t},\n\t// On Mac: Fn + Option + Backspace.\n\tdeleteWordForward: {\n\t\tunit: DELETE_WORD,\n\t\tdirection: DELETE_FORWARD\n\t},\n\t// Chrome on Mac: Ctrl + K (you have to disable the Link plugin first, though, because it uses the same keystroke)\n\t// This is weird that it does not work in Safari on Mac despite being listed in the official shortcuts listing\n\t// on Apple's webpage.\n\tdeleteHardLineForward: {\n\t\tunit: DELETE_SELECTION,\n\t\tdirection: DELETE_FORWARD\n\t},\n\t// At this moment there is no known way to trigger this event type but let's keep it for the symmetry with\n\t// deleteSoftLineBackward.\n\tdeleteSoftLineForward: {\n\t\tunit: DELETE_SELECTION,\n\t\tdirection: DELETE_FORWARD\n\t}\n};\n\n/**\n * Delete observer introduces the {@link module:engine/view/document~Document#event:delete} event.\n */\nexport default class DeleteObserver extends Observer {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: EditingView ) {\n\t\tsuper( view );\n\n\t\tconst document = view.document;\n\n\t\t// It matters how many subsequent deletions were made, e.g. when the backspace key was pressed and held\n\t\t// by the user for some time. For instance, if such scenario ocurred and the heading the selection was\n\t\t// anchored to was the only content of the editor, it will not be converted into a paragraph (the user\n\t\t// wanted to clean it up, not remove it, it's about UX). Check out the DeleteCommand implementation to learn more.\n\t\t//\n\t\t// Fun fact: Safari on Mac won't fire beforeinput for backspace in an empty heading (only content).\n\t\tlet sequence = 0;\n\n\t\tdocument.on( 'keydown', () => {\n\t\t\tsequence++;\n\t\t} );\n\n\t\tdocument.on( 'keyup', () => {\n\t\t\tsequence = 0;\n\t\t} );\n\n\t\tdocument.on<ViewDocumentInputEvent>( 'beforeinput', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { targetRanges, domEvent, inputType } = data;\n\t\t\tconst deleteEventSpec = DELETE_EVENT_TYPES[ inputType ];\n\n\t\t\tif ( !deleteEventSpec ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst deleteData: Partial<DeleteEventData> = {\n\t\t\t\tdirection: deleteEventSpec.direction,\n\t\t\t\tunit: deleteEventSpec.unit,\n\t\t\t\tsequence\n\t\t\t};\n\n\t\t\tif ( deleteData.unit == DELETE_SELECTION ) {\n\t\t\t\tdeleteData.selectionToRemove = view.createSelection( targetRanges[ 0 ] );\n\t\t\t}\n\n\t\t\t// The default deletion unit for deleteContentBackward is a single code point\n\t\t\t// but if the browser provides a wider target range then we should use it.\n\t\t\tif ( inputType === 'deleteContentBackward' ) {\n\t\t\t\t// On Android, deleteContentBackward has sequence 1 by default.\n\t\t\t\tif ( env.isAndroid ) {\n\t\t\t\t\tdeleteData.sequence = 1;\n\t\t\t\t}\n\n\t\t\t\t// The beforeInput event wants more than a single character to be removed.\n\t\t\t\tif ( shouldUseTargetRanges( targetRanges ) ) {\n\t\t\t\t\tdeleteData.unit = DELETE_SELECTION;\n\t\t\t\t\tdeleteData.selectionToRemove = view.createSelection( targetRanges );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst eventInfo = new BubblingEventInfo( document, 'delete', targetRanges[ 0 ] );\n\n\t\t\tdocument.fire( eventInfo, new DomEventData( view, domEvent, deleteData ) );\n\n\t\t\t// Stop the beforeinput event if `delete` event was stopped.\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/753\n\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// TODO: to be removed when https://bugs.chromium.org/p/chromium/issues/detail?id=1365311 is solved.\n\t\tif ( env.isBlink ) {\n\t\t\tenableChromeWorkaround( this );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic observe(): void {}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic stopObserving(): void {}\n}\n\n/**\n * Event fired when the user tries to delete content (e.g. presses <kbd>Delete</kbd> or <kbd>Backspace</kbd>).\n *\n * Note: This event is fired by the {@link module:typing/deleteobserver~DeleteObserver delete observer}\n * (usually registered by the {@link module:typing/delete~Delete delete feature}).\n *\n * @eventName module:engine/view/document~Document#delete\n * @param data The event data.\n */\nexport type ViewDocumentDeleteEvent = BubblingEvent<{\n\tname: 'delete';\n\targs: [ data: DeleteEventData ];\n}>;\n\nexport interface DeleteEventData extends DomEventData<InputEvent> {\n\n\t/**\n\t * The direction in which the deletion should happen.\n\t */\n\tdirection: 'backward' | 'forward';\n\n\t/**\n\t * The \"amount\" of content that should be deleted.\n\t */\n\tunit: 'selection' | 'codePoint' | 'character' | 'word';\n\n\t/**\n\t * A number describing which subsequent delete event it is without the key being released.\n\t * If it's 2 or more it means that the key was pressed and hold.\n\t */\n\tsequence: number;\n\n\t/**\n\t * View selection which content should be removed. If not set,\n\t * current selection should be used.\n\t */\n\tselectionToRemove?: ViewSelection | ViewDocumentSelection;\n}\n\n/**\n * Enables workaround for the issue https://github.com/ckeditor/ckeditor5/issues/11904.\n */\nfunction enableChromeWorkaround( observer: DeleteObserver ) {\n\tconst view = observer.view;\n\tconst document = view.document;\n\n\tlet pressedKeyCode: number | null = null;\n\tlet beforeInputReceived = false;\n\n\tdocument.on<ViewDocumentKeyDownEvent>( 'keydown', ( evt, { keyCode } ) => {\n\t\tpressedKeyCode = keyCode;\n\t\tbeforeInputReceived = false;\n\t} );\n\n\tdocument.on<ViewDocumentKeyUpEvent>( 'keyup', ( evt, { keyCode, domEvent } ) => {\n\t\tconst selection = document.selection;\n\t\tconst shouldFireDeleteEvent = observer.isEnabled &&\n\t\t\tkeyCode == pressedKeyCode &&\n\t\t\tisDeleteKeyCode( keyCode ) &&\n\t\t\t!selection.isCollapsed &&\n\t\t\t!beforeInputReceived;\n\n\t\tpressedKeyCode = null;\n\n\t\tif ( shouldFireDeleteEvent ) {\n\t\t\tconst targetRange = selection.getFirstRange()!;\n\t\t\tconst eventInfo = new BubblingEventInfo( document, 'delete', targetRange );\n\t\t\tconst deleteData: Partial<DeleteEventData> = {\n\t\t\t\tunit: DELETE_SELECTION,\n\t\t\t\tdirection: getDeleteDirection( keyCode ),\n\t\t\t\tselectionToRemove: selection\n\t\t\t};\n\n\t\t\tdocument.fire( eventInfo, new DomEventData( view, domEvent, deleteData ) );\n\t\t}\n\t} );\n\n\tdocument.on<ViewDocumentInputEvent>( 'beforeinput', ( evt, { inputType } ) => {\n\t\tconst deleteEventSpec = DELETE_EVENT_TYPES[ inputType ];\n\t\tconst isMatchingBeforeInput = isDeleteKeyCode( pressedKeyCode ) &&\n\t\t\tdeleteEventSpec &&\n\t\t\tdeleteEventSpec.direction == getDeleteDirection( pressedKeyCode );\n\n\t\tif ( isMatchingBeforeInput ) {\n\t\t\tbeforeInputReceived = true;\n\t\t}\n\t}, { priority: 'high' } );\n\n\tdocument.on<ViewDocumentInputEvent>( 'beforeinput', ( evt, { inputType, data } ) => {\n\t\tconst shouldIgnoreBeforeInput = pressedKeyCode == keyCodes.delete &&\n\t\t\tinputType == 'insertText' &&\n\t\t\tdata == '\\x7f'; // Delete character :P\n\n\t\tif ( shouldIgnoreBeforeInput ) {\n\t\t\tevt.stop();\n\t\t}\n\t}, { priority: 'high' } );\n\n\tfunction isDeleteKeyCode( keyCode: number | null ): boolean {\n\t\treturn keyCode == keyCodes.backspace || keyCode == keyCodes.delete;\n\t}\n\n\tfunction getDeleteDirection( keyCode: number | null ): 'backward' | 'forward' {\n\t\treturn keyCode == keyCodes.backspace ? DELETE_BACKWARD : DELETE_FORWARD;\n\t}\n}\n\n/**\n * Verifies whether the given target ranges cover more than a single character and should be used instead of a single code-point deletion.\n */\nfunction shouldUseTargetRanges( targetRanges: Array<ViewRange> ): boolean {\n\t// The collapsed target range could happen for example while deleting inside an inline filler\n\t// (it's mapped to collapsed position before an inline filler).\n\tif ( targetRanges.length != 1 || targetRanges[ 0 ].isCollapsed ) {\n\t\treturn false;\n\t}\n\n\tconst walker = targetRanges[ 0 ].getWalker( {\n\t\tdirection: 'backward',\n\t\tsingleCharacters: true,\n\t\tignoreElementEnd: true\n\t} );\n\n\tlet count = 0;\n\n\tfor ( const { nextPosition, item } of walker ) {\n\t\tif ( nextPosition.parent.is( '$text' ) ) {\n\t\t\tconst data = nextPosition.parent.data;\n\t\t\tconst offset = nextPosition.offset;\n\n\t\t\t// Count combined symbols and emoji sequences as a single character.\n\t\t\tif (\n\t\t\t\tisInsideSurrogatePair( data, offset ) ||\n\t\t\t\tisInsideCombinedSymbol( data, offset ) ||\n\t\t\t\tisInsideEmojiSequence( data, offset )\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcount++;\n\t\t} else if ( item.is( 'containerElement' ) || item.is( 'emptyElement' ) ) {\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( count > 1 ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/delete\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport DeleteCommand from './deletecommand.js';\nimport DeleteObserver, { type ViewDocumentDeleteEvent } from './deleteobserver.js';\n\n/**\n * The delete and backspace feature. Handles keys such as <kbd>Delete</kbd> and <kbd>Backspace</kbd>, other\n * keystrokes and user actions that result in deleting content in the editor.\n */\nexport default class Delete extends Plugin {\n\t/**\n\t * Whether pressing backspace should trigger undo action\n\t */\n\tprivate _undoOnBackspace!: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Delete' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst modelDocument = editor.model.document;\n\n\t\tview.addObserver( DeleteObserver );\n\n\t\tthis._undoOnBackspace = false;\n\n\t\tconst deleteForwardCommand = new DeleteCommand( editor, 'forward' );\n\n\t\t// Register `deleteForward` command and add `forwardDelete` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'deleteForward', deleteForwardCommand );\n\t\teditor.commands.add( 'forwardDelete', deleteForwardCommand );\n\n\t\teditor.commands.add( 'delete', new DeleteCommand( editor, 'backward' ) );\n\n\t\tthis.listenTo<ViewDocumentDeleteEvent>( viewDocument, 'delete', ( evt, data ) => {\n\t\t\t// When not in composition, we handle the action, so prevent the default one.\n\t\t\t// When in composition, it's the browser who modify the DOM (renderer is disabled).\n\t\t\tif ( !viewDocument.isComposing ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t}\n\n\t\t\tconst { direction, sequence, selectionToRemove, unit } = data;\n\t\t\tconst commandName = direction === 'forward' ? 'deleteForward' : 'delete';\n\t\t\tconst commandData: Parameters<DeleteCommand[ 'execute' ]>[ 0 ] = { sequence };\n\n\t\t\tif ( unit == 'selection' ) {\n\t\t\t\tconst modelRanges = Array.from( selectionToRemove!.getRanges() ).map( viewRange => {\n\t\t\t\t\treturn editor.editing.mapper.toModelRange( viewRange );\n\t\t\t\t} );\n\n\t\t\t\tcommandData.selection = editor.model.createSelection( modelRanges );\n\t\t\t} else {\n\t\t\t\tcommandData.unit = unit;\n\t\t\t}\n\n\t\t\teditor.execute( commandName, commandData );\n\n\t\t\tview.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\n\t\tif ( this.editor.plugins.has( 'UndoEditing' ) ) {\n\t\t\tthis.listenTo<ViewDocumentDeleteEvent>( viewDocument, 'delete', ( evt, data ) => {\n\t\t\t\tif ( this._undoOnBackspace && data.direction == 'backward' && data.sequence == 1 && data.unit == 'codePoint' ) {\n\t\t\t\t\tthis._undoOnBackspace = false;\n\n\t\t\t\t\teditor.execute( 'undo' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}, { context: '$capture' } );\n\n\t\t\tthis.listenTo( modelDocument, 'change', () => {\n\t\t\t\tthis._undoOnBackspace = false;\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * If the next user action after calling this method is pressing backspace, it would undo the last change.\n\t *\n\t * Requires {@link module:undo/undoediting~UndoEditing} plugin. If not loaded, does nothing.\n\t */\n\tpublic requestUndoOnBackspace(): void {\n\t\tif ( this.editor.plugins.has( 'UndoEditing' ) ) {\n\t\t\tthis._undoOnBackspace = true;\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/typing\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport Input from './input.js';\nimport Delete from './delete.js';\n\n/**\n * The typing feature. It handles typing.\n *\n * This is a \"glue\" plugin which loads the {@link module:typing/input~Input} and {@link module:typing/delete~Delete}\n * plugins.\n */\nexport default class Typing extends Plugin {\n\tpublic static get requires() {\n\t\treturn [ Input, Delete ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Typing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/utils/getlasttextline\n */\n\nimport type { Model, Range } from '@ckeditor/ckeditor5-engine';\n\n/**\n * Returns the last text line from the given range.\n *\n * \"The last text line\" is understood as text (from one or more text nodes) which is limited either by a parent block\n * or by inline elements (e.g. `<softBreak>`).\n *\n * ```ts\n * const rangeToCheck = model.createRange(\n * \tmodel.createPositionAt( paragraph, 0 ),\n * \tmodel.createPositionAt( paragraph, 'end' )\n * );\n *\n * const { text, range } = getLastTextLine( rangeToCheck, model );\n * ```\n *\n * For model below, the returned `text` will be \"Foo bar baz\" and `range` will be set on whole `<paragraph>` content:\n *\n * ```xml\n * <paragraph>Foo bar baz<paragraph>\n * ```\n *\n * However, in below case, `text` will be set to \"baz\" and `range` will be set only on \"baz\".\n *\n * ```xml\n * <paragraph>Foo<softBreak></softBreak>bar<softBreak></softBreak>baz<paragraph>\n * ```\n */\nexport default function getLastTextLine( range: Range, model: Model ): LastTextLineData {\n\tlet start = range.start;\n\n\tconst text = Array.from( range.getWalker( { ignoreElementEnd: false } ) ).reduce( ( rangeText, { item } ) => {\n\t\t// Trim text to a last occurrence of an inline element and update range start.\n\t\tif ( !( item.is( '$text' ) || item.is( '$textProxy' ) ) ) {\n\t\t\tstart = model.createPositionAfter( item );\n\n\t\t\treturn '';\n\t\t}\n\n\t\treturn rangeText + item.data;\n\t}, '' );\n\n\treturn { text, range: model.createRange( start, range.end ) };\n}\n\n/**\n * The value returned by {@link module:typing/utils/getlasttextline~getLastTextLine}.\n */\nexport type LastTextLineData = {\n\n\t/**\n\t * The text from the text nodes in the last text line.\n\t */\n\ttext: string;\n\n\t/**\n\t * The range set on the text nodes in the last text line.\n\t */\n\trange: Range;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/textwatcher\n */\n\nimport { ObservableMixin, type ObservableChangeEvent } from '@ckeditor/ckeditor5-utils';\nimport getLastTextLine from './utils/getlasttextline.js';\n\nimport type {\n\tBatch,\n\tModel,\n\tRange,\n\tDocumentChangeEvent,\n\tDocumentSelectionChangeEvent\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * The text watcher feature.\n *\n * Fires the {@link module:typing/textwatcher~TextWatcher#event:matched:data `matched:data`},\n * {@link module:typing/textwatcher~TextWatcher#event:matched:selection `matched:selection`} and\n * {@link module:typing/textwatcher~TextWatcher#event:unmatched `unmatched`} events on typing or selection changes.\n */\nexport default class TextWatcher extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * The editor's model.\n\t */\n\tpublic readonly model: Model;\n\n\t/**\n\t * The function used to match the text.\n\t *\n\t * The test callback can return 3 values:\n\t *\n\t * * `false` if there is no match,\n\t * * `true` if there is a match,\n\t * * an object if there is a match and we want to pass some additional information to the {@link #event:matched:data} event.\n\t */\n\tpublic testCallback: ( text: string ) => unknown;\n\n\t/**\n\t * Whether there is a match currently.\n\t */\n\tprivate _hasMatch: boolean;\n\n\t/**\n\t * Flag indicating whether the `TextWatcher` instance is enabled or disabled.\n\t * A disabled TextWatcher will not evaluate text.\n\t *\n\t * To disable TextWatcher:\n\t *\n\t * ```ts\n\t * const watcher = new TextWatcher( editor.model, testCallback );\n\t *\n\t * // After this a testCallback will not be called.\n\t * watcher.isEnabled = false;\n\t * ```\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * Creates a text watcher instance.\n\t *\n\t * @param testCallback See {@link module:typing/textwatcher~TextWatcher#testCallback}.\n\t */\n\tconstructor( model: Model, testCallback: ( text: string ) => unknown ) {\n\t\tsuper();\n\n\t\tthis.model = model;\n\t\tthis.testCallback = testCallback;\n\t\tthis._hasMatch = false;\n\n\t\tthis.set( 'isEnabled', true );\n\n\t\t// Toggle text watching on isEnabled state change.\n\t\tthis.on<ObservableChangeEvent>( 'change:isEnabled', () => {\n\t\t\tif ( this.isEnabled ) {\n\t\t\t\tthis._startListening();\n\t\t\t} else {\n\t\t\t\tthis.stopListening( model.document.selection );\n\t\t\t\tthis.stopListening( model.document );\n\t\t\t}\n\t\t} );\n\n\t\tthis._startListening();\n\t}\n\n\t/**\n\t * Flag indicating whether there is a match currently.\n\t */\n\tpublic get hasMatch(): boolean {\n\t\treturn this._hasMatch;\n\t}\n\n\t/**\n\t * Starts listening to the editor for typing and selection events.\n\t */\n\tprivate _startListening(): void {\n\t\tconst model = this.model;\n\t\tconst document = model.document;\n\n\t\tthis.listenTo<DocumentSelectionChangeEvent>( document.selection, 'change:range', ( evt, { directChange } ) => {\n\t\t\t// Indirect changes (i.e. when the user types or external changes are applied) are handled in the document's change event.\n\t\t\tif ( !directChange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Act only on collapsed selection.\n\t\t\tif ( !document.selection.isCollapsed ) {\n\t\t\t\tif ( this.hasMatch ) {\n\t\t\t\t\tthis.fire( 'unmatched' );\n\t\t\t\t\tthis._hasMatch = false;\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._evaluateTextBeforeSelection( 'selection' );\n\t\t} );\n\n\t\tthis.listenTo<DocumentChangeEvent>( document, 'change:data', ( evt, batch ) => {\n\t\t\tif ( batch.isUndo || !batch.isLocal ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._evaluateTextBeforeSelection( 'data', { batch } );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the editor content for matched text.\n\t *\n\t * @fires matched:data\n\t * @fires matched:selection\n\t * @fires unmatched\n\t *\n\t * @param suffix A suffix used for generating the event name.\n\t * @param data Data object for event.\n\t */\n\tprivate _evaluateTextBeforeSelection( suffix: 'data' | 'selection', data: { batch?: Batch } = {} ): void {\n\t\tconst model = this.model;\n\t\tconst document = model.document;\n\t\tconst selection = document.selection;\n\n\t\tconst rangeBeforeSelection = model.createRange( model.createPositionAt( selection.focus!.parent, 0 ), selection.focus! );\n\n\t\tconst { text, range } = getLastTextLine( rangeBeforeSelection, model );\n\n\t\tconst testResult = this.testCallback( text );\n\n\t\tif ( !testResult && this.hasMatch ) {\n\t\t\tthis.fire<TextWatcherUnmatchedEvent>( 'unmatched' );\n\t\t}\n\n\t\tthis._hasMatch = !!testResult;\n\n\t\tif ( testResult ) {\n\t\t\tconst eventData = Object.assign( data, { text, range } );\n\n\t\t\t// If the test callback returns an object with additional data, assign the data as well.\n\t\t\tif ( typeof testResult == 'object' ) {\n\t\t\t\tObject.assign( eventData, testResult );\n\t\t\t}\n\n\t\t\tthis.fire<TextWatcherMatchedEvent>( `matched:${ suffix }`, eventData );\n\t\t}\n\t}\n}\n\nexport type TextWatcherMatchedEvent<TCallbackResult extends Record<string, unknown> = Record<string, unknown>> = {\n\tname: 'matched' | 'matched:data' | 'matched:selection';\n\targs: [ {\n\t\ttext: string;\n\t\trange: Range;\n\t\tbatch?: Batch;\n\t} & TCallbackResult ];\n};\n\n/**\n * Fired whenever the text watcher found a match for data changes.\n *\n * @eventName ~TextWatcher#matched:data\n * @param data Event data.\n * @param data.testResult The additional data returned from the {@link module:typing/textwatcher~TextWatcher#testCallback}.\n */\nexport type TextWatcherMatchedDataEvent<TCallbackResult extends Record<string, unknown>> = {\n\tname: 'matched:data';\n\targs: [ data: TextWatcherMatchedDataEventData & TCallbackResult ];\n};\n\nexport interface TextWatcherMatchedDataEventData {\n\n\t/**\n\t * The full text before selection to which the regexp was applied.\n\t */\n\ttext: string;\n\n\t/**\n\t * The range representing the position of the `data.text`.\n\t */\n\trange: Range;\n\n\tbatch: Batch;\n}\n\n/**\n * Fired whenever the text watcher found a match for selection changes.\n *\n * @eventName ~TextWatcher#matched:selection\n * @param data Event data.\n * @param data.testResult The additional data returned from the {@link module:typing/textwatcher~TextWatcher#testCallback}.\n */\nexport type TextWatcherMatchedSelectionEvent<TCallbackResult extends Record<string, unknown>> = {\n\tname: 'matched:selection';\n\targs: [ data: TextWatcherMatchedSelectionEventData & TCallbackResult ];\n};\n\nexport interface TextWatcherMatchedSelectionEventData {\n\n\t/**\n\t * The full text before selection.\n\t */\n\ttext: string;\n\n\t/**\n\t * The range representing the position of the `data.text`.\n\t */\n\trange: Range;\n}\n\n/**\n * Fired whenever the text does not match anymore. Fired only when the text watcher found a match.\n *\n * @eventName ~TextWatcher#unmatched\n */\nexport type TextWatcherUnmatchedEvent = {\n\tname: 'unmatched';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/twostepcaretmovement\n */\n\nimport { Plugin, type Editor } from '@ckeditor/ckeditor5-core';\n\nimport { keyCodes } from '@ckeditor/ckeditor5-utils';\n\nimport {\n\tMouseObserver,\n\ttype DocumentSelection,\n\ttype DocumentSelectionChangeRangeEvent,\n\ttype DomEventData,\n\ttype Model,\n\ttype Position,\n\ttype ViewDocumentArrowKeyEvent,\n\ttype ViewDocumentMouseDownEvent,\n\ttype ViewDocumentSelectionChangeEvent,\n\ttype ModelInsertContentEvent,\n\ttype ModelDeleteContentEvent\n} from '@ckeditor/ckeditor5-engine';\n\nimport type { ViewDocumentDeleteEvent } from './deleteobserver.js';\n\n/**\n * This plugin enables the two-step caret (phantom) movement behavior for\n * {@link module:typing/twostepcaretmovement~TwoStepCaretMovement#registerAttribute registered attributes}\n * on arrow right (<kbd>→</kbd>) and left (<kbd>←</kbd>) key press.\n *\n * Thanks to this (phantom) caret movement the user is able to type before/after as well as at the\n * beginning/end of an attribute.\n *\n * **Note:** This plugin support right–to–left (Arabic, Hebrew, etc.) content by mirroring its behavior\n * but for the sake of simplicity examples showcase only left–to–right use–cases.\n *\n * # Forward movement\n *\n * ## \"Entering\" an attribute:\n *\n * When this plugin is enabled and registered for the `a` attribute and the selection is right before it\n * (at the attribute boundary), pressing the right arrow key will not move the selection but update its\n * attributes accordingly:\n *\n * * When enabled:\n *\n * ```xml\n * foo{}<$text a=\"true\">bar</$text>\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * foo<$text a=\"true\">{}bar</$text>\n * ```\n *\n * * When disabled:\n *\n * ```xml\n * foo{}<$text a=\"true\">bar</$text>\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * foo<$text a=\"true\">b{}ar</$text>\n * ```\n *\n *\n * ## \"Leaving\" an attribute:\n *\n * * When enabled:\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text>baz\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar</$text>{}baz\n * ```\n *\n * * When disabled:\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text>baz\n * ```\n *\n * \t<kbd>→</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar</$text>b{}az\n * ```\n *\n * # Backward movement\n *\n * * When enabled:\n *\n * ```xml\n * <$text a=\"true\">bar</$text>{}baz\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text>baz\n * ```\n *\n * * When disabled:\n *\n * ```xml\n * <$text a=\"true\">bar</$text>{}baz\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\">ba{}r</$text>b{}az\n * ```\n *\n * # Multiple attributes\n *\n * * When enabled and many attributes starts or ends at the same position:\n *\n * ```xml\n * <$text a=\"true\" b=\"true\">bar</$text>{}baz\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\" b=\"true\">bar{}</$text>baz\n * ```\n *\n * * When enabled and one procedes another:\n *\n * ```xml\n * <$text a=\"true\">bar</$text><$text b=\"true\">{}bar</$text>\n * ```\n *\n * \t<kbd>←</kbd>\n *\n * ```xml\n * <$text a=\"true\">bar{}</$text><$text b=\"true\">bar</$text>\n * ```\n *\n */\nexport default class TwoStepCaretMovement extends Plugin {\n\t/**\n\t * A set of attributes to handle.\n\t */\n\tprivate attributes: Set<string>;\n\n\t/**\n\t * The current UID of the overridden gravity, as returned by\n\t * {@link module:engine/model/writer~Writer#overrideSelectionGravity}.\n\t */\n\tprivate _overrideUid: string | null;\n\n\t/**\n\t * A flag indicating that the automatic gravity restoration should not happen upon the next\n\t * gravity restoration.\n\t * {@link module:engine/model/selection~Selection#event:change:range} event.\n\t */\n\n\tprivate _isNextGravityRestorationSkipped = false;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TwoStepCaretMovement' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis.attributes = new Set();\n\t\tthis._overrideUid = null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\t\tconst locale = editor.locale;\n\n\t\tconst modelSelection = model.document.selection;\n\n\t\t// Listen to keyboard events and handle the caret movement according to the 2-step caret logic.\n\t\tthis.listenTo<ViewDocumentArrowKeyEvent>( view.document, 'arrowKey', ( evt, data ) => {\n\t\t\t// This implementation works only for collapsed selection.\n\t\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// When user tries to expand the selection or jump over the whole word or to the beginning/end then\n\t\t\t// two-steps movement is not necessary.\n\t\t\tif ( data.shiftKey || data.altKey || data.ctrlKey ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst arrowRightPressed = data.keyCode == keyCodes.arrowright;\n\t\t\tconst arrowLeftPressed = data.keyCode == keyCodes.arrowleft;\n\n\t\t\t// When neither left or right arrow has been pressed then do noting.\n\t\t\tif ( !arrowRightPressed && !arrowLeftPressed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst contentDirection = locale.contentLanguageDirection;\n\t\t\tlet isMovementHandled = false;\n\n\t\t\tif ( ( contentDirection === 'ltr' && arrowRightPressed ) || ( contentDirection === 'rtl' && arrowLeftPressed ) ) {\n\t\t\t\tisMovementHandled = this._handleForwardMovement( data );\n\t\t\t} else {\n\t\t\t\tisMovementHandled = this._handleBackwardMovement( data );\n\t\t\t}\n\n\t\t\t// Stop the keydown event if the two-step caret movement handled it. Avoid collisions\n\t\t\t// with other features which may also take over the caret movement (e.g. Widget).\n\t\t\tif ( isMovementHandled === true ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: '$text', priority: 'highest' } );\n\n\t\t// The automatic gravity restoration logic.\n\t\tthis.listenTo<DocumentSelectionChangeRangeEvent>( modelSelection, 'change:range', ( evt, data ) => {\n\t\t\t// Skipping the automatic restoration is needed if the selection should change\n\t\t\t// but the gravity must remain overridden afterwards. See the #handleBackwardMovement\n\t\t\t// to learn more.\n\t\t\tif ( this._isNextGravityRestorationSkipped ) {\n\t\t\t\tthis._isNextGravityRestorationSkipped = false;\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip automatic restore when the gravity is not overridden — simply, there's nothing to restore\n\t\t\t// at this moment.\n\t\t\tif ( !this._isGravityOverridden ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip automatic restore when the change is indirect AND the selection is at the attribute boundary.\n\t\t\t// It means that e.g. if the change was external (collaboration) and the user had their\n\t\t\t// selection around the link, its gravity should remain intact in this change:range event.\n\t\t\tif ( !data.directChange && isBetweenDifferentAttributes( modelSelection.getFirstPosition()!, this.attributes ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._restoreGravity();\n\t\t} );\n\n\t\t// Handle a click at the beginning/end of a two-step element.\n\t\tthis._enableClickingAfterNode();\n\n\t\t// Change the attributes of the selection in certain situations after the two-step node was inserted into the document.\n\t\tthis._enableInsertContentSelectionAttributesFixer();\n\n\t\t// Handle removing the content after the two-step node.\n\t\tthis._handleDeleteContentAfterNode();\n\t}\n\n\t/**\n\t * Registers a given attribute for the two-step caret movement.\n\t *\n\t * @param attribute Name of the attribute to handle.\n\t */\n\tpublic registerAttribute( attribute: string ): void {\n\t\tthis.attributes.add( attribute );\n\t}\n\n\t/**\n\t * Updates the document selection and the view according to the two–step caret movement state\n\t * when moving **forwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.\n\t *\n\t * @param data Data of the key press.\n\t * @returns `true` when the handler prevented caret movement.\n\t */\n\tprivate _handleForwardMovement( data: DomEventData ): boolean {\n\t\tconst attributes = this.attributes;\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst position = selection.getFirstPosition()!;\n\n\t\t// DON'T ENGAGE 2-SCM if gravity is already overridden. It means that we just entered\n\t\t//\n\t\t// \t\t<paragraph>foo<$text attribute>{}bar</$text>baz</paragraph>\n\t\t//\n\t\t// or left the attribute\n\t\t//\n\t\t// \t\t<paragraph>foo<$text attribute>bar</$text>{}baz</paragraph>\n\t\t//\n\t\t// and the gravity will be restored automatically.\n\t\tif ( this._isGravityOverridden ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// DON'T ENGAGE 2-SCM when the selection is at the beginning of the block AND already has the\n\t\t// attribute:\n\t\t// * when the selection was initially set there using the mouse,\n\t\t// * when the editor has just started\n\t\t//\n\t\t//\t\t<paragraph><$text attribute>{}bar</$text>baz</paragraph>\n\t\t//\n\t\tif ( position.isAtStart && hasAnyAttribute( selection, attributes ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// ENGAGE 2-SCM When at least one of the observed attributes changes its value (incl. starts, ends).\n\t\t//\n\t\t//\t\t<paragraph>foo<$text attribute>bar{}</$text>baz</paragraph>\n\t\t//\t\t<paragraph>foo<$text attribute>bar{}</$text><$text otherAttribute>baz</$text></paragraph>\n\t\t//\t\t<paragraph>foo<$text attribute=1>bar{}</$text><$text attribute=2>baz</$text></paragraph>\n\t\t//\t\t<paragraph>foo{}<$text attribute>bar</$text>baz</paragraph>\n\t\t//\n\t\tif ( isBetweenDifferentAttributes( position, attributes ) ) {\n\t\t\tpreventCaretMovement( data );\n\n\t\t\t// CLEAR 2-SCM attributes if we are at the end of one 2-SCM and before\n\t\t\t// the next one with a different value of the same attribute.\n\t\t\t//\n\t\t\t//\t\t<paragraph>foo<$text attribute=1>bar{}</$text><$text attribute=2>bar</$text>baz</paragraph>\n\t\t\t//\n\t\t\tif (\n\t\t\t\thasAnyAttribute( selection, attributes ) &&\n\t\t\t\tisBetweenDifferentAttributes( position, attributes, true )\n\t\t\t) {\n\t\t\t\tclearSelectionAttributes( model, attributes );\n\t\t\t} else {\n\t\t\t\tthis._overrideGravity();\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Updates the document selection and the view according to the two–step caret movement state\n\t * when moving **backwards**. Executed upon `keypress` in the {@link module:engine/view/view~View}.\n\t *\n\t * @param data Data of the key press.\n\t * @returns `true` when the handler prevented caret movement\n\t */\n\tprivate _handleBackwardMovement( data: DomEventData ): boolean {\n\t\tconst attributes = this.attributes;\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst position = selection.getFirstPosition()!;\n\n\t\t// When the gravity is already overridden (by this plugin), it means we are on the two-step position.\n\t\t// Prevent the movement, restore the gravity and update selection attributes.\n\t\t//\n\t\t//\t\t<paragraph>foo<$text attribute=1>bar</$text><$text attribute=2>{}baz</$text></paragraph>\n\t\t//\t\t<paragraph>foo<$text attribute>bar</$text><$text otherAttribute>{}baz</$text></paragraph>\n\t\t//\t\t<paragraph>foo<$text attribute>{}bar</$text>baz</paragraph>\n\t\t//\t\t<paragraph>foo<$text attribute>bar</$text>{}baz</paragraph>\n\t\t//\n\t\tif ( this._isGravityOverridden ) {\n\t\t\tpreventCaretMovement( data );\n\t\t\tthis._restoreGravity();\n\n\t\t\t// CLEAR 2-SCM attributes if we are at the end of one 2-SCM and before\n\t\t\t// the next one with a different value of the same attribute.\n\t\t\t//\n\t\t\t//\t\t<paragraph>foo<$text attribute=1>bar</$text><$text attribute=2>{}bar</$text>baz</paragraph>\n\t\t\t//\n\t\t\tif ( isBetweenDifferentAttributes( position, attributes, true ) ) {\n\t\t\t\tclearSelectionAttributes( model, attributes );\n\t\t\t} else {\n\t\t\t\tsetSelectionAttributesFromTheNodeBefore( model, attributes, position );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\t// REMOVE SELECTION ATTRIBUTE when restoring gravity towards a non-existent content at the\n\t\t\t// beginning of the block.\n\t\t\t//\n\t\t\t// \t\t<paragraph>{}<$text attribute>bar</$text></paragraph>\n\t\t\t//\n\t\t\tif ( position.isAtStart ) {\n\t\t\t\tif ( hasAnyAttribute( selection, attributes ) ) {\n\t\t\t\t\tpreventCaretMovement( data );\n\t\t\t\t\tsetSelectionAttributesFromTheNodeBefore( model, attributes, position );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// SET 2-SCM attributes if we are between nodes with the same attribute but with different values.\n\t\t\t//\n\t\t\t//\t\t<paragraph>foo<$text attribute=1>bar</$text>[]<$text attribute=2>bar</$text>baz</paragraph>\n\t\t\t//\n\t\t\tif (\n\t\t\t\t!hasAnyAttribute( selection, attributes ) &&\n\t\t\t\tisBetweenDifferentAttributes( position, attributes, true )\n\t\t\t) {\n\t\t\t\tpreventCaretMovement( data );\n\t\t\t\tsetSelectionAttributesFromTheNodeBefore( model, attributes, position );\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// When we are moving from natural gravity, to the position of the 2SCM, we need to override the gravity,\n\t\t\t// and make sure it won't be restored. Unless it's at the end of the block and an observed attribute.\n\t\t\t// We need to check if the caret is a one position before the attribute boundary:\n\t\t\t//\n\t\t\t//\t\t<paragraph>foo<$text attribute=1>bar</$text><$text attribute=2>b{}az</$text></paragraph>\n\t\t\t//\t\t<paragraph>foo<$text attribute>bar</$text><$text otherAttribute>b{}az</$text></paragraph>\n\t\t\t//\t\t<paragraph>foo<$text attribute>b{}ar</$text>baz</paragraph>\n\t\t\t//\t\t<paragraph>foo<$text attribute>bar</$text>b{}az</paragraph>\n\t\t\t//\n\t\t\tif ( isStepAfterAnyAttributeBoundary( position, attributes ) ) {\n\t\t\t\t// ENGAGE 2-SCM if the selection has no attribute. This may happen when the user\n\t\t\t\t// left the attribute using a FORWARD 2-SCM.\n\t\t\t\t//\n\t\t\t\t// \t\t<paragraph><$text attribute>bar</$text>{}</paragraph>\n\t\t\t\t//\n\t\t\t\tif (\n\t\t\t\t\tposition.isAtEnd &&\n\t\t\t\t\t!hasAnyAttribute( selection, attributes ) &&\n\t\t\t\t\tisBetweenDifferentAttributes( position, attributes )\n\t\t\t\t) {\n\t\t\t\t\tpreventCaretMovement( data );\n\t\t\t\t\tsetSelectionAttributesFromTheNodeBefore( model, attributes, position );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// Skip the automatic gravity restore upon the next selection#change:range event.\n\t\t\t\t// If not skipped, it would automatically restore the gravity, which should remain\n\t\t\t\t// overridden.\n\t\t\t\tthis._isNextGravityRestorationSkipped = true;\n\t\t\t\tthis._overrideGravity();\n\n\t\t\t\t// Don't return \"true\" here because we didn't call _preventCaretMovement.\n\t\t\t\t// Returning here will destabilize the filler logic, which also listens to\n\t\t\t\t// keydown (and the event would be stopped).\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Starts listening to {@link module:engine/view/document~Document#event:mousedown} and\n\t * {@link module:engine/view/document~Document#event:selectionChange} and puts the selection before/after a 2-step node\n\t * if clicked at the beginning/ending of the 2-step node.\n\t *\n\t * The purpose of this action is to allow typing around the 2-step node directly after a click.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/1016.\n\t */\n\tprivate _enableClickingAfterNode(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst document = editor.editing.view.document;\n\n\t\teditor.editing.view.addObserver( MouseObserver );\n\n\t\tlet clicked = false;\n\n\t\t// Detect the click.\n\t\tthis.listenTo<ViewDocumentMouseDownEvent>( document, 'mousedown', () => {\n\t\t\tclicked = true;\n\t\t} );\n\n\t\t// When the selection has changed...\n\t\tthis.listenTo<ViewDocumentSelectionChangeEvent>( document, 'selectionChange', () => {\n\t\t\tconst attributes = this.attributes;\n\n\t\t\tif ( !clicked ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ...and it was caused by the click...\n\t\t\tclicked = false;\n\n\t\t\t// ...and no text is selected...\n\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ...and clicked text is the 2-step node...\n\t\t\tif ( !hasAnyAttribute( selection, attributes ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst position = selection.getFirstPosition()!;\n\n\t\t\tif ( !isBetweenDifferentAttributes( position, attributes ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The selection at the start of a block would use surrounding attributes\n\t\t\t// from text after the selection so just clear 2-SCM attributes.\n\t\t\t//\n\t\t\t// Also, clear attributes for selection between same attribute with different values.\n\t\t\tif (\n\t\t\t\tposition.isAtStart ||\n\t\t\t\tisBetweenDifferentAttributes( position, attributes, true )\n\t\t\t) {\n\t\t\t\tclearSelectionAttributes( model, attributes );\n\t\t\t}\n\t\t\telse if ( !this._isGravityOverridden ) {\n\t\t\t\tthis._overrideGravity();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Starts listening to {@link module:engine/model/model~Model#event:insertContent} and corrects the model\n\t * selection attributes if the selection is at the end of a two-step node after inserting the content.\n\t *\n\t * The purpose of this action is to improve the overall UX because the user is no longer \"trapped\" by the\n\t * two-step attribute of the selection, and they can type a \"clean\" (`linkHref`–less) text right away.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/6053.\n\t */\n\tprivate _enableInsertContentSelectionAttributesFixer(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst attributes = this.attributes;\n\n\t\tthis.listenTo<ModelInsertContentEvent>( model, 'insertContent', () => {\n\t\t\tconst position = selection.getFirstPosition()!;\n\n\t\t\tif (\n\t\t\t\thasAnyAttribute( selection, attributes ) &&\n\t\t\t\tisBetweenDifferentAttributes( position, attributes )\n\t\t\t) {\n\t\t\t\tclearSelectionAttributes( model, attributes );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether\n\t * removing a content right after the tow-step attribute.\n\t *\n\t * If so, the selection should not preserve the two-step attribute. However, if\n\t * the {@link module:typing/twostepcaretmovement~TwoStepCaretMovement} plugin is active and\n\t * the selection has the two-step attribute due to overridden gravity (at the end), the two-step attribute should stay untouched.\n\t *\n\t * The purpose of this action is to allow removing the link text and keep the selection outside the link.\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/7521.\n\t */\n\tprivate _handleDeleteContentAfterNode(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst view = editor.editing.view;\n\n\t\tlet isBackspace = false;\n\t\tlet shouldPreserveAttributes = false;\n\n\t\t// Detect pressing `Backspace`.\n\t\tthis.listenTo<ViewDocumentDeleteEvent>( view.document, 'delete', ( evt, data ) => {\n\t\t\tisBackspace = data.direction === 'backward';\n\t\t}, { priority: 'high' } );\n\n\t\t// Before removing the content, check whether the selection is inside a two-step attribute.\n\t\t// If so, we want to preserve those attributes.\n\t\tthis.listenTo<ModelDeleteContentEvent>( model, 'deleteContent', () => {\n\t\t\tif ( !isBackspace ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst position = selection.getFirstPosition()!;\n\n\t\t\tshouldPreserveAttributes = hasAnyAttribute( selection, this.attributes ) &&\n\t\t\t\t!isStepAfterAnyAttributeBoundary( position, this.attributes );\n\t\t}, { priority: 'high' } );\n\n\t\t// After removing the content, check whether the current selection should preserve the `linkHref` attribute.\n\t\tthis.listenTo<ModelDeleteContentEvent>( model, 'deleteContent', () => {\n\t\t\tif ( !isBackspace ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tisBackspace = false;\n\n\t\t\t// Do not escape two-step attribute if it was inside it before content deletion.\n\t\t\tif ( shouldPreserveAttributes ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Use `model.enqueueChange()` in order to execute the callback at the end of the changes process.\n\t\t\teditor.model.enqueueChange( () => {\n\t\t\t\tconst position = selection.getFirstPosition()!;\n\n\t\t\t\tif (\n\t\t\t\t\thasAnyAttribute( selection, this.attributes ) &&\n\t\t\t\t\tisBetweenDifferentAttributes( position, this.attributes )\n\t\t\t\t) {\n\t\t\t\t\tif ( position.isAtStart || isBetweenDifferentAttributes( position, this.attributes, true ) ) {\n\t\t\t\t\t\tclearSelectionAttributes( model, this.attributes );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( !this._isGravityOverridden ) {\n\t\t\t\t\t\tthis._overrideGravity();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * `true` when the gravity is overridden for the plugin.\n\t */\n\tprivate get _isGravityOverridden(): boolean {\n\t\treturn !!this._overrideUid;\n\t}\n\n\t/**\n\t * Overrides the gravity using the {@link module:engine/model/writer~Writer model writer}\n\t * and stores the information about this fact in the {@link #_overrideUid}.\n\t *\n\t * A shorthand for {@link module:engine/model/writer~Writer#overrideSelectionGravity}.\n\t */\n\tprivate _overrideGravity(): void {\n\t\tthis._overrideUid = this.editor.model.change( writer => {\n\t\t\treturn writer.overrideSelectionGravity();\n\t\t} );\n\t}\n\n\t/**\n\t * Restores the gravity using the {@link module:engine/model/writer~Writer model writer}.\n\t *\n\t * A shorthand for {@link module:engine/model/writer~Writer#restoreSelectionGravity}.\n\t */\n\tprivate _restoreGravity(): void {\n\t\tthis.editor.model.change( writer => {\n\t\t\twriter.restoreSelectionGravity( this._overrideUid! );\n\t\t\tthis._overrideUid = null;\n\t\t} );\n\t}\n}\n\n/**\n * Checks whether the selection has any of given attributes.\n */\nfunction hasAnyAttribute( selection: DocumentSelection, attributes: Set<string> ): boolean {\n\tfor ( const observedAttribute of attributes ) {\n\t\tif ( selection.hasAttribute( observedAttribute ) ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Applies the given attributes to the current selection using using the\n * values from the node before the current position. Uses\n * the {@link module:engine/model/writer~Writer model writer}.\n */\nfunction setSelectionAttributesFromTheNodeBefore( model: Model, attributes: Set<string>, position: Position ) {\n\tconst nodeBefore = position.nodeBefore;\n\n\tmodel.change( writer => {\n\t\tif ( nodeBefore ) {\n\t\t\tconst attributes: Array<[string, unknown]> = [];\n\t\t\tconst isInlineObject = model.schema.isObject( nodeBefore ) && model.schema.isInline( nodeBefore );\n\n\t\t\tfor ( const [ key, value ] of nodeBefore.getAttributes() ) {\n\t\t\t\tif (\n\t\t\t\t\tmodel.schema.checkAttribute( '$text', key ) &&\n\t\t\t\t\t( !isInlineObject || model.schema.getAttributeProperties( key ).copyFromObject !== false )\n\t\t\t\t) {\n\t\t\t\t\tattributes.push( [ key, value ] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twriter.setSelectionAttribute( attributes );\n\t\t} else {\n\t\t\twriter.removeSelectionAttribute( attributes );\n\t\t}\n\t} );\n}\n\n/**\n * Removes 2-SCM attributes from the selection.\n */\nfunction clearSelectionAttributes( model: Model, attributes: Set<string> ) {\n\tmodel.change( writer => {\n\t\twriter.removeSelectionAttribute( attributes );\n\t} );\n}\n\n/**\n * Prevents the caret movement in the view by calling `preventDefault` on the event data.\n *\n * @alias data.preventDefault\n */\nfunction preventCaretMovement( data: DomEventData ) {\n\tdata.preventDefault();\n}\n\n/**\n * Checks whether the step before `isBetweenDifferentAttributes()`.\n */\nfunction isStepAfterAnyAttributeBoundary( position: Position, attributes: Set<string> ): boolean {\n\tconst positionBefore = position.getShiftedBy( -1 );\n\treturn isBetweenDifferentAttributes( positionBefore, attributes );\n}\n\n/**\n * Checks whether the given position is between different values of given attributes.\n */\nfunction isBetweenDifferentAttributes( position: Position, attributes: Set<string>, isStrict: boolean = false ): boolean {\n\tconst { nodeBefore, nodeAfter } = position;\n\n\tfor ( const observedAttribute of attributes ) {\n\t\tconst attrBefore = nodeBefore ? nodeBefore.getAttribute( observedAttribute ) : undefined;\n\t\tconst attrAfter = nodeAfter ? nodeAfter.getAttribute( observedAttribute ) : undefined;\n\n\t\tif ( isStrict && ( attrBefore === undefined || attrAfter === undefined ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ( attrAfter !== attrBefore ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/texttransformation\n */\n\nimport {\n\tPlugin,\n\ttype Editor\n} from '@ckeditor/ckeditor5-core';\n\nimport type { Position } from '@ckeditor/ckeditor5-engine';\n\nimport TextWatcher, { type TextWatcherMatchedDataEvent } from './textwatcher.js';\nimport type { TextTransformationConfig, TextTransformationDescription } from './typingconfig.js';\nimport type Delete from './delete.js';\n\nimport { escapeRegExp } from 'lodash-es';\n\n// All named transformations.\nconst TRANSFORMATIONS: Record<string, TextTransformationDescription> = {\n\t// Common symbols:\n\tcopyright: { from: '(c)', to: '©' },\n\tregisteredTrademark: { from: '(r)', to: '®' },\n\ttrademark: { from: '(tm)', to: '™' },\n\n\t// Mathematical:\n\toneHalf: { from: /(^|[^/a-z0-9])(1\\/2)([^/a-z0-9])$/i, to: [ null, '½', null ] },\n\toneThird: { from: /(^|[^/a-z0-9])(1\\/3)([^/a-z0-9])$/i, to: [ null, '⅓', null ] },\n\ttwoThirds: { from: /(^|[^/a-z0-9])(2\\/3)([^/a-z0-9])$/i, to: [ null, '⅔', null ] },\n\toneForth: { from: /(^|[^/a-z0-9])(1\\/4)([^/a-z0-9])$/i, to: [ null, '¼', null ] },\n\tthreeQuarters: { from: /(^|[^/a-z0-9])(3\\/4)([^/a-z0-9])$/i, to: [ null, '¾', null ] },\n\tlessThanOrEqual: { from: '<=', to: '≤' },\n\tgreaterThanOrEqual: { from: '>=', to: '≥' },\n\tnotEqual: { from: '!=', to: '≠' },\n\tarrowLeft: { from: '<-', to: '←' },\n\tarrowRight: { from: '->', to: '→' },\n\n\t// Typography:\n\thorizontalEllipsis: { from: '...', to: '…' },\n\tenDash: { from: /(^| )(--)( )$/, to: [ null, '–', null ] },\n\temDash: { from: /(^| )(---)( )$/, to: [ null, '—', null ] },\n\t// Quotations:\n\t// English, US\n\tquotesPrimary: { from: buildQuotesRegExp( '\"' ), to: [ null, '“', null, '”' ] },\n\tquotesSecondary: { from: buildQuotesRegExp( '\\'' ), to: [ null, '‘', null, '’' ] },\n\n\t// English, UK\n\tquotesPrimaryEnGb: { from: buildQuotesRegExp( '\\'' ), to: [ null, '‘', null, '’' ] },\n\tquotesSecondaryEnGb: { from: buildQuotesRegExp( '\"' ), to: [ null, '“', null, '”' ] },\n\n\t// Polish\n\tquotesPrimaryPl: { from: buildQuotesRegExp( '\"' ), to: [ null, '„', null, '”' ] },\n\tquotesSecondaryPl: { from: buildQuotesRegExp( '\\'' ), to: [ null, '‚', null, '’' ] }\n};\n\n// Transformation groups.\nconst TRANSFORMATION_GROUPS: Record<string, Array<string>> = {\n\tsymbols: [ 'copyright', 'registeredTrademark', 'trademark' ],\n\tmathematical: [\n\t\t'oneHalf', 'oneThird', 'twoThirds', 'oneForth', 'threeQuarters',\n\t\t'lessThanOrEqual', 'greaterThanOrEqual', 'notEqual',\n\t\t'arrowLeft', 'arrowRight'\n\t],\n\ttypography: [ 'horizontalEllipsis', 'enDash', 'emDash' ],\n\tquotes: [ 'quotesPrimary', 'quotesSecondary' ]\n};\n\n// A set of default transformations provided by the feature.\nconst DEFAULT_TRANSFORMATIONS = [\n\t'symbols',\n\t'mathematical',\n\t'typography',\n\t'quotes'\n];\n\n/**\n * The text transformation plugin.\n */\nexport default class TextTransformation extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ 'Delete', 'Input' ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TextTransformation' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'typing', {\n\t\t\ttransformations: {\n\t\t\t\tinclude: DEFAULT_TRANSFORMATIONS\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst model = this.editor.model;\n\t\tconst modelSelection = model.document.selection;\n\n\t\tmodelSelection.on( 'change:range', () => {\n\t\t\t// Disable plugin when selection is inside a code block.\n\t\t\tthis.isEnabled = !modelSelection.anchor!.parent.is( 'element', 'codeBlock' );\n\t\t} );\n\n\t\tthis._enableTransformationWatchers();\n\t}\n\n\t/**\n\t * Create new TextWatcher listening to the editor for typing and selection events.\n\t */\n\tprivate _enableTransformationWatchers(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst deletePlugin: Delete = editor.plugins.get( 'Delete' );\n\t\tconst normalizedTransformations = normalizeTransformations( editor.config.get( 'typing.transformations' )! );\n\n\t\tconst testCallback = ( text: string ) => {\n\t\t\tfor ( const normalizedTransformation of normalizedTransformations ) {\n\t\t\t\tconst from = normalizedTransformation.from;\n\t\t\t\tconst match = from.test( text );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\treturn { normalizedTransformation };\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst watcher = new TextWatcher( editor.model, testCallback );\n\n\t\twatcher.on<TextWatcherMatchedDataEvent<{\n\t\t\tnormalizedTransformation: NormalizedTransformationConfig;\n\t\t}>>( 'matched:data', ( evt, data ) => {\n\t\t\tif ( !data.batch.isTyping ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { from, to } = data.normalizedTransformation;\n\n\t\t\tconst matches = from.exec( data.text )!;\n\t\t\tconst replaces = to( matches.slice( 1 ) );\n\n\t\t\tconst matchedRange = data.range;\n\n\t\t\tlet changeIndex = matches.index;\n\n\t\t\tmodel.enqueueChange( writer => {\n\t\t\t\tfor ( let i = 1; i < matches.length; i++ ) {\n\t\t\t\t\tconst match = matches[ i ];\n\t\t\t\t\tconst replaceWith = replaces[ i - 1 ];\n\n\t\t\t\t\tif ( replaceWith == null ) {\n\t\t\t\t\t\tchangeIndex += match.length;\n\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst replacePosition = matchedRange.start.getShiftedBy( changeIndex );\n\t\t\t\t\tconst replaceRange = model.createRange( replacePosition, replacePosition.getShiftedBy( match.length ) );\n\t\t\t\t\tconst attributes = getTextAttributesAfterPosition( replacePosition );\n\n\t\t\t\t\tmodel.insertContent( writer.createText( replaceWith, attributes ), replaceRange );\n\n\t\t\t\t\tchangeIndex += replaceWith.length;\n\t\t\t\t}\n\n\t\t\t\tmodel.enqueueChange( () => {\n\t\t\t\t\tdeletePlugin.requestUndoOnBackspace();\n\t\t\t\t} );\n\t\t\t} );\n\t\t} );\n\n\t\twatcher.bind( 'isEnabled' ).to( this );\n\t}\n}\n\n/**\n * Normalizes the configuration `from` parameter value.\n * The normalized value for the `from` parameter is a RegExp instance. If the passed `from` is already a RegExp instance,\n * it is returned unchanged.\n */\nfunction normalizeFrom( from: string | RegExp ): RegExp {\n\tif ( typeof from == 'string' ) {\n\t\treturn new RegExp( `(${ escapeRegExp( from ) })$` );\n\t}\n\n\t// `from` is already a regular expression.\n\treturn from;\n}\n\n/**\n * Normalizes the configuration `to` parameter value.\n * The normalized value for the `to` parameter is a function that takes an array and returns an array. See more in the\n * configuration description. If the passed `to` is already a function, it is returned unchanged.\n */\nfunction normalizeTo( to: TextTransformationDescription[ 'to' ] ) {\n\tif ( typeof to == 'string' ) {\n\t\treturn () => [ to ];\n\t} else if ( to instanceof Array ) {\n\t\treturn () => to;\n\t}\n\n\t// `to` is already a function.\n\treturn to;\n}\n\n/**\n * For given `position` returns attributes for the text that is after that position.\n * The text can be in the same text node as the position (`foo[]bar`) or in the next text node (`foo[]<$text bold=\"true\">bar</$text>`).\n */\nfunction getTextAttributesAfterPosition( position: Position ) {\n\tconst textNode = position.textNode ? position.textNode : position.nodeAfter;\n\n\treturn textNode!.getAttributes();\n}\n\n/**\n * Returns a RegExp pattern string that detects a sentence inside a quote.\n *\n * @param quoteCharacter The character to create a pattern for.\n */\nfunction buildQuotesRegExp( quoteCharacter: string ): RegExp {\n\treturn new RegExp( `(^|\\\\s)(${ quoteCharacter })([^${ quoteCharacter }]*)(${ quoteCharacter })$` );\n}\n\n/**\n * Reads text transformation config and returns normalized array of transformations objects.\n */\nfunction normalizeTransformations( config: TextTransformationConfig ): Array<NormalizedTransformationConfig> {\n\tconst extra = config.extra || [];\n\tconst remove = config.remove || [];\n\tconst isNotRemoved = ( transformation: TextTransformationDescription | string ) => !remove.includes( transformation );\n\n\tconst configured = config.include.concat( extra ).filter( isNotRemoved );\n\n\treturn expandGroupsAndRemoveDuplicates( configured )\n\t\t.filter( isNotRemoved ) // Filter out 'remove' transformations as they might be set in group.\n\t\t.map( transformation => (\n\t\t\ttypeof transformation == 'string' && TRANSFORMATIONS[ transformation ] ? TRANSFORMATIONS[ transformation ] : transformation )\n\t\t)\n\t\t// Filter out transformations set as string that has not been found.\n\t\t.filter( ( transformation ): transformation is TextTransformationDescription => typeof transformation === 'object' )\n\t\t.map( transformation => ( {\n\t\t\tfrom: normalizeFrom( transformation.from ),\n\t\t\tto: normalizeTo( transformation.to )\n\t\t} ) );\n}\n\n/**\n * Reads definitions and expands named groups if needed to transformation names.\n * This method also removes duplicated named transformations if any.\n */\nfunction expandGroupsAndRemoveDuplicates(\n\tdefinitions: Array<TextTransformationDescription | string>\n): Array<TextTransformationDescription | string> {\n\t// Set is using to make sure that transformation names are not duplicated.\n\tconst definedTransformations = new Set<TextTransformationDescription | string>();\n\n\tfor ( const transformationOrGroup of definitions ) {\n\t\tif ( typeof transformationOrGroup == 'string' && TRANSFORMATION_GROUPS[ transformationOrGroup ] ) {\n\t\t\tfor ( const transformation of TRANSFORMATION_GROUPS[ transformationOrGroup ] ) {\n\t\t\t\tdefinedTransformations.add( transformation );\n\t\t\t}\n\t\t} else {\n\t\t\tdefinedTransformations.add( transformationOrGroup );\n\t\t}\n\t}\n\n\treturn Array.from( definedTransformations );\n}\n\ntype NormalizedTransformationConfig = {\n\tfrom: RegExp;\n\tto: ( matches: Array<string> ) => Array<string | null>;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/utils/findattributerange\n */\n\nimport type { Position, Model, Range } from '@ckeditor/ckeditor5-engine';\n\n/**\n * Returns a model range that covers all consecutive nodes with the same `attributeName` and its `value`\n * that intersect the given `position`.\n *\n * It can be used e.g. to get the entire range on which the `linkHref` attribute needs to be changed when having a\n * selection inside a link.\n *\n * @param position The start position.\n * @param attributeName The attribute name.\n * @param value The attribute value.\n * @param model The model instance.\n * @returns The link range.\n */\nexport default function findAttributeRange(\n\tposition: Position,\n\tattributeName: string,\n\tvalue: unknown,\n\tmodel: Model\n): Range {\n\treturn model.createRange(\n\t\tfindAttributeRangeBound( position, attributeName, value, true, model ),\n\t\tfindAttributeRangeBound( position, attributeName, value, false, model )\n\t);\n}\n\n/**\n * Walks forward or backward (depends on the `lookBack` flag), node by node, as long as they have the same attribute value\n * and returns a position just before or after (depends on the `lookBack` flag) the last matched node.\n *\n * @param position The start position.\n * @param attributeName The attribute name.\n * @param value The attribute value.\n * @param lookBack Whether the walk direction is forward (`false`) or backward (`true`).\n * @returns The position just before the last matched node.\n */\nexport function findAttributeRangeBound(\n\tposition: Position,\n\tattributeName: string,\n\tvalue: unknown,\n\tlookBack: boolean,\n\tmodel: Model\n): Position {\n\t// Get node before or after position (depends on `lookBack` flag).\n\t// When position is inside text node then start searching from text node.\n\tlet node = position.textNode || ( lookBack ? position.nodeBefore : position.nodeAfter );\n\n\tlet lastNode = null;\n\n\twhile ( node && node.getAttribute( attributeName ) == value ) {\n\t\tlastNode = node;\n\t\tnode = lookBack ? node.previousSibling : node.nextSibling;\n\t}\n\n\treturn lastNode ? model.createPositionAt( lastNode, lookBack ? 'before' : 'after' ) : position;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module typing/utils/inlinehighlight\n */\n\nimport findAttributeRange from './findattributerange.js';\nimport type { Editor } from '@ckeditor/ckeditor5-core';\nimport type { ViewElement } from '@ckeditor/ckeditor5-engine';\n\n/**\n * Adds a visual highlight style to an attribute element in which the selection is anchored.\n * Together with two-step caret movement, they indicate that the user is typing inside the element.\n *\n * Highlight is turned on by adding the given class to the attribute element in the view:\n *\n * * The class is removed before the conversion has started, as callbacks added with the `'highest'` priority\n * to {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} events.\n * * The class is added in the view post fixer, after other changes in the model tree were converted to the view.\n *\n * This way, adding and removing the highlight does not interfere with conversion.\n *\n * Usage:\n *\n * ```ts\n * import inlineHighlight from '@ckeditor/ckeditor5-typing/src/utils/inlinehighlight';\n *\n * // Make `ck-link_selected` class be applied on an `a` element\n * // whenever the corresponding `linkHref` attribute element is selected.\n * inlineHighlight( editor, 'linkHref', 'a', 'ck-link_selected' );\n * ```\n *\n * @param editor The editor instance.\n * @param attributeName The attribute name to check.\n * @param tagName The tagName of a view item.\n * @param className The class name to apply in the view.\n */\nexport default function inlineHighlight(\n\teditor: Editor,\n\tattributeName: string,\n\ttagName: string,\n\tclassName: string\n): void {\n\tconst view = editor.editing.view;\n\tconst highlightedElements = new Set<ViewElement>();\n\n\t// Adding the class.\n\tview.document.registerPostFixer( writer => {\n\t\tconst selection = editor.model.document.selection;\n\t\tlet changed = false;\n\n\t\tif ( selection.hasAttribute( attributeName ) ) {\n\t\t\tconst modelRange = findAttributeRange(\n\t\t\t\tselection.getFirstPosition()!,\n\t\t\t\tattributeName,\n\t\t\t\tselection.getAttribute( attributeName ),\n\t\t\t\teditor.model\n\t\t\t);\n\t\t\tconst viewRange = editor.editing.mapper.toViewRange( modelRange );\n\n\t\t\t// There might be multiple view elements in the `viewRange`, for example, when the `a` element is\n\t\t\t// broken by a UIElement.\n\t\t\tfor ( const item of viewRange.getItems() ) {\n\t\t\t\tif ( item.is( 'element', tagName ) && !item.hasClass( className ) ) {\n\t\t\t\t\twriter.addClass( className, item );\n\t\t\t\t\thighlightedElements.add( item );\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t} );\n\n\t// Removing the class.\n\teditor.conversion.for( 'editingDowncast' ).add( dispatcher => {\n\t\t// Make sure the highlight is removed on every possible event, before conversion is started.\n\t\tdispatcher.on( 'insert', removeHighlight, { priority: 'highest' } );\n\t\tdispatcher.on( 'remove', removeHighlight, { priority: 'highest' } );\n\t\tdispatcher.on( 'attribute', removeHighlight, { priority: 'highest' } );\n\t\tdispatcher.on( 'selection', removeHighlight, { priority: 'highest' } );\n\n\t\tfunction removeHighlight() {\n\t\t\tview.change( writer => {\n\t\t\t\tfor ( const item of highlightedElements.values() ) {\n\t\t\t\t\twriter.removeClass( className, item );\n\t\t\t\t\thighlightedElements.delete( item );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { MenuBarMenuListItemButtonView, ButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { TwoStepCaretMovement, inlineHighlight } from '@ckeditor/ckeditor5-typing/dist/index.js';\n\n/**\n * An extension of the base {@link module:core/command~Command} class, which provides utilities for a command\n * that toggles a single attribute on a text or an element.\n *\n * `AttributeCommand` uses {@link module:engine/model/document~Document#selection}\n * to decide which nodes (if any) should be changed, and applies or removes the attribute from them.\n *\n * The command checks the {@link module:engine/model/model~Model#schema} to decide if it can be enabled\n * for the current selection and to which nodes the attribute can be applied.\n */ class AttributeCommand extends Command {\n    /**\n\t * The attribute that will be set by the command.\n\t */ attributeKey;\n    /**\n\t * @param attributeKey Attribute that will be set by the command.\n\t */ constructor(editor, attributeKey){\n        super(editor);\n        this.attributeKey = attributeKey;\n    }\n    /**\n\t * Updates the command's {@link #value} and {@link #isEnabled} based on the current selection.\n\t */ refresh() {\n        const model = this.editor.model;\n        const doc = model.document;\n        this.value = this._getValueFromFirstAllowedNode();\n        this.isEnabled = model.schema.checkAttributeInSelection(doc.selection, this.attributeKey);\n    }\n    /**\n\t * Executes the command &ndash; applies the attribute to the selection or removes it from the selection.\n\t *\n\t * If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes.\n\t *\n\t * The execution result differs, depending on the {@link module:engine/model/document~Document#selection}:\n\t *\n\t * * If the selection is on a range, the command applies the attribute to all nodes in that range\n\t * (if they are allowed to have this attribute by the {@link module:engine/model/schema~Schema schema}).\n\t * * If the selection is collapsed in a non-empty node, the command applies the attribute to the\n\t * {@link module:engine/model/document~Document#selection} itself (note that typed characters copy attributes from the selection).\n\t * * If the selection is collapsed in an empty node, the command applies the attribute to the parent node of the selection (note\n\t * that the selection inherits all attributes from a node if it is in an empty node).\n\t *\n\t * @fires execute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`,\n\t * the command will apply the attribute, otherwise the command will remove the attribute.\n\t * If not set, the command will look for its current value to decide what it should do.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const doc = model.document;\n        const selection = doc.selection;\n        const value = options.forceValue === undefined ? !this.value : options.forceValue;\n        model.change((writer)=>{\n            if (selection.isCollapsed) {\n                if (value) {\n                    writer.setSelectionAttribute(this.attributeKey, true);\n                } else {\n                    writer.removeSelectionAttribute(this.attributeKey);\n                }\n            } else {\n                const ranges = model.schema.getValidRanges(selection.getRanges(), this.attributeKey);\n                for (const range of ranges){\n                    if (value) {\n                        writer.setAttribute(this.attributeKey, value, range);\n                    } else {\n                        writer.removeAttribute(this.attributeKey, range);\n                    }\n                }\n            }\n        });\n    }\n    /**\n\t * Checks the attribute value of the first node in the selection that allows the attribute.\n\t * For the collapsed selection returns the selection attribute.\n\t *\n\t * @returns The attribute value.\n\t */ _getValueFromFirstAllowedNode() {\n        const model = this.editor.model;\n        const schema = model.schema;\n        const selection = model.document.selection;\n        if (selection.isCollapsed) {\n            return selection.hasAttribute(this.attributeKey);\n        }\n        for (const range of selection.getRanges()){\n            for (const item of range.getItems()){\n                if (schema.checkAttribute(item, this.attributeKey)) {\n                    return item.hasAttribute(this.attributeKey);\n                }\n            }\n        }\n        return false;\n    }\n}\n\nconst BOLD$1 = 'bold';\n/**\n * The bold editing feature.\n *\n * It registers the `'bold'` command and introduces the `bold` attribute in the model which renders to the view\n * as a `<strong>` element.\n */ class BoldEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'BoldEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        // Allow bold attribute on text nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: BOLD$1\n        });\n        editor.model.schema.setAttributeProperties(BOLD$1, {\n            isFormatting: true,\n            copyOnEnter: true\n        });\n        // Build converter from model to view for data and editing pipelines.\n        editor.conversion.attributeToElement({\n            model: BOLD$1,\n            view: 'strong',\n            upcastAlso: [\n                'b',\n                (viewElement)=>{\n                    const fontWeight = viewElement.getStyle('font-weight');\n                    if (!fontWeight) {\n                        return null;\n                    }\n                    // Value of the `font-weight` attribute can be defined as a string or a number.\n                    if (fontWeight == 'bold' || Number(fontWeight) >= 600) {\n                        return {\n                            name: true,\n                            styles: [\n                                'font-weight'\n                            ]\n                        };\n                    }\n                    return null;\n                }\n            ]\n        });\n        // Create bold command.\n        editor.commands.add(BOLD$1, new AttributeCommand(editor, BOLD$1));\n        // Set the Ctrl+B keystroke.\n        editor.keystrokes.set('CTRL+B', BOLD$1);\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Bold text'),\n                    keystroke: 'CTRL+B'\n                }\n            ]\n        });\n    }\n}\n\n/**\n * Returns a function that creates a (toolbar or menu bar) button for a basic style feature.\n */ function getButtonCreator({ editor, commandName, plugin, icon, label, keystroke }) {\n    return (ButtonClass)=>{\n        const command = editor.commands.get(commandName);\n        const view = new ButtonClass(editor.locale);\n        view.set({\n            label,\n            icon,\n            keystroke,\n            isToggleable: true\n        });\n        view.bind('isEnabled').to(command, 'isEnabled');\n        view.bind('isOn').to(command, 'value');\n        if (view instanceof MenuBarMenuListItemButtonView) {\n            view.set({\n                role: 'menuitemcheckbox'\n            });\n        } else {\n            view.set({\n                tooltip: true\n            });\n        }\n        // Execute the command.\n        plugin.listenTo(view, 'execute', ()=>{\n            editor.execute(commandName);\n            editor.editing.view.focus();\n        });\n        return view;\n    };\n}\n\nconst BOLD = 'bold';\n/**\n * The bold UI feature. It introduces the Bold button.\n */ class BoldUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'BoldUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const createButton = getButtonCreator({\n            editor,\n            commandName: BOLD,\n            plugin: this,\n            icon: icons.bold,\n            label: t('Bold'),\n            keystroke: 'CTRL+B'\n        });\n        // Add bold button to feature components.\n        editor.ui.componentFactory.add(BOLD, ()=>createButton(ButtonView));\n        editor.ui.componentFactory.add('menuBar:' + BOLD, ()=>createButton(MenuBarMenuListItemButtonView));\n    }\n}\n\n/**\n * The bold feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/bold/boldediting~BoldEditing bold editing feature}\n * and {@link module:basic-styles/bold/boldui~BoldUI bold UI feature}.\n */ class Bold extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            BoldEditing,\n            BoldUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Bold';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst CODE$1 = 'code';\nconst HIGHLIGHT_CLASS = 'ck-code_selected';\n/**\n * The code editing feature.\n *\n * It registers the `'code'` command and introduces the `code` attribute in the model which renders to the view\n * as a `<code>` element.\n */ class CodeEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'CodeEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TwoStepCaretMovement\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        // Allow code attribute on text nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: CODE$1\n        });\n        editor.model.schema.setAttributeProperties(CODE$1, {\n            isFormatting: true,\n            copyOnEnter: false\n        });\n        editor.conversion.attributeToElement({\n            model: CODE$1,\n            view: 'code',\n            upcastAlso: {\n                styles: {\n                    'word-wrap': 'break-word'\n                }\n            }\n        });\n        // Create code command.\n        editor.commands.add(CODE$1, new AttributeCommand(editor, CODE$1));\n        // Enable two-step caret movement for `code` attribute.\n        editor.plugins.get(TwoStepCaretMovement).registerAttribute(CODE$1);\n        // Setup highlight over selected element.\n        inlineHighlight(editor, CODE$1, 'code', HIGHLIGHT_CLASS);\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Move out of an inline code style'),\n                    keystroke: [\n                        [\n                            'arrowleft',\n                            'arrowleft'\n                        ],\n                        [\n                            'arrowright',\n                            'arrowright'\n                        ]\n                    ]\n                }\n            ]\n        });\n    }\n}\n\nvar codeIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m12.5 5.7 5.2 3.9v1.3l-5.6 4c-.1.2-.3.2-.5.2-.3-.1-.6-.7-.6-1l.3-.4 4.7-3.5L11.5 7l-.2-.2c-.1-.3-.1-.6 0-.8.2-.2.5-.4.8-.4a.8.8 0 0 1 .4.1zm-5.2 0L2 9.6v1.3l5.6 4c.1.2.3.2.5.2.3-.1.7-.7.6-1 0-.1 0-.3-.2-.4l-5-3.5L8.2 7l.2-.2c.1-.3.1-.6 0-.8-.2-.2-.5-.4-.8-.4a.8.8 0 0 0-.3.1z\\\"/></svg>\";\n\nconst CODE = 'code';\n/**\n * The code UI feature. It introduces the Code button.\n */ class CodeUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'CodeUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const createButton = getButtonCreator({\n            editor,\n            commandName: CODE,\n            plugin: this,\n            icon: codeIcon,\n            label: t('Code')\n        });\n        // Add code button to feature components.\n        editor.ui.componentFactory.add(CODE, ()=>createButton(ButtonView));\n        editor.ui.componentFactory.add('menuBar:' + CODE, ()=>createButton(MenuBarMenuListItemButtonView));\n    }\n}\n\n/**\n * The code feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/code/codeediting~CodeEditing code editing feature}\n * and {@link module:basic-styles/code/codeui~CodeUI code UI feature}.\n */ class Code extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            CodeEditing,\n            CodeUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Code';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst ITALIC$1 = 'italic';\n/**\n * The italic editing feature.\n *\n * It registers the `'italic'` command, the <kbd>Ctrl+I</kbd> keystroke and introduces the `italic` attribute in the model\n * which renders to the view as an `<i>` element.\n */ class ItalicEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ItalicEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        // Allow italic attribute on text nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: ITALIC$1\n        });\n        editor.model.schema.setAttributeProperties(ITALIC$1, {\n            isFormatting: true,\n            copyOnEnter: true\n        });\n        editor.conversion.attributeToElement({\n            model: ITALIC$1,\n            view: 'i',\n            upcastAlso: [\n                'em',\n                {\n                    styles: {\n                        'font-style': 'italic'\n                    }\n                }\n            ]\n        });\n        // Create italic command.\n        editor.commands.add(ITALIC$1, new AttributeCommand(editor, ITALIC$1));\n        // Set the Ctrl+I keystroke.\n        editor.keystrokes.set('CTRL+I', ITALIC$1);\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Italic text'),\n                    keystroke: 'CTRL+I'\n                }\n            ]\n        });\n    }\n}\n\nvar italicIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m9.586 14.633.021.004c-.036.335.095.655.393.962.082.083.173.15.274.201h1.474a.6.6 0 1 1 0 1.2H5.304a.6.6 0 0 1 0-1.2h1.15c.474-.07.809-.182 1.005-.334.157-.122.291-.32.404-.597l2.416-9.55a1.053 1.053 0 0 0-.281-.823 1.12 1.12 0 0 0-.442-.296H8.15a.6.6 0 0 1 0-1.2h6.443a.6.6 0 1 1 0 1.2h-1.195c-.376.056-.65.155-.823.296-.215.175-.423.439-.623.79l-2.366 9.347z\\\"/></svg>\";\n\nconst ITALIC = 'italic';\n/**\n * The italic UI feature. It introduces the Italic button.\n */ class ItalicUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ItalicUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const createButton = getButtonCreator({\n            editor,\n            commandName: ITALIC,\n            plugin: this,\n            icon: italicIcon,\n            keystroke: 'CTRL+I',\n            label: t('Italic')\n        });\n        // Add bold button to feature components.\n        editor.ui.componentFactory.add(ITALIC, ()=>createButton(ButtonView));\n        editor.ui.componentFactory.add('menuBar:' + ITALIC, ()=>createButton(MenuBarMenuListItemButtonView));\n    }\n}\n\n/**\n * The italic feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/italic/italicediting~ItalicEditing} and\n * {@link module:basic-styles/italic/italicui~ItalicUI} plugins.\n */ class Italic extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ItalicEditing,\n            ItalicUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Italic';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst STRIKETHROUGH$1 = 'strikethrough';\n/**\n * The strikethrough editing feature.\n *\n * It registers the `'strikethrough'` command, the <kbd>Ctrl+Shift+X</kbd> keystroke and introduces the\n * `strikethroughsthrough` attribute in the model which renders to the view\n * as a `<s>` element.\n */ class StrikethroughEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'StrikethroughEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        // Allow strikethrough attribute on text nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: STRIKETHROUGH$1\n        });\n        editor.model.schema.setAttributeProperties(STRIKETHROUGH$1, {\n            isFormatting: true,\n            copyOnEnter: true\n        });\n        editor.conversion.attributeToElement({\n            model: STRIKETHROUGH$1,\n            view: 's',\n            upcastAlso: [\n                'del',\n                'strike',\n                {\n                    styles: {\n                        'text-decoration': 'line-through'\n                    }\n                }\n            ]\n        });\n        // Create strikethrough command.\n        editor.commands.add(STRIKETHROUGH$1, new AttributeCommand(editor, STRIKETHROUGH$1));\n        // Set the Ctrl+Shift+X keystroke.\n        editor.keystrokes.set('CTRL+SHIFT+X', 'strikethrough');\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Strikethrough text'),\n                    keystroke: 'CTRL+SHIFT+X'\n                }\n            ]\n        });\n    }\n}\n\nvar strikethroughIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 16.4c-.8-.4-1.5-.9-2.2-1.5a.6.6 0 0 1-.2-.5l.3-.6h1c1 1.2 2.1 1.7 3.7 1.7 1 0 1.8-.3 2.3-.6.6-.4.6-1.2.6-1.3.2-1.2-.9-2.1-.9-2.1h2.1c.3.7.4 1.2.4 1.7v.8l-.6 1.2c-.6.8-1.1 1-1.6 1.2a6 6 0 0 1-2.4.6c-1 0-1.8-.3-2.5-.6zM6.8 9 6 8.3c-.4-.5-.5-.8-.5-1.6 0-.7.1-1.3.5-1.8.4-.6 1-1 1.6-1.3a6.3 6.3 0 0 1 4.7 0 4 4 0 0 1 1.7 1l.3.7c0 .1.2.4-.2.7-.4.2-.9.1-1 0a3 3 0 0 0-1.2-1c-.4-.2-1-.3-2-.4-.7 0-1.4.2-2 .6-.8.6-1 .8-1 1.5 0 .8.5 1 1.2 1.5.6.4 1.1.7 1.9 1H6.8z\\\"/><path d=\\\"M3 10.5V9h14v1.5z\\\"/></svg>\";\n\nconst STRIKETHROUGH = 'strikethrough';\n/**\n * The strikethrough UI feature. It introduces the Strikethrough button.\n */ class StrikethroughUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'StrikethroughUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const createButton = getButtonCreator({\n            editor,\n            commandName: STRIKETHROUGH,\n            plugin: this,\n            icon: strikethroughIcon,\n            keystroke: 'CTRL+SHIFT+X',\n            label: t('Strikethrough')\n        });\n        // Add strikethrough button to feature components.\n        editor.ui.componentFactory.add(STRIKETHROUGH, ()=>createButton(ButtonView));\n        editor.ui.componentFactory.add('menuBar:' + STRIKETHROUGH, ()=>createButton(MenuBarMenuListItemButtonView));\n    }\n}\n\n/**\n * The strikethrough feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/strikethrough/strikethroughediting~StrikethroughEditing} and\n * {@link module:basic-styles/strikethrough/strikethroughui~StrikethroughUI} plugins.\n */ class Strikethrough extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            StrikethroughEditing,\n            StrikethroughUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Strikethrough';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst SUBSCRIPT$1 = 'subscript';\n/**\n * The subscript editing feature.\n *\n * It registers the `sub` command and introduces the `sub` attribute in the model which renders to the view\n * as a `<sub>` element.\n */ class SubscriptEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SubscriptEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Allow sub attribute on text nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: SUBSCRIPT$1\n        });\n        editor.model.schema.setAttributeProperties(SUBSCRIPT$1, {\n            isFormatting: true,\n            copyOnEnter: true\n        });\n        // Build converter from model to view for data and editing pipelines.\n        editor.conversion.attributeToElement({\n            model: SUBSCRIPT$1,\n            view: 'sub',\n            upcastAlso: [\n                {\n                    styles: {\n                        'vertical-align': 'sub'\n                    }\n                }\n            ]\n        });\n        // Create sub command.\n        editor.commands.add(SUBSCRIPT$1, new AttributeCommand(editor, SUBSCRIPT$1));\n    }\n}\n\nvar subscriptIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m7.03 10.349 3.818-3.819a.8.8 0 1 1 1.132 1.132L8.16 11.48l3.819 3.818a.8.8 0 1 1-1.132 1.132L7.03 12.61l-3.818 3.82a.8.8 0 1 1-1.132-1.132L5.9 11.48 2.08 7.662A.8.8 0 1 1 3.212 6.53l3.818 3.82zm8.147 7.829h2.549c.254 0 .447.05.58.152a.49.49 0 0 1 .201.413.54.54 0 0 1-.159.393c-.105.108-.266.162-.48.162h-3.594c-.245 0-.435-.066-.572-.197a.621.621 0 0 1-.205-.463c0-.114.044-.265.132-.453a1.62 1.62 0 0 1 .288-.444c.433-.436.824-.81 1.172-1.122.348-.312.597-.517.747-.615.267-.183.49-.368.667-.553.177-.185.312-.375.405-.57.093-.194.139-.384.139-.57a1.008 1.008 0 0 0-.554-.917 1.197 1.197 0 0 0-.56-.133c-.426 0-.761.182-1.005.546a2.332 2.332 0 0 0-.164.39 1.609 1.609 0 0 1-.258.488c-.096.114-.237.17-.423.17a.558.558 0 0 1-.405-.156.568.568 0 0 1-.161-.427c0-.218.05-.446.151-.683.101-.238.252-.453.452-.646s.454-.349.762-.467a2.998 2.998 0 0 1 1.081-.178c.498 0 .923.076 1.274.228a1.916 1.916 0 0 1 1.004 1.032 1.984 1.984 0 0 1-.156 1.794c-.2.32-.405.572-.613.754-.208.182-.558.468-1.048.857-.49.39-.826.691-1.008.906a2.703 2.703 0 0 0-.24.309z\\\"/></svg>\";\n\nconst SUBSCRIPT = 'subscript';\n/**\n * The subscript UI feature. It introduces the Subscript button.\n */ class SubscriptUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SubscriptUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const createButton = getButtonCreator({\n            editor,\n            commandName: SUBSCRIPT,\n            plugin: this,\n            icon: subscriptIcon,\n            label: t('Subscript')\n        });\n        // Add subscript button to feature components.\n        editor.ui.componentFactory.add(SUBSCRIPT, ()=>createButton(ButtonView));\n        editor.ui.componentFactory.add('menuBar:' + SUBSCRIPT, ()=>createButton(MenuBarMenuListItemButtonView));\n    }\n}\n\n/**\n * The subscript feature.\n *\n * It loads the {@link module:basic-styles/subscript/subscriptediting~SubscriptEditing} and\n * {@link module:basic-styles/subscript/subscriptui~SubscriptUI} plugins.\n */ class Subscript extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            SubscriptEditing,\n            SubscriptUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Subscript';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst SUPERSCRIPT$1 = 'superscript';\n/**\n * The superscript editing feature.\n *\n * It registers the `super` command and introduces the `super` attribute in the model which renders to the view\n * as a `<super>` element.\n */ class SuperscriptEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SuperscriptEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Allow super attribute on text nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: SUPERSCRIPT$1\n        });\n        editor.model.schema.setAttributeProperties(SUPERSCRIPT$1, {\n            isFormatting: true,\n            copyOnEnter: true\n        });\n        // Build converter from model to view for data and editing pipelines.\n        editor.conversion.attributeToElement({\n            model: SUPERSCRIPT$1,\n            view: 'sup',\n            upcastAlso: [\n                {\n                    styles: {\n                        'vertical-align': 'super'\n                    }\n                }\n            ]\n        });\n        // Create super command.\n        editor.commands.add(SUPERSCRIPT$1, new AttributeCommand(editor, SUPERSCRIPT$1));\n    }\n}\n\nvar superscriptIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M15.677 8.678h2.549c.254 0 .447.05.58.152a.49.49 0 0 1 .201.413.54.54 0 0 1-.159.393c-.105.108-.266.162-.48.162h-3.594c-.245 0-.435-.066-.572-.197a.621.621 0 0 1-.205-.463c0-.114.044-.265.132-.453a1.62 1.62 0 0 1 .288-.444c.433-.436.824-.81 1.172-1.122.348-.312.597-.517.747-.615.267-.183.49-.368.667-.553.177-.185.312-.375.405-.57.093-.194.139-.384.139-.57a1.008 1.008 0 0 0-.554-.917 1.197 1.197 0 0 0-.56-.133c-.426 0-.761.182-1.005.546a2.332 2.332 0 0 0-.164.39 1.609 1.609 0 0 1-.258.488c-.096.114-.237.17-.423.17a.558.558 0 0 1-.405-.156.568.568 0 0 1-.161-.427c0-.218.05-.446.151-.683.101-.238.252-.453.452-.646s.454-.349.762-.467a2.998 2.998 0 0 1 1.081-.178c.498 0 .923.076 1.274.228a1.916 1.916 0 0 1 1.004 1.032 1.984 1.984 0 0 1-.156 1.794c-.2.32-.405.572-.613.754-.208.182-.558.468-1.048.857-.49.39-.826.691-1.008.906a2.703 2.703 0 0 0-.24.309zM7.03 10.349l3.818-3.819a.8.8 0 1 1 1.132 1.132L8.16 11.48l3.819 3.818a.8.8 0 1 1-1.132 1.132L7.03 12.61l-3.818 3.82a.8.8 0 1 1-1.132-1.132L5.9 11.48 2.08 7.662A.8.8 0 1 1 3.212 6.53l3.818 3.82z\\\"/></svg>\";\n\nconst SUPERSCRIPT = 'superscript';\n/**\n * The superscript UI feature. It introduces the Superscript button.\n */ class SuperscriptUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SuperscriptUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const createButton = getButtonCreator({\n            editor,\n            commandName: SUPERSCRIPT,\n            plugin: this,\n            icon: superscriptIcon,\n            label: t('Superscript')\n        });\n        // Add superscript button to feature components.\n        editor.ui.componentFactory.add(SUPERSCRIPT, ()=>createButton(ButtonView));\n        editor.ui.componentFactory.add('menuBar:' + SUPERSCRIPT, ()=>createButton(MenuBarMenuListItemButtonView));\n    }\n}\n\n/**\n * The superscript feature.\n *\n * It loads the {@link module:basic-styles/superscript/superscriptediting~SuperscriptEditing} and\n * {@link module:basic-styles/superscript/superscriptui~SuperscriptUI} plugins.\n */ class Superscript extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            SuperscriptEditing,\n            SuperscriptUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Superscript';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst UNDERLINE$1 = 'underline';\n/**\n * The underline editing feature.\n *\n * It registers the `'underline'` command, the <kbd>Ctrl+U</kbd> keystroke\n * and introduces the `underline` attribute in the model which renders to the view as an `<u>` element.\n */ class UnderlineEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'UnderlineEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        // Allow strikethrough attribute on text nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: UNDERLINE$1\n        });\n        editor.model.schema.setAttributeProperties(UNDERLINE$1, {\n            isFormatting: true,\n            copyOnEnter: true\n        });\n        editor.conversion.attributeToElement({\n            model: UNDERLINE$1,\n            view: 'u',\n            upcastAlso: {\n                styles: {\n                    'text-decoration': 'underline'\n                }\n            }\n        });\n        // Create underline command.\n        editor.commands.add(UNDERLINE$1, new AttributeCommand(editor, UNDERLINE$1));\n        // Set the Ctrl+U keystroke.\n        editor.keystrokes.set('CTRL+U', 'underline');\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Underline text'),\n                    keystroke: 'CTRL+U'\n                }\n            ]\n        });\n    }\n}\n\nvar underlineIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 18v-1.5h14V18zm2.2-8V3.6c0-.4.4-.6.8-.6.3 0 .7.2.7.6v6.2c0 2 1.3 2.8 3.2 2.8 1.9 0 3.4-.9 3.4-2.9V3.6c0-.3.4-.5.8-.5.3 0 .7.2.7.5V10c0 2.7-2.2 4-4.9 4-2.6 0-4.7-1.2-4.7-4z\\\"/></svg>\";\n\nconst UNDERLINE = 'underline';\n/**\n * The underline UI feature. It introduces the Underline button.\n */ class UnderlineUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'UnderlineUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const createButton = getButtonCreator({\n            editor,\n            commandName: UNDERLINE,\n            plugin: this,\n            icon: underlineIcon,\n            label: t('Underline'),\n            keystroke: 'CTRL+U'\n        });\n        // Add bold button to feature components.\n        editor.ui.componentFactory.add(UNDERLINE, ()=>createButton(ButtonView));\n        editor.ui.componentFactory.add('menuBar:' + UNDERLINE, ()=>createButton(MenuBarMenuListItemButtonView));\n    }\n}\n\n/**\n * The underline feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/underline/underlineediting~UnderlineEditing} and\n * {@link module:basic-styles/underline/underlineui~UnderlineUI} plugins.\n */ class Underline extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            UnderlineEditing,\n            UnderlineUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Underline';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { AttributeCommand, Bold, BoldEditing, BoldUI, Code, CodeEditing, CodeUI, Italic, ItalicEditing, ItalicUI, Strikethrough, StrikethroughEditing, StrikethroughUI, Subscript, SubscriptEditing, SubscriptUI, Superscript, SuperscriptEditing, SuperscriptUI, Underline, UnderlineEditing, UnderlineUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/attributecommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\n\n/**\n * An extension of the base {@link module:core/command~Command} class, which provides utilities for a command\n * that toggles a single attribute on a text or an element.\n *\n * `AttributeCommand` uses {@link module:engine/model/document~Document#selection}\n * to decide which nodes (if any) should be changed, and applies or removes the attribute from them.\n *\n * The command checks the {@link module:engine/model/model~Model#schema} to decide if it can be enabled\n * for the current selection and to which nodes the attribute can be applied.\n */\nexport default class AttributeCommand extends Command {\n\t/**\n\t * Flag indicating whether the command is active. The command is active when the\n\t * {@link module:engine/model/selection~Selection#hasAttribute selection has the attribute} which means that:\n\t *\n\t * * If the selection is not empty &ndash; That the attribute is set on the first node in the selection that allows this attribute.\n\t * * If the selection is empty &ndash; That the selection has the attribute itself (which means that newly typed\n\t * text will have this attribute, too).\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public value: boolean;\n\n\t/**\n\t * The attribute that will be set by the command.\n\t */\n\tpublic readonly attributeKey: string;\n\n\t/**\n\t * @param attributeKey Attribute that will be set by the command.\n\t */\n\tconstructor( editor: Editor, attributeKey: string ) {\n\t\tsuper( editor );\n\n\t\tthis.attributeKey = attributeKey;\n\t}\n\n\t/**\n\t * Updates the command's {@link #value} and {@link #isEnabled} based on the current selection.\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tthis.value = this._getValueFromFirstAllowedNode();\n\t\tthis.isEnabled = model.schema.checkAttributeInSelection( doc.selection, this.attributeKey );\n\t}\n\n\t/**\n\t * Executes the command &ndash; applies the attribute to the selection or removes it from the selection.\n\t *\n\t * If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes.\n\t *\n\t * The execution result differs, depending on the {@link module:engine/model/document~Document#selection}:\n\t *\n\t * * If the selection is on a range, the command applies the attribute to all nodes in that range\n\t * (if they are allowed to have this attribute by the {@link module:engine/model/schema~Schema schema}).\n\t * * If the selection is collapsed in a non-empty node, the command applies the attribute to the\n\t * {@link module:engine/model/document~Document#selection} itself (note that typed characters copy attributes from the selection).\n\t * * If the selection is collapsed in an empty node, the command applies the attribute to the parent node of the selection (note\n\t * that the selection inherits all attributes from a node if it is in an empty node).\n\t *\n\t * @fires execute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`,\n\t * the command will apply the attribute, otherwise the command will remove the attribute.\n\t * If not set, the command will look for its current value to decide what it should do.\n\t */\n\tpublic override execute( options: { forceValue?: boolean } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst selection = doc.selection;\n\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tif ( value ) {\n\t\t\t\t\twriter.setSelectionAttribute( this.attributeKey, true );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeSelectionAttribute( this.attributeKey );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst ranges = model.schema.getValidRanges( selection.getRanges(), this.attributeKey );\n\n\t\t\t\tfor ( const range of ranges ) {\n\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\twriter.setAttribute( this.attributeKey, value, range );\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.removeAttribute( this.attributeKey, range );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the attribute value of the first node in the selection that allows the attribute.\n\t * For the collapsed selection returns the selection attribute.\n\t *\n\t * @returns The attribute value.\n\t */\n\tprivate _getValueFromFirstAllowedNode(): boolean {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tif ( selection.isCollapsed ) {\n\t\t\treturn selection.hasAttribute( this.attributeKey );\n\t\t}\n\n\t\tfor ( const range of selection.getRanges() ) {\n\t\t\tfor ( const item of range.getItems() ) {\n\t\t\t\tif ( schema.checkAttribute( item, this.attributeKey ) ) {\n\t\t\t\t\treturn item.hasAttribute( this.attributeKey );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/bold/boldediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport AttributeCommand from '../attributecommand.js';\n\nconst BOLD = 'bold';\n\n/**\n * The bold editing feature.\n *\n * It registers the `'bold'` command and introduces the `bold` attribute in the model which renders to the view\n * as a `<strong>` element.\n */\nexport default class BoldEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'BoldEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\n\t\t// Allow bold attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: BOLD } );\n\t\teditor.model.schema.setAttributeProperties( BOLD, {\n\t\t\tisFormatting: true,\n\t\t\tcopyOnEnter: true\n\t\t} );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: BOLD,\n\t\t\tview: 'strong',\n\t\t\tupcastAlso: [\n\t\t\t\t'b',\n\t\t\t\tviewElement => {\n\t\t\t\t\tconst fontWeight = viewElement.getStyle( 'font-weight' );\n\n\t\t\t\t\tif ( !fontWeight ) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Value of the `font-weight` attribute can be defined as a string or a number.\n\t\t\t\t\tif ( fontWeight == 'bold' || Number( fontWeight ) >= 600 ) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: true,\n\t\t\t\t\t\t\tstyles: [ 'font-weight' ]\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create bold command.\n\t\teditor.commands.add( BOLD, new AttributeCommand( editor, BOLD ) );\n\n\t\t// Set the Ctrl+B keystroke.\n\t\teditor.keystrokes.set( 'CTRL+B', BOLD );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Bold text' ),\n\t\t\t\t\tkeystroke: 'CTRL+B'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/utils\n */\n\nimport type { Editor, Plugin } from 'ckeditor5/src/core.js';\nimport type AttributeCommand from './attributecommand.js';\nimport { MenuBarMenuListItemButtonView, type ButtonView } from 'ckeditor5/src/ui.js';\n\n/**\n * Returns a function that creates a (toolbar or menu bar) button for a basic style feature.\n */\nexport function getButtonCreator( {\n\teditor, commandName, plugin, icon, label, keystroke\n}: {\n\teditor: Editor;\n\tcommandName: string;\n\ticon: string;\n\tlabel: string;\n\tplugin: Plugin;\n\tkeystroke?: string;\n} ) {\n\treturn <T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>( ButtonClass: T ): InstanceType<T> => {\n\t\tconst command = editor.commands.get( commandName )! as AttributeCommand;\n\t\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\n\t\tview.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\tkeystroke,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t\tview.bind( 'isOn' ).to( command, 'value' );\n\n\t\tif ( view instanceof MenuBarMenuListItemButtonView ) {\n\t\t\tview.set( {\n\t\t\t\trole: 'menuitemcheckbox'\n\t\t\t} );\n\t\t} else {\n\t\t\tview.set( {\n\t\t\t\ttooltip: true\n\t\t\t} );\n\t\t}\n\n\t\t// Execute the command.\n\t\tplugin.listenTo( view, 'execute', () => {\n\t\t\teditor.execute( commandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn view;\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/bold/boldui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\nimport { getButtonCreator } from '../utils.js';\n\nconst BOLD = 'bold';\n\n/**\n * The bold UI feature. It introduces the Bold button.\n */\nexport default class BoldUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'BoldUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst createButton = getButtonCreator( {\n\t\t\teditor,\n\t\t\tcommandName: BOLD,\n\t\t\tplugin: this,\n\t\t\ticon: icons.bold,\n\t\t\tlabel: t( 'Bold' ),\n\t\t\tkeystroke: 'CTRL+B'\n\t\t} );\n\n\t\t// Add bold button to feature components.\n\t\teditor.ui.componentFactory.add( BOLD, () => createButton( ButtonView ) );\n\t\teditor.ui.componentFactory.add( 'menuBar:' + BOLD, () => createButton( MenuBarMenuListItemButtonView ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/bold\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport BoldEditing from './bold/boldediting.js';\nimport BoldUI from './bold/boldui.js';\n\n/**\n * The bold feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/bold/boldediting~BoldEditing bold editing feature}\n * and {@link module:basic-styles/bold/boldui~BoldUI bold UI feature}.\n */\nexport default class Bold extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ BoldEditing, BoldUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Bold' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/code/codeediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { TwoStepCaretMovement, inlineHighlight } from 'ckeditor5/src/typing.js';\n\nimport AttributeCommand from '../attributecommand.js';\n\nconst CODE = 'code';\nconst HIGHLIGHT_CLASS = 'ck-code_selected';\n\n/**\n * The code editing feature.\n *\n * It registers the `'code'` command and introduces the `code` attribute in the model which renders to the view\n * as a `<code>` element.\n */\nexport default class CodeEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'CodeEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TwoStepCaretMovement ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\n\t\t// Allow code attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: CODE } );\n\t\teditor.model.schema.setAttributeProperties( CODE, {\n\t\t\tisFormatting: true,\n\t\t\tcopyOnEnter: false\n\t\t} );\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: CODE,\n\t\t\tview: 'code',\n\t\t\tupcastAlso: {\n\t\t\t\tstyles: {\n\t\t\t\t\t'word-wrap': 'break-word'\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Create code command.\n\t\teditor.commands.add( CODE, new AttributeCommand( editor, CODE ) );\n\n\t\t// Enable two-step caret movement for `code` attribute.\n\t\teditor.plugins.get( TwoStepCaretMovement ).registerAttribute( CODE );\n\n\t\t// Setup highlight over selected element.\n\t\tinlineHighlight( editor, CODE, 'code', HIGHLIGHT_CLASS );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move out of an inline code style' ),\n\t\t\t\t\tkeystroke: [\n\t\t\t\t\t\t[ 'arrowleft', 'arrowleft' ],\n\t\t\t\t\t\t[ 'arrowright', 'arrowright' ]\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/code/codeui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\nimport { getButtonCreator } from '../utils.js';\n\nimport codeIcon from '../../theme/icons/code.svg';\n\nimport '../../theme/code.css';\n\nconst CODE = 'code';\n\n/**\n * The code UI feature. It introduces the Code button.\n */\nexport default class CodeUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'CodeUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst createButton = getButtonCreator( {\n\t\t\teditor,\n\t\t\tcommandName: CODE,\n\t\t\tplugin: this,\n\t\t\ticon: codeIcon,\n\t\t\tlabel: t( 'Code' )\n\t\t} );\n\n\t\t// Add code button to feature components.\n\t\teditor.ui.componentFactory.add( CODE, () => createButton( ButtonView ) );\n\t\teditor.ui.componentFactory.add( 'menuBar:' + CODE, () => createButton( MenuBarMenuListItemButtonView ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/code\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport CodeEditing from './code/codeediting.js';\nimport CodeUI from './code/codeui.js';\n\nimport '../theme/code.css';\n\n/**\n * The code feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/code/codeediting~CodeEditing code editing feature}\n * and {@link module:basic-styles/code/codeui~CodeUI code UI feature}.\n */\nexport default class Code extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ CodeEditing, CodeUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Code' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/italic/italicediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport AttributeCommand from '../attributecommand.js';\n\nconst ITALIC = 'italic';\n\n/**\n * The italic editing feature.\n *\n * It registers the `'italic'` command, the <kbd>Ctrl+I</kbd> keystroke and introduces the `italic` attribute in the model\n * which renders to the view as an `<i>` element.\n */\nexport default class ItalicEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ItalicEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\n\t\t// Allow italic attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: ITALIC } );\n\t\teditor.model.schema.setAttributeProperties( ITALIC, {\n\t\t\tisFormatting: true,\n\t\t\tcopyOnEnter: true\n\t\t} );\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: ITALIC,\n\t\t\tview: 'i',\n\t\t\tupcastAlso: [\n\t\t\t\t'em',\n\t\t\t\t{\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\t'font-style': 'italic'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create italic command.\n\t\teditor.commands.add( ITALIC, new AttributeCommand( editor, ITALIC ) );\n\n\t\t// Set the Ctrl+I keystroke.\n\t\teditor.keystrokes.set( 'CTRL+I', ITALIC );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Italic text' ),\n\t\t\t\t\tkeystroke: 'CTRL+I'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/italic/italicui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { MenuBarMenuListItemButtonView, ButtonView } from 'ckeditor5/src/ui.js';\nimport { getButtonCreator } from '../utils.js';\n\nimport italicIcon from '../../theme/icons/italic.svg';\n\nconst ITALIC = 'italic';\n\n/**\n * The italic UI feature. It introduces the Italic button.\n */\nexport default class ItalicUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ItalicUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst createButton = getButtonCreator( {\n\t\t\teditor,\n\t\t\tcommandName: ITALIC,\n\t\t\tplugin: this,\n\t\t\ticon: italicIcon,\n\t\t\tkeystroke: 'CTRL+I',\n\t\t\tlabel: t( 'Italic' )\n\t\t} );\n\n\t\t// Add bold button to feature components.\n\t\teditor.ui.componentFactory.add( ITALIC, () => createButton( ButtonView ) );\n\t\teditor.ui.componentFactory.add( 'menuBar:' + ITALIC, () => createButton( MenuBarMenuListItemButtonView ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/italic\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ItalicEditing from './italic/italicediting.js';\nimport ItalicUI from './italic/italicui.js';\n\n/**\n * The italic feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/italic/italicediting~ItalicEditing} and\n * {@link module:basic-styles/italic/italicui~ItalicUI} plugins.\n */\nexport default class Italic extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ItalicEditing, ItalicUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Italic' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/strikethrough/strikethroughediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport AttributeCommand from '../attributecommand.js';\n\nconst STRIKETHROUGH = 'strikethrough';\n\n/**\n * The strikethrough editing feature.\n *\n * It registers the `'strikethrough'` command, the <kbd>Ctrl+Shift+X</kbd> keystroke and introduces the\n * `strikethroughsthrough` attribute in the model which renders to the view\n * as a `<s>` element.\n */\nexport default class StrikethroughEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'StrikethroughEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\n\t\t// Allow strikethrough attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: STRIKETHROUGH } );\n\t\teditor.model.schema.setAttributeProperties( STRIKETHROUGH, {\n\t\t\tisFormatting: true,\n\t\t\tcopyOnEnter: true\n\t\t} );\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: STRIKETHROUGH,\n\t\t\tview: 's',\n\t\t\tupcastAlso: [\n\t\t\t\t'del',\n\t\t\t\t'strike',\n\t\t\t\t{\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\t'text-decoration': 'line-through'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create strikethrough command.\n\t\teditor.commands.add( STRIKETHROUGH, new AttributeCommand( editor, STRIKETHROUGH ) );\n\n\t\t// Set the Ctrl+Shift+X keystroke.\n\t\teditor.keystrokes.set( 'CTRL+SHIFT+X', 'strikethrough' );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Strikethrough text' ),\n\t\t\t\t\tkeystroke: 'CTRL+SHIFT+X'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/strikethrough/strikethroughui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\nimport { getButtonCreator } from '../utils.js';\n\nimport strikethroughIcon from '../../theme/icons/strikethrough.svg';\n\nconst STRIKETHROUGH = 'strikethrough';\n\n/**\n * The strikethrough UI feature. It introduces the Strikethrough button.\n */\nexport default class StrikethroughUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'StrikethroughUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst createButton = getButtonCreator( {\n\t\t\teditor,\n\t\t\tcommandName: STRIKETHROUGH,\n\t\t\tplugin: this,\n\t\t\ticon: strikethroughIcon,\n\t\t\tkeystroke: 'CTRL+SHIFT+X',\n\t\t\tlabel: t( 'Strikethrough' )\n\t\t} );\n\n\t\t// Add strikethrough button to feature components.\n\t\teditor.ui.componentFactory.add( STRIKETHROUGH, () => createButton( ButtonView ) );\n\t\teditor.ui.componentFactory.add( 'menuBar:' + STRIKETHROUGH, () => createButton( MenuBarMenuListItemButtonView ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/strikethrough\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport StrikethroughEditing from './strikethrough/strikethroughediting.js';\nimport StrikethroughUI from './strikethrough/strikethroughui.js';\n\n/**\n * The strikethrough feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/strikethrough/strikethroughediting~StrikethroughEditing} and\n * {@link module:basic-styles/strikethrough/strikethroughui~StrikethroughUI} plugins.\n */\nexport default class Strikethrough extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ StrikethroughEditing, StrikethroughUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Strikethrough' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/subscript/subscriptediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport AttributeCommand from '../attributecommand.js';\n\nconst SUBSCRIPT = 'subscript';\n\n/**\n * The subscript editing feature.\n *\n * It registers the `sub` command and introduces the `sub` attribute in the model which renders to the view\n * as a `<sub>` element.\n */\nexport default class SubscriptEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SubscriptEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\t// Allow sub attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: SUBSCRIPT } );\n\t\teditor.model.schema.setAttributeProperties( SUBSCRIPT, {\n\t\t\tisFormatting: true,\n\t\t\tcopyOnEnter: true\n\t\t} );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: SUBSCRIPT,\n\t\t\tview: 'sub',\n\t\t\tupcastAlso: [\n\t\t\t\t{\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\t'vertical-align': 'sub'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create sub command.\n\t\teditor.commands.add( SUBSCRIPT, new AttributeCommand( editor, SUBSCRIPT ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/subscript/subscriptui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\nimport { getButtonCreator } from '../utils.js';\n\nimport subscriptIcon from '../../theme/icons/subscript.svg';\n\nconst SUBSCRIPT = 'subscript';\n\n/**\n * The subscript UI feature. It introduces the Subscript button.\n */\nexport default class SubscriptUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SubscriptUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\n\t\tconst createButton = getButtonCreator( {\n\t\t\teditor,\n\t\t\tcommandName: SUBSCRIPT,\n\t\t\tplugin: this,\n\t\t\ticon: subscriptIcon,\n\t\t\tlabel: t( 'Subscript' )\n\t\t} );\n\n\t\t// Add subscript button to feature components.\n\t\teditor.ui.componentFactory.add( SUBSCRIPT, () => createButton( ButtonView ) );\n\t\teditor.ui.componentFactory.add( 'menuBar:' + SUBSCRIPT, () => createButton( MenuBarMenuListItemButtonView ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/subscript\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport SubscriptEditing from './subscript/subscriptediting.js';\nimport SubscriptUI from './subscript/subscriptui.js';\n\n/**\n * The subscript feature.\n *\n * It loads the {@link module:basic-styles/subscript/subscriptediting~SubscriptEditing} and\n * {@link module:basic-styles/subscript/subscriptui~SubscriptUI} plugins.\n */\nexport default class Subscript extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ SubscriptEditing, SubscriptUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Subscript' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/superscript/superscriptediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport AttributeCommand from '../attributecommand.js';\n\nconst SUPERSCRIPT = 'superscript';\n\n/**\n * The superscript editing feature.\n *\n * It registers the `super` command and introduces the `super` attribute in the model which renders to the view\n * as a `<super>` element.\n */\nexport default class SuperscriptEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SuperscriptEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\t// Allow super attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: SUPERSCRIPT } );\n\t\teditor.model.schema.setAttributeProperties( SUPERSCRIPT, {\n\t\t\tisFormatting: true,\n\t\t\tcopyOnEnter: true\n\t\t} );\n\n\t\t// Build converter from model to view for data and editing pipelines.\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: SUPERSCRIPT,\n\t\t\tview: 'sup',\n\t\t\tupcastAlso: [\n\t\t\t\t{\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\t'vertical-align': 'super'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\n\t\t// Create super command.\n\t\teditor.commands.add( SUPERSCRIPT, new AttributeCommand( editor, SUPERSCRIPT ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/superscript/superscriptui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\nimport { getButtonCreator } from '../utils.js';\n\nimport superscriptIcon from '../../theme/icons/superscript.svg';\n\nconst SUPERSCRIPT = 'superscript';\n\n/**\n * The superscript UI feature. It introduces the Superscript button.\n */\nexport default class SuperscriptUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SuperscriptUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst createButton = getButtonCreator( {\n\t\t\teditor,\n\t\t\tcommandName: SUPERSCRIPT,\n\t\t\tplugin: this,\n\t\t\ticon: superscriptIcon,\n\t\t\tlabel: t( 'Superscript' )\n\t\t} );\n\n\t\t// Add superscript button to feature components.\n\t\teditor.ui.componentFactory.add( SUPERSCRIPT, () => createButton( ButtonView ) );\n\t\teditor.ui.componentFactory.add( 'menuBar:' + SUPERSCRIPT, () => createButton( MenuBarMenuListItemButtonView ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/superscript\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport SuperscriptEditing from './superscript/superscriptediting.js';\nimport SuperscriptUI from './superscript/superscriptui.js';\n\n/**\n * The superscript feature.\n *\n * It loads the {@link module:basic-styles/superscript/superscriptediting~SuperscriptEditing} and\n * {@link module:basic-styles/superscript/superscriptui~SuperscriptUI} plugins.\n */\nexport default class Superscript extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ SuperscriptEditing, SuperscriptUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Superscript' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/underline/underlineediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport AttributeCommand from '../attributecommand.js';\n\nconst UNDERLINE = 'underline';\n\n/**\n * The underline editing feature.\n *\n * It registers the `'underline'` command, the <kbd>Ctrl+U</kbd> keystroke\n * and introduces the `underline` attribute in the model which renders to the view as an `<u>` element.\n */\nexport default class UnderlineEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'UnderlineEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\n\t\t// Allow strikethrough attribute on text nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: UNDERLINE } );\n\t\teditor.model.schema.setAttributeProperties( UNDERLINE, {\n\t\t\tisFormatting: true,\n\t\t\tcopyOnEnter: true\n\t\t} );\n\n\t\teditor.conversion.attributeToElement( {\n\t\t\tmodel: UNDERLINE,\n\t\t\tview: 'u',\n\t\t\tupcastAlso: {\n\t\t\t\tstyles: {\n\t\t\t\t\t'text-decoration': 'underline'\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Create underline command.\n\t\teditor.commands.add( UNDERLINE, new AttributeCommand( editor, UNDERLINE ) );\n\n\t\t// Set the Ctrl+U keystroke.\n\t\teditor.keystrokes.set( 'CTRL+U', 'underline' );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Underline text' ),\n\t\t\t\t\tkeystroke: 'CTRL+U'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/underline/underlineui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\nimport { getButtonCreator } from '../utils.js';\n\nimport underlineIcon from '../../theme/icons/underline.svg';\n\nconst UNDERLINE = 'underline';\n\n/**\n * The underline UI feature. It introduces the Underline button.\n */\nexport default class UnderlineUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'UnderlineUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst createButton = getButtonCreator( {\n\t\t\teditor,\n\t\t\tcommandName: UNDERLINE,\n\t\t\tplugin: this,\n\t\t\ticon: underlineIcon,\n\t\t\tlabel: t( 'Underline' ),\n\t\t\tkeystroke: 'CTRL+U'\n\t\t} );\n\n\t\t// Add bold button to feature components.\n\t\teditor.ui.componentFactory.add( UNDERLINE, () => createButton( ButtonView ) );\n\t\teditor.ui.componentFactory.add( 'menuBar:' + UNDERLINE, () => createButton( MenuBarMenuListItemButtonView ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module basic-styles/underline\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport UnderlineEditing from './underline/underlineediting.js';\nimport UnderlineUI from './underline/underlineui.js';\n\n/**\n * The underline feature.\n *\n * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide\n * and the {@glink api/basic-styles package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:basic-styles/underline/underlineediting~UnderlineEditing} and\n * {@link module:basic-styles/underline/underlineui~UnderlineUI} plugins.\n */\nexport default class Underline extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ UnderlineEditing, UnderlineUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Underline' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { Observer, BubblingEventInfo, DomEventData } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { env } from '@ckeditor/ckeditor5-utils/dist/index.js';\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module enter/utils\n */ /**\n * Returns attributes that should be preserved on the enter keystroke.\n *\n * Filtering is realized based on `copyOnEnter` attribute property. Read more about attribute properties\n * {@link module:engine/model/schema~Schema#setAttributeProperties here}.\n *\n * @param schema Model's schema.\n * @param allAttributes Attributes to filter.\n */ function* getCopyOnEnterAttributes(schema, allAttributes) {\n    for (const attribute of allAttributes){\n        if (attribute && schema.getAttributeProperties(attribute[0]).copyOnEnter) {\n            yield attribute;\n        }\n    }\n}\n\n/**\n * Enter command used by the {@link module:enter/enter~Enter Enter feature} to handle the <kbd>Enter</kbd> keystroke.\n */ class EnterCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        this.editor.model.change((writer)=>{\n            this.enterBlock(writer);\n            this.fire('afterExecute', {\n                writer\n            });\n        });\n    }\n    /**\n\t * Splits a block where the document selection is placed, in the way how the <kbd>Enter</kbd> key is expected to work:\n\t *\n\t * ```\n\t * <p>Foo[]bar</p>   ->   <p>Foo</p><p>[]bar</p>\n\t * <p>Foobar[]</p>   ->   <p>Foobar</p><p>[]</p>\n\t * <p>Fo[ob]ar</p>   ->   <p>Fo</p><p>[]ar</p>\n\t * ```\n\t *\n\t * In some cases, the split will not happen:\n\t *\n\t * ```\n\t * // The selection parent is a limit element:\n\t * <figcaption>A[bc]d</figcaption>   ->   <figcaption>A[]d</figcaption>\n\t *\n\t * // The selection spans over multiple elements:\n\t * <h>x[x</h><p>y]y<p>   ->   <h>x</h><p>[]y</p>\n\t * ```\n\t *\n\t * @param writer Writer to use when performing the enter action.\n\t * @returns Boolean indicating if the block was split.\n\t */ enterBlock(writer) {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const schema = model.schema;\n        const isSelectionEmpty = selection.isCollapsed;\n        const range = selection.getFirstRange();\n        const startElement = range.start.parent;\n        const endElement = range.end.parent;\n        // Don't touch the roots and other limit elements.\n        if (schema.isLimit(startElement) || schema.isLimit(endElement)) {\n            // Delete the selected content but only if inside a single limit element.\n            // Abort, when crossing limit elements boundary (e.g. <limit1>x[x</limit1>donttouchme<limit2>y]y</limit2>).\n            // This is an edge case and it's hard to tell what should actually happen because such a selection\n            // is not entirely valid.\n            if (!isSelectionEmpty && startElement == endElement) {\n                model.deleteContent(selection);\n            }\n            return false;\n        }\n        if (isSelectionEmpty) {\n            const attributesToCopy = getCopyOnEnterAttributes(writer.model.schema, selection.getAttributes());\n            splitBlock(writer, range.start);\n            writer.setSelectionAttribute(attributesToCopy);\n            return true;\n        } else {\n            const leaveUnmerged = !(range.start.isAtStart && range.end.isAtEnd);\n            const isContainedWithinOneElement = startElement == endElement;\n            model.deleteContent(selection, {\n                leaveUnmerged\n            });\n            if (leaveUnmerged) {\n                // Partially selected elements.\n                //\n                // <h>x[xx]x</h>\t\t-> <h>x^x</h>\t\t\t-> <h>x</h><h>^x</h>\n                if (isContainedWithinOneElement) {\n                    splitBlock(writer, selection.focus);\n                    return true;\n                } else {\n                    writer.setSelection(endElement, 0);\n                }\n            }\n        }\n        return false;\n    }\n}\nfunction splitBlock(writer, splitPos) {\n    writer.split(splitPos);\n    writer.setSelection(splitPos.parent.nextSibling, 0);\n}\n\nconst ENTER_EVENT_TYPES = {\n    insertParagraph: {\n        isSoft: false\n    },\n    insertLineBreak: {\n        isSoft: true\n    }\n};\n/**\n * Enter observer introduces the {@link module:engine/view/document~Document#event:enter `Document#enter`} event.\n */ class EnterObserver extends Observer {\n    /**\n\t * @inheritDoc\n\t */ constructor(view){\n        super(view);\n        const doc = this.document;\n        let shiftPressed = false;\n        doc.on('keydown', (evt, data)=>{\n            shiftPressed = data.shiftKey;\n        });\n        doc.on('beforeinput', (evt, data)=>{\n            if (!this.isEnabled) {\n                return;\n            }\n            let inputType = data.inputType;\n            // See https://github.com/ckeditor/ckeditor5/issues/13321.\n            if (env.isSafari && shiftPressed && inputType == 'insertParagraph') {\n                inputType = 'insertLineBreak';\n            }\n            const domEvent = data.domEvent;\n            const enterEventSpec = ENTER_EVENT_TYPES[inputType];\n            if (!enterEventSpec) {\n                return;\n            }\n            const event = new BubblingEventInfo(doc, 'enter', data.targetRanges[0]);\n            doc.fire(event, new DomEventData(view, domEvent, {\n                isSoft: enterEventSpec.isSoft\n            }));\n            // Stop `beforeinput` event if `enter` event was stopped.\n            // https://github.com/ckeditor/ckeditor5/issues/753\n            if (event.stop.called) {\n                evt.stop();\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ observe() {}\n    /**\n\t * @inheritDoc\n\t */ stopObserving() {}\n}\n\n/**\n * This plugin handles the <kbd>Enter</kbd> keystroke (hard line break) in the editor.\n *\n * See also the {@link module:enter/shiftenter~ShiftEnter} plugin.\n *\n * For more information about this feature see the {@glink api/enter package page}.\n */ class Enter extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Enter';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    init() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const t = this.editor.t;\n        view.addObserver(EnterObserver);\n        editor.commands.add('enter', new EnterCommand(editor));\n        this.listenTo(viewDocument, 'enter', (evt, data)=>{\n            // When not in composition, we handle the action, so prevent the default one.\n            // When in composition, it's the browser who modify the DOM (renderer is disabled).\n            if (!viewDocument.isComposing) {\n                data.preventDefault();\n            }\n            // The soft enter key is handled by the ShiftEnter plugin.\n            if (data.isSoft) {\n                return;\n            }\n            editor.execute('enter');\n            view.scrollToTheSelection();\n        }, {\n            priority: 'low'\n        });\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Insert a hard break (a new paragraph)'),\n                    keystroke: 'Enter'\n                }\n            ]\n        });\n    }\n}\n\n/**\n * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle\n * the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke.\n */ class ShiftEnterCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const model = this.editor.model;\n        const doc = model.document;\n        model.change((writer)=>{\n            softBreakAction(model, writer, doc.selection);\n            this.fire('afterExecute', {\n                writer\n            });\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const doc = model.document;\n        this.isEnabled = isEnabled(model.schema, doc.selection);\n    }\n}\n/**\n * Checks whether the ShiftEnter command should be enabled in the specified selection.\n */ function isEnabled(schema, selection) {\n    // At this moment it is okay to support single range selections only.\n    // But in the future we may need to change that.\n    if (selection.rangeCount > 1) {\n        return false;\n    }\n    const anchorPos = selection.anchor;\n    // Check whether the break element can be inserted in the current selection anchor.\n    if (!anchorPos || !schema.checkChild(anchorPos, 'softBreak')) {\n        return false;\n    }\n    const range = selection.getFirstRange();\n    const startElement = range.start.parent;\n    const endElement = range.end.parent;\n    // Do not modify the content if selection is cross-limit elements.\n    if ((isInsideLimitElement(startElement, schema) || isInsideLimitElement(endElement, schema)) && startElement !== endElement) {\n        return false;\n    }\n    return true;\n}\n/**\n * Creates a break in the way that the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke is expected to work.\n */ function softBreakAction(model, writer, selection) {\n    const isSelectionEmpty = selection.isCollapsed;\n    const range = selection.getFirstRange();\n    const startElement = range.start.parent;\n    const endElement = range.end.parent;\n    const isContainedWithinOneElement = startElement == endElement;\n    if (isSelectionEmpty) {\n        const attributesToCopy = getCopyOnEnterAttributes(model.schema, selection.getAttributes());\n        insertBreak(model, writer, range.end);\n        writer.removeSelectionAttribute(selection.getAttributeKeys());\n        writer.setSelectionAttribute(attributesToCopy);\n    } else {\n        const leaveUnmerged = !(range.start.isAtStart && range.end.isAtEnd);\n        model.deleteContent(selection, {\n            leaveUnmerged\n        });\n        // Selection within one element:\n        //\n        // <h>x[xx]x</h>\t\t-> <h>x^x</h>\t\t\t-> <h>x<br>^x</h>\n        if (isContainedWithinOneElement) {\n            insertBreak(model, writer, selection.focus);\n        } else {\n            // Move the selection to the 2nd element (last step of the example above).\n            if (leaveUnmerged) {\n                writer.setSelection(endElement, 0);\n            }\n        }\n    }\n}\nfunction insertBreak(model, writer, position) {\n    const breakLineElement = writer.createElement('softBreak');\n    model.insertContent(breakLineElement, position);\n    writer.setSelection(breakLineElement, 'after');\n}\n/**\n * Checks whether the specified `element` is a child of the limit element.\n *\n * Checking whether the `<p>` element is inside a limit element:\n *   - `<$root><p>Text.</p></$root> => false`\n *   - `<$root><limitElement><p>Text</p></limitElement></$root> => true`\n */ function isInsideLimitElement(element, schema) {\n    // `$root` is a limit element but in this case is an invalid element.\n    if (element.is('rootElement')) {\n        return false;\n    }\n    return schema.isLimit(element) || isInsideLimitElement(element.parent, schema);\n}\n\n/**\n * This plugin handles the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke (soft line break) in the editor.\n *\n * See also the {@link module:enter/enter~Enter} plugin.\n *\n * For more information about this feature see the {@glink api/enter package page}.\n */ class ShiftEnter extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ShiftEnter';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const conversion = editor.conversion;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const t = this.editor.t;\n        // Configure the schema.\n        schema.register('softBreak', {\n            allowWhere: '$text',\n            isInline: true\n        });\n        // Configure converters.\n        conversion.for('upcast').elementToElement({\n            model: 'softBreak',\n            view: 'br'\n        });\n        conversion.for('downcast').elementToElement({\n            model: 'softBreak',\n            view: (modelElement, { writer })=>writer.createEmptyElement('br')\n        });\n        view.addObserver(EnterObserver);\n        editor.commands.add('shiftEnter', new ShiftEnterCommand(editor));\n        this.listenTo(viewDocument, 'enter', (evt, data)=>{\n            // When not in composition, we handle the action, so prevent the default one.\n            // When in composition, it's the browser who modify the DOM (renderer is disabled).\n            if (!viewDocument.isComposing) {\n                data.preventDefault();\n            }\n            // The hard enter key is handled by the Enter plugin.\n            if (!data.isSoft) {\n                return;\n            }\n            editor.execute('shiftEnter');\n            view.scrollToTheSelection();\n        }, {\n            priority: 'low'\n        });\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Insert a soft break (a <code>&lt;br&gt;</code> element)'),\n                    keystroke: 'Shift+Enter'\n                }\n            ]\n        });\n    }\n}\n\nexport { Enter, ShiftEnter };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module enter/utils\n */\n\nimport type { Schema } from '@ckeditor/ckeditor5-engine';\n\n/**\n * Returns attributes that should be preserved on the enter keystroke.\n *\n * Filtering is realized based on `copyOnEnter` attribute property. Read more about attribute properties\n * {@link module:engine/model/schema~Schema#setAttributeProperties here}.\n *\n * @param schema Model's schema.\n * @param allAttributes Attributes to filter.\n */\nexport function* getCopyOnEnterAttributes(\n\tschema: Schema,\n\tallAttributes: Iterable<[ string, unknown ]>\n): IterableIterator<[ string, unknown ]> {\n\tfor ( const attribute of allAttributes ) {\n\t\tif ( attribute && schema.getAttributeProperties( attribute[ 0 ] ).copyOnEnter ) {\n\t\t\tyield attribute;\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module enter/entercommand\n */\n\nimport { Command } from '@ckeditor/ckeditor5-core';\nimport { getCopyOnEnterAttributes } from './utils.js';\n\nimport type {\n\tElement,\n\tPosition,\n\tWriter\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * Enter command used by the {@link module:enter/enter~Enter Enter feature} to handle the <kbd>Enter</kbd> keystroke.\n */\nexport default class EnterCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tthis.editor.model.change( writer => {\n\t\t\tthis.enterBlock( writer );\n\t\t\tthis.fire<EnterCommandAfterExecuteEvent>( 'afterExecute', { writer } );\n\t\t} );\n\t}\n\n\t/**\n\t * Splits a block where the document selection is placed, in the way how the <kbd>Enter</kbd> key is expected to work:\n\t *\n\t * ```\n\t * <p>Foo[]bar</p>   ->   <p>Foo</p><p>[]bar</p>\n\t * <p>Foobar[]</p>   ->   <p>Foobar</p><p>[]</p>\n\t * <p>Fo[ob]ar</p>   ->   <p>Fo</p><p>[]ar</p>\n\t * ```\n\t *\n\t * In some cases, the split will not happen:\n\t *\n\t * ```\n\t * // The selection parent is a limit element:\n\t * <figcaption>A[bc]d</figcaption>   ->   <figcaption>A[]d</figcaption>\n\t *\n\t * // The selection spans over multiple elements:\n\t * <h>x[x</h><p>y]y<p>   ->   <h>x</h><p>[]y</p>\n\t * ```\n\t *\n\t * @param writer Writer to use when performing the enter action.\n\t * @returns Boolean indicating if the block was split.\n\t */\n\tpublic enterBlock( writer: Writer ): boolean {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst schema = model.schema;\n\t\tconst isSelectionEmpty = selection.isCollapsed;\n\t\tconst range = selection.getFirstRange()!;\n\t\tconst startElement = range.start.parent as Element;\n\t\tconst endElement = range.end.parent as Element;\n\n\t\t// Don't touch the roots and other limit elements.\n\t\tif ( schema.isLimit( startElement ) || schema.isLimit( endElement ) ) {\n\t\t\t// Delete the selected content but only if inside a single limit element.\n\t\t\t// Abort, when crossing limit elements boundary (e.g. <limit1>x[x</limit1>donttouchme<limit2>y]y</limit2>).\n\t\t\t// This is an edge case and it's hard to tell what should actually happen because such a selection\n\t\t\t// is not entirely valid.\n\t\t\tif ( !isSelectionEmpty && startElement == endElement ) {\n\t\t\t\tmodel.deleteContent( selection );\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( isSelectionEmpty ) {\n\t\t\tconst attributesToCopy = getCopyOnEnterAttributes( writer.model.schema, selection.getAttributes() );\n\n\t\t\tsplitBlock( writer, range.start );\n\t\t\twriter.setSelectionAttribute( attributesToCopy );\n\n\t\t\treturn true;\n\t\t} else {\n\t\t\tconst leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd );\n\t\t\tconst isContainedWithinOneElement = ( startElement == endElement );\n\n\t\t\tmodel.deleteContent( selection, { leaveUnmerged } );\n\n\t\t\tif ( leaveUnmerged ) {\n\t\t\t\t// Partially selected elements.\n\t\t\t\t//\n\t\t\t\t// <h>x[xx]x</h>\t\t-> <h>x^x</h>\t\t\t-> <h>x</h><h>^x</h>\n\t\t\t\tif ( isContainedWithinOneElement ) {\n\t\t\t\t\tsplitBlock( writer, selection.focus! );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\t// Selection over multiple elements.\n\t\t\t\t//\n\t\t\t\t// <h>x[x</h><p>y]y<p>\t-> <h>x^</h><p>y</p>\t-> <h>x</h><p>^y</p>\n\t\t\t\telse {\n\t\t\t\t\twriter.setSelection( endElement, 0 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n/**\n * Fired after the the {@link module:enter/entercommand~EnterCommand} is finished executing.\n *\n * @eventName ~EnterCommand#afterExecute\n */\nexport type EnterCommandAfterExecuteEvent = {\n\tname: 'afterExecute';\n\targs: [ { writer: Writer } ];\n};\n\nfunction splitBlock( writer: Writer, splitPos: Position ): void {\n\twriter.split( splitPos );\n\twriter.setSelection( splitPos.parent.nextSibling!, 0 );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module enter/enterobserver\n */\n\nimport {\n\tObserver,\n\tDomEventData,\n\tBubblingEventInfo,\n\ttype EditingView,\n\ttype ViewDocumentInputEvent,\n\ttype BubblingEvent,\n\ttype ViewDocumentKeyDownEvent\n} from '@ckeditor/ckeditor5-engine';\n\nimport { env } from '@ckeditor/ckeditor5-utils';\n\nconst ENTER_EVENT_TYPES: Record<string, { isSoft: boolean }> = {\n\tinsertParagraph: { isSoft: false },\n\tinsertLineBreak: { isSoft: true }\n};\n\n/**\n * Enter observer introduces the {@link module:engine/view/document~Document#event:enter `Document#enter`} event.\n */\nexport default class EnterObserver extends Observer {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view: EditingView ) {\n\t\tsuper( view );\n\n\t\tconst doc = this.document;\n\t\tlet shiftPressed = false;\n\n\t\tdoc.on<ViewDocumentKeyDownEvent>( 'keydown', ( evt, data ) => {\n\t\t\tshiftPressed = data.shiftKey;\n\t\t} );\n\n\t\tdoc.on<ViewDocumentInputEvent>( 'beforeinput', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet inputType = data.inputType;\n\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/13321.\n\t\t\tif ( env.isSafari && shiftPressed && inputType == 'insertParagraph' ) {\n\t\t\t\tinputType = 'insertLineBreak';\n\t\t\t}\n\n\t\t\tconst domEvent = data.domEvent;\n\t\t\tconst enterEventSpec = ENTER_EVENT_TYPES[ inputType ];\n\n\t\t\tif ( !enterEventSpec ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst event = new BubblingEventInfo( doc, 'enter', data.targetRanges[ 0 ] );\n\n\t\t\tdoc.fire( event, new DomEventData( view, domEvent, {\n\t\t\t\tisSoft: enterEventSpec.isSoft\n\t\t\t} ) );\n\n\t\t\t// Stop `beforeinput` event if `enter` event was stopped.\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/753\n\t\t\tif ( event.stop.called ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic observe(): void {}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic stopObserving(): void {}\n}\n\n/**\n * Fired when the user presses the <kbd>Enter</kbd> key.\n *\n * Note: This event is fired by the {@link module:enter/enterobserver~EnterObserver observer}\n * (usually registered by the {@link module:enter/enter~Enter Enter feature} and\n * {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature}).\n *\n * @eventName module:engine/view/document~Document#enter\n */\nexport type ViewDocumentEnterEvent = BubblingEvent<{\n\tname: 'enter';\n\targs: [ EnterEventData ];\n}>;\n\nexport interface EnterEventData extends DomEventData<InputEvent> {\n\n\t/**\n\t * Whether it is a soft enter (<kbd>Shift</kbd>+<kbd>Enter</kbd>) or a hard enter (<kbd>Enter</kbd>).\n\t */\n\tisSoft: boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module enter/enter\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport EnterCommand from './entercommand.js';\nimport EnterObserver, { type ViewDocumentEnterEvent } from './enterobserver.js';\n\n/**\n * This plugin handles the <kbd>Enter</kbd> keystroke (hard line break) in the editor.\n *\n * See also the {@link module:enter/shiftenter~ShiftEnter} plugin.\n *\n * For more information about this feature see the {@glink api/enter package page}.\n */\nexport default class Enter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Enter' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst t = this.editor.t;\n\n\t\tview.addObserver( EnterObserver );\n\n\t\teditor.commands.add( 'enter', new EnterCommand( editor ) );\n\n\t\tthis.listenTo<ViewDocumentEnterEvent>( viewDocument, 'enter', ( evt, data ) => {\n\t\t\t// When not in composition, we handle the action, so prevent the default one.\n\t\t\t// When in composition, it's the browser who modify the DOM (renderer is disabled).\n\t\t\tif ( !viewDocument.isComposing ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t}\n\n\t\t\t// The soft enter key is handled by the ShiftEnter plugin.\n\t\t\tif ( data.isSoft ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.execute( 'enter' );\n\n\t\t\tview.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Insert a hard break (a new paragraph)' ),\n\t\t\t\t\tkeystroke: 'Enter'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module enter/shiftentercommand\n */\n\nimport { Command } from '@ckeditor/ckeditor5-core';\nimport { getCopyOnEnterAttributes } from './utils.js';\n\nimport type {\n\tDocumentSelection,\n\tModel,\n\tPosition,\n\tSchema,\n\tElement,\n\tWriter\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle\n * the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke.\n */\nexport default class ShiftEnterCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tmodel.change( writer => {\n\t\t\tsoftBreakAction( model, writer, doc.selection );\n\t\t\tthis.fire<ShiftEnterCommandAfterExecuteEvent>( 'afterExecute', { writer } );\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tthis.isEnabled = isEnabled( model.schema, doc.selection );\n\t}\n}\n\n/**\n * Fired after the the {@link module:enter/shiftentercommand~ShiftEnterCommand} is finished executing.\n *\n * @eventName ~ShiftEnterCommand#afterExecute\n */\nexport type ShiftEnterCommandAfterExecuteEvent = {\n\tname: 'afterExecute';\n\targs: [ { writer: Writer } ];\n};\n\n/**\n * Checks whether the ShiftEnter command should be enabled in the specified selection.\n */\nfunction isEnabled( schema: Schema, selection: DocumentSelection ): boolean {\n\t// At this moment it is okay to support single range selections only.\n\t// But in the future we may need to change that.\n\tif ( selection.rangeCount > 1 ) {\n\t\treturn false;\n\t}\n\n\tconst anchorPos = selection.anchor;\n\n\t// Check whether the break element can be inserted in the current selection anchor.\n\tif ( !anchorPos || !schema.checkChild( anchorPos, 'softBreak' ) ) {\n\t\treturn false;\n\t}\n\n\tconst range = selection.getFirstRange()!;\n\tconst startElement = range.start.parent as Element;\n\tconst endElement = range.end.parent as Element;\n\n\t// Do not modify the content if selection is cross-limit elements.\n\tif ( ( isInsideLimitElement( startElement, schema ) || isInsideLimitElement( endElement, schema ) ) && startElement !== endElement ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Creates a break in the way that the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke is expected to work.\n */\nfunction softBreakAction( model: Model, writer: Writer, selection: DocumentSelection ): void {\n\tconst isSelectionEmpty = selection.isCollapsed;\n\tconst range = selection.getFirstRange()!;\n\tconst startElement = range.start.parent as Element;\n\tconst endElement = range.end.parent as Element;\n\tconst isContainedWithinOneElement = ( startElement == endElement );\n\n\tif ( isSelectionEmpty ) {\n\t\tconst attributesToCopy = getCopyOnEnterAttributes( model.schema, selection.getAttributes() );\n\n\t\tinsertBreak( model, writer, range.end );\n\n\t\twriter.removeSelectionAttribute( selection.getAttributeKeys() );\n\t\twriter.setSelectionAttribute( attributesToCopy );\n\t} else {\n\t\tconst leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd );\n\n\t\tmodel.deleteContent( selection, { leaveUnmerged } );\n\n\t\t// Selection within one element:\n\t\t//\n\t\t// <h>x[xx]x</h>\t\t-> <h>x^x</h>\t\t\t-> <h>x<br>^x</h>\n\t\tif ( isContainedWithinOneElement ) {\n\t\t\tinsertBreak( model, writer, selection.focus! );\n\t\t}\n\t\t// Selection over multiple elements.\n\t\t//\n\t\t// <h>x[x</h><p>y]y<p>\t-> <h>x^</h><p>y</p>\t-> <h>x</h><p>^y</p>\n\t\t//\n\t\t// We chose not to insert a line break in this case because:\n\t\t//\n\t\t// * it's not a very common scenario,\n\t\t// * it actually surprised me when I saw the \"expected behavior\" in real life.\n\t\t//\n\t\t// It's ok if the user will need to be more specific where they want the <br> to be inserted.\n\t\telse {\n\t\t\t// Move the selection to the 2nd element (last step of the example above).\n\t\t\tif ( leaveUnmerged ) {\n\t\t\t\twriter.setSelection( endElement, 0 );\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction insertBreak( model: Model, writer: Writer, position: Position ): void {\n\tconst breakLineElement = writer.createElement( 'softBreak' );\n\n\tmodel.insertContent( breakLineElement, position );\n\twriter.setSelection( breakLineElement, 'after' );\n}\n\n/**\n * Checks whether the specified `element` is a child of the limit element.\n *\n * Checking whether the `<p>` element is inside a limit element:\n *   - `<$root><p>Text.</p></$root> => false`\n *   - `<$root><limitElement><p>Text</p></limitElement></$root> => true`\n */\nfunction isInsideLimitElement( element: Element, schema: Schema ): boolean {\n\t// `$root` is a limit element but in this case is an invalid element.\n\tif ( element.is( 'rootElement' ) ) {\n\t\treturn false;\n\t}\n\n\treturn schema.isLimit( element ) || isInsideLimitElement( element.parent as Element, schema );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module enter/shiftenter\n */\n\nimport ShiftEnterCommand from './shiftentercommand.js';\nimport EnterObserver, { type ViewDocumentEnterEvent } from './enterobserver.js';\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\n/**\n * This plugin handles the <kbd>Shift</kbd>+<kbd>Enter</kbd> keystroke (soft line break) in the editor.\n *\n * See also the {@link module:enter/enter~Enter} plugin.\n *\n * For more information about this feature see the {@glink api/enter package page}.\n */\nexport default class ShiftEnter extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ShiftEnter' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst t = this.editor.t;\n\n\t\t// Configure the schema.\n\t\tschema.register( 'softBreak', {\n\t\t\tallowWhere: '$text',\n\t\t\tisInline: true\n\t\t} );\n\n\t\t// Configure converters.\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'softBreak',\n\t\t\t\tview: 'br'\n\t\t\t} );\n\n\t\tconversion.for( 'downcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'softBreak',\n\t\t\t\tview: ( modelElement, { writer } ) => writer.createEmptyElement( 'br' )\n\t\t\t} );\n\n\t\tview.addObserver( EnterObserver );\n\n\t\teditor.commands.add( 'shiftEnter', new ShiftEnterCommand( editor ) );\n\n\t\tthis.listenTo<ViewDocumentEnterEvent>( viewDocument, 'enter', ( evt, data ) => {\n\t\t\t// When not in composition, we handle the action, so prevent the default one.\n\t\t\t// When in composition, it's the browser who modify the DOM (renderer is disabled).\n\t\t\tif ( !viewDocument.isComposing ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t}\n\n\t\t\t// The hard enter key is handled by the Enter plugin.\n\t\t\tif ( !data.isSoft ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.execute( 'shiftEnter' );\n\t\t\tview.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Insert a soft break (a <code>&lt;br&gt;</code> element)' ),\n\t\t\t\t\tkeystroke: 'Shift+Enter'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';\nimport { Delete } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { first } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\n\n/**\n * The block quote command plugin.\n *\n * @extends module:core/command~Command\n */ class BlockQuoteCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.value = this._getValue();\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Executes the command. When the command {@link #value is on}, all top-most block quotes within\n\t * the selection will be removed. If it is off, all selected blocks will be wrapped with\n\t * a block quote.\n\t *\n\t * @fires execute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote,\n\t * otherwise the command will remove the block quote. If not set, the command will act basing on its current value.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const schema = model.schema;\n        const selection = model.document.selection;\n        const blocks = Array.from(selection.getSelectedBlocks());\n        const value = options.forceValue === undefined ? !this.value : options.forceValue;\n        model.change((writer)=>{\n            if (!value) {\n                this._removeQuote(writer, blocks.filter(findQuote));\n            } else {\n                const blocksToQuote = blocks.filter((block)=>{\n                    // Already quoted blocks needs to be considered while quoting too\n                    // in order to reuse their <bQ> elements.\n                    return findQuote(block) || checkCanBeQuoted(schema, block);\n                });\n                this._applyQuote(writer, blocksToQuote);\n            }\n        });\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t */ _getValue() {\n        const selection = this.editor.model.document.selection;\n        const firstBlock = first(selection.getSelectedBlocks());\n        // In the current implementation, the block quote must be an immediate parent of a block element.\n        return !!(firstBlock && findQuote(firstBlock));\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        if (this.value) {\n            return true;\n        }\n        const selection = this.editor.model.document.selection;\n        const schema = this.editor.model.schema;\n        const firstBlock = first(selection.getSelectedBlocks());\n        if (!firstBlock) {\n            return false;\n        }\n        return checkCanBeQuoted(schema, firstBlock);\n    }\n    /**\n\t * Removes the quote from given blocks.\n\t *\n\t * If blocks which are supposed to be \"unquoted\" are in the middle of a quote,\n\t * start it or end it, then the quote will be split (if needed) and the blocks\n\t * will be moved out of it, so other quoted blocks remained quoted.\n\t */ _removeQuote(writer, blocks) {\n        // Unquote all groups of block. Iterate in the reverse order to not break following ranges.\n        getRangesOfBlockGroups(writer, blocks).reverse().forEach((groupRange)=>{\n            if (groupRange.start.isAtStart && groupRange.end.isAtEnd) {\n                writer.unwrap(groupRange.start.parent);\n                return;\n            }\n            // The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).\n            if (groupRange.start.isAtStart) {\n                const positionBefore = writer.createPositionBefore(groupRange.start.parent);\n                writer.move(groupRange, positionBefore);\n                return;\n            }\n            // The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block\n            // so we move the items there.\n            if (!groupRange.end.isAtEnd) {\n                writer.split(groupRange.end);\n            }\n            // Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.\n            const positionAfter = writer.createPositionAfter(groupRange.end.parent);\n            writer.move(groupRange, positionAfter);\n        });\n    }\n    /**\n\t * Applies the quote to given blocks.\n\t */ _applyQuote(writer, blocks) {\n        const quotesToMerge = [];\n        // Quote all groups of block. Iterate in the reverse order to not break following ranges.\n        getRangesOfBlockGroups(writer, blocks).reverse().forEach((groupRange)=>{\n            let quote = findQuote(groupRange.start);\n            if (!quote) {\n                quote = writer.createElement('blockQuote');\n                writer.wrap(groupRange, quote);\n            }\n            quotesToMerge.push(quote);\n        });\n        // Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through\n        // the <bQ> elements in the source order (due to how merge works – it moves the right element's content\n        // to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements\n        // we want to keep the reference to the first (furthest left) one.\n        quotesToMerge.reverse().reduce((currentQuote, nextQuote)=>{\n            if (currentQuote.nextSibling == nextQuote) {\n                writer.merge(writer.createPositionAfter(currentQuote));\n                return currentQuote;\n            }\n            return nextQuote;\n        });\n    }\n}\nfunction findQuote(elementOrPosition) {\n    return elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null;\n}\n/**\n * Returns a minimal array of ranges containing groups of subsequent blocks.\n *\n * content:         abcdefgh\n * blocks:          [ a, b, d, f, g, h ]\n * output ranges:   [ab]c[d]e[fgh]\n */ function getRangesOfBlockGroups(writer, blocks) {\n    let startPosition;\n    let i = 0;\n    const ranges = [];\n    while(i < blocks.length){\n        const block = blocks[i];\n        const nextBlock = blocks[i + 1];\n        if (!startPosition) {\n            startPosition = writer.createPositionBefore(block);\n        }\n        if (!nextBlock || block.nextSibling != nextBlock) {\n            ranges.push(writer.createRange(startPosition, writer.createPositionAfter(block)));\n            startPosition = null;\n        }\n        i++;\n    }\n    return ranges;\n}\n/**\n * Checks whether <bQ> can wrap the block.\n */ function checkCanBeQuoted(schema, block) {\n    // TMP will be replaced with schema.checkWrap().\n    const isBQAllowed = schema.checkChild(block.parent, 'blockQuote');\n    const isBlockAllowedInBQ = schema.checkChild([\n        '$root',\n        'blockQuote'\n    ], block);\n    return isBQAllowed && isBlockAllowedInBQ;\n}\n\n/**\n * The block quote editing.\n *\n * Introduces the `'blockQuote'` command and the `'blockQuote'` model element.\n *\n * @extends module:core/plugin~Plugin\n */ class BlockQuoteEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'BlockQuoteEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Enter,\n            Delete\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        editor.commands.add('blockQuote', new BlockQuoteCommand(editor));\n        schema.register('blockQuote', {\n            inheritAllFrom: '$container'\n        });\n        editor.conversion.elementToElement({\n            model: 'blockQuote',\n            view: 'blockquote'\n        });\n        // Postfixer which cleans incorrect model states connected with block quotes.\n        editor.model.document.registerPostFixer((writer)=>{\n            const changes = editor.model.document.differ.getChanges();\n            for (const entry of changes){\n                if (entry.type == 'insert') {\n                    const element = entry.position.nodeAfter;\n                    if (!element) {\n                        continue;\n                    }\n                    if (element.is('element', 'blockQuote') && element.isEmpty) {\n                        // Added an empty blockQuote - remove it.\n                        writer.remove(element);\n                        return true;\n                    } else if (element.is('element', 'blockQuote') && !schema.checkChild(entry.position, element)) {\n                        // Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost.\n                        writer.unwrap(element);\n                        return true;\n                    } else if (element.is('element')) {\n                        // Just added an element. Check that all children meet the scheme rules.\n                        const range = writer.createRangeIn(element);\n                        for (const child of range.getItems()){\n                            if (child.is('element', 'blockQuote') && !schema.checkChild(writer.createPositionBefore(child), child)) {\n                                writer.unwrap(child);\n                                return true;\n                            }\n                        }\n                    }\n                } else if (entry.type == 'remove') {\n                    const parent = entry.position.parent;\n                    if (parent.is('element', 'blockQuote') && parent.isEmpty) {\n                        // Something got removed and now blockQuote is empty. Remove the blockQuote as well.\n                        writer.remove(parent);\n                        return true;\n                    }\n                }\n            }\n            return false;\n        });\n        const viewDocument = this.editor.editing.view.document;\n        const selection = editor.model.document.selection;\n        const blockQuoteCommand = editor.commands.get('blockQuote');\n        // Overwrite default Enter key behavior.\n        // If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.\n        this.listenTo(viewDocument, 'enter', (evt, data)=>{\n            if (!selection.isCollapsed || !blockQuoteCommand.value) {\n                return;\n            }\n            const positionParent = selection.getLastPosition().parent;\n            if (positionParent.isEmpty) {\n                editor.execute('blockQuote');\n                editor.editing.view.scrollToTheSelection();\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: 'blockquote'\n        });\n        // Overwrite default Backspace key behavior.\n        // If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote.\n        this.listenTo(viewDocument, 'delete', (evt, data)=>{\n            if (data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand.value) {\n                return;\n            }\n            const positionParent = selection.getLastPosition().parent;\n            if (positionParent.isEmpty && !positionParent.previousSibling) {\n                editor.execute('blockQuote');\n                editor.editing.view.scrollToTheSelection();\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: 'blockquote'\n        });\n    }\n}\n\n/**\n * The block quote UI plugin.\n *\n * It introduces the `'blockQuote'` button.\n *\n * @extends module:core/plugin~Plugin\n */ class BlockQuoteUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'BlockQuoteUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        editor.ui.componentFactory.add('blockQuote', ()=>{\n            const buttonView = this._createButton(ButtonView);\n            buttonView.set({\n                tooltip: true\n            });\n            return buttonView;\n        });\n        editor.ui.componentFactory.add('menuBar:blockQuote', ()=>{\n            const buttonView = this._createButton(MenuBarMenuListItemButtonView);\n            buttonView.set({\n                role: 'menuitemcheckbox'\n            });\n            return buttonView;\n        });\n    }\n    /**\n\t * Creates a button for block quote command to use either in toolbar or in menu bar.\n\t */ _createButton(ButtonClass) {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const command = editor.commands.get('blockQuote');\n        const view = new ButtonClass(editor.locale);\n        const t = locale.t;\n        view.set({\n            label: t('Block quote'),\n            icon: icons.quote,\n            isToggleable: true\n        });\n        view.bind('isEnabled').to(command, 'isEnabled');\n        view.bind('isOn').to(command, 'value');\n        // Execute the command.\n        this.listenTo(view, 'execute', ()=>{\n            editor.execute('blockQuote');\n            editor.editing.view.focus();\n        });\n        return view;\n    }\n}\n\n/**\n * The block quote plugin.\n *\n * For more information about this feature check the {@glink api/block-quote package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}\n * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */ class BlockQuote extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            BlockQuoteEditing,\n            BlockQuoteUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'BlockQuote';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { BlockQuote, BlockQuoteEditing, BlockQuoteUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquotecommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\nimport type { DocumentFragment, Element, Position, Range, Schema, Writer } from 'ckeditor5/src/engine.js';\n\n/**\n * The block quote command plugin.\n *\n * @extends module:core/command~Command\n */\nexport default class BlockQuoteCommand extends Command {\n\t/**\n\t * Whether the selection starts in a block quote.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command. When the command {@link #value is on}, all top-most block quotes within\n\t * the selection will be removed. If it is off, all selected blocks will be wrapped with\n\t * a block quote.\n\t *\n\t * @fires execute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote,\n\t * otherwise the command will remove the block quote. If not set, the command will act basing on its current value.\n\t */\n\tpublic override execute( options: { forceValue?: boolean } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( !value ) {\n\t\t\t\tthis._removeQuote( writer, blocks.filter( findQuote ) );\n\t\t\t} else {\n\t\t\t\tconst blocksToQuote = blocks.filter( block => {\n\t\t\t\t\t// Already quoted blocks needs to be considered while quoting too\n\t\t\t\t\t// in order to reuse their <bQ> elements.\n\t\t\t\t\treturn findQuote( block ) || checkCanBeQuoted( schema, block );\n\t\t\t\t} );\n\n\t\t\t\tthis._applyQuote( writer, blocksToQuote );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t */\n\tprivate _getValue(): boolean {\n\t\tconst selection = this.editor.model.document.selection;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\t// In the current implementation, the block quote must be an immediate parent of a block element.\n\t\treturn !!( firstBlock && findQuote( firstBlock ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled(): boolean {\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn checkCanBeQuoted( schema, firstBlock );\n\t}\n\n\t/**\n\t * Removes the quote from given blocks.\n\t *\n\t * If blocks which are supposed to be \"unquoted\" are in the middle of a quote,\n\t * start it or end it, then the quote will be split (if needed) and the blocks\n\t * will be moved out of it, so other quoted blocks remained quoted.\n\t */\n\tprivate _removeQuote( writer: Writer, blocks: Array<Element> ): void {\n\t\t// Unquote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => {\n\t\t\tif ( groupRange.start.isAtStart && groupRange.end.isAtEnd ) {\n\t\t\t\twriter.unwrap( groupRange.start.parent as Element );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The group of blocks are at the beginning of an <bQ> so let's move them left (out of the <bQ>).\n\t\t\tif ( groupRange.start.isAtStart ) {\n\t\t\t\tconst positionBefore = writer.createPositionBefore( groupRange.start.parent as Element );\n\n\t\t\t\twriter.move( groupRange, positionBefore );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The blocks are in the middle of an <bQ> so we need to split the <bQ> after the last block\n\t\t\t// so we move the items there.\n\t\t\tif ( !groupRange.end.isAtEnd ) {\n\t\t\t\twriter.split( groupRange.end );\n\t\t\t}\n\n\t\t\t// Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right.\n\n\t\t\tconst positionAfter = writer.createPositionAfter( groupRange.end.parent as Element );\n\n\t\t\twriter.move( groupRange, positionAfter );\n\t\t} );\n\t}\n\n\t/**\n\t * Applies the quote to given blocks.\n\t */\n\tprivate _applyQuote( writer: Writer, blocks: Array<Element> ): void {\n\t\tconst quotesToMerge: Array<Element | DocumentFragment> = [];\n\n\t\t// Quote all groups of block. Iterate in the reverse order to not break following ranges.\n\t\tgetRangesOfBlockGroups( writer, blocks ).reverse().forEach( groupRange => {\n\t\t\tlet quote = findQuote( groupRange.start );\n\n\t\t\tif ( !quote ) {\n\t\t\t\tquote = writer.createElement( 'blockQuote' );\n\n\t\t\t\twriter.wrap( groupRange, quote );\n\t\t\t}\n\n\t\t\tquotesToMerge.push( quote );\n\t\t} );\n\n\t\t// Merge subsequent <bQ> elements. Reverse the order again because this time we want to go through\n\t\t// the <bQ> elements in the source order (due to how merge works – it moves the right element's content\n\t\t// to the first element and removes the right one. Since we may need to merge a couple of subsequent `<bQ>` elements\n\t\t// we want to keep the reference to the first (furthest left) one.\n\t\tquotesToMerge.reverse().reduce( ( currentQuote, nextQuote ) => {\n\t\t\tif ( currentQuote.nextSibling == nextQuote ) {\n\t\t\t\twriter.merge( writer.createPositionAfter( currentQuote ) );\n\n\t\t\t\treturn currentQuote;\n\t\t\t}\n\n\t\t\treturn nextQuote;\n\t\t} );\n\t}\n}\n\nfunction findQuote( elementOrPosition: Element | Position ): Element | DocumentFragment | null {\n\treturn elementOrPosition.parent!.name == 'blockQuote' ? elementOrPosition.parent : null;\n}\n\n/**\n * Returns a minimal array of ranges containing groups of subsequent blocks.\n *\n * content:         abcdefgh\n * blocks:          [ a, b, d, f, g, h ]\n * output ranges:   [ab]c[d]e[fgh]\n */\nfunction getRangesOfBlockGroups( writer: Writer, blocks: Array<Element> ): Array<Range> {\n\tlet startPosition;\n\tlet i = 0;\n\tconst ranges = [];\n\n\twhile ( i < blocks.length ) {\n\t\tconst block = blocks[ i ];\n\t\tconst nextBlock = blocks[ i + 1 ];\n\n\t\tif ( !startPosition ) {\n\t\t\tstartPosition = writer.createPositionBefore( block );\n\t\t}\n\n\t\tif ( !nextBlock || block.nextSibling != nextBlock ) {\n\t\t\tranges.push( writer.createRange( startPosition, writer.createPositionAfter( block ) ) );\n\t\t\tstartPosition = null;\n\t\t}\n\n\t\ti++;\n\t}\n\n\treturn ranges;\n}\n\n/**\n * Checks whether <bQ> can wrap the block.\n */\nfunction checkCanBeQuoted( schema: Schema, block: Element ): boolean {\n\t// TMP will be replaced with schema.checkWrap().\n\tconst isBQAllowed = schema.checkChild( block.parent as Element, 'blockQuote' );\n\tconst isBlockAllowedInBQ = schema.checkChild( [ '$root', 'blockQuote' ], block );\n\n\treturn isBQAllowed && isBlockAllowedInBQ;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquoteediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { Enter, type ViewDocumentEnterEvent } from 'ckeditor5/src/enter.js';\nimport { Delete, type ViewDocumentDeleteEvent } from 'ckeditor5/src/typing.js';\n\nimport BlockQuoteCommand from './blockquotecommand.js';\n\n/**\n * The block quote editing.\n *\n * Introduces the `'blockQuote'` command and the `'blockQuote'` model element.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuoteEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'BlockQuoteEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Enter, Delete ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\teditor.commands.add( 'blockQuote', new BlockQuoteCommand( editor ) );\n\n\t\tschema.register( 'blockQuote', {\n\t\t\tinheritAllFrom: '$container'\n\t\t} );\n\n\t\teditor.conversion.elementToElement( { model: 'blockQuote', view: 'blockquote' } );\n\n\t\t// Postfixer which cleans incorrect model states connected with block quotes.\n\t\teditor.model.document.registerPostFixer( writer => {\n\t\t\tconst changes = editor.model.document.differ.getChanges();\n\n\t\t\tfor ( const entry of changes ) {\n\t\t\t\tif ( entry.type == 'insert' ) {\n\t\t\t\t\tconst element = entry.position.nodeAfter;\n\n\t\t\t\t\tif ( !element ) {\n\t\t\t\t\t\t// We are inside a text node.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( element.is( 'element', 'blockQuote' ) && element.isEmpty ) {\n\t\t\t\t\t\t// Added an empty blockQuote - remove it.\n\t\t\t\t\t\twriter.remove( element );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else if ( element.is( 'element', 'blockQuote' ) && !schema.checkChild( entry.position, element ) ) {\n\t\t\t\t\t\t// Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost.\n\t\t\t\t\t\twriter.unwrap( element );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else if ( element.is( 'element' ) ) {\n\t\t\t\t\t\t// Just added an element. Check that all children meet the scheme rules.\n\t\t\t\t\t\tconst range = writer.createRangeIn( element );\n\n\t\t\t\t\t\tfor ( const child of range.getItems() ) {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tchild.is( 'element', 'blockQuote' ) &&\n\t\t\t\t\t\t\t\t!schema.checkChild( writer.createPositionBefore( child ), child )\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\twriter.unwrap( child );\n\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if ( entry.type == 'remove' ) {\n\t\t\t\t\tconst parent = entry.position.parent;\n\n\t\t\t\t\tif ( parent.is( 'element', 'blockQuote' ) && parent.isEmpty ) {\n\t\t\t\t\t\t// Something got removed and now blockQuote is empty. Remove the blockQuote as well.\n\t\t\t\t\t\twriter.remove( parent );\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t} );\n\n\t\tconst viewDocument = this.editor.editing.view.document;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst blockQuoteCommand: BlockQuoteCommand = editor.commands.get( 'blockQuote' )!;\n\n\t\t// Overwrite default Enter key behavior.\n\t\t// If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote.\n\t\tthis.listenTo<ViewDocumentEnterEvent>( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tif ( !selection.isCollapsed || !blockQuoteCommand.value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = selection.getLastPosition()!.parent;\n\n\t\t\tif ( positionParent.isEmpty ) {\n\t\t\t\teditor.execute( 'blockQuote' );\n\t\t\t\teditor.editing.view.scrollToTheSelection();\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'blockquote' } );\n\n\t\t// Overwrite default Backspace key behavior.\n\t\t// If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote.\n\t\tthis.listenTo<ViewDocumentDeleteEvent>( viewDocument, 'delete', ( evt, data ) => {\n\t\t\tif ( data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand!.value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = selection.getLastPosition()!.parent;\n\n\t\t\tif ( positionParent.isEmpty && !positionParent.previousSibling ) {\n\t\t\t\teditor.execute( 'blockQuote' );\n\t\t\t\teditor.editing.view.scrollToTheSelection();\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'blockquote' } );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquoteui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\n\nimport '../theme/blockquote.css';\n\n/**\n * The block quote UI plugin.\n *\n * It introduces the `'blockQuote'` button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuoteUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'BlockQuoteUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( 'blockQuote', () => {\n\t\t\tconst buttonView = this._createButton( ButtonView );\n\n\t\t\tbuttonView.set( {\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\treturn buttonView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:blockQuote', () => {\n\t\t\tconst buttonView = this._createButton( MenuBarMenuListItemButtonView );\n\n\t\t\tbuttonView.set( {\n\t\t\t\trole: 'menuitemcheckbox'\n\t\t\t} );\n\n\t\t\treturn buttonView;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a button for block quote command to use either in toolbar or in menu bar.\n\t */\n\tprivate _createButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>( ButtonClass: T ): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst command = editor.commands.get( 'blockQuote' )!;\n\t\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\t\tconst t = locale.t;\n\n\t\tview.set( {\n\t\t\tlabel: t( 'Block quote' ),\n\t\t\ticon: icons.quote,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t\tview.bind( 'isOn' ).to( command, 'value' );\n\n\t\t// Execute the command.\n\t\tthis.listenTo( view, 'execute', () => {\n\t\t\teditor.execute( 'blockQuote' );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn view;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module block-quote/blockquote\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport BlockQuoteEditing from './blockquoteediting.js';\nimport BlockQuoteUI from './blockquoteui.js';\n\n/**\n * The block quote plugin.\n *\n * For more information about this feature check the {@glink api/block-quote package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature}\n * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class BlockQuote extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ BlockQuoteEditing, BlockQuoteUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'BlockQuote' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { MouseObserver, TreeWalker } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { Delete } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { EmitterMixin, CKEditorError, Rect, toArray, isForwardArrowKeyCode, env, keyCodes, getLocalizedArrowKeyCodeDirection, getRangeFromMouseEvent, logWarning, ObservableMixin, compareArrays, global, DomEmitterMixin } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { IconView, Template, ContextualBalloon, ToolbarView, BalloonPanelView, View } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';\nimport { throttle } from 'lodash-es';\n\n/**\n * Class used to handle the correct order of highlights on elements.\n *\n * When different highlights are applied to same element the correct order should be preserved:\n *\n * * highlight with highest priority should be applied,\n * * if two highlights have same priority - sort by CSS class provided in\n * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor}.\n *\n * This way, highlight will be applied with the same rules it is applied on texts.\n */ class HighlightStack extends /* #__PURE__ */ EmitterMixin() {\n    _stack = [];\n    /**\n\t * Adds highlight descriptor to the stack.\n\t *\n\t * @fires change:top\n\t */ add(descriptor, writer) {\n        const stack = this._stack;\n        // Save top descriptor and insert new one. If top is changed - fire event.\n        const oldTop = stack[0];\n        this._insertDescriptor(descriptor);\n        const newTop = stack[0];\n        // When new object is at the top and stores different information.\n        if (oldTop !== newTop && !compareDescriptors(oldTop, newTop)) {\n            this.fire('change:top', {\n                oldDescriptor: oldTop,\n                newDescriptor: newTop,\n                writer\n            });\n        }\n    }\n    /**\n\t * Removes highlight descriptor from the stack.\n\t *\n\t * @fires change:top\n\t * @param id Id of the descriptor to remove.\n\t */ remove(id, writer) {\n        const stack = this._stack;\n        const oldTop = stack[0];\n        this._removeDescriptor(id);\n        const newTop = stack[0];\n        // When new object is at the top and stores different information.\n        if (oldTop !== newTop && !compareDescriptors(oldTop, newTop)) {\n            this.fire('change:top', {\n                oldDescriptor: oldTop,\n                newDescriptor: newTop,\n                writer\n            });\n        }\n    }\n    /**\n\t * Inserts a given descriptor in correct place in the stack. It also takes care about updating information\n\t * when descriptor with same id is already present.\n\t */ _insertDescriptor(descriptor) {\n        const stack = this._stack;\n        const index = stack.findIndex((item)=>item.id === descriptor.id);\n        // Inserting exact same descriptor - do nothing.\n        if (compareDescriptors(descriptor, stack[index])) {\n            return;\n        }\n        // If descriptor with same id but with different information is on the stack - remove it.\n        if (index > -1) {\n            stack.splice(index, 1);\n        }\n        // Find correct place to insert descriptor in the stack.\n        // It has different information (for example priority) so it must be re-inserted in correct place.\n        let i = 0;\n        while(stack[i] && shouldABeBeforeB(stack[i], descriptor)){\n            i++;\n        }\n        stack.splice(i, 0, descriptor);\n    }\n    /**\n\t * Removes descriptor with given id from the stack.\n\t *\n\t * @param id Descriptor's id.\n\t */ _removeDescriptor(id) {\n        const stack = this._stack;\n        const index = stack.findIndex((item)=>item.id === id);\n        // If descriptor with same id is on the list - remove it.\n        if (index > -1) {\n            stack.splice(index, 1);\n        }\n    }\n}\n/**\n * Compares two descriptors by checking their priority and class list.\n *\n * @returns Returns true if both descriptors are defined and have same priority and classes.\n */ function compareDescriptors(a, b) {\n    return a && b && a.priority == b.priority && classesToString(a.classes) == classesToString(b.classes);\n}\n/**\n * Checks whenever first descriptor should be placed in the stack before second one.\n */ function shouldABeBeforeB(a, b) {\n    if (a.priority > b.priority) {\n        return true;\n    } else if (a.priority < b.priority) {\n        return false;\n    }\n    // When priorities are equal and names are different - use classes to compare.\n    return classesToString(a.classes) > classesToString(b.classes);\n}\n/**\n * Converts CSS classes passed with {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} to\n * sorted string.\n */ function classesToString(classes) {\n    return Array.isArray(classes) ? classes.sort().join(',') : classes;\n}\n\nvar dragHandleIcon = \"<svg viewBox=\\\"0 0 16 16\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M4 0v1H1v3H0V.5A.5.5 0 0 1 .5 0H4zm8 0h3.5a.5.5 0 0 1 .5.5V4h-1V1h-3V0zM4 16H.5a.5.5 0 0 1-.5-.5V12h1v3h3v1zm8 0v-1h3v-3h1v3.5a.5.5 0 0 1-.5.5H12z\\\"/><path fill-opacity=\\\".256\\\" d=\\\"M1 1h14v14H1z\\\"/><g class=\\\"ck-icon__selected-indicator\\\"><path d=\\\"M7 0h2v1H7V0zM0 7h1v2H0V7zm15 0h1v2h-1V7zm-8 8h2v1H7v-1z\\\"/><path fill-opacity=\\\".254\\\" d=\\\"M1 1h14v14H1z\\\"/></g></svg>\";\n\n/**\n * CSS class added to each widget element.\n */ const WIDGET_CLASS_NAME = 'ck-widget';\n/**\n * CSS class added to currently selected widget element.\n */ const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';\n/**\n * Returns `true` if given {@link module:engine/view/node~Node} is an {@link module:engine/view/element~Element} and a widget.\n */ function isWidget(node) {\n    if (!node.is('element')) {\n        return false;\n    }\n    return !!node.getCustomProperty('widget');\n}\n/**\n * Converts the given {@link module:engine/view/element~Element} to a widget in the following way:\n *\n * * sets the `contenteditable` attribute to `\"false\"`,\n * * adds the `ck-widget` CSS class,\n * * adds a custom {@link module:engine/view/element~Element#getFillerOffset `getFillerOffset()`} method returning `null`,\n * * adds a custom property allowing to recognize widget elements by using {@link ~isWidget `isWidget()`},\n * * implements the {@link ~setHighlightHandling view highlight on widgets}.\n *\n * This function needs to be used in conjunction with\n * {@link module:engine/conversion/downcasthelpers~DowncastHelpers downcast conversion helpers}\n * like {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n * Moreover, typically you will want to use `toWidget()` only for `editingDowncast`, while keeping the `dataDowncast` clean.\n *\n * For example, in order to convert a `<widget>` model element to `<div class=\"widget\">` in the view, you can define\n * such converters:\n *\n * ```ts\n * editor.conversion.for( 'editingDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'widget',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\tconst div = writer.createContainerElement( 'div', { class: 'widget' } );\n *\n * \t\t\treturn toWidget( div, writer, { label: 'some widget' } );\n * \t\t}\n * \t} );\n *\n * editor.conversion.for( 'dataDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'widget',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\treturn writer.createContainerElement( 'div', { class: 'widget' } );\n * \t\t}\n * \t} );\n * ```\n *\n * See the full source code of the widget (with a nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param options Additional options.\n * @param options.label Element's label provided to the {@link ~setLabel} function. It can be passed as\n * a plain string or a function returning a string. It represents the widget for assistive technologies (like screen readers).\n * @param options.hasSelectionHandle If `true`, the widget will have a selection handle added.\n * @returns Returns the same element.\n */ function toWidget(element, writer, options = {}) {\n    if (!element.is('containerElement')) {\n        /**\n\t\t * The element passed to `toWidget()` must be a {@link module:engine/view/containerelement~ContainerElement}\n\t\t * instance.\n\t\t *\n\t\t * @error widget-to-widget-wrong-element-type\n\t\t * @param element The view element passed to `toWidget()`.\n\t\t */ throw new CKEditorError('widget-to-widget-wrong-element-type', null, {\n            element\n        });\n    }\n    writer.setAttribute('contenteditable', 'false', element);\n    writer.addClass(WIDGET_CLASS_NAME, element);\n    writer.setCustomProperty('widget', true, element);\n    element.getFillerOffset = getFillerOffset;\n    writer.setCustomProperty('widgetLabel', [], element);\n    if (options.label) {\n        setLabel(element, options.label);\n    }\n    if (options.hasSelectionHandle) {\n        addSelectionHandle(element, writer);\n    }\n    setHighlightHandling(element, writer);\n    return element;\n}\n/**\n * Default handler for adding a highlight on a widget.\n * It adds CSS class and attributes basing on the given highlight descriptor.\n */ function addHighlight(element, descriptor, writer) {\n    if (descriptor.classes) {\n        writer.addClass(toArray(descriptor.classes), element);\n    }\n    if (descriptor.attributes) {\n        for(const key in descriptor.attributes){\n            writer.setAttribute(key, descriptor.attributes[key], element);\n        }\n    }\n}\n/**\n * Default handler for removing a highlight from a widget.\n * It removes CSS class and attributes basing on the given highlight descriptor.\n */ function removeHighlight(element, descriptor, writer) {\n    if (descriptor.classes) {\n        writer.removeClass(toArray(descriptor.classes), element);\n    }\n    if (descriptor.attributes) {\n        for(const key in descriptor.attributes){\n            writer.removeAttribute(key, element);\n        }\n    }\n}\n/**\n * Sets highlight handling methods. Uses {@link module:widget/highlightstack~HighlightStack} to\n * properly determine which highlight descriptor should be used at given time.\n */ function setHighlightHandling(element, writer, add = addHighlight, remove = removeHighlight) {\n    const stack = new HighlightStack();\n    stack.on('change:top', (evt, data)=>{\n        if (data.oldDescriptor) {\n            remove(element, data.oldDescriptor, data.writer);\n        }\n        if (data.newDescriptor) {\n            add(element, data.newDescriptor, data.writer);\n        }\n    });\n    const addHighlightCallback = (element, descriptor, writer)=>stack.add(descriptor, writer);\n    const removeHighlightCallback = (element, id, writer)=>stack.remove(id, writer);\n    writer.setCustomProperty('addHighlight', addHighlightCallback, element);\n    writer.setCustomProperty('removeHighlight', removeHighlightCallback, element);\n}\n/**\n * Sets label for given element.\n * It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by\n * {@link ~getLabel `getLabel()`}.\n */ function setLabel(element, labelOrCreator) {\n    const widgetLabel = element.getCustomProperty('widgetLabel');\n    widgetLabel.push(labelOrCreator);\n}\n/**\n * Returns the label of the provided element.\n */ function getLabel(element) {\n    const widgetLabel = element.getCustomProperty('widgetLabel');\n    return widgetLabel.reduce((prev, current)=>{\n        if (typeof current === 'function') {\n            return prev ? prev + '. ' + current() : current();\n        } else {\n            return prev ? prev + '. ' + current : current;\n        }\n    }, '');\n}\n/**\n * Adds functionality to the provided {@link module:engine/view/editableelement~EditableElement} to act as a widget's editable:\n *\n * * sets the `contenteditable` attribute to `true` when {@link module:engine/view/editableelement~EditableElement#isReadOnly} is `false`,\n * otherwise sets it to `false`,\n * * adds the `ck-editor__editable` and `ck-editor__nested-editable` CSS classes,\n * * adds the `ck-editor__nested-editable_focused` CSS class when the editable is focused and removes it when it is blurred.\n * * implements the {@link ~setHighlightHandling view highlight on widget's editable}.\n *\n * Similarly to {@link ~toWidget `toWidget()`} this function should be used in `editingDowncast` only and it is usually\n * used together with {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n *\n * For example, in order to convert a `<nested>` model element to `<div class=\"nested\">` in the view, you can define\n * such converters:\n *\n * ```ts\n * editor.conversion.for( 'editingDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'nested',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\tconst div = writer.createEditableElement( 'div', { class: 'nested' } );\n *\n * \t\t\treturn toWidgetEditable( nested, writer, { label: 'label for editable' } );\n * \t\t}\n * \t} );\n *\n * editor.conversion.for( 'dataDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'nested',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\treturn writer.createContainerElement( 'div', { class: 'nested' } );\n * \t\t}\n * \t} );\n * ```\n *\n * See the full source code of the widget (with nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param options Additional options.\n * @param options.label Editable's label used by assistive technologies (e.g. screen readers).\n * @returns Returns the same element that was provided in the `editable` parameter\n */ function toWidgetEditable(editable, writer, options = {}) {\n    writer.addClass([\n        'ck-editor__editable',\n        'ck-editor__nested-editable'\n    ], editable);\n    writer.setAttribute('role', 'textbox', editable);\n    writer.setAttribute('tabindex', '-1', editable);\n    if (options.label) {\n        writer.setAttribute('aria-label', options.label, editable);\n    }\n    // Set initial contenteditable value.\n    writer.setAttribute('contenteditable', editable.isReadOnly ? 'false' : 'true', editable);\n    // Bind the contenteditable property to element#isReadOnly.\n    editable.on('change:isReadOnly', (evt, property, is)=>{\n        writer.setAttribute('contenteditable', is ? 'false' : 'true', editable);\n    });\n    editable.on('change:isFocused', (evt, property, is)=>{\n        if (is) {\n            writer.addClass('ck-editor__nested-editable_focused', editable);\n        } else {\n            writer.removeClass('ck-editor__nested-editable_focused', editable);\n        }\n    });\n    setHighlightHandling(editable, writer);\n    return editable;\n}\n/**\n * Returns a model range which is optimal (in terms of UX) for inserting a widget block.\n *\n * For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph\n * will be returned so that it is not split. If the selection is at the end of a paragraph,\n * the collapsed range after this paragraph will be returned.\n *\n * Note: If the selection is placed in an empty block, the range in that block will be returned. If that range\n * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced\n * by the inserted widget block.\n *\n * @param selection The selection based on which the insertion position should be calculated.\n * @param model Model instance.\n * @returns The optimal range.\n */ function findOptimalInsertionRange(selection, model) {\n    const selectedElement = selection.getSelectedElement();\n    if (selectedElement) {\n        const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(selection);\n        // If the WidgetTypeAround \"fake caret\" is displayed, use its position for the insertion\n        // to provide the most predictable UX (https://github.com/ckeditor/ckeditor5/issues/7438).\n        if (typeAroundFakeCaretPosition) {\n            return model.createRange(model.createPositionAt(selectedElement, typeAroundFakeCaretPosition));\n        }\n    }\n    return model.schema.findOptimalInsertionRange(selection);\n}\n/**\n * A util to be used in order to map view positions to correct model positions when implementing a widget\n * which renders non-empty view element for an empty model element.\n *\n * For example:\n *\n * ```\n * // Model:\n * <placeholder type=\"name\"></placeholder>\n *\n * // View:\n * <span class=\"placeholder\">name</span>\n * ```\n *\n * In such case, view positions inside `<span>` cannot be correctly mapped to the model (because the model element is empty).\n * To handle mapping positions inside `<span class=\"placeholder\">` to the model use this util as follows:\n *\n * ```ts\n * editor.editing.mapper.on(\n * \t'viewToModelPosition',\n * \tviewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )\n * );\n * ```\n *\n * The callback will try to map the view offset of selection to an expected model position.\n *\n * 1. When the position is at the end (or in the middle) of the inline widget:\n *\n * ```\n * // View:\n * <p>foo <span class=\"placeholder\">name|</span> bar</p>\n *\n * // Model:\n * <paragraph>foo <placeholder type=\"name\"></placeholder>| bar</paragraph>\n * ```\n *\n * 2. When the position is at the beginning of the inline widget:\n *\n * ```\n * // View:\n * <p>foo <span class=\"placeholder\">|name</span> bar</p>\n *\n * // Model:\n * <paragraph>foo |<placeholder type=\"name\"></placeholder> bar</paragraph>\n * ```\n *\n * @param model Model instance on which the callback operates.\n * @param viewElementMatcher Function that is passed a view element and should return `true` if the custom mapping\n * should be applied to the given view element.\n */ function viewToModelPositionOutsideModelElement(model, viewElementMatcher) {\n    return (evt, data)=>{\n        const { mapper, viewPosition } = data;\n        const viewParent = mapper.findMappedViewAncestor(viewPosition);\n        if (!viewElementMatcher(viewParent)) {\n            return;\n        }\n        const modelParent = mapper.toModelElement(viewParent);\n        data.modelPosition = model.createPositionAt(modelParent, viewPosition.isAtStart ? 'before' : 'after');\n    };\n}\n/**\n * Default filler offset function applied to all widget elements.\n */ function getFillerOffset() {\n    return null;\n}\n/**\n * Adds a drag handle to the widget.\n */ function addSelectionHandle(widgetElement, writer) {\n    const selectionHandle = writer.createUIElement('div', {\n        class: 'ck ck-widget__selection-handle'\n    }, function(domDocument) {\n        const domElement = this.toDomElement(domDocument);\n        // Use the IconView from the ui library.\n        const icon = new IconView();\n        icon.set('content', dragHandleIcon);\n        // Render the icon view right away to append its #element to the selectionHandle DOM element.\n        icon.render();\n        domElement.appendChild(icon.element);\n        return domElement;\n    });\n    // Append the selection handle into the widget wrapper.\n    writer.insert(writer.createPositionAt(widgetElement, 0), selectionHandle);\n    writer.addClass([\n        'ck-widget_with-selection-handle'\n    ], widgetElement);\n}\n/**\n * Starting from a DOM resize host element (an element that receives dimensions as a result of resizing),\n * this helper returns the width of the found ancestor element.\n *\n *\t* It searches up to 5 levels of ancestors only.\n *\n * @param domResizeHost Resize host DOM element that receives dimensions as a result of resizing.\n * @returns Width of ancestor element in pixels or 0 if no ancestor with a computed width has been found.\n */ function calculateResizeHostAncestorWidth(domResizeHost) {\n    const getElementComputedWidth = (element)=>{\n        const { width, paddingLeft, paddingRight } = element.ownerDocument.defaultView.getComputedStyle(element);\n        return parseFloat(width) - (parseFloat(paddingLeft) || 0) - (parseFloat(paddingRight) || 0);\n    };\n    const domResizeHostParent = domResizeHost.parentElement;\n    if (!domResizeHostParent) {\n        return 0;\n    }\n    // Need to use computed style as it properly excludes parent's paddings from the returned value.\n    let parentWidth = getElementComputedWidth(domResizeHostParent);\n    // Sometimes parent width cannot be accessed. If that happens we should go up in the elements tree\n    // and try to get width from next ancestor.\n    // https://github.com/ckeditor/ckeditor5/issues/10776\n    const ancestorLevelLimit = 5;\n    let currentLevel = 0;\n    let checkedElement = domResizeHostParent;\n    while(isNaN(parentWidth)){\n        checkedElement = checkedElement.parentElement;\n        if (++currentLevel > ancestorLevelLimit) {\n            return 0;\n        }\n        parentWidth = getElementComputedWidth(checkedElement);\n    }\n    return parentWidth;\n}\n/**\n * Calculates a relative width of a `domResizeHost` compared to its ancestor in percents.\n *\n * @param domResizeHost Resize host DOM element.\n * @returns Percentage value between 0 and 100.\n */ function calculateResizeHostPercentageWidth(domResizeHost, resizeHostRect = new Rect(domResizeHost)) {\n    const parentWidth = calculateResizeHostAncestorWidth(domResizeHost);\n    if (!parentWidth) {\n        return 0;\n    }\n    return resizeHostRect.width / parentWidth * 100;\n}\n\n/**\n * The name of the type around model selection attribute responsible for\n * displaying a fake caret next to a selected widget.\n */ const TYPE_AROUND_SELECTION_ATTRIBUTE = 'widget-type-around';\n/**\n * Checks if an element is a widget that qualifies to get the widget type around UI.\n */ function isTypeAroundWidget(viewElement, modelElement, schema) {\n    return !!viewElement && isWidget(viewElement) && !schema.isInline(modelElement);\n}\n/**\n * For the passed HTML element, this helper finds the closest widget type around button ancestor.\n */ function getClosestTypeAroundDomButton(domElement) {\n    return domElement.closest('.ck-widget__type-around__button');\n}\n/**\n * For the passed widget type around button element, this helper determines at which position\n * the paragraph would be inserted into the content if, for instance, the button was\n * clicked by the user.\n *\n * @returns The position of the button.\n */ function getTypeAroundButtonPosition(domElement) {\n    return domElement.classList.contains('ck-widget__type-around__button_before') ? 'before' : 'after';\n}\n/**\n * For the passed HTML element, this helper returns the closest view widget ancestor.\n */ function getClosestWidgetViewElement(domElement, domConverter) {\n    const widgetDomElement = domElement.closest('.ck-widget');\n    return domConverter.mapDomToView(widgetDomElement);\n}\n/**\n * For the passed selection instance, it returns the position of the fake caret displayed next to a widget.\n *\n * **Note**: If the fake caret is not currently displayed, `null` is returned.\n *\n * @returns The position of the fake caret or `null` when none is present.\n */ function getTypeAroundFakeCaretPosition(selection) {\n    return selection.getAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE);\n}\n\nvar returnIcon = \"<svg viewBox=\\\"0 0 10 8\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M9.055.263v3.972h-6.77M1 4.216l2-2.038m-2 2 2 2.038\\\"/></svg>\";\n\nconst POSSIBLE_INSERTION_POSITIONS = [\n    'before',\n    'after'\n];\n// Do the SVG parsing once and then clone the result <svg> DOM element for each new button.\nconst RETURN_ARROW_ICON_ELEMENT = new DOMParser().parseFromString(returnIcon, 'image/svg+xml').firstChild;\nconst PLUGIN_DISABLED_EDITING_ROOT_CLASS = 'ck-widget__type-around_disabled';\n/**\n * A plugin that allows users to type around widgets where normally it is impossible to place the caret due\n * to limitations of web browsers. These \"tight spots\" occur, for instance, before (or after) a widget being\n * the first (or last) child of its parent or between two block widgets.\n *\n * This plugin extends the {@link module:widget/widget~Widget `Widget`} plugin and injects the user interface\n * with two buttons into each widget instance in the editor. Each of the buttons can be clicked by the\n * user if the widget is next to the \"tight spot\". Once clicked, a paragraph is created with the selection anchored\n * in it so that users can type (or insert content, paste, etc.) straight away.\n */ class WidgetTypeAround extends Plugin {\n    /**\n\t * A reference to the model widget element that has the fake caret active\n\t * on either side of it. It is later used to remove CSS classes associated with the fake caret\n\t * when the widget no longer needs it.\n\t */ _currentFakeCaretModelElement = null;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'WidgetTypeAround';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Enter,\n            Delete\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        // Set a CSS class on the view editing root when the plugin is disabled so all the buttons\n        // and lines visually disappear. All the interactions are disabled in individual plugin methods.\n        this.on('change:isEnabled', (evt, data, isEnabled)=>{\n            editingView.change((writer)=>{\n                for (const root of editingView.document.roots){\n                    if (isEnabled) {\n                        writer.removeClass(PLUGIN_DISABLED_EDITING_ROOT_CLASS, root);\n                    } else {\n                        writer.addClass(PLUGIN_DISABLED_EDITING_ROOT_CLASS, root);\n                    }\n                }\n            });\n            if (!isEnabled) {\n                editor.model.change((writer)=>{\n                    writer.removeSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE);\n                });\n            }\n        });\n        this._enableTypeAroundUIInjection();\n        this._enableInsertingParagraphsOnButtonClick();\n        this._enableInsertingParagraphsOnEnterKeypress();\n        this._enableInsertingParagraphsOnTypingKeystroke();\n        this._enableTypeAroundFakeCaretActivationUsingKeyboardArrows();\n        this._enableDeleteIntegration();\n        this._enableInsertContentIntegration();\n        this._enableInsertObjectIntegration();\n        this._enableDeleteContentIntegration();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this._currentFakeCaretModelElement = null;\n    }\n    /**\n\t * Inserts a new paragraph next to a widget element with the selection anchored in it.\n\t *\n\t * **Note**: This method is heavily user-oriented and will both focus the editing view and scroll\n\t * the viewport to the selection in the inserted paragraph.\n\t *\n\t * @param widgetModelElement The model widget element next to which a paragraph is inserted.\n\t * @param position The position where the paragraph is inserted. Either `'before'` or `'after'` the widget.\n\t */ _insertParagraph(widgetModelElement, position) {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const attributesToCopy = editor.model.schema.getAttributesWithProperty(widgetModelElement, 'copyOnReplace', true);\n        editor.execute('insertParagraph', {\n            position: editor.model.createPositionAt(widgetModelElement, position),\n            attributes: attributesToCopy\n        });\n        editingView.focus();\n        editingView.scrollToTheSelection();\n    }\n    /**\n\t * A wrapper for the {@link module:utils/emittermixin~Emitter#listenTo} method that executes the callbacks only\n\t * when the plugin {@link #isEnabled is enabled}.\n\t *\n\t * @param emitter The object that fires the event.\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t * @param options.priority The priority of this event callback. The higher the priority value the sooner\n\t * the callback will be fired. Events having the same priority are called in the order they were added.\n\t */ _listenToIfEnabled(emitter, event, callback, options) {\n        this.listenTo(emitter, event, (...args)=>{\n            // Do not respond if the plugin is disabled.\n            if (this.isEnabled) {\n                callback(...args);\n            }\n        }, options);\n    }\n    /**\n\t * Similar to {@link #_insertParagraph}, this method inserts a paragraph except that it\n\t * does not expect a position. Instead, it performs the insertion next to a selected widget\n\t * according to the `widget-type-around` model selection attribute value (fake caret position).\n\t *\n\t * Because this method requires the `widget-type-around` attribute to be set,\n\t * the insertion can only happen when the widget's fake caret is active (e.g. activated\n\t * using the keyboard).\n\t *\n\t * @returns Returns `true` when the paragraph was inserted (the attribute was present) and `false` otherwise.\n\t */ _insertParagraphAccordingToFakeCaretPosition() {\n        const editor = this.editor;\n        const model = editor.model;\n        const modelSelection = model.document.selection;\n        const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(modelSelection);\n        if (!typeAroundFakeCaretPosition) {\n            return false;\n        }\n        // @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n        // @if CK_DEBUG_TYPING // \tconsole.info( '%c[WidgetTypeAround]%c Fake caret -> insert paragraph',\n        // @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', ''\n        // @if CK_DEBUG_TYPING // \t);\n        // @if CK_DEBUG_TYPING // }\n        const selectedModelElement = modelSelection.getSelectedElement();\n        this._insertParagraph(selectedModelElement, typeAroundFakeCaretPosition);\n        return true;\n    }\n    /**\n\t * Creates a listener in the editing conversion pipeline that injects the widget type around\n\t * UI into every single widget instance created in the editor.\n\t *\n\t * The UI is delivered as a {@link module:engine/view/uielement~UIElement}\n\t * wrapper which renders DOM buttons that users can use to insert paragraphs.\n\t */ _enableTypeAroundUIInjection() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const t = editor.locale.t;\n        const buttonTitles = {\n            before: t('Insert paragraph before block'),\n            after: t('Insert paragraph after block')\n        };\n        editor.editing.downcastDispatcher.on('insert', (evt, data, conversionApi)=>{\n            const viewElement = conversionApi.mapper.toViewElement(data.item);\n            if (!viewElement) {\n                return;\n            }\n            // Filter out non-widgets and inline widgets.\n            if (isTypeAroundWidget(viewElement, data.item, schema)) {\n                injectUIIntoWidget(conversionApi.writer, buttonTitles, viewElement);\n                const widgetLabel = viewElement.getCustomProperty('widgetLabel');\n                widgetLabel.push(()=>{\n                    return this.isEnabled ? t('Press Enter to type after or press Shift + Enter to type before the widget') : '';\n                });\n            }\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * Brings support for the fake caret that appears when either:\n\t *\n\t * * the selection moves to a widget from a position next to it using arrow keys,\n\t * * the arrow key is pressed when the widget is already selected.\n\t *\n\t * The fake caret lets the user know that they can start typing or just press\n\t * <kbd>Enter</kbd> to insert a paragraph at the position next to a widget as suggested by the fake caret.\n\t *\n\t * The fake caret disappears when the user changes the selection or the editor\n\t * gets blurred.\n\t *\n\t * The whole idea is as follows:\n\t *\n\t * 1. A user does one of the 2 scenarios described at the beginning.\n\t * 2. The \"keydown\" listener is executed and the decision is made whether to show or hide the fake caret.\n\t * 3. If it should show up, the `widget-type-around` model selection attribute is set indicating\n\t *    on which side of the widget it should appear.\n\t * 4. The selection dispatcher reacts to the selection attribute and sets CSS classes responsible for the\n\t *    fake caret on the view widget.\n\t * 5. If the fake caret should disappear, the selection attribute is removed and the dispatcher\n\t *    does the CSS class clean-up in the view.\n\t * 6. Additionally, `change:range` and `FocusTracker#isFocused` listeners also remove the selection\n\t *    attribute (the former also removes widget CSS classes).\n\t */ _enableTypeAroundFakeCaretActivationUsingKeyboardArrows() {\n        const editor = this.editor;\n        const model = editor.model;\n        const modelSelection = model.document.selection;\n        const schema = model.schema;\n        const editingView = editor.editing.view;\n        // This is the main listener responsible for the fake caret.\n        // Note: The priority must precede the default Widget class keydown handler (\"high\").\n        this._listenToIfEnabled(editingView.document, 'arrowKey', (evt, domEventData)=>{\n            this._handleArrowKeyPress(evt, domEventData);\n        }, {\n            context: [\n                isWidget,\n                '$text'\n            ],\n            priority: 'high'\n        });\n        // This listener makes sure the widget type around selection attribute will be gone from the model\n        // selection as soon as the model range changes. This attribute only makes sense when a widget is selected\n        // (and the \"fake horizontal caret\" is visible) so whenever the range changes (e.g. selection moved somewhere else),\n        // let's get rid of the attribute so that the selection downcast dispatcher isn't even bothered.\n        this._listenToIfEnabled(modelSelection, 'change:range', (evt, data)=>{\n            // Do not reset the selection attribute when the change was indirect.\n            if (!data.directChange) {\n                return;\n            }\n            // Get rid of the widget type around attribute of the selection on every change:range.\n            // If the range changes, it means for sure, the user is no longer in the active (\"fake horizontal caret\") mode.\n            editor.model.change((writer)=>{\n                writer.removeSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE);\n            });\n        });\n        // Get rid of the widget type around attribute of the selection on every document change\n        // that makes widget not selected any more (i.e. widget was removed).\n        this._listenToIfEnabled(model.document, 'change:data', ()=>{\n            const selectedModelElement = modelSelection.getSelectedElement();\n            if (selectedModelElement) {\n                const selectedViewElement = editor.editing.mapper.toViewElement(selectedModelElement);\n                if (isTypeAroundWidget(selectedViewElement, selectedModelElement, schema)) {\n                    return;\n                }\n            }\n            editor.model.change((writer)=>{\n                writer.removeSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE);\n            });\n        });\n        // React to changes of the model selection attribute made by the arrow keys listener.\n        // If the block widget is selected and the attribute changes, downcast the attribute to special\n        // CSS classes associated with the active (\"fake horizontal caret\") mode of the widget.\n        this._listenToIfEnabled(editor.editing.downcastDispatcher, 'selection', (evt, data, conversionApi)=>{\n            const writer = conversionApi.writer;\n            if (this._currentFakeCaretModelElement) {\n                const selectedViewElement = conversionApi.mapper.toViewElement(this._currentFakeCaretModelElement);\n                if (selectedViewElement) {\n                    // Get rid of CSS classes associated with the active (\"fake horizontal caret\") mode from the view widget.\n                    writer.removeClass(POSSIBLE_INSERTION_POSITIONS.map(positionToWidgetCssClass), selectedViewElement);\n                    this._currentFakeCaretModelElement = null;\n                }\n            }\n            const selectedModelElement = data.selection.getSelectedElement();\n            if (!selectedModelElement) {\n                return;\n            }\n            const selectedViewElement = conversionApi.mapper.toViewElement(selectedModelElement);\n            if (!isTypeAroundWidget(selectedViewElement, selectedModelElement, schema)) {\n                return;\n            }\n            const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(data.selection);\n            if (!typeAroundFakeCaretPosition) {\n                return;\n            }\n            writer.addClass(positionToWidgetCssClass(typeAroundFakeCaretPosition), selectedViewElement);\n            // Remember the view widget that got the \"fake-caret\" CSS class. This class should be removed ASAP when the\n            // selection changes\n            this._currentFakeCaretModelElement = selectedModelElement;\n        });\n        this._listenToIfEnabled(editor.ui.focusTracker, 'change:isFocused', (evt, name, isFocused)=>{\n            if (!isFocused) {\n                editor.model.change((writer)=>{\n                    writer.removeSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE);\n                });\n            }\n        });\n        function positionToWidgetCssClass(position) {\n            return `ck-widget_type-around_show-fake-caret_${position}`;\n        }\n    }\n    /**\n\t * A listener executed on each \"keydown\" in the view document, a part of\n\t * {@link #_enableTypeAroundFakeCaretActivationUsingKeyboardArrows}.\n\t *\n\t * It decides whether the arrow keypress should activate the fake caret or not (also whether it should\n\t * be deactivated).\n\t *\n\t * The fake caret activation is done by setting the `widget-type-around` model selection attribute\n\t * in this listener, and stopping and preventing the event that would normally be handled by the widget\n\t * plugin that is responsible for the regular keyboard navigation near/across all widgets (that\n\t * includes inline widgets, which are ignored by the widget type around plugin).\n\t */ _handleArrowKeyPress(evt, domEventData) {\n        const editor = this.editor;\n        const model = editor.model;\n        const modelSelection = model.document.selection;\n        const schema = model.schema;\n        const editingView = editor.editing.view;\n        const keyCode = domEventData.keyCode;\n        const isForward = isForwardArrowKeyCode(keyCode, editor.locale.contentLanguageDirection);\n        const selectedViewElement = editingView.document.selection.getSelectedElement();\n        const selectedModelElement = editor.editing.mapper.toModelElement(selectedViewElement);\n        let shouldStopAndPreventDefault;\n        // Handle keyboard navigation when a type-around-compatible widget is currently selected.\n        if (isTypeAroundWidget(selectedViewElement, selectedModelElement, schema)) {\n            shouldStopAndPreventDefault = this._handleArrowKeyPressOnSelectedWidget(isForward);\n        } else if (modelSelection.isCollapsed) {\n            shouldStopAndPreventDefault = this._handleArrowKeyPressWhenSelectionNextToAWidget(isForward);\n        } else if (!domEventData.shiftKey) {\n            shouldStopAndPreventDefault = this._handleArrowKeyPressWhenNonCollapsedSelection(isForward);\n        }\n        if (shouldStopAndPreventDefault) {\n            domEventData.preventDefault();\n            evt.stop();\n        }\n    }\n    /**\n\t * Handles the keyboard navigation on \"keydown\" when a widget is currently selected and activates or deactivates\n\t * the fake caret for that widget, depending on the current value of the `widget-type-around` model\n\t * selection attribute and the direction of the pressed arrow key.\n\t *\n\t * @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement\n\t * as in {@link module:utils/keyboard~isForwardArrowKeyCode}.\n\t * @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should\n\t * process the event any further. Returns `false` otherwise.\n\t */ _handleArrowKeyPressOnSelectedWidget(isForward) {\n        const editor = this.editor;\n        const model = editor.model;\n        const modelSelection = model.document.selection;\n        const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(modelSelection);\n        return model.change((writer)=>{\n            // If the fake caret is displayed...\n            if (typeAroundFakeCaretPosition) {\n                const isLeavingWidget = typeAroundFakeCaretPosition === (isForward ? 'after' : 'before');\n                // If the keyboard arrow works against the value of the selection attribute...\n                // then remove the selection attribute but prevent default DOM actions\n                // and do not let the Widget plugin listener move the selection. This brings\n                // the widget back to the state, for instance, like if was selected using the mouse.\n                //\n                // **Note**: If leaving the widget when the fake caret is active, then the default\n                // Widget handler will change the selection and, in turn, this will automatically discard\n                // the selection attribute.\n                if (!isLeavingWidget) {\n                    writer.removeSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE);\n                    return true;\n                }\n            } else {\n                writer.setSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE, isForward ? 'after' : 'before');\n                return true;\n            }\n            return false;\n        });\n    }\n    /**\n\t * Handles the keyboard navigation on \"keydown\" when **no** widget is selected but the selection is **directly** next\n\t * to one and upon the fake caret should become active for this widget upon arrow keypress\n\t * (AKA entering/selecting the widget).\n\t *\n\t * **Note**: This code mirrors the implementation from the widget plugin but also adds the selection attribute.\n\t * Unfortunately, there is no safe way to let the widget plugin do the selection part first and then just set the\n\t * selection attribute here in the widget type around plugin. This is why this code must duplicate some from the widget plugin.\n\t *\n\t * @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement\n\t * as in {@link module:utils/keyboard~isForwardArrowKeyCode}.\n\t * @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should\n\t * process the event any further. Returns `false` otherwise.\n\t */ _handleArrowKeyPressWhenSelectionNextToAWidget(isForward) {\n        const editor = this.editor;\n        const model = editor.model;\n        const schema = model.schema;\n        const widgetPlugin = editor.plugins.get('Widget');\n        // This is the widget the selection is about to be set on.\n        const modelElementNextToSelection = widgetPlugin._getObjectElementNextToSelection(isForward);\n        const viewElementNextToSelection = editor.editing.mapper.toViewElement(modelElementNextToSelection);\n        if (isTypeAroundWidget(viewElementNextToSelection, modelElementNextToSelection, schema)) {\n            model.change((writer)=>{\n                widgetPlugin._setSelectionOverElement(modelElementNextToSelection);\n                writer.setSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE, isForward ? 'before' : 'after');\n            });\n            // The change() block above does the same job as the Widget plugin. The event can\n            // be safely canceled.\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Handles the keyboard navigation on \"keydown\" when a widget is currently selected (together with some other content)\n\t * and the widget is the first or last element in the selection. It activates or deactivates the fake caret for that widget.\n\t *\n\t * @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement\n\t * as in {@link module:utils/keyboard~isForwardArrowKeyCode}.\n\t * @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should\n\t * process the event any further. Returns `false` otherwise.\n\t */ _handleArrowKeyPressWhenNonCollapsedSelection(isForward) {\n        const editor = this.editor;\n        const model = editor.model;\n        const schema = model.schema;\n        const mapper = editor.editing.mapper;\n        const modelSelection = model.document.selection;\n        const selectedModelNode = isForward ? modelSelection.getLastPosition().nodeBefore : modelSelection.getFirstPosition().nodeAfter;\n        const selectedViewNode = mapper.toViewElement(selectedModelNode);\n        // There is a widget at the collapse position so collapse the selection to the fake caret on it.\n        if (isTypeAroundWidget(selectedViewNode, selectedModelNode, schema)) {\n            model.change((writer)=>{\n                writer.setSelection(selectedModelNode, 'on');\n                writer.setSelectionAttribute(TYPE_AROUND_SELECTION_ATTRIBUTE, isForward ? 'after' : 'before');\n            });\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Registers a `mousedown` listener for the view document which intercepts events\n\t * coming from the widget type around UI, which happens when a user clicks one of the buttons\n\t * that insert a paragraph next to a widget.\n\t */ _enableInsertingParagraphsOnButtonClick() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        this._listenToIfEnabled(editingView.document, 'mousedown', (evt, domEventData)=>{\n            const button = getClosestTypeAroundDomButton(domEventData.domTarget);\n            if (!button) {\n                return;\n            }\n            const buttonPosition = getTypeAroundButtonPosition(button);\n            const widgetViewElement = getClosestWidgetViewElement(button, editingView.domConverter);\n            const widgetModelElement = editor.editing.mapper.toModelElement(widgetViewElement);\n            this._insertParagraph(widgetModelElement, buttonPosition);\n            domEventData.preventDefault();\n            evt.stop();\n        });\n    }\n    /**\n\t * Creates the <kbd>Enter</kbd> key listener on the view document that allows the user to insert a paragraph\n\t * near the widget when either:\n\t *\n\t * * The fake caret was first activated using the arrow keys,\n\t * * The entire widget is selected in the model.\n\t *\n\t * In the first case, the new paragraph is inserted according to the `widget-type-around` selection\n\t * attribute (see {@link #_handleArrowKeyPress}).\n\t *\n\t * In the second case, the new paragraph is inserted based on whether a soft (<kbd>Shift</kbd>+<kbd>Enter</kbd>) keystroke\n\t * was pressed or not.\n\t */ _enableInsertingParagraphsOnEnterKeypress() {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const editingView = editor.editing.view;\n        this._listenToIfEnabled(editingView.document, 'enter', (evt, domEventData)=>{\n            // This event could be triggered from inside the widget but we are interested\n            // only when the widget is selected itself.\n            if (evt.eventPhase != 'atTarget') {\n                return;\n            }\n            const selectedModelElement = selection.getSelectedElement();\n            const selectedViewElement = editor.editing.mapper.toViewElement(selectedModelElement);\n            const schema = editor.model.schema;\n            let wasHandled;\n            // First check if the widget is selected and there's a type around selection attribute associated\n            // with the fake caret that would tell where to insert a new paragraph.\n            if (this._insertParagraphAccordingToFakeCaretPosition()) {\n                wasHandled = true;\n            } else if (isTypeAroundWidget(selectedViewElement, selectedModelElement, schema)) {\n                this._insertParagraph(selectedModelElement, domEventData.isSoft ? 'before' : 'after');\n                wasHandled = true;\n            }\n            if (wasHandled) {\n                domEventData.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: isWidget\n        });\n    }\n    /**\n\t * Similar to the {@link #_enableInsertingParagraphsOnEnterKeypress}, it allows the user\n\t * to insert a paragraph next to a widget when the fake caret was activated using arrow\n\t * keys but it responds to typing instead of <kbd>Enter</kbd>.\n\t *\n\t * Listener enabled by this method will insert a new paragraph according to the `widget-type-around`\n\t * model selection attribute as the user simply starts typing, which creates the impression that the fake caret\n\t * behaves like a real one rendered by the browser (AKA your text appears where the caret was).\n\t *\n\t * **Note**: At the moment this listener creates 2 undo steps: one for the `insertParagraph` command\n\t * and another one for actual typing. It is not a disaster but this may need to be fixed\n\t * sooner or later.\n\t */ _enableInsertingParagraphsOnTypingKeystroke() {\n        const editor = this.editor;\n        const viewDocument = editor.editing.view.document;\n        // Note: The priority must precede the default Input plugin insertText handler.\n        this._listenToIfEnabled(viewDocument, 'insertText', (evt, data)=>{\n            if (this._insertParagraphAccordingToFakeCaretPosition()) {\n                // The view selection in the event data contains the widget. If the new paragraph\n                // was inserted, modify the view selection passed along with the insertText event\n                // so the default event handler in the Input plugin starts typing inside the paragraph.\n                // Otherwise, the typing would be over the widget.\n                data.selection = viewDocument.selection;\n            }\n        }, {\n            priority: 'high'\n        });\n        if (env.isAndroid) {\n            // On Android with English keyboard, the composition starts just by putting caret\n            // at the word end or by selecting a table column. This is not a real composition started.\n            // Trigger delete content on first composition key pressed.\n            this._listenToIfEnabled(viewDocument, 'keydown', (evt, data)=>{\n                if (data.keyCode == 229) {\n                    this._insertParagraphAccordingToFakeCaretPosition();\n                }\n            });\n        } else {\n            // Note: The priority must precede the default Input plugin compositionstart handler (to call it before delete content).\n            this._listenToIfEnabled(viewDocument, 'compositionstart', ()=>{\n                this._insertParagraphAccordingToFakeCaretPosition();\n            }, {\n                priority: 'high'\n            });\n        }\n    }\n    /**\n\t * It creates a \"delete\" event listener on the view document to handle cases when the <kbd>Delete</kbd> or <kbd>Backspace</kbd>\n\t * is pressed and the fake caret is currently active.\n\t *\n\t * The fake caret should create an illusion of a real browser caret so that when it appears before or after\n\t * a widget, pressing <kbd>Delete</kbd> or <kbd>Backspace</kbd> should remove a widget or delete the content\n\t * before or after a widget (depending on the content surrounding the widget).\n\t */ _enableDeleteIntegration() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const model = editor.model;\n        const schema = model.schema;\n        this._listenToIfEnabled(editingView.document, 'delete', (evt, domEventData)=>{\n            // This event could be triggered from inside the widget but we are interested\n            // only when the widget is selected itself.\n            if (evt.eventPhase != 'atTarget') {\n                return;\n            }\n            const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(model.document.selection);\n            // This listener handles only these cases when the fake caret is active.\n            if (!typeAroundFakeCaretPosition) {\n                return;\n            }\n            const direction = domEventData.direction;\n            const selectedModelWidget = model.document.selection.getSelectedElement();\n            const isFakeCaretBefore = typeAroundFakeCaretPosition === 'before';\n            const isDeleteForward = direction == 'forward';\n            const shouldDeleteEntireWidget = isFakeCaretBefore === isDeleteForward;\n            if (shouldDeleteEntireWidget) {\n                editor.execute('delete', {\n                    selection: model.createSelection(selectedModelWidget, 'on')\n                });\n            } else {\n                const range = schema.getNearestSelectionRange(model.createPositionAt(selectedModelWidget, typeAroundFakeCaretPosition), direction);\n                // If there is somewhere to move selection to, then there will be something to delete.\n                if (range) {\n                    // If the range is NOT collapsed, then we know that the range contains an object (see getNearestSelectionRange() docs).\n                    if (!range.isCollapsed) {\n                        model.change((writer)=>{\n                            writer.setSelection(range);\n                            editor.execute(isDeleteForward ? 'deleteForward' : 'delete');\n                        });\n                    } else {\n                        const probe = model.createSelection(range.start);\n                        model.modifySelection(probe, {\n                            direction\n                        });\n                        // If the range is collapsed, let's see if a non-collapsed range exists that can could be deleted.\n                        // If such range exists, use the editor command because it it safe for collaboration (it merges where it can).\n                        if (!probe.focus.isEqual(range.start)) {\n                            model.change((writer)=>{\n                                writer.setSelection(range);\n                                editor.execute(isDeleteForward ? 'deleteForward' : 'delete');\n                            });\n                        } else {\n                            const deepestEmptyRangeAncestor = getDeepestEmptyElementAncestor(schema, range.start.parent);\n                            model.deleteContent(model.createSelection(deepestEmptyRangeAncestor, 'on'), {\n                                doNotAutoparagraph: true\n                            });\n                        }\n                    }\n                }\n            }\n            // If some content was deleted, don't let the handler from the Widget plugin kick in.\n            // If nothing was deleted, then the default handler will have nothing to do anyway.\n            domEventData.preventDefault();\n            evt.stop();\n        }, {\n            context: isWidget\n        });\n    }\n    /**\n\t * Attaches the {@link module:engine/model/model~Model#event:insertContent} event listener that, for instance, allows the user to paste\n\t * content near a widget when the fake caret is first activated using the arrow keys.\n\t *\n\t * The content is inserted according to the `widget-type-around` selection attribute (see {@link #_handleArrowKeyPress}).\n\t */ _enableInsertContentIntegration() {\n        const editor = this.editor;\n        const model = this.editor.model;\n        const documentSelection = model.document.selection;\n        this._listenToIfEnabled(editor.model, 'insertContent', (evt, [content, selectable])=>{\n            if (selectable && !selectable.is('documentSelection')) {\n                return;\n            }\n            const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(documentSelection);\n            if (!typeAroundFakeCaretPosition) {\n                return;\n            }\n            evt.stop();\n            return model.change((writer)=>{\n                const selectedElement = documentSelection.getSelectedElement();\n                const position = model.createPositionAt(selectedElement, typeAroundFakeCaretPosition);\n                const selection = writer.createSelection(position);\n                const result = model.insertContent(content, selection);\n                writer.setSelection(selection);\n                return result;\n            });\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Attaches the {@link module:engine/model/model~Model#event:insertObject} event listener that modifies the\n\t * `options.findOptimalPosition`parameter to position of fake caret in relation to selected element\n\t * to reflect user's intent of desired insertion position.\n\t *\n\t * The object is inserted according to the `widget-type-around` selection attribute (see {@link #_handleArrowKeyPress}).\n\t */ _enableInsertObjectIntegration() {\n        const editor = this.editor;\n        const model = this.editor.model;\n        const documentSelection = model.document.selection;\n        this._listenToIfEnabled(editor.model, 'insertObject', (evt, args)=>{\n            const [, selectable, options = {}] = args;\n            if (selectable && !selectable.is('documentSelection')) {\n                return;\n            }\n            const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(documentSelection);\n            if (!typeAroundFakeCaretPosition) {\n                return;\n            }\n            options.findOptimalPosition = typeAroundFakeCaretPosition;\n            args[3] = options;\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Attaches the {@link module:engine/model/model~Model#event:deleteContent} event listener to block the event when the fake\n\t * caret is active.\n\t *\n\t * This is required for cases that trigger {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`}\n\t * before calling {@link module:engine/model/model~Model#insertContent `model.insertContent()`} like, for instance,\n\t * plain text pasting.\n\t */ _enableDeleteContentIntegration() {\n        const editor = this.editor;\n        const model = this.editor.model;\n        const documentSelection = model.document.selection;\n        this._listenToIfEnabled(editor.model, 'deleteContent', (evt, [selection])=>{\n            if (selection && !selection.is('documentSelection')) {\n                return;\n            }\n            const typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition(documentSelection);\n            // Disable removing the selection content while pasting plain text.\n            if (typeAroundFakeCaretPosition) {\n                evt.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n    }\n}\n/**\n * Injects the type around UI into a view widget instance.\n */ function injectUIIntoWidget(viewWriter, buttonTitles, widgetViewElement) {\n    const typeAroundWrapper = viewWriter.createUIElement('div', {\n        class: 'ck ck-reset_all ck-widget__type-around'\n    }, function(domDocument) {\n        const wrapperDomElement = this.toDomElement(domDocument);\n        injectButtons(wrapperDomElement, buttonTitles);\n        injectFakeCaret(wrapperDomElement);\n        return wrapperDomElement;\n    });\n    // Inject the type around wrapper into the widget's wrapper.\n    viewWriter.insert(viewWriter.createPositionAt(widgetViewElement, 'end'), typeAroundWrapper);\n}\n/**\n * FYI: Not using the IconView class because each instance would need to be destroyed to avoid memory leaks\n * and it's pretty hard to figure out when a view (widget) is gone for good so it's cheaper to use raw\n * <svg> here.\n */ function injectButtons(wrapperDomElement, buttonTitles) {\n    for (const position of POSSIBLE_INSERTION_POSITIONS){\n        const buttonTemplate = new Template({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-widget__type-around__button',\n                    `ck-widget__type-around__button_${position}`\n                ],\n                title: buttonTitles[position],\n                'aria-hidden': 'true'\n            },\n            children: [\n                wrapperDomElement.ownerDocument.importNode(RETURN_ARROW_ICON_ELEMENT, true)\n            ]\n        });\n        wrapperDomElement.appendChild(buttonTemplate.render());\n    }\n}\nfunction injectFakeCaret(wrapperDomElement) {\n    const caretTemplate = new Template({\n        tag: 'div',\n        attributes: {\n            class: [\n                'ck',\n                'ck-widget__type-around__fake-caret'\n            ]\n        }\n    });\n    wrapperDomElement.appendChild(caretTemplate.render());\n}\n/**\n * Returns the ancestor of an element closest to the root which is empty. For instance,\n * for `<baz>`:\n *\n * ```\n * <foo>abc<bar><baz></baz></bar></foo>\n * ```\n *\n * it returns `<bar>`.\n */ function getDeepestEmptyElementAncestor(schema, element) {\n    let deepestEmptyAncestor = element;\n    for (const ancestor of element.getAncestors({\n        parentFirst: true\n    })){\n        if (ancestor.childCount > 1 || schema.isLimit(ancestor)) {\n            break;\n        }\n        deepestEmptyAncestor = ancestor;\n    }\n    return deepestEmptyAncestor;\n}\n\n/**\n * Returns 'keydown' handler for up/down arrow keys that modifies the caret movement if it's in a text line next to an object.\n *\n * @param editing The editing controller.\n */ function verticalNavigationHandler(editing) {\n    const model = editing.model;\n    return (evt, data)=>{\n        const arrowUpPressed = data.keyCode == keyCodes.arrowup;\n        const arrowDownPressed = data.keyCode == keyCodes.arrowdown;\n        const expandSelection = data.shiftKey;\n        const selection = model.document.selection;\n        if (!arrowUpPressed && !arrowDownPressed) {\n            return;\n        }\n        const isForward = arrowDownPressed;\n        // Navigation is in the opposite direction than the selection direction so this is shrinking of the selection.\n        // Selection for sure will not approach any object.\n        if (expandSelection && selectionWillShrink(selection, isForward)) {\n            return;\n        }\n        // Find a range between selection and closest limit element.\n        const range = findTextRangeFromSelection(editing, selection, isForward);\n        // There is no selection position inside the limit element.\n        if (!range) {\n            return;\n        }\n        // If already at the edge of a limit element.\n        if (range.isCollapsed) {\n            // A collapsed selection at limit edge - nothing more to do.\n            if (selection.isCollapsed) {\n                return;\n            } else if (expandSelection) {\n                return;\n            }\n        }\n        // If the range is a single line (there is no word wrapping) then move the selection to the position closest to the limit element.\n        //\n        // We can't move the selection directly to the isObject element (eg. table cell) because of dual position at the end/beginning\n        // of wrapped line (it's at the same time at the end of one line and at the start of the next line).\n        if (range.isCollapsed || isSingleLineRange(editing, range, isForward)) {\n            model.change((writer)=>{\n                const newPosition = isForward ? range.end : range.start;\n                if (expandSelection) {\n                    const newSelection = model.createSelection(selection.anchor);\n                    newSelection.setFocus(newPosition);\n                    writer.setSelection(newSelection);\n                } else {\n                    writer.setSelection(newPosition);\n                }\n            });\n            evt.stop();\n            data.preventDefault();\n            data.stopPropagation();\n        }\n    };\n}\n/**\n * Finds the range between selection and closest limit element (in the direction of navigation).\n * The position next to limit element is adjusted to the closest allowed `$text` position.\n *\n * Returns `null` if, according to the schema, the resulting range cannot contain a `$text` element.\n *\n * @param editing The editing controller.\n * @param selection The current selection.\n * @param isForward The expected navigation direction.\n */ function findTextRangeFromSelection(editing, selection, isForward) {\n    const model = editing.model;\n    if (isForward) {\n        const startPosition = selection.isCollapsed ? selection.focus : selection.getLastPosition();\n        const endPosition = getNearestNonInlineLimit(model, startPosition, 'forward');\n        // There is no limit element, browser should handle this.\n        if (!endPosition) {\n            return null;\n        }\n        const range = model.createRange(startPosition, endPosition);\n        const lastRangePosition = getNearestTextPosition(model.schema, range, 'backward');\n        if (lastRangePosition) {\n            return model.createRange(startPosition, lastRangePosition);\n        }\n        return null;\n    } else {\n        const endPosition = selection.isCollapsed ? selection.focus : selection.getFirstPosition();\n        const startPosition = getNearestNonInlineLimit(model, endPosition, 'backward');\n        // There is no limit element, browser should handle this.\n        if (!startPosition) {\n            return null;\n        }\n        const range = model.createRange(startPosition, endPosition);\n        const firstRangePosition = getNearestTextPosition(model.schema, range, 'forward');\n        if (firstRangePosition) {\n            return model.createRange(firstRangePosition, endPosition);\n        }\n        return null;\n    }\n}\n/**\n * Finds the limit element position that is closest to startPosition.\n *\n * @param direction Search direction.\n */ function getNearestNonInlineLimit(model, startPosition, direction) {\n    const schema = model.schema;\n    const range = model.createRangeIn(startPosition.root);\n    const walkerValueType = direction == 'forward' ? 'elementStart' : 'elementEnd';\n    for (const { previousPosition, item, type } of range.getWalker({\n        startPosition,\n        direction\n    })){\n        if (schema.isLimit(item) && !schema.isInline(item)) {\n            return previousPosition;\n        }\n        // Stop looking for isLimit element if the next element is a block element (it is for sure not single line).\n        if (type == walkerValueType && schema.isBlock(item)) {\n            return null;\n        }\n    }\n    return null;\n}\n/**\n * Basing on the provided range, finds the first or last (depending on `direction`) position inside the range\n * that can contain `$text` (according to schema).\n *\n * @param schema The schema.\n * @param range The range to find the position in.\n * @param direction Search direction.\n * @returns The nearest selection position.\n *\n */ function getNearestTextPosition(schema, range, direction) {\n    const position = direction == 'backward' ? range.end : range.start;\n    if (schema.checkChild(position, '$text')) {\n        return position;\n    }\n    for (const { nextPosition } of range.getWalker({\n        direction\n    })){\n        if (schema.checkChild(nextPosition, '$text')) {\n            return nextPosition;\n        }\n    }\n    return null;\n}\n/**\n * Checks if the DOM range corresponding to the provided model range renders as a single line by analyzing DOMRects\n * (verifying if they visually wrap content to the next line).\n *\n * @param editing The editing controller.\n * @param modelRange The current table cell content range.\n * @param isForward The expected navigation direction.\n */ function isSingleLineRange(editing, modelRange, isForward) {\n    const model = editing.model;\n    const domConverter = editing.view.domConverter;\n    // Wrapped lines contain exactly the same position at the end of current line\n    // and at the beginning of next line. That position's client rect is at the end\n    // of current line. In case of caret at first position of the last line that 'dual'\n    // position would be detected as it's not the last line.\n    if (isForward) {\n        const probe = model.createSelection(modelRange.start);\n        model.modifySelection(probe);\n        // If the new position is at the end of the container then we can't use this position\n        // because it would provide incorrect result for eg caption of image and selection\n        // just before end of it. Also in this case there is no \"dual\" position.\n        if (!probe.focus.isAtEnd && !modelRange.start.isEqual(probe.focus)) {\n            modelRange = model.createRange(probe.focus, modelRange.end);\n        }\n    }\n    const viewRange = editing.mapper.toViewRange(modelRange);\n    const domRange = domConverter.viewRangeToDom(viewRange);\n    const rects = Rect.getDomRangeRects(domRange);\n    let boundaryVerticalPosition;\n    for (const rect of rects){\n        if (boundaryVerticalPosition === undefined) {\n            boundaryVerticalPosition = Math.round(rect.bottom);\n            continue;\n        }\n        // Let's check if this rect is in new line.\n        if (Math.round(rect.top) >= boundaryVerticalPosition) {\n            return false;\n        }\n        boundaryVerticalPosition = Math.max(boundaryVerticalPosition, Math.round(rect.bottom));\n    }\n    return true;\n}\nfunction selectionWillShrink(selection, isForward) {\n    return !selection.isCollapsed && selection.isBackward == isForward;\n}\n\n/**\n * The widget plugin. It enables base support for widgets.\n *\n * See {@glink api/widget package page} for more details and documentation.\n *\n * This plugin enables multiple behaviors required by widgets:\n *\n * * The model to view selection converter for the editing pipeline (it handles widget custom selection rendering).\n * If a converted selection wraps around a widget element, that selection is marked as\n * {@link module:engine/view/selection~Selection#isFake fake}. Additionally, the `ck-widget_selected` CSS class\n * is added to indicate that widget has been selected.\n * * The mouse and keyboard events handling on and around widget elements.\n */ class Widget extends Plugin {\n    /**\n\t * Holds previously selected widgets.\n\t */ _previouslySelected = new Set();\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Widget';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            WidgetTypeAround,\n            Delete\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const t = editor.t;\n        // Model to view selection converter.\n        // Converts selection placed over widget element to fake selection.\n        //\n        // By default, the selection is downcasted by the engine to surround the attribute element, even though its only\n        // child is an inline widget. A similar thing also happens when a collapsed marker is rendered as a UI element\n        // next to an inline widget: the view selection contains both the widget and the marker.\n        //\n        // This prevents creating a correct fake selection when this inline widget is selected. Normalize the selection\n        // in these cases based on the model:\n        //\n        //\t\t[<attributeElement><inlineWidget /></attributeElement>] -> <attributeElement>[<inlineWidget />]</attributeElement>\n        //\t\t[<uiElement></uiElement><inlineWidget />] -> <uiElement></uiElement>[<inlineWidget />]\n        //\n        // Thanks to this:\n        //\n        // * fake selection can be set correctly,\n        // * any logic depending on (View)Selection#getSelectedElement() also works OK.\n        //\n        // See https://github.com/ckeditor/ckeditor5/issues/9524.\n        this.editor.editing.downcastDispatcher.on('selection', (evt, data, conversionApi)=>{\n            const viewWriter = conversionApi.writer;\n            const modelSelection = data.selection;\n            // The collapsed selection can't contain any widget.\n            if (modelSelection.isCollapsed) {\n                return;\n            }\n            const selectedModelElement = modelSelection.getSelectedElement();\n            if (!selectedModelElement) {\n                return;\n            }\n            const selectedViewElement = editor.editing.mapper.toViewElement(selectedModelElement);\n            if (!isWidget(selectedViewElement)) {\n                return;\n            }\n            if (!conversionApi.consumable.consume(modelSelection, 'selection')) {\n                return;\n            }\n            viewWriter.setSelection(viewWriter.createRangeOn(selectedViewElement), {\n                fake: true,\n                label: getLabel(selectedViewElement)\n            });\n        });\n        // Mark all widgets inside the selection with the css class.\n        // This handler is registered at the 'low' priority so it's triggered after the real selection conversion.\n        this.editor.editing.downcastDispatcher.on('selection', (evt, data, conversionApi)=>{\n            // Remove selected class from previously selected widgets.\n            this._clearPreviouslySelectedWidgets(conversionApi.writer);\n            const viewWriter = conversionApi.writer;\n            const viewSelection = viewWriter.document.selection;\n            let lastMarked = null;\n            for (const range of viewSelection.getRanges()){\n                // Note: There could be multiple selected widgets in a range but no fake selection.\n                // All of them must be marked as selected, for instance [<widget></widget><widget></widget>]\n                for (const value of range){\n                    const node = value.item;\n                    // Do not mark nested widgets in selected one. See: #4594\n                    if (isWidget(node) && !isChild(node, lastMarked)) {\n                        viewWriter.addClass(WIDGET_SELECTED_CLASS_NAME, node);\n                        this._previouslySelected.add(node);\n                        lastMarked = node;\n                    }\n                }\n            }\n        }, {\n            priority: 'low'\n        });\n        // If mouse down is pressed on widget - create selection over whole widget.\n        view.addObserver(MouseObserver);\n        this.listenTo(viewDocument, 'mousedown', (...args)=>this._onMousedown(...args));\n        // There are two keydown listeners working on different priorities. This allows other\n        // features such as WidgetTypeAround or TableKeyboard to attach their listeners in between\n        // and customize the behavior even further in different content/selection scenarios.\n        //\n        // * The first listener handles changing the selection on arrow key press\n        // if the widget is selected or if the selection is next to a widget and the widget\n        // should become selected upon the arrow key press.\n        //\n        // * The second (late) listener makes sure the default browser action on arrow key press is\n        // prevented when a widget is selected. This prevents the selection from being moved\n        // from a fake selection container.\n        this.listenTo(viewDocument, 'arrowKey', (...args)=>{\n            this._handleSelectionChangeOnArrowKeyPress(...args);\n        }, {\n            context: [\n                isWidget,\n                '$text'\n            ]\n        });\n        this.listenTo(viewDocument, 'arrowKey', (...args)=>{\n            this._preventDefaultOnArrowKeyPress(...args);\n        }, {\n            context: '$root'\n        });\n        this.listenTo(viewDocument, 'arrowKey', verticalNavigationHandler(this.editor.editing), {\n            context: '$text'\n        });\n        // Handle custom delete behaviour.\n        this.listenTo(viewDocument, 'delete', (evt, data)=>{\n            if (this._handleDelete(data.direction == 'forward')) {\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: '$root'\n        });\n        // Handle Tab key while a widget is selected.\n        this.listenTo(viewDocument, 'tab', (evt, data)=>{\n            // This event could be triggered from inside the widget, but we are interested\n            // only when the widget is selected itself.\n            if (evt.eventPhase != 'atTarget') {\n                return;\n            }\n            if (data.shiftKey) {\n                return;\n            }\n            if (this._selectFirstNestedEditable()) {\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: isWidget,\n            priority: 'low'\n        });\n        // Handle Shift+Tab key while caret inside a widget editable.\n        this.listenTo(viewDocument, 'tab', (evt, data)=>{\n            if (!data.shiftKey) {\n                return;\n            }\n            if (this._selectAncestorWidget()) {\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            priority: 'low'\n        });\n        // Handle Esc key while inside a nested editable.\n        this.listenTo(viewDocument, 'keydown', (evt, data)=>{\n            if (data.keystroke != keyCodes.esc) {\n                return;\n            }\n            if (this._selectAncestorWidget()) {\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            priority: 'low'\n        });\n        // Add the information about the keystrokes to the accessibility database.\n        editor.accessibility.addKeystrokeInfoGroup({\n            id: 'widget',\n            label: t('Keystrokes that can be used when a widget is selected (for example: image, table, etc.)'),\n            keystrokes: [\n                {\n                    label: t('Move focus from an editable area back to the parent widget'),\n                    keystroke: 'Esc'\n                },\n                {\n                    label: t('Insert a new paragraph directly after a widget'),\n                    keystroke: 'Enter'\n                },\n                {\n                    label: t('Insert a new paragraph directly before a widget'),\n                    keystroke: 'Shift+Enter'\n                },\n                {\n                    label: t('Move the caret to allow typing directly before a widget'),\n                    keystroke: [\n                        [\n                            'arrowup'\n                        ],\n                        [\n                            'arrowleft'\n                        ]\n                    ]\n                },\n                {\n                    label: t('Move the caret to allow typing directly after a widget'),\n                    keystroke: [\n                        [\n                            'arrowdown'\n                        ],\n                        [\n                            'arrowright'\n                        ]\n                    ]\n                }\n            ]\n        });\n    }\n    /**\n\t * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.\n\t */ _onMousedown(eventInfo, domEventData) {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        let element = domEventData.target;\n        // Some of DOM elements have no view element representation so it may be null.\n        if (!element) {\n            return;\n        }\n        // If triple click should select entire paragraph.\n        if (domEventData.domEvent.detail >= 3) {\n            if (this._selectBlockContent(element)) {\n                domEventData.preventDefault();\n            }\n            return;\n        }\n        // If target is not a widget element - check if one of the ancestors is.\n        if (!isWidget(element)) {\n            const editableOrWidgetElement = findClosestEditableOrWidgetAncestor(element);\n            if (!editableOrWidgetElement) {\n                return;\n            }\n            if (isWidget(editableOrWidgetElement)) {\n                element = editableOrWidgetElement;\n            } else {\n                // Pick view range from the point where the mouse was clicked.\n                const clickTargetFromPoint = getElementFromMouseEvent(view, domEventData);\n                if (clickTargetFromPoint && isWidget(clickTargetFromPoint)) {\n                    element = clickTargetFromPoint;\n                } else {\n                    return;\n                }\n            }\n        }\n        // On Android selection would jump to the first table cell, on other devices\n        // we can't block it (and don't need to) because of drag and drop support.\n        if (env.isAndroid) {\n            domEventData.preventDefault();\n        }\n        // Focus editor if is not focused already.\n        if (!viewDocument.isFocused) {\n            view.focus();\n        }\n        // Create model selection over widget.\n        const modelElement = editor.editing.mapper.toModelElement(element);\n        this._setSelectionOverElement(modelElement);\n    }\n    /**\n\t * Selects entire block content, e.g. on triple click it selects entire paragraph.\n\t */ _selectBlockContent(element) {\n        const editor = this.editor;\n        const model = editor.model;\n        const mapper = editor.editing.mapper;\n        const schema = model.schema;\n        const viewElement = mapper.findMappedViewAncestor(this.editor.editing.view.createPositionAt(element, 0));\n        const modelElement = findTextBlockAncestor(mapper.toModelElement(viewElement), model.schema);\n        if (!modelElement) {\n            return false;\n        }\n        model.change((writer)=>{\n            const nextTextBlock = !schema.isLimit(modelElement) ? findNextTextBlock(writer.createPositionAfter(modelElement), schema) : null;\n            const start = writer.createPositionAt(modelElement, 0);\n            const end = nextTextBlock ? writer.createPositionAt(nextTextBlock, 0) : writer.createPositionAt(modelElement, 'end');\n            writer.setSelection(writer.createRange(start, end));\n        });\n        return true;\n    }\n    /**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes\n\t * the model selection when:\n\t *\n\t * * arrow key is pressed when the widget is selected,\n\t * * the selection is next to a widget and the widget should become selected upon the arrow key press.\n\t *\n\t * See {@link #_preventDefaultOnArrowKeyPress}.\n\t */ _handleSelectionChangeOnArrowKeyPress(eventInfo, domEventData) {\n        const keyCode = domEventData.keyCode;\n        const model = this.editor.model;\n        const schema = model.schema;\n        const modelSelection = model.document.selection;\n        const objectElement = modelSelection.getSelectedElement();\n        const direction = getLocalizedArrowKeyCodeDirection(keyCode, this.editor.locale.contentLanguageDirection);\n        const isForward = direction == 'down' || direction == 'right';\n        const isVerticalNavigation = direction == 'up' || direction == 'down';\n        // If object element is selected.\n        if (objectElement && schema.isObject(objectElement)) {\n            const position = isForward ? modelSelection.getLastPosition() : modelSelection.getFirstPosition();\n            const newRange = schema.getNearestSelectionRange(position, isForward ? 'forward' : 'backward');\n            if (newRange) {\n                model.change((writer)=>{\n                    writer.setSelection(newRange);\n                });\n                domEventData.preventDefault();\n                eventInfo.stop();\n            }\n            return;\n        }\n        // Handle collapsing of the selection when there is any widget on the edge of selection.\n        // This is needed because browsers have problems with collapsing such selection.\n        if (!modelSelection.isCollapsed && !domEventData.shiftKey) {\n            const firstPosition = modelSelection.getFirstPosition();\n            const lastPosition = modelSelection.getLastPosition();\n            const firstSelectedNode = firstPosition.nodeAfter;\n            const lastSelectedNode = lastPosition.nodeBefore;\n            if (firstSelectedNode && schema.isObject(firstSelectedNode) || lastSelectedNode && schema.isObject(lastSelectedNode)) {\n                model.change((writer)=>{\n                    writer.setSelection(isForward ? lastPosition : firstPosition);\n                });\n                domEventData.preventDefault();\n                eventInfo.stop();\n            }\n            return;\n        }\n        // Return if not collapsed.\n        if (!modelSelection.isCollapsed) {\n            return;\n        }\n        // If selection is next to object element.\n        const objectElementNextToSelection = this._getObjectElementNextToSelection(isForward);\n        if (objectElementNextToSelection && schema.isObject(objectElementNextToSelection)) {\n            // Do not select an inline widget while handling up/down arrow.\n            if (schema.isInline(objectElementNextToSelection) && isVerticalNavigation) {\n                return;\n            }\n            this._setSelectionOverElement(objectElementNextToSelection);\n            domEventData.preventDefault();\n            eventInfo.stop();\n        }\n    }\n    /**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and prevents\n\t * the default browser behavior to make sure the fake selection is not being moved from a fake selection\n\t * container.\n\t *\n\t * See {@link #_handleSelectionChangeOnArrowKeyPress}.\n\t */ _preventDefaultOnArrowKeyPress(eventInfo, domEventData) {\n        const model = this.editor.model;\n        const schema = model.schema;\n        const objectElement = model.document.selection.getSelectedElement();\n        // If object element is selected.\n        if (objectElement && schema.isObject(objectElement)) {\n            domEventData.preventDefault();\n            eventInfo.stop();\n        }\n    }\n    /**\n\t * Handles delete keys: backspace and delete.\n\t *\n\t * @param isForward Set to true if delete was performed in forward direction.\n\t * @returns Returns `true` if keys were handled correctly.\n\t */ _handleDelete(isForward) {\n        const modelDocument = this.editor.model.document;\n        const modelSelection = modelDocument.selection;\n        // Do nothing when the read only mode is enabled.\n        if (!this.editor.model.canEditAt(modelSelection)) {\n            return;\n        }\n        // Do nothing on non-collapsed selection.\n        if (!modelSelection.isCollapsed) {\n            return;\n        }\n        const objectElement = this._getObjectElementNextToSelection(isForward);\n        if (objectElement) {\n            this.editor.model.change((writer)=>{\n                let previousNode = modelSelection.anchor.parent;\n                // Remove previous element if empty.\n                while(previousNode.isEmpty){\n                    const nodeToRemove = previousNode;\n                    previousNode = nodeToRemove.parent;\n                    writer.remove(nodeToRemove);\n                }\n                this._setSelectionOverElement(objectElement);\n            });\n            return true;\n        }\n    }\n    /**\n\t * Sets {@link module:engine/model/selection~Selection document's selection} over given element.\n\t *\n\t * @internal\n\t */ _setSelectionOverElement(element) {\n        this.editor.model.change((writer)=>{\n            writer.setSelection(writer.createRangeOn(element));\n        });\n    }\n    /**\n\t * Checks if {@link module:engine/model/element~Element element} placed next to the current\n\t * {@link module:engine/model/selection~Selection model selection} exists and is marked in\n\t * {@link module:engine/model/schema~Schema schema} as `object`.\n\t *\n\t * @internal\n\t * @param forward Direction of checking.\n\t */ _getObjectElementNextToSelection(forward) {\n        const model = this.editor.model;\n        const schema = model.schema;\n        const modelSelection = model.document.selection;\n        // Clone current selection to use it as a probe. We must leave default selection as it is so it can return\n        // to its current state after undo.\n        const probe = model.createSelection(modelSelection);\n        model.modifySelection(probe, {\n            direction: forward ? 'forward' : 'backward'\n        });\n        // The selection didn't change so there is nothing there.\n        if (probe.isEqual(modelSelection)) {\n            return null;\n        }\n        const objectElement = forward ? probe.focus.nodeBefore : probe.focus.nodeAfter;\n        if (!!objectElement && schema.isObject(objectElement)) {\n            return objectElement;\n        }\n        return null;\n    }\n    /**\n\t * Removes CSS class from previously selected widgets.\n\t */ _clearPreviouslySelectedWidgets(writer) {\n        for (const widget of this._previouslySelected){\n            writer.removeClass(WIDGET_SELECTED_CLASS_NAME, widget);\n        }\n        this._previouslySelected.clear();\n    }\n    /**\n\t * Moves the document selection into the first nested editable.\n\t */ _selectFirstNestedEditable() {\n        const editor = this.editor;\n        const view = this.editor.editing.view;\n        const viewDocument = view.document;\n        for (const item of viewDocument.selection.getFirstRange().getItems()){\n            if (item.is('editableElement')) {\n                const modelElement = editor.editing.mapper.toModelElement(item);\n                /* istanbul ignore next -- @preserve */ if (!modelElement) {\n                    continue;\n                }\n                const position = editor.model.createPositionAt(modelElement, 0);\n                const newRange = editor.model.schema.getNearestSelectionRange(position, 'forward');\n                editor.model.change((writer)=>{\n                    writer.setSelection(newRange);\n                });\n                return true;\n            }\n        }\n        return false;\n    }\n    /**\n\t * Updates the document selection so that it selects first ancestor widget.\n\t */ _selectAncestorWidget() {\n        const editor = this.editor;\n        const mapper = editor.editing.mapper;\n        const selection = editor.editing.view.document.selection;\n        const positionParent = selection.getFirstPosition().parent;\n        const positionParentElement = positionParent.is('$text') ? positionParent.parent : positionParent;\n        const viewElement = positionParentElement.findAncestor(isWidget);\n        if (!viewElement) {\n            return false;\n        }\n        const modelElement = mapper.toModelElement(viewElement);\n        /* istanbul ignore next -- @preserve */ if (!modelElement) {\n            return false;\n        }\n        editor.model.change((writer)=>{\n            writer.setSelection(modelElement, 'on');\n        });\n        return true;\n    }\n}\n/**\n * Finds the closest ancestor element that is either an editable element or a widget.\n *\n * @param element The element from which to start searching.\n * @returns The closest ancestor element that is either an editable element or a widget, or null if none is found.\n */ function findClosestEditableOrWidgetAncestor(element) {\n    let currentElement = element;\n    while(currentElement){\n        if (currentElement.is('editableElement') || isWidget(currentElement)) {\n            return currentElement;\n        }\n        currentElement = currentElement.parent;\n    }\n    return null;\n}\n/**\n * Retrieves the ViewElement associated with a mouse event in the editing view.\n *\n * @param view The editing view.\n * @param domEventData The DOM event data containing the mouse event.\n * @returns The ViewElement associated with the mouse event, or null if not found.\n */ function getElementFromMouseEvent(view, domEventData) {\n    const domRange = getRangeFromMouseEvent(domEventData.domEvent);\n    let viewRange = null;\n    if (domRange) {\n        viewRange = view.domConverter.domRangeToView(domRange);\n    } else {\n        // Fallback to create range in target element. It happens frequently on Safari browser.\n        // See more: https://github.com/ckeditor/ckeditor5/issues/16978\n        viewRange = view.createRange(view.createPositionAt(domEventData.target, 0));\n    }\n    if (!viewRange) {\n        return null;\n    }\n    const viewPosition = viewRange.start;\n    if (!viewPosition.parent) {\n        return null;\n    }\n    let viewNode = viewPosition.parent;\n    if (viewPosition.parent.is('editableElement')) {\n        if (viewPosition.isAtEnd && viewPosition.nodeBefore) {\n            // Click after a widget tend to return position at the end of the editable element\n            // so use the node before it if range is at the end of a parent.\n            viewNode = viewPosition.nodeBefore;\n        } else if (viewPosition.isAtStart && viewPosition.nodeAfter) {\n            // Click before a widget tend to return position at the start of the editable element\n            // so use the node after it if range is at the start of a parent.\n            // See more: https://github.com/ckeditor/ckeditor5/issues/16992\n            viewNode = viewPosition.nodeAfter;\n        }\n    }\n    if (viewNode.is('$text')) {\n        return viewNode.parent;\n    }\n    return viewNode;\n}\n/**\n * Checks whether the specified `element` is a child of the `parent` element.\n *\n * @param element An element to check.\n * @param parent A parent for the element.\n */ function isChild(element, parent) {\n    if (!parent) {\n        return false;\n    }\n    return Array.from(element.getAncestors()).includes(parent);\n}\n/**\n * Returns nearest text block ancestor.\n */ function findTextBlockAncestor(modelElement, schema) {\n    for (const element of modelElement.getAncestors({\n        includeSelf: true,\n        parentFirst: true\n    })){\n        if (schema.checkChild(element, '$text')) {\n            return element;\n        }\n        // Do not go beyond nested editable.\n        if (schema.isLimit(element) && !schema.isObject(element)) {\n            break;\n        }\n    }\n    return null;\n}\n/**\n * Returns next text block where could put selection.\n */ function findNextTextBlock(position, schema) {\n    const treeWalker = new TreeWalker({\n        startPosition: position\n    });\n    for (const { item } of treeWalker){\n        if (schema.isLimit(item) || !item.is('element')) {\n            return null;\n        }\n        if (schema.checkChild(item, '$text')) {\n            return item;\n        }\n    }\n    return null;\n}\n\n/**\n * Widget toolbar repository plugin. A central point for registering widget toolbars. This plugin handles the whole\n * toolbar rendering process and exposes a concise API.\n *\n * To add a toolbar for your widget use the {@link ~WidgetToolbarRepository#register `WidgetToolbarRepository#register()`} method.\n *\n * The following example comes from the {@link module:image/imagetoolbar~ImageToolbar} plugin:\n *\n * ```ts\n * class ImageToolbar extends Plugin {\n * \tstatic get requires() {\n * \t\treturn [ WidgetToolbarRepository ];\n * \t}\n *\n * \tafterInit() {\n * \t\tconst editor = this.editor;\n * \t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n *\n * \t\twidgetToolbarRepository.register( 'image', {\n * \t\t\titems: editor.config.get( 'image.toolbar' ),\n * \t\t\tgetRelatedElement: getClosestSelectedImageWidget\n * \t\t} );\n * \t}\n * }\n * ```\n */ class WidgetToolbarRepository extends Plugin {\n    /**\n\t * A map of toolbar definitions.\n\t */ _toolbarDefinitions = new Map();\n    _balloon;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'WidgetToolbarRepository';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Disables the default balloon toolbar for all widgets.\n        if (editor.plugins.has('BalloonToolbar')) {\n            const balloonToolbar = editor.plugins.get('BalloonToolbar');\n            this.listenTo(balloonToolbar, 'show', (evt)=>{\n                if (isWidgetSelected(editor.editing.view.document.selection)) {\n                    evt.stop();\n                }\n            }, {\n                priority: 'high'\n            });\n        }\n        this._balloon = this.editor.plugins.get('ContextualBalloon');\n        this.on('change:isEnabled', ()=>{\n            this._updateToolbarsVisibility();\n        });\n        this.listenTo(editor.ui, 'update', ()=>{\n            this._updateToolbarsVisibility();\n        });\n        // UI#update is not fired after focus is back in editor, we need to check if balloon panel should be visible.\n        this.listenTo(editor.ui.focusTracker, 'change:isFocused', ()=>{\n            this._updateToolbarsVisibility();\n        }, {\n            priority: 'low'\n        });\n    }\n    destroy() {\n        super.destroy();\n        for (const toolbarConfig of this._toolbarDefinitions.values()){\n            toolbarConfig.view.destroy();\n        }\n    }\n    /**\n\t * Registers toolbar in the WidgetToolbarRepository. It renders it in the `ContextualBalloon` based on the value of the invoked\n\t * `getRelatedElement` function. Toolbar items are gathered from `items` array.\n\t * The balloon's CSS class is by default `ck-toolbar-container` and may be override with the `balloonClassName` option.\n\t *\n\t * Note: This method should be called in the {@link module:core/plugin~PluginInterface#afterInit `Plugin#afterInit()`}\n\t * callback (or later) to make sure that the given toolbar items were already registered by other plugins.\n\t *\n\t * @param toolbarId An id for the toolbar. Used to\n\t * @param options.ariaLabel Label used by assistive technologies to describe this toolbar element.\n\t * @param options.items Array of toolbar items.\n\t * @param options.getRelatedElement Callback which returns an element the toolbar should be attached to.\n\t * @param options.balloonClassName CSS class for the widget balloon.\n\t */ register(toolbarId, { ariaLabel, items, getRelatedElement, balloonClassName = 'ck-toolbar-container' }) {\n        // Trying to register a toolbar without any item.\n        if (!items.length) {\n            /**\n\t\t\t * When {@link module:widget/widgettoolbarrepository~WidgetToolbarRepository#register registering} a new widget toolbar, you\n\t\t\t * need to provide a non-empty array with the items that will be inserted into the toolbar.\n\t\t\t *\n\t\t\t * If you see this error when integrating the editor, you likely forgot to configure one of the widget toolbars.\n\t\t\t *\n\t\t\t * See for instance:\n\t\t\t *\n\t\t\t * * {@link module:table/tableconfig~TableConfig#contentToolbar `config.table.contentToolbar`}\n\t\t\t * * {@link module:image/imageconfig~ImageConfig#toolbar `config.image.toolbar`}\n\t\t\t *\n\t\t\t * @error widget-toolbar-no-items\n\t\t\t * @param toolbarId The id of the toolbar that has not been configured correctly.\n\t\t\t */ logWarning('widget-toolbar-no-items', {\n                toolbarId\n            });\n            return;\n        }\n        const editor = this.editor;\n        const t = editor.t;\n        const toolbarView = new ToolbarView(editor.locale);\n        toolbarView.ariaLabel = ariaLabel || t('Widget toolbar');\n        if (this._toolbarDefinitions.has(toolbarId)) {\n            /**\n\t\t\t * Toolbar with the given id was already added.\n\t\t\t *\n\t\t\t * @error widget-toolbar-duplicated\n\t\t\t * @param toolbarId Toolbar id.\n\t\t\t */ throw new CKEditorError('widget-toolbar-duplicated', this, {\n                toolbarId\n            });\n        }\n        const toolbarDefinition = {\n            view: toolbarView,\n            getRelatedElement,\n            balloonClassName,\n            itemsConfig: items,\n            initialized: false\n        };\n        // Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n        editor.ui.addToolbar(toolbarView, {\n            isContextual: true,\n            beforeFocus: ()=>{\n                const relatedElement = getRelatedElement(editor.editing.view.document.selection);\n                if (relatedElement) {\n                    this._showToolbar(toolbarDefinition, relatedElement);\n                }\n            },\n            afterBlur: ()=>{\n                this._hideToolbar(toolbarDefinition);\n            }\n        });\n        this._toolbarDefinitions.set(toolbarId, toolbarDefinition);\n    }\n    /**\n\t * Iterates over stored toolbars and makes them visible or hidden.\n\t */ _updateToolbarsVisibility() {\n        let maxRelatedElementDepth = 0;\n        let deepestRelatedElement = null;\n        let deepestToolbarDefinition = null;\n        for (const definition of this._toolbarDefinitions.values()){\n            const relatedElement = definition.getRelatedElement(this.editor.editing.view.document.selection);\n            if (!this.isEnabled || !relatedElement) {\n                if (this._isToolbarInBalloon(definition)) {\n                    this._hideToolbar(definition);\n                }\n            } else if (!this.editor.ui.focusTracker.isFocused) {\n                if (this._isToolbarVisible(definition)) {\n                    this._hideToolbar(definition);\n                }\n            } else {\n                const relatedElementDepth = relatedElement.getAncestors().length;\n                // Many toolbars can express willingness to be displayed but they do not know about\n                // each other. Figure out which toolbar is deepest in the view tree to decide which\n                // should be displayed. For instance, if a selected image is inside a table cell, display\n                // the ImageToolbar rather than the TableToolbar (#60).\n                if (relatedElementDepth > maxRelatedElementDepth) {\n                    maxRelatedElementDepth = relatedElementDepth;\n                    deepestRelatedElement = relatedElement;\n                    deepestToolbarDefinition = definition;\n                }\n            }\n        }\n        if (deepestToolbarDefinition) {\n            this._showToolbar(deepestToolbarDefinition, deepestRelatedElement);\n        }\n    }\n    /**\n\t * Hides the given toolbar.\n\t */ _hideToolbar(toolbarDefinition) {\n        this._balloon.remove(toolbarDefinition.view);\n        this.stopListening(this._balloon, 'change:visibleView');\n    }\n    /**\n\t * Shows up the toolbar if the toolbar is not visible.\n\t * Otherwise, repositions the toolbar's balloon when toolbar's view is the most top view in balloon stack.\n\t *\n\t * It might happen here that the toolbar's view is under another view. Then do nothing as the other toolbar view\n\t * should be still visible after the {@link module:ui/editorui/editorui~EditorUI#event:update}.\n\t */ _showToolbar(toolbarDefinition, relatedElement) {\n        if (this._isToolbarVisible(toolbarDefinition)) {\n            repositionContextualBalloon(this.editor, relatedElement);\n        } else if (!this._isToolbarInBalloon(toolbarDefinition)) {\n            if (!toolbarDefinition.initialized) {\n                toolbarDefinition.initialized = true;\n                toolbarDefinition.view.fillFromConfig(toolbarDefinition.itemsConfig, this.editor.ui.componentFactory);\n            }\n            this._balloon.add({\n                view: toolbarDefinition.view,\n                position: getBalloonPositionData(this.editor, relatedElement),\n                balloonClassName: toolbarDefinition.balloonClassName\n            });\n            // Update toolbar position each time stack with toolbar view is switched to visible.\n            // This is in a case target element has changed when toolbar was in invisible stack\n            // e.g. target image was wrapped by a block quote.\n            // See https://github.com/ckeditor/ckeditor5-widget/issues/92.\n            this.listenTo(this._balloon, 'change:visibleView', ()=>{\n                for (const definition of this._toolbarDefinitions.values()){\n                    if (this._isToolbarVisible(definition)) {\n                        const relatedElement = definition.getRelatedElement(this.editor.editing.view.document.selection);\n                        repositionContextualBalloon(this.editor, relatedElement);\n                    }\n                }\n            });\n        }\n    }\n    _isToolbarVisible(toolbar) {\n        return this._balloon.visibleView === toolbar.view;\n    }\n    _isToolbarInBalloon(toolbar) {\n        return this._balloon.hasView(toolbar.view);\n    }\n}\nfunction repositionContextualBalloon(editor, relatedElement) {\n    const balloon = editor.plugins.get('ContextualBalloon');\n    const position = getBalloonPositionData(editor, relatedElement);\n    balloon.updatePosition(position);\n}\nfunction getBalloonPositionData(editor, relatedElement) {\n    const editingView = editor.editing.view;\n    const defaultPositions = BalloonPanelView.defaultPositions;\n    return {\n        target: editingView.domConverter.mapViewToDom(relatedElement),\n        positions: [\n            defaultPositions.northArrowSouth,\n            defaultPositions.northArrowSouthWest,\n            defaultPositions.northArrowSouthEast,\n            defaultPositions.southArrowNorth,\n            defaultPositions.southArrowNorthWest,\n            defaultPositions.southArrowNorthEast,\n            defaultPositions.viewportStickyNorth\n        ]\n    };\n}\nfunction isWidgetSelected(selection) {\n    const viewElement = selection.getSelectedElement();\n    return !!(viewElement && isWidget(viewElement));\n}\n\n/**\n * Stores the internal state of a single resizable object.\n */ class ResizeState extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * The reference point of the resizer where the dragging started. It is used to measure the distance the user cursor\n\t * traveled, so how much the image should be enlarged.\n\t * This information is only known after the DOM was rendered, so it will be updated later.\n\t *\n\t * @internal\n\t */ _referenceCoordinates;\n    /**\n\t * Resizer options.\n\t */ _options;\n    /**\n\t * The original width (pixels) of the resized object when the resize process was started.\n\t *\n\t * @readonly\n\t */ _originalWidth;\n    /**\n\t * The original height (pixels) of the resized object when the resize process was started.\n\t *\n\t * @readonly\n\t */ _originalHeight;\n    /**\n\t * The original width (percents) of the resized object when the resize process was started.\n\t *\n\t * @readonly\n\t */ _originalWidthPercents;\n    /**\n\t * A width to height ratio of the resized image.\n\t *\n\t * @readonly\n\t */ _aspectRatio;\n    /**\n\t * @param options Resizer options.\n\t */ constructor(options){\n        super();\n        this.set('activeHandlePosition', null);\n        this.set('proposedWidthPercents', null);\n        this.set('proposedWidth', null);\n        this.set('proposedHeight', null);\n        this.set('proposedHandleHostWidth', null);\n        this.set('proposedHandleHostHeight', null);\n        this._options = options;\n        this._referenceCoordinates = null;\n    }\n    /**\n\t * The original width (pixels) of the resized object when the resize process was started.\n\t */ get originalWidth() {\n        return this._originalWidth;\n    }\n    /**\n\t * The original height (pixels) of the resized object when the resize process was started.\n\t */ get originalHeight() {\n        return this._originalHeight;\n    }\n    /**\n\t * The original width (percents) of the resized object when the resize process was started.\n\t */ get originalWidthPercents() {\n        return this._originalWidthPercents;\n    }\n    /**\n\t * A width to height ratio of the resized image.\n\t */ get aspectRatio() {\n        return this._aspectRatio;\n    }\n    /**\n\t *\n\t * @param domResizeHandle The handle used to calculate the reference point.\n\t */ begin(domResizeHandle, domHandleHost, domResizeHost) {\n        const clientRect = new Rect(domHandleHost);\n        this.activeHandlePosition = getHandlePosition(domResizeHandle);\n        this._referenceCoordinates = getAbsoluteBoundaryPoint(domHandleHost, getOppositePosition(this.activeHandlePosition));\n        this._originalWidth = clientRect.width;\n        this._originalHeight = clientRect.height;\n        this._aspectRatio = clientRect.width / clientRect.height;\n        const widthStyle = domResizeHost.style.width;\n        if (widthStyle && widthStyle.match(/^\\d+(\\.\\d*)?%$/)) {\n            this._originalWidthPercents = parseFloat(widthStyle);\n        } else {\n            this._originalWidthPercents = calculateResizeHostPercentageWidth(domResizeHost, clientRect);\n        }\n    }\n    update(newSize) {\n        this.proposedWidth = newSize.width;\n        this.proposedHeight = newSize.height;\n        this.proposedWidthPercents = newSize.widthPercents;\n        this.proposedHandleHostWidth = newSize.handleHostWidth;\n        this.proposedHandleHostHeight = newSize.handleHostHeight;\n    }\n}\n/**\n * Returns coordinates of the top-left corner of an element, relative to the document's top-left corner.\n *\n * @param resizerPosition The position of the resize handle, e.g. `\"top-left\"`, `\"bottom-right\"`.\n */ function getAbsoluteBoundaryPoint(element, resizerPosition) {\n    const elementRect = new Rect(element);\n    const positionParts = resizerPosition.split('-');\n    const ret = {\n        x: positionParts[1] == 'right' ? elementRect.right : elementRect.left,\n        y: positionParts[0] == 'bottom' ? elementRect.bottom : elementRect.top\n    };\n    ret.x += element.ownerDocument.defaultView.scrollX;\n    ret.y += element.ownerDocument.defaultView.scrollY;\n    return ret;\n}\n/**\n * @param resizerPosition The expected resizer position, like `\"top-left\"`, `\"bottom-right\"`.\n * @returns A prefixed HTML class name for the resizer element.\n */ function getResizerHandleClass(resizerPosition) {\n    return `ck-widget__resizer__handle-${resizerPosition}`;\n}\n/**\n * Determines the position of a given resize handle.\n *\n * @param domHandle Handle used to calculate the reference point.\n * @returns Returns a string like `\"top-left\"` or `undefined` if not matched.\n */ function getHandlePosition(domHandle) {\n    const resizerPositions = [\n        'top-left',\n        'top-right',\n        'bottom-right',\n        'bottom-left'\n    ];\n    for (const position of resizerPositions){\n        if (domHandle.classList.contains(getResizerHandleClass(position))) {\n            return position;\n        }\n    }\n}\n/**\n * @param position Like `\"top-left\"`.\n * @returns Inverted `position`, e.g. it returns `\"bottom-right\"` if `\"top-left\"` was given as `position`.\n */ function getOppositePosition(position) {\n    const parts = position.split('-');\n    const replacements = {\n        top: 'bottom',\n        bottom: 'top',\n        left: 'right',\n        right: 'left'\n    };\n    return `${replacements[parts[0]]}-${replacements[parts[1]]}`;\n}\n\n/**\n * A view displaying the proposed new element size during the resizing.\n */ class SizeView extends View {\n    constructor(){\n        super();\n        const bind = this.bindTemplate;\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-size-view',\n                    bind.to('_viewPosition', (value)=>value ? `ck-orientation-${value}` : '')\n                ],\n                style: {\n                    display: bind.if('_isVisible', 'none', (visible)=>!visible)\n                }\n            },\n            children: [\n                {\n                    text: bind.to('_label')\n                }\n            ]\n        });\n    }\n    /**\n\t * A method used for binding the `SizeView` instance properties to the `ResizeState` instance observable properties.\n\t *\n\t * @internal\n\t * @param options An object defining the resizer options, used for setting the proper size label.\n\t * @param resizeState The `ResizeState` class instance, used for keeping the `SizeView` state up to date.\n\t */ _bindToState(options, resizeState) {\n        this.bind('_isVisible').to(resizeState, 'proposedWidth', resizeState, 'proposedHeight', (width, height)=>width !== null && height !== null);\n        this.bind('_label').to(resizeState, 'proposedHandleHostWidth', resizeState, 'proposedHandleHostHeight', resizeState, 'proposedWidthPercents', (width, height, widthPercents)=>{\n            if (options.unit === 'px') {\n                return `${width}×${height}`;\n            } else {\n                return `${widthPercents}%`;\n            }\n        });\n        this.bind('_viewPosition').to(resizeState, 'activeHandlePosition', resizeState, 'proposedHandleHostWidth', resizeState, 'proposedHandleHostHeight', // If the widget is too small to contain the size label, display the label above.\n        (position, width, height)=>width < 50 || height < 50 ? 'above-center' : position);\n    }\n    /**\n\t * A method used for cleaning up. It removes the bindings and hides the view.\n\t *\n\t * @internal\n\t */ _dismiss() {\n        this.unbind();\n        this._isVisible = false;\n    }\n}\n\n/**\n * Represents a resizer for a single resizable object.\n */ class Resizer extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * Stores the state of the resizable host geometry, such as the original width, the currently proposed height, etc.\n\t *\n\t * Note that a new state is created for each resize transaction.\n\t */ _state;\n    /**\n\t * A view displaying the proposed new element size during the resizing.\n\t */ _sizeView;\n    /**\n\t * Options passed to the {@link #constructor}.\n\t */ _options;\n    /**\n\t * A wrapper that is controlled by the resizer. This is usually a widget element.\n\t */ _viewResizerWrapper = null;\n    /**\n\t * The width of the resized {@link module:widget/widgetresize~ResizerOptions#viewElement viewElement} before the resizing started.\n\t */ _initialViewWidth;\n    /**\n\t * @param options Resizer options.\n\t */ constructor(options){\n        super();\n        this._options = options;\n        this.set('isEnabled', true);\n        this.set('isSelected', false);\n        this.bind('isVisible').to(this, 'isEnabled', this, 'isSelected', (isEnabled, isSelected)=>isEnabled && isSelected);\n        this.decorate('begin');\n        this.decorate('cancel');\n        this.decorate('commit');\n        this.decorate('updateSize');\n        this.on('commit', (event)=>{\n            // State might not be initialized yet. In this case, prevent further handling and make sure that the resizer is\n            // cleaned up (#5195).\n            if (!this.state.proposedWidth && !this.state.proposedWidthPercents) {\n                this._cleanup();\n                event.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Stores the state of the resizable host geometry, such as the original width, the currently proposed height, etc.\n\t *\n\t * Note that a new state is created for each resize transaction.\n\t */ get state() {\n        return this._state;\n    }\n    /**\n\t * Makes resizer visible in the UI.\n\t */ show() {\n        const editingView = this._options.editor.editing.view;\n        editingView.change((writer)=>{\n            writer.removeClass('ck-hidden', this._viewResizerWrapper);\n        });\n    }\n    /**\n\t * Hides resizer in the UI.\n\t */ hide() {\n        const editingView = this._options.editor.editing.view;\n        editingView.change((writer)=>{\n            writer.addClass('ck-hidden', this._viewResizerWrapper);\n        });\n    }\n    /**\n\t * Attaches the resizer to the DOM.\n\t */ attach() {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\n        const that = this;\n        const widgetElement = this._options.viewElement;\n        const editingView = this._options.editor.editing.view;\n        editingView.change((writer)=>{\n            const viewResizerWrapper = writer.createUIElement('div', {\n                class: 'ck ck-reset_all ck-widget__resizer'\n            }, function(domDocument) {\n                const domElement = this.toDomElement(domDocument);\n                that._appendHandles(domElement);\n                that._appendSizeUI(domElement);\n                return domElement;\n            });\n            // Append the resizer wrapper to the widget's wrapper.\n            writer.insert(writer.createPositionAt(widgetElement, 'end'), viewResizerWrapper);\n            writer.addClass('ck-widget_with-resizer', widgetElement);\n            this._viewResizerWrapper = viewResizerWrapper;\n            if (!this.isVisible) {\n                this.hide();\n            }\n        });\n        this.on('change:isVisible', ()=>{\n            if (this.isVisible) {\n                this.show();\n                this.redraw();\n            } else {\n                this.hide();\n            }\n        });\n    }\n    /**\n\t * Starts the resizing process.\n\t *\n\t * Creates a new {@link #state} for the current process.\n\t *\n\t * @fires begin\n\t * @param domResizeHandle Clicked handle.\n\t */ begin(domResizeHandle) {\n        this._state = new ResizeState(this._options);\n        this._sizeView._bindToState(this._options, this.state);\n        this._initialViewWidth = this._options.viewElement.getStyle('width');\n        this.state.begin(domResizeHandle, this._getHandleHost(), this._getResizeHost());\n    }\n    /**\n\t * Updates the proposed size based on `domEventData`.\n\t *\n\t * @fires updateSize\n\t */ updateSize(domEventData) {\n        const newSize = this._proposeNewSize(domEventData);\n        const editingView = this._options.editor.editing.view;\n        editingView.change((writer)=>{\n            const unit = this._options.unit || '%';\n            const newWidth = (unit === '%' ? newSize.widthPercents : newSize.width) + unit;\n            writer.setStyle('width', newWidth, this._options.viewElement);\n        });\n        // Get an actual image width, and:\n        // * reflect this size to the resize wrapper\n        // * apply this **real** size to the state\n        const domHandleHost = this._getHandleHost();\n        const domHandleHostRect = new Rect(domHandleHost);\n        const handleHostWidth = Math.round(domHandleHostRect.width);\n        const handleHostHeight = Math.round(domHandleHostRect.height);\n        // Handle max-width limitation.\n        const domResizeHostRect = new Rect(domHandleHost);\n        newSize.width = Math.round(domResizeHostRect.width);\n        newSize.height = Math.round(domResizeHostRect.height);\n        this.redraw(domHandleHostRect);\n        this.state.update({\n            ...newSize,\n            handleHostWidth,\n            handleHostHeight\n        });\n    }\n    /**\n\t * Applies the geometry proposed with the resizer.\n\t *\n\t * @fires commit\n\t */ commit() {\n        const unit = this._options.unit || '%';\n        const newValue = (unit === '%' ? this.state.proposedWidthPercents : this.state.proposedWidth) + unit;\n        // Both cleanup and onCommit callback are very likely to make view changes. Ensure that it is made in a single step.\n        this._options.editor.editing.view.change(()=>{\n            this._cleanup();\n            this._options.onCommit(newValue);\n        });\n    }\n    /**\n\t * Cancels and rejects the proposed resize dimensions, hiding the UI.\n\t *\n\t * @fires cancel\n\t */ cancel() {\n        this._cleanup();\n    }\n    /**\n\t * Destroys the resizer.\n\t */ destroy() {\n        this.cancel();\n    }\n    /**\n\t * Redraws the resizer.\n\t *\n\t * @param handleHostRect Handle host rectangle might be given to improve performance.\n\t */ redraw(handleHostRect) {\n        const domWrapper = this._domResizerWrapper;\n        // Refresh only if resizer exists in the DOM.\n        if (!existsInDom(domWrapper)) {\n            return;\n        }\n        const widgetWrapper = domWrapper.parentElement;\n        const handleHost = this._getHandleHost();\n        const resizerWrapper = this._viewResizerWrapper;\n        const currentDimensions = [\n            resizerWrapper.getStyle('width'),\n            resizerWrapper.getStyle('height'),\n            resizerWrapper.getStyle('left'),\n            resizerWrapper.getStyle('top')\n        ];\n        let newDimensions;\n        if (widgetWrapper.isSameNode(handleHost)) {\n            const clientRect = handleHostRect || new Rect(handleHost);\n            newDimensions = [\n                clientRect.width + 'px',\n                clientRect.height + 'px',\n                undefined,\n                undefined\n            ];\n        } else {\n            newDimensions = [\n                handleHost.offsetWidth + 'px',\n                handleHost.offsetHeight + 'px',\n                handleHost.offsetLeft + 'px',\n                handleHost.offsetTop + 'px'\n            ];\n        }\n        // Make changes to the view only if the resizer should actually get new dimensions.\n        // Otherwise, if View#change() was always called, this would cause EditorUI#update\n        // loops because the WidgetResize plugin listens to EditorUI#update and updates\n        // the resizer.\n        // https://github.com/ckeditor/ckeditor5/issues/7633\n        if (compareArrays(currentDimensions, newDimensions) !== 'same') {\n            this._options.editor.editing.view.change((writer)=>{\n                writer.setStyle({\n                    width: newDimensions[0],\n                    height: newDimensions[1],\n                    left: newDimensions[2],\n                    top: newDimensions[3]\n                }, resizerWrapper);\n            });\n        }\n    }\n    containsHandle(domElement) {\n        return this._domResizerWrapper.contains(domElement);\n    }\n    static isResizeHandle(domElement) {\n        return domElement.classList.contains('ck-widget__resizer__handle');\n    }\n    /**\n\t * Cleans up the context state.\n\t */ _cleanup() {\n        this._sizeView._dismiss();\n        const editingView = this._options.editor.editing.view;\n        editingView.change((writer)=>{\n            writer.setStyle('width', this._initialViewWidth, this._options.viewElement);\n        });\n    }\n    /**\n\t * Calculates the proposed size as the resize handles are dragged.\n\t *\n\t * @param domEventData Event data that caused the size update request. It should be used to calculate the proposed size.\n\t */ _proposeNewSize(domEventData) {\n        const state = this.state;\n        const currentCoordinates = extractCoordinates(domEventData);\n        const isCentered = this._options.isCentered ? this._options.isCentered(this) : true;\n        // Enlargement defines how much the resize host has changed in a given axis. Naturally it could be a negative number\n        // meaning that it has been shrunk.\n        //\n        // +----------------+--+\n        // |                |  |\n        // |       img      |  |\n        // |  /handle host  |  |\n        // +----------------+  | ^\n        // |                   | | - enlarge y\n        // +-------------------+ v\n        // \t\t\t\t\t<-->\n        // \t\t\t\t\t enlarge x\n        const enlargement = {\n            x: state._referenceCoordinates.x - (currentCoordinates.x + state.originalWidth),\n            y: currentCoordinates.y - state.originalHeight - state._referenceCoordinates.y\n        };\n        if (isCentered && state.activeHandlePosition.endsWith('-right')) {\n            enlargement.x = currentCoordinates.x - (state._referenceCoordinates.x + state.originalWidth);\n        }\n        // Objects needs to be resized twice as much in horizontal axis if centered, since enlargement is counted from\n        // one resized corner to your cursor. It needs to be duplicated to compensate for the other side too.\n        if (isCentered) {\n            enlargement.x *= 2;\n        }\n        // const resizeHost = this._getResizeHost();\n        // The size proposed by the user. It does not consider the aspect ratio.\n        let width = Math.abs(state.originalWidth + enlargement.x);\n        let height = Math.abs(state.originalHeight + enlargement.y);\n        // Dominant determination must take the ratio into account.\n        const dominant = width / state.aspectRatio > height ? 'width' : 'height';\n        if (dominant == 'width') {\n            height = width / state.aspectRatio;\n        } else {\n            width = height * state.aspectRatio;\n        }\n        return {\n            width: Math.round(width),\n            height: Math.round(height),\n            widthPercents: Math.min(Math.round(state.originalWidthPercents / state.originalWidth * width * 100) / 100, 100)\n        };\n    }\n    /**\n\t * Obtains the resize host.\n\t *\n\t * Resize host is an object that receives dimensions which are the result of resizing.\n\t */ _getResizeHost() {\n        const widgetWrapper = this._domResizerWrapper.parentElement;\n        return this._options.getResizeHost(widgetWrapper);\n    }\n    /**\n\t * Obtains the handle host.\n\t *\n\t * Handle host is an object that the handles are aligned to.\n\t *\n\t * Handle host will not always be an entire widget itself. Take an image as an example. The image widget\n\t * contains an image and a caption. Only the image should be surrounded with handles.\n\t */ _getHandleHost() {\n        const widgetWrapper = this._domResizerWrapper.parentElement;\n        return this._options.getHandleHost(widgetWrapper);\n    }\n    /**\n\t * DOM container of the entire resize UI.\n\t *\n\t * Note that this property will have a value only after the element bound with the resizer is rendered\n\t * (otherwise `null`).\n\t */ get _domResizerWrapper() {\n        return this._options.editor.editing.view.domConverter.mapViewToDom(this._viewResizerWrapper);\n    }\n    /**\n\t * Renders the resize handles in the DOM.\n\t *\n\t * @param domElement The resizer wrapper.\n\t */ _appendHandles(domElement) {\n        const resizerPositions = [\n            'top-left',\n            'top-right',\n            'bottom-right',\n            'bottom-left'\n        ];\n        for (const currentPosition of resizerPositions){\n            domElement.appendChild(new Template({\n                tag: 'div',\n                attributes: {\n                    class: `ck-widget__resizer__handle ${getResizerClass(currentPosition)}`\n                }\n            }).render());\n        }\n    }\n    /**\n\t * Sets up the {@link #_sizeView} property and adds it to the passed `domElement`.\n\t */ _appendSizeUI(domElement) {\n        this._sizeView = new SizeView();\n        // Make sure icon#element is rendered before passing to appendChild().\n        this._sizeView.render();\n        domElement.appendChild(this._sizeView.element);\n    }\n}\n/**\n * @param resizerPosition Expected resizer position like `\"top-left\"`, `\"bottom-right\"`.\n * @returns A prefixed HTML class name for the resizer element\n */ function getResizerClass(resizerPosition) {\n    return `ck-widget__resizer__handle-${resizerPosition}`;\n}\nfunction extractCoordinates(event) {\n    return {\n        x: event.pageX,\n        y: event.pageY\n    };\n}\nfunction existsInDom(element) {\n    return element && element.ownerDocument && element.ownerDocument.contains(element);\n}\n\n/**\n * The widget resize feature plugin.\n *\n * Use the {@link module:widget/widgetresize~WidgetResize#attachTo} method to create a resizer for the specified widget.\n */ class WidgetResize extends Plugin {\n    /**\n\t * A map of resizers created using this plugin instance.\n\t */ _resizers = new Map();\n    _observer;\n    _redrawSelectedResizerThrottled;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'WidgetResize';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editing = this.editor.editing;\n        const domDocument = global.window.document;\n        this.set('selectedResizer', null);\n        this.set('_activeResizer', null);\n        editing.view.addObserver(MouseObserver);\n        this._observer = new (DomEmitterMixin())();\n        this.listenTo(editing.view.document, 'mousedown', this._mouseDownListener.bind(this), {\n            priority: 'high'\n        });\n        this._observer.listenTo(domDocument, 'mousemove', this._mouseMoveListener.bind(this));\n        this._observer.listenTo(domDocument, 'mouseup', this._mouseUpListener.bind(this));\n        this._redrawSelectedResizerThrottled = throttle(()=>this.redrawSelectedResizer(), 200);\n        // Redrawing on any change of the UI of the editor (including content changes).\n        this.editor.ui.on('update', this._redrawSelectedResizerThrottled);\n        // Remove view widget-resizer mappings for widgets that have been removed from the document.\n        // https://github.com/ckeditor/ckeditor5/issues/10156\n        // https://github.com/ckeditor/ckeditor5/issues/10266\n        this.editor.model.document.on('change', ()=>{\n            for (const [viewElement, resizer] of this._resizers){\n                if (!viewElement.isAttached()) {\n                    this._resizers.delete(viewElement);\n                    resizer.destroy();\n                }\n            }\n        }, {\n            priority: 'lowest'\n        });\n        // Resizers need to be redrawn upon window resize, because new window might shrink resize host.\n        this._observer.listenTo(global.window, 'resize', this._redrawSelectedResizerThrottled);\n        const viewSelection = this.editor.editing.view.document.selection;\n        viewSelection.on('change', ()=>{\n            const selectedElement = viewSelection.getSelectedElement();\n            const resizer = this.getResizerByViewElement(selectedElement) || null;\n            if (resizer) {\n                this.select(resizer);\n            } else {\n                this.deselect();\n            }\n        });\n    }\n    /**\n\t * Redraws the selected resizer if there is any selected resizer and if it is visible.\n\t */ redrawSelectedResizer() {\n        if (this.selectedResizer && this.selectedResizer.isVisible) {\n            this.selectedResizer.redraw();\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this._observer.stopListening();\n        for (const resizer of this._resizers.values()){\n            resizer.destroy();\n        }\n        this._redrawSelectedResizerThrottled.cancel();\n    }\n    /**\n\t * Marks resizer as selected.\n\t */ select(resizer) {\n        this.deselect();\n        this.selectedResizer = resizer;\n        this.selectedResizer.isSelected = true;\n    }\n    /**\n\t * Deselects currently set resizer.\n\t */ deselect() {\n        if (this.selectedResizer) {\n            this.selectedResizer.isSelected = false;\n        }\n        this.selectedResizer = null;\n    }\n    /**\n\t * @param options Resizer options.\n\t */ attachTo(options) {\n        const resizer = new Resizer(options);\n        const plugins = this.editor.plugins;\n        resizer.attach();\n        if (plugins.has('WidgetToolbarRepository')) {\n            // Hiding widget toolbar to improve the performance\n            // (https://github.com/ckeditor/ckeditor5-widget/pull/112#issuecomment-564528765).\n            const widgetToolbarRepository = plugins.get('WidgetToolbarRepository');\n            resizer.on('begin', ()=>{\n                widgetToolbarRepository.forceDisabled('resize');\n            }, {\n                priority: 'lowest'\n            });\n            resizer.on('cancel', ()=>{\n                widgetToolbarRepository.clearForceDisabled('resize');\n            }, {\n                priority: 'highest'\n            });\n            resizer.on('commit', ()=>{\n                widgetToolbarRepository.clearForceDisabled('resize');\n            }, {\n                priority: 'highest'\n            });\n        }\n        this._resizers.set(options.viewElement, resizer);\n        const viewSelection = this.editor.editing.view.document.selection;\n        const selectedElement = viewSelection.getSelectedElement();\n        // If the element the resizer is created for is currently focused, it should become visible.\n        if (this.getResizerByViewElement(selectedElement) == resizer) {\n            this.select(resizer);\n        }\n        return resizer;\n    }\n    /**\n\t * Returns a resizer created for a given view element (widget element).\n\t *\n\t * @param viewElement View element associated with the resizer.\n\t */ getResizerByViewElement(viewElement) {\n        return this._resizers.get(viewElement);\n    }\n    /**\n\t * Returns a resizer that contains a given resize handle.\n\t */ _getResizerByHandle(domResizeHandle) {\n        for (const resizer of this._resizers.values()){\n            if (resizer.containsHandle(domResizeHandle)) {\n                return resizer;\n            }\n        }\n    }\n    /**\n\t * @param domEventData Native DOM event.\n\t */ _mouseDownListener(event, domEventData) {\n        const resizeHandle = domEventData.domTarget;\n        if (!Resizer.isResizeHandle(resizeHandle)) {\n            return;\n        }\n        this._activeResizer = this._getResizerByHandle(resizeHandle) || null;\n        if (this._activeResizer) {\n            this._activeResizer.begin(resizeHandle);\n            // Do not call other events when resizing. See: #6755.\n            event.stop();\n            domEventData.preventDefault();\n        }\n    }\n    /**\n\t * @param domEventData Native DOM event.\n\t */ _mouseMoveListener(event, domEventData) {\n        if (this._activeResizer) {\n            this._activeResizer.updateSize(domEventData);\n        }\n    }\n    _mouseUpListener() {\n        if (this._activeResizer) {\n            this._activeResizer.commit();\n            this._activeResizer = null;\n        }\n    }\n}\n\nexport { WIDGET_CLASS_NAME, WIDGET_SELECTED_CLASS_NAME, Widget, WidgetResize, WidgetToolbarRepository, WidgetTypeAround, calculateResizeHostAncestorWidth, calculateResizeHostPercentageWidth, findOptimalInsertionRange, getLabel, isWidget, setHighlightHandling, setLabel, toWidget, toWidgetEditable, viewToModelPositionOutsideModelElement };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/highlightstack\n */\n\nimport { EmitterMixin, type ArrayOrItem } from '@ckeditor/ckeditor5-utils';\n\nimport type { DowncastWriter, HighlightDescriptor } from '@ckeditor/ckeditor5-engine';\n\n/**\n * Class used to handle the correct order of highlights on elements.\n *\n * When different highlights are applied to same element the correct order should be preserved:\n *\n * * highlight with highest priority should be applied,\n * * if two highlights have same priority - sort by CSS class provided in\n * {@link module:engine/conversion/downcasthelpers~HighlightDescriptor}.\n *\n * This way, highlight will be applied with the same rules it is applied on texts.\n */\nexport default class HighlightStack extends /* #__PURE__ */ EmitterMixin() {\n\tprivate readonly _stack: Array<HighlightDescriptor> = [];\n\n\t/**\n\t * Adds highlight descriptor to the stack.\n\t *\n\t * @fires change:top\n\t */\n\tpublic add( descriptor: HighlightDescriptor, writer: DowncastWriter ): void {\n\t\tconst stack = this._stack;\n\n\t\t// Save top descriptor and insert new one. If top is changed - fire event.\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._insertDescriptor( descriptor );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire<HighlightStackChangeEvent>( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop,\n\t\t\t\twriter\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Removes highlight descriptor from the stack.\n\t *\n\t * @fires change:top\n\t * @param id Id of the descriptor to remove.\n\t */\n\tpublic remove( id: string, writer: DowncastWriter ): void {\n\t\tconst stack = this._stack;\n\n\t\tconst oldTop = stack[ 0 ];\n\t\tthis._removeDescriptor( id );\n\t\tconst newTop = stack[ 0 ];\n\n\t\t// When new object is at the top and stores different information.\n\t\tif ( oldTop !== newTop && !compareDescriptors( oldTop, newTop ) ) {\n\t\t\tthis.fire<HighlightStackChangeEvent>( 'change:top', {\n\t\t\t\toldDescriptor: oldTop,\n\t\t\t\tnewDescriptor: newTop,\n\t\t\t\twriter\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Inserts a given descriptor in correct place in the stack. It also takes care about updating information\n\t * when descriptor with same id is already present.\n\t */\n\tprivate _insertDescriptor( descriptor: HighlightDescriptor ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === descriptor.id );\n\n\t\t// Inserting exact same descriptor - do nothing.\n\t\tif ( compareDescriptors( descriptor, stack[ index ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If descriptor with same id but with different information is on the stack - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\n\t\t// Find correct place to insert descriptor in the stack.\n\t\t// It has different information (for example priority) so it must be re-inserted in correct place.\n\t\tlet i = 0;\n\n\t\twhile ( stack[ i ] && shouldABeBeforeB( stack[ i ], descriptor ) ) {\n\t\t\ti++;\n\t\t}\n\n\t\tstack.splice( i, 0, descriptor );\n\t}\n\n\t/**\n\t * Removes descriptor with given id from the stack.\n\t *\n\t * @param id Descriptor's id.\n\t */\n\tprivate _removeDescriptor( id: string ) {\n\t\tconst stack = this._stack;\n\t\tconst index = stack.findIndex( item => item.id === id );\n\n\t\t// If descriptor with same id is on the list - remove it.\n\t\tif ( index > -1 ) {\n\t\t\tstack.splice( index, 1 );\n\t\t}\n\t}\n}\n\n/**\n * Compares two descriptors by checking their priority and class list.\n *\n * @returns Returns true if both descriptors are defined and have same priority and classes.\n */\nfunction compareDescriptors( a: HighlightDescriptor, b: HighlightDescriptor ) {\n\treturn a && b && a.priority == b.priority && classesToString( a.classes ) == classesToString( b.classes );\n}\n\n/**\n * Checks whenever first descriptor should be placed in the stack before second one.\n */\nfunction shouldABeBeforeB( a: HighlightDescriptor, b: HighlightDescriptor ) {\n\tif ( a.priority! > b.priority! ) {\n\t\treturn true;\n\t} else if ( a.priority! < b.priority! ) {\n\t\treturn false;\n\t}\n\n\t// When priorities are equal and names are different - use classes to compare.\n\treturn classesToString( a.classes ) > classesToString( b.classes );\n}\n\n/**\n * Converts CSS classes passed with {@link module:engine/conversion/downcasthelpers~HighlightDescriptor} to\n * sorted string.\n */\nfunction classesToString( classes: ArrayOrItem<string> ) {\n\treturn Array.isArray( classes ) ? classes.sort().join( ',' ) : classes;\n}\n\n/**\n * Fired when top element on {@link module:widget/highlightstack~HighlightStack} has been changed\n *\n * @eventName ~HighlightStack#change:top\n */\nexport type HighlightStackChangeEvent = {\n\tname: 'change' | 'change:top';\n\targs: [ HighlightStackChangeEventData ];\n};\n\n/**\n * Additional information about the change.\n */\nexport type HighlightStackChangeEventData = {\n\n\t/**\n\t * Old highlight descriptor. It will be `undefined` when first descriptor is added to the stack.\n\t */\n\toldDescriptor: HighlightDescriptor;\n\n\t/**\n\t * New highlight descriptor. It will be `undefined` when last descriptor is removed from the stack.\n\t */\n\tnewDescriptor: HighlightDescriptor;\n\n\t/**\n\t * View writer that can be used to modify element.\n\t */\n\twriter: DowncastWriter;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/utils\n */\n\nimport {\n\tRect,\n\tCKEditorError,\n\ttoArray,\n\ttype ObservableChangeEvent,\n\ttype GetCallback\n} from '@ckeditor/ckeditor5-utils';\n\nimport {\n\ttype AddHighlightCallback,\n\ttype HighlightDescriptor,\n\ttype RemoveHighlightCallback,\n\ttype MapperViewToModelPositionEvent,\n\ttype DocumentSelection,\n\ttype DowncastWriter,\n\ttype Model,\n\ttype Range,\n\ttype Selection,\n\ttype ViewContainerElement,\n\ttype ViewEditableElement,\n\ttype ViewElement,\n\ttype ViewTypeCheckable\n} from '@ckeditor/ckeditor5-engine';\n\nimport { IconView } from '@ckeditor/ckeditor5-ui';\n\nimport HighlightStack, { type HighlightStackChangeEvent } from './highlightstack.js';\nimport { getTypeAroundFakeCaretPosition } from './widgettypearound/utils.js';\n\nimport dragHandleIcon from '../theme/icons/drag-handle.svg';\n\n/**\n * CSS class added to each widget element.\n */\nexport const WIDGET_CLASS_NAME = 'ck-widget';\n\n/**\n * CSS class added to currently selected widget element.\n */\nexport const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';\n\n/**\n * Returns `true` if given {@link module:engine/view/node~Node} is an {@link module:engine/view/element~Element} and a widget.\n */\nexport function isWidget( node: ViewTypeCheckable ): boolean {\n\tif ( !node.is( 'element' ) ) {\n\t\treturn false;\n\t}\n\n\treturn !!node.getCustomProperty( 'widget' );\n}\n\n/**\n * Converts the given {@link module:engine/view/element~Element} to a widget in the following way:\n *\n * * sets the `contenteditable` attribute to `\"false\"`,\n * * adds the `ck-widget` CSS class,\n * * adds a custom {@link module:engine/view/element~Element#getFillerOffset `getFillerOffset()`} method returning `null`,\n * * adds a custom property allowing to recognize widget elements by using {@link ~isWidget `isWidget()`},\n * * implements the {@link ~setHighlightHandling view highlight on widgets}.\n *\n * This function needs to be used in conjunction with\n * {@link module:engine/conversion/downcasthelpers~DowncastHelpers downcast conversion helpers}\n * like {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n * Moreover, typically you will want to use `toWidget()` only for `editingDowncast`, while keeping the `dataDowncast` clean.\n *\n * For example, in order to convert a `<widget>` model element to `<div class=\"widget\">` in the view, you can define\n * such converters:\n *\n * ```ts\n * editor.conversion.for( 'editingDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'widget',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\tconst div = writer.createContainerElement( 'div', { class: 'widget' } );\n *\n * \t\t\treturn toWidget( div, writer, { label: 'some widget' } );\n * \t\t}\n * \t} );\n *\n * editor.conversion.for( 'dataDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'widget',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\treturn writer.createContainerElement( 'div', { class: 'widget' } );\n * \t\t}\n * \t} );\n * ```\n *\n * See the full source code of the widget (with a nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param options Additional options.\n * @param options.label Element's label provided to the {@link ~setLabel} function. It can be passed as\n * a plain string or a function returning a string. It represents the widget for assistive technologies (like screen readers).\n * @param options.hasSelectionHandle If `true`, the widget will have a selection handle added.\n * @returns Returns the same element.\n */\nexport function toWidget(\n\telement: ViewElement,\n\twriter: DowncastWriter,\n\toptions: {\n\t\tlabel?: string | ( () => string );\n\t\thasSelectionHandle?: boolean;\n\t} = {}\n): ViewElement {\n\tif ( !element.is( 'containerElement' ) ) {\n\t\t/**\n\t\t * The element passed to `toWidget()` must be a {@link module:engine/view/containerelement~ContainerElement}\n\t\t * instance.\n\t\t *\n\t\t * @error widget-to-widget-wrong-element-type\n\t\t * @param element The view element passed to `toWidget()`.\n\t\t */\n\t\tthrow new CKEditorError(\n\t\t\t'widget-to-widget-wrong-element-type',\n\t\t\tnull,\n\t\t\t{ element }\n\t\t);\n\t}\n\n\twriter.setAttribute( 'contenteditable', 'false', element );\n\n\twriter.addClass( WIDGET_CLASS_NAME, element );\n\twriter.setCustomProperty( 'widget', true, element );\n\telement.getFillerOffset = getFillerOffset;\n\n\twriter.setCustomProperty( 'widgetLabel', [], element );\n\n\tif ( options.label ) {\n\t\tsetLabel( element, options.label );\n\t}\n\n\tif ( options.hasSelectionHandle ) {\n\t\taddSelectionHandle( element, writer );\n\t}\n\n\tsetHighlightHandling( element, writer );\n\n\treturn element;\n}\n\n/**\n * Default handler for adding a highlight on a widget.\n * It adds CSS class and attributes basing on the given highlight descriptor.\n */\nfunction addHighlight( element: ViewElement, descriptor: HighlightDescriptor, writer: DowncastWriter ) {\n\tif ( descriptor.classes ) {\n\t\twriter.addClass( toArray( descriptor.classes ), element );\n\t}\n\n\tif ( descriptor.attributes ) {\n\t\tfor ( const key in descriptor.attributes ) {\n\t\t\twriter.setAttribute( key, descriptor.attributes[ key ], element );\n\t\t}\n\t}\n}\n\n/**\n * Default handler for removing a highlight from a widget.\n * It removes CSS class and attributes basing on the given highlight descriptor.\n */\nfunction removeHighlight( element: ViewElement, descriptor: HighlightDescriptor, writer: DowncastWriter ) {\n\tif ( descriptor.classes ) {\n\t\twriter.removeClass( toArray( descriptor.classes ), element );\n\t}\n\n\tif ( descriptor.attributes ) {\n\t\tfor ( const key in descriptor.attributes ) {\n\t\t\twriter.removeAttribute( key, element );\n\t\t}\n\t}\n}\n\n/**\n * Sets highlight handling methods. Uses {@link module:widget/highlightstack~HighlightStack} to\n * properly determine which highlight descriptor should be used at given time.\n */\nexport function setHighlightHandling(\n\telement: ViewElement,\n\twriter: DowncastWriter,\n\tadd: ( element: ViewElement, descriptor: HighlightDescriptor, writer: DowncastWriter ) => void = addHighlight,\n\tremove: ( element: ViewElement, descriptor: HighlightDescriptor, writer: DowncastWriter ) => void = removeHighlight\n): void {\n\tconst stack = new HighlightStack();\n\n\tstack.on<HighlightStackChangeEvent>( 'change:top', ( evt, data ) => {\n\t\tif ( data.oldDescriptor ) {\n\t\t\tremove( element, data.oldDescriptor, data.writer );\n\t\t}\n\n\t\tif ( data.newDescriptor ) {\n\t\t\tadd( element, data.newDescriptor, data.writer );\n\t\t}\n\t} );\n\n\tconst addHighlightCallback: AddHighlightCallback = ( element, descriptor, writer ) => stack.add( descriptor, writer );\n\tconst removeHighlightCallback: RemoveHighlightCallback = ( element, id, writer ) => stack.remove( id, writer );\n\n\twriter.setCustomProperty( 'addHighlight', addHighlightCallback, element );\n\twriter.setCustomProperty( 'removeHighlight', removeHighlightCallback, element );\n}\n\n/**\n * Sets label for given element.\n * It can be passed as a plain string or a function returning a string. Function will be called each time label is retrieved by\n * {@link ~getLabel `getLabel()`}.\n */\nexport function setLabel( element: ViewElement, labelOrCreator: string | ( () => string ) ): void {\n\tconst widgetLabel = element.getCustomProperty( 'widgetLabel' ) as Array<string | ( () => string )>;\n\n\twidgetLabel.push( labelOrCreator );\n}\n\n/**\n * Returns the label of the provided element.\n */\nexport function getLabel( element: ViewElement ): string {\n\tconst widgetLabel = element.getCustomProperty( 'widgetLabel' ) as Array<string | ( () => string )>;\n\n\treturn widgetLabel.reduce( ( prev: string, current: string | ( () => string ) ) => {\n\t\tif ( typeof current === 'function' ) {\n\t\t\treturn prev ? prev + '. ' + current() : current();\n\t\t} else {\n\t\t\treturn prev ? prev + '. ' + current : current;\n\t\t}\n\t}, '' );\n}\n\n/**\n * Adds functionality to the provided {@link module:engine/view/editableelement~EditableElement} to act as a widget's editable:\n *\n * * sets the `contenteditable` attribute to `true` when {@link module:engine/view/editableelement~EditableElement#isReadOnly} is `false`,\n * otherwise sets it to `false`,\n * * adds the `ck-editor__editable` and `ck-editor__nested-editable` CSS classes,\n * * adds the `ck-editor__nested-editable_focused` CSS class when the editable is focused and removes it when it is blurred.\n * * implements the {@link ~setHighlightHandling view highlight on widget's editable}.\n *\n * Similarly to {@link ~toWidget `toWidget()`} this function should be used in `editingDowncast` only and it is usually\n * used together with {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`}.\n *\n * For example, in order to convert a `<nested>` model element to `<div class=\"nested\">` in the view, you can define\n * such converters:\n *\n * ```ts\n * editor.conversion.for( 'editingDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'nested',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\tconst div = writer.createEditableElement( 'div', { class: 'nested' } );\n *\n * \t\t\treturn toWidgetEditable( nested, writer, { label: 'label for editable' } );\n * \t\t}\n * \t} );\n *\n * editor.conversion.for( 'dataDowncast' )\n * \t.elementToElement( {\n * \t\tmodel: 'nested',\n * \t\tview: ( modelItem, { writer } ) => {\n * \t\t\treturn writer.createContainerElement( 'div', { class: 'nested' } );\n * \t\t}\n * \t} );\n * ```\n *\n * See the full source code of the widget (with nested editable) schema definition and converters in\n * [this sample](https://github.com/ckeditor/ckeditor5-widget/blob/master/tests/manual/widget-with-nestededitable.js).\n *\n * @param options Additional options.\n * @param options.label Editable's label used by assistive technologies (e.g. screen readers).\n * @returns Returns the same element that was provided in the `editable` parameter\n */\nexport function toWidgetEditable(\n\teditable: ViewEditableElement,\n\twriter: DowncastWriter,\n\toptions: {\n\t\tlabel?: string;\n\t} = {}\n): ViewEditableElement {\n\twriter.addClass( [ 'ck-editor__editable', 'ck-editor__nested-editable' ], editable );\n\n\twriter.setAttribute( 'role', 'textbox', editable );\n\twriter.setAttribute( 'tabindex', '-1', editable );\n\n\tif ( options.label ) {\n\t\twriter.setAttribute( 'aria-label', options.label, editable );\n\t}\n\n\t// Set initial contenteditable value.\n\twriter.setAttribute( 'contenteditable', editable.isReadOnly ? 'false' : 'true', editable );\n\n\t// Bind the contenteditable property to element#isReadOnly.\n\teditable.on<ObservableChangeEvent<boolean>>( 'change:isReadOnly', ( evt, property, is ) => {\n\t\twriter.setAttribute( 'contenteditable', is ? 'false' : 'true', editable );\n\t} );\n\n\teditable.on<ObservableChangeEvent<boolean>>( 'change:isFocused', ( evt, property, is ) => {\n\t\tif ( is ) {\n\t\t\twriter.addClass( 'ck-editor__nested-editable_focused', editable );\n\t\t} else {\n\t\t\twriter.removeClass( 'ck-editor__nested-editable_focused', editable );\n\t\t}\n\t} );\n\n\tsetHighlightHandling( editable, writer );\n\n\treturn editable;\n}\n\n/**\n * Returns a model range which is optimal (in terms of UX) for inserting a widget block.\n *\n * For instance, if a selection is in the middle of a paragraph, the collapsed range before this paragraph\n * will be returned so that it is not split. If the selection is at the end of a paragraph,\n * the collapsed range after this paragraph will be returned.\n *\n * Note: If the selection is placed in an empty block, the range in that block will be returned. If that range\n * is then passed to {@link module:engine/model/model~Model#insertContent}, the block will be fully replaced\n * by the inserted widget block.\n *\n * @param selection The selection based on which the insertion position should be calculated.\n * @param model Model instance.\n * @returns The optimal range.\n */\nexport function findOptimalInsertionRange(\n\tselection: Selection | DocumentSelection,\n\tmodel: Model\n): Range {\n\tconst selectedElement = selection.getSelectedElement();\n\n\tif ( selectedElement ) {\n\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( selection );\n\n\t\t// If the WidgetTypeAround \"fake caret\" is displayed, use its position for the insertion\n\t\t// to provide the most predictable UX (https://github.com/ckeditor/ckeditor5/issues/7438).\n\t\tif ( typeAroundFakeCaretPosition ) {\n\t\t\treturn model.createRange( model.createPositionAt( selectedElement, typeAroundFakeCaretPosition ) );\n\t\t}\n\t}\n\n\treturn model.schema.findOptimalInsertionRange( selection );\n}\n\n/**\n * A util to be used in order to map view positions to correct model positions when implementing a widget\n * which renders non-empty view element for an empty model element.\n *\n * For example:\n *\n * ```\n * // Model:\n * <placeholder type=\"name\"></placeholder>\n *\n * // View:\n * <span class=\"placeholder\">name</span>\n * ```\n *\n * In such case, view positions inside `<span>` cannot be correctly mapped to the model (because the model element is empty).\n * To handle mapping positions inside `<span class=\"placeholder\">` to the model use this util as follows:\n *\n * ```ts\n * editor.editing.mapper.on(\n * \t'viewToModelPosition',\n * \tviewToModelPositionOutsideModelElement( model, viewElement => viewElement.hasClass( 'placeholder' ) )\n * );\n * ```\n *\n * The callback will try to map the view offset of selection to an expected model position.\n *\n * 1. When the position is at the end (or in the middle) of the inline widget:\n *\n * ```\n * // View:\n * <p>foo <span class=\"placeholder\">name|</span> bar</p>\n *\n * // Model:\n * <paragraph>foo <placeholder type=\"name\"></placeholder>| bar</paragraph>\n * ```\n *\n * 2. When the position is at the beginning of the inline widget:\n *\n * ```\n * // View:\n * <p>foo <span class=\"placeholder\">|name</span> bar</p>\n *\n * // Model:\n * <paragraph>foo |<placeholder type=\"name\"></placeholder> bar</paragraph>\n * ```\n *\n * @param model Model instance on which the callback operates.\n * @param viewElementMatcher Function that is passed a view element and should return `true` if the custom mapping\n * should be applied to the given view element.\n */\nexport function viewToModelPositionOutsideModelElement(\n\tmodel: Model,\n\tviewElementMatcher: ( element: ViewElement ) => boolean\n): GetCallback<MapperViewToModelPositionEvent> {\n\treturn ( evt, data ) => {\n\t\tconst { mapper, viewPosition } = data;\n\n\t\tconst viewParent = mapper.findMappedViewAncestor( viewPosition );\n\n\t\tif ( !viewElementMatcher( viewParent ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelParent = mapper.toModelElement( viewParent );\n\n\t\tdata.modelPosition = model.createPositionAt( modelParent!, viewPosition.isAtStart ? 'before' : 'after' );\n\t};\n}\n\n/**\n * Default filler offset function applied to all widget elements.\n */\nfunction getFillerOffset() {\n\treturn null;\n}\n\n/**\n * Adds a drag handle to the widget.\n */\nfunction addSelectionHandle( widgetElement: ViewContainerElement, writer: DowncastWriter ) {\n\tconst selectionHandle = writer.createUIElement( 'div', { class: 'ck ck-widget__selection-handle' }, function( domDocument ) {\n\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t// Use the IconView from the ui library.\n\t\tconst icon = new IconView();\n\t\ticon.set( 'content', dragHandleIcon );\n\n\t\t// Render the icon view right away to append its #element to the selectionHandle DOM element.\n\t\ticon.render();\n\n\t\tdomElement.appendChild( icon.element! );\n\n\t\treturn domElement;\n\t} );\n\n\t// Append the selection handle into the widget wrapper.\n\twriter.insert( writer.createPositionAt( widgetElement, 0 ), selectionHandle );\n\twriter.addClass( [ 'ck-widget_with-selection-handle' ], widgetElement );\n}\n\n/**\n * Starting from a DOM resize host element (an element that receives dimensions as a result of resizing),\n * this helper returns the width of the found ancestor element.\n *\n *\t* It searches up to 5 levels of ancestors only.\n *\n * @param domResizeHost Resize host DOM element that receives dimensions as a result of resizing.\n * @returns Width of ancestor element in pixels or 0 if no ancestor with a computed width has been found.\n */\nexport function calculateResizeHostAncestorWidth( domResizeHost: HTMLElement ): number {\n\tconst getElementComputedWidth = ( element: HTMLElement ) => {\n\t\tconst { width, paddingLeft, paddingRight } = element.ownerDocument.defaultView!.getComputedStyle( element! );\n\n\t\treturn parseFloat( width ) - ( parseFloat( paddingLeft ) || 0 ) - ( parseFloat( paddingRight ) || 0 );\n\t};\n\n\tconst domResizeHostParent = domResizeHost.parentElement;\n\n\tif ( !domResizeHostParent ) {\n\t\treturn 0;\n\t}\n\n\t// Need to use computed style as it properly excludes parent's paddings from the returned value.\n\tlet parentWidth = getElementComputedWidth( domResizeHostParent! );\n\n\t// Sometimes parent width cannot be accessed. If that happens we should go up in the elements tree\n\t// and try to get width from next ancestor.\n\t// https://github.com/ckeditor/ckeditor5/issues/10776\n\tconst ancestorLevelLimit = 5;\n\tlet currentLevel = 0;\n\n\tlet checkedElement = domResizeHostParent!;\n\n\twhile ( isNaN( parentWidth ) ) {\n\t\tcheckedElement = checkedElement.parentElement!;\n\n\t\tif ( ++currentLevel > ancestorLevelLimit ) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tparentWidth = getElementComputedWidth( checkedElement );\n\t}\n\n\treturn parentWidth;\n}\n\n/**\n * Calculates a relative width of a `domResizeHost` compared to its ancestor in percents.\n *\n * @param domResizeHost Resize host DOM element.\n * @returns Percentage value between 0 and 100.\n */\nexport function calculateResizeHostPercentageWidth(\n\tdomResizeHost: HTMLElement,\n\tresizeHostRect: Rect = new Rect( domResizeHost )\n): number {\n\tconst parentWidth = calculateResizeHostAncestorWidth( domResizeHost );\n\n\tif ( !parentWidth ) {\n\t\treturn 0;\n\t}\n\n\treturn resizeHostRect.width / parentWidth * 100;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/widgettypearound/utils\n */\n\nimport { isWidget } from '../utils.js';\n\nimport type {\n\tDocumentSelection,\n\tDomConverter,\n\tElement,\n\tSchema,\n\tSelection,\n\tViewElement\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * The name of the type around model selection attribute responsible for\n * displaying a fake caret next to a selected widget.\n */\nexport const TYPE_AROUND_SELECTION_ATTRIBUTE = 'widget-type-around';\n\n/**\n * Checks if an element is a widget that qualifies to get the widget type around UI.\n */\nexport function isTypeAroundWidget( viewElement: ViewElement | undefined, modelElement: Element, schema: Schema ): boolean {\n\treturn !!viewElement && isWidget( viewElement ) && !schema.isInline( modelElement );\n}\n\n/**\n * For the passed HTML element, this helper finds the closest widget type around button ancestor.\n */\nexport function getClosestTypeAroundDomButton( domElement: HTMLElement ): HTMLElement | null {\n\treturn domElement.closest( '.ck-widget__type-around__button' );\n}\n\n/**\n * For the passed widget type around button element, this helper determines at which position\n * the paragraph would be inserted into the content if, for instance, the button was\n * clicked by the user.\n *\n * @returns The position of the button.\n */\nexport function getTypeAroundButtonPosition( domElement: HTMLElement ): 'before' | 'after' {\n\treturn domElement.classList.contains( 'ck-widget__type-around__button_before' ) ? 'before' : 'after';\n}\n\n/**\n * For the passed HTML element, this helper returns the closest view widget ancestor.\n */\nexport function getClosestWidgetViewElement( domElement: HTMLElement, domConverter: DomConverter ): ViewElement {\n\tconst widgetDomElement = domElement.closest( '.ck-widget' );\n\n\treturn domConverter.mapDomToView( widgetDomElement as any ) as ViewElement;\n}\n\n/**\n * For the passed selection instance, it returns the position of the fake caret displayed next to a widget.\n *\n * **Note**: If the fake caret is not currently displayed, `null` is returned.\n *\n * @returns The position of the fake caret or `null` when none is present.\n */\nexport function getTypeAroundFakeCaretPosition( selection: Selection | DocumentSelection ): 'before' | 'after' | null {\n\treturn selection.getAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE ) as any;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/* global DOMParser */\n\n/**\n * @module widget/widgettypearound/widgettypearound\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport { Template } from '@ckeditor/ckeditor5-ui';\n\nimport {\n\tEnter,\n\ttype ViewDocumentEnterEvent\n} from '@ckeditor/ckeditor5-enter';\n\nimport {\n\tDelete,\n\ttype ViewDocumentDeleteEvent,\n\ttype ViewDocumentInsertTextEvent\n} from '@ckeditor/ckeditor5-typing';\n\nimport {\n\tenv,\n\tisForwardArrowKeyCode,\n\ttype BaseEvent,\n\ttype Emitter,\n\ttype GetCallback,\n\ttype GetCallbackOptions,\n\ttype ObservableChangeEvent,\n\ttype KeystrokeInfo\n} from '@ckeditor/ckeditor5-utils';\n\nimport type {\n\tBubblingEventInfo,\n\tDocumentChangeEvent,\n\tDomEventData,\n\tDowncastInsertEvent,\n\tDowncastSelectionEvent,\n\tDowncastWriter,\n\tElement,\n\tSchema,\n\tSelectionChangeRangeEvent,\n\tViewDocumentArrowKeyEvent,\n\tViewDocumentCompositionStartEvent,\n\tViewDocumentKeyDownEvent,\n\tViewDocumentMouseDownEvent,\n\tViewElement,\n\tModelDeleteContentEvent,\n\tModelInsertContentEvent,\n\tModelInsertObjectEvent\n} from '@ckeditor/ckeditor5-engine';\n\nimport {\n\tisTypeAroundWidget,\n\tgetClosestTypeAroundDomButton,\n\tgetTypeAroundButtonPosition,\n\tgetClosestWidgetViewElement,\n\tgetTypeAroundFakeCaretPosition,\n\tTYPE_AROUND_SELECTION_ATTRIBUTE\n} from './utils.js';\n\nimport { isWidget } from '../utils.js';\nimport type Widget from '../widget.js';\n\nimport returnIcon from '../../theme/icons/return-arrow.svg';\n\nimport '../../theme/widgettypearound.css';\n\nconst POSSIBLE_INSERTION_POSITIONS = [ 'before', 'after' ] as const;\n\n// Do the SVG parsing once and then clone the result <svg> DOM element for each new button.\nconst RETURN_ARROW_ICON_ELEMENT = new DOMParser().parseFromString( returnIcon, 'image/svg+xml' ).firstChild!;\n\nconst PLUGIN_DISABLED_EDITING_ROOT_CLASS = 'ck-widget__type-around_disabled';\n\n/**\n * A plugin that allows users to type around widgets where normally it is impossible to place the caret due\n * to limitations of web browsers. These \"tight spots\" occur, for instance, before (or after) a widget being\n * the first (or last) child of its parent or between two block widgets.\n *\n * This plugin extends the {@link module:widget/widget~Widget `Widget`} plugin and injects the user interface\n * with two buttons into each widget instance in the editor. Each of the buttons can be clicked by the\n * user if the widget is next to the \"tight spot\". Once clicked, a paragraph is created with the selection anchored\n * in it so that users can type (or insert content, paste, etc.) straight away.\n */\nexport default class WidgetTypeAround extends Plugin {\n\t/**\n\t * A reference to the model widget element that has the fake caret active\n\t * on either side of it. It is later used to remove CSS classes associated with the fake caret\n\t * when the widget no longer needs it.\n\t */\n\tprivate _currentFakeCaretModelElement: Element | null = null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'WidgetTypeAround' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Enter, Delete ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\n\t\t// Set a CSS class on the view editing root when the plugin is disabled so all the buttons\n\t\t// and lines visually disappear. All the interactions are disabled in individual plugin methods.\n\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:isEnabled', ( evt, data, isEnabled ) => {\n\t\t\teditingView.change( writer => {\n\t\t\t\tfor ( const root of editingView.document.roots ) {\n\t\t\t\t\tif ( isEnabled ) {\n\t\t\t\t\t\twriter.removeClass( PLUGIN_DISABLED_EDITING_ROOT_CLASS, root );\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.addClass( PLUGIN_DISABLED_EDITING_ROOT_CLASS, root );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tif ( !isEnabled ) {\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\twriter.removeSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tthis._enableTypeAroundUIInjection();\n\t\tthis._enableInsertingParagraphsOnButtonClick();\n\t\tthis._enableInsertingParagraphsOnEnterKeypress();\n\t\tthis._enableInsertingParagraphsOnTypingKeystroke();\n\t\tthis._enableTypeAroundFakeCaretActivationUsingKeyboardArrows();\n\t\tthis._enableDeleteIntegration();\n\t\tthis._enableInsertContentIntegration();\n\t\tthis._enableInsertObjectIntegration();\n\t\tthis._enableDeleteContentIntegration();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis._currentFakeCaretModelElement = null;\n\t}\n\n\t/**\n\t * Inserts a new paragraph next to a widget element with the selection anchored in it.\n\t *\n\t * **Note**: This method is heavily user-oriented and will both focus the editing view and scroll\n\t * the viewport to the selection in the inserted paragraph.\n\t *\n\t * @param widgetModelElement The model widget element next to which a paragraph is inserted.\n\t * @param position The position where the paragraph is inserted. Either `'before'` or `'after'` the widget.\n\t */\n\tprivate _insertParagraph( widgetModelElement: Element, position: 'before' | 'after' ) {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\n\t\tconst attributesToCopy = editor.model.schema.getAttributesWithProperty( widgetModelElement, 'copyOnReplace', true );\n\n\t\teditor.execute( 'insertParagraph', {\n\t\t\tposition: editor.model.createPositionAt( widgetModelElement, position ),\n\t\t\tattributes: attributesToCopy\n\t\t} );\n\n\t\teditingView.focus();\n\t\teditingView.scrollToTheSelection();\n\t}\n\n\t/**\n\t * A wrapper for the {@link module:utils/emittermixin~Emitter#listenTo} method that executes the callbacks only\n\t * when the plugin {@link #isEnabled is enabled}.\n\t *\n\t * @param emitter The object that fires the event.\n\t * @param event The name of the event.\n\t * @param callback The function to be called on event.\n\t * @param options Additional options.\n\t * @param options.priority The priority of this event callback. The higher the priority value the sooner\n\t * the callback will be fired. Events having the same priority are called in the order they were added.\n\t */\n\tprivate _listenToIfEnabled<TEvent extends BaseEvent>(\n\t\temitter: Emitter,\n\t\tevent: TEvent[ 'name' ],\n\t\tcallback: OmitThisParameter<GetCallback<TEvent>>,\n\t\toptions?: GetCallbackOptions<TEvent>\n\t): void {\n\t\tthis.listenTo( emitter, event, ( ...args ) => {\n\t\t\t// Do not respond if the plugin is disabled.\n\t\t\tif ( this.isEnabled ) {\n\t\t\t\tcallback( ...args );\n\t\t\t}\n\t\t}, options );\n\t}\n\n\t/**\n\t * Similar to {@link #_insertParagraph}, this method inserts a paragraph except that it\n\t * does not expect a position. Instead, it performs the insertion next to a selected widget\n\t * according to the `widget-type-around` model selection attribute value (fake caret position).\n\t *\n\t * Because this method requires the `widget-type-around` attribute to be set,\n\t * the insertion can only happen when the widget's fake caret is active (e.g. activated\n\t * using the keyboard).\n\t *\n\t * @returns Returns `true` when the paragraph was inserted (the attribute was present) and `false` otherwise.\n\t */\n\tprivate _insertParagraphAccordingToFakeCaretPosition() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst modelSelection = model.document.selection;\n\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( modelSelection );\n\n\t\tif ( !typeAroundFakeCaretPosition ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// @if CK_DEBUG_TYPING // if ( ( window as any ).logCKETyping ) {\n\t\t// @if CK_DEBUG_TYPING // \tconsole.info( '%c[WidgetTypeAround]%c Fake caret -> insert paragraph',\n\t\t// @if CK_DEBUG_TYPING // \t\t'font-weight: bold; color: green', ''\n\t\t// @if CK_DEBUG_TYPING // \t);\n\t\t// @if CK_DEBUG_TYPING // }\n\n\t\tconst selectedModelElement = modelSelection.getSelectedElement()!;\n\n\t\tthis._insertParagraph( selectedModelElement, typeAroundFakeCaretPosition );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Creates a listener in the editing conversion pipeline that injects the widget type around\n\t * UI into every single widget instance created in the editor.\n\t *\n\t * The UI is delivered as a {@link module:engine/view/uielement~UIElement}\n\t * wrapper which renders DOM buttons that users can use to insert paragraphs.\n\t */\n\tprivate _enableTypeAroundUIInjection() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst t = editor.locale.t;\n\t\tconst buttonTitles = {\n\t\t\tbefore: t( 'Insert paragraph before block' ),\n\t\t\tafter: t( 'Insert paragraph after block' )\n\t\t};\n\n\t\teditor.editing.downcastDispatcher.on<DowncastInsertEvent<Element>>( 'insert', ( evt, data, conversionApi ) => {\n\t\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item );\n\n\t\t\tif ( !viewElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Filter out non-widgets and inline widgets.\n\t\t\tif ( isTypeAroundWidget( viewElement, data.item, schema ) ) {\n\t\t\t\tinjectUIIntoWidget( conversionApi.writer, buttonTitles, viewElement! );\n\n\t\t\t\tconst widgetLabel = viewElement.getCustomProperty( 'widgetLabel' ) as Array<string | ( () => string )>;\n\n\t\t\t\twidgetLabel.push( () => {\n\t\t\t\t\treturn this.isEnabled ? t( 'Press Enter to type after or press Shift + Enter to type before the widget' ) : '';\n\t\t\t\t} );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Brings support for the fake caret that appears when either:\n\t *\n\t * * the selection moves to a widget from a position next to it using arrow keys,\n\t * * the arrow key is pressed when the widget is already selected.\n\t *\n\t * The fake caret lets the user know that they can start typing or just press\n\t * <kbd>Enter</kbd> to insert a paragraph at the position next to a widget as suggested by the fake caret.\n\t *\n\t * The fake caret disappears when the user changes the selection or the editor\n\t * gets blurred.\n\t *\n\t * The whole idea is as follows:\n\t *\n\t * 1. A user does one of the 2 scenarios described at the beginning.\n\t * 2. The \"keydown\" listener is executed and the decision is made whether to show or hide the fake caret.\n\t * 3. If it should show up, the `widget-type-around` model selection attribute is set indicating\n\t *    on which side of the widget it should appear.\n\t * 4. The selection dispatcher reacts to the selection attribute and sets CSS classes responsible for the\n\t *    fake caret on the view widget.\n\t * 5. If the fake caret should disappear, the selection attribute is removed and the dispatcher\n\t *    does the CSS class clean-up in the view.\n\t * 6. Additionally, `change:range` and `FocusTracker#isFocused` listeners also remove the selection\n\t *    attribute (the former also removes widget CSS classes).\n\t */\n\tprivate _enableTypeAroundFakeCaretActivationUsingKeyboardArrows() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst modelSelection = model.document.selection;\n\t\tconst schema = model.schema;\n\t\tconst editingView = editor.editing.view;\n\n\t\t// This is the main listener responsible for the fake caret.\n\t\t// Note: The priority must precede the default Widget class keydown handler (\"high\").\n\t\tthis._listenToIfEnabled<ViewDocumentArrowKeyEvent>( editingView.document, 'arrowKey', ( evt, domEventData ) => {\n\t\t\tthis._handleArrowKeyPress( evt, domEventData );\n\t\t}, { context: [ isWidget, '$text' ], priority: 'high' } );\n\n\t\t// This listener makes sure the widget type around selection attribute will be gone from the model\n\t\t// selection as soon as the model range changes. This attribute only makes sense when a widget is selected\n\t\t// (and the \"fake horizontal caret\" is visible) so whenever the range changes (e.g. selection moved somewhere else),\n\t\t// let's get rid of the attribute so that the selection downcast dispatcher isn't even bothered.\n\t\tthis._listenToIfEnabled<SelectionChangeRangeEvent>( modelSelection, 'change:range', ( evt, data ) => {\n\t\t\t// Do not reset the selection attribute when the change was indirect.\n\t\t\tif ( !data.directChange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get rid of the widget type around attribute of the selection on every change:range.\n\t\t\t// If the range changes, it means for sure, the user is no longer in the active (\"fake horizontal caret\") mode.\n\t\t\teditor.model.change( writer => {\n\t\t\t\twriter.removeSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );\n\t\t\t} );\n\t\t} );\n\n\t\t// Get rid of the widget type around attribute of the selection on every document change\n\t\t// that makes widget not selected any more (i.e. widget was removed).\n\t\tthis._listenToIfEnabled<DocumentChangeEvent>( model.document, 'change:data', () => {\n\t\t\tconst selectedModelElement = modelSelection.getSelectedElement();\n\n\t\t\tif ( selectedModelElement ) {\n\t\t\t\tconst selectedViewElement = editor.editing.mapper.toViewElement( selectedModelElement );\n\n\t\t\t\tif ( isTypeAroundWidget( selectedViewElement, selectedModelElement, schema ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\twriter.removeSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );\n\t\t\t} );\n\t\t} );\n\n\t\t// React to changes of the model selection attribute made by the arrow keys listener.\n\t\t// If the block widget is selected and the attribute changes, downcast the attribute to special\n\t\t// CSS classes associated with the active (\"fake horizontal caret\") mode of the widget.\n\t\tthis._listenToIfEnabled<DowncastSelectionEvent>( editor.editing.downcastDispatcher, 'selection', ( evt, data, conversionApi ) => {\n\t\t\tconst writer = conversionApi.writer;\n\n\t\t\tif ( this._currentFakeCaretModelElement ) {\n\t\t\t\tconst selectedViewElement = conversionApi.mapper.toViewElement( this._currentFakeCaretModelElement );\n\n\t\t\t\tif ( selectedViewElement ) {\n\t\t\t\t\t// Get rid of CSS classes associated with the active (\"fake horizontal caret\") mode from the view widget.\n\t\t\t\t\twriter.removeClass( POSSIBLE_INSERTION_POSITIONS.map( positionToWidgetCssClass ), selectedViewElement );\n\n\t\t\t\t\tthis._currentFakeCaretModelElement = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst selectedModelElement = data.selection.getSelectedElement();\n\n\t\t\tif ( !selectedModelElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedViewElement = conversionApi.mapper.toViewElement( selectedModelElement );\n\n\t\t\tif ( !isTypeAroundWidget( selectedViewElement, selectedModelElement, schema ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( data.selection );\n\n\t\t\tif ( !typeAroundFakeCaretPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\twriter.addClass( positionToWidgetCssClass( typeAroundFakeCaretPosition ), selectedViewElement! );\n\n\t\t\t// Remember the view widget that got the \"fake-caret\" CSS class. This class should be removed ASAP when the\n\t\t\t// selection changes\n\t\t\tthis._currentFakeCaretModelElement = selectedModelElement;\n\t\t} );\n\n\t\tthis._listenToIfEnabled<ObservableChangeEvent<boolean>>( editor.ui.focusTracker, 'change:isFocused', ( evt, name, isFocused ) => {\n\t\t\tif ( !isFocused ) {\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\twriter.removeSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tfunction positionToWidgetCssClass( position: 'before' | 'after' ) {\n\t\t\treturn `ck-widget_type-around_show-fake-caret_${ position }`;\n\t\t}\n\t}\n\n\t/**\n\t * A listener executed on each \"keydown\" in the view document, a part of\n\t * {@link #_enableTypeAroundFakeCaretActivationUsingKeyboardArrows}.\n\t *\n\t * It decides whether the arrow keypress should activate the fake caret or not (also whether it should\n\t * be deactivated).\n\t *\n\t * The fake caret activation is done by setting the `widget-type-around` model selection attribute\n\t * in this listener, and stopping and preventing the event that would normally be handled by the widget\n\t * plugin that is responsible for the regular keyboard navigation near/across all widgets (that\n\t * includes inline widgets, which are ignored by the widget type around plugin).\n\t */\n\tprivate _handleArrowKeyPress( evt: BubblingEventInfo<'arrowKey'>, domEventData: DomEventData & KeystrokeInfo ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst modelSelection = model.document.selection;\n\t\tconst schema = model.schema;\n\t\tconst editingView = editor.editing.view;\n\n\t\tconst keyCode = domEventData.keyCode;\n\t\tconst isForward = isForwardArrowKeyCode( keyCode, editor.locale.contentLanguageDirection );\n\t\tconst selectedViewElement = editingView.document.selection.getSelectedElement()!;\n\t\tconst selectedModelElement = editor.editing.mapper.toModelElement( selectedViewElement )!;\n\t\tlet shouldStopAndPreventDefault;\n\n\t\t// Handle keyboard navigation when a type-around-compatible widget is currently selected.\n\t\tif ( isTypeAroundWidget( selectedViewElement, selectedModelElement, schema ) ) {\n\t\t\tshouldStopAndPreventDefault = this._handleArrowKeyPressOnSelectedWidget( isForward );\n\t\t}\n\t\t// Handle keyboard arrow navigation when the selection is next to a type-around-compatible widget\n\t\t// and the widget is about to be selected.\n\t\telse if ( modelSelection.isCollapsed ) {\n\t\t\tshouldStopAndPreventDefault = this._handleArrowKeyPressWhenSelectionNextToAWidget( isForward );\n\t\t}\n\t\t// Handle collapsing a non-collapsed selection that is wider than on a single widget.\n\t\telse if ( !domEventData.shiftKey ) {\n\t\t\tshouldStopAndPreventDefault = this._handleArrowKeyPressWhenNonCollapsedSelection( isForward );\n\t\t}\n\n\t\tif ( shouldStopAndPreventDefault ) {\n\t\t\tdomEventData.preventDefault();\n\t\t\tevt.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles the keyboard navigation on \"keydown\" when a widget is currently selected and activates or deactivates\n\t * the fake caret for that widget, depending on the current value of the `widget-type-around` model\n\t * selection attribute and the direction of the pressed arrow key.\n\t *\n\t * @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement\n\t * as in {@link module:utils/keyboard~isForwardArrowKeyCode}.\n\t * @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should\n\t * process the event any further. Returns `false` otherwise.\n\t */\n\tprivate _handleArrowKeyPressOnSelectedWidget( isForward: boolean ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst modelSelection = model.document.selection;\n\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( modelSelection );\n\n\t\treturn model.change( writer => {\n\t\t\t// If the fake caret is displayed...\n\t\t\tif ( typeAroundFakeCaretPosition ) {\n\t\t\t\tconst isLeavingWidget = typeAroundFakeCaretPosition === ( isForward ? 'after' : 'before' );\n\n\t\t\t\t// If the keyboard arrow works against the value of the selection attribute...\n\t\t\t\t// then remove the selection attribute but prevent default DOM actions\n\t\t\t\t// and do not let the Widget plugin listener move the selection. This brings\n\t\t\t\t// the widget back to the state, for instance, like if was selected using the mouse.\n\t\t\t\t//\n\t\t\t\t// **Note**: If leaving the widget when the fake caret is active, then the default\n\t\t\t\t// Widget handler will change the selection and, in turn, this will automatically discard\n\t\t\t\t// the selection attribute.\n\t\t\t\tif ( !isLeavingWidget ) {\n\t\t\t\t\twriter.removeSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If the fake caret wasn't displayed, let's set it now according to the direction of the arrow\n\t\t\t// key press. This also means we cannot let the Widget plugin listener move the selection.\n\t\t\telse {\n\t\t\t\twriter.setSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE, isForward ? 'after' : 'before' );\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t} );\n\t}\n\n\t/**\n\t * Handles the keyboard navigation on \"keydown\" when **no** widget is selected but the selection is **directly** next\n\t * to one and upon the fake caret should become active for this widget upon arrow keypress\n\t * (AKA entering/selecting the widget).\n\t *\n\t * **Note**: This code mirrors the implementation from the widget plugin but also adds the selection attribute.\n\t * Unfortunately, there is no safe way to let the widget plugin do the selection part first and then just set the\n\t * selection attribute here in the widget type around plugin. This is why this code must duplicate some from the widget plugin.\n\t *\n\t * @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement\n\t * as in {@link module:utils/keyboard~isForwardArrowKeyCode}.\n\t * @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should\n\t * process the event any further. Returns `false` otherwise.\n\t */\n\tprivate _handleArrowKeyPressWhenSelectionNextToAWidget( isForward: boolean ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst schema = model.schema;\n\t\tconst widgetPlugin: Widget = editor.plugins.get( 'Widget' );\n\n\t\t// This is the widget the selection is about to be set on.\n\t\tconst modelElementNextToSelection = widgetPlugin._getObjectElementNextToSelection( isForward )!;\n\t\tconst viewElementNextToSelection = editor.editing.mapper.toViewElement( modelElementNextToSelection );\n\n\t\tif ( isTypeAroundWidget( viewElementNextToSelection, modelElementNextToSelection, schema ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twidgetPlugin._setSelectionOverElement( modelElementNextToSelection );\n\t\t\t\twriter.setSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE, isForward ? 'before' : 'after' );\n\t\t\t} );\n\n\t\t\t// The change() block above does the same job as the Widget plugin. The event can\n\t\t\t// be safely canceled.\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Handles the keyboard navigation on \"keydown\" when a widget is currently selected (together with some other content)\n\t * and the widget is the first or last element in the selection. It activates or deactivates the fake caret for that widget.\n\t *\n\t * @param isForward `true` when the pressed arrow key was responsible for the forward model selection movement\n\t * as in {@link module:utils/keyboard~isForwardArrowKeyCode}.\n\t * @returns Returns `true` when the keypress was handled and no other keydown listener of the editor should\n\t * process the event any further. Returns `false` otherwise.\n\t */\n\tprivate _handleArrowKeyPressWhenNonCollapsedSelection( isForward: boolean ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst schema = model.schema;\n\t\tconst mapper = editor.editing.mapper;\n\t\tconst modelSelection = model.document.selection;\n\n\t\tconst selectedModelNode = isForward ?\n\t\t\tmodelSelection.getLastPosition()!.nodeBefore :\n\t\t\tmodelSelection.getFirstPosition()!.nodeAfter;\n\n\t\tconst selectedViewNode = mapper.toViewElement( selectedModelNode as any );\n\n\t\t// There is a widget at the collapse position so collapse the selection to the fake caret on it.\n\t\tif ( isTypeAroundWidget( selectedViewNode, selectedModelNode as any, schema ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( selectedModelNode!, 'on' );\n\t\t\t\twriter.setSelectionAttribute( TYPE_AROUND_SELECTION_ATTRIBUTE, isForward ? 'after' : 'before' );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Registers a `mousedown` listener for the view document which intercepts events\n\t * coming from the widget type around UI, which happens when a user clicks one of the buttons\n\t * that insert a paragraph next to a widget.\n\t */\n\tprivate _enableInsertingParagraphsOnButtonClick() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\n\t\tthis._listenToIfEnabled<ViewDocumentMouseDownEvent>( editingView.document, 'mousedown', ( evt, domEventData ) => {\n\t\t\tconst button = getClosestTypeAroundDomButton( domEventData.domTarget );\n\n\t\t\tif ( !button ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst buttonPosition = getTypeAroundButtonPosition( button );\n\t\t\tconst widgetViewElement = getClosestWidgetViewElement( button, editingView.domConverter );\n\t\t\tconst widgetModelElement = editor.editing.mapper.toModelElement( widgetViewElement );\n\n\t\t\tthis._insertParagraph( widgetModelElement!, buttonPosition );\n\n\t\t\tdomEventData.preventDefault();\n\t\t\tevt.stop();\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the <kbd>Enter</kbd> key listener on the view document that allows the user to insert a paragraph\n\t * near the widget when either:\n\t *\n\t * * The fake caret was first activated using the arrow keys,\n\t * * The entire widget is selected in the model.\n\t *\n\t * In the first case, the new paragraph is inserted according to the `widget-type-around` selection\n\t * attribute (see {@link #_handleArrowKeyPress}).\n\t *\n\t * In the second case, the new paragraph is inserted based on whether a soft (<kbd>Shift</kbd>+<kbd>Enter</kbd>) keystroke\n\t * was pressed or not.\n\t */\n\tprivate _enableInsertingParagraphsOnEnterKeypress() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst editingView = editor.editing.view;\n\n\t\tthis._listenToIfEnabled<ViewDocumentEnterEvent>( editingView.document, 'enter', ( evt, domEventData ) => {\n\t\t\t// This event could be triggered from inside the widget but we are interested\n\t\t\t// only when the widget is selected itself.\n\t\t\tif ( evt.eventPhase != 'atTarget' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedModelElement = selection.getSelectedElement()!;\n\t\t\tconst selectedViewElement = editor.editing.mapper.toViewElement( selectedModelElement );\n\n\t\t\tconst schema = editor.model.schema;\n\t\t\tlet wasHandled;\n\n\t\t\t// First check if the widget is selected and there's a type around selection attribute associated\n\t\t\t// with the fake caret that would tell where to insert a new paragraph.\n\t\t\tif ( this._insertParagraphAccordingToFakeCaretPosition() ) {\n\t\t\t\twasHandled = true;\n\t\t\t}\n\t\t\t// Then, if there is no selection attribute associated with the fake caret, check if the widget\n\t\t\t// simply is selected and create a new paragraph according to the keystroke (Shift+)Enter.\n\t\t\telse if ( isTypeAroundWidget( selectedViewElement, selectedModelElement, schema ) ) {\n\t\t\t\tthis._insertParagraph( selectedModelElement, domEventData.isSoft ? 'before' : 'after' );\n\n\t\t\t\twasHandled = true;\n\t\t\t}\n\n\t\t\tif ( wasHandled ) {\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: isWidget } );\n\t}\n\n\t/**\n\t * Similar to the {@link #_enableInsertingParagraphsOnEnterKeypress}, it allows the user\n\t * to insert a paragraph next to a widget when the fake caret was activated using arrow\n\t * keys but it responds to typing instead of <kbd>Enter</kbd>.\n\t *\n\t * Listener enabled by this method will insert a new paragraph according to the `widget-type-around`\n\t * model selection attribute as the user simply starts typing, which creates the impression that the fake caret\n\t * behaves like a real one rendered by the browser (AKA your text appears where the caret was).\n\t *\n\t * **Note**: At the moment this listener creates 2 undo steps: one for the `insertParagraph` command\n\t * and another one for actual typing. It is not a disaster but this may need to be fixed\n\t * sooner or later.\n\t */\n\tprivate _enableInsertingParagraphsOnTypingKeystroke() {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\t// Note: The priority must precede the default Input plugin insertText handler.\n\t\tthis._listenToIfEnabled<ViewDocumentInsertTextEvent>( viewDocument, 'insertText', ( evt, data ) => {\n\t\t\tif ( this._insertParagraphAccordingToFakeCaretPosition() ) {\n\t\t\t\t// The view selection in the event data contains the widget. If the new paragraph\n\t\t\t\t// was inserted, modify the view selection passed along with the insertText event\n\t\t\t\t// so the default event handler in the Input plugin starts typing inside the paragraph.\n\t\t\t\t// Otherwise, the typing would be over the widget.\n\t\t\t\tdata.selection = viewDocument.selection;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\tif ( env.isAndroid ) {\n\t\t\t// On Android with English keyboard, the composition starts just by putting caret\n\t\t\t// at the word end or by selecting a table column. This is not a real composition started.\n\t\t\t// Trigger delete content on first composition key pressed.\n\t\t\tthis._listenToIfEnabled<ViewDocumentKeyDownEvent>( viewDocument, 'keydown', ( evt, data ) => {\n\t\t\t\tif ( data.keyCode == 229 ) {\n\t\t\t\t\tthis._insertParagraphAccordingToFakeCaretPosition();\n\t\t\t\t}\n\t\t\t} );\n\t\t} else {\n\t\t\t// Note: The priority must precede the default Input plugin compositionstart handler (to call it before delete content).\n\t\t\tthis._listenToIfEnabled<ViewDocumentCompositionStartEvent>( viewDocument, 'compositionstart', () => {\n\t\t\t\tthis._insertParagraphAccordingToFakeCaretPosition();\n\t\t\t}, { priority: 'high' } );\n\t\t}\n\t}\n\n\t/**\n\t * It creates a \"delete\" event listener on the view document to handle cases when the <kbd>Delete</kbd> or <kbd>Backspace</kbd>\n\t * is pressed and the fake caret is currently active.\n\t *\n\t * The fake caret should create an illusion of a real browser caret so that when it appears before or after\n\t * a widget, pressing <kbd>Delete</kbd> or <kbd>Backspace</kbd> should remove a widget or delete the content\n\t * before or after a widget (depending on the content surrounding the widget).\n\t */\n\tprivate _enableDeleteIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst model = editor.model;\n\t\tconst schema = model.schema;\n\n\t\tthis._listenToIfEnabled<ViewDocumentDeleteEvent>( editingView.document, 'delete', ( evt, domEventData ) => {\n\t\t\t// This event could be triggered from inside the widget but we are interested\n\t\t\t// only when the widget is selected itself.\n\t\t\tif ( evt.eventPhase != 'atTarget' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( model.document.selection );\n\n\t\t\t// This listener handles only these cases when the fake caret is active.\n\t\t\tif ( !typeAroundFakeCaretPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst direction = domEventData.direction;\n\t\t\tconst selectedModelWidget = model.document.selection.getSelectedElement();\n\n\t\t\tconst isFakeCaretBefore = typeAroundFakeCaretPosition === 'before';\n\t\t\tconst isDeleteForward = direction == 'forward';\n\t\t\tconst shouldDeleteEntireWidget = isFakeCaretBefore === isDeleteForward;\n\n\t\t\tif ( shouldDeleteEntireWidget ) {\n\t\t\t\teditor.execute( 'delete', {\n\t\t\t\t\tselection: model.createSelection( selectedModelWidget!, 'on' )\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tconst range = schema.getNearestSelectionRange(\n\t\t\t\t\tmodel.createPositionAt( selectedModelWidget!, typeAroundFakeCaretPosition ),\n\t\t\t\t\tdirection\n\t\t\t\t);\n\n\t\t\t\t// If there is somewhere to move selection to, then there will be something to delete.\n\t\t\t\tif ( range ) {\n\t\t\t\t\t// If the range is NOT collapsed, then we know that the range contains an object (see getNearestSelectionRange() docs).\n\t\t\t\t\tif ( !range.isCollapsed ) {\n\t\t\t\t\t\tmodel.change( writer => {\n\t\t\t\t\t\t\twriter.setSelection( range );\n\t\t\t\t\t\t\teditor.execute( isDeleteForward ? 'deleteForward' : 'delete' );\n\t\t\t\t\t\t} );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst probe = model.createSelection( range.start );\n\t\t\t\t\t\tmodel.modifySelection( probe, { direction } );\n\n\t\t\t\t\t\t// If the range is collapsed, let's see if a non-collapsed range exists that can could be deleted.\n\t\t\t\t\t\t// If such range exists, use the editor command because it it safe for collaboration (it merges where it can).\n\t\t\t\t\t\tif ( !probe.focus!.isEqual( range.start ) ) {\n\t\t\t\t\t\t\tmodel.change( writer => {\n\t\t\t\t\t\t\t\twriter.setSelection( range );\n\t\t\t\t\t\t\t\teditor.execute( isDeleteForward ? 'deleteForward' : 'delete' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// If there is no non-collapsed range to be deleted then we are sure that there is an empty element\n\t\t\t\t\t\t// next to a widget that should be removed. \"delete\" and \"deleteForward\" commands cannot get rid of it\n\t\t\t\t\t\t// so calling Model#deleteContent here manually.\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tconst deepestEmptyRangeAncestor = getDeepestEmptyElementAncestor( schema, range.start.parent as Element );\n\n\t\t\t\t\t\t\tmodel.deleteContent( model.createSelection( deepestEmptyRangeAncestor, 'on' ), {\n\t\t\t\t\t\t\t\tdoNotAutoparagraph: true\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If some content was deleted, don't let the handler from the Widget plugin kick in.\n\t\t\t// If nothing was deleted, then the default handler will have nothing to do anyway.\n\t\t\tdomEventData.preventDefault();\n\t\t\tevt.stop();\n\t\t}, { context: isWidget } );\n\t}\n\n\t/**\n\t * Attaches the {@link module:engine/model/model~Model#event:insertContent} event listener that, for instance, allows the user to paste\n\t * content near a widget when the fake caret is first activated using the arrow keys.\n\t *\n\t * The content is inserted according to the `widget-type-around` selection attribute (see {@link #_handleArrowKeyPress}).\n\t */\n\tprivate _enableInsertContentIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst documentSelection = model.document.selection;\n\n\t\tthis._listenToIfEnabled<ModelInsertContentEvent>( editor.model, 'insertContent', ( evt, [ content, selectable ] ) => {\n\t\t\tif ( selectable && !( selectable as any ).is( 'documentSelection' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( documentSelection );\n\n\t\t\tif ( !typeAroundFakeCaretPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tevt.stop();\n\n\t\t\treturn model.change( writer => {\n\t\t\t\tconst selectedElement = documentSelection.getSelectedElement();\n\t\t\t\tconst position = model.createPositionAt( selectedElement!, typeAroundFakeCaretPosition );\n\t\t\t\tconst selection = writer.createSelection( position );\n\n\t\t\t\tconst result = model.insertContent( content, selection );\n\n\t\t\t\twriter.setSelection( selection );\n\n\t\t\t\treturn result;\n\t\t\t} );\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Attaches the {@link module:engine/model/model~Model#event:insertObject} event listener that modifies the\n\t * `options.findOptimalPosition`parameter to position of fake caret in relation to selected element\n\t * to reflect user's intent of desired insertion position.\n\t *\n\t * The object is inserted according to the `widget-type-around` selection attribute (see {@link #_handleArrowKeyPress}).\n\t */\n\tprivate _enableInsertObjectIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst documentSelection = model.document.selection;\n\n\t\tthis._listenToIfEnabled<ModelInsertObjectEvent>( editor.model, 'insertObject', ( evt, args ) => {\n\t\t\tconst [ , selectable, options = {} ] = args;\n\n\t\t\tif ( selectable && !( selectable as any ).is( 'documentSelection' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( documentSelection );\n\n\t\t\tif ( !typeAroundFakeCaretPosition ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\toptions.findOptimalPosition = typeAroundFakeCaretPosition;\n\t\t\targs[ 3 ] = options;\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Attaches the {@link module:engine/model/model~Model#event:deleteContent} event listener to block the event when the fake\n\t * caret is active.\n\t *\n\t * This is required for cases that trigger {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`}\n\t * before calling {@link module:engine/model/model~Model#insertContent `model.insertContent()`} like, for instance,\n\t * plain text pasting.\n\t */\n\tprivate _enableDeleteContentIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst documentSelection = model.document.selection;\n\n\t\tthis._listenToIfEnabled<ModelDeleteContentEvent>( editor.model, 'deleteContent', ( evt, [ selection ] ) => {\n\t\t\tif ( selection && !selection.is( 'documentSelection' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst typeAroundFakeCaretPosition = getTypeAroundFakeCaretPosition( documentSelection );\n\n\t\t\t// Disable removing the selection content while pasting plain text.\n\t\t\tif ( typeAroundFakeCaretPosition ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n}\n\n/**\n * Injects the type around UI into a view widget instance.\n */\nfunction injectUIIntoWidget(\n\tviewWriter: DowncastWriter,\n\tbuttonTitles: { before: string; after: string },\n\twidgetViewElement: ViewElement ) {\n\tconst typeAroundWrapper = viewWriter.createUIElement( 'div', {\n\t\tclass: 'ck ck-reset_all ck-widget__type-around'\n\t}, function( domDocument ) {\n\t\tconst wrapperDomElement = this.toDomElement( domDocument );\n\n\t\tinjectButtons( wrapperDomElement, buttonTitles );\n\t\tinjectFakeCaret( wrapperDomElement );\n\n\t\treturn wrapperDomElement;\n\t} );\n\n\t// Inject the type around wrapper into the widget's wrapper.\n\tviewWriter.insert( viewWriter.createPositionAt( widgetViewElement, 'end' ), typeAroundWrapper );\n}\n\n/**\n * FYI: Not using the IconView class because each instance would need to be destroyed to avoid memory leaks\n * and it's pretty hard to figure out when a view (widget) is gone for good so it's cheaper to use raw\n * <svg> here.\n */\nfunction injectButtons( wrapperDomElement: HTMLElement, buttonTitles: { before: string; after: string } ) {\n\tfor ( const position of POSSIBLE_INSERTION_POSITIONS ) {\n\t\tconst buttonTemplate = new Template( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-widget__type-around__button',\n\t\t\t\t\t`ck-widget__type-around__button_${ position }`\n\t\t\t\t],\n\t\t\t\ttitle: buttonTitles[ position ],\n\t\t\t\t'aria-hidden': 'true'\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\twrapperDomElement.ownerDocument.importNode( RETURN_ARROW_ICON_ELEMENT, true )\n\t\t\t]\n\t\t} );\n\n\t\twrapperDomElement.appendChild( buttonTemplate.render() );\n\t}\n}\n\nfunction injectFakeCaret( wrapperDomElement: HTMLElement ) {\n\tconst caretTemplate = new Template( {\n\t\ttag: 'div',\n\t\tattributes: {\n\t\t\tclass: [\n\t\t\t\t'ck',\n\t\t\t\t'ck-widget__type-around__fake-caret'\n\t\t\t]\n\t\t}\n\t} );\n\n\twrapperDomElement.appendChild( caretTemplate.render() );\n}\n\n/**\n * Returns the ancestor of an element closest to the root which is empty. For instance,\n * for `<baz>`:\n *\n * ```\n * <foo>abc<bar><baz></baz></bar></foo>\n * ```\n *\n * it returns `<bar>`.\n */\nfunction getDeepestEmptyElementAncestor( schema: Schema, element: Element ) {\n\tlet deepestEmptyAncestor = element;\n\n\tfor ( const ancestor of element.getAncestors( { parentFirst: true } ) ) {\n\t\tif ( ( ancestor as any ).childCount > 1 || schema.isLimit( ancestor ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tdeepestEmptyAncestor = ancestor as Element;\n\t}\n\n\treturn deepestEmptyAncestor;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/verticalnavigation\n */\n\nimport {\n\tkeyCodes,\n\tRect,\n\ttype GetCallback\n} from '@ckeditor/ckeditor5-utils';\n\nimport type {\n\tDocumentSelection,\n\tEditingController,\n\tModel,\n\tPosition,\n\tRange,\n\tSchema,\n\tSelection,\n\tViewDocumentArrowKeyEvent\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * Returns 'keydown' handler for up/down arrow keys that modifies the caret movement if it's in a text line next to an object.\n *\n * @param editing The editing controller.\n */\nexport default function verticalNavigationHandler(\n\tediting: EditingController\n): GetCallback<ViewDocumentArrowKeyEvent> {\n\tconst model = editing.model;\n\n\treturn ( evt, data ) => {\n\t\tconst arrowUpPressed = data.keyCode == keyCodes.arrowup;\n\t\tconst arrowDownPressed = data.keyCode == keyCodes.arrowdown;\n\t\tconst expandSelection = data.shiftKey;\n\t\tconst selection = model.document.selection;\n\n\t\tif ( !arrowUpPressed && !arrowDownPressed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isForward = arrowDownPressed;\n\n\t\t// Navigation is in the opposite direction than the selection direction so this is shrinking of the selection.\n\t\t// Selection for sure will not approach any object.\n\t\tif ( expandSelection && selectionWillShrink( selection, isForward ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find a range between selection and closest limit element.\n\t\tconst range = findTextRangeFromSelection( editing, selection, isForward );\n\n\t\t// There is no selection position inside the limit element.\n\t\tif ( !range ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If already at the edge of a limit element.\n\t\tif ( range.isCollapsed ) {\n\t\t\t// A collapsed selection at limit edge - nothing more to do.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// A non collapsed selection is at the limit edge while expanding the selection - let others do their stuff.\n\t\t\telse if ( expandSelection ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// If the range is a single line (there is no word wrapping) then move the selection to the position closest to the limit element.\n\t\t//\n\t\t// We can't move the selection directly to the isObject element (eg. table cell) because of dual position at the end/beginning\n\t\t// of wrapped line (it's at the same time at the end of one line and at the start of the next line).\n\t\tif ( range.isCollapsed || isSingleLineRange( editing, range, isForward ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\tconst newPosition = isForward ? range.end : range.start;\n\n\t\t\t\tif ( expandSelection ) {\n\t\t\t\t\tconst newSelection = model.createSelection( selection.anchor );\n\t\t\t\t\tnewSelection.setFocus( newPosition );\n\n\t\t\t\t\twriter.setSelection( newSelection );\n\t\t\t\t} else {\n\t\t\t\t\twriter.setSelection( newPosition );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tevt.stop();\n\t\t\tdata.preventDefault();\n\t\t\tdata.stopPropagation();\n\t\t}\n\t};\n}\n\n/**\n * Finds the range between selection and closest limit element (in the direction of navigation).\n * The position next to limit element is adjusted to the closest allowed `$text` position.\n *\n * Returns `null` if, according to the schema, the resulting range cannot contain a `$text` element.\n *\n * @param editing The editing controller.\n * @param selection The current selection.\n * @param isForward The expected navigation direction.\n */\nfunction findTextRangeFromSelection( editing: EditingController, selection: Selection | DocumentSelection, isForward: boolean ) {\n\tconst model = editing.model;\n\n\tif ( isForward ) {\n\t\tconst startPosition = selection.isCollapsed ? selection.focus! : selection.getLastPosition()!;\n\t\tconst endPosition = getNearestNonInlineLimit( model, startPosition, 'forward' );\n\n\t\t// There is no limit element, browser should handle this.\n\t\tif ( !endPosition ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = model.createRange( startPosition, endPosition );\n\t\tconst lastRangePosition = getNearestTextPosition( model.schema, range, 'backward' );\n\n\t\tif ( lastRangePosition ) {\n\t\t\treturn model.createRange( startPosition, lastRangePosition );\n\t\t}\n\n\t\treturn null;\n\t} else {\n\t\tconst endPosition = selection.isCollapsed ? selection.focus! : selection.getFirstPosition()!;\n\t\tconst startPosition = getNearestNonInlineLimit( model, endPosition, 'backward' );\n\n\t\t// There is no limit element, browser should handle this.\n\t\tif ( !startPosition ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst range = model.createRange( startPosition, endPosition );\n\t\tconst firstRangePosition = getNearestTextPosition( model.schema, range, 'forward' );\n\n\t\tif ( firstRangePosition ) {\n\t\t\treturn model.createRange( firstRangePosition, endPosition );\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\n/**\n * Finds the limit element position that is closest to startPosition.\n *\n * @param direction Search direction.\n */\nfunction getNearestNonInlineLimit( model: Model, startPosition: Position, direction: 'forward' | 'backward' ) {\n\tconst schema = model.schema;\n\tconst range = model.createRangeIn( startPosition.root );\n\n\tconst walkerValueType = direction == 'forward' ? 'elementStart' : 'elementEnd';\n\n\tfor ( const { previousPosition, item, type } of range.getWalker( { startPosition, direction } ) ) {\n\t\tif ( schema.isLimit( item ) && !schema.isInline( item ) ) {\n\t\t\treturn previousPosition;\n\t\t}\n\n\t\t// Stop looking for isLimit element if the next element is a block element (it is for sure not single line).\n\t\tif ( type == walkerValueType && schema.isBlock( item ) ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Basing on the provided range, finds the first or last (depending on `direction`) position inside the range\n * that can contain `$text` (according to schema).\n *\n * @param schema The schema.\n * @param range The range to find the position in.\n * @param direction Search direction.\n * @returns The nearest selection position.\n *\n */\nfunction getNearestTextPosition( schema: Schema, range: Range, direction: 'forward' | 'backward' ) {\n\tconst position = direction == 'backward' ? range.end : range.start;\n\n\tif ( schema.checkChild( position, '$text' ) ) {\n\t\treturn position;\n\t}\n\n\tfor ( const { nextPosition } of range.getWalker( { direction } ) ) {\n\t\tif ( schema.checkChild( nextPosition, '$text' ) ) {\n\t\t\treturn nextPosition;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Checks if the DOM range corresponding to the provided model range renders as a single line by analyzing DOMRects\n * (verifying if they visually wrap content to the next line).\n *\n * @param editing The editing controller.\n * @param modelRange The current table cell content range.\n * @param isForward The expected navigation direction.\n */\nfunction isSingleLineRange( editing: EditingController, modelRange: Range, isForward: boolean ) {\n\tconst model = editing.model;\n\tconst domConverter = editing.view.domConverter;\n\n\t// Wrapped lines contain exactly the same position at the end of current line\n\t// and at the beginning of next line. That position's client rect is at the end\n\t// of current line. In case of caret at first position of the last line that 'dual'\n\t// position would be detected as it's not the last line.\n\tif ( isForward ) {\n\t\tconst probe = model.createSelection( modelRange.start );\n\n\t\tmodel.modifySelection( probe );\n\n\t\t// If the new position is at the end of the container then we can't use this position\n\t\t// because it would provide incorrect result for eg caption of image and selection\n\t\t// just before end of it. Also in this case there is no \"dual\" position.\n\t\tif ( !probe.focus!.isAtEnd && !modelRange.start.isEqual( probe.focus! ) ) {\n\t\t\tmodelRange = model.createRange( probe.focus!, modelRange.end );\n\t\t}\n\t}\n\n\tconst viewRange = editing.mapper.toViewRange( modelRange );\n\tconst domRange = domConverter.viewRangeToDom( viewRange );\n\tconst rects = Rect.getDomRangeRects( domRange );\n\n\tlet boundaryVerticalPosition;\n\n\tfor ( const rect of rects ) {\n\t\tif ( boundaryVerticalPosition === undefined ) {\n\t\t\tboundaryVerticalPosition = Math.round( rect.bottom );\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Let's check if this rect is in new line.\n\t\tif ( Math.round( rect.top ) >= boundaryVerticalPosition ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tboundaryVerticalPosition = Math.max( boundaryVerticalPosition, Math.round( rect.bottom ) );\n\t}\n\n\treturn true;\n}\n\nfunction selectionWillShrink( selection: DocumentSelection, isForward: boolean ) {\n\treturn !selection.isCollapsed && selection.isBackward == isForward;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/widget\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport {\n\tMouseObserver,\n\tTreeWalker,\n\ttype DomEventData,\n\ttype DowncastSelectionEvent,\n\ttype DowncastWriter,\n\ttype Element,\n\ttype Node,\n\ttype ViewDocumentArrowKeyEvent,\n\ttype ViewDocumentMouseDownEvent,\n\ttype ViewElement,\n\ttype Schema,\n\ttype Position,\n\ttype EditingView,\n\ttype ViewDocumentTabEvent,\n\ttype ViewDocumentKeyDownEvent,\n\ttype ViewNode,\n\ttype ViewRange\n} from '@ckeditor/ckeditor5-engine';\n\nimport { Delete, type ViewDocumentDeleteEvent } from '@ckeditor/ckeditor5-typing';\n\nimport {\n\tenv,\n\tkeyCodes,\n\tgetLocalizedArrowKeyCodeDirection,\n\tgetRangeFromMouseEvent,\n\ttype EventInfo,\n\ttype KeystrokeInfo\n} from '@ckeditor/ckeditor5-utils';\n\nimport WidgetTypeAround from './widgettypearound/widgettypearound.js';\nimport verticalNavigationHandler from './verticalnavigation.js';\nimport { getLabel, isWidget, WIDGET_SELECTED_CLASS_NAME } from './utils.js';\n\nimport '../theme/widget.css';\n\n/**\n * The widget plugin. It enables base support for widgets.\n *\n * See {@glink api/widget package page} for more details and documentation.\n *\n * This plugin enables multiple behaviors required by widgets:\n *\n * * The model to view selection converter for the editing pipeline (it handles widget custom selection rendering).\n * If a converted selection wraps around a widget element, that selection is marked as\n * {@link module:engine/view/selection~Selection#isFake fake}. Additionally, the `ck-widget_selected` CSS class\n * is added to indicate that widget has been selected.\n * * The mouse and keyboard events handling on and around widget elements.\n */\nexport default class Widget extends Plugin {\n\t/**\n\t * Holds previously selected widgets.\n\t */\n\tprivate _previouslySelected = new Set<ViewElement>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Widget' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ WidgetTypeAround, Delete ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst t = editor.t;\n\n\t\t// Model to view selection converter.\n\t\t// Converts selection placed over widget element to fake selection.\n\t\t//\n\t\t// By default, the selection is downcasted by the engine to surround the attribute element, even though its only\n\t\t// child is an inline widget. A similar thing also happens when a collapsed marker is rendered as a UI element\n\t\t// next to an inline widget: the view selection contains both the widget and the marker.\n\t\t//\n\t\t// This prevents creating a correct fake selection when this inline widget is selected. Normalize the selection\n\t\t// in these cases based on the model:\n\t\t//\n\t\t//\t\t[<attributeElement><inlineWidget /></attributeElement>] -> <attributeElement>[<inlineWidget />]</attributeElement>\n\t\t//\t\t[<uiElement></uiElement><inlineWidget />] -> <uiElement></uiElement>[<inlineWidget />]\n\t\t//\n\t\t// Thanks to this:\n\t\t//\n\t\t// * fake selection can be set correctly,\n\t\t// * any logic depending on (View)Selection#getSelectedElement() also works OK.\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/9524.\n\t\tthis.editor.editing.downcastDispatcher.on<DowncastSelectionEvent>( 'selection', ( evt, data, conversionApi ) => {\n\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\tconst modelSelection = data.selection;\n\n\t\t\t// The collapsed selection can't contain any widget.\n\t\t\tif ( modelSelection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedModelElement = modelSelection.getSelectedElement();\n\n\t\t\tif ( !selectedModelElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedViewElement = editor.editing.mapper.toViewElement( selectedModelElement )!;\n\n\t\t\tif ( !isWidget( selectedViewElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !conversionApi.consumable.consume( modelSelection, 'selection' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tviewWriter.setSelection( viewWriter.createRangeOn( selectedViewElement ), {\n\t\t\t\tfake: true,\n\t\t\t\tlabel: getLabel( selectedViewElement )\n\t\t\t} );\n\t\t} );\n\n\t\t// Mark all widgets inside the selection with the css class.\n\t\t// This handler is registered at the 'low' priority so it's triggered after the real selection conversion.\n\t\tthis.editor.editing.downcastDispatcher.on<DowncastSelectionEvent>( 'selection', ( evt, data, conversionApi ) => {\n\t\t\t// Remove selected class from previously selected widgets.\n\t\t\tthis._clearPreviouslySelectedWidgets( conversionApi.writer );\n\n\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\t\tlet lastMarked = null;\n\n\t\t\tfor ( const range of viewSelection.getRanges() ) {\n\t\t\t\t// Note: There could be multiple selected widgets in a range but no fake selection.\n\t\t\t\t// All of them must be marked as selected, for instance [<widget></widget><widget></widget>]\n\t\t\t\tfor ( const value of range ) {\n\t\t\t\t\tconst node = value.item as ViewElement;\n\t\t\t\t\t// Do not mark nested widgets in selected one. See: #4594\n\t\t\t\t\tif ( isWidget( node ) && !isChild( node, lastMarked ) ) {\n\t\t\t\t\t\tviewWriter.addClass( WIDGET_SELECTED_CLASS_NAME, node );\n\t\t\t\t\t\tthis._previouslySelected.add( node );\n\t\t\t\t\t\tlastMarked = node;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// If mouse down is pressed on widget - create selection over whole widget.\n\t\tview.addObserver( MouseObserver );\n\t\tthis.listenTo<ViewDocumentMouseDownEvent>( viewDocument, 'mousedown', ( ...args ) => this._onMousedown( ...args ) );\n\n\t\t// There are two keydown listeners working on different priorities. This allows other\n\t\t// features such as WidgetTypeAround or TableKeyboard to attach their listeners in between\n\t\t// and customize the behavior even further in different content/selection scenarios.\n\t\t//\n\t\t// * The first listener handles changing the selection on arrow key press\n\t\t// if the widget is selected or if the selection is next to a widget and the widget\n\t\t// should become selected upon the arrow key press.\n\t\t//\n\t\t// * The second (late) listener makes sure the default browser action on arrow key press is\n\t\t// prevented when a widget is selected. This prevents the selection from being moved\n\t\t// from a fake selection container.\n\t\tthis.listenTo<ViewDocumentArrowKeyEvent>( viewDocument, 'arrowKey', ( ...args ) => {\n\t\t\tthis._handleSelectionChangeOnArrowKeyPress( ...args );\n\t\t}, { context: [ isWidget, '$text' ] } );\n\n\t\tthis.listenTo<ViewDocumentArrowKeyEvent>( viewDocument, 'arrowKey', ( ...args ) => {\n\t\t\tthis._preventDefaultOnArrowKeyPress( ...args );\n\t\t}, { context: '$root' } );\n\n\t\tthis.listenTo<ViewDocumentArrowKeyEvent>(\n\t\t\tviewDocument,\n\t\t\t'arrowKey',\n\t\t\tverticalNavigationHandler( this.editor.editing ),\n\t\t\t{ context: '$text' }\n\t\t);\n\n\t\t// Handle custom delete behaviour.\n\t\tthis.listenTo<ViewDocumentDeleteEvent>( viewDocument, 'delete', ( evt, data ) => {\n\t\t\tif ( this._handleDelete( data.direction == 'forward' ) ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: '$root' } );\n\n\t\t// Handle Tab key while a widget is selected.\n\t\tthis.listenTo<ViewDocumentTabEvent>( viewDocument, 'tab', ( evt, data ) => {\n\t\t\t// This event could be triggered from inside the widget, but we are interested\n\t\t\t// only when the widget is selected itself.\n\t\t\tif ( evt.eventPhase != 'atTarget' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( data.shiftKey ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this._selectFirstNestedEditable() ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: isWidget, priority: 'low' } );\n\n\t\t// Handle Shift+Tab key while caret inside a widget editable.\n\t\tthis.listenTo<ViewDocumentTabEvent>( viewDocument, 'tab', ( evt, data ) => {\n\t\t\tif ( !data.shiftKey ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this._selectAncestorWidget() ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// Handle Esc key while inside a nested editable.\n\t\tthis.listenTo<ViewDocumentKeyDownEvent>( viewDocument, 'keydown', ( evt, data ) => {\n\t\t\tif ( data.keystroke != keyCodes.esc ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this._selectAncestorWidget() ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// Add the information about the keystrokes to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfoGroup( {\n\t\t\tid: 'widget',\n\t\t\tlabel: t( 'Keystrokes that can be used when a widget is selected (for example: image, table, etc.)' ),\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move focus from an editable area back to the parent widget' ),\n\t\t\t\t\tkeystroke: 'Esc'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Insert a new paragraph directly after a widget' ),\n\t\t\t\t\tkeystroke: 'Enter'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Insert a new paragraph directly before a widget' ),\n\t\t\t\t\tkeystroke: 'Shift+Enter'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move the caret to allow typing directly before a widget' ),\n\t\t\t\t\tkeystroke: [ [ 'arrowup' ], [ 'arrowleft' ] ]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move the caret to allow typing directly after a widget' ),\n\t\t\t\t\tkeystroke: [ [ 'arrowdown' ], [ 'arrowright' ] ]\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:mousedown mousedown} events on widget elements.\n\t */\n\tprivate _onMousedown( eventInfo: EventInfo, domEventData: DomEventData<MouseEvent> ) {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tlet element: ViewElement | null = domEventData.target;\n\n\t\t// Some of DOM elements have no view element representation so it may be null.\n\t\tif ( !element ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If triple click should select entire paragraph.\n\t\tif ( domEventData.domEvent.detail >= 3 ) {\n\t\t\tif ( this._selectBlockContent( element ) ) {\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If target is not a widget element - check if one of the ancestors is.\n\t\tif ( !isWidget( element ) ) {\n\t\t\tconst editableOrWidgetElement = findClosestEditableOrWidgetAncestor( element );\n\n\t\t\tif ( !editableOrWidgetElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isWidget( editableOrWidgetElement ) ) {\n\t\t\t\telement = editableOrWidgetElement;\n\t\t\t} else {\n\t\t\t\t// Pick view range from the point where the mouse was clicked.\n\t\t\t\tconst clickTargetFromPoint = getElementFromMouseEvent( view, domEventData );\n\n\t\t\t\tif ( clickTargetFromPoint && isWidget( clickTargetFromPoint ) ) {\n\t\t\t\t\telement = clickTargetFromPoint;\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// On Android selection would jump to the first table cell, on other devices\n\t\t// we can't block it (and don't need to) because of drag and drop support.\n\t\tif ( env.isAndroid ) {\n\t\t\tdomEventData.preventDefault();\n\t\t}\n\n\t\t// Focus editor if is not focused already.\n\t\tif ( !viewDocument.isFocused ) {\n\t\t\tview.focus();\n\t\t}\n\n\t\t// Create model selection over widget.\n\t\tconst modelElement = editor.editing.mapper.toModelElement( element );\n\n\t\tthis._setSelectionOverElement( modelElement! );\n\t}\n\n\t/**\n\t * Selects entire block content, e.g. on triple click it selects entire paragraph.\n\t */\n\tprivate _selectBlockContent( element: ViewElement ): boolean {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst mapper = editor.editing.mapper;\n\t\tconst schema = model.schema;\n\n\t\tconst viewElement = mapper.findMappedViewAncestor( this.editor.editing.view.createPositionAt( element, 0 ) );\n\t\tconst modelElement = findTextBlockAncestor( mapper.toModelElement( viewElement )!, model.schema );\n\n\t\tif ( !modelElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst nextTextBlock = !schema.isLimit( modelElement ) ?\n\t\t\t\tfindNextTextBlock( writer.createPositionAfter( modelElement ), schema ) :\n\t\t\t\tnull;\n\n\t\t\tconst start = writer.createPositionAt( modelElement, 0 );\n\t\t\tconst end = nextTextBlock ?\n\t\t\t\twriter.createPositionAt( nextTextBlock, 0 ) :\n\t\t\t\twriter.createPositionAt( modelElement, 'end' );\n\n\t\t\twriter.setSelection( writer.createRange( start, end ) );\n\t\t} );\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and changes\n\t * the model selection when:\n\t *\n\t * * arrow key is pressed when the widget is selected,\n\t * * the selection is next to a widget and the widget should become selected upon the arrow key press.\n\t *\n\t * See {@link #_preventDefaultOnArrowKeyPress}.\n\t */\n\tprivate _handleSelectionChangeOnArrowKeyPress( eventInfo: EventInfo, domEventData: DomEventData & KeystrokeInfo ) {\n\t\tconst keyCode = domEventData.keyCode;\n\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst modelSelection = model.document.selection;\n\t\tconst objectElement = modelSelection.getSelectedElement();\n\t\tconst direction = getLocalizedArrowKeyCodeDirection( keyCode, this.editor.locale.contentLanguageDirection );\n\t\tconst isForward = direction == 'down' || direction == 'right';\n\t\tconst isVerticalNavigation = direction == 'up' || direction == 'down';\n\n\t\t// If object element is selected.\n\t\tif ( objectElement && schema.isObject( objectElement ) ) {\n\t\t\tconst position = isForward ? modelSelection.getLastPosition() : modelSelection.getFirstPosition();\n\t\t\tconst newRange = schema.getNearestSelectionRange( position!, isForward ? 'forward' : 'backward' );\n\n\t\t\tif ( newRange ) {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\twriter.setSelection( newRange );\n\t\t\t\t} );\n\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t\teventInfo.stop();\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle collapsing of the selection when there is any widget on the edge of selection.\n\t\t// This is needed because browsers have problems with collapsing such selection.\n\t\tif ( !modelSelection.isCollapsed && !domEventData.shiftKey ) {\n\t\t\tconst firstPosition = modelSelection.getFirstPosition();\n\t\t\tconst lastPosition = modelSelection.getLastPosition();\n\n\t\t\tconst firstSelectedNode = firstPosition!.nodeAfter;\n\t\t\tconst lastSelectedNode = lastPosition!.nodeBefore;\n\n\t\t\tif ( firstSelectedNode && schema.isObject( firstSelectedNode ) || lastSelectedNode && schema.isObject( lastSelectedNode ) ) {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\twriter.setSelection( isForward ? lastPosition : firstPosition );\n\t\t\t\t} );\n\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t\teventInfo.stop();\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Return if not collapsed.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If selection is next to object element.\n\n\t\tconst objectElementNextToSelection = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( objectElementNextToSelection && schema.isObject( objectElementNextToSelection ) ) {\n\t\t\t// Do not select an inline widget while handling up/down arrow.\n\t\t\tif ( schema.isInline( objectElementNextToSelection ) && isVerticalNavigation ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._setSelectionOverElement( objectElementNextToSelection );\n\n\t\t\tdomEventData.preventDefault();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events and prevents\n\t * the default browser behavior to make sure the fake selection is not being moved from a fake selection\n\t * container.\n\t *\n\t * See {@link #_handleSelectionChangeOnArrowKeyPress}.\n\t */\n\tprivate _preventDefaultOnArrowKeyPress( eventInfo: EventInfo, domEventData: DomEventData ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst objectElement = model.document.selection.getSelectedElement();\n\n\t\t// If object element is selected.\n\t\tif ( objectElement && schema.isObject( objectElement ) ) {\n\t\t\tdomEventData.preventDefault();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles delete keys: backspace and delete.\n\t *\n\t * @param isForward Set to true if delete was performed in forward direction.\n\t * @returns Returns `true` if keys were handled correctly.\n\t */\n\tprivate _handleDelete( isForward: boolean ) {\n\t\tconst modelDocument = this.editor.model.document;\n\t\tconst modelSelection = modelDocument.selection;\n\n\t\t// Do nothing when the read only mode is enabled.\n\t\tif ( !this.editor.model.canEditAt( modelSelection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do nothing on non-collapsed selection.\n\t\tif ( !modelSelection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst objectElement = this._getObjectElementNextToSelection( isForward );\n\n\t\tif ( objectElement ) {\n\t\t\tthis.editor.model.change( writer => {\n\t\t\t\tlet previousNode = modelSelection.anchor!.parent;\n\n\t\t\t\t// Remove previous element if empty.\n\t\t\t\twhile ( previousNode.isEmpty ) {\n\t\t\t\t\tconst nodeToRemove = previousNode;\n\t\t\t\t\tpreviousNode = nodeToRemove.parent!;\n\n\t\t\t\t\twriter.remove( nodeToRemove as Element );\n\t\t\t\t}\n\n\t\t\t\tthis._setSelectionOverElement( objectElement );\n\t\t\t} );\n\n\t\t\treturn true;\n\t\t}\n\t}\n\n\t/**\n\t * Sets {@link module:engine/model/selection~Selection document's selection} over given element.\n\t *\n\t * @internal\n\t */\n\tpublic _setSelectionOverElement( element: Node ): void {\n\t\tthis.editor.model.change( writer => {\n\t\t\twriter.setSelection( writer.createRangeOn( element ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if {@link module:engine/model/element~Element element} placed next to the current\n\t * {@link module:engine/model/selection~Selection model selection} exists and is marked in\n\t * {@link module:engine/model/schema~Schema schema} as `object`.\n\t *\n\t * @internal\n\t * @param forward Direction of checking.\n\t */\n\tpublic _getObjectElementNextToSelection( forward: boolean ): Element | null {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst modelSelection = model.document.selection;\n\n\t\t// Clone current selection to use it as a probe. We must leave default selection as it is so it can return\n\t\t// to its current state after undo.\n\t\tconst probe = model.createSelection( modelSelection );\n\t\tmodel.modifySelection( probe, { direction: forward ? 'forward' : 'backward' } );\n\n\t\t// The selection didn't change so there is nothing there.\n\t\tif ( probe.isEqual( modelSelection ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst objectElement = forward ? probe.focus!.nodeBefore : probe.focus!.nodeAfter;\n\n\t\tif ( !!objectElement && schema.isObject( objectElement ) ) {\n\t\t\treturn objectElement as Element;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Removes CSS class from previously selected widgets.\n\t */\n\tprivate _clearPreviouslySelectedWidgets( writer: DowncastWriter ) {\n\t\tfor ( const widget of this._previouslySelected ) {\n\t\t\twriter.removeClass( WIDGET_SELECTED_CLASS_NAME, widget );\n\t\t}\n\n\t\tthis._previouslySelected.clear();\n\t}\n\n\t/**\n\t * Moves the document selection into the first nested editable.\n\t */\n\tprivate _selectFirstNestedEditable(): boolean {\n\t\tconst editor = this.editor;\n\t\tconst view = this.editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\tfor ( const item of viewDocument.selection.getFirstRange()!.getItems() ) {\n\t\t\tif ( item.is( 'editableElement' ) ) {\n\t\t\t\tconst modelElement = editor.editing.mapper.toModelElement( item );\n\n\t\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\t\tif ( !modelElement ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst position = editor.model.createPositionAt( modelElement, 0 );\n\t\t\t\tconst newRange = editor.model.schema.getNearestSelectionRange( position, 'forward' );\n\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\twriter.setSelection( newRange );\n\t\t\t\t} );\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Updates the document selection so that it selects first ancestor widget.\n\t */\n\tprivate _selectAncestorWidget(): boolean {\n\t\tconst editor = this.editor;\n\t\tconst mapper = editor.editing.mapper;\n\t\tconst selection = editor.editing.view.document.selection;\n\n\t\tconst positionParent = selection.getFirstPosition()!.parent;\n\n\t\tconst positionParentElement = positionParent.is( '$text' ) ?\n\t\t\tpositionParent.parent as ViewElement :\n\t\t\tpositionParent as ViewElement;\n\n\t\tconst viewElement = positionParentElement.findAncestor( isWidget );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst modelElement = mapper.toModelElement( viewElement );\n\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif ( !modelElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\twriter.setSelection( modelElement, 'on' );\n\t\t} );\n\n\t\treturn true;\n\t}\n}\n\n/**\n * Finds the closest ancestor element that is either an editable element or a widget.\n *\n * @param element The element from which to start searching.\n * @returns The closest ancestor element that is either an editable element or a widget, or null if none is found.\n */\nfunction findClosestEditableOrWidgetAncestor( element: ViewElement ): ViewElement | null {\n\tlet currentElement: ViewElement | null = element;\n\n\twhile ( currentElement ) {\n\t\tif ( currentElement.is( 'editableElement' ) || isWidget( currentElement ) ) {\n\t\t\treturn currentElement;\n\t\t}\n\n\t\tcurrentElement = currentElement.parent as ViewElement | null;\n\t}\n\n\treturn null;\n}\n\n/**\n * Retrieves the ViewElement associated with a mouse event in the editing view.\n *\n * @param view The editing view.\n * @param domEventData The DOM event data containing the mouse event.\n * @returns The ViewElement associated with the mouse event, or null if not found.\n */\nfunction getElementFromMouseEvent( view: EditingView, domEventData: DomEventData<MouseEvent> ): ViewElement | null {\n\tconst domRange = getRangeFromMouseEvent( domEventData.domEvent );\n\tlet viewRange: ViewRange | null = null;\n\n\tif ( domRange ) {\n\t\tviewRange = view.domConverter.domRangeToView( domRange );\n\t} else {\n\t\t// Fallback to create range in target element. It happens frequently on Safari browser.\n\t\t// See more: https://github.com/ckeditor/ckeditor5/issues/16978\n\t\tviewRange = view.createRange( view.createPositionAt( domEventData.target, 0 ) );\n\t}\n\n\tif ( !viewRange ) {\n\t\treturn null;\n\t}\n\n\tconst viewPosition = viewRange.start;\n\n\tif ( !viewPosition.parent ) {\n\t\treturn null;\n\t}\n\n\tlet viewNode = viewPosition.parent;\n\n\tif ( viewPosition.parent.is( 'editableElement' ) ) {\n\t\tif ( viewPosition.isAtEnd && viewPosition.nodeBefore ) {\n\t\t\t// Click after a widget tend to return position at the end of the editable element\n\t\t\t// so use the node before it if range is at the end of a parent.\n\t\t\tviewNode = viewPosition.nodeBefore as ViewNode;\n\t\t} else if ( viewPosition.isAtStart && viewPosition.nodeAfter ) {\n\t\t\t// Click before a widget tend to return position at the start of the editable element\n\t\t\t// so use the node after it if range is at the start of a parent.\n\t\t\t// See more: https://github.com/ckeditor/ckeditor5/issues/16992\n\t\t\tviewNode = viewPosition.nodeAfter as ViewNode;\n\t\t}\n\t}\n\n\tif ( viewNode.is( '$text' ) ) {\n\t\treturn viewNode.parent as ViewElement;\n\t}\n\n\treturn viewNode as ViewElement;\n}\n\n/**\n * Checks whether the specified `element` is a child of the `parent` element.\n *\n * @param element An element to check.\n * @param parent A parent for the element.\n */\nfunction isChild( element: ViewElement, parent: ViewElement | null ) {\n\tif ( !parent ) {\n\t\treturn false;\n\t}\n\n\treturn Array.from( element.getAncestors() ).includes( parent );\n}\n\n/**\n * Returns nearest text block ancestor.\n */\nfunction findTextBlockAncestor( modelElement: Element, schema: Schema ): Element | null {\n\tfor ( const element of modelElement.getAncestors( { includeSelf: true, parentFirst: true } ) ) {\n\t\tif ( schema.checkChild( element as Element, '$text' ) ) {\n\t\t\treturn element as Element;\n\t\t}\n\n\t\t// Do not go beyond nested editable.\n\t\tif ( schema.isLimit( element ) && !schema.isObject( element ) ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns next text block where could put selection.\n */\nfunction findNextTextBlock( position: Position, schema: Schema ): Element | null {\n\tconst treeWalker = new TreeWalker( { startPosition: position } );\n\n\tfor ( const { item } of treeWalker ) {\n\t\tif ( schema.isLimit( item ) || !item.is( 'element' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( schema.checkChild( item, '$text' ) ) {\n\t\t\treturn item;\n\t\t}\n\t}\n\n\treturn null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/widgettoolbarrepository\n */\n\nimport {\n\tPlugin,\n\ttype Editor,\n\ttype ToolbarConfigItem\n} from '@ckeditor/ckeditor5-core';\n\nimport type { ViewDocumentSelection, ViewElement } from '@ckeditor/ckeditor5-engine';\n\nimport {\n\tBalloonPanelView,\n\tContextualBalloon,\n\tToolbarView,\n\ttype BalloonToolbar,\n\ttype BalloonToolbarShowEvent,\n\ttype EditorUIUpdateEvent\n} from '@ckeditor/ckeditor5-ui';\n\nimport {\n\tCKEditorError,\n\tlogWarning,\n\ttype ObservableChangeEvent,\n\ttype RectSource\n} from '@ckeditor/ckeditor5-utils';\n\nimport { isWidget } from './utils.js';\n\n/**\n * Widget toolbar repository plugin. A central point for registering widget toolbars. This plugin handles the whole\n * toolbar rendering process and exposes a concise API.\n *\n * To add a toolbar for your widget use the {@link ~WidgetToolbarRepository#register `WidgetToolbarRepository#register()`} method.\n *\n * The following example comes from the {@link module:image/imagetoolbar~ImageToolbar} plugin:\n *\n * ```ts\n * class ImageToolbar extends Plugin {\n * \tstatic get requires() {\n * \t\treturn [ WidgetToolbarRepository ];\n * \t}\n *\n * \tafterInit() {\n * \t\tconst editor = this.editor;\n * \t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n *\n * \t\twidgetToolbarRepository.register( 'image', {\n * \t\t\titems: editor.config.get( 'image.toolbar' ),\n * \t\t\tgetRelatedElement: getClosestSelectedImageWidget\n * \t\t} );\n * \t}\n * }\n * ```\n */\nexport default class WidgetToolbarRepository extends Plugin {\n\t/**\n\t * A map of toolbar definitions.\n\t */\n\tprivate _toolbarDefinitions = new Map<string, WidgetRepositoryToolbarDefinition>();\n\n\tprivate _balloon!: ContextualBalloon;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'WidgetToolbarRepository' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\t// Disables the default balloon toolbar for all widgets.\n\t\tif ( editor.plugins.has( 'BalloonToolbar' ) ) {\n\t\t\tconst balloonToolbar: BalloonToolbar = editor.plugins.get( 'BalloonToolbar' );\n\n\t\t\tthis.listenTo<BalloonToolbarShowEvent>( balloonToolbar, 'show', evt => {\n\t\t\t\tif ( isWidgetSelected( editor.editing.view.document.selection ) ) {\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}, { priority: 'high' } );\n\t\t}\n\n\t\tthis._balloon = this.editor.plugins.get( 'ContextualBalloon' );\n\n\t\tthis.on<ObservableChangeEvent>( 'change:isEnabled', () => {\n\t\t\tthis._updateToolbarsVisibility();\n\t\t} );\n\n\t\tthis.listenTo<EditorUIUpdateEvent>( editor.ui, 'update', () => {\n\t\t\tthis._updateToolbarsVisibility();\n\t\t} );\n\n\t\t// UI#update is not fired after focus is back in editor, we need to check if balloon panel should be visible.\n\t\tthis.listenTo<ObservableChangeEvent>( editor.ui.focusTracker, 'change:isFocused', () => {\n\t\t\tthis._updateToolbarsVisibility();\n\t\t}, { priority: 'low' } );\n\t}\n\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tfor ( const toolbarConfig of this._toolbarDefinitions.values() ) {\n\t\t\ttoolbarConfig.view.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Registers toolbar in the WidgetToolbarRepository. It renders it in the `ContextualBalloon` based on the value of the invoked\n\t * `getRelatedElement` function. Toolbar items are gathered from `items` array.\n\t * The balloon's CSS class is by default `ck-toolbar-container` and may be override with the `balloonClassName` option.\n\t *\n\t * Note: This method should be called in the {@link module:core/plugin~PluginInterface#afterInit `Plugin#afterInit()`}\n\t * callback (or later) to make sure that the given toolbar items were already registered by other plugins.\n\t *\n\t * @param toolbarId An id for the toolbar. Used to\n\t * @param options.ariaLabel Label used by assistive technologies to describe this toolbar element.\n\t * @param options.items Array of toolbar items.\n\t * @param options.getRelatedElement Callback which returns an element the toolbar should be attached to.\n\t * @param options.balloonClassName CSS class for the widget balloon.\n\t */\n\tpublic register(\n\t\ttoolbarId: string,\n\t\t{ ariaLabel, items, getRelatedElement, balloonClassName = 'ck-toolbar-container' }: {\n\t\t\tariaLabel?: string;\n\t\t\titems: Array<ToolbarConfigItem>;\n\t\t\tgetRelatedElement: ( selection: ViewDocumentSelection ) => ( ViewElement | null );\n\t\t\tballoonClassName?: string;\n\t\t}\n\t): void {\n\t\t// Trying to register a toolbar without any item.\n\t\tif ( !items.length ) {\n\t\t\t/**\n\t\t\t * When {@link module:widget/widgettoolbarrepository~WidgetToolbarRepository#register registering} a new widget toolbar, you\n\t\t\t * need to provide a non-empty array with the items that will be inserted into the toolbar.\n\t\t\t *\n\t\t\t * If you see this error when integrating the editor, you likely forgot to configure one of the widget toolbars.\n\t\t\t *\n\t\t\t * See for instance:\n\t\t\t *\n\t\t\t * * {@link module:table/tableconfig~TableConfig#contentToolbar `config.table.contentToolbar`}\n\t\t\t * * {@link module:image/imageconfig~ImageConfig#toolbar `config.image.toolbar`}\n\t\t\t *\n\t\t\t * @error widget-toolbar-no-items\n\t\t\t * @param toolbarId The id of the toolbar that has not been configured correctly.\n\t\t\t */\n\t\t\tlogWarning( 'widget-toolbar-no-items', { toolbarId } );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst toolbarView = new ToolbarView( editor.locale );\n\n\t\ttoolbarView.ariaLabel = ariaLabel || t( 'Widget toolbar' );\n\n\t\tif ( this._toolbarDefinitions.has( toolbarId ) ) {\n\t\t\t/**\n\t\t\t * Toolbar with the given id was already added.\n\t\t\t *\n\t\t\t * @error widget-toolbar-duplicated\n\t\t\t * @param toolbarId Toolbar id.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'widget-toolbar-duplicated', this, { toolbarId } );\n\t\t}\n\n\t\tconst toolbarDefinition = {\n\t\t\tview: toolbarView,\n\t\t\tgetRelatedElement,\n\t\t\tballoonClassName,\n\t\t\titemsConfig: items,\n\t\t\tinitialized: false\n\t\t};\n\n\t\t// Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n\t\teditor.ui.addToolbar( toolbarView, {\n\t\t\tisContextual: true,\n\t\t\tbeforeFocus: () => {\n\t\t\t\tconst relatedElement = getRelatedElement( editor.editing.view.document.selection );\n\n\t\t\t\tif ( relatedElement ) {\n\t\t\t\t\tthis._showToolbar( toolbarDefinition, relatedElement );\n\t\t\t\t}\n\t\t\t},\n\t\t\tafterBlur: () => {\n\t\t\t\tthis._hideToolbar( toolbarDefinition );\n\t\t\t}\n\t\t} );\n\n\t\tthis._toolbarDefinitions.set( toolbarId, toolbarDefinition );\n\t}\n\n\t/**\n\t * Iterates over stored toolbars and makes them visible or hidden.\n\t */\n\tprivate _updateToolbarsVisibility() {\n\t\tlet maxRelatedElementDepth = 0;\n\t\tlet deepestRelatedElement = null;\n\t\tlet deepestToolbarDefinition = null;\n\n\t\tfor ( const definition of this._toolbarDefinitions.values() ) {\n\t\t\tconst relatedElement = definition.getRelatedElement( this.editor.editing.view.document.selection );\n\n\t\t\tif ( !this.isEnabled || !relatedElement ) {\n\t\t\t\tif ( this._isToolbarInBalloon( definition ) ) {\n\t\t\t\t\tthis._hideToolbar( definition );\n\t\t\t\t}\n\t\t\t} else if ( !this.editor.ui.focusTracker.isFocused ) {\n\t\t\t\tif ( this._isToolbarVisible( definition ) ) {\n\t\t\t\t\tthis._hideToolbar( definition );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst relatedElementDepth = relatedElement.getAncestors().length;\n\n\t\t\t\t// Many toolbars can express willingness to be displayed but they do not know about\n\t\t\t\t// each other. Figure out which toolbar is deepest in the view tree to decide which\n\t\t\t\t// should be displayed. For instance, if a selected image is inside a table cell, display\n\t\t\t\t// the ImageToolbar rather than the TableToolbar (#60).\n\t\t\t\tif ( relatedElementDepth > maxRelatedElementDepth ) {\n\t\t\t\t\tmaxRelatedElementDepth = relatedElementDepth;\n\t\t\t\t\tdeepestRelatedElement = relatedElement;\n\t\t\t\t\tdeepestToolbarDefinition = definition;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( deepestToolbarDefinition ) {\n\t\t\tthis._showToolbar( deepestToolbarDefinition, deepestRelatedElement! );\n\t\t}\n\t}\n\n\t/**\n\t * Hides the given toolbar.\n\t */\n\tprivate _hideToolbar( toolbarDefinition: WidgetRepositoryToolbarDefinition ) {\n\t\tthis._balloon.remove( toolbarDefinition.view );\n\t\tthis.stopListening( this._balloon, 'change:visibleView' );\n\t}\n\n\t/**\n\t * Shows up the toolbar if the toolbar is not visible.\n\t * Otherwise, repositions the toolbar's balloon when toolbar's view is the most top view in balloon stack.\n\t *\n\t * It might happen here that the toolbar's view is under another view. Then do nothing as the other toolbar view\n\t * should be still visible after the {@link module:ui/editorui/editorui~EditorUI#event:update}.\n\t */\n\tprivate _showToolbar( toolbarDefinition: WidgetRepositoryToolbarDefinition, relatedElement: ViewElement ) {\n\t\tif ( this._isToolbarVisible( toolbarDefinition ) ) {\n\t\t\trepositionContextualBalloon( this.editor, relatedElement );\n\t\t} else if ( !this._isToolbarInBalloon( toolbarDefinition ) ) {\n\t\t\tif ( !toolbarDefinition.initialized ) {\n\t\t\t\ttoolbarDefinition.initialized = true;\n\t\t\t\ttoolbarDefinition.view.fillFromConfig( toolbarDefinition.itemsConfig, this.editor.ui.componentFactory );\n\t\t\t}\n\n\t\t\tthis._balloon.add( {\n\t\t\t\tview: toolbarDefinition.view,\n\t\t\t\tposition: getBalloonPositionData( this.editor, relatedElement ),\n\t\t\t\tballoonClassName: toolbarDefinition.balloonClassName\n\t\t\t} );\n\n\t\t\t// Update toolbar position each time stack with toolbar view is switched to visible.\n\t\t\t// This is in a case target element has changed when toolbar was in invisible stack\n\t\t\t// e.g. target image was wrapped by a block quote.\n\t\t\t// See https://github.com/ckeditor/ckeditor5-widget/issues/92.\n\t\t\tthis.listenTo<ObservableChangeEvent>( this._balloon, 'change:visibleView', () => {\n\t\t\t\tfor ( const definition of this._toolbarDefinitions.values() ) {\n\t\t\t\t\tif ( this._isToolbarVisible( definition ) ) {\n\t\t\t\t\t\tconst relatedElement = definition.getRelatedElement( this.editor.editing.view.document.selection );\n\t\t\t\t\t\trepositionContextualBalloon( this.editor, relatedElement! );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\tprivate _isToolbarVisible( toolbar: WidgetRepositoryToolbarDefinition ) {\n\t\treturn this._balloon.visibleView === toolbar.view;\n\t}\n\n\tprivate _isToolbarInBalloon( toolbar: WidgetRepositoryToolbarDefinition ) {\n\t\treturn this._balloon.hasView( toolbar.view );\n\t}\n}\n\nfunction repositionContextualBalloon( editor: Editor, relatedElement: ViewElement ) {\n\tconst balloon: ContextualBalloon = editor.plugins.get( 'ContextualBalloon' );\n\tconst position = getBalloonPositionData( editor, relatedElement );\n\n\tballoon.updatePosition( position );\n}\n\nfunction getBalloonPositionData( editor: Editor, relatedElement: ViewElement ) {\n\tconst editingView = editor.editing.view;\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\n\treturn {\n\t\ttarget: editingView.domConverter.mapViewToDom( relatedElement ) as RectSource | undefined,\n\t\tpositions: [\n\t\t\tdefaultPositions.northArrowSouth,\n\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\tdefaultPositions.northArrowSouthEast,\n\t\t\tdefaultPositions.southArrowNorth,\n\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\tdefaultPositions.southArrowNorthEast,\n\t\t\tdefaultPositions.viewportStickyNorth\n\t\t]\n\t};\n}\n\nfunction isWidgetSelected( selection: ViewDocumentSelection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\treturn !!( viewElement && isWidget( viewElement ) );\n}\n\n/**\n * The toolbar definition object used by the toolbar repository to manage toolbars.\n * It contains information necessary to display the toolbar in the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} and\n * update it during its life (display) cycle.\n */\ninterface WidgetRepositoryToolbarDefinition {\n\n\t/**\n\t * The UI view of the toolbar.\n\t */\n\tview: ToolbarView;\n\n\t/**\n\t * A function that returns an engine {@link module:engine/view/view~View}\n\t * element the toolbar is to be attached to. For instance, an image widget or a table widget (or `null` when\n\t * there is no such element). The function accepts an instance of {@link module:engine/view/selection~Selection}.\n\t */\n\tgetRelatedElement: ( selection: ViewDocumentSelection ) => ViewElement | null | undefined;\n\n\t/**\n\t * CSS class for the widget balloon when a toolbar is displayed.\n\t */\n\tballoonClassName: string;\n\n\titemsConfig: Array<ToolbarConfigItem>;\n\n\tinitialized: boolean;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/widgetresize/resizerstate\n */\n\nimport { ObservableMixin, Rect } from '@ckeditor/ckeditor5-utils';\n\nimport type { ResizerOptions } from '../widgetresize.js';\nimport { calculateResizeHostPercentageWidth } from '../utils.js';\n\n/**\n * Stores the internal state of a single resizable object.\n */\nexport default class ResizeState extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * The position of the handle that initiated the resizing. E.g. `\"top-left\"`, `\"bottom-right\"` etc. or `null`\n\t * if unknown.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public activeHandlePosition: string | null;\n\n\t/**\n\t * The width (percents) proposed, but not committed yet, in the current resize process.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public proposedWidthPercents: number | null;\n\n\t/**\n\t * The width (pixels) proposed, but not committed yet, in the current resize process.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public proposedWidth: number | null;\n\n\t/**\n\t * The height (pixels) proposed, but not committed yet, in the current resize process.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public proposedHeight: number | null;\n\n\t/**\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public proposedHandleHostWidth: number | null;\n\n\t/**\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public proposedHandleHostHeight: number | null;\n\n\t/**\n\t * The reference point of the resizer where the dragging started. It is used to measure the distance the user cursor\n\t * traveled, so how much the image should be enlarged.\n\t * This information is only known after the DOM was rendered, so it will be updated later.\n\t *\n\t * @internal\n\t */\n\tpublic _referenceCoordinates: { x: number; y: number } | null;\n\n\t/**\n\t * Resizer options.\n\t */\n\tprivate readonly _options: ResizerOptions;\n\n\t/**\n\t * The original width (pixels) of the resized object when the resize process was started.\n\t *\n\t * @readonly\n\t */\n\tprivate _originalWidth?: number;\n\n\t/**\n\t * The original height (pixels) of the resized object when the resize process was started.\n\t *\n\t * @readonly\n\t */\n\tprivate _originalHeight?: number;\n\n\t/**\n\t * The original width (percents) of the resized object when the resize process was started.\n\t *\n\t * @readonly\n\t */\n\tprivate _originalWidthPercents?: number;\n\n\t/**\n\t * A width to height ratio of the resized image.\n\t *\n\t * @readonly\n\t */\n\tprivate _aspectRatio?: number;\n\n\t/**\n\t * @param options Resizer options.\n\t */\n\tconstructor( options: ResizerOptions ) {\n\t\tsuper();\n\n\t\tthis.set( 'activeHandlePosition', null );\n\t\tthis.set( 'proposedWidthPercents', null );\n\t\tthis.set( 'proposedWidth', null );\n\t\tthis.set( 'proposedHeight', null );\n\t\tthis.set( 'proposedHandleHostWidth', null );\n\t\tthis.set( 'proposedHandleHostHeight', null );\n\n\t\tthis._options = options;\n\t\tthis._referenceCoordinates = null;\n\t}\n\n\t/**\n\t * The original width (pixels) of the resized object when the resize process was started.\n\t */\n\tpublic get originalWidth(): number | undefined {\n\t\treturn this._originalWidth;\n\t}\n\n\t/**\n\t * The original height (pixels) of the resized object when the resize process was started.\n\t */\n\tpublic get originalHeight(): number | undefined {\n\t\treturn this._originalHeight;\n\t}\n\n\t/**\n\t * The original width (percents) of the resized object when the resize process was started.\n\t */\n\tpublic get originalWidthPercents(): number | undefined {\n\t\treturn this._originalWidthPercents;\n\t}\n\n\t/**\n\t * A width to height ratio of the resized image.\n\t */\n\tpublic get aspectRatio(): number | undefined {\n\t\treturn this._aspectRatio;\n\t}\n\n\t/**\n\t *\n\t * @param domResizeHandle The handle used to calculate the reference point.\n\t */\n\tpublic begin( domResizeHandle: HTMLElement, domHandleHost: HTMLElement, domResizeHost: HTMLElement ): void {\n\t\tconst clientRect = new Rect( domHandleHost );\n\n\t\tthis.activeHandlePosition = getHandlePosition( domResizeHandle )!;\n\n\t\tthis._referenceCoordinates = getAbsoluteBoundaryPoint( domHandleHost, getOppositePosition( this.activeHandlePosition ) );\n\n\t\tthis._originalWidth = clientRect.width;\n\t\tthis._originalHeight = clientRect.height;\n\n\t\tthis._aspectRatio = clientRect.width / clientRect.height;\n\n\t\tconst widthStyle = domResizeHost.style.width;\n\n\t\tif ( widthStyle && widthStyle.match( /^\\d+(\\.\\d*)?%$/ ) ) {\n\t\t\tthis._originalWidthPercents = parseFloat( widthStyle );\n\t\t} else {\n\t\t\tthis._originalWidthPercents = calculateResizeHostPercentageWidth( domResizeHost, clientRect );\n\t\t}\n\t}\n\n\tpublic update( newSize: {\n\t\twidth: number;\n\t\theight: number;\n\t\twidthPercents: number;\n\t\thandleHostWidth: number;\n\t\thandleHostHeight: number;\n\t} ): void {\n\t\tthis.proposedWidth = newSize.width;\n\t\tthis.proposedHeight = newSize.height;\n\t\tthis.proposedWidthPercents = newSize.widthPercents;\n\n\t\tthis.proposedHandleHostWidth = newSize.handleHostWidth;\n\t\tthis.proposedHandleHostHeight = newSize.handleHostHeight;\n\t}\n}\n\n/**\n * Returns coordinates of the top-left corner of an element, relative to the document's top-left corner.\n *\n * @param resizerPosition The position of the resize handle, e.g. `\"top-left\"`, `\"bottom-right\"`.\n */\nfunction getAbsoluteBoundaryPoint( element: HTMLElement, resizerPosition: string ) {\n\tconst elementRect = new Rect( element );\n\tconst positionParts = resizerPosition.split( '-' );\n\tconst ret = {\n\t\tx: positionParts[ 1 ] == 'right' ? elementRect.right : elementRect.left,\n\t\ty: positionParts[ 0 ] == 'bottom' ? elementRect.bottom : elementRect.top\n\t};\n\n\tret.x += element.ownerDocument.defaultView!.scrollX;\n\tret.y += element.ownerDocument.defaultView!.scrollY;\n\n\treturn ret;\n}\n\n/**\n * @param resizerPosition The expected resizer position, like `\"top-left\"`, `\"bottom-right\"`.\n * @returns A prefixed HTML class name for the resizer element.\n */\nfunction getResizerHandleClass( resizerPosition: string ) {\n\treturn `ck-widget__resizer__handle-${ resizerPosition }`;\n}\n\n/**\n * Determines the position of a given resize handle.\n *\n * @param domHandle Handle used to calculate the reference point.\n * @returns Returns a string like `\"top-left\"` or `undefined` if not matched.\n */\nfunction getHandlePosition( domHandle: HTMLElement ) {\n\tconst resizerPositions = [ 'top-left', 'top-right', 'bottom-right', 'bottom-left' ];\n\n\tfor ( const position of resizerPositions ) {\n\t\tif ( domHandle.classList.contains( getResizerHandleClass( position ) ) ) {\n\t\t\treturn position;\n\t\t}\n\t}\n}\n\n/**\n * @param position Like `\"top-left\"`.\n * @returns Inverted `position`, e.g. it returns `\"bottom-right\"` if `\"top-left\"` was given as `position`.\n */\nfunction getOppositePosition( position: string ) {\n\tconst parts = position.split( '-' );\n\tconst replacements: Record<string, string> = {\n\t\ttop: 'bottom',\n\t\tbottom: 'top',\n\t\tleft: 'right',\n\t\tright: 'left'\n\t};\n\n\treturn `${ replacements[ parts[ 0 ] ] }-${ replacements[ parts[ 1 ] ] }`;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/widgetresize/sizeview\n */\n\nimport { View } from '@ckeditor/ckeditor5-ui';\nimport type { ResizerOptions } from '../widgetresize.js';\nimport type ResizeState from './resizerstate.js';\n\n/**\n * A view displaying the proposed new element size during the resizing.\n */\nexport default class SizeView extends View {\n\t/**\n\t * The visibility of the view defined based on the existence of the host proposed dimensions.\n\t *\n\t * @internal\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public _isVisible: boolean;\n\n\t/**\n\t * The text that will be displayed in the `SizeView` child.\n\t * It can be formatted as the pixel values (e.g. 10x20) or the percentage value (e.g. 10%).\n\t *\n\t * @internal\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public _label: string;\n\n\t/**\n\t * The position of the view defined based on the host size and active handle position.\n\t *\n\t * @internal\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public _viewPosition: string;\n\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-size-view',\n\t\t\t\t\tbind.to( '_viewPosition', value => value ? `ck-orientation-${ value }` : '' )\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\tdisplay: bind.if( '_isVisible', 'none', visible => !visible )\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: [ {\n\t\t\t\ttext: bind.to( '_label' )\n\t\t\t} ]\n\t\t} );\n\t}\n\n\t/**\n\t * A method used for binding the `SizeView` instance properties to the `ResizeState` instance observable properties.\n\t *\n\t * @internal\n\t * @param options An object defining the resizer options, used for setting the proper size label.\n\t * @param resizeState The `ResizeState` class instance, used for keeping the `SizeView` state up to date.\n\t */\n\tpublic _bindToState( options: ResizerOptions, resizeState: ResizeState ): void {\n\t\tthis.bind( '_isVisible' ).to( resizeState, 'proposedWidth', resizeState, 'proposedHeight', ( width, height ) =>\n\t\t\twidth !== null && height !== null );\n\n\t\tthis.bind( '_label' ).to(\n\t\t\tresizeState, 'proposedHandleHostWidth',\n\t\t\tresizeState, 'proposedHandleHostHeight',\n\t\t\tresizeState, 'proposedWidthPercents',\n\t\t\t( width, height, widthPercents ) => {\n\t\t\t\tif ( options.unit === 'px' ) {\n\t\t\t\t\treturn `${ width }×${ height }`;\n\t\t\t\t} else {\n\t\t\t\t\treturn `${ widthPercents }%`;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\tthis.bind( '_viewPosition' ).to(\n\t\t\tresizeState, 'activeHandlePosition',\n\t\t\tresizeState, 'proposedHandleHostWidth',\n\t\t\tresizeState, 'proposedHandleHostHeight',\n\t\t\t// If the widget is too small to contain the size label, display the label above.\n\t\t\t( position, width, height ) => width! < 50 || height! < 50 ? 'above-center' : position!\n\t\t);\n\t}\n\n\t/**\n\t * A method used for cleaning up. It removes the bindings and hides the view.\n\t *\n\t * @internal\n\t */\n\tpublic _dismiss(): void {\n\t\tthis.unbind();\n\t\tthis._isVisible = false;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/widgetresize/resizer\n */\n\nimport { Template } from '@ckeditor/ckeditor5-ui';\nimport {\n\tRect,\n\tObservableMixin,\n\tcompareArrays,\n\ttype ObservableChangeEvent,\n\ttype DecoratedMethodEvent\n} from '@ckeditor/ckeditor5-utils';\n\nimport ResizeState from './resizerstate.js';\nimport SizeView from './sizeview.js';\n\nimport type { ResizerOptions } from '../widgetresize.js';\nimport type { ViewElement } from '@ckeditor/ckeditor5-engine';\n\n/**\n * Represents a resizer for a single resizable object.\n */\nexport default class Resizer extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * Flag that indicates whether resizer can be used.\n\t *\n\t * @observable\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * Flag that indicates that resizer is currently focused.\n\t *\n\t * @observable\n\t */\n\tdeclare public isSelected: boolean;\n\n\t/**\n\t * Flag that indicates whether resizer is rendered (visible on the screen).\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * Stores the state of the resizable host geometry, such as the original width, the currently proposed height, etc.\n\t *\n\t * Note that a new state is created for each resize transaction.\n\t */\n\tprivate _state!: ResizeState;\n\n\t/**\n\t * A view displaying the proposed new element size during the resizing.\n\t */\n\tprivate _sizeView!: SizeView;\n\n\t/**\n\t * Options passed to the {@link #constructor}.\n\t */\n\tprivate _options: ResizerOptions;\n\n\t/**\n\t * A wrapper that is controlled by the resizer. This is usually a widget element.\n\t */\n\tprivate _viewResizerWrapper: ViewElement | null = null;\n\n\t/**\n\t * The width of the resized {@link module:widget/widgetresize~ResizerOptions#viewElement viewElement} before the resizing started.\n\t */\n\tprivate _initialViewWidth: string | undefined;\n\n\t/**\n\t * @param options Resizer options.\n\t */\n\tconstructor( options: ResizerOptions ) {\n\t\tsuper();\n\n\t\tthis._options = options;\n\n\t\tthis.set( 'isEnabled', true );\n\t\tthis.set( 'isSelected', false );\n\n\t\tthis.bind( 'isVisible' ).to( this, 'isEnabled', this, 'isSelected', ( isEnabled, isSelected ) => isEnabled && isSelected );\n\n\t\tthis.decorate( 'begin' );\n\t\tthis.decorate( 'cancel' );\n\t\tthis.decorate( 'commit' );\n\t\tthis.decorate( 'updateSize' );\n\n\t\tthis.on( 'commit', event => {\n\t\t\t// State might not be initialized yet. In this case, prevent further handling and make sure that the resizer is\n\t\t\t// cleaned up (#5195).\n\t\t\tif ( !this.state.proposedWidth && !this.state.proposedWidthPercents ) {\n\t\t\t\tthis._cleanup();\n\t\t\t\tevent.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Stores the state of the resizable host geometry, such as the original width, the currently proposed height, etc.\n\t *\n\t * Note that a new state is created for each resize transaction.\n\t */\n\tpublic get state(): ResizeState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Makes resizer visible in the UI.\n\t */\n\tpublic show(): void {\n\t\tconst editingView = this._options.editor.editing.view;\n\n\t\teditingView.change( writer => {\n\t\t\twriter.removeClass( 'ck-hidden', this._viewResizerWrapper! );\n\t\t} );\n\t}\n\n\t/**\n\t * Hides resizer in the UI.\n\t */\n\tpublic hide(): void {\n\t\tconst editingView = this._options.editor.editing.view;\n\n\t\teditingView.change( writer => {\n\t\t\twriter.addClass( 'ck-hidden', this._viewResizerWrapper! );\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches the resizer to the DOM.\n\t */\n\tpublic attach(): void {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst that = this;\n\t\tconst widgetElement = this._options.viewElement;\n\t\tconst editingView = this._options.editor.editing.view;\n\n\t\teditingView.change( writer => {\n\t\t\tconst viewResizerWrapper = writer.createUIElement( 'div', {\n\t\t\t\tclass: 'ck ck-reset_all ck-widget__resizer'\n\t\t\t}, function( domDocument ) {\n\t\t\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t\t\tthat._appendHandles( domElement );\n\t\t\t\tthat._appendSizeUI( domElement );\n\n\t\t\t\treturn domElement;\n\t\t\t} );\n\n\t\t\t// Append the resizer wrapper to the widget's wrapper.\n\t\t\twriter.insert( writer.createPositionAt( widgetElement, 'end' ), viewResizerWrapper );\n\t\t\twriter.addClass( 'ck-widget_with-resizer', widgetElement );\n\n\t\t\tthis._viewResizerWrapper = viewResizerWrapper;\n\n\t\t\tif ( !this.isVisible ) {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t} );\n\n\t\tthis.on<ObservableChangeEvent>( 'change:isVisible', () => {\n\t\t\tif ( this.isVisible ) {\n\t\t\t\tthis.show();\n\t\t\t\tthis.redraw();\n\t\t\t} else {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Starts the resizing process.\n\t *\n\t * Creates a new {@link #state} for the current process.\n\t *\n\t * @fires begin\n\t * @param domResizeHandle Clicked handle.\n\t */\n\tpublic begin( domResizeHandle: HTMLElement ): void {\n\t\tthis._state = new ResizeState( this._options );\n\n\t\tthis._sizeView._bindToState( this._options, this.state );\n\n\t\tthis._initialViewWidth = this._options.viewElement.getStyle( 'width' );\n\n\t\tthis.state.begin( domResizeHandle, this._getHandleHost(), this._getResizeHost() );\n\t}\n\n\t/**\n\t * Updates the proposed size based on `domEventData`.\n\t *\n\t * @fires updateSize\n\t */\n\tpublic updateSize( domEventData: MouseEvent ): void {\n\t\tconst newSize = this._proposeNewSize( domEventData );\n\t\tconst editingView = this._options.editor.editing.view;\n\n\t\teditingView.change( writer => {\n\t\t\tconst unit = this._options.unit || '%';\n\t\t\tconst newWidth = ( unit === '%' ? newSize.widthPercents : newSize.width ) + unit;\n\n\t\t\twriter.setStyle( 'width', newWidth, this._options.viewElement );\n\t\t} );\n\n\t\t// Get an actual image width, and:\n\t\t// * reflect this size to the resize wrapper\n\t\t// * apply this **real** size to the state\n\t\tconst domHandleHost = this._getHandleHost();\n\t\tconst domHandleHostRect = new Rect( domHandleHost );\n\n\t\tconst handleHostWidth = Math.round( domHandleHostRect.width );\n\t\tconst handleHostHeight = Math.round( domHandleHostRect.height );\n\n\t\t// Handle max-width limitation.\n\t\tconst domResizeHostRect = new Rect( domHandleHost );\n\n\t\tnewSize.width = Math.round( domResizeHostRect.width );\n\t\tnewSize.height = Math.round( domResizeHostRect.height );\n\n\t\tthis.redraw( domHandleHostRect );\n\n\t\tthis.state.update( {\n\t\t\t...newSize,\n\t\t\thandleHostWidth,\n\t\t\thandleHostHeight\n\t\t} );\n\t}\n\n\t/**\n\t * Applies the geometry proposed with the resizer.\n\t *\n\t * @fires commit\n\t */\n\tpublic commit(): void {\n\t\tconst unit = this._options.unit || '%';\n\t\tconst newValue = ( unit === '%' ? this.state.proposedWidthPercents : this.state.proposedWidth ) + unit;\n\n\t\t// Both cleanup and onCommit callback are very likely to make view changes. Ensure that it is made in a single step.\n\t\tthis._options.editor.editing.view.change( () => {\n\t\t\tthis._cleanup();\n\t\t\tthis._options.onCommit( newValue );\n\t\t} );\n\t}\n\n\t/**\n\t * Cancels and rejects the proposed resize dimensions, hiding the UI.\n\t *\n\t * @fires cancel\n\t */\n\tpublic cancel(): void {\n\t\tthis._cleanup();\n\t}\n\n\t/**\n\t * Destroys the resizer.\n\t */\n\tpublic destroy(): void {\n\t\tthis.cancel();\n\t}\n\n\t/**\n\t * Redraws the resizer.\n\t *\n\t * @param handleHostRect Handle host rectangle might be given to improve performance.\n\t */\n\tpublic redraw( handleHostRect?: Rect ): void {\n\t\tconst domWrapper = this._domResizerWrapper;\n\n\t\t// Refresh only if resizer exists in the DOM.\n\t\tif ( !existsInDom( domWrapper ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst widgetWrapper = domWrapper!.parentElement;\n\t\tconst handleHost = this._getHandleHost();\n\t\tconst resizerWrapper = this._viewResizerWrapper!;\n\t\tconst currentDimensions = [\n\t\t\tresizerWrapper.getStyle( 'width' ),\n\t\t\tresizerWrapper.getStyle( 'height' ),\n\t\t\tresizerWrapper.getStyle( 'left' ),\n\t\t\tresizerWrapper.getStyle( 'top' )\n\t\t];\n\t\tlet newDimensions: Array<string | undefined>;\n\n\t\tif ( widgetWrapper!.isSameNode( handleHost ) ) {\n\t\t\tconst clientRect = handleHostRect || new Rect( handleHost );\n\n\t\t\tnewDimensions = [\n\t\t\t\tclientRect.width + 'px',\n\t\t\t\tclientRect.height + 'px',\n\t\t\t\tundefined,\n\t\t\t\tundefined\n\t\t\t];\n\t\t}\n\t\t// In case a resizing host is not a widget wrapper, we need to compensate\n\t\t// for any additional offsets the resize host might have. E.g. wrapper padding\n\t\t// or simply another editable. By doing that the border and resizers are shown\n\t\t// only around the resize host.\n\t\telse {\n\t\t\tnewDimensions = [\n\t\t\t\thandleHost.offsetWidth + 'px',\n\t\t\t\thandleHost.offsetHeight + 'px',\n\t\t\t\thandleHost.offsetLeft + 'px',\n\t\t\t\thandleHost.offsetTop + 'px'\n\t\t\t];\n\t\t}\n\n\t\t// Make changes to the view only if the resizer should actually get new dimensions.\n\t\t// Otherwise, if View#change() was always called, this would cause EditorUI#update\n\t\t// loops because the WidgetResize plugin listens to EditorUI#update and updates\n\t\t// the resizer.\n\t\t// https://github.com/ckeditor/ckeditor5/issues/7633\n\t\tif ( compareArrays( currentDimensions, newDimensions ) !== 'same' ) {\n\t\t\tthis._options.editor.editing.view.change( writer => {\n\t\t\t\twriter.setStyle( {\n\t\t\t\t\twidth: newDimensions[ 0 ]!,\n\t\t\t\t\theight: newDimensions[ 1 ]!,\n\t\t\t\t\tleft: newDimensions[ 2 ]!,\n\t\t\t\t\ttop: newDimensions[ 3 ]!\n\t\t\t\t}, resizerWrapper );\n\t\t\t} );\n\t\t}\n\t}\n\n\tpublic containsHandle( domElement: HTMLElement ): boolean {\n\t\treturn this._domResizerWrapper!.contains( domElement );\n\t}\n\n\tpublic static isResizeHandle( domElement: HTMLElement ): boolean {\n\t\treturn domElement.classList.contains( 'ck-widget__resizer__handle' );\n\t}\n\n\t/**\n\t * Cleans up the context state.\n\t */\n\tprivate _cleanup(): void {\n\t\tthis._sizeView._dismiss();\n\n\t\tconst editingView = this._options.editor.editing.view;\n\n\t\teditingView.change( writer => {\n\t\t\twriter.setStyle( 'width', this._initialViewWidth!, this._options.viewElement );\n\t\t} );\n\t}\n\n\t/**\n\t * Calculates the proposed size as the resize handles are dragged.\n\t *\n\t * @param domEventData Event data that caused the size update request. It should be used to calculate the proposed size.\n\t */\n\tprivate _proposeNewSize( domEventData: MouseEvent ): { width: number; height: number; widthPercents: number } {\n\t\tconst state = this.state;\n\t\tconst currentCoordinates = extractCoordinates( domEventData );\n\t\tconst isCentered = this._options.isCentered ? this._options.isCentered( this ) : true;\n\n\t\t// Enlargement defines how much the resize host has changed in a given axis. Naturally it could be a negative number\n\t\t// meaning that it has been shrunk.\n\t\t//\n\t\t// +----------------+--+\n\t\t// |                |  |\n\t\t// |       img      |  |\n\t\t// |  /handle host  |  |\n\t\t// +----------------+  | ^\n\t\t// |                   | | - enlarge y\n\t\t// +-------------------+ v\n\t\t// \t\t\t\t\t<-->\n\t\t// \t\t\t\t\t enlarge x\n\t\tconst enlargement = {\n\t\t\tx: state._referenceCoordinates!.x - ( currentCoordinates.x + state.originalWidth! ),\n\t\t\ty: ( currentCoordinates.y - state.originalHeight! ) - state._referenceCoordinates!.y\n\t\t};\n\n\t\tif ( isCentered && state.activeHandlePosition!.endsWith( '-right' ) ) {\n\t\t\tenlargement.x = currentCoordinates.x - ( state._referenceCoordinates!.x + state.originalWidth! );\n\t\t}\n\n\t\t// Objects needs to be resized twice as much in horizontal axis if centered, since enlargement is counted from\n\t\t// one resized corner to your cursor. It needs to be duplicated to compensate for the other side too.\n\t\tif ( isCentered ) {\n\t\t\tenlargement.x *= 2;\n\t\t}\n\n\t\t// const resizeHost = this._getResizeHost();\n\n\t\t// The size proposed by the user. It does not consider the aspect ratio.\n\t\tlet width = Math.abs( state.originalWidth! + enlargement.x );\n\t\tlet height = Math.abs( state.originalHeight! + enlargement.y );\n\n\t\t// Dominant determination must take the ratio into account.\n\t\tconst dominant = width / state.aspectRatio! > height ? 'width' : 'height';\n\n\t\tif ( dominant == 'width' ) {\n\t\t\theight = width / state.aspectRatio!;\n\t\t} else {\n\t\t\twidth = height * state.aspectRatio!;\n\t\t}\n\n\t\treturn {\n\t\t\twidth: Math.round( width ),\n\t\t\theight: Math.round( height ),\n\t\t\twidthPercents: Math.min( Math.round( state.originalWidthPercents! / state.originalWidth! * width * 100 ) / 100, 100 )\n\t\t};\n\t}\n\n\t/**\n\t * Obtains the resize host.\n\t *\n\t * Resize host is an object that receives dimensions which are the result of resizing.\n\t */\n\tprivate _getResizeHost(): HTMLElement {\n\t\tconst widgetWrapper = this._domResizerWrapper!.parentElement;\n\n\t\treturn this._options.getResizeHost( widgetWrapper! );\n\t}\n\n\t/**\n\t * Obtains the handle host.\n\t *\n\t * Handle host is an object that the handles are aligned to.\n\t *\n\t * Handle host will not always be an entire widget itself. Take an image as an example. The image widget\n\t * contains an image and a caption. Only the image should be surrounded with handles.\n\t */\n\tprivate _getHandleHost(): HTMLElement {\n\t\tconst widgetWrapper = this._domResizerWrapper!.parentElement;\n\n\t\treturn this._options.getHandleHost( widgetWrapper! );\n\t}\n\n\t/**\n\t * DOM container of the entire resize UI.\n\t *\n\t * Note that this property will have a value only after the element bound with the resizer is rendered\n\t * (otherwise `null`).\n\t */\n\tprivate get _domResizerWrapper(): HTMLElement | null {\n\t\treturn this._options.editor.editing.view.domConverter.mapViewToDom( this._viewResizerWrapper! ) as any;\n\t}\n\n\t/**\n\t * Renders the resize handles in the DOM.\n\t *\n\t * @param domElement The resizer wrapper.\n\t */\n\tprivate _appendHandles( domElement: HTMLElement ) {\n\t\tconst resizerPositions = [ 'top-left', 'top-right', 'bottom-right', 'bottom-left' ];\n\n\t\tfor ( const currentPosition of resizerPositions ) {\n\t\t\tdomElement.appendChild( ( new Template( {\n\t\t\t\ttag: 'div',\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: `ck-widget__resizer__handle ${ getResizerClass( currentPosition ) }`\n\t\t\t\t}\n\t\t\t} ).render() ) );\n\t\t}\n\t}\n\n\t/**\n\t * Sets up the {@link #_sizeView} property and adds it to the passed `domElement`.\n\t */\n\tprivate _appendSizeUI( domElement: HTMLElement ) {\n\t\tthis._sizeView = new SizeView();\n\n\t\t// Make sure icon#element is rendered before passing to appendChild().\n\t\tthis._sizeView.render();\n\n\t\tdomElement.appendChild( this._sizeView.element! );\n\t}\n}\n\n/**\n * @eventName ~Resizer#begin\n */\nexport type ResizerBeginEvent = DecoratedMethodEvent<Resizer, 'begin'>;\n\n/**\n * @eventName ~Resizer#cancel\n */\nexport type ResizerCancelEvent = DecoratedMethodEvent<Resizer, 'cancel'>;\n\n/**\n * @eventName ~Resizer#commit\n */\nexport type ResizerCommitEvent = DecoratedMethodEvent<Resizer, 'commit'>;\n\n/**\n * @eventName ~Resizer#updateSize\n */\nexport type ResizerUpdateSizeEvent = DecoratedMethodEvent<Resizer, 'updateSize'>;\n\n/**\n * @param resizerPosition Expected resizer position like `\"top-left\"`, `\"bottom-right\"`.\n * @returns A prefixed HTML class name for the resizer element\n */\nfunction getResizerClass( resizerPosition: string ) {\n\treturn `ck-widget__resizer__handle-${ resizerPosition }`;\n}\n\nfunction extractCoordinates( event: MouseEvent ) {\n\treturn {\n\t\tx: event.pageX,\n\t\ty: event.pageY\n\t};\n}\n\nfunction existsInDom( element: Node | DocumentFragment | undefined | null ) {\n\treturn element && element.ownerDocument && element.ownerDocument.contains( element );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module widget/widgetresize\n */\n\nimport Resizer, {\n\ttype ResizerBeginEvent,\n\ttype ResizerCancelEvent,\n\ttype ResizerCommitEvent\n} from './widgetresize/resizer.js';\n\nimport type WidgetToolbarRepository from './widgettoolbarrepository.js';\n\nimport {\n\tPlugin,\n\ttype Editor\n} from '@ckeditor/ckeditor5-core';\n\nimport {\n\tMouseObserver,\n\ttype DocumentChangeEvent,\n\ttype DomEventData,\n\ttype Element,\n\ttype ViewContainerElement,\n\ttype ViewDocumentMouseDownEvent,\n\ttype ViewSelectionChangeEvent\n} from '@ckeditor/ckeditor5-engine';\n\nimport type { EditorUIUpdateEvent } from '@ckeditor/ckeditor5-ui';\n\nimport {\n\tDomEmitterMixin,\n\tglobal,\n\ttype DomEmitter,\n\ttype EventInfo\n} from '@ckeditor/ckeditor5-utils';\n\nimport { throttle, type DebouncedFunc } from 'lodash-es';\n\nimport '../theme/widgetresize.css';\n\n/**\n * The widget resize feature plugin.\n *\n * Use the {@link module:widget/widgetresize~WidgetResize#attachTo} method to create a resizer for the specified widget.\n */\nexport default class WidgetResize extends Plugin {\n\t/**\n\t * The currently selected resizer.\n\t *\n\t * @observable\n\t */\n\tdeclare public selectedResizer: Resizer | null;\n\n\t/**\n\t * References an active resizer.\n\t *\n\t * Active resizer means a resizer which handle is actively used by the end user.\n\t *\n\t * @internal\n\t * @observable\n\t */\n\tdeclare public _activeResizer: Resizer | null;\n\n\t/**\n\t * A map of resizers created using this plugin instance.\n\t */\n\tprivate _resizers = new Map<ViewContainerElement, Resizer>();\n\n\tprivate _observer!: DomEmitter;\n\n\tprivate _redrawSelectedResizerThrottled!: DebouncedFunc<() => void>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'WidgetResize' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editing = this.editor.editing;\n\t\tconst domDocument = global.window.document;\n\n\t\tthis.set( 'selectedResizer', null );\n\t\tthis.set( '_activeResizer', null );\n\n\t\tediting.view.addObserver( MouseObserver );\n\n\t\tthis._observer = new ( DomEmitterMixin() )();\n\n\t\tthis.listenTo<ViewDocumentMouseDownEvent>(\n\t\t\tediting.view.document,\n\t\t\t'mousedown',\n\t\t\tthis._mouseDownListener.bind( this ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\n\t\tthis._observer.listenTo( domDocument, 'mousemove', this._mouseMoveListener.bind( this ) );\n\t\tthis._observer.listenTo( domDocument, 'mouseup', this._mouseUpListener.bind( this ) );\n\n\t\tthis._redrawSelectedResizerThrottled = throttle( () => this.redrawSelectedResizer(), 200 );\n\n\t\t// Redrawing on any change of the UI of the editor (including content changes).\n\t\tthis.editor.ui.on<EditorUIUpdateEvent>( 'update', this._redrawSelectedResizerThrottled );\n\n\t\t// Remove view widget-resizer mappings for widgets that have been removed from the document.\n\t\t// https://github.com/ckeditor/ckeditor5/issues/10156\n\t\t// https://github.com/ckeditor/ckeditor5/issues/10266\n\t\tthis.editor.model.document.on<DocumentChangeEvent>( 'change', () => {\n\t\t\tfor ( const [ viewElement, resizer ] of this._resizers ) {\n\t\t\t\tif ( !viewElement.isAttached() ) {\n\t\t\t\t\tthis._resizers.delete( viewElement );\n\t\t\t\t\tresizer.destroy();\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Resizers need to be redrawn upon window resize, because new window might shrink resize host.\n\t\tthis._observer.listenTo( global.window, 'resize', this._redrawSelectedResizerThrottled );\n\n\t\tconst viewSelection = this.editor.editing.view.document.selection;\n\n\t\tviewSelection.on<ViewSelectionChangeEvent>( 'change', () => {\n\t\t\tconst selectedElement = viewSelection.getSelectedElement() as ViewContainerElement;\n\n\t\t\tconst resizer = this.getResizerByViewElement( selectedElement ) || null;\n\t\t\tif ( resizer ) {\n\t\t\t\tthis.select( resizer );\n\t\t\t} else {\n\t\t\t\tthis.deselect();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Redraws the selected resizer if there is any selected resizer and if it is visible.\n\t */\n\tpublic redrawSelectedResizer(): void {\n\t\tif ( this.selectedResizer && this.selectedResizer.isVisible ) {\n\t\t\tthis.selectedResizer.redraw();\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis._observer.stopListening();\n\n\t\tfor ( const resizer of this._resizers.values() ) {\n\t\t\tresizer.destroy();\n\t\t}\n\n\t\tthis._redrawSelectedResizerThrottled.cancel();\n\t}\n\n\t/**\n\t * Marks resizer as selected.\n\t */\n\tpublic select( resizer: Resizer ): void {\n\t\tthis.deselect();\n\t\tthis.selectedResizer = resizer;\n\t\tthis.selectedResizer.isSelected = true;\n\t}\n\n\t/**\n\t * Deselects currently set resizer.\n\t */\n\tpublic deselect(): void {\n\t\tif ( this.selectedResizer ) {\n\t\t\tthis.selectedResizer.isSelected = false;\n\t\t}\n\n\t\tthis.selectedResizer = null;\n\t}\n\n\t/**\n\t * @param options Resizer options.\n\t */\n\tpublic attachTo( options: ResizerOptions ): Resizer {\n\t\tconst resizer = new Resizer( options );\n\t\tconst plugins = this.editor.plugins;\n\n\t\tresizer.attach();\n\n\t\tif ( plugins.has( 'WidgetToolbarRepository' ) ) {\n\t\t\t// Hiding widget toolbar to improve the performance\n\t\t\t// (https://github.com/ckeditor/ckeditor5-widget/pull/112#issuecomment-564528765).\n\t\t\tconst widgetToolbarRepository: WidgetToolbarRepository = plugins.get( 'WidgetToolbarRepository' );\n\n\t\t\tresizer.on<ResizerBeginEvent>( 'begin', () => {\n\t\t\t\twidgetToolbarRepository.forceDisabled( 'resize' );\n\t\t\t}, { priority: 'lowest' } );\n\n\t\t\tresizer.on<ResizerCancelEvent>( 'cancel', () => {\n\t\t\t\twidgetToolbarRepository.clearForceDisabled( 'resize' );\n\t\t\t}, { priority: 'highest' } );\n\n\t\t\tresizer.on<ResizerCommitEvent>( 'commit', () => {\n\t\t\t\twidgetToolbarRepository.clearForceDisabled( 'resize' );\n\t\t\t}, { priority: 'highest' } );\n\t\t}\n\n\t\tthis._resizers.set( options.viewElement, resizer );\n\n\t\tconst viewSelection = this.editor.editing.view.document.selection;\n\t\tconst selectedElement = viewSelection.getSelectedElement() as ViewContainerElement;\n\n\t\t// If the element the resizer is created for is currently focused, it should become visible.\n\t\tif ( this.getResizerByViewElement( selectedElement ) == resizer ) {\n\t\t\tthis.select( resizer );\n\t\t}\n\n\t\treturn resizer;\n\t}\n\n\t/**\n\t * Returns a resizer created for a given view element (widget element).\n\t *\n\t * @param viewElement View element associated with the resizer.\n\t */\n\tpublic getResizerByViewElement( viewElement: ViewContainerElement ): Resizer | undefined {\n\t\treturn this._resizers.get( viewElement );\n\t}\n\n\t/**\n\t * Returns a resizer that contains a given resize handle.\n\t */\n\tprivate _getResizerByHandle( domResizeHandle: HTMLElement ): Resizer | undefined {\n\t\tfor ( const resizer of this._resizers.values() ) {\n\t\t\tif ( resizer.containsHandle( domResizeHandle ) ) {\n\t\t\t\treturn resizer;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @param domEventData Native DOM event.\n\t */\n\tprivate _mouseDownListener( event: EventInfo, domEventData: DomEventData ) {\n\t\tconst resizeHandle = domEventData.domTarget;\n\n\t\tif ( !Resizer.isResizeHandle( resizeHandle ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._activeResizer = this._getResizerByHandle( resizeHandle ) || null;\n\n\t\tif ( this._activeResizer ) {\n\t\t\tthis._activeResizer.begin( resizeHandle );\n\n\t\t\t// Do not call other events when resizing. See: #6755.\n\t\t\tevent.stop();\n\t\t\tdomEventData.preventDefault();\n\t\t}\n\t}\n\n\t/**\n\t * @param domEventData Native DOM event.\n\t */\n\tprivate _mouseMoveListener( event: unknown, domEventData: MouseEvent ) {\n\t\tif ( this._activeResizer ) {\n\t\t\tthis._activeResizer.updateSize( domEventData );\n\t\t}\n\t}\n\n\tprivate _mouseUpListener(): void {\n\t\tif ( this._activeResizer ) {\n\t\t\tthis._activeResizer.commit();\n\t\t\tthis._activeResizer = null;\n\t\t}\n\t}\n}\n\n/**\n * Interface describing a resizer. It allows to specify the resizing host, custom logic for calculating aspect ratio, etc.\n */\nexport interface ResizerOptions {\n\n\t/**\n\t * Editor instance associated with the resizer.\n\t */\n\teditor: Editor;\n\n\tmodelElement: Element;\n\n\t/**\n\t * A view of an element to be resized. Typically it's the main widget's view instance.\n\t */\n\tviewElement: ViewContainerElement;\n\n\tunit?: 'px' | '%';\n\n\t/**\n\t * A callback to be executed once the resizing process is done.\n\t *\n\t * It receives a `Number` (`newValue`) as a parameter.\n\t *\n\t * For example, {@link module:image/imageresize~ImageResize} uses it to execute the resize image command\n\t * which puts the new value into the model.\n\t *\n\t * ```ts\n\t * {\n\t *\teditor,\n\t *\tmodelElement: data.item,\n\t *\tviewElement: widget,\n\t *\n\t *\tonCommit( newValue ) {\n\t *\t\teditor.execute( 'resizeImage', { width: newValue } );\n\t *\t}\n\t * };\n\t * ```\n\t */\n\tonCommit: ( newValue: string ) => void;\n\n\tgetResizeHost: ( widgetWrapper: HTMLElement ) => HTMLElement;\n\n\tgetHandleHost: ( widgetWrapper: HTMLElement ) => HTMLElement;\n\n\tisCentered?: ( resizer: Resizer ) => boolean;\n}\n", "import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { EventInfo, getRangeFromMouseEvent, uid, toUnit, delay, DomEmitterMixin, global, Rect, ResizeObserver, env, createElement } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { DomEventObserver, DataTransfer, Range, MouseObserver, LiveRange } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { mapValues, throttle } from 'lodash-es';\nimport { Widget, isWidget } from '@ckeditor/ckeditor5-widget/dist/index.js';\nimport { View } from '@ckeditor/ckeditor5-ui/dist/index.js';\n\n/**\n * Clipboard events observer.\n *\n * Fires the following events:\n *\n * * {@link module:engine/view/document~Document#event:clipboardInput},\n * * {@link module:engine/view/document~Document#event:paste},\n * * {@link module:engine/view/document~Document#event:copy},\n * * {@link module:engine/view/document~Document#event:cut},\n * * {@link module:engine/view/document~Document#event:drop},\n * * {@link module:engine/view/document~Document#event:dragover},\n * * {@link module:engine/view/document~Document#event:dragging},\n * * {@link module:engine/view/document~Document#event:dragstart},\n * * {@link module:engine/view/document~Document#event:dragend},\n * * {@link module:engine/view/document~Document#event:dragenter},\n * * {@link module:engine/view/document~Document#event:dragleave}.\n *\n * **Note**: This observer is not available by default (ckeditor5-engine does not add it on its own).\n * To make it available, it needs to be added to {@link module:engine/view/document~Document} by using\n * the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. Alternatively, you can load the\n * {@link module:clipboard/clipboard~Clipboard} plugin which adds this observer automatically (because it uses it).\n */ class ClipboardObserver extends DomEventObserver {\n    domEventType = [\n        'paste',\n        'copy',\n        'cut',\n        'drop',\n        'dragover',\n        'dragstart',\n        'dragend',\n        'dragenter',\n        'dragleave'\n    ];\n    constructor(view){\n        super(view);\n        const viewDocument = this.document;\n        this.listenTo(viewDocument, 'paste', handleInput('clipboardInput'), {\n            priority: 'low'\n        });\n        this.listenTo(viewDocument, 'drop', handleInput('clipboardInput'), {\n            priority: 'low'\n        });\n        this.listenTo(viewDocument, 'dragover', handleInput('dragging'), {\n            priority: 'low'\n        });\n        function handleInput(type) {\n            return (evt, data)=>{\n                data.preventDefault();\n                const targetRanges = data.dropRange ? [\n                    data.dropRange\n                ] : null;\n                const eventInfo = new EventInfo(viewDocument, type);\n                viewDocument.fire(eventInfo, {\n                    dataTransfer: data.dataTransfer,\n                    method: evt.name,\n                    targetRanges,\n                    target: data.target,\n                    domEvent: data.domEvent\n                });\n                // If CKEditor handled the input, do not bubble the original event any further.\n                // This helps external integrations recognize that fact and act accordingly.\n                // https://github.com/ckeditor/ckeditor5-upload/issues/92\n                if (eventInfo.stop.called) {\n                    data.stopPropagation();\n                }\n            };\n        }\n    }\n    onDomEvent(domEvent) {\n        const nativeDataTransfer = 'clipboardData' in domEvent ? domEvent.clipboardData : domEvent.dataTransfer;\n        const cacheFiles = domEvent.type == 'drop' || domEvent.type == 'paste';\n        const evtData = {\n            dataTransfer: new DataTransfer(nativeDataTransfer, {\n                cacheFiles\n            })\n        };\n        if (domEvent.type == 'drop' || domEvent.type == 'dragover') {\n            const domRange = getRangeFromMouseEvent(domEvent);\n            evtData.dropRange = domRange && this.view.domConverter.domRangeToView(domRange);\n        }\n        this.fire(domEvent.type, domEvent, evtData);\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module clipboard/utils/plaintexttohtml\n */ /**\n * Converts plain text to its HTML-ized version.\n *\n * @param text The plain text to convert.\n * @returns HTML generated from the plain text.\n */ function plainTextToHtml(text) {\n    text = text// Encode &.\n    .replace(/&/g, '&amp;')// Encode <>.\n    .replace(/</g, '&lt;').replace(/>/g, '&gt;')// Creates a paragraph for each double line break.\n    .replace(/\\r?\\n\\r?\\n/g, '</p><p>')// Creates a line break for each single line break.\n    .replace(/\\r?\\n/g, '<br>')// Replace tabs with four spaces.\n    .replace(/\\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')// Preserve trailing spaces (only the first and last one – the rest is handled below).\n    .replace(/^\\s/, '&nbsp;').replace(/\\s$/, '&nbsp;')// Preserve other subsequent spaces now.\n    .replace(/\\s\\s/g, ' &nbsp;');\n    if (text.includes('</p><p>') || text.includes('<br>')) {\n        // If we created paragraphs above, add the trailing ones.\n        text = `<p>${text}</p>`;\n    }\n    // TODO:\n    // * What about '\\nfoo' vs ' foo'?\n    return text;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module clipboard/utils/normalizeclipboarddata\n */ /**\n * Removes some popular browser quirks out of the clipboard data (HTML).\n * Removes all HTML comments. These are considered an internal thing and it makes little sense if they leak into the editor data.\n *\n * @param data The HTML data to normalize.\n * @returns Normalized HTML.\n */ function normalizeClipboardData(data) {\n    return data.replace(/<span(?: class=\"Apple-converted-space\"|)>(\\s+)<\\/span>/g, (fullMatch, spaces)=>{\n        // Handle the most popular and problematic case when even a single space becomes an nbsp;.\n        // Decode those to normal spaces. Read more in https://github.com/ckeditor/ckeditor5-clipboard/issues/2.\n        if (spaces.length == 1) {\n            return ' ';\n        }\n        return spaces;\n    })// Remove all HTML comments.\n    .replace(/<!--[\\s\\S]*?-->/g, '');\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module clipboard/utils/viewtoplaintext\n */ // Elements which should not have empty-line padding.\n// Most `view.ContainerElement` want to be separate by new-line, but some are creating one structure\n// together (like `<li>`) so it is better to separate them by only one \"\\n\".\nconst smallPaddingElements = [\n    'figcaption',\n    'li'\n];\nconst listElements = [\n    'ol',\n    'ul'\n];\n/**\n * Converts {@link module:engine/view/item~Item view item} and all of its children to plain text.\n *\n * @param viewItem View item to convert.\n * @returns Plain text representation of `viewItem`.\n */ function viewToPlainText(viewItem) {\n    if (viewItem.is('$text') || viewItem.is('$textProxy')) {\n        return viewItem.data;\n    }\n    if (viewItem.is('element', 'img') && viewItem.hasAttribute('alt')) {\n        return viewItem.getAttribute('alt');\n    }\n    if (viewItem.is('element', 'br')) {\n        return '\\n'; // Convert soft breaks to single line break (#8045).\n    }\n    /**\n\t * Item is a document fragment, attribute element or container element. It doesn't\n\t * have it's own text value, so we need to convert its children elements.\n\t */ let text = '';\n    let prev = null;\n    for (const child of viewItem.getChildren()){\n        text += newLinePadding(child, prev) + viewToPlainText(child);\n        prev = child;\n    }\n    return text;\n}\n/**\n * Returns new line padding to prefix the given elements with.\n */ function newLinePadding(element, previous) {\n    if (!previous) {\n        // Don't add padding to first elements in a level.\n        return '';\n    }\n    if (element.is('element', 'li') && !element.isEmpty && element.getChild(0).is('containerElement')) {\n        // Separate document list items with empty lines.\n        return '\\n\\n';\n    }\n    if (listElements.includes(element.name) && listElements.includes(previous.name)) {\n        /**\n\t\t * Because `<ul>` and `<ol>` are AttributeElements, two consecutive lists will not have any padding between\n\t\t * them (see the `if` statement below). To fix this, we need to make an exception for this case.\n\t\t */ return '\\n\\n';\n    }\n    if (!element.is('containerElement') && !previous.is('containerElement')) {\n        // Don't add padding between non-container elements.\n        return '';\n    }\n    if (smallPaddingElements.includes(element.name) || smallPaddingElements.includes(previous.name)) {\n        // Add small padding between selected container elements.\n        return '\\n';\n    }\n    // Do not add padding around the elements that won't be rendered.\n    if (element.is('element') && element.getCustomProperty('dataPipeline:transparentRendering') || previous.is('element') && previous.getCustomProperty('dataPipeline:transparentRendering')) {\n        return '';\n    }\n    // Add empty lines between container elements.\n    return '\\n\\n';\n}\n\n/**\n * Part of the clipboard logic. Responsible for collecting markers from selected fragments\n * and restoring them with proper positions in pasted elements.\n *\n * @internal\n */ class ClipboardMarkersUtils extends Plugin {\n    /**\n\t * Map of marker names that can be copied.\n\t *\n\t * @internal\n\t */ _markersToCopy = new Map();\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ClipboardMarkersUtils';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * Registers marker name as copyable in clipboard pipeline.\n\t *\n\t * @param markerName Name of marker that can be copied.\n\t * @param config Configuration that describes what can be performed on specified marker.\n\t * @internal\n\t */ _registerMarkerToCopy(markerName, config) {\n        this._markersToCopy.set(markerName, config);\n    }\n    /**\n\t * Performs copy markers on provided selection and paste it to fragment returned from `getCopiedFragment`.\n\t *\n\t * \t1. Picks all markers in provided selection.\n\t * \t2. Inserts fake markers to document.\n\t * \t3. Gets copied selection fragment from document.\n\t * \t4. Removes fake elements from fragment and document.\n\t * \t5. Inserts markers in the place of removed fake markers.\n\t *\n\t * Due to selection modification, when inserting items, `getCopiedFragment` must *always* operate on `writer.model.document.selection'.\n\t * Do not use any other custom selection object within callback, as this will lead to out-of-bounds exceptions in rare scenarios.\n\t *\n\t * @param action Type of clipboard action.\n\t * @param writer An instance of the model writer.\n\t * @param selection Selection to be checked.\n\t * @param getCopiedFragment\tCallback that performs copy of selection and returns it as fragment.\n\t * @internal\n\t */ _copySelectedFragmentWithMarkers(action, selection, getCopiedFragment = (writer)=>writer.model.getSelectedContent(writer.model.document.selection)) {\n        return this.editor.model.change((writer)=>{\n            const oldSelection = writer.model.document.selection;\n            // In some scenarios, such like in drag & drop, passed `selection` parameter is not actually\n            // the same `selection` as the `writer.model.document.selection` which means that `_insertFakeMarkersToSelection`\n            // is not affecting passed `selection` `start` and `end` positions but rather modifies `writer.model.document.selection`.\n            //\n            // It is critical due to fact that when we have selection that starts [ 0, 0 ] and ends at [ 1, 0 ]\n            // and after inserting fake marker it will point to such marker instead of new widget position at start: [ 1, 0 ] end: [2, 0 ].\n            // `writer.insert` modifies only original `writer.model.document.selection`.\n            writer.setSelection(selection);\n            const sourceSelectionInsertedMarkers = this._insertFakeMarkersIntoSelection(writer, writer.model.document.selection, action);\n            const fragment = getCopiedFragment(writer);\n            const fakeMarkersRangesInsideRange = this._removeFakeMarkersInsideElement(writer, fragment);\n            // <fake-marker> [Foo] Bar</fake-marker>\n            //      ^                    ^\n            // In `_insertFakeMarkersIntoSelection` call we inserted fake marker just before first element.\n            // The problem is that the first element can be start position of selection so insertion fake-marker\n            // before such element shifts selection (so selection that was at [0, 0] now is at [0, 1]).\n            // It means that inserted fake-marker is no longer present inside such selection and is orphaned.\n            // This function checks special case of such problem. Markers that are orphaned at the start position\n            // and end position in the same time. Basically it means that they overlaps whole element.\n            for (const [markerName, elements] of Object.entries(sourceSelectionInsertedMarkers)){\n                fakeMarkersRangesInsideRange[markerName] ||= writer.createRangeIn(fragment);\n                for (const element of elements){\n                    writer.remove(element);\n                }\n            }\n            fragment.markers.clear();\n            for (const [markerName, range] of Object.entries(fakeMarkersRangesInsideRange)){\n                fragment.markers.set(markerName, range);\n            }\n            // Revert back selection to previous one.\n            writer.setSelection(oldSelection);\n            return fragment;\n        });\n    }\n    /**\n\t * Performs paste of markers on already pasted element.\n\t *\n\t * \t1. Inserts fake markers that are present in fragment element (such fragment will be processed in `getPastedDocumentElement`).\n\t * \t2. Calls `getPastedDocumentElement` and gets element that is inserted into root model.\n\t * \t3. Removes all fake markers present in transformed element.\n\t * \t4. Inserts new markers with removed fake markers ranges into pasted fragment.\n\t *\n\t * There are multiple edge cases that have to be considered before calling this function:\n\t *\n\t * \t* `markers` are inserted into the same element that must be later transformed inside `getPastedDocumentElement`.\n\t * \t* Fake marker elements inside `getPastedDocumentElement` can be cloned, but their ranges cannot overlap.\n\t * \t* If `duplicateOnPaste` is `true` in marker config then associated marker ID is regenerated before pasting.\n\t *\n\t * @param action Type of clipboard action.\n\t * @param markers Object that maps marker name to corresponding range.\n\t * @param getPastedDocumentElement Getter used to get target markers element.\n\t * @internal\n\t */ _pasteMarkersIntoTransformedElement(markers, getPastedDocumentElement) {\n        const pasteMarkers = this._getPasteMarkersFromRangeMap(markers);\n        return this.editor.model.change((writer)=>{\n            // Inserts fake markers into source fragment / element that is later transformed inside `getPastedDocumentElement`.\n            const sourceFragmentFakeMarkers = this._insertFakeMarkersElements(writer, pasteMarkers);\n            // Modifies document fragment (for example, cloning table cells) and then inserts it into the document.\n            const transformedElement = getPastedDocumentElement(writer);\n            // Removes markers in pasted and transformed fragment in root document.\n            const removedFakeMarkers = this._removeFakeMarkersInsideElement(writer, transformedElement);\n            // Cleans up fake markers inserted into source fragment (that one before transformation which is not pasted).\n            for (const element of Object.values(sourceFragmentFakeMarkers).flat()){\n                writer.remove(element);\n            }\n            // Inserts to root document fake markers.\n            for (const [markerName, range] of Object.entries(removedFakeMarkers)){\n                if (!writer.model.markers.has(markerName)) {\n                    writer.addMarker(markerName, {\n                        usingOperation: true,\n                        affectsData: true,\n                        range\n                    });\n                }\n            }\n            return transformedElement;\n        });\n    }\n    /**\n\t * Pastes document fragment with markers to document.\n\t * If `duplicateOnPaste` is `true` in marker config then associated markers IDs\n\t * are regenerated before pasting to avoid markers duplications in content.\n\t *\n\t * @param fragment Document fragment that should contain already processed by pipeline markers.\n\t * @internal\n\t */ _pasteFragmentWithMarkers(fragment) {\n        const pasteMarkers = this._getPasteMarkersFromRangeMap(fragment.markers);\n        fragment.markers.clear();\n        for (const copyableMarker of pasteMarkers){\n            fragment.markers.set(copyableMarker.name, copyableMarker.range);\n        }\n        return this.editor.model.insertContent(fragment);\n    }\n    /**\n\t * In some situations we have to perform copy on selected fragment with certain markers. This function allows to temporarily bypass\n\t * restrictions on markers that we want to copy.\n\t *\n\t * This function executes `executor()` callback. For the duration of the callback, if the clipboard pipeline is used to copy\n\t * content, markers with the specified name will be copied to the clipboard as well.\n\t *\n\t * @param markerName Which markers should be copied.\n\t * @param executor Callback executed.\n\t * @param config Optional configuration flags used to copy (such like partial copy flag).\n\t * @internal\n\t */ _forceMarkersCopy(markerName, executor, config = {\n        allowedActions: 'all',\n        copyPartiallySelected: true,\n        duplicateOnPaste: true\n    }) {\n        const before = this._markersToCopy.get(markerName);\n        this._markersToCopy.set(markerName, config);\n        executor();\n        if (before) {\n            this._markersToCopy.set(markerName, before);\n        } else {\n            this._markersToCopy.delete(markerName);\n        }\n    }\n    /**\n\t * Checks if marker can be copied.\n\t *\n\t * @param markerName Name of checked marker.\n\t * @param action Type of clipboard action. If null then checks only if marker is registered as copyable.\n\t * @internal\n\t */ _isMarkerCopyable(markerName, action) {\n        const config = this._getMarkerClipboardConfig(markerName);\n        if (!config) {\n            return false;\n        }\n        // If there is no action provided then only presence of marker is checked.\n        if (!action) {\n            return true;\n        }\n        const { allowedActions } = config;\n        return allowedActions === 'all' || allowedActions.includes(action);\n    }\n    /**\n\t * Checks if marker has any clipboard copy behavior configuration.\n\t *\n\t * @param markerName Name of checked marker.\n\t */ _hasMarkerConfiguration(markerName) {\n        return !!this._getMarkerClipboardConfig(markerName);\n    }\n    /**\n\t * Returns marker's configuration flags passed during registration.\n\t *\n\t * @param markerName Name of marker that should be returned.\n\t * @internal\n\t */ _getMarkerClipboardConfig(markerName) {\n        const [markerNamePrefix] = markerName.split(':');\n        return this._markersToCopy.get(markerNamePrefix) || null;\n    }\n    /**\n\t * First step of copying markers. It looks for markers intersecting with given selection and inserts `$marker` elements\n\t * at positions where document markers start or end. This way `$marker` elements can be easily copied together with\n\t * the rest of the content of the selection.\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param selection Selection to be checked.\n\t * @param action Type of clipboard action.\n\t */ _insertFakeMarkersIntoSelection(writer, selection, action) {\n        const copyableMarkers = this._getCopyableMarkersFromSelection(writer, selection, action);\n        return this._insertFakeMarkersElements(writer, copyableMarkers);\n    }\n    /**\n\t * Returns array of markers that can be copied in specified selection.\n\t *\n\t * If marker cannot be copied partially (according to `copyPartiallySelected` configuration flag) and\n\t * is not present entirely in any selection range then it will be skipped.\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param selection  Selection which will be checked.\n\t * @param action Type of clipboard action. If null then checks only if marker is registered as copyable.\n\t */ _getCopyableMarkersFromSelection(writer, selection, action) {\n        const selectionRanges = Array.from(selection.getRanges());\n        // Picks all markers in provided ranges. Ensures that there are no duplications if\n        // there are multiple ranges that intersects with the same marker.\n        const markersInRanges = new Set(selectionRanges.flatMap((selectionRange)=>Array.from(writer.model.markers.getMarkersIntersectingRange(selectionRange))));\n        const isSelectionMarkerCopyable = (marker)=>{\n            // Check if marker exists in configuration and provided action can be performed on it.\n            const isCopyable = this._isMarkerCopyable(marker.name, action);\n            if (!isCopyable) {\n                return false;\n            }\n            // Checks if configuration disallows to copy marker only if part of its content is selected.\n            //\n            // Example:\n            // \t<marker-a> Hello [ World ] </marker-a>\n            //\t\t\t\t\t\t^ selection\n            //\n            // In this scenario `marker-a` won't be copied because selection doesn't overlap its content entirely.\n            const { copyPartiallySelected } = this._getMarkerClipboardConfig(marker.name);\n            if (!copyPartiallySelected) {\n                const markerRange = marker.getRange();\n                return selectionRanges.some((selectionRange)=>selectionRange.containsRange(markerRange, true));\n            }\n            return true;\n        };\n        return Array.from(markersInRanges).filter(isSelectionMarkerCopyable).map((copyableMarker)=>{\n            // During `dragstart` event original marker is still present in tree.\n            // It is removed after the clipboard drop event, so none of the copied markers are inserted at the end.\n            // It happens because there already markers with specified `marker.name` when clipboard is trying to insert data\n            // and it aborts inserting.\n            const name = action === 'dragstart' ? this._getUniqueMarkerName(copyableMarker.name) : copyableMarker.name;\n            return {\n                name,\n                range: copyableMarker.getRange()\n            };\n        });\n    }\n    /**\n\t * Picks all markers from markers map that can be pasted.\n\t * If `duplicateOnPaste` is `true`, it regenerates their IDs to ensure uniqueness.\n\t * If marker is not registered, it will be kept in the array anyway.\n\t *\n\t * @param markers Object that maps marker name to corresponding range.\n\t * @param action Type of clipboard action. If null then checks only if marker is registered as copyable.\n\t */ _getPasteMarkersFromRangeMap(markers, action = null) {\n        const { model } = this.editor;\n        const entries = markers instanceof Map ? Array.from(markers.entries()) : Object.entries(markers);\n        return entries.flatMap(([markerName, range])=>{\n            if (!this._hasMarkerConfiguration(markerName)) {\n                return [\n                    {\n                        name: markerName,\n                        range\n                    }\n                ];\n            }\n            if (this._isMarkerCopyable(markerName, action)) {\n                const copyMarkerConfig = this._getMarkerClipboardConfig(markerName);\n                const isInGraveyard = model.markers.has(markerName) && model.markers.get(markerName).getRange().root.rootName === '$graveyard';\n                if (copyMarkerConfig.duplicateOnPaste || isInGraveyard) {\n                    markerName = this._getUniqueMarkerName(markerName);\n                }\n                return [\n                    {\n                        name: markerName,\n                        range\n                    }\n                ];\n            }\n            return [];\n        });\n    }\n    /**\n\t * Inserts specified array of fake markers elements to document and assigns them `type` and `name` attributes.\n\t * Fake markers elements are used to calculate position of markers on pasted fragment that were transformed during\n\t * steps between copy and paste.\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param markers Array of markers that will be inserted.\n\t */ _insertFakeMarkersElements(writer, markers) {\n        const mappedMarkers = {};\n        const sortedMarkers = markers.flatMap((marker)=>{\n            const { start, end } = marker.range;\n            return [\n                {\n                    position: start,\n                    marker,\n                    type: 'start'\n                },\n                {\n                    position: end,\n                    marker,\n                    type: 'end'\n                }\n            ];\n        })// Markers position is sorted backwards to ensure that the insertion of fake markers will not change\n        // the position of the next markers.\n        .sort(({ position: posA }, { position: posB })=>posA.isBefore(posB) ? 1 : -1);\n        for (const { position, marker, type } of sortedMarkers){\n            const fakeMarker = writer.createElement('$marker', {\n                'data-name': marker.name,\n                'data-type': type\n            });\n            if (!mappedMarkers[marker.name]) {\n                mappedMarkers[marker.name] = [];\n            }\n            mappedMarkers[marker.name].push(fakeMarker);\n            writer.insert(fakeMarker, position);\n        }\n        return mappedMarkers;\n    }\n    /**\n\t * Removes all `$marker` elements from the given document fragment.\n\t *\n\t * Returns an object where keys are marker names, and values are ranges corresponding to positions\n\t * where `$marker` elements were inserted.\n\t *\n\t * If the document fragment had only one `$marker` element for given marker (start or end) the other boundary is set automatically\n\t * (to the end or start of the document fragment, respectively).\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param rootElement The element to be checked.\n\t */ _removeFakeMarkersInsideElement(writer, rootElement) {\n        const fakeMarkersElements = this._getAllFakeMarkersFromElement(writer, rootElement);\n        const fakeMarkersRanges = fakeMarkersElements.reduce((acc, fakeMarker)=>{\n            const position = fakeMarker.markerElement && writer.createPositionBefore(fakeMarker.markerElement);\n            let prevFakeMarker = acc[fakeMarker.name];\n            // Handle scenario when tables clone cells with the same fake node. Example:\n            //\n            // <cell><fake-marker-a></cell> <cell><fake-marker-a></cell> <cell><fake-marker-a></cell>\n            //                                          ^ cloned                    ^ cloned\n            //\n            // The easiest way to bypass this issue is to rename already existing in map nodes and\n            // set them new unique name.\n            let skipAssign = false;\n            if (prevFakeMarker && prevFakeMarker.start && prevFakeMarker.end) {\n                const config = this._getMarkerClipboardConfig(fakeMarker.name);\n                if (config.duplicateOnPaste) {\n                    acc[this._getUniqueMarkerName(fakeMarker.name)] = acc[fakeMarker.name];\n                } else {\n                    skipAssign = true;\n                }\n                prevFakeMarker = null;\n            }\n            if (!skipAssign) {\n                acc[fakeMarker.name] = {\n                    ...prevFakeMarker,\n                    [fakeMarker.type]: position\n                };\n            }\n            if (fakeMarker.markerElement) {\n                writer.remove(fakeMarker.markerElement);\n            }\n            return acc;\n        }, {});\n        // We cannot construct ranges directly in previous reduce because element ranges can overlap.\n        // In other words lets assume we have such scenario:\n        // <fake-marker-start /> <paragraph /> <fake-marker-2-start /> <fake-marker-end /> <fake-marker-2-end />\n        //\n        // We have to remove `fake-marker-start` firstly and then remove `fake-marker-2-start`.\n        // Removal of `fake-marker-2-start` affects `fake-marker-end` position so we cannot create\n        // connection between `fake-marker-start` and `fake-marker-end` without iterating whole set firstly.\n        return mapValues(fakeMarkersRanges, (range)=>new Range(range.start || writer.createPositionFromPath(rootElement, [\n                0\n            ]), range.end || writer.createPositionAt(rootElement, 'end')));\n    }\n    /**\n\t * Returns array that contains list of fake markers with corresponding `$marker` elements.\n\t *\n\t * For each marker, there can be two `$marker` elements or only one (if the document fragment contained\n\t * only the beginning or only the end of a marker).\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param rootElement The element to be checked.\n\t */ _getAllFakeMarkersFromElement(writer, rootElement) {\n        const foundFakeMarkers = Array.from(writer.createRangeIn(rootElement)).flatMap(({ item })=>{\n            if (!item.is('element', '$marker')) {\n                return [];\n            }\n            const name = item.getAttribute('data-name');\n            const type = item.getAttribute('data-type');\n            return [\n                {\n                    markerElement: item,\n                    name,\n                    type\n                }\n            ];\n        });\n        const prependFakeMarkers = [];\n        const appendFakeMarkers = [];\n        for (const fakeMarker of foundFakeMarkers){\n            if (fakeMarker.type === 'end') {\n                // <fake-marker> [ phrase</fake-marker> phrase ]\n                //   ^\n                // Handle case when marker is just before start of selection.\n                // Only end marker is inside selection.\n                const hasMatchingStartMarker = foundFakeMarkers.some((otherFakeMarker)=>otherFakeMarker.name === fakeMarker.name && otherFakeMarker.type === 'start');\n                if (!hasMatchingStartMarker) {\n                    prependFakeMarkers.push({\n                        markerElement: null,\n                        name: fakeMarker.name,\n                        type: 'start'\n                    });\n                }\n            }\n            if (fakeMarker.type === 'start') {\n                // [<fake-marker>phrase]</fake-marker>\n                //                           ^\n                // Handle case when fake marker is after selection.\n                // Only start marker is inside selection.\n                const hasMatchingEndMarker = foundFakeMarkers.some((otherFakeMarker)=>otherFakeMarker.name === fakeMarker.name && otherFakeMarker.type === 'end');\n                if (!hasMatchingEndMarker) {\n                    appendFakeMarkers.unshift({\n                        markerElement: null,\n                        name: fakeMarker.name,\n                        type: 'end'\n                    });\n                }\n            }\n        }\n        return [\n            ...prependFakeMarkers,\n            ...foundFakeMarkers,\n            ...appendFakeMarkers\n        ];\n    }\n    /**\n\t * When copy of markers occurs we have to make sure that pasted markers have different names\n\t * than source markers. This functions helps with assigning unique part to marker name to\n\t * prevent duplicated markers error.\n\t *\n\t * @param name Name of marker\n\t */ _getUniqueMarkerName(name) {\n        const parts = name.split(':');\n        const newId = uid().substring(1, 6);\n        // It looks like the marker already is UID marker so in this scenario just swap\n        // last part of marker name and assign new UID.\n        //\n        // example: comment:{ threadId }:{ id } => comment:{ threadId }:{ newId }\n        if (parts.length === 3) {\n            return `${parts.slice(0, 2).join(':')}:${newId}`;\n        }\n        // Assign new segment to marker name with id.\n        //\n        // example: comment => comment:{ newId }\n        return `${parts.join(':')}:${newId}`;\n    }\n}\n\n// Input pipeline events overview:\n//\n//              ┌──────────────────────┐          ┌──────────────────────┐\n//              │     view.Document    │          │     view.Document    │\n//              │         paste        │          │         drop         │\n//              └───────────┬──────────┘          └───────────┬──────────┘\n//                          │                                 │\n//                          └────────────────┌────────────────┘\n//                                           │\n//                                 ┌─────────V────────┐\n//                                 │   view.Document  │   Retrieves text/html or text/plain from data.dataTransfer\n//                                 │  clipboardInput  │   and processes it to view.DocumentFragment.\n//                                 └─────────┬────────┘\n//                                           │\n//                               ┌───────────V───────────┐\n//                               │   ClipboardPipeline   │   Converts view.DocumentFragment to model.DocumentFragment.\n//                               │  inputTransformation  │\n//                               └───────────┬───────────┘\n//                                           │\n//                                ┌──────────V──────────┐\n//                                │  ClipboardPipeline  │   Calls model.insertContent().\n//                                │   contentInsertion  │\n//                                └─────────────────────┘\n//\n//\n// Output pipeline events overview:\n//\n//              ┌──────────────────────┐          ┌──────────────────────┐\n//              │     view.Document    │          │     view.Document    │   Retrieves the selected model.DocumentFragment\n//              │         copy         │          │          cut         │   and fires the `outputTransformation` event.\n//              └───────────┬──────────┘          └───────────┬──────────┘\n//                          │                                 │\n//                          └────────────────┌────────────────┘\n//                                           │\n//                               ┌───────────V───────────┐\n//                               │   ClipboardPipeline   │   Processes model.DocumentFragment and converts it to\n//                               │  outputTransformation │   view.DocumentFragment.\n//                               └───────────┬───────────┘\n//                                           │\n//                                 ┌─────────V────────┐\n//                                 │   view.Document  │   Processes view.DocumentFragment to text/html and text/plain\n//                                 │  clipboardOutput │   and stores the results in data.dataTransfer.\n//                                 └──────────────────┘\n//\n/**\n * The clipboard pipeline feature. It is responsible for intercepting the `paste` and `drop` events and\n * passing the pasted content through a series of events in order to insert it into the editor's content.\n * It also handles the `cut` and `copy` events to fill the native clipboard with the serialized editor's data.\n *\n * # Input pipeline\n *\n * The behavior of the default handlers (all at a `low` priority):\n *\n * ## Event: `paste` or `drop`\n *\n * 1. Translates the event data.\n * 2. Fires the {@link module:engine/view/document~Document#event:clipboardInput `view.Document#clipboardInput`} event.\n *\n * ## Event: `view.Document#clipboardInput`\n *\n * 1. If the `data.content` event field is already set (by some listener on a higher priority), it takes this content and fires the event\n *    from the last point.\n * 2. Otherwise, it retrieves `text/html` or `text/plain` from `data.dataTransfer`.\n * 3. Normalizes the raw data by applying simple filters on string data.\n * 4. Processes the raw data to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} with the\n *    {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.\n * 5. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation\n *   `ClipboardPipeline#inputTransformation`} event with the view document fragment in the `data.content` event field.\n *\n * ## Event: `ClipboardPipeline#inputTransformation`\n *\n * 1. Converts {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} from the `data.content` field to\n *    {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`}.\n * 2. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:contentInsertion `ClipboardPipeline#contentInsertion`}\n *    event with the model document fragment in the `data.content` event field.\n *    **Note**: The `ClipboardPipeline#contentInsertion` event is fired within a model change block to allow other handlers\n *    to run in the same block without post-fixers called in between (i.e., the selection post-fixer).\n *\n * ## Event: `ClipboardPipeline#contentInsertion`\n *\n * 1. Calls {@link module:engine/model/model~Model#insertContent `model.insertContent()`} to insert `data.content`\n *    at the current selection position.\n *\n * # Output pipeline\n *\n * The behavior of the default handlers (all at a `low` priority):\n *\n * ## Event: `copy`, `cut` or `dragstart`\n *\n * 1. Retrieves the selected {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`} by calling\n *    {@link module:engine/model/model~Model#getSelectedContent `model#getSelectedContent()`}.\n * 2. Converts the model document fragment to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`}.\n * 3. Fires the {@link module:engine/view/document~Document#event:clipboardOutput `view.Document#clipboardOutput`} event\n *    with the view document fragment in the `data.content` event field.\n *\n * ## Event: `view.Document#clipboardOutput`\n *\n * 1. Processes `data.content` to HTML and plain text with the\n *    {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.\n * 2. Updates the `data.dataTransfer` data for `text/html` and `text/plain` with the processed data.\n * 3. For the `cut` method, calls {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`}\n *    on the current selection.\n *\n * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n */ class ClipboardPipeline extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ClipboardPipeline';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ClipboardMarkersUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        view.addObserver(ClipboardObserver);\n        this._setupPasteDrop();\n        this._setupCopyCut();\n    }\n    /**\n\t * Fires Clipboard `'outputTransformation'` event for given parameters.\n\t *\n\t * @internal\n\t */ _fireOutputTransformationEvent(dataTransfer, selection, method) {\n        const clipboardMarkersUtils = this.editor.plugins.get('ClipboardMarkersUtils');\n        this.editor.model.enqueueChange({\n            isUndoable: method === 'cut'\n        }, ()=>{\n            const documentFragment = clipboardMarkersUtils._copySelectedFragmentWithMarkers(method, selection);\n            this.fire('outputTransformation', {\n                dataTransfer,\n                content: documentFragment,\n                method\n            });\n        });\n    }\n    /**\n\t * The clipboard paste pipeline.\n\t */ _setupPasteDrop() {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const clipboardMarkersUtils = this.editor.plugins.get('ClipboardMarkersUtils');\n        // Pasting is disabled when selection is in non-editable place.\n        // Dropping is disabled in drag and drop handler.\n        this.listenTo(viewDocument, 'clipboardInput', (evt, data)=>{\n            if (data.method == 'paste' && !editor.model.canEditAt(editor.model.document.selection)) {\n                evt.stop();\n            }\n        }, {\n            priority: 'highest'\n        });\n        this.listenTo(viewDocument, 'clipboardInput', (evt, data)=>{\n            const dataTransfer = data.dataTransfer;\n            let content;\n            // Some feature could already inject content in the higher priority event handler (i.e., codeBlock).\n            if (data.content) {\n                content = data.content;\n            } else {\n                let contentData = '';\n                if (dataTransfer.getData('text/html')) {\n                    contentData = normalizeClipboardData(dataTransfer.getData('text/html'));\n                } else if (dataTransfer.getData('text/plain')) {\n                    contentData = plainTextToHtml(dataTransfer.getData('text/plain'));\n                }\n                content = this.editor.data.htmlProcessor.toView(contentData);\n            }\n            const eventInfo = new EventInfo(this, 'inputTransformation');\n            this.fire(eventInfo, {\n                content,\n                dataTransfer,\n                targetRanges: data.targetRanges,\n                method: data.method\n            });\n            // If CKEditor handled the input, do not bubble the original event any further.\n            // This helps external integrations recognize this fact and act accordingly.\n            // https://github.com/ckeditor/ckeditor5-upload/issues/92\n            if (eventInfo.stop.called) {\n                evt.stop();\n            }\n            view.scrollToTheSelection();\n        }, {\n            priority: 'low'\n        });\n        this.listenTo(this, 'inputTransformation', (evt, data)=>{\n            if (data.content.isEmpty) {\n                return;\n            }\n            const dataController = this.editor.data;\n            // Convert the pasted content into a model document fragment.\n            // The conversion is contextual, but in this case an \"all allowed\" context is needed\n            // and for that we use the $clipboardHolder item.\n            const modelFragment = dataController.toModel(data.content, '$clipboardHolder');\n            if (modelFragment.childCount == 0) {\n                return;\n            }\n            evt.stop();\n            // Fire content insertion event in a single change block to allow other handlers to run in the same block\n            // without post-fixers called in between (i.e., the selection post-fixer).\n            model.change(()=>{\n                this.fire('contentInsertion', {\n                    content: modelFragment,\n                    method: data.method,\n                    dataTransfer: data.dataTransfer,\n                    targetRanges: data.targetRanges\n                });\n            });\n        }, {\n            priority: 'low'\n        });\n        this.listenTo(this, 'contentInsertion', (evt, data)=>{\n            data.resultRange = clipboardMarkersUtils._pasteFragmentWithMarkers(data.content);\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * The clipboard copy/cut pipeline.\n\t */ _setupCopyCut() {\n        const editor = this.editor;\n        const modelDocument = editor.model.document;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const onCopyCut = (evt, data)=>{\n            const dataTransfer = data.dataTransfer;\n            data.preventDefault();\n            this._fireOutputTransformationEvent(dataTransfer, modelDocument.selection, evt.name);\n        };\n        this.listenTo(viewDocument, 'copy', onCopyCut, {\n            priority: 'low'\n        });\n        this.listenTo(viewDocument, 'cut', (evt, data)=>{\n            // Cutting is disabled when selection is in non-editable place.\n            // See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26.\n            if (!editor.model.canEditAt(editor.model.document.selection)) {\n                data.preventDefault();\n            } else {\n                onCopyCut(evt, data);\n            }\n        }, {\n            priority: 'low'\n        });\n        this.listenTo(this, 'outputTransformation', (evt, data)=>{\n            const content = editor.data.toView(data.content);\n            viewDocument.fire('clipboardOutput', {\n                dataTransfer: data.dataTransfer,\n                content,\n                method: data.method\n            });\n        }, {\n            priority: 'low'\n        });\n        this.listenTo(viewDocument, 'clipboardOutput', (evt, data)=>{\n            if (!data.content.isEmpty) {\n                data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content));\n                data.dataTransfer.setData('text/plain', viewToPlainText(data.content));\n            }\n            if (data.method == 'cut') {\n                editor.model.deleteContent(modelDocument.selection);\n            }\n        }, {\n            priority: 'low'\n        });\n    }\n}\n\nconst toPx = /* #__PURE__ */ toUnit('px');\n/**\n * The horizontal drop target line view.\n */ class LineView extends View {\n    /**\n\t * @inheritDoc\n\t */ constructor(){\n        super();\n        const bind = this.bindTemplate;\n        this.set({\n            isVisible: false,\n            left: null,\n            top: null,\n            width: null\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-clipboard-drop-target-line',\n                    bind.if('isVisible', 'ck-hidden', (value)=>!value)\n                ],\n                style: {\n                    left: bind.to('left', (left)=>toPx(left)),\n                    top: bind.to('top', (top)=>toPx(top)),\n                    width: bind.to('width', (width)=>toPx(width))\n                }\n            }\n        });\n    }\n}\n\n/**\n * Part of the Drag and Drop handling. Responsible for finding and displaying the drop target.\n *\n * @internal\n */ class DragDropTarget extends Plugin {\n    /**\n\t * A delayed callback removing the drop marker.\n\t *\n\t * @internal\n\t */ removeDropMarkerDelayed = delay(()=>this.removeDropMarker(), 40);\n    /**\n\t * A throttled callback updating the drop marker.\n\t */ _updateDropMarkerThrottled = throttle((targetRange)=>this._updateDropMarker(targetRange), 40);\n    /**\n\t * A throttled callback reconverting the drop parker.\n\t */ _reconvertMarkerThrottled = throttle(()=>{\n        if (this.editor.model.markers.has('drop-target')) {\n            this.editor.editing.reconvertMarker('drop-target');\n        }\n    }, 0);\n    /**\n\t * The horizontal drop target line view.\n\t */ _dropTargetLineView = new LineView();\n    /**\n\t * DOM Emitter.\n\t */ _domEmitter = new (DomEmitterMixin())();\n    /**\n\t * Map of document scrollable elements.\n\t */ _scrollables = new Map();\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'DragDropTarget';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        this._setupDropMarker();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this._domEmitter.stopListening();\n        for (const { resizeObserver } of this._scrollables.values()){\n            resizeObserver.destroy();\n        }\n        this._updateDropMarkerThrottled.cancel();\n        this.removeDropMarkerDelayed.cancel();\n        this._reconvertMarkerThrottled.cancel();\n        return super.destroy();\n    }\n    /**\n\t * Finds the drop target range and updates the drop marker.\n\t *\n\t * @internal\n\t */ updateDropMarker(targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange) {\n        this.removeDropMarkerDelayed.cancel();\n        const targetRange = findDropTargetRange(this.editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange);\n        /* istanbul ignore next -- @preserve */ if (!targetRange) {\n            return;\n        }\n        if (draggedRange && draggedRange.containsRange(targetRange)) {\n            // Target range is inside the dragged range.\n            return this.removeDropMarker();\n        }\n        this._updateDropMarkerThrottled(targetRange);\n    }\n    /**\n\t * Finds the final drop target range.\n\t *\n\t * @internal\n\t */ getFinalDropRange(targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange) {\n        const targetRange = findDropTargetRange(this.editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange);\n        // The dragging markers must be removed after searching for the target range because sometimes\n        // the target lands on the marker itself.\n        this.removeDropMarker();\n        return targetRange;\n    }\n    /**\n\t * Removes the drop target marker.\n\t *\n\t * @internal\n\t */ removeDropMarker() {\n        const model = this.editor.model;\n        this.removeDropMarkerDelayed.cancel();\n        this._updateDropMarkerThrottled.cancel();\n        this._dropTargetLineView.isVisible = false;\n        if (model.markers.has('drop-target')) {\n            model.change((writer)=>{\n                writer.removeMarker('drop-target');\n            });\n        }\n    }\n    /**\n\t * Creates downcast conversion for the drop target marker.\n\t */ _setupDropMarker() {\n        const editor = this.editor;\n        editor.ui.view.body.add(this._dropTargetLineView);\n        // Drop marker conversion for hovering over widgets.\n        editor.conversion.for('editingDowncast').markerToHighlight({\n            model: 'drop-target',\n            view: {\n                classes: [\n                    'ck-clipboard-drop-target-range'\n                ]\n            }\n        });\n        // Drop marker conversion for in text and block drop target.\n        editor.conversion.for('editingDowncast').markerToElement({\n            model: 'drop-target',\n            view: (data, { writer })=>{\n                // Inline drop.\n                if (editor.model.schema.checkChild(data.markerRange.start, '$text')) {\n                    this._dropTargetLineView.isVisible = false;\n                    return this._createDropTargetPosition(writer);\n                } else {\n                    if (data.markerRange.isCollapsed) {\n                        this._updateDropTargetLine(data.markerRange);\n                    } else {\n                        this._dropTargetLineView.isVisible = false;\n                    }\n                }\n            }\n        });\n    }\n    /**\n\t * Updates the drop target marker to the provided range.\n\t *\n\t * @param targetRange The range to set the marker to.\n\t */ _updateDropMarker(targetRange) {\n        const editor = this.editor;\n        const markers = editor.model.markers;\n        editor.model.change((writer)=>{\n            if (markers.has('drop-target')) {\n                if (!markers.get('drop-target').getRange().isEqual(targetRange)) {\n                    writer.updateMarker('drop-target', {\n                        range: targetRange\n                    });\n                }\n            } else {\n                writer.addMarker('drop-target', {\n                    range: targetRange,\n                    usingOperation: false,\n                    affectsData: false\n                });\n            }\n        });\n    }\n    /**\n\t * Creates the UI element for vertical (in-line) drop target.\n\t */ _createDropTargetPosition(writer) {\n        return writer.createUIElement('span', {\n            class: 'ck ck-clipboard-drop-target-position'\n        }, function(domDocument) {\n            const domElement = this.toDomElement(domDocument);\n            // Using word joiner to make this marker as high as text and also making text not break on marker.\n            domElement.append('\\u2060', domDocument.createElement('span'), '\\u2060');\n            return domElement;\n        });\n    }\n    /**\n\t * Updates the horizontal drop target line.\n\t */ _updateDropTargetLine(range) {\n        const editing = this.editor.editing;\n        const nodeBefore = range.start.nodeBefore;\n        const nodeAfter = range.start.nodeAfter;\n        const nodeParent = range.start.parent;\n        const viewElementBefore = nodeBefore ? editing.mapper.toViewElement(nodeBefore) : null;\n        const domElementBefore = viewElementBefore ? editing.view.domConverter.mapViewToDom(viewElementBefore) : null;\n        const viewElementAfter = nodeAfter ? editing.mapper.toViewElement(nodeAfter) : null;\n        const domElementAfter = viewElementAfter ? editing.view.domConverter.mapViewToDom(viewElementAfter) : null;\n        const viewElementParent = editing.mapper.toViewElement(nodeParent);\n        if (!viewElementParent) {\n            return;\n        }\n        const domElementParent = editing.view.domConverter.mapViewToDom(viewElementParent);\n        const domScrollableRect = this._getScrollableRect(viewElementParent);\n        const { scrollX, scrollY } = global.window;\n        const rectBefore = domElementBefore ? new Rect(domElementBefore) : null;\n        const rectAfter = domElementAfter ? new Rect(domElementAfter) : null;\n        const rectParent = new Rect(domElementParent).excludeScrollbarsAndBorders();\n        const above = rectBefore ? rectBefore.bottom : rectParent.top;\n        const below = rectAfter ? rectAfter.top : rectParent.bottom;\n        const parentStyle = global.window.getComputedStyle(domElementParent);\n        const top = above <= below ? (above + below) / 2 : below;\n        if (domScrollableRect.top < top && top < domScrollableRect.bottom) {\n            const left = rectParent.left + parseFloat(parentStyle.paddingLeft);\n            const right = rectParent.right - parseFloat(parentStyle.paddingRight);\n            const leftClamped = Math.max(left + scrollX, domScrollableRect.left);\n            const rightClamped = Math.min(right + scrollX, domScrollableRect.right);\n            this._dropTargetLineView.set({\n                isVisible: true,\n                left: leftClamped,\n                top: top + scrollY,\n                width: rightClamped - leftClamped\n            });\n        } else {\n            this._dropTargetLineView.isVisible = false;\n        }\n    }\n    /**\n\t * Finds the closest scrollable element rect for the given view element.\n\t */ _getScrollableRect(viewElement) {\n        const rootName = viewElement.root.rootName;\n        let domScrollable;\n        if (this._scrollables.has(rootName)) {\n            domScrollable = this._scrollables.get(rootName).domElement;\n        } else {\n            const domElement = this.editor.editing.view.domConverter.mapViewToDom(viewElement);\n            domScrollable = findScrollableElement(domElement);\n            this._domEmitter.listenTo(domScrollable, 'scroll', this._reconvertMarkerThrottled, {\n                usePassive: true\n            });\n            const resizeObserver = new ResizeObserver(domScrollable, this._reconvertMarkerThrottled);\n            this._scrollables.set(rootName, {\n                domElement: domScrollable,\n                resizeObserver\n            });\n        }\n        return new Rect(domScrollable).excludeScrollbarsAndBorders();\n    }\n}\n/**\n * Returns fixed selection range for given position and target element.\n */ function findDropTargetRange(editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode, draggedRange) {\n    const model = editor.model;\n    const mapper = editor.editing.mapper;\n    const targetModelElement = getClosestMappedModelElement(editor, targetViewElement);\n    let modelElement = targetModelElement;\n    while(modelElement){\n        if (!blockMode) {\n            if (model.schema.checkChild(modelElement, '$text')) {\n                if (targetViewRanges) {\n                    const targetViewPosition = targetViewRanges[0].start;\n                    const targetModelPosition = mapper.toModelPosition(targetViewPosition);\n                    const canDropOnPosition = !draggedRange || Array.from(draggedRange.getItems()).every((item)=>model.schema.checkChild(targetModelPosition, item));\n                    if (canDropOnPosition) {\n                        if (model.schema.checkChild(targetModelPosition, '$text')) {\n                            return model.createRange(targetModelPosition);\n                        } else if (targetViewPosition) {\n                            // This is the case of dropping inside a span wrapper of an inline image.\n                            return findDropTargetRangeForElement(editor, getClosestMappedModelElement(editor, targetViewPosition.parent), clientX, clientY);\n                        }\n                    }\n                }\n            } else if (model.schema.isInline(modelElement)) {\n                return findDropTargetRangeForElement(editor, modelElement, clientX, clientY);\n            }\n        }\n        if (model.schema.isBlock(modelElement)) {\n            return findDropTargetRangeForElement(editor, modelElement, clientX, clientY);\n        } else if (model.schema.checkChild(modelElement, '$block')) {\n            const childNodes = Array.from(modelElement.getChildren()).filter((node)=>node.is('element') && !shouldIgnoreElement(editor, node));\n            let startIndex = 0;\n            let endIndex = childNodes.length;\n            if (endIndex == 0) {\n                return model.createRange(model.createPositionAt(modelElement, 'end'));\n            }\n            while(startIndex < endIndex - 1){\n                const middleIndex = Math.floor((startIndex + endIndex) / 2);\n                const side = findElementSide(editor, childNodes[middleIndex], clientX, clientY);\n                if (side == 'before') {\n                    endIndex = middleIndex;\n                } else {\n                    startIndex = middleIndex;\n                }\n            }\n            return findDropTargetRangeForElement(editor, childNodes[startIndex], clientX, clientY);\n        }\n        modelElement = modelElement.parent;\n    }\n    return null;\n}\n/**\n * Returns true for elements which should be ignored.\n */ function shouldIgnoreElement(editor, modelElement) {\n    const mapper = editor.editing.mapper;\n    const domConverter = editor.editing.view.domConverter;\n    const viewElement = mapper.toViewElement(modelElement);\n    if (!viewElement) {\n        return true;\n    }\n    const domElement = domConverter.mapViewToDom(viewElement);\n    return global.window.getComputedStyle(domElement).float != 'none';\n}\n/**\n * Returns target range relative to the given element.\n */ function findDropTargetRangeForElement(editor, modelElement, clientX, clientY) {\n    const model = editor.model;\n    return model.createRange(model.createPositionAt(modelElement, findElementSide(editor, modelElement, clientX, clientY)));\n}\n/**\n * Resolves whether drop marker should be before or after the given element.\n */ function findElementSide(editor, modelElement, clientX, clientY) {\n    const mapper = editor.editing.mapper;\n    const domConverter = editor.editing.view.domConverter;\n    const viewElement = mapper.toViewElement(modelElement);\n    const domElement = domConverter.mapViewToDom(viewElement);\n    const rect = new Rect(domElement);\n    if (editor.model.schema.isInline(modelElement)) {\n        return clientX < (rect.left + rect.right) / 2 ? 'before' : 'after';\n    } else {\n        return clientY < (rect.top + rect.bottom) / 2 ? 'before' : 'after';\n    }\n}\n/**\n * Returns the closest model element for the specified view element.\n */ function getClosestMappedModelElement(editor, element) {\n    const mapper = editor.editing.mapper;\n    const view = editor.editing.view;\n    const targetModelElement = mapper.toModelElement(element);\n    if (targetModelElement) {\n        return targetModelElement;\n    }\n    // Find mapped ancestor if the target is inside not mapped element (for example inline code element).\n    const viewPosition = view.createPositionBefore(element);\n    const viewElement = mapper.findMappedViewAncestor(viewPosition);\n    return mapper.toModelElement(viewElement);\n}\n/**\n * Returns the closest scrollable ancestor DOM element.\n *\n * It is assumed that `domNode` is attached to the document.\n */ function findScrollableElement(domNode) {\n    let domElement = domNode;\n    do {\n        domElement = domElement.parentElement;\n        const overflow = global.window.getComputedStyle(domElement).overflowY;\n        if (overflow == 'auto' || overflow == 'scroll') {\n            break;\n        }\n    }while (domElement.tagName != 'BODY')\n    return domElement;\n}\n\n/**\n * Integration of a block Drag and Drop support with the block toolbar.\n *\n * @internal\n */ class DragDropBlockToolbar extends Plugin {\n    /**\n\t * Whether current dragging is started by block toolbar button dragging.\n\t */ _isBlockDragging = false;\n    /**\n\t * DOM Emitter.\n\t */ _domEmitter = new (DomEmitterMixin())();\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'DragDropBlockToolbar';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly)=>{\n            if (isReadOnly) {\n                this.forceDisabled('readOnlyMode');\n                this._isBlockDragging = false;\n            } else {\n                this.clearForceDisabled('readOnlyMode');\n            }\n        });\n        if (env.isAndroid) {\n            this.forceDisabled('noAndroidSupport');\n        }\n        if (editor.plugins.has('BlockToolbar')) {\n            const blockToolbar = editor.plugins.get('BlockToolbar');\n            const element = blockToolbar.buttonView.element;\n            this._domEmitter.listenTo(element, 'dragstart', (evt, data)=>this._handleBlockDragStart(data));\n            this._domEmitter.listenTo(global.document, 'dragover', (evt, data)=>this._handleBlockDragging(data));\n            this._domEmitter.listenTo(global.document, 'drop', (evt, data)=>this._handleBlockDragging(data));\n            this._domEmitter.listenTo(global.document, 'dragend', ()=>this._handleBlockDragEnd(), {\n                useCapture: true\n            });\n            if (this.isEnabled) {\n                element.setAttribute('draggable', 'true');\n            }\n            this.on('change:isEnabled', (evt, name, isEnabled)=>{\n                element.setAttribute('draggable', isEnabled ? 'true' : 'false');\n            });\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this._domEmitter.stopListening();\n        return super.destroy();\n    }\n    /**\n\t * The `dragstart` event handler.\n\t */ _handleBlockDragStart(domEvent) {\n        if (!this.isEnabled) {\n            return;\n        }\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const view = this.editor.editing.view;\n        const blocks = Array.from(selection.getSelectedBlocks());\n        const draggedRange = model.createRange(model.createPositionBefore(blocks[0]), model.createPositionAfter(blocks[blocks.length - 1]));\n        model.change((writer)=>writer.setSelection(draggedRange));\n        this._isBlockDragging = true;\n        view.focus();\n        view.getObserver(ClipboardObserver).onDomEvent(domEvent);\n    }\n    /**\n\t * The `dragover` and `drop` event handler.\n\t */ _handleBlockDragging(domEvent) {\n        if (!this.isEnabled || !this._isBlockDragging) {\n            return;\n        }\n        const clientX = domEvent.clientX + (this.editor.locale.contentLanguageDirection == 'ltr' ? 100 : -100);\n        const clientY = domEvent.clientY;\n        const target = document.elementFromPoint(clientX, clientY);\n        const view = this.editor.editing.view;\n        if (!target || !target.closest('.ck-editor__editable')) {\n            return;\n        }\n        view.getObserver(ClipboardObserver).onDomEvent({\n            ...domEvent,\n            type: domEvent.type,\n            dataTransfer: domEvent.dataTransfer,\n            target,\n            clientX,\n            clientY,\n            preventDefault: ()=>domEvent.preventDefault(),\n            stopPropagation: ()=>domEvent.stopPropagation()\n        });\n    }\n    /**\n\t * The `dragend` event handler.\n\t */ _handleBlockDragEnd() {\n        this._isBlockDragging = false;\n    }\n}\n\n// Drag and drop events overview:\n//\n//                ┌──────────────────┐\n//                │     mousedown    │   Sets the draggable attribute.\n//                └─────────┬────────┘\n//                          │\n//                          └─────────────────────┐\n//                          │                     │\n//                          │           ┌─────────V────────┐\n//                          │           │      mouseup     │   Dragging did not start, removes the draggable attribute.\n//                          │           └──────────────────┘\n//                          │\n//                ┌─────────V────────┐   Retrieves the selected model.DocumentFragment\n//                │     dragstart    │   and converts it to view.DocumentFragment.\n//                └─────────┬────────┘\n//                          │\n//                ┌─────────V────────┐   Processes view.DocumentFragment to text/html and text/plain\n//                │  clipboardOutput │   and stores the results in data.dataTransfer.\n//                └─────────┬────────┘\n//                          │\n//                          │   DOM dragover\n//                          ┌────────────┐\n//                          │            │\n//                ┌─────────V────────┐   │\n//                │     dragging     │   │   Updates the drop target marker.\n//                └─────────┬────────┘   │\n//                          │            │\n//            ┌─────────────└────────────┘\n//            │             │            │\n//            │   ┌─────────V────────┐   │\n//            │   │     dragleave    │   │   Removes the drop target marker.\n//            │   └─────────┬────────┘   │\n//            │             │            │\n//        ┌───│─────────────┘            │\n//        │   │             │            │\n//        │   │   ┌─────────V────────┐   │\n//        │   │   │     dragenter    │   │   Focuses the editor view.\n//        │   │   └─────────┬────────┘   │\n//        │   │             │            │\n//        │   │             └────────────┘\n//        │   │\n//        │   └─────────────┐\n//        │   │             │\n//        │   │   ┌─────────V────────┐\n//        └───┐   │       drop       │   (The default handler of the clipboard pipeline).\n//            │   └─────────┬────────┘\n//            │             │\n//            │   ┌─────────V────────┐   Resolves the final data.targetRanges.\n//            │   │  clipboardInput  │   Aborts if dropping on dragged content.\n//            │   └─────────┬────────┘\n//            │             │\n//            │   ┌─────────V────────┐\n//            │   │  clipboardInput  │   (The default handler of the clipboard pipeline).\n//            │   └─────────┬────────┘\n//            │             │\n//            │ ┌───────────V───────────┐\n//            │ │  inputTransformation  │   (The default handler of the clipboard pipeline).\n//            │ └───────────┬───────────┘\n//            │             │\n//            │  ┌──────────V──────────┐\n//            │  │   contentInsertion  │   Updates the document selection to drop range.\n//            │  └──────────┬──────────┘\n//            │             │\n//            │  ┌──────────V──────────┐\n//            │  │   contentInsertion  │   (The default handler of the clipboard pipeline).\n//            │  └──────────┬──────────┘\n//            │             │\n//            │  ┌──────────V──────────┐\n//            │  │   contentInsertion  │   Removes the content from the original range if the insertion was successful.\n//            │  └──────────┬──────────┘\n//            │             │\n//            └─────────────┐\n//                          │\n//                ┌─────────V────────┐\n//                │      dragend     │   Removes the drop marker and cleans the state.\n//                └──────────────────┘\n//\n/**\n * The drag and drop feature. It works on top of the {@link module:clipboard/clipboardpipeline~ClipboardPipeline}.\n *\n * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n *\n * @internal\n */ class DragDrop extends Plugin {\n    /**\n\t * The live range over the original content that is being dragged.\n\t */ _draggedRange;\n    /**\n\t * The UID of current dragging that is used to verify if the drop started in the same editor as the drag start.\n\t *\n\t * **Note**: This is a workaround for broken 'dragend' events (they are not fired if the source text node got removed).\n\t */ _draggingUid;\n    /**\n\t * The reference to the model element that currently has a `draggable` attribute set (it is set while dragging).\n\t */ _draggableElement;\n    /**\n\t * A delayed callback removing draggable attributes.\n\t */ _clearDraggableAttributesDelayed = delay(()=>this._clearDraggableAttributes(), 40);\n    /**\n\t * Whether the dragged content can be dropped only in block context.\n\t */ // TODO handle drag from other editor instance\n    // TODO configure to use block, inline or both\n    _blockMode = false;\n    /**\n\t * DOM Emitter.\n\t */ _domEmitter = new (DomEmitterMixin())();\n    /**\n\t * The DOM element used to generate dragged preview image.\n\t */ _previewContainer;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'DragDrop';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ClipboardPipeline,\n            Widget,\n            DragDropTarget,\n            DragDropBlockToolbar\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        this._draggedRange = null;\n        this._draggingUid = '';\n        this._draggableElement = null;\n        view.addObserver(ClipboardObserver);\n        view.addObserver(MouseObserver);\n        this._setupDragging();\n        this._setupContentInsertionIntegration();\n        this._setupClipboardInputIntegration();\n        this._setupDraggableAttributeHandling();\n        this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly)=>{\n            if (isReadOnly) {\n                this.forceDisabled('readOnlyMode');\n            } else {\n                this.clearForceDisabled('readOnlyMode');\n            }\n        });\n        this.on('change:isEnabled', (evt, name, isEnabled)=>{\n            if (!isEnabled) {\n                this._finalizeDragging(false);\n            }\n        });\n        if (env.isAndroid) {\n            this.forceDisabled('noAndroidSupport');\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        if (this._draggedRange) {\n            this._draggedRange.detach();\n            this._draggedRange = null;\n        }\n        if (this._previewContainer) {\n            this._previewContainer.remove();\n        }\n        this._domEmitter.stopListening();\n        this._clearDraggableAttributesDelayed.cancel();\n        return super.destroy();\n    }\n    /**\n\t * Drag and drop events handling.\n\t */ _setupDragging() {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const dragDropTarget = editor.plugins.get(DragDropTarget);\n        // The handler for the drag start; it is responsible for setting data transfer object.\n        this.listenTo(viewDocument, 'dragstart', (evt, data)=>{\n            // Don't drag the editable element itself.\n            if (data.target && data.target.is('editableElement')) {\n                data.preventDefault();\n                return;\n            }\n            this._prepareDraggedRange(data.target);\n            if (!this._draggedRange) {\n                data.preventDefault();\n                return;\n            }\n            this._draggingUid = uid();\n            data.dataTransfer.effectAllowed = this.isEnabled ? 'copyMove' : 'copy';\n            data.dataTransfer.setData('application/ckeditor5-dragging-uid', this._draggingUid);\n            const draggedSelection = model.createSelection(this._draggedRange.toRange());\n            const clipboardPipeline = this.editor.plugins.get('ClipboardPipeline');\n            clipboardPipeline._fireOutputTransformationEvent(data.dataTransfer, draggedSelection, 'dragstart');\n            const { dataTransfer, domTarget, domEvent } = data;\n            const { clientX } = domEvent;\n            this._updatePreview({\n                dataTransfer,\n                domTarget,\n                clientX\n            });\n            data.stopPropagation();\n            if (!this.isEnabled) {\n                this._draggedRange.detach();\n                this._draggedRange = null;\n                this._draggingUid = '';\n            }\n        }, {\n            priority: 'low'\n        });\n        // The handler for finalizing drag and drop. It should always be triggered after dragging completes\n        // even if it was completed in a different application.\n        // Note: This is not fired if source text node got removed while downcasting a marker.\n        this.listenTo(viewDocument, 'dragend', (evt, data)=>{\n            this._finalizeDragging(!data.dataTransfer.isCanceled && data.dataTransfer.dropEffect == 'move');\n        }, {\n            priority: 'low'\n        });\n        // Reset block dragging mode even if dropped outside the editable.\n        this._domEmitter.listenTo(global.document, 'dragend', ()=>{\n            this._blockMode = false;\n        }, {\n            useCapture: true\n        });\n        // Dragging over the editable.\n        this.listenTo(viewDocument, 'dragenter', ()=>{\n            if (!this.isEnabled) {\n                return;\n            }\n            view.focus();\n        });\n        // Dragging out of the editable.\n        this.listenTo(viewDocument, 'dragleave', ()=>{\n            // We do not know if the mouse left the editor or just some element in it, so let us wait a few milliseconds\n            // to check if 'dragover' is not fired.\n            dragDropTarget.removeDropMarkerDelayed();\n        });\n        // Handler for moving dragged content over the target area.\n        this.listenTo(viewDocument, 'dragging', (evt, data)=>{\n            if (!this.isEnabled) {\n                data.dataTransfer.dropEffect = 'none';\n                return;\n            }\n            const { clientX, clientY } = data.domEvent;\n            dragDropTarget.updateDropMarker(data.target, data.targetRanges, clientX, clientY, this._blockMode, this._draggedRange);\n            // If this is content being dragged from another editor, moving out of current editor instance\n            // is not possible until 'dragend' event case will be fixed.\n            if (!this._draggedRange) {\n                data.dataTransfer.dropEffect = 'copy';\n            }\n            // In Firefox it is already set and effect allowed remains the same as originally set.\n            if (!env.isGecko) {\n                if (data.dataTransfer.effectAllowed == 'copy') {\n                    data.dataTransfer.dropEffect = 'copy';\n                } else if ([\n                    'all',\n                    'copyMove'\n                ].includes(data.dataTransfer.effectAllowed)) {\n                    data.dataTransfer.dropEffect = 'move';\n                }\n            }\n            evt.stop();\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * Integration with the `clipboardInput` event.\n\t */ _setupClipboardInputIntegration() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const dragDropTarget = editor.plugins.get(DragDropTarget);\n        // Update the event target ranges and abort dropping if dropping over itself.\n        this.listenTo(viewDocument, 'clipboardInput', (evt, data)=>{\n            if (data.method != 'drop') {\n                return;\n            }\n            const { clientX, clientY } = data.domEvent;\n            const targetRange = dragDropTarget.getFinalDropRange(data.target, data.targetRanges, clientX, clientY, this._blockMode, this._draggedRange);\n            if (!targetRange) {\n                this._finalizeDragging(false);\n                evt.stop();\n                return;\n            }\n            // Since we cannot rely on the drag end event, we must check if the local drag range is from the current drag and drop\n            // or it is from some previous not cleared one.\n            if (this._draggedRange && this._draggingUid != data.dataTransfer.getData('application/ckeditor5-dragging-uid')) {\n                this._draggedRange.detach();\n                this._draggedRange = null;\n                this._draggingUid = '';\n            }\n            // Do not do anything if some content was dragged within the same document to the same position.\n            const isMove = getFinalDropEffect(data.dataTransfer) == 'move';\n            if (isMove && this._draggedRange && this._draggedRange.containsRange(targetRange, true)) {\n                this._finalizeDragging(false);\n                evt.stop();\n                return;\n            }\n            // Override the target ranges with the one adjusted to the best one for a drop.\n            data.targetRanges = [\n                editor.editing.mapper.toViewRange(targetRange)\n            ];\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Integration with the `contentInsertion` event of the clipboard pipeline.\n\t */ _setupContentInsertionIntegration() {\n        const clipboardPipeline = this.editor.plugins.get(ClipboardPipeline);\n        clipboardPipeline.on('contentInsertion', (evt, data)=>{\n            if (!this.isEnabled || data.method !== 'drop') {\n                return;\n            }\n            // Update the selection to the target range in the same change block to avoid selection post-fixing\n            // and to be able to clone text attributes for plain text dropping.\n            const ranges = data.targetRanges.map((viewRange)=>this.editor.editing.mapper.toModelRange(viewRange));\n            this.editor.model.change((writer)=>writer.setSelection(ranges));\n        }, {\n            priority: 'high'\n        });\n        clipboardPipeline.on('contentInsertion', (evt, data)=>{\n            if (!this.isEnabled || data.method !== 'drop') {\n                return;\n            }\n            // Remove dragged range content, remove markers, clean after dragging.\n            const isMove = getFinalDropEffect(data.dataTransfer) == 'move';\n            // Whether any content was inserted (insertion might fail if the schema is disallowing some elements\n            // (for example an image caption allows only the content of a block but not blocks themselves.\n            // Some integrations might not return valid range (i.e., table pasting).\n            const isSuccess = !data.resultRange || !data.resultRange.isCollapsed;\n            this._finalizeDragging(isSuccess && isMove);\n        }, {\n            priority: 'lowest'\n        });\n    }\n    /**\n\t * Adds listeners that add the `draggable` attribute to the elements while the mouse button is down so the dragging could start.\n\t */ _setupDraggableAttributeHandling() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        // Add the 'draggable' attribute to the widget while pressing the selection handle.\n        // This is required for widgets to be draggable. In Chrome it will enable dragging text nodes.\n        this.listenTo(viewDocument, 'mousedown', (evt, data)=>{\n            // The lack of data can be caused by editor tests firing fake mouse events. This should not occur\n            // in real-life scenarios but this greatly simplifies editor tests that would otherwise fail a lot.\n            if (env.isAndroid || !data) {\n                return;\n            }\n            this._clearDraggableAttributesDelayed.cancel();\n            // Check if this is a mousedown over the widget (but not a nested editable).\n            let draggableElement = findDraggableWidget(data.target);\n            // Note: There is a limitation that if more than a widget is selected (a widget and some text)\n            // and dragging starts on the widget, then only the widget is dragged.\n            // If this was not a widget then we should check if we need to drag some text content.\n            // In Chrome set a 'draggable' attribute on closest editable to allow immediate dragging of the selected text range.\n            // In Firefox this is not needed. In Safari it makes the whole editable draggable (not just textual content).\n            // Disabled in read-only mode because draggable=\"true\" + contenteditable=\"false\" results\n            // in not firing selectionchange event ever, which makes the selection stuck in read-only mode.\n            if (env.isBlink && !editor.isReadOnly && !draggableElement && !viewDocument.selection.isCollapsed) {\n                const selectedElement = viewDocument.selection.getSelectedElement();\n                if (!selectedElement || !isWidget(selectedElement)) {\n                    draggableElement = viewDocument.selection.editableElement;\n                }\n            }\n            if (draggableElement) {\n                view.change((writer)=>{\n                    writer.setAttribute('draggable', 'true', draggableElement);\n                });\n                // Keep the reference to the model element in case the view element gets removed while dragging.\n                this._draggableElement = editor.editing.mapper.toModelElement(draggableElement);\n            }\n        });\n        // Remove the draggable attribute in case no dragging started (only mousedown + mouseup).\n        this.listenTo(viewDocument, 'mouseup', ()=>{\n            if (!env.isAndroid) {\n                this._clearDraggableAttributesDelayed();\n            }\n        });\n    }\n    /**\n\t * Removes the `draggable` attribute from the element that was used for dragging.\n\t */ _clearDraggableAttributes() {\n        const editing = this.editor.editing;\n        editing.view.change((writer)=>{\n            // Remove 'draggable' attribute.\n            if (this._draggableElement && this._draggableElement.root.rootName != '$graveyard') {\n                writer.removeAttribute('draggable', editing.mapper.toViewElement(this._draggableElement));\n            }\n            this._draggableElement = null;\n        });\n    }\n    /**\n\t * Deletes the dragged content from its original range and clears the dragging state.\n\t *\n\t * @param moved Whether the move succeeded.\n\t */ _finalizeDragging(moved) {\n        const editor = this.editor;\n        const model = editor.model;\n        const dragDropTarget = editor.plugins.get(DragDropTarget);\n        dragDropTarget.removeDropMarker();\n        this._clearDraggableAttributes();\n        if (editor.plugins.has('WidgetToolbarRepository')) {\n            const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository');\n            widgetToolbarRepository.clearForceDisabled('dragDrop');\n        }\n        this._draggingUid = '';\n        if (this._previewContainer) {\n            this._previewContainer.remove();\n            this._previewContainer = undefined;\n        }\n        if (!this._draggedRange) {\n            return;\n        }\n        // Delete moved content.\n        if (moved && this.isEnabled) {\n            model.change((writer)=>{\n                const selection = model.createSelection(this._draggedRange);\n                model.deleteContent(selection, {\n                    doNotAutoparagraph: true\n                });\n                // Check result selection if it does not require auto-paragraphing of empty container.\n                const selectionParent = selection.getFirstPosition().parent;\n                if (selectionParent.isEmpty && !model.schema.checkChild(selectionParent, '$text') && model.schema.checkChild(selectionParent, 'paragraph')) {\n                    writer.insertElement('paragraph', selectionParent, 0);\n                }\n            });\n        }\n        this._draggedRange.detach();\n        this._draggedRange = null;\n    }\n    /**\n\t * Sets the dragged source range based on event target and document selection.\n\t */ _prepareDraggedRange(target) {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        // Check if this is dragstart over the widget (but not a nested editable).\n        const draggableWidget = target ? findDraggableWidget(target) : null;\n        if (draggableWidget) {\n            const modelElement = editor.editing.mapper.toModelElement(draggableWidget);\n            this._draggedRange = LiveRange.fromRange(model.createRangeOn(modelElement));\n            this._blockMode = model.schema.isBlock(modelElement);\n            // Disable toolbars so they won't obscure the drop area.\n            if (editor.plugins.has('WidgetToolbarRepository')) {\n                const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository');\n                widgetToolbarRepository.forceDisabled('dragDrop');\n            }\n            return;\n        }\n        // If this was not a widget we should check if we need to drag some text content.\n        if (selection.isCollapsed && !selection.getFirstPosition().parent.isEmpty) {\n            return;\n        }\n        const blocks = Array.from(selection.getSelectedBlocks());\n        const draggedRange = selection.getFirstRange();\n        if (blocks.length == 0) {\n            this._draggedRange = LiveRange.fromRange(draggedRange);\n            return;\n        }\n        const blockRange = getRangeIncludingFullySelectedParents(model, blocks);\n        if (blocks.length > 1) {\n            this._draggedRange = LiveRange.fromRange(blockRange);\n            this._blockMode = true;\n        // TODO block mode for dragging from outside editor? or inline? or both?\n        } else if (blocks.length == 1) {\n            const touchesBlockEdges = draggedRange.start.isTouching(blockRange.start) && draggedRange.end.isTouching(blockRange.end);\n            this._draggedRange = LiveRange.fromRange(touchesBlockEdges ? blockRange : draggedRange);\n            this._blockMode = touchesBlockEdges;\n        }\n        model.change((writer)=>writer.setSelection(this._draggedRange.toRange()));\n    }\n    /**\n\t * Updates the dragged preview image.\n\t */ _updatePreview({ dataTransfer, domTarget, clientX }) {\n        const view = this.editor.editing.view;\n        const editable = view.document.selection.editableElement;\n        const domEditable = view.domConverter.mapViewToDom(editable);\n        const computedStyle = global.window.getComputedStyle(domEditable);\n        if (!this._previewContainer) {\n            this._previewContainer = createElement(global.document, 'div', {\n                style: 'position: fixed; left: -999999px;'\n            });\n            global.document.body.appendChild(this._previewContainer);\n        } else if (this._previewContainer.firstElementChild) {\n            this._previewContainer.removeChild(this._previewContainer.firstElementChild);\n        }\n        const domRect = new Rect(domEditable);\n        // If domTarget is inside the editable root, browsers will display the preview correctly by themselves.\n        if (domEditable.contains(domTarget)) {\n            return;\n        }\n        const domEditablePaddingLeft = parseFloat(computedStyle.paddingLeft);\n        const preview = createElement(global.document, 'div');\n        preview.className = 'ck ck-content';\n        preview.style.width = computedStyle.width;\n        preview.style.paddingLeft = `${domRect.left - clientX + domEditablePaddingLeft}px`;\n        /**\n\t\t * Set white background in drag and drop preview if iOS.\n\t\t * Check: https://github.com/ckeditor/ckeditor5/issues/15085\n\t\t */ if (env.isiOS) {\n            preview.style.backgroundColor = 'white';\n        }\n        view.domConverter.setContentOf(preview, dataTransfer.getData('text/html'));\n        dataTransfer.setDragImage(preview, 0, 0);\n        this._previewContainer.appendChild(preview);\n    }\n}\n/**\n * Returns the drop effect that should be a result of dragging the content.\n * This function is handling a quirk when checking the effect in the 'drop' DOM event.\n */ function getFinalDropEffect(dataTransfer) {\n    if (env.isGecko) {\n        return dataTransfer.dropEffect;\n    }\n    return [\n        'all',\n        'copyMove'\n    ].includes(dataTransfer.effectAllowed) ? 'move' : 'copy';\n}\n/**\n * Returns a widget element that should be dragged.\n */ function findDraggableWidget(target) {\n    // This is directly an editable so not a widget for sure.\n    if (target.is('editableElement')) {\n        return null;\n    }\n    // TODO: Let's have a isWidgetSelectionHandleDomElement() helper in ckeditor5-widget utils.\n    if (target.hasClass('ck-widget__selection-handle')) {\n        return target.findAncestor(isWidget);\n    }\n    // Direct hit on a widget.\n    if (isWidget(target)) {\n        return target;\n    }\n    // Find closest ancestor that is either a widget or an editable element...\n    const ancestor = target.findAncestor((node)=>isWidget(node) || node.is('editableElement'));\n    // ...and if closer was the widget then enable dragging it.\n    if (isWidget(ancestor)) {\n        return ancestor;\n    }\n    return null;\n}\n/**\n * Recursively checks if common parent of provided elements doesn't have any other children. If that's the case,\n * it returns range including this parent. Otherwise, it returns only the range from first to last element.\n *\n * Example:\n *\n * <blockQuote>\n *   <paragraph>[Test 1</paragraph>\n *   <paragraph>Test 2</paragraph>\n *   <paragraph>Test 3]</paragraph>\n * <blockQuote>\n *\n * Because all elements inside the `blockQuote` are selected, the range is extended to include the `blockQuote` too.\n * If only first and second paragraphs would be selected, the range would not include it.\n */ function getRangeIncludingFullySelectedParents(model, elements) {\n    const firstElement = elements[0];\n    const lastElement = elements[elements.length - 1];\n    const parent = firstElement.getCommonAncestor(lastElement);\n    const startPosition = model.createPositionBefore(firstElement);\n    const endPosition = model.createPositionAfter(lastElement);\n    if (parent && parent.is('element') && !model.schema.isLimit(parent)) {\n        const parentRange = model.createRangeOn(parent);\n        const touchesStart = startPosition.isTouching(parentRange.start);\n        const touchesEnd = endPosition.isTouching(parentRange.end);\n        if (touchesStart && touchesEnd) {\n            // Selection includes all elements in the parent.\n            return getRangeIncludingFullySelectedParents(model, [\n                parent\n            ]);\n        }\n    }\n    return model.createRange(startPosition, endPosition);\n}\n\n/**\n * The plugin detects the user's intention to paste plain text.\n *\n * For example, it detects the <kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> keystroke.\n */ class PastePlainText extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'PastePlainText';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ClipboardPipeline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        const selection = model.document.selection;\n        view.addObserver(ClipboardObserver);\n        editor.plugins.get(ClipboardPipeline).on('contentInsertion', (evt, data)=>{\n            if (!isUnformattedInlineContent(data.content, model)) {\n                return;\n            }\n            model.change((writer)=>{\n                // Formatting attributes should be preserved.\n                const textAttributes = Array.from(selection.getAttributes()).filter(([key])=>model.schema.getAttributeProperties(key).isFormatting);\n                if (!selection.isCollapsed) {\n                    model.deleteContent(selection, {\n                        doNotAutoparagraph: true\n                    });\n                }\n                // Also preserve other attributes if they survived the content deletion (because they were not fully selected).\n                // For example linkHref is not a formatting attribute but it should be preserved if pasted text was in the middle\n                // of a link.\n                textAttributes.push(...selection.getAttributes());\n                const range = writer.createRangeIn(data.content);\n                for (const item of range.getItems()){\n                    for (const attribute of textAttributes){\n                        if (model.schema.checkAttribute(item, attribute[0])) {\n                            writer.setAttribute(attribute[0], attribute[1], item);\n                        }\n                    }\n                }\n            });\n        });\n    }\n}\n/**\n * Returns true if specified `documentFragment` represents the unformatted inline content.\n */ function isUnformattedInlineContent(documentFragment, model) {\n    let range = model.createRangeIn(documentFragment);\n    // We consider three scenarios here. The document fragment may include:\n    //\n    // 1. Only text and inline objects. Then it could be unformatted inline content.\n    // 2. Exactly one block element on top-level, eg. <p>Foobar</p> or <h2>Title</h2>.\n    //    In this case, check this element content, it could be treated as unformatted inline content.\n    // 3. More block elements or block objects, then it is not unformatted inline content.\n    //\n    // We will check for scenario 2. specifically, and if it happens, we will unwrap it and follow with the regular algorithm.\n    //\n    if (documentFragment.childCount == 1) {\n        const child = documentFragment.getChild(0);\n        if (child.is('element') && model.schema.isBlock(child) && !model.schema.isObject(child) && !model.schema.isLimit(child)) {\n            // Scenario 2. as described above.\n            range = model.createRangeIn(child);\n        }\n    }\n    for (const child of range.getItems()){\n        if (!model.schema.isInline(child)) {\n            return false;\n        }\n        const attributeKeys = Array.from(child.getAttributeKeys());\n        if (attributeKeys.find((key)=>model.schema.getAttributeProperties(key).isFormatting)) {\n            return false;\n        }\n    }\n    return true;\n}\n\n/**\n * The clipboard feature.\n *\n * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n * * {@link module:clipboard/clipboardpipeline~ClipboardPipeline}\n * * {@link module:clipboard/dragdrop~DragDrop}\n * * {@link module:clipboard/pasteplaintext~PastePlainText}\n */ class Clipboard extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Clipboard';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ClipboardMarkersUtils,\n            ClipboardPipeline,\n            DragDrop,\n            PastePlainText\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        // Add the information about the keystrokes to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Copy selected content'),\n                    keystroke: 'CTRL+C'\n                },\n                {\n                    label: t('Paste content'),\n                    keystroke: 'CTRL+V'\n                },\n                {\n                    label: t('Paste content as plain text'),\n                    keystroke: 'CTRL+SHIFT+V'\n                }\n            ]\n        });\n    }\n}\n\nexport { Clipboard, ClipboardMarkersUtils, ClipboardPipeline, DragDrop, DragDropBlockToolbar, DragDropTarget, PastePlainText, plainTextToHtml };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/clipboardobserver\n */\n\nimport { EventInfo, getRangeFromMouseEvent } from '@ckeditor/ckeditor5-utils';\n\nimport {\n\tDataTransfer,\n\tDomEventObserver,\n\ttype DomEventData,\n\ttype EditingView,\n\ttype ViewDocumentFragment,\n\ttype ViewElement,\n\ttype ViewRange\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * Clipboard events observer.\n *\n * Fires the following events:\n *\n * * {@link module:engine/view/document~Document#event:clipboardInput},\n * * {@link module:engine/view/document~Document#event:paste},\n * * {@link module:engine/view/document~Document#event:copy},\n * * {@link module:engine/view/document~Document#event:cut},\n * * {@link module:engine/view/document~Document#event:drop},\n * * {@link module:engine/view/document~Document#event:dragover},\n * * {@link module:engine/view/document~Document#event:dragging},\n * * {@link module:engine/view/document~Document#event:dragstart},\n * * {@link module:engine/view/document~Document#event:dragend},\n * * {@link module:engine/view/document~Document#event:dragenter},\n * * {@link module:engine/view/document~Document#event:dragleave}.\n *\n * **Note**: This observer is not available by default (ckeditor5-engine does not add it on its own).\n * To make it available, it needs to be added to {@link module:engine/view/document~Document} by using\n * the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. Alternatively, you can load the\n * {@link module:clipboard/clipboard~Clipboard} plugin which adds this observer automatically (because it uses it).\n */\nexport default class ClipboardObserver extends DomEventObserver<\n\t'paste' | 'copy' | 'cut' | 'drop' | 'dragover' | 'dragstart' | 'dragend' | 'dragenter' | 'dragleave',\n\tClipboardEventData\n> {\n\tpublic readonly domEventType = [\n\t\t'paste', 'copy', 'cut', 'drop', 'dragover', 'dragstart', 'dragend', 'dragenter', 'dragleave'\n\t] as const;\n\n\tconstructor( view: EditingView ) {\n\t\tsuper( view );\n\n\t\tconst viewDocument = this.document;\n\n\t\tthis.listenTo<ViewDocumentPasteEvent>( viewDocument, 'paste', handleInput( 'clipboardInput' ), { priority: 'low' } );\n\t\tthis.listenTo<ViewDocumentDropEvent>( viewDocument, 'drop', handleInput( 'clipboardInput' ), { priority: 'low' } );\n\t\tthis.listenTo<ViewDocumentDragOverEvent>( viewDocument, 'dragover', handleInput( 'dragging' ), { priority: 'low' } );\n\n\t\tfunction handleInput( type: 'clipboardInput' | 'dragging' ) {\n\t\t\treturn ( evt: EventInfo, data: DomEventData & ClipboardEventData ) => {\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\tconst targetRanges = data.dropRange ? [ data.dropRange ] : null;\n\t\t\t\tconst eventInfo = new EventInfo( viewDocument, type );\n\n\t\t\t\tviewDocument.fire( eventInfo, {\n\t\t\t\t\tdataTransfer: data.dataTransfer,\n\t\t\t\t\tmethod: evt.name,\n\t\t\t\t\ttargetRanges,\n\t\t\t\t\ttarget: data.target,\n\t\t\t\t\tdomEvent: data.domEvent\n\t\t\t\t} );\n\n\t\t\t\t// If CKEditor handled the input, do not bubble the original event any further.\n\t\t\t\t// This helps external integrations recognize that fact and act accordingly.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-upload/issues/92\n\t\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\t\tdata.stopPropagation();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n\n\tpublic onDomEvent( domEvent: ClipboardEvent | DragEvent ): void {\n\t\tconst nativeDataTransfer = 'clipboardData' in domEvent ? domEvent.clipboardData! : domEvent.dataTransfer!;\n\t\tconst cacheFiles = domEvent.type == 'drop' || domEvent.type == 'paste';\n\n\t\tconst evtData: ClipboardEventData = {\n\t\t\tdataTransfer: new DataTransfer( nativeDataTransfer, { cacheFiles } )\n\t\t};\n\n\t\tif ( domEvent.type == 'drop' || domEvent.type == 'dragover' ) {\n\t\t\tconst domRange = getRangeFromMouseEvent( domEvent as DragEvent );\n\n\t\t\tevtData.dropRange = domRange && this.view.domConverter.domRangeToView( domRange );\n\t\t}\n\n\t\tthis.fire( domEvent.type, domEvent, evtData );\n\t}\n}\n\n/**\n * The data of 'paste', 'copy', 'cut', 'drop', 'dragover', 'dragstart', 'dragend', 'dragenter' and 'dragleave' events.\n */\nexport interface ClipboardEventData {\n\n\t/**\n\t * The data transfer instance.\n\t */\n\tdataTransfer: DataTransfer;\n\n\t/**\n\t * The position into which the content is dropped.\n\t */\n\tdropRange?: ViewRange | null;\n}\n\n/**\n * Fired as a continuation of the {@link module:engine/view/document~Document#event:paste} and\n * {@link module:engine/view/document~Document#event:drop} events.\n *\n * It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.\n *\n * This event carries a `dataTransfer` object which comes from the clipboard and whose content should be processed\n * and inserted into the editor.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n *\n * @eventName module:engine/view/document~Document#clipboardInput\n * @param data The event data.\n */\nexport type ViewDocumentClipboardInputEvent = {\n\tname: 'clipboardInput';\n\targs: [ data: DomEventData<ClipboardEvent | DragEvent> & ClipboardInputEventData ];\n};\n\n/**\n * The value of the {@link module:engine/view/document~Document#event:paste},\n * {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut} events.\n *\n * In order to access the clipboard data, use the `dataTransfer` property.\n */\nexport interface ClipboardInputEventData {\n\n\t/**\n\t * Data transfer instance.\n\t */\n\tdataTransfer: DataTransfer;\n\n\t/**\n\t * Whether the event was triggered by a paste or a drop operation.\n\t */\n\tmethod: 'paste' | 'drop';\n\n\t/**\n\t * The tree view element representing the target.\n\t */\n\ttarget: ViewElement;\n\n\t/**\n\t * The ranges which are the target of the operation (usually – into which the content should be inserted).\n\t * If the clipboard input was triggered by a paste operation, this property is not set. If by a drop operation,\n\t * then it is the drop position (which can be different than the selection at the moment of the drop).\n\t */\n\ttargetRanges: Array<ViewRange> | null;\n\n\t/**\n\t * The content of clipboard input.\n\t */\n\tcontent?: ViewDocumentFragment;\n}\n\n/**\n * Fired when the user drags the content over one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n *\n * @eventName module:engine/view/document~Document#dragover\n * @param data The event data.\n */\nexport type ViewDocumentDragOverEvent = {\n\tname: 'dragover';\n\targs: [ data: DomEventData<DragEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired when the user dropped the content into one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n *\n * @eventName module:engine/view/document~Document#drop\n * @param data The event data.\n */\nexport type ViewDocumentDropEvent = {\n\tname: 'drop';\n\targs: [ data: DomEventData<DragEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired when the user pasted the content into one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n *\n * @eventName module:engine/view/document~Document#paste\n * @param {module:clipboard/clipboardobserver~ClipboardEventData} data The event data.\n */\nexport type ViewDocumentPasteEvent = {\n\tname: 'paste';\n\targs: [ data: DomEventData<ClipboardEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired when the user copied the content from one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n *\n * @eventName module:engine/view/document~Document#copy\n * @param data The event data.\n */\nexport type ViewDocumentCopyEvent = {\n\tname: 'copy';\n\targs: [ data: DomEventData<ClipboardEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired when the user cut the content from one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n *\n * @eventName module:engine/view/document~Document#cut\n * @param data The event data.\n */\nexport type ViewDocumentCutEvent = {\n\tname: 'cut';\n\targs: [ data: DomEventData<ClipboardEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired as a continuation of the {@link module:engine/view/document~Document#event:dragover} event.\n *\n * It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.\n *\n * This event carries a `dataTransfer` object which comes from the clipboard and whose content should be processed\n * and inserted into the editor.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboard~Clipboard\n *\n * @eventName module:engine/view/document~Document#dragging\n * @param data The event data.\n */\nexport type ViewDocumentDraggingEvent = {\n\tname: 'dragging';\n\targs: [ data: DomEventData<DragEvent> & DraggingEventData ];\n};\n\nexport interface DraggingEventData {\n\n\t/**\n\t * The data transfer instance.\n\t */\n\tdataTransfer: DataTransfer;\n\n\t/**\n\t * Whether the event was triggered by a paste or a drop operation.\n\t */\n\tmethod: 'dragover';\n\n\t/**\n\t * The tree view element representing the target.\n\t */\n\ttarget: Element;\n\n\t/**\n\t * Ranges which are the target of the operation (usually – into which the content should be inserted).\n\t * It is the drop position (which can be different than the selection at the moment of drop).\n\t */\n\ttargetRanges: Array<ViewRange> | null;\n}\n\n/**\n * Fired when the user starts dragging the content in one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n *\n * @eventName module:engine/view/document~Document#dragstart\n * @param data The event data.\n */\nexport type ViewDocumentDragStartEvent = {\n\tname: 'dragstart';\n\targs: [ data: DomEventData<DragEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired when the user ended dragging the content.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n *\n * @eventName module:engine/view/document~Document#dragend\n * @param data The event data.\n */\nexport type ViewDocumentDragEndEvent = {\n\tname: 'dragend';\n\targs: [ data: DomEventData<DragEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired when the user drags the content into one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n *\n * @eventName module:engine/view/document~Document#dragenter\n * @param data The event data.\n */\nexport type ViewDocumentDragEnterEvent = {\n\tname: 'dragenter';\n\targs: [ data: DomEventData<DragEvent> & ClipboardEventData ];\n};\n\n/**\n * Fired when the user drags the content out of one of the editing roots of the editor.\n *\n * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.\n *\n * **Note**: This event is not available by default. To make it available, {@link module:clipboard/clipboardobserver~ClipboardObserver}\n * needs to be added to the {@link module:engine/view/document~Document} by using the {@link module:engine/view/view~View#addObserver}\n * method. This is usually done by the {@link module:clipboard/clipboard~Clipboard} plugin, but if for some reason it is not loaded,\n * the observer must be added manually.\n *\n * @see module:engine/view/document~Document#event:clipboardInput\n *\n * @eventName module:engine/view/document~Document#dragleave\n * @param data The event data.\n */\nexport type ViewDocumentDragLeaveEvent = {\n\tname: 'dragleave';\n\targs: [ data: DomEventData<DragEvent> & ClipboardEventData ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/utils/plaintexttohtml\n */\n\n/**\n * Converts plain text to its HTML-ized version.\n *\n * @param text The plain text to convert.\n * @returns HTML generated from the plain text.\n */\nexport default function plainTextToHtml( text: string ): string {\n\ttext = text\n\t\t// Encode &.\n\t\t.replace( /&/g, '&amp;' )\n\t\t// Encode <>.\n\t\t.replace( /</g, '&lt;' )\n\t\t.replace( />/g, '&gt;' )\n\t\t// Creates a paragraph for each double line break.\n\t\t.replace( /\\r?\\n\\r?\\n/g, '</p><p>' )\n\t\t// Creates a line break for each single line break.\n\t\t.replace( /\\r?\\n/g, '<br>' )\n\t\t// Replace tabs with four spaces.\n\t\t.replace( /\\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;' )\n\t\t// Preserve trailing spaces (only the first and last one – the rest is handled below).\n\t\t.replace( /^\\s/, '&nbsp;' )\n\t\t.replace( /\\s$/, '&nbsp;' )\n\t\t// Preserve other subsequent spaces now.\n\t\t.replace( /\\s\\s/g, ' &nbsp;' );\n\n\tif ( text.includes( '</p><p>' ) || text.includes( '<br>' ) ) {\n\t\t// If we created paragraphs above, add the trailing ones.\n\t\ttext = `<p>${ text }</p>`;\n\t}\n\n\t// TODO:\n\t// * What about '\\nfoo' vs ' foo'?\n\n\treturn text;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/utils/normalizeclipboarddata\n */\n\n/**\n * Removes some popular browser quirks out of the clipboard data (HTML).\n * Removes all HTML comments. These are considered an internal thing and it makes little sense if they leak into the editor data.\n *\n * @param data The HTML data to normalize.\n * @returns Normalized HTML.\n */\nexport default function normalizeClipboardData( data: string ): string {\n\treturn data\n\t\t.replace( /<span(?: class=\"Apple-converted-space\"|)>(\\s+)<\\/span>/g, ( fullMatch, spaces ) => {\n\t\t\t// Handle the most popular and problematic case when even a single space becomes an nbsp;.\n\t\t\t// Decode those to normal spaces. Read more in https://github.com/ckeditor/ckeditor5-clipboard/issues/2.\n\t\t\tif ( spaces.length == 1 ) {\n\t\t\t\treturn ' ';\n\t\t\t}\n\n\t\t\treturn spaces;\n\t\t} )\n\t\t// Remove all HTML comments.\n\t\t.replace( /<!--[\\s\\S]*?-->/g, '' );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/utils/viewtoplaintext\n */\n\nimport type { ViewDocumentFragment, ViewElement, ViewItem } from '@ckeditor/ckeditor5-engine';\n\n// Elements which should not have empty-line padding.\n// Most `view.ContainerElement` want to be separate by new-line, but some are creating one structure\n// together (like `<li>`) so it is better to separate them by only one \"\\n\".\nconst smallPaddingElements = [ 'figcaption', 'li' ];\n\nconst listElements = [ 'ol', 'ul' ];\n\n/**\n * Converts {@link module:engine/view/item~Item view item} and all of its children to plain text.\n *\n * @param viewItem View item to convert.\n * @returns Plain text representation of `viewItem`.\n */\nexport default function viewToPlainText( viewItem: ViewItem | ViewDocumentFragment ): string {\n\tif ( viewItem.is( '$text' ) || viewItem.is( '$textProxy' ) ) {\n\t\treturn viewItem.data;\n\t}\n\n\tif ( viewItem.is( 'element', 'img' ) && viewItem.hasAttribute( 'alt' ) ) {\n\t\treturn viewItem.getAttribute( 'alt' )!;\n\t}\n\n\tif ( viewItem.is( 'element', 'br' ) ) {\n\t\treturn '\\n'; // Convert soft breaks to single line break (#8045).\n\t}\n\n\t/**\n\t * Item is a document fragment, attribute element or container element. It doesn't\n\t * have it's own text value, so we need to convert its children elements.\n\t */\n\n\tlet text = '';\n\tlet prev: ViewElement | null = null;\n\n\tfor ( const child of ( viewItem as ViewElement | ViewDocumentFragment ).getChildren() ) {\n\t\ttext += newLinePadding( child as ViewElement, prev ) + viewToPlainText( child );\n\t\tprev = child as ViewElement;\n\t}\n\n\treturn text;\n}\n\n/**\n * Returns new line padding to prefix the given elements with.\n */\nfunction newLinePadding(\n\telement: ViewElement,\n\tprevious: ViewElement | null\n): string {\n\tif ( !previous ) {\n\t\t// Don't add padding to first elements in a level.\n\t\treturn '';\n\t}\n\n\tif ( element.is( 'element', 'li' ) && !element.isEmpty && element.getChild( 0 )!.is( 'containerElement' ) ) {\n\t\t// Separate document list items with empty lines.\n\t\treturn '\\n\\n';\n\t}\n\n\tif ( listElements.includes( element.name ) && listElements.includes( previous.name ) ) {\n\t\t/**\n\t\t * Because `<ul>` and `<ol>` are AttributeElements, two consecutive lists will not have any padding between\n\t\t * them (see the `if` statement below). To fix this, we need to make an exception for this case.\n\t\t */\n\t\treturn '\\n\\n';\n\t}\n\n\tif ( !element.is( 'containerElement' ) && !previous.is( 'containerElement' ) ) {\n\t\t// Don't add padding between non-container elements.\n\t\treturn '';\n\t}\n\n\tif ( smallPaddingElements.includes( element.name ) || smallPaddingElements.includes( previous.name ) ) {\n\t\t// Add small padding between selected container elements.\n\t\treturn '\\n';\n\t}\n\n\t// Do not add padding around the elements that won't be rendered.\n\tif (\n\t\telement.is( 'element' ) && element.getCustomProperty( 'dataPipeline:transparentRendering' ) ||\n\t\tprevious.is( 'element' ) && previous.getCustomProperty( 'dataPipeline:transparentRendering' )\n\t) {\n\t\treturn '';\n\t}\n\n\t// Add empty lines between container elements.\n\treturn '\\n\\n';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/clipboardmarkersutils\n */\nimport { mapValues } from 'lodash-es';\n\nimport { uid } from '@ckeditor/ckeditor5-utils';\nimport { Plugin, type NonEmptyArray } from '@ckeditor/ckeditor5-core';\n\nimport {\n\tRange,\n\ttype DocumentFragment,\n\ttype Position,\n\ttype Element,\n\ttype DocumentSelection,\n\ttype Selection,\n\ttype Writer,\n\ttype Marker\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * Part of the clipboard logic. Responsible for collecting markers from selected fragments\n * and restoring them with proper positions in pasted elements.\n *\n * @internal\n */\nexport default class ClipboardMarkersUtils extends Plugin {\n\t/**\n\t * Map of marker names that can be copied.\n\t *\n\t * @internal\n\t */\n\tprivate _markersToCopy: Map<string, ClipboardMarkerConfiguration> = new Map();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ClipboardMarkersUtils' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Registers marker name as copyable in clipboard pipeline.\n\t *\n\t * @param markerName Name of marker that can be copied.\n\t * @param config Configuration that describes what can be performed on specified marker.\n\t * @internal\n\t */\n\tpublic _registerMarkerToCopy( markerName: string, config: ClipboardMarkerConfiguration ): void {\n\t\tthis._markersToCopy.set( markerName, config );\n\t}\n\n\t/**\n\t * Performs copy markers on provided selection and paste it to fragment returned from `getCopiedFragment`.\n\t *\n\t * \t1. Picks all markers in provided selection.\n\t * \t2. Inserts fake markers to document.\n\t * \t3. Gets copied selection fragment from document.\n\t * \t4. Removes fake elements from fragment and document.\n\t * \t5. Inserts markers in the place of removed fake markers.\n\t *\n\t * Due to selection modification, when inserting items, `getCopiedFragment` must *always* operate on `writer.model.document.selection'.\n\t * Do not use any other custom selection object within callback, as this will lead to out-of-bounds exceptions in rare scenarios.\n\t *\n\t * @param action Type of clipboard action.\n\t * @param writer An instance of the model writer.\n\t * @param selection Selection to be checked.\n\t * @param getCopiedFragment\tCallback that performs copy of selection and returns it as fragment.\n\t * @internal\n\t */\n\tpublic _copySelectedFragmentWithMarkers(\n\t\taction: ClipboardMarkerRestrictedAction,\n\t\tselection: Selection | DocumentSelection,\n\t\tgetCopiedFragment: ( writer: Writer ) => DocumentFragment = writer =>\n\t\t\twriter.model.getSelectedContent( writer.model.document.selection )\n\t): DocumentFragment {\n\t\treturn this.editor.model.change( writer => {\n\t\t\tconst oldSelection = writer.model.document.selection;\n\n\t\t\t// In some scenarios, such like in drag & drop, passed `selection` parameter is not actually\n\t\t\t// the same `selection` as the `writer.model.document.selection` which means that `_insertFakeMarkersToSelection`\n\t\t\t// is not affecting passed `selection` `start` and `end` positions but rather modifies `writer.model.document.selection`.\n\t\t\t//\n\t\t\t// It is critical due to fact that when we have selection that starts [ 0, 0 ] and ends at [ 1, 0 ]\n\t\t\t// and after inserting fake marker it will point to such marker instead of new widget position at start: [ 1, 0 ] end: [2, 0 ].\n\t\t\t// `writer.insert` modifies only original `writer.model.document.selection`.\n\t\t\twriter.setSelection( selection );\n\n\t\t\tconst sourceSelectionInsertedMarkers = this._insertFakeMarkersIntoSelection( writer, writer.model.document.selection, action );\n\t\t\tconst fragment = getCopiedFragment( writer );\n\t\t\tconst fakeMarkersRangesInsideRange = this._removeFakeMarkersInsideElement( writer, fragment );\n\n\t\t\t// <fake-marker> [Foo] Bar</fake-marker>\n\t\t\t//      ^                    ^\n\t\t\t// In `_insertFakeMarkersIntoSelection` call we inserted fake marker just before first element.\n\t\t\t// The problem is that the first element can be start position of selection so insertion fake-marker\n\t\t\t// before such element shifts selection (so selection that was at [0, 0] now is at [0, 1]).\n\t\t\t// It means that inserted fake-marker is no longer present inside such selection and is orphaned.\n\t\t\t// This function checks special case of such problem. Markers that are orphaned at the start position\n\t\t\t// and end position in the same time. Basically it means that they overlaps whole element.\n\t\t\tfor ( const [ markerName, elements ] of Object.entries( sourceSelectionInsertedMarkers ) ) {\n\t\t\t\tfakeMarkersRangesInsideRange[ markerName ] ||= writer.createRangeIn( fragment );\n\n\t\t\t\tfor ( const element of elements ) {\n\t\t\t\t\twriter.remove( element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfragment.markers.clear();\n\n\t\t\tfor ( const [ markerName, range ] of Object.entries( fakeMarkersRangesInsideRange ) ) {\n\t\t\t\tfragment.markers.set( markerName, range );\n\t\t\t}\n\n\t\t\t// Revert back selection to previous one.\n\t\t\twriter.setSelection( oldSelection );\n\n\t\t\treturn fragment;\n\t\t} );\n\t}\n\n\t/**\n\t * Performs paste of markers on already pasted element.\n\t *\n\t * \t1. Inserts fake markers that are present in fragment element (such fragment will be processed in `getPastedDocumentElement`).\n\t * \t2. Calls `getPastedDocumentElement` and gets element that is inserted into root model.\n\t * \t3. Removes all fake markers present in transformed element.\n\t * \t4. Inserts new markers with removed fake markers ranges into pasted fragment.\n\t *\n\t * There are multiple edge cases that have to be considered before calling this function:\n\t *\n\t * \t* `markers` are inserted into the same element that must be later transformed inside `getPastedDocumentElement`.\n\t * \t* Fake marker elements inside `getPastedDocumentElement` can be cloned, but their ranges cannot overlap.\n\t * \t* If `duplicateOnPaste` is `true` in marker config then associated marker ID is regenerated before pasting.\n\t *\n\t * @param action Type of clipboard action.\n\t * @param markers Object that maps marker name to corresponding range.\n\t * @param getPastedDocumentElement Getter used to get target markers element.\n\t * @internal\n\t */\n\tpublic _pasteMarkersIntoTransformedElement(\n\t\tmarkers: Record<string, Range> | Map<string, Range>,\n\t\tgetPastedDocumentElement: ( writer: Writer ) => Element\n\t): Element {\n\t\tconst pasteMarkers = this._getPasteMarkersFromRangeMap( markers );\n\n\t\treturn this.editor.model.change( writer => {\n\t\t\t// Inserts fake markers into source fragment / element that is later transformed inside `getPastedDocumentElement`.\n\t\t\tconst sourceFragmentFakeMarkers = this._insertFakeMarkersElements( writer, pasteMarkers );\n\n\t\t\t// Modifies document fragment (for example, cloning table cells) and then inserts it into the document.\n\t\t\tconst transformedElement = getPastedDocumentElement( writer );\n\n\t\t\t// Removes markers in pasted and transformed fragment in root document.\n\t\t\tconst removedFakeMarkers = this._removeFakeMarkersInsideElement( writer, transformedElement );\n\n\t\t\t// Cleans up fake markers inserted into source fragment (that one before transformation which is not pasted).\n\t\t\tfor ( const element of Object.values( sourceFragmentFakeMarkers ).flat() ) {\n\t\t\t\twriter.remove( element );\n\t\t\t}\n\n\t\t\t// Inserts to root document fake markers.\n\t\t\tfor ( const [ markerName, range ] of Object.entries( removedFakeMarkers ) ) {\n\t\t\t\tif ( !writer.model.markers.has( markerName ) ) {\n\t\t\t\t\twriter.addMarker( markerName, {\n\t\t\t\t\t\tusingOperation: true,\n\t\t\t\t\t\taffectsData: true,\n\t\t\t\t\t\trange\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn transformedElement;\n\t\t} );\n\t}\n\n\t/**\n\t * Pastes document fragment with markers to document.\n\t * If `duplicateOnPaste` is `true` in marker config then associated markers IDs\n\t * are regenerated before pasting to avoid markers duplications in content.\n\t *\n\t * @param fragment Document fragment that should contain already processed by pipeline markers.\n\t * @internal\n\t */\n\tpublic _pasteFragmentWithMarkers( fragment: DocumentFragment ): Range {\n\t\tconst pasteMarkers = this._getPasteMarkersFromRangeMap( fragment.markers );\n\n\t\tfragment.markers.clear();\n\n\t\tfor ( const copyableMarker of pasteMarkers ) {\n\t\t\tfragment.markers.set( copyableMarker.name, copyableMarker.range );\n\t\t}\n\n\t\treturn this.editor.model.insertContent( fragment );\n\t}\n\n\t/**\n\t * In some situations we have to perform copy on selected fragment with certain markers. This function allows to temporarily bypass\n\t * restrictions on markers that we want to copy.\n\t *\n\t * This function executes `executor()` callback. For the duration of the callback, if the clipboard pipeline is used to copy\n\t * content, markers with the specified name will be copied to the clipboard as well.\n\t *\n\t * @param markerName Which markers should be copied.\n\t * @param executor Callback executed.\n\t * @param config Optional configuration flags used to copy (such like partial copy flag).\n\t * @internal\n\t */\n\tpublic _forceMarkersCopy(\n\t\tmarkerName: string,\n\t\texecutor: VoidFunction,\n\t\tconfig: ClipboardMarkerConfiguration = {\n\t\t\tallowedActions: 'all',\n\t\t\tcopyPartiallySelected: true,\n\t\t\tduplicateOnPaste: true\n\t\t}\n\t): void {\n\t\tconst before = this._markersToCopy.get( markerName );\n\n\t\tthis._markersToCopy.set( markerName, config );\n\n\t\texecutor();\n\n\t\tif ( before ) {\n\t\t\tthis._markersToCopy.set( markerName, before );\n\t\t} else {\n\t\t\tthis._markersToCopy.delete( markerName );\n\t\t}\n\t}\n\n\t/**\n\t * Checks if marker can be copied.\n\t *\n\t * @param markerName Name of checked marker.\n\t * @param action Type of clipboard action. If null then checks only if marker is registered as copyable.\n\t * @internal\n\t */\n\tpublic _isMarkerCopyable( markerName: string, action: ClipboardMarkerRestrictedAction | null ): boolean {\n\t\tconst config = this._getMarkerClipboardConfig( markerName );\n\n\t\tif ( !config ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If there is no action provided then only presence of marker is checked.\n\t\tif ( !action ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst { allowedActions } = config;\n\n\t\treturn allowedActions === 'all' || allowedActions.includes( action );\n\t}\n\n\t/**\n\t * Checks if marker has any clipboard copy behavior configuration.\n\t *\n\t * @param markerName Name of checked marker.\n\t */\n\tpublic _hasMarkerConfiguration( markerName: string ): boolean {\n\t\treturn !!this._getMarkerClipboardConfig( markerName );\n\t}\n\n\t/**\n\t * Returns marker's configuration flags passed during registration.\n\t *\n\t * @param markerName Name of marker that should be returned.\n\t * @internal\n\t */\n\tpublic _getMarkerClipboardConfig( markerName: string ): ClipboardMarkerConfiguration | null {\n\t\tconst [ markerNamePrefix ] = markerName.split( ':' );\n\n\t\treturn this._markersToCopy.get( markerNamePrefix ) || null;\n\t}\n\n\t/**\n\t * First step of copying markers. It looks for markers intersecting with given selection and inserts `$marker` elements\n\t * at positions where document markers start or end. This way `$marker` elements can be easily copied together with\n\t * the rest of the content of the selection.\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param selection Selection to be checked.\n\t * @param action Type of clipboard action.\n\t */\n\tprivate _insertFakeMarkersIntoSelection(\n\t\twriter: Writer,\n\t\tselection: Selection | DocumentSelection,\n\t\taction: ClipboardMarkerRestrictedAction\n\t): Record<string, Array<Element>> {\n\t\tconst copyableMarkers = this._getCopyableMarkersFromSelection( writer, selection, action );\n\n\t\treturn this._insertFakeMarkersElements( writer, copyableMarkers );\n\t}\n\n\t/**\n\t * Returns array of markers that can be copied in specified selection.\n\t *\n\t * If marker cannot be copied partially (according to `copyPartiallySelected` configuration flag) and\n\t * is not present entirely in any selection range then it will be skipped.\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param selection  Selection which will be checked.\n\t * @param action Type of clipboard action. If null then checks only if marker is registered as copyable.\n\t */\n\tprivate _getCopyableMarkersFromSelection(\n\t\twriter: Writer,\n\t\tselection: Selection | DocumentSelection,\n\t\taction: ClipboardMarkerRestrictedAction | null\n\t): Array<CopyableMarker> {\n\t\tconst selectionRanges = Array.from( selection.getRanges()! );\n\n\t\t// Picks all markers in provided ranges. Ensures that there are no duplications if\n\t\t// there are multiple ranges that intersects with the same marker.\n\t\tconst markersInRanges = new Set(\n\t\t\tselectionRanges.flatMap(\n\t\t\t\tselectionRange => Array.from( writer.model.markers.getMarkersIntersectingRange( selectionRange ) )\n\t\t\t)\n\t\t);\n\n\t\tconst isSelectionMarkerCopyable = ( marker: Marker ) => {\n\t\t\t// Check if marker exists in configuration and provided action can be performed on it.\n\t\t\tconst isCopyable = this._isMarkerCopyable( marker.name, action );\n\n\t\t\tif ( !isCopyable ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Checks if configuration disallows to copy marker only if part of its content is selected.\n\t\t\t//\n\t\t\t// Example:\n\t\t\t// \t<marker-a> Hello [ World ] </marker-a>\n\t\t\t//\t\t\t\t\t\t^ selection\n\t\t\t//\n\t\t\t// In this scenario `marker-a` won't be copied because selection doesn't overlap its content entirely.\n\t\t\tconst { copyPartiallySelected } = this._getMarkerClipboardConfig( marker.name )!;\n\n\t\t\tif ( !copyPartiallySelected ) {\n\t\t\t\tconst markerRange = marker.getRange();\n\n\t\t\t\treturn selectionRanges.some( selectionRange => selectionRange.containsRange( markerRange, true ) );\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\t\treturn Array\n\t\t\t.from( markersInRanges )\n\t\t\t.filter( isSelectionMarkerCopyable )\n\t\t\t.map( ( copyableMarker ): CopyableMarker => {\n\t\t\t\t// During `dragstart` event original marker is still present in tree.\n\t\t\t\t// It is removed after the clipboard drop event, so none of the copied markers are inserted at the end.\n\t\t\t\t// It happens because there already markers with specified `marker.name` when clipboard is trying to insert data\n\t\t\t\t// and it aborts inserting.\n\t\t\t\tconst name = action === 'dragstart' ? this._getUniqueMarkerName( copyableMarker.name ) : copyableMarker.name;\n\n\t\t\t\treturn {\n\t\t\t\t\tname,\n\t\t\t\t\trange: copyableMarker.getRange()\n\t\t\t\t};\n\t\t\t} );\n\t}\n\n\t/**\n\t * Picks all markers from markers map that can be pasted.\n\t * If `duplicateOnPaste` is `true`, it regenerates their IDs to ensure uniqueness.\n\t * If marker is not registered, it will be kept in the array anyway.\n\t *\n\t * @param markers Object that maps marker name to corresponding range.\n\t * @param action Type of clipboard action. If null then checks only if marker is registered as copyable.\n\t */\n\tprivate _getPasteMarkersFromRangeMap(\n\t\tmarkers: Record<string, Range> | Map<string, Range>,\n\t\taction: ClipboardMarkerRestrictedAction | null = null\n\t): Array<CopyableMarker> {\n\t\tconst { model } = this.editor;\n\t\tconst entries = markers instanceof Map ? Array.from( markers.entries() ) : Object.entries( markers );\n\n\t\treturn entries.flatMap( ( [ markerName, range ] ): Array<CopyableMarker> => {\n\t\t\tif ( !this._hasMarkerConfiguration( markerName ) ) {\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: markerName,\n\t\t\t\t\t\trange\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t}\n\n\t\t\tif ( this._isMarkerCopyable( markerName, action ) ) {\n\t\t\t\tconst copyMarkerConfig = this._getMarkerClipboardConfig( markerName )!;\n\t\t\t\tconst isInGraveyard = model.markers.has( markerName ) &&\n\t\t\t\t\tmodel.markers.get( markerName )!.getRange().root.rootName === '$graveyard';\n\n\t\t\t\tif ( copyMarkerConfig.duplicateOnPaste || isInGraveyard ) {\n\t\t\t\t\tmarkerName = this._getUniqueMarkerName( markerName );\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: markerName,\n\t\t\t\t\t\trange\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t}\n\n\t\t\treturn [];\n\t\t} );\n\t}\n\n\t/**\n\t * Inserts specified array of fake markers elements to document and assigns them `type` and `name` attributes.\n\t * Fake markers elements are used to calculate position of markers on pasted fragment that were transformed during\n\t * steps between copy and paste.\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param markers Array of markers that will be inserted.\n\t */\n\tprivate _insertFakeMarkersElements( writer: Writer, markers: Array<CopyableMarker> ): Record<string, Array<Element>> {\n\t\tconst mappedMarkers: Record<string, Array<Element>> = {};\n\t\tconst sortedMarkers = markers\n\t\t\t.flatMap( marker => {\n\t\t\t\tconst { start, end } = marker.range;\n\n\t\t\t\treturn [\n\t\t\t\t\t{ position: start, marker, type: 'start' },\n\t\t\t\t\t{ position: end, marker, type: 'end' }\n\t\t\t\t];\n\t\t\t} )\n\t\t\t// Markers position is sorted backwards to ensure that the insertion of fake markers will not change\n\t\t\t// the position of the next markers.\n\t\t\t.sort( ( { position: posA }, { position: posB } ) => posA.isBefore( posB ) ? 1 : -1 );\n\n\t\tfor ( const { position, marker, type } of sortedMarkers ) {\n\t\t\tconst fakeMarker = writer.createElement( '$marker', {\n\t\t\t\t'data-name': marker.name,\n\t\t\t\t'data-type': type\n\t\t\t} );\n\n\t\t\tif ( !mappedMarkers[ marker.name ] ) {\n\t\t\t\tmappedMarkers[ marker.name ] = [];\n\t\t\t}\n\n\t\t\tmappedMarkers[ marker.name ]!.push( fakeMarker );\n\t\t\twriter.insert( fakeMarker, position );\n\t\t}\n\n\t\treturn mappedMarkers;\n\t}\n\n\t/**\n\t * Removes all `$marker` elements from the given document fragment.\n\t *\n\t * Returns an object where keys are marker names, and values are ranges corresponding to positions\n\t * where `$marker` elements were inserted.\n\t *\n\t * If the document fragment had only one `$marker` element for given marker (start or end) the other boundary is set automatically\n\t * (to the end or start of the document fragment, respectively).\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param rootElement The element to be checked.\n\t */\n\tprivate _removeFakeMarkersInsideElement( writer: Writer, rootElement: Element | DocumentFragment ): Record<string, Range> {\n\t\tconst fakeMarkersElements = this._getAllFakeMarkersFromElement( writer, rootElement );\n\t\tconst fakeMarkersRanges = fakeMarkersElements.reduce<Record<string, FakeMarkerRangeConstruct>>( ( acc, fakeMarker ) => {\n\t\t\tconst position = fakeMarker.markerElement && writer.createPositionBefore( fakeMarker.markerElement );\n\t\t\tlet prevFakeMarker: FakeMarkerRangeConstruct | null = acc[ fakeMarker.name ];\n\n\t\t\t// Handle scenario when tables clone cells with the same fake node. Example:\n\t\t\t//\n\t\t\t// <cell><fake-marker-a></cell> <cell><fake-marker-a></cell> <cell><fake-marker-a></cell>\n\t\t\t//                                          ^ cloned                    ^ cloned\n\t\t\t//\n\t\t\t// The easiest way to bypass this issue is to rename already existing in map nodes and\n\t\t\t// set them new unique name.\n\t\t\tlet skipAssign = false;\n\n\t\t\tif ( prevFakeMarker && prevFakeMarker.start && prevFakeMarker.end ) {\n\t\t\t\tconst config = this._getMarkerClipboardConfig( fakeMarker.name )!;\n\n\t\t\t\tif ( config.duplicateOnPaste ) {\n\t\t\t\t\tacc[ this._getUniqueMarkerName( fakeMarker.name ) ] = acc[ fakeMarker.name ];\n\t\t\t\t} else {\n\t\t\t\t\tskipAssign = true;\n\t\t\t\t}\n\n\t\t\t\tprevFakeMarker = null;\n\t\t\t}\n\n\t\t\tif ( !skipAssign ) {\n\t\t\t\tacc[ fakeMarker.name ] = {\n\t\t\t\t\t...prevFakeMarker!,\n\t\t\t\t\t[ fakeMarker.type ]: position\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif ( fakeMarker.markerElement ) {\n\t\t\t\twriter.remove( fakeMarker.markerElement );\n\t\t\t}\n\n\t\t\treturn acc;\n\t\t}, {} );\n\n\t\t// We cannot construct ranges directly in previous reduce because element ranges can overlap.\n\t\t// In other words lets assume we have such scenario:\n\n\t\t// <fake-marker-start /> <paragraph /> <fake-marker-2-start /> <fake-marker-end /> <fake-marker-2-end />\n\t\t//\n\t\t// We have to remove `fake-marker-start` firstly and then remove `fake-marker-2-start`.\n\t\t// Removal of `fake-marker-2-start` affects `fake-marker-end` position so we cannot create\n\t\t// connection between `fake-marker-start` and `fake-marker-end` without iterating whole set firstly.\n\t\treturn mapValues(\n\t\t\tfakeMarkersRanges,\n\t\t\trange => new Range(\n\t\t\t\trange.start || writer.createPositionFromPath( rootElement, [ 0 ] ),\n\t\t\t\trange.end || writer.createPositionAt( rootElement, 'end' )\n\t\t\t)\n\t\t);\n\t}\n\n\t/**\n\t * Returns array that contains list of fake markers with corresponding `$marker` elements.\n\t *\n\t * For each marker, there can be two `$marker` elements or only one (if the document fragment contained\n\t * only the beginning or only the end of a marker).\n\t *\n\t * @param writer An instance of the model writer.\n\t * @param rootElement The element to be checked.\n\t */\n\tprivate _getAllFakeMarkersFromElement( writer: Writer, rootElement: Element | DocumentFragment ): Array<FakeMarker> {\n\t\tconst foundFakeMarkers = Array\n\t\t\t.from( writer.createRangeIn( rootElement ) )\n\t\t\t.flatMap( ( { item } ): Array<FakeMarker> => {\n\t\t\t\tif ( !item.is( 'element', '$marker' ) ) {\n\t\t\t\t\treturn [];\n\t\t\t\t}\n\n\t\t\t\tconst name = item.getAttribute( 'data-name' ) as string;\n\t\t\t\tconst type = item.getAttribute( 'data-type' ) as 'start' | 'end';\n\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tmarkerElement: item,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttype\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t} );\n\n\t\tconst prependFakeMarkers: Array<FakeMarker> = [];\n\t\tconst appendFakeMarkers: Array<FakeMarker> = [];\n\n\t\tfor ( const fakeMarker of foundFakeMarkers ) {\n\t\t\tif ( fakeMarker.type === 'end' ) {\n\t\t\t\t// <fake-marker> [ phrase</fake-marker> phrase ]\n\t\t\t\t//   ^\n\t\t\t\t// Handle case when marker is just before start of selection.\n\t\t\t\t// Only end marker is inside selection.\n\n\t\t\t\tconst hasMatchingStartMarker = foundFakeMarkers.some(\n\t\t\t\t\totherFakeMarker => otherFakeMarker.name === fakeMarker.name && otherFakeMarker.type === 'start'\n\t\t\t\t);\n\n\t\t\t\tif ( !hasMatchingStartMarker ) {\n\t\t\t\t\tprependFakeMarkers.push( {\n\t\t\t\t\t\tmarkerElement: null,\n\t\t\t\t\t\tname: fakeMarker.name,\n\t\t\t\t\t\ttype: 'start'\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( fakeMarker.type === 'start' ) {\n\t\t\t\t// [<fake-marker>phrase]</fake-marker>\n\t\t\t\t//                           ^\n\t\t\t\t// Handle case when fake marker is after selection.\n\t\t\t\t// Only start marker is inside selection.\n\n\t\t\t\tconst hasMatchingEndMarker = foundFakeMarkers.some(\n\t\t\t\t\totherFakeMarker => otherFakeMarker.name === fakeMarker.name && otherFakeMarker.type === 'end'\n\t\t\t\t);\n\n\t\t\t\tif ( !hasMatchingEndMarker ) {\n\t\t\t\t\tappendFakeMarkers.unshift( {\n\t\t\t\t\t\tmarkerElement: null,\n\t\t\t\t\t\tname: fakeMarker.name,\n\t\t\t\t\t\ttype: 'end'\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn [\n\t\t\t...prependFakeMarkers,\n\t\t\t...foundFakeMarkers,\n\t\t\t...appendFakeMarkers\n\t\t];\n\t}\n\n\t/**\n\t * When copy of markers occurs we have to make sure that pasted markers have different names\n\t * than source markers. This functions helps with assigning unique part to marker name to\n\t * prevent duplicated markers error.\n\t *\n\t * @param name Name of marker\n\t */\n\tprivate _getUniqueMarkerName( name: string ) {\n\t\tconst parts = name.split( ':' );\n\t\tconst newId = uid().substring( 1, 6 );\n\n\t\t// It looks like the marker already is UID marker so in this scenario just swap\n\t\t// last part of marker name and assign new UID.\n\t\t//\n\t\t// example: comment:{ threadId }:{ id } => comment:{ threadId }:{ newId }\n\t\tif ( parts.length === 3 ) {\n\t\t\treturn `${ parts.slice( 0, 2 ).join( ':' ) }:${ newId }`;\n\t\t}\n\n\t\t// Assign new segment to marker name with id.\n\t\t//\n\t\t// example: comment => comment:{ newId }\n\t\treturn `${ parts.join( ':' ) }:${ newId }`;\n\t}\n}\n\n/**\n * Specifies which action is performed during clipboard event.\n *\n * @internal\n */\nexport type ClipboardMarkerRestrictedAction = 'copy' | 'cut' | 'dragstart';\n\n/**\n * Specifies behavior of markers during clipboard actions.\n *\n * @internal\n */\nexport type ClipboardMarkerConfiguration = {\n\tallowedActions: NonEmptyArray<ClipboardMarkerRestrictedAction> | 'all';\n\n\t// If `false`, do not copy marker when only part of its content is selected.\n\tcopyPartiallySelected?: boolean;\n\n\t// If `true` then every marker that is present in clipboard document fragment element obtain new generated ID just before pasting.\n\t// It means that it is possible to perform copy once and then paste it multiple times wherever we want.\n\t//\n\t// On the other hand if it has false value the marker will be not pasted because ID already exists in the document.\n\t//\n\t// This flag is ignored in `cut` and `dragstart` actions because source marker is moved to graveyard and\n\t// it is still present in `model.markers`. Pasted marker id must be regenerated to avoid duplications.\n\tduplicateOnPaste?: boolean;\n};\n\n/**\n * Marker descriptor type used to revert markers into tree node.\n *\n * @internal\n */\ntype FakeMarker = {\n\ttype: 'start' | 'end';\n\tname: string;\n\tmarkerElement: Element | null;\n};\n\n/**\n * Range used to construct real markers from fake markers. Every property must be optional\n * because real marker range is constructed using iteration over markers that represent `start`\n * and then `end`. Usually `start` is set firstly then after few nodes `end` is set.\n *\n * @internal\n */\ntype FakeMarkerRangeConstruct = {\n\tstart: Position | null;\n\tend: Position | null;\n};\n\n/**\n * Structure used to describe marker that has to be copied.\n *\n * @internal\n */\ntype CopyableMarker = {\n\tname: string;\n\trange: Range;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/clipboardpipeline\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport { EventInfo } from '@ckeditor/ckeditor5-utils';\n\nimport type {\n\tDataTransfer,\n\tDocumentFragment,\n\tDomEventData,\n\tRange,\n\tViewDocumentFragment,\n\tViewRange,\n\tSelection,\n\tDocumentSelection\n} from '@ckeditor/ckeditor5-engine';\n\nimport ClipboardObserver, {\n\ttype ClipboardEventData,\n\ttype ViewDocumentCopyEvent,\n\ttype ViewDocumentCutEvent,\n\ttype ViewDocumentClipboardInputEvent\n} from './clipboardobserver.js';\n\nimport plainTextToHtml from './utils/plaintexttohtml.js';\nimport normalizeClipboardHtml from './utils/normalizeclipboarddata.js';\nimport viewToPlainText from './utils/viewtoplaintext.js';\nimport ClipboardMarkersUtils from './clipboardmarkersutils.js';\n\n// Input pipeline events overview:\n//\n//              ┌──────────────────────┐          ┌──────────────────────┐\n//              │     view.Document    │          │     view.Document    │\n//              │         paste        │          │         drop         │\n//              └───────────┬──────────┘          └───────────┬──────────┘\n//                          │                                 │\n//                          └────────────────┌────────────────┘\n//                                           │\n//                                 ┌─────────V────────┐\n//                                 │   view.Document  │   Retrieves text/html or text/plain from data.dataTransfer\n//                                 │  clipboardInput  │   and processes it to view.DocumentFragment.\n//                                 └─────────┬────────┘\n//                                           │\n//                               ┌───────────V───────────┐\n//                               │   ClipboardPipeline   │   Converts view.DocumentFragment to model.DocumentFragment.\n//                               │  inputTransformation  │\n//                               └───────────┬───────────┘\n//                                           │\n//                                ┌──────────V──────────┐\n//                                │  ClipboardPipeline  │   Calls model.insertContent().\n//                                │   contentInsertion  │\n//                                └─────────────────────┘\n//\n//\n// Output pipeline events overview:\n//\n//              ┌──────────────────────┐          ┌──────────────────────┐\n//              │     view.Document    │          │     view.Document    │   Retrieves the selected model.DocumentFragment\n//              │         copy         │          │          cut         │   and fires the `outputTransformation` event.\n//              └───────────┬──────────┘          └───────────┬──────────┘\n//                          │                                 │\n//                          └────────────────┌────────────────┘\n//                                           │\n//                               ┌───────────V───────────┐\n//                               │   ClipboardPipeline   │   Processes model.DocumentFragment and converts it to\n//                               │  outputTransformation │   view.DocumentFragment.\n//                               └───────────┬───────────┘\n//                                           │\n//                                 ┌─────────V────────┐\n//                                 │   view.Document  │   Processes view.DocumentFragment to text/html and text/plain\n//                                 │  clipboardOutput │   and stores the results in data.dataTransfer.\n//                                 └──────────────────┘\n//\n\n/**\n * The clipboard pipeline feature. It is responsible for intercepting the `paste` and `drop` events and\n * passing the pasted content through a series of events in order to insert it into the editor's content.\n * It also handles the `cut` and `copy` events to fill the native clipboard with the serialized editor's data.\n *\n * # Input pipeline\n *\n * The behavior of the default handlers (all at a `low` priority):\n *\n * ## Event: `paste` or `drop`\n *\n * 1. Translates the event data.\n * 2. Fires the {@link module:engine/view/document~Document#event:clipboardInput `view.Document#clipboardInput`} event.\n *\n * ## Event: `view.Document#clipboardInput`\n *\n * 1. If the `data.content` event field is already set (by some listener on a higher priority), it takes this content and fires the event\n *    from the last point.\n * 2. Otherwise, it retrieves `text/html` or `text/plain` from `data.dataTransfer`.\n * 3. Normalizes the raw data by applying simple filters on string data.\n * 4. Processes the raw data to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} with the\n *    {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.\n * 5. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation\n *   `ClipboardPipeline#inputTransformation`} event with the view document fragment in the `data.content` event field.\n *\n * ## Event: `ClipboardPipeline#inputTransformation`\n *\n * 1. Converts {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} from the `data.content` field to\n *    {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`}.\n * 2. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:contentInsertion `ClipboardPipeline#contentInsertion`}\n *    event with the model document fragment in the `data.content` event field.\n *    **Note**: The `ClipboardPipeline#contentInsertion` event is fired within a model change block to allow other handlers\n *    to run in the same block without post-fixers called in between (i.e., the selection post-fixer).\n *\n * ## Event: `ClipboardPipeline#contentInsertion`\n *\n * 1. Calls {@link module:engine/model/model~Model#insertContent `model.insertContent()`} to insert `data.content`\n *    at the current selection position.\n *\n * # Output pipeline\n *\n * The behavior of the default handlers (all at a `low` priority):\n *\n * ## Event: `copy`, `cut` or `dragstart`\n *\n * 1. Retrieves the selected {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`} by calling\n *    {@link module:engine/model/model~Model#getSelectedContent `model#getSelectedContent()`}.\n * 2. Converts the model document fragment to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`}.\n * 3. Fires the {@link module:engine/view/document~Document#event:clipboardOutput `view.Document#clipboardOutput`} event\n *    with the view document fragment in the `data.content` event field.\n *\n * ## Event: `view.Document#clipboardOutput`\n *\n * 1. Processes `data.content` to HTML and plain text with the\n *    {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}.\n * 2. Updates the `data.dataTransfer` data for `text/html` and `text/plain` with the processed data.\n * 3. For the `cut` method, calls {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`}\n *    on the current selection.\n *\n * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n */\nexport default class ClipboardPipeline extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ClipboardPipeline' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ClipboardMarkersUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\n\t\tview.addObserver( ClipboardObserver );\n\n\t\tthis._setupPasteDrop();\n\t\tthis._setupCopyCut();\n\t}\n\n\t/**\n\t * Fires Clipboard `'outputTransformation'` event for given parameters.\n\t *\n\t * @internal\n\t */\n\tpublic _fireOutputTransformationEvent(\n\t\tdataTransfer: DataTransfer,\n\t\tselection: Selection | DocumentSelection,\n\t\tmethod: 'copy' | 'cut' | 'dragstart'\n\t): void {\n\t\tconst clipboardMarkersUtils: ClipboardMarkersUtils = this.editor.plugins.get( 'ClipboardMarkersUtils' );\n\n\t\tthis.editor.model.enqueueChange( { isUndoable: method === 'cut' }, () => {\n\t\t\tconst documentFragment = clipboardMarkersUtils._copySelectedFragmentWithMarkers( method, selection );\n\n\t\t\tthis.fire<ClipboardOutputTransformationEvent>( 'outputTransformation', {\n\t\t\t\tdataTransfer,\n\t\t\t\tcontent: documentFragment,\n\t\t\t\tmethod\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * The clipboard paste pipeline.\n\t */\n\tprivate _setupPasteDrop(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst clipboardMarkersUtils: ClipboardMarkersUtils = this.editor.plugins.get( 'ClipboardMarkersUtils' );\n\n\t\t// Pasting is disabled when selection is in non-editable place.\n\t\t// Dropping is disabled in drag and drop handler.\n\t\tthis.listenTo<ViewDocumentClipboardInputEvent>( viewDocument, 'clipboardInput', ( evt, data ) => {\n\t\t\tif ( data.method == 'paste' && !editor.model.canEditAt( editor.model.document.selection ) ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo<ViewDocumentClipboardInputEvent>( viewDocument, 'clipboardInput', ( evt, data ) => {\n\t\t\tconst dataTransfer = data.dataTransfer;\n\t\t\tlet content: ViewDocumentFragment;\n\n\t\t\t// Some feature could already inject content in the higher priority event handler (i.e., codeBlock).\n\t\t\tif ( data.content ) {\n\t\t\t\tcontent = data.content;\n\t\t\t} else {\n\t\t\t\tlet contentData = '';\n\n\t\t\t\tif ( dataTransfer.getData( 'text/html' ) ) {\n\t\t\t\t\tcontentData = normalizeClipboardHtml( dataTransfer.getData( 'text/html' ) );\n\t\t\t\t} else if ( dataTransfer.getData( 'text/plain' ) ) {\n\t\t\t\t\tcontentData = plainTextToHtml( dataTransfer.getData( 'text/plain' ) );\n\t\t\t\t}\n\n\t\t\t\tcontent = this.editor.data.htmlProcessor.toView( contentData );\n\t\t\t}\n\n\t\t\tconst eventInfo = new EventInfo( this, 'inputTransformation' );\n\n\t\t\tthis.fire<ClipboardInputTransformationEvent>( eventInfo, {\n\t\t\t\tcontent,\n\t\t\t\tdataTransfer,\n\t\t\t\ttargetRanges: data.targetRanges,\n\t\t\t\tmethod: data.method as 'paste' | 'drop'\n\t\t\t} );\n\n\t\t\t// If CKEditor handled the input, do not bubble the original event any further.\n\t\t\t// This helps external integrations recognize this fact and act accordingly.\n\t\t\t// https://github.com/ckeditor/ckeditor5-upload/issues/92\n\t\t\tif ( eventInfo.stop.called ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\n\t\t\tview.scrollToTheSelection();\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo<ClipboardInputTransformationEvent>( this, 'inputTransformation', ( evt, data ) => {\n\t\t\tif ( data.content.isEmpty ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst dataController = this.editor.data;\n\n\t\t\t// Convert the pasted content into a model document fragment.\n\t\t\t// The conversion is contextual, but in this case an \"all allowed\" context is needed\n\t\t\t// and for that we use the $clipboardHolder item.\n\t\t\tconst modelFragment = dataController.toModel( data.content, '$clipboardHolder' );\n\n\t\t\tif ( modelFragment.childCount == 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tevt.stop();\n\n\t\t\t// Fire content insertion event in a single change block to allow other handlers to run in the same block\n\t\t\t// without post-fixers called in between (i.e., the selection post-fixer).\n\t\t\tmodel.change( () => {\n\t\t\t\tthis.fire<ClipboardContentInsertionEvent>( 'contentInsertion', {\n\t\t\t\t\tcontent: modelFragment,\n\t\t\t\t\tmethod: data.method,\n\t\t\t\t\tdataTransfer: data.dataTransfer,\n\t\t\t\t\ttargetRanges: data.targetRanges\n\t\t\t\t} );\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo<ClipboardContentInsertionEvent>( this, 'contentInsertion', ( evt, data ) => {\n\t\t\tdata.resultRange = clipboardMarkersUtils._pasteFragmentWithMarkers( data.content );\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * The clipboard copy/cut pipeline.\n\t */\n\tprivate _setupCopyCut(): void {\n\t\tconst editor = this.editor;\n\t\tconst modelDocument = editor.model.document;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\tconst onCopyCut = ( evt: EventInfo<'copy' | 'cut'>, data: DomEventData<ClipboardEvent> & ClipboardEventData ) => {\n\t\t\tconst dataTransfer = data.dataTransfer;\n\n\t\t\tdata.preventDefault();\n\n\t\t\tthis._fireOutputTransformationEvent( dataTransfer, modelDocument.selection, evt.name );\n\t\t};\n\n\t\tthis.listenTo<ViewDocumentCopyEvent>( viewDocument, 'copy', onCopyCut, { priority: 'low' } );\n\t\tthis.listenTo<ViewDocumentCutEvent>( viewDocument, 'cut', ( evt, data ) => {\n\t\t\t// Cutting is disabled when selection is in non-editable place.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26.\n\t\t\tif ( !editor.model.canEditAt( editor.model.document.selection ) ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t} else {\n\t\t\t\tonCopyCut( evt, data );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo<ClipboardOutputTransformationEvent>( this, 'outputTransformation', ( evt, data ) => {\n\t\t\tconst content = editor.data.toView( data.content );\n\n\t\t\tviewDocument.fire<ViewDocumentClipboardOutputEvent>( 'clipboardOutput', {\n\t\t\t\tdataTransfer: data.dataTransfer,\n\t\t\t\tcontent,\n\t\t\t\tmethod: data.method\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\n\t\tthis.listenTo<ViewDocumentClipboardOutputEvent>( viewDocument, 'clipboardOutput', ( evt, data ) => {\n\t\t\tif ( !data.content.isEmpty ) {\n\t\t\t\tdata.dataTransfer.setData( 'text/html', this.editor.data.htmlProcessor.toData( data.content ) );\n\t\t\t\tdata.dataTransfer.setData( 'text/plain', viewToPlainText( data.content ) );\n\t\t\t}\n\n\t\t\tif ( data.method == 'cut' ) {\n\t\t\t\teditor.model.deleteContent( modelDocument.selection );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n/**\n * Fired with the `content`, `dataTransfer`, `method`, and `targetRanges` properties:\n *\n * * The `content` which comes from the clipboard (it was pasted or dropped) should be processed in order to be inserted into the editor.\n * * The `dataTransfer` object is available in case the transformation functions need access to the raw clipboard data.\n * * The `method` indicates the original DOM event (for example `'drop'` or `'paste'`).\n * * The `targetRanges` property is an array of view ranges (it is available only for `'drop'`).\n *\n * It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.\n *\n * **Note**: You should not stop this event if you want to change the input data. You should modify the `content` property instead.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboardpipeline~ClipboardPipeline\n *\n * @eventName ~ClipboardPipeline#inputTransformation\n * @param data The event data.\n */\nexport type ClipboardInputTransformationEvent = {\n\tname: 'inputTransformation';\n\targs: [ data: ClipboardInputTransformationData ];\n};\n\n/**\n * The data of 'inputTransformation' event.\n */\nexport interface ClipboardInputTransformationData {\n\n\t/**\n\t * The event data.\n\t * The content to be inserted into the editor. It can be modified by event listeners. Read more about the clipboard pipelines in\n\t * the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n\t */\n\tcontent: ViewDocumentFragment;\n\n\t/**\n\t * The data transfer instance.\n\t */\n\tdataTransfer: DataTransfer;\n\n\t/**\n\t * The target drop ranges.\n\t */\n\ttargetRanges: Array<ViewRange> | null;\n\n\t/**\n\t * Whether the event was triggered by a paste or a drop operation.\n\t */\n\tmethod: 'paste' | 'drop';\n}\n\n/**\n * Fired with the `content`, `dataTransfer`, `method`, and `targetRanges` properties:\n *\n * * The `content` which comes from the clipboard (was pasted or dropped) should be processed in order to be inserted into the editor.\n * * The `dataTransfer` object is available in case the transformation functions need access to the raw clipboard data.\n * * The `method` indicates the original DOM event (for example `'drop'` or `'paste'`).\n * * The `targetRanges` property is an array of view ranges (it is available only for `'drop'`).\n *\n * Event handlers can modify the content according to the final insertion position.\n *\n * It is a part of the {@glink framework/deep-dive/clipboard#input-pipeline clipboard input pipeline}.\n *\n * **Note**: You should not stop this event if you want to change the input data. You should modify the `content` property instead.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboardpipeline~ClipboardPipeline\n * @see module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation\n *\n * @eventName ~ClipboardPipeline#contentInsertion\n * @param data The event data.\n */\nexport type ClipboardContentInsertionEvent = {\n\tname: 'contentInsertion';\n\targs: [ data: ClipboardContentInsertionData ];\n};\n\n/**\n * The data of 'contentInsertion' event.\n */\nexport interface ClipboardContentInsertionData {\n\n\t/**\n\t * The content to be inserted into the editor.\n\t * Read more about the clipboard pipelines in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n\t */\n\tcontent: DocumentFragment;\n\n\t/**\n\t * Whether the event was triggered by a paste or a drop operation.\n\t */\n\tmethod: 'paste' | 'drop';\n\n\t/**\n\t * The data transfer instance.\n\t */\n\n\tdataTransfer: DataTransfer;\n\n\t/**\n\t * The target drop ranges.\n\t */\n\ttargetRanges: Array<ViewRange> | null;\n\n\t/**\n\t * The result of the `model.insertContent()` call\n\t * (inserted by the event handler at a low priority).\n\t */\n\tresultRange?: Range;\n}\n\n/**\n * Fired on {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut}\n * with a copy of the selected content. The content can be processed before it ends up in the clipboard.\n *\n * It is a part of the {@glink framework/deep-dive/clipboard#output-pipeline clipboard output pipeline}.\n *\n * @see module:clipboard/clipboardobserver~ClipboardObserver\n * @see module:clipboard/clipboardpipeline~ClipboardPipeline\n *\n * @eventName module:engine/view/document~Document#clipboardOutput\n * @param data The event data.\n */\nexport type ViewDocumentClipboardOutputEvent = {\n\tname: 'clipboardOutput';\n\targs: [ data: ViewDocumentClipboardOutputEventData ];\n};\n\n/**\n * The value of the 'clipboardOutput' event.\n */\nexport interface ViewDocumentClipboardOutputEventData {\n\n\t/**\n\t * The data transfer instance.\n\t *\n\t * @readonly\n\t */\n\tdataTransfer: DataTransfer;\n\n\t/**\n\t * Content to be put into the clipboard. It can be modified by the event listeners.\n\t * Read more about the clipboard pipelines in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n\t */\n\tcontent: ViewDocumentFragment;\n\n\t/**\n\t * Whether the event was triggered by a copy or cut operation.\n\t */\n\tmethod: 'copy' | 'cut' | 'dragstart';\n}\n\n/**\n * Fired on {@link module:engine/view/document~Document#event:copy}, {@link module:engine/view/document~Document#event:cut}\n * and {@link module:engine/view/document~Document#event:dragstart}. The content can be processed before it ends up in the clipboard.\n *\n * It is a part of the {@glink framework/deep-dive/clipboard#output-pipeline clipboard output pipeline}.\n *\n * @eventName ~ClipboardPipeline#outputTransformation\n * @param data The event data.\n */\nexport type ClipboardOutputTransformationEvent = {\n\tname: 'outputTransformation';\n\targs: [ data: ClipboardOutputTransformationData ];\n};\n\n/**\n * The value of the 'outputTransformation' event.\n */\nexport interface ClipboardOutputTransformationData {\n\n\t/**\n\t * The data transfer instance.\n\t *\n\t * @readonly\n\t */\n\tdataTransfer: DataTransfer;\n\n\t/**\n\t * Content to be put into the clipboard. It can be modified by the event listeners.\n\t * Read more about the clipboard pipelines in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n\t */\n\tcontent: DocumentFragment;\n\n\t/**\n\t * Whether the event was triggered by a copy or cut operation.\n\t */\n\tmethod: 'copy' | 'cut' | 'dragstart';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/lineview\n */\n\n/* istanbul ignore file -- @preserve */\n\nimport { View } from '@ckeditor/ckeditor5-ui';\nimport { toUnit } from '@ckeditor/ckeditor5-utils';\n\nconst toPx = /* #__PURE__ */ toUnit( 'px' );\n\n/**\n * The horizontal drop target line view.\n */\nexport default class LineView extends View {\n\t/**\n\t * Controls whether the line is visible.\n\t *\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isVisible: boolean;\n\n\t/**\n\t * Controls the line position x coordinate.\n\t *\n\t * @observable\n\t * @default null\n\t */\n\tdeclare public left: number | null;\n\n\t/**\n\t * Controls the line width.\n\t *\n\t * @observable\n\t * @default null\n\t */\n\tdeclare public width: number | null;\n\n\t/**\n\t * Controls the line position y coordinate.\n\t *\n\t * @observable\n\t * @default null\n\t */\n\tdeclare public top: number | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( {\n\t\t\tisVisible: false,\n\t\t\tleft: null,\n\t\t\ttop: null,\n\t\t\twidth: null\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-clipboard-drop-target-line',\n\t\t\t\t\tbind.if( 'isVisible', 'ck-hidden', value => !value )\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\tleft: bind.to( 'left', left => toPx( left! ) ),\n\t\t\t\t\ttop: bind.to( 'top', top => toPx( top! ) ),\n\t\t\t\t\twidth: bind.to( 'width', width => toPx( width! ) )\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/dragdroptarget\n */\n\nimport {\n\tPlugin,\n\ttype Editor\n} from '@ckeditor/ckeditor5-core';\n\nimport {\n\ttype Node,\n\ttype Element,\n\ttype Range,\n\ttype LiveRange,\n\ttype ViewElement,\n\ttype ViewRange,\n\ttype DowncastWriter,\n\ttype ViewRootEditableElement\n} from '@ckeditor/ckeditor5-engine';\n\nimport {\n\tglobal,\n\tRect,\n\tDomEmitterMixin,\n\tdelay,\n\tResizeObserver,\n\ttype DomEmitter\n} from '@ckeditor/ckeditor5-utils';\n\nimport LineView from './lineview.js';\n\nimport { throttle } from 'lodash-es';\n\n/**\n * Part of the Drag and Drop handling. Responsible for finding and displaying the drop target.\n *\n * @internal\n */\nexport default class DragDropTarget extends Plugin {\n\t/**\n\t * A delayed callback removing the drop marker.\n\t *\n\t * @internal\n\t */\n\tpublic readonly removeDropMarkerDelayed = delay( () => this.removeDropMarker(), 40 );\n\n\t/**\n\t * A throttled callback updating the drop marker.\n\t */\n\tprivate readonly _updateDropMarkerThrottled = throttle(\n\t\ttargetRange => this._updateDropMarker( targetRange ), 40\n\t);\n\n\t/**\n\t * A throttled callback reconverting the drop parker.\n\t */\n\tprivate readonly _reconvertMarkerThrottled = throttle( () => {\n\t\tif ( this.editor.model.markers.has( 'drop-target' ) ) {\n\t\t\tthis.editor.editing.reconvertMarker( 'drop-target' );\n\t\t}\n\t}, 0 );\n\n\t/**\n\t * The horizontal drop target line view.\n\t */\n\tprivate _dropTargetLineView = new LineView();\n\n\t/**\n\t * DOM Emitter.\n\t */\n\tprivate _domEmitter: DomEmitter = new ( DomEmitterMixin() )();\n\n\t/**\n\t * Map of document scrollable elements.\n\t */\n\tprivate _scrollables = new Map<string, {\n\t\tdomElement: HTMLElement;\n\t\tresizeObserver: ResizeObserver;\n\t}>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'DragDropTarget' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tthis._setupDropMarker();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis._domEmitter.stopListening();\n\n\t\tfor ( const { resizeObserver } of this._scrollables.values() ) {\n\t\t\tresizeObserver.destroy();\n\t\t}\n\n\t\tthis._updateDropMarkerThrottled.cancel();\n\t\tthis.removeDropMarkerDelayed.cancel();\n\t\tthis._reconvertMarkerThrottled.cancel();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Finds the drop target range and updates the drop marker.\n\t *\n\t * @internal\n\t */\n\tpublic updateDropMarker(\n\t\ttargetViewElement: ViewElement,\n\t\ttargetViewRanges: Array<ViewRange> | null,\n\t\tclientX: number,\n\t\tclientY: number,\n\t\tblockMode: boolean,\n\t\tdraggedRange: LiveRange | null\n\t): void {\n\t\tthis.removeDropMarkerDelayed.cancel();\n\n\t\tconst targetRange = findDropTargetRange(\n\t\t\tthis.editor,\n\t\t\ttargetViewElement,\n\t\t\ttargetViewRanges,\n\t\t\tclientX,\n\t\t\tclientY,\n\t\t\tblockMode,\n\t\t\tdraggedRange\n\t\t);\n\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif ( !targetRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( draggedRange && draggedRange.containsRange( targetRange ) ) {\n\t\t\t// Target range is inside the dragged range.\n\t\t\treturn this.removeDropMarker();\n\t\t}\n\n\t\tthis._updateDropMarkerThrottled( targetRange );\n\t}\n\n\t/**\n\t * Finds the final drop target range.\n\t *\n\t * @internal\n\t */\n\tpublic getFinalDropRange(\n\t\ttargetViewElement: ViewElement,\n\t\ttargetViewRanges: Array<ViewRange> | null,\n\t\tclientX: number,\n\t\tclientY: number,\n\t\tblockMode: boolean,\n\t\tdraggedRange: LiveRange | null\n\t): Range | null {\n\t\tconst targetRange = findDropTargetRange(\n\t\t\tthis.editor,\n\t\t\ttargetViewElement,\n\t\t\ttargetViewRanges,\n\t\t\tclientX,\n\t\t\tclientY,\n\t\t\tblockMode,\n\t\t\tdraggedRange\n\t\t);\n\t\t// The dragging markers must be removed after searching for the target range because sometimes\n\t\t// the target lands on the marker itself.\n\t\tthis.removeDropMarker();\n\n\t\treturn targetRange;\n\t}\n\n\t/**\n\t * Removes the drop target marker.\n\t *\n\t * @internal\n\t */\n\tpublic removeDropMarker(): void {\n\t\tconst model = this.editor.model;\n\n\t\tthis.removeDropMarkerDelayed.cancel();\n\t\tthis._updateDropMarkerThrottled.cancel();\n\t\tthis._dropTargetLineView.isVisible = false;\n\n\t\tif ( model.markers.has( 'drop-target' ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.removeMarker( 'drop-target' );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Creates downcast conversion for the drop target marker.\n\t */\n\tprivate _setupDropMarker(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.view.body.add( this._dropTargetLineView );\n\n\t\t// Drop marker conversion for hovering over widgets.\n\t\teditor.conversion.for( 'editingDowncast' ).markerToHighlight( {\n\t\t\tmodel: 'drop-target',\n\t\t\tview: {\n\t\t\t\tclasses: [ 'ck-clipboard-drop-target-range' ]\n\t\t\t}\n\t\t} );\n\n\t\t// Drop marker conversion for in text and block drop target.\n\t\teditor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t\t\tmodel: 'drop-target',\n\t\t\tview: ( data, { writer } ) => {\n\t\t\t\t// Inline drop.\n\t\t\t\tif ( editor.model.schema.checkChild( data.markerRange.start, '$text' ) ) {\n\t\t\t\t\tthis._dropTargetLineView.isVisible = false;\n\n\t\t\t\t\treturn this._createDropTargetPosition( writer );\n\t\t\t\t}\n\t\t\t\t// Block drop.\n\t\t\t\telse {\n\t\t\t\t\tif ( data.markerRange.isCollapsed ) {\n\t\t\t\t\t\tthis._updateDropTargetLine( data.markerRange );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._dropTargetLineView.isVisible = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the drop target marker to the provided range.\n\t *\n\t * @param targetRange The range to set the marker to.\n\t */\n\tprivate _updateDropMarker( targetRange: Range ): void {\n\t\tconst editor = this.editor;\n\t\tconst markers = editor.model.markers;\n\n\t\teditor.model.change( writer => {\n\t\t\tif ( markers.has( 'drop-target' ) ) {\n\t\t\t\tif ( !markers.get( 'drop-target' )!.getRange().isEqual( targetRange ) ) {\n\t\t\t\t\twriter.updateMarker( 'drop-target', { range: targetRange } );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twriter.addMarker( 'drop-target', {\n\t\t\t\t\trange: targetRange,\n\t\t\t\t\tusingOperation: false,\n\t\t\t\t\taffectsData: false\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the UI element for vertical (in-line) drop target.\n\t */\n\tprivate _createDropTargetPosition( writer: DowncastWriter ): ViewElement {\n\t\treturn writer.createUIElement( 'span', { class: 'ck ck-clipboard-drop-target-position' }, function( domDocument ) {\n\t\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t\t// Using word joiner to make this marker as high as text and also making text not break on marker.\n\t\t\tdomElement.append( '\\u2060', domDocument.createElement( 'span' ), '\\u2060' );\n\n\t\t\treturn domElement;\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the horizontal drop target line.\n\t */\n\tprivate _updateDropTargetLine( range: Range ): void {\n\t\tconst editing = this.editor.editing;\n\n\t\tconst nodeBefore = range.start.nodeBefore as Element | null;\n\t\tconst nodeAfter = range.start.nodeAfter as Element | null;\n\t\tconst nodeParent = range.start.parent as Element;\n\n\t\tconst viewElementBefore = nodeBefore ? editing.mapper.toViewElement( nodeBefore ) : null;\n\t\tconst domElementBefore = viewElementBefore ? editing.view.domConverter.mapViewToDom( viewElementBefore ) : null;\n\n\t\tconst viewElementAfter = nodeAfter ? editing.mapper.toViewElement( nodeAfter )! : null;\n\t\tconst domElementAfter = viewElementAfter ? editing.view.domConverter.mapViewToDom( viewElementAfter ) : null;\n\n\t\tconst viewElementParent = editing.mapper.toViewElement( nodeParent )!;\n\n\t\tif ( !viewElementParent ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domElementParent = editing.view.domConverter.mapViewToDom( viewElementParent )!;\n\n\t\tconst domScrollableRect = this._getScrollableRect( viewElementParent );\n\n\t\tconst { scrollX, scrollY } = global.window;\n\t\tconst rectBefore = domElementBefore ? new Rect( domElementBefore ) : null;\n\t\tconst rectAfter = domElementAfter ? new Rect( domElementAfter ) : null;\n\t\tconst rectParent = new Rect( domElementParent ).excludeScrollbarsAndBorders();\n\n\t\tconst above = rectBefore ? rectBefore.bottom : rectParent.top;\n\t\tconst below = rectAfter ? rectAfter.top : rectParent.bottom;\n\n\t\tconst parentStyle = global.window.getComputedStyle( domElementParent );\n\t\tconst top = ( above <= below ? ( above + below ) / 2 : below );\n\n\t\tif ( domScrollableRect.top < top && top < domScrollableRect.bottom ) {\n\t\t\tconst left = rectParent.left + parseFloat( parentStyle.paddingLeft );\n\t\t\tconst right = rectParent.right - parseFloat( parentStyle.paddingRight );\n\n\t\t\tconst leftClamped = Math.max( left + scrollX, domScrollableRect.left );\n\t\t\tconst rightClamped = Math.min( right + scrollX, domScrollableRect.right );\n\n\t\t\tthis._dropTargetLineView.set( {\n\t\t\t\tisVisible: true,\n\t\t\t\tleft: leftClamped,\n\t\t\t\ttop: top + scrollY,\n\t\t\t\twidth: rightClamped - leftClamped\n\t\t\t} );\n\t\t} else {\n\t\t\tthis._dropTargetLineView.isVisible = false;\n\t\t}\n\t}\n\n\t/**\n\t * Finds the closest scrollable element rect for the given view element.\n\t */\n\tprivate _getScrollableRect( viewElement: ViewElement ): Rect {\n\t\tconst rootName = ( viewElement.root as ViewRootEditableElement ).rootName;\n\n\t\tlet domScrollable;\n\n\t\tif ( this._scrollables.has( rootName ) ) {\n\t\t\tdomScrollable = this._scrollables.get( rootName )!.domElement;\n\t\t} else {\n\t\t\tconst domElement = this.editor.editing.view.domConverter.mapViewToDom( viewElement )!;\n\n\t\t\tdomScrollable = findScrollableElement( domElement );\n\n\t\t\tthis._domEmitter.listenTo( domScrollable, 'scroll', this._reconvertMarkerThrottled, { usePassive: true } );\n\t\t\tconst resizeObserver = new ResizeObserver( domScrollable, this._reconvertMarkerThrottled );\n\n\t\t\tthis._scrollables.set( rootName, {\n\t\t\t\tdomElement: domScrollable,\n\t\t\t\tresizeObserver\n\t\t\t} );\n\t\t}\n\n\t\treturn new Rect( domScrollable ).excludeScrollbarsAndBorders();\n\t}\n}\n\n/**\n * Returns fixed selection range for given position and target element.\n */\nfunction findDropTargetRange(\n\teditor: Editor,\n\ttargetViewElement: ViewElement,\n\ttargetViewRanges: Array<ViewRange> | null,\n\tclientX: number,\n\tclientY: number,\n\tblockMode: boolean,\n\tdraggedRange: LiveRange | null\n): Range | null {\n\tconst model = editor.model;\n\tconst mapper = editor.editing.mapper;\n\n\tconst targetModelElement = getClosestMappedModelElement( editor, targetViewElement );\n\tlet modelElement = targetModelElement;\n\n\twhile ( modelElement ) {\n\t\tif ( !blockMode ) {\n\t\t\tif ( model.schema.checkChild( modelElement, '$text' ) ) {\n\t\t\t\tif ( targetViewRanges ) {\n\t\t\t\t\tconst targetViewPosition = targetViewRanges[ 0 ].start;\n\t\t\t\t\tconst targetModelPosition = mapper.toModelPosition( targetViewPosition );\n\t\t\t\t\tconst canDropOnPosition = !draggedRange || Array\n\t\t\t\t\t\t.from( draggedRange.getItems() )\n\t\t\t\t\t\t.every( item => model.schema.checkChild( targetModelPosition, item as Node ) );\n\n\t\t\t\t\tif ( canDropOnPosition ) {\n\t\t\t\t\t\tif ( model.schema.checkChild( targetModelPosition, '$text' ) ) {\n\t\t\t\t\t\t\treturn model.createRange( targetModelPosition );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ( targetViewPosition ) {\n\t\t\t\t\t\t// This is the case of dropping inside a span wrapper of an inline image.\n\t\t\t\t\t\t\treturn findDropTargetRangeForElement(\n\t\t\t\t\t\t\t\teditor,\n\t\t\t\t\t\t\t\tgetClosestMappedModelElement( editor, targetViewPosition.parent as ViewElement ),\n\t\t\t\t\t\t\t\tclientX,\n\t\t\t\t\t\t\t\tclientY\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( model.schema.isInline( modelElement ) ) {\n\t\t\t\treturn findDropTargetRangeForElement( editor, modelElement, clientX, clientY );\n\t\t\t}\n\t\t}\n\n\t\tif ( model.schema.isBlock( modelElement ) ) {\n\t\t\treturn findDropTargetRangeForElement( editor, modelElement, clientX, clientY );\n\t\t}\n\t\telse if ( model.schema.checkChild( modelElement, '$block' ) ) {\n\t\t\tconst childNodes = Array.from( modelElement.getChildren() )\n\t\t\t\t.filter( ( node ): node is Element => node.is( 'element' ) && !shouldIgnoreElement( editor, node ) );\n\n\t\t\tlet startIndex = 0;\n\t\t\tlet endIndex = childNodes.length;\n\n\t\t\tif ( endIndex == 0 ) {\n\t\t\t\treturn model.createRange( model.createPositionAt( modelElement as Element, 'end' ) );\n\t\t\t}\n\n\t\t\twhile ( startIndex < endIndex - 1 ) {\n\t\t\t\tconst middleIndex = Math.floor( ( startIndex + endIndex ) / 2 );\n\t\t\t\tconst side = findElementSide( editor, childNodes[ middleIndex ], clientX, clientY );\n\n\t\t\t\tif ( side == 'before' ) {\n\t\t\t\t\tendIndex = middleIndex;\n\t\t\t\t} else {\n\t\t\t\t\tstartIndex = middleIndex;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn findDropTargetRangeForElement( editor, childNodes[ startIndex ], clientX, clientY );\n\t\t}\n\n\t\tmodelElement = modelElement.parent as Element;\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns true for elements which should be ignored.\n */\nfunction shouldIgnoreElement( editor: Editor, modelElement: Element ): boolean {\n\tconst mapper = editor.editing.mapper;\n\tconst domConverter = editor.editing.view.domConverter;\n\n\tconst viewElement = mapper.toViewElement( modelElement )!;\n\n\tif ( !viewElement ) {\n\t\treturn true;\n\t}\n\n\tconst domElement = domConverter.mapViewToDom( viewElement )!;\n\n\treturn global.window.getComputedStyle( domElement ).float != 'none';\n}\n\n/**\n * Returns target range relative to the given element.\n */\nfunction findDropTargetRangeForElement( editor: Editor, modelElement: Element, clientX: number, clientY: number ): Range {\n\tconst model = editor.model;\n\n\treturn model.createRange(\n\t\tmodel.createPositionAt(\n\t\t\tmodelElement as Element,\n\t\t\tfindElementSide( editor, modelElement, clientX, clientY )\n\t\t)\n\t);\n}\n\n/**\n * Resolves whether drop marker should be before or after the given element.\n */\nfunction findElementSide( editor: Editor, modelElement: Element, clientX: number, clientY: number ): 'before' | 'after' {\n\tconst mapper = editor.editing.mapper;\n\tconst domConverter = editor.editing.view.domConverter;\n\n\tconst viewElement = mapper.toViewElement( modelElement )!;\n\tconst domElement = domConverter.mapViewToDom( viewElement )!;\n\tconst rect = new Rect( domElement );\n\n\tif ( editor.model.schema.isInline( modelElement ) ) {\n\t\treturn clientX < ( rect.left + rect.right ) / 2 ? 'before' : 'after';\n\t} else {\n\t\treturn clientY < ( rect.top + rect.bottom ) / 2 ? 'before' : 'after';\n\t}\n}\n\n/**\n * Returns the closest model element for the specified view element.\n */\nfunction getClosestMappedModelElement( editor: Editor, element: ViewElement ): Element {\n\tconst mapper = editor.editing.mapper;\n\tconst view = editor.editing.view;\n\n\tconst targetModelElement = mapper.toModelElement( element );\n\n\tif ( targetModelElement ) {\n\t\treturn targetModelElement;\n\t}\n\n\t// Find mapped ancestor if the target is inside not mapped element (for example inline code element).\n\tconst viewPosition = view.createPositionBefore( element );\n\tconst viewElement = mapper.findMappedViewAncestor( viewPosition );\n\n\treturn mapper.toModelElement( viewElement )!;\n}\n\n/**\n * Returns the closest scrollable ancestor DOM element.\n *\n * It is assumed that `domNode` is attached to the document.\n */\nfunction findScrollableElement( domNode: HTMLElement ): HTMLElement {\n\tlet domElement: HTMLElement = domNode;\n\n\tdo {\n\t\tdomElement = domElement.parentElement!;\n\n\t\tconst overflow = global.window.getComputedStyle( domElement ).overflowY;\n\n\t\tif ( overflow == 'auto' || overflow == 'scroll' ) {\n\t\t\tbreak;\n\t\t}\n\t} while ( domElement.tagName != 'BODY' );\n\n\treturn domElement;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/dragdropblocktoolbar\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport {\n\tenv,\n\tglobal,\n\tDomEmitterMixin,\n\ttype ObservableChangeEvent,\n\ttype DomEmitter\n} from '@ckeditor/ckeditor5-utils';\n\nimport type { BlockToolbar } from '@ckeditor/ckeditor5-ui';\n\nimport ClipboardObserver from './clipboardobserver.js';\n\n/**\n * Integration of a block Drag and Drop support with the block toolbar.\n *\n * @internal\n */\nexport default class DragDropBlockToolbar extends Plugin {\n\t/**\n\t * Whether current dragging is started by block toolbar button dragging.\n\t */\n\tprivate _isBlockDragging = false;\n\n\t/**\n\t * DOM Emitter.\n\t */\n\tprivate _domEmitter: DomEmitter = new ( DomEmitterMixin() )();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'DragDropBlockToolbar' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\tthis.listenTo<ObservableChangeEvent<boolean>>( editor, 'change:isReadOnly', ( evt, name, isReadOnly ) => {\n\t\t\tif ( isReadOnly ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t\tthis._isBlockDragging = false;\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\n\t\tif ( env.isAndroid ) {\n\t\t\tthis.forceDisabled( 'noAndroidSupport' );\n\t\t}\n\n\t\tif ( editor.plugins.has( 'BlockToolbar' ) ) {\n\t\t\tconst blockToolbar: BlockToolbar = editor.plugins.get( 'BlockToolbar' );\n\t\t\tconst element = blockToolbar.buttonView.element!;\n\n\t\t\tthis._domEmitter.listenTo( element, 'dragstart', ( evt, data ) => this._handleBlockDragStart( data ) );\n\t\t\tthis._domEmitter.listenTo( global.document, 'dragover', ( evt, data ) => this._handleBlockDragging( data ) );\n\t\t\tthis._domEmitter.listenTo( global.document, 'drop', ( evt, data ) => this._handleBlockDragging( data ) );\n\t\t\tthis._domEmitter.listenTo( global.document, 'dragend', () => this._handleBlockDragEnd(), { useCapture: true } );\n\n\t\t\tif ( this.isEnabled ) {\n\t\t\t\telement.setAttribute( 'draggable', 'true' );\n\t\t\t}\n\n\t\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:isEnabled', ( evt, name, isEnabled ) => {\n\t\t\t\telement.setAttribute( 'draggable', isEnabled ? 'true' : 'false' );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis._domEmitter.stopListening();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * The `dragstart` event handler.\n\t */\n\tprivate _handleBlockDragStart( domEvent: DragEvent ): void {\n\t\tif ( !this.isEnabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst view = this.editor.editing.view;\n\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\t\tconst draggedRange = model.createRange(\n\t\t\tmodel.createPositionBefore( blocks[ 0 ] ),\n\t\t\tmodel.createPositionAfter( blocks[ blocks.length - 1 ] )\n\t\t);\n\n\t\tmodel.change( writer => writer.setSelection( draggedRange ) );\n\n\t\tthis._isBlockDragging = true;\n\n\t\tview.focus();\n\t\tview.getObserver( ClipboardObserver )!.onDomEvent( domEvent );\n\t}\n\n\t/**\n\t * The `dragover` and `drop` event handler.\n\t */\n\tprivate _handleBlockDragging( domEvent: DragEvent ): void {\n\t\tif ( !this.isEnabled || !this._isBlockDragging ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst clientX = domEvent.clientX + ( this.editor.locale.contentLanguageDirection == 'ltr' ? 100 : -100 );\n\t\tconst clientY = domEvent.clientY;\n\t\tconst target = document.elementFromPoint( clientX, clientY );\n\t\tconst view = this.editor.editing.view;\n\n\t\tif ( !target || !target.closest( '.ck-editor__editable' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tview.getObserver( ClipboardObserver )!.onDomEvent( {\n\t\t\t...domEvent,\n\t\t\ttype: domEvent.type,\n\t\t\tdataTransfer: domEvent.dataTransfer,\n\t\t\ttarget,\n\t\t\tclientX,\n\t\t\tclientY,\n\t\t\tpreventDefault: () => domEvent.preventDefault(),\n\t\t\tstopPropagation: () => domEvent.stopPropagation()\n\t\t} );\n\t}\n\n\t/**\n\t * The `dragend` event handler.\n\t */\n\tprivate _handleBlockDragEnd(): void {\n\t\tthis._isBlockDragging = false;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/dragdrop\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport {\n\tLiveRange,\n\tMouseObserver,\n\ttype DataTransfer,\n\ttype Element,\n\ttype Model,\n\ttype Range,\n\ttype Position,\n\ttype ViewDocumentMouseDownEvent,\n\ttype ViewDocumentMouseUpEvent,\n\ttype ViewElement,\n\ttype DomEventData\n} from '@ckeditor/ckeditor5-engine';\n\nimport {\n\tWidget,\n\tisWidget,\n\ttype WidgetToolbarRepository\n} from '@ckeditor/ckeditor5-widget';\n\nimport {\n\tenv,\n\tuid,\n\tglobal,\n\tcreateElement,\n\tDomEmitterMixin,\n\tdelay,\n\tRect,\n\ttype DelayedFunc,\n\ttype ObservableChangeEvent,\n\ttype DomEmitter\n} from '@ckeditor/ckeditor5-utils';\n\nimport ClipboardPipeline, {\n\ttype ClipboardContentInsertionEvent\n} from './clipboardpipeline.js';\n\nimport ClipboardObserver, {\n\ttype ViewDocumentDragEndEvent,\n\ttype ViewDocumentDragEnterEvent,\n\ttype ViewDocumentDraggingEvent,\n\ttype ViewDocumentDragLeaveEvent,\n\ttype ViewDocumentDragStartEvent,\n\ttype ViewDocumentClipboardInputEvent\n} from './clipboardobserver.js';\n\nimport DragDropTarget from './dragdroptarget.js';\nimport DragDropBlockToolbar from './dragdropblocktoolbar.js';\n\nimport '../theme/clipboard.css';\n\n// Drag and drop events overview:\n//\n//                ┌──────────────────┐\n//                │     mousedown    │   Sets the draggable attribute.\n//                └─────────┬────────┘\n//                          │\n//                          └─────────────────────┐\n//                          │                     │\n//                          │           ┌─────────V────────┐\n//                          │           │      mouseup     │   Dragging did not start, removes the draggable attribute.\n//                          │           └──────────────────┘\n//                          │\n//                ┌─────────V────────┐   Retrieves the selected model.DocumentFragment\n//                │     dragstart    │   and converts it to view.DocumentFragment.\n//                └─────────┬────────┘\n//                          │\n//                ┌─────────V────────┐   Processes view.DocumentFragment to text/html and text/plain\n//                │  clipboardOutput │   and stores the results in data.dataTransfer.\n//                └─────────┬────────┘\n//                          │\n//                          │   DOM dragover\n//                          ┌────────────┐\n//                          │            │\n//                ┌─────────V────────┐   │\n//                │     dragging     │   │   Updates the drop target marker.\n//                └─────────┬────────┘   │\n//                          │            │\n//            ┌─────────────└────────────┘\n//            │             │            │\n//            │   ┌─────────V────────┐   │\n//            │   │     dragleave    │   │   Removes the drop target marker.\n//            │   └─────────┬────────┘   │\n//            │             │            │\n//        ┌───│─────────────┘            │\n//        │   │             │            │\n//        │   │   ┌─────────V────────┐   │\n//        │   │   │     dragenter    │   │   Focuses the editor view.\n//        │   │   └─────────┬────────┘   │\n//        │   │             │            │\n//        │   │             └────────────┘\n//        │   │\n//        │   └─────────────┐\n//        │   │             │\n//        │   │   ┌─────────V────────┐\n//        └───┐   │       drop       │   (The default handler of the clipboard pipeline).\n//            │   └─────────┬────────┘\n//            │             │\n//            │   ┌─────────V────────┐   Resolves the final data.targetRanges.\n//            │   │  clipboardInput  │   Aborts if dropping on dragged content.\n//            │   └─────────┬────────┘\n//            │             │\n//            │   ┌─────────V────────┐\n//            │   │  clipboardInput  │   (The default handler of the clipboard pipeline).\n//            │   └─────────┬────────┘\n//            │             │\n//            │ ┌───────────V───────────┐\n//            │ │  inputTransformation  │   (The default handler of the clipboard pipeline).\n//            │ └───────────┬───────────┘\n//            │             │\n//            │  ┌──────────V──────────┐\n//            │  │   contentInsertion  │   Updates the document selection to drop range.\n//            │  └──────────┬──────────┘\n//            │             │\n//            │  ┌──────────V──────────┐\n//            │  │   contentInsertion  │   (The default handler of the clipboard pipeline).\n//            │  └──────────┬──────────┘\n//            │             │\n//            │  ┌──────────V──────────┐\n//            │  │   contentInsertion  │   Removes the content from the original range if the insertion was successful.\n//            │  └──────────┬──────────┘\n//            │             │\n//            └─────────────┐\n//                          │\n//                ┌─────────V────────┐\n//                │      dragend     │   Removes the drop marker and cleans the state.\n//                └──────────────────┘\n//\n\n/**\n * The drag and drop feature. It works on top of the {@link module:clipboard/clipboardpipeline~ClipboardPipeline}.\n *\n * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n *\n * @internal\n */\nexport default class DragDrop extends Plugin {\n\t/**\n\t * The live range over the original content that is being dragged.\n\t */\n\tprivate _draggedRange!: LiveRange | null;\n\n\t/**\n\t * The UID of current dragging that is used to verify if the drop started in the same editor as the drag start.\n\t *\n\t * **Note**: This is a workaround for broken 'dragend' events (they are not fired if the source text node got removed).\n\t */\n\tprivate _draggingUid!: string;\n\n\t/**\n\t * The reference to the model element that currently has a `draggable` attribute set (it is set while dragging).\n\t */\n\tprivate _draggableElement!: Element | null;\n\n\t/**\n\t * A delayed callback removing draggable attributes.\n\t */\n\tprivate _clearDraggableAttributesDelayed: DelayedFunc<() => void> = delay( () => this._clearDraggableAttributes(), 40 );\n\n\t/**\n\t * Whether the dragged content can be dropped only in block context.\n\t */\n\t// TODO handle drag from other editor instance\n\t// TODO configure to use block, inline or both\n\tprivate _blockMode: boolean = false;\n\n\t/**\n\t * DOM Emitter.\n\t */\n\tprivate _domEmitter: DomEmitter = new ( DomEmitterMixin() )();\n\n\t/**\n\t * The DOM element used to generate dragged preview image.\n\t */\n\tprivate _previewContainer?: HTMLElement;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'DragDrop' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ClipboardPipeline, Widget, DragDropTarget, DragDropBlockToolbar ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\n\t\tthis._draggedRange = null;\n\t\tthis._draggingUid = '';\n\t\tthis._draggableElement = null;\n\n\t\tview.addObserver( ClipboardObserver );\n\t\tview.addObserver( MouseObserver );\n\n\t\tthis._setupDragging();\n\t\tthis._setupContentInsertionIntegration();\n\t\tthis._setupClipboardInputIntegration();\n\t\tthis._setupDraggableAttributeHandling();\n\n\t\tthis.listenTo<ObservableChangeEvent<boolean>>( editor, 'change:isReadOnly', ( evt, name, isReadOnly ) => {\n\t\t\tif ( isReadOnly ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\n\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:isEnabled', ( evt, name, isEnabled ) => {\n\t\t\tif ( !isEnabled ) {\n\t\t\t\tthis._finalizeDragging( false );\n\t\t\t}\n\t\t} );\n\n\t\tif ( env.isAndroid ) {\n\t\t\tthis.forceDisabled( 'noAndroidSupport' );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tif ( this._draggedRange ) {\n\t\t\tthis._draggedRange.detach();\n\t\t\tthis._draggedRange = null;\n\t\t}\n\n\t\tif ( this._previewContainer ) {\n\t\t\tthis._previewContainer.remove();\n\t\t}\n\n\t\tthis._domEmitter.stopListening();\n\t\tthis._clearDraggableAttributesDelayed.cancel();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Drag and drop events handling.\n\t */\n\tprivate _setupDragging(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst dragDropTarget = editor.plugins.get( DragDropTarget );\n\n\t\t// The handler for the drag start; it is responsible for setting data transfer object.\n\t\tthis.listenTo<ViewDocumentDragStartEvent>( viewDocument, 'dragstart', ( evt, data ) => {\n\t\t\t// Don't drag the editable element itself.\n\t\t\tif ( data.target && data.target.is( 'editableElement' ) ) {\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._prepareDraggedRange( data.target );\n\n\t\t\tif ( !this._draggedRange ) {\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._draggingUid = uid();\n\n\t\t\tdata.dataTransfer.effectAllowed = this.isEnabled ? 'copyMove' : 'copy';\n\t\t\tdata.dataTransfer.setData( 'application/ckeditor5-dragging-uid', this._draggingUid );\n\n\t\t\tconst draggedSelection = model.createSelection( this._draggedRange.toRange() );\n\t\t\tconst clipboardPipeline: ClipboardPipeline = this.editor.plugins.get( 'ClipboardPipeline' );\n\n\t\t\tclipboardPipeline._fireOutputTransformationEvent( data.dataTransfer, draggedSelection, 'dragstart' );\n\n\t\t\tconst { dataTransfer, domTarget, domEvent } = data;\n\t\t\tconst { clientX } = domEvent;\n\n\t\t\tthis._updatePreview( { dataTransfer, domTarget, clientX } );\n\n\t\t\tdata.stopPropagation();\n\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tthis._draggedRange.detach();\n\t\t\t\tthis._draggedRange = null;\n\t\t\t\tthis._draggingUid = '';\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// The handler for finalizing drag and drop. It should always be triggered after dragging completes\n\t\t// even if it was completed in a different application.\n\t\t// Note: This is not fired if source text node got removed while downcasting a marker.\n\t\tthis.listenTo<ViewDocumentDragEndEvent>( viewDocument, 'dragend', ( evt, data ) => {\n\t\t\tthis._finalizeDragging( !data.dataTransfer.isCanceled && data.dataTransfer.dropEffect == 'move' );\n\t\t}, { priority: 'low' } );\n\n\t\t// Reset block dragging mode even if dropped outside the editable.\n\t\tthis._domEmitter.listenTo( global.document, 'dragend', () => {\n\t\t\tthis._blockMode = false;\n\t\t}, { useCapture: true } );\n\n\t\t// Dragging over the editable.\n\t\tthis.listenTo<ViewDocumentDragEnterEvent>( viewDocument, 'dragenter', () => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tview.focus();\n\t\t} );\n\n\t\t// Dragging out of the editable.\n\t\tthis.listenTo<ViewDocumentDragLeaveEvent>( viewDocument, 'dragleave', () => {\n\t\t\t// We do not know if the mouse left the editor or just some element in it, so let us wait a few milliseconds\n\t\t\t// to check if 'dragover' is not fired.\n\t\t\tdragDropTarget.removeDropMarkerDelayed();\n\t\t} );\n\n\t\t// Handler for moving dragged content over the target area.\n\t\tthis.listenTo<ViewDocumentDraggingEvent>( viewDocument, 'dragging', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tdata.dataTransfer.dropEffect = 'none';\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { clientX, clientY } = ( data as DomEventData<DragEvent> ).domEvent;\n\n\t\t\tdragDropTarget.updateDropMarker(\n\t\t\t\tdata.target,\n\t\t\t\tdata.targetRanges,\n\t\t\t\tclientX,\n\t\t\t\tclientY,\n\t\t\t\tthis._blockMode,\n\t\t\t\tthis._draggedRange\n\t\t\t);\n\n\t\t\t// If this is content being dragged from another editor, moving out of current editor instance\n\t\t\t// is not possible until 'dragend' event case will be fixed.\n\t\t\tif ( !this._draggedRange ) {\n\t\t\t\tdata.dataTransfer.dropEffect = 'copy';\n\t\t\t}\n\n\t\t\t// In Firefox it is already set and effect allowed remains the same as originally set.\n\t\t\tif ( !env.isGecko ) {\n\t\t\t\tif ( data.dataTransfer.effectAllowed == 'copy' ) {\n\t\t\t\t\tdata.dataTransfer.dropEffect = 'copy';\n\t\t\t\t} else if ( [ 'all', 'copyMove' ].includes( data.dataTransfer.effectAllowed ) ) {\n\t\t\t\t\tdata.dataTransfer.dropEffect = 'move';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tevt.stop();\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Integration with the `clipboardInput` event.\n\t */\n\tprivate _setupClipboardInputIntegration(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst dragDropTarget = editor.plugins.get( DragDropTarget );\n\n\t\t// Update the event target ranges and abort dropping if dropping over itself.\n\t\tthis.listenTo<ViewDocumentClipboardInputEvent>( viewDocument, 'clipboardInput', ( evt, data ) => {\n\t\t\tif ( data.method != 'drop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { clientX, clientY } = ( data as DomEventData<DragEvent> ).domEvent;\n\t\t\tconst targetRange = dragDropTarget.getFinalDropRange(\n\t\t\t\tdata.target,\n\t\t\t\tdata.targetRanges,\n\t\t\t\tclientX,\n\t\t\t\tclientY,\n\t\t\t\tthis._blockMode,\n\t\t\t\tthis._draggedRange\n\t\t\t);\n\n\t\t\tif ( !targetRange ) {\n\t\t\t\tthis._finalizeDragging( false );\n\t\t\t\tevt.stop();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Since we cannot rely on the drag end event, we must check if the local drag range is from the current drag and drop\n\t\t\t// or it is from some previous not cleared one.\n\t\t\tif ( this._draggedRange && this._draggingUid != data.dataTransfer.getData( 'application/ckeditor5-dragging-uid' ) ) {\n\t\t\t\tthis._draggedRange.detach();\n\t\t\t\tthis._draggedRange = null;\n\t\t\t\tthis._draggingUid = '';\n\t\t\t}\n\n\t\t\t// Do not do anything if some content was dragged within the same document to the same position.\n\t\t\tconst isMove = getFinalDropEffect( data.dataTransfer ) == 'move';\n\n\t\t\tif ( isMove && this._draggedRange && this._draggedRange.containsRange( targetRange, true ) ) {\n\t\t\t\tthis._finalizeDragging( false );\n\t\t\t\tevt.stop();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Override the target ranges with the one adjusted to the best one for a drop.\n\t\t\tdata.targetRanges = [ editor.editing.mapper.toViewRange( targetRange ) ];\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Integration with the `contentInsertion` event of the clipboard pipeline.\n\t */\n\tprivate _setupContentInsertionIntegration(): void {\n\t\tconst clipboardPipeline = this.editor.plugins.get( ClipboardPipeline );\n\n\t\tclipboardPipeline.on<ClipboardContentInsertionEvent>( 'contentInsertion', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled || data.method !== 'drop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Update the selection to the target range in the same change block to avoid selection post-fixing\n\t\t\t// and to be able to clone text attributes for plain text dropping.\n\t\t\tconst ranges = data.targetRanges!.map( viewRange => this.editor.editing.mapper.toModelRange( viewRange ) );\n\n\t\t\tthis.editor.model.change( writer => writer.setSelection( ranges ) );\n\t\t}, { priority: 'high' } );\n\n\t\tclipboardPipeline.on<ClipboardContentInsertionEvent>( 'contentInsertion', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled || data.method !== 'drop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Remove dragged range content, remove markers, clean after dragging.\n\t\t\tconst isMove = getFinalDropEffect( data.dataTransfer ) == 'move';\n\n\t\t\t// Whether any content was inserted (insertion might fail if the schema is disallowing some elements\n\t\t\t// (for example an image caption allows only the content of a block but not blocks themselves.\n\t\t\t// Some integrations might not return valid range (i.e., table pasting).\n\t\t\tconst isSuccess = !data.resultRange || !data.resultRange.isCollapsed;\n\n\t\t\tthis._finalizeDragging( isSuccess && isMove );\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Adds listeners that add the `draggable` attribute to the elements while the mouse button is down so the dragging could start.\n\t */\n\tprivate _setupDraggableAttributeHandling(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t// Add the 'draggable' attribute to the widget while pressing the selection handle.\n\t\t// This is required for widgets to be draggable. In Chrome it will enable dragging text nodes.\n\t\tthis.listenTo<ViewDocumentMouseDownEvent>( viewDocument, 'mousedown', ( evt, data ) => {\n\t\t\t// The lack of data can be caused by editor tests firing fake mouse events. This should not occur\n\t\t\t// in real-life scenarios but this greatly simplifies editor tests that would otherwise fail a lot.\n\t\t\tif ( env.isAndroid || !data ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._clearDraggableAttributesDelayed.cancel();\n\n\t\t\t// Check if this is a mousedown over the widget (but not a nested editable).\n\t\t\tlet draggableElement = findDraggableWidget( data.target );\n\n\t\t\t// Note: There is a limitation that if more than a widget is selected (a widget and some text)\n\t\t\t// and dragging starts on the widget, then only the widget is dragged.\n\n\t\t\t// If this was not a widget then we should check if we need to drag some text content.\n\t\t\t// In Chrome set a 'draggable' attribute on closest editable to allow immediate dragging of the selected text range.\n\t\t\t// In Firefox this is not needed. In Safari it makes the whole editable draggable (not just textual content).\n\t\t\t// Disabled in read-only mode because draggable=\"true\" + contenteditable=\"false\" results\n\t\t\t// in not firing selectionchange event ever, which makes the selection stuck in read-only mode.\n\t\t\tif ( env.isBlink && !editor.isReadOnly && !draggableElement && !viewDocument.selection.isCollapsed ) {\n\t\t\t\tconst selectedElement = viewDocument.selection.getSelectedElement();\n\n\t\t\t\tif ( !selectedElement || !isWidget( selectedElement ) ) {\n\t\t\t\t\tdraggableElement = viewDocument.selection.editableElement;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( draggableElement ) {\n\t\t\t\tview.change( writer => {\n\t\t\t\t\twriter.setAttribute( 'draggable', 'true', draggableElement! );\n\t\t\t\t} );\n\n\t\t\t\t// Keep the reference to the model element in case the view element gets removed while dragging.\n\t\t\t\tthis._draggableElement = editor.editing.mapper.toModelElement( draggableElement )!;\n\t\t\t}\n\t\t} );\n\n\t\t// Remove the draggable attribute in case no dragging started (only mousedown + mouseup).\n\t\tthis.listenTo<ViewDocumentMouseUpEvent>( viewDocument, 'mouseup', () => {\n\t\t\tif ( !env.isAndroid ) {\n\t\t\t\tthis._clearDraggableAttributesDelayed();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes the `draggable` attribute from the element that was used for dragging.\n\t */\n\tprivate _clearDraggableAttributes(): void {\n\t\tconst editing = this.editor.editing;\n\n\t\tediting.view.change( writer => {\n\t\t\t// Remove 'draggable' attribute.\n\t\t\tif ( this._draggableElement && this._draggableElement.root.rootName != '$graveyard' ) {\n\t\t\t\twriter.removeAttribute( 'draggable', editing.mapper.toViewElement( this._draggableElement )! );\n\t\t\t}\n\n\t\t\tthis._draggableElement = null;\n\t\t} );\n\t}\n\n\t/**\n\t * Deletes the dragged content from its original range and clears the dragging state.\n\t *\n\t * @param moved Whether the move succeeded.\n\t */\n\tprivate _finalizeDragging( moved: boolean ): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst dragDropTarget = editor.plugins.get( DragDropTarget );\n\n\t\tdragDropTarget.removeDropMarker();\n\t\tthis._clearDraggableAttributes();\n\n\t\tif ( editor.plugins.has( 'WidgetToolbarRepository' ) ) {\n\t\t\tconst widgetToolbarRepository: WidgetToolbarRepository = editor.plugins.get( 'WidgetToolbarRepository' );\n\n\t\t\twidgetToolbarRepository.clearForceDisabled( 'dragDrop' );\n\t\t}\n\n\t\tthis._draggingUid = '';\n\n\t\tif ( this._previewContainer ) {\n\t\t\tthis._previewContainer.remove();\n\t\t\tthis._previewContainer = undefined;\n\t\t}\n\n\t\tif ( !this._draggedRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Delete moved content.\n\t\tif ( moved && this.isEnabled ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\tconst selection = model.createSelection( this._draggedRange );\n\n\t\t\t\tmodel.deleteContent( selection, { doNotAutoparagraph: true } );\n\n\t\t\t\t// Check result selection if it does not require auto-paragraphing of empty container.\n\t\t\t\tconst selectionParent = selection.getFirstPosition()!.parent as Element;\n\n\t\t\t\tif (\n\t\t\t\t\tselectionParent.isEmpty &&\n\t\t\t\t\t!model.schema.checkChild( selectionParent, '$text' ) &&\n\t\t\t\t\tmodel.schema.checkChild( selectionParent, 'paragraph' )\n\t\t\t\t) {\n\t\t\t\t\twriter.insertElement( 'paragraph', selectionParent, 0 );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tthis._draggedRange.detach();\n\t\tthis._draggedRange = null;\n\t}\n\n\t/**\n\t * Sets the dragged source range based on event target and document selection.\n\t */\n\tprivate _prepareDraggedRange( target: ViewElement ): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\t// Check if this is dragstart over the widget (but not a nested editable).\n\t\tconst draggableWidget = target ? findDraggableWidget( target ) : null;\n\n\t\tif ( draggableWidget ) {\n\t\t\tconst modelElement = editor.editing.mapper.toModelElement( draggableWidget )!;\n\n\t\t\tthis._draggedRange = LiveRange.fromRange( model.createRangeOn( modelElement ) );\n\t\t\tthis._blockMode = model.schema.isBlock( modelElement );\n\n\t\t\t// Disable toolbars so they won't obscure the drop area.\n\t\t\tif ( editor.plugins.has( 'WidgetToolbarRepository' ) ) {\n\t\t\t\tconst widgetToolbarRepository: WidgetToolbarRepository = editor.plugins.get( 'WidgetToolbarRepository' );\n\n\t\t\t\twidgetToolbarRepository.forceDisabled( 'dragDrop' );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If this was not a widget we should check if we need to drag some text content.\n\t\tif ( selection.isCollapsed && !( selection.getFirstPosition()!.parent as Element ).isEmpty ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\t\tconst draggedRange = selection.getFirstRange()!;\n\n\t\tif ( blocks.length == 0 ) {\n\t\t\tthis._draggedRange = LiveRange.fromRange( draggedRange );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst blockRange = getRangeIncludingFullySelectedParents( model, blocks );\n\n\t\tif ( blocks.length > 1 ) {\n\t\t\tthis._draggedRange = LiveRange.fromRange( blockRange );\n\t\t\tthis._blockMode = true;\n\t\t\t// TODO block mode for dragging from outside editor? or inline? or both?\n\t\t} else if ( blocks.length == 1 ) {\n\t\t\tconst touchesBlockEdges = draggedRange.start.isTouching( blockRange.start ) &&\n\t\t\t\t\tdraggedRange.end.isTouching( blockRange.end );\n\n\t\t\tthis._draggedRange = LiveRange.fromRange( touchesBlockEdges ? blockRange : draggedRange );\n\t\t\tthis._blockMode = touchesBlockEdges;\n\t\t}\n\n\t\tmodel.change( writer => writer.setSelection( this._draggedRange!.toRange() ) );\n\t}\n\n\t/**\n\t * Updates the dragged preview image.\n\t */\n\tprivate _updatePreview( {\n\t\tdataTransfer,\n\t\tdomTarget,\n\t\tclientX\n\t}: {\n\t\tdataTransfer: DataTransfer;\n\t\tdomTarget: HTMLElement;\n\t\tclientX: number;\n\t} ): void {\n\t\tconst view = this.editor.editing.view;\n\t\tconst editable = view.document.selection.editableElement!;\n\t\tconst domEditable = view.domConverter.mapViewToDom( editable )!;\n\t\tconst computedStyle = global.window.getComputedStyle( domEditable );\n\n\t\tif ( !this._previewContainer ) {\n\t\t\tthis._previewContainer = createElement( global.document, 'div', {\n\t\t\t\tstyle: 'position: fixed; left: -999999px;'\n\t\t\t} );\n\n\t\t\tglobal.document.body.appendChild( this._previewContainer );\n\t\t} else if ( this._previewContainer.firstElementChild ) {\n\t\t\tthis._previewContainer.removeChild( this._previewContainer.firstElementChild );\n\t\t}\n\n\t\tconst domRect = new Rect( domEditable );\n\n\t\t// If domTarget is inside the editable root, browsers will display the preview correctly by themselves.\n\t\tif ( domEditable.contains( domTarget ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst domEditablePaddingLeft = parseFloat( computedStyle.paddingLeft );\n\t\tconst preview = createElement( global.document, 'div' );\n\n\t\tpreview.className = 'ck ck-content';\n\t\tpreview.style.width = computedStyle.width;\n\t\tpreview.style.paddingLeft = `${ domRect.left - clientX + domEditablePaddingLeft }px`;\n\n\t\t/**\n\t\t * Set white background in drag and drop preview if iOS.\n\t\t * Check: https://github.com/ckeditor/ckeditor5/issues/15085\n\t\t */\n\t\tif ( env.isiOS ) {\n\t\t\tpreview.style.backgroundColor = 'white';\n\t\t}\n\n\t\tview.domConverter.setContentOf( preview, dataTransfer.getData( 'text/html' ) );\n\n\t\tdataTransfer.setDragImage( preview, 0, 0 );\n\n\t\tthis._previewContainer.appendChild( preview );\n\t}\n}\n\n/**\n * Returns the drop effect that should be a result of dragging the content.\n * This function is handling a quirk when checking the effect in the 'drop' DOM event.\n */\nfunction getFinalDropEffect( dataTransfer: DataTransfer ): DataTransfer[ 'dropEffect' ] {\n\tif ( env.isGecko ) {\n\t\treturn dataTransfer.dropEffect;\n\t}\n\n\treturn [ 'all', 'copyMove' ].includes( dataTransfer.effectAllowed ) ? 'move' : 'copy';\n}\n\n/**\n * Returns a widget element that should be dragged.\n */\nfunction findDraggableWidget( target: ViewElement ): ViewElement | null {\n\t// This is directly an editable so not a widget for sure.\n\tif ( target.is( 'editableElement' ) ) {\n\t\treturn null;\n\t}\n\n\t// TODO: Let's have a isWidgetSelectionHandleDomElement() helper in ckeditor5-widget utils.\n\tif ( target.hasClass( 'ck-widget__selection-handle' ) ) {\n\t\treturn target.findAncestor( isWidget );\n\t}\n\n\t// Direct hit on a widget.\n\tif ( isWidget( target ) ) {\n\t\treturn target;\n\t}\n\n\t// Find closest ancestor that is either a widget or an editable element...\n\tconst ancestor = target.findAncestor( node => isWidget( node ) || node.is( 'editableElement' ) )!;\n\n\t// ...and if closer was the widget then enable dragging it.\n\tif ( isWidget( ancestor ) ) {\n\t\treturn ancestor;\n\t}\n\n\treturn null;\n}\n\n/**\n * Recursively checks if common parent of provided elements doesn't have any other children. If that's the case,\n * it returns range including this parent. Otherwise, it returns only the range from first to last element.\n *\n * Example:\n *\n * <blockQuote>\n *   <paragraph>[Test 1</paragraph>\n *   <paragraph>Test 2</paragraph>\n *   <paragraph>Test 3]</paragraph>\n * <blockQuote>\n *\n * Because all elements inside the `blockQuote` are selected, the range is extended to include the `blockQuote` too.\n * If only first and second paragraphs would be selected, the range would not include it.\n */\nfunction getRangeIncludingFullySelectedParents( model: Model, elements: Array<Element> ): Range {\n\tconst firstElement = elements[ 0 ];\n\tconst lastElement = elements[ elements.length - 1 ];\n\tconst parent = firstElement.getCommonAncestor( lastElement );\n\tconst startPosition: Position = model.createPositionBefore( firstElement );\n\tconst endPosition: Position = model.createPositionAfter( lastElement );\n\n\tif (\n\t\tparent &&\n\t\tparent.is( 'element' ) &&\n\t\t!model.schema.isLimit( parent )\n\t) {\n\t\tconst parentRange = model.createRangeOn( parent );\n\t\tconst touchesStart = startPosition.isTouching( parentRange.start );\n\t\tconst touchesEnd = endPosition.isTouching( parentRange.end );\n\n\t\tif ( touchesStart && touchesEnd ) {\n\t\t\t// Selection includes all elements in the parent.\n\t\t\treturn getRangeIncludingFullySelectedParents( model, [ parent ] );\n\t\t}\n\t}\n\n\treturn model.createRange( startPosition, endPosition );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/pasteplaintext\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport type { DocumentFragment, Model, Element } from '@ckeditor/ckeditor5-engine';\n\nimport ClipboardObserver from './clipboardobserver.js';\nimport ClipboardPipeline, { type ClipboardContentInsertionEvent } from './clipboardpipeline.js';\n\n/**\n * The plugin detects the user's intention to paste plain text.\n *\n * For example, it detects the <kbd>Ctrl/Cmd</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> keystroke.\n */\nexport default class PastePlainText extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'PastePlainText' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ClipboardPipeline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\t\tconst selection = model.document.selection;\n\n\t\tview.addObserver( ClipboardObserver );\n\n\t\teditor.plugins.get( ClipboardPipeline ).on<ClipboardContentInsertionEvent>( 'contentInsertion', ( evt, data ) => {\n\t\t\tif ( !isUnformattedInlineContent( data.content, model ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodel.change( writer => {\n\t\t\t\t// Formatting attributes should be preserved.\n\t\t\t\tconst textAttributes = Array.from( selection.getAttributes() )\n\t\t\t\t\t.filter( ( [ key ] ) => model.schema.getAttributeProperties( key ).isFormatting );\n\n\t\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\t\tmodel.deleteContent( selection, { doNotAutoparagraph: true } );\n\t\t\t\t}\n\n\t\t\t\t// Also preserve other attributes if they survived the content deletion (because they were not fully selected).\n\t\t\t\t// For example linkHref is not a formatting attribute but it should be preserved if pasted text was in the middle\n\t\t\t\t// of a link.\n\t\t\t\ttextAttributes.push( ...selection.getAttributes() );\n\n\t\t\t\tconst range = writer.createRangeIn( data.content );\n\n\t\t\t\tfor ( const item of range.getItems() ) {\n\t\t\t\t\tfor ( const attribute of textAttributes ) {\n\t\t\t\t\t\tif ( model.schema.checkAttribute( item, attribute[ 0 ] ) ) {\n\t\t\t\t\t\t\twriter.setAttribute( attribute[ 0 ], attribute[ 1 ], item );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n}\n\n/**\n * Returns true if specified `documentFragment` represents the unformatted inline content.\n */\nfunction isUnformattedInlineContent( documentFragment: DocumentFragment, model: Model ): boolean {\n\tlet range = model.createRangeIn( documentFragment );\n\n\t// We consider three scenarios here. The document fragment may include:\n\t//\n\t// 1. Only text and inline objects. Then it could be unformatted inline content.\n\t// 2. Exactly one block element on top-level, eg. <p>Foobar</p> or <h2>Title</h2>.\n\t//    In this case, check this element content, it could be treated as unformatted inline content.\n\t// 3. More block elements or block objects, then it is not unformatted inline content.\n\t//\n\t// We will check for scenario 2. specifically, and if it happens, we will unwrap it and follow with the regular algorithm.\n\t//\n\tif ( documentFragment.childCount == 1 ) {\n\t\tconst child = documentFragment.getChild( 0 )!;\n\n\t\tif ( child.is( 'element' ) && model.schema.isBlock( child ) && !model.schema.isObject( child ) && !model.schema.isLimit( child ) ) {\n\t\t\t// Scenario 2. as described above.\n\t\t\trange = model.createRangeIn( child as Element );\n\t\t}\n\t}\n\n\tfor ( const child of range.getItems() ) {\n\t\tif ( !model.schema.isInline( child ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst attributeKeys = Array.from( child.getAttributeKeys() );\n\n\t\tif ( attributeKeys.find( key => model.schema.getAttributeProperties( key ).isFormatting ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/clipboard\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport ClipboardPipeline from './clipboardpipeline.js';\nimport DragDrop from './dragdrop.js';\nimport PastePlainText from './pasteplaintext.js';\nimport ClipboardMarkersUtils from './clipboardmarkersutils.js';\n\n/**\n * The clipboard feature.\n *\n * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n * * {@link module:clipboard/clipboardpipeline~ClipboardPipeline}\n * * {@link module:clipboard/dragdrop~DragDrop}\n * * {@link module:clipboard/pasteplaintext~PastePlainText}\n */\nexport default class Clipboard extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Clipboard' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ClipboardMarkersUtils, ClipboardPipeline, DragDrop, PastePlainText ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\n\t\t// Add the information about the keystrokes to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Copy selected content' ),\n\t\t\t\t\tkeystroke: 'CTRL+C'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Paste content' ),\n\t\t\t\t\tkeystroke: 'CTRL+V'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Paste content as plain text' ),\n\t\t\t\t\tkeystroke: 'CTRL+SHIFT+V'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "import { EditorUI, normalizeToolbarConfig, DialogView, BoxedEditorUIView, StickyPanelView, ToolbarView, MenuBarView, InlineEditableUIView } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { enablePlaceholder } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { ElementReplacer, Rect, CKEditorError, getDataFromElement } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { ElementApiMixin, Editor, attachToForm } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { isElement as isElement$1 } from 'lodash-es';\n\n/**\n * The classic editor UI class.\n */ class ClassicEditorUI extends EditorUI {\n    /**\n\t * The main (top–most) view of the editor UI.\n\t */ view;\n    /**\n\t * A normalized `config.toolbar` object.\n\t */ _toolbarConfig;\n    /**\n\t * The element replacer instance used to hide the editor's source element.\n\t */ _elementReplacer;\n    /**\n\t * Creates an instance of the classic editor UI class.\n\t *\n\t * @param editor The editor instance.\n\t * @param view The view of the UI.\n\t */ constructor(editor, view){\n        super(editor);\n        this.view = view;\n        this._toolbarConfig = normalizeToolbarConfig(editor.config.get('toolbar'));\n        this._elementReplacer = new ElementReplacer();\n        this.listenTo(editor.editing.view, 'scrollToTheSelection', this._handleScrollToTheSelectionWithStickyPanel.bind(this));\n    }\n    /**\n\t * @inheritDoc\n\t */ get element() {\n        return this.view.element;\n    }\n    /**\n\t * Initializes the UI.\n\t *\n\t * @param replacementElement The DOM element that will be the source for the created editor.\n\t */ init(replacementElement) {\n        const editor = this.editor;\n        const view = this.view;\n        const editingView = editor.editing.view;\n        const editable = view.editable;\n        const editingRoot = editingView.document.getRoot();\n        // The editable UI and editing root should share the same name. Then name is used\n        // to recognize the particular editable, for instance in ARIA attributes.\n        editable.name = editingRoot.rootName;\n        view.render();\n        // The editable UI element in DOM is available for sure only after the editor UI view has been rendered.\n        // But it can be available earlier if a DOM element has been passed to BalloonEditor.create().\n        const editableElement = editable.element;\n        // Register the editable UI view in the editor. A single editor instance can aggregate multiple\n        // editable areas (roots) but the classic editor has only one.\n        this.setEditableElement(editable.name, editableElement);\n        // Let the editable UI element respond to the changes in the global editor focus\n        // tracker. It has been added to the same tracker a few lines above but, in reality, there are\n        // many focusable areas in the editor, like balloons, toolbars or dropdowns and as long\n        // as they have focus, the editable should act like it is focused too (although technically\n        // it isn't), e.g. by setting the proper CSS class, visually announcing focus to the user.\n        // Doing otherwise will result in editable focus styles disappearing, once e.g. the\n        // toolbar gets focused.\n        view.editable.bind('isFocused').to(this.focusTracker);\n        // Bind the editable UI element to the editing view, making it an end– and entry–point\n        // of the editor's engine. This is where the engine meets the UI.\n        editingView.attachDomRoot(editableElement);\n        // If an element containing the initial data of the editor was provided, replace it with\n        // an editor instance's UI in DOM until the editor is destroyed. For instance, a <textarea>\n        // can be such element.\n        if (replacementElement) {\n            this._elementReplacer.replace(replacementElement, this.element);\n        }\n        this._initPlaceholder();\n        this._initToolbar();\n        if (view.menuBarView) {\n            this._initMenuBar(view.menuBarView);\n        }\n        this._initDialogPluginIntegration();\n        this._initContextualBalloonIntegration();\n        this.fire('ready');\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        const view = this.view;\n        const editingView = this.editor.editing.view;\n        this._elementReplacer.restore();\n        if (editingView.getDomRoot(view.editable.name)) {\n            editingView.detachDomRoot(view.editable.name);\n        }\n        view.destroy();\n    }\n    /**\n\t * Initializes the editor toolbar.\n\t */ _initToolbar() {\n        const view = this.view;\n        // Set–up the sticky panel with toolbar.\n        view.stickyPanel.bind('isActive').to(this.focusTracker, 'isFocused');\n        view.stickyPanel.limiterElement = view.element;\n        view.stickyPanel.bind('viewportTopOffset').to(this, 'viewportOffset', ({ top })=>top || 0);\n        view.toolbar.fillFromConfig(this._toolbarConfig, this.componentFactory);\n        // Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n        this.addToolbar(view.toolbar);\n    }\n    /**\n\t * Enable the placeholder text on the editing root.\n\t */ _initPlaceholder() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const editingRoot = editingView.document.getRoot();\n        const sourceElement = editor.sourceElement;\n        let placeholderText;\n        const placeholder = editor.config.get('placeholder');\n        if (placeholder) {\n            placeholderText = typeof placeholder === 'string' ? placeholder : placeholder[this.view.editable.name];\n        }\n        if (!placeholderText && sourceElement && sourceElement.tagName.toLowerCase() === 'textarea') {\n            placeholderText = sourceElement.getAttribute('placeholder');\n        }\n        if (placeholderText) {\n            editingRoot.placeholder = placeholderText;\n        }\n        enablePlaceholder({\n            view: editingView,\n            element: editingRoot,\n            isDirectHost: false,\n            keepOnFocus: true\n        });\n    }\n    /**\n\t * Provides an integration between the sticky toolbar and {@link module:ui/panel/balloon/contextualballoon contextual balloon plugin}.\n\t * It allows the contextual balloon to consider the height of the\n\t * {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#stickyPanel}. It prevents the balloon from overlapping\n\t * the sticky toolbar by adjusting the balloon's position using viewport offset configuration.\n\t */ _initContextualBalloonIntegration() {\n        if (!this.editor.plugins.has('ContextualBalloon')) {\n            return;\n        }\n        const { stickyPanel } = this.view;\n        const contextualBalloon = this.editor.plugins.get('ContextualBalloon');\n        contextualBalloon.on('getPositionOptions', (evt)=>{\n            const position = evt.return;\n            if (!position || !stickyPanel.isSticky || !stickyPanel.element) {\n                return;\n            }\n            // Measure toolbar (and menu bar) height.\n            const stickyPanelHeight = new Rect(stickyPanel.element).height;\n            // Handle edge case when the target element is larger than the limiter.\n            // It's an issue because the contextual balloon can overlap top table cells when the table is larger than the viewport\n            // and it's placed at the top of the editor. It's better to overlap toolbar in that situation.\n            // Check this issue: https://github.com/ckeditor/ckeditor5/issues/15744\n            const target = typeof position.target === 'function' ? position.target() : position.target;\n            const limiter = typeof position.limiter === 'function' ? position.limiter() : position.limiter;\n            if (target && limiter && new Rect(target).height >= new Rect(limiter).height - stickyPanelHeight) {\n                return;\n            }\n            // Ensure that viewport offset is present, it can be undefined according to the typing.\n            const viewportOffsetConfig = {\n                ...position.viewportOffsetConfig\n            };\n            const newTopViewportOffset = (viewportOffsetConfig.top || 0) + stickyPanelHeight;\n            evt.return = {\n                ...position,\n                viewportOffsetConfig: {\n                    ...viewportOffsetConfig,\n                    top: newTopViewportOffset\n                }\n            };\n        }, {\n            priority: 'low'\n        });\n        // Update balloon position when the toolbar becomes sticky or when ui viewportOffset changes.\n        const updateBalloonPosition = ()=>{\n            if (contextualBalloon.visibleView) {\n                contextualBalloon.updatePosition();\n            }\n        };\n        this.listenTo(stickyPanel, 'change:isSticky', updateBalloonPosition);\n        this.listenTo(this.editor.ui, 'change:viewportOffset', updateBalloonPosition);\n    }\n    /**\n\t * Provides an integration between the sticky toolbar and {@link module:utils/dom/scroll~scrollViewportToShowTarget}.\n\t * It allows the UI-agnostic engine method to consider the geometry of the\n\t * {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#stickyPanel} that pins to the\n\t * edge of the viewport and can obscure the user caret after scrolling the window.\n\t *\n\t * @param evt The `scrollToTheSelection` event info.\n\t * @param data The payload carried by the `scrollToTheSelection` event.\n\t * @param originalArgs The original arguments passed to `scrollViewportToShowTarget()` method (see implementation to learn more).\n\t */ _handleScrollToTheSelectionWithStickyPanel(evt, data, originalArgs) {\n        const stickyPanel = this.view.stickyPanel;\n        if (stickyPanel.isSticky) {\n            const stickyPanelHeight = new Rect(stickyPanel.element).height;\n            data.viewportOffset.top += stickyPanelHeight;\n        } else {\n            const scrollViewportOnPanelGettingSticky = ()=>{\n                this.editor.editing.view.scrollToTheSelection(originalArgs);\n            };\n            this.listenTo(stickyPanel, 'change:isSticky', scrollViewportOnPanelGettingSticky);\n            // This works as a post-scroll-fixer because it's impossible predict whether the panel will be sticky after scrolling or not.\n            // Listen for a short period of time only and if the toolbar does not become sticky very soon, cancel the listener.\n            setTimeout(()=>{\n                this.stopListening(stickyPanel, 'change:isSticky', scrollViewportOnPanelGettingSticky);\n            }, 20);\n        }\n    }\n    /**\n\t * Provides an integration between the sticky toolbar and {@link module:ui/dialog/dialog the Dialog plugin}.\n\t *\n\t * It moves the dialog down to ensure that the\n\t * {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#stickyPanel sticky panel}\n\t * used by the editor UI will not get obscured by the dialog when the dialog uses one of its automatic positions.\n\t */ _initDialogPluginIntegration() {\n        if (!this.editor.plugins.has('Dialog')) {\n            return;\n        }\n        const stickyPanel = this.view.stickyPanel;\n        const dialogPlugin = this.editor.plugins.get('Dialog');\n        dialogPlugin.on('show', ()=>{\n            const dialogView = dialogPlugin.view;\n            dialogView.on('moveTo', (evt, data)=>{\n                // Engage only when the panel is sticky, and the dialog is using one of default positions.\n                if (!stickyPanel.isSticky || dialogView.wasMoved) {\n                    return;\n                }\n                const stickyPanelContentRect = new Rect(stickyPanel.contentPanelElement);\n                if (data[1] < stickyPanelContentRect.bottom + DialogView.defaultOffset) {\n                    data[1] = stickyPanelContentRect.bottom + DialogView.defaultOffset;\n                }\n            }, {\n                priority: 'high'\n            });\n        }, {\n            priority: 'low'\n        });\n    }\n}\n\n/**\n * Classic editor UI view. Uses an inline editable and a sticky toolbar, all\n * enclosed in a boxed UI view.\n */ class ClassicEditorUIView extends BoxedEditorUIView {\n    /**\n\t * Sticky panel view instance. This is a parent view of a {@link #toolbar}\n\t * that makes toolbar sticky.\n\t */ stickyPanel;\n    /**\n\t * Toolbar view instance.\n\t */ toolbar;\n    /**\n\t * Editable UI view.\n\t */ editable;\n    /**\n\t * Creates an instance of the classic editor UI view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param editingView The editing view instance this view is related to.\n\t * @param options Configuration options for the view instance.\n\t * @param options.shouldToolbarGroupWhenFull When set `true` enables automatic items grouping\n\t * in the main {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#toolbar toolbar}.\n\t * See {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull} to learn more.\n\t * @param options.label When set, this value will be used as an accessible `aria-label` of the\n\t * {@link module:ui/editableui/editableuiview~EditableUIView editable view}.\n\t */ constructor(locale, editingView, options = {}){\n        super(locale);\n        this.stickyPanel = new StickyPanelView(locale);\n        this.toolbar = new ToolbarView(locale, {\n            shouldGroupWhenFull: options.shouldToolbarGroupWhenFull\n        });\n        if (options.useMenuBar) {\n            this.menuBarView = new MenuBarView(locale);\n        }\n        this.editable = new InlineEditableUIView(locale, editingView, undefined, {\n            label: options.label\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        if (this.menuBarView) {\n            // Set toolbar as a child of a stickyPanel and makes toolbar sticky.\n            this.stickyPanel.content.addMany([\n                this.menuBarView,\n                this.toolbar\n            ]);\n        } else {\n            this.stickyPanel.content.add(this.toolbar);\n        }\n        this.top.add(this.stickyPanel);\n        this.main.add(this.editable);\n    }\n}\n\n/**\n * The classic editor implementation. It uses an inline editable and a sticky toolbar, all enclosed in a boxed UI.\n * See the {@glink examples/builds/classic-editor demo}.\n *\n * In order to create a classic editor instance, use the static\n * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method.\n */ class ClassicEditor extends /* #__PURE__ */ ElementApiMixin(Editor) {\n    /**\n\t * @inheritDoc\n\t */ ui;\n    /**\n\t * Creates an instance of the classic editor.\n\t *\n\t * **Note:** do not use the constructor to create editor instances. Use the static\n\t * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method instead.\n\t *\n\t * @param sourceElementOrData The DOM element that will be the source for the created editor\n\t * or the editor's initial data. For more information see\n\t * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}.\n\t * @param config The editor configuration.\n\t */ constructor(sourceElementOrData, config = {}){\n        // If both `config.initialData` is set and initial data is passed as the constructor parameter, then throw.\n        if (!isElement(sourceElementOrData) && config.initialData !== undefined) {\n            // Documented in core/editor/editorconfig.jsdoc.\n            // eslint-disable-next-line ckeditor5-rules/ckeditor-error-message\n            throw new CKEditorError('editor-create-initial-data', null);\n        }\n        super(config);\n        this.config.define('menuBar.isVisible', false);\n        if (this.config.get('initialData') === undefined) {\n            this.config.set('initialData', getInitialData(sourceElementOrData));\n        }\n        if (isElement(sourceElementOrData)) {\n            this.sourceElement = sourceElementOrData;\n        }\n        this.model.document.createRoot();\n        const shouldToolbarGroupWhenFull = !this.config.get('toolbar.shouldNotGroupWhenFull');\n        const menuBarConfig = this.config.get('menuBar');\n        const view = new ClassicEditorUIView(this.locale, this.editing.view, {\n            shouldToolbarGroupWhenFull,\n            useMenuBar: menuBarConfig.isVisible,\n            label: this.config.get('label')\n        });\n        this.ui = new ClassicEditorUI(this, view);\n        attachToForm(this);\n    }\n    /**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * Updates the original editor element with the data if the\n\t * {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy `updateSourceElementOnDestroy`}\n\t * configuration option is set to `true`.\n\t */ destroy() {\n        if (this.sourceElement) {\n            this.updateSourceElement();\n        }\n        this.ui.destroy();\n        return super.destroy();\n    }\n    /**\n\t * Creates a new classic editor instance.\n\t *\n\t * There are three ways how the editor can be initialized.\n\t *\n\t * # Replacing a DOM element (and loading data from it)\n\t *\n\t * You can initialize the editor using an existing DOM element:\n\t *\n\t * ```ts\n\t * ClassicEditor\n\t * \t.create( document.querySelector( '#editor' ) )\n\t * \t.then( editor => {\n\t * \t\tconsole.log( 'Editor was initialized', editor );\n\t * \t} )\n\t * \t.catch( err => {\n\t * \t\tconsole.error( err.stack );\n\t * \t} );\n\t * ```\n\t *\n\t * The element's content will be used as the editor data and the element will be replaced by the editor UI.\n\t *\n\t * # Creating a detached editor\n\t *\n\t * Alternatively, you can initialize the editor by passing the initial data directly as a string.\n\t * In this case, the editor will render an element that must be inserted into the DOM:\n\t *\n\t * ```ts\n\t * ClassicEditor\n\t * \t.create( '<p>Hello world!</p>' )\n\t * \t.then( editor => {\n\t * \t\tconsole.log( 'Editor was initialized', editor );\n\t *\n\t * \t\t// Initial data was provided so the editor UI element needs to be added manually to the DOM.\n\t * \t\tdocument.body.appendChild( editor.ui.element );\n\t * \t} )\n\t * \t.catch( err => {\n\t * \t\tconsole.error( err.stack );\n\t * \t} );\n\t * ```\n\t *\n\t * This lets you dynamically append the editor to your web page whenever it is convenient for you. You may use this method if your\n\t * web page content is generated on the client side and the DOM structure is not ready at the moment when you initialize the editor.\n\t *\n\t * # Replacing a DOM element (and data provided in `config.initialData`)\n\t *\n\t * You can also mix these two ways by providing a DOM element to be used and passing the initial data through the configuration:\n\t *\n\t * ```ts\n\t * ClassicEditor\n\t * \t.create( document.querySelector( '#editor' ), {\n\t * \t\tinitialData: '<h2>Initial data</h2><p>Foo bar.</p>'\n\t * \t} )\n\t * \t.then( editor => {\n\t * \t\tconsole.log( 'Editor was initialized', editor );\n\t * \t} )\n\t * \t.catch( err => {\n\t * \t\tconsole.error( err.stack );\n\t * \t} );\n\t * ```\n\t *\n\t * This method can be used to initialize the editor on an existing element with the specified content in case if your integration\n\t * makes it difficult to set the content of the source element.\n\t *\n\t * Note that an error will be thrown if you pass the initial data both as the first parameter and also in the configuration.\n\t *\n\t * # Configuring the editor\n\t *\n\t * See the {@link module:core/editor/editorconfig~EditorConfig editor configuration documentation} to learn more about\n\t * customizing plugins, toolbar and more.\n\t *\n\t * @param sourceElementOrData The DOM element that will be the source for the created editor\n\t * or the editor's initial data.\n\t *\n\t * If a DOM element is passed, its content will be automatically loaded to the editor upon initialization\n\t * and the {@link module:editor-classic/classiceditorui~ClassicEditorUI#element editor element} will replace the passed element\n\t * in the DOM (the original one will be hidden and the editor will be injected next to it).\n\t *\n\t * If the {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy updateSourceElementOnDestroy}\n\t * option is set to `true`, the editor data will be set back to the original element once the editor is destroyed and when a form,\n\t * in which this element is contained, is submitted (if the original element is a `<textarea>`). This ensures seamless integration\n\t * with native web forms.\n\t *\n\t * If the initial data is passed, a detached editor will be created. In this case you need to insert it into the DOM manually.\n\t * It is available under the {@link module:editor-classic/classiceditorui~ClassicEditorUI#element `editor.ui.element`} property.\n\t *\n\t * @param config The editor configuration.\n\t * @returns A promise resolved once the editor is ready. The promise resolves with the created editor instance.\n\t */ static create(sourceElementOrData, config = {}) {\n        return new Promise((resolve)=>{\n            const editor = new this(sourceElementOrData, config);\n            resolve(editor.initPlugins().then(()=>editor.ui.init(isElement(sourceElementOrData) ? sourceElementOrData : null)).then(()=>editor.data.init(editor.config.get('initialData'))).then(()=>editor.fire('ready')).then(()=>editor));\n        });\n    }\n}\nfunction getInitialData(sourceElementOrData) {\n    return isElement(sourceElementOrData) ? getDataFromElement(sourceElementOrData) : sourceElementOrData;\n}\nfunction isElement(value) {\n    return isElement$1(value);\n}\n\nexport { ClassicEditor };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module editor-classic/classiceditorui\n */\n\nimport type { Editor, ElementApi } from 'ckeditor5/src/core.js';\nimport {\n\tEditorUI,\n\tDialogView,\n\tnormalizeToolbarConfig,\n\ttype DialogViewMoveToEvent,\n\ttype Dialog,\n\ttype EditorUIReadyEvent,\n\ttype ContextualBalloonGetPositionOptionsEvent\n} from 'ckeditor5/src/ui.js';\nimport {\n\tenablePlaceholder,\n\ttype ViewScrollToTheSelectionEvent\n} from 'ckeditor5/src/engine.js';\nimport { ElementReplacer, Rect, type EventInfo } from 'ckeditor5/src/utils.js';\nimport type ClassicEditorUIView from './classiceditoruiview.js';\n\n/**\n * The classic editor UI class.\n */\nexport default class ClassicEditorUI extends EditorUI {\n\t/**\n\t * The main (top–most) view of the editor UI.\n\t */\n\tpublic readonly view: ClassicEditorUIView;\n\n\t/**\n\t * A normalized `config.toolbar` object.\n\t */\n\tprivate readonly _toolbarConfig: ReturnType<typeof normalizeToolbarConfig>;\n\n\t/**\n\t * The element replacer instance used to hide the editor's source element.\n\t */\n\tprivate readonly _elementReplacer: ElementReplacer;\n\n\t/**\n\t * Creates an instance of the classic editor UI class.\n\t *\n\t * @param editor The editor instance.\n\t * @param view The view of the UI.\n\t */\n\tconstructor( editor: Editor, view: ClassicEditorUIView ) {\n\t\tsuper( editor );\n\n\t\tthis.view = view;\n\t\tthis._toolbarConfig = normalizeToolbarConfig( editor.config.get( 'toolbar' ) );\n\n\t\tthis._elementReplacer = new ElementReplacer();\n\n\t\tthis.listenTo<ViewScrollToTheSelectionEvent>(\n\t\t\teditor.editing.view, 'scrollToTheSelection', this._handleScrollToTheSelectionWithStickyPanel.bind( this ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override get element(): HTMLElement | null {\n\t\treturn this.view.element;\n\t}\n\n\t/**\n\t * Initializes the UI.\n\t *\n\t * @param replacementElement The DOM element that will be the source for the created editor.\n\t */\n\tpublic init( replacementElement: HTMLElement | null ): void {\n\t\tconst editor = this.editor;\n\t\tconst view = this.view;\n\t\tconst editingView = editor.editing.view;\n\t\tconst editable = view.editable;\n\t\tconst editingRoot = editingView.document.getRoot()!;\n\n\t\t// The editable UI and editing root should share the same name. Then name is used\n\t\t// to recognize the particular editable, for instance in ARIA attributes.\n\t\teditable.name = editingRoot.rootName;\n\n\t\tview.render();\n\n\t\t// The editable UI element in DOM is available for sure only after the editor UI view has been rendered.\n\t\t// But it can be available earlier if a DOM element has been passed to BalloonEditor.create().\n\t\tconst editableElement = editable.element!;\n\n\t\t// Register the editable UI view in the editor. A single editor instance can aggregate multiple\n\t\t// editable areas (roots) but the classic editor has only one.\n\t\tthis.setEditableElement( editable.name, editableElement );\n\n\t\t// Let the editable UI element respond to the changes in the global editor focus\n\t\t// tracker. It has been added to the same tracker a few lines above but, in reality, there are\n\t\t// many focusable areas in the editor, like balloons, toolbars or dropdowns and as long\n\t\t// as they have focus, the editable should act like it is focused too (although technically\n\t\t// it isn't), e.g. by setting the proper CSS class, visually announcing focus to the user.\n\t\t// Doing otherwise will result in editable focus styles disappearing, once e.g. the\n\t\t// toolbar gets focused.\n\t\tview.editable.bind( 'isFocused' ).to( this.focusTracker );\n\n\t\t// Bind the editable UI element to the editing view, making it an end– and entry–point\n\t\t// of the editor's engine. This is where the engine meets the UI.\n\t\teditingView.attachDomRoot( editableElement );\n\n\t\t// If an element containing the initial data of the editor was provided, replace it with\n\t\t// an editor instance's UI in DOM until the editor is destroyed. For instance, a <textarea>\n\t\t// can be such element.\n\t\tif ( replacementElement ) {\n\t\t\tthis._elementReplacer.replace( replacementElement, this.element as HTMLElement | undefined );\n\t\t}\n\n\t\tthis._initPlaceholder();\n\t\tthis._initToolbar();\n\n\t\tif ( view.menuBarView ) {\n\t\t\tthis._initMenuBar( view.menuBarView );\n\t\t}\n\n\t\tthis._initDialogPluginIntegration();\n\t\tthis._initContextualBalloonIntegration();\n\n\t\tthis.fire<EditorUIReadyEvent>( 'ready' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tconst view = this.view;\n\t\tconst editingView = this.editor.editing.view;\n\n\t\tthis._elementReplacer.restore();\n\n\t\tif ( editingView.getDomRoot( view.editable.name! ) ) {\n\t\t\teditingView.detachDomRoot( view.editable.name! );\n\t\t}\n\n\t\tview.destroy();\n\t}\n\n\t/**\n\t * Initializes the editor toolbar.\n\t */\n\tprivate _initToolbar(): void {\n\t\tconst view = this.view;\n\n\t\t// Set–up the sticky panel with toolbar.\n\t\tview.stickyPanel.bind( 'isActive' ).to( this.focusTracker, 'isFocused' );\n\t\tview.stickyPanel.limiterElement = view.element;\n\t\tview.stickyPanel.bind( 'viewportTopOffset' ).to( this, 'viewportOffset', ( { top } ) => top || 0 );\n\n\t\tview.toolbar.fillFromConfig( this._toolbarConfig, this.componentFactory );\n\n\t\t// Register the toolbar so it becomes available for Alt+F10 and Esc navigation.\n\t\tthis.addToolbar( view.toolbar );\n\t}\n\n\t/**\n\t * Enable the placeholder text on the editing root.\n\t */\n\tprivate _initPlaceholder(): void {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst editingRoot = editingView.document.getRoot()!;\n\t\tconst sourceElement = ( editor as Editor & ElementApi ).sourceElement;\n\n\t\tlet placeholderText;\n\t\tconst placeholder = editor.config.get( 'placeholder' );\n\n\t\tif ( placeholder ) {\n\t\t\tplaceholderText = typeof placeholder === 'string' ? placeholder : placeholder[ this.view.editable.name! ];\n\t\t}\n\n\t\tif ( !placeholderText && sourceElement && sourceElement.tagName.toLowerCase() === 'textarea' ) {\n\t\t\tplaceholderText = sourceElement.getAttribute( 'placeholder' );\n\t\t}\n\n\t\tif ( placeholderText ) {\n\t\t\teditingRoot.placeholder = placeholderText;\n\t\t}\n\n\t\tenablePlaceholder( {\n\t\t\tview: editingView,\n\t\t\telement: editingRoot,\n\t\t\tisDirectHost: false,\n\t\t\tkeepOnFocus: true\n\t\t} );\n\t}\n\n\t/**\n\t * Provides an integration between the sticky toolbar and {@link module:ui/panel/balloon/contextualballoon contextual balloon plugin}.\n\t * It allows the contextual balloon to consider the height of the\n\t * {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#stickyPanel}. It prevents the balloon from overlapping\n\t * the sticky toolbar by adjusting the balloon's position using viewport offset configuration.\n\t */\n\tprivate _initContextualBalloonIntegration(): void {\n\t\tif ( !this.editor.plugins.has( 'ContextualBalloon' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { stickyPanel } = this.view;\n\t\tconst contextualBalloon = this.editor.plugins.get( 'ContextualBalloon' );\n\n\t\tcontextualBalloon.on<ContextualBalloonGetPositionOptionsEvent>( 'getPositionOptions', evt => {\n\t\t\tconst position = evt.return;\n\n\t\t\tif ( !position || !stickyPanel.isSticky || !stickyPanel.element ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Measure toolbar (and menu bar) height.\n\t\t\tconst stickyPanelHeight = new Rect( stickyPanel.element ).height;\n\n\t\t\t// Handle edge case when the target element is larger than the limiter.\n\t\t\t// It's an issue because the contextual balloon can overlap top table cells when the table is larger than the viewport\n\t\t\t// and it's placed at the top of the editor. It's better to overlap toolbar in that situation.\n\t\t\t// Check this issue: https://github.com/ckeditor/ckeditor5/issues/15744\n\t\t\tconst target = typeof position.target === 'function' ? position.target() : position.target;\n\t\t\tconst limiter = typeof position.limiter === 'function' ? position.limiter() : position.limiter;\n\n\t\t\tif ( target && limiter && new Rect( target ).height >= new Rect( limiter ).height - stickyPanelHeight ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Ensure that viewport offset is present, it can be undefined according to the typing.\n\t\t\tconst viewportOffsetConfig = { ...position.viewportOffsetConfig };\n\t\t\tconst newTopViewportOffset = ( viewportOffsetConfig.top || 0 ) + stickyPanelHeight;\n\n\t\t\tevt.return = {\n\t\t\t\t...position,\n\t\t\t\tviewportOffsetConfig: {\n\t\t\t\t\t...viewportOffsetConfig,\n\t\t\t\t\ttop: newTopViewportOffset\n\t\t\t\t}\n\t\t\t};\n\t\t}, { priority: 'low' } );\n\n\t\t// Update balloon position when the toolbar becomes sticky or when ui viewportOffset changes.\n\t\tconst updateBalloonPosition = () => {\n\t\t\tif ( contextualBalloon.visibleView ) {\n\t\t\t\tcontextualBalloon.updatePosition();\n\t\t\t}\n\t\t};\n\n\t\tthis.listenTo( stickyPanel, 'change:isSticky', updateBalloonPosition );\n\t\tthis.listenTo( this.editor.ui, 'change:viewportOffset', updateBalloonPosition );\n\t}\n\n\t/**\n\t * Provides an integration between the sticky toolbar and {@link module:utils/dom/scroll~scrollViewportToShowTarget}.\n\t * It allows the UI-agnostic engine method to consider the geometry of the\n\t * {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#stickyPanel} that pins to the\n\t * edge of the viewport and can obscure the user caret after scrolling the window.\n\t *\n\t * @param evt The `scrollToTheSelection` event info.\n\t * @param data The payload carried by the `scrollToTheSelection` event.\n\t * @param originalArgs The original arguments passed to `scrollViewportToShowTarget()` method (see implementation to learn more).\n\t */\n\tprivate _handleScrollToTheSelectionWithStickyPanel(\n\t\tevt: EventInfo<'scrollToTheSelection'>,\n\t\tdata: ViewScrollToTheSelectionEvent[ 'args' ][ 0 ],\n\t\toriginalArgs: ViewScrollToTheSelectionEvent[ 'args' ][ 1 ]\n\t): void {\n\t\tconst stickyPanel = this.view.stickyPanel;\n\n\t\tif ( stickyPanel.isSticky ) {\n\t\t\tconst stickyPanelHeight = new Rect( stickyPanel.element! ).height;\n\n\t\t\tdata.viewportOffset.top += stickyPanelHeight;\n\t\t} else {\n\t\t\tconst scrollViewportOnPanelGettingSticky = () => {\n\t\t\t\tthis.editor.editing.view.scrollToTheSelection( originalArgs );\n\t\t\t};\n\n\t\t\tthis.listenTo( stickyPanel, 'change:isSticky', scrollViewportOnPanelGettingSticky );\n\n\t\t\t// This works as a post-scroll-fixer because it's impossible predict whether the panel will be sticky after scrolling or not.\n\t\t\t// Listen for a short period of time only and if the toolbar does not become sticky very soon, cancel the listener.\n\t\t\tsetTimeout( () => {\n\t\t\t\tthis.stopListening( stickyPanel, 'change:isSticky', scrollViewportOnPanelGettingSticky );\n\t\t\t}, 20 );\n\t\t}\n\t}\n\n\t/**\n\t * Provides an integration between the sticky toolbar and {@link module:ui/dialog/dialog the Dialog plugin}.\n\t *\n\t * It moves the dialog down to ensure that the\n\t * {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#stickyPanel sticky panel}\n\t * used by the editor UI will not get obscured by the dialog when the dialog uses one of its automatic positions.\n\t */\n\tprivate _initDialogPluginIntegration(): void {\n\t\tif ( !this.editor.plugins.has( 'Dialog' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst stickyPanel = this.view.stickyPanel;\n\t\tconst dialogPlugin: Dialog = this.editor.plugins.get( 'Dialog' );\n\n\t\tdialogPlugin.on( 'show', () => {\n\t\t\tconst dialogView = dialogPlugin.view!;\n\n\t\t\tdialogView.on<DialogViewMoveToEvent>( 'moveTo', ( evt, data ) => {\n\t\t\t\t// Engage only when the panel is sticky, and the dialog is using one of default positions.\n\t\t\t\tif ( !stickyPanel.isSticky || dialogView.wasMoved ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst stickyPanelContentRect = new Rect( stickyPanel.contentPanelElement );\n\n\t\t\t\tif ( data[ 1 ] < stickyPanelContentRect.bottom + DialogView.defaultOffset ) {\n\t\t\t\t\tdata[ 1 ] = stickyPanelContentRect.bottom + DialogView.defaultOffset;\n\t\t\t\t}\n\t\t\t}, { priority: 'high' } );\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module editor-classic/classiceditoruiview\n */\n\nimport { BoxedEditorUIView, InlineEditableUIView, MenuBarView, StickyPanelView, ToolbarView } from 'ckeditor5/src/ui.js';\nimport type { Locale } from 'ckeditor5/src/utils.js';\nimport type { EditingView } from 'ckeditor5/src/engine.js';\n\nimport '../theme/classiceditor.css';\n\n/**\n * Classic editor UI view. Uses an inline editable and a sticky toolbar, all\n * enclosed in a boxed UI view.\n */\nexport default class ClassicEditorUIView extends BoxedEditorUIView {\n\t/**\n\t * Sticky panel view instance. This is a parent view of a {@link #toolbar}\n\t * that makes toolbar sticky.\n\t */\n\tpublic readonly stickyPanel: StickyPanelView;\n\n\t/**\n\t * Toolbar view instance.\n\t */\n\tpublic readonly toolbar: ToolbarView;\n\n\t/**\n\t * Editable UI view.\n\t */\n\tpublic readonly editable: InlineEditableUIView;\n\n\t/**\n\t * Creates an instance of the classic editor UI view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param editingView The editing view instance this view is related to.\n\t * @param options Configuration options for the view instance.\n\t * @param options.shouldToolbarGroupWhenFull When set `true` enables automatic items grouping\n\t * in the main {@link module:editor-classic/classiceditoruiview~ClassicEditorUIView#toolbar toolbar}.\n\t * See {@link module:ui/toolbar/toolbarview~ToolbarOptions#shouldGroupWhenFull} to learn more.\n\t * @param options.label When set, this value will be used as an accessible `aria-label` of the\n\t * {@link module:ui/editableui/editableuiview~EditableUIView editable view}.\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\teditingView: EditingView,\n\t\toptions: {\n\t\t\tshouldToolbarGroupWhenFull?: boolean;\n\t\t\tuseMenuBar?: boolean;\n\t\t\tlabel?: string | Record<string, string>;\n\t\t} = {}\n\t) {\n\t\tsuper( locale );\n\n\t\tthis.stickyPanel = new StickyPanelView( locale );\n\n\t\tthis.toolbar = new ToolbarView( locale, {\n\t\t\tshouldGroupWhenFull: options.shouldToolbarGroupWhenFull\n\t\t} );\n\n\t\tif ( options.useMenuBar ) {\n\t\t\tthis.menuBarView = new MenuBarView( locale );\n\t\t}\n\n\t\tthis.editable = new InlineEditableUIView( locale, editingView, undefined, {\n\t\t\tlabel: options.label\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tif ( this.menuBarView ) {\n\t\t\t// Set toolbar as a child of a stickyPanel and makes toolbar sticky.\n\t\t\tthis.stickyPanel.content.addMany( [ this.menuBarView, this.toolbar ] );\n\t\t} else {\n\t\t\tthis.stickyPanel.content.add( this.toolbar );\n\t\t}\n\n\t\tthis.top.add( this.stickyPanel );\n\t\tthis.main.add( this.editable );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module editor-classic/classiceditor\n */\n\nimport ClassicEditorUI from './classiceditorui.js';\nimport ClassicEditorUIView from './classiceditoruiview.js';\n\nimport {\n\tEditor,\n\tElementApiMixin,\n\tattachToForm,\n\ttype EditorConfig,\n\ttype EditorReadyEvent\n} from 'ckeditor5/src/core.js';\nimport { getDataFromElement, CKEditorError } from 'ckeditor5/src/utils.js';\n\nimport { isElement as _isElement } from 'lodash-es';\n\n/**\n * The classic editor implementation. It uses an inline editable and a sticky toolbar, all enclosed in a boxed UI.\n * See the {@glink examples/builds/classic-editor demo}.\n *\n * In order to create a classic editor instance, use the static\n * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method.\n */\nexport default class ClassicEditor extends /* #__PURE__ */ ElementApiMixin( Editor ) {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly ui: ClassicEditorUI;\n\n\t/**\n\t * Creates an instance of the classic editor.\n\t *\n\t * **Note:** do not use the constructor to create editor instances. Use the static\n\t * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} method instead.\n\t *\n\t * @param sourceElementOrData The DOM element that will be the source for the created editor\n\t * or the editor's initial data. For more information see\n\t * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}.\n\t * @param config The editor configuration.\n\t */\n\tprotected constructor( sourceElementOrData: HTMLElement | string, config: EditorConfig = {} ) {\n\t\t// If both `config.initialData` is set and initial data is passed as the constructor parameter, then throw.\n\t\tif ( !isElement( sourceElementOrData ) && config.initialData !== undefined ) {\n\t\t\t// Documented in core/editor/editorconfig.jsdoc.\n\t\t\t// eslint-disable-next-line ckeditor5-rules/ckeditor-error-message\n\t\t\tthrow new CKEditorError( 'editor-create-initial-data', null );\n\t\t}\n\n\t\tsuper( config );\n\n\t\tthis.config.define( 'menuBar.isVisible', false );\n\n\t\tif ( this.config.get( 'initialData' ) === undefined ) {\n\t\t\tthis.config.set( 'initialData', getInitialData( sourceElementOrData ) );\n\t\t}\n\n\t\tif ( isElement( sourceElementOrData ) ) {\n\t\t\tthis.sourceElement = sourceElementOrData;\n\t\t}\n\n\t\tthis.model.document.createRoot();\n\n\t\tconst shouldToolbarGroupWhenFull = !this.config.get( 'toolbar.shouldNotGroupWhenFull' );\n\n\t\tconst menuBarConfig = this.config.get( 'menuBar' )!;\n\n\t\tconst view = new ClassicEditorUIView( this.locale, this.editing.view, {\n\t\t\tshouldToolbarGroupWhenFull,\n\t\t\tuseMenuBar: menuBarConfig.isVisible,\n\t\t\tlabel: this.config.get( 'label' )\n\t\t} );\n\n\t\tthis.ui = new ClassicEditorUI( this, view );\n\n\t\tattachToForm( this );\n\t}\n\n\t/**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * Updates the original editor element with the data if the\n\t * {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy `updateSourceElementOnDestroy`}\n\t * configuration option is set to `true`.\n\t */\n\tpublic override destroy(): Promise<unknown> {\n\t\tif ( this.sourceElement ) {\n\t\t\tthis.updateSourceElement();\n\t\t}\n\n\t\tthis.ui.destroy();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Creates a new classic editor instance.\n\t *\n\t * There are three ways how the editor can be initialized.\n\t *\n\t * # Replacing a DOM element (and loading data from it)\n\t *\n\t * You can initialize the editor using an existing DOM element:\n\t *\n\t * ```ts\n\t * ClassicEditor\n\t * \t.create( document.querySelector( '#editor' ) )\n\t * \t.then( editor => {\n\t * \t\tconsole.log( 'Editor was initialized', editor );\n\t * \t} )\n\t * \t.catch( err => {\n\t * \t\tconsole.error( err.stack );\n\t * \t} );\n\t * ```\n\t *\n\t * The element's content will be used as the editor data and the element will be replaced by the editor UI.\n\t *\n\t * # Creating a detached editor\n\t *\n\t * Alternatively, you can initialize the editor by passing the initial data directly as a string.\n\t * In this case, the editor will render an element that must be inserted into the DOM:\n\t *\n\t * ```ts\n\t * ClassicEditor\n\t * \t.create( '<p>Hello world!</p>' )\n\t * \t.then( editor => {\n\t * \t\tconsole.log( 'Editor was initialized', editor );\n\t *\n\t * \t\t// Initial data was provided so the editor UI element needs to be added manually to the DOM.\n\t * \t\tdocument.body.appendChild( editor.ui.element );\n\t * \t} )\n\t * \t.catch( err => {\n\t * \t\tconsole.error( err.stack );\n\t * \t} );\n\t * ```\n\t *\n\t * This lets you dynamically append the editor to your web page whenever it is convenient for you. You may use this method if your\n\t * web page content is generated on the client side and the DOM structure is not ready at the moment when you initialize the editor.\n\t *\n\t * # Replacing a DOM element (and data provided in `config.initialData`)\n\t *\n\t * You can also mix these two ways by providing a DOM element to be used and passing the initial data through the configuration:\n\t *\n\t * ```ts\n\t * ClassicEditor\n\t * \t.create( document.querySelector( '#editor' ), {\n\t * \t\tinitialData: '<h2>Initial data</h2><p>Foo bar.</p>'\n\t * \t} )\n\t * \t.then( editor => {\n\t * \t\tconsole.log( 'Editor was initialized', editor );\n\t * \t} )\n\t * \t.catch( err => {\n\t * \t\tconsole.error( err.stack );\n\t * \t} );\n\t * ```\n\t *\n\t * This method can be used to initialize the editor on an existing element with the specified content in case if your integration\n\t * makes it difficult to set the content of the source element.\n\t *\n\t * Note that an error will be thrown if you pass the initial data both as the first parameter and also in the configuration.\n\t *\n\t * # Configuring the editor\n\t *\n\t * See the {@link module:core/editor/editorconfig~EditorConfig editor configuration documentation} to learn more about\n\t * customizing plugins, toolbar and more.\n\t *\n\t * @param sourceElementOrData The DOM element that will be the source for the created editor\n\t * or the editor's initial data.\n\t *\n\t * If a DOM element is passed, its content will be automatically loaded to the editor upon initialization\n\t * and the {@link module:editor-classic/classiceditorui~ClassicEditorUI#element editor element} will replace the passed element\n\t * in the DOM (the original one will be hidden and the editor will be injected next to it).\n\t *\n\t * If the {@link module:core/editor/editorconfig~EditorConfig#updateSourceElementOnDestroy updateSourceElementOnDestroy}\n\t * option is set to `true`, the editor data will be set back to the original element once the editor is destroyed and when a form,\n\t * in which this element is contained, is submitted (if the original element is a `<textarea>`). This ensures seamless integration\n\t * with native web forms.\n\t *\n\t * If the initial data is passed, a detached editor will be created. In this case you need to insert it into the DOM manually.\n\t * It is available under the {@link module:editor-classic/classiceditorui~ClassicEditorUI#element `editor.ui.element`} property.\n\t *\n\t * @param config The editor configuration.\n\t * @returns A promise resolved once the editor is ready. The promise resolves with the created editor instance.\n\t */\n\tpublic static override create( sourceElementOrData: HTMLElement | string, config: EditorConfig = {} ): Promise<ClassicEditor> {\n\t\treturn new Promise( resolve => {\n\t\t\tconst editor = new this( sourceElementOrData, config );\n\n\t\t\tresolve(\n\t\t\t\teditor.initPlugins()\n\t\t\t\t\t.then( () => editor.ui.init( isElement( sourceElementOrData ) ? sourceElementOrData : null ) )\n\t\t\t\t\t.then( () => editor.data.init( editor.config.get( 'initialData' )! ) )\n\t\t\t\t\t.then( () => editor.fire<EditorReadyEvent>( 'ready' ) )\n\t\t\t\t\t.then( () => editor )\n\t\t\t);\n\t\t} );\n\t}\n}\n\nfunction getInitialData( sourceElementOrData: HTMLElement | string ): string {\n\treturn isElement( sourceElementOrData ) ? getDataFromElement( sourceElementOrData ) : sourceElementOrData;\n}\n\nfunction isElement( value: any ): value is Element {\n\treturn _isElement( value );\n}\n", "import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { getCode, parseKeystroke } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\n\n/**\n * The select all command.\n *\n * It is used by the {@link module:select-all/selectallediting~SelectAllEditing select all editing feature} to handle\n * the <kbd>Ctrl/⌘</kbd>+<kbd>A</kbd> keystroke.\n *\n * Executing this command changes the {@glink framework/architecture/editing-engine#model model}\n * selection so it contains the entire content of the editable root of the editor the selection is\n * {@link module:engine/model/selection~Selection#anchor anchored} in.\n *\n * If the selection was anchored in a {@glink framework/tutorials/widgets/implementing-a-block-widget nested editable}\n * (e.g. a caption of an image), the new selection will contain its entire content. Successive executions of this command\n * will expand the selection to encompass more and more content up to the entire editable root of the editor.\n */ class SelectAllCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        // It does not affect data so should be enabled in read-only mode.\n        this.affectsData = false;\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        let scopeElement = model.schema.getLimitElement(selection);\n        // If an entire scope is selected, or the selection's ancestor is not a scope yet,\n        // browse through ancestors to find the enclosing parent scope.\n        if (selection.containsEntireContent(scopeElement) || !isSelectAllScope(model.schema, scopeElement)) {\n            do {\n                scopeElement = scopeElement.parent;\n                // Do nothing, if the entire `root` is already selected.\n                if (!scopeElement) {\n                    return;\n                }\n            }while (!isSelectAllScope(model.schema, scopeElement))\n        }\n        model.change((writer)=>{\n            writer.setSelection(scopeElement, 'in');\n        });\n    }\n}\n/**\n * Checks whether the element is a valid select-all scope. Returns true, if the element is a\n * {@link module:engine/model/schema~Schema#isLimit limit}, and can contain any text or paragraph.\n *\n * @param schema Schema to check against.\n * @param element Model element.\n */ function isSelectAllScope(schema, element) {\n    return schema.isLimit(element) && (schema.checkChild(element, '$text') || schema.checkChild(element, 'paragraph'));\n}\n\nconst SELECT_ALL_KEYSTROKE = /* #__PURE__ */ parseKeystroke('Ctrl+A');\n/**\n * The select all editing feature.\n *\n * It registers the `'selectAll'` {@link module:select-all/selectallcommand~SelectAllCommand command}\n * and the <kbd>Ctrl/⌘</kbd>+<kbd>A</kbd> keystroke listener which executes it.\n */ class SelectAllEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SelectAllEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.t;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        editor.commands.add('selectAll', new SelectAllCommand(editor));\n        this.listenTo(viewDocument, 'keydown', (eventInfo, domEventData)=>{\n            if (getCode(domEventData) === SELECT_ALL_KEYSTROKE) {\n                editor.execute('selectAll');\n                domEventData.preventDefault();\n            }\n        });\n        // Add the information about the keystroke to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Select all'),\n                    keystroke: 'CTRL+A'\n                }\n            ]\n        });\n    }\n}\n\nvar selectAllIcon = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 20 20\\\"><path d=\\\"M.75 15.5a.75.75 0 0 1 .75.75V18l.008.09A.5.5 0 0 0 2 18.5h1.75a.75.75 0 1 1 0 1.5H1.5l-.144-.007a1.5 1.5 0 0 1-1.35-1.349L0 18.5v-2.25a.75.75 0 0 1 .75-.75zm18.5 0a.75.75 0 0 1 .75.75v2.25l-.007.144a1.5 1.5 0 0 1-1.349 1.35L18.5 20h-2.25a.75.75 0 1 1 0-1.5H18a.5.5 0 0 0 .492-.41L18.5 18v-1.75a.75.75 0 0 1 .75-.75zm-10.45 3c.11 0 .2.09.2.2v1.1a.2.2 0 0 1-.2.2H7.2a.2.2 0 0 1-.2-.2v-1.1c0-.11.09-.2.2-.2h1.6zm4 0c.11 0 .2.09.2.2v1.1a.2.2 0 0 1-.2.2h-1.6a.2.2 0 0 1-.2-.2v-1.1c0-.11.09-.2.2-.2h1.6zm.45-5.5a.75.75 0 1 1 0 1.5h-8.5a.75.75 0 1 1 0-1.5h8.5zM1.3 11c.11 0 .2.09.2.2v1.6a.2.2 0 0 1-.2.2H.2a.2.2 0 0 1-.2-.2v-1.6c0-.11.09-.2.2-.2h1.1zm18.5 0c.11 0 .2.09.2.2v1.6a.2.2 0 0 1-.2.2h-1.1a.2.2 0 0 1-.2-.2v-1.6c0-.11.09-.2.2-.2h1.1zm-4.55-2a.75.75 0 1 1 0 1.5H4.75a.75.75 0 1 1 0-1.5h10.5zM1.3 7c.11 0 .2.09.2.2v1.6a.2.2 0 0 1-.2.2H.2a.2.2 0 0 1-.2-.2V7.2c0-.11.09-.2.2-.2h1.1zm18.5 0c.11 0 .2.09.2.2v1.6a.2.2 0 0 1-.2.2h-1.1a.2.2 0 0 1-.2-.2V7.2c0-.11.09-.2.2-.2h1.1zm-4.55-2a.75.75 0 1 1 0 1.5h-2.5a.75.75 0 1 1 0-1.5h2.5zm-5 0a.75.75 0 1 1 0 1.5h-5.5a.75.75 0 0 1 0-1.5h5.5zm-6.5-5a.75.75 0 0 1 0 1.5H2a.5.5 0 0 0-.492.41L1.5 2v1.75a.75.75 0 0 1-1.5 0V1.5l.007-.144A1.5 1.5 0 0 1 1.356.006L1.5 0h2.25zM18.5 0l.144.007a1.5 1.5 0 0 1 1.35 1.349L20 1.5v2.25a.75.75 0 1 1-1.5 0V2l-.008-.09A.5.5 0 0 0 18 1.5h-1.75a.75.75 0 1 1 0-1.5h2.25zM8.8 0c.11 0 .2.09.2.2v1.1a.2.2 0 0 1-.2.2H7.2a.2.2 0 0 1-.2-.2V.2c0-.11.09-.2.2-.2h1.6zm4 0c.11 0 .2.09.2.2v1.1a.2.2 0 0 1-.2.2h-1.6a.2.2 0 0 1-.2-.2V.2c0-.11.09-.2.2-.2h1.6z\\\"/></svg>\";\n\n/**\n * The select all UI feature.\n *\n * It registers the `'selectAll'` UI button in the editor's\n * {@link module:ui/componentfactory~ComponentFactory component factory}. When clicked, the button\n * executes the {@link module:select-all/selectallcommand~SelectAllCommand select all command}.\n */ class SelectAllUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SelectAllUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        editor.ui.componentFactory.add('selectAll', ()=>{\n            const buttonView = this._createButton(ButtonView);\n            buttonView.set({\n                tooltip: true\n            });\n            return buttonView;\n        });\n        editor.ui.componentFactory.add('menuBar:selectAll', ()=>{\n            return this._createButton(MenuBarMenuListItemButtonView);\n        });\n    }\n    /**\n\t * Creates a button for select all command to use either in toolbar or in menu bar.\n\t */ _createButton(ButtonClass) {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const command = editor.commands.get('selectAll');\n        const view = new ButtonClass(editor.locale);\n        const t = locale.t;\n        view.set({\n            label: t('Select all'),\n            icon: selectAllIcon,\n            keystroke: 'Ctrl+A'\n        });\n        view.bind('isEnabled').to(command, 'isEnabled');\n        // Execute the command.\n        this.listenTo(view, 'execute', ()=>{\n            editor.execute('selectAll');\n            editor.editing.view.focus();\n        });\n        return view;\n    }\n}\n\n/**\n * The select all feature.\n *\n * This is a \"glue\" plugin which loads the {@link module:select-all/selectallediting~SelectAllEditing select all editing feature}\n * and the {@link module:select-all/selectallui~SelectAllUI select all UI feature}.\n *\n * Please refer to the documentation of individual features to learn more.\n */ class SelectAll extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            SelectAllEditing,\n            SelectAllUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'SelectAll';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { SelectAll, SelectAllEditing, SelectAllUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module select-all/selectallcommand\n */\n\nimport { Command, type Editor } from '@ckeditor/ckeditor5-core';\nimport type { Element, Schema } from '@ckeditor/ckeditor5-engine';\n\n/**\n * The select all command.\n *\n * It is used by the {@link module:select-all/selectallediting~SelectAllEditing select all editing feature} to handle\n * the <kbd>Ctrl/⌘</kbd>+<kbd>A</kbd> keystroke.\n *\n * Executing this command changes the {@glink framework/architecture/editing-engine#model model}\n * selection so it contains the entire content of the editable root of the editor the selection is\n * {@link module:engine/model/selection~Selection#anchor anchored} in.\n *\n * If the selection was anchored in a {@glink framework/tutorials/widgets/implementing-a-block-widget nested editable}\n * (e.g. a caption of an image), the new selection will contain its entire content. Successive executions of this command\n * will expand the selection to encompass more and more content up to the entire editable root of the editor.\n */\nexport default class SelectAllCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// It does not affect data so should be enabled in read-only mode.\n\t\tthis.affectsData = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tlet scopeElement: Element | null = model.schema.getLimitElement( selection );\n\n\t\t// If an entire scope is selected, or the selection's ancestor is not a scope yet,\n\t\t// browse through ancestors to find the enclosing parent scope.\n\t\tif ( selection.containsEntireContent( scopeElement ) || !isSelectAllScope( model.schema, scopeElement ) ) {\n\t\t\tdo {\n\t\t\t\tscopeElement = scopeElement.parent as Element | null;\n\n\t\t\t\t// Do nothing, if the entire `root` is already selected.\n\t\t\t\tif ( !scopeElement ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} while ( !isSelectAllScope( model.schema, scopeElement ) );\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( scopeElement!, 'in' );\n\t\t} );\n\t}\n}\n\n/**\n * Checks whether the element is a valid select-all scope. Returns true, if the element is a\n * {@link module:engine/model/schema~Schema#isLimit limit}, and can contain any text or paragraph.\n *\n * @param schema Schema to check against.\n * @param element Model element.\n */\nfunction isSelectAllScope( schema: Schema, element: Element ): boolean {\n\treturn schema.isLimit( element ) && ( schema.checkChild( element, '$text' ) || schema.checkChild( element, 'paragraph' ) );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module select-all/selectallediting\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport { getCode, parseKeystroke } from '@ckeditor/ckeditor5-utils';\nimport SelectAllCommand from './selectallcommand.js';\nimport type { ViewDocumentKeyDownEvent } from '@ckeditor/ckeditor5-engine';\n\nconst SELECT_ALL_KEYSTROKE = /* #__PURE__ */ parseKeystroke( 'Ctrl+A' );\n\n/**\n * The select all editing feature.\n *\n * It registers the `'selectAll'` {@link module:select-all/selectallcommand~SelectAllCommand command}\n * and the <kbd>Ctrl/⌘</kbd>+<kbd>A</kbd> keystroke listener which executes it.\n */\nexport default class SelectAllEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SelectAllEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\teditor.commands.add( 'selectAll', new SelectAllCommand( editor ) );\n\n\t\tthis.listenTo<ViewDocumentKeyDownEvent>( viewDocument, 'keydown', ( eventInfo, domEventData ) => {\n\t\t\tif ( getCode( domEventData ) === SELECT_ALL_KEYSTROKE ) {\n\t\t\t\teditor.execute( 'selectAll' );\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t}\n\t\t} );\n\n\t\t// Add the information about the keystroke to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Select all' ),\n\t\t\t\t\tkeystroke: 'CTRL+A'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module select-all/selectallui\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui';\n\nimport selectAllIcon from '../theme/icons/select-all.svg';\n\n/**\n * The select all UI feature.\n *\n * It registers the `'selectAll'` UI button in the editor's\n * {@link module:ui/componentfactory~ComponentFactory component factory}. When clicked, the button\n * executes the {@link module:select-all/selectallcommand~SelectAllCommand select all command}.\n */\nexport default class SelectAllUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SelectAllUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( 'selectAll', () => {\n\t\t\tconst buttonView = this._createButton( ButtonView );\n\n\t\t\tbuttonView.set( {\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\treturn buttonView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:selectAll', () => {\n\t\t\treturn this._createButton( MenuBarMenuListItemButtonView );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a button for select all command to use either in toolbar or in menu bar.\n\t */\n\tprivate _createButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>( ButtonClass: T ): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst command = editor.commands.get( 'selectAll' )!;\n\t\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\t\tconst t = locale.t;\n\n\t\tview.set( {\n\t\t\tlabel: t( 'Select all' ),\n\t\t\ticon: selectAllIcon,\n\t\t\tkeystroke: 'Ctrl+A'\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\n\t\t// Execute the command.\n\t\tthis.listenTo( view, 'execute', () => {\n\t\t\teditor.execute( 'selectAll' );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn view;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module select-all/selectall\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport SelectAllEditing from './selectallediting.js';\nimport SelectAllUI from './selectallui.js';\n\n/**\n * The select all feature.\n *\n * This is a \"glue\" plugin which loads the {@link module:select-all/selectallediting~SelectAllEditing select all editing feature}\n * and the {@link module:select-all/selectallui~SelectAllUI select all UI feature}.\n *\n * Please refer to the documentation of individual features to learn more.\n */\nexport default class SelectAll extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ SelectAllEditing, SelectAllUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'SelectAll' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { transformSets, NoOperation } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\n\n/**\n * Base class for the undo feature commands: {@link module:undo/undocommand~UndoCommand} and {@link module:undo/redocommand~RedoCommand}.\n */ class BaseCommand extends Command {\n    /**\n\t * Stack of items stored by the command. These are pairs of:\n\t *\n\t * * {@link module:engine/model/batch~Batch batch} saved by the command,\n\t * * {@link module:engine/model/selection~Selection selection} state at the moment of saving the batch.\n\t */ _stack = [];\n    /**\n\t * Stores all batches that were created by this command.\n\t *\n\t * @internal\n\t */ _createdBatches = new WeakSet();\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        // Refresh state, so the command is inactive right after initialization.\n        this.refresh();\n        // This command should not depend on selection change.\n        this._isEnabledBasedOnSelection = false;\n        // Set the transparent batch for the `editor.data.set()` call if the\n        // batch type is not set already.\n        this.listenTo(editor.data, 'set', (evt, data)=>{\n            // Create a shallow copy of the options to not change the original args.\n            // And make sure that an object is assigned to data[ 1 ].\n            data[1] = {\n                ...data[1]\n            };\n            const options = data[1];\n            // If batch type is not set, default to non-undoable batch.\n            if (!options.batchType) {\n                options.batchType = {\n                    isUndoable: false\n                };\n            }\n        }, {\n            priority: 'high'\n        });\n        // Clear the stack for the `transparent` batches.\n        this.listenTo(editor.data, 'set', (evt, data)=>{\n            // We can assume that the object exists and it has a `batchType` property.\n            // It was ensured with a higher priority listener before.\n            const options = data[1];\n            if (!options.batchType.isUndoable) {\n                this.clearStack();\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.isEnabled = this._stack.length > 0;\n    }\n    /**\n\t * Returns all batches created by this command.\n\t */ get createdBatches() {\n        return this._createdBatches;\n    }\n    /**\n\t * Stores a batch in the command, together with the selection state of the {@link module:engine/model/document~Document document}\n\t * created by the editor which this command is registered to.\n\t *\n\t * @param batch The batch to add.\n\t */ addBatch(batch) {\n        const docSelection = this.editor.model.document.selection;\n        const selection = {\n            ranges: docSelection.hasOwnRange ? Array.from(docSelection.getRanges()) : [],\n            isBackward: docSelection.isBackward\n        };\n        this._stack.push({\n            batch,\n            selection\n        });\n        this.refresh();\n    }\n    /**\n\t * Removes all items from the stack.\n\t */ clearStack() {\n        this._stack = [];\n        this.refresh();\n    }\n    /**\n\t * Restores the {@link module:engine/model/document~Document#selection document selection} state after a batch was undone.\n\t *\n\t * @param ranges Ranges to be restored.\n\t * @param isBackward A flag describing whether the restored range was selected forward or backward.\n\t * @param operations Operations which has been applied since selection has been stored.\n\t */ _restoreSelection(ranges, isBackward, operations) {\n        const model = this.editor.model;\n        const document = model.document;\n        // This will keep the transformed selection ranges.\n        const selectionRanges = [];\n        // Transform all ranges from the restored selection.\n        const transformedRangeGroups = ranges.map((range)=>range.getTransformedByOperations(operations));\n        const allRanges = transformedRangeGroups.flat();\n        for (const rangeGroup of transformedRangeGroups){\n            // While transforming there could appear ranges that are contained by other ranges, we shall ignore them.\n            const transformed = rangeGroup.filter((range)=>range.root != document.graveyard).filter((range)=>!isRangeContainedByAnyOtherRange(range, allRanges));\n            // All the transformed ranges ended up in graveyard.\n            if (!transformed.length) {\n                continue;\n            }\n            // After the range got transformed, we have an array of ranges. Some of those\n            // ranges may be \"touching\" -- they can be next to each other and could be merged.\n            normalizeRanges(transformed);\n            // For each `range` from `ranges`, we take only one transformed range.\n            // This is because we want to prevent situation where single-range selection\n            // got transformed to multi-range selection.\n            selectionRanges.push(transformed[0]);\n        }\n        // @if CK_DEBUG_ENGINE // console.log( `Restored selection by undo: ${ selectionRanges.join( ', ' ) }` );\n        // `selectionRanges` may be empty if all ranges ended up in graveyard. If that is the case, do not restore selection.\n        if (selectionRanges.length) {\n            model.change((writer)=>{\n                writer.setSelection(selectionRanges, {\n                    backward: isBackward\n                });\n            });\n        }\n    }\n    /**\n\t * Undoes a batch by reversing that batch, transforming reversed batch and finally applying it.\n\t * This is a helper method for {@link #execute}.\n\t *\n\t * @param batchToUndo The batch to be undone.\n\t * @param undoingBatch The batch that will contain undoing changes.\n\t */ _undo(batchToUndo, undoingBatch) {\n        const model = this.editor.model;\n        const document = model.document;\n        // All changes done by the command execution will be saved as one batch.\n        this._createdBatches.add(undoingBatch);\n        const operationsToUndo = batchToUndo.operations.slice().filter((operation)=>operation.isDocumentOperation);\n        operationsToUndo.reverse();\n        // We will process each operation from `batchToUndo`, in reverse order. If there were operations A, B and C in undone batch,\n        // we need to revert them in reverse order, so first C' (reversed C), then B', then A'.\n        for (const operationToUndo of operationsToUndo){\n            const nextBaseVersion = operationToUndo.baseVersion + 1;\n            const historyOperations = Array.from(document.history.getOperations(nextBaseVersion));\n            const transformedSets = transformSets([\n                operationToUndo.getReversed()\n            ], historyOperations, {\n                useRelations: true,\n                document: this.editor.model.document,\n                padWithNoOps: false,\n                forceWeakRemove: true\n            });\n            const reversedOperations = transformedSets.operationsA;\n            // After reversed operation has been transformed by all history operations, apply it.\n            for (let operation of reversedOperations){\n                // Do not apply any operation on non-editable space.\n                const affectedSelectable = operation.affectedSelectable;\n                if (affectedSelectable && !model.canEditAt(affectedSelectable)) {\n                    operation = new NoOperation(operation.baseVersion);\n                }\n                // Before applying, add the operation to the `undoingBatch`.\n                undoingBatch.addOperation(operation);\n                model.applyOperation(operation);\n                document.history.setOperationAsUndone(operationToUndo, operation);\n            }\n        }\n    }\n}\n/**\n * Normalizes list of ranges by joining intersecting or \"touching\" ranges.\n *\n * @param ranges Ranges to be normalized.\n */ function normalizeRanges(ranges) {\n    ranges.sort((a, b)=>a.start.isBefore(b.start) ? -1 : 1);\n    for(let i = 1; i < ranges.length; i++){\n        const previousRange = ranges[i - 1];\n        const joinedRange = previousRange.getJoined(ranges[i], true);\n        if (joinedRange) {\n            // Replace the ranges on the list with the new joined range.\n            i--;\n            ranges.splice(i, 2, joinedRange);\n        }\n    }\n}\nfunction isRangeContainedByAnyOtherRange(range, ranges) {\n    return ranges.some((otherRange)=>otherRange !== range && otherRange.containsRange(range, true));\n}\n\n/**\n * The undo command stores {@link module:engine/model/batch~Batch batches} applied to the\n * {@link module:engine/model/document~Document document} and is able to undo a batch by reversing it and transforming by\n * batches from {@link module:engine/model/document~Document#history history} that happened after the reversed batch.\n *\n * The undo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n */ class UndoCommand extends BaseCommand {\n    /**\n\t * Executes the command. This method reverts a {@link module:engine/model/batch~Batch batch} added to the command's stack, transforms\n\t * and applies the reverted version on the {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t * @fires revert\n\t * @param batch A batch that should be undone. If not set, the last added batch will be undone.\n\t */ execute(batch = null) {\n        // If batch is not given, set `batchIndex` to the last index in command stack.\n        const batchIndex = batch ? this._stack.findIndex((a)=>a.batch == batch) : this._stack.length - 1;\n        const item = this._stack.splice(batchIndex, 1)[0];\n        const undoingBatch = this.editor.model.createBatch({\n            isUndo: true\n        });\n        // All changes have to be done in one `enqueueChange` callback so other listeners will not\n        // step between consecutive operations, or won't do changes to the document before selection is properly restored.\n        this.editor.model.enqueueChange(undoingBatch, ()=>{\n            this._undo(item.batch, undoingBatch);\n            const operations = this.editor.model.document.history.getOperations(item.batch.baseVersion);\n            this._restoreSelection(item.selection.ranges, item.selection.isBackward, operations);\n        });\n        // Firing `revert` event after the change block to make sure that it includes all changes from post-fixers\n        // and make sure that the selection is \"stabilized\" (the selection range is saved after undo is executed and then\n        // restored on redo, so it is important that the selection range is saved after post-fixers are done).\n        this.fire('revert', item.batch, undoingBatch);\n        this.refresh();\n    }\n}\n\n/**\n * The redo command stores {@link module:engine/model/batch~Batch batches} that were used to undo a batch by\n * {@link module:undo/undocommand~UndoCommand}. It is able to redo a previously undone batch by reversing the undoing\n * batches created by `UndoCommand`. The reversed batch is transformed by all the batches from\n * {@link module:engine/model/document~Document#history history} that happened after the reversed undo batch.\n *\n * The redo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n */ class RedoCommand extends BaseCommand {\n    /**\n\t * Executes the command. This method reverts the last {@link module:engine/model/batch~Batch batch} added to\n\t * the command's stack, applies the reverted and transformed version on the\n\t * {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t */ execute() {\n        const item = this._stack.pop();\n        const redoingBatch = this.editor.model.createBatch({\n            isUndo: true\n        });\n        // All changes have to be done in one `enqueueChange` callback so other listeners will not step between consecutive\n        // operations, or won't do changes to the document before selection is properly restored.\n        this.editor.model.enqueueChange(redoingBatch, ()=>{\n            const lastOperation = item.batch.operations[item.batch.operations.length - 1];\n            const nextBaseVersion = lastOperation.baseVersion + 1;\n            const operations = this.editor.model.document.history.getOperations(nextBaseVersion);\n            this._restoreSelection(item.selection.ranges, item.selection.isBackward, operations);\n            this._undo(item.batch, redoingBatch);\n        });\n        this.refresh();\n    }\n}\n\n/**\n * The undo engine feature.\n *\n * It introduces the `'undo'` and `'redo'` commands to the editor.\n */ class UndoEditing extends Plugin {\n    /**\n\t * The command that manages the undo {@link module:engine/model/batch~Batch batches} stack (history).\n\t * Created and registered during the {@link #init feature initialization}.\n\t */ _undoCommand;\n    /**\n\t * The command that manages the redo {@link module:engine/model/batch~Batch batches} stack (history).\n\t * Created and registered during the {@link #init feature initialization}.\n\t */ _redoCommand;\n    /**\n\t * Keeps track of which batches were registered in undo.\n\t */ _batchRegistry = new WeakSet();\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'UndoEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.t;\n        // Create commands.\n        this._undoCommand = new UndoCommand(editor);\n        this._redoCommand = new RedoCommand(editor);\n        // Register command to the editor.\n        editor.commands.add('undo', this._undoCommand);\n        editor.commands.add('redo', this._redoCommand);\n        this.listenTo(editor.model, 'applyOperation', (evt, args)=>{\n            const operation = args[0];\n            // Do not register batch if the operation is not a document operation.\n            // This prevents from creating empty undo steps, where all operations where non-document operations.\n            // Non-document operations creates and alters content in detached tree fragments (for example, document fragments).\n            // Most of time this is preparing data before it is inserted into actual tree (for example during copy & paste).\n            // Such operations should not be reversed.\n            if (!operation.isDocumentOperation) {\n                return;\n            }\n            const batch = operation.batch;\n            const isRedoBatch = this._redoCommand.createdBatches.has(batch);\n            const isUndoBatch = this._undoCommand.createdBatches.has(batch);\n            const wasProcessed = this._batchRegistry.has(batch);\n            // Skip the batch if it was already processed.\n            if (wasProcessed) {\n                return;\n            }\n            // Add the batch to the registry so it will not be processed again.\n            this._batchRegistry.add(batch);\n            if (!batch.isUndoable) {\n                return;\n            }\n            if (isRedoBatch) {\n                // If this batch comes from `redoCommand`, add it to the `undoCommand` stack.\n                this._undoCommand.addBatch(batch);\n            } else if (!isUndoBatch) {\n                // If the batch comes neither  from `redoCommand` nor from `undoCommand` then it is a new, regular batch.\n                // Add the batch to the `undoCommand` stack and clear the `redoCommand` stack.\n                this._undoCommand.addBatch(batch);\n                this._redoCommand.clearStack();\n            }\n        }, {\n            priority: 'highest'\n        });\n        this.listenTo(this._undoCommand, 'revert', (evt, undoneBatch, undoingBatch)=>{\n            this._redoCommand.addBatch(undoingBatch);\n        });\n        editor.keystrokes.set('CTRL+Z', 'undo');\n        editor.keystrokes.set('CTRL+Y', 'redo');\n        editor.keystrokes.set('CTRL+SHIFT+Z', 'redo');\n        // Add the information about the keystrokes to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Undo'),\n                    keystroke: 'CTRL+Z'\n                },\n                {\n                    label: t('Redo'),\n                    keystroke: [\n                        [\n                            'CTRL+Y'\n                        ],\n                        [\n                            'CTRL+SHIFT+Z'\n                        ]\n                    ]\n                }\n            ]\n        });\n    }\n}\n\n/**\n * The undo UI feature. It introduces the `'undo'` and `'redo'` buttons to the editor.\n */ class UndoUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'UndoUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const t = editor.t;\n        const localizedUndoIcon = locale.uiLanguageDirection == 'ltr' ? icons.undo : icons.redo;\n        const localizedRedoIcon = locale.uiLanguageDirection == 'ltr' ? icons.redo : icons.undo;\n        this._addButtonsToFactory('undo', t('Undo'), 'CTRL+Z', localizedUndoIcon);\n        this._addButtonsToFactory('redo', t('Redo'), 'CTRL+Y', localizedRedoIcon);\n    }\n    /**\n\t * Creates a button for the specified command.\n\t *\n\t * @param name Command name.\n\t * @param label Button label.\n\t * @param keystroke Command keystroke.\n\t * @param Icon Source of the icon.\n\t */ _addButtonsToFactory(name, label, keystroke, Icon) {\n        const editor = this.editor;\n        editor.ui.componentFactory.add(name, ()=>{\n            const buttonView = this._createButton(ButtonView, name, label, keystroke, Icon);\n            buttonView.set({\n                tooltip: true\n            });\n            return buttonView;\n        });\n        editor.ui.componentFactory.add('menuBar:' + name, ()=>{\n            return this._createButton(MenuBarMenuListItemButtonView, name, label, keystroke, Icon);\n        });\n    }\n    /**\n\t * TODO\n\t */ _createButton(ButtonClass, name, label, keystroke, Icon) {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const command = editor.commands.get(name);\n        const view = new ButtonClass(locale);\n        view.set({\n            label,\n            icon: Icon,\n            keystroke\n        });\n        view.bind('isEnabled').to(command, 'isEnabled');\n        this.listenTo(view, 'execute', ()=>{\n            editor.execute(name);\n            editor.editing.view.focus();\n        });\n        return view;\n    }\n}\n\n/**\n * The undo feature.\n *\n * This is a \"glue\" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}\n * and the {@link module:undo/undoui~UndoUI undo UI feature}.\n *\n * Below is an explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:\n *\n * Whenever an {@link module:engine/model/operation/operation~Operation operation} is applied to the\n * {@link module:engine/model/document~Document document}, it is saved to `History` as is.\n * The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in\n * {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the\n * operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation\n * and a batch is seen as one undo step.\n *\n * After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:\n *\n * ```\n *    History                            Undo stack\n * ==============             ==================================\n * [operation A1]                      [  batch A  ]\n * [operation B1]                      [  batch B  ]\n * [operation B2]                      [  batch C  ]\n * [operation C1]\n * [operation C2]\n * [operation B3]\n * [operation C3]\n * ```\n *\n * Where operations starting with the same letter are from same batch.\n *\n * Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.\n * For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing\n * operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`\n * need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`\n * does not know that operations `Y` and `Z` happened.\n *\n * After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},\n * one needs to make sure if they are ready to be applied. In the scenario above, operation `C3` is the last operation and `C3r`\n * bases on up-to-date document state, so it can be applied to the document.\n *\n * ```\n *      History                             Undo stack\n * =================             ==================================\n * [ operation A1  ]                      [  batch A  ]\n * [ operation B1  ]                      [  batch B  ]\n * [ operation B2  ]             [   processing undoing batch C   ]\n * [ operation C1  ]\n * [ operation C2  ]\n * [ operation B3  ]\n * [ operation C3  ]\n * [ operation C3r ]\n * ```\n *\n * Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be\n * transformed by operations from history that happened after it, so it \"knows\" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,\n * where `*` means \"transformed by\". Rest of operations from that batch are processed in the same fashion.\n *\n * ```\n *      History                             Undo stack                                      Redo stack\n * =================             ==================================             ==================================\n * [ operation A1  ]                      [  batch A  ]                                    [ batch Cr ]\n * [ operation B1  ]                      [  batch B  ]\n * [ operation B2  ]\n * [ operation C1  ]\n * [ operation C2  ]\n * [ operation B3  ]\n * [ operation C3  ]\n * [ operation C3r ]\n * [ operation C2' ]\n * [ operation C1' ]\n * ```\n *\n * Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.\n * The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.\n *\n * Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from\n * the batch that is re-done are reversed-back, transformed in proper order and applied to the document.\n *\n * ```\n *      History                             Undo stack                                      Redo stack\n * =================             ==================================             ==================================\n * [ operation A1  ]                      [  batch A  ]\n * [ operation B1  ]                      [  batch B  ]\n * [ operation B2  ]                      [ batch Crr ]\n * [ operation C1  ]\n * [ operation C2  ]\n * [ operation B3  ]\n * [ operation C3  ]\n * [ operation C3r ]\n * [ operation C2' ]\n * [ operation C1' ]\n * [ operation C1'r]\n * [ operation C2'r]\n * [ operation C3rr]\n * ```\n */ class Undo extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            UndoEditing,\n            UndoUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Undo';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { Undo, UndoEditing, UndoUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module undo/basecommand\n */\n\nimport { Command, type Editor } from '@ckeditor/ckeditor5-core';\n\nimport {\n\ttransformSets,\n\ttype Batch,\n\ttype Operation,\n\ttype DataControllerSetEvent,\n\ttype Range,\n\tNoOperation\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * Base class for the undo feature commands: {@link module:undo/undocommand~UndoCommand} and {@link module:undo/redocommand~RedoCommand}.\n */\nexport default abstract class BaseCommand extends Command {\n\t/**\n\t * Stack of items stored by the command. These are pairs of:\n\t *\n\t * * {@link module:engine/model/batch~Batch batch} saved by the command,\n\t * * {@link module:engine/model/selection~Selection selection} state at the moment of saving the batch.\n\t */\n\tprotected _stack: Array<{ batch: Batch; selection: { ranges: Array<Range>; isBackward: boolean } }> = [];\n\n\t/**\n\t * Stores all batches that were created by this command.\n\t *\n\t * @internal\n\t */\n\tpublic _createdBatches = new WeakSet<Batch>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// Refresh state, so the command is inactive right after initialization.\n\t\tthis.refresh();\n\n\t\t// This command should not depend on selection change.\n\t\tthis._isEnabledBasedOnSelection = false;\n\n\t\t// Set the transparent batch for the `editor.data.set()` call if the\n\t\t// batch type is not set already.\n\t\tthis.listenTo<DataControllerSetEvent>( editor.data, 'set', ( evt, data ) => {\n\t\t\t// Create a shallow copy of the options to not change the original args.\n\t\t\t// And make sure that an object is assigned to data[ 1 ].\n\t\t\tdata[ 1 ] = { ...data[ 1 ] };\n\n\t\t\tconst options = data[ 1 ];\n\n\t\t\t// If batch type is not set, default to non-undoable batch.\n\t\t\tif ( !options.batchType ) {\n\t\t\t\toptions.batchType = { isUndoable: false };\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// Clear the stack for the `transparent` batches.\n\t\tthis.listenTo<DataControllerSetEvent>( editor.data, 'set', ( evt, data ) => {\n\t\t\t// We can assume that the object exists and it has a `batchType` property.\n\t\t\t// It was ensured with a higher priority listener before.\n\t\t\tconst options = data[ 1 ]!;\n\n\t\t\tif ( !options.batchType!.isUndoable ) {\n\t\t\t\tthis.clearStack();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.isEnabled = this._stack.length > 0;\n\t}\n\n\t/**\n\t * Returns all batches created by this command.\n\t */\n\tpublic get createdBatches(): WeakSet<Batch> {\n\t\treturn this._createdBatches;\n\t}\n\n\t/**\n\t * Stores a batch in the command, together with the selection state of the {@link module:engine/model/document~Document document}\n\t * created by the editor which this command is registered to.\n\t *\n\t * @param batch The batch to add.\n\t */\n\tpublic addBatch( batch: Batch ): void {\n\t\tconst docSelection = this.editor.model.document.selection;\n\n\t\tconst selection = {\n\t\t\tranges: docSelection.hasOwnRange ? Array.from( docSelection.getRanges() ) : [],\n\t\t\tisBackward: docSelection.isBackward\n\t\t};\n\n\t\tthis._stack.push( { batch, selection } );\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Removes all items from the stack.\n\t */\n\tpublic clearStack(): void {\n\t\tthis._stack = [];\n\t\tthis.refresh();\n\t}\n\n\t/**\n\t * Restores the {@link module:engine/model/document~Document#selection document selection} state after a batch was undone.\n\t *\n\t * @param ranges Ranges to be restored.\n\t * @param isBackward A flag describing whether the restored range was selected forward or backward.\n\t * @param operations Operations which has been applied since selection has been stored.\n\t */\n\tprotected _restoreSelection(\n\t\tranges: Array<Range>,\n\t\tisBackward: boolean,\n\t\toperations: Array<Operation>\n\t): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\t// This will keep the transformed selection ranges.\n\t\tconst selectionRanges: Array<Range> = [];\n\n\t\t// Transform all ranges from the restored selection.\n\t\tconst transformedRangeGroups = ranges.map( range => range.getTransformedByOperations( operations ) );\n\t\tconst allRanges = transformedRangeGroups.flat();\n\n\t\tfor ( const rangeGroup of transformedRangeGroups ) {\n\t\t\t// While transforming there could appear ranges that are contained by other ranges, we shall ignore them.\n\t\t\tconst transformed = rangeGroup\n\t\t\t\t.filter( range => range.root != document.graveyard )\n\t\t\t\t.filter( range => !isRangeContainedByAnyOtherRange( range, allRanges ) );\n\n\t\t\t// All the transformed ranges ended up in graveyard.\n\t\t\tif ( !transformed.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// After the range got transformed, we have an array of ranges. Some of those\n\t\t\t// ranges may be \"touching\" -- they can be next to each other and could be merged.\n\t\t\tnormalizeRanges( transformed );\n\n\t\t\t// For each `range` from `ranges`, we take only one transformed range.\n\t\t\t// This is because we want to prevent situation where single-range selection\n\t\t\t// got transformed to multi-range selection.\n\t\t\tselectionRanges.push( transformed[ 0 ] );\n\t\t}\n\n\t\t// @if CK_DEBUG_ENGINE // console.log( `Restored selection by undo: ${ selectionRanges.join( ', ' ) }` );\n\n\t\t// `selectionRanges` may be empty if all ranges ended up in graveyard. If that is the case, do not restore selection.\n\t\tif ( selectionRanges.length ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( selectionRanges, { backward: isBackward } );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Undoes a batch by reversing that batch, transforming reversed batch and finally applying it.\n\t * This is a helper method for {@link #execute}.\n\t *\n\t * @param batchToUndo The batch to be undone.\n\t * @param undoingBatch The batch that will contain undoing changes.\n\t */\n\tprotected _undo( batchToUndo: Batch, undoingBatch: Batch ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\t// All changes done by the command execution will be saved as one batch.\n\t\tthis._createdBatches.add( undoingBatch );\n\n\t\tconst operationsToUndo = batchToUndo.operations.slice().filter( operation => operation.isDocumentOperation );\n\t\toperationsToUndo.reverse();\n\n\t\t// We will process each operation from `batchToUndo`, in reverse order. If there were operations A, B and C in undone batch,\n\t\t// we need to revert them in reverse order, so first C' (reversed C), then B', then A'.\n\t\tfor ( const operationToUndo of operationsToUndo ) {\n\t\t\tconst nextBaseVersion = operationToUndo.baseVersion! + 1;\n\t\t\tconst historyOperations = Array.from( document.history.getOperations( nextBaseVersion ) );\n\n\t\t\tconst transformedSets = transformSets(\n\t\t\t\t[ operationToUndo.getReversed() ],\n\t\t\t\thistoryOperations,\n\t\t\t\t{\n\t\t\t\t\tuseRelations: true,\n\t\t\t\t\tdocument: this.editor.model.document,\n\t\t\t\t\tpadWithNoOps: false,\n\t\t\t\t\tforceWeakRemove: true\n\t\t\t\t}\n\t\t\t);\n\n\t\t\tconst reversedOperations = transformedSets.operationsA;\n\n\t\t\t// After reversed operation has been transformed by all history operations, apply it.\n\t\t\tfor ( let operation of reversedOperations ) {\n\t\t\t\t// Do not apply any operation on non-editable space.\n\t\t\t\tconst affectedSelectable = operation.affectedSelectable;\n\n\t\t\t\tif ( affectedSelectable && !model.canEditAt( affectedSelectable ) ) {\n\t\t\t\t\toperation = new NoOperation( operation.baseVersion );\n\t\t\t\t}\n\n\t\t\t\t// Before applying, add the operation to the `undoingBatch`.\n\t\t\t\tundoingBatch.addOperation( operation );\n\t\t\t\tmodel.applyOperation( operation );\n\n\t\t\t\tdocument.history.setOperationAsUndone( operationToUndo, operation );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Normalizes list of ranges by joining intersecting or \"touching\" ranges.\n *\n * @param ranges Ranges to be normalized.\n */\nfunction normalizeRanges( ranges: Array<Range> ): void {\n\tranges.sort( ( a, b ) => a.start.isBefore( b.start ) ? -1 : 1 );\n\n\tfor ( let i = 1; i < ranges.length; i++ ) {\n\t\tconst previousRange = ranges[ i - 1 ];\n\t\tconst joinedRange = previousRange.getJoined( ranges[ i ], true );\n\n\t\tif ( joinedRange ) {\n\t\t\t// Replace the ranges on the list with the new joined range.\n\t\t\ti--;\n\t\t\tranges.splice( i, 2, joinedRange );\n\t\t}\n\t}\n}\n\nfunction isRangeContainedByAnyOtherRange( range: Range, ranges: Array<Range> ): boolean {\n\treturn ranges.some( otherRange => otherRange !== range && otherRange.containsRange( range, true ) );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module undo/undocommand\n */\n\nimport BaseCommand from './basecommand.js';\nimport type { Batch } from '@ckeditor/ckeditor5-engine';\n\n/**\n * The undo command stores {@link module:engine/model/batch~Batch batches} applied to the\n * {@link module:engine/model/document~Document document} and is able to undo a batch by reversing it and transforming by\n * batches from {@link module:engine/model/document~Document#history history} that happened after the reversed batch.\n *\n * The undo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n */\nexport default class UndoCommand extends BaseCommand {\n\t/**\n\t * Executes the command. This method reverts a {@link module:engine/model/batch~Batch batch} added to the command's stack, transforms\n\t * and applies the reverted version on the {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t * @fires revert\n\t * @param batch A batch that should be undone. If not set, the last added batch will be undone.\n\t */\n\tpublic override execute( batch: Batch | null = null ): void {\n\t\t// If batch is not given, set `batchIndex` to the last index in command stack.\n\t\tconst batchIndex = batch ? this._stack.findIndex( a => a.batch == batch ) : this._stack.length - 1;\n\n\t\tconst item = this._stack.splice( batchIndex, 1 )[ 0 ];\n\t\tconst undoingBatch = this.editor.model.createBatch( { isUndo: true } );\n\n\t\t// All changes have to be done in one `enqueueChange` callback so other listeners will not\n\t\t// step between consecutive operations, or won't do changes to the document before selection is properly restored.\n\t\tthis.editor.model.enqueueChange( undoingBatch, () => {\n\t\t\tthis._undo( item.batch, undoingBatch );\n\n\t\t\tconst operations = this.editor.model.document.history.getOperations( item.batch.baseVersion! );\n\t\t\tthis._restoreSelection( item.selection.ranges, item.selection.isBackward, operations );\n\t\t} );\n\n\t\t// Firing `revert` event after the change block to make sure that it includes all changes from post-fixers\n\t\t// and make sure that the selection is \"stabilized\" (the selection range is saved after undo is executed and then\n\t\t// restored on redo, so it is important that the selection range is saved after post-fixers are done).\n\t\tthis.fire<UndoCommandRevertEvent>( 'revert', item.batch, undoingBatch );\n\n\t\tthis.refresh();\n\t}\n}\n\n/**\n * Fired when execution of the command reverts some batch.\n *\n * @eventName ~UndoCommand#revert\n */\nexport type UndoCommandRevertEvent = {\n\tname: 'revert';\n\targs: [ batch: Batch, undoingBatch: Batch ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module undo/redocommand\n */\n\nimport BaseCommand from './basecommand.js';\n\n/**\n * The redo command stores {@link module:engine/model/batch~Batch batches} that were used to undo a batch by\n * {@link module:undo/undocommand~UndoCommand}. It is able to redo a previously undone batch by reversing the undoing\n * batches created by `UndoCommand`. The reversed batch is transformed by all the batches from\n * {@link module:engine/model/document~Document#history history} that happened after the reversed undo batch.\n *\n * The redo command also takes care of restoring the {@link module:engine/model/document~Document#selection document selection}.\n */\nexport default class RedoCommand extends BaseCommand {\n\t/**\n\t * Executes the command. This method reverts the last {@link module:engine/model/batch~Batch batch} added to\n\t * the command's stack, applies the reverted and transformed version on the\n\t * {@link module:engine/model/document~Document document} and removes the batch from the stack.\n\t * Then, it restores the {@link module:engine/model/document~Document#selection document selection}.\n\t *\n\t * @fires execute\n\t */\n\tpublic override execute(): void {\n\t\tconst item = this._stack.pop()!;\n\t\tconst redoingBatch = this.editor.model.createBatch( { isUndo: true } );\n\n\t\t// All changes have to be done in one `enqueueChange` callback so other listeners will not step between consecutive\n\t\t// operations, or won't do changes to the document before selection is properly restored.\n\t\tthis.editor.model.enqueueChange( redoingBatch, () => {\n\t\t\tconst lastOperation = item.batch.operations[ item.batch.operations.length - 1 ];\n\t\t\tconst nextBaseVersion = lastOperation.baseVersion! + 1;\n\t\t\tconst operations = this.editor.model.document.history.getOperations( nextBaseVersion );\n\n\t\t\tthis._restoreSelection( item.selection.ranges, item.selection.isBackward, operations );\n\t\t\tthis._undo( item.batch, redoingBatch );\n\t\t} );\n\n\t\tthis.refresh();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module undo/undoediting\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\nimport UndoCommand, { type UndoCommandRevertEvent } from './undocommand.js';\nimport RedoCommand from './redocommand.js';\n\nimport type {\n\tBatch,\n\tModelApplyOperationEvent\n} from '@ckeditor/ckeditor5-engine';\n\n/**\n * The undo engine feature.\n *\n * It introduces the `'undo'` and `'redo'` commands to the editor.\n */\nexport default class UndoEditing extends Plugin {\n\t/**\n\t * The command that manages the undo {@link module:engine/model/batch~Batch batches} stack (history).\n\t * Created and registered during the {@link #init feature initialization}.\n\t */\n\tprivate _undoCommand!: UndoCommand;\n\n\t/**\n\t * The command that manages the redo {@link module:engine/model/batch~Batch batches} stack (history).\n\t * Created and registered during the {@link #init feature initialization}.\n\t */\n\tprivate _redoCommand!: RedoCommand;\n\n\t/**\n\t * Keeps track of which batches were registered in undo.\n\t */\n\tprivate _batchRegistry = new WeakSet<Batch>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'UndoEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\t// Create commands.\n\t\tthis._undoCommand = new UndoCommand( editor );\n\t\tthis._redoCommand = new RedoCommand( editor );\n\n\t\t// Register command to the editor.\n\t\teditor.commands.add( 'undo', this._undoCommand );\n\t\teditor.commands.add( 'redo', this._redoCommand );\n\n\t\tthis.listenTo<ModelApplyOperationEvent>( editor.model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\t// Do not register batch if the operation is not a document operation.\n\t\t\t// This prevents from creating empty undo steps, where all operations where non-document operations.\n\t\t\t// Non-document operations creates and alters content in detached tree fragments (for example, document fragments).\n\t\t\t// Most of time this is preparing data before it is inserted into actual tree (for example during copy & paste).\n\t\t\t// Such operations should not be reversed.\n\t\t\tif ( !operation.isDocumentOperation ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch = operation.batch!;\n\n\t\t\tconst isRedoBatch = this._redoCommand.createdBatches.has( batch );\n\t\t\tconst isUndoBatch = this._undoCommand.createdBatches.has( batch );\n\t\t\tconst wasProcessed = this._batchRegistry.has( batch );\n\n\t\t\t// Skip the batch if it was already processed.\n\t\t\tif ( wasProcessed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add the batch to the registry so it will not be processed again.\n\t\t\tthis._batchRegistry.add( batch );\n\n\t\t\tif ( !batch.isUndoable ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isRedoBatch ) {\n\t\t\t\t// If this batch comes from `redoCommand`, add it to the `undoCommand` stack.\n\t\t\t\tthis._undoCommand.addBatch( batch );\n\t\t\t} else if ( !isUndoBatch ) {\n\t\t\t\t// If the batch comes neither  from `redoCommand` nor from `undoCommand` then it is a new, regular batch.\n\t\t\t\t// Add the batch to the `undoCommand` stack and clear the `redoCommand` stack.\n\t\t\t\tthis._undoCommand.addBatch( batch );\n\t\t\t\tthis._redoCommand.clearStack();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo<UndoCommandRevertEvent>( this._undoCommand, 'revert', ( evt, undoneBatch, undoingBatch ) => {\n\t\t\tthis._redoCommand.addBatch( undoingBatch );\n\t\t} );\n\n\t\teditor.keystrokes.set( 'CTRL+Z', 'undo' );\n\t\teditor.keystrokes.set( 'CTRL+Y', 'redo' );\n\t\teditor.keystrokes.set( 'CTRL+SHIFT+Z', 'redo' );\n\n\t\t// Add the information about the keystrokes to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Undo' ),\n\t\t\t\t\tkeystroke: 'CTRL+Z'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Redo' ),\n\t\t\t\t\tkeystroke: [ [ 'CTRL+Y' ], [ 'CTRL+SHIFT+Z' ] ]\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module undo/undoui\n */\n\nimport { icons, Plugin } from '@ckeditor/ckeditor5-core';\nimport { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui';\n\n/**\n * The undo UI feature. It introduces the `'undo'` and `'redo'` buttons to the editor.\n */\nexport default class UndoUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'UndoUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst t = editor.t;\n\n\t\tconst localizedUndoIcon = locale.uiLanguageDirection == 'ltr' ? icons.undo : icons.redo;\n\t\tconst localizedRedoIcon = locale.uiLanguageDirection == 'ltr' ? icons.redo : icons.undo;\n\n\t\tthis._addButtonsToFactory( 'undo', t( 'Undo' ), 'CTRL+Z', localizedUndoIcon );\n\t\tthis._addButtonsToFactory( 'redo', t( 'Redo' ), 'CTRL+Y', localizedRedoIcon );\n\t}\n\n\t/**\n\t * Creates a button for the specified command.\n\t *\n\t * @param name Command name.\n\t * @param label Button label.\n\t * @param keystroke Command keystroke.\n\t * @param Icon Source of the icon.\n\t */\n\tprivate _addButtonsToFactory( name: 'undo' | 'redo', label: string, keystroke: string, Icon: string ) {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( name, () => {\n\t\t\tconst buttonView = this._createButton( ButtonView, name, label, keystroke, Icon );\n\n\t\t\tbuttonView.set( {\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\treturn buttonView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:' + name, () => {\n\t\t\treturn this._createButton( MenuBarMenuListItemButtonView, name, label, keystroke, Icon );\n\t\t} );\n\t}\n\n\t/**\n\t * TODO\n\t */\n\tprivate _createButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>(\n\t\tButtonClass: T,\n\t\tname: 'undo' | 'redo',\n\t\tlabel: string,\n\t\tkeystroke: string,\n\t\tIcon: string\n\t): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst command = editor.commands.get( name )!;\n\t\tconst view = new ButtonClass( locale ) as InstanceType<T>;\n\n\t\tview.set( {\n\t\t\tlabel,\n\t\t\ticon: Icon,\n\t\t\tkeystroke\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\n\t\tthis.listenTo( view, 'execute', () => {\n\t\t\teditor.execute( name );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn view;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module undo/undo\n */\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\nimport UndoEditing from './undoediting.js';\nimport UndoUI from './undoui.js';\n\n/**\n * The undo feature.\n *\n * This is a \"glue\" plugin which loads the {@link module:undo/undoediting~UndoEditing undo editing feature}\n * and the {@link module:undo/undoui~UndoUI undo UI feature}.\n *\n * Below is an explanation of the undo mechanism working together with {@link module:engine/model/history~History History}:\n *\n * Whenever an {@link module:engine/model/operation/operation~Operation operation} is applied to the\n * {@link module:engine/model/document~Document document}, it is saved to `History` as is.\n * The {@link module:engine/model/batch~Batch batch} that owns that operation is also saved, in\n * {@link module:undo/undocommand~UndoCommand}, together with the selection that was present in the document before the\n * operation was applied. A batch is saved instead of the operation because changes are undone batch-by-batch, not operation-by-operation\n * and a batch is seen as one undo step.\n *\n * After changes happen to the document, the `History` and `UndoCommand` stack can be represented as follows:\n *\n * ```\n *    History                            Undo stack\n * ==============             ==================================\n * [operation A1]                      [  batch A  ]\n * [operation B1]                      [  batch B  ]\n * [operation B2]                      [  batch C  ]\n * [operation C1]\n * [operation C2]\n * [operation B3]\n * [operation C3]\n * ```\n *\n * Where operations starting with the same letter are from same batch.\n *\n * Undoing a batch means that a set of operations which will reverse the effects of that batch needs to be generated.\n * For example, if a batch added several letters, undoing the batch should remove them. It is important to apply undoing\n * operations in the reversed order, so if a batch has operation `X`, `Y`, `Z`, reversed operations `Zr`, `Yr` and `Xr`\n * need to be applied. Otherwise reversed operation `Xr` would operate on a wrong document state, because operation `X`\n * does not know that operations `Y` and `Z` happened.\n *\n * After operations from an undone batch got {@link module:engine/model/operation/operation~Operation#getReversed reversed},\n * one needs to make sure if they are ready to be applied. In the scenario above, operation `C3` is the last operation and `C3r`\n * bases on up-to-date document state, so it can be applied to the document.\n *\n * ```\n *      History                             Undo stack\n * =================             ==================================\n * [ operation A1  ]                      [  batch A  ]\n * [ operation B1  ]                      [  batch B  ]\n * [ operation B2  ]             [   processing undoing batch C   ]\n * [ operation C1  ]\n * [ operation C2  ]\n * [ operation B3  ]\n * [ operation C3  ]\n * [ operation C3r ]\n * ```\n *\n * Next is operation `C2`, reversed to `C2r`. `C2r` bases on `C2`, so it bases on the wrong document state. It needs to be\n * transformed by operations from history that happened after it, so it \"knows\" about them. Let us assume that `C2' = C2r * B3 * C3 * C3r`,\n * where `*` means \"transformed by\". Rest of operations from that batch are processed in the same fashion.\n *\n * ```\n *      History                             Undo stack                                      Redo stack\n * =================             ==================================             ==================================\n * [ operation A1  ]                      [  batch A  ]                                    [ batch Cr ]\n * [ operation B1  ]                      [  batch B  ]\n * [ operation B2  ]\n * [ operation C1  ]\n * [ operation C2  ]\n * [ operation B3  ]\n * [ operation C3  ]\n * [ operation C3r ]\n * [ operation C2' ]\n * [ operation C1' ]\n * ```\n *\n * Selective undo works on the same basis, however, instead of undoing the last batch in the undo stack, any batch can be undone.\n * The same algorithm applies: operations from a batch (i.e. `A1`) are reversed and then transformed by operations stored in history.\n *\n * Redo also is very similar to undo. It has its own stack that is filled with undoing (reversed batches). Operations from\n * the batch that is re-done are reversed-back, transformed in proper order and applied to the document.\n *\n * ```\n *      History                             Undo stack                                      Redo stack\n * =================             ==================================             ==================================\n * [ operation A1  ]                      [  batch A  ]\n * [ operation B1  ]                      [  batch B  ]\n * [ operation B2  ]                      [ batch Crr ]\n * [ operation C1  ]\n * [ operation C2  ]\n * [ operation B3  ]\n * [ operation C3  ]\n * [ operation C3r ]\n * [ operation C2' ]\n * [ operation C1' ]\n * [ operation C1'r]\n * [ operation C2'r]\n * [ operation C3rr]\n * ```\n */\nexport default class Undo extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ UndoEditing, UndoUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Undo' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { Clipboard } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\nimport { Enter, ShiftEnter } from '@ckeditor/ckeditor5-enter/dist/index.js';\nimport { SelectAll } from '@ckeditor/ckeditor5-select-all/dist/index.js';\nimport { Typing } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { Undo } from '@ckeditor/ckeditor5-undo/dist/index.js';\nimport { AccessibilityHelp } from '@ckeditor/ckeditor5-ui/dist/index.js';\n\n/**\n * A plugin including all essential editing features. It represents a set of features that enables similar functionalities\n * to a `<textarea>` element.\n *\n * It includes:\n *\n * * {@link module:clipboard/clipboard~Clipboard},\n * * {@link module:enter/enter~Enter},\n * * {@link module:select-all/selectall~SelectAll},\n * * {@link module:enter/shiftenter~ShiftEnter},\n * * {@link module:typing/typing~Typing},\n * * {@link module:undo/undo~Undo}.\n *\n * This plugin set does not define any block-level containers (such as {@link module:paragraph/paragraph~Paragraph}).\n * If your editor is supposed to handle block content, make sure to include it.\n */ class Essentials extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            AccessibilityHelp,\n            Clipboard,\n            Enter,\n            SelectAll,\n            ShiftEnter,\n            Typing,\n            Undo\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Essentials';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { Essentials };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module essentials/essentials\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport { Clipboard } from 'ckeditor5/src/clipboard.js';\nimport { Enter, ShiftEnter } from 'ckeditor5/src/enter.js';\nimport { SelectAll } from 'ckeditor5/src/select-all.js';\nimport { Typing } from 'ckeditor5/src/typing.js';\nimport { Undo } from 'ckeditor5/src/undo.js';\nimport { AccessibilityHelp } from 'ckeditor5/src/ui.js';\n\n/**\n * A plugin including all essential editing features. It represents a set of features that enables similar functionalities\n * to a `<textarea>` element.\n *\n * It includes:\n *\n * * {@link module:clipboard/clipboard~Clipboard},\n * * {@link module:enter/enter~Enter},\n * * {@link module:select-all/selectall~SelectAll},\n * * {@link module:enter/shiftenter~ShiftEnter},\n * * {@link module:typing/typing~Typing},\n * * {@link module:undo/undo~Undo}.\n *\n * This plugin set does not define any block-level containers (such as {@link module:paragraph/paragraph~Paragraph}).\n * If your editor is supposed to handle block content, make sure to include it.\n */\nexport default class Essentials extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ AccessibilityHelp, Clipboard, Enter, SelectAll, ShiftEnter, Typing, Undo ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Essentials' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { first } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { ButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\n\n/**\n * The paragraph command.\n */ class ParagraphCommand extends Command {\n    constructor(editor){\n        super(editor);\n        // Since this command may pass selection in execution block, it should be checked directly.\n        this._isEnabledBasedOnSelection = false;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const document = model.document;\n        const block = first(document.selection.getSelectedBlocks());\n        this.value = !!block && block.is('element', 'paragraph');\n        this.isEnabled = !!block && checkCanBecomeParagraph(block, model.schema);\n    }\n    /**\n\t * Executes the command. All the blocks (see {@link module:engine/model/schema~Schema}) in the selection\n\t * will be turned to paragraphs.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.selection The selection that the command should be applied to. By default,\n\t * if not provided, the command is applied to the {@link module:engine/model/document~Document#selection}.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const document = model.document;\n        const selection = options.selection || document.selection;\n        // Don't execute command if selection is in non-editable place.\n        if (!model.canEditAt(selection)) {\n            return;\n        }\n        model.change((writer)=>{\n            const blocks = selection.getSelectedBlocks();\n            for (const block of blocks){\n                if (!block.is('element', 'paragraph') && checkCanBecomeParagraph(block, model.schema)) {\n                    writer.rename(block, 'paragraph');\n                }\n            }\n        });\n    }\n}\n/**\n * Checks whether the given block can be replaced by a paragraph.\n *\n * @param block A block to be tested.\n * @param schema The schema of the document.\n */ function checkCanBecomeParagraph(block, schema) {\n    return schema.checkChild(block.parent, 'paragraph') && !schema.isObject(block);\n}\n\n/**\n * The insert paragraph command. It inserts a new paragraph at a specific\n * {@link module:engine/model/position~Position document position}.\n *\n * ```ts\n * // Insert a new paragraph before an element in the document.\n * editor.execute( 'insertParagraph', {\n *   position: editor.model.createPositionBefore( element )\n * } );\n * ```\n *\n * If a paragraph is disallowed in the context of the specific position, the command\n * will attempt to split position ancestors to find a place where it is possible\n * to insert a paragraph.\n *\n * **Note**: This command moves the selection to the inserted paragraph.\n */ class InsertParagraphCommand extends Command {\n    constructor(editor){\n        super(editor);\n        // Since this command passes position in execution block instead of selection, it should be checked directly.\n        this._isEnabledBasedOnSelection = false;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.position The model position at which the new paragraph will be inserted.\n\t * @param options.attributes Attributes keys and values to set on a inserted paragraph.\n\t * @fires execute\n\t */ execute(options) {\n        const model = this.editor.model;\n        const attributes = options.attributes;\n        let position = options.position;\n        // Don't execute command if position is in non-editable place.\n        if (!model.canEditAt(position)) {\n            return;\n        }\n        model.change((writer)=>{\n            position = this._findPositionToInsertParagraph(position, writer);\n            if (!position) {\n                return;\n            }\n            const paragraph = writer.createElement('paragraph');\n            if (attributes) {\n                model.schema.setAllowedAttributes(paragraph, attributes, writer);\n            }\n            model.insertContent(paragraph, position);\n            writer.setSelection(paragraph, 'in');\n        });\n    }\n    /**\n\t * Returns the best position to insert a new paragraph.\n\t */ _findPositionToInsertParagraph(position, writer) {\n        const model = this.editor.model;\n        if (model.schema.checkChild(position, 'paragraph')) {\n            return position;\n        }\n        const allowedParent = model.schema.findAllowedParent(position, 'paragraph');\n        // It could be there's no ancestor limit that would allow paragraph.\n        // In theory, \"paragraph\" could be disallowed even in the \"$root\".\n        if (!allowedParent) {\n            return null;\n        }\n        const positionParent = position.parent;\n        const isTextAllowed = model.schema.checkChild(positionParent, '$text');\n        // At empty $block or at the end of $block.\n        // <paragraph>[]</paragraph> ---> <paragraph></paragraph><paragraph>[]</paragraph>\n        // <paragraph>foo[]</paragraph> ---> <paragraph>foo</paragraph><paragraph>[]</paragraph>\n        if (positionParent.isEmpty || isTextAllowed && position.isAtEnd) {\n            return model.createPositionAfter(positionParent);\n        }\n        // At the start of $block with text.\n        // <paragraph>[]foo</paragraph> ---> <paragraph>[]</paragraph><paragraph>foo</paragraph>\n        if (!positionParent.isEmpty && isTextAllowed && position.isAtStart) {\n            return model.createPositionBefore(positionParent);\n        }\n        return writer.split(position, allowedParent).position;\n    }\n}\n\n/**\n * The paragraph feature for the editor.\n *\n * It introduces the `<paragraph>` element in the model which renders as a `<p>` element in the DOM and data.\n *\n * It also brings two editors commands:\n *\n * * The {@link module:paragraph/paragraphcommand~ParagraphCommand `'paragraph'`} command that converts all\n * blocks in the model selection into paragraphs.\n * * The {@link module:paragraph/insertparagraphcommand~InsertParagraphCommand `'insertParagraph'`} command\n * that inserts a new paragraph at a specified location in the model.\n */ class Paragraph extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Paragraph';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        editor.commands.add('paragraph', new ParagraphCommand(editor));\n        editor.commands.add('insertParagraph', new InsertParagraphCommand(editor));\n        // Schema.\n        model.schema.register('paragraph', {\n            inheritAllFrom: '$block'\n        });\n        editor.conversion.elementToElement({\n            model: 'paragraph',\n            view: 'p'\n        });\n        // Conversion for paragraph-like elements which has not been converted by any plugin.\n        editor.conversion.for('upcast').elementToElement({\n            model: (viewElement, { writer })=>{\n                if (!Paragraph.paragraphLikeElements.has(viewElement.name)) {\n                    return null;\n                }\n                // Do not auto-paragraph empty elements.\n                if (viewElement.isEmpty) {\n                    return null;\n                }\n                return writer.createElement('paragraph');\n            },\n            view: /.+/,\n            converterPriority: 'low'\n        });\n    }\n    /**\n\t * A list of element names which should be treated by the autoparagraphing algorithms as\n\t * paragraph-like. This means that e.g. the following content:\n\t *\n\t * ```html\n\t * <h1>Foo</h1>\n\t * <table>\n\t *   <tr>\n\t *     <td>X</td>\n\t *     <td>\n\t *       <ul>\n\t *         <li>Y</li>\n\t *         <li>Z</li>\n\t *       </ul>\n\t *     </td>\n\t *   </tr>\n\t * </table>\n\t * ```\n\t *\n\t * contains five paragraph-like elements: `<h1>`, two `<td>`s and two `<li>`s.\n\t * Hence, if none of the features is going to convert those elements the above content will be automatically handled\n\t * by the paragraph feature and converted to:\n\t *\n\t * ```html\n\t * <p>Foo</p>\n\t * <p>X</p>\n\t * <p>Y</p>\n\t * <p>Z</p>\n\t * ```\n\t *\n\t * Note: The `<td>` containing two `<li>` elements was ignored as the innermost paragraph-like elements\n\t * have a priority upon conversion.\n\t */ static paragraphLikeElements = new Set([\n        'blockquote',\n        'dd',\n        'div',\n        'dt',\n        'h1',\n        'h2',\n        'h3',\n        'h4',\n        'h5',\n        'h6',\n        'li',\n        'p',\n        'td',\n        'th'\n    ]);\n}\n\n/**\n * This plugin defines the `'paragraph'` button. It can be used together with\n * {@link module:heading/headingbuttonsui~HeadingButtonsUI} to replace the standard heading dropdown.\n *\n * This plugin is not loaded automatically by the {@link module:paragraph/paragraph~Paragraph} plugin. It must\n * be added manually.\n *\n * ```ts\n * ClassicEditor\n *   .create( {\n *     plugins: [ ..., Heading, Paragraph, HeadingButtonsUI, ParagraphButtonUI ]\n *     toolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3' ]\n *   } )\n *   .then( ... )\n *   .catch( ... );\n * ```\n */ class ParagraphButtonUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Paragraph\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.t;\n        editor.ui.componentFactory.add('paragraph', (locale)=>{\n            const view = new ButtonView(locale);\n            const command = editor.commands.get('paragraph');\n            view.label = t('Paragraph');\n            view.icon = icons.paragraph;\n            view.tooltip = true;\n            view.isToggleable = true;\n            view.bind('isEnabled').to(command);\n            view.bind('isOn').to(command, 'value');\n            view.on('execute', ()=>{\n                editor.execute('paragraph');\n            });\n            return view;\n        });\n    }\n}\n\nexport { Paragraph, ParagraphButtonUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paragraph/paragraphcommand\n */\n\nimport { Command, type Editor } from '@ckeditor/ckeditor5-core';\nimport { first } from '@ckeditor/ckeditor5-utils';\n\nimport type { Schema, Selection, DocumentSelection, Element } from '@ckeditor/ckeditor5-engine';\n\n/**\n * The paragraph command.\n */\nexport default class ParagraphCommand extends Command {\n\tpublic constructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// Since this command may pass selection in execution block, it should be checked directly.\n\t\tthis._isEnabledBasedOnSelection = false;\n\t}\n\n\t/**\n\t * The value of the command. Indicates whether the selection start is placed in a paragraph.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tthis.value = !!block && block.is( 'element', 'paragraph' );\n\t\tthis.isEnabled = !!block && checkCanBecomeParagraph( block, model.schema );\n\t}\n\n\t/**\n\t * Executes the command. All the blocks (see {@link module:engine/model/schema~Schema}) in the selection\n\t * will be turned to paragraphs.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.selection The selection that the command should be applied to. By default,\n\t * if not provided, the command is applied to the {@link module:engine/model/document~Document#selection}.\n\t */\n\tpublic override execute( options: {\n\t\tselection?: Selection | DocumentSelection;\n\t} = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst selection = options.selection || document.selection;\n\n\t\t// Don't execute command if selection is in non-editable place.\n\t\tif ( !model.canEditAt( selection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst blocks = selection.getSelectedBlocks();\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tif ( !block.is( 'element', 'paragraph' ) && checkCanBecomeParagraph( block, model.schema ) ) {\n\t\t\t\t\twriter.rename( block, 'paragraph' );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Checks whether the given block can be replaced by a paragraph.\n *\n * @param block A block to be tested.\n * @param schema The schema of the document.\n */\nfunction checkCanBecomeParagraph( block: Element, schema: Schema ): boolean {\n\treturn schema.checkChild( block.parent as Element, 'paragraph' ) && !schema.isObject( block );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paragraph/insertparagraphcommand\n */\n\nimport { Command, type Editor } from '@ckeditor/ckeditor5-core';\nimport type { Element, Position, Writer } from '@ckeditor/ckeditor5-engine';\n\n/**\n * The insert paragraph command. It inserts a new paragraph at a specific\n * {@link module:engine/model/position~Position document position}.\n *\n * ```ts\n * // Insert a new paragraph before an element in the document.\n * editor.execute( 'insertParagraph', {\n *   position: editor.model.createPositionBefore( element )\n * } );\n * ```\n *\n * If a paragraph is disallowed in the context of the specific position, the command\n * will attempt to split position ancestors to find a place where it is possible\n * to insert a paragraph.\n *\n * **Note**: This command moves the selection to the inserted paragraph.\n */\nexport default class InsertParagraphCommand extends Command {\n\tpublic constructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// Since this command passes position in execution block instead of selection, it should be checked directly.\n\t\tthis._isEnabledBasedOnSelection = false;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.position The model position at which the new paragraph will be inserted.\n\t * @param options.attributes Attributes keys and values to set on a inserted paragraph.\n\t * @fires execute\n\t */\n\tpublic override execute( options: {\n\t\tposition: Position;\n\t\tattributes?: Record<string, unknown>;\n\t} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst attributes = options.attributes;\n\n\t\tlet position: Position | null = options.position;\n\n\t\t// Don't execute command if position is in non-editable place.\n\t\tif ( !model.canEditAt( position ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tposition = this._findPositionToInsertParagraph( position!, writer );\n\n\t\t\tif ( !position ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst paragraph = writer.createElement( 'paragraph' );\n\n\t\t\tif ( attributes ) {\n\t\t\t\tmodel.schema.setAllowedAttributes( paragraph, attributes, writer );\n\t\t\t}\n\n\t\t\tmodel.insertContent( paragraph, position );\n\t\t\twriter.setSelection( paragraph, 'in' );\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the best position to insert a new paragraph.\n\t */\n\tprivate _findPositionToInsertParagraph( position: Position, writer: Writer ): Position | null {\n\t\tconst model = this.editor.model;\n\n\t\tif ( model.schema.checkChild( position, 'paragraph' ) ) {\n\t\t\treturn position;\n\t\t}\n\n\t\tconst allowedParent = model.schema.findAllowedParent( position, 'paragraph' );\n\n\t\t// It could be there's no ancestor limit that would allow paragraph.\n\t\t// In theory, \"paragraph\" could be disallowed even in the \"$root\".\n\t\tif ( !allowedParent ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst positionParent = position.parent as Element;\n\t\tconst isTextAllowed = model.schema.checkChild( positionParent, '$text' );\n\n\t\t// At empty $block or at the end of $block.\n\t\t// <paragraph>[]</paragraph> ---> <paragraph></paragraph><paragraph>[]</paragraph>\n\t\t// <paragraph>foo[]</paragraph> ---> <paragraph>foo</paragraph><paragraph>[]</paragraph>\n\t\tif ( positionParent.isEmpty || isTextAllowed && position.isAtEnd ) {\n\t\t\treturn model.createPositionAfter( positionParent );\n\t\t}\n\n\t\t// At the start of $block with text.\n\t\t// <paragraph>[]foo</paragraph> ---> <paragraph>[]</paragraph><paragraph>foo</paragraph>\n\t\tif ( !positionParent.isEmpty && isTextAllowed && position.isAtStart ) {\n\t\t\treturn model.createPositionBefore( positionParent );\n\t\t}\n\n\t\treturn writer.split( position, allowedParent ).position;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paragraph/paragraph\n */\n\nimport ParagraphCommand from './paragraphcommand.js';\nimport InsertParagraphCommand from './insertparagraphcommand.js';\n\nimport { Plugin } from '@ckeditor/ckeditor5-core';\n\n/**\n * The paragraph feature for the editor.\n *\n * It introduces the `<paragraph>` element in the model which renders as a `<p>` element in the DOM and data.\n *\n * It also brings two editors commands:\n *\n * * The {@link module:paragraph/paragraphcommand~ParagraphCommand `'paragraph'`} command that converts all\n * blocks in the model selection into paragraphs.\n * * The {@link module:paragraph/insertparagraphcommand~InsertParagraphCommand `'insertParagraph'`} command\n * that inserts a new paragraph at a specified location in the model.\n */\nexport default class Paragraph extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Paragraph' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\teditor.commands.add( 'paragraph', new ParagraphCommand( editor ) );\n\t\teditor.commands.add( 'insertParagraph', new InsertParagraphCommand( editor ) );\n\n\t\t// Schema.\n\t\tmodel.schema.register( 'paragraph', { inheritAllFrom: '$block' } );\n\n\t\teditor.conversion.elementToElement( { model: 'paragraph', view: 'p' } );\n\n\t\t// Conversion for paragraph-like elements which has not been converted by any plugin.\n\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t\t\tmodel: ( viewElement, { writer } ) => {\n\t\t\t\tif ( !Paragraph.paragraphLikeElements.has( viewElement.name ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// Do not auto-paragraph empty elements.\n\t\t\t\tif ( viewElement.isEmpty ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn writer.createElement( 'paragraph' );\n\t\t\t},\n\t\t\tview: /.+/,\n\t\t\tconverterPriority: 'low'\n\t\t} );\n\t}\n\n\t/**\n\t * A list of element names which should be treated by the autoparagraphing algorithms as\n\t * paragraph-like. This means that e.g. the following content:\n\t *\n\t * ```html\n\t * <h1>Foo</h1>\n\t * <table>\n\t *   <tr>\n\t *     <td>X</td>\n\t *     <td>\n\t *       <ul>\n\t *         <li>Y</li>\n\t *         <li>Z</li>\n\t *       </ul>\n\t *     </td>\n\t *   </tr>\n\t * </table>\n\t * ```\n\t *\n\t * contains five paragraph-like elements: `<h1>`, two `<td>`s and two `<li>`s.\n\t * Hence, if none of the features is going to convert those elements the above content will be automatically handled\n\t * by the paragraph feature and converted to:\n\t *\n\t * ```html\n\t * <p>Foo</p>\n\t * <p>X</p>\n\t * <p>Y</p>\n\t * <p>Z</p>\n\t * ```\n\t *\n\t * Note: The `<td>` containing two `<li>` elements was ignored as the innermost paragraph-like elements\n\t * have a priority upon conversion.\n\t */\n\tpublic static paragraphLikeElements = new Set( [\n\t\t'blockquote',\n\t\t'dd',\n\t\t'div',\n\t\t'dt',\n\t\t'h1',\n\t\t'h2',\n\t\t'h3',\n\t\t'h4',\n\t\t'h5',\n\t\t'h6',\n\t\t'li',\n\t\t'p',\n\t\t'td',\n\t\t'th'\n\t] );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paragraph/paragraphbuttonui\n */\n\nimport { Plugin, icons } from '@ckeditor/ckeditor5-core';\nimport { ButtonView } from '@ckeditor/ckeditor5-ui';\n\nimport Paragraph from './paragraph.js';\nimport type ParagraphCommand from './paragraphcommand.js';\n\n/**\n * This plugin defines the `'paragraph'` button. It can be used together with\n * {@link module:heading/headingbuttonsui~HeadingButtonsUI} to replace the standard heading dropdown.\n *\n * This plugin is not loaded automatically by the {@link module:paragraph/paragraph~Paragraph} plugin. It must\n * be added manually.\n *\n * ```ts\n * ClassicEditor\n *   .create( {\n *     plugins: [ ..., Heading, Paragraph, HeadingButtonsUI, ParagraphButtonUI ]\n *     toolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3' ]\n *   } )\n *   .then( ... )\n *   .catch( ... );\n * ```\n */\nexport default class ParagraphButtonUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Paragraph ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'paragraph', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\t\t\tconst command: ParagraphCommand = editor.commands.get( 'paragraph' )!;\n\n\t\t\tview.label = t( 'Paragraph' );\n\t\t\tview.icon = icons.paragraph;\n\t\t\tview.tooltip = true;\n\t\t\tview.isToggleable = true;\n\t\t\tview.bind( 'isEnabled' ).to( command );\n\t\t\tview.bind( 'isOn' ).to( command, 'value' );\n\n\t\t\tview.on( 'execute', () => {\n\t\t\t\teditor.execute( 'paragraph' );\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { Paragraph } from '@ckeditor/ckeditor5-paragraph/dist/index.js';\nimport { first, priorities, Collection } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { ViewModel, createDropdown, addListToDropdown, MenuBarMenuView, MenuBarMenuListView, MenuBarMenuListItemView, MenuBarMenuListItemButtonView, ButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { DowncastWriter, enablePlaceholder, hidePlaceholder, needsPlaceholder, showPlaceholder } from '@ckeditor/ckeditor5-engine/dist/index.js';\n\n/**\n * The heading command. It is used by the {@link module:heading/heading~Heading heading feature} to apply headings.\n */ class HeadingCommand extends Command {\n    /**\n\t * Set of defined model's elements names that this command support.\n\t * See {@link module:heading/headingconfig~HeadingOption}.\n\t */ modelElements;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor Editor instance.\n\t * @param modelElements Names of the element which this command can apply in the model.\n\t */ constructor(editor, modelElements){\n        super(editor);\n        this.modelElements = modelElements;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const block = first(this.editor.model.document.selection.getSelectedBlocks());\n        this.value = !!block && this.modelElements.includes(block.name) && block.name;\n        this.isEnabled = !!block && this.modelElements.some((heading)=>checkCanBecomeHeading(block, heading, this.editor.model.schema));\n    }\n    /**\n\t * Executes the command. Applies the heading to the selected blocks or, if the first selected\n\t * block is a heading already, turns selected headings (of this level only) to paragraphs.\n\t *\n\t * @param options.value Name of the element which this command will apply in the model.\n\t * @fires execute\n\t */ execute(options) {\n        const model = this.editor.model;\n        const document = model.document;\n        const modelElement = options.value;\n        model.change((writer)=>{\n            const blocks = Array.from(document.selection.getSelectedBlocks()).filter((block)=>{\n                return checkCanBecomeHeading(block, modelElement, model.schema);\n            });\n            for (const block of blocks){\n                if (!block.is('element', modelElement)) {\n                    writer.rename(block, modelElement);\n                }\n            }\n        });\n    }\n}\n/**\n * Checks whether the given block can be replaced by a specific heading.\n *\n * @param block A block to be tested.\n * @param heading Command element name in the model.\n * @param schema The schema of the document.\n */ function checkCanBecomeHeading(block, heading, schema) {\n    return schema.checkChild(block.parent, heading) && !schema.isObject(block);\n}\n\nconst defaultModelElement = 'paragraph';\n/**\n * The headings engine feature. It handles switching between block formats &ndash; headings and paragraph.\n * This class represents the engine part of the heading feature. See also {@link module:heading/heading~Heading}.\n * It introduces `heading1`-`headingN` commands which allow to convert paragraphs into headings.\n */ class HeadingEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'HeadingEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('heading', {\n            options: [\n                {\n                    model: 'paragraph',\n                    title: 'Paragraph',\n                    class: 'ck-heading_paragraph'\n                },\n                {\n                    model: 'heading1',\n                    view: 'h2',\n                    title: 'Heading 1',\n                    class: 'ck-heading_heading1'\n                },\n                {\n                    model: 'heading2',\n                    view: 'h3',\n                    title: 'Heading 2',\n                    class: 'ck-heading_heading2'\n                },\n                {\n                    model: 'heading3',\n                    view: 'h4',\n                    title: 'Heading 3',\n                    class: 'ck-heading_heading3'\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Paragraph\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const options = editor.config.get('heading.options');\n        const modelElements = [];\n        for (const option of options){\n            // Skip paragraph - it is defined in required Paragraph feature.\n            if (option.model === 'paragraph') {\n                continue;\n            }\n            // Schema.\n            editor.model.schema.register(option.model, {\n                inheritAllFrom: '$block'\n            });\n            editor.conversion.elementToElement(option);\n            modelElements.push(option.model);\n        }\n        this._addDefaultH1Conversion(editor);\n        // Register the heading command for this option.\n        editor.commands.add('heading', new HeadingCommand(editor, modelElements));\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        // If the enter command is added to the editor, alter its behavior.\n        // Enter at the end of a heading element should create a paragraph.\n        const editor = this.editor;\n        const enterCommand = editor.commands.get('enter');\n        const options = editor.config.get('heading.options');\n        if (enterCommand) {\n            this.listenTo(enterCommand, 'afterExecute', (evt, data)=>{\n                const positionParent = editor.model.document.selection.getFirstPosition().parent;\n                const isHeading = options.some((option)=>positionParent.is('element', option.model));\n                if (isHeading && !positionParent.is('element', defaultModelElement) && positionParent.childCount === 0) {\n                    data.writer.rename(positionParent, defaultModelElement);\n                }\n            });\n        }\n    }\n    /**\n\t * Adds default conversion for `h1` -> `heading1` with a low priority.\n\t *\n\t * @param editor Editor instance on which to add the `h1` conversion.\n\t */ _addDefaultH1Conversion(editor) {\n        editor.conversion.for('upcast').elementToElement({\n            model: 'heading1',\n            view: 'h1',\n            // With a `low` priority, `paragraph` plugin autoparagraphing mechanism is executed. Make sure\n            // this listener is called before it. If not, `h1` will be transformed into a paragraph.\n            converterPriority: priorities.low + 1\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module heading/utils\n */ /**\n * Returns heading options as defined in `config.heading.options` but processed to consider\n * the editor localization, i.e. to display {@link module:heading/headingconfig~HeadingOption}\n * in the correct language.\n *\n * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t}\n * when the user configuration is defined because the editor does not exist yet.\n */ function getLocalizedOptions(editor) {\n    const t = editor.t;\n    const localizedTitles = {\n        'Paragraph': t('Paragraph'),\n        'Heading 1': t('Heading 1'),\n        'Heading 2': t('Heading 2'),\n        'Heading 3': t('Heading 3'),\n        'Heading 4': t('Heading 4'),\n        'Heading 5': t('Heading 5'),\n        'Heading 6': t('Heading 6')\n    };\n    return editor.config.get('heading.options').map((option)=>{\n        const title = localizedTitles[option.title];\n        if (title && title != option.title) {\n            option.title = title;\n        }\n        return option;\n    });\n}\n\n/**\n * The headings UI feature. It introduces the `headings` dropdown.\n */ class HeadingUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'HeadingUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.t;\n        const options = getLocalizedOptions(editor);\n        const defaultTitle = t('Choose heading');\n        const accessibleLabel = t('Heading');\n        // Register UI component.\n        editor.ui.componentFactory.add('heading', (locale)=>{\n            const titles = {};\n            const itemDefinitions = new Collection();\n            const headingCommand = editor.commands.get('heading');\n            const paragraphCommand = editor.commands.get('paragraph');\n            const commands = [\n                headingCommand\n            ];\n            for (const option of options){\n                const def = {\n                    type: 'button',\n                    model: new ViewModel({\n                        label: option.title,\n                        class: option.class,\n                        role: 'menuitemradio',\n                        withText: true\n                    })\n                };\n                if (option.model === 'paragraph') {\n                    def.model.bind('isOn').to(paragraphCommand, 'value');\n                    def.model.set('commandName', 'paragraph');\n                    commands.push(paragraphCommand);\n                } else {\n                    def.model.bind('isOn').to(headingCommand, 'value', (value)=>value === option.model);\n                    def.model.set({\n                        commandName: 'heading',\n                        commandValue: option.model\n                    });\n                }\n                // Add the option to the collection.\n                itemDefinitions.add(def);\n                titles[option.model] = option.title;\n            }\n            const dropdownView = createDropdown(locale);\n            addListToDropdown(dropdownView, itemDefinitions, {\n                ariaLabel: accessibleLabel,\n                role: 'menu'\n            });\n            dropdownView.buttonView.set({\n                ariaLabel: accessibleLabel,\n                ariaLabelledBy: undefined,\n                isOn: false,\n                withText: true,\n                tooltip: accessibleLabel\n            });\n            dropdownView.extendTemplate({\n                attributes: {\n                    class: [\n                        'ck-heading-dropdown'\n                    ]\n                }\n            });\n            dropdownView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>{\n                return areEnabled.some((isEnabled)=>isEnabled);\n            });\n            dropdownView.buttonView.bind('label').to(headingCommand, 'value', paragraphCommand, 'value', (heading, paragraph)=>{\n                const whichModel = paragraph ? 'paragraph' : heading;\n                if (typeof whichModel === 'boolean') {\n                    return defaultTitle;\n                }\n                // If none of the commands is active, display default title.\n                if (!titles[whichModel]) {\n                    return defaultTitle;\n                }\n                return titles[whichModel];\n            });\n            dropdownView.buttonView.bind('ariaLabel').to(headingCommand, 'value', paragraphCommand, 'value', (heading, paragraph)=>{\n                const whichModel = paragraph ? 'paragraph' : heading;\n                if (typeof whichModel === 'boolean') {\n                    return accessibleLabel;\n                }\n                // If none of the commands is active, display default title.\n                if (!titles[whichModel]) {\n                    return accessibleLabel;\n                }\n                return `${titles[whichModel]}, ${accessibleLabel}`;\n            });\n            // Execute command when an item from the dropdown is selected.\n            this.listenTo(dropdownView, 'execute', (evt)=>{\n                const { commandName, commandValue } = evt.source;\n                editor.execute(commandName, commandValue ? {\n                    value: commandValue\n                } : undefined);\n                editor.editing.view.focus();\n            });\n            return dropdownView;\n        });\n        editor.ui.componentFactory.add('menuBar:heading', (locale)=>{\n            const menuView = new MenuBarMenuView(locale);\n            const headingCommand = editor.commands.get('heading');\n            const paragraphCommand = editor.commands.get('paragraph');\n            const commands = [\n                headingCommand\n            ];\n            const listView = new MenuBarMenuListView(locale);\n            menuView.set({\n                class: 'ck-heading-dropdown'\n            });\n            listView.set({\n                ariaLabel: t('Heading'),\n                role: 'menu'\n            });\n            menuView.buttonView.set({\n                label: t('Heading')\n            });\n            menuView.panelView.children.add(listView);\n            for (const option of options){\n                const listItemView = new MenuBarMenuListItemView(locale, menuView);\n                const buttonView = new MenuBarMenuListItemButtonView(locale);\n                listItemView.children.add(buttonView);\n                listView.items.add(listItemView);\n                buttonView.set({\n                    isToggleable: true,\n                    label: option.title,\n                    role: 'menuitemradio',\n                    class: option.class\n                });\n                buttonView.delegate('execute').to(menuView);\n                buttonView.on('execute', ()=>{\n                    const commandName = option.model === 'paragraph' ? 'paragraph' : 'heading';\n                    editor.execute(commandName, {\n                        value: option.model\n                    });\n                    editor.editing.view.focus();\n                });\n                if (option.model === 'paragraph') {\n                    buttonView.bind('isOn').to(paragraphCommand, 'value');\n                    commands.push(paragraphCommand);\n                } else {\n                    buttonView.bind('isOn').to(headingCommand, 'value', (value)=>value === option.model);\n                }\n            }\n            menuView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>{\n                return areEnabled.some((isEnabled)=>isEnabled);\n            });\n            return menuView;\n        });\n    }\n}\n\n/**\n * The headings feature.\n *\n * For a detailed overview, check the {@glink features/headings Headings feature} guide\n * and the {@glink api/heading package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:heading/headingediting~HeadingEditing heading editing feature}\n * and {@link module:heading/headingui~HeadingUI heading UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */ class Heading extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            HeadingEditing,\n            HeadingUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Heading';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst defaultIcons = /* #__PURE__ */ (()=>({\n        heading1: icons.heading1,\n        heading2: icons.heading2,\n        heading3: icons.heading3,\n        heading4: icons.heading4,\n        heading5: icons.heading5,\n        heading6: icons.heading6\n    }))();\n/**\n * The `HeadingButtonsUI` plugin defines a set of UI buttons that can be used instead of the\n * standard drop down component.\n *\n * This feature is not enabled by default by the {@link module:heading/heading~Heading} plugin and needs to be\n * installed manually to the editor configuration.\n *\n * Plugin introduces button UI elements, which names are same as `model` property from {@link module:heading/headingconfig~HeadingOption}.\n *\n * ```ts\n * ClassicEditor\n *   .create( {\n *     plugins: [ ..., Heading, Paragraph, HeadingButtonsUI, ParagraphButtonUI ]\n *     heading: {\n *       options: [\n *         { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n *         { model: 'heading1', view: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },\n *         { model: 'heading2', view: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },\n *         { model: 'heading3', view: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }\n *       ]\n *      },\n *      toolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3' ]\n *   } )\n *   .then( ... )\n *   .catch( ... );\n * ```\n *\n * NOTE: The `'paragraph'` button is defined in by the {@link module:paragraph/paragraphbuttonui~ParagraphButtonUI} plugin\n * which needs to be loaded manually as well.\n *\n * It is possible to use custom icons by providing `icon` config option in {@link module:heading/headingconfig~HeadingOption}.\n * For the default configuration standard icons are used.\n */ class HeadingButtonsUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const options = getLocalizedOptions(this.editor);\n        options.filter((item)=>item.model !== 'paragraph').map((item)=>this._createButton(item));\n    }\n    /**\n\t * Creates single button view from provided configuration option.\n\t */ _createButton(option) {\n        const editor = this.editor;\n        editor.ui.componentFactory.add(option.model, (locale)=>{\n            const view = new ButtonView(locale);\n            const command = editor.commands.get('heading');\n            view.label = option.title;\n            view.icon = option.icon || defaultIcons[option.model];\n            view.tooltip = true;\n            view.isToggleable = true;\n            view.bind('isEnabled').to(command);\n            view.bind('isOn').to(command, 'value', (value)=>value == option.model);\n            view.on('execute', ()=>{\n                editor.execute('heading', {\n                    value: option.model\n                });\n                editor.editing.view.focus();\n            });\n            return view;\n        });\n    }\n}\n\n// A list of element names that should be treated by the Title plugin as title-like.\n// This means that an element of a type from this list will be changed to a title element\n// when it is the first element in the root.\nconst titleLikeElements = new Set([\n    'paragraph',\n    'heading1',\n    'heading2',\n    'heading3',\n    'heading4',\n    'heading5',\n    'heading6'\n]);\n/**\n * The Title plugin.\n *\n * It splits the document into `Title` and `Body` sections.\n */ class Title extends Plugin {\n    /**\n\t * A reference to an empty paragraph in the body\n\t * created when there is no element in the body for the placeholder purposes.\n\t */ _bodyPlaceholder = new Map();\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Title';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            'Paragraph'\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        // To use the schema for disabling some features when the selection is inside the title element\n        // it is needed to create the following structure:\n        //\n        // <title>\n        //     <title-content>The title text</title-content>\n        // </title>\n        //\n        // See: https://github.com/ckeditor/ckeditor5/issues/2005.\n        model.schema.register('title', {\n            isBlock: true,\n            allowIn: '$root'\n        });\n        model.schema.register('title-content', {\n            isBlock: true,\n            allowIn: 'title',\n            allowAttributes: [\n                'alignment'\n            ]\n        });\n        model.schema.extend('$text', {\n            allowIn: 'title-content'\n        });\n        // Disallow all attributes in `title-content`.\n        model.schema.addAttributeCheck((context)=>{\n            if (context.endsWith('title-content $text')) {\n                return false;\n            }\n        });\n        // Because `title` is represented by two elements in the model\n        // but only one in the view, it is needed to adjust Mapper.\n        editor.editing.mapper.on('modelToViewPosition', mapModelPositionToView(editor.editing.view));\n        editor.data.mapper.on('modelToViewPosition', mapModelPositionToView(editor.editing.view));\n        // Conversion.\n        editor.conversion.for('downcast').elementToElement({\n            model: 'title-content',\n            view: 'h1'\n        });\n        editor.conversion.for('downcast').add((dispatcher)=>dispatcher.on('insert:title', (evt, data, conversionApi)=>{\n                conversionApi.consumable.consume(data.item, evt.name);\n            }));\n        // Custom converter is used for data v -> m conversion to avoid calling post-fixer when setting data.\n        // See https://github.com/ckeditor/ckeditor5/issues/2036.\n        editor.data.upcastDispatcher.on('element:h1', dataViewModelH1Insertion, {\n            priority: 'high'\n        });\n        editor.data.upcastDispatcher.on('element:h2', dataViewModelH1Insertion, {\n            priority: 'high'\n        });\n        editor.data.upcastDispatcher.on('element:h3', dataViewModelH1Insertion, {\n            priority: 'high'\n        });\n        // Take care about correct `title` element structure.\n        model.document.registerPostFixer((writer)=>this._fixTitleContent(writer));\n        // Create and take care of correct position of a `title` element.\n        model.document.registerPostFixer((writer)=>this._fixTitleElement(writer));\n        // Create element for `Body` placeholder if it is missing.\n        model.document.registerPostFixer((writer)=>this._fixBodyElement(writer));\n        // Prevent from adding extra at the end of the document.\n        model.document.registerPostFixer((writer)=>this._fixExtraParagraph(writer));\n        // Attach `Title` and `Body` placeholders to the empty title and/or content.\n        this._attachPlaceholders();\n        // Attach Tab handling.\n        this._attachTabPressHandling();\n    }\n    /**\n\t * Returns the title of the document. Note that because this plugin does not allow any formatting inside\n\t * the title element, the output of this method will be a plain text, with no HTML tags.\n\t *\n\t * It is not recommended to use this method together with features that insert markers to the\n\t * data output, like comments or track changes features. If such markers start in the title and end in the\n\t * body, the result of this method might be incorrect.\n\t *\n\t * @param options Additional configuration passed to the conversion process.\n\t * See {@link module:engine/controller/datacontroller~DataController#get `DataController#get`}.\n\t * @returns The title of the document.\n\t */ getTitle(options = {}) {\n        const rootName = options.rootName ? options.rootName : undefined;\n        const titleElement = this._getTitleElement(rootName);\n        const titleContentElement = titleElement.getChild(0);\n        return this.editor.data.stringify(titleContentElement, options);\n    }\n    /**\n\t * Returns the body of the document.\n\t *\n\t * Note that it is not recommended to use this method together with features that insert markers to the\n\t * data output, like comments or track changes features. If such markers start in the title and end in the\n\t * body, the result of this method might be incorrect.\n\t *\n\t * @param options Additional configuration passed to the conversion process.\n\t * See {@link module:engine/controller/datacontroller~DataController#get `DataController#get`}.\n\t * @returns The body of the document.\n\t */ getBody(options = {}) {\n        const editor = this.editor;\n        const data = editor.data;\n        const model = editor.model;\n        const rootName = options.rootName ? options.rootName : undefined;\n        const root = editor.model.document.getRoot(rootName);\n        const view = editor.editing.view;\n        const viewWriter = new DowncastWriter(view.document);\n        const rootRange = model.createRangeIn(root);\n        const viewDocumentFragment = viewWriter.createDocumentFragment();\n        // Find all markers that intersects with body.\n        const bodyStartPosition = model.createPositionAfter(root.getChild(0));\n        const bodyRange = model.createRange(bodyStartPosition, model.createPositionAt(root, 'end'));\n        const markers = new Map();\n        for (const marker of model.markers){\n            const intersection = bodyRange.getIntersection(marker.getRange());\n            if (intersection) {\n                markers.set(marker.name, intersection);\n            }\n        }\n        // Convert the entire root to view.\n        data.mapper.clearBindings();\n        data.mapper.bindElements(root, viewDocumentFragment);\n        data.downcastDispatcher.convert(rootRange, markers, viewWriter, options);\n        // Remove title element from view.\n        viewWriter.remove(viewWriter.createRangeOn(viewDocumentFragment.getChild(0)));\n        // view -> data\n        return editor.data.processor.toData(viewDocumentFragment);\n    }\n    /**\n\t * Returns the `title` element when it is in the document. Returns `undefined` otherwise.\n\t */ _getTitleElement(rootName) {\n        const root = this.editor.model.document.getRoot(rootName);\n        for (const child of root.getChildren()){\n            if (isTitle(child)) {\n                return child;\n            }\n        }\n    }\n    /**\n\t * Model post-fixer callback that ensures that `title` has only one `title-content` child.\n\t * All additional children should be moved after the `title` element and renamed to a paragraph.\n\t */ _fixTitleContent(writer) {\n        let changed = false;\n        for (const rootName of this.editor.model.document.getRootNames()){\n            const title = this._getTitleElement(rootName);\n            // If there is no title in the content it will be created by `_fixTitleElement` post-fixer.\n            // If the title has just one element, then it is correct. No fixing.\n            if (!title || title.maxOffset === 1) {\n                continue;\n            }\n            const titleChildren = Array.from(title.getChildren());\n            // Skip first child because it is an allowed element.\n            titleChildren.shift();\n            for (const titleChild of titleChildren){\n                writer.move(writer.createRangeOn(titleChild), title, 'after');\n                writer.rename(titleChild, 'paragraph');\n            }\n            changed = true;\n        }\n        return changed;\n    }\n    /**\n\t * Model post-fixer callback that creates a title element when it is missing,\n\t * takes care of the correct position of it and removes additional title elements.\n\t */ _fixTitleElement(writer) {\n        let changed = false;\n        const model = this.editor.model;\n        for (const modelRoot of this.editor.model.document.getRoots()){\n            const titleElements = Array.from(modelRoot.getChildren()).filter(isTitle);\n            const firstTitleElement = titleElements[0];\n            const firstRootChild = modelRoot.getChild(0);\n            // When title element is at the beginning of the document then try to fix additional title elements (if there are any).\n            if (firstRootChild.is('element', 'title')) {\n                if (titleElements.length > 1) {\n                    fixAdditionalTitleElements(titleElements, writer, model);\n                    changed = true;\n                }\n                continue;\n            }\n            // When there is no title in the document and first element in the document cannot be changed\n            // to the title then create an empty title element at the beginning of the document.\n            if (!firstTitleElement && !titleLikeElements.has(firstRootChild.name)) {\n                const title = writer.createElement('title');\n                writer.insert(title, modelRoot);\n                writer.insertElement('title-content', title);\n                changed = true;\n                continue;\n            }\n            if (titleLikeElements.has(firstRootChild.name)) {\n                // Change the first element in the document to the title if it can be changed (is title-like).\n                changeElementToTitle(firstRootChild, writer, model);\n            } else {\n                // Otherwise, move the first occurrence of the title element to the beginning of the document.\n                writer.move(writer.createRangeOn(firstTitleElement), modelRoot, 0);\n            }\n            fixAdditionalTitleElements(titleElements, writer, model);\n            changed = true;\n        }\n        return changed;\n    }\n    /**\n\t * Model post-fixer callback that adds an empty paragraph at the end of the document\n\t * when it is needed for the placeholder purposes.\n\t */ _fixBodyElement(writer) {\n        let changed = false;\n        for (const rootName of this.editor.model.document.getRootNames()){\n            const modelRoot = this.editor.model.document.getRoot(rootName);\n            if (modelRoot.childCount < 2) {\n                const placeholder = writer.createElement('paragraph');\n                writer.insert(placeholder, modelRoot, 1);\n                this._bodyPlaceholder.set(rootName, placeholder);\n                changed = true;\n            }\n        }\n        return changed;\n    }\n    /**\n\t * Model post-fixer callback that removes a paragraph from the end of the document\n\t * if it was created for the placeholder purposes and is not needed anymore.\n\t */ _fixExtraParagraph(writer) {\n        let changed = false;\n        for (const rootName of this.editor.model.document.getRootNames()){\n            const root = this.editor.model.document.getRoot(rootName);\n            const placeholder = this._bodyPlaceholder.get(rootName);\n            if (shouldRemoveLastParagraph(placeholder, root)) {\n                this._bodyPlaceholder.delete(rootName);\n                writer.remove(placeholder);\n                changed = true;\n            }\n        }\n        return changed;\n    }\n    /**\n\t * Attaches the `Title` and `Body` placeholders to the title and/or content.\n\t */ _attachPlaceholders() {\n        const editor = this.editor;\n        const t = editor.t;\n        const view = editor.editing.view;\n        const sourceElement = editor.sourceElement;\n        const titlePlaceholder = editor.config.get('title.placeholder') || t('Type your title');\n        const bodyPlaceholder = editor.config.get('placeholder') || sourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.getAttribute('placeholder') || t('Type or paste your content here.');\n        // Attach placeholder to the view title element.\n        editor.editing.downcastDispatcher.on('insert:title-content', (evt, data, conversionApi)=>{\n            const element = conversionApi.mapper.toViewElement(data.item);\n            element.placeholder = titlePlaceholder;\n            enablePlaceholder({\n                view,\n                element,\n                keepOnFocus: true\n            });\n        });\n        // Attach placeholder to first element after a title element and remove it if it's not needed anymore.\n        // First element after title can change, so we need to observe all changes keep placeholder in sync.\n        const bodyViewElements = new Map();\n        // This post-fixer runs after the model post-fixer, so we can assume that the second child in view root will always exist.\n        view.document.registerPostFixer((writer)=>{\n            let hasChanged = false;\n            for (const viewRoot of view.document.roots){\n                // `viewRoot` can be empty despite the model post-fixers if the model root was detached.\n                if (viewRoot.isEmpty) {\n                    continue;\n                }\n                // If `viewRoot` is not empty, then we can expect at least two elements in it.\n                const body = viewRoot.getChild(1);\n                const oldBody = bodyViewElements.get(viewRoot.rootName);\n                // If body element has changed we need to disable placeholder on the previous element and enable on the new one.\n                if (body !== oldBody) {\n                    if (oldBody) {\n                        hidePlaceholder(writer, oldBody);\n                        writer.removeAttribute('data-placeholder', oldBody);\n                    }\n                    writer.setAttribute('data-placeholder', bodyPlaceholder, body);\n                    bodyViewElements.set(viewRoot.rootName, body);\n                    hasChanged = true;\n                }\n                // Then we need to display placeholder if it is needed.\n                // See: https://github.com/ckeditor/ckeditor5/issues/8689.\n                if (needsPlaceholder(body, true) && viewRoot.childCount === 2 && body.name === 'p') {\n                    hasChanged = showPlaceholder(writer, body) ? true : hasChanged;\n                } else {\n                    // Or hide if it is not needed.\n                    hasChanged = hidePlaceholder(writer, body) ? true : hasChanged;\n                }\n            }\n            return hasChanged;\n        });\n    }\n    /**\n\t * Creates navigation between the title and body sections using <kbd>Tab</kbd> and <kbd>Shift</kbd>+<kbd>Tab</kbd> keys.\n\t */ _attachTabPressHandling() {\n        const editor = this.editor;\n        const model = editor.model;\n        // Pressing <kbd>Tab</kbd> inside the title should move the caret to the body.\n        editor.keystrokes.set('TAB', (data, cancel)=>{\n            model.change((writer)=>{\n                const selection = model.document.selection;\n                const selectedElements = Array.from(selection.getSelectedBlocks());\n                if (selectedElements.length === 1 && selectedElements[0].is('element', 'title-content')) {\n                    const root = selection.getFirstPosition().root;\n                    const firstBodyElement = root.getChild(1);\n                    writer.setSelection(firstBodyElement, 0);\n                    cancel();\n                }\n            });\n        });\n        // Pressing <kbd>Shift</kbd>+<kbd>Tab</kbd> at the beginning of the body should move the caret to the title.\n        editor.keystrokes.set('SHIFT + TAB', (data, cancel)=>{\n            model.change((writer)=>{\n                const selection = model.document.selection;\n                if (!selection.isCollapsed) {\n                    return;\n                }\n                const selectedElement = first(selection.getSelectedBlocks());\n                const selectionPosition = selection.getFirstPosition();\n                const root = editor.model.document.getRoot(selectionPosition.root.rootName);\n                const title = root.getChild(0);\n                const body = root.getChild(1);\n                if (selectedElement === body && selectionPosition.isAtStart) {\n                    writer.setSelection(title.getChild(0), 0);\n                    cancel();\n                }\n            });\n        });\n    }\n}\n/**\n * A view-to-model converter for the h1 that appears at the beginning of the document (a title element).\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param evt An object containing information about the fired event.\n * @param data An object containing conversion input, a placeholder for conversion output and possibly other values.\n * @param conversionApi Conversion interface to be used by the callback.\n */ function dataViewModelH1Insertion(evt, data, conversionApi) {\n    const modelCursor = data.modelCursor;\n    const viewItem = data.viewItem;\n    if (!modelCursor.isAtStart || !modelCursor.parent.is('element', '$root')) {\n        return;\n    }\n    if (!conversionApi.consumable.consume(viewItem, {\n        name: true\n    })) {\n        return;\n    }\n    const modelWriter = conversionApi.writer;\n    const title = modelWriter.createElement('title');\n    const titleContent = modelWriter.createElement('title-content');\n    modelWriter.append(titleContent, title);\n    modelWriter.insert(title, modelCursor);\n    conversionApi.convertChildren(viewItem, titleContent);\n    conversionApi.updateConversionResult(title, data);\n}\n/**\n * Maps position from the beginning of the model `title` element to the beginning of the view `h1` element.\n *\n * ```html\n * <title>^<title-content>Foo</title-content></title> -> <h1>^Foo</h1>\n * ```\n */ function mapModelPositionToView(editingView) {\n    return (evt, data)=>{\n        const positionParent = data.modelPosition.parent;\n        if (!positionParent.is('element', 'title')) {\n            return;\n        }\n        const modelTitleElement = positionParent.parent;\n        const viewElement = data.mapper.toViewElement(modelTitleElement);\n        data.viewPosition = editingView.createPositionAt(viewElement, 0);\n        evt.stop();\n    };\n}\n/**\n * @returns Returns true when given element is a title. Returns false otherwise.\n */ function isTitle(element) {\n    return element.is('element', 'title');\n}\n/**\n * Changes the given element to the title element.\n */ function changeElementToTitle(element, writer, model) {\n    const title = writer.createElement('title');\n    writer.insert(title, element, 'before');\n    writer.insert(element, title, 0);\n    writer.rename(element, 'title-content');\n    model.schema.removeDisallowedAttributes([\n        element\n    ], writer);\n}\n/**\n * Loops over the list of title elements and fixes additional ones.\n *\n * @returns Returns true when there was any change. Returns false otherwise.\n */ function fixAdditionalTitleElements(titleElements, writer, model) {\n    let hasChanged = false;\n    for (const title of titleElements){\n        if (title.index !== 0) {\n            fixTitleElement(title, writer, model);\n            hasChanged = true;\n        }\n    }\n    return hasChanged;\n}\n/**\n * Changes given title element to a paragraph or removes it when it is empty.\n */ function fixTitleElement(title, writer, model) {\n    const child = title.getChild(0);\n    // Empty title should be removed.\n    // It is created as a result of pasting to the title element.\n    if (child.isEmpty) {\n        writer.remove(title);\n        return;\n    }\n    writer.move(writer.createRangeOn(child), title, 'before');\n    writer.rename(child, 'paragraph');\n    writer.remove(title);\n    model.schema.removeDisallowedAttributes([\n        child\n    ], writer);\n}\n/**\n * Returns true when the last paragraph in the document was created only for the placeholder\n * purpose and it's not needed anymore. Returns false otherwise.\n */ function shouldRemoveLastParagraph(placeholder, root) {\n    if (!placeholder || !placeholder.is('element', 'paragraph') || placeholder.childCount) {\n        return false;\n    }\n    if (root.childCount <= 2 || root.getChild(root.childCount - 1) !== placeholder) {\n        return false;\n    }\n    return true;\n}\n\nexport { Heading, HeadingButtonsUI, HeadingEditing, HeadingUI, Title };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module heading/headingcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\n\nimport type { Element, Schema } from 'ckeditor5/src/engine.js';\n\n/**\n * The heading command. It is used by the {@link module:heading/heading~Heading heading feature} to apply headings.\n */\nexport default class HeadingCommand extends Command {\n\t/**\n\t * If the selection starts in a heading (which {@link #modelElements is supported by this command})\n\t * the value is set to the name of that heading model element.\n\t * It is  set to `false` otherwise.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public value: false | string;\n\n\t/**\n\t * Set of defined model's elements names that this command support.\n\t * See {@link module:heading/headingconfig~HeadingOption}.\n\t */\n\tpublic readonly modelElements: Array<string>;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor Editor instance.\n\t * @param modelElements Names of the element which this command can apply in the model.\n\t */\n\tconstructor( editor: Editor, modelElements: Array<string> ) {\n\t\tsuper( editor );\n\n\t\tthis.modelElements = modelElements;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst block = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\tthis.value = !!block && this.modelElements.includes( block.name ) && block.name;\n\t\tthis.isEnabled = !!block && this.modelElements.some( heading => checkCanBecomeHeading( block, heading, this.editor.model.schema ) );\n\t}\n\n\t/**\n\t * Executes the command. Applies the heading to the selected blocks or, if the first selected\n\t * block is a heading already, turns selected headings (of this level only) to paragraphs.\n\t *\n\t * @param options.value Name of the element which this command will apply in the model.\n\t * @fires execute\n\t */\n\tpublic override execute( options: { value: string } ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst modelElement = options.value;\n\n\t\tmodel.change( writer => {\n\t\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t\t.filter( block => {\n\t\t\t\t\treturn checkCanBecomeHeading( block, modelElement, model.schema );\n\t\t\t\t} );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tif ( !block.is( 'element', modelElement ) ) {\n\t\t\t\t\twriter.rename( block, modelElement );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Checks whether the given block can be replaced by a specific heading.\n *\n * @param block A block to be tested.\n * @param heading Command element name in the model.\n * @param schema The schema of the document.\n */\nfunction checkCanBecomeHeading( block: Element, heading: string, schema: Schema ) {\n\treturn schema.checkChild( block.parent as Element, heading ) && !schema.isObject( block );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module heading/headingediting\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { Paragraph } from 'ckeditor5/src/paragraph.js';\nimport { priorities } from 'ckeditor5/src/utils.js';\nimport type { EnterCommandAfterExecuteEvent } from 'ckeditor5/src/enter.js';\nimport type { HeadingOption } from './headingconfig.js';\n\nimport HeadingCommand from './headingcommand.js';\n\nconst defaultModelElement = 'paragraph';\n\n/**\n * The headings engine feature. It handles switching between block formats &ndash; headings and paragraph.\n * This class represents the engine part of the heading feature. See also {@link module:heading/heading~Heading}.\n * It introduces `heading1`-`headingN` commands which allow to convert paragraphs into headings.\n */\nexport default class HeadingEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'HeadingEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'heading', {\n\t\t\toptions: [\n\t\t\t\t{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n\t\t\t\t{ model: 'heading1', view: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },\n\t\t\t\t{ model: 'heading2', view: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },\n\t\t\t\t{ model: 'heading3', view: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Paragraph ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst options: Array<HeadingOption> = editor.config.get( 'heading.options' )!;\n\n\t\tconst modelElements = [];\n\n\t\tfor ( const option of options ) {\n\t\t\t// Skip paragraph - it is defined in required Paragraph feature.\n\t\t\tif ( option.model === 'paragraph' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Schema.\n\t\t\teditor.model.schema.register( option.model, {\n\t\t\t\tinheritAllFrom: '$block'\n\t\t\t} );\n\n\t\t\teditor.conversion.elementToElement( option );\n\n\t\t\tmodelElements.push( option.model );\n\t\t}\n\n\t\tthis._addDefaultH1Conversion( editor );\n\n\t\t// Register the heading command for this option.\n\t\teditor.commands.add( 'heading', new HeadingCommand( editor, modelElements ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\t// If the enter command is added to the editor, alter its behavior.\n\t\t// Enter at the end of a heading element should create a paragraph.\n\t\tconst editor = this.editor;\n\t\tconst enterCommand = editor.commands.get( 'enter' );\n\t\tconst options: Array<HeadingOption> = editor.config.get( 'heading.options' )!;\n\n\t\tif ( enterCommand ) {\n\t\t\tthis.listenTo<EnterCommandAfterExecuteEvent>( enterCommand, 'afterExecute', ( evt, data ) => {\n\t\t\t\tconst positionParent = editor.model.document.selection.getFirstPosition()!.parent;\n\t\t\t\tconst isHeading = options.some( option => positionParent.is( 'element', option.model ) );\n\n\t\t\t\tif ( isHeading && !positionParent.is( 'element', defaultModelElement ) && positionParent.childCount === 0 ) {\n\t\t\t\t\tdata.writer.rename( positionParent, defaultModelElement );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Adds default conversion for `h1` -> `heading1` with a low priority.\n\t *\n\t * @param editor Editor instance on which to add the `h1` conversion.\n\t */\n\tprivate _addDefaultH1Conversion( editor: Editor ) {\n\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t\t\tmodel: 'heading1',\n\t\t\tview: 'h1',\n\t\t\t// With a `low` priority, `paragraph` plugin autoparagraphing mechanism is executed. Make sure\n\t\t\t// this listener is called before it. If not, `h1` will be transformed into a paragraph.\n\t\t\tconverterPriority: priorities.low + 1\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module heading/utils\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport type { HeadingOption } from './headingconfig.js';\n\n/**\n * Returns heading options as defined in `config.heading.options` but processed to consider\n * the editor localization, i.e. to display {@link module:heading/headingconfig~HeadingOption}\n * in the correct language.\n *\n * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t}\n * when the user configuration is defined because the editor does not exist yet.\n */\nexport function getLocalizedOptions( editor: Editor ): Array<HeadingOption> {\n\tconst t = editor.t;\n\tconst localizedTitles: Record<string, string> = {\n\t\t'Paragraph': t( 'Paragraph' ),\n\t\t'Heading 1': t( 'Heading 1' ),\n\t\t'Heading 2': t( 'Heading 2' ),\n\t\t'Heading 3': t( 'Heading 3' ),\n\t\t'Heading 4': t( 'Heading 4' ),\n\t\t'Heading 5': t( 'Heading 5' ),\n\t\t'Heading 6': t( 'Heading 6' )\n\t};\n\n\treturn editor.config.get( 'heading.options' )!.map( option => {\n\t\tconst title = localizedTitles[ option.title ];\n\n\t\tif ( title && title != option.title ) {\n\t\t\toption.title = title;\n\t\t}\n\n\t\treturn option;\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module heading/headingui\n */\n\nimport { Plugin, type Command } from 'ckeditor5/src/core.js';\nimport {\n\tViewModel,\n\tcreateDropdown,\n\taddListToDropdown,\n\ttype ButtonExecuteEvent,\n\ttype ListDropdownItemDefinition,\n\tMenuBarMenuListItemView,\n\tMenuBarMenuListView,\n\tMenuBarMenuView,\n\tMenuBarMenuListItemButtonView\n} from 'ckeditor5/src/ui.js';\nimport { Collection } from 'ckeditor5/src/utils.js';\nimport type { ParagraphCommand } from 'ckeditor5/src/paragraph.js';\n\nimport { getLocalizedOptions } from './utils.js';\nimport type HeadingCommand from './headingcommand.js';\n\nimport '../theme/heading.css';\n\n/**\n * The headings UI feature. It introduces the `headings` dropdown.\n */\nexport default class HeadingUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'HeadingUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst options = getLocalizedOptions( editor );\n\t\tconst defaultTitle = t( 'Choose heading' );\n\t\tconst accessibleLabel = t( 'Heading' );\n\n\t\t// Register UI component.\n\t\teditor.ui.componentFactory.add( 'heading', locale => {\n\t\t\tconst titles: Record<string, string> = {};\n\t\t\tconst itemDefinitions: Collection<ListDropdownItemDefinition> = new Collection();\n\t\t\tconst headingCommand: HeadingCommand = editor.commands.get( 'heading' )!;\n\t\t\tconst paragraphCommand: ParagraphCommand = editor.commands.get( 'paragraph' )!;\n\t\t\tconst commands: Array<Command> = [ headingCommand ];\n\n\t\t\tfor ( const option of options ) {\n\t\t\t\tconst def: ListDropdownItemDefinition = {\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: new ViewModel( {\n\t\t\t\t\t\tlabel: option.title,\n\t\t\t\t\t\tclass: option.class,\n\t\t\t\t\t\trole: 'menuitemradio',\n\t\t\t\t\t\twithText: true\n\t\t\t\t\t} )\n\t\t\t\t};\n\n\t\t\t\tif ( option.model === 'paragraph' ) {\n\t\t\t\t\tdef.model.bind( 'isOn' ).to( paragraphCommand, 'value' );\n\t\t\t\t\tdef.model.set( 'commandName', 'paragraph' );\n\t\t\t\t\tcommands.push( paragraphCommand );\n\t\t\t\t} else {\n\t\t\t\t\tdef.model.bind( 'isOn' ).to( headingCommand, 'value', value => value === option.model );\n\t\t\t\t\tdef.model.set( {\n\t\t\t\t\t\tcommandName: 'heading',\n\t\t\t\t\t\tcommandValue: option.model\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\t// Add the option to the collection.\n\t\t\t\titemDefinitions.add( def );\n\n\t\t\t\ttitles[ option.model ] = option.title;\n\t\t\t}\n\n\t\t\tconst dropdownView = createDropdown( locale );\n\t\t\taddListToDropdown( dropdownView, itemDefinitions, {\n\t\t\t\tariaLabel: accessibleLabel,\n\t\t\t\trole: 'menu'\n\t\t\t} );\n\n\t\t\tdropdownView.buttonView.set( {\n\t\t\t\tariaLabel: accessibleLabel,\n\t\t\t\tariaLabelledBy: undefined,\n\t\t\t\tisOn: false,\n\t\t\t\twithText: true,\n\t\t\t\ttooltip: accessibleLabel\n\t\t\t} );\n\n\t\t\tdropdownView.extendTemplate( {\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: [\n\t\t\t\t\t\t'ck-heading-dropdown'\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tdropdownView.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => {\n\t\t\t\treturn areEnabled.some( isEnabled => isEnabled );\n\t\t\t} );\n\n\t\t\tdropdownView.buttonView.bind( 'label' ).to( headingCommand, 'value', paragraphCommand, 'value', ( heading, paragraph ) => {\n\t\t\t\tconst whichModel = paragraph ? 'paragraph' : heading;\n\n\t\t\t\tif ( typeof whichModel === 'boolean' ) {\n\t\t\t\t\treturn defaultTitle;\n\t\t\t\t}\n\n\t\t\t\t// If none of the commands is active, display default title.\n\t\t\t\tif ( !titles[ whichModel ] ) {\n\t\t\t\t\treturn defaultTitle;\n\t\t\t\t}\n\n\t\t\t\treturn titles[ whichModel ];\n\t\t\t} );\n\n\t\t\tdropdownView.buttonView.bind( 'ariaLabel' ).to( headingCommand, 'value', paragraphCommand, 'value', ( heading, paragraph ) => {\n\t\t\t\tconst whichModel = paragraph ? 'paragraph' : heading;\n\n\t\t\t\tif ( typeof whichModel === 'boolean' ) {\n\t\t\t\t\treturn accessibleLabel;\n\t\t\t\t}\n\n\t\t\t\t// If none of the commands is active, display default title.\n\t\t\t\tif ( !titles[ whichModel ] ) {\n\t\t\t\t\treturn accessibleLabel;\n\t\t\t\t}\n\n\t\t\t\treturn `${ titles[ whichModel ] }, ${ accessibleLabel }`;\n\t\t\t} );\n\n\t\t\t// Execute command when an item from the dropdown is selected.\n\t\t\tthis.listenTo<ButtonExecuteEvent>( dropdownView, 'execute', evt => {\n\t\t\t\tconst { commandName, commandValue } = evt.source as any;\n\t\t\t\teditor.execute( commandName, commandValue ? { value: commandValue } : undefined );\n\t\t\t\teditor.editing.view.focus();\n\t\t\t} );\n\n\t\t\treturn dropdownView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:heading', locale => {\n\t\t\tconst menuView = new MenuBarMenuView( locale );\n\t\t\tconst headingCommand: HeadingCommand = editor.commands.get( 'heading' )!;\n\t\t\tconst paragraphCommand: ParagraphCommand = editor.commands.get( 'paragraph' )!;\n\t\t\tconst commands: Array<Command> = [ headingCommand ];\n\t\t\tconst listView = new MenuBarMenuListView( locale );\n\n\t\t\tmenuView.set( {\n\t\t\t\tclass: 'ck-heading-dropdown'\n\t\t\t} );\n\n\t\t\tlistView.set( {\n\t\t\t\tariaLabel: t( 'Heading' ),\n\t\t\t\trole: 'menu'\n\t\t\t} );\n\n\t\t\tmenuView.buttonView.set( {\n\t\t\t\tlabel: t( 'Heading' )\n\t\t\t} );\n\n\t\t\tmenuView.panelView.children.add( listView );\n\n\t\t\tfor ( const option of options ) {\n\t\t\t\tconst listItemView = new MenuBarMenuListItemView( locale, menuView );\n\t\t\t\tconst buttonView = new MenuBarMenuListItemButtonView( locale );\n\n\t\t\t\tlistItemView.children.add( buttonView );\n\t\t\t\tlistView.items.add( listItemView );\n\n\t\t\t\tbuttonView.set( {\n\t\t\t\t\tisToggleable: true,\n\t\t\t\t\tlabel: option.title,\n\t\t\t\t\trole: 'menuitemradio',\n\t\t\t\t\tclass: option.class\n\t\t\t\t} );\n\n\t\t\t\tbuttonView.delegate( 'execute' ).to( menuView );\n\n\t\t\t\tbuttonView.on<ButtonExecuteEvent>( 'execute', () => {\n\t\t\t\t\tconst commandName = option.model === 'paragraph' ? 'paragraph' : 'heading';\n\n\t\t\t\t\teditor.execute( commandName, { value: option.model } );\n\t\t\t\t\teditor.editing.view.focus();\n\t\t\t\t} );\n\n\t\t\t\tif ( option.model === 'paragraph' ) {\n\t\t\t\t\tbuttonView.bind( 'isOn' ).to( paragraphCommand, 'value' );\n\t\t\t\t\tcommands.push( paragraphCommand );\n\t\t\t\t} else {\n\t\t\t\t\tbuttonView.bind( 'isOn' ).to( headingCommand, 'value', value => value === option.model );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmenuView.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => {\n\t\t\t\treturn areEnabled.some( isEnabled => isEnabled );\n\t\t\t} );\n\n\t\t\treturn menuView;\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module heading/heading\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport HeadingEditing from './headingediting.js';\nimport HeadingUI from './headingui.js';\n\nimport '../theme/heading.css';\n\n/**\n * The headings feature.\n *\n * For a detailed overview, check the {@glink features/headings Headings feature} guide\n * and the {@glink api/heading package page}.\n *\n * This is a \"glue\" plugin which loads the {@link module:heading/headingediting~HeadingEditing heading editing feature}\n * and {@link module:heading/headingui~HeadingUI heading UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Heading extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ HeadingEditing, HeadingUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Heading' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module heading/headingbuttonsui\n */\n\nimport { icons, Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView } from 'ckeditor5/src/ui.js';\n\nimport { getLocalizedOptions } from './utils.js';\nimport type { HeadingOption } from './headingconfig.js';\nimport type HeadingCommand from './headingcommand.js';\n\nconst defaultIcons: Record<string, string> = /* #__PURE__ */ ( () => ( {\n\theading1: icons.heading1,\n\theading2: icons.heading2,\n\theading3: icons.heading3,\n\theading4: icons.heading4,\n\theading5: icons.heading5,\n\theading6: icons.heading6\n} ) )();\n\n/**\n * The `HeadingButtonsUI` plugin defines a set of UI buttons that can be used instead of the\n * standard drop down component.\n *\n * This feature is not enabled by default by the {@link module:heading/heading~Heading} plugin and needs to be\n * installed manually to the editor configuration.\n *\n * Plugin introduces button UI elements, which names are same as `model` property from {@link module:heading/headingconfig~HeadingOption}.\n *\n * ```ts\n * ClassicEditor\n *   .create( {\n *     plugins: [ ..., Heading, Paragraph, HeadingButtonsUI, ParagraphButtonUI ]\n *     heading: {\n *       options: [\n *         { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },\n *         { model: 'heading1', view: 'h2', title: 'Heading 1', class: 'ck-heading_heading1' },\n *         { model: 'heading2', view: 'h3', title: 'Heading 2', class: 'ck-heading_heading2' },\n *         { model: 'heading3', view: 'h4', title: 'Heading 3', class: 'ck-heading_heading3' }\n *       ]\n *      },\n *      toolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3' ]\n *   } )\n *   .then( ... )\n *   .catch( ... );\n * ```\n *\n * NOTE: The `'paragraph'` button is defined in by the {@link module:paragraph/paragraphbuttonui~ParagraphButtonUI} plugin\n * which needs to be loaded manually as well.\n *\n * It is possible to use custom icons by providing `icon` config option in {@link module:heading/headingconfig~HeadingOption}.\n * For the default configuration standard icons are used.\n */\nexport default class HeadingButtonsUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst options = getLocalizedOptions( this.editor );\n\n\t\toptions\n\t\t\t.filter( item => item.model !== 'paragraph' )\n\t\t\t.map( item => this._createButton( item ) );\n\t}\n\n\t/**\n\t * Creates single button view from provided configuration option.\n\t */\n\tprivate _createButton( option: HeadingOption ) {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( option.model, locale => {\n\t\t\tconst view = new ButtonView( locale );\n\t\t\tconst command: HeadingCommand = editor.commands.get( 'heading' )!;\n\n\t\t\tview.label = option.title;\n\t\t\tview.icon = option.icon || defaultIcons[ option.model ];\n\t\t\tview.tooltip = true;\n\t\t\tview.isToggleable = true;\n\t\t\tview.bind( 'isEnabled' ).to( command );\n\t\t\tview.bind( 'isOn' ).to( command, 'value', value => value == option.model );\n\n\t\t\tview.on( 'execute', () => {\n\t\t\t\teditor.execute( 'heading', { value: option.model } );\n\t\t\t\teditor.editing.view.focus();\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module heading/title\n */\n\nimport { Plugin, type Editor, type ElementApi } from 'ckeditor5/src/core.js';\nimport { first, type GetCallback } from 'ckeditor5/src/utils.js';\nimport {\n\tDowncastWriter,\n\tenablePlaceholder,\n\thidePlaceholder,\n\tneedsPlaceholder,\n\tshowPlaceholder,\n\ttype DowncastInsertEvent,\n\ttype Element,\n\ttype MapperModelToViewPositionEvent,\n\ttype Model,\n\ttype RootElement,\n\ttype UpcastConversionApi,\n\ttype UpcastConversionData,\n\ttype UpcastElementEvent,\n\ttype EditingView,\n\ttype ViewElement,\n\ttype Writer,\n\ttype PlaceholderableElement\n} from 'ckeditor5/src/engine.js';\n\n// A list of element names that should be treated by the Title plugin as title-like.\n// This means that an element of a type from this list will be changed to a title element\n// when it is the first element in the root.\nconst titleLikeElements = new Set( [ 'paragraph', 'heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6' ] );\n\n/**\n * The Title plugin.\n *\n * It splits the document into `Title` and `Body` sections.\n */\nexport default class Title extends Plugin {\n\t/**\n\t * A reference to an empty paragraph in the body\n\t * created when there is no element in the body for the placeholder purposes.\n\t */\n\tprivate _bodyPlaceholder = new Map<string, Element>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Title' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ 'Paragraph' ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\t// To use the schema for disabling some features when the selection is inside the title element\n\t\t// it is needed to create the following structure:\n\t\t//\n\t\t// <title>\n\t\t//     <title-content>The title text</title-content>\n\t\t// </title>\n\t\t//\n\t\t// See: https://github.com/ckeditor/ckeditor5/issues/2005.\n\t\tmodel.schema.register( 'title', { isBlock: true, allowIn: '$root' } );\n\t\tmodel.schema.register( 'title-content', { isBlock: true, allowIn: 'title', allowAttributes: [ 'alignment' ] } );\n\t\tmodel.schema.extend( '$text', { allowIn: 'title-content' } );\n\n\t\t// Disallow all attributes in `title-content`.\n\t\tmodel.schema.addAttributeCheck( context => {\n\t\t\tif ( context.endsWith( 'title-content $text' ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} );\n\n\t\t// Because `title` is represented by two elements in the model\n\t\t// but only one in the view, it is needed to adjust Mapper.\n\t\teditor.editing.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', mapModelPositionToView( editor.editing.view ) );\n\t\teditor.data.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', mapModelPositionToView( editor.editing.view ) );\n\n\t\t// Conversion.\n\t\teditor.conversion.for( 'downcast' ).elementToElement( { model: 'title-content', view: 'h1' } );\n\t\teditor.conversion.for( 'downcast' ).add( dispatcher => dispatcher.on<DowncastInsertEvent>(\n\t\t\t'insert:title',\n\t\t\t( evt, data, conversionApi ) => {\n\t\t\t\tconversionApi.consumable.consume( data.item, evt.name );\n\t\t\t}\n\t\t) );\n\n\t\t// Custom converter is used for data v -> m conversion to avoid calling post-fixer when setting data.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/2036.\n\t\teditor.data.upcastDispatcher.on<UpcastElementEvent>( 'element:h1', dataViewModelH1Insertion, { priority: 'high' } );\n\t\teditor.data.upcastDispatcher.on<UpcastElementEvent>( 'element:h2', dataViewModelH1Insertion, { priority: 'high' } );\n\t\teditor.data.upcastDispatcher.on<UpcastElementEvent>( 'element:h3', dataViewModelH1Insertion, { priority: 'high' } );\n\n\t\t// Take care about correct `title` element structure.\n\t\tmodel.document.registerPostFixer( writer => this._fixTitleContent( writer ) );\n\n\t\t// Create and take care of correct position of a `title` element.\n\t\tmodel.document.registerPostFixer( writer => this._fixTitleElement( writer ) );\n\n\t\t// Create element for `Body` placeholder if it is missing.\n\t\tmodel.document.registerPostFixer( writer => this._fixBodyElement( writer ) );\n\n\t\t// Prevent from adding extra at the end of the document.\n\t\tmodel.document.registerPostFixer( writer => this._fixExtraParagraph( writer ) );\n\n\t\t// Attach `Title` and `Body` placeholders to the empty title and/or content.\n\t\tthis._attachPlaceholders();\n\n\t\t// Attach Tab handling.\n\t\tthis._attachTabPressHandling();\n\t}\n\n\t/**\n\t * Returns the title of the document. Note that because this plugin does not allow any formatting inside\n\t * the title element, the output of this method will be a plain text, with no HTML tags.\n\t *\n\t * It is not recommended to use this method together with features that insert markers to the\n\t * data output, like comments or track changes features. If such markers start in the title and end in the\n\t * body, the result of this method might be incorrect.\n\t *\n\t * @param options Additional configuration passed to the conversion process.\n\t * See {@link module:engine/controller/datacontroller~DataController#get `DataController#get`}.\n\t * @returns The title of the document.\n\t */\n\tpublic getTitle( options: Record<string, unknown> = {} ): string {\n\t\tconst rootName = options.rootName ? options.rootName as string : undefined;\n\t\tconst titleElement = this._getTitleElement( rootName );\n\t\tconst titleContentElement = titleElement!.getChild( 0 ) as Element;\n\n\t\treturn this.editor.data.stringify( titleContentElement, options );\n\t}\n\n\t/**\n\t * Returns the body of the document.\n\t *\n\t * Note that it is not recommended to use this method together with features that insert markers to the\n\t * data output, like comments or track changes features. If such markers start in the title and end in the\n\t * body, the result of this method might be incorrect.\n\t *\n\t * @param options Additional configuration passed to the conversion process.\n\t * See {@link module:engine/controller/datacontroller~DataController#get `DataController#get`}.\n\t * @returns The body of the document.\n\t */\n\tpublic getBody( options: Record<string, unknown> = {} ): string {\n\t\tconst editor = this.editor;\n\t\tconst data = editor.data;\n\t\tconst model = editor.model;\n\t\tconst rootName = options.rootName ? options.rootName as string : undefined;\n\t\tconst root = editor.model.document.getRoot( rootName )!;\n\t\tconst view = editor.editing.view;\n\t\tconst viewWriter = new DowncastWriter( view.document );\n\n\t\tconst rootRange = model.createRangeIn( root );\n\t\tconst viewDocumentFragment = viewWriter.createDocumentFragment();\n\n\t\t// Find all markers that intersects with body.\n\t\tconst bodyStartPosition = model.createPositionAfter( root.getChild( 0 )! );\n\t\tconst bodyRange = model.createRange( bodyStartPosition, model.createPositionAt( root, 'end' ) );\n\n\t\tconst markers = new Map();\n\n\t\tfor ( const marker of model.markers ) {\n\t\t\tconst intersection = bodyRange.getIntersection( marker.getRange() );\n\n\t\t\tif ( intersection ) {\n\t\t\t\tmarkers.set( marker.name, intersection );\n\t\t\t}\n\t\t}\n\n\t\t// Convert the entire root to view.\n\t\tdata.mapper.clearBindings();\n\t\tdata.mapper.bindElements( root, viewDocumentFragment );\n\t\tdata.downcastDispatcher.convert( rootRange, markers, viewWriter, options );\n\n\t\t// Remove title element from view.\n\t\tviewWriter.remove( viewWriter.createRangeOn( viewDocumentFragment.getChild( 0 ) ) );\n\n\t\t// view -> data\n\t\treturn editor.data.processor.toData( viewDocumentFragment );\n\t}\n\n\t/**\n\t * Returns the `title` element when it is in the document. Returns `undefined` otherwise.\n\t */\n\tprivate _getTitleElement( rootName?: string ): Element | undefined {\n\t\tconst root = this.editor.model.document.getRoot( rootName )!;\n\n\t\tfor ( const child of root.getChildren() as IterableIterator<Element> ) {\n\t\t\tif ( isTitle( child ) ) {\n\t\t\t\treturn child;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Model post-fixer callback that ensures that `title` has only one `title-content` child.\n\t * All additional children should be moved after the `title` element and renamed to a paragraph.\n\t */\n\tprivate _fixTitleContent( writer: Writer ) {\n\t\tlet changed = false;\n\n\t\tfor ( const rootName of this.editor.model.document.getRootNames() ) {\n\t\t\tconst title = this._getTitleElement( rootName );\n\n\t\t\t// If there is no title in the content it will be created by `_fixTitleElement` post-fixer.\n\t\t\t// If the title has just one element, then it is correct. No fixing.\n\t\t\tif ( !title || title.maxOffset === 1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst titleChildren = Array.from( title.getChildren() ) as Array<Element>;\n\n\t\t\t// Skip first child because it is an allowed element.\n\t\t\ttitleChildren.shift();\n\n\t\t\tfor ( const titleChild of titleChildren ) {\n\t\t\t\twriter.move( writer.createRangeOn( titleChild ), title, 'after' );\n\t\t\t\twriter.rename( titleChild, 'paragraph' );\n\t\t\t}\n\n\t\t\tchanged = true;\n\t\t}\n\n\t\treturn changed;\n\t}\n\n\t/**\n\t * Model post-fixer callback that creates a title element when it is missing,\n\t * takes care of the correct position of it and removes additional title elements.\n\t */\n\tprivate _fixTitleElement( writer: Writer ) {\n\t\tlet changed = false;\n\t\tconst model = this.editor.model;\n\n\t\tfor ( const modelRoot of this.editor.model.document.getRoots() ) {\n\t\t\tconst titleElements = Array.from( modelRoot.getChildren() as IterableIterator<Element> ).filter( isTitle );\n\t\t\tconst firstTitleElement = titleElements[ 0 ];\n\t\t\tconst firstRootChild = modelRoot.getChild( 0 ) as Element;\n\n\t\t\t// When title element is at the beginning of the document then try to fix additional title elements (if there are any).\n\t\t\tif ( firstRootChild.is( 'element', 'title' ) ) {\n\t\t\t\tif ( titleElements.length > 1 ) {\n\t\t\t\t\tfixAdditionalTitleElements( titleElements, writer, model );\n\n\t\t\t\t\tchanged = true;\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// When there is no title in the document and first element in the document cannot be changed\n\t\t\t// to the title then create an empty title element at the beginning of the document.\n\t\t\tif ( !firstTitleElement && !titleLikeElements.has( firstRootChild.name ) ) {\n\t\t\t\tconst title = writer.createElement( 'title' );\n\n\t\t\t\twriter.insert( title, modelRoot );\n\t\t\t\twriter.insertElement( 'title-content', title );\n\n\t\t\t\tchanged = true;\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( titleLikeElements.has( firstRootChild.name ) ) {\n\t\t\t\t// Change the first element in the document to the title if it can be changed (is title-like).\n\t\t\t\tchangeElementToTitle( firstRootChild, writer, model );\n\t\t\t} else {\n\t\t\t\t// Otherwise, move the first occurrence of the title element to the beginning of the document.\n\t\t\t\twriter.move( writer.createRangeOn( firstTitleElement ), modelRoot, 0 );\n\t\t\t}\n\n\t\t\tfixAdditionalTitleElements( titleElements, writer, model );\n\n\t\t\tchanged = true;\n\t\t}\n\n\t\treturn changed;\n\t}\n\n\t/**\n\t * Model post-fixer callback that adds an empty paragraph at the end of the document\n\t * when it is needed for the placeholder purposes.\n\t */\n\tprivate _fixBodyElement( writer: Writer ) {\n\t\tlet changed = false;\n\n\t\tfor ( const rootName of this.editor.model.document.getRootNames() ) {\n\t\t\tconst modelRoot = this.editor.model.document.getRoot( rootName )!;\n\n\t\t\tif ( modelRoot.childCount < 2 ) {\n\t\t\t\tconst placeholder = writer.createElement( 'paragraph' );\n\n\t\t\t\twriter.insert( placeholder, modelRoot, 1 );\n\t\t\t\tthis._bodyPlaceholder.set( rootName, placeholder );\n\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t}\n\n\t/**\n\t * Model post-fixer callback that removes a paragraph from the end of the document\n\t * if it was created for the placeholder purposes and is not needed anymore.\n\t */\n\tprivate _fixExtraParagraph( writer: Writer ) {\n\t\tlet changed = false;\n\n\t\tfor ( const rootName of this.editor.model.document.getRootNames() ) {\n\t\t\tconst root = this.editor.model.document.getRoot( rootName )!;\n\t\t\tconst placeholder = this._bodyPlaceholder.get( rootName )!;\n\n\t\t\tif ( shouldRemoveLastParagraph( placeholder, root ) ) {\n\t\t\t\tthis._bodyPlaceholder.delete( rootName );\n\t\t\t\twriter.remove( placeholder );\n\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\treturn changed;\n\t}\n\n\t/**\n\t * Attaches the `Title` and `Body` placeholders to the title and/or content.\n\t */\n\tprivate _attachPlaceholders() {\n\t\tconst editor: Editor & Partial<ElementApi> = this.editor;\n\t\tconst t = editor.t;\n\t\tconst view = editor.editing.view;\n\t\tconst sourceElement = editor.sourceElement;\n\n\t\tconst titlePlaceholder = editor.config.get( 'title.placeholder' ) || t( 'Type your title' );\n\t\tconst bodyPlaceholder = editor.config.get( 'placeholder' ) ||\n\t\t\tsourceElement && sourceElement.tagName.toLowerCase() === 'textarea' && sourceElement.getAttribute( 'placeholder' ) ||\n\t\t\tt( 'Type or paste your content here.' );\n\n\t\t// Attach placeholder to the view title element.\n\t\teditor.editing.downcastDispatcher.on<DowncastInsertEvent<Element>>( 'insert:title-content', ( evt, data, conversionApi ) => {\n\t\t\tconst element: PlaceholderableElement = conversionApi.mapper.toViewElement( data.item )!;\n\n\t\t\telement.placeholder = titlePlaceholder;\n\n\t\t\tenablePlaceholder( {\n\t\t\t\tview,\n\t\t\t\telement,\n\t\t\t\tkeepOnFocus: true\n\t\t\t} );\n\t\t} );\n\n\t\t// Attach placeholder to first element after a title element and remove it if it's not needed anymore.\n\t\t// First element after title can change, so we need to observe all changes keep placeholder in sync.\n\t\tconst bodyViewElements = new Map<string, ViewElement>();\n\n\t\t// This post-fixer runs after the model post-fixer, so we can assume that the second child in view root will always exist.\n\t\tview.document.registerPostFixer( writer => {\n\t\t\tlet hasChanged = false;\n\n\t\t\tfor ( const viewRoot of view.document.roots ) {\n\t\t\t\t// `viewRoot` can be empty despite the model post-fixers if the model root was detached.\n\t\t\t\tif ( viewRoot.isEmpty ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// If `viewRoot` is not empty, then we can expect at least two elements in it.\n\t\t\t\tconst body = viewRoot!.getChild( 1 ) as ViewElement;\n\t\t\t\tconst oldBody = bodyViewElements.get( viewRoot.rootName );\n\n\t\t\t\t// If body element has changed we need to disable placeholder on the previous element and enable on the new one.\n\t\t\t\tif ( body !== oldBody ) {\n\t\t\t\t\tif ( oldBody ) {\n\t\t\t\t\t\thidePlaceholder( writer, oldBody );\n\t\t\t\t\t\twriter.removeAttribute( 'data-placeholder', oldBody );\n\t\t\t\t\t}\n\n\t\t\t\t\twriter.setAttribute( 'data-placeholder', bodyPlaceholder, body );\n\t\t\t\t\tbodyViewElements.set( viewRoot.rootName, body );\n\n\t\t\t\t\thasChanged = true;\n\t\t\t\t}\n\n\t\t\t\t// Then we need to display placeholder if it is needed.\n\t\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/8689.\n\t\t\t\tif ( needsPlaceholder( body, true ) && viewRoot!.childCount === 2 && body!.name === 'p' ) {\n\t\t\t\t\thasChanged = showPlaceholder( writer, body ) ? true : hasChanged;\n\t\t\t\t} else {\n\t\t\t\t\t// Or hide if it is not needed.\n\t\t\t\t\thasChanged = hidePlaceholder( writer, body ) ? true : hasChanged;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn hasChanged;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates navigation between the title and body sections using <kbd>Tab</kbd> and <kbd>Shift</kbd>+<kbd>Tab</kbd> keys.\n\t */\n\tprivate _attachTabPressHandling() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\t// Pressing <kbd>Tab</kbd> inside the title should move the caret to the body.\n\t\teditor.keystrokes.set( 'TAB', ( data, cancel ) => {\n\t\t\tmodel.change( writer => {\n\t\t\t\tconst selection = model.document.selection;\n\t\t\t\tconst selectedElements = Array.from( selection.getSelectedBlocks() );\n\n\t\t\t\tif ( selectedElements.length === 1 && selectedElements[ 0 ].is( 'element', 'title-content' ) ) {\n\t\t\t\t\tconst root = selection.getFirstPosition()!.root;\n\t\t\t\t\tconst firstBodyElement = root.getChild( 1 );\n\n\t\t\t\t\twriter.setSelection( firstBodyElement!, 0 );\n\n\t\t\t\t\tcancel();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\n\t\t// Pressing <kbd>Shift</kbd>+<kbd>Tab</kbd> at the beginning of the body should move the caret to the title.\n\t\teditor.keystrokes.set( 'SHIFT + TAB', ( data, cancel ) => {\n\t\t\tmodel.change( writer => {\n\t\t\t\tconst selection = model.document.selection;\n\n\t\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst selectedElement = first( selection.getSelectedBlocks() );\n\t\t\t\tconst selectionPosition = selection.getFirstPosition()!;\n\t\t\t\tconst root = editor.model.document.getRoot( selectionPosition.root.rootName! )!;\n\n\t\t\t\tconst title = root.getChild( 0 ) as Element;\n\t\t\t\tconst body = root.getChild( 1 );\n\n\t\t\t\tif ( selectedElement === body && selectionPosition.isAtStart ) {\n\t\t\t\t\twriter.setSelection( title.getChild( 0 )!, 0 );\n\n\t\t\t\t\tcancel();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n}\n\n/**\n * A view-to-model converter for the h1 that appears at the beginning of the document (a title element).\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param evt An object containing information about the fired event.\n * @param data An object containing conversion input, a placeholder for conversion output and possibly other values.\n * @param conversionApi Conversion interface to be used by the callback.\n */\nfunction dataViewModelH1Insertion( evt: unknown, data: UpcastConversionData<ViewElement>, conversionApi: UpcastConversionApi ) {\n\tconst modelCursor = data.modelCursor;\n\tconst viewItem = data.viewItem;\n\n\tif ( !modelCursor.isAtStart || !modelCursor.parent.is( 'element', '$root' ) ) {\n\t\treturn;\n\t}\n\n\tif ( !conversionApi.consumable.consume( viewItem, { name: true } ) ) {\n\t\treturn;\n\t}\n\n\tconst modelWriter = conversionApi.writer;\n\n\tconst title = modelWriter.createElement( 'title' );\n\tconst titleContent = modelWriter.createElement( 'title-content' );\n\n\tmodelWriter.append( titleContent, title );\n\tmodelWriter.insert( title, modelCursor );\n\n\tconversionApi.convertChildren( viewItem, titleContent );\n\n\tconversionApi.updateConversionResult( title, data );\n}\n\n/**\n * Maps position from the beginning of the model `title` element to the beginning of the view `h1` element.\n *\n * ```html\n * <title>^<title-content>Foo</title-content></title> -> <h1>^Foo</h1>\n * ```\n */\nfunction mapModelPositionToView( editingView: EditingView ): GetCallback<MapperModelToViewPositionEvent> {\n\treturn ( evt, data ) => {\n\t\tconst positionParent = data.modelPosition.parent;\n\n\t\tif ( !positionParent.is( 'element', 'title' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelTitleElement = positionParent.parent as Element;\n\t\tconst viewElement = data.mapper.toViewElement( modelTitleElement )!;\n\n\t\tdata.viewPosition = editingView.createPositionAt( viewElement, 0 );\n\t\tevt.stop();\n\t};\n}\n\n/**\n * @returns Returns true when given element is a title. Returns false otherwise.\n */\nfunction isTitle( element: Element ) {\n\treturn element.is( 'element', 'title' );\n}\n\n/**\n * Changes the given element to the title element.\n */\nfunction changeElementToTitle( element: Element, writer: Writer, model: Model ) {\n\tconst title = writer.createElement( 'title' );\n\n\twriter.insert( title, element, 'before' );\n\twriter.insert( element, title, 0 );\n\twriter.rename( element, 'title-content' );\n\tmodel.schema.removeDisallowedAttributes( [ element ], writer );\n}\n\n/**\n * Loops over the list of title elements and fixes additional ones.\n *\n * @returns Returns true when there was any change. Returns false otherwise.\n */\nfunction fixAdditionalTitleElements( titleElements: Array<Element>, writer: Writer, model: Model ) {\n\tlet hasChanged = false;\n\n\tfor ( const title of titleElements ) {\n\t\tif ( title.index !== 0 ) {\n\t\t\tfixTitleElement( title, writer, model );\n\n\t\t\thasChanged = true;\n\t\t}\n\t}\n\n\treturn hasChanged;\n}\n\n/**\n * Changes given title element to a paragraph or removes it when it is empty.\n */\nfunction fixTitleElement( title: Element, writer: Writer, model: Model ) {\n\tconst child = title.getChild( 0 ) as Element;\n\n\t// Empty title should be removed.\n\t// It is created as a result of pasting to the title element.\n\tif ( child.isEmpty ) {\n\t\twriter.remove( title );\n\n\t\treturn;\n\t}\n\n\twriter.move( writer.createRangeOn( child ), title, 'before' );\n\twriter.rename( child, 'paragraph' );\n\twriter.remove( title );\n\tmodel.schema.removeDisallowedAttributes( [ child ], writer );\n}\n\n/**\n * Returns true when the last paragraph in the document was created only for the placeholder\n * purpose and it's not needed anymore. Returns false otherwise.\n */\nfunction shouldRemoveLastParagraph( placeholder: Element, root: RootElement ) {\n\tif ( !placeholder || !placeholder.is( 'element', 'paragraph' ) || placeholder.childCount ) {\n\t\treturn false;\n\t}\n\n\tif ( root.childCount <= 2 || root.getChild( root.childCount - 1 ) !== placeholder ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/**\n * The configuration of the {@link module:heading/title~Title title feature}.\n *\n * ```ts\n * ClassicEditor\n *   .create( document.querySelector( '#editor' ), {\n *     plugins: [ Title, ... ],\n *     title: {\n *       placeholder: 'My custom placeholder for the title'\n *     },\n *     placeholder: 'My custom placeholder for the body'\n *   } )\n *   .then( ... )\n *   .catch( ... );\n * ```\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor configuration options}.\n */\nexport interface TitleConfig {\n\n\t/**\n\t * Defines a custom value of the placeholder for the title field.\n\t *\n\t * Read more in {@link module:heading/title~TitleConfig}.\n\t */\n\tplaceholder?: string;\n}\n", "import { Plugin, Command, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { Clipboard, ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\nimport { LivePosition, LiveRange, Observer, UpcastWriter, enablePlaceholder, Element } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { Undo } from '@ckeditor/ckeditor5-undo/dist/index.js';\nimport { Delete } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { first, DomEmitterMixin, global, FocusTracker, KeystrokeHandler, logWarning, toArray, env, CKEditorError, Collection, Rect } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { toWidget, isWidget, findOptimalInsertionRange, Widget, toWidgetEditable, WidgetResize, calculateResizeHostAncestorWidth, WidgetToolbarRepository } from '@ckeditor/ckeditor5-widget/dist/index.js';\nimport { View, ViewCollection, FocusCycler, submitHandler, ButtonView, LabeledFieldView, createLabeledInputText, BalloonPanelView, ContextualBalloon, CssTransitionDisablerMixin, clickOutsideHandler, CollapsibleView, SplitButtonView, createDropdown, MenuBarMenuView, MenuBarMenuListView, MenuBarMenuListItemView, FileDialogButtonView, MenuBarMenuListItemFileDialogButtonView, Notification, Dialog, MenuBarMenuListItemButtonView, ViewModel, DropdownButtonView, addListToDropdown, createLabeledInputNumber, addToolbarToDropdown } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { FileRepository } from '@ckeditor/ckeditor5-upload/dist/index.js';\nimport { map, isObject, identity } from 'lodash-es';\n\n/**\n * Creates a view element representing the inline image.\n *\n * ```html\n * <span class=\"image-inline\"><img></img></span>\n * ```\n *\n * Note that `alt` and `src` attributes are converted separately, so they are not included.\n *\n * @internal\n */ function createInlineImageViewElement(writer) {\n    return writer.createContainerElement('span', {\n        class: 'image-inline'\n    }, writer.createEmptyElement('img'));\n}\n/**\n * Creates a view element representing the block image.\n *\n * ```html\n * <figure class=\"image\"><img></img></figure>\n * ```\n *\n * Note that `alt` and `src` attributes are converted separately, so they are not included.\n *\n * @internal\n */ function createBlockImageViewElement(writer) {\n    return writer.createContainerElement('figure', {\n        class: 'image'\n    }, [\n        writer.createEmptyElement('img'),\n        writer.createSlot('children')\n    ]);\n}\n/**\n * A function returning a `MatcherPattern` for a particular type of View images.\n *\n * @internal\n * @param matchImageType The type of created image.\n */ function getImgViewElementMatcher(editor, matchImageType) {\n    const imageUtils = editor.plugins.get('ImageUtils');\n    const areBothImagePluginsLoaded = editor.plugins.has('ImageInlineEditing') && editor.plugins.has('ImageBlockEditing');\n    return (element)=>{\n        // Check if the matched view element is an <img>.\n        if (!imageUtils.isInlineImageView(element)) {\n            return null;\n        }\n        // If just one of the plugins is loaded (block or inline), it will match all kinds of images.\n        if (!areBothImagePluginsLoaded) {\n            return getPositiveMatchPattern(element);\n        }\n        // The <img> can be standalone, wrapped in <figure>...</figure> (ImageBlock plugin) or\n        // wrapped in <figure><a>...</a></figure> (LinkImage plugin).\n        const imageType = element.getStyle('display') == 'block' || element.findAncestor(imageUtils.isBlockImageView) ? 'imageBlock' : 'imageInline';\n        if (imageType !== matchImageType) {\n            return null;\n        }\n        return getPositiveMatchPattern(element);\n    };\n    function getPositiveMatchPattern(element) {\n        const pattern = {\n            name: true\n        };\n        // This will trigger src consumption (See https://github.com/ckeditor/ckeditor5/issues/11530).\n        if (element.hasAttribute('src')) {\n            pattern.attributes = [\n                'src'\n            ];\n        }\n        return pattern;\n    }\n}\n/**\n * Considering the current model selection, it returns the name of the model image element\n * (`'imageBlock'` or `'imageInline'`) that will make most sense from the UX perspective if a new\n * image was inserted (also: uploaded, dropped, pasted) at that selection.\n *\n * The assumption is that inserting images into empty blocks or on other block widgets should\n * produce block images. Inline images should be inserted in other cases, e.g. in paragraphs\n * that already contain some text.\n *\n * @internal\n */ function determineImageTypeForInsertionAtSelection(schema, selection) {\n    const firstBlock = first(selection.getSelectedBlocks());\n    // Insert a block image if the selection is not in/on block elements or it's on a block widget.\n    if (!firstBlock || schema.isObject(firstBlock)) {\n        return 'imageBlock';\n    }\n    // A block image should also be inserted into an empty block element\n    // (that is not an empty list item so the list won't get split).\n    if (firstBlock.isEmpty && firstBlock.name != 'listItem') {\n        return 'imageBlock';\n    }\n    // Otherwise insert an inline image.\n    return 'imageInline';\n}\n/**\n * Returns parsed value of the size, but only if it contains unit: px.\n */ function getSizeValueIfInPx(size) {\n    if (size && size.endsWith('px')) {\n        return parseInt(size);\n    }\n    return null;\n}\n/**\n * Returns true if both styles (width and height) are set.\n *\n * If both image styles: width & height are set, they will override the image width & height attributes in the\n * browser. In this case, the image looks the same as if these styles were applied to attributes instead of styles.\n * That's why we can upcast these styles to width & height attributes instead of resizedWidth and resizedHeight.\n */ function widthAndHeightStylesAreBothSet(viewElement) {\n    const widthStyle = getSizeValueIfInPx(viewElement.getStyle('width'));\n    const heightStyle = getSizeValueIfInPx(viewElement.getStyle('height'));\n    return !!(widthStyle && heightStyle);\n}\n\nconst IMAGE_WIDGETS_CLASSES_MATCH_REGEXP = /^(image|image-inline)$/;\n/**\n * A set of helpers related to images.\n */ class ImageUtils extends Plugin {\n    /**\n\t * DOM Emitter.\n\t */ _domEmitter = new (DomEmitterMixin())();\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageUtils';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * Checks if the provided model element is an `image` or `imageInline`.\n\t */ isImage(modelElement) {\n        return this.isInlineImage(modelElement) || this.isBlockImage(modelElement);\n    }\n    /**\n\t * Checks if the provided view element represents an inline image.\n\t *\n\t * Also, see {@link module:image/imageutils~ImageUtils#isImageWidget}.\n\t */ isInlineImageView(element) {\n        return !!element && element.is('element', 'img');\n    }\n    /**\n\t * Checks if the provided view element represents a block image.\n\t *\n\t * Also, see {@link module:image/imageutils~ImageUtils#isImageWidget}.\n\t */ isBlockImageView(element) {\n        return !!element && element.is('element', 'figure') && element.hasClass('image');\n    }\n    /**\n\t * Handles inserting single file. This method unifies image insertion using {@link module:widget/utils~findOptimalInsertionRange}\n\t * method.\n\t *\n\t * ```ts\n\t * const imageUtils = editor.plugins.get( 'ImageUtils' );\n\t *\n\t * imageUtils.insertImage( { src: 'path/to/image.jpg' } );\n\t * ```\n\t *\n\t * @param attributes Attributes of the inserted image.\n\t * This method filters out the attributes which are disallowed by the {@link module:engine/model/schema~Schema}.\n\t * @param selectable Place to insert the image. If not specified,\n\t * the {@link module:widget/utils~findOptimalInsertionRange} logic will be applied for the block images\n\t * and `model.document.selection` for the inline images.\n\t *\n\t * **Note**: If `selectable` is passed, this helper will not be able to set selection attributes (such as `linkHref`)\n\t * and apply them to the new image. In this case, make sure all selection attributes are passed in `attributes`.\n\t *\n\t * @param imageType Image type of inserted image. If not specified,\n\t * it will be determined automatically depending of editor config or place of the insertion.\n\t * @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.\n\t * The default is `true`.\n\t * @return The inserted model image element.\n\t */ insertImage(attributes = {}, selectable = null, imageType = null, options = {}) {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        const determinedImageType = determineImageTypeForInsertion(editor, selectable || selection, imageType);\n        // Mix declarative attributes with selection attributes because the new image should \"inherit\"\n        // the latter for best UX. For instance, inline images inserted into existing links\n        // should not split them. To do that, they need to have \"linkHref\" inherited from the selection.\n        attributes = {\n            ...Object.fromEntries(selection.getAttributes()),\n            ...attributes\n        };\n        for(const attributeName in attributes){\n            if (!model.schema.checkAttribute(determinedImageType, attributeName)) {\n                delete attributes[attributeName];\n            }\n        }\n        return model.change((writer)=>{\n            const { setImageSizes = true } = options;\n            const imageElement = writer.createElement(determinedImageType, attributes);\n            model.insertObject(imageElement, selectable, null, {\n                setSelection: 'on',\n                // If we want to insert a block image (for whatever reason) then we don't want to split text blocks.\n                // This applies only when we don't have the selectable specified (i.e., we insert multiple block images at once).\n                findOptimalPosition: !selectable && determinedImageType != 'imageInline' ? 'auto' : undefined\n            });\n            // Inserting an image might've failed due to schema regulations.\n            if (imageElement.parent) {\n                if (setImageSizes) {\n                    this.setImageNaturalSizeAttributes(imageElement);\n                }\n                return imageElement;\n            }\n            return null;\n        });\n    }\n    /**\n\t * Reads original image sizes and sets them as `width` and `height`.\n\t *\n\t * The `src` attribute may not be available if the user is using an upload adapter. In such a case,\n\t * this method is called again after the upload process is complete and the `src` attribute is available.\n\t */ setImageNaturalSizeAttributes(imageElement) {\n        const src = imageElement.getAttribute('src');\n        if (!src) {\n            return;\n        }\n        if (imageElement.getAttribute('width') || imageElement.getAttribute('height')) {\n            return;\n        }\n        this.editor.model.change((writer)=>{\n            const img = new global.window.Image();\n            this._domEmitter.listenTo(img, 'load', ()=>{\n                if (!imageElement.getAttribute('width') && !imageElement.getAttribute('height')) {\n                    // We use writer.batch to be able to undo (in a single step) width and height setting\n                    // along with any change that triggered this action (e.g. image resize or image style change).\n                    this.editor.model.enqueueChange(writer.batch, (writer)=>{\n                        writer.setAttribute('width', img.naturalWidth, imageElement);\n                        writer.setAttribute('height', img.naturalHeight, imageElement);\n                    });\n                }\n                this._domEmitter.stopListening(img, 'load');\n            });\n            img.src = src;\n        });\n    }\n    /**\n\t * Returns an image widget editing view element if one is selected or is among the selection's ancestors.\n\t */ getClosestSelectedImageWidget(selection) {\n        const selectionPosition = selection.getFirstPosition();\n        if (!selectionPosition) {\n            return null;\n        }\n        const viewElement = selection.getSelectedElement();\n        if (viewElement && this.isImageWidget(viewElement)) {\n            return viewElement;\n        }\n        let parent = selectionPosition.parent;\n        while(parent){\n            if (parent.is('element') && this.isImageWidget(parent)) {\n                return parent;\n            }\n            parent = parent.parent;\n        }\n        return null;\n    }\n    /**\n\t * Returns a image model element if one is selected or is among the selection's ancestors.\n\t */ getClosestSelectedImageElement(selection) {\n        const selectedElement = selection.getSelectedElement();\n        return this.isImage(selectedElement) ? selectedElement : selection.getFirstPosition().findAncestor('imageBlock');\n    }\n    /**\n\t * Returns an image widget editing view based on the passed image view.\n\t */ getImageWidgetFromImageView(imageView) {\n        return imageView.findAncestor({\n            classes: IMAGE_WIDGETS_CLASSES_MATCH_REGEXP\n        });\n    }\n    /**\n\t * Checks if image can be inserted at current model selection.\n\t *\n\t * @internal\n\t */ isImageAllowed() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        return isImageAllowedInParent(this.editor, selection) && isNotInsideImage(selection);\n    }\n    /**\n\t * Converts a given {@link module:engine/view/element~Element} to an image widget:\n\t * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the image widget\n\t * element.\n\t * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n\t *\n\t * @param writer An instance of the view writer.\n\t * @param label The element's label. It will be concatenated with the image `alt` attribute if one is present.\n\t */ toImageWidget(viewElement, writer, label) {\n        writer.setCustomProperty('image', true, viewElement);\n        const labelCreator = ()=>{\n            const imgElement = this.findViewImgElement(viewElement);\n            const altText = imgElement.getAttribute('alt');\n            return altText ? `${altText} ${label}` : label;\n        };\n        return toWidget(viewElement, writer, {\n            label: labelCreator\n        });\n    }\n    /**\n\t * Checks if a given view element is an image widget.\n\t */ isImageWidget(viewElement) {\n        return !!viewElement.getCustomProperty('image') && isWidget(viewElement);\n    }\n    /**\n\t * Checks if the provided model element is an `image`.\n\t */ isBlockImage(modelElement) {\n        return !!modelElement && modelElement.is('element', 'imageBlock');\n    }\n    /**\n\t * Checks if the provided model element is an `imageInline`.\n\t */ isInlineImage(modelElement) {\n        return !!modelElement && modelElement.is('element', 'imageInline');\n    }\n    /**\n\t * Get the view `<img>` from another view element, e.g. a widget (`<figure class=\"image\">`), a link (`<a>`).\n\t *\n\t * The `<img>` can be located deep in other elements, so this helper performs a deep tree search.\n\t */ findViewImgElement(figureView) {\n        if (this.isInlineImageView(figureView)) {\n            return figureView;\n        }\n        const editingView = this.editor.editing.view;\n        for (const { item } of editingView.createRangeIn(figureView)){\n            if (this.isInlineImageView(item)) {\n                return item;\n            }\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this._domEmitter.stopListening();\n        return super.destroy();\n    }\n}\n/**\n * Checks if image is allowed by schema in optimal insertion parent.\n */ function isImageAllowedInParent(editor, selection) {\n    const imageType = determineImageTypeForInsertion(editor, selection, null);\n    if (imageType == 'imageBlock') {\n        const parent = getInsertImageParent(selection, editor.model);\n        if (editor.model.schema.checkChild(parent, 'imageBlock')) {\n            return true;\n        }\n    } else if (editor.model.schema.checkChild(selection.focus, 'imageInline')) {\n        return true;\n    }\n    return false;\n}\n/**\n * Checks if selection is not placed inside an image (e.g. its caption).\n */ function isNotInsideImage(selection) {\n    return [\n        ...selection.focus.getAncestors()\n    ].every((ancestor)=>!ancestor.is('element', 'imageBlock'));\n}\n/**\n * Returns a node that will be used to insert image with `model.insertContent`.\n */ function getInsertImageParent(selection, model) {\n    const insertionRange = findOptimalInsertionRange(selection, model);\n    const parent = insertionRange.start.parent;\n    if (parent.isEmpty && !parent.is('element', '$root')) {\n        return parent.parent;\n    }\n    return parent;\n}\n/**\n * Determine image element type name depending on editor config or place of insertion.\n *\n * @param imageType Image element type name. Used to force return of provided element name,\n * but only if there is proper plugin enabled.\n */ function determineImageTypeForInsertion(editor, selectable, imageType) {\n    const schema = editor.model.schema;\n    const configImageInsertType = editor.config.get('image.insert.type');\n    if (!editor.plugins.has('ImageBlockEditing')) {\n        return 'imageInline';\n    }\n    if (!editor.plugins.has('ImageInlineEditing')) {\n        return 'imageBlock';\n    }\n    if (imageType) {\n        return imageType;\n    }\n    if (configImageInsertType === 'inline') {\n        return 'imageInline';\n    }\n    if (configImageInsertType !== 'auto') {\n        return 'imageBlock';\n    }\n    // Try to replace the selected widget (e.g. another image).\n    if (selectable.is('selection')) {\n        return determineImageTypeForInsertionAtSelection(schema, selectable);\n    }\n    return schema.checkChild(selectable, 'imageInline') ? 'imageInline' : 'imageBlock';\n}\n\n// Implements the pattern: http(s)://(www.)example.com/path/to/resource.ext?query=params&maybe=too.\nconst IMAGE_URL_REGEXP = new RegExp(String(/^(http(s)?:\\/\\/)?[\\w-]+\\.[\\w.~:/[\\]@!$&'()*+,;=%-]+/.source + /\\.(jpg|jpeg|png|gif|ico|webp|JPG|JPEG|PNG|GIF|ICO|WEBP)/.source + /(\\?[\\w.~:/[\\]@!$&'()*+,;=%-]*)?/.source + /(#[\\w.~:/[\\]@!$&'()*+,;=%-]*)?$/.source));\n/**\n * The auto-image plugin. It recognizes image links in the pasted content and embeds\n * them shortly after they are injected into the document.\n */ class AutoImage extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Clipboard,\n            ImageUtils,\n            Undo,\n            Delete\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'AutoImage';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * The paste–to–embed `setTimeout` ID. Stored as a property to allow\n\t * cleaning of the timeout.\n\t */ _timeoutId;\n    /**\n\t * The position where the `<imageBlock>` element will be inserted after the timeout,\n\t * determined each time a new content is pasted into the document.\n\t */ _positionToInsert;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._timeoutId = null;\n        this._positionToInsert = null;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const modelDocument = editor.model.document;\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        // We need to listen on `Clipboard#inputTransformation` because we need to save positions of selection.\n        // After pasting, the content between those positions will be checked for a URL that could be transformed\n        // into an image.\n        this.listenTo(clipboardPipeline, 'inputTransformation', ()=>{\n            const firstRange = modelDocument.selection.getFirstRange();\n            const leftLivePosition = LivePosition.fromPosition(firstRange.start);\n            leftLivePosition.stickiness = 'toPrevious';\n            const rightLivePosition = LivePosition.fromPosition(firstRange.end);\n            rightLivePosition.stickiness = 'toNext';\n            modelDocument.once('change:data', ()=>{\n                this._embedImageBetweenPositions(leftLivePosition, rightLivePosition);\n                leftLivePosition.detach();\n                rightLivePosition.detach();\n            }, {\n                priority: 'high'\n            });\n        });\n        editor.commands.get('undo').on('execute', ()=>{\n            if (this._timeoutId) {\n                global.window.clearTimeout(this._timeoutId);\n                this._positionToInsert.detach();\n                this._timeoutId = null;\n                this._positionToInsert = null;\n            }\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Analyzes the part of the document between provided positions in search for a URL representing an image.\n\t * When the URL is found, it is automatically converted into an image.\n\t *\n\t * @param leftPosition Left position of the selection.\n\t * @param rightPosition Right position of the selection.\n\t */ _embedImageBetweenPositions(leftPosition, rightPosition) {\n        const editor = this.editor;\n        // TODO: Use a marker instead of LiveRange & LivePositions.\n        const urlRange = new LiveRange(leftPosition, rightPosition);\n        const walker = urlRange.getWalker({\n            ignoreElementEnd: true\n        });\n        const selectionAttributes = Object.fromEntries(editor.model.document.selection.getAttributes());\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        let src = '';\n        for (const node of walker){\n            if (node.item.is('$textProxy')) {\n                src += node.item.data;\n            }\n        }\n        src = src.trim();\n        // If the URL does not match the image URL regexp, let's skip that.\n        if (!src.match(IMAGE_URL_REGEXP)) {\n            urlRange.detach();\n            return;\n        }\n        // Position will not be available in the `setTimeout` function so let's clone it.\n        this._positionToInsert = LivePosition.fromPosition(leftPosition);\n        // This action mustn't be executed if undo was called between pasting and auto-embedding.\n        this._timeoutId = setTimeout(()=>{\n            // Do nothing if image element cannot be inserted at the current position.\n            // See https://github.com/ckeditor/ckeditor5/issues/2763.\n            // Condition must be checked after timeout - pasting may take place on an element, replacing it. The final position matters.\n            const imageCommand = editor.commands.get('insertImage');\n            if (!imageCommand.isEnabled) {\n                urlRange.detach();\n                return;\n            }\n            editor.model.change((writer)=>{\n                this._timeoutId = null;\n                writer.remove(urlRange);\n                urlRange.detach();\n                let insertionPosition;\n                // Check if the position where the element should be inserted is still valid.\n                // Otherwise leave it as undefined to use the logic of insertImage().\n                if (this._positionToInsert.root.rootName !== '$graveyard') {\n                    insertionPosition = this._positionToInsert.toPosition();\n                }\n                imageUtils.insertImage({\n                    ...selectionAttributes,\n                    src\n                }, insertionPosition);\n                this._positionToInsert.detach();\n                this._positionToInsert = null;\n            });\n            const deletePlugin = editor.plugins.get('Delete');\n            deletePlugin.requestUndoOnBackspace();\n        }, 100);\n    }\n}\n\n/**\n * The image text alternative command. It is used to change the `alt` attribute of `<imageBlock>` and `<imageInline>` model elements.\n */ class ImageTextAlternativeCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const element = imageUtils.getClosestSelectedImageElement(this.editor.model.document.selection);\n        this.isEnabled = !!element;\n        if (this.isEnabled && element.hasAttribute('alt')) {\n            this.value = element.getAttribute('alt');\n        } else {\n            this.value = false;\n        }\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options\n\t * @param options.newValue The new value of the `alt` attribute to set.\n\t */ execute(options) {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const model = editor.model;\n        const imageElement = imageUtils.getClosestSelectedImageElement(model.document.selection);\n        model.change((writer)=>{\n            writer.setAttribute('alt', options.newValue, imageElement);\n        });\n    }\n}\n\n/**\n * The image text alternative editing plugin.\n *\n * Registers the `'imageTextAlternative'` command.\n */ class ImageTextAlternativeEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageTextAlternativeEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        this.editor.commands.add('imageTextAlternative', new ImageTextAlternativeCommand(this.editor));\n    }\n}\n\n/**\n * The TextAlternativeFormView class.\n */ class TextAlternativeFormView extends View {\n    /**\n\t * Tracks information about the DOM focus in the form.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * An input with a label.\n\t */ labeledInput;\n    /**\n\t * A button used to submit the form.\n\t */ saveButtonView;\n    /**\n\t * A button used to cancel the form.\n\t */ cancelButtonView;\n    /**\n\t * A collection of views which can be focused in the form.\n\t */ _focusables;\n    /**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */ _focusCycler;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const t = this.locale.t;\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.labeledInput = this._createLabeledInputView();\n        this.saveButtonView = this._createButton(t('Save'), icons.check, 'ck-button-save');\n        this.saveButtonView.type = 'submit';\n        this.cancelButtonView = this._createButton(t('Cancel'), icons.cancel, 'ck-button-cancel', 'cancel');\n        this._focusables = new ViewCollection();\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        this.setTemplate({\n            tag: 'form',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-text-alternative-form',\n                    'ck-responsive-form'\n                ],\n                // https://github.com/ckeditor/ckeditor5-image/issues/40\n                tabindex: '-1'\n            },\n            children: [\n                this.labeledInput,\n                this.saveButtonView,\n                this.cancelButtonView\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.keystrokes.listenTo(this.element);\n        submitHandler({\n            view: this\n        });\n        [\n            this.labeledInput,\n            this.saveButtonView,\n            this.cancelButtonView\n        ].forEach((v)=>{\n            // Register the view as focusable.\n            this._focusables.add(v);\n            // Register the view in the focus tracker.\n            this.focusTracker.add(v.element);\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Creates the button view.\n\t *\n\t * @param label The button label\n\t * @param icon The button's icon.\n\t * @param className The additional button CSS class name.\n\t * @param eventName The event name that the ButtonView#execute event will be delegated to.\n\t * @returns The button view instance.\n\t */ _createButton(label, icon, className, eventName) {\n        const button = new ButtonView(this.locale);\n        button.set({\n            label,\n            icon,\n            tooltip: true\n        });\n        button.extendTemplate({\n            attributes: {\n                class: className\n            }\n        });\n        if (eventName) {\n            button.delegate('execute').to(this, eventName);\n        }\n        return button;\n    }\n    /**\n\t * Creates an input with a label.\n\t *\n\t * @returns Labeled field view instance.\n\t */ _createLabeledInputView() {\n        const t = this.locale.t;\n        const labeledInput = new LabeledFieldView(this.locale, createLabeledInputText);\n        labeledInput.label = t('Text alternative');\n        return labeledInput;\n    }\n}\n\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the image in the editor content, if one is selected.\n *\n * @param editor The editor instance.\n */ function repositionContextualBalloon(editor) {\n    const balloon = editor.plugins.get('ContextualBalloon');\n    const imageUtils = editor.plugins.get('ImageUtils');\n    if (imageUtils.getClosestSelectedImageWidget(editor.editing.view.document.selection)) {\n        const position = getBalloonPositionData(editor);\n        balloon.updatePosition(position);\n    }\n}\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected element in the editor content.\n *\n * @param editor The editor instance.\n */ function getBalloonPositionData(editor) {\n    const editingView = editor.editing.view;\n    const defaultPositions = BalloonPanelView.defaultPositions;\n    const imageUtils = editor.plugins.get('ImageUtils');\n    return {\n        target: editingView.domConverter.mapViewToDom(imageUtils.getClosestSelectedImageWidget(editingView.document.selection)),\n        positions: [\n            defaultPositions.northArrowSouth,\n            defaultPositions.northArrowSouthWest,\n            defaultPositions.northArrowSouthEast,\n            defaultPositions.southArrowNorth,\n            defaultPositions.southArrowNorthWest,\n            defaultPositions.southArrowNorthEast,\n            defaultPositions.viewportStickyNorth\n        ]\n    };\n}\n\n/**\n * The image text alternative UI plugin.\n *\n * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n */ class ImageTextAlternativeUI extends Plugin {\n    /**\n\t * The contextual balloon plugin instance.\n\t */ _balloon;\n    /**\n\t * A form containing a textarea and buttons, used to change the `alt` text value.\n\t */ _form;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageTextAlternativeUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        this._createButton();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n        if (this._form) {\n            this._form.destroy();\n        }\n    }\n    /**\n\t * Creates a button showing the balloon panel for changing the image text alternative and\n\t * registers it in the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}.\n\t */ _createButton() {\n        const editor = this.editor;\n        const t = editor.t;\n        editor.ui.componentFactory.add('imageTextAlternative', (locale)=>{\n            const command = editor.commands.get('imageTextAlternative');\n            const view = new ButtonView(locale);\n            view.set({\n                label: t('Change image text alternative'),\n                icon: icons.textAlternative,\n                tooltip: true\n            });\n            view.bind('isEnabled').to(command, 'isEnabled');\n            view.bind('isOn').to(command, 'value', (value)=>!!value);\n            this.listenTo(view, 'execute', ()=>{\n                this._showForm();\n            });\n            return view;\n        });\n    }\n    /**\n\t * Creates the {@link module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView}\n\t * form.\n\t */ _createForm() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        this._balloon = this.editor.plugins.get('ContextualBalloon');\n        this._form = new (CssTransitionDisablerMixin(TextAlternativeFormView))(editor.locale);\n        // Render the form so its #element is available for clickOutsideHandler.\n        this._form.render();\n        this.listenTo(this._form, 'submit', ()=>{\n            editor.execute('imageTextAlternative', {\n                newValue: this._form.labeledInput.fieldView.element.value\n            });\n            this._hideForm(true);\n        });\n        this.listenTo(this._form, 'cancel', ()=>{\n            this._hideForm(true);\n        });\n        // Close the form on Esc key press.\n        this._form.keystrokes.set('Esc', (data, cancel)=>{\n            this._hideForm(true);\n            cancel();\n        });\n        // Reposition the balloon or hide the form if an image widget is no longer selected.\n        this.listenTo(editor.ui, 'update', ()=>{\n            if (!imageUtils.getClosestSelectedImageWidget(viewDocument.selection)) {\n                this._hideForm(true);\n            } else if (this._isVisible) {\n                repositionContextualBalloon(editor);\n            }\n        });\n        // Close on click outside of balloon panel element.\n        clickOutsideHandler({\n            emitter: this._form,\n            activator: ()=>this._isVisible,\n            contextElements: ()=>[\n                    this._balloon.view.element\n                ],\n            callback: ()=>this._hideForm()\n        });\n    }\n    /**\n\t * Shows the {@link #_form} in the {@link #_balloon}.\n\t */ _showForm() {\n        if (this._isVisible) {\n            return;\n        }\n        if (!this._form) {\n            this._createForm();\n        }\n        const editor = this.editor;\n        const command = editor.commands.get('imageTextAlternative');\n        const labeledInput = this._form.labeledInput;\n        this._form.disableCssTransitions();\n        if (!this._isInBalloon) {\n            this._balloon.add({\n                view: this._form,\n                position: getBalloonPositionData(editor)\n            });\n        }\n        // Make sure that each time the panel shows up, the field remains in sync with the value of\n        // the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`\n        // stays unaltered) and re-opened it without changing the value of the command, they would see the\n        // old value instead of the actual value of the command.\n        // https://github.com/ckeditor/ckeditor5-image/issues/114\n        labeledInput.fieldView.value = labeledInput.fieldView.element.value = command.value || '';\n        this._form.labeledInput.fieldView.select();\n        this._form.enableCssTransitions();\n    }\n    /**\n\t * Removes the {@link #_form} from the {@link #_balloon}.\n\t *\n\t * @param focusEditable Controls whether the editing view is focused afterwards.\n\t */ _hideForm(focusEditable = false) {\n        if (!this._isInBalloon) {\n            return;\n        }\n        // Blur the input element before removing it from DOM to prevent issues in some browsers.\n        // See https://github.com/ckeditor/ckeditor5/issues/1501.\n        if (this._form.focusTracker.isFocused) {\n            this._form.saveButtonView.focus();\n        }\n        this._balloon.remove(this._form);\n        if (focusEditable) {\n            this.editor.editing.view.focus();\n        }\n    }\n    /**\n\t * Returns `true` when the {@link #_form} is the visible view in the {@link #_balloon}.\n\t */ get _isVisible() {\n        return !!this._balloon && this._balloon.visibleView === this._form;\n    }\n    /**\n\t * Returns `true` when the {@link #_form} is in the {@link #_balloon}.\n\t */ get _isInBalloon() {\n        return !!this._balloon && this._balloon.hasView(this._form);\n    }\n}\n\n/**\n * The image text alternative plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-styles image styles} documentation.\n *\n * This is a \"glue\" plugin which loads the\n *  {@link module:image/imagetextalternative/imagetextalternativeediting~ImageTextAlternativeEditing}\n * and {@link module:image/imagetextalternative/imagetextalternativeui~ImageTextAlternativeUI} plugins.\n */ class ImageTextAlternative extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageTextAlternativeEditing,\n            ImageTextAlternativeUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageTextAlternative';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * Returns a function that converts the image view representation:\n *\n * ```html\n * <figure class=\"image\"><img src=\"...\" alt=\"...\"></img></figure>\n * ```\n *\n * to the model representation:\n *\n * ```html\n * <imageBlock src=\"...\" alt=\"...\"></imageBlock>\n * ```\n *\n * The entire content of the `<figure>` element except the first `<img>` is being converted as children\n * of the `<imageBlock>` model element.\n *\n * @internal\n */ function upcastImageFigure(imageUtils) {\n    const converter = (evt, data, conversionApi)=>{\n        // Do not convert if this is not an \"image figure\".\n        if (!conversionApi.consumable.test(data.viewItem, {\n            name: true,\n            classes: 'image'\n        })) {\n            return;\n        }\n        // Find an image element inside the figure element.\n        const viewImage = imageUtils.findViewImgElement(data.viewItem);\n        // Do not convert if image element is absent or was already converted.\n        if (!viewImage || !conversionApi.consumable.test(viewImage, {\n            name: true\n        })) {\n            return;\n        }\n        // Consume the figure to prevent other converters from processing it again.\n        conversionApi.consumable.consume(data.viewItem, {\n            name: true,\n            classes: 'image'\n        });\n        // Convert view image to model image.\n        const conversionResult = conversionApi.convertItem(viewImage, data.modelCursor);\n        // Get image element from conversion result.\n        const modelImage = first(conversionResult.modelRange.getItems());\n        // When image wasn't successfully converted then finish conversion.\n        if (!modelImage) {\n            // Revert consumed figure so other features can convert it.\n            conversionApi.consumable.revert(data.viewItem, {\n                name: true,\n                classes: 'image'\n            });\n            return;\n        }\n        // Convert rest of the figure element's children as an image children.\n        conversionApi.convertChildren(data.viewItem, modelImage);\n        conversionApi.updateConversionResult(modelImage, data);\n    };\n    return (dispatcher)=>{\n        dispatcher.on('element:figure', converter);\n    };\n}\n/**\n * Returns a function that converts the image view representation:\n *\n * ```html\n * <picture><source ... /><source ... />...<img ... /></picture>\n * ```\n *\n * to the model representation as the `sources` attribute:\n *\n * ```html\n * <image[Block|Inline] ... sources=\"...\"></image[Block|Inline]>\n * ```\n *\n * @internal\n */ function upcastPicture(imageUtils) {\n    const sourceAttributeNames = [\n        'srcset',\n        'media',\n        'type',\n        'sizes'\n    ];\n    const converter = (evt, data, conversionApi)=>{\n        const pictureViewElement = data.viewItem;\n        // Do not convert <picture> if already consumed.\n        if (!conversionApi.consumable.test(pictureViewElement, {\n            name: true\n        })) {\n            return;\n        }\n        const sources = new Map();\n        // Collect all <source /> elements attribute values.\n        for (const childSourceElement of pictureViewElement.getChildren()){\n            if (childSourceElement.is('element', 'source')) {\n                const attributes = {};\n                for (const name of sourceAttributeNames){\n                    if (childSourceElement.hasAttribute(name)) {\n                        // Don't collect <source /> attribute if already consumed somewhere else.\n                        if (conversionApi.consumable.test(childSourceElement, {\n                            attributes: name\n                        })) {\n                            attributes[name] = childSourceElement.getAttribute(name);\n                        }\n                    }\n                }\n                if (Object.keys(attributes).length) {\n                    sources.set(childSourceElement, attributes);\n                }\n            }\n        }\n        const imgViewElement = imageUtils.findViewImgElement(pictureViewElement);\n        // Don't convert when a picture has no <img/> inside (it is broken).\n        if (!imgViewElement) {\n            return;\n        }\n        let modelImage = data.modelCursor.parent;\n        // - In case of an inline image (cursor parent in a <paragraph>), the <img/> must be converted right away\n        // because no converter handled it yet and otherwise there would be no model element to set the sources attribute on.\n        // - In case of a block image, the <figure class=\"image\"> converter (in ImageBlockEditing) converts the\n        // <img/> right away on its own and the modelCursor is already inside an imageBlock and there's nothing special\n        // to do here.\n        if (!modelImage.is('element', 'imageBlock')) {\n            const conversionResult = conversionApi.convertItem(imgViewElement, data.modelCursor);\n            // Set image range as conversion result.\n            data.modelRange = conversionResult.modelRange;\n            // Continue conversion where image conversion ends.\n            data.modelCursor = conversionResult.modelCursor;\n            modelImage = first(conversionResult.modelRange.getItems());\n        }\n        conversionApi.consumable.consume(pictureViewElement, {\n            name: true\n        });\n        // Consume only these <source/> attributes that were actually collected and will be passed on\n        // to the image model element.\n        for (const [sourceElement, attributes] of sources){\n            conversionApi.consumable.consume(sourceElement, {\n                attributes: Object.keys(attributes)\n            });\n        }\n        if (sources.size) {\n            conversionApi.writer.setAttribute('sources', Array.from(sources.values()), modelImage);\n        }\n        // Convert rest of the <picture> children as an image children. Other converters may want to consume them.\n        conversionApi.convertChildren(pictureViewElement, modelImage);\n    };\n    return (dispatcher)=>{\n        dispatcher.on('element:picture', converter);\n    };\n}\n/**\n * Converter used to convert the `srcset` model image attribute to the `srcset` and `sizes` attributes in the view.\n *\n * @internal\n * @param imageType The type of the image.\n */ function downcastSrcsetAttribute(imageUtils, imageType) {\n    const converter = (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const writer = conversionApi.writer;\n        const element = conversionApi.mapper.toViewElement(data.item);\n        const img = imageUtils.findViewImgElement(element);\n        if (data.attributeNewValue === null) {\n            writer.removeAttribute('srcset', img);\n            writer.removeAttribute('sizes', img);\n        } else {\n            if (data.attributeNewValue) {\n                writer.setAttribute('srcset', data.attributeNewValue, img);\n                // Always outputting `100vw`. See https://github.com/ckeditor/ckeditor5-image/issues/2.\n                writer.setAttribute('sizes', '100vw', img);\n            }\n        }\n    };\n    return (dispatcher)=>{\n        dispatcher.on(`attribute:srcset:${imageType}`, converter);\n    };\n}\n/**\n * Converts the `source` model attribute to the `<picture><source /><source />...<img /></picture>`\n * view structure.\n *\n * @internal\n */ function downcastSourcesAttribute(imageUtils) {\n    const converter = (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const viewWriter = conversionApi.writer;\n        const element = conversionApi.mapper.toViewElement(data.item);\n        const imgElement = imageUtils.findViewImgElement(element);\n        const attributeNewValue = data.attributeNewValue;\n        if (attributeNewValue && attributeNewValue.length) {\n            // Collect all wrapping attribute elements.\n            const attributeElements = [];\n            let viewElement = imgElement.parent;\n            while(viewElement && viewElement.is('attributeElement')){\n                const parentElement = viewElement.parent;\n                viewWriter.unwrap(viewWriter.createRangeOn(imgElement), viewElement);\n                attributeElements.unshift(viewElement);\n                viewElement = parentElement;\n            }\n            const hasPictureElement = imgElement.parent.is('element', 'picture');\n            // Reuse existing <picture> element (ckeditor5#17192) or create a new one.\n            const pictureElement = hasPictureElement ? imgElement.parent : viewWriter.createContainerElement('picture', null);\n            if (!hasPictureElement) {\n                viewWriter.insert(viewWriter.createPositionBefore(imgElement), pictureElement);\n            }\n            viewWriter.remove(viewWriter.createRangeIn(pictureElement));\n            viewWriter.insert(viewWriter.createPositionAt(pictureElement, 'end'), attributeNewValue.map((sourceAttributes)=>{\n                return viewWriter.createEmptyElement('source', sourceAttributes);\n            }));\n            viewWriter.move(viewWriter.createRangeOn(imgElement), viewWriter.createPositionAt(pictureElement, 'end'));\n            // Apply collected attribute elements over the new picture element.\n            for (const attributeElement of attributeElements){\n                viewWriter.wrap(viewWriter.createRangeOn(pictureElement), attributeElement);\n            }\n        } else if (imgElement.parent.is('element', 'picture')) {\n            const pictureElement = imgElement.parent;\n            viewWriter.move(viewWriter.createRangeOn(imgElement), viewWriter.createPositionBefore(pictureElement));\n            viewWriter.remove(pictureElement);\n        }\n    };\n    return (dispatcher)=>{\n        dispatcher.on('attribute:sources:imageBlock', converter);\n        dispatcher.on('attribute:sources:imageInline', converter);\n    };\n}\n/**\n * Converter used to convert a given image attribute from the model to the view.\n *\n * @internal\n * @param imageType The type of the image.\n * @param attributeKey The name of the attribute to convert.\n */ function downcastImageAttribute(imageUtils, imageType, attributeKey) {\n    const converter = (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const viewWriter = conversionApi.writer;\n        const element = conversionApi.mapper.toViewElement(data.item);\n        const img = imageUtils.findViewImgElement(element);\n        viewWriter.setAttribute(data.attributeKey, data.attributeNewValue || '', img);\n    };\n    return (dispatcher)=>{\n        dispatcher.on(`attribute:${attributeKey}:${imageType}`, converter);\n    };\n}\n\n/**\n * Observes all new images added to the {@link module:engine/view/document~Document},\n * fires {@link module:engine/view/document~Document#event:imageLoaded} and\n * {@link module:engine/view/document~Document#event:layoutChanged} event every time when the new image\n * has been loaded.\n *\n * **Note:** This event is not fired for images that has been added to the document and rendered as `complete` (already loaded).\n */ class ImageLoadObserver extends Observer {\n    /**\n\t * @inheritDoc\n\t */ observe(domRoot) {\n        this.listenTo(domRoot, 'load', (event, domEvent)=>{\n            const domElement = domEvent.target;\n            if (this.checkShouldIgnoreEventFromTarget(domElement)) {\n                return;\n            }\n            if (domElement.tagName == 'IMG') {\n                this._fireEvents(domEvent);\n            }\n        // Use capture phase for better performance (#4504).\n        }, {\n            useCapture: true\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ stopObserving(domRoot) {\n        this.stopListening(domRoot);\n    }\n    /**\n\t * Fires {@link module:engine/view/document~Document#event:layoutChanged} and\n\t * {@link module:engine/view/document~Document#event:imageLoaded}\n\t * if observer {@link #isEnabled is enabled}.\n\t *\n\t * @param domEvent The DOM event.\n\t */ _fireEvents(domEvent) {\n        if (this.isEnabled) {\n            this.document.fire('layoutChanged');\n            this.document.fire('imageLoaded', domEvent);\n        }\n    }\n}\n\n/**\n * Insert image command.\n *\n * The command is registered by the {@link module:image/image/imageediting~ImageEditing} plugin as `insertImage`\n * and it is also available via aliased `imageInsert` name.\n *\n * In order to insert an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionRange} algorithm),\n * execute the command and specify the image source:\n *\n * ```ts\n * editor.execute( 'insertImage', { source: 'http://url.to.the/image' } );\n * ```\n *\n * It is also possible to insert multiple images at once:\n *\n * ```ts\n * editor.execute( 'insertImage', {\n * \tsource:  [\n * \t\t'path/to/image.jpg',\n * \t\t'path/to/other-image.jpg'\n * \t]\n * } );\n * ```\n *\n * If you want to take the full control over the process, you can specify individual model attributes:\n *\n * ```ts\n * editor.execute( 'insertImage', {\n * \tsource:  [\n * \t\t{ src: 'path/to/image.jpg', alt: 'First alt text' },\n * \t\t{ src: 'path/to/other-image.jpg', alt: 'Second alt text', customAttribute: 'My attribute value' }\n * \t]\n * } );\n * ```\n */ class InsertImageCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        const configImageInsertType = editor.config.get('image.insert.type');\n        if (!editor.plugins.has('ImageBlockEditing')) {\n            if (configImageInsertType === 'block') {\n                /**\n\t\t\t\t * The {@link module:image/imageblock~ImageBlock} plugin must be enabled to allow inserting block images. See\n\t\t\t\t * {@link module:image/imageconfig~ImageInsertConfig#type} to learn more.\n\t\t\t\t *\n\t\t\t\t * @error image-block-plugin-required\n\t\t\t\t */ logWarning('image-block-plugin-required');\n            }\n        }\n        if (!editor.plugins.has('ImageInlineEditing')) {\n            if (configImageInsertType === 'inline') {\n                /**\n\t\t\t\t * The {@link module:image/imageinline~ImageInline} plugin must be enabled to allow inserting inline images. See\n\t\t\t\t * {@link module:image/imageconfig~ImageInsertConfig#type} to learn more.\n\t\t\t\t *\n\t\t\t\t * @error image-inline-plugin-required\n\t\t\t\t */ logWarning('image-inline-plugin-required');\n            }\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        this.isEnabled = imageUtils.isImageAllowed();\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.imageType The type of the image to insert. If not specified, the type will be determined automatically.\n\t * @param options.source The image source or an array of image sources to insert.\n\t * See the documentation of the command to learn more about accepted formats.\n\t */ execute(options) {\n        const sourceDefinitions = toArray(options.source);\n        const selection = this.editor.model.document.selection;\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        // In case of multiple images, each image (starting from the 2nd) will be inserted at a position that\n        // follows the previous one. That will move the selection and, to stay on the safe side and make sure\n        // all images inherit the same selection attributes, they are collected beforehand.\n        //\n        // Applying these attributes ensures, for instance, that inserting an (inline) image into a link does\n        // not split that link but preserves its continuity.\n        //\n        // Note: Selection attributes that do not make sense for images will be filtered out by insertImage() anyway.\n        const selectionAttributes = Object.fromEntries(selection.getAttributes());\n        sourceDefinitions.forEach((sourceDefinition, index)=>{\n            const selectedElement = selection.getSelectedElement();\n            if (typeof sourceDefinition === 'string') {\n                sourceDefinition = {\n                    src: sourceDefinition\n                };\n            }\n            // Inserting of an inline image replace the selected element and make a selection on the inserted image.\n            // Therefore inserting multiple inline images requires creating position after each element.\n            if (index && selectedElement && imageUtils.isImage(selectedElement)) {\n                const position = this.editor.model.createPositionAfter(selectedElement);\n                imageUtils.insertImage({\n                    ...sourceDefinition,\n                    ...selectionAttributes\n                }, position, options.imageType);\n            } else {\n                imageUtils.insertImage({\n                    ...sourceDefinition,\n                    ...selectionAttributes\n                }, null, options.imageType);\n            }\n        });\n    }\n}\n\n/**\n * @module image/image/replaceimagesourcecommand\n */ /**\n * Replace image source command.\n *\n * Changes image source to the one provided. Can be executed as follows:\n *\n * ```ts\n * editor.execute( 'replaceImageSource', { source: 'http://url.to.the/image' } );\n * ```\n */ class ReplaceImageSourceCommand extends Command {\n    constructor(editor){\n        super(editor);\n        this.decorate('cleanupImage');\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const element = this.editor.model.document.selection.getSelectedElement();\n        this.isEnabled = imageUtils.isImage(element);\n        this.value = this.isEnabled ? element.getAttribute('src') : null;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.source The image source to replace.\n\t */ execute(options) {\n        const image = this.editor.model.document.selection.getSelectedElement();\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        this.editor.model.change((writer)=>{\n            writer.setAttribute('src', options.source, image);\n            this.cleanupImage(writer, image);\n            imageUtils.setImageNaturalSizeAttributes(image);\n        });\n    }\n    /**\n\t * Cleanup image attributes that are not relevant to the new source.\n\t *\n\t * Removed attributes are: 'srcset', 'sizes', 'sources', 'width', 'height', 'alt'.\n\t *\n\t * This method is decorated, to allow custom cleanup logic.\n\t * For example, to remove 'myImageId' attribute after 'src' has changed:\n\t *\n\t * ```ts\n\t * replaceImageSourceCommand.on( 'cleanupImage', ( eventInfo, [ writer, image ] ) => {\n\t * \twriter.removeAttribute( 'myImageId', image );\n\t * } );\n\t * ```\n\t */ cleanupImage(writer, image) {\n        writer.removeAttribute('srcset', image);\n        writer.removeAttribute('sizes', image);\n        /**\n\t\t * In case responsive images some attributes should be cleaned up.\n\t\t * Check: https://github.com/ckeditor/ckeditor5/issues/15093\n\t\t */ writer.removeAttribute('sources', image);\n        writer.removeAttribute('width', image);\n        writer.removeAttribute('height', image);\n        writer.removeAttribute('alt', image);\n    }\n}\n\n/**\n * The image engine plugin. This module loads common code shared between\n * {@link module:image/image/imageinlineediting~ImageInlineEditing} and\n * {@link module:image/image/imageblockediting~ImageBlockEditing} plugins.\n *\n * This plugin registers the {@link module:image/image/insertimagecommand~InsertImageCommand 'insertImage'} command.\n */ class ImageEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const conversion = editor.conversion;\n        // See https://github.com/ckeditor/ckeditor5-image/issues/142.\n        editor.editing.view.addObserver(ImageLoadObserver);\n        conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: 'img',\n                key: 'alt'\n            },\n            model: 'alt'\n        }).attributeToAttribute({\n            view: {\n                name: 'img',\n                key: 'srcset'\n            },\n            model: 'srcset'\n        });\n        const insertImageCommand = new InsertImageCommand(editor);\n        const replaceImageSourceCommand = new ReplaceImageSourceCommand(editor);\n        editor.commands.add('insertImage', insertImageCommand);\n        editor.commands.add('replaceImageSource', replaceImageSourceCommand);\n        // `imageInsert` is an alias for backward compatibility.\n        editor.commands.add('imageInsert', insertImageCommand);\n    }\n}\n\n/**\n * This plugin enables `width` and `height` attributes in inline and block image elements.\n */ class ImageSizeAttributes extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageSizeAttributes';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        this._registerSchema();\n        this._registerConverters('imageBlock');\n        this._registerConverters('imageInline');\n    }\n    /**\n\t * Registers the `width` and `height` attributes for inline and block images.\n\t */ _registerSchema() {\n        if (this.editor.plugins.has('ImageBlockEditing')) {\n            this.editor.model.schema.extend('imageBlock', {\n                allowAttributes: [\n                    'width',\n                    'height'\n                ]\n            });\n        }\n        if (this.editor.plugins.has('ImageInlineEditing')) {\n            this.editor.model.schema.extend('imageInline', {\n                allowAttributes: [\n                    'width',\n                    'height'\n                ]\n            });\n        }\n    }\n    /**\n\t * Registers converters for `width` and `height` attributes.\n\t */ _registerConverters(imageType) {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const viewElementName = imageType === 'imageBlock' ? 'figure' : 'img';\n        editor.conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: viewElementName,\n                styles: {\n                    width: /.+/\n                }\n            },\n            model: {\n                key: 'width',\n                value: (viewElement)=>{\n                    if (widthAndHeightStylesAreBothSet(viewElement)) {\n                        return getSizeValueIfInPx(viewElement.getStyle('width'));\n                    }\n                    return null;\n                }\n            }\n        }).attributeToAttribute({\n            view: {\n                name: viewElementName,\n                key: 'width'\n            },\n            model: 'width'\n        }).attributeToAttribute({\n            view: {\n                name: viewElementName,\n                styles: {\n                    height: /.+/\n                }\n            },\n            model: {\n                key: 'height',\n                value: (viewElement)=>{\n                    if (widthAndHeightStylesAreBothSet(viewElement)) {\n                        return getSizeValueIfInPx(viewElement.getStyle('height'));\n                    }\n                    return null;\n                }\n            }\n        }).attributeToAttribute({\n            view: {\n                name: viewElementName,\n                key: 'height'\n            },\n            model: 'height'\n        });\n        // Dedicated converters to propagate attributes to the <img> element.\n        editor.conversion.for('editingDowncast').add((dispatcher)=>{\n            attachDowncastConverter(dispatcher, 'width', 'width', true);\n            attachDowncastConverter(dispatcher, 'height', 'height', true);\n        });\n        editor.conversion.for('dataDowncast').add((dispatcher)=>{\n            attachDowncastConverter(dispatcher, 'width', 'width', false);\n            attachDowncastConverter(dispatcher, 'height', 'height', false);\n        });\n        function attachDowncastConverter(dispatcher, modelAttributeName, viewAttributeName, setRatioForInlineImage) {\n            dispatcher.on(`attribute:${modelAttributeName}:${imageType}`, (evt, data, conversionApi)=>{\n                if (!conversionApi.consumable.consume(data.item, evt.name)) {\n                    return;\n                }\n                const viewWriter = conversionApi.writer;\n                const viewElement = conversionApi.mapper.toViewElement(data.item);\n                const img = imageUtils.findViewImgElement(viewElement);\n                if (data.attributeNewValue !== null) {\n                    viewWriter.setAttribute(viewAttributeName, data.attributeNewValue, img);\n                } else {\n                    viewWriter.removeAttribute(viewAttributeName, img);\n                }\n                // Do not set aspect-ratio for pictures. See https://github.com/ckeditor/ckeditor5/issues/14579.\n                if (data.item.hasAttribute('sources')) {\n                    return;\n                }\n                const isResized = data.item.hasAttribute('resizedWidth');\n                // Do not set aspect ratio for inline images which are not resized (data pipeline).\n                if (imageType === 'imageInline' && !isResized && !setRatioForInlineImage) {\n                    return;\n                }\n                const width = data.item.getAttribute('width');\n                const height = data.item.getAttribute('height');\n                if (width && height) {\n                    viewWriter.setStyle('aspect-ratio', `${width}/${height}`, img);\n                }\n            });\n        }\n    }\n}\n\n/**\n * The image type command. It changes the type of a selected image, depending on the configuration.\n */ class ImageTypeCommand extends Command {\n    /**\n\t * Model element name the command converts to.\n\t */ _modelElementName;\n    /**\n\t * @inheritDoc\n\t *\n\t * @param modelElementName Model element name the command converts to.\n\t */ constructor(editor, modelElementName){\n        super(editor);\n        this._modelElementName = modelElementName;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const element = imageUtils.getClosestSelectedImageElement(this.editor.model.document.selection);\n        if (this._modelElementName === 'imageBlock') {\n            this.isEnabled = imageUtils.isInlineImage(element);\n        } else {\n            this.isEnabled = imageUtils.isBlockImage(element);\n        }\n    }\n    /**\n\t * Executes the command and changes the type of a selected image.\n\t *\n\t * @fires execute\n\t * @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.\n\t * The default is `true`.\n\t * @returns An object containing references to old and new model image elements\n\t * (for before and after the change) so external integrations can hook into the decorated\n\t * `execute` event and handle this change. `null` if the type change failed.\n\t */ execute(options = {}) {\n        const editor = this.editor;\n        const model = this.editor.model;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const oldElement = imageUtils.getClosestSelectedImageElement(model.document.selection);\n        const attributes = Object.fromEntries(oldElement.getAttributes());\n        // Don't change image type if \"src\" is missing (a broken image), unless there's \"uploadId\" set.\n        // This state may happen during image upload (before it finishes) and it should be possible to change type\n        // of the image in the meantime.\n        if (!attributes.src && !attributes.uploadId) {\n            return null;\n        }\n        return model.change((writer)=>{\n            const { setImageSizes = true } = options;\n            // Get all markers that contain the old image element.\n            const markers = Array.from(model.markers).filter((marker)=>marker.getRange().containsItem(oldElement));\n            const newElement = imageUtils.insertImage(attributes, model.createSelection(oldElement, 'on'), this._modelElementName, {\n                setImageSizes\n            });\n            if (!newElement) {\n                return null;\n            }\n            const newElementRange = writer.createRangeOn(newElement);\n            // Expand the previously intersecting markers' ranges to include the new image element.\n            for (const marker of markers){\n                const markerRange = marker.getRange();\n                // Join the survived part of the old marker range with the new element range\n                // (loosely because there could be some new paragraph or the existing one might got split).\n                const range = markerRange.root.rootName != '$graveyard' ? markerRange.getJoined(newElementRange, true) : newElementRange;\n                writer.updateMarker(marker, {\n                    range\n                });\n            }\n            return {\n                oldElement,\n                newElement\n            };\n        });\n    }\n}\n\n/**\n * Adds support for image placeholder that is automatically removed when the image is loaded.\n */ class ImagePlaceholder extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImagePlaceholder';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        this._setupSchema();\n        this._setupConversion();\n        this._setupLoadListener();\n    }\n    /**\n\t * Extends model schema.\n\t */ _setupSchema() {\n        const schema = this.editor.model.schema;\n        // Wait for ImageBlockEditing or ImageInlineEditing to register their elements first,\n        // that's why doing this in afterInit() instead of init().\n        if (schema.isRegistered('imageBlock')) {\n            schema.extend('imageBlock', {\n                allowAttributes: [\n                    'placeholder'\n                ]\n            });\n        }\n        if (schema.isRegistered('imageInline')) {\n            schema.extend('imageInline', {\n                allowAttributes: [\n                    'placeholder'\n                ]\n            });\n        }\n    }\n    /**\n\t * Registers converters.\n\t */ _setupConversion() {\n        const editor = this.editor;\n        const conversion = editor.conversion;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        conversion.for('editingDowncast').add((dispatcher)=>{\n            dispatcher.on('attribute:placeholder', (evt, data, conversionApi)=>{\n                if (!conversionApi.consumable.test(data.item, evt.name)) {\n                    return;\n                }\n                if (!data.item.is('element', 'imageBlock') && !data.item.is('element', 'imageInline')) {\n                    return;\n                }\n                conversionApi.consumable.consume(data.item, evt.name);\n                const viewWriter = conversionApi.writer;\n                const element = conversionApi.mapper.toViewElement(data.item);\n                const img = imageUtils.findViewImgElement(element);\n                if (data.attributeNewValue) {\n                    viewWriter.addClass('image_placeholder', img);\n                    viewWriter.setStyle('background-image', `url(${data.attributeNewValue})`, img);\n                    viewWriter.setCustomProperty('editingPipeline:doNotReuseOnce', true, img);\n                } else {\n                    viewWriter.removeClass('image_placeholder', img);\n                    viewWriter.removeStyle('background-image', img);\n                }\n            });\n        });\n    }\n    /**\n\t * Prepares listener for image load.\n\t */ _setupLoadListener() {\n        const editor = this.editor;\n        const model = editor.model;\n        const editing = editor.editing;\n        const editingView = editing.view;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        editingView.addObserver(ImageLoadObserver);\n        this.listenTo(editingView.document, 'imageLoaded', (evt, domEvent)=>{\n            const imgViewElement = editingView.domConverter.mapDomToView(domEvent.target);\n            if (!imgViewElement) {\n                return;\n            }\n            const viewElement = imageUtils.getImageWidgetFromImageView(imgViewElement);\n            if (!viewElement) {\n                return;\n            }\n            const modelElement = editing.mapper.toModelElement(viewElement);\n            if (!modelElement || !modelElement.hasAttribute('placeholder')) {\n                return;\n            }\n            model.enqueueChange({\n                isUndoable: false\n            }, (writer)=>{\n                writer.removeAttribute('placeholder', modelElement);\n            });\n        });\n    }\n}\n\n/**\n * The image block plugin.\n *\n * It registers:\n *\n * * `<imageBlock>` as a block element in the document schema, and allows `alt`, `src` and `srcset` attributes.\n * * converters for editing and data pipelines.,\n * * {@link module:image/image/imagetypecommand~ImageTypeCommand `'imageTypeBlock'`} command that converts inline images into\n * block images.\n */ class ImageBlockEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageEditing,\n            ImageSizeAttributes,\n            ImageUtils,\n            ImagePlaceholder,\n            ClipboardPipeline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageBlockEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        // Converters 'alt' and 'srcset' are added in 'ImageEditing' plugin.\n        schema.register('imageBlock', {\n            inheritAllFrom: '$blockObject',\n            allowAttributes: [\n                'alt',\n                'src',\n                'srcset'\n            ]\n        });\n        this._setupConversion();\n        if (editor.plugins.has('ImageInlineEditing')) {\n            editor.commands.add('imageTypeBlock', new ImageTypeCommand(this.editor, 'imageBlock'));\n            this._setupClipboardIntegration();\n        }\n    }\n    /**\n\t * Configures conversion pipelines to support upcasting and downcasting\n\t * block images (block image widgets) and their attributes.\n\t */ _setupConversion() {\n        const editor = this.editor;\n        const t = editor.t;\n        const conversion = editor.conversion;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        conversion.for('dataDowncast').elementToStructure({\n            model: 'imageBlock',\n            view: (modelElement, { writer })=>createBlockImageViewElement(writer)\n        });\n        conversion.for('editingDowncast').elementToStructure({\n            model: 'imageBlock',\n            view: (modelElement, { writer })=>imageUtils.toImageWidget(createBlockImageViewElement(writer), writer, t('image widget'))\n        });\n        conversion.for('downcast').add(downcastImageAttribute(imageUtils, 'imageBlock', 'src')).add(downcastImageAttribute(imageUtils, 'imageBlock', 'alt')).add(downcastSrcsetAttribute(imageUtils, 'imageBlock'));\n        // More image related upcasts are in 'ImageEditing' plugin.\n        conversion.for('upcast').elementToElement({\n            view: getImgViewElementMatcher(editor, 'imageBlock'),\n            model: (viewImage, { writer })=>writer.createElement('imageBlock', viewImage.hasAttribute('src') ? {\n                    src: viewImage.getAttribute('src')\n                } : undefined)\n        }).add(upcastImageFigure(imageUtils));\n    }\n    /**\n\t * Integrates the plugin with the clipboard pipeline.\n\t *\n\t * Idea is that the feature should recognize the user's intent when an **inline** image is\n\t * pasted or dropped. If such an image is pasted/dropped:\n\t *\n\t * * into an empty block (e.g. an empty paragraph),\n\t * * on another object (e.g. some block widget).\n\t *\n\t * it gets converted into a block image on the fly. We assume this is the user's intent\n\t * if they decided to put their image there.\n\t *\n\t * See the `ImageInlineEditing` for the similar integration that works in the opposite direction.\n\t *\n\t * The feature also sets image `width` and `height` attributes on paste.\n\t */ _setupClipboardIntegration() {\n        const editor = this.editor;\n        const model = editor.model;\n        const editingView = editor.editing.view;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        this.listenTo(clipboardPipeline, 'inputTransformation', (evt, data)=>{\n            const docFragmentChildren = Array.from(data.content.getChildren());\n            let modelRange;\n            // Make sure only <img> elements are dropped or pasted. Otherwise, if there some other HTML\n            // mixed up, this should be handled as a regular paste.\n            if (!docFragmentChildren.every(imageUtils.isInlineImageView)) {\n                return;\n            }\n            // When drag and dropping, data.targetRanges specifies where to drop because\n            // this is usually a different place than the current model selection (the user\n            // uses a drop marker to specify the drop location).\n            if (data.targetRanges) {\n                modelRange = editor.editing.mapper.toModelRange(data.targetRanges[0]);\n            } else {\n                modelRange = model.document.selection.getFirstRange();\n            }\n            const selection = model.createSelection(modelRange);\n            // Convert inline images into block images only when the currently selected block is empty\n            // (e.g. an empty paragraph) or some object is selected (to replace it).\n            if (determineImageTypeForInsertionAtSelection(model.schema, selection) === 'imageBlock') {\n                const writer = new UpcastWriter(editingView.document);\n                // Wrap <img ... /> -> <figure class=\"image\"><img .../></figure>\n                const blockViewImages = docFragmentChildren.map((inlineViewImage)=>writer.createElement('figure', {\n                        class: 'image'\n                    }, inlineViewImage));\n                data.content = writer.createDocumentFragment(blockViewImages);\n            }\n        });\n        this.listenTo(clipboardPipeline, 'contentInsertion', (evt, data)=>{\n            if (data.method !== 'paste') {\n                return;\n            }\n            model.change((writer)=>{\n                const range = writer.createRangeIn(data.content);\n                for (const item of range.getItems()){\n                    if (item.is('element', 'imageBlock')) {\n                        imageUtils.setImageNaturalSizeAttributes(item);\n                    }\n                }\n            });\n        });\n    }\n}\n\n/**\n * The view displayed in the insert image dropdown.\n *\n * See {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.\n */ class ImageInsertFormView extends View {\n    /**\n\t * Tracks information about DOM focus in the form.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * A collection of views that can be focused in the form.\n\t */ _focusables;\n    /**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */ _focusCycler;\n    /**\n\t * A collection of the defined integrations for inserting the images.\n\t */ children;\n    /**\n\t * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param integrations An integrations object that contains components (or tokens for components) to be shown in the panel view.\n\t */ constructor(locale, integrations = []){\n        super(locale);\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this._focusables = new ViewCollection();\n        this.children = this.createCollection();\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        for (const view of integrations){\n            this.children.add(view);\n            this._focusables.add(view);\n            if (view instanceof CollapsibleView) {\n                this._focusables.addMany(view.children);\n            }\n        }\n        this.setTemplate({\n            tag: 'form',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-image-insert-form'\n                ],\n                tabindex: -1\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        submitHandler({\n            view: this\n        });\n        for (const view of this._focusables){\n            this.focusTracker.add(view.element);\n        }\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n        const stopPropagation = (data)=>data.stopPropagation();\n        // Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n        // keystroke handler would take over the key management in the URL input. We need to prevent\n        // this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n        this.keystrokes.set('arrowright', stopPropagation);\n        this.keystrokes.set('arrowleft', stopPropagation);\n        this.keystrokes.set('arrowup', stopPropagation);\n        this.keystrokes.set('arrowdown', stopPropagation);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the first {@link #_focusables focusable} in the form.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n}\n\n/**\n * The image insert dropdown plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}\n * and {@glink features/images/images-inserting Insert images via source URL} documentation.\n *\n * Adds the `'insertImage'` dropdown to the {@link module:ui/componentfactory~ComponentFactory UI component factory}\n * and also the `imageInsert` dropdown as an alias for backward compatibility.\n *\n * Adds the `'menuBar:insertImage'` sub-menu to the {@link module:ui/componentfactory~ComponentFactory UI component factory}, which is\n * by default added to the `'Insert'` menu.\n */ class ImageInsertUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageInsertUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * The dropdown view responsible for displaying the image insert UI.\n\t */ dropdownView;\n    /**\n\t * Registered integrations map.\n\t */ _integrations = new Map();\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('image.insert.integrations', [\n            'upload',\n            'assetManager',\n            'url'\n        ]);\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        this.set('isImageSelected', false);\n        this.listenTo(editor.model.document, 'change', ()=>{\n            this.isImageSelected = imageUtils.isImage(selection.getSelectedElement());\n        });\n        const componentCreator = (locale)=>this._createToolbarComponent(locale);\n        const menuBarComponentCreator = (locale)=>this._createMenuBarComponent(locale);\n        // Register `insertImage` dropdown and add `imageInsert` dropdown as an alias for backward compatibility.\n        editor.ui.componentFactory.add('insertImage', componentCreator);\n        editor.ui.componentFactory.add('imageInsert', componentCreator);\n        editor.ui.componentFactory.add('menuBar:insertImage', menuBarComponentCreator);\n    }\n    /**\n\t * Registers the insert image dropdown integration.\n\t */ registerIntegration({ name, observable, buttonViewCreator, formViewCreator, menuBarButtonViewCreator, requiresForm = false }) {\n        if (this._integrations.has(name)) {\n            /**\n\t\t\t * There are two insert-image integrations registered with the same name.\n\t\t\t *\n\t\t\t * Make sure that you do not load multiple asset manager plugins.\n\t\t\t *\n\t\t\t * @error image-insert-integration-exists\n\t\t\t */ logWarning('image-insert-integration-exists', {\n                name\n            });\n        }\n        this._integrations.set(name, {\n            observable,\n            buttonViewCreator,\n            menuBarButtonViewCreator,\n            formViewCreator,\n            requiresForm\n        });\n    }\n    /**\n\t * Creates the toolbar component.\n\t */ _createToolbarComponent(locale) {\n        const editor = this.editor;\n        const t = locale.t;\n        const integrations = this._prepareIntegrations();\n        if (!integrations.length) {\n            return null;\n        }\n        let dropdownButton;\n        const firstIntegration = integrations[0];\n        if (integrations.length == 1) {\n            // Do not use dropdown for a single integration button (integration that does not require form view).\n            if (!firstIntegration.requiresForm) {\n                return firstIntegration.buttonViewCreator(true);\n            }\n            dropdownButton = firstIntegration.buttonViewCreator(true);\n        } else {\n            const actionButton = firstIntegration.buttonViewCreator(false);\n            dropdownButton = new SplitButtonView(locale, actionButton);\n            dropdownButton.tooltip = true;\n            dropdownButton.bind('label').to(this, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Replace image') : t('Insert image'));\n        }\n        const dropdownView = this.dropdownView = createDropdown(locale, dropdownButton);\n        const observables = integrations.map(({ observable })=>typeof observable == 'function' ? observable() : observable);\n        dropdownView.bind('isEnabled').toMany(observables, 'isEnabled', (...isEnabled)=>isEnabled.some((isEnabled)=>isEnabled));\n        dropdownView.once('change:isOpen', ()=>{\n            const integrationViews = integrations.map(({ formViewCreator })=>formViewCreator(integrations.length == 1));\n            const imageInsertFormView = new ImageInsertFormView(editor.locale, integrationViews);\n            dropdownView.panelView.children.add(imageInsertFormView);\n        });\n        return dropdownView;\n    }\n    /**\n\t * Creates the menu bar component.\n\t */ _createMenuBarComponent(locale) {\n        const t = locale.t;\n        const integrations = this._prepareIntegrations();\n        if (!integrations.length) {\n            return null;\n        }\n        let resultView;\n        const firstIntegration = integrations[0];\n        if (integrations.length == 1) {\n            resultView = firstIntegration.menuBarButtonViewCreator(true);\n        } else {\n            resultView = new MenuBarMenuView(locale);\n            const listView = new MenuBarMenuListView(locale);\n            resultView.panelView.children.add(listView);\n            resultView.buttonView.set({\n                icon: icons.image,\n                label: t('Image')\n            });\n            for (const integration of integrations){\n                const listItemView = new MenuBarMenuListItemView(locale, resultView);\n                const buttonView = integration.menuBarButtonViewCreator(false);\n                listItemView.children.add(buttonView);\n                listView.items.add(listItemView);\n            }\n        }\n        return resultView;\n    }\n    /**\n\t * Validates the integrations list.\n\t */ _prepareIntegrations() {\n        const editor = this.editor;\n        const items = editor.config.get('image.insert.integrations');\n        const result = [];\n        if (!items.length) {\n            /**\n\t\t\t * The insert image feature requires a list of integrations to be provided in the editor configuration.\n\t\t\t *\n\t\t\t * The default list of integrations is `upload`, `assetManager`, `url`. Those integrations are included\n\t\t\t * in the insert image dropdown if the given feature plugin is loaded. You should omit the `integrations`\n\t\t\t * configuration key to use the default set or provide a selected list of integrations that should be used.\n\t\t\t *\n\t\t\t * @error image-insert-integrations-not-specified\n\t\t\t */ logWarning('image-insert-integrations-not-specified');\n            return result;\n        }\n        for (const item of items){\n            if (!this._integrations.has(item)) {\n                if (![\n                    'upload',\n                    'assetManager',\n                    'url'\n                ].includes(item)) {\n                    /**\n\t\t\t\t\t * The specified insert image integration name is unknown or the providing plugin is not loaded in the editor.\n\t\t\t\t\t *\n\t\t\t\t\t * @error image-insert-unknown-integration\n\t\t\t\t\t */ logWarning('image-insert-unknown-integration', {\n                        item\n                    });\n                }\n                continue;\n            }\n            result.push(this._integrations.get(item));\n        }\n        if (!result.length) {\n            /**\n\t\t\t * The image insert feature requires integrations to be registered by separate features.\n\t\t\t *\n\t\t\t * The `insertImage` toolbar button requires integrations to be registered by other features.\n\t\t\t * For example {@link module:image/imageupload~ImageUpload ImageUpload},\n\t\t\t * {@link module:image/imageinsert~ImageInsert ImageInsert},\n\t\t\t * {@link module:image/imageinsertviaurl~ImageInsertViaUrl ImageInsertViaUrl},\n\t\t\t * {@link module:ckbox/ckbox~CKBox CKBox}\n\t\t\t *\n\t\t\t * @error image-insert-integrations-not-registered\n\t\t\t */ logWarning('image-insert-integrations-not-registered');\n        }\n        return result;\n    }\n}\n\n/**\n * The image block plugin.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/image/imageblockediting~ImageBlockEditing},\n * * {@link module:image/imagetextalternative~ImageTextAlternative}.\n *\n * Usually, it is used in conjunction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n */ class ImageBlock extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageBlockEditing,\n            Widget,\n            ImageTextAlternative,\n            ImageInsertUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageBlock';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The image inline plugin.\n *\n * It registers:\n *\n * * `<imageInline>` as an inline element in the document schema, and allows `alt`, `src` and `srcset` attributes.\n * * converters for editing and data pipelines.\n * * {@link module:image/image/imagetypecommand~ImageTypeCommand `'imageTypeInline'`} command that converts block images into\n * inline images.\n */ class ImageInlineEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageEditing,\n            ImageSizeAttributes,\n            ImageUtils,\n            ImagePlaceholder,\n            ClipboardPipeline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageInlineEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        // Converters 'alt' and 'srcset' are added in 'ImageEditing' plugin.\n        schema.register('imageInline', {\n            inheritAllFrom: '$inlineObject',\n            allowAttributes: [\n                'alt',\n                'src',\n                'srcset'\n            ],\n            // Disallow inline images in captions (at least for now).\n            // This is the best spot to do that because independent packages can introduce captions (ImageCaption, TableCaption, etc.).\n            disallowIn: [\n                'caption'\n            ]\n        });\n        this._setupConversion();\n        if (editor.plugins.has('ImageBlockEditing')) {\n            editor.commands.add('imageTypeInline', new ImageTypeCommand(this.editor, 'imageInline'));\n            this._setupClipboardIntegration();\n        }\n    }\n    /**\n\t * Configures conversion pipelines to support upcasting and downcasting\n\t * inline images (inline image widgets) and their attributes.\n\t */ _setupConversion() {\n        const editor = this.editor;\n        const t = editor.t;\n        const conversion = editor.conversion;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        conversion.for('dataDowncast').elementToElement({\n            model: 'imageInline',\n            view: (modelElement, { writer })=>writer.createEmptyElement('img')\n        });\n        conversion.for('editingDowncast').elementToStructure({\n            model: 'imageInline',\n            view: (modelElement, { writer })=>imageUtils.toImageWidget(createInlineImageViewElement(writer), writer, t('image widget'))\n        });\n        conversion.for('downcast').add(downcastImageAttribute(imageUtils, 'imageInline', 'src')).add(downcastImageAttribute(imageUtils, 'imageInline', 'alt')).add(downcastSrcsetAttribute(imageUtils, 'imageInline'));\n        // More image related upcasts are in 'ImageEditing' plugin.\n        conversion.for('upcast').elementToElement({\n            view: getImgViewElementMatcher(editor, 'imageInline'),\n            model: (viewImage, { writer })=>writer.createElement('imageInline', viewImage.hasAttribute('src') ? {\n                    src: viewImage.getAttribute('src')\n                } : undefined)\n        });\n    }\n    /**\n\t * Integrates the plugin with the clipboard pipeline.\n\t *\n\t * Idea is that the feature should recognize the user's intent when an **block** image is\n\t * pasted or dropped. If such an image is pasted/dropped into a non-empty block\n\t * (e.g. a paragraph with some text) it gets converted into an inline image on the fly.\n\t *\n\t * We assume this is the user's intent if they decided to put their image there.\n\t *\n\t * **Note**: If a block image has a caption, it will not be converted to an inline image\n\t * to avoid the confusion. Captions are added on purpose and they should never be lost\n\t * in the clipboard pipeline.\n\t *\n\t * See the `ImageBlockEditing` for the similar integration that works in the opposite direction.\n\t *\n\t * The feature also sets image `width` and `height` attributes when pasting.\n\t */ _setupClipboardIntegration() {\n        const editor = this.editor;\n        const model = editor.model;\n        const editingView = editor.editing.view;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        this.listenTo(clipboardPipeline, 'inputTransformation', (evt, data)=>{\n            const docFragmentChildren = Array.from(data.content.getChildren());\n            let modelRange;\n            // Make sure only <figure class=\"image\"></figure> elements are dropped or pasted. Otherwise, if there some other HTML\n            // mixed up, this should be handled as a regular paste.\n            if (!docFragmentChildren.every(imageUtils.isBlockImageView)) {\n                return;\n            }\n            // When drag and dropping, data.targetRanges specifies where to drop because\n            // this is usually a different place than the current model selection (the user\n            // uses a drop marker to specify the drop location).\n            if (data.targetRanges) {\n                modelRange = editor.editing.mapper.toModelRange(data.targetRanges[0]);\n            } else {\n                modelRange = model.document.selection.getFirstRange();\n            }\n            const selection = model.createSelection(modelRange);\n            // Convert block images into inline images only when pasting or dropping into non-empty blocks\n            // and when the block is not an object (e.g. pasting to replace another widget).\n            if (determineImageTypeForInsertionAtSelection(model.schema, selection) === 'imageInline') {\n                const writer = new UpcastWriter(editingView.document);\n                // Unwrap <figure class=\"image\"><img .../></figure> -> <img ... />\n                // but <figure class=\"image\"><img .../><figcaption>...</figcaption></figure> -> stays the same\n                const inlineViewImages = docFragmentChildren.map((blockViewImage)=>{\n                    // If there's just one child, it can be either <img /> or <a><img></a>.\n                    // If there are other children than <img>, this means that the block image\n                    // has a caption or some other features and this kind of image should be\n                    // pasted/dropped without modifications.\n                    if (blockViewImage.childCount === 1) {\n                        // Pass the attributes which are present only in the <figure> to the <img>\n                        // (e.g. the style=\"width:10%\" attribute applied by the ImageResize plugin).\n                        Array.from(blockViewImage.getAttributes()).forEach((attribute)=>writer.setAttribute(...attribute, imageUtils.findViewImgElement(blockViewImage)));\n                        return blockViewImage.getChild(0);\n                    } else {\n                        return blockViewImage;\n                    }\n                });\n                data.content = writer.createDocumentFragment(inlineViewImages);\n            }\n        });\n        this.listenTo(clipboardPipeline, 'contentInsertion', (evt, data)=>{\n            if (data.method !== 'paste') {\n                return;\n            }\n            model.change((writer)=>{\n                const range = writer.createRangeIn(data.content);\n                for (const item of range.getItems()){\n                    if (item.is('element', 'imageInline')) {\n                        imageUtils.setImageNaturalSizeAttributes(item);\n                    }\n                }\n            });\n        });\n    }\n}\n\n/**\n * The image inline plugin.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/image/imageinlineediting~ImageInlineEditing},\n * * {@link module:image/imagetextalternative~ImageTextAlternative}.\n *\n * Usually, it is used in conjunction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n */ class ImageInline extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageInlineEditing,\n            Widget,\n            ImageTextAlternative,\n            ImageInsertUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageInline';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The image plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-overview image feature} documentation.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/imageblock~ImageBlock},\n * * {@link module:image/imageinline~ImageInline},\n *\n * Usually, it is used in conjunction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n */ class Image extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageBlock,\n            ImageInline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Image';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The image caption utilities plugin.\n */ class ImageCaptionUtils extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageCaptionUtils';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * Returns the caption model element from a given image element. Returns `null` if no caption is found.\n\t */ getCaptionFromImageModelElement(imageModelElement) {\n        for (const node of imageModelElement.getChildren()){\n            if (!!node && node.is('element', 'caption')) {\n                return node;\n            }\n        }\n        return null;\n    }\n    /**\n\t * Returns the caption model element for a model selection. Returns `null` if the selection has no caption element ancestor.\n\t */ getCaptionFromModelSelection(selection) {\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        const captionElement = selection.getFirstPosition().findAncestor('caption');\n        if (!captionElement) {\n            return null;\n        }\n        if (imageUtils.isBlockImage(captionElement.parent)) {\n            return captionElement;\n        }\n        return null;\n    }\n    /**\n\t * {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a `<figcaption>` element that is placed\n\t * inside the image `<figure>` element.\n\t * @returns Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element\n\t * cannot be matched.\n\t */ matchImageCaptionViewElement(element) {\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        // Convert only captions for images.\n        if (element.name == 'figcaption' && imageUtils.isBlockImageView(element.parent)) {\n            return {\n                name: true\n            };\n        }\n        return null;\n    }\n}\n\n/**\n * The toggle image caption command.\n *\n * This command is registered by {@link module:image/imagecaption/imagecaptionediting~ImageCaptionEditing} as the\n * `'toggleImageCaption'` editor command.\n *\n * Executing this command:\n *\n * * either adds or removes the image caption of a selected image (depending on whether the caption is present or not),\n * * removes the image caption if the selection is anchored in one.\n *\n * ```ts\n * // Toggle the presence of the caption.\n * editor.execute( 'toggleImageCaption' );\n * ```\n *\n * **Note**: Upon executing this command, the selection will be set on the image if previously anchored in the caption element.\n *\n * **Note**: You can move the selection to the caption right away as it shows up upon executing this command by using\n * the `focusCaptionOnShow` option:\n *\n * ```ts\n * editor.execute( 'toggleImageCaption', { focusCaptionOnShow: true } );\n * ```\n */ class ToggleImageCaptionCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const imageCaptionUtils = editor.plugins.get('ImageCaptionUtils');\n        const imageUtils = editor.plugins.get('ImageUtils');\n        // Only block images can get captions.\n        if (!editor.plugins.has(ImageBlockEditing)) {\n            this.isEnabled = false;\n            this.value = false;\n            return;\n        }\n        const selection = editor.model.document.selection;\n        const selectedElement = selection.getSelectedElement();\n        if (!selectedElement) {\n            const ancestorCaptionElement = imageCaptionUtils.getCaptionFromModelSelection(selection);\n            this.isEnabled = !!ancestorCaptionElement;\n            this.value = !!ancestorCaptionElement;\n            return;\n        }\n        // Block images support captions by default but the command should also be enabled for inline\n        // images because toggling the caption when one is selected should convert it into a block image.\n        this.isEnabled = imageUtils.isImage(selectedElement);\n        if (!this.isEnabled) {\n            this.value = false;\n        } else {\n            this.value = !!imageCaptionUtils.getCaptionFromImageModelElement(selectedElement);\n        }\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * ```ts\n\t * editor.execute( 'toggleImageCaption' );\n\t * ```\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.focusCaptionOnShow When true and the caption shows up, the selection will be moved into it straight away.\n\t * @fires execute\n\t */ execute(options = {}) {\n        const { focusCaptionOnShow } = options;\n        this.editor.model.change((writer)=>{\n            if (this.value) {\n                this._hideImageCaption(writer);\n            } else {\n                this._showImageCaption(writer, focusCaptionOnShow);\n            }\n        });\n    }\n    /**\n\t * Shows the caption of the `<imageBlock>` or `<imageInline>`. Also:\n\t *\n\t * * it converts `<imageInline>` to `<imageBlock>` to show the caption,\n\t * * it attempts to restore the caption content from the `ImageCaptionEditing` caption registry,\n\t * * it moves the selection to the caption right away, it the `focusCaptionOnShow` option was set.\n\t */ _showImageCaption(writer, focusCaptionOnShow) {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const imageCaptionEditing = this.editor.plugins.get('ImageCaptionEditing');\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        let selectedImage = selection.getSelectedElement();\n        const savedCaption = imageCaptionEditing._getSavedCaption(selectedImage);\n        // Convert imageInline -> image first.\n        if (imageUtils.isInlineImage(selectedImage)) {\n            this.editor.execute('imageTypeBlock');\n            // Executing the command created a new model element. Let's pick it again.\n            selectedImage = selection.getSelectedElement();\n        }\n        // Try restoring the caption from the ImageCaptionEditing plugin storage.\n        const newCaptionElement = savedCaption || writer.createElement('caption');\n        writer.append(newCaptionElement, selectedImage);\n        if (focusCaptionOnShow) {\n            writer.setSelection(newCaptionElement, 'in');\n        }\n    }\n    /**\n\t * Hides the caption of a selected image (or an image caption the selection is anchored to).\n\t *\n\t * The content of the caption is stored in the `ImageCaptionEditing` caption registry to make this\n\t * a reversible action.\n\t */ _hideImageCaption(writer) {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const imageCaptionEditing = editor.plugins.get('ImageCaptionEditing');\n        const imageCaptionUtils = editor.plugins.get('ImageCaptionUtils');\n        let selectedImage = selection.getSelectedElement();\n        let captionElement;\n        if (selectedImage) {\n            captionElement = imageCaptionUtils.getCaptionFromImageModelElement(selectedImage);\n        } else {\n            captionElement = imageCaptionUtils.getCaptionFromModelSelection(selection);\n            selectedImage = captionElement.parent;\n        }\n        // Store the caption content so it can be restored quickly if the user changes their mind even if they toggle image<->imageInline.\n        imageCaptionEditing._saveCaption(selectedImage, captionElement);\n        writer.setSelection(selectedImage, 'on');\n        writer.remove(captionElement);\n    }\n}\n\n/**\n * The image caption engine plugin. It is responsible for:\n *\n * * registering converters for the caption element,\n * * registering converters for the caption model attribute,\n * * registering the {@link module:image/imagecaption/toggleimagecaptioncommand~ToggleImageCaptionCommand `toggleImageCaption`} command.\n */ class ImageCaptionEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils,\n            ImageCaptionUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageCaptionEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * A map that keeps saved JSONified image captions and image model elements they are\n\t * associated with.\n\t *\n\t * To learn more about this system, see {@link #_saveCaption}.\n\t */ _savedCaptionsMap;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._savedCaptionsMap = new WeakMap();\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        // Schema configuration.\n        if (!schema.isRegistered('caption')) {\n            schema.register('caption', {\n                allowIn: 'imageBlock',\n                allowContentOf: '$block',\n                isLimit: true\n            });\n        } else {\n            schema.extend('caption', {\n                allowIn: 'imageBlock'\n            });\n        }\n        editor.commands.add('toggleImageCaption', new ToggleImageCaptionCommand(this.editor));\n        this._setupConversion();\n        this._setupImageTypeCommandsIntegration();\n        this._registerCaptionReconversion();\n    }\n    /**\n\t * Configures conversion pipelines to support upcasting and downcasting\n\t * image captions.\n\t */ _setupConversion() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const imageCaptionUtils = editor.plugins.get('ImageCaptionUtils');\n        const t = editor.t;\n        // View -> model converter for the data pipeline.\n        editor.conversion.for('upcast').elementToElement({\n            view: (element)=>imageCaptionUtils.matchImageCaptionViewElement(element),\n            model: 'caption'\n        });\n        // Model -> view converter for the data pipeline.\n        editor.conversion.for('dataDowncast').elementToElement({\n            model: 'caption',\n            view: (modelElement, { writer })=>{\n                if (!imageUtils.isBlockImage(modelElement.parent)) {\n                    return null;\n                }\n                return writer.createContainerElement('figcaption');\n            }\n        });\n        // Model -> view converter for the editing pipeline.\n        editor.conversion.for('editingDowncast').elementToElement({\n            model: 'caption',\n            view: (modelElement, { writer })=>{\n                if (!imageUtils.isBlockImage(modelElement.parent)) {\n                    return null;\n                }\n                const figcaptionElement = writer.createEditableElement('figcaption');\n                writer.setCustomProperty('imageCaption', true, figcaptionElement);\n                figcaptionElement.placeholder = t('Enter image caption');\n                enablePlaceholder({\n                    view,\n                    element: figcaptionElement,\n                    keepOnFocus: true\n                });\n                const imageAlt = modelElement.parent.getAttribute('alt');\n                const label = imageAlt ? t('Caption for image: %0', [\n                    imageAlt\n                ]) : t('Caption for the image');\n                return toWidgetEditable(figcaptionElement, writer, {\n                    label\n                });\n            }\n        });\n    }\n    /**\n\t * Integrates with {@link module:image/image/imagetypecommand~ImageTypeCommand image type commands}\n\t * to make sure the caption is preserved when the type of an image changes so it can be restored\n\t * in the future if the user decides they want their caption back.\n\t */ _setupImageTypeCommandsIntegration() {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const imageCaptionUtils = editor.plugins.get('ImageCaptionUtils');\n        const imageTypeInlineCommand = editor.commands.get('imageTypeInline');\n        const imageTypeBlockCommand = editor.commands.get('imageTypeBlock');\n        const handleImageTypeChange = (evt)=>{\n            // The image type command execution can be unsuccessful.\n            if (!evt.return) {\n                return;\n            }\n            const { oldElement, newElement } = evt.return;\n            /* istanbul ignore if: paranoid check -- @preserve */ if (!oldElement) {\n                return;\n            }\n            if (imageUtils.isBlockImage(oldElement)) {\n                const oldCaptionElement = imageCaptionUtils.getCaptionFromImageModelElement(oldElement);\n                // If the old element was a captioned block image (the caption was visible),\n                // simply save it so it can be restored.\n                if (oldCaptionElement) {\n                    this._saveCaption(newElement, oldCaptionElement);\n                    return;\n                }\n            }\n            const savedOldElementCaption = this._getSavedCaption(oldElement);\n            // If either:\n            //\n            // * the block image didn't have a visible caption,\n            // * the block image caption was hidden (and already saved),\n            // * the inline image was passed\n            //\n            // just try to \"pass\" the saved caption from the old image to the new image\n            // so it can be retrieved in the future if the user wants it back.\n            if (savedOldElementCaption) {\n                // Note: Since we're writing to a WeakMap, we don't bother with removing the\n                // [ oldElement, savedOldElementCaption ] pair from it.\n                this._saveCaption(newElement, savedOldElementCaption);\n            }\n        };\n        // Presence of the commands depends on the Image(Inline|Block)Editing plugins loaded in the editor.\n        if (imageTypeInlineCommand) {\n            this.listenTo(imageTypeInlineCommand, 'execute', handleImageTypeChange, {\n                priority: 'low'\n            });\n        }\n        if (imageTypeBlockCommand) {\n            this.listenTo(imageTypeBlockCommand, 'execute', handleImageTypeChange, {\n                priority: 'low'\n            });\n        }\n    }\n    /**\n\t * Returns the saved {@link module:engine/model/element~Element#toJSON JSONified} caption\n\t * of an image model element.\n\t *\n\t * See {@link #_saveCaption}.\n\t *\n\t * @internal\n\t * @param imageModelElement The model element the caption should be returned for.\n\t * @returns The model caption element or `null` if there is none.\n\t */ _getSavedCaption(imageModelElement) {\n        const jsonObject = this._savedCaptionsMap.get(imageModelElement);\n        return jsonObject ? Element.fromJSON(jsonObject) : null;\n    }\n    /**\n\t * Saves a {@link module:engine/model/element~Element#toJSON JSONified} caption for\n\t * an image element to allow restoring it in the future.\n\t *\n\t * A caption is saved every time it gets hidden and/or the type of an image changes. The\n\t * user should be able to restore it on demand.\n\t *\n\t * **Note**: The caption cannot be stored in the image model element attribute because,\n\t * for instance, when the model state propagates to collaborators, the attribute would get\n\t * lost (mainly because it does not convert to anything when the caption is hidden) and\n\t * the states of collaborators' models would de-synchronize causing numerous issues.\n\t *\n\t * See {@link #_getSavedCaption}.\n\t *\n\t * @internal\n\t * @param imageModelElement The model element the caption is saved for.\n\t * @param caption The caption model element to be saved.\n\t */ _saveCaption(imageModelElement, caption) {\n        this._savedCaptionsMap.set(imageModelElement, caption.toJSON());\n    }\n    /**\n\t * Reconverts image caption when image alt attribute changes.\n\t * The change of alt attribute is reflected in caption's aria-label attribute.\n\t */ _registerCaptionReconversion() {\n        const editor = this.editor;\n        const model = editor.model;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const imageCaptionUtils = editor.plugins.get('ImageCaptionUtils');\n        model.document.on('change:data', ()=>{\n            const changes = model.document.differ.getChanges();\n            for (const change of changes){\n                if (change.attributeKey !== 'alt') {\n                    continue;\n                }\n                const image = change.range.start.nodeAfter;\n                if (imageUtils.isBlockImage(image)) {\n                    const caption = imageCaptionUtils.getCaptionFromImageModelElement(image);\n                    if (!caption) {\n                        return;\n                    }\n                    editor.editing.reconvertItem(caption);\n                }\n            }\n        });\n    }\n}\n\n/**\n * The image caption UI plugin. It introduces the `'toggleImageCaption'` UI button.\n */ class ImageCaptionUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageCaptionUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageCaptionUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const imageCaptionUtils = editor.plugins.get('ImageCaptionUtils');\n        const t = editor.t;\n        editor.ui.componentFactory.add('toggleImageCaption', (locale)=>{\n            const command = editor.commands.get('toggleImageCaption');\n            const view = new ButtonView(locale);\n            view.set({\n                icon: icons.caption,\n                tooltip: true,\n                isToggleable: true\n            });\n            view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n            view.bind('label').to(command, 'value', (value)=>value ? t('Toggle caption off') : t('Toggle caption on'));\n            this.listenTo(view, 'execute', ()=>{\n                editor.execute('toggleImageCaption', {\n                    focusCaptionOnShow: true\n                });\n                // Scroll to the selection and highlight the caption if the caption showed up.\n                const modelCaptionElement = imageCaptionUtils.getCaptionFromModelSelection(editor.model.document.selection);\n                if (modelCaptionElement) {\n                    const figcaptionElement = editor.editing.mapper.toViewElement(modelCaptionElement);\n                    editingView.scrollToTheSelection();\n                    editingView.change((writer)=>{\n                        writer.addClass('image__caption_highlighted', figcaptionElement);\n                    });\n                }\n                editor.editing.view.focus();\n            });\n            return view;\n        });\n    }\n}\n\n/**\n * The image caption plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-captions image caption} documentation.\n */ class ImageCaption extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageCaptionEditing,\n            ImageCaptionUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageCaption';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * Creates a regular expression used to test for image files.\n *\n * ```ts\n * const imageType = createImageTypeRegExp( [ 'png', 'jpeg', 'svg+xml', 'vnd.microsoft.icon' ] );\n *\n * console.log( 'is supported image', imageType.test( file.type ) );\n * ```\n */ function createImageTypeRegExp(types) {\n    // Sanitize the MIME type name which may include: \"+\", \"-\" or \".\".\n    const regExpSafeNames = types.map((type)=>type.replace('+', '\\\\+'));\n    return new RegExp(`^image\\\\/(${regExpSafeNames.join('|')})$`);\n}\n/**\n * Creates a promise that fetches the image local source (Base64 or blob) and resolves with a `File` object.\n *\n * @param image Image whose source to fetch.\n * @returns A promise which resolves when an image source is fetched and converted to a `File` instance.\n * It resolves with a `File` object. If there were any errors during file processing, the promise will be rejected.\n */ function fetchLocalImage(image) {\n    return new Promise((resolve, reject)=>{\n        const imageSrc = image.getAttribute('src');\n        // Fetch works asynchronously and so does not block browser UI when processing data.\n        fetch(imageSrc).then((resource)=>resource.blob()).then((blob)=>{\n            const mimeType = getImageMimeType(blob, imageSrc);\n            const ext = mimeType.replace('image/', '');\n            const filename = `image.${ext}`;\n            const file = new File([\n                blob\n            ], filename, {\n                type: mimeType\n            });\n            resolve(file);\n        }).catch((err)=>{\n            // Fetch fails only, if it can't make a request due to a network failure or if anything prevented the request\n            // from completing, i.e. the Content Security Policy rules. It is not possible to detect the exact cause of failure,\n            // so we are just trying the fallback solution, if general TypeError is thrown.\n            return err && err.name === 'TypeError' ? convertLocalImageOnCanvas(imageSrc).then(resolve).catch(reject) : reject(err);\n        });\n    });\n}\n/**\n * Checks whether a given node is an image element with a local source (Base64 or blob).\n *\n * @param node The node to check.\n */ function isLocalImage(imageUtils, node) {\n    if (!imageUtils.isInlineImageView(node) || !node.getAttribute('src')) {\n        return false;\n    }\n    return !!node.getAttribute('src').match(/^data:image\\/\\w+;base64,/g) || !!node.getAttribute('src').match(/^blob:/g);\n}\n/**\n * Extracts an image type based on its blob representation or its source.\n * @param blob Image blob representation.\n * @param src Image `src` attribute value.\n */ function getImageMimeType(blob, src) {\n    if (blob.type) {\n        return blob.type;\n    } else if (src.match(/data:(image\\/\\w+);base64/)) {\n        return src.match(/data:(image\\/\\w+);base64/)[1].toLowerCase();\n    } else {\n        // Fallback to 'jpeg' as common extension.\n        return 'image/jpeg';\n    }\n}\n/**\n * Creates a promise that converts the image local source (Base64 or blob) to a blob using canvas and resolves\n * with a `File` object.\n * @param imageSrc Image `src` attribute value.\n * @returns A promise which resolves when an image source is converted to a `File` instance.\n * It resolves with a `File` object. If there were any errors during file processing, the promise will be rejected.\n */ function convertLocalImageOnCanvas(imageSrc) {\n    return getBlobFromCanvas(imageSrc).then((blob)=>{\n        const mimeType = getImageMimeType(blob, imageSrc);\n        const ext = mimeType.replace('image/', '');\n        const filename = `image.${ext}`;\n        return new File([\n            blob\n        ], filename, {\n            type: mimeType\n        });\n    });\n}\n/**\n * Creates a promise that resolves with a `Blob` object converted from the image source (Base64 or blob).\n * @param imageSrc Image `src` attribute value.\n */ function getBlobFromCanvas(imageSrc) {\n    return new Promise((resolve, reject)=>{\n        const image = global.document.createElement('img');\n        image.addEventListener('load', ()=>{\n            const canvas = global.document.createElement('canvas');\n            canvas.width = image.width;\n            canvas.height = image.height;\n            const ctx = canvas.getContext('2d');\n            ctx.drawImage(image, 0, 0);\n            canvas.toBlob((blob)=>blob ? resolve(blob) : reject());\n        });\n        image.addEventListener('error', ()=>reject());\n        image.src = imageSrc;\n    });\n}\n\n/**\n * The image upload button plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature} documentation.\n *\n * Adds the `'uploadImage'` button to the {@link module:ui/componentfactory~ComponentFactory UI component factory}\n * and also the `imageUpload` button as an alias for backward compatibility.\n *\n * Adds the `'menuBar:uploadImage'` menu button to the {@link module:ui/componentfactory~ComponentFactory UI component factory}.\n *\n * It also integrates with the `insertImage` toolbar component and `menuBar:insertImage` menu component, which are the default components\n * through which image upload is available.\n */ class ImageUploadUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageUploadUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Setup `uploadImage` button and add `imageUpload` button as an alias for backward compatibility.\n        editor.ui.componentFactory.add('uploadImage', ()=>this._createToolbarButton());\n        editor.ui.componentFactory.add('imageUpload', ()=>this._createToolbarButton());\n        editor.ui.componentFactory.add('menuBar:uploadImage', ()=>this._createMenuBarButton('standalone'));\n        if (editor.plugins.has('ImageInsertUI')) {\n            editor.plugins.get('ImageInsertUI').registerIntegration({\n                name: 'upload',\n                observable: ()=>editor.commands.get('uploadImage'),\n                buttonViewCreator: ()=>this._createToolbarButton(),\n                formViewCreator: ()=>this._createDropdownButton(),\n                menuBarButtonViewCreator: (isOnly)=>this._createMenuBarButton(isOnly ? 'insertOnly' : 'insertNested')\n            });\n        }\n    }\n    /**\n\t * Creates the base for various kinds of the button component provided by this feature.\n\t */ _createButton(ButtonClass) {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const command = editor.commands.get('uploadImage');\n        const imageTypes = editor.config.get('image.upload.types');\n        const imageTypesRegExp = createImageTypeRegExp(imageTypes);\n        const view = new ButtonClass(editor.locale);\n        const t = locale.t;\n        view.set({\n            acceptedType: imageTypes.map((type)=>`image/${type}`).join(','),\n            allowMultipleFiles: true,\n            label: t('Upload from computer'),\n            icon: icons.imageUpload\n        });\n        view.bind('isEnabled').to(command);\n        view.on('done', (evt, files)=>{\n            const imagesToUpload = Array.from(files).filter((file)=>imageTypesRegExp.test(file.type));\n            if (imagesToUpload.length) {\n                editor.execute('uploadImage', {\n                    file: imagesToUpload\n                });\n                editor.editing.view.focus();\n            }\n        });\n        return view;\n    }\n    /**\n\t * Creates a simple toolbar button, with an icon and a tooltip.\n\t */ _createToolbarButton() {\n        const t = this.editor.locale.t;\n        const imageInsertUI = this.editor.plugins.get('ImageInsertUI');\n        const uploadImageCommand = this.editor.commands.get('uploadImage');\n        const button = this._createButton(FileDialogButtonView);\n        button.tooltip = true;\n        button.bind('label').to(imageInsertUI, 'isImageSelected', uploadImageCommand, 'isAccessAllowed', (isImageSelected, isAccessAllowed)=>{\n            if (!isAccessAllowed) {\n                return t('You have no image upload permissions.');\n            }\n            return isImageSelected ? t('Replace image from computer') : t('Upload image from computer');\n        });\n        return button;\n    }\n    /**\n\t * Creates a button for the dropdown view, with an icon, text and no tooltip.\n\t */ _createDropdownButton() {\n        const t = this.editor.locale.t;\n        const imageInsertUI = this.editor.plugins.get('ImageInsertUI');\n        const button = this._createButton(FileDialogButtonView);\n        button.withText = true;\n        button.bind('label').to(imageInsertUI, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Replace from computer') : t('Upload from computer'));\n        button.on('execute', ()=>{\n            imageInsertUI.dropdownView.isOpen = false;\n        });\n        return button;\n    }\n    /**\n\t * Creates a button for the menu bar.\n\t */ _createMenuBarButton(type) {\n        const t = this.editor.locale.t;\n        const button = this._createButton(MenuBarMenuListItemFileDialogButtonView);\n        button.withText = true;\n        switch(type){\n            case 'standalone':\n                button.label = t('Image from computer');\n                break;\n            case 'insertOnly':\n                button.label = t('Image');\n                break;\n            case 'insertNested':\n                button.label = t('From computer');\n                break;\n        }\n        return button;\n    }\n}\n\n/**\n * The image upload progress plugin.\n * It shows a placeholder when the image is read from the disk and a progress bar while the image is uploading.\n */ class ImageUploadProgress extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageUploadProgress';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * The image placeholder that is displayed before real image data can be accessed.\n\t *\n\t * For the record, this image is a 1x1 px GIF with an aspect ratio set by CSS.\n\t */ placeholder;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this.placeholder = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Upload status change - update image's view according to that status.\n        if (editor.plugins.has('ImageBlockEditing')) {\n            editor.editing.downcastDispatcher.on('attribute:uploadStatus:imageBlock', this.uploadStatusChange);\n        }\n        if (editor.plugins.has('ImageInlineEditing')) {\n            editor.editing.downcastDispatcher.on('attribute:uploadStatus:imageInline', this.uploadStatusChange);\n        }\n    }\n    /**\n\t * This method is called each time the image `uploadStatus` attribute is changed.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param data Additional information about the change.\n\t */ uploadStatusChange = (evt, data, conversionApi)=>{\n        const editor = this.editor;\n        const modelImage = data.item;\n        const uploadId = modelImage.getAttribute('uploadId');\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const fileRepository = editor.plugins.get(FileRepository);\n        const status = uploadId ? data.attributeNewValue : null;\n        const placeholder = this.placeholder;\n        const viewFigure = editor.editing.mapper.toViewElement(modelImage);\n        const viewWriter = conversionApi.writer;\n        if (status == 'reading') {\n            // Start \"appearing\" effect and show placeholder with infinite progress bar on the top\n            // while image is read from disk.\n            _startAppearEffect(viewFigure, viewWriter);\n            _showPlaceholder(imageUtils, placeholder, viewFigure, viewWriter);\n            return;\n        }\n        // Show progress bar on the top of the image when image is uploading.\n        if (status == 'uploading') {\n            const loader = fileRepository.loaders.get(uploadId);\n            // Start appear effect if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n            _startAppearEffect(viewFigure, viewWriter);\n            if (!loader) {\n                // There is no loader associated with uploadId - this means that image came from external changes.\n                // In such cases we still want to show the placeholder until image is fully uploaded.\n                // Show placeholder if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n                _showPlaceholder(imageUtils, placeholder, viewFigure, viewWriter);\n            } else {\n                // Hide placeholder and initialize progress bar showing upload progress.\n                _hidePlaceholder(viewFigure, viewWriter);\n                _showProgressBar(viewFigure, viewWriter, loader, editor.editing.view);\n                _displayLocalImage(imageUtils, viewFigure, viewWriter, loader);\n            }\n            return;\n        }\n        if (status == 'complete' && fileRepository.loaders.get(uploadId)) {\n            _showCompleteIcon(viewFigure, viewWriter, editor.editing.view);\n        }\n        // Clean up.\n        _hideProgressBar(viewFigure, viewWriter);\n        _hidePlaceholder(viewFigure, viewWriter);\n        _stopAppearEffect(viewFigure, viewWriter);\n    };\n}\n/**\n * Adds ck-appear class to the image figure if one is not already applied.\n */ function _startAppearEffect(viewFigure, writer) {\n    if (!viewFigure.hasClass('ck-appear')) {\n        writer.addClass('ck-appear', viewFigure);\n    }\n}\n/**\n * Removes ck-appear class to the image figure if one is not already removed.\n */ function _stopAppearEffect(viewFigure, writer) {\n    writer.removeClass('ck-appear', viewFigure);\n}\n/**\n * Shows placeholder together with infinite progress bar on given image figure.\n */ function _showPlaceholder(imageUtils, placeholder, viewFigure, writer) {\n    if (!viewFigure.hasClass('ck-image-upload-placeholder')) {\n        writer.addClass('ck-image-upload-placeholder', viewFigure);\n    }\n    const viewImg = imageUtils.findViewImgElement(viewFigure);\n    if (viewImg.getAttribute('src') !== placeholder) {\n        writer.setAttribute('src', placeholder, viewImg);\n    }\n    if (!_getUIElement(viewFigure, 'placeholder')) {\n        writer.insert(writer.createPositionAfter(viewImg), _createPlaceholder(writer));\n    }\n}\n/**\n * Removes placeholder together with infinite progress bar on given image figure.\n */ function _hidePlaceholder(viewFigure, writer) {\n    if (viewFigure.hasClass('ck-image-upload-placeholder')) {\n        writer.removeClass('ck-image-upload-placeholder', viewFigure);\n    }\n    _removeUIElement(viewFigure, writer, 'placeholder');\n}\n/**\n * Shows progress bar displaying upload progress.\n * Attaches it to the file loader to update when upload percentace is changed.\n */ function _showProgressBar(viewFigure, writer, loader, view) {\n    const progressBar = _createProgressBar(writer);\n    writer.insert(writer.createPositionAt(viewFigure, 'end'), progressBar);\n    // Update progress bar width when uploadedPercent is changed.\n    loader.on('change:uploadedPercent', (evt, name, value)=>{\n        view.change((writer)=>{\n            writer.setStyle('width', value + '%', progressBar);\n        });\n    });\n}\n/**\n * Hides upload progress bar.\n */ function _hideProgressBar(viewFigure, writer) {\n    _removeUIElement(viewFigure, writer, 'progressBar');\n}\n/**\n * Shows complete icon and hides after a certain amount of time.\n */ function _showCompleteIcon(viewFigure, writer, view) {\n    const completeIcon = writer.createUIElement('div', {\n        class: 'ck-image-upload-complete-icon'\n    });\n    writer.insert(writer.createPositionAt(viewFigure, 'end'), completeIcon);\n    setTimeout(()=>{\n        view.change((writer)=>writer.remove(writer.createRangeOn(completeIcon)));\n    }, 3000);\n}\n/**\n * Create progress bar element using {@link module:engine/view/uielement~UIElement}.\n */ function _createProgressBar(writer) {\n    const progressBar = writer.createUIElement('div', {\n        class: 'ck-progress-bar'\n    });\n    writer.setCustomProperty('progressBar', true, progressBar);\n    return progressBar;\n}\n/**\n * Create placeholder element using {@link module:engine/view/uielement~UIElement}.\n */ function _createPlaceholder(writer) {\n    const placeholder = writer.createUIElement('div', {\n        class: 'ck-upload-placeholder-loader'\n    });\n    writer.setCustomProperty('placeholder', true, placeholder);\n    return placeholder;\n}\n/**\n * Returns {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n * Returns `undefined` if element is not found.\n */ function _getUIElement(imageFigure, uniqueProperty) {\n    for (const child of imageFigure.getChildren()){\n        if (child.getCustomProperty(uniqueProperty)) {\n            return child;\n        }\n    }\n}\n/**\n * Removes {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n */ function _removeUIElement(viewFigure, writer, uniqueProperty) {\n    const element = _getUIElement(viewFigure, uniqueProperty);\n    if (element) {\n        writer.remove(writer.createRangeOn(element));\n    }\n}\n/**\n * Displays local data from file loader.\n */ function _displayLocalImage(imageUtils, viewFigure, writer, loader) {\n    if (loader.data) {\n        const viewImg = imageUtils.findViewImgElement(viewFigure);\n        writer.setAttribute('src', loader.data, viewImg);\n    }\n}\n\n/**\n * @module image/imageupload/uploadimagecommand\n */ /**\n * The upload image command.\n *\n * The command is registered by the {@link module:image/imageupload/imageuploadediting~ImageUploadEditing} plugin as `uploadImage`\n * and it is also available via aliased `imageUpload` name.\n *\n * In order to upload an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionRange} algorithm),\n * execute the command and pass the native image file instance:\n *\n * ```ts\n * this.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {\n * \t// Assuming that only images were pasted:\n * \tconst images = Array.from( data.dataTransfer.files );\n *\n * \t// Upload the first image:\n * \teditor.execute( 'uploadImage', { file: images[ 0 ] } );\n * } );\n * ```\n *\n * It is also possible to insert multiple images at once:\n *\n * ```ts\n * editor.execute( 'uploadImage', {\n * \tfile: [\n * \t\tfile1,\n * \t\tfile2\n * \t]\n * } );\n * ```\n */ class UploadImageCommand extends Command {\n    /**\n\t * Creates an instance of the `imageUlpoad` command. When executed, the command upload one of\n\t * the currently selected image from computer.\n\t *\n\t * @param editor The editor instance.\n\t */ constructor(editor){\n        super(editor);\n        this.set('isAccessAllowed', true);\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const selectedElement = editor.model.document.selection.getSelectedElement();\n        // TODO: This needs refactoring.\n        this.isEnabled = imageUtils.isImageAllowed() || imageUtils.isImage(selectedElement);\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.file The image file or an array of image files to upload.\n\t */ execute(options) {\n        const files = toArray(options.file);\n        const selection = this.editor.model.document.selection;\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        // In case of multiple files, each file (starting from the 2nd) will be inserted at a position that\n        // follows the previous one. That will move the selection and, to stay on the safe side and make sure\n        // all images inherit the same selection attributes, they are collected beforehand.\n        //\n        // Applying these attributes ensures, for instance, that inserting an (inline) image into a link does\n        // not split that link but preserves its continuity.\n        //\n        // Note: Selection attributes that do not make sense for images will be filtered out by insertImage() anyway.\n        const selectionAttributes = Object.fromEntries(selection.getAttributes());\n        files.forEach((file, index)=>{\n            const selectedElement = selection.getSelectedElement();\n            // Inserting of an inline image replace the selected element and make a selection on the inserted image.\n            // Therefore inserting multiple inline images requires creating position after each element.\n            if (index && selectedElement && imageUtils.isImage(selectedElement)) {\n                const position = this.editor.model.createPositionAfter(selectedElement);\n                this._uploadImage(file, selectionAttributes, position);\n            } else {\n                this._uploadImage(file, selectionAttributes);\n            }\n        });\n    }\n    /**\n\t * Handles uploading single file.\n\t */ _uploadImage(file, attributes, position) {\n        const editor = this.editor;\n        const fileRepository = editor.plugins.get(FileRepository);\n        const loader = fileRepository.createLoader(file);\n        const imageUtils = editor.plugins.get('ImageUtils');\n        // Do not throw when upload adapter is not set. FileRepository will log an error anyway.\n        if (!loader) {\n            return;\n        }\n        imageUtils.insertImage({\n            ...attributes,\n            uploadId: loader.id\n        }, position);\n    }\n}\n\n/**\n * The editing part of the image upload feature. It registers the `'uploadImage'` command\n * and the `imageUpload` command as an aliased name.\n *\n * When an image is uploaded, it fires the {@link ~ImageUploadEditing#event:uploadComplete `uploadComplete`} event\n * that allows adding custom attributes to the {@link module:engine/model/element~Element image element}.\n */ class ImageUploadEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            FileRepository,\n            Notification,\n            ClipboardPipeline,\n            ImageUtils\n        ];\n    }\n    static get pluginName() {\n        return 'ImageUploadEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * An internal mapping of {@link module:upload/filerepository~FileLoader#id file loader UIDs} and\n\t * model elements during the upload.\n\t *\n\t * Model element of the uploaded image can change, for instance, when {@link module:image/image/imagetypecommand~ImageTypeCommand}\n\t * is executed as a result of adding caption or changing image style. As a result, the upload logic must keep track of the model\n\t * element (reference) and resolve the upload for the correct model element (instead of the one that landed in the `$graveyard`\n\t * after image type changed).\n\t */ _uploadImageElements;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('image', {\n            upload: {\n                types: [\n                    'jpeg',\n                    'png',\n                    'gif',\n                    'bmp',\n                    'webp',\n                    'tiff'\n                ]\n            }\n        });\n        this._uploadImageElements = new Map();\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const doc = editor.model.document;\n        const conversion = editor.conversion;\n        const fileRepository = editor.plugins.get(FileRepository);\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        const imageTypes = createImageTypeRegExp(editor.config.get('image.upload.types'));\n        const uploadImageCommand = new UploadImageCommand(editor);\n        // Register `uploadImage` command and add `imageUpload` command as an alias for backward compatibility.\n        editor.commands.add('uploadImage', uploadImageCommand);\n        editor.commands.add('imageUpload', uploadImageCommand);\n        // Register upcast converter for uploadId.\n        conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: 'img',\n                key: 'uploadId'\n            },\n            model: 'uploadId'\n        });\n        // Handle pasted images.\n        // For every image file, a new file loader is created and a placeholder image is\n        // inserted into the content. Then, those images are uploaded once they appear in the model\n        // (see Document#change listener below).\n        this.listenTo(editor.editing.view.document, 'clipboardInput', (evt, data)=>{\n            // Skip if non empty HTML data is included.\n            // https://github.com/ckeditor/ckeditor5-upload/issues/68\n            if (isHtmlIncluded(data.dataTransfer)) {\n                return;\n            }\n            const images = Array.from(data.dataTransfer.files).filter((file)=>{\n                // See https://github.com/ckeditor/ckeditor5-image/pull/254.\n                if (!file) {\n                    return false;\n                }\n                return imageTypes.test(file.type);\n            });\n            if (!images.length) {\n                return;\n            }\n            evt.stop();\n            editor.model.change((writer)=>{\n                // Set selection to paste target.\n                if (data.targetRanges) {\n                    writer.setSelection(data.targetRanges.map((viewRange)=>editor.editing.mapper.toModelRange(viewRange)));\n                }\n                editor.execute('uploadImage', {\n                    file: images\n                });\n            });\n            const uploadImageCommand = editor.commands.get('uploadImage');\n            if (!uploadImageCommand.isAccessAllowed) {\n                const notification = editor.plugins.get('Notification');\n                const t = editor.locale.t;\n                // eslint-disable-next-line max-len\n                notification.showWarning(t('You have no image upload permissions.'), {\n                    namespace: 'image'\n                });\n            }\n        });\n        // Handle HTML pasted with images with base64 or blob sources.\n        // For every image file, a new file loader is created and a placeholder image is\n        // inserted into the content. Then, those images are uploaded once they appear in the model\n        // (see Document#change listener below).\n        this.listenTo(clipboardPipeline, 'inputTransformation', (evt, data)=>{\n            const fetchableImages = Array.from(editor.editing.view.createRangeIn(data.content)).map((value)=>value.item).filter((viewElement)=>isLocalImage(imageUtils, viewElement) && !viewElement.getAttribute('uploadProcessed')).map((viewElement)=>{\n                return {\n                    promise: fetchLocalImage(viewElement),\n                    imageElement: viewElement\n                };\n            });\n            if (!fetchableImages.length) {\n                return;\n            }\n            const writer = new UpcastWriter(editor.editing.view.document);\n            for (const fetchableImage of fetchableImages){\n                // Set attribute marking that the image was processed already.\n                writer.setAttribute('uploadProcessed', true, fetchableImage.imageElement);\n                const loader = fileRepository.createLoader(fetchableImage.promise);\n                if (loader) {\n                    writer.setAttribute('src', '', fetchableImage.imageElement);\n                    writer.setAttribute('uploadId', loader.id, fetchableImage.imageElement);\n                }\n            }\n        });\n        // Prevents from the browser redirecting to the dropped image.\n        editor.editing.view.document.on('dragover', (evt, data)=>{\n            data.preventDefault();\n        });\n        // Upload placeholder images that appeared in the model.\n        doc.on('change', ()=>{\n            // Note: Reversing changes to start with insertions and only then handle removals. If it was the other way around,\n            // loaders for **all** images that land in the $graveyard would abort while in fact only those that were **not** replaced\n            // by other images should be aborted.\n            const changes = doc.differ.getChanges({\n                includeChangesInGraveyard: true\n            }).reverse();\n            const insertedImagesIds = new Set();\n            for (const entry of changes){\n                if (entry.type == 'insert' && entry.name != '$text') {\n                    const item = entry.position.nodeAfter;\n                    const isInsertedInGraveyard = entry.position.root.rootName == '$graveyard';\n                    for (const imageElement of getImagesFromChangeItem(editor, item)){\n                        // Check if the image element still has upload id.\n                        const uploadId = imageElement.getAttribute('uploadId');\n                        if (!uploadId) {\n                            continue;\n                        }\n                        // Check if the image is loaded on this client.\n                        const loader = fileRepository.loaders.get(uploadId);\n                        if (!loader) {\n                            continue;\n                        }\n                        if (isInsertedInGraveyard) {\n                            // If the image was inserted to the graveyard for good (**not** replaced by another image),\n                            // only then abort the loading process.\n                            if (!insertedImagesIds.has(uploadId)) {\n                                loader.abort();\n                            }\n                        } else {\n                            // Remember the upload id of the inserted image. If it acted as a replacement for another\n                            // image (which landed in the $graveyard), the related loader will not be aborted because\n                            // this is still the same image upload.\n                            insertedImagesIds.add(uploadId);\n                            // Keep the mapping between the upload ID and the image model element so the upload\n                            // can later resolve in the context of the correct model element. The model element could\n                            // change for the same upload if one image was replaced by another (e.g. image type was changed),\n                            // so this may also replace an existing mapping.\n                            this._uploadImageElements.set(uploadId, imageElement);\n                            if (loader.status == 'idle') {\n                                // If the image was inserted into content and has not been loaded yet, start loading it.\n                                this._readAndUpload(loader);\n                            }\n                        }\n                    }\n                }\n            }\n        });\n        // Set the default handler for feeding the image element with `src` and `srcset` attributes.\n        // Also set the natural `width` and `height` attributes (if not already set).\n        this.on('uploadComplete', (evt, { imageElement, data })=>{\n            const urls = data.urls ? data.urls : data;\n            this.editor.model.change((writer)=>{\n                writer.setAttribute('src', urls.default, imageElement);\n                this._parseAndSetSrcsetAttributeOnImage(urls, imageElement, writer);\n                imageUtils.setImageNaturalSizeAttributes(imageElement);\n            });\n        }, {\n            priority: 'low'\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const schema = this.editor.model.schema;\n        // Setup schema to allow uploadId and uploadStatus for images.\n        // Wait for ImageBlockEditing or ImageInlineEditing to register their elements first,\n        // that's why doing this in afterInit() instead of init().\n        if (this.editor.plugins.has('ImageBlockEditing')) {\n            schema.extend('imageBlock', {\n                allowAttributes: [\n                    'uploadId',\n                    'uploadStatus'\n                ]\n            });\n        }\n        if (this.editor.plugins.has('ImageInlineEditing')) {\n            schema.extend('imageInline', {\n                allowAttributes: [\n                    'uploadId',\n                    'uploadStatus'\n                ]\n            });\n        }\n    }\n    /**\n\t * Reads and uploads an image.\n\t *\n\t * The image is read from the disk and as a Base64-encoded string it is set temporarily to\n\t * `image[src]`. When the image is successfully uploaded, the temporary data is replaced with the target\n\t * image's URL (the URL to the uploaded image on the server).\n\t */ _readAndUpload(loader) {\n        const editor = this.editor;\n        const model = editor.model;\n        const t = editor.locale.t;\n        const fileRepository = editor.plugins.get(FileRepository);\n        const notification = editor.plugins.get(Notification);\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const imageUploadElements = this._uploadImageElements;\n        model.enqueueChange({\n            isUndoable: false\n        }, (writer)=>{\n            writer.setAttribute('uploadStatus', 'reading', imageUploadElements.get(loader.id));\n        });\n        return loader.read().then(()=>{\n            const promise = loader.upload();\n            const imageElement = imageUploadElements.get(loader.id);\n            // Force re–paint in Safari. Without it, the image will display with a wrong size.\n            // https://github.com/ckeditor/ckeditor5/issues/1975\n            /* istanbul ignore next -- @preserve */ if (env.isSafari) {\n                const viewFigure = editor.editing.mapper.toViewElement(imageElement);\n                const viewImg = imageUtils.findViewImgElement(viewFigure);\n                editor.editing.view.once('render', ()=>{\n                    // Early returns just to be safe. There might be some code ran\n                    // in between the outer scope and this callback.\n                    if (!viewImg.parent) {\n                        return;\n                    }\n                    const domFigure = editor.editing.view.domConverter.mapViewToDom(viewImg.parent);\n                    if (!domFigure) {\n                        return;\n                    }\n                    const originalDisplay = domFigure.style.display;\n                    domFigure.style.display = 'none';\n                    // Make sure this line will never be removed during minification for having \"no effect\".\n                    domFigure._ckHack = domFigure.offsetHeight;\n                    domFigure.style.display = originalDisplay;\n                });\n            }\n            if (editor.ui) {\n                editor.ui.ariaLiveAnnouncer.announce(t('Uploading image'));\n            }\n            model.enqueueChange({\n                isUndoable: false\n            }, (writer)=>{\n                writer.setAttribute('uploadStatus', 'uploading', imageElement);\n            });\n            return promise;\n        }).then((data)=>{\n            model.enqueueChange({\n                isUndoable: false\n            }, (writer)=>{\n                const imageElement = imageUploadElements.get(loader.id);\n                writer.setAttribute('uploadStatus', 'complete', imageElement);\n                if (editor.ui) {\n                    editor.ui.ariaLiveAnnouncer.announce(t('Image upload complete'));\n                }\n                this.fire('uploadComplete', {\n                    data,\n                    imageElement\n                });\n            });\n            clean();\n        }).catch((error)=>{\n            if (editor.ui) {\n                editor.ui.ariaLiveAnnouncer.announce(t('Error during image upload'));\n            }\n            // If status is not 'error' nor 'aborted' - throw error because it means that something else went wrong,\n            // it might be generic error and it would be real pain to find what is going on.\n            if (loader.status !== 'error' && loader.status !== 'aborted') {\n                throw error;\n            }\n            // Might be 'aborted'.\n            if (loader.status == 'error' && error) {\n                notification.showWarning(error, {\n                    title: t('Upload failed'),\n                    namespace: 'upload'\n                });\n            }\n            // Permanently remove image from insertion batch.\n            model.enqueueChange({\n                isUndoable: false\n            }, (writer)=>{\n                writer.remove(imageUploadElements.get(loader.id));\n            });\n            clean();\n        });\n        function clean() {\n            model.enqueueChange({\n                isUndoable: false\n            }, (writer)=>{\n                const imageElement = imageUploadElements.get(loader.id);\n                writer.removeAttribute('uploadId', imageElement);\n                writer.removeAttribute('uploadStatus', imageElement);\n                imageUploadElements.delete(loader.id);\n            });\n            fileRepository.destroyLoader(loader);\n        }\n    }\n    /**\n\t * Creates the `srcset` attribute based on a given file upload response and sets it as an attribute to a specific image element.\n\t *\n\t * @param data Data object from which `srcset` will be created.\n\t * @param image The image element on which the `srcset` attribute will be set.\n\t */ _parseAndSetSrcsetAttributeOnImage(data, image, writer) {\n        // Srcset attribute for responsive images support.\n        let maxWidth = 0;\n        const srcsetAttribute = Object.keys(data)// Filter out keys that are not integers.\n        .filter((key)=>{\n            const width = parseInt(key, 10);\n            if (!isNaN(width)) {\n                maxWidth = Math.max(maxWidth, width);\n                return true;\n            }\n        })// Convert each key to srcset entry.\n        .map((key)=>`${data[key]} ${key}w`)// Join all entries.\n        .join(', ');\n        if (srcsetAttribute != '') {\n            const attributes = {\n                srcset: srcsetAttribute\n            };\n            if (!image.hasAttribute('width') && !image.hasAttribute('height')) {\n                attributes.width = maxWidth;\n            }\n            writer.setAttributes(attributes, image);\n        }\n    }\n}\n/**\n * Returns `true` if non-empty `text/html` is included in the data transfer.\n */ function isHtmlIncluded(dataTransfer) {\n    return Array.from(dataTransfer.types).includes('text/html') && dataTransfer.getData('text/html') !== '';\n}\nfunction getImagesFromChangeItem(editor, item) {\n    const imageUtils = editor.plugins.get('ImageUtils');\n    return Array.from(editor.model.createRangeOn(item)).filter((value)=>imageUtils.isImage(value.item)).map((value)=>value.item);\n}\n\n/**\n * The image upload plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload image upload feature} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins to enable image uploading:\n *\n * * {@link module:image/imageupload/imageuploadediting~ImageUploadEditing},\n * * {@link module:image/imageupload/imageuploadui~ImageUploadUI},\n * * {@link module:image/imageupload/imageuploadprogress~ImageUploadProgress}.\n */ class ImageUpload extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageUpload';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUploadEditing,\n            ImageUploadUI,\n            ImageUploadProgress\n        ];\n    }\n}\n\n/**\n * The insert an image via URL view.\n *\n * See {@link module:image/imageinsert/imageinsertviaurlui~ImageInsertViaUrlUI}.\n */ class ImageInsertUrlView extends View {\n    /**\n\t * The URL input field view.\n\t */ urlInputView;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.\n\t *\n\t * @param locale The localization services instance.\n\t */ constructor(locale){\n        super(locale);\n        this.set('imageURLInputValue', '');\n        this.set('isImageSelected', false);\n        this.set('isEnabled', true);\n        this.keystrokes = new KeystrokeHandler();\n        this.urlInputView = this._createUrlInputView();\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-image-insert-url'\n                ]\n            },\n            children: [\n                this.urlInputView,\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-image-insert-url__action-row'\n                        ]\n                    }\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Creates the {@link #urlInputView}.\n\t */ _createUrlInputView() {\n        const locale = this.locale;\n        const t = locale.t;\n        const urlInputView = new LabeledFieldView(locale, createLabeledInputText);\n        urlInputView.bind('label').to(this, 'isImageSelected', (value)=>value ? t('Update image URL') : t('Insert image via URL'));\n        urlInputView.bind('isEnabled').to(this);\n        urlInputView.fieldView.inputMode = 'url';\n        urlInputView.fieldView.placeholder = 'https://example.com/image.png';\n        urlInputView.fieldView.bind('value').to(this, 'imageURLInputValue', (value)=>value || '');\n        urlInputView.fieldView.on('input', ()=>{\n            this.imageURLInputValue = urlInputView.fieldView.element.value.trim();\n        });\n        return urlInputView;\n    }\n    /**\n\t * Focuses the view.\n\t */ focus() {\n        this.urlInputView.focus();\n    }\n}\n\n/**\n * The image insert via URL plugin (UI part).\n *\n * The plugin introduces two UI components to the {@link module:ui/componentfactory~ComponentFactory UI component factory}:\n *\n * * the `'insertImageViaUrl'` toolbar button,\n * * the `'menuBar:insertImageViaUrl'` menu bar component.\n *\n * It also integrates with the `insertImage` toolbar component and `menuBar:insertImage` menu component, which are default components\n * through which inserting image via URL is available.\n */ class ImageInsertViaUrlUI extends Plugin {\n    _imageInsertUI;\n    _formView;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageInsertViaUrlUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageInsertUI,\n            Dialog\n        ];\n    }\n    init() {\n        this.editor.ui.componentFactory.add('insertImageViaUrl', ()=>this._createToolbarButton());\n        this.editor.ui.componentFactory.add('menuBar:insertImageViaUrl', ()=>this._createMenuBarButton('standalone'));\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        this._imageInsertUI = this.editor.plugins.get('ImageInsertUI');\n        this._imageInsertUI.registerIntegration({\n            name: 'url',\n            observable: ()=>this.editor.commands.get('insertImage'),\n            buttonViewCreator: ()=>this._createToolbarButton(),\n            formViewCreator: ()=>this._createDropdownButton(),\n            menuBarButtonViewCreator: (isOnly)=>this._createMenuBarButton(isOnly ? 'insertOnly' : 'insertNested')\n        });\n    }\n    /**\n\t * Creates the base for various kinds of the button component provided by this feature.\n\t */ _createInsertUrlButton(ButtonClass) {\n        const button = new ButtonClass(this.editor.locale);\n        button.icon = icons.imageUrl;\n        button.on('execute', ()=>{\n            this._showModal();\n        });\n        return button;\n    }\n    /**\n\t * Creates a simple toolbar button, with an icon and a tooltip.\n\t */ _createToolbarButton() {\n        const t = this.editor.locale.t;\n        const button = this._createInsertUrlButton(ButtonView);\n        button.tooltip = true;\n        button.bind('label').to(this._imageInsertUI, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Update image URL') : t('Insert image via URL'));\n        return button;\n    }\n    /**\n\t * Creates a button for the dropdown view, with an icon, text and no tooltip.\n\t */ _createDropdownButton() {\n        const t = this.editor.locale.t;\n        const button = this._createInsertUrlButton(ButtonView);\n        button.withText = true;\n        button.bind('label').to(this._imageInsertUI, 'isImageSelected', (isImageSelected)=>isImageSelected ? t('Update image URL') : t('Insert via URL'));\n        return button;\n    }\n    /**\n\t * Creates a button for the menu bar.\n\t */ _createMenuBarButton(type) {\n        const t = this.editor.locale.t;\n        const button = this._createInsertUrlButton(MenuBarMenuListItemButtonView);\n        button.withText = true;\n        switch(type){\n            case 'standalone':\n                button.label = t('Image via URL');\n                break;\n            case 'insertOnly':\n                button.label = t('Image');\n                break;\n            case 'insertNested':\n                button.label = t('Via URL');\n                break;\n        }\n        return button;\n    }\n    /**\n\t * Creates the form view used to submit the image URL.\n\t */ _createInsertUrlView() {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const replaceImageSourceCommand = editor.commands.get('replaceImageSource');\n        const insertImageCommand = editor.commands.get('insertImage');\n        const imageInsertUrlView = new ImageInsertUrlView(locale);\n        imageInsertUrlView.bind('isImageSelected').to(this._imageInsertUI);\n        imageInsertUrlView.bind('isEnabled').toMany([\n            insertImageCommand,\n            replaceImageSourceCommand\n        ], 'isEnabled', (...isEnabled)=>isEnabled.some((isCommandEnabled)=>isCommandEnabled));\n        return imageInsertUrlView;\n    }\n    /**\n\t * Shows the insert image via URL form view in a modal.\n\t */ _showModal() {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const t = locale.t;\n        const dialog = editor.plugins.get('Dialog');\n        if (!this._formView) {\n            this._formView = this._createInsertUrlView();\n            this._formView.on('submit', ()=>this._handleSave());\n        }\n        const replaceImageSourceCommand = editor.commands.get('replaceImageSource');\n        this._formView.imageURLInputValue = replaceImageSourceCommand.value || '';\n        dialog.show({\n            id: 'insertImageViaUrl',\n            title: this._imageInsertUI.isImageSelected ? t('Update image URL') : t('Insert image via URL'),\n            isModal: true,\n            content: this._formView,\n            actionButtons: [\n                {\n                    label: t('Cancel'),\n                    withText: true,\n                    onExecute: ()=>dialog.hide()\n                },\n                {\n                    label: t('Accept'),\n                    class: 'ck-button-action',\n                    withText: true,\n                    onExecute: ()=>this._handleSave()\n                }\n            ]\n        });\n    }\n    /**\n\t * Executes appropriate command depending on selection and form value.\n\t */ _handleSave() {\n        const replaceImageSourceCommand = this.editor.commands.get('replaceImageSource');\n        // If an image element is currently selected, we want to replace its source attribute (instead of inserting a new image).\n        // We detect if an image is selected by checking `replaceImageSource` command state.\n        if (replaceImageSourceCommand.isEnabled) {\n            this.editor.execute('replaceImageSource', {\n                source: this._formView.imageURLInputValue\n            });\n        } else {\n            this.editor.execute('insertImage', {\n                source: this._formView.imageURLInputValue\n            });\n        }\n        this.editor.plugins.get('Dialog').hide();\n    }\n}\n\n/**\n * The image insert via URL plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-inserting\n * Insert images via source URL} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins\n * to enable image inserting via implemented integrations:\n *\n * * {@link module:image/imageinsert/imageinsertui~ImageInsertUI},\n */ class ImageInsertViaUrl extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageInsertViaUrl';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageInsertViaUrlUI,\n            ImageInsertUI\n        ];\n    }\n}\n\n/**\n * The image insert plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}\n * and {@glink features/images/images-inserting Insert images via source URL} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins\n * to enable image uploading or inserting via implemented integrations:\n *\n * * {@link module:image/imageupload~ImageUpload}\n * * {@link module:image/imageinsert/imageinsertui~ImageInsertUI}\n */ class ImageInsert extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageInsert';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUpload,\n            ImageInsertViaUrl,\n            ImageInsertUI\n        ];\n    }\n}\n\n/**\n * The resize image command. Currently, it only supports the width attribute.\n */ class ResizeImageCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const element = imageUtils.getClosestSelectedImageElement(editor.model.document.selection);\n        this.isEnabled = !!element;\n        if (!element || !element.hasAttribute('resizedWidth')) {\n            this.value = null;\n        } else {\n            this.value = {\n                width: element.getAttribute('resizedWidth'),\n                height: null\n            };\n        }\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * ```ts\n\t * // Sets the width to 50%:\n\t * editor.execute( 'resizeImage', { width: '50%' } );\n\t *\n\t * // Removes the width attribute:\n\t * editor.execute( 'resizeImage', { width: null } );\n\t * ```\n\t *\n\t * @param options\n\t * @param options.width The new width of the image.\n\t * @fires execute\n\t */ execute(options) {\n        const editor = this.editor;\n        const model = editor.model;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const imageElement = imageUtils.getClosestSelectedImageElement(model.document.selection);\n        this.value = {\n            width: options.width,\n            height: null\n        };\n        if (imageElement) {\n            model.change((writer)=>{\n                writer.setAttribute('resizedWidth', options.width, imageElement);\n                writer.removeAttribute('resizedHeight', imageElement);\n                imageUtils.setImageNaturalSizeAttributes(imageElement);\n            });\n        }\n    }\n}\n\n/**\n * The image resize editing feature.\n *\n * It adds the ability to resize each image using handles or manually by\n * {@link module:image/imageresize/imageresizebuttons~ImageResizeButtons} buttons.\n */ class ImageResizeEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageResizeEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('image', {\n            resizeUnit: '%',\n            resizeOptions: [\n                {\n                    name: 'resizeImage:original',\n                    value: null,\n                    icon: 'original'\n                },\n                {\n                    name: 'resizeImage:custom',\n                    value: 'custom',\n                    icon: 'custom'\n                },\n                {\n                    name: 'resizeImage:25',\n                    value: '25',\n                    icon: 'small'\n                },\n                {\n                    name: 'resizeImage:50',\n                    value: '50',\n                    icon: 'medium'\n                },\n                {\n                    name: 'resizeImage:75',\n                    value: '75',\n                    icon: 'large'\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const resizeImageCommand = new ResizeImageCommand(editor);\n        this._registerConverters('imageBlock');\n        this._registerConverters('imageInline');\n        // Register `resizeImage` command and add `imageResize` command as an alias for backward compatibility.\n        editor.commands.add('resizeImage', resizeImageCommand);\n        editor.commands.add('imageResize', resizeImageCommand);\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        this._registerSchema();\n    }\n    _registerSchema() {\n        if (this.editor.plugins.has('ImageBlockEditing')) {\n            this.editor.model.schema.extend('imageBlock', {\n                allowAttributes: [\n                    'resizedWidth',\n                    'resizedHeight'\n                ]\n            });\n        }\n        if (this.editor.plugins.has('ImageInlineEditing')) {\n            this.editor.model.schema.extend('imageInline', {\n                allowAttributes: [\n                    'resizedWidth',\n                    'resizedHeight'\n                ]\n            });\n        }\n    }\n    /**\n\t * Registers image resize converters.\n\t *\n\t * @param imageType The type of the image.\n\t */ _registerConverters(imageType) {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        // Dedicated converter to propagate image's attribute to the img tag.\n        editor.conversion.for('downcast').add((dispatcher)=>dispatcher.on(`attribute:resizedWidth:${imageType}`, (evt, data, conversionApi)=>{\n                if (!conversionApi.consumable.consume(data.item, evt.name)) {\n                    return;\n                }\n                const viewWriter = conversionApi.writer;\n                const viewImg = conversionApi.mapper.toViewElement(data.item);\n                if (data.attributeNewValue !== null) {\n                    viewWriter.setStyle('width', data.attributeNewValue, viewImg);\n                    viewWriter.addClass('image_resized', viewImg);\n                } else {\n                    viewWriter.removeStyle('width', viewImg);\n                    viewWriter.removeClass('image_resized', viewImg);\n                }\n            }));\n        editor.conversion.for('dataDowncast').attributeToAttribute({\n            model: {\n                name: imageType,\n                key: 'resizedHeight'\n            },\n            view: (modelAttributeValue)=>({\n                    key: 'style',\n                    value: {\n                        'height': modelAttributeValue\n                    }\n                })\n        });\n        editor.conversion.for('editingDowncast').add((dispatcher)=>dispatcher.on(`attribute:resizedHeight:${imageType}`, (evt, data, conversionApi)=>{\n                if (!conversionApi.consumable.consume(data.item, evt.name)) {\n                    return;\n                }\n                const viewWriter = conversionApi.writer;\n                const viewImg = conversionApi.mapper.toViewElement(data.item);\n                const target = imageType === 'imageInline' ? imageUtils.findViewImgElement(viewImg) : viewImg;\n                if (data.attributeNewValue !== null) {\n                    viewWriter.setStyle('height', data.attributeNewValue, target);\n                } else {\n                    viewWriter.removeStyle('height', target);\n                }\n            }));\n        editor.conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: imageType === 'imageBlock' ? 'figure' : 'img',\n                styles: {\n                    width: /.+/\n                }\n            },\n            model: {\n                key: 'resizedWidth',\n                value: (viewElement)=>{\n                    if (widthAndHeightStylesAreBothSet(viewElement)) {\n                        return null;\n                    }\n                    return viewElement.getStyle('width');\n                }\n            }\n        });\n        editor.conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: imageType === 'imageBlock' ? 'figure' : 'img',\n                styles: {\n                    height: /.+/\n                }\n            },\n            model: {\n                key: 'resizedHeight',\n                value: (viewElement)=>{\n                    if (widthAndHeightStylesAreBothSet(viewElement)) {\n                        return null;\n                    }\n                    return viewElement.getStyle('height');\n                }\n            }\n        });\n    }\n}\n\nconst RESIZE_ICONS = /* #__PURE__ */ (()=>({\n        small: icons.objectSizeSmall,\n        medium: icons.objectSizeMedium,\n        large: icons.objectSizeLarge,\n        custom: icons.objectSizeCustom,\n        original: icons.objectSizeFull\n    }))();\n/**\n * The image resize buttons plugin.\n *\n * It adds a possibility to resize images using the toolbar dropdown or individual buttons, depending on the plugin configuration.\n */ class ImageResizeButtons extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageResizeEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageResizeButtons';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * The resize unit.\n\t * @default '%'\n\t */ _resizeUnit;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._resizeUnit = editor.config.get('image.resizeUnit');\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const options = editor.config.get('image.resizeOptions');\n        const command = editor.commands.get('resizeImage');\n        this.bind('isEnabled').to(command);\n        for (const option of options){\n            this._registerImageResizeButton(option);\n        }\n        this._registerImageResizeDropdown(options);\n    }\n    /**\n\t * A helper function that creates a standalone button component for the plugin.\n\t *\n\t * @param resizeOption A model of the resize option.\n\t */ _registerImageResizeButton(option) {\n        const editor = this.editor;\n        const { name, value, icon } = option;\n        editor.ui.componentFactory.add(name, (locale)=>{\n            const button = new ButtonView(locale);\n            const command = editor.commands.get('resizeImage');\n            const labelText = this._getOptionLabelValue(option, true);\n            if (!RESIZE_ICONS[icon]) {\n                /**\n\t\t\t\t * When configuring {@link module:image/imageconfig~ImageConfig#resizeOptions `config.image.resizeOptions`} for standalone\n\t\t\t\t * buttons, a valid `icon` token must be set for each option.\n\t\t\t\t *\n\t\t\t\t * See all valid options described in the\n\t\t\t\t * {@link module:image/imageconfig~ImageResizeOption plugin configuration}.\n\t\t\t\t *\n\t\t\t\t * @error imageresizebuttons-missing-icon\n\t\t\t\t * @param option Invalid image resize option.\n\t\t\t\t*/ throw new CKEditorError('imageresizebuttons-missing-icon', editor, option);\n            }\n            button.set({\n                // Use the `label` property for a verbose description (because of ARIA).\n                label: labelText,\n                icon: RESIZE_ICONS[icon],\n                tooltip: labelText,\n                isToggleable: true\n            });\n            // Bind button to the command.\n            button.bind('isEnabled').to(this);\n            if (editor.plugins.has('ImageCustomResizeUI') && isCustomImageResizeOption(option)) {\n                const customResizeUI = editor.plugins.get('ImageCustomResizeUI');\n                this.listenTo(button, 'execute', ()=>{\n                    customResizeUI._showForm(this._resizeUnit);\n                });\n            } else {\n                const optionValueWithUnit = value ? value + this._resizeUnit : null;\n                button.bind('isOn').to(command, 'value', getIsOnButtonCallback(optionValueWithUnit));\n                this.listenTo(button, 'execute', ()=>{\n                    editor.execute('resizeImage', {\n                        width: optionValueWithUnit\n                    });\n                });\n            }\n            return button;\n        });\n    }\n    /**\n\t * A helper function that creates a dropdown component for the plugin containing all the resize options defined in\n\t * the editor configuration.\n\t *\n\t * @param options An array of configured options.\n\t */ _registerImageResizeDropdown(options) {\n        const editor = this.editor;\n        const t = editor.t;\n        const originalSizeOption = options.find((option)=>!option.value);\n        const componentCreator = (locale)=>{\n            const command = editor.commands.get('resizeImage');\n            const dropdownView = createDropdown(locale, DropdownButtonView);\n            const dropdownButton = dropdownView.buttonView;\n            const accessibleLabel = t('Resize image');\n            dropdownButton.set({\n                tooltip: accessibleLabel,\n                commandValue: originalSizeOption.value,\n                icon: RESIZE_ICONS.medium,\n                isToggleable: true,\n                label: this._getOptionLabelValue(originalSizeOption),\n                withText: true,\n                class: 'ck-resize-image-button',\n                ariaLabel: accessibleLabel,\n                ariaLabelledBy: undefined\n            });\n            dropdownButton.bind('label').to(command, 'value', (commandValue)=>{\n                if (commandValue && commandValue.width) {\n                    return commandValue.width;\n                } else {\n                    return this._getOptionLabelValue(originalSizeOption);\n                }\n            });\n            dropdownView.bind('isEnabled').to(this);\n            addListToDropdown(dropdownView, ()=>this._getResizeDropdownListItemDefinitions(options, command), {\n                ariaLabel: t('Image resize list'),\n                role: 'menu'\n            });\n            // Execute command when an item from the dropdown is selected.\n            this.listenTo(dropdownView, 'execute', (evt)=>{\n                if ('onClick' in evt.source) {\n                    evt.source.onClick();\n                } else {\n                    editor.execute(evt.source.commandName, {\n                        width: evt.source.commandValue\n                    });\n                    editor.editing.view.focus();\n                }\n            });\n            return dropdownView;\n        };\n        // Register `resizeImage` dropdown and add `imageResize` dropdown as an alias for backward compatibility.\n        editor.ui.componentFactory.add('resizeImage', componentCreator);\n        editor.ui.componentFactory.add('imageResize', componentCreator);\n    }\n    /**\n\t * A helper function for creating an option label value string.\n\t *\n\t * @param option A resize option object.\n\t * @param forTooltip An optional flag for creating a tooltip label.\n\t * @returns A user-defined label combined from the numeric value and the resize unit or the default label\n\t * for reset options (`Original`).\n\t */ _getOptionLabelValue(option, forTooltip = false) {\n        const t = this.editor.t;\n        if (option.label) {\n            return option.label;\n        } else if (forTooltip) {\n            if (isCustomImageResizeOption(option)) {\n                return t('Custom image size');\n            } else if (option.value) {\n                return t('Resize image to %0', option.value + this._resizeUnit);\n            } else {\n                return t('Resize image to the original size');\n            }\n        } else {\n            if (isCustomImageResizeOption(option)) {\n                return t('Custom');\n            } else if (option.value) {\n                return option.value + this._resizeUnit;\n            } else {\n                return t('Original');\n            }\n        }\n    }\n    /**\n\t * A helper function that parses the resize options and returns list item definitions ready for use in the dropdown.\n\t *\n\t * @param options The resize options.\n\t * @param command The resize image command.\n\t * @returns Dropdown item definitions.\n\t */ _getResizeDropdownListItemDefinitions(options, command) {\n        const { editor } = this;\n        const itemDefinitions = new Collection();\n        const optionsWithSerializedValues = options.map((option)=>{\n            if (isCustomImageResizeOption(option)) {\n                return {\n                    ...option,\n                    valueWithUnits: 'custom'\n                };\n            }\n            if (!option.value) {\n                return {\n                    ...option,\n                    valueWithUnits: null\n                };\n            }\n            return {\n                ...option,\n                valueWithUnits: `${option.value}${this._resizeUnit}`\n            };\n        });\n        for (const option of optionsWithSerializedValues){\n            let definition = null;\n            if (editor.plugins.has('ImageCustomResizeUI') && isCustomImageResizeOption(option)) {\n                const customResizeUI = editor.plugins.get('ImageCustomResizeUI');\n                definition = {\n                    type: 'button',\n                    model: new ViewModel({\n                        label: this._getOptionLabelValue(option),\n                        role: 'menuitemradio',\n                        withText: true,\n                        icon: null,\n                        onClick: ()=>{\n                            customResizeUI._showForm(this._resizeUnit);\n                        }\n                    })\n                };\n                const allDropdownValues = map(optionsWithSerializedValues, 'valueWithUnits');\n                definition.model.bind('isOn').to(command, 'value', getIsOnCustomButtonCallback(allDropdownValues));\n            } else {\n                definition = {\n                    type: 'button',\n                    model: new ViewModel({\n                        commandName: 'resizeImage',\n                        commandValue: option.valueWithUnits,\n                        label: this._getOptionLabelValue(option),\n                        role: 'menuitemradio',\n                        withText: true,\n                        icon: null\n                    })\n                };\n                definition.model.bind('isOn').to(command, 'value', getIsOnButtonCallback(option.valueWithUnits));\n            }\n            definition.model.bind('isEnabled').to(command, 'isEnabled');\n            itemDefinitions.add(definition);\n        }\n        return itemDefinitions;\n    }\n}\n/**\n * A helper that checks if provided option triggers custom resize balloon.\n */ function isCustomImageResizeOption(option) {\n    return option.value === 'custom';\n}\n/**\n * A helper function for setting the `isOn` state of buttons in value bindings.\n */ function getIsOnButtonCallback(value) {\n    return (commandValue)=>{\n        const objectCommandValue = commandValue;\n        if (value === null && objectCommandValue === value) {\n            return true;\n        }\n        return objectCommandValue !== null && objectCommandValue.width === value;\n    };\n}\n/**\n * A helper function for setting the `isOn` state of custom size button in value bindings.\n */ function getIsOnCustomButtonCallback(allDropdownValues) {\n    return (commandValue)=>!allDropdownValues.some((dropdownValue)=>getIsOnButtonCallback(dropdownValue)(commandValue));\n}\n\nconst RESIZABLE_IMAGES_CSS_SELECTOR = 'figure.image.ck-widget > img,' + 'figure.image.ck-widget > picture > img,' + 'figure.image.ck-widget > a > img,' + 'figure.image.ck-widget > a > picture > img,' + 'span.image-inline.ck-widget > img,' + 'span.image-inline.ck-widget > picture > img';\nconst RESIZED_IMAGE_CLASS = 'image_resized';\n/**\n * The image resize by handles feature.\n *\n * It adds the ability to resize each image using handles or manually by\n * {@link module:image/imageresize/imageresizebuttons~ImageResizeButtons} buttons.\n */ class ImageResizeHandles extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            WidgetResize,\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageResizeHandles';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const command = this.editor.commands.get('resizeImage');\n        this.bind('isEnabled').to(command);\n        this._setupResizerCreator();\n    }\n    /**\n\t * Attaches the listeners responsible for creating a resizer for each image, except for images inside the HTML embed preview.\n\t */ _setupResizerCreator() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        editingView.addObserver(ImageLoadObserver);\n        this.listenTo(editingView.document, 'imageLoaded', (evt, domEvent)=>{\n            // The resizer must be attached only to images loaded by the `ImageInsert`, `ImageUpload` or `LinkImage` plugins.\n            if (!domEvent.target.matches(RESIZABLE_IMAGES_CSS_SELECTOR)) {\n                return;\n            }\n            const domConverter = editor.editing.view.domConverter;\n            const imageView = domConverter.domToView(domEvent.target);\n            const widgetView = imageUtils.getImageWidgetFromImageView(imageView);\n            let resizer = this.editor.plugins.get(WidgetResize).getResizerByViewElement(widgetView);\n            if (resizer) {\n                // There are rare cases when the image will be triggered multiple times for the same widget, e.g. when\n                // the image's source was changed after upload (https://github.com/ckeditor/ckeditor5/pull/8108#issuecomment-708302992).\n                resizer.redraw();\n                return;\n            }\n            const mapper = editor.editing.mapper;\n            const imageModel = mapper.toModelElement(widgetView);\n            resizer = editor.plugins.get(WidgetResize).attachTo({\n                unit: editor.config.get('image.resizeUnit'),\n                modelElement: imageModel,\n                viewElement: widgetView,\n                editor,\n                getHandleHost (domWidgetElement) {\n                    return domWidgetElement.querySelector('img');\n                },\n                getResizeHost () {\n                    return domConverter.mapViewToDom(mapper.toViewElement(imageModel));\n                },\n                isCentered () {\n                    const imageStyle = imageModel.getAttribute('imageStyle');\n                    return imageStyle == 'alignCenter';\n                },\n                onCommit (newValue) {\n                    // Get rid of the CSS class in case the command execution that follows is unsuccessful\n                    // (e.g. Track Changes can override it and the new dimensions will not apply). Otherwise,\n                    // the presence of the class and the absence of the width style will cause it to take 100%\n                    // of the horizontal space.\n                    editingView.change((writer)=>{\n                        writer.removeClass(RESIZED_IMAGE_CLASS, widgetView);\n                    });\n                    editor.execute('resizeImage', {\n                        width: newValue\n                    });\n                }\n            });\n            resizer.on('updateSize', ()=>{\n                if (!widgetView.hasClass(RESIZED_IMAGE_CLASS)) {\n                    editingView.change((writer)=>{\n                        writer.addClass(RESIZED_IMAGE_CLASS, widgetView);\n                    });\n                }\n                const target = imageModel.name === 'imageInline' ? imageView : widgetView;\n                if (target.getStyle('height')) {\n                    editingView.change((writer)=>{\n                        writer.removeStyle('height', target);\n                    });\n                }\n            });\n            resizer.bind('isEnabled').to(this);\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module image/imageresize/utils/tryparsedimensionwithunit\n */ /**\n * Parses provided string with dimension value and returns extracted numeric value and unit.\n *\n * \t* If non-string dimension is passed then `null` value is returned.\n * \t* If unit is missing then `null` is returned.\n * \t* If numeric value part of string is not a number then `null` is returned.\n *\n * Example:\n * \t`\"222px\"` => `{ value: 222, unit: \"px\" }`\n *\t`\"99%\"` => `{ value: 99, unit: \"%\" }`\n\n * @param dimension Unsafe string with dimension.\n * @returns Parsed dimension with extracted numeric value and units.\n */ function tryParseDimensionWithUnit(dimension) {\n    if (!dimension) {\n        return null;\n    }\n    const [, rawValue, unit] = dimension.trim().match(/([.,\\d]+)(%|px)$/) || [];\n    const parsedValue = Number.parseFloat(rawValue);\n    if (Number.isNaN(parsedValue)) {\n        return null;\n    }\n    return {\n        value: parsedValue,\n        unit\n    };\n}\n/**\n * Converts dimension between `px` -> `%` and `%` -> `px`.\n *\n * @param parentDimensionPx\tDimension of parent element that contains measured element.\n * @param dimension Measured element dimension.\n * @returns Casted dimension.\n */ function tryCastDimensionsToUnit(parentDimensionPx, dimension, targetUnit) {\n    // \"%\" -> \"px\" conversion\n    if (targetUnit === 'px') {\n        return {\n            value: dimension.value,\n            unit: 'px'\n        };\n    }\n    // \"px\" -> \"%\" conversion\n    return {\n        value: dimension.value / parentDimensionPx * 100,\n        unit: '%'\n    };\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module image/imageresize/utils/getselectedimageeditornodes\n */ /**\n * Finds model, view and DOM element for selected image element. Returns `null` if there is no image selected.\n *\n * @param editor Editor instance.\n */ function getSelectedImageEditorNodes(editor) {\n    const { editing } = editor;\n    const imageUtils = editor.plugins.get('ImageUtils');\n    const imageModelElement = imageUtils.getClosestSelectedImageElement(editor.model.document.selection);\n    if (!imageModelElement) {\n        return null;\n    }\n    const imageViewElement = editing.mapper.toViewElement(imageModelElement);\n    const imageDOMElement = editing.view.domConverter.mapViewToDom(imageViewElement);\n    return {\n        model: imageModelElement,\n        view: imageViewElement,\n        dom: imageDOMElement\n    };\n}\n\n/**\n * Returns image width in specified units. It is width of image after resize.\n *\n * \t* If image is not selected or command is disabled then `null` will be returned.\n * \t* If image is not fully loaded (and it is impossible to determine its natural size) then `null` will be returned.\n *\t* If `targetUnit` percentage is passed then it will return width percentage of image related to its accessors.\n *\n * @param editor Editor instance.\n * @param targetUnit Unit in which dimension will be returned.\n * @returns Parsed image width after resize (with unit).\n */ function getSelectedImageWidthInUnits(editor, targetUnit) {\n    const imageNodes = getSelectedImageEditorNodes(editor);\n    if (!imageNodes) {\n        return null;\n    }\n    const parsedResizedWidth = tryParseDimensionWithUnit(imageNodes.model.getAttribute('resizedWidth') || null);\n    if (!parsedResizedWidth) {\n        return null;\n    }\n    if (parsedResizedWidth.unit === targetUnit) {\n        return parsedResizedWidth;\n    }\n    const imageParentWidthPx = calculateResizeHostAncestorWidth(imageNodes.dom);\n    const imageHolderDimension = {\n        unit: 'px',\n        value: new Rect(imageNodes.dom).width\n    };\n    return tryCastDimensionsToUnit(imageParentWidthPx, imageHolderDimension, targetUnit);\n}\n\n/**\n * The ImageCustomResizeFormView class.\n */ class ImageCustomResizeFormView extends View {\n    /**\n\t * Tracks information about the DOM focus in the form.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * Resize unit shortcut.\n\t */ unit;\n    /**\n\t * An input with a label.\n\t */ labeledInput;\n    /**\n\t * A button used to submit the form.\n\t */ saveButtonView;\n    /**\n\t * A button used to cancel the form.\n\t */ cancelButtonView;\n    /**\n\t * A collection of views which can be focused in the form.\n\t */ _focusables;\n    /**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */ _focusCycler;\n    /**\n\t * An array of form validators used by {@link #isValid}.\n\t */ _validators;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, unit, validators){\n        super(locale);\n        const t = this.locale.t;\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.unit = unit;\n        this.labeledInput = this._createLabeledInputView();\n        this.saveButtonView = this._createButton(t('Save'), icons.check, 'ck-button-save');\n        this.saveButtonView.type = 'submit';\n        this.cancelButtonView = this._createButton(t('Cancel'), icons.cancel, 'ck-button-cancel', 'cancel');\n        this._focusables = new ViewCollection();\n        this._validators = validators;\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        this.setTemplate({\n            tag: 'form',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-image-custom-resize-form',\n                    'ck-responsive-form'\n                ],\n                // https://github.com/ckeditor/ckeditor5-image/issues/40\n                tabindex: '-1'\n            },\n            children: [\n                this.labeledInput,\n                this.saveButtonView,\n                this.cancelButtonView\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.keystrokes.listenTo(this.element);\n        submitHandler({\n            view: this\n        });\n        [\n            this.labeledInput,\n            this.saveButtonView,\n            this.cancelButtonView\n        ].forEach((v)=>{\n            // Register the view as focusable.\n            this._focusables.add(v);\n            // Register the view in the focus tracker.\n            this.focusTracker.add(v.element);\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Creates the button view.\n\t *\n\t * @param label The button label\n\t * @param icon The button's icon.\n\t * @param className The additional button CSS class name.\n\t * @param eventName The event name that the ButtonView#execute event will be delegated to.\n\t * @returns The button view instance.\n\t */ _createButton(label, icon, className, eventName) {\n        const button = new ButtonView(this.locale);\n        button.set({\n            label,\n            icon,\n            tooltip: true\n        });\n        button.extendTemplate({\n            attributes: {\n                class: className\n            }\n        });\n        if (eventName) {\n            button.delegate('execute').to(this, eventName);\n        }\n        return button;\n    }\n    /**\n\t * Creates an input with a label.\n\t *\n\t * @returns Labeled field view instance.\n\t */ _createLabeledInputView() {\n        const t = this.locale.t;\n        const labeledInput = new LabeledFieldView(this.locale, createLabeledInputNumber);\n        labeledInput.label = t('Resize image (in %0)', this.unit);\n        labeledInput.fieldView.set({\n            step: 0.1\n        });\n        return labeledInput;\n    }\n    /**\n\t * Validates the form and returns `false` when some fields are invalid.\n\t */ isValid() {\n        this.resetFormStatus();\n        for (const validator of this._validators){\n            const errorText = validator(this);\n            // One error per field is enough.\n            if (errorText) {\n                // Apply updated error.\n                this.labeledInput.errorText = errorText;\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Cleans up the supplementary error and information text of the {@link #labeledInput}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */ resetFormStatus() {\n        this.labeledInput.errorText = null;\n    }\n    /**\n\t * The native DOM `value` of the input element of {@link #labeledInput}.\n\t */ get rawSize() {\n        const { element } = this.labeledInput.fieldView;\n        if (!element) {\n            return null;\n        }\n        return element.value;\n    }\n    /**\n\t * Get numeric value of size. Returns `null` if value of size input element in {@link #labeledInput}.is not a number.\n\t */ get parsedSize() {\n        const { rawSize } = this;\n        if (rawSize === null) {\n            return null;\n        }\n        const parsed = Number.parseFloat(rawSize);\n        if (Number.isNaN(parsed)) {\n            return null;\n        }\n        return parsed;\n    }\n    /**\n\t * Returns serialized image input size with unit.\n\t * Returns `null` if value of size input element in {@link #labeledInput}.is not a number.\n\t */ get sizeWithUnits() {\n        const { parsedSize, unit } = this;\n        if (parsedSize === null) {\n            return null;\n        }\n        return `${parsedSize}${unit}`;\n    }\n}\n\n/**\n * Returns min and max value of resize image in specified unit.\n *\n * @param editor Editor instance.\n * @param targetUnit Unit in which dimension will be returned.\n * @returns Possible resize range in numeric form.\n */ function getSelectedImagePossibleResizeRange(editor, targetUnit) {\n    const imageNodes = getSelectedImageEditorNodes(editor);\n    if (!imageNodes) {\n        return null;\n    }\n    const imageParentWidthPx = calculateResizeHostAncestorWidth(imageNodes.dom);\n    const minimumImageWidth = tryParseDimensionWithUnit(window.getComputedStyle(imageNodes.dom).minWidth) || {\n        value: 1,\n        unit: 'px'\n    };\n    const lower = Math.max(0.1, tryCastDimensionsToUnit(imageParentWidthPx, minimumImageWidth, targetUnit).value);\n    const upper = targetUnit === 'px' ? imageParentWidthPx : 100;\n    return {\n        unit: targetUnit,\n        lower,\n        upper\n    };\n}\n\n/**\n * The custom resize image UI plugin.\n *\n * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n */ class ImageCustomResizeUI extends Plugin {\n    /**\n\t * The contextual balloon plugin instance.\n\t */ _balloon;\n    /**\n\t * A form containing a textarea and buttons, used to change the `alt` text value.\n\t */ _form;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageCustomResizeUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n        if (this._form) {\n            this._form.destroy();\n        }\n    }\n    /**\n\t * Creates the {@link module:image/imageresize/ui/imagecustomresizeformview~ImageCustomResizeFormView}\n\t * form.\n\t */ _createForm(unit) {\n        const editor = this.editor;\n        this._balloon = this.editor.plugins.get('ContextualBalloon');\n        this._form = new (CssTransitionDisablerMixin(ImageCustomResizeFormView))(editor.locale, unit, getFormValidators(editor));\n        // Render the form so its #element is available for clickOutsideHandler.\n        this._form.render();\n        this.listenTo(this._form, 'submit', ()=>{\n            if (this._form.isValid()) {\n                editor.execute('resizeImage', {\n                    width: this._form.sizeWithUnits\n                });\n                this._hideForm(true);\n            }\n        });\n        // Update balloon position when form error label is added .\n        this.listenTo(this._form.labeledInput, 'change:errorText', ()=>{\n            editor.ui.update();\n        });\n        this.listenTo(this._form, 'cancel', ()=>{\n            this._hideForm(true);\n        });\n        // Close the form on Esc key press.\n        this._form.keystrokes.set('Esc', (data, cancel)=>{\n            this._hideForm(true);\n            cancel();\n        });\n        // Close on click outside of balloon panel element.\n        clickOutsideHandler({\n            emitter: this._form,\n            activator: ()=>this._isVisible,\n            contextElements: ()=>[\n                    this._balloon.view.element\n                ],\n            callback: ()=>this._hideForm()\n        });\n    }\n    /**\n\t * Shows the {@link #_form} in the {@link #_balloon}.\n\t *\n\t * @internal\n\t */ _showForm(unit) {\n        if (this._isVisible) {\n            return;\n        }\n        if (!this._form) {\n            this._createForm(unit);\n        }\n        const editor = this.editor;\n        const labeledInput = this._form.labeledInput;\n        this._form.disableCssTransitions();\n        this._form.resetFormStatus();\n        if (!this._isInBalloon) {\n            this._balloon.add({\n                view: this._form,\n                position: getBalloonPositionData(editor)\n            });\n        }\n        // Make sure that each time the panel shows up, the field remains in sync with the value of\n        // the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`\n        // stays unaltered) and re-opened it without changing the value of the command, they would see the\n        // old value instead of the actual value of the command.\n        const currentParsedWidth = getSelectedImageWidthInUnits(editor, unit);\n        const initialInputValue = currentParsedWidth ? currentParsedWidth.value.toFixed(1) : '';\n        const possibleRange = getSelectedImagePossibleResizeRange(editor, unit);\n        labeledInput.fieldView.value = labeledInput.fieldView.element.value = initialInputValue;\n        if (possibleRange) {\n            Object.assign(labeledInput.fieldView, {\n                min: possibleRange.lower.toFixed(1),\n                max: Math.ceil(possibleRange.upper).toFixed(1)\n            });\n        }\n        this._form.labeledInput.fieldView.select();\n        this._form.enableCssTransitions();\n    }\n    /**\n\t * Removes the {@link #_form} from the {@link #_balloon}.\n\t *\n\t * @param focusEditable Controls whether the editing view is focused afterwards.\n\t */ _hideForm(focusEditable = false) {\n        if (!this._isInBalloon) {\n            return;\n        }\n        // Blur the input element before removing it from DOM to prevent issues in some browsers.\n        // See https://github.com/ckeditor/ckeditor5/issues/1501.\n        if (this._form.focusTracker.isFocused) {\n            this._form.saveButtonView.focus();\n        }\n        this._balloon.remove(this._form);\n        if (focusEditable) {\n            this.editor.editing.view.focus();\n        }\n    }\n    /**\n\t * Returns `true` when the {@link #_form} is the visible view in the {@link #_balloon}.\n\t */ get _isVisible() {\n        return !!this._balloon && this._balloon.visibleView === this._form;\n    }\n    /**\n\t * Returns `true` when the {@link #_form} is in the {@link #_balloon}.\n\t */ get _isInBalloon() {\n        return !!this._balloon && this._balloon.hasView(this._form);\n    }\n}\n/**\n * Returns image resize form validation callbacks.\n *\n * @param editor Editor instance.\n */ function getFormValidators(editor) {\n    const t = editor.t;\n    return [\n        (form)=>{\n            if (form.rawSize.trim() === '') {\n                return t('The value must not be empty.');\n            }\n            if (form.parsedSize === null) {\n                return t('The value should be a plain number.');\n            }\n        }\n    ];\n}\n\n/**\n * The image resize plugin.\n *\n * It adds a possibility to resize each image using handles.\n */ class ImageResize extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageResizeEditing,\n            ImageResizeHandles,\n            ImageCustomResizeUI,\n            ImageResizeButtons\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageResize';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The image style command. It is used to apply {@link module:image/imageconfig~ImageStyleConfig#options image style option}\n * to a selected image.\n *\n * **Note**: Executing this command may change the image model element if the desired style requires an image of a different\n * type. See {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand#execute} to learn more.\n */ class ImageStyleCommand extends Command {\n    /**\n\t * An object containing names of default style options for the inline and block images.\n\t * If there is no default style option for the given image type in the configuration,\n\t * the name will be `false`.\n\t */ _defaultStyles;\n    /**\n\t * The styles handled by this command.\n\t */ _styles;\n    /**\n\t * Creates an instance of the image style command. When executed, the command applies one of\n\t * {@link module:image/imageconfig~ImageStyleConfig#options style options} to the currently selected image.\n\t *\n\t * @param editor The editor instance.\n\t * @param styles The style options that this command supports.\n\t */ constructor(editor, styles){\n        super(editor);\n        this._defaultStyles = {\n            imageBlock: false,\n            imageInline: false\n        };\n        this._styles = new Map(styles.map((style)=>{\n            if (style.isDefault) {\n                for (const modelElementName of style.modelElements){\n                    this._defaultStyles[modelElementName] = style.name;\n                }\n            }\n            return [\n                style.name,\n                style\n            ];\n        }));\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        const element = imageUtils.getClosestSelectedImageElement(this.editor.model.document.selection);\n        this.isEnabled = !!element;\n        if (!this.isEnabled) {\n            this.value = false;\n        } else if (element.hasAttribute('imageStyle')) {\n            this.value = element.getAttribute('imageStyle');\n        } else {\n            this.value = this._defaultStyles[element.name];\n        }\n    }\n    /**\n\t * Executes the command and applies the style to the currently selected image:\n\t *\n\t * ```ts\n\t * editor.execute( 'imageStyle', { value: 'side' } );\n\t * ```\n\t *\n\t * **Note**: Executing this command may change the image model element if the desired style requires an image\n\t * of a different type. Learn more about {@link module:image/imageconfig~ImageStyleOptionDefinition#modelElements model element}\n\t * configuration for the style option.\n\t *\n\t * @param options.value The name of the style (as configured in {@link module:image/imageconfig~ImageStyleConfig#options}).\n\t * @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.\n\t * The default is `true`.\n\t * @fires execute\n\t */ execute(options = {}) {\n        const editor = this.editor;\n        const model = editor.model;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        model.change((writer)=>{\n            const requestedStyle = options.value;\n            const { setImageSizes = true } = options;\n            let imageElement = imageUtils.getClosestSelectedImageElement(model.document.selection);\n            // Change the image type if a style requires it.\n            if (requestedStyle && this.shouldConvertImageType(requestedStyle, imageElement)) {\n                this.editor.execute(imageUtils.isBlockImage(imageElement) ? 'imageTypeInline' : 'imageTypeBlock', {\n                    setImageSizes\n                });\n                // Update the imageElement to the newly created image.\n                imageElement = imageUtils.getClosestSelectedImageElement(model.document.selection);\n            }\n            // Default style means that there is no `imageStyle` attribute in the model.\n            // https://github.com/ckeditor/ckeditor5-image/issues/147\n            if (!requestedStyle || this._styles.get(requestedStyle).isDefault) {\n                writer.removeAttribute('imageStyle', imageElement);\n            } else {\n                writer.setAttribute('imageStyle', requestedStyle, imageElement);\n            }\n            if (setImageSizes) {\n                imageUtils.setImageNaturalSizeAttributes(imageElement);\n            }\n        });\n    }\n    /**\n\t * Returns `true` if requested style change would trigger the image type change.\n\t *\n\t * @param requestedStyle The name of the style (as configured in {@link module:image/imageconfig~ImageStyleConfig#options}).\n\t * @param imageElement The image model element.\n\t */ shouldConvertImageType(requestedStyle, imageElement) {\n        const supportedTypes = this._styles.get(requestedStyle).modelElements;\n        return !supportedTypes.includes(imageElement.name);\n    }\n}\n\n/**\n * Default image style options provided by the plugin that can be referred in the {@link module:image/imageconfig~ImageConfig#styles}\n * configuration.\n *\n * There are available 5 styles focused on formatting:\n *\n * * **`'alignLeft'`** aligns the inline or block image to the left and wraps it with the text using the `image-style-align-left` class,\n * * **`'alignRight'`** aligns the inline or block image to the right and wraps it with the text using the `image-style-align-right` class,\n * * **`'alignCenter'`** centers the block image using the `image-style-align-center` class,\n * * **`'alignBlockLeft'`** aligns the block image to the left using the `image-style-block-align-left` class,\n * * **`'alignBlockRight'`** aligns the block image to the right using the `image-style-block-align-right` class,\n *\n * and 3 semantic styles:\n *\n * * **`'inline'`** is an inline image without any CSS class,\n * * **`'block'`** is a block image without any CSS class,\n * * **`'side'`** is a block image styled with the `image-style-side` CSS class.\n */ const DEFAULT_OPTIONS = {\n    // This style represents an image placed in the line of text.\n    get inline () {\n        return {\n            name: 'inline',\n            title: 'In line',\n            icon: icons.objectInline,\n            modelElements: [\n                'imageInline'\n            ],\n            isDefault: true\n        };\n    },\n    // This style represents an image aligned to the left and wrapped with text.\n    get alignLeft () {\n        return {\n            name: 'alignLeft',\n            title: 'Left aligned image',\n            icon: icons.objectLeft,\n            modelElements: [\n                'imageBlock',\n                'imageInline'\n            ],\n            className: 'image-style-align-left'\n        };\n    },\n    // This style represents an image aligned to the left.\n    get alignBlockLeft () {\n        return {\n            name: 'alignBlockLeft',\n            title: 'Left aligned image',\n            icon: icons.objectBlockLeft,\n            modelElements: [\n                'imageBlock'\n            ],\n            className: 'image-style-block-align-left'\n        };\n    },\n    // This style represents a centered image.\n    get alignCenter () {\n        return {\n            name: 'alignCenter',\n            title: 'Centered image',\n            icon: icons.objectCenter,\n            modelElements: [\n                'imageBlock'\n            ],\n            className: 'image-style-align-center'\n        };\n    },\n    // This style represents an image aligned to the right and wrapped with text.\n    get alignRight () {\n        return {\n            name: 'alignRight',\n            title: 'Right aligned image',\n            icon: icons.objectRight,\n            modelElements: [\n                'imageBlock',\n                'imageInline'\n            ],\n            className: 'image-style-align-right'\n        };\n    },\n    // This style represents an image aligned to the right.\n    get alignBlockRight () {\n        return {\n            name: 'alignBlockRight',\n            title: 'Right aligned image',\n            icon: icons.objectBlockRight,\n            modelElements: [\n                'imageBlock'\n            ],\n            className: 'image-style-block-align-right'\n        };\n    },\n    // This option is equal to the situation when no style is applied.\n    get block () {\n        return {\n            name: 'block',\n            title: 'Centered image',\n            icon: icons.objectCenter,\n            modelElements: [\n                'imageBlock'\n            ],\n            isDefault: true\n        };\n    },\n    // This represents a side image.\n    get side () {\n        return {\n            name: 'side',\n            title: 'Side image',\n            icon: icons.objectRight,\n            modelElements: [\n                'imageBlock'\n            ],\n            className: 'image-style-side'\n        };\n    }\n};\n/**\n * Default image style icons provided by the plugin that can be referred in the {@link module:image/imageconfig~ImageConfig#styles}\n * configuration.\n *\n * See {@link module:image/imageconfig~ImageStyleOptionDefinition#icon} to learn more.\n *\n * There are 7 default icons available: `'full'`, `'left'`, `'inlineLeft'`, `'center'`, `'right'`, `'inlineRight'`, and `'inline'`.\n */ const DEFAULT_ICONS = /* #__PURE__ */ (()=>({\n        full: icons.objectFullWidth,\n        left: icons.objectBlockLeft,\n        right: icons.objectBlockRight,\n        center: icons.objectCenter,\n        inlineLeft: icons.objectLeft,\n        inlineRight: icons.objectRight,\n        inline: icons.objectInline\n    }))();\n/**\n * Default drop-downs provided by the plugin that can be referred in the {@link module:image/imageconfig~ImageConfig#toolbar}\n * configuration. The drop-downs are containers for the {@link module:image/imageconfig~ImageStyleConfig#options image style options}.\n *\n * If both of the `ImageEditing` plugins are loaded, there are 2 predefined drop-downs available:\n *\n * * **`'imageStyle:wrapText'`**, which contains the `alignLeft` and `alignRight` options, that is,\n * those that wraps the text around the image,\n * * **`'imageStyle:breakText'`**, which contains the `alignBlockLeft`, `alignCenter` and `alignBlockRight` options, that is,\n * those that breaks the text around the image.\n */ const DEFAULT_DROPDOWN_DEFINITIONS = [\n    {\n        name: 'imageStyle:wrapText',\n        title: 'Wrap text',\n        defaultItem: 'imageStyle:alignLeft',\n        items: [\n            'imageStyle:alignLeft',\n            'imageStyle:alignRight'\n        ]\n    },\n    {\n        name: 'imageStyle:breakText',\n        title: 'Break text',\n        defaultItem: 'imageStyle:block',\n        items: [\n            'imageStyle:alignBlockLeft',\n            'imageStyle:block',\n            'imageStyle:alignBlockRight'\n        ]\n    }\n];\n/**\n * Returns a list of the normalized and validated image style options.\n *\n * @param config\n * @param config.isInlinePluginLoaded\n * Determines whether the {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`} plugin has been loaded.\n * @param config.isBlockPluginLoaded\n * Determines whether the {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`} plugin has been loaded.\n * @param config.configuredStyles\n * The image styles configuration provided in the image styles {@link module:image/imageconfig~ImageConfig#styles configuration}\n * as a default or custom value.\n * @returns\n * * Each of options contains a complete icon markup.\n * * The image style options not supported by any of the loaded plugins are filtered out.\n */ function normalizeStyles(config) {\n    const configuredStyles = config.configuredStyles.options || [];\n    const styles = configuredStyles.map((arrangement)=>normalizeDefinition(arrangement)).filter((arrangement)=>isValidOption(arrangement, config));\n    return styles;\n}\n/**\n * Returns the default image styles configuration depending on the loaded image editing plugins.\n *\n * @param isInlinePluginLoaded\n * Determines whether the {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`} plugin has been loaded.\n *\n * @param isBlockPluginLoaded\n * Determines whether the {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`} plugin has been loaded.\n *\n * @returns\n * It returns an object with the lists of the image style options and groups defined as strings related to the\n * {@link module:image/imagestyle/utils#DEFAULT_OPTIONS default options}\n */ function getDefaultStylesConfiguration(isBlockPluginLoaded, isInlinePluginLoaded) {\n    if (isBlockPluginLoaded && isInlinePluginLoaded) {\n        return {\n            options: [\n                'inline',\n                'alignLeft',\n                'alignRight',\n                'alignCenter',\n                'alignBlockLeft',\n                'alignBlockRight',\n                'block',\n                'side'\n            ]\n        };\n    } else if (isBlockPluginLoaded) {\n        return {\n            options: [\n                'block',\n                'side'\n            ]\n        };\n    } else if (isInlinePluginLoaded) {\n        return {\n            options: [\n                'inline',\n                'alignLeft',\n                'alignRight'\n            ]\n        };\n    }\n    return {};\n}\n/**\n * Returns a list of the available predefined drop-downs' definitions depending on the loaded image editing plugins.\n */ function getDefaultDropdownDefinitions(pluginCollection) {\n    if (pluginCollection.has('ImageBlockEditing') && pluginCollection.has('ImageInlineEditing')) {\n        return [\n            ...DEFAULT_DROPDOWN_DEFINITIONS\n        ];\n    } else {\n        return [];\n    }\n}\n/**\n * Normalizes an image style option or group provided in the {@link module:image/imageconfig~ImageConfig#styles}\n * and returns it in a {@link module:image/imageconfig~ImageStyleOptionDefinition}/\n */ function normalizeDefinition(definition) {\n    if (typeof definition === 'string') {\n        // Just the name of the style has been passed, but none of the defaults.\n        if (!DEFAULT_OPTIONS[definition]) {\n            // Normalize the style anyway to prevent errors.\n            definition = {\n                name: definition\n            };\n        } else {\n            definition = {\n                ...DEFAULT_OPTIONS[definition]\n            };\n        }\n    } else {\n        // If an object style has been passed and if the name matches one of the defaults,\n        // extend it with defaults – the user wants to customize a default style.\n        // Note: Don't override the user–defined style object, clone it instead.\n        definition = extendStyle(DEFAULT_OPTIONS[definition.name], definition);\n    }\n    // If an icon is defined as a string and correspond with a name\n    // in default icons, use the default icon provided by the plugin.\n    if (typeof definition.icon === 'string') {\n        definition.icon = DEFAULT_ICONS[definition.icon] || definition.icon;\n    }\n    return definition;\n}\n/**\n * Checks if the image style option is valid:\n * * if it has the modelElements fields defined and filled,\n * * if the defined modelElements are supported by any of the loaded image editing plugins.\n * It also displays a console warning these conditions are not met.\n *\n * @param option image style option\n */ function isValidOption(option, { isBlockPluginLoaded, isInlinePluginLoaded }) {\n    const { modelElements, name } = option;\n    if (!modelElements || !modelElements.length || !name) {\n        warnInvalidStyle({\n            style: option\n        });\n        return false;\n    } else {\n        const supportedElements = [\n            isBlockPluginLoaded ? 'imageBlock' : null,\n            isInlinePluginLoaded ? 'imageInline' : null\n        ];\n        // Check if the option is supported by any of the loaded plugins.\n        if (!modelElements.some((elementName)=>supportedElements.includes(elementName))) {\n            /**\n\t\t\t * In order to work correctly, each image style {@link module:image/imageconfig~ImageStyleOptionDefinition option}\n\t\t\t * requires specific model elements (also: types of images) to be supported by the editor.\n\t\t\t *\n\t\t\t * Model element names to which the image style option can be applied are defined in the\n\t\t\t * {@link module:image/imageconfig~ImageStyleOptionDefinition#modelElements} property of the style option\n\t\t\t * definition.\n\t\t\t *\n\t\t\t * Explore the warning in the console to find out precisely which option is not supported and which editor plugins\n\t\t\t * are missing. Make sure these plugins are loaded in your editor to get this image style option working.\n\t\t\t *\n\t\t\t * @error image-style-missing-dependency\n\t\t\t * @param {String} [option] The name of the unsupported option.\n\t\t\t * @param {String} [missingPlugins] The names of the plugins one of which has to be loaded for the particular option.\n\t\t\t */ logWarning('image-style-missing-dependency', {\n                style: option,\n                missingPlugins: modelElements.map((name)=>name === 'imageBlock' ? 'ImageBlockEditing' : 'ImageInlineEditing')\n            });\n            return false;\n        }\n    }\n    return true;\n}\n/**\n * Extends the default style with a style provided by the developer.\n * Note: Don't override the custom–defined style object, clone it instead.\n */ function extendStyle(source, style) {\n    const extendedStyle = {\n        ...style\n    };\n    for(const prop in source){\n        if (!Object.prototype.hasOwnProperty.call(style, prop)) {\n            extendedStyle[prop] = source[prop];\n        }\n    }\n    return extendedStyle;\n}\n/**\n * Displays a console warning with the 'image-style-configuration-definition-invalid' error.\n */ function warnInvalidStyle(info) {\n    /**\n\t * The image style definition provided in the configuration is invalid.\n\t *\n\t * Please make sure the definition implements properly one of the following:\n\t *\n\t * * {@link module:image/imageconfig~ImageStyleOptionDefinition image style option definition},\n\t * * {@link module:image/imageconfig~ImageStyleDropdownDefinition image style dropdown definition}\n\t *\n\t * @error image-style-configuration-definition-invalid\n\t * @param {String} [dropdown] The name of the invalid drop-down\n\t * @param {String} [style] The name of the invalid image style option\n\t */ logWarning('image-style-configuration-definition-invalid', info);\n}\nvar utils = {\n    normalizeStyles,\n    getDefaultStylesConfiguration,\n    getDefaultDropdownDefinitions,\n    warnInvalidStyle,\n    DEFAULT_OPTIONS,\n    DEFAULT_ICONS,\n    DEFAULT_DROPDOWN_DEFINITIONS\n};\n\n/**\n * @module image/imagestyle/converters\n */ /**\n * Returns a converter for the `imageStyle` attribute. It can be used for adding, changing and removing the attribute.\n *\n * @param styles An array containing available image style options.\n * @returns A model-to-view attribute converter.\n */ function modelToViewStyleAttribute(styles) {\n    return (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        // Check if there is class name associated with given value.\n        const newStyle = getStyleDefinitionByName(data.attributeNewValue, styles);\n        const oldStyle = getStyleDefinitionByName(data.attributeOldValue, styles);\n        const viewElement = conversionApi.mapper.toViewElement(data.item);\n        const viewWriter = conversionApi.writer;\n        if (oldStyle) {\n            viewWriter.removeClass(oldStyle.className, viewElement);\n        }\n        if (newStyle) {\n            viewWriter.addClass(newStyle.className, viewElement);\n        }\n    };\n}\n/**\n * Returns a view-to-model converter converting image CSS classes to a proper value in the model.\n *\n * @param styles Image style options for which the converter is created.\n * @returns A view-to-model converter.\n */ function viewToModelStyleAttribute(styles) {\n    // Convert only non–default styles.\n    const nonDefaultStyles = {\n        imageInline: styles.filter((style)=>!style.isDefault && style.modelElements.includes('imageInline')),\n        imageBlock: styles.filter((style)=>!style.isDefault && style.modelElements.includes('imageBlock'))\n    };\n    return (evt, data, conversionApi)=>{\n        if (!data.modelRange) {\n            return;\n        }\n        const viewElement = data.viewItem;\n        const modelImageElement = first(data.modelRange.getItems());\n        // Run this converter only if an image has been found in the model.\n        // In some cases it may not be found (for example if we run this on a figure with different type than image).\n        if (!modelImageElement) {\n            return;\n        }\n        // ...and the `imageStyle` attribute is allowed for that element, otherwise stop conversion early.\n        if (!conversionApi.schema.checkAttribute(modelImageElement, 'imageStyle')) {\n            return;\n        }\n        // Convert styles one by one.\n        for (const style of nonDefaultStyles[modelImageElement.name]){\n            // Try to consume class corresponding with the style.\n            if (conversionApi.consumable.consume(viewElement, {\n                classes: style.className\n            })) {\n                // And convert this style to model attribute.\n                conversionApi.writer.setAttribute('imageStyle', style.name, modelImageElement);\n            }\n        }\n    };\n}\n/**\n * Returns the style with a given `name` from an array of styles.\n */ function getStyleDefinitionByName(name, styles) {\n    for (const style of styles){\n        if (style.name === name) {\n            return style;\n        }\n    }\n}\n\n/**\n * The image style engine plugin. It sets the default configuration, creates converters and registers\n * {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand ImageStyleCommand}.\n */ class ImageStyleEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageStyleEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageUtils\n        ];\n    }\n    /**\n\t * It contains a list of the normalized and validated style options.\n\t *\n\t * * Each option contains a complete icon markup.\n\t * * The style options not supported by any of the loaded image editing plugins (\n\t * {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`} or\n\t * {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`}) are filtered out.\n\t *\n\t * @internal\n\t * @readonly\n\t */ normalizedStyles;\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const { normalizeStyles, getDefaultStylesConfiguration } = utils;\n        const editor = this.editor;\n        const isBlockPluginLoaded = editor.plugins.has('ImageBlockEditing');\n        const isInlinePluginLoaded = editor.plugins.has('ImageInlineEditing');\n        editor.config.define('image.styles', getDefaultStylesConfiguration(isBlockPluginLoaded, isInlinePluginLoaded));\n        this.normalizedStyles = normalizeStyles({\n            configuredStyles: editor.config.get('image.styles'),\n            isBlockPluginLoaded,\n            isInlinePluginLoaded\n        });\n        this._setupConversion(isBlockPluginLoaded, isInlinePluginLoaded);\n        this._setupPostFixer();\n        // Register imageStyle command.\n        editor.commands.add('imageStyle', new ImageStyleCommand(editor, this.normalizedStyles));\n    }\n    /**\n\t * Sets the editor conversion taking the presence of\n\t * {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`}\n\t * and {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`} plugins into consideration.\n\t */ _setupConversion(isBlockPluginLoaded, isInlinePluginLoaded) {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const modelToViewConverter = modelToViewStyleAttribute(this.normalizedStyles);\n        const viewToModelConverter = viewToModelStyleAttribute(this.normalizedStyles);\n        editor.editing.downcastDispatcher.on('attribute:imageStyle', modelToViewConverter);\n        editor.data.downcastDispatcher.on('attribute:imageStyle', modelToViewConverter);\n        // Allow imageStyle attribute in image and imageInline.\n        // We could call it 'style' but https://github.com/ckeditor/ckeditor5-engine/issues/559.\n        if (isBlockPluginLoaded) {\n            schema.extend('imageBlock', {\n                allowAttributes: 'imageStyle'\n            });\n            // Converter for figure element from view to model.\n            editor.data.upcastDispatcher.on('element:figure', viewToModelConverter, {\n                priority: 'low'\n            });\n        }\n        if (isInlinePluginLoaded) {\n            schema.extend('imageInline', {\n                allowAttributes: 'imageStyle'\n            });\n            // Converter for the img element from view to model.\n            editor.data.upcastDispatcher.on('element:img', viewToModelConverter, {\n                priority: 'low'\n            });\n        }\n    }\n    /**\n\t * Registers a post-fixer that will make sure that the style attribute value is correct for a specific image type (block vs inline).\n\t */ _setupPostFixer() {\n        const editor = this.editor;\n        const document = editor.model.document;\n        const imageUtils = editor.plugins.get(ImageUtils);\n        const stylesMap = new Map(this.normalizedStyles.map((style)=>[\n                style.name,\n                style\n            ]));\n        // Make sure that style attribute is valid for the image type.\n        document.registerPostFixer((writer)=>{\n            let changed = false;\n            for (const change of document.differ.getChanges()){\n                if (change.type == 'insert' || change.type == 'attribute' && change.attributeKey == 'imageStyle') {\n                    let element = change.type == 'insert' ? change.position.nodeAfter : change.range.start.nodeAfter;\n                    if (element && element.is('element', 'paragraph') && element.childCount > 0) {\n                        element = element.getChild(0);\n                    }\n                    if (!imageUtils.isImage(element)) {\n                        continue;\n                    }\n                    const imageStyle = element.getAttribute('imageStyle');\n                    if (!imageStyle) {\n                        continue;\n                    }\n                    const imageStyleDefinition = stylesMap.get(imageStyle);\n                    if (!imageStyleDefinition || !imageStyleDefinition.modelElements.includes(element.name)) {\n                        writer.removeAttribute('imageStyle', element);\n                        changed = true;\n                    }\n                }\n            }\n            return changed;\n        });\n    }\n}\n\n/**\n * The image style UI plugin.\n *\n * It registers buttons corresponding to the {@link module:image/imageconfig~ImageConfig#styles} configuration.\n * It also registers the {@link module:image/imagestyle/utils#DEFAULT_DROPDOWN_DEFINITIONS default drop-downs} and the\n * custom drop-downs defined by the developer in the {@link module:image/imageconfig~ImageConfig#toolbar} configuration.\n */ class ImageStyleUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageStyleEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageStyleUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * Returns the default localized style titles provided by the plugin.\n\t *\n\t * The following localized titles corresponding with\n\t * {@link module:image/imagestyle/utils#DEFAULT_OPTIONS} are available:\n\t *\n\t * * `'Wrap text'`,\n\t * * `'Break text'`,\n\t * * `'In line'`,\n\t * * `'Full size image'`,\n\t * * `'Side image'`,\n\t * * `'Left aligned image'`,\n\t * * `'Centered image'`,\n\t * * `'Right aligned image'`\n\t */ get localizedDefaultStylesTitles() {\n        const t = this.editor.t;\n        return {\n            'Wrap text': t('Wrap text'),\n            'Break text': t('Break text'),\n            'In line': t('In line'),\n            'Full size image': t('Full size image'),\n            'Side image': t('Side image'),\n            'Left aligned image': t('Left aligned image'),\n            'Centered image': t('Centered image'),\n            'Right aligned image': t('Right aligned image')\n        };\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const plugins = this.editor.plugins;\n        const toolbarConfig = this.editor.config.get('image.toolbar') || [];\n        const imageStyleEditing = plugins.get('ImageStyleEditing');\n        const definedStyles = translateStyles(imageStyleEditing.normalizedStyles, this.localizedDefaultStylesTitles);\n        for (const styleConfig of definedStyles){\n            this._createButton(styleConfig);\n        }\n        const definedDropdowns = translateStyles([\n            ...toolbarConfig.filter(isObject),\n            ...utils.getDefaultDropdownDefinitions(plugins)\n        ], this.localizedDefaultStylesTitles);\n        for (const dropdownConfig of definedDropdowns){\n            this._createDropdown(dropdownConfig, definedStyles);\n        }\n    }\n    /**\n\t * Creates a dropdown and stores it in the editor {@link module:ui/componentfactory~ComponentFactory}.\n\t */ _createDropdown(dropdownConfig, definedStyles) {\n        const factory = this.editor.ui.componentFactory;\n        factory.add(dropdownConfig.name, (locale)=>{\n            let defaultButton;\n            const { defaultItem, items, title } = dropdownConfig;\n            const buttonViews = items.filter((itemName)=>definedStyles.find(({ name })=>getUIComponentName(name) === itemName)).map((buttonName)=>{\n                const button = factory.create(buttonName);\n                if (buttonName === defaultItem) {\n                    defaultButton = button;\n                }\n                return button;\n            });\n            if (items.length !== buttonViews.length) {\n                utils.warnInvalidStyle({\n                    dropdown: dropdownConfig\n                });\n            }\n            const dropdownView = createDropdown(locale, SplitButtonView);\n            const splitButtonView = dropdownView.buttonView;\n            const splitButtonViewArrow = splitButtonView.arrowView;\n            addToolbarToDropdown(dropdownView, buttonViews, {\n                enableActiveItemFocusOnDropdownOpen: true\n            });\n            splitButtonView.set({\n                label: getDropdownButtonTitle(title, defaultButton.label),\n                class: null,\n                tooltip: true\n            });\n            splitButtonViewArrow.unbind('label');\n            splitButtonViewArrow.set({\n                label: title\n            });\n            splitButtonView.bind('icon').toMany(buttonViews, 'isOn', (...areOn)=>{\n                const index = areOn.findIndex(identity);\n                return index < 0 ? defaultButton.icon : buttonViews[index].icon;\n            });\n            splitButtonView.bind('label').toMany(buttonViews, 'isOn', (...areOn)=>{\n                const index = areOn.findIndex(identity);\n                return getDropdownButtonTitle(title, index < 0 ? defaultButton.label : buttonViews[index].label);\n            });\n            splitButtonView.bind('isOn').toMany(buttonViews, 'isOn', (...areOn)=>areOn.some(identity));\n            splitButtonView.bind('class').toMany(buttonViews, 'isOn', (...areOn)=>areOn.some(identity) ? 'ck-splitbutton_flatten' : undefined);\n            splitButtonView.on('execute', ()=>{\n                if (!buttonViews.some(({ isOn })=>isOn)) {\n                    defaultButton.fire('execute');\n                } else {\n                    dropdownView.isOpen = !dropdownView.isOpen;\n                }\n            });\n            dropdownView.bind('isEnabled').toMany(buttonViews, 'isEnabled', (...areEnabled)=>areEnabled.some(identity));\n            // Focus the editable after executing the command.\n            // Overrides a default behaviour where the focus is moved to the dropdown button (#12125).\n            this.listenTo(dropdownView, 'execute', ()=>{\n                this.editor.editing.view.focus();\n            });\n            return dropdownView;\n        });\n    }\n    /**\n\t * Creates a button and stores it in the editor {@link module:ui/componentfactory~ComponentFactory}.\n\t */ _createButton(buttonConfig) {\n        const buttonName = buttonConfig.name;\n        this.editor.ui.componentFactory.add(getUIComponentName(buttonName), (locale)=>{\n            const command = this.editor.commands.get('imageStyle');\n            const view = new ButtonView(locale);\n            view.set({\n                label: buttonConfig.title,\n                icon: buttonConfig.icon,\n                tooltip: true,\n                isToggleable: true\n            });\n            view.bind('isEnabled').to(command, 'isEnabled');\n            view.bind('isOn').to(command, 'value', (value)=>value === buttonName);\n            view.on('execute', this._executeCommand.bind(this, buttonName));\n            return view;\n        });\n    }\n    _executeCommand(name) {\n        this.editor.execute('imageStyle', {\n            value: name\n        });\n        this.editor.editing.view.focus();\n    }\n}\n/**\n * Returns the translated `title` from the passed styles array.\n */ function translateStyles(styles, titles) {\n    for (const style of styles){\n        // Localize the titles of the styles, if a title corresponds with\n        // a localized default provided by the plugin.\n        if (titles[style.title]) {\n            style.title = titles[style.title];\n        }\n    }\n    return styles;\n}\n/**\n * Returns the image style component name with the \"imageStyle:\" prefix.\n */ function getUIComponentName(name) {\n    return `imageStyle:${name}`;\n}\n/**\n * Returns title for the splitbutton containing the dropdown title and default action item title.\n */ function getDropdownButtonTitle(dropdownTitle, buttonTitle) {\n    return (dropdownTitle ? dropdownTitle + ': ' : '') + buttonTitle;\n}\n\n/**\n * The image style plugin.\n *\n * For a detailed overview of the image styles feature, check the {@glink features/images/images-styles documentation}.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n * * {@link module:image/imagestyle/imagestyleediting~ImageStyleEditing},\n * * {@link module:image/imagestyle/imagestyleui~ImageStyleUI}\n *\n * It provides a default configuration, which can be extended or overwritten.\n * Read more about the {@link module:image/imageconfig~ImageConfig#styles image styles configuration}.\n */ class ImageStyle extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageStyleEditing,\n            ImageStyleUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageStyle';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The image toolbar plugin. It creates and manages the image toolbar (the toolbar displayed when an image is selected).\n *\n * For an overview, check the {@glink features/images/images-overview#image-contextual-toolbar image contextual toolbar} documentation.\n *\n * Instances of toolbar components (e.g. buttons) are created using the editor's\n * {@link module:ui/componentfactory~ComponentFactory component factory}\n * based on the {@link module:image/imageconfig~ImageConfig#toolbar `image.toolbar` configuration option}.\n *\n * The toolbar uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n */ class ImageToolbar extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            WidgetToolbarRepository,\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ImageToolbar';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        const t = editor.t;\n        const widgetToolbarRepository = editor.plugins.get(WidgetToolbarRepository);\n        const imageUtils = editor.plugins.get('ImageUtils');\n        widgetToolbarRepository.register('image', {\n            ariaLabel: t('Image toolbar'),\n            items: normalizeDeclarativeConfig(editor.config.get('image.toolbar') || []),\n            getRelatedElement: (selection)=>imageUtils.getClosestSelectedImageWidget(selection)\n        });\n    }\n}\n/**\n * Convert the dropdown definitions to their keys registered in the ComponentFactory.\n * The registration precess should be handled by the plugin which handles the UI of a particular feature.\n */ function normalizeDeclarativeConfig(config) {\n    return config.map((item)=>isObject(item) ? item.name : item);\n}\n\n/**\n * This plugin enables the [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) element support in the editor.\n *\n * * It enables the `sources` model attribute on `imageBlock` and `imageInline` model elements\n * (brought by {@link module:image/imageblock~ImageBlock} and {@link module:image/imageinline~ImageInline}, respectively).\n * * It translates the `sources` model element to the view (also: data) structure that may look as follows:\n *\n * ```html\n * <p>Inline image using picture:\n * \t<picture>\n * \t\t<source media=\"(min-width: 800px)\" srcset=\"image-large.webp\" type=\"image/webp\">\n * \t\t<source media=\"(max-width: 800px)\" srcset=\"image-small.webp\" type=\"image/webp\">\n * \t\t<!-- Other sources as specified in the \"sources\" model attribute... -->\n * \t\t<img src=\"image.png\" alt=\"An image using picture\" />\n * \t</picture>\n * </p>\n *\n * <p>Block image using picture:</p>\n * <figure class=\"image\">\n * \t<picture>\n * \t\t<source media=\"(min-width: 800px)\" srcset=\"image-large.webp\" type=\"image/webp\">\n * \t\t<source media=\"(max-width: 800px)\" srcset=\"image-small.webp\" type=\"image/webp\">\n * \t\t<!-- Other sources as specified in the \"sources\" model attribute... -->\n * \t\t<img src=\"image.png\" alt=\"An image using picture\" />\n * \t</picture>\n * \t<figcaption>Caption of the image</figcaption>\n * </figure>\n * ```\n *\n * **Note:** The value of the `sources` {@glink framework/architecture/editing-engine#changing-the-model model attribute}\n * in both examples equals:\n *\n * ```css\n * [\n * \t{\n * \t\tmedia: '(min-width: 800px)',\n * \t\tsrcset: 'image-large.webp',\n * \t\ttype: 'image/webp'\n * \t},\n * \t{\n * \t\tmedia: '(max-width: 800px)',\n * \t\tsrcset: 'image-small.webp',\n * \t\ttype: 'image/webp'\n * \t}\n * ]\n * ```\n *\n * * It integrates with the {@link module:image/imageupload~ImageUpload} plugin so images uploaded in the editor\n * automatically render using `<picture>` if the {@glink features/images/image-upload/image-upload upload adapter}\n * supports image sources and provides neccessary data.\n *\n * @private\n */ class PictureEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ImageEditing,\n            ImageUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'PictureEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        if (editor.plugins.has('ImageBlockEditing')) {\n            editor.model.schema.extend('imageBlock', {\n                allowAttributes: [\n                    'sources'\n                ]\n            });\n        }\n        if (editor.plugins.has('ImageInlineEditing')) {\n            editor.model.schema.extend('imageInline', {\n                allowAttributes: [\n                    'sources'\n                ]\n            });\n        }\n        this._setupConversion();\n        this._setupImageUploadEditingIntegration();\n    }\n    /**\n\t * Configures conversion pipelines to support upcasting and downcasting images using the `<picture>` view element\n\t * and the model `sources` attribute.\n\t */ _setupConversion() {\n        const editor = this.editor;\n        const conversion = editor.conversion;\n        const imageUtils = editor.plugins.get('ImageUtils');\n        conversion.for('upcast').add(upcastPicture(imageUtils));\n        conversion.for('downcast').add(downcastSourcesAttribute(imageUtils));\n    }\n    /**\n\t * Makes it possible for uploaded images to get the `sources` model attribute and the `<picture>...</picture>`\n\t * view structure out-of-the-box if relevant data is provided along the\n\t * {@link module:image/imageupload/imageuploadediting~ImageUploadEditing#event:uploadComplete} event.\n\t */ _setupImageUploadEditingIntegration() {\n        const editor = this.editor;\n        if (!editor.plugins.has('ImageUploadEditing')) {\n            return;\n        }\n        const imageUploadEditing = editor.plugins.get('ImageUploadEditing');\n        this.listenTo(imageUploadEditing, 'uploadComplete', (evt, { imageElement, data })=>{\n            const sources = data.sources;\n            if (!sources) {\n                return;\n            }\n            editor.model.change((writer)=>{\n                writer.setAttributes({\n                    sources\n                }, imageElement);\n            });\n        });\n    }\n}\n\nexport { AutoImage, Image, ImageBlock, ImageBlockEditing, ImageCaption, ImageCaptionEditing, ImageCaptionUI, ImageCaptionUtils, ImageCustomResizeUI, ImageEditing, ImageInline, ImageInsert, ImageInsertUI, ImageInsertViaUrl, ImageResize, ImageResizeButtons, ImageResizeEditing, ImageResizeHandles, ImageSizeAttributes, ImageStyle, ImageStyleEditing, ImageStyleUI, ImageTextAlternative, ImageTextAlternativeEditing, ImageTextAlternativeUI, ImageToolbar, ImageUpload, ImageUploadEditing, ImageUploadProgress, ImageUploadUI, ImageUtils, PictureEditing, createImageTypeRegExp };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/utils\n */\n\nimport type {\n\tDocumentSelection,\n\tMatcherPattern,\n\tSchema,\n\tSelection,\n\tViewContainerElement,\n\tDowncastWriter,\n\tViewElement\n} from 'ckeditor5/src/engine.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\n\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * Creates a view element representing the inline image.\n *\n * ```html\n * <span class=\"image-inline\"><img></img></span>\n * ```\n *\n * Note that `alt` and `src` attributes are converted separately, so they are not included.\n *\n * @internal\n */\nexport function createInlineImageViewElement( writer: DowncastWriter ): ViewContainerElement {\n\treturn writer.createContainerElement( 'span', { class: 'image-inline' },\n\t\twriter.createEmptyElement( 'img' )\n\t);\n}\n\n/**\n * Creates a view element representing the block image.\n *\n * ```html\n * <figure class=\"image\"><img></img></figure>\n * ```\n *\n * Note that `alt` and `src` attributes are converted separately, so they are not included.\n *\n * @internal\n */\nexport function createBlockImageViewElement( writer: DowncastWriter ): ViewContainerElement {\n\treturn writer.createContainerElement( 'figure', { class: 'image' }, [\n\t\twriter.createEmptyElement( 'img' ),\n\t\twriter.createSlot( 'children' )\n\t] );\n}\n\n/**\n * A function returning a `MatcherPattern` for a particular type of View images.\n *\n * @internal\n * @param matchImageType The type of created image.\n */\nexport function getImgViewElementMatcher( editor: Editor, matchImageType: 'imageBlock' | 'imageInline' ): MatcherPattern {\n\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\tconst areBothImagePluginsLoaded = editor.plugins.has( 'ImageInlineEditing' ) && editor.plugins.has( 'ImageBlockEditing' );\n\n\treturn element => {\n\t\t// Check if the matched view element is an <img>.\n\t\tif ( !imageUtils.isInlineImageView( element ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// If just one of the plugins is loaded (block or inline), it will match all kinds of images.\n\t\tif ( !areBothImagePluginsLoaded ) {\n\t\t\treturn getPositiveMatchPattern( element );\n\t\t}\n\n\t\t// The <img> can be standalone, wrapped in <figure>...</figure> (ImageBlock plugin) or\n\t\t// wrapped in <figure><a>...</a></figure> (LinkImage plugin).\n\t\tconst imageType = element.getStyle( 'display' ) == 'block' || element.findAncestor( imageUtils.isBlockImageView ) ?\n\t\t\t'imageBlock' :\n\t\t\t'imageInline';\n\n\t\tif ( imageType !== matchImageType ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn getPositiveMatchPattern( element );\n\t};\n\n\tfunction getPositiveMatchPattern( element: ViewElement ) {\n\t\tconst pattern: Record<string, unknown> = {\n\t\t\tname: true\n\t\t};\n\n\t\t// This will trigger src consumption (See https://github.com/ckeditor/ckeditor5/issues/11530).\n\t\tif ( element.hasAttribute( 'src' ) ) {\n\t\t\tpattern.attributes = [ 'src' ];\n\t\t}\n\n\t\treturn pattern;\n\t}\n}\n\n/**\n * Considering the current model selection, it returns the name of the model image element\n * (`'imageBlock'` or `'imageInline'`) that will make most sense from the UX perspective if a new\n * image was inserted (also: uploaded, dropped, pasted) at that selection.\n *\n * The assumption is that inserting images into empty blocks or on other block widgets should\n * produce block images. Inline images should be inserted in other cases, e.g. in paragraphs\n * that already contain some text.\n *\n * @internal\n */\nexport function determineImageTypeForInsertionAtSelection(\n\tschema: Schema,\n\tselection: Selection | DocumentSelection\n): 'imageBlock' | 'imageInline' {\n\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t// Insert a block image if the selection is not in/on block elements or it's on a block widget.\n\tif ( !firstBlock || schema.isObject( firstBlock ) ) {\n\t\treturn 'imageBlock';\n\t}\n\n\t// A block image should also be inserted into an empty block element\n\t// (that is not an empty list item so the list won't get split).\n\tif ( firstBlock.isEmpty && firstBlock.name != 'listItem' ) {\n\t\treturn 'imageBlock';\n\t}\n\n\t// Otherwise insert an inline image.\n\treturn 'imageInline';\n}\n\n/**\n * Returns parsed value of the size, but only if it contains unit: px.\n */\nexport function getSizeValueIfInPx( size: string | undefined ): number | null {\n\tif ( size && size.endsWith( 'px' ) ) {\n\t\treturn parseInt( size );\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns true if both styles (width and height) are set.\n *\n * If both image styles: width & height are set, they will override the image width & height attributes in the\n * browser. In this case, the image looks the same as if these styles were applied to attributes instead of styles.\n * That's why we can upcast these styles to width & height attributes instead of resizedWidth and resizedHeight.\n */\nexport function widthAndHeightStylesAreBothSet( viewElement: ViewElement ): boolean {\n\tconst widthStyle = getSizeValueIfInPx( viewElement.getStyle( 'width' ) );\n\tconst heightStyle = getSizeValueIfInPx( viewElement.getStyle( 'height' ) );\n\n\treturn !!( widthStyle && heightStyle );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageutils\n */\n\nimport type {\n\tElement,\n\tViewElement,\n\tViewNode,\n\tDocumentSelection,\n\tViewDocumentSelection,\n\tSelection,\n\tViewSelection,\n\tDocumentFragment,\n\tViewDocumentFragment,\n\tDowncastWriter,\n\tModel,\n\tPosition,\n\tViewContainerElement\n} from 'ckeditor5/src/engine.js';\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { findOptimalInsertionRange, isWidget, toWidget } from 'ckeditor5/src/widget.js';\nimport { determineImageTypeForInsertionAtSelection } from './image/utils.js';\nimport { DomEmitterMixin, type DomEmitter, global } from 'ckeditor5/src/utils.js';\n\nconst IMAGE_WIDGETS_CLASSES_MATCH_REGEXP = /^(image|image-inline)$/;\n\n/**\n * A set of helpers related to images.\n */\nexport default class ImageUtils extends Plugin {\n\t/**\n\t * DOM Emitter.\n\t */\n\tprivate _domEmitter: DomEmitter = new ( DomEmitterMixin() )();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageUtils' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks if the provided model element is an `image` or `imageInline`.\n\t */\n\tpublic isImage( modelElement?: Element | null ): modelElement is Element & { name: 'imageInline' | 'imageBlock' } {\n\t\treturn this.isInlineImage( modelElement ) || this.isBlockImage( modelElement );\n\t}\n\n\t/**\n\t * Checks if the provided view element represents an inline image.\n\t *\n\t * Also, see {@link module:image/imageutils~ImageUtils#isImageWidget}.\n\t */\n\tpublic isInlineImageView( element?: ViewElement | null ): boolean {\n\t\treturn !!element && element.is( 'element', 'img' );\n\t}\n\n\t/**\n\t * Checks if the provided view element represents a block image.\n\t *\n\t * Also, see {@link module:image/imageutils~ImageUtils#isImageWidget}.\n\t */\n\tpublic isBlockImageView( element?: ViewElement | null ): boolean {\n\t\treturn !!element && element.is( 'element', 'figure' ) && element.hasClass( 'image' );\n\t}\n\n\t/**\n\t * Handles inserting single file. This method unifies image insertion using {@link module:widget/utils~findOptimalInsertionRange}\n\t * method.\n\t *\n\t * ```ts\n\t * const imageUtils = editor.plugins.get( 'ImageUtils' );\n\t *\n\t * imageUtils.insertImage( { src: 'path/to/image.jpg' } );\n\t * ```\n\t *\n\t * @param attributes Attributes of the inserted image.\n\t * This method filters out the attributes which are disallowed by the {@link module:engine/model/schema~Schema}.\n\t * @param selectable Place to insert the image. If not specified,\n\t * the {@link module:widget/utils~findOptimalInsertionRange} logic will be applied for the block images\n\t * and `model.document.selection` for the inline images.\n\t *\n\t * **Note**: If `selectable` is passed, this helper will not be able to set selection attributes (such as `linkHref`)\n\t * and apply them to the new image. In this case, make sure all selection attributes are passed in `attributes`.\n\t *\n\t * @param imageType Image type of inserted image. If not specified,\n\t * it will be determined automatically depending of editor config or place of the insertion.\n\t * @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.\n\t * The default is `true`.\n\t * @return The inserted model image element.\n\t */\n\tpublic insertImage(\n\t\tattributes: Record<string, unknown> = {},\n\t\tselectable: Selection | Position | null = null,\n\t\timageType: ( 'imageBlock' | 'imageInline' | null ) = null,\n\t\toptions: { setImageSizes?: boolean } = {}\n\t): Element | null {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tconst determinedImageType = determineImageTypeForInsertion( editor, selectable || selection, imageType );\n\n\t\t// Mix declarative attributes with selection attributes because the new image should \"inherit\"\n\t\t// the latter for best UX. For instance, inline images inserted into existing links\n\t\t// should not split them. To do that, they need to have \"linkHref\" inherited from the selection.\n\t\tattributes = {\n\t\t\t...Object.fromEntries( selection.getAttributes() ),\n\t\t\t...attributes\n\t\t};\n\n\t\tfor ( const attributeName in attributes ) {\n\t\t\tif ( !model.schema.checkAttribute( determinedImageType, attributeName ) ) {\n\t\t\t\tdelete attributes[ attributeName ];\n\t\t\t}\n\t\t}\n\n\t\treturn model.change( writer => {\n\t\t\tconst { setImageSizes = true } = options;\n\t\t\tconst imageElement = writer.createElement( determinedImageType, attributes );\n\n\t\t\tmodel.insertObject( imageElement, selectable, null, {\n\t\t\t\tsetSelection: 'on',\n\t\t\t\t// If we want to insert a block image (for whatever reason) then we don't want to split text blocks.\n\t\t\t\t// This applies only when we don't have the selectable specified (i.e., we insert multiple block images at once).\n\t\t\t\tfindOptimalPosition: !selectable && determinedImageType != 'imageInline' ? 'auto' : undefined\n\t\t\t} );\n\n\t\t\t// Inserting an image might've failed due to schema regulations.\n\t\t\tif ( imageElement.parent ) {\n\t\t\t\tif ( setImageSizes ) {\n\t\t\t\t\tthis.setImageNaturalSizeAttributes( imageElement );\n\t\t\t\t}\n\n\t\t\t\treturn imageElement;\n\t\t\t}\n\n\t\t\treturn null;\n\t\t} );\n\t}\n\n\t/**\n\t * Reads original image sizes and sets them as `width` and `height`.\n\t *\n\t * The `src` attribute may not be available if the user is using an upload adapter. In such a case,\n\t * this method is called again after the upload process is complete and the `src` attribute is available.\n\t */\n\tpublic setImageNaturalSizeAttributes( imageElement: Element ): void {\n\t\tconst src = imageElement.getAttribute( 'src' ) as string;\n\n\t\tif ( !src ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( imageElement.getAttribute( 'width' ) || imageElement.getAttribute( 'height' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.editor.model.change( writer => {\n\t\t\tconst img = new global.window.Image();\n\n\t\t\tthis._domEmitter.listenTo( img, 'load', () => {\n\t\t\t\tif ( !imageElement.getAttribute( 'width' ) && !imageElement.getAttribute( 'height' ) ) {\n\t\t\t\t\t// We use writer.batch to be able to undo (in a single step) width and height setting\n\t\t\t\t\t// along with any change that triggered this action (e.g. image resize or image style change).\n\t\t\t\t\tthis.editor.model.enqueueChange( writer.batch, writer => {\n\t\t\t\t\t\twriter.setAttribute( 'width', img.naturalWidth, imageElement );\n\t\t\t\t\t\twriter.setAttribute( 'height', img.naturalHeight, imageElement );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tthis._domEmitter.stopListening( img, 'load' );\n\t\t\t} );\n\n\t\t\timg.src = src;\n\t\t} );\n\t}\n\n\t/**\n\t * Returns an image widget editing view element if one is selected or is among the selection's ancestors.\n\t */\n\tpublic getClosestSelectedImageWidget( selection: ViewSelection | ViewDocumentSelection ): ViewElement | null {\n\t\tconst selectionPosition = selection.getFirstPosition();\n\n\t\tif ( !selectionPosition ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst viewElement = selection.getSelectedElement();\n\n\t\tif ( viewElement && this.isImageWidget( viewElement ) ) {\n\t\t\treturn viewElement;\n\t\t}\n\n\t\tlet parent: ViewNode | ViewDocumentFragment | null = selectionPosition.parent;\n\n\t\twhile ( parent ) {\n\t\t\tif ( parent.is( 'element' ) && this.isImageWidget( parent ) ) {\n\t\t\t\treturn parent;\n\t\t\t}\n\n\t\t\tparent = parent.parent;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns a image model element if one is selected or is among the selection's ancestors.\n\t */\n\tpublic getClosestSelectedImageElement( selection: Selection | DocumentSelection ): Element | null {\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\treturn this.isImage( selectedElement ) ? selectedElement : selection.getFirstPosition()!.findAncestor( 'imageBlock' );\n\t}\n\n\t/**\n\t * Returns an image widget editing view based on the passed image view.\n\t */\n\tpublic getImageWidgetFromImageView( imageView: ViewElement ): ViewContainerElement | null {\n\t\treturn imageView.findAncestor( { classes: IMAGE_WIDGETS_CLASSES_MATCH_REGEXP } ) as ( ViewContainerElement | null );\n\t}\n\n\t/**\n\t * Checks if image can be inserted at current model selection.\n\t *\n\t * @internal\n\t */\n\tpublic isImageAllowed(): boolean {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\treturn isImageAllowedInParent( this.editor, selection ) && isNotInsideImage( selection );\n\t}\n\n\t/**\n\t * Converts a given {@link module:engine/view/element~Element} to an image widget:\n\t * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the image widget\n\t * element.\n\t * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n\t *\n\t * @param writer An instance of the view writer.\n\t * @param label The element's label. It will be concatenated with the image `alt` attribute if one is present.\n\t */\n\tpublic toImageWidget( viewElement: ViewElement, writer: DowncastWriter, label: string ): ViewElement {\n\t\twriter.setCustomProperty( 'image', true, viewElement );\n\n\t\tconst labelCreator = () => {\n\t\t\tconst imgElement = this.findViewImgElement( viewElement )!;\n\t\t\tconst altText = imgElement.getAttribute( 'alt' );\n\n\t\t\treturn altText ? `${ altText } ${ label }` : label;\n\t\t};\n\n\t\treturn toWidget( viewElement, writer, { label: labelCreator } );\n\t}\n\n\t/**\n\t * Checks if a given view element is an image widget.\n\t */\n\tprotected isImageWidget( viewElement: ViewElement ): boolean {\n\t\treturn !!viewElement.getCustomProperty( 'image' ) && isWidget( viewElement );\n\t}\n\n\t/**\n\t * Checks if the provided model element is an `image`.\n\t */\n\tpublic isBlockImage( modelElement?: Element | null ): boolean {\n\t\treturn !!modelElement && modelElement.is( 'element', 'imageBlock' );\n\t}\n\n\t/**\n\t * Checks if the provided model element is an `imageInline`.\n\t */\n\tpublic isInlineImage( modelElement?: Element | null ): boolean {\n\t\treturn !!modelElement && modelElement.is( 'element', 'imageInline' );\n\t}\n\n\t/**\n\t * Get the view `<img>` from another view element, e.g. a widget (`<figure class=\"image\">`), a link (`<a>`).\n\t *\n\t * The `<img>` can be located deep in other elements, so this helper performs a deep tree search.\n\t */\n\tpublic findViewImgElement( figureView: ViewElement ): ViewElement | undefined {\n\t\tif ( this.isInlineImageView( figureView ) ) {\n\t\t\treturn figureView;\n\t\t}\n\n\t\tconst editingView = this.editor.editing.view;\n\n\t\tfor ( const { item } of editingView.createRangeIn( figureView ) ) {\n\t\t\tif ( this.isInlineImageView( item as ViewElement ) ) {\n\t\t\t\treturn item as ViewElement;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis._domEmitter.stopListening();\n\n\t\treturn super.destroy();\n\t}\n}\n\n/**\n * Checks if image is allowed by schema in optimal insertion parent.\n */\nfunction isImageAllowedInParent( editor: Editor, selection: Selection | DocumentSelection ): boolean {\n\tconst imageType = determineImageTypeForInsertion( editor, selection, null );\n\n\tif ( imageType == 'imageBlock' ) {\n\t\tconst parent = getInsertImageParent( selection, editor.model );\n\n\t\tif ( editor.model.schema.checkChild( parent as Element, 'imageBlock' ) ) {\n\t\t\treturn true;\n\t\t}\n\t} else if ( editor.model.schema.checkChild( selection.focus!, 'imageInline' ) ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Checks if selection is not placed inside an image (e.g. its caption).\n */\nfunction isNotInsideImage( selection: DocumentSelection ): boolean {\n\treturn [ ...selection.focus!.getAncestors() ].every( ancestor => !ancestor.is( 'element', 'imageBlock' ) );\n}\n\n/**\n * Returns a node that will be used to insert image with `model.insertContent`.\n */\nfunction getInsertImageParent( selection: Selection | DocumentSelection, model: Model ): Element | DocumentFragment {\n\tconst insertionRange = findOptimalInsertionRange( selection, model );\n\tconst parent = insertionRange.start.parent;\n\n\tif ( parent.isEmpty && !parent.is( 'element', '$root' ) ) {\n\t\treturn parent.parent!;\n\t}\n\n\treturn parent;\n}\n\n/**\n * Determine image element type name depending on editor config or place of insertion.\n *\n * @param imageType Image element type name. Used to force return of provided element name,\n * but only if there is proper plugin enabled.\n */\nfunction determineImageTypeForInsertion(\n\teditor: Editor,\n\tselectable: Position | Selection | DocumentSelection,\n\timageType: 'imageBlock' | 'imageInline' | null\n): 'imageBlock' | 'imageInline' {\n\tconst schema = editor.model.schema;\n\tconst configImageInsertType = editor.config.get( 'image.insert.type' );\n\n\tif ( !editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\treturn 'imageInline';\n\t}\n\n\tif ( !editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\treturn 'imageBlock';\n\t}\n\n\tif ( imageType ) {\n\t\treturn imageType;\n\t}\n\n\tif ( configImageInsertType === 'inline' ) {\n\t\treturn 'imageInline';\n\t}\n\n\tif ( configImageInsertType !== 'auto' ) {\n\t\treturn 'imageBlock';\n\t}\n\n\t// Try to replace the selected widget (e.g. another image).\n\tif ( selectable.is( 'selection' ) ) {\n\t\treturn determineImageTypeForInsertionAtSelection( schema, selectable );\n\t}\n\n\treturn schema.checkChild( selectable, 'imageInline' ) ? 'imageInline' : 'imageBlock';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/autoimage\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { Clipboard, type ClipboardPipeline } from 'ckeditor5/src/clipboard.js';\nimport { LivePosition, LiveRange } from 'ckeditor5/src/engine.js';\nimport { Undo } from 'ckeditor5/src/undo.js';\nimport { Delete } from 'ckeditor5/src/typing.js';\nimport { global } from 'ckeditor5/src/utils.js';\n\nimport ImageUtils from './imageutils.js';\n\n// Implements the pattern: http(s)://(www.)example.com/path/to/resource.ext?query=params&maybe=too.\nconst IMAGE_URL_REGEXP = new RegExp( String( /^(http(s)?:\\/\\/)?[\\w-]+\\.[\\w.~:/[\\]@!$&'()*+,;=%-]+/.source +\n\t/\\.(jpg|jpeg|png|gif|ico|webp|JPG|JPEG|PNG|GIF|ICO|WEBP)/.source +\n\t/(\\?[\\w.~:/[\\]@!$&'()*+,;=%-]*)?/.source +\n\t/(#[\\w.~:/[\\]@!$&'()*+,;=%-]*)?$/.source ) );\n\n/**\n * The auto-image plugin. It recognizes image links in the pasted content and embeds\n * them shortly after they are injected into the document.\n */\nexport default class AutoImage extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Clipboard, ImageUtils, Undo, Delete ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'AutoImage' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * The paste–to–embed `setTimeout` ID. Stored as a property to allow\n\t * cleaning of the timeout.\n\t */\n\tprivate _timeoutId: ReturnType<typeof setTimeout> | null;\n\n\t/**\n\t * The position where the `<imageBlock>` element will be inserted after the timeout,\n\t * determined each time a new content is pasted into the document.\n\t */\n\tprivate _positionToInsert: LivePosition | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._timeoutId = null;\n\n\t\tthis._positionToInsert = null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst modelDocument = editor.model.document;\n\t\tconst clipboardPipeline: ClipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\n\t\t// We need to listen on `Clipboard#inputTransformation` because we need to save positions of selection.\n\t\t// After pasting, the content between those positions will be checked for a URL that could be transformed\n\t\t// into an image.\n\t\tthis.listenTo( clipboardPipeline, 'inputTransformation', () => {\n\t\t\tconst firstRange = modelDocument.selection.getFirstRange()!;\n\n\t\t\tconst leftLivePosition = LivePosition.fromPosition( firstRange.start );\n\t\t\tleftLivePosition.stickiness = 'toPrevious';\n\n\t\t\tconst rightLivePosition = LivePosition.fromPosition( firstRange.end );\n\t\t\trightLivePosition.stickiness = 'toNext';\n\n\t\t\tmodelDocument.once( 'change:data', () => {\n\t\t\t\tthis._embedImageBetweenPositions( leftLivePosition, rightLivePosition );\n\n\t\t\t\tleftLivePosition.detach();\n\t\t\t\trightLivePosition.detach();\n\t\t\t}, { priority: 'high' } );\n\t\t} );\n\n\t\teditor.commands.get( 'undo' )!.on( 'execute', () => {\n\t\t\tif ( this._timeoutId ) {\n\t\t\t\tglobal.window.clearTimeout( this._timeoutId );\n\t\t\t\tthis._positionToInsert!.detach();\n\n\t\t\t\tthis._timeoutId = null;\n\t\t\t\tthis._positionToInsert = null;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Analyzes the part of the document between provided positions in search for a URL representing an image.\n\t * When the URL is found, it is automatically converted into an image.\n\t *\n\t * @param leftPosition Left position of the selection.\n\t * @param rightPosition Right position of the selection.\n\t */\n\tprivate _embedImageBetweenPositions( leftPosition: LivePosition, rightPosition: LivePosition ): void {\n\t\tconst editor = this.editor;\n\t\t// TODO: Use a marker instead of LiveRange & LivePositions.\n\t\tconst urlRange = new LiveRange( leftPosition, rightPosition );\n\t\tconst walker = urlRange.getWalker( { ignoreElementEnd: true } );\n\t\tconst selectionAttributes = Object.fromEntries( editor.model.document.selection.getAttributes() );\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\tlet src = '';\n\n\t\tfor ( const node of walker ) {\n\t\t\tif ( node.item.is( '$textProxy' ) ) {\n\t\t\t\tsrc += node.item.data;\n\t\t\t}\n\t\t}\n\n\t\tsrc = src.trim();\n\n\t\t// If the URL does not match the image URL regexp, let's skip that.\n\t\tif ( !src.match( IMAGE_URL_REGEXP ) ) {\n\t\t\turlRange.detach();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Position will not be available in the `setTimeout` function so let's clone it.\n\t\tthis._positionToInsert = LivePosition.fromPosition( leftPosition );\n\n\t\t// This action mustn't be executed if undo was called between pasting and auto-embedding.\n\t\tthis._timeoutId = setTimeout( () => {\n\t\t\t// Do nothing if image element cannot be inserted at the current position.\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/2763.\n\t\t\t// Condition must be checked after timeout - pasting may take place on an element, replacing it. The final position matters.\n\t\t\tconst imageCommand = editor.commands.get( 'insertImage' )!;\n\n\t\t\tif ( !imageCommand.isEnabled ) {\n\t\t\t\turlRange.detach();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\tthis._timeoutId = null;\n\n\t\t\t\twriter.remove( urlRange );\n\t\t\t\turlRange.detach();\n\n\t\t\t\tlet insertionPosition;\n\n\t\t\t\t// Check if the position where the element should be inserted is still valid.\n\t\t\t\t// Otherwise leave it as undefined to use the logic of insertImage().\n\t\t\t\tif ( this._positionToInsert!.root.rootName !== '$graveyard' ) {\n\t\t\t\t\tinsertionPosition = this._positionToInsert!.toPosition();\n\t\t\t\t}\n\n\t\t\t\timageUtils.insertImage( { ...selectionAttributes, src }, insertionPosition );\n\n\t\t\t\tthis._positionToInsert!.detach();\n\t\t\t\tthis._positionToInsert = null;\n\t\t\t} );\n\n\t\t\tconst deletePlugin: Delete = editor.plugins.get( 'Delete' );\n\n\t\t\tdeletePlugin.requestUndoOnBackspace();\n\t\t}, 100 );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagetextalternative/imagetextalternativecommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * The image text alternative command. It is used to change the `alt` attribute of `<imageBlock>` and `<imageInline>` model elements.\n */\nexport default class ImageTextAlternativeCommand extends Command {\n\t/**\n\t * The command value: `false` if there is no `alt` attribute, otherwise the value of the `alt` attribute.\n\t *\n\t * @readonly\n\t * @observable\n\t */\n\tdeclare public value: string | false;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst element = imageUtils.getClosestSelectedImageElement( this.editor.model.document.selection )!;\n\n\t\tthis.isEnabled = !!element;\n\n\t\tif ( this.isEnabled && element.hasAttribute( 'alt' ) ) {\n\t\t\tthis.value = element.getAttribute( 'alt' ) as string | false;\n\t\t} else {\n\t\t\tthis.value = false;\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options\n\t * @param options.newValue The new value of the `alt` attribute to set.\n\t */\n\tpublic override execute( options: { newValue: string } ): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst model = editor.model;\n\t\tconst imageElement = imageUtils.getClosestSelectedImageElement( model.document.selection );\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setAttribute( 'alt', options.newValue, imageElement! );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagetextalternative/imagetextalternativeediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageTextAlternativeCommand from './imagetextalternativecommand.js';\nimport ImageUtils from '../imageutils.js';\n\n/**\n * The image text alternative editing plugin.\n *\n * Registers the `'imageTextAlternative'` command.\n */\nexport default class ImageTextAlternativeEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageTextAlternativeEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tthis.editor.commands.add( 'imageTextAlternative', new ImageTextAlternativeCommand( this.editor ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagetextalternative/ui/textalternativeformview\n */\n\nimport {\n\tButtonView,\n\tFocusCycler,\n\tLabeledFieldView,\n\tView,\n\tViewCollection,\n\tcreateLabeledInputText,\n\tsubmitHandler,\n\ttype InputView,\n\ttype FocusableView\n} from 'ckeditor5/src/ui.js';\nimport { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';\nimport { icons } from 'ckeditor5/src/core.js';\n\nimport '../../../theme/textalternativeform.css';\n\n// See: #8833.\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';\n\n/**\n * The TextAlternativeFormView class.\n */\nexport default class TextAlternativeFormView extends View {\n\t/**\n\t * Tracks information about the DOM focus in the form.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * An input with a label.\n\t */\n\tpublic labeledInput: LabeledFieldView<InputView>;\n\n\t/**\n\t * A button used to submit the form.\n\t */\n\tpublic saveButtonView: ButtonView;\n\n\t/**\n\t * A button used to cancel the form.\n\t */\n\tpublic cancelButtonView: ButtonView;\n\n\t/**\n\t * A collection of views which can be focused in the form.\n\t */\n\tprotected readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */\n\tprotected readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\t\tconst t = this.locale!.t;\n\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis.labeledInput = this._createLabeledInputView();\n\n\t\tthis.saveButtonView = this._createButton( t( 'Save' ), icons.check, 'ck-button-save' );\n\t\tthis.saveButtonView.type = 'submit';\n\n\t\tthis.cancelButtonView = this._createButton( t( 'Cancel' ), icons.cancel, 'ck-button-cancel', 'cancel' );\n\n\t\tthis._focusables = new ViewCollection();\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-text-alternative-form',\n\t\t\t\t\t'ck-responsive-form'\n\t\t\t\t],\n\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-image/issues/40\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.labeledInput,\n\t\t\t\tthis.saveButtonView,\n\t\t\t\tthis.cancelButtonView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\tsubmitHandler( { view: this } );\n\n\t\t[ this.labeledInput, this.saveButtonView, this.cancelButtonView ]\n\t\t\t.forEach( v => {\n\t\t\t\t// Register the view as focusable.\n\t\t\t\tthis._focusables.add( v );\n\n\t\t\t\t// Register the view in the focus tracker.\n\t\t\t\tthis.focusTracker.add( v.element! );\n\t\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Creates the button view.\n\t *\n\t * @param label The button label\n\t * @param icon The button's icon.\n\t * @param className The additional button CSS class name.\n\t * @param eventName The event name that the ButtonView#execute event will be delegated to.\n\t * @returns The button view instance.\n\t */\n\tprivate _createButton( label: string, icon: string, className: string, eventName?: string ): ButtonView {\n\t\tconst button = new ButtonView( this.locale );\n\n\t\tbutton.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\tbutton.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: className\n\t\t\t}\n\t\t} );\n\n\t\tif ( eventName ) {\n\t\t\tbutton.delegate( 'execute' ).to( this, eventName );\n\t\t}\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates an input with a label.\n\t *\n\t * @returns Labeled field view instance.\n\t */\n\tprivate _createLabeledInputView(): LabeledFieldView<InputView> {\n\t\tconst t = this.locale!.t;\n\t\tconst labeledInput = new LabeledFieldView<InputView>( this.locale, createLabeledInputText );\n\n\t\tlabeledInput.label = t( 'Text alternative' );\n\n\t\treturn labeledInput;\n\t}\n}\n\n/**\n * Fired when the form view is submitted.\n *\n * @eventName ~TextAlternativeFormView#submit\n */\nexport type TextAlternativeFormViewSubmitEvent = {\n\tname: 'submit';\n\targs: [];\n};\n\n/**\n * Fired when the form view is canceled.\n *\n * @eventName ~TextAlternativeFormView#cancel\n */\nexport type TextAlternativeFormViewCancelEvent = {\n\tname: 'cancel';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/ui/utils\n */\n\nimport type { PositionOptions } from 'ckeditor5/src/utils.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport { BalloonPanelView, type ContextualBalloon } from 'ckeditor5/src/ui.js';\n\nimport type ImageUtils from '../../imageutils.js';\n\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the image in the editor content, if one is selected.\n *\n * @param editor The editor instance.\n */\nexport function repositionContextualBalloon( editor: Editor ): void {\n\tconst balloon: ContextualBalloon = editor.plugins.get( 'ContextualBalloon' );\n\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\tif ( imageUtils.getClosestSelectedImageWidget( editor.editing.view.document.selection ) ) {\n\t\tconst position = getBalloonPositionData( editor );\n\n\t\tballoon.updatePosition( position );\n\t}\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected element in the editor content.\n *\n * @param editor The editor instance.\n */\nexport function getBalloonPositionData( editor: Editor ): Partial<PositionOptions> {\n\tconst editingView = editor.editing.view;\n\tconst defaultPositions = BalloonPanelView.defaultPositions;\n\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\treturn {\n\t\ttarget: editingView.domConverter.mapViewToDom(\n\t\t\timageUtils.getClosestSelectedImageWidget( editingView.document.selection )!\n\t\t) as HTMLElement,\n\t\tpositions: [\n\t\t\tdefaultPositions.northArrowSouth,\n\t\t\tdefaultPositions.northArrowSouthWest,\n\t\t\tdefaultPositions.northArrowSouthEast,\n\t\t\tdefaultPositions.southArrowNorth,\n\t\t\tdefaultPositions.southArrowNorthWest,\n\t\t\tdefaultPositions.southArrowNorthEast,\n\t\t\tdefaultPositions.viewportStickyNorth\n\t\t]\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagetextalternative/imagetextalternativeui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core.js';\nimport {\n\tButtonView,\n\tContextualBalloon,\n\tclickOutsideHandler,\n\tCssTransitionDisablerMixin,\n\ttype ViewWithCssTransitionDisabler\n} from 'ckeditor5/src/ui.js';\n\nimport TextAlternativeFormView, {\n\ttype TextAlternativeFormViewCancelEvent,\n\ttype TextAlternativeFormViewSubmitEvent\n} from './ui/textalternativeformview.js';\nimport { repositionContextualBalloon, getBalloonPositionData } from '../image/ui/utils.js';\nimport type ImageTextAlternativeCommand from './imagetextalternativecommand.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * The image text alternative UI plugin.\n *\n * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n */\nexport default class ImageTextAlternativeUI extends Plugin {\n\t/**\n\t * The contextual balloon plugin instance.\n\t */\n\tprivate _balloon?: ContextualBalloon;\n\n\t/**\n\t * A form containing a textarea and buttons, used to change the `alt` text value.\n\t */\n\tprivate _form?: TextAlternativeFormView & ViewWithCssTransitionDisabler;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageTextAlternativeUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tthis._createButton();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n\t\tif ( this._form ) {\n\t\t\tthis._form.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a button showing the balloon panel for changing the image text alternative and\n\t * registers it in the editor {@link module:ui/componentfactory~ComponentFactory ComponentFactory}.\n\t */\n\tprivate _createButton(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'imageTextAlternative', locale => {\n\t\t\tconst command: ImageTextAlternativeCommand = editor.commands.get( 'imageTextAlternative' )!;\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: t( 'Change image text alternative' ),\n\t\t\t\ticon: icons.textAlternative,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t\t\tview.bind( 'isOn' ).to( command, 'value', value => !!value );\n\n\t\t\tthis.listenTo( view, 'execute', () => {\n\t\t\t\tthis._showForm();\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the {@link module:image/imagetextalternative/ui/textalternativeformview~TextAlternativeFormView}\n\t * form.\n\t */\n\tprivate _createForm(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\tthis._balloon = this.editor.plugins.get( 'ContextualBalloon' );\n\n\t\tthis._form = new ( CssTransitionDisablerMixin( TextAlternativeFormView ) )( editor.locale );\n\n\t\t// Render the form so its #element is available for clickOutsideHandler.\n\t\tthis._form.render();\n\n\t\tthis.listenTo<TextAlternativeFormViewSubmitEvent>( this._form, 'submit', () => {\n\t\t\teditor.execute( 'imageTextAlternative', {\n\t\t\t\tnewValue: this._form!.labeledInput.fieldView.element!.value\n\t\t\t} );\n\n\t\t\tthis._hideForm( true );\n\t\t} );\n\n\t\tthis.listenTo<TextAlternativeFormViewCancelEvent>( this._form, 'cancel', () => {\n\t\t\tthis._hideForm( true );\n\t\t} );\n\n\t\t// Close the form on Esc key press.\n\t\tthis._form.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideForm( true );\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Reposition the balloon or hide the form if an image widget is no longer selected.\n\t\tthis.listenTo( editor.ui, 'update', () => {\n\t\t\tif ( !imageUtils.getClosestSelectedImageWidget( viewDocument.selection ) ) {\n\t\t\t\tthis._hideForm( true );\n\t\t\t} else if ( this._isVisible ) {\n\t\t\t\trepositionContextualBalloon( editor );\n\t\t\t}\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: this._form,\n\t\t\tactivator: () => this._isVisible,\n\t\t\tcontextElements: () => [ this._balloon!.view.element! ],\n\t\t\tcallback: () => this._hideForm()\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the {@link #_form} in the {@link #_balloon}.\n\t */\n\tprivate _showForm(): void {\n\t\tif ( this._isVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this._form ) {\n\t\t\tthis._createForm();\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst command: ImageTextAlternativeCommand = editor.commands.get( 'imageTextAlternative' )!;\n\t\tconst labeledInput = this._form!.labeledInput;\n\n\t\tthis._form!.disableCssTransitions();\n\n\t\tif ( !this._isInBalloon ) {\n\t\t\tthis._balloon!.add( {\n\t\t\t\tview: this._form!,\n\t\t\t\tposition: getBalloonPositionData( editor )\n\t\t\t} );\n\t\t}\n\n\t\t// Make sure that each time the panel shows up, the field remains in sync with the value of\n\t\t// the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`\n\t\t// stays unaltered) and re-opened it without changing the value of the command, they would see the\n\t\t// old value instead of the actual value of the command.\n\t\t// https://github.com/ckeditor/ckeditor5-image/issues/114\n\t\tlabeledInput.fieldView.value = labeledInput.fieldView.element!.value = command.value || '';\n\n\t\tthis._form!.labeledInput.fieldView.select();\n\n\t\tthis._form!.enableCssTransitions();\n\t}\n\n\t/**\n\t * Removes the {@link #_form} from the {@link #_balloon}.\n\t *\n\t * @param focusEditable Controls whether the editing view is focused afterwards.\n\t */\n\tprivate _hideForm( focusEditable: boolean = false ): void {\n\t\tif ( !this._isInBalloon ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Blur the input element before removing it from DOM to prevent issues in some browsers.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\tif ( this._form!.focusTracker.isFocused ) {\n\t\t\tthis._form!.saveButtonView.focus();\n\t\t}\n\n\t\tthis._balloon!.remove( this._form! );\n\n\t\tif ( focusEditable ) {\n\t\t\tthis.editor.editing.view.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #_form} is the visible view in the {@link #_balloon}.\n\t */\n\tprivate get _isVisible(): boolean {\n\t\treturn !!this._balloon && this._balloon.visibleView === this._form;\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #_form} is in the {@link #_balloon}.\n\t */\n\tprivate get _isInBalloon(): boolean {\n\t\treturn !!this._balloon && this._balloon.hasView( this._form! );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagetextalternative\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageTextAlternativeEditing from './imagetextalternative/imagetextalternativeediting.js';\nimport ImageTextAlternativeUI from './imagetextalternative/imagetextalternativeui.js';\n\n/**\n * The image text alternative plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-styles image styles} documentation.\n *\n * This is a \"glue\" plugin which loads the\n *  {@link module:image/imagetextalternative/imagetextalternativeediting~ImageTextAlternativeEditing}\n * and {@link module:image/imagetextalternative/imagetextalternativeui~ImageTextAlternativeUI} plugins.\n */\nexport default class ImageTextAlternative extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageTextAlternativeEditing, ImageTextAlternativeUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageTextAlternative' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/converters\n */\n\nimport type {\n\tDowncastDispatcher,\n\tElement,\n\tUpcastDispatcher,\n\tUpcastElementEvent,\n\tViewElement,\n\tViewElementAttributes,\n\tDowncastAttributeEvent\n} from 'ckeditor5/src/engine.js';\nimport { first, type GetCallback } from 'ckeditor5/src/utils.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * Returns a function that converts the image view representation:\n *\n * ```html\n * <figure class=\"image\"><img src=\"...\" alt=\"...\"></img></figure>\n * ```\n *\n * to the model representation:\n *\n * ```html\n * <imageBlock src=\"...\" alt=\"...\"></imageBlock>\n * ```\n *\n * The entire content of the `<figure>` element except the first `<img>` is being converted as children\n * of the `<imageBlock>` model element.\n *\n * @internal\n */\nexport function upcastImageFigure( imageUtils: ImageUtils ): ( dispatcher: UpcastDispatcher ) => void {\n\tconst converter: GetCallback<UpcastElementEvent> = ( evt, data, conversionApi ) => {\n\t\t// Do not convert if this is not an \"image figure\".\n\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true, classes: 'image' } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find an image element inside the figure element.\n\t\tconst viewImage = imageUtils.findViewImgElement( data.viewItem );\n\n\t\t// Do not convert if image element is absent or was already converted.\n\t\tif ( !viewImage || !conversionApi.consumable.test( viewImage, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Consume the figure to prevent other converters from processing it again.\n\t\tconversionApi.consumable.consume( data.viewItem, { name: true, classes: 'image' } );\n\n\t\t// Convert view image to model image.\n\t\tconst conversionResult = conversionApi.convertItem( viewImage, data.modelCursor );\n\n\t\t// Get image element from conversion result.\n\t\tconst modelImage = first( conversionResult.modelRange!.getItems() ) as Element;\n\n\t\t// When image wasn't successfully converted then finish conversion.\n\t\tif ( !modelImage ) {\n\t\t\t// Revert consumed figure so other features can convert it.\n\t\t\tconversionApi.consumable.revert( data.viewItem, { name: true, classes: 'image' } );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert rest of the figure element's children as an image children.\n\t\tconversionApi.convertChildren( data.viewItem, modelImage );\n\n\t\tconversionApi.updateConversionResult( modelImage, data );\n\t};\n\n\treturn dispatcher => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:figure', converter );\n\t};\n}\n\n/**\n * Returns a function that converts the image view representation:\n *\n * ```html\n * <picture><source ... /><source ... />...<img ... /></picture>\n * ```\n *\n * to the model representation as the `sources` attribute:\n *\n * ```html\n * <image[Block|Inline] ... sources=\"...\"></image[Block|Inline]>\n * ```\n *\n * @internal\n */\nexport function upcastPicture( imageUtils: ImageUtils ): ( dispatcher: UpcastDispatcher ) => void {\n\tconst sourceAttributeNames = [ 'srcset', 'media', 'type', 'sizes' ];\n\n\tconst converter: GetCallback<UpcastElementEvent> = ( evt, data, conversionApi ) => {\n\t\tconst pictureViewElement = data.viewItem;\n\n\t\t// Do not convert <picture> if already consumed.\n\t\tif ( !conversionApi.consumable.test( pictureViewElement, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst sources = new Map<ViewElement, Record<string, string | undefined>>();\n\n\t\t// Collect all <source /> elements attribute values.\n\t\tfor ( const childSourceElement of pictureViewElement.getChildren() ) {\n\t\t\tif ( childSourceElement.is( 'element', 'source' ) ) {\n\t\t\t\tconst attributes: Record<string, string | undefined> = {};\n\n\t\t\t\tfor ( const name of sourceAttributeNames ) {\n\t\t\t\t\tif ( childSourceElement.hasAttribute( name ) ) {\n\t\t\t\t\t\t// Don't collect <source /> attribute if already consumed somewhere else.\n\t\t\t\t\t\tif ( conversionApi.consumable.test( childSourceElement, { attributes: name } ) ) {\n\t\t\t\t\t\t\tattributes[ name ] = childSourceElement.getAttribute( name );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( Object.keys( attributes ).length ) {\n\t\t\t\t\tsources.set( childSourceElement, attributes );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst imgViewElement = imageUtils.findViewImgElement( pictureViewElement );\n\n\t\t// Don't convert when a picture has no <img/> inside (it is broken).\n\t\tif ( !imgViewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet modelImage = data.modelCursor.parent;\n\n\t\t// - In case of an inline image (cursor parent in a <paragraph>), the <img/> must be converted right away\n\t\t// because no converter handled it yet and otherwise there would be no model element to set the sources attribute on.\n\t\t// - In case of a block image, the <figure class=\"image\"> converter (in ImageBlockEditing) converts the\n\t\t// <img/> right away on its own and the modelCursor is already inside an imageBlock and there's nothing special\n\t\t// to do here.\n\t\tif ( !modelImage.is( 'element', 'imageBlock' ) ) {\n\t\t\tconst conversionResult = conversionApi.convertItem( imgViewElement, data.modelCursor );\n\n\t\t\t// Set image range as conversion result.\n\t\t\tdata.modelRange = conversionResult.modelRange;\n\n\t\t\t// Continue conversion where image conversion ends.\n\t\t\tdata.modelCursor = conversionResult.modelCursor;\n\n\t\t\tmodelImage = first( conversionResult.modelRange!.getItems() ) as Element;\n\t\t}\n\n\t\tconversionApi.consumable.consume( pictureViewElement, { name: true } );\n\n\t\t// Consume only these <source/> attributes that were actually collected and will be passed on\n\t\t// to the image model element.\n\t\tfor ( const [ sourceElement, attributes ] of sources ) {\n\t\t\tconversionApi.consumable.consume( sourceElement, { attributes: Object.keys( attributes ) } );\n\t\t}\n\n\t\tif ( sources.size ) {\n\t\t\tconversionApi.writer.setAttribute( 'sources', Array.from( sources.values() ), modelImage );\n\t\t}\n\n\t\t// Convert rest of the <picture> children as an image children. Other converters may want to consume them.\n\t\tconversionApi.convertChildren( pictureViewElement, modelImage );\n\t};\n\n\treturn dispatcher => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:picture', converter );\n\t};\n}\n\n/**\n * Converter used to convert the `srcset` model image attribute to the `srcset` and `sizes` attributes in the view.\n *\n * @internal\n * @param imageType The type of the image.\n */\nexport function downcastSrcsetAttribute(\n\timageUtils: ImageUtils,\n\timageType: 'imageBlock' | 'imageInline'\n): ( dispatcher: DowncastDispatcher ) => void {\n\tconst converter: GetCallback<DowncastAttributeEvent<Element>> = ( evt, data, conversionApi\t) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst writer = conversionApi.writer;\n\t\tconst element = conversionApi.mapper.toViewElement( data.item )!;\n\t\tconst img = imageUtils.findViewImgElement( element )!;\n\n\t\tif ( data.attributeNewValue === null ) {\n\t\t\twriter.removeAttribute( 'srcset', img );\n\t\t\twriter.removeAttribute( 'sizes', img );\n\t\t} else {\n\t\t\tif ( data.attributeNewValue ) {\n\t\t\t\twriter.setAttribute( 'srcset', data.attributeNewValue, img );\n\t\t\t\t// Always outputting `100vw`. See https://github.com/ckeditor/ckeditor5-image/issues/2.\n\t\t\t\twriter.setAttribute( 'sizes', '100vw', img );\n\t\t\t}\n\t\t}\n\t};\n\n\treturn dispatcher => {\n\t\tdispatcher.on<DowncastAttributeEvent<Element>>( `attribute:srcset:${ imageType }`, converter );\n\t};\n}\n\n/**\n * Converts the `source` model attribute to the `<picture><source /><source />...<img /></picture>`\n * view structure.\n *\n * @internal\n */\nexport function downcastSourcesAttribute( imageUtils: ImageUtils ): ( dispatcher: DowncastDispatcher ) => void {\n\tconst converter: GetCallback<DowncastAttributeEvent<Element>> = ( evt, data, conversionApi\t) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst element = conversionApi.mapper.toViewElement( data.item )!;\n\t\tconst imgElement = imageUtils.findViewImgElement( element )!;\n\t\tconst attributeNewValue = data.attributeNewValue as null | Array<ViewElementAttributes>;\n\n\t\tif ( attributeNewValue && attributeNewValue.length ) {\n\t\t\t// Collect all wrapping attribute elements.\n\t\t\tconst attributeElements = [];\n\t\t\tlet viewElement = imgElement.parent;\n\n\t\t\twhile ( viewElement && viewElement.is( 'attributeElement' ) ) {\n\t\t\t\tconst parentElement = viewElement.parent;\n\n\t\t\t\tviewWriter.unwrap( viewWriter.createRangeOn( imgElement ), viewElement );\n\n\t\t\t\tattributeElements.unshift( viewElement );\n\t\t\t\tviewElement = parentElement;\n\t\t\t}\n\n\t\t\tconst hasPictureElement = imgElement.parent!.is( 'element', 'picture' );\n\n\t\t\t// Reuse existing <picture> element (ckeditor5#17192) or create a new one.\n\t\t\tconst pictureElement = hasPictureElement ? imgElement.parent : viewWriter.createContainerElement( 'picture', null );\n\n\t\t\tif ( !hasPictureElement ) {\n\t\t\t\tviewWriter.insert( viewWriter.createPositionBefore( imgElement ), pictureElement );\n\t\t\t}\n\n\t\t\tviewWriter.remove( viewWriter.createRangeIn( pictureElement ) );\n\n\t\t\tviewWriter.insert( viewWriter.createPositionAt( pictureElement, 'end' ),\n\t\t\t\tattributeNewValue.map( sourceAttributes => {\n\t\t\t\t\treturn viewWriter.createEmptyElement( 'source', sourceAttributes );\n\t\t\t\t} )\n\t\t\t);\n\n\t\t\tviewWriter.move( viewWriter.createRangeOn( imgElement ), viewWriter.createPositionAt( pictureElement, 'end' ) );\n\n\t\t\t// Apply collected attribute elements over the new picture element.\n\t\t\tfor ( const attributeElement of attributeElements ) {\n\t\t\t\tviewWriter.wrap( viewWriter.createRangeOn( pictureElement ), attributeElement );\n\t\t\t}\n\t\t}\n\t\t// Both setting \"sources\" to an empty array and removing the attribute should unwrap the <img />.\n\t\t// Unwrap once if the latter followed the former, though.\n\t\telse if ( imgElement.parent!.is( 'element', 'picture' ) ) {\n\t\t\tconst pictureElement = imgElement.parent;\n\n\t\t\tviewWriter.move( viewWriter.createRangeOn( imgElement ), viewWriter.createPositionBefore( pictureElement ) );\n\t\t\tviewWriter.remove( pictureElement );\n\t\t}\n\t};\n\n\treturn dispatcher => {\n\t\tdispatcher.on<DowncastAttributeEvent<Element>>( 'attribute:sources:imageBlock', converter );\n\t\tdispatcher.on<DowncastAttributeEvent<Element>>( 'attribute:sources:imageInline', converter );\n\t};\n}\n\n/**\n * Converter used to convert a given image attribute from the model to the view.\n *\n * @internal\n * @param imageType The type of the image.\n * @param attributeKey The name of the attribute to convert.\n */\nexport function downcastImageAttribute(\n\timageUtils: ImageUtils,\n\timageType: 'imageBlock' | 'imageInline',\n\tattributeKey: string\n): ( dispatcher: DowncastDispatcher ) => void {\n\tconst converter: GetCallback<DowncastAttributeEvent<Element>> = ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst element = conversionApi.mapper.toViewElement( data.item )!;\n\t\tconst img = imageUtils.findViewImgElement( element )!;\n\n\t\tviewWriter.setAttribute( data.attributeKey, data.attributeNewValue || '', img );\n\t};\n\n\treturn dispatcher => {\n\t\tdispatcher.on<DowncastAttributeEvent<Element>>( `attribute:${ attributeKey }:${ imageType }`, converter );\n\t};\n}\n\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/imageloadobserver\n */\n\nimport { Observer } from 'ckeditor5/src/engine.js';\n\n/**\n * Observes all new images added to the {@link module:engine/view/document~Document},\n * fires {@link module:engine/view/document~Document#event:imageLoaded} and\n * {@link module:engine/view/document~Document#event:layoutChanged} event every time when the new image\n * has been loaded.\n *\n * **Note:** This event is not fired for images that has been added to the document and rendered as `complete` (already loaded).\n */\nexport default class ImageLoadObserver extends Observer {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic observe( domRoot: HTMLElement ): void {\n\t\tthis.listenTo( domRoot, 'load', ( event, domEvent ) => {\n\t\t\tconst domElement = domEvent.target as HTMLElement;\n\n\t\t\tif ( this.checkShouldIgnoreEventFromTarget( domElement ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( domElement.tagName == 'IMG' ) {\n\t\t\t\tthis._fireEvents( domEvent );\n\t\t\t}\n\t\t\t// Use capture phase for better performance (#4504).\n\t\t}, { useCapture: true } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override stopObserving( domRoot: HTMLElement ): void {\n\t\tthis.stopListening( domRoot );\n\t}\n\n\t/**\n\t * Fires {@link module:engine/view/document~Document#event:layoutChanged} and\n\t * {@link module:engine/view/document~Document#event:imageLoaded}\n\t * if observer {@link #isEnabled is enabled}.\n\t *\n\t * @param domEvent The DOM event.\n\t */\n\tprivate _fireEvents( domEvent: Event ): void {\n\t\tif ( this.isEnabled ) {\n\t\t\tthis.document.fire( 'layoutChanged' );\n\t\t\tthis.document.fire<ImageLoadedEvent>( 'imageLoaded', domEvent );\n\t\t}\n\t}\n}\n\n/**\n * Fired when an <img/> DOM element has been loaded in the DOM root.\n *\n * Introduced by {@link module:image/image/imageloadobserver~ImageLoadObserver}.\n *\n * @see module:image/image/imageloadobserver~ImageLoadObserver\n *\n * @eventName module:engine/view/document~Document#imageLoaded\n * @param data Event data.\n */\nexport type ImageLoadedEvent = {\n\tname: 'imageLoaded';\n\targs: [ Event ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/insertimagecommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport { logWarning, toArray, type ArrayOrItem } from 'ckeditor5/src/utils.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * Insert image command.\n *\n * The command is registered by the {@link module:image/image/imageediting~ImageEditing} plugin as `insertImage`\n * and it is also available via aliased `imageInsert` name.\n *\n * In order to insert an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionRange} algorithm),\n * execute the command and specify the image source:\n *\n * ```ts\n * editor.execute( 'insertImage', { source: 'http://url.to.the/image' } );\n * ```\n *\n * It is also possible to insert multiple images at once:\n *\n * ```ts\n * editor.execute( 'insertImage', {\n * \tsource:  [\n * \t\t'path/to/image.jpg',\n * \t\t'path/to/other-image.jpg'\n * \t]\n * } );\n * ```\n *\n * If you want to take the full control over the process, you can specify individual model attributes:\n *\n * ```ts\n * editor.execute( 'insertImage', {\n * \tsource:  [\n * \t\t{ src: 'path/to/image.jpg', alt: 'First alt text' },\n * \t\t{ src: 'path/to/other-image.jpg', alt: 'Second alt text', customAttribute: 'My attribute value' }\n * \t]\n * } );\n * ```\n */\nexport default class InsertImageCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tconst configImageInsertType = editor.config.get( 'image.insert.type' );\n\n\t\tif ( !editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\tif ( configImageInsertType === 'block' ) {\n\t\t\t\t/**\n\t\t\t\t * The {@link module:image/imageblock~ImageBlock} plugin must be enabled to allow inserting block images. See\n\t\t\t\t * {@link module:image/imageconfig~ImageInsertConfig#type} to learn more.\n\t\t\t\t *\n\t\t\t\t * @error image-block-plugin-required\n\t\t\t\t */\n\t\t\t\tlogWarning( 'image-block-plugin-required' );\n\t\t\t}\n\t\t}\n\n\t\tif ( !editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\tif ( configImageInsertType === 'inline' ) {\n\t\t\t\t/**\n\t\t\t\t * The {@link module:image/imageinline~ImageInline} plugin must be enabled to allow inserting inline images. See\n\t\t\t\t * {@link module:image/imageconfig~ImageInsertConfig#type} to learn more.\n\t\t\t\t *\n\t\t\t\t * @error image-inline-plugin-required\n\t\t\t\t */\n\t\t\t\tlogWarning( 'image-inline-plugin-required' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\tthis.isEnabled = imageUtils.isImageAllowed();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.imageType The type of the image to insert. If not specified, the type will be determined automatically.\n\t * @param options.source The image source or an array of image sources to insert.\n\t * See the documentation of the command to learn more about accepted formats.\n\t */\n\tpublic override execute(\n\t\toptions: {\n\t\t\tsource: ArrayOrItem<string | Record<string, unknown>>;\n\t\t\timageType?: 'imageBlock' | 'imageInline' | null;\n\t\t}\n\t): void {\n\t\tconst sourceDefinitions = toArray<string | Record<string, unknown>>( options.source );\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\t// In case of multiple images, each image (starting from the 2nd) will be inserted at a position that\n\t\t// follows the previous one. That will move the selection and, to stay on the safe side and make sure\n\t\t// all images inherit the same selection attributes, they are collected beforehand.\n\t\t//\n\t\t// Applying these attributes ensures, for instance, that inserting an (inline) image into a link does\n\t\t// not split that link but preserves its continuity.\n\t\t//\n\t\t// Note: Selection attributes that do not make sense for images will be filtered out by insertImage() anyway.\n\t\tconst selectionAttributes = Object.fromEntries( selection.getAttributes() );\n\n\t\tsourceDefinitions.forEach( ( sourceDefinition, index ) => {\n\t\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t\tif ( typeof sourceDefinition === 'string' ) {\n\t\t\t\tsourceDefinition = { src: sourceDefinition };\n\t\t\t}\n\n\t\t\t// Inserting of an inline image replace the selected element and make a selection on the inserted image.\n\t\t\t// Therefore inserting multiple inline images requires creating position after each element.\n\t\t\tif ( index && selectedElement && imageUtils.isImage( selectedElement ) ) {\n\t\t\t\tconst position = this.editor.model.createPositionAfter( selectedElement );\n\n\t\t\t\timageUtils.insertImage( { ...sourceDefinition, ...selectionAttributes }, position, options.imageType );\n\t\t\t} else {\n\t\t\t\timageUtils.insertImage( { ...sourceDefinition, ...selectionAttributes }, null, options.imageType );\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type ImageUtils from '../imageutils.js';\nimport type { Writer, Element } from 'ckeditor5/src/engine.js';\n\n/**\n * @module image/image/replaceimagesourcecommand\n */\n\n/**\n * Replace image source command.\n *\n * Changes image source to the one provided. Can be executed as follows:\n *\n * ```ts\n * editor.execute( 'replaceImageSource', { source: 'http://url.to.the/image' } );\n * ```\n */\nexport default class ReplaceImageSourceCommand extends Command {\n\tdeclare public value: string | null;\n\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis.decorate( 'cleanupImage' );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst element = this.editor.model.document.selection.getSelectedElement()!;\n\n\t\tthis.isEnabled = imageUtils.isImage( element );\n\t\tthis.value = this.isEnabled ? element.getAttribute( 'src' ) as string : null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.source The image source to replace.\n\t */\n\tpublic override execute( options: { source: string } ): void {\n\t\tconst image = this.editor.model.document.selection.getSelectedElement()!;\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\tthis.editor.model.change( writer => {\n\t\t\twriter.setAttribute( 'src', options.source, image );\n\n\t\t\tthis.cleanupImage( writer, image );\n\n\t\t\timageUtils.setImageNaturalSizeAttributes( image );\n\t\t} );\n\t}\n\n\t/**\n\t * Cleanup image attributes that are not relevant to the new source.\n\t *\n\t * Removed attributes are: 'srcset', 'sizes', 'sources', 'width', 'height', 'alt'.\n\t *\n\t * This method is decorated, to allow custom cleanup logic.\n\t * For example, to remove 'myImageId' attribute after 'src' has changed:\n\t *\n\t * ```ts\n\t * replaceImageSourceCommand.on( 'cleanupImage', ( eventInfo, [ writer, image ] ) => {\n\t * \twriter.removeAttribute( 'myImageId', image );\n\t * } );\n\t * ```\n\t */\n\tpublic cleanupImage( writer: Writer, image: Element ): void {\n\t\twriter.removeAttribute( 'srcset', image );\n\t\twriter.removeAttribute( 'sizes', image );\n\n\t\t/**\n\t\t * In case responsive images some attributes should be cleaned up.\n\t\t * Check: https://github.com/ckeditor/ckeditor5/issues/15093\n\t\t */\n\t\twriter.removeAttribute( 'sources', image );\n\t\twriter.removeAttribute( 'width', image );\n\t\twriter.removeAttribute( 'height', image );\n\t\twriter.removeAttribute( 'alt', image );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/imageediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageLoadObserver from './imageloadobserver.js';\nimport InsertImageCommand from './insertimagecommand.js';\nimport ReplaceImageSourceCommand from './replaceimagesourcecommand.js';\nimport ImageUtils from '../imageutils.js';\n\n/**\n * The image engine plugin. This module loads common code shared between\n * {@link module:image/image/imageinlineediting~ImageInlineEditing} and\n * {@link module:image/image/imageblockediting~ImageBlockEditing} plugins.\n *\n * This plugin registers the {@link module:image/image/insertimagecommand~InsertImageCommand 'insertImage'} command.\n */\nexport default class ImageEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst conversion = editor.conversion;\n\n\t\t// See https://github.com/ckeditor/ckeditor5-image/issues/142.\n\t\teditor.editing.view.addObserver( ImageLoadObserver );\n\n\t\tconversion.for( 'upcast' )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tkey: 'alt'\n\t\t\t\t},\n\t\t\t\tmodel: 'alt'\n\t\t\t} )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tkey: 'srcset'\n\t\t\t\t},\n\t\t\t\tmodel: 'srcset'\n\t\t\t} );\n\n\t\tconst insertImageCommand = new InsertImageCommand( editor );\n\t\tconst replaceImageSourceCommand = new ReplaceImageSourceCommand( editor );\n\n\t\teditor.commands.add( 'insertImage', insertImageCommand );\n\t\teditor.commands.add( 'replaceImageSource', replaceImageSourceCommand );\n\n\t\t// `imageInsert` is an alias for backward compatibility.\n\t\teditor.commands.add( 'imageInsert', insertImageCommand );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagesizeattributes\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type { DowncastDispatcher, DowncastAttributeEvent, ViewElement, Element } from 'ckeditor5/src/engine.js';\nimport ImageUtils from './imageutils.js';\nimport { widthAndHeightStylesAreBothSet, getSizeValueIfInPx } from './image/utils.js';\n\n/**\n * This plugin enables `width` and `height` attributes in inline and block image elements.\n */\nexport default class ImageSizeAttributes extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageSizeAttributes' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tthis._registerSchema();\n\t\tthis._registerConverters( 'imageBlock' );\n\t\tthis._registerConverters( 'imageInline' );\n\t}\n\n\t/**\n\t * Registers the `width` and `height` attributes for inline and block images.\n\t */\n\tprivate _registerSchema(): void {\n\t\tif ( this.editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\tthis.editor.model.schema.extend( 'imageBlock', { allowAttributes: [ 'width', 'height' ] } );\n\t\t}\n\n\t\tif ( this.editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\tthis.editor.model.schema.extend( 'imageInline', { allowAttributes: [ 'width', 'height' ] } );\n\t\t}\n\t}\n\n\t/**\n\t * Registers converters for `width` and `height` attributes.\n\t */\n\tprivate _registerConverters( imageType: 'imageBlock' | 'imageInline' ): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst viewElementName = imageType === 'imageBlock' ? 'figure' : 'img';\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: viewElementName,\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\twidth: /.+/\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: 'width',\n\t\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\t\tif ( widthAndHeightStylesAreBothSet( viewElement ) ) {\n\t\t\t\t\t\t\treturn getSizeValueIfInPx( viewElement.getStyle( 'width' ) );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: viewElementName,\n\t\t\t\t\tkey: 'width'\n\t\t\t\t},\n\t\t\t\tmodel: 'width'\n\t\t\t} )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: viewElementName,\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\theight: /.+/\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: 'height',\n\t\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\t\tif ( widthAndHeightStylesAreBothSet( viewElement ) ) {\n\t\t\t\t\t\t\treturn getSizeValueIfInPx( viewElement.getStyle( 'height' ) );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: viewElementName,\n\t\t\t\t\tkey: 'height'\n\t\t\t\t},\n\t\t\t\tmodel: 'height'\n\t\t\t} );\n\n\t\t// Dedicated converters to propagate attributes to the <img> element.\n\t\teditor.conversion.for( 'editingDowncast' ).add( dispatcher => {\n\t\t\tattachDowncastConverter( dispatcher, 'width', 'width', true );\n\t\t\tattachDowncastConverter( dispatcher, 'height', 'height', true );\n\t\t} );\n\n\t\teditor.conversion.for( 'dataDowncast' ).add( dispatcher => {\n\t\t\tattachDowncastConverter( dispatcher, 'width', 'width', false );\n\t\t\tattachDowncastConverter( dispatcher, 'height', 'height', false );\n\t\t} );\n\n\t\tfunction attachDowncastConverter(\n\t\t\tdispatcher: DowncastDispatcher,\n\t\t\tmodelAttributeName: string,\n\t\t\tviewAttributeName: string,\n\t\t\tsetRatioForInlineImage: boolean\n\t\t) {\n\t\t\tdispatcher.on<DowncastAttributeEvent>( `attribute:${ modelAttributeName }:${ imageType }`, ( evt, data, conversionApi ) => {\n\t\t\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item as Element )!;\n\t\t\t\tconst img = imageUtils.findViewImgElement( viewElement )!;\n\n\t\t\t\tif ( data.attributeNewValue !== null ) {\n\t\t\t\t\tviewWriter.setAttribute( viewAttributeName, data.attributeNewValue, img );\n\t\t\t\t} else {\n\t\t\t\t\tviewWriter.removeAttribute( viewAttributeName, img );\n\t\t\t\t}\n\n\t\t\t\t// Do not set aspect-ratio for pictures. See https://github.com/ckeditor/ckeditor5/issues/14579.\n\t\t\t\tif ( data.item.hasAttribute( 'sources' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst isResized = data.item.hasAttribute( 'resizedWidth' );\n\n\t\t\t\t// Do not set aspect ratio for inline images which are not resized (data pipeline).\n\t\t\t\tif ( imageType === 'imageInline' && !isResized && !setRatioForInlineImage ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst width = data.item.getAttribute( 'width' );\n\t\t\t\tconst height = data.item.getAttribute( 'height' );\n\n\t\t\t\tif ( width && height ) {\n\t\t\t\t\tviewWriter.setStyle( 'aspect-ratio', `${ width }/${ height }`, img );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n}\n\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/imagetypecommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * The image type command. It changes the type of a selected image, depending on the configuration.\n */\nexport default class ImageTypeCommand extends Command {\n\t/**\n\t * Model element name the command converts to.\n\t */\n\tprivate readonly _modelElementName: 'imageBlock' | 'imageInline';\n\n\t/**\n\t * @inheritDoc\n\t *\n\t * @param modelElementName Model element name the command converts to.\n\t */\n\tconstructor( editor: Editor, modelElementName: 'imageBlock' | 'imageInline' ) {\n\t\tsuper( editor );\n\n\t\tthis._modelElementName = modelElementName;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst element = imageUtils.getClosestSelectedImageElement( this.editor.model.document.selection );\n\n\t\tif ( this._modelElementName === 'imageBlock' ) {\n\t\t\tthis.isEnabled = imageUtils.isInlineImage( element );\n\t\t} else {\n\t\t\tthis.isEnabled = imageUtils.isBlockImage( element );\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command and changes the type of a selected image.\n\t *\n\t * @fires execute\n\t * @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.\n\t * The default is `true`.\n\t * @returns An object containing references to old and new model image elements\n\t * (for before and after the change) so external integrations can hook into the decorated\n\t * `execute` event and handle this change. `null` if the type change failed.\n\t */\n\tpublic override execute( options: { setImageSizes?: boolean } = {} ): { oldElement: Element; newElement: Element } | null {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst oldElement = imageUtils.getClosestSelectedImageElement( model.document.selection )!;\n\t\tconst attributes = Object.fromEntries( oldElement.getAttributes() );\n\n\t\t// Don't change image type if \"src\" is missing (a broken image), unless there's \"uploadId\" set.\n\t\t// This state may happen during image upload (before it finishes) and it should be possible to change type\n\t\t// of the image in the meantime.\n\t\tif ( !attributes.src && !attributes.uploadId ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn model.change( writer => {\n\t\t\tconst { setImageSizes = true } = options;\n\n\t\t\t// Get all markers that contain the old image element.\n\t\t\tconst markers = Array.from( model.markers )\n\t\t\t\t.filter( marker => marker.getRange().containsItem( oldElement ) );\n\n\t\t\tconst newElement = imageUtils.insertImage(\n\t\t\t\tattributes,\n\t\t\t\tmodel.createSelection( oldElement, 'on' ),\n\t\t\t\tthis._modelElementName,\n\t\t\t\t{ setImageSizes }\n\t\t\t);\n\n\t\t\tif ( !newElement ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst newElementRange = writer.createRangeOn( newElement );\n\n\t\t\t// Expand the previously intersecting markers' ranges to include the new image element.\n\t\t\tfor ( const marker of markers ) {\n\t\t\t\tconst markerRange = marker.getRange();\n\n\t\t\t\t// Join the survived part of the old marker range with the new element range\n\t\t\t\t// (loosely because there could be some new paragraph or the existing one might got split).\n\t\t\t\tconst range = markerRange.root.rootName != '$graveyard' ?\n\t\t\t\t\tmarkerRange.getJoined( newElementRange, true )! : newElementRange;\n\n\t\t\t\twriter.updateMarker( marker, { range } );\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\toldElement,\n\t\t\t\tnewElement\n\t\t\t};\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/imageplaceholder\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type {\n\tDowncastAttributeEvent,\n\tElement,\n\tViewElement\n} from 'ckeditor5/src/engine.js';\n\nimport ImageUtils from '../imageutils.js';\nimport ImageLoadObserver, { type ImageLoadedEvent } from './imageloadobserver.js';\n\nimport '../../theme/imageplaceholder.css';\n\n/**\n * Adds support for image placeholder that is automatically removed when the image is loaded.\n */\nexport default class ImagePlaceholder extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImagePlaceholder' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tthis._setupSchema();\n\t\tthis._setupConversion();\n\t\tthis._setupLoadListener();\n\t}\n\n\t/**\n\t * Extends model schema.\n\t */\n\tprivate _setupSchema(): void {\n\t\tconst schema = this.editor.model.schema;\n\n\t\t// Wait for ImageBlockEditing or ImageInlineEditing to register their elements first,\n\t\t// that's why doing this in afterInit() instead of init().\n\t\tif ( schema.isRegistered( 'imageBlock' ) ) {\n\t\t\tschema.extend( 'imageBlock', {\n\t\t\t\tallowAttributes: [ 'placeholder' ]\n\t\t\t} );\n\t\t}\n\n\t\tif ( schema.isRegistered( 'imageInline' ) ) {\n\t\t\tschema.extend( 'imageInline', {\n\t\t\t\tallowAttributes: [ 'placeholder' ]\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Registers converters.\n\t */\n\tprivate _setupConversion(): void {\n\t\tconst editor = this.editor;\n\t\tconst conversion = editor.conversion;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\tconversion.for( 'editingDowncast' ).add( dispatcher => {\n\t\t\tdispatcher.on<DowncastAttributeEvent<Element>>( 'attribute:placeholder', ( evt, data, conversionApi ) => {\n\t\t\t\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( !data.item.is( 'element', 'imageBlock' ) && !data.item.is( 'element', 'imageInline' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconversionApi.consumable.consume( data.item, evt.name );\n\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst element = conversionApi.mapper.toViewElement( data.item )!;\n\t\t\t\tconst img = imageUtils.findViewImgElement( element )!;\n\n\t\t\t\tif ( data.attributeNewValue ) {\n\t\t\t\t\tviewWriter.addClass( 'image_placeholder', img );\n\t\t\t\t\tviewWriter.setStyle( 'background-image', `url(${ data.attributeNewValue })`, img );\n\t\t\t\t\tviewWriter.setCustomProperty( 'editingPipeline:doNotReuseOnce', true, img );\n\t\t\t\t} else {\n\t\t\t\t\tviewWriter.removeClass( 'image_placeholder', img );\n\t\t\t\t\tviewWriter.removeStyle( 'background-image', img );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Prepares listener for image load.\n\t */\n\tprivate _setupLoadListener(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst editing = editor.editing;\n\t\tconst editingView = editing.view;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\teditingView.addObserver( ImageLoadObserver );\n\n\t\tthis.listenTo<ImageLoadedEvent>( editingView.document, 'imageLoaded', ( evt, domEvent ) => {\n\t\t\tconst imgViewElement = editingView.domConverter.mapDomToView( domEvent.target as HTMLElement );\n\n\t\t\tif ( !imgViewElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst viewElement = imageUtils.getImageWidgetFromImageView( imgViewElement as ViewElement );\n\n\t\t\tif ( !viewElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst modelElement = editing.mapper.toModelElement( viewElement );\n\n\t\t\tif ( !modelElement || !modelElement.hasAttribute( 'placeholder' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodel.enqueueChange( { isUndoable: false }, writer => {\n\t\t\t\twriter.removeAttribute( 'placeholder', modelElement );\n\t\t\t} );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/imageblockediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ClipboardPipeline, type ClipboardInputTransformationEvent, type ClipboardContentInsertionEvent } from 'ckeditor5/src/clipboard.js';\nimport { UpcastWriter, type ViewElement } from 'ckeditor5/src/engine.js';\n\nimport {\n\tdowncastImageAttribute,\n\tdowncastSrcsetAttribute,\n\tupcastImageFigure\n} from './converters.js';\n\nimport ImageEditing from './imageediting.js';\nimport ImageSizeAttributes from '../imagesizeattributes.js';\nimport ImageTypeCommand from './imagetypecommand.js';\nimport ImageUtils from '../imageutils.js';\nimport {\n\tgetImgViewElementMatcher,\n\tcreateBlockImageViewElement,\n\tdetermineImageTypeForInsertionAtSelection\n} from './utils.js';\nimport ImagePlaceholder from './imageplaceholder.js';\n\n/**\n * The image block plugin.\n *\n * It registers:\n *\n * * `<imageBlock>` as a block element in the document schema, and allows `alt`, `src` and `srcset` attributes.\n * * converters for editing and data pipelines.,\n * * {@link module:image/image/imagetypecommand~ImageTypeCommand `'imageTypeBlock'`} command that converts inline images into\n * block images.\n */\nexport default class ImageBlockEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageEditing, ImageSizeAttributes, ImageUtils, ImagePlaceholder, ClipboardPipeline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageBlockEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\t// Converters 'alt' and 'srcset' are added in 'ImageEditing' plugin.\n\t\tschema.register( 'imageBlock', {\n\t\t\tinheritAllFrom: '$blockObject',\n\t\t\tallowAttributes: [ 'alt', 'src', 'srcset' ]\n\t\t} );\n\n\t\tthis._setupConversion();\n\n\t\tif ( editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\teditor.commands.add( 'imageTypeBlock', new ImageTypeCommand( this.editor, 'imageBlock' ) );\n\n\t\t\tthis._setupClipboardIntegration();\n\t\t}\n\t}\n\n\t/**\n\t * Configures conversion pipelines to support upcasting and downcasting\n\t * block images (block image widgets) and their attributes.\n\t */\n\tprivate _setupConversion(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst conversion = editor.conversion;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\tconversion.for( 'dataDowncast' )\n\t\t\t.elementToStructure( {\n\t\t\t\tmodel: 'imageBlock',\n\t\t\t\tview: ( modelElement, { writer } ) => createBlockImageViewElement( writer )\n\t\t\t} );\n\n\t\tconversion.for( 'editingDowncast' )\n\t\t\t.elementToStructure( {\n\t\t\t\tmodel: 'imageBlock',\n\t\t\t\tview: ( modelElement, { writer } ) => imageUtils.toImageWidget(\n\t\t\t\t\tcreateBlockImageViewElement( writer ), writer, t( 'image widget' )\n\t\t\t\t)\n\t\t\t} );\n\n\t\tconversion.for( 'downcast' )\n\t\t\t.add( downcastImageAttribute( imageUtils, 'imageBlock', 'src' ) )\n\t\t\t.add( downcastImageAttribute( imageUtils, 'imageBlock', 'alt' ) )\n\t\t\t.add( downcastSrcsetAttribute( imageUtils, 'imageBlock' ) );\n\n\t\t// More image related upcasts are in 'ImageEditing' plugin.\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: getImgViewElementMatcher( editor, 'imageBlock' ),\n\t\t\t\tmodel: ( viewImage, { writer } ) => writer.createElement(\n\t\t\t\t\t'imageBlock',\n\t\t\t\t\tviewImage.hasAttribute( 'src' ) ? { src: viewImage.getAttribute( 'src' ) } : undefined\n\t\t\t\t)\n\t\t\t} )\n\t\t\t.add( upcastImageFigure( imageUtils ) );\n\t}\n\n\t/**\n\t * Integrates the plugin with the clipboard pipeline.\n\t *\n\t * Idea is that the feature should recognize the user's intent when an **inline** image is\n\t * pasted or dropped. If such an image is pasted/dropped:\n\t *\n\t * * into an empty block (e.g. an empty paragraph),\n\t * * on another object (e.g. some block widget).\n\t *\n\t * it gets converted into a block image on the fly. We assume this is the user's intent\n\t * if they decided to put their image there.\n\t *\n\t * See the `ImageInlineEditing` for the similar integration that works in the opposite direction.\n\t *\n\t * The feature also sets image `width` and `height` attributes on paste.\n\t */\n\tprivate _setupClipboardIntegration(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst editingView = editor.editing.view;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst clipboardPipeline: ClipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\n\t\tthis.listenTo<ClipboardInputTransformationEvent>(\n\t\t\tclipboardPipeline,\n\t\t\t'inputTransformation',\n\t\t\t( evt, data ) => {\n\t\t\t\tconst docFragmentChildren = Array.from( data.content.getChildren() as IterableIterator<ViewElement> );\n\t\t\t\tlet modelRange;\n\n\t\t\t\t// Make sure only <img> elements are dropped or pasted. Otherwise, if there some other HTML\n\t\t\t\t// mixed up, this should be handled as a regular paste.\n\t\t\t\tif ( !docFragmentChildren.every( imageUtils.isInlineImageView ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// When drag and dropping, data.targetRanges specifies where to drop because\n\t\t\t\t// this is usually a different place than the current model selection (the user\n\t\t\t\t// uses a drop marker to specify the drop location).\n\t\t\t\tif ( data.targetRanges ) {\n\t\t\t\t\tmodelRange = editor.editing.mapper.toModelRange( data.targetRanges[ 0 ] );\n\t\t\t\t}\n\t\t\t\t// Pasting, however, always occurs at the current model selection.\n\t\t\t\telse {\n\t\t\t\t\tmodelRange = model.document.selection.getFirstRange();\n\t\t\t\t}\n\n\t\t\t\tconst selection = model.createSelection( modelRange );\n\n\t\t\t\t// Convert inline images into block images only when the currently selected block is empty\n\t\t\t\t// (e.g. an empty paragraph) or some object is selected (to replace it).\n\t\t\t\tif ( determineImageTypeForInsertionAtSelection( model.schema, selection ) === 'imageBlock' ) {\n\t\t\t\t\tconst writer = new UpcastWriter( editingView.document );\n\n\t\t\t\t\t// Wrap <img ... /> -> <figure class=\"image\"><img .../></figure>\n\t\t\t\t\tconst blockViewImages = docFragmentChildren.map(\n\t\t\t\t\t\tinlineViewImage => writer.createElement( 'figure', { class: 'image' }, inlineViewImage )\n\t\t\t\t\t);\n\n\t\t\t\t\tdata.content = writer.createDocumentFragment( blockViewImages );\n\t\t\t\t}\n\t\t\t} );\n\n\t\tthis.listenTo<ClipboardContentInsertionEvent>(\n\t\t\tclipboardPipeline,\n\t\t\t'contentInsertion',\n\t\t\t( evt, data ) => {\n\t\t\t\tif ( data.method !== 'paste' ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\tconst range = writer.createRangeIn( data.content );\n\n\t\t\t\t\tfor ( const item of range.getItems() ) {\n\t\t\t\t\t\tif ( item.is( 'element', 'imageBlock' ) ) {\n\t\t\t\t\t\t\timageUtils.setImageNaturalSizeAttributes( item );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageinsert/ui/imageinsertformview\n */\n\nimport {\n\tView,\n\tViewCollection,\n\tsubmitHandler,\n\tFocusCycler,\n\tCollapsibleView,\n\ttype FocusableView\n} from 'ckeditor5/src/ui.js';\nimport { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';\n\nimport '../../../theme/imageinsert.css';\n\n/**\n * The view displayed in the insert image dropdown.\n *\n * See {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.\n */\nexport default class ImageInsertFormView extends View {\n\t/**\n\t * Tracks information about DOM focus in the form.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A collection of views that can be focused in the form.\n\t */\n\tprotected readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */\n\tprotected readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * A collection of the defined integrations for inserting the images.\n\t */\n\tprivate readonly children: ViewCollection<FocusableView>;\n\n\t/**\n\t * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param integrations An integrations object that contains components (or tokens for components) to be shown in the panel view.\n\t */\n\tconstructor( locale: Locale, integrations: Array<FocusableView> = [] ) {\n\t\tsuper( locale );\n\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis._focusables = new ViewCollection();\n\t\tthis.children = this.createCollection();\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tfor ( const view of integrations ) {\n\t\t\tthis.children.add( view );\n\t\t\tthis._focusables.add( view );\n\n\t\t\tif ( view instanceof CollapsibleView ) {\n\t\t\t\tthis._focusables.addMany( view.children );\n\t\t\t}\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-image-insert-form'\n\t\t\t\t],\n\t\t\t\ttabindex: -1\n\t\t\t},\n\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\tfor ( const view of this._focusables ) {\n\t\t\tthis.focusTracker.add( view.element! );\n\t\t}\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\tconst stopPropagation = ( data: KeyboardEvent ) => data.stopPropagation();\n\n\t\t// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n\t\t// keystroke handler would take over the key management in the URL input. We need to prevent\n\t\t// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n\t\tthis.keystrokes.set( 'arrowright', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowleft', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowup', stopPropagation );\n\t\tthis.keystrokes.set( 'arrowdown', stopPropagation );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the first {@link #_focusables focusable} in the form.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageinsert/imageinsertui\n */\n\nimport {\n\tPlugin,\n\ttype Editor,\n\ticons\n} from 'ckeditor5/src/core.js';\nimport {\n\tlogWarning,\n\ttype Locale,\n\ttype Observable\n} from 'ckeditor5/src/utils.js';\nimport {\n\tcreateDropdown,\n\ttype ButtonView,\n\ttype DropdownButtonView,\n\ttype DropdownView,\n\ttype FocusableView,\n\ttype MenuBarMenuListItemButtonView,\n\tMenuBarMenuListItemView,\n\tMenuBarMenuListView,\n\tMenuBarMenuView,\n\tSplitButtonView,\n\ttype View\n} from 'ckeditor5/src/ui.js';\n\nimport ImageInsertFormView from './ui/imageinsertformview.js';\nimport ImageUtils from '../imageutils.js';\n\n/**\n * The image insert dropdown plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}\n * and {@glink features/images/images-inserting Insert images via source URL} documentation.\n *\n * Adds the `'insertImage'` dropdown to the {@link module:ui/componentfactory~ComponentFactory UI component factory}\n * and also the `imageInsert` dropdown as an alias for backward compatibility.\n *\n * Adds the `'menuBar:insertImage'` sub-menu to the {@link module:ui/componentfactory~ComponentFactory UI component factory}, which is\n * by default added to the `'Insert'` menu.\n */\nexport default class ImageInsertUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageInsertUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * The dropdown view responsible for displaying the image insert UI.\n\t */\n\tpublic dropdownView?: DropdownView;\n\n\t/**\n\t * Observable property used to alter labels while some image is selected and when it is not.\n\t *\n\t * @observable\n\t */\n\tdeclare public isImageSelected: boolean;\n\n\t/**\n\t * Registered integrations map.\n\t */\n\tprivate _integrations = new Map<string, IntegrationData>();\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'image.insert.integrations', [\n\t\t\t'upload',\n\t\t\t'assetManager',\n\t\t\t'url'\n\t\t] );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\tthis.set( 'isImageSelected', false );\n\n\t\tthis.listenTo( editor.model.document, 'change', () => {\n\t\t\tthis.isImageSelected = imageUtils.isImage( selection.getSelectedElement() );\n\t\t} );\n\n\t\tconst componentCreator = ( locale: Locale ) => this._createToolbarComponent( locale );\n\t\tconst menuBarComponentCreator = ( locale: Locale ) => this._createMenuBarComponent( locale );\n\n\t\t// Register `insertImage` dropdown and add `imageInsert` dropdown as an alias for backward compatibility.\n\t\teditor.ui.componentFactory.add( 'insertImage', componentCreator );\n\t\teditor.ui.componentFactory.add( 'imageInsert', componentCreator );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:insertImage', menuBarComponentCreator );\n\t}\n\n\t/**\n\t * Registers the insert image dropdown integration.\n\t */\n\tpublic registerIntegration( {\n\t\tname,\n\t\tobservable,\n\t\tbuttonViewCreator,\n\t\tformViewCreator,\n\t\tmenuBarButtonViewCreator,\n\t\trequiresForm = false\n\t}: {\n\t\tname: string;\n\t\tobservable: Observable & { isEnabled: boolean } | ( () => Observable & { isEnabled: boolean } );\n\t\tbuttonViewCreator: ( isOnlyOne: boolean ) => ButtonView;\n\t\tformViewCreator: ( isOnlyOne: boolean ) => FocusableView;\n\t\tmenuBarButtonViewCreator: ( isOnlyOne: boolean ) => MenuBarMenuListItemButtonView;\n\t\trequiresForm?: boolean;\n\t} ): void {\n\t\tif ( this._integrations.has( name ) ) {\n\t\t\t/**\n\t\t\t * There are two insert-image integrations registered with the same name.\n\t\t\t *\n\t\t\t * Make sure that you do not load multiple asset manager plugins.\n\t\t\t *\n\t\t\t * @error image-insert-integration-exists\n\t\t\t */\n\t\t\tlogWarning( 'image-insert-integration-exists', { name } );\n\t\t}\n\n\t\tthis._integrations.set( name, {\n\t\t\tobservable,\n\t\t\tbuttonViewCreator,\n\t\t\tmenuBarButtonViewCreator,\n\t\t\tformViewCreator,\n\t\t\trequiresForm\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the toolbar component.\n\t */\n\tprivate _createToolbarComponent( locale: Locale ): DropdownView | FocusableView {\n\t\tconst editor = this.editor;\n\t\tconst t = locale.t;\n\n\t\tconst integrations = this._prepareIntegrations();\n\n\t\tif ( !integrations.length ) {\n\t\t\treturn null as any;\n\t\t}\n\n\t\tlet dropdownButton: SplitButtonView | DropdownButtonView | undefined;\n\t\tconst firstIntegration = integrations[ 0 ];\n\n\t\tif ( integrations.length == 1 ) {\n\t\t\t// Do not use dropdown for a single integration button (integration that does not require form view).\n\t\t\tif ( !firstIntegration.requiresForm ) {\n\t\t\t\treturn firstIntegration.buttonViewCreator( true );\n\t\t\t}\n\n\t\t\tdropdownButton = firstIntegration.buttonViewCreator( true ) as DropdownButtonView;\n\t\t} else {\n\t\t\tconst actionButton = firstIntegration.buttonViewCreator( false ) as ButtonView & FocusableView;\n\n\t\t\tdropdownButton = new SplitButtonView( locale, actionButton );\n\t\t\tdropdownButton.tooltip = true;\n\n\t\t\tdropdownButton.bind( 'label' ).to( this, 'isImageSelected', isImageSelected => isImageSelected ?\n\t\t\t\tt( 'Replace image' ) :\n\t\t\t\tt( 'Insert image' )\n\t\t\t);\n\t\t}\n\n\t\tconst dropdownView = this.dropdownView = createDropdown( locale, dropdownButton );\n\t\tconst observables = integrations.map( ( { observable } ) => typeof observable == 'function' ? observable() : observable );\n\n\t\tdropdownView.bind( 'isEnabled' ).toMany( observables, 'isEnabled', ( ...isEnabled ) => (\n\t\t\tisEnabled.some( isEnabled => isEnabled )\n\t\t) );\n\n\t\tdropdownView.once( 'change:isOpen', () => {\n\t\t\tconst integrationViews = integrations.map( ( { formViewCreator } ) => formViewCreator( integrations.length == 1 ) );\n\t\t\tconst imageInsertFormView = new ImageInsertFormView( editor.locale, integrationViews );\n\n\t\t\tdropdownView.panelView.children.add( imageInsertFormView );\n\t\t} );\n\n\t\treturn dropdownView;\n\t}\n\n\t/**\n\t * Creates the menu bar component.\n\t */\n\tprivate _createMenuBarComponent( locale: Locale ): View {\n\t\tconst t = locale.t;\n\n\t\tconst integrations = this._prepareIntegrations();\n\n\t\tif ( !integrations.length ) {\n\t\t\treturn null as any;\n\t\t}\n\n\t\tlet resultView: MenuBarMenuListItemButtonView | MenuBarMenuView | undefined;\n\t\tconst firstIntegration = integrations[ 0 ];\n\n\t\tif ( integrations.length == 1 ) {\n\t\t\tresultView = firstIntegration.menuBarButtonViewCreator( true );\n\t\t} else {\n\t\t\tresultView = new MenuBarMenuView( locale );\n\t\t\tconst listView = new MenuBarMenuListView( locale );\n\t\t\tresultView.panelView.children.add( listView );\n\n\t\t\tresultView.buttonView.set( {\n\t\t\t\ticon: icons.image,\n\t\t\t\tlabel: t( 'Image' )\n\t\t\t} );\n\n\t\t\tfor ( const integration of integrations ) {\n\t\t\t\tconst listItemView = new MenuBarMenuListItemView( locale, resultView );\n\t\t\t\tconst buttonView = integration.menuBarButtonViewCreator( false );\n\n\t\t\t\tlistItemView.children.add( buttonView );\n\t\t\t\tlistView.items.add( listItemView );\n\t\t\t}\n\t\t}\n\n\t\treturn resultView;\n\t}\n\n\t/**\n\t * Validates the integrations list.\n\t */\n\tprivate _prepareIntegrations(): Array<IntegrationData> {\n\t\tconst editor = this.editor;\n\t\tconst items = editor.config.get( 'image.insert.integrations' )!;\n\t\tconst result: Array<IntegrationData> = [];\n\n\t\tif ( !items.length ) {\n\t\t\t/**\n\t\t\t * The insert image feature requires a list of integrations to be provided in the editor configuration.\n\t\t\t *\n\t\t\t * The default list of integrations is `upload`, `assetManager`, `url`. Those integrations are included\n\t\t\t * in the insert image dropdown if the given feature plugin is loaded. You should omit the `integrations`\n\t\t\t * configuration key to use the default set or provide a selected list of integrations that should be used.\n\t\t\t *\n\t\t\t * @error image-insert-integrations-not-specified\n\t\t\t */\n\t\t\tlogWarning( 'image-insert-integrations-not-specified' );\n\n\t\t\treturn result;\n\t\t}\n\n\t\tfor ( const item of items ) {\n\t\t\tif ( !this._integrations.has( item ) ) {\n\t\t\t\tif ( ![ 'upload', 'assetManager', 'url' ].includes( item ) ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * The specified insert image integration name is unknown or the providing plugin is not loaded in the editor.\n\t\t\t\t\t *\n\t\t\t\t\t * @error image-insert-unknown-integration\n\t\t\t\t\t */\n\t\t\t\t\tlogWarning( 'image-insert-unknown-integration', { item } );\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tresult.push( this._integrations.get( item )! );\n\t\t}\n\n\t\tif ( !result.length ) {\n\t\t\t/**\n\t\t\t * The image insert feature requires integrations to be registered by separate features.\n\t\t\t *\n\t\t\t * The `insertImage` toolbar button requires integrations to be registered by other features.\n\t\t\t * For example {@link module:image/imageupload~ImageUpload ImageUpload},\n\t\t\t * {@link module:image/imageinsert~ImageInsert ImageInsert},\n\t\t\t * {@link module:image/imageinsertviaurl~ImageInsertViaUrl ImageInsertViaUrl},\n\t\t\t * {@link module:ckbox/ckbox~CKBox CKBox}\n\t\t\t *\n\t\t\t * @error image-insert-integrations-not-registered\n\t\t\t */\n\t\t\tlogWarning( 'image-insert-integrations-not-registered' );\n\t\t}\n\n\t\treturn result;\n\t}\n}\n\ntype IntegrationData = {\n\tobservable: Observable & { isEnabled: boolean } | ( () => Observable & { isEnabled: boolean } );\n\tbuttonViewCreator: ( isOnlyOne: boolean ) => ButtonView;\n\tmenuBarButtonViewCreator: ( isOnlyOne: boolean ) => MenuBarMenuListItemButtonView;\n\tformViewCreator: ( isOnlyOne: boolean ) => FocusableView;\n\trequiresForm: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageblock\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { Widget } from 'ckeditor5/src/widget.js';\n\nimport ImageTextAlternative from './imagetextalternative.js';\nimport ImageBlockEditing from './image/imageblockediting.js';\nimport ImageInsertUI from './imageinsert/imageinsertui.js';\n\nimport '../theme/image.css';\n\n/**\n * The image block plugin.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/image/imageblockediting~ImageBlockEditing},\n * * {@link module:image/imagetextalternative~ImageTextAlternative}.\n *\n * Usually, it is used in conjunction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n */\nexport default class ImageBlock extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageBlockEditing, Widget, ImageTextAlternative, ImageInsertUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageBlock' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image/imageinlineediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ClipboardPipeline, type ClipboardInputTransformationEvent, type ClipboardContentInsertionEvent } from 'ckeditor5/src/clipboard.js';\nimport { UpcastWriter, type ViewElement } from 'ckeditor5/src/engine.js';\n\nimport {\n\tdowncastImageAttribute,\n\tdowncastSrcsetAttribute\n} from './converters.js';\n\nimport ImageEditing from './imageediting.js';\nimport ImageSizeAttributes from '../imagesizeattributes.js';\nimport ImageTypeCommand from './imagetypecommand.js';\nimport ImageUtils from '../imageutils.js';\nimport {\n\tgetImgViewElementMatcher,\n\tcreateInlineImageViewElement,\n\tdetermineImageTypeForInsertionAtSelection\n} from './utils.js';\nimport ImagePlaceholder from './imageplaceholder.js';\n\n/**\n * The image inline plugin.\n *\n * It registers:\n *\n * * `<imageInline>` as an inline element in the document schema, and allows `alt`, `src` and `srcset` attributes.\n * * converters for editing and data pipelines.\n * * {@link module:image/image/imagetypecommand~ImageTypeCommand `'imageTypeInline'`} command that converts block images into\n * inline images.\n */\nexport default class ImageInlineEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageEditing, ImageSizeAttributes, ImageUtils, ImagePlaceholder, ClipboardPipeline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageInlineEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\t// Converters 'alt' and 'srcset' are added in 'ImageEditing' plugin.\n\t\tschema.register( 'imageInline', {\n\t\t\tinheritAllFrom: '$inlineObject',\n\t\t\tallowAttributes: [ 'alt', 'src', 'srcset' ],\n\t\t\t// Disallow inline images in captions (at least for now).\n\t\t\t// This is the best spot to do that because independent packages can introduce captions (ImageCaption, TableCaption, etc.).\n\t\t\tdisallowIn: [ 'caption' ]\n\t\t} );\n\n\t\tthis._setupConversion();\n\n\t\tif ( editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\teditor.commands.add( 'imageTypeInline', new ImageTypeCommand( this.editor, 'imageInline' ) );\n\n\t\t\tthis._setupClipboardIntegration();\n\t\t}\n\t}\n\n\t/**\n\t * Configures conversion pipelines to support upcasting and downcasting\n\t * inline images (inline image widgets) and their attributes.\n\t */\n\tprivate _setupConversion(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst conversion = editor.conversion;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\tconversion.for( 'dataDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'imageInline',\n\t\t\t\tview: ( modelElement, { writer } ) => writer.createEmptyElement( 'img' )\n\t\t\t} );\n\n\t\tconversion.for( 'editingDowncast' )\n\t\t\t.elementToStructure( {\n\t\t\t\tmodel: 'imageInline',\n\t\t\t\tview: ( modelElement, { writer } ) => imageUtils.toImageWidget(\n\t\t\t\t\tcreateInlineImageViewElement( writer ), writer, t( 'image widget' )\n\t\t\t\t)\n\t\t\t} );\n\n\t\tconversion.for( 'downcast' )\n\t\t\t.add( downcastImageAttribute( imageUtils, 'imageInline', 'src' ) )\n\t\t\t.add( downcastImageAttribute( imageUtils, 'imageInline', 'alt' ) )\n\t\t\t.add( downcastSrcsetAttribute( imageUtils, 'imageInline' ) );\n\n\t\t// More image related upcasts are in 'ImageEditing' plugin.\n\t\tconversion.for( 'upcast' )\n\t\t\t.elementToElement( {\n\t\t\t\tview: getImgViewElementMatcher( editor, 'imageInline' ),\n\t\t\t\tmodel: ( viewImage, { writer } ) => writer.createElement(\n\t\t\t\t\t'imageInline',\n\t\t\t\t\tviewImage.hasAttribute( 'src' ) ? { src: viewImage.getAttribute( 'src' ) } : undefined\n\t\t\t\t)\n\t\t\t} );\n\t}\n\n\t/**\n\t * Integrates the plugin with the clipboard pipeline.\n\t *\n\t * Idea is that the feature should recognize the user's intent when an **block** image is\n\t * pasted or dropped. If such an image is pasted/dropped into a non-empty block\n\t * (e.g. a paragraph with some text) it gets converted into an inline image on the fly.\n\t *\n\t * We assume this is the user's intent if they decided to put their image there.\n\t *\n\t * **Note**: If a block image has a caption, it will not be converted to an inline image\n\t * to avoid the confusion. Captions are added on purpose and they should never be lost\n\t * in the clipboard pipeline.\n\t *\n\t * See the `ImageBlockEditing` for the similar integration that works in the opposite direction.\n\t *\n\t * The feature also sets image `width` and `height` attributes when pasting.\n\t */\n\tprivate _setupClipboardIntegration(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst editingView = editor.editing.view;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst clipboardPipeline: ClipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\n\t\tthis.listenTo<ClipboardInputTransformationEvent>(\n\t\t\tclipboardPipeline,\n\t\t\t'inputTransformation',\n\t\t\t( evt, data ) => {\n\t\t\t\tconst docFragmentChildren = Array.from( data.content.getChildren() as IterableIterator<ViewElement> );\n\t\t\t\tlet modelRange;\n\n\t\t\t\t// Make sure only <figure class=\"image\"></figure> elements are dropped or pasted. Otherwise, if there some other HTML\n\t\t\t\t// mixed up, this should be handled as a regular paste.\n\t\t\t\tif ( !docFragmentChildren.every( imageUtils.isBlockImageView ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// When drag and dropping, data.targetRanges specifies where to drop because\n\t\t\t\t// this is usually a different place than the current model selection (the user\n\t\t\t\t// uses a drop marker to specify the drop location).\n\t\t\t\tif ( data.targetRanges ) {\n\t\t\t\t\tmodelRange = editor.editing.mapper.toModelRange( data.targetRanges[ 0 ] );\n\t\t\t\t}\n\t\t\t\t// Pasting, however, always occurs at the current model selection.\n\t\t\t\telse {\n\t\t\t\t\tmodelRange = model.document.selection.getFirstRange();\n\t\t\t\t}\n\n\t\t\t\tconst selection = model.createSelection( modelRange );\n\n\t\t\t\t// Convert block images into inline images only when pasting or dropping into non-empty blocks\n\t\t\t\t// and when the block is not an object (e.g. pasting to replace another widget).\n\t\t\t\tif ( determineImageTypeForInsertionAtSelection( model.schema, selection ) === 'imageInline' ) {\n\t\t\t\t\tconst writer = new UpcastWriter( editingView.document );\n\n\t\t\t\t\t// Unwrap <figure class=\"image\"><img .../></figure> -> <img ... />\n\t\t\t\t\t// but <figure class=\"image\"><img .../><figcaption>...</figcaption></figure> -> stays the same\n\t\t\t\t\tconst inlineViewImages = docFragmentChildren.map( blockViewImage => {\n\t\t\t\t\t// If there's just one child, it can be either <img /> or <a><img></a>.\n\t\t\t\t\t// If there are other children than <img>, this means that the block image\n\t\t\t\t\t// has a caption or some other features and this kind of image should be\n\t\t\t\t\t// pasted/dropped without modifications.\n\t\t\t\t\t\tif ( blockViewImage.childCount === 1 ) {\n\t\t\t\t\t\t// Pass the attributes which are present only in the <figure> to the <img>\n\t\t\t\t\t\t// (e.g. the style=\"width:10%\" attribute applied by the ImageResize plugin).\n\t\t\t\t\t\t\tArray.from( blockViewImage.getAttributes() )\n\t\t\t\t\t\t\t\t.forEach( attribute => writer.setAttribute(\n\t\t\t\t\t\t\t\t\t...attribute,\n\t\t\t\t\t\t\t\t\timageUtils.findViewImgElement( blockViewImage )!\n\t\t\t\t\t\t\t\t) );\n\n\t\t\t\t\t\t\treturn blockViewImage.getChild( 0 )!;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn blockViewImage;\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t\tdata.content = writer.createDocumentFragment( inlineViewImages );\n\t\t\t\t}\n\t\t\t} );\n\n\t\tthis.listenTo<ClipboardContentInsertionEvent>(\n\t\t\tclipboardPipeline,\n\t\t\t'contentInsertion',\n\t\t\t( evt, data ) => {\n\t\t\t\tif ( data.method !== 'paste' ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\tconst range = writer.createRangeIn( data.content );\n\n\t\t\t\t\tfor ( const item of range.getItems() ) {\n\t\t\t\t\t\tif ( item.is( 'element', 'imageInline' ) ) {\n\t\t\t\t\t\t\timageUtils.setImageNaturalSizeAttributes( item );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageinline\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { Widget } from 'ckeditor5/src/widget.js';\n\nimport ImageTextAlternative from './imagetextalternative.js';\nimport ImageInlineEditing from './image/imageinlineediting.js';\nimport ImageInsertUI from './imageinsert/imageinsertui.js';\n\nimport '../theme/image.css';\n\n/**\n * The image inline plugin.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/image/imageinlineediting~ImageInlineEditing},\n * * {@link module:image/imagetextalternative~ImageTextAlternative}.\n *\n * Usually, it is used in conjunction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n */\nexport default class ImageInline extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageInlineEditing, Widget, ImageTextAlternative, ImageInsertUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageInline' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/image\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageBlock from './imageblock.js';\nimport ImageInline from './imageinline.js';\n\nimport '../theme/image.css';\n\n/**\n * The image plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-overview image feature} documentation.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * {@link module:image/imageblock~ImageBlock},\n * * {@link module:image/imageinline~ImageInline},\n *\n * Usually, it is used in conjunction with other plugins from this package. See the {@glink api/image package page}\n * for more information.\n */\nexport default class Image extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageBlock, ImageInline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Image' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagecaption/imagecaptionutils\n */\n\nimport type { DocumentSelection, Element, Selection, ViewElement, Match } from 'ckeditor5/src/engine.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport ImageUtils from '../imageutils.js';\n\n/**\n * The image caption utilities plugin.\n */\nexport default class ImageCaptionUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageCaptionUtils' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * Returns the caption model element from a given image element. Returns `null` if no caption is found.\n\t */\n\tpublic getCaptionFromImageModelElement( imageModelElement: Element ): Element | null {\n\t\tfor ( const node of imageModelElement.getChildren() ) {\n\t\t\tif ( !!node && node.is( 'element', 'caption' ) ) {\n\t\t\t\treturn node;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns the caption model element for a model selection. Returns `null` if the selection has no caption element ancestor.\n\t */\n\tpublic getCaptionFromModelSelection( selection: Selection | DocumentSelection ): Element | null {\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\t\tconst captionElement = selection.getFirstPosition()!.findAncestor( 'caption' );\n\n\t\tif ( !captionElement ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( imageUtils.isBlockImage( captionElement.parent as Element ) ) {\n\t\t\treturn captionElement;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a `<figcaption>` element that is placed\n\t * inside the image `<figure>` element.\n\t * @returns Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element\n\t * cannot be matched.\n\t */\n\tpublic matchImageCaptionViewElement( element: ViewElement ): Match | null {\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\t// Convert only captions for images.\n\t\tif ( element.name == 'figcaption' && imageUtils.isBlockImageView( element.parent as ViewElement ) ) {\n\t\t\treturn { name: true };\n\t\t}\n\n\t\treturn null;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagecaption/toggleimagecaptioncommand\n */\n\nimport type { Element, Writer } from 'ckeditor5/src/engine.js';\nimport { Command } from 'ckeditor5/src/core.js';\n\nimport ImageBlockEditing from '../image/imageblockediting.js';\nimport type ImageCaptionUtils from './imagecaptionutils.js';\nimport type ImageUtils from '../imageutils.js';\nimport type ImageCaptionEditing from './imagecaptionediting.js';\n\n/**\n * The toggle image caption command.\n *\n * This command is registered by {@link module:image/imagecaption/imagecaptionediting~ImageCaptionEditing} as the\n * `'toggleImageCaption'` editor command.\n *\n * Executing this command:\n *\n * * either adds or removes the image caption of a selected image (depending on whether the caption is present or not),\n * * removes the image caption if the selection is anchored in one.\n *\n * ```ts\n * // Toggle the presence of the caption.\n * editor.execute( 'toggleImageCaption' );\n * ```\n *\n * **Note**: Upon executing this command, the selection will be set on the image if previously anchored in the caption element.\n *\n * **Note**: You can move the selection to the caption right away as it shows up upon executing this command by using\n * the `focusCaptionOnShow` option:\n *\n * ```ts\n * editor.execute( 'toggleImageCaption', { focusCaptionOnShow: true } );\n * ```\n */\nexport default class ToggleImageCaptionCommand extends Command {\n\tdeclare public value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageCaptionUtils: ImageCaptionUtils = editor.plugins.get( 'ImageCaptionUtils' );\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\t// Only block images can get captions.\n\t\tif ( !editor.plugins.has( ImageBlockEditing ) ) {\n\t\t\tthis.isEnabled = false;\n\t\t\tthis.value = false;\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst selection = editor.model.document.selection;\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\tif ( !selectedElement ) {\n\t\t\tconst ancestorCaptionElement = imageCaptionUtils.getCaptionFromModelSelection( selection );\n\n\t\t\tthis.isEnabled = !!ancestorCaptionElement;\n\t\t\tthis.value = !!ancestorCaptionElement;\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Block images support captions by default but the command should also be enabled for inline\n\t\t// images because toggling the caption when one is selected should convert it into a block image.\n\t\tthis.isEnabled = imageUtils.isImage( selectedElement );\n\n\t\tif ( !this.isEnabled ) {\n\t\t\tthis.value = false;\n\t\t} else {\n\t\t\tthis.value = !!imageCaptionUtils.getCaptionFromImageModelElement( selectedElement );\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * ```ts\n\t * editor.execute( 'toggleImageCaption' );\n\t * ```\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.focusCaptionOnShow When true and the caption shows up, the selection will be moved into it straight away.\n\t * @fires execute\n\t */\n\tpublic override execute( options: { focusCaptionOnShow?: boolean } = {} ): void {\n\t\tconst { focusCaptionOnShow } = options;\n\n\t\tthis.editor.model.change( writer => {\n\t\t\tif ( this.value ) {\n\t\t\t\tthis._hideImageCaption( writer );\n\t\t\t} else {\n\t\t\t\tthis._showImageCaption( writer, focusCaptionOnShow );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the caption of the `<imageBlock>` or `<imageInline>`. Also:\n\t *\n\t * * it converts `<imageInline>` to `<imageBlock>` to show the caption,\n\t * * it attempts to restore the caption content from the `ImageCaptionEditing` caption registry,\n\t * * it moves the selection to the caption right away, it the `focusCaptionOnShow` option was set.\n\t */\n\tprivate _showImageCaption( writer: Writer, focusCaptionOnShow?: boolean ): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst imageCaptionEditing: ImageCaptionEditing = this.editor.plugins.get( 'ImageCaptionEditing' );\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\tlet selectedImage = selection.getSelectedElement()!;\n\n\t\tconst savedCaption = imageCaptionEditing._getSavedCaption( selectedImage );\n\n\t\t// Convert imageInline -> image first.\n\t\tif ( imageUtils.isInlineImage( selectedImage ) ) {\n\t\t\tthis.editor.execute( 'imageTypeBlock' );\n\n\t\t\t// Executing the command created a new model element. Let's pick it again.\n\t\t\tselectedImage = selection.getSelectedElement()!;\n\t\t}\n\n\t\t// Try restoring the caption from the ImageCaptionEditing plugin storage.\n\t\tconst newCaptionElement = savedCaption || writer.createElement( 'caption' );\n\n\t\twriter.append( newCaptionElement, selectedImage );\n\n\t\tif ( focusCaptionOnShow ) {\n\t\t\twriter.setSelection( newCaptionElement, 'in' );\n\t\t}\n\t}\n\n\t/**\n\t * Hides the caption of a selected image (or an image caption the selection is anchored to).\n\t *\n\t * The content of the caption is stored in the `ImageCaptionEditing` caption registry to make this\n\t * a reversible action.\n\t */\n\tprivate _hideImageCaption( writer: Writer ): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst imageCaptionEditing: ImageCaptionEditing = editor.plugins.get( 'ImageCaptionEditing' );\n\t\tconst imageCaptionUtils: ImageCaptionUtils = editor.plugins.get( 'ImageCaptionUtils' );\n\t\tlet selectedImage = selection.getSelectedElement()!;\n\t\tlet captionElement: Element;\n\n\t\tif ( selectedImage ) {\n\t\t\tcaptionElement = imageCaptionUtils.getCaptionFromImageModelElement( selectedImage )!;\n\t\t} else {\n\t\t\tcaptionElement = imageCaptionUtils.getCaptionFromModelSelection( selection )!;\n\t\t\tselectedImage = captionElement!.parent as Element;\n\t\t}\n\n\t\t// Store the caption content so it can be restored quickly if the user changes their mind even if they toggle image<->imageInline.\n\t\timageCaptionEditing._saveCaption( selectedImage, captionElement );\n\n\t\twriter.setSelection( selectedImage, 'on' );\n\t\twriter.remove( captionElement );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagecaption/imagecaptionediting\n */\n\nimport { type Editor, Plugin, type CommandExecuteEvent } from 'ckeditor5/src/core.js';\nimport { Element, enablePlaceholder, type DocumentChangeEvent, type DiffItemAttribute } from 'ckeditor5/src/engine.js';\nimport { toWidgetEditable } from 'ckeditor5/src/widget.js';\nimport type { GetCallback } from 'ckeditor5/src/utils.js';\n\nimport ToggleImageCaptionCommand from './toggleimagecaptioncommand.js';\nimport ImageUtils from '../imageutils.js';\nimport ImageCaptionUtils from './imagecaptionutils.js';\n\n/**\n * The image caption engine plugin. It is responsible for:\n *\n * * registering converters for the caption element,\n * * registering converters for the caption model attribute,\n * * registering the {@link module:image/imagecaption/toggleimagecaptioncommand~ToggleImageCaptionCommand `toggleImageCaption`} command.\n */\nexport default class ImageCaptionEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils, ImageCaptionUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageCaptionEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * A map that keeps saved JSONified image captions and image model elements they are\n\t * associated with.\n\t *\n\t * To learn more about this system, see {@link #_saveCaption}.\n\t */\n\tprivate _savedCaptionsMap: WeakMap<Element, unknown>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._savedCaptionsMap = new WeakMap();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\t// Schema configuration.\n\t\tif ( !schema.isRegistered( 'caption' ) ) {\n\t\t\tschema.register( 'caption', {\n\t\t\t\tallowIn: 'imageBlock',\n\t\t\t\tallowContentOf: '$block',\n\t\t\t\tisLimit: true\n\t\t\t} );\n\t\t} else {\n\t\t\tschema.extend( 'caption', {\n\t\t\t\tallowIn: 'imageBlock'\n\t\t\t} );\n\t\t}\n\n\t\teditor.commands.add( 'toggleImageCaption', new ToggleImageCaptionCommand( this.editor ) );\n\n\t\tthis._setupConversion();\n\t\tthis._setupImageTypeCommandsIntegration();\n\t\tthis._registerCaptionReconversion();\n\t}\n\n\t/**\n\t * Configures conversion pipelines to support upcasting and downcasting\n\t * image captions.\n\t */\n\tprivate _setupConversion(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst imageCaptionUtils: ImageCaptionUtils = editor.plugins.get( 'ImageCaptionUtils' );\n\t\tconst t = editor.t;\n\n\t\t// View -> model converter for the data pipeline.\n\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t\t\tview: element => imageCaptionUtils.matchImageCaptionViewElement( element ),\n\t\t\tmodel: 'caption'\n\t\t} );\n\n\t\t// Model -> view converter for the data pipeline.\n\t\teditor.conversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\tmodel: 'caption',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tif ( !imageUtils.isBlockImage( modelElement.parent as Element ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn writer.createContainerElement( 'figcaption' );\n\t\t\t}\n\t\t} );\n\n\t\t// Model -> view converter for the editing pipeline.\n\t\teditor.conversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'caption',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tif ( !imageUtils.isBlockImage( modelElement.parent as Element ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst figcaptionElement = writer.createEditableElement( 'figcaption' );\n\t\t\t\twriter.setCustomProperty( 'imageCaption', true, figcaptionElement );\n\n\t\t\t\tfigcaptionElement.placeholder = t( 'Enter image caption' );\n\t\t\t\tenablePlaceholder( {\n\t\t\t\t\tview,\n\t\t\t\t\telement: figcaptionElement,\n\t\t\t\t\tkeepOnFocus: true\n\t\t\t\t} );\n\n\t\t\t\tconst imageAlt = ( modelElement.parent as Element ).getAttribute( 'alt' ) as string;\n\t\t\t\tconst label = imageAlt ? t( 'Caption for image: %0', [ imageAlt ] ) : t( 'Caption for the image' );\n\n\t\t\t\treturn toWidgetEditable( figcaptionElement, writer, { label } );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Integrates with {@link module:image/image/imagetypecommand~ImageTypeCommand image type commands}\n\t * to make sure the caption is preserved when the type of an image changes so it can be restored\n\t * in the future if the user decides they want their caption back.\n\t */\n\tprivate _setupImageTypeCommandsIntegration(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst imageCaptionUtils: ImageCaptionUtils = editor.plugins.get( 'ImageCaptionUtils' );\n\t\tconst imageTypeInlineCommand = editor.commands.get( 'imageTypeInline' );\n\t\tconst imageTypeBlockCommand = editor.commands.get( 'imageTypeBlock' );\n\n\t\tconst handleImageTypeChange: GetCallback<CommandExecuteEvent> = evt => {\n\t\t\t// The image type command execution can be unsuccessful.\n\t\t\tif ( !evt.return ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { oldElement, newElement } = evt.return as { oldElement: Element; newElement: Element };\n\n\t\t\t/* istanbul ignore if: paranoid check -- @preserve */\n\t\t\tif ( !oldElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( imageUtils.isBlockImage( oldElement ) ) {\n\t\t\t\tconst oldCaptionElement = imageCaptionUtils.getCaptionFromImageModelElement( oldElement );\n\n\t\t\t\t// If the old element was a captioned block image (the caption was visible),\n\t\t\t\t// simply save it so it can be restored.\n\t\t\t\tif ( oldCaptionElement ) {\n\t\t\t\t\tthis._saveCaption( newElement, oldCaptionElement );\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst savedOldElementCaption = this._getSavedCaption( oldElement );\n\n\t\t\t// If either:\n\t\t\t//\n\t\t\t// * the block image didn't have a visible caption,\n\t\t\t// * the block image caption was hidden (and already saved),\n\t\t\t// * the inline image was passed\n\t\t\t//\n\t\t\t// just try to \"pass\" the saved caption from the old image to the new image\n\t\t\t// so it can be retrieved in the future if the user wants it back.\n\t\t\tif ( savedOldElementCaption ) {\n\t\t\t\t// Note: Since we're writing to a WeakMap, we don't bother with removing the\n\t\t\t\t// [ oldElement, savedOldElementCaption ] pair from it.\n\t\t\t\tthis._saveCaption( newElement, savedOldElementCaption );\n\t\t\t}\n\t\t};\n\n\t\t// Presence of the commands depends on the Image(Inline|Block)Editing plugins loaded in the editor.\n\t\tif ( imageTypeInlineCommand ) {\n\t\t\tthis.listenTo<CommandExecuteEvent>( imageTypeInlineCommand, 'execute', handleImageTypeChange, { priority: 'low' } );\n\t\t}\n\n\t\tif ( imageTypeBlockCommand ) {\n\t\t\tthis.listenTo<CommandExecuteEvent>( imageTypeBlockCommand, 'execute', handleImageTypeChange, { priority: 'low' } );\n\t\t}\n\t}\n\n\t/**\n\t * Returns the saved {@link module:engine/model/element~Element#toJSON JSONified} caption\n\t * of an image model element.\n\t *\n\t * See {@link #_saveCaption}.\n\t *\n\t * @internal\n\t * @param imageModelElement The model element the caption should be returned for.\n\t * @returns The model caption element or `null` if there is none.\n\t */\n\tpublic _getSavedCaption( imageModelElement: Element ): Element | null {\n\t\tconst jsonObject = this._savedCaptionsMap.get( imageModelElement );\n\n\t\treturn jsonObject ? Element.fromJSON( jsonObject ) : null;\n\t}\n\n\t/**\n\t * Saves a {@link module:engine/model/element~Element#toJSON JSONified} caption for\n\t * an image element to allow restoring it in the future.\n\t *\n\t * A caption is saved every time it gets hidden and/or the type of an image changes. The\n\t * user should be able to restore it on demand.\n\t *\n\t * **Note**: The caption cannot be stored in the image model element attribute because,\n\t * for instance, when the model state propagates to collaborators, the attribute would get\n\t * lost (mainly because it does not convert to anything when the caption is hidden) and\n\t * the states of collaborators' models would de-synchronize causing numerous issues.\n\t *\n\t * See {@link #_getSavedCaption}.\n\t *\n\t * @internal\n\t * @param imageModelElement The model element the caption is saved for.\n\t * @param caption The caption model element to be saved.\n\t */\n\tpublic _saveCaption( imageModelElement: Element, caption: Element ): void {\n\t\tthis._savedCaptionsMap.set( imageModelElement, caption.toJSON() );\n\t}\n\n\t/**\n\t * Reconverts image caption when image alt attribute changes.\n\t * The change of alt attribute is reflected in caption's aria-label attribute.\n\t */\n\tprivate _registerCaptionReconversion(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst imageCaptionUtils: ImageCaptionUtils = editor.plugins.get( 'ImageCaptionUtils' );\n\n\t\tmodel.document.on<DocumentChangeEvent>( 'change:data', () => {\n\t\t\tconst changes = model.document.differ.getChanges();\n\n\t\t\tfor ( const change of changes as Array<DiffItemAttribute> ) {\n\t\t\t\tif ( change.attributeKey !== 'alt' ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst image = change.range.start.nodeAfter as Element;\n\n\t\t\t\tif ( imageUtils.isBlockImage( image ) ) {\n\t\t\t\t\tconst caption = imageCaptionUtils.getCaptionFromImageModelElement( image );\n\n\t\t\t\t\tif ( !caption ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\teditor.editing.reconvertItem( caption );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagecaption/imagecaptionui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core.js';\nimport { ButtonView } from 'ckeditor5/src/ui.js';\nimport ImageCaptionUtils from './imagecaptionutils.js';\nimport type ToggleImageCaptionCommand from './toggleimagecaptioncommand.js';\n\n/**\n * The image caption UI plugin. It introduces the `'toggleImageCaption'` UI button.\n */\nexport default class ImageCaptionUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageCaptionUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageCaptionUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst imageCaptionUtils: ImageCaptionUtils = editor.plugins.get( 'ImageCaptionUtils' );\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'toggleImageCaption', locale => {\n\t\t\tconst command: ToggleImageCaptionCommand = editor.commands.get( 'toggleImageCaption' )!;\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\ticon: icons.caption,\n\t\t\t\ttooltip: true,\n\t\t\t\tisToggleable: true\n\t\t\t} );\n\n\t\t\tview.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );\n\t\t\tview.bind( 'label' ).to( command, 'value', value => value ? t( 'Toggle caption off' ) : t( 'Toggle caption on' ) );\n\n\t\t\tthis.listenTo( view, 'execute', () => {\n\t\t\t\teditor.execute( 'toggleImageCaption', { focusCaptionOnShow: true } );\n\n\t\t\t\t// Scroll to the selection and highlight the caption if the caption showed up.\n\t\t\t\tconst modelCaptionElement = imageCaptionUtils.getCaptionFromModelSelection( editor.model.document.selection );\n\n\t\t\t\tif ( modelCaptionElement ) {\n\t\t\t\t\tconst figcaptionElement = editor.editing.mapper.toViewElement( modelCaptionElement );\n\n\t\t\t\t\teditingView.scrollToTheSelection();\n\n\t\t\t\t\teditingView.change( writer => {\n\t\t\t\t\t\twriter.addClass( 'image__caption_highlighted', figcaptionElement! );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\teditor.editing.view.focus();\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagecaption\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageCaptionEditing from './imagecaption/imagecaptionediting.js';\nimport ImageCaptionUI from './imagecaption/imagecaptionui.js';\n\nimport '../theme/imagecaption.css';\n\n/**\n * The image caption plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-captions image caption} documentation.\n */\nexport default class ImageCaption extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageCaptionEditing, ImageCaptionUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageCaption' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload/utils\n */\n\n/* global fetch, File */\n\nimport type { ViewElement } from 'ckeditor5/src/engine.js';\nimport { global } from 'ckeditor5/src/utils.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * Creates a regular expression used to test for image files.\n *\n * ```ts\n * const imageType = createImageTypeRegExp( [ 'png', 'jpeg', 'svg+xml', 'vnd.microsoft.icon' ] );\n *\n * console.log( 'is supported image', imageType.test( file.type ) );\n * ```\n */\nexport function createImageTypeRegExp( types: Array<string> ): RegExp {\n\t// Sanitize the MIME type name which may include: \"+\", \"-\" or \".\".\n\tconst regExpSafeNames = types.map( type => type.replace( '+', '\\\\+' ) );\n\n\treturn new RegExp( `^image\\\\/(${ regExpSafeNames.join( '|' ) })$` );\n}\n\n/**\n * Creates a promise that fetches the image local source (Base64 or blob) and resolves with a `File` object.\n *\n * @param image Image whose source to fetch.\n * @returns A promise which resolves when an image source is fetched and converted to a `File` instance.\n * It resolves with a `File` object. If there were any errors during file processing, the promise will be rejected.\n */\nexport function fetchLocalImage( image: ViewElement ): Promise<File> {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tconst imageSrc = image.getAttribute( 'src' )!;\n\n\t\t// Fetch works asynchronously and so does not block browser UI when processing data.\n\t\tfetch( imageSrc )\n\t\t\t.then( resource => resource.blob() )\n\t\t\t.then( blob => {\n\t\t\t\tconst mimeType = getImageMimeType( blob, imageSrc );\n\t\t\t\tconst ext = mimeType.replace( 'image/', '' );\n\t\t\t\tconst filename = `image.${ ext }`;\n\t\t\t\tconst file = new File( [ blob ], filename, { type: mimeType } );\n\n\t\t\t\tresolve( file );\n\t\t\t} )\n\t\t\t.catch( err => {\n\t\t\t\t// Fetch fails only, if it can't make a request due to a network failure or if anything prevented the request\n\t\t\t\t// from completing, i.e. the Content Security Policy rules. It is not possible to detect the exact cause of failure,\n\t\t\t\t// so we are just trying the fallback solution, if general TypeError is thrown.\n\t\t\t\treturn err && err.name === 'TypeError' ?\n\t\t\t\t\tconvertLocalImageOnCanvas( imageSrc ).then( resolve ).catch( reject ) :\n\t\t\t\t\treject( err );\n\t\t\t} );\n\t} );\n}\n\n/**\n * Checks whether a given node is an image element with a local source (Base64 or blob).\n *\n * @param node The node to check.\n */\nexport function isLocalImage( imageUtils: ImageUtils, node: ViewElement ): boolean {\n\tif ( !imageUtils.isInlineImageView( node ) || !node.getAttribute( 'src' ) ) {\n\t\treturn false;\n\t}\n\n\treturn !!node.getAttribute( 'src' )!.match( /^data:image\\/\\w+;base64,/g ) ||\n\t\t!!node.getAttribute( 'src' )!.match( /^blob:/g );\n}\n\n/**\n * Extracts an image type based on its blob representation or its source.\n * @param blob Image blob representation.\n * @param src Image `src` attribute value.\n */\nfunction getImageMimeType( blob: Blob, src: string ): string {\n\tif ( blob.type ) {\n\t\treturn blob.type;\n\t} else if ( src.match( /data:(image\\/\\w+);base64/ ) ) {\n\t\treturn src.match( /data:(image\\/\\w+);base64/ )![ 1 ].toLowerCase();\n\t} else {\n\t\t// Fallback to 'jpeg' as common extension.\n\t\treturn 'image/jpeg';\n\t}\n}\n\n/**\n * Creates a promise that converts the image local source (Base64 or blob) to a blob using canvas and resolves\n * with a `File` object.\n * @param imageSrc Image `src` attribute value.\n * @returns A promise which resolves when an image source is converted to a `File` instance.\n * It resolves with a `File` object. If there were any errors during file processing, the promise will be rejected.\n */\nfunction convertLocalImageOnCanvas( imageSrc: string ): Promise<File> {\n\treturn getBlobFromCanvas( imageSrc ).then( blob => {\n\t\tconst mimeType = getImageMimeType( blob, imageSrc );\n\t\tconst ext = mimeType.replace( 'image/', '' );\n\t\tconst filename = `image.${ ext }`;\n\n\t\treturn new File( [ blob ], filename, { type: mimeType } );\n\t} );\n}\n\n/**\n * Creates a promise that resolves with a `Blob` object converted from the image source (Base64 or blob).\n * @param imageSrc Image `src` attribute value.\n */\nfunction getBlobFromCanvas( imageSrc: string ): Promise<Blob> {\n\treturn new Promise( ( resolve, reject ) => {\n\t\tconst image = global.document.createElement( 'img' );\n\n\t\timage.addEventListener( 'load', () => {\n\t\t\tconst canvas = global.document.createElement( 'canvas' );\n\n\t\t\tcanvas.width = image.width;\n\t\t\tcanvas.height = image.height;\n\n\t\t\tconst ctx = canvas.getContext( '2d' )!;\n\n\t\t\tctx.drawImage( image, 0, 0 );\n\n\t\t\tcanvas.toBlob( blob => blob ? resolve( blob ) : reject() );\n\t\t} );\n\n\t\timage.addEventListener( 'error', () => reject() );\n\n\t\timage.src = imageSrc;\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload/imageuploadui\n */\n\nimport { Plugin, icons } from 'ckeditor5/src/core.js';\nimport {\n\tFileDialogButtonView, MenuBarMenuListItemFileDialogButtonView,\n\ttype ButtonView, type MenuBarMenuListItemButtonView\n} from 'ckeditor5/src/ui.js';\nimport { createImageTypeRegExp } from './utils.js';\nimport type ImageInsertUI from '../imageinsert/imageinsertui.js';\n\n/**\n * The image upload button plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature} documentation.\n *\n * Adds the `'uploadImage'` button to the {@link module:ui/componentfactory~ComponentFactory UI component factory}\n * and also the `imageUpload` button as an alias for backward compatibility.\n *\n * Adds the `'menuBar:uploadImage'` menu button to the {@link module:ui/componentfactory~ComponentFactory UI component factory}.\n *\n * It also integrates with the `insertImage` toolbar component and `menuBar:insertImage` menu component, which are the default components\n * through which image upload is available.\n */\nexport default class ImageUploadUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageUploadUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\t// Setup `uploadImage` button and add `imageUpload` button as an alias for backward compatibility.\n\t\teditor.ui.componentFactory.add( 'uploadImage', () => this._createToolbarButton() );\n\t\teditor.ui.componentFactory.add( 'imageUpload', () => this._createToolbarButton() );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:uploadImage', () => this._createMenuBarButton( 'standalone' ) );\n\n\t\tif ( editor.plugins.has( 'ImageInsertUI' ) ) {\n\t\t\teditor.plugins.get( 'ImageInsertUI' ).registerIntegration( {\n\t\t\t\tname: 'upload',\n\t\t\t\tobservable: () => editor.commands.get( 'uploadImage' )!,\n\t\t\t\tbuttonViewCreator: () => this._createToolbarButton(),\n\t\t\t\tformViewCreator: () => this._createDropdownButton(),\n\t\t\t\tmenuBarButtonViewCreator: isOnly => this._createMenuBarButton( isOnly ? 'insertOnly' : 'insertNested' )\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the base for various kinds of the button component provided by this feature.\n\t */\n\tprivate _createButton<T extends typeof FileDialogButtonView | typeof MenuBarMenuListItemFileDialogButtonView>(\n\t\tButtonClass: T\n\t): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst command = editor.commands.get( 'uploadImage' )!;\n\t\tconst imageTypes = editor.config.get( 'image.upload.types' )!;\n\t\tconst imageTypesRegExp = createImageTypeRegExp( imageTypes );\n\n\t\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\t\tconst t = locale.t;\n\n\t\tview.set( {\n\t\t\tacceptedType: imageTypes.map( type => `image/${ type }` ).join( ',' ),\n\t\t\tallowMultipleFiles: true,\n\t\t\tlabel: t( 'Upload from computer' ),\n\t\t\ticon: icons.imageUpload\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command );\n\n\t\tview.on( 'done', ( evt, files: FileList ) => {\n\t\t\tconst imagesToUpload = Array.from( files ).filter( file => imageTypesRegExp.test( file.type ) );\n\n\t\t\tif ( imagesToUpload.length ) {\n\t\t\t\teditor.execute( 'uploadImage', { file: imagesToUpload } );\n\n\t\t\t\teditor.editing.view.focus();\n\t\t\t}\n\t\t} );\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Creates a simple toolbar button, with an icon and a tooltip.\n\t */\n\tprivate _createToolbarButton(): ButtonView {\n\t\tconst t = this.editor.locale.t;\n\t\tconst imageInsertUI: ImageInsertUI = this.editor.plugins.get( 'ImageInsertUI' );\n\t\tconst uploadImageCommand = this.editor.commands.get( 'uploadImage' )!;\n\n\t\tconst button = this._createButton( FileDialogButtonView );\n\n\t\tbutton.tooltip = true;\n\t\tbutton.bind( 'label' ).to(\n\t\t\timageInsertUI,\n\t\t\t'isImageSelected',\n\t\t\tuploadImageCommand,\n\t\t\t'isAccessAllowed',\n\t\t\t( isImageSelected, isAccessAllowed ) => {\n\t\t\t\tif ( !isAccessAllowed ) {\n\t\t\t\t\treturn t( 'You have no image upload permissions.' );\n\t\t\t\t}\n\n\t\t\t\treturn isImageSelected ? t( 'Replace image from computer' ) : t( 'Upload image from computer' );\n\t\t\t}\n\t\t);\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates a button for the dropdown view, with an icon, text and no tooltip.\n\t */\n\tprivate _createDropdownButton(): ButtonView {\n\t\tconst t = this.editor.locale.t;\n\t\tconst imageInsertUI: ImageInsertUI = this.editor.plugins.get( 'ImageInsertUI' );\n\n\t\tconst button = this._createButton( FileDialogButtonView );\n\n\t\tbutton.withText = true;\n\n\t\tbutton.bind( 'label' ).to(\n\t\t\timageInsertUI,\n\t\t\t'isImageSelected',\n\t\t\tisImageSelected => isImageSelected ? t( 'Replace from computer' ) : t( 'Upload from computer' )\n\t\t);\n\n\t\tbutton.on( 'execute', () => {\n\t\t\timageInsertUI.dropdownView!.isOpen = false;\n\t\t} );\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates a button for the menu bar.\n\t */\n\tprivate _createMenuBarButton( type: 'standalone' | 'insertOnly' | 'insertNested' ): MenuBarMenuListItemButtonView {\n\t\tconst t = this.editor.locale.t;\n\t\tconst button = this._createButton( MenuBarMenuListItemFileDialogButtonView );\n\n\t\tbutton.withText = true;\n\n\t\tswitch ( type ) {\n\t\t\tcase 'standalone':\n\t\t\t\tbutton.label = t( 'Image from computer' );\n\t\t\t\tbreak;\n\t\t\tcase 'insertOnly':\n\t\t\t\tbutton.label = t( 'Image' );\n\t\t\t\tbreak;\n\t\t\tcase 'insertNested':\n\t\t\t\tbutton.label = t( 'From computer' );\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn button;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload/imageuploadprogress\n */\n\n/* globals setTimeout */\n\nimport { type Editor, Plugin } from 'ckeditor5/src/core.js';\nimport { FileRepository, type FileLoader } from 'ckeditor5/src/upload.js';\n\nimport '../../theme/imageuploadprogress.css';\nimport '../../theme/imageuploadicon.css';\nimport '../../theme/imageuploadloader.css';\nimport type { GetCallback } from 'ckeditor5/src/utils.js';\nimport type {\n\tDowncastWriter,\n\tEditingView,\n\tViewElement,\n\tViewContainerElement,\n\tViewUIElement,\n\tDowncastAttributeEvent,\n\tElement\n} from 'ckeditor5/src/engine.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * The image upload progress plugin.\n * It shows a placeholder when the image is read from the disk and a progress bar while the image is uploading.\n */\nexport default class ImageUploadProgress extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageUploadProgress' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * The image placeholder that is displayed before real image data can be accessed.\n\t *\n\t * For the record, this image is a 1x1 px GIF with an aspect ratio set by CSS.\n\t */\n\tprivate placeholder: string;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis.placeholder = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\t// Upload status change - update image's view according to that status.\n\t\tif ( editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\teditor.editing.downcastDispatcher.on<DowncastAttributeEvent>(\n\t\t\t\t'attribute:uploadStatus:imageBlock',\n\t\t\t\tthis.uploadStatusChange\n\t\t\t);\n\t\t}\n\n\t\tif ( editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\teditor.editing.downcastDispatcher.on<DowncastAttributeEvent>(\n\t\t\t\t'attribute:uploadStatus:imageInline',\n\t\t\t\tthis.uploadStatusChange\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * This method is called each time the image `uploadStatus` attribute is changed.\n\t *\n\t * @param evt An object containing information about the fired event.\n\t * @param data Additional information about the change.\n\t */\n\tprivate uploadStatusChange: GetCallback<DowncastAttributeEvent> = ( evt, data, conversionApi ) => {\n\t\tconst editor = this.editor;\n\t\tconst modelImage = data.item as Element;\n\t\tconst uploadId = modelImage.getAttribute( 'uploadId' ) as string | number;\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst status = uploadId ? data.attributeNewValue : null;\n\t\tconst placeholder = this.placeholder;\n\t\tconst viewFigure = editor.editing.mapper.toViewElement( modelImage )! as ViewContainerElement;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tif ( status == 'reading' ) {\n\t\t\t// Start \"appearing\" effect and show placeholder with infinite progress bar on the top\n\t\t\t// while image is read from disk.\n\t\t\t_startAppearEffect( viewFigure, viewWriter );\n\t\t\t_showPlaceholder( imageUtils, placeholder, viewFigure, viewWriter );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Show progress bar on the top of the image when image is uploading.\n\t\tif ( status == 'uploading' ) {\n\t\t\tconst loader = fileRepository.loaders.get( uploadId );\n\n\t\t\t// Start appear effect if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n\t\t\t_startAppearEffect( viewFigure, viewWriter );\n\n\t\t\tif ( !loader ) {\n\t\t\t\t// There is no loader associated with uploadId - this means that image came from external changes.\n\t\t\t\t// In such cases we still want to show the placeholder until image is fully uploaded.\n\t\t\t\t// Show placeholder if needed - see https://github.com/ckeditor/ckeditor5-image/issues/191.\n\t\t\t\t_showPlaceholder( imageUtils, placeholder, viewFigure, viewWriter );\n\t\t\t} else {\n\t\t\t\t// Hide placeholder and initialize progress bar showing upload progress.\n\t\t\t\t_hidePlaceholder( viewFigure, viewWriter );\n\t\t\t\t_showProgressBar( viewFigure, viewWriter, loader, editor.editing.view );\n\t\t\t\t_displayLocalImage( imageUtils, viewFigure!, viewWriter, loader );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( status == 'complete' && fileRepository.loaders.get( uploadId ) ) {\n\t\t\t_showCompleteIcon( viewFigure, viewWriter, editor.editing.view );\n\t\t}\n\n\t\t// Clean up.\n\t\t_hideProgressBar( viewFigure, viewWriter );\n\t\t_hidePlaceholder( viewFigure, viewWriter );\n\t\t_stopAppearEffect( viewFigure, viewWriter );\n\t};\n}\n\n/**\n * Adds ck-appear class to the image figure if one is not already applied.\n */\nfunction _startAppearEffect( viewFigure: ViewContainerElement, writer: DowncastWriter ) {\n\tif ( !viewFigure.hasClass( 'ck-appear' ) ) {\n\t\twriter.addClass( 'ck-appear', viewFigure );\n\t}\n}\n\n/**\n * Removes ck-appear class to the image figure if one is not already removed.\n */\nfunction _stopAppearEffect( viewFigure: ViewContainerElement, writer: DowncastWriter ) {\n\twriter.removeClass( 'ck-appear', viewFigure );\n}\n\n/**\n * Shows placeholder together with infinite progress bar on given image figure.\n */\nfunction _showPlaceholder( imageUtils: ImageUtils, placeholder: string, viewFigure: ViewContainerElement, writer: DowncastWriter ) {\n\tif ( !viewFigure.hasClass( 'ck-image-upload-placeholder' ) ) {\n\t\twriter.addClass( 'ck-image-upload-placeholder', viewFigure );\n\t}\n\n\tconst viewImg = imageUtils.findViewImgElement( viewFigure )!;\n\n\tif ( viewImg.getAttribute( 'src' ) !== placeholder ) {\n\t\twriter.setAttribute( 'src', placeholder, viewImg );\n\t}\n\n\tif ( !_getUIElement( viewFigure, 'placeholder' ) ) {\n\t\twriter.insert( writer.createPositionAfter( viewImg ), _createPlaceholder( writer ) );\n\t}\n}\n\n/**\n * Removes placeholder together with infinite progress bar on given image figure.\n */\nfunction _hidePlaceholder( viewFigure: ViewContainerElement, writer: DowncastWriter ) {\n\tif ( viewFigure.hasClass( 'ck-image-upload-placeholder' ) ) {\n\t\twriter.removeClass( 'ck-image-upload-placeholder', viewFigure );\n\t}\n\n\t_removeUIElement( viewFigure, writer, 'placeholder' );\n}\n\n/**\n * Shows progress bar displaying upload progress.\n * Attaches it to the file loader to update when upload percentace is changed.\n */\nfunction _showProgressBar( viewFigure: ViewContainerElement, writer: DowncastWriter, loader: FileLoader, view: EditingView ) {\n\tconst progressBar = _createProgressBar( writer );\n\twriter.insert( writer.createPositionAt( viewFigure, 'end' ), progressBar );\n\n\t// Update progress bar width when uploadedPercent is changed.\n\tloader.on( 'change:uploadedPercent', ( evt, name, value ) => {\n\t\tview.change( writer => {\n\t\t\twriter.setStyle( 'width', value + '%', progressBar );\n\t\t} );\n\t} );\n}\n\n/**\n * Hides upload progress bar.\n */\nfunction _hideProgressBar( viewFigure: ViewContainerElement, writer: DowncastWriter ) {\n\t_removeUIElement( viewFigure, writer, 'progressBar' );\n}\n\n/**\n * Shows complete icon and hides after a certain amount of time.\n */\nfunction _showCompleteIcon( viewFigure: ViewContainerElement, writer: DowncastWriter, view: EditingView ) {\n\tconst completeIcon = writer.createUIElement( 'div', { class: 'ck-image-upload-complete-icon' } );\n\n\twriter.insert( writer.createPositionAt( viewFigure, 'end' ), completeIcon );\n\n\tsetTimeout( () => {\n\t\tview.change( writer => writer.remove( writer.createRangeOn( completeIcon ) ) );\n\t}, 3000 );\n}\n\n/**\n * Create progress bar element using {@link module:engine/view/uielement~UIElement}.\n */\nfunction _createProgressBar( writer: DowncastWriter ): ViewUIElement {\n\tconst progressBar = writer.createUIElement( 'div', { class: 'ck-progress-bar' } );\n\n\twriter.setCustomProperty( 'progressBar', true, progressBar );\n\n\treturn progressBar;\n}\n\n/**\n * Create placeholder element using {@link module:engine/view/uielement~UIElement}.\n */\nfunction _createPlaceholder( writer: DowncastWriter ): ViewUIElement {\n\tconst placeholder = writer.createUIElement( 'div', { class: 'ck-upload-placeholder-loader' } );\n\n\twriter.setCustomProperty( 'placeholder', true, placeholder );\n\n\treturn placeholder;\n}\n\n/**\n * Returns {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n * Returns `undefined` if element is not found.\n */\nfunction _getUIElement( imageFigure: ViewElement, uniqueProperty: string ): ViewUIElement | undefined {\n\tfor ( const child of imageFigure.getChildren() ) {\n\t\tif ( ( child as ViewElement ).getCustomProperty( uniqueProperty ) ) {\n\t\t\treturn child as ViewUIElement;\n\t\t}\n\t}\n}\n\n/**\n * Removes {@link module:engine/view/uielement~UIElement} of given unique property from image figure element.\n */\nfunction _removeUIElement( viewFigure: ViewContainerElement, writer: DowncastWriter, uniqueProperty: string ) {\n\tconst element = _getUIElement( viewFigure, uniqueProperty );\n\n\tif ( element ) {\n\t\twriter.remove( writer.createRangeOn( element ) );\n\t}\n}\n\n/**\n * Displays local data from file loader.\n */\nfunction _displayLocalImage( imageUtils: ImageUtils, viewFigure: ViewElement, writer: DowncastWriter, loader: FileLoader ) {\n\tif ( loader.data ) {\n\t\tconst viewImg = imageUtils.findViewImgElement( viewFigure )!;\n\n\t\twriter.setAttribute( 'src', loader.data, viewImg );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport { FileRepository } from 'ckeditor5/src/upload.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport { toArray, type ArrayOrItem } from 'ckeditor5/src/utils.js';\nimport type { Position } from 'ckeditor5/src/engine.js';\n\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * @module image/imageupload/uploadimagecommand\n */\n\n/**\n * The upload image command.\n *\n * The command is registered by the {@link module:image/imageupload/imageuploadediting~ImageUploadEditing} plugin as `uploadImage`\n * and it is also available via aliased `imageUpload` name.\n *\n * In order to upload an image at the current selection position\n * (according to the {@link module:widget/utils~findOptimalInsertionRange} algorithm),\n * execute the command and pass the native image file instance:\n *\n * ```ts\n * this.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {\n * \t// Assuming that only images were pasted:\n * \tconst images = Array.from( data.dataTransfer.files );\n *\n * \t// Upload the first image:\n * \teditor.execute( 'uploadImage', { file: images[ 0 ] } );\n * } );\n * ```\n *\n * It is also possible to insert multiple images at once:\n *\n * ```ts\n * editor.execute( 'uploadImage', {\n * \tfile: [\n * \t\tfile1,\n * \t\tfile2\n * \t]\n * } );\n * ```\n */\nexport default class UploadImageCommand extends Command {\n\t/**\n\t * The command property: `false` if there is no permission on image upload, otherwise `true`.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tdeclare public isAccessAllowed: boolean;\n\n\t/**\n\t * Creates an instance of the `imageUlpoad` command. When executed, the command upload one of\n\t * the currently selected image from computer.\n\t *\n\t * @param editor The editor instance.\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis.set( 'isAccessAllowed', true );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst selectedElement = editor.model.document.selection.getSelectedElement()!;\n\n\t\t// TODO: This needs refactoring.\n\t\tthis.isEnabled = imageUtils.isImageAllowed() || imageUtils.isImage( selectedElement );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options Options for the executed command.\n\t * @param options.file The image file or an array of image files to upload.\n\t */\n\tpublic override execute( options: { file: ArrayOrItem<File> } ): void {\n\t\tconst files = toArray( options.file );\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\t// In case of multiple files, each file (starting from the 2nd) will be inserted at a position that\n\t\t// follows the previous one. That will move the selection and, to stay on the safe side and make sure\n\t\t// all images inherit the same selection attributes, they are collected beforehand.\n\t\t//\n\t\t// Applying these attributes ensures, for instance, that inserting an (inline) image into a link does\n\t\t// not split that link but preserves its continuity.\n\t\t//\n\t\t// Note: Selection attributes that do not make sense for images will be filtered out by insertImage() anyway.\n\t\tconst selectionAttributes = Object.fromEntries( selection.getAttributes() );\n\n\t\tfiles.forEach( ( file, index ) => {\n\t\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t\t// Inserting of an inline image replace the selected element and make a selection on the inserted image.\n\t\t\t// Therefore inserting multiple inline images requires creating position after each element.\n\t\t\tif ( index && selectedElement && imageUtils.isImage( selectedElement ) ) {\n\t\t\t\tconst position = this.editor.model.createPositionAfter( selectedElement );\n\n\t\t\t\tthis._uploadImage( file, selectionAttributes, position );\n\t\t\t} else {\n\t\t\t\tthis._uploadImage( file, selectionAttributes );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Handles uploading single file.\n\t */\n\tprivate _uploadImage( file: File, attributes: object, position?: Position ): void {\n\t\tconst editor = this.editor;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst loader = fileRepository.createLoader( file );\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\t// Do not throw when upload adapter is not set. FileRepository will log an error anyway.\n\t\tif ( !loader ) {\n\t\t\treturn;\n\t\t}\n\n\t\timageUtils.insertImage( { ...attributes, uploadId: loader.id }, position );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload/imageuploadediting\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\n\nimport {\n\tUpcastWriter,\n\ttype Element,\n\ttype Item,\n\ttype Writer,\n\ttype DataTransfer,\n\ttype ViewElement,\n\ttype NodeAttributes\n} from 'ckeditor5/src/engine.js';\n\nimport { Notification } from 'ckeditor5/src/ui.js';\nimport { ClipboardPipeline, type ViewDocumentClipboardInputEvent } from 'ckeditor5/src/clipboard.js';\nimport { FileRepository, type UploadResponse, type FileLoader } from 'ckeditor5/src/upload.js';\nimport { env } from 'ckeditor5/src/utils.js';\n\nimport ImageUtils from '../imageutils.js';\nimport UploadImageCommand from './uploadimagecommand.js';\nimport { fetchLocalImage, isLocalImage } from '../../src/imageupload/utils.js';\nimport { createImageTypeRegExp } from './utils.js';\n\n/**\n * The editing part of the image upload feature. It registers the `'uploadImage'` command\n * and the `imageUpload` command as an aliased name.\n *\n * When an image is uploaded, it fires the {@link ~ImageUploadEditing#event:uploadComplete `uploadComplete`} event\n * that allows adding custom attributes to the {@link module:engine/model/element~Element image element}.\n */\nexport default class ImageUploadEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ FileRepository, Notification, ClipboardPipeline, ImageUtils ] as const;\n\t}\n\n\tpublic static get pluginName() {\n\t\treturn 'ImageUploadEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * An internal mapping of {@link module:upload/filerepository~FileLoader#id file loader UIDs} and\n\t * model elements during the upload.\n\t *\n\t * Model element of the uploaded image can change, for instance, when {@link module:image/image/imagetypecommand~ImageTypeCommand}\n\t * is executed as a result of adding caption or changing image style. As a result, the upload logic must keep track of the model\n\t * element (reference) and resolve the upload for the correct model element (instead of the one that landed in the `$graveyard`\n\t * after image type changed).\n\t */\n\tprivate readonly _uploadImageElements: Map<string, Element>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'image', {\n\t\t\tupload: {\n\t\t\t\ttypes: [ 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff' ]\n\t\t\t}\n\t\t} );\n\n\t\tthis._uploadImageElements = new Map();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst doc = editor.model.document;\n\t\tconst conversion = editor.conversion;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst clipboardPipeline: ClipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\t\tconst imageTypes = createImageTypeRegExp( editor.config.get( 'image.upload.types' )! );\n\t\tconst uploadImageCommand = new UploadImageCommand( editor );\n\n\t\t// Register `uploadImage` command and add `imageUpload` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'uploadImage', uploadImageCommand );\n\t\teditor.commands.add( 'imageUpload', uploadImageCommand );\n\n\t\t// Register upcast converter for uploadId.\n\t\tconversion.for( 'upcast' )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'img',\n\t\t\t\t\tkey: 'uploadId'\n\t\t\t\t},\n\t\t\t\tmodel: 'uploadId'\n\t\t\t} );\n\n\t\t// Handle pasted images.\n\t\t// For every image file, a new file loader is created and a placeholder image is\n\t\t// inserted into the content. Then, those images are uploaded once they appear in the model\n\t\t// (see Document#change listener below).\n\t\tthis.listenTo<ViewDocumentClipboardInputEvent>( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {\n\t\t\t// Skip if non empty HTML data is included.\n\t\t\t// https://github.com/ckeditor/ckeditor5-upload/issues/68\n\t\t\tif ( isHtmlIncluded( data.dataTransfer ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst images = Array.from( data.dataTransfer.files ).filter( file => {\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5-image/pull/254.\n\t\t\t\tif ( !file ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn imageTypes.test( file.type );\n\t\t\t} );\n\n\t\t\tif ( !images.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tevt.stop();\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\t// Set selection to paste target.\n\t\t\t\tif ( data.targetRanges ) {\n\t\t\t\t\twriter.setSelection( data.targetRanges.map( viewRange => editor.editing.mapper.toModelRange( viewRange ) ) );\n\t\t\t\t}\n\n\t\t\t\teditor.execute( 'uploadImage', { file: images } );\n\t\t\t} );\n\n\t\t\tconst uploadImageCommand = editor.commands.get( 'uploadImage' )!;\n\n\t\t\tif ( !uploadImageCommand.isAccessAllowed ) {\n\t\t\t\tconst notification: Notification = editor.plugins.get( 'Notification' );\n\t\t\t\tconst t = editor.locale.t;\n\n\t\t\t\t// eslint-disable-next-line max-len\n\t\t\t\tnotification.showWarning( t( 'You have no image upload permissions.' ), {\n\t\t\t\t\tnamespace: 'image'\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\t// Handle HTML pasted with images with base64 or blob sources.\n\t\t// For every image file, a new file loader is created and a placeholder image is\n\t\t// inserted into the content. Then, those images are uploaded once they appear in the model\n\t\t// (see Document#change listener below).\n\t\tthis.listenTo( clipboardPipeline, 'inputTransformation', ( evt, data ) => {\n\t\t\tconst fetchableImages = Array.from( editor.editing.view.createRangeIn( data.content ) )\n\t\t\t\t.map( value => value.item as ViewElement )\n\t\t\t\t.filter( viewElement =>\n\t\t\t\t\tisLocalImage( imageUtils, viewElement ) &&\n\t\t\t\t\t!viewElement.getAttribute( 'uploadProcessed' ) )\n\t\t\t\t.map( viewElement => { return { promise: fetchLocalImage( viewElement ), imageElement: viewElement }; } );\n\n\t\t\tif ( !fetchableImages.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst writer = new UpcastWriter( editor.editing.view.document );\n\n\t\t\tfor ( const fetchableImage of fetchableImages ) {\n\t\t\t\t// Set attribute marking that the image was processed already.\n\t\t\t\twriter.setAttribute( 'uploadProcessed', true, fetchableImage.imageElement );\n\n\t\t\t\tconst loader = fileRepository.createLoader( fetchableImage.promise );\n\n\t\t\t\tif ( loader ) {\n\t\t\t\t\twriter.setAttribute( 'src', '', fetchableImage.imageElement );\n\t\t\t\t\twriter.setAttribute( 'uploadId', loader.id, fetchableImage.imageElement );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Prevents from the browser redirecting to the dropped image.\n\t\teditor.editing.view.document.on( 'dragover', ( evt, data ) => {\n\t\t\tdata.preventDefault();\n\t\t} );\n\n\t\t// Upload placeholder images that appeared in the model.\n\t\tdoc.on( 'change', () => {\n\t\t\t// Note: Reversing changes to start with insertions and only then handle removals. If it was the other way around,\n\t\t\t// loaders for **all** images that land in the $graveyard would abort while in fact only those that were **not** replaced\n\t\t\t// by other images should be aborted.\n\t\t\tconst changes = doc.differ.getChanges( { includeChangesInGraveyard: true } ).reverse();\n\t\t\tconst insertedImagesIds = new Set();\n\n\t\t\tfor ( const entry of changes ) {\n\t\t\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\t\t\tconst item = entry.position.nodeAfter!;\n\t\t\t\t\tconst isInsertedInGraveyard = entry.position.root.rootName == '$graveyard';\n\n\t\t\t\t\tfor ( const imageElement of getImagesFromChangeItem( editor, item ) ) {\n\t\t\t\t\t\t// Check if the image element still has upload id.\n\t\t\t\t\t\tconst uploadId = imageElement.getAttribute( 'uploadId' ) as string;\n\n\t\t\t\t\t\tif ( !uploadId ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Check if the image is loaded on this client.\n\t\t\t\t\t\tconst loader = fileRepository.loaders.get( uploadId );\n\n\t\t\t\t\t\tif ( !loader ) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( isInsertedInGraveyard ) {\n\t\t\t\t\t\t\t// If the image was inserted to the graveyard for good (**not** replaced by another image),\n\t\t\t\t\t\t\t// only then abort the loading process.\n\t\t\t\t\t\t\tif ( !insertedImagesIds.has( uploadId ) ) {\n\t\t\t\t\t\t\t\tloader.abort();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Remember the upload id of the inserted image. If it acted as a replacement for another\n\t\t\t\t\t\t\t// image (which landed in the $graveyard), the related loader will not be aborted because\n\t\t\t\t\t\t\t// this is still the same image upload.\n\t\t\t\t\t\t\tinsertedImagesIds.add( uploadId );\n\n\t\t\t\t\t\t\t// Keep the mapping between the upload ID and the image model element so the upload\n\t\t\t\t\t\t\t// can later resolve in the context of the correct model element. The model element could\n\t\t\t\t\t\t\t// change for the same upload if one image was replaced by another (e.g. image type was changed),\n\t\t\t\t\t\t\t// so this may also replace an existing mapping.\n\t\t\t\t\t\t\tthis._uploadImageElements.set( uploadId, imageElement as Element );\n\n\t\t\t\t\t\t\tif ( loader.status == 'idle' ) {\n\t\t\t\t\t\t\t\t// If the image was inserted into content and has not been loaded yet, start loading it.\n\t\t\t\t\t\t\t\tthis._readAndUpload( loader );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Set the default handler for feeding the image element with `src` and `srcset` attributes.\n\t\t// Also set the natural `width` and `height` attributes (if not already set).\n\t\tthis.on<ImageUploadCompleteEvent>( 'uploadComplete', ( evt, { imageElement, data } ) => {\n\t\t\tconst urls = data.urls ? data.urls as Record<string, unknown> : data;\n\n\t\t\tthis.editor.model.change( writer => {\n\t\t\t\twriter.setAttribute( 'src', urls.default, imageElement );\n\t\t\t\tthis._parseAndSetSrcsetAttributeOnImage( urls, imageElement, writer );\n\t\t\t\timageUtils.setImageNaturalSizeAttributes( imageElement );\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst schema = this.editor.model.schema;\n\n\t\t// Setup schema to allow uploadId and uploadStatus for images.\n\t\t// Wait for ImageBlockEditing or ImageInlineEditing to register their elements first,\n\t\t// that's why doing this in afterInit() instead of init().\n\t\tif ( this.editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\tschema.extend( 'imageBlock', {\n\t\t\t\tallowAttributes: [ 'uploadId', 'uploadStatus' ]\n\t\t\t} );\n\t\t}\n\n\t\tif ( this.editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\tschema.extend( 'imageInline', {\n\t\t\t\tallowAttributes: [ 'uploadId', 'uploadStatus' ]\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Reads and uploads an image.\n\t *\n\t * The image is read from the disk and as a Base64-encoded string it is set temporarily to\n\t * `image[src]`. When the image is successfully uploaded, the temporary data is replaced with the target\n\t * image's URL (the URL to the uploaded image on the server).\n\t */\n\tprotected _readAndUpload( loader: FileLoader ): Promise<void> {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst t = editor.locale.t;\n\t\tconst fileRepository = editor.plugins.get( FileRepository );\n\t\tconst notification = editor.plugins.get( Notification );\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst imageUploadElements = this._uploadImageElements;\n\n\t\tmodel.enqueueChange( { isUndoable: false }, writer => {\n\t\t\twriter.setAttribute( 'uploadStatus', 'reading', imageUploadElements.get( loader.id )! );\n\t\t} );\n\n\t\treturn loader.read()\n\t\t\t.then( () => {\n\t\t\t\tconst promise = loader.upload();\n\t\t\t\tconst imageElement = imageUploadElements.get( loader.id )!;\n\n\t\t\t\t// Force re–paint in Safari. Without it, the image will display with a wrong size.\n\t\t\t\t// https://github.com/ckeditor/ckeditor5/issues/1975\n\t\t\t\t/* istanbul ignore next -- @preserve */\n\t\t\t\tif ( env.isSafari ) {\n\t\t\t\t\tconst viewFigure = editor.editing.mapper.toViewElement( imageElement )!;\n\t\t\t\t\tconst viewImg = imageUtils.findViewImgElement( viewFigure )!;\n\n\t\t\t\t\teditor.editing.view.once( 'render', () => {\n\t\t\t\t\t\t// Early returns just to be safe. There might be some code ran\n\t\t\t\t\t\t// in between the outer scope and this callback.\n\t\t\t\t\t\tif ( !viewImg.parent ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst domFigure = editor.editing.view.domConverter.mapViewToDom( viewImg.parent ) as HTMLElement | undefined;\n\n\t\t\t\t\t\tif ( !domFigure ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst originalDisplay = domFigure.style.display;\n\n\t\t\t\t\t\tdomFigure.style.display = 'none';\n\n\t\t\t\t\t\t// Make sure this line will never be removed during minification for having \"no effect\".\n\t\t\t\t\t\t( domFigure as any )._ckHack = domFigure.offsetHeight;\n\n\t\t\t\t\t\tdomFigure.style.display = originalDisplay;\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tif ( editor.ui ) {\n\t\t\t\t\teditor.ui.ariaLiveAnnouncer.announce( t( 'Uploading image' ) );\n\t\t\t\t}\n\n\t\t\t\tmodel.enqueueChange( { isUndoable: false }, writer => {\n\t\t\t\t\twriter.setAttribute( 'uploadStatus', 'uploading', imageElement );\n\t\t\t\t} );\n\n\t\t\t\treturn promise;\n\t\t\t} )\n\t\t\t.then( data => {\n\t\t\t\tmodel.enqueueChange( { isUndoable: false }, writer => {\n\t\t\t\t\tconst imageElement = imageUploadElements.get( loader.id )!;\n\n\t\t\t\t\twriter.setAttribute( 'uploadStatus', 'complete', imageElement );\n\n\t\t\t\t\tif ( editor.ui ) {\n\t\t\t\t\t\teditor.ui.ariaLiveAnnouncer.announce( t( 'Image upload complete' ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.fire<ImageUploadCompleteEvent>( 'uploadComplete', { data, imageElement } );\n\t\t\t\t} );\n\n\t\t\t\tclean();\n\t\t\t} )\n\t\t\t.catch( error => {\n\t\t\t\tif ( editor.ui ) {\n\t\t\t\t\teditor.ui.ariaLiveAnnouncer.announce( t( 'Error during image upload' ) );\n\t\t\t\t}\n\n\t\t\t\t// If status is not 'error' nor 'aborted' - throw error because it means that something else went wrong,\n\t\t\t\t// it might be generic error and it would be real pain to find what is going on.\n\t\t\t\tif ( loader.status !== 'error' && loader.status !== 'aborted' ) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\n\t\t\t\t// Might be 'aborted'.\n\t\t\t\tif ( loader.status == 'error' && error ) {\n\t\t\t\t\tnotification.showWarning( error, {\n\t\t\t\t\t\ttitle: t( 'Upload failed' ),\n\t\t\t\t\t\tnamespace: 'upload'\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\t// Permanently remove image from insertion batch.\n\t\t\t\tmodel.enqueueChange( { isUndoable: false }, writer => {\n\t\t\t\t\twriter.remove( imageUploadElements.get( loader.id )! );\n\t\t\t\t} );\n\n\t\t\t\tclean();\n\t\t\t} );\n\n\t\tfunction clean() {\n\t\t\tmodel.enqueueChange( { isUndoable: false }, writer => {\n\t\t\t\tconst imageElement = imageUploadElements.get( loader.id )!;\n\n\t\t\t\twriter.removeAttribute( 'uploadId', imageElement );\n\t\t\t\twriter.removeAttribute( 'uploadStatus', imageElement );\n\n\t\t\t\timageUploadElements.delete( loader.id );\n\t\t\t} );\n\n\t\t\tfileRepository.destroyLoader( loader );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the `srcset` attribute based on a given file upload response and sets it as an attribute to a specific image element.\n\t *\n\t * @param data Data object from which `srcset` will be created.\n\t * @param image The image element on which the `srcset` attribute will be set.\n\t */\n\tprotected _parseAndSetSrcsetAttributeOnImage( data: Record<string, unknown>, image: Element, writer: Writer ): void {\n\t\t// Srcset attribute for responsive images support.\n\t\tlet maxWidth = 0;\n\n\t\tconst srcsetAttribute = Object.keys( data )\n\t\t\t// Filter out keys that are not integers.\n\t\t\t.filter( key => {\n\t\t\t\tconst width = parseInt( key, 10 );\n\n\t\t\t\tif ( !isNaN( width ) ) {\n\t\t\t\t\tmaxWidth = Math.max( maxWidth, width );\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} )\n\n\t\t\t// Convert each key to srcset entry.\n\t\t\t.map( key => `${ data[ key ] } ${ key }w` )\n\n\t\t\t// Join all entries.\n\t\t\t.join( ', ' );\n\n\t\tif ( srcsetAttribute != '' ) {\n\t\t\tconst attributes: NodeAttributes = {\n\t\t\t\tsrcset: srcsetAttribute\n\t\t\t};\n\n\t\t\tif ( !image.hasAttribute( 'width' ) && !image.hasAttribute( 'height' ) ) {\n\t\t\t\tattributes.width = maxWidth;\n\t\t\t}\n\n\t\t\twriter.setAttributes( attributes, image );\n\t\t}\n\t}\n}\n\n/**\n * Returns `true` if non-empty `text/html` is included in the data transfer.\n */\nexport function isHtmlIncluded( dataTransfer: DataTransfer ): boolean {\n\treturn Array.from( dataTransfer.types ).includes( 'text/html' ) && dataTransfer.getData( 'text/html' ) !== '';\n}\n\nfunction getImagesFromChangeItem( editor: Editor, item: Item ): Array<Item> {\n\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\treturn Array.from( editor.model.createRangeOn( item ) )\n\t\t.filter( value => imageUtils.isImage( value.item as Element ) )\n\t\t.map( value => value.item );\n}\n\n/**\n * An event fired when an image is uploaded. You can hook into this event to provide\n * custom attributes to the {@link module:engine/model/element~Element image element} based on the data from\n * the server.\n *\n * ```ts\n * const imageUploadEditing = editor.plugins.get( 'ImageUploadEditing' );\n *\n * imageUploadEditing.on( 'uploadComplete', ( evt, { data, imageElement } ) => {\n * \teditor.model.change( writer => {\n * \t\twriter.setAttribute( 'someAttribute', 'foo', imageElement );\n * \t} );\n * } );\n * ```\n *\n * You can also stop the default handler that sets the `src` and `srcset` attributes\n * if you want to provide custom values for these attributes.\n *\n * ```ts\n * imageUploadEditing.on( 'uploadComplete', ( evt, { data, imageElement } ) => {\n * \tevt.stop();\n * } );\n * ```\n *\n * **Note**: This event is fired by the {@link module:image/imageupload/imageuploadediting~ImageUploadEditing} plugin.\n *\n * @eventName ~ImageUploadEditing#uploadComplete\n * @param data The `uploadComplete` event data.\n */\nexport type ImageUploadCompleteEvent = {\n\tname: 'uploadComplete';\n\targs: [ data: ImageUploadCompleteData];\n};\n\nexport type ImageUploadCompleteData = {\n\n\t/**\n\t * The data coming from the upload adapter.\n\t */\n\tdata: UploadResponse;\n\n\t/**\n\t * The model {@link module:engine/model/element~Element image element} that can be customized.\n\t */\n\timageElement: Element;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageupload\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageUploadUI from './imageupload/imageuploadui.js';\nimport ImageUploadProgress from './imageupload/imageuploadprogress.js';\nimport ImageUploadEditing from './imageupload/imageuploadediting.js';\n\n/**\n * The image upload plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload image upload feature} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins to enable image uploading:\n *\n * * {@link module:image/imageupload/imageuploadediting~ImageUploadEditing},\n * * {@link module:image/imageupload/imageuploadui~ImageUploadUI},\n * * {@link module:image/imageupload/imageuploadprogress~ImageUploadProgress}.\n */\nexport default class ImageUpload extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageUpload' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUploadEditing, ImageUploadUI, ImageUploadProgress ] as const;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageinsert/ui/imageinserturlview\n */\n\nimport {\n\tView,\n\tLabeledFieldView,\n\tcreateLabeledInputText,\n\ttype InputTextView\n} from 'ckeditor5/src/ui.js';\nimport { KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';\n\n/**\n * The insert an image via URL view.\n *\n * See {@link module:image/imageinsert/imageinsertviaurlui~ImageInsertViaUrlUI}.\n */\nexport default class ImageInsertUrlView extends View {\n\t/**\n\t * The URL input field view.\n\t */\n\tpublic urlInputView: LabeledFieldView<InputTextView>;\n\n\t/**\n\t * The value of the URL input.\n\t *\n\t * @observable\n\t */\n\tdeclare public imageURLInputValue: string;\n\n\t/**\n\t * Observable property used to alter labels while some image is selected and when it is not.\n\t *\n\t * @observable\n\t */\n\tdeclare public isImageSelected: boolean;\n\n\t/**\n\t * Observable property indicating whether the form interactive elements should be enabled.\n\t *\n\t * @observable\n\t */\n\tdeclare public isEnabled: boolean;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Creates a view for the dropdown panel of {@link module:image/imageinsert/imageinsertui~ImageInsertUI}.\n\t *\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.set( 'imageURLInputValue', '' );\n\t\tthis.set( 'isImageSelected', false );\n\t\tthis.set( 'isEnabled', true );\n\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\tthis.urlInputView = this._createUrlInputView();\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-image-insert-url'\n\t\t\t\t]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.urlInputView,\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-image-insert-url__action-row'\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Creates the {@link #urlInputView}.\n\t */\n\tprivate _createUrlInputView() {\n\t\tconst locale = this.locale!;\n\t\tconst t = locale.t;\n\t\tconst urlInputView = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\turlInputView.bind( 'label' ).to( this, 'isImageSelected',\n\t\t\tvalue => value ? t( 'Update image URL' ) : t( 'Insert image via URL' )\n\t\t);\n\n\t\turlInputView.bind( 'isEnabled' ).to( this );\n\n\t\turlInputView.fieldView.inputMode = 'url';\n\t\turlInputView.fieldView.placeholder = 'https://example.com/image.png';\n\n\t\turlInputView.fieldView.bind( 'value' ).to( this, 'imageURLInputValue', ( value: string ) => value || '' );\n\t\turlInputView.fieldView.on( 'input', () => {\n\t\t\tthis.imageURLInputValue = urlInputView.fieldView.element!.value.trim();\n\t\t} );\n\n\t\treturn urlInputView;\n\t}\n\n\t/**\n\t * Focuses the view.\n\t */\n\tpublic focus(): void {\n\t\tthis.urlInputView.focus();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageinsert/imageinsertviaurlui\n */\n\nimport { icons, Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, Dialog, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\n\nimport ImageInsertUI from './imageinsertui.js';\nimport ImageInsertUrlView from './ui/imageinserturlview.js';\n\n/**\n * The image insert via URL plugin (UI part).\n *\n * The plugin introduces two UI components to the {@link module:ui/componentfactory~ComponentFactory UI component factory}:\n *\n * * the `'insertImageViaUrl'` toolbar button,\n * * the `'menuBar:insertImageViaUrl'` menu bar component.\n *\n * It also integrates with the `insertImage` toolbar component and `menuBar:insertImage` menu component, which are default components\n * through which inserting image via URL is available.\n */\nexport default class ImageInsertViaUrlUI extends Plugin {\n\tprivate _imageInsertUI!: ImageInsertUI;\n\tprivate _formView?: ImageInsertUrlView;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageInsertViaUrlUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageInsertUI, Dialog ] as const;\n\t}\n\n\tpublic init(): void {\n\t\tthis.editor.ui.componentFactory.add( 'insertImageViaUrl', () => this._createToolbarButton() );\n\t\tthis.editor.ui.componentFactory.add( 'menuBar:insertImageViaUrl', () => this._createMenuBarButton( 'standalone' ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tthis._imageInsertUI = this.editor.plugins.get( 'ImageInsertUI' );\n\n\t\tthis._imageInsertUI.registerIntegration( {\n\t\t\tname: 'url',\n\t\t\tobservable: () => this.editor.commands.get( 'insertImage' )!,\n\t\t\tbuttonViewCreator: () => this._createToolbarButton(),\n\t\t\tformViewCreator: () => this._createDropdownButton(),\n\t\t\tmenuBarButtonViewCreator: isOnly => this._createMenuBarButton( isOnly ? 'insertOnly' : 'insertNested' )\n\t\t} );\n\t}\n\n\t/**\n\t * Creates the base for various kinds of the button component provided by this feature.\n\t */\n\tprivate _createInsertUrlButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>(\n\t\tButtonClass: T\n\t): InstanceType<T> {\n\t\tconst button = new ButtonClass( this.editor.locale ) as InstanceType<T>;\n\n\t\tbutton.icon = icons.imageUrl;\n\t\tbutton.on( 'execute', () => {\n\t\t\tthis._showModal();\n\t\t} );\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates a simple toolbar button, with an icon and a tooltip.\n\t */\n\tprivate _createToolbarButton(): ButtonView {\n\t\tconst t = this.editor.locale.t;\n\t\tconst button = this._createInsertUrlButton( ButtonView );\n\n\t\tbutton.tooltip = true;\n\t\tbutton.bind( 'label' ).to(\n\t\t\tthis._imageInsertUI,\n\t\t\t'isImageSelected',\n\t\t\tisImageSelected => isImageSelected ? t( 'Update image URL' ) : t( 'Insert image via URL' )\n\t\t);\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates a button for the dropdown view, with an icon, text and no tooltip.\n\t */\n\tprivate _createDropdownButton(): ButtonView {\n\t\tconst t = this.editor.locale.t;\n\t\tconst button = this._createInsertUrlButton( ButtonView );\n\n\t\tbutton.withText = true;\n\t\tbutton.bind( 'label' ).to(\n\t\t\tthis._imageInsertUI,\n\t\t\t'isImageSelected',\n\t\t\tisImageSelected => isImageSelected ? t( 'Update image URL' ) : t( 'Insert via URL' )\n\t\t);\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates a button for the menu bar.\n\t */\n\tprivate _createMenuBarButton( type: 'standalone' | 'insertOnly' | 'insertNested' ): MenuBarMenuListItemButtonView {\n\t\tconst t = this.editor.locale.t;\n\t\tconst button = this._createInsertUrlButton( MenuBarMenuListItemButtonView );\n\n\t\tbutton.withText = true;\n\n\t\tswitch ( type ) {\n\t\t\tcase 'standalone':\n\t\t\t\tbutton.label = t( 'Image via URL' );\n\t\t\t\tbreak;\n\t\t\tcase 'insertOnly':\n\t\t\t\tbutton.label = t( 'Image' );\n\t\t\t\tbreak;\n\t\t\tcase 'insertNested':\n\t\t\t\tbutton.label = t( 'Via URL' );\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates the form view used to submit the image URL.\n\t */\n\tprivate _createInsertUrlView(): ImageInsertUrlView {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\n\t\tconst replaceImageSourceCommand = editor.commands.get( 'replaceImageSource' )!;\n\t\tconst insertImageCommand = editor.commands.get( 'insertImage' )!;\n\n\t\tconst imageInsertUrlView = new ImageInsertUrlView( locale );\n\n\t\timageInsertUrlView.bind( 'isImageSelected' ).to( this._imageInsertUI );\n\t\timageInsertUrlView.bind( 'isEnabled' ).toMany( [ insertImageCommand, replaceImageSourceCommand ], 'isEnabled', ( ...isEnabled ) => (\n\t\t\tisEnabled.some( isCommandEnabled => isCommandEnabled )\n\t\t) );\n\n\t\treturn imageInsertUrlView;\n\t}\n\n\t/**\n\t * Shows the insert image via URL form view in a modal.\n\t */\n\tprivate _showModal() {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst t = locale.t;\n\t\tconst dialog = editor.plugins.get( 'Dialog' );\n\n\t\tif ( !this._formView ) {\n\t\t\tthis._formView = this._createInsertUrlView();\n\t\t\tthis._formView.on( 'submit', () => this._handleSave() );\n\t\t}\n\n\t\tconst replaceImageSourceCommand = editor.commands.get( 'replaceImageSource' )!;\n\t\tthis._formView.imageURLInputValue = replaceImageSourceCommand.value || '';\n\n\t\tdialog.show( {\n\t\t\tid: 'insertImageViaUrl',\n\t\t\ttitle: this._imageInsertUI.isImageSelected ?\n\t\t\t\tt( 'Update image URL' ) :\n\t\t\t\tt( 'Insert image via URL' ),\n\t\t\tisModal: true,\n\t\t\tcontent: this._formView,\n\t\t\tactionButtons: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Cancel' ),\n\t\t\t\t\twithText: true,\n\t\t\t\t\tonExecute: () => dialog.hide()\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Accept' ),\n\t\t\t\t\tclass: 'ck-button-action',\n\t\t\t\t\twithText: true,\n\t\t\t\t\tonExecute: () => this._handleSave()\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Executes appropriate command depending on selection and form value.\n\t */\n\tprivate _handleSave() {\n\t\tconst replaceImageSourceCommand = this.editor.commands.get( 'replaceImageSource' )!;\n\n\t\t// If an image element is currently selected, we want to replace its source attribute (instead of inserting a new image).\n\t\t// We detect if an image is selected by checking `replaceImageSource` command state.\n\t\tif ( replaceImageSourceCommand.isEnabled ) {\n\t\t\tthis.editor.execute( 'replaceImageSource', { source: this._formView!.imageURLInputValue } );\n\t\t} else {\n\t\t\tthis.editor.execute( 'insertImage', { source: this._formView!.imageURLInputValue } );\n\t\t}\n\n\t\tthis.editor.plugins.get( 'Dialog' ).hide();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageinsertviaurl\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageInsertUI from './imageinsert/imageinsertui.js';\nimport ImageInsertViaUrlUI from './imageinsert/imageinsertviaurlui.js';\n\n/**\n * The image insert via URL plugin.\n *\n * For a detailed overview, check the {@glink features/images/images-inserting\n * Insert images via source URL} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins\n * to enable image inserting via implemented integrations:\n *\n * * {@link module:image/imageinsert/imageinsertui~ImageInsertUI},\n */\nexport default class ImageInsertViaUrl extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageInsertViaUrl' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageInsertViaUrlUI, ImageInsertUI ] as const;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageinsert\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageUpload from './imageupload.js';\nimport ImageInsertViaUrl from './imageinsertviaurl.js';\nimport ImageInsertUI from './imageinsert/imageinsertui.js';\n\n/**\n * The image insert plugin.\n *\n * For a detailed overview, check the {@glink features/images/image-upload/image-upload Image upload feature}\n * and {@glink features/images/images-inserting Insert images via source URL} documentation.\n *\n * This plugin does not do anything directly, but it loads a set of specific plugins\n * to enable image uploading or inserting via implemented integrations:\n *\n * * {@link module:image/imageupload~ImageUpload}\n * * {@link module:image/imageinsert/imageinsertui~ImageInsertUI}\n */\nexport default class ImageInsert extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageInsert' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUpload, ImageInsertViaUrl, ImageInsertUI ] as const;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/resizeimagecommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * The resize image command. Currently, it only supports the width attribute.\n */\nexport default class ResizeImageCommand extends Command {\n\t/**\n\t * Desired image width and height.\n\t */\n\tdeclare public value: null | {\n\t\twidth: string | null;\n\t\theight: string | null;\n\t};\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst element = imageUtils.getClosestSelectedImageElement( editor.model.document.selection );\n\n\t\tthis.isEnabled = !!element;\n\n\t\tif ( !element || !element.hasAttribute( 'resizedWidth' ) ) {\n\t\t\tthis.value = null;\n\t\t} else {\n\t\t\tthis.value = {\n\t\t\t\twidth: element.getAttribute( 'resizedWidth' ) as string,\n\t\t\t\theight: null\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * ```ts\n\t * // Sets the width to 50%:\n\t * editor.execute( 'resizeImage', { width: '50%' } );\n\t *\n\t * // Removes the width attribute:\n\t * editor.execute( 'resizeImage', { width: null } );\n\t * ```\n\t *\n\t * @param options\n\t * @param options.width The new width of the image.\n\t * @fires execute\n\t */\n\tpublic override execute( options: { width: string | null } ): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst imageElement = imageUtils.getClosestSelectedImageElement( model.document.selection );\n\n\t\tthis.value = {\n\t\t\twidth: options.width,\n\t\t\theight: null\n\t\t};\n\n\t\tif ( imageElement ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setAttribute( 'resizedWidth', options.width, imageElement );\n\t\t\t\twriter.removeAttribute( 'resizedHeight', imageElement );\n\t\t\t\timageUtils.setImageNaturalSizeAttributes( imageElement );\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/imageresizeediting\n */\n\nimport type { ViewElement } from 'ckeditor5/src/engine.js';\nimport { type Editor, Plugin } from 'ckeditor5/src/core.js';\nimport ImageUtils from '../imageutils.js';\nimport ResizeImageCommand from './resizeimagecommand.js';\nimport { widthAndHeightStylesAreBothSet } from '../image/utils.js';\n\n/**\n * The image resize editing feature.\n *\n * It adds the ability to resize each image using handles or manually by\n * {@link module:image/imageresize/imageresizebuttons~ImageResizeButtons} buttons.\n */\nexport default class ImageResizeEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageResizeEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'image', {\n\t\t\tresizeUnit: '%',\n\t\t\tresizeOptions: [\n\t\t\t\t{\n\t\t\t\t\tname: 'resizeImage:original',\n\t\t\t\t\tvalue: null,\n\t\t\t\t\ticon: 'original'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'resizeImage:custom',\n\t\t\t\t\tvalue: 'custom',\n\t\t\t\t\ticon: 'custom'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'resizeImage:25',\n\t\t\t\t\tvalue: '25',\n\t\t\t\t\ticon: 'small'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'resizeImage:50',\n\t\t\t\t\tvalue: '50',\n\t\t\t\t\ticon: 'medium'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'resizeImage:75',\n\t\t\t\t\tvalue: '75',\n\t\t\t\t\ticon: 'large'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst resizeImageCommand = new ResizeImageCommand( editor );\n\n\t\tthis._registerConverters( 'imageBlock' );\n\t\tthis._registerConverters( 'imageInline' );\n\n\t\t// Register `resizeImage` command and add `imageResize` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'resizeImage', resizeImageCommand );\n\t\teditor.commands.add( 'imageResize', resizeImageCommand );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tthis._registerSchema();\n\t}\n\n\tprivate _registerSchema(): void {\n\t\tif ( this.editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\tthis.editor.model.schema.extend( 'imageBlock', { allowAttributes: [ 'resizedWidth', 'resizedHeight' ] } );\n\t\t}\n\n\t\tif ( this.editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\tthis.editor.model.schema.extend( 'imageInline', { allowAttributes: [ 'resizedWidth', 'resizedHeight' ] } );\n\t\t}\n\t}\n\n\t/**\n\t * Registers image resize converters.\n\t *\n\t * @param imageType The type of the image.\n\t */\n\tprivate _registerConverters( imageType: 'imageBlock' | 'imageInline' ) {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\t// Dedicated converter to propagate image's attribute to the img tag.\n\t\teditor.conversion.for( 'downcast' ).add( dispatcher =>\n\t\t\tdispatcher.on( `attribute:resizedWidth:${ imageType }`, ( evt, data, conversionApi ) => {\n\t\t\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst viewImg = conversionApi.mapper.toViewElement( data.item );\n\n\t\t\t\tif ( data.attributeNewValue !== null ) {\n\t\t\t\t\tviewWriter.setStyle( 'width', data.attributeNewValue, viewImg );\n\t\t\t\t\tviewWriter.addClass( 'image_resized', viewImg );\n\t\t\t\t} else {\n\t\t\t\t\tviewWriter.removeStyle( 'width', viewImg );\n\t\t\t\t\tviewWriter.removeClass( 'image_resized', viewImg );\n\t\t\t\t}\n\t\t\t} )\n\t\t);\n\n\t\teditor.conversion.for( 'dataDowncast' ).attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: imageType,\n\t\t\t\tkey: 'resizedHeight'\n\t\t\t},\n\t\t\tview: modelAttributeValue => ( {\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\t'height': modelAttributeValue\n\t\t\t\t}\n\t\t\t} )\n\t\t} );\n\n\t\teditor.conversion.for( 'editingDowncast' ).add( dispatcher =>\n\t\t\tdispatcher.on( `attribute:resizedHeight:${ imageType }`, ( evt, data, conversionApi ) => {\n\t\t\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst viewImg = conversionApi.mapper.toViewElement( data.item );\n\t\t\t\tconst target = imageType === 'imageInline' ? imageUtils.findViewImgElement( viewImg ) : viewImg;\n\n\t\t\t\tif ( data.attributeNewValue !== null ) {\n\t\t\t\t\tviewWriter.setStyle( 'height', data.attributeNewValue, target );\n\t\t\t\t} else {\n\t\t\t\t\tviewWriter.removeStyle( 'height', target );\n\t\t\t\t}\n\t\t\t} )\n\t\t);\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: imageType === 'imageBlock' ? 'figure' : 'img',\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\twidth: /.+/\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: 'resizedWidth',\n\t\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\t\tif ( widthAndHeightStylesAreBothSet( viewElement ) ) {\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn viewElement.getStyle( 'width' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.attributeToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: imageType === 'imageBlock' ? 'figure' : 'img',\n\t\t\t\t\tstyles: {\n\t\t\t\t\t\theight: /.+/\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: 'resizedHeight',\n\t\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\t\tif ( widthAndHeightStylesAreBothSet( viewElement ) ) {\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn viewElement.getStyle( 'height' );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/imageresizebuttons\n */\nimport { map } from 'lodash-es';\n\nimport { Plugin, icons, type Editor } from 'ckeditor5/src/core.js';\nimport {\n\tButtonView,\n\tDropdownButtonView,\n\tViewModel,\n\tcreateDropdown,\n\taddListToDropdown,\n\ttype ListDropdownItemDefinition\n} from 'ckeditor5/src/ui.js';\nimport { CKEditorError, Collection, type Locale } from 'ckeditor5/src/utils.js';\n\nimport ImageResizeEditing from './imageresizeediting.js';\n\nimport type ResizeImageCommand from './resizeimagecommand.js';\nimport type { ImageResizeOption } from '../imageconfig.js';\n\nconst RESIZE_ICONS = /* #__PURE__ */ ( () => ( {\n\tsmall: icons.objectSizeSmall,\n\tmedium: icons.objectSizeMedium,\n\tlarge: icons.objectSizeLarge,\n\tcustom: icons.objectSizeCustom,\n\toriginal: icons.objectSizeFull\n} ) )();\n\n/**\n * The image resize buttons plugin.\n *\n * It adds a possibility to resize images using the toolbar dropdown or individual buttons, depending on the plugin configuration.\n */\nexport default class ImageResizeButtons extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageResizeEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageResizeButtons' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * The resize unit.\n\t * @default '%'\n\t */\n\tprivate readonly _resizeUnit: 'px' | '%';\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._resizeUnit = editor.config.get( 'image.resizeUnit' )!;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst options = editor.config.get( 'image.resizeOptions' )!;\n\t\tconst command: ResizeImageCommand = editor.commands.get( 'resizeImage' )!;\n\n\t\tthis.bind( 'isEnabled' ).to( command );\n\n\t\tfor ( const option of options ) {\n\t\t\tthis._registerImageResizeButton( option );\n\t\t}\n\n\t\tthis._registerImageResizeDropdown( options );\n\t}\n\n\t/**\n\t * A helper function that creates a standalone button component for the plugin.\n\t *\n\t * @param resizeOption A model of the resize option.\n\t */\n\tprivate _registerImageResizeButton( option: ImageResizeOption ): void {\n\t\tconst editor = this.editor;\n\t\tconst { name, value, icon } = option;\n\n\t\teditor.ui.componentFactory.add( name, locale => {\n\t\t\tconst button = new ButtonView( locale );\n\t\t\tconst command: ResizeImageCommand = editor.commands.get( 'resizeImage' )!;\n\t\t\tconst labelText = this._getOptionLabelValue( option, true );\n\n\t\t\tif ( !RESIZE_ICONS[ icon as keyof typeof RESIZE_ICONS ] ) {\n\t\t\t\t/**\n\t\t\t\t * When configuring {@link module:image/imageconfig~ImageConfig#resizeOptions `config.image.resizeOptions`} for standalone\n\t\t\t\t * buttons, a valid `icon` token must be set for each option.\n\t\t\t\t *\n\t\t\t\t * See all valid options described in the\n\t\t\t\t * {@link module:image/imageconfig~ImageResizeOption plugin configuration}.\n\t\t\t\t *\n\t\t\t\t * @error imageresizebuttons-missing-icon\n\t\t\t\t * @param option Invalid image resize option.\n\t\t\t\t*/\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'imageresizebuttons-missing-icon',\n\t\t\t\t\teditor,\n\t\t\t\t\toption\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tbutton.set( {\n\t\t\t\t// Use the `label` property for a verbose description (because of ARIA).\n\t\t\t\tlabel: labelText,\n\t\t\t\ticon: RESIZE_ICONS[ icon as keyof typeof RESIZE_ICONS ],\n\t\t\t\ttooltip: labelText,\n\t\t\t\tisToggleable: true\n\t\t\t} );\n\n\t\t\t// Bind button to the command.\n\t\t\tbutton.bind( 'isEnabled' ).to( this );\n\n\t\t\tif ( editor.plugins.has( 'ImageCustomResizeUI' ) && isCustomImageResizeOption( option ) ) {\n\t\t\t\tconst customResizeUI = editor.plugins.get( 'ImageCustomResizeUI' );\n\n\t\t\t\tthis.listenTo( button, 'execute', () => {\n\t\t\t\t\tcustomResizeUI._showForm( this._resizeUnit );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\tconst optionValueWithUnit = value ? value + this._resizeUnit : null;\n\n\t\t\t\tbutton.bind( 'isOn' ).to( command, 'value', getIsOnButtonCallback( optionValueWithUnit ) );\n\n\t\t\t\tthis.listenTo( button, 'execute', () => {\n\t\t\t\t\teditor.execute( 'resizeImage', { width: optionValueWithUnit } );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn button;\n\t\t} );\n\t}\n\n\t/**\n\t * A helper function that creates a dropdown component for the plugin containing all the resize options defined in\n\t * the editor configuration.\n\t *\n\t * @param options An array of configured options.\n\t */\n\tprivate _registerImageResizeDropdown( options: Array<ImageResizeOption> ): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst originalSizeOption = options.find( option => !option.value )!;\n\n\t\tconst componentCreator = ( locale: Locale ) => {\n\t\t\tconst command: ResizeImageCommand = editor.commands.get( 'resizeImage' )!;\n\t\t\tconst dropdownView = createDropdown( locale, DropdownButtonView );\n\t\t\tconst dropdownButton: typeof dropdownView.buttonView & { commandValue?: string | null } = dropdownView.buttonView;\n\t\t\tconst accessibleLabel = t( 'Resize image' );\n\n\t\t\tdropdownButton.set( {\n\t\t\t\ttooltip: accessibleLabel,\n\t\t\t\tcommandValue: originalSizeOption.value,\n\t\t\t\ticon: RESIZE_ICONS.medium,\n\t\t\t\tisToggleable: true,\n\t\t\t\tlabel: this._getOptionLabelValue( originalSizeOption ),\n\t\t\t\twithText: true,\n\t\t\t\tclass: 'ck-resize-image-button',\n\t\t\t\tariaLabel: accessibleLabel,\n\t\t\t\tariaLabelledBy: undefined\n\t\t\t} );\n\n\t\t\tdropdownButton.bind( 'label' ).to( command, 'value', commandValue => {\n\t\t\t\tif ( commandValue && commandValue.width ) {\n\t\t\t\t\treturn commandValue.width;\n\t\t\t\t} else {\n\t\t\t\t\treturn this._getOptionLabelValue( originalSizeOption );\n\t\t\t\t}\n\t\t\t} );\n\t\t\tdropdownView.bind( 'isEnabled' ).to( this );\n\n\t\t\taddListToDropdown( dropdownView, () => this._getResizeDropdownListItemDefinitions( options, command ), {\n\t\t\t\tariaLabel: t( 'Image resize list' ),\n\t\t\t\trole: 'menu'\n\t\t\t} );\n\n\t\t\t// Execute command when an item from the dropdown is selected.\n\t\t\tthis.listenTo( dropdownView, 'execute', evt => {\n\t\t\t\tif ( 'onClick' in evt.source ) {\n\t\t\t\t\t( evt.source as any ).onClick();\n\t\t\t\t} else {\n\t\t\t\t\teditor.execute( ( evt.source as any ).commandName, { width: ( evt.source as any ).commandValue } );\n\t\t\t\t\teditor.editing.view.focus();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn dropdownView;\n\t\t};\n\n\t\t// Register `resizeImage` dropdown and add `imageResize` dropdown as an alias for backward compatibility.\n\t\teditor.ui.componentFactory.add( 'resizeImage', componentCreator );\n\t\teditor.ui.componentFactory.add( 'imageResize', componentCreator );\n\t}\n\n\t/**\n\t * A helper function for creating an option label value string.\n\t *\n\t * @param option A resize option object.\n\t * @param forTooltip An optional flag for creating a tooltip label.\n\t * @returns A user-defined label combined from the numeric value and the resize unit or the default label\n\t * for reset options (`Original`).\n\t */\n\tprivate _getOptionLabelValue( option: ImageResizeOption, forTooltip: boolean = false ): string {\n\t\tconst t = this.editor.t;\n\n\t\tif ( option.label ) {\n\t\t\treturn option.label;\n\t\t} else if ( forTooltip ) {\n\t\t\tif ( isCustomImageResizeOption( option ) ) {\n\t\t\t\treturn t( 'Custom image size' );\n\t\t\t} else if ( option.value ) {\n\t\t\t\treturn t( 'Resize image to %0', option.value + this._resizeUnit );\n\t\t\t} else {\n\t\t\t\treturn t( 'Resize image to the original size' );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( isCustomImageResizeOption( option ) ) {\n\t\t\t\treturn t( 'Custom' );\n\t\t\t} else if ( option.value ) {\n\t\t\t\treturn option.value + this._resizeUnit;\n\t\t\t} else {\n\t\t\t\treturn t( 'Original' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A helper function that parses the resize options and returns list item definitions ready for use in the dropdown.\n\t *\n\t * @param options The resize options.\n\t * @param command The resize image command.\n\t * @returns Dropdown item definitions.\n\t */\n\tprivate _getResizeDropdownListItemDefinitions(\n\t\toptions: Array<ImageResizeOption>,\n\t\tcommand: ResizeImageCommand\n\t): Collection<ListDropdownItemDefinition> {\n\t\tconst { editor } = this;\n\t\tconst itemDefinitions = new Collection<ListDropdownItemDefinition>();\n\n\t\tconst optionsWithSerializedValues = options.map( option => {\n\t\t\tif ( isCustomImageResizeOption( option ) ) {\n\t\t\t\treturn {\n\t\t\t\t\t...option,\n\t\t\t\t\tvalueWithUnits: 'custom'\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif ( !option.value ) {\n\t\t\t\treturn {\n\t\t\t\t\t...option,\n\t\t\t\t\tvalueWithUnits: null\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...option,\n\t\t\t\tvalueWithUnits: `${ option.value }${ this._resizeUnit }`\n\t\t\t};\n\t\t} );\n\n\t\tfor ( const option of optionsWithSerializedValues ) {\n\t\t\tlet definition: ListDropdownItemDefinition | null = null;\n\n\t\t\tif ( editor.plugins.has( 'ImageCustomResizeUI' ) && isCustomImageResizeOption( option ) ) {\n\t\t\t\tconst customResizeUI = editor.plugins.get( 'ImageCustomResizeUI' );\n\n\t\t\t\tdefinition = {\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: new ViewModel( {\n\t\t\t\t\t\tlabel: this._getOptionLabelValue( option ),\n\t\t\t\t\t\trole: 'menuitemradio',\n\t\t\t\t\t\twithText: true,\n\t\t\t\t\t\ticon: null,\n\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\tcustomResizeUI._showForm( this._resizeUnit );\n\t\t\t\t\t\t}\n\t\t\t\t\t} )\n\t\t\t\t};\n\n\t\t\t\tconst allDropdownValues = map( optionsWithSerializedValues, 'valueWithUnits' );\n\n\t\t\t\tdefinition.model.bind( 'isOn' ).to( command, 'value', getIsOnCustomButtonCallback( allDropdownValues ) );\n\t\t\t} else {\n\t\t\t\tdefinition = {\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: new ViewModel( {\n\t\t\t\t\t\tcommandName: 'resizeImage',\n\t\t\t\t\t\tcommandValue: option.valueWithUnits,\n\t\t\t\t\t\tlabel: this._getOptionLabelValue( option ),\n\t\t\t\t\t\trole: 'menuitemradio',\n\t\t\t\t\t\twithText: true,\n\t\t\t\t\t\ticon: null\n\t\t\t\t\t} )\n\t\t\t\t};\n\n\t\t\t\tdefinition.model.bind( 'isOn' ).to( command, 'value', getIsOnButtonCallback( option.valueWithUnits ) );\n\t\t\t}\n\n\t\t\tdefinition.model.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t\t\titemDefinitions.add( definition );\n\t\t}\n\n\t\treturn itemDefinitions;\n\t}\n}\n\n/**\n * A helper that checks if provided option triggers custom resize balloon.\n */\nfunction isCustomImageResizeOption( option: ImageResizeOption ) {\n\treturn option.value === 'custom';\n}\n\n/**\n * A helper function for setting the `isOn` state of buttons in value bindings.\n */\nfunction getIsOnButtonCallback( value: string | null ): ( commandValue: unknown ) => boolean {\n\treturn ( commandValue: unknown ): boolean => {\n\t\tconst objectCommandValue = commandValue as null | { width: string | null };\n\t\tif ( value === null && objectCommandValue === value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn objectCommandValue !== null && objectCommandValue.width === value;\n\t};\n}\n\n/**\n * A helper function for setting the `isOn` state of custom size button in value bindings.\n */\nfunction getIsOnCustomButtonCallback( allDropdownValues: Array<string | null> ): ( commandValue: unknown ) => boolean {\n\treturn ( commandValue: unknown ): boolean => !allDropdownValues.some(\n\t\tdropdownValue => getIsOnButtonCallback( dropdownValue )( commandValue )\n\t);\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/imageresizehandles\n */\n\nimport type { Element, ViewElement } from 'ckeditor5/src/engine.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { WidgetResize } from 'ckeditor5/src/widget.js';\nimport ImageUtils from '../imageutils.js';\n\nimport ImageLoadObserver, { type ImageLoadedEvent } from '../image/imageloadobserver.js';\nimport type ResizeImageCommand from './resizeimagecommand.js';\n\nconst RESIZABLE_IMAGES_CSS_SELECTOR =\n\t'figure.image.ck-widget > img,' +\n\t'figure.image.ck-widget > picture > img,' +\n\t'figure.image.ck-widget > a > img,' +\n\t'figure.image.ck-widget > a > picture > img,' +\n\t'span.image-inline.ck-widget > img,' +\n\t'span.image-inline.ck-widget > picture > img';\n\nconst RESIZED_IMAGE_CLASS = 'image_resized';\n\n/**\n * The image resize by handles feature.\n *\n * It adds the ability to resize each image using handles or manually by\n * {@link module:image/imageresize/imageresizebuttons~ImageResizeButtons} buttons.\n */\nexport default class ImageResizeHandles extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ WidgetResize, ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageResizeHandles' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst command: ResizeImageCommand = this.editor.commands.get( 'resizeImage' )!;\n\t\tthis.bind( 'isEnabled' ).to( command );\n\n\t\tthis._setupResizerCreator();\n\t}\n\n\t/**\n\t * Attaches the listeners responsible for creating a resizer for each image, except for images inside the HTML embed preview.\n\t */\n\tprivate _setupResizerCreator(): void {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\teditingView.addObserver( ImageLoadObserver );\n\n\t\tthis.listenTo<ImageLoadedEvent>( editingView.document, 'imageLoaded', ( evt, domEvent ) => {\n\t\t\t// The resizer must be attached only to images loaded by the `ImageInsert`, `ImageUpload` or `LinkImage` plugins.\n\t\t\tif ( !( domEvent.target as HTMLElement ).matches( RESIZABLE_IMAGES_CSS_SELECTOR ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst domConverter = editor.editing.view.domConverter;\n\t\t\tconst imageView = domConverter.domToView( domEvent.target as HTMLElement ) as ViewElement;\n\t\t\tconst widgetView = imageUtils.getImageWidgetFromImageView( imageView )!;\n\t\t\tlet resizer = this.editor.plugins.get( WidgetResize ).getResizerByViewElement( widgetView );\n\n\t\t\tif ( resizer ) {\n\t\t\t\t// There are rare cases when the image will be triggered multiple times for the same widget, e.g. when\n\t\t\t\t// the image's source was changed after upload (https://github.com/ckeditor/ckeditor5/pull/8108#issuecomment-708302992).\n\t\t\t\tresizer.redraw();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst mapper = editor.editing.mapper;\n\t\t\tconst imageModel = mapper.toModelElement( widgetView )!;\n\n\t\t\tresizer = editor.plugins\n\t\t\t\t.get( WidgetResize )\n\t\t\t\t.attachTo( {\n\t\t\t\t\tunit: editor.config.get( 'image.resizeUnit' )!,\n\n\t\t\t\t\tmodelElement: imageModel,\n\t\t\t\t\tviewElement: widgetView,\n\t\t\t\t\teditor,\n\n\t\t\t\t\tgetHandleHost( domWidgetElement ) {\n\t\t\t\t\t\treturn domWidgetElement.querySelector( 'img' )!;\n\t\t\t\t\t},\n\t\t\t\t\tgetResizeHost() {\n\t\t\t\t\t\treturn domConverter.mapViewToDom( mapper.toViewElement( imageModel as Element )! ) as HTMLElement;\n\t\t\t\t\t},\n\n\t\t\t\t\tisCentered() {\n\t\t\t\t\t\tconst imageStyle = imageModel.getAttribute( 'imageStyle' );\n\n\t\t\t\t\t\treturn imageStyle == 'alignCenter';\n\t\t\t\t\t},\n\n\t\t\t\t\tonCommit( newValue ) {\n\t\t\t\t\t\t// Get rid of the CSS class in case the command execution that follows is unsuccessful\n\t\t\t\t\t\t// (e.g. Track Changes can override it and the new dimensions will not apply). Otherwise,\n\t\t\t\t\t\t// the presence of the class and the absence of the width style will cause it to take 100%\n\t\t\t\t\t\t// of the horizontal space.\n\t\t\t\t\t\teditingView.change( writer => {\n\t\t\t\t\t\t\twriter.removeClass( RESIZED_IMAGE_CLASS, widgetView );\n\t\t\t\t\t\t} );\n\n\t\t\t\t\t\teditor.execute( 'resizeImage', { width: newValue } );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\tresizer.on( 'updateSize', () => {\n\t\t\t\tif ( !widgetView.hasClass( RESIZED_IMAGE_CLASS ) ) {\n\t\t\t\t\teditingView.change( writer => {\n\t\t\t\t\t\twriter.addClass( RESIZED_IMAGE_CLASS, widgetView );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tconst target = imageModel.name === 'imageInline' ? imageView : widgetView;\n\n\t\t\t\tif ( target.getStyle( 'height' ) ) {\n\t\t\t\t\teditingView.change( writer => {\n\t\t\t\t\t\twriter.removeStyle( 'height', target );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tresizer.bind( 'isEnabled' ).to( this );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/utils/tryparsedimensionwithunit\n */\n\n/**\n * Parses provided string with dimension value and returns extracted numeric value and unit.\n *\n * \t* If non-string dimension is passed then `null` value is returned.\n * \t* If unit is missing then `null` is returned.\n * \t* If numeric value part of string is not a number then `null` is returned.\n *\n * Example:\n * \t`\"222px\"` => `{ value: 222, unit: \"px\" }`\n *\t`\"99%\"` => `{ value: 99, unit: \"%\" }`\n\n * @param dimension Unsafe string with dimension.\n * @returns Parsed dimension with extracted numeric value and units.\n */\nexport function tryParseDimensionWithUnit( dimension: string | null | undefined ): DimensionWithUnit | null {\n\tif ( !dimension ) {\n\t\treturn null;\n\t}\n\n\tconst [ , rawValue, unit ] = dimension.trim().match( /([.,\\d]+)(%|px)$/ ) || [];\n\tconst parsedValue = Number.parseFloat( rawValue );\n\n\tif ( Number.isNaN( parsedValue ) ) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tvalue: parsedValue,\n\t\tunit\n\t};\n}\n\n/**\n * Converts dimension between `px` -> `%` and `%` -> `px`.\n *\n * @param parentDimensionPx\tDimension of parent element that contains measured element.\n * @param dimension Measured element dimension.\n * @returns Casted dimension.\n */\nexport function tryCastDimensionsToUnit( parentDimensionPx: number, dimension: DimensionWithUnit, targetUnit: string ): DimensionWithUnit {\n\t// \"%\" -> \"px\" conversion\n\tif ( targetUnit === 'px' ) {\n\t\treturn {\n\t\t\tvalue: dimension.value,\n\t\t\tunit: 'px'\n\t\t};\n\t}\n\n\t// \"px\" -> \"%\" conversion\n\treturn {\n\t\tvalue: dimension.value / parentDimensionPx * 100,\n\t\tunit: '%'\n\t};\n}\n\n/**\n * @internal\n */\nexport type DimensionWithUnit = {\n\tvalue: number;\n\tunit: string;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/utils/getselectedimageeditornodes\n */\n\nimport type { ViewElement, Element } from 'ckeditor5/src/engine.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\n/**\n * Finds model, view and DOM element for selected image element. Returns `null` if there is no image selected.\n *\n * @param editor Editor instance.\n */\nexport function getSelectedImageEditorNodes( editor: Editor ): ImageEditorNodes | null {\n\tconst { editing } = editor;\n\n\tconst imageUtils = editor.plugins.get( 'ImageUtils' );\n\tconst imageModelElement = imageUtils.getClosestSelectedImageElement( editor.model.document.selection );\n\n\tif ( !imageModelElement ) {\n\t\treturn null;\n\t}\n\n\tconst imageViewElement = editing.mapper.toViewElement( imageModelElement )!;\n\tconst imageDOMElement = editing.view.domConverter.mapViewToDom( imageViewElement )!;\n\n\treturn {\n\t\tmodel: imageModelElement,\n\t\tview: imageViewElement,\n\t\tdom: imageDOMElement\n\t};\n}\n\n/**\n * @internal;\n */\ntype ImageEditorNodes = {\n\tmodel: Element;\n\tview: ViewElement;\n\tdom: HTMLElement;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/utils/getselectedimagewidthinunits\n */\n\nimport { Rect } from 'ckeditor5/src/utils.js';\n\nimport { calculateResizeHostAncestorWidth } from 'ckeditor5/src/widget.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport { tryCastDimensionsToUnit, tryParseDimensionWithUnit, type DimensionWithUnit } from './tryparsedimensionwithunit.js';\nimport { getSelectedImageEditorNodes } from './getselectedimageeditornodes.js';\n\n/**\n * Returns image width in specified units. It is width of image after resize.\n *\n * \t* If image is not selected or command is disabled then `null` will be returned.\n * \t* If image is not fully loaded (and it is impossible to determine its natural size) then `null` will be returned.\n *\t* If `targetUnit` percentage is passed then it will return width percentage of image related to its accessors.\n *\n * @param editor Editor instance.\n * @param targetUnit Unit in which dimension will be returned.\n * @returns Parsed image width after resize (with unit).\n */\nexport function getSelectedImageWidthInUnits( editor: Editor, targetUnit: string ): DimensionWithUnit | null {\n\tconst imageNodes = getSelectedImageEditorNodes( editor );\n\n\tif ( !imageNodes ) {\n\t\treturn null;\n\t}\n\n\tconst parsedResizedWidth = tryParseDimensionWithUnit(\n\t\timageNodes.model.getAttribute( 'resizedWidth' ) as string || null\n\t);\n\n\tif ( !parsedResizedWidth ) {\n\t\treturn null;\n\t}\n\n\tif ( parsedResizedWidth.unit === targetUnit ) {\n\t\treturn parsedResizedWidth;\n\t}\n\n\tconst imageParentWidthPx = calculateResizeHostAncestorWidth( imageNodes.dom );\n\tconst imageHolderDimension = {\n\t\tunit: 'px',\n\t\tvalue: new Rect( imageNodes.dom ).width\n\t};\n\n\treturn tryCastDimensionsToUnit( imageParentWidthPx, imageHolderDimension, targetUnit );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/ui/imagecustomresizeformview\n */\n\nimport {\n\tButtonView,\n\tFocusCycler,\n\tLabeledFieldView,\n\tView,\n\tViewCollection,\n\tcreateLabeledInputNumber,\n\tsubmitHandler,\n\ttype FocusableView,\n\ttype InputNumberView\n} from 'ckeditor5/src/ui.js';\n\nimport { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';\nimport { icons } from 'ckeditor5/src/core.js';\n\nimport '../../../theme/imagecustomresizeform.css';\n\n// See: #8833.\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';\n\n/**\n * The ImageCustomResizeFormView class.\n */\nexport default class ImageCustomResizeFormView extends View {\n\t/**\n\t * Tracks information about the DOM focus in the form.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Resize unit shortcut.\n\t */\n\tpublic readonly unit: string;\n\n\t/**\n\t * An input with a label.\n\t */\n\tpublic labeledInput: LabeledFieldView<InputNumberView>;\n\n\t/**\n\t * A button used to submit the form.\n\t */\n\tpublic saveButtonView: ButtonView;\n\n\t/**\n\t * A button used to cancel the form.\n\t */\n\tpublic cancelButtonView: ButtonView;\n\n\t/**\n\t * A collection of views which can be focused in the form.\n\t */\n\tprotected readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */\n\tprotected readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * An array of form validators used by {@link #isValid}.\n\t */\n\tprivate readonly _validators: Array<ImageCustomResizeFormValidatorCallback>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale, unit: string, validators: Array<ImageCustomResizeFormValidatorCallback> ) {\n\t\tsuper( locale );\n\t\tconst t = this.locale!.t;\n\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.unit = unit;\n\n\t\tthis.labeledInput = this._createLabeledInputView();\n\n\t\tthis.saveButtonView = this._createButton( t( 'Save' ), icons.check, 'ck-button-save' );\n\t\tthis.saveButtonView.type = 'submit';\n\n\t\tthis.cancelButtonView = this._createButton( t( 'Cancel' ), icons.cancel, 'ck-button-cancel', 'cancel' );\n\n\t\tthis._focusables = new ViewCollection();\n\t\tthis._validators = validators;\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-image-custom-resize-form',\n\t\t\t\t\t'ck-responsive-form'\n\t\t\t\t],\n\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-image/issues/40\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.labeledInput,\n\t\t\t\tthis.saveButtonView,\n\t\t\t\tthis.cancelButtonView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.keystrokes.listenTo( this.element! );\n\n\t\tsubmitHandler( { view: this } );\n\n\t\t[ this.labeledInput, this.saveButtonView, this.cancelButtonView ]\n\t\t\t.forEach( v => {\n\t\t\t\t// Register the view as focusable.\n\t\t\t\tthis._focusables.add( v );\n\n\t\t\t\t// Register the view in the focus tracker.\n\t\t\t\tthis.focusTracker.add( v.element! );\n\t\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Creates the button view.\n\t *\n\t * @param label The button label\n\t * @param icon The button's icon.\n\t * @param className The additional button CSS class name.\n\t * @param eventName The event name that the ButtonView#execute event will be delegated to.\n\t * @returns The button view instance.\n\t */\n\tprivate _createButton( label: string, icon: string, className: string, eventName?: string ): ButtonView {\n\t\tconst button = new ButtonView( this.locale );\n\n\t\tbutton.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\tbutton.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: className\n\t\t\t}\n\t\t} );\n\n\t\tif ( eventName ) {\n\t\t\tbutton.delegate( 'execute' ).to( this, eventName );\n\t\t}\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates an input with a label.\n\t *\n\t * @returns Labeled field view instance.\n\t */\n\tprivate _createLabeledInputView(): LabeledFieldView<InputNumberView> {\n\t\tconst t = this.locale!.t;\n\t\tconst labeledInput = new LabeledFieldView<InputNumberView>( this.locale, createLabeledInputNumber );\n\n\t\tlabeledInput.label = t( 'Resize image (in %0)', this.unit );\n\t\tlabeledInput.fieldView.set( {\n\t\t\tstep: 0.1\n\t\t} );\n\n\t\treturn labeledInput;\n\t}\n\n\t/**\n\t * Validates the form and returns `false` when some fields are invalid.\n\t */\n\tpublic isValid(): boolean {\n\t\tthis.resetFormStatus();\n\n\t\tfor ( const validator of this._validators ) {\n\t\t\tconst errorText = validator( this );\n\n\t\t\t// One error per field is enough.\n\t\t\tif ( errorText ) {\n\t\t\t\t// Apply updated error.\n\t\t\t\tthis.labeledInput.errorText = errorText;\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Cleans up the supplementary error and information text of the {@link #labeledInput}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */\n\tpublic resetFormStatus(): void {\n\t\tthis.labeledInput.errorText = null;\n\t}\n\n\t/**\n\t * The native DOM `value` of the input element of {@link #labeledInput}.\n\t */\n\tpublic get rawSize(): string | null {\n\t\tconst { element } = this.labeledInput.fieldView;\n\n\t\tif ( !element ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn element.value;\n\t}\n\n\t/**\n\t * Get numeric value of size. Returns `null` if value of size input element in {@link #labeledInput}.is not a number.\n\t */\n\tpublic get parsedSize(): number | null {\n\t\tconst { rawSize } = this;\n\n\t\tif ( rawSize === null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst parsed = Number.parseFloat( rawSize );\n\n\t\tif ( Number.isNaN( parsed ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn parsed;\n\t}\n\n\t/**\n\t * Returns serialized image input size with unit.\n\t * Returns `null` if value of size input element in {@link #labeledInput}.is not a number.\n\t */\n\tpublic get sizeWithUnits(): string | null {\n\t\tconst { parsedSize, unit } = this;\n\n\t\tif ( parsedSize === null ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn `${ parsedSize }${ unit }`;\n\t}\n}\n\n/**\n * Callback used by {@link ~ImageCustomResizeFormView} to check if passed form value is valid.\n *\n * \t* If `undefined` is returned, it is assumed that the form value is correct and there is no error.\n * \t* If string is returned, it is assumed that the form value is incorrect and the returned string is displayed in the error label\n */\nexport type ImageCustomResizeFormValidatorCallback = ( form: ImageCustomResizeFormView ) => string | undefined;\n\n/**\n * Fired when the form view is submitted.\n *\n * @eventName ~ImageCustomResizeFormView#submit\n */\nexport type ImageCustomResizeFormViewSubmitEvent = {\n\tname: 'submit';\n\targs: [];\n};\n\n/**\n * Fired when the form view is canceled.\n *\n * @eventName ~ImageCustomResizeFormView#cancel\n */\nexport type ImageCustomResizeFormViewCancelEvent = {\n\tname: 'cancel';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/utils/getselectedimagepossibleresizerange\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport { calculateResizeHostAncestorWidth } from 'ckeditor5/src/widget.js';\nimport { getSelectedImageEditorNodes } from './getselectedimageeditornodes.js';\nimport { tryCastDimensionsToUnit, tryParseDimensionWithUnit } from './tryparsedimensionwithunit.js';\n\n/**\n * Returns min and max value of resize image in specified unit.\n *\n * @param editor Editor instance.\n * @param targetUnit Unit in which dimension will be returned.\n * @returns Possible resize range in numeric form.\n */\nexport function getSelectedImagePossibleResizeRange( editor: Editor, targetUnit: string ): PossibleResizeImageRange | null {\n\tconst imageNodes = getSelectedImageEditorNodes( editor );\n\n\tif ( !imageNodes ) {\n\t\treturn null;\n\t}\n\n\tconst imageParentWidthPx = calculateResizeHostAncestorWidth( imageNodes.dom );\n\tconst minimumImageWidth = tryParseDimensionWithUnit( window.getComputedStyle( imageNodes.dom ).minWidth ) || {\n\t\tvalue: 1,\n\t\tunit: 'px'\n\t};\n\n\tconst lower = Math.max( 0.1, tryCastDimensionsToUnit( imageParentWidthPx, minimumImageWidth, targetUnit ).value );\n\tconst upper = targetUnit === 'px' ? imageParentWidthPx : 100;\n\n\treturn {\n\t\tunit: targetUnit,\n\t\tlower,\n\t\tupper\n\t};\n}\n\n/**\n * @internal\n */\nexport type PossibleResizeImageRange = {\n\tunit: string;\n\tlower: number;\n\tupper: number;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize/imagecustomresizeui\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport {\n\tContextualBalloon,\n\tclickOutsideHandler,\n\tCssTransitionDisablerMixin,\n\ttype ViewWithCssTransitionDisabler\n} from 'ckeditor5/src/ui.js';\n\nimport { getBalloonPositionData } from '../image/ui/utils.js';\nimport { getSelectedImageWidthInUnits } from './utils/getselectedimagewidthinunits.js';\n\nimport ImageCustomResizeFormView, {\n\ttype ImageCustomResizeFormValidatorCallback,\n\ttype ImageCustomResizeFormViewCancelEvent,\n\ttype ImageCustomResizeFormViewSubmitEvent\n} from './ui/imagecustomresizeformview.js';\nimport { getSelectedImagePossibleResizeRange } from './utils/getselectedimagepossibleresizerange.js';\n\n/**\n * The custom resize image UI plugin.\n *\n * The plugin uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n */\nexport default class ImageCustomResizeUI extends Plugin {\n\t/**\n\t * The contextual balloon plugin instance.\n\t */\n\tprivate _balloon?: ContextualBalloon;\n\n\t/**\n\t * A form containing a textarea and buttons, used to change the `alt` text value.\n\t */\n\tprivate _form?: ImageCustomResizeFormView & ViewWithCssTransitionDisabler;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageCustomResizeUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n\t\tif ( this._form ) {\n\t\t\tthis._form.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Creates the {@link module:image/imageresize/ui/imagecustomresizeformview~ImageCustomResizeFormView}\n\t * form.\n\t */\n\tprivate _createForm( unit: string ): void {\n\t\tconst editor = this.editor;\n\n\t\tthis._balloon = this.editor.plugins.get( 'ContextualBalloon' );\n\n\t\tthis._form = new ( CssTransitionDisablerMixin( ImageCustomResizeFormView ) )( editor.locale, unit, getFormValidators( editor ) );\n\n\t\t// Render the form so its #element is available for clickOutsideHandler.\n\t\tthis._form.render();\n\n\t\tthis.listenTo<ImageCustomResizeFormViewSubmitEvent>( this._form, 'submit', () => {\n\t\t\tif ( this._form!.isValid() ) {\n\t\t\t\teditor.execute( 'resizeImage', {\n\t\t\t\t\twidth: this._form!.sizeWithUnits\n\t\t\t\t} );\n\n\t\t\t\tthis._hideForm( true );\n\t\t\t}\n\t\t} );\n\n\t\t// Update balloon position when form error label is added .\n\t\tthis.listenTo( this._form.labeledInput, 'change:errorText', () => {\n\t\t\teditor.ui.update();\n\t\t} );\n\n\t\tthis.listenTo<ImageCustomResizeFormViewCancelEvent>( this._form, 'cancel', () => {\n\t\t\tthis._hideForm( true );\n\t\t} );\n\n\t\t// Close the form on Esc key press.\n\t\tthis._form.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideForm( true );\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: this._form,\n\t\t\tactivator: () => this._isVisible,\n\t\t\tcontextElements: () => [ this._balloon!.view.element! ],\n\t\t\tcallback: () => this._hideForm()\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the {@link #_form} in the {@link #_balloon}.\n\t *\n\t * @internal\n\t */\n\tpublic _showForm( unit: string ): void {\n\t\tif ( this._isVisible ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this._form ) {\n\t\t\tthis._createForm( unit );\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst labeledInput = this._form!.labeledInput;\n\n\t\tthis._form!.disableCssTransitions();\n\t\tthis._form!.resetFormStatus();\n\n\t\tif ( !this._isInBalloon ) {\n\t\t\tthis._balloon!.add( {\n\t\t\t\tview: this._form!,\n\t\t\t\tposition: getBalloonPositionData( editor )\n\t\t\t} );\n\t\t}\n\n\t\t// Make sure that each time the panel shows up, the field remains in sync with the value of\n\t\t// the command. If the user typed in the input, then canceled the balloon (`labeledInput#value`\n\t\t// stays unaltered) and re-opened it without changing the value of the command, they would see the\n\t\t// old value instead of the actual value of the command.\n\t\tconst currentParsedWidth = getSelectedImageWidthInUnits( editor, unit );\n\t\tconst initialInputValue = currentParsedWidth ? currentParsedWidth.value.toFixed( 1 ) : '';\n\t\tconst possibleRange = getSelectedImagePossibleResizeRange( editor, unit );\n\n\t\tlabeledInput.fieldView.value = labeledInput.fieldView.element!.value = initialInputValue;\n\n\t\tif ( possibleRange ) {\n\t\t\tObject.assign( labeledInput.fieldView, {\n\t\t\t\tmin: possibleRange.lower.toFixed( 1 ),\n\t\t\t\tmax: Math.ceil( possibleRange.upper ).toFixed( 1 )\n\t\t\t} );\n\t\t}\n\n\t\tthis._form!.labeledInput.fieldView.select();\n\t\tthis._form!.enableCssTransitions();\n\t}\n\n\t/**\n\t * Removes the {@link #_form} from the {@link #_balloon}.\n\t *\n\t * @param focusEditable Controls whether the editing view is focused afterwards.\n\t */\n\tprivate _hideForm( focusEditable: boolean = false ): void {\n\t\tif ( !this._isInBalloon ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Blur the input element before removing it from DOM to prevent issues in some browsers.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\tif ( this._form!.focusTracker.isFocused ) {\n\t\t\tthis._form!.saveButtonView.focus();\n\t\t}\n\n\t\tthis._balloon!.remove( this._form! );\n\n\t\tif ( focusEditable ) {\n\t\t\tthis.editor.editing.view.focus();\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #_form} is the visible view in the {@link #_balloon}.\n\t */\n\tprivate get _isVisible(): boolean {\n\t\treturn !!this._balloon && this._balloon.visibleView === this._form;\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #_form} is in the {@link #_balloon}.\n\t */\n\tprivate get _isInBalloon(): boolean {\n\t\treturn !!this._balloon && this._balloon.hasView( this._form! );\n\t}\n}\n\n/**\n * Returns image resize form validation callbacks.\n *\n * @param editor Editor instance.\n */\nfunction getFormValidators( editor: Editor ): Array<ImageCustomResizeFormValidatorCallback> {\n\tconst t = editor.t;\n\n\treturn [\n\t\tform => {\n\t\t\tif ( form.rawSize!.trim() === '' ) {\n\t\t\t\treturn t( 'The value must not be empty.' );\n\t\t\t}\n\n\t\t\tif ( form.parsedSize === null ) {\n\t\t\t\treturn t( 'The value should be a plain number.' );\n\t\t\t}\n\t\t}\n\t];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imageresize\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageResizeButtons from './imageresize/imageresizebuttons.js';\nimport ImageResizeEditing from './imageresize/imageresizeediting.js';\nimport ImageResizeHandles from './imageresize/imageresizehandles.js';\nimport ImageCustomResizeUI from './imageresize/imagecustomresizeui.js';\n\nimport '../theme/imageresize.css';\n\n/**\n * The image resize plugin.\n *\n * It adds a possibility to resize each image using handles.\n */\nexport default class ImageResize extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageResizeEditing, ImageResizeHandles, ImageCustomResizeUI, ImageResizeButtons ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageResize' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagestyle/imagestylecommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { ImageStyleOptionDefinition } from '../imageconfig.js';\nimport type ImageUtils from '../imageutils.js';\n\n/**\n * The image style command. It is used to apply {@link module:image/imageconfig~ImageStyleConfig#options image style option}\n * to a selected image.\n *\n * **Note**: Executing this command may change the image model element if the desired style requires an image of a different\n * type. See {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand#execute} to learn more.\n */\nexport default class ImageStyleCommand extends Command {\n\t/**\n\t * An object containing names of default style options for the inline and block images.\n\t * If there is no default style option for the given image type in the configuration,\n\t * the name will be `false`.\n\t */\n\tprivate _defaultStyles: Record<string, string | false>;\n\n\t/**\n\t * The styles handled by this command.\n\t */\n\tprivate _styles: Map<string, ImageStyleOptionDefinition>;\n\n\t/**\n\t * Creates an instance of the image style command. When executed, the command applies one of\n\t * {@link module:image/imageconfig~ImageStyleConfig#options style options} to the currently selected image.\n\t *\n\t * @param editor The editor instance.\n\t * @param styles The style options that this command supports.\n\t */\n\tconstructor( editor: Editor, styles: Array<ImageStyleOptionDefinition> ) {\n\t\tsuper( editor );\n\n\t\tthis._defaultStyles = {\n\t\t\timageBlock: false,\n\t\t\timageInline: false\n\t\t};\n\n\t\tthis._styles = new Map( styles.map( style => {\n\t\t\tif ( style.isDefault ) {\n\t\t\t\tfor ( const modelElementName of style.modelElements ) {\n\t\t\t\t\tthis._defaultStyles[ modelElementName ] = style.name;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn [ style.name, style ];\n\t\t} ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\t\tconst element = imageUtils.getClosestSelectedImageElement( this.editor.model.document.selection )!;\n\n\t\tthis.isEnabled = !!element;\n\n\t\tif ( !this.isEnabled ) {\n\t\t\tthis.value = false;\n\t\t} else if ( element.hasAttribute( 'imageStyle' ) ) {\n\t\t\tthis.value = element.getAttribute( 'imageStyle' );\n\t\t} else {\n\t\t\tthis.value = this._defaultStyles[ element.name ];\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command and applies the style to the currently selected image:\n\t *\n\t * ```ts\n\t * editor.execute( 'imageStyle', { value: 'side' } );\n\t * ```\n\t *\n\t * **Note**: Executing this command may change the image model element if the desired style requires an image\n\t * of a different type. Learn more about {@link module:image/imageconfig~ImageStyleOptionDefinition#modelElements model element}\n\t * configuration for the style option.\n\t *\n\t * @param options.value The name of the style (as configured in {@link module:image/imageconfig~ImageStyleConfig#options}).\n\t * @param options.setImageSizes Specifies whether the image `width` and `height` attributes should be set automatically.\n\t * The default is `true`.\n\t * @fires execute\n\t */\n\tpublic override execute( options: { value?: string; setImageSizes?: boolean } = {} ): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\tmodel.change( writer => {\n\t\t\tconst requestedStyle = options.value;\n\t\t\tconst { setImageSizes = true } = options;\n\n\t\t\tlet imageElement = imageUtils.getClosestSelectedImageElement( model.document.selection )!;\n\n\t\t\t// Change the image type if a style requires it.\n\t\t\tif ( requestedStyle && this.shouldConvertImageType( requestedStyle, imageElement ) ) {\n\t\t\t\tthis.editor.execute( imageUtils.isBlockImage( imageElement ) ? 'imageTypeInline' : 'imageTypeBlock', { setImageSizes } );\n\n\t\t\t\t// Update the imageElement to the newly created image.\n\t\t\t\timageElement = imageUtils.getClosestSelectedImageElement( model.document.selection )!;\n\t\t\t}\n\n\t\t\t// Default style means that there is no `imageStyle` attribute in the model.\n\t\t\t// https://github.com/ckeditor/ckeditor5-image/issues/147\n\t\t\tif ( !requestedStyle || this._styles.get( requestedStyle )!.isDefault ) {\n\t\t\t\twriter.removeAttribute( 'imageStyle', imageElement );\n\t\t\t} else {\n\t\t\t\twriter.setAttribute( 'imageStyle', requestedStyle, imageElement );\n\t\t\t}\n\n\t\t\tif ( setImageSizes ) {\n\t\t\t\timageUtils.setImageNaturalSizeAttributes( imageElement );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns `true` if requested style change would trigger the image type change.\n\t *\n\t * @param requestedStyle The name of the style (as configured in {@link module:image/imageconfig~ImageStyleConfig#options}).\n\t * @param imageElement The image model element.\n\t */\n\tpublic shouldConvertImageType( requestedStyle: string, imageElement: Element ): boolean {\n\t\tconst supportedTypes = this._styles.get( requestedStyle )!.modelElements;\n\n\t\treturn !supportedTypes.includes( imageElement.name );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagestyle/utils\n */\n\nimport { type Editor, icons, type PluginCollection } from 'ckeditor5/src/core.js';\nimport { logWarning } from 'ckeditor5/src/utils.js';\nimport type { ImageStyleConfig, ImageStyleDropdownDefinition, ImageStyleOptionDefinition } from '../imageconfig.js';\n\n/**\n * Default image style options provided by the plugin that can be referred in the {@link module:image/imageconfig~ImageConfig#styles}\n * configuration.\n *\n * There are available 5 styles focused on formatting:\n *\n * * **`'alignLeft'`** aligns the inline or block image to the left and wraps it with the text using the `image-style-align-left` class,\n * * **`'alignRight'`** aligns the inline or block image to the right and wraps it with the text using the `image-style-align-right` class,\n * * **`'alignCenter'`** centers the block image using the `image-style-align-center` class,\n * * **`'alignBlockLeft'`** aligns the block image to the left using the `image-style-block-align-left` class,\n * * **`'alignBlockRight'`** aligns the block image to the right using the `image-style-block-align-right` class,\n *\n * and 3 semantic styles:\n *\n * * **`'inline'`** is an inline image without any CSS class,\n * * **`'block'`** is a block image without any CSS class,\n * * **`'side'`** is a block image styled with the `image-style-side` CSS class.\n */\nexport const DEFAULT_OPTIONS: Record<string, ImageStyleOptionDefinition> = {\n\t// This style represents an image placed in the line of text.\n\tget inline() {\n\t\treturn {\n\t\t\tname: 'inline',\n\t\t\ttitle: 'In line',\n\t\t\ticon: icons.objectInline,\n\t\t\tmodelElements: [ 'imageInline' ],\n\t\t\tisDefault: true\n\t\t};\n\t},\n\n\t// This style represents an image aligned to the left and wrapped with text.\n\tget alignLeft() {\n\t\treturn {\n\t\t\tname: 'alignLeft',\n\t\t\ttitle: 'Left aligned image',\n\t\t\ticon: icons.objectLeft,\n\t\t\tmodelElements: [ 'imageBlock', 'imageInline' ],\n\t\t\tclassName: 'image-style-align-left'\n\t\t};\n\t},\n\n\t// This style represents an image aligned to the left.\n\tget alignBlockLeft() {\n\t\treturn {\n\t\t\tname: 'alignBlockLeft',\n\t\t\ttitle: 'Left aligned image',\n\t\t\ticon: icons.objectBlockLeft,\n\t\t\tmodelElements: [ 'imageBlock' ],\n\t\t\tclassName: 'image-style-block-align-left'\n\t\t};\n\t},\n\n\t// This style represents a centered image.\n\tget alignCenter() {\n\t\treturn {\n\t\t\tname: 'alignCenter',\n\t\t\ttitle: 'Centered image',\n\t\t\ticon: icons.objectCenter,\n\t\t\tmodelElements: [ 'imageBlock' ],\n\t\t\tclassName: 'image-style-align-center'\n\t\t};\n\t},\n\n\t// This style represents an image aligned to the right and wrapped with text.\n\tget alignRight() {\n\t\treturn {\n\t\t\tname: 'alignRight',\n\t\t\ttitle: 'Right aligned image',\n\t\t\ticon: icons.objectRight,\n\t\t\tmodelElements: [ 'imageBlock', 'imageInline' ],\n\t\t\tclassName: 'image-style-align-right'\n\t\t};\n\t},\n\n\t// This style represents an image aligned to the right.\n\tget alignBlockRight() {\n\t\treturn {\n\t\t\tname: 'alignBlockRight',\n\t\t\ttitle: 'Right aligned image',\n\t\t\ticon: icons.objectBlockRight,\n\t\t\tmodelElements: [ 'imageBlock' ],\n\t\t\tclassName: 'image-style-block-align-right'\n\t\t};\n\t},\n\n\t// This option is equal to the situation when no style is applied.\n\tget block() {\n\t\treturn {\n\t\t\tname: 'block',\n\t\t\ttitle: 'Centered image',\n\t\t\ticon: icons.objectCenter,\n\t\t\tmodelElements: [ 'imageBlock' ],\n\t\t\tisDefault: true\n\t\t};\n\t},\n\n\t// This represents a side image.\n\tget side() {\n\t\treturn {\n\t\t\tname: 'side',\n\t\t\ttitle: 'Side image',\n\t\t\ticon: icons.objectRight,\n\t\t\tmodelElements: [ 'imageBlock' ],\n\t\t\tclassName: 'image-style-side'\n\t\t};\n\t}\n};\n\n/**\n * Default image style icons provided by the plugin that can be referred in the {@link module:image/imageconfig~ImageConfig#styles}\n * configuration.\n *\n * See {@link module:image/imageconfig~ImageStyleOptionDefinition#icon} to learn more.\n *\n * There are 7 default icons available: `'full'`, `'left'`, `'inlineLeft'`, `'center'`, `'right'`, `'inlineRight'`, and `'inline'`.\n */\nexport const DEFAULT_ICONS: Record<string, string> = /* #__PURE__ */ ( () => ( {\n\tfull: icons.objectFullWidth,\n\tleft: icons.objectBlockLeft,\n\tright: icons.objectBlockRight,\n\tcenter: icons.objectCenter,\n\tinlineLeft: icons.objectLeft,\n\tinlineRight: icons.objectRight,\n\tinline: icons.objectInline\n} ) )();\n\n/**\n * Default drop-downs provided by the plugin that can be referred in the {@link module:image/imageconfig~ImageConfig#toolbar}\n * configuration. The drop-downs are containers for the {@link module:image/imageconfig~ImageStyleConfig#options image style options}.\n *\n * If both of the `ImageEditing` plugins are loaded, there are 2 predefined drop-downs available:\n *\n * * **`'imageStyle:wrapText'`**, which contains the `alignLeft` and `alignRight` options, that is,\n * those that wraps the text around the image,\n * * **`'imageStyle:breakText'`**, which contains the `alignBlockLeft`, `alignCenter` and `alignBlockRight` options, that is,\n * those that breaks the text around the image.\n */\nexport const DEFAULT_DROPDOWN_DEFINITIONS: Array<ImageStyleDropdownDefinition> = [ {\n\tname: 'imageStyle:wrapText',\n\ttitle: 'Wrap text',\n\tdefaultItem: 'imageStyle:alignLeft',\n\titems: [ 'imageStyle:alignLeft', 'imageStyle:alignRight' ]\n}, {\n\tname: 'imageStyle:breakText',\n\ttitle: 'Break text',\n\tdefaultItem: 'imageStyle:block',\n\titems: [ 'imageStyle:alignBlockLeft', 'imageStyle:block', 'imageStyle:alignBlockRight' ]\n} ];\n\n/**\n * Returns a list of the normalized and validated image style options.\n *\n * @param config\n * @param config.isInlinePluginLoaded\n * Determines whether the {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`} plugin has been loaded.\n * @param config.isBlockPluginLoaded\n * Determines whether the {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`} plugin has been loaded.\n * @param config.configuredStyles\n * The image styles configuration provided in the image styles {@link module:image/imageconfig~ImageConfig#styles configuration}\n * as a default or custom value.\n * @returns\n * * Each of options contains a complete icon markup.\n * * The image style options not supported by any of the loaded plugins are filtered out.\n */\nfunction normalizeStyles( config: {\n\tisInlinePluginLoaded: boolean;\n\tisBlockPluginLoaded: boolean;\n\tconfiguredStyles: ImageStyleConfig;\n}\n): Array<ImageStyleOptionDefinition> {\n\tconst configuredStyles = config.configuredStyles.options || [];\n\n\tconst styles = configuredStyles\n\t\t.map( arrangement => normalizeDefinition( arrangement ) )\n\t\t.filter( arrangement => isValidOption( arrangement, config ) );\n\n\treturn styles;\n}\n\n/**\n * Returns the default image styles configuration depending on the loaded image editing plugins.\n *\n * @param isInlinePluginLoaded\n * Determines whether the {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`} plugin has been loaded.\n *\n * @param isBlockPluginLoaded\n * Determines whether the {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`} plugin has been loaded.\n *\n * @returns\n * It returns an object with the lists of the image style options and groups defined as strings related to the\n * {@link module:image/imagestyle/utils#DEFAULT_OPTIONS default options}\n */\nfunction getDefaultStylesConfiguration( isBlockPluginLoaded: boolean, isInlinePluginLoaded: boolean ): ImageStyleConfig {\n\tif ( isBlockPluginLoaded && isInlinePluginLoaded ) {\n\t\treturn {\n\t\t\toptions: [\n\t\t\t\t'inline', 'alignLeft', 'alignRight',\n\t\t\t\t'alignCenter', 'alignBlockLeft', 'alignBlockRight',\n\t\t\t\t'block', 'side'\n\t\t\t]\n\t\t};\n\t} else if ( isBlockPluginLoaded ) {\n\t\treturn {\n\t\t\toptions: [ 'block', 'side' ]\n\t\t};\n\t} else if ( isInlinePluginLoaded ) {\n\t\treturn {\n\t\t\toptions: [ 'inline', 'alignLeft', 'alignRight' ]\n\t\t};\n\t}\n\n\treturn {};\n}\n\n/**\n * Returns a list of the available predefined drop-downs' definitions depending on the loaded image editing plugins.\n */\nfunction getDefaultDropdownDefinitions( pluginCollection: PluginCollection<Editor> ): Array<ImageStyleDropdownDefinition> {\n\tif ( pluginCollection.has( 'ImageBlockEditing' ) && pluginCollection.has( 'ImageInlineEditing' ) ) {\n\t\treturn [ ...DEFAULT_DROPDOWN_DEFINITIONS ];\n\t} else {\n\t\treturn [];\n\t}\n}\n\n/**\n * Normalizes an image style option or group provided in the {@link module:image/imageconfig~ImageConfig#styles}\n * and returns it in a {@link module:image/imageconfig~ImageStyleOptionDefinition}/\n */\nfunction normalizeDefinition( definition: string | Partial<ImageStyleOptionDefinition> & { name: string } ): ImageStyleOptionDefinition {\n\tif ( typeof definition === 'string' ) {\n\t\t// Just the name of the style has been passed, but none of the defaults.\n\t\tif ( !DEFAULT_OPTIONS[ definition ] ) {\n\t\t\t// Normalize the style anyway to prevent errors.\n\t\t\tdefinition = { name: definition };\n\t\t}\n\t\t// Just the name of the style has been passed and it's one of the defaults, just use it.\n\t\t// Clone the style to avoid overriding defaults.\n\t\telse {\n\t\t\tdefinition = { ...DEFAULT_OPTIONS[ definition ] };\n\t\t}\n\t} else {\n\t\t// If an object style has been passed and if the name matches one of the defaults,\n\t\t// extend it with defaults – the user wants to customize a default style.\n\t\t// Note: Don't override the user–defined style object, clone it instead.\n\t\tdefinition = extendStyle( DEFAULT_OPTIONS[ definition.name ], definition );\n\t}\n\n\t// If an icon is defined as a string and correspond with a name\n\t// in default icons, use the default icon provided by the plugin.\n\tif ( typeof definition.icon === 'string' ) {\n\t\tdefinition.icon = DEFAULT_ICONS[ definition.icon ] || definition.icon;\n\t}\n\n\treturn definition as ImageStyleOptionDefinition;\n}\n\n/**\n * Checks if the image style option is valid:\n * * if it has the modelElements fields defined and filled,\n * * if the defined modelElements are supported by any of the loaded image editing plugins.\n * It also displays a console warning these conditions are not met.\n *\n * @param option image style option\n */\nfunction isValidOption(\n\toption: ImageStyleOptionDefinition,\n\t{ isBlockPluginLoaded, isInlinePluginLoaded }: { isBlockPluginLoaded: boolean; isInlinePluginLoaded: boolean }\n): boolean {\n\tconst { modelElements, name } = option;\n\n\tif ( !modelElements || !modelElements.length || !name ) {\n\t\twarnInvalidStyle( { style: option } );\n\n\t\treturn false;\n\t} else {\n\t\tconst supportedElements = [ isBlockPluginLoaded ? 'imageBlock' : null, isInlinePluginLoaded ? 'imageInline' : null ];\n\n\t\t// Check if the option is supported by any of the loaded plugins.\n\t\tif ( !modelElements.some( elementName => supportedElements.includes( elementName ) ) ) {\n\t\t\t/**\n\t\t\t * In order to work correctly, each image style {@link module:image/imageconfig~ImageStyleOptionDefinition option}\n\t\t\t * requires specific model elements (also: types of images) to be supported by the editor.\n\t\t\t *\n\t\t\t * Model element names to which the image style option can be applied are defined in the\n\t\t\t * {@link module:image/imageconfig~ImageStyleOptionDefinition#modelElements} property of the style option\n\t\t\t * definition.\n\t\t\t *\n\t\t\t * Explore the warning in the console to find out precisely which option is not supported and which editor plugins\n\t\t\t * are missing. Make sure these plugins are loaded in your editor to get this image style option working.\n\t\t\t *\n\t\t\t * @error image-style-missing-dependency\n\t\t\t * @param {String} [option] The name of the unsupported option.\n\t\t\t * @param {String} [missingPlugins] The names of the plugins one of which has to be loaded for the particular option.\n\t\t\t */\n\t\t\tlogWarning( 'image-style-missing-dependency', {\n\t\t\t\tstyle: option,\n\t\t\t\tmissingPlugins: modelElements.map( name => name === 'imageBlock' ? 'ImageBlockEditing' : 'ImageInlineEditing' )\n\t\t\t} );\n\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Extends the default style with a style provided by the developer.\n * Note: Don't override the custom–defined style object, clone it instead.\n */\nfunction extendStyle( source: ImageStyleOptionDefinition, style: Partial<ImageStyleOptionDefinition> ): ImageStyleOptionDefinition {\n\tconst extendedStyle: Record<string, any> = { ...style };\n\n\tfor ( const prop in source ) {\n\t\tif ( !Object.prototype.hasOwnProperty.call( style, prop ) ) {\n\t\t\textendedStyle[ prop ] = source[ prop as keyof typeof source ];\n\t\t}\n\t}\n\n\treturn extendedStyle as ImageStyleOptionDefinition;\n}\n\n/**\n * Displays a console warning with the 'image-style-configuration-definition-invalid' error.\n */\nfunction warnInvalidStyle( info: object ): void {\n\t/**\n\t * The image style definition provided in the configuration is invalid.\n\t *\n\t * Please make sure the definition implements properly one of the following:\n\t *\n\t * * {@link module:image/imageconfig~ImageStyleOptionDefinition image style option definition},\n\t * * {@link module:image/imageconfig~ImageStyleDropdownDefinition image style dropdown definition}\n\t *\n\t * @error image-style-configuration-definition-invalid\n\t * @param {String} [dropdown] The name of the invalid drop-down\n\t * @param {String} [style] The name of the invalid image style option\n\t */\n\tlogWarning( 'image-style-configuration-definition-invalid', info );\n}\n\nexport default {\n\tnormalizeStyles,\n\tgetDefaultStylesConfiguration,\n\tgetDefaultDropdownDefinitions,\n\twarnInvalidStyle,\n\tDEFAULT_OPTIONS,\n\tDEFAULT_ICONS,\n\tDEFAULT_DROPDOWN_DEFINITIONS\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\nimport type { DowncastAttributeEvent, Element, UpcastElementEvent } from 'ckeditor5/src/engine.js';\nimport { first, type GetCallback } from 'ckeditor5/src/utils.js';\nimport type { ImageStyleOptionDefinition } from '../imageconfig.js';\n\n/**\n * @module image/imagestyle/converters\n */\n\n/**\n * Returns a converter for the `imageStyle` attribute. It can be used for adding, changing and removing the attribute.\n *\n * @param styles An array containing available image style options.\n * @returns A model-to-view attribute converter.\n */\nexport function modelToViewStyleAttribute( styles: Array<ImageStyleOptionDefinition> ): GetCallback<DowncastAttributeEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if there is class name associated with given value.\n\t\tconst newStyle = getStyleDefinitionByName( data.attributeNewValue as string, styles );\n\t\tconst oldStyle = getStyleDefinitionByName( data.attributeOldValue as string, styles );\n\n\t\tconst viewElement = conversionApi.mapper.toViewElement( data.item as Element )!;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tif ( oldStyle ) {\n\t\t\tviewWriter.removeClass( oldStyle.className!, viewElement );\n\t\t}\n\n\t\tif ( newStyle ) {\n\t\t\tviewWriter.addClass( newStyle.className!, viewElement );\n\t\t}\n\t};\n}\n\n/**\n * Returns a view-to-model converter converting image CSS classes to a proper value in the model.\n *\n * @param styles Image style options for which the converter is created.\n * @returns A view-to-model converter.\n */\nexport function viewToModelStyleAttribute( styles: Array<ImageStyleOptionDefinition> ): GetCallback<UpcastElementEvent> {\n\t// Convert only non–default styles.\n\tconst nonDefaultStyles: Record<string, Array<ImageStyleOptionDefinition>> = {\n\t\timageInline: styles.filter( style => !style.isDefault && style.modelElements.includes( 'imageInline' ) ),\n\t\timageBlock: styles.filter( style => !style.isDefault && style.modelElements.includes( 'imageBlock' ) )\n\t};\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = data.viewItem;\n\t\tconst modelImageElement = first( data.modelRange.getItems() );\n\n\t\t// Run this converter only if an image has been found in the model.\n\t\t// In some cases it may not be found (for example if we run this on a figure with different type than image).\n\t\tif ( !modelImageElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// ...and the `imageStyle` attribute is allowed for that element, otherwise stop conversion early.\n\t\tif ( !conversionApi.schema.checkAttribute( modelImageElement, 'imageStyle' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert styles one by one.\n\t\tfor ( const style of nonDefaultStyles[ ( modelImageElement as Element ).name ] ) {\n\t\t\t// Try to consume class corresponding with the style.\n\t\t\tif ( conversionApi.consumable.consume( viewElement, { classes: style.className } ) ) {\n\t\t\t\t// And convert this style to model attribute.\n\t\t\t\tconversionApi.writer.setAttribute( 'imageStyle', style.name, modelImageElement );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Returns the style with a given `name` from an array of styles.\n */\nfunction getStyleDefinitionByName( name: string, styles: Array<ImageStyleOptionDefinition> ): ImageStyleOptionDefinition | undefined {\n\tfor ( const style of styles ) {\n\t\tif ( style.name === name ) {\n\t\t\treturn style;\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagestyle/imagestyleediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type { Element, UpcastElementEvent } from 'ckeditor5/src/engine.js';\n\nimport ImageStyleCommand from './imagestylecommand.js';\nimport ImageUtils from '../imageutils.js';\nimport utils from './utils.js';\nimport { viewToModelStyleAttribute, modelToViewStyleAttribute } from './converters.js';\nimport type { ImageStyleOptionDefinition } from '../imageconfig.js';\n\n/**\n * The image style engine plugin. It sets the default configuration, creates converters and registers\n * {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand ImageStyleCommand}.\n */\nexport default class ImageStyleEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageStyleEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageUtils ] as const;\n\t}\n\n\t/**\n\t * It contains a list of the normalized and validated style options.\n\t *\n\t * * Each option contains a complete icon markup.\n\t * * The style options not supported by any of the loaded image editing plugins (\n\t * {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`} or\n\t * {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`}) are filtered out.\n\t *\n\t * @internal\n\t * @readonly\n\t */\n\tpublic normalizedStyles?: Array<ImageStyleOptionDefinition>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst { normalizeStyles, getDefaultStylesConfiguration } = utils;\n\t\tconst editor = this.editor;\n\t\tconst isBlockPluginLoaded = editor.plugins.has( 'ImageBlockEditing' );\n\t\tconst isInlinePluginLoaded = editor.plugins.has( 'ImageInlineEditing' );\n\n\t\teditor.config.define( 'image.styles', getDefaultStylesConfiguration( isBlockPluginLoaded, isInlinePluginLoaded ) );\n\n\t\tthis.normalizedStyles = normalizeStyles( {\n\t\t\tconfiguredStyles: editor.config.get( 'image.styles' )!,\n\t\t\tisBlockPluginLoaded,\n\t\t\tisInlinePluginLoaded\n\t\t} );\n\n\t\tthis._setupConversion( isBlockPluginLoaded, isInlinePluginLoaded );\n\t\tthis._setupPostFixer();\n\n\t\t// Register imageStyle command.\n\t\teditor.commands.add( 'imageStyle', new ImageStyleCommand( editor, this.normalizedStyles ) );\n\t}\n\n\t/**\n\t * Sets the editor conversion taking the presence of\n\t * {@link module:image/image/imageinlineediting~ImageInlineEditing `ImageInlineEditing`}\n\t * and {@link module:image/image/imageblockediting~ImageBlockEditing `ImageBlockEditing`} plugins into consideration.\n\t */\n\tprivate _setupConversion( isBlockPluginLoaded: boolean, isInlinePluginLoaded: boolean ): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\tconst modelToViewConverter = modelToViewStyleAttribute( this.normalizedStyles! );\n\t\tconst viewToModelConverter = viewToModelStyleAttribute( this.normalizedStyles! );\n\n\t\teditor.editing.downcastDispatcher.on( 'attribute:imageStyle', modelToViewConverter );\n\t\teditor.data.downcastDispatcher.on( 'attribute:imageStyle', modelToViewConverter );\n\n\t\t// Allow imageStyle attribute in image and imageInline.\n\t\t// We could call it 'style' but https://github.com/ckeditor/ckeditor5-engine/issues/559.\n\t\tif ( isBlockPluginLoaded ) {\n\t\t\tschema.extend( 'imageBlock', { allowAttributes: 'imageStyle' } );\n\n\t\t\t// Converter for figure element from view to model.\n\t\t\teditor.data.upcastDispatcher.on<UpcastElementEvent>( 'element:figure', viewToModelConverter, { priority: 'low' } );\n\t\t}\n\n\t\tif ( isInlinePluginLoaded ) {\n\t\t\tschema.extend( 'imageInline', { allowAttributes: 'imageStyle' } );\n\n\t\t\t// Converter for the img element from view to model.\n\t\t\teditor.data.upcastDispatcher.on( 'element:img', viewToModelConverter, { priority: 'low' } );\n\t\t}\n\t}\n\n\t/**\n\t * Registers a post-fixer that will make sure that the style attribute value is correct for a specific image type (block vs inline).\n\t */\n\tprivate _setupPostFixer(): void {\n\t\tconst editor = this.editor;\n\t\tconst document = editor.model.document;\n\n\t\tconst imageUtils = editor.plugins.get( ImageUtils );\n\t\tconst stylesMap = new Map( this.normalizedStyles!.map( style => [ style.name, style ] ) );\n\n\t\t// Make sure that style attribute is valid for the image type.\n\t\tdocument.registerPostFixer( writer => {\n\t\t\tlet changed = false;\n\n\t\t\tfor ( const change of document.differ.getChanges() ) {\n\t\t\t\tif ( change.type == 'insert' || change.type == 'attribute' && change.attributeKey == 'imageStyle' ) {\n\t\t\t\t\tlet element = change.type == 'insert' ? change.position.nodeAfter! : change.range.start.nodeAfter!;\n\n\t\t\t\t\tif ( element && element.is( 'element', 'paragraph' ) && element.childCount > 0 ) {\n\t\t\t\t\t\telement = element.getChild( 0 )!;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !imageUtils.isImage( element as Element ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst imageStyle = element.getAttribute( 'imageStyle' ) as string | undefined;\n\n\t\t\t\t\tif ( !imageStyle ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst imageStyleDefinition = stylesMap.get( imageStyle );\n\n\t\t\t\t\tif ( !imageStyleDefinition || !imageStyleDefinition.modelElements.includes( ( element as Element ).name ) ) {\n\t\t\t\t\t\twriter.removeAttribute( 'imageStyle', element );\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagestyle/imagestyleui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, createDropdown, addToolbarToDropdown, SplitButtonView } from 'ckeditor5/src/ui.js';\nimport { isObject, identity } from 'lodash-es';\nimport ImageStyleEditing from './imagestyleediting.js';\nimport utils from './utils.js';\nimport type { ImageStyleDropdownDefinition, ImageStyleOptionDefinition } from '../imageconfig.js';\nimport type ImageStyleCommand from './imagestylecommand.js';\n\nimport '../../theme/imagestyle.css';\n\n/**\n * The image style UI plugin.\n *\n * It registers buttons corresponding to the {@link module:image/imageconfig~ImageConfig#styles} configuration.\n * It also registers the {@link module:image/imagestyle/utils#DEFAULT_DROPDOWN_DEFINITIONS default drop-downs} and the\n * custom drop-downs defined by the developer in the {@link module:image/imageconfig~ImageConfig#toolbar} configuration.\n */\nexport default class ImageStyleUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageStyleEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageStyleUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the default localized style titles provided by the plugin.\n\t *\n\t * The following localized titles corresponding with\n\t * {@link module:image/imagestyle/utils#DEFAULT_OPTIONS} are available:\n\t *\n\t * * `'Wrap text'`,\n\t * * `'Break text'`,\n\t * * `'In line'`,\n\t * * `'Full size image'`,\n\t * * `'Side image'`,\n\t * * `'Left aligned image'`,\n\t * * `'Centered image'`,\n\t * * `'Right aligned image'`\n\t */\n\tpublic get localizedDefaultStylesTitles(): Record<string, string> {\n\t\tconst t = this.editor.t;\n\n\t\treturn {\n\t\t\t'Wrap text': t( 'Wrap text' ),\n\t\t\t'Break text': t( 'Break text' ),\n\t\t\t'In line': t( 'In line' ),\n\t\t\t'Full size image': t( 'Full size image' ),\n\t\t\t'Side image': t( 'Side image' ),\n\t\t\t'Left aligned image': t( 'Left aligned image' ),\n\t\t\t'Centered image': t( 'Centered image' ),\n\t\t\t'Right aligned image': t( 'Right aligned image' )\n\t\t};\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst plugins = this.editor.plugins;\n\t\tconst toolbarConfig = this.editor.config.get( 'image.toolbar' ) || [];\n\t\tconst imageStyleEditing: ImageStyleEditing = plugins.get( 'ImageStyleEditing' );\n\n\t\tconst definedStyles = translateStyles(\n\t\t\timageStyleEditing.normalizedStyles!,\n\t\t\tthis.localizedDefaultStylesTitles\n\t\t);\n\n\t\tfor ( const styleConfig of definedStyles ) {\n\t\t\tthis._createButton( styleConfig );\n\t\t}\n\n\t\tconst definedDropdowns = translateStyles(\n\t\t\t[\n\t\t\t\t...toolbarConfig.filter( isObject ) as Array<ImageStyleDropdownDefinition>,\n\t\t\t\t...utils.getDefaultDropdownDefinitions( plugins )\n\t\t\t],\n\t\t\tthis.localizedDefaultStylesTitles\n\t\t);\n\n\t\tfor ( const dropdownConfig of definedDropdowns ) {\n\t\t\tthis._createDropdown( dropdownConfig, definedStyles );\n\t\t}\n\t}\n\n\t/**\n\t * Creates a dropdown and stores it in the editor {@link module:ui/componentfactory~ComponentFactory}.\n\t */\n\tprivate _createDropdown( dropdownConfig: ImageStyleDropdownDefinition, definedStyles: Array<ImageStyleOptionDefinition> ): void {\n\t\tconst factory = this.editor.ui.componentFactory;\n\n\t\tfactory.add( dropdownConfig.name, locale => {\n\t\t\tlet defaultButton: ButtonView | undefined;\n\n\t\t\tconst { defaultItem, items, title } = dropdownConfig;\n\t\t\tconst buttonViews = items\n\t\t\t\t.filter( itemName => definedStyles.find( ( { name } ) => getUIComponentName( name ) === itemName ) )\n\t\t\t\t.map( buttonName => {\n\t\t\t\t\tconst button = factory.create( buttonName ) as ButtonView;\n\n\t\t\t\t\tif ( buttonName === defaultItem ) {\n\t\t\t\t\t\tdefaultButton = button;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn button;\n\t\t\t\t} );\n\n\t\t\tif ( items.length !== buttonViews.length ) {\n\t\t\t\tutils.warnInvalidStyle( { dropdown: dropdownConfig } );\n\t\t\t}\n\n\t\t\tconst dropdownView = createDropdown( locale, SplitButtonView );\n\t\t\tconst splitButtonView = dropdownView.buttonView as SplitButtonView;\n\t\t\tconst splitButtonViewArrow = splitButtonView.arrowView;\n\n\t\t\taddToolbarToDropdown( dropdownView, buttonViews, { enableActiveItemFocusOnDropdownOpen: true } );\n\n\t\t\tsplitButtonView.set( {\n\t\t\t\tlabel: getDropdownButtonTitle( title, defaultButton!.label! ),\n\t\t\t\tclass: null,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tsplitButtonViewArrow.unbind( 'label' );\n\t\t\tsplitButtonViewArrow.set( {\n\t\t\t\tlabel: title\n\t\t\t} );\n\n\t\t\tsplitButtonView.bind( 'icon' ).toMany( buttonViews, 'isOn', ( ...areOn ) => {\n\t\t\t\tconst index = areOn.findIndex( identity );\n\n\t\t\t\treturn ( index < 0 ) ? defaultButton!.icon : buttonViews[ index ].icon;\n\t\t\t} );\n\n\t\t\tsplitButtonView.bind( 'label' ).toMany( buttonViews, 'isOn', ( ...areOn ) => {\n\t\t\t\tconst index = areOn.findIndex( identity );\n\n\t\t\t\treturn getDropdownButtonTitle( title, ( index < 0 ) ? defaultButton!.label! : buttonViews[ index ].label! );\n\t\t\t} );\n\n\t\t\tsplitButtonView.bind( 'isOn' ).toMany( buttonViews, 'isOn', ( ...areOn ) => areOn.some( identity ) );\n\n\t\t\tsplitButtonView.bind( 'class' )\n\t\t\t\t.toMany( buttonViews, 'isOn', ( ...areOn ) => areOn.some( identity ) ? 'ck-splitbutton_flatten' : undefined );\n\n\t\t\tsplitButtonView.on( 'execute', () => {\n\t\t\t\tif ( !buttonViews.some( ( { isOn } ) => isOn ) ) {\n\t\t\t\t\tdefaultButton!.fire( 'execute' );\n\t\t\t\t} else {\n\t\t\t\t\tdropdownView.isOpen = !dropdownView.isOpen;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tdropdownView.bind( 'isEnabled' )\n\t\t\t\t.toMany( buttonViews, 'isEnabled', ( ...areEnabled ) => areEnabled.some( identity ) );\n\n\t\t\t// Focus the editable after executing the command.\n\t\t\t// Overrides a default behaviour where the focus is moved to the dropdown button (#12125).\n\t\t\tthis.listenTo( dropdownView, 'execute', () => {\n\t\t\t\tthis.editor.editing.view.focus();\n\t\t\t} );\n\n\t\t\treturn dropdownView;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a button and stores it in the editor {@link module:ui/componentfactory~ComponentFactory}.\n\t */\n\tprivate _createButton( buttonConfig: ImageStyleOptionDefinition ): void {\n\t\tconst buttonName = buttonConfig.name;\n\n\t\tthis.editor.ui.componentFactory.add( getUIComponentName( buttonName ), locale => {\n\t\t\tconst command: ImageStyleCommand = this.editor.commands.get( 'imageStyle' )!;\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: buttonConfig.title,\n\t\t\t\ticon: buttonConfig.icon,\n\t\t\t\ttooltip: true,\n\t\t\t\tisToggleable: true\n\t\t\t} );\n\n\t\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t\t\tview.bind( 'isOn' ).to( command, 'value', value => value === buttonName );\n\t\t\tview.on( 'execute', this._executeCommand.bind( this, buttonName ) );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\tprivate _executeCommand( name: string ): void {\n\t\tthis.editor.execute( 'imageStyle', { value: name } );\n\t\tthis.editor.editing.view.focus();\n\t}\n}\n\n/**\n * Returns the translated `title` from the passed styles array.\n */\nfunction translateStyles<T extends ImageStyleOptionDefinition | ImageStyleDropdownDefinition>(\n\tstyles: Array<T>,\n\ttitles: Record<string, string>\n): Array<T> {\n\tfor ( const style of styles ) {\n\t\t// Localize the titles of the styles, if a title corresponds with\n\t\t// a localized default provided by the plugin.\n\t\tif ( titles[ style.title! ] ) {\n\t\t\tstyle.title = titles[ style.title! ];\n\t\t}\n\t}\n\n\treturn styles;\n}\n\n/**\n * Returns the image style component name with the \"imageStyle:\" prefix.\n */\nfunction getUIComponentName( name: string ): string {\n\treturn `imageStyle:${ name }`;\n}\n\n/**\n * Returns title for the splitbutton containing the dropdown title and default action item title.\n */\nfunction getDropdownButtonTitle( dropdownTitle: string | undefined, buttonTitle: string ): string {\n\treturn ( dropdownTitle ? dropdownTitle + ': ' : '' ) + buttonTitle;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagestyle\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ImageStyleEditing from './imagestyle/imagestyleediting.js';\nimport ImageStyleUI from './imagestyle/imagestyleui.js';\n\n/**\n * The image style plugin.\n *\n * For a detailed overview of the image styles feature, check the {@glink features/images/images-styles documentation}.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n * * {@link module:image/imagestyle/imagestyleediting~ImageStyleEditing},\n * * {@link module:image/imagestyle/imagestyleui~ImageStyleUI}\n *\n * It provides a default configuration, which can be extended or overwritten.\n * Read more about the {@link module:image/imageconfig~ImageConfig#styles image styles configuration}.\n */\nexport default class ImageStyle extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageStyleEditing, ImageStyleUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageStyle' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/imagetoolbar\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { WidgetToolbarRepository } from 'ckeditor5/src/widget.js';\n\nimport ImageUtils from './imageutils.js';\nimport type { ImageStyleDropdownDefinition } from './imageconfig.js';\n\nimport { isObject } from 'lodash-es';\n\n/**\n * The image toolbar plugin. It creates and manages the image toolbar (the toolbar displayed when an image is selected).\n *\n * For an overview, check the {@glink features/images/images-overview#image-contextual-toolbar image contextual toolbar} documentation.\n *\n * Instances of toolbar components (e.g. buttons) are created using the editor's\n * {@link module:ui/componentfactory~ComponentFactory component factory}\n * based on the {@link module:image/imageconfig~ImageConfig#toolbar `image.toolbar` configuration option}.\n *\n * The toolbar uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon}.\n */\nexport default class ImageToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ WidgetToolbarRepository, ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ImageToolbar' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\twidgetToolbarRepository.register( 'image', {\n\t\t\tariaLabel: t( 'Image toolbar' ),\n\t\t\titems: normalizeDeclarativeConfig( editor.config.get( 'image.toolbar' ) || [] ),\n\t\t\tgetRelatedElement: selection => imageUtils.getClosestSelectedImageWidget( selection )!\n\t\t} );\n\t}\n}\n\n/**\n * Convert the dropdown definitions to their keys registered in the ComponentFactory.\n * The registration precess should be handled by the plugin which handles the UI of a particular feature.\n */\nfunction normalizeDeclarativeConfig( config: Array<string | ImageStyleDropdownDefinition> ): Array<string> {\n\treturn config.map( item => isObject( item ) ? item.name : item );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module image/pictureediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport ImageEditing from './image/imageediting.js';\nimport ImageUtils from './imageutils.js';\nimport { downcastSourcesAttribute, upcastPicture } from './image/converters.js';\nimport type { default as ImageUploadEditing, ImageUploadCompleteEvent } from './imageupload/imageuploadediting.js';\n\n/**\n * This plugin enables the [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) element support in the editor.\n *\n * * It enables the `sources` model attribute on `imageBlock` and `imageInline` model elements\n * (brought by {@link module:image/imageblock~ImageBlock} and {@link module:image/imageinline~ImageInline}, respectively).\n * * It translates the `sources` model element to the view (also: data) structure that may look as follows:\n *\n * ```html\n * <p>Inline image using picture:\n * \t<picture>\n * \t\t<source media=\"(min-width: 800px)\" srcset=\"image-large.webp\" type=\"image/webp\">\n * \t\t<source media=\"(max-width: 800px)\" srcset=\"image-small.webp\" type=\"image/webp\">\n * \t\t<!-- Other sources as specified in the \"sources\" model attribute... -->\n * \t\t<img src=\"image.png\" alt=\"An image using picture\" />\n * \t</picture>\n * </p>\n *\n * <p>Block image using picture:</p>\n * <figure class=\"image\">\n * \t<picture>\n * \t\t<source media=\"(min-width: 800px)\" srcset=\"image-large.webp\" type=\"image/webp\">\n * \t\t<source media=\"(max-width: 800px)\" srcset=\"image-small.webp\" type=\"image/webp\">\n * \t\t<!-- Other sources as specified in the \"sources\" model attribute... -->\n * \t\t<img src=\"image.png\" alt=\"An image using picture\" />\n * \t</picture>\n * \t<figcaption>Caption of the image</figcaption>\n * </figure>\n * ```\n *\n * **Note:** The value of the `sources` {@glink framework/architecture/editing-engine#changing-the-model model attribute}\n * in both examples equals:\n *\n * ```css\n * [\n * \t{\n * \t\tmedia: '(min-width: 800px)',\n * \t\tsrcset: 'image-large.webp',\n * \t\ttype: 'image/webp'\n * \t},\n * \t{\n * \t\tmedia: '(max-width: 800px)',\n * \t\tsrcset: 'image-small.webp',\n * \t\ttype: 'image/webp'\n * \t}\n * ]\n * ```\n *\n * * It integrates with the {@link module:image/imageupload~ImageUpload} plugin so images uploaded in the editor\n * automatically render using `<picture>` if the {@glink features/images/image-upload/image-upload upload adapter}\n * supports image sources and provides neccessary data.\n *\n * @private\n */\nexport default class PictureEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ImageEditing, ImageUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'PictureEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\n\t\tif ( editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\teditor.model.schema.extend( 'imageBlock', {\n\t\t\t\tallowAttributes: [ 'sources' ]\n\t\t\t} );\n\t\t}\n\n\t\tif ( editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\teditor.model.schema.extend( 'imageInline', {\n\t\t\t\tallowAttributes: [ 'sources' ]\n\t\t\t} );\n\t\t}\n\n\t\tthis._setupConversion();\n\t\tthis._setupImageUploadEditingIntegration();\n\t}\n\n\t/**\n\t * Configures conversion pipelines to support upcasting and downcasting images using the `<picture>` view element\n\t * and the model `sources` attribute.\n\t */\n\tprivate _setupConversion(): void {\n\t\tconst editor = this.editor;\n\t\tconst conversion = editor.conversion;\n\t\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\t\tconversion.for( 'upcast' ).add( upcastPicture( imageUtils ) );\n\t\tconversion.for( 'downcast' ).add( downcastSourcesAttribute( imageUtils ) );\n\t}\n\n\t/**\n\t * Makes it possible for uploaded images to get the `sources` model attribute and the `<picture>...</picture>`\n\t * view structure out-of-the-box if relevant data is provided along the\n\t * {@link module:image/imageupload/imageuploadediting~ImageUploadEditing#event:uploadComplete} event.\n\t */\n\tprivate _setupImageUploadEditingIntegration(): void {\n\t\tconst editor = this.editor;\n\n\t\tif ( !editor.plugins.has( 'ImageUploadEditing' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst imageUploadEditing: ImageUploadEditing = editor.plugins.get( 'ImageUploadEditing' );\n\n\t\tthis.listenTo<ImageUploadCompleteEvent>(\n\t\t\timageUploadEditing,\n\t\t\t'uploadComplete',\n\t\t\t( evt, { imageElement, data } ) => {\n\t\t\t\tconst sources = data.sources;\n\n\t\t\t\tif ( !sources ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\twriter.setAttributes( {\n\t\t\t\t\t\tsources\n\t\t\t\t\t}, imageElement );\n\t\t\t\t} );\n\t\t\t} );\n\t}\n}\n", "import { Plugin, MultiCommand, icons, Command } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { addMarginRules } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { first } from '@ckeditor/ckeditor5-utils/dist/index.js';\n\n/**\n * The indent editing feature.\n *\n * This plugin registers the `'indent'` and `'outdent'` commands.\n *\n * **Note**: In order for the commands to work, at least one of the compatible features is required. Read more in the\n * {@link module:indent/indent~Indent indent feature} API documentation.\n */ class IndentEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'IndentEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        editor.commands.add('indent', new MultiCommand(editor));\n        editor.commands.add('outdent', new MultiCommand(editor));\n    }\n}\n\n/**\n * The indent UI feature.\n *\n * This plugin registers the `'indent'` and `'outdent'` buttons.\n *\n * **Note**: In order for the commands to work, at least one of the compatible features is required. Read more in\n * the {@link module:indent/indent~Indent indent feature} API documentation.\n */ class IndentUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'IndentUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const t = editor.t;\n        const localizedIndentIcon = locale.uiLanguageDirection == 'ltr' ? icons.indent : icons.outdent;\n        const localizedOutdentIcon = locale.uiLanguageDirection == 'ltr' ? icons.outdent : icons.indent;\n        this._defineButton('indent', t('Increase indent'), localizedIndentIcon);\n        this._defineButton('outdent', t('Decrease indent'), localizedOutdentIcon);\n    }\n    /**\n\t * Defines UI buttons for both toolbar and menu bar.\n\t */ _defineButton(commandName, label, icon) {\n        const editor = this.editor;\n        editor.ui.componentFactory.add(commandName, ()=>{\n            const buttonView = this._createButton(ButtonView, commandName, label, icon);\n            buttonView.set({\n                tooltip: true\n            });\n            return buttonView;\n        });\n        editor.ui.componentFactory.add('menuBar:' + commandName, ()=>{\n            return this._createButton(MenuBarMenuListItemButtonView, commandName, label, icon);\n        });\n    }\n    /**\n\t * Creates a button to use either in toolbar or in menu bar.\n\t */ _createButton(ButtonClass, commandName, label, icon) {\n        const editor = this.editor;\n        const command = editor.commands.get(commandName);\n        const view = new ButtonClass(editor.locale);\n        view.set({\n            label,\n            icon\n        });\n        view.bind('isEnabled').to(command, 'isEnabled');\n        // Execute the command.\n        this.listenTo(view, 'execute', ()=>{\n            editor.execute(commandName);\n            editor.editing.view.focus();\n        });\n        return view;\n    }\n}\n\n/**\n * The indent feature.\n *\n * This plugin acts as a single entry point plugin for other features that implement indentation of elements like lists or paragraphs.\n *\n * The compatible features are:\n *\n * * The {@link module:list/list~List} or {@link module:list/list/listediting~ListEditing} feature for list indentation.\n * * The {@link module:indent/indentblock~IndentBlock} feature for block indentation.\n *\n * This is a \"glue\" plugin that loads the following plugins:\n *\n * * The {@link module:indent/indentediting~IndentEditing indent editing feature}.\n * * The {@link module:indent/indentui~IndentUI indent UI feature}.\n *\n * The dependent plugins register the `'indent'` and `'outdent'` commands and introduce the `'indent'` and `'outdent'` buttons\n * that allow to increase or decrease text indentation of supported elements.\n *\n * **Note**: In order for the commands and buttons to work, at least one of compatible features is required.\n */ class Indent extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Indent';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            IndentEditing,\n            IndentUI\n        ];\n    }\n}\n\n/**\n * The indent block command.\n *\n * The command is registered by the {@link module:indent/indentblock~IndentBlock} as `'indentBlock'` for indenting blocks and\n * `'outdentBlock'` for outdenting blocks.\n *\n * To increase block indentation at the current selection, execute the command:\n *\n * ```ts\n * editor.execute( 'indentBlock' );\n * ```\n *\n * To decrease block indentation at the current selection, execute the command:\n *\n * ```ts\n * editor.execute( 'outdentBlock' );\n * ```\n */ class IndentBlockCommand extends Command {\n    /**\n\t * The command's indentation behavior.\n\t */ _indentBehavior;\n    /**\n\t * Creates an instance of the command.\n\t */ constructor(editor, indentBehavior){\n        super(editor);\n        this._indentBehavior = indentBehavior;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const model = editor.model;\n        const block = first(model.document.selection.getSelectedBlocks());\n        if (!block || !this._isIndentationChangeAllowed(block)) {\n            this.isEnabled = false;\n            return;\n        }\n        this.isEnabled = this._indentBehavior.checkEnabled(block.getAttribute('blockIndent'));\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const model = this.editor.model;\n        const blocksToChange = this._getBlocksToChange();\n        model.change((writer)=>{\n            for (const block of blocksToChange){\n                const currentIndent = block.getAttribute('blockIndent');\n                const nextIndent = this._indentBehavior.getNextIndent(currentIndent);\n                if (nextIndent) {\n                    writer.setAttribute('blockIndent', nextIndent, block);\n                } else {\n                    writer.removeAttribute('blockIndent', block);\n                }\n            }\n        });\n    }\n    /**\n\t * Returns blocks from selection that should have blockIndent selection set.\n\t */ _getBlocksToChange() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const blocksInSelection = Array.from(selection.getSelectedBlocks());\n        return blocksInSelection.filter((block)=>this._isIndentationChangeAllowed(block));\n    }\n    /**\n\t * Returns false if indentation cannot be applied, i.e.:\n\t * - for blocks disallowed by schema declaration\n\t * - for blocks in Document Lists (disallowed forward indentation only). See https://github.com/ckeditor/ckeditor5/issues/14155.\n\t * Otherwise returns true.\n\t */ _isIndentationChangeAllowed(element) {\n        const editor = this.editor;\n        if (!editor.model.schema.checkAttribute(element, 'blockIndent')) {\n            return false;\n        }\n        if (!editor.plugins.has('ListUtils')) {\n            return true;\n        }\n        // Only forward indentation is disallowed in list items. This allows the user to outdent blocks that are already indented.\n        if (!this._indentBehavior.isForward) {\n            return true;\n        }\n        const documentListUtils = editor.plugins.get('ListUtils');\n        return !documentListUtils.isListItemBlock(element);\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module indent/indentcommandbehavior/indentusingoffset\n */ /**\n * The block indentation behavior that uses offsets to set indentation.\n */ class IndentUsingOffset {\n    /**\n\t * The direction of indentation.\n\t */ isForward;\n    /**\n\t * The offset of the next indentation step.\n\t */ offset;\n    /**\n\t * Indentation unit.\n\t */ unit;\n    /**\n\t * Creates an instance of the indentation behavior.\n\t *\n\t * @param config.direction The direction of indentation.\n\t * @param config.offset The offset of the next indentation step.\n\t * @param config.unit Indentation unit.\n\t */ constructor(config){\n        this.isForward = config.direction === 'forward';\n        this.offset = config.offset;\n        this.unit = config.unit;\n    }\n    /**\n\t * @inheritDoc\n\t */ checkEnabled(indentAttributeValue) {\n        const currentOffset = parseFloat(indentAttributeValue || '0');\n        // The command is always enabled for forward indentation.\n        return this.isForward || currentOffset > 0;\n    }\n    /**\n\t * @inheritDoc\n\t */ getNextIndent(indentAttributeValue) {\n        const currentOffset = parseFloat(indentAttributeValue || '0');\n        const isSameUnit = !indentAttributeValue || indentAttributeValue.endsWith(this.unit);\n        if (!isSameUnit) {\n            return this.isForward ? this.offset + this.unit : undefined;\n        }\n        const nextOffset = this.isForward ? this.offset : -this.offset;\n        const offsetToSet = currentOffset + nextOffset;\n        return offsetToSet > 0 ? offsetToSet + this.unit : undefined;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module indent/indentcommandbehavior/indentusingclasses\n */ /**\n * The block indentation behavior that uses classes to set indentation.\n */ class IndentUsingClasses {\n    /**\n\t * The direction of indentation.\n\t */ isForward;\n    /**\n\t * A list of classes used for indentation.\n\t */ classes;\n    /**\n\t * Creates an instance of the indentation behavior.\n\t *\n\t * @param config.direction The direction of indentation.\n\t * @param config.classes A list of classes used for indentation.\n\t */ constructor(config){\n        this.isForward = config.direction === 'forward';\n        this.classes = config.classes;\n    }\n    /**\n\t * @inheritDoc\n\t */ checkEnabled(indentAttributeValue) {\n        const currentIndex = this.classes.indexOf(indentAttributeValue);\n        if (this.isForward) {\n            return currentIndex < this.classes.length - 1;\n        } else {\n            return currentIndex >= 0;\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ getNextIndent(indentAttributeValue) {\n        const currentIndex = this.classes.indexOf(indentAttributeValue);\n        const indexStep = this.isForward ? 1 : -1;\n        return this.classes[currentIndex + indexStep];\n    }\n}\n\nconst DEFAULT_ELEMENTS = [\n    'paragraph',\n    'heading1',\n    'heading2',\n    'heading3',\n    'heading4',\n    'heading5',\n    'heading6'\n];\n/**\n * The block indentation feature.\n *\n * It registers the `'indentBlock'` and `'outdentBlock'` commands.\n *\n * If the plugin {@link module:indent/indent~Indent} is defined, it also attaches the `'indentBlock'` and `'outdentBlock'` commands to\n * the `'indent'` and `'outdent'` commands.\n */ class IndentBlock extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('indentBlock', {\n            offset: 40,\n            unit: 'px'\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'IndentBlock';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const configuration = editor.config.get('indentBlock');\n        if (configuration.classes && configuration.classes.length) {\n            this._setupConversionUsingClasses(configuration.classes);\n            editor.commands.add('indentBlock', new IndentBlockCommand(editor, new IndentUsingClasses({\n                direction: 'forward',\n                classes: configuration.classes\n            })));\n            editor.commands.add('outdentBlock', new IndentBlockCommand(editor, new IndentUsingClasses({\n                direction: 'backward',\n                classes: configuration.classes\n            })));\n        } else {\n            editor.data.addStyleProcessorRules(addMarginRules);\n            this._setupConversionUsingOffset();\n            editor.commands.add('indentBlock', new IndentBlockCommand(editor, new IndentUsingOffset({\n                direction: 'forward',\n                offset: configuration.offset,\n                unit: configuration.unit\n            })));\n            editor.commands.add('outdentBlock', new IndentBlockCommand(editor, new IndentUsingOffset({\n                direction: 'backward',\n                offset: configuration.offset,\n                unit: configuration.unit\n            })));\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const indentCommand = editor.commands.get('indent');\n        const outdentCommand = editor.commands.get('outdent');\n        // Enable block indentation to heading configuration options. If it is not defined enable in paragraph and default headings.\n        const options = editor.config.get('heading.options');\n        const configuredElements = options && options.map((option)=>option.model);\n        const knownElements = configuredElements || DEFAULT_ELEMENTS;\n        knownElements.forEach((elementName)=>{\n            if (schema.isRegistered(elementName)) {\n                schema.extend(elementName, {\n                    allowAttributes: 'blockIndent'\n                });\n            }\n        });\n        schema.setAttributeProperties('blockIndent', {\n            isFormatting: true\n        });\n        indentCommand.registerChildCommand(editor.commands.get('indentBlock'));\n        outdentCommand.registerChildCommand(editor.commands.get('outdentBlock'));\n    }\n    /**\n\t * Setups conversion for using offset indents.\n\t */ _setupConversionUsingOffset() {\n        const conversion = this.editor.conversion;\n        const locale = this.editor.locale;\n        const marginProperty = locale.contentLanguageDirection === 'rtl' ? 'margin-right' : 'margin-left';\n        conversion.for('upcast').attributeToAttribute({\n            view: {\n                styles: {\n                    [marginProperty]: /[\\s\\S]+/\n                }\n            },\n            model: {\n                key: 'blockIndent',\n                value: (viewElement)=>{\n                    // Do not indent block elements in Document Lists. See https://github.com/ckeditor/ckeditor5/issues/12466.\n                    if (!viewElement.is('element', 'li')) {\n                        return viewElement.getStyle(marginProperty);\n                    }\n                }\n            }\n        });\n        conversion.for('downcast').attributeToAttribute({\n            model: 'blockIndent',\n            view: (modelAttributeValue)=>{\n                return {\n                    key: 'style',\n                    value: {\n                        [marginProperty]: modelAttributeValue\n                    }\n                };\n            }\n        });\n    }\n    /**\n\t * Setups conversion for using classes.\n\t */ _setupConversionUsingClasses(classes) {\n        const definition = {\n            model: {\n                key: 'blockIndent',\n                values: []\n            },\n            view: {}\n        };\n        for (const className of classes){\n            definition.model.values.push(className);\n            definition.view[className] = {\n                key: 'class',\n                value: [\n                    className\n                ]\n            };\n        }\n        this.editor.conversion.attributeToAttribute(definition);\n    }\n}\n\nexport { Indent, IndentBlock, IndentEditing, IndentUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module indent/indentediting\n */\n\nimport { Plugin, MultiCommand } from 'ckeditor5/src/core.js';\n\n/**\n * The indent editing feature.\n *\n * This plugin registers the `'indent'` and `'outdent'` commands.\n *\n * **Note**: In order for the commands to work, at least one of the compatible features is required. Read more in the\n * {@link module:indent/indent~Indent indent feature} API documentation.\n */\nexport default class IndentEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'IndentEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.commands.add( 'indent', new MultiCommand( editor ) );\n\t\teditor.commands.add( 'outdent', new MultiCommand( editor ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module indent/indentui\n */\n\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\nimport { icons, Plugin } from 'ckeditor5/src/core.js';\n\n/**\n * The indent UI feature.\n *\n * This plugin registers the `'indent'` and `'outdent'` buttons.\n *\n * **Note**: In order for the commands to work, at least one of the compatible features is required. Read more in\n * the {@link module:indent/indent~Indent indent feature} API documentation.\n */\nexport default class IndentUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'IndentUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst t = editor.t;\n\n\t\tconst localizedIndentIcon = locale.uiLanguageDirection == 'ltr' ? icons.indent : icons.outdent;\n\t\tconst localizedOutdentIcon = locale.uiLanguageDirection == 'ltr' ? icons.outdent : icons.indent;\n\n\t\tthis._defineButton( 'indent', t( 'Increase indent' ), localizedIndentIcon );\n\t\tthis._defineButton( 'outdent', t( 'Decrease indent' ), localizedOutdentIcon );\n\t}\n\n\t/**\n\t * Defines UI buttons for both toolbar and menu bar.\n\t */\n\tprivate _defineButton( commandName: 'indent' | 'outdent', label: string, icon: string ): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( commandName, () => {\n\t\t\tconst buttonView = this._createButton( ButtonView, commandName, label, icon );\n\n\t\t\tbuttonView.set( {\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\treturn buttonView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:' + commandName, () => {\n\t\t\treturn this._createButton( MenuBarMenuListItemButtonView, commandName, label, icon );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a button to use either in toolbar or in menu bar.\n\t */\n\tprivate _createButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>(\n\t\tButtonClass: T,\n\t\tcommandName: string,\n\t\tlabel: string,\n\t\ticon: string\n\t): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst command = editor.commands.get( commandName )!;\n\t\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\n\t\tview.set( {\n\t\t\tlabel,\n\t\t\ticon\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\n\t\t// Execute the command.\n\t\tthis.listenTo( view, 'execute', () => {\n\t\t\teditor.execute( commandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn view;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module indent/indent\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport IndentEditing from './indentediting.js';\nimport IndentUI from './indentui.js';\n\n/**\n * The indent feature.\n *\n * This plugin acts as a single entry point plugin for other features that implement indentation of elements like lists or paragraphs.\n *\n * The compatible features are:\n *\n * * The {@link module:list/list~List} or {@link module:list/list/listediting~ListEditing} feature for list indentation.\n * * The {@link module:indent/indentblock~IndentBlock} feature for block indentation.\n *\n * This is a \"glue\" plugin that loads the following plugins:\n *\n * * The {@link module:indent/indentediting~IndentEditing indent editing feature}.\n * * The {@link module:indent/indentui~IndentUI indent UI feature}.\n *\n * The dependent plugins register the `'indent'` and `'outdent'` commands and introduce the `'indent'` and `'outdent'` buttons\n * that allow to increase or decrease text indentation of supported elements.\n *\n * **Note**: In order for the commands and buttons to work, at least one of compatible features is required.\n */\nexport default class Indent extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Indent' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ IndentEditing, IndentUI ] as const;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module indent/indentblockcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport type { ListUtils } from '@ckeditor/ckeditor5-list';\nimport { first } from 'ckeditor5/src/utils.js';\n\nimport type { IndentBehavior } from './indentcommandbehavior/indentbehavior.js';\n\n/**\n * The indent block command.\n *\n * The command is registered by the {@link module:indent/indentblock~IndentBlock} as `'indentBlock'` for indenting blocks and\n * `'outdentBlock'` for outdenting blocks.\n *\n * To increase block indentation at the current selection, execute the command:\n *\n * ```ts\n * editor.execute( 'indentBlock' );\n * ```\n *\n * To decrease block indentation at the current selection, execute the command:\n *\n * ```ts\n * editor.execute( 'outdentBlock' );\n * ```\n */\nexport default class IndentBlockCommand extends Command {\n\t/**\n\t * The command's indentation behavior.\n\t */\n\tprivate readonly _indentBehavior: IndentBehavior;\n\n\t/**\n\t * Creates an instance of the command.\n\t */\n\tconstructor( editor: Editor, indentBehavior: IndentBehavior ) {\n\t\tsuper( editor );\n\n\t\tthis._indentBehavior = indentBehavior;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tconst block = first( model.document.selection.getSelectedBlocks() );\n\n\t\tif ( !block || !this._isIndentationChangeAllowed( block ) ) {\n\t\t\tthis.isEnabled = false;\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.isEnabled = this._indentBehavior.checkEnabled( block.getAttribute( 'blockIndent' ) as string );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\n\t\tconst blocksToChange = this._getBlocksToChange();\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const block of blocksToChange ) {\n\t\t\t\tconst currentIndent = block.getAttribute( 'blockIndent' ) as string;\n\n\t\t\t\tconst nextIndent = this._indentBehavior.getNextIndent( currentIndent );\n\n\t\t\t\tif ( nextIndent ) {\n\t\t\t\t\twriter.setAttribute( 'blockIndent', nextIndent, block );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'blockIndent', block );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns blocks from selection that should have blockIndent selection set.\n\t */\n\tprivate _getBlocksToChange(): Array<Element> {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst blocksInSelection = Array.from( selection.getSelectedBlocks() );\n\n\t\treturn blocksInSelection.filter( block => this._isIndentationChangeAllowed( block ) );\n\t}\n\n\t/**\n\t * Returns false if indentation cannot be applied, i.e.:\n\t * - for blocks disallowed by schema declaration\n\t * - for blocks in Document Lists (disallowed forward indentation only). See https://github.com/ckeditor/ckeditor5/issues/14155.\n\t * Otherwise returns true.\n\t */\n\tprivate _isIndentationChangeAllowed( element: Element ): boolean {\n\t\tconst editor = this.editor;\n\n\t\tif ( !editor.model.schema.checkAttribute( element, 'blockIndent' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !editor.plugins.has( 'ListUtils' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Only forward indentation is disallowed in list items. This allows the user to outdent blocks that are already indented.\n\t\tif ( !this._indentBehavior.isForward ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst documentListUtils: ListUtils = editor.plugins.get( 'ListUtils' );\n\n\t\treturn !documentListUtils.isListItemBlock( element );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module indent/indentcommandbehavior/indentusingoffset\n */\n\nimport type { IndentBehavior } from './indentbehavior.js';\n\n/**\n * The block indentation behavior that uses offsets to set indentation.\n */\nexport default class IndentUsingOffset implements IndentBehavior {\n\t/**\n\t * The direction of indentation.\n\t */\n\tpublic isForward: boolean;\n\n\t/**\n\t * The offset of the next indentation step.\n\t */\n\tpublic offset: number;\n\n\t/**\n\t * Indentation unit.\n\t */\n\tpublic unit: string;\n\n\t/**\n\t * Creates an instance of the indentation behavior.\n\t *\n\t * @param config.direction The direction of indentation.\n\t * @param config.offset The offset of the next indentation step.\n\t * @param config.unit Indentation unit.\n\t */\n\tconstructor( config: { direction: 'forward' | 'backward'; offset: number; unit: string } ) {\n\t\tthis.isForward = config.direction === 'forward';\n\t\tthis.offset = config.offset;\n\t\tthis.unit = config.unit;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic checkEnabled( indentAttributeValue: string ): boolean {\n\t\tconst currentOffset = parseFloat( indentAttributeValue || '0' );\n\n\t\t// The command is always enabled for forward indentation.\n\t\treturn this.isForward || currentOffset > 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic getNextIndent( indentAttributeValue: string ): string | undefined {\n\t\tconst currentOffset = parseFloat( indentAttributeValue || '0' );\n\t\tconst isSameUnit = !indentAttributeValue || indentAttributeValue.endsWith( this.unit );\n\n\t\tif ( !isSameUnit ) {\n\t\t\treturn this.isForward ? this.offset + this.unit : undefined;\n\t\t}\n\n\t\tconst nextOffset = this.isForward ? this.offset : -this.offset;\n\n\t\tconst offsetToSet = currentOffset + nextOffset;\n\n\t\treturn offsetToSet > 0 ? offsetToSet + this.unit : undefined;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module indent/indentcommandbehavior/indentusingclasses\n */\n\nimport type { IndentBehavior } from './indentbehavior.js';\n\n/**\n * The block indentation behavior that uses classes to set indentation.\n */\nexport default class IndentUsingClasses implements IndentBehavior {\n\t/**\n\t * The direction of indentation.\n\t */\n\tpublic isForward: boolean;\n\n\t/**\n\t * A list of classes used for indentation.\n\t */\n\tpublic classes: Array<string>;\n\n\t/**\n\t * Creates an instance of the indentation behavior.\n\t *\n\t * @param config.direction The direction of indentation.\n\t * @param config.classes A list of classes used for indentation.\n\t */\n\tconstructor( config: { direction: 'forward' | 'backward'; classes: Array<string> } ) {\n\t\tthis.isForward = config.direction === 'forward';\n\t\tthis.classes = config.classes!;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic checkEnabled( indentAttributeValue: string ): boolean {\n\t\tconst currentIndex = this.classes.indexOf( indentAttributeValue );\n\n\t\tif ( this.isForward ) {\n\t\t\treturn currentIndex < this.classes.length - 1;\n\t\t} else {\n\t\t\treturn currentIndex >= 0;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic getNextIndent( indentAttributeValue: string ): string | undefined {\n\t\tconst currentIndex = this.classes.indexOf( indentAttributeValue );\n\t\tconst indexStep = this.isForward ? 1 : -1;\n\n\t\treturn this.classes[ currentIndex + indexStep ];\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module indent/indentblock\n */\n\nimport { Plugin, type Editor, type MultiCommand } from 'ckeditor5/src/core.js';\nimport { addMarginRules, type AttributeDescriptor, type ViewElement } from 'ckeditor5/src/engine.js';\n\nimport IndentBlockCommand from './indentblockcommand.js';\nimport IndentUsingOffset from './indentcommandbehavior/indentusingoffset.js';\nimport IndentUsingClasses from './indentcommandbehavior/indentusingclasses.js';\nimport type { HeadingOption } from '@ckeditor/ckeditor5-heading';\n\nconst DEFAULT_ELEMENTS = [ 'paragraph', 'heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6' ];\n\n/**\n * The block indentation feature.\n *\n * It registers the `'indentBlock'` and `'outdentBlock'` commands.\n *\n * If the plugin {@link module:indent/indent~Indent} is defined, it also attaches the `'indentBlock'` and `'outdentBlock'` commands to\n * the `'indent'` and `'outdent'` commands.\n */\nexport default class IndentBlock extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'indentBlock', {\n\t\t\toffset: 40,\n\t\t\tunit: 'px'\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'IndentBlock' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst configuration = editor.config.get( 'indentBlock' )!;\n\n\t\tif ( configuration.classes && configuration.classes.length ) {\n\t\t\tthis._setupConversionUsingClasses( configuration.classes );\n\n\t\t\teditor.commands.add( 'indentBlock', new IndentBlockCommand( editor, new IndentUsingClasses( {\n\t\t\t\tdirection: 'forward',\n\t\t\t\tclasses: configuration.classes\n\t\t\t} ) ) );\n\n\t\t\teditor.commands.add( 'outdentBlock', new IndentBlockCommand( editor, new IndentUsingClasses( {\n\t\t\t\tdirection: 'backward',\n\t\t\t\tclasses: configuration.classes\n\t\t\t} ) ) );\n\t\t} else {\n\t\t\teditor.data.addStyleProcessorRules( addMarginRules );\n\t\t\tthis._setupConversionUsingOffset();\n\n\t\t\teditor.commands.add( 'indentBlock', new IndentBlockCommand( editor, new IndentUsingOffset( {\n\t\t\t\tdirection: 'forward',\n\t\t\t\toffset: configuration.offset!,\n\t\t\t\tunit: configuration.unit!\n\t\t\t} ) ) );\n\n\t\t\teditor.commands.add( 'outdentBlock', new IndentBlockCommand( editor, new IndentUsingOffset( {\n\t\t\t\tdirection: 'backward',\n\t\t\t\toffset: configuration.offset!,\n\t\t\t\tunit: configuration.unit!\n\t\t\t} ) ) );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\tconst indentCommand = editor.commands.get( 'indent' ) as MultiCommand;\n\t\tconst outdentCommand = editor.commands.get( 'outdent' ) as MultiCommand;\n\n\t\t// Enable block indentation to heading configuration options. If it is not defined enable in paragraph and default headings.\n\t\tconst options: Array<HeadingOption> = editor.config.get( 'heading.options' )!;\n\t\tconst configuredElements = options && options.map( option => option.model );\n\t\tconst knownElements = configuredElements || DEFAULT_ELEMENTS;\n\n\t\tknownElements.forEach( elementName => {\n\t\t\tif ( schema.isRegistered( elementName ) ) {\n\t\t\t\tschema.extend( elementName, { allowAttributes: 'blockIndent' } );\n\t\t\t}\n\t\t} );\n\n\t\tschema.setAttributeProperties( 'blockIndent', { isFormatting: true } );\n\n\t\tindentCommand.registerChildCommand( editor.commands.get( 'indentBlock' )! );\n\t\toutdentCommand.registerChildCommand( editor.commands.get( 'outdentBlock' )! );\n\t}\n\n\t/**\n\t * Setups conversion for using offset indents.\n\t */\n\tprivate _setupConversionUsingOffset(): void {\n\t\tconst conversion = this.editor.conversion;\n\t\tconst locale = this.editor.locale;\n\t\tconst marginProperty = locale.contentLanguageDirection === 'rtl' ? 'margin-right' : 'margin-left';\n\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tstyles: {\n\t\t\t\t\t[ marginProperty ]: /[\\s\\S]+/\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'blockIndent',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\t// Do not indent block elements in Document Lists. See https://github.com/ckeditor/ckeditor5/issues/12466.\n\t\t\t\t\tif ( !viewElement.is( 'element', 'li' ) ) {\n\t\t\t\t\t\treturn viewElement.getStyle( marginProperty );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tconversion.for( 'downcast' ).attributeToAttribute( {\n\t\t\tmodel: 'blockIndent',\n\t\t\tview: modelAttributeValue => {\n\t\t\t\treturn {\n\t\t\t\t\tkey: 'style',\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\t[ marginProperty as string ]: modelAttributeValue as string\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Setups conversion for using classes.\n\t */\n\tprivate _setupConversionUsingClasses( classes: Array<string> ) {\n\t\tconst definition: {\n\t\t\tmodel: { key: string; values: Array<string> };\n\t\t\tview: Record<string, AttributeDescriptor>;\n\t\t} = {\n\t\t\tmodel: {\n\t\t\t\tkey: 'blockIndent',\n\t\t\t\tvalues: []\n\t\t\t},\n\t\t\tview: {}\n\t\t};\n\n\t\tfor ( const className of classes ) {\n\t\t\tdefinition.model.values.push( className );\n\t\t\tdefinition.view[ className ] = {\n\t\t\t\tkey: 'class',\n\t\t\t\tvalue: [ className ]\n\t\t\t};\n\t\t}\n\n\t\tthis.editor.conversion.attributeToAttribute( definition );\n\t}\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { findAttributeRange, TwoStepCaretMovement, Input, inlineHighlight, Delete, TextWatcher, getLastTextLine } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\nimport { toMap, Collection, first, ObservableMixin, env, keyCodes, FocusTracker, KeystrokeHandler } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { upperFirst } from 'lodash-es';\nimport { ClickObserver, Matcher } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { View, ViewCollection, FocusCycler, submitHandler, LabeledFieldView, createLabeledInputText, ButtonView, SwitchButtonView, ContextualBalloon, CssTransitionDisablerMixin, MenuBarMenuListItemButtonView, clickOutsideHandler } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { isWidget } from '@ckeditor/ckeditor5-widget/dist/index.js';\n\n/**\n * Helper class that ties together all {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition} and provides\n * the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement downcast dispatchers} for them.\n */ class AutomaticDecorators {\n    /**\n\t * Stores the definition of {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic decorators}.\n\t * This data is used as a source for a downcast dispatcher to create a proper conversion to output data.\n\t */ _definitions = new Set();\n    /**\n\t * Gives information about the number of decorators stored in the {@link module:link/utils/automaticdecorators~AutomaticDecorators}\n\t * instance.\n\t */ get length() {\n        return this._definitions.size;\n    }\n    /**\n\t * Adds automatic decorator objects or an array with them to be used during downcasting.\n\t *\n\t * @param item A configuration object of automatic rules for decorating links. It might also be an array of such objects.\n\t */ add(item) {\n        if (Array.isArray(item)) {\n            item.forEach((item)=>this._definitions.add(item));\n        } else {\n            this._definitions.add(item);\n        }\n    }\n    /**\n\t * Provides the conversion helper used in the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add} method.\n\t *\n\t * @returns A dispatcher function used as conversion helper in {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add}.\n\t */ getDispatcher() {\n        return (dispatcher)=>{\n            dispatcher.on('attribute:linkHref', (evt, data, conversionApi)=>{\n                // There is only test as this behavior decorates links and\n                // it is run before dispatcher which actually consumes this node.\n                // This allows on writing own dispatcher with highest priority,\n                // which blocks both native converter and this additional decoration.\n                if (!conversionApi.consumable.test(data.item, 'attribute:linkHref')) {\n                    return;\n                }\n                // Automatic decorators for block links are handled e.g. in LinkImageEditing.\n                if (!(data.item.is('selection') || conversionApi.schema.isInline(data.item))) {\n                    return;\n                }\n                const viewWriter = conversionApi.writer;\n                const viewSelection = viewWriter.document.selection;\n                for (const item of this._definitions){\n                    const viewElement = viewWriter.createAttributeElement('a', item.attributes, {\n                        priority: 5\n                    });\n                    if (item.classes) {\n                        viewWriter.addClass(item.classes, viewElement);\n                    }\n                    for(const key in item.styles){\n                        viewWriter.setStyle(key, item.styles[key], viewElement);\n                    }\n                    viewWriter.setCustomProperty('link', true, viewElement);\n                    if (item.callback(data.attributeNewValue)) {\n                        if (data.item.is('selection')) {\n                            viewWriter.wrap(viewSelection.getFirstRange(), viewElement);\n                        } else {\n                            viewWriter.wrap(conversionApi.mapper.toViewRange(data.range), viewElement);\n                        }\n                    } else {\n                        viewWriter.unwrap(conversionApi.mapper.toViewRange(data.range), viewElement);\n                    }\n                }\n            }, {\n                priority: 'high'\n            });\n        };\n    }\n    /**\n\t * Provides the conversion helper used in the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add} method\n\t * when linking images.\n\t *\n\t * @returns A dispatcher function used as conversion helper in {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add}.\n\t */ getDispatcherForLinkedImage() {\n        return (dispatcher)=>{\n            dispatcher.on('attribute:linkHref:imageBlock', (evt, data, { writer, mapper })=>{\n                const viewFigure = mapper.toViewElement(data.item);\n                const linkInImage = Array.from(viewFigure.getChildren()).find((child)=>child.is('element', 'a'));\n                // It's not guaranteed that the anchor is present in the image block during execution of this dispatcher.\n                // It might have been removed during the execution of unlink command that runs the image link downcast dispatcher\n                // that is executed before this one and removes the anchor from the image block.\n                if (!linkInImage) {\n                    return;\n                }\n                for (const item of this._definitions){\n                    const attributes = toMap(item.attributes);\n                    if (item.callback(data.attributeNewValue)) {\n                        for (const [key, val] of attributes){\n                            // Left for backward compatibility. Since v30 decorator should\n                            // accept `classes` and `styles` separately from `attributes`.\n                            if (key === 'class') {\n                                writer.addClass(val, linkInImage);\n                            } else {\n                                writer.setAttribute(key, val, linkInImage);\n                            }\n                        }\n                        if (item.classes) {\n                            writer.addClass(item.classes, linkInImage);\n                        }\n                        for(const key in item.styles){\n                            writer.setStyle(key, item.styles[key], linkInImage);\n                        }\n                    } else {\n                        for (const [key, val] of attributes){\n                            if (key === 'class') {\n                                writer.removeClass(val, linkInImage);\n                            } else {\n                                writer.removeAttribute(key, linkInImage);\n                            }\n                        }\n                        if (item.classes) {\n                            writer.removeClass(item.classes, linkInImage);\n                        }\n                        for(const key in item.styles){\n                            writer.removeStyle(key, linkInImage);\n                        }\n                    }\n                }\n            });\n        };\n    }\n}\n\nconst ATTRIBUTE_WHITESPACES = /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205f\\u3000]/g; // eslint-disable-line no-control-regex\nconst SAFE_URL_TEMPLATE = '^(?:(?:<protocols>):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))';\n// Simplified email test - should be run over previously found URL.\nconst EMAIL_REG_EXP = /^[\\S]+@((?![-_])(?:[-\\w\\u00a1-\\uffff]{0,63}[^-_]\\.))+(?:[a-z\\u00a1-\\uffff]{2,})$/i;\n// The regex checks for the protocol syntax ('xxxx://' or 'xxxx:')\n// or non-word characters at the beginning of the link ('/', '#' etc.).\nconst PROTOCOL_REG_EXP = /^((\\w+:(\\/{2,})?)|(\\W))/i;\nconst DEFAULT_LINK_PROTOCOLS = [\n    'https?',\n    'ftps?',\n    'mailto'\n];\n/**\n * A keystroke used by the {@link module:link/linkui~LinkUI link UI feature}.\n */ const LINK_KEYSTROKE = 'Ctrl+K';\n/**\n * Returns `true` if a given view node is the link element.\n */ function isLinkElement(node) {\n    return node.is('attributeElement') && !!node.getCustomProperty('link');\n}\n/**\n * Creates a link {@link module:engine/view/attributeelement~AttributeElement} with the provided `href` attribute.\n */ function createLinkElement(href, { writer }) {\n    // Priority 5 - https://github.com/ckeditor/ckeditor5-link/issues/121.\n    const linkElement = writer.createAttributeElement('a', {\n        href\n    }, {\n        priority: 5\n    });\n    writer.setCustomProperty('link', true, linkElement);\n    return linkElement;\n}\n/**\n * Returns a safe URL based on a given value.\n *\n * A URL is considered safe if it is safe for the user (does not contain any malicious code).\n *\n * If a URL is considered unsafe, a simple `\"#\"` is returned.\n *\n * @internal\n */ function ensureSafeUrl(url, allowedProtocols = DEFAULT_LINK_PROTOCOLS) {\n    const urlString = String(url);\n    const protocolsList = allowedProtocols.join('|');\n    const customSafeRegex = new RegExp(`${SAFE_URL_TEMPLATE.replace('<protocols>', protocolsList)}`, 'i');\n    return isSafeUrl(urlString, customSafeRegex) ? urlString : '#';\n}\n/**\n * Checks whether the given URL is safe for the user (does not contain any malicious code).\n */ function isSafeUrl(url, customRegexp) {\n    const normalizedUrl = url.replace(ATTRIBUTE_WHITESPACES, '');\n    return !!normalizedUrl.match(customRegexp);\n}\n/**\n * Returns the {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`} configuration processed\n * to respect the locale of the editor, i.e. to display the {@link module:link/linkconfig~LinkDecoratorManualDefinition label}\n * in the correct language.\n *\n * **Note**: Only the few most commonly used labels are translated automatically. Other labels should be manually\n * translated in the {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`} configuration.\n *\n * @param t Shorthand for {@link module:utils/locale~Locale#t Locale#t}.\n * @param decorators The decorator reference where the label values should be localized.\n */ function getLocalizedDecorators(t, decorators) {\n    const localizedDecoratorsLabels = {\n        'Open in a new tab': t('Open in a new tab'),\n        'Downloadable': t('Downloadable')\n    };\n    decorators.forEach((decorator)=>{\n        if ('label' in decorator && localizedDecoratorsLabels[decorator.label]) {\n            decorator.label = localizedDecoratorsLabels[decorator.label];\n        }\n        return decorator;\n    });\n    return decorators;\n}\n/**\n * Converts an object with defined decorators to a normalized array of decorators. The `id` key is added for each decorator and\n * is used as the attribute's name in the model.\n */ function normalizeDecorators(decorators) {\n    const retArray = [];\n    if (decorators) {\n        for (const [key, value] of Object.entries(decorators)){\n            const decorator = Object.assign({}, value, {\n                id: `link${upperFirst(key)}`\n            });\n            retArray.push(decorator);\n        }\n    }\n    return retArray;\n}\n/**\n * Returns `true` if the specified `element` can be linked (the element allows the `linkHref` attribute).\n */ function isLinkableElement(element, schema) {\n    if (!element) {\n        return false;\n    }\n    return schema.checkAttribute(element.name, 'linkHref');\n}\n/**\n * Returns `true` if the specified `value` is an email.\n */ function isEmail(value) {\n    return EMAIL_REG_EXP.test(value);\n}\n/**\n * Adds the protocol prefix to the specified `link` when:\n *\n * * it does not contain it already, and there is a {@link module:link/linkconfig~LinkConfig#defaultProtocol `defaultProtocol` }\n * configuration value provided,\n * * or the link is an email address.\n */ function addLinkProtocolIfApplicable(link, defaultProtocol) {\n    const protocol = isEmail(link) ? 'mailto:' : defaultProtocol;\n    const isProtocolNeeded = !!protocol && !linkHasProtocol(link);\n    return link && isProtocolNeeded ? protocol + link : link;\n}\n/**\n * Checks if protocol is already included in the link.\n */ function linkHasProtocol(link) {\n    return PROTOCOL_REG_EXP.test(link);\n}\n/**\n * Opens the link in a new browser tab.\n */ function openLink(link) {\n    window.open(link, '_blank', 'noopener');\n}\n\n/**\n * The link command. It is used by the {@link module:link/link~Link link feature}.\n */ class LinkCommand extends Command {\n    /**\n\t * A collection of {@link module:link/utils/manualdecorator~ManualDecorator manual decorators}\n\t * corresponding to the {@link module:link/linkconfig~LinkConfig#decorators decorator configuration}.\n\t *\n\t * You can consider it a model with states of manual decorators added to the currently selected link.\n\t */ manualDecorators = new Collection();\n    /**\n\t * An instance of the helper that ties together all {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition}\n\t * that are used by the {@glink features/link link} and the {@glink features/images/images-linking linking images} features.\n\t */ automaticDecorators = new AutomaticDecorators();\n    /**\n\t * Synchronizes the state of {@link #manualDecorators} with the currently present elements in the model.\n\t */ restoreManualDecoratorStates() {\n        for (const manualDecorator of this.manualDecorators){\n            manualDecorator.value = this._getDecoratorStateFromModel(manualDecorator.id);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const selectedElement = selection.getSelectedElement() || first(selection.getSelectedBlocks());\n        // A check for any integration that allows linking elements (e.g. `LinkImage`).\n        // Currently the selection reads attributes from text nodes only. See #7429 and #7465.\n        if (isLinkableElement(selectedElement, model.schema)) {\n            this.value = selectedElement.getAttribute('linkHref');\n            this.isEnabled = model.schema.checkAttribute(selectedElement, 'linkHref');\n        } else {\n            this.value = selection.getAttribute('linkHref');\n            this.isEnabled = model.schema.checkAttributeInSelection(selection, 'linkHref');\n        }\n        for (const manualDecorator of this.manualDecorators){\n            manualDecorator.value = this._getDecoratorStateFromModel(manualDecorator.id);\n        }\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * When the selection is non-collapsed, the `linkHref` attribute will be applied to nodes inside the selection, but only to\n\t * those nodes where the `linkHref` attribute is allowed (disallowed nodes will be omitted).\n\t *\n\t * When the selection is collapsed and is not inside the text with the `linkHref` attribute, a\n\t * new {@link module:engine/model/text~Text text node} with the `linkHref` attribute will be inserted in place of the caret, but\n\t * only if such element is allowed in this place. The `_data` of the inserted text will equal the `href` parameter.\n\t * The selection will be updated to wrap the just inserted text node.\n\t *\n\t * When the selection is collapsed and inside the text with the `linkHref` attribute, the attribute value will be updated.\n\t *\n\t * # Decorators and model attribute management\n\t *\n\t * There is an optional argument to this command that applies or removes model\n\t * {@glink framework/architecture/editing-engine#text-attributes text attributes} brought by\n\t * {@link module:link/utils/manualdecorator~ManualDecorator manual link decorators}.\n\t *\n\t * Text attribute names in the model correspond to the entries in the {@link module:link/linkconfig~LinkConfig#decorators\n\t * configuration}.\n\t * For every decorator configured, a model text attribute exists with the \"link\" prefix. For example, a `'linkMyDecorator'` attribute\n\t * corresponds to `'myDecorator'` in the configuration.\n\t *\n\t * To learn more about link decorators, check out the {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`}\n\t * documentation.\n\t *\n\t * Here is how to manage decorator attributes with the link command:\n\t *\n\t * ```ts\n\t * const linkCommand = editor.commands.get( 'link' );\n\t *\n\t * // Adding a new decorator attribute.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: true\n\t * } );\n\t *\n\t * // Removing a decorator attribute from the selection.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: false\n\t * } );\n\t *\n\t * // Adding multiple decorator attributes at the same time.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: true,\n\t * \tlinkIsDownloadable: true,\n\t * } );\n\t *\n\t * // Removing and adding decorator attributes at the same time.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: false,\n\t * \tlinkFoo: true,\n\t * \tlinkIsDownloadable: false,\n\t * } );\n\t * ```\n\t *\n\t * **Note**: If the decorator attribute name is not specified, its state remains untouched.\n\t *\n\t * **Note**: {@link module:link/unlinkcommand~UnlinkCommand#execute `UnlinkCommand#execute()`} removes all\n\t * decorator attributes.\n\t *\n\t * @fires execute\n\t * @param href Link destination.\n\t * @param manualDecoratorIds The information about manual decorator attributes to be applied or removed upon execution.\n\t */ execute(href, manualDecoratorIds = {}) {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        // Stores information about manual decorators to turn them on/off when command is applied.\n        const truthyManualDecorators = [];\n        const falsyManualDecorators = [];\n        for(const name in manualDecoratorIds){\n            if (manualDecoratorIds[name]) {\n                truthyManualDecorators.push(name);\n            } else {\n                falsyManualDecorators.push(name);\n            }\n        }\n        model.change((writer)=>{\n            // If selection is collapsed then update selected link or insert new one at the place of caret.\n            if (selection.isCollapsed) {\n                const position = selection.getFirstPosition();\n                // When selection is inside text with `linkHref` attribute.\n                if (selection.hasAttribute('linkHref')) {\n                    const linkText = extractTextFromSelection(selection);\n                    // Then update `linkHref` value.\n                    let linkRange = findAttributeRange(position, 'linkHref', selection.getAttribute('linkHref'), model);\n                    if (selection.getAttribute('linkHref') === linkText) {\n                        linkRange = this._updateLinkContent(model, writer, linkRange, href);\n                    }\n                    writer.setAttribute('linkHref', href, linkRange);\n                    truthyManualDecorators.forEach((item)=>{\n                        writer.setAttribute(item, true, linkRange);\n                    });\n                    falsyManualDecorators.forEach((item)=>{\n                        writer.removeAttribute(item, linkRange);\n                    });\n                    // Put the selection at the end of the updated link.\n                    writer.setSelection(writer.createPositionAfter(linkRange.end.nodeBefore));\n                } else if (href !== '') {\n                    const attributes = toMap(selection.getAttributes());\n                    attributes.set('linkHref', href);\n                    truthyManualDecorators.forEach((item)=>{\n                        attributes.set(item, true);\n                    });\n                    const { end: positionAfter } = model.insertContent(writer.createText(href, attributes), position);\n                    // Put the selection at the end of the inserted link.\n                    // Using end of range returned from insertContent in case nodes with the same attributes got merged.\n                    writer.setSelection(positionAfter);\n                }\n                // Remove the `linkHref` attribute and all link decorators from the selection.\n                // It stops adding a new content into the link element.\n                [\n                    'linkHref',\n                    ...truthyManualDecorators,\n                    ...falsyManualDecorators\n                ].forEach((item)=>{\n                    writer.removeSelectionAttribute(item);\n                });\n            } else {\n                // If selection has non-collapsed ranges, we change attribute on nodes inside those ranges\n                // omitting nodes where the `linkHref` attribute is disallowed.\n                const ranges = model.schema.getValidRanges(selection.getRanges(), 'linkHref');\n                // But for the first, check whether the `linkHref` attribute is allowed on selected blocks (e.g. the \"image\" element).\n                const allowedRanges = [];\n                for (const element of selection.getSelectedBlocks()){\n                    if (model.schema.checkAttribute(element, 'linkHref')) {\n                        allowedRanges.push(writer.createRangeOn(element));\n                    }\n                }\n                // Ranges that accept the `linkHref` attribute. Since we will iterate over `allowedRanges`, let's clone it.\n                const rangesToUpdate = allowedRanges.slice();\n                // For all selection ranges we want to check whether given range is inside an element that accepts the `linkHref` attribute.\n                // If so, we don't want to propagate applying the attribute to its children.\n                for (const range of ranges){\n                    if (this._isRangeToUpdate(range, allowedRanges)) {\n                        rangesToUpdate.push(range);\n                    }\n                }\n                for (const range of rangesToUpdate){\n                    let linkRange = range;\n                    if (rangesToUpdate.length === 1) {\n                        // Current text of the link in the document.\n                        const linkText = extractTextFromSelection(selection);\n                        if (selection.getAttribute('linkHref') === linkText) {\n                            linkRange = this._updateLinkContent(model, writer, range, href);\n                            writer.setSelection(writer.createSelection(linkRange));\n                        }\n                    }\n                    writer.setAttribute('linkHref', href, linkRange);\n                    truthyManualDecorators.forEach((item)=>{\n                        writer.setAttribute(item, true, linkRange);\n                    });\n                    falsyManualDecorators.forEach((item)=>{\n                        writer.removeAttribute(item, linkRange);\n                    });\n                }\n            }\n        });\n    }\n    /**\n\t * Provides information whether a decorator with a given name is present in the currently processed selection.\n\t *\n\t * @param decoratorName The name of the manual decorator used in the model\n\t * @returns The information whether a given decorator is currently present in the selection.\n\t */ _getDecoratorStateFromModel(decoratorName) {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const selectedElement = selection.getSelectedElement();\n        // A check for the `LinkImage` plugin. If the selection contains an element, get values from the element.\n        // Currently the selection reads attributes from text nodes only. See #7429 and #7465.\n        if (isLinkableElement(selectedElement, model.schema)) {\n            return selectedElement.getAttribute(decoratorName);\n        }\n        return selection.getAttribute(decoratorName);\n    }\n    /**\n\t * Checks whether specified `range` is inside an element that accepts the `linkHref` attribute.\n\t *\n\t * @param range A range to check.\n\t * @param allowedRanges An array of ranges created on elements where the attribute is accepted.\n\t */ _isRangeToUpdate(range, allowedRanges) {\n        for (const allowedRange of allowedRanges){\n            // A range is inside an element that will have the `linkHref` attribute. Do not modify its nodes.\n            if (allowedRange.containsRange(range)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Updates selected link with a new value as its content and as its href attribute.\n\t *\n\t * @param model Model is need to insert content.\n\t * @param writer Writer is need to create text element in model.\n\t * @param range A range where should be inserted content.\n\t * @param href A link value which should be in the href attribute and in the content.\n\t */ _updateLinkContent(model, writer, range, href) {\n        const text = writer.createText(href, {\n            linkHref: href\n        });\n        return model.insertContent(text, range);\n    }\n}\n// Returns a text of a link under the collapsed selection or a selection that contains the entire link.\nfunction extractTextFromSelection(selection) {\n    if (selection.isCollapsed) {\n        const firstPosition = selection.getFirstPosition();\n        return firstPosition.textNode && firstPosition.textNode.data;\n    } else {\n        const rangeItems = Array.from(selection.getFirstRange().getItems());\n        if (rangeItems.length > 1) {\n            return null;\n        }\n        const firstNode = rangeItems[0];\n        if (firstNode.is('$text') || firstNode.is('$textProxy')) {\n            return firstNode.data;\n        }\n        return null;\n    }\n}\n\n/**\n * The unlink command. It is used by the {@link module:link/link~Link link plugin}.\n */ class UnlinkCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const selectedElement = selection.getSelectedElement();\n        // A check for any integration that allows linking elements (e.g. `LinkImage`).\n        // Currently the selection reads attributes from text nodes only. See #7429 and #7465.\n        if (isLinkableElement(selectedElement, model.schema)) {\n            this.isEnabled = model.schema.checkAttribute(selectedElement, 'linkHref');\n        } else {\n            this.isEnabled = model.schema.checkAttributeInSelection(selection, 'linkHref');\n        }\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * When the selection is collapsed, it removes the `linkHref` attribute from each node with the same `linkHref` attribute value.\n\t * When the selection is non-collapsed, it removes the `linkHref` attribute from each node in selected ranges.\n\t *\n\t * # Decorators\n\t *\n\t * If {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`} is specified,\n\t * all configured decorators are removed together with the `linkHref` attribute.\n\t *\n\t * @fires execute\n\t */ execute() {\n        const editor = this.editor;\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const linkCommand = editor.commands.get('link');\n        model.change((writer)=>{\n            // Get ranges to unlink.\n            const rangesToUnlink = selection.isCollapsed ? [\n                findAttributeRange(selection.getFirstPosition(), 'linkHref', selection.getAttribute('linkHref'), model)\n            ] : model.schema.getValidRanges(selection.getRanges(), 'linkHref');\n            // Remove `linkHref` attribute from specified ranges.\n            for (const range of rangesToUnlink){\n                writer.removeAttribute('linkHref', range);\n                // If there are registered custom attributes, then remove them during unlink.\n                if (linkCommand) {\n                    for (const manualDecorator of linkCommand.manualDecorators){\n                        writer.removeAttribute(manualDecorator.id, range);\n                    }\n                }\n            }\n        });\n    }\n}\n\n/**\n * Helper class that stores manual decorators with observable {@link module:link/utils/manualdecorator~ManualDecorator#value}\n * to support integration with the UI state. An instance of this class is a model with the state of individual manual decorators.\n * These decorators are kept as collections in {@link module:link/linkcommand~LinkCommand#manualDecorators}.\n */ class ManualDecorator extends /* #__PURE__ */ ObservableMixin() {\n    /**\n\t * An ID of a manual decorator which is the name of the attribute in the model, for example: 'linkManualDecorator0'.\n\t */ id;\n    /**\n\t * The default value of manual decorator.\n\t */ defaultValue;\n    /**\n\t * The label used in the user interface to toggle the manual decorator.\n\t */ label;\n    /**\n\t * A set of attributes added to downcasted data when the decorator is activated for a specific link.\n\t * Attributes should be added in a form of attributes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t */ attributes;\n    /**\n\t * A set of classes added to downcasted data when the decorator is activated for a specific link.\n\t * Classes should be added in a form of classes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t */ classes;\n    /**\n\t * A set of styles added to downcasted data when the decorator is activated for a specific link.\n\t * Styles should be added in a form of styles defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t */ styles;\n    /**\n\t * Creates a new instance of {@link module:link/utils/manualdecorator~ManualDecorator}.\n\t *\n\t * @param config.id The name of the attribute used in the model that represents a given manual decorator.\n\t * For example: `'linkIsExternal'`.\n\t * @param config.label The label used in the user interface to toggle the manual decorator.\n\t * @param config.attributes A set of attributes added to output data when the decorator is active for a specific link.\n\t * Attributes should keep the format of attributes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t * @param [config.defaultValue] Controls whether the decorator is \"on\" by default.\n\t */ constructor({ id, label, attributes, classes, styles, defaultValue }){\n        super();\n        this.id = id;\n        this.set('value', undefined);\n        this.defaultValue = defaultValue;\n        this.label = label;\n        this.attributes = attributes;\n        this.classes = classes;\n        this.styles = styles;\n    }\n    /**\n\t * Returns {@link module:engine/view/matcher~MatcherPattern} with decorator attributes.\n\t *\n\t * @internal\n\t */ _createPattern() {\n        return {\n            attributes: this.attributes,\n            classes: this.classes,\n            styles: this.styles\n        };\n    }\n}\n\nconst HIGHLIGHT_CLASS = 'ck-link_selected';\nconst DECORATOR_AUTOMATIC = 'automatic';\nconst DECORATOR_MANUAL = 'manual';\nconst EXTERNAL_LINKS_REGEXP = /^(https?:)?\\/\\//;\n/**\n * The link engine feature.\n *\n * It introduces the `linkHref=\"url\"` attribute in the model which renders to the view as a `<a href=\"url\">` element\n * as well as `'link'` and `'unlink'` commands.\n */ class LinkEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LinkEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        // Clipboard is required for handling cut and paste events while typing over the link.\n        return [\n            TwoStepCaretMovement,\n            Input,\n            ClipboardPipeline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('link', {\n            allowCreatingEmptyLinks: false,\n            addTargetToExternalLinks: false\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const allowedProtocols = this.editor.config.get('link.allowedProtocols');\n        // Allow link attribute on all inline nodes.\n        editor.model.schema.extend('$text', {\n            allowAttributes: 'linkHref'\n        });\n        editor.conversion.for('dataDowncast').attributeToElement({\n            model: 'linkHref',\n            view: createLinkElement\n        });\n        editor.conversion.for('editingDowncast').attributeToElement({\n            model: 'linkHref',\n            view: (href, conversionApi)=>{\n                return createLinkElement(ensureSafeUrl(href, allowedProtocols), conversionApi);\n            }\n        });\n        editor.conversion.for('upcast').elementToAttribute({\n            view: {\n                name: 'a',\n                attributes: {\n                    href: true\n                }\n            },\n            model: {\n                key: 'linkHref',\n                value: (viewElement)=>viewElement.getAttribute('href')\n            }\n        });\n        // Create linking commands.\n        editor.commands.add('link', new LinkCommand(editor));\n        editor.commands.add('unlink', new UnlinkCommand(editor));\n        const linkDecorators = getLocalizedDecorators(editor.t, normalizeDecorators(editor.config.get('link.decorators')));\n        this._enableAutomaticDecorators(linkDecorators.filter((item)=>item.mode === DECORATOR_AUTOMATIC));\n        this._enableManualDecorators(linkDecorators.filter((item)=>item.mode === DECORATOR_MANUAL));\n        // Enable two-step caret movement for `linkHref` attribute.\n        const twoStepCaretMovementPlugin = editor.plugins.get(TwoStepCaretMovement);\n        twoStepCaretMovementPlugin.registerAttribute('linkHref');\n        // Setup highlight over selected link.\n        inlineHighlight(editor, 'linkHref', 'a', HIGHLIGHT_CLASS);\n        // Handle link following by CTRL+click or ALT+ENTER\n        this._enableLinkOpen();\n        // Clears the DocumentSelection decorator attributes if the selection is no longer in a link (for example while using 2-SCM).\n        this._enableSelectionAttributesFixer();\n        // Handle adding default protocol to pasted links.\n        this._enableClipboardIntegration();\n    }\n    /**\n\t * Processes an array of configured {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic decorators}\n\t * and registers a {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher downcast dispatcher}\n\t * for each one of them. Downcast dispatchers are obtained using the\n\t * {@link module:link/utils/automaticdecorators~AutomaticDecorators#getDispatcher} method.\n\t *\n\t * **Note**: This method also activates the automatic external link decorator if enabled with\n\t * {@link module:link/linkconfig~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`}.\n\t */ _enableAutomaticDecorators(automaticDecoratorDefinitions) {\n        const editor = this.editor;\n        // Store automatic decorators in the command instance as we do the same with manual decorators.\n        // Thanks to that, `LinkImageEditing` plugin can re-use the same definitions.\n        const command = editor.commands.get('link');\n        const automaticDecorators = command.automaticDecorators;\n        // Adds a default decorator for external links.\n        if (editor.config.get('link.addTargetToExternalLinks')) {\n            automaticDecorators.add({\n                id: 'linkIsExternal',\n                mode: DECORATOR_AUTOMATIC,\n                callback: (url)=>!!url && EXTERNAL_LINKS_REGEXP.test(url),\n                attributes: {\n                    target: '_blank',\n                    rel: 'noopener noreferrer'\n                }\n            });\n        }\n        automaticDecorators.add(automaticDecoratorDefinitions);\n        if (automaticDecorators.length) {\n            editor.conversion.for('downcast').add(automaticDecorators.getDispatcher());\n        }\n    }\n    /**\n\t * Processes an array of configured {@link module:link/linkconfig~LinkDecoratorManualDefinition manual decorators},\n\t * transforms them into {@link module:link/utils/manualdecorator~ManualDecorator} instances and stores them in the\n\t * {@link module:link/linkcommand~LinkCommand#manualDecorators} collection (a model for manual decorators state).\n\t *\n\t * Also registers an {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement attribute-to-element}\n\t * converter for each manual decorator and extends the {@link module:engine/model/schema~Schema model's schema}\n\t * with adequate model attributes.\n\t */ _enableManualDecorators(manualDecoratorDefinitions) {\n        if (!manualDecoratorDefinitions.length) {\n            return;\n        }\n        const editor = this.editor;\n        const command = editor.commands.get('link');\n        const manualDecorators = command.manualDecorators;\n        manualDecoratorDefinitions.forEach((decoratorDefinition)=>{\n            editor.model.schema.extend('$text', {\n                allowAttributes: decoratorDefinition.id\n            });\n            // Keeps reference to manual decorator to decode its name to attributes during downcast.\n            const decorator = new ManualDecorator(decoratorDefinition);\n            manualDecorators.add(decorator);\n            editor.conversion.for('downcast').attributeToElement({\n                model: decorator.id,\n                view: (manualDecoratorValue, { writer, schema }, { item })=>{\n                    // Manual decorators for block links are handled e.g. in LinkImageEditing.\n                    if (!(item.is('selection') || schema.isInline(item))) {\n                        return;\n                    }\n                    if (manualDecoratorValue) {\n                        const element = writer.createAttributeElement('a', decorator.attributes, {\n                            priority: 5\n                        });\n                        if (decorator.classes) {\n                            writer.addClass(decorator.classes, element);\n                        }\n                        for(const key in decorator.styles){\n                            writer.setStyle(key, decorator.styles[key], element);\n                        }\n                        writer.setCustomProperty('link', true, element);\n                        return element;\n                    }\n                }\n            });\n            editor.conversion.for('upcast').elementToAttribute({\n                view: {\n                    name: 'a',\n                    ...decorator._createPattern()\n                },\n                model: {\n                    key: decorator.id\n                }\n            });\n        });\n    }\n    /**\n\t * Attaches handlers for {@link module:engine/view/document~Document#event:enter} and\n\t * {@link module:engine/view/document~Document#event:click} to enable link following.\n\t */ _enableLinkOpen() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        this.listenTo(viewDocument, 'click', (evt, data)=>{\n            const shouldOpen = env.isMac ? data.domEvent.metaKey : data.domEvent.ctrlKey;\n            if (!shouldOpen) {\n                return;\n            }\n            let clickedElement = data.domTarget;\n            if (clickedElement.tagName.toLowerCase() != 'a') {\n                clickedElement = clickedElement.closest('a');\n            }\n            if (!clickedElement) {\n                return;\n            }\n            const url = clickedElement.getAttribute('href');\n            if (!url) {\n                return;\n            }\n            evt.stop();\n            data.preventDefault();\n            openLink(url);\n        }, {\n            context: '$capture'\n        });\n        // Open link on Alt+Enter.\n        this.listenTo(viewDocument, 'keydown', (evt, data)=>{\n            const linkCommand = editor.commands.get('link');\n            const url = linkCommand.value;\n            const shouldOpen = !!url && data.keyCode === keyCodes.enter && data.altKey;\n            if (!shouldOpen) {\n                return;\n            }\n            evt.stop();\n            openLink(url);\n        });\n    }\n    /**\n\t * Watches the DocumentSelection attribute changes and removes link decorator attributes when the linkHref attribute is removed.\n\t *\n\t * This is to ensure that there is no left-over link decorator attributes on the document selection that is no longer in a link.\n\t */ _enableSelectionAttributesFixer() {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        this.listenTo(selection, 'change:attribute', (evt, { attributeKeys })=>{\n            if (!attributeKeys.includes('linkHref') || selection.hasAttribute('linkHref')) {\n                return;\n            }\n            model.change((writer)=>{\n                removeLinkAttributesFromSelection(writer, getLinkAttributesAllowedOnText(model.schema));\n            });\n        });\n    }\n    /**\n\t * Enables URL fixing on pasting.\n\t */ _enableClipboardIntegration() {\n        const editor = this.editor;\n        const model = editor.model;\n        const defaultProtocol = this.editor.config.get('link.defaultProtocol');\n        if (!defaultProtocol) {\n            return;\n        }\n        this.listenTo(editor.plugins.get('ClipboardPipeline'), 'contentInsertion', (evt, data)=>{\n            model.change((writer)=>{\n                const range = writer.createRangeIn(data.content);\n                for (const item of range.getItems()){\n                    if (item.hasAttribute('linkHref')) {\n                        const newLink = addLinkProtocolIfApplicable(item.getAttribute('linkHref'), defaultProtocol);\n                        writer.setAttribute('linkHref', newLink, item);\n                    }\n                }\n            });\n        });\n    }\n}\n/**\n * Make the selection free of link-related model attributes.\n * All link-related model attributes start with \"link\". That includes not only \"linkHref\"\n * but also all decorator attributes (they have dynamic names), or even custom plugins.\n */ function removeLinkAttributesFromSelection(writer, linkAttributes) {\n    writer.removeSelectionAttribute('linkHref');\n    for (const attribute of linkAttributes){\n        writer.removeSelectionAttribute(attribute);\n    }\n}\n/**\n * Returns an array containing names of the attributes allowed on `$text` that describes the link item.\n */ function getLinkAttributesAllowedOnText(schema) {\n    const textAttributes = schema.getDefinition('$text').allowAttributes;\n    return textAttributes.filter((attribute)=>attribute.startsWith('link'));\n}\n\n/**\n * The link form view controller class.\n *\n * See {@link module:link/ui/linkformview~LinkFormView}.\n */ class LinkFormView extends View {\n    /**\n\t * Tracks information about DOM focus in the form.\n\t */ focusTracker = new FocusTracker();\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes = new KeystrokeHandler();\n    /**\n\t * The URL input view.\n\t */ urlInputView;\n    /**\n\t * The Save button view.\n\t */ saveButtonView;\n    /**\n\t * The Cancel button view.\n\t */ cancelButtonView;\n    /**\n\t * A collection of {@link module:ui/button/switchbuttonview~SwitchButtonView},\n\t * which corresponds to {@link module:link/linkcommand~LinkCommand#manualDecorators manual decorators}\n\t * configured in the editor.\n\t */ _manualDecoratorSwitches;\n    /**\n\t * A collection of child views in the form.\n\t */ children;\n    /**\n\t * An array of form validators used by {@link #isValid}.\n\t */ _validators;\n    /**\n\t * A collection of views that can be focused in the form.\n\t */ _focusables = new ViewCollection();\n    /**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */ _focusCycler;\n    /**\n\t * Creates an instance of the {@link module:link/ui/linkformview~LinkFormView} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param linkCommand Reference to {@link module:link/linkcommand~LinkCommand}.\n\t * @param validators  Form validators used by {@link #isValid}.\n\t */ constructor(locale, linkCommand, validators){\n        super(locale);\n        const t = locale.t;\n        this._validators = validators;\n        this.urlInputView = this._createUrlInput();\n        this.saveButtonView = this._createButton(t('Save'), icons.check, 'ck-button-save');\n        this.saveButtonView.type = 'submit';\n        this.cancelButtonView = this._createButton(t('Cancel'), icons.cancel, 'ck-button-cancel', 'cancel');\n        this._manualDecoratorSwitches = this._createManualDecoratorSwitches(linkCommand);\n        this.children = this._createFormChildren(linkCommand.manualDecorators);\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        const classList = [\n            'ck',\n            'ck-link-form',\n            'ck-responsive-form'\n        ];\n        if (linkCommand.manualDecorators.length) {\n            classList.push('ck-link-form_layout-vertical', 'ck-vertical-form');\n        }\n        this.setTemplate({\n            tag: 'form',\n            attributes: {\n                class: classList,\n                // https://github.com/ckeditor/ckeditor5-link/issues/90\n                tabindex: '-1'\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * Obtains the state of the {@link module:ui/button/switchbuttonview~SwitchButtonView switch buttons} representing\n\t * {@link module:link/linkcommand~LinkCommand#manualDecorators manual link decorators}\n\t * in the {@link module:link/ui/linkformview~LinkFormView}.\n\t *\n\t * @returns Key-value pairs, where the key is the name of the decorator and the value is its state.\n\t */ getDecoratorSwitchesState() {\n        return Array.from(this._manualDecoratorSwitches).reduce((accumulator, switchButton)=>{\n            accumulator[switchButton.name] = switchButton.isOn;\n            return accumulator;\n        }, {});\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        submitHandler({\n            view: this\n        });\n        const childViews = [\n            this.urlInputView,\n            ...this._manualDecoratorSwitches,\n            this.saveButtonView,\n            this.cancelButtonView\n        ];\n        childViews.forEach((v)=>{\n            // Register the view as focusable.\n            this._focusables.add(v);\n            // Register the view in the focus tracker.\n            this.focusTracker.add(v.element);\n        });\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the fist {@link #_focusables} in the form.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Validates the form and returns `false` when some fields are invalid.\n\t */ isValid() {\n        this.resetFormStatus();\n        for (const validator of this._validators){\n            const errorText = validator(this);\n            // One error per field is enough.\n            if (errorText) {\n                // Apply updated error.\n                this.urlInputView.errorText = errorText;\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Cleans up the supplementary error and information text of the {@link #urlInputView}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */ resetFormStatus() {\n        this.urlInputView.errorText = null;\n    }\n    /**\n\t * Creates a labeled input view.\n\t *\n\t * @returns Labeled field view instance.\n\t */ _createUrlInput() {\n        const t = this.locale.t;\n        const labeledInput = new LabeledFieldView(this.locale, createLabeledInputText);\n        labeledInput.fieldView.inputMode = 'url';\n        labeledInput.label = t('Link URL');\n        return labeledInput;\n    }\n    /**\n\t * Creates a button view.\n\t *\n\t * @param label The button label.\n\t * @param icon The button icon.\n\t * @param className The additional button CSS class name.\n\t * @param eventName An event name that the `ButtonView#execute` event will be delegated to.\n\t * @returns The button view instance.\n\t */ _createButton(label, icon, className, eventName) {\n        const button = new ButtonView(this.locale);\n        button.set({\n            label,\n            icon,\n            tooltip: true\n        });\n        button.extendTemplate({\n            attributes: {\n                class: className\n            }\n        });\n        if (eventName) {\n            button.delegate('execute').to(this, eventName);\n        }\n        return button;\n    }\n    /**\n\t * Populates {@link module:ui/viewcollection~ViewCollection} of {@link module:ui/button/switchbuttonview~SwitchButtonView}\n\t * made based on {@link module:link/linkcommand~LinkCommand#manualDecorators}.\n\t *\n\t * @param linkCommand A reference to the link command.\n\t * @returns ViewCollection of switch buttons.\n\t */ _createManualDecoratorSwitches(linkCommand) {\n        const switches = this.createCollection();\n        for (const manualDecorator of linkCommand.manualDecorators){\n            const switchButton = new SwitchButtonView(this.locale);\n            switchButton.set({\n                name: manualDecorator.id,\n                label: manualDecorator.label,\n                withText: true\n            });\n            switchButton.bind('isOn').toMany([\n                manualDecorator,\n                linkCommand\n            ], 'value', (decoratorValue, commandValue)=>{\n                return commandValue === undefined && decoratorValue === undefined ? !!manualDecorator.defaultValue : !!decoratorValue;\n            });\n            switchButton.on('execute', ()=>{\n                manualDecorator.set('value', !switchButton.isOn);\n            });\n            switches.add(switchButton);\n        }\n        return switches;\n    }\n    /**\n\t * Populates the {@link #children} collection of the form.\n\t *\n\t * If {@link module:link/linkcommand~LinkCommand#manualDecorators manual decorators} are configured in the editor, it creates an\n\t * additional `View` wrapping all {@link #_manualDecoratorSwitches} switch buttons corresponding\n\t * to these decorators.\n\t *\n\t * @param manualDecorators A reference to\n\t * the collection of manual decorators stored in the link command.\n\t * @returns The children of link form view.\n\t */ _createFormChildren(manualDecorators) {\n        const children = this.createCollection();\n        children.add(this.urlInputView);\n        if (manualDecorators.length) {\n            const additionalButtonsView = new View();\n            additionalButtonsView.setTemplate({\n                tag: 'ul',\n                children: this._manualDecoratorSwitches.map((switchButton)=>({\n                        tag: 'li',\n                        children: [\n                            switchButton\n                        ],\n                        attributes: {\n                            class: [\n                                'ck',\n                                'ck-list__item'\n                            ]\n                        }\n                    })),\n                attributes: {\n                    class: [\n                        'ck',\n                        'ck-reset',\n                        'ck-list'\n                    ]\n                }\n            });\n            children.add(additionalButtonsView);\n        }\n        children.add(this.saveButtonView);\n        children.add(this.cancelButtonView);\n        return children;\n    }\n    /**\n\t * The native DOM `value` of the {@link #urlInputView} element.\n\t *\n\t * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}\n\t * which works one way only and may not represent the actual state of the component in the DOM.\n\t */ get url() {\n        const { element } = this.urlInputView.fieldView;\n        if (!element) {\n            return null;\n        }\n        return element.value.trim();\n    }\n}\n\nvar unlinkIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m11.077 15 .991-1.416a.75.75 0 1 1 1.229.86l-1.148 1.64a.748.748 0 0 1-.217.206 5.251 5.251 0 0 1-8.503-5.955.741.741 0 0 1 .12-.274l1.147-1.639a.75.75 0 1 1 1.228.86L4.933 10.7l.006.003a3.75 3.75 0 0 0 6.132 4.294l.006.004zm5.494-5.335a.748.748 0 0 1-.12.274l-1.147 1.639a.75.75 0 1 1-1.228-.86l.86-1.23a3.75 3.75 0 0 0-6.144-4.301l-.86 1.229a.75.75 0 0 1-1.229-.86l1.148-1.64a.748.748 0 0 1 .217-.206 5.251 5.251 0 0 1 8.503 5.955zm-4.563-2.532a.75.75 0 0 1 .184 1.045l-3.155 4.505a.75.75 0 1 1-1.229-.86l3.155-4.506a.75.75 0 0 1 1.045-.184zm4.919 10.562-1.414 1.414a.75.75 0 1 1-1.06-1.06l1.414-1.415-1.415-1.414a.75.75 0 0 1 1.061-1.06l1.414 1.414 1.414-1.415a.75.75 0 0 1 1.061 1.061l-1.414 1.414 1.414 1.415a.75.75 0 0 1-1.06 1.06l-1.415-1.414z\\\"/></svg>\";\n\n/**\n * The link actions view class. This view displays the link preview, allows\n * unlinking or editing the link.\n */ class LinkActionsView extends View {\n    /**\n\t * Tracks information about DOM focus in the actions.\n\t */ focusTracker = new FocusTracker();\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes = new KeystrokeHandler();\n    /**\n\t * The href preview view.\n\t */ previewButtonView;\n    /**\n\t * The unlink button view.\n\t */ unlinkButtonView;\n    /**\n\t * The edit link button view.\n\t */ editButtonView;\n    /**\n\t * A collection of views that can be focused in the view.\n\t */ _focusables = new ViewCollection();\n    /**\n\t * Helps cycling over {@link #_focusables} in the view.\n\t */ _focusCycler;\n    _linkConfig;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale, linkConfig = {}){\n        super(locale);\n        const t = locale.t;\n        this.previewButtonView = this._createPreviewButton();\n        this.unlinkButtonView = this._createButton(t('Unlink'), unlinkIcon, 'unlink');\n        this.editButtonView = this._createButton(t('Edit link'), icons.pencil, 'edit');\n        this.set('href', undefined);\n        this._linkConfig = linkConfig;\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-link-actions',\n                    'ck-responsive-form'\n                ],\n                // https://github.com/ckeditor/ckeditor5-link/issues/90\n                tabindex: '-1'\n            },\n            children: [\n                this.previewButtonView,\n                this.editButtonView,\n                this.unlinkButtonView\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        const childViews = [\n            this.previewButtonView,\n            this.editButtonView,\n            this.unlinkButtonView\n        ];\n        childViews.forEach((v)=>{\n            // Register the view as focusable.\n            this._focusables.add(v);\n            // Register the view in the focus tracker.\n            this.focusTracker.add(v.element);\n        });\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the fist {@link #_focusables} in the actions.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Creates a button view.\n\t *\n\t * @param label The button label.\n\t * @param icon The button icon.\n\t * @param eventName An event name that the `ButtonView#execute` event will be delegated to.\n\t * @returns The button view instance.\n\t */ _createButton(label, icon, eventName) {\n        const button = new ButtonView(this.locale);\n        button.set({\n            label,\n            icon,\n            tooltip: true\n        });\n        button.delegate('execute').to(this, eventName);\n        return button;\n    }\n    /**\n\t * Creates a link href preview button.\n\t *\n\t * @returns The button view instance.\n\t */ _createPreviewButton() {\n        const button = new ButtonView(this.locale);\n        const bind = this.bindTemplate;\n        const t = this.t;\n        button.set({\n            withText: true,\n            tooltip: t('Open link in new tab')\n        });\n        button.extendTemplate({\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-link-actions__preview'\n                ],\n                href: bind.to('href', (href)=>href && ensureSafeUrl(href, this._linkConfig.allowedProtocols)),\n                target: '_blank',\n                rel: 'noopener noreferrer'\n            }\n        });\n        button.bind('label').to(this, 'href', (href)=>{\n            return href || t('This link has no URL');\n        });\n        button.bind('isEnabled').to(this, 'href', (href)=>!!href);\n        button.template.tag = 'a';\n        button.template.eventListeners = {};\n        return button;\n    }\n}\n\nvar linkIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m11.077 15 .991-1.416a.75.75 0 1 1 1.229.86l-1.148 1.64a.748.748 0 0 1-.217.206 5.251 5.251 0 0 1-8.503-5.955.741.741 0 0 1 .12-.274l1.147-1.639a.75.75 0 1 1 1.228.86L4.933 10.7l.006.003a3.75 3.75 0 0 0 6.132 4.294l.006.004zm5.494-5.335a.748.748 0 0 1-.12.274l-1.147 1.639a.75.75 0 1 1-1.228-.86l.86-1.23a3.75 3.75 0 0 0-6.144-4.301l-.86 1.229a.75.75 0 0 1-1.229-.86l1.148-1.64a.748.748 0 0 1 .217-.206 5.251 5.251 0 0 1 8.503 5.955zm-4.563-2.532a.75.75 0 0 1 .184 1.045l-3.155 4.505a.75.75 0 1 1-1.229-.86l3.155-4.506a.75.75 0 0 1 1.045-.184z\\\"/></svg>\";\n\nconst VISUAL_SELECTION_MARKER_NAME = 'link-ui';\n/**\n * The link UI plugin. It introduces the `'link'` and `'unlink'` buttons and support for the <kbd>Ctrl+K</kbd> keystroke.\n *\n * It uses the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */ class LinkUI extends Plugin {\n    /**\n\t * The actions view displayed inside of the balloon.\n\t */ actionsView = null;\n    /**\n\t * The form view displayed inside the balloon.\n\t */ formView = null;\n    /**\n\t * The contextual balloon plugin instance.\n\t */ _balloon;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LinkUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        editor.editing.view.addObserver(ClickObserver);\n        this._balloon = editor.plugins.get(ContextualBalloon);\n        // Create toolbar buttons.\n        this._createToolbarLinkButton();\n        this._enableBalloonActivators();\n        // Renders a fake visual selection marker on an expanded selection.\n        editor.conversion.for('editingDowncast').markerToHighlight({\n            model: VISUAL_SELECTION_MARKER_NAME,\n            view: {\n                classes: [\n                    'ck-fake-link-selection'\n                ]\n            }\n        });\n        // Renders a fake visual selection marker on a collapsed selection.\n        editor.conversion.for('editingDowncast').markerToElement({\n            model: VISUAL_SELECTION_MARKER_NAME,\n            view: (data, { writer })=>{\n                if (!data.markerRange.isCollapsed) {\n                    return null;\n                }\n                const markerElement = writer.createUIElement('span');\n                writer.addClass([\n                    'ck-fake-link-selection',\n                    'ck-fake-link-selection_collapsed'\n                ], markerElement);\n                return markerElement;\n            }\n        });\n        // Add the information about the keystrokes to the accessibility database.\n        editor.accessibility.addKeystrokeInfos({\n            keystrokes: [\n                {\n                    label: t('Create link'),\n                    keystroke: LINK_KEYSTROKE\n                },\n                {\n                    label: t('Move out of a link'),\n                    keystroke: [\n                        [\n                            'arrowleft',\n                            'arrowleft'\n                        ],\n                        [\n                            'arrowright',\n                            'arrowright'\n                        ]\n                    ]\n                }\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n        if (this.formView) {\n            this.formView.destroy();\n        }\n        if (this.actionsView) {\n            this.actionsView.destroy();\n        }\n    }\n    /**\n\t * Creates views.\n\t */ _createViews() {\n        this.actionsView = this._createActionsView();\n        this.formView = this._createFormView();\n        // Attach lifecycle actions to the the balloon.\n        this._enableUserBalloonInteractions();\n    }\n    /**\n\t * Creates the {@link module:link/ui/linkactionsview~LinkActionsView} instance.\n\t */ _createActionsView() {\n        const editor = this.editor;\n        const actionsView = new LinkActionsView(editor.locale, editor.config.get('link'));\n        const linkCommand = editor.commands.get('link');\n        const unlinkCommand = editor.commands.get('unlink');\n        actionsView.bind('href').to(linkCommand, 'value');\n        actionsView.editButtonView.bind('isEnabled').to(linkCommand);\n        actionsView.unlinkButtonView.bind('isEnabled').to(unlinkCommand);\n        // Execute unlink command after clicking on the \"Edit\" button.\n        this.listenTo(actionsView, 'edit', ()=>{\n            this._addFormView();\n        });\n        // Execute unlink command after clicking on the \"Unlink\" button.\n        this.listenTo(actionsView, 'unlink', ()=>{\n            editor.execute('unlink');\n            this._hideUI();\n        });\n        // Close the panel on esc key press when the **actions have focus**.\n        actionsView.keystrokes.set('Esc', (data, cancel)=>{\n            this._hideUI();\n            cancel();\n        });\n        // Open the form view on Ctrl+K when the **actions have focus**..\n        actionsView.keystrokes.set(LINK_KEYSTROKE, (data, cancel)=>{\n            this._addFormView();\n            cancel();\n        });\n        return actionsView;\n    }\n    /**\n\t * Creates the {@link module:link/ui/linkformview~LinkFormView} instance.\n\t */ _createFormView() {\n        const editor = this.editor;\n        const linkCommand = editor.commands.get('link');\n        const defaultProtocol = editor.config.get('link.defaultProtocol');\n        const formView = new (CssTransitionDisablerMixin(LinkFormView))(editor.locale, linkCommand, getFormValidators(editor));\n        formView.urlInputView.fieldView.bind('value').to(linkCommand, 'value');\n        // Form elements should be read-only when corresponding commands are disabled.\n        formView.urlInputView.bind('isEnabled').to(linkCommand, 'isEnabled');\n        // Disable the \"save\" button if the command is disabled.\n        formView.saveButtonView.bind('isEnabled').to(linkCommand, 'isEnabled');\n        // Execute link command after clicking the \"Save\" button.\n        this.listenTo(formView, 'submit', ()=>{\n            if (formView.isValid()) {\n                const { value } = formView.urlInputView.fieldView.element;\n                const parsedUrl = addLinkProtocolIfApplicable(value, defaultProtocol);\n                editor.execute('link', parsedUrl, formView.getDecoratorSwitchesState());\n                this._closeFormView();\n            }\n        });\n        // Update balloon position when form error changes.\n        this.listenTo(formView.urlInputView, 'change:errorText', ()=>{\n            editor.ui.update();\n        });\n        // Hide the panel after clicking the \"Cancel\" button.\n        this.listenTo(formView, 'cancel', ()=>{\n            this._closeFormView();\n        });\n        // Close the panel on esc key press when the **form has focus**.\n        formView.keystrokes.set('Esc', (data, cancel)=>{\n            this._closeFormView();\n            cancel();\n        });\n        return formView;\n    }\n    /**\n\t * Creates a toolbar Link button. Clicking this button will show\n\t * a {@link #_balloon} attached to the selection.\n\t */ _createToolbarLinkButton() {\n        const editor = this.editor;\n        editor.ui.componentFactory.add('link', ()=>{\n            const button = this._createButton(ButtonView);\n            button.set({\n                tooltip: true\n            });\n            return button;\n        });\n        editor.ui.componentFactory.add('menuBar:link', ()=>{\n            const button = this._createButton(MenuBarMenuListItemButtonView);\n            button.set({\n                role: 'menuitemcheckbox'\n            });\n            return button;\n        });\n    }\n    /**\n\t * Creates a button for link command to use either in toolbar or in menu bar.\n\t */ _createButton(ButtonClass) {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const command = editor.commands.get('link');\n        const view = new ButtonClass(editor.locale);\n        const t = locale.t;\n        view.set({\n            label: t('Link'),\n            icon: linkIcon,\n            keystroke: LINK_KEYSTROKE,\n            isToggleable: true\n        });\n        view.bind('isEnabled').to(command, 'isEnabled');\n        view.bind('isOn').to(command, 'value', (value)=>!!value);\n        // Show the panel on button click.\n        this.listenTo(view, 'execute', ()=>this._showUI(true));\n        return view;\n    }\n    /**\n\t * Attaches actions that control whether the balloon panel containing the\n\t * {@link #formView} should be displayed.\n\t */ _enableBalloonActivators() {\n        const editor = this.editor;\n        const viewDocument = editor.editing.view.document;\n        // Handle click on view document and show panel when selection is placed inside the link element.\n        // Keep panel open until selection will be inside the same link element.\n        this.listenTo(viewDocument, 'click', ()=>{\n            const parentLink = this._getSelectedLinkElement();\n            if (parentLink) {\n                // Then show panel but keep focus inside editor editable.\n                this._showUI();\n            }\n        });\n        // Handle the `Ctrl+K` keystroke and show the panel.\n        editor.keystrokes.set(LINK_KEYSTROKE, (keyEvtData, cancel)=>{\n            // Prevent focusing the search bar in FF, Chrome and Edge. See https://github.com/ckeditor/ckeditor5/issues/4811.\n            cancel();\n            if (editor.commands.get('link').isEnabled) {\n                this._showUI(true);\n            }\n        });\n    }\n    /**\n\t * Attaches actions that control whether the balloon panel containing the\n\t * {@link #formView} is visible or not.\n\t */ _enableUserBalloonInteractions() {\n        // Focus the form if the balloon is visible and the Tab key has been pressed.\n        this.editor.keystrokes.set('Tab', (data, cancel)=>{\n            if (this._areActionsVisible && !this.actionsView.focusTracker.isFocused) {\n                this.actionsView.focus();\n                cancel();\n            }\n        }, {\n            // Use the high priority because the link UI navigation is more important\n            // than other feature's actions, e.g. list indentation.\n            // https://github.com/ckeditor/ckeditor5-link/issues/146\n            priority: 'high'\n        });\n        // Close the panel on the Esc key press when the editable has focus and the balloon is visible.\n        this.editor.keystrokes.set('Esc', (data, cancel)=>{\n            if (this._isUIVisible) {\n                this._hideUI();\n                cancel();\n            }\n        });\n        // Close on click outside of balloon panel element.\n        clickOutsideHandler({\n            emitter: this.formView,\n            activator: ()=>this._isUIInPanel,\n            contextElements: ()=>[\n                    this._balloon.view.element\n                ],\n            callback: ()=>this._hideUI()\n        });\n    }\n    /**\n\t * Adds the {@link #actionsView} to the {@link #_balloon}.\n\t *\n\t * @internal\n\t */ _addActionsView() {\n        if (!this.actionsView) {\n            this._createViews();\n        }\n        if (this._areActionsInPanel) {\n            return;\n        }\n        this._balloon.add({\n            view: this.actionsView,\n            position: this._getBalloonPositionData()\n        });\n    }\n    /**\n\t * Adds the {@link #formView} to the {@link #_balloon}.\n\t */ _addFormView() {\n        if (!this.formView) {\n            this._createViews();\n        }\n        if (this._isFormInPanel) {\n            return;\n        }\n        const editor = this.editor;\n        const linkCommand = editor.commands.get('link');\n        this.formView.disableCssTransitions();\n        this.formView.resetFormStatus();\n        this._balloon.add({\n            view: this.formView,\n            position: this._getBalloonPositionData()\n        });\n        // Make sure that each time the panel shows up, the URL field remains in sync with the value of\n        // the command. If the user typed in the input, then canceled the balloon (`urlInputView.fieldView#value` stays\n        // unaltered) and re-opened it without changing the value of the link command (e.g. because they\n        // clicked the same link), they would see the old value instead of the actual value of the command.\n        // https://github.com/ckeditor/ckeditor5-link/issues/78\n        // https://github.com/ckeditor/ckeditor5-link/issues/123\n        this.formView.urlInputView.fieldView.value = linkCommand.value || '';\n        // Select input when form view is currently visible.\n        if (this._balloon.visibleView === this.formView) {\n            this.formView.urlInputView.fieldView.select();\n        }\n        this.formView.enableCssTransitions();\n    }\n    /**\n\t * Closes the form view. Decides whether the balloon should be hidden completely or if the action view should be shown. This is\n\t * decided upon the link command value (which has a value if the document selection is in the link).\n\t *\n\t * Additionally, if any {@link module:link/linkconfig~LinkConfig#decorators} are defined in the editor configuration, the state of\n\t * switch buttons responsible for manual decorator handling is restored.\n\t */ _closeFormView() {\n        const linkCommand = this.editor.commands.get('link');\n        // Restore manual decorator states to represent the current model state. This case is important to reset the switch buttons\n        // when the user cancels the editing form.\n        linkCommand.restoreManualDecoratorStates();\n        if (linkCommand.value !== undefined) {\n            this._removeFormView();\n        } else {\n            this._hideUI();\n        }\n    }\n    /**\n\t * Removes the {@link #formView} from the {@link #_balloon}.\n\t */ _removeFormView() {\n        if (this._isFormInPanel) {\n            // Blur the input element before removing it from DOM to prevent issues in some browsers.\n            // See https://github.com/ckeditor/ckeditor5/issues/1501.\n            this.formView.saveButtonView.focus();\n            // Reset the URL field to update the state of the submit button.\n            this.formView.urlInputView.fieldView.reset();\n            this._balloon.remove(this.formView);\n            // Because the form has an input which has focus, the focus must be brought back\n            // to the editor. Otherwise, it would be lost.\n            this.editor.editing.view.focus();\n            this._hideFakeVisualSelection();\n        }\n    }\n    /**\n\t * Shows the correct UI type. It is either {@link #formView} or {@link #actionsView}.\n\t *\n\t * @internal\n\t */ _showUI(forceVisible = false) {\n        if (!this.formView) {\n            this._createViews();\n        }\n        // When there's no link under the selection, go straight to the editing UI.\n        if (!this._getSelectedLinkElement()) {\n            // Show visual selection on a text without a link when the contextual balloon is displayed.\n            // See https://github.com/ckeditor/ckeditor5/issues/4721.\n            this._showFakeVisualSelection();\n            this._addActionsView();\n            // Be sure panel with link is visible.\n            if (forceVisible) {\n                this._balloon.showStack('main');\n            }\n            this._addFormView();\n        } else {\n            // Go to the editing UI if actions are already visible.\n            if (this._areActionsVisible) {\n                this._addFormView();\n            } else {\n                this._addActionsView();\n            }\n            // Be sure panel with link is visible.\n            if (forceVisible) {\n                this._balloon.showStack('main');\n            }\n        }\n        // Begin responding to ui#update once the UI is added.\n        this._startUpdatingUI();\n    }\n    /**\n\t * Removes the {@link #formView} from the {@link #_balloon}.\n\t *\n\t * See {@link #_addFormView}, {@link #_addActionsView}.\n\t */ _hideUI() {\n        if (!this._isUIInPanel) {\n            return;\n        }\n        const editor = this.editor;\n        this.stopListening(editor.ui, 'update');\n        this.stopListening(this._balloon, 'change:visibleView');\n        // Make sure the focus always gets back to the editable _before_ removing the focused form view.\n        // Doing otherwise causes issues in some browsers. See https://github.com/ckeditor/ckeditor5-link/issues/193.\n        editor.editing.view.focus();\n        // Remove form first because it's on top of the stack.\n        this._removeFormView();\n        // Then remove the actions view because it's beneath the form.\n        this._balloon.remove(this.actionsView);\n        this._hideFakeVisualSelection();\n    }\n    /**\n\t * Makes the UI react to the {@link module:ui/editorui/editorui~EditorUI#event:update} event to\n\t * reposition itself when the editor UI should be refreshed.\n\t *\n\t * See: {@link #_hideUI} to learn when the UI stops reacting to the `update` event.\n\t */ _startUpdatingUI() {\n        const editor = this.editor;\n        const viewDocument = editor.editing.view.document;\n        let prevSelectedLink = this._getSelectedLinkElement();\n        let prevSelectionParent = getSelectionParent();\n        const update = ()=>{\n            const selectedLink = this._getSelectedLinkElement();\n            const selectionParent = getSelectionParent();\n            // Hide the panel if:\n            //\n            // * the selection went out of the EXISTING link element. E.g. user moved the caret out\n            //   of the link,\n            // * the selection went to a different parent when creating a NEW link. E.g. someone\n            //   else modified the document.\n            // * the selection has expanded (e.g. displaying link actions then pressing SHIFT+Right arrow).\n            //\n            // Note: #_getSelectedLinkElement will return a link for a non-collapsed selection only\n            // when fully selected.\n            if (prevSelectedLink && !selectedLink || !prevSelectedLink && selectionParent !== prevSelectionParent) {\n                this._hideUI();\n            } else if (this._isUIVisible) {\n                // If still in a link element, simply update the position of the balloon.\n                // If there was no link (e.g. inserting one), the balloon must be moved\n                // to the new position in the editing view (a new native DOM range).\n                this._balloon.updatePosition(this._getBalloonPositionData());\n            }\n            prevSelectedLink = selectedLink;\n            prevSelectionParent = selectionParent;\n        };\n        function getSelectionParent() {\n            return viewDocument.selection.focus.getAncestors().reverse().find((node)=>node.is('element'));\n        }\n        this.listenTo(editor.ui, 'update', update);\n        this.listenTo(this._balloon, 'change:visibleView', update);\n    }\n    /**\n\t * Returns `true` when {@link #formView} is in the {@link #_balloon}.\n\t */ get _isFormInPanel() {\n        return !!this.formView && this._balloon.hasView(this.formView);\n    }\n    /**\n\t * Returns `true` when {@link #actionsView} is in the {@link #_balloon}.\n\t */ get _areActionsInPanel() {\n        return !!this.actionsView && this._balloon.hasView(this.actionsView);\n    }\n    /**\n\t * Returns `true` when {@link #actionsView} is in the {@link #_balloon} and it is\n\t * currently visible.\n\t */ get _areActionsVisible() {\n        return !!this.actionsView && this._balloon.visibleView === this.actionsView;\n    }\n    /**\n\t * Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon}.\n\t */ get _isUIInPanel() {\n        return this._isFormInPanel || this._areActionsInPanel;\n    }\n    /**\n\t * Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon} and it is\n\t * currently visible.\n\t */ get _isUIVisible() {\n        const visibleView = this._balloon.visibleView;\n        return !!this.formView && visibleView == this.formView || this._areActionsVisible;\n    }\n    /**\n\t * Returns positioning options for the {@link #_balloon}. They control the way the balloon is attached\n\t * to the target element or selection.\n\t *\n\t * If the selection is collapsed and inside a link element, the panel will be attached to the\n\t * entire link element. Otherwise, it will be attached to the selection.\n\t */ _getBalloonPositionData() {\n        const view = this.editor.editing.view;\n        const model = this.editor.model;\n        const viewDocument = view.document;\n        let target;\n        if (model.markers.has(VISUAL_SELECTION_MARKER_NAME)) {\n            // There are cases when we highlight selection using a marker (#7705, #4721).\n            const markerViewElements = Array.from(this.editor.editing.mapper.markerNameToElements(VISUAL_SELECTION_MARKER_NAME));\n            const newRange = view.createRange(view.createPositionBefore(markerViewElements[0]), view.createPositionAfter(markerViewElements[markerViewElements.length - 1]));\n            target = view.domConverter.viewRangeToDom(newRange);\n        } else {\n            // Make sure the target is calculated on demand at the last moment because a cached DOM range\n            // (which is very fragile) can desynchronize with the state of the editing view if there was\n            // any rendering done in the meantime. This can happen, for instance, when an inline widget\n            // gets unlinked.\n            target = ()=>{\n                const targetLink = this._getSelectedLinkElement();\n                return targetLink ? // When selection is inside link element, then attach panel to this element.\n                view.domConverter.mapViewToDom(targetLink) : // Otherwise attach panel to the selection.\n                view.domConverter.viewRangeToDom(viewDocument.selection.getFirstRange());\n            };\n        }\n        return {\n            target\n        };\n    }\n    /**\n\t * Returns the link {@link module:engine/view/attributeelement~AttributeElement} under\n\t * the {@link module:engine/view/document~Document editing view's} selection or `null`\n\t * if there is none.\n\t *\n\t * **Note**: For a non–collapsed selection, the link element is returned when **fully**\n\t * selected and the **only** element within the selection boundaries, or when\n\t * a linked widget is selected.\n\t */ _getSelectedLinkElement() {\n        const view = this.editor.editing.view;\n        const selection = view.document.selection;\n        const selectedElement = selection.getSelectedElement();\n        // The selection is collapsed or some widget is selected (especially inline widget).\n        if (selection.isCollapsed || selectedElement && isWidget(selectedElement)) {\n            return findLinkElementAncestor(selection.getFirstPosition());\n        } else {\n            // The range for fully selected link is usually anchored in adjacent text nodes.\n            // Trim it to get closer to the actual link element.\n            const range = selection.getFirstRange().getTrimmed();\n            const startLink = findLinkElementAncestor(range.start);\n            const endLink = findLinkElementAncestor(range.end);\n            if (!startLink || startLink != endLink) {\n                return null;\n            }\n            // Check if the link element is fully selected.\n            if (view.createRangeIn(startLink).getTrimmed().isEqual(range)) {\n                return startLink;\n            } else {\n                return null;\n            }\n        }\n    }\n    /**\n\t * Displays a fake visual selection when the contextual balloon is displayed.\n\t *\n\t * This adds a 'link-ui' marker into the document that is rendered as a highlight on selected text fragment.\n\t */ _showFakeVisualSelection() {\n        const model = this.editor.model;\n        model.change((writer)=>{\n            const range = model.document.selection.getFirstRange();\n            if (model.markers.has(VISUAL_SELECTION_MARKER_NAME)) {\n                writer.updateMarker(VISUAL_SELECTION_MARKER_NAME, {\n                    range\n                });\n            } else {\n                if (range.start.isAtEnd) {\n                    const startPosition = range.start.getLastMatchingPosition(({ item })=>!model.schema.isContent(item), {\n                        boundaries: range\n                    });\n                    writer.addMarker(VISUAL_SELECTION_MARKER_NAME, {\n                        usingOperation: false,\n                        affectsData: false,\n                        range: writer.createRange(startPosition, range.end)\n                    });\n                } else {\n                    writer.addMarker(VISUAL_SELECTION_MARKER_NAME, {\n                        usingOperation: false,\n                        affectsData: false,\n                        range\n                    });\n                }\n            }\n        });\n    }\n    /**\n\t * Hides the fake visual selection created in {@link #_showFakeVisualSelection}.\n\t */ _hideFakeVisualSelection() {\n        const model = this.editor.model;\n        if (model.markers.has(VISUAL_SELECTION_MARKER_NAME)) {\n            model.change((writer)=>{\n                writer.removeMarker(VISUAL_SELECTION_MARKER_NAME);\n            });\n        }\n    }\n}\n/**\n * Returns a link element if there's one among the ancestors of the provided `Position`.\n *\n * @param View position to analyze.\n * @returns Link element at the position or null.\n */ function findLinkElementAncestor(position) {\n    return position.getAncestors().find((ancestor)=>isLinkElement(ancestor)) || null;\n}\n/**\n * Returns link form validation callbacks.\n *\n * @param editor Editor instance.\n */ function getFormValidators(editor) {\n    const t = editor.t;\n    const allowCreatingEmptyLinks = editor.config.get('link.allowCreatingEmptyLinks');\n    return [\n        (form)=>{\n            if (!allowCreatingEmptyLinks && !form.url.length) {\n                return t('Link URL must not be empty.');\n            }\n        }\n    ];\n}\n\nconst MIN_LINK_LENGTH_WITH_SPACE_AT_END = 4; // Ie: \"t.co \" (length 5).\n// This was a tweak from https://gist.github.com/dperini/729294.\nconst URL_REG_EXP = new RegExp(// Group 1: Line start or after a space.\n'(^|\\\\s)' + // Group 2: Detected URL (or e-mail).\n'(' + // Protocol identifier or short syntax \"//\"\n// a. Full form http://user@foo.bar.baz:8080/foo/bar.html#baz?foo=bar\n'(' + '(?:(?:(?:https?|ftp):)?\\\\/\\\\/)' + // BasicAuth using user:pass (optional)\n'(?:\\\\S+(?::\\\\S*)?@)?' + '(?:' + // IP address dotted notation octets\n// excludes loopback network 0.0.0.0\n// excludes reserved space >= 224.0.0.0\n// excludes network & broadcast addresses\n// (first & last IP address of each class)\n'(?:[1-9]\\\\d?|1\\\\d\\\\d|2[01]\\\\d|22[0-3])' + '(?:\\\\.(?:1?\\\\d{1,2}|2[0-4]\\\\d|25[0-5])){2}' + '(?:\\\\.(?:[1-9]\\\\d?|1\\\\d\\\\d|2[0-4]\\\\d|25[0-4]))' + '|' + '(' + // Do not allow `www.foo` - see https://github.com/ckeditor/ckeditor5/issues/8050.\n'((?!www\\\\.)|(www\\\\.))' + // Host & domain names.\n'(?![-_])(?:[-_a-z0-9\\\\u00a1-\\\\uffff]{1,63}\\\\.)+' + // TLD identifier name.\n'(?:[a-z\\\\u00a1-\\\\uffff]{2,63})' + ')' + ')' + // port number (optional)\n'(?::\\\\d{2,5})?' + // resource path (optional)\n'(?:[/?#]\\\\S*)?' + ')' + '|' + // b. Short form (either www.example.com or example@example.com)\n'(' + '(www.|(\\\\S+@))' + // Host & domain names.\n'((?![-_])(?:[-_a-z0-9\\\\u00a1-\\\\uffff]{1,63}\\\\.))+' + // TLD identifier name.\n'(?:[a-z\\\\u00a1-\\\\uffff]{2,63})' + ')' + ')$', 'i');\nconst URL_GROUP_IN_MATCH = 2;\n/**\n * The autolink plugin.\n */ class AutoLink extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Delete,\n            LinkEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'AutoLink';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        selection.on('change:range', ()=>{\n            // Disable plugin when selection is inside a code block.\n            this.isEnabled = !selection.anchor.parent.is('element', 'codeBlock');\n        });\n        this._enableTypingHandling();\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        this._enableEnterHandling();\n        this._enableShiftEnterHandling();\n        this._enablePasteLinking();\n    }\n    /**\n\t * For given position, returns a range that includes the whole link that contains the position.\n\t *\n\t * If position is not inside a link, returns `null`.\n\t */ _expandLinkRange(model, position) {\n        if (position.textNode && position.textNode.hasAttribute('linkHref')) {\n            return findAttributeRange(position, 'linkHref', position.textNode.getAttribute('linkHref'), model);\n        } else {\n            return null;\n        }\n    }\n    /**\n\t * Extends the document selection to includes all links that intersects with given `selectedRange`.\n\t */ _selectEntireLinks(writer, selectedRange) {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        const selStart = selection.getFirstPosition();\n        const selEnd = selection.getLastPosition();\n        let updatedSelection = selectedRange.getJoined(this._expandLinkRange(model, selStart) || selectedRange);\n        if (updatedSelection) {\n            updatedSelection = updatedSelection.getJoined(this._expandLinkRange(model, selEnd) || selectedRange);\n        }\n        if (updatedSelection && (updatedSelection.start.isBefore(selStart) || updatedSelection.end.isAfter(selEnd))) {\n            // Only update the selection if it changed.\n            writer.setSelection(updatedSelection);\n        }\n    }\n    /**\n\t * Enables autolinking on pasting a URL when some content is selected.\n\t */ _enablePasteLinking() {\n        const editor = this.editor;\n        const model = editor.model;\n        const selection = model.document.selection;\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        const linkCommand = editor.commands.get('link');\n        clipboardPipeline.on('inputTransformation', (evt, data)=>{\n            if (!this.isEnabled || !linkCommand.isEnabled || selection.isCollapsed || data.method !== 'paste') {\n                // Abort if we are disabled or the selection is collapsed.\n                return;\n            }\n            if (selection.rangeCount > 1) {\n                // Abort if there are multiple selection ranges.\n                return;\n            }\n            const selectedRange = selection.getFirstRange();\n            const newLink = data.dataTransfer.getData('text/plain');\n            if (!newLink) {\n                // Abort if there is no plain text on the clipboard.\n                return;\n            }\n            const matches = newLink.match(URL_REG_EXP);\n            // If the text in the clipboard has a URL, and that URL is the whole clipboard.\n            if (matches && matches[2] === newLink) {\n                model.change((writer)=>{\n                    this._selectEntireLinks(writer, selectedRange);\n                    linkCommand.execute(newLink);\n                });\n                evt.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Enables autolinking on typing.\n\t */ _enableTypingHandling() {\n        const editor = this.editor;\n        const watcher = new TextWatcher(editor.model, (text)=>{\n            // 1. Detect <kbd>Space</kbd> after a text with a potential link.\n            if (!isSingleSpaceAtTheEnd(text)) {\n                return;\n            }\n            // 2. Check text before last typed <kbd>Space</kbd>.\n            const url = getUrlAtTextEnd(text.substr(0, text.length - 1));\n            if (url) {\n                return {\n                    url\n                };\n            }\n        });\n        watcher.on('matched:data', (evt, data)=>{\n            const { batch, range, url } = data;\n            if (!batch.isTyping) {\n                return;\n            }\n            const linkEnd = range.end.getShiftedBy(-1); // Executed after a space character.\n            const linkStart = linkEnd.getShiftedBy(-url.length);\n            const linkRange = editor.model.createRange(linkStart, linkEnd);\n            this._applyAutoLink(url, linkRange);\n        });\n        watcher.bind('isEnabled').to(this);\n    }\n    /**\n\t * Enables autolinking on the <kbd>Enter</kbd> key.\n\t */ _enableEnterHandling() {\n        const editor = this.editor;\n        const model = editor.model;\n        const enterCommand = editor.commands.get('enter');\n        if (!enterCommand) {\n            return;\n        }\n        enterCommand.on('execute', ()=>{\n            const position = model.document.selection.getFirstPosition();\n            if (!position.parent.previousSibling) {\n                return;\n            }\n            const rangeToCheck = model.createRangeIn(position.parent.previousSibling);\n            this._checkAndApplyAutoLinkOnRange(rangeToCheck);\n        });\n    }\n    /**\n\t * Enables autolinking on the <kbd>Shift</kbd>+<kbd>Enter</kbd> keyboard shortcut.\n\t */ _enableShiftEnterHandling() {\n        const editor = this.editor;\n        const model = editor.model;\n        const shiftEnterCommand = editor.commands.get('shiftEnter');\n        if (!shiftEnterCommand) {\n            return;\n        }\n        shiftEnterCommand.on('execute', ()=>{\n            const position = model.document.selection.getFirstPosition();\n            const rangeToCheck = model.createRange(model.createPositionAt(position.parent, 0), position.getShiftedBy(-1));\n            this._checkAndApplyAutoLinkOnRange(rangeToCheck);\n        });\n    }\n    /**\n\t * Checks if the passed range contains a linkable text.\n\t */ _checkAndApplyAutoLinkOnRange(rangeToCheck) {\n        const model = this.editor.model;\n        const { text, range } = getLastTextLine(rangeToCheck, model);\n        const url = getUrlAtTextEnd(text);\n        if (url) {\n            const linkRange = model.createRange(range.end.getShiftedBy(-url.length), range.end);\n            this._applyAutoLink(url, linkRange);\n        }\n    }\n    /**\n\t * Applies a link on a given range if the link should be applied.\n\t *\n\t * @param url The URL to link.\n\t * @param range The text range to apply the link attribute to.\n\t */ _applyAutoLink(url, range) {\n        const model = this.editor.model;\n        const defaultProtocol = this.editor.config.get('link.defaultProtocol');\n        const fullUrl = addLinkProtocolIfApplicable(url, defaultProtocol);\n        if (!this.isEnabled || !isLinkAllowedOnRange(range, model) || !linkHasProtocol(fullUrl) || linkIsAlreadySet(range)) {\n            return;\n        }\n        this._persistAutoLink(fullUrl, range);\n    }\n    /**\n\t * Enqueues autolink changes in the model.\n\t *\n\t * @param url The URL to link.\n\t * @param range The text range to apply the link attribute to.\n\t */ _persistAutoLink(url, range) {\n        const model = this.editor.model;\n        const deletePlugin = this.editor.plugins.get('Delete');\n        // Enqueue change to make undo step.\n        model.enqueueChange((writer)=>{\n            writer.setAttribute('linkHref', url, range);\n            model.enqueueChange(()=>{\n                deletePlugin.requestUndoOnBackspace();\n            });\n        });\n    }\n}\n// Check if text should be evaluated by the plugin in order to reduce number of RegExp checks on whole text.\nfunction isSingleSpaceAtTheEnd(text) {\n    return text.length > MIN_LINK_LENGTH_WITH_SPACE_AT_END && text[text.length - 1] === ' ' && text[text.length - 2] !== ' ';\n}\nfunction getUrlAtTextEnd(text) {\n    const match = URL_REG_EXP.exec(text);\n    return match ? match[URL_GROUP_IN_MATCH] : null;\n}\nfunction isLinkAllowedOnRange(range, model) {\n    return model.schema.checkAttributeInSelection(model.createSelection(range), 'linkHref');\n}\nfunction linkIsAlreadySet(range) {\n    const item = range.start.nodeAfter;\n    return !!item && item.hasAttribute('linkHref');\n}\n\n/**\n * The link plugin.\n *\n * This is a \"glue\" plugin that loads the {@link module:link/linkediting~LinkEditing link editing feature}\n * and {@link module:link/linkui~LinkUI link UI feature}.\n */ class Link extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LinkEditing,\n            LinkUI,\n            AutoLink\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Link';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The link image engine feature.\n *\n * It accepts the `linkHref=\"url\"` attribute in the model for the {@link module:image/image~Image `<imageBlock>`} element\n * which allows linking images.\n */ class LinkImageEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            'ImageEditing',\n            'ImageUtils',\n            LinkEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LinkImageEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        if (editor.plugins.has('ImageBlockEditing')) {\n            schema.extend('imageBlock', {\n                allowAttributes: [\n                    'linkHref'\n                ]\n            });\n        }\n        editor.conversion.for('upcast').add(upcastLink(editor));\n        editor.conversion.for('downcast').add(downcastImageLink(editor));\n        // Definitions for decorators are provided by the `link` command and the `LinkEditing` plugin.\n        this._enableAutomaticDecorators();\n        this._enableManualDecorators();\n    }\n    /**\n\t * Processes {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic decorators} definitions and\n\t * attaches proper converters that will work when linking an image.`\n\t */ _enableAutomaticDecorators() {\n        const editor = this.editor;\n        const command = editor.commands.get('link');\n        const automaticDecorators = command.automaticDecorators;\n        if (automaticDecorators.length) {\n            editor.conversion.for('downcast').add(automaticDecorators.getDispatcherForLinkedImage());\n        }\n    }\n    /**\n\t * Processes transformed {@link module:link/utils/manualdecorator~ManualDecorator} instances and attaches proper converters\n\t * that will work when linking an image.\n\t */ _enableManualDecorators() {\n        const editor = this.editor;\n        const command = editor.commands.get('link');\n        for (const decorator of command.manualDecorators){\n            if (editor.plugins.has('ImageBlockEditing')) {\n                editor.model.schema.extend('imageBlock', {\n                    allowAttributes: decorator.id\n                });\n            }\n            if (editor.plugins.has('ImageInlineEditing')) {\n                editor.model.schema.extend('imageInline', {\n                    allowAttributes: decorator.id\n                });\n            }\n            editor.conversion.for('downcast').add(downcastImageLinkManualDecorator(decorator));\n            editor.conversion.for('upcast').add(upcastImageLinkManualDecorator(editor, decorator));\n        }\n    }\n}\n/**\n * Returns a converter for linked block images that consumes the \"href\" attribute\n * if a link contains an image.\n *\n * @param editor The editor instance.\n */ function upcastLink(editor) {\n    const isImageInlinePluginLoaded = editor.plugins.has('ImageInlineEditing');\n    const imageUtils = editor.plugins.get('ImageUtils');\n    return (dispatcher)=>{\n        dispatcher.on('element:a', (evt, data, conversionApi)=>{\n            const viewLink = data.viewItem;\n            const imageInLink = imageUtils.findViewImgElement(viewLink);\n            if (!imageInLink) {\n                return;\n            }\n            const blockImageView = imageInLink.findAncestor((element)=>imageUtils.isBlockImageView(element));\n            // There are four possible cases to consider here\n            //\n            // 1. A \"root > ... > figure.image > a > img\" structure.\n            // 2. A \"root > ... > figure.image > a > picture > img\" structure.\n            // 3. A \"root > ... > block > a > img\" structure.\n            // 4. A \"root > ... > block > a > picture > img\" structure.\n            //\n            // but the last 2 cases should only be considered by this converter when the inline image plugin\n            // is NOT loaded in the editor (because otherwise, that would be a plain, linked inline image).\n            if (isImageInlinePluginLoaded && !blockImageView) {\n                return;\n            }\n            // There's an image inside an <a> element - we consume it so it won't be picked up by the Link plugin.\n            const consumableAttributes = {\n                attributes: [\n                    'href'\n                ]\n            };\n            // Consume the `href` attribute so the default one will not convert it to $text attribute.\n            if (!conversionApi.consumable.consume(viewLink, consumableAttributes)) {\n                // Might be consumed by something else - i.e. other converter with priority=highest - a standard check.\n                return;\n            }\n            const linkHref = viewLink.getAttribute('href');\n            // Missing the 'href' attribute.\n            if (!linkHref) {\n                return;\n            }\n            // A full definition of the image feature.\n            // figure > a > img: parent of the view link element is an image element (figure).\n            let modelElement = data.modelCursor.parent;\n            if (!modelElement.is('element', 'imageBlock')) {\n                // a > img: parent of the view link is not the image (figure) element. We need to convert it manually.\n                const conversionResult = conversionApi.convertItem(imageInLink, data.modelCursor);\n                // Set image range as conversion result.\n                data.modelRange = conversionResult.modelRange;\n                // Continue conversion where image conversion ends.\n                data.modelCursor = conversionResult.modelCursor;\n                modelElement = data.modelCursor.nodeBefore;\n            }\n            if (modelElement && modelElement.is('element', 'imageBlock')) {\n                // Set the linkHref attribute from link element on model image element.\n                conversionApi.writer.setAttribute('linkHref', linkHref, modelElement);\n            }\n        }, {\n            priority: 'high'\n        });\n    // Using the same priority that `upcastImageLinkManualDecorator()` converter guarantees\n    // that manual decorators will decorate the proper element.\n    };\n}\n/**\n * Creates a converter that adds `<a>` to linked block image view elements.\n */ function downcastImageLink(editor) {\n    const imageUtils = editor.plugins.get('ImageUtils');\n    return (dispatcher)=>{\n        dispatcher.on('attribute:linkHref:imageBlock', (evt, data, conversionApi)=>{\n            if (!conversionApi.consumable.consume(data.item, evt.name)) {\n                return;\n            }\n            // The image will be already converted - so it will be present in the view.\n            const viewFigure = conversionApi.mapper.toViewElement(data.item);\n            const writer = conversionApi.writer;\n            // But we need to check whether the link element exists.\n            const linkInImage = Array.from(viewFigure.getChildren()).find((child)=>child.is('element', 'a'));\n            const viewImage = imageUtils.findViewImgElement(viewFigure);\n            // <picture>...<img/></picture> or <img/>\n            const viewImgOrPicture = viewImage.parent.is('element', 'picture') ? viewImage.parent : viewImage;\n            // If so, update the attribute if it's defined or remove the entire link if the attribute is empty.\n            if (linkInImage) {\n                if (data.attributeNewValue) {\n                    writer.setAttribute('href', data.attributeNewValue, linkInImage);\n                } else {\n                    writer.move(writer.createRangeOn(viewImgOrPicture), writer.createPositionAt(viewFigure, 0));\n                    writer.remove(linkInImage);\n                }\n            } else {\n                // But if it does not exist. Let's wrap already converted image by newly created link element.\n                // 1. Create an empty link element.\n                const linkElement = writer.createContainerElement('a', {\n                    href: data.attributeNewValue\n                });\n                // 2. Insert link inside the associated image.\n                writer.insert(writer.createPositionAt(viewFigure, 0), linkElement);\n                // 3. Move the image to the link.\n                writer.move(writer.createRangeOn(viewImgOrPicture), writer.createPositionAt(linkElement, 0));\n            }\n        }, {\n            priority: 'high'\n        });\n    };\n}\n/**\n * Returns a converter that decorates the `<a>` element when the image is the link label.\n */ function downcastImageLinkManualDecorator(decorator) {\n    return (dispatcher)=>{\n        dispatcher.on(`attribute:${decorator.id}:imageBlock`, (evt, data, conversionApi)=>{\n            const viewFigure = conversionApi.mapper.toViewElement(data.item);\n            const linkInImage = Array.from(viewFigure.getChildren()).find((child)=>child.is('element', 'a'));\n            // The <a> element was removed by the time this converter is executed.\n            // It may happen when the base `linkHref` and decorator attributes are removed\n            // at the same time (see #8401).\n            if (!linkInImage) {\n                return;\n            }\n            for (const [key, val] of toMap(decorator.attributes)){\n                conversionApi.writer.setAttribute(key, val, linkInImage);\n            }\n            if (decorator.classes) {\n                conversionApi.writer.addClass(decorator.classes, linkInImage);\n            }\n            for(const key in decorator.styles){\n                conversionApi.writer.setStyle(key, decorator.styles[key], linkInImage);\n            }\n        });\n    };\n}\n/**\n * Returns a converter that checks whether manual decorators should be applied to the link.\n */ function upcastImageLinkManualDecorator(editor, decorator) {\n    const isImageInlinePluginLoaded = editor.plugins.has('ImageInlineEditing');\n    const imageUtils = editor.plugins.get('ImageUtils');\n    return (dispatcher)=>{\n        dispatcher.on('element:a', (evt, data, conversionApi)=>{\n            const viewLink = data.viewItem;\n            const imageInLink = imageUtils.findViewImgElement(viewLink);\n            // We need to check whether an image is inside a link because the converter handles\n            // only manual decorators for linked images. See #7975.\n            if (!imageInLink) {\n                return;\n            }\n            const blockImageView = imageInLink.findAncestor((element)=>imageUtils.isBlockImageView(element));\n            if (isImageInlinePluginLoaded && !blockImageView) {\n                return;\n            }\n            const matcher = new Matcher(decorator._createPattern());\n            const result = matcher.match(viewLink);\n            // The link element does not have required attributes or/and proper values.\n            if (!result) {\n                return;\n            }\n            // Check whether we can consume those attributes.\n            if (!conversionApi.consumable.consume(viewLink, result.match)) {\n                return;\n            }\n            // At this stage we can assume that we have the `<imageBlock>` element.\n            // `nodeBefore` comes after conversion: `<a><img></a>`.\n            // `parent` comes with full image definition: `<figure><a><img></a></figure>.\n            // See the body of the `upcastLink()` function.\n            const modelElement = data.modelCursor.nodeBefore || data.modelCursor.parent;\n            conversionApi.writer.setAttribute(decorator.id, true, modelElement);\n        }, {\n            priority: 'high'\n        });\n    // Using the same priority that `upcastLink()` converter guarantees that the linked image was properly converted.\n    };\n}\n\n/**\n * The link image UI plugin.\n *\n * This plugin provides the `'linkImage'` button that can be displayed in the {@link module:image/imagetoolbar~ImageToolbar}.\n * It can be used to wrap images in links.\n */ class LinkImageUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LinkEditing,\n            LinkUI,\n            'ImageBlockEditing'\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LinkImageUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const viewDocument = editor.editing.view.document;\n        this.listenTo(viewDocument, 'click', (evt, data)=>{\n            if (this._isSelectedLinkedImage(editor.model.document.selection)) {\n                // Prevent browser navigation when clicking a linked image.\n                data.preventDefault();\n                // Block the `LinkUI` plugin when an image was clicked.\n                // In such a case, we'd like to display the image toolbar.\n                evt.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n        this._createToolbarLinkImageButton();\n    }\n    /**\n\t * Creates a `LinkImageUI` button view.\n\t *\n\t * Clicking this button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.\n\t * When an image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or\n\t * {@link module:link/linkui~LinkUI#formView} if it is not.\n\t */ _createToolbarLinkImageButton() {\n        const editor = this.editor;\n        const t = editor.t;\n        editor.ui.componentFactory.add('linkImage', (locale)=>{\n            const button = new ButtonView(locale);\n            const plugin = editor.plugins.get('LinkUI');\n            const linkCommand = editor.commands.get('link');\n            button.set({\n                isEnabled: true,\n                label: t('Link image'),\n                icon: linkIcon,\n                keystroke: LINK_KEYSTROKE,\n                tooltip: true,\n                isToggleable: true\n            });\n            // Bind button to the command.\n            button.bind('isEnabled').to(linkCommand, 'isEnabled');\n            button.bind('isOn').to(linkCommand, 'value', (value)=>!!value);\n            // Show the actionsView or formView (both from LinkUI) on button click depending on whether the image is linked already.\n            this.listenTo(button, 'execute', ()=>{\n                if (this._isSelectedLinkedImage(editor.model.document.selection)) {\n                    plugin._addActionsView();\n                } else {\n                    plugin._showUI(true);\n                }\n            });\n            return button;\n        });\n    }\n    /**\n\t * Returns true if a linked image (either block or inline) is the only selected element\n\t * in the model document.\n\t */ _isSelectedLinkedImage(selection) {\n        const selectedModelElement = selection.getSelectedElement();\n        const imageUtils = this.editor.plugins.get('ImageUtils');\n        return imageUtils.isImage(selectedModelElement) && selectedModelElement.hasAttribute('linkHref');\n    }\n}\n\n/**\n * The `LinkImage` plugin.\n *\n * This is a \"glue\" plugin that loads the {@link module:link/linkimageediting~LinkImageEditing link image editing feature}\n * and {@link module:link/linkimageui~LinkImageUI link image UI feature}.\n */ class LinkImage extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LinkImageEditing,\n            LinkImageUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LinkImage';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { AutoLink, Link, LinkActionsView, LinkCommand, LinkEditing, LinkFormView, LinkImage, LinkImageEditing, LinkImageUI, LinkUI, UnlinkCommand, addLinkProtocolIfApplicable, isLinkableElement };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/utils/automaticdecorators\n */\n\nimport { toMap, type ArrayOrItem } from 'ckeditor5/src/utils.js';\nimport type { DowncastAttributeEvent, DowncastDispatcher, Element, ViewElement } from 'ckeditor5/src/engine.js';\nimport type { NormalizedLinkDecoratorAutomaticDefinition } from '../utils.js';\n\n/**\n * Helper class that ties together all {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition} and provides\n * the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement downcast dispatchers} for them.\n */\nexport default class AutomaticDecorators {\n\t/**\n\t * Stores the definition of {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic decorators}.\n\t * This data is used as a source for a downcast dispatcher to create a proper conversion to output data.\n\t */\n\tprivate _definitions = new Set<NormalizedLinkDecoratorAutomaticDefinition>();\n\n\t/**\n\t * Gives information about the number of decorators stored in the {@link module:link/utils/automaticdecorators~AutomaticDecorators}\n\t * instance.\n\t */\n\tpublic get length(): number {\n\t\treturn this._definitions.size;\n\t}\n\n\t/**\n\t * Adds automatic decorator objects or an array with them to be used during downcasting.\n\t *\n\t * @param item A configuration object of automatic rules for decorating links. It might also be an array of such objects.\n\t */\n\tpublic add( item: ArrayOrItem<NormalizedLinkDecoratorAutomaticDefinition> ): void {\n\t\tif ( Array.isArray( item ) ) {\n\t\t\titem.forEach( item => this._definitions.add( item ) );\n\t\t} else {\n\t\t\tthis._definitions.add( item );\n\t\t}\n\t}\n\n\t/**\n\t * Provides the conversion helper used in the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add} method.\n\t *\n\t * @returns A dispatcher function used as conversion helper in {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add}.\n\t */\n\tpublic getDispatcher(): ( dispatcher: DowncastDispatcher ) => void {\n\t\treturn dispatcher => {\n\t\t\tdispatcher.on<DowncastAttributeEvent>( 'attribute:linkHref', ( evt, data, conversionApi ) => {\n\t\t\t\t// There is only test as this behavior decorates links and\n\t\t\t\t// it is run before dispatcher which actually consumes this node.\n\t\t\t\t// This allows on writing own dispatcher with highest priority,\n\t\t\t\t// which blocks both native converter and this additional decoration.\n\t\t\t\tif ( !conversionApi.consumable.test( data.item, 'attribute:linkHref' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Automatic decorators for block links are handled e.g. in LinkImageEditing.\n\t\t\t\tif ( !( data.item.is( 'selection' ) || conversionApi.schema.isInline( data.item ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst viewSelection = viewWriter.document.selection;\n\n\t\t\t\tfor ( const item of this._definitions ) {\n\t\t\t\t\tconst viewElement = viewWriter.createAttributeElement( 'a', item.attributes, {\n\t\t\t\t\t\tpriority: 5\n\t\t\t\t\t} );\n\n\t\t\t\t\tif ( item.classes ) {\n\t\t\t\t\t\tviewWriter.addClass( item.classes, viewElement );\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ( const key in item.styles ) {\n\t\t\t\t\t\tviewWriter.setStyle( key, item.styles[ key ], viewElement );\n\t\t\t\t\t}\n\n\t\t\t\t\tviewWriter.setCustomProperty( 'link', true, viewElement );\n\n\t\t\t\t\tif ( item.callback( data.attributeNewValue as string | null ) ) {\n\t\t\t\t\t\tif ( data.item.is( 'selection' ) ) {\n\t\t\t\t\t\t\tviewWriter.wrap( viewSelection.getFirstRange()!, viewElement );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tviewWriter.wrap( conversionApi.mapper.toViewRange( data.range ), viewElement );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tviewWriter.unwrap( conversionApi.mapper.toViewRange( data.range ), viewElement );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, { priority: 'high' } );\n\t\t};\n\t}\n\n\t/**\n\t * Provides the conversion helper used in the {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add} method\n\t * when linking images.\n\t *\n\t * @returns A dispatcher function used as conversion helper in {@link module:engine/conversion/downcasthelpers~DowncastHelpers#add}.\n\t */\n\tpublic getDispatcherForLinkedImage(): ( dispatcher: DowncastDispatcher ) => void {\n\t\treturn dispatcher => {\n\t\t\tdispatcher.on<DowncastAttributeEvent<Element>>( 'attribute:linkHref:imageBlock', ( evt, data, { writer, mapper } ) => {\n\t\t\t\tconst viewFigure = mapper.toViewElement( data.item )!;\n\t\t\t\tconst linkInImage = Array.from( viewFigure.getChildren() )\n\t\t\t\t\t.find( ( child ): child is ViewElement => child.is( 'element', 'a' ) )!;\n\n\t\t\t\t// It's not guaranteed that the anchor is present in the image block during execution of this dispatcher.\n\t\t\t\t// It might have been removed during the execution of unlink command that runs the image link downcast dispatcher\n\t\t\t\t// that is executed before this one and removes the anchor from the image block.\n\t\t\t\tif ( !linkInImage ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfor ( const item of this._definitions ) {\n\t\t\t\t\tconst attributes = toMap( item.attributes );\n\n\t\t\t\t\tif ( item.callback( data.attributeNewValue as string | null ) ) {\n\t\t\t\t\t\tfor ( const [ key, val ] of attributes ) {\n\t\t\t\t\t\t\t// Left for backward compatibility. Since v30 decorator should\n\t\t\t\t\t\t\t// accept `classes` and `styles` separately from `attributes`.\n\t\t\t\t\t\t\tif ( key === 'class' ) {\n\t\t\t\t\t\t\t\twriter.addClass( val, linkInImage );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twriter.setAttribute( key, val, linkInImage );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( item.classes ) {\n\t\t\t\t\t\t\twriter.addClass( item.classes, linkInImage );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor ( const key in item.styles ) {\n\t\t\t\t\t\t\twriter.setStyle( key, item.styles[ key ], linkInImage );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor ( const [ key, val ] of attributes ) {\n\t\t\t\t\t\t\tif ( key === 'class' ) {\n\t\t\t\t\t\t\t\twriter.removeClass( val, linkInImage );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twriter.removeAttribute( key, linkInImage );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( item.classes ) {\n\t\t\t\t\t\t\twriter.removeClass( item.classes, linkInImage );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor ( const key in item.styles ) {\n\t\t\t\t\t\t\twriter.removeStyle( key, linkInImage );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/utils\n */\n\n/* global window */\n\nimport type {\n\tDowncastConversionApi,\n\tElement,\n\tSchema,\n\tViewAttributeElement,\n\tViewNode,\n\tViewDocumentFragment\n} from 'ckeditor5/src/engine.js';\nimport type { LocaleTranslate } from 'ckeditor5/src/utils.js';\n\nimport type {\n\tLinkDecoratorAutomaticDefinition,\n\tLinkDecoratorDefinition,\n\tLinkDecoratorManualDefinition\n} from './linkconfig.js';\n\nimport { upperFirst } from 'lodash-es';\n\nconst ATTRIBUTE_WHITESPACES = /[\\u0000-\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u2029\\u205f\\u3000]/g; // eslint-disable-line no-control-regex\n\nconst SAFE_URL_TEMPLATE = '^(?:(?:<protocols>):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))';\n\n// Simplified email test - should be run over previously found URL.\nconst EMAIL_REG_EXP = /^[\\S]+@((?![-_])(?:[-\\w\\u00a1-\\uffff]{0,63}[^-_]\\.))+(?:[a-z\\u00a1-\\uffff]{2,})$/i;\n\n// The regex checks for the protocol syntax ('xxxx://' or 'xxxx:')\n// or non-word characters at the beginning of the link ('/', '#' etc.).\nconst PROTOCOL_REG_EXP = /^((\\w+:(\\/{2,})?)|(\\W))/i;\n\nconst DEFAULT_LINK_PROTOCOLS = [\n\t'https?',\n\t'ftps?',\n\t'mailto'\n];\n\n/**\n * A keystroke used by the {@link module:link/linkui~LinkUI link UI feature}.\n */\nexport const LINK_KEYSTROKE = 'Ctrl+K';\n\n/**\n * Returns `true` if a given view node is the link element.\n */\nexport function isLinkElement( node: ViewNode | ViewDocumentFragment ): boolean {\n\treturn node.is( 'attributeElement' ) && !!node.getCustomProperty( 'link' );\n}\n\n/**\n * Creates a link {@link module:engine/view/attributeelement~AttributeElement} with the provided `href` attribute.\n */\nexport function createLinkElement( href: string, { writer }: DowncastConversionApi ): ViewAttributeElement {\n\t// Priority 5 - https://github.com/ckeditor/ckeditor5-link/issues/121.\n\tconst linkElement = writer.createAttributeElement( 'a', { href }, { priority: 5 } );\n\n\twriter.setCustomProperty( 'link', true, linkElement );\n\n\treturn linkElement;\n}\n\n/**\n * Returns a safe URL based on a given value.\n *\n * A URL is considered safe if it is safe for the user (does not contain any malicious code).\n *\n * If a URL is considered unsafe, a simple `\"#\"` is returned.\n *\n * @internal\n */\nexport function ensureSafeUrl( url: unknown, allowedProtocols: Array<string> = DEFAULT_LINK_PROTOCOLS ): string {\n\tconst urlString = String( url );\n\n\tconst protocolsList = allowedProtocols.join( '|' );\n\tconst customSafeRegex = new RegExp( `${ SAFE_URL_TEMPLATE.replace( '<protocols>', protocolsList ) }`, 'i' );\n\n\treturn isSafeUrl( urlString, customSafeRegex ) ? urlString : '#';\n}\n\n/**\n * Checks whether the given URL is safe for the user (does not contain any malicious code).\n */\nfunction isSafeUrl( url: string, customRegexp: RegExp ): boolean {\n\tconst normalizedUrl = url.replace( ATTRIBUTE_WHITESPACES, '' );\n\n\treturn !!normalizedUrl.match( customRegexp );\n}\n\n/**\n * Returns the {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`} configuration processed\n * to respect the locale of the editor, i.e. to display the {@link module:link/linkconfig~LinkDecoratorManualDefinition label}\n * in the correct language.\n *\n * **Note**: Only the few most commonly used labels are translated automatically. Other labels should be manually\n * translated in the {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`} configuration.\n *\n * @param t Shorthand for {@link module:utils/locale~Locale#t Locale#t}.\n * @param decorators The decorator reference where the label values should be localized.\n */\nexport function getLocalizedDecorators(\n\tt: LocaleTranslate,\n\tdecorators: Array<NormalizedLinkDecoratorDefinition>\n): Array<NormalizedLinkDecoratorDefinition> {\n\tconst localizedDecoratorsLabels: Record<string, string> = {\n\t\t'Open in a new tab': t( 'Open in a new tab' ),\n\t\t'Downloadable': t( 'Downloadable' )\n\t};\n\n\tdecorators.forEach( decorator => {\n\t\tif ( 'label' in decorator && localizedDecoratorsLabels[ decorator.label ] ) {\n\t\t\tdecorator.label = localizedDecoratorsLabels[ decorator.label ];\n\t\t}\n\n\t\treturn decorator;\n\t} );\n\n\treturn decorators;\n}\n\n/**\n * Converts an object with defined decorators to a normalized array of decorators. The `id` key is added for each decorator and\n * is used as the attribute's name in the model.\n */\nexport function normalizeDecorators( decorators?: Record<string, LinkDecoratorDefinition> ): Array<NormalizedLinkDecoratorDefinition> {\n\tconst retArray: Array<NormalizedLinkDecoratorDefinition> = [];\n\n\tif ( decorators ) {\n\t\tfor ( const [ key, value ] of Object.entries( decorators ) ) {\n\t\t\tconst decorator = Object.assign(\n\t\t\t\t{},\n\t\t\t\tvalue,\n\t\t\t\t{ id: `link${ upperFirst( key ) }` }\n\t\t\t);\n\n\t\t\tretArray.push( decorator );\n\t\t}\n\t}\n\n\treturn retArray;\n}\n\n/**\n * Returns `true` if the specified `element` can be linked (the element allows the `linkHref` attribute).\n */\nexport function isLinkableElement( element: Element | null, schema: Schema ): element is Element {\n\tif ( !element ) {\n\t\treturn false;\n\t}\n\n\treturn schema.checkAttribute( element.name, 'linkHref' );\n}\n\n/**\n * Returns `true` if the specified `value` is an email.\n */\nexport function isEmail( value: string ): boolean {\n\treturn EMAIL_REG_EXP.test( value );\n}\n\n/**\n * Adds the protocol prefix to the specified `link` when:\n *\n * * it does not contain it already, and there is a {@link module:link/linkconfig~LinkConfig#defaultProtocol `defaultProtocol` }\n * configuration value provided,\n * * or the link is an email address.\n */\nexport function addLinkProtocolIfApplicable( link: string, defaultProtocol?: string ): string {\n\tconst protocol = isEmail( link ) ? 'mailto:' : defaultProtocol;\n\tconst isProtocolNeeded = !!protocol && !linkHasProtocol( link );\n\n\treturn link && isProtocolNeeded ? protocol + link : link;\n}\n\n/**\n * Checks if protocol is already included in the link.\n */\nexport function linkHasProtocol( link: string ): boolean {\n\treturn PROTOCOL_REG_EXP.test( link );\n}\n\n/**\n * Opens the link in a new browser tab.\n */\nexport function openLink( link: string ): void {\n\twindow.open( link, '_blank', 'noopener' );\n}\n\nexport type NormalizedLinkDecoratorAutomaticDefinition = LinkDecoratorAutomaticDefinition & { id: string };\nexport type NormalizedLinkDecoratorManualDefinition = LinkDecoratorManualDefinition & { id: string };\nexport type NormalizedLinkDecoratorDefinition = NormalizedLinkDecoratorAutomaticDefinition | NormalizedLinkDecoratorManualDefinition;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/linkcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport { findAttributeRange } from 'ckeditor5/src/typing.js';\nimport { Collection, first, toMap } from 'ckeditor5/src/utils.js';\nimport type { Range, DocumentSelection, Model, Writer } from 'ckeditor5/src/engine.js';\n\nimport AutomaticDecorators from './utils/automaticdecorators.js';\nimport { isLinkableElement } from './utils.js';\nimport type ManualDecorator from './utils/manualdecorator.js';\n\n/**\n * The link command. It is used by the {@link module:link/link~Link link feature}.\n */\nexport default class LinkCommand extends Command {\n\t/**\n\t * The value of the `'linkHref'` attribute if the start of the selection is located in a node with this attribute.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public value: string | undefined;\n\n\t/**\n\t * A collection of {@link module:link/utils/manualdecorator~ManualDecorator manual decorators}\n\t * corresponding to the {@link module:link/linkconfig~LinkConfig#decorators decorator configuration}.\n\t *\n\t * You can consider it a model with states of manual decorators added to the currently selected link.\n\t */\n\tpublic readonly manualDecorators = new Collection<ManualDecorator>();\n\n\t/**\n\t * An instance of the helper that ties together all {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition}\n\t * that are used by the {@glink features/link link} and the {@glink features/images/images-linking linking images} features.\n\t */\n\tpublic readonly automaticDecorators = new AutomaticDecorators();\n\n\t/**\n\t * Synchronizes the state of {@link #manualDecorators} with the currently present elements in the model.\n\t */\n\tpublic restoreManualDecoratorStates(): void {\n\t\tfor ( const manualDecorator of this.manualDecorators ) {\n\t\t\tmanualDecorator.value = this._getDecoratorStateFromModel( manualDecorator.id );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedElement = selection.getSelectedElement() || first( selection.getSelectedBlocks() );\n\n\t\t// A check for any integration that allows linking elements (e.g. `LinkImage`).\n\t\t// Currently the selection reads attributes from text nodes only. See #7429 and #7465.\n\t\tif ( isLinkableElement( selectedElement, model.schema ) ) {\n\t\t\tthis.value = selectedElement.getAttribute( 'linkHref' ) as string | undefined;\n\t\t\tthis.isEnabled = model.schema.checkAttribute( selectedElement, 'linkHref' );\n\t\t} else {\n\t\t\tthis.value = selection.getAttribute( 'linkHref' ) as string | undefined;\n\t\t\tthis.isEnabled = model.schema.checkAttributeInSelection( selection, 'linkHref' );\n\t\t}\n\n\t\tfor ( const manualDecorator of this.manualDecorators ) {\n\t\t\tmanualDecorator.value = this._getDecoratorStateFromModel( manualDecorator.id );\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is non-collapsed, the `linkHref` attribute will be applied to nodes inside the selection, but only to\n\t * those nodes where the `linkHref` attribute is allowed (disallowed nodes will be omitted).\n\t *\n\t * When the selection is collapsed and is not inside the text with the `linkHref` attribute, a\n\t * new {@link module:engine/model/text~Text text node} with the `linkHref` attribute will be inserted in place of the caret, but\n\t * only if such element is allowed in this place. The `_data` of the inserted text will equal the `href` parameter.\n\t * The selection will be updated to wrap the just inserted text node.\n\t *\n\t * When the selection is collapsed and inside the text with the `linkHref` attribute, the attribute value will be updated.\n\t *\n\t * # Decorators and model attribute management\n\t *\n\t * There is an optional argument to this command that applies or removes model\n\t * {@glink framework/architecture/editing-engine#text-attributes text attributes} brought by\n\t * {@link module:link/utils/manualdecorator~ManualDecorator manual link decorators}.\n\t *\n\t * Text attribute names in the model correspond to the entries in the {@link module:link/linkconfig~LinkConfig#decorators\n\t * configuration}.\n\t * For every decorator configured, a model text attribute exists with the \"link\" prefix. For example, a `'linkMyDecorator'` attribute\n\t * corresponds to `'myDecorator'` in the configuration.\n\t *\n\t * To learn more about link decorators, check out the {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`}\n\t * documentation.\n\t *\n\t * Here is how to manage decorator attributes with the link command:\n\t *\n\t * ```ts\n\t * const linkCommand = editor.commands.get( 'link' );\n\t *\n\t * // Adding a new decorator attribute.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: true\n\t * } );\n\t *\n\t * // Removing a decorator attribute from the selection.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: false\n\t * } );\n\t *\n\t * // Adding multiple decorator attributes at the same time.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: true,\n\t * \tlinkIsDownloadable: true,\n\t * } );\n\t *\n\t * // Removing and adding decorator attributes at the same time.\n\t * linkCommand.execute( 'http://example.com', {\n\t * \tlinkIsExternal: false,\n\t * \tlinkFoo: true,\n\t * \tlinkIsDownloadable: false,\n\t * } );\n\t * ```\n\t *\n\t * **Note**: If the decorator attribute name is not specified, its state remains untouched.\n\t *\n\t * **Note**: {@link module:link/unlinkcommand~UnlinkCommand#execute `UnlinkCommand#execute()`} removes all\n\t * decorator attributes.\n\t *\n\t * @fires execute\n\t * @param href Link destination.\n\t * @param manualDecoratorIds The information about manual decorator attributes to be applied or removed upon execution.\n\t */\n\tpublic override execute( href: string, manualDecoratorIds: Record<string, boolean> = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\t// Stores information about manual decorators to turn them on/off when command is applied.\n\t\tconst truthyManualDecorators: Array<string> = [];\n\t\tconst falsyManualDecorators: Array<string> = [];\n\n\t\tfor ( const name in manualDecoratorIds ) {\n\t\t\tif ( manualDecoratorIds[ name ] ) {\n\t\t\t\ttruthyManualDecorators.push( name );\n\t\t\t} else {\n\t\t\t\tfalsyManualDecorators.push( name );\n\t\t\t}\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\t// If selection is collapsed then update selected link or insert new one at the place of caret.\n\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\tconst position = selection.getFirstPosition()!;\n\n\t\t\t\t// When selection is inside text with `linkHref` attribute.\n\t\t\t\tif ( selection.hasAttribute( 'linkHref' ) ) {\n\t\t\t\t\tconst linkText = extractTextFromSelection( selection );\n\t\t\t\t\t// Then update `linkHref` value.\n\t\t\t\t\tlet linkRange = findAttributeRange( position, 'linkHref', selection.getAttribute( 'linkHref' ), model );\n\n\t\t\t\t\tif ( selection.getAttribute( 'linkHref' ) === linkText ) {\n\t\t\t\t\t\tlinkRange = this._updateLinkContent( model, writer, linkRange, href );\n\t\t\t\t\t}\n\n\t\t\t\t\twriter.setAttribute( 'linkHref', href, linkRange );\n\n\t\t\t\t\ttruthyManualDecorators.forEach( item => {\n\t\t\t\t\t\twriter.setAttribute( item, true, linkRange );\n\t\t\t\t\t} );\n\n\t\t\t\t\tfalsyManualDecorators.forEach( item => {\n\t\t\t\t\t\twriter.removeAttribute( item, linkRange );\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Put the selection at the end of the updated link.\n\t\t\t\t\twriter.setSelection( writer.createPositionAfter( linkRange.end.nodeBefore! ) );\n\t\t\t\t}\n\t\t\t\t// If not then insert text node with `linkHref` attribute in place of caret.\n\t\t\t\t// However, since selection is collapsed, attribute value will be used as data for text node.\n\t\t\t\t// So, if `href` is empty, do not create text node.\n\t\t\t\telse if ( href !== '' ) {\n\t\t\t\t\tconst attributes = toMap( selection.getAttributes() );\n\n\t\t\t\t\tattributes.set( 'linkHref', href );\n\n\t\t\t\t\ttruthyManualDecorators.forEach( item => {\n\t\t\t\t\t\tattributes.set( item, true );\n\t\t\t\t\t} );\n\n\t\t\t\t\tconst { end: positionAfter } = model.insertContent( writer.createText( href, attributes ), position );\n\n\t\t\t\t\t// Put the selection at the end of the inserted link.\n\t\t\t\t\t// Using end of range returned from insertContent in case nodes with the same attributes got merged.\n\t\t\t\t\twriter.setSelection( positionAfter );\n\t\t\t\t}\n\n\t\t\t\t// Remove the `linkHref` attribute and all link decorators from the selection.\n\t\t\t\t// It stops adding a new content into the link element.\n\t\t\t\t[ 'linkHref', ...truthyManualDecorators, ...falsyManualDecorators ].forEach( item => {\n\t\t\t\t\twriter.removeSelectionAttribute( item );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\t// If selection has non-collapsed ranges, we change attribute on nodes inside those ranges\n\t\t\t\t// omitting nodes where the `linkHref` attribute is disallowed.\n\t\t\t\tconst ranges = model.schema.getValidRanges( selection.getRanges(), 'linkHref' );\n\n\t\t\t\t// But for the first, check whether the `linkHref` attribute is allowed on selected blocks (e.g. the \"image\" element).\n\t\t\t\tconst allowedRanges = [];\n\n\t\t\t\tfor ( const element of selection.getSelectedBlocks() ) {\n\t\t\t\t\tif ( model.schema.checkAttribute( element, 'linkHref' ) ) {\n\t\t\t\t\t\tallowedRanges.push( writer.createRangeOn( element ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Ranges that accept the `linkHref` attribute. Since we will iterate over `allowedRanges`, let's clone it.\n\t\t\t\tconst rangesToUpdate = allowedRanges.slice();\n\n\t\t\t\t// For all selection ranges we want to check whether given range is inside an element that accepts the `linkHref` attribute.\n\t\t\t\t// If so, we don't want to propagate applying the attribute to its children.\n\t\t\t\tfor ( const range of ranges ) {\n\t\t\t\t\tif ( this._isRangeToUpdate( range, allowedRanges ) ) {\n\t\t\t\t\t\trangesToUpdate.push( range );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor ( const range of rangesToUpdate ) {\n\t\t\t\t\tlet linkRange = range;\n\n\t\t\t\t\tif ( rangesToUpdate.length === 1 ) {\n\t\t\t\t\t\t// Current text of the link in the document.\n\t\t\t\t\t\tconst linkText = extractTextFromSelection( selection );\n\n\t\t\t\t\t\tif ( selection.getAttribute( 'linkHref' ) === linkText ) {\n\t\t\t\t\t\t\tlinkRange = this._updateLinkContent( model, writer, range, href );\n\t\t\t\t\t\t\twriter.setSelection( writer.createSelection( linkRange ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\twriter.setAttribute( 'linkHref', href, linkRange );\n\n\t\t\t\t\ttruthyManualDecorators.forEach( item => {\n\t\t\t\t\t\twriter.setAttribute( item, true, linkRange );\n\t\t\t\t\t} );\n\n\t\t\t\t\tfalsyManualDecorators.forEach( item => {\n\t\t\t\t\t\twriter.removeAttribute( item, linkRange );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Provides information whether a decorator with a given name is present in the currently processed selection.\n\t *\n\t * @param decoratorName The name of the manual decorator used in the model\n\t * @returns The information whether a given decorator is currently present in the selection.\n\t */\n\tprivate _getDecoratorStateFromModel( decoratorName: string ): boolean | undefined {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t// A check for the `LinkImage` plugin. If the selection contains an element, get values from the element.\n\t\t// Currently the selection reads attributes from text nodes only. See #7429 and #7465.\n\t\tif ( isLinkableElement( selectedElement, model.schema ) ) {\n\t\t\treturn selectedElement.getAttribute( decoratorName ) as boolean | undefined;\n\t\t}\n\n\t\treturn selection.getAttribute( decoratorName ) as boolean | undefined;\n\t}\n\n\t/**\n\t * Checks whether specified `range` is inside an element that accepts the `linkHref` attribute.\n\t *\n\t * @param range A range to check.\n\t * @param allowedRanges An array of ranges created on elements where the attribute is accepted.\n\t */\n\tprivate _isRangeToUpdate( range: Range, allowedRanges: Array<Range> ): boolean {\n\t\tfor ( const allowedRange of allowedRanges ) {\n\t\t\t// A range is inside an element that will have the `linkHref` attribute. Do not modify its nodes.\n\t\t\tif ( allowedRange.containsRange( range ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Updates selected link with a new value as its content and as its href attribute.\n\t *\n\t * @param model Model is need to insert content.\n\t * @param writer Writer is need to create text element in model.\n\t * @param range A range where should be inserted content.\n\t * @param href A link value which should be in the href attribute and in the content.\n\t */\n\tprivate _updateLinkContent( model: Model, writer: Writer, range: Range, href: string ): Range {\n\t\tconst text = writer.createText( href, { linkHref: href } );\n\n\t\treturn model.insertContent( text, range );\n\t}\n}\n\n// Returns a text of a link under the collapsed selection or a selection that contains the entire link.\nfunction extractTextFromSelection( selection: DocumentSelection ): string | null {\n\tif ( selection.isCollapsed ) {\n\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\treturn firstPosition!.textNode && firstPosition!.textNode.data;\n\t} else {\n\t\tconst rangeItems = Array.from( selection.getFirstRange()!.getItems() );\n\n\t\tif ( rangeItems.length > 1 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst firstNode = rangeItems[ 0 ];\n\n\t\tif ( firstNode.is( '$text' ) || firstNode.is( '$textProxy' ) ) {\n\t\t\treturn firstNode.data;\n\t\t}\n\n\t\treturn null;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/unlinkcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport { findAttributeRange } from 'ckeditor5/src/typing.js';\n\nimport type LinkCommand from './linkcommand.js';\nimport { isLinkableElement } from './utils.js';\n\n/**\n * The unlink command. It is used by the {@link module:link/link~Link link plugin}.\n */\nexport default class UnlinkCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t// A check for any integration that allows linking elements (e.g. `LinkImage`).\n\t\t// Currently the selection reads attributes from text nodes only. See #7429 and #7465.\n\t\tif ( isLinkableElement( selectedElement, model.schema ) ) {\n\t\t\tthis.isEnabled = model.schema.checkAttribute( selectedElement, 'linkHref' );\n\t\t} else {\n\t\t\tthis.isEnabled = model.schema.checkAttributeInSelection( selection, 'linkHref' );\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is collapsed, it removes the `linkHref` attribute from each node with the same `linkHref` attribute value.\n\t * When the selection is non-collapsed, it removes the `linkHref` attribute from each node in selected ranges.\n\t *\n\t * # Decorators\n\t *\n\t * If {@link module:link/linkconfig~LinkConfig#decorators `config.link.decorators`} is specified,\n\t * all configured decorators are removed together with the `linkHref` attribute.\n\t *\n\t * @fires execute\n\t */\n\tpublic override execute(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst linkCommand: LinkCommand | undefined = editor.commands.get( 'link' );\n\n\t\tmodel.change( writer => {\n\t\t\t// Get ranges to unlink.\n\t\t\tconst rangesToUnlink = selection.isCollapsed ?\n\t\t\t\t[ findAttributeRange(\n\t\t\t\t\tselection.getFirstPosition()!,\n\t\t\t\t\t'linkHref',\n\t\t\t\t\tselection.getAttribute( 'linkHref' ),\n\t\t\t\t\tmodel\n\t\t\t\t) ] :\n\t\t\t\tmodel.schema.getValidRanges( selection.getRanges(), 'linkHref' );\n\n\t\t\t// Remove `linkHref` attribute from specified ranges.\n\t\t\tfor ( const range of rangesToUnlink ) {\n\t\t\t\twriter.removeAttribute( 'linkHref', range );\n\t\t\t\t// If there are registered custom attributes, then remove them during unlink.\n\t\t\t\tif ( linkCommand ) {\n\t\t\t\t\tfor ( const manualDecorator of linkCommand.manualDecorators ) {\n\t\t\t\t\t\twriter.removeAttribute( manualDecorator.id, range );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/utils/manualdecorator\n */\n\nimport { ObservableMixin, type ArrayOrItem } from 'ckeditor5/src/utils.js';\nimport type { MatcherObjectPattern } from 'ckeditor5/src/engine.js';\nimport type { NormalizedLinkDecoratorManualDefinition } from '../utils.js';\n\n/**\n * Helper class that stores manual decorators with observable {@link module:link/utils/manualdecorator~ManualDecorator#value}\n * to support integration with the UI state. An instance of this class is a model with the state of individual manual decorators.\n * These decorators are kept as collections in {@link module:link/linkcommand~LinkCommand#manualDecorators}.\n */\nexport default class ManualDecorator extends /* #__PURE__ */ ObservableMixin() {\n\t/**\n\t * An ID of a manual decorator which is the name of the attribute in the model, for example: 'linkManualDecorator0'.\n\t */\n\tpublic id: string;\n\n\t/**\n\t * The value of the current manual decorator. It reflects its state from the UI.\n\t *\n\t * @observable\n\t */\n\tdeclare public value: boolean | undefined;\n\n\t/**\n\t * The default value of manual decorator.\n\t */\n\tpublic defaultValue?: boolean;\n\n\t/**\n\t * The label used in the user interface to toggle the manual decorator.\n\t */\n\tpublic label: string;\n\n\t/**\n\t * A set of attributes added to downcasted data when the decorator is activated for a specific link.\n\t * Attributes should be added in a form of attributes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t */\n\tpublic attributes?: Record<string, string>;\n\n\t/**\n\t * A set of classes added to downcasted data when the decorator is activated for a specific link.\n\t * Classes should be added in a form of classes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t */\n\tpublic classes?: ArrayOrItem<string>;\n\n\t/**\n\t * A set of styles added to downcasted data when the decorator is activated for a specific link.\n\t * Styles should be added in a form of styles defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t */\n\tpublic styles?: Record<string, string>;\n\n\t/**\n\t * Creates a new instance of {@link module:link/utils/manualdecorator~ManualDecorator}.\n\t *\n\t * @param config.id The name of the attribute used in the model that represents a given manual decorator.\n\t * For example: `'linkIsExternal'`.\n\t * @param config.label The label used in the user interface to toggle the manual decorator.\n\t * @param config.attributes A set of attributes added to output data when the decorator is active for a specific link.\n\t * Attributes should keep the format of attributes defined in {@link module:engine/view/elementdefinition~ElementDefinition}.\n\t * @param [config.defaultValue] Controls whether the decorator is \"on\" by default.\n\t */\n\tconstructor( { id, label, attributes, classes, styles, defaultValue }: NormalizedLinkDecoratorManualDefinition ) {\n\t\tsuper();\n\n\t\tthis.id = id;\n\t\tthis.set( 'value', undefined );\n\t\tthis.defaultValue = defaultValue;\n\t\tthis.label = label;\n\t\tthis.attributes = attributes;\n\t\tthis.classes = classes;\n\t\tthis.styles = styles;\n\t}\n\n\t/**\n\t * Returns {@link module:engine/view/matcher~MatcherPattern} with decorator attributes.\n\t *\n\t * @internal\n\t */\n\tpublic _createPattern(): MatcherObjectPattern {\n\t\treturn {\n\t\t\tattributes: this.attributes,\n\t\t\tclasses: this.classes,\n\t\t\tstyles: this.styles\n\t\t};\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/linkediting\n */\n\nimport {\n\tPlugin,\n\ttype Editor\n} from 'ckeditor5/src/core.js';\nimport type {\n\tSchema,\n\tWriter,\n\tViewElement,\n\tViewDocumentKeyDownEvent,\n\tViewDocumentClickEvent,\n\tDocumentSelectionChangeAttributeEvent\n} from 'ckeditor5/src/engine.js';\nimport {\n\tInput,\n\tTwoStepCaretMovement,\n\tinlineHighlight\n} from 'ckeditor5/src/typing.js';\nimport {\n\tClipboardPipeline,\n\ttype ClipboardContentInsertionEvent\n} from 'ckeditor5/src/clipboard.js';\nimport { keyCodes, env } from 'ckeditor5/src/utils.js';\n\nimport LinkCommand from './linkcommand.js';\nimport UnlinkCommand from './unlinkcommand.js';\nimport ManualDecorator from './utils/manualdecorator.js';\nimport {\n\tcreateLinkElement,\n\tensureSafeUrl,\n\tgetLocalizedDecorators,\n\tnormalizeDecorators,\n\topenLink,\n\taddLinkProtocolIfApplicable,\n\ttype NormalizedLinkDecoratorAutomaticDefinition,\n\ttype NormalizedLinkDecoratorManualDefinition\n} from './utils.js';\n\nimport '../theme/link.css';\n\nconst HIGHLIGHT_CLASS = 'ck-link_selected';\nconst DECORATOR_AUTOMATIC = 'automatic';\nconst DECORATOR_MANUAL = 'manual';\nconst EXTERNAL_LINKS_REGEXP = /^(https?:)?\\/\\//;\n\n/**\n * The link engine feature.\n *\n * It introduces the `linkHref=\"url\"` attribute in the model which renders to the view as a `<a href=\"url\">` element\n * as well as `'link'` and `'unlink'` commands.\n */\nexport default class LinkEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LinkEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\t// Clipboard is required for handling cut and paste events while typing over the link.\n\t\treturn [ TwoStepCaretMovement, Input, ClipboardPipeline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'link', {\n\t\t\tallowCreatingEmptyLinks: false,\n\t\t\taddTargetToExternalLinks: false\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst allowedProtocols = this.editor.config.get( 'link.allowedProtocols' );\n\n\t\t// Allow link attribute on all inline nodes.\n\t\teditor.model.schema.extend( '$text', { allowAttributes: 'linkHref' } );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.attributeToElement( { model: 'linkHref', view: createLinkElement } );\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.attributeToElement( { model: 'linkHref', view: ( href, conversionApi ) => {\n\t\t\t\treturn createLinkElement( ensureSafeUrl( href, allowedProtocols ), conversionApi );\n\t\t\t} } );\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.elementToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'a',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\thref: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: 'linkHref',\n\t\t\t\t\tvalue: ( viewElement: ViewElement ) => viewElement.getAttribute( 'href' )\n\t\t\t\t}\n\t\t\t} );\n\n\t\t// Create linking commands.\n\t\teditor.commands.add( 'link', new LinkCommand( editor ) );\n\t\teditor.commands.add( 'unlink', new UnlinkCommand( editor ) );\n\n\t\tconst linkDecorators = getLocalizedDecorators( editor.t, normalizeDecorators( editor.config.get( 'link.decorators' ) ) );\n\n\t\tthis._enableAutomaticDecorators( linkDecorators\n\t\t\t.filter( ( item ): item is NormalizedLinkDecoratorAutomaticDefinition => item.mode === DECORATOR_AUTOMATIC ) );\n\t\tthis._enableManualDecorators( linkDecorators\n\t\t\t.filter( ( item ): item is NormalizedLinkDecoratorManualDefinition => item.mode === DECORATOR_MANUAL ) );\n\n\t\t// Enable two-step caret movement for `linkHref` attribute.\n\t\tconst twoStepCaretMovementPlugin = editor.plugins.get( TwoStepCaretMovement );\n\t\ttwoStepCaretMovementPlugin.registerAttribute( 'linkHref' );\n\n\t\t// Setup highlight over selected link.\n\t\tinlineHighlight( editor, 'linkHref', 'a', HIGHLIGHT_CLASS );\n\n\t\t// Handle link following by CTRL+click or ALT+ENTER\n\t\tthis._enableLinkOpen();\n\n\t\t// Clears the DocumentSelection decorator attributes if the selection is no longer in a link (for example while using 2-SCM).\n\t\tthis._enableSelectionAttributesFixer();\n\n\t\t// Handle adding default protocol to pasted links.\n\t\tthis._enableClipboardIntegration();\n\t}\n\n\t/**\n\t * Processes an array of configured {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic decorators}\n\t * and registers a {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher downcast dispatcher}\n\t * for each one of them. Downcast dispatchers are obtained using the\n\t * {@link module:link/utils/automaticdecorators~AutomaticDecorators#getDispatcher} method.\n\t *\n\t * **Note**: This method also activates the automatic external link decorator if enabled with\n\t * {@link module:link/linkconfig~LinkConfig#addTargetToExternalLinks `config.link.addTargetToExternalLinks`}.\n\t */\n\tprivate _enableAutomaticDecorators( automaticDecoratorDefinitions: Array<NormalizedLinkDecoratorAutomaticDefinition> ): void {\n\t\tconst editor = this.editor;\n\t\t// Store automatic decorators in the command instance as we do the same with manual decorators.\n\t\t// Thanks to that, `LinkImageEditing` plugin can re-use the same definitions.\n\t\tconst command: LinkCommand = editor.commands.get( 'link' )!;\n\t\tconst automaticDecorators = command.automaticDecorators;\n\n\t\t// Adds a default decorator for external links.\n\t\tif ( editor.config.get( 'link.addTargetToExternalLinks' ) ) {\n\t\t\tautomaticDecorators.add( {\n\t\t\t\tid: 'linkIsExternal',\n\t\t\t\tmode: DECORATOR_AUTOMATIC,\n\t\t\t\tcallback: url => !!url && EXTERNAL_LINKS_REGEXP.test( url ),\n\t\t\t\tattributes: {\n\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\trel: 'noopener noreferrer'\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tautomaticDecorators.add( automaticDecoratorDefinitions );\n\n\t\tif ( automaticDecorators.length ) {\n\t\t\teditor.conversion.for( 'downcast' ).add( automaticDecorators.getDispatcher() );\n\t\t}\n\t}\n\n\t/**\n\t * Processes an array of configured {@link module:link/linkconfig~LinkDecoratorManualDefinition manual decorators},\n\t * transforms them into {@link module:link/utils/manualdecorator~ManualDecorator} instances and stores them in the\n\t * {@link module:link/linkcommand~LinkCommand#manualDecorators} collection (a model for manual decorators state).\n\t *\n\t * Also registers an {@link module:engine/conversion/downcasthelpers~DowncastHelpers#attributeToElement attribute-to-element}\n\t * converter for each manual decorator and extends the {@link module:engine/model/schema~Schema model's schema}\n\t * with adequate model attributes.\n\t */\n\tprivate _enableManualDecorators( manualDecoratorDefinitions: Array<NormalizedLinkDecoratorManualDefinition> ): void {\n\t\tif ( !manualDecoratorDefinitions.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst command: LinkCommand = editor.commands.get( 'link' )!;\n\t\tconst manualDecorators = command.manualDecorators;\n\n\t\tmanualDecoratorDefinitions.forEach( decoratorDefinition => {\n\t\t\teditor.model.schema.extend( '$text', { allowAttributes: decoratorDefinition.id } );\n\n\t\t\t// Keeps reference to manual decorator to decode its name to attributes during downcast.\n\t\t\tconst decorator = new ManualDecorator( decoratorDefinition );\n\n\t\t\tmanualDecorators.add( decorator );\n\n\t\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t\t\t\tmodel: decorator.id,\n\t\t\t\tview: ( manualDecoratorValue, { writer, schema }, { item } ) => {\n\t\t\t\t\t// Manual decorators for block links are handled e.g. in LinkImageEditing.\n\t\t\t\t\tif ( !( item.is( 'selection' ) || schema.isInline( item ) ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( manualDecoratorValue ) {\n\t\t\t\t\t\tconst element = writer.createAttributeElement( 'a', decorator.attributes, { priority: 5 } );\n\n\t\t\t\t\t\tif ( decorator.classes ) {\n\t\t\t\t\t\t\twriter.addClass( decorator.classes, element );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor ( const key in decorator.styles ) {\n\t\t\t\t\t\t\twriter.setStyle( key, decorator.styles[ key ], element );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twriter.setCustomProperty( 'link', true, element );\n\n\t\t\t\t\t\treturn element;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'a',\n\t\t\t\t\t...decorator._createPattern()\n\t\t\t\t},\n\t\t\t\tmodel: {\n\t\t\t\t\tkey: decorator.id\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches handlers for {@link module:engine/view/document~Document#event:enter} and\n\t * {@link module:engine/view/document~Document#event:click} to enable link following.\n\t */\n\tprivate _enableLinkOpen(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\tthis.listenTo<ViewDocumentClickEvent>( viewDocument, 'click', ( evt, data ) => {\n\t\t\tconst shouldOpen = env.isMac ? data.domEvent.metaKey : data.domEvent.ctrlKey;\n\n\t\t\tif ( !shouldOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet clickedElement: Element | null = data.domTarget;\n\n\t\t\tif ( clickedElement.tagName.toLowerCase() != 'a' ) {\n\t\t\t\tclickedElement = clickedElement.closest( 'a' );\n\t\t\t}\n\n\t\t\tif ( !clickedElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst url = clickedElement.getAttribute( 'href' );\n\n\t\t\tif ( !url ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tevt.stop();\n\t\t\tdata.preventDefault();\n\n\t\t\topenLink( url );\n\t\t}, { context: '$capture' } );\n\n\t\t// Open link on Alt+Enter.\n\t\tthis.listenTo<ViewDocumentKeyDownEvent>( viewDocument, 'keydown', ( evt, data ) => {\n\t\t\tconst linkCommand: LinkCommand = editor.commands.get( 'link' )!;\n\t\t\tconst url = linkCommand!.value;\n\t\t\tconst shouldOpen = !!url && data.keyCode === keyCodes.enter && data.altKey;\n\n\t\t\tif ( !shouldOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tevt.stop();\n\n\t\t\topenLink( url );\n\t\t} );\n\t}\n\n\t/**\n\t * Watches the DocumentSelection attribute changes and removes link decorator attributes when the linkHref attribute is removed.\n\t *\n\t * This is to ensure that there is no left-over link decorator attributes on the document selection that is no longer in a link.\n\t */\n\tprivate _enableSelectionAttributesFixer(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tthis.listenTo<DocumentSelectionChangeAttributeEvent>( selection, 'change:attribute', ( evt, { attributeKeys } ) => {\n\t\t\tif ( !attributeKeys.includes( 'linkHref' ) || selection.hasAttribute( 'linkHref' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodel.change( writer => {\n\t\t\t\tremoveLinkAttributesFromSelection( writer, getLinkAttributesAllowedOnText( model.schema ) );\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Enables URL fixing on pasting.\n\t */\n\tprivate _enableClipboardIntegration(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst defaultProtocol = this.editor.config.get( 'link.defaultProtocol' );\n\n\t\tif ( !defaultProtocol ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.listenTo<ClipboardContentInsertionEvent>( editor.plugins.get( 'ClipboardPipeline' ), 'contentInsertion', ( evt, data ) => {\n\t\t\tmodel.change( writer => {\n\t\t\t\tconst range = writer.createRangeIn( data.content );\n\n\t\t\t\tfor ( const item of range.getItems() ) {\n\t\t\t\t\tif ( item.hasAttribute( 'linkHref' ) ) {\n\t\t\t\t\t\tconst newLink = addLinkProtocolIfApplicable( item.getAttribute( 'linkHref' ) as string, defaultProtocol );\n\n\t\t\t\t\t\twriter.setAttribute( 'linkHref', newLink, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n}\n\n/**\n * Make the selection free of link-related model attributes.\n * All link-related model attributes start with \"link\". That includes not only \"linkHref\"\n * but also all decorator attributes (they have dynamic names), or even custom plugins.\n */\nfunction removeLinkAttributesFromSelection( writer: Writer, linkAttributes: Array<string> ): void {\n\twriter.removeSelectionAttribute( 'linkHref' );\n\n\tfor ( const attribute of linkAttributes ) {\n\t\twriter.removeSelectionAttribute( attribute );\n\t}\n}\n\n/**\n * Returns an array containing names of the attributes allowed on `$text` that describes the link item.\n */\nfunction getLinkAttributesAllowedOnText( schema: Schema ): Array<string> {\n\tconst textAttributes = schema.getDefinition( '$text' )!.allowAttributes;\n\n\treturn textAttributes.filter( attribute => attribute.startsWith( 'link' ) );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/ui/linkformview\n */\n\nimport {\n\tButtonView,\n\tFocusCycler,\n\tLabeledFieldView,\n\tSwitchButtonView,\n\tView,\n\tViewCollection,\n\tcreateLabeledInputText,\n\tsubmitHandler,\n\ttype InputTextView,\n\ttype FocusableView\n} from 'ckeditor5/src/ui.js';\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\ttype Collection,\n\ttype Locale\n} from 'ckeditor5/src/utils.js';\nimport { icons } from 'ckeditor5/src/core.js';\n\nimport type LinkCommand from '../linkcommand.js';\nimport type ManualDecorator from '../utils/manualdecorator.js';\n\n// See: #8833.\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';\nimport '../../theme/linkform.css';\n\n/**\n * The link form view controller class.\n *\n * See {@link module:link/ui/linkformview~LinkFormView}.\n */\nexport default class LinkFormView extends View {\n\t/**\n\t * Tracks information about DOM focus in the form.\n\t */\n\tpublic readonly focusTracker = new FocusTracker();\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes = new KeystrokeHandler();\n\n\t/**\n\t * The URL input view.\n\t */\n\tpublic urlInputView: LabeledFieldView<InputTextView>;\n\n\t/**\n\t * The Save button view.\n\t */\n\tpublic saveButtonView: ButtonView;\n\n\t/**\n\t * The Cancel button view.\n\t */\n\tpublic cancelButtonView: ButtonView;\n\n\t/**\n\t * A collection of {@link module:ui/button/switchbuttonview~SwitchButtonView},\n\t * which corresponds to {@link module:link/linkcommand~LinkCommand#manualDecorators manual decorators}\n\t * configured in the editor.\n\t */\n\tprivate readonly _manualDecoratorSwitches: ViewCollection<SwitchButtonView>;\n\n\t/**\n\t * A collection of child views in the form.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * An array of form validators used by {@link #isValid}.\n\t */\n\tprivate readonly _validators: Array<LinkFormValidatorCallback>;\n\n\t/**\n\t * A collection of views that can be focused in the form.\n\t */\n\tprivate readonly _focusables = new ViewCollection<FocusableView>();\n\n\t/**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */\n\tprivate readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * Creates an instance of the {@link module:link/ui/linkformview~LinkFormView} class.\n\t *\n\t * Also see {@link #render}.\n\t *\n\t * @param locale The localization services instance.\n\t * @param linkCommand Reference to {@link module:link/linkcommand~LinkCommand}.\n\t * @param validators  Form validators used by {@link #isValid}.\n\t */\n\tconstructor( locale: Locale, linkCommand: LinkCommand, validators: Array<LinkFormValidatorCallback> ) {\n\t\tsuper( locale );\n\n\t\tconst t = locale.t;\n\n\t\tthis._validators = validators;\n\t\tthis.urlInputView = this._createUrlInput();\n\t\tthis.saveButtonView = this._createButton( t( 'Save' ), icons.check, 'ck-button-save' );\n\t\tthis.saveButtonView.type = 'submit';\n\t\tthis.cancelButtonView = this._createButton( t( 'Cancel' ), icons.cancel, 'ck-button-cancel', 'cancel' );\n\t\tthis._manualDecoratorSwitches = this._createManualDecoratorSwitches( linkCommand );\n\t\tthis.children = this._createFormChildren( linkCommand.manualDecorators );\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tconst classList = [ 'ck', 'ck-link-form', 'ck-responsive-form' ];\n\n\t\tif ( linkCommand.manualDecorators.length ) {\n\t\t\tclassList.push( 'ck-link-form_layout-vertical', 'ck-vertical-form' );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\n\t\t\tattributes: {\n\t\t\t\tclass: classList,\n\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/90\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * Obtains the state of the {@link module:ui/button/switchbuttonview~SwitchButtonView switch buttons} representing\n\t * {@link module:link/linkcommand~LinkCommand#manualDecorators manual link decorators}\n\t * in the {@link module:link/ui/linkformview~LinkFormView}.\n\t *\n\t * @returns Key-value pairs, where the key is the name of the decorator and the value is its state.\n\t */\n\tpublic getDecoratorSwitchesState(): Record<string, boolean> {\n\t\treturn Array\n\t\t\t.from( this._manualDecoratorSwitches as Iterable<SwitchButtonView & { name: string }> )\n\t\t\t.reduce( ( accumulator, switchButton ) => {\n\t\t\t\taccumulator[ switchButton.name ] = switchButton.isOn;\n\t\t\t\treturn accumulator;\n\t\t\t}, {} as Record<string, boolean> );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\tconst childViews = [\n\t\t\tthis.urlInputView,\n\t\t\t...this._manualDecoratorSwitches,\n\t\t\tthis.saveButtonView,\n\t\t\tthis.cancelButtonView\n\t\t];\n\n\t\tchildViews.forEach( v => {\n\t\t\t// Register the view as focusable.\n\t\t\tthis._focusables.add( v );\n\n\t\t\t// Register the view in the focus tracker.\n\t\t\tthis.focusTracker.add( v.element! );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the fist {@link #_focusables} in the form.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Validates the form and returns `false` when some fields are invalid.\n\t */\n\tpublic isValid(): boolean {\n\t\tthis.resetFormStatus();\n\n\t\tfor ( const validator of this._validators ) {\n\t\t\tconst errorText = validator( this );\n\n\t\t\t// One error per field is enough.\n\t\t\tif ( errorText ) {\n\t\t\t\t// Apply updated error.\n\t\t\t\tthis.urlInputView.errorText = errorText;\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Cleans up the supplementary error and information text of the {@link #urlInputView}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */\n\tpublic resetFormStatus(): void {\n\t\tthis.urlInputView.errorText = null;\n\t}\n\n\t/**\n\t * Creates a labeled input view.\n\t *\n\t * @returns Labeled field view instance.\n\t */\n\tprivate _createUrlInput(): LabeledFieldView<InputTextView> {\n\t\tconst t = this.locale!.t;\n\t\tconst labeledInput = new LabeledFieldView( this.locale, createLabeledInputText );\n\n\t\tlabeledInput.fieldView.inputMode = 'url';\n\t\tlabeledInput.label = t( 'Link URL' );\n\n\t\treturn labeledInput;\n\t}\n\n\t/**\n\t * Creates a button view.\n\t *\n\t * @param label The button label.\n\t * @param icon The button icon.\n\t * @param className The additional button CSS class name.\n\t * @param eventName An event name that the `ButtonView#execute` event will be delegated to.\n\t * @returns The button view instance.\n\t */\n\tprivate _createButton( label: string, icon: string, className: string, eventName?: string ): ButtonView {\n\t\tconst button = new ButtonView( this.locale );\n\n\t\tbutton.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\tbutton.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: className\n\t\t\t}\n\t\t} );\n\n\t\tif ( eventName ) {\n\t\t\tbutton.delegate( 'execute' ).to( this, eventName );\n\t\t}\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Populates {@link module:ui/viewcollection~ViewCollection} of {@link module:ui/button/switchbuttonview~SwitchButtonView}\n\t * made based on {@link module:link/linkcommand~LinkCommand#manualDecorators}.\n\t *\n\t * @param linkCommand A reference to the link command.\n\t * @returns ViewCollection of switch buttons.\n\t */\n\tprivate _createManualDecoratorSwitches( linkCommand: LinkCommand ): ViewCollection<SwitchButtonView> {\n\t\tconst switches = this.createCollection<SwitchButtonView>();\n\n\t\tfor ( const manualDecorator of linkCommand.manualDecorators ) {\n\t\t\tconst switchButton: SwitchButtonView & { name?: string } = new SwitchButtonView( this.locale );\n\n\t\t\tswitchButton.set( {\n\t\t\t\tname: manualDecorator.id,\n\t\t\t\tlabel: manualDecorator.label,\n\t\t\t\twithText: true\n\t\t\t} );\n\n\t\t\tswitchButton.bind( 'isOn' ).toMany( [ manualDecorator, linkCommand ], 'value', ( decoratorValue, commandValue ) => {\n\t\t\t\treturn commandValue === undefined && decoratorValue === undefined ? !!manualDecorator.defaultValue : !!decoratorValue;\n\t\t\t} );\n\n\t\t\tswitchButton.on( 'execute', () => {\n\t\t\t\tmanualDecorator.set( 'value', !switchButton.isOn );\n\t\t\t} );\n\n\t\t\tswitches.add( switchButton );\n\t\t}\n\n\t\treturn switches;\n\t}\n\n\t/**\n\t * Populates the {@link #children} collection of the form.\n\t *\n\t * If {@link module:link/linkcommand~LinkCommand#manualDecorators manual decorators} are configured in the editor, it creates an\n\t * additional `View` wrapping all {@link #_manualDecoratorSwitches} switch buttons corresponding\n\t * to these decorators.\n\t *\n\t * @param manualDecorators A reference to\n\t * the collection of manual decorators stored in the link command.\n\t * @returns The children of link form view.\n\t */\n\tprivate _createFormChildren( manualDecorators: Collection<ManualDecorator> ): ViewCollection {\n\t\tconst children = this.createCollection();\n\n\t\tchildren.add( this.urlInputView );\n\n\t\tif ( manualDecorators.length ) {\n\t\t\tconst additionalButtonsView = new View();\n\n\t\t\tadditionalButtonsView.setTemplate( {\n\t\t\t\ttag: 'ul',\n\t\t\t\tchildren: this._manualDecoratorSwitches.map( switchButton => ( {\n\t\t\t\t\ttag: 'li',\n\t\t\t\t\tchildren: [ switchButton ],\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-list__item'\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t} ) ),\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: [\n\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t'ck-reset',\n\t\t\t\t\t\t'ck-list'\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t} );\n\t\t\tchildren.add( additionalButtonsView );\n\t\t}\n\n\t\tchildren.add( this.saveButtonView );\n\t\tchildren.add( this.cancelButtonView );\n\n\t\treturn children;\n\t}\n\n\t/**\n\t * The native DOM `value` of the {@link #urlInputView} element.\n\t *\n\t * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}\n\t * which works one way only and may not represent the actual state of the component in the DOM.\n\t */\n\tpublic get url(): string | null {\n\t\tconst { element } = this.urlInputView.fieldView;\n\n\t\tif ( !element ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn element.value.trim();\n\t}\n}\n\n/**\n * Callback used by {@link ~LinkFormView} to check if passed form value is valid.\n *\n * \t* If `undefined` is returned, it is assumed that the form value is correct and there is no error.\n * \t* If string is returned, it is assumed that the form value is incorrect and the returned string is displayed in the error label\n */\nexport type LinkFormValidatorCallback = ( form: LinkFormView ) => string | undefined;\n\n/**\n * Fired when the form view is submitted (when one of the children triggered the submit event),\n * for example with a click on {@link ~LinkFormView#saveButtonView}.\n *\n * @eventName ~LinkFormView#submit\n */\nexport type SubmitEvent = {\n\tname: 'submit';\n\targs: [];\n};\n\n/**\n * Fired when the form view is canceled, for example with a click on {@link ~LinkFormView#cancelButtonView}.\n *\n * @eventName ~LinkFormView#cancel\n */\nexport type CancelEvent = {\n\tname: 'cancel';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/ui/linkactionsview\n */\n\nimport { ButtonView, View, ViewCollection, FocusCycler, type FocusableView } from 'ckeditor5/src/ui.js';\nimport { FocusTracker, KeystrokeHandler, type LocaleTranslate, type Locale } from 'ckeditor5/src/utils.js';\nimport { icons } from 'ckeditor5/src/core.js';\n\nimport { ensureSafeUrl } from '../utils.js';\n\n// See: #8833.\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';\nimport '../../theme/linkactions.css';\n\nimport unlinkIcon from '../../theme/icons/unlink.svg';\nimport type { LinkConfig } from '../linkconfig.js';\n\n/**\n * The link actions view class. This view displays the link preview, allows\n * unlinking or editing the link.\n */\nexport default class LinkActionsView extends View {\n\t/**\n\t * Tracks information about DOM focus in the actions.\n\t */\n\tpublic readonly focusTracker = new FocusTracker();\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes = new KeystrokeHandler();\n\n\t/**\n\t * The href preview view.\n\t */\n\tpublic previewButtonView: ButtonView;\n\n\t/**\n\t * The unlink button view.\n\t */\n\tpublic unlinkButtonView: ButtonView;\n\n\t/**\n\t * The edit link button view.\n\t */\n\tpublic editButtonView: ButtonView;\n\n\t/**\n\t * The value of the \"href\" attribute of the link to use in the {@link #previewButtonView}.\n\t *\n\t * @observable\n\t */\n\tdeclare public href: string | undefined;\n\n\t/**\n\t * A collection of views that can be focused in the view.\n\t */\n\tprivate readonly _focusables = new ViewCollection<FocusableView>();\n\n\t/**\n\t * Helps cycling over {@link #_focusables} in the view.\n\t */\n\tprivate readonly _focusCycler: FocusCycler;\n\n\tprivate readonly _linkConfig: LinkConfig;\n\n\tdeclare public t: LocaleTranslate;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale, linkConfig: LinkConfig = {} ) {\n\t\tsuper( locale );\n\n\t\tconst t = locale.t;\n\n\t\tthis.previewButtonView = this._createPreviewButton();\n\t\tthis.unlinkButtonView = this._createButton( t( 'Unlink' ), unlinkIcon, 'unlink' );\n\t\tthis.editButtonView = this._createButton( t( 'Edit link' ), icons.pencil, 'edit' );\n\n\t\tthis.set( 'href', undefined );\n\n\t\tthis._linkConfig = linkConfig;\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-link-actions',\n\t\t\t\t\t'ck-responsive-form'\n\t\t\t\t],\n\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/90\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.previewButtonView,\n\t\t\t\tthis.editButtonView,\n\t\t\t\tthis.unlinkButtonView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tconst childViews = [\n\t\t\tthis.previewButtonView,\n\t\t\tthis.editButtonView,\n\t\t\tthis.unlinkButtonView\n\t\t];\n\n\t\tchildViews.forEach( v => {\n\t\t\t// Register the view as focusable.\n\t\t\tthis._focusables.add( v );\n\n\t\t\t// Register the view in the focus tracker.\n\t\t\tthis.focusTracker.add( v.element! );\n\t\t} );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the fist {@link #_focusables} in the actions.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Creates a button view.\n\t *\n\t * @param label The button label.\n\t * @param icon The button icon.\n\t * @param eventName An event name that the `ButtonView#execute` event will be delegated to.\n\t * @returns The button view instance.\n\t */\n\tprivate _createButton( label: string, icon: string, eventName?: string ): ButtonView {\n\t\tconst button = new ButtonView( this.locale );\n\n\t\tbutton.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\tbutton.delegate( 'execute' ).to( this, eventName );\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * Creates a link href preview button.\n\t *\n\t * @returns The button view instance.\n\t */\n\tprivate _createPreviewButton(): ButtonView {\n\t\tconst button = new ButtonView( this.locale );\n\t\tconst bind = this.bindTemplate;\n\t\tconst t = this.t;\n\n\t\tbutton.set( {\n\t\t\twithText: true,\n\t\t\ttooltip: t( 'Open link in new tab' )\n\t\t} );\n\n\t\tbutton.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-link-actions__preview'\n\t\t\t\t],\n\t\t\t\thref: bind.to( 'href', href => href && ensureSafeUrl( href, this._linkConfig.allowedProtocols ) ),\n\t\t\t\ttarget: '_blank',\n\t\t\t\trel: 'noopener noreferrer'\n\t\t\t}\n\t\t} );\n\n\t\tbutton.bind( 'label' ).to( this, 'href', href => {\n\t\t\treturn href || t( 'This link has no URL' );\n\t\t} );\n\n\t\tbutton.bind( 'isEnabled' ).to( this, 'href', href => !!href );\n\n\t\tbutton.template!.tag = 'a';\n\t\tbutton.template!.eventListeners = {};\n\n\t\treturn button;\n\t}\n}\n\n/**\n * Fired when the {@link ~LinkActionsView#editButtonView} is clicked.\n *\n * @eventName ~LinkActionsView#edit\n */\nexport type EditEvent = {\n\tname: 'edit';\n\targs: [];\n};\n\n/**\n * Fired when the {@link ~LinkActionsView#unlinkButtonView} is clicked.\n *\n * @eventName ~LinkActionsView#unlink\n */\nexport type UnlinkEvent = {\n\tname: 'unlink';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/linkui\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport {\n\tClickObserver,\n\ttype ViewAttributeElement,\n\ttype ViewDocumentClickEvent,\n\ttype ViewElement,\n\ttype ViewPosition\n} from 'ckeditor5/src/engine.js';\nimport {\n\tButtonView,\n\tContextualBalloon,\n\tclickOutsideHandler,\n\tCssTransitionDisablerMixin,\n\tMenuBarMenuListItemButtonView,\n\ttype ViewWithCssTransitionDisabler\n} from 'ckeditor5/src/ui.js';\nimport type { PositionOptions } from 'ckeditor5/src/utils.js';\nimport { isWidget } from 'ckeditor5/src/widget.js';\n\nimport LinkFormView, { type LinkFormValidatorCallback } from './ui/linkformview.js';\nimport LinkActionsView from './ui/linkactionsview.js';\nimport type LinkCommand from './linkcommand.js';\nimport type UnlinkCommand from './unlinkcommand.js';\nimport { addLinkProtocolIfApplicable, isLinkElement, LINK_KEYSTROKE } from './utils.js';\n\nimport linkIcon from '../theme/icons/link.svg';\n\nconst VISUAL_SELECTION_MARKER_NAME = 'link-ui';\n\n/**\n * The link UI plugin. It introduces the `'link'` and `'unlink'` buttons and support for the <kbd>Ctrl+K</kbd> keystroke.\n *\n * It uses the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */\nexport default class LinkUI extends Plugin {\n\t/**\n\t * The actions view displayed inside of the balloon.\n\t */\n\tpublic actionsView: LinkActionsView | null = null;\n\n\t/**\n\t * The form view displayed inside the balloon.\n\t */\n\tpublic formView: LinkFormView & ViewWithCssTransitionDisabler | null = null;\n\n\t/**\n\t * The contextual balloon plugin instance.\n\t */\n\tprivate _balloon!: ContextualBalloon;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LinkUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\n\t\teditor.editing.view.addObserver( ClickObserver );\n\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\n\t\t// Create toolbar buttons.\n\t\tthis._createToolbarLinkButton();\n\t\tthis._enableBalloonActivators();\n\n\t\t// Renders a fake visual selection marker on an expanded selection.\n\t\teditor.conversion.for( 'editingDowncast' ).markerToHighlight( {\n\t\t\tmodel: VISUAL_SELECTION_MARKER_NAME,\n\t\t\tview: {\n\t\t\t\tclasses: [ 'ck-fake-link-selection' ]\n\t\t\t}\n\t\t} );\n\n\t\t// Renders a fake visual selection marker on a collapsed selection.\n\t\teditor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t\t\tmodel: VISUAL_SELECTION_MARKER_NAME,\n\t\t\tview: ( data, { writer } ) => {\n\t\t\t\tif ( !data.markerRange.isCollapsed ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst markerElement = writer.createUIElement( 'span' );\n\n\t\t\t\twriter.addClass(\n\t\t\t\t\t[ 'ck-fake-link-selection', 'ck-fake-link-selection_collapsed' ],\n\t\t\t\t\tmarkerElement\n\t\t\t\t);\n\n\t\t\t\treturn markerElement;\n\t\t\t}\n\t\t} );\n\n\t\t// Add the information about the keystrokes to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfos( {\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Create link' ),\n\t\t\t\t\tkeystroke: LINK_KEYSTROKE\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move out of a link' ),\n\t\t\t\t\tkeystroke: [\n\t\t\t\t\t\t[ 'arrowleft', 'arrowleft' ],\n\t\t\t\t\t\t[ 'arrowright', 'arrowright' ]\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n\t\tif ( this.formView ) {\n\t\t\tthis.formView.destroy();\n\t\t}\n\n\t\tif ( this.actionsView ) {\n\t\t\tthis.actionsView.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Creates views.\n\t */\n\tprivate _createViews() {\n\t\tthis.actionsView = this._createActionsView();\n\t\tthis.formView = this._createFormView();\n\n\t\t// Attach lifecycle actions to the the balloon.\n\t\tthis._enableUserBalloonInteractions();\n\t}\n\n\t/**\n\t * Creates the {@link module:link/ui/linkactionsview~LinkActionsView} instance.\n\t */\n\tprivate _createActionsView(): LinkActionsView {\n\t\tconst editor = this.editor;\n\t\tconst actionsView = new LinkActionsView( editor.locale, editor.config.get( 'link' ) );\n\t\tconst linkCommand: LinkCommand = editor.commands.get( 'link' )!;\n\t\tconst unlinkCommand: UnlinkCommand = editor.commands.get( 'unlink' )!;\n\n\t\tactionsView.bind( 'href' ).to( linkCommand, 'value' );\n\t\tactionsView.editButtonView.bind( 'isEnabled' ).to( linkCommand );\n\t\tactionsView.unlinkButtonView.bind( 'isEnabled' ).to( unlinkCommand );\n\n\t\t// Execute unlink command after clicking on the \"Edit\" button.\n\t\tthis.listenTo( actionsView, 'edit', () => {\n\t\t\tthis._addFormView();\n\t\t} );\n\n\t\t// Execute unlink command after clicking on the \"Unlink\" button.\n\t\tthis.listenTo( actionsView, 'unlink', () => {\n\t\t\teditor.execute( 'unlink' );\n\t\t\tthis._hideUI();\n\t\t} );\n\n\t\t// Close the panel on esc key press when the **actions have focus**.\n\t\tactionsView.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideUI();\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Open the form view on Ctrl+K when the **actions have focus**..\n\t\tactionsView.keystrokes.set( LINK_KEYSTROKE, ( data, cancel ) => {\n\t\t\tthis._addFormView();\n\t\t\tcancel();\n\t\t} );\n\n\t\treturn actionsView;\n\t}\n\n\t/**\n\t * Creates the {@link module:link/ui/linkformview~LinkFormView} instance.\n\t */\n\tprivate _createFormView(): LinkFormView & ViewWithCssTransitionDisabler {\n\t\tconst editor = this.editor;\n\t\tconst linkCommand: LinkCommand = editor.commands.get( 'link' )!;\n\t\tconst defaultProtocol = editor.config.get( 'link.defaultProtocol' );\n\n\t\tconst formView = new ( CssTransitionDisablerMixin( LinkFormView ) )( editor.locale, linkCommand, getFormValidators( editor ) );\n\n\t\tformView.urlInputView.fieldView.bind( 'value' ).to( linkCommand, 'value' );\n\n\t\t// Form elements should be read-only when corresponding commands are disabled.\n\t\tformView.urlInputView.bind( 'isEnabled' ).to( linkCommand, 'isEnabled' );\n\n\t\t// Disable the \"save\" button if the command is disabled.\n\t\tformView.saveButtonView.bind( 'isEnabled' ).to( linkCommand, 'isEnabled' );\n\n\t\t// Execute link command after clicking the \"Save\" button.\n\t\tthis.listenTo( formView, 'submit', () => {\n\t\t\tif ( formView.isValid() ) {\n\t\t\t\tconst { value } = formView.urlInputView.fieldView.element!;\n\t\t\t\tconst parsedUrl = addLinkProtocolIfApplicable( value, defaultProtocol );\n\t\t\t\teditor.execute( 'link', parsedUrl, formView.getDecoratorSwitchesState() );\n\t\t\t\tthis._closeFormView();\n\t\t\t}\n\t\t} );\n\n\t\t// Update balloon position when form error changes.\n\t\tthis.listenTo( formView.urlInputView, 'change:errorText', () => {\n\t\t\teditor.ui.update();\n\t\t} );\n\n\t\t// Hide the panel after clicking the \"Cancel\" button.\n\t\tthis.listenTo( formView, 'cancel', () => {\n\t\t\tthis._closeFormView();\n\t\t} );\n\n\t\t// Close the panel on esc key press when the **form has focus**.\n\t\tformView.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._closeFormView();\n\t\t\tcancel();\n\t\t} );\n\n\t\treturn formView;\n\t}\n\n\t/**\n\t * Creates a toolbar Link button. Clicking this button will show\n\t * a {@link #_balloon} attached to the selection.\n\t */\n\tprivate _createToolbarLinkButton(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( 'link', () => {\n\t\t\tconst button = this._createButton( ButtonView );\n\n\t\t\tbutton.set( {\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\treturn button;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:link', () => {\n\t\t\tconst button = this._createButton( MenuBarMenuListItemButtonView );\n\n\t\t\tbutton.set( {\n\t\t\t\trole: 'menuitemcheckbox'\n\t\t\t} );\n\n\t\t\treturn button;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a button for link command to use either in toolbar or in menu bar.\n\t */\n\tprivate _createButton<T extends typeof ButtonView>( ButtonClass: T ): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst command = editor.commands.get( 'link' )!;\n\t\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\t\tconst t = locale.t;\n\n\t\tview.set( {\n\t\t\tlabel: t( 'Link' ),\n\t\t\ticon: linkIcon,\n\t\t\tkeystroke: LINK_KEYSTROKE,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\t\tview.bind( 'isOn' ).to( command, 'value', value => !!value );\n\n\t\t// Show the panel on button click.\n\t\tthis.listenTo( view, 'execute', () => this._showUI( true ) );\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Attaches actions that control whether the balloon panel containing the\n\t * {@link #formView} should be displayed.\n\t */\n\tprivate _enableBalloonActivators(): void {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\t// Handle click on view document and show panel when selection is placed inside the link element.\n\t\t// Keep panel open until selection will be inside the same link element.\n\t\tthis.listenTo<ViewDocumentClickEvent>( viewDocument, 'click', () => {\n\t\t\tconst parentLink = this._getSelectedLinkElement();\n\n\t\t\tif ( parentLink ) {\n\t\t\t\t// Then show panel but keep focus inside editor editable.\n\t\t\t\tthis._showUI();\n\t\t\t}\n\t\t} );\n\n\t\t// Handle the `Ctrl+K` keystroke and show the panel.\n\t\teditor.keystrokes.set( LINK_KEYSTROKE, ( keyEvtData, cancel ) => {\n\t\t\t// Prevent focusing the search bar in FF, Chrome and Edge. See https://github.com/ckeditor/ckeditor5/issues/4811.\n\t\t\tcancel();\n\n\t\t\tif ( editor.commands.get( 'link' )!.isEnabled ) {\n\t\t\t\tthis._showUI( true );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches actions that control whether the balloon panel containing the\n\t * {@link #formView} is visible or not.\n\t */\n\tprivate _enableUserBalloonInteractions(): void {\n\t\t// Focus the form if the balloon is visible and the Tab key has been pressed.\n\t\tthis.editor.keystrokes.set( 'Tab', ( data, cancel ) => {\n\t\t\tif ( this._areActionsVisible && !this.actionsView!.focusTracker.isFocused ) {\n\t\t\t\tthis.actionsView!.focus();\n\t\t\t\tcancel();\n\t\t\t}\n\t\t}, {\n\t\t\t// Use the high priority because the link UI navigation is more important\n\t\t\t// than other feature's actions, e.g. list indentation.\n\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/146\n\t\t\tpriority: 'high'\n\t\t} );\n\n\t\t// Close the panel on the Esc key press when the editable has focus and the balloon is visible.\n\t\tthis.editor.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tif ( this._isUIVisible ) {\n\t\t\t\tthis._hideUI();\n\t\t\t\tcancel();\n\t\t\t}\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: this.formView!,\n\t\t\tactivator: () => this._isUIInPanel,\n\t\t\tcontextElements: () => [ this._balloon.view.element! ],\n\t\t\tcallback: () => this._hideUI()\n\t\t} );\n\t}\n\n\t/**\n\t * Adds the {@link #actionsView} to the {@link #_balloon}.\n\t *\n\t * @internal\n\t */\n\tpublic _addActionsView(): void {\n\t\tif ( !this.actionsView ) {\n\t\t\tthis._createViews();\n\t\t}\n\n\t\tif ( this._areActionsInPanel ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._balloon.add( {\n\t\t\tview: this.actionsView!,\n\t\t\tposition: this._getBalloonPositionData()\n\t\t} );\n\t}\n\n\t/**\n\t * Adds the {@link #formView} to the {@link #_balloon}.\n\t */\n\tprivate _addFormView(): void {\n\t\tif ( !this.formView ) {\n\t\t\tthis._createViews();\n\t\t}\n\n\t\tif ( this._isFormInPanel ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst linkCommand: LinkCommand = editor.commands.get( 'link' )!;\n\n\t\tthis.formView!.disableCssTransitions();\n\t\tthis.formView!.resetFormStatus();\n\n\t\tthis._balloon.add( {\n\t\t\tview: this.formView!,\n\t\t\tposition: this._getBalloonPositionData()\n\t\t} );\n\n\t\t// Make sure that each time the panel shows up, the URL field remains in sync with the value of\n\t\t// the command. If the user typed in the input, then canceled the balloon (`urlInputView.fieldView#value` stays\n\t\t// unaltered) and re-opened it without changing the value of the link command (e.g. because they\n\t\t// clicked the same link), they would see the old value instead of the actual value of the command.\n\t\t// https://github.com/ckeditor/ckeditor5-link/issues/78\n\t\t// https://github.com/ckeditor/ckeditor5-link/issues/123\n\t\tthis.formView!.urlInputView.fieldView.value = linkCommand.value || '';\n\n\t\t// Select input when form view is currently visible.\n\t\tif ( this._balloon.visibleView === this.formView ) {\n\t\t\tthis.formView!.urlInputView.fieldView.select();\n\t\t}\n\n\t\tthis.formView!.enableCssTransitions();\n\t}\n\n\t/**\n\t * Closes the form view. Decides whether the balloon should be hidden completely or if the action view should be shown. This is\n\t * decided upon the link command value (which has a value if the document selection is in the link).\n\t *\n\t * Additionally, if any {@link module:link/linkconfig~LinkConfig#decorators} are defined in the editor configuration, the state of\n\t * switch buttons responsible for manual decorator handling is restored.\n\t */\n\tprivate _closeFormView(): void {\n\t\tconst linkCommand: LinkCommand = this.editor.commands.get( 'link' )!;\n\n\t\t// Restore manual decorator states to represent the current model state. This case is important to reset the switch buttons\n\t\t// when the user cancels the editing form.\n\t\tlinkCommand.restoreManualDecoratorStates();\n\n\t\tif ( linkCommand.value !== undefined ) {\n\t\t\tthis._removeFormView();\n\t\t} else {\n\t\t\tthis._hideUI();\n\t\t}\n\t}\n\n\t/**\n\t * Removes the {@link #formView} from the {@link #_balloon}.\n\t */\n\tprivate _removeFormView(): void {\n\t\tif ( this._isFormInPanel ) {\n\t\t\t// Blur the input element before removing it from DOM to prevent issues in some browsers.\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\t\tthis.formView!.saveButtonView.focus();\n\n\t\t\t// Reset the URL field to update the state of the submit button.\n\t\t\tthis.formView!.urlInputView.fieldView.reset();\n\n\t\t\tthis._balloon.remove( this.formView! );\n\n\t\t\t// Because the form has an input which has focus, the focus must be brought back\n\t\t\t// to the editor. Otherwise, it would be lost.\n\t\t\tthis.editor.editing.view.focus();\n\n\t\t\tthis._hideFakeVisualSelection();\n\t\t}\n\t}\n\n\t/**\n\t * Shows the correct UI type. It is either {@link #formView} or {@link #actionsView}.\n\t *\n\t * @internal\n\t */\n\tpublic _showUI( forceVisible: boolean = false ): void {\n\t\tif ( !this.formView ) {\n\t\t\tthis._createViews();\n\t\t}\n\n\t\t// When there's no link under the selection, go straight to the editing UI.\n\t\tif ( !this._getSelectedLinkElement() ) {\n\t\t\t// Show visual selection on a text without a link when the contextual balloon is displayed.\n\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/4721.\n\t\t\tthis._showFakeVisualSelection();\n\n\t\t\tthis._addActionsView();\n\n\t\t\t// Be sure panel with link is visible.\n\t\t\tif ( forceVisible ) {\n\t\t\t\tthis._balloon.showStack( 'main' );\n\t\t\t}\n\n\t\t\tthis._addFormView();\n\t\t}\n\t\t// If there's a link under the selection...\n\t\telse {\n\t\t\t// Go to the editing UI if actions are already visible.\n\t\t\tif ( this._areActionsVisible ) {\n\t\t\t\tthis._addFormView();\n\t\t\t}\n\t\t\t// Otherwise display just the actions UI.\n\t\t\telse {\n\t\t\t\tthis._addActionsView();\n\t\t\t}\n\n\t\t\t// Be sure panel with link is visible.\n\t\t\tif ( forceVisible ) {\n\t\t\t\tthis._balloon.showStack( 'main' );\n\t\t\t}\n\t\t}\n\n\t\t// Begin responding to ui#update once the UI is added.\n\t\tthis._startUpdatingUI();\n\t}\n\n\t/**\n\t * Removes the {@link #formView} from the {@link #_balloon}.\n\t *\n\t * See {@link #_addFormView}, {@link #_addActionsView}.\n\t */\n\tprivate _hideUI(): void {\n\t\tif ( !this._isUIInPanel ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\n\t\tthis.stopListening( editor.ui, 'update' );\n\t\tthis.stopListening( this._balloon, 'change:visibleView' );\n\n\t\t// Make sure the focus always gets back to the editable _before_ removing the focused form view.\n\t\t// Doing otherwise causes issues in some browsers. See https://github.com/ckeditor/ckeditor5-link/issues/193.\n\t\teditor.editing.view.focus();\n\n\t\t// Remove form first because it's on top of the stack.\n\t\tthis._removeFormView();\n\n\t\t// Then remove the actions view because it's beneath the form.\n\t\tthis._balloon.remove( this.actionsView! );\n\n\t\tthis._hideFakeVisualSelection();\n\t}\n\n\t/**\n\t * Makes the UI react to the {@link module:ui/editorui/editorui~EditorUI#event:update} event to\n\t * reposition itself when the editor UI should be refreshed.\n\t *\n\t * See: {@link #_hideUI} to learn when the UI stops reacting to the `update` event.\n\t */\n\tprivate _startUpdatingUI(): void {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\tlet prevSelectedLink = this._getSelectedLinkElement();\n\t\tlet prevSelectionParent = getSelectionParent();\n\n\t\tconst update = () => {\n\t\t\tconst selectedLink = this._getSelectedLinkElement();\n\t\t\tconst selectionParent = getSelectionParent();\n\n\t\t\t// Hide the panel if:\n\t\t\t//\n\t\t\t// * the selection went out of the EXISTING link element. E.g. user moved the caret out\n\t\t\t//   of the link,\n\t\t\t// * the selection went to a different parent when creating a NEW link. E.g. someone\n\t\t\t//   else modified the document.\n\t\t\t// * the selection has expanded (e.g. displaying link actions then pressing SHIFT+Right arrow).\n\t\t\t//\n\t\t\t// Note: #_getSelectedLinkElement will return a link for a non-collapsed selection only\n\t\t\t// when fully selected.\n\t\t\tif ( ( prevSelectedLink && !selectedLink ) ||\n\t\t\t\t( !prevSelectedLink && selectionParent !== prevSelectionParent ) ) {\n\t\t\t\tthis._hideUI();\n\t\t\t}\n\t\t\t// Update the position of the panel when:\n\t\t\t//  * link panel is in the visible stack\n\t\t\t//  * the selection remains in the original link element,\n\t\t\t//  * there was no link element in the first place, i.e. creating a new link\n\t\t\telse if ( this._isUIVisible ) {\n\t\t\t\t// If still in a link element, simply update the position of the balloon.\n\t\t\t\t// If there was no link (e.g. inserting one), the balloon must be moved\n\t\t\t\t// to the new position in the editing view (a new native DOM range).\n\t\t\t\tthis._balloon.updatePosition( this._getBalloonPositionData() );\n\t\t\t}\n\n\t\t\tprevSelectedLink = selectedLink;\n\t\t\tprevSelectionParent = selectionParent;\n\t\t};\n\n\t\tfunction getSelectionParent() {\n\t\t\treturn viewDocument.selection.focus!.getAncestors()\n\t\t\t\t.reverse()\n\t\t\t\t.find( ( node ): node is ViewElement => node.is( 'element' ) );\n\t\t}\n\n\t\tthis.listenTo( editor.ui, 'update', update );\n\t\tthis.listenTo( this._balloon, 'change:visibleView', update );\n\t}\n\n\t/**\n\t * Returns `true` when {@link #formView} is in the {@link #_balloon}.\n\t */\n\tprivate get _isFormInPanel(): boolean {\n\t\treturn !!this.formView && this._balloon.hasView( this.formView );\n\t}\n\n\t/**\n\t * Returns `true` when {@link #actionsView} is in the {@link #_balloon}.\n\t */\n\tprivate get _areActionsInPanel(): boolean {\n\t\treturn !!this.actionsView && this._balloon.hasView( this.actionsView );\n\t}\n\n\t/**\n\t * Returns `true` when {@link #actionsView} is in the {@link #_balloon} and it is\n\t * currently visible.\n\t */\n\tprivate get _areActionsVisible(): boolean {\n\t\treturn !!this.actionsView && this._balloon.visibleView === this.actionsView;\n\t}\n\n\t/**\n\t * Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon}.\n\t */\n\tprivate get _isUIInPanel(): boolean {\n\t\treturn this._isFormInPanel || this._areActionsInPanel;\n\t}\n\n\t/**\n\t * Returns `true` when {@link #actionsView} or {@link #formView} is in the {@link #_balloon} and it is\n\t * currently visible.\n\t */\n\tprivate get _isUIVisible(): boolean {\n\t\tconst visibleView = this._balloon.visibleView;\n\n\t\treturn !!this.formView && visibleView == this.formView || this._areActionsVisible;\n\t}\n\n\t/**\n\t * Returns positioning options for the {@link #_balloon}. They control the way the balloon is attached\n\t * to the target element or selection.\n\t *\n\t * If the selection is collapsed and inside a link element, the panel will be attached to the\n\t * entire link element. Otherwise, it will be attached to the selection.\n\t */\n\tprivate _getBalloonPositionData(): Partial<PositionOptions> {\n\t\tconst view = this.editor.editing.view;\n\t\tconst model = this.editor.model;\n\t\tconst viewDocument = view.document;\n\t\tlet target: PositionOptions[ 'target' ];\n\n\t\tif ( model.markers.has( VISUAL_SELECTION_MARKER_NAME ) ) {\n\t\t\t// There are cases when we highlight selection using a marker (#7705, #4721).\n\t\t\tconst markerViewElements = Array.from( this.editor.editing.mapper.markerNameToElements( VISUAL_SELECTION_MARKER_NAME )! );\n\t\t\tconst newRange = view.createRange(\n\t\t\t\tview.createPositionBefore( markerViewElements[ 0 ] ),\n\t\t\t\tview.createPositionAfter( markerViewElements[ markerViewElements.length - 1 ] )\n\t\t\t);\n\n\t\t\ttarget = view.domConverter.viewRangeToDom( newRange );\n\t\t} else {\n\t\t\t// Make sure the target is calculated on demand at the last moment because a cached DOM range\n\t\t\t// (which is very fragile) can desynchronize with the state of the editing view if there was\n\t\t\t// any rendering done in the meantime. This can happen, for instance, when an inline widget\n\t\t\t// gets unlinked.\n\t\t\ttarget = () => {\n\t\t\t\tconst targetLink = this._getSelectedLinkElement();\n\n\t\t\t\treturn targetLink ?\n\t\t\t\t\t// When selection is inside link element, then attach panel to this element.\n\t\t\t\t\tview.domConverter.mapViewToDom( targetLink )! :\n\t\t\t\t\t// Otherwise attach panel to the selection.\n\t\t\t\t\tview.domConverter.viewRangeToDom( viewDocument.selection.getFirstRange()! );\n\t\t\t};\n\t\t}\n\n\t\treturn { target };\n\t}\n\n\t/**\n\t * Returns the link {@link module:engine/view/attributeelement~AttributeElement} under\n\t * the {@link module:engine/view/document~Document editing view's} selection or `null`\n\t * if there is none.\n\t *\n\t * **Note**: For a non–collapsed selection, the link element is returned when **fully**\n\t * selected and the **only** element within the selection boundaries, or when\n\t * a linked widget is selected.\n\t */\n\tprivate _getSelectedLinkElement(): ViewAttributeElement | null {\n\t\tconst view = this.editor.editing.view;\n\t\tconst selection = view.document.selection;\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t// The selection is collapsed or some widget is selected (especially inline widget).\n\t\tif ( selection.isCollapsed || selectedElement && isWidget( selectedElement ) ) {\n\t\t\treturn findLinkElementAncestor( selection.getFirstPosition()! );\n\t\t} else {\n\t\t\t// The range for fully selected link is usually anchored in adjacent text nodes.\n\t\t\t// Trim it to get closer to the actual link element.\n\t\t\tconst range = selection.getFirstRange()!.getTrimmed();\n\t\t\tconst startLink = findLinkElementAncestor( range.start );\n\t\t\tconst endLink = findLinkElementAncestor( range.end );\n\n\t\t\tif ( !startLink || startLink != endLink ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Check if the link element is fully selected.\n\t\t\tif ( view.createRangeIn( startLink ).getTrimmed().isEqual( range ) ) {\n\t\t\t\treturn startLink;\n\t\t\t} else {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Displays a fake visual selection when the contextual balloon is displayed.\n\t *\n\t * This adds a 'link-ui' marker into the document that is rendered as a highlight on selected text fragment.\n\t */\n\tprivate _showFakeVisualSelection(): void {\n\t\tconst model = this.editor.model;\n\n\t\tmodel.change( writer => {\n\t\t\tconst range = model.document.selection.getFirstRange()!;\n\n\t\t\tif ( model.markers.has( VISUAL_SELECTION_MARKER_NAME ) ) {\n\t\t\t\twriter.updateMarker( VISUAL_SELECTION_MARKER_NAME, { range } );\n\t\t\t} else {\n\t\t\t\tif ( range.start.isAtEnd ) {\n\t\t\t\t\tconst startPosition = range.start.getLastMatchingPosition(\n\t\t\t\t\t\t( { item } ) => !model.schema.isContent( item ),\n\t\t\t\t\t\t{ boundaries: range }\n\t\t\t\t\t);\n\n\t\t\t\t\twriter.addMarker( VISUAL_SELECTION_MARKER_NAME, {\n\t\t\t\t\t\tusingOperation: false,\n\t\t\t\t\t\taffectsData: false,\n\t\t\t\t\t\trange: writer.createRange( startPosition, range.end )\n\t\t\t\t\t} );\n\t\t\t\t} else {\n\t\t\t\t\twriter.addMarker( VISUAL_SELECTION_MARKER_NAME, {\n\t\t\t\t\t\tusingOperation: false,\n\t\t\t\t\t\taffectsData: false,\n\t\t\t\t\t\trange\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Hides the fake visual selection created in {@link #_showFakeVisualSelection}.\n\t */\n\tprivate _hideFakeVisualSelection(): void {\n\t\tconst model = this.editor.model;\n\n\t\tif ( model.markers.has( VISUAL_SELECTION_MARKER_NAME ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.removeMarker( VISUAL_SELECTION_MARKER_NAME );\n\t\t\t} );\n\t\t}\n\t}\n}\n\n/**\n * Returns a link element if there's one among the ancestors of the provided `Position`.\n *\n * @param View position to analyze.\n * @returns Link element at the position or null.\n */\nfunction findLinkElementAncestor( position: ViewPosition ): ViewAttributeElement | null {\n\treturn position.getAncestors().find( ( ancestor ): ancestor is ViewAttributeElement => isLinkElement( ancestor ) ) || null;\n}\n\n/**\n * Returns link form validation callbacks.\n *\n * @param editor Editor instance.\n */\nfunction getFormValidators( editor: Editor ): Array<LinkFormValidatorCallback> {\n\tconst t = editor.t;\n\tconst allowCreatingEmptyLinks = editor.config.get( 'link.allowCreatingEmptyLinks' );\n\n\treturn [\n\t\tform => {\n\t\t\tif ( !allowCreatingEmptyLinks && !form.url!.length ) {\n\t\t\t\treturn t( 'Link URL must not be empty.' );\n\t\t\t}\n\t\t}\n\t];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/autolink\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type { ClipboardInputTransformationData } from 'ckeditor5/src/clipboard.js';\nimport type { DocumentSelectionChangeEvent, Element, Model, Position, Range, Writer } from 'ckeditor5/src/engine.js';\nimport { Delete, TextWatcher, getLastTextLine, findAttributeRange, type TextWatcherMatchedDataEvent } from 'ckeditor5/src/typing.js';\nimport type { EnterCommand, ShiftEnterCommand } from 'ckeditor5/src/enter.js';\n\nimport { addLinkProtocolIfApplicable, linkHasProtocol } from './utils.js';\nimport LinkEditing from './linkediting.js';\n\nconst MIN_LINK_LENGTH_WITH_SPACE_AT_END = 4; // Ie: \"t.co \" (length 5).\n\n// This was a tweak from https://gist.github.com/dperini/729294.\nconst URL_REG_EXP = new RegExp(\n\t// Group 1: Line start or after a space.\n\t'(^|\\\\s)' +\n\t// Group 2: Detected URL (or e-mail).\n\t'(' +\n\t\t// Protocol identifier or short syntax \"//\"\n\t\t// a. Full form http://user@foo.bar.baz:8080/foo/bar.html#baz?foo=bar\n\t\t'(' +\n\t\t\t'(?:(?:(?:https?|ftp):)?\\\\/\\\\/)' +\n\t\t\t// BasicAuth using user:pass (optional)\n\t\t\t'(?:\\\\S+(?::\\\\S*)?@)?' +\n\t\t\t'(?:' +\n\t\t\t\t// IP address dotted notation octets\n\t\t\t\t// excludes loopback network 0.0.0.0\n\t\t\t\t// excludes reserved space >= 224.0.0.0\n\t\t\t\t// excludes network & broadcast addresses\n\t\t\t\t// (first & last IP address of each class)\n\t\t\t\t'(?:[1-9]\\\\d?|1\\\\d\\\\d|2[01]\\\\d|22[0-3])' +\n\t\t\t\t'(?:\\\\.(?:1?\\\\d{1,2}|2[0-4]\\\\d|25[0-5])){2}' +\n\t\t\t\t'(?:\\\\.(?:[1-9]\\\\d?|1\\\\d\\\\d|2[0-4]\\\\d|25[0-4]))' +\n\t\t\t\t'|' +\n\t\t\t\t'(' +\n\t\t\t\t\t// Do not allow `www.foo` - see https://github.com/ckeditor/ckeditor5/issues/8050.\n\t\t\t\t\t'((?!www\\\\.)|(www\\\\.))' +\n\t\t\t\t\t// Host & domain names.\n\t\t\t\t\t'(?![-_])(?:[-_a-z0-9\\\\u00a1-\\\\uffff]{1,63}\\\\.)+' +\n\t\t\t\t\t// TLD identifier name.\n\t\t\t\t\t'(?:[a-z\\\\u00a1-\\\\uffff]{2,63})' +\n\t\t\t\t')' +\n\t\t\t')' +\n\t\t\t// port number (optional)\n\t\t\t'(?::\\\\d{2,5})?' +\n\t\t\t// resource path (optional)\n\t\t\t'(?:[/?#]\\\\S*)?' +\n\t\t')' +\n\t\t'|' +\n\t\t// b. Short form (either www.example.com or example@example.com)\n\t\t'(' +\n\t\t\t'(www.|(\\\\S+@))' +\n\t\t\t// Host & domain names.\n\t\t\t'((?![-_])(?:[-_a-z0-9\\\\u00a1-\\\\uffff]{1,63}\\\\.))+' +\n\t\t\t// TLD identifier name.\n\t\t\t'(?:[a-z\\\\u00a1-\\\\uffff]{2,63})' +\n\t\t')' +\n\t')$', 'i' );\n\nconst URL_GROUP_IN_MATCH = 2;\n\n/**\n * The autolink plugin.\n */\nexport default class AutoLink extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Delete, LinkEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'AutoLink' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\n\t\tselection.on<DocumentSelectionChangeEvent>( 'change:range', () => {\n\t\t\t// Disable plugin when selection is inside a code block.\n\t\t\tthis.isEnabled = !selection.anchor!.parent.is( 'element', 'codeBlock' );\n\t\t} );\n\n\t\tthis._enableTypingHandling();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tthis._enableEnterHandling();\n\t\tthis._enableShiftEnterHandling();\n\t\tthis._enablePasteLinking();\n\t}\n\n\t/**\n\t * For given position, returns a range that includes the whole link that contains the position.\n\t *\n\t * If position is not inside a link, returns `null`.\n\t */\n\tprivate _expandLinkRange( model: Model, position: Position ): Range | null {\n\t\tif ( position.textNode && position.textNode.hasAttribute( 'linkHref' ) ) {\n\t\t\treturn findAttributeRange( position, 'linkHref', position.textNode.getAttribute( 'linkHref' ), model );\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Extends the document selection to includes all links that intersects with given `selectedRange`.\n\t */\n\tprivate _selectEntireLinks( writer: Writer, selectedRange: Range ): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selStart = selection.getFirstPosition()!;\n\t\tconst selEnd = selection.getLastPosition()!;\n\n\t\tlet updatedSelection = selectedRange.getJoined( this._expandLinkRange( model, selStart ) || selectedRange );\n\t\tif ( updatedSelection ) {\n\t\t\tupdatedSelection = updatedSelection.getJoined( this._expandLinkRange( model, selEnd ) || selectedRange );\n\t\t}\n\n\t\tif ( updatedSelection && ( updatedSelection.start.isBefore( selStart ) || updatedSelection.end.isAfter( selEnd ) ) ) {\n\t\t\t// Only update the selection if it changed.\n\t\t\twriter.setSelection( updatedSelection );\n\t\t}\n\t}\n\n\t/**\n\t * Enables autolinking on pasting a URL when some content is selected.\n\t */\n\tprivate _enablePasteLinking(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst clipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\t\tconst linkCommand = editor.commands.get( 'link' )!;\n\n\t\tclipboardPipeline.on( 'inputTransformation', ( evt, data: ClipboardInputTransformationData ) => {\n\t\t\tif ( !this.isEnabled || !linkCommand.isEnabled || selection.isCollapsed || data.method !== 'paste' ) {\n\t\t\t\t// Abort if we are disabled or the selection is collapsed.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( selection.rangeCount > 1 ) {\n\t\t\t\t// Abort if there are multiple selection ranges.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectedRange = selection.getFirstRange()!;\n\n\t\t\tconst newLink = data.dataTransfer.getData( 'text/plain' );\n\n\t\t\tif ( !newLink ) {\n\t\t\t\t// Abort if there is no plain text on the clipboard.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst matches = newLink.match( URL_REG_EXP );\n\n\t\t\t// If the text in the clipboard has a URL, and that URL is the whole clipboard.\n\t\t\tif ( matches && matches[ 2 ] === newLink ) {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\tthis._selectEntireLinks( writer, selectedRange );\n\t\t\t\t\tlinkCommand.execute( newLink );\n\t\t\t\t} );\n\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Enables autolinking on typing.\n\t */\n\tprivate _enableTypingHandling(): void {\n\t\tconst editor = this.editor;\n\n\t\tconst watcher = new TextWatcher( editor.model, text => {\n\t\t\t// 1. Detect <kbd>Space</kbd> after a text with a potential link.\n\t\t\tif ( !isSingleSpaceAtTheEnd( text ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// 2. Check text before last typed <kbd>Space</kbd>.\n\t\t\tconst url = getUrlAtTextEnd( text.substr( 0, text.length - 1 ) );\n\n\t\t\tif ( url ) {\n\t\t\t\treturn { url };\n\t\t\t}\n\t\t} );\n\n\t\twatcher.on<TextWatcherMatchedDataEvent<{ url: string }>>( 'matched:data', ( evt, data ) => {\n\t\t\tconst { batch, range, url } = data;\n\n\t\t\tif ( !batch.isTyping ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst linkEnd = range.end.getShiftedBy( -1 ); // Executed after a space character.\n\t\t\tconst linkStart = linkEnd.getShiftedBy( -url.length );\n\n\t\t\tconst linkRange = editor.model.createRange( linkStart, linkEnd );\n\n\t\t\tthis._applyAutoLink( url, linkRange );\n\t\t} );\n\n\t\twatcher.bind( 'isEnabled' ).to( this );\n\t}\n\n\t/**\n\t * Enables autolinking on the <kbd>Enter</kbd> key.\n\t */\n\tprivate _enableEnterHandling(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst enterCommand: EnterCommand | undefined = editor.commands.get( 'enter' );\n\n\t\tif ( !enterCommand ) {\n\t\t\treturn;\n\t\t}\n\n\t\tenterCommand.on( 'execute', () => {\n\t\t\tconst position = model.document.selection.getFirstPosition()!;\n\n\t\t\tif ( !position.parent.previousSibling ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst rangeToCheck = model.createRangeIn( position.parent.previousSibling as Element );\n\n\t\t\tthis._checkAndApplyAutoLinkOnRange( rangeToCheck );\n\t\t} );\n\t}\n\n\t/**\n\t * Enables autolinking on the <kbd>Shift</kbd>+<kbd>Enter</kbd> keyboard shortcut.\n\t */\n\tprivate _enableShiftEnterHandling(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tconst shiftEnterCommand: ShiftEnterCommand | undefined = editor.commands.get( 'shiftEnter' );\n\n\t\tif ( !shiftEnterCommand ) {\n\t\t\treturn;\n\t\t}\n\n\t\tshiftEnterCommand.on( 'execute', () => {\n\t\t\tconst position = model.document.selection.getFirstPosition()!;\n\n\t\t\tconst rangeToCheck = model.createRange(\n\t\t\t\tmodel.createPositionAt( position.parent, 0 ),\n\t\t\t\tposition.getShiftedBy( -1 )\n\t\t\t);\n\n\t\t\tthis._checkAndApplyAutoLinkOnRange( rangeToCheck );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if the passed range contains a linkable text.\n\t */\n\tprivate _checkAndApplyAutoLinkOnRange( rangeToCheck: Range ): void {\n\t\tconst model = this.editor.model;\n\t\tconst { text, range } = getLastTextLine( rangeToCheck, model );\n\n\t\tconst url = getUrlAtTextEnd( text );\n\n\t\tif ( url ) {\n\t\t\tconst linkRange = model.createRange(\n\t\t\t\trange.end.getShiftedBy( -url.length ),\n\t\t\t\trange.end\n\t\t\t);\n\n\t\t\tthis._applyAutoLink( url, linkRange );\n\t\t}\n\t}\n\n\t/**\n\t * Applies a link on a given range if the link should be applied.\n\t *\n\t * @param url The URL to link.\n\t * @param range The text range to apply the link attribute to.\n\t */\n\tprivate _applyAutoLink( url: string, range: Range ): void {\n\t\tconst model = this.editor.model;\n\n\t\tconst defaultProtocol = this.editor.config.get( 'link.defaultProtocol' );\n\t\tconst fullUrl = addLinkProtocolIfApplicable( url, defaultProtocol );\n\n\t\tif ( !this.isEnabled || !isLinkAllowedOnRange( range, model ) || !linkHasProtocol( fullUrl ) || linkIsAlreadySet( range ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._persistAutoLink( fullUrl, range );\n\t}\n\n\t/**\n\t * Enqueues autolink changes in the model.\n\t *\n\t * @param url The URL to link.\n\t * @param range The text range to apply the link attribute to.\n\t */\n\tprivate _persistAutoLink( url: string, range: Range ): void {\n\t\tconst model = this.editor.model;\n\t\tconst deletePlugin = this.editor.plugins.get( 'Delete' );\n\n\t\t// Enqueue change to make undo step.\n\t\tmodel.enqueueChange( writer => {\n\t\t\twriter.setAttribute( 'linkHref', url, range );\n\n\t\t\tmodel.enqueueChange( () => {\n\t\t\t\tdeletePlugin.requestUndoOnBackspace();\n\t\t\t} );\n\t\t} );\n\t}\n}\n\n// Check if text should be evaluated by the plugin in order to reduce number of RegExp checks on whole text.\nfunction isSingleSpaceAtTheEnd( text: string ): boolean {\n\treturn text.length > MIN_LINK_LENGTH_WITH_SPACE_AT_END && text[ text.length - 1 ] === ' ' && text[ text.length - 2 ] !== ' ';\n}\n\nfunction getUrlAtTextEnd( text: string ): string | null {\n\tconst match = URL_REG_EXP.exec( text );\n\n\treturn match ? match[ URL_GROUP_IN_MATCH ] : null;\n}\n\nfunction isLinkAllowedOnRange( range: Range, model: Model ): boolean {\n\treturn model.schema.checkAttributeInSelection( model.createSelection( range ), 'linkHref' );\n}\n\nfunction linkIsAlreadySet( range: Range ): boolean {\n\tconst item = range.start.nodeAfter;\n\treturn !!item && item.hasAttribute( 'linkHref' );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/link\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport LinkEditing from './linkediting.js';\nimport LinkUI from './linkui.js';\nimport AutoLink from './autolink.js';\n\n/**\n * The link plugin.\n *\n * This is a \"glue\" plugin that loads the {@link module:link/linkediting~LinkEditing link editing feature}\n * and {@link module:link/linkui~LinkUI link UI feature}.\n */\nexport default class Link extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LinkEditing, LinkUI, AutoLink ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Link' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/linkimageediting\n */\n\nimport {\n\tPlugin,\n\ttype Editor\n} from 'ckeditor5/src/core.js';\nimport {\n\tMatcher,\n\ttype UpcastElementEvent,\n\ttype Node,\n\ttype Element,\n\ttype DowncastAttributeEvent,\n\ttype ViewElement,\n\ttype DowncastDispatcher,\n\ttype UpcastDispatcher\n} from 'ckeditor5/src/engine.js';\nimport { toMap } from 'ckeditor5/src/utils.js';\n\nimport LinkEditing from './linkediting.js';\nimport type ManualDecorator from './utils/manualdecorator.js';\nimport type LinkCommand from './linkcommand.js';\n\nimport type { ImageUtils } from '@ckeditor/ckeditor5-image';\n\n/**\n * The link image engine feature.\n *\n * It accepts the `linkHref=\"url\"` attribute in the model for the {@link module:image/image~Image `<imageBlock>`} element\n * which allows linking images.\n */\nexport default class LinkImageEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ 'ImageEditing', 'ImageUtils', LinkEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LinkImageEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\n\t\tif ( editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\tschema.extend( 'imageBlock', { allowAttributes: [ 'linkHref' ] } );\n\t\t}\n\n\t\teditor.conversion.for( 'upcast' ).add( upcastLink( editor ) );\n\t\teditor.conversion.for( 'downcast' ).add( downcastImageLink( editor ) );\n\n\t\t// Definitions for decorators are provided by the `link` command and the `LinkEditing` plugin.\n\t\tthis._enableAutomaticDecorators();\n\t\tthis._enableManualDecorators();\n\t}\n\n\t/**\n\t * Processes {@link module:link/linkconfig~LinkDecoratorAutomaticDefinition automatic decorators} definitions and\n\t * attaches proper converters that will work when linking an image.`\n\t */\n\tprivate _enableAutomaticDecorators(): void {\n\t\tconst editor = this.editor;\n\t\tconst command: LinkCommand = editor.commands.get( 'link' )!;\n\t\tconst automaticDecorators = command.automaticDecorators;\n\n\t\tif ( automaticDecorators.length ) {\n\t\t\teditor.conversion.for( 'downcast' ).add( automaticDecorators.getDispatcherForLinkedImage() );\n\t\t}\n\t}\n\n\t/**\n\t * Processes transformed {@link module:link/utils/manualdecorator~ManualDecorator} instances and attaches proper converters\n\t * that will work when linking an image.\n\t */\n\tprivate _enableManualDecorators(): void {\n\t\tconst editor = this.editor;\n\t\tconst command: LinkCommand = editor.commands.get( 'link' )!;\n\n\t\tfor ( const decorator of command.manualDecorators ) {\n\t\t\tif ( editor.plugins.has( 'ImageBlockEditing' ) ) {\n\t\t\t\teditor.model.schema.extend( 'imageBlock', { allowAttributes: decorator.id } );\n\t\t\t}\n\n\t\t\tif ( editor.plugins.has( 'ImageInlineEditing' ) ) {\n\t\t\t\teditor.model.schema.extend( 'imageInline', { allowAttributes: decorator.id } );\n\t\t\t}\n\n\t\t\teditor.conversion.for( 'downcast' ).add( downcastImageLinkManualDecorator( decorator ) );\n\t\t\teditor.conversion.for( 'upcast' ).add( upcastImageLinkManualDecorator( editor, decorator ) );\n\t\t}\n\t}\n}\n\n/**\n * Returns a converter for linked block images that consumes the \"href\" attribute\n * if a link contains an image.\n *\n * @param editor The editor instance.\n */\nfunction upcastLink( editor: Editor ): ( dispatcher: UpcastDispatcher ) => void {\n\tconst isImageInlinePluginLoaded = editor.plugins.has( 'ImageInlineEditing' );\n\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\treturn dispatcher => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:a', ( evt, data, conversionApi ) => {\n\t\t\tconst viewLink = data.viewItem;\n\t\t\tconst imageInLink = imageUtils.findViewImgElement( viewLink );\n\n\t\t\tif ( !imageInLink ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst blockImageView = imageInLink.findAncestor( element => imageUtils.isBlockImageView( element ) );\n\n\t\t\t// There are four possible cases to consider here\n\t\t\t//\n\t\t\t// 1. A \"root > ... > figure.image > a > img\" structure.\n\t\t\t// 2. A \"root > ... > figure.image > a > picture > img\" structure.\n\t\t\t// 3. A \"root > ... > block > a > img\" structure.\n\t\t\t// 4. A \"root > ... > block > a > picture > img\" structure.\n\t\t\t//\n\t\t\t// but the last 2 cases should only be considered by this converter when the inline image plugin\n\t\t\t// is NOT loaded in the editor (because otherwise, that would be a plain, linked inline image).\n\t\t\tif ( isImageInlinePluginLoaded && !blockImageView ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// There's an image inside an <a> element - we consume it so it won't be picked up by the Link plugin.\n\t\t\tconst consumableAttributes = { attributes: [ 'href' ] };\n\n\t\t\t// Consume the `href` attribute so the default one will not convert it to $text attribute.\n\t\t\tif ( !conversionApi.consumable.consume( viewLink, consumableAttributes ) ) {\n\t\t\t\t// Might be consumed by something else - i.e. other converter with priority=highest - a standard check.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst linkHref = viewLink.getAttribute( 'href' );\n\n\t\t\t// Missing the 'href' attribute.\n\t\t\tif ( !linkHref ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// A full definition of the image feature.\n\t\t\t// figure > a > img: parent of the view link element is an image element (figure).\n\t\t\tlet modelElement: Node | null = data.modelCursor.parent as Node;\n\n\t\t\tif ( !modelElement.is( 'element', 'imageBlock' ) ) {\n\t\t\t\t// a > img: parent of the view link is not the image (figure) element. We need to convert it manually.\n\t\t\t\tconst conversionResult = conversionApi.convertItem( imageInLink, data.modelCursor );\n\n\t\t\t\t// Set image range as conversion result.\n\t\t\t\tdata.modelRange = conversionResult.modelRange;\n\n\t\t\t\t// Continue conversion where image conversion ends.\n\t\t\t\tdata.modelCursor = conversionResult.modelCursor;\n\n\t\t\t\tmodelElement = data.modelCursor.nodeBefore as Node;\n\t\t\t}\n\n\t\t\tif ( modelElement && modelElement.is( 'element', 'imageBlock' ) ) {\n\t\t\t\t// Set the linkHref attribute from link element on model image element.\n\t\t\t\tconversionApi.writer.setAttribute( 'linkHref', linkHref, modelElement );\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t\t// Using the same priority that `upcastImageLinkManualDecorator()` converter guarantees\n\t\t// that manual decorators will decorate the proper element.\n\t};\n}\n\n/**\n * Creates a converter that adds `<a>` to linked block image view elements.\n */\nfunction downcastImageLink( editor: Editor ): ( dispatcher: DowncastDispatcher ) => void {\n\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\treturn dispatcher => {\n\t\tdispatcher.on<DowncastAttributeEvent<Element>>( 'attribute:linkHref:imageBlock', ( evt, data, conversionApi ) => {\n\t\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The image will be already converted - so it will be present in the view.\n\t\t\tconst viewFigure = conversionApi.mapper.toViewElement( data.item )!;\n\t\t\tconst writer = conversionApi.writer;\n\n\t\t\t// But we need to check whether the link element exists.\n\t\t\tconst linkInImage = Array.from( viewFigure.getChildren() )\n\t\t\t\t.find( ( child ): child is ViewElement => child.is( 'element', 'a' ) );\n\t\t\tconst viewImage = imageUtils.findViewImgElement( viewFigure )!;\n\t\t\t// <picture>...<img/></picture> or <img/>\n\t\t\tconst viewImgOrPicture = viewImage.parent!.is( 'element', 'picture' ) ? viewImage.parent : viewImage;\n\n\t\t\t// If so, update the attribute if it's defined or remove the entire link if the attribute is empty.\n\t\t\tif ( linkInImage ) {\n\t\t\t\tif ( data.attributeNewValue ) {\n\t\t\t\t\twriter.setAttribute( 'href', data.attributeNewValue, linkInImage );\n\t\t\t\t} else {\n\t\t\t\t\twriter.move( writer.createRangeOn( viewImgOrPicture ), writer.createPositionAt( viewFigure, 0 ) );\n\t\t\t\t\twriter.remove( linkInImage );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// But if it does not exist. Let's wrap already converted image by newly created link element.\n\t\t\t\t// 1. Create an empty link element.\n\t\t\t\tconst linkElement = writer.createContainerElement( 'a', { href: data.attributeNewValue } );\n\n\t\t\t\t// 2. Insert link inside the associated image.\n\t\t\t\twriter.insert( writer.createPositionAt( viewFigure, 0 ), linkElement );\n\n\t\t\t\t// 3. Move the image to the link.\n\t\t\t\twriter.move( writer.createRangeOn( viewImgOrPicture ), writer.createPositionAt( linkElement, 0 ) );\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t};\n}\n\n/**\n * Returns a converter that decorates the `<a>` element when the image is the link label.\n */\nfunction downcastImageLinkManualDecorator( decorator: ManualDecorator ): ( dispatcher: DowncastDispatcher ) => void {\n\treturn dispatcher => {\n\t\tdispatcher.on<DowncastAttributeEvent<Element>>( `attribute:${ decorator.id }:imageBlock`, ( evt, data, conversionApi ) => {\n\t\t\tconst viewFigure = conversionApi.mapper.toViewElement( data.item )!;\n\t\t\tconst linkInImage = Array.from( viewFigure.getChildren() )\n\t\t\t\t.find( ( child ): child is ViewElement => child.is( 'element', 'a' ) );\n\n\t\t\t// The <a> element was removed by the time this converter is executed.\n\t\t\t// It may happen when the base `linkHref` and decorator attributes are removed\n\t\t\t// at the same time (see #8401).\n\t\t\tif ( !linkInImage ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor ( const [ key, val ] of toMap( decorator.attributes ) ) {\n\t\t\t\tconversionApi.writer.setAttribute( key, val, linkInImage );\n\t\t\t}\n\n\t\t\tif ( decorator.classes ) {\n\t\t\t\tconversionApi.writer.addClass( decorator.classes, linkInImage );\n\t\t\t}\n\n\t\t\tfor ( const key in decorator.styles ) {\n\t\t\t\tconversionApi.writer.setStyle( key, decorator.styles[ key ], linkInImage );\n\t\t\t}\n\t\t} );\n\t};\n}\n\n/**\n * Returns a converter that checks whether manual decorators should be applied to the link.\n */\nfunction upcastImageLinkManualDecorator( editor: Editor, decorator: ManualDecorator ): ( dispatcher: UpcastDispatcher ) => void {\n\tconst isImageInlinePluginLoaded = editor.plugins.has( 'ImageInlineEditing' );\n\tconst imageUtils: ImageUtils = editor.plugins.get( 'ImageUtils' );\n\n\treturn dispatcher => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:a', ( evt, data, conversionApi ) => {\n\t\t\tconst viewLink = data.viewItem;\n\t\t\tconst imageInLink = imageUtils.findViewImgElement( viewLink );\n\n\t\t\t// We need to check whether an image is inside a link because the converter handles\n\t\t\t// only manual decorators for linked images. See #7975.\n\t\t\tif ( !imageInLink ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst blockImageView = imageInLink.findAncestor( element => imageUtils.isBlockImageView( element ) );\n\n\t\t\tif ( isImageInlinePluginLoaded && !blockImageView ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst matcher = new Matcher( decorator._createPattern() );\n\t\t\tconst result = matcher.match( viewLink );\n\n\t\t\t// The link element does not have required attributes or/and proper values.\n\t\t\tif ( !result ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check whether we can consume those attributes.\n\t\t\tif ( !conversionApi.consumable.consume( viewLink, result.match ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// At this stage we can assume that we have the `<imageBlock>` element.\n\t\t\t// `nodeBefore` comes after conversion: `<a><img></a>`.\n\t\t\t// `parent` comes with full image definition: `<figure><a><img></a></figure>.\n\t\t\t// See the body of the `upcastLink()` function.\n\t\t\tconst modelElement = data.modelCursor.nodeBefore as Element || data.modelCursor.parent;\n\n\t\t\tconversionApi.writer.setAttribute( decorator.id, true, modelElement );\n\t\t}, { priority: 'high' } );\n\t\t// Using the same priority that `upcastLink()` converter guarantees that the linked image was properly converted.\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/linkimageui\n */\n\nimport { ButtonView } from 'ckeditor5/src/ui.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type {\n\tDocumentSelection,\n\tSelection,\n\tViewDocumentClickEvent\n} from 'ckeditor5/src/engine.js';\n\nimport type { ImageUtils } from '@ckeditor/ckeditor5-image';\n\nimport LinkUI from './linkui.js';\nimport LinkEditing from './linkediting.js';\nimport type LinkCommand from './linkcommand.js';\n\nimport { LINK_KEYSTROKE } from './utils.js';\n\nimport linkIcon from '../theme/icons/link.svg';\n\n/**\n * The link image UI plugin.\n *\n * This plugin provides the `'linkImage'` button that can be displayed in the {@link module:image/imagetoolbar~ImageToolbar}.\n * It can be used to wrap images in links.\n */\nexport default class LinkImageUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LinkEditing, LinkUI, 'ImageBlockEditing' ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LinkImageUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\tthis.listenTo<ViewDocumentClickEvent>( viewDocument, 'click', ( evt, data ) => {\n\t\t\tif ( this._isSelectedLinkedImage( editor.model.document.selection ) ) {\n\t\t\t\t// Prevent browser navigation when clicking a linked image.\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\t// Block the `LinkUI` plugin when an image was clicked.\n\t\t\t\t// In such a case, we'd like to display the image toolbar.\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\tthis._createToolbarLinkImageButton();\n\t}\n\n\t/**\n\t * Creates a `LinkImageUI` button view.\n\t *\n\t * Clicking this button shows a {@link module:link/linkui~LinkUI#_balloon} attached to the selection.\n\t * When an image is already linked, the view shows {@link module:link/linkui~LinkUI#actionsView} or\n\t * {@link module:link/linkui~LinkUI#formView} if it is not.\n\t */\n\tprivate _createToolbarLinkImageButton(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'linkImage', locale => {\n\t\t\tconst button = new ButtonView( locale );\n\t\t\tconst plugin = editor.plugins.get( 'LinkUI' );\n\t\t\tconst linkCommand: LinkCommand = editor.commands.get( 'link' )!;\n\n\t\t\tbutton.set( {\n\t\t\t\tisEnabled: true,\n\t\t\t\tlabel: t( 'Link image' ),\n\t\t\t\ticon: linkIcon,\n\t\t\t\tkeystroke: LINK_KEYSTROKE,\n\t\t\t\ttooltip: true,\n\t\t\t\tisToggleable: true\n\t\t\t} );\n\n\t\t\t// Bind button to the command.\n\t\t\tbutton.bind( 'isEnabled' ).to( linkCommand, 'isEnabled' );\n\t\t\tbutton.bind( 'isOn' ).to( linkCommand, 'value', value => !!value );\n\n\t\t\t// Show the actionsView or formView (both from LinkUI) on button click depending on whether the image is linked already.\n\t\t\tthis.listenTo( button, 'execute', () => {\n\t\t\t\tif ( this._isSelectedLinkedImage( editor.model.document.selection ) ) {\n\t\t\t\t\tplugin._addActionsView();\n\t\t\t\t} else {\n\t\t\t\t\tplugin._showUI( true );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn button;\n\t\t} );\n\t}\n\n\t/**\n\t * Returns true if a linked image (either block or inline) is the only selected element\n\t * in the model document.\n\t */\n\tprivate _isSelectedLinkedImage( selection: DocumentSelection | Selection ): boolean {\n\t\tconst selectedModelElement = selection.getSelectedElement();\n\t\tconst imageUtils: ImageUtils = this.editor.plugins.get( 'ImageUtils' );\n\n\t\treturn imageUtils.isImage( selectedModelElement ) && selectedModelElement.hasAttribute( 'linkHref' );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module link/linkimage\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport LinkImageEditing from './linkimageediting.js';\nimport LinkImageUI from './linkimageui.js';\n\nimport '../theme/linkimage.css';\n\n/**\n * The `LinkImage` plugin.\n *\n * This is a \"glue\" plugin that loads the {@link module:link/linkimageediting~LinkImageEditing link image editing feature}\n * and {@link module:link/linkimageui~LinkImageUI link image UI feature}.\n */\nexport default class LinkImage extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LinkImageEditing, LinkImageUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LinkImage' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { Delete } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { Enter } from '@ckeditor/ckeditor5-enter/dist/index.js';\nimport { toArray, first, uid, CKEditorError, FocusTracker, KeystrokeHandler, global, getCode, parseKeystroke, getLocalizedArrowKeyCodeDirection, createElement, logWarning } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\nimport { ButtonView, MenuBarMenuListItemButtonView, View, ViewCollection, FocusCycler, addKeyboardHandlingForGrid, CollapsibleView, LabeledFieldView, createLabeledInputNumber, SwitchButtonView, createDropdown, SplitButtonView, focusChildOnDropdownOpen, MenuBarMenuView } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { DomEventObserver, Matcher, TreeWalker, getFillerOffset } from '@ckeditor/ckeditor5-engine/dist/index.js';\n\n/**\n * Document list blocks iterator.\n */ class ListWalker {\n    /**\n\t * The start list item block element.\n\t */ _startElement;\n    /**\n\t * The reference indent. Initialized by the indent of the start block.\n\t */ _referenceIndent;\n    /**\n\t * The iterating direction.\n\t */ _isForward;\n    /**\n\t * Whether start block should be included in the result (if it's matching other criteria).\n\t */ _includeSelf;\n    /**\n\t * Additional attributes that must be the same for each block.\n\t */ _sameAttributes;\n    /**\n\t * Whether blocks with the same indent level as the start block should be included in the result.\n\t */ _sameIndent;\n    /**\n\t * Whether blocks with a lower indent level than the start block should be included in the result.\n\t */ _lowerIndent;\n    /**\n\t * Whether blocks with a higher indent level than the start block should be included in the result.\n\t */ _higherIndent;\n    /**\n\t * Creates a document list iterator.\n\t *\n\t * @param startElement The start list item block element.\n\t * @param options.direction The iterating direction.\n\t * @param options.includeSelf Whether start block should be included in the result (if it's matching other criteria).\n\t * @param options.sameAttributes Additional attributes that must be the same for each block.\n\t * @param options.sameIndent Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param options.lowerIndent Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t */ constructor(startElement, options){\n        this._startElement = startElement;\n        this._referenceIndent = startElement.getAttribute('listIndent');\n        this._isForward = options.direction == 'forward';\n        this._includeSelf = !!options.includeSelf;\n        this._sameAttributes = toArray(options.sameAttributes || []);\n        this._sameIndent = !!options.sameIndent;\n        this._lowerIndent = !!options.lowerIndent;\n        this._higherIndent = !!options.higherIndent;\n    }\n    /**\n\t * Performs only first step of iteration and returns the result.\n\t *\n\t * @param startElement The start list item block element.\n\t * @param options.direction The iterating direction.\n\t * @param options.includeSelf Whether start block should be included in the result (if it's matching other criteria).\n\t * @param options.sameAttributes Additional attributes that must be the same for each block.\n\t * @param options.sameIndent Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param options.lowerIndent Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t */ static first(startElement, options) {\n        const walker = new this(startElement, options);\n        const iterator = walker[Symbol.iterator]();\n        return first(iterator);\n    }\n    /**\n\t * Iterable interface.\n\t */ *[Symbol.iterator]() {\n        const nestedItems = [];\n        for (const { node } of iterateSiblingListBlocks(this._getStartNode(), this._isForward ? 'forward' : 'backward')){\n            const indent = node.getAttribute('listIndent');\n            // Leaving a nested list.\n            if (indent < this._referenceIndent) {\n                // Abort searching blocks.\n                if (!this._lowerIndent) {\n                    break;\n                }\n                // While searching for lower indents, update the reference indent to find another parent in the next step.\n                this._referenceIndent = indent;\n            } else if (indent > this._referenceIndent) {\n                // Ignore nested blocks.\n                if (!this._higherIndent) {\n                    continue;\n                }\n                // Collect nested blocks to verify if they are really nested, or it's a different item.\n                if (!this._isForward) {\n                    nestedItems.push(node);\n                    continue;\n                }\n            } else {\n                // Ignore same indent block.\n                if (!this._sameIndent) {\n                    // While looking for nested blocks, stop iterating while encountering first same indent block.\n                    if (this._higherIndent) {\n                        // No more nested blocks so yield nested items.\n                        if (nestedItems.length) {\n                            yield* nestedItems;\n                            nestedItems.length = 0;\n                        }\n                        break;\n                    }\n                    continue;\n                }\n                // Abort if item has any additionally specified attribute different.\n                if (this._sameAttributes.some((attr)=>node.getAttribute(attr) !== this._startElement.getAttribute(attr))) {\n                    break;\n                }\n            }\n            // There is another block for the same list item so the nested items were in the same list item.\n            if (nestedItems.length) {\n                yield* nestedItems;\n                nestedItems.length = 0;\n            }\n            yield node;\n        }\n    }\n    /**\n\t * Returns the model element to start iterating.\n\t */ _getStartNode() {\n        if (this._includeSelf) {\n            return this._startElement;\n        }\n        return this._isForward ? this._startElement.nextSibling : this._startElement.previousSibling;\n    }\n}\n/**\n * Iterates sibling list blocks starting from the given node.\n *\n * @internal\n * @param node The model node.\n * @param direction Iteration direction.\n * @returns The object with `node` and `previous` {@link module:engine/model/element~Element blocks}.\n */ function* iterateSiblingListBlocks(node, direction = 'forward') {\n    const isForward = direction == 'forward';\n    const previousNodesByIndent = []; // Last seen nodes of lower indented lists.\n    let previous = null;\n    while(isListItemBlock(node)){\n        let previousNodeInList = null; // It's like `previous` but has the same indent as current node.\n        if (previous) {\n            const nodeIndent = node.getAttribute('listIndent');\n            const previousNodeIndent = previous.getAttribute('listIndent');\n            // Let's find previous node for the same indent.\n            // We're going to need that when we get back to previous indent.\n            if (nodeIndent > previousNodeIndent) {\n                previousNodesByIndent[previousNodeIndent] = previous;\n            } else if (nodeIndent < previousNodeIndent) {\n                previousNodeInList = previousNodesByIndent[nodeIndent];\n                previousNodesByIndent.length = nodeIndent;\n            } else {\n                previousNodeInList = previous;\n            }\n        }\n        yield {\n            node,\n            previous,\n            previousNodeInList\n        };\n        previous = node;\n        node = isForward ? node.nextSibling : node.previousSibling;\n    }\n}\n/**\n * The iterable protocol over the list elements.\n *\n * @internal\n */ class ListBlocksIterable {\n    _listHead;\n    /**\n\t * @param listHead The head element of a list.\n\t */ constructor(listHead){\n        this._listHead = listHead;\n    }\n    /**\n\t * List blocks iterator.\n\t *\n\t * Iterates over all blocks of a list.\n\t */ [Symbol.iterator]() {\n        return iterateSiblingListBlocks(this._listHead, 'forward');\n    }\n}\n\n/**\n * The list item ID generator.\n *\n * @internal\n */ class ListItemUid {\n    /**\n\t * Returns the next ID.\n\t *\n\t * @internal\n\t */ /* istanbul ignore next: static function definition -- @preserve */ static next() {\n        return uid();\n    }\n}\n/**\n * Returns true if the given model node is a list item block.\n *\n * @internal\n */ function isListItemBlock(node) {\n    return !!node && node.is('element') && node.hasAttribute('listItemId');\n}\n/**\n * Returns an array with all elements that represents the same list item.\n *\n * It means that values for `listIndent`, and `listItemId` for all items are equal.\n *\n * @internal\n * @param listItem Starting list item element.\n * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n * in the result.\n */ function getAllListItemBlocks(listItem, options = {}) {\n    return [\n        ...getListItemBlocks(listItem, {\n            ...options,\n            direction: 'backward'\n        }),\n        ...getListItemBlocks(listItem, {\n            ...options,\n            direction: 'forward'\n        })\n    ];\n}\n/**\n * Returns an array with elements that represents the same list item in the specified direction.\n *\n * It means that values for `listIndent` and `listItemId` for all items are equal.\n *\n * **Note**: For backward search the provided item is not included, but for forward search it is included in the result.\n *\n * @internal\n * @param listItem Starting list item element.\n * @param options.direction Walking direction.\n * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included in the result.\n */ function getListItemBlocks(listItem, options = {}) {\n    const isForward = options.direction == 'forward';\n    const items = Array.from(new ListWalker(listItem, {\n        ...options,\n        includeSelf: isForward,\n        sameIndent: true,\n        sameAttributes: 'listItemId'\n    }));\n    return isForward ? items : items.reverse();\n}\n/**\n * Returns a list items nested inside the given list item.\n *\n * @internal\n */ function getNestedListBlocks(listItem) {\n    return Array.from(new ListWalker(listItem, {\n        direction: 'forward',\n        higherIndent: true\n    }));\n}\n/**\n * Returns array of all blocks/items of the same list as given block (same indent, same type and properties).\n *\n * @internal\n * @param listItem Starting list item element.\n * @param options Additional list walker options to modify the range of returned list items.\n */ function getListItems(listItem, options) {\n    const backwardBlocks = new ListWalker(listItem, {\n        sameIndent: true,\n        sameAttributes: 'listType',\n        ...options\n    });\n    const forwardBlocks = new ListWalker(listItem, {\n        sameIndent: true,\n        sameAttributes: 'listType',\n        includeSelf: true,\n        direction: 'forward',\n        ...options\n    });\n    return [\n        ...Array.from(backwardBlocks).reverse(),\n        ...forwardBlocks\n    ];\n}\n/**\n * Check if the given block is the first in the list item.\n *\n * @internal\n * @param listBlock The list block element.\n */ function isFirstBlockOfListItem(listBlock) {\n    const previousSibling = ListWalker.first(listBlock, {\n        sameIndent: true,\n        sameAttributes: 'listItemId'\n    });\n    if (!previousSibling) {\n        return true;\n    }\n    return false;\n}\n/**\n * Check if the given block is the last in the list item.\n *\n * @internal\n */ function isLastBlockOfListItem(listBlock) {\n    const nextSibling = ListWalker.first(listBlock, {\n        direction: 'forward',\n        sameIndent: true,\n        sameAttributes: 'listItemId'\n    });\n    if (!nextSibling) {\n        return true;\n    }\n    return false;\n}\n/**\n * Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n *\n * @internal\n * @param blocks The list of selected blocks.\n * @param options.withNested Whether should include nested list items.\n */ function expandListBlocksToCompleteItems(blocks, options = {}) {\n    blocks = toArray(blocks);\n    const higherIndent = options.withNested !== false;\n    const allBlocks = new Set();\n    for (const block of blocks){\n        for (const itemBlock of getAllListItemBlocks(block, {\n            higherIndent\n        })){\n            allBlocks.add(itemBlock);\n        }\n    }\n    return sortBlocks(allBlocks);\n}\n/**\n * Expands the given list of selected blocks to include all the items of the lists they're in.\n *\n * @internal\n * @param blocks The list of selected blocks.\n */ function expandListBlocksToCompleteList(blocks) {\n    blocks = toArray(blocks);\n    const allBlocks = new Set();\n    for (const block of blocks){\n        for (const itemBlock of getListItems(block)){\n            allBlocks.add(itemBlock);\n        }\n    }\n    return sortBlocks(allBlocks);\n}\n/**\n * Splits the list item just before the provided list block.\n *\n * @internal\n * @param listBlock The list block element.\n * @param writer The model writer.\n * @returns The array of updated blocks.\n */ function splitListItemBefore(listBlock, writer) {\n    const blocks = getListItemBlocks(listBlock, {\n        direction: 'forward'\n    });\n    const id = ListItemUid.next();\n    for (const block of blocks){\n        writer.setAttribute('listItemId', id, block);\n    }\n    return blocks;\n}\n/**\n * Merges the list item with the parent list item.\n *\n * @internal\n * @param listBlock The list block element.\n * @param parentBlock The list block element to merge with.\n * @param writer The model writer.\n * @returns The array of updated blocks.\n */ function mergeListItemBefore(listBlock, parentBlock, writer) {\n    const attributes = {};\n    for (const [key, value] of parentBlock.getAttributes()){\n        if (key.startsWith('list')) {\n            attributes[key] = value;\n        }\n    }\n    const blocks = getListItemBlocks(listBlock, {\n        direction: 'forward'\n    });\n    for (const block of blocks){\n        writer.setAttributes(attributes, block);\n    }\n    return blocks;\n}\n/**\n * Increases indentation of given list blocks.\n *\n * @internal\n * @param blocks The block or iterable of blocks.\n * @param writer The model writer.\n * @param options.expand Whether should expand the list of blocks to include complete list items.\n * @param options.indentBy The number of levels the indentation should change (could be negative).\n */ function indentBlocks(blocks, writer, { expand, indentBy = 1 } = {}) {\n    blocks = toArray(blocks);\n    // Expand the selected blocks to contain the whole list items.\n    const allBlocks = expand ? expandListBlocksToCompleteItems(blocks) : blocks;\n    for (const block of allBlocks){\n        const blockIndent = block.getAttribute('listIndent') + indentBy;\n        if (blockIndent < 0) {\n            removeListAttributes(block, writer);\n        } else {\n            writer.setAttribute('listIndent', blockIndent, block);\n        }\n    }\n    return allBlocks;\n}\n/**\n * Decreases indentation of given list of blocks. If the indentation of some blocks matches the indentation\n * of surrounding blocks, they get merged together.\n *\n * @internal\n * @param blocks The block or iterable of blocks.\n * @param writer The model writer.\n */ function outdentBlocksWithMerge(blocks, writer) {\n    blocks = toArray(blocks);\n    // Expand the selected blocks to contain the whole list items.\n    const allBlocks = expandListBlocksToCompleteItems(blocks);\n    const visited = new Set();\n    const referenceIndent = Math.min(...allBlocks.map((block)=>block.getAttribute('listIndent')));\n    const parentBlocks = new Map();\n    // Collect parent blocks before the list structure gets altered.\n    for (const block of allBlocks){\n        parentBlocks.set(block, ListWalker.first(block, {\n            lowerIndent: true\n        }));\n    }\n    for (const block of allBlocks){\n        if (visited.has(block)) {\n            continue;\n        }\n        visited.add(block);\n        const blockIndent = block.getAttribute('listIndent') - 1;\n        if (blockIndent < 0) {\n            removeListAttributes(block, writer);\n            continue;\n        }\n        // Merge with parent list item while outdenting and indent matches reference indent.\n        if (block.getAttribute('listIndent') == referenceIndent) {\n            const mergedBlocks = mergeListItemIfNotLast(block, parentBlocks.get(block), writer);\n            // All list item blocks are updated while merging so add those to visited set.\n            for (const mergedBlock of mergedBlocks){\n                visited.add(mergedBlock);\n            }\n            // The indent level was updated while merging so continue to next block.\n            if (mergedBlocks.length) {\n                continue;\n            }\n        }\n        writer.setAttribute('listIndent', blockIndent, block);\n    }\n    return sortBlocks(visited);\n}\n/**\n * Removes all list attributes from the given blocks.\n *\n * @internal\n * @param blocks The block or iterable of blocks.\n * @param writer The model writer.\n * @returns Array of altered blocks.\n */ function removeListAttributes(blocks, writer) {\n    blocks = toArray(blocks);\n    // Convert simple list items to plain paragraphs.\n    for (const block of blocks){\n        if (block.is('element', 'listItem')) {\n            writer.rename(block, 'paragraph');\n        }\n    }\n    // Remove list attributes.\n    for (const block of blocks){\n        for (const attributeKey of block.getAttributeKeys()){\n            if (attributeKey.startsWith('list')) {\n                writer.removeAttribute(attributeKey, block);\n            }\n        }\n    }\n    return blocks;\n}\n/**\n * Checks whether the given blocks are related to a single list item.\n *\n * @internal\n * @param blocks The list block elements.\n */ function isSingleListItem(blocks) {\n    if (!blocks.length) {\n        return false;\n    }\n    const firstItemId = blocks[0].getAttribute('listItemId');\n    if (!firstItemId) {\n        return false;\n    }\n    return !blocks.some((item)=>item.getAttribute('listItemId') != firstItemId);\n}\n/**\n * Modifies the indents of list blocks following the given list block so the indentation is valid after\n * the given block is no longer a list item.\n *\n * @internal\n * @param lastBlock The last list block that has become a non-list element.\n * @param writer The model writer.\n * @returns Array of altered blocks.\n */ function outdentFollowingItems(lastBlock, writer) {\n    const changedBlocks = [];\n    // Start from the model item that is just after the last turned-off item.\n    let currentIndent = Number.POSITIVE_INFINITY;\n    // Correct indent of all items after the last turned off item.\n    // Rules that should be followed:\n    // 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n    //    will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n    // 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n    //    should not end up as a child of any of list items that they were not children of before.\n    // 3. All other items should have their indent changed relatively to it's parent.\n    //\n    // For example:\n    // 1  * --------\n    // 2     * --------\n    // 3        * --------\t\t\t<-- this is turned off.\n    // 4           * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n    // 5              * --------\t<-- this should be still be a child of item above, so indent = 1.\n    // 6        * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n    // 7           * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n    // 8     * --------\t\t\t\t<-- this has to become indent = 0.\n    // 9        * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n    // 10          * --------\t\t<-- this should still be a child of item above, so indent = 2.\n    // 11          * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n    // 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n    // 13    * --------\n    // 14       * --------\n    //\n    // After turning off 3 the list becomes:\n    //\n    // 1  * --------\n    // 2     * --------\n    //\n    // 3  --------\n    //\n    // 4  * --------\n    // 5     * --------\n    // 6  * --------\n    // 7     * --------\n    // 8  * --------\n    // 9     * --------\n    // 10       * --------\n    // 11       * --------\n    // 12 * --------\n    // 13    * --------\n    // 14       * --------\n    //\n    // Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n    // those parent-child connection which are possible to maintain are still maintained. It's worth noting\n    // that this is the same effect that we would be get by multiple use of outdent command. However doing\n    // it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n    // less conversion (faster).\n    for (const { node } of iterateSiblingListBlocks(lastBlock.nextSibling, 'forward')){\n        // Check each next list item, as long as its indent is higher than 0.\n        const indent = node.getAttribute('listIndent');\n        // If the indent is 0 we are not going to change anything anyway.\n        if (indent == 0) {\n            break;\n        }\n        // We check if that's item indent is lower than current relative indent.\n        if (indent < currentIndent) {\n            // If it is, current relative indent becomes that indent.\n            currentIndent = indent;\n        }\n        // Fix indent relatively to current relative indent.\n        // Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n        const newIndent = indent - currentIndent;\n        writer.setAttribute('listIndent', newIndent, node);\n        changedBlocks.push(node);\n    }\n    return changedBlocks;\n}\n/**\n * Returns the array of given blocks sorted by model indexes (document order).\n *\n * @internal\n */ function sortBlocks(blocks) {\n    return Array.from(blocks).filter((block)=>block.root.rootName !== '$graveyard').sort((a, b)=>a.index - b.index);\n}\n/**\n * Returns a selected block object. If a selected object is inline or when there is no selected\n * object, `null` is returned.\n *\n * @internal\n * @param model The instance of editor model.\n * @returns Selected block object or `null`.\n */ function getSelectedBlockObject(model) {\n    const selectedElement = model.document.selection.getSelectedElement();\n    if (!selectedElement) {\n        return null;\n    }\n    if (model.schema.isObject(selectedElement) && model.schema.isBlock(selectedElement)) {\n        return selectedElement;\n    }\n    return null;\n}\n/**\n * Checks whether the given block can be replaced by a listItem.\n *\n * Note that this is possible only when multiBlock = false option is set in feature config.\n *\n * @param block A block to be tested.\n * @param schema The schema of the document.\n */ function canBecomeSimpleListItem(block, schema) {\n    return schema.checkChild(block.parent, 'listItem') && schema.checkChild(block, '$text') && !schema.isObject(block);\n}\n/**\n * Returns true if listType is of type `numbered` or `customNumbered`.\n */ function isNumberedListType(listType) {\n    return listType == 'numbered' || listType == 'customNumbered';\n}\n/**\n * Merges a given block to the given parent block if parent is a list item and there is no more blocks in the same item.\n */ function mergeListItemIfNotLast(block, parentBlock, writer) {\n    const parentItemBlocks = getListItemBlocks(parentBlock, {\n        direction: 'forward'\n    });\n    // Merge with parent only if outdented item wasn't the last one in its parent.\n    // Merge:\n    // * a\t\t\t->\t\t* a\n    //   * [b]\t\t->\t\t  b\n    //   c\t\t\t->\t\t  c\n    // Don't merge:\n    // * a\t\t\t->\t\t* a\n    //   * [b]\t\t-> \t\t* b\n    // * c\t\t\t->\t\t* c\n    if (parentItemBlocks.pop().index > block.index) {\n        return mergeListItemBefore(block, parentBlock, writer);\n    }\n    return [];\n}\n\n/**\n * The document list indent command. It is used by the {@link module:list/list~List list feature}.\n */ class ListIndentCommand extends Command {\n    /**\n\t * Determines by how much the command will change the list item's indent attribute.\n\t */ _direction;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */ constructor(editor, indentDirection){\n        super(editor);\n        this._direction = indentDirection;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */ execute() {\n        const model = this.editor.model;\n        const blocks = getSelectedListBlocks(model.document.selection);\n        model.change((writer)=>{\n            const changedBlocks = [];\n            // Handle selection contained in the single list item and starting in the following blocks.\n            if (isSingleListItem(blocks) && !isFirstBlockOfListItem(blocks[0])) {\n                // Allow increasing indent of following list item blocks.\n                if (this._direction == 'forward') {\n                    changedBlocks.push(...indentBlocks(blocks, writer));\n                }\n                // For indent make sure that indented blocks have a new ID.\n                // For outdent just split blocks from the list item (give them a new IDs).\n                changedBlocks.push(...splitListItemBefore(blocks[0], writer));\n            } else {\n                // Now just update the attributes of blocks.\n                if (this._direction == 'forward') {\n                    changedBlocks.push(...indentBlocks(blocks, writer, {\n                        expand: true\n                    }));\n                } else {\n                    changedBlocks.push(...outdentBlocksWithMerge(blocks, writer));\n                }\n            }\n            // Align the list item type to match the previous list item (from the same list).\n            for (const block of changedBlocks){\n                // This block become a plain block (for example a paragraph).\n                if (!block.hasAttribute('listType')) {\n                    continue;\n                }\n                const previousItemBlock = ListWalker.first(block, {\n                    sameIndent: true\n                });\n                if (previousItemBlock) {\n                    writer.setAttribute('listType', previousItemBlock.getAttribute('listType'), block);\n                }\n            }\n            this._fireAfterExecute(changedBlocks);\n        });\n    }\n    /**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */ _fireAfterExecute(changedBlocks) {\n        this.fire('afterExecute', sortBlocks(new Set(changedBlocks)));\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        // Check whether any of position's ancestor is a list item.\n        let blocks = getSelectedListBlocks(this.editor.model.document.selection);\n        let firstBlock = blocks[0];\n        // If selection is not in a list item, the command is disabled.\n        if (!firstBlock) {\n            return false;\n        }\n        // If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n        if (this._direction == 'backward') {\n            return true;\n        }\n        // A single block of a list item is selected, so it could be indented as a sublist.\n        if (isSingleListItem(blocks) && !isFirstBlockOfListItem(blocks[0])) {\n            return true;\n        }\n        blocks = expandListBlocksToCompleteItems(blocks);\n        firstBlock = blocks[0];\n        // Check if there is any list item before selected items that could become a parent of selected items.\n        const siblingItem = ListWalker.first(firstBlock, {\n            sameIndent: true\n        });\n        if (!siblingItem) {\n            return false;\n        }\n        if (siblingItem.getAttribute('listType') == firstBlock.getAttribute('listType')) {\n            return true;\n        }\n        return false;\n    }\n}\n/**\n * Returns an array of selected blocks truncated to the first non list block element.\n */ function getSelectedListBlocks(selection) {\n    const blocks = Array.from(selection.getSelectedBlocks());\n    const firstNonListBlockIndex = blocks.findIndex((block)=>!isListItemBlock(block));\n    if (firstNonListBlockIndex != -1) {\n        blocks.length = firstNonListBlockIndex;\n    }\n    return blocks;\n}\n\n/**\n * The list command. It is used by the {@link module:list/list~List list feature}.\n */ class ListCommand extends Command {\n    /**\n\t * The type of the list created by the command.\n\t */ type;\n    /**\n\t * List Walker options that change the range of the list items to be changed when the selection is collapsed within a list item.\n\t *\n\t * In a multi-level list, when the selection is collapsed within a list item, instead of changing only the list items of the same list\n\t * type and current indent level, the entire list structure is changed (all list items at all indent levels of any list type).\n\t */ _listWalkerOptions;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param type List type that will be handled by this command.\n\t */ constructor(editor, type, options = {}){\n        super(editor);\n        this.type = type;\n        this._listWalkerOptions = options.multiLevel ? {\n            higherIndent: true,\n            lowerIndent: true,\n            sameAttributes: []\n        } : undefined;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.value = this._getValue();\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false` it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t * @param options.additionalAttributes Additional attributes that are set for list items when the command is executed.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const document = model.document;\n        const selectedBlockObject = getSelectedBlockObject(model);\n        const blocks = Array.from(document.selection.getSelectedBlocks()).filter((block)=>model.schema.checkAttribute(block, 'listType') || canBecomeSimpleListItem(block, model.schema));\n        // Whether we are turning off some items.\n        const turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n        model.change((writer)=>{\n            if (turnOff) {\n                const lastBlock = blocks[blocks.length - 1];\n                // Split the first block from the list item.\n                const itemBlocks = getListItemBlocks(lastBlock, {\n                    direction: 'forward'\n                });\n                const changedBlocks = [];\n                if (itemBlocks.length > 1) {\n                    changedBlocks.push(...splitListItemBefore(itemBlocks[1], writer));\n                }\n                // Strip list attributes.\n                changedBlocks.push(...removeListAttributes(blocks, writer));\n                // Outdent items following the selected list item.\n                changedBlocks.push(...outdentFollowingItems(lastBlock, writer));\n                this._fireAfterExecute(changedBlocks);\n            } else if ((selectedBlockObject || document.selection.isCollapsed) && isListItemBlock(blocks[0])) {\n                const changedBlocks = getListItems(selectedBlockObject || blocks[0], this._listWalkerOptions);\n                for (const block of changedBlocks){\n                    writer.setAttributes({\n                        ...options.additionalAttributes,\n                        listType: this.type\n                    }, block);\n                }\n                this._fireAfterExecute(changedBlocks);\n            } else {\n                const changedBlocks = [];\n                for (const block of blocks){\n                    // Promote the given block to the list item.\n                    if (!block.hasAttribute('listType')) {\n                        // Rename block to a simple list item if this option is enabled.\n                        if (!block.is('element', 'listItem') && canBecomeSimpleListItem(block, model.schema)) {\n                            writer.rename(block, 'listItem');\n                        }\n                        writer.setAttributes({\n                            ...options.additionalAttributes,\n                            listIndent: 0,\n                            listItemId: ListItemUid.next(),\n                            listType: this.type\n                        }, block);\n                        changedBlocks.push(block);\n                    } else {\n                        for (const node of expandListBlocksToCompleteItems(block, {\n                            withNested: false\n                        })){\n                            if (node.getAttribute('listType') != this.type) {\n                                writer.setAttributes({\n                                    ...options.additionalAttributes,\n                                    listType: this.type\n                                }, node);\n                                changedBlocks.push(node);\n                            }\n                        }\n                    }\n                }\n                this._fireAfterExecute(changedBlocks);\n            }\n        });\n    }\n    /**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */ _fireAfterExecute(changedBlocks) {\n        this.fire('afterExecute', sortBlocks(new Set(changedBlocks)));\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */ _getValue() {\n        const selection = this.editor.model.document.selection;\n        const blocks = Array.from(selection.getSelectedBlocks());\n        if (!blocks.length) {\n            return false;\n        }\n        for (const block of blocks){\n            if (block.getAttribute('listType') != this.type) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        const model = this.editor.model;\n        const schema = model.schema;\n        const selection = model.document.selection;\n        const blocks = Array.from(selection.getSelectedBlocks());\n        if (!blocks.length) {\n            return false;\n        }\n        // If command value is true it means that we are in list item, so the command should be enabled.\n        if (this.value) {\n            return true;\n        }\n        for (const block of blocks){\n            if (schema.checkAttribute(block, 'listType') || canBecomeSimpleListItem(block, schema)) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n\n/**\n * The document list merge command. It is used by the {@link module:list/list~List list feature}.\n */ class ListMergeCommand extends Command {\n    /**\n\t * Whether list item should be merged before or after the selected block.\n\t */ _direction;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param direction Whether list item should be merged before or after the selected block.\n\t */ constructor(editor, direction){\n        super(editor);\n        this._direction = direction;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Merges list blocks together (depending on the {@link #constructor}'s `direction` parameter).\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param options Command options.\n\t * @param options.shouldMergeOnBlocksContentLevel When set `true`, merging will be performed together\n\t * with {@link module:engine/model/model~Model#deleteContent} to get rid of the inline content in the selection or take advantage\n\t * of the heuristics in `deleteContent()` that helps convert lists into paragraphs in certain cases.\n\t */ execute({ shouldMergeOnBlocksContentLevel = false } = {}) {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const changedBlocks = [];\n        model.change((writer)=>{\n            const { firstElement, lastElement } = this._getMergeSubjectElements(selection, shouldMergeOnBlocksContentLevel);\n            const firstIndent = firstElement.getAttribute('listIndent') || 0;\n            const lastIndent = lastElement.getAttribute('listIndent');\n            const lastElementId = lastElement.getAttribute('listItemId');\n            if (firstIndent != lastIndent) {\n                const nestedLastElementBlocks = getNestedListBlocks(lastElement);\n                changedBlocks.push(...indentBlocks([\n                    lastElement,\n                    ...nestedLastElementBlocks\n                ], writer, {\n                    indentBy: firstIndent - lastIndent,\n                    // If outdenting, the entire sub-tree that follows must be included.\n                    expand: firstIndent < lastIndent\n                }));\n            }\n            if (shouldMergeOnBlocksContentLevel) {\n                let sel = selection;\n                if (selection.isCollapsed) {\n                    sel = writer.createSelection(writer.createRange(writer.createPositionAt(firstElement, 'end'), writer.createPositionAt(lastElement, 0)));\n                }\n                // Delete selected content. Replace entire content only for non-collapsed selection.\n                model.deleteContent(sel, {\n                    doNotResetEntireContent: selection.isCollapsed\n                });\n                // Get the last \"touched\" element after deleteContent call (can't use the lastElement because\n                // it could get merged into the firstElement while deleting content).\n                const lastElementAfterDelete = sel.getLastPosition().parent;\n                // Check if the element after it was in the same list item and adjust it if needed.\n                const nextSibling = lastElementAfterDelete.nextSibling;\n                changedBlocks.push(lastElementAfterDelete);\n                if (nextSibling && nextSibling !== lastElement && nextSibling.getAttribute('listItemId') == lastElementId) {\n                    changedBlocks.push(...mergeListItemBefore(nextSibling, lastElementAfterDelete, writer));\n                }\n            } else {\n                changedBlocks.push(...mergeListItemBefore(lastElement, firstElement, writer));\n            }\n            this._fireAfterExecute(changedBlocks);\n        });\n    }\n    /**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */ _fireAfterExecute(changedBlocks) {\n        this.fire('afterExecute', sortBlocks(new Set(changedBlocks)));\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const selectedBlockObject = getSelectedBlockObject(model);\n        if (selection.isCollapsed || selectedBlockObject) {\n            const positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n            if (!isListItemBlock(positionParent)) {\n                return false;\n            }\n            const siblingNode = this._direction == 'backward' ? positionParent.previousSibling : positionParent.nextSibling;\n            if (!siblingNode) {\n                return false;\n            }\n            if (isSingleListItem([\n                positionParent,\n                siblingNode\n            ])) {\n                return false;\n            }\n        } else {\n            const lastPosition = selection.getLastPosition();\n            const firstPosition = selection.getFirstPosition();\n            // If deleting within a single block of a list item, there's no need to merge anything.\n            // The default delete should be executed instead.\n            if (lastPosition.parent === firstPosition.parent) {\n                return false;\n            }\n            if (!isListItemBlock(lastPosition.parent)) {\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Returns the boundary elements the merge should be executed for. These are not necessarily selection's first\n\t * and last position parents but sometimes sibling or even further blocks depending on the context.\n\t *\n\t * @param selection The selection the merge is executed for.\n\t * @param shouldMergeOnBlocksContentLevel When `true`, merge is performed together with\n\t * {@link module:engine/model/model~Model#deleteContent} to remove the inline content within the selection.\n\t */ _getMergeSubjectElements(selection, shouldMergeOnBlocksContentLevel) {\n        const model = this.editor.model;\n        const selectedBlockObject = getSelectedBlockObject(model);\n        let firstElement, lastElement;\n        if (selection.isCollapsed || selectedBlockObject) {\n            const positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n            const isFirstBlock = isFirstBlockOfListItem(positionParent);\n            if (this._direction == 'backward') {\n                lastElement = positionParent;\n                if (isFirstBlock && !shouldMergeOnBlocksContentLevel) {\n                    // For the \"c\" as an anchorElement:\n                    //  * a\n                    //    * b\n                    //  * [c]  <-- this block should be merged with \"a\"\n                    // It should find \"a\" element to merge with:\n                    //  * a\n                    //    * b\n                    //    c\n                    firstElement = ListWalker.first(positionParent, {\n                        sameIndent: true,\n                        lowerIndent: true\n                    });\n                } else {\n                    firstElement = positionParent.previousSibling;\n                }\n            } else {\n                // In case of the forward merge there is no case as above, just merge with next sibling.\n                firstElement = positionParent;\n                lastElement = positionParent.nextSibling;\n            }\n        } else {\n            firstElement = selection.getFirstPosition().parent;\n            lastElement = selection.getLastPosition().parent;\n        }\n        return {\n            firstElement: firstElement,\n            lastElement: lastElement\n        };\n    }\n}\n\n/**\n * The document list split command that splits the list item at the selection.\n *\n * It is used by the {@link module:list/list~List list feature}.\n */ class ListSplitCommand extends Command {\n    /**\n\t * Whether list item should be split before or after the selected block.\n\t */ _direction;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param direction Whether list item should be split before or after the selected block.\n\t */ constructor(editor, direction){\n        super(editor);\n        this._direction = direction;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Splits the list item at the selection.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */ execute() {\n        const editor = this.editor;\n        editor.model.change((writer)=>{\n            const changedBlocks = splitListItemBefore(this._getStartBlock(), writer);\n            this._fireAfterExecute(changedBlocks);\n        });\n    }\n    /**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */ _fireAfterExecute(changedBlocks) {\n        this.fire('afterExecute', sortBlocks(new Set(changedBlocks)));\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        const selection = this.editor.model.document.selection;\n        const block = this._getStartBlock();\n        return selection.isCollapsed && isListItemBlock(block) && !isFirstBlockOfListItem(block);\n    }\n    /**\n\t * Returns the model element that is the main focus of the command (according to the current selection and command direction).\n\t */ _getStartBlock() {\n        const doc = this.editor.model.document;\n        const positionParent = doc.selection.getFirstPosition().parent;\n        return this._direction == 'before' ? positionParent : positionParent.nextSibling;\n    }\n}\n\n/**\n * A set of helpers related to document lists.\n */ class ListUtils extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ListUtils';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * Expands the given list of selected blocks to include all the items of the lists they're in.\n\t *\n\t * @param blocks The list of selected blocks.\n\t */ expandListBlocksToCompleteList(blocks) {\n        return expandListBlocksToCompleteList(blocks);\n    }\n    /**\n\t * Check if the given block is the first in the list item.\n\t *\n\t * @param listBlock The list block element.\n\t */ isFirstBlockOfListItem(listBlock) {\n        return isFirstBlockOfListItem(listBlock);\n    }\n    /**\n\t * Returns true if the given model node is a list item block.\n\t *\n\t * @param node A model node.\n\t */ isListItemBlock(node) {\n        return isListItemBlock(node);\n    }\n    /**\n\t * Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n\t *\n\t * @param blocks The list of selected blocks.\n\t * @param options.withNested Whether should include nested list items.\n\t */ expandListBlocksToCompleteItems(blocks, options = {}) {\n        return expandListBlocksToCompleteItems(blocks, options);\n    }\n    /**\n\t * Returns true if listType is of type `numbered` or `customNumbered`.\n\t */ isNumberedListType(listType) {\n        return isNumberedListType(listType);\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module list/list/utils/view\n */ /**\n * Checks if view element is a list type (ul or ol).\n *\n * @internal\n */ function isListView(viewElement) {\n    return viewElement.is('element', 'ol') || viewElement.is('element', 'ul');\n}\n/**\n * Checks if view element is a list item (li).\n *\n * @internal\n */ function isListItemView(viewElement) {\n    return viewElement.is('element', 'li');\n}\n/**\n * Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n *\n * Also, fixes non HTML compliant lists indents:\n *\n * ```\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI     (indent: 0)\n *     |-> OL                                  |-> OL\n *         |-> OL                                  |\n *         |   |-> OL                              |\n *         |       |-> OL                          |\n *         |           |-> LI (parent LIs: 1)      |-> LI (indent: 1)\n *         |-> LI (parent LIs: 1)                  |-> LI (indent: 1)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> OL                                      |\n *     |-> OL                                  |\n *          |-> OL                             |\n *              |-> LI (parent LIs: 0)         |-> LI        (indent: 0)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI         (indent: 0)\n * |-> OL                                          |-> OL\n *     |-> LI (parent LIs: 0)                          |-> LI (indent: 1)\n * ```\n *\n * @internal\n */ function getIndent$1(listItem) {\n    let indent = 0;\n    let parent = listItem.parent;\n    while(parent){\n        // Each LI in the tree will result in an increased indent for HTML compliant lists.\n        if (isListItemView(parent)) {\n            indent++;\n        } else {\n            // If however the list is nested in other list we should check previous sibling of any of the list elements...\n            const previousSibling = parent.previousSibling;\n            // ...because the we might need increase its indent:\n            //\t\tbefore:                           fixed list:\n            //\t\tOL                                OL\n            //\t\t|-> LI (parent LIs: 0)            |-> LI         (indent: 0)\n            //\t\t|-> OL                                |-> OL\n            //\t\t    |-> LI (parent LIs: 0)                |-> LI (indent: 1)\n            if (previousSibling && isListItemView(previousSibling)) {\n                indent++;\n            }\n        }\n        parent = parent.parent;\n    }\n    return indent;\n}\n/**\n * Creates a list attribute element (ol or ul).\n *\n * @internal\n */ function createListElement(writer, indent, type, id = getViewElementIdForListType(type, indent)) {\n    // Negative priorities so that restricted editing attribute won't wrap lists.\n    return writer.createAttributeElement(getViewElementNameForListType(type), null, {\n        priority: 2 * indent / 100 - 100,\n        id\n    });\n}\n/**\n * Creates a list item attribute element (li).\n *\n * @internal\n */ function createListItemElement(writer, indent, id) {\n    // Negative priorities so that restricted editing attribute won't wrap list items.\n    return writer.createAttributeElement('li', null, {\n        priority: (2 * indent + 1) / 100 - 100,\n        id\n    });\n}\n/**\n * Returns a view element name for the given list type.\n *\n * @internal\n */ function getViewElementNameForListType(type) {\n    return type == 'numbered' || type == 'customNumbered' ? 'ol' : 'ul';\n}\n/**\n * Returns a view element ID for the given list type and indent.\n *\n * @internal\n */ function getViewElementIdForListType(type, indent) {\n    return `list-${type}-${indent}`;\n}\n\n/**\n * Based on the provided positions looks for the list head and stores it in the provided map.\n *\n * @internal\n * @param position The search starting position.\n * @param itemToListHead The map from list item element to the list head element.\n */ function findAndAddListHeadToMap(position, itemToListHead) {\n    const previousNode = position.nodeBefore;\n    if (!isListItemBlock(previousNode)) {\n        const item = position.nodeAfter;\n        if (isListItemBlock(item)) {\n            itemToListHead.set(item, item);\n        }\n    } else {\n        let listHead = previousNode;\n        // Previously, the loop below was defined like this:\n        //\n        // \t\tfor ( { node: listHead } of iterateSiblingListBlocks( listHead, 'backward' ) )\n        //\n        // Unfortunately, such a destructuring is incorrectly transpiled by Babel and the loop never ends.\n        // See: https://github.com/ckeditor/ckeditor5-react/issues/345.\n        for (const { node } of iterateSiblingListBlocks(listHead, 'backward')){\n            listHead = node;\n            if (itemToListHead.has(listHead)) {\n                return;\n            }\n        }\n        itemToListHead.set(previousNode, listHead);\n    }\n}\n/**\n * Scans the list starting from the given list head element and fixes items' indentation.\n *\n * @internal\n * @param listNodes The iterable of list nodes.\n * @param writer The model writer.\n * @returns Whether the model was modified.\n */ function fixListIndents(listNodes, writer) {\n    let maxIndent = 0; // Guards local sublist max indents that need fixing.\n    let prevIndent = -1; // Previous item indent.\n    let fixBy = null;\n    let applied = false;\n    for (const { node } of listNodes){\n        const itemIndent = node.getAttribute('listIndent');\n        if (itemIndent > maxIndent) {\n            let newIndent;\n            if (fixBy === null) {\n                fixBy = itemIndent - maxIndent;\n                newIndent = maxIndent;\n            } else {\n                if (fixBy > itemIndent) {\n                    fixBy = itemIndent;\n                }\n                newIndent = itemIndent - fixBy;\n            }\n            if (newIndent > prevIndent + 1) {\n                newIndent = prevIndent + 1;\n            }\n            writer.setAttribute('listIndent', newIndent, node);\n            applied = true;\n            prevIndent = newIndent;\n        } else {\n            fixBy = null;\n            maxIndent = itemIndent + 1;\n            prevIndent = itemIndent;\n        }\n    }\n    return applied;\n}\n/**\n * Scans the list starting from the given list head element and fixes items' types.\n *\n * @internal\n * @param listNodes The iterable of list nodes.\n * @param seenIds The set of already known IDs.\n * @param writer The model writer.\n * @returns Whether the model was modified.\n */ function fixListItemIds(listNodes, seenIds, writer) {\n    const visited = new Set();\n    let applied = false;\n    for (const { node } of listNodes){\n        if (visited.has(node)) {\n            continue;\n        }\n        let listType = node.getAttribute('listType');\n        let listItemId = node.getAttribute('listItemId');\n        // Use a new ID if this one was spot earlier (even in other list).\n        if (seenIds.has(listItemId)) {\n            listItemId = ListItemUid.next();\n        }\n        seenIds.add(listItemId);\n        // Make sure that all items in a simple list have unique IDs.\n        if (node.is('element', 'listItem')) {\n            if (node.getAttribute('listItemId') != listItemId) {\n                writer.setAttribute('listItemId', listItemId, node);\n                applied = true;\n            }\n            continue;\n        }\n        for (const block of getListItemBlocks(node, {\n            direction: 'forward'\n        })){\n            visited.add(block);\n            // Use a new ID if a block of a bigger list item has different type.\n            if (block.getAttribute('listType') != listType) {\n                listItemId = ListItemUid.next();\n                listType = block.getAttribute('listType');\n            }\n            if (block.getAttribute('listItemId') != listItemId) {\n                writer.setAttribute('listItemId', listItemId, block);\n                applied = true;\n            }\n        }\n    }\n    return applied;\n}\n\n/**\n * Returns the upcast converter for list items. It's supposed to work after the block converters (content inside list items) are converted.\n *\n * @internal\n */ function listItemUpcastConverter() {\n    return (evt, data, conversionApi)=>{\n        const { writer, schema } = conversionApi;\n        if (!data.modelRange) {\n            return;\n        }\n        const items = Array.from(data.modelRange.getItems({\n            shallow: true\n        })).filter((item)=>schema.checkAttribute(item, 'listItemId'));\n        if (!items.length) {\n            return;\n        }\n        const listItemId = ListItemUid.next();\n        const listIndent = getIndent$1(data.viewItem);\n        let listType = data.viewItem.parent && data.viewItem.parent.is('element', 'ol') ? 'numbered' : 'bulleted';\n        // Preserve list type if was already set (for example by to-do list feature).\n        const firstItemListType = items[0].getAttribute('listType');\n        if (firstItemListType) {\n            listType = firstItemListType;\n        }\n        const attributes = {\n            listItemId,\n            listIndent,\n            listType\n        };\n        for (const item of items){\n            // Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n            if (!item.hasAttribute('listItemId')) {\n                writer.setAttributes(attributes, item);\n            }\n        }\n        if (items.length > 1) {\n            // Make sure that list item that contain only nested list will preserve paragraph for itself:\n            //\t<ul>\n            //\t\t<li>\n            //\t\t\t<p></p>  <-- this one must be kept\n            //\t\t\t<ul>\n            //\t\t\t\t<li></li>\n            //\t\t\t</ul>\n            //\t\t</li>\n            //\t</ul>\n            if (items[1].getAttribute('listItemId') != attributes.listItemId) {\n                conversionApi.keepEmptyElement(items[0]);\n            }\n        }\n    };\n}\n/**\n * Returns a model document change:data event listener that triggers conversion of related items if needed.\n *\n * @internal\n * @param model The editor model.\n * @param editing The editing controller.\n * @param attributeNames The list of all model list attributes (including registered strategies).\n * @param listEditing The document list editing plugin.\n */ function reconvertItemsOnDataChange(model, editing, attributeNames, listEditing) {\n    return ()=>{\n        const changes = model.document.differ.getChanges();\n        const itemsToRefresh = [];\n        const itemToListHead = new Map();\n        const changedItems = new Set();\n        for (const entry of changes){\n            if (entry.type == 'insert' && entry.name != '$text') {\n                findAndAddListHeadToMap(entry.position, itemToListHead);\n                // Insert of a non-list item.\n                if (!entry.attributes.has('listItemId')) {\n                    findAndAddListHeadToMap(entry.position.getShiftedBy(entry.length), itemToListHead);\n                } else {\n                    changedItems.add(entry.position.nodeAfter);\n                }\n            } else if (entry.type == 'remove' && entry.attributes.has('listItemId')) {\n                findAndAddListHeadToMap(entry.position, itemToListHead);\n            } else if (entry.type == 'attribute') {\n                const item = entry.range.start.nodeAfter;\n                if (attributeNames.includes(entry.attributeKey)) {\n                    findAndAddListHeadToMap(entry.range.start, itemToListHead);\n                    if (entry.attributeNewValue === null) {\n                        findAndAddListHeadToMap(entry.range.start.getShiftedBy(1), itemToListHead);\n                        // Check if paragraph should be converted from bogus to plain paragraph.\n                        if (doesItemBlockRequiresRefresh(item)) {\n                            itemsToRefresh.push(item);\n                        }\n                    } else {\n                        changedItems.add(item);\n                    }\n                } else if (isListItemBlock(item)) {\n                    // Some other attribute was changed on the list item,\n                    // check if paragraph does not need to be converted to bogus or back.\n                    if (doesItemBlockRequiresRefresh(item)) {\n                        itemsToRefresh.push(item);\n                    }\n                }\n            }\n        }\n        for (const listHead of itemToListHead.values()){\n            itemsToRefresh.push(...collectListItemsToRefresh(listHead, changedItems));\n        }\n        for (const item of new Set(itemsToRefresh)){\n            editing.reconvertItem(item);\n        }\n    };\n    function collectListItemsToRefresh(listHead, changedItems) {\n        const itemsToRefresh = [];\n        const visited = new Set();\n        const stack = [];\n        for (const { node, previous } of iterateSiblingListBlocks(listHead, 'forward')){\n            if (visited.has(node)) {\n                continue;\n            }\n            const itemIndent = node.getAttribute('listIndent');\n            // Current node is at the lower indent so trim the stack.\n            if (previous && itemIndent < previous.getAttribute('listIndent')) {\n                stack.length = itemIndent + 1;\n            }\n            // Update the stack for the current indent level.\n            stack[itemIndent] = Object.fromEntries(Array.from(node.getAttributes()).filter(([key])=>attributeNames.includes(key)));\n            // Find all blocks of the current node.\n            const blocks = getListItemBlocks(node, {\n                direction: 'forward'\n            });\n            for (const block of blocks){\n                visited.add(block);\n                // Check if bogus vs plain paragraph needs refresh.\n                if (doesItemBlockRequiresRefresh(block, blocks)) {\n                    itemsToRefresh.push(block);\n                } else if (doesItemWrappingRequiresRefresh(block, stack, changedItems)) {\n                    itemsToRefresh.push(block);\n                }\n            }\n        }\n        return itemsToRefresh;\n    }\n    function doesItemBlockRequiresRefresh(item, blocks) {\n        const viewElement = editing.mapper.toViewElement(item);\n        if (!viewElement) {\n            return false;\n        }\n        const needsRefresh = listEditing.fire('checkElement', {\n            modelElement: item,\n            viewElement\n        });\n        if (needsRefresh) {\n            return true;\n        }\n        if (!item.is('element', 'paragraph') && !item.is('element', 'listItem')) {\n            return false;\n        }\n        const useBogus = shouldUseBogusParagraph(item, attributeNames, blocks);\n        if (useBogus && viewElement.is('element', 'p')) {\n            return true;\n        } else if (!useBogus && viewElement.is('element', 'span')) {\n            return true;\n        }\n        return false;\n    }\n    function doesItemWrappingRequiresRefresh(item, stack, changedItems) {\n        // Items directly affected by some \"change\" don't need a refresh, they will be converted by their own changes.\n        if (changedItems.has(item)) {\n            return false;\n        }\n        const viewElement = editing.mapper.toViewElement(item);\n        let indent = stack.length - 1;\n        // Traverse down the stack to the root to verify if all ULs, OLs, and LIs are as expected.\n        for(let element = viewElement.parent; !element.is('editableElement'); element = element.parent){\n            const isListItemElement = isListItemView(element);\n            const isListElement = isListView(element);\n            if (!isListElement && !isListItemElement) {\n                continue;\n            }\n            const eventName = `checkAttributes:${isListItemElement ? 'item' : 'list'}`;\n            const needsRefresh = listEditing.fire(eventName, {\n                viewElement: element,\n                modelAttributes: stack[indent]\n            });\n            if (needsRefresh) {\n                break;\n            }\n            if (isListElement) {\n                indent--;\n                // Don't need to iterate further if we already know that the item is wrapped appropriately.\n                if (indent < 0) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n}\n/**\n * Returns the list item downcast converter.\n *\n * @internal\n * @param attributeNames A list of attribute names that should be converted if they are set.\n * @param strategies The strategies.\n * @param model The model.\n */ function listItemDowncastConverter(attributeNames, strategies, model, { dataPipeline } = {}) {\n    const consumer = createAttributesConsumer(attributeNames);\n    return (evt, data, conversionApi)=>{\n        const { writer, mapper, consumable } = conversionApi;\n        const listItem = data.item;\n        if (!attributeNames.includes(data.attributeKey)) {\n            return;\n        }\n        // Test if attributes on the converted items are not consumed.\n        if (!consumer(listItem, consumable)) {\n            return;\n        }\n        // Use positions mapping instead of mapper.toViewElement( listItem ) to find outermost view element.\n        // This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n        const viewElement = findMappedViewElement(listItem, mapper, model);\n        // Remove custom item marker.\n        removeCustomMarkerElements(viewElement, writer, mapper);\n        // Unwrap element from current list wrappers.\n        unwrapListItemBlock(viewElement, writer);\n        // Insert custom item marker.\n        const viewRange = insertCustomMarkerElements(listItem, viewElement, strategies, writer, {\n            dataPipeline\n        });\n        // Then wrap them with the new list wrappers (UL, OL, LI).\n        wrapListItemBlock(listItem, viewRange, strategies, writer);\n    };\n}\n/**\n * The 'remove' downcast converter for custom markers.\n */ function listItemDowncastRemoveConverter(schema) {\n    return (evt, data, conversionApi)=>{\n        const { writer, mapper } = conversionApi;\n        const elementName = evt.name.split(':')[1];\n        // Do not remove marker if the deleted element is some inline object inside paragraph.\n        // See https://github.com/cksource/ckeditor5-internal/issues/3680.\n        if (!schema.checkAttribute(elementName, 'listItemId')) {\n            return;\n        }\n        // Find the view range start position by mapping the model position at which the remove happened.\n        const viewStart = mapper.toViewPosition(data.position);\n        const modelEnd = data.position.getShiftedBy(data.length);\n        const viewEnd = mapper.toViewPosition(modelEnd, {\n            isPhantom: true\n        });\n        // Trim the range to remove in case some UI elements are on the view range boundaries.\n        const viewRange = writer.createRange(viewStart, viewEnd).getTrimmed();\n        // Use positions mapping instead of mapper.toViewElement( listItem ) to find outermost view element.\n        // This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n        const viewElement = viewRange.end.nodeBefore;\n        /* istanbul ignore next -- @preserve */ if (!viewElement) {\n            return;\n        }\n        // Remove custom item marker.\n        removeCustomMarkerElements(viewElement, writer, mapper);\n    };\n}\n/**\n * Returns the bogus paragraph view element creator. A bogus paragraph is used if a list item contains only a single block or nested list.\n *\n * @internal\n * @param attributeNames The list of all model list attributes (including registered strategies).\n */ function bogusParagraphCreator(attributeNames, { dataPipeline } = {}) {\n    return (modelElement, { writer })=>{\n        // Convert only if a bogus paragraph should be used.\n        if (!shouldUseBogusParagraph(modelElement, attributeNames)) {\n            return null;\n        }\n        if (!dataPipeline) {\n            return writer.createContainerElement('span', {\n                class: 'ck-list-bogus-paragraph'\n            });\n        }\n        // Using `<p>` in case there are some markers on it and transparentRendering will render it anyway.\n        const viewElement = writer.createContainerElement('p');\n        writer.setCustomProperty('dataPipeline:transparentRendering', true, viewElement);\n        return viewElement;\n    };\n}\n/**\n * Helper for mapping mode to view elements. It's using positions mapping instead of mapper.toViewElement( element )\n * to find outermost view element. This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n *\n * @internal\n * @param element The model element.\n * @param mapper The mapper instance.\n * @param model The model.\n */ function findMappedViewElement(element, mapper, model) {\n    const modelRange = model.createRangeOn(element);\n    const viewRange = mapper.toViewRange(modelRange).getTrimmed();\n    return viewRange.end.nodeBefore;\n}\n/**\n * The model to view custom position mapping for cases when marker is injected at the beginning of a block.\n */ function createModelToViewPositionMapper(strategies, view) {\n    return (evt, data)=>{\n        if (data.modelPosition.offset > 0) {\n            return;\n        }\n        const positionParent = data.modelPosition.parent;\n        if (!isListItemBlock(positionParent)) {\n            return;\n        }\n        if (!strategies.some((strategy)=>strategy.scope == 'itemMarker' && strategy.canInjectMarkerIntoElement && strategy.canInjectMarkerIntoElement(positionParent))) {\n            return;\n        }\n        const viewElement = data.mapper.toViewElement(positionParent);\n        const viewRange = view.createRangeIn(viewElement);\n        const viewWalker = viewRange.getWalker();\n        let positionAfterLastMarker = viewRange.start;\n        for (const { item } of viewWalker){\n            // Walk only over the non-mapped elements (UIElements, AttributeElements, $text, or any other element without mapping).\n            if (item.is('element') && data.mapper.toModelElement(item) || item.is('$textProxy')) {\n                break;\n            }\n            if (item.is('element') && item.getCustomProperty('listItemMarker')) {\n                positionAfterLastMarker = view.createPositionAfter(item);\n                // Jump over the content of the marker (this is not needed for UIElement but required for other element types).\n                viewWalker.skip(({ previousPosition })=>!previousPosition.isEqual(positionAfterLastMarker));\n            }\n        }\n        data.viewPosition = positionAfterLastMarker;\n    };\n}\n/**\n * Removes a custom marker elements and item wrappers related to that marker.\n */ function removeCustomMarkerElements(viewElement, viewWriter, mapper) {\n    // Remove item wrapper.\n    while(viewElement.parent.is('attributeElement') && viewElement.parent.getCustomProperty('listItemWrapper')){\n        viewWriter.unwrap(viewWriter.createRangeOn(viewElement), viewElement.parent);\n    }\n    // Remove custom item markers.\n    const markersToRemove = [];\n    // Markers before a block.\n    collectMarkersToRemove(viewWriter.createPositionBefore(viewElement).getWalker({\n        direction: 'backward'\n    }));\n    // Markers inside a block.\n    collectMarkersToRemove(viewWriter.createRangeIn(viewElement).getWalker());\n    for (const marker of markersToRemove){\n        viewWriter.remove(marker);\n    }\n    function collectMarkersToRemove(viewWalker) {\n        for (const { item } of viewWalker){\n            // Walk only over the non-mapped elements (UIElements, AttributeElements, $text, or any other element without mapping).\n            if (item.is('element') && mapper.toModelElement(item)) {\n                break;\n            }\n            if (item.is('element') && item.getCustomProperty('listItemMarker')) {\n                markersToRemove.push(item);\n            }\n        }\n    }\n}\n/**\n * Inserts a custom marker elements and wraps first block of a list item if marker requires it.\n */ function insertCustomMarkerElements(listItem, viewElement, strategies, writer, { dataPipeline }) {\n    let viewRange = writer.createRangeOn(viewElement);\n    // Marker can be inserted only before the first block of a list item.\n    if (!isFirstBlockOfListItem(listItem)) {\n        return viewRange;\n    }\n    for (const strategy of strategies){\n        if (strategy.scope != 'itemMarker') {\n            continue;\n        }\n        // Create the custom marker element and inject it before the first block of the list item.\n        const markerElement = strategy.createElement(writer, listItem, {\n            dataPipeline\n        });\n        if (!markerElement) {\n            continue;\n        }\n        writer.setCustomProperty('listItemMarker', true, markerElement);\n        if (strategy.canInjectMarkerIntoElement && strategy.canInjectMarkerIntoElement(listItem)) {\n            writer.insert(writer.createPositionAt(viewElement, 0), markerElement);\n        } else {\n            writer.insert(viewRange.start, markerElement);\n            viewRange = writer.createRange(writer.createPositionBefore(markerElement), writer.createPositionAfter(viewElement));\n        }\n        // Wrap the marker and optionally the first block with an attribute element (label for to-do lists).\n        if (!strategy.createWrapperElement || !strategy.canWrapElement) {\n            continue;\n        }\n        const wrapper = strategy.createWrapperElement(writer, listItem, {\n            dataPipeline\n        });\n        writer.setCustomProperty('listItemWrapper', true, wrapper);\n        // The whole block can be wrapped...\n        if (strategy.canWrapElement(listItem)) {\n            viewRange = writer.wrap(viewRange, wrapper);\n        } else {\n            // ... or only the marker element (if the block is downcasted to heading or block widget).\n            viewRange = writer.wrap(writer.createRangeOn(markerElement), wrapper);\n            viewRange = writer.createRange(viewRange.start, writer.createPositionAfter(viewElement));\n        }\n    }\n    return viewRange;\n}\n/**\n * Unwraps all ol, ul, and li attribute elements that are wrapping the provided view element.\n */ function unwrapListItemBlock(viewElement, viewWriter) {\n    let attributeElement = viewElement.parent;\n    while(attributeElement.is('attributeElement') && [\n        'ul',\n        'ol',\n        'li'\n    ].includes(attributeElement.name)){\n        const parentElement = attributeElement.parent;\n        viewWriter.unwrap(viewWriter.createRangeOn(viewElement), attributeElement);\n        attributeElement = parentElement;\n    }\n}\n/**\n * Wraps the given list item with appropriate attribute elements for ul, ol, and li.\n */ function wrapListItemBlock(listItem, viewRange, strategies, writer) {\n    if (!listItem.hasAttribute('listIndent')) {\n        return;\n    }\n    const listItemIndent = listItem.getAttribute('listIndent');\n    let currentListItem = listItem;\n    for(let indent = listItemIndent; indent >= 0; indent--){\n        const listItemViewElement = createListItemElement(writer, indent, currentListItem.getAttribute('listItemId'));\n        const listViewElement = createListElement(writer, indent, currentListItem.getAttribute('listType'));\n        for (const strategy of strategies){\n            if ((strategy.scope == 'list' || strategy.scope == 'item') && currentListItem.hasAttribute(strategy.attributeName)) {\n                strategy.setAttributeOnDowncast(writer, currentListItem.getAttribute(strategy.attributeName), strategy.scope == 'list' ? listViewElement : listItemViewElement);\n            }\n        }\n        viewRange = writer.wrap(viewRange, listItemViewElement);\n        viewRange = writer.wrap(viewRange, listViewElement);\n        if (indent == 0) {\n            break;\n        }\n        currentListItem = ListWalker.first(currentListItem, {\n            lowerIndent: true\n        });\n        // There is no list item with lower indent, this means this is a document fragment containing\n        // only a part of nested list (like copy to clipboard) so we don't need to try to wrap it further.\n        if (!currentListItem) {\n            break;\n        }\n    }\n}\n// Returns the function that is responsible for consuming attributes that are set on the model node.\nfunction createAttributesConsumer(attributeNames) {\n    return (node, consumable)=>{\n        const events = [];\n        // Collect all set attributes that are triggering conversion.\n        for (const attributeName of attributeNames){\n            if (node.hasAttribute(attributeName)) {\n                events.push(`attribute:${attributeName}`);\n            }\n        }\n        if (!events.every((event)=>consumable.test(node, event) !== false)) {\n            return false;\n        }\n        events.forEach((event)=>consumable.consume(node, event));\n        return true;\n    };\n}\n// Whether the given item should be rendered as a bogus paragraph.\nfunction shouldUseBogusParagraph(item, attributeNames, blocks = getAllListItemBlocks(item)) {\n    if (!isListItemBlock(item)) {\n        return false;\n    }\n    for (const attributeKey of item.getAttributeKeys()){\n        // Ignore selection attributes stored on block elements.\n        if (attributeKey.startsWith('selection:')) {\n            continue;\n        }\n        // Don't use bogus paragraph if there are attributes from other features.\n        if (!attributeNames.includes(attributeKey)) {\n            return false;\n        }\n    }\n    return blocks.length < 2;\n}\n\n/**\n * A list of base list model attributes.\n */ const LIST_BASE_ATTRIBUTES = [\n    'listType',\n    'listIndent',\n    'listItemId'\n];\n/**\n * The editing part of the document-list feature. It handles creating, editing and removing lists and list items.\n */ class ListEditing extends Plugin {\n    /**\n\t * The list of registered downcast strategies.\n\t */ _downcastStrategies = [];\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ListEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Enter,\n            Delete,\n            ListUtils,\n            ClipboardPipeline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('list.multiBlock', true);\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const multiBlock = editor.config.get('list.multiBlock');\n        if (editor.plugins.has('LegacyListEditing')) {\n            /**\n\t\t\t * The `List` feature can not be loaded together with the `LegacyList` plugin.\n\t\t\t *\n\t\t\t * @error list-feature-conflict\n\t\t\t * @param conflictPlugin Name of the plugin.\n\t\t\t */ throw new CKEditorError('list-feature-conflict', this, {\n                conflictPlugin: 'LegacyListEditing'\n            });\n        }\n        model.schema.register('$listItem', {\n            allowAttributes: LIST_BASE_ATTRIBUTES\n        });\n        if (multiBlock) {\n            model.schema.extend('$container', {\n                allowAttributesOf: '$listItem'\n            });\n            model.schema.extend('$block', {\n                allowAttributesOf: '$listItem'\n            });\n            model.schema.extend('$blockObject', {\n                allowAttributesOf: '$listItem'\n            });\n        } else {\n            model.schema.register('listItem', {\n                inheritAllFrom: '$block',\n                allowAttributesOf: '$listItem'\n            });\n        }\n        for (const attribute of LIST_BASE_ATTRIBUTES){\n            model.schema.setAttributeProperties(attribute, {\n                copyOnReplace: true\n            });\n        }\n        // Register commands.\n        editor.commands.add('numberedList', new ListCommand(editor, 'numbered'));\n        editor.commands.add('bulletedList', new ListCommand(editor, 'bulleted'));\n        editor.commands.add('customNumberedList', new ListCommand(editor, 'customNumbered', {\n            multiLevel: true\n        }));\n        editor.commands.add('customBulletedList', new ListCommand(editor, 'customBulleted', {\n            multiLevel: true\n        }));\n        editor.commands.add('indentList', new ListIndentCommand(editor, 'forward'));\n        editor.commands.add('outdentList', new ListIndentCommand(editor, 'backward'));\n        editor.commands.add('splitListItemBefore', new ListSplitCommand(editor, 'before'));\n        editor.commands.add('splitListItemAfter', new ListSplitCommand(editor, 'after'));\n        if (multiBlock) {\n            editor.commands.add('mergeListItemBackward', new ListMergeCommand(editor, 'backward'));\n            editor.commands.add('mergeListItemForward', new ListMergeCommand(editor, 'forward'));\n        }\n        this._setupDeleteIntegration();\n        this._setupEnterIntegration();\n        this._setupTabIntegration();\n        this._setupClipboardIntegration();\n        this._setupAccessibilityIntegration();\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        const commands = editor.commands;\n        const indent = commands.get('indent');\n        const outdent = commands.get('outdent');\n        if (indent) {\n            // Priority is high due to integration with `IndentBlock` plugin. We want to indent list first and if it's not possible\n            // user can indent content with `IndentBlock` plugin.\n            indent.registerChildCommand(commands.get('indentList'), {\n                priority: 'high'\n            });\n        }\n        if (outdent) {\n            // Priority is lowest due to integration with `IndentBlock` and `IndentCode` plugins.\n            // First we want to allow user to outdent all indendations from other features then he can oudent list item.\n            outdent.registerChildCommand(commands.get('outdentList'), {\n                priority: 'lowest'\n            });\n        }\n        // Register conversion and model post-fixer after other plugins had a chance to register their attribute strategies.\n        this._setupModelPostFixing();\n        this._setupConversion();\n    }\n    /**\n\t * Registers a downcast strategy.\n\t *\n\t * **Note**: Strategies must be registered in the `Plugin#init()` phase so that it can be applied\n\t * in the `ListEditing#afterInit()`.\n\t *\n\t * @param strategy The downcast strategy to register.\n\t */ registerDowncastStrategy(strategy) {\n        this._downcastStrategies.push(strategy);\n    }\n    /**\n\t * Returns list of model attribute names that should affect downcast conversion.\n\t */ getListAttributeNames() {\n        return [\n            ...LIST_BASE_ATTRIBUTES,\n            ...this._downcastStrategies.map((strategy)=>strategy.attributeName)\n        ];\n    }\n    /**\n\t * Attaches the listener to the {@link module:engine/view/document~Document#event:delete} event and handles backspace/delete\n\t * keys in and around document lists.\n\t */ _setupDeleteIntegration() {\n        const editor = this.editor;\n        const mergeBackwardCommand = editor.commands.get('mergeListItemBackward');\n        const mergeForwardCommand = editor.commands.get('mergeListItemForward');\n        this.listenTo(editor.editing.view.document, 'delete', (evt, data)=>{\n            const selection = editor.model.document.selection;\n            // Let the Widget plugin take care of block widgets while deleting (https://github.com/ckeditor/ckeditor5/issues/11346).\n            if (getSelectedBlockObject(editor.model)) {\n                return;\n            }\n            editor.model.change(()=>{\n                const firstPosition = selection.getFirstPosition();\n                if (selection.isCollapsed && data.direction == 'backward') {\n                    if (!firstPosition.isAtStart) {\n                        return;\n                    }\n                    const positionParent = firstPosition.parent;\n                    if (!isListItemBlock(positionParent)) {\n                        return;\n                    }\n                    const previousBlock = ListWalker.first(positionParent, {\n                        sameAttributes: 'listType',\n                        sameIndent: true\n                    });\n                    // Outdent the first block of a first list item.\n                    if (!previousBlock && positionParent.getAttribute('listIndent') === 0) {\n                        if (!isLastBlockOfListItem(positionParent)) {\n                            editor.execute('splitListItemAfter');\n                        }\n                        editor.execute('outdentList');\n                    } else {\n                        if (!mergeBackwardCommand || !mergeBackwardCommand.isEnabled) {\n                            return;\n                        }\n                        mergeBackwardCommand.execute({\n                            shouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel(editor.model, 'backward')\n                        });\n                    }\n                    data.preventDefault();\n                    evt.stop();\n                } else {\n                    // Collapsed selection should trigger forward merging only if at the end of a block.\n                    if (selection.isCollapsed && !selection.getLastPosition().isAtEnd) {\n                        return;\n                    }\n                    if (!mergeForwardCommand || !mergeForwardCommand.isEnabled) {\n                        return;\n                    }\n                    mergeForwardCommand.execute({\n                        shouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel(editor.model, 'forward')\n                    });\n                    data.preventDefault();\n                    evt.stop();\n                }\n            });\n        }, {\n            context: 'li'\n        });\n    }\n    /**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:enter} event and handles enter key press\n\t * in document lists.\n\t */ _setupEnterIntegration() {\n        const editor = this.editor;\n        const model = editor.model;\n        const commands = editor.commands;\n        const enterCommand = commands.get('enter');\n        // Overwrite the default Enter key behavior: outdent or split the list in certain cases.\n        this.listenTo(editor.editing.view.document, 'enter', (evt, data)=>{\n            const doc = model.document;\n            const positionParent = doc.selection.getFirstPosition().parent;\n            if (doc.selection.isCollapsed && isListItemBlock(positionParent) && positionParent.isEmpty && !data.isSoft) {\n                const isFirstBlock = isFirstBlockOfListItem(positionParent);\n                const isLastBlock = isLastBlockOfListItem(positionParent);\n                // * a      →      * a\n                // * []     →      []\n                if (isFirstBlock && isLastBlock) {\n                    editor.execute('outdentList');\n                    data.preventDefault();\n                    evt.stop();\n                } else if (isFirstBlock && !isLastBlock) {\n                    editor.execute('splitListItemAfter');\n                    data.preventDefault();\n                    evt.stop();\n                } else if (isLastBlock) {\n                    editor.execute('splitListItemBefore');\n                    data.preventDefault();\n                    evt.stop();\n                }\n            }\n        }, {\n            context: 'li'\n        });\n        // In some cases, after the default block splitting, we want to modify the new block to become a new list item\n        // instead of an additional block in the same list item.\n        this.listenTo(enterCommand, 'afterExecute', ()=>{\n            const splitCommand = commands.get('splitListItemBefore');\n            // The command has not refreshed because the change block related to EnterCommand#execute() is not over yet.\n            // Let's keep it up to date and take advantage of ListSplitCommand#isEnabled.\n            splitCommand.refresh();\n            if (!splitCommand.isEnabled) {\n                return;\n            }\n            const doc = editor.model.document;\n            const positionParent = doc.selection.getLastPosition().parent;\n            const listItemBlocks = getAllListItemBlocks(positionParent);\n            // Keep in mind this split happens after the default enter handler was executed. For instance:\n            //\n            // │       Initial state       │    After default enter    │   Here in #afterExecute   │\n            // ├───────────────────────────┼───────────────────────────┼───────────────────────────┤\n            // │          * a[]            │           * a             │           * a             │\n            // │                           │             []            │           * []            │\n            if (listItemBlocks.length === 2) {\n                splitCommand.execute();\n            }\n        });\n    }\n    /**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:tab} event and handles tab key and tab+shift keys\n\t * presses in document lists.\n\t */ _setupTabIntegration() {\n        const editor = this.editor;\n        this.listenTo(editor.editing.view.document, 'tab', (evt, data)=>{\n            const commandName = data.shiftKey ? 'outdentList' : 'indentList';\n            const command = this.editor.commands.get(commandName);\n            if (command.isEnabled) {\n                editor.execute(commandName);\n                data.stopPropagation();\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: 'li'\n        });\n    }\n    /**\n\t * Registers the conversion helpers for the document-list feature.\n\t */ _setupConversion() {\n        const editor = this.editor;\n        const model = editor.model;\n        const attributeNames = this.getListAttributeNames();\n        const multiBlock = editor.config.get('list.multiBlock');\n        const elementName = multiBlock ? 'paragraph' : 'listItem';\n        editor.conversion.for('upcast')// Convert <li> to a generic paragraph (or listItem element) so the content of <li> is always inside a block.\n        // Setting the listType attribute to let other features (to-do list) know that this is part of a list item.\n        // This is also important to properly handle simple lists so that paragraphs inside a list item won't break the list item.\n        // <li>  <-- converted to listItem\n        //   <p></p> <-- should be also converted to listItem, so it won't split and replace the listItem generated from the above li.\n        .elementToElement({\n            view: 'li',\n            model: (viewElement, { writer })=>writer.createElement(elementName, {\n                    listType: ''\n                })\n        })// Convert paragraph to the list block (without list type defined yet).\n        // This is important to properly handle bogus paragraph and to-do lists.\n        // Most of the time the bogus paragraph should not appear in the data of to-do list,\n        // but if there is any marker or an attribute on the paragraph then the bogus paragraph\n        // is preserved in the data, and we need to be able to detect this case.\n        .elementToElement({\n            view: 'p',\n            model: (viewElement, { writer })=>{\n                if (viewElement.parent && viewElement.parent.is('element', 'li')) {\n                    return writer.createElement(elementName, {\n                        listType: ''\n                    });\n                }\n                return null;\n            },\n            converterPriority: 'high'\n        }).add((dispatcher)=>{\n            dispatcher.on('element:li', listItemUpcastConverter());\n        });\n        if (!multiBlock) {\n            editor.conversion.for('downcast').elementToElement({\n                model: 'listItem',\n                view: 'p'\n            });\n        }\n        editor.conversion.for('editingDowncast').elementToElement({\n            model: elementName,\n            view: bogusParagraphCreator(attributeNames),\n            converterPriority: 'high'\n        }).add((dispatcher)=>{\n            dispatcher.on('attribute', listItemDowncastConverter(attributeNames, this._downcastStrategies, model));\n            dispatcher.on('remove', listItemDowncastRemoveConverter(model.schema));\n        });\n        editor.conversion.for('dataDowncast').elementToElement({\n            model: elementName,\n            view: bogusParagraphCreator(attributeNames, {\n                dataPipeline: true\n            }),\n            converterPriority: 'high'\n        }).add((dispatcher)=>{\n            dispatcher.on('attribute', listItemDowncastConverter(attributeNames, this._downcastStrategies, model, {\n                dataPipeline: true\n            }));\n        });\n        const modelToViewPositionMapper = createModelToViewPositionMapper(this._downcastStrategies, editor.editing.view);\n        editor.editing.mapper.on('modelToViewPosition', modelToViewPositionMapper);\n        editor.data.mapper.on('modelToViewPosition', modelToViewPositionMapper);\n        this.listenTo(model.document, 'change:data', reconvertItemsOnDataChange(model, editor.editing, attributeNames, this), {\n            priority: 'high'\n        });\n        // For LI verify if an ID of the attribute element is correct.\n        this.on('checkAttributes:item', (evt, { viewElement, modelAttributes })=>{\n            if (viewElement.id != modelAttributes.listItemId) {\n                evt.return = true;\n                evt.stop();\n            }\n        });\n        // For UL and OL check if the name and ID of element is correct.\n        this.on('checkAttributes:list', (evt, { viewElement, modelAttributes })=>{\n            if (viewElement.name != getViewElementNameForListType(modelAttributes.listType) || viewElement.id != getViewElementIdForListType(modelAttributes.listType, modelAttributes.listIndent)) {\n                evt.return = true;\n                evt.stop();\n            }\n        });\n    }\n    /**\n\t * Registers model post-fixers.\n\t */ _setupModelPostFixing() {\n        const model = this.editor.model;\n        const attributeNames = this.getListAttributeNames();\n        // Register list fixing.\n        // First the low level handler.\n        model.document.registerPostFixer((writer)=>modelChangePostFixer$1(model, writer, attributeNames, this));\n        // Then the callbacks for the specific lists.\n        // The indentation fixing must be the first one...\n        this.on('postFixer', (evt, { listNodes, writer })=>{\n            evt.return = fixListIndents(listNodes, writer) || evt.return;\n        }, {\n            priority: 'high'\n        });\n        // ...then the item ids... and after that other fixers that rely on the correct indentation and ids.\n        this.on('postFixer', (evt, { listNodes, writer, seenIds })=>{\n            evt.return = fixListItemIds(listNodes, seenIds, writer) || evt.return;\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Integrates the feature with the clipboard via {@link module:engine/model/model~Model#insertContent} and\n\t * {@link module:engine/model/model~Model#getSelectedContent}.\n\t */ _setupClipboardIntegration() {\n        const model = this.editor.model;\n        const clipboardPipeline = this.editor.plugins.get('ClipboardPipeline');\n        this.listenTo(model, 'insertContent', createModelIndentPasteFixer(model), {\n            priority: 'high'\n        });\n        // To enhance the UX, the editor should not copy list attributes to the clipboard if the selection\n        // started and ended in the same list item.\n        //\n        // If the selection was enclosed in a single list item, there is a good chance the user did not want it\n        // copied as a list item but plain blocks.\n        //\n        // This avoids pasting orphaned list items instead of paragraphs, for instance, straight into the root.\n        //\n        //\t                       ┌─────────────────────┬───────────────────┐\n        //\t                       │ Selection           │ Clipboard content │\n        //\t                       ├─────────────────────┼───────────────────┤\n        //\t                       │ [* <Widget />]      │ <Widget />        │\n        //\t                       ├─────────────────────┼───────────────────┤\n        //\t                       │ [* Foo]             │ Foo               │\n        //\t                       ├─────────────────────┼───────────────────┤\n        //\t                       │ * Foo [bar] baz     │ bar               │\n        //\t                       ├─────────────────────┼───────────────────┤\n        //\t                       │ * Fo[o              │ o                 │\n        //\t                       │   ba]r              │ ba                │\n        //\t                       ├─────────────────────┼───────────────────┤\n        //\t                       │ * Fo[o              │ * o               │\n        //\t                       │ * ba]r              │ * ba              │\n        //\t                       ├─────────────────────┼───────────────────┤\n        //\t                       │ [* Foo              │ * Foo             │\n        //\t                       │  * bar]             │ * bar             │\n        //\t                       └─────────────────────┴───────────────────┘\n        //\n        // See https://github.com/ckeditor/ckeditor5/issues/11608, https://github.com/ckeditor/ckeditor5/issues/14969\n        this.listenTo(clipboardPipeline, 'outputTransformation', (evt, data)=>{\n            model.change((writer)=>{\n                // Remove last block if it's empty.\n                const allContentChildren = Array.from(data.content.getChildren());\n                const lastItem = allContentChildren[allContentChildren.length - 1];\n                if (allContentChildren.length > 1 && lastItem.is('element') && lastItem.isEmpty) {\n                    const contentChildrenExceptLastItem = allContentChildren.slice(0, -1);\n                    if (contentChildrenExceptLastItem.every(isListItemBlock)) {\n                        writer.remove(lastItem);\n                    }\n                }\n                // Copy/cut only content of a list item (for drag-drop move the whole list item).\n                if (data.method == 'copy' || data.method == 'cut') {\n                    const allChildren = Array.from(data.content.getChildren());\n                    const isSingleListItemSelected = isSingleListItem(allChildren);\n                    if (isSingleListItemSelected) {\n                        removeListAttributes(allChildren, writer);\n                    }\n                }\n            });\n        });\n    }\n    /**\n\t * Informs editor accessibility features about keystrokes brought by the plugin.\n\t */ _setupAccessibilityIntegration() {\n        const editor = this.editor;\n        const t = editor.t;\n        editor.accessibility.addKeystrokeInfoGroup({\n            id: 'list',\n            label: t('Keystrokes that can be used in a list'),\n            keystrokes: [\n                {\n                    label: t('Increase list item indent'),\n                    keystroke: 'Tab'\n                },\n                {\n                    label: t('Decrease list item indent'),\n                    keystroke: 'Shift+Tab'\n                }\n            ]\n        });\n    }\n}\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states (invalid `listItemId` and `listIndent` values).\n *\n * In the example below, there is a correct list structure.\n * Then the middle element is removed so the list structure will become incorrect:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>Item 2</paragraph>   <--- this is removed.\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n * ```\n *\n * The list structure after the middle element is removed:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=1>Item 3</paragraph>   <--- note that indent got post-fixed.\n * ```\n *\n * @param model The data model.\n * @param writer The writer to do changes with.\n * @param attributeNames The list of all model list attributes (including registered strategies).\n * @param ListEditing The document list editing plugin.\n * @returns `true` if any change has been applied, `false` otherwise.\n */ function modelChangePostFixer$1(model, writer, attributeNames, listEditing) {\n    const changes = model.document.differ.getChanges();\n    const itemToListHead = new Map();\n    const multiBlock = listEditing.editor.config.get('list.multiBlock');\n    let applied = false;\n    for (const entry of changes){\n        if (entry.type == 'insert' && entry.name != '$text') {\n            const item = entry.position.nodeAfter;\n            // Remove attributes in case of renamed element.\n            if (!model.schema.checkAttribute(item, 'listItemId')) {\n                for (const attributeName of Array.from(item.getAttributeKeys())){\n                    if (attributeNames.includes(attributeName)) {\n                        writer.removeAttribute(attributeName, item);\n                        applied = true;\n                    }\n                }\n            }\n            findAndAddListHeadToMap(entry.position, itemToListHead);\n            // Insert of a non-list item - check if there is a list after it.\n            if (!entry.attributes.has('listItemId')) {\n                findAndAddListHeadToMap(entry.position.getShiftedBy(entry.length), itemToListHead);\n            }\n            // Check if there is no nested list.\n            for (const { item: innerItem, previousPosition } of model.createRangeIn(item)){\n                if (isListItemBlock(innerItem)) {\n                    findAndAddListHeadToMap(previousPosition, itemToListHead);\n                }\n            }\n        } else if (entry.type == 'remove') {\n            findAndAddListHeadToMap(entry.position, itemToListHead);\n        } else if (entry.type == 'attribute' && attributeNames.includes(entry.attributeKey)) {\n            findAndAddListHeadToMap(entry.range.start, itemToListHead);\n            if (entry.attributeNewValue === null) {\n                findAndAddListHeadToMap(entry.range.start.getShiftedBy(1), itemToListHead);\n            }\n        }\n        // Make sure that there is no left over listItem element without attributes or a block with list attributes that is not a listItem.\n        if (!multiBlock && entry.type == 'attribute' && LIST_BASE_ATTRIBUTES.includes(entry.attributeKey)) {\n            const element = entry.range.start.nodeAfter;\n            if (entry.attributeNewValue === null && element && element.is('element', 'listItem')) {\n                writer.rename(element, 'paragraph');\n                applied = true;\n            } else if (entry.attributeOldValue === null && element && element.is('element') && element.name != 'listItem') {\n                writer.rename(element, 'listItem');\n                applied = true;\n            }\n        }\n    }\n    // Make sure that IDs are not shared by split list.\n    const seenIds = new Set();\n    for (const listHead of itemToListHead.values()){\n        applied = listEditing.fire('postFixer', {\n            listNodes: new ListBlocksIterable(listHead),\n            listHead,\n            writer,\n            seenIds\n        }) || applied;\n    }\n    return applied;\n}\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=\"0\">A</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=\"1\">B^</paragraph>\n * // At ^ paste:  <paragraph listType=\"numbered\" listItemId=\"x\" listIndent=\"0\">X</paragraph>\n * //              <paragraph listType=\"numbered\" listItemId=\"y\" listIndent=\"1\">Y</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=\"2\">C</paragraph>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=\"0\">A</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=\"1\">BX</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"y\" listIndent=\"2\">Y/paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=\"2\">C</paragraph>\n * ```\n */ function createModelIndentPasteFixer(model) {\n    return (evt, [content, selectable])=>{\n        const items = content.is('documentFragment') ? Array.from(content.getChildren()) : [\n            content\n        ];\n        if (!items.length) {\n            return;\n        }\n        const selection = selectable ? model.createSelection(selectable) : model.document.selection;\n        const position = selection.getFirstPosition();\n        // Get a reference list item. Attributes of the inserted list items will be fixed according to that item.\n        let refItem;\n        if (isListItemBlock(position.parent)) {\n            refItem = position.parent;\n        } else if (isListItemBlock(position.nodeBefore)) {\n            refItem = position.nodeBefore;\n        } else {\n            return; // Content is not copied into a list.\n        }\n        model.change((writer)=>{\n            const refType = refItem.getAttribute('listType');\n            const refIndent = refItem.getAttribute('listIndent');\n            const firstElementIndent = items[0].getAttribute('listIndent') || 0;\n            const indentDiff = Math.max(refIndent - firstElementIndent, 0);\n            for (const item of items){\n                const isListItem = isListItemBlock(item);\n                if (refItem.is('element', 'listItem') && item.is('element', 'paragraph')) {\n                    /**\n\t\t\t\t\t * When paragraphs or a plain text list is pasted into a simple list, convert\n\t\t\t\t\t * the `<paragraphs>' to `<listItem>' to avoid breaking the target list.\n\t\t\t\t\t *\n\t\t\t\t\t * See https://github.com/ckeditor/ckeditor5/issues/13826.\n\t\t\t\t\t */ writer.rename(item, 'listItem');\n                }\n                writer.setAttributes({\n                    listIndent: (isListItem ? item.getAttribute('listIndent') : 0) + indentDiff,\n                    listItemId: isListItem ? item.getAttribute('listItemId') : ListItemUid.next(),\n                    listType: refType\n                }, item);\n            }\n        });\n    };\n}\n/**\n * Decides whether the merge should be accompanied by the model's `deleteContent()`, for instance, to get rid of the inline\n * content in the selection or take advantage of the heuristics in `deleteContent()` that helps convert lists into paragraphs\n * in certain cases.\n */ function shouldMergeOnBlocksContentLevel(model, direction) {\n    const selection = model.document.selection;\n    if (!selection.isCollapsed) {\n        return !getSelectedBlockObject(model);\n    }\n    if (direction === 'forward') {\n        return true;\n    }\n    const firstPosition = selection.getFirstPosition();\n    const positionParent = firstPosition.parent;\n    const previousSibling = positionParent.previousSibling;\n    if (model.schema.isObject(previousSibling)) {\n        return false;\n    }\n    if (previousSibling.isEmpty) {\n        return true;\n    }\n    return isSingleListItem([\n        positionParent,\n        previousSibling\n    ]);\n}\n\n/**\n * Helper method for creating toolbar and menu buttons and linking them with an appropriate command.\n *\n * @internal\n * @param editor The editor instance to which the UI component will be added.\n * @param commandName The name of the command.\n * @param label The button label.\n * @param icon The source of the icon.\n */ function createUIComponents(editor, commandName, label, icon) {\n    editor.ui.componentFactory.add(commandName, ()=>{\n        const buttonView = _createButton(ButtonView, editor, commandName, label, icon);\n        buttonView.set({\n            tooltip: true,\n            isToggleable: true\n        });\n        return buttonView;\n    });\n    editor.ui.componentFactory.add(`menuBar:${commandName}`, ()=>{\n        const buttonView = _createButton(MenuBarMenuListItemButtonView, editor, commandName, label, icon);\n        buttonView.set({\n            role: 'menuitemcheckbox',\n            isToggleable: true\n        });\n        return buttonView;\n    });\n}\n/**\n * Creates a button to use either in toolbar or in menu bar.\n */ function _createButton(ButtonClass, editor, commandName, label, icon) {\n    const command = editor.commands.get(commandName);\n    const view = new ButtonClass(editor.locale);\n    view.set({\n        label,\n        icon\n    });\n    // Bind button model to command.\n    view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n    // Execute the command.\n    view.on('execute', ()=>{\n        editor.execute(commandName);\n        editor.editing.view.focus();\n    });\n    return view;\n}\n\n/**\n * The list UI feature. It introduces the `'numberedList'` and `'bulletedList'` buttons that\n * allow to convert paragraphs to and from list items and indent or outdent them.\n */ class ListUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ListUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const t = this.editor.t;\n        // Create button numberedList.\n        if (!this.editor.ui.componentFactory.has('numberedList')) {\n            createUIComponents(this.editor, 'numberedList', t('Numbered List'), icons.numberedList);\n        }\n        // Create button bulletedList.\n        if (!this.editor.ui.componentFactory.has('bulletedList')) {\n            createUIComponents(this.editor, 'bulletedList', t('Bulleted List'), icons.bulletedList);\n        }\n    }\n}\n\n/**\n * The list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/list/listediting~ListEditing  list\n * editing feature} and {@link module:list/list/listui~ListUI list UI feature}.\n */ class List extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ListEditing,\n            ListUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'List';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items,\n * letting the user to choose the starting point of an ordered list.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n */ class ListStartCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const value = this._getValue();\n        this.value = value;\n        this.isEnabled = value != null;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.startIndex The list start index.\n\t */ execute({ startIndex = 1 } = {}) {\n        const model = this.editor.model;\n        const document = model.document;\n        let blocks = Array.from(document.selection.getSelectedBlocks()).filter((block)=>isListItemBlock(block) && isNumberedListType(block.getAttribute('listType')));\n        blocks = expandListBlocksToCompleteList(blocks);\n        model.change((writer)=>{\n            for (const block of blocks){\n                writer.setAttribute('listStart', startIndex >= 0 ? startIndex : 1, block);\n            }\n        });\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */ _getValue() {\n        const model = this.editor.model;\n        const document = model.document;\n        const block = first(document.selection.getSelectedBlocks());\n        if (block && isListItemBlock(block) && isNumberedListType(block.getAttribute('listType'))) {\n            return block.getAttribute('listStart');\n        }\n        return null;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n* @module list/listproperties/utils/style\n*/ const LIST_STYLE_TO_LIST_TYPE = {};\nconst LIST_STYLE_TO_TYPE_ATTRIBUTE = {};\nconst TYPE_ATTRIBUTE_TO_LIST_STYLE = {};\nconst LIST_STYLE_TYPES = [\n    {\n        listStyle: 'disc',\n        typeAttribute: 'disc',\n        listType: 'bulleted'\n    },\n    {\n        listStyle: 'circle',\n        typeAttribute: 'circle',\n        listType: 'bulleted'\n    },\n    {\n        listStyle: 'square',\n        typeAttribute: 'square',\n        listType: 'bulleted'\n    },\n    {\n        listStyle: 'decimal',\n        typeAttribute: '1',\n        listType: 'numbered'\n    },\n    {\n        listStyle: 'decimal-leading-zero',\n        typeAttribute: null,\n        listType: 'numbered'\n    },\n    {\n        listStyle: 'lower-roman',\n        typeAttribute: 'i',\n        listType: 'numbered'\n    },\n    {\n        listStyle: 'upper-roman',\n        typeAttribute: 'I',\n        listType: 'numbered'\n    },\n    {\n        listStyle: 'lower-alpha',\n        typeAttribute: 'a',\n        listType: 'numbered'\n    },\n    {\n        listStyle: 'upper-alpha',\n        typeAttribute: 'A',\n        listType: 'numbered'\n    },\n    {\n        listStyle: 'lower-latin',\n        typeAttribute: 'a',\n        listType: 'numbered'\n    },\n    {\n        listStyle: 'upper-latin',\n        typeAttribute: 'A',\n        listType: 'numbered'\n    }\n];\nfor (const { listStyle, typeAttribute, listType } of LIST_STYLE_TYPES){\n    LIST_STYLE_TO_LIST_TYPE[listStyle] = listType;\n    LIST_STYLE_TO_TYPE_ATTRIBUTE[listStyle] = typeAttribute;\n    if (typeAttribute) {\n        TYPE_ATTRIBUTE_TO_LIST_STYLE[typeAttribute] = listStyle;\n    }\n}\n/**\n * Gets all the style types supported by given list type.\n */ function getAllSupportedStyleTypes() {\n    return LIST_STYLE_TYPES.map((x)=>x.listStyle);\n}\n/**\n * Checks whether the given list-style-type is supported by numbered or bulleted list.\n */ function getListTypeFromListStyleType$1(listStyleType) {\n    return LIST_STYLE_TO_LIST_TYPE[listStyleType] || null;\n}\n/**\n * Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n */ function getListStyleTypeFromTypeAttribute(value) {\n    return TYPE_ATTRIBUTE_TO_LIST_STYLE[value] || null;\n}\n/**\n * Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n */ function getTypeAttributeFromListStyleType(value) {\n    return LIST_STYLE_TO_TYPE_ATTRIBUTE[value] || null;\n}\n\n/**\n * The list style command. It changes `listStyle` attribute of the selected list items,\n * letting the user choose styles for the list item markers.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n */ class ListStyleCommand extends Command {\n    /**\n\t * The default type of the list style.\n\t */ defaultType;\n    /**\n\t * The list of supported style types by this command.\n\t */ _supportedTypes;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t * @param supportedTypes The list of supported style types by this command.\n\t */ constructor(editor, defaultType, supportedTypes){\n        super(editor);\n        this.defaultType = defaultType;\n        this._supportedTypes = supportedTypes;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.value = this._getValue();\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.type The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const document = model.document;\n        model.change((writer)=>{\n            this._tryToConvertItemsToList(options);\n            let blocks = Array.from(document.selection.getSelectedBlocks()).filter((block)=>block.hasAttribute('listType'));\n            if (!blocks.length) {\n                return;\n            }\n            blocks = expandListBlocksToCompleteList(blocks);\n            for (const block of blocks){\n                writer.setAttribute('listStyle', options.type || this.defaultType, block);\n            }\n        });\n    }\n    /**\n\t * Checks if the given style type is supported by this plugin.\n\t */ isStyleTypeSupported(value) {\n        if (!this._supportedTypes) {\n            return true;\n        }\n        return this._supportedTypes.includes(value);\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */ _getValue() {\n        const listItem = first(this.editor.model.document.selection.getSelectedBlocks());\n        if (isListItemBlock(listItem)) {\n            return listItem.getAttribute('listStyle');\n        }\n        return null;\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        const editor = this.editor;\n        const numberedList = editor.commands.get('numberedList');\n        const bulletedList = editor.commands.get('bulletedList');\n        return numberedList.isEnabled || bulletedList.isEnabled;\n    }\n    /**\n\t * Check if the provided list style is valid. Also change the selection to a list if it's not set yet.\n\t *\n\t * @param options.type The type of the list style. If `null` is specified, the function does nothing.\n\t*/ _tryToConvertItemsToList(options) {\n        if (!options.type) {\n            return;\n        }\n        const listType = getListTypeFromListStyleType$1(options.type);\n        if (!listType) {\n            return;\n        }\n        const editor = this.editor;\n        const commandName = `${listType}List`;\n        const command = editor.commands.get(commandName);\n        if (!command.value) {\n            editor.execute(commandName);\n        }\n    }\n}\n\n/**\n * The list reversed command. It changes the `listReversed` attribute of the selected list items,\n * letting the user to choose the order of an ordered list.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n */ class ListReversedCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const value = this._getValue();\n        this.value = value;\n        this.isEnabled = value != null;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.reversed Whether the list should be reversed.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const document = model.document;\n        let blocks = Array.from(document.selection.getSelectedBlocks()).filter((block)=>isListItemBlock(block) && block.getAttribute('listType') == 'numbered');\n        blocks = expandListBlocksToCompleteList(blocks);\n        model.change((writer)=>{\n            for (const block of blocks){\n                writer.setAttribute('listReversed', !!options.reversed, block);\n            }\n        });\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t */ _getValue() {\n        const model = this.editor.model;\n        const document = model.document;\n        const block = first(document.selection.getSelectedBlocks());\n        if (isListItemBlock(block) && block.getAttribute('listType') == 'numbered') {\n            return block.getAttribute('listReversed');\n        }\n        return null;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module list/listproperties/converters\n */ /**\n * Returns a converter that consumes the `style`, `reversed`, and `start` attributes.\n * In `style`, it searches for the `list-style-type` definition.\n * If not found, the `\"default\"` value will be used.\n *\n * @internal\n * @param strategy\n */ function listPropertiesUpcastConverter(strategy) {\n    return (evt, data, conversionApi)=>{\n        const { writer, schema, consumable } = conversionApi;\n        // If there is no view consumable to consume, set the default attribute value to be able to reconvert nested lists on parent change.\n        // So abort converting if attribute was directly consumed.\n        if (consumable.test(data.viewItem, strategy.viewConsumables) === false) {\n            return;\n        }\n        if (!data.modelRange) {\n            Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n        }\n        let applied = false;\n        for (const item of data.modelRange.getItems({\n            shallow: true\n        })){\n            if (!schema.checkAttribute(item, strategy.attributeName)) {\n                continue;\n            }\n            if (!strategy.appliesToListItem(item)) {\n                continue;\n            }\n            // Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n            if (item.hasAttribute(strategy.attributeName)) {\n                continue;\n            }\n            writer.setAttribute(strategy.attributeName, strategy.getAttributeOnUpcast(data.viewItem), item);\n            applied = true;\n        }\n        if (applied) {\n            consumable.consume(data.viewItem, strategy.viewConsumables);\n        }\n    };\n}\n\n/**\n * A set of helpers related to document lists.\n */ class ListPropertiesUtils extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ListPropertiesUtils';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * Gets all the style types supported by given list type.\n\t */ getAllSupportedStyleTypes() {\n        return getAllSupportedStyleTypes();\n    }\n    /**\n\t * Checks whether the given list-style-type is supported by numbered or bulleted list.\n\t */ getListTypeFromListStyleType(listStyleType) {\n        return getListTypeFromListStyleType$1(listStyleType);\n    }\n    /**\n\t * Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n\t */ getListStyleTypeFromTypeAttribute(value) {\n        return getListStyleTypeFromTypeAttribute(value);\n    }\n    /**\n\t * Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n\t */ getTypeAttributeFromListStyleType(value) {\n        return getTypeAttributeFromListStyleType(value);\n    }\n}\n\n/**\n * Normalizes {@link module:list/listconfig~ListPropertiesConfig} in the configuration of the list properties feature.\n * The structure of normalized list properties options looks as follows:\n *\n * ```ts\n * {\n * \tstyles: {\n * \t\tlistTypes: [ 'bulleted', 'numbered' ],\n * \t\tuseAttribute: false\n * \t},\n * \tstartIndex: true,\n * \treversed: true\n * }\n * ```\n *\n * @param config The list properties {@link module:list/listconfig~ListPropertiesConfig config}.\n * @returns An object with normalized list properties options.\n */ function getNormalizedConfig(config) {\n    const { startIndex, reversed, styles } = config;\n    return {\n        styles: getNormalizedStylesConfig(styles),\n        startIndex: startIndex || false,\n        reversed: reversed || false\n    };\n}\n/**\n * Normalizes styles in the configuration of the list properties feature.\n * The structure of normalized list properties options looks as follows:\n *\n * ```ts\n * {\n * \tlistTypes: [ 'bulleted', 'numbered' ],\n * \tuseAttribute: false\n * }\n * ```\n *\n * @param styles The list properties styles.\n * @returns An object with normalized list properties styles.\n */ function getNormalizedStylesConfig(styles) {\n    const normalizedConfig = {\n        listTypes: [\n            'bulleted',\n            'numbered'\n        ],\n        useAttribute: false\n    };\n    if (styles === true) {\n        return normalizedConfig;\n    }\n    if (!styles) {\n        normalizedConfig.listTypes = [];\n    } else if (Array.isArray(styles) || typeof styles == 'string') {\n        normalizedConfig.listTypes = toArray(styles);\n    } else {\n        normalizedConfig.listTypes = styles.listTypes ? toArray(styles.listTypes) : normalizedConfig.listTypes;\n        normalizedConfig.useAttribute = !!styles.useAttribute;\n    }\n    return normalizedConfig;\n}\n\nconst DEFAULT_LIST_TYPE$1 = 'default';\n/**\n * The document list properties engine feature.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listconfig~ListPropertiesConfig}.\n */ class ListPropertiesEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ListEditing,\n            ListPropertiesUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ListPropertiesEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('list.properties', {\n            styles: true,\n            startIndex: false,\n            reversed: false\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const listEditing = editor.plugins.get(ListEditing);\n        const enabledProperties = editor.config.get('list.properties');\n        const strategies = createAttributeStrategies$1(enabledProperties);\n        for (const strategy of strategies){\n            strategy.addCommand(editor);\n            model.schema.extend('$listItem', {\n                allowAttributes: strategy.attributeName\n            });\n            // Register downcast strategy.\n            listEditing.registerDowncastStrategy({\n                scope: 'list',\n                attributeName: strategy.attributeName,\n                setAttributeOnDowncast (writer, attributeValue, viewElement) {\n                    strategy.setAttributeOnDowncast(writer, attributeValue, viewElement);\n                }\n            });\n        }\n        // Set up conversion.\n        editor.conversion.for('upcast').add((dispatcher)=>{\n            for (const strategy of strategies){\n                dispatcher.on('element:ol', listPropertiesUpcastConverter(strategy));\n                dispatcher.on('element:ul', listPropertiesUpcastConverter(strategy));\n            }\n        });\n        // Verify if the list view element (ul or ol) requires refreshing.\n        listEditing.on('checkAttributes:list', (evt, { viewElement, modelAttributes })=>{\n            for (const strategy of strategies){\n                if (strategy.getAttributeOnUpcast(viewElement) != modelAttributes[strategy.attributeName]) {\n                    evt.return = true;\n                    evt.stop();\n                }\n            }\n        });\n        // Reset list properties after indenting list items.\n        this.listenTo(editor.commands.get('indentList'), 'afterExecute', (evt, changedBlocks)=>{\n            model.change((writer)=>{\n                for (const node of changedBlocks){\n                    for (const strategy of strategies){\n                        if (strategy.appliesToListItem(node)) {\n                            // Just reset the attribute.\n                            // If there is a previous indented list that this node should be merged into,\n                            // the postfixer will unify all the attributes of both sub-lists.\n                            writer.setAttribute(strategy.attributeName, strategy.defaultValue, node);\n                        }\n                    }\n                }\n            });\n        });\n        // Add or remove list properties attributes depending on the list type.\n        listEditing.on('postFixer', (evt, { listNodes, writer })=>{\n            for (const { node } of listNodes){\n                for (const strategy of strategies){\n                    // Check if attribute is valid.\n                    if (strategy.hasValidAttribute(node)) {\n                        continue;\n                    }\n                    // Add missing default property attributes...\n                    if (strategy.appliesToListItem(node)) {\n                        writer.setAttribute(strategy.attributeName, strategy.defaultValue, node);\n                    } else {\n                        writer.removeAttribute(strategy.attributeName, node);\n                    }\n                    evt.return = true;\n                }\n            }\n        });\n        // Make sure that all items in a single list (items at the same level & listType) have the same properties.\n        listEditing.on('postFixer', (evt, { listNodes, writer })=>{\n            for (const { node, previousNodeInList } of listNodes){\n                // This is a first item of a nested list.\n                if (!previousNodeInList) {\n                    continue;\n                }\n                // This is a first block of a list of a different type.\n                if (previousNodeInList.getAttribute('listType') != node.getAttribute('listType')) {\n                    continue;\n                }\n                // Copy properties from the previous one.\n                for (const strategy of strategies){\n                    const { attributeName } = strategy;\n                    if (!strategy.appliesToListItem(node)) {\n                        continue;\n                    }\n                    const value = previousNodeInList.getAttribute(attributeName);\n                    if (node.getAttribute(attributeName) != value) {\n                        writer.setAttribute(attributeName, value, node);\n                        evt.return = true;\n                    }\n                }\n            }\n        });\n    }\n}\n/**\n * Creates an array of strategies for dealing with enabled listItem attributes.\n */ function createAttributeStrategies$1(enabledProperties) {\n    const strategies = [];\n    const normalizedConfig = getNormalizedConfig(enabledProperties);\n    if (enabledProperties.styles) {\n        const useAttribute = normalizedConfig.styles.useAttribute;\n        strategies.push({\n            attributeName: 'listStyle',\n            defaultValue: DEFAULT_LIST_TYPE$1,\n            viewConsumables: {\n                styles: 'list-style-type'\n            },\n            addCommand (editor) {\n                let supportedTypes = getAllSupportedStyleTypes();\n                if (useAttribute) {\n                    supportedTypes = supportedTypes.filter((styleType)=>!!getTypeAttributeFromListStyleType(styleType));\n                }\n                editor.commands.add('listStyle', new ListStyleCommand(editor, DEFAULT_LIST_TYPE$1, supportedTypes));\n            },\n            appliesToListItem (item) {\n                return item.getAttribute('listType') == 'numbered' || item.getAttribute('listType') == 'bulleted';\n            },\n            hasValidAttribute (item) {\n                if (!this.appliesToListItem(item)) {\n                    return !item.hasAttribute('listStyle');\n                }\n                if (!item.hasAttribute('listStyle')) {\n                    return false;\n                }\n                const value = item.getAttribute('listStyle');\n                if (value == DEFAULT_LIST_TYPE$1) {\n                    return true;\n                }\n                return getListTypeFromListStyleType$1(value) == item.getAttribute('listType');\n            },\n            setAttributeOnDowncast (writer, listStyle, element) {\n                if (listStyle && listStyle !== DEFAULT_LIST_TYPE$1) {\n                    if (useAttribute) {\n                        const value = getTypeAttributeFromListStyleType(listStyle);\n                        if (value) {\n                            writer.setAttribute('type', value, element);\n                            return;\n                        }\n                    } else {\n                        writer.setStyle('list-style-type', listStyle, element);\n                        return;\n                    }\n                }\n                writer.removeStyle('list-style-type', element);\n                writer.removeAttribute('type', element);\n            },\n            getAttributeOnUpcast (listParent) {\n                const style = listParent.getStyle('list-style-type');\n                if (style) {\n                    return style;\n                }\n                const attribute = listParent.getAttribute('type');\n                if (attribute) {\n                    return getListStyleTypeFromTypeAttribute(attribute);\n                }\n                return DEFAULT_LIST_TYPE$1;\n            }\n        });\n    }\n    if (enabledProperties.reversed) {\n        strategies.push({\n            attributeName: 'listReversed',\n            defaultValue: false,\n            viewConsumables: {\n                attributes: 'reversed'\n            },\n            addCommand (editor) {\n                editor.commands.add('listReversed', new ListReversedCommand(editor));\n            },\n            appliesToListItem (item) {\n                return item.getAttribute('listType') == 'numbered';\n            },\n            hasValidAttribute (item) {\n                return this.appliesToListItem(item) == item.hasAttribute('listReversed');\n            },\n            setAttributeOnDowncast (writer, listReversed, element) {\n                if (listReversed) {\n                    writer.setAttribute('reversed', 'reversed', element);\n                } else {\n                    writer.removeAttribute('reversed', element);\n                }\n            },\n            getAttributeOnUpcast (listParent) {\n                return listParent.hasAttribute('reversed');\n            }\n        });\n    }\n    if (enabledProperties.startIndex) {\n        strategies.push({\n            attributeName: 'listStart',\n            defaultValue: 1,\n            viewConsumables: {\n                attributes: 'start'\n            },\n            addCommand (editor) {\n                editor.commands.add('listStart', new ListStartCommand(editor));\n            },\n            appliesToListItem (item) {\n                return isNumberedListType(item.getAttribute('listType'));\n            },\n            hasValidAttribute (item) {\n                return this.appliesToListItem(item) == item.hasAttribute('listStart');\n            },\n            setAttributeOnDowncast (writer, listStart, element) {\n                if (listStart == 0 || listStart > 1) {\n                    writer.setAttribute('start', listStart, element);\n                } else {\n                    writer.removeAttribute('start', element);\n                }\n            },\n            getAttributeOnUpcast (listParent) {\n                const startAttributeValue = listParent.getAttribute('start');\n                return startAttributeValue >= 0 ? startAttributeValue : 1;\n            }\n        });\n    }\n    return strategies;\n}\n\n/**\n * The list properties view to be displayed in the list dropdown.\n *\n * Contains a grid of available list styles and, for numbered list, also the list start index and reversed fields.\n *\n * @internal\n */ class ListPropertiesView extends View {\n    /**\n\t * A collection of the child views.\n\t */ children;\n    /**\n\t * A view that renders the grid of list styles.\n\t */ stylesView = null;\n    /**\n\t * A collapsible view that hosts additional list property fields ({@link #startIndexFieldView} and\n\t * {@link #reversedSwitchButtonView}) to visually separate them from the {@link #stylesView grid of styles}.\n\t *\n\t * **Note**: Only present when:\n\t * * the view represents **numbered** list properties,\n\t * * and the {@link #stylesView} is rendered,\n\t * * and either {@link #startIndexFieldView} or {@link #reversedSwitchButtonView} is rendered.\n\t *\n\t * @readonly\n\t */ additionalPropertiesCollapsibleView = null;\n    /**\n\t * A labeled number field allowing the user to set the start index of the list.\n\t *\n\t * **Note**: Only present when the view represents **numbered** list properties.\n\t *\n\t * @readonly\n\t */ startIndexFieldView = null;\n    /**\n\t * A switch button allowing the user to make the edited list reversed.\n\t *\n\t * **Note**: Only present when the view represents **numbered** list properties.\n\t *\n\t * @readonly\n\t */ reversedSwitchButtonView = null;\n    /**\n\t * Tracks information about the DOM focus in the view.\n\t */ focusTracker = new FocusTracker();\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes = new KeystrokeHandler();\n    /**\n\t * A collection of views that can be focused in the properties view.\n\t */ focusables = new ViewCollection();\n    /**\n\t * Helps cycling over {@link #focusables} in the view.\n\t */ focusCycler;\n    /**\n\t * Creates an instance of the list properties view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options Options of the view.\n\t * @param options.enabledProperties An object containing the configuration of enabled list property names.\n\t * Allows conditional rendering the sub-components of the properties view.\n\t * @param options.styleButtonViews A list of style buttons to be rendered\n\t * inside the styles grid. The grid will not be rendered when `enabledProperties` does not include the `'styles'` key.\n\t * @param options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n\t */ constructor(locale, { enabledProperties, styleButtonViews, styleGridAriaLabel }){\n        super(locale);\n        const elementCssClasses = [\n            'ck',\n            'ck-list-properties'\n        ];\n        this.children = this.createCollection();\n        this.focusCycler = new FocusCycler({\n            focusables: this.focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate #children backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate #children forwards using the <kbd>Tab</kbd> key.\n                focusNext: 'tab'\n            }\n        });\n        // The rendering of the styles grid is conditional. When there is no styles grid, the view will render without collapsible\n        // for numbered list properties, hence simplifying the layout.\n        if (styleButtonViews && styleButtonViews.length) {\n            this.stylesView = this._createStylesView(styleButtonViews, styleGridAriaLabel);\n            this.children.add(this.stylesView);\n        } else {\n            elementCssClasses.push('ck-list-properties_without-styles');\n        }\n        // The rendering of the numbered list property views is also conditional. It only makes sense for the numbered list\n        // dropdown. The unordered list does not have such properties.\n        if (enabledProperties.startIndex || enabledProperties.reversed) {\n            this._addNumberedListPropertyViews(enabledProperties);\n            elementCssClasses.push('ck-list-properties_with-numbered-properties');\n        }\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: elementCssClasses\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        if (this.stylesView) {\n            this.focusables.add(this.stylesView);\n            this.focusTracker.add(this.stylesView.element);\n            // Register the collapsible toggle button to the focus system.\n            if (this.startIndexFieldView || this.reversedSwitchButtonView) {\n                this.focusables.add(this.children.last.buttonView);\n                this.focusTracker.add(this.children.last.buttonView.element);\n            }\n            for (const item of this.stylesView.children){\n                this.stylesView.focusTracker.add(item.element);\n            }\n            addKeyboardHandlingForGrid({\n                keystrokeHandler: this.stylesView.keystrokes,\n                focusTracker: this.stylesView.focusTracker,\n                gridItems: this.stylesView.children,\n                // Note: The styles view has a different number of columns depending on whether the other properties\n                // are enabled in the dropdown or not (https://github.com/ckeditor/ckeditor5/issues/12340)\n                numberOfColumns: ()=>global.window.getComputedStyle(this.stylesView.element).getPropertyValue('grid-template-columns').split(' ').length,\n                uiLanguageDirection: this.locale && this.locale.uiLanguageDirection\n            });\n        }\n        if (this.startIndexFieldView) {\n            this.focusables.add(this.startIndexFieldView);\n            this.focusTracker.add(this.startIndexFieldView.element);\n            const stopPropagation = (data)=>data.stopPropagation();\n            // Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n            // keystroke handler would take over the key management in the input. We need to prevent\n            // this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n            this.keystrokes.set('arrowright', stopPropagation);\n            this.keystrokes.set('arrowleft', stopPropagation);\n            this.keystrokes.set('arrowup', stopPropagation);\n            this.keystrokes.set('arrowdown', stopPropagation);\n        }\n        if (this.reversedSwitchButtonView) {\n            this.focusables.add(this.reversedSwitchButtonView);\n            this.focusTracker.add(this.reversedSwitchButtonView.element);\n        }\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ focus() {\n        this.focusCycler.focusFirst();\n    }\n    /**\n\t * @inheritDoc\n\t */ focusLast() {\n        this.focusCycler.focusLast();\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Creates the list styles grid.\n\t *\n\t * @param styleButtons Buttons to be placed in the grid.\n\t * @param styleGridAriaLabel The assistive technology label of the grid.\n\t */ _createStylesView(styleButtons, styleGridAriaLabel) {\n        const stylesView = new View(this.locale);\n        stylesView.children = stylesView.createCollection();\n        stylesView.children.addMany(styleButtons);\n        stylesView.setTemplate({\n            tag: 'div',\n            attributes: {\n                'aria-label': styleGridAriaLabel,\n                class: [\n                    'ck',\n                    'ck-list-styles-list'\n                ]\n            },\n            children: stylesView.children\n        });\n        stylesView.children.delegate('execute').to(this);\n        stylesView.focus = function() {\n            this.children.first.focus();\n        };\n        stylesView.focusTracker = new FocusTracker();\n        stylesView.keystrokes = new KeystrokeHandler();\n        stylesView.render();\n        stylesView.keystrokes.listenTo(stylesView.element);\n        return stylesView;\n    }\n    /**\n\t * Renders {@link #startIndexFieldView} and/or {@link #reversedSwitchButtonView} depending on the configuration of the properties view.\n\t *\n\t * @param enabledProperties An object containing the configuration of enabled list property names\n\t * (see {@link #constructor}).\n\t */ _addNumberedListPropertyViews(enabledProperties) {\n        const t = this.locale.t;\n        const numberedPropertyViews = [];\n        if (enabledProperties.startIndex) {\n            this.startIndexFieldView = this._createStartIndexField();\n            numberedPropertyViews.push(this.startIndexFieldView);\n        }\n        if (enabledProperties.reversed) {\n            this.reversedSwitchButtonView = this._createReversedSwitchButton();\n            numberedPropertyViews.push(this.reversedSwitchButtonView);\n        }\n        // When there are some style buttons, pack the numbered list properties into a collapsible to separate them.\n        if (this.stylesView) {\n            this.additionalPropertiesCollapsibleView = new CollapsibleView(this.locale, numberedPropertyViews);\n            this.additionalPropertiesCollapsibleView.set({\n                label: t('List properties'),\n                isCollapsed: true\n            });\n            // Don't enable the collapsible view unless either start index or reversed field is enabled (e.g. when no list is selected).\n            this.additionalPropertiesCollapsibleView.buttonView.bind('isEnabled').toMany(numberedPropertyViews, 'isEnabled', (...areEnabled)=>areEnabled.some((isEnabled)=>isEnabled));\n            // Automatically collapse the additional properties collapsible when either start index or reversed field gets disabled.\n            this.additionalPropertiesCollapsibleView.buttonView.on('change:isEnabled', (evt, data, isEnabled)=>{\n                if (!isEnabled) {\n                    this.additionalPropertiesCollapsibleView.isCollapsed = true;\n                }\n            });\n            this.children.add(this.additionalPropertiesCollapsibleView);\n        } else {\n            this.children.addMany(numberedPropertyViews);\n        }\n    }\n    /**\n\t * Creates the list start index labeled field.\n\t */ _createStartIndexField() {\n        const t = this.locale.t;\n        const startIndexFieldView = new LabeledFieldView(this.locale, createLabeledInputNumber);\n        startIndexFieldView.set({\n            label: t('Start at'),\n            class: 'ck-numbered-list-properties__start-index'\n        });\n        startIndexFieldView.fieldView.set({\n            min: 0,\n            step: 1,\n            value: 1,\n            inputMode: 'numeric'\n        });\n        startIndexFieldView.fieldView.on('input', ()=>{\n            const inputElement = startIndexFieldView.fieldView.element;\n            const startIndex = inputElement.valueAsNumber;\n            if (Number.isNaN(startIndex)) {\n                // Number inputs allow for the entry of characters that may result in NaN,\n                // such as 'e', '+', '123e', '2-'.\n                startIndexFieldView.errorText = t('Invalid start index value.');\n                return;\n            }\n            if (!inputElement.checkValidity()) {\n                startIndexFieldView.errorText = t('Start index must be greater than 0.');\n            } else {\n                this.fire('listStart', {\n                    startIndex\n                });\n            }\n        });\n        return startIndexFieldView;\n    }\n    /**\n\t * Creates the reversed list switch button.\n\t */ _createReversedSwitchButton() {\n        const t = this.locale.t;\n        const reversedButtonView = new SwitchButtonView(this.locale);\n        reversedButtonView.set({\n            withText: true,\n            label: t('Reversed order'),\n            class: 'ck-numbered-list-properties__reversed-order'\n        });\n        reversedButtonView.delegate('execute').to(this, 'listReversed');\n        return reversedButtonView;\n    }\n}\n\nvar listStyleDiscIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11 27a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0-9a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0-9a3 3 0 1 1 0 6 3 3 0 0 1 0-6z\\\"/></svg>\";\n\nvar listStyleCircleIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11 27a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm0-10a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm0-10a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\\\"/></svg>\";\n\nvar listStyleSquareIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M14 27v6H8v-6h6zm0-9v6H8v-6h6zm0-9v6H8V9h6z\\\"/></svg>\";\n\nvar listStyleDecimalIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M10.29 15V8.531H9.286c-.14.393-.4.736-.778 1.03-.378.295-.728.495-1.05.6v1.121a4.257 4.257 0 0 0 1.595-.936V15h1.235zm3.343 0v-1.235h-1.235V15h1.235zM11.3 24v-1.147H8.848c.064-.111.148-.226.252-.343.104-.117.351-.354.74-.712.39-.357.66-.631.81-.821.225-.288.39-.562.494-.824.104-.263.156-.539.156-.829 0-.51-.182-.936-.545-1.279-.363-.342-.863-.514-1.499-.514-.58 0-1.063.148-1.45.444-.387.296-.617.784-.69 1.463l1.23.124c.024-.36.112-.619.264-.774.153-.155.358-.233.616-.233.26 0 .465.074.613.222.148.148.222.36.222.635 0 .25-.085.501-.255.756-.126.185-.468.536-1.024 1.055-.692.641-1.155 1.156-1.389 1.544-.234.389-.375.8-.422 1.233H11.3zm2.333 0v-1.235h-1.235V24h1.235zM9.204 34.11c.615 0 1.129-.2 1.542-.598.413-.398.62-.88.62-1.446 0-.39-.11-.722-.332-.997a1.5 1.5 0 0 0-.886-.532c.619-.337.928-.788.928-1.353 0-.399-.151-.756-.453-1.073-.366-.386-.852-.58-1.459-.58a2.25 2.25 0 0 0-.96.2 1.617 1.617 0 0 0-.668.55c-.16.232-.28.544-.358.933l1.138.194c.032-.282.123-.495.272-.642.15-.146.33-.22.54-.22.215 0 .386.065.515.194s.193.302.193.518c0 .255-.087.46-.263.613-.176.154-.43.227-.765.218l-.136 1.006c.22-.061.409-.092.567-.092.24 0 .444.09.61.272.168.182.251.428.251.739 0 .328-.087.589-.261.782a.833.833 0 0 1-.644.29.841.841 0 0 1-.607-.242c-.167-.16-.27-.394-.307-.698l-1.196.145c.062.542.285.98.668 1.316.384.335.868.503 1.45.503zm4.43-.11v-1.235h-1.236V34h1.235z\\\"/></svg>\";\n\nvar listStyleDecimalWithLeadingZeroIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M5.714 15.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm6.078.914V8.531H10.79c-.14.393-.4.736-.778 1.03-.378.295-.728.495-1.05.6v1.121a4.257 4.257 0 0 0 1.595-.936V15h1.235zm3.344 0v-1.235h-1.235V15h1.235zm-9.422 9.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm7.088.914v-1.147H10.35c.065-.111.149-.226.253-.343.104-.117.35-.354.74-.712.39-.357.66-.631.81-.821.225-.288.39-.562.493-.824.104-.263.156-.539.156-.829 0-.51-.181-.936-.544-1.279-.364-.342-.863-.514-1.499-.514-.58 0-1.063.148-1.45.444-.387.296-.617.784-.69 1.463l1.23.124c.024-.36.112-.619.264-.774.152-.155.357-.233.615-.233.261 0 .465.074.613.222.148.148.222.36.222.635 0 .25-.085.501-.255.756-.126.185-.467.536-1.024 1.055-.691.641-1.154 1.156-1.388 1.544-.235.389-.375.8-.422 1.233h4.328zm2.334 0v-1.235h-1.235V24h1.235zM5.714 34.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm4.992 1.024c.616 0 1.13-.2 1.543-.598.413-.398.62-.88.62-1.446 0-.39-.111-.722-.332-.997a1.5 1.5 0 0 0-.886-.532c.618-.337.927-.788.927-1.353 0-.399-.15-.756-.452-1.073-.366-.386-.853-.58-1.46-.58a2.25 2.25 0 0 0-.96.2 1.617 1.617 0 0 0-.667.55c-.16.232-.28.544-.359.933l1.139.194c.032-.282.123-.495.272-.642.15-.146.33-.22.54-.22.214 0 .386.065.515.194s.193.302.193.518c0 .255-.088.46-.264.613-.175.154-.43.227-.764.218l-.136 1.006c.22-.061.408-.092.566-.092.24 0 .444.09.611.272.167.182.25.428.25.739 0 .328-.086.589-.26.782a.833.833 0 0 1-.644.29.841.841 0 0 1-.607-.242c-.167-.16-.27-.394-.308-.698l-1.195.145c.062.542.284.98.668 1.316.384.335.867.503 1.45.503zm4.43-.11v-1.235h-1.235V34h1.235z\\\"/></svg>\";\n\nvar listStyleLowerRomanIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11.88 8.7V7.558h-1.234V8.7h1.234zm0 5.3V9.333h-1.234V14h1.234zm2.5 0v-1.235h-1.234V14h1.235zm-4.75 4.7v-1.142H8.395V18.7H9.63zm0 5.3v-4.667H8.395V24H9.63zm2.5-5.3v-1.142h-1.234V18.7h1.235zm0 5.3v-4.667h-1.234V24h1.235zm2.501 0v-1.235h-1.235V24h1.235zM7.38 28.7v-1.142H6.145V28.7H7.38zm0 5.3v-4.667H6.145V34H7.38zm2.5-5.3v-1.142H8.646V28.7H9.88zm0 5.3v-4.667H8.646V34H9.88zm2.5-5.3v-1.142h-1.234V28.7h1.235zm0 5.3v-4.667h-1.234V34h1.235zm2.501 0v-1.235h-1.235V34h1.235z\\\"/></svg>\";\n\nvar listStyleUpperRomanIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11.916 15V8.558h-1.301V15h1.3zm2.465 0v-1.235h-1.235V15h1.235zM9.665 25v-6.442h-1.3V25h1.3zm2.5 0v-6.442h-1.3V25h1.3zm2.466 0v-1.235h-1.235V25h1.235zm-7.216 9v-6.442h-1.3V34h1.3zm2.5 0v-6.442h-1.3V34h1.3zm2.501 0v-6.442h-1.3V34h1.3zm2.465 0v-1.235h-1.235V34h1.235z\\\"/></svg>\";\n\nvar listStyleLowerLatinIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M9.62 14.105c.272 0 .528-.05.768-.153s.466-.257.677-.462c.009.024.023.072.044.145.047.161.086.283.119.365h1.221a2.649 2.649 0 0 1-.222-.626c-.04-.195-.059-.498-.059-.908l.013-1.441c0-.536-.055-.905-.165-1.105-.11-.201-.3-.367-.569-.497-.27-.13-.68-.195-1.23-.195-.607 0-1.064.108-1.371.325-.308.217-.525.55-.65 1.002l1.12.202c.076-.217.176-.369.299-.455.123-.086.294-.13.514-.13.325 0 .546.05.663.152.118.101.176.27.176.508v.123c-.222.093-.622.194-1.2.303-.427.082-.755.178-.982.288-.227.11-.403.268-.53.474a1.327 1.327 0 0 0-.188.706c0 .398.138.728.415.988.277.261.656.391 1.136.391zm.368-.87a.675.675 0 0 1-.492-.189.606.606 0 0 1-.193-.448c0-.176.08-.32.241-.435.106-.07.33-.142.673-.215a7.19 7.19 0 0 0 .751-.19v.247c0 .296-.016.496-.048.602a.773.773 0 0 1-.295.409 1.07 1.07 0 0 1-.637.22zm4.645.765v-1.235h-1.235V14h1.235zM10.2 25.105c.542 0 1.003-.215 1.382-.646.38-.43.57-1.044.57-1.84 0-.771-.187-1.362-.559-1.774a1.82 1.82 0 0 0-1.41-.617c-.522 0-.973.216-1.354.65v-2.32H7.594V25h1.147v-.686a1.9 1.9 0 0 0 .67.592c.26.133.523.2.79.2zm-.299-.975c-.354 0-.638-.164-.852-.492-.153-.232-.229-.59-.229-1.073 0-.468.098-.818.295-1.048a.93.93 0 0 1 .738-.345c.302 0 .55.118.743.354.193.236.29.62.29 1.154 0 .5-.096.868-.288 1.1-.192.233-.424.35-.697.35zm4.478.87v-1.235h-1.234V25h1.234zm-4.017 9.105c.6 0 1.08-.142 1.437-.426.357-.284.599-.704.725-1.261l-1.213-.207c-.061.326-.167.555-.316.688a.832.832 0 0 1-.576.2.916.916 0 0 1-.75-.343c-.185-.228-.278-.62-.278-1.173 0-.498.091-.853.274-1.066.183-.212.429-.318.736-.318.232 0 .42.061.565.184.145.123.238.306.28.55l1.216-.22c-.146-.501-.387-.874-.722-1.119-.336-.244-.788-.366-1.356-.366-.695 0-1.245.214-1.653.643-.407.43-.61 1.03-.61 1.8 0 .762.202 1.358.608 1.788.406.431.95.646 1.633.646zM14.633 34v-1.235h-1.235V34h1.235z\\\"/></svg>\";\n\nvar listStyleUpperLatinIcon = \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"m7.88 15 .532-1.463h2.575L11.549 15h1.415l-2.58-6.442H9.01L6.5 15h1.38zm2.69-2.549H8.811l.87-2.39.887 2.39zM14.88 15v-1.235h-1.234V15h1.234zM9.352 25c.83-.006 1.352-.02 1.569-.044.346-.038.636-.14.872-.305.236-.166.422-.387.558-.664.137-.277.205-.562.205-.855 0-.372-.106-.695-.317-.97-.21-.276-.512-.471-.905-.585a1.51 1.51 0 0 0 .661-.567 1.5 1.5 0 0 0 .244-.83c0-.28-.066-.53-.197-.754a1.654 1.654 0 0 0-.495-.539 1.676 1.676 0 0 0-.672-.266c-.25-.042-.63-.063-1.14-.063H7.158V25h2.193zm.142-3.88H8.46v-1.49h.747c.612 0 .983.007 1.112.022.217.026.38.102.49.226.11.125.165.287.165.486a.68.68 0 0 1-.192.503.86.86 0 0 1-.525.23 11.47 11.47 0 0 1-.944.023h.18zm.17 2.795H8.46v-1.723h1.05c.592 0 .977.03 1.154.092.177.062.313.16.406.295a.84.84 0 0 1 .14.492c0 .228-.06.41-.181.547a.806.806 0 0 1-.473.257c-.126.026-.423.04-.892.04zM14.88 25v-1.235h-1.234V25h1.234zm-5.018 9.11c.691 0 1.262-.17 1.711-.512.45-.341.772-.864.965-1.567l-1.261-.4c-.109.472-.287.818-.536 1.037-.25.22-.547.33-.892.33-.47 0-.85-.173-1.143-.519-.293-.345-.44-.925-.44-1.74 0-.767.15-1.322.447-1.665.297-.343.684-.514 1.162-.514.346 0 .64.096.881.29.242.193.4.457.477.79l1.288-.307c-.147-.516-.367-.911-.66-1.187-.492-.465-1.132-.698-1.92-.698-.902 0-1.63.296-2.184.89-.554.593-.83 1.426-.83 2.498 0 1.014.275 1.813.825 2.397.551.585 1.254.877 2.11.877zM14.88 34v-1.235h-1.234V34h1.234z\\\"/></svg>\";\n\n/**\n * The list properties UI plugin. It introduces the extended `'bulletedList'` and `'numberedList'` toolbar\n * buttons that allow users to control such aspects of list as the marker, start index or order.\n *\n * **Note**: Buttons introduced by this plugin override implementations from the {@link module:list/list/listui~ListUI}\n * (because they share the same names).\n */ class ListPropertiesUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ListPropertiesUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    init() {\n        const editor = this.editor;\n        const t = editor.locale.t;\n        const propertiesConfig = editor.config.get('list.properties');\n        const normalizedConfig = getNormalizedConfig(propertiesConfig);\n        const stylesListTypes = normalizedConfig.styles.listTypes;\n        // Note: When this plugin does not register the \"bulletedList\" dropdown due to properties configuration,\n        // a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n        // in most editor configuration because the List plugin automatically requires ListUI.\n        if (stylesListTypes.includes('bulleted')) {\n            const styleDefinitions = [\n                {\n                    label: t('Toggle the disc list style'),\n                    tooltip: t('Disc'),\n                    type: 'disc',\n                    icon: listStyleDiscIcon\n                },\n                {\n                    label: t('Toggle the circle list style'),\n                    tooltip: t('Circle'),\n                    type: 'circle',\n                    icon: listStyleCircleIcon\n                },\n                {\n                    label: t('Toggle the square list style'),\n                    tooltip: t('Square'),\n                    type: 'square',\n                    icon: listStyleSquareIcon\n                }\n            ];\n            const buttonLabel = t('Bulleted List');\n            const styleGridAriaLabel = t('Bulleted list styles toolbar');\n            const commandName = 'bulletedList';\n            editor.ui.componentFactory.add(commandName, getDropdownViewCreator({\n                editor,\n                normalizedConfig,\n                parentCommandName: commandName,\n                buttonLabel,\n                buttonIcon: icons.bulletedList,\n                styleGridAriaLabel,\n                styleDefinitions\n            }));\n            // Add the menu bar item for bulleted list.\n            editor.ui.componentFactory.add(`menuBar:${commandName}`, getMenuBarStylesMenuCreator({\n                editor,\n                normalizedConfig,\n                parentCommandName: commandName,\n                buttonLabel,\n                styleGridAriaLabel,\n                styleDefinitions\n            }));\n        }\n        // Note: When this plugin does not register the \"numberedList\" dropdown due to properties configuration,\n        // a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n        // in most editor configuration because the List plugin automatically requires ListUI.\n        if (stylesListTypes.includes('numbered') || propertiesConfig.startIndex || propertiesConfig.reversed) {\n            const styleDefinitions = [\n                {\n                    label: t('Toggle the decimal list style'),\n                    tooltip: t('Decimal'),\n                    type: 'decimal',\n                    icon: listStyleDecimalIcon\n                },\n                {\n                    label: t('Toggle the decimal with leading zero list style'),\n                    tooltip: t('Decimal with leading zero'),\n                    type: 'decimal-leading-zero',\n                    icon: listStyleDecimalWithLeadingZeroIcon\n                },\n                {\n                    label: t('Toggle the lower–roman list style'),\n                    tooltip: t('Lower–roman'),\n                    type: 'lower-roman',\n                    icon: listStyleLowerRomanIcon\n                },\n                {\n                    label: t('Toggle the upper–roman list style'),\n                    tooltip: t('Upper-roman'),\n                    type: 'upper-roman',\n                    icon: listStyleUpperRomanIcon\n                },\n                {\n                    label: t('Toggle the lower–latin list style'),\n                    tooltip: t('Lower-latin'),\n                    type: 'lower-latin',\n                    icon: listStyleLowerLatinIcon\n                },\n                {\n                    label: t('Toggle the upper–latin list style'),\n                    tooltip: t('Upper-latin'),\n                    type: 'upper-latin',\n                    icon: listStyleUpperLatinIcon\n                }\n            ];\n            const buttonLabel = t('Numbered List');\n            const styleGridAriaLabel = t('Numbered list styles toolbar');\n            const commandName = 'numberedList';\n            editor.ui.componentFactory.add(commandName, getDropdownViewCreator({\n                editor,\n                normalizedConfig,\n                parentCommandName: commandName,\n                buttonLabel,\n                buttonIcon: icons.numberedList,\n                styleGridAriaLabel,\n                styleDefinitions\n            }));\n            // Menu bar menu does not display list start index or reverse UI. If there are no styles enabled,\n            // the menu makes no sense and should be omitted.\n            if (stylesListTypes.includes('numbered')) {\n                editor.ui.componentFactory.add(`menuBar:${commandName}`, getMenuBarStylesMenuCreator({\n                    editor,\n                    normalizedConfig,\n                    parentCommandName: commandName,\n                    buttonLabel,\n                    styleGridAriaLabel,\n                    styleDefinitions\n                }));\n            }\n        }\n    }\n}\n/**\n * A helper that returns a function that creates a split button with a toolbar in the dropdown,\n * which in turn contains buttons allowing users to change list styles in the context of the current selection.\n *\n * @param options.editor\n * @param options.normalizedConfig List properties configuration.\n * @param options.parentCommandName The name of the higher-order editor command associated with\n * the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n * @param options.buttonLabel Label of the main part of the split button.\n * @param options.buttonIcon The SVG string of an icon for the main part of the split button.\n * @param options.styleGridAriaLabel The ARIA label for the styles grid in the split button dropdown.\n * @param options.styleDefinitions Definitions of the style buttons.\n * @returns A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\n */ function getDropdownViewCreator({ editor, normalizedConfig, parentCommandName, buttonLabel, buttonIcon, styleGridAriaLabel, styleDefinitions }) {\n    const parentCommand = editor.commands.get(parentCommandName);\n    return (locale)=>{\n        const dropdownView = createDropdown(locale, SplitButtonView);\n        const mainButtonView = dropdownView.buttonView;\n        dropdownView.bind('isEnabled').to(parentCommand);\n        dropdownView.class = 'ck-list-styles-dropdown';\n        // Main button was clicked.\n        mainButtonView.on('execute', ()=>{\n            editor.execute(parentCommandName);\n            editor.editing.view.focus();\n        });\n        mainButtonView.set({\n            label: buttonLabel,\n            icon: buttonIcon,\n            tooltip: true,\n            isToggleable: true\n        });\n        mainButtonView.bind('isOn').to(parentCommand, 'value', (value)=>!!value);\n        dropdownView.once('change:isOpen', ()=>{\n            const listPropertiesView = createListPropertiesView({\n                editor,\n                normalizedConfig,\n                dropdownView,\n                parentCommandName,\n                styleGridAriaLabel,\n                styleDefinitions\n            });\n            dropdownView.panelView.children.add(listPropertiesView);\n        });\n        // Focus the editable after executing the command.\n        // Overrides a default behaviour where the focus is moved to the dropdown button (#12125).\n        dropdownView.on('execute', ()=>{\n            editor.editing.view.focus();\n        });\n        return dropdownView;\n    };\n}\n/**\n * A helper that returns a function (factory) that creates individual buttons used by users to change styles\n * of lists.\n *\n * @param options.editor\n * @param options.listStyleCommand The instance of the `ListStylesCommand` class.\n * @param options.parentCommandName The name of the higher-order command associated with a\n * particular list style (e.g. \"bulletedList\" is associated with \"square\" and \"numberedList\" is associated with \"roman\").\n * @returns A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\n */ function getStyleButtonCreator({ editor, listStyleCommand, parentCommandName }) {\n    const locale = editor.locale;\n    const parentCommand = editor.commands.get(parentCommandName);\n    return ({ label, type, icon, tooltip })=>{\n        const button = new ButtonView(locale);\n        button.set({\n            label,\n            icon,\n            tooltip\n        });\n        listStyleCommand.on('change:value', ()=>{\n            button.isOn = listStyleCommand.value === type;\n        });\n        button.on('execute', ()=>{\n            // If the content the selection is anchored to is a list, let's change its style.\n            if (parentCommand.value) {\n                // Remove the list when the current list style is the same as the one that would normally be applied.\n                if (listStyleCommand.value === type) {\n                    editor.execute(parentCommandName);\n                } else if (listStyleCommand.value !== type) {\n                    editor.execute('listStyle', {\n                        type\n                    });\n                }\n            } else {\n                editor.model.change(()=>{\n                    editor.execute('listStyle', {\n                        type\n                    });\n                });\n            }\n        });\n        return button;\n    };\n}\n/**\n * A helper that creates the properties view for the individual style dropdown.\n *\n * @param options.editor Editor instance.\n * @param options.normalizedConfig List properties configuration.\n * @param options.dropdownView Styles dropdown view that hosts the properties view.\n * @param options.parentCommandName The name of the higher-order editor command associated with\n * the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n * @param options.styleDefinitions Definitions of the style buttons.\n * @param options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n */ function createListPropertiesView({ editor, normalizedConfig, dropdownView, parentCommandName, styleDefinitions, styleGridAriaLabel }) {\n    const locale = editor.locale;\n    const enabledProperties = {\n        ...normalizedConfig,\n        ...parentCommandName != 'numberedList' ? {\n            startIndex: false,\n            reversed: false\n        } : null\n    };\n    const listType = parentCommandName.replace('List', '');\n    let styleButtonViews = null;\n    if (normalizedConfig.styles.listTypes.includes(listType)) {\n        const listStyleCommand = editor.commands.get('listStyle');\n        const styleButtonCreator = getStyleButtonCreator({\n            editor,\n            parentCommandName,\n            listStyleCommand\n        });\n        // The command can be ListStyleCommand or DocumentListStyleCommand.\n        const isStyleTypeSupported = getStyleTypeSupportChecker(listStyleCommand);\n        styleButtonViews = styleDefinitions.filter(isStyleTypeSupported).map(styleButtonCreator);\n    }\n    const listPropertiesView = new ListPropertiesView(locale, {\n        styleGridAriaLabel,\n        enabledProperties,\n        styleButtonViews\n    });\n    if (normalizedConfig.styles.listTypes.includes(listType)) {\n        // Accessibility: focus the first active style when opening the dropdown.\n        focusChildOnDropdownOpen(dropdownView, ()=>{\n            return listPropertiesView.stylesView.children.find((child)=>child.isOn);\n        });\n    }\n    if (enabledProperties.startIndex) {\n        const listStartCommand = editor.commands.get('listStart');\n        listPropertiesView.startIndexFieldView.bind('isEnabled').to(listStartCommand);\n        listPropertiesView.startIndexFieldView.fieldView.bind('value').to(listStartCommand);\n        listPropertiesView.on('listStart', (evt, data)=>editor.execute('listStart', data));\n    }\n    if (enabledProperties.reversed) {\n        const listReversedCommand = editor.commands.get('listReversed');\n        listPropertiesView.reversedSwitchButtonView.bind('isEnabled').to(listReversedCommand);\n        listPropertiesView.reversedSwitchButtonView.bind('isOn').to(listReversedCommand, 'value', (value)=>!!value);\n        listPropertiesView.on('listReversed', ()=>{\n            const isReversed = listReversedCommand.value;\n            editor.execute('listReversed', {\n                reversed: !isReversed\n            });\n        });\n    }\n    // Make sure applying styles closes the dropdown.\n    listPropertiesView.delegate('execute').to(dropdownView);\n    return listPropertiesView;\n}\n/**\n * A helper that creates the list style submenu for menu bar.\n *\n * @param editor Editor instance.\n * @param normalizedConfig List properties configuration.\n * @param parentCommandName Name of the list command.\n * @param buttonLabel Label of the menu button.\n * @param styleGridAriaLabel ARIA label of the styles grid.\n */ function getMenuBarStylesMenuCreator({ editor, normalizedConfig, parentCommandName, buttonLabel, styleGridAriaLabel, styleDefinitions }) {\n    return (locale)=>{\n        const menuView = new MenuBarMenuView(locale);\n        const listCommand = editor.commands.get(parentCommandName);\n        const listStyleCommand = editor.commands.get('listStyle');\n        const isStyleTypeSupported = getStyleTypeSupportChecker(listStyleCommand);\n        const styleButtonCreator = getStyleButtonCreator({\n            editor,\n            parentCommandName,\n            listStyleCommand\n        });\n        const styleButtonViews = styleDefinitions.filter(isStyleTypeSupported).map(styleButtonCreator);\n        const listPropertiesView = new ListPropertiesView(locale, {\n            styleGridAriaLabel,\n            enabledProperties: {\n                ...normalizedConfig,\n                // Disable list start index and reversed in the menu bar.\n                startIndex: false,\n                reversed: false\n            },\n            styleButtonViews\n        });\n        listPropertiesView.delegate('execute').to(menuView);\n        menuView.buttonView.set({\n            label: buttonLabel,\n            icon: icons[parentCommandName]\n        });\n        menuView.panelView.children.add(listPropertiesView);\n        menuView.bind('isEnabled').to(listCommand, 'isEnabled');\n        menuView.on('execute', ()=>{\n            editor.editing.view.focus();\n        });\n        return menuView;\n    };\n}\nfunction getStyleTypeSupportChecker(listStyleCommand) {\n    if (typeof listStyleCommand.isStyleTypeSupported == 'function') {\n        return (styleDefinition)=>listStyleCommand.isStyleTypeSupported(styleDefinition.type);\n    } else {\n        return ()=>true;\n    }\n}\n\n/**\n * The list properties feature.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:list/listproperties/listpropertiesediting~ListPropertiesEditing list properties\n * editing feature} and the {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n */ class ListProperties extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ListPropertiesEditing,\n            ListPropertiesUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'ListProperties';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The check to-do command.\n *\n * The command is registered by the {@link module:list/todolist/todolistediting~TodoListEditing} as\n * the `checkTodoList` editor command.\n */ class CheckTodoListCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        // Refresh command before executing to be sure all values are up to date.\n        // It is needed when selection has changed before command execution, in the same change block.\n        this.on('execute', ()=>{\n            this.refresh();\n        }, {\n            priority: 'highest'\n        });\n    }\n    /**\n\t * Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t */ refresh() {\n        const selectedElements = this._getSelectedItems();\n        this.value = this._getValue(selectedElements);\n        this.isEnabled = !!selectedElements.length;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply\n\t * the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t * value to decide what it should do.\n\t */ execute(options = {}) {\n        this.editor.model.change((writer)=>{\n            const selectedElements = this._getSelectedItems();\n            const value = options.forceValue === undefined ? !this._getValue(selectedElements) : options.forceValue;\n            for (const element of selectedElements){\n                if (value) {\n                    writer.setAttribute('todoListChecked', true, element);\n                } else {\n                    writer.removeAttribute('todoListChecked', element);\n                }\n            }\n        });\n    }\n    /**\n\t * Returns a value for the command.\n\t */ _getValue(selectedElements) {\n        return selectedElements.every((element)=>element.getAttribute('todoListChecked'));\n    }\n    /**\n\t * Gets all to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t */ _getSelectedItems() {\n        const model = this.editor.model;\n        const schema = model.schema;\n        const selectionRange = model.document.selection.getFirstRange();\n        const startElement = selectionRange.start.parent;\n        const elements = [];\n        if (schema.checkAttribute(startElement, 'todoListChecked')) {\n            elements.push(...getAllListItemBlocks(startElement));\n        }\n        for (const item of selectionRange.getItems({\n            shallow: true\n        })){\n            if (schema.checkAttribute(item, 'todoListChecked') && !elements.includes(item)) {\n                elements.push(...getAllListItemBlocks(item));\n            }\n        }\n        return elements;\n    }\n}\n\n/**\n * Observes all to-do list checkboxes state changes.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View} by {@link module:engine/view/view~View#addObserver} method.\n */ class TodoCheckboxChangeObserver extends DomEventObserver {\n    /**\n\t * @inheritDoc\n\t */ domEventType = [\n        'change'\n    ];\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvent) {\n        if (domEvent.target) {\n            const viewTarget = this.view.domConverter.mapDomToView(domEvent.target);\n            if (viewTarget && viewTarget.is('element', 'input') && viewTarget.getAttribute('type') == 'checkbox' && viewTarget.findAncestor({\n                classes: 'todo-list__label'\n            })) {\n                this.fire('todoCheckboxChange', domEvent);\n            }\n        }\n    }\n}\n\nconst ITEM_TOGGLE_KEYSTROKE$1 = /* #__PURE__ */ parseKeystroke('Ctrl+Enter');\n/**\n * The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n *\n * It registers the entire functionality of the {@link module:list/list/listediting~ListEditing list editing plugin}\n * and extends it with the commands:\n *\n * - `'todoList'`,\n * - `'checkTodoList'`,\n */ class TodoListEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TodoListEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ListEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const editing = editor.editing;\n        const listEditing = editor.plugins.get(ListEditing);\n        const multiBlock = editor.config.get('list.multiBlock');\n        const elementName = multiBlock ? 'paragraph' : 'listItem';\n        editor.commands.add('todoList', new ListCommand(editor, 'todo'));\n        editor.commands.add('checkTodoList', new CheckTodoListCommand(editor));\n        editing.view.addObserver(TodoCheckboxChangeObserver);\n        model.schema.extend('$listItem', {\n            allowAttributes: 'todoListChecked'\n        });\n        model.schema.addAttributeCheck((context)=>{\n            const item = context.last;\n            // Don't allow `todoListChecked` attribute on elements which are not todo list items.\n            if (!item.getAttribute('listItemId') || item.getAttribute('listType') != 'todo') {\n                return false;\n            }\n        }, 'todoListChecked');\n        editor.conversion.for('upcast').add((dispatcher)=>{\n            // Upcast of to-do list item is based on a checkbox at the beginning of a <li> to keep compatibility with markdown input.\n            dispatcher.on('element:input', todoItemInputConverter());\n            // Priority is set to low to allow generic list item converter to run first.\n            dispatcher.on('element:li', todoListItemUpcastConverter(), {\n                priority: 'low'\n            });\n            // Consume other elements that are normally generated in data downcast, so they won't get captured by GHS.\n            dispatcher.on('element:label', elementUpcastConsumingConverter({\n                name: 'label',\n                classes: 'todo-list__label'\n            }));\n            dispatcher.on('element:label', elementUpcastConsumingConverter({\n                name: 'label',\n                classes: [\n                    'todo-list__label',\n                    'todo-list__label_without-description'\n                ]\n            }));\n            dispatcher.on('element:span', elementUpcastConsumingConverter({\n                name: 'span',\n                classes: 'todo-list__label__description'\n            }));\n            dispatcher.on('element:ul', attributeUpcastConsumingConverter({\n                name: 'ul',\n                classes: 'todo-list'\n            }));\n        });\n        editor.conversion.for('downcast').elementToElement({\n            model: elementName,\n            view: (element, { writer })=>{\n                if (isDescriptionBlock(element, listEditing.getListAttributeNames())) {\n                    return writer.createContainerElement('span', {\n                        class: 'todo-list__label__description'\n                    });\n                }\n            },\n            converterPriority: 'highest'\n        });\n        listEditing.registerDowncastStrategy({\n            scope: 'list',\n            attributeName: 'listType',\n            setAttributeOnDowncast (writer, value, element) {\n                if (value == 'todo') {\n                    writer.addClass('todo-list', element);\n                } else {\n                    writer.removeClass('todo-list', element);\n                }\n            }\n        });\n        listEditing.registerDowncastStrategy({\n            scope: 'itemMarker',\n            attributeName: 'todoListChecked',\n            createElement (writer, modelElement, { dataPipeline }) {\n                if (modelElement.getAttribute('listType') != 'todo') {\n                    return null;\n                }\n                const viewElement = writer.createUIElement('input', {\n                    type: 'checkbox',\n                    ...modelElement.getAttribute('todoListChecked') ? {\n                        checked: 'checked'\n                    } : null,\n                    ...dataPipeline ? {\n                        disabled: 'disabled'\n                    } : {\n                        tabindex: '-1'\n                    }\n                });\n                if (dataPipeline) {\n                    return viewElement;\n                }\n                const wrapper = writer.createContainerElement('span', {\n                    contenteditable: 'false'\n                }, viewElement);\n                wrapper.getFillerOffset = ()=>null;\n                return wrapper;\n            },\n            canWrapElement (modelElement) {\n                return isDescriptionBlock(modelElement, listEditing.getListAttributeNames());\n            },\n            createWrapperElement (writer, modelElement, { dataPipeline }) {\n                const classes = [\n                    'todo-list__label'\n                ];\n                if (!isDescriptionBlock(modelElement, listEditing.getListAttributeNames())) {\n                    classes.push('todo-list__label_without-description');\n                }\n                return writer.createAttributeElement(dataPipeline ? 'label' : 'span', {\n                    class: classes.join(' ')\n                });\n            }\n        });\n        // Verifies if a to-do list block requires reconversion of a first item downcasted as an item description.\n        listEditing.on('checkElement', (evt, { modelElement, viewElement })=>{\n            const isFirstTodoModelParagraphBlock = isDescriptionBlock(modelElement, listEditing.getListAttributeNames());\n            const hasViewClass = viewElement.hasClass('todo-list__label__description');\n            if (hasViewClass != isFirstTodoModelParagraphBlock) {\n                evt.return = true;\n                evt.stop();\n            }\n        });\n        // Verifies if a to-do list block requires reconversion of a checkbox element\n        // (for example there is a new paragraph inserted as a first block of a list item).\n        listEditing.on('checkElement', (evt, { modelElement, viewElement })=>{\n            const isFirstTodoModelItemBlock = modelElement.getAttribute('listType') == 'todo' && isFirstBlockOfListItem(modelElement);\n            let hasViewItemMarker = false;\n            const viewWalker = editor.editing.view.createPositionBefore(viewElement).getWalker({\n                direction: 'backward'\n            });\n            for (const { item } of viewWalker){\n                if (item.is('element') && editor.editing.mapper.toModelElement(item)) {\n                    break;\n                }\n                if (item.is('element', 'input') && item.getAttribute('type') == 'checkbox') {\n                    hasViewItemMarker = true;\n                }\n            }\n            if (hasViewItemMarker != isFirstTodoModelItemBlock) {\n                evt.return = true;\n                evt.stop();\n            }\n        });\n        // Make sure that all blocks of the same list item have the same todoListChecked attribute.\n        listEditing.on('postFixer', (evt, { listNodes, writer })=>{\n            for (const { node, previousNodeInList } of listNodes){\n                // This is a first item of a nested list.\n                if (!previousNodeInList) {\n                    continue;\n                }\n                if (previousNodeInList.getAttribute('listItemId') != node.getAttribute('listItemId')) {\n                    continue;\n                }\n                const previousHasAttribute = previousNodeInList.hasAttribute('todoListChecked');\n                const nodeHasAttribute = node.hasAttribute('todoListChecked');\n                if (nodeHasAttribute && !previousHasAttribute) {\n                    writer.removeAttribute('todoListChecked', node);\n                    evt.return = true;\n                } else if (!nodeHasAttribute && previousHasAttribute) {\n                    writer.setAttribute('todoListChecked', true, node);\n                    evt.return = true;\n                }\n            }\n        });\n        // Make sure that todoListChecked attribute is only present for to-do list items.\n        model.document.registerPostFixer((writer)=>{\n            const changes = model.document.differ.getChanges();\n            let wasFixed = false;\n            for (const change of changes){\n                if (change.type == 'attribute' && change.attributeKey == 'listType') {\n                    const element = change.range.start.nodeAfter;\n                    if (change.attributeOldValue == 'todo' && element.hasAttribute('todoListChecked')) {\n                        writer.removeAttribute('todoListChecked', element);\n                        wasFixed = true;\n                    }\n                } else if (change.type == 'insert' && change.name != '$text') {\n                    for (const { item } of writer.createRangeOn(change.position.nodeAfter)){\n                        if (item.is('element') && item.getAttribute('listType') != 'todo' && item.hasAttribute('todoListChecked')) {\n                            writer.removeAttribute('todoListChecked', item);\n                            wasFixed = true;\n                        }\n                    }\n                }\n            }\n            return wasFixed;\n        });\n        // Toggle check state of selected to-do list items on keystroke.\n        this.listenTo(editing.view.document, 'keydown', (evt, data)=>{\n            if (getCode(data) === ITEM_TOGGLE_KEYSTROKE$1) {\n                editor.execute('checkTodoList');\n                evt.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n        // Toggle check state of a to-do list item clicked on the checkbox.\n        this.listenTo(editing.view.document, 'todoCheckboxChange', (evt, data)=>{\n            const viewTarget = data.target;\n            if (!viewTarget || !viewTarget.is('element', 'input')) {\n                return;\n            }\n            const viewPositionAfter = editing.view.createPositionAfter(viewTarget);\n            const modelPositionAfter = editing.mapper.toModelPosition(viewPositionAfter);\n            const modelElement = modelPositionAfter.parent;\n            if (modelElement && isListItemBlock(modelElement) && modelElement.getAttribute('listType') == 'todo') {\n                this._handleCheckmarkChange(modelElement);\n            }\n        });\n        // Jump at the start/end of the next node on right arrow key press, when selection is before the checkbox.\n        //\n        // <blockquote><p>Foo{}</p></blockquote>\n        // <ul><li><checkbox/>Bar</li></ul>\n        //\n        // press: `->`\n        //\n        // <blockquote><p>Foo</p></blockquote>\n        // <ul><li><checkbox/>{}Bar</li></ul>\n        //\n        this.listenTo(editing.view.document, 'arrowKey', jumpOverCheckmarkOnSideArrowKeyPress$1(model, editor.locale), {\n            context: '$text'\n        });\n        // Map view positions inside the checkbox and wrappers to the position in the first block of the list item.\n        this.listenTo(editing.mapper, 'viewToModelPosition', (evt, data)=>{\n            const viewParent = data.viewPosition.parent;\n            const isStartOfListItem = viewParent.is('attributeElement', 'li') && data.viewPosition.offset == 0;\n            const isStartOfListLabel = isLabelElement(viewParent) && data.viewPosition.offset <= 1;\n            const isInInputWrapper = viewParent.is('element', 'span') && viewParent.getAttribute('contenteditable') == 'false' && isLabelElement(viewParent.parent);\n            if (!isStartOfListItem && !isStartOfListLabel && !isInInputWrapper) {\n                return;\n            }\n            const nodeAfter = data.modelPosition.nodeAfter;\n            if (nodeAfter && nodeAfter.getAttribute('listType') == 'todo') {\n                data.modelPosition = model.createPositionAt(nodeAfter, 0);\n            }\n        }, {\n            priority: 'low'\n        });\n        this._initAriaAnnouncements();\n    }\n    /**\n\t * Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t * to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t *\n\t * Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t * is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t * See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t */ _handleCheckmarkChange(listItem) {\n        const editor = this.editor;\n        const model = editor.model;\n        const previousSelectionRanges = Array.from(model.document.selection.getRanges());\n        model.change((writer)=>{\n            writer.setSelection(listItem, 'end');\n            editor.execute('checkTodoList');\n            writer.setSelection(previousSelectionRanges);\n        });\n    }\n    /**\n\t * Observe when user enters or leaves todo list and set proper aria value in global live announcer.\n\t * This allows screen readers to indicate when the user has entered and left the specified todo list.\n\t *\n\t * @internal\n\t */ _initAriaAnnouncements() {\n        const { model, ui, t } = this.editor;\n        let lastFocusedCodeBlock = null;\n        if (!ui) {\n            return;\n        }\n        model.document.selection.on('change:range', ()=>{\n            const focusParent = model.document.selection.focus.parent;\n            const lastElementIsTodoList = isTodoListItemElement(lastFocusedCodeBlock);\n            const currentElementIsTodoList = isTodoListItemElement(focusParent);\n            if (lastElementIsTodoList && !currentElementIsTodoList) {\n                ui.ariaLiveAnnouncer.announce(t('Leaving a to-do list'));\n            } else if (!lastElementIsTodoList && currentElementIsTodoList) {\n                ui.ariaLiveAnnouncer.announce(t('Entering a to-do list'));\n            }\n            lastFocusedCodeBlock = focusParent;\n        });\n    }\n}\n/**\n * Returns an upcast converter for to-do list items.\n */ function todoListItemUpcastConverter() {\n    return (evt, data, conversionApi)=>{\n        const { writer, schema } = conversionApi;\n        if (!data.modelRange) {\n            return;\n        }\n        // Group to-do list items by their listItemId attribute to ensure that all items of the same list item have the same checked state.\n        const groupedItems = Array.from(data.modelRange.getItems({\n            shallow: true\n        })).filter((item)=>item.getAttribute('listType') === 'todo' && schema.checkAttribute(item, 'listItemId')).reduce((acc, item)=>{\n            const listItemId = item.getAttribute('listItemId');\n            if (!acc.has(listItemId)) {\n                acc.set(listItemId, getAllListItemBlocks(item));\n            }\n            return acc;\n        }, new Map());\n        // During the upcast, we need to ensure that all items of the same list have the same checked state. From time to time\n        // the checked state of the items can be different when the user pastes content from the clipboard with <input type=\"checkbox\">\n        // that has checked state set to true. In such cases, we need to ensure that all items of the same list have the same checked state.\n        // See more: https://github.com/ckeditor/ckeditor5/issues/15602\n        for (const [, items] of groupedItems.entries()){\n            if (items.some((item)=>item.getAttribute('todoListChecked'))) {\n                for (const item of items){\n                    writer.setAttribute('todoListChecked', true, item);\n                }\n            }\n        }\n    };\n}\n/**\n * Returns an upcast converter that detects a to-do list checkbox and marks the list item as a to-do list.\n */ function todoItemInputConverter() {\n    return (evt, data, conversionApi)=>{\n        const modelCursor = data.modelCursor;\n        const modelItem = modelCursor.parent;\n        const viewItem = data.viewItem;\n        if (!conversionApi.consumable.test(viewItem, {\n            name: true\n        })) {\n            return;\n        }\n        if (viewItem.getAttribute('type') != 'checkbox' || !modelCursor.isAtStart || !modelItem.hasAttribute('listType')) {\n            return;\n        }\n        conversionApi.consumable.consume(viewItem, {\n            name: true\n        });\n        const writer = conversionApi.writer;\n        writer.setAttribute('listType', 'todo', modelItem);\n        if (data.viewItem.hasAttribute('checked')) {\n            writer.setAttribute('todoListChecked', true, modelItem);\n        }\n        data.modelRange = writer.createRange(modelCursor);\n    };\n}\n/**\n * Returns an upcast converter that consumes element matching the given matcher pattern.\n */ function elementUpcastConsumingConverter(matcherPattern) {\n    const matcher = new Matcher(matcherPattern);\n    return (evt, data, conversionApi)=>{\n        const matcherResult = matcher.match(data.viewItem);\n        if (!matcherResult) {\n            return;\n        }\n        if (!conversionApi.consumable.consume(data.viewItem, matcherResult.match)) {\n            return;\n        }\n        Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n    };\n}\n/**\n * Returns an upcast converter that consumes attributes matching the given matcher pattern.\n */ function attributeUpcastConsumingConverter(matcherPattern) {\n    const matcher = new Matcher(matcherPattern);\n    return (evt, data, conversionApi)=>{\n        const matcherResult = matcher.match(data.viewItem);\n        if (!matcherResult) {\n            return;\n        }\n        const match = matcherResult.match;\n        match.name = false;\n        conversionApi.consumable.consume(data.viewItem, match);\n    };\n}\n/**\n * Returns true if the given list item block should be converted as a description block of a to-do list item.\n */ function isDescriptionBlock(modelElement, listAttributeNames) {\n    return (modelElement.is('element', 'paragraph') || modelElement.is('element', 'listItem')) && modelElement.getAttribute('listType') == 'todo' && isFirstBlockOfListItem(modelElement) && hasOnlyListAttributes(modelElement, listAttributeNames);\n}\n/**\n * Returns true if only attributes from the given list are present on the model element.\n */ function hasOnlyListAttributes(modelElement, attributeNames) {\n    for (const attributeKey of modelElement.getAttributeKeys()){\n        // Ignore selection attributes stored on block elements.\n        if (attributeKey.startsWith('selection:')) {\n            continue;\n        }\n        if (!attributeNames.includes(attributeKey)) {\n            return false;\n        }\n    }\n    return true;\n}\n/**\n * Jump at the start and end of a to-do list item.\n */ function jumpOverCheckmarkOnSideArrowKeyPress$1(model, locale) {\n    return (eventInfo, domEventData)=>{\n        const direction = getLocalizedArrowKeyCodeDirection(domEventData.keyCode, locale.contentLanguageDirection);\n        const schema = model.schema;\n        const selection = model.document.selection;\n        if (!selection.isCollapsed) {\n            return;\n        }\n        const position = selection.getFirstPosition();\n        const parent = position.parent;\n        // Right arrow before a to-do list item.\n        if (direction == 'right' && position.isAtEnd) {\n            const newRange = schema.getNearestSelectionRange(model.createPositionAfter(parent), 'forward');\n            if (!newRange) {\n                return;\n            }\n            const newRangeParent = newRange.start.parent;\n            if (newRangeParent && isListItemBlock(newRangeParent) && newRangeParent.getAttribute('listType') == 'todo') {\n                model.change((writer)=>writer.setSelection(newRange));\n                domEventData.preventDefault();\n                domEventData.stopPropagation();\n                eventInfo.stop();\n            }\n        } else if (direction == 'left' && position.isAtStart && isListItemBlock(parent) && parent.getAttribute('listType') == 'todo') {\n            const newRange = schema.getNearestSelectionRange(model.createPositionBefore(parent), 'backward');\n            if (!newRange) {\n                return;\n            }\n            model.change((writer)=>writer.setSelection(newRange));\n            domEventData.preventDefault();\n            domEventData.stopPropagation();\n            eventInfo.stop();\n        }\n    };\n}\n/**\n * Returns true if the given element is a label element of a to-do list item.\n */ function isLabelElement(viewElement) {\n    return !!viewElement && viewElement.is('attributeElement') && viewElement.hasClass('todo-list__label');\n}\n/**\n * Returns true if the given element is a list item model element of a to-do list.\n */ function isTodoListItemElement(element) {\n    if (!element) {\n        return false;\n    }\n    if (!element.is('element', 'paragraph') && !element.is('element', 'listItem')) {\n        return false;\n    }\n    return element.getAttribute('listType') == 'todo';\n}\n\n/**\n * The to-do list UI feature. It introduces the `'todoList'` button that\n * allows to convert elements to and from to-do list items and to indent or outdent them.\n */ class TodoListUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TodoListUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const t = this.editor.t;\n        createUIComponents(this.editor, 'todoList', t('To-do List'), icons.todoList);\n    }\n}\n\n/**\n * The to-do list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/todolist/todolistediting~TodoListEditing to-do list\n * editing feature} and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n */ class TodoList extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TodoListEditing,\n            TodoListUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TodoList';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The list command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.\n */ class LegacyListCommand extends Command {\n    /**\n\t * The type of the list created by the command.\n\t */ type;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param type List type that will be handled by this command.\n\t */ constructor(editor, type){\n        super(editor);\n        this.type = type;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.value = this._getValue();\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false`, it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const document = model.document;\n        const blocks = Array.from(document.selection.getSelectedBlocks()).filter((block)=>checkCanBecomeListItem(block, model.schema));\n        // Whether we are turning off some items.\n        const turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n        // If we are turning off items, we are going to rename them to paragraphs.\n        model.change((writer)=>{\n            // If part of a list got turned off, we need to handle (outdent) all of sub-items of the last turned-off item.\n            // To be sure that model is all the time in a good state, we first fix items below turned-off item.\n            if (turnOff) {\n                // Start from the model item that is just after the last turned-off item.\n                let next = blocks[blocks.length - 1].nextSibling;\n                let currentIndent = Number.POSITIVE_INFINITY;\n                let changes = [];\n                // Correct indent of all items after the last turned off item.\n                // Rules that should be followed:\n                // 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n                //    will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n                // 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n                //    should not end up as a child of any of list items that they were not children of before.\n                // 3. All other items should have their indent changed relatively to it's parent.\n                //\n                // For example:\n                // 1  * --------\n                // 2     * --------\n                // 3        * --------\t\t\t<-- this is turned off.\n                // 4           * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n                // 5              * --------\t<-- this should be still be a child of item above, so indent = 1.\n                // 6        * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n                // 7           * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n                // 8     * --------\t\t\t\t<-- this has to become indent = 0.\n                // 9        * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n                // 10          * --------\t\t<-- this should still be a child of item above, so indent = 2.\n                // 11          * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n                // 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n                // 13    * --------\n                // 14       * --------\n                //\n                // After turning off 3 the list becomes:\n                //\n                // 1  * --------\n                // 2     * --------\n                //\n                // 3  --------\n                //\n                // 4  * --------\n                // 5     * --------\n                // 6  * --------\n                // 7     * --------\n                // 8  * --------\n                // 9     * --------\n                // 10       * --------\n                // 11       * --------\n                // 12 * --------\n                // 13    * --------\n                // 14       * --------\n                //\n                // Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n                // those parent-child connection which are possible to maintain are still maintained. It's worth noting\n                // that this is the same effect that we would be get by multiple use of outdent command. However doing\n                // it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n                // less conversion (faster).\n                while(next && next.name == 'listItem' && next.getAttribute('listIndent') !== 0){\n                    // Check each next list item, as long as its indent is bigger than 0.\n                    // If the indent is 0 we are not going to change anything anyway.\n                    const indent = next.getAttribute('listIndent');\n                    // We check if that's item indent is lower as current relative indent.\n                    if (indent < currentIndent) {\n                        // If it is, current relative indent becomes that indent.\n                        currentIndent = indent;\n                    }\n                    // Fix indent relatively to current relative indent.\n                    // Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n                    const newIndent = indent - currentIndent;\n                    // Save the entry in changes array. We do not apply it at the moment, because we will need to\n                    // reverse the changes so the last item is changed first.\n                    // This is to keep model in correct state all the time.\n                    changes.push({\n                        element: next,\n                        listIndent: newIndent\n                    });\n                    // Find next item.\n                    next = next.nextSibling;\n                }\n                changes = changes.reverse();\n                for (const item of changes){\n                    writer.setAttribute('listIndent', item.listIndent, item.element);\n                }\n            }\n            // If we are turning on, we might change some items that are already `listItem`s but with different type.\n            // Changing one nested list item to other type should also trigger changing all its siblings so the\n            // whole nested list is of the same type.\n            // Example (assume changing to numbered list):\n            // * ------\t\t\t\t<-- do not fix, top level item\n            //   * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n            //      * ------\t\t<-- do not fix, item is not affected (different list)\n            //   * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n            //      * ------\t\t<-- fix, because latter list item of this item's list is changed\n            //      * ---[--\t\t<-- already in selection\n            //   * ------\t\t\t<-- already in selection\n            //   * ------\t\t\t<-- already in selection\n            // * ------\t\t\t\t<-- already in selection, but does not cause other list items to change because is top-level\n            //   * ---]--\t\t\t<-- already in selection\n            //   * ------\t\t\t<-- fix, because preceding list item of this item's list is changed\n            //      * ------\t\t<-- do not fix, item is not affected (different list)\n            // * ------\t\t\t\t<-- do not fix, top level item\n            if (!turnOff) {\n                // Find lowest indent among selected items. This will be indicator what is the indent of\n                // top-most list affected by the command.\n                let lowestIndent = Number.POSITIVE_INFINITY;\n                for (const item of blocks){\n                    if (item.is('element', 'listItem') && item.getAttribute('listIndent') < lowestIndent) {\n                        lowestIndent = item.getAttribute('listIndent');\n                    }\n                }\n                // Do not execute the fix for top-level lists.\n                lowestIndent = lowestIndent === 0 ? 1 : lowestIndent;\n                // Fix types of list items that are \"before\" the selected blocks.\n                _fixType(blocks, true, lowestIndent);\n                // Fix types of list items that are \"after\" the selected blocks.\n                _fixType(blocks, false, lowestIndent);\n            }\n            // Phew! Now it will be easier :).\n            // For each block element that was in the selection, we will either: turn it to list item,\n            // turn it to paragraph, or change it's type. Or leave it as it is.\n            // Do it in reverse as there might be multiple blocks (same as with changing indents).\n            for (const element of blocks.reverse()){\n                if (turnOff && element.name == 'listItem') {\n                    // We are turning off and the element is a `listItem` - it should be converted to `paragraph`.\n                    // List item specific attributes are removed by post fixer.\n                    writer.rename(element, 'paragraph');\n                } else if (!turnOff && element.name != 'listItem') {\n                    // We are turning on and the element is not a `listItem` - it should be converted to `listItem`.\n                    // The order of operations is important to keep model in correct state.\n                    writer.setAttributes({\n                        listType: this.type,\n                        listIndent: 0\n                    }, element);\n                    writer.rename(element, 'listItem');\n                } else if (!turnOff && element.name == 'listItem' && element.getAttribute('listType') != this.type) {\n                    // We are turning on and the element is a `listItem` but has different type - change it's type and\n                    // type of it's all siblings that have same indent.\n                    writer.setAttribute('listType', this.type, element);\n                }\n            }\n            /**\n\t\t\t * Event fired by the {@link #execute} method.\n\t\t\t *\n\t\t\t * It allows to execute an action after executing the {@link ~ListCommand#execute} method, for example adjusting\n\t\t\t * attributes of changed blocks.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event _executeCleanup\n\t\t\t */ this.fire('_executeCleanup', blocks);\n        });\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */ _getValue() {\n        // Check whether closest `listItem` ancestor of the position has a correct type.\n        const listItem = first(this.editor.model.document.selection.getSelectedBlocks());\n        return !!listItem && listItem.is('element', 'listItem') && listItem.getAttribute('listType') == this.type;\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        // If command value is true it means that we are in list item, so the command should be enabled.\n        if (this.value) {\n            return true;\n        }\n        const selection = this.editor.model.document.selection;\n        const schema = this.editor.model.schema;\n        const firstBlock = first(selection.getSelectedBlocks());\n        if (!firstBlock) {\n            return false;\n        }\n        // Otherwise, check if list item can be inserted at the position start.\n        return checkCanBecomeListItem(firstBlock, schema);\n    }\n}\n/**\n * Helper function used when one or more list item have their type changed. Fixes type of other list items\n * that are affected by the change (are in same lists) but are not directly in selection. The function got extracted\n * not to duplicated code, as same fix has to be performed before and after selection.\n *\n * @param blocks Blocks that are in selection.\n * @param isBackward Specified whether fix will be applied for blocks before first selected block (`true`)\n * or blocks after last selected block (`false`).\n * @param lowestIndent Lowest indent among selected blocks.\n */ function _fixType(blocks, isBackward, lowestIndent) {\n    // We need to check previous sibling of first changed item and next siblings of last changed item.\n    const startingItem = isBackward ? blocks[0] : blocks[blocks.length - 1];\n    if (startingItem.is('element', 'listItem')) {\n        let item = startingItem[isBackward ? 'previousSibling' : 'nextSibling'];\n        // During processing items, keeps the lowest indent of already processed items.\n        // This saves us from changing too many items.\n        // Following example is for going forward as it is easier to read, however same applies to going backward.\n        // * ------\n        //   * ------\n        //     * --[---\n        //   * ------\t\t<-- `lowestIndent` should be 1\n        //     * --]---\t\t<-- `startingItem`, `currentIndent` = 2, `lowestIndent` == 1\n        //     * ------\t\t<-- should be fixed, `indent` == 2 == `currentIndent`\n        //   * ------\t\t<-- should be fixed, set `currentIndent` to 1, `indent` == 1 == `currentIndent`\n        //     * ------\t\t<-- should not be fixed, item is in different list, `indent` = 2, `indent` != `currentIndent`\n        //   * ------\t\t<-- should be fixed, `indent` == 1 == `currentIndent`\n        // * ------\t\t\t<-- break loop (`indent` < `lowestIndent`)\n        let currentIndent = startingItem.getAttribute('listIndent');\n        // Look back until a list item with indent lower than reference `lowestIndent`.\n        // That would be the parent of nested sublist which contains item having `lowestIndent`.\n        while(item && item.is('element', 'listItem') && item.getAttribute('listIndent') >= lowestIndent){\n            if (currentIndent > item.getAttribute('listIndent')) {\n                currentIndent = item.getAttribute('listIndent');\n            }\n            // Found an item that is in the same nested sublist.\n            if (item.getAttribute('listIndent') == currentIndent) {\n                // Just add the item to selected blocks like it was selected by the user.\n                blocks[isBackward ? 'unshift' : 'push'](item);\n            }\n            item = item[isBackward ? 'previousSibling' : 'nextSibling'];\n        }\n    }\n}\n/**\n * Checks whether the given block can be replaced by a listItem.\n *\n * @param block A block to be tested.\n * @param schema The schema of the document.\n */ function checkCanBecomeListItem(block, schema) {\n    return schema.checkChild(block.parent, 'listItem') && !schema.isObject(block);\n}\n\n/**\n * The list indent command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.\n */ class LegacyIndentCommand extends Command {\n    /**\n\t * Determines by how much the command will change the list item's indent attribute.\n\t */ _indentBy;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param indentDirection The direction of indent. If it is equal to `backward`, the command will outdent a list item.\n\t */ constructor(editor, indentDirection){\n        super(editor);\n        this._indentBy = indentDirection == 'forward' ? 1 : -1;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t */ execute() {\n        const model = this.editor.model;\n        const doc = model.document;\n        let itemsToChange = Array.from(doc.selection.getSelectedBlocks());\n        model.change((writer)=>{\n            const lastItem = itemsToChange[itemsToChange.length - 1];\n            // Indenting a list item should also indent all the items that are already sub-items of indented item.\n            let next = lastItem.nextSibling;\n            // Check all items after last indented item, as long as their indent is bigger than indent of that item.\n            while(next && next.name == 'listItem' && next.getAttribute('listIndent') > lastItem.getAttribute('listIndent')){\n                itemsToChange.push(next);\n                next = next.nextSibling;\n            }\n            // We need to be sure to keep model in correct state after each small change, because converters\n            // bases on that state and assumes that model is correct.\n            // Because of that, if the command outdents items, we will outdent them starting from the last item, as\n            // it is safer.\n            if (this._indentBy < 0) {\n                itemsToChange = itemsToChange.reverse();\n            }\n            for (const item of itemsToChange){\n                const indent = item.getAttribute('listIndent') + this._indentBy;\n                // If indent is lower than 0, it means that the item got outdented when it was not indented.\n                // This means that we need to convert that list item to paragraph.\n                if (indent < 0) {\n                    // To keep the model as correct as possible, first rename listItem, then remove attributes,\n                    // as listItem without attributes is very incorrect and will cause problems in converters.\n                    // No need to remove attributes, will be removed by post fixer.\n                    writer.rename(item, 'paragraph');\n                } else {\n                    writer.setAttribute('listIndent', indent, item);\n                }\n            }\n            // It allows to execute an action after executing the `~IndentCommand#execute` method, for example adjusting\n            // attributes of changed list items.\n            this.fire('_executeCleanup', itemsToChange);\n        });\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        // Check whether any of position's ancestor is a list item.\n        const listItem = first(this.editor.model.document.selection.getSelectedBlocks());\n        // If selection is not in a list item, the command is disabled.\n        if (!listItem || !listItem.is('element', 'listItem')) {\n            return false;\n        }\n        if (this._indentBy > 0) {\n            // Cannot indent first item in it's list. Check if before `listItem` is a list item that is in same list.\n            // To be in the same list, the item has to have same attributes and cannot be \"split\" by an item with lower indent.\n            const indent = listItem.getAttribute('listIndent');\n            const type = listItem.getAttribute('listType');\n            let prev = listItem.previousSibling;\n            while(prev && prev.is('element', 'listItem') && prev.getAttribute('listIndent') >= indent){\n                if (prev.getAttribute('listIndent') == indent) {\n                    // The item is on the same level.\n                    // If it has same type, it means that we found a preceding sibling from the same list.\n                    // If it does not have same type, it means that `listItem` is on different list (this can happen only\n                    // on top level lists, though).\n                    return prev.getAttribute('listType') == type;\n                }\n                prev = prev.previousSibling;\n            }\n            // Could not find similar list item, this means that `listItem` is first in its list.\n            return false;\n        }\n        // If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n        return true;\n    }\n}\n\n/**\n * Creates a list item {@link module:engine/view/containerelement~ContainerElement}.\n *\n * @param writer The writer instance.\n */ function createViewListItemElement(writer) {\n    const viewItem = writer.createContainerElement('li');\n    viewItem.getFillerOffset = getListItemFillerOffset;\n    return viewItem;\n}\n/**\n * Helper function that creates a `<ul><li></li></ul>` or (`<ol>`) structure out of the given `modelItem` model `listItem` element.\n * Then, it binds the created view list item (`<li>`) with the model `listItem` element.\n * The function then returns the created view list item (`<li>`).\n *\n * @param modelItem Model list item.\n * @param conversionApi Conversion interface.\n * @returns View list element.\n */ function generateLiInUl(modelItem, conversionApi) {\n    const mapper = conversionApi.mapper;\n    const viewWriter = conversionApi.writer;\n    const listType = modelItem.getAttribute('listType') == 'numbered' ? 'ol' : 'ul';\n    const viewItem = createViewListItemElement(viewWriter);\n    const viewList = viewWriter.createContainerElement(listType, null);\n    viewWriter.insert(viewWriter.createPositionAt(viewList, 0), viewItem);\n    mapper.bindElements(modelItem, viewItem);\n    return viewItem;\n}\n/**\n * Helper function that inserts a view list at a correct place and merges it with its siblings.\n * It takes a model list item element (`modelItem`) and a corresponding view list item element (`injectedItem`). The view list item\n * should be in a view list element (`<ul>` or `<ol>`) and should be its only child.\n * See comments below to better understand the algorithm.\n *\n * @param modelItem Model list item.\n * @param injectedItem\n * @param conversionApi Conversion interface.\n * @param model The model instance.\n */ function injectViewList(modelItem, injectedItem, conversionApi, model) {\n    const injectedList = injectedItem.parent;\n    const mapper = conversionApi.mapper;\n    const viewWriter = conversionApi.writer;\n    // The position where the view list will be inserted.\n    let insertPosition = mapper.toViewPosition(model.createPositionBefore(modelItem));\n    // 1. Find the previous list item that has the same or smaller indent. Basically we are looking for the first model item\n    // that is a \"parent\" or \"sibling\" of the injected model item.\n    // If there is no such list item, it means that the injected list item is the first item in \"its list\".\n    const refItem = getSiblingListItem(modelItem.previousSibling, {\n        sameIndent: true,\n        smallerIndent: true,\n        listIndent: modelItem.getAttribute('listIndent')\n    });\n    const prevItem = modelItem.previousSibling;\n    if (refItem && refItem.getAttribute('listIndent') == modelItem.getAttribute('listIndent')) {\n        // There is a list item with the same indent - we found the same-level sibling.\n        // Break the list after it. The inserted view item will be added in the broken space.\n        const viewItem = mapper.toViewElement(refItem);\n        insertPosition = viewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n    } else {\n        // There is no list item with the same indent. Check the previous model item.\n        if (prevItem && prevItem.name == 'listItem') {\n            // If it is a list item, it has to have a lower indent.\n            // It means that the inserted item should be added to it as its nested item.\n            insertPosition = mapper.toViewPosition(model.createPositionAt(prevItem, 'end'));\n            // There could be some not mapped elements (eg. span in to-do list) but we need to insert\n            // a nested list directly inside the li element.\n            const mappedViewAncestor = mapper.findMappedViewAncestor(insertPosition);\n            const nestedList = findNestedList(mappedViewAncestor);\n            // If there already is some nested list, then use it's position.\n            if (nestedList) {\n                insertPosition = viewWriter.createPositionBefore(nestedList);\n            } else {\n                // Else just put new list on the end of list item content.\n                insertPosition = viewWriter.createPositionAt(mappedViewAncestor, 'end');\n            }\n        } else {\n            // The previous item is not a list item (or does not exist at all).\n            // Just map the position and insert the view item at the mapped position.\n            insertPosition = mapper.toViewPosition(model.createPositionBefore(modelItem));\n        }\n    }\n    insertPosition = positionAfterUiElements(insertPosition);\n    // Insert the view item.\n    viewWriter.insert(insertPosition, injectedList);\n    // 2. Handle possible children of the injected model item.\n    if (prevItem && prevItem.name == 'listItem') {\n        const prevView = mapper.toViewElement(prevItem);\n        const walkerBoundaries = viewWriter.createRange(viewWriter.createPositionAt(prevView, 0), insertPosition);\n        const walker = walkerBoundaries.getWalker({\n            ignoreElementEnd: true\n        });\n        for (const value of walker){\n            if (value.item.is('element', 'li')) {\n                const breakPosition = viewWriter.breakContainer(viewWriter.createPositionBefore(value.item));\n                const viewList = value.item.parent;\n                const targetPosition = viewWriter.createPositionAt(injectedItem, 'end');\n                mergeViewLists(viewWriter, targetPosition.nodeBefore, targetPosition.nodeAfter);\n                viewWriter.move(viewWriter.createRangeOn(viewList), targetPosition);\n                // This is bad, but those lists will be removed soon anyway.\n                walker._position = breakPosition;\n            }\n        }\n    } else {\n        const nextViewList = injectedList.nextSibling;\n        if (nextViewList && (nextViewList.is('element', 'ul') || nextViewList.is('element', 'ol'))) {\n            let lastSubChild = null;\n            for (const child of nextViewList.getChildren()){\n                const modelChild = mapper.toModelElement(child);\n                if (modelChild && modelChild.getAttribute('listIndent') > modelItem.getAttribute('listIndent')) {\n                    lastSubChild = child;\n                } else {\n                    break;\n                }\n            }\n            if (lastSubChild) {\n                viewWriter.breakContainer(viewWriter.createPositionAfter(lastSubChild));\n                viewWriter.move(viewWriter.createRangeOn(lastSubChild.parent), viewWriter.createPositionAt(injectedItem, 'end'));\n            }\n        }\n    }\n    // Merge the inserted view list with its possible neighbor lists.\n    mergeViewLists(viewWriter, injectedList, injectedList.nextSibling);\n    mergeViewLists(viewWriter, injectedList.previousSibling, injectedList);\n}\nfunction mergeViewLists(viewWriter, firstList, secondList) {\n    // Check if two lists are going to be merged.\n    if (!firstList || !secondList || firstList.name != 'ul' && firstList.name != 'ol') {\n        return null;\n    }\n    // Both parameters are list elements, so compare types now.\n    if (firstList.name != secondList.name || firstList.getAttribute('class') !== secondList.getAttribute('class')) {\n        return null;\n    }\n    return viewWriter.mergeContainers(viewWriter.createPositionAfter(firstList));\n}\n/**\n * Helper function that for a given `view.Position`, returns a `view.Position` that is after all `view.UIElement`s that\n * are after the given position.\n *\n * For example:\n * `<container:p>foo^<ui:span></ui:span><ui:span></ui:span>bar</container:p>`\n * For position ^, the position before \"bar\" will be returned.\n *\n */ function positionAfterUiElements(viewPosition) {\n    return viewPosition.getLastMatchingPosition((value)=>value.item.is('uiElement'));\n}\n/**\n * Helper function that searches for a previous list item sibling of a given model item that meets the given criteria\n * passed by the options object.\n *\n * @param options Search criteria.\n * @param options.sameIndent Whether the sought sibling should have the same indentation.\n * @param options.smallerIndent Whether the sought sibling should have a smaller indentation.\n * @param options.listIndent The reference indentation.\n * @param options.direction Walking direction.\n */ function getSiblingListItem(modelItem, options) {\n    const sameIndent = !!options.sameIndent;\n    const smallerIndent = !!options.smallerIndent;\n    const indent = options.listIndent;\n    let item = modelItem;\n    while(item && item.name == 'listItem'){\n        const itemIndent = item.getAttribute('listIndent');\n        if (sameIndent && indent == itemIndent || smallerIndent && indent > itemIndent) {\n            return item;\n        }\n        if (options.direction === 'forward') {\n            item = item.nextSibling;\n        } else {\n            item = item.previousSibling;\n        }\n    }\n    return null;\n}\n/**\n * Returns a first list view element that is direct child of the given view element.\n */ function findNestedList(viewElement) {\n    for (const node of viewElement.getChildren()){\n        if (node.name == 'ul' || node.name == 'ol') {\n            return node;\n        }\n    }\n    return null;\n}\n/**\n * Returns an array with all `listItem` elements that represent the same list.\n *\n * It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n *\n * Additionally, if the `position` is inside a list item, that list item will be returned as well.\n *\n * @param position Starting position.\n * @param direction Walking direction.\n */ function getSiblingNodes(position, direction) {\n    const items = [];\n    const listItem = position.parent;\n    const walkerOptions = {\n        ignoreElementEnd: false,\n        startPosition: position,\n        shallow: true,\n        direction\n    };\n    const limitIndent = listItem.getAttribute('listIndent');\n    const nodes = [\n        ...new TreeWalker(walkerOptions)\n    ].filter((value)=>value.item.is('element')).map((value)=>value.item);\n    for (const element of nodes){\n        // If found something else than `listItem`, we're out of the list scope.\n        if (!element.is('element', 'listItem')) {\n            break;\n        }\n        // If current parsed item has lower indent that element that the element that was a starting point,\n        // it means we left a nested list. Abort searching items.\n        //\n        // ■ List item 1.       [listIndent=0]\n        //     ○ List item 2.[] [listIndent=1], limitIndent = 1,\n        //     ○ List item 3.   [listIndent=1]\n        // ■ List item 4.       [listIndent=0]\n        //\n        // Abort searching when leave nested list.\n        if (element.getAttribute('listIndent') < limitIndent) {\n            break;\n        }\n        // ■ List item 1.[]     [listIndent=0] limitIndent = 0,\n        //     ○ List item 2.   [listIndent=1]\n        //     ○ List item 3.   [listIndent=1]\n        // ■ List item 4.       [listIndent=0]\n        //\n        // Ignore nested lists.\n        if (element.getAttribute('listIndent') > limitIndent) {\n            continue;\n        }\n        // ■ List item 1.[]  [listType=bulleted]\n        // 1. List item 2.   [listType=numbered]\n        // 2.List item 3.    [listType=numbered]\n        //\n        // Abort searching when found a different kind of a list.\n        if (element.getAttribute('listType') !== listItem.getAttribute('listType')) {\n            break;\n        }\n        // ■ List item 1.[]  [listType=bulleted]\n        // ■ List item 2.    [listType=bulleted]\n        // ○ List item 3.    [listType=bulleted]\n        // ○ List item 4.    [listType=bulleted]\n        //\n        // Abort searching when found a different list style,\n        if (element.getAttribute('listStyle') !== listItem.getAttribute('listStyle')) {\n            break;\n        }\n        // ... different direction\n        if (element.getAttribute('listReversed') !== listItem.getAttribute('listReversed')) {\n            break;\n        }\n        // ... and different start index\n        if (element.getAttribute('listStart') !== listItem.getAttribute('listStart')) {\n            break;\n        }\n        if (direction === 'backward') {\n            items.unshift(element);\n        } else {\n            items.push(element);\n        }\n    }\n    return items;\n}\n/**\n * Returns an array with all `listItem` elements in the model selection.\n *\n * It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n * If no list is selected, it returns an empty array.\n * The order of the elements is not specified.\n *\n * @internal\n */ function getSelectedListItems(model) {\n    const document = model.document;\n    // For all selected blocks find all list items that are being selected\n    // and update the `listStyle` attribute in those lists.\n    let listItems = [\n        ...document.selection.getSelectedBlocks()\n    ].filter((element)=>element.is('element', 'listItem')).map((element)=>{\n        const position = model.change((writer)=>writer.createPositionAt(element, 0));\n        return [\n            ...getSiblingNodes(position, 'backward'),\n            ...getSiblingNodes(position, 'forward')\n        ];\n    }).flat();\n    // Since `getSelectedBlocks()` can return items that belong to the same list, and\n    // `getSiblingNodes()` returns the entire list, we need to remove duplicated items.\n    listItems = [\n        ...new Set(listItems)\n    ];\n    return listItems;\n}\nconst BULLETED_LIST_STYLE_TYPES = [\n    'disc',\n    'circle',\n    'square'\n];\n// There's a lot of them (https://www.w3.org/TR/css-counter-styles-3/#typedef-counter-style).\n// Let's support only those that can be selected by ListPropertiesUI.\nconst NUMBERED_LIST_STYLE_TYPES = [\n    'decimal',\n    'decimal-leading-zero',\n    'lower-roman',\n    'upper-roman',\n    'lower-latin',\n    'upper-latin'\n];\n/**\n * Checks whether the given list-style-type is supported by numbered or bulleted list.\n */ function getListTypeFromListStyleType(listStyleType) {\n    if (BULLETED_LIST_STYLE_TYPES.includes(listStyleType)) {\n        return 'bulleted';\n    }\n    if (NUMBERED_LIST_STYLE_TYPES.includes(listStyleType)) {\n        return 'numbered';\n    }\n    return null;\n}\n/**\n * Implementation of getFillerOffset for view list item element.\n *\n * @returns Block filler offset or `null` if block filler is not needed.\n */ function getListItemFillerOffset() {\n    const hasOnlyLists = !this.isEmpty && (this.getChild(0).name == 'ul' || this.getChild(0).name == 'ol');\n    if (this.isEmpty || hasOnlyLists) {\n        return 0;\n    }\n    return getFillerOffset.call(this);\n}\n\n/**\n * A set of helpers related to legacy lists.\n */ class LegacyListUtils extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LegacyListUtils';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * Checks whether the given list-style-type is supported by numbered or bulleted list.\n\t */ getListTypeFromListStyleType(listStyleType) {\n        return getListTypeFromListStyleType(listStyleType);\n    }\n    /**\n\t * Returns an array with all `listItem` elements in the model selection.\n\t *\n\t * It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n\t * If no list is selected, it returns an empty array.\n\t * The order of the elements is not specified.\n\t */ getSelectedListItems(model) {\n        return getSelectedListItems(model);\n    }\n    /**\n\t * Returns an array with all `listItem` elements that represent the same list.\n\t *\n\t * It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n\t *\n\t * Additionally, if the `position` is inside a list item, that list item will be returned as well.\n\t *\n\t * @param position Starting position.\n\t * @param direction Walking direction.\n\t */ getSiblingNodes(position, direction) {\n        return getSiblingNodes(position, direction);\n    }\n}\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It creates a `<ul><li></li><ul>` (or `<ol>`) view structure out of a `listItem` model element, inserts it at the correct\n * position, and merges the list with surrounding lists (if available).\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param model Model instance.\n */ function modelViewInsertion$1(model) {\n    return (evt, data, conversionApi)=>{\n        const consumable = conversionApi.consumable;\n        if (!consumable.test(data.item, 'insert') || !consumable.test(data.item, 'attribute:listType') || !consumable.test(data.item, 'attribute:listIndent')) {\n            return;\n        }\n        consumable.consume(data.item, 'insert');\n        consumable.consume(data.item, 'attribute:listType');\n        consumable.consume(data.item, 'attribute:listIndent');\n        const modelItem = data.item;\n        const viewItem = generateLiInUl(modelItem, conversionApi);\n        injectViewList(modelItem, viewItem, conversionApi, model);\n    };\n}\n/**\n * A model-to-view converter for the `listItem` model element removal.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */ function modelViewRemove(model) {\n    return (evt, data, conversionApi)=>{\n        const viewPosition = conversionApi.mapper.toViewPosition(data.position);\n        const viewStart = viewPosition.getLastMatchingPosition((value)=>!value.item.is('element', 'li'));\n        const viewItem = viewStart.nodeAfter;\n        const viewWriter = conversionApi.writer;\n        // 1. Break the container after and before the list item.\n        // This will create a view list with one view list item - the one to remove.\n        viewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n        viewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n        // 2. Remove the list with the item to remove.\n        const viewList = viewItem.parent;\n        const viewListPrev = viewList.previousSibling;\n        const removeRange = viewWriter.createRangeOn(viewList);\n        const removed = viewWriter.remove(removeRange);\n        // 3. Merge the whole created by breaking and removing the list.\n        if (viewListPrev && viewListPrev.nextSibling) {\n            mergeViewLists(viewWriter, viewListPrev, viewListPrev.nextSibling);\n        }\n        // 4. Bring back nested list that was in the removed <li>.\n        const modelItem = conversionApi.mapper.toModelElement(viewItem);\n        hoistNestedLists(modelItem.getAttribute('listIndent') + 1, data.position, removeRange.start, viewItem, conversionApi, model);\n        // 5. Unbind removed view item and all children.\n        for (const child of viewWriter.createRangeIn(removed).getItems()){\n            conversionApi.mapper.unbindViewElement(child);\n        }\n        evt.stop();\n    };\n}\n/**\n * A model-to-view converter for the `type` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes from `<ul>` to `<ol>` (or vice versa). This is accomplished\n * by breaking view elements and changing their name. The next {@link module:list/legacylist/legacyconverters~modelViewMergeAfterChangeType}\n * converter will attempt to merge split nodes.\n *\n * Splitting this conversion into 2 steps makes it possible to add an additional conversion in the middle.\n * Check {@link module:list/legacytodolist/legacytodolistconverters~modelViewChangeType} to see an example of it.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n */ const modelViewChangeType$1 = (evt, data, conversionApi)=>{\n    if (!conversionApi.consumable.test(data.item, evt.name)) {\n        return;\n    }\n    const viewItem = conversionApi.mapper.toViewElement(data.item);\n    const viewWriter = conversionApi.writer;\n    // Break the container after and before the list item.\n    // This will create a view list with one view list item -- the one that changed type.\n    viewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n    viewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n    // Change name of the view list that holds the changed view item.\n    // We cannot just change name property, because that would not render properly.\n    const viewList = viewItem.parent;\n    const listName = data.attributeNewValue == 'numbered' ? 'ol' : 'ul';\n    viewWriter.rename(listName, viewList);\n};\n/**\n * A model-to-view converter that attempts to merge nodes split by {@link module:list/legacylist/legacyconverters~modelViewChangeType}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n */ const modelViewMergeAfterChangeType = (evt, data, conversionApi)=>{\n    conversionApi.consumable.consume(data.item, evt.name);\n    const viewItem = conversionApi.mapper.toViewElement(data.item);\n    const viewList = viewItem.parent;\n    const viewWriter = conversionApi.writer;\n    // Merge the changed view list with other lists, if possible.\n    mergeViewLists(viewWriter, viewList, viewList.nextSibling);\n    mergeViewLists(viewWriter, viewList.previousSibling, viewList);\n};\n/**\n * A model-to-view converter for the `listIndent` attribute change on the `listItem` model element.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */ function modelViewChangeIndent(model) {\n    return (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, 'attribute:listIndent')) {\n            return;\n        }\n        const viewItem = conversionApi.mapper.toViewElement(data.item);\n        const viewWriter = conversionApi.writer;\n        // 1. Break the container after and before the list item.\n        // This will create a view list with one view list item -- the one that changed type.\n        viewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n        viewWriter.breakContainer(viewWriter.createPositionAfter(viewItem));\n        // 2. Extract view list with changed view list item and merge \"hole\" possibly created by breaking and removing elements.\n        const viewList = viewItem.parent;\n        const viewListPrev = viewList.previousSibling;\n        const removeRange = viewWriter.createRangeOn(viewList);\n        viewWriter.remove(removeRange);\n        if (viewListPrev && viewListPrev.nextSibling) {\n            mergeViewLists(viewWriter, viewListPrev, viewListPrev.nextSibling);\n        }\n        // 3. Bring back nested list that was in the removed <li>.\n        hoistNestedLists(data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi, model);\n        // 4. Inject view list like it is newly inserted.\n        injectViewList(data.item, viewItem, conversionApi, model);\n        // 5. Consume insertion of children inside the item. They are already handled by re-building the item in view.\n        for (const child of data.item.getChildren()){\n            conversionApi.consumable.consume(child, 'insert');\n        }\n    };\n}\n/**\n * A special model-to-view converter introduced by the {@link module:list/legacylist~LegacyList list feature}. This converter is fired for\n * insert change of every model item, and should be fired before the actual converter. The converter checks whether the inserted\n * model item is a non-`listItem` element. If it is, and it is inserted inside a view list, the converter breaks the\n * list so the model element is inserted to the view parent element corresponding to its model parent element.\n *\n * The converter prevents such situations:\n *\n * ```xml\n * // Model:                        // View:\n * <listItem>foo</listItem>         <ul>\n * <listItem>bar</listItem>             <li>foo</li>\n *                                      <li>bar</li>\n *                                  </ul>\n *\n * // After change:                 // Correct view guaranteed by this converter:\n * <listItem>foo</listItem>         <ul><li>foo</li></ul><p>xxx</p><ul><li>bar</li></ul>\n * <paragraph>xxx</paragraph>       // Instead of this wrong view state:\n * <listItem>bar</listItem>         <ul><li>foo</li><p>xxx</p><li>bar</li></ul>\n * ```\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n */ const modelViewSplitOnInsert = (evt, data, conversionApi)=>{\n    if (!conversionApi.consumable.test(data.item, evt.name)) {\n        return;\n    }\n    if (data.item.name != 'listItem') {\n        let viewPosition = conversionApi.mapper.toViewPosition(data.range.start);\n        const viewWriter = conversionApi.writer;\n        const lists = [];\n        // Break multiple ULs/OLs if there are.\n        //\n        // Imagine following list:\n        //\n        // 1 --------\n        //   1.1 --------\n        //     1.1.1 --------\n        //     1.1.2 --------\n        //     1.1.3 --------\n        //       1.1.3.1 --------\n        //   1.2 --------\n        //     1.2.1 --------\n        // 2 --------\n        //\n        // Insert paragraph after item 1.1.1:\n        //\n        // 1 --------\n        //   1.1 --------\n        //     1.1.1 --------\n        //\n        // Lorem ipsum.\n        //\n        //     1.1.2 --------\n        //     1.1.3 --------\n        //       1.1.3.1 --------\n        //   1.2 --------\n        //     1.2.1 --------\n        // 2 --------\n        //\n        // In this case 1.1.2 has to become beginning of a new list.\n        // We need to break list before 1.1.2 (obvious), then we need to break list also before 1.2.\n        // Then we need to move those broken pieces one after another and merge:\n        //\n        // 1 --------\n        //   1.1 --------\n        //     1.1.1 --------\n        //\n        // Lorem ipsum.\n        //\n        // 1.1.2 --------\n        //   1.1.3 --------\n        //     1.1.3.1 --------\n        // 1.2 --------\n        //   1.2.1 --------\n        // 2 --------\n        //\n        while(viewPosition.parent.name == 'ul' || viewPosition.parent.name == 'ol'){\n            viewPosition = viewWriter.breakContainer(viewPosition);\n            if (viewPosition.parent.name != 'li') {\n                break;\n            }\n            // Remove lists that are after inserted element.\n            // They will be brought back later, below the inserted element.\n            const removeStart = viewPosition;\n            const removeEnd = viewWriter.createPositionAt(viewPosition.parent, 'end');\n            // Don't remove if there is nothing to remove.\n            if (!removeStart.isEqual(removeEnd)) {\n                const removed = viewWriter.remove(viewWriter.createRange(removeStart, removeEnd));\n                lists.push(removed);\n            }\n            viewPosition = viewWriter.createPositionAfter(viewPosition.parent);\n        }\n        // Bring back removed lists.\n        if (lists.length > 0) {\n            for(let i = 0; i < lists.length; i++){\n                const previousList = viewPosition.nodeBefore;\n                const insertedRange = viewWriter.insert(viewPosition, lists[i]);\n                viewPosition = insertedRange.end;\n                // Don't merge first list! We want a split in that place (this is why this converter is introduced).\n                if (i > 0) {\n                    const mergePos = mergeViewLists(viewWriter, previousList, previousList.nextSibling);\n                    // If `mergePos` is in `previousList` it means that the lists got merged.\n                    // In this case, we need to fix insert position.\n                    if (mergePos && mergePos.parent == previousList) {\n                        viewPosition.offset--;\n                    }\n                }\n            }\n            // Merge last inserted list with element after it.\n            mergeViewLists(viewWriter, viewPosition.nodeBefore, viewPosition.nodeAfter);\n        }\n    }\n};\n/**\n * A special model-to-view converter introduced by the {@link module:list/legacylist~LegacyList list feature}. This converter takes care of\n * merging view lists after something is removed or moved from near them.\n *\n * Example:\n *\n * ```xml\n * // Model:                        // View:\n * <listItem>foo</listItem>         <ul><li>foo</li></ul>\n * <paragraph>xxx</paragraph>       <p>xxx</p>\n * <listItem>bar</listItem>         <ul><li>bar</li></ul>\n *\n * // After change:                 // Correct view guaranteed by this converter:\n * <listItem>foo</listItem>         <ul>\n * <listItem>bar</listItem>             <li>foo</li>\n *                                      <li>bar</li>\n *                                  </ul>\n * ```\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n */ const modelViewMergeAfter = (evt, data, conversionApi)=>{\n    const viewPosition = conversionApi.mapper.toViewPosition(data.position);\n    const viewItemPrev = viewPosition.nodeBefore;\n    const viewItemNext = viewPosition.nodeAfter;\n    // Merge lists if something (remove, move) was done from inside of list.\n    // Merging will be done only if both items are view lists of the same type.\n    // The check is done inside the helper function.\n    mergeViewLists(conversionApi.writer, viewItemPrev, viewItemNext);\n};\n/**\n * A view-to-model converter that converts the `<li>` view elements into the `listItem` model elements.\n *\n * To set correct values of the `listType` and `listIndent` attributes the converter:\n * * checks `<li>`'s parent,\n * * stores and increases the `conversionApi.store.indent` value when `<li>`'s sub-items are converted.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */ const viewModelConverter = (evt, data, conversionApi)=>{\n    if (conversionApi.consumable.consume(data.viewItem, {\n        name: true\n    })) {\n        const writer = conversionApi.writer;\n        // 1. Create `listItem` model element.\n        const listItem = writer.createElement('listItem');\n        // 2. Handle `listItem` model element attributes.\n        const indent = getIndent(data.viewItem);\n        writer.setAttribute('listIndent', indent, listItem);\n        // Set 'bulleted' as default. If this item is pasted into a context,\n        const type = data.viewItem.parent && data.viewItem.parent.name == 'ol' ? 'numbered' : 'bulleted';\n        writer.setAttribute('listType', type, listItem);\n        if (!conversionApi.safeInsert(listItem, data.modelCursor)) {\n            return;\n        }\n        const nextPosition = viewToModelListItemChildrenConverter(listItem, data.viewItem.getChildren(), conversionApi);\n        // Result range starts before the first item and ends after the last.\n        data.modelRange = writer.createRange(data.modelCursor, nextPosition);\n        conversionApi.updateConversionResult(listItem, data);\n    }\n};\n/**\n * A view-to-model converter for the `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between the `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */ const cleanList = (evt, data, conversionApi)=>{\n    if (conversionApi.consumable.test(data.viewItem, {\n        name: true\n    })) {\n        // Caching children because when we start removing them iterating fails.\n        const children = Array.from(data.viewItem.getChildren());\n        for (const child of children){\n            const isWrongElement = !(child.is('element', 'li') || isList(child));\n            if (isWrongElement) {\n                child._remove();\n            }\n        }\n    }\n};\n/**\n * A view-to-model converter for the `<li>` elements that cleans whitespace formatting from the input view.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */ const cleanListItem = (evt, data, conversionApi)=>{\n    if (conversionApi.consumable.test(data.viewItem, {\n        name: true\n    })) {\n        if (data.viewItem.childCount === 0) {\n            return;\n        }\n        const children = [\n            ...data.viewItem.getChildren()\n        ];\n        let foundList = false;\n        for (const child of children){\n            if (foundList && !isList(child)) {\n                child._remove();\n            }\n            if (isList(child)) {\n                // If this is a <ul> or <ol>, do not process it, just mark that we already visited list element.\n                foundList = true;\n            }\n        }\n    }\n};\n/**\n * Returns a callback for model position to view position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `listItem` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n */ function modelToViewPosition(view) {\n    return (evt, data)=>{\n        if (data.isPhantom) {\n            return;\n        }\n        const modelItem = data.modelPosition.nodeBefore;\n        if (modelItem && modelItem.is('element', 'listItem')) {\n            const viewItem = data.mapper.toViewElement(modelItem);\n            const topmostViewList = viewItem.getAncestors().find(isList);\n            const walker = view.createPositionAt(viewItem, 0).getWalker();\n            for (const value of walker){\n                if (value.type == 'elementStart' && value.item.is('element', 'li')) {\n                    data.viewPosition = value.previousPosition;\n                    break;\n                } else if (value.type == 'elementEnd' && value.item == topmostViewList) {\n                    data.viewPosition = value.nextPosition;\n                    break;\n                }\n            }\n        }\n    };\n}\n/**\n * The callback for view position to model position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `<li>` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:viewToModelPosition\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */ function viewToModelPosition(model) {\n    return (evt, data)=>{\n        const viewPos = data.viewPosition;\n        const viewParent = viewPos.parent;\n        const mapper = data.mapper;\n        if (viewParent.name == 'ul' || viewParent.name == 'ol') {\n            // Position is directly in <ul> or <ol>.\n            if (!viewPos.isAtEnd) {\n                // If position is not at the end, it must be before <li>.\n                // Get that <li>, map it to `listItem` and set model position before that `listItem`.\n                const modelNode = mapper.toModelElement(viewPos.nodeAfter);\n                data.modelPosition = model.createPositionBefore(modelNode);\n            } else {\n                // Position is at the end of <ul> or <ol>, so there is no <li> after it to be mapped.\n                // There is <li> before the position, but we cannot just map it to `listItem` and set model position after it,\n                // because that <li> may contain nested items.\n                // We will check \"model length\" of that <li>, in other words - how many `listItem`s are in that <li>.\n                const modelNode = mapper.toModelElement(viewPos.nodeBefore);\n                const modelLength = mapper.getModelLength(viewPos.nodeBefore);\n                // Then we get model position before mapped `listItem` and shift it accordingly.\n                data.modelPosition = model.createPositionBefore(modelNode).getShiftedBy(modelLength);\n            }\n            evt.stop();\n        } else if (viewParent.name == 'li' && viewPos.nodeBefore && (viewPos.nodeBefore.name == 'ul' || viewPos.nodeBefore.name == 'ol')) {\n            // In most cases when view position is in <li> it is in text and this is a correct position.\n            // However, if position is after <ul> or <ol> we have to fix it -- because in model <ul>/<ol> are not in the `listItem`.\n            const modelNode = mapper.toModelElement(viewParent);\n            // Check all <ul>s and <ol>s that are in the <li> but before mapped position.\n            // Get model length of those elements and then add it to the offset of `listItem` mapped to the original <li>.\n            let modelLength = 1; // Starts from 1 because the original <li> has to be counted in too.\n            let viewList = viewPos.nodeBefore;\n            while(viewList && isList(viewList)){\n                modelLength += mapper.getModelLength(viewList);\n                viewList = viewList.previousSibling;\n            }\n            data.modelPosition = model.createPositionBefore(modelNode).getShiftedBy(modelLength);\n            evt.stop();\n        }\n    };\n}\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states.\n *\n * In the example below, there is a correct list structure.\n * Then the middle element is removed so the list structure will become incorrect:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>Item 2</listItem>   <--- this is removed.\n * <listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n * ```\n *\n * The list structure after the middle element is removed:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n * <listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>Item 3</listItem>   <--- note that indent got post-fixed.\n * ```\n *\n * @param model The data model.\n * @param writer The writer to do changes with.\n * @returns `true` if any change has been applied, `false` otherwise.\n */ function modelChangePostFixer(model, writer) {\n    const changes = model.document.differ.getChanges();\n    const itemToListHead = new Map();\n    let applied = false;\n    for (const entry of changes){\n        if (entry.type == 'insert' && entry.name == 'listItem') {\n            _addListToFix(entry.position);\n        } else if (entry.type == 'insert' && entry.name != 'listItem') {\n            if (entry.name != '$text') {\n                // In case of renamed element.\n                const item = entry.position.nodeAfter;\n                if (item.hasAttribute('listIndent')) {\n                    writer.removeAttribute('listIndent', item);\n                    applied = true;\n                }\n                if (item.hasAttribute('listType')) {\n                    writer.removeAttribute('listType', item);\n                    applied = true;\n                }\n                if (item.hasAttribute('listStyle')) {\n                    writer.removeAttribute('listStyle', item);\n                    applied = true;\n                }\n                if (item.hasAttribute('listReversed')) {\n                    writer.removeAttribute('listReversed', item);\n                    applied = true;\n                }\n                if (item.hasAttribute('listStart')) {\n                    writer.removeAttribute('listStart', item);\n                    applied = true;\n                }\n                for (const innerItem of Array.from(model.createRangeIn(item)).filter((e)=>e.item.is('element', 'listItem'))){\n                    _addListToFix(innerItem.previousPosition);\n                }\n            }\n            const posAfter = entry.position.getShiftedBy(entry.length);\n            _addListToFix(posAfter);\n        } else if (entry.type == 'remove' && entry.name == 'listItem') {\n            _addListToFix(entry.position);\n        } else if (entry.type == 'attribute' && entry.attributeKey == 'listIndent') {\n            _addListToFix(entry.range.start);\n        } else if (entry.type == 'attribute' && entry.attributeKey == 'listType') {\n            _addListToFix(entry.range.start);\n        }\n    }\n    for (const listHead of itemToListHead.values()){\n        _fixListIndents(listHead);\n        _fixListTypes(listHead);\n    }\n    return applied;\n    function _addListToFix(position) {\n        const previousNode = position.nodeBefore;\n        if (!previousNode || !previousNode.is('element', 'listItem')) {\n            const item = position.nodeAfter;\n            if (item && item.is('element', 'listItem')) {\n                itemToListHead.set(item, item);\n            }\n        } else {\n            let listHead = previousNode;\n            if (itemToListHead.has(listHead)) {\n                return;\n            }\n            for(// Cache previousSibling and reuse for performance reasons. See #6581.\n            let previousSibling = listHead.previousSibling; previousSibling && previousSibling.is('element', 'listItem'); previousSibling = listHead.previousSibling){\n                listHead = previousSibling;\n                if (itemToListHead.has(listHead)) {\n                    return;\n                }\n            }\n            itemToListHead.set(previousNode, listHead);\n        }\n    }\n    function _fixListIndents(item) {\n        let maxIndent = 0;\n        let fixBy = null;\n        while(item && item.is('element', 'listItem')){\n            const itemIndent = item.getAttribute('listIndent');\n            if (itemIndent > maxIndent) {\n                let newIndent;\n                if (fixBy === null) {\n                    fixBy = itemIndent - maxIndent;\n                    newIndent = maxIndent;\n                } else {\n                    if (fixBy > itemIndent) {\n                        fixBy = itemIndent;\n                    }\n                    newIndent = itemIndent - fixBy;\n                }\n                writer.setAttribute('listIndent', newIndent, item);\n                applied = true;\n            } else {\n                fixBy = null;\n                maxIndent = item.getAttribute('listIndent') + 1;\n            }\n            item = item.nextSibling;\n        }\n    }\n    function _fixListTypes(item) {\n        let typesStack = [];\n        let prev = null;\n        while(item && item.is('element', 'listItem')){\n            const itemIndent = item.getAttribute('listIndent');\n            if (prev && prev.getAttribute('listIndent') > itemIndent) {\n                typesStack = typesStack.slice(0, itemIndent + 1);\n            }\n            if (itemIndent != 0) {\n                if (typesStack[itemIndent]) {\n                    const type = typesStack[itemIndent];\n                    if (item.getAttribute('listType') != type) {\n                        writer.setAttribute('listType', type, item);\n                        applied = true;\n                    }\n                } else {\n                    typesStack[itemIndent] = item.getAttribute('listType');\n                }\n            }\n            prev = item;\n            item = item.nextSibling;\n        }\n    }\n}\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>A</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>B^</listItem>\n * // At ^ paste:  <listItem listType=\"bulleted\" listIndent=4>X</listItem>\n * //              <listItem listType=\"bulleted\" listIndent=5>Y</listItem>\n * <listItem listType=\"bulleted\" listIndent=2>C</listItem>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>A</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>BX</listItem>\n * <listItem listType=\"bulleted\" listIndent=2>Y/listItem>\n * <listItem listType=\"bulleted\" listIndent=2>C</listItem>\n * ```\n */ const modelIndentPasteFixer = function(evt, [content, selectable]) {\n    const model = this;\n    // Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n    // elements before it and there is no need to fix indents, because even if we insert that content into a list,\n    // that list will be broken.\n    // Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n    // would create incorrect model.\n    let item = content.is('documentFragment') ? content.getChild(0) : content;\n    let selection;\n    if (!selectable) {\n        selection = model.document.selection;\n    } else {\n        selection = model.createSelection(selectable);\n    }\n    if (item && item.is('element', 'listItem')) {\n        // Get a reference list item. Inserted list items will be fixed according to that item.\n        const pos = selection.getFirstPosition();\n        let refItem = null;\n        if (pos.parent.is('element', 'listItem')) {\n            refItem = pos.parent;\n        } else if (pos.nodeBefore && pos.nodeBefore.is('element', 'listItem')) {\n            refItem = pos.nodeBefore;\n        }\n        // If there is `refItem` it means that we do insert list items into an existing list.\n        if (refItem) {\n            // First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n            // to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n            // Indent of all those items has to be adjusted to reference item.\n            const indentChange = refItem.getAttribute('listIndent');\n            // Fix only if there is anything to fix.\n            if (indentChange > 0) {\n                // Adjust indent of all \"first\" list items in inserted data.\n                while(item && item.is('element', 'listItem')){\n                    item._setAttribute('listIndent', item.getAttribute('listIndent') + indentChange);\n                    item = item.nextSibling;\n                }\n            }\n        }\n    }\n};\n/**\n * Helper function that converts children of a given `<li>` view element into corresponding model elements.\n * The function maintains proper order of elements if model `listItem` is split during the conversion\n * due to block children conversion.\n *\n * @param listItemModel List item model element to which converted children will be inserted.\n * @param viewChildren View elements which will be converted.\n * @param conversionApi Conversion interface to be used by the callback.\n * @returns Position on which next elements should be inserted after children conversion.\n */ function viewToModelListItemChildrenConverter(listItemModel, viewChildren, conversionApi) {\n    const { writer, schema } = conversionApi;\n    // A position after the last inserted `listItem`.\n    let nextPosition = writer.createPositionAfter(listItemModel);\n    // Check all children of the converted `<li>`. At this point we assume there are no \"whitespace\" view text nodes\n    // in view list, between view list items. This should be handled by `<ul>` and `<ol>` converters.\n    for (const child of viewChildren){\n        if (child.name == 'ul' || child.name == 'ol') {\n            // If the children is a list, we will insert its conversion result after currently handled `listItem`.\n            // Then, next insertion position will be set after all the new list items (and maybe other elements if\n            // something split list item).\n            //\n            // If this is a list, we expect that some `listItem`s and possibly other blocks will be inserted, however `.modelCursor`\n            // should be set after last `listItem` (or block). This is why it feels safe to use it as `nextPosition`\n            nextPosition = conversionApi.convertItem(child, nextPosition).modelCursor;\n        } else {\n            // If this is not a list, try inserting content at the end of the currently handled `listItem`.\n            const result = conversionApi.convertItem(child, writer.createPositionAt(listItemModel, 'end'));\n            // It may end up that the current `listItem` becomes split (if that content cannot be inside `listItem`). For example:\n            //\n            // <li><p>Foo</p></li>\n            //\n            // will be converted to:\n            //\n            // <listItem></listItem><paragraph>Foo</paragraph><listItem></listItem>\n            //\n            const convertedChild = result.modelRange.start.nodeAfter;\n            const wasSplit = convertedChild && convertedChild.is('element') && !schema.checkChild(listItemModel, convertedChild.name);\n            if (wasSplit) {\n                // As `lastListItem` got split, we need to update it to the second part of the split `listItem` element.\n                //\n                // `modelCursor` should be set to a position where the conversion should continue. There are multiple possible scenarios\n                // that may happen. Usually, `modelCursor` (marked as `#` below) would point to the second list item after conversion:\n                //\n                //\t\t`<li><p>Foo</p></li>` -> `<listItem></listItem><paragraph>Foo</paragraph><listItem>#</listItem>`\n                //\n                // However, in some cases, like auto-paragraphing, the position is placed at the end of the block element:\n                //\n                //\t\t`<li><div>Foo</div></li>` -> `<listItem></listItem><paragraph>Foo#</paragraph><listItem></listItem>`\n                //\n                // or after an element if another element broken auto-paragraphed element:\n                //\n                //\t\t`<li><div><h2>Foo</h2></div></li>` -> `<listItem></listItem><heading1>Foo</heading1>#<listItem></listItem>`\n                //\n                // We need to check for such cases and use proper list item and position based on it.\n                //\n                if (result.modelCursor.parent.is('element', 'listItem')) {\n                    // (1).\n                    listItemModel = result.modelCursor.parent;\n                } else {\n                    // (2), (3).\n                    listItemModel = findNextListItem(result.modelCursor);\n                }\n                nextPosition = writer.createPositionAfter(listItemModel);\n            }\n        }\n    }\n    return nextPosition;\n}\n/**\n * Helper function that seeks for a next list item starting from given `startPosition`.\n */ function findNextListItem(startPosition) {\n    const treeWalker = new TreeWalker({\n        startPosition\n    });\n    let value;\n    do {\n        value = treeWalker.next();\n    }while (!value.value.item.is('element', 'listItem'))\n    return value.value.item;\n}\n/**\n * Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according\n * to other given parameters.\n */ function hoistNestedLists(nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, conversionApi, model) {\n    // Find correct previous model list item element.\n    // The element has to have either same or smaller indent than given reference indent.\n    // This will be the model element which will get nested items (if it has smaller indent) or sibling items (if it has same indent).\n    // Keep in mind that such element might not be found, if removed item was the first item.\n    const prevModelItem = getSiblingListItem(modelRemoveStartPosition.nodeBefore, {\n        sameIndent: true,\n        smallerIndent: true,\n        listIndent: nextIndent\n    });\n    const mapper = conversionApi.mapper;\n    const viewWriter = conversionApi.writer;\n    // Indent of found element or `null` if the element has not been found.\n    const prevIndent = prevModelItem ? prevModelItem.getAttribute('listIndent') : null;\n    let insertPosition;\n    if (!prevModelItem) {\n        // If element has not been found, simply insert lists at the position where the removed item was:\n        //\n        // Lorem ipsum.\n        // 1 --------           <--- this is removed, no previous list item, put nested items in place of removed item.\n        //   1.1 --------       <--- this is reference indent.\n        //     1.1.1 --------\n        //     1.1.2 --------\n        //   1.2 --------\n        //\n        // Becomes:\n        //\n        // Lorem ipsum.\n        // 1.1 --------\n        //   1.1.1 --------\n        //   1.1.2 --------\n        // 1.2 --------\n        insertPosition = viewRemoveStartPosition;\n    } else if (prevIndent == nextIndent) {\n        // If element has been found and has same indent as reference indent it means that nested items should\n        // become siblings of found element:\n        //\n        // 1 --------\n        //   1.1 --------\n        //   1.2 --------       <--- this is `prevModelItem`.\n        // 2 --------           <--- this is removed, previous list item has indent same as reference indent.\n        //   2.1 --------       <--- this is reference indent, this and 2.2 should become siblings of 1.2.\n        //   2.2 --------\n        //\n        // Becomes:\n        //\n        // 1 --------\n        //   1.1 --------\n        //   1.2 --------\n        //   2.1 --------\n        //   2.2 --------\n        const prevViewList = mapper.toViewElement(prevModelItem).parent;\n        insertPosition = viewWriter.createPositionAfter(prevViewList);\n    } else {\n        // If element has been found and has smaller indent as reference indent it means that nested items\n        // should become nested items of found item:\n        //\n        // 1 --------           <--- this is `prevModelItem`.\n        //   1.1 --------       <--- this is removed, previous list item has indent smaller than reference indent.\n        //     1.1.1 --------   <--- this is reference indent, this and 1.1.1 should become nested items of 1.\n        //     1.1.2 --------\n        //   1.2 --------\n        //\n        // Becomes:\n        //\n        // 1 --------\n        //   1.1.1 --------\n        //   1.1.2 --------\n        //   1.2 --------\n        //\n        // Note: in this case 1.1.1 have indent 2 while 1 have indent 0. In model that should not be possible,\n        // because following item may have indent bigger only by one. But this is fixed by postfixer.\n        const modelPosition = model.createPositionAt(prevModelItem, 'end');\n        insertPosition = mapper.toViewPosition(modelPosition);\n    }\n    insertPosition = positionAfterUiElements(insertPosition);\n    // Handle multiple lists. This happens if list item has nested numbered and bulleted lists. Following lists\n    // are inserted after the first list (no need to recalculate insertion position for them).\n    for (const child of [\n        ...viewRemovedItem.getChildren()\n    ]){\n        if (isList(child)) {\n            insertPosition = viewWriter.move(viewWriter.createRangeOn(child), insertPosition).end;\n            mergeViewLists(viewWriter, child, child.nextSibling);\n            mergeViewLists(viewWriter, child.previousSibling, child);\n        }\n    }\n}\n/**\n * Checks if view element is a list type (ul or ol).\n */ function isList(viewElement) {\n    return viewElement.is('element', 'ol') || viewElement.is('element', 'ul');\n}\n/**\n * Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n *\n * Also, fixes non HTML compliant lists indents:\n *\n * ```\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI     (indent: 0)\n *     |-> OL                                  |-> OL\n *         |-> OL                                  |\n *         |   |-> OL                              |\n *         |       |-> OL                          |\n *         |           |-> LI (parent LIs: 1)      |-> LI (indent: 1)\n *         |-> LI (parent LIs: 1)                  |-> LI (indent: 1)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> OL                                      |\n *     |-> OL                                  |\n *          |-> OL                             |\n *              |-> LI (parent LIs: 0)         |-> LI        (indent: 0)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI         (indent: 0)\n * |-> OL                                          |-> OL\n *     |-> LI (parent LIs: 0)                          |-> LI (indent: 1)\n * ```\n */ function getIndent(listItem) {\n    let indent = 0;\n    let parent = listItem.parent;\n    while(parent){\n        // Each LI in the tree will result in an increased indent for HTML compliant lists.\n        if (parent.is('element', 'li')) {\n            indent++;\n        } else {\n            // If however the list is nested in other list we should check previous sibling of any of the list elements...\n            const previousSibling = parent.previousSibling;\n            // ...because the we might need increase its indent:\n            //\t\tbefore:                           fixed list:\n            //\t\tOL                                OL\n            //\t\t|-> LI (parent LIs: 0)            |-> LI         (indent: 0)\n            //\t\t|-> OL                                |-> OL\n            //\t\t    |-> LI (parent LIs: 0)                |-> LI (indent: 1)\n            if (previousSibling && previousSibling.is('element', 'li')) {\n                indent++;\n            }\n        }\n        parent = parent.parent;\n    }\n    return indent;\n}\n\n/**\n * The engine of the list feature. It handles creating, editing and removing lists and list items.\n *\n * It registers the `'numberedList'`, `'bulletedList'`, `'indentList'` and `'outdentList'` commands.\n */ class LegacyListEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LegacyListEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Enter,\n            Delete,\n            LegacyListUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Schema.\n        // Note: in case `$block` will ever be allowed in `listItem`, keep in mind that this feature\n        // uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.\n        // If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.\n        editor.model.schema.register('listItem', {\n            inheritAllFrom: '$block',\n            allowAttributes: [\n                'listType',\n                'listIndent'\n            ]\n        });\n        // Converters.\n        const data = editor.data;\n        const editing = editor.editing;\n        editor.model.document.registerPostFixer((writer)=>modelChangePostFixer(editor.model, writer));\n        editing.mapper.registerViewToModelLength('li', getViewListItemLength);\n        data.mapper.registerViewToModelLength('li', getViewListItemLength);\n        editing.mapper.on('modelToViewPosition', modelToViewPosition(editing.view));\n        editing.mapper.on('viewToModelPosition', viewToModelPosition(editor.model));\n        data.mapper.on('modelToViewPosition', modelToViewPosition(editing.view));\n        editor.conversion.for('editingDowncast').add((dispatcher)=>{\n            dispatcher.on('insert', modelViewSplitOnInsert, {\n                priority: 'high'\n            });\n            dispatcher.on('insert:listItem', modelViewInsertion$1(editor.model));\n            dispatcher.on('attribute:listType:listItem', modelViewChangeType$1, {\n                priority: 'high'\n            });\n            dispatcher.on('attribute:listType:listItem', modelViewMergeAfterChangeType, {\n                priority: 'low'\n            });\n            dispatcher.on('attribute:listIndent:listItem', modelViewChangeIndent(editor.model));\n            dispatcher.on('remove:listItem', modelViewRemove(editor.model));\n            dispatcher.on('remove', modelViewMergeAfter, {\n                priority: 'low'\n            });\n        });\n        editor.conversion.for('dataDowncast').add((dispatcher)=>{\n            dispatcher.on('insert', modelViewSplitOnInsert, {\n                priority: 'high'\n            });\n            dispatcher.on('insert:listItem', modelViewInsertion$1(editor.model));\n        });\n        editor.conversion.for('upcast').add((dispatcher)=>{\n            dispatcher.on('element:ul', cleanList, {\n                priority: 'high'\n            });\n            dispatcher.on('element:ol', cleanList, {\n                priority: 'high'\n            });\n            dispatcher.on('element:li', cleanListItem, {\n                priority: 'high'\n            });\n            dispatcher.on('element:li', viewModelConverter);\n        });\n        // Fix indentation of pasted items.\n        editor.model.on('insertContent', modelIndentPasteFixer, {\n            priority: 'high'\n        });\n        // Register commands for numbered and bulleted list.\n        editor.commands.add('numberedList', new LegacyListCommand(editor, 'numbered'));\n        editor.commands.add('bulletedList', new LegacyListCommand(editor, 'bulleted'));\n        // Register commands for indenting.\n        editor.commands.add('indentList', new LegacyIndentCommand(editor, 'forward'));\n        editor.commands.add('outdentList', new LegacyIndentCommand(editor, 'backward'));\n        const viewDocument = editing.view.document;\n        // Overwrite default Enter key behavior.\n        // If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.\n        this.listenTo(viewDocument, 'enter', (evt, data)=>{\n            const doc = this.editor.model.document;\n            const positionParent = doc.selection.getLastPosition().parent;\n            if (doc.selection.isCollapsed && positionParent.name == 'listItem' && positionParent.isEmpty) {\n                this.editor.execute('outdentList');\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: 'li'\n        });\n        // Overwrite default Backspace key behavior.\n        // If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83\n        this.listenTo(viewDocument, 'delete', (evt, data)=>{\n            // Check conditions from those that require less computations like those immediately available.\n            if (data.direction !== 'backward') {\n                return;\n            }\n            const selection = this.editor.model.document.selection;\n            if (!selection.isCollapsed) {\n                return;\n            }\n            const firstPosition = selection.getFirstPosition();\n            if (!firstPosition.isAtStart) {\n                return;\n            }\n            const positionParent = firstPosition.parent;\n            if (positionParent.name !== 'listItem') {\n                return;\n            }\n            const previousIsAListItem = positionParent.previousSibling && positionParent.previousSibling.name === 'listItem';\n            if (previousIsAListItem) {\n                return;\n            }\n            this.editor.execute('outdentList');\n            data.preventDefault();\n            evt.stop();\n        }, {\n            context: 'li'\n        });\n        this.listenTo(editor.editing.view.document, 'tab', (evt, data)=>{\n            const commandName = data.shiftKey ? 'outdentList' : 'indentList';\n            const command = this.editor.commands.get(commandName);\n            if (command.isEnabled) {\n                editor.execute(commandName);\n                data.stopPropagation();\n                data.preventDefault();\n                evt.stop();\n            }\n        }, {\n            context: 'li'\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const commands = this.editor.commands;\n        const indent = commands.get('indent');\n        const outdent = commands.get('outdent');\n        if (indent) {\n            indent.registerChildCommand(commands.get('indentList'));\n        }\n        if (outdent) {\n            outdent.registerChildCommand(commands.get('outdentList'));\n        }\n    }\n}\nfunction getViewListItemLength(element) {\n    let length = 1;\n    for (const child of element.getChildren()){\n        if (child.name == 'ul' || child.name == 'ol') {\n            for (const item of child.getChildren()){\n                length += getViewListItemLength(item);\n            }\n        }\n    }\n    return length;\n}\n\n/**\n * The legacy list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/legacylist/legacylistediting~LegacyListEditing legacy list editing feature}\n * and {@link module:list/list/listui~ListUI list UI feature}.\n */ class LegacyList extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LegacyListEditing,\n            ListUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LegacyList';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The list style command. It changes the `listStyle` attribute of the selected list items.\n *\n * If the list type (numbered or bulleted) can be inferred from the passed style type,\n * the command tries to convert selected items to a list of that type.\n * It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n */ class LegacyListStyleCommand extends Command {\n    /**\n\t * The default type of the list style.\n\t */ defaultType;\n    /**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t */ constructor(editor, defaultType){\n        super(editor);\n        this.defaultType = defaultType;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        this.value = this._getValue();\n        this.isEnabled = this._checkEnabled();\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.type The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */ execute(options = {}) {\n        this._tryToConvertItemsToList(options);\n        const model = this.editor.model;\n        const listItems = getSelectedListItems(model);\n        if (!listItems.length) {\n            return;\n        }\n        model.change((writer)=>{\n            for (const item of listItems){\n                writer.setAttribute('listStyle', options.type || this.defaultType, item);\n            }\n        });\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */ _getValue() {\n        const listItem = this.editor.model.document.selection.getFirstPosition().parent;\n        if (listItem && listItem.is('element', 'listItem')) {\n            return listItem.getAttribute('listStyle');\n        }\n        return null;\n    }\n    /**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */ _checkEnabled() {\n        const editor = this.editor;\n        const numberedList = editor.commands.get('numberedList');\n        const bulletedList = editor.commands.get('bulletedList');\n        return numberedList.isEnabled || bulletedList.isEnabled;\n    }\n    /**\n\t * Checks if the provided list style is valid. Also changes the selection to a list if it's not set yet.\n\t *\n\t * @param The type of the list style. If `null` is specified, the function does nothing.\n\t*/ _tryToConvertItemsToList(options) {\n        if (!options.type) {\n            return;\n        }\n        const listType = getListTypeFromListStyleType(options.type);\n        /* istanbul ignore next -- @preserve */ if (!listType) {\n            return;\n        }\n        const editor = this.editor;\n        const commandName = `${listType}List`;\n        const command = editor.commands.get(commandName);\n        if (!command.value) {\n            editor.execute(commandName);\n        }\n    }\n}\n\n/**\n * The reversed list command. It changes the `listReversed` attribute of the selected list items. As a result, the list order will be\n * reversed.\n * It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n */ class LegacyListReversedCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const value = this._getValue();\n        this.value = value;\n        this.isEnabled = value != null;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.reversed Whether the list should be reversed.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const listItems = getSelectedListItems(model).filter((item)=>item.getAttribute('listType') == 'numbered');\n        model.change((writer)=>{\n            for (const item of listItems){\n                writer.setAttribute('listReversed', !!options.reversed, item);\n            }\n        });\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */ _getValue() {\n        const listItem = this.editor.model.document.selection.getFirstPosition().parent;\n        if (listItem && listItem.is('element', 'listItem') && listItem.getAttribute('listType') == 'numbered') {\n            return listItem.getAttribute('listReversed');\n        }\n        return null;\n    }\n}\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items.\n * It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n */ class LegacyListStartCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const value = this._getValue();\n        this.value = value;\n        this.isEnabled = value != null;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.startIndex The list start index.\n\t */ execute({ startIndex = 1 } = {}) {\n        const model = this.editor.model;\n        const listItems = getSelectedListItems(model).filter((item)=>item.getAttribute('listType') == 'numbered');\n        model.change((writer)=>{\n            for (const item of listItems){\n                writer.setAttribute('listStart', startIndex >= 0 ? startIndex : 1, item);\n            }\n        });\n    }\n    /**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */ _getValue() {\n        const listItem = this.editor.model.document.selection.getFirstPosition().parent;\n        if (listItem && listItem.is('element', 'listItem') && listItem.getAttribute('listType') == 'numbered') {\n            return listItem.getAttribute('listStart');\n        }\n        return null;\n    }\n}\n\nconst DEFAULT_LIST_TYPE = 'default';\n/**\n * The engine of the list properties feature.\n *\n * It sets the value for the `listItem` attribute of the {@link module:list/legacylist~LegacyList `<listItem>`} element that\n * allows modifying the list style type.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listconfig~ListPropertiesConfig}.\n */ class LegacyListPropertiesEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LegacyListEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LegacyListPropertiesEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('list', {\n            properties: {\n                styles: true,\n                startIndex: false,\n                reversed: false\n            }\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const enabledProperties = editor.config.get('list.properties');\n        const strategies = createAttributeStrategies(enabledProperties);\n        // Extend schema.\n        model.schema.extend('listItem', {\n            allowAttributes: strategies.map((s)=>s.attributeName)\n        });\n        for (const strategy of strategies){\n            strategy.addCommand(editor);\n        }\n        // Fix list attributes when modifying their nesting levels (the `listIndent` attribute).\n        this.listenTo(editor.commands.get('indentList'), '_executeCleanup', fixListAfterIndentListCommand(editor, strategies));\n        this.listenTo(editor.commands.get('outdentList'), '_executeCleanup', fixListAfterOutdentListCommand(editor, strategies));\n        this.listenTo(editor.commands.get('bulletedList'), '_executeCleanup', restoreDefaultListStyle(editor));\n        this.listenTo(editor.commands.get('numberedList'), '_executeCleanup', restoreDefaultListStyle(editor));\n        // Register a post-fixer that ensures that the attributes is specified in each `listItem` element.\n        model.document.registerPostFixer(fixListAttributesOnListItemElements(editor, strategies));\n        // Set up conversion.\n        editor.conversion.for('upcast').add(upcastListItemAttributes(strategies));\n        editor.conversion.for('downcast').add(downcastListItemAttributes(strategies));\n        // Handle merging two separated lists into the single one.\n        this._mergeListAttributesWhileMergingLists(strategies);\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        // Enable post-fixer that removes the attributes from to-do list items only if the \"TodoList\" plugin is on.\n        // We need to registry the hook here since the `TodoList` plugin can be added after the `ListPropertiesEditing`.\n        if (editor.commands.get('todoList')) {\n            editor.model.document.registerPostFixer(removeListItemAttributesFromTodoList(editor));\n        }\n    }\n    /**\n\t * Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether two lists will be merged into a single\n\t * one after deleting the content.\n\t *\n\t * The purpose of this action is to adjust the `listStyle`, `listReversed` and `listStart` values\n\t * for the list that was merged.\n\t *\n\t * Consider the following model's content:\n\t *\n\t * ```xml\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <paragraph>[A paragraph.]</paragraph>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t * ```\n\t *\n\t * After removing the paragraph element, the second list will be merged into the first one.\n\t * We want to inherit the `listStyle` attribute for the second list from the first one.\n\t *\n\t * ```xml\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * ```\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/7879.\n\t *\n\t * @param attributeStrategies Strategies for the enabled attributes.\n\t */ _mergeListAttributesWhileMergingLists(attributeStrategies) {\n        const editor = this.editor;\n        const model = editor.model;\n        // First the outer-most`listItem` in the first list reference.\n        // If found, the lists should be merged and this `listItem` provides the attributes\n        // and it is also a starting point when searching for items in the second list.\n        let firstMostOuterItem;\n        // Check whether the removed content is between two lists.\n        this.listenTo(model, 'deleteContent', (evt, [selection])=>{\n            const firstPosition = selection.getFirstPosition();\n            const lastPosition = selection.getLastPosition();\n            // Typing or removing content in a single item. Aborting.\n            if (firstPosition.parent === lastPosition.parent) {\n                return;\n            }\n            // An element before the content that will be removed is not a list.\n            if (!firstPosition.parent.is('element', 'listItem')) {\n                return;\n            }\n            const nextSibling = lastPosition.parent.nextSibling;\n            // An element after the content that will be removed is not a list.\n            if (!nextSibling || !nextSibling.is('element', 'listItem')) {\n                return;\n            }\n            // Find the outermost list item based on the `listIndent` attribute. We can't assume that `listIndent=0`\n            // because the selection can be hooked in nested lists.\n            //\n            // <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n            // <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List [item 1.1</listItem>\n            // <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1.</listItem>\n            // <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"circle\">UL List ]item 1.1</listItem>\n            //\n            // After deleting the content, we would like to inherit the \"square\" attribute for the last element:\n            //\n            // <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n            // <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List []item 1.1</listItem>\n            const mostOuterItemList = getSiblingListItem(firstPosition.parent, {\n                sameIndent: true,\n                listIndent: nextSibling.getAttribute('listIndent')\n            });\n            // The outermost list item may not exist while removing elements between lists with different value\n            // of the `listIndent` attribute. In such a case we don't want to update anything. See: #8073.\n            if (!mostOuterItemList) {\n                return;\n            }\n            if (mostOuterItemList.getAttribute('listType') === nextSibling.getAttribute('listType')) {\n                firstMostOuterItem = mostOuterItemList;\n            }\n        }, {\n            priority: 'high'\n        });\n        // If so, update the `listStyle` attribute for the second list.\n        this.listenTo(model, 'deleteContent', ()=>{\n            if (!firstMostOuterItem) {\n                return;\n            }\n            model.change((writer)=>{\n                // Find the first most-outer item list in the merged list.\n                // A case when the first list item in the second list was merged into the last item in the first list.\n                //\n                // <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n                // <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n                // <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1</listItem>\n                // <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n                const secondListMostOuterItem = getSiblingListItem(firstMostOuterItem.nextSibling, {\n                    sameIndent: true,\n                    listIndent: firstMostOuterItem.getAttribute('listIndent'),\n                    direction: 'forward'\n                });\n                // If the selection ends in a non-list element, there are no <listItem>s that would require adjustments.\n                // See: #8642.\n                if (!secondListMostOuterItem) {\n                    firstMostOuterItem = null;\n                    return;\n                }\n                const items = [\n                    secondListMostOuterItem,\n                    ...getSiblingNodes(writer.createPositionAt(secondListMostOuterItem, 0), 'forward')\n                ];\n                for (const listItem of items){\n                    for (const strategy of attributeStrategies){\n                        if (strategy.appliesToListItem(listItem)) {\n                            const attributeName = strategy.attributeName;\n                            const value = firstMostOuterItem.getAttribute(attributeName);\n                            writer.setAttribute(attributeName, value, listItem);\n                        }\n                    }\n                }\n            });\n            firstMostOuterItem = null;\n        }, {\n            priority: 'low'\n        });\n    }\n}\n/**\n * Creates an array of strategies for dealing with enabled listItem attributes.\n */ function createAttributeStrategies(enabledProperties) {\n    const strategies = [];\n    if (enabledProperties.styles) {\n        strategies.push({\n            attributeName: 'listStyle',\n            defaultValue: DEFAULT_LIST_TYPE,\n            addCommand (editor) {\n                editor.commands.add('listStyle', new LegacyListStyleCommand(editor, DEFAULT_LIST_TYPE));\n            },\n            appliesToListItem () {\n                return true;\n            },\n            setAttributeOnDowncast (writer, listStyle, element) {\n                if (listStyle && listStyle !== DEFAULT_LIST_TYPE) {\n                    writer.setStyle('list-style-type', listStyle, element);\n                } else {\n                    writer.removeStyle('list-style-type', element);\n                }\n            },\n            getAttributeOnUpcast (listParent) {\n                return listParent.getStyle('list-style-type') || DEFAULT_LIST_TYPE;\n            }\n        });\n    }\n    if (enabledProperties.reversed) {\n        strategies.push({\n            attributeName: 'listReversed',\n            defaultValue: false,\n            addCommand (editor) {\n                editor.commands.add('listReversed', new LegacyListReversedCommand(editor));\n            },\n            appliesToListItem (item) {\n                return item.getAttribute('listType') == 'numbered';\n            },\n            setAttributeOnDowncast (writer, listReversed, element) {\n                if (listReversed) {\n                    writer.setAttribute('reversed', 'reversed', element);\n                } else {\n                    writer.removeAttribute('reversed', element);\n                }\n            },\n            getAttributeOnUpcast (listParent) {\n                return listParent.hasAttribute('reversed');\n            }\n        });\n    }\n    if (enabledProperties.startIndex) {\n        strategies.push({\n            attributeName: 'listStart',\n            defaultValue: 1,\n            addCommand (editor) {\n                editor.commands.add('listStart', new LegacyListStartCommand(editor));\n            },\n            appliesToListItem (item) {\n                return item.getAttribute('listType') == 'numbered';\n            },\n            setAttributeOnDowncast (writer, listStart, element) {\n                if (listStart == 0 || listStart > 1) {\n                    writer.setAttribute('start', listStart, element);\n                } else {\n                    writer.removeAttribute('start', element);\n                }\n            },\n            getAttributeOnUpcast (listParent) {\n                const startAttributeValue = listParent.getAttribute('start');\n                return startAttributeValue >= 0 ? startAttributeValue : 1;\n            }\n        });\n    }\n    return strategies;\n}\n/**\n * Returns a converter consumes the `style`, `reversed` and `start` attribute.\n * In `style` it searches for the `list-style-type` definition.\n * If not found, the `\"default\"` value will be used.\n */ function upcastListItemAttributes(attributeStrategies) {\n    return (dispatcher)=>{\n        dispatcher.on('element:li', (evt, data, conversionApi)=>{\n            // https://github.com/ckeditor/ckeditor5/issues/13858\n            if (!data.modelRange) {\n                return;\n            }\n            const listParent = data.viewItem.parent;\n            const listItem = data.modelRange.start.nodeAfter || data.modelRange.end.nodeBefore;\n            for (const strategy of attributeStrategies){\n                if (strategy.appliesToListItem(listItem)) {\n                    const listStyle = strategy.getAttributeOnUpcast(listParent);\n                    conversionApi.writer.setAttribute(strategy.attributeName, listStyle, listItem);\n                }\n            }\n        }, {\n            priority: 'low'\n        });\n    };\n}\n/**\n * Returns a converter that adds `reversed`, `start` attributes and adds `list-style-type` definition as a value for the `style` attribute.\n * The `\"default\"` values are removed and not present in the view/data.\n */ function downcastListItemAttributes(attributeStrategies) {\n    return (dispatcher)=>{\n        for (const strategy of attributeStrategies){\n            dispatcher.on(`attribute:${strategy.attributeName}:listItem`, (evt, data, conversionApi)=>{\n                const viewWriter = conversionApi.writer;\n                const currentElement = data.item;\n                const previousElement = getSiblingListItem(currentElement.previousSibling, {\n                    sameIndent: true,\n                    listIndent: currentElement.getAttribute('listIndent'),\n                    direction: 'backward'\n                });\n                const viewItem = conversionApi.mapper.toViewElement(currentElement);\n                // A case when elements represent different lists. We need to separate their container.\n                if (!areRepresentingSameList(currentElement, previousElement)) {\n                    viewWriter.breakContainer(viewWriter.createPositionBefore(viewItem));\n                }\n                strategy.setAttributeOnDowncast(viewWriter, data.attributeNewValue, viewItem.parent);\n            }, {\n                priority: 'low'\n            });\n        }\n    };\n    /**\n\t * Checks whether specified list items belong to the same list.\n\t */ function areRepresentingSameList(listItem1, listItem2) {\n        return listItem2 && listItem1.getAttribute('listType') === listItem2.getAttribute('listType') && listItem1.getAttribute('listIndent') === listItem2.getAttribute('listIndent') && listItem1.getAttribute('listStyle') === listItem2.getAttribute('listStyle') && listItem1.getAttribute('listReversed') === listItem2.getAttribute('listReversed') && listItem1.getAttribute('listStart') === listItem2.getAttribute('listStart');\n    }\n}\n/**\n * When indenting list, nested list should clear its value for the attributes or inherit from nested lists.\n *\n * ■ List item 1.\n * ■ List item 2.[]\n * ■ List item 3.\n * editor.execute( 'indentList' );\n *\n * ■ List item 1.\n *     ○ List item 2.[]\n * ■ List item 3.\n */ function fixListAfterIndentListCommand(editor, attributeStrategies) {\n    return (evt, changedItems)=>{\n        const root = changedItems[0];\n        const rootIndent = root.getAttribute('listIndent');\n        const itemsToUpdate = changedItems.filter((item)=>item.getAttribute('listIndent') === rootIndent);\n        // A case where a few list items are indented must be checked separately\n        // since `getSiblingListItem()` returns the first changed element.\n        // ■ List item 1.\n        //     ○ [List item 2.\n        //     ○ List item 3.]\n        // ■ List item 4.\n        //\n        // List items: `2` and `3` should be adjusted.\n        let previousSibling = null;\n        if (root.previousSibling.getAttribute('listIndent') + 1 !== rootIndent) {\n            previousSibling = getSiblingListItem(root.previousSibling, {\n                sameIndent: true,\n                direction: 'backward',\n                listIndent: rootIndent\n            });\n        }\n        editor.model.change((writer)=>{\n            for (const item of itemsToUpdate){\n                for (const strategy of attributeStrategies){\n                    if (strategy.appliesToListItem(item)) {\n                        const valueToSet = previousSibling == null ? strategy.defaultValue : previousSibling.getAttribute(strategy.attributeName);\n                        writer.setAttribute(strategy.attributeName, valueToSet, item);\n                    }\n                }\n            }\n        });\n    };\n}\n/**\n * When outdenting a list, a nested list should copy attribute values\n * from the previous sibling list item including the same value for the `listIndent` value.\n *\n * ■ List item 1.\n *     ○ List item 2.[]\n * ■ List item 3.\n *\n * editor.execute( 'outdentList' );\n *\n * ■ List item 1.\n * ■ List item 2.[]\n * ■ List item 3.\n */ function fixListAfterOutdentListCommand(editor, attributeStrategies) {\n    return (evt, changedItems)=>{\n        changedItems = changedItems.reverse().filter((item)=>item.is('element', 'listItem'));\n        if (!changedItems.length) {\n            return;\n        }\n        const indent = changedItems[0].getAttribute('listIndent');\n        const listType = changedItems[0].getAttribute('listType');\n        let listItem = changedItems[0].previousSibling;\n        // ■ List item 1.\n        //     ○ List item 2.\n        //     ○ List item 3.[]\n        // ■ List item 4.\n        //\n        // After outdenting a list, `List item 3` should inherit the `listStyle` attribute from `List item 1`.\n        //\n        // ■ List item 1.\n        //     ○ List item 2.\n        // ■ List item 3.[]\n        // ■ List item 4.\n        if (listItem.is('element', 'listItem')) {\n            while(listItem.getAttribute('listIndent') !== indent){\n                listItem = listItem.previousSibling;\n            }\n        } else {\n            listItem = null;\n        }\n        // Outdenting such a list should restore values based on `List item 4`.\n        // ■ List item 1.[]\n        //     ○ List item 2.\n        //     ○ List item 3.\n        // ■ List item 4.\n        if (!listItem) {\n            listItem = changedItems[changedItems.length - 1].nextSibling;\n        }\n        // And such a list should not modify anything.\n        // However, `listItem` can indicate a node below the list. Be sure that we have the `listItem` element.\n        // ■ List item 1.[]\n        //     ○ List item 2.\n        //     ○ List item 3.\n        // <paragraph>The later if check.</paragraph>\n        if (!listItem || !listItem.is('element', 'listItem')) {\n            return;\n        }\n        // Do not modify the list if found `listItem` represents other type of list than outdented list items.\n        if (listItem.getAttribute('listType') !== listType) {\n            return;\n        }\n        editor.model.change((writer)=>{\n            const itemsToUpdate = changedItems.filter((item)=>item.getAttribute('listIndent') === indent);\n            for (const item of itemsToUpdate){\n                for (const strategy of attributeStrategies){\n                    if (strategy.appliesToListItem(item)) {\n                        const attributeName = strategy.attributeName;\n                        const valueToSet = listItem.getAttribute(attributeName);\n                        writer.setAttribute(attributeName, valueToSet, item);\n                    }\n                }\n            }\n        });\n    };\n}\n/**\n * Each `listItem` element must have specified the `listStyle`, `listReversed` and `listStart` attributes\n * if they are enabled and supported by its `listType`.\n * This post-fixer checks whether inserted elements `listItem` elements should inherit the attribute values from\n * their sibling nodes or should use the default values.\n *\n * Paragraph[]\n * ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2. // ...\n * ■ List item 3. // ...\n *\n * editor.execute( 'bulletedList' )\n *\n * ■ Paragraph[]  // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2.\n * ■ List item 3.\n *\n * It also covers a such change:\n *\n * [Paragraph 1\n * Paragraph 2]\n * ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2. // ...\n * ■ List item 3. // ...\n *\n * editor.execute( 'numberedList' )\n *\n * 1. [Paragraph 1 // [listStyle=\"default\", listType=\"numbered\"]\n * 2. Paragraph 2] // [listStyle=\"default\", listType=\"numbered\"]\n * ■ List item 1.  // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2.  // ...\n * ■ List item 3.  // ...\n */ function fixListAttributesOnListItemElements(editor, attributeStrategies) {\n    return (writer)=>{\n        let wasFixed = false;\n        const insertedListItems = getChangedListItems(editor.model.document.differ.getChanges()).filter((item)=>{\n            // Don't touch todo lists. They are handled in another post-fixer.\n            return item.getAttribute('listType') !== 'todo';\n        });\n        if (!insertedListItems.length) {\n            return wasFixed;\n        }\n        // Check whether the last inserted element is next to the `listItem` element.\n        //\n        // ■ Paragraph[]  // <-- The inserted item.\n        // ■ List item 1.\n        let existingListItem = insertedListItems[insertedListItems.length - 1].nextSibling;\n        // If it doesn't, maybe the `listItem` was inserted at the end of the list.\n        //\n        // ■ List item 1.\n        // ■ Paragraph[]  // <-- The inserted item.\n        if (!existingListItem || !existingListItem.is('element', 'listItem')) {\n            existingListItem = insertedListItems[0].previousSibling;\n            if (existingListItem) {\n                const indent = insertedListItems[0].getAttribute('listIndent');\n                // But we need to find a `listItem` with the `listIndent=0` attribute.\n                // If doesn't, maybe the `listItem` was inserted at the end of the list.\n                //\n                // ■ List item 1.\n                //     ○ List item 2.\n                // ■ Paragraph[]  // <-- The inserted item.\n                while(existingListItem.is('element', 'listItem') && existingListItem.getAttribute('listIndent') !== indent){\n                    existingListItem = existingListItem.previousSibling;\n                    // If the item does not exist, most probably there is no other content in the editor. See: #8072.\n                    if (!existingListItem) {\n                        break;\n                    }\n                }\n            }\n        }\n        for (const strategy of attributeStrategies){\n            const attributeName = strategy.attributeName;\n            for (const item of insertedListItems){\n                if (!strategy.appliesToListItem(item)) {\n                    writer.removeAttribute(attributeName, item);\n                    continue;\n                }\n                if (!item.hasAttribute(attributeName)) {\n                    if (shouldInheritListType(existingListItem, item, strategy)) {\n                        writer.setAttribute(attributeName, existingListItem.getAttribute(attributeName), item);\n                    } else {\n                        writer.setAttribute(attributeName, strategy.defaultValue, item);\n                    }\n                    wasFixed = true;\n                } else {\n                    // Adjust the `listStyle`, `listReversed` and `listStart`\n                    // attributes for inserted (pasted) items. See #8160.\n                    //\n                    // ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n                    //     ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n                    //     ○ [] (selection is here)\n                    //\n                    // Then, pasting a list with different attributes (listStyle, listType):\n                    //\n                    // 1. First. // [listStyle=\"decimal\", listType=\"numbered\"]\n                    // 2. Second // [listStyle=\"decimal\", listType=\"numbered\"]\n                    //\n                    // The `listType` attribute will be corrected by the `ListEditing` converters.\n                    // We need to adjust the `listStyle` attribute. Expected structure:\n                    //\n                    // ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n                    //     ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n                    //     ○ First. // [listStyle=\"circle\", listType=\"bulleted\"]\n                    //     ○ Second // [listStyle=\"circle\", listType=\"bulleted\"]\n                    const previousSibling = item.previousSibling;\n                    if (shouldInheritListTypeFromPreviousItem(previousSibling, item, strategy.attributeName)) {\n                        writer.setAttribute(attributeName, previousSibling.getAttribute(attributeName), item);\n                        wasFixed = true;\n                    }\n                }\n            }\n        }\n        return wasFixed;\n    };\n}\n/**\n * Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n * should be copied from the `baseItem` element.\n *\n * The attribute should be copied if the inserted element does not have defined it and\n * the value for the element is other than default in the base element.\n */ function shouldInheritListType(baseItem, itemToChange, attributeStrategy) {\n    if (!baseItem) {\n        return false;\n    }\n    const baseListAttribute = baseItem.getAttribute(attributeStrategy.attributeName);\n    if (!baseListAttribute) {\n        return false;\n    }\n    if (baseListAttribute == attributeStrategy.defaultValue) {\n        return false;\n    }\n    if (baseItem.getAttribute('listType') !== itemToChange.getAttribute('listType')) {\n        return false;\n    }\n    return true;\n}\n/**\n * Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n * should be copied from previous list item.\n *\n * The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list.\n * Top-level lists are not normalized as we allow side-by-side list of different types.\n */ function shouldInheritListTypeFromPreviousItem(previousItem, itemToChange, attributeName) {\n    if (!previousItem || !previousItem.is('element', 'listItem')) {\n        return false;\n    }\n    if (itemToChange.getAttribute('listType') !== previousItem.getAttribute('listType')) {\n        return false;\n    }\n    const previousItemIndent = previousItem.getAttribute('listIndent');\n    if (previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute('listIndent')) {\n        return false;\n    }\n    const previousItemListAttribute = previousItem.getAttribute(attributeName);\n    if (!previousItemListAttribute || previousItemListAttribute === itemToChange.getAttribute(attributeName)) {\n        return false;\n    }\n    return true;\n}\n/**\n * Removes the `listStyle`, `listReversed` and `listStart` attributes from \"todo\" list items.\n */ function removeListItemAttributesFromTodoList(editor) {\n    return (writer)=>{\n        const todoListItems = getChangedListItems(editor.model.document.differ.getChanges()).filter((item)=>{\n            // Handle the todo lists only. The rest is handled in another post-fixer.\n            return item.getAttribute('listType') === 'todo' && (item.hasAttribute('listStyle') || item.hasAttribute('listReversed') || item.hasAttribute('listStart'));\n        });\n        if (!todoListItems.length) {\n            return false;\n        }\n        for (const item of todoListItems){\n            writer.removeAttribute('listStyle', item);\n            writer.removeAttribute('listReversed', item);\n            writer.removeAttribute('listStart', item);\n        }\n        return true;\n    };\n}\n/**\n * Restores the `listStyle` attribute after changing the list type.\n */ function restoreDefaultListStyle(editor) {\n    return (evt, changedItems)=>{\n        changedItems = changedItems.filter((item)=>item.is('element', 'listItem'));\n        editor.model.change((writer)=>{\n            for (const item of changedItems){\n                // Remove the attribute. Post-fixer will restore the proper value.\n                writer.removeAttribute('listStyle', item);\n            }\n        });\n    };\n}\n/**\n * Returns the `listItem` that was inserted or changed.\n *\n * @param changes The changes list returned by the differ.\n */ function getChangedListItems(changes) {\n    const items = [];\n    for (const change of changes){\n        const item = getItemFromChange(change);\n        if (item && item.is('element', 'listItem')) {\n            items.push(item);\n        }\n    }\n    return items;\n}\nfunction getItemFromChange(change) {\n    if (change.type === 'attribute') {\n        return change.range.start.nodeAfter;\n    }\n    if (change.type === 'insert') {\n        return change.position.nodeAfter;\n    }\n    return null;\n}\n\n/**\n * The legacy list properties feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/legacylistproperties/legacylistpropertiesediting~LegacyListPropertiesEditing\n * legacy list properties editing feature} and the\n * {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n */ class LegacyListProperties extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LegacyListPropertiesEditing,\n            ListPropertiesUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LegacyListProperties';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst attributeKey = 'todoListChecked';\n/**\n * The check to-do command.\n *\n * The command is registered by the {@link module:list/legacytodolist/legacytodolistediting~LegacyTodoListEditing} as\n * the `checkTodoList` editor command and it is also available via aliased `todoListCheck` name.\n */ class LegacyCheckTodoListCommand extends Command {\n    /**\n\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t *\n\t * @internal\n\t */ _selectedElements;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._selectedElements = [];\n        // Refresh command before executing to be sure all values are up to date.\n        // It is needed when selection has changed before command execution, in the same change block.\n        this.on('execute', ()=>{\n            this.refresh();\n        }, {\n            priority: 'highest'\n        });\n    }\n    /**\n\t * Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t */ refresh() {\n        this._selectedElements = this._getSelectedItems();\n        this.value = this._selectedElements.every((element)=>!!element.getAttribute(attributeKey));\n        this.isEnabled = !!this._selectedElements.length;\n    }\n    /**\n\t * Gets all to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t */ _getSelectedItems() {\n        const model = this.editor.model;\n        const schema = model.schema;\n        const selectionRange = model.document.selection.getFirstRange();\n        const startElement = selectionRange.start.parent;\n        const elements = [];\n        if (schema.checkAttribute(startElement, attributeKey)) {\n            elements.push(startElement);\n        }\n        for (const item of selectionRange.getItems()){\n            if (schema.checkAttribute(item, attributeKey) && !elements.includes(item)) {\n                elements.push(item);\n            }\n        }\n        return elements;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply\n\t * the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t * value to decide what it should do.\n\t */ execute(options = {}) {\n        this.editor.model.change((writer)=>{\n            for (const element of this._selectedElements){\n                const value = options.forceValue === undefined ? !this.value : options.forceValue;\n                if (value) {\n                    writer.setAttribute(attributeKey, true, element);\n                } else {\n                    writer.removeAttribute(attributeKey, element);\n                }\n            }\n        });\n    }\n}\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It converts the `listItem` model element to an unordered list with a {@link module:engine/view/uielement~UIElement checkbox element}\n * at the beginning of each list item. It also merges the list with surrounding lists (if available).\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param model Model instance.\n * @param onCheckboxChecked Callback function.\n * @returns Returns a conversion callback.\n */ function modelViewInsertion(model, onCheckboxChecked) {\n    return (evt, data, conversionApi)=>{\n        const consumable = conversionApi.consumable;\n        if (!consumable.test(data.item, 'insert') || !consumable.test(data.item, 'attribute:listType') || !consumable.test(data.item, 'attribute:listIndent')) {\n            return;\n        }\n        if (data.item.getAttribute('listType') != 'todo') {\n            return;\n        }\n        const modelItem = data.item;\n        consumable.consume(modelItem, 'insert');\n        consumable.consume(modelItem, 'attribute:listType');\n        consumable.consume(modelItem, 'attribute:listIndent');\n        consumable.consume(modelItem, 'attribute:todoListChecked');\n        const viewWriter = conversionApi.writer;\n        const viewItem = generateLiInUl(modelItem, conversionApi);\n        const isChecked = !!modelItem.getAttribute('todoListChecked');\n        const checkmarkElement = createCheckmarkElement(modelItem, viewWriter, isChecked, onCheckboxChecked);\n        const span = viewWriter.createContainerElement('span', {\n            class: 'todo-list__label__description'\n        });\n        viewWriter.addClass('todo-list', viewItem.parent);\n        viewWriter.insert(viewWriter.createPositionAt(viewItem, 0), checkmarkElement);\n        viewWriter.insert(viewWriter.createPositionAfter(checkmarkElement), span);\n        injectViewList(modelItem, viewItem, conversionApi, model);\n    };\n}\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */ function dataModelViewInsertion(model) {\n    return (evt, data, conversionApi)=>{\n        const consumable = conversionApi.consumable;\n        if (!consumable.test(data.item, 'insert') || !consumable.test(data.item, 'attribute:listType') || !consumable.test(data.item, 'attribute:listIndent')) {\n            return;\n        }\n        if (data.item.getAttribute('listType') != 'todo') {\n            return;\n        }\n        const modelItem = data.item;\n        consumable.consume(modelItem, 'insert');\n        consumable.consume(modelItem, 'attribute:listType');\n        consumable.consume(modelItem, 'attribute:listIndent');\n        consumable.consume(modelItem, 'attribute:todoListChecked');\n        const viewWriter = conversionApi.writer;\n        const viewItem = generateLiInUl(modelItem, conversionApi);\n        viewWriter.addClass('todo-list', viewItem.parent);\n        const label = viewWriter.createContainerElement('label', {\n            class: 'todo-list__label'\n        });\n        const checkbox = viewWriter.createEmptyElement('input', {\n            type: 'checkbox',\n            disabled: 'disabled'\n        });\n        const span = viewWriter.createContainerElement('span', {\n            class: 'todo-list__label__description'\n        });\n        if (modelItem.getAttribute('todoListChecked')) {\n            viewWriter.setAttribute('checked', 'checked', checkbox);\n        }\n        viewWriter.insert(viewWriter.createPositionAt(viewItem, 0), label);\n        viewWriter.insert(viewWriter.createPositionAt(label, 0), checkbox);\n        viewWriter.insert(viewWriter.createPositionAfter(checkbox), span);\n        injectViewList(modelItem, viewItem, conversionApi, model);\n    };\n}\n/**\n * A view-to-model converter for the checkbox element inside a view list item.\n *\n * It changes the `listType` of the model `listItem` to a `todo` value.\n * When a view checkbox element is marked as checked, an additional `todoListChecked=\"true\"` attribute is added to the model item.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */ const dataViewModelCheckmarkInsertion = (evt, data, conversionApi)=>{\n    const modelCursor = data.modelCursor;\n    const modelItem = modelCursor.parent;\n    const viewItem = data.viewItem;\n    if (viewItem.getAttribute('type') != 'checkbox' || modelItem.name != 'listItem' || !modelCursor.isAtStart) {\n        return;\n    }\n    if (!conversionApi.consumable.consume(viewItem, {\n        name: true\n    })) {\n        return;\n    }\n    const writer = conversionApi.writer;\n    writer.setAttribute('listType', 'todo', modelItem);\n    if (data.viewItem.hasAttribute('checked')) {\n        writer.setAttribute('todoListChecked', true, modelItem);\n    }\n    data.modelRange = writer.createRange(modelCursor);\n};\n/**\n * A model-to-view converter for the `listType` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes to `<ul class=\"todo-list\">` and a\n * {@link module:engine/view/uielement~UIElement checkbox UI element} is added at the beginning\n * of the list item element (or vice versa).\n *\n * This converter is preceded by {@link module:list/legacylist/legacyconverters~modelViewChangeType} and followed by\n * {@link module:list/legacylist/legacyconverters~modelViewMergeAfterChangeType} to handle splitting and merging surrounding lists\n * of the same type.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param onCheckedChange Callback fired after clicking the checkbox UI element.\n * @param view Editing view controller.\n * @returns Returns a conversion callback.\n */ function modelViewChangeType(onCheckedChange, view) {\n    return (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const viewItem = conversionApi.mapper.toViewElement(data.item);\n        const viewWriter = conversionApi.writer;\n        const labelElement = findLabel(viewItem, view);\n        if (data.attributeNewValue == 'todo') {\n            const isChecked = !!data.item.getAttribute('todoListChecked');\n            const checkmarkElement = createCheckmarkElement(data.item, viewWriter, isChecked, onCheckedChange);\n            const span = viewWriter.createContainerElement('span', {\n                class: 'todo-list__label__description'\n            });\n            const itemRange = viewWriter.createRangeIn(viewItem);\n            const nestedList = findNestedList(viewItem);\n            const descriptionStart = positionAfterUiElements(itemRange.start);\n            const descriptionEnd = nestedList ? viewWriter.createPositionBefore(nestedList) : itemRange.end;\n            const descriptionRange = viewWriter.createRange(descriptionStart, descriptionEnd);\n            viewWriter.addClass('todo-list', viewItem.parent);\n            viewWriter.move(descriptionRange, viewWriter.createPositionAt(span, 0));\n            viewWriter.insert(viewWriter.createPositionAt(viewItem, 0), checkmarkElement);\n            viewWriter.insert(viewWriter.createPositionAfter(checkmarkElement), span);\n        } else if (data.attributeOldValue == 'todo') {\n            const descriptionSpan = findDescription(viewItem, view);\n            viewWriter.removeClass('todo-list', viewItem.parent);\n            viewWriter.remove(labelElement);\n            viewWriter.move(viewWriter.createRangeIn(descriptionSpan), viewWriter.createPositionBefore(descriptionSpan));\n            viewWriter.remove(descriptionSpan);\n        }\n    };\n}\n/**\n * A model-to-view converter for the `todoListChecked` attribute change on the `listItem` model element.\n *\n * It marks the {@link module:engine/view/uielement~UIElement checkbox UI element} as checked.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param onCheckedChange Callback fired after clicking the checkbox UI element.\n * @returns Returns a conversion callback.\n */ function modelViewChangeChecked(onCheckedChange) {\n    return (evt, data, conversionApi)=>{\n        // Do not convert `todoListChecked` attribute when to-do list item has changed to other list item.\n        // This attribute will be removed by the model post fixer.\n        if (data.item.getAttribute('listType') != 'todo') {\n            return;\n        }\n        if (!conversionApi.consumable.consume(data.item, 'attribute:todoListChecked')) {\n            return;\n        }\n        const { mapper, writer: viewWriter } = conversionApi;\n        const isChecked = !!data.item.getAttribute('todoListChecked');\n        const viewItem = mapper.toViewElement(data.item);\n        // Because of m -> v position mapper we can be sure checkbox is always at the beginning.\n        const oldCheckmarkElement = viewItem.getChild(0);\n        const newCheckmarkElement = createCheckmarkElement(data.item, viewWriter, isChecked, onCheckedChange);\n        viewWriter.insert(viewWriter.createPositionAfter(oldCheckmarkElement), newCheckmarkElement);\n        viewWriter.remove(oldCheckmarkElement);\n    };\n}\n/**\n * A model-to-view position at zero offset mapper.\n *\n * This helper ensures that position inside todo-list in the view is mapped after the checkbox.\n *\n * It only handles the position at the beginning of a list item as other positions are properly mapped be the default mapper.\n */ function mapModelToViewPosition(view) {\n    return (evt, data)=>{\n        const modelPosition = data.modelPosition;\n        const parent = modelPosition.parent;\n        if (!parent.is('element', 'listItem') || parent.getAttribute('listType') != 'todo') {\n            return;\n        }\n        const viewLi = data.mapper.toViewElement(parent);\n        const descSpan = findDescription(viewLi, view);\n        if (descSpan) {\n            data.viewPosition = data.mapper.findPositionIn(descSpan, modelPosition.offset);\n        }\n    };\n}\n/**\n * Creates a checkbox UI element.\n */ function createCheckmarkElement(modelItem, viewWriter, isChecked, onChange) {\n    const uiElement = viewWriter.createUIElement('label', {\n        class: 'todo-list__label',\n        contenteditable: false\n    }, function(domDocument) {\n        const checkbox = createElement(document, 'input', {\n            type: 'checkbox',\n            tabindex: '-1'\n        });\n        if (isChecked) {\n            checkbox.setAttribute('checked', 'checked');\n        }\n        checkbox.addEventListener('change', ()=>onChange(modelItem));\n        const domElement = this.toDomElement(domDocument);\n        domElement.appendChild(checkbox);\n        return domElement;\n    });\n    return uiElement;\n}\n// Helper method to find label element inside li.\nfunction findLabel(viewItem, view) {\n    const range = view.createRangeIn(viewItem);\n    for (const value of range){\n        if (value.item.is('uiElement', 'label')) {\n            return value.item;\n        }\n    }\n}\nfunction findDescription(viewItem, view) {\n    const range = view.createRangeIn(viewItem);\n    for (const value of range){\n        if (value.item.is('containerElement', 'span') && value.item.hasClass('todo-list__label__description')) {\n            return value.item;\n        }\n    }\n}\n\nconst ITEM_TOGGLE_KEYSTROKE = /* #__PURE__ */ parseKeystroke('Ctrl+Enter');\n/**\n * The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n *\n * It registers the entire functionality of the {@link module:list/legacylist/legacylistediting~LegacyListEditing legacy list editing\n * plugin} and extends it with the commands:\n *\n * - `'todoList'`,\n * - `'checkTodoList'`,\n * - `'todoListCheck'` as an alias for `checkTodoList` command.\n */ class LegacyTodoListEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LegacyTodoListEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LegacyListEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const { editing, data, model } = editor;\n        // Extend schema.\n        model.schema.extend('listItem', {\n            allowAttributes: [\n                'todoListChecked'\n            ]\n        });\n        // Disallow todoListChecked attribute on other nodes than listItem with to-do listType.\n        model.schema.addAttributeCheck((context, attributeName)=>{\n            const item = context.last;\n            if (attributeName == 'todoListChecked' && item.name == 'listItem' && item.getAttribute('listType') != 'todo') {\n                return false;\n            }\n        });\n        // Register `todoList` command.\n        editor.commands.add('todoList', new LegacyListCommand(editor, 'todo'));\n        const checkTodoListCommand = new LegacyCheckTodoListCommand(editor);\n        // Register `checkTodoList` command and add `todoListCheck` command as an alias for backward compatibility.\n        editor.commands.add('checkTodoList', checkTodoListCommand);\n        editor.commands.add('todoListCheck', checkTodoListCommand);\n        // Define converters.\n        data.downcastDispatcher.on('insert:listItem', dataModelViewInsertion(model), {\n            priority: 'high'\n        });\n        data.upcastDispatcher.on('element:input', dataViewModelCheckmarkInsertion, {\n            priority: 'high'\n        });\n        editing.downcastDispatcher.on('insert:listItem', modelViewInsertion(model, (listItem)=>this._handleCheckmarkChange(listItem)), {\n            priority: 'high'\n        });\n        editing.downcastDispatcher.on('attribute:listType:listItem', modelViewChangeType((listItem)=>this._handleCheckmarkChange(listItem), editing.view));\n        editing.downcastDispatcher.on('attribute:todoListChecked:listItem', modelViewChangeChecked((listItem)=>this._handleCheckmarkChange(listItem)));\n        editing.mapper.on('modelToViewPosition', mapModelToViewPosition(editing.view));\n        data.mapper.on('modelToViewPosition', mapModelToViewPosition(editing.view));\n        // Jump at the end of the previous node on left arrow key press, when selection is after the checkbox.\n        //\n        // <blockquote><p>Foo</p></blockquote>\n        // <ul><li><checkbox/>{}Bar</li></ul>\n        //\n        // press: `<-`\n        //\n        // <blockquote><p>Foo{}</p></blockquote>\n        // <ul><li><checkbox/>Bar</li></ul>\n        //\n        this.listenTo(editing.view.document, 'arrowKey', jumpOverCheckmarkOnSideArrowKeyPress(model, editor.locale), {\n            context: 'li'\n        });\n        // Toggle check state of selected to-do list items on keystroke.\n        this.listenTo(editing.view.document, 'keydown', (evt, data)=>{\n            if (getCode(data) === ITEM_TOGGLE_KEYSTROKE) {\n                editor.execute('checkTodoList');\n                evt.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n        // Remove `todoListChecked` attribute when a host element is no longer a to-do list item.\n        const listItemsToFix = new Set();\n        this.listenTo(model, 'applyOperation', (evt, args)=>{\n            const operation = args[0];\n            if (operation.type == 'rename' && operation.oldName == 'listItem') {\n                const item = operation.position.nodeAfter;\n                if (item.hasAttribute('todoListChecked')) {\n                    listItemsToFix.add(item);\n                }\n            } else if (operation.type == 'changeAttribute' && operation.key == 'listType' && operation.oldValue === 'todo') {\n                for (const item of operation.range.getItems()){\n                    if (item.hasAttribute('todoListChecked') && item.getAttribute('listType') !== 'todo') {\n                        listItemsToFix.add(item);\n                    }\n                }\n            }\n        });\n        model.document.registerPostFixer((writer)=>{\n            let hasChanged = false;\n            for (const listItem of listItemsToFix){\n                writer.removeAttribute('todoListChecked', listItem);\n                hasChanged = true;\n            }\n            listItemsToFix.clear();\n            return hasChanged;\n        });\n        this._initAriaAnnouncements();\n    }\n    /**\n\t * Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t * to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t *\n\t * Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t * is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t * See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t */ _handleCheckmarkChange(listItem) {\n        const editor = this.editor;\n        const model = editor.model;\n        const previousSelectionRanges = Array.from(model.document.selection.getRanges());\n        model.change((writer)=>{\n            writer.setSelection(listItem, 'end');\n            editor.execute('checkTodoList');\n            writer.setSelection(previousSelectionRanges);\n        });\n    }\n    /**\n\t * Observe when user enters or leaves todo list and set proper aria value in global live announcer.\n\t * This allows screen readers to indicate when the user has entered and left the specified todo list.\n\t *\n\t * @internal\n\t */ _initAriaAnnouncements() {\n        const { model, ui, t } = this.editor;\n        let lastFocusedCodeBlock = null;\n        if (!ui) {\n            return;\n        }\n        model.document.selection.on('change:range', ()=>{\n            const focusParent = model.document.selection.focus.parent;\n            const lastElementIsTodoList = isLegacyTodoListItemElement(lastFocusedCodeBlock);\n            const currentElementIsTodoList = isLegacyTodoListItemElement(focusParent);\n            if (lastElementIsTodoList && !currentElementIsTodoList) {\n                ui.ariaLiveAnnouncer.announce(t('Leaving a to-do list'));\n            } else if (!lastElementIsTodoList && currentElementIsTodoList) {\n                ui.ariaLiveAnnouncer.announce(t('Entering a to-do list'));\n            }\n            lastFocusedCodeBlock = focusParent;\n        });\n    }\n}\n/**\n * Handles the left/right (LTR/RTL content) arrow key and moves the selection at the end of the previous block element\n * if the selection is just after the checkbox element. In other words, it jumps over the checkbox element when\n * moving the selection to the left/right (LTR/RTL).\n *\n * @returns Callback for 'keydown' events.\n */ function jumpOverCheckmarkOnSideArrowKeyPress(model, locale) {\n    return (eventInfo, domEventData)=>{\n        const direction = getLocalizedArrowKeyCodeDirection(domEventData.keyCode, locale.contentLanguageDirection);\n        if (direction != 'left') {\n            return;\n        }\n        const schema = model.schema;\n        const selection = model.document.selection;\n        if (!selection.isCollapsed) {\n            return;\n        }\n        const position = selection.getFirstPosition();\n        const parent = position.parent;\n        if (parent.name === 'listItem' && parent.getAttribute('listType') == 'todo' && position.isAtStart) {\n            const newRange = schema.getNearestSelectionRange(model.createPositionBefore(parent), 'backward');\n            if (newRange) {\n                model.change((writer)=>writer.setSelection(newRange));\n            }\n            domEventData.preventDefault();\n            domEventData.stopPropagation();\n            eventInfo.stop();\n        }\n    };\n}\n/**\n * Returns true if the given element is a list item model element of a to-do list.\n */ function isLegacyTodoListItemElement(element) {\n    return !!element && element.is('element', 'listItem') && element.getAttribute('listType') === 'todo';\n}\n\n/**\n * The legacy to-do list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/legacytodolist/legacytodolistediting~LegacyTodoListEditing legacy to-do list\n * editing feature} and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n */ class LegacyTodoList extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            LegacyTodoListEditing,\n            TodoListUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'LegacyTodoList';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nclass AdjacentListsSupport extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'AdjacentListsSupport';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        model.schema.register('listSeparator', {\n            allowWhere: '$block',\n            isBlock: true\n        });\n        editor.conversion.for('upcast')// Add a list separator element between similar list elements on upcast.\n        .add((dispatcher)=>{\n            dispatcher.on('element:ol', listSeparatorUpcastConverter());\n            dispatcher.on('element:ul', listSeparatorUpcastConverter());\n        })// View-to-model transformation.\n        .elementToElement({\n            model: 'listSeparator',\n            view: 'ck-list-separator'\n        });\n        // The list separator element should exist in the view, but should be invisible (hidden).\n        editor.conversion.for('editingDowncast').elementToElement({\n            model: 'listSeparator',\n            view: {\n                name: 'div',\n                classes: [\n                    'ck-list-separator',\n                    'ck-hidden'\n                ]\n            }\n        });\n        // The list separator element should not exist in the output data.\n        editor.conversion.for('dataDowncast').elementToElement({\n            model: 'listSeparator',\n            view: (modelElement, conversionApi)=>{\n                const viewElement = conversionApi.writer.createContainerElement('ck-list-separator');\n                conversionApi.writer.setCustomProperty('dataPipeline:transparentRendering', true, viewElement);\n                viewElement.getFillerOffset = ()=>null;\n                return viewElement;\n            }\n        });\n    }\n}\n/**\n * Inserts a list separator element between two lists of the same type (`ol` + `ol` or `ul` + `ul`).\n */ function listSeparatorUpcastConverter() {\n    return (evt, data, conversionApi)=>{\n        const element = data.viewItem;\n        const nextSibling = element.nextSibling;\n        if (!nextSibling) {\n            return;\n        }\n        if (element.name !== nextSibling.name) {\n            return;\n        }\n        if (!data.modelRange) {\n            Object.assign(data, conversionApi.convertChildren(data.viewItem, data.modelCursor));\n        }\n        const writer = conversionApi.writer;\n        const modelElement = writer.createElement('listSeparator');\n        // Try to insert a list separator element on the current model cursor position.\n        if (!conversionApi.safeInsert(modelElement, data.modelCursor)) {\n            return;\n        }\n        const parts = conversionApi.getSplitParts(modelElement);\n        // Extend the model range with the range of the created list separator element.\n        data.modelRange = writer.createRange(data.modelRange.start, writer.createPositionAfter(parts[parts.length - 1]));\n        conversionApi.updateConversionResult(modelElement, data);\n    };\n}\n\n/**\n * The document list feature.\n *\n * This is an obsolete plugin that exists for backward compatibility only.\n * Use the {@link module:list/list~List `List`} instead.\n *\n * @deprecated\n */ class DocumentList extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            List\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'DocumentList';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    constructor(editor){\n        super(editor);\n        /**\n\t\t * The `DocumentList` plugin is obsolete. Use `List` instead.\n\t\t *\n\t\t * @error plugin-obsolete-documentlist\n\t\t */ logWarning('plugin-obsolete-documentlist', {\n            pluginName: 'DocumentList'\n        });\n    }\n}\n\n/**\n * The document list properties feature.\n *\n * This is an obsolete plugin that exists for backward compatibility only.\n * Use the {@link module:list/listproperties~ListProperties `ListProperties`} instead.\n *\n * @deprecated\n */ class DocumentListProperties extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ListProperties\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'DocumentListProperties';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    constructor(editor){\n        super(editor);\n        /**\n\t\t * The `DocumentListProperties` plugin is obsolete. Use `ListProperties` instead.\n\t\t *\n\t\t * @error plugin-obsolete-documentlistproperties\n\t\t */ logWarning('plugin-obsolete-documentlistproperties', {\n            pluginName: 'DocumentListProperties'\n        });\n    }\n}\n\n/**\n * The to-do list feature.\n *\n * This is an obsolete plugin that exists for backward compatibility only.\n * Use the {@link module:list/todolist~TodoList `TodoList`} instead.\n *\n * @deprecated\n */ class TodoDocumentList extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TodoList\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TodoDocumentList';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    constructor(editor){\n        super(editor);\n        /**\n\t\t * The `TodoDocumentList` plugin is obsolete. Use `TodoList` instead.\n\t\t *\n\t\t * @error plugin-obsolete-tododocumentlist\n\t\t */ logWarning('plugin-obsolete-tododocumentlist', {\n            pluginName: 'TodoDocumentList'\n        });\n    }\n}\n\nexport { AdjacentListsSupport, DocumentList, DocumentListProperties, LegacyIndentCommand, LegacyList, LegacyListEditing, LegacyListProperties, LegacyListPropertiesEditing, LegacyListUtils, LegacyTodoList, LegacyTodoListEditing, List, ListCommand, ListEditing, ListIndentCommand, ListProperties, ListPropertiesEditing, ListPropertiesUI, ListPropertiesUtils, ListUI, ListUtils, TodoDocumentList, TodoList, TodoListEditing, TodoListUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/utils/listwalker\n */\n\nimport { first, toArray, type ArrayOrItem } from 'ckeditor5/src/utils.js';\nimport { isListItemBlock, type ListElement } from './model.js';\n\nimport type { Element, Node } from 'ckeditor5/src/engine.js';\n\n/**\n * Document list blocks iterator.\n */\nexport default class ListWalker {\n\t/**\n\t * The start list item block element.\n\t */\n\tprivate _startElement: Node;\n\n\t/**\n\t * The reference indent. Initialized by the indent of the start block.\n\t */\n\tprivate _referenceIndent: number;\n\n\t/**\n\t * The iterating direction.\n\t */\n\tprivate _isForward: boolean;\n\n\t/**\n\t * Whether start block should be included in the result (if it's matching other criteria).\n\t */\n\tprivate _includeSelf: boolean;\n\n\t/**\n\t * Additional attributes that must be the same for each block.\n\t */\n\tprivate _sameAttributes: Array<string>;\n\n\t/**\n\t * Whether blocks with the same indent level as the start block should be included in the result.\n\t */\n\tprivate _sameIndent: boolean;\n\n\t/**\n\t * Whether blocks with a lower indent level than the start block should be included in the result.\n\t */\n\tprivate _lowerIndent: boolean;\n\n\t/**\n\t * Whether blocks with a higher indent level than the start block should be included in the result.\n\t */\n\tprivate _higherIndent: boolean;\n\n\t/**\n\t * Creates a document list iterator.\n\t *\n\t * @param startElement The start list item block element.\n\t * @param options.direction The iterating direction.\n\t * @param options.includeSelf Whether start block should be included in the result (if it's matching other criteria).\n\t * @param options.sameAttributes Additional attributes that must be the same for each block.\n\t * @param options.sameIndent Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param options.lowerIndent Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t */\n\tconstructor(\n\t\tstartElement: Node,\n\t\toptions: ListWalkerOptions\n\t) {\n\t\tthis._startElement = startElement;\n\t\tthis._referenceIndent = startElement.getAttribute( 'listIndent' ) as number;\n\t\tthis._isForward = options.direction == 'forward';\n\t\tthis._includeSelf = !!options.includeSelf;\n\t\tthis._sameAttributes = toArray( options.sameAttributes || [] );\n\t\tthis._sameIndent = !!options.sameIndent;\n\t\tthis._lowerIndent = !!options.lowerIndent;\n\t\tthis._higherIndent = !!options.higherIndent;\n\t}\n\n\t/**\n\t * Performs only first step of iteration and returns the result.\n\t *\n\t * @param startElement The start list item block element.\n\t * @param options.direction The iterating direction.\n\t * @param options.includeSelf Whether start block should be included in the result (if it's matching other criteria).\n\t * @param options.sameAttributes Additional attributes that must be the same for each block.\n\t * @param options.sameIndent Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param options.lowerIndent Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t */\n\tpublic static first(\n\t\tstartElement: Node,\n\t\toptions: ListWalkerOptions\n\t): ListElement | null {\n\t\tconst walker = new this( startElement, options );\n\t\tconst iterator = walker[ Symbol.iterator ]();\n\n\t\treturn first( iterator );\n\t}\n\n\t/**\n\t * Iterable interface.\n\t */\n\tpublic* [ Symbol.iterator ](): Iterator<ListElement> {\n\t\tconst nestedItems: Array<ListElement> = [];\n\n\t\tfor ( const { node } of iterateSiblingListBlocks( this._getStartNode(), this._isForward ? 'forward' : 'backward' ) ) {\n\t\t\tconst indent = node.getAttribute( 'listIndent' );\n\n\t\t\t// Leaving a nested list.\n\t\t\tif ( indent < this._referenceIndent ) {\n\t\t\t\t// Abort searching blocks.\n\t\t\t\tif ( !this._lowerIndent ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// While searching for lower indents, update the reference indent to find another parent in the next step.\n\t\t\t\tthis._referenceIndent = indent;\n\t\t\t}\n\t\t\t// Entering a nested list.\n\t\t\telse if ( indent > this._referenceIndent ) {\n\t\t\t\t// Ignore nested blocks.\n\t\t\t\tif ( !this._higherIndent ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Collect nested blocks to verify if they are really nested, or it's a different item.\n\t\t\t\tif ( !this._isForward ) {\n\t\t\t\t\tnestedItems.push( node );\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Same indent level block.\n\t\t\telse {\n\t\t\t\t// Ignore same indent block.\n\t\t\t\tif ( !this._sameIndent ) {\n\t\t\t\t\t// While looking for nested blocks, stop iterating while encountering first same indent block.\n\t\t\t\t\tif ( this._higherIndent ) {\n\t\t\t\t\t\t// No more nested blocks so yield nested items.\n\t\t\t\t\t\tif ( nestedItems.length ) {\n\t\t\t\t\t\t\tyield* nestedItems;\n\t\t\t\t\t\t\tnestedItems.length = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Abort if item has any additionally specified attribute different.\n\t\t\t\tif ( this._sameAttributes.some( attr => node.getAttribute( attr ) !== this._startElement.getAttribute( attr ) ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// There is another block for the same list item so the nested items were in the same list item.\n\t\t\tif ( nestedItems.length ) {\n\t\t\t\tyield* nestedItems;\n\t\t\t\tnestedItems.length = 0;\n\t\t\t}\n\n\t\t\tyield node;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the model element to start iterating.\n\t */\n\tprivate _getStartNode() {\n\t\tif ( this._includeSelf ) {\n\t\t\treturn this._startElement;\n\t\t}\n\n\t\treturn this._isForward ?\n\t\t\tthis._startElement.nextSibling :\n\t\t\tthis._startElement.previousSibling;\n\t}\n}\n\n/**\n * Iterates sibling list blocks starting from the given node.\n *\n * @internal\n * @param node The model node.\n * @param direction Iteration direction.\n * @returns The object with `node` and `previous` {@link module:engine/model/element~Element blocks}.\n */\nexport function* iterateSiblingListBlocks(\n\tnode: Node | null,\n\tdirection: 'forward' | 'backward' = 'forward'\n): IterableIterator<ListIteratorValue> {\n\tconst isForward = direction == 'forward';\n\tconst previousNodesByIndent: Array<ListElement> = []; // Last seen nodes of lower indented lists.\n\tlet previous = null;\n\n\twhile ( isListItemBlock( node ) ) {\n\t\tlet previousNodeInList = null; // It's like `previous` but has the same indent as current node.\n\n\t\tif ( previous ) {\n\t\t\tconst nodeIndent = node.getAttribute( 'listIndent' );\n\t\t\tconst previousNodeIndent = previous.getAttribute( 'listIndent' );\n\n\t\t\t// Let's find previous node for the same indent.\n\t\t\t// We're going to need that when we get back to previous indent.\n\t\t\tif ( nodeIndent > previousNodeIndent ) {\n\t\t\t\tpreviousNodesByIndent[ previousNodeIndent ] = previous;\n\t\t\t}\n\t\t\t// Restore the one for given indent.\n\t\t\telse if ( nodeIndent < previousNodeIndent ) {\n\t\t\t\tpreviousNodeInList = previousNodesByIndent[ nodeIndent ];\n\t\t\t\tpreviousNodesByIndent.length = nodeIndent;\n\t\t\t}\n\t\t\t// Same indent.\n\t\t\telse {\n\t\t\t\tpreviousNodeInList = previous;\n\t\t\t}\n\t\t}\n\n\t\tyield { node, previous, previousNodeInList };\n\n\t\tprevious = node;\n\t\tnode = isForward ? node.nextSibling : node.previousSibling;\n\t}\n}\n\n/**\n * The iterable protocol over the list elements.\n *\n * @internal\n */\nexport class ListBlocksIterable {\n\tprivate _listHead: Element;\n\n\t/**\n\t * @param listHead The head element of a list.\n\t */\n\tconstructor( listHead: Element ) {\n\t\tthis._listHead = listHead;\n\t}\n\n\t/**\n\t * List blocks iterator.\n\t *\n\t * Iterates over all blocks of a list.\n\t */\n\tpublic [ Symbol.iterator ](): Iterator<ListIteratorValue> {\n\t\treturn iterateSiblingListBlocks( this._listHead, 'forward' );\n\t}\n}\n\n/**\n * Object returned by `iterateSiblingListBlocks()` when traversing a list.\n *\n * @internal\n */\nexport interface ListIteratorValue {\n\n\t/**\n\t * The current list node.\n\t */\n\tnode: ListElement;\n\n\t/**\n\t * The previous list node.\n\t */\n\tprevious: ListElement | null;\n\n\t/**\n\t * The previous list node at the same indent as current node.\n\t */\n\tpreviousNodeInList: ListElement | null;\n}\n\n/**\n * Document list blocks iterator options.\n */\nexport type ListWalkerOptions = {\n\tdirection?: 'forward' | 'backward';\n\tincludeSelf?: boolean;\n\tsameAttributes?: ArrayOrItem<string>;\n\tsameIndent?: boolean;\n\tlowerIndent?: boolean;\n\thigherIndent?: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/utils/model\n */\n\nimport type {\n\tDocumentFragment,\n\tElement,\n\tModel,\n\tNode,\n\tWriter,\n\tItem,\n\tSchema\n} from 'ckeditor5/src/engine.js';\n\nimport { uid, toArray, type ArrayOrItem } from 'ckeditor5/src/utils.js';\n\nimport ListWalker, { type ListWalkerOptions, iterateSiblingListBlocks } from './listwalker.js';\nimport { type ListType } from '../listediting.js';\n\n/**\n * The list item ID generator.\n *\n * @internal\n */\nexport class ListItemUid {\n\t/**\n\t * Returns the next ID.\n\t *\n\t * @internal\n\t */\n\t/* istanbul ignore next: static function definition -- @preserve */\n\tpublic static next(): string {\n\t\treturn uid();\n\t}\n}\n\n/**\n * An {@link module:engine/model/element~Element} that is known to be a list element.\n *\n * @internal\n */\nexport interface ListElement extends Element {\n\tgetAttribute( key: 'listItemId' ): string;\n\tgetAttribute( key: 'listIndent' ): number;\n\tgetAttribute( key: 'listType' ): ListType;\n\tgetAttribute( key: string ): unknown;\n}\n\n/**\n * Returns true if the given model node is a list item block.\n *\n * @internal\n */\nexport function isListItemBlock( node: Item | DocumentFragment | null ): node is ListElement {\n\treturn !!node && node.is( 'element' ) && node.hasAttribute( 'listItemId' );\n}\n\n/**\n * Returns an array with all elements that represents the same list item.\n *\n * It means that values for `listIndent`, and `listItemId` for all items are equal.\n *\n * @internal\n * @param listItem Starting list item element.\n * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included\n * in the result.\n */\nexport function getAllListItemBlocks(\n\tlistItem: Node,\n\toptions: {\n\t\thigherIndent?: boolean;\n\t} = {}\n): Array<ListElement> {\n\treturn [\n\t\t...getListItemBlocks( listItem, { ...options, direction: 'backward' } ),\n\t\t...getListItemBlocks( listItem, { ...options, direction: 'forward' } )\n\t];\n}\n\n/**\n * Returns an array with elements that represents the same list item in the specified direction.\n *\n * It means that values for `listIndent` and `listItemId` for all items are equal.\n *\n * **Note**: For backward search the provided item is not included, but for forward search it is included in the result.\n *\n * @internal\n * @param listItem Starting list item element.\n * @param options.direction Walking direction.\n * @param options.higherIndent Whether blocks with a higher indent level than the start block should be included in the result.\n */\nexport function getListItemBlocks(\n\tlistItem: Node,\n\toptions: {\n\t\tdirection?: 'forward' | 'backward';\n\t\thigherIndent?: boolean;\n\t} = {}\n): Array<ListElement> {\n\tconst isForward = options.direction == 'forward';\n\n\tconst items = Array.from( new ListWalker( listItem, {\n\t\t...options,\n\t\tincludeSelf: isForward,\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} ) );\n\n\treturn isForward ? items : items.reverse();\n}\n\n/**\n * Returns a list items nested inside the given list item.\n *\n * @internal\n */\nexport function getNestedListBlocks( listItem: Element ): Array<ListElement> {\n\treturn Array.from( new ListWalker( listItem, {\n\t\tdirection: 'forward',\n\t\thigherIndent: true\n\t} ) );\n}\n\n/**\n * Returns array of all blocks/items of the same list as given block (same indent, same type and properties).\n *\n * @internal\n * @param listItem Starting list item element.\n * @param options Additional list walker options to modify the range of returned list items.\n */\nexport function getListItems( listItem: Element, options?: ListWalkerOptions ): Array<ListElement> {\n\tconst backwardBlocks = new ListWalker( listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listType',\n\t\t...options\n\t} );\n\n\tconst forwardBlocks = new ListWalker( listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listType',\n\t\tincludeSelf: true,\n\t\tdirection: 'forward',\n\t\t...options\n\t} );\n\n\treturn [\n\t\t...Array.from( backwardBlocks ).reverse(),\n\t\t...forwardBlocks\n\t];\n}\n\n/**\n * Check if the given block is the first in the list item.\n *\n * @internal\n * @param listBlock The list block element.\n */\nexport function isFirstBlockOfListItem( listBlock: Node ): boolean {\n\tconst previousSibling = ListWalker.first( listBlock, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} );\n\n\tif ( !previousSibling ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Check if the given block is the last in the list item.\n *\n * @internal\n */\nexport function isLastBlockOfListItem( listBlock: Element ): boolean {\n\tconst nextSibling = ListWalker.first( listBlock, {\n\t\tdirection: 'forward',\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} );\n\n\tif ( !nextSibling ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n *\n * @internal\n * @param blocks The list of selected blocks.\n * @param options.withNested Whether should include nested list items.\n */\nexport function expandListBlocksToCompleteItems(\n\tblocks: ArrayOrItem<Element>,\n\toptions: { withNested?: boolean } = {}\n): Array<ListElement> {\n\tblocks = toArray( blocks );\n\n\tconst higherIndent = options.withNested !== false;\n\tconst allBlocks = new Set<ListElement>();\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const itemBlock of getAllListItemBlocks( block, { higherIndent } ) ) {\n\t\t\tallBlocks.add( itemBlock );\n\t\t}\n\t}\n\n\treturn sortBlocks( allBlocks );\n}\n\n/**\n * Expands the given list of selected blocks to include all the items of the lists they're in.\n *\n * @internal\n * @param blocks The list of selected blocks.\n */\nexport function expandListBlocksToCompleteList( blocks: ArrayOrItem<Element> ): Array<ListElement> {\n\tblocks = toArray( blocks );\n\n\tconst allBlocks = new Set<ListElement>();\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const itemBlock of getListItems( block ) ) {\n\t\t\tallBlocks.add( itemBlock );\n\t\t}\n\t}\n\n\treturn sortBlocks( allBlocks );\n}\n\n/**\n * Splits the list item just before the provided list block.\n *\n * @internal\n * @param listBlock The list block element.\n * @param writer The model writer.\n * @returns The array of updated blocks.\n */\nexport function splitListItemBefore(\n\tlistBlock: Element,\n\twriter: Writer\n): Array<ListElement> {\n\tconst blocks = getListItemBlocks( listBlock, { direction: 'forward' } );\n\tconst id = ListItemUid.next();\n\n\tfor ( const block of blocks ) {\n\t\twriter.setAttribute( 'listItemId', id, block );\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Merges the list item with the parent list item.\n *\n * @internal\n * @param listBlock The list block element.\n * @param parentBlock The list block element to merge with.\n * @param writer The model writer.\n * @returns The array of updated blocks.\n */\nexport function mergeListItemBefore(\n\tlistBlock: Node,\n\tparentBlock: Element,\n\twriter: Writer\n): Array<ListElement> {\n\tconst attributes: Record<string, unknown> = {};\n\n\tfor ( const [ key, value ] of parentBlock.getAttributes() ) {\n\t\tif ( key.startsWith( 'list' ) ) {\n\t\t\tattributes[ key ] = value;\n\t\t}\n\t}\n\n\tconst blocks = getListItemBlocks( listBlock, { direction: 'forward' } );\n\n\tfor ( const block of blocks ) {\n\t\twriter.setAttributes( attributes, block );\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Increases indentation of given list blocks.\n *\n * @internal\n * @param blocks The block or iterable of blocks.\n * @param writer The model writer.\n * @param options.expand Whether should expand the list of blocks to include complete list items.\n * @param options.indentBy The number of levels the indentation should change (could be negative).\n */\nexport function indentBlocks(\n\tblocks: ArrayOrItem<ListElement>,\n\twriter: Writer,\n\t{ expand, indentBy = 1 }: { expand?: boolean; indentBy?: number } = {}\n): Array<ListElement> {\n\tblocks = toArray( blocks );\n\n\t// Expand the selected blocks to contain the whole list items.\n\tconst allBlocks = expand ? expandListBlocksToCompleteItems( blocks ) : blocks;\n\n\tfor ( const block of allBlocks ) {\n\t\tconst blockIndent = block.getAttribute( 'listIndent' ) + indentBy;\n\n\t\tif ( blockIndent < 0 ) {\n\t\t\tremoveListAttributes( block, writer );\n\t\t} else {\n\t\t\twriter.setAttribute( 'listIndent', blockIndent, block );\n\t\t}\n\t}\n\n\treturn allBlocks;\n}\n\n/**\n * Decreases indentation of given list of blocks. If the indentation of some blocks matches the indentation\n * of surrounding blocks, they get merged together.\n *\n * @internal\n * @param blocks The block or iterable of blocks.\n * @param writer The model writer.\n */\nexport function outdentBlocksWithMerge(\n\tblocks: ArrayOrItem<ListElement>,\n\twriter: Writer\n): Array<ListElement> {\n\tblocks = toArray( blocks );\n\n\t// Expand the selected blocks to contain the whole list items.\n\tconst allBlocks = expandListBlocksToCompleteItems( blocks );\n\tconst visited = new Set<ListElement>();\n\n\tconst referenceIndent = Math.min( ...allBlocks.map( block => block.getAttribute( 'listIndent' ) ) );\n\tconst parentBlocks = new Map();\n\n\t// Collect parent blocks before the list structure gets altered.\n\tfor ( const block of allBlocks ) {\n\t\tparentBlocks.set( block, ListWalker.first( block, { lowerIndent: true } ) );\n\t}\n\n\tfor ( const block of allBlocks ) {\n\t\tif ( visited.has( block ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvisited.add( block );\n\n\t\tconst blockIndent = block.getAttribute( 'listIndent' ) - 1;\n\n\t\tif ( blockIndent < 0 ) {\n\t\t\tremoveListAttributes( block, writer );\n\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Merge with parent list item while outdenting and indent matches reference indent.\n\t\tif ( block.getAttribute( 'listIndent' ) == referenceIndent ) {\n\t\t\tconst mergedBlocks = mergeListItemIfNotLast( block, parentBlocks.get( block ), writer );\n\n\t\t\t// All list item blocks are updated while merging so add those to visited set.\n\t\t\tfor ( const mergedBlock of mergedBlocks ) {\n\t\t\t\tvisited.add( mergedBlock );\n\t\t\t}\n\n\t\t\t// The indent level was updated while merging so continue to next block.\n\t\t\tif ( mergedBlocks.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\twriter.setAttribute( 'listIndent', blockIndent, block );\n\t}\n\n\treturn sortBlocks( visited );\n}\n\n/**\n * Removes all list attributes from the given blocks.\n *\n * @internal\n * @param blocks The block or iterable of blocks.\n * @param writer The model writer.\n * @returns Array of altered blocks.\n */\nexport function removeListAttributes(\n\tblocks: ArrayOrItem<Element>,\n\twriter: Writer\n): Array<Element> {\n\tblocks = toArray( blocks );\n\n\t// Convert simple list items to plain paragraphs.\n\tfor ( const block of blocks ) {\n\t\tif ( block.is( 'element', 'listItem' ) ) {\n\t\t\twriter.rename( block, 'paragraph' );\n\t\t}\n\t}\n\n\t// Remove list attributes.\n\tfor ( const block of blocks ) {\n\t\tfor ( const attributeKey of block.getAttributeKeys() ) {\n\t\t\tif ( attributeKey.startsWith( 'list' ) ) {\n\t\t\t\twriter.removeAttribute( attributeKey, block );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Checks whether the given blocks are related to a single list item.\n *\n * @internal\n * @param blocks The list block elements.\n */\nexport function isSingleListItem( blocks: Array<Node> ): boolean {\n\tif ( !blocks.length ) {\n\t\treturn false;\n\t}\n\n\tconst firstItemId = blocks[ 0 ].getAttribute( 'listItemId' );\n\n\tif ( !firstItemId ) {\n\t\treturn false;\n\t}\n\n\treturn !blocks.some( item => item.getAttribute( 'listItemId' ) != firstItemId );\n}\n\n/**\n * Modifies the indents of list blocks following the given list block so the indentation is valid after\n * the given block is no longer a list item.\n *\n * @internal\n * @param lastBlock The last list block that has become a non-list element.\n * @param writer The model writer.\n * @returns Array of altered blocks.\n */\nexport function outdentFollowingItems( lastBlock: Element, writer: Writer ): Array<ListElement> {\n\tconst changedBlocks = [];\n\n\t// Start from the model item that is just after the last turned-off item.\n\tlet currentIndent = Number.POSITIVE_INFINITY;\n\n\t// Correct indent of all items after the last turned off item.\n\t// Rules that should be followed:\n\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t//    will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t//    should not end up as a child of any of list items that they were not children of before.\n\t// 3. All other items should have their indent changed relatively to it's parent.\n\t//\n\t// For example:\n\t// 1  * --------\n\t// 2     * --------\n\t// 3        * --------\t\t\t<-- this is turned off.\n\t// 4           * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t// 5              * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t// 6        * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t// 7           * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t// 8     * --------\t\t\t\t<-- this has to become indent = 0.\n\t// 9        * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t// 10          * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t// 11          * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t// 13    * --------\n\t// 14       * --------\n\t//\n\t// After turning off 3 the list becomes:\n\t//\n\t// 1  * --------\n\t// 2     * --------\n\t//\n\t// 3  --------\n\t//\n\t// 4  * --------\n\t// 5     * --------\n\t// 6  * --------\n\t// 7     * --------\n\t// 8  * --------\n\t// 9     * --------\n\t// 10       * --------\n\t// 11       * --------\n\t// 12 * --------\n\t// 13    * --------\n\t// 14       * --------\n\t//\n\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t// less conversion (faster).\n\tfor ( const { node } of iterateSiblingListBlocks( lastBlock.nextSibling, 'forward' ) ) {\n\t\t// Check each next list item, as long as its indent is higher than 0.\n\t\tconst indent = node.getAttribute( 'listIndent' );\n\n\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\tif ( indent == 0 ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// We check if that's item indent is lower than current relative indent.\n\t\tif ( indent < currentIndent ) {\n\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\tcurrentIndent = indent;\n\t\t}\n\n\t\t// Fix indent relatively to current relative indent.\n\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\tconst newIndent = indent - currentIndent;\n\n\t\twriter.setAttribute( 'listIndent', newIndent, node );\n\t\tchangedBlocks.push( node );\n\t}\n\n\treturn changedBlocks;\n}\n\n/**\n * Returns the array of given blocks sorted by model indexes (document order).\n *\n * @internal\n */\nexport function sortBlocks<T extends Element>( blocks: Iterable<T> ): Array<T> {\n\treturn Array.from( blocks )\n\t\t.filter( block => block.root.rootName !== '$graveyard' )\n\t\t.sort( ( a, b ) => a.index! - b.index! );\n}\n\n/**\n * Returns a selected block object. If a selected object is inline or when there is no selected\n * object, `null` is returned.\n *\n * @internal\n * @param model The instance of editor model.\n * @returns Selected block object or `null`.\n */\nexport function getSelectedBlockObject( model: Model ): Element | null {\n\tconst selectedElement = model.document.selection.getSelectedElement();\n\n\tif ( !selectedElement ) {\n\t\treturn null;\n\t}\n\n\tif ( model.schema.isObject( selectedElement ) && model.schema.isBlock( selectedElement ) ) {\n\t\treturn selectedElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Checks whether the given block can be replaced by a listItem.\n *\n * Note that this is possible only when multiBlock = false option is set in feature config.\n *\n * @param block A block to be tested.\n * @param schema The schema of the document.\n */\nexport function canBecomeSimpleListItem( block: Element, schema: Schema ): boolean {\n\treturn schema.checkChild( block.parent as Element, 'listItem' ) && schema.checkChild( block, '$text' ) && !schema.isObject( block );\n}\n\n/**\n * Returns true if listType is of type `numbered` or `customNumbered`.\n */\nexport function isNumberedListType( listType: ListType ): boolean {\n\treturn listType == 'numbered' || listType == 'customNumbered';\n}\n\n/**\n * Merges a given block to the given parent block if parent is a list item and there is no more blocks in the same item.\n */\nfunction mergeListItemIfNotLast(\n\tblock: ListElement,\n\tparentBlock: ListElement,\n\twriter: Writer\n) {\n\tconst parentItemBlocks = getListItemBlocks( parentBlock, { direction: 'forward' } );\n\n\t// Merge with parent only if outdented item wasn't the last one in its parent.\n\t// Merge:\n\t// * a\t\t\t->\t\t* a\n\t//   * [b]\t\t->\t\t  b\n\t//   c\t\t\t->\t\t  c\n\t// Don't merge:\n\t// * a\t\t\t->\t\t* a\n\t//   * [b]\t\t-> \t\t* b\n\t// * c\t\t\t->\t\t* c\n\tif ( parentItemBlocks.pop()!.index! > block.index! ) {\n\t\treturn mergeListItemBefore( block, parentBlock, writer );\n\t}\n\n\treturn [];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/listindentcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { DocumentSelection, Element } from 'ckeditor5/src/engine.js';\n\nimport {\n\texpandListBlocksToCompleteItems,\n\tindentBlocks,\n\tisFirstBlockOfListItem,\n\tisListItemBlock,\n\tisSingleListItem,\n\toutdentBlocksWithMerge,\n\tsortBlocks,\n\tsplitListItemBefore,\n\ttype ListElement\n} from './utils/model.js';\nimport ListWalker from './utils/listwalker.js';\n\n/**\n * The document list indent command. It is used by the {@link module:list/list~List list feature}.\n */\nexport default class ListIndentCommand extends Command {\n\t/**\n\t * Determines by how much the command will change the list item's indent attribute.\n\t */\n\tprivate readonly _direction: 'forward' | 'backward';\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */\n\tconstructor( editor: Editor, indentDirection: 'forward' | 'backward' ) {\n\t\tsuper( editor );\n\n\t\tthis._direction = indentDirection;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst blocks = getSelectedListBlocks( model.document.selection );\n\n\t\tmodel.change( writer => {\n\t\t\tconst changedBlocks = [];\n\n\t\t\t// Handle selection contained in the single list item and starting in the following blocks.\n\t\t\tif ( isSingleListItem( blocks ) && !isFirstBlockOfListItem( blocks[ 0 ] ) ) {\n\t\t\t\t// Allow increasing indent of following list item blocks.\n\t\t\t\tif ( this._direction == 'forward' ) {\n\t\t\t\t\tchangedBlocks.push( ...indentBlocks( blocks, writer ) );\n\t\t\t\t}\n\n\t\t\t\t// For indent make sure that indented blocks have a new ID.\n\t\t\t\t// For outdent just split blocks from the list item (give them a new IDs).\n\t\t\t\tchangedBlocks.push( ...splitListItemBefore( blocks[ 0 ], writer ) );\n\t\t\t}\n\t\t\t// More than a single list item is selected, or the first block of list item is selected.\n\t\t\telse {\n\t\t\t\t// Now just update the attributes of blocks.\n\t\t\t\tif ( this._direction == 'forward' ) {\n\t\t\t\t\tchangedBlocks.push( ...indentBlocks( blocks, writer, { expand: true } ) );\n\t\t\t\t} else {\n\t\t\t\t\tchangedBlocks.push( ...outdentBlocksWithMerge( blocks, writer ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Align the list item type to match the previous list item (from the same list).\n\t\t\tfor ( const block of changedBlocks ) {\n\t\t\t\t// This block become a plain block (for example a paragraph).\n\t\t\t\tif ( !block.hasAttribute( 'listType' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst previousItemBlock = ListWalker.first( block, { sameIndent: true } );\n\n\t\t\t\tif ( previousItemBlock ) {\n\t\t\t\t\twriter.setAttribute( 'listType', previousItemBlock.getAttribute( 'listType' ), block );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */\n\tprivate _fireAfterExecute( changedBlocks: Array<Element> ) {\n\t\tthis.fire<ListIndentCommandAfterExecuteEvent>( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled(): boolean {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tlet blocks = getSelectedListBlocks( this.editor.model.document.selection );\n\t\tlet firstBlock = blocks[ 0 ];\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\tif ( this._direction == 'backward' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// A single block of a list item is selected, so it could be indented as a sublist.\n\t\tif ( isSingleListItem( blocks ) && !isFirstBlockOfListItem( blocks[ 0 ] ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tblocks = expandListBlocksToCompleteItems( blocks );\n\t\tfirstBlock = blocks[ 0 ];\n\n\t\t// Check if there is any list item before selected items that could become a parent of selected items.\n\t\tconst siblingItem = ListWalker.first( firstBlock, { sameIndent: true } );\n\n\t\tif ( !siblingItem ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( siblingItem.getAttribute( 'listType' ) == firstBlock.getAttribute( 'listType' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n/**\n * Returns an array of selected blocks truncated to the first non list block element.\n */\nfunction getSelectedListBlocks( selection: DocumentSelection ) {\n\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\tconst firstNonListBlockIndex = blocks.findIndex( block => !isListItemBlock( block ) );\n\n\tif ( firstNonListBlockIndex != -1 ) {\n\t\tblocks.length = firstNonListBlockIndex;\n\t}\n\n\treturn blocks as Array<ListElement>;\n}\n\n/**\n * Event fired by the {@link ~ListIndentCommand#execute} method.\n *\n * It allows to execute an action after executing the {@link module:list/list/listcommand~ListCommand#execute}\n * method, for example adjusting attributes of changed list items.\n *\n * @internal\n * @eventName ~ListIndentCommand#afterExecute\n */\nexport type ListIndentCommandAfterExecuteEvent = {\n\tname: 'afterExecute';\n\targs: [ changedBlocks: Array<Element> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/listcommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport {\n\tsplitListItemBefore,\n\texpandListBlocksToCompleteItems,\n\tgetListItemBlocks,\n\tgetListItems,\n\tremoveListAttributes,\n\toutdentFollowingItems,\n\tListItemUid,\n\tsortBlocks,\n\tgetSelectedBlockObject,\n\tisListItemBlock,\n\tcanBecomeSimpleListItem\n} from './utils/model.js';\nimport { type ListType } from './listediting.js';\nimport type { ListWalkerOptions } from './utils/listwalker.js';\n\n/**\n * The list command. It is used by the {@link module:list/list~List list feature}.\n */\nexport default class ListCommand extends Command {\n\t/**\n\t * The type of the list created by the command.\n\t */\n\tpublic readonly type: ListType;\n\n\t/**\n\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tpublic declare value: boolean;\n\n\t/**\n\t * List Walker options that change the range of the list items to be changed when the selection is collapsed within a list item.\n\t *\n\t * In a multi-level list, when the selection is collapsed within a list item, instead of changing only the list items of the same list\n\t * type and current indent level, the entire list structure is changed (all list items at all indent levels of any list type).\n\t */\n\tprivate readonly _listWalkerOptions?: ListWalkerOptions;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param type List type that will be handled by this command.\n\t */\n\tconstructor( editor: Editor, type: ListType, options: { multiLevel?: boolean } = {} ) {\n\t\tsuper( editor );\n\n\t\tthis.type = type;\n\n\t\tthis._listWalkerOptions = options.multiLevel ? {\n\t\t\thigherIndent: true,\n\t\t\tlowerIndent: true,\n\t\t\tsameAttributes: []\n\t\t} :\tundefined;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false` it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t * @param options.additionalAttributes Additional attributes that are set for list items when the command is executed.\n\t */\n\tpublic override execute( options: { forceValue?: boolean; additionalAttributes?: Record<string, unknown> } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => model.schema.checkAttribute( block, 'listType' ) || canBecomeSimpleListItem( block, model.schema ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( turnOff ) {\n\t\t\t\tconst lastBlock = blocks[ blocks.length - 1 ];\n\n\t\t\t\t// Split the first block from the list item.\n\t\t\t\tconst itemBlocks = getListItemBlocks( lastBlock, { direction: 'forward' } );\n\t\t\t\tconst changedBlocks = [];\n\n\t\t\t\tif ( itemBlocks.length > 1 ) {\n\t\t\t\t\tchangedBlocks.push( ...splitListItemBefore( itemBlocks[ 1 ], writer ) );\n\t\t\t\t}\n\n\t\t\t\t// Strip list attributes.\n\t\t\t\tchangedBlocks.push( ...removeListAttributes( blocks, writer ) );\n\n\t\t\t\t// Outdent items following the selected list item.\n\t\t\t\tchangedBlocks.push( ...outdentFollowingItems( lastBlock, writer ) );\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t\t// Changing type of list items for a collapsed selection inside a list item.\n\t\t\telse if ( ( selectedBlockObject || document.selection.isCollapsed ) && isListItemBlock( blocks[ 0 ] ) ) {\n\t\t\t\tconst changedBlocks = getListItems( selectedBlockObject || blocks[ 0 ], this._listWalkerOptions );\n\n\t\t\t\tfor ( const block of changedBlocks ) {\n\t\t\t\t\twriter.setAttributes( {\n\t\t\t\t\t\t...options.additionalAttributes,\n\t\t\t\t\t\tlistType: this.type\n\t\t\t\t\t}, block );\n\t\t\t\t}\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t\t// Turning on the list items for a non-collapsed selection.\n\t\t\telse {\n\t\t\t\tconst changedBlocks = [];\n\n\t\t\t\tfor ( const block of blocks ) {\n\t\t\t\t\t// Promote the given block to the list item.\n\t\t\t\t\tif ( !block.hasAttribute( 'listType' ) ) {\n\t\t\t\t\t\t// Rename block to a simple list item if this option is enabled.\n\t\t\t\t\t\tif ( !block.is( 'element', 'listItem' ) && canBecomeSimpleListItem( block, model.schema ) ) {\n\t\t\t\t\t\t\twriter.rename( block, 'listItem' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twriter.setAttributes( {\n\t\t\t\t\t\t\t...options.additionalAttributes,\n\t\t\t\t\t\t\tlistIndent: 0,\n\t\t\t\t\t\t\tlistItemId: ListItemUid.next(),\n\t\t\t\t\t\t\tlistType: this.type\n\t\t\t\t\t\t}, block );\n\n\t\t\t\t\t\tchangedBlocks.push( block );\n\t\t\t\t\t}\n\t\t\t\t\t// Change the type of list item.\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor ( const node of expandListBlocksToCompleteItems( block, { withNested: false } ) ) {\n\t\t\t\t\t\t\tif ( node.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\t\t\t\t\twriter.setAttributes( {\n\t\t\t\t\t\t\t\t\t...options.additionalAttributes,\n\t\t\t\t\t\t\t\t\tlistType: this.type\n\t\t\t\t\t\t\t\t}, node );\n\n\t\t\t\t\t\t\t\tchangedBlocks.push( node );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */\n\tprivate _fireAfterExecute( changedBlocks: Array<Element> ) {\n\t\tthis.fire<ListCommandAfterExecuteEvent>( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */\n\tprivate _getValue(): boolean {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tif ( !blocks.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const block of blocks ) {\n\t\t\tif ( block.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled(): boolean {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tif ( !blocks.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tfor ( const block of blocks ) {\n\t\t\tif ( schema.checkAttribute( block, 'listType' ) || canBecomeSimpleListItem( block, schema ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n/**\n * Event fired by the {@link ~ListCommand#execute} method.\n *\n * It allows to execute an action after executing the {@link ~ListCommand#execute} method,\n * for example adjusting attributes of changed list items.\n *\n * @internal\n * @eventName ~ListCommand#afterExecute\n */\nexport type ListCommandAfterExecuteEvent = {\n\tname: 'afterExecute';\n\targs: [ changedBlocks: Array<Element> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/listmergecommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { DocumentSelection, Element, Node, Selection } from 'ckeditor5/src/engine.js';\n\nimport {\n\tgetNestedListBlocks,\n\tindentBlocks,\n\tsortBlocks,\n\tisFirstBlockOfListItem,\n\tmergeListItemBefore,\n\tisSingleListItem,\n\tgetSelectedBlockObject,\n\tisListItemBlock,\n\ttype ListElement\n} from './utils/model.js';\nimport ListWalker from './utils/listwalker.js';\n\n/**\n * The document list merge command. It is used by the {@link module:list/list~List list feature}.\n */\nexport default class ListMergeCommand extends Command {\n\t/**\n\t * Whether list item should be merged before or after the selected block.\n\t */\n\tprivate readonly _direction: 'forward' | 'backward';\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param direction Whether list item should be merged before or after the selected block.\n\t */\n\tconstructor( editor: Editor, direction: 'forward' | 'backward' ) {\n\t\tsuper( editor );\n\n\t\tthis._direction = direction;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Merges list blocks together (depending on the {@link #constructor}'s `direction` parameter).\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param options Command options.\n\t * @param options.shouldMergeOnBlocksContentLevel When set `true`, merging will be performed together\n\t * with {@link module:engine/model/model~Model#deleteContent} to get rid of the inline content in the selection or take advantage\n\t * of the heuristics in `deleteContent()` that helps convert lists into paragraphs in certain cases.\n\t */\n\tpublic override execute(\n\t\t{ shouldMergeOnBlocksContentLevel = false }: { shouldMergeOnBlocksContentLevel?: boolean } = {}\n\t): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst changedBlocks: Array<Element> = [];\n\n\t\tmodel.change( writer => {\n\t\t\tconst { firstElement, lastElement } = this._getMergeSubjectElements( selection, shouldMergeOnBlocksContentLevel );\n\n\t\t\tconst firstIndent = firstElement.getAttribute( 'listIndent' ) || 0;\n\t\t\tconst lastIndent = lastElement.getAttribute( 'listIndent' );\n\t\t\tconst lastElementId = lastElement.getAttribute( 'listItemId' );\n\n\t\t\tif ( firstIndent != lastIndent ) {\n\t\t\t\tconst nestedLastElementBlocks = getNestedListBlocks( lastElement );\n\n\t\t\t\tchangedBlocks.push( ...indentBlocks( [ lastElement, ...nestedLastElementBlocks ], writer, {\n\t\t\t\t\tindentBy: firstIndent - lastIndent,\n\n\t\t\t\t\t// If outdenting, the entire sub-tree that follows must be included.\n\t\t\t\t\texpand: firstIndent < lastIndent\n\t\t\t\t} ) );\n\t\t\t}\n\n\t\t\tif ( shouldMergeOnBlocksContentLevel ) {\n\t\t\t\tlet sel: Selection | DocumentSelection = selection;\n\n\t\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\t\tsel = writer.createSelection( writer.createRange(\n\t\t\t\t\t\twriter.createPositionAt( firstElement, 'end' ),\n\t\t\t\t\t\twriter.createPositionAt( lastElement, 0 )\n\t\t\t\t\t) );\n\t\t\t\t}\n\n\t\t\t\t// Delete selected content. Replace entire content only for non-collapsed selection.\n\t\t\t\tmodel.deleteContent( sel, { doNotResetEntireContent: selection.isCollapsed } );\n\n\t\t\t\t// Get the last \"touched\" element after deleteContent call (can't use the lastElement because\n\t\t\t\t// it could get merged into the firstElement while deleting content).\n\t\t\t\tconst lastElementAfterDelete = sel.getLastPosition()!.parent;\n\n\t\t\t\t// Check if the element after it was in the same list item and adjust it if needed.\n\t\t\t\tconst nextSibling = lastElementAfterDelete.nextSibling;\n\n\t\t\t\tchangedBlocks.push( lastElementAfterDelete as Element );\n\n\t\t\t\tif ( nextSibling && nextSibling !== lastElement && nextSibling.getAttribute( 'listItemId' ) == lastElementId ) {\n\t\t\t\t\tchangedBlocks.push( ...mergeListItemBefore( nextSibling, lastElementAfterDelete, writer ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tchangedBlocks.push( ...mergeListItemBefore( lastElement, firstElement, writer ) );\n\t\t\t}\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */\n\tprivate _fireAfterExecute( changedBlocks: Array<Element> ) {\n\t\tthis.fire<ListMergeCommandAfterExecuteEvent>( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled(): boolean {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\n\t\tif ( selection.isCollapsed || selectedBlockObject ) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition()!.parent;\n\n\t\t\tif ( !isListItemBlock( positionParent ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst siblingNode = this._direction == 'backward' ?\n\t\t\t\tpositionParent.previousSibling :\n\t\t\t\tpositionParent.nextSibling;\n\n\t\t\tif ( !siblingNode ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( isSingleListItem( [ positionParent, siblingNode ] ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tconst lastPosition = selection.getLastPosition()!;\n\t\t\tconst firstPosition = selection.getFirstPosition()!;\n\n\t\t\t// If deleting within a single block of a list item, there's no need to merge anything.\n\t\t\t// The default delete should be executed instead.\n\t\t\tif ( lastPosition.parent === firstPosition.parent ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( !isListItemBlock( lastPosition.parent ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the boundary elements the merge should be executed for. These are not necessarily selection's first\n\t * and last position parents but sometimes sibling or even further blocks depending on the context.\n\t *\n\t * @param selection The selection the merge is executed for.\n\t * @param shouldMergeOnBlocksContentLevel When `true`, merge is performed together with\n\t * {@link module:engine/model/model~Model#deleteContent} to remove the inline content within the selection.\n\t */\n\tprivate _getMergeSubjectElements(\n\t\tselection: Selection | DocumentSelection,\n\t\tshouldMergeOnBlocksContentLevel: boolean\n\t) {\n\t\tconst model = this.editor.model;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\t\tlet firstElement, lastElement;\n\n\t\tif ( selection.isCollapsed || selectedBlockObject ) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition()!.parent as Node;\n\t\t\tconst isFirstBlock = isFirstBlockOfListItem( positionParent );\n\n\t\t\tif ( this._direction == 'backward' ) {\n\t\t\t\tlastElement = positionParent;\n\n\t\t\t\tif ( isFirstBlock && !shouldMergeOnBlocksContentLevel ) {\n\t\t\t\t\t// For the \"c\" as an anchorElement:\n\t\t\t\t\t//  * a\n\t\t\t\t\t//    * b\n\t\t\t\t\t//  * [c]  <-- this block should be merged with \"a\"\n\t\t\t\t\t// It should find \"a\" element to merge with:\n\t\t\t\t\t//  * a\n\t\t\t\t\t//    * b\n\t\t\t\t\t//    c\n\t\t\t\t\tfirstElement = ListWalker.first( positionParent, { sameIndent: true, lowerIndent: true } );\n\t\t\t\t} else {\n\t\t\t\t\tfirstElement = positionParent.previousSibling;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// In case of the forward merge there is no case as above, just merge with next sibling.\n\t\t\t\tfirstElement = positionParent;\n\t\t\t\tlastElement = positionParent.nextSibling;\n\t\t\t}\n\t\t} else {\n\t\t\tfirstElement = selection.getFirstPosition()!.parent;\n\t\t\tlastElement = selection.getLastPosition()!.parent;\n\t\t}\n\n\t\treturn {\n\t\t\tfirstElement: firstElement as ListElement,\n\t\t\tlastElement: lastElement as ListElement\n\t\t};\n\t}\n}\n\n/**\n * Event fired by the {@link ~ListMergeCommand#execute} method.\n *\n * It allows to execute an action after executing the {@link module:list/list/listcommand~ListCommand#execute}\n * method, for example adjusting attributes of changed list items.\n *\n * @internal\n * @eventName ~ListMergeCommand#afterExecute\n */\nexport type ListMergeCommandAfterExecuteEvent = {\n\tname: 'afterExecute';\n\targs: [ changedBlocks: Array<Element> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/listsplitcommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\n\nimport {\n\tisFirstBlockOfListItem,\n\tisListItemBlock,\n\tsortBlocks,\n\tsplitListItemBefore\n} from './utils/model.js';\n\n/**\n * The document list split command that splits the list item at the selection.\n *\n * It is used by the {@link module:list/list~List list feature}.\n */\nexport default class ListSplitCommand extends Command {\n\t/**\n\t * Whether list item should be split before or after the selected block.\n\t */\n\tprivate readonly _direction: 'before' | 'after';\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param direction Whether list item should be split before or after the selected block.\n\t */\n\tconstructor( editor: Editor, direction: 'before' | 'after' ) {\n\t\tsuper( editor );\n\n\t\tthis._direction = direction;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Splits the list item at the selection.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */\n\tpublic override execute(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.model.change( writer => {\n\t\t\tconst changedBlocks = splitListItemBefore( this._getStartBlock(), writer );\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @param changedBlocks The changed list elements.\n\t */\n\tprivate _fireAfterExecute( changedBlocks: Array<Element> ) {\n\t\tthis.fire<ListSplitCommandAfterExecuteEvent>( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst block = this._getStartBlock();\n\n\t\treturn selection.isCollapsed &&\n\t\t\tisListItemBlock( block ) &&\n\t\t\t!isFirstBlockOfListItem( block );\n\t}\n\n\t/**\n\t * Returns the model element that is the main focus of the command (according to the current selection and command direction).\n\t */\n\tprivate _getStartBlock() {\n\t\tconst doc = this.editor.model.document;\n\t\tconst positionParent = doc.selection.getFirstPosition()!.parent;\n\n\t\treturn ( this._direction == 'before' ? positionParent : positionParent.nextSibling ) as Element;\n\t}\n}\n\n/**\n * Event fired by the {@link ~ListSplitCommand#execute} method.\n *\n * It allows to execute an action after executing the {@link module:list/list/listcommand~ListCommand#execute}\n * method, for example adjusting attributes of changed list items.\n *\n * @internal\n * @eventName ~ListSplitCommand#afterExecute\n */\nexport type ListSplitCommandAfterExecuteEvent = {\n\tname: 'afterExecute';\n\targs: [ changedBlocks: Array<Element> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/listutils\n */\n\nimport type { Element, Node } from 'ckeditor5/src/engine.js';\nimport type { ArrayOrItem } from 'ckeditor5/src/utils.js';\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport {\n\ttype ListElement,\n\texpandListBlocksToCompleteItems,\n\texpandListBlocksToCompleteList,\n\tisFirstBlockOfListItem,\n\tisListItemBlock,\n\tisNumberedListType\n} from './utils/model.js';\nimport type { ListType } from './listediting.js';\n\n/**\n * A set of helpers related to document lists.\n */\nexport default class ListUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ListUtils' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Expands the given list of selected blocks to include all the items of the lists they're in.\n\t *\n\t * @param blocks The list of selected blocks.\n\t */\n\tpublic expandListBlocksToCompleteList( blocks: ArrayOrItem<Element> ): Array<Element> {\n\t\treturn expandListBlocksToCompleteList( blocks );\n\t}\n\n\t/**\n\t * Check if the given block is the first in the list item.\n\t *\n\t * @param listBlock The list block element.\n\t */\n\tpublic isFirstBlockOfListItem( listBlock: Element ): boolean {\n\t\treturn isFirstBlockOfListItem( listBlock );\n\t}\n\n\t/**\n\t * Returns true if the given model node is a list item block.\n\t *\n\t * @param node A model node.\n\t */\n\tpublic isListItemBlock( node: Node | null ): node is ListElement {\n\t\treturn isListItemBlock( node );\n\t}\n\n\t/**\n\t * Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n\t *\n\t * @param blocks The list of selected blocks.\n\t * @param options.withNested Whether should include nested list items.\n\t */\n\tpublic expandListBlocksToCompleteItems( blocks: ArrayOrItem<Element>, options: { withNested?: boolean } = {} ): Array<Element> {\n\t\treturn expandListBlocksToCompleteItems( blocks, options );\n\t}\n\n\t/**\n\t * Returns true if listType is of type `numbered` or `customNumbered`.\n\t */\n\tpublic isNumberedListType( listType: ListType ): boolean {\n\t\treturn isNumberedListType( listType );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/utils/view\n */\n\nimport type { DowncastWriter, ViewAttributeElement, ViewDocumentFragment, ViewElement, ViewNode } from 'ckeditor5/src/engine.js';\nimport { type ListType } from '../listediting.js';\n\n/**\n * Checks if view element is a list type (ul or ol).\n *\n * @internal\n */\nexport function isListView( viewElement: ViewNode | ViewDocumentFragment ): viewElement is ViewElement & { name: 'ul' | 'ol' } {\n\treturn viewElement.is( 'element', 'ol' ) || viewElement.is( 'element', 'ul' );\n}\n\n/**\n * Checks if view element is a list item (li).\n *\n * @internal\n */\nexport function isListItemView( viewElement: ViewNode | ViewDocumentFragment ): viewElement is ViewElement & { name: 'li' } {\n\treturn viewElement.is( 'element', 'li' );\n}\n\n/**\n * Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n *\n * Also, fixes non HTML compliant lists indents:\n *\n * ```\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI     (indent: 0)\n *     |-> OL                                  |-> OL\n *         |-> OL                                  |\n *         |   |-> OL                              |\n *         |       |-> OL                          |\n *         |           |-> LI (parent LIs: 1)      |-> LI (indent: 1)\n *         |-> LI (parent LIs: 1)                  |-> LI (indent: 1)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> OL                                      |\n *     |-> OL                                  |\n *          |-> OL                             |\n *              |-> LI (parent LIs: 0)         |-> LI        (indent: 0)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI         (indent: 0)\n * |-> OL                                          |-> OL\n *     |-> LI (parent LIs: 0)                          |-> LI (indent: 1)\n * ```\n *\n * @internal\n */\nexport function getIndent( listItem: ViewElement ): number {\n\tlet indent = 0;\n\tlet parent = listItem.parent;\n\n\twhile ( parent ) {\n\t\t// Each LI in the tree will result in an increased indent for HTML compliant lists.\n\t\tif ( isListItemView( parent ) ) {\n\t\t\tindent++;\n\t\t} else {\n\t\t\t// If however the list is nested in other list we should check previous sibling of any of the list elements...\n\t\t\tconst previousSibling = ( parent as ViewElement ).previousSibling;\n\n\t\t\t// ...because the we might need increase its indent:\n\t\t\t//\t\tbefore:                           fixed list:\n\t\t\t//\t\tOL                                OL\n\t\t\t//\t\t|-> LI (parent LIs: 0)            |-> LI         (indent: 0)\n\t\t\t//\t\t|-> OL                                |-> OL\n\t\t\t//\t\t    |-> LI (parent LIs: 0)                |-> LI (indent: 1)\n\t\t\tif ( previousSibling && isListItemView( previousSibling ) ) {\n\t\t\t\tindent++;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\treturn indent;\n}\n\n/**\n * Creates a list attribute element (ol or ul).\n *\n * @internal\n */\nexport function createListElement(\n\twriter: DowncastWriter,\n\tindent: number,\n\ttype: ListType,\n\tid = getViewElementIdForListType( type, indent )\n): ViewAttributeElement {\n\t// Negative priorities so that restricted editing attribute won't wrap lists.\n\treturn writer.createAttributeElement( getViewElementNameForListType( type ), null, {\n\t\tpriority: 2 * indent / 100 - 100,\n\t\tid\n\t} );\n}\n\n/**\n * Creates a list item attribute element (li).\n *\n * @internal\n */\nexport function createListItemElement(\n\twriter: DowncastWriter,\n\tindent: number,\n\tid: string\n): ViewAttributeElement {\n\t// Negative priorities so that restricted editing attribute won't wrap list items.\n\treturn writer.createAttributeElement( 'li', null, {\n\t\tpriority: ( 2 * indent + 1 ) / 100 - 100,\n\t\tid\n\t} );\n}\n\n/**\n * Returns a view element name for the given list type.\n *\n * @internal\n */\nexport function getViewElementNameForListType( type?: ListType ): 'ol' | 'ul' {\n\treturn type == 'numbered' || type == 'customNumbered' ? 'ol' : 'ul';\n}\n\n/**\n * Returns a view element ID for the given list type and indent.\n *\n * @internal\n */\nexport function getViewElementIdForListType( type?: ListType, indent?: number ): string {\n\treturn `list-${ type }-${ indent }`;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/utils/postfixers\n */\n\nimport type { Position, Writer } from 'ckeditor5/src/engine.js';\nimport { iterateSiblingListBlocks, type ListIteratorValue } from './listwalker.js';\nimport { getListItemBlocks, isListItemBlock, ListItemUid, type ListElement } from './model.js';\n\n/**\n * Based on the provided positions looks for the list head and stores it in the provided map.\n *\n * @internal\n * @param position The search starting position.\n * @param itemToListHead The map from list item element to the list head element.\n */\nexport function findAndAddListHeadToMap(\n\tposition: Position,\n\titemToListHead: Map<ListElement, ListElement>\n): void {\n\tconst previousNode = position.nodeBefore;\n\n\tif ( !isListItemBlock( previousNode ) ) {\n\t\tconst item = position.nodeAfter;\n\n\t\tif ( isListItemBlock( item ) ) {\n\t\t\titemToListHead.set( item, item );\n\t\t}\n\t} else {\n\t\tlet listHead = previousNode;\n\n\t\t// Previously, the loop below was defined like this:\n\t\t//\n\t\t// \t\tfor ( { node: listHead } of iterateSiblingListBlocks( listHead, 'backward' ) )\n\t\t//\n\t\t// Unfortunately, such a destructuring is incorrectly transpiled by Babel and the loop never ends.\n\t\t// See: https://github.com/ckeditor/ckeditor5-react/issues/345.\n\t\tfor ( const { node } of iterateSiblingListBlocks( listHead, 'backward' ) ) {\n\t\t\tlistHead = node;\n\n\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\titemToListHead.set( previousNode, listHead );\n\t}\n}\n\n/**\n * Scans the list starting from the given list head element and fixes items' indentation.\n *\n * @internal\n * @param listNodes The iterable of list nodes.\n * @param writer The model writer.\n * @returns Whether the model was modified.\n */\nexport function fixListIndents(\n\tlistNodes: Iterable<ListIteratorValue>,\n\twriter: Writer\n): boolean {\n\tlet maxIndent = 0; // Guards local sublist max indents that need fixing.\n\tlet prevIndent = -1; // Previous item indent.\n\tlet fixBy = null;\n\tlet applied = false;\n\n\tfor ( const { node } of listNodes ) {\n\t\tconst itemIndent = node.getAttribute( 'listIndent' );\n\n\t\tif ( itemIndent > maxIndent ) {\n\t\t\tlet newIndent;\n\n\t\t\tif ( fixBy === null ) {\n\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\tnewIndent = maxIndent;\n\t\t\t} else {\n\t\t\t\tif ( fixBy > itemIndent ) {\n\t\t\t\t\tfixBy = itemIndent;\n\t\t\t\t}\n\n\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t}\n\n\t\t\tif ( newIndent > prevIndent + 1 ) {\n\t\t\t\tnewIndent = prevIndent + 1;\n\t\t\t}\n\n\t\t\twriter.setAttribute( 'listIndent', newIndent, node );\n\n\t\t\tapplied = true;\n\t\t\tprevIndent = newIndent;\n\t\t} else {\n\t\t\tfixBy = null;\n\t\t\tmaxIndent = itemIndent + 1;\n\t\t\tprevIndent = itemIndent;\n\t\t}\n\t}\n\n\treturn applied;\n}\n\n/**\n * Scans the list starting from the given list head element and fixes items' types.\n *\n * @internal\n * @param listNodes The iterable of list nodes.\n * @param seenIds The set of already known IDs.\n * @param writer The model writer.\n * @returns Whether the model was modified.\n */\nexport function fixListItemIds(\n\tlistNodes: Iterable<ListIteratorValue>,\n\tseenIds: Set<string>,\n\twriter: Writer\n): boolean {\n\tconst visited = new Set();\n\tlet applied = false;\n\n\tfor ( const { node } of listNodes ) {\n\t\tif ( visited.has( node ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet listType = node.getAttribute( 'listType' );\n\t\tlet listItemId = node.getAttribute( 'listItemId' );\n\n\t\t// Use a new ID if this one was spot earlier (even in other list).\n\t\tif ( seenIds.has( listItemId ) ) {\n\t\t\tlistItemId = ListItemUid.next();\n\t\t}\n\n\t\tseenIds.add( listItemId );\n\n\t\t// Make sure that all items in a simple list have unique IDs.\n\t\tif ( node.is( 'element', 'listItem' ) ) {\n\t\t\tif ( node.getAttribute( 'listItemId' ) != listItemId ) {\n\t\t\t\twriter.setAttribute( 'listItemId', listItemId, node );\n\n\t\t\t\tapplied = true;\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor ( const block of getListItemBlocks( node, { direction: 'forward' } ) ) {\n\t\t\tvisited.add( block );\n\n\t\t\t// Use a new ID if a block of a bigger list item has different type.\n\t\t\tif ( block.getAttribute( 'listType' ) != listType ) {\n\t\t\t\tlistItemId = ListItemUid.next();\n\t\t\t\tlistType = block.getAttribute( 'listType' );\n\t\t\t}\n\n\t\t\tif ( block.getAttribute( 'listItemId' ) != listItemId ) {\n\t\t\t\twriter.setAttribute( 'listItemId', listItemId, block );\n\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn applied;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/converters\n */\n\nimport {\n\ttype DowncastAttributeEvent,\n\ttype DowncastWriter,\n\ttype EditingController,\n\ttype Element,\n\ttype ElementCreatorFunction,\n\ttype Mapper,\n\ttype Model,\n\ttype ModelConsumable,\n\ttype Node,\n\ttype UpcastElementEvent,\n\ttype ViewDocumentFragment,\n\ttype ViewElement,\n\ttype ViewRange,\n\ttype DowncastRemoveEvent,\n\ttype EditingView,\n\ttype MapperModelToViewPositionEvent,\n\ttype ViewTreeWalker,\n\ttype Schema\n} from 'ckeditor5/src/engine.js';\n\nimport type { GetCallback } from 'ckeditor5/src/utils.js';\n\nimport {\n\tgetAllListItemBlocks,\n\tgetListItemBlocks,\n\tisListItemBlock,\n\tisFirstBlockOfListItem,\n\tListItemUid,\n\ttype ListElement\n} from './utils/model.js';\n\nimport {\n\tcreateListElement,\n\tcreateListItemElement,\n\tgetIndent,\n\tisListView,\n\tisListItemView\n} from './utils/view.js';\n\nimport ListWalker, { iterateSiblingListBlocks } from './utils/listwalker.js';\nimport { findAndAddListHeadToMap } from './utils/postfixers.js';\n\nimport type {\n\tdefault as ListEditing,\n\tListEditingCheckAttributesEvent,\n\tListEditingCheckElementEvent,\n\tListItemAttributesMap,\n\tDowncastStrategy\n} from './listediting.js';\n\n/**\n * Returns the upcast converter for list items. It's supposed to work after the block converters (content inside list items) are converted.\n *\n * @internal\n */\nexport function listItemUpcastConverter(): GetCallback<UpcastElementEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, schema } = conversionApi;\n\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst items = Array.from( data.modelRange.getItems( { shallow: true } ) )\n\t\t\t.filter( ( item ): item is Element => schema.checkAttribute( item, 'listItemId' ) );\n\n\t\tif ( !items.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst listItemId = ListItemUid.next();\n\t\tconst listIndent = getIndent( data.viewItem );\n\t\tlet listType = data.viewItem.parent && data.viewItem.parent.is( 'element', 'ol' ) ? 'numbered' : 'bulleted';\n\n\t\t// Preserve list type if was already set (for example by to-do list feature).\n\t\tconst firstItemListType = items[ 0 ].getAttribute( 'listType' ) as string;\n\n\t\tif ( firstItemListType ) {\n\t\t\tlistType = firstItemListType;\n\t\t}\n\n\t\tconst attributes = {\n\t\t\tlistItemId,\n\t\t\tlistIndent,\n\t\t\tlistType\n\t\t};\n\n\t\tfor ( const item of items ) {\n\t\t\t// Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n\t\t\tif ( !item.hasAttribute( 'listItemId' ) ) {\n\t\t\t\twriter.setAttributes( attributes, item );\n\t\t\t}\n\t\t}\n\n\t\tif ( items.length > 1 ) {\n\t\t\t// Make sure that list item that contain only nested list will preserve paragraph for itself:\n\t\t\t//\t<ul>\n\t\t\t//\t\t<li>\n\t\t\t//\t\t\t<p></p>  <-- this one must be kept\n\t\t\t//\t\t\t<ul>\n\t\t\t//\t\t\t\t<li></li>\n\t\t\t//\t\t\t</ul>\n\t\t\t//\t\t</li>\n\t\t\t//\t</ul>\n\t\t\tif ( items[ 1 ].getAttribute( 'listItemId' ) != attributes.listItemId ) {\n\t\t\t\tconversionApi.keepEmptyElement( items[ 0 ] );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Returns a model document change:data event listener that triggers conversion of related items if needed.\n *\n * @internal\n * @param model The editor model.\n * @param editing The editing controller.\n * @param attributeNames The list of all model list attributes (including registered strategies).\n * @param listEditing The document list editing plugin.\n */\nexport function reconvertItemsOnDataChange(\n\tmodel: Model,\n\tediting: EditingController,\n\tattributeNames: Array<string>,\n\tlistEditing: ListEditing\n): () => void {\n\treturn () => {\n\t\tconst changes = model.document.differ.getChanges();\n\t\tconst itemsToRefresh = [];\n\t\tconst itemToListHead = new Map<ListElement, ListElement>();\n\t\tconst changedItems = new Set<Node>();\n\n\t\tfor ( const entry of changes ) {\n\t\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\n\t\t\t\t// Insert of a non-list item.\n\t\t\t\tif ( !entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( entry.position.getShiftedBy( entry.length ), itemToListHead );\n\t\t\t\t} else {\n\t\t\t\t\tchangedItems.add( entry.position.nodeAfter! );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Removed list item.\n\t\t\telse if ( entry.type == 'remove' && entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\t\t\t}\n\t\t\t// Changed list attribute.\n\t\t\telse if ( entry.type == 'attribute' ) {\n\t\t\t\tconst item = entry.range.start.nodeAfter!;\n\n\t\t\t\tif ( attributeNames.includes( entry.attributeKey ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( entry.range.start, itemToListHead );\n\n\t\t\t\t\tif ( entry.attributeNewValue === null ) {\n\t\t\t\t\t\tfindAndAddListHeadToMap( entry.range.start.getShiftedBy( 1 ), itemToListHead );\n\n\t\t\t\t\t\t// Check if paragraph should be converted from bogus to plain paragraph.\n\t\t\t\t\t\tif ( doesItemBlockRequiresRefresh( item as Element ) ) {\n\t\t\t\t\t\t\titemsToRefresh.push( item );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchangedItems.add( item );\n\t\t\t\t\t}\n\t\t\t\t} else if ( isListItemBlock( item ) ) {\n\t\t\t\t\t// Some other attribute was changed on the list item,\n\t\t\t\t\t// check if paragraph does not need to be converted to bogus or back.\n\t\t\t\t\tif ( doesItemBlockRequiresRefresh( item ) ) {\n\t\t\t\t\t\titemsToRefresh.push( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const listHead of itemToListHead.values() ) {\n\t\t\titemsToRefresh.push( ...collectListItemsToRefresh( listHead, changedItems ) );\n\t\t}\n\n\t\tfor ( const item of new Set( itemsToRefresh ) ) {\n\t\t\tediting.reconvertItem( item );\n\t\t}\n\t};\n\n\tfunction collectListItemsToRefresh( listHead: ListElement, changedItems: Set<Node> ) {\n\t\tconst itemsToRefresh = [];\n\t\tconst visited = new Set();\n\t\tconst stack: Array<ListItemAttributesMap> = [];\n\n\t\tfor ( const { node, previous } of iterateSiblingListBlocks( listHead, 'forward' ) ) {\n\t\t\tif ( visited.has( node ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst itemIndent = node.getAttribute( 'listIndent' );\n\n\t\t\t// Current node is at the lower indent so trim the stack.\n\t\t\tif ( previous && itemIndent < previous.getAttribute( 'listIndent' ) ) {\n\t\t\t\tstack.length = itemIndent + 1;\n\t\t\t}\n\n\t\t\t// Update the stack for the current indent level.\n\t\t\tstack[ itemIndent ] = Object.fromEntries(\n\t\t\t\tArray.from( node.getAttributes() )\n\t\t\t\t\t.filter( ( [ key ] ) => attributeNames.includes( key ) )\n\t\t\t);\n\n\t\t\t// Find all blocks of the current node.\n\t\t\tconst blocks = getListItemBlocks( node, { direction: 'forward' } );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tvisited.add( block );\n\n\t\t\t\t// Check if bogus vs plain paragraph needs refresh.\n\t\t\t\tif ( doesItemBlockRequiresRefresh( block, blocks ) ) {\n\t\t\t\t\titemsToRefresh.push( block );\n\t\t\t\t}\n\t\t\t\t// Check if wrapping with UL, OL, LIs needs refresh.\n\t\t\t\telse if ( doesItemWrappingRequiresRefresh( block, stack, changedItems ) ) {\n\t\t\t\t\titemsToRefresh.push( block );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn itemsToRefresh;\n\t}\n\n\tfunction doesItemBlockRequiresRefresh( item: Element, blocks?: Array<Node> ) {\n\t\tconst viewElement = editing.mapper.toViewElement( item );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst needsRefresh = listEditing.fire<ListEditingCheckElementEvent>( 'checkElement', {\n\t\t\tmodelElement: item,\n\t\t\tviewElement\n\t\t} );\n\n\t\tif ( needsRefresh ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif ( !item.is( 'element', 'paragraph' ) && !item.is( 'element', 'listItem' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst useBogus = shouldUseBogusParagraph( item, attributeNames, blocks );\n\n\t\tif ( useBogus && viewElement.is( 'element', 'p' ) ) {\n\t\t\treturn true;\n\t\t} else if ( !useBogus && viewElement.is( 'element', 'span' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction doesItemWrappingRequiresRefresh(\n\t\titem: Element,\n\t\tstack: Array<ListItemAttributesMap>,\n\t\tchangedItems: Set<Node>\n\t) {\n\t\t// Items directly affected by some \"change\" don't need a refresh, they will be converted by their own changes.\n\t\tif ( changedItems.has( item ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewElement = editing.mapper.toViewElement( item )!;\n\t\tlet indent = stack.length - 1;\n\n\t\t// Traverse down the stack to the root to verify if all ULs, OLs, and LIs are as expected.\n\t\tfor (\n\t\t\tlet element = viewElement.parent!;\n\t\t\t!element.is( 'editableElement' );\n\t\t\telement = element.parent!\n\t\t) {\n\t\t\tconst isListItemElement = isListItemView( element );\n\t\t\tconst isListElement = isListView( element );\n\n\t\t\tif ( !isListElement && !isListItemElement ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst eventName = `checkAttributes:${ isListItemElement ? 'item' : 'list' }` as const;\n\t\t\tconst needsRefresh = listEditing.fire<ListEditingCheckAttributesEvent>( eventName, {\n\t\t\t\tviewElement: element as ViewElement,\n\t\t\t\tmodelAttributes: stack[ indent ]\n\t\t\t} );\n\n\t\t\tif ( needsRefresh ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ( isListElement ) {\n\t\t\t\tindent--;\n\n\t\t\t\t// Don't need to iterate further if we already know that the item is wrapped appropriately.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n}\n\n/**\n * Returns the list item downcast converter.\n *\n * @internal\n * @param attributeNames A list of attribute names that should be converted if they are set.\n * @param strategies The strategies.\n * @param model The model.\n */\nexport function listItemDowncastConverter(\n\tattributeNames: Array<string>,\n\tstrategies: Array<DowncastStrategy>,\n\tmodel: Model,\n\t{ dataPipeline }: { dataPipeline?: boolean } = {}\n): GetCallback<DowncastAttributeEvent<ListElement>> {\n\tconst consumer = createAttributesConsumer( attributeNames );\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, mapper, consumable } = conversionApi;\n\n\t\tconst listItem = data.item;\n\n\t\tif ( !attributeNames.includes( data.attributeKey ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Test if attributes on the converted items are not consumed.\n\t\tif ( !consumer( listItem, consumable ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Use positions mapping instead of mapper.toViewElement( listItem ) to find outermost view element.\n\t\t// This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n\t\tconst viewElement = findMappedViewElement( listItem, mapper, model )!;\n\n\t\t// Remove custom item marker.\n\t\tremoveCustomMarkerElements( viewElement, writer, mapper );\n\n\t\t// Unwrap element from current list wrappers.\n\t\tunwrapListItemBlock( viewElement, writer );\n\n\t\t// Insert custom item marker.\n\t\tconst viewRange = insertCustomMarkerElements( listItem, viewElement, strategies, writer, { dataPipeline } );\n\n\t\t// Then wrap them with the new list wrappers (UL, OL, LI).\n\t\twrapListItemBlock( listItem, viewRange, strategies, writer );\n\t};\n}\n\n/**\n * The 'remove' downcast converter for custom markers.\n */\nexport function listItemDowncastRemoveConverter( schema: Schema ): GetCallback<DowncastRemoveEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, mapper } = conversionApi;\n\t\tconst elementName = evt.name.split( ':' )[ 1 ];\n\n\t\t// Do not remove marker if the deleted element is some inline object inside paragraph.\n\t\t// See https://github.com/cksource/ckeditor5-internal/issues/3680.\n\t\tif ( !schema.checkAttribute( elementName, 'listItemId' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the view range start position by mapping the model position at which the remove happened.\n\t\tconst viewStart = mapper.toViewPosition( data.position );\n\n\t\tconst modelEnd = data.position.getShiftedBy( data.length );\n\t\tconst viewEnd = mapper.toViewPosition( modelEnd, { isPhantom: true } );\n\n\t\t// Trim the range to remove in case some UI elements are on the view range boundaries.\n\t\tconst viewRange = writer.createRange( viewStart, viewEnd ).getTrimmed();\n\n\t\t// Use positions mapping instead of mapper.toViewElement( listItem ) to find outermost view element.\n\t\t// This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n\t\tconst viewElement = viewRange.end.nodeBefore as ViewElement | null;\n\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif ( !viewElement ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove custom item marker.\n\t\tremoveCustomMarkerElements( viewElement, writer, mapper );\n\t};\n}\n\n/**\n * Returns the bogus paragraph view element creator. A bogus paragraph is used if a list item contains only a single block or nested list.\n *\n * @internal\n * @param attributeNames The list of all model list attributes (including registered strategies).\n */\nexport function bogusParagraphCreator(\n\tattributeNames: Array<string>,\n\t{ dataPipeline }: { dataPipeline?: boolean } = {}\n): ElementCreatorFunction {\n\treturn ( modelElement, { writer } ) => {\n\t\t// Convert only if a bogus paragraph should be used.\n\t\tif ( !shouldUseBogusParagraph( modelElement, attributeNames ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( !dataPipeline ) {\n\t\t\treturn writer.createContainerElement( 'span', { class: 'ck-list-bogus-paragraph' } );\n\t\t}\n\n\t\t// Using `<p>` in case there are some markers on it and transparentRendering will render it anyway.\n\t\tconst viewElement = writer.createContainerElement( 'p' );\n\n\t\twriter.setCustomProperty( 'dataPipeline:transparentRendering', true, viewElement );\n\n\t\treturn viewElement;\n\t};\n}\n\n/**\n * Helper for mapping mode to view elements. It's using positions mapping instead of mapper.toViewElement( element )\n * to find outermost view element. This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n *\n * @internal\n * @param element The model element.\n * @param mapper The mapper instance.\n * @param model The model.\n */\nexport function findMappedViewElement( element: Element, mapper: Mapper, model: Model ): ViewElement | null {\n\tconst modelRange = model.createRangeOn( element );\n\tconst viewRange = mapper.toViewRange( modelRange ).getTrimmed();\n\n\treturn viewRange.end.nodeBefore as ViewElement | null;\n}\n\n/**\n * The model to view custom position mapping for cases when marker is injected at the beginning of a block.\n */\nexport function createModelToViewPositionMapper(\n\tstrategies: Array<DowncastStrategy>,\n\tview: EditingView\n): GetCallback<MapperModelToViewPositionEvent> {\n\treturn ( evt, data ) => {\n\t\tif ( data.modelPosition.offset > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst positionParent = data.modelPosition.parent;\n\n\t\tif ( !isListItemBlock( positionParent ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !strategies.some( strategy => (\n\t\t\tstrategy.scope == 'itemMarker' &&\n\t\t\tstrategy.canInjectMarkerIntoElement &&\n\t\t\tstrategy.canInjectMarkerIntoElement( positionParent )\n\t\t) ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = data.mapper.toViewElement( positionParent )!;\n\t\tconst viewRange = view.createRangeIn( viewElement );\n\n\t\tconst viewWalker = viewRange.getWalker();\n\t\tlet positionAfterLastMarker = viewRange.start;\n\n\t\tfor ( const { item } of viewWalker ) {\n\t\t\t// Walk only over the non-mapped elements (UIElements, AttributeElements, $text, or any other element without mapping).\n\t\t\tif ( item.is( 'element' ) && data.mapper.toModelElement( item ) || item.is( '$textProxy' ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ( item.is( 'element' ) && item.getCustomProperty( 'listItemMarker' ) ) {\n\t\t\t\tpositionAfterLastMarker = view.createPositionAfter( item );\n\n\t\t\t\t// Jump over the content of the marker (this is not needed for UIElement but required for other element types).\n\t\t\t\tviewWalker.skip( ( { previousPosition } ) => !previousPosition.isEqual( positionAfterLastMarker ) );\n\t\t\t}\n\t\t}\n\n\t\tdata.viewPosition = positionAfterLastMarker;\n\t};\n}\n\n/**\n * Removes a custom marker elements and item wrappers related to that marker.\n */\nfunction removeCustomMarkerElements( viewElement: ViewElement, viewWriter: DowncastWriter, mapper: Mapper ): void {\n\t// Remove item wrapper.\n\twhile ( viewElement.parent!.is( 'attributeElement' ) && viewElement.parent!.getCustomProperty( 'listItemWrapper' ) ) {\n\t\tviewWriter.unwrap( viewWriter.createRangeOn( viewElement ), viewElement.parent );\n\t}\n\n\t// Remove custom item markers.\n\tconst markersToRemove: Array<ViewElement> = [];\n\n\t// Markers before a block.\n\tcollectMarkersToRemove( viewWriter.createPositionBefore( viewElement ).getWalker( { direction: 'backward' } ) );\n\n\t// Markers inside a block.\n\tcollectMarkersToRemove( viewWriter.createRangeIn( viewElement ).getWalker() );\n\n\tfor ( const marker of markersToRemove ) {\n\t\tviewWriter.remove( marker );\n\t}\n\n\tfunction collectMarkersToRemove( viewWalker: ViewTreeWalker ) {\n\t\tfor ( const { item } of viewWalker ) {\n\t\t\t// Walk only over the non-mapped elements (UIElements, AttributeElements, $text, or any other element without mapping).\n\t\t\tif ( item.is( 'element' ) && mapper.toModelElement( item ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ( item.is( 'element' ) && item.getCustomProperty( 'listItemMarker' ) ) {\n\t\t\t\tmarkersToRemove.push( item );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Inserts a custom marker elements and wraps first block of a list item if marker requires it.\n */\nfunction insertCustomMarkerElements(\n\tlistItem: Element,\n\tviewElement: ViewElement,\n\tstrategies: Array<DowncastStrategy>,\n\twriter: DowncastWriter,\n\t{ dataPipeline }: { dataPipeline?: boolean }\n): ViewRange {\n\tlet viewRange = writer.createRangeOn( viewElement );\n\n\t// Marker can be inserted only before the first block of a list item.\n\tif ( !isFirstBlockOfListItem( listItem ) ) {\n\t\treturn viewRange;\n\t}\n\n\tfor ( const strategy of strategies ) {\n\t\tif ( strategy.scope != 'itemMarker' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Create the custom marker element and inject it before the first block of the list item.\n\t\tconst markerElement = strategy.createElement( writer, listItem, { dataPipeline } );\n\n\t\tif ( !markerElement ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\twriter.setCustomProperty( 'listItemMarker', true, markerElement );\n\n\t\tif ( strategy.canInjectMarkerIntoElement && strategy.canInjectMarkerIntoElement( listItem ) ) {\n\t\t\twriter.insert( writer.createPositionAt( viewElement, 0 ), markerElement );\n\t\t} else {\n\t\t\twriter.insert( viewRange.start, markerElement );\n\n\t\t\tviewRange = writer.createRange(\n\t\t\t\twriter.createPositionBefore( markerElement ),\n\t\t\t\twriter.createPositionAfter( viewElement )\n\t\t\t);\n\t\t}\n\n\t\t// Wrap the marker and optionally the first block with an attribute element (label for to-do lists).\n\t\tif ( !strategy.createWrapperElement || !strategy.canWrapElement ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst wrapper = strategy.createWrapperElement( writer, listItem, { dataPipeline } );\n\n\t\twriter.setCustomProperty( 'listItemWrapper', true, wrapper );\n\n\t\t// The whole block can be wrapped...\n\t\tif ( strategy.canWrapElement( listItem ) ) {\n\t\t\tviewRange = writer.wrap( viewRange, wrapper );\n\t\t} else {\n\t\t\t// ... or only the marker element (if the block is downcasted to heading or block widget).\n\t\t\tviewRange = writer.wrap( writer.createRangeOn( markerElement ), wrapper );\n\n\t\t\tviewRange = writer.createRange(\n\t\t\t\tviewRange.start,\n\t\t\t\twriter.createPositionAfter( viewElement )\n\t\t\t);\n\t\t}\n\t}\n\n\treturn viewRange;\n}\n\n/**\n * Unwraps all ol, ul, and li attribute elements that are wrapping the provided view element.\n */\nfunction unwrapListItemBlock( viewElement: ViewElement, viewWriter: DowncastWriter ) {\n\tlet attributeElement: ViewElement | ViewDocumentFragment = viewElement.parent!;\n\n\twhile ( attributeElement.is( 'attributeElement' ) && [ 'ul', 'ol', 'li' ].includes( attributeElement.name ) ) {\n\t\tconst parentElement = attributeElement.parent;\n\n\t\tviewWriter.unwrap( viewWriter.createRangeOn( viewElement ), attributeElement );\n\n\t\tattributeElement = parentElement!;\n\t}\n}\n\n/**\n * Wraps the given list item with appropriate attribute elements for ul, ol, and li.\n */\nfunction wrapListItemBlock(\n\tlistItem: ListElement,\n\tviewRange: ViewRange,\n\tstrategies: Array<DowncastStrategy>,\n\twriter: DowncastWriter\n) {\n\tif ( !listItem.hasAttribute( 'listIndent' ) ) {\n\t\treturn;\n\t}\n\n\tconst listItemIndent = listItem.getAttribute( 'listIndent' );\n\tlet currentListItem: ListElement | null = listItem;\n\n\tfor ( let indent = listItemIndent; indent >= 0; indent-- ) {\n\t\tconst listItemViewElement = createListItemElement( writer, indent, currentListItem.getAttribute( 'listItemId' ) );\n\t\tconst listViewElement = createListElement( writer, indent, currentListItem.getAttribute( 'listType' ) );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tif (\n\t\t\t\t( strategy.scope == 'list' || strategy.scope == 'item' ) &&\n\t\t\t\tcurrentListItem.hasAttribute( strategy.attributeName )\n\t\t\t) {\n\t\t\t\tstrategy.setAttributeOnDowncast(\n\t\t\t\t\twriter,\n\t\t\t\t\tcurrentListItem.getAttribute( strategy.attributeName ),\n\t\t\t\t\tstrategy.scope == 'list' ? listViewElement : listItemViewElement\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tviewRange = writer.wrap( viewRange, listItemViewElement );\n\t\tviewRange = writer.wrap( viewRange, listViewElement );\n\n\t\tif ( indent == 0 ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurrentListItem = ListWalker.first( currentListItem, { lowerIndent: true } );\n\n\t\t// There is no list item with lower indent, this means this is a document fragment containing\n\t\t// only a part of nested list (like copy to clipboard) so we don't need to try to wrap it further.\n\t\tif ( !currentListItem ) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n// Returns the function that is responsible for consuming attributes that are set on the model node.\nfunction createAttributesConsumer( attributeNames: Array<string> ) {\n\treturn ( node: Node, consumable: ModelConsumable ) => {\n\t\tconst events = [];\n\n\t\t// Collect all set attributes that are triggering conversion.\n\t\tfor ( const attributeName of attributeNames ) {\n\t\t\tif ( node.hasAttribute( attributeName ) ) {\n\t\t\t\tevents.push( `attribute:${ attributeName }` );\n\t\t\t}\n\t\t}\n\n\t\tif ( !events.every( event => consumable.test( node, event ) !== false ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tevents.forEach( event => consumable.consume( node, event ) );\n\n\t\treturn true;\n\t};\n}\n\n// Whether the given item should be rendered as a bogus paragraph.\nfunction shouldUseBogusParagraph(\n\titem: Node,\n\tattributeNames: Array<string>,\n\tblocks: Array<Node> = getAllListItemBlocks( item )\n) {\n\tif ( !isListItemBlock( item ) ) {\n\t\treturn false;\n\t}\n\n\tfor ( const attributeKey of item.getAttributeKeys() ) {\n\t\t// Ignore selection attributes stored on block elements.\n\t\tif ( attributeKey.startsWith( 'selection:' ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Don't use bogus paragraph if there are attributes from other features.\n\t\tif ( !attributeNames.includes( attributeKey ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn blocks.length < 2;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/listediting\n */\n\nimport {\n\tPlugin,\n\ttype Editor,\n\ttype MultiCommand\n} from 'ckeditor5/src/core.js';\n\nimport type {\n\tDowncastAttributeEvent,\n\tDocumentChangeEvent,\n\tDowncastWriter,\n\tElement,\n\tModel,\n\tModelInsertContentEvent,\n\tUpcastElementEvent,\n\tViewDocumentTabEvent,\n\tViewElement,\n\tViewAttributeElement,\n\tWriter,\n\tDowncastRemoveEvent,\n\tMapperModelToViewPositionEvent\n} from 'ckeditor5/src/engine.js';\n\nimport { Delete, type ViewDocumentDeleteEvent } from 'ckeditor5/src/typing.js';\nimport { Enter, type EnterCommand, type ViewDocumentEnterEvent } from 'ckeditor5/src/enter.js';\nimport { CKEditorError, type GetCallback } from 'ckeditor5/src/utils.js';\n\nimport ListIndentCommand from './listindentcommand.js';\nimport ListCommand from './listcommand.js';\nimport ListMergeCommand from './listmergecommand.js';\nimport ListSplitCommand from './listsplitcommand.js';\nimport ListUtils from './listutils.js';\n\nimport {\n\tbogusParagraphCreator,\n\tcreateModelToViewPositionMapper,\n\tlistItemDowncastConverter,\n\tlistItemDowncastRemoveConverter,\n\tlistItemUpcastConverter,\n\treconvertItemsOnDataChange\n} from './converters.js';\nimport {\n\tfindAndAddListHeadToMap,\n\tfixListIndents,\n\tfixListItemIds\n} from './utils/postfixers.js';\nimport {\n\tgetAllListItemBlocks,\n\tisFirstBlockOfListItem,\n\tisLastBlockOfListItem,\n\tisSingleListItem,\n\tgetSelectedBlockObject,\n\tisListItemBlock,\n\tremoveListAttributes,\n\tListItemUid,\n\ttype ListElement\n} from './utils/model.js';\nimport {\n\tgetViewElementIdForListType,\n\tgetViewElementNameForListType\n} from './utils/view.js';\n\nimport ListWalker, { ListBlocksIterable } from './utils/listwalker.js';\n\nimport {\n\tClipboardPipeline,\n\ttype ClipboardOutputTransformationEvent\n} from 'ckeditor5/src/clipboard.js';\n\nimport '../../theme/documentlist.css';\nimport '../../theme/list.css';\n\n/**\n * A list of base list model attributes.\n */\nconst LIST_BASE_ATTRIBUTES = [ 'listType', 'listIndent', 'listItemId' ];\n\nexport type ListType = 'numbered' | 'bulleted' | 'todo' | 'customNumbered' | 'customBulleted';\n\n/**\n * Map of model attributes applicable to list blocks.\n */\nexport interface ListItemAttributesMap {\n\tlistType?: ListType;\n\tlistIndent?: number;\n\tlistItemId?: string;\n}\n\n/**\n * The editing part of the document-list feature. It handles creating, editing and removing lists and list items.\n */\nexport default class ListEditing extends Plugin {\n\t/**\n\t * The list of registered downcast strategies.\n\t */\n\tprivate readonly _downcastStrategies: Array<DowncastStrategy> = [];\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ListEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Enter, Delete, ListUtils, ClipboardPipeline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'list.multiBlock', true );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst multiBlock = editor.config.get( 'list.multiBlock' );\n\n\t\tif ( editor.plugins.has( 'LegacyListEditing' ) ) {\n\t\t\t/**\n\t\t\t * The `List` feature can not be loaded together with the `LegacyList` plugin.\n\t\t\t *\n\t\t\t * @error list-feature-conflict\n\t\t\t * @param conflictPlugin Name of the plugin.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'list-feature-conflict', this, { conflictPlugin: 'LegacyListEditing' } );\n\t\t}\n\n\t\tmodel.schema.register( '$listItem', { allowAttributes: LIST_BASE_ATTRIBUTES } );\n\n\t\tif ( multiBlock ) {\n\t\t\tmodel.schema.extend( '$container', { allowAttributesOf: '$listItem' } );\n\t\t\tmodel.schema.extend( '$block', { allowAttributesOf: '$listItem' } );\n\t\t\tmodel.schema.extend( '$blockObject', { allowAttributesOf: '$listItem' } );\n\t\t} else {\n\t\t\tmodel.schema.register( 'listItem', {\n\t\t\t\tinheritAllFrom: '$block',\n\t\t\t\tallowAttributesOf: '$listItem'\n\t\t\t} );\n\t\t}\n\n\t\tfor ( const attribute of LIST_BASE_ATTRIBUTES ) {\n\t\t\tmodel.schema.setAttributeProperties( attribute, {\n\t\t\t\tcopyOnReplace: true\n\t\t\t} );\n\t\t}\n\n\t\t// Register commands.\n\t\teditor.commands.add( 'numberedList', new ListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new ListCommand( editor, 'bulleted' ) );\n\n\t\teditor.commands.add( 'customNumberedList', new ListCommand(\teditor,\t'customNumbered', {\tmultiLevel: true } ) );\n\t\teditor.commands.add( 'customBulletedList', new ListCommand( editor, 'customBulleted', {\tmultiLevel: true } ) );\n\n\t\teditor.commands.add( 'indentList', new ListIndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new ListIndentCommand( editor, 'backward' ) );\n\n\t\teditor.commands.add( 'splitListItemBefore', new ListSplitCommand( editor, 'before' ) );\n\t\teditor.commands.add( 'splitListItemAfter', new ListSplitCommand( editor, 'after' ) );\n\n\t\tif ( multiBlock ) {\n\t\t\teditor.commands.add( 'mergeListItemBackward', new ListMergeCommand( editor, 'backward' ) );\n\t\t\teditor.commands.add( 'mergeListItemForward', new ListMergeCommand( editor, 'forward' ) );\n\t\t}\n\n\t\tthis._setupDeleteIntegration();\n\t\tthis._setupEnterIntegration();\n\t\tthis._setupTabIntegration();\n\t\tthis._setupClipboardIntegration();\n\t\tthis._setupAccessibilityIntegration();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\t\tconst commands = editor.commands;\n\t\tconst indent = commands.get( 'indent' ) as MultiCommand;\n\t\tconst outdent = commands.get( 'outdent' ) as MultiCommand;\n\n\t\tif ( indent ) {\n\t\t\t// Priority is high due to integration with `IndentBlock` plugin. We want to indent list first and if it's not possible\n\t\t\t// user can indent content with `IndentBlock` plugin.\n\t\t\tindent.registerChildCommand( commands.get( 'indentList' )!, { priority: 'high' } );\n\t\t}\n\n\t\tif ( outdent ) {\n\t\t\t// Priority is lowest due to integration with `IndentBlock` and `IndentCode` plugins.\n\t\t\t// First we want to allow user to outdent all indendations from other features then he can oudent list item.\n\t\t\toutdent.registerChildCommand( commands.get( 'outdentList' )!, { priority: 'lowest' } );\n\t\t}\n\n\t\t// Register conversion and model post-fixer after other plugins had a chance to register their attribute strategies.\n\t\tthis._setupModelPostFixing();\n\t\tthis._setupConversion();\n\t}\n\n\t/**\n\t * Registers a downcast strategy.\n\t *\n\t * **Note**: Strategies must be registered in the `Plugin#init()` phase so that it can be applied\n\t * in the `ListEditing#afterInit()`.\n\t *\n\t * @param strategy The downcast strategy to register.\n\t */\n\tpublic registerDowncastStrategy( strategy: DowncastStrategy ): void {\n\t\tthis._downcastStrategies.push( strategy );\n\t}\n\n\t/**\n\t * Returns list of model attribute names that should affect downcast conversion.\n\t */\n\tpublic getListAttributeNames(): Array<string> {\n\t\treturn [\n\t\t\t...LIST_BASE_ATTRIBUTES,\n\t\t\t...this._downcastStrategies.map( strategy => strategy.attributeName )\n\t\t];\n\t}\n\n\t/**\n\t * Attaches the listener to the {@link module:engine/view/document~Document#event:delete} event and handles backspace/delete\n\t * keys in and around document lists.\n\t */\n\tprivate _setupDeleteIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst mergeBackwardCommand: ListMergeCommand | undefined = editor.commands.get( 'mergeListItemBackward' );\n\t\tconst mergeForwardCommand: ListMergeCommand | undefined = editor.commands.get( 'mergeListItemForward' );\n\n\t\tthis.listenTo<ViewDocumentDeleteEvent>( editor.editing.view.document, 'delete', ( evt, data ) => {\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\t// Let the Widget plugin take care of block widgets while deleting (https://github.com/ckeditor/ckeditor5/issues/11346).\n\t\t\tif ( getSelectedBlockObject( editor.model ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.model.change( () => {\n\t\t\t\tconst firstPosition = selection.getFirstPosition()!;\n\n\t\t\t\tif ( selection.isCollapsed && data.direction == 'backward' ) {\n\t\t\t\t\tif ( !firstPosition.isAtStart ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst positionParent = firstPosition.parent;\n\n\t\t\t\t\tif ( !isListItemBlock( positionParent ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst previousBlock = ListWalker.first( positionParent, {\n\t\t\t\t\t\tsameAttributes: 'listType',\n\t\t\t\t\t\tsameIndent: true\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Outdent the first block of a first list item.\n\t\t\t\t\tif ( !previousBlock && positionParent.getAttribute( 'listIndent' ) === 0 ) {\n\t\t\t\t\t\tif ( !isLastBlockOfListItem( positionParent ) ) {\n\t\t\t\t\t\t\teditor.execute( 'splitListItemAfter' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\teditor.execute( 'outdentList' );\n\t\t\t\t\t}\n\t\t\t\t\t// Merge block with previous one (on the block level or on the content level).\n\t\t\t\t\telse {\n\t\t\t\t\t\tif ( !mergeBackwardCommand || !mergeBackwardCommand.isEnabled ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmergeBackwardCommand.execute( {\n\t\t\t\t\t\t\tshouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel( editor.model, 'backward' )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// Non-collapsed selection or forward delete.\n\t\t\t\telse {\n\t\t\t\t\t// Collapsed selection should trigger forward merging only if at the end of a block.\n\t\t\t\t\tif ( selection.isCollapsed && !selection.getLastPosition()!.isAtEnd ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !mergeForwardCommand || !mergeForwardCommand.isEnabled ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tmergeForwardCommand.execute( {\n\t\t\t\t\t\tshouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel( editor.model, 'forward' )\n\t\t\t\t\t} );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t} );\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:enter} event and handles enter key press\n\t * in document lists.\n\t */\n\tprivate _setupEnterIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst commands = editor.commands;\n\t\tconst enterCommand: EnterCommand = commands.get( 'enter' )!;\n\n\t\t// Overwrite the default Enter key behavior: outdent or split the list in certain cases.\n\t\tthis.listenTo<ViewDocumentEnterEvent>( editor.editing.view.document, 'enter', ( evt, data ) => {\n\t\t\tconst doc = model.document;\n\t\t\tconst positionParent = doc.selection.getFirstPosition()!.parent;\n\n\t\t\tif (\n\t\t\t\tdoc.selection.isCollapsed &&\n\t\t\t\tisListItemBlock( positionParent ) &&\n\t\t\t\tpositionParent.isEmpty &&\n\t\t\t\t!data.isSoft\n\t\t\t) {\n\t\t\t\tconst isFirstBlock = isFirstBlockOfListItem( positionParent );\n\t\t\t\tconst isLastBlock = isLastBlockOfListItem( positionParent );\n\n\t\t\t\t// * a      →      * a\n\t\t\t\t// * []     →      []\n\t\t\t\tif ( isFirstBlock && isLastBlock ) {\n\t\t\t\t\teditor.execute( 'outdentList' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// * []     →      * []\n\t\t\t\t//   a      →      * a\n\t\t\t\telse if ( isFirstBlock && !isLastBlock ) {\n\t\t\t\t\teditor.execute( 'splitListItemAfter' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// * a      →      * a\n\t\t\t\t//   []     →      * []\n\t\t\t\telse if ( isLastBlock ) {\n\t\t\t\t\teditor.execute( 'splitListItemBefore' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}, { context: 'li' } );\n\n\t\t// In some cases, after the default block splitting, we want to modify the new block to become a new list item\n\t\t// instead of an additional block in the same list item.\n\t\tthis.listenTo( enterCommand, 'afterExecute', () => {\n\t\t\tconst splitCommand: ListSplitCommand = commands.get( 'splitListItemBefore' )!;\n\n\t\t\t// The command has not refreshed because the change block related to EnterCommand#execute() is not over yet.\n\t\t\t// Let's keep it up to date and take advantage of ListSplitCommand#isEnabled.\n\t\t\tsplitCommand.refresh();\n\n\t\t\tif ( !splitCommand.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst doc = editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition()!.parent;\n\t\t\tconst listItemBlocks = getAllListItemBlocks( positionParent as any );\n\n\t\t\t// Keep in mind this split happens after the default enter handler was executed. For instance:\n\t\t\t//\n\t\t\t// │       Initial state       │    After default enter    │   Here in #afterExecute   │\n\t\t\t// ├───────────────────────────┼───────────────────────────┼───────────────────────────┤\n\t\t\t// │          * a[]            │           * a             │           * a             │\n\t\t\t// │                           │             []            │           * []            │\n\t\t\tif ( listItemBlocks.length === 2 ) {\n\t\t\t\tsplitCommand.execute();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:tab} event and handles tab key and tab+shift keys\n\t * presses in document lists.\n\t */\n\tprivate _setupTabIntegration() {\n\t\tconst editor = this.editor;\n\n\t\tthis.listenTo<ViewDocumentTabEvent>( editor.editing.view.document, 'tab', ( evt, data ) => {\n\t\t\tconst commandName = data.shiftKey ? 'outdentList' : 'indentList';\n\t\t\tconst command = this.editor.commands.get( commandName )!;\n\n\t\t\tif ( command.isEnabled ) {\n\t\t\t\teditor.execute( commandName );\n\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * Registers the conversion helpers for the document-list feature.\n\t */\n\tprivate _setupConversion() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst attributeNames = this.getListAttributeNames();\n\t\tconst multiBlock = editor.config.get( 'list.multiBlock' );\n\t\tconst elementName = multiBlock ? 'paragraph' : 'listItem';\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t// Convert <li> to a generic paragraph (or listItem element) so the content of <li> is always inside a block.\n\t\t\t// Setting the listType attribute to let other features (to-do list) know that this is part of a list item.\n\t\t\t// This is also important to properly handle simple lists so that paragraphs inside a list item won't break the list item.\n\t\t\t// <li>  <-- converted to listItem\n\t\t\t//   <p></p> <-- should be also converted to listItem, so it won't split and replace the listItem generated from the above li.\n\t\t\t.elementToElement( {\n\t\t\t\tview: 'li',\n\t\t\t\tmodel: ( viewElement, { writer } ) => writer.createElement( elementName, { listType: '' } )\n\t\t\t} )\n\t\t\t// Convert paragraph to the list block (without list type defined yet).\n\t\t\t// This is important to properly handle bogus paragraph and to-do lists.\n\t\t\t// Most of the time the bogus paragraph should not appear in the data of to-do list,\n\t\t\t// but if there is any marker or an attribute on the paragraph then the bogus paragraph\n\t\t\t// is preserved in the data, and we need to be able to detect this case.\n\t\t\t.elementToElement( {\n\t\t\t\tview: 'p',\n\t\t\t\tmodel: ( viewElement, { writer } ) => {\n\t\t\t\t\tif ( viewElement.parent && viewElement.parent.is( 'element', 'li' ) ) {\n\t\t\t\t\t\treturn writer.createElement( elementName, { listType: '' } );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t},\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:li', listItemUpcastConverter() );\n\t\t\t} );\n\n\t\tif ( !multiBlock ) {\n\t\t\teditor.conversion.for( 'downcast' )\n\t\t\t\t.elementToElement( {\n\t\t\t\t\tmodel: 'listItem',\n\t\t\t\t\tview: 'p'\n\t\t\t\t} );\n\t\t}\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: elementName,\n\t\t\t\tview: bogusParagraphCreator( attributeNames ),\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on<DowncastAttributeEvent<ListElement>>(\n\t\t\t\t\t'attribute',\n\t\t\t\t\tlistItemDowncastConverter( attributeNames, this._downcastStrategies, model )\n\t\t\t\t);\n\n\t\t\t\tdispatcher.on<DowncastRemoveEvent>( 'remove', listItemDowncastRemoveConverter( model.schema ) );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: elementName,\n\t\t\t\tview: bogusParagraphCreator( attributeNames, { dataPipeline: true } ),\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on<DowncastAttributeEvent<ListElement>>(\n\t\t\t\t\t'attribute',\n\t\t\t\t\tlistItemDowncastConverter( attributeNames, this._downcastStrategies, model, { dataPipeline: true } )\n\t\t\t\t);\n\t\t\t} );\n\n\t\tconst modelToViewPositionMapper = createModelToViewPositionMapper( this._downcastStrategies, editor.editing.view );\n\n\t\teditor.editing.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', modelToViewPositionMapper );\n\t\teditor.data.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', modelToViewPositionMapper );\n\n\t\tthis.listenTo<DocumentChangeEvent>(\n\t\t\tmodel.document,\n\t\t\t'change:data',\n\t\t\treconvertItemsOnDataChange( model, editor.editing, attributeNames, this ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\n\t\t// For LI verify if an ID of the attribute element is correct.\n\t\tthis.on<ListEditingCheckAttributesEvent>( 'checkAttributes:item', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tif ( viewElement.id != modelAttributes.listItemId ) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// For UL and OL check if the name and ID of element is correct.\n\t\tthis.on<ListEditingCheckAttributesEvent>( 'checkAttributes:list', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tif (\n\t\t\t\tviewElement.name != getViewElementNameForListType( modelAttributes.listType ) ||\n\t\t\t\tviewElement.id != getViewElementIdForListType( modelAttributes.listType, modelAttributes.listIndent )\n\t\t\t) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Registers model post-fixers.\n\t */\n\tprivate _setupModelPostFixing() {\n\t\tconst model = this.editor.model;\n\t\tconst attributeNames = this.getListAttributeNames();\n\n\t\t// Register list fixing.\n\t\t// First the low level handler.\n\t\tmodel.document.registerPostFixer( writer => modelChangePostFixer( model, writer, attributeNames, this ) );\n\n\t\t// Then the callbacks for the specific lists.\n\t\t// The indentation fixing must be the first one...\n\t\tthis.on<ListEditingPostFixerEvent>( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tevt.return = fixListIndents( listNodes, writer ) || evt.return;\n\t\t}, { priority: 'high' } );\n\n\t\t// ...then the item ids... and after that other fixers that rely on the correct indentation and ids.\n\t\tthis.on<ListEditingPostFixerEvent>( 'postFixer', ( evt, { listNodes, writer, seenIds } ) => {\n\t\t\tevt.return = fixListItemIds( listNodes, seenIds, writer ) || evt.return;\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Integrates the feature with the clipboard via {@link module:engine/model/model~Model#insertContent} and\n\t * {@link module:engine/model/model~Model#getSelectedContent}.\n\t */\n\tprivate _setupClipboardIntegration() {\n\t\tconst model = this.editor.model;\n\t\tconst clipboardPipeline: ClipboardPipeline = this.editor.plugins.get( 'ClipboardPipeline' );\n\n\t\tthis.listenTo<ModelInsertContentEvent>( model, 'insertContent', createModelIndentPasteFixer( model ), { priority: 'high' } );\n\n\t\t// To enhance the UX, the editor should not copy list attributes to the clipboard if the selection\n\t\t// started and ended in the same list item.\n\t\t//\n\t\t// If the selection was enclosed in a single list item, there is a good chance the user did not want it\n\t\t// copied as a list item but plain blocks.\n\t\t//\n\t\t// This avoids pasting orphaned list items instead of paragraphs, for instance, straight into the root.\n\t\t//\n\t\t//\t                       ┌─────────────────────┬───────────────────┐\n\t\t//\t                       │ Selection           │ Clipboard content │\n\t\t//\t                       ├─────────────────────┼───────────────────┤\n\t\t//\t                       │ [* <Widget />]      │ <Widget />        │\n\t\t//\t                       ├─────────────────────┼───────────────────┤\n\t\t//\t                       │ [* Foo]             │ Foo               │\n\t\t//\t                       ├─────────────────────┼───────────────────┤\n\t\t//\t                       │ * Foo [bar] baz     │ bar               │\n\t\t//\t                       ├─────────────────────┼───────────────────┤\n\t\t//\t                       │ * Fo[o              │ o                 │\n\t\t//\t                       │   ba]r              │ ba                │\n\t\t//\t                       ├─────────────────────┼───────────────────┤\n\t\t//\t                       │ * Fo[o              │ * o               │\n\t\t//\t                       │ * ba]r              │ * ba              │\n\t\t//\t                       ├─────────────────────┼───────────────────┤\n\t\t//\t                       │ [* Foo              │ * Foo             │\n\t\t//\t                       │  * bar]             │ * bar             │\n\t\t//\t                       └─────────────────────┴───────────────────┘\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/11608, https://github.com/ckeditor/ckeditor5/issues/14969\n\t\tthis.listenTo<ClipboardOutputTransformationEvent>( clipboardPipeline, 'outputTransformation', ( evt, data ) => {\n\t\t\tmodel.change( writer => {\n\t\t\t\t// Remove last block if it's empty.\n\t\t\t\tconst allContentChildren = Array.from( data.content.getChildren() );\n\t\t\t\tconst lastItem = allContentChildren[ allContentChildren.length - 1 ];\n\n\t\t\t\tif ( allContentChildren.length > 1 && lastItem.is( 'element' ) && lastItem.isEmpty ) {\n\t\t\t\t\tconst contentChildrenExceptLastItem = allContentChildren.slice( 0, -1 );\n\n\t\t\t\t\tif ( contentChildrenExceptLastItem.every( isListItemBlock ) ) {\n\t\t\t\t\t\twriter.remove( lastItem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Copy/cut only content of a list item (for drag-drop move the whole list item).\n\t\t\t\tif ( data.method == 'copy' || data.method == 'cut' ) {\n\t\t\t\t\tconst allChildren = Array.from( data.content.getChildren() );\n\t\t\t\t\tconst isSingleListItemSelected = isSingleListItem( allChildren );\n\n\t\t\t\t\tif ( isSingleListItemSelected ) {\n\t\t\t\t\t\tremoveListAttributes( allChildren as Array<Element>, writer );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Informs editor accessibility features about keystrokes brought by the plugin.\n\t */\n\tprivate _setupAccessibilityIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\teditor.accessibility.addKeystrokeInfoGroup( {\n\t\t\tid: 'list',\n\t\t\tlabel: t( 'Keystrokes that can be used in a list' ),\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Increase list item indent' ),\n\t\t\t\t\tkeystroke: 'Tab'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Decrease list item indent' ),\n\t\t\t\t\tkeystroke: 'Shift+Tab'\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n}\n\n/**\n * The attribute to attribute downcast strategy for UL, OL, LI elements.\n */\nexport interface AttributeDowncastStrategy {\n\n\t/**\n\t * The scope of the downcast (whether it applies to LI or OL/UL).\n\t */\n\tscope: 'list' | 'item';\n\n\t/**\n\t * The model attribute name.\n\t */\n\tattributeName: string;\n\n\t/**\n\t * Sets the property on the view element.\n\t */\n\tsetAttributeOnDowncast( writer: DowncastWriter, value: unknown, element: ViewElement ): void;\n}\n\n/**\n * The custom marker downcast strategy.\n */\nexport interface ItemMarkerDowncastStrategy {\n\n\t/**\n\t * The scope of the downcast.\n\t */\n\tscope: 'itemMarker';\n\n\t/**\n\t * The model attribute name.\n\t */\n\tattributeName: string;\n\n\t/**\n\t * Creates a view element for a custom item marker.\n\t */\n\tcreateElement(\n\t\twriter: DowncastWriter,\n\t\tmodelElement: Element,\n\t\t{ dataPipeline }: { dataPipeline?: boolean }\n\t): ViewElement | null;\n\n\t/**\n\t * Creates an AttributeElement to be used for wrapping a first block of a list item.\n\t */\n\tcreateWrapperElement?(\n\t\twriter: DowncastWriter,\n\t\tmodelElement: Element,\n\t\t{ dataPipeline }: { dataPipeline?: boolean }\n\t): ViewAttributeElement;\n\n\t/**\n\t * Should return true if the given list block can be wrapped with the wrapper created by `createWrapperElement()`\n\t * or only the marker element should be wrapped.\n\t */\n\tcanWrapElement?( modelElement: Element ): boolean;\n\n\t/**\n\t * Should return true if the custom marker can be injected into a given list block.\n\t * Otherwise, custom marker view element is always injected before the block element.\n\t */\n\tcanInjectMarkerIntoElement?( modelElement: Element ): boolean;\n}\n\n/**\n * The downcast strategy.\n */\nexport type DowncastStrategy = AttributeDowncastStrategy | ItemMarkerDowncastStrategy;\n\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states (invalid `listItemId` and `listIndent` values).\n *\n * In the example below, there is a correct list structure.\n * Then the middle element is removed so the list structure will become incorrect:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>Item 2</paragraph>   <--- this is removed.\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n * ```\n *\n * The list structure after the middle element is removed:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=1>Item 3</paragraph>   <--- note that indent got post-fixed.\n * ```\n *\n * @param model The data model.\n * @param writer The writer to do changes with.\n * @param attributeNames The list of all model list attributes (including registered strategies).\n * @param ListEditing The document list editing plugin.\n * @returns `true` if any change has been applied, `false` otherwise.\n */\nfunction modelChangePostFixer(\n\tmodel: Model,\n\twriter: Writer,\n\tattributeNames: Array<string>,\n\tlistEditing: ListEditing\n) {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = new Map<ListElement, ListElement>();\n\tconst multiBlock = listEditing.editor.config.get( 'list.multiBlock' );\n\n\tlet applied = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\tconst item = entry.position.nodeAfter!;\n\n\t\t\t// Remove attributes in case of renamed element.\n\t\t\tif ( !model.schema.checkAttribute( item, 'listItemId' ) ) {\n\t\t\t\tfor ( const attributeName of Array.from( item.getAttributeKeys() ) ) {\n\t\t\t\t\tif ( attributeNames.includes( attributeName ) ) {\n\t\t\t\t\t\twriter.removeAttribute( attributeName, item );\n\n\t\t\t\t\t\tapplied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\n\t\t\t// Insert of a non-list item - check if there is a list after it.\n\t\t\tif ( !entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position.getShiftedBy( entry.length ), itemToListHead );\n\t\t\t}\n\n\t\t\t// Check if there is no nested list.\n\t\t\tfor ( const { item: innerItem, previousPosition } of model.createRangeIn( item as Element ) ) {\n\t\t\t\tif ( isListItemBlock( innerItem ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( previousPosition, itemToListHead );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Removed list item or block adjacent to a list.\n\t\telse if ( entry.type == 'remove' ) {\n\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\t\t}\n\t\t// Changed list item indent or type.\n\t\telse if ( entry.type == 'attribute' && attributeNames.includes( entry.attributeKey ) ) {\n\t\t\tfindAndAddListHeadToMap( entry.range.start, itemToListHead );\n\n\t\t\tif ( entry.attributeNewValue === null ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.range.start.getShiftedBy( 1 ), itemToListHead );\n\t\t\t}\n\t\t}\n\n\t\t// Make sure that there is no left over listItem element without attributes or a block with list attributes that is not a listItem.\n\t\tif ( !multiBlock && entry.type == 'attribute' && LIST_BASE_ATTRIBUTES.includes( entry.attributeKey ) ) {\n\t\t\tconst element = entry.range.start.nodeAfter!;\n\n\t\t\tif ( entry.attributeNewValue === null && element && element.is( 'element', 'listItem' ) ) {\n\t\t\t\twriter.rename( element, 'paragraph' );\n\t\t\t\tapplied = true;\n\t\t\t} else if ( entry.attributeOldValue === null && element && element.is( 'element' ) && element.name != 'listItem' ) {\n\t\t\t\twriter.rename( element, 'listItem' );\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Make sure that IDs are not shared by split list.\n\tconst seenIds = new Set<string>();\n\n\tfor ( const listHead of itemToListHead.values() ) {\n\t\tapplied = listEditing.fire<ListEditingPostFixerEvent>( 'postFixer', {\n\t\t\tlistNodes: new ListBlocksIterable( listHead ),\n\t\t\tlistHead,\n\t\t\twriter,\n\t\t\tseenIds\n\t\t} ) || applied;\n\t}\n\n\treturn applied;\n}\n\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=\"0\">A</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=\"1\">B^</paragraph>\n * // At ^ paste:  <paragraph listType=\"numbered\" listItemId=\"x\" listIndent=\"0\">X</paragraph>\n * //              <paragraph listType=\"numbered\" listItemId=\"y\" listIndent=\"1\">Y</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=\"2\">C</paragraph>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=\"0\">A</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=\"1\">BX</paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"y\" listIndent=\"2\">Y/paragraph>\n * <paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=\"2\">C</paragraph>\n * ```\n */\nfunction createModelIndentPasteFixer( model: Model ): GetCallback<ModelInsertContentEvent> {\n\treturn ( evt, [ content, selectable ] ) => {\n\t\tconst items = content.is( 'documentFragment' ) ?\n\t\t\tArray.from( content.getChildren() ) :\n\t\t\t[ content ];\n\n\t\tif ( !items.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst selection = selectable ?\n\t\t\tmodel.createSelection( selectable ) :\n\t\t\tmodel.document.selection;\n\n\t\tconst position = selection.getFirstPosition()!;\n\n\t\t// Get a reference list item. Attributes of the inserted list items will be fixed according to that item.\n\t\tlet refItem: ListElement;\n\n\t\tif ( isListItemBlock( position.parent ) ) {\n\t\t\trefItem = position.parent;\n\t\t} else if ( isListItemBlock( position.nodeBefore ) ) {\n\t\t\trefItem = position.nodeBefore;\n\t\t} else {\n\t\t\treturn; // Content is not copied into a list.\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst refType = refItem.getAttribute( 'listType' );\n\t\t\tconst refIndent = refItem.getAttribute( 'listIndent' );\n\t\t\tconst firstElementIndent = items[ 0 ].getAttribute( 'listIndent' ) as number || 0;\n\t\t\tconst indentDiff = Math.max( refIndent - firstElementIndent, 0 );\n\n\t\t\tfor ( const item of items ) {\n\t\t\t\tconst isListItem = isListItemBlock( item );\n\n\t\t\t\tif ( refItem.is( 'element', 'listItem' ) && item.is( 'element', 'paragraph' ) ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * When paragraphs or a plain text list is pasted into a simple list, convert\n\t\t\t\t\t * the `<paragraphs>' to `<listItem>' to avoid breaking the target list.\n\t\t\t\t\t *\n\t\t\t\t\t * See https://github.com/ckeditor/ckeditor5/issues/13826.\n\t\t\t\t\t */\n\t\t\t\t\twriter.rename( item as Element, 'listItem' );\n\t\t\t\t}\n\n\t\t\t\twriter.setAttributes( {\n\t\t\t\t\tlistIndent: ( isListItem ? item.getAttribute( 'listIndent' ) : 0 ) + indentDiff,\n\t\t\t\t\tlistItemId: isListItem ? item.getAttribute( 'listItemId' ) : ListItemUid.next(),\n\t\t\t\t\tlistType: refType\n\t\t\t\t}, item );\n\t\t\t}\n\t\t} );\n\t};\n}\n\n/**\n * Decides whether the merge should be accompanied by the model's `deleteContent()`, for instance, to get rid of the inline\n * content in the selection or take advantage of the heuristics in `deleteContent()` that helps convert lists into paragraphs\n * in certain cases.\n */\nfunction shouldMergeOnBlocksContentLevel( model: Model, direction: 'backward' | 'forward' ) {\n\tconst selection = model.document.selection;\n\n\tif ( !selection.isCollapsed ) {\n\t\treturn !getSelectedBlockObject( model );\n\t}\n\n\tif ( direction === 'forward' ) {\n\t\treturn true;\n\t}\n\n\tconst firstPosition = selection.getFirstPosition()!;\n\tconst positionParent = firstPosition.parent;\n\tconst previousSibling = positionParent.previousSibling!;\n\n\tif ( model.schema.isObject( previousSibling ) ) {\n\t\treturn false;\n\t}\n\n\tif ( ( previousSibling as Element ).isEmpty ) {\n\t\treturn true;\n\t}\n\n\treturn isSingleListItem( [ positionParent as Element, previousSibling ] );\n}\n\n/**\n * Event fired on changes detected on the model list element to verify if the view representation of a list element\n * is representing those attributes.\n *\n * It allows triggering a re-wrapping of a list item.\n *\n * @internal\n * @eventName ~ListEditing#postFixer\n * @param listHead The head element of a list.\n * @param writer The writer to do changes with.\n * @param seenIds The set of already known IDs.\n * @returns If a post-fixer made a change of the model tree, it should return `true`.\n */\nexport type ListEditingPostFixerEvent = {\n\tname: 'postFixer';\n\targs: [ {\n\t\tlistNodes: ListBlocksIterable;\n\t\tlistHead: Element;\n\t\twriter: Writer;\n\t\tseenIds: Set<string>;\n\t} ];\n\treturn: boolean;\n};\n\n/**\n * Event fired on changes detected on the model list element to verify if the view representation of a list element\n * is representing those attributes.\n *\n * It allows triggering a re-wrapping of a list item.\n *\n * **Note**: For convenience this event is namespaced and could be captured as `checkAttributes:list` or `checkAttributes:item`.\n *\n * @internal\n * @eventName ~ListEditing#checkAttributes\n */\nexport type ListEditingCheckAttributesEvent = {\n\tname: 'checkAttributes' | 'checkAttributes:list' | 'checkAttributes:item';\n\targs: [ {\n\t\tviewElement: ViewElement & { id?: string };\n\t\tmodelAttributes: ListItemAttributesMap;\n\t} ];\n\treturn: boolean;\n};\n\n/**\n * Event fired on changes detected on the model list element to verify if the view representation of a list block element\n * is representing those attributes.\n *\n * It allows triggering a reconversion of a list item block.\n *\n * @internal\n * @eventName ~ListEditing#checkElement\n */\nexport type ListEditingCheckElementEvent = {\n\tname: 'checkElement';\n\targs: [ {\n\t\tviewElement: ViewElement;\n\t\tmodelElement: Element;\n\t} ];\n\treturn: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/utils\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView, type ButtonExecuteEvent } from 'ckeditor5/src/ui.js';\n\n/**\n * Helper method for creating toolbar and menu buttons and linking them with an appropriate command.\n *\n * @internal\n * @param editor The editor instance to which the UI component will be added.\n * @param commandName The name of the command.\n * @param label The button label.\n * @param icon The source of the icon.\n */\nexport function createUIComponents(\n\teditor: Editor,\n\tcommandName: 'bulletedList' | 'numberedList' | 'todoList',\n\tlabel: string,\n\ticon: string\n): void {\n\teditor.ui.componentFactory.add( commandName, () => {\n\t\tconst buttonView = _createButton( ButtonView, editor, commandName, label, icon );\n\n\t\tbuttonView.set( {\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\treturn buttonView;\n\t} );\n\n\teditor.ui.componentFactory.add( `menuBar:${ commandName }`, () => {\n\t\tconst buttonView = _createButton( MenuBarMenuListItemButtonView, editor, commandName, label, icon );\n\n\t\tbuttonView.set( {\n\t\t\trole: 'menuitemcheckbox',\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\treturn buttonView;\n\t} );\n}\n\n/**\n * Creates a button to use either in toolbar or in menu bar.\n */\nfunction _createButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>(\n\tButtonClass: T,\n\teditor: Editor,\n\tcommandName: 'bulletedList' | 'numberedList' | 'todoList',\n\tlabel: string,\n\ticon: string\n): InstanceType<T> {\n\tconst command = editor.commands.get( commandName )!;\n\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\n\tview.set( {\n\t\tlabel,\n\t\ticon\n\t} );\n\n\t// Bind button model to command.\n\tview.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );\n\n\t// Execute the command.\n\tview.on<ButtonExecuteEvent>( 'execute', () => {\n\t\teditor.execute( commandName );\n\t\teditor.editing.view.focus();\n\t} );\n\n\treturn view;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/listui\n */\n\nimport { createUIComponents } from './utils.js';\nimport { icons, Plugin } from 'ckeditor5/src/core.js';\n\n/**\n * The list UI feature. It introduces the `'numberedList'` and `'bulletedList'` buttons that\n * allow to convert paragraphs to and from list items and indent or outdent them.\n */\nexport default class ListUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ListUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst t = this.editor.t;\n\n\t\t// Create button numberedList.\n\t\tif ( !this.editor.ui.componentFactory.has( 'numberedList' ) ) {\n\t\t\tcreateUIComponents( this.editor, 'numberedList', t( 'Numbered List' ), icons.numberedList );\n\t\t}\n\n\t\t// Create button bulletedList.\n\t\tif ( !this.editor.ui.componentFactory.has( 'bulletedList' ) ) {\n\t\t\tcreateUIComponents( this.editor, 'bulletedList', t( 'Bulleted List' ), icons.bulletedList );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ListEditing from './list/listediting.js';\nimport ListUI from './list/listui.js';\n\n/**\n * The list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/list/listediting~ListEditing  list\n * editing feature} and {@link module:list/list/listui~ListUI list UI feature}.\n */\nexport default class List extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ListEditing, ListUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'List' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/liststartcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock,\n\tisNumberedListType\n} from '../list/utils/model.js';\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items,\n * letting the user to choose the starting point of an ordered list.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n */\nexport default class ListStartCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public value: number | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst value = this._getValue();\n\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.startIndex The list start index.\n\t */\n\tpublic override execute( { startIndex = 1 }: { startIndex?: number } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block =>\n\t\t\t\tisListItemBlock( block ) &&\n\t\t\t\tisNumberedListType( block.getAttribute( 'listType' ) )\n\t\t\t);\n\n\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listStart', startIndex >= 0 ? startIndex : 1, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */\n\tprivate _getValue() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tif (\n\t\t\tblock &&\n\t\t\tisListItemBlock( block ) &&\n\t\t\tisNumberedListType( block.getAttribute( 'listType' ) )\n\t\t) {\n\t\t\treturn block.getAttribute( 'listStart' ) as number;\n\t\t}\n\n\t\treturn null;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n* @module list/listproperties/utils/style\n*/\n\nconst LIST_STYLE_TO_LIST_TYPE: Record<string, 'bulleted' | 'numbered' | undefined> = {};\nconst LIST_STYLE_TO_TYPE_ATTRIBUTE: Record<string, string | null | undefined> = {};\nconst TYPE_ATTRIBUTE_TO_LIST_STYLE: Record<string, string | undefined> = {};\n\nconst LIST_STYLE_TYPES: Array<{ listStyle: string; typeAttribute: string | null; listType: 'bulleted' | 'numbered' }> = [\n\t{ listStyle: 'disc', typeAttribute: 'disc', listType: 'bulleted' },\n\t{ listStyle: 'circle', typeAttribute: 'circle', listType: 'bulleted' },\n\t{ listStyle: 'square', typeAttribute: 'square', listType: 'bulleted' },\n\t{ listStyle: 'decimal', typeAttribute: '1', listType: 'numbered' },\n\t{ listStyle: 'decimal-leading-zero', typeAttribute: null, listType: 'numbered' },\n\t{ listStyle: 'lower-roman', typeAttribute: 'i', listType: 'numbered' },\n\t{ listStyle: 'upper-roman', typeAttribute: 'I', listType: 'numbered' },\n\t{ listStyle: 'lower-alpha', typeAttribute: 'a', listType: 'numbered' },\n\t{ listStyle: 'upper-alpha', typeAttribute: 'A', listType: 'numbered' },\n\t{ listStyle: 'lower-latin', typeAttribute: 'a', listType: 'numbered' },\n\t{ listStyle: 'upper-latin', typeAttribute: 'A', listType: 'numbered' }\n];\n\nfor ( const { listStyle, typeAttribute, listType } of LIST_STYLE_TYPES ) {\n\tLIST_STYLE_TO_LIST_TYPE[ listStyle ] = listType;\n\tLIST_STYLE_TO_TYPE_ATTRIBUTE[ listStyle ] = typeAttribute;\n\n\tif ( typeAttribute ) {\n\t\tTYPE_ATTRIBUTE_TO_LIST_STYLE[ typeAttribute ] = listStyle;\n\t}\n}\n\n/**\n * Gets all the style types supported by given list type.\n */\nexport function getAllSupportedStyleTypes(): Array<string> {\n\treturn LIST_STYLE_TYPES.map( x => x.listStyle );\n}\n\n/**\n * Checks whether the given list-style-type is supported by numbered or bulleted list.\n */\nexport function getListTypeFromListStyleType( listStyleType: string ): 'bulleted' | 'numbered' | null {\n\treturn LIST_STYLE_TO_LIST_TYPE[ listStyleType ] || null;\n}\n\n/**\n * Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n */\nexport function getListStyleTypeFromTypeAttribute( value: string ): string | null {\n\treturn TYPE_ATTRIBUTE_TO_LIST_STYLE[ value ] || null;\n}\n\n/**\n * Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n */\nexport function getTypeAttributeFromListStyleType( value: string ): string | null {\n\treturn LIST_STYLE_TO_TYPE_ATTRIBUTE[ value ] || null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/liststylecommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../list/utils/model.js';\nimport { getListTypeFromListStyleType } from './utils/style.js';\n\n/**\n * The list style command. It changes `listStyle` attribute of the selected list items,\n * letting the user choose styles for the list item markers.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n */\nexport default class ListStyleCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public value: string | null;\n\n\t/**\n\t * The default type of the list style.\n\t */\n\tpublic readonly defaultType: string;\n\n\t/**\n\t * The list of supported style types by this command.\n\t */\n\tprivate _supportedTypes: Array<string> | undefined;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t * @param supportedTypes The list of supported style types by this command.\n\t */\n\tconstructor( editor: Editor, defaultType: string, supportedTypes?: Array<string> ) {\n\t\tsuper( editor );\n\n\t\tthis.defaultType = defaultType;\n\t\tthis._supportedTypes = supportedTypes;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.type The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */\n\tpublic override execute( options: { type?: string | null } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tmodel.change( writer => {\n\t\t\tthis._tryToConvertItemsToList( options );\n\n\t\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t\t.filter( block => block.hasAttribute( 'listType' ) );\n\n\t\t\tif ( !blocks.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listStyle', options.type || this.defaultType, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if the given style type is supported by this plugin.\n\t */\n\tpublic isStyleTypeSupported( value: string ): boolean {\n\t\tif ( !this._supportedTypes ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn this._supportedTypes.includes( value );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */\n\tprivate _getValue() {\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\tif ( isListItemBlock( listItem ) ) {\n\t\t\treturn listItem.getAttribute( 'listStyle' ) as string;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled() {\n\t\tconst editor = this.editor;\n\n\t\tconst numberedList = editor.commands.get( 'numberedList' )!;\n\t\tconst bulletedList = editor.commands.get( 'bulletedList' )!;\n\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\n\t/**\n\t * Check if the provided list style is valid. Also change the selection to a list if it's not set yet.\n\t *\n\t * @param options.type The type of the list style. If `null` is specified, the function does nothing.\n\t*/\n\tprivate _tryToConvertItemsToList( options: { type?: string | null } ) {\n\t\tif ( !options.type ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst listType = getListTypeFromListStyleType( options.type );\n\n\t\tif ( !listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst commandName = `${ listType }List` as const;\n\t\tconst command = editor.commands.get( commandName )!;\n\n\t\tif ( !command.value ) {\n\t\t\teditor.execute( commandName );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/listreversedcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../list/utils/model.js';\n\n/**\n * The list reversed command. It changes the `listReversed` attribute of the selected list items,\n * letting the user to choose the order of an ordered list.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n */\nexport default class ListReversedCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public value: boolean | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst value = this._getValue();\n\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.reversed Whether the list should be reversed.\n\t */\n\tpublic override execute( options: { reversed?: boolean } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listReversed', !!options.reversed, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t */\n\tprivate _getValue() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tif ( isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn block.getAttribute( 'listReversed' ) as boolean;\n\t\t}\n\n\t\treturn null;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/converters\n */\n\nimport type { UpcastElementEvent } from 'ckeditor5/src/engine.js';\nimport type { GetCallback } from 'ckeditor5/src/utils.js';\n\nimport type { AttributeStrategy } from './listpropertiesediting.js';\n\n/**\n * Returns a converter that consumes the `style`, `reversed`, and `start` attributes.\n * In `style`, it searches for the `list-style-type` definition.\n * If not found, the `\"default\"` value will be used.\n *\n * @internal\n * @param strategy\n */\nexport function listPropertiesUpcastConverter( strategy: AttributeStrategy ): GetCallback<UpcastElementEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, schema, consumable } = conversionApi;\n\n\t\t// If there is no view consumable to consume, set the default attribute value to be able to reconvert nested lists on parent change.\n\t\t// So abort converting if attribute was directly consumed.\n\t\tif ( consumable.test( data.viewItem, strategy.viewConsumables ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !data.modelRange ) {\n\t\t\tObject.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t\t}\n\n\t\tlet applied = false;\n\n\t\tfor ( const item of data.modelRange!.getItems( { shallow: true } ) ) {\n\t\t\tif ( !schema.checkAttribute( item, strategy.attributeName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !strategy.appliesToListItem( item ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n\t\t\tif ( item.hasAttribute( strategy.attributeName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\twriter.setAttribute( strategy.attributeName, strategy.getAttributeOnUpcast( data.viewItem ), item );\n\t\t\tapplied = true;\n\t\t}\n\n\t\tif ( applied ) {\n\t\t\tconsumable.consume( data.viewItem, strategy.viewConsumables );\n\t\t}\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/listpropertiesutils\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport {\n\tgetAllSupportedStyleTypes,\n\tgetListStyleTypeFromTypeAttribute,\n\tgetListTypeFromListStyleType,\n\tgetTypeAttributeFromListStyleType\n} from './utils/style.js';\n\n/**\n * A set of helpers related to document lists.\n */\nexport default class ListPropertiesUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ListPropertiesUtils' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Gets all the style types supported by given list type.\n\t */\n\tpublic getAllSupportedStyleTypes(): Array<string> {\n\t\treturn getAllSupportedStyleTypes();\n\t}\n\n\t/**\n\t * Checks whether the given list-style-type is supported by numbered or bulleted list.\n\t */\n\tpublic getListTypeFromListStyleType( listStyleType: string ): 'bulleted' | 'numbered' | null {\n\t\treturn getListTypeFromListStyleType( listStyleType );\n\t}\n\n\t/**\n\t * Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n\t */\n\tpublic getListStyleTypeFromTypeAttribute( value: string ): string | null {\n\t\treturn getListStyleTypeFromTypeAttribute( value );\n\t}\n\n\t/**\n\t * Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n\t */\n\tpublic getTypeAttributeFromListStyleType( value: string ): string | null {\n\t\treturn getTypeAttributeFromListStyleType( value );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/utils/config\n */\n\nimport { toArray } from 'ckeditor5/src/utils.js';\nimport type { ListPropertiesConfig, ListPropertiesStyleListType } from '../../listconfig.js';\n\n/**\n * Normalizes {@link module:list/listconfig~ListPropertiesConfig} in the configuration of the list properties feature.\n * The structure of normalized list properties options looks as follows:\n *\n * ```ts\n * {\n * \tstyles: {\n * \t\tlistTypes: [ 'bulleted', 'numbered' ],\n * \t\tuseAttribute: false\n * \t},\n * \tstartIndex: true,\n * \treversed: true\n * }\n * ```\n *\n * @param config The list properties {@link module:list/listconfig~ListPropertiesConfig config}.\n * @returns An object with normalized list properties options.\n */\nexport function getNormalizedConfig( config: ListPropertiesConfig ): NormalizedListPropertiesConfig {\n\tconst { startIndex, reversed, styles } = config;\n\n\treturn {\n\t\tstyles: getNormalizedStylesConfig( styles ),\n\t\tstartIndex: startIndex || false,\n\t\treversed: reversed || false\n\t};\n}\n\n/**\n * Normalizes styles in the configuration of the list properties feature.\n * The structure of normalized list properties options looks as follows:\n *\n * ```ts\n * {\n * \tlistTypes: [ 'bulleted', 'numbered' ],\n * \tuseAttribute: false\n * }\n * ```\n *\n * @param styles The list properties styles.\n * @returns An object with normalized list properties styles.\n */\nfunction getNormalizedStylesConfig( styles: ListPropertiesConfig[ 'styles' ] ): NormalizedListPropertiesConfig[ 'styles' ] {\n\tconst normalizedConfig = {\n\t\tlistTypes: [ 'bulleted', 'numbered' ] as Array<ListPropertiesStyleListType>,\n\t\tuseAttribute: false\n\t};\n\n\tif ( styles === true ) {\n\t\treturn normalizedConfig;\n\t}\n\n\tif ( !styles ) {\n\t\tnormalizedConfig.listTypes = [];\n\t}\n\telse if ( Array.isArray( styles ) || typeof styles == 'string' ) {\n\t\tnormalizedConfig.listTypes = toArray( styles );\n\t}\n\telse {\n\t\tnormalizedConfig.listTypes = styles.listTypes ?\n\t\t\ttoArray( styles.listTypes ) :\n\t\t\tnormalizedConfig.listTypes;\n\n\t\tnormalizedConfig.useAttribute = !!styles.useAttribute;\n\t}\n\n\treturn normalizedConfig;\n}\n\n/**\n* Normalized list properties config.\n*/\nexport type NormalizedListPropertiesConfig = {\n\tstyles: {\n\t\tlistTypes: Array<ListPropertiesStyleListType>;\n\t\tuseAttribute: boolean;\n\t};\n\tstartIndex: boolean;\n\treversed: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/listpropertiesediting\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\n\nimport type {\n\tConsumables,\n\tDowncastWriter,\n\tElement,\n\tItem,\n\tUpcastElementEvent,\n\tViewElement\n} from 'ckeditor5/src/engine.js';\n\nimport ListEditing, {\n\ttype ListType,\n\ttype ListEditingCheckAttributesEvent,\n\ttype ListEditingPostFixerEvent,\n\ttype ListItemAttributesMap\n} from '../list/listediting.js';\n\nimport ListStartCommand from './liststartcommand.js';\nimport ListStyleCommand from './liststylecommand.js';\nimport ListReversedCommand from './listreversedcommand.js';\nimport { listPropertiesUpcastConverter } from './converters.js';\nimport {\n\tgetAllSupportedStyleTypes,\n\tgetListTypeFromListStyleType,\n\tgetListStyleTypeFromTypeAttribute,\n\tgetTypeAttributeFromListStyleType\n} from './utils/style.js';\nimport ListPropertiesUtils from './listpropertiesutils.js';\nimport {\n\tisNumberedListType\n} from '../list/utils/model.js';\n\nimport type { ListIndentCommandAfterExecuteEvent } from '../list/listindentcommand.js';\nimport type { ListPropertiesConfig } from '../listconfig.js';\nimport { getNormalizedConfig } from './utils/config.js';\n\nconst DEFAULT_LIST_TYPE = 'default';\n\n/**\n * The document list properties engine feature.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listconfig~ListPropertiesConfig}.\n */\nexport default class ListPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ListEditing, ListPropertiesUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ListPropertiesEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'list.properties', {\n\t\t\tstyles: true,\n\t\t\tstartIndex: false,\n\t\t\treversed: false\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst listEditing = editor.plugins.get( ListEditing );\n\n\t\tconst enabledProperties = editor.config.get( 'list.properties' )!;\n\t\tconst strategies = createAttributeStrategies( enabledProperties );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tstrategy.addCommand( editor );\n\n\t\t\tmodel.schema.extend( '$listItem', { allowAttributes: strategy.attributeName } );\n\n\t\t\t// Register downcast strategy.\n\t\t\tlistEditing.registerDowncastStrategy( {\n\t\t\t\tscope: 'list',\n\t\t\t\tattributeName: strategy.attributeName,\n\n\t\t\t\tsetAttributeOnDowncast( writer, attributeValue, viewElement ) {\n\t\t\t\t\tstrategy.setAttributeOnDowncast( writer, attributeValue, viewElement );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Set up conversion.\n\t\teditor.conversion.for( 'upcast' ).add( dispatcher => {\n\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:ol', listPropertiesUpcastConverter( strategy ) );\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:ul', listPropertiesUpcastConverter( strategy ) );\n\t\t\t}\n\t\t} );\n\n\t\t// Verify if the list view element (ul or ol) requires refreshing.\n\t\tlistEditing.on<ListEditingCheckAttributesEvent>(\n\t\t\t'checkAttributes:list',\n\t\t\t( evt, { viewElement, modelAttributes } ) => {\n\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\tif ( strategy.getAttributeOnUpcast( viewElement ) != modelAttributes[ strategy.attributeName ] ) {\n\t\t\t\t\t\tevt.return = true;\n\t\t\t\t\t\tevt.stop();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\t// Reset list properties after indenting list items.\n\t\tthis.listenTo<ListIndentCommandAfterExecuteEvent>(\n\t\t\teditor.commands.get( 'indentList' )!,\n\t\t\t'afterExecute',\n\t\t\t( evt, changedBlocks ) => {\n\t\t\t\tmodel.change( writer => {\n\t\t\t\t\tfor ( const node of changedBlocks ) {\n\t\t\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\t\t\tif ( strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\t\t\t// Just reset the attribute.\n\t\t\t\t\t\t\t\t// If there is a previous indented list that this node should be merged into,\n\t\t\t\t\t\t\t\t// the postfixer will unify all the attributes of both sub-lists.\n\t\t\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, strategy.defaultValue, node );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t);\n\n\t\t// Add or remove list properties attributes depending on the list type.\n\t\tlistEditing.on<ListEditingPostFixerEvent>( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tfor ( const { node } of listNodes ) {\n\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\t// Check if attribute is valid.\n\t\t\t\t\tif ( strategy.hasValidAttribute( node ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add missing default property attributes...\n\t\t\t\t\tif ( strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, strategy.defaultValue, node );\n\t\t\t\t\t}\n\t\t\t\t\t// ...or remove invalid property attributes.\n\t\t\t\t\telse {\n\t\t\t\t\t\twriter.removeAttribute( strategy.attributeName, node );\n\t\t\t\t\t}\n\n\t\t\t\t\tevt.return = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Make sure that all items in a single list (items at the same level & listType) have the same properties.\n\t\tlistEditing.on<ListEditingPostFixerEvent>( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tfor ( const { node, previousNodeInList } of listNodes ) {\n\t\t\t\t// This is a first item of a nested list.\n\t\t\t\tif ( !previousNodeInList ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// This is a first block of a list of a different type.\n\t\t\t\tif ( previousNodeInList.getAttribute( 'listType' ) != node.getAttribute( 'listType' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Copy properties from the previous one.\n\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\tconst { attributeName } = strategy;\n\n\t\t\t\t\tif ( !strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = previousNodeInList.getAttribute( attributeName );\n\n\t\t\t\t\tif ( node.getAttribute( attributeName ) != value ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, value, node );\n\t\t\t\t\t\tevt.return = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Strategy for dealing with `listItem` attributes supported by this plugin.\n *\n * @internal\n */\nexport interface AttributeStrategy {\n\n\t/**\n\t * The model attribute name.\n\t */\n\tattributeName: keyof ListItemAttributesMap;\n\n\t/**\n\t * The model attribute default value.\n\t */\n\tdefaultValue: unknown;\n\n\t/**\n\t * The view consumable as expected by {@link module:engine/conversion/viewconsumable~ViewConsumable#consume `ViewConsumable`}.\n\t */\n\tviewConsumables: Consumables;\n\n\t/**\n\t * Registers an editor command.\n\t */\n\taddCommand( editor: Editor ): void;\n\n\t/**\n\t * Verifies whether the strategy is applicable for the specified model element.\n\t */\n\tappliesToListItem( element: Item ): boolean;\n\n\t/**\n\t * Verifies whether the model attribute value is valid.\n\t */\n\thasValidAttribute( element: Element ): boolean;\n\n\t/**\n\t * Sets the property on the view element.\n\t */\n\tsetAttributeOnDowncast( writer: DowncastWriter, value: unknown, element: ViewElement ): void;\n\n\t/**\n\t * Retrieves the property value from the view element.\n\t */\n\tgetAttributeOnUpcast( element: ViewElement ): unknown;\n}\n\n/**\n * Creates an array of strategies for dealing with enabled listItem attributes.\n */\nfunction createAttributeStrategies( enabledProperties: ListPropertiesConfig ) {\n\tconst strategies: Array<AttributeStrategy> = [];\n\tconst normalizedConfig = getNormalizedConfig( enabledProperties );\n\n\tif ( enabledProperties.styles ) {\n\t\tconst useAttribute = normalizedConfig.styles.useAttribute;\n\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStyle',\n\t\t\tdefaultValue: DEFAULT_LIST_TYPE,\n\t\t\tviewConsumables: { styles: 'list-style-type' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\tlet supportedTypes = getAllSupportedStyleTypes();\n\n\t\t\t\tif ( useAttribute ) {\n\t\t\t\t\tsupportedTypes = supportedTypes.filter( styleType => !!getTypeAttributeFromListStyleType( styleType ) );\n\t\t\t\t}\n\n\t\t\t\teditor.commands.add( 'listStyle', new ListStyleCommand( editor, DEFAULT_LIST_TYPE, supportedTypes ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered' || item.getAttribute( 'listType' ) == 'bulleted';\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\tif ( !this.appliesToListItem( item ) ) {\n\t\t\t\t\treturn !item.hasAttribute( 'listStyle' );\n\t\t\t\t}\n\n\t\t\t\tif ( !item.hasAttribute( 'listStyle' ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconst value = item.getAttribute( 'listStyle' );\n\n\t\t\t\tif ( value == DEFAULT_LIST_TYPE ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn getListTypeFromListStyleType( value as string ) == item.getAttribute( 'listType' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStyle, element ) {\n\t\t\t\tif ( listStyle && listStyle !== DEFAULT_LIST_TYPE ) {\n\t\t\t\t\tif ( useAttribute ) {\n\t\t\t\t\t\tconst value = getTypeAttributeFromListStyleType( listStyle as string );\n\n\t\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\t\twriter.setAttribute( 'type', value, element );\n\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.setStyle( 'list-style-type', listStyle as string, element );\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\twriter.removeStyle( 'list-style-type', element );\n\t\t\t\twriter.removeAttribute( 'type', element );\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\tconst style = listParent.getStyle( 'list-style-type' );\n\n\t\t\t\tif ( style ) {\n\t\t\t\t\treturn style;\n\t\t\t\t}\n\n\t\t\t\tconst attribute = listParent.getAttribute( 'type' );\n\n\t\t\t\tif ( attribute ) {\n\t\t\t\t\treturn getListStyleTypeFromTypeAttribute( attribute );\n\t\t\t\t}\n\n\t\t\t\treturn DEFAULT_LIST_TYPE;\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listReversed',\n\t\t\tdefaultValue: false,\n\t\t\tviewConsumables: { attributes: 'reversed' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listReversed', new ListReversedCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\treturn this.appliesToListItem( item ) == item.hasAttribute( 'listReversed' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listReversed, element ) {\n\t\t\t\tif ( listReversed ) {\n\t\t\t\t\twriter.setAttribute( 'reversed', 'reversed', element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'reversed', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.hasAttribute( 'reversed' );\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStart',\n\t\t\tdefaultValue: 1,\n\t\t\tviewConsumables: { attributes: 'start' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStart', new ListStartCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn isNumberedListType( item.getAttribute( 'listType' ) as ListType );\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\treturn this.appliesToListItem( item ) == item.hasAttribute( 'listStart' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStart, element ) {\n\t\t\t\tif ( listStart == 0 || ( listStart as number ) > 1 ) {\n\t\t\t\t\twriter.setAttribute( 'start', listStart, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'start', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\tconst startAttributeValue: any = listParent.getAttribute( 'start' );\n\n\t\t\t\treturn startAttributeValue >= 0 ? startAttributeValue : 1;\n\t\t\t}\n\t\t} );\n\t}\n\n\treturn strategies;\n}\n\ndeclare module '../list/listediting' {\n\tinterface ListItemAttributesMap {\n\t\tlistStyle?: string;\n\t\tlistStart?: number;\n\t\tlistReversed?: boolean;\n\t}\n}\n\ndeclare module '../list/utils/model' {\n\tinterface ListElement {\n\t\tgetAttribute( key: 'listStyle' ): string;\n\t\tgetAttribute( key: 'listStart' ): number;\n\t\tgetAttribute( key: 'listReversed' ): boolean;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/ui/listpropertiesview\n */\n\nimport {\n\tView,\n\tViewCollection,\n\tFocusCycler,\n\tSwitchButtonView,\n\tLabeledFieldView,\n\tcreateLabeledInputNumber,\n\taddKeyboardHandlingForGrid,\n\tCollapsibleView,\n\ttype ButtonView,\n\ttype InputNumberView,\n\ttype FocusableView\n} from 'ckeditor5/src/ui.js';\n\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\tglobal,\n\ttype Locale\n} from 'ckeditor5/src/utils.js';\n\nimport type { NormalizedListPropertiesConfig } from '../utils/config.js';\n\nimport '../../../theme/listproperties.css';\n\n/**\n * The list properties view to be displayed in the list dropdown.\n *\n * Contains a grid of available list styles and, for numbered list, also the list start index and reversed fields.\n *\n * @internal\n */\nexport default class ListPropertiesView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public locale: Locale;\n\n\t/**\n\t * A collection of the child views.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * A view that renders the grid of list styles.\n\t */\n\tpublic readonly stylesView: StylesView | null = null;\n\n\t/**\n\t * A collapsible view that hosts additional list property fields ({@link #startIndexFieldView} and\n\t * {@link #reversedSwitchButtonView}) to visually separate them from the {@link #stylesView grid of styles}.\n\t *\n\t * **Note**: Only present when:\n\t * * the view represents **numbered** list properties,\n\t * * and the {@link #stylesView} is rendered,\n\t * * and either {@link #startIndexFieldView} or {@link #reversedSwitchButtonView} is rendered.\n\t *\n\t * @readonly\n\t */\n\tpublic additionalPropertiesCollapsibleView: CollapsibleView | null = null;\n\n\t/**\n\t * A labeled number field allowing the user to set the start index of the list.\n\t *\n\t * **Note**: Only present when the view represents **numbered** list properties.\n\t *\n\t * @readonly\n\t */\n\tpublic startIndexFieldView: LabeledFieldView<InputNumberView> | null = null;\n\n\t/**\n\t * A switch button allowing the user to make the edited list reversed.\n\t *\n\t * **Note**: Only present when the view represents **numbered** list properties.\n\t *\n\t * @readonly\n\t */\n\tpublic reversedSwitchButtonView: SwitchButtonView | null = null;\n\n\t/**\n\t * Tracks information about the DOM focus in the view.\n\t */\n\tpublic readonly focusTracker: FocusTracker = new FocusTracker();\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler = new KeystrokeHandler();\n\n\t/**\n\t * A collection of views that can be focused in the properties view.\n\t */\n\tpublic readonly focusables = new ViewCollection<FocusableView>();\n\n\t/**\n\t * Helps cycling over {@link #focusables} in the view.\n\t */\n\tpublic readonly focusCycler: FocusCycler;\n\n\t/**\n\t * Creates an instance of the list properties view.\n\t *\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options Options of the view.\n\t * @param options.enabledProperties An object containing the configuration of enabled list property names.\n\t * Allows conditional rendering the sub-components of the properties view.\n\t * @param options.styleButtonViews A list of style buttons to be rendered\n\t * inside the styles grid. The grid will not be rendered when `enabledProperties` does not include the `'styles'` key.\n\t * @param options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n\t */\n\tconstructor(\n\t\tlocale: Locale,\n\t\t{ enabledProperties, styleButtonViews, styleGridAriaLabel }: {\n\t\t\tenabledProperties: NormalizedListPropertiesConfig;\n\t\t\tstyleButtonViews: Array<ButtonView> | null;\n\t\t\tstyleGridAriaLabel: string;\n\t\t}\n\t) {\n\t\tsuper( locale );\n\n\t\tconst elementCssClasses = [\n\t\t\t'ck',\n\t\t\t'ck-list-properties'\n\t\t];\n\n\t\tthis.children = this.createCollection();\n\n\t\tthis.focusCycler = new FocusCycler( {\n\t\t\tfocusables: this.focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate #children backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate #children forwards using the <kbd>Tab</kbd> key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t// The rendering of the styles grid is conditional. When there is no styles grid, the view will render without collapsible\n\t\t// for numbered list properties, hence simplifying the layout.\n\t\tif ( styleButtonViews && styleButtonViews.length ) {\n\t\t\tthis.stylesView = this._createStylesView( styleButtonViews!, styleGridAriaLabel );\n\t\t\tthis.children.add( this.stylesView );\n\t\t} else {\n\t\t\telementCssClasses.push( 'ck-list-properties_without-styles' );\n\t\t}\n\n\t\t// The rendering of the numbered list property views is also conditional. It only makes sense for the numbered list\n\t\t// dropdown. The unordered list does not have such properties.\n\t\tif ( enabledProperties.startIndex || enabledProperties.reversed ) {\n\t\t\tthis._addNumberedListPropertyViews( enabledProperties );\n\n\t\t\telementCssClasses.push( 'ck-list-properties_with-numbered-properties' );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: elementCssClasses\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tif ( this.stylesView ) {\n\t\t\tthis.focusables.add( this.stylesView );\n\t\t\tthis.focusTracker.add( this.stylesView.element! );\n\n\t\t\t// Register the collapsible toggle button to the focus system.\n\t\t\tif ( this.startIndexFieldView || this.reversedSwitchButtonView ) {\n\t\t\t\tthis.focusables.add( ( this.children.last as any ).buttonView );\n\t\t\t\tthis.focusTracker.add( ( this.children.last as any ).buttonView.element );\n\t\t\t}\n\n\t\t\tfor ( const item of this.stylesView.children ) {\n\t\t\t\tthis.stylesView.focusTracker.add( item.element! );\n\t\t\t}\n\n\t\t\taddKeyboardHandlingForGrid( {\n\t\t\t\tkeystrokeHandler: this.stylesView.keystrokes,\n\t\t\t\tfocusTracker: this.stylesView.focusTracker,\n\t\t\t\tgridItems: this.stylesView.children,\n\t\t\t\t// Note: The styles view has a different number of columns depending on whether the other properties\n\t\t\t\t// are enabled in the dropdown or not (https://github.com/ckeditor/ckeditor5/issues/12340)\n\t\t\t\tnumberOfColumns: () => global.window\n\t\t\t\t\t.getComputedStyle( this.stylesView!.element! )\n\t\t\t\t\t.getPropertyValue( 'grid-template-columns' )\n\t\t\t\t\t.split( ' ' )\n\t\t\t\t\t.length,\n\t\t\t\tuiLanguageDirection: this.locale && this.locale.uiLanguageDirection\n\t\t\t} );\n\t\t}\n\n\t\tif ( this.startIndexFieldView ) {\n\t\t\tthis.focusables.add( this.startIndexFieldView );\n\t\t\tthis.focusTracker.add( this.startIndexFieldView.element! );\n\n\t\t\tconst stopPropagation = ( data: Event ) => data.stopPropagation();\n\n\t\t\t// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n\t\t\t// keystroke handler would take over the key management in the input. We need to prevent\n\t\t\t// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n\t\t\tthis.keystrokes.set( 'arrowright', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowleft', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowup', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowdown', stopPropagation );\n\t\t}\n\n\t\tif ( this.reversedSwitchButtonView ) {\n\t\t\tthis.focusables.add( this.reversedSwitchButtonView );\n\t\t\tthis.focusTracker.add( this.reversedSwitchButtonView.element! );\n\t\t}\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focus(): void {\n\t\tthis.focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focusLast(): void {\n\t\tthis.focusCycler.focusLast();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Creates the list styles grid.\n\t *\n\t * @param styleButtons Buttons to be placed in the grid.\n\t * @param styleGridAriaLabel The assistive technology label of the grid.\n\t */\n\tprivate _createStylesView( styleButtons: Array<ButtonView>, styleGridAriaLabel: string ) {\n\t\tconst stylesView = new View( this.locale ) as StylesView;\n\n\t\tstylesView.children = stylesView.createCollection();\n\t\tstylesView.children.addMany( styleButtons );\n\n\t\tstylesView.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\t'aria-label': styleGridAriaLabel,\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list-styles-list'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: stylesView.children\n\t\t} );\n\n\t\tstylesView.children.delegate( 'execute' ).to( this );\n\n\t\tstylesView.focus = function( this: any ) {\n\t\t\tthis.children.first.focus();\n\t\t};\n\n\t\tstylesView.focusTracker = new FocusTracker();\n\t\tstylesView.keystrokes = new KeystrokeHandler();\n\n\t\tstylesView.render();\n\n\t\tstylesView.keystrokes.listenTo( stylesView.element! );\n\n\t\treturn stylesView;\n\t}\n\n\t/**\n\t * Renders {@link #startIndexFieldView} and/or {@link #reversedSwitchButtonView} depending on the configuration of the properties view.\n\t *\n\t * @param enabledProperties An object containing the configuration of enabled list property names\n\t * (see {@link #constructor}).\n\t */\n\tprivate _addNumberedListPropertyViews( enabledProperties: NormalizedListPropertiesConfig ) {\n\t\tconst t = this.locale.t;\n\t\tconst numberedPropertyViews = [];\n\n\t\tif ( enabledProperties.startIndex ) {\n\t\t\tthis.startIndexFieldView = this._createStartIndexField();\n\t\t\tnumberedPropertyViews.push( this.startIndexFieldView );\n\t\t}\n\n\t\tif ( enabledProperties.reversed ) {\n\t\t\tthis.reversedSwitchButtonView = this._createReversedSwitchButton();\n\t\t\tnumberedPropertyViews.push( this.reversedSwitchButtonView );\n\t\t}\n\n\t\t// When there are some style buttons, pack the numbered list properties into a collapsible to separate them.\n\t\tif ( this.stylesView ) {\n\t\t\tthis.additionalPropertiesCollapsibleView = new CollapsibleView( this.locale, numberedPropertyViews );\n\n\t\t\tthis.additionalPropertiesCollapsibleView.set( {\n\t\t\t\tlabel: t( 'List properties' ),\n\t\t\t\tisCollapsed: true\n\t\t\t} );\n\n\t\t\t// Don't enable the collapsible view unless either start index or reversed field is enabled (e.g. when no list is selected).\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.bind( 'isEnabled' ).toMany(\n\t\t\t\tnumberedPropertyViews, 'isEnabled', ( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled ) );\n\n\t\t\t// Automatically collapse the additional properties collapsible when either start index or reversed field gets disabled.\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.on( 'change:isEnabled', ( evt, data, isEnabled ) => {\n\t\t\t\tif ( !isEnabled ) {\n\t\t\t\t\tthis.additionalPropertiesCollapsibleView!.isCollapsed = true;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tthis.children.add( this.additionalPropertiesCollapsibleView );\n\t\t} else {\n\t\t\tthis.children.addMany( numberedPropertyViews );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the list start index labeled field.\n\t */\n\tprivate _createStartIndexField() {\n\t\tconst t = this.locale.t;\n\t\tconst startIndexFieldView = new LabeledFieldView( this.locale, createLabeledInputNumber );\n\n\t\tstartIndexFieldView.set( {\n\t\t\tlabel: t( 'Start at' ),\n\t\t\tclass: 'ck-numbered-list-properties__start-index'\n\t\t} );\n\n\t\tstartIndexFieldView.fieldView.set( {\n\t\t\tmin: 0,\n\t\t\tstep: 1,\n\t\t\tvalue: 1,\n\t\t\tinputMode: 'numeric'\n\t\t} );\n\n\t\tstartIndexFieldView.fieldView.on( 'input', () => {\n\t\t\tconst inputElement = startIndexFieldView.fieldView.element!;\n\t\t\tconst startIndex = inputElement.valueAsNumber;\n\n\t\t\tif ( Number.isNaN( startIndex ) ) {\n\t\t\t\t// Number inputs allow for the entry of characters that may result in NaN,\n\t\t\t\t// such as 'e', '+', '123e', '2-'.\n\t\t\t\tstartIndexFieldView.errorText = t( 'Invalid start index value.' );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !inputElement.checkValidity() ) {\n\t\t\t\tstartIndexFieldView.errorText = t( 'Start index must be greater than 0.' );\n\t\t\t} else {\n\t\t\t\tthis.fire<ListPropertiesViewListStartEvent>( 'listStart', { startIndex } );\n\t\t\t}\n\t\t} );\n\n\t\treturn startIndexFieldView;\n\t}\n\n\t/**\n\t * Creates the reversed list switch button.\n\t */\n\tprivate _createReversedSwitchButton() {\n\t\tconst t = this.locale.t;\n\t\tconst reversedButtonView = new SwitchButtonView( this.locale );\n\n\t\treversedButtonView.set( {\n\t\t\twithText: true,\n\t\t\tlabel: t( 'Reversed order' ),\n\t\t\tclass: 'ck-numbered-list-properties__reversed-order'\n\t\t} );\n\n\t\treversedButtonView.delegate( 'execute' ).to( this, 'listReversed' );\n\n\t\treturn reversedButtonView;\n\t}\n}\n\nexport type StylesView = View & {\n\tchildren: ViewCollection;\n\tfocusTracker: FocusTracker;\n\tkeystrokes: KeystrokeHandler;\n\tfocus(): void;\n};\n\n/**\n * Fired when the list start index value has changed via {@link ~ListPropertiesView#startIndexFieldView}.\n *\n * @eventName ~ListPropertiesView#listStart\n */\nexport type ListPropertiesViewListStartEvent = {\n\tname: 'listStart';\n\targs: [ data: { startIndex: number } ];\n};\n\n/**\n * Fired when the list order has changed (reversed) via {@link ~ListPropertiesView#reversedSwitchButtonView}.\n *\n * @eventName ~ListPropertiesView#listReversed\n */\nexport type ListPropertiesViewListReversedEvent = {\n\tname: 'listReversed';\n\targs: [];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties/listpropertiesui\n */\n\nimport { icons, Plugin, type Editor } from 'ckeditor5/src/core.js';\n\nimport {\n\tButtonView,\n\tSplitButtonView,\n\tcreateDropdown,\n\tfocusChildOnDropdownOpen,\n\tMenuBarMenuView,\n\ttype DropdownView\n} from 'ckeditor5/src/ui.js';\n\nimport type { Locale } from 'ckeditor5/src/utils.js';\n\nimport ListPropertiesView from './ui/listpropertiesview.js';\n\nimport type LegacyListStyleCommand from '../legacylistproperties/legacyliststylecommand.js';\nimport type ListStyleCommand from '../listproperties/liststylecommand.js';\nimport type LegacyListStartCommand from '../legacylistproperties/legacyliststartcommand.js';\nimport type ListStartCommand from '../listproperties/liststartcommand.js';\nimport type LegacyListReversedCommand from '../legacylistproperties/legacylistreversedcommand.js';\nimport type ListReversedCommand from '../listproperties/listreversedcommand.js';\n\nimport { getNormalizedConfig, type NormalizedListPropertiesConfig } from './utils/config.js';\nimport { type ListPropertiesStyleListType } from '../listconfig.js';\n\nimport listStyleDiscIcon from '../../theme/icons/liststyledisc.svg';\nimport listStyleCircleIcon from '../../theme/icons/liststylecircle.svg';\nimport listStyleSquareIcon from '../../theme/icons/liststylesquare.svg';\nimport listStyleDecimalIcon from '../../theme/icons/liststyledecimal.svg';\nimport listStyleDecimalWithLeadingZeroIcon from '../../theme/icons/liststyledecimalleadingzero.svg';\nimport listStyleLowerRomanIcon from '../../theme/icons/liststylelowerroman.svg';\nimport listStyleUpperRomanIcon from '../../theme/icons/liststyleupperroman.svg';\nimport listStyleLowerLatinIcon from '../../theme/icons/liststylelowerlatin.svg';\nimport listStyleUpperLatinIcon from '../../theme/icons/liststyleupperlatin.svg';\n\nimport '../../theme/liststyles.css';\n\n/**\n * The list properties UI plugin. It introduces the extended `'bulletedList'` and `'numberedList'` toolbar\n * buttons that allow users to control such aspects of list as the marker, start index or order.\n *\n * **Note**: Buttons introduced by this plugin override implementations from the {@link module:list/list/listui~ListUI}\n * (because they share the same names).\n */\nexport default class ListPropertiesUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ListPropertiesUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst propertiesConfig = editor.config.get( 'list.properties' )!;\n\t\tconst normalizedConfig = getNormalizedConfig( propertiesConfig );\n\t\tconst stylesListTypes = normalizedConfig.styles.listTypes;\n\n\t\t// Note: When this plugin does not register the \"bulletedList\" dropdown due to properties configuration,\n\t\t// a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n\t\t// in most editor configuration because the List plugin automatically requires ListUI.\n\t\tif ( stylesListTypes.includes( 'bulleted' ) ) {\n\t\t\tconst styleDefinitions = [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the disc list style' ),\n\t\t\t\t\ttooltip: t( 'Disc' ),\n\t\t\t\t\ttype: 'disc',\n\t\t\t\t\ticon: listStyleDiscIcon\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the circle list style' ),\n\t\t\t\t\ttooltip: t( 'Circle' ),\n\t\t\t\t\ttype: 'circle',\n\t\t\t\t\ticon: listStyleCircleIcon\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the square list style' ),\n\t\t\t\t\ttooltip: t( 'Square' ),\n\t\t\t\t\ttype: 'square',\n\t\t\t\t\ticon: listStyleSquareIcon\n\t\t\t\t}\n\t\t\t];\n\t\t\tconst buttonLabel = t( 'Bulleted List' );\n\t\t\tconst styleGridAriaLabel = t( 'Bulleted list styles toolbar' );\n\t\t\tconst commandName = 'bulletedList';\n\n\t\t\teditor.ui.componentFactory.add( commandName, getDropdownViewCreator( {\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tparentCommandName: commandName,\n\t\t\t\tbuttonLabel,\n\t\t\t\tbuttonIcon: icons.bulletedList,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t} ) );\n\n\t\t\t// Add the menu bar item for bulleted list.\n\t\t\teditor.ui.componentFactory.add( `menuBar:${ commandName }`, getMenuBarStylesMenuCreator( {\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tparentCommandName: commandName,\n\t\t\t\tbuttonLabel,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t} ) );\n\t\t}\n\n\t\t// Note: When this plugin does not register the \"numberedList\" dropdown due to properties configuration,\n\t\t// a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n\t\t// in most editor configuration because the List plugin automatically requires ListUI.\n\t\tif ( stylesListTypes.includes( 'numbered' ) || propertiesConfig.startIndex || propertiesConfig.reversed ) {\n\t\t\tconst styleDefinitions = [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the decimal list style' ),\n\t\t\t\t\ttooltip: t( 'Decimal' ),\n\t\t\t\t\ttype: 'decimal',\n\t\t\t\t\ticon: listStyleDecimalIcon\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the decimal with leading zero list style' ),\n\t\t\t\t\ttooltip: t( 'Decimal with leading zero' ),\n\t\t\t\t\ttype: 'decimal-leading-zero',\n\t\t\t\t\ticon: listStyleDecimalWithLeadingZeroIcon\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the lower–roman list style' ),\n\t\t\t\t\ttooltip: t( 'Lower–roman' ),\n\t\t\t\t\ttype: 'lower-roman',\n\t\t\t\t\ticon: listStyleLowerRomanIcon\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the upper–roman list style' ),\n\t\t\t\t\ttooltip: t( 'Upper-roman' ),\n\t\t\t\t\ttype: 'upper-roman',\n\t\t\t\t\ticon: listStyleUpperRomanIcon\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the lower–latin list style' ),\n\t\t\t\t\ttooltip: t( 'Lower-latin' ),\n\t\t\t\t\ttype: 'lower-latin',\n\t\t\t\t\ticon: listStyleLowerLatinIcon\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Toggle the upper–latin list style' ),\n\t\t\t\t\ttooltip: t( 'Upper-latin' ),\n\t\t\t\t\ttype: 'upper-latin',\n\t\t\t\t\ticon: listStyleUpperLatinIcon\n\t\t\t\t}\n\t\t\t];\n\t\t\tconst buttonLabel = t( 'Numbered List' );\n\t\t\tconst styleGridAriaLabel = t( 'Numbered list styles toolbar' );\n\t\t\tconst commandName = 'numberedList';\n\n\t\t\teditor.ui.componentFactory.add( commandName, getDropdownViewCreator( {\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tparentCommandName: commandName,\n\t\t\t\tbuttonLabel,\n\t\t\t\tbuttonIcon: icons.numberedList,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t} ) );\n\n\t\t\t// Menu bar menu does not display list start index or reverse UI. If there are no styles enabled,\n\t\t\t// the menu makes no sense and should be omitted.\n\t\t\tif ( stylesListTypes.includes( 'numbered' ) ) {\n\t\t\t\teditor.ui.componentFactory.add( `menuBar:${ commandName }`, getMenuBarStylesMenuCreator( {\n\t\t\t\t\teditor,\n\t\t\t\t\tnormalizedConfig,\n\t\t\t\t\tparentCommandName: commandName,\n\t\t\t\t\tbuttonLabel,\n\t\t\t\t\tstyleGridAriaLabel,\n\t\t\t\t\tstyleDefinitions\n\t\t\t\t} ) );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A helper that returns a function that creates a split button with a toolbar in the dropdown,\n * which in turn contains buttons allowing users to change list styles in the context of the current selection.\n *\n * @param options.editor\n * @param options.normalizedConfig List properties configuration.\n * @param options.parentCommandName The name of the higher-order editor command associated with\n * the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n * @param options.buttonLabel Label of the main part of the split button.\n * @param options.buttonIcon The SVG string of an icon for the main part of the split button.\n * @param options.styleGridAriaLabel The ARIA label for the styles grid in the split button dropdown.\n * @param options.styleDefinitions Definitions of the style buttons.\n * @returns A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\n */\nfunction getDropdownViewCreator( {\n\teditor,\n\tnormalizedConfig,\n\tparentCommandName,\n\tbuttonLabel,\n\tbuttonIcon,\n\tstyleGridAriaLabel,\n\tstyleDefinitions\n}: {\n\teditor: Editor;\n\tnormalizedConfig: Readonly<NormalizedListPropertiesConfig>;\n\tparentCommandName: string;\n\tbuttonLabel: string;\n\tbuttonIcon: string;\n\tstyleGridAriaLabel: string;\n\tstyleDefinitions: Array<StyleDefinition>;\n} ) {\n\tconst parentCommand = editor.commands.get( parentCommandName )!;\n\n\treturn ( locale: Locale ) => {\n\t\tconst dropdownView = createDropdown( locale, SplitButtonView );\n\t\tconst mainButtonView = dropdownView.buttonView;\n\n\t\tdropdownView.bind( 'isEnabled' ).to( parentCommand );\n\t\tdropdownView.class = 'ck-list-styles-dropdown';\n\n\t\t// Main button was clicked.\n\t\tmainButtonView.on( 'execute', () => {\n\t\t\teditor.execute( parentCommandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\tmainButtonView.set( {\n\t\t\tlabel: buttonLabel,\n\t\t\ticon: buttonIcon,\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\tmainButtonView.bind( 'isOn' ).to( parentCommand, 'value', value => !!value );\n\n\t\tdropdownView.once( 'change:isOpen', () => {\n\t\t\tconst listPropertiesView = createListPropertiesView( {\n\t\t\t\teditor,\n\t\t\t\tnormalizedConfig,\n\t\t\t\tdropdownView,\n\t\t\t\tparentCommandName,\n\t\t\t\tstyleGridAriaLabel,\n\t\t\t\tstyleDefinitions\n\t\t\t} );\n\n\t\t\tdropdownView.panelView.children.add( listPropertiesView );\n\t\t} );\n\n\t\t// Focus the editable after executing the command.\n\t\t// Overrides a default behaviour where the focus is moved to the dropdown button (#12125).\n\t\tdropdownView.on( 'execute', () => {\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn dropdownView;\n\t};\n}\n\n/**\n * A helper that returns a function (factory) that creates individual buttons used by users to change styles\n * of lists.\n *\n * @param options.editor\n * @param options.listStyleCommand The instance of the `ListStylesCommand` class.\n * @param options.parentCommandName The name of the higher-order command associated with a\n * particular list style (e.g. \"bulletedList\" is associated with \"square\" and \"numberedList\" is associated with \"roman\").\n * @returns A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\n */\nfunction getStyleButtonCreator( {\n\teditor,\n\tlistStyleCommand,\n\tparentCommandName\n}: {\n\teditor: Editor;\n\tlistStyleCommand: LegacyListStyleCommand | ListStyleCommand;\n\tparentCommandName: string;\n} ) {\n\tconst locale = editor.locale;\n\tconst parentCommand = editor.commands.get( parentCommandName )!;\n\n\treturn ( { label, type, icon, tooltip }: StyleDefinition ) => {\n\t\tconst button = new ButtonView( locale );\n\n\t\tbutton.set( { label, icon, tooltip } );\n\n\t\tlistStyleCommand.on( 'change:value', () => {\n\t\t\tbutton.isOn = listStyleCommand.value === type;\n\t\t} );\n\n\t\tbutton.on( 'execute', () => {\n\t\t\t// If the content the selection is anchored to is a list, let's change its style.\n\t\t\tif ( parentCommand.value ) {\n\t\t\t\t// Remove the list when the current list style is the same as the one that would normally be applied.\n\t\t\t\tif ( listStyleCommand.value === type ) {\n\t\t\t\t\teditor.execute( parentCommandName );\n\t\t\t\t}\n\t\t\t\t// If the current list style is not set in the model or the style is different than the\n\t\t\t\t// one to be applied, simply apply the new style.\n\t\t\t\telse if ( listStyleCommand.value !== type ) {\n\t\t\t\t\teditor.execute( 'listStyle', { type } );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Otherwise, leave the creation of the styled list to the `ListStyleCommand`.\n\t\t\telse {\n\t\t\t\teditor.model.change( () => {\n\t\t\t\t\teditor.execute( 'listStyle', { type } );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\treturn button;\n\t};\n}\n\n/**\n * A helper that creates the properties view for the individual style dropdown.\n *\n * @param options.editor Editor instance.\n * @param options.normalizedConfig List properties configuration.\n * @param options.dropdownView Styles dropdown view that hosts the properties view.\n * @param options.parentCommandName The name of the higher-order editor command associated with\n * the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n * @param options.styleDefinitions Definitions of the style buttons.\n * @param options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n */\nfunction createListPropertiesView( {\n\teditor,\n\tnormalizedConfig,\n\tdropdownView,\n\tparentCommandName,\n\tstyleDefinitions,\n\tstyleGridAriaLabel\n}: {\n\teditor: Editor;\n\tnormalizedConfig: Readonly<NormalizedListPropertiesConfig>;\n\tdropdownView: DropdownView;\n\tparentCommandName: string;\n\tstyleDefinitions: Array<StyleDefinition>;\n\tstyleGridAriaLabel: string;\n} ) {\n\tconst locale = editor.locale;\n\tconst enabledProperties = {\n\t\t...normalizedConfig,\n\n\t\t...( parentCommandName != 'numberedList' ? {\n\t\t\tstartIndex: false,\n\t\t\treversed: false\n\t\t} : null )\n\t};\n\tconst listType = parentCommandName.replace( 'List', '' ) as ListPropertiesStyleListType;\n\n\tlet styleButtonViews = null;\n\n\tif ( normalizedConfig.styles.listTypes.includes( listType ) ) {\n\t\tconst listStyleCommand: LegacyListStyleCommand | ListStyleCommand = editor.commands.get( 'listStyle' )!;\n\n\t\tconst styleButtonCreator = getStyleButtonCreator( {\n\t\t\teditor,\n\t\t\tparentCommandName,\n\t\t\tlistStyleCommand\n\t\t} );\n\n\t\t// The command can be ListStyleCommand or DocumentListStyleCommand.\n\t\tconst isStyleTypeSupported = getStyleTypeSupportChecker( listStyleCommand );\n\n\t\tstyleButtonViews = styleDefinitions.filter( isStyleTypeSupported ).map( styleButtonCreator );\n\t}\n\n\tconst listPropertiesView = new ListPropertiesView( locale, {\n\t\tstyleGridAriaLabel,\n\t\tenabledProperties,\n\t\tstyleButtonViews\n\t} );\n\n\tif ( normalizedConfig.styles.listTypes.includes( listType ) ) {\n\t\t// Accessibility: focus the first active style when opening the dropdown.\n\t\tfocusChildOnDropdownOpen( dropdownView, () => {\n\t\t\treturn listPropertiesView.stylesView!.children.find( ( child: any ) => child.isOn );\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tconst listStartCommand: LegacyListStartCommand | ListStartCommand = editor.commands.get( 'listStart' )!;\n\n\t\tlistPropertiesView.startIndexFieldView!.bind( 'isEnabled' ).to( listStartCommand );\n\t\tlistPropertiesView.startIndexFieldView!.fieldView.bind( 'value' ).to( listStartCommand as any );\n\t\tlistPropertiesView.on( 'listStart', ( evt, data ) => editor.execute( 'listStart', data ) );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tconst listReversedCommand: LegacyListReversedCommand | ListReversedCommand = editor.commands.get( 'listReversed' )!;\n\n\t\tlistPropertiesView.reversedSwitchButtonView!.bind( 'isEnabled' ).to( listReversedCommand );\n\t\tlistPropertiesView.reversedSwitchButtonView!.bind( 'isOn' ).to( listReversedCommand, 'value', value => !!value );\n\t\tlistPropertiesView.on( 'listReversed', () => {\n\t\t\tconst isReversed = listReversedCommand.value;\n\n\t\t\teditor.execute( 'listReversed', { reversed: !isReversed } );\n\t\t} );\n\t}\n\n\t// Make sure applying styles closes the dropdown.\n\tlistPropertiesView.delegate( 'execute' ).to( dropdownView );\n\n\treturn listPropertiesView;\n}\n\n/**\n * A helper that creates the list style submenu for menu bar.\n *\n * @param editor Editor instance.\n * @param normalizedConfig List properties configuration.\n * @param parentCommandName Name of the list command.\n * @param buttonLabel Label of the menu button.\n * @param styleGridAriaLabel ARIA label of the styles grid.\n */\nfunction getMenuBarStylesMenuCreator(\n\t{\n\t\teditor,\n\t\tnormalizedConfig,\n\t\tparentCommandName,\n\t\tbuttonLabel,\n\t\tstyleGridAriaLabel,\n\t\tstyleDefinitions\n\t}: {\n\t\teditor: Editor;\n\t\tnormalizedConfig: Readonly<NormalizedListPropertiesConfig>;\n\t\tparentCommandName: 'bulletedList' | 'numberedList';\n\t\tbuttonLabel: string;\n\t\tstyleGridAriaLabel: string;\n\t\tstyleDefinitions: Array<StyleDefinition>;\n\t}\n) {\n\treturn ( locale: Locale ) => {\n\t\tconst menuView = new MenuBarMenuView( locale );\n\t\tconst listCommand = editor.commands.get( parentCommandName )!;\n\t\tconst listStyleCommand = editor.commands.get( 'listStyle' )!;\n\t\tconst isStyleTypeSupported = getStyleTypeSupportChecker( listStyleCommand );\n\t\tconst styleButtonCreator = getStyleButtonCreator( {\n\t\t\teditor,\n\t\t\tparentCommandName,\n\t\t\tlistStyleCommand\n\t\t} );\n\t\tconst styleButtonViews = styleDefinitions.filter( isStyleTypeSupported ).map( styleButtonCreator );\n\t\tconst listPropertiesView = new ListPropertiesView( locale, {\n\t\t\tstyleGridAriaLabel,\n\t\t\tenabledProperties: {\n\t\t\t\t...normalizedConfig,\n\n\t\t\t\t// Disable list start index and reversed in the menu bar.\n\t\t\t\tstartIndex: false,\n\t\t\t\treversed: false\n\t\t\t},\n\t\t\tstyleButtonViews\n\t\t} );\n\n\t\tlistPropertiesView.delegate( 'execute' ).to( menuView );\n\n\t\tmenuView.buttonView.set( {\n\t\t\tlabel: buttonLabel,\n\t\t\ticon: icons[ parentCommandName ]\n\t\t} );\n\t\tmenuView.panelView.children.add( listPropertiesView );\n\t\tmenuView.bind( 'isEnabled' ).to( listCommand, 'isEnabled' );\n\t\tmenuView.on( 'execute', () => {\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn menuView;\n\t};\n}\n\nfunction getStyleTypeSupportChecker( listStyleCommand: LegacyListStyleCommand | ListStyleCommand ) {\n\tif ( typeof listStyleCommand.isStyleTypeSupported == 'function' ) {\n\t\treturn ( styleDefinition: StyleDefinition ) => listStyleCommand.isStyleTypeSupported( styleDefinition.type );\n\t} else {\n\t\treturn () => true;\n\t}\n}\n\ninterface StyleDefinition {\n\n\t/**\n\t * The label of the style button.\n\t */\n\tlabel: string;\n\n\t/**\n\t * The type of the style button (e.g. \"roman\" or \"circle\").\n\t */\n\ttype: string;\n\n\t/**\n\t * The SVG string of an icon of the style button.\n\t */\n\ticon: string;\n\n\t/**\n\t * The tooltip text of the button (shorter than verbose label).\n\t */\n\ttooltip: string;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/listproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport ListPropertiesEditing from './listproperties/listpropertiesediting.js';\nimport ListPropertiesUI from './listproperties/listpropertiesui.js';\n\n/**\n * The list properties feature.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:list/listproperties/listpropertiesediting~ListPropertiesEditing list properties\n * editing feature} and the {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n */\nexport default class ListProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ListPropertiesEditing, ListPropertiesUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'ListProperties' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/todolist/checktodolistcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport { getAllListItemBlocks } from '../list/utils/model.js';\n\n/**\n * The check to-do command.\n *\n * The command is registered by the {@link module:list/todolist/todolistediting~TodoListEditing} as\n * the `checkTodoList` editor command.\n */\nexport default class CheckTodoListCommand extends Command {\n\t/**\n\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// Refresh command before executing to be sure all values are up to date.\n\t\t// It is needed when selection has changed before command execution, in the same change block.\n\t\tthis.on( 'execute', () => {\n\t\t\tthis.refresh();\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t */\n\tpublic override refresh(): void {\n\t\tconst selectedElements = this._getSelectedItems();\n\n\t\tthis.value = this._getValue( selectedElements );\n\t\tthis.isEnabled = !!selectedElements.length;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply\n\t * the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t * value to decide what it should do.\n\t */\n\tpublic override execute( options: { forceValue?: boolean } = {} ): void {\n\t\tthis.editor.model.change( writer => {\n\t\t\tconst selectedElements = this._getSelectedItems();\n\t\t\tconst value = ( options.forceValue === undefined ) ? !this._getValue( selectedElements ) : options.forceValue;\n\n\t\t\tfor ( const element of selectedElements ) {\n\t\t\t\tif ( value ) {\n\t\t\t\t\twriter.setAttribute( 'todoListChecked', true, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'todoListChecked', element );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns a value for the command.\n\t */\n\tprivate _getValue( selectedElements: Array<Element> ): boolean {\n\t\treturn selectedElements.every( element => element.getAttribute( 'todoListChecked' ) );\n\t}\n\n\t/**\n\t * Gets all to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t */\n\tprivate _getSelectedItems() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\n\t\tconst selectionRange = model.document.selection.getFirstRange()!;\n\t\tconst startElement = selectionRange.start.parent as Element;\n\t\tconst elements: Array<Element> = [];\n\n\t\tif ( schema.checkAttribute( startElement, 'todoListChecked' ) ) {\n\t\t\telements.push( ...getAllListItemBlocks( startElement ) );\n\t\t}\n\n\t\tfor ( const item of selectionRange.getItems( { shallow: true } ) as Iterable<Element> ) {\n\t\t\tif ( schema.checkAttribute( item, 'todoListChecked' ) && !elements.includes( item ) ) {\n\t\t\t\telements.push( ...getAllListItemBlocks( item ) );\n\t\t\t}\n\t\t}\n\n\t\treturn elements;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/todolist/todocheckboxchangeobserver\n */\n\nimport { DomEventObserver, type DomEventData } from 'ckeditor5/src/engine.js';\n\n/**\n * Observes all to-do list checkboxes state changes.\n *\n * Note that this observer is not available by default. To make it available it needs to be added to\n * {@link module:engine/view/view~View} by {@link module:engine/view/view~View#addObserver} method.\n */\nexport default class TodoCheckboxChangeObserver extends DomEventObserver<'change'> {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic readonly domEventType = [ 'change' ] as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvent: Event ): void {\n\t\tif ( domEvent.target ) {\n\t\t\tconst viewTarget = this.view.domConverter.mapDomToView( domEvent.target as HTMLElement );\n\n\t\t\tif (\n\t\t\t\tviewTarget &&\n\t\t\t\tviewTarget.is( 'element', 'input' ) &&\n\t\t\t\tviewTarget.getAttribute( 'type' ) == 'checkbox' &&\n\t\t\t\tviewTarget.findAncestor( { classes: 'todo-list__label' } )\n\t\t\t) {\n\t\t\t\tthis.fire( 'todoCheckboxChange', domEvent );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Fired when the to-do list checkbox is toggled.\n *\n * Introduced by {@link module:list/todolist/todocheckboxchangeobserver~TodoCheckboxChangeObserver}.\n *\n * Note that this event is not available by default. To make it available,\n * {@link module:list/todolist/todocheckboxchangeobserver~TodoCheckboxChangeObserver}\n * needs to be added to {@link module:engine/view/view~View} by the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:list/todolist/todocheckboxchangeobserver~TodoCheckboxChangeObserver\n * @eventName module:engine/view/document~Document#todoCheckboxChange\n * @param data The event data.\n */\nexport type ViewDocumentTodoCheckboxChangeEvent = {\n\tname: 'todoCheckboxChange';\n\targs: [ data: DomEventData<Event> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/todolist/todolistediting\n */\n\nimport {\n\tMatcher,\n\ttype UpcastElementEvent,\n\ttype Model,\n\ttype MatcherPattern,\n\ttype ViewElement,\n\ttype ViewDocumentKeyDownEvent,\n\ttype ViewDocumentArrowKeyEvent,\n\ttype MapperViewToModelPositionEvent,\n\ttype ViewDocumentFragment,\n\ttype SelectionChangeRangeEvent,\n\ttype DocumentFragment,\n\ttype Element\n} from 'ckeditor5/src/engine.js';\n\nimport {\n\tgetCode,\n\tparseKeystroke,\n\tgetLocalizedArrowKeyCodeDirection,\n\ttype GetCallback,\n\ttype Locale\n} from 'ckeditor5/src/utils.js';\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport { getAllListItemBlocks, isFirstBlockOfListItem, isListItemBlock } from '../list/utils/model.js';\nimport ListEditing, {\n\ttype ListEditingCheckElementEvent,\n\ttype ListEditingPostFixerEvent\n} from '../list/listediting.js';\nimport ListCommand from '../list/listcommand.js';\nimport CheckTodoListCommand from './checktodolistcommand.js';\nimport TodoCheckboxChangeObserver, { type ViewDocumentTodoCheckboxChangeEvent } from './todocheckboxchangeobserver.js';\n\nconst ITEM_TOGGLE_KEYSTROKE = /* #__PURE__ */ parseKeystroke( 'Ctrl+Enter' );\n\n/**\n * The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n *\n * It registers the entire functionality of the {@link module:list/list/listediting~ListEditing list editing plugin}\n * and extends it with the commands:\n *\n * - `'todoList'`,\n * - `'checkTodoList'`,\n */\nexport default class TodoListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TodoListEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ListEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst editing = editor.editing;\n\t\tconst listEditing = editor.plugins.get( ListEditing );\n\t\tconst multiBlock = editor.config.get( 'list.multiBlock' );\n\t\tconst elementName = multiBlock ? 'paragraph' : 'listItem';\n\n\t\teditor.commands.add( 'todoList', new ListCommand( editor, 'todo' ) );\n\t\teditor.commands.add( 'checkTodoList', new CheckTodoListCommand( editor ) );\n\n\t\tediting.view.addObserver( TodoCheckboxChangeObserver );\n\n\t\tmodel.schema.extend( '$listItem', { allowAttributes: 'todoListChecked' } );\n\n\t\tmodel.schema.addAttributeCheck( context => {\n\t\t\tconst item = context.last;\n\n\t\t\t// Don't allow `todoListChecked` attribute on elements which are not todo list items.\n\t\t\tif ( !item.getAttribute( 'listItemId' ) || item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}, 'todoListChecked' );\n\n\t\teditor.conversion.for( 'upcast' ).add( dispatcher => {\n\t\t\t// Upcast of to-do list item is based on a checkbox at the beginning of a <li> to keep compatibility with markdown input.\n\t\t\tdispatcher.on( 'element:input', todoItemInputConverter() );\n\n\t\t\t// Priority is set to low to allow generic list item converter to run first.\n\t\t\tdispatcher.on( 'element:li', todoListItemUpcastConverter(), {\n\t\t\t\tpriority: 'low'\n\t\t\t} );\n\n\t\t\t// Consume other elements that are normally generated in data downcast, so they won't get captured by GHS.\n\t\t\tdispatcher.on( 'element:label', elementUpcastConsumingConverter(\n\t\t\t\t{ name: 'label', classes: 'todo-list__label' }\n\t\t\t) );\n\t\t\tdispatcher.on( 'element:label', elementUpcastConsumingConverter(\n\t\t\t\t{ name: 'label', classes: [ 'todo-list__label', 'todo-list__label_without-description' ] }\n\t\t\t) );\n\t\t\tdispatcher.on( 'element:span', elementUpcastConsumingConverter(\n\t\t\t\t{ name: 'span', classes: 'todo-list__label__description' }\n\t\t\t) );\n\n\t\t\tdispatcher.on( 'element:ul', attributeUpcastConsumingConverter(\n\t\t\t\t{ name: 'ul', classes: 'todo-list' }\n\t\t\t) );\n\t\t} );\n\n\t\teditor.conversion.for( 'downcast' ).elementToElement( {\n\t\t\tmodel: elementName,\n\t\t\tview: ( element, { writer } ) => {\n\t\t\t\tif ( isDescriptionBlock( element, listEditing.getListAttributeNames() ) ) {\n\t\t\t\t\treturn writer.createContainerElement( 'span', { class: 'todo-list__label__description' } );\n\t\t\t\t}\n\t\t\t},\n\t\t\tconverterPriority: 'highest'\n\t\t} );\n\n\t\tlistEditing.registerDowncastStrategy( {\n\t\t\tscope: 'list',\n\t\t\tattributeName: 'listType',\n\n\t\t\tsetAttributeOnDowncast( writer, value, element ) {\n\t\t\t\tif ( value == 'todo' ) {\n\t\t\t\t\twriter.addClass( 'todo-list', element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeClass( 'todo-list', element );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tlistEditing.registerDowncastStrategy( {\n\t\t\tscope: 'itemMarker',\n\t\t\tattributeName: 'todoListChecked',\n\n\t\t\tcreateElement( writer, modelElement, { dataPipeline } ) {\n\t\t\t\tif ( modelElement.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst viewElement = writer.createUIElement( 'input', {\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\t...( modelElement.getAttribute( 'todoListChecked' ) ?\n\t\t\t\t\t\t{ checked: 'checked' } :\n\t\t\t\t\t\tnull\n\t\t\t\t\t),\n\t\t\t\t\t...( dataPipeline ?\n\t\t\t\t\t\t{ disabled: 'disabled' } :\n\t\t\t\t\t\t{ tabindex: '-1' }\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\tif ( dataPipeline ) {\n\t\t\t\t\treturn viewElement;\n\t\t\t\t}\n\n\t\t\t\tconst wrapper = writer.createContainerElement( 'span', { contenteditable: 'false' }, viewElement );\n\n\t\t\t\twrapper.getFillerOffset = () => null;\n\n\t\t\t\treturn wrapper;\n\t\t\t},\n\n\t\t\tcanWrapElement( modelElement ) {\n\t\t\t\treturn isDescriptionBlock( modelElement, listEditing.getListAttributeNames() );\n\t\t\t},\n\n\t\t\tcreateWrapperElement( writer, modelElement, { dataPipeline } ) {\n\t\t\t\tconst classes = [ 'todo-list__label' ];\n\n\t\t\t\tif ( !isDescriptionBlock( modelElement, listEditing.getListAttributeNames() ) ) {\n\t\t\t\t\tclasses.push( 'todo-list__label_without-description' );\n\t\t\t\t}\n\n\t\t\t\treturn writer.createAttributeElement( dataPipeline ? 'label' : 'span', {\n\t\t\t\t\tclass: classes.join( ' ' )\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\t// Verifies if a to-do list block requires reconversion of a first item downcasted as an item description.\n\t\tlistEditing.on<ListEditingCheckElementEvent>( 'checkElement', ( evt, { modelElement, viewElement } ) => {\n\t\t\tconst isFirstTodoModelParagraphBlock = isDescriptionBlock( modelElement, listEditing.getListAttributeNames() );\n\t\t\tconst hasViewClass = viewElement.hasClass( 'todo-list__label__description' );\n\n\t\t\tif ( hasViewClass != isFirstTodoModelParagraphBlock ) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// Verifies if a to-do list block requires reconversion of a checkbox element\n\t\t// (for example there is a new paragraph inserted as a first block of a list item).\n\t\tlistEditing.on<ListEditingCheckElementEvent>( 'checkElement', ( evt, { modelElement, viewElement } ) => {\n\t\t\tconst isFirstTodoModelItemBlock = modelElement.getAttribute( 'listType' ) == 'todo' && isFirstBlockOfListItem( modelElement );\n\n\t\t\tlet hasViewItemMarker = false;\n\t\t\tconst viewWalker = editor.editing.view.createPositionBefore( viewElement ).getWalker( { direction: 'backward' } );\n\n\t\t\tfor ( const { item } of viewWalker ) {\n\t\t\t\tif ( item.is( 'element' ) && editor.editing.mapper.toModelElement( item ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( item.is( 'element', 'input' ) && item.getAttribute( 'type' ) == 'checkbox' ) {\n\t\t\t\t\thasViewItemMarker = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( hasViewItemMarker != isFirstTodoModelItemBlock ) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// Make sure that all blocks of the same list item have the same todoListChecked attribute.\n\t\tlistEditing.on<ListEditingPostFixerEvent>( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tfor ( const { node, previousNodeInList } of listNodes ) {\n\t\t\t\t// This is a first item of a nested list.\n\t\t\t\tif ( !previousNodeInList ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( previousNodeInList.getAttribute( 'listItemId' ) != node.getAttribute( 'listItemId' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst previousHasAttribute = previousNodeInList.hasAttribute( 'todoListChecked' );\n\t\t\t\tconst nodeHasAttribute = node.hasAttribute( 'todoListChecked' );\n\n\t\t\t\tif ( nodeHasAttribute && !previousHasAttribute ) {\n\t\t\t\t\twriter.removeAttribute( 'todoListChecked', node );\n\t\t\t\t\tevt.return = true;\n\t\t\t\t}\n\t\t\t\telse if ( !nodeHasAttribute && previousHasAttribute ) {\n\t\t\t\t\twriter.setAttribute( 'todoListChecked', true, node );\n\t\t\t\t\tevt.return = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Make sure that todoListChecked attribute is only present for to-do list items.\n\t\tmodel.document.registerPostFixer( writer => {\n\t\t\tconst changes = model.document.differ.getChanges();\n\t\t\tlet wasFixed = false;\n\n\t\t\tfor ( const change of changes ) {\n\t\t\t\tif ( change.type == 'attribute' && change.attributeKey == 'listType' ) {\n\t\t\t\t\tconst element = change.range.start.nodeAfter!;\n\n\t\t\t\t\tif ( change.attributeOldValue == 'todo' && element.hasAttribute( 'todoListChecked' ) ) {\n\t\t\t\t\t\twriter.removeAttribute( 'todoListChecked', element );\n\t\t\t\t\t\twasFixed = true;\n\t\t\t\t\t}\n\t\t\t\t} else if ( change.type == 'insert' && change.name != '$text' ) {\n\t\t\t\t\tfor ( const { item } of writer.createRangeOn( change.position.nodeAfter! ) ) {\n\t\t\t\t\t\tif ( item.is( 'element' ) && item.getAttribute( 'listType' ) != 'todo' && item.hasAttribute( 'todoListChecked' ) ) {\n\t\t\t\t\t\t\twriter.removeAttribute( 'todoListChecked', item );\n\t\t\t\t\t\t\twasFixed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn wasFixed;\n\t\t} );\n\n\t\t// Toggle check state of selected to-do list items on keystroke.\n\t\tthis.listenTo<ViewDocumentKeyDownEvent>( editing.view.document, 'keydown', ( evt, data ) => {\n\t\t\tif ( getCode( data ) === ITEM_TOGGLE_KEYSTROKE ) {\n\t\t\t\teditor.execute( 'checkTodoList' );\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// Toggle check state of a to-do list item clicked on the checkbox.\n\t\tthis.listenTo<ViewDocumentTodoCheckboxChangeEvent>( editing.view.document, 'todoCheckboxChange', ( evt, data ) => {\n\t\t\tconst viewTarget = data.target;\n\n\t\t\tif ( !viewTarget || !viewTarget.is( 'element', 'input' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst viewPositionAfter = editing.view.createPositionAfter( viewTarget );\n\t\t\tconst modelPositionAfter = editing.mapper.toModelPosition( viewPositionAfter );\n\t\t\tconst modelElement = modelPositionAfter.parent;\n\n\t\t\tif ( modelElement && isListItemBlock( modelElement ) && modelElement.getAttribute( 'listType' ) == 'todo' ) {\n\t\t\t\tthis._handleCheckmarkChange( modelElement );\n\t\t\t}\n\t\t} );\n\n\t\t// Jump at the start/end of the next node on right arrow key press, when selection is before the checkbox.\n\t\t//\n\t\t// <blockquote><p>Foo{}</p></blockquote>\n\t\t// <ul><li><checkbox/>Bar</li></ul>\n\t\t//\n\t\t// press: `->`\n\t\t//\n\t\t// <blockquote><p>Foo</p></blockquote>\n\t\t// <ul><li><checkbox/>{}Bar</li></ul>\n\t\t//\n\t\tthis.listenTo<ViewDocumentArrowKeyEvent>(\n\t\t\tediting.view.document,\n\t\t\t'arrowKey',\n\t\t\tjumpOverCheckmarkOnSideArrowKeyPress( model, editor.locale ),\n\t\t\t{ context: '$text' }\n\t\t);\n\n\t\t// Map view positions inside the checkbox and wrappers to the position in the first block of the list item.\n\t\tthis.listenTo<MapperViewToModelPositionEvent>( editing.mapper, 'viewToModelPosition', ( evt, data ) => {\n\t\t\tconst viewParent = data.viewPosition.parent as ViewElement;\n\n\t\t\tconst isStartOfListItem = viewParent.is( 'attributeElement', 'li' ) && data.viewPosition.offset == 0;\n\t\t\tconst isStartOfListLabel = isLabelElement( viewParent ) && data.viewPosition.offset <= 1;\n\n\t\t\tconst isInInputWrapper = viewParent.is( 'element', 'span' ) &&\n\t\t\t\tviewParent.getAttribute( 'contenteditable' ) == 'false' &&\n\t\t\t\tisLabelElement( viewParent.parent );\n\n\t\t\tif ( !isStartOfListItem && !isStartOfListLabel && !isInInputWrapper ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nodeAfter = data.modelPosition!.nodeAfter;\n\n\t\t\tif ( nodeAfter && nodeAfter.getAttribute( 'listType' ) == 'todo' ) {\n\t\t\t\tdata.modelPosition = model.createPositionAt( nodeAfter, 0 );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\tthis._initAriaAnnouncements();\n\t}\n\n\t/**\n\t * Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t * to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t *\n\t * Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t * is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t * See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t */\n\tprivate _handleCheckmarkChange( listItem: Element ): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst previousSelectionRanges = Array.from( model.document.selection.getRanges() );\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( listItem, 'end' );\n\t\t\teditor.execute( 'checkTodoList' );\n\t\t\twriter.setSelection( previousSelectionRanges );\n\t\t} );\n\t}\n\n\t/**\n\t * Observe when user enters or leaves todo list and set proper aria value in global live announcer.\n\t * This allows screen readers to indicate when the user has entered and left the specified todo list.\n\t *\n\t * @internal\n\t */\n\tprivate _initAriaAnnouncements( ) {\n\t\tconst { model, ui, t } = this.editor;\n\t\tlet lastFocusedCodeBlock: Element | DocumentFragment | null = null;\n\n\t\tif ( !ui ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.document.selection.on<SelectionChangeRangeEvent>( 'change:range', () => {\n\t\t\tconst focusParent = model.document.selection.focus!.parent;\n\t\t\tconst lastElementIsTodoList = isTodoListItemElement( lastFocusedCodeBlock );\n\t\t\tconst currentElementIsTodoList = isTodoListItemElement( focusParent );\n\n\t\t\tif ( lastElementIsTodoList && !currentElementIsTodoList ) {\n\t\t\t\tui.ariaLiveAnnouncer.announce( t( 'Leaving a to-do list' ) );\n\t\t\t} else if ( !lastElementIsTodoList && currentElementIsTodoList ) {\n\t\t\t\tui.ariaLiveAnnouncer.announce( t( 'Entering a to-do list' ) );\n\t\t\t}\n\n\t\t\tlastFocusedCodeBlock = focusParent;\n\t\t} );\n\t}\n}\n\n/**\n * Returns an upcast converter for to-do list items.\n */\nfunction todoListItemUpcastConverter(): GetCallback<UpcastElementEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, schema } = conversionApi;\n\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Group to-do list items by their listItemId attribute to ensure that all items of the same list item have the same checked state.\n\t\tconst groupedItems = Array\n\t\t\t.from( data.modelRange.getItems( { shallow: true } ) )\n\t\t\t.filter( ( item ): item is Element =>\n\t\t\t\titem.getAttribute( 'listType' ) === 'todo' && schema.checkAttribute( item, 'listItemId' )\n\t\t\t)\n\t\t\t.reduce( ( acc, item ) => {\n\t\t\t\tconst listItemId = item.getAttribute( 'listItemId' ) as string;\n\n\t\t\t\tif ( !acc.has( listItemId ) ) {\n\t\t\t\t\tacc.set( listItemId, getAllListItemBlocks( item ) );\n\t\t\t\t}\n\n\t\t\t\treturn acc;\n\t\t\t}, new Map<string, Array<Element>>() );\n\n\t\t// During the upcast, we need to ensure that all items of the same list have the same checked state. From time to time\n\t\t// the checked state of the items can be different when the user pastes content from the clipboard with <input type=\"checkbox\">\n\t\t// that has checked state set to true. In such cases, we need to ensure that all items of the same list have the same checked state.\n\t\t// See more: https://github.com/ckeditor/ckeditor5/issues/15602\n\t\tfor ( const [ , items ] of groupedItems.entries() ) {\n\t\t\tif ( items.some( item => item.getAttribute( 'todoListChecked' ) ) ) {\n\t\t\t\tfor ( const item of items ) {\n\t\t\t\t\twriter.setAttribute( 'todoListChecked', true, item );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Returns an upcast converter that detects a to-do list checkbox and marks the list item as a to-do list.\n */\nfunction todoItemInputConverter(): GetCallback<UpcastElementEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst modelCursor = data.modelCursor;\n\t\tconst modelItem = modelCursor.parent as Element;\n\t\tconst viewItem = data.viewItem;\n\n\t\tif ( !conversionApi.consumable.test( viewItem, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( viewItem.getAttribute( 'type' ) != 'checkbox' || !modelCursor.isAtStart || !modelItem.hasAttribute( 'listType' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconversionApi.consumable.consume( viewItem, { name: true } );\n\n\t\tconst writer = conversionApi.writer;\n\n\t\twriter.setAttribute( 'listType', 'todo', modelItem );\n\n\t\tif ( data.viewItem.hasAttribute( 'checked' ) ) {\n\t\t\twriter.setAttribute( 'todoListChecked', true, modelItem );\n\t\t}\n\n\t\tdata.modelRange = writer.createRange( modelCursor );\n\t};\n}\n\n/**\n * Returns an upcast converter that consumes element matching the given matcher pattern.\n */\nfunction elementUpcastConsumingConverter( matcherPattern: MatcherPattern ): GetCallback<UpcastElementEvent> {\n\tconst matcher = new Matcher( matcherPattern );\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst matcherResult = matcher.match( data.viewItem );\n\n\t\tif ( !matcherResult ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.viewItem, matcherResult.match ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tObject.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t};\n}\n\n/**\n * Returns an upcast converter that consumes attributes matching the given matcher pattern.\n */\nfunction attributeUpcastConsumingConverter( matcherPattern: MatcherPattern ): GetCallback<UpcastElementEvent> {\n\tconst matcher = new Matcher( matcherPattern );\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst matcherResult = matcher.match( data.viewItem );\n\n\t\tif ( !matcherResult ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst match = matcherResult.match;\n\n\t\tmatch.name = false;\n\t\tconversionApi.consumable.consume( data.viewItem, match );\n\t};\n}\n\n/**\n * Returns true if the given list item block should be converted as a description block of a to-do list item.\n */\nfunction isDescriptionBlock( modelElement: Element, listAttributeNames: Array<string> ): boolean {\n\treturn ( modelElement.is( 'element', 'paragraph' ) || modelElement.is( 'element', 'listItem' ) ) &&\n\t\tmodelElement.getAttribute( 'listType' ) == 'todo' &&\n\t\tisFirstBlockOfListItem( modelElement ) &&\n\t\thasOnlyListAttributes( modelElement, listAttributeNames );\n}\n\n/**\n * Returns true if only attributes from the given list are present on the model element.\n */\nfunction hasOnlyListAttributes( modelElement: Element, attributeNames: Array<string> ): boolean {\n\tfor ( const attributeKey of modelElement.getAttributeKeys() ) {\n\t\t// Ignore selection attributes stored on block elements.\n\t\tif ( attributeKey.startsWith( 'selection:' ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ( !attributeNames.includes( attributeKey ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Jump at the start and end of a to-do list item.\n */\nfunction jumpOverCheckmarkOnSideArrowKeyPress( model: Model, locale: Locale ): GetCallback<ViewDocumentArrowKeyEvent> {\n\treturn ( eventInfo, domEventData ) => {\n\t\tconst direction = getLocalizedArrowKeyCodeDirection( domEventData.keyCode, locale.contentLanguageDirection );\n\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = selection.getFirstPosition()!;\n\t\tconst parent = position.parent as Element;\n\n\t\t// Right arrow before a to-do list item.\n\t\tif ( direction == 'right' && position.isAtEnd ) {\n\t\t\tconst newRange = schema.getNearestSelectionRange( model.createPositionAfter( parent ), 'forward' );\n\n\t\t\tif ( !newRange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst newRangeParent = newRange.start.parent;\n\n\t\t\tif ( newRangeParent && isListItemBlock( newRangeParent ) && newRangeParent.getAttribute( 'listType' ) == 'todo' ) {\n\t\t\t\tmodel.change( writer => writer.setSelection( newRange ) );\n\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t\tdomEventData.stopPropagation();\n\t\t\t\teventInfo.stop();\n\t\t\t}\n\t\t}\n\t\t// Left arrow at the beginning of a to-do list item.\n\t\telse if ( direction == 'left' && position.isAtStart && isListItemBlock( parent ) && parent.getAttribute( 'listType' ) == 'todo' ) {\n\t\t\tconst newRange = schema.getNearestSelectionRange( model.createPositionBefore( parent ), 'backward' );\n\n\t\t\tif ( !newRange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodel.change( writer => writer.setSelection( newRange ) );\n\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\n\t\t}\n\t};\n}\n\n/**\n * Returns true if the given element is a label element of a to-do list item.\n */\nfunction isLabelElement( viewElement: ViewElement | ViewDocumentFragment | null ): boolean {\n\treturn !!viewElement && viewElement.is( 'attributeElement' ) && viewElement.hasClass( 'todo-list__label' );\n}\n\n/**\n * Returns true if the given element is a list item model element of a to-do list.\n */\nfunction isTodoListItemElement( element: Element | DocumentFragment | null ): boolean {\n\tif ( !element ) {\n\t\treturn false;\n\t}\n\n\tif ( !element.is( 'element', 'paragraph' ) && !element.is( 'element', 'listItem' ) ) {\n\t\treturn false;\n\t}\n\n\treturn element.getAttribute( 'listType' ) == 'todo';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/todolist/todolistui\n */\n\nimport { createUIComponents } from '../list/utils.js';\nimport { icons, Plugin } from 'ckeditor5/src/core.js';\n\n/**\n * The to-do list UI feature. It introduces the `'todoList'` button that\n * allows to convert elements to and from to-do list items and to indent or outdent them.\n */\nexport default class TodoListUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TodoListUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst t = this.editor.t;\n\n\t\tcreateUIComponents( this.editor, 'todoList', t( 'To-do List' ), icons.todoList );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/todolist\n */\n\nimport TodoListEditing from './todolist/todolistediting.js';\nimport TodoListUI from './todolist/todolistui.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport '../theme/todolist.css';\n\n/**\n * The to-do list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/todolist/todolistediting~TodoListEditing to-do list\n * editing feature} and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n */\nexport default class TodoList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TodoListEditing, TodoListUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TodoList' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylist/legacylistcommand\n */\n\nimport type { Element, Node, Schema } from 'ckeditor5/src/engine.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\n\nimport { first } from 'ckeditor5/src/utils.js';\nimport { type ListType } from '../list/listediting.js';\n\n/**\n * The list command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.\n */\nexport default class LegacyListCommand extends Command {\n\t/**\n\t * The type of the list created by the command.\n\t */\n\tpublic readonly type: ListType;\n\n\t/**\n\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t *\n\t * @readonly\n\t */\n\tdeclare public value: boolean;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param type List type that will be handled by this command.\n\t */\n\tconstructor( editor: Editor, type: ListType ) {\n\t\tsuper( editor );\n\n\t\tthis.type = type;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @param options Command options.\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false`, it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t */\n\tpublic override execute( options: { forceValue?: boolean } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => checkCanBecomeListItem( block, model.schema ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n\n\t\t// If we are turning off items, we are going to rename them to paragraphs.\n\n\t\tmodel.change( writer => {\n\t\t\t// If part of a list got turned off, we need to handle (outdent) all of sub-items of the last turned-off item.\n\t\t\t// To be sure that model is all the time in a good state, we first fix items below turned-off item.\n\t\t\tif ( turnOff ) {\n\t\t\t\t// Start from the model item that is just after the last turned-off item.\n\t\t\t\tlet next = blocks[ blocks.length - 1 ].nextSibling as Element;\n\t\t\t\tlet currentIndent = Number.POSITIVE_INFINITY;\n\t\t\t\tlet changes = [];\n\n\t\t\t\t// Correct indent of all items after the last turned off item.\n\t\t\t\t// Rules that should be followed:\n\t\t\t\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t\t\t\t//    will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t\t\t\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t\t\t\t//    should not end up as a child of any of list items that they were not children of before.\n\t\t\t\t// 3. All other items should have their indent changed relatively to it's parent.\n\t\t\t\t//\n\t\t\t\t// For example:\n\t\t\t\t// 1  * --------\n\t\t\t\t// 2     * --------\n\t\t\t\t// 3        * --------\t\t\t<-- this is turned off.\n\t\t\t\t// 4           * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t\t\t\t// 5              * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 6        * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t\t\t\t// 7           * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 8     * --------\t\t\t\t<-- this has to become indent = 0.\n\t\t\t\t// 9        * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t\t\t\t// 10          * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t\t\t\t// 11          * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t\t\t\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t\t\t\t// 13    * --------\n\t\t\t\t// 14       * --------\n\t\t\t\t//\n\t\t\t\t// After turning off 3 the list becomes:\n\t\t\t\t//\n\t\t\t\t// 1  * --------\n\t\t\t\t// 2     * --------\n\t\t\t\t//\n\t\t\t\t// 3  --------\n\t\t\t\t//\n\t\t\t\t// 4  * --------\n\t\t\t\t// 5     * --------\n\t\t\t\t// 6  * --------\n\t\t\t\t// 7     * --------\n\t\t\t\t// 8  * --------\n\t\t\t\t// 9     * --------\n\t\t\t\t// 10       * --------\n\t\t\t\t// 11       * --------\n\t\t\t\t// 12 * --------\n\t\t\t\t// 13    * --------\n\t\t\t\t// 14       * --------\n\t\t\t\t//\n\t\t\t\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t\t\t\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t\t\t\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t\t\t\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t\t\t\t// less conversion (faster).\n\t\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'listIndent' ) !== 0 ) {\n\t\t\t\t\t// Check each next list item, as long as its indent is bigger than 0.\n\t\t\t\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\t\t\t\tconst indent = next.getAttribute( 'listIndent' ) as number;\n\n\t\t\t\t\t// We check if that's item indent is lower as current relative indent.\n\t\t\t\t\tif ( indent < currentIndent ) {\n\t\t\t\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\t\t\t\tcurrentIndent = indent;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fix indent relatively to current relative indent.\n\t\t\t\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\t\t\t\tconst newIndent = indent - currentIndent;\n\n\t\t\t\t\t// Save the entry in changes array. We do not apply it at the moment, because we will need to\n\t\t\t\t\t// reverse the changes so the last item is changed first.\n\t\t\t\t\t// This is to keep model in correct state all the time.\n\t\t\t\t\tchanges.push( { element: next, listIndent: newIndent } );\n\n\t\t\t\t\t// Find next item.\n\t\t\t\t\tnext = next.nextSibling as Element;\n\t\t\t\t}\n\n\t\t\t\tchanges = changes.reverse();\n\n\t\t\t\tfor ( const item of changes ) {\n\t\t\t\t\twriter.setAttribute( 'listIndent', item.listIndent, item.element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are turning on, we might change some items that are already `listItem`s but with different type.\n\t\t\t// Changing one nested list item to other type should also trigger changing all its siblings so the\n\t\t\t// whole nested list is of the same type.\n\t\t\t// Example (assume changing to numbered list):\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\t//   * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t//      * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t//   * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t//      * ------\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t//      * ---[--\t\t<-- already in selection\n\t\t\t//   * ------\t\t\t<-- already in selection\n\t\t\t//   * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t\t<-- already in selection, but does not cause other list items to change because is top-level\n\t\t\t//   * ---]--\t\t\t<-- already in selection\n\t\t\t//   * ------\t\t\t<-- fix, because preceding list item of this item's list is changed\n\t\t\t//      * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\tif ( !turnOff ) {\n\t\t\t\t// Find lowest indent among selected items. This will be indicator what is the indent of\n\t\t\t\t// top-most list affected by the command.\n\t\t\t\tlet lowestIndent = Number.POSITIVE_INFINITY;\n\n\t\t\t\tfor ( const item of blocks ) {\n\t\t\t\t\tif ( item.is( 'element', 'listItem' ) && ( item.getAttribute( 'listIndent' ) as number ) < lowestIndent ) {\n\t\t\t\t\t\tlowestIndent = item.getAttribute( 'listIndent' ) as number;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Do not execute the fix for top-level lists.\n\t\t\t\tlowestIndent = lowestIndent === 0 ? 1 : lowestIndent;\n\n\t\t\t\t// Fix types of list items that are \"before\" the selected blocks.\n\t\t\t\t_fixType( blocks, true, lowestIndent );\n\n\t\t\t\t// Fix types of list items that are \"after\" the selected blocks.\n\t\t\t\t_fixType( blocks, false, lowestIndent );\n\t\t\t}\n\n\t\t\t// Phew! Now it will be easier :).\n\t\t\t// For each block element that was in the selection, we will either: turn it to list item,\n\t\t\t// turn it to paragraph, or change it's type. Or leave it as it is.\n\t\t\t// Do it in reverse as there might be multiple blocks (same as with changing indents).\n\t\t\tfor ( const element of blocks.reverse() ) {\n\t\t\t\tif ( turnOff && element.name == 'listItem' ) {\n\t\t\t\t\t// We are turning off and the element is a `listItem` - it should be converted to `paragraph`.\n\t\t\t\t\t// List item specific attributes are removed by post fixer.\n\t\t\t\t\twriter.rename( element, 'paragraph' );\n\t\t\t\t} else if ( !turnOff && element.name != 'listItem' ) {\n\t\t\t\t\t// We are turning on and the element is not a `listItem` - it should be converted to `listItem`.\n\t\t\t\t\t// The order of operations is important to keep model in correct state.\n\t\t\t\t\twriter.setAttributes( { listType: this.type, listIndent: 0 }, element );\n\t\t\t\t\twriter.rename( element, 'listItem' );\n\t\t\t\t} else if ( !turnOff && element.name == 'listItem' && element.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\t\t// We are turning on and the element is a `listItem` but has different type - change it's type and\n\t\t\t\t\t// type of it's all siblings that have same indent.\n\t\t\t\t\twriter.setAttribute( 'listType', this.type, element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Event fired by the {@link #execute} method.\n\t\t\t *\n\t\t\t * It allows to execute an action after executing the {@link ~ListCommand#execute} method, for example adjusting\n\t\t\t * attributes of changed blocks.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event _executeCleanup\n\t\t\t */\n\t\t\tthis.fire( '_executeCleanup', blocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */\n\tprivate _getValue(): boolean {\n\t\t// Check whether closest `listItem` ancestor of the position has a correct type.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\treturn !!listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == this.type;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled() {\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Otherwise, check if list item can be inserted at the position start.\n\t\treturn checkCanBecomeListItem( firstBlock, schema );\n\t}\n}\n\n/**\n * Helper function used when one or more list item have their type changed. Fixes type of other list items\n * that are affected by the change (are in same lists) but are not directly in selection. The function got extracted\n * not to duplicated code, as same fix has to be performed before and after selection.\n *\n * @param blocks Blocks that are in selection.\n * @param isBackward Specified whether fix will be applied for blocks before first selected block (`true`)\n * or blocks after last selected block (`false`).\n * @param lowestIndent Lowest indent among selected blocks.\n */\nfunction _fixType(\n\tblocks: Array<Node>,\n\tisBackward: boolean,\n\tlowestIndent: number\n) {\n\t// We need to check previous sibling of first changed item and next siblings of last changed item.\n\tconst startingItem = isBackward ? blocks[ 0 ] : blocks[ blocks.length - 1 ];\n\n\tif ( startingItem.is( 'element', 'listItem' ) ) {\n\t\tlet item = startingItem[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t// During processing items, keeps the lowest indent of already processed items.\n\t\t// This saves us from changing too many items.\n\t\t// Following example is for going forward as it is easier to read, however same applies to going backward.\n\t\t// * ------\n\t\t//   * ------\n\t\t//     * --[---\n\t\t//   * ------\t\t<-- `lowestIndent` should be 1\n\t\t//     * --]---\t\t<-- `startingItem`, `currentIndent` = 2, `lowestIndent` == 1\n\t\t//     * ------\t\t<-- should be fixed, `indent` == 2 == `currentIndent`\n\t\t//   * ------\t\t<-- should be fixed, set `currentIndent` to 1, `indent` == 1 == `currentIndent`\n\t\t//     * ------\t\t<-- should not be fixed, item is in different list, `indent` = 2, `indent` != `currentIndent`\n\t\t//   * ------\t\t<-- should be fixed, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t\t<-- break loop (`indent` < `lowestIndent`)\n\t\tlet currentIndent = startingItem.getAttribute( 'listIndent' ) as number;\n\n\t\t// Look back until a list item with indent lower than reference `lowestIndent`.\n\t\t// That would be the parent of nested sublist which contains item having `lowestIndent`.\n\t\twhile ( item && item.is( 'element', 'listItem' ) && ( item.getAttribute( 'listIndent' ) as number ) >= lowestIndent ) {\n\t\t\tif ( currentIndent > ( item.getAttribute( 'listIndent' ) as number ) ) {\n\t\t\t\tcurrentIndent = item.getAttribute( 'listIndent' ) as number;\n\t\t\t}\n\n\t\t\t// Found an item that is in the same nested sublist.\n\t\t\tif ( item.getAttribute( 'listIndent' ) == currentIndent ) {\n\t\t\t\t// Just add the item to selected blocks like it was selected by the user.\n\t\t\t\tblocks[ isBackward ? 'unshift' : 'push' ]( item );\n\t\t\t}\n\n\t\t\titem = item[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t}\n\t}\n}\n\n/**\n * Checks whether the given block can be replaced by a listItem.\n *\n * @param block A block to be tested.\n * @param schema The schema of the document.\n */\nfunction checkCanBecomeListItem( block: Element, schema: Schema ) {\n\treturn schema.checkChild( block.parent as any, 'listItem' ) && !schema.isObject( block );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylist/legacyindentcommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\n\n/**\n * The list indent command. It is used by the {@link module:list/legacylist~LegacyList legacy list feature}.\n */\nexport default class LegacyIndentCommand extends Command {\n\t/**\n\t * Determines by how much the command will change the list item's indent attribute.\n\t */\n\tprivate readonly _indentBy: 1 | -1;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param indentDirection The direction of indent. If it is equal to `backward`, the command will outdent a list item.\n\t */\n\tconstructor( editor: Editor, indentDirection: 'forward' | 'backward' ) {\n\t\tsuper( editor );\n\n\t\tthis._indentBy = indentDirection == 'forward' ? 1 : -1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tlet itemsToChange = Array.from( doc.selection.getSelectedBlocks() );\n\n\t\tmodel.change( writer => {\n\t\t\tconst lastItem = itemsToChange[ itemsToChange.length - 1 ];\n\n\t\t\t// Indenting a list item should also indent all the items that are already sub-items of indented item.\n\t\t\tlet next = lastItem.nextSibling as Element | null;\n\n\t\t\t// Check all items after last indented item, as long as their indent is bigger than indent of that item.\n\t\t\twhile (\n\t\t\t\tnext && next.name == 'listItem' &&\n\t\t\t\t( next.getAttribute( 'listIndent' ) as number ) > ( lastItem.getAttribute( 'listIndent' ) as number )\n\t\t\t) {\n\t\t\t\titemsToChange.push( next );\n\n\t\t\t\tnext = next.nextSibling as Element | null;\n\t\t\t}\n\n\t\t\t// We need to be sure to keep model in correct state after each small change, because converters\n\t\t\t// bases on that state and assumes that model is correct.\n\t\t\t// Because of that, if the command outdents items, we will outdent them starting from the last item, as\n\t\t\t// it is safer.\n\t\t\tif ( this._indentBy < 0 ) {\n\t\t\t\titemsToChange = itemsToChange.reverse();\n\t\t\t}\n\n\t\t\tfor ( const item of itemsToChange ) {\n\t\t\t\tconst indent = ( item.getAttribute( 'listIndent' ) as number ) + this._indentBy;\n\n\t\t\t\t// If indent is lower than 0, it means that the item got outdented when it was not indented.\n\t\t\t\t// This means that we need to convert that list item to paragraph.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\t// To keep the model as correct as possible, first rename listItem, then remove attributes,\n\t\t\t\t\t// as listItem without attributes is very incorrect and will cause problems in converters.\n\t\t\t\t\t// No need to remove attributes, will be removed by post fixer.\n\t\t\t\t\twriter.rename( item, 'paragraph' );\n\t\t\t\t}\n\t\t\t\t// If indent is >= 0, change the attribute value.\n\t\t\t\telse {\n\t\t\t\t\twriter.setAttribute( 'listIndent', indent, item );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// It allows to execute an action after executing the `~IndentCommand#execute` method, for example adjusting\n\t\t\t// attributes of changed list items.\n\t\t\tthis.fire( '_executeCleanup', itemsToChange );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled() {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !listItem || !listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this._indentBy > 0 ) {\n\t\t\t// Cannot indent first item in it's list. Check if before `listItem` is a list item that is in same list.\n\t\t\t// To be in the same list, the item has to have same attributes and cannot be \"split\" by an item with lower indent.\n\t\t\tconst indent = listItem.getAttribute( 'listIndent' ) as number;\n\t\t\tconst type = listItem.getAttribute( 'listType' ) as string;\n\n\t\t\tlet prev = listItem.previousSibling;\n\n\t\t\twhile ( prev && prev.is( 'element', 'listItem' ) && ( prev.getAttribute( 'listIndent' ) as number ) >= indent ) {\n\t\t\t\tif ( prev.getAttribute( 'listIndent' ) == indent ) {\n\t\t\t\t\t// The item is on the same level.\n\t\t\t\t\t// If it has same type, it means that we found a preceding sibling from the same list.\n\t\t\t\t\t// If it does not have same type, it means that `listItem` is on different list (this can happen only\n\t\t\t\t\t// on top level lists, though).\n\t\t\t\t\treturn prev.getAttribute( 'listType' ) == type;\n\t\t\t\t}\n\n\t\t\t\tprev = prev.previousSibling;\n\t\t\t}\n\n\t\t\t// Could not find similar list item, this means that `listItem` is first in its list.\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylist/legacyutils\n */\n\nimport {\n\tTreeWalker,\n\tgetFillerOffset,\n\ttype DowncastConversionApi,\n\ttype DowncastWriter,\n\ttype Element,\n\ttype Item,\n\ttype Model,\n\ttype Position,\n\ttype ViewContainerElement,\n\ttype ViewElement,\n\ttype ViewItem,\n\ttype ViewPosition\n} from 'ckeditor5/src/engine.js';\n\n/**\n * Creates a list item {@link module:engine/view/containerelement~ContainerElement}.\n *\n * @param writer The writer instance.\n */\nexport function createViewListItemElement( writer: DowncastWriter ): ViewContainerElement {\n\tconst viewItem = writer.createContainerElement( 'li' );\n\n\tviewItem.getFillerOffset = getListItemFillerOffset;\n\n\treturn viewItem;\n}\n\n/**\n * Helper function that creates a `<ul><li></li></ul>` or (`<ol>`) structure out of the given `modelItem` model `listItem` element.\n * Then, it binds the created view list item (`<li>`) with the model `listItem` element.\n * The function then returns the created view list item (`<li>`).\n *\n * @param modelItem Model list item.\n * @param conversionApi Conversion interface.\n * @returns View list element.\n */\nexport function generateLiInUl( modelItem: Item, conversionApi: DowncastConversionApi ): ViewContainerElement {\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\tconst listType = modelItem.getAttribute( 'listType' ) == 'numbered' ? 'ol' : 'ul';\n\tconst viewItem = createViewListItemElement( viewWriter );\n\n\tconst viewList = viewWriter.createContainerElement( listType, null );\n\n\tviewWriter.insert( viewWriter.createPositionAt( viewList, 0 ), viewItem );\n\n\tmapper.bindElements( modelItem as any, viewItem );\n\n\treturn viewItem;\n}\n\n/**\n * Helper function that inserts a view list at a correct place and merges it with its siblings.\n * It takes a model list item element (`modelItem`) and a corresponding view list item element (`injectedItem`). The view list item\n * should be in a view list element (`<ul>` or `<ol>`) and should be its only child.\n * See comments below to better understand the algorithm.\n *\n * @param modelItem Model list item.\n * @param injectedItem\n * @param conversionApi Conversion interface.\n * @param model The model instance.\n */\nexport function injectViewList(\n\tmodelItem: Element,\n\tinjectedItem: ViewContainerElement,\n\tconversionApi: DowncastConversionApi,\n\tmodel: Model\n): void {\n\tconst injectedList = injectedItem.parent as ViewElement;\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// The position where the view list will be inserted.\n\tlet insertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\n\t// 1. Find the previous list item that has the same or smaller indent. Basically we are looking for the first model item\n\t// that is a \"parent\" or \"sibling\" of the injected model item.\n\t// If there is no such list item, it means that the injected list item is the first item in \"its list\".\n\tconst refItem = getSiblingListItem( modelItem.previousSibling, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: modelItem.getAttribute( 'listIndent' ) as number\n\t} );\n\tconst prevItem = modelItem.previousSibling as Element | null;\n\n\tif ( refItem && refItem.getAttribute( 'listIndent' ) == modelItem.getAttribute( 'listIndent' ) ) {\n\t\t// There is a list item with the same indent - we found the same-level sibling.\n\t\t// Break the list after it. The inserted view item will be added in the broken space.\n\t\tconst viewItem = mapper.toViewElement( refItem )!;\n\t\tinsertPosition = viewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\t} else {\n\t\t// There is no list item with the same indent. Check the previous model item.\n\t\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\t\t// If it is a list item, it has to have a lower indent.\n\t\t\t// It means that the inserted item should be added to it as its nested item.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionAt( prevItem, 'end' ) );\n\n\t\t\t// There could be some not mapped elements (eg. span in to-do list) but we need to insert\n\t\t\t// a nested list directly inside the li element.\n\t\t\tconst mappedViewAncestor = mapper.findMappedViewAncestor( insertPosition );\n\t\t\tconst nestedList = findNestedList( mappedViewAncestor );\n\n\t\t\t// If there already is some nested list, then use it's position.\n\t\t\tif ( nestedList ) {\n\t\t\t\tinsertPosition = viewWriter.createPositionBefore( nestedList );\n\t\t\t} else {\n\t\t\t\t// Else just put new list on the end of list item content.\n\t\t\t\tinsertPosition = viewWriter.createPositionAt( mappedViewAncestor, 'end' );\n\t\t\t}\n\t\t} else {\n\t\t\t// The previous item is not a list item (or does not exist at all).\n\t\t\t// Just map the position and insert the view item at the mapped position.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\t\t}\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Insert the view item.\n\tviewWriter.insert( insertPosition, injectedList );\n\n\t// 2. Handle possible children of the injected model item.\n\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\tconst prevView = mapper.toViewElement( prevItem )!;\n\n\t\tconst walkerBoundaries = viewWriter.createRange( viewWriter.createPositionAt( prevView, 0 ), insertPosition );\n\t\tconst walker = walkerBoundaries.getWalker( { ignoreElementEnd: true } );\n\n\t\tfor ( const value of walker ) {\n\t\t\tif ( value.item.is( 'element', 'li' ) ) {\n\t\t\t\tconst breakPosition = viewWriter.breakContainer( viewWriter.createPositionBefore( value.item ) );\n\t\t\t\tconst viewList = value.item.parent as ViewElement;\n\n\t\t\t\tconst targetPosition = viewWriter.createPositionAt( injectedItem, 'end' );\n\t\t\t\tmergeViewLists( viewWriter, targetPosition.nodeBefore!, targetPosition.nodeAfter! );\n\t\t\t\tviewWriter.move( viewWriter.createRangeOn( viewList ), targetPosition );\n\n\t\t\t\t// This is bad, but those lists will be removed soon anyway.\n\t\t\t\t( walker as any )._position = breakPosition;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst nextViewList = injectedList.nextSibling;\n\n\t\tif ( nextViewList && ( nextViewList.is( 'element', 'ul' ) || nextViewList.is( 'element', 'ol' ) ) ) {\n\t\t\tlet lastSubChild = null;\n\n\t\t\tfor ( const child of nextViewList.getChildren() as Iterable<ViewElement> ) {\n\t\t\t\tconst modelChild = mapper.toModelElement( child );\n\n\t\t\t\tif (\n\t\t\t\t\tmodelChild &&\n\t\t\t\t\t( modelChild.getAttribute( 'listIndent' ) as number ) > ( modelItem.getAttribute( 'listIndent' ) as number )\n\t\t\t\t) {\n\t\t\t\t\tlastSubChild = child;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( lastSubChild ) {\n\t\t\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( lastSubChild ) );\n\t\t\t\tviewWriter.move(\n\t\t\t\t\tviewWriter.createRangeOn( lastSubChild.parent as any ),\n\t\t\t\t\tviewWriter.createPositionAt( injectedItem, 'end' )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge the inserted view list with its possible neighbor lists.\n\tmergeViewLists( viewWriter, injectedList, injectedList.nextSibling! );\n\tmergeViewLists( viewWriter, injectedList.previousSibling!, injectedList );\n}\n\n/**\n * Helper function that takes two parameters that are expected to be view list elements, and merges them.\n * The merge happens only if both parameters are list elements of the same type (the same element name and the same class attributes).\n *\n * @param viewWriter The writer instance.\n * @param firstList The first element to compare.\n * @param secondList The second element to compare.\n * @returns The position after merge or `null` when there was no merge.\n */\nexport function mergeViewLists(\n\tviewWriter: DowncastWriter,\n\tfirstList: ViewItem,\n\tsecondList: ViewItem\n): ViewPosition | null;\n\nexport function mergeViewLists(\n\tviewWriter: DowncastWriter,\n\tfirstList: any,\n\tsecondList: any\n): ViewPosition | null {\n\t// Check if two lists are going to be merged.\n\tif ( !firstList || !secondList || ( firstList.name != 'ul' && firstList.name != 'ol' ) ) {\n\t\treturn null;\n\t}\n\n\t// Both parameters are list elements, so compare types now.\n\tif ( firstList.name != secondList.name || firstList.getAttribute( 'class' ) !== secondList.getAttribute( 'class' ) ) {\n\t\treturn null;\n\t}\n\n\treturn viewWriter.mergeContainers( viewWriter.createPositionAfter( firstList ) );\n}\n\n/**\n * Helper function that for a given `view.Position`, returns a `view.Position` that is after all `view.UIElement`s that\n * are after the given position.\n *\n * For example:\n * `<container:p>foo^<ui:span></ui:span><ui:span></ui:span>bar</container:p>`\n * For position ^, the position before \"bar\" will be returned.\n *\n */\nexport function positionAfterUiElements( viewPosition: ViewPosition ): ViewPosition {\n\treturn viewPosition.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n}\n\n/**\n * Helper function that searches for a previous list item sibling of a given model item that meets the given criteria\n * passed by the options object.\n *\n * @param options Search criteria.\n * @param options.sameIndent Whether the sought sibling should have the same indentation.\n * @param options.smallerIndent Whether the sought sibling should have a smaller indentation.\n * @param options.listIndent The reference indentation.\n * @param options.direction Walking direction.\n */\nexport function getSiblingListItem(\n\tmodelItem: Item | null,\n\toptions: {\n\t\tsameIndent?: boolean;\n\t\tsmallerIndent?: boolean;\n\t\tlistIndent?: number;\n\t\tdirection?: 'forward' | 'backward';\n\t}\n): Element | null {\n\tconst sameIndent = !!options.sameIndent;\n\tconst smallerIndent = !!options.smallerIndent;\n\tconst indent = options.listIndent;\n\n\tlet item: any = modelItem;\n\n\twhile ( item && item.name == 'listItem' ) {\n\t\tconst itemIndent = item.getAttribute( 'listIndent' ) as number;\n\n\t\tif ( ( sameIndent && indent == itemIndent ) || ( smallerIndent && indent as number > itemIndent ) ) {\n\t\t\treturn item;\n\t\t}\n\n\t\tif ( options.direction === 'forward' ) {\n\t\t\titem = item.nextSibling;\n\t\t} else {\n\t\t\titem = item.previousSibling;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns a first list view element that is direct child of the given view element.\n */\nexport function findNestedList( viewElement: ViewElement ): ViewElement | null {\n\tfor ( const node of ( viewElement.getChildren() as Iterable<ViewElement> ) ) {\n\t\tif ( node.name == 'ul' || node.name == 'ol' ) {\n\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns an array with all `listItem` elements that represent the same list.\n *\n * It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n *\n * Additionally, if the `position` is inside a list item, that list item will be returned as well.\n *\n * @param position Starting position.\n * @param direction Walking direction.\n */\nexport function getSiblingNodes( position: Position, direction: 'forward' | 'backward' ): Array<Element> {\n\tconst items: Array<Element> = [];\n\tconst listItem = position.parent as Element;\n\tconst walkerOptions = {\n\t\tignoreElementEnd: false,\n\t\tstartPosition: position,\n\t\tshallow: true,\n\t\tdirection\n\t};\n\tconst limitIndent = listItem.getAttribute( 'listIndent' ) as number;\n\tconst nodes = [ ...new TreeWalker( walkerOptions ) ]\n\t\t.filter( value => value.item.is( 'element' ) )\n\t\t.map( value => value.item );\n\n\tfor ( const element of nodes ) {\n\t\t// If found something else than `listItem`, we're out of the list scope.\n\t\tif ( !element.is( 'element', 'listItem' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// If current parsed item has lower indent that element that the element that was a starting point,\n\t\t// it means we left a nested list. Abort searching items.\n\t\t//\n\t\t// ■ List item 1.       [listIndent=0]\n\t\t//     ○ List item 2.[] [listIndent=1], limitIndent = 1,\n\t\t//     ○ List item 3.   [listIndent=1]\n\t\t// ■ List item 4.       [listIndent=0]\n\t\t//\n\t\t// Abort searching when leave nested list.\n\t\tif ( ( element.getAttribute( 'listIndent' ) as number ) < limitIndent ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ■ List item 1.[]     [listIndent=0] limitIndent = 0,\n\t\t//     ○ List item 2.   [listIndent=1]\n\t\t//     ○ List item 3.   [listIndent=1]\n\t\t// ■ List item 4.       [listIndent=0]\n\t\t//\n\t\t// Ignore nested lists.\n\t\tif ( ( element.getAttribute( 'listIndent' ) as number ) > limitIndent ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// ■ List item 1.[]  [listType=bulleted]\n\t\t// 1. List item 2.   [listType=numbered]\n\t\t// 2.List item 3.    [listType=numbered]\n\t\t//\n\t\t// Abort searching when found a different kind of a list.\n\t\tif ( element.getAttribute( 'listType' ) !== listItem.getAttribute( 'listType' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ■ List item 1.[]  [listType=bulleted]\n\t\t// ■ List item 2.    [listType=bulleted]\n\t\t// ○ List item 3.    [listType=bulleted]\n\t\t// ○ List item 4.    [listType=bulleted]\n\t\t//\n\t\t// Abort searching when found a different list style,\n\t\tif ( element.getAttribute( 'listStyle' ) !== listItem.getAttribute( 'listStyle' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ... different direction\n\t\tif ( element.getAttribute( 'listReversed' ) !== listItem.getAttribute( 'listReversed' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ... and different start index\n\t\tif ( element.getAttribute( 'listStart' ) !== listItem.getAttribute( 'listStart' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif ( direction === 'backward' ) {\n\t\t\titems.unshift( element );\n\t\t} else {\n\t\t\titems.push( element );\n\t\t}\n\t}\n\n\treturn items;\n}\n\n/**\n * Returns an array with all `listItem` elements in the model selection.\n *\n * It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n * If no list is selected, it returns an empty array.\n * The order of the elements is not specified.\n *\n * @internal\n */\nexport function getSelectedListItems( model: Model ): Array<Element> {\n\tconst document = model.document;\n\n\t// For all selected blocks find all list items that are being selected\n\t// and update the `listStyle` attribute in those lists.\n\tlet listItems = [ ...document.selection.getSelectedBlocks() ]\n\t\t.filter( element => element.is( 'element', 'listItem' ) )\n\t\t.map( element => {\n\t\t\tconst position = model.change( writer => writer.createPositionAt( element, 0 ) );\n\n\t\t\treturn [\n\t\t\t\t...getSiblingNodes( position, 'backward' ),\n\t\t\t\t...getSiblingNodes( position, 'forward' )\n\t\t\t];\n\t\t} )\n\t\t.flat();\n\n\t// Since `getSelectedBlocks()` can return items that belong to the same list, and\n\t// `getSiblingNodes()` returns the entire list, we need to remove duplicated items.\n\tlistItems = [ ...new Set( listItems ) ];\n\n\treturn listItems;\n}\n\nconst BULLETED_LIST_STYLE_TYPES = [ 'disc', 'circle', 'square' ];\n\n// There's a lot of them (https://www.w3.org/TR/css-counter-styles-3/#typedef-counter-style).\n// Let's support only those that can be selected by ListPropertiesUI.\nconst NUMBERED_LIST_STYLE_TYPES = [\n\t'decimal',\n\t'decimal-leading-zero',\n\t'lower-roman',\n\t'upper-roman',\n\t'lower-latin',\n\t'upper-latin'\n];\n\n/**\n * Checks whether the given list-style-type is supported by numbered or bulleted list.\n */\nexport function getListTypeFromListStyleType( listStyleType: string ): 'bulleted' | 'numbered' | null {\n\tif ( BULLETED_LIST_STYLE_TYPES.includes( listStyleType ) ) {\n\t\treturn 'bulleted';\n\t}\n\n\tif ( NUMBERED_LIST_STYLE_TYPES.includes( listStyleType ) ) {\n\t\treturn 'numbered';\n\t}\n\n\treturn null;\n}\n\n/**\n * Implementation of getFillerOffset for view list item element.\n *\n * @returns Block filler offset or `null` if block filler is not needed.\n */\nfunction getListItemFillerOffset( this: any ): number | null {\n\tconst hasOnlyLists = !this.isEmpty && ( this.getChild( 0 ).name == 'ul' || this.getChild( 0 ).name == 'ol' );\n\n\tif ( this.isEmpty || hasOnlyLists ) {\n\t\treturn 0;\n\t}\n\n\treturn getFillerOffset.call( this );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylist/legacylistutils\n */\n\nimport type { Element, Model, Position } from 'ckeditor5/src/engine.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport {\n\tgetListTypeFromListStyleType,\n\tgetSelectedListItems,\n\tgetSiblingNodes\n} from './legacyutils.js';\n\n/**\n * A set of helpers related to legacy lists.\n */\nexport default class LegacyListUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LegacyListUtils' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether the given list-style-type is supported by numbered or bulleted list.\n\t */\n\tpublic getListTypeFromListStyleType( listStyleType: string ): 'bulleted' | 'numbered' | null {\n\t\treturn getListTypeFromListStyleType( listStyleType );\n\t}\n\n\t/**\n\t * Returns an array with all `listItem` elements in the model selection.\n\t *\n\t * It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n\t * If no list is selected, it returns an empty array.\n\t * The order of the elements is not specified.\n\t */\n\tpublic getSelectedListItems( model: Model ): Array<Element> {\n\t\treturn getSelectedListItems( model );\n\t}\n\n\t/**\n\t * Returns an array with all `listItem` elements that represent the same list.\n\t *\n\t * It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n\t *\n\t * Additionally, if the `position` is inside a list item, that list item will be returned as well.\n\t *\n\t * @param position Starting position.\n\t * @param direction Walking direction.\n\t */\n\tpublic getSiblingNodes( position: Position, direction: 'forward' | 'backward' ): Array<Element> {\n\t\treturn getSiblingNodes( position, direction );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylist/legacyconverters\n */\n\nimport {\n\tTreeWalker,\n\ttype DowncastAttributeEvent,\n\ttype DowncastConversionApi,\n\ttype DowncastInsertEvent,\n\ttype DowncastRemoveEvent,\n\ttype Element,\n\ttype MapperModelToViewPositionEvent,\n\ttype MapperViewToModelPositionEvent,\n\ttype Model,\n\ttype ModelInsertContentEvent,\n\ttype Node,\n\ttype Position,\n\ttype UpcastConversionApi,\n\ttype UpcastElementEvent,\n\ttype EditingView,\n\ttype ViewContainerElement,\n\ttype ViewElement,\n\ttype ViewNode,\n\ttype ViewPosition,\n\ttype ViewTypeCheckable,\n\ttype Writer\n} from 'ckeditor5/src/engine.js';\n\nimport type { GetCallback } from 'ckeditor5/src/utils.js';\n\nimport {\n\tgenerateLiInUl,\n\tinjectViewList,\n\tmergeViewLists,\n\tgetSiblingListItem,\n\tpositionAfterUiElements\n} from './legacyutils.js';\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It creates a `<ul><li></li><ul>` (or `<ol>`) view structure out of a `listItem` model element, inserts it at the correct\n * position, and merges the list with surrounding lists (if available).\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param model Model instance.\n */\nexport function modelViewInsertion( model: Model ): GetCallback<DowncastInsertEvent<Element>> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconsumable.consume( data.item, 'insert' );\n\t\tconsumable.consume( data.item, 'attribute:listType' );\n\t\tconsumable.consume( data.item, 'attribute:listIndent' );\n\n\t\tconst modelItem = data.item;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A model-to-view converter for the `listItem` model element removal.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */\nexport function modelViewRemove( model: Model ): GetCallback<DowncastRemoveEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.position );\n\t\tconst viewStart = viewPosition.getLastMatchingPosition( value => !value.item.is( 'element', 'li' ) );\n\t\tconst viewItem = viewStart.nodeAfter as ViewElement;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item - the one to remove.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Remove the list with the item to remove.\n\t\tconst viewList = viewItem.parent as ViewElement;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tconst removed = viewWriter.remove( removeRange );\n\n\t\t// 3. Merge the whole created by breaking and removing the list.\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 4. Bring back nested list that was in the removed <li>.\n\t\tconst modelItem = conversionApi.mapper.toModelElement( viewItem )!;\n\n\t\thoistNestedLists(\n\t\t\tmodelItem.getAttribute( 'listIndent' ) as number + 1,\n\t\t\tdata.position,\n\t\t\tremoveRange.start,\n\t\t\tviewItem,\n\t\t\tconversionApi,\n\t\t\tmodel\n\t\t);\n\n\t\t// 5. Unbind removed view item and all children.\n\t\tfor ( const child of viewWriter.createRangeIn( removed ).getItems() ) {\n\t\t\tconversionApi.mapper.unbindViewElement( child as ViewElement );\n\t\t}\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * A model-to-view converter for the `type` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes from `<ul>` to `<ol>` (or vice versa). This is accomplished\n * by breaking view elements and changing their name. The next {@link module:list/legacylist/legacyconverters~modelViewMergeAfterChangeType}\n * converter will attempt to merge split nodes.\n *\n * Splitting this conversion into 2 steps makes it possible to add an additional conversion in the middle.\n * Check {@link module:list/legacytodolist/legacytodolistconverters~modelViewChangeType} to see an example of it.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n */\nexport const modelViewChangeType: GetCallback<DowncastAttributeEvent<Element>> = ( evt, data, conversionApi ) => {\n\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\treturn;\n\t}\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item )!;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Break the container after and before the list item.\n\t// This will create a view list with one view list item -- the one that changed type.\n\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t// Change name of the view list that holds the changed view item.\n\t// We cannot just change name property, because that would not render properly.\n\tconst viewList = viewItem.parent as ViewContainerElement;\n\tconst listName = data.attributeNewValue == 'numbered' ? 'ol' : 'ul';\n\n\tviewWriter.rename( listName, viewList );\n};\n\n/**\n * A model-to-view converter that attempts to merge nodes split by {@link module:list/legacylist/legacyconverters~modelViewChangeType}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n */\nexport const modelViewMergeAfterChangeType: GetCallback<DowncastAttributeEvent<Element>> = ( evt, data, conversionApi ) => {\n\tconversionApi.consumable.consume( data.item, evt.name );\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item )!;\n\tconst viewList = viewItem.parent as ViewContainerElement;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Merge the changed view list with other lists, if possible.\n\tmergeViewLists( viewWriter, viewList, viewList.nextSibling! );\n\tmergeViewLists( viewWriter, viewList.previousSibling!, viewList );\n};\n\n/**\n * A model-to-view converter for the `listIndent` attribute change on the `listItem` model element.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */\nexport function modelViewChangeIndent( model: Model ): GetCallback<DowncastAttributeEvent<Element>> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, 'attribute:listIndent' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewItem = conversionApi.mapper.toViewElement( data.item ) as ViewContainerElement;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item -- the one that changed type.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Extract view list with changed view list item and merge \"hole\" possibly created by breaking and removing elements.\n\t\tconst viewList = viewItem.parent as ViewElement;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tviewWriter.remove( removeRange );\n\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 3. Bring back nested list that was in the removed <li>.\n\t\thoistNestedLists(\n\t\t\tdata.attributeOldValue as number + 1,\n\t\t\tdata.range.start,\n\t\t\tremoveRange.start,\n\t\t\tviewItem,\n\t\t\tconversionApi,\n\t\t\tmodel\n\t\t);\n\n\t\t// 4. Inject view list like it is newly inserted.\n\t\tinjectViewList( data.item, viewItem, conversionApi, model );\n\n\t\t// 5. Consume insertion of children inside the item. They are already handled by re-building the item in view.\n\t\tfor ( const child of data.item.getChildren() ) {\n\t\t\tconversionApi.consumable.consume( child, 'insert' );\n\t\t}\n\t};\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/legacylist~LegacyList list feature}. This converter is fired for\n * insert change of every model item, and should be fired before the actual converter. The converter checks whether the inserted\n * model item is a non-`listItem` element. If it is, and it is inserted inside a view list, the converter breaks the\n * list so the model element is inserted to the view parent element corresponding to its model parent element.\n *\n * The converter prevents such situations:\n *\n * ```xml\n * // Model:                        // View:\n * <listItem>foo</listItem>         <ul>\n * <listItem>bar</listItem>             <li>foo</li>\n *                                      <li>bar</li>\n *                                  </ul>\n *\n * // After change:                 // Correct view guaranteed by this converter:\n * <listItem>foo</listItem>         <ul><li>foo</li></ul><p>xxx</p><ul><li>bar</li></ul>\n * <paragraph>xxx</paragraph>       // Instead of this wrong view state:\n * <listItem>bar</listItem>         <ul><li>foo</li><p>xxx</p><li>bar</li></ul>\n * ```\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n */\nexport const modelViewSplitOnInsert: GetCallback<DowncastInsertEvent<Element>> = ( evt, data, conversionApi ) => {\n\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\treturn;\n\t}\n\n\tif ( data.item.name != 'listItem' ) {\n\t\tlet viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst lists = [];\n\n\t\t// Break multiple ULs/OLs if there are.\n\t\t//\n\t\t// Imagine following list:\n\t\t//\n\t\t// 1 --------\n\t\t//   1.1 --------\n\t\t//     1.1.1 --------\n\t\t//     1.1.2 --------\n\t\t//     1.1.3 --------\n\t\t//       1.1.3.1 --------\n\t\t//   1.2 --------\n\t\t//     1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// Insert paragraph after item 1.1.1:\n\t\t//\n\t\t// 1 --------\n\t\t//   1.1 --------\n\t\t//     1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t//     1.1.2 --------\n\t\t//     1.1.3 --------\n\t\t//       1.1.3.1 --------\n\t\t//   1.2 --------\n\t\t//     1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// In this case 1.1.2 has to become beginning of a new list.\n\t\t// We need to break list before 1.1.2 (obvious), then we need to break list also before 1.2.\n\t\t// Then we need to move those broken pieces one after another and merge:\n\t\t//\n\t\t// 1 --------\n\t\t//   1.1 --------\n\t\t//     1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t//   1.1.3 --------\n\t\t//     1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t//   1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\twhile ( ( viewPosition.parent as any ).name == 'ul' || ( viewPosition.parent as any ).name == 'ol' ) {\n\t\t\tviewPosition = viewWriter.breakContainer( viewPosition );\n\n\t\t\tif ( ( viewPosition.parent as any ).name != 'li' ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Remove lists that are after inserted element.\n\t\t\t// They will be brought back later, below the inserted element.\n\t\t\tconst removeStart = viewPosition;\n\t\t\tconst removeEnd = viewWriter.createPositionAt( viewPosition.parent as any, 'end' );\n\n\t\t\t// Don't remove if there is nothing to remove.\n\t\t\tif ( !removeStart.isEqual( removeEnd ) ) {\n\t\t\t\tconst removed = viewWriter.remove( viewWriter.createRange( removeStart, removeEnd ) );\n\t\t\t\tlists.push( removed );\n\t\t\t}\n\n\t\t\tviewPosition = viewWriter.createPositionAfter( viewPosition.parent as any );\n\t\t}\n\n\t\t// Bring back removed lists.\n\t\tif ( lists.length > 0 ) {\n\t\t\tfor ( let i = 0; i < lists.length; i++ ) {\n\t\t\t\tconst previousList = viewPosition.nodeBefore;\n\t\t\t\tconst insertedRange = viewWriter.insert( viewPosition, lists[ i ] );\n\t\t\t\tviewPosition = insertedRange.end;\n\n\t\t\t\t// Don't merge first list! We want a split in that place (this is why this converter is introduced).\n\t\t\t\tif ( i > 0 ) {\n\t\t\t\t\tconst mergePos = mergeViewLists( viewWriter, previousList!, previousList!.nextSibling! );\n\n\t\t\t\t\t// If `mergePos` is in `previousList` it means that the lists got merged.\n\t\t\t\t\t// In this case, we need to fix insert position.\n\t\t\t\t\tif ( mergePos && mergePos.parent == previousList ) {\n\t\t\t\t\t\tviewPosition.offset--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge last inserted list with element after it.\n\t\t\tmergeViewLists( viewWriter, viewPosition.nodeBefore!, viewPosition.nodeAfter! );\n\t\t}\n\t}\n};\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/legacylist~LegacyList list feature}. This converter takes care of\n * merging view lists after something is removed or moved from near them.\n *\n * Example:\n *\n * ```xml\n * // Model:                        // View:\n * <listItem>foo</listItem>         <ul><li>foo</li></ul>\n * <paragraph>xxx</paragraph>       <p>xxx</p>\n * <listItem>bar</listItem>         <ul><li>bar</li></ul>\n *\n * // After change:                 // Correct view guaranteed by this converter:\n * <listItem>foo</listItem>         <ul>\n * <listItem>bar</listItem>             <li>foo</li>\n *                                      <li>bar</li>\n *                                  </ul>\n * ```\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n */\nexport const modelViewMergeAfter: GetCallback<DowncastRemoveEvent> = ( evt, data, conversionApi ) => {\n\tconst viewPosition = conversionApi.mapper.toViewPosition( data.position );\n\tconst viewItemPrev = viewPosition.nodeBefore;\n\tconst viewItemNext = viewPosition.nodeAfter;\n\n\t// Merge lists if something (remove, move) was done from inside of list.\n\t// Merging will be done only if both items are view lists of the same type.\n\t// The check is done inside the helper function.\n\tmergeViewLists( conversionApi.writer, viewItemPrev!, viewItemNext! );\n};\n\n/**\n * A view-to-model converter that converts the `<li>` view elements into the `listItem` model elements.\n *\n * To set correct values of the `listType` and `listIndent` attributes the converter:\n * * checks `<li>`'s parent,\n * * stores and increases the `conversionApi.store.indent` value when `<li>`'s sub-items are converted.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */\nexport const viewModelConverter: GetCallback<UpcastElementEvent> = ( evt, data, conversionApi ) => {\n\tif ( conversionApi.consumable.consume( data.viewItem, { name: true } ) ) {\n\t\tconst writer = conversionApi.writer;\n\n\t\t// 1. Create `listItem` model element.\n\t\tconst listItem = writer.createElement( 'listItem' );\n\n\t\t// 2. Handle `listItem` model element attributes.\n\t\tconst indent = getIndent( data.viewItem );\n\n\t\twriter.setAttribute( 'listIndent', indent, listItem );\n\n\t\t// Set 'bulleted' as default. If this item is pasted into a context,\n\t\tconst type = data.viewItem.parent && ( data.viewItem.parent as any ).name == 'ol' ? 'numbered' : 'bulleted';\n\t\twriter.setAttribute( 'listType', type, listItem );\n\n\t\tif ( !conversionApi.safeInsert( listItem, data.modelCursor ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextPosition = viewToModelListItemChildrenConverter( listItem, data.viewItem.getChildren(), conversionApi );\n\n\t\t// Result range starts before the first item and ends after the last.\n\t\tdata.modelRange = writer.createRange( data.modelCursor, nextPosition );\n\n\t\tconversionApi.updateConversionResult( listItem, data );\n\t}\n};\n\n/**\n * A view-to-model converter for the `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between the `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */\nexport const cleanList: GetCallback<UpcastElementEvent> = ( evt, data, conversionApi ) => {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t// Caching children because when we start removing them iterating fails.\n\t\tconst children = Array.from( data.viewItem.getChildren() );\n\n\t\tfor ( const child of children ) {\n\t\t\tconst isWrongElement = !( child.is( 'element', 'li' ) || isList( child ) );\n\n\t\t\tif ( isWrongElement ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * A view-to-model converter for the `<li>` elements that cleans whitespace formatting from the input view.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */\nexport const cleanListItem: GetCallback<UpcastElementEvent> = ( evt, data, conversionApi ) => {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\tif ( data.viewItem.childCount === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst children = [ ...data.viewItem.getChildren() ];\n\n\t\tlet foundList = false;\n\n\t\tfor ( const child of children ) {\n\t\t\tif ( foundList && !isList( child ) ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\n\t\t\tif ( isList( child ) ) {\n\t\t\t\t// If this is a <ul> or <ol>, do not process it, just mark that we already visited list element.\n\t\t\t\tfoundList = true;\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * Returns a callback for model position to view position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `listItem` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n */\nexport function modelToViewPosition( view: EditingView ): GetCallback<MapperModelToViewPositionEvent> {\n\treturn ( evt, data ) => {\n\t\tif ( data.isPhantom ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.modelPosition.nodeBefore;\n\n\t\tif ( modelItem && modelItem.is( 'element', 'listItem' ) ) {\n\t\t\tconst viewItem = data.mapper.toViewElement( modelItem )!;\n\t\t\tconst topmostViewList = viewItem.getAncestors().find( isList );\n\t\t\tconst walker = view.createPositionAt( viewItem, 0 ).getWalker();\n\n\t\t\tfor ( const value of walker ) {\n\t\t\t\tif ( value.type == 'elementStart' && value.item.is( 'element', 'li' ) ) {\n\t\t\t\t\tdata.viewPosition = value.previousPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t} else if ( value.type == 'elementEnd' && value.item == topmostViewList ) {\n\t\t\t\t\tdata.viewPosition = value.nextPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * The callback for view position to model position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `<li>` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:viewToModelPosition\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */\nexport function viewToModelPosition( model: Model ): GetCallback<MapperViewToModelPositionEvent> {\n\treturn ( evt, data ) => {\n\t\tconst viewPos = data.viewPosition;\n\t\tconst viewParent = viewPos.parent as ViewElement;\n\t\tconst mapper = data.mapper;\n\n\t\tif ( viewParent.name == 'ul' || viewParent.name == 'ol' ) {\n\t\t\t// Position is directly in <ul> or <ol>.\n\t\t\tif ( !viewPos.isAtEnd ) {\n\t\t\t\t// If position is not at the end, it must be before <li>.\n\t\t\t\t// Get that <li>, map it to `listItem` and set model position before that `listItem`.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeAfter as any )!;\n\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode );\n\t\t\t} else {\n\t\t\t\t// Position is at the end of <ul> or <ol>, so there is no <li> after it to be mapped.\n\t\t\t\t// There is <li> before the position, but we cannot just map it to `listItem` and set model position after it,\n\t\t\t\t// because that <li> may contain nested items.\n\t\t\t\t// We will check \"model length\" of that <li>, in other words - how many `listItem`s are in that <li>.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeBefore as any );\n\t\t\t\tconst modelLength = mapper.getModelLength( viewPos.nodeBefore! );\n\n\t\t\t\t// Then we get model position before mapped `listItem` and shift it accordingly.\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode! ).getShiftedBy( modelLength );\n\t\t\t}\n\n\t\t\tevt.stop();\n\t\t} else if (\n\t\t\tviewParent.name == 'li' &&\n\t\t\tviewPos.nodeBefore &&\n\t\t\t( ( viewPos.nodeBefore as any ).name == 'ul' || ( viewPos.nodeBefore as any ).name == 'ol' )\n\t\t) {\n\t\t\t// In most cases when view position is in <li> it is in text and this is a correct position.\n\t\t\t// However, if position is after <ul> or <ol> we have to fix it -- because in model <ul>/<ol> are not in the `listItem`.\n\t\t\tconst modelNode = mapper.toModelElement( viewParent );\n\n\t\t\t// Check all <ul>s and <ol>s that are in the <li> but before mapped position.\n\t\t\t// Get model length of those elements and then add it to the offset of `listItem` mapped to the original <li>.\n\t\t\tlet modelLength = 1; // Starts from 1 because the original <li> has to be counted in too.\n\t\t\tlet viewList: ViewNode | null = viewPos.nodeBefore;\n\n\t\t\twhile ( viewList && isList( viewList ) ) {\n\t\t\t\tmodelLength += mapper.getModelLength( viewList );\n\n\t\t\t\tviewList = viewList.previousSibling;\n\t\t\t}\n\n\t\t\tdata.modelPosition = model.createPositionBefore( modelNode! ).getShiftedBy( modelLength );\n\n\t\t\tevt.stop();\n\t\t}\n\t};\n}\n\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states.\n *\n * In the example below, there is a correct list structure.\n * Then the middle element is removed so the list structure will become incorrect:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>Item 2</listItem>   <--- this is removed.\n * <listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n * ```\n *\n * The list structure after the middle element is removed:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n * <listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>Item 3</listItem>   <--- note that indent got post-fixed.\n * ```\n *\n * @param model The data model.\n * @param writer The writer to do changes with.\n * @returns `true` if any change has been applied, `false` otherwise.\n */\nexport function modelChangePostFixer( model: Model, writer: Writer ): boolean {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = new Map<Element, Element>();\n\n\tlet applied = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'insert' && entry.name != 'listItem' ) {\n\t\t\tif ( entry.name != '$text' ) {\n\t\t\t\t// In case of renamed element.\n\t\t\t\tconst item = entry.position.nodeAfter as Element;\n\n\t\t\t\tif ( item.hasAttribute( 'listIndent' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listIndent', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listType' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listType', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listStyle' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listStyle', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listReversed' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listReversed', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listStart' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listStart', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tfor ( const innerItem of Array.from( model.createRangeIn( item ) ).filter( e => e.item.is( 'element', 'listItem' ) ) ) {\n\t\t\t\t\t_addListToFix( innerItem.previousPosition );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst posAfter = entry.position.getShiftedBy( entry.length );\n\n\t\t\t_addListToFix( posAfter );\n\t\t} else if ( entry.type == 'remove' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listIndent' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listType' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t}\n\t}\n\n\tfor ( const listHead of itemToListHead.values() ) {\n\t\t_fixListIndents( listHead );\n\t\t_fixListTypes( listHead );\n\t}\n\n\treturn applied;\n\n\tfunction _addListToFix( position: Position ) {\n\t\tconst previousNode = position.nodeBefore;\n\n\t\tif ( !previousNode || !previousNode.is( 'element', 'listItem' ) ) {\n\t\t\tconst item = position.nodeAfter;\n\n\t\t\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\t\titemToListHead.set( item, item );\n\t\t\t}\n\t\t} else {\n\t\t\tlet listHead = previousNode;\n\n\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (\n\t\t\t\t// Cache previousSibling and reuse for performance reasons. See #6581.\n\t\t\t\tlet previousSibling = listHead.previousSibling;\n\t\t\t\tpreviousSibling && previousSibling.is( 'element', 'listItem' );\n\t\t\t\tpreviousSibling = listHead.previousSibling\n\t\t\t) {\n\t\t\t\tlistHead = previousSibling;\n\n\t\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titemToListHead.set( previousNode, listHead );\n\t\t}\n\t}\n\n\tfunction _fixListIndents( item: Node | null ) {\n\t\tlet maxIndent = 0;\n\t\tlet fixBy = null;\n\n\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' ) as number;\n\n\t\t\tif ( itemIndent > maxIndent ) {\n\t\t\t\tlet newIndent;\n\n\t\t\t\tif ( fixBy === null ) {\n\t\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\t\tnewIndent = maxIndent;\n\t\t\t\t} else {\n\t\t\t\t\tif ( fixBy > itemIndent ) {\n\t\t\t\t\t\tfixBy = itemIndent;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t\t}\n\n\t\t\t\twriter.setAttribute( 'listIndent', newIndent, item );\n\n\t\t\t\tapplied = true;\n\t\t\t} else {\n\t\t\t\tfixBy = null;\n\t\t\t\tmaxIndent = item.getAttribute( 'listIndent' ) as number + 1;\n\t\t\t}\n\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n\n\tfunction _fixListTypes( item: Node | null ) {\n\t\tlet typesStack: Array<string> = [];\n\t\tlet prev = null;\n\n\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' ) as number;\n\n\t\t\tif ( prev && prev.getAttribute( 'listIndent' ) as number > itemIndent ) {\n\t\t\t\ttypesStack = typesStack.slice( 0, itemIndent + 1 );\n\t\t\t}\n\n\t\t\tif ( itemIndent != 0 ) {\n\t\t\t\tif ( typesStack[ itemIndent ] ) {\n\t\t\t\t\tconst type = typesStack[ itemIndent ];\n\n\t\t\t\t\tif ( item.getAttribute( 'listType' ) != type ) {\n\t\t\t\t\t\twriter.setAttribute( 'listType', type, item );\n\n\t\t\t\t\t\tapplied = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttypesStack[ itemIndent ] = item.getAttribute( 'listType' ) as string;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprev = item;\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n}\n\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>A</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>B^</listItem>\n * // At ^ paste:  <listItem listType=\"bulleted\" listIndent=4>X</listItem>\n * //              <listItem listType=\"bulleted\" listIndent=5>Y</listItem>\n * <listItem listType=\"bulleted\" listIndent=2>C</listItem>\n * ```\n *\n * Should become:\n *\n * ```xml\n * <listItem listType=\"bulleted\" listIndent=0>A</listItem>\n * <listItem listType=\"bulleted\" listIndent=1>BX</listItem>\n * <listItem listType=\"bulleted\" listIndent=2>Y/listItem>\n * <listItem listType=\"bulleted\" listIndent=2>C</listItem>\n * ```\n */\nexport const modelIndentPasteFixer: GetCallback<ModelInsertContentEvent> = function( evt, [ content, selectable ] ) {\n\tconst model = this as Model;\n\n\t// Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n\t// elements before it and there is no need to fix indents, because even if we insert that content into a list,\n\t// that list will be broken.\n\t// Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n\t// would create incorrect model.\n\tlet item = content.is( 'documentFragment' ) ? content.getChild( 0 ) : content;\n\n\tlet selection;\n\n\tif ( !selectable ) {\n\t\tselection = model.document.selection;\n\t} else {\n\t\tselection = model.createSelection( selectable );\n\t}\n\n\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t// Get a reference list item. Inserted list items will be fixed according to that item.\n\t\tconst pos = selection.getFirstPosition()!;\n\t\tlet refItem = null;\n\n\t\tif ( pos.parent.is( 'element', 'listItem' ) ) {\n\t\t\trefItem = pos.parent;\n\t\t} else if ( pos.nodeBefore && pos.nodeBefore.is( 'element', 'listItem' ) ) {\n\t\t\trefItem = pos.nodeBefore;\n\t\t}\n\n\t\t// If there is `refItem` it means that we do insert list items into an existing list.\n\t\tif ( refItem ) {\n\t\t\t// First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n\t\t\t// to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n\t\t\t// Indent of all those items has to be adjusted to reference item.\n\t\t\tconst indentChange = refItem.getAttribute( 'listIndent' ) as number;\n\n\t\t\t// Fix only if there is anything to fix.\n\t\t\tif ( indentChange > 0 ) {\n\t\t\t\t// Adjust indent of all \"first\" list items in inserted data.\n\t\t\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\t\t\titem._setAttribute( 'listIndent', item.getAttribute( 'listIndent' ) as number + indentChange );\n\n\t\t\t\t\titem = item.nextSibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n/**\n * Helper function that converts children of a given `<li>` view element into corresponding model elements.\n * The function maintains proper order of elements if model `listItem` is split during the conversion\n * due to block children conversion.\n *\n * @param listItemModel List item model element to which converted children will be inserted.\n * @param viewChildren View elements which will be converted.\n * @param conversionApi Conversion interface to be used by the callback.\n * @returns Position on which next elements should be inserted after children conversion.\n */\nfunction viewToModelListItemChildrenConverter(\n\tlistItemModel: Element,\n\tviewChildren: Iterable<ViewNode>,\n\tconversionApi: UpcastConversionApi\n) {\n\tconst { writer, schema } = conversionApi;\n\n\t// A position after the last inserted `listItem`.\n\tlet nextPosition = writer.createPositionAfter( listItemModel );\n\n\t// Check all children of the converted `<li>`. At this point we assume there are no \"whitespace\" view text nodes\n\t// in view list, between view list items. This should be handled by `<ul>` and `<ol>` converters.\n\tfor ( const child of viewChildren ) {\n\t\tif ( ( child as any ).name == 'ul' || ( child as any ).name == 'ol' ) {\n\t\t\t// If the children is a list, we will insert its conversion result after currently handled `listItem`.\n\t\t\t// Then, next insertion position will be set after all the new list items (and maybe other elements if\n\t\t\t// something split list item).\n\t\t\t//\n\t\t\t// If this is a list, we expect that some `listItem`s and possibly other blocks will be inserted, however `.modelCursor`\n\t\t\t// should be set after last `listItem` (or block). This is why it feels safe to use it as `nextPosition`\n\t\t\tnextPosition = conversionApi.convertItem( child, nextPosition ).modelCursor;\n\t\t} else {\n\t\t\t// If this is not a list, try inserting content at the end of the currently handled `listItem`.\n\t\t\tconst result = conversionApi.convertItem( child, writer.createPositionAt( listItemModel, 'end' ) );\n\n\t\t\t// It may end up that the current `listItem` becomes split (if that content cannot be inside `listItem`). For example:\n\t\t\t//\n\t\t\t// <li><p>Foo</p></li>\n\t\t\t//\n\t\t\t// will be converted to:\n\t\t\t//\n\t\t\t// <listItem></listItem><paragraph>Foo</paragraph><listItem></listItem>\n\t\t\t//\n\t\t\tconst convertedChild = result.modelRange!.start.nodeAfter;\n\t\t\tconst wasSplit = convertedChild && convertedChild.is( 'element' ) && !schema.checkChild( listItemModel, convertedChild.name );\n\n\t\t\tif ( wasSplit ) {\n\t\t\t\t// As `lastListItem` got split, we need to update it to the second part of the split `listItem` element.\n\t\t\t\t//\n\t\t\t\t// `modelCursor` should be set to a position where the conversion should continue. There are multiple possible scenarios\n\t\t\t\t// that may happen. Usually, `modelCursor` (marked as `#` below) would point to the second list item after conversion:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><p>Foo</p></li>` -> `<listItem></listItem><paragraph>Foo</paragraph><listItem>#</listItem>`\n\t\t\t\t//\n\t\t\t\t// However, in some cases, like auto-paragraphing, the position is placed at the end of the block element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div>Foo</div></li>` -> `<listItem></listItem><paragraph>Foo#</paragraph><listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// or after an element if another element broken auto-paragraphed element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div><h2>Foo</h2></div></li>` -> `<listItem></listItem><heading1>Foo</heading1>#<listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// We need to check for such cases and use proper list item and position based on it.\n\t\t\t\t//\n\t\t\t\tif ( result.modelCursor.parent.is( 'element', 'listItem' ) ) {\n\t\t\t\t\t// (1).\n\t\t\t\t\tlistItemModel = result.modelCursor.parent;\n\t\t\t\t} else {\n\t\t\t\t\t// (2), (3).\n\t\t\t\t\tlistItemModel = findNextListItem( result.modelCursor );\n\t\t\t\t}\n\n\t\t\t\tnextPosition = writer.createPositionAfter( listItemModel );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nextPosition;\n}\n\n/**\n * Helper function that seeks for a next list item starting from given `startPosition`.\n */\nfunction findNextListItem( startPosition: Position ) {\n\tconst treeWalker = new TreeWalker( { startPosition } );\n\n\tlet value;\n\n\tdo {\n\t\tvalue = treeWalker.next();\n\t} while ( !value.value.item.is( 'element', 'listItem' ) );\n\n\treturn value.value.item;\n}\n\n/**\n * Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according\n * to other given parameters.\n */\nfunction hoistNestedLists(\n\tnextIndent: number,\n\tmodelRemoveStartPosition: Position,\n\tviewRemoveStartPosition: ViewPosition,\n\tviewRemovedItem: ViewElement,\n\tconversionApi: DowncastConversionApi,\n\tmodel: Model\n) {\n\t// Find correct previous model list item element.\n\t// The element has to have either same or smaller indent than given reference indent.\n\t// This will be the model element which will get nested items (if it has smaller indent) or sibling items (if it has same indent).\n\t// Keep in mind that such element might not be found, if removed item was the first item.\n\tconst prevModelItem = getSiblingListItem( modelRemoveStartPosition.nodeBefore, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: nextIndent\n\t} );\n\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Indent of found element or `null` if the element has not been found.\n\tconst prevIndent = prevModelItem ? prevModelItem.getAttribute( 'listIndent' ) : null;\n\n\tlet insertPosition;\n\n\tif ( !prevModelItem ) {\n\t\t// If element has not been found, simply insert lists at the position where the removed item was:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1 --------           <--- this is removed, no previous list item, put nested items in place of removed item.\n\t\t//   1.1 --------       <--- this is reference indent.\n\t\t//     1.1.1 --------\n\t\t//     1.1.2 --------\n\t\t//   1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1.1 --------\n\t\t//   1.1.1 --------\n\t\t//   1.1.2 --------\n\t\t// 1.2 --------\n\t\tinsertPosition = viewRemoveStartPosition;\n\t} else if ( prevIndent == nextIndent ) {\n\t\t// If element has been found and has same indent as reference indent it means that nested items should\n\t\t// become siblings of found element:\n\t\t//\n\t\t// 1 --------\n\t\t//   1.1 --------\n\t\t//   1.2 --------       <--- this is `prevModelItem`.\n\t\t// 2 --------           <--- this is removed, previous list item has indent same as reference indent.\n\t\t//   2.1 --------       <--- this is reference indent, this and 2.2 should become siblings of 1.2.\n\t\t//   2.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t//   1.1 --------\n\t\t//   1.2 --------\n\t\t//   2.1 --------\n\t\t//   2.2 --------\n\t\tconst prevViewList = mapper.toViewElement( prevModelItem )!.parent as ViewElement;\n\t\tinsertPosition = viewWriter.createPositionAfter( prevViewList );\n\t} else {\n\t\t// If element has been found and has smaller indent as reference indent it means that nested items\n\t\t// should become nested items of found item:\n\t\t//\n\t\t// 1 --------           <--- this is `prevModelItem`.\n\t\t//   1.1 --------       <--- this is removed, previous list item has indent smaller than reference indent.\n\t\t//     1.1.1 --------   <--- this is reference indent, this and 1.1.1 should become nested items of 1.\n\t\t//     1.1.2 --------\n\t\t//   1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t//   1.1.1 --------\n\t\t//   1.1.2 --------\n\t\t//   1.2 --------\n\t\t//\n\t\t// Note: in this case 1.1.1 have indent 2 while 1 have indent 0. In model that should not be possible,\n\t\t// because following item may have indent bigger only by one. But this is fixed by postfixer.\n\t\tconst modelPosition = model.createPositionAt( prevModelItem, 'end' );\n\t\tinsertPosition = mapper.toViewPosition( modelPosition );\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Handle multiple lists. This happens if list item has nested numbered and bulleted lists. Following lists\n\t// are inserted after the first list (no need to recalculate insertion position for them).\n\tfor ( const child of [ ...viewRemovedItem.getChildren() ] ) {\n\t\tif ( isList( child ) ) {\n\t\t\tinsertPosition = viewWriter.move( viewWriter.createRangeOn( child ), insertPosition ).end;\n\n\t\t\tmergeViewLists( viewWriter, child, child.nextSibling! );\n\t\t\tmergeViewLists( viewWriter, child.previousSibling!, child );\n\t\t}\n\t}\n}\n\n/**\n * Checks if view element is a list type (ul or ol).\n */\nfunction isList( viewElement: ViewTypeCheckable ): viewElement is ViewElement & { name: 'ol' | 'ul' } {\n\treturn viewElement.is( 'element', 'ol' ) || viewElement.is( 'element', 'ul' );\n}\n\n/**\n * Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n *\n * Also, fixes non HTML compliant lists indents:\n *\n * ```\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI     (indent: 0)\n *     |-> OL                                  |-> OL\n *         |-> OL                                  |\n *         |   |-> OL                              |\n *         |       |-> OL                          |\n *         |           |-> LI (parent LIs: 1)      |-> LI (indent: 1)\n *         |-> LI (parent LIs: 1)                  |-> LI (indent: 1)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> OL                                      |\n *     |-> OL                                  |\n *          |-> OL                             |\n *              |-> LI (parent LIs: 0)         |-> LI        (indent: 0)\n *\n * before:                                     fixed list:\n * OL                                          OL\n * |-> LI (parent LIs: 0)                      |-> LI         (indent: 0)\n * |-> OL                                          |-> OL\n *     |-> LI (parent LIs: 0)                          |-> LI (indent: 1)\n * ```\n */\nfunction getIndent( listItem: ViewElement ) {\n\tlet indent = 0;\n\n\tlet parent = listItem.parent as ViewElement;\n\n\twhile ( parent ) {\n\t\t// Each LI in the tree will result in an increased indent for HTML compliant lists.\n\t\tif ( parent.is( 'element', 'li' ) ) {\n\t\t\tindent++;\n\t\t} else {\n\t\t\t// If however the list is nested in other list we should check previous sibling of any of the list elements...\n\t\t\tconst previousSibling = parent.previousSibling;\n\n\t\t\t// ...because the we might need increase its indent:\n\t\t\t//\t\tbefore:                           fixed list:\n\t\t\t//\t\tOL                                OL\n\t\t\t//\t\t|-> LI (parent LIs: 0)            |-> LI         (indent: 0)\n\t\t\t//\t\t|-> OL                                |-> OL\n\t\t\t//\t\t    |-> LI (parent LIs: 0)                |-> LI (indent: 1)\n\t\t\tif ( previousSibling && previousSibling.is( 'element', 'li' ) ) {\n\t\t\t\tindent++;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parent as ViewElement;\n\t}\n\n\treturn indent;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylist/legacylistediting\n */\n\nimport LegacyListCommand from './legacylistcommand.js';\nimport LegacyIndentCommand from './legacyindentcommand.js';\nimport LegacyListUtils from './legacylistutils.js';\n\nimport { Plugin, type MultiCommand } from 'ckeditor5/src/core.js';\n\nimport { Enter, type ViewDocumentEnterEvent } from 'ckeditor5/src/enter.js';\nimport { Delete, type ViewDocumentDeleteEvent } from 'ckeditor5/src/typing.js';\n\nimport type {\n\tDowncastAttributeEvent,\n\tDowncastInsertEvent,\n\tDowncastRemoveEvent,\n\tElement,\n\tMapperModelToViewPositionEvent,\n\tMapperViewToModelPositionEvent,\n\tModelInsertContentEvent,\n\tUpcastElementEvent,\n\tViewDocumentTabEvent,\n\tViewElement\n} from 'ckeditor5/src/engine.js';\n\nimport {\n\tcleanList,\n\tcleanListItem,\n\tmodelViewInsertion,\n\tmodelViewChangeType,\n\tmodelViewMergeAfterChangeType,\n\tmodelViewMergeAfter,\n\tmodelViewRemove,\n\tmodelViewSplitOnInsert,\n\tmodelViewChangeIndent,\n\tmodelChangePostFixer,\n\tmodelIndentPasteFixer,\n\tviewModelConverter,\n\tmodelToViewPosition,\n\tviewToModelPosition\n} from './legacyconverters.js';\n\nimport '../../theme/list.css';\n\n/**\n * The engine of the list feature. It handles creating, editing and removing lists and list items.\n *\n * It registers the `'numberedList'`, `'bulletedList'`, `'indentList'` and `'outdentList'` commands.\n */\nexport default class LegacyListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LegacyListEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Enter, Delete, LegacyListUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\t// Schema.\n\t\t// Note: in case `$block` will ever be allowed in `listItem`, keep in mind that this feature\n\t\t// uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.\n\t\t// If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.\n\t\teditor.model.schema.register( 'listItem', {\n\t\t\tinheritAllFrom: '$block',\n\t\t\tallowAttributes: [ 'listType', 'listIndent' ]\n\t\t} );\n\n\t\t// Converters.\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\teditor.model.document.registerPostFixer( writer => modelChangePostFixer( editor.model, writer ) );\n\n\t\tediting.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t\tdata.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\n\t\tediting.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\t\tediting.mapper.on<MapperViewToModelPositionEvent>( 'viewToModelPosition', viewToModelPosition( editor.model ) );\n\t\tdata.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on<DowncastInsertEvent<Element>>( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\t\t\tdispatcher.on<DowncastInsertEvent<Element>>( 'insert:listItem', modelViewInsertion( editor.model ) );\n\t\t\t\tdispatcher.on<DowncastAttributeEvent<Element>>( 'attribute:listType:listItem', modelViewChangeType, { priority: 'high' } );\n\t\t\t\tdispatcher.on<DowncastAttributeEvent<Element>>(\n\t\t\t\t\t'attribute:listType:listItem', modelViewMergeAfterChangeType, { priority: 'low' } );\n\t\t\t\tdispatcher.on<DowncastAttributeEvent<Element>>( 'attribute:listIndent:listItem', modelViewChangeIndent( editor.model ) );\n\t\t\t\tdispatcher.on<DowncastRemoveEvent>( 'remove:listItem', modelViewRemove( editor.model ) );\n\t\t\t\tdispatcher.on<DowncastRemoveEvent>( 'remove', modelViewMergeAfter, { priority: 'low' } );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on<DowncastInsertEvent<Element>>( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\t\t\tdispatcher.on<DowncastInsertEvent<Element>>( 'insert:listItem', modelViewInsertion( editor.model ) );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:ul', cleanList, { priority: 'high' } );\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:ol', cleanList, { priority: 'high' } );\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:li', cleanListItem, { priority: 'high' } );\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:li', viewModelConverter );\n\t\t\t} );\n\n\t\t// Fix indentation of pasted items.\n\t\teditor.model.on<ModelInsertContentEvent>( 'insertContent', modelIndentPasteFixer, { priority: 'high' } );\n\n\t\t// Register commands for numbered and bulleted list.\n\t\teditor.commands.add( 'numberedList', new LegacyListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new LegacyListCommand( editor, 'bulleted' ) );\n\n\t\t// Register commands for indenting.\n\t\teditor.commands.add( 'indentList', new LegacyIndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new LegacyIndentCommand( editor, 'backward' ) );\n\n\t\tconst viewDocument = editing.view.document;\n\n\t\t// Overwrite default Enter key behavior.\n\t\t// If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.\n\t\tthis.listenTo<ViewDocumentEnterEvent>( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tconst doc = this.editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition()!.parent;\n\n\t\t\tif ( doc.selection.isCollapsed && positionParent.name == 'listItem' && positionParent.isEmpty ) {\n\t\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\n\t\t// Overwrite default Backspace key behavior.\n\t\t// If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83\n\t\tthis.listenTo<ViewDocumentDeleteEvent>( viewDocument, 'delete', ( evt, data ) => {\n\t\t\t// Check conditions from those that require less computations like those immediately available.\n\t\t\tif ( data.direction !== 'backward' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selection = this.editor.model.document.selection;\n\n\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst firstPosition = selection.getFirstPosition()!;\n\n\t\t\tif ( !firstPosition.isAtStart ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = firstPosition.parent;\n\n\t\t\tif ( positionParent.name !== 'listItem' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst previousIsAListItem = positionParent.previousSibling && ( positionParent.previousSibling as any ).name === 'listItem';\n\n\t\t\tif ( previousIsAListItem ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\tdata.preventDefault();\n\t\t\tevt.stop();\n\t\t}, { context: 'li' } );\n\n\t\tthis.listenTo<ViewDocumentTabEvent>( editor.editing.view.document, 'tab', ( evt, data ) => {\n\t\t\tconst commandName = data.shiftKey ? 'outdentList' : 'indentList';\n\t\t\tconst command = this.editor.commands.get( commandName )!;\n\n\t\t\tif ( command.isEnabled ) {\n\t\t\t\teditor.execute( commandName );\n\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst commands = this.editor.commands;\n\n\t\tconst indent = commands.get( 'indent' ) as MultiCommand;\n\t\tconst outdent = commands.get( 'outdent' ) as MultiCommand;\n\n\t\tif ( indent ) {\n\t\t\tindent.registerChildCommand( commands.get( 'indentList' )! );\n\t\t}\n\n\t\tif ( outdent ) {\n\t\t\toutdent.registerChildCommand( commands.get( 'outdentList' )! );\n\t\t}\n\t}\n}\n\nfunction getViewListItemLength( element: ViewElement ) {\n\tlet length = 1;\n\n\tfor ( const child of element.getChildren() as Iterable<ViewElement> ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\tfor ( const item of child.getChildren() ) {\n\t\t\t\tlength += getViewListItemLength( item as ViewElement );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn length;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylist\n */\n\nimport LegacyListEditing from './legacylist/legacylistediting.js';\nimport ListUI from './list/listui.js';\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\n/**\n * The legacy list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/legacylist/legacylistediting~LegacyListEditing legacy list editing feature}\n * and {@link module:list/list/listui~ListUI list UI feature}.\n */\nexport default class LegacyList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LegacyListEditing, ListUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LegacyList' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylistproperties/legacyliststylecommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport { getListTypeFromListStyleType, getSelectedListItems } from '../legacylist/legacyutils.js';\n\n/**\n * The list style command. It changes the `listStyle` attribute of the selected list items.\n *\n * If the list type (numbered or bulleted) can be inferred from the passed style type,\n * the command tries to convert selected items to a list of that type.\n * It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n */\nexport default class LegacyListStyleCommand extends Command {\n\tdeclare public isStyleTypeSupported: undefined;\n\n\t/**\n\t * @inheritDoc\n\t * @readonly\n\t */\n\tdeclare public value: string | null;\n\n\t/**\n\t * The default type of the list style.\n\t */\n\tpublic readonly defaultType: string;\n\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param editor The editor instance.\n\t * @param defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t */\n\tconstructor( editor: Editor, defaultType: string ) {\n\t\tsuper( editor );\n\n\t\tthis.defaultType = defaultType;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.type The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */\n\tpublic override execute( options: { type?: string | null } = {} ): void {\n\t\tthis._tryToConvertItemsToList( options );\n\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model );\n\n\t\tif ( !listItems.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listStyle', options.type || this.defaultType, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */\n\tprivate _getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition()!.parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn listItem.getAttribute( 'listStyle' ) as string;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @returns Whether the command should be enabled.\n\t */\n\tprivate _checkEnabled() {\n\t\tconst editor = this.editor;\n\n\t\tconst numberedList = editor.commands.get( 'numberedList' )!;\n\t\tconst bulletedList = editor.commands.get( 'bulletedList' )!;\n\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\n\t/**\n\t * Checks if the provided list style is valid. Also changes the selection to a list if it's not set yet.\n\t *\n\t * @param The type of the list style. If `null` is specified, the function does nothing.\n\t*/\n\tprivate _tryToConvertItemsToList( options: { type?: string | null } ) {\n\t\tif ( !options.type ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst listType = getListTypeFromListStyleType( options.type );\n\n\t\t/* istanbul ignore next -- @preserve */\n\t\tif ( !listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst commandName = `${ listType }List` as const;\n\t\tconst command = editor.commands.get( commandName )!;\n\n\t\tif ( !command.value ) {\n\t\t\teditor.execute( commandName );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylistproperties/legacylistreversedcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport { getSelectedListItems } from '../legacylist/legacyutils.js';\n\n/**\n * The reversed list command. It changes the `listReversed` attribute of the selected list items. As a result, the list order will be\n * reversed.\n * It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n */\nexport default class LegacyListReversedCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public value: boolean | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.reversed Whether the list should be reversed.\n\t */\n\tpublic override execute( options: { reversed?: boolean } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model )\n\t\t\t.filter( item => item.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listReversed', !!options.reversed, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */\n\tprivate _getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition()!.parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn listItem.getAttribute( 'listReversed' ) as boolean;\n\t\t}\n\n\t\treturn null;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylistproperties/legacyliststartcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport { getSelectedListItems } from '../legacylist/legacyutils.js';\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items.\n * It is used by the {@link module:list/legacylistproperties~LegacyListProperties legacy list properties feature}.\n */\nexport default class LegacyListStartCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tdeclare public value: number | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.startIndex The list start index.\n\t */\n\tpublic override execute( { startIndex = 1 }: { startIndex?: number } = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model )\n\t\t\t.filter( item => item.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listStart', startIndex >= 0 ? startIndex : 1, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @returns The current value.\n\t */\n\tprivate _getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition()!.parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn listItem.getAttribute( 'listStart' ) as number;\n\t\t}\n\n\t\treturn null;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylistproperties/legacylistpropertiesediting\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\n\nimport type {\n\tDiffItem,\n\tDowncastAttributeEvent,\n\tDowncastDispatcher,\n\tDowncastWriter,\n\tElement,\n\tModelDeleteContentEvent,\n\tNode,\n\tUpcastDispatcher,\n\tUpcastElementEvent,\n\tViewElement,\n\tWriter\n} from 'ckeditor5/src/engine.js';\n\nimport LegacyListEditing from '../legacylist/legacylistediting.js';\nimport LegacyListStyleCommand from './legacyliststylecommand.js';\nimport LegacyListReversedCommand from './legacylistreversedcommand.js';\nimport LegacyListStartCommand from './legacyliststartcommand.js';\nimport { getSiblingListItem, getSiblingNodes } from '../legacylist/legacyutils.js';\nimport type { ListPropertiesConfig } from '../listconfig.js';\n\nconst DEFAULT_LIST_TYPE = 'default';\n\n/**\n * The engine of the list properties feature.\n *\n * It sets the value for the `listItem` attribute of the {@link module:list/legacylist~LegacyList `<listItem>`} element that\n * allows modifying the list style type.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listconfig~ListPropertiesConfig}.\n */\nexport default class LegacyListPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LegacyListEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LegacyListPropertiesEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'list', {\n\t\t\tproperties: {\n\t\t\t\tstyles: true,\n\t\t\t\tstartIndex: false,\n\t\t\t\treversed: false\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tconst enabledProperties = editor.config.get( 'list.properties' )!;\n\t\tconst strategies = createAttributeStrategies( enabledProperties );\n\n\t\t// Extend schema.\n\t\tmodel.schema.extend( 'listItem', {\n\t\t\tallowAttributes: strategies.map( s => s.attributeName )\n\t\t} );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tstrategy.addCommand( editor );\n\t\t}\n\n\t\t// Fix list attributes when modifying their nesting levels (the `listIndent` attribute).\n\t\tthis.listenTo( editor.commands.get( 'indentList' )!, '_executeCleanup', fixListAfterIndentListCommand( editor, strategies ) );\n\t\tthis.listenTo( editor.commands.get( 'outdentList' )!, '_executeCleanup', fixListAfterOutdentListCommand( editor, strategies ) );\n\n\t\tthis.listenTo( editor.commands.get( 'bulletedList' )!, '_executeCleanup', restoreDefaultListStyle( editor ) );\n\t\tthis.listenTo( editor.commands.get( 'numberedList' )!, '_executeCleanup', restoreDefaultListStyle( editor ) );\n\n\t\t// Register a post-fixer that ensures that the attributes is specified in each `listItem` element.\n\t\tmodel.document.registerPostFixer( fixListAttributesOnListItemElements( editor, strategies ) );\n\n\t\t// Set up conversion.\n\t\teditor.conversion.for( 'upcast' ).add( upcastListItemAttributes( strategies ) );\n\t\teditor.conversion.for( 'downcast' ).add( downcastListItemAttributes( strategies ) );\n\n\t\t// Handle merging two separated lists into the single one.\n\t\tthis._mergeListAttributesWhileMergingLists( strategies );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\n\t\t// Enable post-fixer that removes the attributes from to-do list items only if the \"TodoList\" plugin is on.\n\t\t// We need to registry the hook here since the `TodoList` plugin can be added after the `ListPropertiesEditing`.\n\t\tif ( editor.commands.get( 'todoList' ) ) {\n\t\t\teditor.model.document.registerPostFixer( removeListItemAttributesFromTodoList( editor ) );\n\t\t}\n\t}\n\n\t/**\n\t * Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether two lists will be merged into a single\n\t * one after deleting the content.\n\t *\n\t * The purpose of this action is to adjust the `listStyle`, `listReversed` and `listStart` values\n\t * for the list that was merged.\n\t *\n\t * Consider the following model's content:\n\t *\n\t * ```xml\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <paragraph>[A paragraph.]</paragraph>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t * ```\n\t *\n\t * After removing the paragraph element, the second list will be merged into the first one.\n\t * We want to inherit the `listStyle` attribute for the second list from the first one.\n\t *\n\t * ```xml\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * ```\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/7879.\n\t *\n\t * @param attributeStrategies Strategies for the enabled attributes.\n\t */\n\tprivate _mergeListAttributesWhileMergingLists( attributeStrategies: Array<AttributeStrategy> ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\t// First the outer-most`listItem` in the first list reference.\n\t\t// If found, the lists should be merged and this `listItem` provides the attributes\n\t\t// and it is also a starting point when searching for items in the second list.\n\t\tlet firstMostOuterItem: Element | null;\n\n\t\t// Check whether the removed content is between two lists.\n\t\tthis.listenTo<ModelDeleteContentEvent>( model, 'deleteContent', ( evt, [ selection ] ) => {\n\t\t\tconst firstPosition = selection.getFirstPosition()!;\n\t\t\tconst lastPosition = selection.getLastPosition()!;\n\n\t\t\t// Typing or removing content in a single item. Aborting.\n\t\t\tif ( firstPosition.parent === lastPosition.parent ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// An element before the content that will be removed is not a list.\n\t\t\tif ( !firstPosition.parent.is( 'element', 'listItem' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nextSibling = lastPosition.parent.nextSibling;\n\n\t\t\t// An element after the content that will be removed is not a list.\n\t\t\tif ( !nextSibling || !nextSibling.is( 'element', 'listItem' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Find the outermost list item based on the `listIndent` attribute. We can't assume that `listIndent=0`\n\t\t\t// because the selection can be hooked in nested lists.\n\t\t\t//\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List [item 1.1</listItem>\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1.</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"circle\">UL List ]item 1.1</listItem>\n\t\t\t//\n\t\t\t// After deleting the content, we would like to inherit the \"square\" attribute for the last element:\n\t\t\t//\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List []item 1.1</listItem>\n\t\t\tconst mostOuterItemList = getSiblingListItem( firstPosition.parent, {\n\t\t\t\tsameIndent: true,\n\t\t\t\tlistIndent: nextSibling.getAttribute( 'listIndent' ) as number\n\t\t\t} );\n\n\t\t\t// The outermost list item may not exist while removing elements between lists with different value\n\t\t\t// of the `listIndent` attribute. In such a case we don't want to update anything. See: #8073.\n\t\t\tif ( !mostOuterItemList ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( mostOuterItemList.getAttribute( 'listType' ) === nextSibling.getAttribute( 'listType' ) ) {\n\t\t\t\tfirstMostOuterItem = mostOuterItemList;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// If so, update the `listStyle` attribute for the second list.\n\t\tthis.listenTo<ModelDeleteContentEvent>( model, 'deleteContent', () => {\n\t\t\tif ( !firstMostOuterItem ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodel.change( writer => {\n\t\t\t\t// Find the first most-outer item list in the merged list.\n\t\t\t\t// A case when the first list item in the second list was merged into the last item in the first list.\n\t\t\t\t//\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t\t\t\tconst secondListMostOuterItem = getSiblingListItem( firstMostOuterItem!.nextSibling, {\n\t\t\t\t\tsameIndent: true,\n\t\t\t\t\tlistIndent: firstMostOuterItem!.getAttribute( 'listIndent' ) as number,\n\t\t\t\t\tdirection: 'forward'\n\t\t\t\t} );\n\n\t\t\t\t// If the selection ends in a non-list element, there are no <listItem>s that would require adjustments.\n\t\t\t\t// See: #8642.\n\t\t\t\tif ( !secondListMostOuterItem ) {\n\t\t\t\t\tfirstMostOuterItem = null;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst items = [\n\t\t\t\t\tsecondListMostOuterItem,\n\t\t\t\t\t...getSiblingNodes( writer.createPositionAt( secondListMostOuterItem, 0 ), 'forward' )\n\t\t\t\t];\n\n\t\t\t\tfor ( const listItem of items ) {\n\t\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\t\tif ( strategy.appliesToListItem( listItem ) ) {\n\t\t\t\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\t\t\t\tconst value = firstMostOuterItem!.getAttribute( attributeName );\n\n\t\t\t\t\t\t\twriter.setAttribute( attributeName, value, listItem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tfirstMostOuterItem = null;\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n/**\n * Strategy for dealing with `listItem` attributes supported by this plugin.\n */\ninterface AttributeStrategy {\n\tattributeName: string;\n\tdefaultValue: unknown;\n\taddCommand: ( editor: Editor ) => void;\n\tappliesToListItem: ( element: Node ) => boolean;\n\tsetAttributeOnDowncast: ( writer: DowncastWriter, value: any, element: ViewElement ) => void;\n\tgetAttributeOnUpcast: ( element: ViewElement ) => unknown;\n}\n\n/**\n * Creates an array of strategies for dealing with enabled listItem attributes.\n */\nfunction createAttributeStrategies( enabledProperties: ListPropertiesConfig ) {\n\tconst strategies: Array<AttributeStrategy> = [];\n\n\tif ( enabledProperties.styles ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStyle',\n\t\t\tdefaultValue: DEFAULT_LIST_TYPE,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStyle', new LegacyListStyleCommand( editor, DEFAULT_LIST_TYPE ) );\n\t\t\t},\n\n\t\t\tappliesToListItem() {\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStyle, element ) {\n\t\t\t\tif ( listStyle && listStyle !== DEFAULT_LIST_TYPE ) {\n\t\t\t\t\twriter.setStyle( 'list-style-type', listStyle, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeStyle( 'list-style-type', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.getStyle( 'list-style-type' ) || DEFAULT_LIST_TYPE;\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listReversed',\n\t\t\tdefaultValue: false,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listReversed', new LegacyListReversedCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listReversed, element ) {\n\t\t\t\tif ( listReversed ) {\n\t\t\t\t\twriter.setAttribute( 'reversed', 'reversed', element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'reversed', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.hasAttribute( 'reversed' );\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStart',\n\t\t\tdefaultValue: 1,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStart', new LegacyListStartCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStart, element ) {\n\t\t\t\tif ( listStart == 0 || listStart > 1 ) {\n\t\t\t\t\twriter.setAttribute( 'start', listStart, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'start', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\tconst startAttributeValue: any = listParent.getAttribute( 'start' );\n\n\t\t\t\treturn startAttributeValue >= 0 ? startAttributeValue : 1;\n\t\t\t}\n\t\t} );\n\t}\n\n\treturn strategies;\n}\n\n/**\n * Returns a converter consumes the `style`, `reversed` and `start` attribute.\n * In `style` it searches for the `list-style-type` definition.\n * If not found, the `\"default\"` value will be used.\n */\nfunction upcastListItemAttributes( attributeStrategies: Array<AttributeStrategy> ) {\n\treturn ( dispatcher: UpcastDispatcher ) => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:li', ( evt, data, conversionApi ) => {\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/13858\n\t\t\tif ( !data.modelRange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst listParent = data.viewItem.parent as ViewElement;\n\t\t\tconst listItem = data.modelRange.start.nodeAfter || data.modelRange.end.nodeBefore;\n\n\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\tif ( strategy.appliesToListItem( listItem! ) ) {\n\t\t\t\t\tconst listStyle = strategy.getAttributeOnUpcast( listParent );\n\t\t\t\t\tconversionApi.writer.setAttribute( strategy.attributeName, listStyle, listItem! );\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t};\n}\n\n/**\n * Returns a converter that adds `reversed`, `start` attributes and adds `list-style-type` definition as a value for the `style` attribute.\n * The `\"default\"` values are removed and not present in the view/data.\n */\nfunction downcastListItemAttributes( attributeStrategies: Array<AttributeStrategy> ) {\n\treturn ( dispatcher: DowncastDispatcher ) => {\n\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\tdispatcher.on<DowncastAttributeEvent>( `attribute:${ strategy.attributeName }:listItem`, ( evt, data, conversionApi ) => {\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst currentElement = data.item as Element;\n\n\t\t\t\tconst previousElement = getSiblingListItem( currentElement.previousSibling, {\n\t\t\t\t\tsameIndent: true,\n\t\t\t\t\tlistIndent: currentElement.getAttribute( 'listIndent' ) as number,\n\t\t\t\t\tdirection: 'backward'\n\t\t\t\t} );\n\n\t\t\t\tconst viewItem = conversionApi.mapper.toViewElement( currentElement )!;\n\n\t\t\t\t// A case when elements represent different lists. We need to separate their container.\n\t\t\t\tif ( !areRepresentingSameList( currentElement, previousElement ) ) {\n\t\t\t\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\t\t\t}\n\t\t\t\tstrategy.setAttributeOnDowncast( viewWriter, data.attributeNewValue, viewItem.parent as ViewElement );\n\t\t\t}, { priority: 'low' } );\n\t\t}\n\t};\n\n\t/**\n\t * Checks whether specified list items belong to the same list.\n\t */\n\tfunction areRepresentingSameList( listItem1: Element, listItem2: Element | null ) {\n\t\treturn listItem2 &&\n\t\t\tlistItem1.getAttribute( 'listType' ) === listItem2.getAttribute( 'listType' ) &&\n\t\t\tlistItem1.getAttribute( 'listIndent' ) === listItem2.getAttribute( 'listIndent' ) &&\n\t\t\tlistItem1.getAttribute( 'listStyle' ) === listItem2.getAttribute( 'listStyle' ) &&\n\t\t\tlistItem1.getAttribute( 'listReversed' ) === listItem2.getAttribute( 'listReversed' ) &&\n\t\t\tlistItem1.getAttribute( 'listStart' ) === listItem2.getAttribute( 'listStart' );\n\t}\n}\n\n/**\n * When indenting list, nested list should clear its value for the attributes or inherit from nested lists.\n *\n * ■ List item 1.\n * ■ List item 2.[]\n * ■ List item 3.\n * editor.execute( 'indentList' );\n *\n * ■ List item 1.\n *     ○ List item 2.[]\n * ■ List item 3.\n */\nfunction fixListAfterIndentListCommand( editor: Editor, attributeStrategies: Array<AttributeStrategy> ) {\n\treturn ( evt: unknown, changedItems: Array<Element> ) => {\n\t\tconst root = changedItems[ 0 ];\n\t\tconst rootIndent = root.getAttribute( 'listIndent' ) as number;\n\n\t\tconst itemsToUpdate = changedItems.filter( item => item.getAttribute( 'listIndent' ) === rootIndent );\n\n\t\t// A case where a few list items are indented must be checked separately\n\t\t// since `getSiblingListItem()` returns the first changed element.\n\t\t// ■ List item 1.\n\t\t//     ○ [List item 2.\n\t\t//     ○ List item 3.]\n\t\t// ■ List item 4.\n\t\t//\n\t\t// List items: `2` and `3` should be adjusted.\n\t\tlet previousSibling: Element | null = null;\n\n\t\tif ( root.previousSibling!.getAttribute( 'listIndent' ) as number + 1 !== rootIndent ) {\n\t\t\tpreviousSibling = getSiblingListItem( root.previousSibling, {\n\t\t\t\tsameIndent: true, direction: 'backward', listIndent: rootIndent\n\t\t\t} );\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\tfor ( const item of itemsToUpdate ) {\n\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\tif ( strategy.appliesToListItem( item ) ) {\n\t\t\t\t\t\tconst valueToSet = previousSibling == null ?\n\t\t\t\t\t\t\tstrategy.defaultValue :\n\t\t\t\t\t\t\tpreviousSibling.getAttribute( strategy.attributeName );\n\n\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, valueToSet, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t};\n}\n\n/**\n * When outdenting a list, a nested list should copy attribute values\n * from the previous sibling list item including the same value for the `listIndent` value.\n *\n * ■ List item 1.\n *     ○ List item 2.[]\n * ■ List item 3.\n *\n * editor.execute( 'outdentList' );\n *\n * ■ List item 1.\n * ■ List item 2.[]\n * ■ List item 3.\n */\nfunction fixListAfterOutdentListCommand( editor: Editor, attributeStrategies: Array<AttributeStrategy> ) {\n\treturn ( evt: unknown, changedItems: Array<Element> ) => {\n\t\tchangedItems = changedItems.reverse().filter( item => item.is( 'element', 'listItem' ) );\n\n\t\tif ( !changedItems.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst indent = changedItems[ 0 ].getAttribute( 'listIndent' );\n\t\tconst listType = changedItems[ 0 ].getAttribute( 'listType' );\n\t\tlet listItem: Node | null = changedItems[ 0 ].previousSibling!;\n\n\t\t// ■ List item 1.\n\t\t//     ○ List item 2.\n\t\t//     ○ List item 3.[]\n\t\t// ■ List item 4.\n\t\t//\n\t\t// After outdenting a list, `List item 3` should inherit the `listStyle` attribute from `List item 1`.\n\t\t//\n\t\t// ■ List item 1.\n\t\t//     ○ List item 2.\n\t\t// ■ List item 3.[]\n\t\t// ■ List item 4.\n\t\tif ( listItem.is( 'element', 'listItem' ) ) {\n\t\t\twhile ( listItem!.getAttribute( 'listIndent' ) !== indent ) {\n\t\t\t\tlistItem = listItem!.previousSibling;\n\t\t\t}\n\t\t} else {\n\t\t\tlistItem = null;\n\t\t}\n\n\t\t// Outdenting such a list should restore values based on `List item 4`.\n\t\t// ■ List item 1.[]\n\t\t//     ○ List item 2.\n\t\t//     ○ List item 3.\n\t\t// ■ List item 4.\n\t\tif ( !listItem ) {\n\t\t\tlistItem = changedItems[ changedItems.length - 1 ].nextSibling;\n\t\t}\n\n\t\t// And such a list should not modify anything.\n\t\t// However, `listItem` can indicate a node below the list. Be sure that we have the `listItem` element.\n\t\t// ■ List item 1.[]\n\t\t//     ○ List item 2.\n\t\t//     ○ List item 3.\n\t\t// <paragraph>The later if check.</paragraph>\n\t\tif ( !listItem || !listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not modify the list if found `listItem` represents other type of list than outdented list items.\n\t\tif ( listItem.getAttribute( 'listType' ) !== listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\tconst itemsToUpdate = changedItems.filter( item => item.getAttribute( 'listIndent' ) === indent );\n\n\t\t\tfor ( const item of itemsToUpdate ) {\n\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\tif ( strategy.appliesToListItem( item ) ) {\n\t\t\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\t\t\tconst valueToSet = listItem!.getAttribute( attributeName );\n\n\t\t\t\t\t\twriter.setAttribute( attributeName, valueToSet, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t};\n}\n\n/**\n * Each `listItem` element must have specified the `listStyle`, `listReversed` and `listStart` attributes\n * if they are enabled and supported by its `listType`.\n * This post-fixer checks whether inserted elements `listItem` elements should inherit the attribute values from\n * their sibling nodes or should use the default values.\n *\n * Paragraph[]\n * ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2. // ...\n * ■ List item 3. // ...\n *\n * editor.execute( 'bulletedList' )\n *\n * ■ Paragraph[]  // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2.\n * ■ List item 3.\n *\n * It also covers a such change:\n *\n * [Paragraph 1\n * Paragraph 2]\n * ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2. // ...\n * ■ List item 3. // ...\n *\n * editor.execute( 'numberedList' )\n *\n * 1. [Paragraph 1 // [listStyle=\"default\", listType=\"numbered\"]\n * 2. Paragraph 2] // [listStyle=\"default\", listType=\"numbered\"]\n * ■ List item 1.  // [listStyle=\"square\", listType=\"bulleted\"]\n * ■ List item 2.  // ...\n * ■ List item 3.  // ...\n */\nfunction fixListAttributesOnListItemElements( editor: Editor, attributeStrategies: Array<AttributeStrategy> ) {\n\treturn ( writer: Writer ) => {\n\t\tlet wasFixed = false;\n\n\t\tconst insertedListItems = getChangedListItems( editor.model.document.differ.getChanges() )\n\t\t\t.filter( item => {\n\t\t\t\t// Don't touch todo lists. They are handled in another post-fixer.\n\t\t\t\treturn item.getAttribute( 'listType' ) !== 'todo';\n\t\t\t} );\n\n\t\tif ( !insertedListItems.length ) {\n\t\t\treturn wasFixed;\n\t\t}\n\n\t\t// Check whether the last inserted element is next to the `listItem` element.\n\t\t//\n\t\t// ■ Paragraph[]  // <-- The inserted item.\n\t\t// ■ List item 1.\n\t\tlet existingListItem = insertedListItems[ insertedListItems.length - 1 ].nextSibling;\n\n\t\t// If it doesn't, maybe the `listItem` was inserted at the end of the list.\n\t\t//\n\t\t// ■ List item 1.\n\t\t// ■ Paragraph[]  // <-- The inserted item.\n\t\tif ( !existingListItem || !existingListItem.is( 'element', 'listItem' ) ) {\n\t\t\texistingListItem = insertedListItems[ 0 ].previousSibling;\n\n\t\t\tif ( existingListItem ) {\n\t\t\t\tconst indent = insertedListItems[ 0 ].getAttribute( 'listIndent' );\n\n\t\t\t\t// But we need to find a `listItem` with the `listIndent=0` attribute.\n\t\t\t\t// If doesn't, maybe the `listItem` was inserted at the end of the list.\n\t\t\t\t//\n\t\t\t\t// ■ List item 1.\n\t\t\t\t//     ○ List item 2.\n\t\t\t\t// ■ Paragraph[]  // <-- The inserted item.\n\t\t\t\twhile ( existingListItem.is( 'element', 'listItem' ) && existingListItem.getAttribute( 'listIndent' ) !== indent ) {\n\t\t\t\t\texistingListItem = existingListItem.previousSibling;\n\n\t\t\t\t\t// If the item does not exist, most probably there is no other content in the editor. See: #8072.\n\t\t\t\t\tif ( !existingListItem ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\tconst attributeName = strategy.attributeName;\n\n\t\t\tfor ( const item of insertedListItems ) {\n\t\t\t\tif ( !strategy.appliesToListItem( item ) ) {\n\t\t\t\t\twriter.removeAttribute( attributeName, item );\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( !item.hasAttribute( attributeName ) ) {\n\t\t\t\t\tif ( shouldInheritListType( existingListItem, item, strategy ) ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, existingListItem!.getAttribute( attributeName ), item );\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.setAttribute( attributeName, strategy.defaultValue, item );\n\t\t\t\t\t}\n\t\t\t\t\twasFixed = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Adjust the `listStyle`, `listReversed` and `listStart`\n\t\t\t\t\t// attributes for inserted (pasted) items. See #8160.\n\t\t\t\t\t//\n\t\t\t\t\t// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n\t\t\t\t\t//     ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t//     ○ [] (selection is here)\n\t\t\t\t\t//\n\t\t\t\t\t// Then, pasting a list with different attributes (listStyle, listType):\n\t\t\t\t\t//\n\t\t\t\t\t// 1. First. // [listStyle=\"decimal\", listType=\"numbered\"]\n\t\t\t\t\t// 2. Second // [listStyle=\"decimal\", listType=\"numbered\"]\n\t\t\t\t\t//\n\t\t\t\t\t// The `listType` attribute will be corrected by the `ListEditing` converters.\n\t\t\t\t\t// We need to adjust the `listStyle` attribute. Expected structure:\n\t\t\t\t\t//\n\t\t\t\t\t// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n\t\t\t\t\t//     ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t//     ○ First. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t//     ○ Second // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\tconst previousSibling = item.previousSibling;\n\n\t\t\t\t\tif ( shouldInheritListTypeFromPreviousItem( previousSibling, item, strategy.attributeName ) ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, previousSibling!.getAttribute( attributeName ), item );\n\n\t\t\t\t\t\twasFixed = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn wasFixed;\n\t};\n}\n\n/**\n * Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n * should be copied from the `baseItem` element.\n *\n * The attribute should be copied if the inserted element does not have defined it and\n * the value for the element is other than default in the base element.\n */\nfunction shouldInheritListType( baseItem: Node | null, itemToChange: Element, attributeStrategy: AttributeStrategy ) {\n\tif ( !baseItem ) {\n\t\treturn false;\n\t}\n\n\tconst baseListAttribute = baseItem.getAttribute( attributeStrategy.attributeName );\n\n\tif ( !baseListAttribute ) {\n\t\treturn false;\n\t}\n\n\tif ( baseListAttribute == attributeStrategy.defaultValue ) {\n\t\treturn false;\n\t}\n\n\tif ( baseItem.getAttribute( 'listType' ) !== itemToChange.getAttribute( 'listType' ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n * should be copied from previous list item.\n *\n * The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list.\n * Top-level lists are not normalized as we allow side-by-side list of different types.\n */\nfunction shouldInheritListTypeFromPreviousItem( previousItem: Node | null, itemToChange: Element, attributeName: string ) {\n\tif ( !previousItem || !previousItem.is( 'element', 'listItem' ) ) {\n\t\treturn false;\n\t}\n\n\tif ( itemToChange.getAttribute( 'listType' ) !== previousItem.getAttribute( 'listType' ) ) {\n\t\treturn false;\n\t}\n\n\tconst previousItemIndent = previousItem.getAttribute( 'listIndent' ) as number;\n\n\tif ( previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute( 'listIndent' ) ) {\n\t\treturn false;\n\t}\n\n\tconst previousItemListAttribute = previousItem.getAttribute( attributeName );\n\n\tif ( !previousItemListAttribute || previousItemListAttribute === itemToChange.getAttribute( attributeName ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/**\n * Removes the `listStyle`, `listReversed` and `listStart` attributes from \"todo\" list items.\n */\nfunction removeListItemAttributesFromTodoList( editor: Editor ) {\n\treturn ( writer: Writer ) => {\n\t\tconst todoListItems = getChangedListItems( editor.model.document.differ.getChanges() )\n\t\t\t.filter( item => {\n\t\t\t\t// Handle the todo lists only. The rest is handled in another post-fixer.\n\t\t\t\treturn item.getAttribute( 'listType' ) === 'todo' && (\n\t\t\t\t\titem.hasAttribute( 'listStyle' ) ||\n\t\t\t\t\titem.hasAttribute( 'listReversed' ) ||\n\t\t\t\t\titem.hasAttribute( 'listStart' )\n\t\t\t\t);\n\t\t\t} );\n\n\t\tif ( !todoListItems.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const item of todoListItems ) {\n\t\t\twriter.removeAttribute( 'listStyle', item );\n\t\t\twriter.removeAttribute( 'listReversed', item );\n\t\t\twriter.removeAttribute( 'listStart', item );\n\t\t}\n\n\t\treturn true;\n\t};\n}\n\n/**\n * Restores the `listStyle` attribute after changing the list type.\n */\nfunction restoreDefaultListStyle( editor: Editor ) {\n\treturn ( evt: unknown, changedItems: Array<Element> ) => {\n\t\tchangedItems = changedItems.filter( item => item.is( 'element', 'listItem' ) );\n\n\t\teditor.model.change( writer => {\n\t\t\tfor ( const item of changedItems ) {\n\t\t\t\t// Remove the attribute. Post-fixer will restore the proper value.\n\t\t\t\twriter.removeAttribute( 'listStyle', item );\n\t\t\t}\n\t\t} );\n\t};\n}\n\n/**\n * Returns the `listItem` that was inserted or changed.\n *\n * @param changes The changes list returned by the differ.\n */\nfunction getChangedListItems( changes: Array<DiffItem> ) {\n\tconst items: Array<Element> = [];\n\n\tfor ( const change of changes ) {\n\t\tconst item = getItemFromChange( change );\n\n\t\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\titems.push( item );\n\t\t}\n\t}\n\n\treturn items;\n}\n\nfunction getItemFromChange( change: DiffItem ) {\n\tif ( change.type === 'attribute' ) {\n\t\treturn change.range.start.nodeAfter;\n\t}\n\n\tif ( change.type === 'insert' ) {\n\t\treturn change.position.nodeAfter;\n\t}\n\n\treturn null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacylistproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport LegacyListPropertiesEditing from './legacylistproperties/legacylistpropertiesediting.js';\nimport ListPropertiesUI from './listproperties/listpropertiesui.js';\n\n/**\n * The legacy list properties feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/legacylistproperties/legacylistpropertiesediting~LegacyListPropertiesEditing\n * legacy list properties editing feature} and the\n * {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n */\nexport default class LegacyListProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LegacyListPropertiesEditing, ListPropertiesUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LegacyListProperties' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacytodolist/legacychecktodolistcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\n\nconst attributeKey = 'todoListChecked';\n\n/**\n * The check to-do command.\n *\n * The command is registered by the {@link module:list/legacytodolist/legacytodolistediting~LegacyTodoListEditing} as\n * the `checkTodoList` editor command and it is also available via aliased `todoListCheck` name.\n */\nexport default class LegacyCheckTodoListCommand extends Command {\n\t/**\n\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t *\n\t * @observable\n\t * @readonly\n\t */\n\tdeclare public value: boolean;\n\n\t/**\n\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t *\n\t * @internal\n\t */\n\tpublic _selectedElements: Array<Element>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._selectedElements = [];\n\n\t\t// Refresh command before executing to be sure all values are up to date.\n\t\t// It is needed when selection has changed before command execution, in the same change block.\n\t\tthis.on( 'execute', () => {\n\t\t\tthis.refresh();\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t */\n\tpublic override refresh(): void {\n\t\tthis._selectedElements = this._getSelectedItems();\n\t\tthis.value = this._selectedElements.every( element => !!element.getAttribute( attributeKey ) );\n\t\tthis.isEnabled = !!this._selectedElements.length;\n\t}\n\n\t/**\n\t * Gets all to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t */\n\tprivate _getSelectedItems() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\n\t\tconst selectionRange = model.document.selection.getFirstRange()!;\n\t\tconst startElement = selectionRange.start.parent as Element;\n\t\tconst elements: Array<Element> = [];\n\n\t\tif ( schema.checkAttribute( startElement, attributeKey ) ) {\n\t\t\telements.push( startElement );\n\t\t}\n\n\t\tfor ( const item of selectionRange.getItems() as Iterable<Element> ) {\n\t\t\tif ( schema.checkAttribute( item, attributeKey ) && !elements.includes( item ) ) {\n\t\t\t\telements.push( item );\n\t\t\t}\n\t\t}\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply\n\t * the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t * value to decide what it should do.\n\t */\n\tpublic override execute( options: { forceValue?: boolean } = {} ): void {\n\t\tthis.editor.model.change( writer => {\n\t\t\tfor ( const element of this._selectedElements ) {\n\t\t\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\t\t\tif ( value ) {\n\t\t\t\t\twriter.setAttribute( attributeKey, true, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( attributeKey, element );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacytodolist/legacytodolistconverters\n */\n\n/* global document */\n\nimport type {\n\tDowncastAttributeEvent,\n\tDowncastInsertEvent,\n\tDowncastWriter,\n\tElement,\n\tMapperModelToViewPositionEvent,\n\tModel,\n\tUpcastElementEvent,\n\tEditingView,\n\tViewElement\n} from 'ckeditor5/src/engine.js';\n\nimport { createElement, type GetCallback } from 'ckeditor5/src/utils.js';\n\nimport { generateLiInUl, injectViewList, positionAfterUiElements, findNestedList } from '../legacylist/legacyutils.js';\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It converts the `listItem` model element to an unordered list with a {@link module:engine/view/uielement~UIElement checkbox element}\n * at the beginning of each list item. It also merges the list with surrounding lists (if available).\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param model Model instance.\n * @param onCheckboxChecked Callback function.\n * @returns Returns a conversion callback.\n */\nexport function modelViewInsertion(\n\tmodel: Model,\n\tonCheckboxChecked: ( element: Element ) => void\n): GetCallback<DowncastInsertEvent<Element>> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.item;\n\n\t\tconsumable.consume( modelItem, 'insert' );\n\t\tconsumable.consume( modelItem, 'attribute:listType' );\n\t\tconsumable.consume( modelItem, 'attribute:listIndent' );\n\t\tconsumable.consume( modelItem, 'attribute:todoListChecked' );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tconst isChecked = !!modelItem.getAttribute( 'todoListChecked' );\n\t\tconst checkmarkElement = createCheckmarkElement( modelItem, viewWriter, isChecked, onCheckboxChecked );\n\n\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\tclass: 'todo-list__label__description'\n\t\t} );\n\n\t\tviewWriter.addClass( 'todo-list', viewItem.parent as any );\n\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), checkmarkElement );\n\t\tviewWriter.insert( viewWriter.createPositionAfter( checkmarkElement ), span );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param model Model instance.\n * @returns Returns a conversion callback.\n */\nexport function dataModelViewInsertion( model: Model ): GetCallback<DowncastInsertEvent<Element>> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.item;\n\n\t\tconsumable.consume( modelItem, 'insert' );\n\t\tconsumable.consume( modelItem, 'attribute:listType' );\n\t\tconsumable.consume( modelItem, 'attribute:listIndent' );\n\t\tconsumable.consume( modelItem, 'attribute:todoListChecked' );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tviewWriter.addClass( 'todo-list', viewItem.parent as any );\n\n\t\tconst label = viewWriter.createContainerElement( 'label', {\n\t\t\tclass: 'todo-list__label'\n\t\t} );\n\n\t\tconst checkbox = viewWriter.createEmptyElement( 'input', {\n\t\t\ttype: 'checkbox',\n\t\t\tdisabled: 'disabled'\n\t\t} );\n\n\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\tclass: 'todo-list__label__description'\n\t\t} );\n\n\t\tif ( modelItem.getAttribute( 'todoListChecked' ) ) {\n\t\t\tviewWriter.setAttribute( 'checked', 'checked', checkbox );\n\t\t}\n\n\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), label );\n\t\tviewWriter.insert( viewWriter.createPositionAt( label, 0 ), checkbox );\n\t\tviewWriter.insert( viewWriter.createPositionAfter( checkbox ), span );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A view-to-model converter for the checkbox element inside a view list item.\n *\n * It changes the `listType` of the model `listItem` to a `todo` value.\n * When a view checkbox element is marked as checked, an additional `todoListChecked=\"true\"` attribute is added to the model item.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n */\nexport const dataViewModelCheckmarkInsertion: GetCallback<UpcastElementEvent> = ( evt, data, conversionApi ) => {\n\tconst modelCursor = data.modelCursor;\n\tconst modelItem = modelCursor.parent;\n\tconst viewItem = data.viewItem;\n\n\tif ( viewItem.getAttribute( 'type' ) != 'checkbox' || modelItem.name != 'listItem' || !modelCursor.isAtStart ) {\n\t\treturn;\n\t}\n\n\tif ( !conversionApi.consumable.consume( viewItem, { name: true } ) ) {\n\t\treturn;\n\t}\n\n\tconst writer = conversionApi.writer;\n\n\twriter.setAttribute( 'listType', 'todo', modelItem );\n\n\tif ( data.viewItem.hasAttribute( 'checked' ) ) {\n\t\twriter.setAttribute( 'todoListChecked', true, modelItem );\n\t}\n\n\tdata.modelRange = writer.createRange( modelCursor );\n};\n\n/**\n * A model-to-view converter for the `listType` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes to `<ul class=\"todo-list\">` and a\n * {@link module:engine/view/uielement~UIElement checkbox UI element} is added at the beginning\n * of the list item element (or vice versa).\n *\n * This converter is preceded by {@link module:list/legacylist/legacyconverters~modelViewChangeType} and followed by\n * {@link module:list/legacylist/legacyconverters~modelViewMergeAfterChangeType} to handle splitting and merging surrounding lists\n * of the same type.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param onCheckedChange Callback fired after clicking the checkbox UI element.\n * @param view Editing view controller.\n * @returns Returns a conversion callback.\n */\nexport function modelViewChangeType(\n\tonCheckedChange: ( element: Element ) => void,\n\tview: EditingView\n): GetCallback<DowncastAttributeEvent<Element>> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewItem = conversionApi.mapper.toViewElement( data.item )!;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tconst labelElement = findLabel( viewItem, view )!;\n\n\t\tif ( data.attributeNewValue == 'todo' ) {\n\t\t\tconst isChecked = !!data.item.getAttribute( 'todoListChecked' );\n\t\t\tconst checkmarkElement = createCheckmarkElement( data.item, viewWriter, isChecked, onCheckedChange );\n\n\t\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\t\tclass: 'todo-list__label__description'\n\t\t\t} );\n\n\t\t\tconst itemRange = viewWriter.createRangeIn( viewItem );\n\t\t\tconst nestedList = findNestedList( viewItem );\n\n\t\t\tconst descriptionStart = positionAfterUiElements( itemRange.start );\n\t\t\tconst descriptionEnd = nestedList ? viewWriter.createPositionBefore( nestedList ) : itemRange.end;\n\t\t\tconst descriptionRange = viewWriter.createRange( descriptionStart, descriptionEnd );\n\n\t\t\tviewWriter.addClass( 'todo-list', viewItem.parent as any );\n\t\t\tviewWriter.move( descriptionRange, viewWriter.createPositionAt( span, 0 ) );\n\t\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), checkmarkElement );\n\t\t\tviewWriter.insert( viewWriter.createPositionAfter( checkmarkElement ), span );\n\t\t} else if ( data.attributeOldValue == 'todo' ) {\n\t\t\tconst descriptionSpan = findDescription( viewItem, view )!;\n\n\t\t\tviewWriter.removeClass( 'todo-list', viewItem.parent as any );\n\t\t\tviewWriter.remove( labelElement );\n\t\t\tviewWriter.move( viewWriter.createRangeIn( descriptionSpan ), viewWriter.createPositionBefore( descriptionSpan ) );\n\t\t\tviewWriter.remove( descriptionSpan );\n\t\t}\n\t};\n}\n\n/**\n * A model-to-view converter for the `todoListChecked` attribute change on the `listItem` model element.\n *\n * It marks the {@link module:engine/view/uielement~UIElement checkbox UI element} as checked.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param onCheckedChange Callback fired after clicking the checkbox UI element.\n * @returns Returns a conversion callback.\n */\nexport function modelViewChangeChecked(\n\tonCheckedChange: ( element: Element ) => void\n): GetCallback<DowncastAttributeEvent<Element>> {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// Do not convert `todoListChecked` attribute when to-do list item has changed to other list item.\n\t\t// This attribute will be removed by the model post fixer.\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, 'attribute:todoListChecked' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { mapper, writer: viewWriter } = conversionApi;\n\t\tconst isChecked = !!data.item.getAttribute( 'todoListChecked' );\n\t\tconst viewItem = mapper.toViewElement( data.item )!;\n\t\t// Because of m -> v position mapper we can be sure checkbox is always at the beginning.\n\t\tconst oldCheckmarkElement = viewItem.getChild( 0 )!;\n\t\tconst newCheckmarkElement = createCheckmarkElement( data.item, viewWriter, isChecked, onCheckedChange );\n\n\t\tviewWriter.insert( viewWriter.createPositionAfter( oldCheckmarkElement ), newCheckmarkElement );\n\t\tviewWriter.remove( oldCheckmarkElement );\n\t};\n}\n\n/**\n * A model-to-view position at zero offset mapper.\n *\n * This helper ensures that position inside todo-list in the view is mapped after the checkbox.\n *\n * It only handles the position at the beginning of a list item as other positions are properly mapped be the default mapper.\n */\nexport function mapModelToViewPosition( view: EditingView ): GetCallback<MapperModelToViewPositionEvent> {\n\treturn ( evt, data ) => {\n\t\tconst modelPosition = data.modelPosition;\n\t\tconst parent = modelPosition.parent;\n\n\t\tif ( !parent.is( 'element', 'listItem' ) || parent.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewLi = data.mapper.toViewElement( parent )!;\n\t\tconst descSpan = findDescription( viewLi, view );\n\n\t\tif ( descSpan ) {\n\t\t\tdata.viewPosition = data.mapper.findPositionIn( descSpan, modelPosition.offset );\n\t\t}\n\t};\n}\n\n/**\n * Creates a checkbox UI element.\n */\nfunction createCheckmarkElement(\n\tmodelItem: Element,\n\tviewWriter: DowncastWriter,\n\tisChecked: boolean,\n\tonChange: ( element: Element ) => void\n) {\n\tconst uiElement = viewWriter.createUIElement(\n\t\t'label',\n\t\t{\n\t\t\tclass: 'todo-list__label',\n\t\t\tcontenteditable: false\n\t\t},\n\t\tfunction( domDocument ) {\n\t\t\tconst checkbox = createElement( document, 'input', { type: 'checkbox', tabindex: '-1' } );\n\n\t\t\tif ( isChecked ) {\n\t\t\t\tcheckbox.setAttribute( 'checked', 'checked' );\n\t\t\t}\n\n\t\t\tcheckbox.addEventListener( 'change', () => onChange( modelItem ) );\n\n\t\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t\tdomElement.appendChild( checkbox );\n\n\t\t\treturn domElement;\n\t\t}\n\t);\n\n\treturn uiElement;\n}\n\n// Helper method to find label element inside li.\nfunction findLabel( viewItem: ViewElement, view: EditingView ) {\n\tconst range = view.createRangeIn( viewItem );\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'uiElement', 'label' ) ) {\n\t\t\treturn value.item;\n\t\t}\n\t}\n}\n\nfunction findDescription( viewItem: ViewElement, view: EditingView ) {\n\tconst range = view.createRangeIn( viewItem );\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'containerElement', 'span' ) && value.item.hasClass( 'todo-list__label__description' ) ) {\n\t\t\treturn value.item;\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacytodolist/legacytodolistediting\n */\n\nimport type {\n\tDowncastAttributeEvent,\n\tDowncastInsertEvent,\n\tElement,\n\tItem,\n\tMapperModelToViewPositionEvent,\n\tModel,\n\tModelApplyOperationEvent,\n\tUpcastElementEvent,\n\tViewDocumentArrowKeyEvent,\n\tViewDocumentKeyDownEvent,\n\tAttributeOperation,\n\tRenameOperation,\n\tSelectionChangeRangeEvent,\n\tDocumentFragment\n} from 'ckeditor5/src/engine.js';\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport {\n\tgetCode,\n\tparseKeystroke,\n\tgetLocalizedArrowKeyCodeDirection,\n\ttype Locale,\n\ttype GetCallback\n} from 'ckeditor5/src/utils.js';\n\nimport LegacyListCommand from '../legacylist/legacylistcommand.js';\nimport LegacyListEditing from '../legacylist/legacylistediting.js';\nimport LegacyCheckTodoListCommand from './legacychecktodolistcommand.js';\nimport {\n\tdataModelViewInsertion,\n\tdataViewModelCheckmarkInsertion,\n\tmapModelToViewPosition,\n\tmodelViewChangeChecked,\n\tmodelViewChangeType,\n\tmodelViewInsertion\n} from './legacytodolistconverters.js';\n\nconst ITEM_TOGGLE_KEYSTROKE = /* #__PURE__ */ parseKeystroke( 'Ctrl+Enter' );\n\n/**\n * The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n *\n * It registers the entire functionality of the {@link module:list/legacylist/legacylistediting~LegacyListEditing legacy list editing\n * plugin} and extends it with the commands:\n *\n * - `'todoList'`,\n * - `'checkTodoList'`,\n * - `'todoListCheck'` as an alias for `checkTodoList` command.\n */\nexport default class LegacyTodoListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LegacyTodoListEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LegacyListEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst { editing, data, model } = editor;\n\n\t\t// Extend schema.\n\t\tmodel.schema.extend( 'listItem', {\n\t\t\tallowAttributes: [ 'todoListChecked' ]\n\t\t} );\n\n\t\t// Disallow todoListChecked attribute on other nodes than listItem with to-do listType.\n\t\tmodel.schema.addAttributeCheck( ( context: any, attributeName ) => {\n\t\t\tconst item = context.last;\n\n\t\t\tif ( attributeName == 'todoListChecked' && item.name == 'listItem' && item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} );\n\n\t\t// Register `todoList` command.\n\t\teditor.commands.add( 'todoList', new LegacyListCommand( editor, 'todo' ) );\n\n\t\tconst checkTodoListCommand = new LegacyCheckTodoListCommand( editor );\n\n\t\t// Register `checkTodoList` command and add `todoListCheck` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'checkTodoList', checkTodoListCommand );\n\t\teditor.commands.add( 'todoListCheck', checkTodoListCommand );\n\n\t\t// Define converters.\n\t\tdata.downcastDispatcher.on<DowncastInsertEvent<Element>>(\n\t\t\t'insert:listItem',\n\t\t\tdataModelViewInsertion( model ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\t\tdata.upcastDispatcher.on<UpcastElementEvent>(\n\t\t\t'element:input',\n\t\t\tdataViewModelCheckmarkInsertion,\n\t\t\t{ priority: 'high' }\n\t\t);\n\n\t\tediting.downcastDispatcher.on<DowncastInsertEvent<Element>>(\n\t\t\t'insert:listItem',\n\t\t\tmodelViewInsertion( model, listItem => this._handleCheckmarkChange( listItem ) ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\t\tediting.downcastDispatcher.on<DowncastAttributeEvent<Element>>(\n\t\t\t'attribute:listType:listItem',\n\t\t\tmodelViewChangeType( listItem => this._handleCheckmarkChange( listItem ), editing.view )\n\t\t);\n\t\tediting.downcastDispatcher.on<DowncastAttributeEvent<Element>>(\n\t\t\t'attribute:todoListChecked:listItem',\n\t\t\tmodelViewChangeChecked( listItem => this._handleCheckmarkChange( listItem ) )\n\t\t);\n\n\t\tediting.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', mapModelToViewPosition( editing.view ) );\n\t\tdata.mapper.on<MapperModelToViewPositionEvent>( 'modelToViewPosition', mapModelToViewPosition( editing.view ) );\n\n\t\t// Jump at the end of the previous node on left arrow key press, when selection is after the checkbox.\n\t\t//\n\t\t// <blockquote><p>Foo</p></blockquote>\n\t\t// <ul><li><checkbox/>{}Bar</li></ul>\n\t\t//\n\t\t// press: `<-`\n\t\t//\n\t\t// <blockquote><p>Foo{}</p></blockquote>\n\t\t// <ul><li><checkbox/>Bar</li></ul>\n\t\t//\n\t\tthis.listenTo<ViewDocumentArrowKeyEvent>(\n\t\t\tediting.view.document,\n\t\t\t'arrowKey',\n\t\t\tjumpOverCheckmarkOnSideArrowKeyPress( model, editor.locale ),\n\t\t\t{ context: 'li' }\n\t\t);\n\n\t\t// Toggle check state of selected to-do list items on keystroke.\n\t\tthis.listenTo<ViewDocumentKeyDownEvent>( editing.view.document, 'keydown', ( evt, data ) => {\n\t\t\tif ( getCode( data ) === ITEM_TOGGLE_KEYSTROKE ) {\n\t\t\t\teditor.execute( 'checkTodoList' );\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// Remove `todoListChecked` attribute when a host element is no longer a to-do list item.\n\t\tconst listItemsToFix = new Set<Item>();\n\n\t\tthis.listenTo<ModelApplyOperationEvent>( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ] as RenameOperation | AttributeOperation;\n\n\t\t\tif ( operation.type == 'rename' && operation.oldName == 'listItem' ) {\n\t\t\t\tconst item = operation.position.nodeAfter!;\n\n\t\t\t\tif ( item.hasAttribute( 'todoListChecked' ) ) {\n\t\t\t\t\tlistItemsToFix.add( item );\n\t\t\t\t}\n\t\t\t} else if ( operation.type == 'changeAttribute' && operation.key == 'listType' && operation.oldValue === 'todo' ) {\n\t\t\t\tfor ( const item of operation.range.getItems() ) {\n\t\t\t\t\tif ( item.hasAttribute( 'todoListChecked' ) && item.getAttribute( 'listType' ) !== 'todo' ) {\n\t\t\t\t\t\tlistItemsToFix.add( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tmodel.document.registerPostFixer( writer => {\n\t\t\tlet hasChanged = false;\n\n\t\t\tfor ( const listItem of listItemsToFix ) {\n\t\t\t\twriter.removeAttribute( 'todoListChecked', listItem );\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tlistItemsToFix.clear();\n\n\t\t\treturn hasChanged;\n\t\t} );\n\n\t\tthis._initAriaAnnouncements();\n\t}\n\n\t/**\n\t * Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t * to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t *\n\t * Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t * is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t * See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t */\n\tprivate _handleCheckmarkChange( listItem: Element ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst previousSelectionRanges = Array.from( model.document.selection.getRanges() );\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( listItem, 'end' );\n\t\t\teditor.execute( 'checkTodoList' );\n\t\t\twriter.setSelection( previousSelectionRanges );\n\t\t} );\n\t}\n\n\t/**\n\t * Observe when user enters or leaves todo list and set proper aria value in global live announcer.\n\t * This allows screen readers to indicate when the user has entered and left the specified todo list.\n\t *\n\t * @internal\n\t */\n\tprivate _initAriaAnnouncements( ) {\n\t\tconst { model, ui, t } = this.editor;\n\t\tlet lastFocusedCodeBlock: Element | DocumentFragment | null = null;\n\n\t\tif ( !ui ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.document.selection.on<SelectionChangeRangeEvent>( 'change:range', () => {\n\t\t\tconst focusParent = model.document.selection.focus!.parent;\n\t\t\tconst lastElementIsTodoList = isLegacyTodoListItemElement( lastFocusedCodeBlock );\n\t\t\tconst currentElementIsTodoList = isLegacyTodoListItemElement( focusParent );\n\n\t\t\tif ( lastElementIsTodoList && !currentElementIsTodoList ) {\n\t\t\t\tui.ariaLiveAnnouncer.announce( t( 'Leaving a to-do list' ) );\n\t\t\t} else if ( !lastElementIsTodoList && currentElementIsTodoList ) {\n\t\t\t\tui.ariaLiveAnnouncer.announce( t( 'Entering a to-do list' ) );\n\t\t\t}\n\n\t\t\tlastFocusedCodeBlock = focusParent;\n\t\t} );\n\t}\n}\n\n/**\n * Handles the left/right (LTR/RTL content) arrow key and moves the selection at the end of the previous block element\n * if the selection is just after the checkbox element. In other words, it jumps over the checkbox element when\n * moving the selection to the left/right (LTR/RTL).\n *\n * @returns Callback for 'keydown' events.\n */\nfunction jumpOverCheckmarkOnSideArrowKeyPress( model: Model, locale: Locale ): GetCallback<ViewDocumentArrowKeyEvent> {\n\treturn ( eventInfo, domEventData ) => {\n\t\tconst direction = getLocalizedArrowKeyCodeDirection( domEventData.keyCode, locale.contentLanguageDirection );\n\n\t\tif ( direction != 'left' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = selection.getFirstPosition()!;\n\t\tconst parent = position.parent;\n\n\t\tif ( parent.name === 'listItem' && parent.getAttribute( 'listType' ) == 'todo' && position.isAtStart ) {\n\t\t\tconst newRange = schema.getNearestSelectionRange( model.createPositionBefore( parent ), 'backward' );\n\n\t\t\tif ( newRange ) {\n\t\t\t\tmodel.change( writer => writer.setSelection( newRange ) );\n\t\t\t}\n\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\n\t\t}\n\t};\n}\n\n/**\n * Returns true if the given element is a list item model element of a to-do list.\n */\nfunction isLegacyTodoListItemElement( element: Element | DocumentFragment | null ): boolean {\n\treturn !!element && element.is( 'element', 'listItem' ) && element.getAttribute( 'listType' ) === 'todo';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/legacytodolist\n */\n\nimport LegacyTodoListEditing from './legacytodolist/legacytodolistediting.js';\nimport TodoListUI from './todolist/todolistui.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport '../theme/todolist.css';\n\n/**\n * The legacy to-do list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/legacytodolist/legacytodolistediting~LegacyTodoListEditing legacy to-do list\n * editing feature} and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n */\nexport default class LegacyTodoList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ LegacyTodoListEditing, TodoListUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'LegacyTodoList' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/list/adjacentlistssupport\n */\n\nimport type { GetCallback } from 'ckeditor5/src/utils.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport type { UpcastElementEvent, ViewElement } from 'ckeditor5/src/engine.js';\n\nexport default class AdjacentListsSupport extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'AdjacentListsSupport' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tmodel.schema.register( 'listSeparator', {\n\t\t\tallowWhere: '$block',\n\t\t\tisBlock: true\n\t\t} );\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t// Add a list separator element between similar list elements on upcast.\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:ol', listSeparatorUpcastConverter() );\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:ul', listSeparatorUpcastConverter() );\n\t\t\t} )\n\t\t\t// View-to-model transformation.\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'listSeparator',\n\t\t\t\tview: 'ck-list-separator'\n\t\t\t} );\n\n\t\t// The list separator element should exist in the view, but should be invisible (hidden).\n\t\teditor.conversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'listSeparator',\n\t\t\tview: {\n\t\t\t\tname: 'div',\n\t\t\t\tclasses: [ 'ck-list-separator', 'ck-hidden' ]\n\t\t\t}\n\t\t} );\n\n\t\t// The list separator element should not exist in the output data.\n\t\teditor.conversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\tmodel: 'listSeparator',\n\t\t\tview: ( modelElement, conversionApi ) => {\n\t\t\t\tconst viewElement = conversionApi.writer.createContainerElement( 'ck-list-separator' );\n\n\t\t\t\tconversionApi.writer.setCustomProperty( 'dataPipeline:transparentRendering', true, viewElement );\n\n\t\t\t\tviewElement.getFillerOffset = () => null;\n\n\t\t\t\treturn viewElement;\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Inserts a list separator element between two lists of the same type (`ol` + `ol` or `ul` + `ul`).\n */\nfunction listSeparatorUpcastConverter(): GetCallback<UpcastElementEvent> {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst element: ViewElement = data.viewItem;\n\t\tconst nextSibling = element.nextSibling as ViewElement | null;\n\n\t\tif ( !nextSibling ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( element.name !== nextSibling.name ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !data.modelRange ) {\n\t\t\tObject.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t\t}\n\n\t\tconst writer = conversionApi.writer;\n\t\tconst modelElement = writer.createElement( 'listSeparator' );\n\n\t\t// Try to insert a list separator element on the current model cursor position.\n\t\tif ( !conversionApi.safeInsert( modelElement, data.modelCursor ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst parts = conversionApi.getSplitParts( modelElement );\n\n\t\t// Extend the model range with the range of the created list separator element.\n\t\tdata.modelRange = writer.createRange(\n\t\t\tdata.modelRange!.start,\n\t\t\twriter.createPositionAfter( parts[ parts.length - 1 ] )\n\t\t);\n\n\t\tconversionApi.updateConversionResult( modelElement, data );\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/documentlist\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { logWarning } from 'ckeditor5/src/utils.js';\nimport List from './list.js';\n\n/**\n * The document list feature.\n *\n * This is an obsolete plugin that exists for backward compatibility only.\n * Use the {@link module:list/list~List `List`} instead.\n *\n * @deprecated\n */\nexport default class DocumentList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ List ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'DocumentList' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The `DocumentList` plugin is obsolete. Use `List` instead.\n\t\t *\n\t\t * @error plugin-obsolete-documentlist\n\t\t */\n\t\tlogWarning( 'plugin-obsolete-documentlist', { pluginName: 'DocumentList' } );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/documentlistproperties\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { logWarning } from 'ckeditor5/src/utils.js';\nimport ListProperties from './listproperties.js';\n\n/**\n * The document list properties feature.\n *\n * This is an obsolete plugin that exists for backward compatibility only.\n * Use the {@link module:list/listproperties~ListProperties `ListProperties`} instead.\n *\n * @deprecated\n */\nexport default class DocumentListProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ListProperties ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'DocumentListProperties' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The `DocumentListProperties` plugin is obsolete. Use `ListProperties` instead.\n\t\t *\n\t\t * @error plugin-obsolete-documentlistproperties\n\t\t */\n\t\tlogWarning( 'plugin-obsolete-documentlistproperties', { pluginName: 'DocumentListProperties' } );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module list/tododocumentlist\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { logWarning } from 'ckeditor5/src/utils.js';\nimport TodoList from './todolist.js';\n\n/**\n * The to-do list feature.\n *\n * This is an obsolete plugin that exists for backward compatibility only.\n * Use the {@link module:list/todolist~TodoList `TodoList`} instead.\n *\n * @deprecated\n */\nexport default class TodoDocumentList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TodoList ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TodoDocumentList' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The `TodoDocumentList` plugin is obsolete. Use `TodoList` instead.\n\t\t *\n\t\t * @error plugin-obsolete-tododocumentlist\n\t\t */\n\t\tlogWarning( 'plugin-obsolete-tododocumentlist', { pluginName: 'TodoDocumentList' } );\n\t}\n}\n", "/**\n * marked - a markdown parser\n * Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed)\n * https://github.com/markedjs/marked\n */\n\n/**\n * DO NOT EDIT THIS FILE\n * The code in this file is generated from files in ./src/\n */\n\nfunction getDefaults() {\n  return {\n    baseUrl: null,\n    breaks: false,\n    extensions: null,\n    gfm: true,\n    headerIds: true,\n    headerPrefix: '',\n    highlight: null,\n    langPrefix: 'language-',\n    mangle: true,\n    pedantic: false,\n    renderer: null,\n    sanitize: false,\n    sanitizer: null,\n    silent: false,\n    smartLists: false,\n    smartypants: false,\n    tokenizer: null,\n    walkTokens: null,\n    xhtml: false\n  };\n}\n\nlet defaults = getDefaults();\n\nfunction changeDefaults(newDefaults) {\n  defaults = newDefaults;\n}\n\n/**\n * Helpers\n */\nconst escapeTest = /[&<>\"']/;\nconst escapeReplace = /[&<>\"']/g;\nconst escapeTestNoEncode = /[<>\"']|&(?!#?\\w+;)/;\nconst escapeReplaceNoEncode = /[<>\"']|&(?!#?\\w+;)/g;\nconst escapeReplacements = {\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&#39;'\n};\nconst getEscapeReplacement = (ch) => escapeReplacements[ch];\nfunction escape(html, encode) {\n  if (encode) {\n    if (escapeTest.test(html)) {\n      return html.replace(escapeReplace, getEscapeReplacement);\n    }\n  } else {\n    if (escapeTestNoEncode.test(html)) {\n      return html.replace(escapeReplaceNoEncode, getEscapeReplacement);\n    }\n  }\n\n  return html;\n}\n\nconst unescapeTest = /&(#(?:\\d+)|(?:#x[0-9A-Fa-f]+)|(?:\\w+));?/ig;\n\nfunction unescape(html) {\n  // explicitly match decimal, hex, and named HTML entities\n  return html.replace(unescapeTest, (_, n) => {\n    n = n.toLowerCase();\n    if (n === 'colon') return ':';\n    if (n.charAt(0) === '#') {\n      return n.charAt(1) === 'x'\n        ? String.fromCharCode(parseInt(n.substring(2), 16))\n        : String.fromCharCode(+n.substring(1));\n    }\n    return '';\n  });\n}\n\nconst caret = /(^|[^\\[])\\^/g;\nfunction edit(regex, opt) {\n  regex = regex.source || regex;\n  opt = opt || '';\n  const obj = {\n    replace: (name, val) => {\n      val = val.source || val;\n      val = val.replace(caret, '$1');\n      regex = regex.replace(name, val);\n      return obj;\n    },\n    getRegex: () => {\n      return new RegExp(regex, opt);\n    }\n  };\n  return obj;\n}\n\nconst nonWordAndColonTest = /[^\\w:]/g;\nconst originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;\nfunction cleanUrl(sanitize, base, href) {\n  if (sanitize) {\n    let prot;\n    try {\n      prot = decodeURIComponent(unescape(href))\n        .replace(nonWordAndColonTest, '')\n        .toLowerCase();\n    } catch (e) {\n      return null;\n    }\n    if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {\n      return null;\n    }\n  }\n  if (base && !originIndependentUrl.test(href)) {\n    href = resolveUrl(base, href);\n  }\n  try {\n    href = encodeURI(href).replace(/%25/g, '%');\n  } catch (e) {\n    return null;\n  }\n  return href;\n}\n\nconst baseUrls = {};\nconst justDomain = /^[^:]+:\\/*[^/]*$/;\nconst protocol = /^([^:]+:)[\\s\\S]*$/;\nconst domain = /^([^:]+:\\/*[^/]*)[\\s\\S]*$/;\n\nfunction resolveUrl(base, href) {\n  if (!baseUrls[' ' + base]) {\n    // we can ignore everything in base after the last slash of its path component,\n    // but we might need to add _that_\n    // https://tools.ietf.org/html/rfc3986#section-3\n    if (justDomain.test(base)) {\n      baseUrls[' ' + base] = base + '/';\n    } else {\n      baseUrls[' ' + base] = rtrim(base, '/', true);\n    }\n  }\n  base = baseUrls[' ' + base];\n  const relativeBase = base.indexOf(':') === -1;\n\n  if (href.substring(0, 2) === '//') {\n    if (relativeBase) {\n      return href;\n    }\n    return base.replace(protocol, '$1') + href;\n  } else if (href.charAt(0) === '/') {\n    if (relativeBase) {\n      return href;\n    }\n    return base.replace(domain, '$1') + href;\n  } else {\n    return base + href;\n  }\n}\n\nconst noopTest = { exec: function noopTest() {} };\n\nfunction merge(obj) {\n  let i = 1,\n    target,\n    key;\n\n  for (; i < arguments.length; i++) {\n    target = arguments[i];\n    for (key in target) {\n      if (Object.prototype.hasOwnProperty.call(target, key)) {\n        obj[key] = target[key];\n      }\n    }\n  }\n\n  return obj;\n}\n\nfunction splitCells(tableRow, count) {\n  // ensure that every cell-delimiting pipe has a space\n  // before it to distinguish it from an escaped pipe\n  const row = tableRow.replace(/\\|/g, (match, offset, str) => {\n      let escaped = false,\n        curr = offset;\n      while (--curr >= 0 && str[curr] === '\\\\') escaped = !escaped;\n      if (escaped) {\n        // odd number of slashes means | is escaped\n        // so we leave it alone\n        return '|';\n      } else {\n        // add space before unescaped |\n        return ' |';\n      }\n    }),\n    cells = row.split(/ \\|/);\n  let i = 0;\n\n  // First/last cell in a row cannot be empty if it has no leading/trailing pipe\n  if (!cells[0].trim()) { cells.shift(); }\n  if (cells.length > 0 && !cells[cells.length - 1].trim()) { cells.pop(); }\n\n  if (cells.length > count) {\n    cells.splice(count);\n  } else {\n    while (cells.length < count) cells.push('');\n  }\n\n  for (; i < cells.length; i++) {\n    // leading or trailing whitespace is ignored per the gfm spec\n    cells[i] = cells[i].trim().replace(/\\\\\\|/g, '|');\n  }\n  return cells;\n}\n\n// Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').\n// /c*$/ is vulnerable to REDOS.\n// invert: Remove suffix of non-c chars instead. Default falsey.\nfunction rtrim(str, c, invert) {\n  const l = str.length;\n  if (l === 0) {\n    return '';\n  }\n\n  // Length of suffix matching the invert condition.\n  let suffLen = 0;\n\n  // Step left until we fail to match the invert condition.\n  while (suffLen < l) {\n    const currChar = str.charAt(l - suffLen - 1);\n    if (currChar === c && !invert) {\n      suffLen++;\n    } else if (currChar !== c && invert) {\n      suffLen++;\n    } else {\n      break;\n    }\n  }\n\n  return str.substr(0, l - suffLen);\n}\n\nfunction findClosingBracket(str, b) {\n  if (str.indexOf(b[1]) === -1) {\n    return -1;\n  }\n  const l = str.length;\n  let level = 0,\n    i = 0;\n  for (; i < l; i++) {\n    if (str[i] === '\\\\') {\n      i++;\n    } else if (str[i] === b[0]) {\n      level++;\n    } else if (str[i] === b[1]) {\n      level--;\n      if (level < 0) {\n        return i;\n      }\n    }\n  }\n  return -1;\n}\n\nfunction checkSanitizeDeprecation(opt) {\n  if (opt && opt.sanitize && !opt.silent) {\n    console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');\n  }\n}\n\n// copied from https://stackoverflow.com/a/5450113/806777\nfunction repeatString(pattern, count) {\n  if (count < 1) {\n    return '';\n  }\n  let result = '';\n  while (count > 1) {\n    if (count & 1) {\n      result += pattern;\n    }\n    count >>= 1;\n    pattern += pattern;\n  }\n  return result + pattern;\n}\n\nfunction outputLink(cap, link, raw, lexer) {\n  const href = link.href;\n  const title = link.title ? escape(link.title) : null;\n  const text = cap[1].replace(/\\\\([\\[\\]])/g, '$1');\n\n  if (cap[0].charAt(0) !== '!') {\n    lexer.state.inLink = true;\n    const token = {\n      type: 'link',\n      raw,\n      href,\n      title,\n      text,\n      tokens: lexer.inlineTokens(text, [])\n    };\n    lexer.state.inLink = false;\n    return token;\n  } else {\n    return {\n      type: 'image',\n      raw,\n      href,\n      title,\n      text: escape(text)\n    };\n  }\n}\n\nfunction indentCodeCompensation(raw, text) {\n  const matchIndentToCode = raw.match(/^(\\s+)(?:```)/);\n\n  if (matchIndentToCode === null) {\n    return text;\n  }\n\n  const indentToCode = matchIndentToCode[1];\n\n  return text\n    .split('\\n')\n    .map(node => {\n      const matchIndentInNode = node.match(/^\\s+/);\n      if (matchIndentInNode === null) {\n        return node;\n      }\n\n      const [indentInNode] = matchIndentInNode;\n\n      if (indentInNode.length >= indentToCode.length) {\n        return node.slice(indentToCode.length);\n      }\n\n      return node;\n    })\n    .join('\\n');\n}\n\n/**\n * Tokenizer\n */\nclass Tokenizer {\n  constructor(options) {\n    this.options = options || defaults;\n  }\n\n  space(src) {\n    const cap = this.rules.block.newline.exec(src);\n    if (cap && cap[0].length > 0) {\n      return {\n        type: 'space',\n        raw: cap[0]\n      };\n    }\n  }\n\n  code(src) {\n    const cap = this.rules.block.code.exec(src);\n    if (cap) {\n      const text = cap[0].replace(/^ {1,4}/gm, '');\n      return {\n        type: 'code',\n        raw: cap[0],\n        codeBlockStyle: 'indented',\n        text: !this.options.pedantic\n          ? rtrim(text, '\\n')\n          : text\n      };\n    }\n  }\n\n  fences(src) {\n    const cap = this.rules.block.fences.exec(src);\n    if (cap) {\n      const raw = cap[0];\n      const text = indentCodeCompensation(raw, cap[3] || '');\n\n      return {\n        type: 'code',\n        raw,\n        lang: cap[2] ? cap[2].trim() : cap[2],\n        text\n      };\n    }\n  }\n\n  heading(src) {\n    const cap = this.rules.block.heading.exec(src);\n    if (cap) {\n      let text = cap[2].trim();\n\n      // remove trailing #s\n      if (/#$/.test(text)) {\n        const trimmed = rtrim(text, '#');\n        if (this.options.pedantic) {\n          text = trimmed.trim();\n        } else if (!trimmed || / $/.test(trimmed)) {\n          // CommonMark requires space before trailing #s\n          text = trimmed.trim();\n        }\n      }\n\n      const token = {\n        type: 'heading',\n        raw: cap[0],\n        depth: cap[1].length,\n        text: text,\n        tokens: []\n      };\n      this.lexer.inline(token.text, token.tokens);\n      return token;\n    }\n  }\n\n  hr(src) {\n    const cap = this.rules.block.hr.exec(src);\n    if (cap) {\n      return {\n        type: 'hr',\n        raw: cap[0]\n      };\n    }\n  }\n\n  blockquote(src) {\n    const cap = this.rules.block.blockquote.exec(src);\n    if (cap) {\n      const text = cap[0].replace(/^ *> ?/gm, '');\n\n      return {\n        type: 'blockquote',\n        raw: cap[0],\n        tokens: this.lexer.blockTokens(text, []),\n        text\n      };\n    }\n  }\n\n  list(src) {\n    let cap = this.rules.block.list.exec(src);\n    if (cap) {\n      let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine,\n        line, nextLine, rawLine, itemContents, endEarly;\n\n      let bull = cap[1].trim();\n      const isordered = bull.length > 1;\n\n      const list = {\n        type: 'list',\n        raw: '',\n        ordered: isordered,\n        start: isordered ? +bull.slice(0, -1) : '',\n        loose: false,\n        items: []\n      };\n\n      bull = isordered ? `\\\\d{1,9}\\\\${bull.slice(-1)}` : `\\\\${bull}`;\n\n      if (this.options.pedantic) {\n        bull = isordered ? bull : '[*+-]';\n      }\n\n      // Get next list item\n      const itemRegex = new RegExp(`^( {0,3}${bull})((?: [^\\\\n]*)?(?:\\\\n|$))`);\n\n      // Check if current bullet point can start a new List Item\n      while (src) {\n        endEarly = false;\n        if (!(cap = itemRegex.exec(src))) {\n          break;\n        }\n\n        if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)\n          break;\n        }\n\n        raw = cap[0];\n        src = src.substring(raw.length);\n\n        line = cap[2].split('\\n', 1)[0];\n        nextLine = src.split('\\n', 1)[0];\n\n        if (this.options.pedantic) {\n          indent = 2;\n          itemContents = line.trimLeft();\n        } else {\n          indent = cap[2].search(/[^ ]/); // Find first non-space char\n          indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent\n          itemContents = line.slice(indent);\n          indent += cap[1].length;\n        }\n\n        blankLine = false;\n\n        if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line\n          raw += nextLine + '\\n';\n          src = src.substring(nextLine.length + 1);\n          endEarly = true;\n        }\n\n        if (!endEarly) {\n          const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\\\d{1,9}[.)])`);\n\n          // Check if following lines should be included in List Item\n          while (src) {\n            rawLine = src.split('\\n', 1)[0];\n            line = rawLine;\n\n            // Re-align to follow commonmark nesting rules\n            if (this.options.pedantic) {\n              line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');\n            }\n\n            // End list item if found start of new bullet\n            if (nextBulletRegex.test(line)) {\n              break;\n            }\n\n            if (line.search(/[^ ]/) >= indent || !line.trim()) { // Dedent if possible\n              itemContents += '\\n' + line.slice(indent);\n            } else if (!blankLine) { // Until blank line, item doesn't need indentation\n              itemContents += '\\n' + line;\n            } else { // Otherwise, improper indentation ends this item\n              break;\n            }\n\n            if (!blankLine && !line.trim()) { // Check if current line is blank\n              blankLine = true;\n            }\n\n            raw += rawLine + '\\n';\n            src = src.substring(rawLine.length + 1);\n          }\n        }\n\n        if (!list.loose) {\n          // If the previous item ended with a blank line, the list is loose\n          if (endsWithBlankLine) {\n            list.loose = true;\n          } else if (/\\n *\\n *$/.test(raw)) {\n            endsWithBlankLine = true;\n          }\n        }\n\n        // Check for task list items\n        if (this.options.gfm) {\n          istask = /^\\[[ xX]\\] /.exec(itemContents);\n          if (istask) {\n            ischecked = istask[0] !== '[ ] ';\n            itemContents = itemContents.replace(/^\\[[ xX]\\] +/, '');\n          }\n        }\n\n        list.items.push({\n          type: 'list_item',\n          raw: raw,\n          task: !!istask,\n          checked: ischecked,\n          loose: false,\n          text: itemContents\n        });\n\n        list.raw += raw;\n      }\n\n      // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic\n      list.items[list.items.length - 1].raw = raw.trimRight();\n      list.items[list.items.length - 1].text = itemContents.trimRight();\n      list.raw = list.raw.trimRight();\n\n      const l = list.items.length;\n\n      // Item child tokens handled here at end because we needed to have the final item to trim it first\n      for (i = 0; i < l; i++) {\n        this.lexer.state.top = false;\n        list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);\n        const spacers = list.items[i].tokens.filter(t => t.type === 'space');\n        const hasMultipleLineBreaks = spacers.every(t => {\n          const chars = t.raw.split('');\n          let lineBreaks = 0;\n          for (const char of chars) {\n            if (char === '\\n') {\n              lineBreaks += 1;\n            }\n            if (lineBreaks > 1) {\n              return true;\n            }\n          }\n\n          return false;\n        });\n\n        if (!list.loose && spacers.length && hasMultipleLineBreaks) {\n          // Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item\n          list.loose = true;\n          list.items[i].loose = true;\n        }\n      }\n\n      return list;\n    }\n  }\n\n  html(src) {\n    const cap = this.rules.block.html.exec(src);\n    if (cap) {\n      const token = {\n        type: 'html',\n        raw: cap[0],\n        pre: !this.options.sanitizer\n          && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),\n        text: cap[0]\n      };\n      if (this.options.sanitize) {\n        token.type = 'paragraph';\n        token.text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);\n        token.tokens = [];\n        this.lexer.inline(token.text, token.tokens);\n      }\n      return token;\n    }\n  }\n\n  def(src) {\n    const cap = this.rules.block.def.exec(src);\n    if (cap) {\n      if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1);\n      const tag = cap[1].toLowerCase().replace(/\\s+/g, ' ');\n      return {\n        type: 'def',\n        tag,\n        raw: cap[0],\n        href: cap[2],\n        title: cap[3]\n      };\n    }\n  }\n\n  table(src) {\n    const cap = this.rules.block.table.exec(src);\n    if (cap) {\n      const item = {\n        type: 'table',\n        header: splitCells(cap[1]).map(c => { return { text: c }; }),\n        align: cap[2].replace(/^ *|\\| *$/g, '').split(/ *\\| */),\n        rows: cap[3] && cap[3].trim() ? cap[3].replace(/\\n[ \\t]*$/, '').split('\\n') : []\n      };\n\n      if (item.header.length === item.align.length) {\n        item.raw = cap[0];\n\n        let l = item.align.length;\n        let i, j, k, row;\n        for (i = 0; i < l; i++) {\n          if (/^ *-+: *$/.test(item.align[i])) {\n            item.align[i] = 'right';\n          } else if (/^ *:-+: *$/.test(item.align[i])) {\n            item.align[i] = 'center';\n          } else if (/^ *:-+ *$/.test(item.align[i])) {\n            item.align[i] = 'left';\n          } else {\n            item.align[i] = null;\n          }\n        }\n\n        l = item.rows.length;\n        for (i = 0; i < l; i++) {\n          item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { return { text: c }; });\n        }\n\n        // parse child tokens inside headers and cells\n\n        // header child tokens\n        l = item.header.length;\n        for (j = 0; j < l; j++) {\n          item.header[j].tokens = [];\n          this.lexer.inlineTokens(item.header[j].text, item.header[j].tokens);\n        }\n\n        // cell child tokens\n        l = item.rows.length;\n        for (j = 0; j < l; j++) {\n          row = item.rows[j];\n          for (k = 0; k < row.length; k++) {\n            row[k].tokens = [];\n            this.lexer.inlineTokens(row[k].text, row[k].tokens);\n          }\n        }\n\n        return item;\n      }\n    }\n  }\n\n  lheading(src) {\n    const cap = this.rules.block.lheading.exec(src);\n    if (cap) {\n      const token = {\n        type: 'heading',\n        raw: cap[0],\n        depth: cap[2].charAt(0) === '=' ? 1 : 2,\n        text: cap[1],\n        tokens: []\n      };\n      this.lexer.inline(token.text, token.tokens);\n      return token;\n    }\n  }\n\n  paragraph(src) {\n    const cap = this.rules.block.paragraph.exec(src);\n    if (cap) {\n      const token = {\n        type: 'paragraph',\n        raw: cap[0],\n        text: cap[1].charAt(cap[1].length - 1) === '\\n'\n          ? cap[1].slice(0, -1)\n          : cap[1],\n        tokens: []\n      };\n      this.lexer.inline(token.text, token.tokens);\n      return token;\n    }\n  }\n\n  text(src) {\n    const cap = this.rules.block.text.exec(src);\n    if (cap) {\n      const token = {\n        type: 'text',\n        raw: cap[0],\n        text: cap[0],\n        tokens: []\n      };\n      this.lexer.inline(token.text, token.tokens);\n      return token;\n    }\n  }\n\n  escape(src) {\n    const cap = this.rules.inline.escape.exec(src);\n    if (cap) {\n      return {\n        type: 'escape',\n        raw: cap[0],\n        text: escape(cap[1])\n      };\n    }\n  }\n\n  tag(src) {\n    const cap = this.rules.inline.tag.exec(src);\n    if (cap) {\n      if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {\n        this.lexer.state.inLink = true;\n      } else if (this.lexer.state.inLink && /^<\\/a>/i.test(cap[0])) {\n        this.lexer.state.inLink = false;\n      }\n      if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\\s|>)/i.test(cap[0])) {\n        this.lexer.state.inRawBlock = true;\n      } else if (this.lexer.state.inRawBlock && /^<\\/(pre|code|kbd|script)(\\s|>)/i.test(cap[0])) {\n        this.lexer.state.inRawBlock = false;\n      }\n\n      return {\n        type: this.options.sanitize\n          ? 'text'\n          : 'html',\n        raw: cap[0],\n        inLink: this.lexer.state.inLink,\n        inRawBlock: this.lexer.state.inRawBlock,\n        text: this.options.sanitize\n          ? (this.options.sanitizer\n            ? this.options.sanitizer(cap[0])\n            : escape(cap[0]))\n          : cap[0]\n      };\n    }\n  }\n\n  link(src) {\n    const cap = this.rules.inline.link.exec(src);\n    if (cap) {\n      const trimmedUrl = cap[2].trim();\n      if (!this.options.pedantic && /^</.test(trimmedUrl)) {\n        // commonmark requires matching angle brackets\n        if (!(/>$/.test(trimmedUrl))) {\n          return;\n        }\n\n        // ending angle bracket cannot be escaped\n        const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\\\');\n        if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {\n          return;\n        }\n      } else {\n        // find closing parenthesis\n        const lastParenIndex = findClosingBracket(cap[2], '()');\n        if (lastParenIndex > -1) {\n          const start = cap[0].indexOf('!') === 0 ? 5 : 4;\n          const linkLen = start + cap[1].length + lastParenIndex;\n          cap[2] = cap[2].substring(0, lastParenIndex);\n          cap[0] = cap[0].substring(0, linkLen).trim();\n          cap[3] = '';\n        }\n      }\n      let href = cap[2];\n      let title = '';\n      if (this.options.pedantic) {\n        // split pedantic href and title\n        const link = /^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/.exec(href);\n\n        if (link) {\n          href = link[1];\n          title = link[3];\n        }\n      } else {\n        title = cap[3] ? cap[3].slice(1, -1) : '';\n      }\n\n      href = href.trim();\n      if (/^</.test(href)) {\n        if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {\n          // pedantic allows starting angle bracket without ending angle bracket\n          href = href.slice(1);\n        } else {\n          href = href.slice(1, -1);\n        }\n      }\n      return outputLink(cap, {\n        href: href ? href.replace(this.rules.inline._escapes, '$1') : href,\n        title: title ? title.replace(this.rules.inline._escapes, '$1') : title\n      }, cap[0], this.lexer);\n    }\n  }\n\n  reflink(src, links) {\n    let cap;\n    if ((cap = this.rules.inline.reflink.exec(src))\n        || (cap = this.rules.inline.nolink.exec(src))) {\n      let link = (cap[2] || cap[1]).replace(/\\s+/g, ' ');\n      link = links[link.toLowerCase()];\n      if (!link || !link.href) {\n        const text = cap[0].charAt(0);\n        return {\n          type: 'text',\n          raw: text,\n          text\n        };\n      }\n      return outputLink(cap, link, cap[0], this.lexer);\n    }\n  }\n\n  emStrong(src, maskedSrc, prevChar = '') {\n    let match = this.rules.inline.emStrong.lDelim.exec(src);\n    if (!match) return;\n\n    // _ can't be between two alphanumerics. \\p{L}\\p{N} includes non-english alphabet/numbers as well\n    if (match[3] && prevChar.match(/[\\p{L}\\p{N}]/u)) return;\n\n    const nextChar = match[1] || match[2] || '';\n\n    if (!nextChar || (nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {\n      const lLength = match[0].length - 1;\n      let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;\n\n      const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;\n      endReg.lastIndex = 0;\n\n      // Clip maskedSrc to same section of string as src (move to lexer?)\n      maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n\n      while ((match = endReg.exec(maskedSrc)) != null) {\n        rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n\n        if (!rDelim) continue; // skip single * in __abc*abc__\n\n        rLength = rDelim.length;\n\n        if (match[3] || match[4]) { // found another Left Delim\n          delimTotal += rLength;\n          continue;\n        } else if (match[5] || match[6]) { // either Left or Right Delim\n          if (lLength % 3 && !((lLength + rLength) % 3)) {\n            midDelimTotal += rLength;\n            continue; // CommonMark Emphasis Rules 9-10\n          }\n        }\n\n        delimTotal -= rLength;\n\n        if (delimTotal > 0) continue; // Haven't found enough closing delimiters\n\n        // Remove extra characters. *a*** -> *a*\n        rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);\n\n        // Create `em` if smallest delimiter has odd char count. *a***\n        if (Math.min(lLength, rLength) % 2) {\n          const text = src.slice(1, lLength + match.index + rLength);\n          return {\n            type: 'em',\n            raw: src.slice(0, lLength + match.index + rLength + 1),\n            text,\n            tokens: this.lexer.inlineTokens(text, [])\n          };\n        }\n\n        // Create 'strong' if smallest delimiter has even char count. **a***\n        const text = src.slice(2, lLength + match.index + rLength - 1);\n        return {\n          type: 'strong',\n          raw: src.slice(0, lLength + match.index + rLength + 1),\n          text,\n          tokens: this.lexer.inlineTokens(text, [])\n        };\n      }\n    }\n  }\n\n  codespan(src) {\n    const cap = this.rules.inline.code.exec(src);\n    if (cap) {\n      let text = cap[2].replace(/\\n/g, ' ');\n      const hasNonSpaceChars = /[^ ]/.test(text);\n      const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);\n      if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n        text = text.substring(1, text.length - 1);\n      }\n      text = escape(text, true);\n      return {\n        type: 'codespan',\n        raw: cap[0],\n        text\n      };\n    }\n  }\n\n  br(src) {\n    const cap = this.rules.inline.br.exec(src);\n    if (cap) {\n      return {\n        type: 'br',\n        raw: cap[0]\n      };\n    }\n  }\n\n  del(src) {\n    const cap = this.rules.inline.del.exec(src);\n    if (cap) {\n      return {\n        type: 'del',\n        raw: cap[0],\n        text: cap[2],\n        tokens: this.lexer.inlineTokens(cap[2], [])\n      };\n    }\n  }\n\n  autolink(src, mangle) {\n    const cap = this.rules.inline.autolink.exec(src);\n    if (cap) {\n      let text, href;\n      if (cap[2] === '@') {\n        text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);\n        href = 'mailto:' + text;\n      } else {\n        text = escape(cap[1]);\n        href = text;\n      }\n\n      return {\n        type: 'link',\n        raw: cap[0],\n        text,\n        href,\n        tokens: [\n          {\n            type: 'text',\n            raw: text,\n            text\n          }\n        ]\n      };\n    }\n  }\n\n  url(src, mangle) {\n    let cap;\n    if (cap = this.rules.inline.url.exec(src)) {\n      let text, href;\n      if (cap[2] === '@') {\n        text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);\n        href = 'mailto:' + text;\n      } else {\n        // do extended autolink path validation\n        let prevCapZero;\n        do {\n          prevCapZero = cap[0];\n          cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];\n        } while (prevCapZero !== cap[0]);\n        text = escape(cap[0]);\n        if (cap[1] === 'www.') {\n          href = 'http://' + text;\n        } else {\n          href = text;\n        }\n      }\n      return {\n        type: 'link',\n        raw: cap[0],\n        text,\n        href,\n        tokens: [\n          {\n            type: 'text',\n            raw: text,\n            text\n          }\n        ]\n      };\n    }\n  }\n\n  inlineText(src, smartypants) {\n    const cap = this.rules.inline.text.exec(src);\n    if (cap) {\n      let text;\n      if (this.lexer.state.inRawBlock) {\n        text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0])) : cap[0];\n      } else {\n        text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);\n      }\n      return {\n        type: 'text',\n        raw: cap[0],\n        text\n      };\n    }\n  }\n}\n\n/**\n * Block-Level Grammar\n */\nconst block = {\n  newline: /^(?: *(?:\\n|$))+/,\n  code: /^( {4}[^\\n]+(?:\\n(?: *(?:\\n|$))*)?)+/,\n  fences: /^ {0,3}(`{3,}(?=[^`\\n]*\\n)|~{3,})([^\\n]*)\\n(?:|([\\s\\S]*?)\\n)(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/,\n  hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)/,\n  heading: /^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/,\n  blockquote: /^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/,\n  list: /^( {0,3}bull)( [^\\n]+?)?(?:\\n|$)/,\n  html: '^ {0,3}(?:' // optional indentation\n    + '<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n+|$)' // (1)\n    + '|comment[^\\\\n]*(\\\\n+|$)' // (2)\n    + '|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)' // (3)\n    + '|<![A-Z][\\\\s\\\\S]*?(?:>\\\\n*|$)' // (4)\n    + '|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>\\\\n*|$)' // (5)\n    + '|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n *)+\\\\n|$)' // (6)\n    + '|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n *)+\\\\n|$)' // (7) open tag\n    + '|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n *)+\\\\n|$)' // (7) closing tag\n    + ')',\n  def: /^ {0,3}\\[(label)\\]: *(?:\\n *)?<?([^\\s>]+)>?(?:(?: +(?:\\n *)?| *\\n *)(title))? *(?:\\n+|$)/,\n  table: noopTest,\n  lheading: /^([^\\n]+)\\n {0,3}(=+|-+) *(?:\\n+|$)/,\n  // regex template, placeholders will be replaced according to different paragraph\n  // interruption rules of commonmark and the original markdown spec:\n  _paragraph: /^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/,\n  text: /^[^\\n]+/\n};\n\nblock._label = /(?!\\s*\\])(?:\\\\.|[^\\[\\]\\\\])+/;\nblock._title = /(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/;\nblock.def = edit(block.def)\n  .replace('label', block._label)\n  .replace('title', block._title)\n  .getRegex();\n\nblock.bullet = /(?:[*+-]|\\d{1,9}[.)])/;\nblock.listItemStart = edit(/^( *)(bull) */)\n  .replace('bull', block.bullet)\n  .getRegex();\n\nblock.list = edit(block.list)\n  .replace(/bull/g, block.bullet)\n  .replace('hr', '\\\\n+(?=\\\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$))')\n  .replace('def', '\\\\n+(?=' + block.def.source + ')')\n  .getRegex();\n\nblock._tag = 'address|article|aside|base|basefont|blockquote|body|caption'\n  + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'\n  + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'\n  + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'\n  + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'\n  + '|track|ul';\nblock._comment = /<!--(?!-?>)[\\s\\S]*?(?:-->|$)/;\nblock.html = edit(block.html, 'i')\n  .replace('comment', block._comment)\n  .replace('tag', block._tag)\n  .replace('attribute', / +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/)\n  .getRegex();\n\nblock.paragraph = edit(block._paragraph)\n  .replace('hr', block.hr)\n  .replace('heading', ' {0,3}#{1,6} ')\n  .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs\n  .replace('|table', '')\n  .replace('blockquote', ' {0,3}>')\n  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n  .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n  .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks\n  .getRegex();\n\nblock.blockquote = edit(block.blockquote)\n  .replace('paragraph', block.paragraph)\n  .getRegex();\n\n/**\n * Normal Block Grammar\n */\n\nblock.normal = merge({}, block);\n\n/**\n * GFM Block Grammar\n */\n\nblock.gfm = merge({}, block.normal, {\n  table: '^ *([^\\\\n ].*\\\\|.*)\\\\n' // Header\n    + ' {0,3}(?:\\\\| *)?(:?-+:? *(?:\\\\| *:?-+:? *)*)(?:\\\\| *)?' // Align\n    + '(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)' // Cells\n});\n\nblock.gfm.table = edit(block.gfm.table)\n  .replace('hr', block.hr)\n  .replace('heading', ' {0,3}#{1,6} ')\n  .replace('blockquote', ' {0,3}>')\n  .replace('code', ' {4}[^\\\\n]')\n  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n  .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n  .replace('tag', block._tag) // tables can be interrupted by type (6) html blocks\n  .getRegex();\n\nblock.gfm.paragraph = edit(block._paragraph)\n  .replace('hr', block.hr)\n  .replace('heading', ' {0,3}#{1,6} ')\n  .replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs\n  .replace('table', block.gfm.table) // interrupt paragraphs with table\n  .replace('blockquote', ' {0,3}>')\n  .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n  .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n  .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n  .replace('tag', block._tag) // pars can be interrupted by type (6) html blocks\n  .getRegex();\n/**\n * Pedantic grammar (original John Gruber's loose markdown specification)\n */\n\nblock.pedantic = merge({}, block.normal, {\n  html: edit(\n    '^ *(?:comment *(?:\\\\n|\\\\s*$)'\n    + '|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)' // closed tag\n    + '|<tag(?:\"[^\"]*\"|\\'[^\\']*\\'|\\\\s[^\\'\"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))')\n    .replace('comment', block._comment)\n    .replace(/tag/g, '(?!(?:'\n      + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'\n      + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'\n      + '\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b')\n    .getRegex(),\n  def: /^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,\n  heading: /^(#{1,6})(.*)(?:\\n+|$)/,\n  fences: noopTest, // fences not supported\n  paragraph: edit(block.normal._paragraph)\n    .replace('hr', block.hr)\n    .replace('heading', ' *#{1,6} *[^\\n]')\n    .replace('lheading', block.lheading)\n    .replace('blockquote', ' {0,3}>')\n    .replace('|fences', '')\n    .replace('|list', '')\n    .replace('|html', '')\n    .getRegex()\n});\n\n/**\n * Inline-Level Grammar\n */\nconst inline = {\n  escape: /^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/,\n  autolink: /^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/,\n  url: noopTest,\n  tag: '^comment'\n    + '|^</[a-zA-Z][\\\\w:-]*\\\\s*>' // self-closing tag\n    + '|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>' // open tag\n    + '|^<\\\\?[\\\\s\\\\S]*?\\\\?>' // processing instruction, e.g. <?php ?>\n    + '|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>' // declaration, e.g. <!DOCTYPE html>\n    + '|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>', // CDATA section\n  link: /^!?\\[(label)\\]\\(\\s*(href)(?:\\s+(title))?\\s*\\)/,\n  reflink: /^!?\\[(label)\\]\\[(ref)\\]/,\n  nolink: /^!?\\[(ref)\\](?:\\[\\])?/,\n  reflinkSearch: 'reflink|nolink(?!\\\\()',\n  emStrong: {\n    lDelim: /^(?:\\*+(?:([punct_])|[^\\s*]))|^_+(?:([punct*])|([^\\s_]))/,\n    //        (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left.  (5) and (6) can be either Left or Right.\n    //        () Skip orphan delim inside strong    (1) #***                (2) a***#, a***                   (3) #***a, ***a                 (4) ***#              (5) #***#                 (6) a***a\n    rDelimAst: /^[^_*]*?\\_\\_[^_*]*?\\*[^_*]*?(?=\\_\\_)|[punct_](\\*+)(?=[\\s]|$)|[^punct*_\\s](\\*+)(?=[punct_\\s]|$)|[punct_\\s](\\*+)(?=[^punct*_\\s])|[\\s](\\*+)(?=[punct_])|[punct_](\\*+)(?=[punct_])|[^punct*_\\s](\\*+)(?=[^punct*_\\s])/,\n    rDelimUnd: /^[^_*]*?\\*\\*[^_*]*?\\_[^_*]*?(?=\\*\\*)|[punct*](\\_+)(?=[\\s]|$)|[^punct*_\\s](\\_+)(?=[punct*\\s]|$)|[punct*\\s](\\_+)(?=[^punct*_\\s])|[\\s](\\_+)(?=[punct*])|[punct*](\\_+)(?=[punct*])/ // ^- Not allowed for _\n  },\n  code: /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/,\n  br: /^( {2,}|\\\\)\\n(?!\\s*$)/,\n  del: noopTest,\n  text: /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/,\n  punctuation: /^([\\spunctuation])/\n};\n\n// list of punctuation marks from CommonMark spec\n// without * and _ to handle the different emphasis markers * and _\ninline._punctuation = '!\"#$%&\\'()+\\\\-.,/:;<=>?@\\\\[\\\\]`^{|}~';\ninline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();\n\n// sequences em should skip over [title](link), `code`, <html>\ninline.blockSkip = /\\[[^\\]]*?\\]\\([^\\)]*?\\)|`[^`]*?`|<[^>]*?>/g;\ninline.escapedEmSt = /\\\\\\*|\\\\_/g;\n\ninline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();\n\ninline.emStrong.lDelim = edit(inline.emStrong.lDelim)\n  .replace(/punct/g, inline._punctuation)\n  .getRegex();\n\ninline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g')\n  .replace(/punct/g, inline._punctuation)\n  .getRegex();\n\ninline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g')\n  .replace(/punct/g, inline._punctuation)\n  .getRegex();\n\ninline._escapes = /\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/g;\n\ninline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;\ninline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;\ninline.autolink = edit(inline.autolink)\n  .replace('scheme', inline._scheme)\n  .replace('email', inline._email)\n  .getRegex();\n\ninline._attribute = /\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/;\n\ninline.tag = edit(inline.tag)\n  .replace('comment', inline._comment)\n  .replace('attribute', inline._attribute)\n  .getRegex();\n\ninline._label = /(?:\\[(?:\\\\.|[^\\[\\]\\\\])*\\]|\\\\.|`[^`]*`|[^\\[\\]\\\\`])*?/;\ninline._href = /<(?:\\\\.|[^\\n<>\\\\])+>|[^\\s\\x00-\\x1f]*/;\ninline._title = /\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/;\n\ninline.link = edit(inline.link)\n  .replace('label', inline._label)\n  .replace('href', inline._href)\n  .replace('title', inline._title)\n  .getRegex();\n\ninline.reflink = edit(inline.reflink)\n  .replace('label', inline._label)\n  .replace('ref', block._label)\n  .getRegex();\n\ninline.nolink = edit(inline.nolink)\n  .replace('ref', block._label)\n  .getRegex();\n\ninline.reflinkSearch = edit(inline.reflinkSearch, 'g')\n  .replace('reflink', inline.reflink)\n  .replace('nolink', inline.nolink)\n  .getRegex();\n\n/**\n * Normal Inline Grammar\n */\n\ninline.normal = merge({}, inline);\n\n/**\n * Pedantic Inline Grammar\n */\n\ninline.pedantic = merge({}, inline.normal, {\n  strong: {\n    start: /^__|\\*\\*/,\n    middle: /^__(?=\\S)([\\s\\S]*?\\S)__(?!_)|^\\*\\*(?=\\S)([\\s\\S]*?\\S)\\*\\*(?!\\*)/,\n    endAst: /\\*\\*(?!\\*)/g,\n    endUnd: /__(?!_)/g\n  },\n  em: {\n    start: /^_|\\*/,\n    middle: /^()\\*(?=\\S)([\\s\\S]*?\\S)\\*(?!\\*)|^_(?=\\S)([\\s\\S]*?\\S)_(?!_)/,\n    endAst: /\\*(?!\\*)/g,\n    endUnd: /_(?!_)/g\n  },\n  link: edit(/^!?\\[(label)\\]\\((.*?)\\)/)\n    .replace('label', inline._label)\n    .getRegex(),\n  reflink: edit(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/)\n    .replace('label', inline._label)\n    .getRegex()\n});\n\n/**\n * GFM Inline Grammar\n */\n\ninline.gfm = merge({}, inline.normal, {\n  escape: edit(inline.escape).replace('])', '~|])').getRegex(),\n  _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,\n  url: /^((?:ftp|https?):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/,\n  _backpedal: /(?:[^?!.,:;*_~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,\n  del: /^(~~?)(?=[^\\s~])([\\s\\S]*?[^\\s~])\\1(?=[^~]|$)/,\n  text: /^([`~]+|[^`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|https?:\\/\\/|ftp:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)))/\n});\n\ninline.gfm.url = edit(inline.gfm.url, 'i')\n  .replace('email', inline.gfm._extended_email)\n  .getRegex();\n/**\n * GFM + Line Breaks Inline Grammar\n */\n\ninline.breaks = merge({}, inline.gfm, {\n  br: edit(inline.br).replace('{2,}', '*').getRegex(),\n  text: edit(inline.gfm.text)\n    .replace('\\\\b_', '\\\\b_| {2,}\\\\n')\n    .replace(/\\{2,\\}/g, '*')\n    .getRegex()\n});\n\n/**\n * smartypants text replacement\n */\nfunction smartypants(text) {\n  return text\n    // em-dashes\n    .replace(/---/g, '\\u2014')\n    // en-dashes\n    .replace(/--/g, '\\u2013')\n    // opening singles\n    .replace(/(^|[-\\u2014/(\\[{\"\\s])'/g, '$1\\u2018')\n    // closing singles & apostrophes\n    .replace(/'/g, '\\u2019')\n    // opening doubles\n    .replace(/(^|[-\\u2014/(\\[{\\u2018\\s])\"/g, '$1\\u201c')\n    // closing doubles\n    .replace(/\"/g, '\\u201d')\n    // ellipses\n    .replace(/\\.{3}/g, '\\u2026');\n}\n\n/**\n * mangle email addresses\n */\nfunction mangle(text) {\n  let out = '',\n    i,\n    ch;\n\n  const l = text.length;\n  for (i = 0; i < l; i++) {\n    ch = text.charCodeAt(i);\n    if (Math.random() > 0.5) {\n      ch = 'x' + ch.toString(16);\n    }\n    out += '&#' + ch + ';';\n  }\n\n  return out;\n}\n\n/**\n * Block Lexer\n */\nclass Lexer {\n  constructor(options) {\n    this.tokens = [];\n    this.tokens.links = Object.create(null);\n    this.options = options || defaults;\n    this.options.tokenizer = this.options.tokenizer || new Tokenizer();\n    this.tokenizer = this.options.tokenizer;\n    this.tokenizer.options = this.options;\n    this.tokenizer.lexer = this;\n    this.inlineQueue = [];\n    this.state = {\n      inLink: false,\n      inRawBlock: false,\n      top: true\n    };\n\n    const rules = {\n      block: block.normal,\n      inline: inline.normal\n    };\n\n    if (this.options.pedantic) {\n      rules.block = block.pedantic;\n      rules.inline = inline.pedantic;\n    } else if (this.options.gfm) {\n      rules.block = block.gfm;\n      if (this.options.breaks) {\n        rules.inline = inline.breaks;\n      } else {\n        rules.inline = inline.gfm;\n      }\n    }\n    this.tokenizer.rules = rules;\n  }\n\n  /**\n   * Expose Rules\n   */\n  static get rules() {\n    return {\n      block,\n      inline\n    };\n  }\n\n  /**\n   * Static Lex Method\n   */\n  static lex(src, options) {\n    const lexer = new Lexer(options);\n    return lexer.lex(src);\n  }\n\n  /**\n   * Static Lex Inline Method\n   */\n  static lexInline(src, options) {\n    const lexer = new Lexer(options);\n    return lexer.inlineTokens(src);\n  }\n\n  /**\n   * Preprocessing\n   */\n  lex(src) {\n    src = src\n      .replace(/\\r\\n|\\r/g, '\\n')\n      .replace(/\\t/g, '    ');\n\n    this.blockTokens(src, this.tokens);\n\n    let next;\n    while (next = this.inlineQueue.shift()) {\n      this.inlineTokens(next.src, next.tokens);\n    }\n\n    return this.tokens;\n  }\n\n  /**\n   * Lexing\n   */\n  blockTokens(src, tokens = []) {\n    if (this.options.pedantic) {\n      src = src.replace(/^ +$/gm, '');\n    }\n    let token, lastToken, cutSrc, lastParagraphClipped;\n\n    while (src) {\n      if (this.options.extensions\n        && this.options.extensions.block\n        && this.options.extensions.block.some((extTokenizer) => {\n          if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n            src = src.substring(token.raw.length);\n            tokens.push(token);\n            return true;\n          }\n          return false;\n        })) {\n        continue;\n      }\n\n      // newline\n      if (token = this.tokenizer.space(src)) {\n        src = src.substring(token.raw.length);\n        if (token.raw.length === 1 && tokens.length > 0) {\n          // if there's a single \\n as a spacer, it's terminating the last line,\n          // so move it there so that we don't get unecessary paragraph tags\n          tokens[tokens.length - 1].raw += '\\n';\n        } else {\n          tokens.push(token);\n        }\n        continue;\n      }\n\n      // code\n      if (token = this.tokenizer.code(src)) {\n        src = src.substring(token.raw.length);\n        lastToken = tokens[tokens.length - 1];\n        // An indented code block cannot interrupt a paragraph.\n        if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {\n          lastToken.raw += '\\n' + token.raw;\n          lastToken.text += '\\n' + token.text;\n          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n        } else {\n          tokens.push(token);\n        }\n        continue;\n      }\n\n      // fences\n      if (token = this.tokenizer.fences(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // heading\n      if (token = this.tokenizer.heading(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // hr\n      if (token = this.tokenizer.hr(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // blockquote\n      if (token = this.tokenizer.blockquote(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // list\n      if (token = this.tokenizer.list(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // html\n      if (token = this.tokenizer.html(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // def\n      if (token = this.tokenizer.def(src)) {\n        src = src.substring(token.raw.length);\n        lastToken = tokens[tokens.length - 1];\n        if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {\n          lastToken.raw += '\\n' + token.raw;\n          lastToken.text += '\\n' + token.raw;\n          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n        } else if (!this.tokens.links[token.tag]) {\n          this.tokens.links[token.tag] = {\n            href: token.href,\n            title: token.title\n          };\n        }\n        continue;\n      }\n\n      // table (gfm)\n      if (token = this.tokenizer.table(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // lheading\n      if (token = this.tokenizer.lheading(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // top-level paragraph\n      // prevent paragraph consuming extensions by clipping 'src' to extension start\n      cutSrc = src;\n      if (this.options.extensions && this.options.extensions.startBlock) {\n        let startIndex = Infinity;\n        const tempSrc = src.slice(1);\n        let tempStart;\n        this.options.extensions.startBlock.forEach(function(getStartIndex) {\n          tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n          if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }\n        });\n        if (startIndex < Infinity && startIndex >= 0) {\n          cutSrc = src.substring(0, startIndex + 1);\n        }\n      }\n      if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {\n        lastToken = tokens[tokens.length - 1];\n        if (lastParagraphClipped && lastToken.type === 'paragraph') {\n          lastToken.raw += '\\n' + token.raw;\n          lastToken.text += '\\n' + token.text;\n          this.inlineQueue.pop();\n          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n        } else {\n          tokens.push(token);\n        }\n        lastParagraphClipped = (cutSrc.length !== src.length);\n        src = src.substring(token.raw.length);\n        continue;\n      }\n\n      // text\n      if (token = this.tokenizer.text(src)) {\n        src = src.substring(token.raw.length);\n        lastToken = tokens[tokens.length - 1];\n        if (lastToken && lastToken.type === 'text') {\n          lastToken.raw += '\\n' + token.raw;\n          lastToken.text += '\\n' + token.text;\n          this.inlineQueue.pop();\n          this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n        } else {\n          tokens.push(token);\n        }\n        continue;\n      }\n\n      if (src) {\n        const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n        if (this.options.silent) {\n          console.error(errMsg);\n          break;\n        } else {\n          throw new Error(errMsg);\n        }\n      }\n    }\n\n    this.state.top = true;\n    return tokens;\n  }\n\n  inline(src, tokens) {\n    this.inlineQueue.push({ src, tokens });\n  }\n\n  /**\n   * Lexing/Compiling\n   */\n  inlineTokens(src, tokens = []) {\n    let token, lastToken, cutSrc;\n\n    // String with links masked to avoid interference with em and strong\n    let maskedSrc = src;\n    let match;\n    let keepPrevChar, prevChar;\n\n    // Mask out reflinks\n    if (this.tokens.links) {\n      const links = Object.keys(this.tokens.links);\n      if (links.length > 0) {\n        while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {\n          if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {\n            maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);\n          }\n        }\n      }\n    }\n    // Mask out other blocks\n    while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {\n      maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);\n    }\n\n    // Mask out escaped em & strong delimiters\n    while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {\n      maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);\n    }\n\n    while (src) {\n      if (!keepPrevChar) {\n        prevChar = '';\n      }\n      keepPrevChar = false;\n\n      // extensions\n      if (this.options.extensions\n        && this.options.extensions.inline\n        && this.options.extensions.inline.some((extTokenizer) => {\n          if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n            src = src.substring(token.raw.length);\n            tokens.push(token);\n            return true;\n          }\n          return false;\n        })) {\n        continue;\n      }\n\n      // escape\n      if (token = this.tokenizer.escape(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // tag\n      if (token = this.tokenizer.tag(src)) {\n        src = src.substring(token.raw.length);\n        lastToken = tokens[tokens.length - 1];\n        if (lastToken && token.type === 'text' && lastToken.type === 'text') {\n          lastToken.raw += token.raw;\n          lastToken.text += token.text;\n        } else {\n          tokens.push(token);\n        }\n        continue;\n      }\n\n      // link\n      if (token = this.tokenizer.link(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // reflink, nolink\n      if (token = this.tokenizer.reflink(src, this.tokens.links)) {\n        src = src.substring(token.raw.length);\n        lastToken = tokens[tokens.length - 1];\n        if (lastToken && token.type === 'text' && lastToken.type === 'text') {\n          lastToken.raw += token.raw;\n          lastToken.text += token.text;\n        } else {\n          tokens.push(token);\n        }\n        continue;\n      }\n\n      // em & strong\n      if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // code\n      if (token = this.tokenizer.codespan(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // br\n      if (token = this.tokenizer.br(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // del (gfm)\n      if (token = this.tokenizer.del(src)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // autolink\n      if (token = this.tokenizer.autolink(src, mangle)) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // url (gfm)\n      if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {\n        src = src.substring(token.raw.length);\n        tokens.push(token);\n        continue;\n      }\n\n      // text\n      // prevent inlineText consuming extensions by clipping 'src' to extension start\n      cutSrc = src;\n      if (this.options.extensions && this.options.extensions.startInline) {\n        let startIndex = Infinity;\n        const tempSrc = src.slice(1);\n        let tempStart;\n        this.options.extensions.startInline.forEach(function(getStartIndex) {\n          tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n          if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }\n        });\n        if (startIndex < Infinity && startIndex >= 0) {\n          cutSrc = src.substring(0, startIndex + 1);\n        }\n      }\n      if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {\n        src = src.substring(token.raw.length);\n        if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started\n          prevChar = token.raw.slice(-1);\n        }\n        keepPrevChar = true;\n        lastToken = tokens[tokens.length - 1];\n        if (lastToken && lastToken.type === 'text') {\n          lastToken.raw += token.raw;\n          lastToken.text += token.text;\n        } else {\n          tokens.push(token);\n        }\n        continue;\n      }\n\n      if (src) {\n        const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n        if (this.options.silent) {\n          console.error(errMsg);\n          break;\n        } else {\n          throw new Error(errMsg);\n        }\n      }\n    }\n\n    return tokens;\n  }\n}\n\n/**\n * Renderer\n */\nclass Renderer {\n  constructor(options) {\n    this.options = options || defaults;\n  }\n\n  code(code, infostring, escaped) {\n    const lang = (infostring || '').match(/\\S*/)[0];\n    if (this.options.highlight) {\n      const out = this.options.highlight(code, lang);\n      if (out != null && out !== code) {\n        escaped = true;\n        code = out;\n      }\n    }\n\n    code = code.replace(/\\n$/, '') + '\\n';\n\n    if (!lang) {\n      return '<pre><code>'\n        + (escaped ? code : escape(code, true))\n        + '</code></pre>\\n';\n    }\n\n    return '<pre><code class=\"'\n      + this.options.langPrefix\n      + escape(lang, true)\n      + '\">'\n      + (escaped ? code : escape(code, true))\n      + '</code></pre>\\n';\n  }\n\n  blockquote(quote) {\n    return '<blockquote>\\n' + quote + '</blockquote>\\n';\n  }\n\n  html(html) {\n    return html;\n  }\n\n  heading(text, level, raw, slugger) {\n    if (this.options.headerIds) {\n      return '<h'\n        + level\n        + ' id=\"'\n        + this.options.headerPrefix\n        + slugger.slug(raw)\n        + '\">'\n        + text\n        + '</h'\n        + level\n        + '>\\n';\n    }\n    // ignore IDs\n    return '<h' + level + '>' + text + '</h' + level + '>\\n';\n  }\n\n  hr() {\n    return this.options.xhtml ? '<hr/>\\n' : '<hr>\\n';\n  }\n\n  list(body, ordered, start) {\n    const type = ordered ? 'ol' : 'ul',\n      startatt = (ordered && start !== 1) ? (' start=\"' + start + '\"') : '';\n    return '<' + type + startatt + '>\\n' + body + '</' + type + '>\\n';\n  }\n\n  listitem(text) {\n    return '<li>' + text + '</li>\\n';\n  }\n\n  checkbox(checked) {\n    return '<input '\n      + (checked ? 'checked=\"\" ' : '')\n      + 'disabled=\"\" type=\"checkbox\"'\n      + (this.options.xhtml ? ' /' : '')\n      + '> ';\n  }\n\n  paragraph(text) {\n    return '<p>' + text + '</p>\\n';\n  }\n\n  table(header, body) {\n    if (body) body = '<tbody>' + body + '</tbody>';\n\n    return '<table>\\n'\n      + '<thead>\\n'\n      + header\n      + '</thead>\\n'\n      + body\n      + '</table>\\n';\n  }\n\n  tablerow(content) {\n    return '<tr>\\n' + content + '</tr>\\n';\n  }\n\n  tablecell(content, flags) {\n    const type = flags.header ? 'th' : 'td';\n    const tag = flags.align\n      ? '<' + type + ' align=\"' + flags.align + '\">'\n      : '<' + type + '>';\n    return tag + content + '</' + type + '>\\n';\n  }\n\n  // span level renderer\n  strong(text) {\n    return '<strong>' + text + '</strong>';\n  }\n\n  em(text) {\n    return '<em>' + text + '</em>';\n  }\n\n  codespan(text) {\n    return '<code>' + text + '</code>';\n  }\n\n  br() {\n    return this.options.xhtml ? '<br/>' : '<br>';\n  }\n\n  del(text) {\n    return '<del>' + text + '</del>';\n  }\n\n  link(href, title, text) {\n    href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);\n    if (href === null) {\n      return text;\n    }\n    let out = '<a href=\"' + escape(href) + '\"';\n    if (title) {\n      out += ' title=\"' + title + '\"';\n    }\n    out += '>' + text + '</a>';\n    return out;\n  }\n\n  image(href, title, text) {\n    href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);\n    if (href === null) {\n      return text;\n    }\n\n    let out = '<img src=\"' + href + '\" alt=\"' + text + '\"';\n    if (title) {\n      out += ' title=\"' + title + '\"';\n    }\n    out += this.options.xhtml ? '/>' : '>';\n    return out;\n  }\n\n  text(text) {\n    return text;\n  }\n}\n\n/**\n * TextRenderer\n * returns only the textual part of the token\n */\nclass TextRenderer {\n  // no need for block level renderers\n  strong(text) {\n    return text;\n  }\n\n  em(text) {\n    return text;\n  }\n\n  codespan(text) {\n    return text;\n  }\n\n  del(text) {\n    return text;\n  }\n\n  html(text) {\n    return text;\n  }\n\n  text(text) {\n    return text;\n  }\n\n  link(href, title, text) {\n    return '' + text;\n  }\n\n  image(href, title, text) {\n    return '' + text;\n  }\n\n  br() {\n    return '';\n  }\n}\n\n/**\n * Slugger generates header id\n */\nclass Slugger {\n  constructor() {\n    this.seen = {};\n  }\n\n  serialize(value) {\n    return value\n      .toLowerCase()\n      .trim()\n      // remove html tags\n      .replace(/<[!\\/a-z].*?>/ig, '')\n      // remove unwanted chars\n      .replace(/[\\u2000-\\u206F\\u2E00-\\u2E7F\\\\'!\"#$%&()*+,./:;<=>?@[\\]^`{|}~]/g, '')\n      .replace(/\\s/g, '-');\n  }\n\n  /**\n   * Finds the next safe (unique) slug to use\n   */\n  getNextSafeSlug(originalSlug, isDryRun) {\n    let slug = originalSlug;\n    let occurenceAccumulator = 0;\n    if (this.seen.hasOwnProperty(slug)) {\n      occurenceAccumulator = this.seen[originalSlug];\n      do {\n        occurenceAccumulator++;\n        slug = originalSlug + '-' + occurenceAccumulator;\n      } while (this.seen.hasOwnProperty(slug));\n    }\n    if (!isDryRun) {\n      this.seen[originalSlug] = occurenceAccumulator;\n      this.seen[slug] = 0;\n    }\n    return slug;\n  }\n\n  /**\n   * Convert string to unique id\n   * @param {object} options\n   * @param {boolean} options.dryrun Generates the next unique slug without updating the internal accumulator.\n   */\n  slug(value, options = {}) {\n    const slug = this.serialize(value);\n    return this.getNextSafeSlug(slug, options.dryrun);\n  }\n}\n\n/**\n * Parsing & Compiling\n */\nclass Parser {\n  constructor(options) {\n    this.options = options || defaults;\n    this.options.renderer = this.options.renderer || new Renderer();\n    this.renderer = this.options.renderer;\n    this.renderer.options = this.options;\n    this.textRenderer = new TextRenderer();\n    this.slugger = new Slugger();\n  }\n\n  /**\n   * Static Parse Method\n   */\n  static parse(tokens, options) {\n    const parser = new Parser(options);\n    return parser.parse(tokens);\n  }\n\n  /**\n   * Static Parse Inline Method\n   */\n  static parseInline(tokens, options) {\n    const parser = new Parser(options);\n    return parser.parseInline(tokens);\n  }\n\n  /**\n   * Parse Loop\n   */\n  parse(tokens, top = true) {\n    let out = '',\n      i,\n      j,\n      k,\n      l2,\n      l3,\n      row,\n      cell,\n      header,\n      body,\n      token,\n      ordered,\n      start,\n      loose,\n      itemBody,\n      item,\n      checked,\n      task,\n      checkbox,\n      ret;\n\n    const l = tokens.length;\n    for (i = 0; i < l; i++) {\n      token = tokens[i];\n\n      // Run any renderer extensions\n      if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {\n        ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);\n        if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {\n          out += ret || '';\n          continue;\n        }\n      }\n\n      switch (token.type) {\n        case 'space': {\n          continue;\n        }\n        case 'hr': {\n          out += this.renderer.hr();\n          continue;\n        }\n        case 'heading': {\n          out += this.renderer.heading(\n            this.parseInline(token.tokens),\n            token.depth,\n            unescape(this.parseInline(token.tokens, this.textRenderer)),\n            this.slugger);\n          continue;\n        }\n        case 'code': {\n          out += this.renderer.code(token.text,\n            token.lang,\n            token.escaped);\n          continue;\n        }\n        case 'table': {\n          header = '';\n\n          // header\n          cell = '';\n          l2 = token.header.length;\n          for (j = 0; j < l2; j++) {\n            cell += this.renderer.tablecell(\n              this.parseInline(token.header[j].tokens),\n              { header: true, align: token.align[j] }\n            );\n          }\n          header += this.renderer.tablerow(cell);\n\n          body = '';\n          l2 = token.rows.length;\n          for (j = 0; j < l2; j++) {\n            row = token.rows[j];\n\n            cell = '';\n            l3 = row.length;\n            for (k = 0; k < l3; k++) {\n              cell += this.renderer.tablecell(\n                this.parseInline(row[k].tokens),\n                { header: false, align: token.align[k] }\n              );\n            }\n\n            body += this.renderer.tablerow(cell);\n          }\n          out += this.renderer.table(header, body);\n          continue;\n        }\n        case 'blockquote': {\n          body = this.parse(token.tokens);\n          out += this.renderer.blockquote(body);\n          continue;\n        }\n        case 'list': {\n          ordered = token.ordered;\n          start = token.start;\n          loose = token.loose;\n          l2 = token.items.length;\n\n          body = '';\n          for (j = 0; j < l2; j++) {\n            item = token.items[j];\n            checked = item.checked;\n            task = item.task;\n\n            itemBody = '';\n            if (item.task) {\n              checkbox = this.renderer.checkbox(checked);\n              if (loose) {\n                if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {\n                  item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;\n                  if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {\n                    item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;\n                  }\n                } else {\n                  item.tokens.unshift({\n                    type: 'text',\n                    text: checkbox\n                  });\n                }\n              } else {\n                itemBody += checkbox;\n              }\n            }\n\n            itemBody += this.parse(item.tokens, loose);\n            body += this.renderer.listitem(itemBody, task, checked);\n          }\n\n          out += this.renderer.list(body, ordered, start);\n          continue;\n        }\n        case 'html': {\n          // TODO parse inline content if parameter markdown=1\n          out += this.renderer.html(token.text);\n          continue;\n        }\n        case 'paragraph': {\n          out += this.renderer.paragraph(this.parseInline(token.tokens));\n          continue;\n        }\n        case 'text': {\n          body = token.tokens ? this.parseInline(token.tokens) : token.text;\n          while (i + 1 < l && tokens[i + 1].type === 'text') {\n            token = tokens[++i];\n            body += '\\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);\n          }\n          out += top ? this.renderer.paragraph(body) : body;\n          continue;\n        }\n\n        default: {\n          const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n          if (this.options.silent) {\n            console.error(errMsg);\n            return;\n          } else {\n            throw new Error(errMsg);\n          }\n        }\n      }\n    }\n\n    return out;\n  }\n\n  /**\n   * Parse Inline Tokens\n   */\n  parseInline(tokens, renderer) {\n    renderer = renderer || this.renderer;\n    let out = '',\n      i,\n      token,\n      ret;\n\n    const l = tokens.length;\n    for (i = 0; i < l; i++) {\n      token = tokens[i];\n\n      // Run any renderer extensions\n      if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {\n        ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);\n        if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {\n          out += ret || '';\n          continue;\n        }\n      }\n\n      switch (token.type) {\n        case 'escape': {\n          out += renderer.text(token.text);\n          break;\n        }\n        case 'html': {\n          out += renderer.html(token.text);\n          break;\n        }\n        case 'link': {\n          out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));\n          break;\n        }\n        case 'image': {\n          out += renderer.image(token.href, token.title, token.text);\n          break;\n        }\n        case 'strong': {\n          out += renderer.strong(this.parseInline(token.tokens, renderer));\n          break;\n        }\n        case 'em': {\n          out += renderer.em(this.parseInline(token.tokens, renderer));\n          break;\n        }\n        case 'codespan': {\n          out += renderer.codespan(token.text);\n          break;\n        }\n        case 'br': {\n          out += renderer.br();\n          break;\n        }\n        case 'del': {\n          out += renderer.del(this.parseInline(token.tokens, renderer));\n          break;\n        }\n        case 'text': {\n          out += renderer.text(token.text);\n          break;\n        }\n        default: {\n          const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n          if (this.options.silent) {\n            console.error(errMsg);\n            return;\n          } else {\n            throw new Error(errMsg);\n          }\n        }\n      }\n    }\n    return out;\n  }\n}\n\n/**\n * Marked\n */\nfunction marked(src, opt, callback) {\n  // throw error in case of non string input\n  if (typeof src === 'undefined' || src === null) {\n    throw new Error('marked(): input parameter is undefined or null');\n  }\n  if (typeof src !== 'string') {\n    throw new Error('marked(): input parameter is of type '\n      + Object.prototype.toString.call(src) + ', string expected');\n  }\n\n  if (typeof opt === 'function') {\n    callback = opt;\n    opt = null;\n  }\n\n  opt = merge({}, marked.defaults, opt || {});\n  checkSanitizeDeprecation(opt);\n\n  if (callback) {\n    const highlight = opt.highlight;\n    let tokens;\n\n    try {\n      tokens = Lexer.lex(src, opt);\n    } catch (e) {\n      return callback(e);\n    }\n\n    const done = function(err) {\n      let out;\n\n      if (!err) {\n        try {\n          if (opt.walkTokens) {\n            marked.walkTokens(tokens, opt.walkTokens);\n          }\n          out = Parser.parse(tokens, opt);\n        } catch (e) {\n          err = e;\n        }\n      }\n\n      opt.highlight = highlight;\n\n      return err\n        ? callback(err)\n        : callback(null, out);\n    };\n\n    if (!highlight || highlight.length < 3) {\n      return done();\n    }\n\n    delete opt.highlight;\n\n    if (!tokens.length) return done();\n\n    let pending = 0;\n    marked.walkTokens(tokens, function(token) {\n      if (token.type === 'code') {\n        pending++;\n        setTimeout(() => {\n          highlight(token.text, token.lang, function(err, code) {\n            if (err) {\n              return done(err);\n            }\n            if (code != null && code !== token.text) {\n              token.text = code;\n              token.escaped = true;\n            }\n\n            pending--;\n            if (pending === 0) {\n              done();\n            }\n          });\n        }, 0);\n      }\n    });\n\n    if (pending === 0) {\n      done();\n    }\n\n    return;\n  }\n\n  try {\n    const tokens = Lexer.lex(src, opt);\n    if (opt.walkTokens) {\n      marked.walkTokens(tokens, opt.walkTokens);\n    }\n    return Parser.parse(tokens, opt);\n  } catch (e) {\n    e.message += '\\nPlease report this to https://github.com/markedjs/marked.';\n    if (opt.silent) {\n      return '<p>An error occurred:</p><pre>'\n        + escape(e.message + '', true)\n        + '</pre>';\n    }\n    throw e;\n  }\n}\n\n/**\n * Options\n */\n\nmarked.options =\nmarked.setOptions = function(opt) {\n  merge(marked.defaults, opt);\n  changeDefaults(marked.defaults);\n  return marked;\n};\n\nmarked.getDefaults = getDefaults;\n\nmarked.defaults = defaults;\n\n/**\n * Use Extension\n */\n\nmarked.use = function(...args) {\n  const opts = merge({}, ...args);\n  const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} };\n  let hasExtensions;\n\n  args.forEach((pack) => {\n    // ==-- Parse \"addon\" extensions --== //\n    if (pack.extensions) {\n      hasExtensions = true;\n      pack.extensions.forEach((ext) => {\n        if (!ext.name) {\n          throw new Error('extension name required');\n        }\n        if (ext.renderer) { // Renderer extensions\n          const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null;\n          if (prevRenderer) {\n            // Replace extension with func to run new extension but fall back if false\n            extensions.renderers[ext.name] = function(...args) {\n              let ret = ext.renderer.apply(this, args);\n              if (ret === false) {\n                ret = prevRenderer.apply(this, args);\n              }\n              return ret;\n            };\n          } else {\n            extensions.renderers[ext.name] = ext.renderer;\n          }\n        }\n        if (ext.tokenizer) { // Tokenizer Extensions\n          if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {\n            throw new Error(\"extension level must be 'block' or 'inline'\");\n          }\n          if (extensions[ext.level]) {\n            extensions[ext.level].unshift(ext.tokenizer);\n          } else {\n            extensions[ext.level] = [ext.tokenizer];\n          }\n          if (ext.start) { // Function to check for start of token\n            if (ext.level === 'block') {\n              if (extensions.startBlock) {\n                extensions.startBlock.push(ext.start);\n              } else {\n                extensions.startBlock = [ext.start];\n              }\n            } else if (ext.level === 'inline') {\n              if (extensions.startInline) {\n                extensions.startInline.push(ext.start);\n              } else {\n                extensions.startInline = [ext.start];\n              }\n            }\n          }\n        }\n        if (ext.childTokens) { // Child tokens to be visited by walkTokens\n          extensions.childTokens[ext.name] = ext.childTokens;\n        }\n      });\n    }\n\n    // ==-- Parse \"overwrite\" extensions --== //\n    if (pack.renderer) {\n      const renderer = marked.defaults.renderer || new Renderer();\n      for (const prop in pack.renderer) {\n        const prevRenderer = renderer[prop];\n        // Replace renderer with func to run extension, but fall back if false\n        renderer[prop] = (...args) => {\n          let ret = pack.renderer[prop].apply(renderer, args);\n          if (ret === false) {\n            ret = prevRenderer.apply(renderer, args);\n          }\n          return ret;\n        };\n      }\n      opts.renderer = renderer;\n    }\n    if (pack.tokenizer) {\n      const tokenizer = marked.defaults.tokenizer || new Tokenizer();\n      for (const prop in pack.tokenizer) {\n        const prevTokenizer = tokenizer[prop];\n        // Replace tokenizer with func to run extension, but fall back if false\n        tokenizer[prop] = (...args) => {\n          let ret = pack.tokenizer[prop].apply(tokenizer, args);\n          if (ret === false) {\n            ret = prevTokenizer.apply(tokenizer, args);\n          }\n          return ret;\n        };\n      }\n      opts.tokenizer = tokenizer;\n    }\n\n    // ==-- Parse WalkTokens extensions --== //\n    if (pack.walkTokens) {\n      const walkTokens = marked.defaults.walkTokens;\n      opts.walkTokens = function(token) {\n        pack.walkTokens.call(this, token);\n        if (walkTokens) {\n          walkTokens.call(this, token);\n        }\n      };\n    }\n\n    if (hasExtensions) {\n      opts.extensions = extensions;\n    }\n\n    marked.setOptions(opts);\n  });\n};\n\n/**\n * Run callback for every token\n */\n\nmarked.walkTokens = function(tokens, callback) {\n  for (const token of tokens) {\n    callback.call(marked, token);\n    switch (token.type) {\n      case 'table': {\n        for (const cell of token.header) {\n          marked.walkTokens(cell.tokens, callback);\n        }\n        for (const row of token.rows) {\n          for (const cell of row) {\n            marked.walkTokens(cell.tokens, callback);\n          }\n        }\n        break;\n      }\n      case 'list': {\n        marked.walkTokens(token.items, callback);\n        break;\n      }\n      default: {\n        if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions\n          marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) {\n            marked.walkTokens(token[childTokens], callback);\n          });\n        } else if (token.tokens) {\n          marked.walkTokens(token.tokens, callback);\n        }\n      }\n    }\n  }\n};\n\n/**\n * Parse Inline\n */\nmarked.parseInline = function(src, opt) {\n  // throw error in case of non string input\n  if (typeof src === 'undefined' || src === null) {\n    throw new Error('marked.parseInline(): input parameter is undefined or null');\n  }\n  if (typeof src !== 'string') {\n    throw new Error('marked.parseInline(): input parameter is of type '\n      + Object.prototype.toString.call(src) + ', string expected');\n  }\n\n  opt = merge({}, marked.defaults, opt || {});\n  checkSanitizeDeprecation(opt);\n\n  try {\n    const tokens = Lexer.lexInline(src, opt);\n    if (opt.walkTokens) {\n      marked.walkTokens(tokens, opt.walkTokens);\n    }\n    return Parser.parseInline(tokens, opt);\n  } catch (e) {\n    e.message += '\\nPlease report this to https://github.com/markedjs/marked.';\n    if (opt.silent) {\n      return '<p>An error occurred:</p><pre>'\n        + escape(e.message + '', true)\n        + '</pre>';\n    }\n    throw e;\n  }\n};\n\n/**\n * Expose\n */\nmarked.Parser = Parser;\nmarked.parser = Parser.parse;\nmarked.Renderer = Renderer;\nmarked.TextRenderer = TextRenderer;\nmarked.Lexer = Lexer;\nmarked.lexer = Lexer.lex;\nmarked.Tokenizer = Tokenizer;\nmarked.Slugger = Slugger;\nmarked.parse = marked;\n\nconst options = marked.options;\nconst setOptions = marked.setOptions;\nconst use = marked.use;\nconst walkTokens = marked.walkTokens;\nconst parseInline = marked.parseInline;\nconst parse = marked;\nconst parser = Parser.parse;\nconst lexer = Lexer.lex;\n\nexport { Lexer, Parser, Renderer, Slugger, TextRenderer, Tokenizer, defaults, getDefaults, lexer, marked, options, parse, parseInline, parser, setOptions, use, walkTokens };\n", "function extend (destination) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i];\n    for (var key in source) {\n      if (source.hasOwnProperty(key)) destination[key] = source[key];\n    }\n  }\n  return destination\n}\n\nfunction repeat (character, count) {\n  return Array(count + 1).join(character)\n}\n\nfunction trimLeadingNewlines (string) {\n  return string.replace(/^\\n*/, '')\n}\n\nfunction trimTrailingNewlines (string) {\n  // avoid match-at-end regexp bottleneck, see #370\n  var indexEnd = string.length;\n  while (indexEnd > 0 && string[indexEnd - 1] === '\\n') indexEnd--;\n  return string.substring(0, indexEnd)\n}\n\nvar blockElements = [\n  'ADDRESS', 'ARTICLE', 'ASIDE', 'AUDIO', 'BLOCKQUOTE', 'BODY', 'CANVAS',\n  'CENTER', 'DD', 'DIR', 'DIV', 'DL', 'DT', 'FIELDSET', 'FIGCAPTION', 'FIGURE',\n  'FOOTER', 'FORM', 'FRAMESET', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEADER',\n  'HGROUP', 'HR', 'HTML', 'ISINDEX', 'LI', 'MAIN', 'MENU', 'NAV', 'NOFRAMES',\n  'NOSCRIPT', 'OL', 'OUTPUT', 'P', 'PRE', 'SECTION', 'TABLE', 'TBODY', 'TD',\n  'TFOOT', 'TH', 'THEAD', 'TR', 'UL'\n];\n\nfunction isBlock (node) {\n  return is(node, blockElements)\n}\n\nvar voidElements = [\n  'AREA', 'BASE', 'BR', 'COL', 'COMMAND', 'EMBED', 'HR', 'IMG', 'INPUT',\n  'KEYGEN', 'LINK', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR'\n];\n\nfunction isVoid (node) {\n  return is(node, voidElements)\n}\n\nfunction hasVoid (node) {\n  return has(node, voidElements)\n}\n\nvar meaningfulWhenBlankElements = [\n  'A', 'TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TH', 'TD', 'IFRAME', 'SCRIPT',\n  'AUDIO', 'VIDEO'\n];\n\nfunction isMeaningfulWhenBlank (node) {\n  return is(node, meaningfulWhenBlankElements)\n}\n\nfunction hasMeaningfulWhenBlank (node) {\n  return has(node, meaningfulWhenBlankElements)\n}\n\nfunction is (node, tagNames) {\n  return tagNames.indexOf(node.nodeName) >= 0\n}\n\nfunction has (node, tagNames) {\n  return (\n    node.getElementsByTagName &&\n    tagNames.some(function (tagName) {\n      return node.getElementsByTagName(tagName).length\n    })\n  )\n}\n\nvar rules = {};\n\nrules.paragraph = {\n  filter: 'p',\n\n  replacement: function (content) {\n    return '\\n\\n' + content + '\\n\\n'\n  }\n};\n\nrules.lineBreak = {\n  filter: 'br',\n\n  replacement: function (content, node, options) {\n    return options.br + '\\n'\n  }\n};\n\nrules.heading = {\n  filter: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],\n\n  replacement: function (content, node, options) {\n    var hLevel = Number(node.nodeName.charAt(1));\n\n    if (options.headingStyle === 'setext' && hLevel < 3) {\n      var underline = repeat((hLevel === 1 ? '=' : '-'), content.length);\n      return (\n        '\\n\\n' + content + '\\n' + underline + '\\n\\n'\n      )\n    } else {\n      return '\\n\\n' + repeat('#', hLevel) + ' ' + content + '\\n\\n'\n    }\n  }\n};\n\nrules.blockquote = {\n  filter: 'blockquote',\n\n  replacement: function (content) {\n    content = content.replace(/^\\n+|\\n+$/g, '');\n    content = content.replace(/^/gm, '> ');\n    return '\\n\\n' + content + '\\n\\n'\n  }\n};\n\nrules.list = {\n  filter: ['ul', 'ol'],\n\n  replacement: function (content, node) {\n    var parent = node.parentNode;\n    if (parent.nodeName === 'LI' && parent.lastElementChild === node) {\n      return '\\n' + content\n    } else {\n      return '\\n\\n' + content + '\\n\\n'\n    }\n  }\n};\n\nrules.listItem = {\n  filter: 'li',\n\n  replacement: function (content, node, options) {\n    content = content\n      .replace(/^\\n+/, '') // remove leading newlines\n      .replace(/\\n+$/, '\\n') // replace trailing newlines with just a single one\n      .replace(/\\n/gm, '\\n    '); // indent\n    var prefix = options.bulletListMarker + '   ';\n    var parent = node.parentNode;\n    if (parent.nodeName === 'OL') {\n      var start = parent.getAttribute('start');\n      var index = Array.prototype.indexOf.call(parent.children, node);\n      prefix = (start ? Number(start) + index : index + 1) + '.  ';\n    }\n    return (\n      prefix + content + (node.nextSibling && !/\\n$/.test(content) ? '\\n' : '')\n    )\n  }\n};\n\nrules.indentedCodeBlock = {\n  filter: function (node, options) {\n    return (\n      options.codeBlockStyle === 'indented' &&\n      node.nodeName === 'PRE' &&\n      node.firstChild &&\n      node.firstChild.nodeName === 'CODE'\n    )\n  },\n\n  replacement: function (content, node, options) {\n    return (\n      '\\n\\n    ' +\n      node.firstChild.textContent.replace(/\\n/g, '\\n    ') +\n      '\\n\\n'\n    )\n  }\n};\n\nrules.fencedCodeBlock = {\n  filter: function (node, options) {\n    return (\n      options.codeBlockStyle === 'fenced' &&\n      node.nodeName === 'PRE' &&\n      node.firstChild &&\n      node.firstChild.nodeName === 'CODE'\n    )\n  },\n\n  replacement: function (content, node, options) {\n    var className = node.firstChild.getAttribute('class') || '';\n    var language = (className.match(/language-(\\S+)/) || [null, ''])[1];\n    var code = node.firstChild.textContent;\n\n    var fenceChar = options.fence.charAt(0);\n    var fenceSize = 3;\n    var fenceInCodeRegex = new RegExp('^' + fenceChar + '{3,}', 'gm');\n\n    var match;\n    while ((match = fenceInCodeRegex.exec(code))) {\n      if (match[0].length >= fenceSize) {\n        fenceSize = match[0].length + 1;\n      }\n    }\n\n    var fence = repeat(fenceChar, fenceSize);\n\n    return (\n      '\\n\\n' + fence + language + '\\n' +\n      code.replace(/\\n$/, '') +\n      '\\n' + fence + '\\n\\n'\n    )\n  }\n};\n\nrules.horizontalRule = {\n  filter: 'hr',\n\n  replacement: function (content, node, options) {\n    return '\\n\\n' + options.hr + '\\n\\n'\n  }\n};\n\nrules.inlineLink = {\n  filter: function (node, options) {\n    return (\n      options.linkStyle === 'inlined' &&\n      node.nodeName === 'A' &&\n      node.getAttribute('href')\n    )\n  },\n\n  replacement: function (content, node) {\n    var href = node.getAttribute('href');\n    if (href) href = href.replace(/([()])/g, '\\\\$1');\n    var title = cleanAttribute(node.getAttribute('title'));\n    if (title) title = ' \"' + title.replace(/\"/g, '\\\\\"') + '\"';\n    return '[' + content + '](' + href + title + ')'\n  }\n};\n\nrules.referenceLink = {\n  filter: function (node, options) {\n    return (\n      options.linkStyle === 'referenced' &&\n      node.nodeName === 'A' &&\n      node.getAttribute('href')\n    )\n  },\n\n  replacement: function (content, node, options) {\n    var href = node.getAttribute('href');\n    var title = cleanAttribute(node.getAttribute('title'));\n    if (title) title = ' \"' + title + '\"';\n    var replacement;\n    var reference;\n\n    switch (options.linkReferenceStyle) {\n      case 'collapsed':\n        replacement = '[' + content + '][]';\n        reference = '[' + content + ']: ' + href + title;\n        break\n      case 'shortcut':\n        replacement = '[' + content + ']';\n        reference = '[' + content + ']: ' + href + title;\n        break\n      default:\n        var id = this.references.length + 1;\n        replacement = '[' + content + '][' + id + ']';\n        reference = '[' + id + ']: ' + href + title;\n    }\n\n    this.references.push(reference);\n    return replacement\n  },\n\n  references: [],\n\n  append: function (options) {\n    var references = '';\n    if (this.references.length) {\n      references = '\\n\\n' + this.references.join('\\n') + '\\n\\n';\n      this.references = []; // Reset references\n    }\n    return references\n  }\n};\n\nrules.emphasis = {\n  filter: ['em', 'i'],\n\n  replacement: function (content, node, options) {\n    if (!content.trim()) return ''\n    return options.emDelimiter + content + options.emDelimiter\n  }\n};\n\nrules.strong = {\n  filter: ['strong', 'b'],\n\n  replacement: function (content, node, options) {\n    if (!content.trim()) return ''\n    return options.strongDelimiter + content + options.strongDelimiter\n  }\n};\n\nrules.code = {\n  filter: function (node) {\n    var hasSiblings = node.previousSibling || node.nextSibling;\n    var isCodeBlock = node.parentNode.nodeName === 'PRE' && !hasSiblings;\n\n    return node.nodeName === 'CODE' && !isCodeBlock\n  },\n\n  replacement: function (content) {\n    if (!content) return ''\n    content = content.replace(/\\r?\\n|\\r/g, ' ');\n\n    var extraSpace = /^`|^ .*?[^ ].* $|`$/.test(content) ? ' ' : '';\n    var delimiter = '`';\n    var matches = content.match(/`+/gm) || [];\n    while (matches.indexOf(delimiter) !== -1) delimiter = delimiter + '`';\n\n    return delimiter + extraSpace + content + extraSpace + delimiter\n  }\n};\n\nrules.image = {\n  filter: 'img',\n\n  replacement: function (content, node) {\n    var alt = cleanAttribute(node.getAttribute('alt'));\n    var src = node.getAttribute('src') || '';\n    var title = cleanAttribute(node.getAttribute('title'));\n    var titlePart = title ? ' \"' + title + '\"' : '';\n    return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : ''\n  }\n};\n\nfunction cleanAttribute (attribute) {\n  return attribute ? attribute.replace(/(\\n+\\s*)+/g, '\\n') : ''\n}\n\n/**\n * Manages a collection of rules used to convert HTML to Markdown\n */\n\nfunction Rules (options) {\n  this.options = options;\n  this._keep = [];\n  this._remove = [];\n\n  this.blankRule = {\n    replacement: options.blankReplacement\n  };\n\n  this.keepReplacement = options.keepReplacement;\n\n  this.defaultRule = {\n    replacement: options.defaultReplacement\n  };\n\n  this.array = [];\n  for (var key in options.rules) this.array.push(options.rules[key]);\n}\n\nRules.prototype = {\n  add: function (key, rule) {\n    this.array.unshift(rule);\n  },\n\n  keep: function (filter) {\n    this._keep.unshift({\n      filter: filter,\n      replacement: this.keepReplacement\n    });\n  },\n\n  remove: function (filter) {\n    this._remove.unshift({\n      filter: filter,\n      replacement: function () {\n        return ''\n      }\n    });\n  },\n\n  forNode: function (node) {\n    if (node.isBlank) return this.blankRule\n    var rule;\n\n    if ((rule = findRule(this.array, node, this.options))) return rule\n    if ((rule = findRule(this._keep, node, this.options))) return rule\n    if ((rule = findRule(this._remove, node, this.options))) return rule\n\n    return this.defaultRule\n  },\n\n  forEach: function (fn) {\n    for (var i = 0; i < this.array.length; i++) fn(this.array[i], i);\n  }\n};\n\nfunction findRule (rules, node, options) {\n  for (var i = 0; i < rules.length; i++) {\n    var rule = rules[i];\n    if (filterValue(rule, node, options)) return rule\n  }\n  return void 0\n}\n\nfunction filterValue (rule, node, options) {\n  var filter = rule.filter;\n  if (typeof filter === 'string') {\n    if (filter === node.nodeName.toLowerCase()) return true\n  } else if (Array.isArray(filter)) {\n    if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true\n  } else if (typeof filter === 'function') {\n    if (filter.call(rule, node, options)) return true\n  } else {\n    throw new TypeError('`filter` needs to be a string, array, or function')\n  }\n}\n\n/**\n * The collapseWhitespace function is adapted from collapse-whitespace\n * by Luc Thevenard.\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2014 Luc Thevenard <lucthevenard@gmail.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n/**\n * collapseWhitespace(options) removes extraneous whitespace from an the given element.\n *\n * @param {Object} options\n */\nfunction collapseWhitespace (options) {\n  var element = options.element;\n  var isBlock = options.isBlock;\n  var isVoid = options.isVoid;\n  var isPre = options.isPre || function (node) {\n    return node.nodeName === 'PRE'\n  };\n\n  if (!element.firstChild || isPre(element)) return\n\n  var prevText = null;\n  var keepLeadingWs = false;\n\n  var prev = null;\n  var node = next(prev, element, isPre);\n\n  while (node !== element) {\n    if (node.nodeType === 3 || node.nodeType === 4) { // Node.TEXT_NODE or Node.CDATA_SECTION_NODE\n      var text = node.data.replace(/[ \\r\\n\\t]+/g, ' ');\n\n      if ((!prevText || / $/.test(prevText.data)) &&\n          !keepLeadingWs && text[0] === ' ') {\n        text = text.substr(1);\n      }\n\n      // `text` might be empty at this point.\n      if (!text) {\n        node = remove(node);\n        continue\n      }\n\n      node.data = text;\n\n      prevText = node;\n    } else if (node.nodeType === 1) { // Node.ELEMENT_NODE\n      if (isBlock(node) || node.nodeName === 'BR') {\n        if (prevText) {\n          prevText.data = prevText.data.replace(/ $/, '');\n        }\n\n        prevText = null;\n        keepLeadingWs = false;\n      } else if (isVoid(node) || isPre(node)) {\n        // Avoid trimming space around non-block, non-BR void elements and inline PRE.\n        prevText = null;\n        keepLeadingWs = true;\n      } else if (prevText) {\n        // Drop protection if set previously.\n        keepLeadingWs = false;\n      }\n    } else {\n      node = remove(node);\n      continue\n    }\n\n    var nextNode = next(prev, node, isPre);\n    prev = node;\n    node = nextNode;\n  }\n\n  if (prevText) {\n    prevText.data = prevText.data.replace(/ $/, '');\n    if (!prevText.data) {\n      remove(prevText);\n    }\n  }\n}\n\n/**\n * remove(node) removes the given node from the DOM and returns the\n * next node in the sequence.\n *\n * @param {Node} node\n * @return {Node} node\n */\nfunction remove (node) {\n  var next = node.nextSibling || node.parentNode;\n\n  node.parentNode.removeChild(node);\n\n  return next\n}\n\n/**\n * next(prev, current, isPre) returns the next node in the sequence, given the\n * current and previous nodes.\n *\n * @param {Node} prev\n * @param {Node} current\n * @param {Function} isPre\n * @return {Node}\n */\nfunction next (prev, current, isPre) {\n  if ((prev && prev.parentNode === current) || isPre(current)) {\n    return current.nextSibling || current.parentNode\n  }\n\n  return current.firstChild || current.nextSibling || current.parentNode\n}\n\n/*\n * Set up window for Node.js\n */\n\nvar root = (typeof window !== 'undefined' ? window : {});\n\n/*\n * Parsing HTML strings\n */\n\nfunction canParseHTMLNatively () {\n  var Parser = root.DOMParser;\n  var canParse = false;\n\n  // Adapted from https://gist.github.com/1129031\n  // Firefox/Opera/IE throw errors on unsupported types\n  try {\n    // WebKit returns null on unsupported types\n    if (new Parser().parseFromString('', 'text/html')) {\n      canParse = true;\n    }\n  } catch (e) {}\n\n  return canParse\n}\n\nfunction createHTMLParser () {\n  var Parser = function () {};\n\n  {\n    if (shouldUseActiveX()) {\n      Parser.prototype.parseFromString = function (string) {\n        var doc = new window.ActiveXObject('htmlfile');\n        doc.designMode = 'on'; // disable on-page scripts\n        doc.open();\n        doc.write(string);\n        doc.close();\n        return doc\n      };\n    } else {\n      Parser.prototype.parseFromString = function (string) {\n        var doc = document.implementation.createHTMLDocument('');\n        doc.open();\n        doc.write(string);\n        doc.close();\n        return doc\n      };\n    }\n  }\n  return Parser\n}\n\nfunction shouldUseActiveX () {\n  var useActiveX = false;\n  try {\n    document.implementation.createHTMLDocument('').open();\n  } catch (e) {\n    if (root.ActiveXObject) useActiveX = true;\n  }\n  return useActiveX\n}\n\nvar HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser();\n\nfunction RootNode (input, options) {\n  var root;\n  if (typeof input === 'string') {\n    var doc = htmlParser().parseFromString(\n      // DOM parsers arrange elements in the <head> and <body>.\n      // Wrapping in a custom element ensures elements are reliably arranged in\n      // a single element.\n      '<x-turndown id=\"turndown-root\">' + input + '</x-turndown>',\n      'text/html'\n    );\n    root = doc.getElementById('turndown-root');\n  } else {\n    root = input.cloneNode(true);\n  }\n  collapseWhitespace({\n    element: root,\n    isBlock: isBlock,\n    isVoid: isVoid,\n    isPre: options.preformattedCode ? isPreOrCode : null\n  });\n\n  return root\n}\n\nvar _htmlParser;\nfunction htmlParser () {\n  _htmlParser = _htmlParser || new HTMLParser();\n  return _htmlParser\n}\n\nfunction isPreOrCode (node) {\n  return node.nodeName === 'PRE' || node.nodeName === 'CODE'\n}\n\nfunction Node (node, options) {\n  node.isBlock = isBlock(node);\n  node.isCode = node.nodeName === 'CODE' || node.parentNode.isCode;\n  node.isBlank = isBlank(node);\n  node.flankingWhitespace = flankingWhitespace(node, options);\n  return node\n}\n\nfunction isBlank (node) {\n  return (\n    !isVoid(node) &&\n    !isMeaningfulWhenBlank(node) &&\n    /^\\s*$/i.test(node.textContent) &&\n    !hasVoid(node) &&\n    !hasMeaningfulWhenBlank(node)\n  )\n}\n\nfunction flankingWhitespace (node, options) {\n  if (node.isBlock || (options.preformattedCode && node.isCode)) {\n    return { leading: '', trailing: '' }\n  }\n\n  var edges = edgeWhitespace(node.textContent);\n\n  // abandon leading ASCII WS if left-flanked by ASCII WS\n  if (edges.leadingAscii && isFlankedByWhitespace('left', node, options)) {\n    edges.leading = edges.leadingNonAscii;\n  }\n\n  // abandon trailing ASCII WS if right-flanked by ASCII WS\n  if (edges.trailingAscii && isFlankedByWhitespace('right', node, options)) {\n    edges.trailing = edges.trailingNonAscii;\n  }\n\n  return { leading: edges.leading, trailing: edges.trailing }\n}\n\nfunction edgeWhitespace (string) {\n  var m = string.match(/^(([ \\t\\r\\n]*)(\\s*))(?:(?=\\S)[\\s\\S]*\\S)?((\\s*?)([ \\t\\r\\n]*))$/);\n  return {\n    leading: m[1], // whole string for whitespace-only strings\n    leadingAscii: m[2],\n    leadingNonAscii: m[3],\n    trailing: m[4], // empty for whitespace-only strings\n    trailingNonAscii: m[5],\n    trailingAscii: m[6]\n  }\n}\n\nfunction isFlankedByWhitespace (side, node, options) {\n  var sibling;\n  var regExp;\n  var isFlanked;\n\n  if (side === 'left') {\n    sibling = node.previousSibling;\n    regExp = / $/;\n  } else {\n    sibling = node.nextSibling;\n    regExp = /^ /;\n  }\n\n  if (sibling) {\n    if (sibling.nodeType === 3) {\n      isFlanked = regExp.test(sibling.nodeValue);\n    } else if (options.preformattedCode && sibling.nodeName === 'CODE') {\n      isFlanked = false;\n    } else if (sibling.nodeType === 1 && !isBlock(sibling)) {\n      isFlanked = regExp.test(sibling.textContent);\n    }\n  }\n  return isFlanked\n}\n\nvar reduce = Array.prototype.reduce;\nvar escapes = [\n  [/\\\\/g, '\\\\\\\\'],\n  [/\\*/g, '\\\\*'],\n  [/^-/g, '\\\\-'],\n  [/^\\+ /g, '\\\\+ '],\n  [/^(=+)/g, '\\\\$1'],\n  [/^(#{1,6}) /g, '\\\\$1 '],\n  [/`/g, '\\\\`'],\n  [/^~~~/g, '\\\\~~~'],\n  [/\\[/g, '\\\\['],\n  [/\\]/g, '\\\\]'],\n  [/^>/g, '\\\\>'],\n  [/_/g, '\\\\_'],\n  [/^(\\d+)\\. /g, '$1\\\\. ']\n];\n\nfunction TurndownService (options) {\n  if (!(this instanceof TurndownService)) return new TurndownService(options)\n\n  var defaults = {\n    rules: rules,\n    headingStyle: 'setext',\n    hr: '* * *',\n    bulletListMarker: '*',\n    codeBlockStyle: 'indented',\n    fence: '```',\n    emDelimiter: '_',\n    strongDelimiter: '**',\n    linkStyle: 'inlined',\n    linkReferenceStyle: 'full',\n    br: '  ',\n    preformattedCode: false,\n    blankReplacement: function (content, node) {\n      return node.isBlock ? '\\n\\n' : ''\n    },\n    keepReplacement: function (content, node) {\n      return node.isBlock ? '\\n\\n' + node.outerHTML + '\\n\\n' : node.outerHTML\n    },\n    defaultReplacement: function (content, node) {\n      return node.isBlock ? '\\n\\n' + content + '\\n\\n' : content\n    }\n  };\n  this.options = extend({}, defaults, options);\n  this.rules = new Rules(this.options);\n}\n\nTurndownService.prototype = {\n  /**\n   * The entry point for converting a string or DOM node to Markdown\n   * @public\n   * @param {String|HTMLElement} input The string or DOM node to convert\n   * @returns A Markdown representation of the input\n   * @type String\n   */\n\n  turndown: function (input) {\n    if (!canConvert(input)) {\n      throw new TypeError(\n        input + ' is not a string, or an element/document/fragment node.'\n      )\n    }\n\n    if (input === '') return ''\n\n    var output = process.call(this, new RootNode(input, this.options));\n    return postProcess.call(this, output)\n  },\n\n  /**\n   * Add one or more plugins\n   * @public\n   * @param {Function|Array} plugin The plugin or array of plugins to add\n   * @returns The Turndown instance for chaining\n   * @type Object\n   */\n\n  use: function (plugin) {\n    if (Array.isArray(plugin)) {\n      for (var i = 0; i < plugin.length; i++) this.use(plugin[i]);\n    } else if (typeof plugin === 'function') {\n      plugin(this);\n    } else {\n      throw new TypeError('plugin must be a Function or an Array of Functions')\n    }\n    return this\n  },\n\n  /**\n   * Adds a rule\n   * @public\n   * @param {String} key The unique key of the rule\n   * @param {Object} rule The rule\n   * @returns The Turndown instance for chaining\n   * @type Object\n   */\n\n  addRule: function (key, rule) {\n    this.rules.add(key, rule);\n    return this\n  },\n\n  /**\n   * Keep a node (as HTML) that matches the filter\n   * @public\n   * @param {String|Array|Function} filter The unique key of the rule\n   * @returns The Turndown instance for chaining\n   * @type Object\n   */\n\n  keep: function (filter) {\n    this.rules.keep(filter);\n    return this\n  },\n\n  /**\n   * Remove a node that matches the filter\n   * @public\n   * @param {String|Array|Function} filter The unique key of the rule\n   * @returns The Turndown instance for chaining\n   * @type Object\n   */\n\n  remove: function (filter) {\n    this.rules.remove(filter);\n    return this\n  },\n\n  /**\n   * Escapes Markdown syntax\n   * @public\n   * @param {String} string The string to escape\n   * @returns A string with Markdown syntax escaped\n   * @type String\n   */\n\n  escape: function (string) {\n    return escapes.reduce(function (accumulator, escape) {\n      return accumulator.replace(escape[0], escape[1])\n    }, string)\n  }\n};\n\n/**\n * Reduces a DOM node down to its Markdown string equivalent\n * @private\n * @param {HTMLElement} parentNode The node to convert\n * @returns A Markdown representation of the node\n * @type String\n */\n\nfunction process (parentNode) {\n  var self = this;\n  return reduce.call(parentNode.childNodes, function (output, node) {\n    node = new Node(node, self.options);\n\n    var replacement = '';\n    if (node.nodeType === 3) {\n      replacement = node.isCode ? node.nodeValue : self.escape(node.nodeValue);\n    } else if (node.nodeType === 1) {\n      replacement = replacementForNode.call(self, node);\n    }\n\n    return join(output, replacement)\n  }, '')\n}\n\n/**\n * Appends strings as each rule requires and trims the output\n * @private\n * @param {String} output The conversion output\n * @returns A trimmed version of the ouput\n * @type String\n */\n\nfunction postProcess (output) {\n  var self = this;\n  this.rules.forEach(function (rule) {\n    if (typeof rule.append === 'function') {\n      output = join(output, rule.append(self.options));\n    }\n  });\n\n  return output.replace(/^[\\t\\r\\n]+/, '').replace(/[\\t\\r\\n\\s]+$/, '')\n}\n\n/**\n * Converts an element node to its Markdown equivalent\n * @private\n * @param {HTMLElement} node The node to convert\n * @returns A Markdown representation of the node\n * @type String\n */\n\nfunction replacementForNode (node) {\n  var rule = this.rules.forNode(node);\n  var content = process.call(this, node);\n  var whitespace = node.flankingWhitespace;\n  if (whitespace.leading || whitespace.trailing) content = content.trim();\n  return (\n    whitespace.leading +\n    rule.replacement(content, node, this.options) +\n    whitespace.trailing\n  )\n}\n\n/**\n * Joins replacement to the current output with appropriate number of new lines\n * @private\n * @param {String} output The current conversion output\n * @param {String} replacement The string to append to the output\n * @returns Joined output\n * @type String\n */\n\nfunction join (output, replacement) {\n  var s1 = trimTrailingNewlines(output);\n  var s2 = trimLeadingNewlines(replacement);\n  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);\n  var separator = '\\n\\n'.substring(0, nls);\n\n  return s1 + separator + s2\n}\n\n/**\n * Determines whether an input can be converted\n * @private\n * @param {String|HTMLElement} input Describe this parameter\n * @returns Describe what it returns\n * @type String|Object|Array|Boolean|Number\n */\n\nfunction canConvert (input) {\n  return (\n    input != null && (\n      typeof input === 'string' ||\n      (input.nodeType && (\n        input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11\n      ))\n    )\n  )\n}\n\nexport default TurndownService;\n", "var highlightRegExp = /highlight-(?:text|source)-([a-z0-9]+)/;\n\nfunction highlightedCodeBlock (turndownService) {\n  turndownService.addRule('highlightedCodeBlock', {\n    filter: function (node) {\n      var firstChild = node.firstChild;\n      return (\n        node.nodeName === 'DIV' &&\n        highlightRegExp.test(node.className) &&\n        firstChild &&\n        firstChild.nodeName === 'PRE'\n      )\n    },\n    replacement: function (content, node, options) {\n      var className = node.className || '';\n      var language = (className.match(highlightRegExp) || [null, ''])[1];\n\n      return (\n        '\\n\\n' + options.fence + language + '\\n' +\n        node.firstChild.textContent +\n        '\\n' + options.fence + '\\n\\n'\n      )\n    }\n  });\n}\n\nfunction strikethrough (turndownService) {\n  turndownService.addRule('strikethrough', {\n    filter: ['del', 's', 'strike'],\n    replacement: function (content) {\n      return '~' + content + '~'\n    }\n  });\n}\n\nvar indexOf = Array.prototype.indexOf;\nvar every = Array.prototype.every;\nvar rules = {};\n\nrules.tableCell = {\n  filter: ['th', 'td'],\n  replacement: function (content, node) {\n    return cell(content, node)\n  }\n};\n\nrules.tableRow = {\n  filter: 'tr',\n  replacement: function (content, node) {\n    var borderCells = '';\n    var alignMap = { left: ':--', right: '--:', center: ':-:' };\n\n    if (isHeadingRow(node)) {\n      for (var i = 0; i < node.childNodes.length; i++) {\n        var border = '---';\n        var align = (\n          node.childNodes[i].getAttribute('align') || ''\n        ).toLowerCase();\n\n        if (align) border = alignMap[align] || border;\n\n        borderCells += cell(border, node.childNodes[i]);\n      }\n    }\n    return '\\n' + content + (borderCells ? '\\n' + borderCells : '')\n  }\n};\n\nrules.table = {\n  // Only convert tables with a heading row.\n  // Tables with no heading row are kept using `keep` (see below).\n  filter: function (node) {\n    return node.nodeName === 'TABLE' && isHeadingRow(node.rows[0])\n  },\n\n  replacement: function (content) {\n    // Ensure there are no blank lines\n    content = content.replace('\\n\\n', '\\n');\n    return '\\n\\n' + content + '\\n\\n'\n  }\n};\n\nrules.tableSection = {\n  filter: ['thead', 'tbody', 'tfoot'],\n  replacement: function (content) {\n    return content\n  }\n};\n\n// A tr is a heading row if:\n// - the parent is a THEAD\n// - or if its the first child of the TABLE or the first TBODY (possibly\n//   following a blank THEAD)\n// - and every cell is a TH\nfunction isHeadingRow (tr) {\n  var parentNode = tr.parentNode;\n  return (\n    parentNode.nodeName === 'THEAD' ||\n    (\n      parentNode.firstChild === tr &&\n      (parentNode.nodeName === 'TABLE' || isFirstTbody(parentNode)) &&\n      every.call(tr.childNodes, function (n) { return n.nodeName === 'TH' })\n    )\n  )\n}\n\nfunction isFirstTbody (element) {\n  var previousSibling = element.previousSibling;\n  return (\n    element.nodeName === 'TBODY' && (\n      !previousSibling ||\n      (\n        previousSibling.nodeName === 'THEAD' &&\n        /^\\s*$/i.test(previousSibling.textContent)\n      )\n    )\n  )\n}\n\nfunction cell (content, node) {\n  var index = indexOf.call(node.parentNode.childNodes, node);\n  var prefix = ' ';\n  if (index === 0) prefix = '| ';\n  return prefix + content + ' |'\n}\n\nfunction tables (turndownService) {\n  turndownService.keep(function (node) {\n    return node.nodeName === 'TABLE' && !isHeadingRow(node.rows[0])\n  });\n  for (var key in rules) turndownService.addRule(key, rules[key]);\n}\n\nfunction taskListItems (turndownService) {\n  turndownService.addRule('taskListItems', {\n    filter: function (node) {\n      return node.type === 'checkbox' && node.parentNode.nodeName === 'LI'\n    },\n    replacement: function (content, node) {\n      return (node.checked ? '[x]' : '[ ]') + ' '\n    }\n  });\n}\n\nfunction gfm (turndownService) {\n  turndownService.use([\n    highlightedCodeBlock,\n    strikethrough,\n    tables,\n    taskListItems\n  ]);\n}\n\nexport { gfm, highlightedCodeBlock, strikethrough, tables, taskListItems };\n", "import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { HtmlDataProcessor } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { marked } from 'marked';\nimport Turndown from 'turndown';\nimport { gfm } from 'turndown-plugin-gfm';\nimport { ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\n\n/**\n * This is a helper class used by the {@link module:markdown-gfm/markdown Markdown feature} to convert Markdown to HTML.\n */ class MarkdownToHtml {\n    _parser;\n    _options = {\n        gfm: true,\n        breaks: true,\n        tables: true,\n        xhtml: true,\n        headerIds: false\n    };\n    constructor(){\n        // Overrides.\n        marked.use({\n            tokenizer: {\n                // Disable the autolink rule in the lexer.\n                autolink: ()=>null,\n                url: ()=>null\n            },\n            renderer: {\n                checkbox (...args) {\n                    // Remove bogus space after <input type=\"checkbox\"> because it would be preserved\n                    // by DomConverter as it's next to an inline object.\n                    return Object.getPrototypeOf(this).checkbox.call(this, ...args).trimRight();\n                },\n                code (...args) {\n                    // Since marked v1.2.8, every <code> gets a trailing \"\\n\" whether it originally\n                    // ended with one or not (see https://github.com/markedjs/marked/issues/1884 to learn why).\n                    // This results in a redundant soft break in the model when loaded into the editor, which\n                    // is best prevented at this stage. See https://github.com/ckeditor/ckeditor5/issues/11124.\n                    return Object.getPrototypeOf(this).code.call(this, ...args).replace('\\n</code>', '</code>');\n                }\n            }\n        });\n        this._parser = marked;\n    }\n    parse(markdown) {\n        return this._parser.parse(markdown, this._options);\n    }\n}\n\nconst autolinkRegex = /* #__PURE__ */ new RegExp(// Prefix.\n/\\b(?:(?:https?|ftp):\\/\\/|www\\.)/.source + // Domain name.\n/(?![-_])(?:[-_a-z0-9\\u00a1-\\uffff]{1,63}\\.)+(?:[a-z\\u00a1-\\uffff]{2,63})/.source + // The rest.\n/(?:[^\\s<>]*)/.source, 'gi');\nclass UpdatedTurndown extends Turndown {\n    escape(string) {\n        const originalEscape = super.escape;\n        function escape(string) {\n            string = originalEscape(string);\n            // Escape \"<\".\n            string = string.replace(/</g, '\\\\<');\n            return string;\n        }\n        // Urls should not be escaped. Our strategy is using a regex to find them and escape everything\n        // which is out of the matches parts.\n        let escaped = '';\n        let lastLinkEnd = 0;\n        for (const match of this._matchAutolink(string)){\n            const index = match.index;\n            // Append the substring between the last match and the current one (if anything).\n            if (index > lastLinkEnd) {\n                escaped += escape(string.substring(lastLinkEnd, index));\n            }\n            const matchedURL = match[0];\n            escaped += matchedURL;\n            lastLinkEnd = index + matchedURL.length;\n        }\n        // Add text after the last link or at the string start if no matches.\n        if (lastLinkEnd < string.length) {\n            escaped += escape(string.substring(lastLinkEnd, string.length));\n        }\n        return escaped;\n    }\n    /**\n\t * Trimming end of link.\n\t * https://github.github.com/gfm/#autolinks-extension-\n\t */ *_matchAutolink(string) {\n        for (const match of string.matchAll(autolinkRegex)){\n            const matched = match[0];\n            const length = this._autolinkFindEnd(matched);\n            yield Object.assign([\n                matched.substring(0, length)\n            ], {\n                index: match.index\n            });\n        // We could adjust regex.lastIndex but it's not needed because what we skipped is for sure not a valid URL.\n        }\n    }\n    /**\n\t * Returns the new length of the link (after it would trim trailing characters).\n\t */ _autolinkFindEnd(string) {\n        let length = string.length;\n        while(length > 0){\n            const char = string[length - 1];\n            if ('?!.,:*_~\\'\"'.includes(char)) {\n                length--;\n            } else if (char == ')') {\n                let openBrackets = 0;\n                for(let i = 0; i < length; i++){\n                    if (string[i] == '(') {\n                        openBrackets++;\n                    } else if (string[i] == ')') {\n                        openBrackets--;\n                    }\n                }\n                // If there is fewer opening brackets then closing ones we should remove a closing bracket.\n                if (openBrackets < 0) {\n                    length--;\n                } else {\n                    break;\n                }\n            } else {\n                break;\n            }\n        }\n        return length;\n    }\n}\n/**\n * This is a helper class used by the {@link module:markdown-gfm/markdown Markdown feature} to convert HTML to Markdown.\n */ class HtmlToMarkdown {\n    _parser;\n    constructor(){\n        this._parser = this._createParser();\n    }\n    parse(html) {\n        return this._parser.turndown(html);\n    }\n    keep(elements) {\n        this._parser.keep(elements);\n    }\n    _createParser() {\n        const parser = new UpdatedTurndown({\n            codeBlockStyle: 'fenced',\n            hr: '---',\n            headingStyle: 'atx'\n        });\n        parser.use([\n            gfm,\n            this._todoList\n        ]);\n        return parser;\n    }\n    // This is a copy of the original taskListItems rule from turndown-plugin-gfm, with minor changes.\n    _todoList(turndown) {\n        turndown.addRule('taskListItems', {\n            filter (node) {\n                return node.type === 'checkbox' && // Changes here as CKEditor outputs a deeper structure.\n                (node.parentNode.nodeName === 'LI' || node.parentNode.parentNode.nodeName === 'LI');\n            },\n            replacement (content, node) {\n                return (node.checked ? '[x]' : '[ ]') + ' ';\n            }\n        });\n    }\n}\n\n/**\n * This data processor implementation uses GitHub Flavored Markdown as input/output data.\n *\n * See the {@glink features/markdown Markdown output} guide to learn more on how to enable it.\n */ class GFMDataProcessor {\n    /**\n\t * HTML data processor used to process HTML produced by the Markdown-to-HTML converter and the other way.\n\t */ _htmlDP;\n    /**\n\t * Helper for converting Markdown to HTML.\n\t */ _markdown2html;\n    /**\n\t * Helper for converting HTML to Markdown.\n\t */ _html2markdown;\n    /**\n\t * Creates a new instance of the Markdown data processor class.\n\t */ constructor(document){\n        this._htmlDP = new HtmlDataProcessor(document);\n        this._markdown2html = new MarkdownToHtml();\n        this._html2markdown = new HtmlToMarkdown();\n    }\n    /**\n\t * Keeps the specified element in the output as HTML. This is useful if the editor contains\n\t * features producing HTML that is not a part of the Markdown standard.\n\t *\n\t * By default, all HTML tags are removed.\n\t *\n\t * @param element The element name to be kept.\n\t */ keepHtml(element) {\n        this._html2markdown.keep([\n            element\n        ]);\n    }\n    /**\n\t * Converts the provided Markdown string to a view tree.\n\t *\n\t * @param data A Markdown string.\n\t * @returns The converted view element.\n\t */ toView(data) {\n        const html = this._markdown2html.parse(data);\n        return this._htmlDP.toView(html);\n    }\n    /**\n\t * Converts the provided {@link module:engine/view/documentfragment~DocumentFragment} to data format &ndash; in this\n\t * case to a Markdown string.\n\t *\n\t * @returns Markdown string.\n\t */ toData(viewFragment) {\n        const html = this._htmlDP.toData(viewFragment);\n        return this._html2markdown.parse(html);\n    }\n    /**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from Markdown to view elements.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern The pattern matching all view elements whose content should\n\t * be treated as raw data.\n\t */ registerRawContentMatcher(pattern) {\n        this._htmlDP.registerRawContentMatcher(pattern);\n    }\n    /**\n\t * This method does not have any effect on the data processor result. It exists for compatibility with the\n\t * {@link module:engine/dataprocessor/dataprocessor~DataProcessor `DataProcessor` interface}.\n\t */ useFillerType() {}\n}\n\n/**\n * The GitHub Flavored Markdown (GFM) plugin.\n *\n * For a detailed overview, check the {@glink features/markdown Markdown feature} guide.\n */ class Markdown extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.data.processor = new GFMDataProcessor(editor.data.viewDocument);\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Markdown';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nconst ALLOWED_MARKDOWN_FIRST_LEVEL_TAGS = [\n    'SPAN',\n    'BR',\n    'PRE',\n    'CODE'\n];\n/**\n * The GitHub Flavored Markdown (GFM) paste plugin.\n *\n * For a detailed overview, check the {@glink features/pasting/paste-markdown Paste Markdown feature} guide.\n */ class PasteFromMarkdownExperimental extends Plugin {\n    /**\n\t * @internal\n\t */ _gfmDataProcessor;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._gfmDataProcessor = new GFMDataProcessor(editor.data.viewDocument);\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'PasteFromMarkdownExperimental';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ClipboardPipeline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        let shiftPressed = false;\n        this.listenTo(viewDocument, 'keydown', (evt, data)=>{\n            shiftPressed = data.shiftKey;\n        });\n        this.listenTo(clipboardPipeline, 'inputTransformation', (evt, data)=>{\n            if (shiftPressed) {\n                return;\n            }\n            const dataAsTextHtml = data.dataTransfer.getData('text/html');\n            if (!dataAsTextHtml) {\n                const dataAsTextPlain = data.dataTransfer.getData('text/plain');\n                data.content = this._gfmDataProcessor.toView(dataAsTextPlain);\n                return;\n            }\n            const markdownFromHtml = this._parseMarkdownFromHtml(dataAsTextHtml);\n            if (markdownFromHtml) {\n                data.content = this._gfmDataProcessor.toView(markdownFromHtml);\n            }\n        });\n    }\n    /**\n\t * Determines if the code copied from a website in the `text/html` type can be parsed as Markdown.\n\t * It removes any OS-specific HTML tags, for example, <meta> on macOS and <!--StartFragment--> on Windows.\n\t * Then removes a single wrapper HTML tag or wrappers for sibling tags, and if there are no more tags left,\n\t * returns the remaining text. Returns null if there are any remaining HTML tags detected.\n\t *\n\t * @param htmlString Clipboard content in the `text/html` type format.\n\t */ _parseMarkdownFromHtml(htmlString) {\n        const withoutOsSpecificTags = this._removeOsSpecificTags(htmlString);\n        if (!this._containsOnlyAllowedFirstLevelTags(withoutOsSpecificTags)) {\n            return null;\n        }\n        const withoutWrapperTag = this._removeFirstLevelWrapperTagsAndBrs(withoutOsSpecificTags);\n        if (this._containsAnyRemainingHtmlTags(withoutWrapperTag)) {\n            return null;\n        }\n        return this._replaceHtmlReservedEntitiesWithCharacters(withoutWrapperTag);\n    }\n    /**\n\t * Removes OS-specific tags.\n\t *\n\t * @param htmlString Clipboard content in the `text/html` type format.\n\t */ _removeOsSpecificTags(htmlString) {\n        // Removing the <meta> tag present on Mac.\n        const withoutMetaTag = htmlString.replace(/^<meta\\b[^>]*>/, '').trim();\n        // Removing the <html> tag present on Windows.\n        const withoutHtmlTag = withoutMetaTag.replace(/^<html>/, '').replace(/<\\/html>$/, '').trim();\n        // Removing the <body> tag present on Windows.\n        const withoutBodyTag = withoutHtmlTag.replace(/^<body>/, '').replace(/<\\/body>$/, '').trim();\n        // Removing the <!--StartFragment--> tag present on Windows.\n        return withoutBodyTag.replace(/^<!--StartFragment-->/, '').replace(/<!--EndFragment-->$/, '').trim();\n    }\n    /**\n\t * If the input HTML string contains any first-level formatting tags\n\t * like <b>, <strong>, or <i>, we should not treat it as Markdown.\n\t *\n\t * @param htmlString Clipboard content.\n\t */ _containsOnlyAllowedFirstLevelTags(htmlString) {\n        const parser = new DOMParser();\n        const { body: tempElement } = parser.parseFromString(htmlString, 'text/html');\n        const tagNames = Array.from(tempElement.children).map((el)=>el.tagName);\n        return tagNames.every((el)=>ALLOWED_MARKDOWN_FIRST_LEVEL_TAGS.includes(el));\n    }\n    /**\n\t * Removes multiple HTML wrapper tags from a list of sibling HTML tags.\n\t *\n\t * @param htmlString Clipboard content without any OS-specific tags.\n\t */ _removeFirstLevelWrapperTagsAndBrs(htmlString) {\n        const parser = new DOMParser();\n        const { body: tempElement } = parser.parseFromString(htmlString, 'text/html');\n        const brElements = tempElement.querySelectorAll('br');\n        for (const br of brElements){\n            br.replaceWith('\\n');\n        }\n        const outerElements = tempElement.querySelectorAll(':scope > *');\n        for (const element of outerElements){\n            const elementClone = element.cloneNode(true);\n            element.replaceWith(...elementClone.childNodes);\n        }\n        return tempElement.innerHTML;\n    }\n    /**\n\t * Determines if a string contains any HTML tags.\n\t */ _containsAnyRemainingHtmlTags(str) {\n        return str.includes('<');\n    }\n    /**\n\t * Replaces the reserved HTML entities with the actual characters.\n\t *\n\t * @param htmlString Clipboard content without any tags.\n\t */ _replaceHtmlReservedEntitiesWithCharacters(htmlString) {\n        return htmlString.replace(/&gt;/g, '>').replace(/&lt;/g, '<').replace(/&nbsp;/g, ' ');\n    }\n}\n\nexport { Markdown, PasteFromMarkdownExperimental };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module markdown-gfm/markdown2html/markdown2html\n */\n\nimport { marked } from 'marked';\n\n/**\n * This is a helper class used by the {@link module:markdown-gfm/markdown Markdown feature} to convert Markdown to HTML.\n */\nexport class MarkdownToHtml {\n\tprivate _parser: typeof marked;\n\n\tprivate _options = {\n\t\tgfm: true,\n\t\tbreaks: true,\n\t\ttables: true,\n\t\txhtml: true,\n\t\theaderIds: false\n\t};\n\n\tconstructor() {\n\t\t// Overrides.\n\t\tmarked.use( {\n\t\t\ttokenizer: {\n\t\t\t\t// Disable the autolink rule in the lexer.\n\t\t\t\tautolink: () => null as any,\n\t\t\t\turl: () => null as any\n\t\t\t},\n\t\t\trenderer: {\n\t\t\t\tcheckbox( ...args: Array<any> ) {\n\t\t\t\t\t// Remove bogus space after <input type=\"checkbox\"> because it would be preserved\n\t\t\t\t\t// by DomConverter as it's next to an inline object.\n\t\t\t\t\treturn Object.getPrototypeOf( this ).checkbox.call( this, ...args ).trimRight();\n\t\t\t\t},\n\n\t\t\t\tcode( ...args: Array<any> ) {\n\t\t\t\t\t// Since marked v1.2.8, every <code> gets a trailing \"\\n\" whether it originally\n\t\t\t\t\t// ended with one or not (see https://github.com/markedjs/marked/issues/1884 to learn why).\n\t\t\t\t\t// This results in a redundant soft break in the model when loaded into the editor, which\n\t\t\t\t\t// is best prevented at this stage. See https://github.com/ckeditor/ckeditor5/issues/11124.\n\t\t\t\t\treturn Object.getPrototypeOf( this ).code.call( this, ...args ).replace( '\\n</code>', '</code>' );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tthis._parser = marked;\n\t}\n\n\tpublic parse( markdown: string ): string {\n\t\treturn this._parser.parse( markdown, this._options );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module markdown-gfm/html2markdown/html2markdown\n */\n\nimport Turndown from 'turndown';\n\n// There no avaialble types for 'turndown-plugin-gfm' module and it's not worth to generate them on our own.\n/* eslint-disable @typescript-eslint/ban-ts-comment */\n// @ts-ignore\nimport { gfm } from 'turndown-plugin-gfm';\n\nconst autolinkRegex = /* #__PURE__ */ new RegExp(\n\t// Prefix.\n\t/\\b(?:(?:https?|ftp):\\/\\/|www\\.)/.source +\n\n\t// Domain name.\n\t/(?![-_])(?:[-_a-z0-9\\u00a1-\\uffff]{1,63}\\.)+(?:[a-z\\u00a1-\\uffff]{2,63})/.source +\n\n\t// The rest.\n\t/(?:[^\\s<>]*)/.source,\n\t'gi'\n);\n\nclass UpdatedTurndown extends Turndown {\n\tpublic override escape( string: string ): string {\n\t\tconst originalEscape = super.escape;\n\n\t\tfunction escape( string: string ): string {\n\t\t\tstring = originalEscape( string );\n\n\t\t\t// Escape \"<\".\n\t\t\tstring = string.replace( /</g, '\\\\<' );\n\n\t\t\treturn string;\n\t\t}\n\n\t\t// Urls should not be escaped. Our strategy is using a regex to find them and escape everything\n\t\t// which is out of the matches parts.\n\n\t\tlet escaped = '';\n\t\tlet lastLinkEnd = 0;\n\n\t\tfor ( const match of this._matchAutolink( string ) ) {\n\t\t\tconst index = match.index!;\n\n\t\t\t// Append the substring between the last match and the current one (if anything).\n\t\t\tif ( index > lastLinkEnd ) {\n\t\t\t\tescaped += escape( string.substring( lastLinkEnd, index ) );\n\t\t\t}\n\n\t\t\tconst matchedURL = match[ 0 ];\n\n\t\t\tescaped += matchedURL;\n\n\t\t\tlastLinkEnd = index + matchedURL.length;\n\t\t}\n\n\t\t// Add text after the last link or at the string start if no matches.\n\t\tif ( lastLinkEnd < string.length ) {\n\t\t\tescaped += escape( string.substring( lastLinkEnd, string.length ) );\n\t\t}\n\n\t\treturn escaped;\n\t}\n\n\t/**\n\t * Trimming end of link.\n\t * https://github.github.com/gfm/#autolinks-extension-\n\t */\n\tprivate* _matchAutolink( string: string ) {\n\t\tfor ( const match of string.matchAll( autolinkRegex ) ) {\n\t\t\tconst matched = match[ 0 ];\n\t\t\tconst length = this._autolinkFindEnd( matched );\n\n\t\t\tyield Object.assign(\n\t\t\t\t[ matched.substring( 0, length ) ],\n\t\t\t\t{ index: match.index }\n\t\t\t);\n\n\t\t\t// We could adjust regex.lastIndex but it's not needed because what we skipped is for sure not a valid URL.\n\t\t}\n\t}\n\n\t/**\n\t * Returns the new length of the link (after it would trim trailing characters).\n\t */\n\tprivate _autolinkFindEnd( string: string ) {\n\t\tlet length = string.length;\n\n\t\twhile ( length > 0 ) {\n\t\t\tconst char = string[ length - 1 ];\n\n\t\t\tif ( '?!.,:*_~\\'\"'.includes( char ) ) {\n\t\t\t\tlength--;\n\t\t\t} else if ( char == ')' ) {\n\t\t\t\tlet openBrackets = 0;\n\n\t\t\t\tfor ( let i = 0; i < length; i++ ) {\n\t\t\t\t\tif ( string[ i ] == '(' ) {\n\t\t\t\t\t\topenBrackets++;\n\t\t\t\t\t} else if ( string[ i ] == ')' ) {\n\t\t\t\t\t\topenBrackets--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If there is fewer opening brackets then closing ones we should remove a closing bracket.\n\t\t\t\tif ( openBrackets < 0 ) {\n\t\t\t\t\tlength--;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn length;\n\t}\n}\n\n/**\n * This is a helper class used by the {@link module:markdown-gfm/markdown Markdown feature} to convert HTML to Markdown.\n */\nexport class HtmlToMarkdown {\n\tprivate _parser: UpdatedTurndown;\n\n\tconstructor() {\n\t\tthis._parser = this._createParser();\n\t}\n\n\tpublic parse( html: string ): string {\n\t\treturn this._parser.turndown( html );\n\t}\n\n\tpublic keep( elements: Turndown.Filter ): void {\n\t\tthis._parser.keep( elements );\n\t}\n\n\tprivate _createParser(): UpdatedTurndown {\n\t\tconst parser = new UpdatedTurndown( {\n\t\t\tcodeBlockStyle: 'fenced',\n\t\t\thr: '---',\n\t\t\theadingStyle: 'atx'\n\t\t} );\n\n\t\tparser.use( [\n\t\t\tgfm,\n\t\t\tthis._todoList\n\t\t] );\n\n\t\treturn parser;\n\t}\n\n\t// This is a copy of the original taskListItems rule from turndown-plugin-gfm, with minor changes.\n\tprivate _todoList( turndown: UpdatedTurndown ): void {\n\t\tturndown.addRule( 'taskListItems', {\n\t\t\tfilter( node: any ) {\n\t\t\t\treturn node.type === 'checkbox' &&\n\t\t\t\t\t// Changes here as CKEditor outputs a deeper structure.\n\t\t\t\t\t( node.parentNode.nodeName === 'LI' || node.parentNode.parentNode.nodeName === 'LI' );\n\t\t\t},\n\t\t\treplacement( content: any, node: any ) {\n\t\t\t\treturn ( node.checked ? '[x]' : '[ ]' ) + ' ';\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module markdown-gfm/gfmdataprocessor\n */\n\nimport {\n\tHtmlDataProcessor,\n\ttype DataProcessor,\n\ttype ViewDocument,\n\ttype ViewDocumentFragment,\n\ttype MatcherPattern\n} from 'ckeditor5/src/engine.js';\n\nimport { MarkdownToHtml } from './markdown2html/markdown2html.js';\nimport { HtmlToMarkdown } from './html2markdown/html2markdown.js';\n\n/**\n * This data processor implementation uses GitHub Flavored Markdown as input/output data.\n *\n * See the {@glink features/markdown Markdown output} guide to learn more on how to enable it.\n */\nexport default class GFMDataProcessor implements DataProcessor {\n\t/**\n\t * HTML data processor used to process HTML produced by the Markdown-to-HTML converter and the other way.\n\t */\n\tprivate _htmlDP: HtmlDataProcessor;\n\n\t/**\n\t * Helper for converting Markdown to HTML.\n\t */\n\tprivate _markdown2html: MarkdownToHtml;\n\n\t/**\n\t * Helper for converting HTML to Markdown.\n\t */\n\tprivate _html2markdown: HtmlToMarkdown;\n\n\t/**\n\t * Creates a new instance of the Markdown data processor class.\n\t */\n\tconstructor( document: ViewDocument ) {\n\t\tthis._htmlDP = new HtmlDataProcessor( document );\n\t\tthis._markdown2html = new MarkdownToHtml();\n\t\tthis._html2markdown = new HtmlToMarkdown();\n\t}\n\n\t/**\n\t * Keeps the specified element in the output as HTML. This is useful if the editor contains\n\t * features producing HTML that is not a part of the Markdown standard.\n\t *\n\t * By default, all HTML tags are removed.\n\t *\n\t * @param element The element name to be kept.\n\t */\n\tpublic keepHtml( element: keyof HTMLElementTagNameMap ): void {\n\t\tthis._html2markdown.keep( [ element ] );\n\t}\n\n\t/**\n\t * Converts the provided Markdown string to a view tree.\n\t *\n\t * @param data A Markdown string.\n\t * @returns The converted view element.\n\t */\n\tpublic toView( data: string ): ViewDocumentFragment {\n\t\tconst html = this._markdown2html.parse( data );\n\t\treturn this._htmlDP.toView( html );\n\t}\n\n\t/**\n\t * Converts the provided {@link module:engine/view/documentfragment~DocumentFragment} to data format &ndash; in this\n\t * case to a Markdown string.\n\t *\n\t * @returns Markdown string.\n\t */\n\tpublic toData( viewFragment: ViewDocumentFragment ): string {\n\t\tconst html = this._htmlDP.toData( viewFragment );\n\t\treturn this._html2markdown.parse( html );\n\t}\n\n\t/**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} for view elements whose content should be treated as raw data\n\t * and not processed during the conversion from Markdown to view elements.\n\t *\n\t * The raw data can be later accessed by a\n\t * {@link module:engine/view/element~Element#getCustomProperty custom property of a view element} called `\"$rawContent\"`.\n\t *\n\t * @param pattern The pattern matching all view elements whose content should\n\t * be treated as raw data.\n\t */\n\tpublic registerRawContentMatcher( pattern: MatcherPattern ): void {\n\t\tthis._htmlDP.registerRawContentMatcher( pattern );\n\t}\n\n\t/**\n\t * This method does not have any effect on the data processor result. It exists for compatibility with the\n\t * {@link module:engine/dataprocessor/dataprocessor~DataProcessor `DataProcessor` interface}.\n\t */\n\tpublic useFillerType(): void {}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module markdown-gfm/markdown\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport GFMDataProcessor from './gfmdataprocessor.js';\n\n/**\n * The GitHub Flavored Markdown (GFM) plugin.\n *\n * For a detailed overview, check the {@glink features/markdown Markdown feature} guide.\n */\nexport default class Markdown extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.data.processor = new GFMDataProcessor( editor.data.viewDocument );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Markdown' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module markdown-gfm/pastefrommarkdownexperimental\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { ClipboardPipeline, type ClipboardInputTransformationEvent } from 'ckeditor5/src/clipboard.js';\nimport GFMDataProcessor from './gfmdataprocessor.js';\nimport type { ViewDocumentKeyDownEvent } from 'ckeditor5/src/engine.js';\n\nconst ALLOWED_MARKDOWN_FIRST_LEVEL_TAGS = [ 'SPAN', 'BR', 'PRE', 'CODE' ];\n\n/**\n * The GitHub Flavored Markdown (GFM) paste plugin.\n *\n * For a detailed overview, check the {@glink features/pasting/paste-markdown Paste Markdown feature} guide.\n */\nexport default class PasteFromMarkdownExperimental extends Plugin {\n\t/**\n\t * @internal\n\t */\n\tprivate _gfmDataProcessor: GFMDataProcessor;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._gfmDataProcessor = new GFMDataProcessor( editor.data.viewDocument );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'PasteFromMarkdownExperimental' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ClipboardPipeline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\tconst clipboardPipeline: ClipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\n\t\tlet shiftPressed = false;\n\n\t\tthis.listenTo<ViewDocumentKeyDownEvent>( viewDocument, 'keydown', ( evt, data ) => {\n\t\t\tshiftPressed = data.shiftKey;\n\t\t} );\n\n\t\tthis.listenTo<ClipboardInputTransformationEvent>( clipboardPipeline, 'inputTransformation', ( evt, data ) => {\n\t\t\tif ( shiftPressed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst dataAsTextHtml = data.dataTransfer.getData( 'text/html' );\n\n\t\t\tif ( !dataAsTextHtml ) {\n\t\t\t\tconst dataAsTextPlain = data.dataTransfer.getData( 'text/plain' );\n\n\t\t\t\tdata.content = this._gfmDataProcessor.toView( dataAsTextPlain );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst markdownFromHtml = this._parseMarkdownFromHtml( dataAsTextHtml );\n\n\t\t\tif ( markdownFromHtml ) {\n\t\t\t\tdata.content = this._gfmDataProcessor.toView( markdownFromHtml );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Determines if the code copied from a website in the `text/html` type can be parsed as Markdown.\n\t * It removes any OS-specific HTML tags, for example, <meta> on macOS and <!--StartFragment--> on Windows.\n\t * Then removes a single wrapper HTML tag or wrappers for sibling tags, and if there are no more tags left,\n\t * returns the remaining text. Returns null if there are any remaining HTML tags detected.\n\t *\n\t * @param htmlString Clipboard content in the `text/html` type format.\n\t */\n\tprivate _parseMarkdownFromHtml( htmlString: string ): string | null {\n\t\tconst withoutOsSpecificTags = this._removeOsSpecificTags( htmlString );\n\n\t\tif ( !this._containsOnlyAllowedFirstLevelTags( withoutOsSpecificTags ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst withoutWrapperTag = this._removeFirstLevelWrapperTagsAndBrs( withoutOsSpecificTags );\n\n\t\tif ( this._containsAnyRemainingHtmlTags( withoutWrapperTag ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this._replaceHtmlReservedEntitiesWithCharacters( withoutWrapperTag );\n\t}\n\n\t/**\n\t * Removes OS-specific tags.\n\t *\n\t * @param htmlString Clipboard content in the `text/html` type format.\n\t */\n\tprivate _removeOsSpecificTags( htmlString: string ): string {\n\t\t// Removing the <meta> tag present on Mac.\n\t\tconst withoutMetaTag = htmlString.replace( /^<meta\\b[^>]*>/, '' ).trim();\n\t\t// Removing the <html> tag present on Windows.\n\t\tconst withoutHtmlTag = withoutMetaTag.replace( /^<html>/, '' ).replace( /<\\/html>$/, '' ).trim();\n\t\t// Removing the <body> tag present on Windows.\n\t\tconst withoutBodyTag = withoutHtmlTag.replace( /^<body>/, '' ).replace( /<\\/body>$/, '' ).trim();\n\n\t\t// Removing the <!--StartFragment--> tag present on Windows.\n\t\treturn withoutBodyTag.replace( /^<!--StartFragment-->/, '' ).replace( /<!--EndFragment-->$/, '' ).trim();\n\t}\n\n\t/**\n\t * If the input HTML string contains any first-level formatting tags\n\t * like <b>, <strong>, or <i>, we should not treat it as Markdown.\n\t *\n\t * @param htmlString Clipboard content.\n\t */\n\tprivate _containsOnlyAllowedFirstLevelTags( htmlString: string ): boolean {\n\t\tconst parser = new DOMParser();\n\t\tconst { body: tempElement } = parser.parseFromString( htmlString, 'text/html' );\n\n\t\tconst tagNames = Array.from( tempElement.children ).map( el => el.tagName );\n\n\t\treturn tagNames.every( el => ALLOWED_MARKDOWN_FIRST_LEVEL_TAGS.includes( el ) );\n\t}\n\n\t/**\n\t * Removes multiple HTML wrapper tags from a list of sibling HTML tags.\n\t *\n\t * @param htmlString Clipboard content without any OS-specific tags.\n\t */\n\tprivate _removeFirstLevelWrapperTagsAndBrs( htmlString: string ): string {\n\t\tconst parser = new DOMParser();\n\t\tconst { body: tempElement } = parser.parseFromString( htmlString, 'text/html' );\n\n\t\tconst brElements = tempElement.querySelectorAll( 'br' );\n\n\t\tfor ( const br of brElements ) {\n\t\t\tbr.replaceWith( '\\n' );\n\t\t}\n\n\t\tconst outerElements = tempElement.querySelectorAll( ':scope > *' );\n\n\t\tfor ( const element of outerElements ) {\n\t\t\tconst elementClone = element.cloneNode( true );\n\t\t\telement.replaceWith( ...elementClone.childNodes );\n\t\t}\n\n\t\treturn tempElement.innerHTML;\n\t}\n\n\t/**\n\t * Determines if a string contains any HTML tags.\n\t */\n\tprivate _containsAnyRemainingHtmlTags( str: string ): boolean {\n\t\treturn str.includes( '<' );\n\t}\n\n\t/**\n\t * Replaces the reserved HTML entities with the actual characters.\n\t *\n\t * @param htmlString Clipboard content without any tags.\n\t */\n\tprivate _replaceHtmlReservedEntitiesWithCharacters( htmlString: string ) {\n\t\treturn htmlString\n\t\t\t.replace( /&gt;/g, '>' )\n\t\t\t.replace( /&lt;/g, '<' )\n\t\t\t.replace( /&nbsp;/g, ' ' );\n\t}\n}\n", "import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { toWidget, isWidget, findOptimalInsertionRange, Widget, WidgetToolbarRepository } from '@ckeditor/ckeditor5-widget/dist/index.js';\nimport { logWarning, toArray, first, global, FocusTracker, KeystrokeHandler } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { IconView, Template, View, submitHandler, LabeledFieldView, createLabeledInputText, Dialog, ButtonView, MenuBarMenuListItemButtonView, CssTransitionDisablerMixin } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { LivePosition, LiveRange } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { Clipboard } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\nimport { Delete } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { Undo } from '@ckeditor/ckeditor5-undo/dist/index.js';\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module media-embed/converters\n */ /**\n * Returns a function that converts the model \"url\" attribute to the view representation.\n *\n * Depending on the configuration, the view representation can be \"semantic\" (for the data pipeline):\n *\n * ```html\n * <figure class=\"media\">\n * \t<oembed url=\"foo\"></oembed>\n * </figure>\n * ```\n *\n * or \"non-semantic\" (for the editing view pipeline):\n *\n * ```html\n * <figure class=\"media\">\n * \t<div data-oembed-url=\"foo\">[ non-semantic media preview for \"foo\" ]</div>\n * </figure>\n * ```\n *\n * **Note:** Changing the model \"url\" attribute replaces the entire content of the\n * `<figure>` in the view.\n *\n * @param registry The registry providing\n * the media and their content.\n * @param options options object with following properties:\n * - elementName When set, overrides the default element name for semantic media embeds.\n * - renderMediaPreview When `true`, the converter will create the view in the non-semantic form.\n * - renderForEditingView When `true`, the converter will create a view specific for the\n * editing pipeline (e.g. including CSS classes, content placeholders).\n */ function modelToViewUrlAttributeConverter(registry, options) {\n    const converter = (evt, data, conversionApi)=>{\n        if (!conversionApi.consumable.consume(data.item, evt.name)) {\n            return;\n        }\n        const url = data.attributeNewValue;\n        const viewWriter = conversionApi.writer;\n        const figure = conversionApi.mapper.toViewElement(data.item);\n        const mediaContentElement = [\n            ...figure.getChildren()\n        ].find((child)=>child.getCustomProperty('media-content'));\n        // TODO: removing the wrapper and creating it from scratch is a hack. We can do better than that.\n        viewWriter.remove(mediaContentElement);\n        const mediaViewElement = registry.getMediaViewElement(viewWriter, url, options);\n        viewWriter.insert(viewWriter.createPositionAt(figure, 0), mediaViewElement);\n    };\n    return (dispatcher)=>{\n        dispatcher.on('attribute:url:media', converter);\n    };\n}\n\n/**\n * Converts a given {@link module:engine/view/element~Element} to a media embed widget:\n * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the media widget element.\n * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n *\n * @param writer An instance of the view writer.\n * @param label The element's label.\n */ function toMediaWidget(viewElement, writer, label) {\n    writer.setCustomProperty('media', true, viewElement);\n    return toWidget(viewElement, writer, {\n        label\n    });\n}\n/**\n * Returns a media widget editing view element if one is selected.\n */ function getSelectedMediaViewWidget(selection) {\n    const viewElement = selection.getSelectedElement();\n    if (viewElement && isMediaWidget(viewElement)) {\n        return viewElement;\n    }\n    return null;\n}\n/**\n * Checks if a given view element is a media widget.\n */ function isMediaWidget(viewElement) {\n    return !!viewElement.getCustomProperty('media') && isWidget(viewElement);\n}\n/**\n * Creates a view element representing the media. Either a \"semantic\" one for the data pipeline:\n *\n * ```html\n * <figure class=\"media\">\n * \t<oembed url=\"foo\"></oembed>\n * </figure>\n * ```\n *\n * or a \"non-semantic\" (for the editing view pipeline):\n *\n * ```html\n * <figure class=\"media\">\n * \t<div data-oembed-url=\"foo\">[ non-semantic media preview for \"foo\" ]</div>\n * </figure>\n * ```\n */ function createMediaFigureElement(writer, registry, url, options) {\n    return writer.createContainerElement('figure', {\n        class: 'media'\n    }, [\n        registry.getMediaViewElement(writer, url, options),\n        writer.createSlot()\n    ]);\n}\n/**\n * Returns a selected media element in the model, if any.\n */ function getSelectedMediaModelWidget(selection) {\n    const selectedElement = selection.getSelectedElement();\n    if (selectedElement && selectedElement.is('element', 'media')) {\n        return selectedElement;\n    }\n    return null;\n}\n/**\n * Creates a media element and inserts it into the model.\n *\n * **Note**: This method will use {@link module:engine/model/model~Model#insertContent `model.insertContent()`} logic of inserting content\n * if no `insertPosition` is passed.\n *\n * @param url An URL of an embeddable media.\n * @param findOptimalPosition If true it will try to find optimal position to insert media without breaking content\n * in which a selection is.\n */ function insertMedia(model, url, selectable, findOptimalPosition) {\n    model.change((writer)=>{\n        const mediaElement = writer.createElement('media', {\n            url\n        });\n        model.insertObject(mediaElement, selectable, null, {\n            setSelection: 'on',\n            findOptimalPosition: findOptimalPosition ? 'auto' : undefined\n        });\n    });\n}\n\n/**\n * The insert media command.\n *\n * The command is registered by the {@link module:media-embed/mediaembedediting~MediaEmbedEditing} as `'mediaEmbed'`.\n *\n * To insert media at the current selection, execute the command and specify the URL:\n *\n * ```ts\n * editor.execute( 'mediaEmbed', 'http://url.to.the/media' );\n * ```\n */ class MediaEmbedCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const selectedMedia = getSelectedMediaModelWidget(selection);\n        this.value = selectedMedia ? selectedMedia.getAttribute('url') : undefined;\n        this.isEnabled = isMediaSelected(selection) || isAllowedInParent(selection, model);\n    }\n    /**\n\t * Executes the command, which either:\n\t *\n\t * * updates the URL of the selected media,\n\t * * inserts the new media into the editor and puts the selection around it.\n\t *\n\t * @fires execute\n\t * @param url The URL of the media.\n\t */ execute(url) {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const selectedMedia = getSelectedMediaModelWidget(selection);\n        if (selectedMedia) {\n            model.change((writer)=>{\n                writer.setAttribute('url', url, selectedMedia);\n            });\n        } else {\n            insertMedia(model, url, selection, true);\n        }\n    }\n}\n/**\n * Checks if the media embed is allowed in the parent.\n */ function isAllowedInParent(selection, model) {\n    const insertionRange = findOptimalInsertionRange(selection, model);\n    let parent = insertionRange.start.parent;\n    // The model.insertContent() will remove empty parent (unless it is a $root or a limit).\n    if (parent.isEmpty && !model.schema.isLimit(parent)) {\n        parent = parent.parent;\n    }\n    return model.schema.checkChild(parent, 'media');\n}\n/**\n * Checks if the media object is selected.\n */ function isMediaSelected(selection) {\n    const element = selection.getSelectedElement();\n    return !!element && element.name === 'media';\n}\n\nvar mediaPlaceholderIcon = \"<svg viewBox=\\\"0 0 64 42\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M47.426 17V3.713L63.102 0v19.389h-.001l.001.272c0 1.595-2.032 3.43-4.538 4.098-2.506.668-4.538-.083-4.538-1.678 0-1.594 2.032-3.43 4.538-4.098.914-.244 2.032-.565 2.888-.603V4.516L49.076 7.447v9.556A1.014 1.014 0 0 0 49 17h-1.574zM29.5 17h-8.343a7.073 7.073 0 1 0-4.657 4.06v3.781H3.3a2.803 2.803 0 0 1-2.8-2.804V8.63a2.803 2.803 0 0 1 2.8-2.805h4.082L8.58 2.768A1.994 1.994 0 0 1 10.435 1.5h8.985c.773 0 1.477.448 1.805 1.149l1.488 3.177H26.7c1.546 0 2.8 1.256 2.8 2.805V17zm-11.637 0H17.5a1 1 0 0 0-1 1v.05A4.244 4.244 0 1 1 17.863 17zm29.684 2c.97 0 .953-.048.953.889v20.743c0 .953.016.905-.953.905H19.453c-.97 0-.953.048-.953-.905V19.89c0-.937-.016-.889.97-.889h28.077zm-4.701 19.338V22.183H24.154v16.155h18.692zM20.6 21.375v1.616h1.616v-1.616H20.6zm0 3.231v1.616h1.616v-1.616H20.6zm0 3.231v1.616h1.616v-1.616H20.6zm0 3.231v1.616h1.616v-1.616H20.6zm0 3.231v1.616h1.616v-1.616H20.6zm0 3.231v1.616h1.616V37.53H20.6zm24.233-16.155v1.616h1.615v-1.616h-1.615zm0 3.231v1.616h1.615v-1.616h-1.615zm0 3.231v1.616h1.615v-1.616h-1.615zm0 3.231v1.616h1.615v-1.616h-1.615zm0 3.231v1.616h1.615v-1.616h-1.615zm0 3.231v1.616h1.615V37.53h-1.615zM29.485 25.283a.4.4 0 0 1 .593-.35l9.05 4.977a.4.4 0 0 1 0 .701l-9.05 4.978a.4.4 0 0 1-.593-.35v-9.956z\\\"/></svg>\";\n\nconst mediaPlaceholderIconViewBox = '0 0 64 42';\n/**\n * A bridge between the raw media content provider definitions and the editor view content.\n *\n * It helps translating media URLs to corresponding {@link module:engine/view/element~Element view elements}.\n *\n * Mostly used by the {@link module:media-embed/mediaembedediting~MediaEmbedEditing} plugin.\n */ class MediaRegistry {\n    /**\n\t * The {@link module:utils/locale~Locale} instance.\n\t */ locale;\n    /**\n\t * The media provider definitions available for the registry. Usually corresponding with the\n\t * {@link module:media-embed/mediaembedconfig~MediaEmbedConfig media configuration}.\n\t */ providerDefinitions;\n    /**\n\t * Creates an instance of the {@link module:media-embed/mediaregistry~MediaRegistry} class.\n\t *\n\t * @param locale The localization services instance.\n\t * @param config The configuration of the media embed feature.\n\t */ constructor(locale, config){\n        const providers = config.providers;\n        const extraProviders = config.extraProviders || [];\n        const removedProviders = new Set(config.removeProviders);\n        const providerDefinitions = providers.concat(extraProviders).filter((provider)=>{\n            const name = provider.name;\n            if (!name) {\n                /**\n\t\t\t\t\t * One of the providers (or extra providers) specified in the media embed configuration\n\t\t\t\t\t * has no name and will not be used by the editor. In order to get this media\n\t\t\t\t\t * provider working, double check your editor configuration.\n\t\t\t\t\t *\n\t\t\t\t\t * @error media-embed-no-provider-name\n\t\t\t\t\t */ logWarning('media-embed-no-provider-name', {\n                    provider\n                });\n                return false;\n            }\n            return !removedProviders.has(name);\n        });\n        this.locale = locale;\n        this.providerDefinitions = providerDefinitions;\n    }\n    /**\n\t * Checks whether the passed URL is representing a certain media type allowed in the editor.\n\t *\n\t * @param url The URL to be checked\n\t */ hasMedia(url) {\n        return !!this._getMedia(url);\n    }\n    /**\n\t * For the given media URL string and options, it returns the {@link module:engine/view/element~Element view element}\n\t * representing that media.\n\t *\n\t * **Note:** If no URL is specified, an empty view element is returned.\n\t *\n\t * @param writer The view writer used to produce a view element.\n\t * @param url The URL to be translated into a view element.\n\t */ getMediaViewElement(writer, url, options) {\n        return this._getMedia(url).getViewElement(writer, options);\n    }\n    /**\n\t * Returns a `Media` instance for the given URL.\n\t *\n\t * @param url The URL of the media.\n\t * @returns The `Media` instance or `null` when there is none.\n\t */ _getMedia(url) {\n        if (!url) {\n            return new Media(this.locale);\n        }\n        url = url.trim();\n        for (const definition of this.providerDefinitions){\n            const previewRenderer = definition.html;\n            const pattern = toArray(definition.url);\n            for (const subPattern of pattern){\n                const match = this._getUrlMatches(url, subPattern);\n                if (match) {\n                    return new Media(this.locale, url, match, previewRenderer);\n                }\n            }\n        }\n        return null;\n    }\n    /**\n\t * Tries to match `url` to `pattern`.\n\t *\n\t * @param url The URL of the media.\n\t * @param pattern The pattern that should accept the media URL.\n\t */ _getUrlMatches(url, pattern) {\n        // 1. Try to match without stripping the protocol and \"www\" subdomain.\n        let match = url.match(pattern);\n        if (match) {\n            return match;\n        }\n        // 2. Try to match after stripping the protocol.\n        let rawUrl = url.replace(/^https?:\\/\\//, '');\n        match = rawUrl.match(pattern);\n        if (match) {\n            return match;\n        }\n        // 3. Try to match after stripping the \"www\" subdomain.\n        rawUrl = rawUrl.replace(/^www\\./, '');\n        match = rawUrl.match(pattern);\n        if (match) {\n            return match;\n        }\n        return null;\n    }\n}\n/**\n * Represents media defined by the provider configuration.\n *\n * It can be rendered to the {@link module:engine/view/element~Element view element} and used in the editing or data pipeline.\n */ class Media {\n    /**\n\t * The URL this Media instance represents.\n\t */ url;\n    /**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t *\n\t * @see module:utils/locale~Locale#t\n\t */ _locale;\n    /**\n\t * The output of the `RegExp.match` which validated the {@link #url} of this media.\n\t */ _match;\n    /**\n\t * The function returning the HTML string preview of this media.\n\t */ _previewRenderer;\n    constructor(locale, url, match, previewRenderer){\n        this.url = this._getValidUrl(url);\n        this._locale = locale;\n        this._match = match;\n        this._previewRenderer = previewRenderer;\n    }\n    /**\n\t * Returns the view element representation of the media.\n\t *\n\t * @param writer The view writer used to produce a view element.\n\t */ getViewElement(writer, options) {\n        const attributes = {};\n        let viewElement;\n        if (options.renderForEditingView || options.renderMediaPreview && this.url && this._previewRenderer) {\n            if (this.url) {\n                attributes['data-oembed-url'] = this.url;\n            }\n            if (options.renderForEditingView) {\n                attributes.class = 'ck-media__wrapper';\n            }\n            const mediaHtml = this._getPreviewHtml(options);\n            viewElement = writer.createRawElement('div', attributes, (domElement, domConverter)=>{\n                domConverter.setContentOf(domElement, mediaHtml);\n            });\n        } else {\n            if (this.url) {\n                attributes.url = this.url;\n            }\n            viewElement = writer.createEmptyElement(options.elementName, attributes);\n        }\n        writer.setCustomProperty('media-content', true, viewElement);\n        return viewElement;\n    }\n    /**\n\t * Returns the HTML string of the media content preview.\n\t */ _getPreviewHtml(options) {\n        if (this._previewRenderer) {\n            return this._previewRenderer(this._match);\n        } else {\n            // The placeholder only makes sense for editing view and media which have URLs.\n            // Placeholder is never displayed in data and URL-less media have no content.\n            if (this.url && options.renderForEditingView) {\n                return this._getPlaceholderHtml();\n            }\n            return '';\n        }\n    }\n    /**\n\t * Returns the placeholder HTML when the media has no content preview.\n\t */ _getPlaceholderHtml() {\n        const icon = new IconView();\n        const t = this._locale.t;\n        icon.content = mediaPlaceholderIcon;\n        icon.viewBox = mediaPlaceholderIconViewBox;\n        const placeholder = new Template({\n            tag: 'div',\n            attributes: {\n                class: 'ck ck-reset_all ck-media__placeholder'\n            },\n            children: [\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: 'ck-media__placeholder__icon'\n                    },\n                    children: [\n                        icon\n                    ]\n                },\n                {\n                    tag: 'a',\n                    attributes: {\n                        class: 'ck-media__placeholder__url',\n                        target: '_blank',\n                        rel: 'noopener noreferrer',\n                        href: this.url,\n                        'data-cke-tooltip-text': t('Open media in new tab')\n                    },\n                    children: [\n                        {\n                            tag: 'span',\n                            attributes: {\n                                class: 'ck-media__placeholder__url__text'\n                            },\n                            children: [\n                                this.url\n                            ]\n                        }\n                    ]\n                }\n            ]\n        }).render();\n        return placeholder.outerHTML;\n    }\n    /**\n\t * Returns the full URL to the specified media.\n\t *\n\t * @param url The URL of the media.\n\t */ _getValidUrl(url) {\n        if (!url) {\n            return null;\n        }\n        if (url.match(/^https?/)) {\n            return url;\n        }\n        return 'https://' + url;\n    }\n}\n\n/**\n * The media embed editing feature.\n */ class MediaEmbedEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'MediaEmbedEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * The media registry managing the media providers in the editor.\n\t */ registry;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('mediaEmbed', {\n            elementName: 'oembed',\n            providers: [\n                {\n                    name: 'dailymotion',\n                    url: [\n                        /^dailymotion\\.com\\/video\\/(\\w+)/,\n                        /^dai.ly\\/(\\w+)/\n                    ],\n                    html: (match)=>{\n                        const id = match[1];\n                        return '<div style=\"position: relative; padding-bottom: 100%; height: 0; \">' + `<iframe src=\"https://www.dailymotion.com/embed/video/${id}\" ` + 'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' + 'frameborder=\"0\" width=\"480\" height=\"270\" allowfullscreen allow=\"autoplay\">' + '</iframe>' + '</div>';\n                    }\n                },\n                {\n                    name: 'spotify',\n                    url: [\n                        /^open\\.spotify\\.com\\/(artist\\/\\w+)/,\n                        /^open\\.spotify\\.com\\/(album\\/\\w+)/,\n                        /^open\\.spotify\\.com\\/(track\\/\\w+)/\n                    ],\n                    html: (match)=>{\n                        const id = match[1];\n                        return '<div style=\"position: relative; padding-bottom: 100%; height: 0; padding-bottom: 126%;\">' + `<iframe src=\"https://open.spotify.com/embed/${id}\" ` + 'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' + 'frameborder=\"0\" allowtransparency=\"true\" allow=\"encrypted-media\">' + '</iframe>' + '</div>';\n                    }\n                },\n                {\n                    name: 'youtube',\n                    url: [\n                        /^(?:m\\.)?youtube\\.com\\/watch\\?v=([\\w-]+)(?:&t=(\\d+))?/,\n                        /^(?:m\\.)?youtube\\.com\\/shorts\\/([\\w-]+)(?:\\?t=(\\d+))?/,\n                        /^(?:m\\.)?youtube\\.com\\/v\\/([\\w-]+)(?:\\?t=(\\d+))?/,\n                        /^youtube\\.com\\/embed\\/([\\w-]+)(?:\\?start=(\\d+))?/,\n                        /^youtu\\.be\\/([\\w-]+)(?:\\?t=(\\d+))?/\n                    ],\n                    html: (match)=>{\n                        const id = match[1];\n                        const time = match[2];\n                        return '<div style=\"position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;\">' + `<iframe src=\"https://www.youtube.com/embed/${id}${time ? `?start=${time}` : ''}\" ` + 'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' + 'frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen>' + '</iframe>' + '</div>';\n                    }\n                },\n                {\n                    name: 'vimeo',\n                    url: [\n                        /^vimeo\\.com\\/(\\d+)/,\n                        /^vimeo\\.com\\/[^/]+\\/[^/]+\\/video\\/(\\d+)/,\n                        /^vimeo\\.com\\/album\\/[^/]+\\/video\\/(\\d+)/,\n                        /^vimeo\\.com\\/channels\\/[^/]+\\/(\\d+)/,\n                        /^vimeo\\.com\\/groups\\/[^/]+\\/videos\\/(\\d+)/,\n                        /^vimeo\\.com\\/ondemand\\/[^/]+\\/(\\d+)/,\n                        /^player\\.vimeo\\.com\\/video\\/(\\d+)/\n                    ],\n                    html: (match)=>{\n                        const id = match[1];\n                        return '<div style=\"position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;\">' + `<iframe src=\"https://player.vimeo.com/video/${id}\" ` + 'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' + 'frameborder=\"0\" webkitallowfullscreen mozallowfullscreen allowfullscreen>' + '</iframe>' + '</div>';\n                    }\n                },\n                {\n                    name: 'instagram',\n                    url: [\n                        /^instagram\\.com\\/p\\/(\\w+)/,\n                        /^instagram\\.com\\/reel\\/(\\w+)/\n                    ]\n                },\n                {\n                    name: 'twitter',\n                    url: [\n                        /^twitter\\.com/,\n                        /^x\\.com/\n                    ]\n                },\n                {\n                    name: 'googleMaps',\n                    url: [\n                        /^google\\.com\\/maps/,\n                        /^goo\\.gl\\/maps/,\n                        /^maps\\.google\\.com/,\n                        /^maps\\.app\\.goo\\.gl/\n                    ]\n                },\n                {\n                    name: 'flickr',\n                    url: /^flickr\\.com/\n                },\n                {\n                    name: 'facebook',\n                    url: /^facebook\\.com/\n                }\n            ]\n        });\n        this.registry = new MediaRegistry(editor.locale, editor.config.get('mediaEmbed'));\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const t = editor.t;\n        const conversion = editor.conversion;\n        const renderMediaPreview = editor.config.get('mediaEmbed.previewsInData');\n        const elementName = editor.config.get('mediaEmbed.elementName');\n        const registry = this.registry;\n        editor.commands.add('mediaEmbed', new MediaEmbedCommand(editor));\n        // Configure the schema.\n        schema.register('media', {\n            inheritAllFrom: '$blockObject',\n            allowAttributes: [\n                'url'\n            ]\n        });\n        // Model -> Data\n        conversion.for('dataDowncast').elementToStructure({\n            model: 'media',\n            view: (modelElement, { writer })=>{\n                const url = modelElement.getAttribute('url');\n                return createMediaFigureElement(writer, registry, url, {\n                    elementName,\n                    renderMediaPreview: !!url && renderMediaPreview\n                });\n            }\n        });\n        // Model -> Data (url -> data-oembed-url)\n        conversion.for('dataDowncast').add(modelToViewUrlAttributeConverter(registry, {\n            elementName,\n            renderMediaPreview\n        }));\n        // Model -> View (element)\n        conversion.for('editingDowncast').elementToStructure({\n            model: 'media',\n            view: (modelElement, { writer })=>{\n                const url = modelElement.getAttribute('url');\n                const figure = createMediaFigureElement(writer, registry, url, {\n                    elementName,\n                    renderForEditingView: true\n                });\n                return toMediaWidget(figure, writer, t('media widget'));\n            }\n        });\n        // Model -> View (url -> data-oembed-url)\n        conversion.for('editingDowncast').add(modelToViewUrlAttributeConverter(registry, {\n            elementName,\n            renderForEditingView: true\n        }));\n        // View -> Model (data-oembed-url -> url)\n        conversion.for('upcast')// Upcast semantic media.\n        .elementToElement({\n            view: (element)=>[\n                    'oembed',\n                    elementName\n                ].includes(element.name) && element.getAttribute('url') ? {\n                    name: true\n                } : null,\n            model: (viewMedia, { writer })=>{\n                const url = viewMedia.getAttribute('url');\n                if (registry.hasMedia(url)) {\n                    return writer.createElement('media', {\n                        url\n                    });\n                }\n                return null;\n            }\n        })// Upcast non-semantic media.\n        .elementToElement({\n            view: {\n                name: 'div',\n                attributes: {\n                    'data-oembed-url': true\n                }\n            },\n            model: (viewMedia, { writer })=>{\n                const url = viewMedia.getAttribute('data-oembed-url');\n                if (registry.hasMedia(url)) {\n                    return writer.createElement('media', {\n                        url\n                    });\n                }\n                return null;\n            }\n        })// Consume `<figure class=\"media\">` elements, that were left after upcast.\n        .add((dispatcher)=>{\n            const converter = (evt, data, conversionApi)=>{\n                if (!conversionApi.consumable.consume(data.viewItem, {\n                    name: true,\n                    classes: 'media'\n                })) {\n                    return;\n                }\n                const { modelRange, modelCursor } = conversionApi.convertChildren(data.viewItem, data.modelCursor);\n                data.modelRange = modelRange;\n                data.modelCursor = modelCursor;\n                const modelElement = first(modelRange.getItems());\n                if (!modelElement) {\n                    // Revert consumed figure so other features can convert it.\n                    conversionApi.consumable.revert(data.viewItem, {\n                        name: true,\n                        classes: 'media'\n                    });\n                }\n            };\n            dispatcher.on('element:figure', converter);\n        });\n    }\n}\n\nconst URL_REGEXP = /^(?:http(s)?:\\/\\/)?[\\w-]+\\.[\\w-.~:/?#[\\]@!$&'()*+,;=%]+$/;\n/**\n * The auto-media embed plugin. It recognizes media links in the pasted content and embeds\n * them shortly after they are injected into the document.\n */ class AutoMediaEmbed extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Clipboard,\n            Delete,\n            Undo\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'AutoMediaEmbed';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * The paste–to–embed `setTimeout` ID. Stored as a property to allow\n\t * cleaning of the timeout.\n\t */ _timeoutId;\n    /**\n\t * The position where the `<media>` element will be inserted after the timeout,\n\t * determined each time the new content is pasted into the document.\n\t */ _positionToInsert;\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._timeoutId = null;\n        this._positionToInsert = null;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const modelDocument = editor.model.document;\n        // We need to listen on `Clipboard#inputTransformation` because we need to save positions of selection.\n        // After pasting, the content between those positions will be checked for a URL that could be transformed\n        // into media.\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        this.listenTo(clipboardPipeline, 'inputTransformation', ()=>{\n            const firstRange = modelDocument.selection.getFirstRange();\n            const leftLivePosition = LivePosition.fromPosition(firstRange.start);\n            leftLivePosition.stickiness = 'toPrevious';\n            const rightLivePosition = LivePosition.fromPosition(firstRange.end);\n            rightLivePosition.stickiness = 'toNext';\n            modelDocument.once('change:data', ()=>{\n                this._embedMediaBetweenPositions(leftLivePosition, rightLivePosition);\n                leftLivePosition.detach();\n                rightLivePosition.detach();\n            }, {\n                priority: 'high'\n            });\n        });\n        const undoCommand = editor.commands.get('undo');\n        undoCommand.on('execute', ()=>{\n            if (this._timeoutId) {\n                global.window.clearTimeout(this._timeoutId);\n                this._positionToInsert.detach();\n                this._timeoutId = null;\n                this._positionToInsert = null;\n            }\n        }, {\n            priority: 'high'\n        });\n    }\n    /**\n\t * Analyzes the part of the document between provided positions in search for a URL representing media.\n\t * When the URL is found, it is automatically converted into media.\n\t *\n\t * @param leftPosition Left position of the selection.\n\t * @param rightPosition Right position of the selection.\n\t */ _embedMediaBetweenPositions(leftPosition, rightPosition) {\n        const editor = this.editor;\n        const mediaRegistry = editor.plugins.get(MediaEmbedEditing).registry;\n        // TODO: Use marker instead of LiveRange & LivePositions.\n        const urlRange = new LiveRange(leftPosition, rightPosition);\n        const walker = urlRange.getWalker({\n            ignoreElementEnd: true\n        });\n        let url = '';\n        for (const node of walker){\n            if (node.item.is('$textProxy')) {\n                url += node.item.data;\n            }\n        }\n        url = url.trim();\n        // If the URL does not match to universal URL regexp, let's skip that.\n        if (!url.match(URL_REGEXP)) {\n            urlRange.detach();\n            return;\n        }\n        // If the URL represents a media, let's use it.\n        if (!mediaRegistry.hasMedia(url)) {\n            urlRange.detach();\n            return;\n        }\n        const mediaEmbedCommand = editor.commands.get('mediaEmbed');\n        // Do not anything if media element cannot be inserted at the current position (#47).\n        if (!mediaEmbedCommand.isEnabled) {\n            urlRange.detach();\n            return;\n        }\n        // Position won't be available in the `setTimeout` function so let's clone it.\n        this._positionToInsert = LivePosition.fromPosition(leftPosition);\n        // This action mustn't be executed if undo was called between pasting and auto-embedding.\n        this._timeoutId = global.window.setTimeout(()=>{\n            editor.model.change((writer)=>{\n                this._timeoutId = null;\n                writer.remove(urlRange);\n                urlRange.detach();\n                let insertionPosition = null;\n                // Check if position where the media element should be inserted is still valid.\n                // Otherwise leave it as undefined to use document.selection - default behavior of model.insertContent().\n                if (this._positionToInsert.root.rootName !== '$graveyard') {\n                    insertionPosition = this._positionToInsert;\n                }\n                insertMedia(editor.model, url, insertionPosition, false);\n                this._positionToInsert.detach();\n                this._positionToInsert = null;\n            });\n            editor.plugins.get(Delete).requestUndoOnBackspace();\n        }, 100);\n    }\n}\n\n/**\n * The media form view controller class.\n *\n * See {@link module:media-embed/ui/mediaformview~MediaFormView}.\n */ class MediaFormView extends View {\n    /**\n\t * Tracks information about the DOM focus in the form.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * The URL input view.\n\t */ urlInputView;\n    /**\n\t * An array of form validators used by {@link #isValid}.\n\t */ _validators;\n    /**\n\t * The default info text for the {@link #urlInputView}.\n\t */ _urlInputViewInfoDefault;\n    /**\n\t * The info text with an additional tip for the {@link #urlInputView},\n\t * displayed when the input has some value.\n\t */ _urlInputViewInfoTip;\n    /**\n\t * @param validators Form validators used by {@link #isValid}.\n\t * @param locale The localization services instance.\n\t */ constructor(validators, locale){\n        super(locale);\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.set('mediaURLInputValue', '');\n        this.urlInputView = this._createUrlInput();\n        this._validators = validators;\n        this.setTemplate({\n            tag: 'form',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-media-form',\n                    'ck-responsive-form'\n                ],\n                tabindex: '-1'\n            },\n            children: [\n                this.urlInputView\n            ]\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        submitHandler({\n            view: this\n        });\n        // Register the view in the focus tracker.\n        this.focusTracker.add(this.urlInputView.element);\n        // Start listening for the keystrokes coming from #element.\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the {@link #urlInputView}.\n\t */ focus() {\n        this.urlInputView.focus();\n    }\n    /**\n\t * The native DOM `value` of the {@link #urlInputView} element.\n\t *\n\t * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}\n\t * which works one way only and may not represent the actual state of the component in the DOM.\n\t */ get url() {\n        return this.urlInputView.fieldView.element.value.trim();\n    }\n    set url(url) {\n        this.urlInputView.fieldView.value = url.trim();\n    }\n    /**\n\t * Validates the form and returns `false` when some fields are invalid.\n\t */ isValid() {\n        this.resetFormStatus();\n        for (const validator of this._validators){\n            const errorText = validator(this);\n            // One error per field is enough.\n            if (errorText) {\n                // Apply updated error.\n                this.urlInputView.errorText = errorText;\n                return false;\n            }\n        }\n        return true;\n    }\n    /**\n\t * Cleans up the supplementary error and information text of the {@link #urlInputView}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */ resetFormStatus() {\n        this.urlInputView.errorText = null;\n        this.urlInputView.infoText = this._urlInputViewInfoDefault;\n    }\n    /**\n\t * Creates a labeled input view.\n\t *\n\t * @returns Labeled input view instance.\n\t */ _createUrlInput() {\n        const t = this.locale.t;\n        const labeledInput = new LabeledFieldView(this.locale, createLabeledInputText);\n        const inputField = labeledInput.fieldView;\n        this._urlInputViewInfoDefault = t('Paste the media URL in the input.');\n        this._urlInputViewInfoTip = t('Tip: Paste the URL into the content to embed faster.');\n        labeledInput.label = t('Media URL');\n        labeledInput.infoText = this._urlInputViewInfoDefault;\n        inputField.inputMode = 'url';\n        inputField.on('input', ()=>{\n            // Display the tip text only when there is some value. Otherwise fall back to the default info text.\n            labeledInput.infoText = inputField.element.value ? this._urlInputViewInfoTip : this._urlInputViewInfoDefault;\n            this.mediaURLInputValue = inputField.element.value.trim();\n        });\n        return labeledInput;\n    }\n}\n\nvar mediaIcon = \"<svg viewBox=\\\"0 0 22 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M1.587 1.5c-.612 0-.601-.029-.601.551v14.84c0 .59-.01.559.591.559h18.846c.602 0 .591.03.591-.56V2.052c0-.58.01-.55-.591-.55H1.587Zm.701.971h1.003v1H2.288v-1Zm16.448 0h1.003v1h-1.003v-1Zm-14.24 1h13.008v12H4.467l.029-12Zm-2.208 1h1.003v1H2.288v-1Zm16.448 0h1.003v1h-1.003v-1Zm-16.448 2h1.003v1H2.288v-1Zm16.448 0h1.003v1h-1.003v-1Zm-16.448 2h1.003v1H2.288v-1Zm16.448 0h1.003v1h-1.003v-1Zm-16.448 2h1.003v1H2.288v-1Zm16.448 0h1.003v1h-1.003v-1Zm-16.448 2h1.003l-.029 1h-.974v-1Zm16.448 0h1.003v1h-1.003v-1Zm-16.448 2h.974v1h-.974v-1Zm16.448 0h1.003v1h-1.003v-1Z\\\"/><path d=\\\"M8.374 6.648a.399.399 0 0 1 .395-.4.402.402 0 0 1 .2.049l5.148 2.824a.4.4 0 0 1 0 .7l-5.148 2.824a.403.403 0 0 1-.595-.35V6.648Z\\\"/></svg>\";\n\n/**\n * The media embed UI plugin.\n */ class MediaEmbedUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            MediaEmbedEditing,\n            Dialog\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'MediaEmbedUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    _formView;\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        editor.ui.componentFactory.add('mediaEmbed', ()=>{\n            const t = this.editor.locale.t;\n            const button = this._createDialogButton(ButtonView);\n            button.tooltip = true;\n            button.label = t('Insert media');\n            return button;\n        });\n        editor.ui.componentFactory.add('menuBar:mediaEmbed', ()=>{\n            const t = this.editor.locale.t;\n            const button = this._createDialogButton(MenuBarMenuListItemButtonView);\n            button.label = t('Media');\n            return button;\n        });\n    }\n    /**\n\t * Creates a button for menu bar that will show media embed dialog.\n\t */ _createDialogButton(ButtonClass) {\n        const editor = this.editor;\n        const buttonView = new ButtonClass(editor.locale);\n        const command = editor.commands.get('mediaEmbed');\n        const dialogPlugin = this.editor.plugins.get('Dialog');\n        buttonView.icon = mediaIcon;\n        buttonView.bind('isEnabled').to(command, 'isEnabled');\n        buttonView.on('execute', ()=>{\n            if (dialogPlugin.id === 'mediaEmbed') {\n                dialogPlugin.hide();\n            } else {\n                this._showDialog();\n            }\n        });\n        return buttonView;\n    }\n    _showDialog() {\n        const editor = this.editor;\n        const dialog = editor.plugins.get('Dialog');\n        const command = editor.commands.get('mediaEmbed');\n        const t = editor.locale.t;\n        if (!this._formView) {\n            const registry = editor.plugins.get(MediaEmbedEditing).registry;\n            this._formView = new (CssTransitionDisablerMixin(MediaFormView))(getFormValidators(editor.t, registry), editor.locale);\n            this._formView.on('submit', ()=>this._handleSubmitForm());\n        }\n        dialog.show({\n            id: 'mediaEmbed',\n            title: t('Insert media'),\n            content: this._formView,\n            isModal: true,\n            onShow: ()=>{\n                this._formView.url = command.value || '';\n                this._formView.resetFormStatus();\n                this._formView.urlInputView.fieldView.select();\n            },\n            actionButtons: [\n                {\n                    label: t('Cancel'),\n                    withText: true,\n                    onExecute: ()=>dialog.hide()\n                },\n                {\n                    label: t('Accept'),\n                    class: 'ck-button-action',\n                    withText: true,\n                    onExecute: ()=>this._handleSubmitForm()\n                }\n            ]\n        });\n    }\n    _handleSubmitForm() {\n        const editor = this.editor;\n        const dialog = editor.plugins.get('Dialog');\n        if (this._formView.isValid()) {\n            editor.execute('mediaEmbed', this._formView.url);\n            dialog.hide();\n            editor.editing.view.focus();\n        }\n    }\n}\nfunction getFormValidators(t, registry) {\n    return [\n        (form)=>{\n            if (!form.url.length) {\n                return t('The URL must not be empty.');\n            }\n        },\n        (form)=>{\n            if (!registry.hasMedia(form.url)) {\n                return t('This media URL is not supported.');\n            }\n        }\n    ];\n}\n\n/**\n * The media embed plugin.\n *\n * For a detailed overview, check the {@glink features/media-embed Media Embed feature documentation}.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * The {@link module:media-embed/mediaembedediting~MediaEmbedEditing media embed editing feature},\n * * The {@link module:media-embed/mediaembedui~MediaEmbedUI media embed UI feature} and\n * * The {@link module:media-embed/automediaembed~AutoMediaEmbed auto-media embed feature}.\n */ class MediaEmbed extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            MediaEmbedEditing,\n            MediaEmbedUI,\n            AutoMediaEmbed,\n            Widget\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'MediaEmbed';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The media embed toolbar plugin. It creates a toolbar for media embed that shows up when the media element is selected.\n *\n * Instances of toolbar components (e.g. buttons) are created based on the\n * {@link module:media-embed/mediaembedconfig~MediaEmbedConfig#toolbar `media.toolbar` configuration option}.\n */ class MediaEmbedToolbar extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            WidgetToolbarRepository\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'MediaEmbedToolbar';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        const t = editor.t;\n        const widgetToolbarRepository = editor.plugins.get(WidgetToolbarRepository);\n        widgetToolbarRepository.register('mediaEmbed', {\n            ariaLabel: t('Media toolbar'),\n            items: editor.config.get('mediaEmbed.toolbar') || [],\n            getRelatedElement: getSelectedMediaViewWidget\n        });\n    }\n}\n\nexport { AutoMediaEmbed, MediaEmbed, MediaEmbedEditing, MediaEmbedToolbar, MediaEmbedUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/converters\n */\n\nimport type { GetCallback } from 'ckeditor5/src/utils.js';\nimport type { DowncastAttributeEvent, DowncastDispatcher, Element, ViewElement } from 'ckeditor5/src/engine.js';\nimport type MediaRegistry from './mediaregistry.js';\nimport type { MediaOptions } from './utils.js';\n\n/**\n * Returns a function that converts the model \"url\" attribute to the view representation.\n *\n * Depending on the configuration, the view representation can be \"semantic\" (for the data pipeline):\n *\n * ```html\n * <figure class=\"media\">\n * \t<oembed url=\"foo\"></oembed>\n * </figure>\n * ```\n *\n * or \"non-semantic\" (for the editing view pipeline):\n *\n * ```html\n * <figure class=\"media\">\n * \t<div data-oembed-url=\"foo\">[ non-semantic media preview for \"foo\" ]</div>\n * </figure>\n * ```\n *\n * **Note:** Changing the model \"url\" attribute replaces the entire content of the\n * `<figure>` in the view.\n *\n * @param registry The registry providing\n * the media and their content.\n * @param options options object with following properties:\n * - elementName When set, overrides the default element name for semantic media embeds.\n * - renderMediaPreview When `true`, the converter will create the view in the non-semantic form.\n * - renderForEditingView When `true`, the converter will create a view specific for the\n * editing pipeline (e.g. including CSS classes, content placeholders).\n */\nexport function modelToViewUrlAttributeConverter(\n\tregistry: MediaRegistry,\n\toptions: MediaOptions\n): ( dispatcher: DowncastDispatcher ) => void {\n\tconst converter: GetCallback<DowncastAttributeEvent> = ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = data.attributeNewValue as string;\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst figure = conversionApi.mapper.toViewElement( data.item as Element )!;\n\t\tconst mediaContentElement = [ ...figure.getChildren() ]\n\t\t\t.find( child => ( child as ViewElement ).getCustomProperty( 'media-content' ) )!;\n\n\t\t// TODO: removing the wrapper and creating it from scratch is a hack. We can do better than that.\n\t\tviewWriter.remove( mediaContentElement );\n\n\t\tconst mediaViewElement = registry.getMediaViewElement( viewWriter, url, options );\n\n\t\tviewWriter.insert( viewWriter.createPositionAt( figure, 0 ), mediaViewElement );\n\t};\n\n\treturn dispatcher => {\n\t\tdispatcher.on<DowncastAttributeEvent>( 'attribute:url:media', converter );\n\t};\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/utils\n */\n\nimport type {\n\tViewContainerElement,\n\tElement,\n\tModel,\n\tSelectable,\n\tSelection,\n\tDowncastWriter,\n\tViewDocumentSelection,\n\tViewElement,\n\tDocumentSelection\n} from 'ckeditor5/src/engine.js';\nimport { isWidget, toWidget } from 'ckeditor5/src/widget.js';\nimport type MediaRegistry from './mediaregistry.js';\n\n/**\n * Converts a given {@link module:engine/view/element~Element} to a media embed widget:\n * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the media widget element.\n * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n *\n * @param writer An instance of the view writer.\n * @param label The element's label.\n */\nexport function toMediaWidget( viewElement: ViewElement, writer: DowncastWriter, label: string ): ViewElement {\n\twriter.setCustomProperty( 'media', true, viewElement );\n\n\treturn toWidget( viewElement, writer, { label } );\n}\n\n/**\n * Returns a media widget editing view element if one is selected.\n */\nexport function getSelectedMediaViewWidget( selection: ViewDocumentSelection ): ViewElement | null {\n\tconst viewElement = selection.getSelectedElement();\n\n\tif ( viewElement && isMediaWidget( viewElement ) ) {\n\t\treturn viewElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Checks if a given view element is a media widget.\n */\nexport function isMediaWidget( viewElement: ViewElement ): boolean {\n\treturn !!viewElement.getCustomProperty( 'media' ) && isWidget( viewElement );\n}\n\n/**\n * Creates a view element representing the media. Either a \"semantic\" one for the data pipeline:\n *\n * ```html\n * <figure class=\"media\">\n * \t<oembed url=\"foo\"></oembed>\n * </figure>\n * ```\n *\n * or a \"non-semantic\" (for the editing view pipeline):\n *\n * ```html\n * <figure class=\"media\">\n * \t<div data-oembed-url=\"foo\">[ non-semantic media preview for \"foo\" ]</div>\n * </figure>\n * ```\n */\nexport function createMediaFigureElement(\n\twriter: DowncastWriter,\n\tregistry: MediaRegistry,\n\turl: string,\n\toptions: MediaOptions\n): ViewContainerElement {\n\treturn writer.createContainerElement( 'figure', { class: 'media' }, [\n\t\tregistry.getMediaViewElement( writer, url, options ),\n\t\twriter.createSlot()\n\t] );\n}\n\n/**\n * Returns a selected media element in the model, if any.\n */\nexport function getSelectedMediaModelWidget( selection: Selection | DocumentSelection ): Element | null {\n\tconst selectedElement = selection.getSelectedElement();\n\n\tif ( selectedElement && selectedElement.is( 'element', 'media' ) ) {\n\t\treturn selectedElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Creates a media element and inserts it into the model.\n *\n * **Note**: This method will use {@link module:engine/model/model~Model#insertContent `model.insertContent()`} logic of inserting content\n * if no `insertPosition` is passed.\n *\n * @param url An URL of an embeddable media.\n * @param findOptimalPosition If true it will try to find optimal position to insert media without breaking content\n * in which a selection is.\n */\nexport function insertMedia( model: Model, url: string, selectable: Selectable, findOptimalPosition: boolean ): void {\n\tmodel.change( writer => {\n\t\tconst mediaElement = writer.createElement( 'media', { url } );\n\n\t\tmodel.insertObject( mediaElement, selectable, null, {\n\t\t\tsetSelection: 'on',\n\t\t\tfindOptimalPosition: findOptimalPosition ? 'auto' : undefined\n\t\t} );\n\t} );\n}\n\n/**\n * Type for commonly grouped function parameters across this package.\n */\nexport type MediaOptions = {\n\telementName: string;\n\trenderMediaPreview?: boolean;\n\trenderForEditingView?: boolean;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/mediaembedcommand\n */\n\nimport type { DocumentSelection, Element, Model, Selection } from 'ckeditor5/src/engine.js';\nimport { Command } from 'ckeditor5/src/core.js';\nimport { findOptimalInsertionRange } from 'ckeditor5/src/widget.js';\n\nimport { getSelectedMediaModelWidget, insertMedia } from './utils.js';\n\n/**\n * The insert media command.\n *\n * The command is registered by the {@link module:media-embed/mediaembedediting~MediaEmbedEditing} as `'mediaEmbed'`.\n *\n * To insert media at the current selection, execute the command and specify the URL:\n *\n * ```ts\n * editor.execute( 'mediaEmbed', 'http://url.to.the/media' );\n * ```\n */\nexport default class MediaEmbedCommand extends Command {\n\t/**\n\t * Media url.\n\t */\n\tdeclare public value: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedMedia = getSelectedMediaModelWidget( selection );\n\n\t\tthis.value = selectedMedia ? selectedMedia.getAttribute( 'url' ) as string : undefined;\n\n\t\tthis.isEnabled = isMediaSelected( selection ) || isAllowedInParent( selection, model );\n\t}\n\n\t/**\n\t * Executes the command, which either:\n\t *\n\t * * updates the URL of the selected media,\n\t * * inserts the new media into the editor and puts the selection around it.\n\t *\n\t * @fires execute\n\t * @param url The URL of the media.\n\t */\n\tpublic override execute( url: string ): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedMedia = getSelectedMediaModelWidget( selection );\n\n\t\tif ( selectedMedia ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setAttribute( 'url', url, selectedMedia );\n\t\t\t} );\n\t\t} else {\n\t\t\tinsertMedia( model, url, selection, true );\n\t\t}\n\t}\n}\n\n/**\n * Checks if the media embed is allowed in the parent.\n */\nfunction isAllowedInParent( selection: Selection | DocumentSelection, model: Model ): boolean {\n\tconst insertionRange = findOptimalInsertionRange( selection, model );\n\tlet parent = insertionRange.start.parent as Element;\n\n\t// The model.insertContent() will remove empty parent (unless it is a $root or a limit).\n\tif ( parent.isEmpty && !model.schema.isLimit( parent ) ) {\n\t\tparent = parent.parent as Element;\n\t}\n\n\treturn model.schema.checkChild( parent, 'media' );\n}\n\n/**\n * Checks if the media object is selected.\n */\nfunction isMediaSelected( selection: Selection | DocumentSelection ): boolean {\n\tconst element = selection.getSelectedElement();\n\treturn !!element && element.name === 'media';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/mediaregistry\n */\n\nimport type { DowncastWriter, ViewElement } from 'ckeditor5/src/engine.js';\nimport { IconView, Template } from 'ckeditor5/src/ui.js';\nimport { type Locale, logWarning, toArray } from 'ckeditor5/src/utils.js';\n\nimport mediaPlaceholderIcon from '../theme/icons/media-placeholder.svg';\nimport type { MediaEmbedConfig, MediaEmbedProvider } from './mediaembedconfig.js';\nimport type { MediaOptions } from './utils.js';\n\nconst mediaPlaceholderIconViewBox = '0 0 64 42';\n\n/**\n * A bridge between the raw media content provider definitions and the editor view content.\n *\n * It helps translating media URLs to corresponding {@link module:engine/view/element~Element view elements}.\n *\n * Mostly used by the {@link module:media-embed/mediaembedediting~MediaEmbedEditing} plugin.\n */\nexport default class MediaRegistry {\n\t/**\n\t * The {@link module:utils/locale~Locale} instance.\n\t */\n\tpublic locale: Locale;\n\n\t/**\n\t * The media provider definitions available for the registry. Usually corresponding with the\n\t * {@link module:media-embed/mediaembedconfig~MediaEmbedConfig media configuration}.\n\t */\n\tpublic providerDefinitions: Array<MediaEmbedProvider>;\n\n\t/**\n\t * Creates an instance of the {@link module:media-embed/mediaregistry~MediaRegistry} class.\n\t *\n\t * @param locale The localization services instance.\n\t * @param config The configuration of the media embed feature.\n\t */\n\tconstructor( locale: Locale, config: MediaEmbedConfig ) {\n\t\tconst providers = config.providers!;\n\t\tconst extraProviders = config.extraProviders || [];\n\t\tconst removedProviders = new Set( config.removeProviders );\n\t\tconst providerDefinitions = providers\n\t\t\t.concat( extraProviders )\n\t\t\t.filter( provider => {\n\t\t\t\tconst name = provider.name;\n\n\t\t\t\tif ( !name ) {\n\t\t\t\t\t/**\n\t\t\t\t\t * One of the providers (or extra providers) specified in the media embed configuration\n\t\t\t\t\t * has no name and will not be used by the editor. In order to get this media\n\t\t\t\t\t * provider working, double check your editor configuration.\n\t\t\t\t\t *\n\t\t\t\t\t * @error media-embed-no-provider-name\n\t\t\t\t\t */\n\t\t\t\t\tlogWarning( 'media-embed-no-provider-name', { provider } );\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn !removedProviders.has( name );\n\t\t\t} );\n\n\t\tthis.locale = locale;\n\t\tthis.providerDefinitions = providerDefinitions;\n\t}\n\n\t/**\n\t * Checks whether the passed URL is representing a certain media type allowed in the editor.\n\t *\n\t * @param url The URL to be checked\n\t */\n\tpublic hasMedia( url: string ): boolean {\n\t\treturn !!this._getMedia( url );\n\t}\n\n\t/**\n\t * For the given media URL string and options, it returns the {@link module:engine/view/element~Element view element}\n\t * representing that media.\n\t *\n\t * **Note:** If no URL is specified, an empty view element is returned.\n\t *\n\t * @param writer The view writer used to produce a view element.\n\t * @param url The URL to be translated into a view element.\n\t */\n\tpublic getMediaViewElement(\n\t\twriter: DowncastWriter,\n\t\turl: string,\n\t\toptions: MediaOptions\n\t): ViewElement {\n\t\treturn this._getMedia( url )!.getViewElement( writer, options );\n\t}\n\n\t/**\n\t * Returns a `Media` instance for the given URL.\n\t *\n\t * @param url The URL of the media.\n\t * @returns The `Media` instance or `null` when there is none.\n\t */\n\tprivate _getMedia( url: string ): Media | null {\n\t\tif ( !url ) {\n\t\t\treturn new Media( this.locale );\n\t\t}\n\n\t\turl = url.trim();\n\n\t\tfor ( const definition of this.providerDefinitions ) {\n\t\t\tconst previewRenderer = definition.html!;\n\t\t\tconst pattern = toArray( definition.url );\n\n\t\t\tfor ( const subPattern of pattern ) {\n\t\t\t\tconst match = this._getUrlMatches( url, subPattern );\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\treturn new Media( this.locale, url, match, previewRenderer );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Tries to match `url` to `pattern`.\n\t *\n\t * @param url The URL of the media.\n\t * @param pattern The pattern that should accept the media URL.\n\t */\n\tprivate _getUrlMatches( url: string, pattern: RegExp ): RegExpMatchArray | null {\n\t\t// 1. Try to match without stripping the protocol and \"www\" subdomain.\n\t\tlet match = url.match( pattern );\n\n\t\tif ( match ) {\n\t\t\treturn match;\n\t\t}\n\n\t\t// 2. Try to match after stripping the protocol.\n\t\tlet rawUrl = url.replace( /^https?:\\/\\//, '' );\n\t\tmatch = rawUrl.match( pattern );\n\n\t\tif ( match ) {\n\t\t\treturn match;\n\t\t}\n\n\t\t// 3. Try to match after stripping the \"www\" subdomain.\n\t\trawUrl = rawUrl.replace( /^www\\./, '' );\n\t\tmatch = rawUrl.match( pattern );\n\n\t\tif ( match ) {\n\t\t\treturn match;\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\n/**\n * Represents media defined by the provider configuration.\n *\n * It can be rendered to the {@link module:engine/view/element~Element view element} and used in the editing or data pipeline.\n */\nclass Media {\n\t/**\n\t * The URL this Media instance represents.\n\t */\n\tpublic url: string | null;\n\n\t/**\n\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t *\n\t * @see module:utils/locale~Locale#t\n\t */\n\tprivate _locale: Locale;\n\n\t/**\n\t * The output of the `RegExp.match` which validated the {@link #url} of this media.\n\t */\n\tprivate _match?: RegExpMatchArray;\n\n\t/**\n\t * The function returning the HTML string preview of this media.\n\t */\n\tprivate _previewRenderer?: ( match: RegExpMatchArray ) => string;\n\n\tconstructor( locale: Locale, url?: string, match?: RegExpMatchArray, previewRenderer?: ( match: RegExpMatchArray ) => string ) {\n\t\tthis.url = this._getValidUrl( url );\n\t\tthis._locale = locale;\n\t\tthis._match = match;\n\t\tthis._previewRenderer = previewRenderer;\n\t}\n\n\t/**\n\t * Returns the view element representation of the media.\n\t *\n\t * @param writer The view writer used to produce a view element.\n\t */\n\tpublic getViewElement(\n\t\twriter: DowncastWriter,\n\t\toptions: MediaOptions\n\t): ViewElement {\n\t\tconst attributes: Record<string, unknown> = {};\n\t\tlet viewElement;\n\n\t\tif ( options.renderForEditingView || ( options.renderMediaPreview && this.url && this._previewRenderer ) ) {\n\t\t\tif ( this.url ) {\n\t\t\t\tattributes[ 'data-oembed-url' ] = this.url;\n\t\t\t}\n\n\t\t\tif ( options.renderForEditingView ) {\n\t\t\t\tattributes.class = 'ck-media__wrapper';\n\t\t\t}\n\n\t\t\tconst mediaHtml = this._getPreviewHtml( options );\n\n\t\t\tviewElement = writer.createRawElement( 'div', attributes, ( domElement, domConverter ) => {\n\t\t\t\tdomConverter!.setContentOf( domElement, mediaHtml );\n\t\t\t} );\n\t\t} else {\n\t\t\tif ( this.url ) {\n\t\t\t\tattributes.url = this.url;\n\t\t\t}\n\n\t\t\tviewElement = writer.createEmptyElement( options.elementName, attributes );\n\t\t}\n\n\t\twriter.setCustomProperty( 'media-content', true, viewElement );\n\n\t\treturn viewElement;\n\t}\n\n\t/**\n\t * Returns the HTML string of the media content preview.\n\t */\n\tprivate _getPreviewHtml( options: { renderForEditingView?: boolean } ): string {\n\t\tif ( this._previewRenderer ) {\n\t\t\treturn this._previewRenderer( this._match! );\n\t\t} else {\n\t\t\t// The placeholder only makes sense for editing view and media which have URLs.\n\t\t\t// Placeholder is never displayed in data and URL-less media have no content.\n\t\t\tif ( this.url && options.renderForEditingView ) {\n\t\t\t\treturn this._getPlaceholderHtml();\n\t\t\t}\n\n\t\t\treturn '';\n\t\t}\n\t}\n\n\t/**\n\t * Returns the placeholder HTML when the media has no content preview.\n\t */\n\tprivate _getPlaceholderHtml(): string {\n\t\tconst icon = new IconView();\n\t\tconst t = this._locale.t;\n\n\t\ticon.content = mediaPlaceholderIcon;\n\t\ticon.viewBox = mediaPlaceholderIconViewBox;\n\n\t\tconst placeholder = new Template( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck ck-reset_all ck-media__placeholder'\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: 'ck-media__placeholder__icon'\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [ icon ]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'a',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: 'ck-media__placeholder__url',\n\t\t\t\t\t\ttarget: '_blank',\n\t\t\t\t\t\trel: 'noopener noreferrer',\n\t\t\t\t\t\thref: this.url,\n\t\t\t\t\t\t'data-cke-tooltip-text': t( 'Open media in new tab' )\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttag: 'span',\n\t\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\t\tclass: 'ck-media__placeholder__url__text'\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tchildren: [ this.url ]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t} ).render() as HTMLElement;\n\n\t\treturn placeholder.outerHTML;\n\t}\n\n\t/**\n\t * Returns the full URL to the specified media.\n\t *\n\t * @param url The URL of the media.\n\t */\n\tprivate _getValidUrl( url: string | undefined ): string | null {\n\t\tif ( !url ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( url.match( /^https?/ ) ) {\n\t\t\treturn url;\n\t\t}\n\n\t\treturn 'https://' + url;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/mediaembedediting\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport type { UpcastElementEvent } from 'ckeditor5/src/engine.js';\nimport { first, type GetCallback } from 'ckeditor5/src/utils.js';\n\nimport { modelToViewUrlAttributeConverter } from './converters.js';\nimport type { MediaEmbedConfig } from './mediaembedconfig.js';\nimport MediaEmbedCommand from './mediaembedcommand.js';\nimport MediaRegistry from './mediaregistry.js';\nimport { toMediaWidget, createMediaFigureElement } from './utils.js';\n\nimport '../theme/mediaembedediting.css';\n\n/**\n * The media embed editing feature.\n */\nexport default class MediaEmbedEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'MediaEmbedEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * The media registry managing the media providers in the editor.\n\t */\n\tpublic registry: MediaRegistry;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\t\teditor.config.define( 'mediaEmbed', {\n\t\t\telementName: 'oembed',\n\t\t\tproviders: [\n\t\t\t\t{\n\t\t\t\t\tname: 'dailymotion',\n\t\t\t\t\turl: [\n\t\t\t\t\t\t/^dailymotion\\.com\\/video\\/(\\w+)/,\n\t\t\t\t\t\t/^dai.ly\\/(\\w+)/\n\t\t\t\t\t],\n\t\t\t\t\thtml: match => {\n\t\t\t\t\t\tconst id = match[ 1 ];\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t'<div style=\"position: relative; padding-bottom: 100%; height: 0; \">' +\n\t\t\t\t\t\t\t\t`<iframe src=\"https://www.dailymotion.com/embed/video/${ id }\" ` +\n\t\t\t\t\t\t\t\t\t'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' +\n\t\t\t\t\t\t\t\t\t'frameborder=\"0\" width=\"480\" height=\"270\" allowfullscreen allow=\"autoplay\">' +\n\t\t\t\t\t\t\t\t'</iframe>' +\n\t\t\t\t\t\t\t'</div>'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t{\n\t\t\t\t\tname: 'spotify',\n\t\t\t\t\turl: [\n\t\t\t\t\t\t/^open\\.spotify\\.com\\/(artist\\/\\w+)/,\n\t\t\t\t\t\t/^open\\.spotify\\.com\\/(album\\/\\w+)/,\n\t\t\t\t\t\t/^open\\.spotify\\.com\\/(track\\/\\w+)/\n\t\t\t\t\t],\n\t\t\t\t\thtml: match => {\n\t\t\t\t\t\tconst id = match[ 1 ];\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t'<div style=\"position: relative; padding-bottom: 100%; height: 0; padding-bottom: 126%;\">' +\n\t\t\t\t\t\t\t\t`<iframe src=\"https://open.spotify.com/embed/${ id }\" ` +\n\t\t\t\t\t\t\t\t\t'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' +\n\t\t\t\t\t\t\t\t\t'frameborder=\"0\" allowtransparency=\"true\" allow=\"encrypted-media\">' +\n\t\t\t\t\t\t\t\t'</iframe>' +\n\t\t\t\t\t\t\t'</div>'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t{\n\t\t\t\t\tname: 'youtube',\n\t\t\t\t\turl: [\n\t\t\t\t\t\t/^(?:m\\.)?youtube\\.com\\/watch\\?v=([\\w-]+)(?:&t=(\\d+))?/,\n\t\t\t\t\t\t/^(?:m\\.)?youtube\\.com\\/shorts\\/([\\w-]+)(?:\\?t=(\\d+))?/,\n\t\t\t\t\t\t/^(?:m\\.)?youtube\\.com\\/v\\/([\\w-]+)(?:\\?t=(\\d+))?/,\n\t\t\t\t\t\t/^youtube\\.com\\/embed\\/([\\w-]+)(?:\\?start=(\\d+))?/,\n\t\t\t\t\t\t/^youtu\\.be\\/([\\w-]+)(?:\\?t=(\\d+))?/\n\t\t\t\t\t],\n\t\t\t\t\thtml: match => {\n\t\t\t\t\t\tconst id = match[ 1 ];\n\t\t\t\t\t\tconst time = match[ 2 ];\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t'<div style=\"position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;\">' +\n\t\t\t\t\t\t\t\t`<iframe src=\"https://www.youtube.com/embed/${ id }${ time ? `?start=${ time }` : '' }\" ` +\n\t\t\t\t\t\t\t\t\t'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' +\n\t\t\t\t\t\t\t\t\t'frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen>' +\n\t\t\t\t\t\t\t\t'</iframe>' +\n\t\t\t\t\t\t\t'</div>'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t{\n\t\t\t\t\tname: 'vimeo',\n\t\t\t\t\turl: [\n\t\t\t\t\t\t/^vimeo\\.com\\/(\\d+)/,\n\t\t\t\t\t\t/^vimeo\\.com\\/[^/]+\\/[^/]+\\/video\\/(\\d+)/,\n\t\t\t\t\t\t/^vimeo\\.com\\/album\\/[^/]+\\/video\\/(\\d+)/,\n\t\t\t\t\t\t/^vimeo\\.com\\/channels\\/[^/]+\\/(\\d+)/,\n\t\t\t\t\t\t/^vimeo\\.com\\/groups\\/[^/]+\\/videos\\/(\\d+)/,\n\t\t\t\t\t\t/^vimeo\\.com\\/ondemand\\/[^/]+\\/(\\d+)/,\n\t\t\t\t\t\t/^player\\.vimeo\\.com\\/video\\/(\\d+)/\n\t\t\t\t\t],\n\t\t\t\t\thtml: match => {\n\t\t\t\t\t\tconst id = match[ 1 ];\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t'<div style=\"position: relative; padding-bottom: 100%; height: 0; padding-bottom: 56.2493%;\">' +\n\t\t\t\t\t\t\t\t`<iframe src=\"https://player.vimeo.com/video/${ id }\" ` +\n\t\t\t\t\t\t\t\t\t'style=\"position: absolute; width: 100%; height: 100%; top: 0; left: 0;\" ' +\n\t\t\t\t\t\t\t\t\t'frameborder=\"0\" webkitallowfullscreen mozallowfullscreen allowfullscreen>' +\n\t\t\t\t\t\t\t\t'</iframe>' +\n\t\t\t\t\t\t\t'</div>'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t{\n\t\t\t\t\tname: 'instagram',\n\t\t\t\t\turl: [\n\t\t\t\t\t\t/^instagram\\.com\\/p\\/(\\w+)/,\n\t\t\t\t\t\t/^instagram\\.com\\/reel\\/(\\w+)/\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'twitter',\n\t\t\t\t\turl: [\n\t\t\t\t\t\t/^twitter\\.com/,\n\t\t\t\t\t\t/^x\\.com/\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'googleMaps',\n\t\t\t\t\turl: [\n\t\t\t\t\t\t/^google\\.com\\/maps/,\n\t\t\t\t\t\t/^goo\\.gl\\/maps/,\n\t\t\t\t\t\t/^maps\\.google\\.com/,\n\t\t\t\t\t\t/^maps\\.app\\.goo\\.gl/\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'flickr',\n\t\t\t\t\turl: /^flickr\\.com/\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'facebook',\n\t\t\t\t\turl: /^facebook\\.com/\n\t\t\t\t}\n\t\t\t]\n\t\t} as MediaEmbedConfig );\n\n\t\tthis.registry = new MediaRegistry( editor.locale, editor.config.get( 'mediaEmbed' )! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst t = editor.t;\n\t\tconst conversion = editor.conversion;\n\t\tconst renderMediaPreview = editor.config.get( 'mediaEmbed.previewsInData' );\n\t\tconst elementName = editor.config.get( 'mediaEmbed.elementName' )!;\n\n\t\tconst registry = this.registry;\n\n\t\teditor.commands.add( 'mediaEmbed', new MediaEmbedCommand( editor ) );\n\n\t\t// Configure the schema.\n\t\tschema.register( 'media', {\n\t\t\tinheritAllFrom: '$blockObject',\n\t\t\tallowAttributes: [ 'url' ]\n\t\t} );\n\n\t\t// Model -> Data\n\t\tconversion.for( 'dataDowncast' ).elementToStructure( {\n\t\t\tmodel: 'media',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tconst url = modelElement.getAttribute( 'url' ) as string;\n\n\t\t\t\treturn createMediaFigureElement( writer, registry, url, {\n\t\t\t\t\telementName,\n\t\t\t\t\trenderMediaPreview: !!url && renderMediaPreview\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\t// Model -> Data (url -> data-oembed-url)\n\t\tconversion.for( 'dataDowncast' ).add(\n\t\t\tmodelToViewUrlAttributeConverter( registry, {\n\t\t\t\telementName,\n\t\t\t\trenderMediaPreview\n\t\t\t} ) );\n\n\t\t// Model -> View (element)\n\t\tconversion.for( 'editingDowncast' ).elementToStructure( {\n\t\t\tmodel: 'media',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tconst url = modelElement.getAttribute( 'url' ) as string;\n\t\t\t\tconst figure = createMediaFigureElement( writer, registry, url, {\n\t\t\t\t\telementName,\n\t\t\t\t\trenderForEditingView: true\n\t\t\t\t} );\n\n\t\t\t\treturn toMediaWidget( figure, writer, t( 'media widget' ) );\n\t\t\t}\n\t\t} );\n\n\t\t// Model -> View (url -> data-oembed-url)\n\t\tconversion.for( 'editingDowncast' ).add(\n\t\t\tmodelToViewUrlAttributeConverter( registry, {\n\t\t\t\telementName,\n\t\t\t\trenderForEditingView: true\n\t\t\t} ) );\n\n\t\t// View -> Model (data-oembed-url -> url)\n\t\tconversion.for( 'upcast' )\n\t\t\t// Upcast semantic media.\n\t\t\t.elementToElement( {\n\t\t\t\tview: element => [ 'oembed', elementName ].includes( element.name ) && element.getAttribute( 'url' ) ?\n\t\t\t\t\t{ name: true } :\n\t\t\t\t\tnull,\n\t\t\t\tmodel: ( viewMedia, { writer } ) => {\n\t\t\t\t\tconst url = viewMedia.getAttribute( 'url' ) as string;\n\n\t\t\t\t\tif ( registry.hasMedia( url ) ) {\n\t\t\t\t\t\treturn writer.createElement( 'media', { url } );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t} )\n\t\t\t// Upcast non-semantic media.\n\t\t\t.elementToElement( {\n\t\t\t\tview: {\n\t\t\t\t\tname: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\t'data-oembed-url': true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmodel: ( viewMedia, { writer } ) => {\n\t\t\t\t\tconst url = viewMedia.getAttribute( 'data-oembed-url' ) as string;\n\n\t\t\t\t\tif ( registry.hasMedia( url ) ) {\n\t\t\t\t\t\treturn writer.createElement( 'media', { url } );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t} )\n\t\t\t// Consume `<figure class=\"media\">` elements, that were left after upcast.\n\t\t\t.add( dispatcher => {\n\t\t\t\tconst converter: GetCallback<UpcastElementEvent> = ( evt, data, conversionApi ) => {\n\t\t\t\t\tif ( !conversionApi.consumable.consume( data.viewItem, { name: true, classes: 'media' } ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { modelRange, modelCursor } = conversionApi.convertChildren( data.viewItem, data.modelCursor );\n\n\t\t\t\t\tdata.modelRange = modelRange;\n\t\t\t\t\tdata.modelCursor = modelCursor;\n\n\t\t\t\t\tconst modelElement = first( modelRange!.getItems() );\n\n\t\t\t\t\tif ( !modelElement ) {\n\t\t\t\t\t\t// Revert consumed figure so other features can convert it.\n\t\t\t\t\t\tconversionApi.consumable.revert( data.viewItem, { name: true, classes: 'media' } );\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tdispatcher.on<UpcastElementEvent>( 'element:figure', converter );\n\t\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/automediaembed\n */\n\nimport { type Editor, Plugin } from 'ckeditor5/src/core.js';\nimport { LiveRange, LivePosition } from 'ckeditor5/src/engine.js';\nimport { Clipboard, type ClipboardPipeline } from 'ckeditor5/src/clipboard.js';\nimport { Delete } from 'ckeditor5/src/typing.js';\nimport { Undo, type UndoCommand } from 'ckeditor5/src/undo.js';\nimport { global } from 'ckeditor5/src/utils.js';\n\nimport MediaEmbedEditing from './mediaembedediting.js';\nimport { insertMedia } from './utils.js';\nimport type MediaEmbedCommand from './mediaembedcommand.js';\n\nconst URL_REGEXP = /^(?:http(s)?:\\/\\/)?[\\w-]+\\.[\\w-.~:/?#[\\]@!$&'()*+,;=%]+$/;\n\n/**\n * The auto-media embed plugin. It recognizes media links in the pasted content and embeds\n * them shortly after they are injected into the document.\n */\nexport default class AutoMediaEmbed extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Clipboard, Delete, Undo ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'AutoMediaEmbed' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * The paste–to–embed `setTimeout` ID. Stored as a property to allow\n\t * cleaning of the timeout.\n\t */\n\tprivate _timeoutId: number | null;\n\n\t/**\n\t * The position where the `<media>` element will be inserted after the timeout,\n\t * determined each time the new content is pasted into the document.\n\t */\n\tprivate _positionToInsert: LivePosition | null;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._timeoutId = null;\n\t\tthis._positionToInsert = null;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst modelDocument = editor.model.document;\n\n\t\t// We need to listen on `Clipboard#inputTransformation` because we need to save positions of selection.\n\t\t// After pasting, the content between those positions will be checked for a URL that could be transformed\n\t\t// into media.\n\t\tconst clipboardPipeline: ClipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\t\tthis.listenTo( clipboardPipeline, 'inputTransformation', () => {\n\t\t\tconst firstRange = modelDocument.selection.getFirstRange()!;\n\n\t\t\tconst leftLivePosition = LivePosition.fromPosition( firstRange.start );\n\t\t\tleftLivePosition.stickiness = 'toPrevious';\n\n\t\t\tconst rightLivePosition = LivePosition.fromPosition( firstRange.end );\n\t\t\trightLivePosition.stickiness = 'toNext';\n\n\t\t\tmodelDocument.once( 'change:data', () => {\n\t\t\t\tthis._embedMediaBetweenPositions( leftLivePosition, rightLivePosition );\n\n\t\t\t\tleftLivePosition.detach();\n\t\t\t\trightLivePosition.detach();\n\t\t\t}, { priority: 'high' } );\n\t\t} );\n\n\t\tconst undoCommand: UndoCommand = editor.commands.get( 'undo' )!;\n\t\tundoCommand.on( 'execute', () => {\n\t\t\tif ( this._timeoutId ) {\n\t\t\t\tglobal.window.clearTimeout( this._timeoutId );\n\t\t\t\tthis._positionToInsert!.detach();\n\n\t\t\t\tthis._timeoutId = null;\n\t\t\t\tthis._positionToInsert = null;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Analyzes the part of the document between provided positions in search for a URL representing media.\n\t * When the URL is found, it is automatically converted into media.\n\t *\n\t * @param leftPosition Left position of the selection.\n\t * @param rightPosition Right position of the selection.\n\t */\n\tprivate _embedMediaBetweenPositions( leftPosition: LivePosition, rightPosition: LivePosition ): void {\n\t\tconst editor = this.editor;\n\t\tconst mediaRegistry = editor.plugins.get( MediaEmbedEditing ).registry;\n\t\t// TODO: Use marker instead of LiveRange & LivePositions.\n\t\tconst urlRange = new LiveRange( leftPosition, rightPosition );\n\t\tconst walker = urlRange.getWalker( { ignoreElementEnd: true } );\n\n\t\tlet url = '';\n\n\t\tfor ( const node of walker ) {\n\t\t\tif ( node.item.is( '$textProxy' ) ) {\n\t\t\t\turl += node.item.data;\n\t\t\t}\n\t\t}\n\n\t\turl = url.trim();\n\n\t\t// If the URL does not match to universal URL regexp, let's skip that.\n\t\tif ( !url.match( URL_REGEXP ) ) {\n\t\t\turlRange.detach();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// If the URL represents a media, let's use it.\n\t\tif ( !mediaRegistry.hasMedia( url ) ) {\n\t\t\turlRange.detach();\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst mediaEmbedCommand: MediaEmbedCommand = editor.commands.get( 'mediaEmbed' )!;\n\n\t\t// Do not anything if media element cannot be inserted at the current position (#47).\n\t\tif ( !mediaEmbedCommand.isEnabled ) {\n\t\t\turlRange.detach();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Position won't be available in the `setTimeout` function so let's clone it.\n\t\tthis._positionToInsert = LivePosition.fromPosition( leftPosition );\n\n\t\t// This action mustn't be executed if undo was called between pasting and auto-embedding.\n\t\tthis._timeoutId = global.window.setTimeout( () => {\n\t\t\teditor.model.change( writer => {\n\t\t\t\tthis._timeoutId = null;\n\n\t\t\t\twriter.remove( urlRange );\n\t\t\t\turlRange.detach();\n\n\t\t\t\tlet insertionPosition: LivePosition | null = null;\n\n\t\t\t\t// Check if position where the media element should be inserted is still valid.\n\t\t\t\t// Otherwise leave it as undefined to use document.selection - default behavior of model.insertContent().\n\t\t\t\tif ( this._positionToInsert!.root.rootName !== '$graveyard' ) {\n\t\t\t\t\tinsertionPosition = this._positionToInsert;\n\t\t\t\t}\n\n\t\t\t\tinsertMedia( editor.model, url, insertionPosition, false );\n\n\t\t\t\tthis._positionToInsert!.detach();\n\t\t\t\tthis._positionToInsert = null;\n\t\t\t} );\n\n\t\t\teditor.plugins.get( Delete ).requestUndoOnBackspace();\n\t\t}, 100 );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/ui/mediaformview\n */\n\nimport {\n\ttype InputTextView,\n\tLabeledFieldView,\n\tView,\n\tcreateLabeledInputText,\n\tsubmitHandler\n} from 'ckeditor5/src/ui.js';\nimport { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';\n\n// See: #8833.\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport '@ckeditor/ckeditor5-ui/theme/components/responsive-form/responsiveform.css';\nimport '../../theme/mediaform.css';\n\n/**\n * The media form view controller class.\n *\n * See {@link module:media-embed/ui/mediaformview~MediaFormView}.\n */\nexport default class MediaFormView extends View {\n\t/**\n\t * Tracks information about the DOM focus in the form.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * The value of the URL input.\n\t */\n\tdeclare public mediaURLInputValue: string;\n\n\t/**\n\t * The URL input view.\n\t */\n\tpublic urlInputView: LabeledFieldView<InputTextView>;\n\n\t/**\n\t * An array of form validators used by {@link #isValid}.\n\t */\n\tprivate readonly _validators: Array<( v: MediaFormView ) => string | undefined>;\n\n\t/**\n\t * The default info text for the {@link #urlInputView}.\n\t */\n\tprivate _urlInputViewInfoDefault?: string;\n\n\t/**\n\t * The info text with an additional tip for the {@link #urlInputView},\n\t * displayed when the input has some value.\n\t */\n\tprivate _urlInputViewInfoTip?: string;\n\n\t/**\n\t * @param validators Form validators used by {@link #isValid}.\n\t * @param locale The localization services instance.\n\t */\n\tconstructor( validators: Array<( v: MediaFormView ) => string | undefined>, locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.set( 'mediaURLInputValue', '' );\n\t\tthis.urlInputView = this._createUrlInput();\n\n\t\tthis._validators = validators;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-media-form',\n\t\t\t\t\t'ck-responsive-form'\n\t\t\t\t],\n\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\tthis.urlInputView\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\t// Register the view in the focus tracker.\n\t\tthis.focusTracker.add( this.urlInputView.element! );\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the {@link #urlInputView}.\n\t */\n\tpublic focus(): void {\n\t\tthis.urlInputView.focus();\n\t}\n\n\t/**\n\t * The native DOM `value` of the {@link #urlInputView} element.\n\t *\n\t * **Note**: Do not confuse it with the {@link module:ui/inputtext/inputtextview~InputTextView#value}\n\t * which works one way only and may not represent the actual state of the component in the DOM.\n\t */\n\tpublic get url(): string {\n\t\treturn this.urlInputView.fieldView.element!.value.trim();\n\t}\n\n\tpublic set url( url: string ) {\n\t\tthis.urlInputView.fieldView.value = url.trim();\n\t}\n\n\t/**\n\t * Validates the form and returns `false` when some fields are invalid.\n\t */\n\tpublic isValid(): boolean {\n\t\tthis.resetFormStatus();\n\n\t\tfor ( const validator of this._validators ) {\n\t\t\tconst errorText = validator( this );\n\n\t\t\t// One error per field is enough.\n\t\t\tif ( errorText ) {\n\t\t\t\t// Apply updated error.\n\t\t\t\tthis.urlInputView.errorText = errorText;\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Cleans up the supplementary error and information text of the {@link #urlInputView}\n\t * bringing them back to the state when the form has been displayed for the first time.\n\t *\n\t * See {@link #isValid}.\n\t */\n\tpublic resetFormStatus(): void {\n\t\tthis.urlInputView.errorText = null;\n\t\tthis.urlInputView.infoText = this._urlInputViewInfoDefault!;\n\t}\n\n\t/**\n\t * Creates a labeled input view.\n\t *\n\t * @returns Labeled input view instance.\n\t */\n\tprivate _createUrlInput(): LabeledFieldView<InputTextView> {\n\t\tconst t = this.locale!.t;\n\n\t\tconst labeledInput = new LabeledFieldView( this.locale, createLabeledInputText );\n\t\tconst inputField = labeledInput.fieldView;\n\n\t\tthis._urlInputViewInfoDefault = t( 'Paste the media URL in the input.' );\n\t\tthis._urlInputViewInfoTip = t( 'Tip: Paste the URL into the content to embed faster.' );\n\n\t\tlabeledInput.label = t( 'Media URL' );\n\t\tlabeledInput.infoText = this._urlInputViewInfoDefault;\n\n\t\tinputField.inputMode = 'url';\n\t\tinputField.on( 'input', () => {\n\t\t\t// Display the tip text only when there is some value. Otherwise fall back to the default info text.\n\t\t\tlabeledInput.infoText = inputField.element!.value ? this._urlInputViewInfoTip! : this._urlInputViewInfoDefault!;\n\t\t\tthis.mediaURLInputValue = inputField.element!.value.trim();\n\t\t} );\n\n\t\treturn labeledInput;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/mediaembedui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, CssTransitionDisablerMixin, MenuBarMenuListItemButtonView, Dialog } from 'ckeditor5/src/ui.js';\n\nimport MediaFormView from './ui/mediaformview.js';\nimport MediaEmbedEditing from './mediaembedediting.js';\nimport mediaIcon from '../theme/icons/media.svg';\nimport type { LocaleTranslate } from 'ckeditor5/src/utils.js';\nimport type MediaRegistry from './mediaregistry.js';\n\n/**\n * The media embed UI plugin.\n */\nexport default class MediaEmbedUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ MediaEmbedEditing, Dialog ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'MediaEmbedUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\tprivate _formView: MediaFormView | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( 'mediaEmbed', () => {\n\t\t\tconst t = this.editor.locale.t;\n\t\t\tconst button = this._createDialogButton( ButtonView );\n\n\t\t\tbutton.tooltip = true;\n\t\t\tbutton.label = t( 'Insert media' );\n\n\t\t\treturn button;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:mediaEmbed', () => {\n\t\t\tconst t = this.editor.locale.t;\n\t\t\tconst button = this._createDialogButton( MenuBarMenuListItemButtonView );\n\n\t\t\tbutton.label = t( 'Media' );\n\n\t\t\treturn button;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a button for menu bar that will show media embed dialog.\n\t */\n\tprivate _createDialogButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>( ButtonClass: T ): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst buttonView = new ButtonClass( editor.locale ) as InstanceType<T>;\n\t\tconst command = editor.commands.get( 'mediaEmbed' )!;\n\t\tconst dialogPlugin = this.editor.plugins.get( 'Dialog' );\n\n\t\tbuttonView.icon = mediaIcon;\n\n\t\tbuttonView.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\n\t\tbuttonView.on( 'execute', () => {\n\t\t\tif ( dialogPlugin.id === 'mediaEmbed' ) {\n\t\t\t\tdialogPlugin.hide();\n\t\t\t} else {\n\t\t\t\tthis._showDialog();\n\t\t\t}\n\t\t} );\n\n\t\treturn buttonView;\n\t}\n\n\tprivate _showDialog() {\n\t\tconst editor = this.editor;\n\t\tconst dialog = editor.plugins.get( 'Dialog' );\n\t\tconst command = editor.commands.get( 'mediaEmbed' )!;\n\t\tconst t = editor.locale.t;\n\n\t\tif ( !this._formView ) {\n\t\t\tconst registry = editor.plugins.get( MediaEmbedEditing ).registry;\n\n\t\t\tthis._formView = new ( CssTransitionDisablerMixin( MediaFormView ) )( getFormValidators( editor.t, registry ), editor.locale );\n\t\t\tthis._formView.on( 'submit', () => this._handleSubmitForm() );\n\t\t}\n\n\t\tdialog.show( {\n\t\t\tid: 'mediaEmbed',\n\t\t\ttitle: t( 'Insert media' ),\n\t\t\tcontent: this._formView,\n\t\t\tisModal: true,\n\t\t\tonShow: () => {\n\t\t\t\tthis._formView!.url = command.value || '';\n\t\t\t\tthis._formView!.resetFormStatus();\n\t\t\t\tthis._formView!.urlInputView.fieldView.select();\n\t\t\t},\n\t\t\tactionButtons: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Cancel' ),\n\t\t\t\t\twithText: true,\n\t\t\t\t\tonExecute: () => dialog.hide()\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Accept' ),\n\t\t\t\t\tclass: 'ck-button-action',\n\t\t\t\t\twithText: true,\n\t\t\t\t\tonExecute: () => this._handleSubmitForm()\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\tprivate _handleSubmitForm() {\n\t\tconst editor = this.editor;\n\t\tconst dialog = editor.plugins.get( 'Dialog' );\n\n\t\tif ( this._formView!.isValid() ) {\n\t\t\teditor.execute( 'mediaEmbed', this._formView!.url );\n\t\t\tdialog.hide();\n\t\t\teditor.editing.view.focus();\n\t\t}\n\t}\n}\n\nfunction getFormValidators( t: LocaleTranslate, registry: MediaRegistry ): Array<( v: MediaFormView ) => string | undefined> {\n\treturn [\n\t\tform => {\n\t\t\tif ( !form.url.length ) {\n\t\t\t\treturn t( 'The URL must not be empty.' );\n\t\t\t}\n\t\t},\n\t\tform => {\n\t\t\tif ( !registry.hasMedia( form.url ) ) {\n\t\t\t\treturn t( 'This media URL is not supported.' );\n\t\t\t}\n\t\t}\n\t];\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/mediaembed\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { Widget } from 'ckeditor5/src/widget.js';\n\nimport MediaEmbedEditing from './mediaembedediting.js';\nimport AutoMediaEmbed from './automediaembed.js';\nimport MediaEmbedUI from './mediaembedui.js';\n\nimport '../theme/mediaembed.css';\n\n/**\n * The media embed plugin.\n *\n * For a detailed overview, check the {@glink features/media-embed Media Embed feature documentation}.\n *\n * This is a \"glue\" plugin which loads the following plugins:\n *\n * * The {@link module:media-embed/mediaembedediting~MediaEmbedEditing media embed editing feature},\n * * The {@link module:media-embed/mediaembedui~MediaEmbedUI media embed UI feature} and\n * * The {@link module:media-embed/automediaembed~AutoMediaEmbed auto-media embed feature}.\n */\nexport default class MediaEmbed extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ MediaEmbedEditing, MediaEmbedUI, AutoMediaEmbed, Widget ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'MediaEmbed' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module media-embed/mediaembedtoolbar\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { WidgetToolbarRepository } from 'ckeditor5/src/widget.js';\n\nimport { getSelectedMediaViewWidget } from './utils.js';\n\nimport './mediaembedconfig.js';\n\n/**\n * The media embed toolbar plugin. It creates a toolbar for media embed that shows up when the media element is selected.\n *\n * Instances of toolbar components (e.g. buttons) are created based on the\n * {@link module:media-embed/mediaembedconfig~MediaEmbedConfig#toolbar `media.toolbar` configuration option}.\n */\nexport default class MediaEmbedToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ WidgetToolbarRepository ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'MediaEmbedToolbar' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n\t\twidgetToolbarRepository.register( 'mediaEmbed', {\n\t\t\tariaLabel: t( 'Media toolbar' ),\n\t\t\titems: editor.config.get( 'mediaEmbed.toolbar' ) || [],\n\t\t\tgetRelatedElement: getSelectedMediaViewWidget\n\t\t} );\n\t}\n}\n", "import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { CKEditorError, toMap, uid, Rect, keyCodes, Collection, logWarning, env } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { ListView, View, ListItemView, ContextualBalloon, clickOutsideHandler, ButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { TextWatcher } from '@ckeditor/ckeditor5-typing/dist/index.js';\nimport { debounce } from 'lodash-es';\n\nconst BRACKET_PAIRS = {\n    '(': ')',\n    '[': ']',\n    '{': '}'\n};\n/**\n * The mention command.\n *\n * The command is registered by {@link module:mention/mentionediting~MentionEditing} as `'mention'`.\n *\n * To insert a mention into a range, execute the command and specify a mention object with a range to replace:\n *\n * ```ts\n * const focus = editor.model.document.selection.focus;\n *\n * // It will replace one character before the selection focus with the '#1234' text\n * // with the mention attribute filled with passed attributes.\n * editor.execute( 'mention', {\n * \tmarker: '#',\n * \tmention: {\n * \t\tid: '#1234',\n * \t\tname: 'Foo',\n * \t\ttitle: 'Big Foo'\n * \t},\n * \trange: editor.model.createRange( focus.getShiftedBy( -1 ), focus )\n * } );\n *\n * // It will replace one character before the selection focus with the 'The \"Big Foo\"' text\n * // with the mention attribute filled with passed attributes.\n * editor.execute( 'mention', {\n * \tmarker: '#',\n * \tmention: {\n * \t\tid: '#1234',\n * \t\tname: 'Foo',\n * \t\ttitle: 'Big Foo'\n * \t},\n * \ttext: 'The \"Big Foo\"',\n * \trange: editor.model.createRange( focus.getShiftedBy( -1 ), focus )\n * } );\n *\t```\n */ class MentionCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        // Since this command may pass range in execution parameters, it should be checked directly in execute block.\n        this._isEnabledBasedOnSelection = false;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const doc = model.document;\n        this.isEnabled = model.schema.checkAttributeInSelection(doc.selection, 'mention');\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.mention The mention object to insert. When a string is passed, it will be used to create a plain\n\t * object with the name attribute that equals the passed string.\n\t * @param options.marker The marker character (e.g. `'@'`).\n\t * @param options.text The text of the inserted mention. Defaults to the full mention string composed from `marker` and\n\t * `mention` string or `mention.id` if an object is passed.\n\t * @param options.range The range to replace.\n\t * Note that the replaced range might be shorter than the inserted text with the mention attribute.\n\t * @fires execute\n\t */ execute(options) {\n        const model = this.editor.model;\n        const document = model.document;\n        const selection = document.selection;\n        const mentionData = typeof options.mention == 'string' ? {\n            id: options.mention\n        } : options.mention;\n        const mentionID = mentionData.id;\n        const range = options.range || selection.getFirstRange();\n        // Don't execute command if range is in non-editable place.\n        if (!model.canEditAt(range)) {\n            return;\n        }\n        const mentionText = options.text || mentionID;\n        const mention = _addMentionAttributes({\n            _text: mentionText,\n            id: mentionID\n        }, mentionData);\n        if (options.marker.length != 1) {\n            /**\n\t\t\t * The marker must be a single character.\n\t\t\t *\n\t\t\t * Correct markers: `'@'`, `'#'`.\n\t\t\t *\n\t\t\t * Incorrect markers: `'@@'`, `'[@'`.\n\t\t\t *\n\t\t\t * See {@link module:mention/mentionconfig~MentionConfig}.\n\t\t\t *\n\t\t\t * @error mentioncommand-incorrect-marker\n\t\t\t */ throw new CKEditorError('mentioncommand-incorrect-marker', this);\n        }\n        if (mentionID.charAt(0) != options.marker) {\n            /**\n\t\t\t * The feed item ID must start with the marker character.\n\t\t\t *\n\t\t\t * Correct mention feed setting:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * mentions: [\n\t\t\t * \t{\n\t\t\t * \t\tmarker: '@',\n\t\t\t * \t\tfeed: [ '@Ann', '@Barney', ... ]\n\t\t\t * \t}\n\t\t\t * ]\n\t\t\t * ```\n\t\t\t *\n\t\t\t * Incorrect mention feed setting:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * mentions: [\n\t\t\t * \t{\n\t\t\t * \t\tmarker: '@',\n\t\t\t * \t\tfeed: [ 'Ann', 'Barney', ... ]\n\t\t\t * \t}\n\t\t\t * ]\n\t\t\t * ```\n\t\t\t *\n\t\t\t * See {@link module:mention/mentionconfig~MentionConfig}.\n\t\t\t *\n\t\t\t * @error mentioncommand-incorrect-id\n\t\t\t */ throw new CKEditorError('mentioncommand-incorrect-id', this);\n        }\n        model.change((writer)=>{\n            const currentAttributes = toMap(selection.getAttributes());\n            const attributesWithMention = new Map(currentAttributes.entries());\n            attributesWithMention.set('mention', mention);\n            // Replace a range with the text with a mention.\n            const insertionRange = model.insertContent(writer.createText(mentionText, attributesWithMention), range);\n            const nodeBefore = insertionRange.start.nodeBefore;\n            const nodeAfter = insertionRange.end.nodeAfter;\n            const isFollowedByWhiteSpace = nodeAfter && nodeAfter.is('$text') && nodeAfter.data.startsWith(' ');\n            let isInsertedInBrackets = false;\n            if (nodeBefore && nodeAfter && nodeBefore.is('$text') && nodeAfter.is('$text')) {\n                const precedingCharacter = nodeBefore.data.slice(-1);\n                const isPrecededByOpeningBracket = precedingCharacter in BRACKET_PAIRS;\n                const isFollowedByBracketClosure = isPrecededByOpeningBracket && nodeAfter.data.startsWith(BRACKET_PAIRS[precedingCharacter]);\n                isInsertedInBrackets = isPrecededByOpeningBracket && isFollowedByBracketClosure;\n            }\n            // Don't add a white space if either of the following is true:\n            // * there's already one after the mention;\n            // * the mention was inserted in the empty matching brackets.\n            // https://github.com/ckeditor/ckeditor5/issues/4651\n            if (!isInsertedInBrackets && !isFollowedByWhiteSpace) {\n                model.insertContent(writer.createText(' ', currentAttributes), range.start.getShiftedBy(mentionText.length));\n            }\n        });\n    }\n}\n\n/**\n * The mention editing feature.\n *\n * It introduces the {@link module:mention/mentioncommand~MentionCommand command} and the `mention`\n * attribute in the {@link module:engine/model/model~Model model} which renders in the {@link module:engine/view/view view}\n * as a `<span class=\"mention\" data-mention=\"@mention\">`.\n */ class MentionEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'MentionEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const doc = model.document;\n        // Allow the mention attribute on all text nodes.\n        model.schema.extend('$text', {\n            allowAttributes: 'mention'\n        });\n        // Upcast conversion.\n        editor.conversion.for('upcast').elementToAttribute({\n            view: {\n                name: 'span',\n                key: 'data-mention',\n                classes: 'mention'\n            },\n            model: {\n                key: 'mention',\n                value: (viewElement)=>_toMentionAttribute(viewElement)\n            }\n        });\n        // Downcast conversion.\n        editor.conversion.for('downcast').attributeToElement({\n            model: 'mention',\n            view: createViewMentionElement\n        });\n        editor.conversion.for('downcast').add(preventPartialMentionDowncast);\n        doc.registerPostFixer((writer)=>removePartialMentionPostFixer(writer, doc, model.schema));\n        doc.registerPostFixer((writer)=>extendAttributeOnMentionPostFixer(writer, doc));\n        doc.registerPostFixer((writer)=>selectionMentionAttributePostFixer(writer, doc));\n        editor.commands.add('mention', new MentionCommand(editor));\n    }\n}\n/**\n * @internal\n */ function _addMentionAttributes(baseMentionData, data) {\n    return Object.assign({\n        uid: uid()\n    }, baseMentionData, data || {});\n}\n/**\n * Creates a mention attribute value from the provided view element and optional data.\n *\n * This function is exposed as\n * {@link module:mention/mention~Mention#toMentionAttribute `editor.plugins.get( 'Mention' ).toMentionAttribute()`}.\n *\n * @internal\n */ function _toMentionAttribute(viewElementOrMention, data) {\n    const dataMention = viewElementOrMention.getAttribute('data-mention');\n    const textNode = viewElementOrMention.getChild(0);\n    // Do not convert empty mentions.\n    if (!textNode) {\n        return;\n    }\n    const baseMentionData = {\n        id: dataMention,\n        _text: textNode.data\n    };\n    return _addMentionAttributes(baseMentionData, data);\n}\n/**\n * A converter that blocks partial mention from being converted.\n *\n * This converter is registered with 'highest' priority in order to consume mention attribute before it is converted by\n * any other converters. This converter only consumes partial mention - those whose `_text` attribute is not equal to text with mention\n * attribute. This may happen when copying part of mention text.\n */ function preventPartialMentionDowncast(dispatcher) {\n    dispatcher.on('attribute:mention', (evt, data, conversionApi)=>{\n        const mention = data.attributeNewValue;\n        if (!data.item.is('$textProxy') || !mention) {\n            return;\n        }\n        const start = data.range.start;\n        const textNode = start.textNode || start.nodeAfter;\n        if (textNode.data != mention._text) {\n            // Consume item to prevent partial mention conversion.\n            conversionApi.consumable.consume(data.item, evt.name);\n        }\n    }, {\n        priority: 'highest'\n    });\n}\n/**\n * Creates a mention element from the mention data.\n */ function createViewMentionElement(mention, { writer }) {\n    if (!mention) {\n        return;\n    }\n    const attributes = {\n        class: 'mention',\n        'data-mention': mention.id\n    };\n    const options = {\n        id: mention.uid,\n        priority: 20\n    };\n    return writer.createAttributeElement('span', attributes, options);\n}\n/**\n * Model post-fixer that disallows typing with selection when the selection is placed after the text node with the mention attribute or\n * before a text node with mention attribute.\n */ function selectionMentionAttributePostFixer(writer, doc) {\n    const selection = doc.selection;\n    const focus = selection.focus;\n    if (selection.isCollapsed && selection.hasAttribute('mention') && shouldNotTypeWithMentionAt(focus)) {\n        writer.removeSelectionAttribute('mention');\n        return true;\n    }\n    return false;\n}\n/**\n * Helper function to detect if mention attribute should be removed from selection.\n * This check makes only sense if the selection has mention attribute.\n *\n * The mention attribute should be removed from a selection when selection focus is placed:\n * a) after a text node\n * b) the position is at parents start - the selection will set attributes from node after.\n */ function shouldNotTypeWithMentionAt(position) {\n    const isAtStart = position.isAtStart;\n    const isAfterAMention = position.nodeBefore && position.nodeBefore.is('$text');\n    return isAfterAMention || isAtStart;\n}\n/**\n * Model post-fixer that removes the mention attribute from the modified text node.\n */ function removePartialMentionPostFixer(writer, doc, schema) {\n    const changes = doc.differ.getChanges();\n    let wasChanged = false;\n    for (const change of changes){\n        if (change.type == 'attribute') {\n            continue;\n        }\n        // Checks the text node on the current position.\n        const position = change.position;\n        if (change.name == '$text') {\n            const nodeAfterInsertedTextNode = position.textNode && position.textNode.nextSibling;\n            // Checks the text node where the change occurred.\n            wasChanged = checkAndFix(position.textNode, writer) || wasChanged;\n            // Occurs on paste inside a text node with mention.\n            wasChanged = checkAndFix(nodeAfterInsertedTextNode, writer) || wasChanged;\n            wasChanged = checkAndFix(position.nodeBefore, writer) || wasChanged;\n            wasChanged = checkAndFix(position.nodeAfter, writer) || wasChanged;\n        }\n        // Checks text nodes in inserted elements (might occur when splitting a paragraph or pasting content inside text with mention).\n        if (change.name != '$text' && change.type == 'insert') {\n            const insertedNode = position.nodeAfter;\n            for (const item of writer.createRangeIn(insertedNode).getItems()){\n                wasChanged = checkAndFix(item, writer) || wasChanged;\n            }\n        }\n        // Inserted inline elements might break mention.\n        if (change.type == 'insert' && schema.isInline(change.name)) {\n            const nodeAfterInserted = position.nodeAfter && position.nodeAfter.nextSibling;\n            wasChanged = checkAndFix(position.nodeBefore, writer) || wasChanged;\n            wasChanged = checkAndFix(nodeAfterInserted, writer) || wasChanged;\n        }\n    }\n    return wasChanged;\n}\n/**\n * This post-fixer will extend the attribute applied on the part of the mention so the whole text node of the mention will have\n * the added attribute.\n */ function extendAttributeOnMentionPostFixer(writer, doc) {\n    const changes = doc.differ.getChanges();\n    let wasChanged = false;\n    for (const change of changes){\n        if (change.type === 'attribute' && change.attributeKey != 'mention') {\n            // Checks the node on the left side of the range...\n            const nodeBefore = change.range.start.nodeBefore;\n            // ... and on the right side of the range.\n            const nodeAfter = change.range.end.nodeAfter;\n            for (const node of [\n                nodeBefore,\n                nodeAfter\n            ]){\n                if (isBrokenMentionNode(node) && node.getAttribute(change.attributeKey) != change.attributeNewValue) {\n                    writer.setAttribute(change.attributeKey, change.attributeNewValue, node);\n                    wasChanged = true;\n                }\n            }\n        }\n    }\n    return wasChanged;\n}\n/**\n * Checks if a node has a correct mention attribute if present.\n * Returns `true` if the node is text and has a mention attribute whose text does not match the expected mention text.\n */ function isBrokenMentionNode(node) {\n    if (!node || !(node.is('$text') || node.is('$textProxy')) || !node.hasAttribute('mention')) {\n        return false;\n    }\n    const text = node.data;\n    const mention = node.getAttribute('mention');\n    const expectedText = mention._text;\n    return text != expectedText;\n}\n/**\n * Fixes a mention on a text node if it needs a fix.\n */ function checkAndFix(textNode, writer) {\n    if (isBrokenMentionNode(textNode)) {\n        writer.removeAttribute('mention', textNode);\n        return true;\n    }\n    return false;\n}\n\n/**\n * The mention ui view.\n */ class MentionsView extends ListView {\n    selected;\n    position;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        this.extendTemplate({\n            attributes: {\n                class: [\n                    'ck-mentions'\n                ],\n                tabindex: '-1'\n            }\n        });\n    }\n    /**\n\t * {@link #select Selects} the first item.\n\t */ selectFirst() {\n        this.select(0);\n    }\n    /**\n\t * Selects next item to the currently {@link #select selected}.\n\t *\n\t * If the last item is already selected, it will select the first item.\n\t */ selectNext() {\n        const item = this.selected;\n        const index = this.items.getIndex(item);\n        this.select(index + 1);\n    }\n    /**\n\t * Selects previous item to the currently {@link #select selected}.\n\t *\n\t * If the first item is already selected, it will select the last item.\n\t */ selectPrevious() {\n        const item = this.selected;\n        const index = this.items.getIndex(item);\n        this.select(index - 1);\n    }\n    /**\n\t * Marks item at a given index as selected.\n\t *\n\t * Handles selection cycling when passed index is out of bounds:\n\t * - if the index is lower than 0, it will select the last item,\n\t * - if the index is higher than the last item index, it will select the first item.\n\t *\n\t * @param index Index of an item to be marked as selected.\n\t */ select(index) {\n        let indexToGet = 0;\n        if (index > 0 && index < this.items.length) {\n            indexToGet = index;\n        } else if (index < 0) {\n            indexToGet = this.items.length - 1;\n        }\n        const item = this.items.get(indexToGet);\n        // Return early if item is already selected.\n        if (this.selected === item) {\n            return;\n        }\n        // Remove highlight of previously selected item.\n        if (this.selected) {\n            this.selected.removeHighlight();\n        }\n        item.highlight();\n        this.selected = item;\n        // Scroll the mentions view to the selected element.\n        if (!this._isItemVisibleInScrolledArea(item)) {\n            this.element.scrollTop = item.element.offsetTop;\n        }\n    }\n    /**\n\t * Triggers the `execute` event on the {@link #select selected} item.\n\t */ executeSelected() {\n        this.selected.fire('execute');\n    }\n    /**\n\t * Checks if an item is visible in the scrollable area.\n\t *\n\t * The item is considered visible when:\n\t * - its top boundary is inside the scrollable rect\n\t * - its bottom boundary is inside the scrollable rect (the whole item must be visible)\n\t */ _isItemVisibleInScrolledArea(item) {\n        return new Rect(this.element).contains(new Rect(item.element));\n    }\n}\n\n/**\n * This class wraps DOM element as a CKEditor5 UI View.\n *\n * It allows to render any DOM element and use it in mentions list.\n */ class DomWrapperView extends View {\n    /**\n\t * The DOM element for which wrapper was created.\n\t */ domElement;\n    /**\n\t * Creates an instance of {@link module:mention/ui/domwrapperview~DomWrapperView} class.\n\t *\n\t * Also see {@link #render}.\n\t */ constructor(locale, domElement){\n        super(locale);\n        // Disable template rendering on this view.\n        this.template = undefined;\n        this.domElement = domElement;\n        // Render dom wrapper as a button.\n        this.domElement.classList.add('ck-button');\n        this.set('isOn', false);\n        // Handle isOn state as in buttons.\n        this.on('change:isOn', (evt, name, isOn)=>{\n            if (isOn) {\n                this.domElement.classList.add('ck-on');\n                this.domElement.classList.remove('ck-off');\n            } else {\n                this.domElement.classList.add('ck-off');\n                this.domElement.classList.remove('ck-on');\n            }\n        });\n        // Pass click event as execute event.\n        this.listenTo(this.domElement, 'click', ()=>{\n            this.fire('execute');\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        this.element = this.domElement;\n    }\n    /**\n\t * Focuses the DOM element.\n\t */ focus() {\n        this.domElement.focus();\n    }\n}\n\nclass MentionListItemView extends ListItemView {\n    item;\n    marker;\n    highlight() {\n        const child = this.children.first;\n        child.isOn = true;\n    }\n    removeHighlight() {\n        const child = this.children.first;\n        child.isOn = false;\n    }\n}\n\nconst VERTICAL_SPACING = 3;\n// The key codes that mention UI handles when it is open (without commit keys).\nconst defaultHandledKeyCodes = [\n    keyCodes.arrowup,\n    keyCodes.arrowdown,\n    keyCodes.esc\n];\n// Dropdown commit key codes.\nconst defaultCommitKeyCodes = [\n    keyCodes.enter,\n    keyCodes.tab\n];\n/**\n * The mention UI feature.\n */ class MentionUI extends Plugin {\n    /**\n\t * The mention view.\n\t */ _mentionsView;\n    /**\n\t * Stores mention feeds configurations.\n\t */ _mentionsConfigurations;\n    /**\n\t * The contextual balloon plugin instance.\n\t */ _balloon;\n    _items = new Collection();\n    _lastRequested;\n    /**\n\t * Debounced feed requester. It uses `lodash#debounce` method to delay function call.\n\t */ _requestFeedDebounced;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'MentionUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._mentionsView = this._createMentionView();\n        this._mentionsConfigurations = new Map();\n        this._requestFeedDebounced = debounce(this._requestFeed, 100);\n        editor.config.define('mention', {\n            feeds: []\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const commitKeys = editor.config.get('mention.commitKeys') || defaultCommitKeyCodes;\n        const handledKeyCodes = defaultHandledKeyCodes.concat(commitKeys);\n        this._balloon = editor.plugins.get(ContextualBalloon);\n        // Key listener that handles navigation in mention view.\n        editor.editing.view.document.on('keydown', (evt, data)=>{\n            if (isHandledKey(data.keyCode) && this._isUIVisible) {\n                data.preventDefault();\n                evt.stop(); // Required for Enter key overriding.\n                if (data.keyCode == keyCodes.arrowdown) {\n                    this._mentionsView.selectNext();\n                }\n                if (data.keyCode == keyCodes.arrowup) {\n                    this._mentionsView.selectPrevious();\n                }\n                if (commitKeys.includes(data.keyCode)) {\n                    this._mentionsView.executeSelected();\n                }\n                if (data.keyCode == keyCodes.esc) {\n                    this._hideUIAndRemoveMarker();\n                }\n            }\n        }, {\n            priority: 'highest'\n        }); // Required to override the Enter key.\n        // Close the dropdown upon clicking outside of the plugin UI.\n        clickOutsideHandler({\n            emitter: this._mentionsView,\n            activator: ()=>this._isUIVisible,\n            contextElements: ()=>[\n                    this._balloon.view.element\n                ],\n            callback: ()=>this._hideUIAndRemoveMarker()\n        });\n        const feeds = editor.config.get('mention.feeds');\n        for (const mentionDescription of feeds){\n            const { feed, marker, dropdownLimit } = mentionDescription;\n            if (!isValidMentionMarker(marker)) {\n                /**\n\t\t\t\t * The marker must be a single character.\n\t\t\t\t *\n\t\t\t\t * Correct markers: `'@'`, `'#'`.\n\t\t\t\t *\n\t\t\t\t * Incorrect markers: `'$$'`, `'[@'`.\n\t\t\t\t *\n\t\t\t\t * See {@link module:mention/mentionconfig~MentionConfig}.\n\t\t\t\t *\n\t\t\t\t * @error mentionconfig-incorrect-marker\n\t\t\t\t * @param marker Configured marker\n\t\t\t\t */ throw new CKEditorError('mentionconfig-incorrect-marker', null, {\n                    marker\n                });\n            }\n            const feedCallback = typeof feed == 'function' ? feed.bind(this.editor) : createFeedCallback(feed);\n            const itemRenderer = mentionDescription.itemRenderer;\n            const definition = {\n                marker,\n                feedCallback,\n                itemRenderer,\n                dropdownLimit\n            };\n            this._mentionsConfigurations.set(marker, definition);\n        }\n        this._setupTextWatcher(feeds);\n        this.listenTo(editor, 'change:isReadOnly', ()=>{\n            this._hideUIAndRemoveMarker();\n        });\n        this.on('requestFeed:response', (evt, data)=>this._handleFeedResponse(data));\n        this.on('requestFeed:error', ()=>this._hideUIAndRemoveMarker());\n        /**\n\t\t * Checks if a given key code is handled by the mention UI.\n\t\t */ function isHandledKey(keyCode) {\n            return handledKeyCodes.includes(keyCode);\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n        this._mentionsView.destroy();\n    }\n    /**\n\t * Returns true when {@link #_mentionsView} is in the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} and it is\n\t * currently visible.\n\t */ get _isUIVisible() {\n        return this._balloon.visibleView === this._mentionsView;\n    }\n    /**\n\t * Creates the {@link #_mentionsView}.\n\t */ _createMentionView() {\n        const locale = this.editor.locale;\n        const mentionsView = new MentionsView(locale);\n        mentionsView.items.bindTo(this._items).using((data)=>{\n            const { item, marker } = data;\n            const { dropdownLimit: markerDropdownLimit } = this._mentionsConfigurations.get(marker);\n            // Set to 10 by default for backwards compatibility. See: #10479\n            const dropdownLimit = markerDropdownLimit || this.editor.config.get('mention.dropdownLimit') || 10;\n            if (mentionsView.items.length >= dropdownLimit) {\n                return null;\n            }\n            const listItemView = new MentionListItemView(locale);\n            const view = this._renderItem(item, marker);\n            view.delegate('execute').to(listItemView);\n            listItemView.children.add(view);\n            listItemView.item = item;\n            listItemView.marker = marker;\n            listItemView.on('execute', ()=>{\n                mentionsView.fire('execute', {\n                    item,\n                    marker\n                });\n            });\n            return listItemView;\n        });\n        mentionsView.on('execute', (evt, data)=>{\n            const editor = this.editor;\n            const model = editor.model;\n            const item = data.item;\n            const marker = data.marker;\n            const mentionMarker = editor.model.markers.get('mention');\n            // Create a range on matched text.\n            const end = model.createPositionAt(model.document.selection.focus);\n            const start = model.createPositionAt(mentionMarker.getStart());\n            const range = model.createRange(start, end);\n            this._hideUIAndRemoveMarker();\n            editor.execute('mention', {\n                mention: item,\n                text: item.text,\n                marker,\n                range\n            });\n            editor.editing.view.focus();\n        });\n        return mentionsView;\n    }\n    /**\n\t * Returns item renderer for the marker.\n\t */ _getItemRenderer(marker) {\n        const { itemRenderer } = this._mentionsConfigurations.get(marker);\n        return itemRenderer;\n    }\n    /**\n\t * Requests a feed from a configured callbacks.\n\t */ _requestFeed(marker, feedText) {\n        // @if CK_DEBUG_MENTION // console.log( '%c[Feed]%c Requesting for', 'color: blue', 'color: black', `\"${ feedText }\"` );\n        // Store the last requested feed - it is used to discard any out-of order requests.\n        this._lastRequested = feedText;\n        const { feedCallback } = this._mentionsConfigurations.get(marker);\n        const feedResponse = feedCallback(feedText);\n        const isAsynchronous = feedResponse instanceof Promise;\n        // For synchronous feeds (e.g. callbacks, arrays) fire the response event immediately.\n        if (!isAsynchronous) {\n            this.fire('requestFeed:response', {\n                feed: feedResponse,\n                marker,\n                feedText\n            });\n            return;\n        }\n        // Handle the asynchronous responses.\n        feedResponse.then((response)=>{\n            // Check the feed text of this response with the last requested one so either:\n            if (this._lastRequested == feedText) {\n                // It is the same and fire the response event.\n                this.fire('requestFeed:response', {\n                    feed: response,\n                    marker,\n                    feedText\n                });\n            } else {\n                // It is different - most probably out-of-order one, so fire the discarded event.\n                this.fire('requestFeed:discarded', {\n                    feed: response,\n                    marker,\n                    feedText\n                });\n            }\n        }).catch((error)=>{\n            this.fire('requestFeed:error', {\n                error\n            });\n            /**\n\t\t\t\t * The callback used for obtaining mention autocomplete feed thrown and error and the mention UI was hidden or\n\t\t\t\t * not displayed at all.\n\t\t\t\t *\n\t\t\t\t * @error mention-feed-callback-error\n\t\t\t\t */ logWarning('mention-feed-callback-error', {\n                marker\n            });\n        });\n    }\n    /**\n\t * Registers a text watcher for the marker.\n\t */ _setupTextWatcher(feeds) {\n        const editor = this.editor;\n        const feedsWithPattern = feeds.map((feed)=>({\n                ...feed,\n                pattern: createRegExp(feed.marker, feed.minimumCharacters || 0)\n            }));\n        const watcher = new TextWatcher(editor.model, createTestCallback(feedsWithPattern));\n        watcher.on('matched', (evt, data)=>{\n            const markerDefinition = getLastValidMarkerInText(feedsWithPattern, data.text);\n            const selection = editor.model.document.selection;\n            const focus = selection.focus;\n            const markerPosition = editor.model.createPositionAt(focus.parent, markerDefinition.position);\n            if (isPositionInExistingMention(focus) || isMarkerInExistingMention(markerPosition)) {\n                this._hideUIAndRemoveMarker();\n                return;\n            }\n            const feedText = requestFeedText(markerDefinition, data.text);\n            const matchedTextLength = markerDefinition.marker.length + feedText.length;\n            // Create a marker range.\n            const start = focus.getShiftedBy(-matchedTextLength);\n            const end = focus.getShiftedBy(-feedText.length);\n            const markerRange = editor.model.createRange(start, end);\n            // @if CK_DEBUG_MENTION // console.group( '%c[TextWatcher]%c matched', 'color: red', 'color: black', `\"${ feedText }\"` );\n            // @if CK_DEBUG_MENTION // console.log( 'data#text', `\"${ data.text }\"` );\n            // @if CK_DEBUG_MENTION // console.log( 'data#range', data.range.start.path, data.range.end.path );\n            // @if CK_DEBUG_MENTION // console.log( 'marker definition', markerDefinition );\n            // @if CK_DEBUG_MENTION // console.log( 'marker range', markerRange.start.path, markerRange.end.path );\n            if (checkIfStillInCompletionMode(editor)) {\n                const mentionMarker = editor.model.markers.get('mention');\n                // Update the marker - user might've moved the selection to other mention trigger.\n                editor.model.change((writer)=>{\n                    // @if CK_DEBUG_MENTION // console.log( '%c[Editing]%c Updating the marker.', 'color: purple', 'color: black' );\n                    writer.updateMarker(mentionMarker, {\n                        range: markerRange\n                    });\n                });\n            } else {\n                editor.model.change((writer)=>{\n                    // @if CK_DEBUG_MENTION // console.log( '%c[Editing]%c Adding the marker.', 'color: purple', 'color: black' );\n                    writer.addMarker('mention', {\n                        range: markerRange,\n                        usingOperation: false,\n                        affectsData: false\n                    });\n                });\n            }\n            this._requestFeedDebounced(markerDefinition.marker, feedText);\n        // @if CK_DEBUG_MENTION // console.groupEnd();\n        });\n        watcher.on('unmatched', ()=>{\n            this._hideUIAndRemoveMarker();\n        });\n        const mentionCommand = editor.commands.get('mention');\n        watcher.bind('isEnabled').to(mentionCommand);\n        return watcher;\n    }\n    /**\n\t * Handles the feed response event data.\n\t */ _handleFeedResponse(data) {\n        const { feed, marker } = data;\n        // eslint-disable-next-line max-len\n        // @if CK_DEBUG_MENTION // console.log( `%c[Feed]%c Response for \"${ data.feedText }\" (${ feed.length })`, 'color: blue', 'color: black', feed );\n        // If the marker is not in the document happens when the selection had changed and the 'mention' marker was removed.\n        if (!checkIfStillInCompletionMode(this.editor)) {\n            return;\n        }\n        // Reset the view.\n        this._items.clear();\n        for (const feedItem of feed){\n            const item = typeof feedItem != 'object' ? {\n                id: feedItem,\n                text: feedItem\n            } : feedItem;\n            this._items.add({\n                item,\n                marker\n            });\n        }\n        const mentionMarker = this.editor.model.markers.get('mention');\n        if (this._items.length) {\n            this._showOrUpdateUI(mentionMarker);\n        } else {\n            // Do not show empty mention UI.\n            this._hideUIAndRemoveMarker();\n        }\n    }\n    /**\n\t * Shows the mentions balloon. If the panel is already visible, it will reposition it.\n\t */ _showOrUpdateUI(markerMarker) {\n        if (this._isUIVisible) {\n            // @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Updating position.', 'color: green', 'color: black' );\n            // Update balloon position as the mention list view may change its size.\n            this._balloon.updatePosition(this._getBalloonPanelPositionData(markerMarker, this._mentionsView.position));\n        } else {\n            // @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Showing the UI.', 'color: green', 'color: black' );\n            this._balloon.add({\n                view: this._mentionsView,\n                position: this._getBalloonPanelPositionData(markerMarker, this._mentionsView.position),\n                singleViewMode: true\n            });\n        }\n        this._mentionsView.position = this._balloon.view.position;\n        this._mentionsView.selectFirst();\n    }\n    /**\n\t * Hides the mentions balloon and removes the 'mention' marker from the markers collection.\n\t */ _hideUIAndRemoveMarker() {\n        // Remove the mention view from balloon before removing marker - it is used by balloon position target().\n        if (this._balloon.hasView(this._mentionsView)) {\n            // @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Hiding the UI.', 'color: green', 'color: black' );\n            this._balloon.remove(this._mentionsView);\n        }\n        if (checkIfStillInCompletionMode(this.editor)) {\n            // @if CK_DEBUG_MENTION // console.log( '%c[Editing]%c Removing marker.', 'color: purple', 'color: black' );\n            this.editor.model.change((writer)=>writer.removeMarker('mention'));\n        }\n        // Make the last matched position on panel view undefined so the #_getBalloonPanelPositionData() method will return all positions\n        // on the next call.\n        this._mentionsView.position = undefined;\n    }\n    /**\n\t * Renders a single item in the autocomplete list.\n\t */ _renderItem(item, marker) {\n        const editor = this.editor;\n        let view;\n        let label = item.id;\n        const renderer = this._getItemRenderer(marker);\n        if (renderer) {\n            const renderResult = renderer(item);\n            if (typeof renderResult != 'string') {\n                view = new DomWrapperView(editor.locale, renderResult);\n            } else {\n                label = renderResult;\n            }\n        }\n        if (!view) {\n            const buttonView = new ButtonView(editor.locale);\n            buttonView.label = label;\n            buttonView.withText = true;\n            view = buttonView;\n        }\n        return view;\n    }\n    /**\n\t * Creates a position options object used to position the balloon panel.\n\t *\n\t * @param mentionMarker\n\t * @param preferredPosition The name of the last matched position name.\n\t */ _getBalloonPanelPositionData(mentionMarker, preferredPosition) {\n        const editor = this.editor;\n        const editing = editor.editing;\n        const domConverter = editing.view.domConverter;\n        const mapper = editing.mapper;\n        const uiLanguageDirection = editor.locale.uiLanguageDirection;\n        return {\n            target: ()=>{\n                let modelRange = mentionMarker.getRange();\n                // Target the UI to the model selection range - the marker has been removed so probably the UI will not be shown anyway.\n                // The logic is used by ContextualBalloon to display another panel in the same place.\n                if (modelRange.start.root.rootName == '$graveyard') {\n                    modelRange = editor.model.document.selection.getFirstRange();\n                }\n                const viewRange = mapper.toViewRange(modelRange);\n                const rangeRects = Rect.getDomRangeRects(domConverter.viewRangeToDom(viewRange));\n                return rangeRects.pop();\n            },\n            limiter: ()=>{\n                const view = this.editor.editing.view;\n                const viewDocument = view.document;\n                const editableElement = viewDocument.selection.editableElement;\n                if (editableElement) {\n                    return view.domConverter.mapViewToDom(editableElement.root);\n                }\n                return null;\n            },\n            positions: getBalloonPanelPositions(preferredPosition, uiLanguageDirection)\n        };\n    }\n}\n/**\n * Returns the balloon positions data callbacks.\n */ function getBalloonPanelPositions(preferredPosition, uiLanguageDirection) {\n    const positions = {\n        // Positions the panel to the southeast of the caret rectangle.\n        'caret_se': (targetRect)=>{\n            return {\n                top: targetRect.bottom + VERTICAL_SPACING,\n                left: targetRect.right,\n                name: 'caret_se',\n                config: {\n                    withArrow: false\n                }\n            };\n        },\n        // Positions the panel to the northeast of the caret rectangle.\n        'caret_ne': (targetRect, balloonRect)=>{\n            return {\n                top: targetRect.top - balloonRect.height - VERTICAL_SPACING,\n                left: targetRect.right,\n                name: 'caret_ne',\n                config: {\n                    withArrow: false\n                }\n            };\n        },\n        // Positions the panel to the southwest of the caret rectangle.\n        'caret_sw': (targetRect, balloonRect)=>{\n            return {\n                top: targetRect.bottom + VERTICAL_SPACING,\n                left: targetRect.right - balloonRect.width,\n                name: 'caret_sw',\n                config: {\n                    withArrow: false\n                }\n            };\n        },\n        // Positions the panel to the northwest of the caret rect.\n        'caret_nw': (targetRect, balloonRect)=>{\n            return {\n                top: targetRect.top - balloonRect.height - VERTICAL_SPACING,\n                left: targetRect.right - balloonRect.width,\n                name: 'caret_nw',\n                config: {\n                    withArrow: false\n                }\n            };\n        }\n    };\n    // Returns only the last position if it was matched to prevent the panel from jumping after the first match.\n    if (Object.prototype.hasOwnProperty.call(positions, preferredPosition)) {\n        return [\n            positions[preferredPosition]\n        ];\n    }\n    // By default, return all position callbacks ordered depending on the UI language direction.\n    return uiLanguageDirection !== 'rtl' ? [\n        positions.caret_se,\n        positions.caret_sw,\n        positions.caret_ne,\n        positions.caret_nw\n    ] : [\n        positions.caret_sw,\n        positions.caret_se,\n        positions.caret_nw,\n        positions.caret_ne\n    ];\n}\n/**\n * Returns a marker definition of the last valid occurring marker in a given string.\n * If there is no valid marker in a string, it returns undefined.\n *\n * Example of returned object:\n *\n * ```ts\n * {\n * \tmarker: '@',\n * \tposition: 4,\n * \tminimumCharacters: 0\n * }\n * ````\n *\n * @param feedsWithPattern Registered feeds in editor for mention plugin with created RegExp for matching marker.\n * @param text String to find the marker in\n * @returns Matched marker's definition\n */ function getLastValidMarkerInText(feedsWithPattern, text) {\n    let lastValidMarker;\n    for (const feed of feedsWithPattern){\n        const currentMarkerLastIndex = text.lastIndexOf(feed.marker);\n        if (currentMarkerLastIndex > 0 && !text.substring(currentMarkerLastIndex - 1).match(feed.pattern)) {\n            continue;\n        }\n        if (!lastValidMarker || currentMarkerLastIndex >= lastValidMarker.position) {\n            lastValidMarker = {\n                marker: feed.marker,\n                position: currentMarkerLastIndex,\n                minimumCharacters: feed.minimumCharacters,\n                pattern: feed.pattern\n            };\n        }\n    }\n    return lastValidMarker;\n}\n/**\n * Creates a RegExp pattern for the marker.\n *\n * Function has to be exported to achieve 100% code coverage.\n */ function createRegExp(marker, minimumCharacters) {\n    const numberOfCharacters = minimumCharacters == 0 ? '*' : `{${minimumCharacters},}`;\n    const openAfterCharacters = env.features.isRegExpUnicodePropertySupported ? '\\\\p{Ps}\\\\p{Pi}\"\\'' : '\\\\(\\\\[{\"\\'';\n    const mentionCharacters = '.';\n    // I wanted to make an util out of it, but since this regexp uses \"u\" flag, it became difficult.\n    // When \"u\" flag is used, the regexp has \"strict\" escaping rules, i.e. if you try to escape a character that does not need\n    // to be escaped, RegExp() will throw. It made it difficult to write a generic util, because different characters are\n    // allowed in different context. For example, escaping \"-\" sometimes was correct, but sometimes it threw an error.\n    marker = marker.replace(/[.*+?^${}()\\-|[\\]\\\\]/g, '\\\\$&');\n    // The pattern consists of 3 groups:\n    //\n    // - 0 (non-capturing): Opening sequence - start of the line, space or an opening punctuation character like \"(\" or \"\\\"\",\n    // - 1: The marker character,\n    // - 2: Mention input (taking the minimal length into consideration to trigger the UI),\n    //\n    // The pattern matches up to the caret (end of string switch - $).\n    //               (0:      opening sequence       )(1:   marker  )(2:                typed mention              )$\n    const pattern = `(?:^|[ ${openAfterCharacters}])([${marker}])(${mentionCharacters}${numberOfCharacters})$`;\n    return new RegExp(pattern, 'u');\n}\n/**\n * Creates a test callback for the marker to be used in the text watcher instance.\n *\n * @param feedsWithPattern Feeds of mention plugin configured in editor with RegExp to match marker in text\n */ function createTestCallback(feedsWithPattern) {\n    const textMatcher = (text)=>{\n        const markerDefinition = getLastValidMarkerInText(feedsWithPattern, text);\n        if (!markerDefinition) {\n            return false;\n        }\n        let splitStringFrom = 0;\n        if (markerDefinition.position !== 0) {\n            splitStringFrom = markerDefinition.position - 1;\n        }\n        const textToTest = text.substring(splitStringFrom);\n        return markerDefinition.pattern.test(textToTest);\n    };\n    return textMatcher;\n}\n/**\n * Creates a text matcher from the marker.\n */ function requestFeedText(markerDefinition, text) {\n    let splitStringFrom = 0;\n    if (markerDefinition.position !== 0) {\n        splitStringFrom = markerDefinition.position - 1;\n    }\n    const regExp = createRegExp(markerDefinition.marker, 0);\n    const textToMatch = text.substring(splitStringFrom);\n    const match = textToMatch.match(regExp);\n    return match[2];\n}\n/**\n * The default feed callback.\n */ function createFeedCallback(feedItems) {\n    return (feedText)=>{\n        const filteredItems = feedItems// Make the default mention feed case-insensitive.\n        .filter((item)=>{\n            // Item might be defined as object.\n            const itemId = typeof item == 'string' ? item : String(item.id);\n            // The default feed is case insensitive.\n            return itemId.toLowerCase().includes(feedText.toLowerCase());\n        });\n        return filteredItems;\n    };\n}\n/**\n * Checks if position in inside or right after a text with a mention.\n */ function isPositionInExistingMention(position) {\n    // The text watcher listens only to changed range in selection - so the selection attributes are not yet available\n    // and you cannot use selection.hasAttribute( 'mention' ) just yet.\n    // See https://github.com/ckeditor/ckeditor5-engine/issues/1723.\n    const hasMention = position.textNode && position.textNode.hasAttribute('mention');\n    const nodeBefore = position.nodeBefore;\n    return hasMention || nodeBefore && nodeBefore.is('$text') && nodeBefore.hasAttribute('mention');\n}\n/**\n * Checks if the closest marker offset is at the beginning of a mention.\n *\n * See https://github.com/ckeditor/ckeditor5/issues/11400.\n */ function isMarkerInExistingMention(markerPosition) {\n    const nodeAfter = markerPosition.nodeAfter;\n    return nodeAfter && nodeAfter.is('$text') && nodeAfter.hasAttribute('mention');\n}\n/**\n * Checks if string is a valid mention marker.\n */ function isValidMentionMarker(marker) {\n    return marker && marker.length == 1;\n}\n/**\n * Checks the mention plugins is in completion mode (e.g. when typing is after a valid mention string like @foo).\n */ function checkIfStillInCompletionMode(editor) {\n    return editor.model.markers.has('mention');\n}\n\n/**\n * The mention plugin.\n *\n * For a detailed overview, check the {@glink features/mentions Mention feature} guide.\n */ class Mention extends Plugin {\n    toMentionAttribute(viewElement, data) {\n        return _toMentionAttribute(viewElement, data);\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Mention';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            MentionEditing,\n            MentionUI\n        ];\n    }\n}\n\nexport { DomWrapperView, Mention, MentionEditing, MentionListItemView, MentionUI, MentionsView };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module mention/mentioncommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { Range } from 'ckeditor5/src/engine.js';\nimport { CKEditorError, toMap } from 'ckeditor5/src/utils.js';\n\nimport { _addMentionAttributes } from './mentionediting.js';\n\nconst BRACKET_PAIRS = {\n\t'(': ')',\n\t'[': ']',\n\t'{': '}'\n} as const;\n\n/**\n * The mention command.\n *\n * The command is registered by {@link module:mention/mentionediting~MentionEditing} as `'mention'`.\n *\n * To insert a mention into a range, execute the command and specify a mention object with a range to replace:\n *\n * ```ts\n * const focus = editor.model.document.selection.focus;\n *\n * // It will replace one character before the selection focus with the '#1234' text\n * // with the mention attribute filled with passed attributes.\n * editor.execute( 'mention', {\n * \tmarker: '#',\n * \tmention: {\n * \t\tid: '#1234',\n * \t\tname: 'Foo',\n * \t\ttitle: 'Big Foo'\n * \t},\n * \trange: editor.model.createRange( focus.getShiftedBy( -1 ), focus )\n * } );\n *\n * // It will replace one character before the selection focus with the 'The \"Big Foo\"' text\n * // with the mention attribute filled with passed attributes.\n * editor.execute( 'mention', {\n * \tmarker: '#',\n * \tmention: {\n * \t\tid: '#1234',\n * \t\tname: 'Foo',\n * \t\ttitle: 'Big Foo'\n * \t},\n * \ttext: 'The \"Big Foo\"',\n * \trange: editor.model.createRange( focus.getShiftedBy( -1 ), focus )\n * } );\n *\t```\n */\nexport default class MentionCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic constructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// Since this command may pass range in execution parameters, it should be checked directly in execute block.\n\t\tthis._isEnabledBasedOnSelection = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\n\t\tthis.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'mention' );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.mention The mention object to insert. When a string is passed, it will be used to create a plain\n\t * object with the name attribute that equals the passed string.\n\t * @param options.marker The marker character (e.g. `'@'`).\n\t * @param options.text The text of the inserted mention. Defaults to the full mention string composed from `marker` and\n\t * `mention` string or `mention.id` if an object is passed.\n\t * @param options.range The range to replace.\n\t * Note that the replaced range might be shorter than the inserted text with the mention attribute.\n\t * @fires execute\n\t */\n\tpublic override execute( options: {\n\t\tmention: string | { id: string; [ key: string ]: unknown };\n\t\tmarker: string;\n\t\ttext?: string;\n\t\trange?: Range;\n\t} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst selection = document.selection;\n\n\t\tconst mentionData = typeof options.mention == 'string' ? { id: options.mention } : options.mention;\n\t\tconst mentionID = mentionData.id;\n\n\t\tconst range = options.range || selection.getFirstRange();\n\n\t\t// Don't execute command if range is in non-editable place.\n\t\tif ( !model.canEditAt( range ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mentionText = options.text || mentionID;\n\n\t\tconst mention = _addMentionAttributes( { _text: mentionText, id: mentionID }, mentionData );\n\n\t\tif ( options.marker.length != 1 ) {\n\t\t\t/**\n\t\t\t * The marker must be a single character.\n\t\t\t *\n\t\t\t * Correct markers: `'@'`, `'#'`.\n\t\t\t *\n\t\t\t * Incorrect markers: `'@@'`, `'[@'`.\n\t\t\t *\n\t\t\t * See {@link module:mention/mentionconfig~MentionConfig}.\n\t\t\t *\n\t\t\t * @error mentioncommand-incorrect-marker\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'mentioncommand-incorrect-marker',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tif ( mentionID.charAt( 0 ) != options.marker ) {\n\t\t\t/**\n\t\t\t * The feed item ID must start with the marker character.\n\t\t\t *\n\t\t\t * Correct mention feed setting:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * mentions: [\n\t\t\t * \t{\n\t\t\t * \t\tmarker: '@',\n\t\t\t * \t\tfeed: [ '@Ann', '@Barney', ... ]\n\t\t\t * \t}\n\t\t\t * ]\n\t\t\t * ```\n\t\t\t *\n\t\t\t * Incorrect mention feed setting:\n\t\t\t *\n\t\t\t * ```ts\n\t\t\t * mentions: [\n\t\t\t * \t{\n\t\t\t * \t\tmarker: '@',\n\t\t\t * \t\tfeed: [ 'Ann', 'Barney', ... ]\n\t\t\t * \t}\n\t\t\t * ]\n\t\t\t * ```\n\t\t\t *\n\t\t\t * See {@link module:mention/mentionconfig~MentionConfig}.\n\t\t\t *\n\t\t\t * @error mentioncommand-incorrect-id\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'mentioncommand-incorrect-id',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst currentAttributes = toMap( selection.getAttributes() );\n\t\t\tconst attributesWithMention = new Map( currentAttributes.entries() );\n\n\t\t\tattributesWithMention.set( 'mention', mention );\n\n\t\t\t// Replace a range with the text with a mention.\n\t\t\tconst insertionRange = model.insertContent( writer.createText( mentionText, attributesWithMention ), range );\n\t\t\tconst nodeBefore = insertionRange.start.nodeBefore;\n\t\t\tconst nodeAfter = insertionRange.end.nodeAfter;\n\n\t\t\tconst isFollowedByWhiteSpace = nodeAfter && nodeAfter.is( '$text' ) && nodeAfter.data.startsWith( ' ' );\n\t\t\tlet isInsertedInBrackets = false;\n\n\t\t\tif ( nodeBefore && nodeAfter && nodeBefore.is( '$text' ) && nodeAfter.is( '$text' ) ) {\n\t\t\t\tconst precedingCharacter = nodeBefore.data.slice( -1 );\n\t\t\t\tconst isPrecededByOpeningBracket = precedingCharacter in BRACKET_PAIRS;\n\t\t\t\tconst isFollowedByBracketClosure = isPrecededByOpeningBracket && nodeAfter.data.startsWith(\n\t\t\t\t\tBRACKET_PAIRS[ precedingCharacter as keyof typeof BRACKET_PAIRS ]\n\t\t\t\t);\n\n\t\t\t\tisInsertedInBrackets = isPrecededByOpeningBracket && isFollowedByBracketClosure;\n\t\t\t}\n\n\t\t\t// Don't add a white space if either of the following is true:\n\t\t\t// * there's already one after the mention;\n\t\t\t// * the mention was inserted in the empty matching brackets.\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/4651\n\t\t\tif ( !isInsertedInBrackets && !isFollowedByWhiteSpace ) {\n\t\t\t\tmodel.insertContent( writer.createText( ' ', currentAttributes ), range!.start.getShiftedBy( mentionText.length ) );\n\t\t\t}\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module mention/mentionediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type {\n\tElement,\n\tText,\n\tWriter,\n\tDocument,\n\tAttributeElement,\n\tDowncastConversionApi,\n\tDowncastDispatcher,\n\tPosition,\n\tSchema,\n\tDowncastAttributeEvent,\n\tItem\n} from 'ckeditor5/src/engine.js';\nimport { uid } from 'ckeditor5/src/utils.js';\n\nimport MentionCommand from './mentioncommand.js';\nimport type { MentionAttribute } from './mention.js';\n\n/**\n * The mention editing feature.\n *\n * It introduces the {@link module:mention/mentioncommand~MentionCommand command} and the `mention`\n * attribute in the {@link module:engine/model/model~Model model} which renders in the {@link module:engine/view/view view}\n * as a `<span class=\"mention\" data-mention=\"@mention\">`.\n */\nexport default class MentionEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'MentionEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst doc = model.document;\n\n\t\t// Allow the mention attribute on all text nodes.\n\t\tmodel.schema.extend( '$text', { allowAttributes: 'mention' } );\n\n\t\t// Upcast conversion.\n\t\teditor.conversion.for( 'upcast' ).elementToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: 'span',\n\t\t\t\tkey: 'data-mention',\n\t\t\t\tclasses: 'mention'\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'mention',\n\t\t\t\tvalue: ( viewElement: Element ) => _toMentionAttribute( viewElement )\n\t\t\t}\n\t\t} );\n\n\t\t// Downcast conversion.\n\t\teditor.conversion.for( 'downcast' ).attributeToElement( {\n\t\t\tmodel: 'mention',\n\t\t\tview: createViewMentionElement\n\t\t} );\n\t\teditor.conversion.for( 'downcast' ).add( preventPartialMentionDowncast );\n\n\t\tdoc.registerPostFixer( writer => removePartialMentionPostFixer( writer, doc, model.schema ) );\n\t\tdoc.registerPostFixer( writer => extendAttributeOnMentionPostFixer( writer, doc ) );\n\t\tdoc.registerPostFixer( writer => selectionMentionAttributePostFixer( writer, doc ) );\n\n\t\teditor.commands.add( 'mention', new MentionCommand( editor ) );\n\t}\n}\n\n/**\n * @internal\n */\nexport function _addMentionAttributes(\n\tbaseMentionData: { id: string; _text: string },\n\tdata?: Record<string, unknown>\n): MentionAttribute {\n\treturn Object.assign( { uid: uid() }, baseMentionData, data || {} );\n}\n\n/**\n * Creates a mention attribute value from the provided view element and optional data.\n *\n * This function is exposed as\n * {@link module:mention/mention~Mention#toMentionAttribute `editor.plugins.get( 'Mention' ).toMentionAttribute()`}.\n *\n * @internal\n */\nexport function _toMentionAttribute(\n\tviewElementOrMention: Element,\n\tdata?: Record<string, unknown>\n): MentionAttribute | undefined {\n\tconst dataMention = viewElementOrMention.getAttribute( 'data-mention' ) as string;\n\n\tconst textNode = viewElementOrMention.getChild( 0 ) as Text;\n\n\t// Do not convert empty mentions.\n\tif ( !textNode ) {\n\t\treturn;\n\t}\n\n\tconst baseMentionData = {\n\t\tid: dataMention,\n\t\t_text: textNode.data\n\t};\n\n\treturn _addMentionAttributes( baseMentionData, data );\n}\n\n/**\n * A converter that blocks partial mention from being converted.\n *\n * This converter is registered with 'highest' priority in order to consume mention attribute before it is converted by\n * any other converters. This converter only consumes partial mention - those whose `_text` attribute is not equal to text with mention\n * attribute. This may happen when copying part of mention text.\n */\nfunction preventPartialMentionDowncast( dispatcher: DowncastDispatcher ) {\n\tdispatcher.on<DowncastAttributeEvent>( 'attribute:mention', ( evt, data, conversionApi ) => {\n\t\tconst mention = data.attributeNewValue as MentionAttribute;\n\n\t\tif ( !data.item.is( '$textProxy' ) || !mention ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst start = data.range.start;\n\t\tconst textNode = start.textNode || start.nodeAfter as Text;\n\n\t\tif ( textNode!.data != mention._text ) {\n\t\t\t// Consume item to prevent partial mention conversion.\n\t\t\tconversionApi.consumable.consume( data.item, evt.name );\n\t\t}\n\t}, { priority: 'highest' } );\n}\n\n/**\n * Creates a mention element from the mention data.\n */\nfunction createViewMentionElement( mention: MentionAttribute, { writer }: DowncastConversionApi ): AttributeElement | undefined {\n\tif ( !mention ) {\n\t\treturn;\n\t}\n\n\tconst attributes = {\n\t\tclass: 'mention',\n\t\t'data-mention': mention.id\n\t};\n\n\tconst options = {\n\t\tid: mention.uid,\n\t\tpriority: 20\n\t};\n\n\treturn writer.createAttributeElement( 'span', attributes, options );\n}\n\n/**\n * Model post-fixer that disallows typing with selection when the selection is placed after the text node with the mention attribute or\n * before a text node with mention attribute.\n */\nfunction selectionMentionAttributePostFixer( writer: Writer, doc: Document ): boolean {\n\tconst selection = doc.selection;\n\tconst focus = selection.focus;\n\n\tif ( selection.isCollapsed && selection.hasAttribute( 'mention' ) && shouldNotTypeWithMentionAt( focus! ) ) {\n\t\twriter.removeSelectionAttribute( 'mention' );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Helper function to detect if mention attribute should be removed from selection.\n * This check makes only sense if the selection has mention attribute.\n *\n * The mention attribute should be removed from a selection when selection focus is placed:\n * a) after a text node\n * b) the position is at parents start - the selection will set attributes from node after.\n */\nfunction shouldNotTypeWithMentionAt( position: Position ): boolean {\n\tconst isAtStart = position.isAtStart;\n\tconst isAfterAMention = position.nodeBefore && position.nodeBefore.is( '$text' );\n\n\treturn isAfterAMention || isAtStart;\n}\n\n/**\n * Model post-fixer that removes the mention attribute from the modified text node.\n */\nfunction removePartialMentionPostFixer( writer: Writer, doc: Document, schema: Schema ): boolean {\n\tconst changes = doc.differ.getChanges();\n\n\tlet wasChanged = false;\n\n\tfor ( const change of changes ) {\n\t\tif ( change.type == 'attribute' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Checks the text node on the current position.\n\t\tconst position = change.position;\n\n\t\tif ( change.name == '$text' ) {\n\t\t\tconst nodeAfterInsertedTextNode = position.textNode && position.textNode.nextSibling;\n\n\t\t\t// Checks the text node where the change occurred.\n\t\t\twasChanged = checkAndFix( position.textNode, writer ) || wasChanged;\n\n\t\t\t// Occurs on paste inside a text node with mention.\n\t\t\twasChanged = checkAndFix( nodeAfterInsertedTextNode, writer ) || wasChanged;\n\t\t\twasChanged = checkAndFix( position.nodeBefore, writer ) || wasChanged;\n\t\t\twasChanged = checkAndFix( position.nodeAfter, writer ) || wasChanged;\n\t\t}\n\n\t\t// Checks text nodes in inserted elements (might occur when splitting a paragraph or pasting content inside text with mention).\n\t\tif ( change.name != '$text' && change.type == 'insert' ) {\n\t\t\tconst insertedNode = position.nodeAfter as Element;\n\n\t\t\tfor ( const item of writer.createRangeIn( insertedNode! ).getItems() ) {\n\t\t\t\twasChanged = checkAndFix( item, writer ) || wasChanged;\n\t\t\t}\n\t\t}\n\n\t\t// Inserted inline elements might break mention.\n\t\tif ( change.type == 'insert' && schema.isInline( change.name ) ) {\n\t\t\tconst nodeAfterInserted = position.nodeAfter && position.nodeAfter.nextSibling;\n\n\t\t\twasChanged = checkAndFix( position.nodeBefore, writer ) || wasChanged;\n\t\t\twasChanged = checkAndFix( nodeAfterInserted, writer ) || wasChanged;\n\t\t}\n\t}\n\n\treturn wasChanged;\n}\n\n/**\n * This post-fixer will extend the attribute applied on the part of the mention so the whole text node of the mention will have\n * the added attribute.\n */\nfunction extendAttributeOnMentionPostFixer( writer: Writer, doc: Document ): boolean {\n\tconst changes = doc.differ.getChanges();\n\n\tlet wasChanged = false;\n\n\tfor ( const change of changes ) {\n\t\tif ( change.type === 'attribute' && change.attributeKey != 'mention' ) {\n\t\t\t// Checks the node on the left side of the range...\n\t\t\tconst nodeBefore = change.range.start.nodeBefore;\n\t\t\t// ... and on the right side of the range.\n\t\t\tconst nodeAfter = change.range.end.nodeAfter;\n\n\t\t\tfor ( const node of [ nodeBefore, nodeAfter ] ) {\n\t\t\t\tif ( isBrokenMentionNode( node ) && node!.getAttribute( change.attributeKey ) != change.attributeNewValue ) {\n\t\t\t\t\twriter.setAttribute( change.attributeKey, change.attributeNewValue, node! );\n\n\t\t\t\t\twasChanged = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn wasChanged;\n}\n\n/**\n * Checks if a node has a correct mention attribute if present.\n * Returns `true` if the node is text and has a mention attribute whose text does not match the expected mention text.\n */\nfunction isBrokenMentionNode( node: Item | null ): boolean {\n\tif ( !node || !( node.is( '$text' ) || node.is( '$textProxy' ) ) || !node.hasAttribute( 'mention' ) ) {\n\t\treturn false;\n\t}\n\n\tconst text = node.data;\n\tconst mention = node.getAttribute( 'mention' ) as MentionAttribute;\n\n\tconst expectedText = mention._text;\n\n\treturn text != expectedText;\n}\n\n/**\n * Fixes a mention on a text node if it needs a fix.\n */\nfunction checkAndFix( textNode: Item | null, writer: Writer ): boolean {\n\tif ( isBrokenMentionNode( textNode ) ) {\n\t\twriter.removeAttribute( 'mention', textNode! );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module mention/ui/mentionsview\n */\n\nimport { ListView } from 'ckeditor5/src/ui.js';\nimport { Rect, type Locale } from 'ckeditor5/src/utils.js';\n\nimport type MentionListItemView from './mentionlistitemview.js';\n\nimport '../../theme/mentionui.css';\n\n/**\n * The mention ui view.\n */\nexport default class MentionsView extends ListView {\n\tpublic selected: MentionListItemView | undefined;\n\n\tpublic position: string | undefined;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tthis.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-mentions'\n\t\t\t\t],\n\n\t\t\t\ttabindex: '-1'\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * {@link #select Selects} the first item.\n\t */\n\tpublic selectFirst(): void {\n\t\tthis.select( 0 );\n\t}\n\n\t/**\n\t * Selects next item to the currently {@link #select selected}.\n\t *\n\t * If the last item is already selected, it will select the first item.\n\t */\n\tpublic selectNext(): void {\n\t\tconst item = this.selected;\n\t\tconst index = this.items.getIndex( item! );\n\n\t\tthis.select( index + 1 );\n\t}\n\n\t/**\n\t * Selects previous item to the currently {@link #select selected}.\n\t *\n\t * If the first item is already selected, it will select the last item.\n\t */\n\tpublic selectPrevious(): void {\n\t\tconst item = this.selected;\n\t\tconst index = this.items.getIndex( item! );\n\n\t\tthis.select( index - 1 );\n\t}\n\n\t/**\n\t * Marks item at a given index as selected.\n\t *\n\t * Handles selection cycling when passed index is out of bounds:\n\t * - if the index is lower than 0, it will select the last item,\n\t * - if the index is higher than the last item index, it will select the first item.\n\t *\n\t * @param index Index of an item to be marked as selected.\n\t */\n\tpublic select( index: number ): void {\n\t\tlet indexToGet = 0;\n\n\t\tif ( index > 0 && index < this.items.length ) {\n\t\t\tindexToGet = index;\n\t\t} else if ( index < 0 ) {\n\t\t\tindexToGet = this.items.length - 1;\n\t\t}\n\n\t\tconst item = this.items.get( indexToGet ) as MentionListItemView;\n\n\t\t// Return early if item is already selected.\n\t\tif ( this.selected === item ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight of previously selected item.\n\t\tif ( this.selected ) {\n\t\t\tthis.selected.removeHighlight();\n\t\t}\n\n\t\titem.highlight();\n\t\tthis.selected = item;\n\n\t\t// Scroll the mentions view to the selected element.\n\t\tif ( !this._isItemVisibleInScrolledArea( item ) ) {\n\t\t\tthis.element!.scrollTop = item.element!.offsetTop;\n\t\t}\n\t}\n\n\t/**\n\t * Triggers the `execute` event on the {@link #select selected} item.\n\t */\n\tpublic executeSelected(): void {\n\t\tthis.selected!.fire( 'execute' );\n\t}\n\n\t/**\n\t * Checks if an item is visible in the scrollable area.\n\t *\n\t * The item is considered visible when:\n\t * - its top boundary is inside the scrollable rect\n\t * - its bottom boundary is inside the scrollable rect (the whole item must be visible)\n\t */\n\tprivate _isItemVisibleInScrolledArea( item: MentionListItemView ) {\n\t\treturn new Rect( this.element! ).contains( new Rect( item.element! ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module mention/ui/domwrapperview\n */\n\nimport { View } from 'ckeditor5/src/ui.js';\nimport type { Locale } from 'ckeditor5/src/utils.js';\n\n/**\n * This class wraps DOM element as a CKEditor5 UI View.\n *\n * It allows to render any DOM element and use it in mentions list.\n */\nexport default class DomWrapperView extends View {\n\t/**\n\t * The DOM element for which wrapper was created.\n\t */\n\tpublic domElement: HTMLElement;\n\n\t/**\n\t * Controls whether the dom wrapper view is \"on\". This is in line with {@link module:ui/button/button~Button#isOn} property.\n\t *\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public isOn: boolean;\n\n\t/**\n\t * Creates an instance of {@link module:mention/ui/domwrapperview~DomWrapperView} class.\n\t *\n\t * Also see {@link #render}.\n\t */\n\tconstructor( locale: Locale, domElement: HTMLElement ) {\n\t\tsuper( locale );\n\n\t\t// Disable template rendering on this view.\n\t\tthis.template = undefined;\n\n\t\tthis.domElement = domElement;\n\n\t\t// Render dom wrapper as a button.\n\t\tthis.domElement.classList.add( 'ck-button' );\n\n\t\tthis.set( 'isOn', false );\n\n\t\t// Handle isOn state as in buttons.\n\t\tthis.on( 'change:isOn', ( evt, name, isOn ) => {\n\t\t\tif ( isOn ) {\n\t\t\t\tthis.domElement.classList.add( 'ck-on' );\n\t\t\t\tthis.domElement.classList.remove( 'ck-off' );\n\t\t\t} else {\n\t\t\t\tthis.domElement.classList.add( 'ck-off' );\n\t\t\t\tthis.domElement.classList.remove( 'ck-on' );\n\t\t\t}\n\t\t} );\n\n\t\t// Pass click event as execute event.\n\t\tthis.listenTo( this.domElement, 'click', () => {\n\t\t\tthis.fire( 'execute' );\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\tthis.element = this.domElement;\n\t}\n\n\t/**\n\t * Focuses the DOM element.\n\t */\n\tpublic focus(): void {\n\t\tthis.domElement.focus();\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module mention/ui/mentionlistitemview\n */\n\nimport { ListItemView } from 'ckeditor5/src/ui.js';\n\nimport type { MentionFeedItem } from '../mentionconfig.js';\n\nimport type DomWrapperView from './domwrapperview.js';\n\nexport default class MentionListItemView extends ListItemView {\n\tpublic item!: MentionFeedItem;\n\n\tpublic marker!: string;\n\n\tpublic highlight(): void {\n\t\tconst child = this.children.first as DomWrapperView;\n\n\t\tchild.isOn = true;\n\t}\n\n\tpublic removeHighlight(): void {\n\t\tconst child = this.children.first as DomWrapperView;\n\n\t\tchild.isOn = false;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module mention/mentionui\n */\n\nimport {\n\tPlugin,\n\ttype Editor\n} from 'ckeditor5/src/core.js';\n\nimport type {\n\tViewDocumentKeyDownEvent,\n\tMarker,\n\tPosition\n} from 'ckeditor5/src/engine.js';\n\nimport {\n\tButtonView,\n\tContextualBalloon,\n\tclickOutsideHandler\n} from 'ckeditor5/src/ui.js';\n\nimport {\n\tCKEditorError,\n\tCollection,\n\tRect,\n\tenv,\n\tkeyCodes,\n\tlogWarning,\n\ttype PositionOptions\n} from 'ckeditor5/src/utils.js';\n\nimport { TextWatcher, type TextWatcherMatchedEvent } from 'ckeditor5/src/typing.js';\n\nimport { debounce } from 'lodash-es';\n\nimport MentionsView from './ui/mentionsview.js';\nimport DomWrapperView from './ui/domwrapperview.js';\nimport MentionListItemView from './ui/mentionlistitemview.js';\n\nimport type {\n\tFeedCallback,\n\tMentionFeed,\n\tMentionFeedItem,\n\tItemRenderer,\n\tMentionFeedObjectItem\n} from './mentionconfig.js';\n\nconst VERTICAL_SPACING = 3;\n\n// The key codes that mention UI handles when it is open (without commit keys).\nconst defaultHandledKeyCodes = [\n\tkeyCodes.arrowup,\n\tkeyCodes.arrowdown,\n\tkeyCodes.esc\n];\n\n// Dropdown commit key codes.\nconst defaultCommitKeyCodes = [\n\tkeyCodes.enter,\n\tkeyCodes.tab\n];\n\n/**\n * The mention UI feature.\n */\nexport default class MentionUI extends Plugin {\n\t/**\n\t * The mention view.\n\t */\n\tprivate readonly _mentionsView: MentionsView;\n\n\t/**\n\t * Stores mention feeds configurations.\n\t */\n\tprivate _mentionsConfigurations: Map<string, Definition>;\n\n\t/**\n\t * The contextual balloon plugin instance.\n\t */\n\tprivate _balloon: ContextualBalloon | undefined;\n\n\tprivate _items = new Collection<{ item: MentionFeedObjectItem; marker: string }>();\n\n\tprivate _lastRequested?: string;\n\n\t/**\n\t * Debounced feed requester. It uses `lodash#debounce` method to delay function call.\n\t */\n\tprivate _requestFeedDebounced: ( marker: string, feedText: string ) => void;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'MentionUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._mentionsView = this._createMentionView();\n\t\tthis._mentionsConfigurations = new Map();\n\t\tthis._requestFeedDebounced = debounce( this._requestFeed, 100 );\n\n\t\teditor.config.define( 'mention', { feeds: [] } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\tconst commitKeys = editor.config.get( 'mention.commitKeys' ) || defaultCommitKeyCodes;\n\t\tconst handledKeyCodes = defaultHandledKeyCodes.concat( commitKeys );\n\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\n\t\t// Key listener that handles navigation in mention view.\n\t\teditor.editing.view.document.on<ViewDocumentKeyDownEvent>( 'keydown', ( evt, data ) => {\n\t\t\tif ( isHandledKey( data.keyCode ) && this._isUIVisible ) {\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop(); // Required for Enter key overriding.\n\n\t\t\t\tif ( data.keyCode == keyCodes.arrowdown ) {\n\t\t\t\t\tthis._mentionsView.selectNext();\n\t\t\t\t}\n\n\t\t\t\tif ( data.keyCode == keyCodes.arrowup ) {\n\t\t\t\t\tthis._mentionsView.selectPrevious();\n\t\t\t\t}\n\n\t\t\t\tif ( commitKeys.includes( data.keyCode ) ) {\n\t\t\t\t\tthis._mentionsView.executeSelected();\n\t\t\t\t}\n\n\t\t\t\tif ( data.keyCode == keyCodes.esc ) {\n\t\t\t\t\tthis._hideUIAndRemoveMarker();\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'highest' } ); // Required to override the Enter key.\n\n\t\t// Close the dropdown upon clicking outside of the plugin UI.\n\t\tclickOutsideHandler( {\n\t\t\temitter: this._mentionsView,\n\t\t\tactivator: () => this._isUIVisible,\n\t\t\tcontextElements: () => [ this._balloon!.view.element! ],\n\t\t\tcallback: () => this._hideUIAndRemoveMarker()\n\t\t} );\n\n\t\tconst feeds = editor.config.get( 'mention.feeds' )!;\n\n\t\tfor ( const mentionDescription of feeds ) {\n\t\t\tconst { feed, marker, dropdownLimit } = mentionDescription;\n\n\t\t\tif ( !isValidMentionMarker( marker ) ) {\n\t\t\t\t/**\n\t\t\t\t * The marker must be a single character.\n\t\t\t\t *\n\t\t\t\t * Correct markers: `'@'`, `'#'`.\n\t\t\t\t *\n\t\t\t\t * Incorrect markers: `'$$'`, `'[@'`.\n\t\t\t\t *\n\t\t\t\t * See {@link module:mention/mentionconfig~MentionConfig}.\n\t\t\t\t *\n\t\t\t\t * @error mentionconfig-incorrect-marker\n\t\t\t\t * @param marker Configured marker\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError( 'mentionconfig-incorrect-marker', null, { marker } );\n\t\t\t}\n\n\t\t\tconst feedCallback = typeof feed == 'function' ? feed.bind( this.editor ) : createFeedCallback( feed );\n\t\t\tconst itemRenderer = mentionDescription.itemRenderer;\n\t\t\tconst definition = { marker, feedCallback, itemRenderer, dropdownLimit };\n\n\t\t\tthis._mentionsConfigurations.set( marker, definition );\n\t\t}\n\n\t\tthis._setupTextWatcher( feeds );\n\t\tthis.listenTo( editor, 'change:isReadOnly', () => {\n\t\t\tthis._hideUIAndRemoveMarker();\n\t\t} );\n\t\tthis.on<RequestFeedResponseEvent>( 'requestFeed:response', ( evt, data ) => this._handleFeedResponse( data ) );\n\t\tthis.on<RequestFeedErrorEvent>( 'requestFeed:error', () => this._hideUIAndRemoveMarker() );\n\n\t\t/**\n\t\t * Checks if a given key code is handled by the mention UI.\n\t\t */\n\t\tfunction isHandledKey( keyCode: number ): boolean {\n\t\t\treturn handledKeyCodes.includes( keyCode );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).\n\t\tthis._mentionsView.destroy();\n\t}\n\n\t/**\n\t * Returns true when {@link #_mentionsView} is in the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} and it is\n\t * currently visible.\n\t */\n\tprivate get _isUIVisible(): boolean {\n\t\treturn this._balloon!.visibleView === this._mentionsView;\n\t}\n\n\t/**\n\t * Creates the {@link #_mentionsView}.\n\t */\n\tprivate _createMentionView(): MentionsView {\n\t\tconst locale = this.editor.locale;\n\n\t\tconst mentionsView = new MentionsView( locale );\n\n\t\tmentionsView.items.bindTo( this._items ).using( data => {\n\t\t\tconst { item, marker } = data;\n\n\t\t\tconst { dropdownLimit: markerDropdownLimit } = this._mentionsConfigurations.get( marker )!;\n\n\t\t\t// Set to 10 by default for backwards compatibility. See: #10479\n\t\t\tconst dropdownLimit = markerDropdownLimit || this.editor.config.get( 'mention.dropdownLimit' ) || 10;\n\n\t\t\tif ( mentionsView.items.length >= dropdownLimit ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst listItemView = new MentionListItemView( locale );\n\n\t\t\tconst view = this._renderItem( item, marker );\n\t\t\tview.delegate( 'execute' ).to( listItemView );\n\n\t\t\tlistItemView.children.add( view );\n\t\t\tlistItemView.item = item;\n\t\t\tlistItemView.marker = marker;\n\n\t\t\tlistItemView.on( 'execute', () => {\n\t\t\t\tmentionsView.fire( 'execute', {\n\t\t\t\t\titem,\n\t\t\t\t\tmarker\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\treturn listItemView;\n\t\t} );\n\n\t\tmentionsView.on( 'execute', ( evt, data ) => {\n\t\t\tconst editor = this.editor;\n\t\t\tconst model = editor.model;\n\n\t\t\tconst item = data.item;\n\t\t\tconst marker = data.marker;\n\n\t\t\tconst mentionMarker = editor.model.markers.get( 'mention' );\n\n\t\t\t// Create a range on matched text.\n\t\t\tconst end = model.createPositionAt( model.document.selection.focus! );\n\t\t\tconst start = model.createPositionAt( mentionMarker!.getStart() );\n\t\t\tconst range = model.createRange( start, end );\n\n\t\t\tthis._hideUIAndRemoveMarker();\n\n\t\t\teditor.execute( 'mention', {\n\t\t\t\tmention: item,\n\t\t\t\ttext: item.text,\n\t\t\t\tmarker,\n\t\t\t\trange\n\t\t\t} );\n\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn mentionsView;\n\t}\n\n\t/**\n\t * Returns item renderer for the marker.\n\t */\n\tprivate _getItemRenderer( marker: string ): ItemRenderer | undefined {\n\t\tconst { itemRenderer } = this._mentionsConfigurations.get( marker )!;\n\n\t\treturn itemRenderer;\n\t}\n\n\t/**\n\t * Requests a feed from a configured callbacks.\n\t */\n\tprivate _requestFeed( marker: string, feedText: string ): void {\n\t\t// @if CK_DEBUG_MENTION // console.log( '%c[Feed]%c Requesting for', 'color: blue', 'color: black', `\"${ feedText }\"` );\n\n\t\t// Store the last requested feed - it is used to discard any out-of order requests.\n\t\tthis._lastRequested = feedText;\n\n\t\tconst { feedCallback } = this._mentionsConfigurations.get( marker )!;\n\t\tconst feedResponse = feedCallback( feedText );\n\n\t\tconst isAsynchronous = feedResponse instanceof Promise;\n\n\t\t// For synchronous feeds (e.g. callbacks, arrays) fire the response event immediately.\n\t\tif ( !isAsynchronous ) {\n\t\t\tthis.fire<RequestFeedResponseEvent>( 'requestFeed:response', { feed: feedResponse, marker, feedText } );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle the asynchronous responses.\n\t\tfeedResponse\n\t\t\t.then( response => {\n\t\t\t\t// Check the feed text of this response with the last requested one so either:\n\t\t\t\tif ( this._lastRequested == feedText ) {\n\t\t\t\t\t// It is the same and fire the response event.\n\t\t\t\t\tthis.fire<RequestFeedResponseEvent>( 'requestFeed:response', { feed: response, marker, feedText } );\n\t\t\t\t} else {\n\t\t\t\t\t// It is different - most probably out-of-order one, so fire the discarded event.\n\t\t\t\t\tthis.fire<RequestFeedDiscardedEvent>( 'requestFeed:discarded', { feed: response, marker, feedText } );\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.catch( error => {\n\t\t\t\tthis.fire<RequestFeedErrorEvent>( 'requestFeed:error', { error } );\n\n\t\t\t\t/**\n\t\t\t\t * The callback used for obtaining mention autocomplete feed thrown and error and the mention UI was hidden or\n\t\t\t\t * not displayed at all.\n\t\t\t\t *\n\t\t\t\t * @error mention-feed-callback-error\n\t\t\t\t */\n\t\t\t\tlogWarning( 'mention-feed-callback-error', { marker } );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Registers a text watcher for the marker.\n\t */\n\tprivate _setupTextWatcher( feeds: Array<MentionFeed> ): TextWatcher {\n\t\tconst editor = this.editor;\n\n\t\tconst feedsWithPattern: Array<MentionFeed & { pattern: RegExp }> = feeds.map( feed => ( {\n\t\t\t...feed,\n\t\t\tpattern: createRegExp( feed.marker, feed.minimumCharacters || 0 )\n\t\t} ) );\n\n\t\tconst watcher = new TextWatcher( editor.model, createTestCallback( feedsWithPattern ) );\n\n\t\twatcher.on<TextWatcherMatchedEvent>( 'matched', ( evt, data ) => {\n\t\t\tconst markerDefinition = getLastValidMarkerInText( feedsWithPattern, data.text );\n\t\t\tconst selection = editor.model.document.selection;\n\t\t\tconst focus = selection.focus;\n\t\t\tconst markerPosition = editor.model.createPositionAt( focus!.parent, markerDefinition!.position );\n\n\t\t\tif ( isPositionInExistingMention( focus! ) || isMarkerInExistingMention( markerPosition ) ) {\n\t\t\t\tthis._hideUIAndRemoveMarker();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst feedText = requestFeedText( markerDefinition, data.text );\n\t\t\tconst matchedTextLength = markerDefinition!.marker.length + feedText.length;\n\n\t\t\t// Create a marker range.\n\t\t\tconst start = focus!.getShiftedBy( -matchedTextLength );\n\t\t\tconst end = focus!.getShiftedBy( -feedText.length );\n\n\t\t\tconst markerRange = editor.model.createRange( start, end );\n\n\t\t\t// @if CK_DEBUG_MENTION // console.group( '%c[TextWatcher]%c matched', 'color: red', 'color: black', `\"${ feedText }\"` );\n\t\t\t// @if CK_DEBUG_MENTION // console.log( 'data#text', `\"${ data.text }\"` );\n\t\t\t// @if CK_DEBUG_MENTION // console.log( 'data#range', data.range.start.path, data.range.end.path );\n\t\t\t// @if CK_DEBUG_MENTION // console.log( 'marker definition', markerDefinition );\n\t\t\t// @if CK_DEBUG_MENTION // console.log( 'marker range', markerRange.start.path, markerRange.end.path );\n\n\t\t\tif ( checkIfStillInCompletionMode( editor ) ) {\n\t\t\t\tconst mentionMarker = editor.model.markers.get( 'mention' )!;\n\n\t\t\t\t// Update the marker - user might've moved the selection to other mention trigger.\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\t// @if CK_DEBUG_MENTION // console.log( '%c[Editing]%c Updating the marker.', 'color: purple', 'color: black' );\n\n\t\t\t\t\twriter.updateMarker( mentionMarker, { range: markerRange } );\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\t// @if CK_DEBUG_MENTION // console.log( '%c[Editing]%c Adding the marker.', 'color: purple', 'color: black' );\n\n\t\t\t\t\twriter.addMarker( 'mention', { range: markerRange, usingOperation: false, affectsData: false } );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\tthis._requestFeedDebounced( markerDefinition!.marker, feedText );\n\n\t\t\t// @if CK_DEBUG_MENTION // console.groupEnd();\n\t\t} );\n\n\t\twatcher.on( 'unmatched', () => {\n\t\t\tthis._hideUIAndRemoveMarker();\n\t\t} );\n\n\t\tconst mentionCommand = editor.commands.get( 'mention' )!;\n\t\twatcher.bind( 'isEnabled' ).to( mentionCommand );\n\n\t\treturn watcher;\n\t}\n\n\t/**\n\t * Handles the feed response event data.\n\t */\n\tprivate _handleFeedResponse( data: RequestFeedResponseEvent['args'][0] ) {\n\t\tconst { feed, marker } = data;\n\n\t\t// eslint-disable-next-line max-len\n\t\t// @if CK_DEBUG_MENTION // console.log( `%c[Feed]%c Response for \"${ data.feedText }\" (${ feed.length })`, 'color: blue', 'color: black', feed );\n\n\t\t// If the marker is not in the document happens when the selection had changed and the 'mention' marker was removed.\n\t\tif ( !checkIfStillInCompletionMode( this.editor ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Reset the view.\n\t\tthis._items.clear();\n\n\t\tfor ( const feedItem of feed ) {\n\t\t\tconst item = typeof feedItem != 'object' ? { id: feedItem, text: feedItem } : feedItem;\n\n\t\t\tthis._items.add( { item, marker } );\n\t\t}\n\n\t\tconst mentionMarker = this.editor.model.markers.get( 'mention' );\n\n\t\tif ( this._items.length ) {\n\t\t\tthis._showOrUpdateUI( mentionMarker! );\n\t\t} else {\n\t\t\t// Do not show empty mention UI.\n\t\t\tthis._hideUIAndRemoveMarker();\n\t\t}\n\t}\n\n\t/**\n\t * Shows the mentions balloon. If the panel is already visible, it will reposition it.\n\t */\n\tprivate _showOrUpdateUI( markerMarker: Marker ): void {\n\t\tif ( this._isUIVisible ) {\n\t\t\t// @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Updating position.', 'color: green', 'color: black' );\n\n\t\t\t// Update balloon position as the mention list view may change its size.\n\t\t\tthis._balloon!.updatePosition( this._getBalloonPanelPositionData( markerMarker, this._mentionsView!.position ) );\n\t\t} else {\n\t\t\t// @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Showing the UI.', 'color: green', 'color: black' );\n\n\t\t\tthis._balloon!.add( {\n\t\t\t\tview: this._mentionsView,\n\t\t\t\tposition: this._getBalloonPanelPositionData( markerMarker, this._mentionsView.position ),\n\t\t\t\tsingleViewMode: true\n\t\t\t} );\n\t\t}\n\n\t\tthis._mentionsView.position = this._balloon!.view.position;\n\t\tthis._mentionsView.selectFirst();\n\t}\n\n\t/**\n\t * Hides the mentions balloon and removes the 'mention' marker from the markers collection.\n\t */\n\tprivate _hideUIAndRemoveMarker(): void {\n\t\t// Remove the mention view from balloon before removing marker - it is used by balloon position target().\n\t\tif ( this._balloon!.hasView( this._mentionsView ) ) {\n\t\t\t// @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Hiding the UI.', 'color: green', 'color: black' );\n\n\t\t\tthis._balloon!.remove( this._mentionsView );\n\t\t}\n\n\t\tif ( checkIfStillInCompletionMode( this.editor ) ) {\n\t\t\t// @if CK_DEBUG_MENTION // console.log( '%c[Editing]%c Removing marker.', 'color: purple', 'color: black' );\n\n\t\t\tthis.editor.model.change( writer => writer.removeMarker( 'mention' ) );\n\t\t}\n\n\t\t// Make the last matched position on panel view undefined so the #_getBalloonPanelPositionData() method will return all positions\n\t\t// on the next call.\n\t\tthis._mentionsView.position = undefined;\n\t}\n\n\t/**\n\t * Renders a single item in the autocomplete list.\n\t */\n\tprivate _renderItem( item: MentionFeedObjectItem, marker: string ): DomWrapperView | ButtonView {\n\t\tconst editor = this.editor;\n\n\t\tlet view;\n\t\tlet label = item.id;\n\n\t\tconst renderer = this._getItemRenderer( marker );\n\n\t\tif ( renderer ) {\n\t\t\tconst renderResult = renderer( item );\n\n\t\t\tif ( typeof renderResult != 'string' ) {\n\t\t\t\tview = new DomWrapperView( editor.locale, renderResult );\n\t\t\t} else {\n\t\t\t\tlabel = renderResult;\n\t\t\t}\n\t\t}\n\n\t\tif ( !view ) {\n\t\t\tconst buttonView = new ButtonView( editor.locale );\n\n\t\t\tbuttonView.label = label;\n\t\t\tbuttonView.withText = true;\n\n\t\t\tview = buttonView;\n\t\t}\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * Creates a position options object used to position the balloon panel.\n\t *\n\t * @param mentionMarker\n\t * @param preferredPosition The name of the last matched position name.\n\t */\n\tprivate _getBalloonPanelPositionData( mentionMarker: Marker, preferredPosition: MentionsView['position'] ): Partial<PositionOptions> {\n\t\tconst editor = this.editor;\n\t\tconst editing = editor.editing;\n\t\tconst domConverter = editing.view.domConverter;\n\t\tconst mapper = editing.mapper;\n\t\tconst uiLanguageDirection = editor.locale.uiLanguageDirection;\n\n\t\treturn {\n\t\t\ttarget: () => {\n\t\t\t\tlet modelRange = mentionMarker.getRange();\n\n\t\t\t\t// Target the UI to the model selection range - the marker has been removed so probably the UI will not be shown anyway.\n\t\t\t\t// The logic is used by ContextualBalloon to display another panel in the same place.\n\t\t\t\tif ( modelRange.start.root.rootName == '$graveyard' ) {\n\t\t\t\t\tmodelRange = editor.model.document.selection.getFirstRange()!;\n\t\t\t\t}\n\n\t\t\t\tconst viewRange = mapper.toViewRange( modelRange );\n\t\t\t\tconst rangeRects = Rect.getDomRangeRects( domConverter.viewRangeToDom( viewRange ) );\n\n\t\t\t\treturn rangeRects.pop()!;\n\t\t\t},\n\t\t\tlimiter: () => {\n\t\t\t\tconst view = this.editor.editing.view;\n\t\t\t\tconst viewDocument = view.document;\n\t\t\t\tconst editableElement = viewDocument.selection.editableElement;\n\n\t\t\t\tif ( editableElement ) {\n\t\t\t\t\treturn view.domConverter.mapViewToDom( editableElement.root ) as HTMLElement;\n\t\t\t\t}\n\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\tpositions: getBalloonPanelPositions( preferredPosition, uiLanguageDirection )\n\t\t};\n\t}\n}\n\n/**\n * Returns the balloon positions data callbacks.\n */\nfunction getBalloonPanelPositions(\n\tpreferredPosition: MentionsView['position'],\n\tuiLanguageDirection: string\n): PositionOptions['positions'] {\n\tconst positions: Record<string, PositionOptions['positions'][0]> = {\n\t\t// Positions the panel to the southeast of the caret rectangle.\n\t\t'caret_se': ( targetRect: Rect ) => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.bottom + VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right,\n\t\t\t\tname: 'caret_se',\n\t\t\t\tconfig: {\n\t\t\t\t\twithArrow: false\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\n\t\t// Positions the panel to the northeast of the caret rectangle.\n\t\t'caret_ne': ( targetRect: Rect, balloonRect: Rect ) => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.top - balloonRect.height - VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right,\n\t\t\t\tname: 'caret_ne',\n\t\t\t\tconfig: {\n\t\t\t\t\twithArrow: false\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\n\t\t// Positions the panel to the southwest of the caret rectangle.\n\t\t'caret_sw': ( targetRect: Rect, balloonRect: Rect ) => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.bottom + VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right - balloonRect.width,\n\t\t\t\tname: 'caret_sw',\n\t\t\t\tconfig: {\n\t\t\t\t\twithArrow: false\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\n\t\t// Positions the panel to the northwest of the caret rect.\n\t\t'caret_nw': ( targetRect: Rect, balloonRect: Rect ) => {\n\t\t\treturn {\n\t\t\t\ttop: targetRect.top - balloonRect.height - VERTICAL_SPACING,\n\t\t\t\tleft: targetRect.right - balloonRect.width,\n\t\t\t\tname: 'caret_nw',\n\t\t\t\tconfig: {\n\t\t\t\t\twithArrow: false\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n\n\t// Returns only the last position if it was matched to prevent the panel from jumping after the first match.\n\tif ( Object.prototype.hasOwnProperty.call( positions, preferredPosition! ) ) {\n\t\treturn [\n\t\t\tpositions[ preferredPosition! ]\n\t\t];\n\t}\n\n\t// By default, return all position callbacks ordered depending on the UI language direction.\n\treturn uiLanguageDirection !== 'rtl' ? [\n\t\tpositions.caret_se,\n\t\tpositions.caret_sw,\n\t\tpositions.caret_ne,\n\t\tpositions.caret_nw\n\t] : [\n\t\tpositions.caret_sw,\n\t\tpositions.caret_se,\n\t\tpositions.caret_nw,\n\t\tpositions.caret_ne\n\t];\n}\n\n/**\n * Returns a marker definition of the last valid occurring marker in a given string.\n * If there is no valid marker in a string, it returns undefined.\n *\n * Example of returned object:\n *\n * ```ts\n * {\n * \tmarker: '@',\n * \tposition: 4,\n * \tminimumCharacters: 0\n * }\n * ````\n *\n * @param feedsWithPattern Registered feeds in editor for mention plugin with created RegExp for matching marker.\n * @param text String to find the marker in\n * @returns Matched marker's definition\n */\nfunction getLastValidMarkerInText(\n\tfeedsWithPattern: Array<MentionFeed & { pattern: RegExp }>,\n\ttext: string\n): MarkerDefinition {\n\tlet lastValidMarker: any;\n\n\tfor ( const feed of feedsWithPattern ) {\n\t\tconst currentMarkerLastIndex = text.lastIndexOf( feed.marker );\n\n\t\tif ( currentMarkerLastIndex > 0 && !text.substring( currentMarkerLastIndex - 1 ).match( feed.pattern ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ( !lastValidMarker || currentMarkerLastIndex >= lastValidMarker.position ) {\n\t\t\tlastValidMarker = {\n\t\t\t\tmarker: feed.marker,\n\t\t\t\tposition: currentMarkerLastIndex,\n\t\t\t\tminimumCharacters: feed.minimumCharacters,\n\t\t\t\tpattern: feed.pattern\n\t\t\t};\n\t\t}\n\t}\n\n\treturn lastValidMarker;\n}\n\n/**\n * Creates a RegExp pattern for the marker.\n *\n * Function has to be exported to achieve 100% code coverage.\n */\nexport function createRegExp( marker: string, minimumCharacters: number ): RegExp {\n\tconst numberOfCharacters = minimumCharacters == 0 ? '*' : `{${ minimumCharacters },}`;\n\tconst openAfterCharacters = env.features.isRegExpUnicodePropertySupported ? '\\\\p{Ps}\\\\p{Pi}\"\\'' : '\\\\(\\\\[{\"\\'';\n\tconst mentionCharacters = '.';\n\n\t// I wanted to make an util out of it, but since this regexp uses \"u\" flag, it became difficult.\n\t// When \"u\" flag is used, the regexp has \"strict\" escaping rules, i.e. if you try to escape a character that does not need\n\t// to be escaped, RegExp() will throw. It made it difficult to write a generic util, because different characters are\n\t// allowed in different context. For example, escaping \"-\" sometimes was correct, but sometimes it threw an error.\n\tmarker = marker.replace( /[.*+?^${}()\\-|[\\]\\\\]/g, '\\\\$&' );\n\n\t// The pattern consists of 3 groups:\n\t//\n\t// - 0 (non-capturing): Opening sequence - start of the line, space or an opening punctuation character like \"(\" or \"\\\"\",\n\t// - 1: The marker character,\n\t// - 2: Mention input (taking the minimal length into consideration to trigger the UI),\n\t//\n\t// The pattern matches up to the caret (end of string switch - $).\n\t//               (0:      opening sequence       )(1:   marker  )(2:                typed mention              )$\n\tconst pattern = `(?:^|[ ${ openAfterCharacters }])([${ marker }])(${ mentionCharacters }${ numberOfCharacters })$`;\n\n\treturn new RegExp( pattern, 'u' );\n}\n\n/**\n * Creates a test callback for the marker to be used in the text watcher instance.\n *\n * @param feedsWithPattern Feeds of mention plugin configured in editor with RegExp to match marker in text\n */\nfunction createTestCallback( feedsWithPattern: Array<MentionFeed & { pattern: RegExp }> ): ( text: string ) => boolean {\n\tconst textMatcher = ( text: string ) => {\n\t\tconst markerDefinition = getLastValidMarkerInText( feedsWithPattern, text );\n\n\t\tif ( !markerDefinition ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tlet splitStringFrom = 0;\n\n\t\tif ( markerDefinition.position !== 0 ) {\n\t\t\tsplitStringFrom = markerDefinition.position - 1;\n\t\t}\n\n\t\tconst textToTest = text.substring( splitStringFrom );\n\n\t\treturn markerDefinition.pattern.test( textToTest );\n\t};\n\n\treturn textMatcher;\n}\n\n/**\n * Creates a text matcher from the marker.\n */\nfunction requestFeedText( markerDefinition: MarkerDefinition, text: string ): string {\n\tlet splitStringFrom = 0;\n\n\tif ( markerDefinition.position !== 0 ) {\n\t\tsplitStringFrom = markerDefinition.position - 1;\n\t}\n\n\tconst regExp = createRegExp( markerDefinition.marker, 0 );\n\tconst textToMatch = text.substring( splitStringFrom );\n\tconst match = textToMatch.match( regExp )!;\n\n\treturn match[ 2 ];\n}\n\n/**\n * The default feed callback.\n */\nfunction createFeedCallback( feedItems: Array<MentionFeedItem> ) {\n\treturn ( feedText: string ) => {\n\t\tconst filteredItems = feedItems\n\t\t\t// Make the default mention feed case-insensitive.\n\t\t\t.filter( item => {\n\t\t\t\t// Item might be defined as object.\n\t\t\t\tconst itemId = typeof item == 'string' ? item : String( item.id );\n\n\t\t\t\t// The default feed is case insensitive.\n\t\t\t\treturn itemId.toLowerCase().includes( feedText.toLowerCase() );\n\t\t\t} );\n\t\treturn filteredItems;\n\t};\n}\n\n/**\n * Checks if position in inside or right after a text with a mention.\n */\nfunction isPositionInExistingMention( position: Position ): boolean | null {\n\t// The text watcher listens only to changed range in selection - so the selection attributes are not yet available\n\t// and you cannot use selection.hasAttribute( 'mention' ) just yet.\n\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1723.\n\tconst hasMention = position.textNode && position.textNode.hasAttribute( 'mention' );\n\n\tconst nodeBefore = position.nodeBefore;\n\n\treturn hasMention || nodeBefore && nodeBefore.is( '$text' ) && nodeBefore.hasAttribute( 'mention' );\n}\n\n/**\n * Checks if the closest marker offset is at the beginning of a mention.\n *\n * See https://github.com/ckeditor/ckeditor5/issues/11400.\n */\nfunction isMarkerInExistingMention( markerPosition: Position ): boolean | null {\n\tconst nodeAfter = markerPosition.nodeAfter;\n\n\treturn nodeAfter && nodeAfter.is( '$text' ) && nodeAfter.hasAttribute( 'mention' );\n}\n\n/**\n * Checks if string is a valid mention marker.\n */\nfunction isValidMentionMarker( marker: string ): boolean | string {\n\treturn marker && marker.length == 1;\n}\n\n/**\n * Checks the mention plugins is in completion mode (e.g. when typing is after a valid mention string like @foo).\n */\nfunction checkIfStillInCompletionMode( editor: Editor ): boolean {\n\treturn editor.model.markers.has( 'mention' );\n}\n\ntype RequestFeedResponse = {\n\n\t/**\n\t * Autocomplete items\n\t */\n\tfeed: Array<MentionFeedItem>;\n\n\t/**\n\t * The character which triggers autocompletion for mention.\n\t */\n\tmarker: string;\n\n\t/**\n\t * The text for which feed items were requested.\n\t */\n\tfeedText: string;\n};\n\ntype RequestFeedError = {\n\n\t/**\n\t * The error that was caught.\n\t */\n\terror: ErrorEvent;\n};\n\n/**\n * Fired whenever requested feed has a response.\n */\ntype RequestFeedResponseEvent = {\n\tname: 'requestFeed:response';\n\targs: [ RequestFeedResponse ];\n};\n\n/**\n * Fired whenever the requested feed was discarded. This happens when the response was delayed and\n * other feed was already requested.\n */\ntype RequestFeedDiscardedEvent = {\n\tname: 'requestFeed:discarded';\n\targs: [ RequestFeedResponse ];\n};\n\n/**\n * Fired whenever the requested {@link module:mention/mentionconfig~MentionFeed#feed} promise fails with error.\n */\ntype RequestFeedErrorEvent = {\n\tname: 'requestFeed:error';\n\targs: [ RequestFeedError ];\n};\n\ntype Definition = {\n\tmarker: string;\n\tfeedCallback: FeedCallback;\n\titemRenderer?: ItemRenderer;\n\tdropdownLimit?: number;\n};\n\ntype MarkerDefinition = {\n\tmarker: string;\n\tminimumCharacters?: number;\n\tpattern: RegExp;\n\tposition: number;\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module mention/mention\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\n\nimport MentionEditing, { _toMentionAttribute } from './mentionediting.js';\nimport MentionUI from './mentionui.js';\n\nimport '../theme/mention.css';\n\n/**\n * The mention plugin.\n *\n * For a detailed overview, check the {@glink features/mentions Mention feature} guide.\n */\nexport default class Mention extends Plugin {\n\t/**\n\t * Creates a mention attribute value from the provided view element and additional data.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'Mention' ).toMentionAttribute( viewElement, { userId: '1234' } );\n\t *\n\t * // For a view element: <span data-mention=\"@joe\">@John Doe</span>\n\t * // it will return:\n\t * // { id: '@joe', userId: '1234', uid: '7a7bc7...', _text: '@John Doe' }\n\t * ```\n\t *\n\t * @param data Additional data to be stored in the mention attribute.\n\t */\n\tpublic toMentionAttribute<MentionData extends Record<string, unknown>>(\n\t\tviewElement: Element,\n\t\tdata: MentionData\n\t): ( MentionAttribute & MentionData ) | undefined;\n\n\t/**\n\t * Creates a mention attribute value from the provided view element.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'Mention' ).toMentionAttribute( viewElement );\n\t *\n\t * // For a view element: <span data-mention=\"@joe\">@John Doe</span>\n\t * // it will return:\n\t * // { id: '@joe', uid: '7a7bc7...', _text: '@John Doe' }\n\t * ```\n\t */\n\tpublic toMentionAttribute( viewElement: Element ): MentionAttribute | undefined;\n\n\tpublic toMentionAttribute( viewElement: Element, data?: Record<string, unknown> ): MentionAttribute | undefined {\n\t\treturn _toMentionAttribute( viewElement, data );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Mention' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ MentionEditing, MentionUI ] as const;\n\t}\n}\n\n/**\n * Represents a mention in the model.\n *\n * See {@link module:mention/mention~Mention#toMentionAttribute `Mention#toMentionAttribute()`}.\n */\nexport type MentionAttribute = {\n\n\t/**\n\t * The ID of a mention. It identifies the mention item in the mention feed. There can be multiple mentions\n\t * in the document with the same ID (e.g. the same hashtag being mentioned).\n\t */\n\tid: string;\n\n\t/**\n\t * A unique ID of this mention instance. Should be passed as an `option.id` when using\n\t * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement writer.createAttributeElement()}.\n\t */\n\tuid: string;\n\n\t/**\n\t * Helper property that stores the text of the inserted mention. Used for detecting a broken mention\n\t * in the editing area.\n\t *\n\t * @internal\n\t */\n\t_text: string;\n};\n", "import { Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\nimport { UpcastWriter, Matcher, ViewDocument, DomConverter } from '@ckeditor/ckeditor5-engine/dist/index.js';\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module paste-from-office/filters/utils\n */ /**\n * Normalizes CSS length value to 'px'.\n *\n * @internal\n */ function convertCssLengthToPx(value) {\n    const numericValue = parseFloat(value);\n    if (value.endsWith('pt')) {\n        // 1pt = 1in / 72\n        return toPx(numericValue * 96 / 72);\n    } else if (value.endsWith('pc')) {\n        // 1pc = 12pt = 1in / 6.\n        return toPx(numericValue * 12 * 96 / 72);\n    } else if (value.endsWith('in')) {\n        // 1in = 2.54cm = 96px\n        return toPx(numericValue * 96);\n    } else if (value.endsWith('cm')) {\n        // 1cm = 96px / 2.54\n        return toPx(numericValue * 96 / 2.54);\n    } else if (value.endsWith('mm')) {\n        // 1mm = 1cm / 10\n        return toPx(numericValue / 10 * 96 / 2.54);\n    }\n    return value;\n}\n/**\n * Returns true for value with 'px' unit.\n *\n * @internal\n */ function isPx(value) {\n    return value !== undefined && value.endsWith('px');\n}\n/**\n * Returns a rounded 'px' value.\n *\n * @internal\n */ function toPx(value) {\n    return value.toFixed(2).replace(/\\.?0+$/, '') + 'px';\n}\n\n/**\n * Transforms Word specific list-like elements to the semantic HTML lists.\n *\n * Lists in Word are represented by block elements with special attributes like:\n *\n * ```xml\n * <p class=MsoListParagraphCxSpFirst style='mso-list:l1 level1 lfo1'>...</p> // Paragraph based list.\n * <h1 style='mso-list:l0 level1 lfo1'>...</h1> // Heading 1 based list.\n * ```\n *\n * @param documentFragment The view structure to be transformed.\n * @param stylesString Styles from which list-like elements styling will be extracted.\n */ function transformListItemLikeElementsIntoLists(documentFragment, stylesString, hasMultiLevelListPlugin) {\n    if (!documentFragment.childCount) {\n        return;\n    }\n    const writer = new UpcastWriter(documentFragment.document);\n    const itemLikeElements = findAllItemLikeElements(documentFragment, writer);\n    if (!itemLikeElements.length) {\n        return;\n    }\n    const encounteredLists = {};\n    const stack = [];\n    for (const itemLikeElement of itemLikeElements){\n        if (itemLikeElement.indent !== undefined) {\n            if (!isListContinuation(itemLikeElement)) {\n                stack.length = 0;\n            }\n            // Combined list ID for addressing encounter lists counters.\n            const originalListId = `${itemLikeElement.id}:${itemLikeElement.indent}`;\n            // Normalized list item indentation.\n            const indent = Math.min(itemLikeElement.indent - 1, stack.length);\n            // Trimming of the list stack on list ID change.\n            if (indent < stack.length && stack[indent].id !== itemLikeElement.id) {\n                stack.length = indent;\n            }\n            // Trimming of the list stack on lower indent list encountered.\n            if (indent < stack.length - 1) {\n                stack.length = indent + 1;\n            } else {\n                const listStyle = detectListStyle(itemLikeElement, stylesString);\n                // Create a new OL/UL if required (greater indent or different list type).\n                if (indent > stack.length - 1 || stack[indent].listElement.name != listStyle.type) {\n                    // Check if there is some start index to set from a previous list.\n                    if (indent == 0 && listStyle.type == 'ol' && itemLikeElement.id !== undefined && encounteredLists[originalListId]) {\n                        listStyle.startIndex = encounteredLists[originalListId];\n                    }\n                    const listElement = createNewEmptyList(listStyle, writer, hasMultiLevelListPlugin);\n                    // Apply list padding only if we have margins for the item and the parent item.\n                    if (isPx(itemLikeElement.marginLeft) && (indent == 0 || isPx(stack[indent - 1].marginLeft))) {\n                        let marginLeft = itemLikeElement.marginLeft;\n                        if (indent > 0) {\n                            // Convert the padding from absolute to relative.\n                            marginLeft = toPx(parseFloat(marginLeft) - parseFloat(stack[indent - 1].marginLeft));\n                        }\n                        writer.setStyle('padding-left', marginLeft, listElement);\n                    }\n                    // Insert the new OL/UL.\n                    if (stack.length == 0) {\n                        const parent = itemLikeElement.element.parent;\n                        const index = parent.getChildIndex(itemLikeElement.element) + 1;\n                        writer.insertChild(index, listElement, parent);\n                    } else {\n                        const parentListItems = stack[indent - 1].listItemElements;\n                        writer.appendChild(listElement, parentListItems[parentListItems.length - 1]);\n                    }\n                    // Update the list stack for other items to reference.\n                    stack[indent] = {\n                        ...itemLikeElement,\n                        listElement,\n                        listItemElements: []\n                    };\n                    // Prepare list counter for start index.\n                    if (indent == 0 && itemLikeElement.id !== undefined) {\n                        encounteredLists[originalListId] = listStyle.startIndex || 1;\n                    }\n                }\n            }\n            // Use LI if it is already it or create a new LI element.\n            // https://github.com/ckeditor/ckeditor5/issues/15964\n            const listItem = itemLikeElement.element.name == 'li' ? itemLikeElement.element : writer.createElement('li');\n            // Append the LI to OL/UL.\n            writer.appendChild(listItem, stack[indent].listElement);\n            stack[indent].listItemElements.push(listItem);\n            // Increment list counter.\n            if (indent == 0 && itemLikeElement.id !== undefined) {\n                encounteredLists[originalListId]++;\n            }\n            // Append list block to LI.\n            if (itemLikeElement.element != listItem) {\n                writer.appendChild(itemLikeElement.element, listItem);\n            }\n            // Clean list block.\n            removeBulletElement(itemLikeElement.element, writer);\n            writer.removeStyle('text-indent', itemLikeElement.element); // #12361\n            writer.removeStyle('margin-left', itemLikeElement.element);\n        } else {\n            // Other blocks in a list item.\n            const stackItem = stack.find((stackItem)=>stackItem.marginLeft == itemLikeElement.marginLeft);\n            // This might be a paragraph that has known margin, but it is not a real list block.\n            if (stackItem) {\n                const listItems = stackItem.listItemElements;\n                // Append block to LI.\n                writer.appendChild(itemLikeElement.element, listItems[listItems.length - 1]);\n                writer.removeStyle('margin-left', itemLikeElement.element);\n            } else {\n                stack.length = 0;\n            }\n        }\n    }\n}\n/**\n * Removes paragraph wrapping content inside a list item.\n */ function unwrapParagraphInListItem(documentFragment, writer) {\n    for (const value of writer.createRangeIn(documentFragment)){\n        const element = value.item;\n        if (element.is('element', 'li')) {\n            // Google Docs allows for single paragraph inside LI.\n            const firstChild = element.getChild(0);\n            if (firstChild && firstChild.is('element', 'p')) {\n                writer.unwrapElement(firstChild);\n            }\n        }\n    }\n}\n/**\n * Finds all list-like elements in a given document fragment.\n *\n * @param documentFragment Document fragment in which to look for list-like nodes.\n * @returns Array of found list-like items. Each item is an object containing:\n */ function findAllItemLikeElements(documentFragment, writer) {\n    const range = writer.createRangeIn(documentFragment);\n    const itemLikeElements = [];\n    const foundMargins = new Set();\n    for (const item of range.getItems()){\n        // https://github.com/ckeditor/ckeditor5/issues/15964\n        if (!item.is('element') || !item.name.match(/^(p|h\\d+|li|div)$/)) {\n            continue;\n        }\n        // Try to rely on margin-left style to find paragraphs visually aligned with previously encountered list item.\n        let marginLeft = getMarginLeftNormalized(item);\n        // Ignore margin-left 0 style if there is no MsoList... class.\n        if (marginLeft !== undefined && parseFloat(marginLeft) == 0 && !Array.from(item.getClassNames()).find((className)=>className.startsWith('MsoList'))) {\n            marginLeft = undefined;\n        }\n        // List item or a following list item block.\n        if (item.hasStyle('mso-list') || marginLeft !== undefined && foundMargins.has(marginLeft)) {\n            const itemData = getListItemData(item);\n            itemLikeElements.push({\n                element: item,\n                id: itemData.id,\n                order: itemData.order,\n                indent: itemData.indent,\n                marginLeft\n            });\n            if (marginLeft !== undefined) {\n                foundMargins.add(marginLeft);\n            }\n        } else {\n            foundMargins.clear();\n        }\n    }\n    return itemLikeElements;\n}\n/**\n * Whether the given element is possibly a list continuation. Previous element was wrapped into a list\n * or the current element already is inside a list.\n */ function isListContinuation(currentItem) {\n    const previousSibling = currentItem.element.previousSibling;\n    if (!previousSibling) {\n        // If it's a li inside ul or ol like in here: https://github.com/ckeditor/ckeditor5/issues/15964.\n        return isList(currentItem.element.parent);\n    }\n    // Even with the same id the list does not have to be continuous (#43).\n    return isList(previousSibling);\n}\nfunction isList(element) {\n    return element.is('element', 'ol') || element.is('element', 'ul');\n}\n/**\n * Extracts list item style from the provided CSS.\n *\n * List item style is extracted from the CSS stylesheet. Each list with its specific style attribute\n * value (`mso-list:l1 level1 lfo1`) has its dedicated properties in a CSS stylesheet defined with a selector like:\n *\n * ```css\n * @list l1:level1 { ... }\n * ```\n *\n * It contains `mso-level-number-format` property which defines list numbering/bullet style. If this property\n * is not defined it means default `decimal` numbering.\n *\n * Here CSS string representation is used as `mso-level-number-format` property is an invalid CSS property\n * and will be removed during CSS parsing.\n *\n * @param listLikeItem List-like item for which list style will be searched for. Usually\n * a result of `findAllItemLikeElements()` function.\n * @param stylesString CSS stylesheet.\n * @returns An object with properties:\n *\n * * type - List type, could be `ul` or `ol`.\n * * startIndex - List start index, valid only for ordered lists.\n * * style - List style, for example: `decimal`, `lower-roman`, etc. It is extracted\n *     directly from Word stylesheet and adjusted to represent proper values for the CSS `list-style-type` property.\n *     If it cannot be adjusted, the `null` value is returned.\n */ function detectListStyle(listLikeItem, stylesString) {\n    const listStyleRegexp = new RegExp(`@list l${listLikeItem.id}:level${listLikeItem.indent}\\\\s*({[^}]*)`, 'gi');\n    const listStyleTypeRegex = /mso-level-number-format:([^;]{0,100});/gi;\n    const listStartIndexRegex = /mso-level-start-at:\\s{0,100}([0-9]{0,10})\\s{0,100};/gi;\n    const legalStyleListRegex = new RegExp(`@list\\\\s+l${listLikeItem.id}:level\\\\d\\\\s*{[^{]*mso-level-text:\"%\\\\d\\\\\\\\.`, 'gi');\n    const multiLevelNumberFormatTypeRegex = new RegExp(`@list l${listLikeItem.id}:level\\\\d\\\\s*{[^{]*mso-level-number-format:`, 'gi');\n    const legalStyleListMatch = legalStyleListRegex.exec(stylesString);\n    const multiLevelNumberFormatMatch = multiLevelNumberFormatTypeRegex.exec(stylesString);\n    // Multi level lists in Word have mso-level-number-format attribute except legal lists,\n    // so we used that. If list has legal list match and doesn't has mso-level-number-format\n    // then this is legal-list.\n    const islegalStyleList = legalStyleListMatch && !multiLevelNumberFormatMatch;\n    const listStyleMatch = listStyleRegexp.exec(stylesString);\n    let listStyleType = 'decimal'; // Decimal is default one.\n    let type = 'ol'; // <ol> is default list.\n    let startIndex = null;\n    if (listStyleMatch && listStyleMatch[1]) {\n        const listStyleTypeMatch = listStyleTypeRegex.exec(listStyleMatch[1]);\n        if (listStyleTypeMatch && listStyleTypeMatch[1]) {\n            listStyleType = listStyleTypeMatch[1].trim();\n            type = listStyleType !== 'bullet' && listStyleType !== 'image' ? 'ol' : 'ul';\n        }\n        // Styles for the numbered lists are always defined in the Word CSS stylesheet.\n        // Unordered lists MAY contain a value for the Word CSS definition `mso-level-text` but sometimes\n        // this tag is missing. And because of that, we cannot depend on that. We need to predict the list style value\n        // based on the list style marker element.\n        if (listStyleType === 'bullet') {\n            const bulletedStyle = findBulletedListStyle(listLikeItem.element);\n            if (bulletedStyle) {\n                listStyleType = bulletedStyle;\n            }\n        } else {\n            const listStartIndexMatch = listStartIndexRegex.exec(listStyleMatch[1]);\n            if (listStartIndexMatch && listStartIndexMatch[1]) {\n                startIndex = parseInt(listStartIndexMatch[1]);\n            }\n        }\n        if (islegalStyleList) {\n            type = 'ol';\n        }\n    }\n    return {\n        type,\n        startIndex,\n        style: mapListStyleDefinition(listStyleType),\n        isLegalStyleList: islegalStyleList\n    };\n}\n/**\n * Tries to extract the `list-style-type` value based on the marker element for bulleted list.\n */ function findBulletedListStyle(element) {\n    // https://github.com/ckeditor/ckeditor5/issues/15964\n    if (element.name == 'li' && element.parent.name == 'ul' && element.parent.hasAttribute('type')) {\n        return element.parent.getAttribute('type');\n    }\n    const listMarkerElement = findListMarkerNode(element);\n    if (!listMarkerElement) {\n        return null;\n    }\n    const listMarker = listMarkerElement._data;\n    if (listMarker === 'o') {\n        return 'circle';\n    } else if (listMarker === '·') {\n        return 'disc';\n    } else if (listMarker === '§') {\n        return 'square';\n    }\n    return null;\n}\n/**\n * Tries to find a text node that represents the marker element (list-style-type).\n */ function findListMarkerNode(element) {\n    // If the first child is a text node, it is the data for the element.\n    // The list-style marker is not present here.\n    if (element.getChild(0).is('$text')) {\n        return null;\n    }\n    for (const childNode of element.getChildren()){\n        // The list-style marker will be inside the `<span>` element. Let's ignore all non-span elements.\n        // It may happen that the `<a>` element is added as the first child. Most probably, it's an anchor element.\n        if (!childNode.is('element', 'span')) {\n            continue;\n        }\n        const textNodeOrElement = childNode.getChild(0);\n        if (!textNodeOrElement) {\n            continue;\n        }\n        // If already found the marker element, use it.\n        if (textNodeOrElement.is('$text')) {\n            return textNodeOrElement;\n        }\n        return textNodeOrElement.getChild(0);\n    }\n    /* istanbul ignore next -- @preserve */ return null;\n}\n/**\n * Parses the `list-style-type` value extracted directly from the Word CSS stylesheet and returns proper CSS definition.\n */ function mapListStyleDefinition(value) {\n    if (value.startsWith('arabic-leading-zero')) {\n        return 'decimal-leading-zero';\n    }\n    switch(value){\n        case 'alpha-upper':\n            return 'upper-alpha';\n        case 'alpha-lower':\n            return 'lower-alpha';\n        case 'roman-upper':\n            return 'upper-roman';\n        case 'roman-lower':\n            return 'lower-roman';\n        case 'circle':\n        case 'disc':\n        case 'square':\n            return value;\n        default:\n            return null;\n    }\n}\n/**\n * Creates a new list OL/UL element.\n */ function createNewEmptyList(listStyle, writer, hasMultiLevelListPlugin) {\n    const list = writer.createElement(listStyle.type);\n    // We do not support modifying the marker for a particular list item.\n    // Set the value for the `list-style-type` property directly to the list container.\n    if (listStyle.style) {\n        writer.setStyle('list-style-type', listStyle.style, list);\n    }\n    if (listStyle.startIndex && listStyle.startIndex > 1) {\n        writer.setAttribute('start', listStyle.startIndex, list);\n    }\n    if (listStyle.isLegalStyleList && hasMultiLevelListPlugin) {\n        writer.addClass('legal-list', list);\n    }\n    return list;\n}\n/**\n * Extracts list item information from Word specific list-like element style:\n *\n * ```\n * `style=\"mso-list:l1 level1 lfo1\"`\n * ```\n *\n * where:\n *\n * ```\n * * `l1` is a list id (however it does not mean this is a continuous list - see #43),\n * * `level1` is a list item indentation level,\n * * `lfo1` is a list insertion order in a document.\n * ```\n *\n * @param element Element from which style data is extracted.\n */ function getListItemData(element) {\n    const listStyle = element.getStyle('mso-list');\n    if (listStyle === undefined) {\n        return {};\n    }\n    const idMatch = listStyle.match(/(^|\\s{1,100})l(\\d+)/i);\n    const orderMatch = listStyle.match(/\\s{0,100}lfo(\\d+)/i);\n    const indentMatch = listStyle.match(/\\s{0,100}level(\\d+)/i);\n    if (idMatch && orderMatch && indentMatch) {\n        return {\n            id: idMatch[2],\n            order: orderMatch[1],\n            indent: parseInt(indentMatch[1])\n        };\n    }\n    return {\n        indent: 1 // Handle empty mso-list style as a marked for default list item.\n    };\n}\n/**\n * Removes span with a numbering/bullet from a given element.\n */ function removeBulletElement(element, writer) {\n    // Matcher for finding `span` elements holding lists numbering/bullets.\n    const bulletMatcher = new Matcher({\n        name: 'span',\n        styles: {\n            'mso-list': 'Ignore'\n        }\n    });\n    const range = writer.createRangeIn(element);\n    for (const value of range){\n        if (value.type === 'elementStart' && bulletMatcher.match(value.item)) {\n            writer.remove(value.item);\n        }\n    }\n}\n/**\n * Returns element left margin normalized to 'px' if possible.\n */ function getMarginLeftNormalized(element) {\n    const value = element.getStyle('margin-left');\n    if (value === undefined || value.endsWith('px')) {\n        return value;\n    }\n    return convertCssLengthToPx(value);\n}\n\n/**\n * Replaces source attribute of all `<img>` elements representing regular\n * images (not the Word shapes) with inlined base64 image representation extracted from RTF or Blob data.\n *\n * @param documentFragment Document fragment on which transform images.\n * @param rtfData The RTF data from which images representation will be used.\n */ function replaceImagesSourceWithBase64(documentFragment, rtfData) {\n    if (!documentFragment.childCount) {\n        return;\n    }\n    const upcastWriter = new UpcastWriter(documentFragment.document);\n    const shapesIds = findAllShapesIds(documentFragment, upcastWriter);\n    removeAllImgElementsRepresentingShapes(shapesIds, documentFragment, upcastWriter);\n    insertMissingImgs(shapesIds, documentFragment, upcastWriter);\n    removeAllShapeElements(documentFragment, upcastWriter);\n    const images = findAllImageElementsWithLocalSource(documentFragment, upcastWriter);\n    if (images.length) {\n        replaceImagesFileSourceWithInlineRepresentation(images, extractImageDataFromRtf(rtfData), upcastWriter);\n    }\n}\n/**\n * Converts given HEX string to base64 representation.\n *\n * @internal\n * @param hexString The HEX string to be converted.\n * @returns Base64 representation of a given HEX string.\n */ function _convertHexToBase64(hexString) {\n    return btoa(hexString.match(/\\w{2}/g).map((char)=>{\n        return String.fromCharCode(parseInt(char, 16));\n    }).join(''));\n}\n/**\n * Finds all shapes (`<v:*>...</v:*>`) ids. Shapes can represent images (canvas)\n * or Word shapes (which does not have RTF or Blob representation).\n *\n * @param documentFragment Document fragment from which to extract shape ids.\n * @returns Array of shape ids.\n */ function findAllShapesIds(documentFragment, writer) {\n    const range = writer.createRangeIn(documentFragment);\n    const shapeElementsMatcher = new Matcher({\n        name: /v:(.+)/\n    });\n    const shapesIds = [];\n    for (const value of range){\n        if (value.type != 'elementStart') {\n            continue;\n        }\n        const el = value.item;\n        const previousSibling = el.previousSibling;\n        const prevSiblingName = previousSibling && previousSibling.is('element') ? previousSibling.name : null;\n        // List of ids which should not be considered as shapes.\n        // https://github.com/ckeditor/ckeditor5/pull/15847#issuecomment-1941543983\n        const exceptionIds = [\n            'Chart'\n        ];\n        const isElementAShape = shapeElementsMatcher.match(el);\n        const hasElementGfxdataAttribute = el.getAttribute('o:gfxdata');\n        const isPreviousSiblingAShapeType = prevSiblingName === 'v:shapetype';\n        const isElementIdInExceptionsArray = hasElementGfxdataAttribute && exceptionIds.some((item)=>el.getAttribute('id').includes(item));\n        // If shape element has 'o:gfxdata' attribute and is not directly before\n        // `<v:shapetype>` element it means that it represents a Word shape.\n        if (isElementAShape && hasElementGfxdataAttribute && !isPreviousSiblingAShapeType && !isElementIdInExceptionsArray) {\n            shapesIds.push(value.item.getAttribute('id'));\n        }\n    }\n    return shapesIds;\n}\n/**\n * Removes all `<img>` elements which represents Word shapes and not regular images.\n *\n * @param shapesIds Shape ids which will be checked against `<img>` elements.\n * @param documentFragment Document fragment from which to remove `<img>` elements.\n */ function removeAllImgElementsRepresentingShapes(shapesIds, documentFragment, writer) {\n    const range = writer.createRangeIn(documentFragment);\n    const imageElementsMatcher = new Matcher({\n        name: 'img'\n    });\n    const imgs = [];\n    for (const value of range){\n        if (value.item.is('element') && imageElementsMatcher.match(value.item)) {\n            const el = value.item;\n            const shapes = el.getAttribute('v:shapes') ? el.getAttribute('v:shapes').split(' ') : [];\n            if (shapes.length && shapes.every((shape)=>shapesIds.indexOf(shape) > -1)) {\n                imgs.push(el);\n            // Shapes may also have empty source while content is paste in some browsers (Safari).\n            } else if (!el.getAttribute('src')) {\n                imgs.push(el);\n            }\n        }\n    }\n    for (const img of imgs){\n        writer.remove(img);\n    }\n}\n/**\n * Removes all shape elements (`<v:*>...</v:*>`) so they do not pollute the output structure.\n *\n * @param documentFragment Document fragment from which to remove shape elements.\n */ function removeAllShapeElements(documentFragment, writer) {\n    const range = writer.createRangeIn(documentFragment);\n    const shapeElementsMatcher = new Matcher({\n        name: /v:(.+)/\n    });\n    const shapes = [];\n    for (const value of range){\n        if (value.type == 'elementStart' && shapeElementsMatcher.match(value.item)) {\n            shapes.push(value.item);\n        }\n    }\n    for (const shape of shapes){\n        writer.remove(shape);\n    }\n}\n/**\n * Inserts `img` tags if there is none after a shape.\n */ function insertMissingImgs(shapeIds, documentFragment, writer) {\n    const range = writer.createRangeIn(documentFragment);\n    const shapes = [];\n    for (const value of range){\n        if (value.type == 'elementStart' && value.item.is('element', 'v:shape')) {\n            const id = value.item.getAttribute('id');\n            if (shapeIds.includes(id)) {\n                continue;\n            }\n            if (!containsMatchingImg(value.item.parent.getChildren(), id)) {\n                shapes.push(value.item);\n            }\n        }\n    }\n    for (const shape of shapes){\n        const attrs = {\n            src: findSrc(shape)\n        };\n        if (shape.hasAttribute('alt')) {\n            attrs.alt = shape.getAttribute('alt');\n        }\n        const img = writer.createElement('img', attrs);\n        writer.insertChild(shape.index + 1, img, shape.parent);\n    }\n    function containsMatchingImg(nodes, id) {\n        for (const node of nodes){\n            /* istanbul ignore else -- @preserve */ if (node.is('element')) {\n                if (node.name == 'img' && node.getAttribute('v:shapes') == id) {\n                    return true;\n                }\n                if (containsMatchingImg(node.getChildren(), id)) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    function findSrc(shape) {\n        for (const child of shape.getChildren()){\n            /* istanbul ignore else -- @preserve */ if (child.is('element') && child.getAttribute('src')) {\n                return child.getAttribute('src');\n            }\n        }\n    }\n}\n/**\n * Finds all `<img>` elements in a given document fragment which have source pointing to local `file://` resource.\n *\n * @param documentFragment Document fragment in which to look for `<img>` elements.\n * @returns result All found images grouped by source type.\n */ function findAllImageElementsWithLocalSource(documentFragment, writer) {\n    const range = writer.createRangeIn(documentFragment);\n    const imageElementsMatcher = new Matcher({\n        name: 'img'\n    });\n    const imgs = [];\n    for (const value of range){\n        if (value.item.is('element') && imageElementsMatcher.match(value.item)) {\n            if (value.item.getAttribute('src').startsWith('file://')) {\n                imgs.push(value.item);\n            }\n        }\n    }\n    return imgs;\n}\n/**\n * Extracts all images HEX representations from a given RTF data.\n *\n * @param rtfData The RTF data from which to extract images HEX representation.\n * @returns Array of found HEX representations. Each array item is an object containing:\n *\n * * hex Image representation in HEX format.\n * * type Type of image, `image/png` or `image/jpeg`.\n */ function extractImageDataFromRtf(rtfData) {\n    if (!rtfData) {\n        return [];\n    }\n    const regexPictureHeader = /{\\\\pict[\\s\\S]+?\\\\bliptag-?\\d+(\\\\blipupi-?\\d+)?({\\\\\\*\\\\blipuid\\s?[\\da-fA-F]+)?[\\s}]*?/;\n    const regexPicture = new RegExp('(?:(' + regexPictureHeader.source + '))([\\\\da-fA-F\\\\s]+)\\\\}', 'g');\n    const images = rtfData.match(regexPicture);\n    const result = [];\n    if (images) {\n        for (const image of images){\n            let imageType = false;\n            if (image.includes('\\\\pngblip')) {\n                imageType = 'image/png';\n            } else if (image.includes('\\\\jpegblip')) {\n                imageType = 'image/jpeg';\n            }\n            if (imageType) {\n                result.push({\n                    hex: image.replace(regexPictureHeader, '').replace(/[^\\da-fA-F]/g, ''),\n                    type: imageType\n                });\n            }\n        }\n    }\n    return result;\n}\n/**\n * Replaces `src` attribute value of all given images with the corresponding base64 image representation.\n *\n * @param imageElements Array of image elements which will have its source replaced.\n * @param imagesHexSources Array of images hex sources (usually the result of `extractImageDataFromRtf()` function).\n * The array should be the same length as `imageElements` parameter.\n */ function replaceImagesFileSourceWithInlineRepresentation(imageElements, imagesHexSources, writer) {\n    // Assume there is an equal amount of image elements and images HEX sources so they can be matched accordingly based on existing order.\n    if (imageElements.length === imagesHexSources.length) {\n        for(let i = 0; i < imageElements.length; i++){\n            const newSrc = `data:${imagesHexSources[i].type};base64,${_convertHexToBase64(imagesHexSources[i].hex)}`;\n            writer.setAttribute('src', newSrc, imageElements[i]);\n        }\n    }\n}\n\n/**\n * Cleanup MS attributes like styles, attributes and elements.\n *\n * @param documentFragment element `data.content` obtained from clipboard.\n */ function removeMSAttributes(documentFragment) {\n    const elementsToUnwrap = [];\n    const writer = new UpcastWriter(documentFragment.document);\n    for (const { item } of writer.createRangeIn(documentFragment)){\n        if (!item.is('element')) {\n            continue;\n        }\n        for (const className of item.getClassNames()){\n            if (/\\bmso/gi.exec(className)) {\n                writer.removeClass(className, item);\n            }\n        }\n        for (const styleName of item.getStyleNames()){\n            if (/\\bmso/gi.exec(styleName)) {\n                writer.removeStyle(styleName, item);\n            }\n        }\n        if (item.is('element', 'w:sdt') || item.is('element', 'w:sdtpr') && item.isEmpty || item.is('element', 'o:p') && item.isEmpty) {\n            elementsToUnwrap.push(item);\n        }\n    }\n    for (const item of elementsToUnwrap){\n        const itemParent = item.parent;\n        const childIndex = itemParent.getChildIndex(item);\n        writer.insertChild(childIndex, item.getChildren(), itemParent);\n        writer.remove(item);\n    }\n}\n\nconst msWordMatch1 = /<meta\\s*name=\"?generator\"?\\s*content=\"?microsoft\\s*word\\s*\\d+\"?\\/?>/i;\nconst msWordMatch2 = /xmlns:o=\"urn:schemas-microsoft-com/i;\n/**\n * Normalizer for the content pasted from Microsoft Word.\n */ class MSWordNormalizer {\n    document;\n    hasMultiLevelListPlugin;\n    /**\n\t * Creates a new `MSWordNormalizer` instance.\n\t *\n\t * @param document View document.\n\t */ constructor(document, hasMultiLevelListPlugin = false){\n        this.document = document;\n        this.hasMultiLevelListPlugin = hasMultiLevelListPlugin;\n    }\n    /**\n\t * @inheritDoc\n\t */ isActive(htmlString) {\n        return msWordMatch1.test(htmlString) || msWordMatch2.test(htmlString);\n    }\n    /**\n\t * @inheritDoc\n\t */ execute(data) {\n        const { body: documentFragment, stylesString } = data._parsedData;\n        transformListItemLikeElementsIntoLists(documentFragment, stylesString, this.hasMultiLevelListPlugin);\n        replaceImagesSourceWithBase64(documentFragment, data.dataTransfer.getData('text/rtf'));\n        removeMSAttributes(documentFragment);\n        data.content = documentFragment;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module paste-from-office/filters/removeboldwrapper\n */ /**\n * Removes the `<b>` tag wrapper added by Google Docs to a copied content.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */ function removeBoldWrapper(documentFragment, writer) {\n    for (const child of documentFragment.getChildren()){\n        if (child.is('element', 'b') && child.getStyle('font-weight') === 'normal') {\n            const childIndex = documentFragment.getChildIndex(child);\n            writer.remove(child);\n            writer.insertChild(childIndex, child.getChildren(), documentFragment);\n        }\n    }\n}\n\n/**\n * Transforms `<br>` elements that are siblings to some block element into a paragraphs.\n *\n * @param documentFragment The view structure to be transformed.\n */ function transformBlockBrsToParagraphs(documentFragment, writer) {\n    const viewDocument = new ViewDocument(writer.document.stylesProcessor);\n    const domConverter = new DomConverter(viewDocument, {\n        renderingMode: 'data'\n    });\n    const blockElements = domConverter.blockElements;\n    const inlineObjectElements = domConverter.inlineObjectElements;\n    const elementsToReplace = [];\n    for (const value of writer.createRangeIn(documentFragment)){\n        const element = value.item;\n        if (element.is('element', 'br')) {\n            const nextSibling = findSibling(element, 'forward', writer, {\n                blockElements,\n                inlineObjectElements\n            });\n            const previousSibling = findSibling(element, 'backward', writer, {\n                blockElements,\n                inlineObjectElements\n            });\n            const nextSiblingIsBlock = isBlockViewElement(nextSibling, blockElements);\n            const previousSiblingIsBlock = isBlockViewElement(previousSibling, blockElements);\n            // If the <br> is surrounded by blocks then convert it to a paragraph:\n            // * <p>foo</p>[<br>]<p>bar</p> -> <p>foo</p>[<p></p>]<p>bar</p>\n            // * <p>foo</p>[<br>] -> <p>foo</p>[<p></p>]\n            // * [<br>]<p>foo</p> -> [<p></p>]<p>foo</p>\n            if (previousSiblingIsBlock || nextSiblingIsBlock) {\n                elementsToReplace.push(element);\n            }\n        }\n    }\n    for (const element of elementsToReplace){\n        if (element.hasClass('Apple-interchange-newline')) {\n            writer.remove(element);\n        } else {\n            writer.replace(element, writer.createElement('p'));\n        }\n    }\n}\n/**\n * Returns sibling node, threats inline elements as transparent (but should stop on an inline objects).\n */ function findSibling(viewElement, direction, writer, { blockElements, inlineObjectElements }) {\n    let position = writer.createPositionAt(viewElement, direction == 'forward' ? 'after' : 'before');\n    // Find first position that is just before a first:\n    // * text node,\n    // * block element,\n    // * inline object element.\n    // It's ignoring any inline (non-object) elements like span, strong, etc.\n    position = position.getLastMatchingPosition(({ item })=>item.is('element') && !blockElements.includes(item.name) && !inlineObjectElements.includes(item.name), {\n        direction\n    });\n    return direction == 'forward' ? position.nodeAfter : position.nodeBefore;\n}\n/**\n * Returns true for view elements that are listed as block view elements.\n */ function isBlockViewElement(node, blockElements) {\n    return !!node && node.is('element') && blockElements.includes(node.name);\n}\n\nconst googleDocsMatch = /id=(\"|')docs-internal-guid-[-0-9a-f]+(\"|')/i;\n/**\n * Normalizer for the content pasted from Google Docs.\n */ class GoogleDocsNormalizer {\n    document;\n    /**\n\t * Creates a new `GoogleDocsNormalizer` instance.\n\t *\n\t * @param document View document.\n\t */ constructor(document){\n        this.document = document;\n    }\n    /**\n\t * @inheritDoc\n\t */ isActive(htmlString) {\n        return googleDocsMatch.test(htmlString);\n    }\n    /**\n\t * @inheritDoc\n\t */ execute(data) {\n        const writer = new UpcastWriter(this.document);\n        const { body: documentFragment } = data._parsedData;\n        removeBoldWrapper(documentFragment, writer);\n        unwrapParagraphInListItem(documentFragment, writer);\n        transformBlockBrsToParagraphs(documentFragment, writer);\n        data.content = documentFragment;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module paste-from-office/filters/removexmlns\n */ /**\n * Removes the `xmlns` attribute from table pasted from Google Sheets.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */ function removeXmlns(documentFragment, writer) {\n    for (const child of documentFragment.getChildren()){\n        if (child.is('element', 'table') && child.hasAttribute('xmlns')) {\n            writer.removeAttribute('xmlns', child);\n        }\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module paste-from-office/filters/removegooglesheetstag\n */ /**\n * Removes the `<google-sheets-html-origin>` tag wrapper added by Google Sheets to a copied content.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */ function removeGoogleSheetsTag(documentFragment, writer) {\n    for (const child of documentFragment.getChildren()){\n        if (child.is('element', 'google-sheets-html-origin')) {\n            const childIndex = documentFragment.getChildIndex(child);\n            writer.remove(child);\n            writer.insertChild(childIndex, child.getChildren(), documentFragment);\n        }\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module paste-from-office/filters/removeinvalidtablewidth\n */ /**\n * Removes the `width:0px` style from table pasted from Google Sheets.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */ function removeInvalidTableWidth(documentFragment, writer) {\n    for (const child of documentFragment.getChildren()){\n        if (child.is('element', 'table') && child.getStyle('width') === '0px') {\n            writer.removeStyle('width', child);\n        }\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module paste-from-office/filters/removestyleblock\n */ /**\n * Removes `<style>` block added by Google Sheets to a copied content.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */ function removeStyleBlock(documentFragment, writer) {\n    for (const child of Array.from(documentFragment.getChildren())){\n        if (child.is('element', 'style')) {\n            writer.remove(child);\n        }\n    }\n}\n\nconst googleSheetsMatch = /<google-sheets-html-origin/i;\n/**\n * Normalizer for the content pasted from Google Sheets.\n */ class GoogleSheetsNormalizer {\n    document;\n    /**\n\t * Creates a new `GoogleSheetsNormalizer` instance.\n\t *\n\t * @param document View document.\n\t */ constructor(document){\n        this.document = document;\n    }\n    /**\n\t * @inheritDoc\n\t */ isActive(htmlString) {\n        return googleSheetsMatch.test(htmlString);\n    }\n    /**\n\t * @inheritDoc\n\t */ execute(data) {\n        const writer = new UpcastWriter(this.document);\n        const { body: documentFragment } = data._parsedData;\n        removeGoogleSheetsTag(documentFragment, writer);\n        removeXmlns(documentFragment, writer);\n        removeInvalidTableWidth(documentFragment, writer);\n        removeStyleBlock(documentFragment, writer);\n        data.content = documentFragment;\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module paste-from-office/filters/space\n */ /**\n * Replaces last space preceding elements closing tag with `&nbsp;`. Such operation prevents spaces from being removed\n * during further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDomInlineNodes}).\n * This method also takes into account Word specific `<o:p></o:p>` empty tags.\n * Additionally multiline sequences of spaces and new lines between tags are removed (see #39 and #40).\n *\n * @param htmlString HTML string in which spacing should be normalized.\n * @returns Input HTML with spaces normalized.\n */ function normalizeSpacing(htmlString) {\n    // Run normalizeSafariSpaceSpans() two times to cover nested spans.\n    return normalizeSafariSpaceSpans(normalizeSafariSpaceSpans(htmlString))// Remove all \\r\\n from \"spacerun spans\" so the last replace line doesn't strip all whitespaces.\n    .replace(/(<span\\s+style=['\"]mso-spacerun:yes['\"]>[^\\S\\r\\n]*?)[\\r\\n]+([^\\S\\r\\n]*<\\/span>)/g, '$1$2').replace(/<span\\s+style=['\"]mso-spacerun:yes['\"]><\\/span>/g, '').replace(/(<span\\s+style=['\"]letter-spacing:[^'\"]+?['\"]>)[\\r\\n]+(<\\/span>)/g, '$1 $2').replace(/ <\\//g, '\\u00A0</').replace(/ <o:p><\\/o:p>/g, '\\u00A0<o:p></o:p>')// Remove <o:p> block filler from empty paragraph. Safari uses \\u00A0 instead of &nbsp;.\n    .replace(/<o:p>(&nbsp;|\\u00A0)<\\/o:p>/g, '')// Remove all whitespaces when they contain any \\r or \\n.\n    .replace(/>([^\\S\\r\\n]*[\\r\\n]\\s*)</g, '><');\n}\n/**\n * Normalizes spacing in special Word `spacerun spans` (`<span style='mso-spacerun:yes'>\\s+</span>`) by replacing\n * all spaces with `&nbsp; ` pairs. This prevents spaces from being removed during further DOM/View processing\n * (see especially {@link module:engine/view/domconverter~DomConverter#_processDomInlineNodes}).\n *\n * @param htmlDocument Native `Document` object in which spacing should be normalized.\n */ function normalizeSpacerunSpans(htmlDocument) {\n    htmlDocument.querySelectorAll('span[style*=spacerun]').forEach((el)=>{\n        const htmlElement = el;\n        const innerTextLength = htmlElement.innerText.length || 0;\n        htmlElement.innerText = Array(innerTextLength + 1).join('\\u00A0 ').substr(0, innerTextLength);\n    });\n}\n/**\n * Normalizes specific spacing generated by Safari when content pasted from Word (`<span class=\"Apple-converted-space\"> </span>`)\n * by replacing all spaces sequences longer than 1 space with `&nbsp; ` pairs. This prevents spaces from being removed during\n * further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).\n *\n * This function is similar to {@link module:clipboard/utils/normalizeclipboarddata normalizeClipboardData util} but uses\n * regular spaces / &nbsp; sequence for replacement.\n *\n * @param htmlString HTML string in which spacing should be normalized\n * @returns Input HTML with spaces normalized.\n */ function normalizeSafariSpaceSpans(htmlString) {\n    return htmlString.replace(/<span(?: class=\"Apple-converted-space\"|)>(\\s+)<\\/span>/g, (fullMatch, spaces)=>{\n        return spaces.length === 1 ? ' ' : Array(spaces.length + 1).join('\\u00A0 ').substr(0, spaces.length);\n    });\n}\n\n/**\n * Parses the provided HTML extracting contents of `<body>` and `<style>` tags.\n *\n * @param htmlString HTML string to be parsed.\n */ function parseHtml(htmlString, stylesProcessor) {\n    const domParser = new DOMParser();\n    // Remove Word specific \"if comments\" so content inside is not omitted by the parser.\n    htmlString = htmlString.replace(/<!--\\[if gte vml 1]>/g, '');\n    // Clean the <head> section of MS Windows specific tags. See https://github.com/ckeditor/ckeditor5/issues/15333.\n    // The regular expression matches the <o:SmartTagType> tag with optional attributes (with or without values).\n    htmlString = htmlString.replace(/<o:SmartTagType(?:\\s+[^\\s>=]+(?:=\"[^\"]*\")?)*\\s*\\/?>/gi, '');\n    const normalizedHtml = normalizeSpacing(cleanContentAfterBody(htmlString));\n    // Parse htmlString as native Document object.\n    const htmlDocument = domParser.parseFromString(normalizedHtml, 'text/html');\n    normalizeSpacerunSpans(htmlDocument);\n    // Get `innerHTML` first as transforming to View modifies the source document.\n    const bodyString = htmlDocument.body.innerHTML;\n    // Transform document.body to View.\n    const bodyView = documentToView(htmlDocument, stylesProcessor);\n    // Extract stylesheets.\n    const stylesObject = extractStyles(htmlDocument);\n    return {\n        body: bodyView,\n        bodyString,\n        styles: stylesObject.styles,\n        stylesString: stylesObject.stylesString\n    };\n}\n/**\n * Transforms native `Document` object into {@link module:engine/view/documentfragment~DocumentFragment}. Comments are skipped.\n *\n * @param htmlDocument Native `Document` object to be transformed.\n */ function documentToView(htmlDocument, stylesProcessor) {\n    const viewDocument = new ViewDocument(stylesProcessor);\n    const domConverter = new DomConverter(viewDocument, {\n        renderingMode: 'data'\n    });\n    const fragment = htmlDocument.createDocumentFragment();\n    const nodes = htmlDocument.body.childNodes;\n    while(nodes.length > 0){\n        fragment.appendChild(nodes[0]);\n    }\n    return domConverter.domToView(fragment, {\n        skipComments: true\n    });\n}\n/**\n * Extracts both `CSSStyleSheet` and string representation from all `style` elements available in a provided `htmlDocument`.\n *\n * @param htmlDocument Native `Document` object from which styles will be extracted.\n */ function extractStyles(htmlDocument) {\n    const styles = [];\n    const stylesString = [];\n    const styleTags = Array.from(htmlDocument.getElementsByTagName('style'));\n    for (const style of styleTags){\n        if (style.sheet && style.sheet.cssRules && style.sheet.cssRules.length) {\n            styles.push(style.sheet);\n            stylesString.push(style.innerHTML);\n        }\n    }\n    return {\n        styles,\n        stylesString: stylesString.join(' ')\n    };\n}\n/**\n * Removes leftover content from between closing </body> and closing </html> tag:\n *\n * ```html\n * <html><body><p>Foo Bar</p></body><span>Fo</span></html> -> <html><body><p>Foo Bar</p></body></html>\n * ```\n *\n * This function is used as specific browsers (Edge) add some random content after `body` tag when pasting from Word.\n * @param htmlString The HTML string to be cleaned.\n * @returns The HTML string with leftover content removed.\n */ function cleanContentAfterBody(htmlString) {\n    const bodyCloseTag = '</body>';\n    const htmlCloseTag = '</html>';\n    const bodyCloseIndex = htmlString.indexOf(bodyCloseTag);\n    if (bodyCloseIndex < 0) {\n        return htmlString;\n    }\n    const htmlCloseIndex = htmlString.indexOf(htmlCloseTag, bodyCloseIndex + bodyCloseTag.length);\n    return htmlString.substring(0, bodyCloseIndex + bodyCloseTag.length) + (htmlCloseIndex >= 0 ? htmlString.substring(htmlCloseIndex) : '');\n}\n\n/**\n * The Paste from Office plugin.\n *\n * This plugin handles content pasted from Office apps and transforms it (if necessary)\n * to a valid structure which can then be understood by the editor features.\n *\n * Transformation is made by a set of predefined {@link module:paste-from-office/normalizer~Normalizer normalizers}.\n * This plugin includes following normalizers:\n * * {@link module:paste-from-office/normalizers/mswordnormalizer~MSWordNormalizer Microsoft Word normalizer}\n * * {@link module:paste-from-office/normalizers/googledocsnormalizer~GoogleDocsNormalizer Google Docs normalizer}\n *\n * For more information about this feature check the {@glink api/paste-from-office package page}.\n */ class PasteFromOffice extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'PasteFromOffice';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ClipboardPipeline\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const clipboardPipeline = editor.plugins.get('ClipboardPipeline');\n        const viewDocument = editor.editing.view.document;\n        const normalizers = [];\n        const hasMultiLevelListPlugin = this.editor.plugins.has('MultiLevelList');\n        normalizers.push(new MSWordNormalizer(viewDocument, hasMultiLevelListPlugin));\n        normalizers.push(new GoogleDocsNormalizer(viewDocument));\n        normalizers.push(new GoogleSheetsNormalizer(viewDocument));\n        clipboardPipeline.on('inputTransformation', (evt, data)=>{\n            if (data._isTransformedWithPasteFromOffice) {\n                return;\n            }\n            const codeBlock = editor.model.document.selection.getFirstPosition().parent;\n            if (codeBlock.is('element', 'codeBlock')) {\n                return;\n            }\n            const htmlString = data.dataTransfer.getData('text/html');\n            const activeNormalizer = normalizers.find((normalizer)=>normalizer.isActive(htmlString));\n            if (activeNormalizer) {\n                if (!data._parsedData) {\n                    data._parsedData = parseHtml(htmlString, viewDocument.stylesProcessor);\n                }\n                activeNormalizer.execute(data);\n                data._isTransformedWithPasteFromOffice = true;\n            }\n        }, {\n            priority: 'high'\n        });\n    }\n}\n\nexport { MSWordNormalizer, PasteFromOffice, parseHtml };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/utils\n */\n\n/**\n * Normalizes CSS length value to 'px'.\n *\n * @internal\n */\nexport function convertCssLengthToPx( value: string ): string {\n\tconst numericValue = parseFloat( value );\n\n\tif ( value.endsWith( 'pt' ) ) {\n\t\t// 1pt = 1in / 72\n\t\treturn toPx( numericValue * 96 / 72 );\n\t}\n\telse if ( value.endsWith( 'pc' ) ) {\n\t\t// 1pc = 12pt = 1in / 6.\n\t\treturn toPx( numericValue * 12 * 96 / 72 );\n\t}\n\telse if ( value.endsWith( 'in' ) ) {\n\t\t// 1in = 2.54cm = 96px\n\t\treturn toPx( numericValue * 96 );\n\t}\n\telse if ( value.endsWith( 'cm' ) ) {\n\t\t// 1cm = 96px / 2.54\n\t\treturn toPx( numericValue * 96 / 2.54 );\n\t}\n\telse if ( value.endsWith( 'mm' ) ) {\n\t\t// 1mm = 1cm / 10\n\t\treturn toPx( numericValue / 10 * 96 / 2.54 );\n\t}\n\n\treturn value;\n}\n\n/**\n * Returns true for value with 'px' unit.\n *\n * @internal\n */\nexport function isPx( value?: string ): value is string {\n\treturn value !== undefined && value.endsWith( 'px' );\n}\n\n/**\n * Returns a rounded 'px' value.\n *\n * @internal\n */\nexport function toPx( value: number ): string {\n\treturn value.toFixed( 2 ).replace( /\\.?0+$/, '' ) + 'px';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/list\n */\n\nimport {\n\tMatcher,\n\tUpcastWriter,\n\ttype ViewDocumentFragment,\n\ttype ViewElement,\n\ttype ViewNode,\n\ttype ViewText\n} from 'ckeditor5/src/engine.js';\n\nimport {\n\tconvertCssLengthToPx,\n\tisPx,\n\ttoPx\n} from './utils.js';\n\n/**\n * Transforms Word specific list-like elements to the semantic HTML lists.\n *\n * Lists in Word are represented by block elements with special attributes like:\n *\n * ```xml\n * <p class=MsoListParagraphCxSpFirst style='mso-list:l1 level1 lfo1'>...</p> // Paragraph based list.\n * <h1 style='mso-list:l0 level1 lfo1'>...</h1> // Heading 1 based list.\n * ```\n *\n * @param documentFragment The view structure to be transformed.\n * @param stylesString Styles from which list-like elements styling will be extracted.\n */\nexport function transformListItemLikeElementsIntoLists(\n\tdocumentFragment: ViewDocumentFragment,\n\tstylesString: string,\n\thasMultiLevelListPlugin: boolean\n): void {\n\tif ( !documentFragment.childCount ) {\n\t\treturn;\n\t}\n\n\tconst writer = new UpcastWriter( documentFragment.document );\n\tconst itemLikeElements = findAllItemLikeElements( documentFragment, writer );\n\n\tif ( !itemLikeElements.length ) {\n\t\treturn;\n\t}\n\n\tconst encounteredLists: Record<string, number> = {};\n\n\tconst stack: Array<ListLikeElement & {\n\t\tlistElement: ViewElement;\n\t\tlistItemElements: Array<ViewElement>;\n\t}> = [];\n\n\tfor ( const itemLikeElement of itemLikeElements ) {\n\t\tif ( itemLikeElement.indent !== undefined ) {\n\t\t\tif ( !isListContinuation( itemLikeElement ) ) {\n\t\t\t\tstack.length = 0;\n\t\t\t}\n\n\t\t\t// Combined list ID for addressing encounter lists counters.\n\t\t\tconst originalListId = `${ itemLikeElement.id }:${ itemLikeElement.indent }`;\n\n\t\t\t// Normalized list item indentation.\n\t\t\tconst indent = Math.min( itemLikeElement.indent - 1, stack.length );\n\n\t\t\t// Trimming of the list stack on list ID change.\n\t\t\tif ( indent < stack.length && stack[ indent ].id !== itemLikeElement.id ) {\n\t\t\t\tstack.length = indent;\n\t\t\t}\n\n\t\t\t// Trimming of the list stack on lower indent list encountered.\n\t\t\tif ( indent < stack.length - 1 ) {\n\t\t\t\tstack.length = indent + 1;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconst listStyle = detectListStyle( itemLikeElement, stylesString );\n\n\t\t\t\t// Create a new OL/UL if required (greater indent or different list type).\n\t\t\t\tif ( indent > stack.length - 1 || stack[ indent ].listElement.name != listStyle.type ) {\n\t\t\t\t\t// Check if there is some start index to set from a previous list.\n\t\t\t\t\tif (\n\t\t\t\t\t\tindent == 0 &&\n\t\t\t\t\t\tlistStyle.type == 'ol' &&\n\t\t\t\t\t\titemLikeElement.id !== undefined &&\n\t\t\t\t\t\tencounteredLists[ originalListId ]\n\t\t\t\t\t) {\n\t\t\t\t\t\tlistStyle.startIndex = encounteredLists[ originalListId ];\n\t\t\t\t\t}\n\n\t\t\t\t\tconst listElement = createNewEmptyList( listStyle, writer, hasMultiLevelListPlugin );\n\n\t\t\t\t\t// Apply list padding only if we have margins for the item and the parent item.\n\t\t\t\t\tif (\n\t\t\t\t\t\tisPx( itemLikeElement.marginLeft ) &&\n\t\t\t\t\t\t( indent == 0 || isPx( stack[ indent - 1 ].marginLeft ) )\n\t\t\t\t\t) {\n\t\t\t\t\t\tlet marginLeft = itemLikeElement.marginLeft;\n\n\t\t\t\t\t\tif ( indent > 0 ) {\n\t\t\t\t\t\t\t// Convert the padding from absolute to relative.\n\t\t\t\t\t\t\tmarginLeft = toPx( parseFloat( marginLeft ) - parseFloat( stack[ indent - 1 ].marginLeft! ) );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twriter.setStyle( 'padding-left', marginLeft, listElement );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Insert the new OL/UL.\n\t\t\t\t\tif ( stack.length == 0 ) {\n\t\t\t\t\t\tconst parent = itemLikeElement.element.parent!;\n\t\t\t\t\t\tconst index = parent.getChildIndex( itemLikeElement.element ) + 1;\n\n\t\t\t\t\t\twriter.insertChild( index, listElement, parent );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst parentListItems = stack[ indent - 1 ].listItemElements;\n\n\t\t\t\t\t\twriter.appendChild( listElement, parentListItems[ parentListItems.length - 1 ] );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Update the list stack for other items to reference.\n\t\t\t\t\tstack[ indent ] = {\n\t\t\t\t\t\t...itemLikeElement,\n\t\t\t\t\t\tlistElement,\n\t\t\t\t\t\tlistItemElements: []\n\t\t\t\t\t};\n\n\t\t\t\t\t// Prepare list counter for start index.\n\t\t\t\t\tif ( indent == 0 && itemLikeElement.id !== undefined ) {\n\t\t\t\t\t\tencounteredLists[ originalListId ] = listStyle.startIndex || 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Use LI if it is already it or create a new LI element.\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/15964\n\t\t\tconst listItem = itemLikeElement.element.name == 'li' ? itemLikeElement.element : writer.createElement( 'li' );\n\n\t\t\t// Append the LI to OL/UL.\n\t\t\twriter.appendChild( listItem, stack[ indent ].listElement );\n\t\t\tstack[ indent ].listItemElements.push( listItem );\n\n\t\t\t// Increment list counter.\n\t\t\tif ( indent == 0 && itemLikeElement.id !== undefined ) {\n\t\t\t\tencounteredLists[ originalListId ]++;\n\t\t\t}\n\n\t\t\t// Append list block to LI.\n\t\t\tif ( itemLikeElement.element != listItem ) {\n\t\t\t\twriter.appendChild( itemLikeElement.element, listItem );\n\t\t\t}\n\n\t\t\t// Clean list block.\n\t\t\tremoveBulletElement( itemLikeElement.element, writer );\n\t\t\twriter.removeStyle( 'text-indent', itemLikeElement.element ); // #12361\n\t\t\twriter.removeStyle( 'margin-left', itemLikeElement.element );\n\t\t}\n\t\telse {\n\t\t\t// Other blocks in a list item.\n\t\t\tconst stackItem = stack.find( stackItem => stackItem.marginLeft == itemLikeElement.marginLeft );\n\n\t\t\t// This might be a paragraph that has known margin, but it is not a real list block.\n\t\t\tif ( stackItem ) {\n\t\t\t\tconst listItems = stackItem.listItemElements;\n\n\t\t\t\t// Append block to LI.\n\t\t\t\twriter.appendChild( itemLikeElement.element, listItems[ listItems.length - 1 ] );\n\t\t\t\twriter.removeStyle( 'margin-left', itemLikeElement.element );\n\t\t\t} else {\n\t\t\t\tstack.length = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Removes paragraph wrapping content inside a list item.\n */\nexport function unwrapParagraphInListItem(\n\tdocumentFragment: ViewDocumentFragment,\n\twriter: UpcastWriter\n): void {\n\tfor ( const value of writer.createRangeIn( documentFragment ) ) {\n\t\tconst element = value.item;\n\n\t\tif ( element.is( 'element', 'li' ) ) {\n\t\t\t// Google Docs allows for single paragraph inside LI.\n\t\t\tconst firstChild = element.getChild( 0 );\n\n\t\t\tif ( firstChild && firstChild.is( 'element', 'p' ) ) {\n\t\t\t\twriter.unwrapElement( firstChild );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Finds all list-like elements in a given document fragment.\n *\n * @param documentFragment Document fragment in which to look for list-like nodes.\n * @returns Array of found list-like items. Each item is an object containing:\n */\nfunction findAllItemLikeElements(\n\tdocumentFragment: ViewDocumentFragment,\n\twriter: UpcastWriter\n): Array<ListLikeElement> {\n\tconst range = writer.createRangeIn( documentFragment );\n\tconst itemLikeElements: Array<ListLikeElement> = [];\n\tconst foundMargins = new Set<string>();\n\n\tfor ( const item of range.getItems() ) {\n\t\t// https://github.com/ckeditor/ckeditor5/issues/15964\n\t\tif ( !item.is( 'element' ) || !item.name.match( /^(p|h\\d+|li|div)$/ ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Try to rely on margin-left style to find paragraphs visually aligned with previously encountered list item.\n\t\tlet marginLeft = getMarginLeftNormalized( item );\n\n\t\t// Ignore margin-left 0 style if there is no MsoList... class.\n\t\tif (\n\t\t\tmarginLeft !== undefined &&\n\t\t\tparseFloat( marginLeft ) == 0 &&\n\t\t\t!Array.from( item.getClassNames() ).find( className => className.startsWith( 'MsoList' ) )\n\t\t) {\n\t\t\tmarginLeft = undefined;\n\t\t}\n\n\t\t// List item or a following list item block.\n\t\tif ( item.hasStyle( 'mso-list' ) || marginLeft !== undefined && foundMargins.has( marginLeft ) ) {\n\t\t\tconst itemData = getListItemData( item );\n\n\t\t\titemLikeElements.push( {\n\t\t\t\telement: item,\n\t\t\t\tid: itemData.id,\n\t\t\t\torder: itemData.order,\n\t\t\t\tindent: itemData.indent,\n\t\t\t\tmarginLeft\n\t\t\t} );\n\n\t\t\tif ( marginLeft !== undefined ) {\n\t\t\t\tfoundMargins.add( marginLeft );\n\t\t\t}\n\t\t}\n\t\t// Clear found margins as we found block after a list.\n\t\telse {\n\t\t\tfoundMargins.clear();\n\t\t}\n\t}\n\n\treturn itemLikeElements;\n}\n\n/**\n * Whether the given element is possibly a list continuation. Previous element was wrapped into a list\n * or the current element already is inside a list.\n */\nfunction isListContinuation( currentItem: ListLikeElement ) {\n\tconst previousSibling = currentItem.element.previousSibling;\n\n\tif ( !previousSibling ) {\n\t\t// If it's a li inside ul or ol like in here: https://github.com/ckeditor/ckeditor5/issues/15964.\n\t\treturn isList( currentItem.element.parent as ViewElement );\n\t}\n\n\t// Even with the same id the list does not have to be continuous (#43).\n\treturn isList( previousSibling );\n}\n\nfunction isList( element: ViewNode ) {\n\treturn element.is( 'element', 'ol' ) || element.is( 'element', 'ul' );\n}\n\n/**\n * Extracts list item style from the provided CSS.\n *\n * List item style is extracted from the CSS stylesheet. Each list with its specific style attribute\n * value (`mso-list:l1 level1 lfo1`) has its dedicated properties in a CSS stylesheet defined with a selector like:\n *\n * ```css\n * @list l1:level1 { ... }\n * ```\n *\n * It contains `mso-level-number-format` property which defines list numbering/bullet style. If this property\n * is not defined it means default `decimal` numbering.\n *\n * Here CSS string representation is used as `mso-level-number-format` property is an invalid CSS property\n * and will be removed during CSS parsing.\n *\n * @param listLikeItem List-like item for which list style will be searched for. Usually\n * a result of `findAllItemLikeElements()` function.\n * @param stylesString CSS stylesheet.\n * @returns An object with properties:\n *\n * * type - List type, could be `ul` or `ol`.\n * * startIndex - List start index, valid only for ordered lists.\n * * style - List style, for example: `decimal`, `lower-roman`, etc. It is extracted\n *     directly from Word stylesheet and adjusted to represent proper values for the CSS `list-style-type` property.\n *     If it cannot be adjusted, the `null` value is returned.\n */\nfunction detectListStyle( listLikeItem: ListLikeElement, stylesString: string ) {\n\tconst listStyleRegexp = new RegExp( `@list l${ listLikeItem.id }:level${ listLikeItem.indent }\\\\s*({[^}]*)`, 'gi' );\n\tconst listStyleTypeRegex = /mso-level-number-format:([^;]{0,100});/gi;\n\tconst listStartIndexRegex = /mso-level-start-at:\\s{0,100}([0-9]{0,10})\\s{0,100};/gi;\n\tconst legalStyleListRegex = new RegExp( `@list\\\\s+l${ listLikeItem.id }:level\\\\d\\\\s*{[^{]*mso-level-text:\"%\\\\d\\\\\\\\.`, 'gi' );\n\tconst multiLevelNumberFormatTypeRegex = new RegExp( `@list l${ listLikeItem.id }:level\\\\d\\\\s*{[^{]*mso-level-number-format:`, 'gi' );\n\n\tconst legalStyleListMatch = legalStyleListRegex.exec( stylesString );\n\tconst multiLevelNumberFormatMatch = multiLevelNumberFormatTypeRegex.exec( stylesString );\n\n\t// Multi level lists in Word have mso-level-number-format attribute except legal lists,\n\t// so we used that. If list has legal list match and doesn't has mso-level-number-format\n\t// then this is legal-list.\n\tconst islegalStyleList = legalStyleListMatch && !multiLevelNumberFormatMatch;\n\n\tconst listStyleMatch = listStyleRegexp.exec( stylesString );\n\n\tlet listStyleType = 'decimal'; // Decimal is default one.\n\tlet type = 'ol'; // <ol> is default list.\n\tlet startIndex = null;\n\n\tif ( listStyleMatch && listStyleMatch[ 1 ] ) {\n\t\tconst listStyleTypeMatch = listStyleTypeRegex.exec( listStyleMatch[ 1 ] );\n\n\t\tif ( listStyleTypeMatch && listStyleTypeMatch[ 1 ] ) {\n\t\t\tlistStyleType = listStyleTypeMatch[ 1 ].trim();\n\t\t\ttype = listStyleType !== 'bullet' && listStyleType !== 'image' ? 'ol' : 'ul';\n\t\t}\n\n\t\t// Styles for the numbered lists are always defined in the Word CSS stylesheet.\n\t\t// Unordered lists MAY contain a value for the Word CSS definition `mso-level-text` but sometimes\n\t\t// this tag is missing. And because of that, we cannot depend on that. We need to predict the list style value\n\t\t// based on the list style marker element.\n\t\tif ( listStyleType === 'bullet' ) {\n\t\t\tconst bulletedStyle = findBulletedListStyle( listLikeItem.element );\n\n\t\t\tif ( bulletedStyle ) {\n\t\t\t\tlistStyleType = bulletedStyle;\n\t\t\t}\n\t\t} else {\n\t\t\tconst listStartIndexMatch = listStartIndexRegex.exec( listStyleMatch[ 1 ] );\n\n\t\t\tif ( listStartIndexMatch && listStartIndexMatch[ 1 ] ) {\n\t\t\t\tstartIndex = parseInt( listStartIndexMatch[ 1 ] );\n\t\t\t}\n\t\t}\n\n\t\tif ( islegalStyleList ) {\n\t\t\ttype = 'ol';\n\t\t}\n\t}\n\n\treturn {\n\t\ttype,\n\t\tstartIndex,\n\t\tstyle: mapListStyleDefinition( listStyleType ),\n\t\tisLegalStyleList: islegalStyleList\n\t};\n}\n\n/**\n * Tries to extract the `list-style-type` value based on the marker element for bulleted list.\n */\nfunction findBulletedListStyle( element: ViewElement ) {\n\t// https://github.com/ckeditor/ckeditor5/issues/15964\n\tif ( element.name == 'li' && element.parent!.name == 'ul' && element.parent!.hasAttribute( 'type' ) ) {\n\t\treturn element.parent!.getAttribute( 'type' );\n\t}\n\n\tconst listMarkerElement = findListMarkerNode( element );\n\n\tif ( !listMarkerElement ) {\n\t\treturn null;\n\t}\n\n\tconst listMarker = listMarkerElement._data;\n\n\tif ( listMarker === 'o' ) {\n\t\treturn 'circle';\n\t} else if ( listMarker === '·' ) {\n\t\treturn 'disc';\n\t}\n\t// Word returns '§' instead of '■' for the square list style.\n\telse if ( listMarker === '§' ) {\n\t\treturn 'square';\n\t}\n\n\treturn null;\n}\n\n/**\n * Tries to find a text node that represents the marker element (list-style-type).\n */\nfunction findListMarkerNode( element: ViewElement ): ViewText | null {\n\t// If the first child is a text node, it is the data for the element.\n\t// The list-style marker is not present here.\n\tif ( element.getChild( 0 )!.is( '$text' ) ) {\n\t\treturn null;\n\t}\n\n\tfor ( const childNode of element.getChildren() ) {\n\t\t// The list-style marker will be inside the `<span>` element. Let's ignore all non-span elements.\n\t\t// It may happen that the `<a>` element is added as the first child. Most probably, it's an anchor element.\n\t\tif ( !childNode.is( 'element', 'span' ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst textNodeOrElement = childNode.getChild( 0 );\n\n\t\tif ( !textNodeOrElement ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// If already found the marker element, use it.\n\t\tif ( textNodeOrElement.is( '$text' ) ) {\n\t\t\treturn textNodeOrElement;\n\t\t}\n\n\t\treturn ( textNodeOrElement as any ).getChild( 0 );\n\t}\n\n\t/* istanbul ignore next -- @preserve */\n\treturn null;\n}\n\n/**\n * Parses the `list-style-type` value extracted directly from the Word CSS stylesheet and returns proper CSS definition.\n */\nfunction mapListStyleDefinition( value: string ) {\n\tif ( value.startsWith( 'arabic-leading-zero' ) ) {\n\t\treturn 'decimal-leading-zero';\n\t}\n\n\tswitch ( value ) {\n\t\tcase 'alpha-upper':\n\t\t\treturn 'upper-alpha';\n\t\tcase 'alpha-lower':\n\t\t\treturn 'lower-alpha';\n\t\tcase 'roman-upper':\n\t\t\treturn 'upper-roman';\n\t\tcase 'roman-lower':\n\t\t\treturn 'lower-roman';\n\t\tcase 'circle':\n\t\tcase 'disc':\n\t\tcase 'square':\n\t\t\treturn value;\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n/**\n * Creates a new list OL/UL element.\n */\nfunction createNewEmptyList(\n\tlistStyle: ReturnType<typeof detectListStyle>,\n\twriter: UpcastWriter,\n\thasMultiLevelListPlugin: boolean\n) {\n\tconst list = writer.createElement( listStyle.type );\n\n\t// We do not support modifying the marker for a particular list item.\n\t// Set the value for the `list-style-type` property directly to the list container.\n\tif ( listStyle.style ) {\n\t\twriter.setStyle( 'list-style-type', listStyle.style, list );\n\t}\n\n\tif ( listStyle.startIndex && listStyle.startIndex > 1 ) {\n\t\twriter.setAttribute( 'start', listStyle.startIndex, list );\n\t}\n\n\tif ( listStyle.isLegalStyleList && hasMultiLevelListPlugin ) {\n\t\twriter.addClass( 'legal-list', list );\n\t}\n\n\treturn list;\n}\n\n/**\n * Extracts list item information from Word specific list-like element style:\n *\n * ```\n * `style=\"mso-list:l1 level1 lfo1\"`\n * ```\n *\n * where:\n *\n * ```\n * * `l1` is a list id (however it does not mean this is a continuous list - see #43),\n * * `level1` is a list item indentation level,\n * * `lfo1` is a list insertion order in a document.\n * ```\n *\n * @param element Element from which style data is extracted.\n */\nfunction getListItemData( element: ViewElement ): ListItemData {\n\tconst listStyle = element.getStyle( 'mso-list' );\n\n\tif ( listStyle === undefined ) {\n\t\treturn {};\n\t}\n\n\tconst idMatch = listStyle.match( /(^|\\s{1,100})l(\\d+)/i );\n\tconst orderMatch = listStyle.match( /\\s{0,100}lfo(\\d+)/i );\n\tconst indentMatch = listStyle.match( /\\s{0,100}level(\\d+)/i );\n\n\tif ( idMatch && orderMatch && indentMatch ) {\n\t\treturn {\n\t\t\tid: idMatch[ 2 ],\n\t\t\torder: orderMatch[ 1 ],\n\t\t\tindent: parseInt( indentMatch[ 1 ] )\n\t\t};\n\t}\n\n\treturn {\n\t\tindent: 1 // Handle empty mso-list style as a marked for default list item.\n\t};\n}\n\n/**\n * Removes span with a numbering/bullet from a given element.\n */\nfunction removeBulletElement( element: ViewElement, writer: UpcastWriter ) {\n\t// Matcher for finding `span` elements holding lists numbering/bullets.\n\tconst bulletMatcher = new Matcher( {\n\t\tname: 'span',\n\t\tstyles: {\n\t\t\t'mso-list': 'Ignore'\n\t\t}\n\t} );\n\n\tconst range = writer.createRangeIn( element );\n\n\tfor ( const value of range ) {\n\t\tif ( value.type === 'elementStart' && bulletMatcher.match( value.item as ViewElement ) ) {\n\t\t\twriter.remove( value.item as ViewElement );\n\t\t}\n\t}\n}\n\n/**\n * Returns element left margin normalized to 'px' if possible.\n */\nfunction getMarginLeftNormalized( element: ViewElement ): string | undefined {\n\tconst value = element.getStyle( 'margin-left' );\n\n\tif ( value === undefined || value.endsWith( 'px' ) ) {\n\t\treturn value;\n\t}\n\n\treturn convertCssLengthToPx( value );\n}\n\ninterface ListItemData {\n\n\t/**\n\t * Parent list id.\n\t */\n\tid?: string;\n\n\t/**\n\t * List item creation order.\n\t */\n\torder?: string;\n\n\t/**\n\t * List item indentation level.\n\t */\n\tindent?: number;\n}\n\ninterface ListLikeElement extends ListItemData {\n\n\t/**\n\t * List-like element.\n\t */\n\telement: ViewElement;\n\n\t/**\n\t * The margin-left normalized to 'px' if possible.\n\t */\n\tmarginLeft?: string;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/image\n */\n\n/* globals btoa */\n\nimport {\n\tMatcher,\n\tUpcastWriter,\n\ttype ViewDocumentFragment,\n\ttype ViewElement,\n\ttype ViewNode\n} from 'ckeditor5/src/engine.js';\n\n/**\n * Replaces source attribute of all `<img>` elements representing regular\n * images (not the Word shapes) with inlined base64 image representation extracted from RTF or Blob data.\n *\n * @param documentFragment Document fragment on which transform images.\n * @param rtfData The RTF data from which images representation will be used.\n */\nexport function replaceImagesSourceWithBase64( documentFragment: ViewDocumentFragment, rtfData: string ): void {\n\tif ( !documentFragment.childCount ) {\n\t\treturn;\n\t}\n\n\tconst upcastWriter = new UpcastWriter( documentFragment.document );\n\tconst shapesIds = findAllShapesIds( documentFragment, upcastWriter );\n\n\tremoveAllImgElementsRepresentingShapes( shapesIds, documentFragment, upcastWriter );\n\tinsertMissingImgs( shapesIds, documentFragment, upcastWriter );\n\tremoveAllShapeElements( documentFragment, upcastWriter );\n\n\tconst images = findAllImageElementsWithLocalSource( documentFragment, upcastWriter );\n\n\tif ( images.length ) {\n\t\treplaceImagesFileSourceWithInlineRepresentation( images, extractImageDataFromRtf( rtfData ), upcastWriter );\n\t}\n}\n\n/**\n * Converts given HEX string to base64 representation.\n *\n * @internal\n * @param hexString The HEX string to be converted.\n * @returns Base64 representation of a given HEX string.\n */\nexport function _convertHexToBase64( hexString: string ): string {\n\treturn btoa( hexString.match( /\\w{2}/g )!.map( char => {\n\t\treturn String.fromCharCode( parseInt( char, 16 ) );\n\t} ).join( '' ) );\n}\n\n/**\n * Finds all shapes (`<v:*>...</v:*>`) ids. Shapes can represent images (canvas)\n * or Word shapes (which does not have RTF or Blob representation).\n *\n * @param documentFragment Document fragment from which to extract shape ids.\n * @returns Array of shape ids.\n */\nfunction findAllShapesIds( documentFragment: ViewDocumentFragment, writer: UpcastWriter ): Array<string> {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst shapeElementsMatcher = new Matcher( {\n\t\tname: /v:(.+)/\n\t} );\n\n\tconst shapesIds = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.type != 'elementStart' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst el = value.item as ViewElement;\n\t\tconst previousSibling = el.previousSibling;\n\t\tconst prevSiblingName = previousSibling && previousSibling.is( 'element' ) ? previousSibling.name : null;\n\t\t// List of ids which should not be considered as shapes.\n\t\t// https://github.com/ckeditor/ckeditor5/pull/15847#issuecomment-1941543983\n\t\tconst exceptionIds = [ 'Chart' ];\n\n\t\tconst isElementAShape = shapeElementsMatcher.match( el );\n\t\tconst hasElementGfxdataAttribute = el.getAttribute( 'o:gfxdata' );\n\t\tconst isPreviousSiblingAShapeType = prevSiblingName === 'v:shapetype';\n\t\tconst isElementIdInExceptionsArray = hasElementGfxdataAttribute &&\n\t\t\texceptionIds.some( item => el.getAttribute( 'id' )!.includes( item ) );\n\n\t\t// If shape element has 'o:gfxdata' attribute and is not directly before\n\t\t// `<v:shapetype>` element it means that it represents a Word shape.\n\t\tif (\n\t\t\tisElementAShape &&\n\t\t\thasElementGfxdataAttribute &&\n\t\t\t!isPreviousSiblingAShapeType &&\n\t\t\t!isElementIdInExceptionsArray\n\t\t) {\n\t\t\tshapesIds.push( ( value.item as ViewElement ).getAttribute( 'id' )! );\n\t\t}\n\t}\n\n\treturn shapesIds;\n}\n\n/**\n * Removes all `<img>` elements which represents Word shapes and not regular images.\n *\n * @param shapesIds Shape ids which will be checked against `<img>` elements.\n * @param documentFragment Document fragment from which to remove `<img>` elements.\n */\nfunction removeAllImgElementsRepresentingShapes(\n\tshapesIds: Array<string>,\n\tdocumentFragment: ViewDocumentFragment,\n\twriter: UpcastWriter\n): void {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst imageElementsMatcher = new Matcher( {\n\t\tname: 'img'\n\t} );\n\n\tconst imgs = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'element' ) && imageElementsMatcher.match( value.item ) ) {\n\t\t\tconst el = value.item;\n\t\t\tconst shapes = el.getAttribute( 'v:shapes' ) ? el.getAttribute( 'v:shapes' )!.split( ' ' ) : [];\n\n\t\t\tif ( shapes.length && shapes.every( shape => shapesIds.indexOf( shape ) > -1 ) ) {\n\t\t\t\timgs.push( el );\n\t\t\t// Shapes may also have empty source while content is paste in some browsers (Safari).\n\t\t\t} else if ( !el.getAttribute( 'src' ) ) {\n\t\t\t\timgs.push( el );\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( const img of imgs ) {\n\t\twriter.remove( img );\n\t}\n}\n\n/**\n * Removes all shape elements (`<v:*>...</v:*>`) so they do not pollute the output structure.\n *\n * @param documentFragment Document fragment from which to remove shape elements.\n */\nfunction removeAllShapeElements( documentFragment: ViewDocumentFragment, writer: UpcastWriter ) {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst shapeElementsMatcher = new Matcher( {\n\t\tname: /v:(.+)/\n\t} );\n\n\tconst shapes = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.type == 'elementStart' && shapeElementsMatcher.match( value.item as ViewElement ) ) {\n\t\t\tshapes.push( value.item as ViewElement );\n\t\t}\n\t}\n\n\tfor ( const shape of shapes ) {\n\t\twriter.remove( shape );\n\t}\n}\n\n/**\n * Inserts `img` tags if there is none after a shape.\n */\nfunction insertMissingImgs( shapeIds: Array<string>, documentFragment: ViewDocumentFragment, writer: UpcastWriter ) {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst shapes: Array<ViewElement> = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.type == 'elementStart' && value.item.is( 'element', 'v:shape' ) ) {\n\t\t\tconst id = value.item.getAttribute( 'id' )!;\n\n\t\t\tif ( shapeIds.includes( id ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !containsMatchingImg( value.item.parent!.getChildren(), id ) ) {\n\t\t\t\tshapes.push( value.item );\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( const shape of shapes ) {\n\t\tconst attrs: Record<string, unknown> = {\n\t\t\tsrc: findSrc( shape )\n\t\t};\n\n\t\tif ( shape.hasAttribute( 'alt' ) ) {\n\t\t\tattrs.alt = shape.getAttribute( 'alt' );\n\t\t}\n\n\t\tconst img = writer.createElement( 'img', attrs );\n\n\t\twriter.insertChild( shape.index! + 1, img, shape.parent! );\n\t}\n\n\tfunction containsMatchingImg( nodes: Iterable<ViewNode>, id: string ): boolean {\n\t\tfor ( const node of nodes ) {\n\t\t\t/* istanbul ignore else -- @preserve */\n\t\t\tif ( node.is( 'element' ) ) {\n\t\t\t\tif ( node.name == 'img' && node.getAttribute( 'v:shapes' ) == id ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tif ( containsMatchingImg( node.getChildren(), id ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction findSrc( shape: ViewElement ) {\n\t\tfor ( const child of shape.getChildren() ) {\n\t\t\t/* istanbul ignore else -- @preserve */\n\t\t\tif ( child.is( 'element' ) && child.getAttribute( 'src' ) ) {\n\t\t\t\treturn child.getAttribute( 'src' );\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Finds all `<img>` elements in a given document fragment which have source pointing to local `file://` resource.\n *\n * @param documentFragment Document fragment in which to look for `<img>` elements.\n * @returns result All found images grouped by source type.\n */\nfunction findAllImageElementsWithLocalSource(\n\tdocumentFragment: ViewDocumentFragment,\n\twriter: UpcastWriter\n): Array<ViewElement> {\n\tconst range = writer.createRangeIn( documentFragment );\n\n\tconst imageElementsMatcher = new Matcher( {\n\t\tname: 'img'\n\t} );\n\n\tconst imgs = [];\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'element' ) && imageElementsMatcher.match( value.item ) ) {\n\t\t\tif ( value.item.getAttribute( 'src' )!.startsWith( 'file://' ) ) {\n\t\t\t\timgs.push( value.item );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn imgs;\n}\n\n/**\n * Extracts all images HEX representations from a given RTF data.\n *\n * @param rtfData The RTF data from which to extract images HEX representation.\n * @returns Array of found HEX representations. Each array item is an object containing:\n *\n * * hex Image representation in HEX format.\n * * type Type of image, `image/png` or `image/jpeg`.\n */\nfunction extractImageDataFromRtf( rtfData: string ): Array<{ hex: string; type: string }> {\n\tif ( !rtfData ) {\n\t\treturn [];\n\t}\n\n\tconst regexPictureHeader = /{\\\\pict[\\s\\S]+?\\\\bliptag-?\\d+(\\\\blipupi-?\\d+)?({\\\\\\*\\\\blipuid\\s?[\\da-fA-F]+)?[\\s}]*?/;\n\tconst regexPicture = new RegExp( '(?:(' + regexPictureHeader.source + '))([\\\\da-fA-F\\\\s]+)\\\\}', 'g' );\n\tconst images = rtfData.match( regexPicture );\n\tconst result = [];\n\n\tif ( images ) {\n\t\tfor ( const image of images ) {\n\t\t\tlet imageType: string | false = false;\n\n\t\t\tif ( image.includes( '\\\\pngblip' ) ) {\n\t\t\t\timageType = 'image/png';\n\t\t\t} else if ( image.includes( '\\\\jpegblip' ) ) {\n\t\t\t\timageType = 'image/jpeg';\n\t\t\t}\n\n\t\t\tif ( imageType ) {\n\t\t\t\tresult.push( {\n\t\t\t\t\thex: image.replace( regexPictureHeader, '' ).replace( /[^\\da-fA-F]/g, '' ),\n\t\t\t\t\ttype: imageType\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Replaces `src` attribute value of all given images with the corresponding base64 image representation.\n *\n * @param imageElements Array of image elements which will have its source replaced.\n * @param imagesHexSources Array of images hex sources (usually the result of `extractImageDataFromRtf()` function).\n * The array should be the same length as `imageElements` parameter.\n */\nfunction replaceImagesFileSourceWithInlineRepresentation(\n\timageElements: Array<ViewElement>,\n\timagesHexSources: ReturnType<typeof extractImageDataFromRtf>,\n\twriter: UpcastWriter\n) {\n\t// Assume there is an equal amount of image elements and images HEX sources so they can be matched accordingly based on existing order.\n\tif ( imageElements.length === imagesHexSources.length ) {\n\t\tfor ( let i = 0; i < imageElements.length; i++ ) {\n\t\t\tconst newSrc = `data:${ imagesHexSources[ i ].type };base64,${ _convertHexToBase64( imagesHexSources[ i ].hex ) }`;\n\t\t\twriter.setAttribute( 'src', newSrc, imageElements[ i ] );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/removemsattributes\n */\n\nimport { UpcastWriter, type ViewDocumentFragment, type ViewElement } from 'ckeditor5/src/engine.js';\n\n/**\n * Cleanup MS attributes like styles, attributes and elements.\n *\n * @param documentFragment element `data.content` obtained from clipboard.\n */\nexport default function removeMSAttributes( documentFragment: ViewDocumentFragment ): void {\n\tconst elementsToUnwrap: Array<ViewElement> = [];\n\n\tconst writer = new UpcastWriter( documentFragment.document );\n\n\tfor ( const { item } of writer.createRangeIn( documentFragment ) ) {\n\t\tif ( !item.is( 'element' ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor ( const className of item.getClassNames() ) {\n\t\t\tif ( /\\bmso/gi.exec( className ) ) {\n\t\t\t\twriter.removeClass( className, item );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const styleName of item.getStyleNames() ) {\n\t\t\tif ( /\\bmso/gi.exec( styleName ) ) {\n\t\t\t\twriter.removeStyle( styleName, item );\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\titem.is( 'element', 'w:sdt' ) ||\n\t\t\titem.is( 'element', 'w:sdtpr' ) && item.isEmpty ||\n\t\t\titem.is( 'element', 'o:p' ) && item.isEmpty\n\t\t) {\n\t\t\telementsToUnwrap.push( item );\n\t\t}\n\t}\n\n\tfor ( const item of elementsToUnwrap ) {\n\t\tconst itemParent = item.parent!;\n\t\tconst childIndex = itemParent.getChildIndex( item );\n\n\t\twriter.insertChild( childIndex, item.getChildren(), itemParent );\n\t\twriter.remove( item );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/normalizers/mswordnormalizer\n */\n\nimport { transformListItemLikeElementsIntoLists } from '../filters/list.js';\nimport { replaceImagesSourceWithBase64 } from '../filters/image.js';\nimport removeMSAttributes from '../filters/removemsattributes.js';\nimport type { ViewDocument } from 'ckeditor5/src/engine.js';\nimport type { Normalizer, NormalizerData } from '../normalizer.js';\n\nconst msWordMatch1 = /<meta\\s*name=\"?generator\"?\\s*content=\"?microsoft\\s*word\\s*\\d+\"?\\/?>/i;\nconst msWordMatch2 = /xmlns:o=\"urn:schemas-microsoft-com/i;\n\n/**\n * Normalizer for the content pasted from Microsoft Word.\n */\nexport default class MSWordNormalizer implements Normalizer {\n\tpublic readonly document: ViewDocument;\n\n\tpublic readonly hasMultiLevelListPlugin: boolean;\n\n\t/**\n\t * Creates a new `MSWordNormalizer` instance.\n\t *\n\t * @param document View document.\n\t */\n\tconstructor( document: ViewDocument, hasMultiLevelListPlugin: boolean = false ) {\n\t\tthis.document = document;\n\t\tthis.hasMultiLevelListPlugin = hasMultiLevelListPlugin;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isActive( htmlString: string ): boolean {\n\t\treturn msWordMatch1.test( htmlString ) || msWordMatch2.test( htmlString );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic execute( data: NormalizerData ): void {\n\t\tconst { body: documentFragment, stylesString } = data._parsedData;\n\n\t\ttransformListItemLikeElementsIntoLists( documentFragment, stylesString, this.hasMultiLevelListPlugin );\n\t\treplaceImagesSourceWithBase64( documentFragment, data.dataTransfer.getData( 'text/rtf' ) );\n\t\tremoveMSAttributes( documentFragment );\n\n\t\tdata.content = documentFragment;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/removeboldwrapper\n */\n\nimport type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';\n\n/**\n * Removes the `<b>` tag wrapper added by Google Docs to a copied content.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */\nexport default function removeBoldWrapper( documentFragment: ViewDocumentFragment, writer: UpcastWriter ): void {\n\tfor ( const child of documentFragment.getChildren() ) {\n\t\tif ( child.is( 'element', 'b' ) && child.getStyle( 'font-weight' ) === 'normal' ) {\n\t\t\tconst childIndex = documentFragment.getChildIndex( child );\n\n\t\t\twriter.remove( child );\n\t\t\twriter.insertChild( childIndex, child.getChildren(), documentFragment );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/br\n */\n\nimport {\n\tDomConverter,\n\tViewDocument,\n\ttype UpcastWriter,\n\ttype ViewDocumentFragment,\n\ttype ViewElement,\n\ttype ViewNode\n} from 'ckeditor5/src/engine.js';\n\n/**\n * Transforms `<br>` elements that are siblings to some block element into a paragraphs.\n *\n * @param documentFragment The view structure to be transformed.\n */\nexport default function transformBlockBrsToParagraphs(\n\tdocumentFragment: ViewDocumentFragment,\n\twriter: UpcastWriter\n): void {\n\tconst viewDocument = new ViewDocument( writer.document.stylesProcessor );\n\tconst domConverter = new DomConverter( viewDocument, { renderingMode: 'data' } );\n\n\tconst blockElements = domConverter.blockElements;\n\tconst inlineObjectElements = domConverter.inlineObjectElements;\n\n\tconst elementsToReplace = [];\n\n\tfor ( const value of writer.createRangeIn( documentFragment ) ) {\n\t\tconst element = value.item;\n\n\t\tif ( element.is( 'element', 'br' ) ) {\n\t\t\tconst nextSibling = findSibling( element, 'forward', writer, { blockElements, inlineObjectElements } );\n\t\t\tconst previousSibling = findSibling( element, 'backward', writer, { blockElements, inlineObjectElements } );\n\n\t\t\tconst nextSiblingIsBlock = isBlockViewElement( nextSibling, blockElements );\n\t\t\tconst previousSiblingIsBlock = isBlockViewElement( previousSibling, blockElements );\n\n\t\t\t// If the <br> is surrounded by blocks then convert it to a paragraph:\n\t\t\t// * <p>foo</p>[<br>]<p>bar</p> -> <p>foo</p>[<p></p>]<p>bar</p>\n\t\t\t// * <p>foo</p>[<br>] -> <p>foo</p>[<p></p>]\n\t\t\t// * [<br>]<p>foo</p> -> [<p></p>]<p>foo</p>\n\t\t\tif ( previousSiblingIsBlock || nextSiblingIsBlock ) {\n\t\t\t\telementsToReplace.push( element );\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( const element of elementsToReplace ) {\n\t\tif ( element.hasClass( 'Apple-interchange-newline' ) ) {\n\t\t\twriter.remove( element );\n\t\t} else {\n\t\t\twriter.replace( element, writer.createElement( 'p' ) );\n\t\t}\n\t}\n}\n\n/**\n * Returns sibling node, threats inline elements as transparent (but should stop on an inline objects).\n */\nfunction findSibling(\n\tviewElement: ViewElement,\n\tdirection: 'forward' | 'backward',\n\twriter: UpcastWriter,\n\t{ blockElements, inlineObjectElements }: { blockElements: Array<string>; inlineObjectElements: Array<string> }\n) {\n\tlet position = writer.createPositionAt( viewElement, direction == 'forward' ? 'after' : 'before' );\n\n\t// Find first position that is just before a first:\n\t// * text node,\n\t// * block element,\n\t// * inline object element.\n\t// It's ignoring any inline (non-object) elements like span, strong, etc.\n\tposition = position.getLastMatchingPosition( ( { item } ) => (\n\t\titem.is( 'element' ) &&\n\t\t!blockElements.includes( item.name ) &&\n\t\t!inlineObjectElements.includes( item.name )\n\t), { direction } );\n\n\treturn direction == 'forward' ? position.nodeAfter : position.nodeBefore;\n}\n\n/**\n * Returns true for view elements that are listed as block view elements.\n */\nfunction isBlockViewElement( node: ViewNode | null, blockElements: Array<string> ) {\n\treturn !!node && node.is( 'element' ) && blockElements.includes( node.name );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/normalizers/googledocsnormalizer\n */\n\nimport { UpcastWriter, type ViewDocument } from 'ckeditor5/src/engine.js';\n\nimport removeBoldWrapper from '../filters/removeboldwrapper.js';\nimport transformBlockBrsToParagraphs from '../filters/br.js';\nimport { unwrapParagraphInListItem } from '../filters/list.js';\nimport type { Normalizer, NormalizerData } from '../normalizer.js';\n\nconst googleDocsMatch = /id=(\"|')docs-internal-guid-[-0-9a-f]+(\"|')/i;\n\n/**\n * Normalizer for the content pasted from Google Docs.\n */\nexport default class GoogleDocsNormalizer implements Normalizer {\n\tpublic readonly document: ViewDocument;\n\n\t/**\n\t * Creates a new `GoogleDocsNormalizer` instance.\n\t *\n\t * @param document View document.\n\t */\n\tconstructor( document: ViewDocument ) {\n\t\tthis.document = document;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isActive( htmlString: string ): boolean {\n\t\treturn googleDocsMatch.test( htmlString );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic execute( data: NormalizerData ): void {\n\t\tconst writer = new UpcastWriter( this.document );\n\t\tconst { body: documentFragment } = data._parsedData;\n\n\t\tremoveBoldWrapper( documentFragment, writer );\n\t\tunwrapParagraphInListItem( documentFragment, writer );\n\t\ttransformBlockBrsToParagraphs( documentFragment, writer );\n\n\t\tdata.content = documentFragment;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/removexmlns\n */\n\nimport type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';\n\n/**\n * Removes the `xmlns` attribute from table pasted from Google Sheets.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */\nexport default function removeXmlns( documentFragment: ViewDocumentFragment, writer: UpcastWriter ): void {\n\tfor ( const child of documentFragment.getChildren() ) {\n\t\tif ( child.is( 'element', 'table' ) && child.hasAttribute( 'xmlns' ) ) {\n\t\t\twriter.removeAttribute( 'xmlns', child );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/removegooglesheetstag\n */\n\nimport type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';\n\n/**\n * Removes the `<google-sheets-html-origin>` tag wrapper added by Google Sheets to a copied content.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */\nexport default function removeGoogleSheetsTag( documentFragment: ViewDocumentFragment, writer: UpcastWriter ): void {\n\tfor ( const child of documentFragment.getChildren() ) {\n\t\tif ( child.is( 'element', 'google-sheets-html-origin' ) ) {\n\t\t\tconst childIndex = documentFragment.getChildIndex( child );\n\n\t\t\twriter.remove( child );\n\t\t\twriter.insertChild( childIndex, child.getChildren(), documentFragment );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/removeinvalidtablewidth\n */\n\nimport type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';\n\n/**\n * Removes the `width:0px` style from table pasted from Google Sheets.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */\nexport default function removeInvalidTableWidth( documentFragment: ViewDocumentFragment, writer: UpcastWriter ): void {\n\tfor ( const child of documentFragment.getChildren() ) {\n\t\tif ( child.is( 'element', 'table' ) && child.getStyle( 'width' ) === '0px' ) {\n\t\t\twriter.removeStyle( 'width', child );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/removestyleblock\n */\n\nimport type { UpcastWriter, ViewDocumentFragment } from 'ckeditor5/src/engine.js';\n\n/**\n * Removes `<style>` block added by Google Sheets to a copied content.\n *\n * @param documentFragment element `data.content` obtained from clipboard\n */\nexport default function removeStyleBlock( documentFragment: ViewDocumentFragment, writer: UpcastWriter ): void {\n\tfor ( const child of Array.from( documentFragment.getChildren() ) ) {\n\t\tif ( child.is( 'element', 'style' ) ) {\n\t\t\twriter.remove( child );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/normalizers/googlesheetsnormalizer\n */\n\nimport { UpcastWriter, type ViewDocument } from 'ckeditor5/src/engine.js';\n\nimport removeXmlns from '../filters/removexmlns.js';\nimport removeGoogleSheetsTag from '../filters/removegooglesheetstag.js';\nimport removeInvalidTableWidth from '../filters/removeinvalidtablewidth.js';\nimport removeStyleBlock from '../filters/removestyleblock.js';\nimport type { Normalizer, NormalizerData } from '../normalizer.js';\n\nconst googleSheetsMatch = /<google-sheets-html-origin/i;\n\n/**\n * Normalizer for the content pasted from Google Sheets.\n */\nexport default class GoogleSheetsNormalizer implements Normalizer {\n\tpublic readonly document: ViewDocument;\n\n\t/**\n\t * Creates a new `GoogleSheetsNormalizer` instance.\n\t *\n\t * @param document View document.\n\t */\n\tconstructor( document: ViewDocument ) {\n\t\tthis.document = document;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic isActive( htmlString: string ): boolean {\n\t\treturn googleSheetsMatch.test( htmlString );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic execute( data: NormalizerData ): void {\n\t\tconst writer = new UpcastWriter( this.document );\n\t\tconst { body: documentFragment } = data._parsedData;\n\n\t\tremoveGoogleSheetsTag( documentFragment, writer );\n\t\tremoveXmlns( documentFragment, writer );\n\t\tremoveInvalidTableWidth( documentFragment, writer );\n\t\tremoveStyleBlock( documentFragment, writer );\n\n\t\tdata.content = documentFragment;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/space\n */\n\n/**\n * Replaces last space preceding elements closing tag with `&nbsp;`. Such operation prevents spaces from being removed\n * during further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDomInlineNodes}).\n * This method also takes into account Word specific `<o:p></o:p>` empty tags.\n * Additionally multiline sequences of spaces and new lines between tags are removed (see #39 and #40).\n *\n * @param htmlString HTML string in which spacing should be normalized.\n * @returns Input HTML with spaces normalized.\n */\nexport function normalizeSpacing( htmlString: string ): string {\n\t// Run normalizeSafariSpaceSpans() two times to cover nested spans.\n\treturn normalizeSafariSpaceSpans( normalizeSafariSpaceSpans( htmlString ) )\n\t\t// Remove all \\r\\n from \"spacerun spans\" so the last replace line doesn't strip all whitespaces.\n\t\t.replace( /(<span\\s+style=['\"]mso-spacerun:yes['\"]>[^\\S\\r\\n]*?)[\\r\\n]+([^\\S\\r\\n]*<\\/span>)/g, '$1$2' )\n\t\t.replace( /<span\\s+style=['\"]mso-spacerun:yes['\"]><\\/span>/g, '' )\n\t\t.replace( /(<span\\s+style=['\"]letter-spacing:[^'\"]+?['\"]>)[\\r\\n]+(<\\/span>)/g, '$1 $2' )\n\t\t.replace( / <\\//g, '\\u00A0</' )\n\t\t.replace( / <o:p><\\/o:p>/g, '\\u00A0<o:p></o:p>' )\n\t\t// Remove <o:p> block filler from empty paragraph. Safari uses \\u00A0 instead of &nbsp;.\n\t\t.replace( /<o:p>(&nbsp;|\\u00A0)<\\/o:p>/g, '' )\n\t\t// Remove all whitespaces when they contain any \\r or \\n.\n\t\t.replace( />([^\\S\\r\\n]*[\\r\\n]\\s*)</g, '><' );\n}\n\n/**\n * Normalizes spacing in special Word `spacerun spans` (`<span style='mso-spacerun:yes'>\\s+</span>`) by replacing\n * all spaces with `&nbsp; ` pairs. This prevents spaces from being removed during further DOM/View processing\n * (see especially {@link module:engine/view/domconverter~DomConverter#_processDomInlineNodes}).\n *\n * @param htmlDocument Native `Document` object in which spacing should be normalized.\n */\nexport function normalizeSpacerunSpans( htmlDocument: Document ): void {\n\thtmlDocument.querySelectorAll( 'span[style*=spacerun]' ).forEach( el => {\n\t\tconst htmlElement = el as HTMLElement;\n\t\tconst innerTextLength = htmlElement.innerText.length || 0;\n\n\t\thtmlElement.innerText = Array( innerTextLength + 1 ).join( '\\u00A0 ' ).substr( 0, innerTextLength );\n\t} );\n}\n\n/**\n * Normalizes specific spacing generated by Safari when content pasted from Word (`<span class=\"Apple-converted-space\"> </span>`)\n * by replacing all spaces sequences longer than 1 space with `&nbsp; ` pairs. This prevents spaces from being removed during\n * further DOM/View processing (see especially {@link module:engine/view/domconverter~DomConverter#_processDataFromDomText}).\n *\n * This function is similar to {@link module:clipboard/utils/normalizeclipboarddata normalizeClipboardData util} but uses\n * regular spaces / &nbsp; sequence for replacement.\n *\n * @param htmlString HTML string in which spacing should be normalized\n * @returns Input HTML with spaces normalized.\n */\nfunction normalizeSafariSpaceSpans( htmlString: string ) {\n\treturn htmlString.replace( /<span(?: class=\"Apple-converted-space\"|)>(\\s+)<\\/span>/g, ( fullMatch, spaces ) => {\n\t\treturn spaces.length === 1 ? ' ' : Array( spaces.length + 1 ).join( '\\u00A0 ' ).substr( 0, spaces.length );\n\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/filters/parse\n */\n\n/* globals DOMParser */\n\nimport {\n\tDomConverter,\n\tViewDocument,\n\ttype StylesProcessor,\n\ttype ViewDocumentFragment\n} from 'ckeditor5/src/engine.js';\n\nimport { normalizeSpacing, normalizeSpacerunSpans } from './space.js';\n\n/**\n * Parses the provided HTML extracting contents of `<body>` and `<style>` tags.\n *\n * @param htmlString HTML string to be parsed.\n */\nexport function parseHtml( htmlString: string, stylesProcessor: StylesProcessor ): ParseHtmlResult {\n\tconst domParser = new DOMParser();\n\n\t// Remove Word specific \"if comments\" so content inside is not omitted by the parser.\n\thtmlString = htmlString.replace( /<!--\\[if gte vml 1]>/g, '' );\n\n\t// Clean the <head> section of MS Windows specific tags. See https://github.com/ckeditor/ckeditor5/issues/15333.\n\t// The regular expression matches the <o:SmartTagType> tag with optional attributes (with or without values).\n\thtmlString = htmlString.replace( /<o:SmartTagType(?:\\s+[^\\s>=]+(?:=\"[^\"]*\")?)*\\s*\\/?>/gi, '' );\n\n\tconst normalizedHtml = normalizeSpacing( cleanContentAfterBody( htmlString ) );\n\n\t// Parse htmlString as native Document object.\n\tconst htmlDocument = domParser.parseFromString( normalizedHtml, 'text/html' );\n\n\tnormalizeSpacerunSpans( htmlDocument );\n\n\t// Get `innerHTML` first as transforming to View modifies the source document.\n\tconst bodyString = htmlDocument.body.innerHTML;\n\n\t// Transform document.body to View.\n\tconst bodyView = documentToView( htmlDocument, stylesProcessor );\n\n\t// Extract stylesheets.\n\tconst stylesObject = extractStyles( htmlDocument );\n\n\treturn {\n\t\tbody: bodyView,\n\t\tbodyString,\n\t\tstyles: stylesObject.styles,\n\t\tstylesString: stylesObject.stylesString\n\t};\n}\n\n/**\n * The result of {@link ~parseHtml}.\n */\nexport interface ParseHtmlResult {\n\n\t/**\n\t * Parsed body content as a traversable structure.\n\t */\n\tbody: ViewDocumentFragment;\n\n\t/**\n\t * Entire body content as a string.\n\t */\n\tbodyString: string;\n\n\t/**\n\t * Array of native `CSSStyleSheet` objects, each representing separate `style` tag from the source HTML.\n\t */\n\tstyles: Array<CSSStyleSheet>;\n\n\t/**\n\t * All `style` tags contents combined in the order of occurrence into one string.\n\t */\n\tstylesString: string;\n}\n\n/**\n * Transforms native `Document` object into {@link module:engine/view/documentfragment~DocumentFragment}. Comments are skipped.\n *\n * @param htmlDocument Native `Document` object to be transformed.\n */\nfunction documentToView( htmlDocument: Document, stylesProcessor: StylesProcessor ) {\n\tconst viewDocument = new ViewDocument( stylesProcessor );\n\tconst domConverter = new DomConverter( viewDocument, { renderingMode: 'data' } );\n\tconst fragment = htmlDocument.createDocumentFragment();\n\tconst nodes = htmlDocument.body.childNodes;\n\n\twhile ( nodes.length > 0 ) {\n\t\tfragment.appendChild( nodes[ 0 ] );\n\t}\n\n\treturn domConverter.domToView( fragment, { skipComments: true } ) as ViewDocumentFragment;\n}\n\n/**\n * Extracts both `CSSStyleSheet` and string representation from all `style` elements available in a provided `htmlDocument`.\n *\n * @param htmlDocument Native `Document` object from which styles will be extracted.\n */\nfunction extractStyles( htmlDocument: Document ): { styles: Array<CSSStyleSheet>; stylesString: string } {\n\tconst styles = [];\n\tconst stylesString = [];\n\tconst styleTags = Array.from( htmlDocument.getElementsByTagName( 'style' ) );\n\n\tfor ( const style of styleTags ) {\n\t\tif ( style.sheet && style.sheet.cssRules && style.sheet.cssRules.length ) {\n\t\t\tstyles.push( style.sheet );\n\t\t\tstylesString.push( style.innerHTML );\n\t\t}\n\t}\n\n\treturn {\n\t\tstyles,\n\t\tstylesString: stylesString.join( ' ' )\n\t};\n}\n\n/**\n * Removes leftover content from between closing </body> and closing </html> tag:\n *\n * ```html\n * <html><body><p>Foo Bar</p></body><span>Fo</span></html> -> <html><body><p>Foo Bar</p></body></html>\n * ```\n *\n * This function is used as specific browsers (Edge) add some random content after `body` tag when pasting from Word.\n * @param htmlString The HTML string to be cleaned.\n * @returns The HTML string with leftover content removed.\n */\nfunction cleanContentAfterBody( htmlString: string ) {\n\tconst bodyCloseTag = '</body>';\n\tconst htmlCloseTag = '</html>';\n\n\tconst bodyCloseIndex = htmlString.indexOf( bodyCloseTag );\n\n\tif ( bodyCloseIndex < 0 ) {\n\t\treturn htmlString;\n\t}\n\n\tconst htmlCloseIndex = htmlString.indexOf( htmlCloseTag, bodyCloseIndex + bodyCloseTag.length );\n\n\treturn htmlString.substring( 0, bodyCloseIndex + bodyCloseTag.length ) +\n\t\t( htmlCloseIndex >= 0 ? htmlString.substring( htmlCloseIndex ) : '' );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module paste-from-office/pastefromoffice\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport { ClipboardPipeline } from 'ckeditor5/src/clipboard.js';\n\nimport MSWordNormalizer from './normalizers/mswordnormalizer.js';\nimport GoogleDocsNormalizer from './normalizers/googledocsnormalizer.js';\nimport GoogleSheetsNormalizer from './normalizers/googlesheetsnormalizer.js';\n\nimport { parseHtml } from './filters/parse.js';\nimport type { Normalizer, NormalizerData } from './normalizer.js';\n\n/**\n * The Paste from Office plugin.\n *\n * This plugin handles content pasted from Office apps and transforms it (if necessary)\n * to a valid structure which can then be understood by the editor features.\n *\n * Transformation is made by a set of predefined {@link module:paste-from-office/normalizer~Normalizer normalizers}.\n * This plugin includes following normalizers:\n * * {@link module:paste-from-office/normalizers/mswordnormalizer~MSWordNormalizer Microsoft Word normalizer}\n * * {@link module:paste-from-office/normalizers/googledocsnormalizer~GoogleDocsNormalizer Google Docs normalizer}\n *\n * For more information about this feature check the {@glink api/paste-from-office package page}.\n */\nexport default class PasteFromOffice extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'PasteFromOffice' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ClipboardPipeline ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst clipboardPipeline: ClipboardPipeline = editor.plugins.get( 'ClipboardPipeline' );\n\t\tconst viewDocument = editor.editing.view.document;\n\t\tconst normalizers: Array<Normalizer> = [];\n\t\tconst hasMultiLevelListPlugin = this.editor.plugins.has( 'MultiLevelList' );\n\n\t\tnormalizers.push( new MSWordNormalizer( viewDocument, hasMultiLevelListPlugin ) );\n\t\tnormalizers.push( new GoogleDocsNormalizer( viewDocument ) );\n\t\tnormalizers.push( new GoogleSheetsNormalizer( viewDocument ) );\n\n\t\tclipboardPipeline.on(\n\t\t\t'inputTransformation',\n\t\t\t( evt, data: NormalizerData ) => {\n\t\t\t\tif ( data._isTransformedWithPasteFromOffice ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst codeBlock = editor.model.document.selection.getFirstPosition()!.parent;\n\n\t\t\t\tif ( codeBlock.is( 'element', 'codeBlock' ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst htmlString = data.dataTransfer.getData( 'text/html' );\n\t\t\t\tconst activeNormalizer = normalizers.find( normalizer => normalizer.isActive( htmlString ) );\n\n\t\t\t\tif ( activeNormalizer ) {\n\t\t\t\t\tif ( !data._parsedData ) {\n\t\t\t\t\t\tdata._parsedData = parseHtml( htmlString, viewDocument.stylesProcessor );\n\t\t\t\t\t}\n\n\t\t\t\t\tactiveNormalizer.execute( data );\n\n\t\t\t\t\tdata._isTransformedWithPasteFromOffice = true;\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ priority: 'high' }\n\t\t);\n\t}\n}\n", "import { Plugin, Command } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { first } from '@ckeditor/ckeditor5-utils/dist/index.js';\n\nvar removeFormatIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M8.69 14.915c.053.052.173.083.36.093a.366.366 0 0 1 .345.485l-.003.01a.738.738 0 0 1-.697.497h-2.67a.374.374 0 0 1-.353-.496l.013-.038a.681.681 0 0 1 .644-.458c.197-.012.325-.043.386-.093a.28.28 0 0 0 .072-.11L9.592 4.5H6.269c-.359-.017-.609.013-.75.09-.142.078-.289.265-.442.563-.192.29-.516.464-.864.464H4.17a.43.43 0 0 1-.407-.569L4.46 3h13.08l-.62 2.043a.81.81 0 0 1-.775.574h-.114a.486.486 0 0 1-.486-.486c.001-.284-.054-.464-.167-.54-.112-.076-.367-.106-.766-.091h-3.28l-2.68 10.257c-.006.074.007.127.038.158zM3 17h8a.5.5 0 1 1 0 1H3a.5.5 0 1 1 0-1zm11.299 1.17a.75.75 0 1 1-1.06-1.06l1.414-1.415-1.415-1.414a.75.75 0 0 1 1.06-1.06l1.415 1.414 1.414-1.415a.75.75 0 1 1 1.06 1.06l-1.413 1.415 1.414 1.415a.75.75 0 0 1-1.06 1.06l-1.415-1.414-1.414 1.414z\\\"/></svg>\";\n\nconst REMOVE_FORMAT = 'removeFormat';\n/**\n * The remove format UI plugin. It registers the `'removeFormat'` button which can be\n * used in the toolbar.\n */ class RemoveFormatUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'RemoveFormatUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        editor.ui.componentFactory.add(REMOVE_FORMAT, ()=>{\n            const view = this._createButton(ButtonView);\n            view.set({\n                tooltip: true\n            });\n            return view;\n        });\n        editor.ui.componentFactory.add(`menuBar:${REMOVE_FORMAT}`, ()=>this._createButton(MenuBarMenuListItemButtonView));\n    }\n    /**\n\t * Creates a button for remove format command to use either in toolbar or in menu bar.\n\t */ _createButton(ButtonClass) {\n        const editor = this.editor;\n        const locale = editor.locale;\n        const command = editor.commands.get(REMOVE_FORMAT);\n        const view = new ButtonClass(editor.locale);\n        const t = locale.t;\n        view.set({\n            label: t('Remove Format'),\n            icon: removeFormatIcon\n        });\n        view.bind('isEnabled').to(command, 'isEnabled');\n        // Execute the command.\n        this.listenTo(view, 'execute', ()=>{\n            editor.execute(REMOVE_FORMAT);\n            editor.editing.view.focus();\n        });\n        return view;\n    }\n}\n\n/**\n * The remove format command.\n *\n * It is used by the {@link module:remove-format/removeformat~RemoveFormat remove format feature}\n * to clear the formatting in the selection.\n *\n * ```ts\n * editor.execute( 'removeFormat' );\n * ```\n */ class RemoveFormatCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        this.isEnabled = !!first(this._getFormattingItems(model.document.selection, model.schema));\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const model = this.editor.model;\n        const schema = model.schema;\n        model.change((writer)=>{\n            for (const item of this._getFormattingItems(model.document.selection, schema)){\n                if (item.is('selection')) {\n                    for (const attributeName of this._getFormattingAttributes(item, schema)){\n                        writer.removeSelectionAttribute(attributeName);\n                    }\n                } else {\n                    // Workaround for items with multiple removable attributes. See\n                    // https://github.com/ckeditor/ckeditor5-remove-format/pull/1#pullrequestreview-220515609\n                    const itemRange = writer.createRangeOn(item);\n                    for (const attributeName of this._getFormattingAttributes(item, schema)){\n                        writer.removeAttribute(attributeName, itemRange);\n                    }\n                }\n            }\n        });\n    }\n    /**\n\t * Returns an iterable of items in a selection (including the selection itself) that have formatting model\n\t * attributes to be removed by the feature.\n\t *\n\t * @param schema The schema describing the item.\n\t */ *_getFormattingItems(selection, schema) {\n        const itemHasRemovableFormatting = (item)=>{\n            return !!first(this._getFormattingAttributes(item, schema));\n        };\n        // Check formatting on selected items that are not blocks.\n        for (const curRange of selection.getRanges()){\n            for (const item of curRange.getItems()){\n                if (!schema.isBlock(item) && itemHasRemovableFormatting(item)) {\n                    yield item;\n                }\n            }\n        }\n        // Check formatting from selected blocks.\n        for (const block of selection.getSelectedBlocks()){\n            if (itemHasRemovableFormatting(block)) {\n                yield block;\n            }\n        }\n        // Finally the selection might be formatted as well, so make sure to check it.\n        if (itemHasRemovableFormatting(selection)) {\n            yield selection;\n        }\n    }\n    /**\n\t * Returns an iterable of formatting attributes of a given model item.\n\t *\n\t * **Note:** Formatting items have the `isFormatting` property set to `true`.\n\t *\n\t * @param schema The schema describing the item.\n\t * @returns The names of formatting attributes found in a given item.\n\t */ *_getFormattingAttributes(item, schema) {\n        for (const [attributeName] of item.getAttributes()){\n            const attributeProperties = schema.getAttributeProperties(attributeName);\n            if (attributeProperties && attributeProperties.isFormatting) {\n                yield attributeName;\n            }\n        }\n    }\n}\n\n/**\n * The remove format editing plugin.\n *\n * It registers the {@link module:remove-format/removeformatcommand~RemoveFormatCommand removeFormat} command.\n */ class RemoveFormatEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'RemoveFormatEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        editor.commands.add('removeFormat', new RemoveFormatCommand(editor));\n    }\n}\n\n/**\n * The remove format plugin.\n *\n * This is a \"glue\" plugin which loads the {@link module:remove-format/removeformatediting~RemoveFormatEditing}\n * and {@link module:remove-format/removeformatui~RemoveFormatUI} plugins.\n *\n * For a detailed overview, check out the {@glink features/remove-format remove format} feature documentation.\n */ class RemoveFormat extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            RemoveFormatEditing,\n            RemoveFormatUI\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'RemoveFormat';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { RemoveFormat, RemoveFormatEditing, RemoveFormatUI };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module remove-format/removeformatui\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { ButtonView, MenuBarMenuListItemButtonView } from 'ckeditor5/src/ui.js';\n\nimport type RemoveFormatCommand from './removeformatcommand.js';\n\nimport removeFormatIcon from '../theme/icons/remove-format.svg';\n\nconst REMOVE_FORMAT = 'removeFormat';\n\n/**\n * The remove format UI plugin. It registers the `'removeFormat'` button which can be\n * used in the toolbar.\n */\nexport default class RemoveFormatUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'RemoveFormatUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.ui.componentFactory.add( REMOVE_FORMAT, () => {\n\t\t\tconst view = this._createButton( ButtonView );\n\n\t\t\tview.set( {\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( `menuBar:${ REMOVE_FORMAT }`, () => this._createButton( MenuBarMenuListItemButtonView ) );\n\t}\n\n\t/**\n\t * Creates a button for remove format command to use either in toolbar or in menu bar.\n\t */\n\tprivate _createButton<T extends typeof ButtonView | typeof MenuBarMenuListItemButtonView>( ButtonClass: T ): InstanceType<T> {\n\t\tconst editor = this.editor;\n\t\tconst locale = editor.locale;\n\t\tconst command: RemoveFormatCommand = editor.commands.get( REMOVE_FORMAT )!;\n\t\tconst view = new ButtonClass( editor.locale ) as InstanceType<T>;\n\t\tconst t = locale.t;\n\n\t\tview.set( {\n\t\t\tlabel: t( 'Remove Format' ),\n\t\t\ticon: removeFormatIcon\n\t\t} );\n\n\t\tview.bind( 'isEnabled' ).to( command, 'isEnabled' );\n\n\t\t// Execute the command.\n\t\tthis.listenTo( view, 'execute', () => {\n\t\t\teditor.execute( REMOVE_FORMAT );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn view;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module remove-format/removeformatcommand\n */\n\nimport type { DocumentSelection, Item, Schema } from 'ckeditor5/src/engine.js';\nimport { Command } from 'ckeditor5/src/core.js';\nimport { first } from 'ckeditor5/src/utils.js';\n\n/**\n * The remove format command.\n *\n * It is used by the {@link module:remove-format/removeformat~RemoveFormat remove format feature}\n * to clear the formatting in the selection.\n *\n * ```ts\n * editor.execute( 'removeFormat' );\n * ```\n */\nexport default class RemoveFormatCommand extends Command {\n\tdeclare public value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\n\t\tthis.isEnabled = !!first( this._getFormattingItems( model.document.selection, model.schema ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of this._getFormattingItems( model.document.selection, schema ) ) {\n\t\t\t\tif ( item.is( 'selection' ) ) {\n\t\t\t\t\tfor ( const attributeName of this._getFormattingAttributes( item, schema ) ) {\n\t\t\t\t\t\twriter.removeSelectionAttribute( attributeName );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Workaround for items with multiple removable attributes. See\n\t\t\t\t\t// https://github.com/ckeditor/ckeditor5-remove-format/pull/1#pullrequestreview-220515609\n\t\t\t\t\tconst itemRange = writer.createRangeOn( item );\n\n\t\t\t\t\tfor ( const attributeName of this._getFormattingAttributes( item, schema ) ) {\n\t\t\t\t\t\twriter.removeAttribute( attributeName, itemRange );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns an iterable of items in a selection (including the selection itself) that have formatting model\n\t * attributes to be removed by the feature.\n\t *\n\t * @param schema The schema describing the item.\n\t */\n\tprivate* _getFormattingItems( selection: DocumentSelection, schema: Schema ) {\n\t\tconst itemHasRemovableFormatting = ( item: Item | DocumentSelection ) => {\n\t\t\treturn !!first( this._getFormattingAttributes( item, schema ) );\n\t\t};\n\n\t\t// Check formatting on selected items that are not blocks.\n\t\tfor ( const curRange of selection.getRanges() ) {\n\t\t\tfor ( const item of curRange.getItems() ) {\n\t\t\t\tif ( !schema.isBlock( item ) && itemHasRemovableFormatting( item ) ) {\n\t\t\t\t\tyield item;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check formatting from selected blocks.\n\t\tfor ( const block of selection.getSelectedBlocks() ) {\n\t\t\tif ( itemHasRemovableFormatting( block ) ) {\n\t\t\t\tyield block;\n\t\t\t}\n\t\t}\n\n\t\t// Finally the selection might be formatted as well, so make sure to check it.\n\t\tif ( itemHasRemovableFormatting( selection ) ) {\n\t\t\tyield selection;\n\t\t}\n\t}\n\n\t/**\n\t * Returns an iterable of formatting attributes of a given model item.\n\t *\n\t * **Note:** Formatting items have the `isFormatting` property set to `true`.\n\t *\n\t * @param schema The schema describing the item.\n\t * @returns The names of formatting attributes found in a given item.\n\t */\n\tprivate* _getFormattingAttributes( item: Item | DocumentSelection, schema: Schema ) {\n\t\tfor ( const [ attributeName ] of item.getAttributes() ) {\n\t\t\tconst attributeProperties = schema.getAttributeProperties( attributeName );\n\n\t\t\tif ( attributeProperties && attributeProperties.isFormatting ) {\n\t\t\t\tyield attributeName;\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module remove-format/removeformatediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport RemoveFormatCommand from './removeformatcommand.js';\n\n/**\n * The remove format editing plugin.\n *\n * It registers the {@link module:remove-format/removeformatcommand~RemoveFormatCommand removeFormat} command.\n */\nexport default class RemoveFormatEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'RemoveFormatEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\teditor.commands.add( 'removeFormat', new RemoveFormatCommand( editor ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module remove-format/removeformat\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport RemoveFormatUI from './removeformatui.js';\nimport RemoveFormatEditing from './removeformatediting.js';\n\n/**\n * The remove format plugin.\n *\n * This is a \"glue\" plugin which loads the {@link module:remove-format/removeformatediting~RemoveFormatEditing}\n * and {@link module:remove-format/removeformatui~RemoveFormatUI} plugins.\n *\n * For a detailed overview, check out the {@glink features/remove-format remove format} feature documentation.\n */\nexport default class RemoveFormat extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ RemoveFormatEditing, RemoveFormatUI ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'RemoveFormat' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "import { Command, Plugin, icons } from '@ckeditor/ckeditor5-core/dist/index.js';\nimport { toWidgetEditable, toWidget, Widget, isWidget, WidgetToolbarRepository } from '@ckeditor/ckeditor5-widget/dist/index.js';\nimport { first, global, CKEditorError, KeystrokeHandler, FocusTracker, Collection, getLocalizedArrowKeyCodeDirection, Rect, DomEmitterMixin } from '@ckeditor/ckeditor5-utils/dist/index.js';\nimport { View, addKeyboardHandlingForGrid, ButtonView, createDropdown, MenuBarMenuView, SwitchButtonView, SplitButtonView, addListToDropdown, ViewModel, ViewCollection, FocusCycler, InputTextView, ColorSelectorView, FormHeaderView, submitHandler, LabelView, LabeledFieldView, createLabeledDropdown, createLabeledInputText, ToolbarView, BalloonPanelView, ContextualBalloon, normalizeColorOptions, getLocalizedColorOptions, clickOutsideHandler } from '@ckeditor/ckeditor5-ui/dist/index.js';\nimport { ClipboardMarkersUtils, ClipboardPipeline } from '@ckeditor/ckeditor5-clipboard/dist/index.js';\nimport { DomEventObserver, isColor, isLength, isPercentage, addBorderRules, addPaddingRules, addBackgroundRules, enablePlaceholder, Element } from '@ckeditor/ckeditor5-engine/dist/index.js';\nimport { isObject, debounce, isEqual, throttle } from 'lodash-es';\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module table/converters/tableproperties\n */ /**\n * Conversion helper for upcasting attributes using normalized styles.\n *\n * @param options.modelAttribute The attribute to set.\n * @param options.styleName The style name to convert.\n * @param options.viewElement The view element name that should be converted.\n * @param options.defaultValue The default value for the specified `modelAttribute`.\n * @param options.shouldUpcast The function which returns `true` if style should be upcasted from this element.\n */ function upcastStyleToAttribute(conversion, options) {\n    const { modelAttribute, styleName, viewElement, defaultValue, reduceBoxSides = false, shouldUpcast = ()=>true } = options;\n    conversion.for('upcast').attributeToAttribute({\n        view: {\n            name: viewElement,\n            styles: {\n                [styleName]: /[\\s\\S]+/\n            }\n        },\n        model: {\n            key: modelAttribute,\n            value: (viewElement)=>{\n                if (!shouldUpcast(viewElement)) {\n                    return;\n                }\n                const normalized = viewElement.getNormalizedStyle(styleName);\n                const value = reduceBoxSides ? reduceBoxSidesValue(normalized) : normalized;\n                if (defaultValue !== value) {\n                    return value;\n                }\n            }\n        }\n    });\n}\n/**\n * Conversion helper for upcasting border styles for view elements.\n *\n * @param defaultBorder The default border values.\n * @param defaultBorder.color The default `borderColor` value.\n * @param defaultBorder.style The default `borderStyle` value.\n * @param defaultBorder.width The default `borderWidth` value.\n */ function upcastBorderStyles(conversion, viewElementName, modelAttributes, defaultBorder) {\n    conversion.for('upcast').add((dispatcher)=>dispatcher.on('element:' + viewElementName, (evt, data, conversionApi)=>{\n            // If the element was not converted by element-to-element converter,\n            // we should not try to convert the style. See #8393.\n            if (!data.modelRange) {\n                return;\n            }\n            // Check the most detailed properties. These will be always set directly or\n            // when using the \"group\" properties like: `border-(top|right|bottom|left)` or `border`.\n            const stylesToConsume = [\n                'border-top-width',\n                'border-top-color',\n                'border-top-style',\n                'border-bottom-width',\n                'border-bottom-color',\n                'border-bottom-style',\n                'border-right-width',\n                'border-right-color',\n                'border-right-style',\n                'border-left-width',\n                'border-left-color',\n                'border-left-style'\n            ].filter((styleName)=>data.viewItem.hasStyle(styleName));\n            if (!stylesToConsume.length) {\n                return;\n            }\n            const matcherPattern = {\n                styles: stylesToConsume\n            };\n            // Try to consume appropriate values from consumable values list.\n            if (!conversionApi.consumable.test(data.viewItem, matcherPattern)) {\n                return;\n            }\n            const modelElement = [\n                ...data.modelRange.getItems({\n                    shallow: true\n                })\n            ].pop();\n            conversionApi.consumable.consume(data.viewItem, matcherPattern);\n            const normalizedBorder = {\n                style: data.viewItem.getNormalizedStyle('border-style'),\n                color: data.viewItem.getNormalizedStyle('border-color'),\n                width: data.viewItem.getNormalizedStyle('border-width')\n            };\n            const reducedBorder = {\n                style: reduceBoxSidesValue(normalizedBorder.style),\n                color: reduceBoxSidesValue(normalizedBorder.color),\n                width: reduceBoxSidesValue(normalizedBorder.width)\n            };\n            if (reducedBorder.style !== defaultBorder.style) {\n                conversionApi.writer.setAttribute(modelAttributes.style, reducedBorder.style, modelElement);\n            }\n            if (reducedBorder.color !== defaultBorder.color) {\n                conversionApi.writer.setAttribute(modelAttributes.color, reducedBorder.color, modelElement);\n            }\n            if (reducedBorder.width !== defaultBorder.width) {\n                conversionApi.writer.setAttribute(modelAttributes.width, reducedBorder.width, modelElement);\n            }\n        }));\n}\n/**\n * Conversion helper for downcasting an attribute to a style.\n */ function downcastAttributeToStyle(conversion, options) {\n    const { modelElement, modelAttribute, styleName } = options;\n    conversion.for('downcast').attributeToAttribute({\n        model: {\n            name: modelElement,\n            key: modelAttribute\n        },\n        view: (modelAttributeValue)=>({\n                key: 'style',\n                value: {\n                    [styleName]: modelAttributeValue\n                }\n            })\n    });\n}\n/**\n * Conversion helper for downcasting attributes from the model table to a view table (not to `<figure>`).\n */ function downcastTableAttribute(conversion, options) {\n    const { modelAttribute, styleName } = options;\n    conversion.for('downcast').add((dispatcher)=>dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi)=>{\n            const { item, attributeNewValue } = data;\n            const { mapper, writer } = conversionApi;\n            if (!conversionApi.consumable.consume(data.item, evt.name)) {\n                return;\n            }\n            const table = [\n                ...mapper.toViewElement(item).getChildren()\n            ].find((child)=>child.is('element', 'table'));\n            if (attributeNewValue) {\n                writer.setStyle(styleName, attributeNewValue, table);\n            } else {\n                writer.removeStyle(styleName, table);\n            }\n        }));\n}\n/**\n * Reduces the full top, right, bottom, left object to a single string if all sides are equal.\n * Returns original style otherwise.\n */ function reduceBoxSidesValue(style) {\n    if (!style) {\n        return;\n    }\n    const sides = [\n        'top',\n        'right',\n        'bottom',\n        'left'\n    ];\n    const allSidesDefined = sides.every((side)=>style[side]);\n    if (!allSidesDefined) {\n        return style;\n    }\n    const topSideStyle = style.top;\n    const allSidesEqual = sides.every((side)=>style[side] === topSideStyle);\n    if (!allSidesEqual) {\n        return style;\n    }\n    return topSideStyle;\n}\n\n/**\n * A common method to update the numeric value. If a value is the default one, it will be unset.\n *\n * @param key An attribute key.\n * @param value The new attribute value.\n * @param item A model item on which the attribute will be set.\n * @param defaultValue The default attribute value. If a value is lower or equal, it will be unset.\n */ function updateNumericAttribute(key, value, item, writer, defaultValue = 1) {\n    if (value !== undefined && value !== null && defaultValue !== undefined && defaultValue !== null && value > defaultValue) {\n        writer.setAttribute(key, value, item);\n    } else {\n        writer.removeAttribute(key, item);\n    }\n}\n/**\n * A common method to create an empty table cell. It creates a proper model structure as a table cell must have at least one block inside.\n *\n * @param writer The model writer.\n * @param insertPosition The position at which the table cell should be inserted.\n * @param attributes The element attributes.\n * @returns Created table cell.\n */ function createEmptyTableCell(writer, insertPosition, attributes = {}) {\n    const tableCell = writer.createElement('tableCell', attributes);\n    writer.insertElement('paragraph', tableCell);\n    writer.insert(tableCell, insertPosition);\n    return tableCell;\n}\n/**\n * Checks if a table cell belongs to the heading column section.\n */ function isHeadingColumnCell(tableUtils, tableCell) {\n    const table = tableCell.parent.parent;\n    const headingColumns = parseInt(table.getAttribute('headingColumns') || '0');\n    const { column } = tableUtils.getCellLocation(tableCell);\n    return !!headingColumns && column < headingColumns;\n}\n/**\n * Enables conversion for an attribute for simple view-model mappings.\n *\n * @param options.defaultValue The default value for the specified `modelAttribute`.\n */ function enableProperty$1(schema, conversion, options) {\n    const { modelAttribute } = options;\n    schema.extend('tableCell', {\n        allowAttributes: [\n            modelAttribute\n        ]\n    });\n    upcastStyleToAttribute(conversion, {\n        viewElement: /^(td|th)$/,\n        ...options\n    });\n    downcastAttributeToStyle(conversion, {\n        modelElement: 'tableCell',\n        ...options\n    });\n}\n/**\n * Depending on the position of the selection we either return the table under cursor or look for the table higher in the hierarchy.\n */ function getSelectionAffectedTable(selection) {\n    const selectedElement = selection.getSelectedElement();\n    // Is the command triggered from the `tableToolbar`?\n    if (selectedElement && selectedElement.is('element', 'table')) {\n        return selectedElement;\n    }\n    return selection.getFirstPosition().findAncestor('table');\n}\n\n/**\n * Returns a function that converts the table view representation:\n *\n * ```xml\n * <figure class=\"table\"><table>...</table></figure>\n * ```\n *\n * to the model representation:\n *\n * ```xml\n * <table></table>\n * ```\n */ function upcastTableFigure() {\n    return (dispatcher)=>{\n        dispatcher.on('element:figure', (evt, data, conversionApi)=>{\n            // Do not convert if this is not a \"table figure\".\n            if (!conversionApi.consumable.test(data.viewItem, {\n                name: true,\n                classes: 'table'\n            })) {\n                return;\n            }\n            // Find a table element inside the figure element.\n            const viewTable = getViewTableFromFigure(data.viewItem);\n            // Do not convert if table element is absent or was already converted.\n            if (!viewTable || !conversionApi.consumable.test(viewTable, {\n                name: true\n            })) {\n                return;\n            }\n            // Consume the figure to prevent other converters from processing it again.\n            conversionApi.consumable.consume(data.viewItem, {\n                name: true,\n                classes: 'table'\n            });\n            // Convert view table to model table.\n            const conversionResult = conversionApi.convertItem(viewTable, data.modelCursor);\n            // Get table element from conversion result.\n            const modelTable = first(conversionResult.modelRange.getItems());\n            // When table wasn't successfully converted then finish conversion.\n            if (!modelTable) {\n                // Revert consumed figure so other features can convert it.\n                conversionApi.consumable.revert(data.viewItem, {\n                    name: true,\n                    classes: 'table'\n                });\n                return;\n            }\n            conversionApi.convertChildren(data.viewItem, conversionApi.writer.createPositionAt(modelTable, 'end'));\n            conversionApi.updateConversionResult(modelTable, data);\n        });\n    };\n}\n/**\n * View table element to model table element conversion helper.\n *\n * This conversion helper converts the table element as well as table rows.\n *\n * @returns Conversion helper.\n */ function upcastTable() {\n    return (dispatcher)=>{\n        dispatcher.on('element:table', (evt, data, conversionApi)=>{\n            const viewTable = data.viewItem;\n            // When element was already consumed then skip it.\n            if (!conversionApi.consumable.test(viewTable, {\n                name: true\n            })) {\n                return;\n            }\n            const { rows, headingRows, headingColumns } = scanTable(viewTable);\n            // Only set attributes if values is greater then 0.\n            const attributes = {};\n            if (headingColumns) {\n                attributes.headingColumns = headingColumns;\n            }\n            if (headingRows) {\n                attributes.headingRows = headingRows;\n            }\n            const table = conversionApi.writer.createElement('table', attributes);\n            if (!conversionApi.safeInsert(table, data.modelCursor)) {\n                return;\n            }\n            conversionApi.consumable.consume(viewTable, {\n                name: true\n            });\n            // Upcast table rows in proper order (heading rows first).\n            rows.forEach((row)=>conversionApi.convertItem(row, conversionApi.writer.createPositionAt(table, 'end')));\n            // Convert everything else.\n            conversionApi.convertChildren(viewTable, conversionApi.writer.createPositionAt(table, 'end'));\n            // Create one row and one table cell for empty table.\n            if (table.isEmpty) {\n                const row = conversionApi.writer.createElement('tableRow');\n                conversionApi.writer.insert(row, conversionApi.writer.createPositionAt(table, 'end'));\n                createEmptyTableCell(conversionApi.writer, conversionApi.writer.createPositionAt(row, 'end'));\n            }\n            conversionApi.updateConversionResult(table, data);\n        });\n    };\n}\n/**\n * A conversion helper that skips empty <tr> elements from upcasting at the beginning of the table.\n *\n * An empty row is considered a table model error but when handling clipboard data there could be rows that contain only row-spanned cells\n * and empty TR-s are used to maintain the table structure (also {@link module:table/tablewalker~TableWalker} assumes that there are only\n * rows that have related `tableRow` elements).\n *\n * *Note:* Only the first empty rows are removed because they have no meaning and it solves the issue\n * of an improper table with all empty rows.\n *\n * @returns Conversion helper.\n */ function skipEmptyTableRow() {\n    return (dispatcher)=>{\n        dispatcher.on('element:tr', (evt, data)=>{\n            if (data.viewItem.isEmpty && data.modelCursor.index == 0) {\n                evt.stop();\n            }\n        }, {\n            priority: 'high'\n        });\n    };\n}\n/**\n * A converter that ensures an empty paragraph is inserted in a table cell if no other content was converted.\n *\n * @returns Conversion helper.\n */ function ensureParagraphInTableCell(elementName) {\n    return (dispatcher)=>{\n        dispatcher.on(`element:${elementName}`, (evt, data, { writer })=>{\n            // The default converter will create a model range on converted table cell.\n            if (!data.modelRange) {\n                return;\n            }\n            const tableCell = data.modelRange.start.nodeAfter;\n            const modelCursor = writer.createPositionAt(tableCell, 0);\n            // Ensure a paragraph in the model for empty table cells for converted table cells.\n            if (data.viewItem.isEmpty) {\n                writer.insertElement('paragraph', modelCursor);\n                return;\n            }\n            const childNodes = Array.from(tableCell.getChildren());\n            // In case there are only markers inside the table cell then move them to the paragraph.\n            if (childNodes.every((node)=>node.is('element', '$marker'))) {\n                const paragraph = writer.createElement('paragraph');\n                writer.insert(paragraph, writer.createPositionAt(tableCell, 0));\n                for (const node of childNodes){\n                    writer.move(writer.createRangeOn(node), writer.createPositionAt(paragraph, 'end'));\n                }\n            }\n        }, {\n            priority: 'low'\n        });\n    };\n}\n/**\n * Get view `<table>` element from the view widget (`<figure>`).\n */ function getViewTableFromFigure(figureView) {\n    for (const figureChild of figureView.getChildren()){\n        if (figureChild.is('element', 'table')) {\n            return figureChild;\n        }\n    }\n}\n/**\n * Scans table rows and extracts required metadata from the table:\n *\n * headingRows    - The number of rows that go as table headers.\n * headingColumns - The maximum number of row headings.\n * rows           - Sorted `<tr>` elements as they should go into the model - ie. if `<thead>` is inserted after `<tbody>` in the view.\n */ function scanTable(viewTable) {\n    let headingRows = 0;\n    let headingColumns = undefined;\n    // The `<tbody>` and `<thead>` sections in the DOM do not have to be in order `<thead>` -> `<tbody>` and there might be more than one\n    // of them.\n    // As the model does not have these sections, rows from different sections must be sorted.\n    // For example, below is a valid HTML table:\n    //\n    // <table>\n    //   <tbody><tr><td>2</td></tr></tbody>\n    //   <thead><tr><td>1</td></tr></thead>\n    //   <tbody><tr><td>3</td></tr></tbody>\n    // </table>\n    //\n    // But browsers will render rows in order as: 1 as the heading and 2 and 3 as the body.\n    const headRows = [];\n    const bodyRows = [];\n    // Currently the editor does not support more then one <thead> section.\n    // Only the first <thead> from the view will be used as a heading row and the others will be converted to body rows.\n    let firstTheadElement;\n    for (const tableChild of Array.from(viewTable.getChildren())){\n        // Only `<thead>`, `<tbody>` & `<tfoot>` from allowed table children can have `<tr>`s.\n        // The else is for future purposes (mainly `<caption>`).\n        if (tableChild.name !== 'tbody' && tableChild.name !== 'thead' && tableChild.name !== 'tfoot') {\n            continue;\n        }\n        // Save the first `<thead>` in the table as table header - all other ones will be converted to table body rows.\n        if (tableChild.name === 'thead' && !firstTheadElement) {\n            firstTheadElement = tableChild;\n        }\n        // There might be some extra empty text nodes between the `<tr>`s.\n        // Make sure further code operates on `tr`s only. (#145)\n        const trs = Array.from(tableChild.getChildren()).filter((el)=>el.is('element', 'tr'));\n        for (const tr of trs){\n            // This <tr> is a child of a first <thead> element.\n            if (firstTheadElement && tableChild === firstTheadElement || tableChild.name === 'tbody' && Array.from(tr.getChildren()).length && Array.from(tr.getChildren()).every((e)=>e.is('element', 'th'))) {\n                headingRows++;\n                headRows.push(tr);\n            } else {\n                bodyRows.push(tr);\n                // For other rows check how many column headings this row has.\n                const headingCols = scanRowForHeadingColumns(tr);\n                if (!headingColumns || headingCols < headingColumns) {\n                    headingColumns = headingCols;\n                }\n            }\n        }\n    }\n    return {\n        headingRows,\n        headingColumns: headingColumns || 0,\n        rows: [\n            ...headRows,\n            ...bodyRows\n        ]\n    };\n}\n/**\n * Scans a `<tr>` element and its children for metadata:\n * - For heading row:\n *     - Adds this row to either the heading or the body rows.\n *     - Updates the number of heading rows.\n * - For body rows:\n *     - Calculates the number of column headings.\n */ function scanRowForHeadingColumns(tr) {\n    let headingColumns = 0;\n    let index = 0;\n    // Filter out empty text nodes from tr children.\n    const children = Array.from(tr.getChildren()).filter((child)=>child.name === 'th' || child.name === 'td');\n    // Count starting adjacent <th> elements of a <tr>.\n    while(index < children.length && children[index].name === 'th'){\n        const th = children[index];\n        // Adjust columns calculation by the number of spanned columns.\n        const colspan = parseInt(th.getAttribute('colspan') || '1');\n        headingColumns = headingColumns + colspan;\n        index++;\n    }\n    return headingColumns;\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module table/tablewalker\n */ /**\n * The table iterator class. It allows to iterate over table cells. For each cell the iterator yields\n * {@link module:table/tablewalker~TableSlot} with proper table cell attributes.\n */ class TableWalker {\n    /**\n\t * The walker's table element.\n\t *\n\t * @internal\n\t */ _table;\n    /**\n\t * A row index from which this iterator will start.\n\t */ _startRow;\n    /**\n\t * A row index at which this iterator will end.\n\t */ _endRow;\n    /**\n\t * If set, the table walker will only output cells from a given column and following ones or cells that overlap them.\n\t */ _startColumn;\n    /**\n\t * If set, the table walker will only output cells up to a given column.\n\t */ _endColumn;\n    /**\n\t * Enables output of spanned cells that are normally not yielded.\n\t */ _includeAllSlots;\n    /**\n\t * Row indexes to skip from the iteration.\n\t */ _skipRows;\n    /**\n\t * The current row index.\n\t *\n\t * @internal\n\t */ _row;\n    /**\n\t * The index of the current row element in the table.\n\t *\n\t * @internal\n\t */ _rowIndex;\n    /**\n\t * The current column index.\n\t *\n\t * @internal\n\t */ _column;\n    /**\n\t * The cell index in a parent row. For spanned cells when {@link #_includeAllSlots} is set to `true`,\n\t * this represents the index of the next table cell.\n\t *\n\t * @internal\n\t */ _cellIndex;\n    /**\n\t * Holds a map of spanned cells in a table.\n\t */ _spannedCells;\n    /**\n\t * Index of the next column where a cell is anchored.\n\t */ _nextCellAtColumn;\n    /**\n\t * Indicates whether the iterator jumped to (or close to) the start row, ignoring rows that don't need to be traversed.\n\t */ _jumpedToStartRow = false;\n    /**\n\t * Creates an instance of the table walker.\n\t *\n\t * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.\n\t * It walks row by row and column by column in order to output values defined in the constructor.\n\t * By default it will output only the locations that are occupied by a cell. To include also spanned rows and columns,\n\t * pass the `includeAllSlots` option to the constructor.\n\t *\n\t * The most important values of the iterator are column and row indexes of a cell.\n\t *\n\t * See {@link module:table/tablewalker~TableSlot} what values are returned by the table walker.\n\t *\n\t * To iterate over a given row:\n\t *\n\t * ```ts\n\t * const tableWalker = new TableWalker( table, { startRow: 1, endRow: 2 } );\n\t *\n\t * for ( const tableSlot of tableWalker ) {\n\t *   console.log( 'A cell at row', tableSlot.row, 'and column', tableSlot.column );\n\t * }\n\t * ```\n\t *\n\t * For instance the code above for the following table:\n\t *\n\t *  +----+----+----+----+----+----+\n\t *  | 00      | 02 | 03 | 04 | 05 |\n\t *  |         +----+----+----+----+\n\t *  |         | 12      | 14 | 15 |\n\t *  |         +----+----+----+    +\n\t *  |         | 22           |    |\n\t *  |----+----+----+----+----+    +\n\t *  | 30 | 31 | 32 | 33 | 34 |    |\n\t *  +----+----+----+----+----+----+\n\t *\n\t * will log in the console:\n\t *\n\t *  'A cell at row 1 and column 2'\n\t *  'A cell at row 1 and column 4'\n\t *  'A cell at row 1 and column 5'\n\t *  'A cell at row 2 and column 2'\n\t *\n\t * To also iterate over spanned cells:\n\t *\n\t * ```ts\n\t * const tableWalker = new TableWalker( table, { row: 1, includeAllSlots: true } );\n\t *\n\t * for ( const tableSlot of tableWalker ) {\n\t *   console.log( 'Slot at', tableSlot.row, 'x', tableSlot.column, ':', tableSlot.isAnchor ? 'is anchored' : 'is spanned' );\n\t * }\n\t * ```\n\t *\n\t * will log in the console for the table from the previous example:\n\t *\n\t *  'Cell at 1 x 0 : is spanned'\n\t *  'Cell at 1 x 1 : is spanned'\n\t *  'Cell at 1 x 2 : is anchored'\n\t *  'Cell at 1 x 3 : is spanned'\n\t *  'Cell at 1 x 4 : is anchored'\n\t *  'Cell at 1 x 5 : is anchored'\n\t *\n\t * **Note**: Option `row` is a shortcut that sets both `startRow` and `endRow` to the same row.\n\t * (Use either `row` or `startRow` and `endRow` but never together). Similarly the `column` option sets both `startColumn`\n\t * and `endColumn` to the same column (Use either `column` or `startColumn` and `endColumn` but never together).\n\t *\n\t * @param table A table over which the walker iterates.\n\t * @param options An object with configuration.\n\t * @param options.row A row index for which this iterator will output cells. Can't be used together with `startRow` and `endRow`.\n\t * @param options.startRow A row index from which this iterator should start. Can't be used together with `row`. Default value is 0.\n\t * @param options.endRow A row index at which this iterator should end. Can't be used together with `row`.\n\t * @param options.column A column index for which this iterator will output cells.\n\t * Can't be used together with `startColumn` and `endColumn`.\n\t * @param options.startColumn A column index from which this iterator should start.\n\t * Can't be used together with `column`. Default value is 0.\n\t * @param options.endColumn A column index at which this iterator should end. Can't be used together with `column`.\n\t * @param options.includeAllSlots Also return values for spanned cells. Default value is \"false\".\n\t */ constructor(table, options = {}){\n        this._table = table;\n        this._startRow = options.row !== undefined ? options.row : options.startRow || 0;\n        this._endRow = options.row !== undefined ? options.row : options.endRow;\n        this._startColumn = options.column !== undefined ? options.column : options.startColumn || 0;\n        this._endColumn = options.column !== undefined ? options.column : options.endColumn;\n        this._includeAllSlots = !!options.includeAllSlots;\n        this._skipRows = new Set();\n        this._row = 0;\n        this._rowIndex = 0;\n        this._column = 0;\n        this._cellIndex = 0;\n        this._spannedCells = new Map();\n        this._nextCellAtColumn = -1;\n    }\n    /**\n\t * Iterable interface.\n\t */ [Symbol.iterator]() {\n        return this;\n    }\n    /**\n\t * Gets the next table walker's value.\n\t *\n\t * @returns The next table walker's value.\n\t */ next() {\n        if (this._canJumpToStartRow()) {\n            this._jumpToNonSpannedRowClosestToStartRow();\n        }\n        const row = this._table.getChild(this._rowIndex);\n        // Iterator is done when there's no row (table ended) or the row is after `endRow` limit.\n        if (!row || this._isOverEndRow()) {\n            return {\n                done: true,\n                value: undefined\n            };\n        }\n        // We step over current element when it is not a tableRow instance.\n        if (!row.is('element', 'tableRow')) {\n            this._rowIndex++;\n            return this.next();\n        }\n        if (this._isOverEndColumn()) {\n            return this._advanceToNextRow();\n        }\n        let outValue = null;\n        const spanData = this._getSpanned();\n        if (spanData) {\n            if (this._includeAllSlots && !this._shouldSkipSlot()) {\n                outValue = this._formatOutValue(spanData.cell, spanData.row, spanData.column);\n            }\n        } else {\n            const cell = row.getChild(this._cellIndex);\n            if (!cell) {\n                // If there are no more cells left in row advance to the next row.\n                return this._advanceToNextRow();\n            }\n            const colspan = parseInt(cell.getAttribute('colspan') || '1');\n            const rowspan = parseInt(cell.getAttribute('rowspan') || '1');\n            // Record this cell spans if it's not 1x1 cell.\n            if (colspan > 1 || rowspan > 1) {\n                this._recordSpans(cell, rowspan, colspan);\n            }\n            if (!this._shouldSkipSlot()) {\n                outValue = this._formatOutValue(cell);\n            }\n            this._nextCellAtColumn = this._column + colspan;\n        }\n        // Advance to the next column before returning value.\n        this._column++;\n        if (this._column == this._nextCellAtColumn) {\n            this._cellIndex++;\n        }\n        // The current value will be returned only if current row and column are not skipped.\n        return outValue || this.next();\n    }\n    /**\n\t * Marks a row to skip in the next iteration. It will also skip cells from the current row if there are any cells from the current row\n\t * to output.\n\t *\n\t * @param row The row index to skip.\n\t */ skipRow(row) {\n        this._skipRows.add(row);\n    }\n    /**\n\t * Advances internal cursor to the next row.\n\t */ _advanceToNextRow() {\n        this._row++;\n        this._rowIndex++;\n        this._column = 0;\n        this._cellIndex = 0;\n        this._nextCellAtColumn = -1;\n        return this.next();\n    }\n    /**\n\t * Checks if the current row is over {@link #_endRow}.\n\t */ _isOverEndRow() {\n        // If #_endRow is defined skip all rows after it.\n        return this._endRow !== undefined && this._row > this._endRow;\n    }\n    /**\n\t * Checks if the current cell is over {@link #_endColumn}\n\t */ _isOverEndColumn() {\n        // If #_endColumn is defined skip all cells after it.\n        return this._endColumn !== undefined && this._column > this._endColumn;\n    }\n    /**\n\t * A common method for formatting the iterator's output value.\n\t *\n\t * @param cell The table cell to output.\n\t * @param anchorRow The row index of a cell anchor slot.\n\t * @param anchorColumn The column index of a cell anchor slot.\n\t */ _formatOutValue(cell, anchorRow = this._row, anchorColumn = this._column) {\n        return {\n            done: false,\n            value: new TableSlot(this, cell, anchorRow, anchorColumn)\n        };\n    }\n    /**\n\t * Checks if the current slot should be skipped.\n\t */ _shouldSkipSlot() {\n        const rowIsMarkedAsSkipped = this._skipRows.has(this._row);\n        const rowIsBeforeStartRow = this._row < this._startRow;\n        const columnIsBeforeStartColumn = this._column < this._startColumn;\n        const columnIsAfterEndColumn = this._endColumn !== undefined && this._column > this._endColumn;\n        return rowIsMarkedAsSkipped || rowIsBeforeStartRow || columnIsBeforeStartColumn || columnIsAfterEndColumn;\n    }\n    /**\n\t * Returns the cell element that is spanned over the current cell location.\n\t */ _getSpanned() {\n        const rowMap = this._spannedCells.get(this._row);\n        // No spans for given row.\n        if (!rowMap) {\n            return null;\n        }\n        // If spans for given rows has entry for column it means that this location if spanned by other cell.\n        return rowMap.get(this._column) || null;\n    }\n    /**\n\t * Updates spanned cells map relative to the current cell location and its span dimensions.\n\t *\n\t * @param cell A cell that is spanned.\n\t * @param rowspan Cell height.\n\t * @param colspan Cell width.\n\t */ _recordSpans(cell, rowspan, colspan) {\n        const data = {\n            cell,\n            row: this._row,\n            column: this._column\n        };\n        for(let rowToUpdate = this._row; rowToUpdate < this._row + rowspan; rowToUpdate++){\n            for(let columnToUpdate = this._column; columnToUpdate < this._column + colspan; columnToUpdate++){\n                if (rowToUpdate != this._row || columnToUpdate != this._column) {\n                    this._markSpannedCell(rowToUpdate, columnToUpdate, data);\n                }\n            }\n        }\n    }\n    /**\n\t * Marks the cell location as spanned by another cell.\n\t *\n\t * @param row The row index of the cell location.\n\t * @param column The column index of the cell location.\n\t * @param data A spanned cell details (cell element, anchor row and column).\n\t */ _markSpannedCell(row, column, data) {\n        if (!this._spannedCells.has(row)) {\n            this._spannedCells.set(row, new Map());\n        }\n        const rowSpans = this._spannedCells.get(row);\n        rowSpans.set(column, data);\n    }\n    /**\n\t * Checks if part of the table can be skipped.\n\t */ _canJumpToStartRow() {\n        return !!this._startRow && this._startRow > 0 && !this._jumpedToStartRow;\n    }\n    /**\n\t * Sets the current row to `this._startRow` or the first row before it that has the number of cells\n\t * equal to the number of columns in the table.\n\t *\n\t * Example:\n\t * \t+----+----+----+\n\t *  | 00 | 01 | 02 |\n\t *  |----+----+----+\n\t *  | 10      | 12 |\n\t *  |         +----+\n\t *  |         | 22 |\n\t *  |         +----+\n\t *  |         | 32 | <--- Start row\n\t *  +----+----+----+\n\t *  | 40 | 41 | 42 |\n\t *  +----+----+----+\n\t *\n\t * If the 4th row is a `this._startRow`, this method will:\n\t * 1.) Count the number of columns this table has based on the first row (3 columns in this case).\n\t * 2.) Check if the 4th row contains 3 cells. It doesn't, so go to the row before it.\n\t * 3.) Check if the 3rd row contains 3 cells. It doesn't, so go to the row before it.\n\t * 4.) Check if the 2nd row contains 3 cells. It does, so set the current row to that row.\n\t *\n\t * Setting the current row this way is necessary to let the `next()`  method loop over the cells\n\t * spanning multiple rows or columns and update the `this._spannedCells` property.\n\t */ _jumpToNonSpannedRowClosestToStartRow() {\n        const firstRowLength = this._getRowLength(0);\n        for(let i = this._startRow; !this._jumpedToStartRow; i--){\n            if (firstRowLength === this._getRowLength(i)) {\n                this._row = i;\n                this._rowIndex = i;\n                this._jumpedToStartRow = true;\n            }\n        }\n    }\n    /**\n\t * Returns a number of columns in a row taking `colspan` into consideration.\n\t */ _getRowLength(rowIndex) {\n        const row = this._table.getChild(rowIndex);\n        return [\n            ...row.getChildren()\n        ].reduce((cols, row)=>{\n            return cols + parseInt(row.getAttribute('colspan') || '1');\n        }, 0);\n    }\n}\n/**\n * An object returned by {@link module:table/tablewalker~TableWalker} when traversing table cells.\n */ class TableSlot {\n    /**\n\t * The current table cell.\n\t */ cell;\n    /**\n\t * The row index of a table slot.\n\t */ row;\n    /**\n\t * The column index of a table slot.\n\t */ column;\n    /**\n\t * The row index of a cell anchor slot.\n\t */ cellAnchorRow;\n    /**\n\t * The column index of a cell anchor slot.\n\t */ cellAnchorColumn;\n    /**\n\t * The index of the current cell in the parent row.\n\t */ _cellIndex;\n    /**\n\t * The index of the current row element in the table.\n\t */ _rowIndex;\n    /**\n\t * The table element.\n\t */ _table;\n    /**\n\t * Creates an instance of the table walker value.\n\t *\n\t * @param tableWalker The table walker instance.\n\t * @param cell The current table cell.\n\t * @param anchorRow The row index of a cell anchor slot.\n\t * @param anchorColumn The column index of a cell anchor slot.\n\t */ constructor(tableWalker, cell, anchorRow, anchorColumn){\n        this.cell = cell;\n        this.row = tableWalker._row;\n        this.column = tableWalker._column;\n        this.cellAnchorRow = anchorRow;\n        this.cellAnchorColumn = anchorColumn;\n        this._cellIndex = tableWalker._cellIndex;\n        this._rowIndex = tableWalker._rowIndex;\n        this._table = tableWalker._table;\n    }\n    // @if CK_DEBUG // public get isSpanned(): unknown { return throwMissingGetterError( 'isSpanned' ); }\n    // @if CK_DEBUG // public get colspan(): unknown { return throwMissingGetterError( 'colspan' ); }\n    // @if CK_DEBUG // public get rowspan(): unknown { return throwMissingGetterError( 'rowspan' ); }\n    // @if CK_DEBUG // public get cellIndex(): unknown { return throwMissingGetterError( 'cellIndex' ); }\n    /**\n\t * Whether the cell is anchored in the current slot.\n\t */ get isAnchor() {\n        return this.row === this.cellAnchorRow && this.column === this.cellAnchorColumn;\n    }\n    /**\n\t * The width of a cell defined by a `colspan` attribute. If the model attribute is not present, it is set to `1`.\n\t */ get cellWidth() {\n        return parseInt(this.cell.getAttribute('colspan') || '1');\n    }\n    /**\n\t * The height of a cell defined by a `rowspan` attribute. If the model attribute is not present, it is set to `1`.\n\t */ get cellHeight() {\n        return parseInt(this.cell.getAttribute('rowspan') || '1');\n    }\n    /**\n\t * The index of the current row element in the table.\n\t */ get rowIndex() {\n        return this._rowIndex;\n    }\n    /**\n\t * Returns the {@link module:engine/model/position~Position} before the table slot.\n\t */ getPositionBefore() {\n        const model = this._table.root.document.model;\n        return model.createPositionAt(this._table.getChild(this.row), this._cellIndex);\n    }\n}\n /**\n * This `TableSlot`'s getter (property) was removed in CKEditor 5 v20.0.0.\n *\n * Check out the new `TableWalker`'s API in the documentation.\n *\n * @error tableslot-getter-removed\n * @param getterName\n */  // @if CK_DEBUG // function throwMissingGetterError( getterName: string ): void {\n // @if CK_DEBUG //\t\tthrow new CKEditorError( 'tableslot-getter-removed', null, {\n // @if CK_DEBUG //\t\t\tgetterName\n // @if CK_DEBUG //\t\t} );\n // @if CK_DEBUG // }\n\n/**\n * Model table element to view table element conversion helper.\n */ function downcastTable(tableUtils, options) {\n    return (table, { writer })=>{\n        const headingRows = table.getAttribute('headingRows') || 0;\n        const tableElement = writer.createContainerElement('table', null, []);\n        const figureElement = writer.createContainerElement('figure', {\n            class: 'table'\n        }, tableElement);\n        // Table head slot.\n        if (headingRows > 0) {\n            writer.insert(writer.createPositionAt(tableElement, 'end'), writer.createContainerElement('thead', null, writer.createSlot((element)=>element.is('element', 'tableRow') && element.index < headingRows)));\n        }\n        // Table body slot.\n        if (headingRows < tableUtils.getRows(table)) {\n            writer.insert(writer.createPositionAt(tableElement, 'end'), writer.createContainerElement('tbody', null, writer.createSlot((element)=>element.is('element', 'tableRow') && element.index >= headingRows)));\n        }\n        // Dynamic slots.\n        for (const { positionOffset, filter } of options.additionalSlots){\n            writer.insert(writer.createPositionAt(tableElement, positionOffset), writer.createSlot(filter));\n        }\n        // Create a slot with items that don't fit into the table.\n        writer.insert(writer.createPositionAt(tableElement, 'after'), writer.createSlot((element)=>{\n            if (element.is('element', 'tableRow')) {\n                return false;\n            }\n            return !options.additionalSlots.some(({ filter })=>filter(element));\n        }));\n        return options.asWidget ? toTableWidget(figureElement, writer) : figureElement;\n    };\n}\n/**\n * Model table row element to view `<tr>` element conversion helper.\n *\n * @returns Element creator.\n */ function downcastRow() {\n    return (tableRow, { writer })=>{\n        return tableRow.isEmpty ? writer.createEmptyElement('tr') : writer.createContainerElement('tr');\n    };\n}\n/**\n * Model table cell element to view `<td>` or `<th>` element conversion helper.\n *\n * This conversion helper will create proper `<th>` elements for table cells that are in the heading section (heading row or column)\n * and `<td>` otherwise.\n *\n * @param options.asWidget If set to `true`, the downcast conversion will produce a widget.\n * @returns Element creator.\n */ function downcastCell(options = {}) {\n    return (tableCell, { writer })=>{\n        const tableRow = tableCell.parent;\n        const table = tableRow.parent;\n        const rowIndex = table.getChildIndex(tableRow);\n        const tableWalker = new TableWalker(table, {\n            row: rowIndex\n        });\n        const headingRows = table.getAttribute('headingRows') || 0;\n        const headingColumns = table.getAttribute('headingColumns') || 0;\n        let result = null;\n        // We need to iterate over a table in order to get proper row & column values from a walker.\n        for (const tableSlot of tableWalker){\n            if (tableSlot.cell == tableCell) {\n                const isHeading = tableSlot.row < headingRows || tableSlot.column < headingColumns;\n                const cellElementName = isHeading ? 'th' : 'td';\n                result = options.asWidget ? toWidgetEditable(writer.createEditableElement(cellElementName), writer) : writer.createContainerElement(cellElementName);\n                break;\n            }\n        }\n        return result;\n    };\n}\n/**\n * Overrides paragraph inside table cell conversion.\n *\n * This converter:\n * * should be used to override default paragraph conversion.\n * * It will only convert `<paragraph>` placed directly inside `<tableCell>`.\n * * For a single paragraph without attributes it returns `<span>` to simulate data table.\n * * For all other cases it returns `<p>` element.\n *\n * @param options.asWidget If set to `true`, the downcast conversion will produce a widget.\n * @returns Element creator.\n */ function convertParagraphInTableCell(options = {}) {\n    return (modelElement, { writer })=>{\n        if (!modelElement.parent.is('element', 'tableCell')) {\n            return null;\n        }\n        if (!isSingleParagraphWithoutAttributes(modelElement)) {\n            return null;\n        }\n        if (options.asWidget) {\n            return writer.createContainerElement('span', {\n                class: 'ck-table-bogus-paragraph'\n            });\n        } else {\n            // Using `<p>` in case there are some markers on it and transparentRendering will render it anyway.\n            const viewElement = writer.createContainerElement('p');\n            writer.setCustomProperty('dataPipeline:transparentRendering', true, viewElement);\n            return viewElement;\n        }\n    };\n}\n/**\n * Checks if given model `<paragraph>` is an only child of a parent (`<tableCell>`) and if it has any attribute set.\n *\n * The paragraph should be converted in the editing view to:\n *\n * * If returned `true` - to a `<span class=\"ck-table-bogus-paragraph\">`\n * * If returned `false` - to a `<p>`\n */ function isSingleParagraphWithoutAttributes(modelElement) {\n    const tableCell = modelElement.parent;\n    const isSingleParagraph = tableCell.childCount == 1;\n    return isSingleParagraph && !hasAnyAttribute(modelElement);\n}\n/**\n * Converts a given {@link module:engine/view/element~Element} to a table widget:\n * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the table widget element.\n * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n *\n * @param writer An instance of the view writer.\n * @param label The element's label. It will be concatenated with the table `alt` attribute if one is present.\n */ function toTableWidget(viewElement, writer) {\n    writer.setCustomProperty('table', true, viewElement);\n    return toWidget(viewElement, writer, {\n        hasSelectionHandle: true\n    });\n}\n/**\n * Checks if an element has any attributes set.\n */ function hasAnyAttribute(element) {\n    const iteratorItem = element.getAttributeKeys().next();\n    return !iteratorItem.done;\n}\n\n/**\n * The insert table command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTable'` editor command.\n *\n * To insert a table at the current selection, execute the command and specify the dimensions:\n *\n * ```ts\n * editor.execute( 'insertTable', { rows: 20, columns: 5 } );\n * ```\n */ class InsertTableCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const schema = model.schema;\n        this.isEnabled = isAllowedInParent(selection, schema);\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * Inserts a table with the given number of rows and columns into the editor.\n\t *\n\t * @param options.rows The number of rows to create in the inserted table. Default value is 2.\n\t * @param options.columns The number of columns to create in the inserted table. Default value is 2.\n\t * @param options.headingRows The number of heading rows. If not provided it will default to\n\t * {@link module:table/tableconfig~TableConfig#defaultHeadings `config.table.defaultHeadings.rows`} table config.\n\t * @param options.headingColumns The number of heading columns. If not provided it will default to\n\t * {@link module:table/tableconfig~TableConfig#defaultHeadings `config.table.defaultHeadings.columns`} table config.\n\t * @fires execute\n\t */ execute(options = {}) {\n        const editor = this.editor;\n        const model = editor.model;\n        const tableUtils = editor.plugins.get('TableUtils');\n        const defaultRows = editor.config.get('table.defaultHeadings.rows');\n        const defaultColumns = editor.config.get('table.defaultHeadings.columns');\n        if (options.headingRows === undefined && defaultRows) {\n            options.headingRows = defaultRows;\n        }\n        if (options.headingColumns === undefined && defaultColumns) {\n            options.headingColumns = defaultColumns;\n        }\n        model.change((writer)=>{\n            const table = tableUtils.createTable(writer, options);\n            model.insertObject(table, null, null, {\n                findOptimalPosition: 'auto'\n            });\n            writer.setSelection(writer.createPositionAt(table.getNodeByPath([\n                0,\n                0,\n                0\n            ]), 0));\n        });\n    }\n}\n/**\n * Checks if the table is allowed in the parent.\n */ function isAllowedInParent(selection, schema) {\n    const positionParent = selection.getFirstPosition().parent;\n    const validParent = positionParent === positionParent.root ? positionParent : positionParent.parent;\n    return schema.checkChild(validParent, 'table');\n}\n\n/**\n * The insert row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTableRowBelow'` and\n * `'insertTableRowAbove'` editor commands.\n *\n * To insert a row below the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableRowBelow' );\n * ```\n *\n * To insert a row above the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableRowAbove' );\n * ```\n */ class InsertRowCommand extends Command {\n    /**\n\t * The order of insertion relative to the row in which the caret is located.\n\t */ order;\n    /**\n\t * Creates a new `InsertRowCommand` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t * @param options.order The order of insertion relative to the row in which the caret is located.\n\t * Possible values: `\"above\"` and `\"below\"`. Default value is \"below\"\n\t */ constructor(editor, options = {}){\n        super(editor);\n        this.order = options.order || 'below';\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const selection = this.editor.model.document.selection;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const isAnyCellSelected = !!tableUtils.getSelectionAffectedTableCells(selection).length;\n        this.isEnabled = isAnyCellSelected;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a row `'below'` or `'above'` the row in which selection is set.\n\t *\n\t * @fires execute\n\t */ execute() {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const tableUtils = editor.plugins.get('TableUtils');\n        const insertAbove = this.order === 'above';\n        const affectedTableCells = tableUtils.getSelectionAffectedTableCells(selection);\n        const rowIndexes = tableUtils.getRowIndexes(affectedTableCells);\n        const row = insertAbove ? rowIndexes.first : rowIndexes.last;\n        const table = affectedTableCells[0].findAncestor('table');\n        tableUtils.insertRows(table, {\n            at: insertAbove ? row : row + 1,\n            copyStructureFromAbove: !insertAbove\n        });\n    }\n}\n\n/**\n * The insert column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTableColumnLeft'` and\n * `'insertTableColumnRight'` editor commands.\n *\n * To insert a column to the left of the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableColumnLeft' );\n * ```\n *\n * To insert a column to the right of the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableColumnRight' );\n * ```\n */ class InsertColumnCommand extends Command {\n    /**\n\t * The order of insertion relative to the column in which the caret is located.\n\t */ order;\n    /**\n\t * Creates a new `InsertColumnCommand` instance.\n\t *\n\t * @param editor An editor on which this command will be used.\n\t * @param options.order The order of insertion relative to the column in which the caret is located.\n\t * Possible values: `\"left\"` and `\"right\"`. Default value is \"right\".\n\t */ constructor(editor, options = {}){\n        super(editor);\n        this.order = options.order || 'right';\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const selection = this.editor.model.document.selection;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const isAnyCellSelected = !!tableUtils.getSelectionAffectedTableCells(selection).length;\n        this.isEnabled = isAnyCellSelected;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a column to the `'left'` or `'right'` of the column\n\t * in which the selection is set.\n\t *\n\t * @fires execute\n\t */ execute() {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const tableUtils = editor.plugins.get('TableUtils');\n        const insertBefore = this.order === 'left';\n        const affectedTableCells = tableUtils.getSelectionAffectedTableCells(selection);\n        const columnIndexes = tableUtils.getColumnIndexes(affectedTableCells);\n        const column = insertBefore ? columnIndexes.first : columnIndexes.last;\n        const table = affectedTableCells[0].findAncestor('table');\n        tableUtils.insertColumns(table, {\n            columns: 1,\n            at: insertBefore ? column : column + 1\n        });\n    }\n}\n\n/**\n * The split cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'splitTableCellVertically'`\n * and `'splitTableCellHorizontally'`  editor commands.\n *\n * You can split any cell vertically or horizontally by executing this command. For example, to split the selected table cell vertically:\n *\n * ```ts\n * editor.execute( 'splitTableCellVertically' );\n * ```\n */ class SplitCellCommand extends Command {\n    /**\n\t * The direction that indicates which cell will be split.\n\t */ direction;\n    /**\n\t * Creates a new `SplitCellCommand` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t * @param options.direction Indicates whether the command should split cells `'horizontally'` or `'vertically'`.\n\t */ constructor(editor, options = {}){\n        super(editor);\n        this.direction = options.direction || 'horizontally';\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection);\n        this.isEnabled = selectedCells.length === 1;\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const tableCell = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection)[0];\n        const isHorizontal = this.direction === 'horizontally';\n        if (isHorizontal) {\n            tableUtils.splitCellHorizontally(tableCell, 2);\n        } else {\n            tableUtils.splitCellVertically(tableCell, 2);\n        }\n    }\n}\n\n/**\n * Returns a cropped table according to given dimensions.\n\n * To return a cropped table that starts at first row and first column and end in third row and column:\n *\n * ```ts\n * const croppedTable = cropTableToDimensions( table, {\n *   startRow: 1,\n *   endRow: 3,\n *   startColumn: 1,\n *   endColumn: 3\n * }, writer );\n * ```\n *\n * Calling the code above for the table below:\n *\n *        0   1   2   3   4                      0   1   2\n *      ┌───┬───┬───┬───┬───┐\n *   0  │ a │ b │ c │ d │ e │\n *      ├───┴───┤   ├───┴───┤                  ┌───┬───┬───┐\n *   1  │ f     │   │ g     │                  │   │   │ g │  0\n *      ├───┬───┴───┼───┬───┤   will return:   ├───┴───┼───┤\n *   2  │ h │ i     │ j │ k │                  │ i     │ j │  1\n *      ├───┤       ├───┤   │                  │       ├───┤\n *   3  │ l │       │ m │   │                  │       │ m │  2\n *      ├───┼───┬───┤   ├───┤                  └───────┴───┘\n *   4  │ n │ o │ p │   │ q │\n *      └───┴───┴───┴───┴───┘\n */ function cropTableToDimensions(sourceTable, cropDimensions, writer) {\n    const { startRow, startColumn, endRow, endColumn } = cropDimensions;\n    // Create empty table with empty rows equal to crop height.\n    const croppedTable = writer.createElement('table');\n    const cropHeight = endRow - startRow + 1;\n    for(let i = 0; i < cropHeight; i++){\n        writer.insertElement('tableRow', croppedTable, 'end');\n    }\n    const tableMap = [\n        ...new TableWalker(sourceTable, {\n            startRow,\n            endRow,\n            startColumn,\n            endColumn,\n            includeAllSlots: true\n        })\n    ];\n    // Iterate over source table slots (including empty - spanned - ones).\n    for (const { row: sourceRow, column: sourceColumn, cell: tableCell, isAnchor, cellAnchorRow, cellAnchorColumn } of tableMap){\n        // Row index in cropped table.\n        const rowInCroppedTable = sourceRow - startRow;\n        const row = croppedTable.getChild(rowInCroppedTable);\n        // For empty slots: fill the gap with empty table cell.\n        if (!isAnchor) {\n            // But fill the gap only if the spanning cell is anchored outside cropped area.\n            // In the table from method jsdoc those cells are: \"c\" & \"f\".\n            if (cellAnchorRow < startRow || cellAnchorColumn < startColumn) {\n                createEmptyTableCell(writer, writer.createPositionAt(row, 'end'));\n            }\n        } else {\n            const tableCellCopy = writer.cloneElement(tableCell);\n            writer.append(tableCellCopy, row);\n            // Trim table if it exceeds cropped area.\n            // In the table from method jsdoc those cells are: \"g\" & \"m\".\n            trimTableCellIfNeeded(tableCellCopy, sourceRow, sourceColumn, endRow, endColumn, writer);\n        }\n    }\n    // Adjust heading rows & columns in cropped table if crop selection includes headings parts.\n    addHeadingsToCroppedTable(croppedTable, sourceTable, startRow, startColumn, writer);\n    return croppedTable;\n}\n/**\n * Returns slot info of cells that starts above and overlaps a given row.\n *\n * In a table below, passing `overlapRow = 3`\n *\n *     ┌───┬───┬───┬───┬───┐\n *  0  │ a │ b │ c │ d │ e │\n *     │   ├───┼───┼───┼───┤\n *  1  │   │ f │ g │ h │ i │\n *     ├───┤   ├───┼───┤   │\n *  2  │ j │   │ k │ l │   │\n *     │   │   │   ├───┼───┤\n *  3  │   │   │   │ m │ n │  <- overlap row to check\n *     ├───┼───┤   │   ├───│\n *  4  │ o │ p │   │   │ q │\n *     └───┴───┴───┴───┴───┘\n *\n * will return slot info for cells: \"j\", \"f\", \"k\".\n *\n * @param table The table to check.\n * @param overlapRow The index of the row to check.\n * @param startRow row to start analysis. Use it when it is known that the cells above that row will not overlap. Default value is 0.\n */ function getVerticallyOverlappingCells(table, overlapRow, startRow = 0) {\n    const cells = [];\n    const tableWalker = new TableWalker(table, {\n        startRow,\n        endRow: overlapRow - 1\n    });\n    for (const slotInfo of tableWalker){\n        const { row, cellHeight } = slotInfo;\n        const cellEndRow = row + cellHeight - 1;\n        if (row < overlapRow && overlapRow <= cellEndRow) {\n            cells.push(slotInfo);\n        }\n    }\n    return cells;\n}\n/**\n * Splits the table cell horizontally.\n *\n * @returns Created table cell, if any were created.\n */ function splitHorizontally(tableCell, splitRow, writer) {\n    const tableRow = tableCell.parent;\n    const table = tableRow.parent;\n    const rowIndex = tableRow.index;\n    const rowspan = parseInt(tableCell.getAttribute('rowspan'));\n    const newRowspan = splitRow - rowIndex;\n    const newCellAttributes = {};\n    const newCellRowSpan = rowspan - newRowspan;\n    if (newCellRowSpan > 1) {\n        newCellAttributes.rowspan = newCellRowSpan;\n    }\n    const colspan = parseInt(tableCell.getAttribute('colspan') || '1');\n    if (colspan > 1) {\n        newCellAttributes.colspan = colspan;\n    }\n    const startRow = rowIndex;\n    const endRow = startRow + newRowspan;\n    const tableMap = [\n        ...new TableWalker(table, {\n            startRow,\n            endRow,\n            includeAllSlots: true\n        })\n    ];\n    let newCell = null;\n    let columnIndex;\n    for (const tableSlot of tableMap){\n        const { row, column, cell } = tableSlot;\n        if (cell === tableCell && columnIndex === undefined) {\n            columnIndex = column;\n        }\n        if (columnIndex !== undefined && columnIndex === column && row === endRow) {\n            newCell = createEmptyTableCell(writer, tableSlot.getPositionBefore(), newCellAttributes);\n        }\n    }\n    // Update the rowspan attribute after updating table.\n    updateNumericAttribute('rowspan', newRowspan, tableCell, writer);\n    return newCell;\n}\n/**\n * Returns slot info of cells that starts before and overlaps a given column.\n *\n * In a table below, passing `overlapColumn = 3`\n *\n *    0   1   2   3   4\n *  ┌───────┬───────┬───┐\n *  │ a     │ b     │ c │\n *  │───┬───┴───────┼───┤\n *  │ d │ e         │ f │\n *  ├───┼───┬───────┴───┤\n *  │ g │ h │ i         │\n *  ├───┼───┼───┬───────┤\n *  │ j │ k │ l │ m     │\n *  ├───┼───┴───┼───┬───┤\n *  │ n │ o     │ p │ q │\n *  └───┴───────┴───┴───┘\n *                ^\n *                Overlap column to check\n *\n * will return slot info for cells: \"b\", \"e\", \"i\".\n *\n * @param table The table to check.\n * @param overlapColumn The index of the column to check.\n */ function getHorizontallyOverlappingCells(table, overlapColumn) {\n    const cellsToSplit = [];\n    const tableWalker = new TableWalker(table);\n    for (const slotInfo of tableWalker){\n        const { column, cellWidth } = slotInfo;\n        const cellEndColumn = column + cellWidth - 1;\n        if (column < overlapColumn && overlapColumn <= cellEndColumn) {\n            cellsToSplit.push(slotInfo);\n        }\n    }\n    return cellsToSplit;\n}\n/**\n * Splits the table cell vertically.\n *\n * @param columnIndex The table cell column index.\n * @param splitColumn The index of column to split cell on.\n * @returns Created table cell.\n */ function splitVertically(tableCell, columnIndex, splitColumn, writer) {\n    const colspan = parseInt(tableCell.getAttribute('colspan'));\n    const newColspan = splitColumn - columnIndex;\n    const newCellAttributes = {};\n    const newCellColSpan = colspan - newColspan;\n    if (newCellColSpan > 1) {\n        newCellAttributes.colspan = newCellColSpan;\n    }\n    const rowspan = parseInt(tableCell.getAttribute('rowspan') || '1');\n    if (rowspan > 1) {\n        newCellAttributes.rowspan = rowspan;\n    }\n    const newCell = createEmptyTableCell(writer, writer.createPositionAfter(tableCell), newCellAttributes);\n    // Update the colspan attribute after updating table.\n    updateNumericAttribute('colspan', newColspan, tableCell, writer);\n    return newCell;\n}\n/**\n * Adjusts table cell dimensions to not exceed limit row and column.\n *\n * If table cell width (or height) covers a column (or row) that is after a limit column (or row)\n * this method will trim \"colspan\" (or \"rowspan\") attribute so the table cell will fit in a defined limits.\n */ function trimTableCellIfNeeded(tableCell, cellRow, cellColumn, limitRow, limitColumn, writer) {\n    const colspan = parseInt(tableCell.getAttribute('colspan') || '1');\n    const rowspan = parseInt(tableCell.getAttribute('rowspan') || '1');\n    const endColumn = cellColumn + colspan - 1;\n    if (endColumn > limitColumn) {\n        const trimmedSpan = limitColumn - cellColumn + 1;\n        updateNumericAttribute('colspan', trimmedSpan, tableCell, writer, 1);\n    }\n    const endRow = cellRow + rowspan - 1;\n    if (endRow > limitRow) {\n        const trimmedSpan = limitRow - cellRow + 1;\n        updateNumericAttribute('rowspan', trimmedSpan, tableCell, writer, 1);\n    }\n}\n/**\n * Sets proper heading attributes to a cropped table.\n */ function addHeadingsToCroppedTable(croppedTable, sourceTable, startRow, startColumn, writer) {\n    const headingRows = parseInt(sourceTable.getAttribute('headingRows') || '0');\n    if (headingRows > 0) {\n        const headingRowsInCrop = headingRows - startRow;\n        updateNumericAttribute('headingRows', headingRowsInCrop, croppedTable, writer, 0);\n    }\n    const headingColumns = parseInt(sourceTable.getAttribute('headingColumns') || '0');\n    if (headingColumns > 0) {\n        const headingColumnsInCrop = headingColumns - startColumn;\n        updateNumericAttribute('headingColumns', headingColumnsInCrop, croppedTable, writer, 0);\n    }\n}\n/**\n * Removes columns that have no cells anchored.\n *\n * In table below:\n *\n *     +----+----+----+----+----+----+----+\n *     | 00 | 01      | 03 | 04      | 06 |\n *     +----+----+----+----+         +----+\n *     | 10 | 11      | 13 |         | 16 |\n *     +----+----+----+----+----+----+----+\n *     | 20 | 21      | 23 | 24      | 26 |\n *     +----+----+----+----+----+----+----+\n *                  ^--- empty ---^\n *\n * Will remove columns 2 and 5.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a column from a table use {@link module:table/tableutils~TableUtils#removeColumns `TableUtils.removeColumns()`}.\n *\n * @internal\n * @returns True if removed some columns.\n */ function removeEmptyColumns(table, tableUtils) {\n    const width = tableUtils.getColumns(table);\n    const columnsMap = new Array(width).fill(0);\n    for (const { column } of new TableWalker(table)){\n        columnsMap[column]++;\n    }\n    const emptyColumns = columnsMap.reduce((result, cellsCount, column)=>{\n        return cellsCount ? result : [\n            ...result,\n            column\n        ];\n    }, []);\n    if (emptyColumns.length > 0) {\n        // Remove only last empty column because it will recurrently trigger removing empty rows.\n        const emptyColumn = emptyColumns[emptyColumns.length - 1];\n        // @if CK_DEBUG_TABLE // console.log( `Removing empty column: ${ emptyColumn }.` );\n        tableUtils.removeColumns(table, {\n            at: emptyColumn\n        });\n        return true;\n    }\n    return false;\n}\n/**\n * Removes rows that have no cells anchored.\n *\n * In table below:\n *\n *     +----+----+----+\n *     | 00 | 01 | 02 |\n *     +----+----+----+\n *     | 10 | 11 | 12 |\n *     +    +    +    +\n *     |    |    |    | <-- empty\n *     +----+----+----+\n *     | 30 | 31 | 32 |\n *     +----+----+----+\n *     | 40      | 42 |\n *     +         +    +\n *     |         |    | <-- empty\n *     +----+----+----+\n *     | 60 | 61 | 62 |\n *     +----+----+----+\n *\n * Will remove rows 2 and 5.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a row from a table use {@link module:table/tableutils~TableUtils#removeRows `TableUtils.removeRows()`}.\n *\n * @internal\n * @returns True if removed some rows.\n */ function removeEmptyRows(table, tableUtils) {\n    const emptyRows = [];\n    const tableRowCount = tableUtils.getRows(table);\n    for(let rowIndex = 0; rowIndex < tableRowCount; rowIndex++){\n        const tableRow = table.getChild(rowIndex);\n        if (tableRow.isEmpty) {\n            emptyRows.push(rowIndex);\n        }\n    }\n    if (emptyRows.length > 0) {\n        // Remove only last empty row because it will recurrently trigger removing empty columns.\n        const emptyRow = emptyRows[emptyRows.length - 1];\n        // @if CK_DEBUG_TABLE // console.log( `Removing empty row: ${ emptyRow }.` );\n        tableUtils.removeRows(table, {\n            at: emptyRow\n        });\n        return true;\n    }\n    return false;\n}\n/**\n * Removes rows and columns that have no cells anchored.\n *\n * In table below:\n *\n *     +----+----+----+----+\n *     | 00      | 02      |\n *     +----+----+         +\n *     | 10      |         |\n *     +----+----+----+----+\n *     | 20      | 22 | 23 |\n *     +         +    +    +\n *     |         |    |    | <-- empty row\n *     +----+----+----+----+\n *             ^--- empty column\n *\n * Will remove row 3 and column 1.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a rows from a table use {@link module:table/tableutils~TableUtils#removeRows `TableUtils.removeRows()`} and\n * {@link module:table/tableutils~TableUtils#removeColumns `TableUtils.removeColumns()`} to remove a column.\n *\n * @internal\n */ function removeEmptyRowsColumns(table, tableUtils) {\n    const removedColumns = removeEmptyColumns(table, tableUtils);\n    // If there was some columns removed then cleaning empty rows was already triggered.\n    if (!removedColumns) {\n        removeEmptyRows(table, tableUtils);\n    }\n}\n/**\n * Returns adjusted last row index if selection covers part of a row with empty slots (spanned by other cells).\n * The `dimensions.lastRow` is equal to last row index but selection might be bigger.\n *\n * This happens *only* on rectangular selection so we analyze a case like this:\n *\n *        +---+---+---+---+\n *      0 | a | b | c | d |\n *        +   +   +---+---+\n *      1 |   | e | f | g |\n *        +   +---+   +---+\n *      2 |   | h |   | i | <- last row, each cell has rowspan = 2,\n *        +   +   +   +   +    so we need to return 3, not 2\n *      3 |   |   |   |   |\n *        +---+---+---+---+\n *\n * @returns Adjusted last row index.\n */ function adjustLastRowIndex(table, dimensions) {\n    const lastRowMap = Array.from(new TableWalker(table, {\n        startColumn: dimensions.firstColumn,\n        endColumn: dimensions.lastColumn,\n        row: dimensions.lastRow\n    }));\n    const everyCellHasSingleRowspan = lastRowMap.every(({ cellHeight })=>cellHeight === 1);\n    // It is a \"flat\" row, so the last row index is OK.\n    if (everyCellHasSingleRowspan) {\n        return dimensions.lastRow;\n    }\n    // Otherwise get any cell's rowspan and adjust the last row index.\n    const rowspanAdjustment = lastRowMap[0].cellHeight - 1;\n    return dimensions.lastRow + rowspanAdjustment;\n}\n/**\n * Returns adjusted last column index if selection covers part of a column with empty slots (spanned by other cells).\n * The `dimensions.lastColumn` is equal to last column index but selection might be bigger.\n *\n * This happens *only* on rectangular selection so we analyze a case like this:\n *\n *       0   1   2   3\n *     +---+---+---+---+\n *     | a             |\n *     +---+---+---+---+\n *     | b | c | d     |\n *     +---+---+---+---+\n *     | e     | f     |\n *     +---+---+---+---+\n *     | g | h         |\n *     +---+---+---+---+\n *               ^\n *              last column, each cell has colspan = 2, so we need to return 3, not 2\n *\n * @returns Adjusted last column index.\n */ function adjustLastColumnIndex(table, dimensions) {\n    const lastColumnMap = Array.from(new TableWalker(table, {\n        startRow: dimensions.firstRow,\n        endRow: dimensions.lastRow,\n        column: dimensions.lastColumn\n    }));\n    const everyCellHasSingleColspan = lastColumnMap.every(({ cellWidth })=>cellWidth === 1);\n    // It is a \"flat\" column, so the last column index is OK.\n    if (everyCellHasSingleColspan) {\n        return dimensions.lastColumn;\n    }\n    // Otherwise get any cell's colspan and adjust the last column index.\n    const colspanAdjustment = lastColumnMap[0].cellWidth - 1;\n    return dimensions.lastColumn + colspanAdjustment;\n}\n\n/**\n * The merge cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'mergeTableCellRight'`, `'mergeTableCellLeft'`,\n * `'mergeTableCellUp'` and `'mergeTableCellDown'` editor commands.\n *\n * To merge a table cell at the current selection with another cell, execute the command corresponding with the preferred direction.\n *\n * For example, to merge with a cell to the right:\n *\n * ```ts\n * editor.execute( 'mergeTableCellRight' );\n * ```\n *\n * **Note**: If a table cell has a different [`rowspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-rowspan)\n * (for `'mergeTableCellRight'` and `'mergeTableCellLeft'`) or [`colspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-colspan)\n * (for `'mergeTableCellUp'` and `'mergeTableCellDown'`), the command will be disabled.\n */ class MergeCellCommand extends Command {\n    /**\n\t * The direction that indicates which cell will be merged with the currently selected one.\n\t */ direction;\n    /**\n\t * Whether the merge is horizontal (left/right) or vertical (up/down).\n\t */ isHorizontal;\n    /**\n\t * Creates a new `MergeCellCommand` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t * @param options.direction Indicates which cell to merge with the currently selected one.\n\t * Possible values are: `'left'`, `'right'`, `'up'` and `'down'`.\n\t */ constructor(editor, options){\n        super(editor);\n        this.direction = options.direction;\n        this.isHorizontal = this.direction == 'right' || this.direction == 'left';\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const cellToMerge = this._getMergeableCell();\n        this.value = cellToMerge;\n        this.isEnabled = !!cellToMerge;\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #direction} value, it will merge the cell that is to the `'left'`, `'right'`, `'up'` or `'down'`.\n\t *\n\t * @fires execute\n\t */ execute() {\n        const model = this.editor.model;\n        const doc = model.document;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const tableCell = tableUtils.getTableCellsContainingSelection(doc.selection)[0];\n        const cellToMerge = this.value;\n        const direction = this.direction;\n        model.change((writer)=>{\n            const isMergeNext = direction == 'right' || direction == 'down';\n            // The merge mechanism is always the same so sort cells to be merged.\n            const cellToExpand = isMergeNext ? tableCell : cellToMerge;\n            const cellToRemove = isMergeNext ? cellToMerge : tableCell;\n            // Cache the parent of cell to remove for later check.\n            const removedTableCellRow = cellToRemove.parent;\n            mergeTableCells$1(cellToRemove, cellToExpand, writer);\n            const spanAttribute = this.isHorizontal ? 'colspan' : 'rowspan';\n            const cellSpan = parseInt(tableCell.getAttribute(spanAttribute) || '1');\n            const cellToMergeSpan = parseInt(cellToMerge.getAttribute(spanAttribute) || '1');\n            // Update table cell span attribute and merge set selection on merged contents.\n            writer.setAttribute(spanAttribute, cellSpan + cellToMergeSpan, cellToExpand);\n            writer.setSelection(writer.createRangeIn(cellToExpand));\n            const tableUtils = this.editor.plugins.get('TableUtils');\n            const table = removedTableCellRow.findAncestor('table');\n            // Remove empty rows and columns after merging.\n            removeEmptyRowsColumns(table, tableUtils);\n        });\n    }\n    /**\n\t * Returns a cell that can be merged with the current cell depending on the command's direction.\n\t */ _getMergeableCell() {\n        const model = this.editor.model;\n        const doc = model.document;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const tableCell = tableUtils.getTableCellsContainingSelection(doc.selection)[0];\n        if (!tableCell) {\n            return;\n        }\n        // First get the cell on proper direction.\n        const cellToMerge = this.isHorizontal ? getHorizontalCell(tableCell, this.direction, tableUtils) : getVerticalCell(tableCell, this.direction, tableUtils);\n        if (!cellToMerge) {\n            return;\n        }\n        // If found check if the span perpendicular to merge direction is equal on both cells.\n        const spanAttribute = this.isHorizontal ? 'rowspan' : 'colspan';\n        const span = parseInt(tableCell.getAttribute(spanAttribute) || '1');\n        const cellToMergeSpan = parseInt(cellToMerge.getAttribute(spanAttribute) || '1');\n        if (cellToMergeSpan === span) {\n            return cellToMerge;\n        }\n    }\n}\n/**\n * Returns the cell that can be merged horizontally.\n */ function getHorizontalCell(tableCell, direction, tableUtils) {\n    const tableRow = tableCell.parent;\n    const table = tableRow.parent;\n    const horizontalCell = direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;\n    const hasHeadingColumns = (table.getAttribute('headingColumns') || 0) > 0;\n    if (!horizontalCell) {\n        return;\n    }\n    // Sort cells:\n    const cellOnLeft = direction == 'right' ? tableCell : horizontalCell;\n    const cellOnRight = direction == 'right' ? horizontalCell : tableCell;\n    // Get their column indexes:\n    const { column: leftCellColumn } = tableUtils.getCellLocation(cellOnLeft);\n    const { column: rightCellColumn } = tableUtils.getCellLocation(cellOnRight);\n    const leftCellSpan = parseInt(cellOnLeft.getAttribute('colspan') || '1');\n    const isCellOnLeftInHeadingColumn = isHeadingColumnCell(tableUtils, cellOnLeft);\n    const isCellOnRightInHeadingColumn = isHeadingColumnCell(tableUtils, cellOnRight);\n    // We cannot merge heading columns cells with regular cells.\n    if (hasHeadingColumns && isCellOnLeftInHeadingColumn != isCellOnRightInHeadingColumn) {\n        return;\n    }\n    // The cell on the right must have index that is distant to the cell on the left by the left cell's width (colspan).\n    const cellsAreTouching = leftCellColumn + leftCellSpan === rightCellColumn;\n    // If the right cell's column index is different it means that there are rowspanned cells between them.\n    return cellsAreTouching ? horizontalCell : undefined;\n}\n/**\n * Returns the cell that can be merged vertically.\n */ function getVerticalCell(tableCell, direction, tableUtils) {\n    const tableRow = tableCell.parent;\n    const table = tableRow.parent;\n    const rowIndex = table.getChildIndex(tableRow);\n    // Don't search for mergeable cell if direction points out of the table.\n    if (direction == 'down' && rowIndex === tableUtils.getRows(table) - 1 || direction == 'up' && rowIndex === 0) {\n        return null;\n    }\n    const rowspan = parseInt(tableCell.getAttribute('rowspan') || '1');\n    const headingRows = table.getAttribute('headingRows') || 0;\n    const isMergeWithBodyCell = direction == 'down' && rowIndex + rowspan === headingRows;\n    const isMergeWithHeadCell = direction == 'up' && rowIndex === headingRows;\n    // Don't search for mergeable cell if direction points out of the current table section.\n    if (headingRows && (isMergeWithBodyCell || isMergeWithHeadCell)) {\n        return null;\n    }\n    const currentCellRowSpan = parseInt(tableCell.getAttribute('rowspan') || '1');\n    const rowOfCellToMerge = direction == 'down' ? rowIndex + currentCellRowSpan : rowIndex;\n    const tableMap = [\n        ...new TableWalker(table, {\n            endRow: rowOfCellToMerge\n        })\n    ];\n    const currentCellData = tableMap.find((value)=>value.cell === tableCell);\n    const mergeColumn = currentCellData.column;\n    const cellToMergeData = tableMap.find(({ row, cellHeight, column })=>{\n        if (column !== mergeColumn) {\n            return false;\n        }\n        if (direction == 'down') {\n            // If merging a cell below the mergeRow is already calculated.\n            return row === rowOfCellToMerge;\n        } else {\n            // If merging a cell above calculate if it spans to mergeRow.\n            return rowOfCellToMerge === row + cellHeight;\n        }\n    });\n    return cellToMergeData && cellToMergeData.cell ? cellToMergeData.cell : null;\n}\n/**\n * Merges two table cells. It will ensure that after merging cells with an empty paragraph, the resulting table cell will only have one\n * paragraph. If one of the merged table cells is empty, the merged table cell will have the contents of the non-empty table cell.\n * If both are empty, the merged table cell will have only one empty paragraph.\n */ function mergeTableCells$1(cellToRemove, cellToExpand, writer) {\n    if (!isEmpty$2(cellToRemove)) {\n        if (isEmpty$2(cellToExpand)) {\n            writer.remove(writer.createRangeIn(cellToExpand));\n        }\n        writer.move(writer.createRangeIn(cellToRemove), writer.createPositionAt(cellToExpand, 'end'));\n    }\n    // Remove merged table cell.\n    writer.remove(cellToRemove);\n}\n/**\n * Checks if the passed table cell contains an empty paragraph.\n */ function isEmpty$2(tableCell) {\n    const firstTableChild = tableCell.getChild(0);\n    return tableCell.childCount == 1 && firstTableChild.is('element', 'paragraph') && firstTableChild.isEmpty;\n}\n\n/**\n * The remove row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableRow'` editor command.\n *\n * To remove the row containing the selected cell, execute the command:\n *\n * ```ts\n * editor.execute( 'removeTableRow' );\n * ```\n */ class RemoveRowCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection);\n        const firstCell = selectedCells[0];\n        if (firstCell) {\n            const table = firstCell.findAncestor('table');\n            const tableRowCount = tableUtils.getRows(table);\n            const lastRowIndex = tableRowCount - 1;\n            const selectedRowIndexes = tableUtils.getRowIndexes(selectedCells);\n            const areAllRowsSelected = selectedRowIndexes.first === 0 && selectedRowIndexes.last === lastRowIndex;\n            // Disallow selecting whole table -> delete whole table should be used instead.\n            this.isEnabled = !areAllRowsSelected;\n        } else {\n            this.isEnabled = false;\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const model = this.editor.model;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const referenceCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const removedRowIndexes = tableUtils.getRowIndexes(referenceCells);\n        const firstCell = referenceCells[0];\n        const table = firstCell.findAncestor('table');\n        const columnIndexToFocus = tableUtils.getCellLocation(firstCell).column;\n        model.change((writer)=>{\n            const rowsToRemove = removedRowIndexes.last - removedRowIndexes.first + 1;\n            tableUtils.removeRows(table, {\n                at: removedRowIndexes.first,\n                rows: rowsToRemove\n            });\n            const cellToFocus = getCellToFocus$1(table, removedRowIndexes.first, columnIndexToFocus, tableUtils.getRows(table));\n            writer.setSelection(writer.createPositionAt(cellToFocus, 0));\n        });\n    }\n}\n/**\n * Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.\n * - If the row was not the last one, the cell to focus will be in the row that followed it (before removal).\n * - If the row was the last one, the cell to focus will be in the row that preceded it (before removal).\n */ function getCellToFocus$1(table, removedRowIndex, columnToFocus, tableRowCount) {\n    // Don't go beyond last row's index.\n    const row = table.getChild(Math.min(removedRowIndex, tableRowCount - 1));\n    // Default to first table cell.\n    let cellToFocus = row.getChild(0);\n    let column = 0;\n    for (const tableCell of row.getChildren()){\n        if (column > columnToFocus) {\n            return cellToFocus;\n        }\n        cellToFocus = tableCell;\n        column += parseInt(tableCell.getAttribute('colspan') || '1');\n    }\n    return cellToFocus;\n}\n\n/**\n * The remove column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableColumn'` editor command.\n *\n * To remove the column containing the selected cell, execute the command:\n *\n * ```ts\n * editor.execute( 'removeTableColumn' );\n * ```\n */ class RemoveColumnCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection);\n        const firstCell = selectedCells[0];\n        if (firstCell) {\n            const table = firstCell.findAncestor('table');\n            const tableColumnCount = tableUtils.getColumns(table);\n            const { first, last } = tableUtils.getColumnIndexes(selectedCells);\n            this.isEnabled = last - first < tableColumnCount - 1;\n        } else {\n            this.isEnabled = false;\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const [firstCell, lastCell] = getBoundaryCells(this.editor.model.document.selection, tableUtils);\n        const table = firstCell.parent.parent;\n        // Cache the table before removing or updating colspans.\n        const tableMap = [\n            ...new TableWalker(table)\n        ];\n        // Store column indexes of removed columns.\n        const removedColumnIndexes = {\n            first: tableMap.find((value)=>value.cell === firstCell).column,\n            last: tableMap.find((value)=>value.cell === lastCell).column\n        };\n        const cellToFocus = getCellToFocus(tableMap, firstCell, lastCell, removedColumnIndexes);\n        this.editor.model.change((writer)=>{\n            const columnsToRemove = removedColumnIndexes.last - removedColumnIndexes.first + 1;\n            tableUtils.removeColumns(table, {\n                at: removedColumnIndexes.first,\n                columns: columnsToRemove\n            });\n            writer.setSelection(writer.createPositionAt(cellToFocus, 0));\n        });\n    }\n}\n/**\n * Returns a proper table cell to focus after removing a column.\n * - selection is on last table cell it will return previous cell.\n */ function getCellToFocus(tableMap, firstCell, lastCell, removedColumnIndexes) {\n    const colspan = parseInt(lastCell.getAttribute('colspan') || '1');\n    // If the table cell is spanned over 2+ columns - it will be truncated so the selection should\n    // stay in that cell.\n    if (colspan > 1) {\n        return lastCell;\n    } else if (firstCell.previousSibling || lastCell.nextSibling) {\n        return lastCell.nextSibling || firstCell.previousSibling;\n    } else {\n        // Look for any cell in a column that precedes the first removed column.\n        if (removedColumnIndexes.first) {\n            return tableMap.reverse().find(({ column })=>{\n                return column < removedColumnIndexes.first;\n            }).cell;\n        } else {\n            return tableMap.reverse().find(({ column })=>{\n                return column > removedColumnIndexes.last;\n            }).cell;\n        }\n    }\n}\n/**\n * Returns helper object returning the first and the last cell contained in given selection, based on DOM order.\n */ function getBoundaryCells(selection, tableUtils) {\n    const referenceCells = tableUtils.getSelectionAffectedTableCells(selection);\n    const firstCell = referenceCells[0];\n    const lastCell = referenceCells.pop();\n    const returnValue = [\n        firstCell,\n        lastCell\n    ];\n    return firstCell.isBefore(lastCell) ? returnValue : returnValue.reverse();\n}\n\n/**\n * The header row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.\n *\n * You can make the row containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element) by executing:\n *\n * ```ts\n * editor.execute( 'setTableRowHeader' );\n * ```\n *\n * **Note:** All preceding rows will also become headers. If the current row is already a header, executing this command\n * will make it a regular row back again (including the following rows).\n */ class SetHeaderRowCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const model = this.editor.model;\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const isInTable = selectedCells.length > 0;\n        this.isEnabled = isInTable;\n        this.value = isInTable && selectedCells.every((cell)=>this._isInHeading(cell, cell.parent.parent));\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header row, the command will set the `headingRows` table attribute to cover that row.\n\t *\n\t * When the selection is already in a header row, it will set `headingRows` so the heading section will end before that row.\n\t *\n\t * @fires execute\n\t * @param options.forceValue If set, the command will set (`true`) or unset (`false`) the header rows according to\n\t * the `forceValue` parameter instead of the current model state.\n\t */ execute(options = {}) {\n        if (options.forceValue === this.value) {\n            return;\n        }\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const model = this.editor.model;\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const table = selectedCells[0].findAncestor('table');\n        const { first, last } = tableUtils.getRowIndexes(selectedCells);\n        const headingRowsToSet = this.value ? first : last + 1;\n        const currentHeadingRows = table.getAttribute('headingRows') || 0;\n        model.change((writer)=>{\n            if (headingRowsToSet) {\n                // Changing heading rows requires to check if any of a heading cell is overlapping vertically the table head.\n                // Any table cell that has a rowspan attribute > 1 will not exceed the table head so we need to fix it in rows below.\n                const startRow = headingRowsToSet > currentHeadingRows ? currentHeadingRows : 0;\n                const overlappingCells = getVerticallyOverlappingCells(table, headingRowsToSet, startRow);\n                for (const { cell } of overlappingCells){\n                    splitHorizontally(cell, headingRowsToSet, writer);\n                }\n            }\n            updateNumericAttribute('headingRows', headingRowsToSet, table, writer, 0);\n        });\n    }\n    /**\n\t * Checks if a table cell is in the heading section.\n\t */ _isInHeading(tableCell, table) {\n        const headingRows = parseInt(table.getAttribute('headingRows') || '0');\n        return !!headingRows && tableCell.parent.index < headingRows;\n    }\n}\n\n/**\n * The header column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.\n *\n * You can make the column containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element)\n * by executing:\n *\n * ```ts\n * editor.execute( 'setTableColumnHeader' );\n * ```\n *\n * **Note:** All preceding columns will also become headers. If the current column is already a header, executing this command\n * will make it a regular column back again (including the following columns).\n */ class SetHeaderColumnCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const model = this.editor.model;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const isInTable = selectedCells.length > 0;\n        this.isEnabled = isInTable;\n        this.value = isInTable && selectedCells.every((cell)=>isHeadingColumnCell(tableUtils, cell));\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header column, the command will set the `headingColumns` table attribute to cover that column.\n\t *\n\t * When the selection is already in a header column, it will set `headingColumns` so the heading section will end before that column.\n\t *\n\t * @fires execute\n\t * @param options.forceValue If set, the command will set (`true`) or unset (`false`) the header columns according to\n\t * the `forceValue` parameter instead of the current model state.\n\t */ execute(options = {}) {\n        if (options.forceValue === this.value) {\n            return;\n        }\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const model = this.editor.model;\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const table = selectedCells[0].findAncestor('table');\n        const { first, last } = tableUtils.getColumnIndexes(selectedCells);\n        const headingColumnsToSet = this.value ? first : last + 1;\n        model.change((writer)=>{\n            if (headingColumnsToSet) {\n                // Changing heading columns requires to check if any of a heading cell is overlapping horizontally the table head.\n                // Any table cell that has a colspan attribute > 1 will not exceed the table head so we need to fix it in columns before.\n                const overlappingCells = getHorizontallyOverlappingCells(table, headingColumnsToSet);\n                for (const { cell, column } of overlappingCells){\n                    splitVertically(cell, column, headingColumnsToSet, writer);\n                }\n            }\n            updateNumericAttribute('headingColumns', headingColumnsToSet, table, writer, 0);\n        });\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module table/tablecolumnresize/constants\n */ /**\n * The minimum column width given as a percentage value. Used in situations when the table is not yet rendered, so it is impossible to\n * calculate how many percentage of the table width would be {@link ~COLUMN_MIN_WIDTH_IN_PIXELS minimum column width in pixels}.\n */ const COLUMN_MIN_WIDTH_AS_PERCENTAGE = 5;\n/**\n * The minimum column width in pixels when the maximum table width is known.\n */ const COLUMN_MIN_WIDTH_IN_PIXELS = 40;\n/**\n * Determines how many digits after the decimal point are used to store the column width as a percentage value.\n */ const COLUMN_WIDTH_PRECISION = 2;\n\n/**\n * Returns all the inserted or changed table model elements in a given change set. Only the tables\n * with 'columnsWidth' attribute are taken into account. The returned set may be empty.\n *\n * Most notably if an entire table is removed it will not be included in returned set.\n *\n * @param model The model to collect the affected elements from.\n * @returns A set of table model elements.\n */ function getChangedResizedTables(model) {\n    const affectedTables = new Set();\n    for (const change of model.document.differ.getChanges()){\n        let referencePosition = null;\n        // Checks if the particular change from the differ is:\n        // - an insertion or removal of a table, a row or a cell,\n        // - an attribute change on a table, a row or a cell.\n        switch(change.type){\n            case 'insert':\n                referencePosition = [\n                    'table',\n                    'tableRow',\n                    'tableCell'\n                ].includes(change.name) ? change.position : null;\n                break;\n            case 'remove':\n                // If the whole table is removed, there's no need to update its column widths (#12201).\n                referencePosition = [\n                    'tableRow',\n                    'tableCell'\n                ].includes(change.name) ? change.position : null;\n                break;\n            case 'attribute':\n                if (change.range.start.nodeAfter) {\n                    referencePosition = [\n                        'table',\n                        'tableRow',\n                        'tableCell'\n                    ].includes(change.range.start.nodeAfter.name) ? change.range.start : null;\n                }\n                break;\n        }\n        if (!referencePosition) {\n            continue;\n        }\n        const tableNode = referencePosition.nodeAfter && referencePosition.nodeAfter.is('element', 'table') ? referencePosition.nodeAfter : referencePosition.findAncestor('table');\n        // We iterate over the whole table looking for the nested tables that are also affected.\n        for (const node of model.createRangeOn(tableNode).getItems()){\n            if (!node.is('element', 'table')) {\n                continue;\n            }\n            if (!getColumnGroupElement(node)) {\n                continue;\n            }\n            affectedTables.add(node);\n        }\n    }\n    return affectedTables;\n}\n/**\n * Calculates the percentage of the minimum column width given in pixels for a given table.\n *\n * @param modelTable A table model element.\n * @param editor The editor instance.\n * @returns The minimal column width in percentage.\n */ function getColumnMinWidthAsPercentage(modelTable, editor) {\n    return COLUMN_MIN_WIDTH_IN_PIXELS * 100 / getTableWidthInPixels(modelTable, editor);\n}\n/**\n * Calculates the table width in pixels.\n *\n * @param modelTable A table model element.\n * @param editor The editor instance.\n * @returns The width of the table in pixels.\n */ function getTableWidthInPixels(modelTable, editor) {\n    // It is possible for a table to not have a <tbody> element - see #11878.\n    const referenceElement = getChildrenViewElement(modelTable, 'tbody', editor) || getChildrenViewElement(modelTable, 'thead', editor);\n    const domReferenceElement = editor.editing.view.domConverter.mapViewToDom(referenceElement);\n    return getElementWidthInPixels(domReferenceElement);\n}\n/**\n * Returns the a view element with a given name that is nested directly in a `<table>` element\n * related to a given `modelTable`.\n *\n * @param elementName Name of a view to be looked for, e.g. `'colgroup`', `'thead`'.\n * @returns Matched view or `undefined` otherwise.\n */ function getChildrenViewElement(modelTable, elementName, editor) {\n    const viewFigure = editor.editing.mapper.toViewElement(modelTable);\n    const viewTable = [\n        ...viewFigure.getChildren()\n    ].find((node)=>node.is('element', 'table'));\n    return [\n        ...viewTable.getChildren()\n    ].find((node)=>node.is('element', elementName));\n}\n/**\n * Returns the computed width (in pixels) of the DOM element without padding and borders.\n *\n * @param domElement A DOM element.\n * @returns The width of the DOM element in pixels.\n */ function getElementWidthInPixels(domElement) {\n    const styles = global.window.getComputedStyle(domElement);\n    // In the 'border-box' box sizing algorithm, the element's width\n    // already includes the padding and border width (#12335).\n    if (styles.boxSizing === 'border-box') {\n        return parseFloat(styles.width) - parseFloat(styles.paddingLeft) - parseFloat(styles.paddingRight) - parseFloat(styles.borderLeftWidth) - parseFloat(styles.borderRightWidth);\n    } else {\n        return parseFloat(styles.width);\n    }\n}\n/**\n * Returns the column indexes on the left and right edges of a cell. They differ if the cell spans\n * across multiple columns.\n *\n * @param cell A table cell model element.\n * @param tableUtils The Table Utils plugin instance.\n * @returns An object containing the indexes of the left and right edges of the cell.\n */ function getColumnEdgesIndexes(cell, tableUtils) {\n    const cellColumnIndex = tableUtils.getCellLocation(cell).column;\n    const cellWidth = cell.getAttribute('colspan') || 1;\n    return {\n        leftEdge: cellColumnIndex,\n        rightEdge: cellColumnIndex + cellWidth - 1\n    };\n}\n/**\n * Rounds the provided value to a fixed-point number with defined number of digits after the decimal point.\n *\n * @param value A number to be rounded.\n * @returns The rounded number.\n */ function toPrecision(value) {\n    const multiplier = Math.pow(10, COLUMN_WIDTH_PRECISION);\n    const number = typeof value === 'number' ? value : parseFloat(value);\n    return Math.round(number * multiplier) / multiplier;\n}\n/**\n * Clamps the number within the inclusive lower (min) and upper (max) bounds. Returned number is rounded using the\n * {@link ~toPrecision `toPrecision()`} function.\n *\n * @param number A number to be clamped.\n * @param min A lower bound.\n * @param max An upper bound.\n * @returns The clamped number.\n */ function clamp(number, min, max) {\n    if (number <= min) {\n        return toPrecision(min);\n    }\n    if (number >= max) {\n        return toPrecision(max);\n    }\n    return toPrecision(number);\n}\n/**\n * Creates an array with defined length and fills all elements with defined value.\n *\n * @param length The length of the array.\n * @param value The value to fill the array with.\n * @returns An array with defined length and filled with defined value.\n */ function createFilledArray(length, value) {\n    return Array(length).fill(value);\n}\n/**\n * Sums all array values that can be parsed to a float.\n *\n * @param array An array of numbers.\n * @returns The sum of all array values.\n */ function sumArray(array) {\n    return array.map((value)=>typeof value === 'number' ? value : parseFloat(value)).filter((value)=>!Number.isNaN(value)).reduce((result, item)=>result + item, 0);\n}\n/**\n * Makes sure that the sum of the widths from all columns is 100%. If the sum of all the widths is not equal 100%, all the widths are\n * changed proportionally so that they all sum back to 100%. If there are columns without specified width, the amount remaining\n * after assigning the known widths will be distributed equally between them.\n *\n * @param columnWidths An array of column widths.\n * @returns An array of column widths guaranteed to sum up to 100%.\n */ function normalizeColumnWidths(columnWidths) {\n    const widths = columnWidths.map((width)=>{\n        if (width === 'auto') {\n            return width;\n        }\n        return parseFloat(width.replace('%', ''));\n    });\n    let normalizedWidths = calculateMissingColumnWidths(widths);\n    const totalWidth = sumArray(normalizedWidths);\n    if (totalWidth !== 100) {\n        normalizedWidths = normalizedWidths// Adjust all the columns proportionally.\n        .map((width)=>toPrecision(width * 100 / totalWidth))// Due to rounding of numbers it may happen that the sum of the widths of all columns will not be exactly 100%.\n        // Therefore, the width of the last column is explicitly adjusted (narrowed or expanded), since all the columns\n        // have been proportionally changed already.\n        .map((columnWidth, columnIndex, width)=>{\n            const isLastColumn = columnIndex === width.length - 1;\n            if (!isLastColumn) {\n                return columnWidth;\n            }\n            const totalWidth = sumArray(width);\n            return toPrecision(columnWidth + 100 - totalWidth);\n        });\n    }\n    return normalizedWidths.map((width)=>width + '%');\n}\n/**\n * Initializes the column widths by parsing the attribute value and calculating the uninitialized column widths. The special value 'auto'\n * indicates that width for the column must be calculated. The width of such uninitialized column is calculated as follows:\n * - If there is enough free space in the table for all uninitialized columns to have at least the minimum allowed width for all of them,\n *   then set this width equally for all uninitialized columns.\n * - Otherwise, just set the minimum allowed width for all uninitialized columns. The sum of all column widths will be greater than 100%,\n *   but then it will be adjusted proportionally to 100% in {@link #normalizeColumnWidths `normalizeColumnWidths()`}.\n *\n * @param columnWidths An array of column widths.\n * @returns An array with 'auto' values replaced with calculated widths.\n */ function calculateMissingColumnWidths(columnWidths) {\n    const numberOfUninitializedColumns = columnWidths.filter((columnWidth)=>columnWidth === 'auto').length;\n    if (numberOfUninitializedColumns === 0) {\n        return columnWidths.map((columnWidth)=>toPrecision(columnWidth));\n    }\n    const totalWidthOfInitializedColumns = sumArray(columnWidths);\n    const widthForUninitializedColumn = Math.max((100 - totalWidthOfInitializedColumns) / numberOfUninitializedColumns, COLUMN_MIN_WIDTH_AS_PERCENTAGE);\n    return columnWidths.map((columnWidth)=>columnWidth === 'auto' ? widthForUninitializedColumn : columnWidth).map((columnWidth)=>toPrecision(columnWidth));\n}\n/**\n * Calculates the total horizontal space taken by the cell. That includes:\n *  * width,\n *  * left and red padding,\n *  * border width.\n *\n * @param domCell A DOM cell element.\n * @returns Width in pixels without `px` at the end.\n */ function getDomCellOuterWidth(domCell) {\n    const styles = global.window.getComputedStyle(domCell);\n    // In the 'border-box' box sizing algorithm, the element's width\n    // already includes the padding and border width (#12335).\n    if (styles.boxSizing === 'border-box') {\n        return parseInt(styles.width);\n    } else {\n        return parseFloat(styles.width) + parseFloat(styles.paddingLeft) + parseFloat(styles.paddingRight) + parseFloat(styles.borderWidth);\n    }\n}\n/**\n * Updates column elements to match columns widths.\n *\n * @param columns\n * @param tableColumnGroup\n * @param normalizedWidths\n * @param writer\n */ function updateColumnElements(columns, tableColumnGroup, normalizedWidths, writer) {\n    for(let i = 0; i < Math.max(normalizedWidths.length, columns.length); i++){\n        const column = columns[i];\n        const columnWidth = normalizedWidths[i];\n        if (!columnWidth) {\n            // Number of `<tableColumn>` elements exceeds actual number of columns.\n            writer.remove(column);\n        } else if (!column) {\n            // There is fewer `<tableColumn>` elements than actual columns.\n            writer.appendElement('tableColumn', {\n                columnWidth\n            }, tableColumnGroup);\n        } else {\n            // Update column width.\n            writer.setAttribute('columnWidth', columnWidth, column);\n        }\n    }\n}\n/**\n * Returns a 'tableColumnGroup' element from the 'table'.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @returns A 'tableColumnGroup' element.\n */ function getColumnGroupElement(element) {\n    if (element.is('element', 'tableColumnGroup')) {\n        return element;\n    }\n    const children = element.getChildren();\n    return Array.from(children).find((element)=>element.is('element', 'tableColumnGroup'));\n}\n/**\n * Returns an array of 'tableColumn' elements. It may be empty if there's no `tableColumnGroup` element.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @returns An array of 'tableColumn' elements.\n */ function getTableColumnElements(element) {\n    const columnGroupElement = getColumnGroupElement(element);\n    if (!columnGroupElement) {\n        return [];\n    }\n    return Array.from(columnGroupElement.getChildren());\n}\n/**\n * Returns an array of table column widths.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @returns An array of table column widths.\n */ function getTableColumnsWidths(element) {\n    return getTableColumnElements(element).map((column)=>column.getAttribute('columnWidth'));\n}\n/**\n * Translates the `colSpan` model attribute into additional column widths and returns the resulting array.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @param writer A writer instance.\n * @returns An array of table column widths.\n */ function translateColSpanAttribute(element, writer) {\n    const tableColumnElements = getTableColumnElements(element);\n    return tableColumnElements.reduce((acc, element)=>{\n        const columnWidth = element.getAttribute('columnWidth');\n        const colSpan = element.getAttribute('colSpan');\n        if (!colSpan) {\n            acc.push(columnWidth);\n            return acc;\n        }\n        // Translate the `colSpan` model attribute on to the proper number of column widths\n        // and remove it from the element.\n        // See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for more details.\n        for(let i = 0; i < colSpan; i++){\n            acc.push(columnWidth);\n        }\n        writer.removeAttribute('colSpan', element);\n        return acc;\n    }, []);\n}\n\n/**\n * The table utilities plugin.\n */ class TableUtils extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableUtils';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        this.decorate('insertColumns');\n        this.decorate('insertRows');\n    }\n    /**\n\t * Returns the table cell location as an object with table row and table column indexes.\n\t *\n\t * For instance, in the table below:\n\t *\n\t *      0   1   2   3\n\t *    +---+---+---+---+\n\t *  0 | a     | b | c |\n\t *    +       +   +---+\n\t *  1 |       |   | d |\n\t *    +---+---+   +---+\n\t *  2 | e     |   | f |\n\t *    +---+---+---+---+\n\t *\n\t * the method will return:\n\t *\n\t * ```ts\n\t * const cellA = table.getNodeByPath( [ 0, 0 ] );\n\t * editor.plugins.get( 'TableUtils' ).getCellLocation( cellA );\n\t * // will return { row: 0, column: 0 }\n\t *\n\t * const cellD = table.getNodeByPath( [ 1, 0 ] );\n\t * editor.plugins.get( 'TableUtils' ).getCellLocation( cellD );\n\t * // will return { row: 1, column: 3 }\n\t * ```\n\t *\n\t * @returns Returns a `{row, column}` object.\n\t */ getCellLocation(tableCell) {\n        const tableRow = tableCell.parent;\n        const table = tableRow.parent;\n        const rowIndex = table.getChildIndex(tableRow);\n        const tableWalker = new TableWalker(table, {\n            row: rowIndex\n        });\n        for (const { cell, row, column } of tableWalker){\n            if (cell === tableCell) {\n                return {\n                    row,\n                    column\n                };\n            }\n        }\n        // Should be unreachable code.\n        /* istanbul ignore next -- @preserve */ return undefined;\n    }\n    /**\n\t * Creates an empty table with a proper structure. The table needs to be inserted into the model,\n\t * for example, by using the {@link module:engine/model/model~Model#insertContent} function.\n\t *\n\t * ```ts\n\t * model.change( ( writer ) => {\n\t *   // Create a table of 2 rows and 7 columns:\n\t *   const table = tableUtils.createTable( writer, { rows: 2, columns: 7 } );\n\t *\n\t *   // Insert a table to the model at the best position taking the current selection:\n\t *   model.insertContent( table );\n\t * }\n\t * ```\n\t *\n\t * @param writer The model writer.\n\t * @param options.rows The number of rows to create. Default value is 2.\n\t * @param options.columns The number of columns to create. Default value is 2.\n\t * @param options.headingRows The number of heading rows. Default value is 0.\n\t * @param options.headingColumns The number of heading columns. Default value is 0.\n\t * @returns The created table element.\n\t */ createTable(writer, options) {\n        const table = writer.createElement('table');\n        const rows = options.rows || 2;\n        const columns = options.columns || 2;\n        createEmptyRows(writer, table, 0, rows, columns);\n        if (options.headingRows) {\n            updateNumericAttribute('headingRows', Math.min(options.headingRows, rows), table, writer, 0);\n        }\n        if (options.headingColumns) {\n            updateNumericAttribute('headingColumns', Math.min(options.headingColumns, columns), table, writer, 0);\n        }\n        return table;\n    }\n    /**\n\t * Inserts rows into a table.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).insertRows( table, { at: 1, rows: 2 } );\n\t * ```\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *  row index\n\t *    0 +---+---+---+       `at` = 1,      +---+---+---+ 0\n\t *      | a | b | c |       `rows` = 2,    | a | b | c |\n\t *    1 +   +---+---+   <-- insert here    +   +---+---+ 1\n\t *      |   | d | e |                      |   |   |   |\n\t *    2 +   +---+---+       will give:     +   +---+---+ 2\n\t *      |   | f | g |                      |   |   |   |\n\t *    3 +---+---+---+                      +   +---+---+ 3\n\t *                                         |   | d | e |\n\t *                                         +   +---+---+ 4\n\t *                                         +   + f | g |\n\t *                                         +---+---+---+ 5\n\t *\n\t * @param table The table model element where the rows will be inserted.\n\t * @param options.at The row index at which the rows will be inserted.  Default value is 0.\n\t * @param options.rows The number of rows to insert.  Default value is 1.\n\t * @param options.copyStructureFromAbove The flag for copying row structure. Note that\n\t * the row structure will not be copied if this option is not provided.\n\t */ insertRows(table, options = {}) {\n        const model = this.editor.model;\n        const insertAt = options.at || 0;\n        const rowsToInsert = options.rows || 1;\n        const isCopyStructure = options.copyStructureFromAbove !== undefined;\n        const copyStructureFrom = options.copyStructureFromAbove ? insertAt - 1 : insertAt;\n        const rows = this.getRows(table);\n        const columns = this.getColumns(table);\n        if (insertAt > rows) {\n            /**\n\t\t\t * The `options.at` points at a row position that does not exist.\n\t\t\t *\n\t\t\t * @error tableutils-insertrows-insert-out-of-range\n\t\t\t */ throw new CKEditorError('tableutils-insertrows-insert-out-of-range', this, {\n                options\n            });\n        }\n        model.change((writer)=>{\n            const headingRows = table.getAttribute('headingRows') || 0;\n            // Inserting rows inside heading section requires to update `headingRows` attribute as the heading section will grow.\n            if (headingRows > insertAt) {\n                updateNumericAttribute('headingRows', headingRows + rowsToInsert, table, writer, 0);\n            }\n            // Inserting at the end or at the beginning of a table doesn't require to calculate anything special.\n            if (!isCopyStructure && (insertAt === 0 || insertAt === rows)) {\n                createEmptyRows(writer, table, insertAt, rowsToInsert, columns);\n                return;\n            }\n            // Iterate over all the rows above the inserted rows in order to check for the row-spanned cells.\n            const walkerEndRow = isCopyStructure ? Math.max(insertAt, copyStructureFrom) : insertAt;\n            const tableIterator = new TableWalker(table, {\n                endRow: walkerEndRow\n            });\n            // Store spans of the reference row to reproduce it's structure. This array is column number indexed.\n            const rowColSpansMap = new Array(columns).fill(1);\n            for (const { row, column, cellHeight, cellWidth, cell } of tableIterator){\n                const lastCellRow = row + cellHeight - 1;\n                const isOverlappingInsertedRow = row < insertAt && insertAt <= lastCellRow;\n                const isReferenceRow = row <= copyStructureFrom && copyStructureFrom <= lastCellRow;\n                // If the cell is row-spanned and overlaps the inserted row, then reserve space for it in the row map.\n                if (isOverlappingInsertedRow) {\n                    // This cell overlaps the inserted rows so we need to expand it further.\n                    writer.setAttribute('rowspan', cellHeight + rowsToInsert, cell);\n                    // Mark this cell with negative number to indicate how many cells should be skipped when adding the new cells.\n                    rowColSpansMap[column] = -cellWidth;\n                } else if (isCopyStructure && isReferenceRow) {\n                    rowColSpansMap[column] = cellWidth;\n                }\n            }\n            for(let rowIndex = 0; rowIndex < rowsToInsert; rowIndex++){\n                const tableRow = writer.createElement('tableRow');\n                writer.insert(tableRow, table, insertAt);\n                for(let cellIndex = 0; cellIndex < rowColSpansMap.length; cellIndex++){\n                    const colspan = rowColSpansMap[cellIndex];\n                    const insertPosition = writer.createPositionAt(tableRow, 'end');\n                    // Insert the empty cell only if this slot is not row-spanned from any other cell.\n                    if (colspan > 0) {\n                        createEmptyTableCell(writer, insertPosition, colspan > 1 ? {\n                            colspan\n                        } : undefined);\n                    }\n                    // Skip the col-spanned slots, there won't be any cells.\n                    cellIndex += Math.abs(colspan) - 1;\n                }\n            }\n        });\n    }\n    /**\n\t * Inserts columns into a table.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).insertColumns( table, { at: 1, columns: 2 } );\n\t * ```\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *  0   1   2   3                   0   1   2   3   4   5\n\t *  +---+---+---+                   +---+---+---+---+---+\n\t *  | a     | b |                   | a             | b |\n\t *  +       +---+                   +               +---+\n\t *  |       | c |                   |               | c |\n\t *  +---+---+---+     will give:    +---+---+---+---+---+\n\t *  | d | e | f |                   | d |   |   | e | f |\n\t *  +---+   +---+                   +---+---+---+   +---+\n\t *  | g |   | h |                   | g |   |   |   | h |\n\t *  +---+---+---+                   +---+---+---+---+---+\n\t *  | i         |                   | i                 |\n\t *  +---+---+---+                   +---+---+---+---+---+\n\t *      ^---- insert here, `at` = 1, `columns` = 2\n\t *\n\t * @param table The table model element where the columns will be inserted.\n\t * @param options.at The column index at which the columns will be inserted. Default value is 0.\n\t * @param options.columns The number of columns to insert. Default value is 1.\n\t */ insertColumns(table, options = {}) {\n        const model = this.editor.model;\n        const insertAt = options.at || 0;\n        const columnsToInsert = options.columns || 1;\n        model.change((writer)=>{\n            const headingColumns = table.getAttribute('headingColumns');\n            // Inserting columns inside heading section requires to update `headingColumns` attribute as the heading section will grow.\n            if (insertAt < headingColumns) {\n                writer.setAttribute('headingColumns', headingColumns + columnsToInsert, table);\n            }\n            const tableColumns = this.getColumns(table);\n            // Inserting at the end and at the beginning of a table doesn't require to calculate anything special.\n            if (insertAt === 0 || tableColumns === insertAt) {\n                for (const tableRow of table.getChildren()){\n                    // Ignore non-row elements inside the table (e.g. caption).\n                    if (!tableRow.is('element', 'tableRow')) {\n                        continue;\n                    }\n                    createCells(columnsToInsert, writer, writer.createPositionAt(tableRow, insertAt ? 'end' : 0));\n                }\n                return;\n            }\n            const tableWalker = new TableWalker(table, {\n                column: insertAt,\n                includeAllSlots: true\n            });\n            for (const tableSlot of tableWalker){\n                const { row, cell, cellAnchorColumn, cellAnchorRow, cellWidth, cellHeight } = tableSlot;\n                // When iterating over column the table walker outputs either:\n                // - cells at given column index (cell \"e\" from method docs),\n                // - spanned columns (spanned cell from row between cells \"g\" and \"h\" - spanned by \"e\", only if `includeAllSlots: true`),\n                // - or a cell from the same row which spans over this column (cell \"a\").\n                if (cellAnchorColumn < insertAt) {\n                    // If cell is anchored in previous column, it is a cell that spans over an inserted column (cell \"a\" & \"i\").\n                    // For such cells expand them by a number of columns inserted.\n                    writer.setAttribute('colspan', cellWidth + columnsToInsert, cell);\n                    // This cell will overlap cells in rows below so skip them (because of `includeAllSlots` option) - (cell \"a\")\n                    const lastCellRow = cellAnchorRow + cellHeight - 1;\n                    for(let i = row; i <= lastCellRow; i++){\n                        tableWalker.skipRow(i);\n                    }\n                } else {\n                    // It's either cell at this column index or spanned cell by a row-spanned cell from row above.\n                    // In table above it's cell \"e\" and a spanned position from row below (empty cell between cells \"g\" and \"h\")\n                    createCells(columnsToInsert, writer, tableSlot.getPositionBefore());\n                }\n            }\n        });\n    }\n    /**\n\t * Removes rows from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including `rowspan` attribute of table cells overlapping removed rows\n\t * and table headings values.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).removeRows( table, { at: 1, rows: 2 } );\n\t * ```\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *  row index\n\t *      ┌───┬───┬───┐        `at` = 1        ┌───┬───┬───┐\n\t *    0 │ a │ b │ c │        `rows` = 2      │ a │ b │ c │ 0\n\t *      │   ├───┼───┤                        │   ├───┼───┤\n\t *    1 │   │ d │ e │  <-- remove from here  │   │ d │ g │ 1\n\t *      │   │   ├───┤        will give:      ├───┼───┼───┤\n\t *    2 │   │   │ f │                        │ h │ i │ j │ 2\n\t *      │   │   ├───┤                        └───┴───┴───┘\n\t *    3 │   │   │ g │\n\t *      ├───┼───┼───┤\n\t *    4 │ h │ i │ j │\n\t *      └───┴───┴───┘\n\t *\n\t * @param options.at The row index at which the removing rows will start.\n\t * @param options.rows The number of rows to remove. Default value is 1.\n\t */ removeRows(table, options) {\n        const model = this.editor.model;\n        const rowsToRemove = options.rows || 1;\n        const rowCount = this.getRows(table);\n        const first = options.at;\n        const last = first + rowsToRemove - 1;\n        if (last > rowCount - 1) {\n            /**\n\t\t\t * The `options.at` param must point at existing row and `options.rows` must not exceed the rows in the table.\n\t\t\t *\n\t\t\t * @error tableutils-removerows-row-index-out-of-range\n\t\t\t */ throw new CKEditorError('tableutils-removerows-row-index-out-of-range', this, {\n                table,\n                options\n            });\n        }\n        model.change((writer)=>{\n            const indexesObject = {\n                first,\n                last\n            };\n            // Removing rows from the table require that most calculations to be done prior to changing table structure.\n            // Preparations must be done in the same enqueueChange callback to use the current table structure.\n            // 1. Preparation - get row-spanned cells that have to be modified after removing rows.\n            const { cellsToMove, cellsToTrim } = getCellsToMoveAndTrimOnRemoveRow(table, indexesObject);\n            // 2. Execution\n            // 2a. Move cells from removed rows that extends over a removed section - must be done before removing rows.\n            // This will fill any gaps in a rows below that previously were empty because of row-spanned cells.\n            if (cellsToMove.size) {\n                const rowAfterRemovedSection = last + 1;\n                moveCellsToRow(table, rowAfterRemovedSection, cellsToMove, writer);\n            }\n            // 2b. Remove all required rows.\n            for(let i = last; i >= first; i--){\n                writer.remove(table.getChild(i));\n            }\n            // 2c. Update cells from rows above that overlap removed section. Similar to step 2 but does not involve moving cells.\n            for (const { rowspan, cell } of cellsToTrim){\n                updateNumericAttribute('rowspan', rowspan, cell, writer);\n            }\n            // 2d. Adjust heading rows if removed rows were in a heading section.\n            updateHeadingRows(table, indexesObject, writer);\n            // 2e. Remove empty columns (without anchored cells) if there are any.\n            if (!removeEmptyColumns(table, this)) {\n                // If there wasn't any empty columns then we still need to check if this wasn't called\n                // because of cleaning empty rows and we only removed one of them.\n                removeEmptyRows(table, this);\n            }\n        });\n    }\n    /**\n\t * Removes columns from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including the `colspan` attribute of table cells overlapping removed columns\n\t * and table headings values.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).removeColumns( table, { at: 1, columns: 2 } );\n\t * ```\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *    0   1   2   3   4                       0   1   2\n\t *  ┌───────────────┬───┐                   ┌───────┬───┐\n\t *  │ a             │ b │                   │ a     │ b │\n\t *  │               ├───┤                   │       ├───┤\n\t *  │               │ c │                   │       │ c │\n\t *  ├───┬───┬───┬───┼───┤     will give:    ├───┬───┼───┤\n\t *  │ d │ e │ f │ g │ h │                   │ d │ g │ h │\n\t *  ├───┼───┼───┤   ├───┤                   ├───┤   ├───┤\n\t *  │ i │ j │ k │   │ l │                   │ i │   │ l │\n\t *  ├───┴───┴───┴───┴───┤                   ├───┴───┴───┤\n\t *  │ m                 │                   │ m         │\n\t *  └───────────────────┘                   └───────────┘\n\t *        ^---- remove from here, `at` = 1, `columns` = 2\n\t *\n\t * @param options.at The row index at which the removing columns will start.\n\t * @param options.columns The number of columns to remove.\n\t */ removeColumns(table, options) {\n        const model = this.editor.model;\n        const first = options.at;\n        const columnsToRemove = options.columns || 1;\n        const last = options.at + columnsToRemove - 1;\n        model.change((writer)=>{\n            adjustHeadingColumns(table, {\n                first,\n                last\n            }, writer);\n            const tableColumns = getTableColumnElements(table);\n            for(let removedColumnIndex = last; removedColumnIndex >= first; removedColumnIndex--){\n                for (const { cell, column, cellWidth } of [\n                    ...new TableWalker(table)\n                ]){\n                    // If colspaned cell overlaps removed column decrease its span.\n                    if (column <= removedColumnIndex && cellWidth > 1 && column + cellWidth > removedColumnIndex) {\n                        updateNumericAttribute('colspan', cellWidth - 1, cell, writer);\n                    } else if (column === removedColumnIndex) {\n                        // The cell in removed column has colspan of 1.\n                        writer.remove(cell);\n                    }\n                }\n                // If table has `tableColumn` elements, we need to update it manually.\n                // See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for details.\n                if (tableColumns[removedColumnIndex]) {\n                    // If the removed column is the first one then we need to add its width to the next column.\n                    // Otherwise we add it to the previous column.\n                    const adjacentColumn = removedColumnIndex === 0 ? tableColumns[1] : tableColumns[removedColumnIndex - 1];\n                    const removedColumnWidth = parseFloat(tableColumns[removedColumnIndex].getAttribute('columnWidth'));\n                    const adjacentColumnWidth = parseFloat(adjacentColumn.getAttribute('columnWidth'));\n                    writer.remove(tableColumns[removedColumnIndex]);\n                    // Add the removed column width (in %) to the adjacent column.\n                    writer.setAttribute('columnWidth', removedColumnWidth + adjacentColumnWidth + '%', adjacentColumn);\n                }\n            }\n            // Remove empty rows that could appear after removing columns.\n            if (!removeEmptyRows(table, this)) {\n                // If there wasn't any empty rows then we still need to check if this wasn't called\n                // because of cleaning empty columns and we only removed one of them.\n                removeEmptyColumns(table, this);\n            }\n        });\n    }\n    /**\n\t * Divides a table cell vertically into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating colspans of other cells in a column\n\t * and inserting cells (columns) after that cell.\n\t *\n\t * In the table below, if cell \"a\" is split into 3 cells:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +---+---+---+\n\t *  | d | e | f |\n\t *  +---+---+---+\n\t *\n\t * it will result in the table below:\n\t *\n\t *  +---+---+---+---+---+\n\t *  | a |   |   | b | c |\n\t *  +---+---+---+---+---+\n\t *  | d         | e | f |\n\t *  +---+---+---+---+---+\n\t *\n\t * So cell \"d\" will get its `colspan` updated to `3` and 2 cells will be added (2 columns will be created).\n\t *\n\t * Splitting a cell that already has a `colspan` attribute set will distribute the cell `colspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *  +---+---+---+\n\t *  | a         |\n\t *  +---+---+---+\n\t *  | b | c | d |\n\t *  +---+---+---+\n\t *\n\t * Splitting cell \"a\" with `colspan=3` into 2 cells will create 1 cell with a `colspan=a` and cell \"a\" that will have `colspan=2`:\n\t *\n\t *  +---+---+---+\n\t *  | a     |   |\n\t *  +---+---+---+\n\t *  | b | c | d |\n\t *  +---+---+---+\n\t */ splitCellVertically(tableCell, numberOfCells = 2) {\n        const model = this.editor.model;\n        const tableRow = tableCell.parent;\n        const table = tableRow.parent;\n        const rowspan = parseInt(tableCell.getAttribute('rowspan') || '1');\n        const colspan = parseInt(tableCell.getAttribute('colspan') || '1');\n        model.change((writer)=>{\n            // First check - the cell spans over multiple rows so before doing anything else just split this cell.\n            if (colspan > 1) {\n                // Get spans of new (inserted) cells and span to update of split cell.\n                const { newCellsSpan, updatedSpan } = breakSpanEvenly(colspan, numberOfCells);\n                updateNumericAttribute('colspan', updatedSpan, tableCell, writer);\n                // Each inserted cell will have the same attributes:\n                const newCellsAttributes = {};\n                // Do not store default value in the model.\n                if (newCellsSpan > 1) {\n                    newCellsAttributes.colspan = newCellsSpan;\n                }\n                // Copy rowspan of split cell.\n                if (rowspan > 1) {\n                    newCellsAttributes.rowspan = rowspan;\n                }\n                const cellsToInsert = colspan > numberOfCells ? numberOfCells - 1 : colspan - 1;\n                createCells(cellsToInsert, writer, writer.createPositionAfter(tableCell), newCellsAttributes);\n            }\n            // Second check - the cell has colspan of 1 or we need to create more cells then the currently one spans over.\n            if (colspan < numberOfCells) {\n                const cellsToInsert = numberOfCells - colspan;\n                // First step: expand cells on the same column as split cell.\n                const tableMap = [\n                    ...new TableWalker(table)\n                ];\n                // Get the column index of split cell.\n                const { column: splitCellColumn } = tableMap.find(({ cell })=>cell === tableCell);\n                // Find cells which needs to be expanded vertically - those on the same column or those that spans over split cell's column.\n                const cellsToUpdate = tableMap.filter(({ cell, cellWidth, column })=>{\n                    const isOnSameColumn = cell !== tableCell && column === splitCellColumn;\n                    const spansOverColumn = column < splitCellColumn && column + cellWidth > splitCellColumn;\n                    return isOnSameColumn || spansOverColumn;\n                });\n                // Expand cells vertically.\n                for (const { cell, cellWidth } of cellsToUpdate){\n                    writer.setAttribute('colspan', cellWidth + cellsToInsert, cell);\n                }\n                // Second step: create columns after split cell.\n                // Each inserted cell will have the same attributes:\n                const newCellsAttributes = {};\n                // Do not store default value in the model.\n                // Copy rowspan of split cell.\n                if (rowspan > 1) {\n                    newCellsAttributes.rowspan = rowspan;\n                }\n                createCells(cellsToInsert, writer, writer.createPositionAfter(tableCell), newCellsAttributes);\n                const headingColumns = table.getAttribute('headingColumns') || 0;\n                // Update heading section if split cell is in heading section.\n                if (headingColumns > splitCellColumn) {\n                    updateNumericAttribute('headingColumns', headingColumns + cellsToInsert, table, writer);\n                }\n            }\n        });\n    }\n    /**\n\t * Divides a table cell horizontally into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating rowspans of other cells in the row and inserting rows with a single cell\n\t * below.\n\t *\n\t * If in the table below cell \"b\" is split into 3 cells:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +---+---+---+\n\t *  | d | e | f |\n\t *  +---+---+---+\n\t *\n\t * It will result in the table below:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +   +---+   +\n\t *  |   |   |   |\n\t *  +   +---+   +\n\t *  |   |   |   |\n\t *  +---+---+---+\n\t *  | d | e | f |\n\t *  +---+---+---+\n\t *\n\t * So cells \"a\" and \"b\" will get their `rowspan` updated to `3` and 2 rows with a single cell will be added.\n\t *\n\t * Splitting a cell that already has a `rowspan` attribute set will distribute the cell `rowspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +   +---+---+\n\t *  |   | d | e |\n\t *  +   +---+---+\n\t *  |   | f | g |\n\t *  +   +---+---+\n\t *  |   | h | i |\n\t *  +---+---+---+\n\t *\n\t * Splitting cell \"a\" with `rowspan=4` into 3 cells will create 2 cells with a `rowspan=1` and cell \"a\" will have `rowspan=2`:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +   +---+---+\n\t *  |   | d | e |\n\t *  +---+---+---+\n\t *  |   | f | g |\n\t *  +---+---+---+\n\t *  |   | h | i |\n\t *  +---+---+---+\n\t */ splitCellHorizontally(tableCell, numberOfCells = 2) {\n        const model = this.editor.model;\n        const tableRow = tableCell.parent;\n        const table = tableRow.parent;\n        const splitCellRow = table.getChildIndex(tableRow);\n        const rowspan = parseInt(tableCell.getAttribute('rowspan') || '1');\n        const colspan = parseInt(tableCell.getAttribute('colspan') || '1');\n        model.change((writer)=>{\n            // First check - the cell spans over multiple rows so before doing anything else just split this cell.\n            if (rowspan > 1) {\n                // Cache table map before updating table.\n                const tableMap = [\n                    ...new TableWalker(table, {\n                        startRow: splitCellRow,\n                        endRow: splitCellRow + rowspan - 1,\n                        includeAllSlots: true\n                    })\n                ];\n                // Get spans of new (inserted) cells and span to update of split cell.\n                const { newCellsSpan, updatedSpan } = breakSpanEvenly(rowspan, numberOfCells);\n                updateNumericAttribute('rowspan', updatedSpan, tableCell, writer);\n                const { column: cellColumn } = tableMap.find(({ cell })=>cell === tableCell);\n                // Each inserted cell will have the same attributes:\n                const newCellsAttributes = {};\n                // Do not store default value in the model.\n                if (newCellsSpan > 1) {\n                    newCellsAttributes.rowspan = newCellsSpan;\n                }\n                // Copy colspan of split cell.\n                if (colspan > 1) {\n                    newCellsAttributes.colspan = colspan;\n                }\n                // Accumulator that stores distance from the last inserted cell span.\n                // It helps with evenly splitting larger cell spans (for example 10 cells collapsing into 3 cells).\n                // We split these cells into 3, 3, 4 cells and we have to call `createCells` only when distance between\n                // these cells is equal or greater than the new cells span size.\n                let distanceFromLastCellSpan = 0;\n                for (const tableSlot of tableMap){\n                    const { column, row } = tableSlot;\n                    // As both newly created cells and the split cell might have rowspan,\n                    // the insertion of new cells must go to appropriate rows:\n                    //\n                    // 1. It's a row after split cell + it's height.\n                    const isAfterSplitCell = row >= splitCellRow + updatedSpan;\n                    // 2. Is on the same column.\n                    const isOnSameColumn = column === cellColumn;\n                    // Reset distance from the last cell span if we are on the same column and we exceeded the new cells span size.\n                    if (distanceFromLastCellSpan >= newCellsSpan && isOnSameColumn) {\n                        distanceFromLastCellSpan = 0;\n                    }\n                    if (isAfterSplitCell && isOnSameColumn) {\n                        // Create new cells only if the distance from the last cell span is equal or greater than the new cells span.\n                        if (!distanceFromLastCellSpan) {\n                            createCells(1, writer, tableSlot.getPositionBefore(), newCellsAttributes);\n                        }\n                        // Increase the distance from the last cell span.\n                        distanceFromLastCellSpan++;\n                    }\n                }\n            }\n            // Second check - the cell has rowspan of 1 or we need to create more cells than the current cell spans over.\n            if (rowspan < numberOfCells) {\n                // We already split the cell in check one so here we split to the remaining number of cells only.\n                const cellsToInsert = numberOfCells - rowspan;\n                // This check is needed since we need to check if there are any cells from previous rows than spans over this cell's row.\n                const tableMap = [\n                    ...new TableWalker(table, {\n                        startRow: 0,\n                        endRow: splitCellRow\n                    })\n                ];\n                // First step: expand cells.\n                for (const { cell, cellHeight, row } of tableMap){\n                    // Expand rowspan of cells that are either:\n                    // - on the same row as current cell,\n                    // - or are below split cell row and overlaps that row.\n                    if (cell !== tableCell && row + cellHeight > splitCellRow) {\n                        const rowspanToSet = cellHeight + cellsToInsert;\n                        writer.setAttribute('rowspan', rowspanToSet, cell);\n                    }\n                }\n                // Second step: create rows with single cell below split cell.\n                const newCellsAttributes = {};\n                // Copy colspan of split cell.\n                if (colspan > 1) {\n                    newCellsAttributes.colspan = colspan;\n                }\n                createEmptyRows(writer, table, splitCellRow + 1, cellsToInsert, 1, newCellsAttributes);\n                // Update heading section if split cell is in heading section.\n                const headingRows = table.getAttribute('headingRows') || 0;\n                if (headingRows > splitCellRow) {\n                    updateNumericAttribute('headingRows', headingRows + cellsToInsert, table, writer);\n                }\n            }\n        });\n    }\n    /**\n\t * Returns the number of columns for a given table.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).getColumns( table );\n\t * ```\n\t *\n\t * @param table The table to analyze.\n\t */ getColumns(table) {\n        // Analyze first row only as all the rows should have the same width.\n        // Using the first row without checking if it's a tableRow because we expect\n        // that table will have only tableRow model elements at the beginning.\n        const row = table.getChild(0);\n        return [\n            ...row.getChildren()\n        ]// $marker elements can also be children of a row too (when TrackChanges is on). Don't include them in the count.\n        .filter((node)=>node.is('element', 'tableCell')).reduce((columns, row)=>{\n            const columnWidth = parseInt(row.getAttribute('colspan') || '1');\n            return columns + columnWidth;\n        }, 0);\n    }\n    /**\n\t * Returns the number of rows for a given table. Any other element present in the table model is omitted.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).getRows( table );\n\t * ```\n\t *\n\t * @param table The table to analyze.\n\t */ getRows(table) {\n        // Rowspan not included due to #6427.\n        return Array.from(table.getChildren()).reduce((rowCount, child)=>child.is('element', 'tableRow') ? rowCount + 1 : rowCount, 0);\n    }\n    /**\n\t * Creates an instance of the table walker.\n\t *\n\t * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.\n\t * It walks row by row and column by column in order to output values defined in the options.\n\t * By default it will output only the locations that are occupied by a cell. To include also spanned rows and columns,\n\t * pass the `includeAllSlots` option.\n\t *\n\t * @internal\n\t * @param table A table over which the walker iterates.\n\t * @param options An object with configuration.\n\t */ createTableWalker(table, options = {}) {\n        return new TableWalker(table, options);\n    }\n    /**\n\t * Returns all model table cells that are fully selected (from the outside)\n\t * within the provided model selection's ranges.\n\t *\n\t * To obtain the cells selected from the inside, use\n\t * {@link #getTableCellsContainingSelection}.\n\t */ getSelectedTableCells(selection) {\n        const cells = [];\n        for (const range of this.sortRanges(selection.getRanges())){\n            const element = range.getContainedElement();\n            if (element && element.is('element', 'tableCell')) {\n                cells.push(element);\n            }\n        }\n        return cells;\n    }\n    /**\n\t * Returns all model table cells that the provided model selection's ranges\n\t * {@link module:engine/model/range~Range#start} inside.\n\t *\n\t * To obtain the cells selected from the outside, use\n\t * {@link #getSelectedTableCells}.\n\t */ getTableCellsContainingSelection(selection) {\n        const cells = [];\n        for (const range of selection.getRanges()){\n            const cellWithSelection = range.start.findAncestor('tableCell');\n            if (cellWithSelection) {\n                cells.push(cellWithSelection);\n            }\n        }\n        return cells;\n    }\n    /**\n\t * Returns all model table cells that are either completely selected\n\t * by selection ranges or host selection range\n\t * {@link module:engine/model/range~Range#start start positions} inside them.\n\t *\n\t * Combines {@link #getTableCellsContainingSelection} and\n\t * {@link #getSelectedTableCells}.\n\t */ getSelectionAffectedTableCells(selection) {\n        const selectedCells = this.getSelectedTableCells(selection);\n        if (selectedCells.length) {\n            return selectedCells;\n        }\n        return this.getTableCellsContainingSelection(selection);\n    }\n    /**\n\t * Returns an object with the `first` and `last` row index contained in the given `tableCells`.\n\t *\n\t * ```ts\n\t * const selectedTableCells = getSelectedTableCells( editor.model.document.selection );\n\t *\n\t * const { first, last } = getRowIndexes( selectedTableCells );\n\t *\n\t * console.log( `Selected rows: ${ first } to ${ last }` );\n\t * ```\n\t *\n\t * @returns Returns an object with the `first` and `last` table row indexes.\n\t */ getRowIndexes(tableCells) {\n        const indexes = tableCells.map((cell)=>cell.parent.index);\n        return this._getFirstLastIndexesObject(indexes);\n    }\n    /**\n\t * Returns an object with the `first` and `last` column index contained in the given `tableCells`.\n\t *\n\t * ```ts\n\t * const selectedTableCells = getSelectedTableCells( editor.model.document.selection );\n\t *\n\t * const { first, last } = getColumnIndexes( selectedTableCells );\n\t *\n\t * console.log( `Selected columns: ${ first } to ${ last }` );\n\t * ```\n\t *\n\t * @returns Returns an object with the `first` and `last` table column indexes.\n\t */ getColumnIndexes(tableCells) {\n        const table = tableCells[0].findAncestor('table');\n        const tableMap = [\n            ...new TableWalker(table)\n        ];\n        const indexes = tableMap.filter((entry)=>tableCells.includes(entry.cell)).map((entry)=>entry.column);\n        return this._getFirstLastIndexesObject(indexes);\n    }\n    /**\n\t * Checks if the selection contains cells that do not exceed rectangular selection.\n\t *\n\t * In a table below:\n\t *\n\t *  ┌───┬───┬───┬───┐\n\t *  │ a │ b │ c │ d │\n\t *  ├───┴───┼───┤   │\n\t *  │ e     │ f │   │\n\t *  │       ├───┼───┤\n\t *  │       │ g │ h │\n\t *  └───────┴───┴───┘\n\t *\n\t * Valid selections are these which create a solid rectangle (without gaps), such as:\n\t *   - a, b (two horizontal cells)\n\t *   - c, f (two vertical cells)\n\t *   - a, b, e (cell \"e\" spans over four cells)\n\t *   - c, d, f (cell d spans over a cell in the row below)\n\t *\n\t * While an invalid selection would be:\n\t *   - a, c (the unselected cell \"b\" creates a gap)\n\t *   - f, g, h (cell \"d\" spans over a cell from the row of \"f\" cell - thus creates a gap)\n\t */ isSelectionRectangular(selectedTableCells) {\n        if (selectedTableCells.length < 2 || !this._areCellInTheSameTableSection(selectedTableCells)) {\n            return false;\n        }\n        // A valid selection is a fully occupied rectangle composed of table cells.\n        // Below we will calculate the area of a selected table cells and the area of valid selection.\n        // The area of a valid selection is defined by top-left and bottom-right cells.\n        const rows = new Set();\n        const columns = new Set();\n        let areaOfSelectedCells = 0;\n        for (const tableCell of selectedTableCells){\n            const { row, column } = this.getCellLocation(tableCell);\n            const rowspan = parseInt(tableCell.getAttribute('rowspan')) || 1;\n            const colspan = parseInt(tableCell.getAttribute('colspan')) || 1;\n            // Record row & column indexes of current cell.\n            rows.add(row);\n            columns.add(column);\n            // For cells that spans over multiple rows add also the last row that this cell spans over.\n            if (rowspan > 1) {\n                rows.add(row + rowspan - 1);\n            }\n            // For cells that spans over multiple columns add also the last column that this cell spans over.\n            if (colspan > 1) {\n                columns.add(column + colspan - 1);\n            }\n            areaOfSelectedCells += rowspan * colspan;\n        }\n        // We can only merge table cells that are in adjacent rows...\n        const areaOfValidSelection = getBiggestRectangleArea(rows, columns);\n        return areaOfValidSelection == areaOfSelectedCells;\n    }\n    /**\n\t * Returns array of sorted ranges.\n\t */ sortRanges(ranges) {\n        return Array.from(ranges).sort(compareRangeOrder);\n    }\n    /**\n\t * Helper method to get an object with `first` and `last` indexes from an unsorted array of indexes.\n\t */ _getFirstLastIndexesObject(indexes) {\n        const allIndexesSorted = indexes.sort((indexA, indexB)=>indexA - indexB);\n        const first = allIndexesSorted[0];\n        const last = allIndexesSorted[allIndexesSorted.length - 1];\n        return {\n            first,\n            last\n        };\n    }\n    /**\n\t * Checks if the selection does not mix a header (column or row) with other cells.\n\t *\n\t * For instance, in the table below valid selections consist of cells with the same letter only.\n\t * So, a-a (same heading row and column) or d-d (body cells) are valid while c-d or a-b are not.\n\t *\n\t * header columns\n\t *    ↓   ↓\n\t *  ┌───┬───┬───┬───┐\n\t *  │ a │ a │ b │ b │  ← header row\n\t *  ├───┼───┼───┼───┤\n\t *  │ c │ c │ d │ d │\n\t *  ├───┼───┼───┼───┤\n\t *  │ c │ c │ d │ d │\n\t *  └───┴───┴───┴───┘\n\t */ _areCellInTheSameTableSection(tableCells) {\n        const table = tableCells[0].findAncestor('table');\n        const rowIndexes = this.getRowIndexes(tableCells);\n        const headingRows = parseInt(table.getAttribute('headingRows')) || 0;\n        // Calculating row indexes is a bit cheaper so if this check fails we can't merge.\n        if (!this._areIndexesInSameSection(rowIndexes, headingRows)) {\n            return false;\n        }\n        const columnIndexes = this.getColumnIndexes(tableCells);\n        const headingColumns = parseInt(table.getAttribute('headingColumns')) || 0;\n        // Similarly cells must be in same column section.\n        return this._areIndexesInSameSection(columnIndexes, headingColumns);\n    }\n    /**\n\t * Unified check if table rows/columns indexes are in the same heading/body section.\n\t */ _areIndexesInSameSection({ first, last }, headingSectionSize) {\n        const firstCellIsInHeading = first < headingSectionSize;\n        const lastCellIsInHeading = last < headingSectionSize;\n        return firstCellIsInHeading === lastCellIsInHeading;\n    }\n}\n/**\n * Creates empty rows at the given index in an existing table.\n *\n * @param insertAt The row index of row insertion.\n * @param rows The number of rows to create.\n * @param tableCellToInsert The number of cells to insert in each row.\n */ function createEmptyRows(writer, table, insertAt, rows, tableCellToInsert, attributes = {}) {\n    for(let i = 0; i < rows; i++){\n        const tableRow = writer.createElement('tableRow');\n        writer.insert(tableRow, table, insertAt);\n        createCells(tableCellToInsert, writer, writer.createPositionAt(tableRow, 'end'), attributes);\n    }\n}\n/**\n * Creates cells at a given position.\n *\n * @param cells The number of cells to create\n */ function createCells(cells, writer, insertPosition, attributes = {}) {\n    for(let i = 0; i < cells; i++){\n        createEmptyTableCell(writer, insertPosition, attributes);\n    }\n}\n/**\n * Evenly distributes the span of a cell to a number of provided cells.\n * The resulting spans will always be integer values.\n *\n * For instance breaking a span of 7 into 3 cells will return:\n *\n * ```ts\n * { newCellsSpan: 2, updatedSpan: 3 }\n * ```\n *\n * as two cells will have a span of 2 and the remainder will go the first cell so its span will change to 3.\n *\n * @param span The span value do break.\n * @param numberOfCells The number of resulting spans.\n */ function breakSpanEvenly(span, numberOfCells) {\n    if (span < numberOfCells) {\n        return {\n            newCellsSpan: 1,\n            updatedSpan: 1\n        };\n    }\n    const newCellsSpan = Math.floor(span / numberOfCells);\n    const updatedSpan = span - newCellsSpan * numberOfCells + newCellsSpan;\n    return {\n        newCellsSpan,\n        updatedSpan\n    };\n}\n/**\n * Updates heading columns attribute if removing a row from head section.\n */ function adjustHeadingColumns(table, removedColumnIndexes, writer) {\n    const headingColumns = table.getAttribute('headingColumns') || 0;\n    if (headingColumns && removedColumnIndexes.first < headingColumns) {\n        const headingsRemoved = Math.min(headingColumns - 1 /* Other numbers are 0-based */ , removedColumnIndexes.last) - removedColumnIndexes.first + 1;\n        writer.setAttribute('headingColumns', headingColumns - headingsRemoved, table);\n    }\n}\n/**\n * Calculates a new heading rows value for removing rows from heading section.\n */ function updateHeadingRows(table, { first, last }, writer) {\n    const headingRows = table.getAttribute('headingRows') || 0;\n    if (first < headingRows) {\n        const newRows = last < headingRows ? headingRows - (last - first + 1) : first;\n        updateNumericAttribute('headingRows', newRows, table, writer, 0);\n    }\n}\n/**\n * Finds cells that will be:\n * - trimmed - Cells that are \"above\" removed rows sections and overlap the removed section - their rowspan must be trimmed.\n * - moved - Cells from removed rows section might stick out of. These cells are moved to the next row after a removed section.\n *\n * Sample table with overlapping & sticking out cells:\n *\n *      +----+----+----+----+----+\n *      | 00 | 01 | 02 | 03 | 04 |\n *      +----+    +    +    +    +\n *      | 10 |    |    |    |    |\n *      +----+----+    +    +    +\n *      | 20 | 21 |    |    |    | <-- removed row\n *      +    +    +----+    +    +\n *      |    |    | 32 |    |    | <-- removed row\n *      +----+    +    +----+    +\n *      | 40 |    |    | 43 |    |\n *      +----+----+----+----+----+\n *\n * In a table above:\n * - cells to trim: '02', '03' & '04'.\n * - cells to move: '21' & '32'.\n */ function getCellsToMoveAndTrimOnRemoveRow(table, { first, last }) {\n    const cellsToMove = new Map();\n    const cellsToTrim = [];\n    for (const { row, column, cellHeight, cell } of new TableWalker(table, {\n        endRow: last\n    })){\n        const lastRowOfCell = row + cellHeight - 1;\n        const isCellStickingOutFromRemovedRows = row >= first && row <= last && lastRowOfCell > last;\n        if (isCellStickingOutFromRemovedRows) {\n            const rowspanInRemovedSection = last - row + 1;\n            const rowSpanToSet = cellHeight - rowspanInRemovedSection;\n            cellsToMove.set(column, {\n                cell,\n                rowspan: rowSpanToSet\n            });\n        }\n        const isCellOverlappingRemovedRows = row < first && lastRowOfCell >= first;\n        if (isCellOverlappingRemovedRows) {\n            let rowspanAdjustment;\n            // Cell fully covers removed section - trim it by removed rows count.\n            if (lastRowOfCell >= last) {\n                rowspanAdjustment = last - first + 1;\n            } else {\n                rowspanAdjustment = lastRowOfCell - first + 1;\n            }\n            cellsToTrim.push({\n                cell,\n                rowspan: cellHeight - rowspanAdjustment\n            });\n        }\n    }\n    return {\n        cellsToMove,\n        cellsToTrim\n    };\n}\nfunction moveCellsToRow(table, targetRowIndex, cellsToMove, writer) {\n    const tableWalker = new TableWalker(table, {\n        includeAllSlots: true,\n        row: targetRowIndex\n    });\n    const tableRowMap = [\n        ...tableWalker\n    ];\n    const row = table.getChild(targetRowIndex);\n    let previousCell;\n    for (const { column, cell, isAnchor } of tableRowMap){\n        if (cellsToMove.has(column)) {\n            const { cell: cellToMove, rowspan } = cellsToMove.get(column);\n            const targetPosition = previousCell ? writer.createPositionAfter(previousCell) : writer.createPositionAt(row, 0);\n            writer.move(writer.createRangeOn(cellToMove), targetPosition);\n            updateNumericAttribute('rowspan', rowspan, cellToMove, writer);\n            previousCell = cellToMove;\n        } else if (isAnchor) {\n            // If cell is spanned then `cell` holds reference to overlapping cell. See ckeditor/ckeditor5#6502.\n            previousCell = cell;\n        }\n    }\n}\nfunction compareRangeOrder(rangeA, rangeB) {\n    // Since table cell ranges are disjoint, it's enough to check their start positions.\n    const posA = rangeA.start;\n    const posB = rangeB.start;\n    // Checking for equal position (returning 0) is not needed because this would be either:\n    // a. Intersecting range (not allowed by model)\n    // b. Collapsed range on the same position (allowed by model but should not happen).\n    return posA.isBefore(posB) ? -1 : 1;\n}\n/**\n * Calculates the area of a maximum rectangle that can span over the provided row & column indexes.\n */ function getBiggestRectangleArea(rows, columns) {\n    const rowsIndexes = Array.from(rows.values());\n    const columnIndexes = Array.from(columns.values());\n    const lastRow = Math.max(...rowsIndexes);\n    const firstRow = Math.min(...rowsIndexes);\n    const lastColumn = Math.max(...columnIndexes);\n    const firstColumn = Math.min(...columnIndexes);\n    return (lastRow - firstRow + 1) * (lastColumn - firstColumn + 1);\n}\n\n/**\n * The merge cells command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'mergeTableCells'` editor command.\n *\n * For example, to merge selected table cells:\n *\n * ```ts\n * editor.execute( 'mergeTableCells' );\n * ```\n */ class MergeCellsCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const selectedTableCells = tableUtils.getSelectedTableCells(this.editor.model.document.selection);\n        this.isEnabled = tableUtils.isSelectionRectangular(selectedTableCells);\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t */ execute() {\n        const model = this.editor.model;\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        model.change((writer)=>{\n            const selectedTableCells = tableUtils.getSelectedTableCells(model.document.selection);\n            // All cells will be merged into the first one.\n            const firstTableCell = selectedTableCells.shift();\n            // Update target cell dimensions.\n            const { mergeWidth, mergeHeight } = getMergeDimensions(firstTableCell, selectedTableCells, tableUtils);\n            updateNumericAttribute('colspan', mergeWidth, firstTableCell, writer);\n            updateNumericAttribute('rowspan', mergeHeight, firstTableCell, writer);\n            for (const tableCell of selectedTableCells){\n                mergeTableCells(tableCell, firstTableCell, writer);\n            }\n            const table = firstTableCell.findAncestor('table');\n            // Remove rows and columns that become empty (have no anchored cells).\n            removeEmptyRowsColumns(table, tableUtils);\n            writer.setSelection(firstTableCell, 'in');\n        });\n    }\n}\n/**\n *  Merges two table cells. It will ensure that after merging cells with empty paragraphs the resulting table cell will only have one\n * paragraph. If one of the merged table cells is empty, the merged table cell will have contents of the non-empty table cell.\n * If both are empty, the merged table cell will have only one empty paragraph.\n */ function mergeTableCells(cellBeingMerged, targetCell, writer) {\n    if (!isEmpty$1(cellBeingMerged)) {\n        if (isEmpty$1(targetCell)) {\n            writer.remove(writer.createRangeIn(targetCell));\n        }\n        writer.move(writer.createRangeIn(cellBeingMerged), writer.createPositionAt(targetCell, 'end'));\n    }\n    // Remove merged table cell.\n    writer.remove(cellBeingMerged);\n}\n/**\n * Checks if the passed table cell contains an empty paragraph.\n */ function isEmpty$1(tableCell) {\n    const firstTableChild = tableCell.getChild(0);\n    return tableCell.childCount == 1 && firstTableChild.is('element', 'paragraph') && firstTableChild.isEmpty;\n}\nfunction getMergeDimensions(firstTableCell, selectedTableCells, tableUtils) {\n    let maxWidthOffset = 0;\n    let maxHeightOffset = 0;\n    for (const tableCell of selectedTableCells){\n        const { row, column } = tableUtils.getCellLocation(tableCell);\n        maxWidthOffset = getMaxOffset(tableCell, column, maxWidthOffset, 'colspan');\n        maxHeightOffset = getMaxOffset(tableCell, row, maxHeightOffset, 'rowspan');\n    }\n    // Update table cell span attribute and merge set selection on a merged contents.\n    const { row: firstCellRow, column: firstCellColumn } = tableUtils.getCellLocation(firstTableCell);\n    const mergeWidth = maxWidthOffset - firstCellColumn;\n    const mergeHeight = maxHeightOffset - firstCellRow;\n    return {\n        mergeWidth,\n        mergeHeight\n    };\n}\nfunction getMaxOffset(tableCell, start, currentMaxOffset, which) {\n    const dimensionValue = parseInt(tableCell.getAttribute(which) || '1');\n    return Math.max(currentMaxOffset, start + dimensionValue);\n}\n\n/**\n * The select row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableRow'` editor command.\n *\n * To select the rows containing the selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'selectTableRow' );\n * ```\n */ class SelectRowCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        // It does not affect data so should be enabled in read-only mode.\n        this.affectsData = false;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection);\n        this.isEnabled = selectedCells.length > 0;\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const model = this.editor.model;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const referenceCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const rowIndexes = tableUtils.getRowIndexes(referenceCells);\n        const table = referenceCells[0].findAncestor('table');\n        const rangesToSelect = [];\n        for(let rowIndex = rowIndexes.first; rowIndex <= rowIndexes.last; rowIndex++){\n            for (const cell of table.getChild(rowIndex).getChildren()){\n                rangesToSelect.push(model.createRangeOn(cell));\n            }\n        }\n        model.change((writer)=>{\n            writer.setSelection(rangesToSelect);\n        });\n    }\n}\n\n/**\n * The select column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableColumn'` editor command.\n *\n * To select the columns containing the selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'selectTableColumn' );\n * ```\n */ class SelectColumnCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        // It does not affect data so should be enabled in read-only mode.\n        this.affectsData = false;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const selectedCells = tableUtils.getSelectionAffectedTableCells(this.editor.model.document.selection);\n        this.isEnabled = selectedCells.length > 0;\n    }\n    /**\n\t * @inheritDoc\n\t */ execute() {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const model = this.editor.model;\n        const referenceCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const firstCell = referenceCells[0];\n        const lastCell = referenceCells.pop();\n        const table = firstCell.findAncestor('table');\n        const startLocation = tableUtils.getCellLocation(firstCell);\n        const endLocation = tableUtils.getCellLocation(lastCell);\n        const startColumn = Math.min(startLocation.column, endLocation.column);\n        const endColumn = Math.max(startLocation.column, endLocation.column);\n        const rangesToSelect = [];\n        for (const cellInfo of new TableWalker(table, {\n            startColumn,\n            endColumn\n        })){\n            rangesToSelect.push(model.createRangeOn(cellInfo.cell));\n        }\n        model.change((writer)=>{\n            writer.setSelection(rangesToSelect);\n        });\n    }\n}\n\n/**\n * Injects a table layout post-fixer into the model.\n *\n * The role of the table layout post-fixer is to ensure that the table rows have the correct structure\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct structure means that:\n *\n * * All table rows have the same size.\n * * None of the table cells extend vertically beyond their section (either header or body).\n * * A table cell has always at least one element as a child.\n *\n * If the table structure is not correct, the post-fixer will automatically correct it in two steps:\n *\n * 1. It will clip table cells that extend beyond their section.\n * 2. It will add empty table cells to the rows that are narrower than the widest table row.\n *\n * ## Clipping overlapping table cells\n *\n * Such situation may occur when pasting a table (or a part of a table) to the editor from external sources.\n *\n * For example, see the following table which has a cell (FOO) with the rowspan attribute (2):\n *\n * ```xml\n * <table headingRows=\"1\">\n *   <tableRow>\n *     <tableCell rowspan=\"2\"><paragraph>FOO</paragraph></tableCell>\n *     <tableCell colspan=\"2\"><paragraph>BAR</paragraph></tableCell>\n *   </tableRow>\n *   <tableRow>\n *     <tableCell><paragraph>BAZ</paragraph></tableCell>\n *     <tableCell><paragraph>XYZ</paragraph></tableCell>\n *   </tableRow>\n * </table>\n * ```\n *\n * It will be rendered in the view as:\n *\n * ```xml\n * <table>\n *   <thead>\n *     <tr>\n *       <td rowspan=\"2\">FOO</td>\n *       <td colspan=\"2\">BAR</td>\n *     </tr>\n *   </thead>\n *   <tbody>\n *     <tr>\n *       <td>BAZ</td>\n *       <td>XYZ</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * In the above example the table will be rendered as a table with two rows: one in the header and second one in the body.\n * The table cell (FOO) cannot span over multiple rows as it would extend from the header to the body section.\n * The `rowspan` attribute must be changed to (1). The value (1) is the default value of the `rowspan` attribute\n * so the `rowspan` attribute will be removed from the model.\n *\n * The table cell with BAZ in the content will be in the first column of the table.\n *\n * ## Adding missing table cells\n *\n * The table post-fixer will insert empty table cells to equalize table row sizes (the number of columns).\n * The size of a table row is calculated by counting column spans of table cells, both horizontal (from the same row) and\n * vertical (from the rows above).\n *\n * In the above example, the table row in the body section of the table is narrower then the row from the header: it has two cells\n * with the default colspan (1). The header row has one cell with colspan (1) and the second with colspan (2).\n * The table cell (FOO) does not extend beyond the head section (and as such will be fixed in the first step of this post-fixer).\n * The post-fixer will add a missing table cell to the row in the body section of the table.\n *\n * The table from the above example will be fixed and rendered to the view as below:\n *\n * ```xml\n * <table>\n *   <thead>\n *     <tr>\n *       <td rowspan=\"2\">FOO</td>\n *       <td colspan=\"2\">BAR</td>\n *     </tr>\n *   </thead>\n *   <tbody>\n *     <tr>\n *       <td>BAZ</td>\n *       <td>XYZ</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * ## Collaboration and undo - Expectations vs post-fixer results\n *\n * The table post-fixer only ensures proper structure without a deeper analysis of the nature of the change. As such, it might lead\n * to a structure which was not intended by the user. In particular, it will also fix undo steps (in conjunction with collaboration)\n * in which the editor content might not return to the original state.\n *\n * This will usually happen when one or more users change the size of the table.\n *\n * As an example see the table below:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * and the user actions:\n *\n * 1. Both users have a table with two rows and two columns.\n * 2. User A adds a column at the end of the table. This will insert empty table cells to two rows.\n * 3. User B adds a row at the end of the table. This will insert a row with two empty table cells.\n * 4. Both users will have a table as below:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * The last row is shorter then others so the table post-fixer will add an empty row to the last row:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by the post-fixer)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * Unfortunately undo does not know the nature of the changes and depending on which user applies the post-fixer changes, undoing them\n * might lead to a broken table. If User B undoes inserting the column to the table, the undo engine will undo only the operations of\n * inserting empty cells to rows from the initial table state (row 1 and 2) but the cell in the post-fixed row will remain:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by a post-fixer)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * After undo, the table post-fixer will detect that two rows are shorter than others and will fix the table to:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *       <td>(empty, inserted by a post-fixer after undo)</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *       <td>(empty, inserted by a post-fixer after undo)</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by a post-fixer)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n */ function injectTableLayoutPostFixer(model) {\n    model.document.registerPostFixer((writer)=>tableLayoutPostFixer(writer, model));\n}\n/**\n * The table layout post-fixer.\n */ function tableLayoutPostFixer(writer, model) {\n    const changes = model.document.differ.getChanges();\n    let wasFixed = false;\n    // Do not analyze the same table more then once - may happen for multiple changes in the same table.\n    const analyzedTables = new Set();\n    for (const entry of changes){\n        let table = null;\n        if (entry.type == 'insert' && entry.name == 'table') {\n            table = entry.position.nodeAfter;\n        }\n        // Fix table on adding/removing table cells and rows.\n        if ((entry.type == 'insert' || entry.type == 'remove') && (entry.name == 'tableRow' || entry.name == 'tableCell')) {\n            table = entry.position.findAncestor('table');\n        }\n        // Fix table on any table's attribute change - including attributes of table cells.\n        if (isTableAttributeEntry(entry)) {\n            table = entry.range.start.findAncestor('table');\n        }\n        if (table && !analyzedTables.has(table)) {\n            // Step 1: correct rowspans of table cells if necessary.\n            // The wasFixed flag should be true if any of tables in batch was fixed - might be more then one.\n            wasFixed = fixTableCellsRowspan(table, writer) || wasFixed;\n            // Step 2: fix table rows sizes.\n            wasFixed = fixTableRowsSizes(table, writer) || wasFixed;\n            analyzedTables.add(table);\n        }\n    }\n    return wasFixed;\n}\n/**\n * Fixes the invalid value of the `rowspan` attribute because a table cell cannot vertically extend beyond the table section it belongs to.\n *\n * @returns Returns `true` if the table was fixed.\n */ function fixTableCellsRowspan(table, writer) {\n    let wasFixed = false;\n    const cellsToTrim = findCellsToTrim(table);\n    if (cellsToTrim.length) {\n        // @if CK_DEBUG_TABLE // console.log( `Post-fixing table: trimming cells row-spans (${ cellsToTrim.length }).` );\n        wasFixed = true;\n        for (const data of cellsToTrim){\n            updateNumericAttribute('rowspan', data.rowspan, data.cell, writer, 1);\n        }\n    }\n    return wasFixed;\n}\n/**\n * Makes all table rows in a table the same size.\n *\n * @returns Returns `true` if the table was fixed.\n */ function fixTableRowsSizes(table, writer) {\n    let wasFixed = false;\n    const childrenLengths = getChildrenLengths(table);\n    const rowsToRemove = [];\n    // Find empty rows.\n    for (const [rowIndex, size] of childrenLengths.entries()){\n        // Ignore all non-row models.\n        if (!size && table.getChild(rowIndex).is('element', 'tableRow')) {\n            rowsToRemove.push(rowIndex);\n        }\n    }\n    // Remove empty rows.\n    if (rowsToRemove.length) {\n        // @if CK_DEBUG_TABLE // console.log( `Post-fixing table: remove empty rows (${ rowsToRemove.length }).` );\n        wasFixed = true;\n        for (const rowIndex of rowsToRemove.reverse()){\n            writer.remove(table.getChild(rowIndex));\n            childrenLengths.splice(rowIndex, 1);\n        }\n    }\n    // Filter out everything that's not a table row.\n    const rowsLengths = childrenLengths.filter((row, rowIndex)=>table.getChild(rowIndex).is('element', 'tableRow'));\n    // Verify if all the rows have the same number of columns.\n    const tableSize = rowsLengths[0];\n    const isValid = rowsLengths.every((length)=>length === tableSize);\n    if (!isValid) {\n        // @if CK_DEBUG_TABLE // console.log( 'Post-fixing table: adding missing cells.' );\n        // Find the maximum number of columns.\n        const maxColumns = rowsLengths.reduce((prev, current)=>current > prev ? current : prev, 0);\n        for (const [rowIndex, size] of rowsLengths.entries()){\n            const columnsToInsert = maxColumns - size;\n            if (columnsToInsert) {\n                for(let i = 0; i < columnsToInsert; i++){\n                    createEmptyTableCell(writer, writer.createPositionAt(table.getChild(rowIndex), 'end'));\n                }\n                wasFixed = true;\n            }\n        }\n    }\n    return wasFixed;\n}\n/**\n * Searches for table cells that extend beyond the table section to which they belong to. It will return an array of objects\n * that stores table cells to be trimmed and the correct value of the `rowspan` attribute to set.\n */ function findCellsToTrim(table) {\n    const headingRows = parseInt(table.getAttribute('headingRows') || '0');\n    const maxRows = Array.from(table.getChildren()).reduce((count, row)=>row.is('element', 'tableRow') ? count + 1 : count, 0);\n    const cellsToTrim = [];\n    for (const { row, cell, cellHeight } of new TableWalker(table)){\n        // Skip cells that do not expand over its row.\n        if (cellHeight < 2) {\n            continue;\n        }\n        const isInHeader = row < headingRows;\n        // Row limit is either end of header section or whole table as table body is after the header.\n        const rowLimit = isInHeader ? headingRows : maxRows;\n        // If table cell expands over its limit reduce it height to proper value.\n        if (row + cellHeight > rowLimit) {\n            const newRowspan = rowLimit - row;\n            cellsToTrim.push({\n                cell,\n                rowspan: newRowspan\n            });\n        }\n    }\n    return cellsToTrim;\n}\n/**\n * Returns an array with lengths of rows assigned to the corresponding row index.\n */ function getChildrenLengths(table) {\n    // TableWalker will not provide items for the empty rows, we need to pre-fill this array.\n    const lengths = new Array(table.childCount).fill(0);\n    for (const { rowIndex } of new TableWalker(table, {\n        includeAllSlots: true\n    })){\n        lengths[rowIndex]++;\n    }\n    return lengths;\n}\n/**\n * Checks if the differ entry for an attribute change is one of the table's attributes.\n */ function isTableAttributeEntry(entry) {\n    if (entry.type !== 'attribute') {\n        return false;\n    }\n    const key = entry.attributeKey;\n    return key === 'headingRows' || key === 'colspan' || key === 'rowspan';\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module table/converters/table-cell-paragraph-post-fixer\n */ /**\n * Injects a table cell post-fixer into the model which inserts a `paragraph` element into empty table cells.\n *\n * A table cell must contain at least one block element as a child. An empty table cell will have an empty `paragraph` as a child.\n *\n * ```xml\n * <table>\n *   <tableRow>\n *      <tableCell></tableCell>\n *   </tableRow>\n * </table>\n * ```\n *\n * Will be fixed to:\n *\n * ```xml\n * <table>\n *   <tableRow>\n *      <tableCell><paragraph></paragraph></tableCell>\n *   </tableRow>\n * </table>\n * ```\n */ function injectTableCellParagraphPostFixer(model) {\n    model.document.registerPostFixer((writer)=>tableCellContentsPostFixer(writer, model));\n}\n/**\n * The table cell contents post-fixer.\n */ function tableCellContentsPostFixer(writer, model) {\n    const changes = model.document.differ.getChanges();\n    let wasFixed = false;\n    for (const entry of changes){\n        if (entry.type == 'insert' && entry.name == 'table') {\n            wasFixed = fixTable(entry.position.nodeAfter, writer) || wasFixed;\n        }\n        if (entry.type == 'insert' && entry.name == 'tableRow') {\n            wasFixed = fixTableRow(entry.position.nodeAfter, writer) || wasFixed;\n        }\n        if (entry.type == 'insert' && entry.name == 'tableCell') {\n            wasFixed = fixTableCellContent(entry.position.nodeAfter, writer) || wasFixed;\n        }\n        if ((entry.type == 'remove' || entry.type == 'insert') && checkTableCellChange(entry)) {\n            wasFixed = fixTableCellContent(entry.position.parent, writer) || wasFixed;\n        }\n    }\n    return wasFixed;\n}\n/**\n * Fixes all table cells in a table.\n */ function fixTable(table, writer) {\n    let wasFixed = false;\n    for (const row of table.getChildren()){\n        if (row.is('element', 'tableRow')) {\n            wasFixed = fixTableRow(row, writer) || wasFixed;\n        }\n    }\n    return wasFixed;\n}\n/**\n * Fixes all table cells in a table row.\n */ function fixTableRow(tableRow, writer) {\n    let wasFixed = false;\n    for (const tableCell of tableRow.getChildren()){\n        wasFixed = fixTableCellContent(tableCell, writer) || wasFixed;\n    }\n    return wasFixed;\n}\n/**\n * Fixes all table cell content by:\n * - Adding a paragraph to a table cell without any child.\n * - Wrapping direct $text in a `<paragraph>`.\n */ function fixTableCellContent(tableCell, writer) {\n    // Insert paragraph to an empty table cell.\n    if (tableCell.childCount == 0) {\n        // @if CK_DEBUG_TABLE // console.log( 'Post-fixing table: insert paragraph in empty cell.' );\n        writer.insertElement('paragraph', tableCell);\n        return true;\n    }\n    // Check table cell children for directly placed text nodes.\n    // Temporary solution. See https://github.com/ckeditor/ckeditor5/issues/1464.\n    const textNodes = Array.from(tableCell.getChildren()).filter((child)=>child.is('$text'));\n    // @if CK_DEBUG_TABLE // textNodes.length && console.log( 'Post-fixing table: wrap cell content with paragraph.' );\n    for (const child of textNodes){\n        writer.wrap(writer.createRangeOn(child), 'paragraph');\n    }\n    // Return true when there were text nodes to fix.\n    return !!textNodes.length;\n}\n/**\n * Checks if a differ change should fix the table cell. This happens on:\n * - Removing content from the table cell (i.e. `tableCell` can be left empty).\n * - Adding a text node directly into a table cell.\n */ function checkTableCellChange(entry) {\n    if (!entry.position.parent.is('element', 'tableCell')) {\n        return false;\n    }\n    return entry.type == 'insert' && entry.name == '$text' || entry.type == 'remove';\n}\n\n/**\n * A table headings refresh handler which marks the table cells or rows in the differ to have it re-rendered\n * if the headings attribute changed.\n *\n * Table heading rows and heading columns are represented in the model by a `headingRows` and `headingColumns` attributes.\n *\n * When table headings attribute changes, all the cells/rows are marked to re-render to change between `<td>` and `<th>`.\n */ function tableHeadingsRefreshHandler(model, editing) {\n    const differ = model.document.differ;\n    for (const change of differ.getChanges()){\n        let table;\n        let isRowChange = false;\n        if (change.type == 'attribute') {\n            const element = change.range.start.nodeAfter;\n            if (!element || !element.is('element', 'table')) {\n                continue;\n            }\n            if (change.attributeKey != 'headingRows' && change.attributeKey != 'headingColumns') {\n                continue;\n            }\n            table = element;\n            isRowChange = change.attributeKey == 'headingRows';\n        } else if (change.name == 'tableRow' || change.name == 'tableCell') {\n            table = change.position.findAncestor('table');\n            isRowChange = change.name == 'tableRow';\n        }\n        if (!table) {\n            continue;\n        }\n        const headingRows = table.getAttribute('headingRows') || 0;\n        const headingColumns = table.getAttribute('headingColumns') || 0;\n        const tableWalker = new TableWalker(table);\n        for (const tableSlot of tableWalker){\n            const isHeading = tableSlot.row < headingRows || tableSlot.column < headingColumns;\n            const expectedElementName = isHeading ? 'th' : 'td';\n            const viewElement = editing.mapper.toViewElement(tableSlot.cell);\n            if (viewElement && viewElement.is('element') && viewElement.name != expectedElementName) {\n                editing.reconvertItem(isRowChange ? tableSlot.cell.parent : tableSlot.cell);\n            }\n        }\n    }\n}\n\n/**\n * A table cell refresh handler which marks the table cell in the differ to have it re-rendered.\n *\n * Model `paragraph` inside a table cell can be rendered as `<span>` or `<p>`. It is rendered as `<span>` if this is the only block\n * element in that table cell and it does not have any attributes. It is rendered as `<p>` otherwise.\n *\n * When table cell content changes, for example a second `paragraph` element is added, we need to ensure that the first `paragraph` is\n * re-rendered so it changes from `<span>` to `<p>`. The easiest way to do it is to re-render the entire table cell.\n */ function tableCellRefreshHandler(model, editing) {\n    const differ = model.document.differ;\n    // Stores cells to be refreshed, so the table cell will be refreshed once for multiple changes.\n    const cellsToCheck = new Set();\n    for (const change of differ.getChanges()){\n        const parent = change.type == 'attribute' ? change.range.start.parent : change.position.parent;\n        if (parent.is('element', 'tableCell')) {\n            cellsToCheck.add(parent);\n        }\n    }\n    for (const tableCell of cellsToCheck.values()){\n        const paragraphsToRefresh = Array.from(tableCell.getChildren()).filter((child)=>shouldRefresh(child, editing.mapper));\n        for (const paragraph of paragraphsToRefresh){\n            editing.reconvertItem(paragraph);\n        }\n    }\n}\n/**\n * Check if given model element needs refreshing.\n */ function shouldRefresh(child, mapper) {\n    if (!child.is('element', 'paragraph')) {\n        return false;\n    }\n    const viewElement = mapper.toViewElement(child);\n    if (!viewElement) {\n        return false;\n    }\n    return isSingleParagraphWithoutAttributes(child) !== viewElement.is('element', 'span');\n}\n\n/**\n * The table editing feature.\n */ class TableEditing extends Plugin {\n    /**\n\t * Handlers for creating additional slots in the table.\n\t */ _additionalSlots;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._additionalSlots = [];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const schema = model.schema;\n        const conversion = editor.conversion;\n        const tableUtils = editor.plugins.get(TableUtils);\n        schema.register('table', {\n            inheritAllFrom: '$blockObject',\n            allowAttributes: [\n                'headingRows',\n                'headingColumns'\n            ]\n        });\n        schema.register('tableRow', {\n            allowIn: 'table',\n            isLimit: true\n        });\n        schema.register('tableCell', {\n            allowContentOf: '$container',\n            allowIn: 'tableRow',\n            allowAttributes: [\n                'colspan',\n                'rowspan'\n            ],\n            isLimit: true,\n            isSelectable: true\n        });\n        // Figure conversion.\n        conversion.for('upcast').add(upcastTableFigure());\n        // Table conversion.\n        conversion.for('upcast').add(upcastTable());\n        conversion.for('editingDowncast').elementToStructure({\n            model: {\n                name: 'table',\n                attributes: [\n                    'headingRows'\n                ]\n            },\n            view: downcastTable(tableUtils, {\n                asWidget: true,\n                additionalSlots: this._additionalSlots\n            })\n        });\n        conversion.for('dataDowncast').elementToStructure({\n            model: {\n                name: 'table',\n                attributes: [\n                    'headingRows'\n                ]\n            },\n            view: downcastTable(tableUtils, {\n                additionalSlots: this._additionalSlots\n            })\n        });\n        // Table row conversion.\n        conversion.for('upcast').elementToElement({\n            model: 'tableRow',\n            view: 'tr'\n        });\n        conversion.for('upcast').add(skipEmptyTableRow());\n        conversion.for('downcast').elementToElement({\n            model: 'tableRow',\n            view: downcastRow()\n        });\n        // Table cell conversion.\n        conversion.for('upcast').elementToElement({\n            model: 'tableCell',\n            view: 'td'\n        });\n        conversion.for('upcast').elementToElement({\n            model: 'tableCell',\n            view: 'th'\n        });\n        conversion.for('upcast').add(ensureParagraphInTableCell('td'));\n        conversion.for('upcast').add(ensureParagraphInTableCell('th'));\n        conversion.for('editingDowncast').elementToElement({\n            model: 'tableCell',\n            view: downcastCell({\n                asWidget: true\n            })\n        });\n        conversion.for('dataDowncast').elementToElement({\n            model: 'tableCell',\n            view: downcastCell()\n        });\n        // Duplicates code - needed to properly refresh paragraph inside a table cell.\n        conversion.for('editingDowncast').elementToElement({\n            model: 'paragraph',\n            view: convertParagraphInTableCell({\n                asWidget: true\n            }),\n            converterPriority: 'high'\n        });\n        conversion.for('dataDowncast').elementToElement({\n            model: 'paragraph',\n            view: convertParagraphInTableCell(),\n            converterPriority: 'high'\n        });\n        // Table attributes conversion.\n        conversion.for('downcast').attributeToAttribute({\n            model: 'colspan',\n            view: 'colspan'\n        });\n        conversion.for('upcast').attributeToAttribute({\n            model: {\n                key: 'colspan',\n                value: upcastCellSpan('colspan')\n            },\n            view: 'colspan'\n        });\n        conversion.for('downcast').attributeToAttribute({\n            model: 'rowspan',\n            view: 'rowspan'\n        });\n        conversion.for('upcast').attributeToAttribute({\n            model: {\n                key: 'rowspan',\n                value: upcastCellSpan('rowspan')\n            },\n            view: 'rowspan'\n        });\n        // Define the config.\n        editor.config.define('table.defaultHeadings.rows', 0);\n        editor.config.define('table.defaultHeadings.columns', 0);\n        // Define all the commands.\n        editor.commands.add('insertTable', new InsertTableCommand(editor));\n        editor.commands.add('insertTableRowAbove', new InsertRowCommand(editor, {\n            order: 'above'\n        }));\n        editor.commands.add('insertTableRowBelow', new InsertRowCommand(editor, {\n            order: 'below'\n        }));\n        editor.commands.add('insertTableColumnLeft', new InsertColumnCommand(editor, {\n            order: 'left'\n        }));\n        editor.commands.add('insertTableColumnRight', new InsertColumnCommand(editor, {\n            order: 'right'\n        }));\n        editor.commands.add('removeTableRow', new RemoveRowCommand(editor));\n        editor.commands.add('removeTableColumn', new RemoveColumnCommand(editor));\n        editor.commands.add('splitTableCellVertically', new SplitCellCommand(editor, {\n            direction: 'vertically'\n        }));\n        editor.commands.add('splitTableCellHorizontally', new SplitCellCommand(editor, {\n            direction: 'horizontally'\n        }));\n        editor.commands.add('mergeTableCells', new MergeCellsCommand(editor));\n        editor.commands.add('mergeTableCellRight', new MergeCellCommand(editor, {\n            direction: 'right'\n        }));\n        editor.commands.add('mergeTableCellLeft', new MergeCellCommand(editor, {\n            direction: 'left'\n        }));\n        editor.commands.add('mergeTableCellDown', new MergeCellCommand(editor, {\n            direction: 'down'\n        }));\n        editor.commands.add('mergeTableCellUp', new MergeCellCommand(editor, {\n            direction: 'up'\n        }));\n        editor.commands.add('setTableColumnHeader', new SetHeaderColumnCommand(editor));\n        editor.commands.add('setTableRowHeader', new SetHeaderRowCommand(editor));\n        editor.commands.add('selectTableRow', new SelectRowCommand(editor));\n        editor.commands.add('selectTableColumn', new SelectColumnCommand(editor));\n        injectTableLayoutPostFixer(model);\n        injectTableCellParagraphPostFixer(model);\n        this.listenTo(model.document, 'change:data', ()=>{\n            tableHeadingsRefreshHandler(model, editor.editing);\n            tableCellRefreshHandler(model, editor.editing);\n        });\n    }\n    /**\n\t * Registers downcast handler for the additional table slot.\n\t */ registerAdditionalSlot(slotHandler) {\n        this._additionalSlots.push(slotHandler);\n    }\n}\n/**\n * Returns fixed colspan and rowspan attrbutes values.\n *\n * @param type colspan or rowspan.\n * @returns conversion value function.\n */ function upcastCellSpan(type) {\n    return (cell)=>{\n        const span = parseInt(cell.getAttribute(type));\n        if (Number.isNaN(span) || span <= 0) {\n            return null;\n        }\n        return span;\n    };\n}\n\n/**\n * The table size view.\n *\n * It renders a 10x10 grid to choose the inserted table size.\n */ class InsertTableView extends View {\n    /**\n\t * A collection of table size box items.\n\t */ items;\n    /**\n\t * Listen to `keydown` events fired in this view's main element.\n\t */ keystrokes;\n    /**\n\t * Tracks information about the DOM focus in the grid.\n\t */ focusTracker;\n    /**\n\t * @inheritDoc\n\t */ constructor(locale){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.items = this._createGridCollection();\n        this.keystrokes = new KeystrokeHandler();\n        this.focusTracker = new FocusTracker();\n        this.set('rows', 0);\n        this.set('columns', 0);\n        this.bind('label').to(this, 'columns', this, 'rows', (columns, rows)=>`${rows} × ${columns}`);\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck'\n                ]\n            },\n            children: [\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck-insert-table-dropdown__grid'\n                        ]\n                    },\n                    on: {\n                        'mouseover@.ck-insert-table-dropdown-grid-box': bind.to('boxover')\n                    },\n                    children: this.items\n                },\n                {\n                    tag: 'div',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-insert-table-dropdown__label'\n                        ],\n                        'aria-hidden': true\n                    },\n                    children: [\n                        {\n                            text: bind.to('label')\n                        }\n                    ]\n                }\n            ],\n            on: {\n                mousedown: bind.to((evt)=>{\n                    evt.preventDefault();\n                }),\n                click: bind.to(()=>{\n                    this.fire('execute');\n                })\n            }\n        });\n        // #rows and #columns are set via changes to #focusTracker on mouse over.\n        this.on('boxover', (evt, domEvt)=>{\n            const { row, column } = domEvt.target.dataset;\n            this.items.get((parseInt(row, 10) - 1) * 10 + (parseInt(column, 10) - 1)).focus();\n        });\n        // This allows the #rows and #columns to be updated when:\n        // * the user navigates the grid using the keyboard,\n        // * the user moves the mouse over grid items.\n        this.focusTracker.on('change:focusedElement', (evt, name, focusedElement)=>{\n            if (!focusedElement) {\n                return;\n            }\n            const { row, column } = focusedElement.dataset;\n            // As row & column indexes are zero-based transform it to number of selected rows & columns.\n            this.set({\n                rows: parseInt(row),\n                columns: parseInt(column)\n            });\n        });\n        this.on('change:columns', ()=>this._highlightGridBoxes());\n        this.on('change:rows', ()=>this._highlightGridBoxes());\n    }\n    render() {\n        super.render();\n        addKeyboardHandlingForGrid({\n            keystrokeHandler: this.keystrokes,\n            focusTracker: this.focusTracker,\n            gridItems: this.items,\n            numberOfColumns: 10,\n            uiLanguageDirection: this.locale && this.locale.uiLanguageDirection\n        });\n        for (const item of this.items){\n            this.focusTracker.add(item.element);\n        }\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * Resets the rows and columns selection.\n\t */ reset() {\n        this.set({\n            rows: 1,\n            columns: 1\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ focus() {\n        this.items.get(0).focus();\n    }\n    /**\n\t * @inheritDoc\n\t */ focusLast() {\n        this.items.get(0).focus();\n    }\n    /**\n\t * Highlights grid boxes depending on rows and columns selected.\n\t */ _highlightGridBoxes() {\n        const rows = this.rows;\n        const columns = this.columns;\n        this.items.map((boxView, index)=>{\n            // Translate box index to the row & column index.\n            const itemRow = Math.floor(index / 10);\n            const itemColumn = index % 10;\n            // Grid box is highlighted when its row & column index belongs to selected number of rows & columns.\n            const isOn = itemRow < rows && itemColumn < columns;\n            boxView.set('isOn', isOn);\n        });\n    }\n    /**\n\t * Creates a new Button for the grid.\n\t *\n\t * @param locale The locale instance.\n\t * @param row Row number.\n\t * @param column Column number.\n\t * @param label The grid button label.\n\t */ _createGridButton(locale, row, column, label) {\n        const button = new ButtonView(locale);\n        button.set({\n            label,\n            class: 'ck-insert-table-dropdown-grid-box'\n        });\n        button.extendTemplate({\n            attributes: {\n                'data-row': row,\n                'data-column': column\n            }\n        });\n        return button;\n    }\n    /**\n\t * @returns A view collection containing boxes to be placed in a table grid.\n\t */ _createGridCollection() {\n        const boxes = [];\n        // Add grid boxes to table selection view.\n        for(let index = 0; index < 100; index++){\n            const row = Math.floor(index / 10);\n            const column = index % 10;\n            const label = `${row + 1} × ${column + 1}`;\n            boxes.push(this._createGridButton(this.locale, row + 1, column + 1, label));\n        }\n        return this.createCollection(boxes);\n    }\n}\n\nvar tableColumnIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M18 7v1H2V7h16zm0 5v1H2v-1h16z\\\" opacity=\\\".6\\\"/><path d=\\\"M14 1v18a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1zm-2 1H8v4h4V2zm0 6H8v4h4V8zm0 6H8v4h4v-4z\\\"/></svg>\";\n\nvar tableRowIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 2h1v16H7V2zm5 0h1v16h-1V2z\\\" opacity=\\\".6\\\"/><path d=\\\"M1 6h18a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm1 2v4h4V8H2zm6 0v4h4V8H8zm6 0v4h4V8h-4z\\\"/></svg>\";\n\nvar tableMergeCellIcon = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 2h1v16H7V2zm5 0h1v7h-1V2zm6 5v1H2V7h16zM8 12v1H2v-1h6z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 7h12a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1zm1 2v9h10V9H8z\\\"/></svg>\";\n\n/**\n * The table UI plugin. It introduces:\n *\n * * The `'insertTable'` dropdown,\n * * The `'menuBar:insertTable'` menu bar menu,\n * * The `'tableColumn'` dropdown,\n * * The `'tableRow'` dropdown,\n * * The `'mergeTableCells'` split button.\n *\n * The `'tableColumn'`, `'tableRow'` and `'mergeTableCells'` dropdowns work best with {@link module:table/tabletoolbar~TableToolbar}.\n */ class TableUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = this.editor.t;\n        const contentLanguageDirection = editor.locale.contentLanguageDirection;\n        const isContentLtr = contentLanguageDirection === 'ltr';\n        editor.ui.componentFactory.add('insertTable', (locale)=>{\n            const command = editor.commands.get('insertTable');\n            const dropdownView = createDropdown(locale);\n            dropdownView.bind('isEnabled').to(command);\n            // Decorate dropdown's button.\n            dropdownView.buttonView.set({\n                icon: icons.table,\n                label: t('Insert table'),\n                tooltip: true\n            });\n            let insertTableView;\n            dropdownView.on('change:isOpen', ()=>{\n                if (insertTableView) {\n                    return;\n                }\n                // Prepare custom view for dropdown's panel.\n                insertTableView = new InsertTableView(locale);\n                dropdownView.panelView.children.add(insertTableView);\n                insertTableView.delegate('execute').to(dropdownView);\n                dropdownView.on('execute', ()=>{\n                    editor.execute('insertTable', {\n                        rows: insertTableView.rows,\n                        columns: insertTableView.columns\n                    });\n                    editor.editing.view.focus();\n                });\n            });\n            return dropdownView;\n        });\n        editor.ui.componentFactory.add('menuBar:insertTable', (locale)=>{\n            const command = editor.commands.get('insertTable');\n            const menuView = new MenuBarMenuView(locale);\n            const insertTableView = new InsertTableView(locale);\n            insertTableView.delegate('execute').to(menuView);\n            menuView.on('change:isOpen', (event, name, isOpen)=>{\n                if (!isOpen) {\n                    insertTableView.reset();\n                }\n            });\n            insertTableView.on('execute', ()=>{\n                editor.execute('insertTable', {\n                    rows: insertTableView.rows,\n                    columns: insertTableView.columns\n                });\n                editor.editing.view.focus();\n            });\n            menuView.buttonView.set({\n                label: t('Table'),\n                icon: icons.table\n            });\n            menuView.panelView.children.add(insertTableView);\n            menuView.bind('isEnabled').to(command);\n            return menuView;\n        });\n        editor.ui.componentFactory.add('tableColumn', (locale)=>{\n            const options = [\n                {\n                    type: 'switchbutton',\n                    model: {\n                        commandName: 'setTableColumnHeader',\n                        label: t('Header column'),\n                        bindIsOn: true\n                    }\n                },\n                {\n                    type: 'separator'\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: isContentLtr ? 'insertTableColumnLeft' : 'insertTableColumnRight',\n                        label: t('Insert column left')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: isContentLtr ? 'insertTableColumnRight' : 'insertTableColumnLeft',\n                        label: t('Insert column right')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'removeTableColumn',\n                        label: t('Delete column')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'selectTableColumn',\n                        label: t('Select column')\n                    }\n                }\n            ];\n            return this._prepareDropdown(t('Column'), tableColumnIcon, options, locale);\n        });\n        editor.ui.componentFactory.add('tableRow', (locale)=>{\n            const options = [\n                {\n                    type: 'switchbutton',\n                    model: {\n                        commandName: 'setTableRowHeader',\n                        label: t('Header row'),\n                        bindIsOn: true\n                    }\n                },\n                {\n                    type: 'separator'\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'insertTableRowAbove',\n                        label: t('Insert row above')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'insertTableRowBelow',\n                        label: t('Insert row below')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'removeTableRow',\n                        label: t('Delete row')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'selectTableRow',\n                        label: t('Select row')\n                    }\n                }\n            ];\n            return this._prepareDropdown(t('Row'), tableRowIcon, options, locale);\n        });\n        editor.ui.componentFactory.add('mergeTableCells', (locale)=>{\n            const options = [\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'mergeTableCellUp',\n                        label: t('Merge cell up')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: isContentLtr ? 'mergeTableCellRight' : 'mergeTableCellLeft',\n                        label: t('Merge cell right')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'mergeTableCellDown',\n                        label: t('Merge cell down')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: isContentLtr ? 'mergeTableCellLeft' : 'mergeTableCellRight',\n                        label: t('Merge cell left')\n                    }\n                },\n                {\n                    type: 'separator'\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'splitTableCellVertically',\n                        label: t('Split cell vertically')\n                    }\n                },\n                {\n                    type: 'button',\n                    model: {\n                        commandName: 'splitTableCellHorizontally',\n                        label: t('Split cell horizontally')\n                    }\n                }\n            ];\n            return this._prepareMergeSplitButtonDropdown(t('Merge cells'), tableMergeCellIcon, options, locale);\n        });\n    }\n    /**\n\t * Creates a dropdown view from a set of options.\n\t *\n\t * @param label The dropdown button label.\n\t * @param icon An icon for the dropdown button.\n\t * @param options The list of options for the dropdown.\n\t */ _prepareDropdown(label, icon, options, locale) {\n        const editor = this.editor;\n        const dropdownView = createDropdown(locale);\n        const commands = this._fillDropdownWithListOptions(dropdownView, options);\n        // Decorate dropdown's button.\n        dropdownView.buttonView.set({\n            label,\n            icon,\n            tooltip: true\n        });\n        // Make dropdown button disabled when all options are disabled.\n        dropdownView.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>{\n            return areEnabled.some((isEnabled)=>isEnabled);\n        });\n        this.listenTo(dropdownView, 'execute', (evt)=>{\n            editor.execute(evt.source.commandName);\n            // Toggling a switch button view should not move the focus to the editable.\n            if (!(evt.source instanceof SwitchButtonView)) {\n                editor.editing.view.focus();\n            }\n        });\n        return dropdownView;\n    }\n    /**\n\t * Creates a dropdown view with a {@link module:ui/dropdown/button/splitbuttonview~SplitButtonView} for\n\t * merge (and split)–related commands.\n\t *\n\t * @param label The dropdown button label.\n\t * @param icon An icon for the dropdown button.\n\t * @param options The list of options for the dropdown.\n\t */ _prepareMergeSplitButtonDropdown(label, icon, options, locale) {\n        const editor = this.editor;\n        const dropdownView = createDropdown(locale, SplitButtonView);\n        const mergeCommandName = 'mergeTableCells';\n        // Main command.\n        const mergeCommand = editor.commands.get(mergeCommandName);\n        // Subcommands in the dropdown.\n        const commands = this._fillDropdownWithListOptions(dropdownView, options);\n        dropdownView.buttonView.set({\n            label,\n            icon,\n            tooltip: true,\n            isEnabled: true\n        });\n        // Make dropdown button disabled when all options are disabled together with the main command.\n        dropdownView.bind('isEnabled').toMany([\n            mergeCommand,\n            ...commands\n        ], 'isEnabled', (...areEnabled)=>{\n            return areEnabled.some((isEnabled)=>isEnabled);\n        });\n        // Merge selected table cells when the main part of the split button is clicked.\n        this.listenTo(dropdownView.buttonView, 'execute', ()=>{\n            editor.execute(mergeCommandName);\n            editor.editing.view.focus();\n        });\n        // Execute commands for events coming from the list in the dropdown panel.\n        this.listenTo(dropdownView, 'execute', (evt)=>{\n            editor.execute(evt.source.commandName);\n            editor.editing.view.focus();\n        });\n        return dropdownView;\n    }\n    /**\n\t * Injects a {@link module:ui/list/listview~ListView} into the passed dropdown with buttons\n\t * which execute editor commands as configured in passed options.\n\t *\n\t * @param options The list of options for the dropdown.\n\t * @returns Commands the list options are interacting with.\n\t */ _fillDropdownWithListOptions(dropdownView, options) {\n        const editor = this.editor;\n        const commands = [];\n        const itemDefinitions = new Collection();\n        for (const option of options){\n            addListOption(option, editor, commands, itemDefinitions);\n        }\n        addListToDropdown(dropdownView, itemDefinitions);\n        return commands;\n    }\n}\n/**\n * Adds an option to a list view.\n *\n * @param option A configuration option.\n * @param commands The list of commands to update.\n * @param itemDefinitions A collection of dropdown items to update with the given option.\n */ function addListOption(option, editor, commands, itemDefinitions) {\n    if (option.type === 'button' || option.type === 'switchbutton') {\n        const model = option.model = new ViewModel(option.model);\n        const { commandName, bindIsOn } = option.model;\n        const command = editor.commands.get(commandName);\n        commands.push(command);\n        model.set({\n            commandName\n        });\n        model.bind('isEnabled').to(command);\n        if (bindIsOn) {\n            model.bind('isOn').to(command, 'value');\n        }\n        model.set({\n            withText: true\n        });\n    }\n    itemDefinitions.add(option);\n}\n\n/**\n * This plugin enables the advanced table cells, rows and columns selection.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */ class TableSelection extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableSelection';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableUtils,\n            TableUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const model = editor.model;\n        const view = editor.editing.view;\n        this.listenTo(model, 'deleteContent', (evt, args)=>this._handleDeleteContent(evt, args), {\n            priority: 'high'\n        });\n        this.listenTo(view.document, 'insertText', (evt, data)=>this._handleInsertTextEvent(evt, data), {\n            priority: 'high'\n        });\n        this._defineSelectionConverter();\n        this._enablePluginDisabling(); // sic!\n    }\n    /**\n\t * Returns the currently selected table cells or `null` if it is not a table cells selection.\n\t */ getSelectedTableCells() {\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const selection = this.editor.model.document.selection;\n        const selectedCells = tableUtils.getSelectedTableCells(selection);\n        if (selectedCells.length == 0) {\n            return null;\n        }\n        // This should never happen, but let's know if it ever happens.\n        // @if CK_DEBUG //\tif ( selectedCells.length != selection.rangeCount ) {\n        // @if CK_DEBUG //\t\tconsole.warn( 'Mixed selection warning. The selection contains table cells and some other ranges.' );\n        // @if CK_DEBUG //\t}\n        return selectedCells;\n    }\n    /**\n\t * Returns the selected table fragment as a document fragment.\n\t */ getSelectionAsFragment() {\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const selectedCells = this.getSelectedTableCells();\n        if (!selectedCells) {\n            return null;\n        }\n        return this.editor.model.change((writer)=>{\n            const documentFragment = writer.createDocumentFragment();\n            const { first: firstColumn, last: lastColumn } = tableUtils.getColumnIndexes(selectedCells);\n            const { first: firstRow, last: lastRow } = tableUtils.getRowIndexes(selectedCells);\n            const sourceTable = selectedCells[0].findAncestor('table');\n            let adjustedLastRow = lastRow;\n            let adjustedLastColumn = lastColumn;\n            // If the selection is rectangular there could be a case of all cells in the last row/column spanned over\n            // next row/column so the real lastRow/lastColumn should be updated.\n            if (tableUtils.isSelectionRectangular(selectedCells)) {\n                const dimensions = {\n                    firstColumn,\n                    lastColumn,\n                    firstRow,\n                    lastRow\n                };\n                adjustedLastRow = adjustLastRowIndex(sourceTable, dimensions);\n                adjustedLastColumn = adjustLastColumnIndex(sourceTable, dimensions);\n            }\n            const cropDimensions = {\n                startRow: firstRow,\n                startColumn: firstColumn,\n                endRow: adjustedLastRow,\n                endColumn: adjustedLastColumn\n            };\n            const table = cropTableToDimensions(sourceTable, cropDimensions, writer);\n            writer.insert(table, documentFragment, 0);\n            return documentFragment;\n        });\n    }\n    /**\n\t * Sets the model selection based on given anchor and target cells (can be the same cell).\n\t * Takes care of setting the backward flag.\n\t *\n\t * ```ts\n\t * const modelRoot = editor.model.document.getRoot();\n\t * const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );\n\t * const lastCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );\n\t *\n\t * const tableSelection = editor.plugins.get( 'TableSelection' );\n\t * tableSelection.setCellSelection( firstCell, lastCell );\n\t * ```\n\t */ setCellSelection(anchorCell, targetCell) {\n        const cellsToSelect = this._getCellsToSelect(anchorCell, targetCell);\n        this.editor.model.change((writer)=>{\n            writer.setSelection(cellsToSelect.cells.map((cell)=>writer.createRangeOn(cell)), {\n                backward: cellsToSelect.backward\n            });\n        });\n    }\n    /**\n\t * Returns the focus cell from the current selection.\n\t */ getFocusCell() {\n        const selection = this.editor.model.document.selection;\n        const focusCellRange = [\n            ...selection.getRanges()\n        ].pop();\n        const element = focusCellRange.getContainedElement();\n        if (element && element.is('element', 'tableCell')) {\n            return element;\n        }\n        return null;\n    }\n    /**\n\t * Returns the anchor cell from the current selection.\n\t */ getAnchorCell() {\n        const selection = this.editor.model.document.selection;\n        const anchorCellRange = first(selection.getRanges());\n        const element = anchorCellRange.getContainedElement();\n        if (element && element.is('element', 'tableCell')) {\n            return element;\n        }\n        return null;\n    }\n    /**\n\t * Defines a selection converter which marks the selected cells with a specific class.\n\t *\n\t * The real DOM selection is put in the last cell. Since the order of ranges is dependent on whether the\n\t * selection is backward or not, the last cell will usually be close to the \"focus\" end of the selection\n\t * (a selection has anchor and focus).\n\t *\n\t * The real DOM selection is then hidden with CSS.\n\t */ _defineSelectionConverter() {\n        const editor = this.editor;\n        const highlighted = new Set();\n        editor.conversion.for('editingDowncast').add((dispatcher)=>dispatcher.on('selection', (evt, data, conversionApi)=>{\n                const viewWriter = conversionApi.writer;\n                clearHighlightedTableCells(viewWriter);\n                const selectedCells = this.getSelectedTableCells();\n                if (!selectedCells) {\n                    return;\n                }\n                for (const tableCell of selectedCells){\n                    const viewElement = conversionApi.mapper.toViewElement(tableCell);\n                    viewWriter.addClass('ck-editor__editable_selected', viewElement);\n                    highlighted.add(viewElement);\n                }\n                const lastViewCell = conversionApi.mapper.toViewElement(selectedCells[selectedCells.length - 1]);\n                viewWriter.setSelection(lastViewCell, 0);\n            }, {\n                priority: 'lowest'\n            }));\n        function clearHighlightedTableCells(viewWriter) {\n            for (const previouslyHighlighted of highlighted){\n                viewWriter.removeClass('ck-editor__editable_selected', previouslyHighlighted);\n            }\n            highlighted.clear();\n        }\n    }\n    /**\n\t * Creates a listener that reacts to changes in {@link #isEnabled} and, if the plugin was disabled,\n\t * it collapses the multi-cell selection to a regular selection placed inside a table cell.\n\t *\n\t * This listener helps features that disable the table selection plugin bring the selection\n\t * to a clear state they can work with (for instance, because they don't support multiple cell selection).\n\t */ _enablePluginDisabling() {\n        const editor = this.editor;\n        this.on('change:isEnabled', ()=>{\n            if (!this.isEnabled) {\n                const selectedCells = this.getSelectedTableCells();\n                if (!selectedCells) {\n                    return;\n                }\n                editor.model.change((writer)=>{\n                    const position = writer.createPositionAt(selectedCells[0], 0);\n                    const range = editor.model.schema.getNearestSelectionRange(position);\n                    writer.setSelection(range);\n                });\n            }\n        });\n    }\n    /**\n\t * Overrides the default `model.deleteContent()` behavior over a selected table fragment.\n\t *\n\t * @param args Delete content method arguments.\n\t */ _handleDeleteContent(event, args) {\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const selection = args[0];\n        const options = args[1];\n        const model = this.editor.model;\n        const isBackward = !options || options.direction == 'backward';\n        const selectedTableCells = tableUtils.getSelectedTableCells(selection);\n        if (!selectedTableCells.length) {\n            return;\n        }\n        event.stop();\n        model.change((writer)=>{\n            const tableCellToSelect = selectedTableCells[isBackward ? selectedTableCells.length - 1 : 0];\n            model.change((writer)=>{\n                for (const tableCell of selectedTableCells){\n                    model.deleteContent(writer.createSelection(tableCell, 'in'));\n                }\n            });\n            const rangeToSelect = model.schema.getNearestSelectionRange(writer.createPositionAt(tableCellToSelect, 0));\n            // Note: we ignore the case where rangeToSelect may be null because deleteContent() will always (unless someone broke it)\n            // create an empty paragraph to accommodate the selection.\n            if (selection.is('documentSelection')) {\n                writer.setSelection(rangeToSelect);\n            } else {\n                selection.setTo(rangeToSelect);\n            }\n        });\n    }\n    /**\n\t * This handler makes it possible to remove the content of all selected cells by starting to type.\n\t * If you take a look at {@link #_defineSelectionConverter} you will find out that despite the multi-cell selection being set\n\t * in the model, the view selection is collapsed in the last cell (because most browsers are unable to render multi-cell selections;\n\t * yes, it's a hack).\n\t *\n\t * When multiple cells are selected in the model and the user starts to type, the\n\t * {@link module:engine/view/document~Document#event:insertText} event carries information provided by the\n\t * beforeinput DOM  event, that in turn only knows about this collapsed DOM selection in the last cell.\n\t *\n\t * As a result, the selected cells have no chance to be cleaned up. To fix this, this listener intercepts\n\t * the event and injects the custom view selection in the data that translates correctly to the actual state\n\t * of the multi-cell selection in the model.\n\t *\n\t * @param data Insert text event data.\n\t */ _handleInsertTextEvent(evt, data) {\n        const editor = this.editor;\n        const selectedCells = this.getSelectedTableCells();\n        if (!selectedCells) {\n            return;\n        }\n        const view = editor.editing.view;\n        const mapper = editor.editing.mapper;\n        const viewRanges = selectedCells.map((tableCell)=>view.createRangeOn(mapper.toViewElement(tableCell)));\n        data.selection = view.createSelection(viewRanges);\n    }\n    /**\n\t * Returns an array of table cells that should be selected based on the\n\t * given anchor cell and target (focus) cell.\n\t *\n\t * The cells are returned in a reverse direction if the selection is backward.\n\t */ _getCellsToSelect(anchorCell, targetCell) {\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const startLocation = tableUtils.getCellLocation(anchorCell);\n        const endLocation = tableUtils.getCellLocation(targetCell);\n        const startRow = Math.min(startLocation.row, endLocation.row);\n        const endRow = Math.max(startLocation.row, endLocation.row);\n        const startColumn = Math.min(startLocation.column, endLocation.column);\n        const endColumn = Math.max(startLocation.column, endLocation.column);\n        // 2-dimensional array of the selected cells to ease flipping the order of cells for backward selections.\n        const selectionMap = new Array(endRow - startRow + 1).fill(null).map(()=>[]);\n        const walkerOptions = {\n            startRow,\n            endRow,\n            startColumn,\n            endColumn\n        };\n        for (const { row, cell } of new TableWalker(anchorCell.findAncestor('table'), walkerOptions)){\n            selectionMap[row - startRow].push(cell);\n        }\n        const flipVertically = endLocation.row < startLocation.row;\n        const flipHorizontally = endLocation.column < startLocation.column;\n        if (flipVertically) {\n            selectionMap.reverse();\n        }\n        if (flipHorizontally) {\n            selectionMap.forEach((row)=>row.reverse());\n        }\n        return {\n            cells: selectionMap.flat(),\n            backward: flipVertically || flipHorizontally\n        };\n    }\n}\n\n/**\n * This plugin adds support for copying/cutting/pasting fragments of tables.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */ class TableClipboard extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableClipboard';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ClipboardMarkersUtils,\n            ClipboardPipeline,\n            TableSelection,\n            TableUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const viewDocument = editor.editing.view.document;\n        this.listenTo(viewDocument, 'copy', (evt, data)=>this._onCopyCut(evt, data));\n        this.listenTo(viewDocument, 'cut', (evt, data)=>this._onCopyCut(evt, data));\n        this.listenTo(editor.model, 'insertContent', (evt, [content, selectable])=>this._onInsertContent(evt, content, selectable), {\n            priority: 'high'\n        });\n        this.decorate('_replaceTableSlotCell');\n    }\n    /**\n\t * Copies table content to a clipboard on \"copy\" & \"cut\" events.\n\t *\n\t * @param evt An object containing information about the handled event.\n\t * @param data Clipboard event data.\n\t */ _onCopyCut(evt, data) {\n        const view = this.editor.editing.view;\n        const tableSelection = this.editor.plugins.get(TableSelection);\n        const clipboardMarkersUtils = this.editor.plugins.get(ClipboardMarkersUtils);\n        if (!tableSelection.getSelectedTableCells()) {\n            return;\n        }\n        if (evt.name == 'cut' && !this.editor.model.canEditAt(this.editor.model.document.selection)) {\n            return;\n        }\n        data.preventDefault();\n        evt.stop();\n        this.editor.model.enqueueChange({\n            isUndoable: evt.name === 'cut'\n        }, ()=>{\n            const documentFragment = clipboardMarkersUtils._copySelectedFragmentWithMarkers(evt.name, this.editor.model.document.selection, ()=>tableSelection.getSelectionAsFragment());\n            view.document.fire('clipboardOutput', {\n                dataTransfer: data.dataTransfer,\n                content: this.editor.data.toView(documentFragment),\n                method: evt.name\n            });\n        });\n    }\n    /**\n\t * Overrides default {@link module:engine/model/model~Model#insertContent `model.insertContent()`} method to handle pasting table inside\n\t * selected table fragment.\n\t *\n\t * Depending on selected table fragment:\n\t * - If a selected table fragment is smaller than paste table it will crop pasted table to match dimensions.\n\t * - If dimensions are equal it will replace selected table fragment with a pasted table contents.\n\t *\n\t * @param content The content to insert.\n\t * @param selectable The selection into which the content should be inserted.\n\t * If not provided the current model document selection will be used.\n\t */ _onInsertContent(evt, content, selectable) {\n        if (selectable && !selectable.is('documentSelection')) {\n            return;\n        }\n        const model = this.editor.model;\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const clipboardMarkersUtils = this.editor.plugins.get(ClipboardMarkersUtils);\n        // We might need to crop table before inserting so reference might change.\n        const pastedTable = this.getTableIfOnlyTableInContent(content, model);\n        if (!pastedTable) {\n            return;\n        }\n        const selectedTableCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        if (!selectedTableCells.length) {\n            removeEmptyRowsColumns(pastedTable, tableUtils);\n            return;\n        }\n        // Override default model.insertContent() handling at this point.\n        evt.stop();\n        if (content.is('documentFragment')) {\n            clipboardMarkersUtils._pasteMarkersIntoTransformedElement(content.markers, (writer)=>this._replaceSelectedCells(pastedTable, selectedTableCells, writer));\n        } else {\n            this.editor.model.change((writer)=>{\n                this._replaceSelectedCells(pastedTable, selectedTableCells, writer);\n            });\n        }\n    }\n    /**\n\t * Inserts provided `selectedTableCells` into `pastedTable`.\n\t */ _replaceSelectedCells(pastedTable, selectedTableCells, writer) {\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const pastedDimensions = {\n            width: tableUtils.getColumns(pastedTable),\n            height: tableUtils.getRows(pastedTable)\n        };\n        // Prepare the table for pasting.\n        const selection = prepareTableForPasting(selectedTableCells, pastedDimensions, writer, tableUtils);\n        // Beyond this point we operate on a fixed content table with rectangular selection and proper last row/column values.\n        const selectionHeight = selection.lastRow - selection.firstRow + 1;\n        const selectionWidth = selection.lastColumn - selection.firstColumn + 1;\n        // Crop pasted table if:\n        // - Pasted table dimensions exceeds selection area.\n        // - Pasted table has broken layout (ie some cells sticks out by the table dimensions established by the first and last row).\n        //\n        // Note: The table dimensions are established by the width of the first row and the total number of rows.\n        // It is possible to programmatically create a table that has rows which would have cells anchored beyond first row width but\n        // such table will not be created by other editing solutions.\n        const cropDimensions = {\n            startRow: 0,\n            startColumn: 0,\n            endRow: Math.min(selectionHeight, pastedDimensions.height) - 1,\n            endColumn: Math.min(selectionWidth, pastedDimensions.width) - 1\n        };\n        pastedTable = cropTableToDimensions(pastedTable, cropDimensions, writer);\n        // Content table to which we insert a pasted table.\n        const selectedTable = selectedTableCells[0].findAncestor('table');\n        const cellsToSelect = this._replaceSelectedCellsWithPasted(pastedTable, pastedDimensions, selectedTable, selection, writer);\n        if (this.editor.plugins.get('TableSelection').isEnabled) {\n            // Selection ranges must be sorted because the first and last selection ranges are considered\n            // as anchor/focus cell ranges for multi-cell selection.\n            const selectionRanges = tableUtils.sortRanges(cellsToSelect.map((cell)=>writer.createRangeOn(cell)));\n            writer.setSelection(selectionRanges);\n        } else {\n            // Set selection inside first cell if multi-cell selection is disabled.\n            writer.setSelection(cellsToSelect[0], 0);\n        }\n        return selectedTable;\n    }\n    /**\n\t * Replaces the part of selectedTable with pastedTable.\n\t */ _replaceSelectedCellsWithPasted(pastedTable, pastedDimensions, selectedTable, selection, writer) {\n        const { width: pastedWidth, height: pastedHeight } = pastedDimensions;\n        // Holds two-dimensional array that is addressed by [ row ][ column ] that stores cells anchored at given location.\n        const pastedTableLocationMap = createLocationMap(pastedTable, pastedWidth, pastedHeight);\n        const selectedTableMap = [\n            ...new TableWalker(selectedTable, {\n                startRow: selection.firstRow,\n                endRow: selection.lastRow,\n                startColumn: selection.firstColumn,\n                endColumn: selection.lastColumn,\n                includeAllSlots: true\n            })\n        ];\n        // Selection must be set to pasted cells (some might be removed or new created).\n        const cellsToSelect = [];\n        // Store next cell insert position.\n        let insertPosition;\n        // Content table replace cells algorithm iterates over a selected table fragment and:\n        //\n        // - Removes existing table cells at current slot (location).\n        // - Inserts cell from a pasted table for a matched slots.\n        //\n        // This ensures proper table geometry after the paste\n        for (const tableSlot of selectedTableMap){\n            const { row, column } = tableSlot;\n            // Save the insert position for current row start.\n            if (column === selection.firstColumn) {\n                insertPosition = tableSlot.getPositionBefore();\n            }\n            // Map current table slot location to an pasted table slot location.\n            const pastedRow = row - selection.firstRow;\n            const pastedColumn = column - selection.firstColumn;\n            const pastedCell = pastedTableLocationMap[pastedRow % pastedHeight][pastedColumn % pastedWidth];\n            // Clone cell to insert (to duplicate its attributes and children).\n            // Cloning is required to support repeating pasted table content when inserting to a bigger selection.\n            const cellToInsert = pastedCell ? writer.cloneElement(pastedCell) : null;\n            // Replace the cell from the current slot with new table cell.\n            const newTableCell = this._replaceTableSlotCell(tableSlot, cellToInsert, insertPosition, writer);\n            // The cell was only removed.\n            if (!newTableCell) {\n                continue;\n            }\n            // Trim the cell if it's row/col-spans would exceed selection area.\n            trimTableCellIfNeeded(newTableCell, row, column, selection.lastRow, selection.lastColumn, writer);\n            cellsToSelect.push(newTableCell);\n            insertPosition = writer.createPositionAfter(newTableCell);\n        }\n        // If there are any headings, all the cells that overlap from heading must be splitted.\n        const headingRows = parseInt(selectedTable.getAttribute('headingRows') || '0');\n        const headingColumns = parseInt(selectedTable.getAttribute('headingColumns') || '0');\n        const areHeadingRowsIntersectingSelection = selection.firstRow < headingRows && headingRows <= selection.lastRow;\n        const areHeadingColumnsIntersectingSelection = selection.firstColumn < headingColumns && headingColumns <= selection.lastColumn;\n        if (areHeadingRowsIntersectingSelection) {\n            const columnsLimit = {\n                first: selection.firstColumn,\n                last: selection.lastColumn\n            };\n            const newCells = doHorizontalSplit(selectedTable, headingRows, columnsLimit, writer, selection.firstRow);\n            cellsToSelect.push(...newCells);\n        }\n        if (areHeadingColumnsIntersectingSelection) {\n            const rowsLimit = {\n                first: selection.firstRow,\n                last: selection.lastRow\n            };\n            const newCells = doVerticalSplit(selectedTable, headingColumns, rowsLimit, writer);\n            cellsToSelect.push(...newCells);\n        }\n        return cellsToSelect;\n    }\n    /**\n\t * Replaces a single table slot.\n\t *\n\t * @returns Inserted table cell or null if slot should remain empty.\n\t * @private\n\t */ _replaceTableSlotCell(tableSlot, cellToInsert, insertPosition, writer) {\n        const { cell, isAnchor } = tableSlot;\n        // If the slot is occupied by a cell in a selected table - remove it.\n        // The slot of this cell will be either:\n        // - Replaced by a pasted table cell.\n        // - Spanned by a previously pasted table cell.\n        if (isAnchor) {\n            writer.remove(cell);\n        }\n        // There is no cell to insert (might be spanned by other cell in a pasted table) - advance to the next content table slot.\n        if (!cellToInsert) {\n            return null;\n        }\n        writer.insert(cellToInsert, insertPosition);\n        return cellToInsert;\n    }\n    /**\n\t * Extracts the table for pasting into a table.\n\t *\n\t * @param content The content to insert.\n\t * @param model The editor model.\n\t */ getTableIfOnlyTableInContent(content, model) {\n        if (!content.is('documentFragment') && !content.is('element')) {\n            return null;\n        }\n        // Table passed directly.\n        if (content.is('element', 'table')) {\n            return content;\n        }\n        // We do not support mixed content when pasting table into table.\n        // See: https://github.com/ckeditor/ckeditor5/issues/6817.\n        if (content.childCount == 1 && content.getChild(0).is('element', 'table')) {\n            return content.getChild(0);\n        }\n        // If there are only whitespaces around a table then use that table for pasting.\n        const contentRange = model.createRangeIn(content);\n        for (const element of contentRange.getItems()){\n            if (element.is('element', 'table')) {\n                // Stop checking if there is some content before table.\n                const rangeBefore = model.createRange(contentRange.start, model.createPositionBefore(element));\n                if (model.hasContent(rangeBefore, {\n                    ignoreWhitespaces: true\n                })) {\n                    return null;\n                }\n                // Stop checking if there is some content after table.\n                const rangeAfter = model.createRange(model.createPositionAfter(element), contentRange.end);\n                if (model.hasContent(rangeAfter, {\n                    ignoreWhitespaces: true\n                })) {\n                    return null;\n                }\n                // There wasn't any content neither before nor after.\n                return element;\n            }\n        }\n        return null;\n    }\n}\n/**\n * Prepares a table for pasting and returns adjusted selection dimensions.\n */ function prepareTableForPasting(selectedTableCells, pastedDimensions, writer, tableUtils) {\n    const selectedTable = selectedTableCells[0].findAncestor('table');\n    const columnIndexes = tableUtils.getColumnIndexes(selectedTableCells);\n    const rowIndexes = tableUtils.getRowIndexes(selectedTableCells);\n    const selection = {\n        firstColumn: columnIndexes.first,\n        lastColumn: columnIndexes.last,\n        firstRow: rowIndexes.first,\n        lastRow: rowIndexes.last\n    };\n    // Single cell selected - expand selection to pasted table dimensions.\n    const shouldExpandSelection = selectedTableCells.length === 1;\n    if (shouldExpandSelection) {\n        selection.lastRow += pastedDimensions.height - 1;\n        selection.lastColumn += pastedDimensions.width - 1;\n        expandTableSize(selectedTable, selection.lastRow + 1, selection.lastColumn + 1, tableUtils);\n    }\n    // In case of expanding selection we do not reset the selection so in this case we will always try to fix selection\n    // like in the case of a non-rectangular area. This might be fixed by re-setting selected cells array but this shortcut is safe.\n    if (shouldExpandSelection || !tableUtils.isSelectionRectangular(selectedTableCells)) {\n        // For a non-rectangular selection (ie in which some cells sticks out from a virtual selection rectangle) we need to create\n        // a table layout that has a rectangular selection. This will split cells so the selection become rectangular.\n        // Beyond this point we will operate on fixed content table.\n        splitCellsToRectangularSelection(selectedTable, selection, writer);\n    } else {\n        selection.lastRow = adjustLastRowIndex(selectedTable, selection);\n        selection.lastColumn = adjustLastColumnIndex(selectedTable, selection);\n    }\n    return selection;\n}\n/**\n * Expand table (in place) to expected size.\n */ function expandTableSize(table, expectedHeight, expectedWidth, tableUtils) {\n    const tableWidth = tableUtils.getColumns(table);\n    const tableHeight = tableUtils.getRows(table);\n    if (expectedWidth > tableWidth) {\n        tableUtils.insertColumns(table, {\n            at: tableWidth,\n            columns: expectedWidth - tableWidth\n        });\n    }\n    if (expectedHeight > tableHeight) {\n        tableUtils.insertRows(table, {\n            at: tableHeight,\n            rows: expectedHeight - tableHeight\n        });\n    }\n}\n/**\n * Returns two-dimensional array that is addressed by [ row ][ column ] that stores cells anchored at given location.\n *\n * At given row & column location it might be one of:\n *\n * * cell - cell from pasted table anchored at this location.\n * * null - if no cell is anchored at this location.\n *\n * For instance, from a table below:\n *\n *   +----+----+----+----+\n *   | 00 | 01 | 02 | 03 |\n *   +    +----+----+----+\n *   |    | 11      | 13 |\n *   +----+         +----+\n *   | 20 |         | 23 |\n *   +----+----+----+----+\n *\n * The method will return an array (numbers represents cell element):\n *\n * ```ts\n * const map = [\n *   [ '00', '01', '02', '03' ],\n *   [ null, '11', null, '13' ],\n *   [ '20', null, null, '23' ]\n * ]\n * ```\n *\n * This allows for a quick access to table at give row & column. For instance to access table cell \"13\" from pasted table call:\n *\n * ```ts\n * const cell = map[ 1 ][ 3 ]\n * ```\n */ function createLocationMap(table, width, height) {\n    // Create height x width (row x column) two-dimensional table to store cells.\n    const map = new Array(height).fill(null).map(()=>new Array(width).fill(null));\n    for (const { column, row, cell } of new TableWalker(table)){\n        map[row][column] = cell;\n    }\n    return map;\n}\n/**\n * Make selected cells rectangular by splitting the cells that stand out from a rectangular selection.\n *\n * In the table below a selection is shown with \"::\" and slots with anchor cells are named.\n *\n * +----+----+----+----+----+                    +----+----+----+----+----+\n * | 00 | 01 | 02 | 03      |                    | 00 | 01 | 02 | 03      |\n * +    +----+    +----+----+                    |    ::::::::::::::::----+\n * |    | 11 |    | 13 | 14 |                    |    ::11 |    | 13:: 14 |    <- first row\n * +----+----+    +    +----+                    +----::---|    |   ::----+\n * | 20 | 21 |    |    | 24 |   select cells:    | 20 ::21 |    |   :: 24 |\n * +----+----+    +----+----+     11 -> 33       +----::---|    |---::----+\n * | 30      |    | 33 | 34 |                    | 30 ::   |    | 33:: 34 |    <- last row\n * +         +    +----+    +                    |    ::::::::::::::::    +\n * |         |    | 43 |    |                    |         |    | 43 |    |\n * +----+----+----+----+----+                    +----+----+----+----+----+\n *                                                      ^          ^\n *                                                     first & last columns\n *\n * Will update table to:\n *\n *                       +----+----+----+----+----+\n *                       | 00 | 01 | 02 | 03      |\n *                       +    +----+----+----+----+\n *                       |    | 11 |    | 13 | 14 |\n *                       +----+----+    +    +----+\n *                       | 20 | 21 |    |    | 24 |\n *                       +----+----+    +----+----+\n *                       | 30 |    |    | 33 | 34 |\n *                       +    +----+----+----+    +\n *                       |    |    |    | 43 |    |\n *                       +----+----+----+----+----+\n *\n * In th example above:\n * - Cell \"02\" which have `rowspan = 4` must be trimmed at first and at after last row.\n * - Cell \"03\" which have `rowspan = 2` and `colspan = 2` must be trimmed at first column and after last row.\n * - Cells \"00\", \"03\" & \"30\" which cannot be cut by this algorithm as they are outside the trimmed area.\n * - Cell \"13\" cannot be cut as it is inside the trimmed area.\n */ function splitCellsToRectangularSelection(table, dimensions, writer) {\n    const { firstRow, lastRow, firstColumn, lastColumn } = dimensions;\n    const rowIndexes = {\n        first: firstRow,\n        last: lastRow\n    };\n    const columnIndexes = {\n        first: firstColumn,\n        last: lastColumn\n    };\n    // 1. Split cells vertically in two steps as first step might create cells that needs to split again.\n    doVerticalSplit(table, firstColumn, rowIndexes, writer);\n    doVerticalSplit(table, lastColumn + 1, rowIndexes, writer);\n    // 2. Split cells horizontally in two steps as first step might create cells that needs to split again.\n    doHorizontalSplit(table, firstRow, columnIndexes, writer);\n    doHorizontalSplit(table, lastRow + 1, columnIndexes, writer, firstRow);\n}\nfunction doHorizontalSplit(table, splitRow, limitColumns, writer, startRow = 0) {\n    // If selection starts at first row then no split is needed.\n    if (splitRow < 1) {\n        return;\n    }\n    const overlappingCells = getVerticallyOverlappingCells(table, splitRow, startRow);\n    // Filter out cells that are not touching insides of the rectangular selection.\n    const cellsToSplit = overlappingCells.filter(({ column, cellWidth })=>isAffectedBySelection(column, cellWidth, limitColumns));\n    return cellsToSplit.map(({ cell })=>splitHorizontally(cell, splitRow, writer));\n}\nfunction doVerticalSplit(table, splitColumn, limitRows, writer) {\n    // If selection starts at first column then no split is needed.\n    if (splitColumn < 1) {\n        return;\n    }\n    const overlappingCells = getHorizontallyOverlappingCells(table, splitColumn);\n    // Filter out cells that are not touching insides of the rectangular selection.\n    const cellsToSplit = overlappingCells.filter(({ row, cellHeight })=>isAffectedBySelection(row, cellHeight, limitRows));\n    return cellsToSplit.map(({ cell, column })=>splitVertically(cell, column, splitColumn, writer));\n}\n/**\n * Checks if cell at given row (column) is affected by a rectangular selection defined by first/last column (row).\n *\n * The same check is used for row as for column.\n */ function isAffectedBySelection(index, span, limit) {\n    const endIndex = index + span - 1;\n    const { first, last } = limit;\n    const isInsideSelection = index >= first && index <= last;\n    const overlapsSelectionFromOutside = index < first && endIndex >= first;\n    return isInsideSelection || overlapsSelectionFromOutside;\n}\n\n/**\n * This plugin enables keyboard navigation for tables.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */ class TableKeyboard extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableKeyboard';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableSelection,\n            TableUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const view = editor.editing.view;\n        const viewDocument = view.document;\n        const t = editor.t;\n        this.listenTo(viewDocument, 'arrowKey', (...args)=>this._onArrowKey(...args), {\n            context: 'table'\n        });\n        this.listenTo(viewDocument, 'tab', (...args)=>this._handleTabOnSelectedTable(...args), {\n            context: 'figure'\n        });\n        this.listenTo(viewDocument, 'tab', (...args)=>this._handleTab(...args), {\n            context: [\n                'th',\n                'td'\n            ]\n        });\n        // Add the information about the keystrokes to the accessibility database.\n        editor.accessibility.addKeystrokeInfoGroup({\n            id: 'table',\n            label: t('Keystrokes that can be used in a table cell'),\n            keystrokes: [\n                {\n                    label: t('Move the selection to the next cell'),\n                    keystroke: 'Tab'\n                },\n                {\n                    label: t('Move the selection to the previous cell'),\n                    keystroke: 'Shift+Tab'\n                },\n                {\n                    label: t('Insert a new table row (when in the last cell of a table)'),\n                    keystroke: 'Tab'\n                },\n                {\n                    label: t('Navigate through the table'),\n                    keystroke: [\n                        [\n                            'arrowup'\n                        ],\n                        [\n                            'arrowright'\n                        ],\n                        [\n                            'arrowdown'\n                        ],\n                        [\n                            'arrowleft'\n                        ]\n                    ]\n                }\n            ]\n        });\n    }\n    /**\n\t * Handles {@link module:engine/view/document~Document#event:tab tab} events for the <kbd>Tab</kbd> key executed\n\t * when the table widget is selected.\n\t */ _handleTabOnSelectedTable(bubblingEventInfo, domEventData) {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const selectedElement = selection.getSelectedElement();\n        if (!selectedElement || !selectedElement.is('element', 'table')) {\n            return;\n        }\n        domEventData.preventDefault();\n        domEventData.stopPropagation();\n        bubblingEventInfo.stop();\n        editor.model.change((writer)=>{\n            writer.setSelection(writer.createRangeIn(selectedElement.getChild(0).getChild(0)));\n        });\n    }\n    /**\n\t * Handles {@link module:engine/view/document~Document#event:tab tab} events for the <kbd>Tab</kbd> key executed\n\t * inside table cells.\n\t */ _handleTab(bubblingEventInfo, domEventData) {\n        const editor = this.editor;\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const tableSelection = this.editor.plugins.get('TableSelection');\n        const selection = editor.model.document.selection;\n        const isForward = !domEventData.shiftKey;\n        let tableCell = tableUtils.getTableCellsContainingSelection(selection)[0];\n        if (!tableCell) {\n            tableCell = tableSelection.getFocusCell();\n        }\n        if (!tableCell) {\n            return;\n        }\n        domEventData.preventDefault();\n        domEventData.stopPropagation();\n        bubblingEventInfo.stop();\n        const tableRow = tableCell.parent;\n        const table = tableRow.parent;\n        const currentRowIndex = table.getChildIndex(tableRow);\n        const currentCellIndex = tableRow.getChildIndex(tableCell);\n        const isFirstCellInRow = currentCellIndex === 0;\n        if (!isForward && isFirstCellInRow && currentRowIndex === 0) {\n            // Set the selection over the whole table if the selection was in the first table cell.\n            editor.model.change((writer)=>{\n                writer.setSelection(writer.createRangeOn(table));\n            });\n            return;\n        }\n        const isLastCellInRow = currentCellIndex === tableRow.childCount - 1;\n        const isLastRow = currentRowIndex === tableUtils.getRows(table) - 1;\n        if (isForward && isLastRow && isLastCellInRow) {\n            editor.execute('insertTableRowBelow');\n            // Check if the command actually added a row. If `insertTableRowBelow` execution didn't add a row (because it was disabled\n            // or it got overwritten) set the selection over the whole table to mirror the first cell case.\n            if (currentRowIndex === tableUtils.getRows(table) - 1) {\n                editor.model.change((writer)=>{\n                    writer.setSelection(writer.createRangeOn(table));\n                });\n                return;\n            }\n        }\n        let cellToFocus;\n        // Move to the first cell in the next row.\n        if (isForward && isLastCellInRow) {\n            const nextRow = table.getChild(currentRowIndex + 1);\n            cellToFocus = nextRow.getChild(0);\n        } else if (!isForward && isFirstCellInRow) {\n            const previousRow = table.getChild(currentRowIndex - 1);\n            cellToFocus = previousRow.getChild(previousRow.childCount - 1);\n        } else {\n            cellToFocus = tableRow.getChild(currentCellIndex + (isForward ? 1 : -1));\n        }\n        editor.model.change((writer)=>{\n            writer.setSelection(writer.createRangeIn(cellToFocus));\n        });\n    }\n    /**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events.\n\t */ _onArrowKey(eventInfo, domEventData) {\n        const editor = this.editor;\n        const keyCode = domEventData.keyCode;\n        const direction = getLocalizedArrowKeyCodeDirection(keyCode, editor.locale.contentLanguageDirection);\n        const wasHandled = this._handleArrowKeys(direction, domEventData.shiftKey);\n        if (wasHandled) {\n            domEventData.preventDefault();\n            domEventData.stopPropagation();\n            eventInfo.stop();\n        }\n    }\n    /**\n\t * Handles arrow keys to move the selection around the table.\n\t *\n\t * @param direction The direction of the arrow key.\n\t * @param expandSelection If the current selection should be expanded.\n\t * @returns Returns `true` if key was handled.\n\t */ _handleArrowKeys(direction, expandSelection) {\n        const tableUtils = this.editor.plugins.get(TableUtils);\n        const tableSelection = this.editor.plugins.get('TableSelection');\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const isForward = [\n            'right',\n            'down'\n        ].includes(direction);\n        // In case one or more table cells are selected (from outside),\n        // move the selection to a cell adjacent to the selected table fragment.\n        const selectedCells = tableUtils.getSelectedTableCells(selection);\n        if (selectedCells.length) {\n            let focusCell;\n            if (expandSelection) {\n                focusCell = tableSelection.getFocusCell();\n            } else {\n                focusCell = isForward ? selectedCells[selectedCells.length - 1] : selectedCells[0];\n            }\n            this._navigateFromCellInDirection(focusCell, direction, expandSelection);\n            return true;\n        }\n        // Abort if we're not in a table cell.\n        const tableCell = selection.focus.findAncestor('tableCell');\n        /* istanbul ignore if: paranoid check -- @preserve */ if (!tableCell) {\n            return false;\n        }\n        // When the selection is not collapsed.\n        if (!selection.isCollapsed) {\n            if (expandSelection) {\n                // Navigation is in the opposite direction than the selection direction so this is shrinking of the selection.\n                // Selection for sure will not approach cell edge.\n                //\n                // With a special case when all cell content is selected - then selection should expand to the other cell.\n                // Note: When the entire cell gets selected using CTRL+A, the selection is always forward.\n                if (selection.isBackward == isForward && !selection.containsEntireContent(tableCell)) {\n                    return false;\n                }\n            } else {\n                const selectedElement = selection.getSelectedElement();\n                // It will collapse for non-object selected so it's not going to move to other cell.\n                if (!selectedElement || !model.schema.isObject(selectedElement)) {\n                    return false;\n                }\n            }\n        }\n        // Let's check if the selection is at the beginning/end of the cell.\n        if (this._isSelectionAtCellEdge(selection, tableCell, isForward)) {\n            this._navigateFromCellInDirection(tableCell, direction, expandSelection);\n            return true;\n        }\n        return false;\n    }\n    /**\n\t * Returns `true` if the selection is at the boundary of a table cell according to the navigation direction.\n\t *\n\t * @param selection The current selection.\n\t * @param tableCell The current table cell element.\n\t * @param isForward The expected navigation direction.\n\t */ _isSelectionAtCellEdge(selection, tableCell, isForward) {\n        const model = this.editor.model;\n        const schema = this.editor.model.schema;\n        const focus = isForward ? selection.getLastPosition() : selection.getFirstPosition();\n        // If the current limit element is not table cell we are for sure not at the cell edge.\n        // Also `modifySelection` will not let us out of it.\n        if (!schema.getLimitElement(focus).is('element', 'tableCell')) {\n            const boundaryPosition = model.createPositionAt(tableCell, isForward ? 'end' : 0);\n            return boundaryPosition.isTouching(focus);\n        }\n        const probe = model.createSelection(focus);\n        model.modifySelection(probe, {\n            direction: isForward ? 'forward' : 'backward'\n        });\n        // If there was no change in the focus position, then it's not possible to move the selection there.\n        return focus.isEqual(probe.focus);\n    }\n    /**\n\t * Moves the selection from the given table cell in the specified direction.\n\t *\n\t * @param focusCell The table cell that is current multi-cell selection focus.\n\t * @param direction Direction in which selection should move.\n\t * @param expandSelection If the current selection should be expanded. Default value is false.\n\t */ _navigateFromCellInDirection(focusCell, direction, expandSelection = false) {\n        const model = this.editor.model;\n        const table = focusCell.findAncestor('table');\n        const tableMap = [\n            ...new TableWalker(table, {\n                includeAllSlots: true\n            })\n        ];\n        const { row: lastRow, column: lastColumn } = tableMap[tableMap.length - 1];\n        const currentCellInfo = tableMap.find(({ cell })=>cell == focusCell);\n        let { row, column } = currentCellInfo;\n        switch(direction){\n            case 'left':\n                column--;\n                break;\n            case 'up':\n                row--;\n                break;\n            case 'right':\n                column += currentCellInfo.cellWidth;\n                break;\n            case 'down':\n                row += currentCellInfo.cellHeight;\n                break;\n        }\n        const isOutsideVertically = row < 0 || row > lastRow;\n        const isBeforeFirstCell = column < 0 && row <= 0;\n        const isAfterLastCell = column > lastColumn && row >= lastRow;\n        // Note that if the table cell at the end of a row is row-spanned then isAfterLastCell will never be true.\n        // However, we don't know if user was navigating on the last row or not, so let's stay in the table.\n        if (isOutsideVertically || isBeforeFirstCell || isAfterLastCell) {\n            model.change((writer)=>{\n                writer.setSelection(writer.createRangeOn(table));\n            });\n            return;\n        }\n        if (column < 0) {\n            column = expandSelection ? 0 : lastColumn;\n            row--;\n        } else if (column > lastColumn) {\n            column = expandSelection ? lastColumn : 0;\n            row++;\n        }\n        const cellToSelect = tableMap.find((cellInfo)=>cellInfo.row == row && cellInfo.column == column).cell;\n        const isForward = [\n            'right',\n            'down'\n        ].includes(direction);\n        const tableSelection = this.editor.plugins.get('TableSelection');\n        if (expandSelection && tableSelection.isEnabled) {\n            const anchorCell = tableSelection.getAnchorCell() || focusCell;\n            tableSelection.setCellSelection(anchorCell, cellToSelect);\n        } else {\n            const positionToSelect = model.createPositionAt(cellToSelect, isForward ? 0 : 'end');\n            model.change((writer)=>{\n                writer.setSelection(positionToSelect);\n            });\n        }\n    }\n}\n\n/**\n * The mouse selection event observer.\n *\n * It registers listeners for the following DOM events:\n *\n * - `'mousemove'`\n * - `'mouseleave'`\n *\n * Note that this observer is disabled by default. To enable this observer, it needs to be added to\n * {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.\n *\n * The observer is registered by the {@link module:table/tableselection~TableSelection} plugin.\n */ class MouseEventsObserver extends DomEventObserver {\n    domEventType = [\n        'mousemove',\n        'mouseleave'\n    ];\n    /**\n\t * @inheritDoc\n\t */ onDomEvent(domEvent) {\n        this.fire(domEvent.type, domEvent);\n    }\n}\n\n/**\n * This plugin enables a table cells' selection with the mouse.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */ class TableMouse extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableMouse';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableSelection,\n            TableUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Currently the MouseObserver only handles `mousedown` and `mouseup` events.\n        // TODO move to the engine?\n        editor.editing.view.addObserver(MouseEventsObserver);\n        this._enableShiftClickSelection();\n        this._enableMouseDragSelection();\n    }\n    /**\n\t * Enables making cells selection by <kbd>Shift</kbd>+click. Creates a selection from the cell which previously held\n\t * the selection to the cell which was clicked. It can be the same cell, in which case it selects a single cell.\n\t */ _enableShiftClickSelection() {\n        const editor = this.editor;\n        const tableUtils = editor.plugins.get(TableUtils);\n        let blockSelectionChange = false;\n        const tableSelection = editor.plugins.get(TableSelection);\n        this.listenTo(editor.editing.view.document, 'mousedown', (evt, domEventData)=>{\n            const selection = editor.model.document.selection;\n            if (!this.isEnabled || !tableSelection.isEnabled) {\n                return;\n            }\n            if (!domEventData.domEvent.shiftKey) {\n                return;\n            }\n            const anchorCell = tableSelection.getAnchorCell() || tableUtils.getTableCellsContainingSelection(selection)[0];\n            if (!anchorCell) {\n                return;\n            }\n            const targetCell = this._getModelTableCellFromDomEvent(domEventData);\n            if (targetCell && haveSameTableParent(anchorCell, targetCell)) {\n                blockSelectionChange = true;\n                tableSelection.setCellSelection(anchorCell, targetCell);\n                domEventData.preventDefault();\n            }\n        });\n        this.listenTo(editor.editing.view.document, 'mouseup', ()=>{\n            blockSelectionChange = false;\n        });\n        // We need to ignore a `selectionChange` event that is fired after we render our new table cells selection.\n        // When downcasting table cells selection to the view, we put the view selection in the last selected cell\n        // in a place that may not be natively a \"correct\" location. This is – we put it directly in the `<td>` element.\n        // All browsers fire the native `selectionchange` event.\n        // However, all browsers except Safari return the selection in the exact place where we put it\n        // (even though it's visually normalized). Safari returns `<td><p>^foo` that makes our selection observer\n        // fire our `selectionChange` event (because the view selection that we set in the first step differs from the DOM selection).\n        // Since `selectionChange` is fired, we automatically update the model selection that moves it that paragraph.\n        // This breaks our dear cells selection.\n        //\n        // Theoretically this issue concerns only Safari that is the only browser that do normalize the selection.\n        // However, to avoid code branching and to have a good coverage for this event blocker, I enabled it for all browsers.\n        //\n        // Note: I'm keeping the `blockSelectionChange` state separately for shift+click and mouse drag (exact same logic)\n        // so I don't have to try to analyze whether they don't overlap in some weird cases. Probably they don't.\n        // But I have other things to do, like writing this comment.\n        this.listenTo(editor.editing.view.document, 'selectionChange', (evt)=>{\n            if (blockSelectionChange) {\n                // @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );\n                evt.stop();\n            }\n        }, {\n            priority: 'highest'\n        });\n    }\n    /**\n\t * Enables making cells selection by dragging.\n\t *\n\t * The selection is made only on mousemove. Mouse tracking is started on mousedown.\n\t * However, the cells selection is enabled only after the mouse cursor left the anchor cell.\n\t * Thanks to that normal text selection within one cell works just fine. However, you can still select\n\t * just one cell by leaving the anchor cell and moving back to it.\n\t */ _enableMouseDragSelection() {\n        const editor = this.editor;\n        let anchorCell, targetCell;\n        let beganCellSelection = false;\n        let blockSelectionChange = false;\n        const tableSelection = editor.plugins.get(TableSelection);\n        this.listenTo(editor.editing.view.document, 'mousedown', (evt, domEventData)=>{\n            if (!this.isEnabled || !tableSelection.isEnabled) {\n                return;\n            }\n            // Make sure to not conflict with the shift+click listener and any other possible handler.\n            if (domEventData.domEvent.shiftKey || domEventData.domEvent.ctrlKey || domEventData.domEvent.altKey) {\n                return;\n            }\n            anchorCell = this._getModelTableCellFromDomEvent(domEventData);\n        });\n        this.listenTo(editor.editing.view.document, 'mousemove', (evt, domEventData)=>{\n            if (!domEventData.domEvent.buttons) {\n                return;\n            }\n            if (!anchorCell) {\n                return;\n            }\n            const newTargetCell = this._getModelTableCellFromDomEvent(domEventData);\n            if (newTargetCell && haveSameTableParent(anchorCell, newTargetCell)) {\n                targetCell = newTargetCell;\n                // Switch to the cell selection mode after the mouse cursor left the anchor cell.\n                // Switch off only on mouseup (makes selecting a single cell possible).\n                if (!beganCellSelection && targetCell != anchorCell) {\n                    beganCellSelection = true;\n                }\n            }\n            // Yep, not making a cell selection yet. See method docs.\n            if (!beganCellSelection) {\n                return;\n            }\n            blockSelectionChange = true;\n            tableSelection.setCellSelection(anchorCell, targetCell);\n            domEventData.preventDefault();\n        });\n        this.listenTo(editor.editing.view.document, 'mouseup', ()=>{\n            beganCellSelection = false;\n            blockSelectionChange = false;\n            anchorCell = null;\n            targetCell = null;\n        });\n        // See the explanation in `_enableShiftClickSelection()`.\n        this.listenTo(editor.editing.view.document, 'selectionChange', (evt)=>{\n            if (blockSelectionChange) {\n                // @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );\n                evt.stop();\n            }\n        }, {\n            priority: 'highest'\n        });\n    }\n    /**\n\t * Returns the model table cell element based on the target element of the passed DOM event.\n\t *\n\t * @returns Returns the table cell or `undefined`.\n\t */ _getModelTableCellFromDomEvent(domEventData) {\n        // Note: Work with positions (not element mapping) because the target element can be an attribute or other non-mapped element.\n        const viewTargetElement = domEventData.target;\n        const viewPosition = this.editor.editing.view.createPositionAt(viewTargetElement, 0);\n        const modelPosition = this.editor.editing.mapper.toModelPosition(viewPosition);\n        const modelElement = modelPosition.parent;\n        return modelElement.findAncestor('tableCell', {\n            includeSelf: true\n        });\n    }\n}\nfunction haveSameTableParent(cellA, cellB) {\n    return cellA.parent.parent == cellB.parent.parent;\n}\n\n/**\n * The table plugin.\n *\n * For a detailed overview, check the {@glink features/tables/tables Table feature documentation}.\n *\n * This is a \"glue\" plugin that loads the following table features:\n *\n * * {@link module:table/tableediting~TableEditing editing feature},\n * * {@link module:table/tableselection~TableSelection selection feature},\n * * {@link module:table/tablekeyboard~TableKeyboard keyboard navigation feature},\n * * {@link module:table/tablemouse~TableMouse mouse selection feature},\n * * {@link module:table/tableclipboard~TableClipboard clipboard feature},\n * * {@link module:table/tableui~TableUI UI feature}.\n */ class Table extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableEditing,\n            TableUI,\n            TableSelection,\n            TableMouse,\n            TableKeyboard,\n            TableClipboard,\n            Widget\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'Table';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\n/**\n * The plain table output feature.\n */ class PlainTableOutput extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'PlainTableOutput';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            Table\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        // Override default table data downcast converter.\n        editor.conversion.for('dataDowncast').elementToStructure({\n            model: 'table',\n            view: downcastTableElement,\n            converterPriority: 'high'\n        });\n        // Make sure table <caption> is downcasted into <caption> in the data pipeline when necessary.\n        if (editor.plugins.has('TableCaption')) {\n            editor.conversion.for('dataDowncast').elementToElement({\n                model: 'caption',\n                view: (modelElement, { writer })=>{\n                    if (modelElement.parent.name === 'table') {\n                        return writer.createContainerElement('caption');\n                    }\n                },\n                converterPriority: 'high'\n            });\n        }\n        // Handle border-style, border-color, border-width and background-color table attributes.\n        if (editor.plugins.has('TableProperties')) {\n            downcastTableBorderAndBackgroundAttributes(editor);\n        }\n    }\n}\n/**\n * The plain table downcast converter callback.\n *\n * @param table Table model element.\n * @param conversionApi The conversion API object.\n * @returns Created element.\n */ function downcastTableElement(table, { writer }) {\n    const headingRows = table.getAttribute('headingRows') || 0;\n    // Table head rows slot.\n    const headRowsSlot = writer.createSlot((element)=>element.is('element', 'tableRow') && element.index < headingRows);\n    // Table body rows slot.\n    const bodyRowsSlot = writer.createSlot((element)=>element.is('element', 'tableRow') && element.index >= headingRows);\n    // Table children slot.\n    const childrenSlot = writer.createSlot((element)=>!element.is('element', 'tableRow'));\n    // Table <thead> element with all the heading rows.\n    const theadElement = writer.createContainerElement('thead', null, headRowsSlot);\n    // Table <tbody> element with all the body rows.\n    const tbodyElement = writer.createContainerElement('tbody', null, bodyRowsSlot);\n    // Table contents element containing <thead> and <tbody> when necessary.\n    const tableContentElements = [];\n    if (headingRows) {\n        tableContentElements.push(theadElement);\n    }\n    if (headingRows < table.childCount) {\n        tableContentElements.push(tbodyElement);\n    }\n    // Create table structure.\n    //\n    // <table>\n    //    {children-slot-like-caption}\n    //    <thead>\n    //        {table-head-rows-slot}\n    //    </thead>\n    //    <tbody>\n    //        {table-body-rows-slot}\n    //    </tbody>\n    // </table>\n    return writer.createContainerElement('table', null, [\n        childrenSlot,\n        ...tableContentElements\n    ]);\n}\n/**\n * Register table border and background attributes converters.\n */ function downcastTableBorderAndBackgroundAttributes(editor) {\n    const modelAttributes = {\n        'border-width': 'tableBorderWidth',\n        'border-color': 'tableBorderColor',\n        'border-style': 'tableBorderStyle',\n        'background-color': 'tableBackgroundColor'\n    };\n    for (const [styleName, modelAttribute] of Object.entries(modelAttributes)){\n        editor.conversion.for('dataDowncast').add((dispatcher)=>{\n            return dispatcher.on(`attribute:${modelAttribute}:table`, (evt, data, conversionApi)=>{\n                const { item, attributeNewValue } = data;\n                const { mapper, writer } = conversionApi;\n                if (!conversionApi.consumable.consume(item, evt.name)) {\n                    return;\n                }\n                const table = mapper.toViewElement(item);\n                if (attributeNewValue) {\n                    writer.setStyle(styleName, attributeNewValue, table);\n                } else {\n                    writer.removeStyle(styleName, table);\n                }\n            }, {\n                priority: 'high'\n            });\n        });\n    }\n}\n\n/**\n * Depending on the position of the selection either return the selected table or the table higher in the hierarchy.\n */ function getSelectionAffectedTableWidget(selection) {\n    const selectedTable = getSelectedTableWidget(selection);\n    if (selectedTable) {\n        return selectedTable;\n    }\n    return getTableWidgetAncestor(selection);\n}\n/**\n * Returns a table widget editing view element if one is selected.\n */ function getSelectedTableWidget(selection) {\n    const viewElement = selection.getSelectedElement();\n    if (viewElement && isTableWidget(viewElement)) {\n        return viewElement;\n    }\n    return null;\n}\n/**\n * Returns a table widget editing view element if one is among the selection's ancestors.\n */ function getTableWidgetAncestor(selection) {\n    const selectionPosition = selection.getFirstPosition();\n    if (!selectionPosition) {\n        return null;\n    }\n    let parent = selectionPosition.parent;\n    while(parent){\n        if (parent.is('element') && isTableWidget(parent)) {\n            return parent;\n        }\n        parent = parent.parent;\n    }\n    return null;\n}\n/**\n * Checks if a given view element is a table widget.\n */ function isTableWidget(viewElement) {\n    return !!viewElement.getCustomProperty('table') && isWidget(viewElement);\n}\n\n/**\n * The table toolbar class. It creates toolbars for the table feature and its content (for now only for the table cell content).\n *\n * The table toolbar shows up when a table widget is selected. Its components (e.g. buttons) are created based on the\n * {@link module:table/tableconfig~TableConfig#tableToolbar `table.tableToolbar` configuration option}.\n *\n * Table content toolbar shows up when the selection is inside the content of a table. It creates its component based on the\n * {@link module:table/tableconfig~TableConfig#contentToolbar `table.contentToolbar` configuration option}.\n */ class TableToolbar extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            WidgetToolbarRepository\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableToolbar';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ afterInit() {\n        const editor = this.editor;\n        const t = editor.t;\n        const widgetToolbarRepository = editor.plugins.get(WidgetToolbarRepository);\n        const tableContentToolbarItems = editor.config.get('table.contentToolbar');\n        const tableToolbarItems = editor.config.get('table.tableToolbar');\n        if (tableContentToolbarItems) {\n            widgetToolbarRepository.register('tableContent', {\n                ariaLabel: t('Table toolbar'),\n                items: tableContentToolbarItems,\n                getRelatedElement: getTableWidgetAncestor\n            });\n        }\n        if (tableToolbarItems) {\n            widgetToolbarRepository.register('table', {\n                ariaLabel: t('Table toolbar'),\n                items: tableToolbarItems,\n                getRelatedElement: getSelectedTableWidget\n            });\n        }\n    }\n}\n\n/**\n * The color input view class. It allows the user to type in a color (hex, rgb, etc.)\n * or choose it from the configurable color palette with a preview.\n *\n * @internal\n */ class ColorInputView extends View {\n    /**\n\t * A cached reference to the options passed to the constructor.\n\t */ options;\n    /**\n\t * Tracks information about the DOM focus in the view.\n\t */ focusTracker;\n    /**\n\t * Helps cycling over focusable children in the input view.\n\t */ focusCycler;\n    /**\n\t * A collection of views that can be focused in the view.\n\t */ _focusables;\n    /**\n\t * An instance of the dropdown allowing to select a color from a grid.\n\t */ dropdownView;\n    /**\n\t * An instance of the input allowing the user to type a color value.\n\t */ inputView;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * The flag that indicates whether the user is still typing.\n\t * If set to true, it means that the text input field ({@link #inputView}) still has the focus.\n\t * So, we should interrupt the user by replacing the input's value.\n\t */ _stillTyping;\n    /**\n\t * Creates an instance of the color input view.\n\t *\n\t * @param locale The locale instance.\n\t * @param options The input options.\n\t * @param options.colorDefinitions The colors to be displayed in the palette inside the input's dropdown.\n\t * @param options.columns The number of columns in which the colors will be displayed.\n\t * @param options.defaultColorValue If specified, the color input view will replace the \"Remove color\" button with\n\t * the \"Restore default\" button. Instead of clearing the input field, the default color value will be set.\n\t */ constructor(locale, options){\n        super(locale);\n        this.set('value', '');\n        this.set('isReadOnly', false);\n        this.set('isFocused', false);\n        this.set('isEmpty', true);\n        this.options = options;\n        this.focusTracker = new FocusTracker();\n        this._focusables = new ViewCollection();\n        this.dropdownView = this._createDropdownView();\n        this.inputView = this._createInputTextView();\n        this.keystrokes = new KeystrokeHandler();\n        this._stillTyping = false;\n        this.focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate items backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate items forwards using the <kbd>Tab</kbd> key.\n                focusNext: 'tab'\n            }\n        });\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-input-color'\n                ]\n            },\n            children: [\n                this.dropdownView,\n                this.inputView\n            ]\n        });\n        this.on('change:value', (evt, name, inputValue)=>this._setInputValue(inputValue));\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        [\n            this.inputView,\n            this.dropdownView.buttonView\n        ].forEach((view)=>{\n            this.focusTracker.add(view.element);\n            this._focusables.add(view);\n        });\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * Focuses the view.\n\t */ focus(direction) {\n        if (direction === -1) {\n            this.focusCycler.focusLast();\n        } else {\n            this.focusCycler.focusFirst();\n        }\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Creates and configures the {@link #dropdownView}.\n\t */ _createDropdownView() {\n        const locale = this.locale;\n        const t = locale.t;\n        const bind = this.bindTemplate;\n        const colorSelector = this._createColorSelector(locale);\n        const dropdown = createDropdown(locale);\n        const colorPreview = new View();\n        colorPreview.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-input-color__button__preview'\n                ],\n                style: {\n                    backgroundColor: bind.to('value')\n                }\n            },\n            children: [\n                {\n                    tag: 'span',\n                    attributes: {\n                        class: [\n                            'ck',\n                            'ck-input-color__button__preview__no-color-indicator',\n                            bind.if('value', 'ck-hidden', (value)=>value != '')\n                        ]\n                    }\n                }\n            ]\n        });\n        dropdown.buttonView.extendTemplate({\n            attributes: {\n                class: 'ck-input-color__button'\n            }\n        });\n        dropdown.buttonView.children.add(colorPreview);\n        dropdown.buttonView.label = t('Color picker');\n        dropdown.buttonView.tooltip = true;\n        dropdown.panelPosition = locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw';\n        dropdown.panelView.children.add(colorSelector);\n        dropdown.bind('isEnabled').to(this, 'isReadOnly', (value)=>!value);\n        dropdown.on('change:isOpen', (evt, name, isVisible)=>{\n            if (isVisible) {\n                colorSelector.updateSelectedColors();\n                colorSelector.showColorGridsFragment();\n            }\n        });\n        return dropdown;\n    }\n    /**\n\t * Creates and configures an instance of {@link module:ui/inputtext/inputtextview~InputTextView}.\n\t *\n\t * @returns A configured instance to be set as {@link #inputView}.\n\t */ _createInputTextView() {\n        const locale = this.locale;\n        const inputView = new InputTextView(locale);\n        inputView.extendTemplate({\n            on: {\n                blur: inputView.bindTemplate.to('blur')\n            }\n        });\n        inputView.value = this.value;\n        inputView.bind('isReadOnly', 'hasError').to(this);\n        this.bind('isFocused', 'isEmpty').to(inputView);\n        inputView.on('input', ()=>{\n            const inputValue = inputView.element.value;\n            // Check if the value matches one of our defined colors' label.\n            const mappedColor = this.options.colorDefinitions.find((def)=>inputValue === def.label);\n            this._stillTyping = true;\n            this.value = mappedColor && mappedColor.color || inputValue;\n        });\n        inputView.on('blur', ()=>{\n            this._stillTyping = false;\n            this._setInputValue(inputView.element.value);\n        });\n        inputView.delegate('input').to(this);\n        return inputView;\n    }\n    /**\n\t * Creates and configures the panel with \"color grid\" and \"color picker\" inside the {@link #dropdownView}.\n\t */ _createColorSelector(locale) {\n        const t = locale.t;\n        const defaultColor = this.options.defaultColorValue || '';\n        const removeColorButtonLabel = defaultColor ? t('Restore default') : t('Remove color');\n        const colorSelector = new ColorSelectorView(locale, {\n            colors: this.options.colorDefinitions,\n            columns: this.options.columns,\n            removeButtonLabel: removeColorButtonLabel,\n            colorPickerLabel: t('Color picker'),\n            colorPickerViewConfig: this.options.colorPickerConfig === false ? false : {\n                ...this.options.colorPickerConfig,\n                hideInput: true\n            }\n        });\n        colorSelector.appendUI();\n        colorSelector.on('execute', (evt, data)=>{\n            if (data.source === 'colorPickerSaveButton') {\n                this.dropdownView.isOpen = false;\n                return;\n            }\n            this.value = data.value || defaultColor;\n            // Trigger the listener that actually applies the set value.\n            this.fire('input');\n            if (data.source !== 'colorPicker') {\n                this.dropdownView.isOpen = false;\n            }\n        });\n        /**\n\t\t * Color is saved before changes in color picker. In case \"cancel button\" is pressed\n\t\t * this color will be applied.\n\t\t */ let backupColor = this.value;\n        colorSelector.on('colorPicker:cancel', ()=>{\n            /**\n\t\t\t * Revert color to previous value before changes in color picker.\n\t\t\t */ this.value = backupColor;\n            this.fire('input');\n            this.dropdownView.isOpen = false;\n        });\n        colorSelector.colorGridsFragmentView.colorPickerButtonView.on('execute', ()=>{\n            /**\n\t\t\t * Save color value before changes in color picker.\n\t\t\t */ backupColor = this.value;\n        });\n        colorSelector.bind('selectedColor').to(this, 'value');\n        return colorSelector;\n    }\n    /**\n\t * Sets {@link #inputView}'s value property to the color value or color label,\n\t * if there is one and the user is not typing.\n\t *\n\t * Handles cases like:\n\t *\n\t * * Someone picks the color in the grid.\n\t * * The color is set from the plugin level.\n\t *\n\t * @param inputValue Color value to be set.\n\t */ _setInputValue(inputValue) {\n        if (!this._stillTyping) {\n            const normalizedInputValue = normalizeColor(inputValue);\n            // Check if the value matches one of our defined colors.\n            const mappedColor = this.options.colorDefinitions.find((def)=>normalizedInputValue === normalizeColor(def.color));\n            if (mappedColor) {\n                this.inputView.value = mappedColor.label;\n            } else {\n                this.inputView.value = inputValue || '';\n            }\n        }\n    }\n}\n/**\n * Normalizes color value, by stripping extensive whitespace.\n * For example., transforms:\n * * `   rgb(  25 50    0 )` to `rgb(25 50 0)`,\n * * \"\\t  rgb(  25 ,  50,0 )\t\t\" to `rgb(25 50 0)`.\n *\n * @param colorString The value to be normalized.\n */ function normalizeColor(colorString) {\n    return colorString// Remove any whitespace right after `(` or `,`.\n    .replace(/([(,])\\s+/g, '$1')// Remove any whitespace at the beginning or right before the end, `)`, `,`, or another whitespace.\n    .replace(/^\\s+|\\s+(?=[),\\s]|$)/g, '')// Then, replace `,` or whitespace with a single space.\n    .replace(/,|\\s/g, ' ');\n}\n\nconst isEmpty = (val)=>val === '';\n/**\n * Returns an object containing pairs of CSS border style values and their localized UI\n * labels. Used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}\n * and {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView}.\n *\n * @param t The \"t\" function provided by the editor that is used to localize strings.\n */ function getBorderStyleLabels(t) {\n    return {\n        none: t('None'),\n        solid: t('Solid'),\n        dotted: t('Dotted'),\n        dashed: t('Dashed'),\n        double: t('Double'),\n        groove: t('Groove'),\n        ridge: t('Ridge'),\n        inset: t('Inset'),\n        outset: t('Outset')\n    };\n}\n/**\n * Returns a localized error string that can be displayed next to color (background, border)\n * fields that have an invalid value.\n *\n * @param t The \"t\" function provided by the editor that is used to localize strings.\n */ function getLocalizedColorErrorText(t) {\n    return t('The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".');\n}\n/**\n * Returns a localized error string that can be displayed next to length (padding, border width)\n * fields that have an invalid value.\n *\n * @param t The \"t\" function provided by the editor that is used to localize strings.\n */ function getLocalizedLengthErrorText(t) {\n    return t('The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".');\n}\n/**\n * Returns `true` when the passed value is an empty string or a valid CSS color expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isColor}.\n */ function colorFieldValidator(value) {\n    value = value.trim().toLowerCase();\n    return isEmpty(value) || isColor(value);\n}\n/**\n * Returns `true` when the passed value is an empty string, a number without a unit or a valid CSS length expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isLength}.\n * See {@link module:engine/view/styles/utils~isPercentage}.\n */ function lengthFieldValidator(value) {\n    value = value.trim();\n    return isEmpty(value) || isNumberString(value) || isLength(value) || isPercentage(value);\n}\n/**\n * Returns `true` when the passed value is an empty string, a number without a unit or a valid CSS length expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isLength}.\n */ function lineWidthFieldValidator(value) {\n    value = value.trim();\n    return isEmpty(value) || isNumberString(value) || isLength(value);\n}\n/**\n * Generates item definitions for a UI dropdown that allows changing the border style of a table or a table cell.\n *\n * @param defaultStyle The default border.\n */ function getBorderStyleDefinitions(view, defaultStyle) {\n    const itemDefinitions = new Collection();\n    const styleLabels = getBorderStyleLabels(view.t);\n    for(const style in styleLabels){\n        const definition = {\n            type: 'button',\n            model: new ViewModel({\n                _borderStyleValue: style,\n                label: styleLabels[style],\n                role: 'menuitemradio',\n                withText: true\n            })\n        };\n        if (style === 'none') {\n            definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{\n                if (defaultStyle === 'none') {\n                    return !value;\n                }\n                return value === style;\n            });\n        } else {\n            definition.model.bind('isOn').to(view, 'borderStyle', (value)=>{\n                return value === style;\n            });\n        }\n        itemDefinitions.add(definition);\n    }\n    return itemDefinitions;\n}\n/**\n * A helper that fills a toolbar with buttons that:\n *\n * * have some labels,\n * * have some icons,\n * * set a certain UI view property value upon execution.\n *\n * @param nameToValue A function that maps a button name to a value. By default names are the same as values.\n */ function fillToolbar(options) {\n    const { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;\n    for(const name in labels){\n        const button = new ButtonView(view.locale);\n        button.set({\n            label: labels[name],\n            icon: icons[name],\n            tooltip: labels[name]\n        });\n        // If specified the `nameToValue()` callback, map the value based on the option's name.\n        const buttonValue = nameToValue ? nameToValue(name) : name;\n        button.bind('isOn').to(view, propertyName, (value)=>{\n            // `value` comes from `view[ propertyName ]`.\n            let valueToCompare = value;\n            // If it's empty, and the `defaultValue` is specified, use it instead.\n            if (value === '' && defaultValue) {\n                valueToCompare = defaultValue;\n            }\n            return buttonValue === valueToCompare;\n        });\n        button.on('execute', ()=>{\n            view[propertyName] = buttonValue;\n        });\n        toolbar.items.add(button);\n    }\n}\n/**\n * A default color palette used by various user interfaces related to tables, for instance,\n * by {@link module:table/tablecellproperties/tablecellpropertiesui~TableCellPropertiesUI} or\n * {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI}.\n *\n * The color palette follows the {@link module:table/tableconfig~TableColorConfig table color configuration format}\n * and contains the following color definitions:\n *\n * ```ts\n * const defaultColors = [\n *   {\n *     color: 'hsl(0, 0%, 0%)',\n *     label: 'Black'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 30%)',\n *     label: 'Dim grey'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 60%)',\n *     label: 'Grey'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 90%)',\n *     label: 'Light grey'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 100%)',\n *     label: 'White',\n *     hasBorder: true\n *   },\n *   {\n *     color: 'hsl(0, 75%, 60%)',\n *     label: 'Red'\n *   },\n *   {\n *     color: 'hsl(30, 75%, 60%)',\n *     label: 'Orange'\n *   },\n *   {\n *     color: 'hsl(60, 75%, 60%)',\n *     label: 'Yellow'\n *   },\n *   {\n *     color: 'hsl(90, 75%, 60%)',\n *     label: 'Light green'\n *   },\n *   {\n *     color: 'hsl(120, 75%, 60%)',\n *     label: 'Green'\n *   },\n *   {\n *     color: 'hsl(150, 75%, 60%)',\n *     label: 'Aquamarine'\n *   },\n *   {\n *     color: 'hsl(180, 75%, 60%)',\n *     label: 'Turquoise'\n *   },\n *   {\n *     color: 'hsl(210, 75%, 60%)',\n *     label: 'Light blue'\n *   },\n *   {\n *     color: 'hsl(240, 75%, 60%)',\n *     label: 'Blue'\n *   },\n *   {\n *     color: 'hsl(270, 75%, 60%)',\n *     label: 'Purple'\n *   }\n * ];\n * ```\n */ const defaultColors = [\n    {\n        color: 'hsl(0, 0%, 0%)',\n        label: 'Black'\n    },\n    {\n        color: 'hsl(0, 0%, 30%)',\n        label: 'Dim grey'\n    },\n    {\n        color: 'hsl(0, 0%, 60%)',\n        label: 'Grey'\n    },\n    {\n        color: 'hsl(0, 0%, 90%)',\n        label: 'Light grey'\n    },\n    {\n        color: 'hsl(0, 0%, 100%)',\n        label: 'White',\n        hasBorder: true\n    },\n    {\n        color: 'hsl(0, 75%, 60%)',\n        label: 'Red'\n    },\n    {\n        color: 'hsl(30, 75%, 60%)',\n        label: 'Orange'\n    },\n    {\n        color: 'hsl(60, 75%, 60%)',\n        label: 'Yellow'\n    },\n    {\n        color: 'hsl(90, 75%, 60%)',\n        label: 'Light green'\n    },\n    {\n        color: 'hsl(120, 75%, 60%)',\n        label: 'Green'\n    },\n    {\n        color: 'hsl(150, 75%, 60%)',\n        label: 'Aquamarine'\n    },\n    {\n        color: 'hsl(180, 75%, 60%)',\n        label: 'Turquoise'\n    },\n    {\n        color: 'hsl(210, 75%, 60%)',\n        label: 'Light blue'\n    },\n    {\n        color: 'hsl(240, 75%, 60%)',\n        label: 'Blue'\n    },\n    {\n        color: 'hsl(270, 75%, 60%)',\n        label: 'Purple'\n    }\n];\n/**\n * Returns a creator for a color input with a label.\n *\n * For given options, it returns a function that creates an instance of a\n * {@link module:table/ui/colorinputview~ColorInputView color input} logically related to\n * a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in the DOM.\n *\n * The helper does the following:\n *\n * * It sets the color input `id` and `ariaDescribedById` attributes.\n * * It binds the color input `isReadOnly` to the labeled view.\n * * It binds the color input `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when the user starts typing in the color input.\n *\n * Usage:\n *\n * ```ts\n * const colorInputCreator = getLabeledColorInputCreator( {\n *   colorConfig: [ ... ],\n *   columns: 3,\n * } );\n *\n * const labeledInputView = new LabeledFieldView( locale, colorInputCreator );\n * console.log( labeledInputView.view ); // A color input instance.\n * ```\n *\n * @internal\n * @param options Color input options.\n * @param options.colorConfig The configuration of the color palette displayed in the input's dropdown.\n * @param options.columns The configuration of the number of columns the color palette consists of in the input's dropdown.\n * @param options.defaultColorValue If specified, the color input view will replace the \"Remove color\" button with\n * the \"Restore default\" button. Instead of clearing the input field, the default color value will be set.\n * @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.\n */ function getLabeledColorInputCreator(options) {\n    return (labeledFieldView, viewUid, statusUid)=>{\n        const colorInputView = new ColorInputView(labeledFieldView.locale, {\n            colorDefinitions: colorConfigToColorGridDefinitions(options.colorConfig),\n            columns: options.columns,\n            defaultColorValue: options.defaultColorValue,\n            colorPickerConfig: options.colorPickerConfig\n        });\n        colorInputView.inputView.set({\n            id: viewUid,\n            ariaDescribedById: statusUid\n        });\n        colorInputView.bind('isReadOnly').to(labeledFieldView, 'isEnabled', (value)=>!value);\n        colorInputView.bind('hasError').to(labeledFieldView, 'errorText', (value)=>!!value);\n        colorInputView.on('input', ()=>{\n            // UX: Make the error text disappear and disable the error indicator as the user\n            // starts fixing the errors.\n            labeledFieldView.errorText = null;\n        });\n        labeledFieldView.bind('isEmpty', 'isFocused').to(colorInputView);\n        return colorInputView;\n    };\n}\n/**\n * A simple helper method to detect number strings.\n * I allows full number notation, so omitting 0 is not allowed:\n */ function isNumberString(value) {\n    const parsedValue = parseFloat(value);\n    return !Number.isNaN(parsedValue) && value === String(parsedValue);\n}\nfunction colorConfigToColorGridDefinitions(colorConfig) {\n    return colorConfig.map((item)=>({\n            color: item.model,\n            label: item.label,\n            options: {\n                hasBorder: item.hasBorder\n            }\n        }));\n}\n\n/**\n * The class representing a single row in a complex form,\n * used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}.\n *\n * **Note**: For now this class is private. When more use cases arrive (beyond ckeditor5-table),\n * it will become a component in ckeditor5-ui.\n *\n * @internal\n */ class FormRowView extends View {\n    /**\n\t * A collection of row items (buttons, dropdowns, etc.).\n\t */ children;\n    /**\n\t * Creates an instance of the form row class.\n\t *\n\t * @param locale The locale instance.\n\t * @param options.labelView When passed, the row gets the `group` and `aria-labelledby`\n\t * DOM attributes and gets described by the label.\n\t */ constructor(locale, options = {}){\n        super(locale);\n        const bind = this.bindTemplate;\n        this.set('class', options.class || null);\n        this.children = this.createCollection();\n        if (options.children) {\n            options.children.forEach((child)=>this.children.add(child));\n        }\n        this.set('_role', null);\n        this.set('_ariaLabelledBy', null);\n        if (options.labelView) {\n            this.set({\n                _role: 'group',\n                _ariaLabelledBy: options.labelView.id\n            });\n        }\n        this.setTemplate({\n            tag: 'div',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-form__row',\n                    bind.to('class')\n                ],\n                role: bind.to('_role'),\n                'aria-labelledby': bind.to('_ariaLabelledBy')\n            },\n            children: this.children\n        });\n    }\n}\n\n/**\n * The class representing a table cell properties form, allowing users to customize\n * certain style aspects of a table cell, for instance, border, padding, text alignment, etc..\n */ class TableCellPropertiesView extends View {\n    /**\n\t * Options passed to the view. See {@link #constructor} to learn more.\n\t */ options;\n    /**\n\t * Tracks information about the DOM focus in the form.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * A collection of child views in the form.\n\t */ children;\n    /**\n\t * A dropdown that allows selecting the style of the table cell border.\n\t */ borderStyleDropdown;\n    /**\n\t * An input that allows specifying the width of the table cell border.\n\t */ borderWidthInput;\n    /**\n\t * An input that allows specifying the color of the table cell border.\n\t */ borderColorInput;\n    /**\n\t * An input that allows specifying the table cell background color.\n\t */ backgroundInput;\n    /**\n\t * An input that allows specifying the table cell padding.\n\t */ paddingInput;\n    /**\n\t * An input that allows specifying the table cell width.\n\t */ widthInput;\n    /**\n\t * An input that allows specifying the table cell height.\n\t */ heightInput;\n    /**\n\t * A toolbar with buttons that allow changing the horizontal text alignment in a table cell.\n\t */ horizontalAlignmentToolbar;\n    /**\n\t * A toolbar with buttons that allow changing the vertical text alignment in a table cell.\n\t */ verticalAlignmentToolbar;\n    /**\n\t * The \"Save\" button view.\n\t */ saveButtonView;\n    /**\n\t * The \"Cancel\" button view.\n\t */ cancelButtonView;\n    /**\n\t * A collection of views that can be focused in the form.\n\t */ _focusables;\n    /**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */ _focusCycler;\n    /**\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options Additional configuration of the view.\n\t * @param options.borderColors A configuration of the border color palette used by the\n\t * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}.\n\t * @param options.backgroundColors A configuration of the background color palette used by the\n\t * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.\n\t * @param options.defaultTableCellProperties The default table cell properties.\n\t */ constructor(locale, options){\n        super(locale);\n        this.set({\n            borderStyle: '',\n            borderWidth: '',\n            borderColor: '',\n            padding: '',\n            backgroundColor: '',\n            width: '',\n            height: '',\n            horizontalAlignment: '',\n            verticalAlignment: ''\n        });\n        this.options = options;\n        const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();\n        const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();\n        const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();\n        const { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.children = this.createCollection();\n        this.borderStyleDropdown = borderStyleDropdown;\n        this.borderWidthInput = borderWidthInput;\n        this.borderColorInput = borderColorInput;\n        this.backgroundInput = backgroundInput;\n        this.paddingInput = this._createPaddingField();\n        this.widthInput = widthInput;\n        this.heightInput = heightInput;\n        this.horizontalAlignmentToolbar = horizontalAlignmentToolbar;\n        this.verticalAlignmentToolbar = verticalAlignmentToolbar;\n        // Defer creating to make sure other fields are present and the Save button can\n        // bind its #isEnabled to their error messages so there's no way to save unless all\n        // fields are valid.\n        const { saveButtonView, cancelButtonView } = this._createActionButtons();\n        this.saveButtonView = saveButtonView;\n        this.cancelButtonView = cancelButtonView;\n        this._focusables = new ViewCollection();\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        // Form header.\n        this.children.add(new FormHeaderView(locale, {\n            label: this.t('Cell properties')\n        }));\n        // Border row.\n        this.children.add(new FormRowView(locale, {\n            labelView: borderRowLabel,\n            children: [\n                borderRowLabel,\n                borderStyleDropdown,\n                borderColorInput,\n                borderWidthInput\n            ],\n            class: 'ck-table-form__border-row'\n        }));\n        // Background.\n        this.children.add(new FormRowView(locale, {\n            labelView: backgroundRowLabel,\n            children: [\n                backgroundRowLabel,\n                backgroundInput\n            ],\n            class: 'ck-table-form__background-row'\n        }));\n        // Dimensions row and padding.\n        this.children.add(new FormRowView(locale, {\n            children: [\n                // Dimensions row.\n                new FormRowView(locale, {\n                    labelView: dimensionsLabel,\n                    children: [\n                        dimensionsLabel,\n                        widthInput,\n                        operatorLabel,\n                        heightInput\n                    ],\n                    class: 'ck-table-form__dimensions-row'\n                }),\n                // Padding row.\n                new FormRowView(locale, {\n                    children: [\n                        this.paddingInput\n                    ],\n                    class: 'ck-table-cell-properties-form__padding-row'\n                })\n            ]\n        }));\n        // Text alignment row.\n        this.children.add(new FormRowView(locale, {\n            labelView: alignmentLabel,\n            children: [\n                alignmentLabel,\n                horizontalAlignmentToolbar,\n                verticalAlignmentToolbar\n            ],\n            class: 'ck-table-cell-properties-form__alignment-row'\n        }));\n        // Action row.\n        this.children.add(new FormRowView(locale, {\n            children: [\n                this.saveButtonView,\n                this.cancelButtonView\n            ],\n            class: 'ck-table-form__action-row'\n        }));\n        this.setTemplate({\n            tag: 'form',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-form',\n                    'ck-table-form',\n                    'ck-table-cell-properties-form'\n                ],\n                // https://github.com/ckeditor/ckeditor5-link/issues/90\n                tabindex: '-1'\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        // Enable the \"submit\" event for this view. It can be triggered by the #saveButtonView\n        // which is of the \"submit\" DOM \"type\".\n        submitHandler({\n            view: this\n        });\n        // Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.\n        [\n            this.borderColorInput,\n            this.backgroundInput\n        ].forEach((view)=>{\n            this._focusCycler.chain(view.fieldView.focusCycler);\n        });\n        [\n            this.borderStyleDropdown,\n            this.borderColorInput,\n            this.borderWidthInput,\n            this.backgroundInput,\n            this.widthInput,\n            this.heightInput,\n            this.paddingInput,\n            this.horizontalAlignmentToolbar,\n            this.verticalAlignmentToolbar,\n            this.saveButtonView,\n            this.cancelButtonView\n        ].forEach((view)=>{\n            // Register the view as focusable.\n            this._focusables.add(view);\n            // Register the view in the focus tracker.\n            this.focusTracker.add(view.element);\n        });\n        // Mainly for closing using \"Esc\" and navigation using \"Tab\".\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the fist focusable field in the form.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #borderStyleDropdown},\n\t * * {@link #borderWidthInput},\n\t * * {@link #borderColorInput}.\n\t */ _createBorderFields() {\n        const defaultTableCellProperties = this.options.defaultTableCellProperties;\n        const defaultBorder = {\n            style: defaultTableCellProperties.borderStyle,\n            width: defaultTableCellProperties.borderWidth,\n            color: defaultTableCellProperties.borderColor\n        };\n        const colorInputCreator = getLabeledColorInputCreator({\n            colorConfig: this.options.borderColors,\n            columns: 5,\n            defaultColorValue: defaultBorder.color,\n            colorPickerConfig: this.options.colorPickerConfig\n        });\n        const locale = this.locale;\n        const t = this.t;\n        const accessibleLabel = t('Style');\n        // -- Group label ---------------------------------------------\n        const borderRowLabel = new LabelView(locale);\n        borderRowLabel.text = t('Border');\n        // -- Style ---------------------------------------------------\n        const styleLabels = getBorderStyleLabels(t);\n        const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);\n        borderStyleDropdown.set({\n            label: accessibleLabel,\n            class: 'ck-table-form__border-style'\n        });\n        borderStyleDropdown.fieldView.buttonView.set({\n            ariaLabel: accessibleLabel,\n            ariaLabelledBy: undefined,\n            isOn: false,\n            withText: true,\n            tooltip: accessibleLabel\n        });\n        borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{\n            return styleLabels[value ? value : 'none'];\n        });\n        borderStyleDropdown.fieldView.on('execute', (evt)=>{\n            this.borderStyle = evt.source._borderStyleValue;\n        });\n        borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);\n        addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {\n            role: 'menu',\n            ariaLabel: accessibleLabel\n        });\n        // -- Width ---------------------------------------------------\n        const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);\n        borderWidthInput.set({\n            label: t('Width'),\n            class: 'ck-table-form__border-width'\n        });\n        borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');\n        borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);\n        borderWidthInput.fieldView.on('input', ()=>{\n            this.borderWidth = borderWidthInput.fieldView.element.value;\n        });\n        // -- Color ---------------------------------------------------\n        const borderColorInput = new LabeledFieldView(locale, colorInputCreator);\n        borderColorInput.set({\n            label: t('Color'),\n            class: 'ck-table-form__border-color'\n        });\n        borderColorInput.fieldView.bind('value').to(this, 'borderColor');\n        borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet$1);\n        borderColorInput.fieldView.on('input', ()=>{\n            this.borderColor = borderColorInput.fieldView.value;\n        });\n        // Reset the border color and width fields depending on the `border-style` value.\n        this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{\n            // When removing the border (`border-style:none`), clear the remaining `border-*` properties.\n            // See: https://github.com/ckeditor/ckeditor5/issues/6227.\n            if (!isBorderStyleSet$1(newValue)) {\n                this.borderColor = '';\n                this.borderWidth = '';\n            }\n            // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.\n            if (!isBorderStyleSet$1(oldValue)) {\n                this.borderColor = defaultBorder.color;\n                this.borderWidth = defaultBorder.width;\n            }\n        });\n        return {\n            borderRowLabel,\n            borderStyleDropdown,\n            borderColorInput,\n            borderWidthInput\n        };\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #backgroundInput}.\n\t */ _createBackgroundFields() {\n        const locale = this.locale;\n        const t = this.t;\n        // -- Group label ---------------------------------------------\n        const backgroundRowLabel = new LabelView(locale);\n        backgroundRowLabel.text = t('Background');\n        // -- Background color input -----------------------------------\n        const colorInputCreator = getLabeledColorInputCreator({\n            colorConfig: this.options.backgroundColors,\n            columns: 5,\n            defaultColorValue: this.options.defaultTableCellProperties.backgroundColor,\n            colorPickerConfig: this.options.colorPickerConfig\n        });\n        const backgroundInput = new LabeledFieldView(locale, colorInputCreator);\n        backgroundInput.set({\n            label: t('Color'),\n            class: 'ck-table-cell-properties-form__background'\n        });\n        backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');\n        backgroundInput.fieldView.on('input', ()=>{\n            this.backgroundColor = backgroundInput.fieldView.value;\n        });\n        return {\n            backgroundRowLabel,\n            backgroundInput\n        };\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #widthInput}.\n\t * * {@link #heightInput}.\n\t */ _createDimensionFields() {\n        const locale = this.locale;\n        const t = this.t;\n        // -- Label ---------------------------------------------------\n        const dimensionsLabel = new LabelView(locale);\n        dimensionsLabel.text = t('Dimensions');\n        // -- Width ---------------------------------------------------\n        const widthInput = new LabeledFieldView(locale, createLabeledInputText);\n        widthInput.set({\n            label: t('Width'),\n            class: 'ck-table-form__dimensions-row__width'\n        });\n        widthInput.fieldView.bind('value').to(this, 'width');\n        widthInput.fieldView.on('input', ()=>{\n            this.width = widthInput.fieldView.element.value;\n        });\n        // -- Operator ---------------------------------------------------\n        const operatorLabel = new View(locale);\n        operatorLabel.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck-table-form__dimension-operator'\n                ]\n            },\n            children: [\n                {\n                    text: '×'\n                }\n            ]\n        });\n        // -- Height ---------------------------------------------------\n        const heightInput = new LabeledFieldView(locale, createLabeledInputText);\n        heightInput.set({\n            label: t('Height'),\n            class: 'ck-table-form__dimensions-row__height'\n        });\n        heightInput.fieldView.bind('value').to(this, 'height');\n        heightInput.fieldView.on('input', ()=>{\n            this.height = heightInput.fieldView.element.value;\n        });\n        return {\n            dimensionsLabel,\n            widthInput,\n            operatorLabel,\n            heightInput\n        };\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #paddingInput}.\n\t */ _createPaddingField() {\n        const locale = this.locale;\n        const t = this.t;\n        const paddingInput = new LabeledFieldView(locale, createLabeledInputText);\n        paddingInput.set({\n            label: t('Padding'),\n            class: 'ck-table-cell-properties-form__padding'\n        });\n        paddingInput.fieldView.bind('value').to(this, 'padding');\n        paddingInput.fieldView.on('input', ()=>{\n            this.padding = paddingInput.fieldView.element.value;\n        });\n        return paddingInput;\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #horizontalAlignmentToolbar},\n\t * * {@link #verticalAlignmentToolbar}.\n\t */ _createAlignmentFields() {\n        const locale = this.locale;\n        const t = this.t;\n        const alignmentLabel = new LabelView(locale);\n        const ALIGNMENT_ICONS = {\n            left: icons.alignLeft,\n            center: icons.alignCenter,\n            right: icons.alignRight,\n            justify: icons.alignJustify,\n            top: icons.alignTop,\n            middle: icons.alignMiddle,\n            bottom: icons.alignBottom\n        };\n        alignmentLabel.text = t('Table cell text alignment');\n        // -- Horizontal ---------------------------------------------------\n        const horizontalAlignmentToolbar = new ToolbarView(locale);\n        const isContentRTL = locale.contentLanguageDirection === 'rtl';\n        horizontalAlignmentToolbar.set({\n            isCompact: true,\n            ariaLabel: t('Horizontal text alignment toolbar')\n        });\n        fillToolbar({\n            view: this,\n            icons: ALIGNMENT_ICONS,\n            toolbar: horizontalAlignmentToolbar,\n            labels: this._horizontalAlignmentLabels,\n            propertyName: 'horizontalAlignment',\n            nameToValue: (name)=>{\n                // For the RTL content, we want to swap the buttons \"align to the left\" and \"align to the right\".\n                if (isContentRTL) {\n                    if (name === 'left') {\n                        return 'right';\n                    } else if (name === 'right') {\n                        return 'left';\n                    }\n                }\n                return name;\n            },\n            defaultValue: this.options.defaultTableCellProperties.horizontalAlignment\n        });\n        // -- Vertical -----------------------------------------------------\n        const verticalAlignmentToolbar = new ToolbarView(locale);\n        verticalAlignmentToolbar.set({\n            isCompact: true,\n            ariaLabel: t('Vertical text alignment toolbar')\n        });\n        fillToolbar({\n            view: this,\n            icons: ALIGNMENT_ICONS,\n            toolbar: verticalAlignmentToolbar,\n            labels: this._verticalAlignmentLabels,\n            propertyName: 'verticalAlignment',\n            defaultValue: this.options.defaultTableCellProperties.verticalAlignment\n        });\n        return {\n            horizontalAlignmentToolbar,\n            verticalAlignmentToolbar,\n            alignmentLabel\n        };\n    }\n    /**\n\t * Creates the following form controls:\n\t *\n\t * * {@link #saveButtonView},\n\t * * {@link #cancelButtonView}.\n\t */ _createActionButtons() {\n        const locale = this.locale;\n        const t = this.t;\n        const saveButtonView = new ButtonView(locale);\n        const cancelButtonView = new ButtonView(locale);\n        const fieldsThatShouldValidateToSave = [\n            this.borderWidthInput,\n            this.borderColorInput,\n            this.backgroundInput,\n            this.paddingInput\n        ];\n        saveButtonView.set({\n            label: t('Save'),\n            icon: icons.check,\n            class: 'ck-button-save',\n            type: 'submit',\n            withText: true\n        });\n        saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{\n            return errorTexts.every((errorText)=>!errorText);\n        });\n        cancelButtonView.set({\n            label: t('Cancel'),\n            icon: icons.cancel,\n            class: 'ck-button-cancel',\n            withText: true\n        });\n        cancelButtonView.delegate('execute').to(this, 'cancel');\n        return {\n            saveButtonView,\n            cancelButtonView\n        };\n    }\n    /**\n\t * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.\n\t */ get _horizontalAlignmentLabels() {\n        const locale = this.locale;\n        const t = this.t;\n        const left = t('Align cell text to the left');\n        const center = t('Align cell text to the center');\n        const right = t('Align cell text to the right');\n        const justify = t('Justify cell text');\n        // Returns object with a proper order of labels.\n        if (locale.uiLanguageDirection === 'rtl') {\n            return {\n                right,\n                center,\n                left,\n                justify\n            };\n        } else {\n            return {\n                left,\n                center,\n                right,\n                justify\n            };\n        }\n    }\n    /**\n\t * Provides localized labels for {@link #verticalAlignmentToolbar} buttons.\n\t */ get _verticalAlignmentLabels() {\n        const t = this.t;\n        return {\n            top: t('Align cell text to the top'),\n            middle: t('Align cell text to the middle'),\n            bottom: t('Align cell text to the bottom')\n        };\n    }\n}\nfunction isBorderStyleSet$1(value) {\n    return value !== 'none';\n}\n\nconst BALLOON_POSITIONS = /* #__PURE__ */ (()=>[\n        BalloonPanelView.defaultPositions.northArrowSouth,\n        BalloonPanelView.defaultPositions.northArrowSouthWest,\n        BalloonPanelView.defaultPositions.northArrowSouthEast,\n        BalloonPanelView.defaultPositions.southArrowNorth,\n        BalloonPanelView.defaultPositions.southArrowNorthWest,\n        BalloonPanelView.defaultPositions.southArrowNorthEast,\n        BalloonPanelView.defaultPositions.viewportStickyNorth\n    ])();\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the table in the editor content, if one is selected.\n *\n * @param editor The editor instance.\n * @param target Either \"cell\" or \"table\". Determines the target the balloon will be attached to.\n */ function repositionContextualBalloon(editor, target) {\n    const balloon = editor.plugins.get('ContextualBalloon');\n    const selection = editor.editing.view.document.selection;\n    let position;\n    if (target === 'cell') {\n        if (getTableWidgetAncestor(selection)) {\n            position = getBalloonCellPositionData(editor);\n        }\n    } else if (getSelectionAffectedTableWidget(selection)) {\n        position = getBalloonTablePositionData(editor);\n    }\n    if (position) {\n        balloon.updatePosition(position);\n    }\n}\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected table in the editor content.\n *\n * @param editor The editor instance.\n */ function getBalloonTablePositionData(editor) {\n    const selection = editor.model.document.selection;\n    const modelTable = getSelectionAffectedTable(selection);\n    const viewTable = editor.editing.mapper.toViewElement(modelTable);\n    return {\n        target: editor.editing.view.domConverter.mapViewToDom(viewTable),\n        positions: BALLOON_POSITIONS\n    };\n}\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected table cell in the editor content.\n *\n * @param editor The editor instance.\n */ function getBalloonCellPositionData(editor) {\n    const mapper = editor.editing.mapper;\n    const domConverter = editor.editing.view.domConverter;\n    const selection = editor.model.document.selection;\n    if (selection.rangeCount > 1) {\n        return {\n            target: ()=>createBoundingRect(selection.getRanges(), editor),\n            positions: BALLOON_POSITIONS\n        };\n    }\n    const modelTableCell = getTableCellAtPosition(selection.getFirstPosition());\n    const viewTableCell = mapper.toViewElement(modelTableCell);\n    return {\n        target: domConverter.mapViewToDom(viewTableCell),\n        positions: BALLOON_POSITIONS\n    };\n}\n/**\n * Returns the first selected table cell from a multi-cell or in-cell selection.\n *\n * @param position Document position.\n */ function getTableCellAtPosition(position) {\n    const isTableCellSelected = position.nodeAfter && position.nodeAfter.is('element', 'tableCell');\n    return isTableCellSelected ? position.nodeAfter : position.findAncestor('tableCell');\n}\n/**\n * Returns bounding rectangle for given model ranges.\n *\n * @param ranges Model ranges that the bounding rect should be returned for.\n * @param editor The editor instance.\n */ function createBoundingRect(ranges, editor) {\n    const mapper = editor.editing.mapper;\n    const domConverter = editor.editing.view.domConverter;\n    const rects = Array.from(ranges).map((range)=>{\n        const modelTableCell = getTableCellAtPosition(range.start);\n        const viewTableCell = mapper.toViewElement(modelTableCell);\n        return new Rect(domConverter.mapViewToDom(viewTableCell));\n    });\n    return Rect.getBoundingRect(rects);\n}\n\nvar tableCellProperties = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m11.105 18-.17 1H2.5A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1h15A1.5 1.5 0 0 1 19 2.5v9.975l-.85-.124-.15-.302V8h-5v4h.021l-.172.351-1.916.28-.151.027c-.287.063-.54.182-.755.341L8 13v5h3.105zM2 12h5V8H2v4zm10-4H8v4h4V8zM2 2v5h5V2H2zm0 16h5v-5H2v5zM13 7h5V2h-5v5zM8 2v5h4V2H8z\\\" opacity=\\\".6\\\"/><path d=\\\"m15.5 11.5 1.323 2.68 2.957.43-2.14 2.085.505 2.946L15.5 18.25l-2.645 1.39.505-2.945-2.14-2.086 2.957-.43L15.5 11.5zM13 6a1 1 0 0 1 1 1v3.172a2.047 2.047 0 0 0-.293.443l-.858 1.736-1.916.28-.151.027A1.976 1.976 0 0 0 9.315 14H7a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6zm-1 2H8v4h4V8z\\\"/></svg>\";\n\n/**\n * Returns a string if all four values of box sides are equal.\n *\n * If a string is passed, it is treated as a single value (pass-through).\n *\n * ```ts\n * // Returns 'foo':\n * getSingleValue( { top: 'foo', right: 'foo', bottom: 'foo', left: 'foo' } );\n * getSingleValue( 'foo' );\n *\n * // Returns undefined:\n * getSingleValue( { top: 'foo', right: 'foo', bottom: 'bar', left: 'foo' } );\n * getSingleValue( { top: 'foo', right: 'foo' } );\n * ```\n */ function getSingleValue(objectOrString) {\n    if (!objectOrString || !isObject(objectOrString)) {\n        return objectOrString;\n    }\n    const { top, right, bottom, left } = objectOrString;\n    if (top == right && right == bottom && bottom == left) {\n        return top;\n    }\n}\n/**\n * Adds a unit to a value if the value is a number or a string representing a number.\n *\n * **Note**: It does nothing to non-numeric values.\n *\n * ```ts\n * getSingleValue( 25, 'px' ); // '25px'\n * getSingleValue( 25, 'em' ); // '25em'\n * getSingleValue( '25em', 'px' ); // '25em'\n * getSingleValue( 'foo', 'px' ); // 'foo'\n * ```\n *\n * @param defaultUnit A default unit added to a numeric value.\n */ function addDefaultUnitToNumericValue(value, defaultUnit) {\n    const numericValue = parseFloat(value);\n    if (Number.isNaN(numericValue)) {\n        return value;\n    }\n    if (String(numericValue) !== String(value)) {\n        return value;\n    }\n    return `${numericValue}${defaultUnit}`;\n}\n/**\n * Returns the normalized configuration.\n *\n * @param config The configuration to normalize.\n * @param options Options used to determine which properties should be added.\n */ function getNormalizedDefaultProperties(config, options = {}) {\n    const normalizedConfig = {\n        borderStyle: 'none',\n        borderWidth: '',\n        borderColor: '',\n        backgroundColor: '',\n        width: '',\n        height: '',\n        ...config\n    };\n    if (options.includeAlignmentProperty && !normalizedConfig.alignment) {\n        normalizedConfig.alignment = 'center';\n    }\n    if (options.includePaddingProperty && !normalizedConfig.padding) {\n        normalizedConfig.padding = '';\n    }\n    if (options.includeVerticalAlignmentProperty && !normalizedConfig.verticalAlignment) {\n        normalizedConfig.verticalAlignment = 'middle';\n    }\n    if (options.includeHorizontalAlignmentProperty && !normalizedConfig.horizontalAlignment) {\n        normalizedConfig.horizontalAlignment = options.isRightToLeftContent ? 'right' : 'left';\n    }\n    return normalizedConfig;\n}\n/**\n * Returns the normalized default table properties.\n *\n * @param config The configuration to normalize.\n * @param options Options used to determine which properties should be added.\n */ function getNormalizedDefaultTableProperties(config, options) {\n    return getNormalizedDefaultProperties({\n        // It adds support for border none in the table element, keep it in sync with the content styles\n        // See more: https://github.com/ckeditor/ckeditor5/issues/6841#issuecomment-1959195608\n        borderStyle: 'double',\n        borderColor: 'hsl(0, 0%, 70%)',\n        borderWidth: '1px',\n        ...config\n    }, options);\n}\n/**\n * Returns the normalized default cell properties.\n *\n * @param config The configuration to normalize.\n * @param options Options used to determine which properties should be added.\n */ function getNormalizedDefaultCellProperties(config, options) {\n    return getNormalizedDefaultProperties({\n        // It adds support for border none in the table element, keep it in sync with the content styles\n        // See more: https://github.com/ckeditor/ckeditor5/issues/6841#issuecomment-1959195608\n        borderStyle: 'solid',\n        borderColor: 'hsl(0, 0%, 75%)',\n        borderWidth: '1px',\n        ...config\n    }, options);\n}\n\nconst ERROR_TEXT_TIMEOUT$1 = 500;\n// Map of view properties and related commands.\nconst propertyToCommandMap$1 = {\n    borderStyle: 'tableCellBorderStyle',\n    borderColor: 'tableCellBorderColor',\n    borderWidth: 'tableCellBorderWidth',\n    height: 'tableCellHeight',\n    width: 'tableCellWidth',\n    padding: 'tableCellPadding',\n    backgroundColor: 'tableCellBackgroundColor',\n    horizontalAlignment: 'tableCellHorizontalAlignment',\n    verticalAlignment: 'tableCellVerticalAlignment'\n};\n/**\n * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button\n * that opens a form allowing to specify the visual styling of a table cell.\n *\n * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */ class TableCellPropertiesUI extends Plugin {\n    /**\n\t * The default table cell properties.\n\t */ _defaultTableCellProperties;\n    /**\n\t * The contextual balloon plugin instance.\n\t */ _balloon;\n    /**\n\t * The cell properties form view displayed inside the balloon.\n\t */ view;\n    /**\n\t * The batch used to undo all changes made by the form (which are live, as the user types)\n\t * when \"Cancel\" was pressed. Each time the view is shown, a new batch is created.\n\t */ _undoStepBatch;\n    /**\n\t * Flag used to indicate whether view is ready to execute update commands\n\t * (it finished loading initial data).\n\t */ _isReady;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableCellPropertiesUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('table.tableCellProperties', {\n            borderColors: defaultColors,\n            backgroundColors: defaultColors\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.t;\n        this._defaultTableCellProperties = getNormalizedDefaultCellProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {\n            includeVerticalAlignmentProperty: true,\n            includeHorizontalAlignmentProperty: true,\n            includePaddingProperty: true,\n            isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'\n        });\n        this._balloon = editor.plugins.get(ContextualBalloon);\n        this.view = null;\n        this._isReady = false;\n        editor.ui.componentFactory.add('tableCellProperties', (locale)=>{\n            const view = new ButtonView(locale);\n            view.set({\n                label: t('Cell properties'),\n                icon: tableCellProperties,\n                tooltip: true\n            });\n            this.listenTo(view, 'execute', ()=>this._showView());\n            const commands = Object.values(propertyToCommandMap$1).map((commandName)=>editor.commands.get(commandName));\n            view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));\n            return view;\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        // Destroy created UI components as they are not automatically destroyed.\n        // See https://github.com/ckeditor/ckeditor5/issues/1341.\n        if (this.view) {\n            this.view.destroy();\n        }\n    }\n    /**\n\t * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.\n\t *\n\t * @returns The cell properties form view instance.\n\t */ _createPropertiesView() {\n        const editor = this.editor;\n        const config = editor.config.get('table.tableCellProperties');\n        const borderColorsConfig = normalizeColorOptions(config.borderColors);\n        const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);\n        const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);\n        const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);\n        const hasColorPicker = config.colorPicker !== false;\n        const view = new TableCellPropertiesView(editor.locale, {\n            borderColors: localizedBorderColors,\n            backgroundColors: localizedBackgroundColors,\n            defaultTableCellProperties: this._defaultTableCellProperties,\n            colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false\n        });\n        const t = editor.t;\n        // Render the view so its #element is available for the clickOutsideHandler.\n        view.render();\n        this.listenTo(view, 'submit', ()=>{\n            this._hideView();\n        });\n        this.listenTo(view, 'cancel', ()=>{\n            // https://github.com/ckeditor/ckeditor5/issues/6180\n            if (this._undoStepBatch.operations.length) {\n                editor.execute('undo', this._undoStepBatch);\n            }\n            this._hideView();\n        });\n        // Close the balloon on Esc key press.\n        view.keystrokes.set('Esc', (data, cancel)=>{\n            this._hideView();\n            cancel();\n        });\n        // Close on click outside of balloon panel element.\n        clickOutsideHandler({\n            emitter: view,\n            activator: ()=>this._isViewInBalloon,\n            contextElements: [\n                this._balloon.view.element\n            ],\n            callback: ()=>this._hideView()\n        });\n        const colorErrorText = getLocalizedColorErrorText(t);\n        const lengthErrorText = getLocalizedLengthErrorText(t);\n        // Create the \"UI -> editor data\" binding.\n        // These listeners update the editor data (via table commands) when any observable\n        // property of the view has changed. They also validate the value and display errors in the UI\n        // when necessary. This makes the view live, which means the changes are\n        // visible in the editing as soon as the user types or changes fields' values.\n        view.on('change:borderStyle', this._getPropertyChangeCallback('tableCellBorderStyle'));\n        view.on('change:borderColor', this._getValidatedPropertyChangeCallback({\n            viewField: view.borderColorInput,\n            commandName: 'tableCellBorderColor',\n            errorText: colorErrorText,\n            validator: colorFieldValidator\n        }));\n        view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({\n            viewField: view.borderWidthInput,\n            commandName: 'tableCellBorderWidth',\n            errorText: lengthErrorText,\n            validator: lineWidthFieldValidator\n        }));\n        view.on('change:padding', this._getValidatedPropertyChangeCallback({\n            viewField: view.paddingInput,\n            commandName: 'tableCellPadding',\n            errorText: lengthErrorText,\n            validator: lengthFieldValidator\n        }));\n        view.on('change:width', this._getValidatedPropertyChangeCallback({\n            viewField: view.widthInput,\n            commandName: 'tableCellWidth',\n            errorText: lengthErrorText,\n            validator: lengthFieldValidator\n        }));\n        view.on('change:height', this._getValidatedPropertyChangeCallback({\n            viewField: view.heightInput,\n            commandName: 'tableCellHeight',\n            errorText: lengthErrorText,\n            validator: lengthFieldValidator\n        }));\n        view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({\n            viewField: view.backgroundInput,\n            commandName: 'tableCellBackgroundColor',\n            errorText: colorErrorText,\n            validator: colorFieldValidator\n        }));\n        view.on('change:horizontalAlignment', this._getPropertyChangeCallback('tableCellHorizontalAlignment'));\n        view.on('change:verticalAlignment', this._getPropertyChangeCallback('tableCellVerticalAlignment'));\n        return view;\n    }\n    /**\n\t * In this method the \"editor data -> UI\" binding is happening.\n\t *\n\t * When executed, this method obtains selected cell property values from various table commands\n\t * and passes them to the {@link #view}.\n\t *\n\t * This way, the UI stays up–to–date with the editor data.\n\t */ _fillViewFormFromCommandValues() {\n        const commands = this.editor.commands;\n        const borderStyleCommand = commands.get('tableCellBorderStyle');\n        Object.entries(propertyToCommandMap$1).map(([property, commandName])=>{\n            const defaultValue = this._defaultTableCellProperties[property] || '';\n            return [\n                property,\n                commands.get(commandName).value || defaultValue\n            ];\n        }).forEach(([property, value])=>{\n            // Do not set the `border-color` and `border-width` fields if `border-style:none`.\n            if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {\n                return;\n            }\n            this.view.set(property, value);\n        });\n        this._isReady = true;\n    }\n    /**\n\t * Shows the {@link #view} in the {@link #_balloon}.\n\t *\n\t * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains\n\t * all changes made to the document when the view is visible, allowing a single undo step\n\t * for all of them.\n\t */ _showView() {\n        const editor = this.editor;\n        if (!this.view) {\n            this.view = this._createPropertiesView();\n        }\n        this.listenTo(editor.ui, 'update', ()=>{\n            this._updateView();\n        });\n        // Update the view with the model values.\n        this._fillViewFormFromCommandValues();\n        this._balloon.add({\n            view: this.view,\n            position: getBalloonCellPositionData(editor)\n        });\n        // Create a new batch. Clicking \"Cancel\" will undo this batch.\n        this._undoStepBatch = editor.model.createBatch();\n        // Basic a11y.\n        this.view.focus();\n    }\n    /**\n\t * Removes the {@link #view} from the {@link #_balloon}.\n\t */ _hideView() {\n        const editor = this.editor;\n        this.stopListening(editor.ui, 'update');\n        this._isReady = false;\n        // Blur any input element before removing it from DOM to prevent issues in some browsers.\n        // See https://github.com/ckeditor/ckeditor5/issues/1501.\n        this.view.saveButtonView.focus();\n        this._balloon.remove(this.view);\n        // Make sure the focus is not lost in the process by putting it directly\n        // into the editing view.\n        this.editor.editing.view.focus();\n    }\n    /**\n\t * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.\n\t */ _updateView() {\n        const editor = this.editor;\n        const viewDocument = editor.editing.view.document;\n        if (!getTableWidgetAncestor(viewDocument.selection)) {\n            this._hideView();\n        } else if (this._isViewVisible) {\n            repositionContextualBalloon(editor, 'cell');\n        }\n    }\n    /**\n\t * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.\n\t */ get _isViewVisible() {\n        return !!this.view && this._balloon.visibleView === this.view;\n    }\n    /**\n\t * Returns `true` when the {@link #view} is in the {@link #_balloon}.\n\t */ get _isViewInBalloon() {\n        return !!this.view && this._balloon.hasView(this.view);\n    }\n    /**\n\t * Creates a callback that when executed upon the {@link #view view's} property change\n\t * executes a related editor command with the new property value.\n\t *\n\t * @param defaultValue The default value of the command.\n\t */ _getPropertyChangeCallback(commandName) {\n        return (evt, propertyName, newValue)=>{\n            if (!this._isReady) {\n                return;\n            }\n            this.editor.execute(commandName, {\n                value: newValue,\n                batch: this._undoStepBatch\n            });\n        };\n    }\n    /**\n\t * Creates a callback that when executed upon the {@link #view view's} property change:\n\t * * Executes a related editor command with the new property value if the value is valid,\n\t * * Or sets the error text next to the invalid field, if the value did not pass the validation.\n\t */ _getValidatedPropertyChangeCallback(options) {\n        const { commandName, viewField, validator, errorText } = options;\n        const setErrorTextDebounced = debounce(()=>{\n            viewField.errorText = errorText;\n        }, ERROR_TEXT_TIMEOUT$1);\n        return (evt, propertyName, newValue)=>{\n            setErrorTextDebounced.cancel();\n            // Do not execute the command on initial call (opening the table properties view).\n            if (!this._isReady) {\n                return;\n            }\n            if (validator(newValue)) {\n                this.editor.execute(commandName, {\n                    value: newValue,\n                    batch: this._undoStepBatch\n                });\n                viewField.errorText = null;\n            } else {\n                setErrorTextDebounced();\n            }\n        };\n    }\n}\n\n/**\n * The table cell attribute command.\n *\n * The command is a base command for other table cell property commands.\n */ class TableCellPropertyCommand extends Command {\n    /**\n\t * The attribute that will be set by the command.\n\t */ attributeName;\n    /**\n\t * The default value for the attribute.\n\t */ _defaultValue;\n    /**\n\t * Creates a new `TableCellPropertyCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param attributeName Table cell attribute name.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, attributeName, defaultValue){\n        super(editor);\n        this.attributeName = attributeName;\n        this._defaultValue = defaultValue;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const selectedTableCells = tableUtils.getSelectionAffectedTableCells(editor.model.document.selection);\n        this.isEnabled = !!selectedTableCells.length;\n        this.value = this._getSingleValue(selectedTableCells);\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.value If set, the command will set the attribute on selected table cells.\n\t * If it is not set, the command will remove the attribute from the selected table cells.\n\t * @param options.batch Pass the model batch instance to the command to aggregate changes,\n\t * for example to allow a single undo step for multiple executions.\n\t */ execute(options = {}) {\n        const { value, batch } = options;\n        const model = this.editor.model;\n        const tableUtils = this.editor.plugins.get('TableUtils');\n        const tableCells = tableUtils.getSelectionAffectedTableCells(model.document.selection);\n        const valueToSet = this._getValueToSet(value);\n        model.enqueueChange(batch, (writer)=>{\n            if (valueToSet) {\n                tableCells.forEach((tableCell)=>writer.setAttribute(this.attributeName, valueToSet, tableCell));\n            } else {\n                tableCells.forEach((tableCell)=>writer.removeAttribute(this.attributeName, tableCell));\n            }\n        });\n    }\n    /**\n\t * Returns the attribute value for a table cell.\n\t */ _getAttribute(tableCell) {\n        if (!tableCell) {\n            return;\n        }\n        const value = tableCell.getAttribute(this.attributeName);\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n    /**\n\t * Returns the proper model value. It can be used to add a default unit to numeric values.\n\t */ _getValueToSet(value) {\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n    /**\n\t * Returns a single value for all selected table cells. If the value is the same for all cells,\n\t * it will be returned (`undefined` otherwise).\n\t */ _getSingleValue(tableCells) {\n        const firstCellValue = this._getAttribute(tableCells[0]);\n        const everyCellHasAttribute = tableCells.every((tableCells)=>this._getAttribute(tableCells) === firstCellValue);\n        return everyCellHasAttribute ? firstCellValue : undefined;\n    }\n}\n\n/**\n * The table cell width command.\n *\n * The command is registered by the {@link module:table/tablecellwidth/tablecellwidthediting~TableCellWidthEditing} as\n * the `'tableCellWidth'` editor command.\n *\n * To change the width of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellWidth', {\n *   value: '50px'\n * } );\n * ```\n *\n * **Note**: This command adds a default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellWidth', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `width` attribute to `'50px'` in the model.\n */ class TableCellWidthCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellWidth', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValueToSet(value) {\n        value = addDefaultUnitToNumericValue(value, 'px');\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table cell width editing feature.\n *\n * Introduces `tableCellWidth` table cell model attribute alongside with its converters\n * and a command.\n */ class TableCellWidthEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableCellWidthEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const defaultTableCellProperties = getNormalizedDefaultCellProperties(editor.config.get('table.tableCellProperties.defaultProperties'));\n        enableProperty$1(editor.model.schema, editor.conversion, {\n            modelAttribute: 'tableCellWidth',\n            styleName: 'width',\n            defaultValue: defaultTableCellProperties.width\n        });\n        editor.commands.add('tableCellWidth', new TableCellWidthCommand(editor, defaultTableCellProperties.width));\n    }\n}\n\n/**\n * The table cell padding command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellPadding'` editor command.\n *\n * To change the padding of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellPadding', {\n *   value: '5px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellPadding', {\n *   value: '5'\n * } );\n * ```\n *\n * will set the `padding` attribute to `'5px'` in the model.\n */ class TableCellPaddingCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellPaddingCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellPadding', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getAttribute(tableCell) {\n        if (!tableCell) {\n            return;\n        }\n        const value = getSingleValue(tableCell.getAttribute(this.attributeName));\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValueToSet(value) {\n        const newValue = addDefaultUnitToNumericValue(value, 'px');\n        if (newValue === this._defaultValue) {\n            return;\n        }\n        return newValue;\n    }\n}\n\n/**\n * The table cell height command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellHeight'` editor command.\n *\n * To change the height of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellHeight', {\n *   value: '50px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellHeight', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `height` attribute to `'50px'` in the model.\n */ class TableCellHeightCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellHeightCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellHeight', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValueToSet(value) {\n        const newValue = addDefaultUnitToNumericValue(value, 'px');\n        if (newValue === this._defaultValue) {\n            return;\n        }\n        return newValue;\n    }\n}\n\n/**\n * The table cell background color command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBackgroundColor'` editor command.\n *\n * To change the background color of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBackgroundColor', {\n *   value: '#f00'\n * } );\n * ```\n */ class TableCellBackgroundColorCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellBackgroundColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellBackgroundColor', defaultValue);\n    }\n}\n\n/**\n * The table cell vertical alignment command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellVerticalAlignment'` editor command.\n *\n * To change the vertical text alignment of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellVerticalAlignment', {\n *   value: 'top'\n * } );\n * ```\n *\n * The following values, corresponding to the\n * [`vertical-align` CSS attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align), are allowed:\n *\n * * `'top'`\n * * `'bottom'`\n *\n * The `'middle'` value is the default one so there is no need to set it.\n */ class TableCellVerticalAlignmentCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellVerticalAlignmentCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value for the \"alignment\" attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellVerticalAlignment', defaultValue);\n    }\n}\n\n/**\n * The table cell horizontal alignment command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellHorizontalAlignment'` editor command.\n *\n * To change the horizontal text alignment of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellHorizontalAlignment', {\n *  value: 'right'\n * } );\n * ```\n */ class TableCellHorizontalAlignmentCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellHorizontalAlignmentCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value for the \"alignment\" attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellHorizontalAlignment', defaultValue);\n    }\n}\n\n/**\n * The table cell border style command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderStyle'` editor command.\n *\n * To change the border style of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBorderStyle', {\n *   value: 'dashed'\n * } );\n * ```\n */ class TableCellBorderStyleCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellBorderStyleCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellBorderStyle', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getAttribute(tableCell) {\n        if (!tableCell) {\n            return;\n        }\n        const value = getSingleValue(tableCell.getAttribute(this.attributeName));\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table cell border color command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderColor'` editor command.\n *\n * To change the border color of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBorderColor', {\n *   value: '#f00'\n * } );\n * ```\n */ class TableCellBorderColorCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellBorderColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellBorderColor', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getAttribute(tableCell) {\n        if (!tableCell) {\n            return;\n        }\n        const value = getSingleValue(tableCell.getAttribute(this.attributeName));\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table cell border width command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderWidth'` editor command.\n *\n * To change the border width of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBorderWidth', {\n *   value: '5px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellBorderWidth', {\n *   value: '5'\n * } );\n * ```\n *\n * will set the `borderWidth` attribute to `'5px'` in the model.\n */ class TableCellBorderWidthCommand extends TableCellPropertyCommand {\n    /**\n\t * Creates a new `TableCellBorderWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableCellBorderWidth', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getAttribute(tableCell) {\n        if (!tableCell) {\n            return;\n        }\n        const value = getSingleValue(tableCell.getAttribute(this.attributeName));\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValueToSet(value) {\n        const newValue = addDefaultUnitToNumericValue(value, 'px');\n        if (newValue === this._defaultValue) {\n            return;\n        }\n        return newValue;\n    }\n}\n\nconst VALIGN_VALUES_REG_EXP = /^(top|middle|bottom)$/;\nconst ALIGN_VALUES_REG_EXP$1 = /^(left|center|right|justify)$/;\n/**\n * The table cell properties editing feature.\n *\n * Introduces table cell model attributes and their conversion:\n *\n * - border: `tableCellBorderStyle`, `tableCellBorderColor` and `tableCellBorderWidth`\n * - background color: `tableCellBackgroundColor`\n * - cell padding: `tableCellPadding`\n * - horizontal and vertical alignment: `tableCellHorizontalAlignment`, `tableCellVerticalAlignment`\n * - cell width and height: `tableCellWidth`, `tableCellHeight`\n *\n * It also registers commands used to manipulate the above attributes:\n *\n * - border: the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` commands\n * - background color: the `'tableCellBackgroundColor'` command\n * - cell padding: the `'tableCellPadding'` command\n * - horizontal and vertical alignment: the `'tableCellHorizontalAlignment'` and `'tableCellVerticalAlignment'` commands\n * - width and height: the `'tableCellWidth'` and `'tableCellHeight'` commands\n */ class TableCellPropertiesEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableCellPropertiesEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableEditing,\n            TableCellWidthEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const conversion = editor.conversion;\n        editor.config.define('table.tableCellProperties.defaultProperties', {});\n        const defaultTableCellProperties = getNormalizedDefaultCellProperties(editor.config.get('table.tableCellProperties.defaultProperties'), {\n            includeVerticalAlignmentProperty: true,\n            includeHorizontalAlignmentProperty: true,\n            includePaddingProperty: true,\n            isRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'\n        });\n        editor.data.addStyleProcessorRules(addBorderRules);\n        enableBorderProperties$1(schema, conversion, {\n            color: defaultTableCellProperties.borderColor,\n            style: defaultTableCellProperties.borderStyle,\n            width: defaultTableCellProperties.borderWidth\n        });\n        editor.commands.add('tableCellBorderStyle', new TableCellBorderStyleCommand(editor, defaultTableCellProperties.borderStyle));\n        editor.commands.add('tableCellBorderColor', new TableCellBorderColorCommand(editor, defaultTableCellProperties.borderColor));\n        editor.commands.add('tableCellBorderWidth', new TableCellBorderWidthCommand(editor, defaultTableCellProperties.borderWidth));\n        enableProperty$1(schema, conversion, {\n            modelAttribute: 'tableCellHeight',\n            styleName: 'height',\n            defaultValue: defaultTableCellProperties.height\n        });\n        editor.commands.add('tableCellHeight', new TableCellHeightCommand(editor, defaultTableCellProperties.height));\n        editor.data.addStyleProcessorRules(addPaddingRules);\n        enableProperty$1(schema, conversion, {\n            modelAttribute: 'tableCellPadding',\n            styleName: 'padding',\n            reduceBoxSides: true,\n            defaultValue: defaultTableCellProperties.padding\n        });\n        editor.commands.add('tableCellPadding', new TableCellPaddingCommand(editor, defaultTableCellProperties.padding));\n        editor.data.addStyleProcessorRules(addBackgroundRules);\n        enableProperty$1(schema, conversion, {\n            modelAttribute: 'tableCellBackgroundColor',\n            styleName: 'background-color',\n            defaultValue: defaultTableCellProperties.backgroundColor\n        });\n        editor.commands.add('tableCellBackgroundColor', new TableCellBackgroundColorCommand(editor, defaultTableCellProperties.backgroundColor));\n        enableHorizontalAlignmentProperty(schema, conversion, defaultTableCellProperties.horizontalAlignment);\n        editor.commands.add('tableCellHorizontalAlignment', new TableCellHorizontalAlignmentCommand(editor, defaultTableCellProperties.horizontalAlignment));\n        enableVerticalAlignmentProperty(schema, conversion, defaultTableCellProperties.verticalAlignment);\n        editor.commands.add('tableCellVerticalAlignment', new TableCellVerticalAlignmentCommand(editor, defaultTableCellProperties.verticalAlignment));\n    }\n}\n/**\n * Enables the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` attributes for table cells.\n *\n * @param defaultBorder The default border values.\n * @param defaultBorder.color The default `tableCellBorderColor` value.\n * @param defaultBorder.style The default `tableCellBorderStyle` value.\n * @param defaultBorder.width The default `tableCellBorderWidth` value.\n */ function enableBorderProperties$1(schema, conversion, defaultBorder) {\n    const modelAttributes = {\n        width: 'tableCellBorderWidth',\n        color: 'tableCellBorderColor',\n        style: 'tableCellBorderStyle'\n    };\n    schema.extend('tableCell', {\n        allowAttributes: Object.values(modelAttributes)\n    });\n    upcastBorderStyles(conversion, 'td', modelAttributes, defaultBorder);\n    upcastBorderStyles(conversion, 'th', modelAttributes, defaultBorder);\n    downcastAttributeToStyle(conversion, {\n        modelElement: 'tableCell',\n        modelAttribute: modelAttributes.style,\n        styleName: 'border-style'\n    });\n    downcastAttributeToStyle(conversion, {\n        modelElement: 'tableCell',\n        modelAttribute: modelAttributes.color,\n        styleName: 'border-color'\n    });\n    downcastAttributeToStyle(conversion, {\n        modelElement: 'tableCell',\n        modelAttribute: modelAttributes.width,\n        styleName: 'border-width'\n    });\n}\n/**\n * Enables the `'tableCellHorizontalAlignment'` attribute for table cells.\n *\n * @param defaultValue The default horizontal alignment value.\n */ function enableHorizontalAlignmentProperty(schema, conversion, defaultValue) {\n    schema.extend('tableCell', {\n        allowAttributes: [\n            'tableCellHorizontalAlignment'\n        ]\n    });\n    conversion.for('downcast').attributeToAttribute({\n        model: {\n            name: 'tableCell',\n            key: 'tableCellHorizontalAlignment'\n        },\n        view: (alignment)=>({\n                key: 'style',\n                value: {\n                    'text-align': alignment\n                }\n            })\n    });\n    conversion.for('upcast')// Support for the `text-align:*;` CSS definition for the table cell alignment.\n    .attributeToAttribute({\n        view: {\n            name: /^(td|th)$/,\n            styles: {\n                'text-align': ALIGN_VALUES_REG_EXP$1\n            }\n        },\n        model: {\n            key: 'tableCellHorizontalAlignment',\n            value: (viewElement)=>{\n                const align = viewElement.getStyle('text-align');\n                return align === defaultValue ? null : align;\n            }\n        }\n    })// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n    .attributeToAttribute({\n        view: {\n            name: /^(td|th)$/,\n            attributes: {\n                align: ALIGN_VALUES_REG_EXP$1\n            }\n        },\n        model: {\n            key: 'tableCellHorizontalAlignment',\n            value: (viewElement)=>{\n                const align = viewElement.getAttribute('align');\n                return align === defaultValue ? null : align;\n            }\n        }\n    });\n}\n/**\n * Enables the `'verticalAlignment'` attribute for table cells.\n *\n * @param defaultValue The default vertical alignment value.\n */ function enableVerticalAlignmentProperty(schema, conversion, defaultValue) {\n    schema.extend('tableCell', {\n        allowAttributes: [\n            'tableCellVerticalAlignment'\n        ]\n    });\n    conversion.for('downcast').attributeToAttribute({\n        model: {\n            name: 'tableCell',\n            key: 'tableCellVerticalAlignment'\n        },\n        view: (alignment)=>({\n                key: 'style',\n                value: {\n                    'vertical-align': alignment\n                }\n            })\n    });\n    conversion.for('upcast')// Support for the `vertical-align:*;` CSS definition for the table cell alignment.\n    .attributeToAttribute({\n        view: {\n            name: /^(td|th)$/,\n            styles: {\n                'vertical-align': VALIGN_VALUES_REG_EXP\n            }\n        },\n        model: {\n            key: 'tableCellVerticalAlignment',\n            value: (viewElement)=>{\n                const align = viewElement.getStyle('vertical-align');\n                return align === defaultValue ? null : align;\n            }\n        }\n    })// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n    .attributeToAttribute({\n        view: {\n            name: /^(td|th)$/,\n            attributes: {\n                valign: VALIGN_VALUES_REG_EXP\n            }\n        },\n        model: {\n            key: 'tableCellVerticalAlignment',\n            value: (viewElement)=>{\n                const valign = viewElement.getAttribute('valign');\n                return valign === defaultValue ? null : valign;\n            }\n        }\n    });\n}\n\n/**\n * The table cell properties feature. Enables support for setting properties of table cells (size, border, background, etc.).\n *\n * Read more in the {@glink features/tables/tables-styling Table and cell styling tools} section.\n * See also the {@link module:table/tableproperties~TableProperties} plugin.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing table cell properties editing feature} and\n * the {@link module:table/tablecellproperties/tablecellpropertiesui~TableCellPropertiesUI table cell properties UI feature}.\n */ class TableCellProperties extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableCellProperties';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableCellPropertiesEditing,\n            TableCellPropertiesUI\n        ];\n    }\n}\n\n/**\n * The table cell attribute command.\n *\n * This command is a base command for other table property commands.\n */ class TablePropertyCommand extends Command {\n    /**\n\t * The attribute that will be set by the command.\n\t */ attributeName;\n    /**\n\t * The default value for the attribute.\n\t */ _defaultValue;\n    /**\n\t * Creates a new `TablePropertyCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param attributeName Table cell attribute name.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, attributeName, defaultValue){\n        super(editor);\n        this.attributeName = attributeName;\n        this._defaultValue = defaultValue;\n    }\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const selection = editor.model.document.selection;\n        const table = getSelectionAffectedTable(selection);\n        this.isEnabled = !!table;\n        this.value = this._getValue(table);\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.value If set, the command will set the attribute on the selected table.\n\t * If not set, the command will remove the attribute from the selected table.\n\t * @param options.batch Pass the model batch instance to the command to aggregate changes,\n\t * for example, to allow a single undo step for multiple executions.\n\t */ execute(options = {}) {\n        const model = this.editor.model;\n        const selection = model.document.selection;\n        const { value, batch } = options;\n        const table = getSelectionAffectedTable(selection);\n        const valueToSet = this._getValueToSet(value);\n        model.enqueueChange(batch, (writer)=>{\n            if (valueToSet) {\n                writer.setAttribute(this.attributeName, valueToSet, table);\n            } else {\n                writer.removeAttribute(this.attributeName, table);\n            }\n        });\n    }\n    /**\n\t * Returns the attribute value for a table.\n\t */ _getValue(table) {\n        if (!table) {\n            return;\n        }\n        const value = table.getAttribute(this.attributeName);\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n    /**\n\t * Returns the proper model value. It can be used to add a default unit to numeric values.\n\t */ _getValueToSet(value) {\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table background color command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBackgroundColor'` editor command.\n *\n * To change the background color of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBackgroundColor', {\n *   value: '#f00'\n * } );\n * ```\n */ class TableBackgroundColorCommand extends TablePropertyCommand {\n    /**\n\t * Creates a new `TableBackgroundColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableBackgroundColor', defaultValue);\n    }\n}\n\n/**\n * The table border color command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderColor'` editor command.\n *\n * To change the border color of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBorderColor', {\n *   value: '#f00'\n * } );\n * ```\n */ class TableBorderColorCommand extends TablePropertyCommand {\n    /**\n\t * Creates a new `TableBorderColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableBorderColor', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValue(table) {\n        if (!table) {\n            return;\n        }\n        const value = getSingleValue(table.getAttribute(this.attributeName));\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table style border command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderStyle'` editor command.\n *\n * To change the border style of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBorderStyle', {\n *   value: 'dashed'\n * } );\n * ```\n */ class TableBorderStyleCommand extends TablePropertyCommand {\n    /**\n\t * Creates a new `TableBorderStyleCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableBorderStyle', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValue(table) {\n        if (!table) {\n            return;\n        }\n        const value = getSingleValue(table.getAttribute(this.attributeName));\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table width border command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderWidth'` editor command.\n *\n * To change the border width of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBorderWidth', {\n *   value: '5px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableBorderWidth', {\n *   value: '5'\n * } );\n * ```\n *\n * will set the `borderWidth` attribute to `'5px'` in the model.\n */ class TableBorderWidthCommand extends TablePropertyCommand {\n    /**\n\t * Creates a new `TableBorderWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableBorderWidth', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValue(table) {\n        if (!table) {\n            return;\n        }\n        const value = getSingleValue(table.getAttribute(this.attributeName));\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValueToSet(value) {\n        const newValue = addDefaultUnitToNumericValue(value, 'px');\n        if (newValue === this._defaultValue) {\n            return;\n        }\n        return newValue;\n    }\n}\n\n/**\n * The table width command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableWidth'` editor command.\n *\n * To change the width of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableWidth', {\n *   value: '400px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableWidth', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `width` attribute to `'50px'` in the model.\n */ class TableWidthCommand extends TablePropertyCommand {\n    /**\n\t * Creates a new `TableWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableWidth', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValueToSet(value) {\n        value = addDefaultUnitToNumericValue(value, 'px');\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table height command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableHeight'` editor command.\n *\n * To change the height of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableHeight', {\n *   value: '500px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableHeight', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `height` attribute to `'50px'` in the model.\n */ class TableHeightCommand extends TablePropertyCommand {\n    /**\n\t * Creates a new `TableHeightCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableHeight', defaultValue);\n    }\n    /**\n\t * @inheritDoc\n\t */ _getValueToSet(value) {\n        value = addDefaultUnitToNumericValue(value, 'px');\n        if (value === this._defaultValue) {\n            return;\n        }\n        return value;\n    }\n}\n\n/**\n * The table alignment command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableAlignment'` editor command.\n *\n * To change the alignment of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableAlignment', {\n *   value: 'right'\n * } );\n * ```\n */ class TableAlignmentCommand extends TablePropertyCommand {\n    /**\n\t * Creates a new `TableAlignmentCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value for the \"alignment\" attribute.\n\t */ constructor(editor, defaultValue){\n        super(editor, 'tableAlignment', defaultValue);\n    }\n}\n\nconst ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;\nconst FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;\n/**\n * The table properties editing feature.\n *\n * Introduces table's model attributes and their conversion:\n *\n * - border: `tableBorderStyle`, `tableBorderColor` and `tableBorderWidth`\n * - background color: `tableBackgroundColor`\n * - horizontal alignment: `tableAlignment`\n * - width & height: `tableWidth` & `tableHeight`\n *\n * It also registers commands used to manipulate the above attributes:\n *\n * - border: `'tableBorderStyle'`, `'tableBorderColor'` and `'tableBorderWidth'` commands\n * - background color: `'tableBackgroundColor'`\n * - horizontal alignment: `'tableAlignment'`\n * - width & height: `'tableWidth'` & `'tableHeight'`\n */ class TablePropertiesEditing extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TablePropertiesEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const conversion = editor.conversion;\n        editor.config.define('table.tableProperties.defaultProperties', {});\n        const defaultTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {\n            includeAlignmentProperty: true\n        });\n        editor.data.addStyleProcessorRules(addBorderRules);\n        enableBorderProperties(schema, conversion, {\n            color: defaultTableProperties.borderColor,\n            style: defaultTableProperties.borderStyle,\n            width: defaultTableProperties.borderWidth\n        });\n        editor.commands.add('tableBorderColor', new TableBorderColorCommand(editor, defaultTableProperties.borderColor));\n        editor.commands.add('tableBorderStyle', new TableBorderStyleCommand(editor, defaultTableProperties.borderStyle));\n        editor.commands.add('tableBorderWidth', new TableBorderWidthCommand(editor, defaultTableProperties.borderWidth));\n        enableAlignmentProperty(schema, conversion, defaultTableProperties.alignment);\n        editor.commands.add('tableAlignment', new TableAlignmentCommand(editor, defaultTableProperties.alignment));\n        enableTableToFigureProperty(schema, conversion, {\n            modelAttribute: 'tableWidth',\n            styleName: 'width',\n            defaultValue: defaultTableProperties.width\n        });\n        editor.commands.add('tableWidth', new TableWidthCommand(editor, defaultTableProperties.width));\n        enableTableToFigureProperty(schema, conversion, {\n            modelAttribute: 'tableHeight',\n            styleName: 'height',\n            defaultValue: defaultTableProperties.height\n        });\n        editor.commands.add('tableHeight', new TableHeightCommand(editor, defaultTableProperties.height));\n        editor.data.addStyleProcessorRules(addBackgroundRules);\n        enableProperty(schema, conversion, {\n            modelAttribute: 'tableBackgroundColor',\n            styleName: 'background-color',\n            defaultValue: defaultTableProperties.backgroundColor\n        });\n        editor.commands.add('tableBackgroundColor', new TableBackgroundColorCommand(editor, defaultTableProperties.backgroundColor));\n    }\n}\n/**\n * Enables `tableBorderStyle'`, `tableBorderColor'` and `tableBorderWidth'` attributes for table.\n *\n * @param defaultBorder The default border values.\n * @param defaultBorder.color The default `tableBorderColor` value.\n * @param defaultBorder.style The default `tableBorderStyle` value.\n * @param defaultBorder.width The default `tableBorderWidth` value.\n */ function enableBorderProperties(schema, conversion, defaultBorder) {\n    const modelAttributes = {\n        width: 'tableBorderWidth',\n        color: 'tableBorderColor',\n        style: 'tableBorderStyle'\n    };\n    schema.extend('table', {\n        allowAttributes: Object.values(modelAttributes)\n    });\n    upcastBorderStyles(conversion, 'table', modelAttributes, defaultBorder);\n    downcastTableAttribute(conversion, {\n        modelAttribute: modelAttributes.color,\n        styleName: 'border-color'\n    });\n    downcastTableAttribute(conversion, {\n        modelAttribute: modelAttributes.style,\n        styleName: 'border-style'\n    });\n    downcastTableAttribute(conversion, {\n        modelAttribute: modelAttributes.width,\n        styleName: 'border-width'\n    });\n}\n/**\n * Enables the `'alignment'` attribute for table.\n *\n * @param defaultValue The default alignment value.\n */ function enableAlignmentProperty(schema, conversion, defaultValue) {\n    schema.extend('table', {\n        allowAttributes: [\n            'tableAlignment'\n        ]\n    });\n    conversion.for('downcast').attributeToAttribute({\n        model: {\n            name: 'table',\n            key: 'tableAlignment'\n        },\n        view: (alignment)=>({\n                key: 'style',\n                value: {\n                    // Model: `alignment:center` => CSS: `float:none`.\n                    float: alignment === 'center' ? 'none' : alignment\n                }\n            }),\n        converterPriority: 'high'\n    });\n    conversion.for('upcast')// Support for the `float:*;` CSS definition for the table alignment.\n    .attributeToAttribute({\n        view: {\n            name: /^(table|figure)$/,\n            styles: {\n                float: FLOAT_VALUES_REG_EXP\n            }\n        },\n        model: {\n            key: 'tableAlignment',\n            value: (viewElement)=>{\n                let align = viewElement.getStyle('float');\n                // CSS: `float:none` => Model: `alignment:center`.\n                if (align === 'none') {\n                    align = 'center';\n                }\n                return align === defaultValue ? null : align;\n            }\n        }\n    })// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n    .attributeToAttribute({\n        view: {\n            attributes: {\n                align: ALIGN_VALUES_REG_EXP\n            }\n        },\n        model: {\n            name: 'table',\n            key: 'tableAlignment',\n            value: (viewElement)=>{\n                const align = viewElement.getAttribute('align');\n                return align === defaultValue ? null : align;\n            }\n        }\n    });\n}\n/**\n * Enables conversion for an attribute for simple view-model mappings.\n *\n * @param options.defaultValue The default value for the specified `modelAttribute`.\n */ function enableProperty(schema, conversion, options) {\n    const { modelAttribute } = options;\n    schema.extend('table', {\n        allowAttributes: [\n            modelAttribute\n        ]\n    });\n    upcastStyleToAttribute(conversion, {\n        viewElement: 'table',\n        ...options\n    });\n    downcastTableAttribute(conversion, options);\n}\n/**\n * Enables conversion for an attribute for simple view (figure) to model (table) mappings.\n */ function enableTableToFigureProperty(schema, conversion, options) {\n    const { modelAttribute } = options;\n    schema.extend('table', {\n        allowAttributes: [\n            modelAttribute\n        ]\n    });\n    upcastStyleToAttribute(conversion, {\n        viewElement: /^(table|figure)$/,\n        shouldUpcast: (element)=>!(element.name == 'table' && element.parent.name == 'figure'),\n        ...options\n    });\n    downcastAttributeToStyle(conversion, {\n        modelElement: 'table',\n        ...options\n    });\n}\n\n/**\n * The class representing a table properties form, allowing users to customize\n * certain style aspects of a table, for instance, border, background color, alignment, etc..\n */ class TablePropertiesView extends View {\n    /**\n\t * Options passed to the view. See {@link #constructor} to learn more.\n\t */ options;\n    /**\n\t * Tracks information about the DOM focus in the form.\n\t */ focusTracker;\n    /**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */ keystrokes;\n    /**\n\t * A collection of child views in the form.\n\t */ children;\n    /**\n\t * A dropdown that allows selecting the style of the table border.\n\t */ borderStyleDropdown;\n    /**\n\t * An input that allows specifying the width of the table border.\n\t */ borderWidthInput;\n    /**\n\t * An input that allows specifying the color of the table border.\n\t */ borderColorInput;\n    /**\n\t * An input that allows specifying the table background color.\n\t */ backgroundInput;\n    /**\n\t * An input that allows specifying the table width.\n\t */ widthInput;\n    /**\n\t * An input that allows specifying the table height.\n\t */ heightInput;\n    /**\n\t * A toolbar with buttons that allow changing the alignment of an entire table.\n\t */ alignmentToolbar;\n    /**\n\t * The \"Save\" button view.\n\t */ saveButtonView;\n    /**\n\t * The \"Cancel\" button view.\n\t */ cancelButtonView;\n    /**\n\t * A collection of views that can be focused in the form.\n\t */ _focusables;\n    /**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */ _focusCycler;\n    /**\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options Additional configuration of the view.\n\t */ constructor(locale, options){\n        super(locale);\n        this.set({\n            borderStyle: '',\n            borderWidth: '',\n            borderColor: '',\n            backgroundColor: '',\n            width: '',\n            height: '',\n            alignment: ''\n        });\n        this.options = options;\n        const { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();\n        const { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();\n        const { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();\n        const { alignmentToolbar, alignmentLabel } = this._createAlignmentFields();\n        this.focusTracker = new FocusTracker();\n        this.keystrokes = new KeystrokeHandler();\n        this.children = this.createCollection();\n        this.borderStyleDropdown = borderStyleDropdown;\n        this.borderWidthInput = borderWidthInput;\n        this.borderColorInput = borderColorInput;\n        this.backgroundInput = backgroundInput;\n        this.widthInput = widthInput;\n        this.heightInput = heightInput;\n        this.alignmentToolbar = alignmentToolbar;\n        // Defer creating to make sure other fields are present and the Save button can\n        // bind its #isEnabled to their error messages so there's no way to save unless all\n        // fields are valid.\n        const { saveButtonView, cancelButtonView } = this._createActionButtons();\n        this.saveButtonView = saveButtonView;\n        this.cancelButtonView = cancelButtonView;\n        this._focusables = new ViewCollection();\n        this._focusCycler = new FocusCycler({\n            focusables: this._focusables,\n            focusTracker: this.focusTracker,\n            keystrokeHandler: this.keystrokes,\n            actions: {\n                // Navigate form fields backwards using the Shift + Tab keystroke.\n                focusPrevious: 'shift + tab',\n                // Navigate form fields forwards using the Tab key.\n                focusNext: 'tab'\n            }\n        });\n        // Form header.\n        this.children.add(new FormHeaderView(locale, {\n            label: this.t('Table properties')\n        }));\n        // Border row.\n        this.children.add(new FormRowView(locale, {\n            labelView: borderRowLabel,\n            children: [\n                borderRowLabel,\n                borderStyleDropdown,\n                borderColorInput,\n                borderWidthInput\n            ],\n            class: 'ck-table-form__border-row'\n        }));\n        // Background row.\n        this.children.add(new FormRowView(locale, {\n            labelView: backgroundRowLabel,\n            children: [\n                backgroundRowLabel,\n                backgroundInput\n            ],\n            class: 'ck-table-form__background-row'\n        }));\n        this.children.add(new FormRowView(locale, {\n            children: [\n                // Dimensions row.\n                new FormRowView(locale, {\n                    labelView: dimensionsLabel,\n                    children: [\n                        dimensionsLabel,\n                        widthInput,\n                        operatorLabel,\n                        heightInput\n                    ],\n                    class: 'ck-table-form__dimensions-row'\n                }),\n                // Alignment row.\n                new FormRowView(locale, {\n                    labelView: alignmentLabel,\n                    children: [\n                        alignmentLabel,\n                        alignmentToolbar\n                    ],\n                    class: 'ck-table-properties-form__alignment-row'\n                })\n            ]\n        }));\n        // Action row.\n        this.children.add(new FormRowView(locale, {\n            children: [\n                this.saveButtonView,\n                this.cancelButtonView\n            ],\n            class: 'ck-table-form__action-row'\n        }));\n        this.setTemplate({\n            tag: 'form',\n            attributes: {\n                class: [\n                    'ck',\n                    'ck-form',\n                    'ck-table-form',\n                    'ck-table-properties-form'\n                ],\n                // https://github.com/ckeditor/ckeditor5-link/issues/90\n                tabindex: '-1'\n            },\n            children: this.children\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ render() {\n        super.render();\n        // Enable the \"submit\" event for this view. It can be triggered by the #saveButtonView\n        // which is of the \"submit\" DOM \"type\".\n        submitHandler({\n            view: this\n        });\n        // Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.\n        [\n            this.borderColorInput,\n            this.backgroundInput\n        ].forEach((view)=>{\n            this._focusCycler.chain(view.fieldView.focusCycler);\n        });\n        [\n            this.borderStyleDropdown,\n            this.borderColorInput,\n            this.borderWidthInput,\n            this.backgroundInput,\n            this.widthInput,\n            this.heightInput,\n            this.alignmentToolbar,\n            this.saveButtonView,\n            this.cancelButtonView\n        ].forEach((view)=>{\n            // Register the view as focusable.\n            this._focusables.add(view);\n            // Register the view in the focus tracker.\n            this.focusTracker.add(view.element);\n        });\n        // Mainly for closing using \"Esc\" and navigation using \"Tab\".\n        this.keystrokes.listenTo(this.element);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        this.focusTracker.destroy();\n        this.keystrokes.destroy();\n    }\n    /**\n\t * Focuses the fist focusable field in the form.\n\t */ focus() {\n        this._focusCycler.focusFirst();\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #borderStyleDropdown},\n\t * * {@link #borderWidthInput},\n\t * * {@link #borderColorInput}.\n\t */ _createBorderFields() {\n        const defaultTableProperties = this.options.defaultTableProperties;\n        const defaultBorder = {\n            style: defaultTableProperties.borderStyle,\n            width: defaultTableProperties.borderWidth,\n            color: defaultTableProperties.borderColor\n        };\n        const colorInputCreator = getLabeledColorInputCreator({\n            colorConfig: this.options.borderColors,\n            columns: 5,\n            defaultColorValue: defaultBorder.color,\n            colorPickerConfig: this.options.colorPickerConfig\n        });\n        const locale = this.locale;\n        const t = this.t;\n        const accessibleLabel = t('Style');\n        // -- Group label ---------------------------------------------\n        const borderRowLabel = new LabelView(locale);\n        borderRowLabel.text = t('Border');\n        // -- Style ---------------------------------------------------\n        const styleLabels = getBorderStyleLabels(t);\n        const borderStyleDropdown = new LabeledFieldView(locale, createLabeledDropdown);\n        borderStyleDropdown.set({\n            label: accessibleLabel,\n            class: 'ck-table-form__border-style'\n        });\n        borderStyleDropdown.fieldView.buttonView.set({\n            ariaLabel: accessibleLabel,\n            ariaLabelledBy: undefined,\n            isOn: false,\n            withText: true,\n            tooltip: accessibleLabel\n        });\n        borderStyleDropdown.fieldView.buttonView.bind('label').to(this, 'borderStyle', (value)=>{\n            return styleLabels[value ? value : 'none'];\n        });\n        borderStyleDropdown.fieldView.on('execute', (evt)=>{\n            this.borderStyle = evt.source._borderStyleValue;\n        });\n        borderStyleDropdown.bind('isEmpty').to(this, 'borderStyle', (value)=>!value);\n        addListToDropdown(borderStyleDropdown.fieldView, getBorderStyleDefinitions(this, defaultBorder.style), {\n            role: 'menu',\n            ariaLabel: accessibleLabel\n        });\n        // -- Width ---------------------------------------------------\n        const borderWidthInput = new LabeledFieldView(locale, createLabeledInputText);\n        borderWidthInput.set({\n            label: t('Width'),\n            class: 'ck-table-form__border-width'\n        });\n        borderWidthInput.fieldView.bind('value').to(this, 'borderWidth');\n        borderWidthInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);\n        borderWidthInput.fieldView.on('input', ()=>{\n            this.borderWidth = borderWidthInput.fieldView.element.value;\n        });\n        // -- Color ---------------------------------------------------\n        const borderColorInput = new LabeledFieldView(locale, colorInputCreator);\n        borderColorInput.set({\n            label: t('Color'),\n            class: 'ck-table-form__border-color'\n        });\n        borderColorInput.fieldView.bind('value').to(this, 'borderColor');\n        borderColorInput.bind('isEnabled').to(this, 'borderStyle', isBorderStyleSet);\n        borderColorInput.fieldView.on('input', ()=>{\n            this.borderColor = borderColorInput.fieldView.value;\n        });\n        // Reset the border color and width fields depending on the `border-style` value.\n        this.on('change:borderStyle', (evt, name, newValue, oldValue)=>{\n            // When removing the border (`border-style:none`), clear the remaining `border-*` properties.\n            // See: https://github.com/ckeditor/ckeditor5/issues/6227.\n            if (!isBorderStyleSet(newValue)) {\n                this.borderColor = '';\n                this.borderWidth = '';\n            }\n            // When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.\n            if (!isBorderStyleSet(oldValue)) {\n                this.borderColor = defaultBorder.color;\n                this.borderWidth = defaultBorder.width;\n            }\n        });\n        return {\n            borderRowLabel,\n            borderStyleDropdown,\n            borderColorInput,\n            borderWidthInput\n        };\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #backgroundInput}.\n\t */ _createBackgroundFields() {\n        const locale = this.locale;\n        const t = this.t;\n        // -- Group label ---------------------------------------------\n        const backgroundRowLabel = new LabelView(locale);\n        backgroundRowLabel.text = t('Background');\n        // -- Background color input -----------------------------------\n        const backgroundInputCreator = getLabeledColorInputCreator({\n            colorConfig: this.options.backgroundColors,\n            columns: 5,\n            defaultColorValue: this.options.defaultTableProperties.backgroundColor,\n            colorPickerConfig: this.options.colorPickerConfig\n        });\n        const backgroundInput = new LabeledFieldView(locale, backgroundInputCreator);\n        backgroundInput.set({\n            label: t('Color'),\n            class: 'ck-table-properties-form__background'\n        });\n        backgroundInput.fieldView.bind('value').to(this, 'backgroundColor');\n        backgroundInput.fieldView.on('input', ()=>{\n            this.backgroundColor = backgroundInput.fieldView.value;\n        });\n        return {\n            backgroundRowLabel,\n            backgroundInput\n        };\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #widthInput},\n\t * * {@link #heightInput}.\n\t */ _createDimensionFields() {\n        const locale = this.locale;\n        const t = this.t;\n        // -- Label ---------------------------------------------------\n        const dimensionsLabel = new LabelView(locale);\n        dimensionsLabel.text = t('Dimensions');\n        // -- Width ---------------------------------------------------\n        const widthInput = new LabeledFieldView(locale, createLabeledInputText);\n        widthInput.set({\n            label: t('Width'),\n            class: 'ck-table-form__dimensions-row__width'\n        });\n        widthInput.fieldView.bind('value').to(this, 'width');\n        widthInput.fieldView.on('input', ()=>{\n            this.width = widthInput.fieldView.element.value;\n        });\n        // -- Operator ---------------------------------------------------\n        const operatorLabel = new View(locale);\n        operatorLabel.setTemplate({\n            tag: 'span',\n            attributes: {\n                class: [\n                    'ck-table-form__dimension-operator'\n                ]\n            },\n            children: [\n                {\n                    text: '×'\n                }\n            ]\n        });\n        // -- Height ---------------------------------------------------\n        const heightInput = new LabeledFieldView(locale, createLabeledInputText);\n        heightInput.set({\n            label: t('Height'),\n            class: 'ck-table-form__dimensions-row__height'\n        });\n        heightInput.fieldView.bind('value').to(this, 'height');\n        heightInput.fieldView.on('input', ()=>{\n            this.height = heightInput.fieldView.element.value;\n        });\n        return {\n            dimensionsLabel,\n            widthInput,\n            operatorLabel,\n            heightInput\n        };\n    }\n    /**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #alignmentToolbar}.\n\t */ _createAlignmentFields() {\n        const locale = this.locale;\n        const t = this.t;\n        // -- Label ---------------------------------------------------\n        const alignmentLabel = new LabelView(locale);\n        alignmentLabel.text = t('Alignment');\n        // -- Toolbar ---------------------------------------------------\n        const alignmentToolbar = new ToolbarView(locale);\n        alignmentToolbar.set({\n            isCompact: true,\n            ariaLabel: t('Table alignment toolbar')\n        });\n        fillToolbar({\n            view: this,\n            icons: {\n                left: icons.objectLeft,\n                center: icons.objectCenter,\n                right: icons.objectRight\n            },\n            toolbar: alignmentToolbar,\n            labels: this._alignmentLabels,\n            propertyName: 'alignment',\n            defaultValue: this.options.defaultTableProperties.alignment\n        });\n        return {\n            alignmentLabel,\n            alignmentToolbar\n        };\n    }\n    /**\n\t * Creates the following form controls:\n\t *\n\t * * {@link #saveButtonView},\n\t * * {@link #cancelButtonView}.\n\t */ _createActionButtons() {\n        const locale = this.locale;\n        const t = this.t;\n        const saveButtonView = new ButtonView(locale);\n        const cancelButtonView = new ButtonView(locale);\n        const fieldsThatShouldValidateToSave = [\n            this.borderWidthInput,\n            this.borderColorInput,\n            this.backgroundInput,\n            this.widthInput,\n            this.heightInput\n        ];\n        saveButtonView.set({\n            label: t('Save'),\n            icon: icons.check,\n            class: 'ck-button-save',\n            type: 'submit',\n            withText: true\n        });\n        saveButtonView.bind('isEnabled').toMany(fieldsThatShouldValidateToSave, 'errorText', (...errorTexts)=>{\n            return errorTexts.every((errorText)=>!errorText);\n        });\n        cancelButtonView.set({\n            label: t('Cancel'),\n            icon: icons.cancel,\n            class: 'ck-button-cancel',\n            withText: true\n        });\n        cancelButtonView.delegate('execute').to(this, 'cancel');\n        return {\n            saveButtonView,\n            cancelButtonView\n        };\n    }\n    /**\n\t * Provides localized labels for {@link #alignmentToolbar} buttons.\n\t */ get _alignmentLabels() {\n        const locale = this.locale;\n        const t = this.t;\n        const left = t('Align table to the left');\n        const center = t('Center table');\n        const right = t('Align table to the right');\n        // Returns object with a proper order of labels.\n        if (locale.uiLanguageDirection === 'rtl') {\n            return {\n                right,\n                center,\n                left\n            };\n        } else {\n            return {\n                left,\n                center,\n                right\n            };\n        }\n    }\n}\nfunction isBorderStyleSet(value) {\n    return value !== 'none';\n}\n\nvar tableProperties = \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M8 2v5h4V2h1v5h5v1h-5v4h.021l-.172.351-1.916.28-.151.027c-.287.063-.54.182-.755.341L8 13v5H7v-5H2v-1h5V8H2V7h5V2h1zm4 6H8v4h4V8z\\\" opacity=\\\".6\\\"/><path d=\\\"m15.5 11.5 1.323 2.68 2.957.43-2.14 2.085.505 2.946L15.5 18.25l-2.645 1.39.505-2.945-2.14-2.086 2.957-.43L15.5 11.5zM17 1a2 2 0 0 1 2 2v9.475l-.85-.124-.857-1.736a2.048 2.048 0 0 0-.292-.44L17 3H3v14h7.808l.402.392L10.935 19H3a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h14z\\\"/></svg>\";\n\nconst ERROR_TEXT_TIMEOUT = 500;\n// Map of view properties and related commands.\nconst propertyToCommandMap = {\n    borderStyle: 'tableBorderStyle',\n    borderColor: 'tableBorderColor',\n    borderWidth: 'tableBorderWidth',\n    backgroundColor: 'tableBackgroundColor',\n    width: 'tableWidth',\n    height: 'tableHeight',\n    alignment: 'tableAlignment'\n};\n/**\n * The table properties UI plugin. It introduces the `'tableProperties'` button\n * that opens a form allowing to specify visual styling of an entire table.\n *\n * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */ class TablePropertiesUI extends Plugin {\n    /**\n\t * The default table properties.\n\t */ _defaultTableProperties;\n    /**\n\t * The contextual balloon plugin instance.\n\t */ _balloon;\n    /**\n\t * The properties form view displayed inside the balloon.\n\t */ view = null;\n    /**\n\t * The batch used to undo all changes made by the form (which are live, as the user types)\n\t * when \"Cancel\" was pressed. Each time the view is shown, a new batch is created.\n\t */ _undoStepBatch;\n    /**\n\t * Flag used to indicate whether view is ready to execute update commands\n\t * (it finished loading initial data).\n\t */ _isReady;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            ContextualBalloon\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TablePropertiesUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        editor.config.define('table.tableProperties', {\n            borderColors: defaultColors,\n            backgroundColors: defaultColors\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const t = editor.t;\n        this._defaultTableProperties = getNormalizedDefaultTableProperties(editor.config.get('table.tableProperties.defaultProperties'), {\n            includeAlignmentProperty: true\n        });\n        this._balloon = editor.plugins.get(ContextualBalloon);\n        editor.ui.componentFactory.add('tableProperties', (locale)=>{\n            const view = new ButtonView(locale);\n            view.set({\n                label: t('Table properties'),\n                icon: tableProperties,\n                tooltip: true\n            });\n            this.listenTo(view, 'execute', ()=>this._showView());\n            const commands = Object.values(propertyToCommandMap).map((commandName)=>editor.commands.get(commandName));\n            view.bind('isEnabled').toMany(commands, 'isEnabled', (...areEnabled)=>areEnabled.some((isCommandEnabled)=>isCommandEnabled));\n            return view;\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        super.destroy();\n        // Destroy created UI components as they are not automatically destroyed.\n        // See https://github.com/ckeditor/ckeditor5/issues/1341.\n        if (this.view) {\n            this.view.destroy();\n        }\n    }\n    /**\n\t * Creates the {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} instance.\n\t *\n\t * @returns The table properties form view instance.\n\t */ _createPropertiesView() {\n        const editor = this.editor;\n        const config = editor.config.get('table.tableProperties');\n        const borderColorsConfig = normalizeColorOptions(config.borderColors);\n        const localizedBorderColors = getLocalizedColorOptions(editor.locale, borderColorsConfig);\n        const backgroundColorsConfig = normalizeColorOptions(config.backgroundColors);\n        const localizedBackgroundColors = getLocalizedColorOptions(editor.locale, backgroundColorsConfig);\n        const hasColorPicker = config.colorPicker !== false;\n        const view = new TablePropertiesView(editor.locale, {\n            borderColors: localizedBorderColors,\n            backgroundColors: localizedBackgroundColors,\n            defaultTableProperties: this._defaultTableProperties,\n            colorPickerConfig: hasColorPicker ? config.colorPicker || {} : false\n        });\n        const t = editor.t;\n        // Render the view so its #element is available for the clickOutsideHandler.\n        view.render();\n        this.listenTo(view, 'submit', ()=>{\n            this._hideView();\n        });\n        this.listenTo(view, 'cancel', ()=>{\n            // https://github.com/ckeditor/ckeditor5/issues/6180\n            if (this._undoStepBatch.operations.length) {\n                editor.execute('undo', this._undoStepBatch);\n            }\n            this._hideView();\n        });\n        // Close the balloon on Esc key press.\n        view.keystrokes.set('Esc', (data, cancel)=>{\n            this._hideView();\n            cancel();\n        });\n        // Close on click outside of balloon panel element.\n        clickOutsideHandler({\n            emitter: view,\n            activator: ()=>this._isViewInBalloon,\n            contextElements: [\n                this._balloon.view.element\n            ],\n            callback: ()=>this._hideView()\n        });\n        const colorErrorText = getLocalizedColorErrorText(t);\n        const lengthErrorText = getLocalizedLengthErrorText(t);\n        // Create the \"UI -> editor data\" binding.\n        // These listeners update the editor data (via table commands) when any observable\n        // property of the view has changed. They also validate the value and display errors in the UI\n        // when necessary. This makes the view live, which means the changes are\n        // visible in the editing as soon as the user types or changes fields' values.\n        view.on('change:borderStyle', this._getPropertyChangeCallback('tableBorderStyle'));\n        view.on('change:borderColor', this._getValidatedPropertyChangeCallback({\n            viewField: view.borderColorInput,\n            commandName: 'tableBorderColor',\n            errorText: colorErrorText,\n            validator: colorFieldValidator\n        }));\n        view.on('change:borderWidth', this._getValidatedPropertyChangeCallback({\n            viewField: view.borderWidthInput,\n            commandName: 'tableBorderWidth',\n            errorText: lengthErrorText,\n            validator: lineWidthFieldValidator\n        }));\n        view.on('change:backgroundColor', this._getValidatedPropertyChangeCallback({\n            viewField: view.backgroundInput,\n            commandName: 'tableBackgroundColor',\n            errorText: colorErrorText,\n            validator: colorFieldValidator\n        }));\n        view.on('change:width', this._getValidatedPropertyChangeCallback({\n            viewField: view.widthInput,\n            commandName: 'tableWidth',\n            errorText: lengthErrorText,\n            validator: lengthFieldValidator\n        }));\n        view.on('change:height', this._getValidatedPropertyChangeCallback({\n            viewField: view.heightInput,\n            commandName: 'tableHeight',\n            errorText: lengthErrorText,\n            validator: lengthFieldValidator\n        }));\n        view.on('change:alignment', this._getPropertyChangeCallback('tableAlignment'));\n        return view;\n    }\n    /**\n\t * In this method the \"editor data -> UI\" binding is happening.\n\t *\n\t * When executed, this method obtains selected table property values from various table commands\n\t * and passes them to the {@link #view}.\n\t *\n\t * This way, the UI stays up–to–date with the editor data.\n\t */ _fillViewFormFromCommandValues() {\n        const commands = this.editor.commands;\n        const borderStyleCommand = commands.get('tableBorderStyle');\n        Object.entries(propertyToCommandMap).map(([property, commandName])=>{\n            const propertyKey = property;\n            const defaultValue = this._defaultTableProperties[propertyKey] || '';\n            return [\n                propertyKey,\n                commands.get(commandName).value || defaultValue\n            ];\n        }).forEach(([property, value])=>{\n            // Do not set the `border-color` and `border-width` fields if `border-style:none`.\n            if ((property === 'borderColor' || property === 'borderWidth') && borderStyleCommand.value === 'none') {\n                return;\n            }\n            this.view.set(property, value);\n        });\n        this._isReady = true;\n    }\n    /**\n\t * Shows the {@link #view} in the {@link #_balloon}.\n\t *\n\t * **Note**: Each time a view is shown, the new {@link #_undoStepBatch} is created that contains\n\t * all changes made to the document when the view is visible, allowing a single undo step\n\t * for all of them.\n\t */ _showView() {\n        const editor = this.editor;\n        if (!this.view) {\n            this.view = this._createPropertiesView();\n        }\n        this.listenTo(editor.ui, 'update', ()=>{\n            this._updateView();\n        });\n        // Update the view with the model values.\n        this._fillViewFormFromCommandValues();\n        this._balloon.add({\n            view: this.view,\n            position: getBalloonTablePositionData(editor)\n        });\n        // Create a new batch. Clicking \"Cancel\" will undo this batch.\n        this._undoStepBatch = editor.model.createBatch();\n        // Basic a11y.\n        this.view.focus();\n    }\n    /**\n\t * Removes the {@link #view} from the {@link #_balloon}.\n\t */ _hideView() {\n        const editor = this.editor;\n        this.stopListening(editor.ui, 'update');\n        this._isReady = false;\n        // Blur any input element before removing it from DOM to prevent issues in some browsers.\n        // See https://github.com/ckeditor/ckeditor5/issues/1501.\n        this.view.saveButtonView.focus();\n        this._balloon.remove(this.view);\n        // Make sure the focus is not lost in the process by putting it directly\n        // into the editing view.\n        this.editor.editing.view.focus();\n    }\n    /**\n\t * Repositions the {@link #_balloon} or hides the {@link #view} if a table is no longer selected.\n\t */ _updateView() {\n        const editor = this.editor;\n        const viewDocument = editor.editing.view.document;\n        if (!getSelectionAffectedTableWidget(viewDocument.selection)) {\n            this._hideView();\n        } else if (this._isViewVisible) {\n            repositionContextualBalloon(editor, 'table');\n        }\n    }\n    /**\n\t * Returns `true` when the {@link #view} is the visible in the {@link #_balloon}.\n\t */ get _isViewVisible() {\n        return !!this.view && this._balloon.visibleView === this.view;\n    }\n    /**\n\t * Returns `true` when the {@link #view} is in the {@link #_balloon}.\n\t */ get _isViewInBalloon() {\n        return !!this.view && this._balloon.hasView(this.view);\n    }\n    /**\n\t * Creates a callback that when executed upon {@link #view view's} property change\n\t * executes a related editor command with the new property value.\n\t *\n\t * If new value will be set to the default value, the command will not be executed.\n\t *\n\t * @param commandName The command that will be executed.\n\t */ _getPropertyChangeCallback(commandName) {\n        return (evt, propertyName, newValue)=>{\n            // Do not execute the command on initial call (opening the table properties view).\n            if (!this._isReady) {\n                return;\n            }\n            this.editor.execute(commandName, {\n                value: newValue,\n                batch: this._undoStepBatch\n            });\n        };\n    }\n    /**\n\t * Creates a callback that when executed upon {@link #view view's} property change:\n\t * * executes a related editor command with the new property value if the value is valid,\n\t * * or sets the error text next to the invalid field, if the value did not pass the validation.\n\t */ _getValidatedPropertyChangeCallback(options) {\n        const { commandName, viewField, validator, errorText } = options;\n        const setErrorTextDebounced = debounce(()=>{\n            viewField.errorText = errorText;\n        }, ERROR_TEXT_TIMEOUT);\n        return (evt, propertyName, newValue)=>{\n            setErrorTextDebounced.cancel();\n            // Do not execute the command on initial call (opening the table properties view).\n            if (!this._isReady) {\n                return;\n            }\n            if (validator(newValue)) {\n                this.editor.execute(commandName, {\n                    value: newValue,\n                    batch: this._undoStepBatch\n                });\n                viewField.errorText = null;\n            } else {\n                setErrorTextDebounced();\n            }\n        };\n    }\n}\n\n/**\n * The table properties feature. Enables support for setting properties of tables (size, border, background, etc.).\n *\n * Read more in the {@glink features/tables/tables-styling Table and cell styling tools} section.\n * See also the {@link module:table/tablecellproperties~TableCellProperties} plugin.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing table properties editing feature} and\n * the {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI table properties UI feature}.\n */ class TableProperties extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableProperties';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TablePropertiesEditing,\n            TablePropertiesUI\n        ];\n    }\n}\n\n/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */ /**\n * @module table/converters/table-caption-post-fixer\n */ /**\n * Injects a table caption post-fixer into the model.\n *\n * The role of the table caption post-fixer is to ensure that the table with caption have the correct structure\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct structure means that:\n *\n * * If there are many caption model element, they are merged into one model.\n * * A final, merged caption model is placed at the end of the table.\n */ function injectTableCaptionPostFixer(model) {\n    model.document.registerPostFixer((writer)=>tableCaptionPostFixer(writer, model));\n}\n/**\n * The table caption post-fixer.\n */ function tableCaptionPostFixer(writer, model) {\n    const changes = model.document.differ.getChanges();\n    let wasFixed = false;\n    for (const entry of changes){\n        if (entry.type != 'insert') {\n            continue;\n        }\n        const positionParent = entry.position.parent;\n        if (positionParent.is('element', 'table') || entry.name == 'table') {\n            const table = entry.name == 'table' ? entry.position.nodeAfter : positionParent;\n            const captionsToMerge = Array.from(table.getChildren()).filter((child)=>child.is('element', 'caption'));\n            const firstCaption = captionsToMerge.shift();\n            if (!firstCaption) {\n                continue;\n            }\n            // Move all the contents of the captions to the first one.\n            for (const caption of captionsToMerge){\n                writer.move(writer.createRangeIn(caption), firstCaption, 'end');\n                writer.remove(caption);\n            }\n            // Make sure the final caption is at the end of the table.\n            if (firstCaption.nextSibling) {\n                writer.move(writer.createRangeOn(firstCaption), table, 'end');\n                wasFixed = true;\n            }\n            // Do we merged captions and/or moved the single caption to the end of the table?\n            wasFixed = !!captionsToMerge.length || wasFixed;\n        }\n    }\n    return wasFixed;\n}\n\n/**\n * Checks if the provided model element is a `table`.\n *\n * @param modelElement Element to check if it is a table.\n */ function isTable(modelElement) {\n    return !!modelElement && modelElement.is('element', 'table');\n}\n/**\n * Returns the caption model element from a given table element. Returns `null` if no caption is found.\n *\n * @param tableModelElement Table element in which we will try to find a caption element.\n */ function getCaptionFromTableModelElement(tableModelElement) {\n    for (const node of tableModelElement.getChildren()){\n        if (node.is('element', 'caption')) {\n            return node;\n        }\n    }\n    return null;\n}\n/**\n * Returns the caption model element for a model selection. Returns `null` if the selection has no caption element ancestor.\n *\n * @param selection The selection checked for caption presence.\n */ function getCaptionFromModelSelection(selection) {\n    const tableElement = getSelectionAffectedTable(selection);\n    if (!tableElement) {\n        return null;\n    }\n    return getCaptionFromTableModelElement(tableElement);\n}\n/**\n * {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a caption.\n *\n * There are two possible forms of the valid caption:\n *  - A `<figcaption>` element inside a `<figure class=\"table\">` element.\n *  - A `<caption>` inside a <table>.\n *\n * @returns Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element cannot be matched.\n */ function matchTableCaptionViewElement(element) {\n    const parent = element.parent;\n    if (element.name == 'figcaption' && parent && parent.is('element', 'figure') && parent.hasClass('table')) {\n        return {\n            name: true\n        };\n    }\n    if (element.name == 'caption' && parent && parent.is('element', 'table')) {\n        return {\n            name: true\n        };\n    }\n    return null;\n}\n\n/**\n * The toggle table caption command.\n *\n * This command is registered by {@link module:table/tablecaption/tablecaptionediting~TableCaptionEditing} as the\n * `'toggleTableCaption'` editor command.\n *\n * Executing this command:\n *\n * * either adds or removes the table caption of a selected table (depending on whether the caption is present or not),\n * * removes the table caption if the selection is anchored in one.\n *\n * ```ts\n * // Toggle the presence of the caption.\n * editor.execute( 'toggleTableCaption' );\n * ```\n *\n * **Note**: You can move the selection to the caption right away as it shows up upon executing this command by using\n * the `focusCaptionOnShow` option:\n *\n * ```ts\n * editor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );\n * ```\n */ class ToggleTableCaptionCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        const editor = this.editor;\n        const tableElement = getSelectionAffectedTable(editor.model.document.selection);\n        this.isEnabled = !!tableElement;\n        if (!this.isEnabled) {\n            this.value = false;\n        } else {\n            this.value = !!getCaptionFromTableModelElement(tableElement);\n        }\n    }\n    /**\n\t * Executes the command.\n\t *\n\t * ```ts\n\t * editor.execute( 'toggleTableCaption' );\n\t * ```\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.focusCaptionOnShow When true and the caption shows up, the selection will be moved into it straight away.\n\t * @fires execute\n\t */ execute({ focusCaptionOnShow = false } = {}) {\n        this.editor.model.change((writer)=>{\n            if (this.value) {\n                this._hideTableCaption(writer);\n            } else {\n                this._showTableCaption(writer, focusCaptionOnShow);\n            }\n        });\n    }\n    /**\n\t * Shows the table caption. Also:\n\t *\n\t * * it attempts to restore the caption content from the `TableCaptionEditing` caption registry,\n\t * * it moves the selection to the caption right away, it the `focusCaptionOnShow` option was set.\n\t *\n\t * @param focusCaptionOnShow Default focus behavior when showing the caption.\n\t */ _showTableCaption(writer, focusCaptionOnShow) {\n        const model = this.editor.model;\n        const tableElement = getSelectionAffectedTable(model.document.selection);\n        const tableCaptionEditing = this.editor.plugins.get('TableCaptionEditing');\n        const savedCaptionElement = tableCaptionEditing._getSavedCaption(tableElement);\n        // Try restoring the caption from the TableCaptionEditing plugin storage.\n        const newCaptionElement = savedCaptionElement || writer.createElement('caption');\n        model.insertContent(newCaptionElement, tableElement, 'end');\n        if (focusCaptionOnShow) {\n            writer.setSelection(newCaptionElement, 'in');\n        }\n    }\n    /**\n\t * Hides the caption of a selected table (or an table caption the selection is anchored to).\n\t *\n\t * The content of the caption is stored in the `TableCaptionEditing` caption registry to make this\n\t * a reversible action.\n\t */ _hideTableCaption(writer) {\n        const model = this.editor.model;\n        const tableElement = getSelectionAffectedTable(model.document.selection);\n        const tableCaptionEditing = this.editor.plugins.get('TableCaptionEditing');\n        const captionElement = getCaptionFromTableModelElement(tableElement);\n        // Store the caption content so it can be restored quickly if the user changes their mind.\n        tableCaptionEditing._saveCaption(tableElement, captionElement);\n        model.deleteContent(writer.createSelection(captionElement, 'on'));\n    }\n}\n\n/**\n * The table caption editing plugin.\n */ class TableCaptionEditing extends Plugin {\n    /**\n\t * A map that keeps saved JSONified table captions and table model elements they are\n\t * associated with.\n\t *\n\t * To learn more about this system, see {@link #_saveCaption}.\n\t */ _savedCaptionsMap;\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableCaptionEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._savedCaptionsMap = new WeakMap();\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const schema = editor.model.schema;\n        const view = editor.editing.view;\n        const t = editor.t;\n        if (!schema.isRegistered('caption')) {\n            schema.register('caption', {\n                allowIn: 'table',\n                allowContentOf: '$block',\n                isLimit: true\n            });\n        } else {\n            schema.extend('caption', {\n                allowIn: 'table'\n            });\n        }\n        editor.commands.add('toggleTableCaption', new ToggleTableCaptionCommand(this.editor));\n        // View -> model converter for the data pipeline.\n        editor.conversion.for('upcast').elementToElement({\n            view: matchTableCaptionViewElement,\n            model: 'caption'\n        });\n        // Model -> view converter for the data pipeline.\n        editor.conversion.for('dataDowncast').elementToElement({\n            model: 'caption',\n            view: (modelElement, { writer })=>{\n                if (!isTable(modelElement.parent)) {\n                    return null;\n                }\n                return writer.createContainerElement('figcaption');\n            }\n        });\n        // Model -> view converter for the editing pipeline.\n        editor.conversion.for('editingDowncast').elementToElement({\n            model: 'caption',\n            view: (modelElement, { writer })=>{\n                if (!isTable(modelElement.parent)) {\n                    return null;\n                }\n                const figcaptionElement = writer.createEditableElement('figcaption');\n                writer.setCustomProperty('tableCaption', true, figcaptionElement);\n                figcaptionElement.placeholder = t('Enter table caption');\n                enablePlaceholder({\n                    view,\n                    element: figcaptionElement,\n                    keepOnFocus: true\n                });\n                return toWidgetEditable(figcaptionElement, writer);\n            }\n        });\n        injectTableCaptionPostFixer(editor.model);\n    }\n    /**\n\t * Returns the saved {@link module:engine/model/element~Element#toJSON JSONified} caption\n\t * of a table model element.\n\t *\n\t * See {@link #_saveCaption}.\n\t *\n\t * @internal\n\t * @param tableModelElement The model element the caption should be returned for.\n\t * @returns The model caption element or `null` if there is none.\n\t */ _getSavedCaption(tableModelElement) {\n        const jsonObject = this._savedCaptionsMap.get(tableModelElement);\n        return jsonObject ? Element.fromJSON(jsonObject) : null;\n    }\n    /**\n\t * Saves a {@link module:engine/model/element~Element#toJSON JSONified} caption for\n\t * a table element to allow restoring it in the future.\n\t *\n\t * A caption is saved every time it gets hidden. The\n\t * user should be able to restore it on demand.\n\t *\n\t * **Note**: The caption cannot be stored in the table model element attribute because,\n\t * for instance, when the model state propagates to collaborators, the attribute would get\n\t * lost (mainly because it does not convert to anything when the caption is hidden) and\n\t * the states of collaborators' models would de-synchronize causing numerous issues.\n\t *\n\t * See {@link #_getSavedCaption}.\n\t *\n\t * @internal\n\t * @param tableModelElement The model element the caption is saved for.\n\t * @param caption The caption model element to be saved.\n\t */ _saveCaption(tableModelElement, caption) {\n        this._savedCaptionsMap.set(tableModelElement, caption.toJSON());\n    }\n}\n\n/**\n  * The table caption UI plugin. It introduces the `'toggleTableCaption'` UI button.\n  */ class TableCaptionUI extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableCaptionUI';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const t = editor.t;\n        editor.ui.componentFactory.add('toggleTableCaption', (locale)=>{\n            const command = editor.commands.get('toggleTableCaption');\n            const view = new ButtonView(locale);\n            view.set({\n                icon: icons.caption,\n                tooltip: true,\n                isToggleable: true\n            });\n            view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled');\n            view.bind('label').to(command, 'value', (value)=>value ? t('Toggle caption off') : t('Toggle caption on'));\n            this.listenTo(view, 'execute', ()=>{\n                editor.execute('toggleTableCaption', {\n                    focusCaptionOnShow: true\n                });\n                // Scroll to the selection and highlight the caption if the caption showed up.\n                if (command.value) {\n                    const modelCaptionElement = getCaptionFromModelSelection(editor.model.document.selection);\n                    const figcaptionElement = editor.editing.mapper.toViewElement(modelCaptionElement);\n                    if (!figcaptionElement) {\n                        return;\n                    }\n                    editingView.scrollToTheSelection();\n                    editingView.change((writer)=>{\n                        writer.addClass('table__caption_highlighted', figcaptionElement);\n                    });\n                }\n                editor.editing.view.focus();\n            });\n            return view;\n        });\n    }\n}\n\n/**\n * The table caption plugin.\n */ class TableCaption extends Plugin {\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableCaption';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableCaptionEditing,\n            TableCaptionUI\n        ];\n    }\n}\n\n/**\n * Command used by the {@link module:table/tablecolumnresize~TableColumnResize Table column resize feature} that\n * updates the width of the whole table as well as its individual columns.\n */ class TableWidthsCommand extends Command {\n    /**\n\t * @inheritDoc\n\t */ refresh() {\n        // The command is always enabled as it doesn't care about the actual selection - table can be resized\n        // even if the selection is elsewhere.\n        this.isEnabled = true;\n    }\n    /**\n\t * Updated the `tableWidth` attribute of the table and the `columnWidth` attribute of the columns of that table.\n\t */ execute(options = {}) {\n        const { model, plugins } = this.editor;\n        let { table = model.document.selection.getSelectedElement(), columnWidths, tableWidth } = options;\n        if (columnWidths) {\n            // For backwards compatibility, columnWidths might be an array or a string of comma-separated values.\n            columnWidths = Array.isArray(columnWidths) ? columnWidths : columnWidths.split(',');\n        }\n        model.change((writer)=>{\n            if (tableWidth) {\n                writer.setAttribute('tableWidth', tableWidth, table);\n            } else {\n                writer.removeAttribute('tableWidth', table);\n            }\n            const tableColumnGroup = plugins.get('TableColumnResizeEditing').getColumnGroupElement(table);\n            if (!columnWidths && !tableColumnGroup) {\n                return;\n            }\n            if (!columnWidths) {\n                return writer.remove(tableColumnGroup);\n            }\n            const widths = normalizeColumnWidths(columnWidths);\n            if (!tableColumnGroup) {\n                const colGroupElement = writer.createElement('tableColumnGroup');\n                widths.forEach((columnWidth)=>writer.appendElement('tableColumn', {\n                        columnWidth\n                    }, colGroupElement));\n                writer.append(colGroupElement, table);\n            } else {\n                Array.from(tableColumnGroup.getChildren()).forEach((column, index)=>writer.setAttribute('columnWidth', widths[index], column));\n            }\n        });\n    }\n}\n\n/**\n * Returns a upcast helper that ensures the number of `<tableColumn>` elements corresponds to the actual number of columns in the table,\n * because the input data might have too few or too many <col> elements.\n */ function upcastColgroupElement(tableUtilsPlugin) {\n    return (dispatcher)=>dispatcher.on('element:colgroup', (evt, data, conversionApi)=>{\n            const modelTable = data.modelCursor.findAncestor('table');\n            const tableColumnGroup = getColumnGroupElement(modelTable);\n            if (!tableColumnGroup) {\n                return;\n            }\n            const columnElements = getTableColumnElements(tableColumnGroup);\n            const columnsCount = tableUtilsPlugin.getColumns(modelTable);\n            let columnWidths = translateColSpanAttribute(tableColumnGroup, conversionApi.writer);\n            // Fill the array with 'auto' values if the number of columns is higher than number of declared values.\n            columnWidths = Array.from({\n                length: columnsCount\n            }, (_, index)=>columnWidths[index] || 'auto');\n            if (columnWidths.length != columnElements.length || columnWidths.includes('auto')) {\n                updateColumnElements(columnElements, tableColumnGroup, normalizeColumnWidths(columnWidths), conversionApi.writer);\n            }\n        }, {\n            priority: 'low'\n        });\n}\n/**\n * Returns downcast helper for adding `ck-table-resized` class if there is a `<tableColumnGroup>` element inside the table.\n */ function downcastTableResizedClass() {\n    return (dispatcher)=>dispatcher.on('insert:table', (evt, data, conversionApi)=>{\n            const viewWriter = conversionApi.writer;\n            const modelTable = data.item;\n            const viewElement = conversionApi.mapper.toViewElement(modelTable);\n            const viewTable = viewElement.is('element', 'table') ? viewElement : Array.from(viewElement.getChildren()).find((viewChild)=>viewChild.is('element', 'table'));\n            const tableColumnGroup = getColumnGroupElement(modelTable);\n            if (tableColumnGroup) {\n                viewWriter.addClass('ck-table-resized', viewTable);\n            } else {\n                viewWriter.removeClass('ck-table-resized', viewTable);\n            }\n        }, {\n            priority: 'low'\n        });\n}\n\n/**\n * The table column resize editing plugin.\n */ class TableColumnResizeEditing extends Plugin {\n    /**\n\t * A flag indicating if the column resizing is in progress.\n\t */ _isResizingActive;\n    /**\n\t * A temporary storage for the required data needed to correctly calculate the widths of the resized columns. This storage is\n\t * initialized when column resizing begins, and is purged upon completion.\n\t */ _resizingData;\n    /**\n\t * DOM emitter.\n\t */ _domEmitter;\n    /**\n\t * A local reference to the {@link module:table/tableutils~TableUtils} plugin.\n\t */ _tableUtilsPlugin;\n    /**\n\t * @inheritDoc\n\t */ static get requires() {\n        return [\n            TableEditing,\n            TableUtils\n        ];\n    }\n    /**\n\t * @inheritDoc\n\t */ static get pluginName() {\n        return 'TableColumnResizeEditing';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n    /**\n\t * @inheritDoc\n\t */ constructor(editor){\n        super(editor);\n        this._isResizingActive = false;\n        this.set('_isResizingAllowed', true);\n        this._resizingData = null;\n        this._domEmitter = new (DomEmitterMixin())();\n        this._tableUtilsPlugin = editor.plugins.get('TableUtils');\n        this.on('change:_isResizingAllowed', (evt, name, value)=>{\n            // Toggling the `ck-column-resize_disabled` class shows and hides the resizers through CSS.\n            const classAction = value ? 'removeClass' : 'addClass';\n            editor.editing.view.change((writer)=>{\n                for (const root of editor.editing.view.document.roots){\n                    writer[classAction]('ck-column-resize_disabled', editor.editing.view.document.getRoot(root.rootName));\n                }\n            });\n        });\n    }\n    /**\n\t * @inheritDoc\n\t */ init() {\n        this._extendSchema();\n        this._registerPostFixer();\n        this._registerConverters();\n        this._registerResizingListeners();\n        this._registerResizerInserter();\n        const editor = this.editor;\n        const columnResizePlugin = editor.plugins.get('TableColumnResize');\n        const tableEditing = editor.plugins.get('TableEditing');\n        tableEditing.registerAdditionalSlot({\n            filter: (element)=>element.is('element', 'tableColumnGroup'),\n            positionOffset: 0\n        });\n        const tableWidthsCommand = new TableWidthsCommand(editor);\n        // For backwards compatibility we have two commands that perform exactly the same operation.\n        editor.commands.add('resizeTableWidth', tableWidthsCommand);\n        editor.commands.add('resizeColumnWidths', tableWidthsCommand);\n        // Currently the states of column resize and table resize (which is actually the last column resize) features\n        // are bound together. They can be separated in the future by adding distinct listeners and applying\n        // different CSS classes (e.g. `ck-column-resize_disabled` and `ck-table-resize_disabled`) to the editor root.\n        // See #12148 for the details.\n        this.bind('_isResizingAllowed').to(editor, 'isReadOnly', columnResizePlugin, 'isEnabled', tableWidthsCommand, 'isEnabled', (isEditorReadOnly, isPluginEnabled, isTableWidthsCommandCommandEnabled)=>!isEditorReadOnly && isPluginEnabled && isTableWidthsCommandCommandEnabled);\n    }\n    /**\n\t * @inheritDoc\n\t */ destroy() {\n        this._domEmitter.stopListening();\n        super.destroy();\n    }\n    /**\n\t * Returns a 'tableColumnGroup' element from the 'table'.\n\t *\n\t * @param element A 'table' or 'tableColumnGroup' element.\n\t * @returns A 'tableColumnGroup' element.\n\t */ getColumnGroupElement(element) {\n        return getColumnGroupElement(element);\n    }\n    /**\n\t * Returns an array of 'tableColumn' elements.\n\t *\n\t * @param element A 'table' or 'tableColumnGroup' element.\n\t * @returns An array of 'tableColumn' elements.\n\t */ getTableColumnElements(element) {\n        return getTableColumnElements(element);\n    }\n    /**\n\t * Returns an array of table column widths.\n\t *\n\t * @param element A 'table' or 'tableColumnGroup' element.\n\t * @returns An array of table column widths.\n\t */ getTableColumnsWidths(element) {\n        return getTableColumnsWidths(element);\n    }\n    /**\n\t * Registers new attributes for a table model element.\n\t */ _extendSchema() {\n        this.editor.model.schema.extend('table', {\n            allowAttributes: [\n                'tableWidth'\n            ]\n        });\n        this.editor.model.schema.register('tableColumnGroup', {\n            allowIn: 'table',\n            isLimit: true\n        });\n        this.editor.model.schema.register('tableColumn', {\n            allowIn: 'tableColumnGroup',\n            allowAttributes: [\n                'columnWidth',\n                'colSpan'\n            ],\n            isLimit: true\n        });\n    }\n    /**\n\t * Registers table column resize post-fixer.\n\t *\n\t * It checks if the change from the differ concerns a table-related element or attribute. For detected changes it:\n\t *  * Adjusts the `columnWidths` attribute to guarantee that the sum of the widths from all columns is 100%.\n\t *  * Checks if the `columnWidths` attribute gets updated accordingly after columns have been added or removed.\n\t */ _registerPostFixer() {\n        const editor = this.editor;\n        const model = editor.model;\n        model.document.registerPostFixer((writer)=>{\n            let changed = false;\n            for (const table of getChangedResizedTables(model)){\n                const tableColumnGroup = this.getColumnGroupElement(table);\n                const columns = this.getTableColumnElements(tableColumnGroup);\n                const columnWidths = this.getTableColumnsWidths(tableColumnGroup);\n                // Adjust the `columnWidths` attribute to guarantee that the sum of the widths from all columns is 100%.\n                let normalizedWidths = normalizeColumnWidths(columnWidths);\n                // If the number of columns has changed, then we need to adjust the widths of the affected columns.\n                normalizedWidths = adjustColumnWidths(normalizedWidths, table, this);\n                if (isEqual(columnWidths, normalizedWidths)) {\n                    continue;\n                }\n                updateColumnElements(columns, tableColumnGroup, normalizedWidths, writer);\n                changed = true;\n            }\n            return changed;\n        });\n        /**\n\t\t * Adjusts if necessary the `columnWidths` in case if the number of column has changed.\n\t\t *\n\t\t * @param columnWidths Note: this array **may be modified** by the function.\n\t\t * @param table Table to be checked.\n\t\t */ function adjustColumnWidths(columnWidths, table, plugin) {\n            const newTableColumnsCount = plugin._tableUtilsPlugin.getColumns(table);\n            const columnsCountDelta = newTableColumnsCount - columnWidths.length;\n            if (columnsCountDelta === 0) {\n                return columnWidths;\n            }\n            const widths = columnWidths.map((width)=>Number(width.replace('%', '')));\n            // Collect all cells that are affected by the change.\n            const cellSet = getAffectedCells(plugin.editor.model.document.differ, table);\n            for (const cell of cellSet){\n                const currentColumnsDelta = newTableColumnsCount - widths.length;\n                if (currentColumnsDelta === 0) {\n                    continue;\n                }\n                // If the column count in the table changed, adjust the widths of the affected columns.\n                const hasMoreColumns = currentColumnsDelta > 0;\n                const currentColumnIndex = plugin._tableUtilsPlugin.getCellLocation(cell).column;\n                if (hasMoreColumns) {\n                    const columnMinWidthAsPercentage = getColumnMinWidthAsPercentage(table, plugin.editor);\n                    const columnWidthsToInsert = createFilledArray(currentColumnsDelta, columnMinWidthAsPercentage);\n                    widths.splice(currentColumnIndex, 0, ...columnWidthsToInsert);\n                } else {\n                    // Moves the widths of the removed columns to the preceding one.\n                    // Other editors either reduce the width of the whole table or adjust the widths\n                    // proportionally, so change of this behavior can be considered in the future.\n                    const removedColumnWidths = widths.splice(currentColumnIndex, Math.abs(currentColumnsDelta));\n                    widths[currentColumnIndex] += sumArray(removedColumnWidths);\n                }\n            }\n            return widths.map((width)=>width + '%');\n        }\n        /**\n\t\t * Returns a set of cells that have been changed in a given table.\n\t\t */ function getAffectedCells(differ, table) {\n            const cellSet = new Set();\n            for (const change of differ.getChanges()){\n                if (change.type == 'insert' && change.position.nodeAfter && change.position.nodeAfter.name == 'tableCell' && change.position.nodeAfter.getAncestors().includes(table)) {\n                    cellSet.add(change.position.nodeAfter);\n                } else if (change.type == 'remove') {\n                    // If the first cell was removed, use the node after the change position instead.\n                    const referenceNode = change.position.nodeBefore || change.position.nodeAfter;\n                    if (referenceNode.name == 'tableCell' && referenceNode.getAncestors().includes(table)) {\n                        cellSet.add(referenceNode);\n                    }\n                }\n            }\n            return cellSet;\n        }\n    }\n    /**\n\t * Registers table column resize converters.\n\t */ _registerConverters() {\n        const editor = this.editor;\n        const conversion = editor.conversion;\n        // Table width style\n        conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: 'figure',\n                key: 'style',\n                value: {\n                    width: /[\\s\\S]+/\n                }\n            },\n            model: {\n                name: 'table',\n                key: 'tableWidth',\n                value: (viewElement)=>viewElement.getStyle('width')\n            }\n        });\n        conversion.for('downcast').attributeToAttribute({\n            model: {\n                name: 'table',\n                key: 'tableWidth'\n            },\n            view: (width)=>({\n                    name: 'figure',\n                    key: 'style',\n                    value: {\n                        width\n                    }\n                })\n        });\n        conversion.elementToElement({\n            model: 'tableColumnGroup',\n            view: 'colgroup'\n        });\n        conversion.elementToElement({\n            model: 'tableColumn',\n            view: 'col'\n        });\n        conversion.for('downcast').add(downcastTableResizedClass());\n        conversion.for('upcast').add(upcastColgroupElement(this._tableUtilsPlugin));\n        conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: 'col',\n                styles: {\n                    width: /.*/\n                }\n            },\n            model: {\n                key: 'columnWidth',\n                value: (viewElement)=>{\n                    const viewColWidth = viewElement.getStyle('width');\n                    // 'pt' is the default unit for table column width pasted from MS Office.\n                    // See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for more details.\n                    if (!viewColWidth || !viewColWidth.endsWith('%') && !viewColWidth.endsWith('pt')) {\n                        return 'auto';\n                    }\n                    return viewColWidth;\n                }\n            }\n        });\n        // The `col[span]` attribute is present in tables pasted from MS Excel. We use it to set the temporary `colSpan` model attribute,\n        // which is consumed during the `colgroup` element upcast.\n        // See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for more details.\n        conversion.for('upcast').attributeToAttribute({\n            view: {\n                name: 'col',\n                key: 'span'\n            },\n            model: 'colSpan'\n        });\n        conversion.for('downcast').attributeToAttribute({\n            model: {\n                name: 'tableColumn',\n                key: 'columnWidth'\n            },\n            view: (width)=>({\n                    key: 'style',\n                    value: {\n                        width\n                    }\n                })\n        });\n    }\n    /**\n\t * Registers listeners to handle resizing process.\n\t */ _registerResizingListeners() {\n        const editingView = this.editor.editing.view;\n        editingView.addObserver(MouseEventsObserver);\n        editingView.document.on('mousedown', this._onMouseDownHandler.bind(this), {\n            priority: 'high'\n        });\n        this._domEmitter.listenTo(global.window.document, 'mousemove', throttle(this._onMouseMoveHandler.bind(this), 50));\n        this._domEmitter.listenTo(global.window.document, 'mouseup', this._onMouseUpHandler.bind(this));\n    }\n    /**\n\t * Handles the `mousedown` event on column resizer element:\n\t *  * calculates the initial column pixel widths,\n\t *  * inserts the `<colgroup>` element if it is not present in the `<table>`,\n\t *  * puts the necessary data in the temporary storage,\n\t *  * applies the attributes to the `<table>` view element.\n\t *\n\t * @param eventInfo An object containing information about the fired event.\n\t * @param domEventData The data related to the DOM event.\n\t */ _onMouseDownHandler(eventInfo, domEventData) {\n        const target = domEventData.target;\n        if (!target.hasClass('ck-table-column-resizer')) {\n            return;\n        }\n        if (!this._isResizingAllowed) {\n            return;\n        }\n        const editor = this.editor;\n        const modelTable = editor.editing.mapper.toModelElement(target.findAncestor('figure'));\n        // Do not resize if table model is in non-editable place.\n        if (!editor.model.canEditAt(modelTable)) {\n            return;\n        }\n        domEventData.preventDefault();\n        eventInfo.stop();\n        // The column widths are calculated upon mousedown to allow lazy applying the `columnWidths` attribute on the table.\n        const columnWidthsInPx = _calculateDomColumnWidths(modelTable, this._tableUtilsPlugin, editor);\n        const viewTable = target.findAncestor('table');\n        const editingView = editor.editing.view;\n        // Insert colgroup for the table that is resized for the first time.\n        if (!Array.from(viewTable.getChildren()).find((viewCol)=>viewCol.is('element', 'colgroup'))) {\n            editingView.change((viewWriter)=>{\n                _insertColgroupElement(viewWriter, columnWidthsInPx, viewTable);\n            });\n        }\n        this._isResizingActive = true;\n        this._resizingData = this._getResizingData(domEventData, columnWidthsInPx);\n        // At this point we change only the editor view - we don't want other users to see our changes yet,\n        // so we can't apply them in the model.\n        editingView.change((writer)=>_applyResizingAttributesToTable(writer, viewTable, this._resizingData));\n        /**\n\t\t * Calculates the DOM columns' widths. It is done by taking the width of the widest cell\n\t\t * from each table column (we rely on the  {@link module:table/tablewalker~TableWalker}\n\t\t * to determine which column the cell belongs to).\n\t\t *\n\t\t * @param modelTable A table which columns should be measured.\n\t\t * @param tableUtils The Table Utils plugin instance.\n\t\t * @param editor The editor instance.\n\t\t * @returns Columns' widths expressed in pixels (without unit).\n\t\t */ function _calculateDomColumnWidths(modelTable, tableUtilsPlugin, editor) {\n            const columnWidthsInPx = Array(tableUtilsPlugin.getColumns(modelTable));\n            const tableWalker = new TableWalker(modelTable);\n            for (const cellSlot of tableWalker){\n                const viewCell = editor.editing.mapper.toViewElement(cellSlot.cell);\n                const domCell = editor.editing.view.domConverter.mapViewToDom(viewCell);\n                const domCellWidth = getDomCellOuterWidth(domCell);\n                if (!columnWidthsInPx[cellSlot.column] || domCellWidth < columnWidthsInPx[cellSlot.column]) {\n                    columnWidthsInPx[cellSlot.column] = toPrecision(domCellWidth);\n                }\n            }\n            return columnWidthsInPx;\n        }\n        /**\n\t\t * Creates a `<colgroup>` element with `<col>`s and inserts it into a given view table.\n\t\t *\n\t\t * @param viewWriter A writer instance.\n\t\t * @param columnWidthsInPx Column widths.\n\t\t * @param viewTable A table view element.\n\t\t */ function _insertColgroupElement(viewWriter, columnWidthsInPx, viewTable) {\n            const colgroup = viewWriter.createContainerElement('colgroup');\n            for(let i = 0; i < columnWidthsInPx.length; i++){\n                const viewColElement = viewWriter.createEmptyElement('col');\n                const columnWidthInPc = `${toPrecision(columnWidthsInPx[i] / sumArray(columnWidthsInPx) * 100)}%`;\n                viewWriter.setStyle('width', columnWidthInPc, viewColElement);\n                viewWriter.insert(viewWriter.createPositionAt(colgroup, 'end'), viewColElement);\n            }\n            viewWriter.insert(viewWriter.createPositionAt(viewTable, 0), colgroup);\n        }\n        /**\n\t\t * Applies the style and classes to the view table as the resizing begun.\n\t\t *\n\t\t * @param viewWriter A writer instance.\n\t\t * @param viewTable A table containing the clicked resizer.\n\t\t * @param resizingData Data related to the resizing.\n\t\t */ function _applyResizingAttributesToTable(viewWriter, viewTable, resizingData) {\n            const figureInitialPcWidth = resizingData.widths.viewFigureWidth / resizingData.widths.viewFigureParentWidth;\n            viewWriter.addClass('ck-table-resized', viewTable);\n            viewWriter.addClass('ck-table-column-resizer__active', resizingData.elements.viewResizer);\n            viewWriter.setStyle('width', `${toPrecision(figureInitialPcWidth * 100)}%`, viewTable.findAncestor('figure'));\n        }\n    }\n    /**\n\t * Handles the `mousemove` event.\n\t *  * If resizing process is not in progress, it does nothing.\n\t *  * If resizing is active but not allowed, it stops the resizing process instantly calling the `mousedown` event handler.\n\t *  * Otherwise it dynamically updates the widths of the resized columns.\n\t *\n\t * @param eventInfo An object containing information about the fired event.\n\t * @param mouseEventData The native DOM event.\n\t */ _onMouseMoveHandler(eventInfo, mouseEventData) {\n        if (!this._isResizingActive) {\n            return;\n        }\n        if (!this._isResizingAllowed) {\n            this._onMouseUpHandler();\n            return;\n        }\n        const { columnPosition, flags: { isRightEdge, isTableCentered, isLtrContent }, elements: { viewFigure, viewLeftColumn, viewRightColumn }, widths: { viewFigureParentWidth, tableWidth, leftColumnWidth, rightColumnWidth } } = this._resizingData;\n        const dxLowerBound = -leftColumnWidth + COLUMN_MIN_WIDTH_IN_PIXELS;\n        const dxUpperBound = isRightEdge ? viewFigureParentWidth - tableWidth : rightColumnWidth - COLUMN_MIN_WIDTH_IN_PIXELS;\n        // The multiplier is needed for calculating the proper movement offset:\n        // - it should negate the sign if content language direction is right-to-left,\n        // - it should double the offset if the table edge is resized and table is centered.\n        const multiplier = (isLtrContent ? 1 : -1) * (isRightEdge && isTableCentered ? 2 : 1);\n        const dx = clamp((mouseEventData.clientX - columnPosition) * multiplier, Math.min(dxLowerBound, 0), Math.max(dxUpperBound, 0));\n        if (dx === 0) {\n            return;\n        }\n        this.editor.editing.view.change((writer)=>{\n            const leftColumnWidthAsPercentage = toPrecision((leftColumnWidth + dx) * 100 / tableWidth);\n            writer.setStyle('width', `${leftColumnWidthAsPercentage}%`, viewLeftColumn);\n            if (isRightEdge) {\n                const tableWidthAsPercentage = toPrecision((tableWidth + dx) * 100 / viewFigureParentWidth);\n                writer.setStyle('width', `${tableWidthAsPercentage}%`, viewFigure);\n            } else {\n                const rightColumnWidthAsPercentage = toPrecision((rightColumnWidth - dx) * 100 / tableWidth);\n                writer.setStyle('width', `${rightColumnWidthAsPercentage}%`, viewRightColumn);\n            }\n        });\n    }\n    /**\n\t * Handles the `mouseup` event.\n\t *  * If resizing process is not in progress, it does nothing.\n\t *  * If resizing is active but not allowed, it cancels the resizing process restoring the original widths.\n\t *  * Otherwise it propagates the changes from view to the model by executing the adequate commands.\n\t */ _onMouseUpHandler() {\n        if (!this._isResizingActive) {\n            return;\n        }\n        const { viewResizer, modelTable, viewFigure, viewColgroup } = this._resizingData.elements;\n        const editor = this.editor;\n        const editingView = editor.editing.view;\n        const tableColumnGroup = this.getColumnGroupElement(modelTable);\n        const viewColumns = Array.from(viewColgroup.getChildren()).filter((column)=>column.is('view:element'));\n        const columnWidthsAttributeOld = tableColumnGroup ? this.getTableColumnsWidths(tableColumnGroup) : null;\n        const columnWidthsAttributeNew = viewColumns.map((column)=>column.getStyle('width'));\n        const isColumnWidthsAttributeChanged = !isEqual(columnWidthsAttributeOld, columnWidthsAttributeNew);\n        const tableWidthAttributeOld = modelTable.getAttribute('tableWidth');\n        const tableWidthAttributeNew = viewFigure.getStyle('width');\n        const isTableWidthAttributeChanged = tableWidthAttributeOld !== tableWidthAttributeNew;\n        if (isColumnWidthsAttributeChanged || isTableWidthAttributeChanged) {\n            if (this._isResizingAllowed) {\n                editor.execute('resizeTableWidth', {\n                    table: modelTable,\n                    tableWidth: `${toPrecision(tableWidthAttributeNew)}%`,\n                    columnWidths: columnWidthsAttributeNew\n                });\n            } else {\n                // In read-only mode revert all changes in the editing view. The model is not touched so it does not need to be restored.\n                // This case can occur if the read-only mode kicks in during the resizing process.\n                editingView.change((writer)=>{\n                    // If table had resized columns before, restore the previous column widths.\n                    // Otherwise clean up the view from the temporary column resizing markup.\n                    if (columnWidthsAttributeOld) {\n                        for (const viewCol of viewColumns){\n                            writer.setStyle('width', columnWidthsAttributeOld.shift(), viewCol);\n                        }\n                    } else {\n                        writer.remove(viewColgroup);\n                    }\n                    if (isTableWidthAttributeChanged) {\n                        // If the whole table was already resized before, restore the previous table width.\n                        // Otherwise clean up the view from the temporary table resizing markup.\n                        if (tableWidthAttributeOld) {\n                            writer.setStyle('width', tableWidthAttributeOld, viewFigure);\n                        } else {\n                            writer.removeStyle('width', viewFigure);\n                        }\n                    }\n                    // If a table and its columns weren't resized before,\n                    // prune the remaining common resizing markup.\n                    if (!columnWidthsAttributeOld && !tableWidthAttributeOld) {\n                        writer.removeClass('ck-table-resized', [\n                            ...viewFigure.getChildren()\n                        ].find((element)=>element.name === 'table'));\n                    }\n                });\n            }\n        }\n        editingView.change((writer)=>{\n            writer.removeClass('ck-table-column-resizer__active', viewResizer);\n        });\n        this._isResizingActive = false;\n        this._resizingData = null;\n    }\n    /**\n\t * Retrieves and returns required data needed for the resizing process.\n\t *\n\t * @param domEventData The data of the `mousedown` event.\n\t * @param columnWidths The current widths of the columns.\n\t * @returns The data needed for the resizing process.\n\t */ _getResizingData(domEventData, columnWidths) {\n        const editor = this.editor;\n        const columnPosition = domEventData.domEvent.clientX;\n        const viewResizer = domEventData.target;\n        const viewLeftCell = viewResizer.findAncestor('td') || viewResizer.findAncestor('th');\n        const modelLeftCell = editor.editing.mapper.toModelElement(viewLeftCell);\n        const modelTable = modelLeftCell.findAncestor('table');\n        const leftColumnIndex = getColumnEdgesIndexes(modelLeftCell, this._tableUtilsPlugin).rightEdge;\n        const lastColumnIndex = this._tableUtilsPlugin.getColumns(modelTable) - 1;\n        const isRightEdge = leftColumnIndex === lastColumnIndex;\n        const isTableCentered = !modelTable.hasAttribute('tableAlignment');\n        const isLtrContent = editor.locale.contentLanguageDirection !== 'rtl';\n        const viewTable = viewLeftCell.findAncestor('table');\n        const viewFigure = viewTable.findAncestor('figure');\n        const viewColgroup = [\n            ...viewTable.getChildren()\n        ].find((viewCol)=>viewCol.is('element', 'colgroup'));\n        const viewLeftColumn = viewColgroup.getChild(leftColumnIndex);\n        const viewRightColumn = isRightEdge ? undefined : viewColgroup.getChild(leftColumnIndex + 1);\n        const viewFigureParentWidth = getElementWidthInPixels(editor.editing.view.domConverter.mapViewToDom(viewFigure.parent));\n        const viewFigureWidth = getElementWidthInPixels(editor.editing.view.domConverter.mapViewToDom(viewFigure));\n        const tableWidth = getTableWidthInPixels(modelTable, editor);\n        const leftColumnWidth = columnWidths[leftColumnIndex];\n        const rightColumnWidth = isRightEdge ? undefined : columnWidths[leftColumnIndex + 1];\n        return {\n            columnPosition,\n            flags: {\n                isRightEdge,\n                isTableCentered,\n                isLtrContent\n            },\n            elements: {\n                viewResizer,\n                modelTable,\n                viewFigure,\n                viewColgroup,\n                viewLeftColumn,\n                viewRightColumn\n            },\n            widths: {\n                viewFigureParentWidth,\n                viewFigureWidth,\n                tableWidth,\n                leftColumnWidth,\n                rightColumnWidth\n            }\n        };\n    }\n    /**\n\t * Registers a listener ensuring that each resizable cell have a resizer handle.\n\t */ _registerResizerInserter() {\n        this.editor.conversion.for('editingDowncast').add((dispatcher)=>{\n            dispatcher.on('insert:tableCell', (evt, data, conversionApi)=>{\n                const modelElement = data.item;\n                const viewElement = conversionApi.mapper.toViewElement(modelElement);\n                const viewWriter = conversionApi.writer;\n                viewWriter.insert(viewWriter.createPositionAt(viewElement, 'end'), viewWriter.createUIElement('div', {\n                    class: 'ck-table-column-resizer'\n                }));\n            }, {\n                priority: 'lowest'\n            });\n        });\n    }\n}\n\n/**\n * The table column resize feature.\n *\n * It provides the possibility to set the width of each column in a table using a resize handler.\n */ class TableColumnResize extends Plugin {\n    /**\n\t * @inheritDoc\n \t */ static get requires() {\n        return [\n            TableColumnResizeEditing,\n            TableCellWidthEditing\n        ];\n    }\n    /**\n\t * @inheritDoc\n \t */ static get pluginName() {\n        return 'TableColumnResize';\n    }\n    /**\n\t * @inheritDoc\n\t */ static get isOfficialPlugin() {\n        return true;\n    }\n}\n\nexport { PlainTableOutput, Table, TableCaption, TableCaptionEditing, TableCaptionUI, TableCellProperties, TableCellPropertiesEditing, TableCellPropertiesUI, TableCellWidthEditing, TableClipboard, TableColumnResize, TableColumnResizeEditing, TableEditing, TableKeyboard, TableMouse, TableProperties, TablePropertiesEditing, TablePropertiesUI, TableSelection, TableToolbar, TableUI, TableUtils };\n//# sourceMappingURL=index.js.map\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/tableproperties\n */\n\nimport type { Conversion, ViewElement } from 'ckeditor5/src/engine.js';\n\n/**\n * Conversion helper for upcasting attributes using normalized styles.\n *\n * @param options.modelAttribute The attribute to set.\n * @param options.styleName The style name to convert.\n * @param options.viewElement The view element name that should be converted.\n * @param options.defaultValue The default value for the specified `modelAttribute`.\n * @param options.shouldUpcast The function which returns `true` if style should be upcasted from this element.\n */\nexport function upcastStyleToAttribute(\n\tconversion: Conversion,\n\toptions: {\n\t\tmodelAttribute: string;\n\t\tstyleName: string;\n\t\tviewElement: string | RegExp;\n\t\tdefaultValue: string;\n\t\treduceBoxSides?: boolean;\n\t\tshouldUpcast?: ( viewElement: ViewElement ) => boolean;\n\t}\n): void {\n\tconst {\n\t\tmodelAttribute,\n\t\tstyleName,\n\t\tviewElement,\n\t\tdefaultValue,\n\t\treduceBoxSides = false,\n\t\tshouldUpcast = () => true\n\t} = options;\n\n\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\tview: {\n\t\t\tname: viewElement,\n\t\t\tstyles: {\n\t\t\t\t[ styleName ]: /[\\s\\S]+/\n\t\t\t}\n\t\t},\n\t\tmodel: {\n\t\t\tkey: modelAttribute,\n\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\tif ( !shouldUpcast( viewElement ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst normalized = viewElement.getNormalizedStyle( styleName ) as Record<Side, string>;\n\t\t\t\tconst value = reduceBoxSides ? reduceBoxSidesValue( normalized ) : normalized;\n\n\t\t\t\tif ( defaultValue !== value ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n}\n\nexport interface StyleValues {\n\tcolor: string;\n\tstyle: string;\n\twidth: string;\n}\n\n/**\n * Conversion helper for upcasting border styles for view elements.\n *\n * @param defaultBorder The default border values.\n * @param defaultBorder.color The default `borderColor` value.\n * @param defaultBorder.style The default `borderStyle` value.\n * @param defaultBorder.width The default `borderWidth` value.\n */\nexport function upcastBorderStyles(\n\tconversion: Conversion,\n\tviewElementName: string,\n\tmodelAttributes: StyleValues,\n\tdefaultBorder: StyleValues\n): void {\n\tconversion.for( 'upcast' ).add( dispatcher => dispatcher.on( 'element:' + viewElementName, ( evt, data, conversionApi ) => {\n\t\t// If the element was not converted by element-to-element converter,\n\t\t// we should not try to convert the style. See #8393.\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check the most detailed properties. These will be always set directly or\n\t\t// when using the \"group\" properties like: `border-(top|right|bottom|left)` or `border`.\n\t\tconst stylesToConsume = [\n\t\t\t'border-top-width',\n\t\t\t'border-top-color',\n\t\t\t'border-top-style',\n\t\t\t'border-bottom-width',\n\t\t\t'border-bottom-color',\n\t\t\t'border-bottom-style',\n\t\t\t'border-right-width',\n\t\t\t'border-right-color',\n\t\t\t'border-right-style',\n\t\t\t'border-left-width',\n\t\t\t'border-left-color',\n\t\t\t'border-left-style'\n\t\t].filter( styleName => data.viewItem.hasStyle( styleName ) );\n\n\t\tif ( !stylesToConsume.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst matcherPattern = {\n\t\t\tstyles: stylesToConsume\n\t\t};\n\n\t\t// Try to consume appropriate values from consumable values list.\n\t\tif ( !conversionApi.consumable.test( data.viewItem, matcherPattern ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelElement = [ ...data.modelRange.getItems( { shallow: true } ) ].pop();\n\n\t\tconversionApi.consumable.consume( data.viewItem, matcherPattern );\n\n\t\tconst normalizedBorder = {\n\t\t\tstyle: data.viewItem.getNormalizedStyle( 'border-style' ),\n\t\t\tcolor: data.viewItem.getNormalizedStyle( 'border-color' ),\n\t\t\twidth: data.viewItem.getNormalizedStyle( 'border-width' )\n\t\t};\n\n\t\tconst reducedBorder = {\n\t\t\tstyle: reduceBoxSidesValue( normalizedBorder.style ),\n\t\t\tcolor: reduceBoxSidesValue( normalizedBorder.color ),\n\t\t\twidth: reduceBoxSidesValue( normalizedBorder.width )\n\t\t};\n\n\t\tif ( reducedBorder.style !== defaultBorder.style ) {\n\t\t\tconversionApi.writer.setAttribute( modelAttributes.style, reducedBorder.style, modelElement );\n\t\t}\n\n\t\tif ( reducedBorder.color !== defaultBorder.color ) {\n\t\t\tconversionApi.writer.setAttribute( modelAttributes.color, reducedBorder.color, modelElement );\n\t\t}\n\n\t\tif ( reducedBorder.width !== defaultBorder.width ) {\n\t\t\tconversionApi.writer.setAttribute( modelAttributes.width, reducedBorder.width, modelElement );\n\t\t}\n\t} ) );\n}\n\n/**\n * Conversion helper for downcasting an attribute to a style.\n */\nexport function downcastAttributeToStyle(\n\tconversion: Conversion,\n\toptions: {\n\t\tmodelElement: string;\n\t\tmodelAttribute: string;\n\t\tstyleName: string;\n\t}\n): void {\n\tconst { modelElement, modelAttribute, styleName } = options;\n\n\tconversion.for( 'downcast' ).attributeToAttribute( {\n\t\tmodel: {\n\t\t\tname: modelElement,\n\t\t\tkey: modelAttribute\n\t\t},\n\t\tview: modelAttributeValue => ( {\n\t\t\tkey: 'style',\n\t\t\tvalue: {\n\t\t\t\t[ styleName ]: modelAttributeValue\n\t\t\t}\n\t\t} )\n\t} );\n}\n\n/**\n * Conversion helper for downcasting attributes from the model table to a view table (not to `<figure>`).\n */\nexport function downcastTableAttribute(\n\tconversion: Conversion,\n\toptions: {\n\t\tmodelAttribute: string;\n\t\tstyleName: string;\n\t}\n): void {\n\tconst { modelAttribute, styleName } = options;\n\n\tconversion.for( 'downcast' ).add( dispatcher => dispatcher.on( `attribute:${ modelAttribute }:table`, ( evt, data, conversionApi ) => {\n\t\tconst { item, attributeNewValue } = data;\n\t\tconst { mapper, writer } = conversionApi;\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst table = [ ...mapper.toViewElement( item ).getChildren() ].find( child => child.is( 'element', 'table' ) );\n\n\t\tif ( attributeNewValue ) {\n\t\t\twriter.setStyle( styleName, attributeNewValue, table );\n\t\t} else {\n\t\t\twriter.removeStyle( styleName, table );\n\t\t}\n\t} ) );\n}\n\ntype Side = 'top' | 'right' | 'bottom' | 'left';\ntype Style = Record<Side, string>;\n\n/**\n * Reduces the full top, right, bottom, left object to a single string if all sides are equal.\n * Returns original style otherwise.\n */\nfunction reduceBoxSidesValue( style?: Style ): undefined | string | Style {\n\tif ( !style ) {\n\t\treturn;\n\t}\n\tconst sides: Array<Side> = [ 'top', 'right', 'bottom', 'left' ];\n\tconst allSidesDefined = sides.every( side => style[ side ] );\n\n\tif ( !allSidesDefined ) {\n\t\treturn style;\n\t}\n\n\tconst topSideStyle = style.top;\n\tconst allSidesEqual = sides.every( side => style[ side ] === topSideStyle );\n\n\tif ( !allSidesEqual ) {\n\t\treturn style;\n\t}\n\n\treturn topSideStyle;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/common\n */\n\nimport type {\n\tConversion,\n\tElement,\n\tItem,\n\tPosition,\n\tSchema,\n\tWriter,\n\tDocumentSelection\n} from 'ckeditor5/src/engine.js';\n\nimport { downcastAttributeToStyle, upcastStyleToAttribute } from './../converters/tableproperties.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * A common method to update the numeric value. If a value is the default one, it will be unset.\n *\n * @param key An attribute key.\n * @param value The new attribute value.\n * @param item A model item on which the attribute will be set.\n * @param defaultValue The default attribute value. If a value is lower or equal, it will be unset.\n */\nexport function updateNumericAttribute( key: string, value: unknown, item: Item, writer: Writer, defaultValue: unknown = 1 ): void {\n\tif ( value !== undefined && value !== null && defaultValue !== undefined && defaultValue !== null && value > defaultValue ) {\n\t\twriter.setAttribute( key, value, item );\n\t} else {\n\t\twriter.removeAttribute( key, item );\n\t}\n}\n\n/**\n * A common method to create an empty table cell. It creates a proper model structure as a table cell must have at least one block inside.\n *\n * @param writer The model writer.\n * @param insertPosition The position at which the table cell should be inserted.\n * @param attributes The element attributes.\n * @returns Created table cell.\n */\nexport function createEmptyTableCell( writer: Writer, insertPosition: Position, attributes: Record<string, unknown> = {} ): Element {\n\tconst tableCell = writer.createElement( 'tableCell', attributes );\n\n\twriter.insertElement( 'paragraph', tableCell );\n\twriter.insert( tableCell, insertPosition );\n\n\treturn tableCell;\n}\n\n/**\n * Checks if a table cell belongs to the heading column section.\n */\nexport function isHeadingColumnCell( tableUtils: TableUtils, tableCell: Element ): boolean {\n\tconst table = tableCell.parent!.parent as Element;\n\tconst headingColumns = parseInt( table.getAttribute( 'headingColumns' ) as string || '0' );\n\tconst { column } = tableUtils.getCellLocation( tableCell );\n\n\treturn !!headingColumns && column < headingColumns;\n}\n\n/**\n * Enables conversion for an attribute for simple view-model mappings.\n *\n * @param options.defaultValue The default value for the specified `modelAttribute`.\n */\nexport function enableProperty(\n\tschema: Schema,\n\tconversion: Conversion,\n\toptions: {\n\t\tmodelAttribute: string;\n\t\tstyleName: string;\n\t\tdefaultValue: string;\n\t\treduceBoxSides?: boolean;\n\t}\n): void {\n\tconst { modelAttribute } = options;\n\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: [ modelAttribute ]\n\t} );\n\n\tupcastStyleToAttribute( conversion, { viewElement: /^(td|th)$/, ...options } );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', ...options } );\n}\n\n/**\n * Depending on the position of the selection we either return the table under cursor or look for the table higher in the hierarchy.\n */\nexport function getSelectionAffectedTable( selection: DocumentSelection ): Element {\n\tconst selectedElement = selection.getSelectedElement();\n\n\t// Is the command triggered from the `tableToolbar`?\n\tif ( selectedElement && selectedElement.is( 'element', 'table' ) ) {\n\t\treturn selectedElement;\n\t}\n\n\treturn selection.getFirstPosition()!.findAncestor( 'table' )!;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/upcasttable\n */\n\nimport type { Element, UpcastDispatcher, UpcastElementEvent, ViewElement, ViewNode } from 'ckeditor5/src/engine.js';\n\nimport { createEmptyTableCell } from '../utils/common.js';\nimport { first } from 'ckeditor5/src/utils.js';\n\n/**\n * Returns a function that converts the table view representation:\n *\n * ```xml\n * <figure class=\"table\"><table>...</table></figure>\n * ```\n *\n * to the model representation:\n *\n * ```xml\n * <table></table>\n * ```\n */\nexport function upcastTableFigure() {\n\treturn ( dispatcher: UpcastDispatcher ): void => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:figure', ( evt, data, conversionApi ) => {\n\t\t\t// Do not convert if this is not a \"table figure\".\n\t\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true, classes: 'table' } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Find a table element inside the figure element.\n\t\t\tconst viewTable = getViewTableFromFigure( data.viewItem );\n\n\t\t\t// Do not convert if table element is absent or was already converted.\n\t\t\tif ( !viewTable || !conversionApi.consumable.test( viewTable, { name: true } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Consume the figure to prevent other converters from processing it again.\n\t\t\tconversionApi.consumable.consume( data.viewItem, { name: true, classes: 'table' } );\n\n\t\t\t// Convert view table to model table.\n\t\t\tconst conversionResult = conversionApi.convertItem( viewTable, data.modelCursor );\n\n\t\t\t// Get table element from conversion result.\n\t\t\tconst modelTable = first( conversionResult.modelRange!.getItems() as Iterator<Element> );\n\n\t\t\t// When table wasn't successfully converted then finish conversion.\n\t\t\tif ( !modelTable ) {\n\t\t\t\t// Revert consumed figure so other features can convert it.\n\t\t\t\tconversionApi.consumable.revert( data.viewItem, { name: true, classes: 'table' } );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconversionApi.convertChildren( data.viewItem, conversionApi.writer.createPositionAt( modelTable, 'end' ) );\n\t\t\tconversionApi.updateConversionResult( modelTable, data );\n\t\t} );\n\t};\n}\n\n/**\n * View table element to model table element conversion helper.\n *\n * This conversion helper converts the table element as well as table rows.\n *\n * @returns Conversion helper.\n */\nexport default function upcastTable() {\n\treturn ( dispatcher: UpcastDispatcher ): void => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:table', ( evt, data, conversionApi ) => {\n\t\t\tconst viewTable = data.viewItem;\n\n\t\t\t// When element was already consumed then skip it.\n\t\t\tif ( !conversionApi.consumable.test( viewTable, { name: true } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { rows, headingRows, headingColumns } = scanTable( viewTable );\n\n\t\t\t// Only set attributes if values is greater then 0.\n\t\t\tconst attributes: { headingColumns?: number; headingRows?: number } = {};\n\n\t\t\tif ( headingColumns ) {\n\t\t\t\tattributes.headingColumns = headingColumns;\n\t\t\t}\n\n\t\t\tif ( headingRows ) {\n\t\t\t\tattributes.headingRows = headingRows;\n\t\t\t}\n\n\t\t\tconst table = conversionApi.writer.createElement( 'table', attributes );\n\n\t\t\tif ( !conversionApi.safeInsert( table, data.modelCursor ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconversionApi.consumable.consume( viewTable, { name: true } );\n\n\t\t\t// Upcast table rows in proper order (heading rows first).\n\t\t\trows.forEach( row => conversionApi.convertItem( row, conversionApi.writer.createPositionAt( table, 'end' ) ) );\n\n\t\t\t// Convert everything else.\n\t\t\tconversionApi.convertChildren( viewTable, conversionApi.writer.createPositionAt( table, 'end' ) );\n\n\t\t\t// Create one row and one table cell for empty table.\n\t\t\tif ( table.isEmpty ) {\n\t\t\t\tconst row = conversionApi.writer.createElement( 'tableRow' );\n\t\t\t\tconversionApi.writer.insert( row, conversionApi.writer.createPositionAt( table, 'end' ) );\n\n\t\t\t\tcreateEmptyTableCell( conversionApi.writer, conversionApi.writer.createPositionAt( row, 'end' ) );\n\t\t\t}\n\n\t\t\tconversionApi.updateConversionResult( table, data );\n\t\t} );\n\t};\n}\n\n/**\n * A conversion helper that skips empty <tr> elements from upcasting at the beginning of the table.\n *\n * An empty row is considered a table model error but when handling clipboard data there could be rows that contain only row-spanned cells\n * and empty TR-s are used to maintain the table structure (also {@link module:table/tablewalker~TableWalker} assumes that there are only\n * rows that have related `tableRow` elements).\n *\n * *Note:* Only the first empty rows are removed because they have no meaning and it solves the issue\n * of an improper table with all empty rows.\n *\n * @returns Conversion helper.\n */\nexport function skipEmptyTableRow() {\n\treturn ( dispatcher: UpcastDispatcher ): void => {\n\t\tdispatcher.on<UpcastElementEvent>( 'element:tr', ( evt, data ) => {\n\t\t\tif ( data.viewItem.isEmpty && data.modelCursor.index == 0 ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t};\n}\n\n/**\n * A converter that ensures an empty paragraph is inserted in a table cell if no other content was converted.\n *\n * @returns Conversion helper.\n */\nexport function ensureParagraphInTableCell( elementName: string ) {\n\treturn ( dispatcher: UpcastDispatcher ): void => {\n\t\tdispatcher.on<UpcastElementEvent>( `element:${ elementName }`, ( evt, data, { writer } ) => {\n\t\t\t// The default converter will create a model range on converted table cell.\n\t\t\tif ( !data.modelRange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tableCell = data.modelRange.start.nodeAfter as Element;\n\t\t\tconst modelCursor = writer.createPositionAt( tableCell, 0 );\n\n\t\t\t// Ensure a paragraph in the model for empty table cells for converted table cells.\n\t\t\tif ( data.viewItem.isEmpty ) {\n\t\t\t\twriter.insertElement( 'paragraph', modelCursor );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst childNodes = Array.from( tableCell.getChildren() );\n\n\t\t\t// In case there are only markers inside the table cell then move them to the paragraph.\n\t\t\tif ( childNodes.every( node => node.is( 'element', '$marker' ) ) ) {\n\t\t\t\tconst paragraph = writer.createElement( 'paragraph' );\n\n\t\t\t\twriter.insert( paragraph, writer.createPositionAt( tableCell, 0 ) );\n\n\t\t\t\tfor ( const node of childNodes ) {\n\t\t\t\t\twriter.move( writer.createRangeOn( node ), writer.createPositionAt( paragraph, 'end' ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t};\n}\n\n/**\n * Get view `<table>` element from the view widget (`<figure>`).\n */\nfunction getViewTableFromFigure( figureView: ViewElement ) {\n\tfor ( const figureChild of figureView.getChildren() ) {\n\t\tif ( figureChild.is( 'element', 'table' ) ) {\n\t\t\treturn figureChild;\n\t\t}\n\t}\n}\n\n/**\n * Scans table rows and extracts required metadata from the table:\n *\n * headingRows    - The number of rows that go as table headers.\n * headingColumns - The maximum number of row headings.\n * rows           - Sorted `<tr>` elements as they should go into the model - ie. if `<thead>` is inserted after `<tbody>` in the view.\n */\nfunction scanTable( viewTable: ViewElement ) {\n\tlet headingRows = 0;\n\tlet headingColumns: number | undefined = undefined;\n\n\t// The `<tbody>` and `<thead>` sections in the DOM do not have to be in order `<thead>` -> `<tbody>` and there might be more than one\n\t// of them.\n\t// As the model does not have these sections, rows from different sections must be sorted.\n\t// For example, below is a valid HTML table:\n\t//\n\t// <table>\n\t//   <tbody><tr><td>2</td></tr></tbody>\n\t//   <thead><tr><td>1</td></tr></thead>\n\t//   <tbody><tr><td>3</td></tr></tbody>\n\t// </table>\n\t//\n\t// But browsers will render rows in order as: 1 as the heading and 2 and 3 as the body.\n\tconst headRows = [];\n\tconst bodyRows = [];\n\n\t// Currently the editor does not support more then one <thead> section.\n\t// Only the first <thead> from the view will be used as a heading row and the others will be converted to body rows.\n\tlet firstTheadElement;\n\n\tfor ( const tableChild of Array.from( viewTable.getChildren() as IterableIterator<ViewElement> ) ) {\n\t\t// Only `<thead>`, `<tbody>` & `<tfoot>` from allowed table children can have `<tr>`s.\n\t\t// The else is for future purposes (mainly `<caption>`).\n\t\tif ( tableChild.name !== 'tbody' && tableChild.name !== 'thead' && tableChild.name !== 'tfoot' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Save the first `<thead>` in the table as table header - all other ones will be converted to table body rows.\n\t\tif ( tableChild.name === 'thead' && !firstTheadElement ) {\n\t\t\tfirstTheadElement = tableChild;\n\t\t}\n\n\t\t// There might be some extra empty text nodes between the `<tr>`s.\n\t\t// Make sure further code operates on `tr`s only. (#145)\n\t\tconst trs = Array.from( tableChild.getChildren() ).filter(\n\t\t\t( el: ViewNode ): el is ViewElement & { name: 'tr' } => el.is( 'element', 'tr' )\n\t\t);\n\n\t\tfor ( const tr of trs ) {\n\t\t\t// This <tr> is a child of a first <thead> element.\n\t\t\tif (\n\t\t\t\t( firstTheadElement && tableChild === firstTheadElement ) ||\n\t\t\t\t(\n\t\t\t\t\ttableChild.name === 'tbody' &&\n\t\t\t\t\tArray.from( tr.getChildren() ).length &&\n\t\t\t\t\tArray.from( tr.getChildren() ).every( e => e.is( 'element', 'th' ) )\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\theadingRows++;\n\t\t\t\theadRows.push( tr );\n\t\t\t} else {\n\t\t\t\tbodyRows.push( tr );\n\t\t\t\t// For other rows check how many column headings this row has.\n\n\t\t\t\tconst headingCols = scanRowForHeadingColumns( tr );\n\n\t\t\t\tif ( !headingColumns || headingCols < headingColumns ) {\n\t\t\t\t\theadingColumns = headingCols;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\theadingRows,\n\t\theadingColumns: headingColumns || 0,\n\t\trows: [ ...headRows, ...bodyRows ]\n\t};\n}\n\n/**\n * Scans a `<tr>` element and its children for metadata:\n * - For heading row:\n *     - Adds this row to either the heading or the body rows.\n *     - Updates the number of heading rows.\n * - For body rows:\n *     - Calculates the number of column headings.\n */\nfunction scanRowForHeadingColumns( tr: ViewElement ) {\n\tlet headingColumns = 0;\n\tlet index = 0;\n\n\t// Filter out empty text nodes from tr children.\n\tconst children = Array.from( tr.getChildren() as IterableIterator<ViewElement> )\n\t\t.filter( child => child.name === 'th' || child.name === 'td' );\n\n\t// Count starting adjacent <th> elements of a <tr>.\n\twhile ( index < children.length && children[ index ].name === 'th' ) {\n\t\tconst th = children[ index ];\n\n\t\t// Adjust columns calculation by the number of spanned columns.\n\t\tconst colspan = parseInt( th.getAttribute( 'colspan' ) as string || '1' );\n\n\t\theadingColumns = headingColumns + colspan;\n\t\tindex++;\n\t}\n\n\treturn headingColumns;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablewalker\n */\nimport type { Element, Position } from 'ckeditor5/src/engine.js';\n\n// @if CK_DEBUG // const CKEditorError = require( '@ckeditor/ckeditor5-utils/src/ckeditorerror' ).default;\n\ninterface CellData {\n\tcell: Element;\n\trow: number;\n\tcolumn: number;\n}\n\n/**\n * An object with configuration for `TableWalker`.\n */\nexport interface TableWalkerOptions {\n\n\t/**\n\t * A row index for which this iterator will output cells. Can't be used together with `startRow` and `endRow`.\n\t */\n\trow?: number | null;\n\n\t/**\n\t * A row index from which this iterator should start. Can't be used together with `row`. Default value is 0.\n\t */\n\tstartRow?: number;\n\n\t/**\n\t * A row index at which this iterator should end. Can't be used together with `row`.\n\t */\n\tendRow?: number;\n\n\t/**\n\t * A column index for which this iterator will output cells. Can't be used together with `startColumn` and `endColumn`.\n\t */\n\tcolumn?: number;\n\n\t/**\n\t * A column index from which this iterator should start. Can't be used together with `column`. Default value is 0.\n\t */\n\tstartColumn?: number;\n\n\t/**\n\t * A column index at which this iterator should end. Can't be used together with `column`.\n\t */\n\tendColumn?: number;\n\n\t/**\n\t * Also return values for spanned cells. Default value is false.\n\t */\n\tincludeAllSlots?: boolean;\n}\n\n/**\n * The table iterator class. It allows to iterate over table cells. For each cell the iterator yields\n * {@link module:table/tablewalker~TableSlot} with proper table cell attributes.\n */\nexport default class TableWalker implements IterableIterator<TableSlot> {\n\t/**\n\t * The walker's table element.\n\t *\n\t * @internal\n\t */\n\tpublic readonly _table: Element;\n\n\t/**\n\t * A row index from which this iterator will start.\n\t */\n\tprivate readonly _startRow: number | null;\n\n\t/**\n\t * A row index at which this iterator will end.\n\t */\n\tprivate readonly _endRow?: number | null;\n\n\t/**\n\t * If set, the table walker will only output cells from a given column and following ones or cells that overlap them.\n\t */\n\tprivate readonly _startColumn: number;\n\n\t/**\n\t * If set, the table walker will only output cells up to a given column.\n\t */\n\tprivate readonly _endColumn?: number;\n\n\t/**\n\t * Enables output of spanned cells that are normally not yielded.\n\t */\n\tprivate readonly _includeAllSlots: boolean;\n\n\t/**\n\t * Row indexes to skip from the iteration.\n\t */\n\tprivate readonly _skipRows: Set<number>;\n\n\t/**\n\t * The current row index.\n\t *\n\t * @internal\n\t */\n\tpublic _row: number;\n\n\t/**\n\t * The index of the current row element in the table.\n\t *\n\t * @internal\n\t */\n\tpublic _rowIndex: number;\n\n\t/**\n\t * The current column index.\n\t *\n\t * @internal\n\t */\n\tpublic _column: number;\n\n\t/**\n\t * The cell index in a parent row. For spanned cells when {@link #_includeAllSlots} is set to `true`,\n\t * this represents the index of the next table cell.\n\t *\n\t * @internal\n\t */\n\tpublic _cellIndex: number;\n\n\t/**\n\t * Holds a map of spanned cells in a table.\n\t */\n\tprivate readonly _spannedCells: Map<number, Map<number, CellData>>;\n\n\t/**\n\t * Index of the next column where a cell is anchored.\n\t */\n\tprivate _nextCellAtColumn: number;\n\n\t/**\n\t * Indicates whether the iterator jumped to (or close to) the start row, ignoring rows that don't need to be traversed.\n\t */\n\tprivate _jumpedToStartRow = false;\n\n\t/**\n\t * Creates an instance of the table walker.\n\t *\n\t * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.\n\t * It walks row by row and column by column in order to output values defined in the constructor.\n\t * By default it will output only the locations that are occupied by a cell. To include also spanned rows and columns,\n\t * pass the `includeAllSlots` option to the constructor.\n\t *\n\t * The most important values of the iterator are column and row indexes of a cell.\n\t *\n\t * See {@link module:table/tablewalker~TableSlot} what values are returned by the table walker.\n\t *\n\t * To iterate over a given row:\n\t *\n\t * ```ts\n\t * const tableWalker = new TableWalker( table, { startRow: 1, endRow: 2 } );\n\t *\n\t * for ( const tableSlot of tableWalker ) {\n\t *   console.log( 'A cell at row', tableSlot.row, 'and column', tableSlot.column );\n\t * }\n\t * ```\n\t *\n\t * For instance the code above for the following table:\n\t *\n\t *  +----+----+----+----+----+----+\n\t *  | 00      | 02 | 03 | 04 | 05 |\n\t *  |         +----+----+----+----+\n\t *  |         | 12      | 14 | 15 |\n\t *  |         +----+----+----+    +\n\t *  |         | 22           |    |\n\t *  |----+----+----+----+----+    +\n\t *  | 30 | 31 | 32 | 33 | 34 |    |\n\t *  +----+----+----+----+----+----+\n\t *\n\t * will log in the console:\n\t *\n\t *  'A cell at row 1 and column 2'\n\t *  'A cell at row 1 and column 4'\n\t *  'A cell at row 1 and column 5'\n\t *  'A cell at row 2 and column 2'\n\t *\n\t * To also iterate over spanned cells:\n\t *\n\t * ```ts\n\t * const tableWalker = new TableWalker( table, { row: 1, includeAllSlots: true } );\n\t *\n\t * for ( const tableSlot of tableWalker ) {\n\t *   console.log( 'Slot at', tableSlot.row, 'x', tableSlot.column, ':', tableSlot.isAnchor ? 'is anchored' : 'is spanned' );\n\t * }\n\t * ```\n\t *\n\t * will log in the console for the table from the previous example:\n\t *\n\t *  'Cell at 1 x 0 : is spanned'\n\t *  'Cell at 1 x 1 : is spanned'\n\t *  'Cell at 1 x 2 : is anchored'\n\t *  'Cell at 1 x 3 : is spanned'\n\t *  'Cell at 1 x 4 : is anchored'\n\t *  'Cell at 1 x 5 : is anchored'\n\t *\n\t * **Note**: Option `row` is a shortcut that sets both `startRow` and `endRow` to the same row.\n\t * (Use either `row` or `startRow` and `endRow` but never together). Similarly the `column` option sets both `startColumn`\n\t * and `endColumn` to the same column (Use either `column` or `startColumn` and `endColumn` but never together).\n\t *\n\t * @param table A table over which the walker iterates.\n\t * @param options An object with configuration.\n\t * @param options.row A row index for which this iterator will output cells. Can't be used together with `startRow` and `endRow`.\n\t * @param options.startRow A row index from which this iterator should start. Can't be used together with `row`. Default value is 0.\n\t * @param options.endRow A row index at which this iterator should end. Can't be used together with `row`.\n\t * @param options.column A column index for which this iterator will output cells.\n\t * Can't be used together with `startColumn` and `endColumn`.\n\t * @param options.startColumn A column index from which this iterator should start.\n\t * Can't be used together with `column`. Default value is 0.\n\t * @param options.endColumn A column index at which this iterator should end. Can't be used together with `column`.\n\t * @param options.includeAllSlots Also return values for spanned cells. Default value is \"false\".\n\t */\n\tconstructor( table: Element, options: TableWalkerOptions = {} ) {\n\t\tthis._table = table;\n\t\tthis._startRow = options.row !== undefined ? options.row : options.startRow || 0;\n\t\tthis._endRow = options.row !== undefined ? options.row : options.endRow;\n\t\tthis._startColumn = options.column !== undefined ? options.column : options.startColumn || 0;\n\t\tthis._endColumn = options.column !== undefined ? options.column : options.endColumn;\n\t\tthis._includeAllSlots = !!options.includeAllSlots;\n\t\tthis._skipRows = new Set();\n\t\tthis._row = 0;\n\t\tthis._rowIndex = 0;\n\t\tthis._column = 0;\n\t\tthis._cellIndex = 0;\n\t\tthis._spannedCells = new Map();\n\t\tthis._nextCellAtColumn = -1;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t */\n\tpublic [ Symbol.iterator ](): IterableIterator<TableSlot> {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the next table walker's value.\n\t *\n\t * @returns The next table walker's value.\n\t */\n\tpublic next(): IteratorResult<TableSlot, undefined> {\n\t\tif ( this._canJumpToStartRow() ) {\n\t\t\tthis._jumpToNonSpannedRowClosestToStartRow();\n\t\t}\n\n\t\tconst row = this._table.getChild( this._rowIndex );\n\n\t\t// Iterator is done when there's no row (table ended) or the row is after `endRow` limit.\n\t\tif ( !row || this._isOverEndRow() ) {\n\t\t\treturn { done: true, value: undefined };\n\t\t}\n\n\t\t// We step over current element when it is not a tableRow instance.\n\t\tif ( !row.is( 'element', 'tableRow' ) ) {\n\t\t\tthis._rowIndex++;\n\n\t\t\treturn this.next();\n\t\t}\n\n\t\tif ( this._isOverEndColumn() ) {\n\t\t\treturn this._advanceToNextRow();\n\t\t}\n\n\t\tlet outValue: IteratorYieldResult<TableSlot> | null = null;\n\n\t\tconst spanData = this._getSpanned();\n\n\t\tif ( spanData ) {\n\t\t\tif ( this._includeAllSlots && !this._shouldSkipSlot() ) {\n\t\t\t\toutValue = this._formatOutValue( spanData.cell, spanData.row, spanData.column );\n\t\t\t}\n\t\t} else {\n\t\t\tconst cell = row.getChild( this._cellIndex ) as Element;\n\n\t\t\tif ( !cell ) {\n\t\t\t\t// If there are no more cells left in row advance to the next row.\n\t\t\t\treturn this._advanceToNextRow();\n\t\t\t}\n\n\t\t\tconst colspan = parseInt( cell.getAttribute( 'colspan' ) as string || '1' );\n\t\t\tconst rowspan = parseInt( cell.getAttribute( 'rowspan' ) as string || '1' );\n\n\t\t\t// Record this cell spans if it's not 1x1 cell.\n\t\t\tif ( colspan > 1 || rowspan > 1 ) {\n\t\t\t\tthis._recordSpans( cell, rowspan, colspan );\n\t\t\t}\n\n\t\t\tif ( !this._shouldSkipSlot() ) {\n\t\t\t\toutValue = this._formatOutValue( cell );\n\t\t\t}\n\n\t\t\tthis._nextCellAtColumn = this._column + colspan;\n\t\t}\n\n\t\t// Advance to the next column before returning value.\n\t\tthis._column++;\n\n\t\tif ( this._column == this._nextCellAtColumn ) {\n\t\t\tthis._cellIndex++;\n\t\t}\n\n\t\t// The current value will be returned only if current row and column are not skipped.\n\t\treturn outValue || this.next();\n\t}\n\n\t/**\n\t * Marks a row to skip in the next iteration. It will also skip cells from the current row if there are any cells from the current row\n\t * to output.\n\t *\n\t * @param row The row index to skip.\n\t */\n\tpublic skipRow( row: number ): void {\n\t\tthis._skipRows.add( row );\n\t}\n\n\t/**\n\t * Advances internal cursor to the next row.\n\t */\n\tprivate _advanceToNextRow() {\n\t\tthis._row++;\n\t\tthis._rowIndex++;\n\t\tthis._column = 0;\n\t\tthis._cellIndex = 0;\n\t\tthis._nextCellAtColumn = -1;\n\n\t\treturn this.next();\n\t}\n\n\t/**\n\t * Checks if the current row is over {@link #_endRow}.\n\t */\n\tprivate _isOverEndRow() {\n\t\t// If #_endRow is defined skip all rows after it.\n\t\treturn this._endRow !== undefined && this._row > this._endRow!;\n\t}\n\n\t/**\n\t * Checks if the current cell is over {@link #_endColumn}\n\t */\n\tprivate _isOverEndColumn() {\n\t\t// If #_endColumn is defined skip all cells after it.\n\t\treturn this._endColumn !== undefined && this._column > this._endColumn;\n\t}\n\n\t/**\n\t * A common method for formatting the iterator's output value.\n\t *\n\t * @param cell The table cell to output.\n\t * @param anchorRow The row index of a cell anchor slot.\n\t * @param anchorColumn The column index of a cell anchor slot.\n\t */\n\tprivate _formatOutValue( cell: Element, anchorRow = this._row, anchorColumn = this._column ): IteratorYieldResult<TableSlot> {\n\t\treturn {\n\t\t\tdone: false,\n\t\t\tvalue: new TableSlot( this, cell, anchorRow, anchorColumn )\n\t\t};\n\t}\n\n\t/**\n\t * Checks if the current slot should be skipped.\n\t */\n\tprivate _shouldSkipSlot(): boolean {\n\t\tconst rowIsMarkedAsSkipped = this._skipRows.has( this._row );\n\t\tconst rowIsBeforeStartRow = this._row < this._startRow!;\n\n\t\tconst columnIsBeforeStartColumn = this._column < this._startColumn;\n\t\tconst columnIsAfterEndColumn = this._endColumn !== undefined && this._column > this._endColumn;\n\n\t\treturn rowIsMarkedAsSkipped || rowIsBeforeStartRow || columnIsBeforeStartColumn || columnIsAfterEndColumn;\n\t}\n\n\t/**\n\t * Returns the cell element that is spanned over the current cell location.\n\t */\n\tprivate _getSpanned(): CellData | null {\n\t\tconst rowMap = this._spannedCells.get( this._row );\n\n\t\t// No spans for given row.\n\t\tif ( !rowMap ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// If spans for given rows has entry for column it means that this location if spanned by other cell.\n\t\treturn rowMap.get( this._column ) || null;\n\t}\n\n\t/**\n\t * Updates spanned cells map relative to the current cell location and its span dimensions.\n\t *\n\t * @param cell A cell that is spanned.\n\t * @param rowspan Cell height.\n\t * @param colspan Cell width.\n\t */\n\tprivate _recordSpans( cell: Element, rowspan: number, colspan: number ) {\n\t\tconst data = {\n\t\t\tcell,\n\t\t\trow: this._row,\n\t\t\tcolumn: this._column\n\t\t};\n\n\t\tfor ( let rowToUpdate = this._row; rowToUpdate < this._row + rowspan; rowToUpdate++ ) {\n\t\t\tfor ( let columnToUpdate = this._column; columnToUpdate < this._column + colspan; columnToUpdate++ ) {\n\t\t\t\tif ( rowToUpdate != this._row || columnToUpdate != this._column ) {\n\t\t\t\t\tthis._markSpannedCell( rowToUpdate, columnToUpdate, data );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Marks the cell location as spanned by another cell.\n\t *\n\t * @param row The row index of the cell location.\n\t * @param column The column index of the cell location.\n\t * @param data A spanned cell details (cell element, anchor row and column).\n\t */\n\tprivate _markSpannedCell( row: number, column: number, data: CellData ) {\n\t\tif ( !this._spannedCells.has( row ) ) {\n\t\t\tthis._spannedCells.set( row, new Map() );\n\t\t}\n\n\t\tconst rowSpans = this._spannedCells.get( row )!;\n\n\t\trowSpans.set( column, data );\n\t}\n\n\t/**\n\t * Checks if part of the table can be skipped.\n\t */\n\tprivate _canJumpToStartRow(): boolean {\n\t\treturn !!this._startRow &&\n\t\t\tthis._startRow > 0 &&\n\t\t\t!this._jumpedToStartRow;\n\t}\n\n\t/**\n\t * Sets the current row to `this._startRow` or the first row before it that has the number of cells\n\t * equal to the number of columns in the table.\n\t *\n\t * Example:\n\t * \t+----+----+----+\n\t *  | 00 | 01 | 02 |\n\t *  |----+----+----+\n\t *  | 10      | 12 |\n\t *  |         +----+\n\t *  |         | 22 |\n\t *  |         +----+\n\t *  |         | 32 | <--- Start row\n\t *  +----+----+----+\n\t *  | 40 | 41 | 42 |\n\t *  +----+----+----+\n\t *\n\t * If the 4th row is a `this._startRow`, this method will:\n\t * 1.) Count the number of columns this table has based on the first row (3 columns in this case).\n\t * 2.) Check if the 4th row contains 3 cells. It doesn't, so go to the row before it.\n\t * 3.) Check if the 3rd row contains 3 cells. It doesn't, so go to the row before it.\n\t * 4.) Check if the 2nd row contains 3 cells. It does, so set the current row to that row.\n\t *\n\t * Setting the current row this way is necessary to let the `next()`  method loop over the cells\n\t * spanning multiple rows or columns and update the `this._spannedCells` property.\n\t */\n\tprivate _jumpToNonSpannedRowClosestToStartRow(): void {\n\t\tconst firstRowLength = this._getRowLength( 0 );\n\n\t\tfor ( let i = this._startRow!; !this._jumpedToStartRow; i-- ) {\n\t\t\tif ( firstRowLength === this._getRowLength( i ) ) {\n\t\t\t\tthis._row = i;\n\t\t\t\tthis._rowIndex = i;\n\t\t\t\tthis._jumpedToStartRow = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns a number of columns in a row taking `colspan` into consideration.\n\t */\n\tprivate _getRowLength( rowIndex: number ): number {\n\t\tconst row = this._table.getChild( rowIndex ) as Element;\n\n\t\treturn [ ...row.getChildren() ].reduce( ( cols, row ) => {\n\t\t\treturn cols + parseInt( row.getAttribute( 'colspan' ) as string || '1' );\n\t\t}, 0 );\n\t}\n}\n\n/**\n * An object returned by {@link module:table/tablewalker~TableWalker} when traversing table cells.\n */\nclass TableSlot {\n\t/**\n\t * The current table cell.\n\t */\n\tpublic readonly cell: Element;\n\n\t/**\n\t * The row index of a table slot.\n\t */\n\tpublic readonly row: number;\n\n\t/**\n\t * The column index of a table slot.\n\t */\n\tpublic readonly column: number;\n\n\t/**\n\t * The row index of a cell anchor slot.\n\t */\n\tpublic readonly cellAnchorRow: number;\n\n\t/**\n\t * The column index of a cell anchor slot.\n\t */\n\tpublic readonly cellAnchorColumn: number;\n\n\t/**\n\t * The index of the current cell in the parent row.\n\t */\n\tprivate readonly _cellIndex: number;\n\n\t/**\n\t * The index of the current row element in the table.\n\t */\n\tprivate readonly _rowIndex: number;\n\n\t/**\n\t * The table element.\n\t */\n\tprivate readonly _table: Element;\n\n\t/**\n\t * Creates an instance of the table walker value.\n\t *\n\t * @param tableWalker The table walker instance.\n\t * @param cell The current table cell.\n\t * @param anchorRow The row index of a cell anchor slot.\n\t * @param anchorColumn The column index of a cell anchor slot.\n\t */\n\tconstructor( tableWalker: TableWalker, cell: Element, anchorRow: number, anchorColumn: number ) {\n\t\tthis.cell = cell;\n\t\tthis.row = tableWalker._row;\n\t\tthis.column = tableWalker._column;\n\t\tthis.cellAnchorRow = anchorRow;\n\t\tthis.cellAnchorColumn = anchorColumn;\n\t\tthis._cellIndex = tableWalker._cellIndex;\n\t\tthis._rowIndex = tableWalker._rowIndex;\n\t\tthis._table = tableWalker._table;\n\t}\n\n\t// @if CK_DEBUG // public get isSpanned(): unknown { return throwMissingGetterError( 'isSpanned' ); }\n\t// @if CK_DEBUG // public get colspan(): unknown { return throwMissingGetterError( 'colspan' ); }\n\t// @if CK_DEBUG // public get rowspan(): unknown { return throwMissingGetterError( 'rowspan' ); }\n\t// @if CK_DEBUG // public get cellIndex(): unknown { return throwMissingGetterError( 'cellIndex' ); }\n\n\t/**\n\t * Whether the cell is anchored in the current slot.\n\t */\n\tpublic get isAnchor(): boolean {\n\t\treturn this.row === this.cellAnchorRow && this.column === this.cellAnchorColumn;\n\t}\n\n\t/**\n\t * The width of a cell defined by a `colspan` attribute. If the model attribute is not present, it is set to `1`.\n\t */\n\tpublic get cellWidth(): number {\n\t\treturn parseInt( this.cell.getAttribute( 'colspan' ) as string || '1' );\n\t}\n\n\t/**\n\t * The height of a cell defined by a `rowspan` attribute. If the model attribute is not present, it is set to `1`.\n\t */\n\tpublic get cellHeight(): number {\n\t\treturn parseInt( this.cell.getAttribute( 'rowspan' ) as string || '1' );\n\t}\n\n\t/**\n\t * The index of the current row element in the table.\n\t */\n\tpublic get rowIndex(): number {\n\t\treturn this._rowIndex;\n\t}\n\n\t/**\n\t * Returns the {@link module:engine/model/position~Position} before the table slot.\n\t */\n\tpublic getPositionBefore(): Position {\n\t\tconst model = this._table.root.document!.model;\n\n\t\treturn model.createPositionAt( this._table.getChild( this.row ) as Element, this._cellIndex );\n\t}\n}\n\nexport type { TableSlot };\n\n/**\n * This `TableSlot`'s getter (property) was removed in CKEditor 5 v20.0.0.\n *\n * Check out the new `TableWalker`'s API in the documentation.\n *\n * @error tableslot-getter-removed\n * @param getterName\n */\n// @if CK_DEBUG // function throwMissingGetterError( getterName: string ): void {\n// @if CK_DEBUG //\t\tthrow new CKEditorError( 'tableslot-getter-removed', null, {\n// @if CK_DEBUG //\t\t\tgetterName\n// @if CK_DEBUG //\t\t} );\n// @if CK_DEBUG // }\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/downcast\n */\n\nimport { toWidget, toWidgetEditable } from 'ckeditor5/src/widget.js';\nimport type { Node, ViewElement, Element, DowncastWriter, ElementCreatorFunction } from 'ckeditor5/src/engine.js';\n\nimport TableWalker from './../tablewalker.js';\nimport type TableUtils from '../tableutils.js';\nimport type { AdditionalSlot } from '../tableediting.js';\n\n/**\n * Model table element to view table element conversion helper.\n */\nexport function downcastTable( tableUtils: TableUtils, options: DowncastTableOptions ): ElementCreatorFunction {\n\treturn ( table, { writer } ) => {\n\t\tconst headingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\t\tconst tableElement = writer.createContainerElement( 'table', null, [] );\n\t\tconst figureElement = writer.createContainerElement( 'figure', { class: 'table' }, tableElement );\n\n\t\t// Table head slot.\n\t\tif ( headingRows > 0 ) {\n\t\t\twriter.insert(\n\t\t\t\twriter.createPositionAt( tableElement, 'end' ),\n\t\t\t\twriter.createContainerElement(\n\t\t\t\t\t'thead',\n\t\t\t\t\tnull,\n\t\t\t\t\twriter.createSlot( element => element.is( 'element', 'tableRow' ) && element.index! < headingRows )\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Table body slot.\n\t\tif ( headingRows < tableUtils.getRows( table ) ) {\n\t\t\twriter.insert(\n\t\t\t\twriter.createPositionAt( tableElement, 'end' ),\n\t\t\t\twriter.createContainerElement(\n\t\t\t\t\t'tbody',\n\t\t\t\t\tnull,\n\t\t\t\t\twriter.createSlot( element => element.is( 'element', 'tableRow' ) && element.index! >= headingRows )\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\t// Dynamic slots.\n\t\tfor ( const { positionOffset, filter } of options.additionalSlots ) {\n\t\t\twriter.insert(\n\t\t\t\twriter.createPositionAt( tableElement, positionOffset ),\n\t\t\t\twriter.createSlot( filter )\n\t\t\t);\n\t\t}\n\n\t\t// Create a slot with items that don't fit into the table.\n\t\twriter.insert(\n\t\t\twriter.createPositionAt( tableElement, 'after' ),\n\t\t\twriter.createSlot( element => {\n\t\t\t\tif ( element.is( 'element', 'tableRow' ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn !options.additionalSlots.some( ( { filter } ) => filter( element ) );\n\t\t\t} )\n\t\t);\n\n\t\treturn options.asWidget ? toTableWidget( figureElement, writer ) : figureElement;\n\t};\n}\n\n/**\n * Model table row element to view `<tr>` element conversion helper.\n *\n * @returns Element creator.\n */\nexport function downcastRow(): ElementCreatorFunction {\n\treturn ( tableRow, { writer } ) => {\n\t\treturn tableRow.isEmpty ?\n\t\t\twriter.createEmptyElement( 'tr' ) :\n\t\t\twriter.createContainerElement( 'tr' );\n\t};\n}\n\n/**\n * Model table cell element to view `<td>` or `<th>` element conversion helper.\n *\n * This conversion helper will create proper `<th>` elements for table cells that are in the heading section (heading row or column)\n * and `<td>` otherwise.\n *\n * @param options.asWidget If set to `true`, the downcast conversion will produce a widget.\n * @returns Element creator.\n */\nexport function downcastCell( options: { asWidget?: boolean } = {} ): ElementCreatorFunction {\n\treturn ( tableCell, { writer } ) => {\n\t\tconst tableRow = tableCell.parent as Element;\n\t\tconst table = tableRow.parent as Element;\n\t\tconst rowIndex = table.getChildIndex( tableRow )!;\n\n\t\tconst tableWalker = new TableWalker( table, { row: rowIndex } );\n\t\tconst headingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) as number || 0;\n\n\t\tlet result: ViewElement | null = null;\n\n\t\t// We need to iterate over a table in order to get proper row & column values from a walker.\n\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\tif ( tableSlot.cell == tableCell ) {\n\t\t\t\tconst isHeading = tableSlot.row < headingRows || tableSlot.column < headingColumns;\n\t\t\t\tconst cellElementName = isHeading ? 'th' : 'td';\n\n\t\t\t\tresult = options.asWidget ?\n\t\t\t\t\ttoWidgetEditable( writer.createEditableElement( cellElementName ), writer ) :\n\t\t\t\t\twriter.createContainerElement( cellElementName );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t};\n}\n\n/**\n * Overrides paragraph inside table cell conversion.\n *\n * This converter:\n * * should be used to override default paragraph conversion.\n * * It will only convert `<paragraph>` placed directly inside `<tableCell>`.\n * * For a single paragraph without attributes it returns `<span>` to simulate data table.\n * * For all other cases it returns `<p>` element.\n *\n * @param options.asWidget If set to `true`, the downcast conversion will produce a widget.\n * @returns Element creator.\n */\nexport function convertParagraphInTableCell( options: { asWidget?: boolean } = {} ): ElementCreatorFunction {\n\treturn ( modelElement, { writer } ) => {\n\t\tif ( !modelElement.parent!.is( 'element', 'tableCell' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( !isSingleParagraphWithoutAttributes( modelElement ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( options.asWidget ) {\n\t\t\treturn writer.createContainerElement( 'span', { class: 'ck-table-bogus-paragraph' } );\n\t\t} else {\n\t\t\t// Using `<p>` in case there are some markers on it and transparentRendering will render it anyway.\n\t\t\tconst viewElement = writer.createContainerElement( 'p' );\n\n\t\t\twriter.setCustomProperty( 'dataPipeline:transparentRendering', true, viewElement );\n\n\t\t\treturn viewElement;\n\t\t}\n\t};\n}\n\n/**\n * Checks if given model `<paragraph>` is an only child of a parent (`<tableCell>`) and if it has any attribute set.\n *\n * The paragraph should be converted in the editing view to:\n *\n * * If returned `true` - to a `<span class=\"ck-table-bogus-paragraph\">`\n * * If returned `false` - to a `<p>`\n */\nexport function isSingleParagraphWithoutAttributes( modelElement: Element ): boolean {\n\tconst tableCell = modelElement.parent!;\n\n\tconst isSingleParagraph = tableCell.childCount == 1;\n\n\treturn isSingleParagraph && !hasAnyAttribute( modelElement );\n}\n\n/**\n * Converts a given {@link module:engine/view/element~Element} to a table widget:\n * * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the table widget element.\n * * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n *\n * @param writer An instance of the view writer.\n * @param label The element's label. It will be concatenated with the table `alt` attribute if one is present.\n */\nfunction toTableWidget( viewElement: ViewElement, writer: DowncastWriter ): ViewElement {\n\twriter.setCustomProperty( 'table', true, viewElement );\n\n\treturn toWidget( viewElement, writer, { hasSelectionHandle: true } );\n}\n\n/**\n * Checks if an element has any attributes set.\n */\nfunction hasAnyAttribute( element: Node ): boolean {\n\tconst iteratorItem = element.getAttributeKeys().next();\n\n\treturn !iteratorItem.done;\n}\n\nexport interface DowncastTableOptions {\n\n\t/**\n\t * If set to `true`, the downcast conversion will produce a widget.\n\t */\n\tasWidget?: boolean;\n\n\t/**\n\t * Array of additional slot handlers.\n\t */\n\tadditionalSlots: Array<AdditionalSlot>;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/inserttablecommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\n\nimport type {\n\tDocumentSelection,\n\tSchema,\n\tSelection,\n\tElement\n} from 'ckeditor5/src/engine.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The insert table command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTable'` editor command.\n *\n * To insert a table at the current selection, execute the command and specify the dimensions:\n *\n * ```ts\n * editor.execute( 'insertTable', { rows: 20, columns: 5 } );\n * ```\n */\nexport default class InsertTableCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst schema = model.schema;\n\n\t\tthis.isEnabled = isAllowedInParent( selection, schema );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Inserts a table with the given number of rows and columns into the editor.\n\t *\n\t * @param options.rows The number of rows to create in the inserted table. Default value is 2.\n\t * @param options.columns The number of columns to create in the inserted table. Default value is 2.\n\t * @param options.headingRows The number of heading rows. If not provided it will default to\n\t * {@link module:table/tableconfig~TableConfig#defaultHeadings `config.table.defaultHeadings.rows`} table config.\n\t * @param options.headingColumns The number of heading columns. If not provided it will default to\n\t * {@link module:table/tableconfig~TableConfig#defaultHeadings `config.table.defaultHeadings.columns`} table config.\n\t * @fires execute\n\t */\n\tpublic override execute(\n\t\toptions: {\n\t\t\trows?: number;\n\t\t\tcolumns?: number;\n\t\t\theadingRows?: number;\n\t\t\theadingColumns?: number;\n\t\t} = {}\n\t): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst tableUtils: TableUtils = editor.plugins.get( 'TableUtils' );\n\n\t\tconst defaultRows = editor.config.get( 'table.defaultHeadings.rows' );\n\t\tconst defaultColumns = editor.config.get( 'table.defaultHeadings.columns' );\n\n\t\tif ( options.headingRows === undefined && defaultRows ) {\n\t\t\toptions.headingRows = defaultRows;\n\t\t}\n\n\t\tif ( options.headingColumns === undefined && defaultColumns ) {\n\t\t\toptions.headingColumns = defaultColumns;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst table = tableUtils.createTable( writer, options );\n\n\t\t\tmodel.insertObject( table, null, null, { findOptimalPosition: 'auto' } );\n\n\t\t\twriter.setSelection( writer.createPositionAt( table.getNodeByPath( [ 0, 0, 0 ] ), 0 ) );\n\t\t} );\n\t}\n}\n\n/**\n * Checks if the table is allowed in the parent.\n */\nfunction isAllowedInParent( selection: Selection | DocumentSelection, schema: Schema ) {\n\tconst positionParent = selection.getFirstPosition()!.parent;\n\tconst validParent = positionParent === positionParent.root ? positionParent : positionParent.parent;\n\n\treturn schema.checkChild( validParent as Element, 'table' );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/insertrowcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The insert row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTableRowBelow'` and\n * `'insertTableRowAbove'` editor commands.\n *\n * To insert a row below the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableRowBelow' );\n * ```\n *\n * To insert a row above the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableRowAbove' );\n * ```\n */\nexport default class InsertRowCommand extends Command {\n\t/**\n\t * The order of insertion relative to the row in which the caret is located.\n\t */\n\tpublic readonly order: 'above' | 'below';\n\n\t/**\n\t * Creates a new `InsertRowCommand` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t * @param options.order The order of insertion relative to the row in which the caret is located.\n\t * Possible values: `\"above\"` and `\"below\"`. Default value is \"below\"\n\t */\n\tconstructor( editor: Editor, options: { order?: 'above' | 'below' } = {} ) {\n\t\tsuper( editor );\n\n\t\tthis.order = options.order || 'below';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst isAnyCellSelected = !!tableUtils.getSelectionAffectedTableCells( selection ).length;\n\n\t\tthis.isEnabled = isAnyCellSelected;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a row `'below'` or `'above'` the row in which selection is set.\n\t *\n\t * @fires execute\n\t */\n\tpublic override execute(): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst tableUtils: TableUtils = editor.plugins.get( 'TableUtils' );\n\t\tconst insertAbove = this.order === 'above';\n\n\t\tconst affectedTableCells = tableUtils.getSelectionAffectedTableCells( selection );\n\t\tconst rowIndexes = tableUtils.getRowIndexes( affectedTableCells );\n\n\t\tconst row = insertAbove ? rowIndexes.first : rowIndexes.last;\n\t\tconst table = affectedTableCells[ 0 ].findAncestor( 'table' )!;\n\n\t\ttableUtils.insertRows( table, { at: insertAbove ? row : row + 1, copyStructureFromAbove: !insertAbove } );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/insertcolumncommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The insert column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTableColumnLeft'` and\n * `'insertTableColumnRight'` editor commands.\n *\n * To insert a column to the left of the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableColumnLeft' );\n * ```\n *\n * To insert a column to the right of the selected cell, execute the following command:\n *\n * ```ts\n * editor.execute( 'insertTableColumnRight' );\n * ```\n */\nexport default class InsertColumnCommand extends Command {\n\t/**\n\t * The order of insertion relative to the column in which the caret is located.\n\t */\n\tpublic readonly order: 'left' | 'right';\n\n\t/**\n\t * Creates a new `InsertColumnCommand` instance.\n\t *\n\t * @param editor An editor on which this command will be used.\n\t * @param options.order The order of insertion relative to the column in which the caret is located.\n\t * Possible values: `\"left\"` and `\"right\"`. Default value is \"right\".\n\t */\n\tconstructor( editor: Editor, options: { order?: 'left' | 'right' } = {} ) {\n\t\tsuper( editor );\n\n\t\tthis.order = options.order || 'right';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst isAnyCellSelected = !!tableUtils.getSelectionAffectedTableCells( selection ).length;\n\n\t\tthis.isEnabled = isAnyCellSelected;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a column to the `'left'` or `'right'` of the column\n\t * in which the selection is set.\n\t *\n\t * @fires execute\n\t */\n\tpublic override execute(): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst tableUtils: TableUtils = editor.plugins.get( 'TableUtils' );\n\t\tconst insertBefore = this.order === 'left';\n\n\t\tconst affectedTableCells = tableUtils.getSelectionAffectedTableCells( selection );\n\t\tconst columnIndexes = tableUtils.getColumnIndexes( affectedTableCells );\n\n\t\tconst column = insertBefore ? columnIndexes.first : columnIndexes.last;\n\t\tconst table = affectedTableCells[ 0 ].findAncestor( 'table' )!;\n\n\t\ttableUtils.insertColumns( table, { columns: 1, at: insertBefore ? column : column + 1 } );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/splitcellcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The split cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'splitTableCellVertically'`\n * and `'splitTableCellHorizontally'`  editor commands.\n *\n * You can split any cell vertically or horizontally by executing this command. For example, to split the selected table cell vertically:\n *\n * ```ts\n * editor.execute( 'splitTableCellVertically' );\n * ```\n */\nexport default class SplitCellCommand extends Command {\n\t/**\n\t * The direction that indicates which cell will be split.\n\t */\n\tpublic readonly direction: 'horizontally' | 'vertically';\n\n\t/**\n\t * Creates a new `SplitCellCommand` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t * @param options.direction Indicates whether the command should split cells `'horizontally'` or `'vertically'`.\n\t */\n\tconstructor( editor: Editor, options: { direction?: 'horizontally' | 'vertically' } = {} ) {\n\t\tsuper( editor );\n\n\t\tthis.direction = options.direction || 'horizontally';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( this.editor.model.document.selection );\n\n\t\tthis.isEnabled = selectedCells.length === 1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst tableCell = tableUtils.getSelectionAffectedTableCells( this.editor.model.document.selection )[ 0 ];\n\t\tconst isHorizontal = this.direction === 'horizontally';\n\n\t\tif ( isHorizontal ) {\n\t\t\ttableUtils.splitCellHorizontally( tableCell, 2 );\n\t\t} else {\n\t\t\ttableUtils.splitCellVertically( tableCell, 2 );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/structure\n */\n\nimport type { Element, Node, Writer } from 'ckeditor5/src/engine.js';\n\nimport { default as TableWalker, type TableSlot } from '../tablewalker.js';\nimport { createEmptyTableCell, updateNumericAttribute } from './common.js';\nimport type TableUtils from '../tableutils.js';\n\ntype CellAttributes = {\n\trowspan?: number;\n\tcolspan?: number;\n};\n\n/**\n * Returns a cropped table according to given dimensions.\n\n * To return a cropped table that starts at first row and first column and end in third row and column:\n *\n * ```ts\n * const croppedTable = cropTableToDimensions( table, {\n *   startRow: 1,\n *   endRow: 3,\n *   startColumn: 1,\n *   endColumn: 3\n * }, writer );\n * ```\n *\n * Calling the code above for the table below:\n *\n *        0   1   2   3   4                      0   1   2\n *      ┌───┬───┬───┬───┬───┐\n *   0  │ a │ b │ c │ d │ e │\n *      ├───┴───┤   ├───┴───┤                  ┌───┬───┬───┐\n *   1  │ f     │   │ g     │                  │   │   │ g │  0\n *      ├───┬───┴───┼───┬───┤   will return:   ├───┴───┼───┤\n *   2  │ h │ i     │ j │ k │                  │ i     │ j │  1\n *      ├───┤       ├───┤   │                  │       ├───┤\n *   3  │ l │       │ m │   │                  │       │ m │  2\n *      ├───┼───┬───┤   ├───┤                  └───────┴───┘\n *   4  │ n │ o │ p │   │ q │\n *      └───┴───┴───┴───┴───┘\n */\nexport function cropTableToDimensions(\n\tsourceTable: Element,\n\tcropDimensions: {\n\t\tstartRow: number;\n\t\tstartColumn: number;\n\t\tendRow: number;\n\t\tendColumn: number;\n\t},\n\twriter: Writer\n): Element {\n\tconst { startRow, startColumn, endRow, endColumn } = cropDimensions;\n\n\t// Create empty table with empty rows equal to crop height.\n\tconst croppedTable = writer.createElement( 'table' );\n\tconst cropHeight = endRow - startRow + 1;\n\n\tfor ( let i = 0; i < cropHeight; i++ ) {\n\t\twriter.insertElement( 'tableRow', croppedTable, 'end' );\n\t}\n\n\tconst tableMap = [ ...new TableWalker( sourceTable, { startRow, endRow, startColumn, endColumn, includeAllSlots: true } ) ];\n\n\t// Iterate over source table slots (including empty - spanned - ones).\n\tfor ( const { row: sourceRow, column: sourceColumn, cell: tableCell, isAnchor, cellAnchorRow, cellAnchorColumn } of tableMap ) {\n\t\t// Row index in cropped table.\n\t\tconst rowInCroppedTable = sourceRow - startRow;\n\t\tconst row = croppedTable.getChild( rowInCroppedTable ) as Element;\n\n\t\t// For empty slots: fill the gap with empty table cell.\n\t\tif ( !isAnchor ) {\n\t\t\t// But fill the gap only if the spanning cell is anchored outside cropped area.\n\t\t\t// In the table from method jsdoc those cells are: \"c\" & \"f\".\n\t\t\tif ( cellAnchorRow < startRow || cellAnchorColumn < startColumn ) {\n\t\t\t\tcreateEmptyTableCell( writer, writer.createPositionAt( row, 'end' ) );\n\t\t\t}\n\t\t}\n\t\t// Otherwise clone the cell with all children and trim if it exceeds cropped area.\n\t\telse {\n\t\t\tconst tableCellCopy = writer.cloneElement( tableCell );\n\n\t\t\twriter.append( tableCellCopy, row );\n\n\t\t\t// Trim table if it exceeds cropped area.\n\t\t\t// In the table from method jsdoc those cells are: \"g\" & \"m\".\n\t\t\ttrimTableCellIfNeeded( tableCellCopy, sourceRow, sourceColumn, endRow, endColumn, writer );\n\t\t}\n\t}\n\n\t// Adjust heading rows & columns in cropped table if crop selection includes headings parts.\n\taddHeadingsToCroppedTable( croppedTable, sourceTable, startRow, startColumn, writer );\n\n\treturn croppedTable;\n}\n\n/**\n * Returns slot info of cells that starts above and overlaps a given row.\n *\n * In a table below, passing `overlapRow = 3`\n *\n *     ┌───┬───┬───┬───┬───┐\n *  0  │ a │ b │ c │ d │ e │\n *     │   ├───┼───┼───┼───┤\n *  1  │   │ f │ g │ h │ i │\n *     ├───┤   ├───┼───┤   │\n *  2  │ j │   │ k │ l │   │\n *     │   │   │   ├───┼───┤\n *  3  │   │   │   │ m │ n │  <- overlap row to check\n *     ├───┼───┤   │   ├───│\n *  4  │ o │ p │   │   │ q │\n *     └───┴───┴───┴───┴───┘\n *\n * will return slot info for cells: \"j\", \"f\", \"k\".\n *\n * @param table The table to check.\n * @param overlapRow The index of the row to check.\n * @param startRow row to start analysis. Use it when it is known that the cells above that row will not overlap. Default value is 0.\n */\nexport function getVerticallyOverlappingCells( table: Element, overlapRow: number, startRow: number = 0 ): Array<TableSlot> {\n\tconst cells: Array<TableSlot> = [];\n\n\tconst tableWalker = new TableWalker( table, { startRow, endRow: overlapRow - 1 } );\n\n\tfor ( const slotInfo of tableWalker ) {\n\t\tconst { row, cellHeight } = slotInfo;\n\t\tconst cellEndRow = row + cellHeight - 1;\n\n\t\tif ( row < overlapRow && overlapRow <= cellEndRow ) {\n\t\t\tcells.push( slotInfo );\n\t\t}\n\t}\n\n\treturn cells;\n}\n\n/**\n * Splits the table cell horizontally.\n *\n * @returns Created table cell, if any were created.\n */\nexport function splitHorizontally( tableCell: Element, splitRow: number, writer: Writer ): Element | null {\n\tconst tableRow = tableCell.parent as Node;\n\tconst table = tableRow.parent as Element;\n\tconst rowIndex = tableRow.index!;\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) as string );\n\tconst newRowspan = splitRow - rowIndex;\n\n\tconst newCellAttributes: CellAttributes = {};\n\tconst newCellRowSpan = rowspan - newRowspan;\n\n\tif ( newCellRowSpan > 1 ) {\n\t\tnewCellAttributes.rowspan = newCellRowSpan;\n\t}\n\n\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) as string || '1' );\n\n\tif ( colspan > 1 ) {\n\t\tnewCellAttributes.colspan = colspan;\n\t}\n\n\tconst startRow = rowIndex;\n\tconst endRow = startRow + newRowspan;\n\tconst tableMap = [ ...new TableWalker( table, { startRow, endRow, includeAllSlots: true } ) ];\n\n\tlet newCell = null;\n\tlet columnIndex;\n\n\tfor ( const tableSlot of tableMap ) {\n\t\tconst { row, column, cell } = tableSlot;\n\n\t\tif ( cell === tableCell && columnIndex === undefined ) {\n\t\t\tcolumnIndex = column;\n\t\t}\n\n\t\tif ( columnIndex !== undefined && columnIndex === column && row === endRow ) {\n\t\t\tnewCell = createEmptyTableCell( writer, tableSlot.getPositionBefore(), newCellAttributes );\n\t\t}\n\t}\n\n\t// Update the rowspan attribute after updating table.\n\tupdateNumericAttribute( 'rowspan', newRowspan, tableCell, writer );\n\n\treturn newCell;\n}\n\n/**\n * Returns slot info of cells that starts before and overlaps a given column.\n *\n * In a table below, passing `overlapColumn = 3`\n *\n *    0   1   2   3   4\n *  ┌───────┬───────┬───┐\n *  │ a     │ b     │ c │\n *  │───┬───┴───────┼───┤\n *  │ d │ e         │ f │\n *  ├───┼───┬───────┴───┤\n *  │ g │ h │ i         │\n *  ├───┼───┼───┬───────┤\n *  │ j │ k │ l │ m     │\n *  ├───┼───┴───┼───┬───┤\n *  │ n │ o     │ p │ q │\n *  └───┴───────┴───┴───┘\n *                ^\n *                Overlap column to check\n *\n * will return slot info for cells: \"b\", \"e\", \"i\".\n *\n * @param table The table to check.\n * @param overlapColumn The index of the column to check.\n */\nexport function getHorizontallyOverlappingCells( table: Element, overlapColumn: number ): Array<TableSlot> {\n\tconst cellsToSplit = [];\n\n\tconst tableWalker = new TableWalker( table );\n\n\tfor ( const slotInfo of tableWalker ) {\n\t\tconst { column, cellWidth } = slotInfo;\n\t\tconst cellEndColumn = column + cellWidth - 1;\n\n\t\tif ( column < overlapColumn && overlapColumn <= cellEndColumn ) {\n\t\t\tcellsToSplit.push( slotInfo );\n\t\t}\n\t}\n\n\treturn cellsToSplit;\n}\n\n/**\n * Splits the table cell vertically.\n *\n * @param columnIndex The table cell column index.\n * @param splitColumn The index of column to split cell on.\n * @returns Created table cell.\n */\nexport function splitVertically( tableCell: Element, columnIndex: number, splitColumn: number, writer: Writer ): Element {\n\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) as string );\n\tconst newColspan = splitColumn - columnIndex;\n\n\tconst newCellAttributes: CellAttributes = {};\n\tconst newCellColSpan = colspan - newColspan;\n\n\tif ( newCellColSpan > 1 ) {\n\t\tnewCellAttributes.colspan = newCellColSpan;\n\t}\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) as string || '1' );\n\n\tif ( rowspan > 1 ) {\n\t\tnewCellAttributes.rowspan = rowspan;\n\t}\n\n\tconst newCell = createEmptyTableCell( writer, writer.createPositionAfter( tableCell ), newCellAttributes );\n\n\t// Update the colspan attribute after updating table.\n\tupdateNumericAttribute( 'colspan', newColspan, tableCell, writer );\n\n\treturn newCell;\n}\n\n/**\n * Adjusts table cell dimensions to not exceed limit row and column.\n *\n * If table cell width (or height) covers a column (or row) that is after a limit column (or row)\n * this method will trim \"colspan\" (or \"rowspan\") attribute so the table cell will fit in a defined limits.\n */\nexport function trimTableCellIfNeeded(\n\ttableCell: Element,\n\tcellRow: number,\n\tcellColumn: number,\n\tlimitRow: number,\n\tlimitColumn: number,\n\twriter: Writer\n): void {\n\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) as string || '1' );\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) as string || '1' );\n\n\tconst endColumn = cellColumn + colspan - 1;\n\n\tif ( endColumn > limitColumn ) {\n\t\tconst trimmedSpan = limitColumn - cellColumn + 1;\n\n\t\tupdateNumericAttribute( 'colspan', trimmedSpan, tableCell, writer, 1 );\n\t}\n\n\tconst endRow = cellRow + rowspan - 1;\n\n\tif ( endRow > limitRow ) {\n\t\tconst trimmedSpan = limitRow - cellRow + 1;\n\n\t\tupdateNumericAttribute( 'rowspan', trimmedSpan, tableCell, writer, 1 );\n\t}\n}\n\n/**\n * Sets proper heading attributes to a cropped table.\n */\nfunction addHeadingsToCroppedTable( croppedTable: Element, sourceTable: Element, startRow: number, startColumn: number, writer: Writer ) {\n\tconst headingRows = parseInt( sourceTable.getAttribute( 'headingRows' ) as string || '0' );\n\n\tif ( headingRows > 0 ) {\n\t\tconst headingRowsInCrop = headingRows - startRow;\n\t\tupdateNumericAttribute( 'headingRows', headingRowsInCrop, croppedTable, writer, 0 );\n\t}\n\n\tconst headingColumns = parseInt( sourceTable.getAttribute( 'headingColumns' ) as string || '0' );\n\n\tif ( headingColumns > 0 ) {\n\t\tconst headingColumnsInCrop = headingColumns - startColumn;\n\t\tupdateNumericAttribute( 'headingColumns', headingColumnsInCrop, croppedTable, writer, 0 );\n\t}\n}\n\n/**\n * Removes columns that have no cells anchored.\n *\n * In table below:\n *\n *     +----+----+----+----+----+----+----+\n *     | 00 | 01      | 03 | 04      | 06 |\n *     +----+----+----+----+         +----+\n *     | 10 | 11      | 13 |         | 16 |\n *     +----+----+----+----+----+----+----+\n *     | 20 | 21      | 23 | 24      | 26 |\n *     +----+----+----+----+----+----+----+\n *                  ^--- empty ---^\n *\n * Will remove columns 2 and 5.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a column from a table use {@link module:table/tableutils~TableUtils#removeColumns `TableUtils.removeColumns()`}.\n *\n * @internal\n * @returns True if removed some columns.\n */\nexport function removeEmptyColumns( table: Element, tableUtils: TableUtils ): boolean {\n\tconst width = tableUtils.getColumns( table );\n\tconst columnsMap = new Array( width ).fill( 0 );\n\n\tfor ( const { column } of new TableWalker( table ) ) {\n\t\tcolumnsMap[ column ]++;\n\t}\n\n\tconst emptyColumns = columnsMap.reduce( ( result, cellsCount, column ) => {\n\t\treturn cellsCount ? result : [ ...result, column ];\n\t}, [] );\n\n\tif ( emptyColumns.length > 0 ) {\n\t\t// Remove only last empty column because it will recurrently trigger removing empty rows.\n\t\tconst emptyColumn = emptyColumns[ emptyColumns.length - 1 ];\n\n\t\t// @if CK_DEBUG_TABLE // console.log( `Removing empty column: ${ emptyColumn }.` );\n\t\ttableUtils.removeColumns( table, { at: emptyColumn } );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Removes rows that have no cells anchored.\n *\n * In table below:\n *\n *     +----+----+----+\n *     | 00 | 01 | 02 |\n *     +----+----+----+\n *     | 10 | 11 | 12 |\n *     +    +    +    +\n *     |    |    |    | <-- empty\n *     +----+----+----+\n *     | 30 | 31 | 32 |\n *     +----+----+----+\n *     | 40      | 42 |\n *     +         +    +\n *     |         |    | <-- empty\n *     +----+----+----+\n *     | 60 | 61 | 62 |\n *     +----+----+----+\n *\n * Will remove rows 2 and 5.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a row from a table use {@link module:table/tableutils~TableUtils#removeRows `TableUtils.removeRows()`}.\n *\n * @internal\n * @returns True if removed some rows.\n */\nexport function removeEmptyRows( table: Element, tableUtils: TableUtils ): boolean {\n\tconst emptyRows = [];\n\tconst tableRowCount = tableUtils.getRows( table );\n\n\tfor ( let rowIndex = 0; rowIndex < tableRowCount; rowIndex++ ) {\n\t\tconst tableRow = table.getChild( rowIndex ) as Element;\n\n\t\tif ( tableRow.isEmpty ) {\n\t\t\temptyRows.push( rowIndex );\n\t\t}\n\t}\n\n\tif ( emptyRows.length > 0 ) {\n\t\t// Remove only last empty row because it will recurrently trigger removing empty columns.\n\t\tconst emptyRow = emptyRows[ emptyRows.length - 1 ];\n\n\t\t// @if CK_DEBUG_TABLE // console.log( `Removing empty row: ${ emptyRow }.` );\n\t\ttableUtils.removeRows( table, { at: emptyRow } );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Removes rows and columns that have no cells anchored.\n *\n * In table below:\n *\n *     +----+----+----+----+\n *     | 00      | 02      |\n *     +----+----+         +\n *     | 10      |         |\n *     +----+----+----+----+\n *     | 20      | 22 | 23 |\n *     +         +    +    +\n *     |         |    |    | <-- empty row\n *     +----+----+----+----+\n *             ^--- empty column\n *\n * Will remove row 3 and column 1.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a rows from a table use {@link module:table/tableutils~TableUtils#removeRows `TableUtils.removeRows()`} and\n * {@link module:table/tableutils~TableUtils#removeColumns `TableUtils.removeColumns()`} to remove a column.\n *\n * @internal\n */\nexport function removeEmptyRowsColumns( table: Element, tableUtils: TableUtils ): void {\n\tconst removedColumns = removeEmptyColumns( table, tableUtils );\n\n\t// If there was some columns removed then cleaning empty rows was already triggered.\n\tif ( !removedColumns ) {\n\t\tremoveEmptyRows( table, tableUtils );\n\t}\n}\n\n/**\n * Returns adjusted last row index if selection covers part of a row with empty slots (spanned by other cells).\n * The `dimensions.lastRow` is equal to last row index but selection might be bigger.\n *\n * This happens *only* on rectangular selection so we analyze a case like this:\n *\n *        +---+---+---+---+\n *      0 | a | b | c | d |\n *        +   +   +---+---+\n *      1 |   | e | f | g |\n *        +   +---+   +---+\n *      2 |   | h |   | i | <- last row, each cell has rowspan = 2,\n *        +   +   +   +   +    so we need to return 3, not 2\n *      3 |   |   |   |   |\n *        +---+---+---+---+\n *\n * @returns Adjusted last row index.\n */\nexport function adjustLastRowIndex(\n\ttable: Element,\n\tdimensions: {\n\t\tfirstRow: number;\n\t\tfirstColumn: number;\n\t\tlastRow: number;\n\t\tlastColumn: number;\n\t}\n): number {\n\tconst lastRowMap = Array.from( new TableWalker( table, {\n\t\tstartColumn: dimensions.firstColumn,\n\t\tendColumn: dimensions.lastColumn,\n\t\trow: dimensions.lastRow\n\t} ) );\n\n\tconst everyCellHasSingleRowspan = lastRowMap.every( ( { cellHeight } ) => cellHeight === 1 );\n\n\t// It is a \"flat\" row, so the last row index is OK.\n\tif ( everyCellHasSingleRowspan ) {\n\t\treturn dimensions.lastRow;\n\t}\n\n\t// Otherwise get any cell's rowspan and adjust the last row index.\n\tconst rowspanAdjustment = lastRowMap[ 0 ].cellHeight - 1;\n\treturn dimensions.lastRow + rowspanAdjustment;\n}\n\n/**\n * Returns adjusted last column index if selection covers part of a column with empty slots (spanned by other cells).\n * The `dimensions.lastColumn` is equal to last column index but selection might be bigger.\n *\n * This happens *only* on rectangular selection so we analyze a case like this:\n *\n *       0   1   2   3\n *     +---+---+---+---+\n *     | a             |\n *     +---+---+---+---+\n *     | b | c | d     |\n *     +---+---+---+---+\n *     | e     | f     |\n *     +---+---+---+---+\n *     | g | h         |\n *     +---+---+---+---+\n *               ^\n *              last column, each cell has colspan = 2, so we need to return 3, not 2\n *\n * @returns Adjusted last column index.\n */\nexport function adjustLastColumnIndex(\n\ttable: Element,\n\tdimensions: {\n\t\tfirstRow: number;\n\t\tfirstColumn: number;\n\t\tlastRow: number;\n\t\tlastColumn: number;\n\t}\n): number {\n\tconst lastColumnMap = Array.from( new TableWalker( table, {\n\t\tstartRow: dimensions.firstRow,\n\t\tendRow: dimensions.lastRow,\n\t\tcolumn: dimensions.lastColumn\n\t} ) );\n\n\tconst everyCellHasSingleColspan = lastColumnMap.every( ( { cellWidth } ) => cellWidth === 1 );\n\n\t// It is a \"flat\" column, so the last column index is OK.\n\tif ( everyCellHasSingleColspan ) {\n\t\treturn dimensions.lastColumn;\n\t}\n\n\t// Otherwise get any cell's colspan and adjust the last column index.\n\tconst colspanAdjustment = lastColumnMap[ 0 ].cellWidth - 1;\n\treturn dimensions.lastColumn + colspanAdjustment;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/mergecellcommand\n */\n\nimport type {\n\tElement,\n\tNode,\n\tWriter\n} from 'ckeditor5/src/engine.js';\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport TableWalker from '../tablewalker.js';\nimport { isHeadingColumnCell } from '../utils/common.js';\nimport { removeEmptyRowsColumns } from '../utils/structure.js';\nimport type { ArrowKeyCodeDirection } from 'ckeditor5/src/utils.js';\n\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The merge cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'mergeTableCellRight'`, `'mergeTableCellLeft'`,\n * `'mergeTableCellUp'` and `'mergeTableCellDown'` editor commands.\n *\n * To merge a table cell at the current selection with another cell, execute the command corresponding with the preferred direction.\n *\n * For example, to merge with a cell to the right:\n *\n * ```ts\n * editor.execute( 'mergeTableCellRight' );\n * ```\n *\n * **Note**: If a table cell has a different [`rowspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-rowspan)\n * (for `'mergeTableCellRight'` and `'mergeTableCellLeft'`) or [`colspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-colspan)\n * (for `'mergeTableCellUp'` and `'mergeTableCellDown'`), the command will be disabled.\n */\nexport default class MergeCellCommand extends Command {\n\t/**\n\t * The direction that indicates which cell will be merged with the currently selected one.\n\t */\n\tpublic readonly direction: ArrowKeyCodeDirection;\n\n\t/**\n\t * Whether the merge is horizontal (left/right) or vertical (up/down).\n\t */\n\tpublic readonly isHorizontal: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic declare value: Node | undefined;\n\n\t/**\n\t * Creates a new `MergeCellCommand` instance.\n\t *\n\t * @param editor The editor on which this command will be used.\n\t * @param options.direction Indicates which cell to merge with the currently selected one.\n\t * Possible values are: `'left'`, `'right'`, `'up'` and `'down'`.\n\t */\n\tconstructor( editor: Editor, options: { direction: ArrowKeyCodeDirection } ) {\n\t\tsuper( editor );\n\n\t\tthis.direction = options.direction;\n\t\tthis.isHorizontal = this.direction == 'right' || this.direction == 'left';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst cellToMerge = this._getMergeableCell();\n\n\t\tthis.value = cellToMerge;\n\t\tthis.isEnabled = !!cellToMerge;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #direction} value, it will merge the cell that is to the `'left'`, `'right'`, `'up'` or `'down'`.\n\t *\n\t * @fires execute\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst tableCell = tableUtils.getTableCellsContainingSelection( doc.selection )[ 0 ];\n\n\t\tconst cellToMerge = this.value!;\n\t\tconst direction = this.direction;\n\n\t\tmodel.change( writer => {\n\t\t\tconst isMergeNext = direction == 'right' || direction == 'down';\n\n\t\t\t// The merge mechanism is always the same so sort cells to be merged.\n\t\t\tconst cellToExpand = ( isMergeNext ? tableCell : cellToMerge ) as Element;\n\t\t\tconst cellToRemove = ( isMergeNext ? cellToMerge : tableCell ) as Element;\n\n\t\t\t// Cache the parent of cell to remove for later check.\n\t\t\tconst removedTableCellRow = cellToRemove.parent as Element;\n\n\t\t\tmergeTableCells( cellToRemove, cellToExpand, writer );\n\n\t\t\tconst spanAttribute = this.isHorizontal ? 'colspan' : 'rowspan';\n\t\t\tconst cellSpan = parseInt( tableCell.getAttribute( spanAttribute ) as string || '1' );\n\t\t\tconst cellToMergeSpan = parseInt( cellToMerge.getAttribute( spanAttribute ) as string || '1' );\n\n\t\t\t// Update table cell span attribute and merge set selection on merged contents.\n\t\t\twriter.setAttribute( spanAttribute, cellSpan + cellToMergeSpan, cellToExpand );\n\t\t\twriter.setSelection( writer.createRangeIn( cellToExpand ) );\n\n\t\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\t\tconst table = removedTableCellRow.findAncestor( 'table' )!;\n\n\t\t\t// Remove empty rows and columns after merging.\n\t\t\tremoveEmptyRowsColumns( table, tableUtils );\n\t\t} );\n\t}\n\n\t/**\n\t * Returns a cell that can be merged with the current cell depending on the command's direction.\n\t */\n\tprivate _getMergeableCell(): Node | undefined {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst tableCell = tableUtils.getTableCellsContainingSelection( doc.selection )[ 0 ];\n\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// First get the cell on proper direction.\n\t\tconst cellToMerge = this.isHorizontal ?\n\t\t\tgetHorizontalCell( tableCell, this.direction, tableUtils ) :\n\t\t\tgetVerticalCell( tableCell, this.direction, tableUtils );\n\n\t\tif ( !cellToMerge ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If found check if the span perpendicular to merge direction is equal on both cells.\n\t\tconst spanAttribute = this.isHorizontal ? 'rowspan' : 'colspan';\n\t\tconst span = parseInt( tableCell.getAttribute( spanAttribute ) as string || '1' );\n\n\t\tconst cellToMergeSpan = parseInt( cellToMerge.getAttribute( spanAttribute ) as string || '1' );\n\n\t\tif ( cellToMergeSpan === span ) {\n\t\t\treturn cellToMerge;\n\t\t}\n\t}\n}\n\n/**\n * Returns the cell that can be merged horizontally.\n */\nfunction getHorizontalCell( tableCell: Element, direction: ArrowKeyCodeDirection, tableUtils: TableUtils ) {\n\tconst tableRow = tableCell.parent!;\n\tconst table = tableRow.parent as Element;\n\tconst horizontalCell = direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;\n\tconst hasHeadingColumns = ( table.getAttribute( 'headingColumns' ) as number || 0 ) > 0;\n\n\tif ( !horizontalCell ) {\n\t\treturn;\n\t}\n\n\t// Sort cells:\n\tconst cellOnLeft = ( direction == 'right' ? tableCell : horizontalCell ) as Element;\n\tconst cellOnRight = ( direction == 'right' ? horizontalCell : tableCell ) as Element;\n\n\t// Get their column indexes:\n\tconst { column: leftCellColumn } = tableUtils.getCellLocation( cellOnLeft );\n\tconst { column: rightCellColumn } = tableUtils.getCellLocation( cellOnRight );\n\n\tconst leftCellSpan = parseInt( cellOnLeft.getAttribute( 'colspan' ) as string || '1' );\n\n\tconst isCellOnLeftInHeadingColumn = isHeadingColumnCell( tableUtils, cellOnLeft );\n\tconst isCellOnRightInHeadingColumn = isHeadingColumnCell( tableUtils, cellOnRight );\n\n\t// We cannot merge heading columns cells with regular cells.\n\tif ( hasHeadingColumns && isCellOnLeftInHeadingColumn != isCellOnRightInHeadingColumn ) {\n\t\treturn;\n\t}\n\n\t// The cell on the right must have index that is distant to the cell on the left by the left cell's width (colspan).\n\tconst cellsAreTouching = leftCellColumn + leftCellSpan === rightCellColumn;\n\n\t// If the right cell's column index is different it means that there are rowspanned cells between them.\n\treturn cellsAreTouching ? horizontalCell : undefined;\n}\n\n/**\n * Returns the cell that can be merged vertically.\n */\nfunction getVerticalCell( tableCell: Element, direction: ArrowKeyCodeDirection, tableUtils: TableUtils ): Node | null {\n\tconst tableRow = tableCell.parent as Element;\n\tconst table = tableRow.parent as Element;\n\n\tconst rowIndex = table.getChildIndex( tableRow )!;\n\n\t// Don't search for mergeable cell if direction points out of the table.\n\tif ( ( direction == 'down' && rowIndex === tableUtils.getRows( table ) - 1 ) || ( direction == 'up' && rowIndex === 0 ) ) {\n\t\treturn null;\n\t}\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) as string || '1' );\n\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\tconst isMergeWithBodyCell = direction == 'down' && ( rowIndex + rowspan ) === headingRows;\n\tconst isMergeWithHeadCell = direction == 'up' && rowIndex === headingRows;\n\n\t// Don't search for mergeable cell if direction points out of the current table section.\n\tif ( headingRows && ( isMergeWithBodyCell || isMergeWithHeadCell ) ) {\n\t\treturn null;\n\t}\n\n\tconst currentCellRowSpan = parseInt( tableCell.getAttribute( 'rowspan' ) as string || '1' );\n\tconst rowOfCellToMerge = direction == 'down' ? rowIndex + currentCellRowSpan : rowIndex;\n\n\tconst tableMap = [ ...new TableWalker( table, { endRow: rowOfCellToMerge } ) ];\n\n\tconst currentCellData = tableMap.find( value => value.cell === tableCell )!;\n\tconst mergeColumn = currentCellData.column;\n\n\tconst cellToMergeData = tableMap.find( ( { row, cellHeight, column } ) => {\n\t\tif ( column !== mergeColumn ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( direction == 'down' ) {\n\t\t\t// If merging a cell below the mergeRow is already calculated.\n\t\t\treturn row === rowOfCellToMerge;\n\t\t} else {\n\t\t\t// If merging a cell above calculate if it spans to mergeRow.\n\t\t\treturn rowOfCellToMerge === row + cellHeight;\n\t\t}\n\t} );\n\n\treturn cellToMergeData && cellToMergeData.cell ? cellToMergeData.cell : null;\n}\n\n/**\n * Merges two table cells. It will ensure that after merging cells with an empty paragraph, the resulting table cell will only have one\n * paragraph. If one of the merged table cells is empty, the merged table cell will have the contents of the non-empty table cell.\n * If both are empty, the merged table cell will have only one empty paragraph.\n */\nfunction mergeTableCells( cellToRemove: Element, cellToExpand: Element, writer: Writer ) {\n\tif ( !isEmpty( cellToRemove ) ) {\n\t\tif ( isEmpty( cellToExpand ) ) {\n\t\t\twriter.remove( writer.createRangeIn( cellToExpand ) );\n\t\t}\n\n\t\twriter.move( writer.createRangeIn( cellToRemove ), writer.createPositionAt( cellToExpand, 'end' ) );\n\t}\n\n\t// Remove merged table cell.\n\twriter.remove( cellToRemove );\n}\n\n/**\n * Checks if the passed table cell contains an empty paragraph.\n */\nfunction isEmpty( tableCell: Element ): boolean {\n\tconst firstTableChild = tableCell.getChild( 0 ) as Element;\n\n\treturn tableCell.childCount == 1 && firstTableChild.is( 'element', 'paragraph' ) && firstTableChild.isEmpty;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/removerowcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport type { Element, Node } from 'ckeditor5/src/engine.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The remove row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableRow'` editor command.\n *\n * To remove the row containing the selected cell, execute the command:\n *\n * ```ts\n * editor.execute( 'removeTableRow' );\n * ```\n */\nexport default class RemoveRowCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( this.editor.model.document.selection );\n\t\tconst firstCell = selectedCells[ 0 ];\n\n\t\tif ( firstCell ) {\n\t\t\tconst table = firstCell.findAncestor( 'table' )!;\n\t\t\tconst tableRowCount = tableUtils.getRows( table );\n\t\t\tconst lastRowIndex = tableRowCount - 1;\n\n\t\t\tconst selectedRowIndexes = tableUtils.getRowIndexes( selectedCells );\n\n\t\t\tconst areAllRowsSelected = selectedRowIndexes.first === 0 && selectedRowIndexes.last === lastRowIndex;\n\n\t\t\t// Disallow selecting whole table -> delete whole table should be used instead.\n\t\t\tthis.isEnabled = !areAllRowsSelected;\n\t\t} else {\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tconst referenceCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst removedRowIndexes = tableUtils.getRowIndexes( referenceCells );\n\n\t\tconst firstCell = referenceCells[ 0 ];\n\t\tconst table = firstCell.findAncestor( 'table' )!;\n\n\t\tconst columnIndexToFocus = tableUtils.getCellLocation( firstCell ).column;\n\n\t\tmodel.change( writer => {\n\t\t\tconst rowsToRemove = removedRowIndexes.last - removedRowIndexes.first + 1;\n\n\t\t\ttableUtils.removeRows( table, {\n\t\t\t\tat: removedRowIndexes.first,\n\t\t\t\trows: rowsToRemove\n\t\t\t} );\n\n\t\t\tconst cellToFocus = getCellToFocus( table, removedRowIndexes.first, columnIndexToFocus, tableUtils.getRows( table ) );\n\n\t\t\twriter.setSelection( writer.createPositionAt( cellToFocus, 0 ) );\n\t\t} );\n\t}\n}\n\n/**\n * Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.\n * - If the row was not the last one, the cell to focus will be in the row that followed it (before removal).\n * - If the row was the last one, the cell to focus will be in the row that preceded it (before removal).\n */\nfunction getCellToFocus( table: Element, removedRowIndex: number, columnToFocus: number, tableRowCount: number ): Node {\n\t// Don't go beyond last row's index.\n\tconst row = table.getChild( Math.min( removedRowIndex, tableRowCount - 1 ) ) as Element;\n\n\t// Default to first table cell.\n\tlet cellToFocus = row.getChild( 0 )!;\n\tlet column = 0;\n\n\tfor ( const tableCell of row.getChildren() ) {\n\t\tif ( column > columnToFocus ) {\n\t\t\treturn cellToFocus;\n\t\t}\n\n\t\tcellToFocus = tableCell;\n\t\tcolumn += parseInt( tableCell.getAttribute( 'colspan' ) as string || '1' );\n\t}\n\n\treturn cellToFocus;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/removecolumncommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport type {\n\tDocumentSelection,\n\tElement,\n\tSelection\n} from 'ckeditor5/src/engine.js';\n\nimport TableWalker, { type TableSlot } from '../tablewalker.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The remove column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableColumn'` editor command.\n *\n * To remove the column containing the selected cell, execute the command:\n *\n * ```ts\n * editor.execute( 'removeTableColumn' );\n * ```\n */\nexport default class RemoveColumnCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( this.editor.model.document.selection );\n\t\tconst firstCell = selectedCells[ 0 ];\n\n\t\tif ( firstCell ) {\n\t\t\tconst table = firstCell.findAncestor( 'table' )!;\n\t\t\tconst tableColumnCount = tableUtils.getColumns( table );\n\n\t\t\tconst { first, last } = tableUtils.getColumnIndexes( selectedCells );\n\n\t\t\tthis.isEnabled = last - first < ( tableColumnCount - 1 );\n\t\t} else {\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst [ firstCell, lastCell ] = getBoundaryCells( this.editor.model.document.selection, tableUtils );\n\t\tconst table = firstCell.parent!.parent as Element;\n\n\t\t// Cache the table before removing or updating colspans.\n\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\t// Store column indexes of removed columns.\n\t\tconst removedColumnIndexes = {\n\t\t\tfirst: tableMap.find( value => value.cell === firstCell )!.column,\n\t\t\tlast: tableMap.find( value => value.cell === lastCell )!.column\n\t\t};\n\n\t\tconst cellToFocus = getCellToFocus( tableMap, firstCell, lastCell, removedColumnIndexes )!;\n\n\t\tthis.editor.model.change( writer => {\n\t\t\tconst columnsToRemove = removedColumnIndexes.last - removedColumnIndexes.first + 1;\n\n\t\t\ttableUtils.removeColumns( table, {\n\t\t\t\tat: removedColumnIndexes.first,\n\t\t\t\tcolumns: columnsToRemove\n\t\t\t} );\n\n\t\t\twriter.setSelection( writer.createPositionAt( cellToFocus, 0 ) );\n\t\t} );\n\t}\n}\n\n/**\n * Returns a proper table cell to focus after removing a column.\n * - selection is on last table cell it will return previous cell.\n */\nfunction getCellToFocus(\n\ttableMap: Array<TableSlot>,\n\tfirstCell: Element,\n\tlastCell: Element,\n\tremovedColumnIndexes: {\n\t\tfirst: number;\n\t\tlast: number;\n\t}\n) {\n\tconst colspan = parseInt( lastCell.getAttribute( 'colspan' ) as string || '1' );\n\n\t// If the table cell is spanned over 2+ columns - it will be truncated so the selection should\n\t// stay in that cell.\n\tif ( colspan > 1 ) {\n\t\treturn lastCell;\n\t}\n\t// Normally, look for the cell in the same row that precedes the first cell to put selection there (\"column on the left\").\n\t// If the deleted column is the first column of the table, there will be no predecessor: use the cell\n\t// from the column that follows then (also in the same row).\n\telse if ( firstCell.previousSibling || lastCell.nextSibling ) {\n\t\treturn lastCell.nextSibling || firstCell.previousSibling;\n\t}\n\t// It can happen that table cells have no siblings in a row, for instance, when there are row spans\n\t// in the table (in the previous row). Then just look for the closest cell that is in a column\n\t// that will not be removed to put the selection there.\n\telse {\n\t\t// Look for any cell in a column that precedes the first removed column.\n\t\tif ( removedColumnIndexes.first ) {\n\t\t\treturn tableMap.reverse().find( ( { column } ) => {\n\t\t\t\treturn column < removedColumnIndexes.first;\n\t\t\t} )!.cell;\n\t\t}\n\t\t// If the first removed column is the first column of the table, then\n\t\t// look for any cell that is in a column that follows the last removed column.\n\t\telse {\n\t\t\treturn tableMap.reverse().find( ( { column } ) => {\n\t\t\t\treturn column > removedColumnIndexes.last;\n\t\t\t} )!.cell;\n\t\t}\n\t}\n}\n\n/**\n * Returns helper object returning the first and the last cell contained in given selection, based on DOM order.\n */\nfunction getBoundaryCells( selection: Selection | DocumentSelection, tableUtils: TableUtils ) {\n\tconst referenceCells = tableUtils.getSelectionAffectedTableCells( selection );\n\tconst firstCell = referenceCells[ 0 ];\n\tconst lastCell = referenceCells.pop()!;\n\n\tconst returnValue = [ firstCell, lastCell ];\n\n\treturn firstCell.isBefore( lastCell ) ? returnValue : returnValue.reverse();\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/setheaderrowcommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport type TableUtils from '../tableutils.js';\n\nimport { updateNumericAttribute } from '../utils/common.js';\nimport { getVerticallyOverlappingCells, splitHorizontally } from '../utils/structure.js';\n\n/**\n * The header row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.\n *\n * You can make the row containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element) by executing:\n *\n * ```ts\n * editor.execute( 'setTableRowHeader' );\n * ```\n *\n * **Note:** All preceding rows will also become headers. If the current row is already a header, executing this command\n * will make it a regular row back again (including the following rows).\n */\nexport default class SetHeaderRowCommand extends Command {\n\t/**\n\t * Flag indicating whether the command is active. The command is active when the\n\t * {@link module:engine/model/selection~Selection} is in a header row.\n\t *\n\t * @observable\n\t */\n\tpublic declare value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst model = this.editor.model;\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst isInTable = selectedCells.length > 0;\n\n\t\tthis.isEnabled = isInTable;\n\t\tthis.value = isInTable && selectedCells.every( cell => this._isInHeading( cell, cell.parent!.parent as Element ) );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header row, the command will set the `headingRows` table attribute to cover that row.\n\t *\n\t * When the selection is already in a header row, it will set `headingRows` so the heading section will end before that row.\n\t *\n\t * @fires execute\n\t * @param options.forceValue If set, the command will set (`true`) or unset (`false`) the header rows according to\n\t * the `forceValue` parameter instead of the current model state.\n\t */\n\tpublic override execute( options: { forceValue?: boolean } = {} ): void {\n\t\tif ( options.forceValue === this.value ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst model = this.editor.model;\n\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst table = selectedCells[ 0 ].findAncestor( 'table' )!;\n\n\t\tconst { first, last } = tableUtils.getRowIndexes( selectedCells );\n\t\tconst headingRowsToSet = this.value ? first : last + 1;\n\t\tconst currentHeadingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( headingRowsToSet ) {\n\t\t\t\t// Changing heading rows requires to check if any of a heading cell is overlapping vertically the table head.\n\t\t\t\t// Any table cell that has a rowspan attribute > 1 will not exceed the table head so we need to fix it in rows below.\n\t\t\t\tconst startRow = headingRowsToSet > currentHeadingRows ? currentHeadingRows : 0;\n\t\t\t\tconst overlappingCells = getVerticallyOverlappingCells( table, headingRowsToSet, startRow );\n\n\t\t\t\tfor ( const { cell } of overlappingCells ) {\n\t\t\t\t\tsplitHorizontally( cell, headingRowsToSet, writer );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tupdateNumericAttribute( 'headingRows', headingRowsToSet, table, writer, 0 );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if a table cell is in the heading section.\n\t */\n\tprivate _isInHeading( tableCell: Element, table: Element ): boolean {\n\t\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) as string || '0' );\n\n\t\treturn !!headingRows && ( tableCell.parent as Element ).index! < headingRows;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/setheadercolumncommand\n */\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport type TableUtils from '../tableutils.js';\n\nimport {\n\tisHeadingColumnCell,\n\tupdateNumericAttribute\n} from '../utils/common.js';\nimport { getHorizontallyOverlappingCells, splitVertically } from '../utils/structure.js';\n\n/**\n * The header column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.\n *\n * You can make the column containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element)\n * by executing:\n *\n * ```ts\n * editor.execute( 'setTableColumnHeader' );\n * ```\n *\n * **Note:** All preceding columns will also become headers. If the current column is already a header, executing this command\n * will make it a regular column back again (including the following columns).\n */\nexport default class SetHeaderColumnCommand extends Command {\n\t/**\n\t * Flag indicating whether the command is active. The command is active when the\n\t * {@link module:engine/model/selection~Selection} is in a header column.\n\t *\n\t * @observable\n\t */\n\tpublic declare value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst isInTable = selectedCells.length > 0;\n\n\t\tthis.isEnabled = isInTable;\n\t\tthis.value = isInTable && selectedCells.every( cell => isHeadingColumnCell( tableUtils, cell ) );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header column, the command will set the `headingColumns` table attribute to cover that column.\n\t *\n\t * When the selection is already in a header column, it will set `headingColumns` so the heading section will end before that column.\n\t *\n\t * @fires execute\n\t * @param options.forceValue If set, the command will set (`true`) or unset (`false`) the header columns according to\n\t * the `forceValue` parameter instead of the current model state.\n\t */\n\tpublic override execute( options: { forceValue?: boolean } = {} ): void {\n\t\tif ( options.forceValue === this.value ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst model = this.editor.model;\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst table = selectedCells[ 0 ].findAncestor( 'table' )!;\n\n\t\tconst { first, last } = tableUtils.getColumnIndexes( selectedCells );\n\t\tconst headingColumnsToSet = this.value ? first : last + 1;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( headingColumnsToSet ) {\n\t\t\t\t// Changing heading columns requires to check if any of a heading cell is overlapping horizontally the table head.\n\t\t\t\t// Any table cell that has a colspan attribute > 1 will not exceed the table head so we need to fix it in columns before.\n\t\t\t\tconst overlappingCells = getHorizontallyOverlappingCells( table, headingColumnsToSet );\n\n\t\t\t\tfor ( const { cell, column } of overlappingCells ) {\n\t\t\t\t\tsplitVertically( cell, column, headingColumnsToSet, writer );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tupdateNumericAttribute( 'headingColumns', headingColumnsToSet, table, writer, 0 );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecolumnresize/constants\n */\n\n/**\n * The minimum column width given as a percentage value. Used in situations when the table is not yet rendered, so it is impossible to\n * calculate how many percentage of the table width would be {@link ~COLUMN_MIN_WIDTH_IN_PIXELS minimum column width in pixels}.\n */\nexport const COLUMN_MIN_WIDTH_AS_PERCENTAGE = 5;\n\n/**\n * The minimum column width in pixels when the maximum table width is known.\n */\nexport const COLUMN_MIN_WIDTH_IN_PIXELS = 40;\n\n/**\n * Determines how many digits after the decimal point are used to store the column width as a percentage value.\n */\nexport const COLUMN_WIDTH_PRECISION = 2;\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecolumnresize/utils\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport type { Element, Model, ViewElement, ViewNode, Writer } from 'ckeditor5/src/engine.js';\nimport { global } from 'ckeditor5/src/utils.js';\nimport type TableUtils from '../tableutils.js';\nimport {\n\tCOLUMN_WIDTH_PRECISION,\n\tCOLUMN_MIN_WIDTH_AS_PERCENTAGE,\n\tCOLUMN_MIN_WIDTH_IN_PIXELS\n} from './constants.js';\n\n/**\n * Returns all the inserted or changed table model elements in a given change set. Only the tables\n * with 'columnsWidth' attribute are taken into account. The returned set may be empty.\n *\n * Most notably if an entire table is removed it will not be included in returned set.\n *\n * @param model The model to collect the affected elements from.\n * @returns A set of table model elements.\n */\nexport function getChangedResizedTables( model: Model ): Set<Element> {\n\tconst affectedTables: Set<Element> = new Set();\n\n\tfor ( const change of model.document.differ.getChanges() ) {\n\t\tlet referencePosition = null;\n\n\t\t// Checks if the particular change from the differ is:\n\t\t// - an insertion or removal of a table, a row or a cell,\n\t\t// - an attribute change on a table, a row or a cell.\n\t\tswitch ( change.type ) {\n\t\t\tcase 'insert':\n\t\t\t\treferencePosition = [ 'table', 'tableRow', 'tableCell' ].includes( change.name ) ?\n\t\t\t\t\tchange.position :\n\t\t\t\t\tnull;\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'remove':\n\t\t\t\t// If the whole table is removed, there's no need to update its column widths (#12201).\n\t\t\t\treferencePosition = [ 'tableRow', 'tableCell' ].includes( change.name ) ?\n\t\t\t\t\tchange.position :\n\t\t\t\t\tnull;\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'attribute':\n\t\t\t\tif ( change.range.start.nodeAfter ) {\n\t\t\t\t\treferencePosition = [ 'table', 'tableRow', 'tableCell' ].includes( ( change.range.start.nodeAfter as Element ).name ) ?\n\t\t\t\t\t\tchange.range.start :\n\t\t\t\t\t\tnull;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( !referencePosition ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst tableNode = ( referencePosition.nodeAfter && referencePosition.nodeAfter.is( 'element', 'table' ) ) ?\n\t\t\treferencePosition.nodeAfter : referencePosition.findAncestor( 'table' )!;\n\n\t\t// We iterate over the whole table looking for the nested tables that are also affected.\n\t\tfor ( const node of model.createRangeOn( tableNode ).getItems() ) {\n\t\t\tif ( !node.is( 'element', 'table' ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !getColumnGroupElement( node ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\taffectedTables.add( node );\n\t\t}\n\t}\n\n\treturn affectedTables;\n}\n\n/**\n * Calculates the percentage of the minimum column width given in pixels for a given table.\n *\n * @param modelTable A table model element.\n * @param editor The editor instance.\n * @returns The minimal column width in percentage.\n */\nexport function getColumnMinWidthAsPercentage( modelTable: Element, editor: Editor ): number {\n\treturn COLUMN_MIN_WIDTH_IN_PIXELS * 100 / getTableWidthInPixels( modelTable, editor );\n}\n\n/**\n * Calculates the table width in pixels.\n *\n * @param modelTable A table model element.\n * @param editor The editor instance.\n * @returns The width of the table in pixels.\n */\nexport function getTableWidthInPixels( modelTable: Element, editor: Editor ): number {\n\t// It is possible for a table to not have a <tbody> element - see #11878.\n\tconst referenceElement = getChildrenViewElement( modelTable, 'tbody', editor ) || getChildrenViewElement( modelTable, 'thead', editor );\n\tconst domReferenceElement = editor.editing.view.domConverter.mapViewToDom( referenceElement! )!;\n\n\treturn getElementWidthInPixels( domReferenceElement );\n}\n\n/**\n * Returns the a view element with a given name that is nested directly in a `<table>` element\n * related to a given `modelTable`.\n *\n * @param elementName Name of a view to be looked for, e.g. `'colgroup`', `'thead`'.\n * @returns Matched view or `undefined` otherwise.\n */\nfunction getChildrenViewElement( modelTable: Element, elementName: string, editor: Editor ) {\n\tconst viewFigure = editor.editing.mapper.toViewElement( modelTable )!;\n\tconst viewTable = [ ...viewFigure.getChildren() ]\n\t\t.find( ( node: ViewNode ): node is ViewElement & { name: 'table' } => node.is( 'element', 'table' ) )!;\n\n\treturn [ ...viewTable.getChildren() ]\n\t\t.find( ( node: ViewNode ): node is ViewElement => node.is( 'element', elementName ) );\n}\n\n/**\n * Returns the computed width (in pixels) of the DOM element without padding and borders.\n *\n * @param domElement A DOM element.\n * @returns The width of the DOM element in pixels.\n */\nexport function getElementWidthInPixels( domElement: HTMLElement ): number {\n\tconst styles = global.window.getComputedStyle( domElement );\n\n\t// In the 'border-box' box sizing algorithm, the element's width\n\t// already includes the padding and border width (#12335).\n\tif ( styles.boxSizing === 'border-box' ) {\n\t\treturn parseFloat( styles.width ) -\n\t\t\tparseFloat( styles.paddingLeft ) -\n\t\t\tparseFloat( styles.paddingRight ) -\n\t\t\tparseFloat( styles.borderLeftWidth ) -\n\t\t\tparseFloat( styles.borderRightWidth );\n\t} else {\n\t\treturn parseFloat( styles.width );\n\t}\n}\n\n/**\n * Returns the column indexes on the left and right edges of a cell. They differ if the cell spans\n * across multiple columns.\n *\n * @param cell A table cell model element.\n * @param tableUtils The Table Utils plugin instance.\n * @returns An object containing the indexes of the left and right edges of the cell.\n */\nexport function getColumnEdgesIndexes( cell: Element, tableUtils: TableUtils ): { leftEdge: number; rightEdge: number } {\n\tconst cellColumnIndex = tableUtils.getCellLocation( cell ).column;\n\tconst cellWidth = cell.getAttribute( 'colspan' ) as number || 1;\n\n\treturn {\n\t\tleftEdge: cellColumnIndex,\n\t\trightEdge: cellColumnIndex + cellWidth - 1\n\t};\n}\n\n/**\n * Rounds the provided value to a fixed-point number with defined number of digits after the decimal point.\n *\n * @param value A number to be rounded.\n * @returns The rounded number.\n */\nexport function toPrecision( value: number | string ): number {\n\tconst multiplier = Math.pow( 10, COLUMN_WIDTH_PRECISION );\n\tconst number = typeof value === 'number' ? value : parseFloat( value );\n\n\treturn Math.round( number * multiplier ) / multiplier;\n}\n\n/**\n * Clamps the number within the inclusive lower (min) and upper (max) bounds. Returned number is rounded using the\n * {@link ~toPrecision `toPrecision()`} function.\n *\n * @param number A number to be clamped.\n * @param min A lower bound.\n * @param max An upper bound.\n * @returns The clamped number.\n */\nexport function clamp( number: number, min: number, max: number ): number {\n\tif ( number <= min ) {\n\t\treturn toPrecision( min );\n\t}\n\n\tif ( number >= max ) {\n\t\treturn toPrecision( max );\n\t}\n\n\treturn toPrecision( number );\n}\n\n/**\n * Creates an array with defined length and fills all elements with defined value.\n *\n * @param length The length of the array.\n * @param value The value to fill the array with.\n * @returns An array with defined length and filled with defined value.\n */\nexport function createFilledArray<T>( length: number, value: T ): Array<T> {\n\treturn Array( length ).fill( value );\n}\n\n/**\n * Sums all array values that can be parsed to a float.\n *\n * @param array An array of numbers.\n * @returns The sum of all array values.\n */\nexport function sumArray( array: Array<number | string> ): number {\n\treturn array\n\t\t.map( value => typeof value === 'number' ? value : parseFloat( value ) )\n\t\t.filter( value => !Number.isNaN( value ) )\n\t\t.reduce( ( result, item ) => result + item, 0 );\n}\n\n/**\n * Makes sure that the sum of the widths from all columns is 100%. If the sum of all the widths is not equal 100%, all the widths are\n * changed proportionally so that they all sum back to 100%. If there are columns without specified width, the amount remaining\n * after assigning the known widths will be distributed equally between them.\n *\n * @param columnWidths An array of column widths.\n * @returns An array of column widths guaranteed to sum up to 100%.\n */\nexport function normalizeColumnWidths( columnWidths: Array<string> ): Array<string> {\n\tconst widths: Array<number | 'auto'> = columnWidths.map( width => {\n\t\tif ( width === 'auto' ) {\n\t\t\treturn width;\n\t\t}\n\n\t\treturn parseFloat( width.replace( '%', '' ) );\n\t} );\n\n\tlet normalizedWidths: Array<number> = calculateMissingColumnWidths( widths );\n\tconst totalWidth = sumArray( normalizedWidths );\n\n\tif ( totalWidth !== 100 ) {\n\t\tnormalizedWidths = normalizedWidths\n\t\t\t// Adjust all the columns proportionally.\n\t\t\t.map( width => toPrecision( width * 100 / totalWidth ) )\n\t\t\t// Due to rounding of numbers it may happen that the sum of the widths of all columns will not be exactly 100%.\n\t\t\t// Therefore, the width of the last column is explicitly adjusted (narrowed or expanded), since all the columns\n\t\t\t// have been proportionally changed already.\n\t\t\t.map( ( columnWidth, columnIndex, width ) => {\n\t\t\t\tconst isLastColumn = columnIndex === width.length - 1;\n\n\t\t\t\tif ( !isLastColumn ) {\n\t\t\t\t\treturn columnWidth;\n\t\t\t\t}\n\n\t\t\t\tconst totalWidth = sumArray( width );\n\n\t\t\t\treturn toPrecision( columnWidth + 100 - totalWidth );\n\t\t\t} );\n\t}\n\n\treturn normalizedWidths.map( width => width + '%' );\n}\n\n/**\n * Initializes the column widths by parsing the attribute value and calculating the uninitialized column widths. The special value 'auto'\n * indicates that width for the column must be calculated. The width of such uninitialized column is calculated as follows:\n * - If there is enough free space in the table for all uninitialized columns to have at least the minimum allowed width for all of them,\n *   then set this width equally for all uninitialized columns.\n * - Otherwise, just set the minimum allowed width for all uninitialized columns. The sum of all column widths will be greater than 100%,\n *   but then it will be adjusted proportionally to 100% in {@link #normalizeColumnWidths `normalizeColumnWidths()`}.\n *\n * @param columnWidths An array of column widths.\n * @returns An array with 'auto' values replaced with calculated widths.\n */\nfunction calculateMissingColumnWidths( columnWidths: Array<number | string> ): Array<number> {\n\tconst numberOfUninitializedColumns = columnWidths.filter( columnWidth => columnWidth === 'auto' ).length;\n\n\tif ( numberOfUninitializedColumns === 0 ) {\n\t\treturn columnWidths.map( columnWidth => toPrecision( columnWidth ) );\n\t}\n\n\tconst totalWidthOfInitializedColumns = sumArray( columnWidths );\n\n\tconst widthForUninitializedColumn = Math.max(\n\t\t( 100 - totalWidthOfInitializedColumns ) / numberOfUninitializedColumns,\n\t\tCOLUMN_MIN_WIDTH_AS_PERCENTAGE\n\t);\n\n\treturn columnWidths\n\t\t.map( columnWidth => columnWidth === 'auto' ? widthForUninitializedColumn : columnWidth )\n\t\t.map( columnWidth => toPrecision( columnWidth ) );\n}\n\n/**\n * Calculates the total horizontal space taken by the cell. That includes:\n *  * width,\n *  * left and red padding,\n *  * border width.\n *\n * @param domCell A DOM cell element.\n * @returns Width in pixels without `px` at the end.\n */\nexport function getDomCellOuterWidth( domCell: HTMLElement ): number {\n\tconst styles = global.window.getComputedStyle( domCell );\n\n\t// In the 'border-box' box sizing algorithm, the element's width\n\t// already includes the padding and border width (#12335).\n\tif ( styles.boxSizing === 'border-box' ) {\n\t\treturn parseInt( styles.width );\n\t} else {\n\t\treturn parseFloat( styles.width ) +\n\t\t\tparseFloat( styles.paddingLeft ) +\n\t\t\tparseFloat( styles.paddingRight ) +\n\t\t\tparseFloat( styles.borderWidth );\n\t}\n}\n\n/**\n * Updates column elements to match columns widths.\n *\n * @param columns\n * @param tableColumnGroup\n * @param normalizedWidths\n * @param writer\n */\nexport function updateColumnElements(\n\tcolumns: Array<Element>,\n\ttableColumnGroup: Element,\n\tnormalizedWidths: Array<string>,\n\twriter: Writer\n): void {\n\tfor ( let i = 0; i < Math.max( normalizedWidths.length, columns.length ); i++ ) {\n\t\tconst column = columns[ i ];\n\t\tconst columnWidth = normalizedWidths[ i ];\n\n\t\tif ( !columnWidth ) {\n\t\t\t// Number of `<tableColumn>` elements exceeds actual number of columns.\n\t\t\twriter.remove( column );\n\t\t} else if ( !column ) {\n\t\t\t// There is fewer `<tableColumn>` elements than actual columns.\n\t\t\twriter.appendElement( 'tableColumn', { columnWidth }, tableColumnGroup );\n\t\t} else {\n\t\t\t// Update column width.\n\t\t\twriter.setAttribute( 'columnWidth', columnWidth, column );\n\t\t}\n\t}\n}\n\n/**\n * Returns a 'tableColumnGroup' element from the 'table'.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @returns A 'tableColumnGroup' element.\n */\nexport function getColumnGroupElement( element: Element ): Element {\n\tif ( element.is( 'element', 'tableColumnGroup' ) ) {\n\t\treturn element;\n\t}\n\n\tconst children = element.getChildren()!;\n\n\treturn Array\n\t\t.from( children )\n\t\t.find( element => element.is( 'element', 'tableColumnGroup' ) )! as Element;\n}\n\n/**\n * Returns an array of 'tableColumn' elements. It may be empty if there's no `tableColumnGroup` element.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @returns An array of 'tableColumn' elements.\n */\nexport function getTableColumnElements( element: Element ): Array<Element> {\n\tconst columnGroupElement = getColumnGroupElement( element );\n\n\tif ( !columnGroupElement ) {\n\t\treturn [];\n\t}\n\n\treturn Array.from( columnGroupElement.getChildren() as IterableIterator<Element> );\n}\n\n/**\n * Returns an array of table column widths.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @returns An array of table column widths.\n */\nexport function getTableColumnsWidths( element: Element ): Array<string> {\n\treturn getTableColumnElements( element ).map( column => column.getAttribute( 'columnWidth' ) as string );\n}\n\n/**\n * Translates the `colSpan` model attribute into additional column widths and returns the resulting array.\n *\n * @internal\n * @param element A 'table' or 'tableColumnGroup' element.\n * @param writer A writer instance.\n * @returns An array of table column widths.\n */\nexport function translateColSpanAttribute( element: Element, writer: Writer ): Array<string> {\n\tconst tableColumnElements = getTableColumnElements( element );\n\n\treturn tableColumnElements.reduce( ( acc: Array<string>, element ) => {\n\t\tconst columnWidth = element.getAttribute( 'columnWidth' ) as string;\n\t\tconst colSpan = element.getAttribute( 'colSpan' ) as number | undefined;\n\n\t\tif ( !colSpan ) {\n\t\t\tacc.push( columnWidth );\n\t\t\treturn acc;\n\t\t}\n\n\t\t// Translate the `colSpan` model attribute on to the proper number of column widths\n\t\t// and remove it from the element.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for more details.\n\t\tfor ( let i = 0; i < colSpan; i++ ) {\n\t\t\tacc.push( columnWidth );\n\t\t}\n\n\t\twriter.removeAttribute( 'colSpan', element );\n\n\t\treturn acc;\n\t}, [] );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableutils\n */\n\nimport { CKEditorError } from 'ckeditor5/src/utils.js';\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport type {\n\tDocumentSelection,\n\tElement,\n\tNode,\n\tPosition,\n\tRange,\n\tSelection,\n\tWriter\n} from 'ckeditor5/src/engine.js';\n\nimport TableWalker, { type TableWalkerOptions } from './tablewalker.js';\nimport { createEmptyTableCell, updateNumericAttribute } from './utils/common.js';\nimport { removeEmptyColumns, removeEmptyRows } from './utils/structure.js';\nimport { getTableColumnElements } from './tablecolumnresize/utils.js';\n\ntype Cell = { cell: Element; rowspan: number };\ntype CellsToMove = Map<number, Cell>;\ntype CellsToTrim = Array<Cell>;\n\ntype IndexesObject = { first: number; last: number };\n\n/**\n * The table utilities plugin.\n */\nexport default class TableUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableUtils' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tthis.decorate( 'insertColumns' );\n\t\tthis.decorate( 'insertRows' );\n\t}\n\n\t/**\n\t * Returns the table cell location as an object with table row and table column indexes.\n\t *\n\t * For instance, in the table below:\n\t *\n\t *      0   1   2   3\n\t *    +---+---+---+---+\n\t *  0 | a     | b | c |\n\t *    +       +   +---+\n\t *  1 |       |   | d |\n\t *    +---+---+   +---+\n\t *  2 | e     |   | f |\n\t *    +---+---+---+---+\n\t *\n\t * the method will return:\n\t *\n\t * ```ts\n\t * const cellA = table.getNodeByPath( [ 0, 0 ] );\n\t * editor.plugins.get( 'TableUtils' ).getCellLocation( cellA );\n\t * // will return { row: 0, column: 0 }\n\t *\n\t * const cellD = table.getNodeByPath( [ 1, 0 ] );\n\t * editor.plugins.get( 'TableUtils' ).getCellLocation( cellD );\n\t * // will return { row: 1, column: 3 }\n\t * ```\n\t *\n\t * @returns Returns a `{row, column}` object.\n\t */\n\tpublic getCellLocation( tableCell: Element ): { row: number; column: number } {\n\t\tconst tableRow = tableCell.parent!;\n\t\tconst table = tableRow.parent as Element;\n\n\t\tconst rowIndex = table.getChildIndex( tableRow as Node );\n\n\t\tconst tableWalker = new TableWalker( table, { row: rowIndex } );\n\n\t\tfor ( const { cell, row, column } of tableWalker ) {\n\t\t\tif ( cell === tableCell ) {\n\t\t\t\treturn { row, column };\n\t\t\t}\n\t\t}\n\n\t\t// Should be unreachable code.\n\t\t/* istanbul ignore next -- @preserve */\n\t\treturn undefined as any;\n\t}\n\n\t/**\n\t * Creates an empty table with a proper structure. The table needs to be inserted into the model,\n\t * for example, by using the {@link module:engine/model/model~Model#insertContent} function.\n\t *\n\t * ```ts\n\t * model.change( ( writer ) => {\n\t *   // Create a table of 2 rows and 7 columns:\n\t *   const table = tableUtils.createTable( writer, { rows: 2, columns: 7 } );\n\t *\n\t *   // Insert a table to the model at the best position taking the current selection:\n\t *   model.insertContent( table );\n\t * }\n\t * ```\n\t *\n\t * @param writer The model writer.\n\t * @param options.rows The number of rows to create. Default value is 2.\n\t * @param options.columns The number of columns to create. Default value is 2.\n\t * @param options.headingRows The number of heading rows. Default value is 0.\n\t * @param options.headingColumns The number of heading columns. Default value is 0.\n\t * @returns The created table element.\n\t */\n\tpublic createTable(\n\t\twriter: Writer,\n\t\toptions: {\n\t\t\trows?: number;\n\t\t\tcolumns?: number;\n\t\t\theadingRows?: number;\n\t\t\theadingColumns?: number;\n\t\t}\n\t): Element {\n\t\tconst table = writer.createElement( 'table' );\n\n\t\tconst rows = options.rows || 2;\n\t\tconst columns = options.columns || 2;\n\n\t\tcreateEmptyRows( writer, table, 0, rows, columns );\n\n\t\tif ( options.headingRows ) {\n\t\t\tupdateNumericAttribute( 'headingRows', Math.min( options.headingRows, rows ), table, writer, 0 );\n\t\t}\n\n\t\tif ( options.headingColumns ) {\n\t\t\tupdateNumericAttribute( 'headingColumns', Math.min( options.headingColumns, columns ), table, writer, 0 );\n\t\t}\n\n\t\treturn table;\n\t}\n\n\t/**\n\t * Inserts rows into a table.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).insertRows( table, { at: 1, rows: 2 } );\n\t * ```\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *  row index\n\t *    0 +---+---+---+       `at` = 1,      +---+---+---+ 0\n\t *      | a | b | c |       `rows` = 2,    | a | b | c |\n\t *    1 +   +---+---+   <-- insert here    +   +---+---+ 1\n\t *      |   | d | e |                      |   |   |   |\n\t *    2 +   +---+---+       will give:     +   +---+---+ 2\n\t *      |   | f | g |                      |   |   |   |\n\t *    3 +---+---+---+                      +   +---+---+ 3\n\t *                                         |   | d | e |\n\t *                                         +   +---+---+ 4\n\t *                                         +   + f | g |\n\t *                                         +---+---+---+ 5\n\t *\n\t * @param table The table model element where the rows will be inserted.\n\t * @param options.at The row index at which the rows will be inserted.  Default value is 0.\n\t * @param options.rows The number of rows to insert.  Default value is 1.\n\t * @param options.copyStructureFromAbove The flag for copying row structure. Note that\n\t * the row structure will not be copied if this option is not provided.\n\t */\n\tpublic insertRows( table: Element, options: { at?: number; rows?: number; copyStructureFromAbove?: boolean } = {} ): void {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst rowsToInsert = options.rows || 1;\n\t\tconst isCopyStructure = options.copyStructureFromAbove !== undefined;\n\t\tconst copyStructureFrom = options.copyStructureFromAbove ? insertAt - 1 : insertAt;\n\n\t\tconst rows = this.getRows( table );\n\t\tconst columns = this.getColumns( table );\n\n\t\tif ( insertAt > rows ) {\n\t\t\t/**\n\t\t\t * The `options.at` points at a row position that does not exist.\n\t\t\t *\n\t\t\t * @error tableutils-insertrows-insert-out-of-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'tableutils-insertrows-insert-out-of-range',\n\t\t\t\tthis,\n\t\t\t\t{ options }\n\t\t\t);\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\n\t\t\t// Inserting rows inside heading section requires to update `headingRows` attribute as the heading section will grow.\n\t\t\tif ( headingRows > insertAt ) {\n\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows + rowsToInsert, table, writer, 0 );\n\t\t\t}\n\n\t\t\t// Inserting at the end or at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( !isCopyStructure && ( insertAt === 0 || insertAt === rows ) ) {\n\t\t\t\tcreateEmptyRows( writer, table, insertAt, rowsToInsert, columns );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Iterate over all the rows above the inserted rows in order to check for the row-spanned cells.\n\t\t\tconst walkerEndRow = isCopyStructure ? Math.max( insertAt, copyStructureFrom ) : insertAt;\n\t\t\tconst tableIterator = new TableWalker( table, { endRow: walkerEndRow } );\n\n\t\t\t// Store spans of the reference row to reproduce it's structure. This array is column number indexed.\n\t\t\tconst rowColSpansMap = new Array( columns ).fill( 1 );\n\n\t\t\tfor ( const { row, column, cellHeight, cellWidth, cell } of tableIterator ) {\n\t\t\t\tconst lastCellRow = row + cellHeight - 1;\n\n\t\t\t\tconst isOverlappingInsertedRow = row < insertAt && insertAt <= lastCellRow;\n\t\t\t\tconst isReferenceRow = row <= copyStructureFrom && copyStructureFrom <= lastCellRow;\n\n\t\t\t\t// If the cell is row-spanned and overlaps the inserted row, then reserve space for it in the row map.\n\t\t\t\tif ( isOverlappingInsertedRow ) {\n\t\t\t\t\t// This cell overlaps the inserted rows so we need to expand it further.\n\t\t\t\t\twriter.setAttribute( 'rowspan', cellHeight + rowsToInsert, cell );\n\n\t\t\t\t\t// Mark this cell with negative number to indicate how many cells should be skipped when adding the new cells.\n\t\t\t\t\trowColSpansMap[ column ] = -cellWidth;\n\t\t\t\t}\n\t\t\t\t// Store the colspan from reference row.\n\t\t\t\telse if ( isCopyStructure && isReferenceRow ) {\n\t\t\t\t\trowColSpansMap[ column ] = cellWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( let rowIndex = 0; rowIndex < rowsToInsert; rowIndex++ ) {\n\t\t\t\tconst tableRow = writer.createElement( 'tableRow' );\n\n\t\t\t\twriter.insert( tableRow, table, insertAt );\n\n\t\t\t\tfor ( let cellIndex = 0; cellIndex < rowColSpansMap.length; cellIndex++ ) {\n\t\t\t\t\tconst colspan = rowColSpansMap[ cellIndex ];\n\t\t\t\t\tconst insertPosition = writer.createPositionAt( tableRow, 'end' );\n\n\t\t\t\t\t// Insert the empty cell only if this slot is not row-spanned from any other cell.\n\t\t\t\t\tif ( colspan > 0 ) {\n\t\t\t\t\t\tcreateEmptyTableCell( writer, insertPosition, colspan > 1 ? { colspan } : undefined );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Skip the col-spanned slots, there won't be any cells.\n\t\t\t\t\tcellIndex += Math.abs( colspan ) - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Inserts columns into a table.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).insertColumns( table, { at: 1, columns: 2 } );\n\t * ```\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *  0   1   2   3                   0   1   2   3   4   5\n\t *  +---+---+---+                   +---+---+---+---+---+\n\t *  | a     | b |                   | a             | b |\n\t *  +       +---+                   +               +---+\n\t *  |       | c |                   |               | c |\n\t *  +---+---+---+     will give:    +---+---+---+---+---+\n\t *  | d | e | f |                   | d |   |   | e | f |\n\t *  +---+   +---+                   +---+---+---+   +---+\n\t *  | g |   | h |                   | g |   |   |   | h |\n\t *  +---+---+---+                   +---+---+---+---+---+\n\t *  | i         |                   | i                 |\n\t *  +---+---+---+                   +---+---+---+---+---+\n\t *      ^---- insert here, `at` = 1, `columns` = 2\n\t *\n\t * @param table The table model element where the columns will be inserted.\n\t * @param options.at The column index at which the columns will be inserted. Default value is 0.\n\t * @param options.columns The number of columns to insert. Default value is 1.\n\t */\n\tpublic insertColumns( table: Element, options: { at?: number; columns?: number } = {} ): void {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst columnsToInsert = options.columns || 1;\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) as number;\n\n\t\t\t// Inserting columns inside heading section requires to update `headingColumns` attribute as the heading section will grow.\n\t\t\tif ( insertAt < headingColumns ) {\n\t\t\t\twriter.setAttribute( 'headingColumns', headingColumns + columnsToInsert, table );\n\t\t\t}\n\n\t\t\tconst tableColumns = this.getColumns( table );\n\n\t\t\t// Inserting at the end and at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( insertAt === 0 || tableColumns === insertAt ) {\n\t\t\t\tfor ( const tableRow of table.getChildren() ) {\n\t\t\t\t\t// Ignore non-row elements inside the table (e.g. caption).\n\t\t\t\t\tif ( !tableRow.is( 'element', 'tableRow' ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tcreateCells( columnsToInsert, writer, writer.createPositionAt( tableRow, insertAt ? 'end' : 0 ) );\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tableWalker = new TableWalker( table, { column: insertAt, includeAllSlots: true } );\n\n\t\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\t\tconst { row, cell, cellAnchorColumn, cellAnchorRow, cellWidth, cellHeight } = tableSlot;\n\n\t\t\t\t// When iterating over column the table walker outputs either:\n\t\t\t\t// - cells at given column index (cell \"e\" from method docs),\n\t\t\t\t// - spanned columns (spanned cell from row between cells \"g\" and \"h\" - spanned by \"e\", only if `includeAllSlots: true`),\n\t\t\t\t// - or a cell from the same row which spans over this column (cell \"a\").\n\n\t\t\t\tif ( cellAnchorColumn < insertAt ) {\n\t\t\t\t\t// If cell is anchored in previous column, it is a cell that spans over an inserted column (cell \"a\" & \"i\").\n\t\t\t\t\t// For such cells expand them by a number of columns inserted.\n\t\t\t\t\twriter.setAttribute( 'colspan', cellWidth + columnsToInsert, cell );\n\n\t\t\t\t\t// This cell will overlap cells in rows below so skip them (because of `includeAllSlots` option) - (cell \"a\")\n\t\t\t\t\tconst lastCellRow = cellAnchorRow + cellHeight - 1;\n\n\t\t\t\t\tfor ( let i = row; i <= lastCellRow; i++ ) {\n\t\t\t\t\t\ttableWalker.skipRow( i );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// It's either cell at this column index or spanned cell by a row-spanned cell from row above.\n\t\t\t\t\t// In table above it's cell \"e\" and a spanned position from row below (empty cell between cells \"g\" and \"h\")\n\t\t\t\t\tcreateCells( columnsToInsert, writer, tableSlot.getPositionBefore() );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes rows from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including `rowspan` attribute of table cells overlapping removed rows\n\t * and table headings values.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).removeRows( table, { at: 1, rows: 2 } );\n\t * ```\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *  row index\n\t *      ┌───┬───┬───┐        `at` = 1        ┌───┬───┬───┐\n\t *    0 │ a │ b │ c │        `rows` = 2      │ a │ b │ c │ 0\n\t *      │   ├───┼───┤                        │   ├───┼───┤\n\t *    1 │   │ d │ e │  <-- remove from here  │   │ d │ g │ 1\n\t *      │   │   ├───┤        will give:      ├───┼───┼───┤\n\t *    2 │   │   │ f │                        │ h │ i │ j │ 2\n\t *      │   │   ├───┤                        └───┴───┴───┘\n\t *    3 │   │   │ g │\n\t *      ├───┼───┼───┤\n\t *    4 │ h │ i │ j │\n\t *      └───┴───┴───┘\n\t *\n\t * @param options.at The row index at which the removing rows will start.\n\t * @param options.rows The number of rows to remove. Default value is 1.\n\t */\n\tpublic removeRows( table: Element, options: { at: number; rows?: number } ): void {\n\t\tconst model = this.editor.model;\n\n\t\tconst rowsToRemove = options.rows || 1;\n\t\tconst rowCount = this.getRows( table );\n\t\tconst first = options.at;\n\t\tconst last = first + rowsToRemove - 1;\n\n\t\tif ( last > rowCount - 1 ) {\n\t\t\t/**\n\t\t\t * The `options.at` param must point at existing row and `options.rows` must not exceed the rows in the table.\n\t\t\t *\n\t\t\t * @error tableutils-removerows-row-index-out-of-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'tableutils-removerows-row-index-out-of-range',\n\t\t\t\tthis,\n\t\t\t\t{ table, options }\n\t\t\t);\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst indexesObject = { first, last };\n\n\t\t\t// Removing rows from the table require that most calculations to be done prior to changing table structure.\n\t\t\t// Preparations must be done in the same enqueueChange callback to use the current table structure.\n\n\t\t\t// 1. Preparation - get row-spanned cells that have to be modified after removing rows.\n\t\t\tconst { cellsToMove, cellsToTrim } = getCellsToMoveAndTrimOnRemoveRow( table, indexesObject );\n\n\t\t\t// 2. Execution\n\n\t\t\t// 2a. Move cells from removed rows that extends over a removed section - must be done before removing rows.\n\t\t\t// This will fill any gaps in a rows below that previously were empty because of row-spanned cells.\n\t\t\tif ( cellsToMove.size ) {\n\t\t\t\tconst rowAfterRemovedSection = last + 1;\n\t\t\t\tmoveCellsToRow( table, rowAfterRemovedSection, cellsToMove, writer );\n\t\t\t}\n\n\t\t\t// 2b. Remove all required rows.\n\t\t\tfor ( let i = last; i >= first; i-- ) {\n\t\t\t\twriter.remove( table.getChild( i )! );\n\t\t\t}\n\n\t\t\t// 2c. Update cells from rows above that overlap removed section. Similar to step 2 but does not involve moving cells.\n\t\t\tfor ( const { rowspan, cell } of cellsToTrim ) {\n\t\t\t\tupdateNumericAttribute( 'rowspan', rowspan, cell, writer );\n\t\t\t}\n\n\t\t\t// 2d. Adjust heading rows if removed rows were in a heading section.\n\t\t\tupdateHeadingRows( table, indexesObject, writer );\n\n\t\t\t// 2e. Remove empty columns (without anchored cells) if there are any.\n\t\t\tif ( !removeEmptyColumns( table, this ) ) {\n\t\t\t\t// If there wasn't any empty columns then we still need to check if this wasn't called\n\t\t\t\t// because of cleaning empty rows and we only removed one of them.\n\t\t\t\tremoveEmptyRows( table, this );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes columns from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including the `colspan` attribute of table cells overlapping removed columns\n\t * and table headings values.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).removeColumns( table, { at: 1, columns: 2 } );\n\t * ```\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *    0   1   2   3   4                       0   1   2\n\t *  ┌───────────────┬───┐                   ┌───────┬───┐\n\t *  │ a             │ b │                   │ a     │ b │\n\t *  │               ├───┤                   │       ├───┤\n\t *  │               │ c │                   │       │ c │\n\t *  ├───┬───┬───┬───┼───┤     will give:    ├───┬───┼───┤\n\t *  │ d │ e │ f │ g │ h │                   │ d │ g │ h │\n\t *  ├───┼───┼───┤   ├───┤                   ├───┤   ├───┤\n\t *  │ i │ j │ k │   │ l │                   │ i │   │ l │\n\t *  ├───┴───┴───┴───┴───┤                   ├───┴───┴───┤\n\t *  │ m                 │                   │ m         │\n\t *  └───────────────────┘                   └───────────┘\n\t *        ^---- remove from here, `at` = 1, `columns` = 2\n\t *\n\t * @param options.at The row index at which the removing columns will start.\n\t * @param options.columns The number of columns to remove.\n\t */\n\tpublic removeColumns( table: Element, options: { at: number; columns?: number } ): void {\n\t\tconst model = this.editor.model;\n\t\tconst first = options.at;\n\t\tconst columnsToRemove = options.columns || 1;\n\t\tconst last = options.at + columnsToRemove - 1;\n\n\t\tmodel.change( writer => {\n\t\t\tadjustHeadingColumns( table, { first, last }, writer );\n\t\t\tconst tableColumns = getTableColumnElements( table );\n\n\t\t\tfor ( let removedColumnIndex = last; removedColumnIndex >= first; removedColumnIndex-- ) {\n\t\t\t\tfor ( const { cell, column, cellWidth } of [ ...new TableWalker( table ) ] ) {\n\t\t\t\t\t// If colspaned cell overlaps removed column decrease its span.\n\t\t\t\t\tif ( column <= removedColumnIndex && cellWidth > 1 && column + cellWidth > removedColumnIndex ) {\n\t\t\t\t\t\tupdateNumericAttribute( 'colspan', cellWidth - 1, cell, writer );\n\t\t\t\t\t} else if ( column === removedColumnIndex ) {\n\t\t\t\t\t\t// The cell in removed column has colspan of 1.\n\t\t\t\t\t\twriter.remove( cell );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If table has `tableColumn` elements, we need to update it manually.\n\t\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for details.\n\t\t\t\tif ( tableColumns[ removedColumnIndex ] ) {\n\t\t\t\t\t// If the removed column is the first one then we need to add its width to the next column.\n\t\t\t\t\t// Otherwise we add it to the previous column.\n\t\t\t\t\tconst adjacentColumn = removedColumnIndex === 0 ? tableColumns[ 1 ] : tableColumns[ removedColumnIndex - 1 ];\n\n\t\t\t\t\tconst removedColumnWidth = parseFloat( tableColumns[ removedColumnIndex ].getAttribute( 'columnWidth' ) as string );\n\t\t\t\t\tconst adjacentColumnWidth = parseFloat( adjacentColumn.getAttribute( 'columnWidth' ) as string );\n\n\t\t\t\t\twriter.remove( tableColumns[ removedColumnIndex ] );\n\n\t\t\t\t\t// Add the removed column width (in %) to the adjacent column.\n\t\t\t\t\twriter.setAttribute( 'columnWidth', removedColumnWidth + adjacentColumnWidth + '%', adjacentColumn );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove empty rows that could appear after removing columns.\n\t\t\tif ( !removeEmptyRows( table, this ) ) {\n\t\t\t\t// If there wasn't any empty rows then we still need to check if this wasn't called\n\t\t\t\t// because of cleaning empty columns and we only removed one of them.\n\t\t\t\tremoveEmptyColumns( table, this );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell vertically into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating colspans of other cells in a column\n\t * and inserting cells (columns) after that cell.\n\t *\n\t * In the table below, if cell \"a\" is split into 3 cells:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +---+---+---+\n\t *  | d | e | f |\n\t *  +---+---+---+\n\t *\n\t * it will result in the table below:\n\t *\n\t *  +---+---+---+---+---+\n\t *  | a |   |   | b | c |\n\t *  +---+---+---+---+---+\n\t *  | d         | e | f |\n\t *  +---+---+---+---+---+\n\t *\n\t * So cell \"d\" will get its `colspan` updated to `3` and 2 cells will be added (2 columns will be created).\n\t *\n\t * Splitting a cell that already has a `colspan` attribute set will distribute the cell `colspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *  +---+---+---+\n\t *  | a         |\n\t *  +---+---+---+\n\t *  | b | c | d |\n\t *  +---+---+---+\n\t *\n\t * Splitting cell \"a\" with `colspan=3` into 2 cells will create 1 cell with a `colspan=a` and cell \"a\" that will have `colspan=2`:\n\t *\n\t *  +---+---+---+\n\t *  | a     |   |\n\t *  +---+---+---+\n\t *  | b | c | d |\n\t *  +---+---+---+\n\t */\n\tpublic splitCellVertically( tableCell: Element, numberOfCells = 2 ): void {\n\t\tconst model = this.editor.model;\n\t\tconst tableRow = tableCell.parent!;\n\t\tconst table = tableRow.parent as Element;\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) as string || '1' );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) as string || '1' );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( colspan > 1 ) {\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( colspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'colspan', updatedSpan, tableCell, writer );\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes: { colspan?: number; rowspan?: number } = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tconst cellsToInsert = colspan > numberOfCells ? numberOfCells - 1 : colspan - 1;\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\t\t\t}\n\n\t\t\t// Second check - the cell has colspan of 1 or we need to create more cells then the currently one spans over.\n\t\t\tif ( colspan < numberOfCells ) {\n\t\t\t\tconst cellsToInsert = numberOfCells - colspan;\n\n\t\t\t\t// First step: expand cells on the same column as split cell.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\t\t\t// Get the column index of split cell.\n\t\t\t\tconst { column: splitCellColumn } = tableMap.find( ( { cell } ) => cell === tableCell )!;\n\n\t\t\t\t// Find cells which needs to be expanded vertically - those on the same column or those that spans over split cell's column.\n\t\t\t\tconst cellsToUpdate = tableMap.filter( ( { cell, cellWidth, column } ) => {\n\t\t\t\t\tconst isOnSameColumn = cell !== tableCell && column === splitCellColumn;\n\t\t\t\t\tconst spansOverColumn = ( column < splitCellColumn && column + cellWidth > splitCellColumn );\n\n\t\t\t\t\treturn isOnSameColumn || spansOverColumn;\n\t\t\t\t} );\n\n\t\t\t\t// Expand cells vertically.\n\t\t\t\tfor ( const { cell, cellWidth } of cellsToUpdate ) {\n\t\t\t\t\twriter.setAttribute( 'colspan', cellWidth + cellsToInsert, cell );\n\t\t\t\t}\n\n\t\t\t\t// Second step: create columns after split cell.\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes: { rowspan?: number } = {};\n\n\t\t\t\t// Do not store default value in the model.\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\n\t\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) as number || 0;\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tif ( headingColumns > splitCellColumn ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingColumns', headingColumns + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell horizontally into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating rowspans of other cells in the row and inserting rows with a single cell\n\t * below.\n\t *\n\t * If in the table below cell \"b\" is split into 3 cells:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +---+---+---+\n\t *  | d | e | f |\n\t *  +---+---+---+\n\t *\n\t * It will result in the table below:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +   +---+   +\n\t *  |   |   |   |\n\t *  +   +---+   +\n\t *  |   |   |   |\n\t *  +---+---+---+\n\t *  | d | e | f |\n\t *  +---+---+---+\n\t *\n\t * So cells \"a\" and \"b\" will get their `rowspan` updated to `3` and 2 rows with a single cell will be added.\n\t *\n\t * Splitting a cell that already has a `rowspan` attribute set will distribute the cell `rowspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +   +---+---+\n\t *  |   | d | e |\n\t *  +   +---+---+\n\t *  |   | f | g |\n\t *  +   +---+---+\n\t *  |   | h | i |\n\t *  +---+---+---+\n\t *\n\t * Splitting cell \"a\" with `rowspan=4` into 3 cells will create 2 cells with a `rowspan=1` and cell \"a\" will have `rowspan=2`:\n\t *\n\t *  +---+---+---+\n\t *  | a | b | c |\n\t *  +   +---+---+\n\t *  |   | d | e |\n\t *  +---+---+---+\n\t *  |   | f | g |\n\t *  +---+---+---+\n\t *  |   | h | i |\n\t *  +---+---+---+\n\t */\n\tpublic splitCellHorizontally( tableCell: Element, numberOfCells = 2 ): void {\n\t\tconst model = this.editor.model;\n\n\t\tconst tableRow = tableCell.parent as Node;\n\t\tconst table = tableRow.parent! as Element;\n\t\tconst splitCellRow = table.getChildIndex( tableRow )!;\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) as string || '1' );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) as string || '1' );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t// Cache table map before updating table.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, {\n\t\t\t\t\tstartRow: splitCellRow,\n\t\t\t\t\tendRow: splitCellRow + rowspan - 1,\n\t\t\t\t\tincludeAllSlots: true\n\t\t\t\t} ) ];\n\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( rowspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'rowspan', updatedSpan, tableCell, writer );\n\n\t\t\t\tconst { column: cellColumn } = tableMap.find( ( { cell } ) => cell === tableCell )!;\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes: { rowspan?: number; colspan?: number } = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\t// Accumulator that stores distance from the last inserted cell span.\n\t\t\t\t// It helps with evenly splitting larger cell spans (for example 10 cells collapsing into 3 cells).\n\t\t\t\t// We split these cells into 3, 3, 4 cells and we have to call `createCells` only when distance between\n\t\t\t\t// these cells is equal or greater than the new cells span size.\n\t\t\t\tlet distanceFromLastCellSpan = 0;\n\n\t\t\t\tfor ( const tableSlot of tableMap ) {\n\t\t\t\t\tconst { column, row } = tableSlot;\n\n\t\t\t\t\t// As both newly created cells and the split cell might have rowspan,\n\t\t\t\t\t// the insertion of new cells must go to appropriate rows:\n\t\t\t\t\t//\n\t\t\t\t\t// 1. It's a row after split cell + it's height.\n\t\t\t\t\tconst isAfterSplitCell = row >= splitCellRow + updatedSpan;\n\n\t\t\t\t\t// 2. Is on the same column.\n\t\t\t\t\tconst isOnSameColumn = column === cellColumn;\n\n\t\t\t\t\t// Reset distance from the last cell span if we are on the same column and we exceeded the new cells span size.\n\t\t\t\t\tif ( distanceFromLastCellSpan >= newCellsSpan && isOnSameColumn ) {\n\t\t\t\t\t\tdistanceFromLastCellSpan = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( isAfterSplitCell && isOnSameColumn ) {\n\t\t\t\t\t\t// Create new cells only if the distance from the last cell span is equal or greater than the new cells span.\n\t\t\t\t\t\tif ( !distanceFromLastCellSpan ) {\n\t\t\t\t\t\t\tcreateCells( 1, writer, tableSlot.getPositionBefore(), newCellsAttributes );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Increase the distance from the last cell span.\n\t\t\t\t\t\tdistanceFromLastCellSpan++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Second check - the cell has rowspan of 1 or we need to create more cells than the current cell spans over.\n\t\t\tif ( rowspan < numberOfCells ) {\n\t\t\t\t// We already split the cell in check one so here we split to the remaining number of cells only.\n\t\t\t\tconst cellsToInsert = numberOfCells - rowspan;\n\n\t\t\t\t// This check is needed since we need to check if there are any cells from previous rows than spans over this cell's row.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, { startRow: 0, endRow: splitCellRow } ) ];\n\n\t\t\t\t// First step: expand cells.\n\t\t\t\tfor ( const { cell, cellHeight, row } of tableMap ) {\n\t\t\t\t\t// Expand rowspan of cells that are either:\n\t\t\t\t\t// - on the same row as current cell,\n\t\t\t\t\t// - or are below split cell row and overlaps that row.\n\t\t\t\t\tif ( cell !== tableCell && row + cellHeight > splitCellRow ) {\n\t\t\t\t\t\tconst rowspanToSet = cellHeight + cellsToInsert;\n\n\t\t\t\t\t\twriter.setAttribute( 'rowspan', rowspanToSet, cell );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Second step: create rows with single cell below split cell.\n\t\t\t\tconst newCellsAttributes: { colspan?: number } = {};\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\tcreateEmptyRows( writer, table, splitCellRow + 1, cellsToInsert, 1, newCellsAttributes );\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\n\t\t\t\tif ( headingRows > splitCellRow ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the number of columns for a given table.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).getColumns( table );\n\t * ```\n\t *\n\t * @param table The table to analyze.\n\t */\n\tpublic getColumns( table: Element ): number {\n\t\t// Analyze first row only as all the rows should have the same width.\n\t\t// Using the first row without checking if it's a tableRow because we expect\n\t\t// that table will have only tableRow model elements at the beginning.\n\t\tconst row = table.getChild( 0 ) as Element;\n\n\t\treturn [ ...row.getChildren() ]\n\t\t\t// $marker elements can also be children of a row too (when TrackChanges is on). Don't include them in the count.\n\t\t\t.filter( node => node.is( 'element', 'tableCell' ) )\n\t\t\t.reduce( ( columns, row ) => {\n\t\t\t\tconst columnWidth = parseInt( row.getAttribute( 'colspan' ) as string || '1' );\n\n\t\t\t\treturn columns + columnWidth;\n\t\t\t}, 0 );\n\t}\n\n\t/**\n\t * Returns the number of rows for a given table. Any other element present in the table model is omitted.\n\t *\n\t * ```ts\n\t * editor.plugins.get( 'TableUtils' ).getRows( table );\n\t * ```\n\t *\n\t * @param table The table to analyze.\n\t */\n\tpublic getRows( table: Element ): number {\n\t\t// Rowspan not included due to #6427.\n\t\treturn Array.from( table.getChildren() )\n\t\t\t.reduce( ( rowCount, child ) => child.is( 'element', 'tableRow' ) ? rowCount + 1 : rowCount, 0 );\n\t}\n\n\t/**\n\t * Creates an instance of the table walker.\n\t *\n\t * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.\n\t * It walks row by row and column by column in order to output values defined in the options.\n\t * By default it will output only the locations that are occupied by a cell. To include also spanned rows and columns,\n\t * pass the `includeAllSlots` option.\n\t *\n\t * @internal\n\t * @param table A table over which the walker iterates.\n\t * @param options An object with configuration.\n\t */\n\tpublic createTableWalker( table: Element, options: TableWalkerOptions = {} ): TableWalker {\n\t\treturn new TableWalker( table, options );\n\t}\n\n\t/**\n\t * Returns all model table cells that are fully selected (from the outside)\n\t * within the provided model selection's ranges.\n\t *\n\t * To obtain the cells selected from the inside, use\n\t * {@link #getTableCellsContainingSelection}.\n\t */\n\tpublic getSelectedTableCells( selection: Selection | DocumentSelection ): Array<Element> {\n\t\tconst cells = [];\n\n\t\tfor ( const range of this.sortRanges( selection.getRanges() ) ) {\n\t\t\tconst element = range.getContainedElement();\n\n\t\t\tif ( element && element.is( 'element', 'tableCell' ) ) {\n\t\t\t\tcells.push( element );\n\t\t\t}\n\t\t}\n\n\t\treturn cells;\n\t}\n\n\t/**\n\t * Returns all model table cells that the provided model selection's ranges\n\t * {@link module:engine/model/range~Range#start} inside.\n\t *\n\t * To obtain the cells selected from the outside, use\n\t * {@link #getSelectedTableCells}.\n\t */\n\tpublic getTableCellsContainingSelection( selection: Selection | DocumentSelection ): Array<Element> {\n\t\tconst cells = [];\n\n\t\tfor ( const range of selection.getRanges() ) {\n\t\t\tconst cellWithSelection = range.start.findAncestor( 'tableCell' );\n\n\t\t\tif ( cellWithSelection ) {\n\t\t\t\tcells.push( cellWithSelection );\n\t\t\t}\n\t\t}\n\n\t\treturn cells;\n\t}\n\n\t/**\n\t * Returns all model table cells that are either completely selected\n\t * by selection ranges or host selection range\n\t * {@link module:engine/model/range~Range#start start positions} inside them.\n\t *\n\t * Combines {@link #getTableCellsContainingSelection} and\n\t * {@link #getSelectedTableCells}.\n\t */\n\tpublic getSelectionAffectedTableCells( selection: Selection | DocumentSelection ): Array<Element> {\n\t\tconst selectedCells = this.getSelectedTableCells( selection );\n\n\t\tif ( selectedCells.length ) {\n\t\t\treturn selectedCells;\n\t\t}\n\n\t\treturn this.getTableCellsContainingSelection( selection );\n\t}\n\n\t/**\n\t * Returns an object with the `first` and `last` row index contained in the given `tableCells`.\n\t *\n\t * ```ts\n\t * const selectedTableCells = getSelectedTableCells( editor.model.document.selection );\n\t *\n\t * const { first, last } = getRowIndexes( selectedTableCells );\n\t *\n\t * console.log( `Selected rows: ${ first } to ${ last }` );\n\t * ```\n\t *\n\t * @returns Returns an object with the `first` and `last` table row indexes.\n\t */\n\tpublic getRowIndexes( tableCells: Array<Element> ): IndexesObject {\n\t\tconst indexes = tableCells.map( cell => ( cell.parent as Element ).index! );\n\n\t\treturn this._getFirstLastIndexesObject( indexes );\n\t}\n\n\t/**\n\t * Returns an object with the `first` and `last` column index contained in the given `tableCells`.\n\t *\n\t * ```ts\n\t * const selectedTableCells = getSelectedTableCells( editor.model.document.selection );\n\t *\n\t * const { first, last } = getColumnIndexes( selectedTableCells );\n\t *\n\t * console.log( `Selected columns: ${ first } to ${ last }` );\n\t * ```\n\t *\n\t * @returns Returns an object with the `first` and `last` table column indexes.\n\t */\n\tpublic getColumnIndexes( tableCells: Array<Element> ): IndexesObject {\n\t\tconst table = tableCells[ 0 ].findAncestor( 'table' )!;\n\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\tconst indexes = tableMap\n\t\t\t.filter( entry => tableCells.includes( entry.cell ) )\n\t\t\t.map( entry => entry.column );\n\n\t\treturn this._getFirstLastIndexesObject( indexes );\n\t}\n\n\t/**\n\t * Checks if the selection contains cells that do not exceed rectangular selection.\n\t *\n\t * In a table below:\n\t *\n\t *  ┌───┬───┬───┬───┐\n\t *  │ a │ b │ c │ d │\n\t *  ├───┴───┼───┤   │\n\t *  │ e     │ f │   │\n\t *  │       ├───┼───┤\n\t *  │       │ g │ h │\n\t *  └───────┴───┴───┘\n\t *\n\t * Valid selections are these which create a solid rectangle (without gaps), such as:\n\t *   - a, b (two horizontal cells)\n\t *   - c, f (two vertical cells)\n\t *   - a, b, e (cell \"e\" spans over four cells)\n\t *   - c, d, f (cell d spans over a cell in the row below)\n\t *\n\t * While an invalid selection would be:\n\t *   - a, c (the unselected cell \"b\" creates a gap)\n\t *   - f, g, h (cell \"d\" spans over a cell from the row of \"f\" cell - thus creates a gap)\n\t */\n\tpublic isSelectionRectangular( selectedTableCells: Array<Element> ): boolean {\n\t\tif ( selectedTableCells.length < 2 || !this._areCellInTheSameTableSection( selectedTableCells ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// A valid selection is a fully occupied rectangle composed of table cells.\n\t\t// Below we will calculate the area of a selected table cells and the area of valid selection.\n\t\t// The area of a valid selection is defined by top-left and bottom-right cells.\n\t\tconst rows: Set<number> = new Set();\n\t\tconst columns: Set<number> = new Set();\n\n\t\tlet areaOfSelectedCells = 0;\n\n\t\tfor ( const tableCell of selectedTableCells ) {\n\t\t\tconst { row, column } = this.getCellLocation( tableCell );\n\t\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) as string ) || 1;\n\t\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) as string ) || 1;\n\n\t\t\t// Record row & column indexes of current cell.\n\t\t\trows.add( row );\n\t\t\tcolumns.add( column );\n\n\t\t\t// For cells that spans over multiple rows add also the last row that this cell spans over.\n\t\t\tif ( rowspan > 1 ) {\n\t\t\t\trows.add( row + rowspan - 1 );\n\t\t\t}\n\n\t\t\t// For cells that spans over multiple columns add also the last column that this cell spans over.\n\t\t\tif ( colspan > 1 ) {\n\t\t\t\tcolumns.add( column + colspan - 1 );\n\t\t\t}\n\n\t\t\tareaOfSelectedCells += ( rowspan * colspan );\n\t\t}\n\n\t\t// We can only merge table cells that are in adjacent rows...\n\t\tconst areaOfValidSelection = getBiggestRectangleArea( rows, columns );\n\n\t\treturn areaOfValidSelection == areaOfSelectedCells;\n\t}\n\n\t/**\n\t * Returns array of sorted ranges.\n\t */\n\tpublic sortRanges( ranges: Iterable<Range> ): Array<Range> {\n\t\treturn Array.from( ranges ).sort( compareRangeOrder );\n\t}\n\n\t/**\n\t * Helper method to get an object with `first` and `last` indexes from an unsorted array of indexes.\n\t */\n\tprivate _getFirstLastIndexesObject( indexes: Array<number> ): IndexesObject {\n\t\tconst allIndexesSorted = indexes.sort( ( indexA, indexB ) => indexA - indexB );\n\n\t\tconst first = allIndexesSorted[ 0 ];\n\t\tconst last = allIndexesSorted[ allIndexesSorted.length - 1 ];\n\n\t\treturn { first, last };\n\t}\n\n\t/**\n\t * Checks if the selection does not mix a header (column or row) with other cells.\n\t *\n\t * For instance, in the table below valid selections consist of cells with the same letter only.\n\t * So, a-a (same heading row and column) or d-d (body cells) are valid while c-d or a-b are not.\n\t *\n\t * header columns\n\t *    ↓   ↓\n\t *  ┌───┬───┬───┬───┐\n\t *  │ a │ a │ b │ b │  ← header row\n\t *  ├───┼───┼───┼───┤\n\t *  │ c │ c │ d │ d │\n\t *  ├───┼───┼───┼───┤\n\t *  │ c │ c │ d │ d │\n\t *  └───┴───┴───┴───┘\n\t */\n\tprivate _areCellInTheSameTableSection( tableCells: Array<Element> ): boolean {\n\t\tconst table = tableCells[ 0 ].findAncestor( 'table' )!;\n\n\t\tconst rowIndexes = this.getRowIndexes( tableCells );\n\t\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) as string ) || 0;\n\n\t\t// Calculating row indexes is a bit cheaper so if this check fails we can't merge.\n\t\tif ( !this._areIndexesInSameSection( rowIndexes, headingRows ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst columnIndexes = this.getColumnIndexes( tableCells );\n\t\tconst headingColumns = parseInt( table.getAttribute( 'headingColumns' ) as string ) || 0;\n\n\t\t// Similarly cells must be in same column section.\n\t\treturn this._areIndexesInSameSection( columnIndexes, headingColumns );\n\t}\n\n\t/**\n\t * Unified check if table rows/columns indexes are in the same heading/body section.\n\t */\n\tprivate _areIndexesInSameSection( { first, last }: IndexesObject, headingSectionSize: number ): boolean {\n\t\tconst firstCellIsInHeading = first < headingSectionSize;\n\t\tconst lastCellIsInHeading = last < headingSectionSize;\n\n\t\treturn firstCellIsInHeading === lastCellIsInHeading;\n\t}\n}\n\n/**\n * Creates empty rows at the given index in an existing table.\n *\n * @param insertAt The row index of row insertion.\n * @param rows The number of rows to create.\n * @param tableCellToInsert The number of cells to insert in each row.\n */\nfunction createEmptyRows( writer: Writer, table: Element, insertAt: number, rows: number, tableCellToInsert: number, attributes = {} ) {\n\tfor ( let i = 0; i < rows; i++ ) {\n\t\tconst tableRow = writer.createElement( 'tableRow' );\n\n\t\twriter.insert( tableRow, table, insertAt );\n\n\t\tcreateCells( tableCellToInsert, writer, writer.createPositionAt( tableRow, 'end' ), attributes );\n\t}\n}\n\n/**\n * Creates cells at a given position.\n *\n * @param cells The number of cells to create\n */\nfunction createCells( cells: number, writer: Writer, insertPosition: Position, attributes = {} ) {\n\tfor ( let i = 0; i < cells; i++ ) {\n\t\tcreateEmptyTableCell( writer, insertPosition, attributes );\n\t}\n}\n\n/**\n * Evenly distributes the span of a cell to a number of provided cells.\n * The resulting spans will always be integer values.\n *\n * For instance breaking a span of 7 into 3 cells will return:\n *\n * ```ts\n * { newCellsSpan: 2, updatedSpan: 3 }\n * ```\n *\n * as two cells will have a span of 2 and the remainder will go the first cell so its span will change to 3.\n *\n * @param span The span value do break.\n * @param numberOfCells The number of resulting spans.\n */\nfunction breakSpanEvenly( span: number, numberOfCells: number ): { newCellsSpan: number; updatedSpan: number } {\n\tif ( span < numberOfCells ) {\n\t\treturn { newCellsSpan: 1, updatedSpan: 1 };\n\t}\n\n\tconst newCellsSpan = Math.floor( span / numberOfCells );\n\tconst updatedSpan = ( span - newCellsSpan * numberOfCells ) + newCellsSpan;\n\n\treturn { newCellsSpan, updatedSpan };\n}\n\n/**\n * Updates heading columns attribute if removing a row from head section.\n */\nfunction adjustHeadingColumns( table: Element, removedColumnIndexes: IndexesObject, writer: Writer ) {\n\tconst headingColumns = table.getAttribute( 'headingColumns' ) as number || 0;\n\n\tif ( headingColumns && removedColumnIndexes.first < headingColumns ) {\n\t\tconst headingsRemoved = Math.min( headingColumns - 1 /* Other numbers are 0-based */, removedColumnIndexes.last ) -\n\t\t\tremovedColumnIndexes.first + 1;\n\n\t\twriter.setAttribute( 'headingColumns', headingColumns - headingsRemoved, table );\n\t}\n}\n\n/**\n * Calculates a new heading rows value for removing rows from heading section.\n */\nfunction updateHeadingRows( table: Element, { first, last }: IndexesObject, writer: Writer ) {\n\tconst headingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\n\tif ( first < headingRows ) {\n\t\tconst newRows = last < headingRows ? headingRows - ( last - first + 1 ) : first;\n\n\t\tupdateNumericAttribute( 'headingRows', newRows, table, writer, 0 );\n\t}\n}\n\n/**\n * Finds cells that will be:\n * - trimmed - Cells that are \"above\" removed rows sections and overlap the removed section - their rowspan must be trimmed.\n * - moved - Cells from removed rows section might stick out of. These cells are moved to the next row after a removed section.\n *\n * Sample table with overlapping & sticking out cells:\n *\n *      +----+----+----+----+----+\n *      | 00 | 01 | 02 | 03 | 04 |\n *      +----+    +    +    +    +\n *      | 10 |    |    |    |    |\n *      +----+----+    +    +    +\n *      | 20 | 21 |    |    |    | <-- removed row\n *      +    +    +----+    +    +\n *      |    |    | 32 |    |    | <-- removed row\n *      +----+    +    +----+    +\n *      | 40 |    |    | 43 |    |\n *      +----+----+----+----+----+\n *\n * In a table above:\n * - cells to trim: '02', '03' & '04'.\n * - cells to move: '21' & '32'.\n */\nfunction getCellsToMoveAndTrimOnRemoveRow( table: Element, { first, last }: IndexesObject ) {\n\tconst cellsToMove: CellsToMove = new Map();\n\tconst cellsToTrim: CellsToTrim = [];\n\n\tfor ( const { row, column, cellHeight, cell } of new TableWalker( table, { endRow: last } ) ) {\n\t\tconst lastRowOfCell = row + cellHeight - 1;\n\n\t\tconst isCellStickingOutFromRemovedRows = row >= first && row <= last && lastRowOfCell > last;\n\n\t\tif ( isCellStickingOutFromRemovedRows ) {\n\t\t\tconst rowspanInRemovedSection = last - row + 1;\n\t\t\tconst rowSpanToSet = cellHeight - rowspanInRemovedSection;\n\n\t\t\tcellsToMove.set( column, {\n\t\t\t\tcell,\n\t\t\t\trowspan: rowSpanToSet\n\t\t\t} );\n\t\t}\n\n\t\tconst isCellOverlappingRemovedRows = row < first && lastRowOfCell >= first;\n\n\t\tif ( isCellOverlappingRemovedRows ) {\n\t\t\tlet rowspanAdjustment;\n\n\t\t\t// Cell fully covers removed section - trim it by removed rows count.\n\t\t\tif ( lastRowOfCell >= last ) {\n\t\t\t\trowspanAdjustment = last - first + 1;\n\t\t\t}\n\t\t\t// Cell partially overlaps removed section - calculate cell's span that is in removed section.\n\t\t\telse {\n\t\t\t\trowspanAdjustment = lastRowOfCell - first + 1;\n\t\t\t}\n\n\t\t\tcellsToTrim.push( {\n\t\t\t\tcell,\n\t\t\t\trowspan: cellHeight - rowspanAdjustment\n\t\t\t} );\n\t\t}\n\t}\n\n\treturn { cellsToMove, cellsToTrim };\n}\n\nfunction moveCellsToRow( table: Element, targetRowIndex: number, cellsToMove: CellsToMove, writer: Writer ) {\n\tconst tableWalker = new TableWalker( table, {\n\t\tincludeAllSlots: true,\n\t\trow: targetRowIndex\n\t} );\n\n\tconst tableRowMap = [ ...tableWalker ];\n\tconst row = table.getChild( targetRowIndex )!;\n\n\tlet previousCell;\n\n\tfor ( const { column, cell, isAnchor } of tableRowMap ) {\n\t\tif ( cellsToMove.has( column ) ) {\n\t\t\tconst { cell: cellToMove, rowspan } = cellsToMove.get( column )!;\n\n\t\t\tconst targetPosition = previousCell ?\n\t\t\t\twriter.createPositionAfter( previousCell ) :\n\t\t\t\twriter.createPositionAt( row, 0 );\n\n\t\t\twriter.move( writer.createRangeOn( cellToMove ), targetPosition );\n\t\t\tupdateNumericAttribute( 'rowspan', rowspan, cellToMove, writer );\n\n\t\t\tpreviousCell = cellToMove;\n\t\t} else if ( isAnchor ) {\n\t\t\t// If cell is spanned then `cell` holds reference to overlapping cell. See ckeditor/ckeditor5#6502.\n\t\t\tpreviousCell = cell;\n\t\t}\n\t}\n}\n\nfunction compareRangeOrder( rangeA: Range, rangeB: Range ) {\n\t// Since table cell ranges are disjoint, it's enough to check their start positions.\n\tconst posA = rangeA.start;\n\tconst posB = rangeB.start;\n\n\t// Checking for equal position (returning 0) is not needed because this would be either:\n\t// a. Intersecting range (not allowed by model)\n\t// b. Collapsed range on the same position (allowed by model but should not happen).\n\treturn posA.isBefore( posB ) ? -1 : 1;\n}\n\n/**\n * Calculates the area of a maximum rectangle that can span over the provided row & column indexes.\n */\nfunction getBiggestRectangleArea( rows: Set<number>, columns: Set<number> ): number {\n\tconst rowsIndexes = Array.from( rows.values() );\n\tconst columnIndexes = Array.from( columns.values() );\n\n\tconst lastRow = Math.max( ...rowsIndexes );\n\tconst firstRow = Math.min( ...rowsIndexes );\n\tconst lastColumn = Math.max( ...columnIndexes );\n\tconst firstColumn = Math.min( ...columnIndexes );\n\n\treturn ( lastRow - firstRow + 1 ) * ( lastColumn - firstColumn + 1 );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/mergecellscommand\n */\n\nimport type {\n\tElement,\n\tWriter\n} from 'ckeditor5/src/engine.js';\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport TableUtils from '../tableutils.js';\nimport { updateNumericAttribute } from '../utils/common.js';\nimport { removeEmptyRowsColumns } from '../utils/structure.js';\n\n/**\n * The merge cells command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'mergeTableCells'` editor command.\n *\n * For example, to merge selected table cells:\n *\n * ```ts\n * editor.execute( 'mergeTableCells' );\n * ```\n */\nexport default class MergeCellsCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\n\t\tconst selectedTableCells = tableUtils.getSelectedTableCells( this.editor.model.document.selection );\n\t\tthis.isEnabled = tableUtils.isSelectionRectangular( selectedTableCells );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\n\t\tmodel.change( writer => {\n\t\t\tconst selectedTableCells = tableUtils.getSelectedTableCells( model.document.selection );\n\n\t\t\t// All cells will be merged into the first one.\n\t\t\tconst firstTableCell = selectedTableCells.shift()!;\n\n\t\t\t// Update target cell dimensions.\n\t\t\tconst { mergeWidth, mergeHeight } = getMergeDimensions( firstTableCell, selectedTableCells, tableUtils );\n\t\t\tupdateNumericAttribute( 'colspan', mergeWidth, firstTableCell, writer );\n\t\t\tupdateNumericAttribute( 'rowspan', mergeHeight, firstTableCell, writer );\n\n\t\t\tfor ( const tableCell of selectedTableCells ) {\n\t\t\t\tmergeTableCells( tableCell, firstTableCell, writer );\n\t\t\t}\n\n\t\t\tconst table = firstTableCell.findAncestor( 'table' )!;\n\n\t\t\t// Remove rows and columns that become empty (have no anchored cells).\n\t\t\tremoveEmptyRowsColumns( table, tableUtils );\n\n\t\t\twriter.setSelection( firstTableCell, 'in' );\n\t\t} );\n\t}\n}\n\n/**\n *  Merges two table cells. It will ensure that after merging cells with empty paragraphs the resulting table cell will only have one\n * paragraph. If one of the merged table cells is empty, the merged table cell will have contents of the non-empty table cell.\n * If both are empty, the merged table cell will have only one empty paragraph.\n */\nfunction mergeTableCells( cellBeingMerged: Element, targetCell: Element, writer: Writer ) {\n\tif ( !isEmpty( cellBeingMerged ) ) {\n\t\tif ( isEmpty( targetCell ) ) {\n\t\t\twriter.remove( writer.createRangeIn( targetCell ) );\n\t\t}\n\n\t\twriter.move( writer.createRangeIn( cellBeingMerged ), writer.createPositionAt( targetCell, 'end' ) );\n\t}\n\n\t// Remove merged table cell.\n\twriter.remove( cellBeingMerged );\n}\n\n/**\n * Checks if the passed table cell contains an empty paragraph.\n */\nfunction isEmpty( tableCell: Element ): boolean {\n\tconst firstTableChild = tableCell.getChild( 0 );\n\n\treturn tableCell.childCount == 1 && firstTableChild!.is( 'element', 'paragraph' ) && firstTableChild.isEmpty;\n}\n\nfunction getMergeDimensions( firstTableCell: Element, selectedTableCells: Array<Element>, tableUtils: TableUtils ) {\n\tlet maxWidthOffset = 0;\n\tlet maxHeightOffset = 0;\n\n\tfor ( const tableCell of selectedTableCells ) {\n\t\tconst { row, column } = tableUtils.getCellLocation( tableCell );\n\n\t\tmaxWidthOffset = getMaxOffset( tableCell, column, maxWidthOffset, 'colspan' );\n\t\tmaxHeightOffset = getMaxOffset( tableCell, row, maxHeightOffset, 'rowspan' );\n\t}\n\n\t// Update table cell span attribute and merge set selection on a merged contents.\n\tconst { row: firstCellRow, column: firstCellColumn } = tableUtils.getCellLocation( firstTableCell );\n\n\tconst mergeWidth = maxWidthOffset - firstCellColumn;\n\tconst mergeHeight = maxHeightOffset - firstCellRow;\n\n\treturn { mergeWidth, mergeHeight };\n}\n\nfunction getMaxOffset( tableCell: Element, start: number, currentMaxOffset: number, which: string ) {\n\tconst dimensionValue = parseInt( tableCell.getAttribute( which ) as string || '1' );\n\n\treturn Math.max( currentMaxOffset, start + dimensionValue );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/selectrowcommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { Range, Element } from 'ckeditor5/src/engine.js';\nimport type TableUtils from '../tableutils.js';\n\n/**\n * The select row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableRow'` editor command.\n *\n * To select the rows containing the selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'selectTableRow' );\n * ```\n */\nexport default class SelectRowCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// It does not affect data so should be enabled in read-only mode.\n\t\tthis.affectsData = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( this.editor.model.document.selection );\n\n\t\tthis.isEnabled = selectedCells.length > 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst referenceCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst rowIndexes = tableUtils.getRowIndexes( referenceCells );\n\n\t\tconst table = referenceCells[ 0 ].findAncestor( 'table' )!;\n\t\tconst rangesToSelect: Array<Range> = [];\n\n\t\tfor ( let rowIndex = rowIndexes.first; rowIndex <= rowIndexes.last; rowIndex++ ) {\n\t\t\tfor ( const cell of ( table.getChild( rowIndex ) as Element ).getChildren() ) {\n\t\t\t\trangesToSelect.push( model.createRangeOn( cell ) );\n\t\t\t}\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( rangesToSelect );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/selectcolumncommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { Range } from 'ckeditor5/src/engine.js';\nimport type TableUtils from '../tableutils.js';\n\nimport TableWalker from '../tablewalker.js';\n\n/**\n * The select column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableColumn'` editor command.\n *\n * To select the columns containing the selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'selectTableColumn' );\n * ```\n */\nexport default class SelectColumnCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\t// It does not affect data so should be enabled in read-only mode.\n\t\tthis.affectsData = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst selectedCells = tableUtils.getSelectionAffectedTableCells( this.editor.model.document.selection );\n\n\t\tthis.isEnabled = selectedCells.length > 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override execute(): void {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst model = this.editor.model;\n\t\tconst referenceCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst firstCell = referenceCells[ 0 ];\n\t\tconst lastCell = referenceCells.pop()!;\n\t\tconst table = firstCell.findAncestor( 'table' )!;\n\n\t\tconst startLocation = tableUtils.getCellLocation( firstCell );\n\t\tconst endLocation = tableUtils.getCellLocation( lastCell );\n\n\t\tconst startColumn = Math.min( startLocation.column, endLocation.column );\n\t\tconst endColumn = Math.max( startLocation.column, endLocation.column );\n\n\t\tconst rangesToSelect: Array<Range> = [];\n\n\t\tfor ( const cellInfo of new TableWalker( table, { startColumn, endColumn } ) ) {\n\t\t\trangesToSelect.push( model.createRangeOn( cellInfo.cell ) );\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( rangesToSelect );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-layout-post-fixer\n */\n\nimport type {\n\tElement,\n\tModel,\n\tWriter,\n\tDiffItem,\n\tDiffItemAttribute\n} from 'ckeditor5/src/engine.js';\n\nimport TableWalker from './../tablewalker.js';\nimport { createEmptyTableCell, updateNumericAttribute } from '../utils/common.js';\n\n/**\n * Injects a table layout post-fixer into the model.\n *\n * The role of the table layout post-fixer is to ensure that the table rows have the correct structure\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct structure means that:\n *\n * * All table rows have the same size.\n * * None of the table cells extend vertically beyond their section (either header or body).\n * * A table cell has always at least one element as a child.\n *\n * If the table structure is not correct, the post-fixer will automatically correct it in two steps:\n *\n * 1. It will clip table cells that extend beyond their section.\n * 2. It will add empty table cells to the rows that are narrower than the widest table row.\n *\n * ## Clipping overlapping table cells\n *\n * Such situation may occur when pasting a table (or a part of a table) to the editor from external sources.\n *\n * For example, see the following table which has a cell (FOO) with the rowspan attribute (2):\n *\n * ```xml\n * <table headingRows=\"1\">\n *   <tableRow>\n *     <tableCell rowspan=\"2\"><paragraph>FOO</paragraph></tableCell>\n *     <tableCell colspan=\"2\"><paragraph>BAR</paragraph></tableCell>\n *   </tableRow>\n *   <tableRow>\n *     <tableCell><paragraph>BAZ</paragraph></tableCell>\n *     <tableCell><paragraph>XYZ</paragraph></tableCell>\n *   </tableRow>\n * </table>\n * ```\n *\n * It will be rendered in the view as:\n *\n * ```xml\n * <table>\n *   <thead>\n *     <tr>\n *       <td rowspan=\"2\">FOO</td>\n *       <td colspan=\"2\">BAR</td>\n *     </tr>\n *   </thead>\n *   <tbody>\n *     <tr>\n *       <td>BAZ</td>\n *       <td>XYZ</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * In the above example the table will be rendered as a table with two rows: one in the header and second one in the body.\n * The table cell (FOO) cannot span over multiple rows as it would extend from the header to the body section.\n * The `rowspan` attribute must be changed to (1). The value (1) is the default value of the `rowspan` attribute\n * so the `rowspan` attribute will be removed from the model.\n *\n * The table cell with BAZ in the content will be in the first column of the table.\n *\n * ## Adding missing table cells\n *\n * The table post-fixer will insert empty table cells to equalize table row sizes (the number of columns).\n * The size of a table row is calculated by counting column spans of table cells, both horizontal (from the same row) and\n * vertical (from the rows above).\n *\n * In the above example, the table row in the body section of the table is narrower then the row from the header: it has two cells\n * with the default colspan (1). The header row has one cell with colspan (1) and the second with colspan (2).\n * The table cell (FOO) does not extend beyond the head section (and as such will be fixed in the first step of this post-fixer).\n * The post-fixer will add a missing table cell to the row in the body section of the table.\n *\n * The table from the above example will be fixed and rendered to the view as below:\n *\n * ```xml\n * <table>\n *   <thead>\n *     <tr>\n *       <td rowspan=\"2\">FOO</td>\n *       <td colspan=\"2\">BAR</td>\n *     </tr>\n *   </thead>\n *   <tbody>\n *     <tr>\n *       <td>BAZ</td>\n *       <td>XYZ</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * ## Collaboration and undo - Expectations vs post-fixer results\n *\n * The table post-fixer only ensures proper structure without a deeper analysis of the nature of the change. As such, it might lead\n * to a structure which was not intended by the user. In particular, it will also fix undo steps (in conjunction with collaboration)\n * in which the editor content might not return to the original state.\n *\n * This will usually happen when one or more users change the size of the table.\n *\n * As an example see the table below:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * and the user actions:\n *\n * 1. Both users have a table with two rows and two columns.\n * 2. User A adds a column at the end of the table. This will insert empty table cells to two rows.\n * 3. User B adds a row at the end of the table. This will insert a row with two empty table cells.\n * 4. Both users will have a table as below:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * The last row is shorter then others so the table post-fixer will add an empty row to the last row:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *       <td>(empty, inserted by A)</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by the post-fixer)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * Unfortunately undo does not know the nature of the changes and depending on which user applies the post-fixer changes, undoing them\n * might lead to a broken table. If User B undoes inserting the column to the table, the undo engine will undo only the operations of\n * inserting empty cells to rows from the initial table state (row 1 and 2) but the cell in the post-fixed row will remain:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by a post-fixer)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n *\n * After undo, the table post-fixer will detect that two rows are shorter than others and will fix the table to:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>\n *       <td>11</td>\n *       <td>12</td>\n *       <td>(empty, inserted by a post-fixer after undo)</td>\n *     </tr>\n *     <tr>\n *       <td>21</td>\n *       <td>22</td>\n *       <td>(empty, inserted by a post-fixer after undo)</td>\n *     </tr>\n *     <tr>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by B)</td>\n *       <td>(empty, inserted by a post-fixer)</td>\n *     </tr>\n *   </tbody>\n * </table>\n * ```\n */\nexport default function injectTableLayoutPostFixer( model: Model ): void {\n\tmodel.document.registerPostFixer( writer => tableLayoutPostFixer( writer, model ) );\n}\n\n/**\n * The table layout post-fixer.\n */\nfunction tableLayoutPostFixer( writer: Writer, model: Model ) {\n\tconst changes = model.document.differ.getChanges();\n\n\tlet wasFixed = false;\n\n\t// Do not analyze the same table more then once - may happen for multiple changes in the same table.\n\tconst analyzedTables = new Set();\n\n\tfor ( const entry of changes ) {\n\t\tlet table: Element | null = null;\n\n\t\tif ( entry.type == 'insert' && entry.name == 'table' ) {\n\t\t\ttable = entry.position.nodeAfter as Element;\n\t\t}\n\n\t\t// Fix table on adding/removing table cells and rows.\n\t\tif ( ( entry.type == 'insert' || entry.type == 'remove' ) && ( entry.name == 'tableRow' || entry.name == 'tableCell' ) ) {\n\t\t\ttable = entry.position.findAncestor( 'table' );\n\t\t}\n\n\t\t// Fix table on any table's attribute change - including attributes of table cells.\n\t\tif ( isTableAttributeEntry( entry ) ) {\n\t\t\ttable = entry.range.start.findAncestor( 'table' );\n\t\t}\n\n\t\tif ( table && !analyzedTables.has( table ) ) {\n\t\t\t// Step 1: correct rowspans of table cells if necessary.\n\t\t\t// The wasFixed flag should be true if any of tables in batch was fixed - might be more then one.\n\t\t\twasFixed = fixTableCellsRowspan( table, writer ) || wasFixed;\n\t\t\t// Step 2: fix table rows sizes.\n\t\t\twasFixed = fixTableRowsSizes( table, writer ) || wasFixed;\n\n\t\t\tanalyzedTables.add( table );\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n/**\n * Fixes the invalid value of the `rowspan` attribute because a table cell cannot vertically extend beyond the table section it belongs to.\n *\n * @returns Returns `true` if the table was fixed.\n */\nfunction fixTableCellsRowspan( table: Element, writer: Writer ) {\n\tlet wasFixed = false;\n\n\tconst cellsToTrim = findCellsToTrim( table );\n\n\tif ( cellsToTrim.length ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: trimming cells row-spans (${ cellsToTrim.length }).` );\n\n\t\twasFixed = true;\n\n\t\tfor ( const data of cellsToTrim ) {\n\t\t\tupdateNumericAttribute( 'rowspan', data.rowspan, data.cell, writer, 1 );\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n/**\n * Makes all table rows in a table the same size.\n *\n * @returns Returns `true` if the table was fixed.\n */\nfunction fixTableRowsSizes( table: Element, writer: Writer ) {\n\tlet wasFixed = false;\n\n\tconst childrenLengths = getChildrenLengths( table );\n\tconst rowsToRemove = [];\n\n\t// Find empty rows.\n\tfor ( const [ rowIndex, size ] of childrenLengths.entries() ) {\n\t\t// Ignore all non-row models.\n\t\tif ( !size && table.getChild( rowIndex )!.is( 'element', 'tableRow' ) ) {\n\t\t\trowsToRemove.push( rowIndex );\n\t\t}\n\t}\n\n\t// Remove empty rows.\n\tif ( rowsToRemove.length ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: remove empty rows (${ rowsToRemove.length }).` );\n\n\t\twasFixed = true;\n\n\t\tfor ( const rowIndex of rowsToRemove.reverse() ) {\n\t\t\twriter.remove( table.getChild( rowIndex )! );\n\t\t\tchildrenLengths.splice( rowIndex, 1 );\n\t\t}\n\t}\n\n\t// Filter out everything that's not a table row.\n\tconst rowsLengths = childrenLengths.filter( ( row, rowIndex ) => table.getChild( rowIndex )!.is( 'element', 'tableRow' ) );\n\n\t// Verify if all the rows have the same number of columns.\n\tconst tableSize = rowsLengths[ 0 ];\n\tconst isValid = rowsLengths.every( length => length === tableSize );\n\n\tif ( !isValid ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( 'Post-fixing table: adding missing cells.' );\n\n\t\t// Find the maximum number of columns.\n\t\tconst maxColumns = rowsLengths.reduce( ( prev, current ) => current > prev ? current : prev, 0 );\n\n\t\tfor ( const [ rowIndex, size ] of rowsLengths.entries() ) {\n\t\t\tconst columnsToInsert = maxColumns - size;\n\n\t\t\tif ( columnsToInsert ) {\n\t\t\t\tfor ( let i = 0; i < columnsToInsert; i++ ) {\n\t\t\t\t\tcreateEmptyTableCell( writer, writer.createPositionAt( table.getChild( rowIndex )!, 'end' ) );\n\t\t\t\t}\n\n\t\t\t\twasFixed = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n/**\n * Searches for table cells that extend beyond the table section to which they belong to. It will return an array of objects\n * that stores table cells to be trimmed and the correct value of the `rowspan` attribute to set.\n */\nfunction findCellsToTrim( table: Element ) {\n\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) as string || '0' );\n\tconst maxRows = Array.from( table.getChildren() )\n\t\t.reduce( ( count, row ) => row.is( 'element', 'tableRow' ) ? count + 1 : count, 0 );\n\n\tconst cellsToTrim = [];\n\n\tfor ( const { row, cell, cellHeight } of new TableWalker( table ) ) {\n\t\t// Skip cells that do not expand over its row.\n\t\tif ( cellHeight < 2 ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst isInHeader = row < headingRows;\n\n\t\t// Row limit is either end of header section or whole table as table body is after the header.\n\t\tconst rowLimit = isInHeader ? headingRows : maxRows;\n\n\t\t// If table cell expands over its limit reduce it height to proper value.\n\t\tif ( row + cellHeight > rowLimit ) {\n\t\t\tconst newRowspan = rowLimit - row;\n\n\t\t\tcellsToTrim.push( { cell, rowspan: newRowspan } );\n\t\t}\n\t}\n\n\treturn cellsToTrim;\n}\n\n/**\n * Returns an array with lengths of rows assigned to the corresponding row index.\n */\nfunction getChildrenLengths( table: Element ) {\n\t// TableWalker will not provide items for the empty rows, we need to pre-fill this array.\n\tconst lengths = new Array( table.childCount ).fill( 0 );\n\n\tfor ( const { rowIndex } of new TableWalker( table, { includeAllSlots: true } ) ) {\n\t\tlengths[ rowIndex ]++;\n\t}\n\n\treturn lengths;\n}\n\n/**\n * Checks if the differ entry for an attribute change is one of the table's attributes.\n */\nfunction isTableAttributeEntry( entry: DiffItem ): entry is DiffItemAttribute {\n\tif ( entry.type !== 'attribute' ) {\n\t\treturn false;\n\t}\n\n\tconst key = entry.attributeKey;\n\n\treturn key === 'headingRows' || key === 'colspan' || key === 'rowspan';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-cell-paragraph-post-fixer\n */\n\nimport type { Model, Writer, Element, DiffItemInsert, DiffItemRemove } from 'ckeditor5/src/engine.js';\n\n/**\n * Injects a table cell post-fixer into the model which inserts a `paragraph` element into empty table cells.\n *\n * A table cell must contain at least one block element as a child. An empty table cell will have an empty `paragraph` as a child.\n *\n * ```xml\n * <table>\n *   <tableRow>\n *      <tableCell></tableCell>\n *   </tableRow>\n * </table>\n * ```\n *\n * Will be fixed to:\n *\n * ```xml\n * <table>\n *   <tableRow>\n *      <tableCell><paragraph></paragraph></tableCell>\n *   </tableRow>\n * </table>\n * ```\n */\nexport default function injectTableCellParagraphPostFixer( model: Model ): void {\n\tmodel.document.registerPostFixer( writer => tableCellContentsPostFixer( writer, model ) );\n}\n\n/**\n * The table cell contents post-fixer.\n */\nfunction tableCellContentsPostFixer( writer: Writer, model: Model ) {\n\tconst changes = model.document.differ.getChanges();\n\n\tlet wasFixed = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name == 'table' ) {\n\t\t\twasFixed = fixTable( entry.position.nodeAfter as Element, writer ) || wasFixed;\n\t\t}\n\n\t\tif ( entry.type == 'insert' && entry.name == 'tableRow' ) {\n\t\t\twasFixed = fixTableRow( entry.position.nodeAfter as Element, writer ) || wasFixed;\n\t\t}\n\n\t\tif ( entry.type == 'insert' && entry.name == 'tableCell' ) {\n\t\t\twasFixed = fixTableCellContent( entry.position.nodeAfter as Element, writer ) || wasFixed;\n\t\t}\n\n\t\tif ( ( entry.type == 'remove' || entry.type == 'insert' ) && checkTableCellChange( entry ) ) {\n\t\t\twasFixed = fixTableCellContent( entry.position.parent as Element, writer ) || wasFixed;\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n/**\n * Fixes all table cells in a table.\n */\nfunction fixTable( table: Element, writer: Writer ) {\n\tlet wasFixed = false;\n\n\tfor ( const row of table.getChildren() ) {\n\t\tif ( row.is( 'element', 'tableRow' ) ) {\n\t\t\twasFixed = fixTableRow( row, writer ) || wasFixed;\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n/**\n * Fixes all table cells in a table row.\n */\nfunction fixTableRow( tableRow: Element, writer: Writer ) {\n\tlet wasFixed = false;\n\n\tfor ( const tableCell of tableRow.getChildren() as IterableIterator<Element> ) {\n\t\twasFixed = fixTableCellContent( tableCell, writer ) || wasFixed;\n\t}\n\n\treturn wasFixed;\n}\n\n/**\n * Fixes all table cell content by:\n * - Adding a paragraph to a table cell without any child.\n * - Wrapping direct $text in a `<paragraph>`.\n */\nfunction fixTableCellContent( tableCell: Element, writer: Writer ) {\n\t// Insert paragraph to an empty table cell.\n\tif ( tableCell.childCount == 0 ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( 'Post-fixing table: insert paragraph in empty cell.' );\n\n\t\twriter.insertElement( 'paragraph', tableCell );\n\n\t\treturn true;\n\t}\n\n\t// Check table cell children for directly placed text nodes.\n\t// Temporary solution. See https://github.com/ckeditor/ckeditor5/issues/1464.\n\tconst textNodes = Array.from( tableCell.getChildren() ).filter( child => child.is( '$text' ) );\n\n\t// @if CK_DEBUG_TABLE // textNodes.length && console.log( 'Post-fixing table: wrap cell content with paragraph.' );\n\n\tfor ( const child of textNodes ) {\n\t\twriter.wrap( writer.createRangeOn( child ), 'paragraph' );\n\t}\n\n\t// Return true when there were text nodes to fix.\n\treturn !!textNodes.length;\n}\n\n/**\n * Checks if a differ change should fix the table cell. This happens on:\n * - Removing content from the table cell (i.e. `tableCell` can be left empty).\n * - Adding a text node directly into a table cell.\n */\nfunction checkTableCellChange( entry: DiffItemInsert | DiffItemRemove ) {\n\tif ( !entry.position.parent.is( 'element', 'tableCell' ) ) {\n\t\treturn false;\n\t}\n\n\treturn entry.type == 'insert' && entry.name == '$text' || entry.type == 'remove';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-headings-refresh-handler\n */\n\nimport type {\n\tEditingController,\n\tElement,\n\tModel\n} from 'ckeditor5/src/engine.js';\n\nimport TableWalker from '../tablewalker.js';\n\n/**\n * A table headings refresh handler which marks the table cells or rows in the differ to have it re-rendered\n * if the headings attribute changed.\n *\n * Table heading rows and heading columns are represented in the model by a `headingRows` and `headingColumns` attributes.\n *\n * When table headings attribute changes, all the cells/rows are marked to re-render to change between `<td>` and `<th>`.\n */\nexport default function tableHeadingsRefreshHandler( model: Model, editing: EditingController ): void {\n\tconst differ = model.document.differ;\n\n\tfor ( const change of differ.getChanges() ) {\n\t\tlet table;\n\t\tlet isRowChange = false;\n\n\t\tif ( change.type == 'attribute' ) {\n\t\t\tconst element = change.range.start.nodeAfter;\n\n\t\t\tif ( !element || !element.is( 'element', 'table' ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( change.attributeKey != 'headingRows' && change.attributeKey != 'headingColumns' ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttable = element;\n\t\t\tisRowChange = change.attributeKey == 'headingRows';\n\t\t} else if ( change.name == 'tableRow' || change.name == 'tableCell' ) {\n\t\t\ttable = change.position.findAncestor( 'table' );\n\t\t\tisRowChange = change.name == 'tableRow';\n\t\t}\n\n\t\tif ( !table ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst headingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) as number || 0;\n\n\t\tconst tableWalker = new TableWalker( table );\n\n\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\tconst isHeading = tableSlot.row < headingRows || tableSlot.column < headingColumns;\n\t\t\tconst expectedElementName = isHeading ? 'th' : 'td';\n\n\t\t\tconst viewElement = editing.mapper.toViewElement( tableSlot.cell );\n\n\t\t\tif ( viewElement && viewElement.is( 'element' ) && viewElement.name != expectedElementName ) {\n\t\t\t\tediting.reconvertItem( ( isRowChange ? tableSlot.cell.parent : tableSlot.cell ) as Element );\n\t\t\t}\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-cell-refresh-handler\n */\n\nimport type {\n\tEditingController,\n\tElement,\n\tMapper,\n\tModel\n} from 'ckeditor5/src/engine.js';\n\nimport { isSingleParagraphWithoutAttributes } from './downcast.js';\n\n/**\n * A table cell refresh handler which marks the table cell in the differ to have it re-rendered.\n *\n * Model `paragraph` inside a table cell can be rendered as `<span>` or `<p>`. It is rendered as `<span>` if this is the only block\n * element in that table cell and it does not have any attributes. It is rendered as `<p>` otherwise.\n *\n * When table cell content changes, for example a second `paragraph` element is added, we need to ensure that the first `paragraph` is\n * re-rendered so it changes from `<span>` to `<p>`. The easiest way to do it is to re-render the entire table cell.\n */\nexport default function tableCellRefreshHandler( model: Model, editing: EditingController ): void {\n\tconst differ = model.document.differ;\n\n\t// Stores cells to be refreshed, so the table cell will be refreshed once for multiple changes.\n\tconst cellsToCheck = new Set();\n\n\tfor ( const change of differ.getChanges() ) {\n\t\tconst parent = change.type == 'attribute' ? change.range.start.parent : change.position.parent;\n\n\t\tif ( parent.is( 'element', 'tableCell' ) ) {\n\t\t\tcellsToCheck.add( parent );\n\t\t}\n\t}\n\n\tfor ( const tableCell of cellsToCheck.values() as Iterable<Element> ) {\n\t\tconst paragraphsToRefresh = Array.from( tableCell.getChildren() )\n\t\t\t.filter( child => shouldRefresh( child as Element, editing.mapper ) );\n\n\t\tfor ( const paragraph of paragraphsToRefresh ) {\n\t\t\tediting.reconvertItem( paragraph );\n\t\t}\n\t}\n}\n\n/**\n * Check if given model element needs refreshing.\n */\nfunction shouldRefresh( child: Element, mapper: Mapper ) {\n\tif ( !child.is( 'element', 'paragraph' ) ) {\n\t\treturn false;\n\t}\n\n\tconst viewElement = mapper.toViewElement( child );\n\n\tif ( !viewElement ) {\n\t\treturn false;\n\t}\n\n\treturn isSingleParagraphWithoutAttributes( child ) !== viewElement.is( 'element', 'span' );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableediting\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport type { PositionOffset, ViewElement, SlotFilter } from 'ckeditor5/src/engine.js';\n\nimport upcastTable, { ensureParagraphInTableCell, skipEmptyTableRow, upcastTableFigure } from './converters/upcasttable.js';\nimport { convertParagraphInTableCell, downcastCell, downcastRow, downcastTable } from './converters/downcast.js';\n\nimport InsertTableCommand from './commands/inserttablecommand.js';\nimport InsertRowCommand from './commands/insertrowcommand.js';\nimport InsertColumnCommand from './commands/insertcolumncommand.js';\nimport SplitCellCommand from './commands/splitcellcommand.js';\nimport MergeCellCommand from './commands/mergecellcommand.js';\nimport RemoveRowCommand from './commands/removerowcommand.js';\nimport RemoveColumnCommand from './commands/removecolumncommand.js';\nimport SetHeaderRowCommand from './commands/setheaderrowcommand.js';\nimport SetHeaderColumnCommand from './commands/setheadercolumncommand.js';\nimport MergeCellsCommand from './commands/mergecellscommand.js';\nimport SelectRowCommand from './commands/selectrowcommand.js';\nimport SelectColumnCommand from './commands/selectcolumncommand.js';\nimport TableUtils from '../src/tableutils.js';\n\nimport injectTableLayoutPostFixer from './converters/table-layout-post-fixer.js';\nimport injectTableCellParagraphPostFixer from './converters/table-cell-paragraph-post-fixer.js';\n\nimport tableHeadingsRefreshHandler from './converters/table-headings-refresh-handler.js';\nimport tableCellRefreshHandler from './converters/table-cell-refresh-handler.js';\n\nimport '../theme/tableediting.css';\n\n/**\n * The table editing feature.\n */\nexport default class TableEditing extends Plugin {\n\t/**\n\t * Handlers for creating additional slots in the table.\n\t */\n\tprivate _additionalSlots: Array<AdditionalSlot>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._additionalSlots = [];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst schema = model.schema;\n\t\tconst conversion = editor.conversion;\n\t\tconst tableUtils = editor.plugins.get( TableUtils );\n\n\t\tschema.register( 'table', {\n\t\t\tinheritAllFrom: '$blockObject',\n\t\t\tallowAttributes: [ 'headingRows', 'headingColumns' ]\n\t\t} );\n\n\t\tschema.register( 'tableRow', {\n\t\t\tallowIn: 'table',\n\t\t\tisLimit: true\n\t\t} );\n\n\t\tschema.register( 'tableCell', {\n\t\t\tallowContentOf: '$container',\n\t\t\tallowIn: 'tableRow',\n\t\t\tallowAttributes: [ 'colspan', 'rowspan' ],\n\t\t\tisLimit: true,\n\t\t\tisSelectable: true\n\t\t} );\n\n\t\t// Figure conversion.\n\t\tconversion.for( 'upcast' ).add( upcastTableFigure() );\n\n\t\t// Table conversion.\n\t\tconversion.for( 'upcast' ).add( upcastTable() );\n\n\t\tconversion.for( 'editingDowncast' ).elementToStructure( {\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tattributes: [ 'headingRows' ]\n\t\t\t},\n\t\t\tview: downcastTable( tableUtils, {\n\t\t\t\tasWidget: true,\n\t\t\t\tadditionalSlots: this._additionalSlots\n\t\t\t} )\n\t\t} );\n\t\tconversion.for( 'dataDowncast' ).elementToStructure( {\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tattributes: [ 'headingRows' ]\n\t\t\t},\n\t\t\tview: downcastTable( tableUtils, {\n\t\t\t\tadditionalSlots: this._additionalSlots\n\t\t\t} )\n\t\t} );\n\n\t\t// Table row conversion.\n\t\tconversion.for( 'upcast' ).elementToElement( { model: 'tableRow', view: 'tr' } );\n\t\tconversion.for( 'upcast' ).add( skipEmptyTableRow() );\n\n\t\tconversion.for( 'downcast' ).elementToElement( {\n\t\t\tmodel: 'tableRow',\n\t\t\tview: downcastRow()\n\t\t} );\n\n\t\t// Table cell conversion.\n\t\tconversion.for( 'upcast' ).elementToElement( { model: 'tableCell', view: 'td' } );\n\t\tconversion.for( 'upcast' ).elementToElement( { model: 'tableCell', view: 'th' } );\n\t\tconversion.for( 'upcast' ).add( ensureParagraphInTableCell( 'td' ) );\n\t\tconversion.for( 'upcast' ).add( ensureParagraphInTableCell( 'th' ) );\n\n\t\tconversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'tableCell',\n\t\t\tview: downcastCell( { asWidget: true } )\n\t\t} );\n\t\tconversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\tmodel: 'tableCell',\n\t\t\tview: downcastCell()\n\t\t} );\n\n\t\t// Duplicates code - needed to properly refresh paragraph inside a table cell.\n\t\tconversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'paragraph',\n\t\t\tview: convertParagraphInTableCell( { asWidget: true } ),\n\t\t\tconverterPriority: 'high'\n\t\t} );\n\t\tconversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\tmodel: 'paragraph',\n\t\t\tview: convertParagraphInTableCell(),\n\t\t\tconverterPriority: 'high'\n\t\t} );\n\n\t\t// Table attributes conversion.\n\t\tconversion.for( 'downcast' ).attributeToAttribute( { model: 'colspan', view: 'colspan' } );\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tmodel: { key: 'colspan', value: upcastCellSpan( 'colspan' ) },\n\t\t\tview: 'colspan'\n\t\t} );\n\n\t\tconversion.for( 'downcast' ).attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tmodel: { key: 'rowspan', value: upcastCellSpan( 'rowspan' ) },\n\t\t\tview: 'rowspan'\n\t\t} );\n\n\t\t// Define the config.\n\t\teditor.config.define( 'table.defaultHeadings.rows', 0 );\n\t\teditor.config.define( 'table.defaultHeadings.columns', 0 );\n\n\t\t// Define all the commands.\n\t\teditor.commands.add( 'insertTable', new InsertTableCommand( editor ) );\n\t\teditor.commands.add( 'insertTableRowAbove', new InsertRowCommand( editor, { order: 'above' } ) );\n\t\teditor.commands.add( 'insertTableRowBelow', new InsertRowCommand( editor, { order: 'below' } ) );\n\t\teditor.commands.add( 'insertTableColumnLeft', new InsertColumnCommand( editor, { order: 'left' } ) );\n\t\teditor.commands.add( 'insertTableColumnRight', new InsertColumnCommand( editor, { order: 'right' } ) );\n\n\t\teditor.commands.add( 'removeTableRow', new RemoveRowCommand( editor ) );\n\t\teditor.commands.add( 'removeTableColumn', new RemoveColumnCommand( editor ) );\n\n\t\teditor.commands.add( 'splitTableCellVertically', new SplitCellCommand( editor, { direction: 'vertically' } ) );\n\t\teditor.commands.add( 'splitTableCellHorizontally', new SplitCellCommand( editor, { direction: 'horizontally' } ) );\n\n\t\teditor.commands.add( 'mergeTableCells', new MergeCellsCommand( editor ) );\n\n\t\teditor.commands.add( 'mergeTableCellRight', new MergeCellCommand( editor, { direction: 'right' } ) );\n\t\teditor.commands.add( 'mergeTableCellLeft', new MergeCellCommand( editor, { direction: 'left' } ) );\n\t\teditor.commands.add( 'mergeTableCellDown', new MergeCellCommand( editor, { direction: 'down' } ) );\n\t\teditor.commands.add( 'mergeTableCellUp', new MergeCellCommand( editor, { direction: 'up' } ) );\n\n\t\teditor.commands.add( 'setTableColumnHeader', new SetHeaderColumnCommand( editor ) );\n\t\teditor.commands.add( 'setTableRowHeader', new SetHeaderRowCommand( editor ) );\n\n\t\teditor.commands.add( 'selectTableRow', new SelectRowCommand( editor ) );\n\t\teditor.commands.add( 'selectTableColumn', new SelectColumnCommand( editor ) );\n\n\t\tinjectTableLayoutPostFixer( model );\n\t\tinjectTableCellParagraphPostFixer( model );\n\n\t\tthis.listenTo( model.document, 'change:data', () => {\n\t\t\ttableHeadingsRefreshHandler( model, editor.editing );\n\t\t\ttableCellRefreshHandler( model, editor.editing );\n\t\t} );\n\t}\n\n\t/**\n\t * Registers downcast handler for the additional table slot.\n\t */\n\tpublic registerAdditionalSlot( slotHandler: AdditionalSlot ): void {\n\t\tthis._additionalSlots.push( slotHandler );\n\t}\n}\n\n/**\n * Returns fixed colspan and rowspan attrbutes values.\n *\n * @param type colspan or rowspan.\n * @returns conversion value function.\n */\nfunction upcastCellSpan( type: string ) {\n\treturn ( cell: ViewElement ) => {\n\t\tconst span = parseInt( cell.getAttribute( type )! );\n\n\t\tif ( Number.isNaN( span ) || span <= 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn span;\n\t};\n}\n\n/**\n * By default, only the `tableRow` elements from the `table` model are downcast inside the `<table>` and\n * all other elements are pushed outside the table. This handler allows creating additional slots inside\n * the table for other elements.\n *\n * Take this model as an example:\n *\n * ```xml\n * <table>\n *   <tableRow>...</tableRow>\n *   <tableRow>...</tableRow>\n *   <tableColumnGroup>...</tableColumnGroup>\n * </table>\n * ```\n *\n * By default, downcasting result will be:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>...</tr>\n *     <tr>...</tr>\n *   </tbody>\n * </table>\n * <colgroup>...</colgroup>\n * ```\n *\n * To allow the `tableColumnGroup` element at the end of the table, use the following configuration:\n *\n * ```ts\n * const additionalSlot = {\n *   filter: element => element.is( 'element', 'tableColumnGroup' ),\n *   positionOffset: 'end'\n * }\n * ```\n *\n * Now, the downcast result will be:\n *\n * ```xml\n * <table>\n *   <tbody>\n *     <tr>...</tr>\n *     <tr>...</tr>\n *   </tbody>\n *   <colgroup>...</colgroup>\n * </table>\n * ```\n */\nexport interface AdditionalSlot {\n\n\t/**\n\t * Filter for elements that should be placed inside given slot.\n\t */\n\tfilter: SlotFilter;\n\n\t/**\n\t * Position of the slot within the table.\n\t */\n\tpositionOffset: PositionOffset;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/ui/inserttableview\n */\n\nimport { View, ButtonView, addKeyboardHandlingForGrid, type ViewCollection } from 'ckeditor5/src/ui.js';\n\nimport { KeystrokeHandler, FocusTracker, type Locale } from 'ckeditor5/src/utils.js';\n\nimport './../../theme/inserttable.css';\n\n/**\n * The table size view.\n *\n * It renders a 10x10 grid to choose the inserted table size.\n */\nexport default class InsertTableView extends View {\n\t/**\n\t * A collection of table size box items.\n\t */\n\tpublic readonly items: ViewCollection<ButtonView>;\n\n\t/**\n\t * Listen to `keydown` events fired in this view's main element.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * Tracks information about the DOM focus in the grid.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * The currently selected number of rows of the new table.\n\t *\n\t * @observable\n\t */\n\tdeclare public rows: number;\n\n\t/**\n\t * The currently selected number of columns of the new table.\n\t *\n\t * @observable\n\t */\n\tdeclare public columns: number;\n\n\t/**\n\t * The label text displayed under the boxes.\n\t *\n\t * @observable\n\t */\n\tdeclare public label: string;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale: Locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\t\tthis.items = this._createGridCollection();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.set( 'rows', 0 );\n\t\tthis.set( 'columns', 0 );\n\t\tthis.bind( 'label' ).to( this, 'columns', this, 'rows', ( columns, rows ) => `${ rows } × ${ columns }` );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck' ]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [ 'ck-insert-table-dropdown__grid' ]\n\t\t\t\t\t},\n\t\t\t\t\ton: {\n\t\t\t\t\t\t'mouseover@.ck-insert-table-dropdown-grid-box': bind.to( 'boxover' )\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.items\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-insert-table-dropdown__label'\n\t\t\t\t\t\t],\n\t\t\t\t\t\t'aria-hidden': true\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttext: bind.to( 'label' )\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t],\n\n\t\t\ton: {\n\t\t\t\tmousedown: bind.to( evt => {\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} ),\n\n\t\t\t\tclick: bind.to( () => {\n\t\t\t\t\tthis.fire( 'execute' );\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\n\t\t// #rows and #columns are set via changes to #focusTracker on mouse over.\n\t\tthis.on( 'boxover', ( evt, domEvt ) => {\n\t\t\tconst { row, column } = domEvt.target.dataset;\n\t\t\tthis.items.get( ( parseInt( row, 10 ) - 1 ) * 10 + ( parseInt( column, 10 ) - 1 ) )!.focus();\n\t\t} );\n\n\t\t// This allows the #rows and #columns to be updated when:\n\t\t// * the user navigates the grid using the keyboard,\n\t\t// * the user moves the mouse over grid items.\n\t\tthis.focusTracker.on( 'change:focusedElement', ( evt, name, focusedElement ) => {\n\t\t\tif ( !focusedElement ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { row, column } = focusedElement.dataset;\n\n\t\t\t// As row & column indexes are zero-based transform it to number of selected rows & columns.\n\t\t\tthis.set( {\n\t\t\t\trows: parseInt( row ),\n\t\t\t\tcolumns: parseInt( column )\n\t\t\t} );\n\t\t} );\n\n\t\tthis.on( 'change:columns', () => this._highlightGridBoxes() );\n\t\tthis.on( 'change:rows', () => this._highlightGridBoxes() );\n\t}\n\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\taddKeyboardHandlingForGrid( {\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tgridItems: this.items,\n\t\t\tnumberOfColumns: 10,\n\t\t\tuiLanguageDirection: this.locale && this.locale.uiLanguageDirection\n\t\t} );\n\n\t\tfor ( const item of this.items ) {\n\t\t\tthis.focusTracker.add( item.element! );\n\t\t}\n\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * Resets the rows and columns selection.\n\t */\n\tpublic reset(): void {\n\t\tthis.set( {\n\t\t\trows: 1,\n\t\t\tcolumns: 1\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focus(): void {\n\t\tthis.items.get( 0 )!.focus();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic focusLast(): void {\n\t\tthis.items.get( 0 )!.focus();\n\t}\n\n\t/**\n\t * Highlights grid boxes depending on rows and columns selected.\n\t */\n\tprivate _highlightGridBoxes() {\n\t\tconst rows = this.rows;\n\t\tconst columns = this.columns;\n\n\t\tthis.items.map( ( boxView, index ) => {\n\t\t\t// Translate box index to the row & column index.\n\t\t\tconst itemRow = Math.floor( index / 10 );\n\t\t\tconst itemColumn = index % 10;\n\n\t\t\t// Grid box is highlighted when its row & column index belongs to selected number of rows & columns.\n\t\t\tconst isOn = itemRow < rows && itemColumn < columns;\n\n\t\t\tboxView.set( 'isOn', isOn );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a new Button for the grid.\n\t *\n\t * @param locale The locale instance.\n\t * @param row Row number.\n\t * @param column Column number.\n\t * @param label The grid button label.\n\t */\n\tprivate _createGridButton( locale: Locale, row: number, column: number, label: string ): ButtonView {\n\t\tconst button = new ButtonView( locale );\n\n\t\tbutton.set( {\n\t\t\tlabel,\n\t\t\tclass: 'ck-insert-table-dropdown-grid-box'\n\t\t} );\n\n\t\tbutton.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\t'data-row': row,\n\t\t\t\t'data-column': column\n\t\t\t}\n\t\t} );\n\n\t\treturn button;\n\t}\n\n\t/**\n\t * @returns A view collection containing boxes to be placed in a table grid.\n\t */\n\tprivate _createGridCollection() {\n\t\tconst boxes = [];\n\n\t\t// Add grid boxes to table selection view.\n\t\tfor ( let index = 0; index < 100; index++ ) {\n\t\t\tconst row = Math.floor( index / 10 );\n\t\t\tconst column = index % 10;\n\t\t\tconst label = `${ row + 1 } × ${ column + 1 }`;\n\n\t\t\tboxes.push( this._createGridButton( this.locale!, row + 1, column + 1, label ) );\n\t\t}\n\n\t\treturn this.createCollection( boxes );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableui\n */\n\nimport { icons, Plugin, type Command, type Editor } from 'ckeditor5/src/core.js';\nimport {\n\taddListToDropdown,\n\tcreateDropdown,\n\tViewModel,\n\tSplitButtonView,\n\tSwitchButtonView,\n\ttype DropdownView,\n\ttype ListDropdownItemDefinition,\n\tMenuBarMenuView\n} from 'ckeditor5/src/ui.js';\nimport { Collection, type ObservableChangeEvent, type Locale } from 'ckeditor5/src/utils.js';\n\nimport InsertTableView from './ui/inserttableview.js';\n\nimport tableColumnIcon from './../theme/icons/table-column.svg';\nimport tableRowIcon from './../theme/icons/table-row.svg';\nimport tableMergeCellIcon from './../theme/icons/table-merge-cell.svg';\nimport type InsertTableCommand from './commands/inserttablecommand.js';\nimport type MergeCellsCommand from './commands/mergecellscommand.js';\n\n/**\n * The table UI plugin. It introduces:\n *\n * * The `'insertTable'` dropdown,\n * * The `'menuBar:insertTable'` menu bar menu,\n * * The `'tableColumn'` dropdown,\n * * The `'tableRow'` dropdown,\n * * The `'mergeTableCells'` split button.\n *\n * The `'tableColumn'`, `'tableRow'` and `'mergeTableCells'` dropdowns work best with {@link module:table/tabletoolbar~TableToolbar}.\n */\nexport default class TableUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\t\tconst contentLanguageDirection = editor.locale.contentLanguageDirection;\n\t\tconst isContentLtr = contentLanguageDirection === 'ltr';\n\n\t\teditor.ui.componentFactory.add( 'insertTable', locale => {\n\t\t\tconst command: InsertTableCommand = editor.commands.get( 'insertTable' )!;\n\t\t\tconst dropdownView = createDropdown( locale );\n\n\t\t\tdropdownView.bind( 'isEnabled' ).to( command );\n\n\t\t\t// Decorate dropdown's button.\n\t\t\tdropdownView.buttonView.set( {\n\t\t\t\ticon: icons.table,\n\t\t\t\tlabel: t( 'Insert table' ),\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tlet insertTableView: InsertTableView;\n\n\t\t\tdropdownView.on( 'change:isOpen', () => {\n\t\t\t\tif ( insertTableView ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Prepare custom view for dropdown's panel.\n\t\t\t\tinsertTableView = new InsertTableView( locale );\n\t\t\t\tdropdownView.panelView.children.add( insertTableView );\n\n\t\t\t\tinsertTableView.delegate( 'execute' ).to( dropdownView );\n\n\t\t\t\tdropdownView.on( 'execute', () => {\n\t\t\t\t\teditor.execute( 'insertTable', { rows: insertTableView.rows, columns: insertTableView.columns } );\n\t\t\t\t\teditor.editing.view.focus();\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\treturn dropdownView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'menuBar:insertTable', locale => {\n\t\t\tconst command: InsertTableCommand = editor.commands.get( 'insertTable' )!;\n\t\t\tconst menuView = new MenuBarMenuView( locale );\n\t\t\tconst insertTableView = new InsertTableView( locale );\n\n\t\t\tinsertTableView.delegate( 'execute' ).to( menuView );\n\n\t\t\tmenuView.on<ObservableChangeEvent<boolean>>( 'change:isOpen', ( event, name, isOpen ) => {\n\t\t\t\tif ( !isOpen ) {\n\t\t\t\t\tinsertTableView.reset();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tinsertTableView.on( 'execute', () => {\n\t\t\t\teditor.execute( 'insertTable', { rows: insertTableView.rows, columns: insertTableView.columns } );\n\t\t\t\teditor.editing.view.focus();\n\t\t\t} );\n\n\t\t\tmenuView.buttonView.set( {\n\t\t\t\tlabel: t( 'Table' ),\n\t\t\t\ticon: icons.table\n\t\t\t} );\n\n\t\t\tmenuView.panelView.children.add( insertTableView );\n\n\t\t\tmenuView.bind( 'isEnabled' ).to( command );\n\n\t\t\treturn menuView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'tableColumn', locale => {\n\t\t\tconst options = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'switchbutton',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'setTableColumnHeader',\n\t\t\t\t\t\tlabel: t( 'Header column' ),\n\t\t\t\t\t\tbindIsOn: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ type: 'separator' },\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'insertTableColumnLeft' : 'insertTableColumnRight',\n\t\t\t\t\t\tlabel: t( 'Insert column left' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'insertTableColumnRight' : 'insertTableColumnLeft',\n\t\t\t\t\t\tlabel: t( 'Insert column right' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'removeTableColumn',\n\t\t\t\t\t\tlabel: t( 'Delete column' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'selectTableColumn',\n\t\t\t\t\t\tlabel: t( 'Select column' )\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t] as Array<ListDropdownItemDefinition>;\n\n\t\t\treturn this._prepareDropdown( t( 'Column' ), tableColumnIcon, options, locale );\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'tableRow', locale => {\n\t\t\tconst options = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'switchbutton',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'setTableRowHeader',\n\t\t\t\t\t\tlabel: t( 'Header row' ),\n\t\t\t\t\t\tbindIsOn: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ type: 'separator' },\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'insertTableRowAbove',\n\t\t\t\t\t\tlabel: t( 'Insert row above' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'insertTableRowBelow',\n\t\t\t\t\t\tlabel: t( 'Insert row below' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'removeTableRow',\n\t\t\t\t\t\tlabel: t( 'Delete row' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'selectTableRow',\n\t\t\t\t\t\tlabel: t( 'Select row' )\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t] as Array<ListDropdownItemDefinition>;\n\n\t\t\treturn this._prepareDropdown( t( 'Row' ), tableRowIcon, options, locale );\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'mergeTableCells', locale => {\n\t\t\tconst options = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'mergeTableCellUp',\n\t\t\t\t\t\tlabel: t( 'Merge cell up' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'mergeTableCellRight' : 'mergeTableCellLeft',\n\t\t\t\t\t\tlabel: t( 'Merge cell right' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'mergeTableCellDown',\n\t\t\t\t\t\tlabel: t( 'Merge cell down' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'mergeTableCellLeft' : 'mergeTableCellRight',\n\t\t\t\t\t\tlabel: t( 'Merge cell left' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ type: 'separator' },\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'splitTableCellVertically',\n\t\t\t\t\t\tlabel: t( 'Split cell vertically' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'splitTableCellHorizontally',\n\t\t\t\t\t\tlabel: t( 'Split cell horizontally' )\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t] as Array<ListDropdownItemDefinition>;\n\n\t\t\treturn this._prepareMergeSplitButtonDropdown( t( 'Merge cells' ), tableMergeCellIcon, options, locale );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a dropdown view from a set of options.\n\t *\n\t * @param label The dropdown button label.\n\t * @param icon An icon for the dropdown button.\n\t * @param options The list of options for the dropdown.\n\t */\n\tprivate _prepareDropdown( label: string, icon: string, options: Array<ListDropdownItemDefinition>, locale: Locale ) {\n\t\tconst editor = this.editor;\n\t\tconst dropdownView = createDropdown( locale );\n\t\tconst commands = this._fillDropdownWithListOptions( dropdownView, options );\n\n\t\t// Decorate dropdown's button.\n\t\tdropdownView.buttonView.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\t// Make dropdown button disabled when all options are disabled.\n\t\tdropdownView.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => {\n\t\t\treturn areEnabled.some( isEnabled => isEnabled );\n\t\t} );\n\n\t\tthis.listenTo( dropdownView, 'execute', evt => {\n\t\t\teditor.execute( ( evt.source as any ).commandName );\n\n\t\t\t// Toggling a switch button view should not move the focus to the editable.\n\t\t\tif ( !( evt.source instanceof SwitchButtonView ) ) {\n\t\t\t\teditor.editing.view.focus();\n\t\t\t}\n\t\t} );\n\n\t\treturn dropdownView;\n\t}\n\n\t/**\n\t * Creates a dropdown view with a {@link module:ui/dropdown/button/splitbuttonview~SplitButtonView} for\n\t * merge (and split)–related commands.\n\t *\n\t * @param label The dropdown button label.\n\t * @param icon An icon for the dropdown button.\n\t * @param options The list of options for the dropdown.\n\t */\n\tprivate _prepareMergeSplitButtonDropdown( label: string, icon: string, options: Array<ListDropdownItemDefinition>, locale: Locale ) {\n\t\tconst editor = this.editor;\n\t\tconst dropdownView = createDropdown( locale, SplitButtonView );\n\t\tconst mergeCommandName = 'mergeTableCells';\n\n\t\t// Main command.\n\t\tconst mergeCommand: MergeCellsCommand = editor.commands.get( mergeCommandName )!;\n\n\t\t// Subcommands in the dropdown.\n\t\tconst commands = this._fillDropdownWithListOptions( dropdownView, options );\n\n\t\tdropdownView.buttonView.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true,\n\t\t\tisEnabled: true\n\t\t} );\n\n\t\t// Make dropdown button disabled when all options are disabled together with the main command.\n\t\tdropdownView.bind( 'isEnabled' ).toMany( [ mergeCommand, ...commands ], 'isEnabled', ( ...areEnabled ) => {\n\t\t\treturn areEnabled.some( isEnabled => isEnabled );\n\t\t} );\n\n\t\t// Merge selected table cells when the main part of the split button is clicked.\n\t\tthis.listenTo( dropdownView.buttonView, 'execute', () => {\n\t\t\teditor.execute( mergeCommandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\t// Execute commands for events coming from the list in the dropdown panel.\n\t\tthis.listenTo( dropdownView, 'execute', evt => {\n\t\t\teditor.execute( ( evt.source as any ).commandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn dropdownView;\n\t}\n\n\t/**\n\t * Injects a {@link module:ui/list/listview~ListView} into the passed dropdown with buttons\n\t * which execute editor commands as configured in passed options.\n\t *\n\t * @param options The list of options for the dropdown.\n\t * @returns Commands the list options are interacting with.\n\t */\n\tprivate _fillDropdownWithListOptions( dropdownView: DropdownView, options: Array<ListDropdownItemDefinition> ) {\n\t\tconst editor = this.editor;\n\t\tconst commands: Array<Command> = [];\n\t\tconst itemDefinitions = new Collection<ListDropdownItemDefinition>();\n\n\t\tfor ( const option of options ) {\n\t\t\taddListOption( option, editor, commands, itemDefinitions );\n\t\t}\n\n\t\taddListToDropdown( dropdownView, itemDefinitions );\n\n\t\treturn commands;\n\t}\n}\n\n/**\n * Adds an option to a list view.\n *\n * @param option A configuration option.\n * @param commands The list of commands to update.\n * @param itemDefinitions A collection of dropdown items to update with the given option.\n */\nfunction addListOption(\n\toption: ListDropdownItemDefinition,\n\teditor: Editor,\n\tcommands: Array<Command>,\n\titemDefinitions: Collection<ListDropdownItemDefinition>\n) {\n\tif ( option.type === 'button' || option.type === 'switchbutton' ) {\n\t\tconst model = option.model = new ViewModel( option.model );\n\t\tconst { commandName, bindIsOn } = option.model;\n\t\tconst command = editor.commands.get( commandName as string )!;\n\n\t\tcommands.push( command );\n\n\t\tmodel.set( { commandName } );\n\n\t\tmodel.bind( 'isEnabled' ).to( command );\n\n\t\tif ( bindIsOn ) {\n\t\t\tmodel.bind( 'isOn' ).to( command, 'value' );\n\t\t}\n\n\t\tmodel.set( {\n\t\t\twithText: true\n\t\t} );\n\t}\n\n\titemDefinitions.add( option );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableselection\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { type EventInfo, first } from 'ckeditor5/src/utils.js';\n\nimport type {\n\tElement,\n\tDocumentFragment,\n\tSelection,\n\tDowncastWriter,\n\tViewElement,\n\tModelDeleteContentEvent\n} from 'ckeditor5/src/engine.js';\n\nimport type {\n\tViewDocumentInsertTextEvent,\n\tInsertTextEventData\n} from 'ckeditor5/src/typing.js';\n\nimport TableWalker from './tablewalker.js';\nimport TableUtils from './tableutils.js';\n\nimport { cropTableToDimensions, adjustLastRowIndex, adjustLastColumnIndex } from './utils/structure.js';\n\nimport '../theme/tableselection.css';\n\n/**\n * This plugin enables the advanced table cells, rows and columns selection.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */\nexport default class TableSelection extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableSelection' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableUtils, TableUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst view = editor.editing.view;\n\n\t\tthis.listenTo<ModelDeleteContentEvent>(\n\t\t\tmodel,\n\t\t\t'deleteContent',\n\t\t\t( evt, args ) => this._handleDeleteContent( evt, args ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\n\t\tthis.listenTo<ViewDocumentInsertTextEvent>(\n\t\t\tview.document,\n\t\t\t'insertText',\n\t\t\t( evt, data ) => this._handleInsertTextEvent( evt, data ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\n\t\tthis._defineSelectionConverter();\n\t\tthis._enablePluginDisabling(); // sic!\n\t}\n\n\t/**\n\t * Returns the currently selected table cells or `null` if it is not a table cells selection.\n\t */\n\tpublic getSelectedTableCells(): Array<Element> | null {\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\t\tconst selection = this.editor.model.document.selection;\n\n\t\tconst selectedCells = tableUtils.getSelectedTableCells( selection );\n\n\t\tif ( selectedCells.length == 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// This should never happen, but let's know if it ever happens.\n\t\t// @if CK_DEBUG //\tif ( selectedCells.length != selection.rangeCount ) {\n\t\t// @if CK_DEBUG //\t\tconsole.warn( 'Mixed selection warning. The selection contains table cells and some other ranges.' );\n\t\t// @if CK_DEBUG //\t}\n\n\t\treturn selectedCells;\n\t}\n\n\t/**\n\t * Returns the selected table fragment as a document fragment.\n\t */\n\tpublic getSelectionAsFragment(): DocumentFragment | null {\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\t\tconst selectedCells = this.getSelectedTableCells();\n\n\t\tif ( !selectedCells ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.editor.model.change( writer => {\n\t\t\tconst documentFragment = writer.createDocumentFragment();\n\n\t\t\tconst { first: firstColumn, last: lastColumn } = tableUtils.getColumnIndexes( selectedCells );\n\t\t\tconst { first: firstRow, last: lastRow } = tableUtils.getRowIndexes( selectedCells );\n\n\t\t\tconst sourceTable = selectedCells[ 0 ].findAncestor( 'table' )!;\n\n\t\t\tlet adjustedLastRow = lastRow;\n\t\t\tlet adjustedLastColumn = lastColumn;\n\n\t\t\t// If the selection is rectangular there could be a case of all cells in the last row/column spanned over\n\t\t\t// next row/column so the real lastRow/lastColumn should be updated.\n\t\t\tif ( tableUtils.isSelectionRectangular( selectedCells ) ) {\n\t\t\t\tconst dimensions = {\n\t\t\t\t\tfirstColumn,\n\t\t\t\t\tlastColumn,\n\t\t\t\t\tfirstRow,\n\t\t\t\t\tlastRow\n\t\t\t\t};\n\n\t\t\t\tadjustedLastRow = adjustLastRowIndex( sourceTable, dimensions );\n\t\t\t\tadjustedLastColumn = adjustLastColumnIndex( sourceTable, dimensions );\n\t\t\t}\n\n\t\t\tconst cropDimensions = {\n\t\t\t\tstartRow: firstRow,\n\t\t\t\tstartColumn: firstColumn,\n\t\t\t\tendRow: adjustedLastRow,\n\t\t\t\tendColumn: adjustedLastColumn\n\t\t\t};\n\n\t\t\tconst table = cropTableToDimensions( sourceTable, cropDimensions, writer );\n\t\t\twriter.insert( table, documentFragment, 0 );\n\n\t\t\treturn documentFragment;\n\t\t} );\n\t}\n\n\t/**\n\t * Sets the model selection based on given anchor and target cells (can be the same cell).\n\t * Takes care of setting the backward flag.\n\t *\n\t * ```ts\n\t * const modelRoot = editor.model.document.getRoot();\n\t * const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );\n\t * const lastCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );\n\t *\n\t * const tableSelection = editor.plugins.get( 'TableSelection' );\n\t * tableSelection.setCellSelection( firstCell, lastCell );\n\t * ```\n\t */\n\tpublic setCellSelection( anchorCell: Element, targetCell: Element ): void {\n\t\tconst cellsToSelect = this._getCellsToSelect( anchorCell, targetCell );\n\n\t\tthis.editor.model.change( writer => {\n\t\t\twriter.setSelection(\n\t\t\t\tcellsToSelect.cells.map( cell => writer.createRangeOn( cell ) ),\n\t\t\t\t{ backward: cellsToSelect.backward }\n\t\t\t);\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the focus cell from the current selection.\n\t */\n\tpublic getFocusCell(): Element | null {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst focusCellRange = [ ...selection.getRanges() ].pop()!;\n\t\tconst element = focusCellRange.getContainedElement();\n\n\t\tif ( element && element.is( 'element', 'tableCell' ) ) {\n\t\t\treturn element;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns the anchor cell from the current selection.\n\t */\n\tpublic getAnchorCell(): Element | null {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst anchorCellRange = first( selection.getRanges() )!;\n\t\tconst element = anchorCellRange.getContainedElement();\n\n\t\tif ( element && element.is( 'element', 'tableCell' ) ) {\n\t\t\treturn element;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Defines a selection converter which marks the selected cells with a specific class.\n\t *\n\t * The real DOM selection is put in the last cell. Since the order of ranges is dependent on whether the\n\t * selection is backward or not, the last cell will usually be close to the \"focus\" end of the selection\n\t * (a selection has anchor and focus).\n\t *\n\t * The real DOM selection is then hidden with CSS.\n\t */\n\tprivate _defineSelectionConverter() {\n\t\tconst editor = this.editor;\n\t\tconst highlighted: Set<ViewElement> = new Set();\n\n\t\teditor.conversion.for( 'editingDowncast' ).add( dispatcher => dispatcher.on( 'selection', ( evt, data, conversionApi ) => {\n\t\t\tconst viewWriter = conversionApi.writer;\n\n\t\t\tclearHighlightedTableCells( viewWriter );\n\n\t\t\tconst selectedCells = this.getSelectedTableCells();\n\n\t\t\tif ( !selectedCells ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor ( const tableCell of selectedCells ) {\n\t\t\t\tconst viewElement = conversionApi.mapper.toViewElement( tableCell )!;\n\n\t\t\t\tviewWriter.addClass( 'ck-editor__editable_selected', viewElement );\n\t\t\t\thighlighted.add( viewElement );\n\t\t\t}\n\n\t\t\tconst lastViewCell = conversionApi.mapper.toViewElement( selectedCells[ selectedCells.length - 1 ] );\n\t\t\tviewWriter.setSelection( lastViewCell, 0 );\n\t\t}, { priority: 'lowest' } ) );\n\n\t\tfunction clearHighlightedTableCells( viewWriter: DowncastWriter ) {\n\t\t\tfor ( const previouslyHighlighted of highlighted ) {\n\t\t\t\tviewWriter.removeClass( 'ck-editor__editable_selected', previouslyHighlighted );\n\t\t\t}\n\n\t\t\thighlighted.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a listener that reacts to changes in {@link #isEnabled} and, if the plugin was disabled,\n\t * it collapses the multi-cell selection to a regular selection placed inside a table cell.\n\t *\n\t * This listener helps features that disable the table selection plugin bring the selection\n\t * to a clear state they can work with (for instance, because they don't support multiple cell selection).\n\t */\n\tprivate _enablePluginDisabling() {\n\t\tconst editor = this.editor;\n\n\t\tthis.on( 'change:isEnabled', () => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tconst selectedCells = this.getSelectedTableCells();\n\n\t\t\t\tif ( !selectedCells ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\tconst position = writer.createPositionAt( selectedCells[ 0 ], 0 );\n\t\t\t\t\tconst range = editor.model.schema.getNearestSelectionRange( position );\n\n\t\t\t\t\twriter.setSelection( range );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Overrides the default `model.deleteContent()` behavior over a selected table fragment.\n\t *\n\t * @param args Delete content method arguments.\n\t */\n\tprivate _handleDeleteContent( event: EventInfo, args: Array<unknown> ) {\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\t\tconst selection = args[ 0 ] as Selection;\n\t\tconst options = args[ 1 ] as { direction?: string };\n\t\tconst model = this.editor.model;\n\t\tconst isBackward = !options || options.direction == 'backward';\n\t\tconst selectedTableCells = tableUtils.getSelectedTableCells( selection );\n\n\t\tif ( !selectedTableCells.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.stop();\n\n\t\tmodel.change( writer => {\n\t\t\tconst tableCellToSelect = selectedTableCells[ isBackward ? selectedTableCells.length - 1 : 0 ];\n\n\t\t\tmodel.change( writer => {\n\t\t\t\tfor ( const tableCell of selectedTableCells ) {\n\t\t\t\t\tmodel.deleteContent( writer.createSelection( tableCell, 'in' ) );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tconst rangeToSelect = model.schema.getNearestSelectionRange( writer.createPositionAt( tableCellToSelect, 0 ) );\n\n\t\t\t// Note: we ignore the case where rangeToSelect may be null because deleteContent() will always (unless someone broke it)\n\t\t\t// create an empty paragraph to accommodate the selection.\n\n\t\t\tif ( selection.is( 'documentSelection' ) ) {\n\t\t\t\twriter.setSelection( rangeToSelect );\n\t\t\t} else {\n\t\t\t\tselection.setTo( rangeToSelect );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * This handler makes it possible to remove the content of all selected cells by starting to type.\n\t * If you take a look at {@link #_defineSelectionConverter} you will find out that despite the multi-cell selection being set\n\t * in the model, the view selection is collapsed in the last cell (because most browsers are unable to render multi-cell selections;\n\t * yes, it's a hack).\n\t *\n\t * When multiple cells are selected in the model and the user starts to type, the\n\t * {@link module:engine/view/document~Document#event:insertText} event carries information provided by the\n\t * beforeinput DOM  event, that in turn only knows about this collapsed DOM selection in the last cell.\n\t *\n\t * As a result, the selected cells have no chance to be cleaned up. To fix this, this listener intercepts\n\t * the event and injects the custom view selection in the data that translates correctly to the actual state\n\t * of the multi-cell selection in the model.\n\t *\n\t * @param data Insert text event data.\n\t */\n\tprivate _handleInsertTextEvent( evt: EventInfo, data: InsertTextEventData ) {\n\t\tconst editor = this.editor;\n\t\tconst selectedCells = this.getSelectedTableCells();\n\n\t\tif ( !selectedCells ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst view = editor.editing.view;\n\t\tconst mapper = editor.editing.mapper;\n\t\tconst viewRanges = selectedCells.map( tableCell => view.createRangeOn( mapper.toViewElement( tableCell )! ) );\n\n\t\tdata.selection = view.createSelection( viewRanges );\n\t}\n\n\t/**\n\t * Returns an array of table cells that should be selected based on the\n\t * given anchor cell and target (focus) cell.\n\t *\n\t * The cells are returned in a reverse direction if the selection is backward.\n\t */\n\tprivate _getCellsToSelect( anchorCell: Element, targetCell: Element ) {\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst startLocation = tableUtils.getCellLocation( anchorCell );\n\t\tconst endLocation = tableUtils.getCellLocation( targetCell );\n\n\t\tconst startRow = Math.min( startLocation.row, endLocation.row );\n\t\tconst endRow = Math.max( startLocation.row, endLocation.row );\n\n\t\tconst startColumn = Math.min( startLocation.column, endLocation.column );\n\t\tconst endColumn = Math.max( startLocation.column, endLocation.column );\n\n\t\t// 2-dimensional array of the selected cells to ease flipping the order of cells for backward selections.\n\t\tconst selectionMap: Array<Array<Element>> = new Array( endRow - startRow + 1 ).fill( null ).map( () => [] );\n\n\t\tconst walkerOptions = {\n\t\t\tstartRow,\n\t\t\tendRow,\n\t\t\tstartColumn,\n\t\t\tendColumn\n\t\t};\n\n\t\tfor ( const { row, cell } of new TableWalker( anchorCell.findAncestor( 'table' )!, walkerOptions ) ) {\n\t\t\tselectionMap[ row - startRow ].push( cell );\n\t\t}\n\n\t\tconst flipVertically = endLocation.row < startLocation.row;\n\t\tconst flipHorizontally = endLocation.column < startLocation.column;\n\n\t\tif ( flipVertically ) {\n\t\t\tselectionMap.reverse();\n\t\t}\n\n\t\tif ( flipHorizontally ) {\n\t\t\tselectionMap.forEach( row => row.reverse() );\n\t\t}\n\n\t\treturn {\n\t\t\tcells: selectionMap.flat(),\n\t\t\tbackward: flipVertically || flipHorizontally\n\t\t};\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableclipboard\n */\n\nimport type { EventInfo } from 'ckeditor5/src/utils.js';\n\nimport {\n\tClipboardPipeline,\n\tClipboardMarkersUtils,\n\ttype ClipboardEventData,\n\ttype ViewDocumentCopyEvent,\n\ttype ViewDocumentCutEvent,\n\ttype ViewDocumentClipboardOutputEvent\n} from 'ckeditor5/src/clipboard.js';\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport type {\n\tDocumentFragment,\n\tDocumentSelection,\n\tDomEventData,\n\tElement,\n\tItem,\n\tModel,\n\tModelInsertContentEvent,\n\tPosition,\n\tSelection,\n\tWriter\n} from 'ckeditor5/src/engine.js';\n\nimport TableSelection from './tableselection.js';\nimport TableWalker, { type TableSlot } from './tablewalker.js';\nimport TableUtils from './tableutils.js';\nimport {\n\tcropTableToDimensions,\n\tgetHorizontallyOverlappingCells,\n\tgetVerticallyOverlappingCells,\n\tremoveEmptyRowsColumns,\n\tsplitHorizontally,\n\tsplitVertically,\n\ttrimTableCellIfNeeded,\n\tadjustLastRowIndex,\n\tadjustLastColumnIndex\n} from './utils/structure.js';\n\n/**\n * This plugin adds support for copying/cutting/pasting fragments of tables.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */\nexport default class TableClipboard extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableClipboard' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ClipboardMarkersUtils, ClipboardPipeline, TableSelection, TableUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\tthis.listenTo<ViewDocumentCopyEvent>( viewDocument, 'copy', ( evt, data ) => this._onCopyCut( evt, data ) );\n\t\tthis.listenTo<ViewDocumentCutEvent>( viewDocument, 'cut', ( evt, data ) => this._onCopyCut( evt, data ) );\n\t\tthis.listenTo<ModelInsertContentEvent>(\n\t\t\teditor.model,\n\t\t\t'insertContent',\n\t\t\t( evt, [ content, selectable ] ) => this._onInsertContent( evt, content, selectable ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\n\t\tthis.decorate( '_replaceTableSlotCell' );\n\t}\n\n\t/**\n\t * Copies table content to a clipboard on \"copy\" & \"cut\" events.\n\t *\n\t * @param evt An object containing information about the handled event.\n\t * @param data Clipboard event data.\n\t */\n\tprivate _onCopyCut( evt: EventInfo<'copy' | 'cut'>, data: DomEventData<ClipboardEvent> & ClipboardEventData ) {\n\t\tconst view = this.editor.editing.view;\n\t\tconst tableSelection = this.editor.plugins.get( TableSelection );\n\t\tconst clipboardMarkersUtils = this.editor.plugins.get( ClipboardMarkersUtils );\n\n\t\tif ( !tableSelection.getSelectedTableCells() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( evt.name == 'cut' && !this.editor.model.canEditAt( this.editor.model.document.selection ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdata.preventDefault();\n\t\tevt.stop();\n\n\t\tthis.editor.model.enqueueChange( { isUndoable: evt.name === 'cut' }, () => {\n\t\t\tconst documentFragment = clipboardMarkersUtils._copySelectedFragmentWithMarkers(\n\t\t\t\tevt.name,\n\t\t\t\tthis.editor.model.document.selection,\n\t\t\t\t() => tableSelection.getSelectionAsFragment()!\n\t\t\t);\n\n\t\t\tview.document.fire<ViewDocumentClipboardOutputEvent>( 'clipboardOutput', {\n\t\t\t\tdataTransfer: data.dataTransfer,\n\t\t\t\tcontent: this.editor.data.toView( documentFragment ),\n\t\t\t\tmethod: evt.name\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * Overrides default {@link module:engine/model/model~Model#insertContent `model.insertContent()`} method to handle pasting table inside\n\t * selected table fragment.\n\t *\n\t * Depending on selected table fragment:\n\t * - If a selected table fragment is smaller than paste table it will crop pasted table to match dimensions.\n\t * - If dimensions are equal it will replace selected table fragment with a pasted table contents.\n\t *\n\t * @param content The content to insert.\n\t * @param selectable The selection into which the content should be inserted.\n\t * If not provided the current model document selection will be used.\n\t */\n\tprivate _onInsertContent( evt: EventInfo, content: DocumentFragment | Item, selectable: Selection | DocumentSelection | undefined ) {\n\t\tif ( selectable && !selectable.is( 'documentSelection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\t\tconst clipboardMarkersUtils = this.editor.plugins.get( ClipboardMarkersUtils );\n\n\t\t// We might need to crop table before inserting so reference might change.\n\t\tconst pastedTable = this.getTableIfOnlyTableInContent( content, model )!;\n\n\t\tif ( !pastedTable ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst selectedTableCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\n\t\tif ( !selectedTableCells.length ) {\n\t\t\tremoveEmptyRowsColumns( pastedTable, tableUtils );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Override default model.insertContent() handling at this point.\n\t\tevt.stop();\n\n\t\tif ( content.is( 'documentFragment' ) ) {\n\t\t\tclipboardMarkersUtils._pasteMarkersIntoTransformedElement(\n\t\t\t\tcontent.markers,\n\t\t\t\twriter => this._replaceSelectedCells( pastedTable, selectedTableCells, writer )\n\t\t\t);\n\t\t} else {\n\t\t\tthis.editor.model.change( writer => {\n\t\t\t\tthis._replaceSelectedCells( pastedTable, selectedTableCells, writer );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Inserts provided `selectedTableCells` into `pastedTable`.\n\t */\n\tprivate _replaceSelectedCells( pastedTable: Element, selectedTableCells: Array<Element>, writer: Writer ) {\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\n\t\tconst pastedDimensions = {\n\t\t\twidth: tableUtils.getColumns( pastedTable ),\n\t\t\theight: tableUtils.getRows( pastedTable )\n\t\t};\n\n\t\t// Prepare the table for pasting.\n\t\tconst selection = prepareTableForPasting( selectedTableCells, pastedDimensions, writer, tableUtils );\n\n\t\t// Beyond this point we operate on a fixed content table with rectangular selection and proper last row/column values.\n\n\t\tconst selectionHeight = selection.lastRow - selection.firstRow + 1;\n\t\tconst selectionWidth = selection.lastColumn - selection.firstColumn + 1;\n\n\t\t// Crop pasted table if:\n\t\t// - Pasted table dimensions exceeds selection area.\n\t\t// - Pasted table has broken layout (ie some cells sticks out by the table dimensions established by the first and last row).\n\t\t//\n\t\t// Note: The table dimensions are established by the width of the first row and the total number of rows.\n\t\t// It is possible to programmatically create a table that has rows which would have cells anchored beyond first row width but\n\t\t// such table will not be created by other editing solutions.\n\t\tconst cropDimensions = {\n\t\t\tstartRow: 0,\n\t\t\tstartColumn: 0,\n\t\t\tendRow: Math.min( selectionHeight, pastedDimensions.height ) - 1,\n\t\t\tendColumn: Math.min( selectionWidth, pastedDimensions.width ) - 1\n\t\t};\n\n\t\tpastedTable = cropTableToDimensions( pastedTable, cropDimensions, writer );\n\n\t\t// Content table to which we insert a pasted table.\n\t\tconst selectedTable = selectedTableCells[ 0 ].findAncestor( 'table' )!;\n\n\t\tconst cellsToSelect = this._replaceSelectedCellsWithPasted( pastedTable, pastedDimensions, selectedTable, selection, writer );\n\n\t\tif ( this.editor.plugins.get( 'TableSelection' ).isEnabled ) {\n\t\t\t// Selection ranges must be sorted because the first and last selection ranges are considered\n\t\t\t// as anchor/focus cell ranges for multi-cell selection.\n\t\t\tconst selectionRanges = tableUtils.sortRanges( cellsToSelect.map( cell => writer.createRangeOn( cell ) ) );\n\n\t\t\twriter.setSelection( selectionRanges );\n\t\t} else {\n\t\t\t// Set selection inside first cell if multi-cell selection is disabled.\n\t\t\twriter.setSelection( cellsToSelect[ 0 ], 0 );\n\t\t}\n\n\t\treturn selectedTable;\n\t}\n\n\t/**\n\t * Replaces the part of selectedTable with pastedTable.\n\t */\n\tprivate _replaceSelectedCellsWithPasted(\n\t\tpastedTable: Element,\n\t\tpastedDimensions: Record<string, number>,\n\t\tselectedTable: Element,\n\t\tselection: Record<string, number>,\n\t\twriter: Writer\n\t) {\n\t\tconst { width: pastedWidth, height: pastedHeight } = pastedDimensions;\n\n\t\t// Holds two-dimensional array that is addressed by [ row ][ column ] that stores cells anchored at given location.\n\t\tconst pastedTableLocationMap = createLocationMap( pastedTable, pastedWidth, pastedHeight );\n\n\t\tconst selectedTableMap = [ ...new TableWalker( selectedTable, {\n\t\t\tstartRow: selection.firstRow,\n\t\t\tendRow: selection.lastRow,\n\t\t\tstartColumn: selection.firstColumn,\n\t\t\tendColumn: selection.lastColumn,\n\t\t\tincludeAllSlots: true\n\t\t} ) ];\n\n\t\t// Selection must be set to pasted cells (some might be removed or new created).\n\t\tconst cellsToSelect: Array<Element> = [];\n\n\t\t// Store next cell insert position.\n\t\tlet insertPosition: Position;\n\n\t\t// Content table replace cells algorithm iterates over a selected table fragment and:\n\t\t//\n\t\t// - Removes existing table cells at current slot (location).\n\t\t// - Inserts cell from a pasted table for a matched slots.\n\t\t//\n\t\t// This ensures proper table geometry after the paste\n\t\tfor ( const tableSlot of selectedTableMap ) {\n\t\t\tconst { row, column } = tableSlot;\n\n\t\t\t// Save the insert position for current row start.\n\t\t\tif ( column === selection.firstColumn ) {\n\t\t\t\tinsertPosition = tableSlot.getPositionBefore();\n\t\t\t}\n\n\t\t\t// Map current table slot location to an pasted table slot location.\n\t\t\tconst pastedRow = row - selection.firstRow;\n\t\t\tconst pastedColumn = column - selection.firstColumn;\n\t\t\tconst pastedCell = pastedTableLocationMap[ pastedRow % pastedHeight ][ pastedColumn % pastedWidth ];\n\n\t\t\t// Clone cell to insert (to duplicate its attributes and children).\n\t\t\t// Cloning is required to support repeating pasted table content when inserting to a bigger selection.\n\t\t\tconst cellToInsert = pastedCell ? writer.cloneElement( pastedCell ) : null;\n\n\t\t\t// Replace the cell from the current slot with new table cell.\n\t\t\tconst newTableCell = this._replaceTableSlotCell( tableSlot, cellToInsert, insertPosition!, writer );\n\n\t\t\t// The cell was only removed.\n\t\t\tif ( !newTableCell ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Trim the cell if it's row/col-spans would exceed selection area.\n\t\t\ttrimTableCellIfNeeded( newTableCell, row, column, selection.lastRow, selection.lastColumn, writer );\n\n\t\t\tcellsToSelect.push( newTableCell );\n\n\t\t\tinsertPosition = writer.createPositionAfter( newTableCell );\n\t\t}\n\n\t\t// If there are any headings, all the cells that overlap from heading must be splitted.\n\t\tconst headingRows = parseInt( selectedTable.getAttribute( 'headingRows' ) as string || '0' );\n\t\tconst headingColumns = parseInt( selectedTable.getAttribute( 'headingColumns' ) as string || '0' );\n\n\t\tconst areHeadingRowsIntersectingSelection = selection.firstRow < headingRows && headingRows <= selection.lastRow;\n\t\tconst areHeadingColumnsIntersectingSelection = selection.firstColumn < headingColumns && headingColumns <= selection.lastColumn;\n\n\t\tif ( areHeadingRowsIntersectingSelection ) {\n\t\t\tconst columnsLimit = { first: selection.firstColumn, last: selection.lastColumn };\n\t\t\tconst newCells = doHorizontalSplit( selectedTable, headingRows, columnsLimit, writer, selection.firstRow ) as Array<Element>;\n\n\t\t\tcellsToSelect.push( ...newCells );\n\t\t}\n\n\t\tif ( areHeadingColumnsIntersectingSelection ) {\n\t\t\tconst rowsLimit = { first: selection.firstRow, last: selection.lastRow };\n\t\t\tconst newCells = doVerticalSplit( selectedTable, headingColumns, rowsLimit, writer ) as Array<Element>;\n\n\t\t\tcellsToSelect.push( ...newCells );\n\t\t}\n\n\t\treturn cellsToSelect;\n\t}\n\n\t/**\n\t * Replaces a single table slot.\n\t *\n\t * @returns Inserted table cell or null if slot should remain empty.\n\t * @private\n\t */\n\tpublic _replaceTableSlotCell(\n\t\ttableSlot: TableSlot,\n\t\tcellToInsert: Element | null,\n\t\tinsertPosition: Position,\n\t\twriter: Writer\n\t): Element | null {\n\t\tconst { cell, isAnchor } = tableSlot;\n\n\t\t// If the slot is occupied by a cell in a selected table - remove it.\n\t\t// The slot of this cell will be either:\n\t\t// - Replaced by a pasted table cell.\n\t\t// - Spanned by a previously pasted table cell.\n\t\tif ( isAnchor ) {\n\t\t\twriter.remove( cell );\n\t\t}\n\n\t\t// There is no cell to insert (might be spanned by other cell in a pasted table) - advance to the next content table slot.\n\t\tif ( !cellToInsert ) {\n\t\t\treturn null;\n\t\t}\n\n\t\twriter.insert( cellToInsert, insertPosition );\n\n\t\treturn cellToInsert;\n\t}\n\n\t/**\n\t * Extracts the table for pasting into a table.\n\t *\n\t * @param content The content to insert.\n\t * @param model The editor model.\n\t */\n\tpublic getTableIfOnlyTableInContent( content: DocumentFragment | Item, model: Model ): Element | null {\n\t\tif ( !content.is( 'documentFragment' ) && !content.is( 'element' ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Table passed directly.\n\t\tif ( content.is( 'element', 'table' ) ) {\n\t\t\treturn content;\n\t\t}\n\n\t\t// We do not support mixed content when pasting table into table.\n\t\t// See: https://github.com/ckeditor/ckeditor5/issues/6817.\n\t\tif ( content.childCount == 1 && content.getChild( 0 )!.is( 'element', 'table' ) ) {\n\t\t\treturn content.getChild( 0 ) as Element;\n\t\t}\n\n\t\t// If there are only whitespaces around a table then use that table for pasting.\n\n\t\tconst contentRange = model.createRangeIn( content );\n\n\t\tfor ( const element of contentRange.getItems() ) {\n\t\t\tif ( element.is( 'element', 'table' ) ) {\n\t\t\t\t// Stop checking if there is some content before table.\n\t\t\t\tconst rangeBefore = model.createRange( contentRange.start, model.createPositionBefore( element ) );\n\n\t\t\t\tif ( model.hasContent( rangeBefore, { ignoreWhitespaces: true } ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// Stop checking if there is some content after table.\n\t\t\t\tconst rangeAfter = model.createRange( model.createPositionAfter( element ), contentRange.end );\n\n\t\t\t\tif ( model.hasContent( rangeAfter, { ignoreWhitespaces: true } ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// There wasn't any content neither before nor after.\n\t\t\t\treturn element;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\n/**\n * Prepares a table for pasting and returns adjusted selection dimensions.\n */\nfunction prepareTableForPasting(\n\tselectedTableCells: Array<Element>,\n\tpastedDimensions: {\n\t\theight: number;\n\t\twidth: number;\n\t},\n\twriter: Writer,\n\ttableUtils: TableUtils\n) {\n\tconst selectedTable = selectedTableCells[ 0 ].findAncestor( 'table' )!;\n\n\tconst columnIndexes = tableUtils.getColumnIndexes( selectedTableCells );\n\tconst rowIndexes = tableUtils.getRowIndexes( selectedTableCells );\n\n\tconst selection = {\n\t\tfirstColumn: columnIndexes.first,\n\t\tlastColumn: columnIndexes.last,\n\t\tfirstRow: rowIndexes.first,\n\t\tlastRow: rowIndexes.last\n\t};\n\n\t// Single cell selected - expand selection to pasted table dimensions.\n\tconst shouldExpandSelection = selectedTableCells.length === 1;\n\n\tif ( shouldExpandSelection ) {\n\t\tselection.lastRow += pastedDimensions.height - 1;\n\t\tselection.lastColumn += pastedDimensions.width - 1;\n\n\t\texpandTableSize( selectedTable, selection.lastRow + 1, selection.lastColumn + 1, tableUtils );\n\t}\n\n\t// In case of expanding selection we do not reset the selection so in this case we will always try to fix selection\n\t// like in the case of a non-rectangular area. This might be fixed by re-setting selected cells array but this shortcut is safe.\n\tif ( shouldExpandSelection || !tableUtils.isSelectionRectangular( selectedTableCells ) ) {\n\t\t// For a non-rectangular selection (ie in which some cells sticks out from a virtual selection rectangle) we need to create\n\t\t// a table layout that has a rectangular selection. This will split cells so the selection become rectangular.\n\t\t// Beyond this point we will operate on fixed content table.\n\t\tsplitCellsToRectangularSelection( selectedTable, selection, writer );\n\t}\n\t// However a selected table fragment might be invalid if examined alone. Ie such table fragment:\n\t//\n\t//    +---+---+---+---+\n\t//  0 | a | b | c | d |\n\t//    +   +   +---+---+\n\t//  1 |   | e | f | g |\n\t//    +   +---+   +---+\n\t//  2 |   | h |   | i | <- last row, each cell has rowspan = 2,\n\t//    +   +   +   +   +    so we need to return 3, not 2\n\t//  3 |   |   |   |   |\n\t//    +---+---+---+---+\n\t//\n\t// is invalid as the cells \"h\" and \"i\" have rowspans.\n\t// This case needs only adjusting the selection dimension as the rest of the algorithm operates on empty slots also.\n\telse {\n\t\tselection.lastRow = adjustLastRowIndex( selectedTable, selection );\n\t\tselection.lastColumn = adjustLastColumnIndex( selectedTable, selection );\n\t}\n\n\treturn selection;\n}\n\n/**\n * Expand table (in place) to expected size.\n */\nfunction expandTableSize( table: Element, expectedHeight: number, expectedWidth: number, tableUtils: TableUtils ) {\n\tconst tableWidth = tableUtils.getColumns( table );\n\tconst tableHeight = tableUtils.getRows( table );\n\n\tif ( expectedWidth > tableWidth ) {\n\t\ttableUtils.insertColumns( table, {\n\t\t\tat: tableWidth,\n\t\t\tcolumns: expectedWidth - tableWidth\n\t\t} );\n\t}\n\n\tif ( expectedHeight > tableHeight ) {\n\t\ttableUtils.insertRows( table, {\n\t\t\tat: tableHeight,\n\t\t\trows: expectedHeight - tableHeight\n\t\t} );\n\t}\n}\n\n/**\n * Returns two-dimensional array that is addressed by [ row ][ column ] that stores cells anchored at given location.\n *\n * At given row & column location it might be one of:\n *\n * * cell - cell from pasted table anchored at this location.\n * * null - if no cell is anchored at this location.\n *\n * For instance, from a table below:\n *\n *   +----+----+----+----+\n *   | 00 | 01 | 02 | 03 |\n *   +    +----+----+----+\n *   |    | 11      | 13 |\n *   +----+         +----+\n *   | 20 |         | 23 |\n *   +----+----+----+----+\n *\n * The method will return an array (numbers represents cell element):\n *\n * ```ts\n * const map = [\n *   [ '00', '01', '02', '03' ],\n *   [ null, '11', null, '13' ],\n *   [ '20', null, null, '23' ]\n * ]\n * ```\n *\n * This allows for a quick access to table at give row & column. For instance to access table cell \"13\" from pasted table call:\n *\n * ```ts\n * const cell = map[ 1 ][ 3 ]\n * ```\n */\nfunction createLocationMap( table: Element, width: number, height: number ) {\n\t// Create height x width (row x column) two-dimensional table to store cells.\n\tconst map = new Array( height ).fill( null )\n\t\t.map( () => new Array( width ).fill( null ) );\n\n\tfor ( const { column, row, cell } of new TableWalker( table ) ) {\n\t\tmap[ row ][ column ] = cell;\n\t}\n\n\treturn map;\n}\n\n/**\n * Make selected cells rectangular by splitting the cells that stand out from a rectangular selection.\n *\n * In the table below a selection is shown with \"::\" and slots with anchor cells are named.\n *\n * +----+----+----+----+----+                    +----+----+----+----+----+\n * | 00 | 01 | 02 | 03      |                    | 00 | 01 | 02 | 03      |\n * +    +----+    +----+----+                    |    ::::::::::::::::----+\n * |    | 11 |    | 13 | 14 |                    |    ::11 |    | 13:: 14 |    <- first row\n * +----+----+    +    +----+                    +----::---|    |   ::----+\n * | 20 | 21 |    |    | 24 |   select cells:    | 20 ::21 |    |   :: 24 |\n * +----+----+    +----+----+     11 -> 33       +----::---|    |---::----+\n * | 30      |    | 33 | 34 |                    | 30 ::   |    | 33:: 34 |    <- last row\n * +         +    +----+    +                    |    ::::::::::::::::    +\n * |         |    | 43 |    |                    |         |    | 43 |    |\n * +----+----+----+----+----+                    +----+----+----+----+----+\n *                                                      ^          ^\n *                                                     first & last columns\n *\n * Will update table to:\n *\n *                       +----+----+----+----+----+\n *                       | 00 | 01 | 02 | 03      |\n *                       +    +----+----+----+----+\n *                       |    | 11 |    | 13 | 14 |\n *                       +----+----+    +    +----+\n *                       | 20 | 21 |    |    | 24 |\n *                       +----+----+    +----+----+\n *                       | 30 |    |    | 33 | 34 |\n *                       +    +----+----+----+    +\n *                       |    |    |    | 43 |    |\n *                       +----+----+----+----+----+\n *\n * In th example above:\n * - Cell \"02\" which have `rowspan = 4` must be trimmed at first and at after last row.\n * - Cell \"03\" which have `rowspan = 2` and `colspan = 2` must be trimmed at first column and after last row.\n * - Cells \"00\", \"03\" & \"30\" which cannot be cut by this algorithm as they are outside the trimmed area.\n * - Cell \"13\" cannot be cut as it is inside the trimmed area.\n */\nfunction splitCellsToRectangularSelection( table: Element, dimensions: Record<string, number>, writer: Writer ) {\n\tconst { firstRow, lastRow, firstColumn, lastColumn } = dimensions;\n\n\tconst rowIndexes = { first: firstRow, last: lastRow };\n\tconst columnIndexes = { first: firstColumn, last: lastColumn };\n\n\t// 1. Split cells vertically in two steps as first step might create cells that needs to split again.\n\tdoVerticalSplit( table, firstColumn, rowIndexes, writer );\n\tdoVerticalSplit( table, lastColumn + 1, rowIndexes, writer );\n\n\t// 2. Split cells horizontally in two steps as first step might create cells that needs to split again.\n\tdoHorizontalSplit( table, firstRow, columnIndexes, writer );\n\tdoHorizontalSplit( table, lastRow + 1, columnIndexes, writer, firstRow );\n}\n\nfunction doHorizontalSplit( table: Element, splitRow: number, limitColumns: Record<string, number>, writer: Writer, startRow: number = 0 ) {\n\t// If selection starts at first row then no split is needed.\n\tif ( splitRow < 1 ) {\n\t\treturn;\n\t}\n\n\tconst overlappingCells = getVerticallyOverlappingCells( table, splitRow, startRow );\n\n\t// Filter out cells that are not touching insides of the rectangular selection.\n\tconst cellsToSplit = overlappingCells.filter( ( { column, cellWidth } ) => isAffectedBySelection( column, cellWidth, limitColumns ) );\n\n\treturn cellsToSplit.map( ( { cell } ) => splitHorizontally( cell, splitRow, writer ) );\n}\n\nfunction doVerticalSplit( table: Element, splitColumn: number, limitRows: Record<string, number>, writer: Writer ) {\n\t// If selection starts at first column then no split is needed.\n\tif ( splitColumn < 1 ) {\n\t\treturn;\n\t}\n\n\tconst overlappingCells = getHorizontallyOverlappingCells( table, splitColumn );\n\n\t// Filter out cells that are not touching insides of the rectangular selection.\n\tconst cellsToSplit = overlappingCells.filter( ( { row, cellHeight } ) => isAffectedBySelection( row, cellHeight, limitRows ) );\n\n\treturn cellsToSplit.map( ( { cell, column } ) => splitVertically( cell, column, splitColumn, writer ) );\n}\n\n/**\n * Checks if cell at given row (column) is affected by a rectangular selection defined by first/last column (row).\n *\n * The same check is used for row as for column.\n */\nfunction isAffectedBySelection( index: number, span: number, limit: Record<string, number> ) {\n\tconst endIndex = index + span - 1;\n\tconst { first, last } = limit;\n\n\tconst isInsideSelection = index >= first && index <= last;\n\tconst overlapsSelectionFromOutside = index < first && endIndex >= first;\n\n\treturn isInsideSelection || overlapsSelectionFromOutside;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablekeyboard\n */\n\nimport TableSelection from './tableselection.js';\nimport TableWalker from './tablewalker.js';\nimport TableUtils from './tableutils.js';\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport {\n\tgetLocalizedArrowKeyCodeDirection,\n\ttype EventInfo,\n\ttype ArrowKeyCodeDirection,\n\ttype KeystrokeInfo\n} from 'ckeditor5/src/utils.js';\n\nimport type {\n\tBubblingEventInfo,\n\tDocumentSelection,\n\tDomEventData,\n\tElement,\n\tSelection,\n\tViewDocumentArrowKeyEvent,\n\tViewDocumentTabEvent\n} from 'ckeditor5/src/engine.js';\n\n/**\n * This plugin enables keyboard navigation for tables.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */\nexport default class TableKeyboard extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableKeyboard' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableSelection, TableUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\t\tconst t = editor.t;\n\n\t\tthis.listenTo<ViewDocumentArrowKeyEvent>(\n\t\t\tviewDocument,\n\t\t\t'arrowKey',\n\t\t\t( ...args ) => this._onArrowKey( ...args ),\n\t\t\t{ context: 'table' }\n\t\t);\n\n\t\tthis.listenTo<ViewDocumentTabEvent>(\n\t\t\tviewDocument,\n\t\t\t'tab',\n\t\t\t( ...args ) => this._handleTabOnSelectedTable( ...args ),\n\t\t\t{ context: 'figure' }\n\t\t);\n\n\t\tthis.listenTo<ViewDocumentTabEvent>(\n\t\t\tviewDocument,\n\t\t\t'tab',\n\t\t\t( ...args ) => this._handleTab( ...args ),\n\t\t\t{ context: [ 'th', 'td' ] }\n\t\t);\n\n\t\t// Add the information about the keystrokes to the accessibility database.\n\t\teditor.accessibility.addKeystrokeInfoGroup( {\n\t\t\tid: 'table',\n\t\t\tlabel: t( 'Keystrokes that can be used in a table cell' ),\n\t\t\tkeystrokes: [\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move the selection to the next cell' ),\n\t\t\t\t\tkeystroke: 'Tab'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Move the selection to the previous cell' ),\n\t\t\t\t\tkeystroke: 'Shift+Tab'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Insert a new table row (when in the last cell of a table)' ),\n\t\t\t\t\tkeystroke: 'Tab'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: t( 'Navigate through the table' ),\n\t\t\t\t\tkeystroke: [ [ 'arrowup' ], [ 'arrowright' ], [ 'arrowdown' ], [ 'arrowleft' ] ]\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:tab tab} events for the <kbd>Tab</kbd> key executed\n\t * when the table widget is selected.\n\t */\n\tprivate _handleTabOnSelectedTable( bubblingEventInfo: BubblingEventInfo, domEventData: DomEventData ) {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\tif ( !selectedElement || !selectedElement.is( 'element', 'table' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdomEventData.preventDefault();\n\t\tdomEventData.stopPropagation();\n\t\tbubblingEventInfo.stop();\n\n\t\teditor.model.change( writer => {\n\t\t\twriter.setSelection( writer.createRangeIn( ( selectedElement.getChild( 0 ) as Element ).getChild( 0 ) as Element ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:tab tab} events for the <kbd>Tab</kbd> key executed\n\t * inside table cells.\n\t */\n\tprivate _handleTab( bubblingEventInfo: BubblingEventInfo, domEventData: DomEventData & KeystrokeInfo ) {\n\t\tconst editor = this.editor;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( TableUtils );\n\t\tconst tableSelection: TableSelection = this.editor.plugins.get( 'TableSelection' );\n\n\t\tconst selection = editor.model.document.selection;\n\t\tconst isForward = !domEventData.shiftKey;\n\n\t\tlet tableCell: Element | null = tableUtils.getTableCellsContainingSelection( selection )[ 0 ];\n\n\t\tif ( !tableCell ) {\n\t\t\ttableCell = tableSelection.getFocusCell();\n\t\t}\n\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdomEventData.preventDefault();\n\t\tdomEventData.stopPropagation();\n\t\tbubblingEventInfo.stop();\n\n\t\tconst tableRow = tableCell.parent as Element;\n\t\tconst table = tableRow.parent as Element;\n\n\t\tconst currentRowIndex = table.getChildIndex( tableRow )!;\n\t\tconst currentCellIndex = tableRow.getChildIndex( tableCell )!;\n\n\t\tconst isFirstCellInRow = currentCellIndex === 0;\n\n\t\tif ( !isForward && isFirstCellInRow && currentRowIndex === 0 ) {\n\t\t\t// Set the selection over the whole table if the selection was in the first table cell.\n\t\t\teditor.model.change( writer => {\n\t\t\t\twriter.setSelection( writer.createRangeOn( table ) );\n\t\t\t} );\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst isLastCellInRow = currentCellIndex === tableRow.childCount - 1;\n\t\tconst isLastRow = currentRowIndex === tableUtils.getRows( table ) - 1;\n\n\t\tif ( isForward && isLastRow && isLastCellInRow ) {\n\t\t\teditor.execute( 'insertTableRowBelow' );\n\n\t\t\t// Check if the command actually added a row. If `insertTableRowBelow` execution didn't add a row (because it was disabled\n\t\t\t// or it got overwritten) set the selection over the whole table to mirror the first cell case.\n\t\t\tif ( currentRowIndex === tableUtils.getRows( table ) - 1 ) {\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\twriter.setSelection( writer.createRangeOn( table ) );\n\t\t\t\t} );\n\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tlet cellToFocus: Element;\n\n\t\t// Move to the first cell in the next row.\n\t\tif ( isForward && isLastCellInRow ) {\n\t\t\tconst nextRow = table.getChild( currentRowIndex + 1 ) as Element;\n\n\t\t\tcellToFocus = nextRow.getChild( 0 ) as Element;\n\t\t}\n\t\t// Move to the last cell in the previous row.\n\t\telse if ( !isForward && isFirstCellInRow ) {\n\t\t\tconst previousRow = table.getChild( currentRowIndex - 1 ) as Element;\n\n\t\t\tcellToFocus = previousRow.getChild( previousRow.childCount - 1 ) as Element;\n\t\t}\n\t\t// Move to the next/previous cell.\n\t\telse {\n\t\t\tcellToFocus = tableRow.getChild( currentCellIndex + ( isForward ? 1 : -1 ) ) as Element;\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\twriter.setSelection( writer.createRangeIn( cellToFocus ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events.\n\t */\n\tprivate _onArrowKey( eventInfo: EventInfo, domEventData: DomEventData & KeystrokeInfo ) {\n\t\tconst editor = this.editor;\n\t\tconst keyCode = domEventData.keyCode;\n\n\t\tconst direction = getLocalizedArrowKeyCodeDirection( keyCode, editor.locale.contentLanguageDirection )!;\n\t\tconst wasHandled = this._handleArrowKeys( direction, domEventData.shiftKey );\n\n\t\tif ( wasHandled ) {\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles arrow keys to move the selection around the table.\n\t *\n\t * @param direction The direction of the arrow key.\n\t * @param expandSelection If the current selection should be expanded.\n\t * @returns Returns `true` if key was handled.\n\t */\n\tprivate _handleArrowKeys( direction: ArrowKeyCodeDirection, expandSelection: boolean ) {\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\t\tconst tableSelection: TableSelection = this.editor.plugins.get( 'TableSelection' );\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst isForward = [ 'right', 'down' ].includes( direction );\n\n\t\t// In case one or more table cells are selected (from outside),\n\t\t// move the selection to a cell adjacent to the selected table fragment.\n\t\tconst selectedCells = tableUtils.getSelectedTableCells( selection );\n\n\t\tif ( selectedCells.length ) {\n\t\t\tlet focusCell;\n\n\t\t\tif ( expandSelection ) {\n\t\t\t\tfocusCell = tableSelection.getFocusCell();\n\t\t\t} else {\n\t\t\t\tfocusCell = isForward ? selectedCells[ selectedCells.length - 1 ] : selectedCells[ 0 ];\n\t\t\t}\n\n\t\t\tthis._navigateFromCellInDirection( focusCell!, direction, expandSelection );\n\n\t\t\treturn true;\n\t\t}\n\n\t\t// Abort if we're not in a table cell.\n\t\tconst tableCell = selection.focus!.findAncestor( 'tableCell' );\n\n\t\t/* istanbul ignore if: paranoid check -- @preserve */\n\t\tif ( !tableCell ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// When the selection is not collapsed.\n\t\tif ( !selection.isCollapsed ) {\n\t\t\tif ( expandSelection ) {\n\t\t\t\t// Navigation is in the opposite direction than the selection direction so this is shrinking of the selection.\n\t\t\t\t// Selection for sure will not approach cell edge.\n\t\t\t\t//\n\t\t\t\t// With a special case when all cell content is selected - then selection should expand to the other cell.\n\t\t\t\t// Note: When the entire cell gets selected using CTRL+A, the selection is always forward.\n\t\t\t\tif ( selection.isBackward == isForward && !selection.containsEntireContent( tableCell ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t\t\t// It will collapse for non-object selected so it's not going to move to other cell.\n\t\t\t\tif ( !selectedElement || !model.schema.isObject( selectedElement ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Let's check if the selection is at the beginning/end of the cell.\n\t\tif ( this._isSelectionAtCellEdge( selection, tableCell, isForward ) ) {\n\t\t\tthis._navigateFromCellInDirection( tableCell, direction, expandSelection );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns `true` if the selection is at the boundary of a table cell according to the navigation direction.\n\t *\n\t * @param selection The current selection.\n\t * @param tableCell The current table cell element.\n\t * @param isForward The expected navigation direction.\n\t */\n\tprivate _isSelectionAtCellEdge( selection: Selection | DocumentSelection, tableCell: Element, isForward: boolean ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst focus = isForward ? selection.getLastPosition()! : selection.getFirstPosition()!;\n\n\t\t// If the current limit element is not table cell we are for sure not at the cell edge.\n\t\t// Also `modifySelection` will not let us out of it.\n\t\tif ( !schema.getLimitElement( focus ).is( 'element', 'tableCell' ) ) {\n\t\t\tconst boundaryPosition = model.createPositionAt( tableCell, isForward ? 'end' : 0 );\n\n\t\t\treturn boundaryPosition.isTouching( focus );\n\t\t}\n\n\t\tconst probe = model.createSelection( focus );\n\n\t\tmodel.modifySelection( probe, { direction: isForward ? 'forward' : 'backward' } );\n\n\t\t// If there was no change in the focus position, then it's not possible to move the selection there.\n\t\treturn focus.isEqual( probe.focus! );\n\t}\n\n\t/**\n\t * Moves the selection from the given table cell in the specified direction.\n\t *\n\t * @param focusCell The table cell that is current multi-cell selection focus.\n\t * @param direction Direction in which selection should move.\n\t * @param expandSelection If the current selection should be expanded. Default value is false.\n\t */\n\tprotected _navigateFromCellInDirection( focusCell: Element, direction: ArrowKeyCodeDirection, expandSelection = false ): void {\n\t\tconst model = this.editor.model;\n\n\t\tconst table = focusCell.findAncestor( 'table' )!;\n\t\tconst tableMap = [ ...new TableWalker( table, { includeAllSlots: true } ) ];\n\t\tconst { row: lastRow, column: lastColumn } = tableMap[ tableMap.length - 1 ];\n\n\t\tconst currentCellInfo = tableMap.find( ( { cell } ) => cell == focusCell )!;\n\t\tlet { row, column } = currentCellInfo;\n\n\t\tswitch ( direction ) {\n\t\t\tcase 'left':\n\t\t\t\tcolumn--;\n\t\t\t\tbreak;\n\n\t\t\tcase 'up':\n\t\t\t\trow--;\n\t\t\t\tbreak;\n\n\t\t\tcase 'right':\n\t\t\t\tcolumn += currentCellInfo.cellWidth;\n\t\t\t\tbreak;\n\n\t\t\tcase 'down':\n\t\t\t\trow += currentCellInfo.cellHeight;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst isOutsideVertically = row < 0 || row > lastRow;\n\t\tconst isBeforeFirstCell = column < 0 && row <= 0;\n\t\tconst isAfterLastCell = column > lastColumn && row >= lastRow;\n\n\t\t// Note that if the table cell at the end of a row is row-spanned then isAfterLastCell will never be true.\n\t\t// However, we don't know if user was navigating on the last row or not, so let's stay in the table.\n\n\t\tif ( isOutsideVertically || isBeforeFirstCell || isAfterLastCell ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( writer.createRangeOn( table ) );\n\t\t\t} );\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( column < 0 ) {\n\t\t\tcolumn = expandSelection ? 0 : lastColumn;\n\t\t\trow--;\n\t\t} else if ( column > lastColumn ) {\n\t\t\tcolumn = expandSelection ? lastColumn : 0;\n\t\t\trow++;\n\t\t}\n\n\t\tconst cellToSelect = tableMap.find( cellInfo => cellInfo.row == row && cellInfo.column == column )!.cell;\n\t\tconst isForward = [ 'right', 'down' ].includes( direction );\n\t\tconst tableSelection: TableSelection = this.editor.plugins.get( 'TableSelection' );\n\n\t\tif ( expandSelection && tableSelection.isEnabled ) {\n\t\t\tconst anchorCell = tableSelection.getAnchorCell() || focusCell;\n\n\t\t\ttableSelection.setCellSelection( anchorCell, cellToSelect );\n\t\t} else {\n\t\t\tconst positionToSelect = model.createPositionAt( cellToSelect, isForward ? 0 : 'end' );\n\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( positionToSelect );\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablemouse/mouseeventsobserver\n */\n\nimport { DomEventObserver, type DomEventData } from 'ckeditor5/src/engine.js';\n\n/**\n * The mouse selection event observer.\n *\n * It registers listeners for the following DOM events:\n *\n * - `'mousemove'`\n * - `'mouseleave'`\n *\n * Note that this observer is disabled by default. To enable this observer, it needs to be added to\n * {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.\n *\n * The observer is registered by the {@link module:table/tableselection~TableSelection} plugin.\n */\nexport default class MouseEventsObserver extends DomEventObserver<'mousemove' | 'mouseleave'> {\n\tpublic readonly domEventType = [\n\t\t'mousemove', 'mouseleave'\n\t] as const;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic onDomEvent( domEvent: MouseEvent ): void {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when the mouse is moved over one of the editables.\n *\n * Introduced by {@link module:table/tablemouse/mouseeventsobserver~MouseEventsObserver}.\n *\n * Note that this event is not available by default. To make it available,\n * {@link module:table/tablemouse/mouseeventsobserver~MouseEventsObserver} needs to be added\n * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:table/tablemouse/mouseeventsobserver~MouseEventsObserver\n * @eventName module:engine/view/document~Document#mousemove\n * @param data Event data.\n */\nexport type ViewDocumentMouseMoveEvent = {\n\tname: 'mousemove';\n\targs: [ data: DomEventData<MouseEvent> ];\n};\n\n/**\n * Fired when the mouse is moved out of one of the editables.\n *\n * Introduced by {@link module:table/tablemouse/mouseeventsobserver~MouseEventsObserver}.\n *\n * Note that this event is not available by default. To make it available,\n * {@link module:table/tablemouse/mouseeventsobserver~MouseEventsObserver} needs to be added\n * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:table/tablemouse/mouseeventsobserver~MouseEventsObserver\n * @eventName module:engine/view/document~Document#mouseleave\n * @param data Event data.\n */\nexport type ViewDocumentMouseLeaveEvent = {\n\tname: 'mouseleave';\n\targs: [ data: DomEventData<MouseEvent> ];\n};\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablemouse\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport TableSelection from './tableselection.js';\nimport MouseEventsObserver from './tablemouse/mouseeventsobserver.js';\nimport TableUtils from './tableutils.js';\nimport type { DomEventData, Element } from 'ckeditor5/src/engine.js';\n\n/**\n * This plugin enables a table cells' selection with the mouse.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n */\nexport default class TableMouse extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableMouse' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableSelection, TableUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\t// Currently the MouseObserver only handles `mousedown` and `mouseup` events.\n\t\t// TODO move to the engine?\n\t\teditor.editing.view.addObserver( MouseEventsObserver );\n\n\t\tthis._enableShiftClickSelection();\n\t\tthis._enableMouseDragSelection();\n\t}\n\n\t/**\n\t * Enables making cells selection by <kbd>Shift</kbd>+click. Creates a selection from the cell which previously held\n\t * the selection to the cell which was clicked. It can be the same cell, in which case it selects a single cell.\n\t */\n\tprivate _enableShiftClickSelection() {\n\t\tconst editor = this.editor;\n\t\tconst tableUtils = editor.plugins.get( TableUtils );\n\t\tlet blockSelectionChange = false;\n\n\t\tconst tableSelection = editor.plugins.get( TableSelection );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mousedown', ( evt, domEventData ) => {\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\tif ( !this.isEnabled || !tableSelection.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !domEventData.domEvent.shiftKey ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst anchorCell = tableSelection.getAnchorCell() || tableUtils.getTableCellsContainingSelection( selection )[ 0 ];\n\n\t\t\tif ( !anchorCell ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst targetCell = this._getModelTableCellFromDomEvent( domEventData );\n\n\t\t\tif ( targetCell && haveSameTableParent( anchorCell, targetCell ) ) {\n\t\t\t\tblockSelectionChange = true;\n\t\t\t\ttableSelection.setCellSelection( anchorCell, targetCell );\n\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t}\n\t\t} );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mouseup', () => {\n\t\t\tblockSelectionChange = false;\n\t\t} );\n\n\t\t// We need to ignore a `selectionChange` event that is fired after we render our new table cells selection.\n\t\t// When downcasting table cells selection to the view, we put the view selection in the last selected cell\n\t\t// in a place that may not be natively a \"correct\" location. This is – we put it directly in the `<td>` element.\n\t\t// All browsers fire the native `selectionchange` event.\n\t\t// However, all browsers except Safari return the selection in the exact place where we put it\n\t\t// (even though it's visually normalized). Safari returns `<td><p>^foo` that makes our selection observer\n\t\t// fire our `selectionChange` event (because the view selection that we set in the first step differs from the DOM selection).\n\t\t// Since `selectionChange` is fired, we automatically update the model selection that moves it that paragraph.\n\t\t// This breaks our dear cells selection.\n\t\t//\n\t\t// Theoretically this issue concerns only Safari that is the only browser that do normalize the selection.\n\t\t// However, to avoid code branching and to have a good coverage for this event blocker, I enabled it for all browsers.\n\t\t//\n\t\t// Note: I'm keeping the `blockSelectionChange` state separately for shift+click and mouse drag (exact same logic)\n\t\t// so I don't have to try to analyze whether they don't overlap in some weird cases. Probably they don't.\n\t\t// But I have other things to do, like writing this comment.\n\t\tthis.listenTo( editor.editing.view.document, 'selectionChange', evt => {\n\t\t\tif ( blockSelectionChange ) {\n\t\t\t\t// @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );\n\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Enables making cells selection by dragging.\n\t *\n\t * The selection is made only on mousemove. Mouse tracking is started on mousedown.\n\t * However, the cells selection is enabled only after the mouse cursor left the anchor cell.\n\t * Thanks to that normal text selection within one cell works just fine. However, you can still select\n\t * just one cell by leaving the anchor cell and moving back to it.\n\t */\n\tprivate _enableMouseDragSelection() {\n\t\tconst editor = this.editor;\n\t\tlet anchorCell: Element | null, targetCell: Element | null;\n\t\tlet beganCellSelection = false;\n\t\tlet blockSelectionChange = false;\n\n\t\tconst tableSelection = editor.plugins.get( TableSelection );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mousedown', ( evt, domEventData ) => {\n\t\t\tif ( !this.isEnabled || !tableSelection.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Make sure to not conflict with the shift+click listener and any other possible handler.\n\t\t\tif ( domEventData.domEvent.shiftKey || domEventData.domEvent.ctrlKey || domEventData.domEvent.altKey ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tanchorCell = this._getModelTableCellFromDomEvent( domEventData );\n\t\t} );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mousemove', ( evt, domEventData ) => {\n\t\t\tif ( !domEventData.domEvent.buttons ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !anchorCell ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst newTargetCell = this._getModelTableCellFromDomEvent( domEventData );\n\n\t\t\tif ( newTargetCell && haveSameTableParent( anchorCell, newTargetCell ) ) {\n\t\t\t\ttargetCell = newTargetCell;\n\n\t\t\t\t// Switch to the cell selection mode after the mouse cursor left the anchor cell.\n\t\t\t\t// Switch off only on mouseup (makes selecting a single cell possible).\n\t\t\t\tif ( !beganCellSelection && targetCell != anchorCell ) {\n\t\t\t\t\tbeganCellSelection = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Yep, not making a cell selection yet. See method docs.\n\t\t\tif ( !beganCellSelection ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tblockSelectionChange = true;\n\t\t\ttableSelection.setCellSelection( anchorCell, targetCell! );\n\n\t\t\tdomEventData.preventDefault();\n\t\t} );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mouseup', () => {\n\t\t\tbeganCellSelection = false;\n\t\t\tblockSelectionChange = false;\n\t\t\tanchorCell = null;\n\t\t\ttargetCell = null;\n\t\t} );\n\n\t\t// See the explanation in `_enableShiftClickSelection()`.\n\t\tthis.listenTo( editor.editing.view.document, 'selectionChange', evt => {\n\t\t\tif ( blockSelectionChange ) {\n\t\t\t\t// @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );\n\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Returns the model table cell element based on the target element of the passed DOM event.\n\t *\n\t * @returns Returns the table cell or `undefined`.\n\t */\n\tprivate _getModelTableCellFromDomEvent( domEventData: DomEventData ) {\n\t\t// Note: Work with positions (not element mapping) because the target element can be an attribute or other non-mapped element.\n\t\tconst viewTargetElement = domEventData.target;\n\t\tconst viewPosition = this.editor.editing.view.createPositionAt( viewTargetElement, 0 );\n\t\tconst modelPosition = this.editor.editing.mapper.toModelPosition( viewPosition );\n\t\tconst modelElement = modelPosition.parent as Element;\n\n\t\treturn modelElement.findAncestor( 'tableCell', { includeSelf: true } );\n\t}\n}\n\nfunction haveSameTableParent( cellA: Element, cellB: Element ) {\n\treturn cellA.parent!.parent == cellB.parent!.parent;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/table\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { Widget } from 'ckeditor5/src/widget.js';\n\nimport TableEditing from './tableediting.js';\nimport TableUI from './tableui.js';\nimport TableSelection from './tableselection.js';\nimport TableClipboard from './tableclipboard.js';\nimport TableKeyboard from './tablekeyboard.js';\nimport TableMouse from './tablemouse.js';\n\nimport '../theme/table.css';\n\n/**\n * The table plugin.\n *\n * For a detailed overview, check the {@glink features/tables/tables Table feature documentation}.\n *\n * This is a \"glue\" plugin that loads the following table features:\n *\n * * {@link module:table/tableediting~TableEditing editing feature},\n * * {@link module:table/tableselection~TableSelection selection feature},\n * * {@link module:table/tablekeyboard~TableKeyboard keyboard navigation feature},\n * * {@link module:table/tablemouse~TableMouse mouse selection feature},\n * * {@link module:table/tableclipboard~TableClipboard clipboard feature},\n * * {@link module:table/tableui~TableUI UI feature}.\n */\nexport default class Table extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableEditing, TableUI, TableSelection, TableMouse, TableKeyboard, TableClipboard, Widget ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'Table' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/plaintableoutput\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport type { DowncastWriter, Element, Node, ViewContainerElement } from 'ckeditor5/src/engine.js';\n\nimport Table from './table.js';\n\n/**\n * The plain table output feature.\n */\nexport default class PlainTableOutput extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'PlainTableOutput' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ Table ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\t// Override default table data downcast converter.\n\t\teditor.conversion.for( 'dataDowncast' ).elementToStructure( {\n\t\t\tmodel: 'table',\n\t\t\tview: downcastTableElement,\n\t\t\tconverterPriority: 'high'\n\t\t} );\n\n\t\t// Make sure table <caption> is downcasted into <caption> in the data pipeline when necessary.\n\t\tif ( editor.plugins.has( 'TableCaption' ) ) {\n\t\t\teditor.conversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\t\tmodel: 'caption',\n\t\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\t\tif ( modelElement.parent!.name === 'table' ) {\n\t\t\t\t\t\treturn writer.createContainerElement( 'caption' );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} );\n\t\t}\n\n\t\t// Handle border-style, border-color, border-width and background-color table attributes.\n\t\tif ( editor.plugins.has( 'TableProperties' ) ) {\n\t\t\tdowncastTableBorderAndBackgroundAttributes( editor );\n\t\t}\n\t}\n}\n\n/**\n * The plain table downcast converter callback.\n *\n * @param table Table model element.\n * @param conversionApi The conversion API object.\n * @returns Created element.\n */\nfunction downcastTableElement( table: Element, { writer }: { writer: DowncastWriter } ) {\n\tconst headingRows = table.getAttribute( 'headingRows' ) as number || 0;\n\n\t// Table head rows slot.\n\tconst headRowsSlot = writer.createSlot( ( element: Node ) =>\n\t\telement.is( 'element', 'tableRow' ) && element.index! < headingRows\n\t);\n\n\t// Table body rows slot.\n\tconst bodyRowsSlot = writer.createSlot( ( element: Node ) =>\n\t\telement.is( 'element', 'tableRow' ) && element.index! >= headingRows\n\t);\n\n\t// Table children slot.\n\tconst childrenSlot = writer.createSlot( ( element: Node ) => !element.is( 'element', 'tableRow' ) );\n\n\t// Table <thead> element with all the heading rows.\n\tconst theadElement = writer.createContainerElement( 'thead', null, headRowsSlot );\n\n\t// Table <tbody> element with all the body rows.\n\tconst tbodyElement = writer.createContainerElement( 'tbody', null, bodyRowsSlot );\n\n\t// Table contents element containing <thead> and <tbody> when necessary.\n\tconst tableContentElements: Array<ViewContainerElement> = [];\n\n\tif ( headingRows ) {\n\t\ttableContentElements.push( theadElement );\n\t}\n\n\tif ( headingRows < table.childCount ) {\n\t\ttableContentElements.push( tbodyElement );\n\t}\n\n\t// Create table structure.\n\t//\n\t// <table>\n\t//    {children-slot-like-caption}\n\t//    <thead>\n\t//        {table-head-rows-slot}\n\t//    </thead>\n\t//    <tbody>\n\t//        {table-body-rows-slot}\n\t//    </tbody>\n\t// </table>\n\treturn writer.createContainerElement( 'table', null, [ childrenSlot, ...tableContentElements ] );\n}\n\n/**\n * Register table border and background attributes converters.\n */\nfunction downcastTableBorderAndBackgroundAttributes( editor: Editor ) {\n\tconst modelAttributes = {\n\t\t'border-width': 'tableBorderWidth',\n\t\t'border-color': 'tableBorderColor',\n\t\t'border-style': 'tableBorderStyle',\n\t\t'background-color': 'tableBackgroundColor'\n\t};\n\n\tfor ( const [ styleName, modelAttribute ] of Object.entries( modelAttributes ) ) {\n\t\teditor.conversion.for( 'dataDowncast' ).add( dispatcher => {\n\t\t\treturn dispatcher.on( `attribute:${ modelAttribute }:table`, ( evt, data, conversionApi ) => {\n\t\t\t\tconst { item, attributeNewValue } = data;\n\t\t\t\tconst { mapper, writer } = conversionApi;\n\n\t\t\t\tif ( !conversionApi.consumable.consume( item, evt.name ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst table = mapper.toViewElement( item );\n\n\t\t\t\tif ( attributeNewValue ) {\n\t\t\t\t\twriter.setStyle( styleName, attributeNewValue, table );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeStyle( styleName, table );\n\t\t\t\t}\n\t\t\t}, { priority: 'high' } );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/ui/widget\n */\n\nimport type { ViewDocumentFragment, ViewDocumentSelection, ViewElement, ViewNode } from 'ckeditor5/src/engine.js';\n\nimport { isWidget } from 'ckeditor5/src/widget.js';\n\n/**\n * Depending on the position of the selection either return the selected table or the table higher in the hierarchy.\n */\nexport function getSelectionAffectedTableWidget( selection: ViewDocumentSelection ): ViewElement | null {\n\tconst selectedTable = getSelectedTableWidget( selection );\n\n\tif ( selectedTable ) {\n\t\treturn selectedTable;\n\t}\n\n\treturn getTableWidgetAncestor( selection );\n}\n\n/**\n * Returns a table widget editing view element if one is selected.\n */\nexport function getSelectedTableWidget( selection: ViewDocumentSelection ): ViewElement | null {\n\tconst viewElement = selection.getSelectedElement();\n\n\tif ( viewElement && isTableWidget( viewElement ) ) {\n\t\treturn viewElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns a table widget editing view element if one is among the selection's ancestors.\n */\nexport function getTableWidgetAncestor( selection: ViewDocumentSelection ): ViewElement | null {\n\tconst selectionPosition = selection.getFirstPosition();\n\n\tif ( !selectionPosition ) {\n\t\treturn null;\n\t}\n\n\tlet parent: ViewNode | ViewDocumentFragment | null = selectionPosition.parent;\n\n\twhile ( parent ) {\n\t\tif ( parent.is( 'element' ) && isTableWidget( parent ) ) {\n\t\t\treturn parent;\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\treturn null;\n}\n\n/**\n * Checks if a given view element is a table widget.\n */\nfunction isTableWidget( viewElement: ViewElement ): boolean {\n\treturn !!viewElement.getCustomProperty( 'table' ) && isWidget( viewElement );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tabletoolbar\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { WidgetToolbarRepository } from 'ckeditor5/src/widget.js';\nimport { getSelectedTableWidget, getTableWidgetAncestor } from './utils/ui/widget.js';\n\n/**\n * The table toolbar class. It creates toolbars for the table feature and its content (for now only for the table cell content).\n *\n * The table toolbar shows up when a table widget is selected. Its components (e.g. buttons) are created based on the\n * {@link module:table/tableconfig~TableConfig#tableToolbar `table.tableToolbar` configuration option}.\n *\n * Table content toolbar shows up when the selection is inside the content of a table. It creates its component based on the\n * {@link module:table/tableconfig~TableConfig#contentToolbar `table.contentToolbar` configuration option}.\n */\nexport default class TableToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ WidgetToolbarRepository ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableToolbar' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic afterInit(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n\n\t\tconst tableContentToolbarItems = editor.config.get( 'table.contentToolbar' );\n\n\t\tconst tableToolbarItems = editor.config.get( 'table.tableToolbar' );\n\n\t\tif ( tableContentToolbarItems ) {\n\t\t\twidgetToolbarRepository.register( 'tableContent', {\n\t\t\t\tariaLabel: t( 'Table toolbar' ),\n\t\t\t\titems: tableContentToolbarItems,\n\t\t\t\tgetRelatedElement: getTableWidgetAncestor\n\t\t\t} );\n\t\t}\n\n\t\tif ( tableToolbarItems ) {\n\t\t\twidgetToolbarRepository.register( 'table', {\n\t\t\t\tariaLabel: t( 'Table toolbar' ),\n\t\t\t\titems: tableToolbarItems,\n\t\t\t\tgetRelatedElement: getSelectedTableWidget\n\t\t\t} );\n\t\t}\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/ui/colorinputview\n */\n\nimport {\n\tView,\n\tInputTextView,\n\tcreateDropdown,\n\tFocusCycler,\n\tViewCollection,\n\tColorSelectorView,\n\ttype ColorDefinition,\n\ttype DropdownView,\n\ttype ColorPickerConfig,\n\ttype ColorSelectorExecuteEvent,\n\ttype ColorSelectorColorPickerCancelEvent,\n\ttype FocusableView\n} from 'ckeditor5/src/ui.js';\n\nimport { FocusTracker, KeystrokeHandler, type Locale } from 'ckeditor5/src/utils.js';\n\nimport '../../theme/colorinput.css';\n\nexport type ColorInputViewOptions = {\n\tcolorDefinitions: Array<ColorDefinition>;\n\tcolumns: number;\n\tdefaultColorValue?: string;\n\tcolorPickerConfig: false | ColorPickerConfig;\n};\n\n/**\n * The color input view class. It allows the user to type in a color (hex, rgb, etc.)\n * or choose it from the configurable color palette with a preview.\n *\n * @internal\n */\nexport default class ColorInputView extends View implements FocusableView {\n\t/**\n\t * The value of the input.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public value: string;\n\n\t/**\n\t * Controls whether the input view is in read-only mode.\n\t *\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public isReadOnly: boolean;\n\n\t/**\n\t * An observable flag set to `true` when the input is focused by the user.\n\t * `false` otherwise.\n\t *\n\t * @observable\n\t * @default false\n\t */\n\tdeclare public readonly isFocused: boolean;\n\n\t/**\n\t * An observable flag set to `true` when the input contains no text.\n\t *\n\t * @observable\n\t * @default true\n\t */\n\tdeclare public readonly isEmpty: boolean;\n\n\t/**\n\t * @observable\n\t */\n\tdeclare public hasError: boolean;\n\n\t/**\n\t * A cached reference to the options passed to the constructor.\n\t */\n\tpublic options: ColorInputViewOptions;\n\n\t/**\n\t * Tracks information about the DOM focus in the view.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * Helps cycling over focusable children in the input view.\n\t */\n\tpublic readonly focusCycler: FocusCycler;\n\n\t/**\n\t * A collection of views that can be focused in the view.\n\t */\n\tprotected readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * An instance of the dropdown allowing to select a color from a grid.\n\t */\n\tpublic dropdownView: DropdownView;\n\n\t/**\n\t * An instance of the input allowing the user to type a color value.\n\t */\n\tpublic inputView: InputTextView;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * The flag that indicates whether the user is still typing.\n\t * If set to true, it means that the text input field ({@link #inputView}) still has the focus.\n\t * So, we should interrupt the user by replacing the input's value.\n\t */\n\tprotected _stillTyping: boolean;\n\n\t/**\n\t * Creates an instance of the color input view.\n\t *\n\t * @param locale The locale instance.\n\t * @param options The input options.\n\t * @param options.colorDefinitions The colors to be displayed in the palette inside the input's dropdown.\n\t * @param options.columns The number of columns in which the colors will be displayed.\n\t * @param options.defaultColorValue If specified, the color input view will replace the \"Remove color\" button with\n\t * the \"Restore default\" button. Instead of clearing the input field, the default color value will be set.\n\t */\n\tconstructor( locale: Locale, options: ColorInputViewOptions ) {\n\t\tsuper( locale );\n\n\t\tthis.set( 'value', '' );\n\t\tthis.set( 'isReadOnly', false );\n\t\tthis.set( 'isFocused', false );\n\t\tthis.set( 'isEmpty', true );\n\n\t\tthis.options = options;\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis._focusables = new ViewCollection();\n\t\tthis.dropdownView = this._createDropdownView();\n\t\tthis.inputView = this._createInputTextView();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis._stillTyping = false;\n\n\t\tthis.focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate items backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate items forwards using the <kbd>Tab</kbd> key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-input-color'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.dropdownView,\n\t\t\t\tthis.inputView\n\t\t\t]\n\t\t} );\n\n\t\tthis.on( 'change:value', ( evt, name, inputValue ) => this._setInputValue( inputValue ) );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t[ this.inputView, this.dropdownView.buttonView ].forEach( view => {\n\t\t\tthis.focusTracker.add( view.element! );\n\t\t\tthis._focusables.add( view );\n\t\t} );\n\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * Focuses the view.\n\t */\n\tpublic focus( direction: 1 | -1 ): void {\n\t\tif ( direction === -1 ) {\n\t\t\tthis.focusCycler.focusLast();\n\t\t} else {\n\t\t\tthis.focusCycler.focusFirst();\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Creates and configures the {@link #dropdownView}.\n\t */\n\tprivate _createDropdownView() {\n\t\tconst locale = this.locale!;\n\t\tconst t = locale.t;\n\t\tconst bind = this.bindTemplate;\n\t\tconst colorSelector = this._createColorSelector( locale );\n\t\tconst dropdown = createDropdown( locale );\n\t\tconst colorPreview = new View();\n\n\t\tcolorPreview.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-input-color__button__preview'\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\tbackgroundColor: bind.to( 'value' )\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: [ {\n\t\t\t\ttag: 'span',\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: [\n\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t'ck-input-color__button__preview__no-color-indicator',\n\t\t\t\t\t\tbind.if( 'value', 'ck-hidden', value => value != '' )\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t} ]\n\t\t} );\n\n\t\tdropdown.buttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-input-color__button'\n\t\t\t}\n\t\t} );\n\n\t\tdropdown.buttonView.children.add( colorPreview );\n\t\tdropdown.buttonView.label = t( 'Color picker' );\n\t\tdropdown.buttonView.tooltip = true;\n\n\t\tdropdown.panelPosition = locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw';\n\t\tdropdown.panelView.children.add( colorSelector );\n\t\tdropdown.bind( 'isEnabled' ).to( this, 'isReadOnly', value => !value );\n\n\t\tdropdown.on( 'change:isOpen', ( evt, name, isVisible ) => {\n\t\t\tif ( isVisible ) {\n\t\t\t\tcolorSelector.updateSelectedColors();\n\t\t\t\tcolorSelector.showColorGridsFragment();\n\t\t\t}\n\t\t} );\n\n\t\treturn dropdown;\n\t}\n\n\t/**\n\t * Creates and configures an instance of {@link module:ui/inputtext/inputtextview~InputTextView}.\n\t *\n\t * @returns A configured instance to be set as {@link #inputView}.\n\t */\n\tprivate _createInputTextView(): InputTextView {\n\t\tconst locale = this.locale;\n\t\tconst inputView = new InputTextView( locale );\n\n\t\tinputView.extendTemplate( {\n\t\t\ton: {\n\t\t\t\tblur: inputView.bindTemplate.to( 'blur' )\n\t\t\t}\n\t\t} );\n\n\t\tinputView.value = this.value;\n\t\tinputView.bind( 'isReadOnly', 'hasError' ).to( this );\n\t\tthis.bind( 'isFocused', 'isEmpty' ).to( inputView );\n\n\t\tinputView.on( 'input', () => {\n\t\t\tconst inputValue = inputView.element!.value;\n\t\t\t// Check if the value matches one of our defined colors' label.\n\t\t\tconst mappedColor = this.options.colorDefinitions.find( def => inputValue === def.label );\n\n\t\t\tthis._stillTyping = true;\n\t\t\tthis.value = mappedColor && mappedColor.color || inputValue;\n\t\t} );\n\n\t\tinputView.on( 'blur', () => {\n\t\t\tthis._stillTyping = false;\n\t\t\tthis._setInputValue( inputView.element!.value );\n\t\t} );\n\n\t\tinputView.delegate( 'input' ).to( this );\n\n\t\treturn inputView;\n\t}\n\n\t/**\n\t * Creates and configures the panel with \"color grid\" and \"color picker\" inside the {@link #dropdownView}.\n\t */\n\tprivate _createColorSelector( locale: Locale ) {\n\t\tconst t = locale.t;\n\t\tconst defaultColor = this.options.defaultColorValue || '';\n\t\tconst removeColorButtonLabel = defaultColor ? t( 'Restore default' ) : t( 'Remove color' );\n\n\t\tconst colorSelector = new ColorSelectorView( locale, {\n\t\t\tcolors: this.options.colorDefinitions,\n\t\t\tcolumns: this.options.columns,\n\t\t\tremoveButtonLabel: removeColorButtonLabel,\n\t\t\tcolorPickerLabel: t( 'Color picker' ),\n\t\t\tcolorPickerViewConfig: this.options.colorPickerConfig === false ? false : {\n\t\t\t\t...this.options.colorPickerConfig,\n\t\t\t\thideInput: true\n\t\t\t}\n\t\t} );\n\n\t\tcolorSelector.appendUI();\n\n\t\tcolorSelector.on<ColorSelectorExecuteEvent>( 'execute', ( evt, data ) => {\n\t\t\tif ( data.source === 'colorPickerSaveButton' ) {\n\t\t\t\tthis.dropdownView.isOpen = false;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.value = data.value || defaultColor;\n\n\t\t\t// Trigger the listener that actually applies the set value.\n\t\t\tthis.fire( 'input' );\n\n\t\t\tif ( data.source !== 'colorPicker' ) {\n\t\t\t\tthis.dropdownView.isOpen = false;\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Color is saved before changes in color picker. In case \"cancel button\" is pressed\n\t\t * this color will be applied.\n\t\t */\n\t\tlet backupColor = this.value;\n\n\t\tcolorSelector.on<ColorSelectorColorPickerCancelEvent>( 'colorPicker:cancel', () => {\n\t\t\t/**\n\t\t\t * Revert color to previous value before changes in color picker.\n\t\t\t */\n\t\t\tthis.value = backupColor;\n\n\t\t\tthis.fire( 'input' );\n\n\t\t\tthis.dropdownView.isOpen = false;\n\t\t} );\n\n\t\tcolorSelector.colorGridsFragmentView.colorPickerButtonView!.on( 'execute', () => {\n\t\t\t/**\n\t\t\t * Save color value before changes in color picker.\n\t\t\t */\n\t\t\tbackupColor = this.value;\n\t\t} );\n\n\t\tcolorSelector.bind( 'selectedColor' ).to( this, 'value' );\n\n\t\treturn colorSelector;\n\t}\n\n\t/**\n\t * Sets {@link #inputView}'s value property to the color value or color label,\n\t * if there is one and the user is not typing.\n\t *\n\t * Handles cases like:\n\t *\n\t * * Someone picks the color in the grid.\n\t * * The color is set from the plugin level.\n\t *\n\t * @param inputValue Color value to be set.\n\t */\n\tprivate _setInputValue( inputValue: string ) {\n\t\tif ( !this._stillTyping ) {\n\t\t\tconst normalizedInputValue = normalizeColor( inputValue );\n\t\t\t// Check if the value matches one of our defined colors.\n\t\t\tconst mappedColor = this.options.colorDefinitions.find( def => normalizedInputValue === normalizeColor( def.color ) );\n\n\t\t\tif ( mappedColor ) {\n\t\t\t\tthis.inputView.value = mappedColor.label;\n\t\t\t} else {\n\t\t\t\tthis.inputView.value = inputValue || '';\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Normalizes color value, by stripping extensive whitespace.\n * For example., transforms:\n * * `   rgb(  25 50    0 )` to `rgb(25 50 0)`,\n * * \"\\t  rgb(  25 ,  50,0 )\t\t\" to `rgb(25 50 0)`.\n *\n * @param colorString The value to be normalized.\n */\nfunction normalizeColor( colorString: string ): string {\n\treturn colorString\n\t\t// Remove any whitespace right after `(` or `,`.\n\t\t.replace( /([(,])\\s+/g, '$1' )\n\t\t// Remove any whitespace at the beginning or right before the end, `)`, `,`, or another whitespace.\n\t\t.replace( /^\\s+|\\s+(?=[),\\s]|$)/g, '' )\n\t\t// Then, replace `,` or whitespace with a single space.\n\t\t.replace( /,|\\s/g, ' ' );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/ui/table-properties\n */\n\nimport {\n\tButtonView,\n\tViewModel,\n\ttype ColorOption,\n\ttype LabeledFieldView,\n\ttype ListDropdownItemDefinition,\n\ttype NormalizedColorOption,\n\ttype ToolbarView,\n\ttype View,\n\ttype ColorPickerConfig\n} from 'ckeditor5/src/ui.js';\n\nimport { Collection, type LocaleTranslate } from 'ckeditor5/src/utils.js';\nimport { isColor, isLength, isPercentage } from 'ckeditor5/src/engine.js';\n\nimport type TableCellPropertiesView from '../../tablecellproperties/ui/tablecellpropertiesview.js';\nimport type TablePropertiesView from '../../tableproperties/ui/tablepropertiesview.js';\n\nimport ColorInputView from '../../ui/colorinputview.js';\n\nconst isEmpty = ( val: string ) => val === '';\n\n/**\n * Returns an object containing pairs of CSS border style values and their localized UI\n * labels. Used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}\n * and {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView}.\n *\n * @param t The \"t\" function provided by the editor that is used to localize strings.\n */\nexport function getBorderStyleLabels( t: LocaleTranslate ): Record<string, string> {\n\treturn {\n\t\tnone: t( 'None' ),\n\t\tsolid: t( 'Solid' ),\n\t\tdotted: t( 'Dotted' ),\n\t\tdashed: t( 'Dashed' ),\n\t\tdouble: t( 'Double' ),\n\t\tgroove: t( 'Groove' ),\n\t\tridge: t( 'Ridge' ),\n\t\tinset: t( 'Inset' ),\n\t\toutset: t( 'Outset' )\n\t};\n}\n\n/**\n * Returns a localized error string that can be displayed next to color (background, border)\n * fields that have an invalid value.\n *\n * @param t The \"t\" function provided by the editor that is used to localize strings.\n */\nexport function getLocalizedColorErrorText( t: LocaleTranslate ): string {\n\treturn t( 'The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".' );\n}\n\n/**\n * Returns a localized error string that can be displayed next to length (padding, border width)\n * fields that have an invalid value.\n *\n * @param t The \"t\" function provided by the editor that is used to localize strings.\n */\nexport function getLocalizedLengthErrorText( t: LocaleTranslate ): string {\n\treturn t( 'The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".' );\n}\n\n/**\n * Returns `true` when the passed value is an empty string or a valid CSS color expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isColor}.\n */\nexport function colorFieldValidator( value: string ): boolean {\n\tvalue = value.trim().toLowerCase();\n\n\treturn isEmpty( value ) || isColor( value );\n}\n\n/**\n * Returns `true` when the passed value is an empty string, a number without a unit or a valid CSS length expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isLength}.\n * See {@link module:engine/view/styles/utils~isPercentage}.\n */\nexport function lengthFieldValidator( value: string ): boolean {\n\tvalue = value.trim();\n\n\treturn isEmpty( value ) || isNumberString( value ) || isLength( value ) || isPercentage( value );\n}\n\n/**\n * Returns `true` when the passed value is an empty string, a number without a unit or a valid CSS length expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isLength}.\n */\nexport function lineWidthFieldValidator( value: string ): boolean {\n\tvalue = value.trim();\n\n\treturn isEmpty( value ) || isNumberString( value ) || isLength( value );\n}\n\n/**\n * Generates item definitions for a UI dropdown that allows changing the border style of a table or a table cell.\n *\n * @param defaultStyle The default border.\n */\nexport function getBorderStyleDefinitions(\n\tview: TableCellPropertiesView | TablePropertiesView,\n\tdefaultStyle: string\n): Collection<ListDropdownItemDefinition> {\n\tconst itemDefinitions: Collection<ListDropdownItemDefinition> = new Collection();\n\tconst styleLabels = getBorderStyleLabels( view.t! );\n\n\tfor ( const style in styleLabels ) {\n\t\tconst definition: ListDropdownItemDefinition = {\n\t\t\ttype: 'button',\n\t\t\tmodel: new ViewModel( {\n\t\t\t\t_borderStyleValue: style,\n\t\t\t\tlabel: styleLabels[ style ],\n\t\t\t\trole: 'menuitemradio',\n\t\t\t\twithText: true\n\t\t\t} )\n\t\t};\n\n\t\tif ( style === 'none' ) {\n\t\t\tdefinition.model.bind( 'isOn' ).to( view, 'borderStyle', value => {\n\t\t\t\tif ( defaultStyle === 'none' ) {\n\t\t\t\t\treturn !value;\n\t\t\t\t}\n\n\t\t\t\treturn value === style;\n\t\t\t} );\n\t\t} else {\n\t\t\tdefinition.model.bind( 'isOn' ).to( view, 'borderStyle', value => {\n\t\t\t\treturn value === style;\n\t\t\t} );\n\t\t}\n\n\t\titemDefinitions.add( definition );\n\t}\n\n\treturn itemDefinitions;\n}\n\n/**\n * A helper that fills a toolbar with buttons that:\n *\n * * have some labels,\n * * have some icons,\n * * set a certain UI view property value upon execution.\n *\n * @param nameToValue A function that maps a button name to a value. By default names are the same as values.\n */\nexport function fillToolbar<TView extends View, TPropertyName extends keyof TView>(\n\toptions: {\n\t\tview: TView;\n\t\ticons: Record<string, string>;\n\t\ttoolbar: ToolbarView;\n\t\tlabels: Record<number, string>;\n\t\tpropertyName: TPropertyName;\n\t\tnameToValue?: ( name: string ) => string;\n\t\tdefaultValue?: string;\n\t}\n): void {\n\tconst { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;\n\tfor ( const name in labels ) {\n\t\tconst button = new ButtonView( view.locale );\n\n\t\tbutton.set( {\n\t\t\tlabel: labels[ name ],\n\t\t\ticon: icons[ name ],\n\t\t\ttooltip: labels[ name ]\n\t\t} );\n\n\t\t// If specified the `nameToValue()` callback, map the value based on the option's name.\n\t\tconst buttonValue = nameToValue ? nameToValue( name ) : name;\n\n\t\tbutton.bind( 'isOn' ).to( view, propertyName, value => {\n\t\t\t// `value` comes from `view[ propertyName ]`.\n\t\t\tlet valueToCompare: unknown = value;\n\n\t\t\t// If it's empty, and the `defaultValue` is specified, use it instead.\n\t\t\tif ( value === '' && defaultValue ) {\n\t\t\t\tvalueToCompare = defaultValue;\n\t\t\t}\n\n\t\t\treturn buttonValue === valueToCompare;\n\t\t} );\n\n\t\tbutton.on( 'execute', () => {\n\t\t\tview[ propertyName ] = buttonValue as any;\n\t\t} );\n\n\t\ttoolbar.items.add( button );\n\t}\n}\n\n/**\n * A default color palette used by various user interfaces related to tables, for instance,\n * by {@link module:table/tablecellproperties/tablecellpropertiesui~TableCellPropertiesUI} or\n * {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI}.\n *\n * The color palette follows the {@link module:table/tableconfig~TableColorConfig table color configuration format}\n * and contains the following color definitions:\n *\n * ```ts\n * const defaultColors = [\n *   {\n *     color: 'hsl(0, 0%, 0%)',\n *     label: 'Black'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 30%)',\n *     label: 'Dim grey'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 60%)',\n *     label: 'Grey'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 90%)',\n *     label: 'Light grey'\n *   },\n *   {\n *     color: 'hsl(0, 0%, 100%)',\n *     label: 'White',\n *     hasBorder: true\n *   },\n *   {\n *     color: 'hsl(0, 75%, 60%)',\n *     label: 'Red'\n *   },\n *   {\n *     color: 'hsl(30, 75%, 60%)',\n *     label: 'Orange'\n *   },\n *   {\n *     color: 'hsl(60, 75%, 60%)',\n *     label: 'Yellow'\n *   },\n *   {\n *     color: 'hsl(90, 75%, 60%)',\n *     label: 'Light green'\n *   },\n *   {\n *     color: 'hsl(120, 75%, 60%)',\n *     label: 'Green'\n *   },\n *   {\n *     color: 'hsl(150, 75%, 60%)',\n *     label: 'Aquamarine'\n *   },\n *   {\n *     color: 'hsl(180, 75%, 60%)',\n *     label: 'Turquoise'\n *   },\n *   {\n *     color: 'hsl(210, 75%, 60%)',\n *     label: 'Light blue'\n *   },\n *   {\n *     color: 'hsl(240, 75%, 60%)',\n *     label: 'Blue'\n *   },\n *   {\n *     color: 'hsl(270, 75%, 60%)',\n *     label: 'Purple'\n *   }\n * ];\n * ```\n */\nexport const defaultColors: Array<ColorOption> = [\n\t{\n\t\tcolor: 'hsl(0, 0%, 0%)',\n\t\tlabel: 'Black'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 30%)',\n\t\tlabel: 'Dim grey'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 60%)',\n\t\tlabel: 'Grey'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 90%)',\n\t\tlabel: 'Light grey'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 100%)',\n\t\tlabel: 'White',\n\t\thasBorder: true\n\t},\n\t{\n\t\tcolor: 'hsl(0, 75%, 60%)',\n\t\tlabel: 'Red'\n\t},\n\t{\n\t\tcolor: 'hsl(30, 75%, 60%)',\n\t\tlabel: 'Orange'\n\t},\n\t{\n\t\tcolor: 'hsl(60, 75%, 60%)',\n\t\tlabel: 'Yellow'\n\t},\n\t{\n\t\tcolor: 'hsl(90, 75%, 60%)',\n\t\tlabel: 'Light green'\n\t},\n\t{\n\t\tcolor: 'hsl(120, 75%, 60%)',\n\t\tlabel: 'Green'\n\t},\n\t{\n\t\tcolor: 'hsl(150, 75%, 60%)',\n\t\tlabel: 'Aquamarine'\n\t},\n\t{\n\t\tcolor: 'hsl(180, 75%, 60%)',\n\t\tlabel: 'Turquoise'\n\t},\n\t{\n\t\tcolor: 'hsl(210, 75%, 60%)',\n\t\tlabel: 'Light blue'\n\t},\n\t{\n\t\tcolor: 'hsl(240, 75%, 60%)',\n\t\tlabel: 'Blue'\n\t},\n\t{\n\t\tcolor: 'hsl(270, 75%, 60%)',\n\t\tlabel: 'Purple'\n\t}\n];\n\n/**\n * Returns a creator for a color input with a label.\n *\n * For given options, it returns a function that creates an instance of a\n * {@link module:table/ui/colorinputview~ColorInputView color input} logically related to\n * a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in the DOM.\n *\n * The helper does the following:\n *\n * * It sets the color input `id` and `ariaDescribedById` attributes.\n * * It binds the color input `isReadOnly` to the labeled view.\n * * It binds the color input `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when the user starts typing in the color input.\n *\n * Usage:\n *\n * ```ts\n * const colorInputCreator = getLabeledColorInputCreator( {\n *   colorConfig: [ ... ],\n *   columns: 3,\n * } );\n *\n * const labeledInputView = new LabeledFieldView( locale, colorInputCreator );\n * console.log( labeledInputView.view ); // A color input instance.\n * ```\n *\n * @internal\n * @param options Color input options.\n * @param options.colorConfig The configuration of the color palette displayed in the input's dropdown.\n * @param options.columns The configuration of the number of columns the color palette consists of in the input's dropdown.\n * @param options.defaultColorValue If specified, the color input view will replace the \"Remove color\" button with\n * the \"Restore default\" button. Instead of clearing the input field, the default color value will be set.\n * @param options.colorPickerConfig The configuration of the color picker. You could disable it or define your output format.\n */\nexport function getLabeledColorInputCreator(\n\toptions: {\n\t\tcolorConfig: Array<NormalizedColorOption>;\n\t\tcolumns: number;\n\t\tdefaultColorValue?: string;\n\t\tcolorPickerConfig: false | ColorPickerConfig;\n\t}\n) {\n\treturn ( labeledFieldView: LabeledFieldView, viewUid: string, statusUid: string ): ColorInputView => {\n\t\tconst colorInputView = new ColorInputView( labeledFieldView.locale!, {\n\t\t\tcolorDefinitions: colorConfigToColorGridDefinitions( options.colorConfig ),\n\t\t\tcolumns: options.columns,\n\t\t\tdefaultColorValue: options.defaultColorValue,\n\t\t\tcolorPickerConfig: options.colorPickerConfig\n\t\t} );\n\n\t\tcolorInputView.inputView.set( {\n\t\t\tid: viewUid,\n\t\t\tariaDescribedById: statusUid\n\t\t} );\n\n\t\tcolorInputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );\n\t\tcolorInputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );\n\n\t\tcolorInputView.on( 'input', () => {\n\t\t\t// UX: Make the error text disappear and disable the error indicator as the user\n\t\t\t// starts fixing the errors.\n\t\t\tlabeledFieldView.errorText = null;\n\t\t} );\n\n\t\tlabeledFieldView.bind( 'isEmpty', 'isFocused' ).to( colorInputView );\n\n\t\treturn colorInputView;\n\t};\n}\n\n/**\n * A simple helper method to detect number strings.\n * I allows full number notation, so omitting 0 is not allowed:\n */\nfunction isNumberString( value: string ) {\n\tconst parsedValue = parseFloat( value );\n\n\treturn !Number.isNaN( parsedValue ) && value === String( parsedValue );\n}\n\nfunction colorConfigToColorGridDefinitions( colorConfig: Array<NormalizedColorOption> ) {\n\treturn colorConfig.map( item => ( {\n\t\tcolor: item.model,\n\t\tlabel: item.label,\n\t\toptions: {\n\t\t\thasBorder: item.hasBorder\n\t\t}\n\t} ) );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/ui/formrowview\n */\n\nimport { View, type LabelView, type ViewCollection } from 'ckeditor5/src/ui.js';\nimport type { Locale } from 'ckeditor5/src/utils.js';\n\nimport '../../theme/formrow.css';\n\n/**\n * The class representing a single row in a complex form,\n * used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}.\n *\n * **Note**: For now this class is private. When more use cases arrive (beyond ckeditor5-table),\n * it will become a component in ckeditor5-ui.\n *\n * @internal\n */\nexport default class FormRowView extends View {\n\t/**\n\t * An additional CSS class added to the {@link #element}.\n\t *\n\t * @observable\n\t */\n\tpublic declare class: string | null;\n\n\t/**\n\t * A collection of row items (buttons, dropdowns, etc.).\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * The role property reflected by the `role` DOM attribute of the {@link #element}.\n\t *\n\t * **Note**: Used only when a `labelView` is passed to constructor `options`.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tpublic declare _role: string | null;\n\n\t/**\n\t * The ARIA property reflected by the `aria-labelledby` DOM attribute of the {@link #element}.\n\t *\n\t * **Note**: Used only when a `labelView` is passed to constructor `options`.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tpublic declare _ariaLabelledBy: string | null;\n\n\t/**\n\t * Creates an instance of the form row class.\n\t *\n\t * @param locale The locale instance.\n\t * @param options.labelView When passed, the row gets the `group` and `aria-labelledby`\n\t * DOM attributes and gets described by the label.\n\t */\n\tconstructor( locale: Locale, options: { children?: Array<View>; class?: string; labelView?: LabelView } = {} ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\tthis.set( 'class', options.class || null );\n\t\tthis.children = this.createCollection();\n\n\t\tif ( options.children ) {\n\t\t\toptions.children.forEach( child => this.children.add( child ) );\n\t\t}\n\n\t\tthis.set( '_role', null );\n\t\tthis.set( '_ariaLabelledBy', null );\n\n\t\tif ( options.labelView ) {\n\t\t\tthis.set( {\n\t\t\t\t_role: 'group',\n\t\t\t\t_ariaLabelledBy: options.labelView.id\n\t\t\t} );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form__row',\n\t\t\t\t\tbind.to( 'class' )\n\t\t\t\t],\n\t\t\t\trole: bind.to( '_role' ),\n\t\t\t\t'aria-labelledby': bind.to( '_ariaLabelledBy' )\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/ui/tablecellpropertiesview\n */\n\nimport {\n\taddListToDropdown,\n\tButtonView,\n\tcreateLabeledDropdown,\n\tcreateLabeledInputText,\n\tFocusCycler,\n\tFormHeaderView,\n\tLabeledFieldView,\n\tLabelView,\n\tsubmitHandler,\n\tToolbarView,\n\tView,\n\tViewCollection,\n\ttype FocusableView,\n\ttype NormalizedColorOption,\n\ttype ColorPickerConfig\n} from 'ckeditor5/src/ui.js';\nimport {\n\tKeystrokeHandler,\n\tFocusTracker,\n\ttype Locale,\n\ttype ObservableChangeEvent\n} from 'ckeditor5/src/utils.js';\nimport { icons } from 'ckeditor5/src/core.js';\n\nimport {\n\tfillToolbar,\n\tgetBorderStyleDefinitions,\n\tgetBorderStyleLabels,\n\tgetLabeledColorInputCreator\n} from '../../utils/ui/table-properties.js';\nimport FormRowView from '../../ui/formrowview.js';\nimport type ColorInputView from '../../ui/colorinputview.js';\nimport type { TableCellPropertiesOptions } from '../../tableconfig.js';\n\nimport '../../../theme/form.css';\nimport '../../../theme/tableform.css';\nimport '../../../theme/tablecellproperties.css';\n\nexport interface TableCellPropertiesViewOptions {\n\tborderColors: Array<NormalizedColorOption>;\n\tbackgroundColors: Array<NormalizedColorOption>;\n\tdefaultTableCellProperties: TableCellPropertiesOptions;\n\tcolorPickerConfig: false | ColorPickerConfig;\n}\n\n/**\n * The class representing a table cell properties form, allowing users to customize\n * certain style aspects of a table cell, for instance, border, padding, text alignment, etc..\n */\nexport default class TableCellPropertiesView extends View {\n\t/**\n\t * The value of the cell border style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare borderStyle: string;\n\n\t/**\n\t * The value of the cell border width style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare borderWidth: string;\n\n\t/**\n\t * The value of the cell border color style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare borderColor: string;\n\n\t/**\n\t * The value of the cell padding style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare padding: string;\n\n\t/**\n\t * The value of the cell background color style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare backgroundColor: string;\n\n\t/**\n\t * The value of the table cell width style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare width: string;\n\n\t/**\n\t * The value of the table cell height style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare height: string;\n\n\t/**\n\t * The value of the horizontal text alignment style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare horizontalAlignment: string;\n\n\t/**\n\t * The value of the vertical text alignment style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tpublic declare verticalAlignment: string;\n\n\t/**\n\t * Options passed to the view. See {@link #constructor} to learn more.\n\t */\n\tpublic readonly options: TableCellPropertiesViewOptions;\n\n\t/**\n\t * Tracks information about the DOM focus in the form.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A collection of child views in the form.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * A dropdown that allows selecting the style of the table cell border.\n\t */\n\tpublic readonly borderStyleDropdown: LabeledFieldView<FocusableView>;\n\n\t/**\n\t * An input that allows specifying the width of the table cell border.\n\t */\n\tpublic readonly borderWidthInput: LabeledFieldView<FocusableView>;\n\n\t/**\n\t * An input that allows specifying the color of the table cell border.\n\t */\n\tpublic readonly borderColorInput: LabeledFieldView<ColorInputView>;\n\n\t/**\n\t * An input that allows specifying the table cell background color.\n\t */\n\tpublic readonly backgroundInput: LabeledFieldView<ColorInputView>;\n\n\t/**\n\t * An input that allows specifying the table cell padding.\n\t */\n\tpublic readonly paddingInput: LabeledFieldView;\n\n\t/**\n\t * An input that allows specifying the table cell width.\n\t */\n\tpublic readonly widthInput: LabeledFieldView<FocusableView>;\n\n\t/**\n\t * An input that allows specifying the table cell height.\n\t */\n\tpublic readonly heightInput: LabeledFieldView<FocusableView>;\n\n\t/**\n\t * A toolbar with buttons that allow changing the horizontal text alignment in a table cell.\n\t */\n\tpublic readonly horizontalAlignmentToolbar: ToolbarView;\n\n\t/**\n\t * A toolbar with buttons that allow changing the vertical text alignment in a table cell.\n\t */\n\tpublic readonly verticalAlignmentToolbar: ToolbarView;\n\n\t/**\n\t * The \"Save\" button view.\n\t */\n\tpublic saveButtonView: ButtonView;\n\n\t/**\n\t * The \"Cancel\" button view.\n\t */\n\tpublic cancelButtonView: ButtonView;\n\n\t/**\n\t * A collection of views that can be focused in the form.\n\t */\n\tprotected readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */\n\tprotected readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options Additional configuration of the view.\n\t * @param options.borderColors A configuration of the border color palette used by the\n\t * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}.\n\t * @param options.backgroundColors A configuration of the background color palette used by the\n\t * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.\n\t * @param options.defaultTableCellProperties The default table cell properties.\n\t */\n\tconstructor( locale: Locale, options: TableCellPropertiesViewOptions ) {\n\t\tsuper( locale );\n\n\t\tthis.set( {\n\t\t\tborderStyle: '',\n\t\t\tborderWidth: '',\n\t\t\tborderColor: '',\n\t\t\tpadding: '',\n\t\t\tbackgroundColor: '',\n\t\t\twidth: '',\n\t\t\theight: '',\n\t\t\thorizontalAlignment: '',\n\t\t\tverticalAlignment: ''\n\t\t} );\n\n\t\tthis.options = options;\n\n\t\tconst { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();\n\t\tconst { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();\n\t\tconst { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();\n\t\tconst { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();\n\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.children = this.createCollection();\n\t\tthis.borderStyleDropdown = borderStyleDropdown;\n\t\tthis.borderWidthInput = borderWidthInput;\n\t\tthis.borderColorInput = borderColorInput;\n\t\tthis.backgroundInput = backgroundInput;\n\t\tthis.paddingInput = this._createPaddingField();\n\t\tthis.widthInput = widthInput;\n\t\tthis.heightInput = heightInput;\n\t\tthis.horizontalAlignmentToolbar = horizontalAlignmentToolbar;\n\t\tthis.verticalAlignmentToolbar = verticalAlignmentToolbar;\n\n\t\t// Defer creating to make sure other fields are present and the Save button can\n\t\t// bind its #isEnabled to their error messages so there's no way to save unless all\n\t\t// fields are valid.\n\t\tconst { saveButtonView, cancelButtonView } = this._createActionButtons();\n\n\t\tthis.saveButtonView = saveButtonView;\n\t\tthis.cancelButtonView = cancelButtonView;\n\t\tthis._focusables = new ViewCollection();\n\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t// Form header.\n\t\tthis.children.add( new FormHeaderView( locale, {\n\t\t\tlabel: this.t!( 'Cell properties' )\n\t\t} ) );\n\n\t\t// Border row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: borderRowLabel,\n\t\t\tchildren: [\n\t\t\t\tborderRowLabel,\n\t\t\t\tborderStyleDropdown,\n\t\t\t\tborderColorInput,\n\t\t\t\tborderWidthInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__border-row'\n\t\t} ) );\n\n\t\t// Background.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: backgroundRowLabel,\n\t\t\tchildren: [\n\t\t\t\tbackgroundRowLabel,\n\t\t\t\tbackgroundInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__background-row'\n\t\t} ) );\n\n\t\t// Dimensions row and padding.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\t// Dimensions row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tlabelView: dimensionsLabel,\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tdimensionsLabel,\n\t\t\t\t\t\twidthInput,\n\t\t\t\t\t\toperatorLabel,\n\t\t\t\t\t\theightInput\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-form__dimensions-row'\n\t\t\t\t} ),\n\t\t\t\t// Padding row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tthis.paddingInput\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-cell-properties-form__padding-row'\n\t\t\t\t} )\n\t\t\t]\n\t\t} ) );\n\n\t\t// Text alignment row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: alignmentLabel,\n\t\t\tchildren: [\n\t\t\t\talignmentLabel,\n\t\t\t\thorizontalAlignmentToolbar,\n\t\t\t\tverticalAlignmentToolbar\n\t\t\t],\n\t\t\tclass: 'ck-table-cell-properties-form__alignment-row'\n\t\t} ) );\n\n\t\t// Action row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\tthis.saveButtonView,\n\t\t\t\tthis.cancelButtonView\n\t\t\t],\n\t\t\tclass: 'ck-table-form__action-row'\n\t\t} ) );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form',\n\t\t\t\t\t'ck-table-form',\n\t\t\t\t\t'ck-table-cell-properties-form'\n\t\t\t\t],\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/90\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Enable the \"submit\" event for this view. It can be triggered by the #saveButtonView\n\t\t// which is of the \"submit\" DOM \"type\".\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\t// Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.\n\t\t[ this.borderColorInput, this.backgroundInput ].forEach( view => {\n\t\t\tthis._focusCycler.chain( view.fieldView.focusCycler );\n\t\t} );\n\n\t\t[\n\t\t\tthis.borderStyleDropdown,\n\t\t\tthis.borderColorInput,\n\t\t\tthis.borderWidthInput,\n\t\t\tthis.backgroundInput,\n\t\t\tthis.widthInput,\n\t\t\tthis.heightInput,\n\t\t\tthis.paddingInput,\n\t\t\tthis.horizontalAlignmentToolbar,\n\t\t\tthis.verticalAlignmentToolbar,\n\t\t\tthis.saveButtonView,\n\t\t\tthis.cancelButtonView\n\t\t].forEach( view => {\n\t\t\t// Register the view as focusable.\n\t\t\tthis._focusables.add( view );\n\n\t\t\t// Register the view in the focus tracker.\n\t\t\tthis.focusTracker.add( view.element! );\n\t\t} );\n\n\t\t// Mainly for closing using \"Esc\" and navigation using \"Tab\".\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the fist focusable field in the form.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #borderStyleDropdown},\n\t * * {@link #borderWidthInput},\n\t * * {@link #borderColorInput}.\n\t */\n\tprivate _createBorderFields(): {\n\t\tborderRowLabel: LabelView;\n\t\tborderStyleDropdown: LabeledFieldView;\n\t\tborderColorInput: LabeledFieldView<ColorInputView>;\n\t\tborderWidthInput: LabeledFieldView;\n\t\t} {\n\t\tconst defaultTableCellProperties = this.options.defaultTableCellProperties;\n\t\tconst defaultBorder = {\n\t\t\tstyle: defaultTableCellProperties.borderStyle,\n\t\t\twidth: defaultTableCellProperties.borderWidth,\n\t\t\tcolor: defaultTableCellProperties.borderColor\n\t\t};\n\n\t\tconst colorInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.borderColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: defaultBorder.color,\n\t\t\tcolorPickerConfig: this.options.colorPickerConfig\n\t\t} );\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\t\tconst accessibleLabel = t( 'Style' );\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst borderRowLabel = new LabelView( locale );\n\t\tborderRowLabel.text = t( 'Border' );\n\n\t\t// -- Style ---------------------------------------------------\n\n\t\tconst styleLabels = getBorderStyleLabels( t );\n\t\tconst borderStyleDropdown = new LabeledFieldView( locale, createLabeledDropdown );\n\t\tborderStyleDropdown.set( {\n\t\t\tlabel: accessibleLabel,\n\t\t\tclass: 'ck-table-form__border-style'\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.set( {\n\t\t\tariaLabel: accessibleLabel,\n\t\t\tariaLabelledBy: undefined,\n\t\t\tisOn: false,\n\t\t\twithText: true,\n\t\t\ttooltip: accessibleLabel\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {\n\t\t\treturn styleLabels[ value ? value : 'none' ];\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.on( 'execute', evt => {\n\t\t\tthis.borderStyle = ( evt.source as Record<string, unknown> )._borderStyleValue as string;\n\t\t} );\n\n\t\tborderStyleDropdown.bind( 'isEmpty' ).to( this, 'borderStyle', value => !value );\n\n\t\taddListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this, defaultBorder.style! ), {\n\t\t\trole: 'menu',\n\t\t\tariaLabel: accessibleLabel\n\t\t} );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst borderWidthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\tborderWidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__border-width'\n\t\t} );\n\n\t\tborderWidthInput.fieldView.bind( 'value' ).to( this, 'borderWidth' );\n\t\tborderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\t\tborderWidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderWidth = borderWidthInput.fieldView.element!.value;\n\t\t} );\n\n\t\t// -- Color ---------------------------------------------------\n\n\t\tconst borderColorInput = new LabeledFieldView( locale, colorInputCreator );\n\n\t\tborderColorInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-form__border-color'\n\t\t} );\n\n\t\tborderColorInput.fieldView.bind( 'value' ).to( this, 'borderColor' );\n\t\tborderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\n\t\tborderColorInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderColor = borderColorInput.fieldView.value;\n\t\t} );\n\n\t\t// Reset the border color and width fields depending on the `border-style` value.\n\t\tthis.on<ObservableChangeEvent<string>>( 'change:borderStyle', ( evt, name, newValue, oldValue ) => {\n\t\t\t// When removing the border (`border-style:none`), clear the remaining `border-*` properties.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/6227.\n\t\t\tif ( !isBorderStyleSet( newValue ) ) {\n\t\t\t\tthis.borderColor = '';\n\t\t\t\tthis.borderWidth = '';\n\t\t\t}\n\n\t\t\t// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.\n\t\t\tif ( !isBorderStyleSet( oldValue ) ) {\n\t\t\t\tthis.borderColor = defaultBorder.color!;\n\t\t\t\tthis.borderWidth = defaultBorder.width!;\n\t\t\t}\n\t\t} );\n\n\t\treturn {\n\t\t\tborderRowLabel,\n\t\t\tborderStyleDropdown,\n\t\t\tborderColorInput,\n\t\t\tborderWidthInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #backgroundInput}.\n\t */\n\tprivate _createBackgroundFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst backgroundRowLabel = new LabelView( locale );\n\t\tbackgroundRowLabel.text = t( 'Background' );\n\n\t\t// -- Background color input -----------------------------------\n\n\t\tconst colorInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.backgroundColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: this.options.defaultTableCellProperties.backgroundColor,\n\t\t\tcolorPickerConfig: this.options.colorPickerConfig\n\t\t} );\n\n\t\tconst backgroundInput = new LabeledFieldView( locale, colorInputCreator );\n\n\t\tbackgroundInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-cell-properties-form__background'\n\t\t} );\n\n\t\tbackgroundInput.fieldView.bind( 'value' ).to( this, 'backgroundColor' );\n\t\tbackgroundInput.fieldView.on( 'input', () => {\n\t\t\tthis.backgroundColor = backgroundInput.fieldView.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tbackgroundRowLabel,\n\t\t\tbackgroundInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #widthInput}.\n\t * * {@link #heightInput}.\n\t */\n\tprivate _createDimensionFields(): {\n\t\tdimensionsLabel: LabelView;\n\t\twidthInput: LabeledFieldView;\n\t\toperatorLabel: View;\n\t\theightInput: LabeledFieldView;\n\t\t} {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\n\t\t// -- Label ---------------------------------------------------\n\n\t\tconst dimensionsLabel = new LabelView( locale );\n\t\tdimensionsLabel.text = t( 'Dimensions' );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst widthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\twidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__width'\n\t\t} );\n\n\t\twidthInput.fieldView.bind( 'value' ).to( this, 'width' );\n\t\twidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.width = widthInput.fieldView.element!.value;\n\t\t} );\n\n\t\t// -- Operator ---------------------------------------------------\n\n\t\tconst operatorLabel = new View( locale );\n\t\toperatorLabel.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-table-form__dimension-operator'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{ text: '×' }\n\t\t\t]\n\t\t} );\n\n\t\t// -- Height ---------------------------------------------------\n\n\t\tconst heightInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\theightInput.set( {\n\t\t\tlabel: t( 'Height' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__height'\n\t\t} );\n\n\t\theightInput.fieldView.bind( 'value' ).to( this, 'height' );\n\t\theightInput.fieldView.on( 'input', () => {\n\t\t\tthis.height = heightInput.fieldView.element!.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tdimensionsLabel,\n\t\t\twidthInput,\n\t\t\toperatorLabel,\n\t\t\theightInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #paddingInput}.\n\t */\n\tprivate _createPaddingField(): LabeledFieldView {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\n\t\tconst paddingInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\tpaddingInput.set( {\n\t\t\tlabel: t( 'Padding' ),\n\t\t\tclass: 'ck-table-cell-properties-form__padding'\n\t\t} );\n\n\t\tpaddingInput.fieldView.bind( 'value' ).to( this, 'padding' );\n\t\tpaddingInput.fieldView.on( 'input', () => {\n\t\t\tthis.padding = paddingInput.fieldView.element!.value;\n\t\t} );\n\n\t\treturn paddingInput;\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #horizontalAlignmentToolbar},\n\t * * {@link #verticalAlignmentToolbar}.\n\t */\n\tprivate _createAlignmentFields() {\n\t\tconst locale = this.locale!;\n\t\tconst t = this.t!;\n\n\t\tconst alignmentLabel = new LabelView( locale );\n\n\t\tconst ALIGNMENT_ICONS = {\n\t\t\tleft: icons.alignLeft,\n\t\t\tcenter: icons.alignCenter,\n\t\t\tright: icons.alignRight,\n\t\t\tjustify: icons.alignJustify,\n\t\t\ttop: icons.alignTop,\n\t\t\tmiddle: icons.alignMiddle,\n\t\t\tbottom: icons.alignBottom\n\t\t};\n\n\t\talignmentLabel.text = t( 'Table cell text alignment' );\n\n\t\t// -- Horizontal ---------------------------------------------------\n\n\t\tconst horizontalAlignmentToolbar = new ToolbarView( locale );\n\t\tconst isContentRTL = locale.contentLanguageDirection === 'rtl';\n\n\t\thorizontalAlignmentToolbar.set( {\n\t\t\tisCompact: true,\n\t\t\tariaLabel: t( 'Horizontal text alignment toolbar' )\n\t\t} );\n\n\t\tfillToolbar( {\n\t\t\tview: this,\n\t\t\ticons: ALIGNMENT_ICONS,\n\t\t\ttoolbar: horizontalAlignmentToolbar,\n\t\t\tlabels: this._horizontalAlignmentLabels,\n\t\t\tpropertyName: 'horizontalAlignment',\n\t\t\tnameToValue: name => {\n\t\t\t\t// For the RTL content, we want to swap the buttons \"align to the left\" and \"align to the right\".\n\t\t\t\tif ( isContentRTL ) {\n\t\t\t\t\tif ( name === 'left' ) {\n\t\t\t\t\t\treturn 'right';\n\t\t\t\t\t} else if ( name === 'right' ) {\n\t\t\t\t\t\treturn 'left';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn name;\n\t\t\t},\n\t\t\tdefaultValue: this.options.defaultTableCellProperties.horizontalAlignment\n\t\t} );\n\n\t\t// -- Vertical -----------------------------------------------------\n\n\t\tconst verticalAlignmentToolbar = new ToolbarView( locale );\n\n\t\tverticalAlignmentToolbar.set( {\n\t\t\tisCompact: true,\n\t\t\tariaLabel: t( 'Vertical text alignment toolbar' )\n\t\t} );\n\n\t\tfillToolbar( {\n\t\t\tview: this,\n\t\t\ticons: ALIGNMENT_ICONS,\n\t\t\ttoolbar: verticalAlignmentToolbar,\n\t\t\tlabels: this._verticalAlignmentLabels,\n\t\t\tpropertyName: 'verticalAlignment',\n\t\t\tdefaultValue: this.options.defaultTableCellProperties.verticalAlignment\n\t\t} );\n\n\t\treturn {\n\t\t\thorizontalAlignmentToolbar,\n\t\t\tverticalAlignmentToolbar,\n\t\t\talignmentLabel\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form controls:\n\t *\n\t * * {@link #saveButtonView},\n\t * * {@link #cancelButtonView}.\n\t */\n\tprivate _createActionButtons() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\t\tconst saveButtonView = new ButtonView( locale );\n\t\tconst cancelButtonView = new ButtonView( locale );\n\t\tconst fieldsThatShouldValidateToSave = [\n\t\t\tthis.borderWidthInput,\n\t\t\tthis.borderColorInput,\n\t\t\tthis.backgroundInput,\n\t\t\tthis.paddingInput\n\t\t];\n\n\t\tsaveButtonView.set( {\n\t\t\tlabel: t( 'Save' ),\n\t\t\ticon: icons.check,\n\t\t\tclass: 'ck-button-save',\n\t\t\ttype: 'submit',\n\t\t\twithText: true\n\t\t} );\n\n\t\tsaveButtonView.bind( 'isEnabled' ).toMany( fieldsThatShouldValidateToSave, 'errorText', ( ...errorTexts ) => {\n\t\t\treturn errorTexts.every( errorText => !errorText );\n\t\t} );\n\n\t\tcancelButtonView.set( {\n\t\t\tlabel: t( 'Cancel' ),\n\t\t\ticon: icons.cancel,\n\t\t\tclass: 'ck-button-cancel',\n\t\t\twithText: true\n\t\t} );\n\n\t\tcancelButtonView.delegate( 'execute' ).to( this, 'cancel' );\n\n\t\treturn {\n\t\t\tsaveButtonView, cancelButtonView\n\t\t};\n\t}\n\n\t/**\n\t * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.\n\t */\n\tprivate get _horizontalAlignmentLabels(): Record<string, string> {\n\t\tconst locale = this.locale!;\n\t\tconst t = this.t!;\n\n\t\tconst left = t( 'Align cell text to the left' );\n\t\tconst center = t( 'Align cell text to the center' );\n\t\tconst right = t( 'Align cell text to the right' );\n\t\tconst justify = t( 'Justify cell text' );\n\n\t\t// Returns object with a proper order of labels.\n\t\tif ( locale.uiLanguageDirection === 'rtl' ) {\n\t\t\treturn { right, center, left, justify };\n\t\t} else {\n\t\t\treturn { left, center, right, justify };\n\t\t}\n\t}\n\n\t/**\n\t * Provides localized labels for {@link #verticalAlignmentToolbar} buttons.\n\t */\n\tprivate get _verticalAlignmentLabels(): Record<string, string> {\n\t\tconst t = this.t!;\n\n\t\treturn {\n\t\t\ttop: t( 'Align cell text to the top' ),\n\t\t\tmiddle: t( 'Align cell text to the middle' ),\n\t\t\tbottom: t( 'Align cell text to the bottom' )\n\t\t};\n\t}\n}\n\nfunction isBorderStyleSet( value: string ) {\n\treturn value !== 'none';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/ui/contextualballoon\n */\n\nimport { Rect, type PositionOptions } from 'ckeditor5/src/utils.js';\nimport { BalloonPanelView, type ContextualBalloon } from 'ckeditor5/src/ui.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport type { Element, Position, Range } from 'ckeditor5/src/engine.js';\n\nimport { getSelectionAffectedTableWidget, getTableWidgetAncestor } from './widget.js';\nimport { getSelectionAffectedTable } from '../common.js';\n\nconst BALLOON_POSITIONS = /* #__PURE__ */ ( () => [\n\tBalloonPanelView.defaultPositions.northArrowSouth,\n\tBalloonPanelView.defaultPositions.northArrowSouthWest,\n\tBalloonPanelView.defaultPositions.northArrowSouthEast,\n\tBalloonPanelView.defaultPositions.southArrowNorth,\n\tBalloonPanelView.defaultPositions.southArrowNorthWest,\n\tBalloonPanelView.defaultPositions.southArrowNorthEast,\n\tBalloonPanelView.defaultPositions.viewportStickyNorth\n] )();\n\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the table in the editor content, if one is selected.\n *\n * @param editor The editor instance.\n * @param target Either \"cell\" or \"table\". Determines the target the balloon will be attached to.\n */\nexport function repositionContextualBalloon( editor: Editor, target: string ): void {\n\tconst balloon: ContextualBalloon = editor.plugins.get( 'ContextualBalloon' );\n\tconst selection = editor.editing.view.document.selection;\n\tlet position;\n\n\tif ( target === 'cell' ) {\n\t\tif ( getTableWidgetAncestor( selection ) ) {\n\t\t\tposition = getBalloonCellPositionData( editor );\n\t\t}\n\t}\n\telse if ( getSelectionAffectedTableWidget( selection ) ) {\n\t\tposition = getBalloonTablePositionData( editor );\n\t}\n\n\tif ( position ) {\n\t\tballoon.updatePosition( position );\n\t}\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected table in the editor content.\n *\n * @param editor The editor instance.\n */\nexport function getBalloonTablePositionData( editor: Editor ): Partial<PositionOptions> {\n\tconst selection = editor.model.document.selection;\n\tconst modelTable = getSelectionAffectedTable( selection );\n\tconst viewTable = editor.editing.mapper.toViewElement( modelTable )!;\n\n\treturn {\n\t\ttarget: editor.editing.view.domConverter.mapViewToDom( viewTable )!,\n\t\tpositions: BALLOON_POSITIONS\n\t};\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected table cell in the editor content.\n *\n * @param editor The editor instance.\n */\nexport function getBalloonCellPositionData( editor: Editor ): Partial<PositionOptions> {\n\tconst mapper = editor.editing.mapper;\n\tconst domConverter = editor.editing.view.domConverter;\n\tconst selection = editor.model.document.selection;\n\n\tif ( selection.rangeCount > 1 ) {\n\t\treturn {\n\t\t\ttarget: () => createBoundingRect( selection.getRanges(), editor ),\n\t\t\tpositions: BALLOON_POSITIONS\n\t\t};\n\t}\n\n\tconst modelTableCell = getTableCellAtPosition( selection.getFirstPosition()! );\n\tconst viewTableCell = mapper.toViewElement( modelTableCell )!;\n\n\treturn {\n\t\ttarget: domConverter.mapViewToDom( viewTableCell ),\n\t\tpositions: BALLOON_POSITIONS\n\t};\n}\n\n/**\n * Returns the first selected table cell from a multi-cell or in-cell selection.\n *\n * @param position Document position.\n */\nfunction getTableCellAtPosition( position: Position ): Element {\n\tconst isTableCellSelected = position.nodeAfter && position.nodeAfter.is( 'element', 'tableCell' );\n\n\treturn isTableCellSelected ? position.nodeAfter : position.findAncestor( 'tableCell' )!;\n}\n\n/**\n * Returns bounding rectangle for given model ranges.\n *\n * @param ranges Model ranges that the bounding rect should be returned for.\n * @param editor The editor instance.\n */\nfunction createBoundingRect( ranges: Iterable<Range>, editor: Editor ): Rect {\n\tconst mapper = editor.editing.mapper;\n\tconst domConverter = editor.editing.view.domConverter;\n\tconst rects = Array.from( ranges ).map( range => {\n\t\tconst modelTableCell = getTableCellAtPosition( range.start );\n\t\tconst viewTableCell = mapper.toViewElement( modelTableCell )!;\n\t\treturn new Rect( domConverter.mapViewToDom( viewTableCell )! );\n\t} );\n\n\treturn Rect.getBoundingRect( rects )!;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/table-properties\n */\n\nimport type { BoxSides } from 'ckeditor5/src/engine.js';\nimport { isObject } from 'lodash-es';\n\n/**\n * Returns a string if all four values of box sides are equal.\n *\n * If a string is passed, it is treated as a single value (pass-through).\n *\n * ```ts\n * // Returns 'foo':\n * getSingleValue( { top: 'foo', right: 'foo', bottom: 'foo', left: 'foo' } );\n * getSingleValue( 'foo' );\n *\n * // Returns undefined:\n * getSingleValue( { top: 'foo', right: 'foo', bottom: 'bar', left: 'foo' } );\n * getSingleValue( { top: 'foo', right: 'foo' } );\n * ```\n */\nexport function getSingleValue( objectOrString: BoxSides | string | undefined ): string | undefined {\n\tif ( !objectOrString || !isObject( objectOrString ) ) {\n\t\treturn objectOrString;\n\t}\n\n\tconst { top, right, bottom, left } = objectOrString;\n\n\tif ( top == right && right == bottom && bottom == left ) {\n\t\treturn top!;\n\t}\n}\n\n/**\n * Adds a unit to a value if the value is a number or a string representing a number.\n *\n * **Note**: It does nothing to non-numeric values.\n *\n * ```ts\n * getSingleValue( 25, 'px' ); // '25px'\n * getSingleValue( 25, 'em' ); // '25em'\n * getSingleValue( '25em', 'px' ); // '25em'\n * getSingleValue( 'foo', 'px' ); // 'foo'\n * ```\n *\n * @param defaultUnit A default unit added to a numeric value.\n */\nexport function addDefaultUnitToNumericValue( value: string | number | undefined, defaultUnit: string ): string | number | undefined {\n\tconst numericValue = parseFloat( value as any );\n\n\tif ( Number.isNaN( numericValue ) ) {\n\t\treturn value;\n\t}\n\n\tif ( String( numericValue ) !== String( value ) ) {\n\t\treturn value;\n\t}\n\n\treturn `${ numericValue }${ defaultUnit }`;\n}\n\nexport interface NormalizedDefaultProperties {\n\tborderStyle: string;\n\tborderWidth: string;\n\tborderColor: string;\n\tbackgroundColor: string;\n\twidth: string;\n\theight: string;\n\talignment?: string;\n\tpadding?: string;\n\tverticalAlignment?: string;\n\thorizontalAlignment?: string;\n}\n\n/**\n * Options used to determine which properties should be added to the normalized configuration.\n */\nexport type NormalizeTableDefaultPropertiesOptions = {\n\n\t/**\n\t * Whether the \"alignment\" property should be added.\n\t */\n\tincludeAlignmentProperty?: boolean;\n\n\t/**\n\t * Whether the \"padding\" property should be added.\n\t */\n\tincludePaddingProperty?: boolean;\n\n\t/**\n\t * Whether the \"verticalAlignment\" property should be added.\n\t */\n\tincludeVerticalAlignmentProperty?: boolean;\n\n\t/**\n\t * Whether the \"horizontalAlignment\" property should be added.\n\t */\n\tincludeHorizontalAlignmentProperty?: boolean;\n\n\t/**\n\t * Whether the content is right-to-left.\n\t */\n\tisRightToLeftContent?: boolean;\n};\n\n/**\n * Returns the normalized configuration.\n *\n * @param config The configuration to normalize.\n * @param options Options used to determine which properties should be added.\n */\nexport function getNormalizedDefaultProperties(\n\tconfig: Partial<NormalizedDefaultProperties> | undefined,\n\toptions: NormalizeTableDefaultPropertiesOptions = {}\n): NormalizedDefaultProperties {\n\tconst normalizedConfig: NormalizedDefaultProperties = {\n\t\tborderStyle: 'none',\n\t\tborderWidth: '',\n\t\tborderColor: '',\n\t\tbackgroundColor: '',\n\t\twidth: '',\n\t\theight: '',\n\t\t...config\n\t};\n\n\tif ( options.includeAlignmentProperty && !normalizedConfig.alignment ) {\n\t\tnormalizedConfig.alignment = 'center';\n\t}\n\n\tif ( options.includePaddingProperty && !normalizedConfig.padding ) {\n\t\tnormalizedConfig.padding = '';\n\t}\n\n\tif ( options.includeVerticalAlignmentProperty && !normalizedConfig.verticalAlignment ) {\n\t\tnormalizedConfig.verticalAlignment = 'middle';\n\t}\n\n\tif ( options.includeHorizontalAlignmentProperty && !normalizedConfig.horizontalAlignment ) {\n\t\tnormalizedConfig.horizontalAlignment = options.isRightToLeftContent ? 'right' : 'left';\n\t}\n\n\treturn normalizedConfig;\n}\n\n/**\n * Returns the normalized default table properties.\n *\n * @param config The configuration to normalize.\n * @param options Options used to determine which properties should be added.\n */\nexport function getNormalizedDefaultTableProperties(\n\tconfig: Partial<NormalizedDefaultProperties> | undefined,\n\toptions?: NormalizeTableDefaultPropertiesOptions\n): NormalizedDefaultProperties {\n\treturn getNormalizedDefaultProperties( {\n\t\t// It adds support for border none in the table element, keep it in sync with the content styles\n\t\t// See more: https://github.com/ckeditor/ckeditor5/issues/6841#issuecomment-1959195608\n\t\tborderStyle: 'double',\n\t\tborderColor: 'hsl(0, 0%, 70%)',\n\t\tborderWidth: '1px',\n\t\t...config\n\t}, options );\n}\n\n/**\n * Returns the normalized default cell properties.\n *\n * @param config The configuration to normalize.\n * @param options Options used to determine which properties should be added.\n */\nexport function getNormalizedDefaultCellProperties(\n\tconfig: Partial<NormalizedDefaultProperties> | undefined,\n\toptions?: NormalizeTableDefaultPropertiesOptions\n): NormalizedDefaultProperties {\n\treturn getNormalizedDefaultProperties( {\n\t\t// It adds support for border none in the table element, keep it in sync with the content styles\n\t\t// See more: https://github.com/ckeditor/ckeditor5/issues/6841#issuecomment-1959195608\n\t\tborderStyle: 'solid',\n\t\tborderColor: 'hsl(0, 0%, 75%)',\n\t\tborderWidth: '1px',\n\t\t...config\n\t}, options );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/tablecellpropertiesui\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport {\n\tButtonView,\n\tclickOutsideHandler,\n\tContextualBalloon,\n\tgetLocalizedColorOptions,\n\tnormalizeColorOptions,\n\ttype View\n} from 'ckeditor5/src/ui.js';\nimport type { Batch } from 'ckeditor5/src/engine.js';\n\nimport TableCellPropertiesView from './ui/tablecellpropertiesview.js';\nimport {\n\tcolorFieldValidator,\n\tgetLocalizedColorErrorText,\n\tgetLocalizedLengthErrorText,\n\tdefaultColors,\n\tlengthFieldValidator,\n\tlineWidthFieldValidator\n} from '../utils/ui/table-properties.js';\nimport { debounce } from 'lodash-es';\nimport { getTableWidgetAncestor } from '../utils/ui/widget.js';\nimport { getBalloonCellPositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon.js';\n\nimport tableCellProperties from './../../theme/icons/table-cell-properties.svg';\nimport { getNormalizedDefaultCellProperties, type NormalizedDefaultProperties } from '../utils/table-properties.js';\nimport type { GetCallback, ObservableChangeEvent } from 'ckeditor5/src/utils.js';\n\nimport type TableCellBorderStyleCommand from './commands/tablecellborderstylecommand.js';\n\nconst ERROR_TEXT_TIMEOUT = 500;\n\n// Map of view properties and related commands.\nconst propertyToCommandMap = {\n\tborderStyle: 'tableCellBorderStyle',\n\tborderColor: 'tableCellBorderColor',\n\tborderWidth: 'tableCellBorderWidth',\n\theight: 'tableCellHeight',\n\twidth: 'tableCellWidth',\n\tpadding: 'tableCellPadding',\n\tbackgroundColor: 'tableCellBackgroundColor',\n\thorizontalAlignment: 'tableCellHorizontalAlignment',\n\tverticalAlignment: 'tableCellVerticalAlignment'\n} as const;\n\n/**\n * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button\n * that opens a form allowing to specify the visual styling of a table cell.\n *\n * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */\nexport default class TableCellPropertiesUI extends Plugin {\n\t/**\n\t * The default table cell properties.\n\t */\n\tprivate _defaultTableCellProperties!: NormalizedDefaultProperties;\n\n\t/**\n\t * The contextual balloon plugin instance.\n\t */\n\tprivate _balloon?: ContextualBalloon;\n\n\t/**\n\t * The cell properties form view displayed inside the balloon.\n\t */\n\tpublic view?: TableCellPropertiesView | null;\n\n\t/**\n\t * The batch used to undo all changes made by the form (which are live, as the user types)\n\t * when \"Cancel\" was pressed. Each time the view is shown, a new batch is created.\n\t */\n\tprivate _undoStepBatch?: Batch;\n\n\t/**\n\t * Flag used to indicate whether view is ready to execute update commands\n\t * (it finished loading initial data).\n\t */\n\tprivate _isReady?: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableCellPropertiesUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'table.tableCellProperties', {\n\t\t\tborderColors: defaultColors,\n\t\t\tbackgroundColors: defaultColors\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\tthis._defaultTableCellProperties = getNormalizedDefaultCellProperties(\n\t\t\teditor.config.get( 'table.tableCellProperties.defaultProperties' )!,\n\t\t\t{\n\t\t\t\tincludeVerticalAlignmentProperty: true,\n\t\t\t\tincludeHorizontalAlignmentProperty: true,\n\t\t\t\tincludePaddingProperty: true,\n\t\t\t\tisRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'\n\t\t\t}\n\t\t);\n\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\t\tthis.view = null;\n\t\tthis._isReady = false;\n\n\t\teditor.ui.componentFactory.add( 'tableCellProperties', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: t( 'Cell properties' ),\n\t\t\t\ticon: tableCellProperties,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tthis.listenTo( view, 'execute', () => this._showView() );\n\n\t\t\tconst commands = Object.values( propertyToCommandMap )\n\t\t\t\t.map( commandName => editor.commands.get( commandName )! );\n\n\t\t\tview.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => (\n\t\t\t\tareEnabled.some( isCommandEnabled => isCommandEnabled )\n\t\t\t) );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1341.\n\t\tif ( this.view ) {\n\t\t\tthis.view.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.\n\t *\n\t * @returns The cell properties form view instance.\n\t */\n\tprivate _createPropertiesView() {\n\t\tconst editor = this.editor;\n\t\tconst config = editor.config.get( 'table.tableCellProperties' )!;\n\t\tconst borderColorsConfig = normalizeColorOptions( config.borderColors! );\n\t\tconst localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig );\n\t\tconst backgroundColorsConfig = normalizeColorOptions( config.backgroundColors! );\n\t\tconst localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig );\n\t\tconst hasColorPicker = config.colorPicker !== false;\n\n\t\tconst view = new TableCellPropertiesView( editor.locale, {\n\t\t\tborderColors: localizedBorderColors,\n\t\t\tbackgroundColors: localizedBackgroundColors,\n\t\t\tdefaultTableCellProperties: this._defaultTableCellProperties,\n\t\t\tcolorPickerConfig: hasColorPicker ? ( config.colorPicker || {} ) : false\n\t\t} );\n\t\tconst t = editor.t;\n\n\t\t// Render the view so its #element is available for the clickOutsideHandler.\n\t\tview.render();\n\n\t\tthis.listenTo( view, 'submit', () => {\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\tthis.listenTo( view, 'cancel', () => {\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/6180\n\t\t\tif ( this._undoStepBatch!.operations.length ) {\n\t\t\t\teditor.execute( 'undo', this._undoStepBatch );\n\t\t\t}\n\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\t// Close the balloon on Esc key press.\n\t\tview.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideView();\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: view,\n\t\t\tactivator: () => this._isViewInBalloon,\n\t\t\tcontextElements: [ this._balloon!.view.element! ],\n\t\t\tcallback: () => this._hideView()\n\t\t} );\n\n\t\tconst colorErrorText = getLocalizedColorErrorText( t );\n\t\tconst lengthErrorText = getLocalizedLengthErrorText( t );\n\n\t\t// Create the \"UI -> editor data\" binding.\n\t\t// These listeners update the editor data (via table commands) when any observable\n\t\t// property of the view has changed. They also validate the value and display errors in the UI\n\t\t// when necessary. This makes the view live, which means the changes are\n\t\t// visible in the editing as soon as the user types or changes fields' values.\n\t\tview.on<ObservableChangeEvent<string>>(\n\t\t\t'change:borderStyle',\n\t\t\tthis._getPropertyChangeCallback( 'tableCellBorderStyle' )\n\t\t);\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:borderColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderColorInput,\n\t\t\tcommandName: 'tableCellBorderColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:borderWidth', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderWidthInput,\n\t\t\tcommandName: 'tableCellBorderWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lineWidthFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:padding', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.paddingInput,\n\t\t\tcommandName: 'tableCellPadding',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:width', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.widthInput,\n\t\t\tcommandName: 'tableCellWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:height', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.heightInput,\n\t\t\tcommandName: 'tableCellHeight',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:backgroundColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.backgroundInput,\n\t\t\tcommandName: 'tableCellBackgroundColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>(\n\t\t\t'change:horizontalAlignment',\n\t\t\tthis._getPropertyChangeCallback( 'tableCellHorizontalAlignment' )\n\t\t);\n\t\tview.on<ObservableChangeEvent<string>>(\n\t\t\t'change:verticalAlignment',\n\t\t\tthis._getPropertyChangeCallback( 'tableCellVerticalAlignment' )\n\t\t);\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * In this method the \"editor data -> UI\" binding is happening.\n\t *\n\t * When executed, this method obtains selected cell property values from various table commands\n\t * and passes them to the {@link #view}.\n\t *\n\t * This way, the UI stays up–to–date with the editor data.\n\t */\n\tprivate _fillViewFormFromCommandValues() {\n\t\tconst commands = this.editor.commands;\n\t\tconst borderStyleCommand: TableCellBorderStyleCommand = commands.get( 'tableCellBorderStyle' )!;\n\n\t\tObject.entries( propertyToCommandMap )\n\t\t\t.map( ( [ property, commandName ] ) => {\n\t\t\t\tconst defaultValue = this._defaultTableCellProperties[ property as keyof NormalizedDefaultProperties ] || '';\n\n\t\t\t\treturn [\n\t\t\t\t\tproperty as keyof typeof propertyToCommandMap,\n\t\t\t\t\tcommands.get( commandName )!.value as string || defaultValue\n\t\t\t\t] as const;\n\t\t\t} )\n\t\t\t.forEach( ( [ property, value ] ) => {\n\t\t\t\t// Do not set the `border-color` and `border-width` fields if `border-style:none`.\n\t\t\t\tif ( ( property === 'borderColor' || property === 'borderWidth' ) && borderStyleCommand.value === 'none' ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.view!.set( property, value );\n\t\t\t} );\n\n\t\tthis._isReady = true;\n\t}\n\n\t/**\n\t * Shows the {@link #view} in the {@link #_balloon}.\n\t *\n\t * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains\n\t * all changes made to the document when the view is visible, allowing a single undo step\n\t * for all of them.\n\t */\n\tprotected _showView(): void {\n\t\tconst editor = this.editor;\n\n\t\tif ( !this.view ) {\n\t\t\tthis.view = this._createPropertiesView();\n\t\t}\n\n\t\tthis.listenTo( editor.ui, 'update', () => {\n\t\t\tthis._updateView();\n\t\t} );\n\n\t\t// Update the view with the model values.\n\t\tthis._fillViewFormFromCommandValues();\n\n\t\tthis._balloon!.add( {\n\t\t\tview: this.view,\n\t\t\tposition: getBalloonCellPositionData( editor )\n\t\t} );\n\n\t\t// Create a new batch. Clicking \"Cancel\" will undo this batch.\n\t\tthis._undoStepBatch = editor.model.createBatch();\n\n\t\t// Basic a11y.\n\t\tthis.view.focus();\n\t}\n\n\t/**\n\t * Removes the {@link #view} from the {@link #_balloon}.\n\t */\n\tprotected _hideView(): void {\n\t\tconst editor = this.editor;\n\n\t\tthis.stopListening( editor.ui, 'update' );\n\n\t\tthis._isReady = false;\n\n\t\t// Blur any input element before removing it from DOM to prevent issues in some browsers.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\tthis.view!.saveButtonView.focus();\n\n\t\tthis._balloon!.remove( this.view! );\n\n\t\t// Make sure the focus is not lost in the process by putting it directly\n\t\t// into the editing view.\n\t\tthis.editor.editing.view.focus();\n\t}\n\n\t/**\n\t * Repositions the {@link #_balloon} or hides the {@link #view} if a table cell is no longer selected.\n\t */\n\tprotected _updateView(): void {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\tif ( !getTableWidgetAncestor( viewDocument.selection ) ) {\n\t\t\tthis._hideView();\n\t\t} else if ( this._isViewVisible ) {\n\t\t\trepositionContextualBalloon( editor, 'cell' );\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.\n\t */\n\tprivate get _isViewVisible() {\n\t\treturn !!this.view && this._balloon!.visibleView === this.view;\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is in the {@link #_balloon}.\n\t */\n\tprivate get _isViewInBalloon() {\n\t\treturn !!this.view && this._balloon!.hasView( this.view );\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon the {@link #view view's} property change\n\t * executes a related editor command with the new property value.\n\t *\n\t * @param defaultValue The default value of the command.\n\t */\n\tprivate _getPropertyChangeCallback(\n\t\tcommandName: 'tableCellBorderStyle' | 'tableCellHorizontalAlignment' | 'tableCellVerticalAlignment'\n\t): GetCallback<ObservableChangeEvent<string>> {\n\t\treturn ( evt, propertyName, newValue ) => {\n\t\t\tif ( !this._isReady ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( commandName, {\n\t\t\t\tvalue: newValue,\n\t\t\t\tbatch: this._undoStepBatch\n\t\t\t} );\n\t\t};\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon the {@link #view view's} property change:\n\t * * Executes a related editor command with the new property value if the value is valid,\n\t * * Or sets the error text next to the invalid field, if the value did not pass the validation.\n\t */\n\tprivate _getValidatedPropertyChangeCallback(\n\t\toptions: {\n\t\t\tcommandName: `tableCell${ 'BorderColor' | 'BorderWidth' | 'Padding' | 'Width' | 'Height' | 'BackgroundColor' }`;\n\t\t\tviewField: View & { errorText?: string | null };\n\t\t\tvalidator: ( arg0: string ) => boolean;\n\t\t\terrorText: string;\n\t\t}\n\t): GetCallback<ObservableChangeEvent<string>> {\n\t\tconst { commandName, viewField, validator, errorText } = options;\n\t\tconst setErrorTextDebounced = debounce( () => {\n\t\t\tviewField.errorText = errorText;\n\t\t}, ERROR_TEXT_TIMEOUT );\n\n\t\treturn ( evt, propertyName, newValue ) => {\n\t\t\tsetErrorTextDebounced.cancel();\n\t\t\t// Do not execute the command on initial call (opening the table properties view).\n\t\t\tif ( !this._isReady ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( validator( newValue ) ) {\n\t\t\t\tthis.editor.execute( commandName, {\n\t\t\t\t\tvalue: newValue,\n\t\t\t\t\tbatch: this._undoStepBatch\n\t\t\t\t} );\n\n\t\t\t\tviewField.errorText = null;\n\t\t\t} else {\n\t\t\t\tsetErrorTextDebounced();\n\t\t\t}\n\t\t};\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellpropertycommand\n */\n\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport type { Element, Batch } from 'ckeditor5/src/engine.js';\nimport type TableUtils from '../../tableutils.js';\n\n/**\n * The table cell attribute command.\n *\n * The command is a base command for other table cell property commands.\n */\nexport default class TableCellPropertyCommand extends Command {\n\t/**\n\t * The attribute that will be set by the command.\n\t */\n\tpublic readonly attributeName: string;\n\n\t/**\n\t * The default value for the attribute.\n\t */\n\tprotected readonly _defaultValue: string;\n\n\t/**\n\t * Creates a new `TableCellPropertyCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param attributeName Table cell attribute name.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, attributeName: string, defaultValue: string ) {\n\t\tsuper( editor );\n\n\t\tthis.attributeName = attributeName;\n\t\tthis._defaultValue = defaultValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst selectedTableCells = tableUtils.getSelectionAffectedTableCells( editor.model.document.selection );\n\n\t\tthis.isEnabled = !!selectedTableCells.length;\n\t\tthis.value = this._getSingleValue( selectedTableCells );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.value If set, the command will set the attribute on selected table cells.\n\t * If it is not set, the command will remove the attribute from the selected table cells.\n\t * @param options.batch Pass the model batch instance to the command to aggregate changes,\n\t * for example to allow a single undo step for multiple executions.\n\t */\n\tpublic override execute( options: { value?: string | number; batch?: Batch } = {} ): void {\n\t\tconst { value, batch } = options;\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils: TableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst tableCells = tableUtils.getSelectionAffectedTableCells( model.document.selection );\n\t\tconst valueToSet = this._getValueToSet( value );\n\n\t\tmodel.enqueueChange( batch, writer => {\n\t\t\tif ( valueToSet ) {\n\t\t\t\ttableCells.forEach( tableCell => writer.setAttribute( this.attributeName, valueToSet, tableCell ) );\n\t\t\t} else {\n\t\t\t\ttableCells.forEach( tableCell => writer.removeAttribute( this.attributeName, tableCell ) );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the attribute value for a table cell.\n\t */\n\tprotected _getAttribute( tableCell: Element | undefined ): unknown {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = tableCell.getAttribute( this.attributeName );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Returns the proper model value. It can be used to add a default unit to numeric values.\n\t */\n\tprotected _getValueToSet( value: string | number | undefined ): unknown {\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Returns a single value for all selected table cells. If the value is the same for all cells,\n\t * it will be returned (`undefined` otherwise).\n\t */\n\tprivate _getSingleValue( tableCells: Array<Element> ) {\n\t\tconst firstCellValue = this._getAttribute( tableCells[ 0 ] );\n\n\t\tconst everyCellHasAttribute = tableCells.every( tableCells => this._getAttribute( tableCells ) === firstCellValue );\n\n\t\treturn everyCellHasAttribute ? firstCellValue : undefined;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellwidth/commands/tablecellwidthcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TableCellPropertyCommand from '../../tablecellproperties/commands/tablecellpropertycommand.js';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties.js';\n\n/**\n * The table cell width command.\n *\n * The command is registered by the {@link module:table/tablecellwidth/tablecellwidthediting~TableCellWidthEditing} as\n * the `'tableCellWidth'` editor command.\n *\n * To change the width of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellWidth', {\n *   value: '50px'\n * } );\n * ```\n *\n * **Note**: This command adds a default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellWidth', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `width` attribute to `'50px'` in the model.\n */\nexport default class TableCellWidthCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override _getValueToSet( value: string | number | undefined ): unknown {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellwidth/tablecellwidthediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport TableEditing from './../tableediting.js';\nimport TableCellWidthCommand from './commands/tablecellwidthcommand.js';\nimport { getNormalizedDefaultCellProperties } from '../utils/table-properties.js';\nimport { enableProperty } from '../utils/common.js';\n\n/**\n * The table cell width editing feature.\n *\n * Introduces `tableCellWidth` table cell model attribute alongside with its converters\n * and a command.\n */\nexport default class TableCellWidthEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableCellWidthEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\n\t\tconst defaultTableCellProperties = getNormalizedDefaultCellProperties(\n\t\t\teditor.config.get( 'table.tableCellProperties.defaultProperties' )!\n\t\t);\n\n\t\tenableProperty( editor.model.schema, editor.conversion, {\n\t\t\tmodelAttribute: 'tableCellWidth',\n\t\t\tstyleName: 'width',\n\t\t\tdefaultValue: defaultTableCellProperties.width\n\t\t} );\n\n\t\teditor.commands.add( 'tableCellWidth', new TableCellWidthCommand( editor, defaultTableCellProperties.width ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellpaddingcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\nimport { addDefaultUnitToNumericValue, getSingleValue } from '../../utils/table-properties.js';\n\n/**\n * The table cell padding command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellPadding'` editor command.\n *\n * To change the padding of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellPadding', {\n *   value: '5px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellPadding', {\n *   value: '5'\n * } );\n * ```\n *\n * will set the `padding` attribute to `'5px'` in the model.\n */\nexport default class TableCellPaddingCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellPaddingCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellPadding', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getAttribute( tableCell: Element ): unknown {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) as string );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValueToSet( value: string | number | undefined ): unknown {\n\t\tconst newValue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( newValue === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn newValue;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellheightcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties.js';\n\n/**\n * The table cell height command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellHeight'` editor command.\n *\n * To change the height of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellHeight', {\n *   value: '50px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellHeight', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `height` attribute to `'50px'` in the model.\n */\nexport default class TableCellHeightCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellHeightCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellHeight', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValueToSet( value: string | number | undefined ): unknown {\n\t\tconst newValue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( newValue === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn newValue;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellbackgroundcolorcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\n\n/**\n * The table cell background color command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBackgroundColor'` editor command.\n *\n * To change the background color of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBackgroundColor', {\n *   value: '#f00'\n * } );\n * ```\n */\nexport default class TableCellBackgroundColorCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBackgroundColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellBackgroundColor', defaultValue );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellverticalalignmentcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\n\n/**\n * The table cell vertical alignment command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellVerticalAlignment'` editor command.\n *\n * To change the vertical text alignment of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellVerticalAlignment', {\n *   value: 'top'\n * } );\n * ```\n *\n * The following values, corresponding to the\n * [`vertical-align` CSS attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align), are allowed:\n *\n * * `'top'`\n * * `'bottom'`\n *\n * The `'middle'` value is the default one so there is no need to set it.\n */\nexport default class TableCellVerticalAlignmentCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellVerticalAlignmentCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value for the \"alignment\" attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellVerticalAlignment', defaultValue );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellhorizontalalignmentcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\n\n/**\n * The table cell horizontal alignment command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellHorizontalAlignment'` editor command.\n *\n * To change the horizontal text alignment of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellHorizontalAlignment', {\n *  value: 'right'\n * } );\n * ```\n */\nexport default class TableCellHorizontalAlignmentCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellHorizontalAlignmentCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value for the \"alignment\" attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellHorizontalAlignment', defaultValue );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellborderstylecommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\nimport { getSingleValue } from '../../utils/table-properties.js';\n\n/**\n * The table cell border style command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderStyle'` editor command.\n *\n * To change the border style of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBorderStyle', {\n *   value: 'dashed'\n * } );\n * ```\n */\nexport default class TableCellBorderStyleCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBorderStyleCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellBorderStyle', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getAttribute( tableCell: Element ): unknown {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) as string | undefined );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellbordercolorcommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\nimport { getSingleValue } from '../../utils/table-properties.js';\n\n/**\n * The table cell border color command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderColor'` editor command.\n *\n * To change the border color of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBorderColor', {\n *   value: '#f00'\n * } );\n * ```\n */\nexport default class TableCellBorderColorCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBorderColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellBorderColor', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getAttribute( tableCell: Element ): unknown {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) as string | undefined );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellborderwidthcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport type { Element } from 'ckeditor5/src/engine.js';\n\nimport TableCellPropertyCommand from './tablecellpropertycommand.js';\nimport { addDefaultUnitToNumericValue, getSingleValue } from '../../utils/table-properties.js';\n\n/**\n * The table cell border width command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderWidth'` editor command.\n *\n * To change the border width of selected cells, execute the command:\n *\n * ```ts\n * editor.execute( 'tableCellBorderWidth', {\n *   value: '5px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableCellBorderWidth', {\n *   value: '5'\n * } );\n * ```\n *\n * will set the `borderWidth` attribute to `'5px'` in the model.\n */\nexport default class TableCellBorderWidthCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBorderWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableCellBorderWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getAttribute( tableCell: Element ): unknown {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) as string );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValueToSet( value: string | number | undefined ): unknown {\n\t\tconst newValue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( newValue === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn newValue;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/tablecellpropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport {\n\taddBorderRules,\n\taddPaddingRules,\n\taddBackgroundRules,\n\ttype Schema,\n\ttype Conversion,\n\ttype ViewElement\n} from 'ckeditor5/src/engine.js';\n\nimport { downcastAttributeToStyle, upcastBorderStyles } from './../converters/tableproperties.js';\nimport TableEditing from './../tableediting.js';\nimport TableCellWidthEditing from '../tablecellwidth/tablecellwidthediting.js';\nimport TableCellPaddingCommand from './commands/tablecellpaddingcommand.js';\nimport TableCellHeightCommand from './commands/tablecellheightcommand.js';\nimport TableCellBackgroundColorCommand from './commands/tablecellbackgroundcolorcommand.js';\nimport TableCellVerticalAlignmentCommand from './commands/tablecellverticalalignmentcommand.js';\nimport TableCellHorizontalAlignmentCommand from './commands/tablecellhorizontalalignmentcommand.js';\nimport TableCellBorderStyleCommand from './commands/tablecellborderstylecommand.js';\nimport TableCellBorderColorCommand from './commands/tablecellbordercolorcommand.js';\nimport TableCellBorderWidthCommand from './commands/tablecellborderwidthcommand.js';\nimport { getNormalizedDefaultCellProperties } from '../utils/table-properties.js';\nimport { enableProperty } from '../utils/common.js';\n\nconst VALIGN_VALUES_REG_EXP = /^(top|middle|bottom)$/;\nconst ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;\n\n/**\n * The table cell properties editing feature.\n *\n * Introduces table cell model attributes and their conversion:\n *\n * - border: `tableCellBorderStyle`, `tableCellBorderColor` and `tableCellBorderWidth`\n * - background color: `tableCellBackgroundColor`\n * - cell padding: `tableCellPadding`\n * - horizontal and vertical alignment: `tableCellHorizontalAlignment`, `tableCellVerticalAlignment`\n * - cell width and height: `tableCellWidth`, `tableCellHeight`\n *\n * It also registers commands used to manipulate the above attributes:\n *\n * - border: the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` commands\n * - background color: the `'tableCellBackgroundColor'` command\n * - cell padding: the `'tableCellPadding'` command\n * - horizontal and vertical alignment: the `'tableCellHorizontalAlignment'` and `'tableCellVerticalAlignment'` commands\n * - width and height: the `'tableCellWidth'` and `'tableCellHeight'` commands\n */\nexport default class TableCellPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableCellPropertiesEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableEditing, TableCellWidthEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\n\t\teditor.config.define( 'table.tableCellProperties.defaultProperties', { } );\n\n\t\tconst defaultTableCellProperties = getNormalizedDefaultCellProperties(\n\t\t\teditor.config.get( 'table.tableCellProperties.defaultProperties' )!,\n\t\t\t{\n\t\t\t\tincludeVerticalAlignmentProperty: true,\n\t\t\t\tincludeHorizontalAlignmentProperty: true,\n\t\t\t\tincludePaddingProperty: true,\n\t\t\t\tisRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'\n\t\t\t}\n\t\t);\n\n\t\teditor.data.addStyleProcessorRules( addBorderRules );\n\t\tenableBorderProperties( schema, conversion, {\n\t\t\tcolor: defaultTableCellProperties.borderColor,\n\t\t\tstyle: defaultTableCellProperties.borderStyle,\n\t\t\twidth: defaultTableCellProperties.borderWidth\n\t\t} );\n\t\teditor.commands.add( 'tableCellBorderStyle', new TableCellBorderStyleCommand( editor, defaultTableCellProperties.borderStyle ) );\n\t\teditor.commands.add( 'tableCellBorderColor', new TableCellBorderColorCommand( editor, defaultTableCellProperties.borderColor ) );\n\t\teditor.commands.add( 'tableCellBorderWidth', new TableCellBorderWidthCommand( editor, defaultTableCellProperties.borderWidth ) );\n\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableCellHeight',\n\t\t\tstyleName: 'height',\n\t\t\tdefaultValue: defaultTableCellProperties.height\n\t\t} );\n\t\teditor.commands.add( 'tableCellHeight', new TableCellHeightCommand( editor, defaultTableCellProperties.height ) );\n\n\t\teditor.data.addStyleProcessorRules( addPaddingRules );\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableCellPadding',\n\t\t\tstyleName: 'padding',\n\t\t\treduceBoxSides: true,\n\t\t\tdefaultValue: defaultTableCellProperties.padding!\n\t\t} );\n\t\teditor.commands.add( 'tableCellPadding', new TableCellPaddingCommand( editor, defaultTableCellProperties.padding! ) );\n\n\t\teditor.data.addStyleProcessorRules( addBackgroundRules );\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableCellBackgroundColor',\n\t\t\tstyleName: 'background-color',\n\t\t\tdefaultValue: defaultTableCellProperties.backgroundColor\n\t\t} );\n\t\teditor.commands.add(\n\t\t\t'tableCellBackgroundColor',\n\t\t\tnew TableCellBackgroundColorCommand( editor, defaultTableCellProperties.backgroundColor )\n\t\t);\n\n\t\tenableHorizontalAlignmentProperty( schema, conversion, defaultTableCellProperties.horizontalAlignment! );\n\t\teditor.commands.add(\n\t\t\t'tableCellHorizontalAlignment',\n\t\t\tnew TableCellHorizontalAlignmentCommand( editor, defaultTableCellProperties.horizontalAlignment! )\n\t\t);\n\n\t\tenableVerticalAlignmentProperty( schema, conversion, defaultTableCellProperties.verticalAlignment! );\n\t\teditor.commands.add(\n\t\t\t'tableCellVerticalAlignment',\n\t\t\tnew TableCellVerticalAlignmentCommand( editor, defaultTableCellProperties.verticalAlignment! )\n\t\t);\n\t}\n}\n\n/**\n * Enables the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` attributes for table cells.\n *\n * @param defaultBorder The default border values.\n * @param defaultBorder.color The default `tableCellBorderColor` value.\n * @param defaultBorder.style The default `tableCellBorderStyle` value.\n * @param defaultBorder.width The default `tableCellBorderWidth` value.\n */\nfunction enableBorderProperties( schema: Schema, conversion: Conversion, defaultBorder: { color: string; style: string; width: string } ) {\n\tconst modelAttributes = {\n\t\twidth: 'tableCellBorderWidth',\n\t\tcolor: 'tableCellBorderColor',\n\t\tstyle: 'tableCellBorderStyle'\n\t};\n\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: Object.values( modelAttributes )\n\t} );\n\n\tupcastBorderStyles( conversion, 'td', modelAttributes, defaultBorder );\n\tupcastBorderStyles( conversion, 'th', modelAttributes, defaultBorder );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.style, styleName: 'border-style' } );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.color, styleName: 'border-color' } );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.width, styleName: 'border-width' } );\n}\n\n/**\n * Enables the `'tableCellHorizontalAlignment'` attribute for table cells.\n *\n * @param defaultValue The default horizontal alignment value.\n */\nfunction enableHorizontalAlignmentProperty( schema: Schema, conversion: Conversion, defaultValue: string ) {\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: [ 'tableCellHorizontalAlignment' ]\n\t} );\n\n\tconversion.for( 'downcast' )\n\t\t.attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'tableCell',\n\t\t\t\tkey: 'tableCellHorizontalAlignment'\n\t\t\t},\n\t\t\tview: alignment => ( {\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\t'text-align': alignment\n\t\t\t\t}\n\t\t\t} )\n\t\t} );\n\n\tconversion.for( 'upcast' )\n\t\t// Support for the `text-align:*;` CSS definition for the table cell alignment.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tstyles: {\n\t\t\t\t\t'text-align': ALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellHorizontalAlignment',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\tconst align = viewElement.getStyle( 'text-align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t\t// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tattributes: {\n\t\t\t\t\talign: ALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellHorizontalAlignment',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\tconst align = viewElement.getAttribute( 'align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n}\n\n/**\n * Enables the `'verticalAlignment'` attribute for table cells.\n *\n * @param defaultValue The default vertical alignment value.\n */\nfunction enableVerticalAlignmentProperty( schema: Schema, conversion: Conversion, defaultValue: string ) {\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: [ 'tableCellVerticalAlignment' ]\n\t} );\n\n\tconversion.for( 'downcast' )\n\t\t.attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'tableCell',\n\t\t\t\tkey: 'tableCellVerticalAlignment'\n\t\t\t},\n\t\t\tview: alignment => ( {\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\t'vertical-align': alignment\n\t\t\t\t}\n\t\t\t} )\n\t\t} );\n\n\tconversion.for( 'upcast' )\n\t\t// Support for the `vertical-align:*;` CSS definition for the table cell alignment.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tstyles: {\n\t\t\t\t\t'vertical-align': VALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellVerticalAlignment',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\tconst align = viewElement.getStyle( 'vertical-align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t\t// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tattributes: {\n\t\t\t\t\tvalign: VALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellVerticalAlignment',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\tconst valign = viewElement.getAttribute( 'valign' );\n\n\t\t\t\t\treturn valign === defaultValue ? null : valign;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport TableCellPropertiesUI from './tablecellproperties/tablecellpropertiesui.js';\nimport TableCellPropertiesEditing from './tablecellproperties/tablecellpropertiesediting.js';\n\n/**\n * The table cell properties feature. Enables support for setting properties of table cells (size, border, background, etc.).\n *\n * Read more in the {@glink features/tables/tables-styling Table and cell styling tools} section.\n * See also the {@link module:table/tableproperties~TableProperties} plugin.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing table cell properties editing feature} and\n * the {@link module:table/tablecellproperties/tablecellpropertiesui~TableCellPropertiesUI table cell properties UI feature}.\n */\nexport default class TableCellProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableCellProperties' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableCellPropertiesEditing, TableCellPropertiesUI ] as const;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablepropertycommand\n */\n\nimport type { Batch, Element } from 'ckeditor5/src/engine.js';\nimport { Command, type Editor } from 'ckeditor5/src/core.js';\nimport { getSelectionAffectedTable } from '../../utils/common.js';\n\nexport interface TablePropertyCommandExecuteOptions {\n\tbatch?: Batch;\n\tcolumnWidths?: string;\n\ttable?: Element;\n\ttableWidth?: string;\n\tvalue?: string;\n}\n\n/**\n * The table cell attribute command.\n *\n * This command is a base command for other table property commands.\n */\nexport default class TablePropertyCommand extends Command {\n\t/**\n\t * The attribute that will be set by the command.\n\t */\n\tpublic readonly attributeName: string;\n\n\t/**\n\t * The default value for the attribute.\n\t */\n\tprotected readonly _defaultValue: string | undefined;\n\n\t/**\n\t * Creates a new `TablePropertyCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param attributeName Table cell attribute name.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, attributeName: string, defaultValue?: string ) {\n\t\tsuper( editor );\n\n\t\tthis.attributeName = attributeName;\n\t\tthis._defaultValue = defaultValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\n\t\tconst table = getSelectionAffectedTable( selection );\n\n\t\tthis.isEnabled = !!table;\n\t\tthis.value = this._getValue( table );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param options.value If set, the command will set the attribute on the selected table.\n\t * If not set, the command will remove the attribute from the selected table.\n\t * @param options.batch Pass the model batch instance to the command to aggregate changes,\n\t * for example, to allow a single undo step for multiple executions.\n\t */\n\tpublic override execute( options: TablePropertyCommandExecuteOptions = {} ): void {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tconst { value, batch } = options;\n\n\t\tconst table = getSelectionAffectedTable( selection );\n\t\tconst valueToSet = this._getValueToSet( value );\n\n\t\tmodel.enqueueChange( batch, writer => {\n\t\t\tif ( valueToSet ) {\n\t\t\t\twriter.setAttribute( this.attributeName, valueToSet, table );\n\t\t\t} else {\n\t\t\t\twriter.removeAttribute( this.attributeName, table );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the attribute value for a table.\n\t */\n\tprotected _getValue( table: Element ): unknown {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = table.getAttribute( this.attributeName );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Returns the proper model value. It can be used to add a default unit to numeric values.\n\t */\n\tprotected _getValueToSet( value: string | number | undefined ): unknown {\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablebackgroundcolorcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport TablePropertyCommand from './tablepropertycommand.js';\n\n/**\n * The table background color command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBackgroundColor'` editor command.\n *\n * To change the background color of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBackgroundColor', {\n *   value: '#f00'\n * } );\n * ```\n */\nexport default class TableBackgroundColorCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBackgroundColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableBackgroundColor', defaultValue );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablebordercolorcommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TablePropertyCommand from './tablepropertycommand.js';\nimport { getSingleValue } from '../../utils/table-properties.js';\n\n/**\n * The table border color command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderColor'` editor command.\n *\n * To change the border color of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBorderColor', {\n *   value: '#f00'\n * } );\n * ```\n */\nexport default class TableBorderColorCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBorderColorCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableBorderColor', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValue( table: Element ): unknown {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( table.getAttribute( this.attributeName ) as string );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tableborderstylecommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\n\nimport TablePropertyCommand from './tablepropertycommand.js';\nimport { getSingleValue } from '../../utils/table-properties.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\n/**\n * The table style border command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderStyle'` editor command.\n *\n * To change the border style of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBorderStyle', {\n *   value: 'dashed'\n * } );\n * ```\n */\nexport default class TableBorderStyleCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBorderStyleCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableBorderStyle', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValue( table: Element ): unknown {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( table.getAttribute( this.attributeName ) as string );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tableborderwidthcommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\nimport TablePropertyCommand from './tablepropertycommand.js';\nimport { addDefaultUnitToNumericValue, getSingleValue } from '../../utils/table-properties.js';\n\n/**\n * The table width border command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderWidth'` editor command.\n *\n * To change the border width of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableBorderWidth', {\n *   value: '5px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableBorderWidth', {\n *   value: '5'\n * } );\n * ```\n *\n * will set the `borderWidth` attribute to `'5px'` in the model.\n */\nexport default class TableBorderWidthCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBorderWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableBorderWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValue( table: Element ): string | undefined {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( table.getAttribute( this.attributeName ) as string );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValueToSet( value: string | number | undefined ): unknown {\n\t\tconst newValue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( newValue === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn newValue;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablewidthcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand.js';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\n/**\n * The table width command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableWidth'` editor command.\n *\n * To change the width of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableWidth', {\n *   value: '400px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableWidth', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `width` attribute to `'50px'` in the model.\n */\nexport default class TableWidthCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableWidthCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override _getValueToSet( value: string | number | undefined ): unknown {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tableheightcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand.js';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties.js';\nimport type { Editor } from 'ckeditor5/src/core.js';\n\n/**\n * The table height command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableHeight'` editor command.\n *\n * To change the height of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableHeight', {\n *   value: '500px'\n * } );\n * ```\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n * ```ts\n * editor.execute( 'tableHeight', {\n *   value: '50'\n * } );\n * ```\n *\n * will set the `height` attribute to `'50px'` in the model.\n */\nexport default class TableHeightCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableHeightCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableHeight', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tprotected override _getValueToSet( value: string | number | undefined ): unknown {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablealignmentcommand\n */\n\nimport type { Editor } from 'ckeditor5/src/core.js';\nimport TablePropertyCommand from './tablepropertycommand.js';\n\n/**\n * The table alignment command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableAlignment'` editor command.\n *\n * To change the alignment of the selected table, execute the command:\n *\n * ```ts\n * editor.execute( 'tableAlignment', {\n *   value: 'right'\n * } );\n * ```\n */\nexport default class TableAlignmentCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableAlignmentCommand` instance.\n\t *\n\t * @param editor An editor in which this command will be used.\n\t * @param defaultValue The default value for the \"alignment\" attribute.\n\t */\n\tconstructor( editor: Editor, defaultValue: string ) {\n\t\tsuper( editor, 'tableAlignment', defaultValue );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/tablepropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport { addBackgroundRules, addBorderRules, type ViewElement, type Conversion, type Schema } from 'ckeditor5/src/engine.js';\n\nimport TableEditing from '../tableediting.js';\nimport {\n\tdowncastAttributeToStyle,\n\tdowncastTableAttribute,\n\tupcastBorderStyles,\n\tupcastStyleToAttribute\n} from '../converters/tableproperties.js';\nimport TableBackgroundColorCommand from './commands/tablebackgroundcolorcommand.js';\nimport TableBorderColorCommand from './commands/tablebordercolorcommand.js';\nimport TableBorderStyleCommand from './commands/tableborderstylecommand.js';\nimport TableBorderWidthCommand from './commands/tableborderwidthcommand.js';\nimport TableWidthCommand from './commands/tablewidthcommand.js';\nimport TableHeightCommand from './commands/tableheightcommand.js';\nimport TableAlignmentCommand from './commands/tablealignmentcommand.js';\nimport { getNormalizedDefaultTableProperties } from '../utils/table-properties.js';\n\nconst ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;\nconst FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;\n\n/**\n * The table properties editing feature.\n *\n * Introduces table's model attributes and their conversion:\n *\n * - border: `tableBorderStyle`, `tableBorderColor` and `tableBorderWidth`\n * - background color: `tableBackgroundColor`\n * - horizontal alignment: `tableAlignment`\n * - width & height: `tableWidth` & `tableHeight`\n *\n * It also registers commands used to manipulate the above attributes:\n *\n * - border: `'tableBorderStyle'`, `'tableBorderColor'` and `'tableBorderWidth'` commands\n * - background color: `'tableBackgroundColor'`\n * - horizontal alignment: `'tableAlignment'`\n * - width & height: `'tableWidth'` & `'tableHeight'`\n */\nexport default class TablePropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TablePropertiesEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\n\t\teditor.config.define( 'table.tableProperties.defaultProperties', {} );\n\n\t\tconst defaultTableProperties = getNormalizedDefaultTableProperties(\n\t\t\teditor.config.get( 'table.tableProperties.defaultProperties' )!,\n\t\t\t{\n\t\t\t\tincludeAlignmentProperty: true\n\t\t\t}\n\t\t);\n\n\t\teditor.data.addStyleProcessorRules( addBorderRules );\n\t\tenableBorderProperties( schema, conversion, {\n\t\t\tcolor: defaultTableProperties.borderColor,\n\t\t\tstyle: defaultTableProperties.borderStyle,\n\t\t\twidth: defaultTableProperties.borderWidth\n\t\t} );\n\n\t\teditor.commands.add( 'tableBorderColor', new TableBorderColorCommand( editor, defaultTableProperties.borderColor ) );\n\t\teditor.commands.add( 'tableBorderStyle', new TableBorderStyleCommand( editor, defaultTableProperties.borderStyle ) );\n\t\teditor.commands.add( 'tableBorderWidth', new TableBorderWidthCommand( editor, defaultTableProperties.borderWidth ) );\n\n\t\tenableAlignmentProperty( schema, conversion, defaultTableProperties.alignment! );\n\t\teditor.commands.add( 'tableAlignment', new TableAlignmentCommand( editor, defaultTableProperties.alignment! ) );\n\n\t\tenableTableToFigureProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableWidth',\n\t\t\tstyleName: 'width',\n\t\t\tdefaultValue: defaultTableProperties.width\n\t\t} );\n\t\teditor.commands.add( 'tableWidth', new TableWidthCommand( editor, defaultTableProperties.width ) );\n\n\t\tenableTableToFigureProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableHeight',\n\t\t\tstyleName: 'height',\n\t\t\tdefaultValue: defaultTableProperties.height\n\t\t} );\n\t\teditor.commands.add( 'tableHeight', new TableHeightCommand( editor, defaultTableProperties.height ) );\n\n\t\teditor.data.addStyleProcessorRules( addBackgroundRules );\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableBackgroundColor',\n\t\t\tstyleName: 'background-color',\n\t\t\tdefaultValue: defaultTableProperties.backgroundColor\n\t\t} );\n\t\teditor.commands.add(\n\t\t\t'tableBackgroundColor',\n\t\t\tnew TableBackgroundColorCommand( editor, defaultTableProperties.backgroundColor )\n\t\t);\n\t}\n}\n\n/**\n * Enables `tableBorderStyle'`, `tableBorderColor'` and `tableBorderWidth'` attributes for table.\n *\n * @param defaultBorder The default border values.\n * @param defaultBorder.color The default `tableBorderColor` value.\n * @param defaultBorder.style The default `tableBorderStyle` value.\n * @param defaultBorder.width The default `tableBorderWidth` value.\n */\nfunction enableBorderProperties( schema: Schema, conversion: Conversion, defaultBorder: { color: string; style: string; width: string } ) {\n\tconst modelAttributes = {\n\t\twidth: 'tableBorderWidth',\n\t\tcolor: 'tableBorderColor',\n\t\tstyle: 'tableBorderStyle'\n\t};\n\n\tschema.extend( 'table', {\n\t\tallowAttributes: Object.values( modelAttributes )\n\t} );\n\n\tupcastBorderStyles( conversion, 'table', modelAttributes, defaultBorder );\n\n\tdowncastTableAttribute( conversion, { modelAttribute: modelAttributes.color, styleName: 'border-color' } );\n\tdowncastTableAttribute( conversion, { modelAttribute: modelAttributes.style, styleName: 'border-style' } );\n\tdowncastTableAttribute( conversion, { modelAttribute: modelAttributes.width, styleName: 'border-width' } );\n}\n\n/**\n * Enables the `'alignment'` attribute for table.\n *\n * @param defaultValue The default alignment value.\n */\nfunction enableAlignmentProperty( schema: Schema, conversion: Conversion, defaultValue: string ) {\n\tschema.extend( 'table', {\n\t\tallowAttributes: [ 'tableAlignment' ]\n\t} );\n\n\tconversion.for( 'downcast' )\n\t\t.attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tkey: 'tableAlignment'\n\t\t\t},\n\t\t\tview: alignment => ( {\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\t// Model: `alignment:center` => CSS: `float:none`.\n\t\t\t\t\tfloat: alignment === 'center' ? 'none' : alignment\n\t\t\t\t}\n\t\t\t} ),\n\t\t\tconverterPriority: 'high'\n\t\t} );\n\n\tconversion.for( 'upcast' )\n\t\t// Support for the `float:*;` CSS definition for the table alignment.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(table|figure)$/,\n\t\t\t\tstyles: {\n\t\t\t\t\tfloat: FLOAT_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableAlignment',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\tlet align = viewElement.getStyle( 'float' );\n\n\t\t\t\t\t// CSS: `float:none` => Model: `alignment:center`.\n\t\t\t\t\tif ( align === 'none' ) {\n\t\t\t\t\t\talign = 'center';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t\t// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tattributes: {\n\t\t\t\t\talign: ALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tkey: 'tableAlignment',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\tconst align = viewElement.getAttribute( 'align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n}\n\n/**\n * Enables conversion for an attribute for simple view-model mappings.\n *\n * @param options.defaultValue The default value for the specified `modelAttribute`.\n */\nfunction enableProperty(\n\tschema: Schema,\n\tconversion: Conversion,\n\toptions: {\n\t\tmodelAttribute: string;\n\t\tstyleName: string;\n\t\tdefaultValue: string;\n\t}\n) {\n\tconst { modelAttribute } = options;\n\n\tschema.extend( 'table', {\n\t\tallowAttributes: [ modelAttribute ]\n\t} );\n\tupcastStyleToAttribute( conversion, { viewElement: 'table', ...options } );\n\tdowncastTableAttribute( conversion, options );\n}\n\n/**\n * Enables conversion for an attribute for simple view (figure) to model (table) mappings.\n */\nfunction enableTableToFigureProperty(\n\tschema: Schema,\n\tconversion: Conversion,\n\toptions: {\n\t\tmodelAttribute: string;\n\t\tstyleName: string;\n\t\tdefaultValue: string;\n\t}\n) {\n\tconst { modelAttribute } = options;\n\n\tschema.extend( 'table', {\n\t\tallowAttributes: [ modelAttribute ]\n\t} );\n\n\tupcastStyleToAttribute( conversion, {\n\t\tviewElement: /^(table|figure)$/,\n\t\tshouldUpcast: ( element: ViewElement ) => !( element.name == 'table' && element.parent!.name == 'figure' ),\n\t\t...options\n\t} );\n\n\tdowncastAttributeToStyle( conversion, { modelElement: 'table', ...options } );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/ui/tablepropertiesview\n */\n\nimport {\n\taddListToDropdown,\n\tButtonView,\n\tcreateLabeledDropdown,\n\tcreateLabeledInputText,\n\tFocusCycler,\n\tFormHeaderView,\n\tLabeledFieldView,\n\tLabelView,\n\tsubmitHandler,\n\tToolbarView,\n\tView,\n\tViewCollection,\n\ttype DropdownView,\n\ttype InputTextView,\n\ttype NormalizedColorOption,\n\ttype ColorPickerConfig,\n\ttype FocusableView\n} from 'ckeditor5/src/ui.js';\nimport { FocusTracker, KeystrokeHandler, type ObservableChangeEvent, type Locale } from 'ckeditor5/src/utils.js';\nimport { icons } from 'ckeditor5/src/core.js';\n\nimport {\n\tfillToolbar,\n\tgetBorderStyleDefinitions,\n\tgetBorderStyleLabels,\n\tgetLabeledColorInputCreator\n} from '../../utils/ui/table-properties.js';\nimport FormRowView from '../../ui/formrowview.js';\n\nimport '../../../theme/form.css';\nimport '../../../theme/tableform.css';\nimport '../../../theme/tableproperties.css';\nimport type ColorInputView from '../../ui/colorinputview.js';\nimport type { TablePropertiesOptions } from '../../tableconfig.js';\n\n/**\n * Additional configuration of the view.\n */\nexport interface TablePropertiesViewOptions {\n\n\t/**\n\t * A configuration of the border color palette used by the\n\t * {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView#borderColorInput}.\n\t */\n\tborderColors: Array<NormalizedColorOption>;\n\n\t/**\n\t * A configuration of the background color palette used by the\n\t * {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView#backgroundInput}.\n\t */\n\tbackgroundColors: Array<NormalizedColorOption>;\n\n\t/**\n\t * The default table properties.\n\t */\n\tdefaultTableProperties: TablePropertiesOptions;\n\n\t/**\n\t * The default color picker config.\n\t */\n\tcolorPickerConfig: false | ColorPickerConfig;\n}\n\n/**\n * The class representing a table properties form, allowing users to customize\n * certain style aspects of a table, for instance, border, background color, alignment, etc..\n */\nexport default class TablePropertiesView extends View {\n\t/**\n\t * The value of the border style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public borderStyle: string;\n\n\t/**\n\t * The value of the border width style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public borderWidth: string;\n\n\t/**\n\t * The value of the border color style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public borderColor: string;\n\n\t/**\n\t * The value of the background color style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public backgroundColor: string;\n\n\t/**\n\t * The value of the table width style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public width: string;\n\n\t/**\n\t * The value of the table height style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public height: string;\n\n\t/**\n\t * The value of the table alignment style.\n\t *\n\t * @observable\n\t * @default ''\n\t */\n\tdeclare public alignment: string;\n\n\t/**\n\t * Options passed to the view. See {@link #constructor} to learn more.\n\t */\n\tpublic readonly options: TablePropertiesViewOptions;\n\n\t/**\n\t * Tracks information about the DOM focus in the form.\n\t */\n\tpublic readonly focusTracker: FocusTracker;\n\n\t/**\n\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t */\n\tpublic readonly keystrokes: KeystrokeHandler;\n\n\t/**\n\t * A collection of child views in the form.\n\t */\n\tpublic readonly children: ViewCollection;\n\n\t/**\n\t * A dropdown that allows selecting the style of the table border.\n\t */\n\tpublic readonly borderStyleDropdown: LabeledFieldView<DropdownView>;\n\n\t/**\n\t * An input that allows specifying the width of the table border.\n\t */\n\tpublic readonly borderWidthInput: LabeledFieldView<InputTextView>;\n\n\t/**\n\t * An input that allows specifying the color of the table border.\n\t */\n\tpublic readonly borderColorInput: LabeledFieldView<ColorInputView>;\n\n\t/**\n\t * An input that allows specifying the table background color.\n\t */\n\tpublic readonly backgroundInput: LabeledFieldView<ColorInputView>;\n\n\t/**\n\t * An input that allows specifying the table width.\n\t */\n\tpublic readonly widthInput: LabeledFieldView<InputTextView>;\n\n\t/**\n\t * An input that allows specifying the table height.\n\t */\n\tpublic readonly heightInput: LabeledFieldView<InputTextView>;\n\n\t/**\n\t * A toolbar with buttons that allow changing the alignment of an entire table.\n\t */\n\tpublic readonly alignmentToolbar: ToolbarView;\n\n\t/**\n\t * The \"Save\" button view.\n\t */\n\tpublic saveButtonView: ButtonView;\n\n\t/**\n\t * The \"Cancel\" button view.\n\t */\n\tpublic cancelButtonView: ButtonView;\n\n\t/**\n\t * A collection of views that can be focused in the form.\n\t */\n\tprotected readonly _focusables: ViewCollection<FocusableView>;\n\n\t/**\n\t * Helps cycling over {@link #_focusables} in the form.\n\t */\n\tprotected readonly _focusCycler: FocusCycler;\n\n\t/**\n\t * @param locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param options Additional configuration of the view.\n\t */\n\tconstructor( locale: Locale, options: TablePropertiesViewOptions ) {\n\t\tsuper( locale );\n\n\t\tthis.set( {\n\t\t\tborderStyle: '',\n\t\t\tborderWidth: '',\n\t\t\tborderColor: '',\n\t\t\tbackgroundColor: '',\n\t\t\twidth: '',\n\t\t\theight: '',\n\t\t\talignment: ''\n\t\t} );\n\n\t\tthis.options = options;\n\n\t\tconst { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();\n\t\tconst { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();\n\t\tconst { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();\n\t\tconst { alignmentToolbar, alignmentLabel } = this._createAlignmentFields();\n\n\t\tthis.focusTracker = new FocusTracker();\n\t\tthis.keystrokes = new KeystrokeHandler();\n\t\tthis.children = this.createCollection();\n\n\t\tthis.borderStyleDropdown = borderStyleDropdown;\n\t\tthis.borderWidthInput = borderWidthInput;\n\t\tthis.borderColorInput = borderColorInput;\n\t\tthis.backgroundInput = backgroundInput;\n\t\tthis.widthInput = widthInput;\n\t\tthis.heightInput = heightInput;\n\t\tthis.alignmentToolbar = alignmentToolbar;\n\n\t\t// Defer creating to make sure other fields are present and the Save button can\n\t\t// bind its #isEnabled to their error messages so there's no way to save unless all\n\t\t// fields are valid.\n\t\tconst { saveButtonView, cancelButtonView } = this._createActionButtons();\n\n\t\tthis.saveButtonView = saveButtonView;\n\t\tthis.cancelButtonView = cancelButtonView;\n\t\tthis._focusables = new ViewCollection();\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t// Form header.\n\t\tthis.children.add( new FormHeaderView( locale, {\n\t\t\tlabel: this.t!( 'Table properties' )\n\t\t} ) );\n\n\t\t// Border row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: borderRowLabel,\n\t\t\tchildren: [\n\t\t\t\tborderRowLabel,\n\t\t\t\tborderStyleDropdown,\n\t\t\t\tborderColorInput,\n\t\t\t\tborderWidthInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__border-row'\n\t\t} ) );\n\n\t\t// Background row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: backgroundRowLabel,\n\t\t\tchildren: [\n\t\t\t\tbackgroundRowLabel,\n\t\t\t\tbackgroundInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__background-row'\n\t\t} ) );\n\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\t// Dimensions row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tlabelView: dimensionsLabel,\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tdimensionsLabel,\n\t\t\t\t\t\twidthInput,\n\t\t\t\t\t\toperatorLabel,\n\t\t\t\t\t\theightInput\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-form__dimensions-row'\n\t\t\t\t} ),\n\t\t\t\t// Alignment row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tlabelView: alignmentLabel,\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\talignmentLabel,\n\t\t\t\t\t\talignmentToolbar\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-properties-form__alignment-row'\n\t\t\t\t} )\n\t\t\t]\n\t\t} ) );\n\n\t\t// Action row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\tthis.saveButtonView,\n\t\t\t\tthis.cancelButtonView\n\t\t\t],\n\t\t\tclass: 'ck-table-form__action-row'\n\t\t} ) );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form',\n\t\t\t\t\t'ck-table-form',\n\t\t\t\t\t'ck-table-properties-form'\n\t\t\t\t],\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/90\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override render(): void {\n\t\tsuper.render();\n\n\t\t// Enable the \"submit\" event for this view. It can be triggered by the #saveButtonView\n\t\t// which is of the \"submit\" DOM \"type\".\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\t// Maintain continuous focus cycling over views that have focusable children and focus cyclers themselves.\n\t\t[ this.borderColorInput, this.backgroundInput ].forEach( view => {\n\t\t\tthis._focusCycler.chain( view.fieldView.focusCycler );\n\t\t} );\n\n\t\t[\n\t\t\tthis.borderStyleDropdown,\n\t\t\tthis.borderColorInput,\n\t\t\tthis.borderWidthInput,\n\t\t\tthis.backgroundInput,\n\t\t\tthis.widthInput,\n\t\t\tthis.heightInput,\n\t\t\tthis.alignmentToolbar,\n\t\t\tthis.saveButtonView,\n\t\t\tthis.cancelButtonView\n\t\t].forEach( view => {\n\t\t\t// Register the view as focusable.\n\t\t\tthis._focusables.add( view! );\n\n\t\t\t// Register the view in the focus tracker.\n\t\t\tthis.focusTracker.add( view!.element! );\n\t\t} );\n\n\t\t// Mainly for closing using \"Esc\" and navigation using \"Tab\".\n\t\tthis.keystrokes.listenTo( this.element! );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the fist focusable field in the form.\n\t */\n\tpublic focus(): void {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #borderStyleDropdown},\n\t * * {@link #borderWidthInput},\n\t * * {@link #borderColorInput}.\n\t */\n\tprivate _createBorderFields() {\n\t\tconst defaultTableProperties = this.options.defaultTableProperties;\n\t\tconst defaultBorder = {\n\t\t\tstyle: defaultTableProperties.borderStyle,\n\t\t\twidth: defaultTableProperties.borderWidth,\n\t\t\tcolor: defaultTableProperties.borderColor\n\t\t};\n\n\t\tconst colorInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.borderColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: defaultBorder.color,\n\t\t\tcolorPickerConfig: this.options.colorPickerConfig\n\t\t} );\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\t\tconst accessibleLabel = t( 'Style' );\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst borderRowLabel = new LabelView( locale );\n\t\tborderRowLabel.text = t( 'Border' );\n\n\t\t// -- Style ---------------------------------------------------\n\n\t\tconst styleLabels = getBorderStyleLabels( t );\n\t\tconst borderStyleDropdown = new LabeledFieldView( locale, createLabeledDropdown );\n\t\tborderStyleDropdown.set( {\n\t\t\tlabel: accessibleLabel,\n\t\t\tclass: 'ck-table-form__border-style'\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.set( {\n\t\t\tariaLabel: accessibleLabel,\n\t\t\tariaLabelledBy: undefined,\n\t\t\tisOn: false,\n\t\t\twithText: true,\n\t\t\ttooltip: accessibleLabel\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {\n\t\t\treturn styleLabels[ value ? value : 'none' ];\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.on( 'execute', evt => {\n\t\t\tthis.borderStyle = ( evt.source as any )._borderStyleValue;\n\t\t} );\n\n\t\tborderStyleDropdown.bind( 'isEmpty' ).to( this, 'borderStyle', value => !value );\n\n\t\taddListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this, defaultBorder.style! ), {\n\t\t\trole: 'menu',\n\t\t\tariaLabel: accessibleLabel\n\t\t} );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst borderWidthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\tborderWidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__border-width'\n\t\t} );\n\n\t\tborderWidthInput.fieldView.bind( 'value' ).to( this, 'borderWidth' );\n\t\tborderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\t\tborderWidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderWidth = borderWidthInput.fieldView.element!.value;\n\t\t} );\n\n\t\t// -- Color ---------------------------------------------------\n\n\t\tconst borderColorInput = new LabeledFieldView( locale, colorInputCreator );\n\n\t\tborderColorInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-form__border-color'\n\t\t} );\n\n\t\tborderColorInput.fieldView.bind( 'value' ).to( this, 'borderColor' );\n\t\tborderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\n\t\tborderColorInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderColor = borderColorInput.fieldView.value;\n\t\t} );\n\n\t\t// Reset the border color and width fields depending on the `border-style` value.\n\t\tthis.on<ObservableChangeEvent<string>>( 'change:borderStyle', ( evt, name, newValue, oldValue ) => {\n\t\t\t// When removing the border (`border-style:none`), clear the remaining `border-*` properties.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/6227.\n\t\t\tif ( !isBorderStyleSet( newValue ) ) {\n\t\t\t\tthis.borderColor = '';\n\t\t\t\tthis.borderWidth = '';\n\t\t\t}\n\n\t\t\t// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.\n\t\t\tif ( !isBorderStyleSet( oldValue ) ) {\n\t\t\t\tthis.borderColor = defaultBorder.color!;\n\t\t\t\tthis.borderWidth = defaultBorder.width!;\n\t\t\t}\n\t\t} );\n\n\t\treturn {\n\t\t\tborderRowLabel,\n\t\t\tborderStyleDropdown,\n\t\t\tborderColorInput,\n\t\t\tborderWidthInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #backgroundInput}.\n\t */\n\tprivate _createBackgroundFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst backgroundRowLabel = new LabelView( locale );\n\t\tbackgroundRowLabel.text = t( 'Background' );\n\n\t\t// -- Background color input -----------------------------------\n\n\t\tconst backgroundInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.backgroundColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: this.options.defaultTableProperties.backgroundColor,\n\t\t\tcolorPickerConfig: this.options.colorPickerConfig\n\t\t} );\n\n\t\tconst backgroundInput = new LabeledFieldView( locale, backgroundInputCreator );\n\n\t\tbackgroundInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-properties-form__background'\n\t\t} );\n\n\t\tbackgroundInput.fieldView.bind( 'value' ).to( this, 'backgroundColor' );\n\t\tbackgroundInput.fieldView.on( 'input', () => {\n\t\t\tthis.backgroundColor = backgroundInput.fieldView.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tbackgroundRowLabel,\n\t\t\tbackgroundInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #widthInput},\n\t * * {@link #heightInput}.\n\t */\n\tprivate _createDimensionFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\n\t\t// -- Label ---------------------------------------------------\n\n\t\tconst dimensionsLabel = new LabelView( locale );\n\t\tdimensionsLabel.text = t( 'Dimensions' );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst widthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\twidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__width'\n\t\t} );\n\n\t\twidthInput.fieldView.bind( 'value' ).to( this, 'width' );\n\t\twidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.width = widthInput.fieldView.element!.value;\n\t\t} );\n\n\t\t// -- Operator ---------------------------------------------------\n\n\t\tconst operatorLabel = new View( locale );\n\t\toperatorLabel.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-table-form__dimension-operator'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{ text: '×' }\n\t\t\t]\n\t\t} );\n\n\t\t// -- Height ---------------------------------------------------\n\n\t\tconst heightInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\theightInput.set( {\n\t\t\tlabel: t( 'Height' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__height'\n\t\t} );\n\n\t\theightInput.fieldView.bind( 'value' ).to( this, 'height' );\n\t\theightInput.fieldView.on( 'input', () => {\n\t\t\tthis.height = heightInput.fieldView.element!.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tdimensionsLabel,\n\t\t\twidthInput,\n\t\t\toperatorLabel,\n\t\t\theightInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #alignmentToolbar}.\n\t */\n\tprivate _createAlignmentFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\n\t\t// -- Label ---------------------------------------------------\n\n\t\tconst alignmentLabel = new LabelView( locale );\n\t\talignmentLabel.text = t( 'Alignment' );\n\n\t\t// -- Toolbar ---------------------------------------------------\n\n\t\tconst alignmentToolbar = new ToolbarView( locale! );\n\t\talignmentToolbar.set( {\n\t\t\tisCompact: true,\n\t\t\tariaLabel: t( 'Table alignment toolbar' )\n\t\t} );\n\n\t\tfillToolbar( {\n\t\t\tview: this,\n\t\t\ticons: {\n\t\t\t\tleft: icons.objectLeft,\n\t\t\t\tcenter: icons.objectCenter,\n\t\t\t\tright: icons.objectRight\n\t\t\t},\n\t\t\ttoolbar: alignmentToolbar,\n\t\t\tlabels: this._alignmentLabels,\n\t\t\tpropertyName: 'alignment',\n\t\t\tdefaultValue: this.options.defaultTableProperties.alignment!\n\t\t} );\n\n\t\treturn {\n\t\t\talignmentLabel,\n\t\t\talignmentToolbar\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form controls:\n\t *\n\t * * {@link #saveButtonView},\n\t * * {@link #cancelButtonView}.\n\t */\n\tprivate _createActionButtons(): {\n\t\tsaveButtonView: ButtonView;\n\t\tcancelButtonView: ButtonView;\n\t\t} {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t!;\n\n\t\tconst saveButtonView = new ButtonView( locale );\n\t\tconst cancelButtonView = new ButtonView( locale );\n\t\tconst fieldsThatShouldValidateToSave = [\n\t\t\tthis.borderWidthInput!,\n\t\t\tthis.borderColorInput!,\n\t\t\tthis.backgroundInput!,\n\t\t\tthis.widthInput!,\n\t\t\tthis.heightInput!\n\t\t];\n\n\t\tsaveButtonView.set( {\n\t\t\tlabel: t( 'Save' ),\n\t\t\ticon: icons.check,\n\t\t\tclass: 'ck-button-save',\n\t\t\ttype: 'submit',\n\t\t\twithText: true\n\t\t} );\n\n\t\tsaveButtonView.bind( 'isEnabled' ).toMany( fieldsThatShouldValidateToSave, 'errorText', ( ...errorTexts ) => {\n\t\t\treturn errorTexts.every( errorText => !errorText );\n\t\t} );\n\n\t\tcancelButtonView.set( {\n\t\t\tlabel: t( 'Cancel' ),\n\t\t\ticon: icons.cancel,\n\t\t\tclass: 'ck-button-cancel',\n\t\t\twithText: true\n\t\t} );\n\n\t\tcancelButtonView.delegate( 'execute' ).to( this, 'cancel' );\n\n\t\treturn {\n\t\t\tsaveButtonView, cancelButtonView\n\t\t};\n\t}\n\n\t/**\n\t * Provides localized labels for {@link #alignmentToolbar} buttons.\n\t */\n\tprivate get _alignmentLabels() {\n\t\tconst locale = this.locale!;\n\t\tconst t = this.t!;\n\n\t\tconst left = t( 'Align table to the left' );\n\t\tconst center = t( 'Center table' );\n\t\tconst right = t( 'Align table to the right' );\n\n\t\t// Returns object with a proper order of labels.\n\t\tif ( locale.uiLanguageDirection === 'rtl' ) {\n\t\t\treturn { right, center, left };\n\t\t} else {\n\t\t\treturn { left, center, right };\n\t\t}\n\t}\n}\n\nfunction isBorderStyleSet( value: string ) {\n\treturn value !== 'none';\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/tablepropertiesui\n */\n\nimport { type Editor, Plugin } from 'ckeditor5/src/core.js';\nimport {\n\tButtonView,\n\tContextualBalloon,\n\tclickOutsideHandler,\n\tgetLocalizedColorOptions,\n\tnormalizeColorOptions,\n\ttype LabeledFieldView\n} from 'ckeditor5/src/ui.js';\n\nimport { debounce } from 'lodash-es';\n\nimport TablePropertiesView from './ui/tablepropertiesview.js';\nimport tableProperties from './../../theme/icons/table-properties.svg';\nimport {\n\tcolorFieldValidator,\n\tgetLocalizedColorErrorText,\n\tgetLocalizedLengthErrorText,\n\tlengthFieldValidator,\n\tlineWidthFieldValidator,\n\tdefaultColors\n} from '../utils/ui/table-properties.js';\nimport { getSelectionAffectedTableWidget } from '../utils/ui/widget.js';\nimport { getBalloonTablePositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon.js';\nimport { getNormalizedDefaultTableProperties, type NormalizedDefaultProperties } from '../utils/table-properties.js';\nimport type { Batch } from 'ckeditor5/src/engine.js';\nimport type { EventInfo, ObservableChangeEvent } from 'ckeditor5/src/utils.js';\n\nimport type TableBorderStyleCommand from './commands/tableborderstylecommand.js';\n\nconst ERROR_TEXT_TIMEOUT = 500;\n\n// Map of view properties and related commands.\nconst propertyToCommandMap = {\n\tborderStyle: 'tableBorderStyle',\n\tborderColor: 'tableBorderColor',\n\tborderWidth: 'tableBorderWidth',\n\tbackgroundColor: 'tableBackgroundColor',\n\twidth: 'tableWidth',\n\theight: 'tableHeight',\n\talignment: 'tableAlignment'\n};\n\n/**\n * The table properties UI plugin. It introduces the `'tableProperties'` button\n * that opens a form allowing to specify visual styling of an entire table.\n *\n * It uses the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n */\nexport default class TablePropertiesUI extends Plugin {\n\t/**\n\t * The default table properties.\n\t */\n\tprivate _defaultTableProperties!: NormalizedDefaultProperties;\n\n\t/**\n\t * The contextual balloon plugin instance.\n\t */\n\tprivate _balloon!: ContextualBalloon;\n\n\t/**\n\t * The properties form view displayed inside the balloon.\n\t */\n\tpublic view: TablePropertiesView | null = null;\n\n\t/**\n\t * The batch used to undo all changes made by the form (which are live, as the user types)\n\t * when \"Cancel\" was pressed. Each time the view is shown, a new batch is created.\n\t */\n\tprivate _undoStepBatch?: Batch;\n\n\t/**\n\t * Flag used to indicate whether view is ready to execute update commands\n\t * (it finished loading initial data).\n\t */\n\tprivate _isReady?: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ ContextualBalloon ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TablePropertiesUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'table.tableProperties', {\n\t\t\tborderColors: defaultColors,\n\t\t\tbackgroundColors: defaultColors\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\tthis._defaultTableProperties = getNormalizedDefaultTableProperties(\n\t\t\teditor.config.get( 'table.tableProperties.defaultProperties' )!,\n\t\t\t{\n\t\t\t\tincludeAlignmentProperty: true\n\t\t\t}\n\t\t);\n\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\n\t\teditor.ui.componentFactory.add( 'tableProperties', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: t( 'Table properties' ),\n\t\t\t\ticon: tableProperties,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tthis.listenTo( view, 'execute', () => this._showView() );\n\n\t\t\tconst commands = Object.values( propertyToCommandMap )\n\t\t\t\t.map( commandName => editor.commands.get( commandName )! );\n\n\t\t\tview.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => (\n\t\t\t\tareEnabled.some( isCommandEnabled => isCommandEnabled )\n\t\t\t) );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1341.\n\t\tif ( this.view ) {\n\t\t\tthis.view.destroy();\n\t\t}\n\t}\n\n\t/**\n\t * Creates the {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} instance.\n\t *\n\t * @returns The table properties form view instance.\n\t */\n\tprivate _createPropertiesView() {\n\t\tconst editor = this.editor;\n\t\tconst config = editor.config.get( 'table.tableProperties' )!;\n\t\tconst borderColorsConfig = normalizeColorOptions( config.borderColors! );\n\t\tconst localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig );\n\t\tconst backgroundColorsConfig = normalizeColorOptions( config.backgroundColors! );\n\t\tconst localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig );\n\t\tconst hasColorPicker = config.colorPicker !== false;\n\n\t\tconst view = new TablePropertiesView( editor.locale, {\n\t\t\tborderColors: localizedBorderColors,\n\t\t\tbackgroundColors: localizedBackgroundColors,\n\t\t\tdefaultTableProperties: this._defaultTableProperties,\n\t\t\tcolorPickerConfig: hasColorPicker ? ( config.colorPicker || {} ) : false\n\t\t} );\n\t\tconst t = editor.t;\n\n\t\t// Render the view so its #element is available for the clickOutsideHandler.\n\t\tview.render();\n\n\t\tthis.listenTo( view, 'submit', () => {\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\tthis.listenTo( view, 'cancel', () => {\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/6180\n\t\t\tif ( this._undoStepBatch!.operations.length ) {\n\t\t\t\teditor.execute( 'undo', this._undoStepBatch );\n\t\t\t}\n\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\t// Close the balloon on Esc key press.\n\t\tview.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideView();\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: view,\n\t\t\tactivator: () => this._isViewInBalloon,\n\t\t\tcontextElements: [ this._balloon.view.element! ],\n\t\t\tcallback: () => this._hideView()\n\t\t} );\n\n\t\tconst colorErrorText = getLocalizedColorErrorText( t );\n\t\tconst lengthErrorText = getLocalizedLengthErrorText( t );\n\n\t\t// Create the \"UI -> editor data\" binding.\n\t\t// These listeners update the editor data (via table commands) when any observable\n\t\t// property of the view has changed. They also validate the value and display errors in the UI\n\t\t// when necessary. This makes the view live, which means the changes are\n\t\t// visible in the editing as soon as the user types or changes fields' values.\n\t\tview.on<ObservableChangeEvent<string>>(\n\t\t\t'change:borderStyle',\n\t\t\tthis._getPropertyChangeCallback( 'tableBorderStyle' )\n\t\t);\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:borderColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderColorInput,\n\t\t\tcommandName: 'tableBorderColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:borderWidth', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderWidthInput,\n\t\t\tcommandName: 'tableBorderWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lineWidthFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:backgroundColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.backgroundInput,\n\t\t\tcommandName: 'tableBackgroundColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:width', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.widthInput,\n\t\t\tcommandName: 'tableWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>( 'change:height', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.heightInput,\n\t\t\tcommandName: 'tableHeight',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator\n\t\t} ) );\n\n\t\tview.on<ObservableChangeEvent<string>>(\n\t\t\t'change:alignment',\n\t\t\tthis._getPropertyChangeCallback( 'tableAlignment' )\n\t\t);\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * In this method the \"editor data -> UI\" binding is happening.\n\t *\n\t * When executed, this method obtains selected table property values from various table commands\n\t * and passes them to the {@link #view}.\n\t *\n\t * This way, the UI stays up–to–date with the editor data.\n\t */\n\tprivate _fillViewFormFromCommandValues() {\n\t\tconst commands = this.editor.commands;\n\t\tconst borderStyleCommand: TableBorderStyleCommand = commands.get( 'tableBorderStyle' )!;\n\n\t\tObject.entries( propertyToCommandMap )\n\t\t\t.map( ( [ property, commandName ] ) => {\n\t\t\t\tconst propertyKey = property as keyof typeof propertyToCommandMap;\n\t\t\t\tconst defaultValue = this._defaultTableProperties[ propertyKey ] || '';\n\n\t\t\t\treturn [ propertyKey, ( commands.get( commandName )!.value || defaultValue ) as string ] as const;\n\t\t\t} )\n\t\t\t.forEach( ( [ property, value ] ) => {\n\t\t\t\t// Do not set the `border-color` and `border-width` fields if `border-style:none`.\n\t\t\t\tif ( ( property === 'borderColor' || property === 'borderWidth' ) && borderStyleCommand.value === 'none' ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.view!.set( property, value );\n\t\t\t} );\n\n\t\tthis._isReady = true;\n\t}\n\n\t/**\n\t * Shows the {@link #view} in the {@link #_balloon}.\n\t *\n\t * **Note**: Each time a view is shown, the new {@link #_undoStepBatch} is created that contains\n\t * all changes made to the document when the view is visible, allowing a single undo step\n\t * for all of them.\n\t */\n\tprotected _showView(): void {\n\t\tconst editor = this.editor;\n\n\t\tif ( !this.view ) {\n\t\t\tthis.view = this._createPropertiesView();\n\t\t}\n\n\t\tthis.listenTo( editor.ui, 'update', () => {\n\t\t\tthis._updateView();\n\t\t} );\n\n\t\t// Update the view with the model values.\n\t\tthis._fillViewFormFromCommandValues();\n\n\t\tthis._balloon.add( {\n\t\t\tview: this.view,\n\t\t\tposition: getBalloonTablePositionData( editor )\n\t\t} );\n\n\t\t// Create a new batch. Clicking \"Cancel\" will undo this batch.\n\t\tthis._undoStepBatch = editor.model.createBatch();\n\n\t\t// Basic a11y.\n\t\tthis.view.focus();\n\t}\n\n\t/**\n\t * Removes the {@link #view} from the {@link #_balloon}.\n\t */\n\tprotected _hideView(): void {\n\t\tconst editor = this.editor;\n\n\t\tthis.stopListening( editor.ui, 'update' );\n\n\t\tthis._isReady = false;\n\n\t\t// Blur any input element before removing it from DOM to prevent issues in some browsers.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\tthis.view!.saveButtonView.focus();\n\n\t\tthis._balloon.remove( this.view! );\n\n\t\t// Make sure the focus is not lost in the process by putting it directly\n\t\t// into the editing view.\n\t\tthis.editor.editing.view.focus();\n\t}\n\n\t/**\n\t * Repositions the {@link #_balloon} or hides the {@link #view} if a table is no longer selected.\n\t */\n\tprotected _updateView(): void {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\tif ( !getSelectionAffectedTableWidget( viewDocument.selection ) ) {\n\t\t\tthis._hideView();\n\t\t} else if ( this._isViewVisible ) {\n\t\t\trepositionContextualBalloon( editor, 'table' );\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is the visible in the {@link #_balloon}.\n\t */\n\tprivate get _isViewVisible(): boolean {\n\t\treturn !!this.view && this._balloon.visibleView === this.view;\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is in the {@link #_balloon}.\n\t */\n\tprivate get _isViewInBalloon(): boolean {\n\t\treturn !!this.view && this._balloon.hasView( this.view );\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon {@link #view view's} property change\n\t * executes a related editor command with the new property value.\n\t *\n\t * If new value will be set to the default value, the command will not be executed.\n\t *\n\t * @param commandName The command that will be executed.\n\t */\n\tprivate _getPropertyChangeCallback( commandName: 'tableBorderStyle' | 'tableAlignment' ) {\n\t\treturn ( evt: EventInfo, propertyName: string, newValue: string ) => {\n\t\t\t// Do not execute the command on initial call (opening the table properties view).\n\t\t\tif ( !this._isReady ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( commandName, {\n\t\t\t\tvalue: newValue,\n\t\t\t\tbatch: this._undoStepBatch\n\t\t\t} );\n\t\t};\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon {@link #view view's} property change:\n\t * * executes a related editor command with the new property value if the value is valid,\n\t * * or sets the error text next to the invalid field, if the value did not pass the validation.\n\t */\n\tprivate _getValidatedPropertyChangeCallback(\n\t\toptions: {\n\t\t\tcommandName: 'tableBorderColor' | 'tableBorderWidth' | 'tableBackgroundColor' | 'tableWidth' | 'tableHeight';\n\t\t\tviewField: LabeledFieldView;\n\t\t\tvalidator: ( value: string ) => boolean;\n\t\t\terrorText: string;\n\t\t}\n\t) {\n\t\tconst { commandName, viewField, validator, errorText } = options;\n\t\tconst setErrorTextDebounced = debounce( () => {\n\t\t\tviewField.errorText = errorText;\n\t\t}, ERROR_TEXT_TIMEOUT );\n\n\t\treturn ( evt: EventInfo, propertyName: string, newValue: string ) => {\n\t\t\tsetErrorTextDebounced.cancel();\n\n\t\t\t// Do not execute the command on initial call (opening the table properties view).\n\t\t\tif ( !this._isReady ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( validator( newValue ) ) {\n\t\t\t\tthis.editor.execute( commandName, {\n\t\t\t\t\tvalue: newValue,\n\t\t\t\t\tbatch: this._undoStepBatch\n\t\t\t\t} );\n\n\t\t\t\tviewField.errorText = null;\n\t\t\t} else {\n\t\t\t\tsetErrorTextDebounced();\n\t\t\t}\n\t\t};\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\n\nimport TablePropertiesEditing from './tableproperties/tablepropertiesediting.js';\nimport TablePropertiesUI from './tableproperties/tablepropertiesui.js';\n\n/**\n * The table properties feature. Enables support for setting properties of tables (size, border, background, etc.).\n *\n * Read more in the {@glink features/tables/tables-styling Table and cell styling tools} section.\n * See also the {@link module:table/tablecellproperties~TableCellProperties} plugin.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing table properties editing feature} and\n * the {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI table properties UI feature}.\n */\nexport default class TableProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableProperties' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TablePropertiesEditing, TablePropertiesUI ] as const;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-caption-post-fixer\n */\n\nimport type { Model, Writer, Element, Node } from 'ckeditor5/src/engine.js';\n\n/**\n * Injects a table caption post-fixer into the model.\n *\n * The role of the table caption post-fixer is to ensure that the table with caption have the correct structure\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct structure means that:\n *\n * * If there are many caption model element, they are merged into one model.\n * * A final, merged caption model is placed at the end of the table.\n */\nexport default function injectTableCaptionPostFixer( model: Model ): void {\n\tmodel.document.registerPostFixer( writer => tableCaptionPostFixer( writer, model ) );\n}\n\n/**\n * The table caption post-fixer.\n */\nfunction tableCaptionPostFixer( writer: Writer, model: Model ) {\n\tconst changes = model.document.differ.getChanges();\n\tlet wasFixed = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type != 'insert' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst positionParent = entry.position.parent;\n\n\t\tif ( positionParent.is( 'element', 'table' ) || entry.name == 'table' ) {\n\t\t\tconst table = ( entry.name == 'table' ? entry.position.nodeAfter : positionParent ) as Element;\n\t\t\tconst captionsToMerge = Array.from( table.getChildren() )\n\t\t\t\t.filter( ( child: Node ): child is Element => child.is( 'element', 'caption' ) );\n\t\t\tconst firstCaption = captionsToMerge.shift();\n\n\t\t\tif ( !firstCaption ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Move all the contents of the captions to the first one.\n\t\t\tfor ( const caption of captionsToMerge ) {\n\t\t\t\twriter.move( writer.createRangeIn( caption ), firstCaption, 'end' );\n\t\t\t\twriter.remove( caption );\n\t\t\t}\n\n\t\t\t// Make sure the final caption is at the end of the table.\n\t\t\tif ( firstCaption.nextSibling ) {\n\t\t\t\twriter.move( writer.createRangeOn( firstCaption ), table, 'end' );\n\t\t\t\twasFixed = true;\n\t\t\t}\n\n\t\t\t// Do we merged captions and/or moved the single caption to the end of the table?\n\t\t\twasFixed = !!captionsToMerge.length || wasFixed;\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecaption/utils\n */\n\nimport type {\n\tDocumentFragment,\n\tDocumentSelection,\n\tElement,\n\tViewElement\n} from 'ckeditor5/src/engine.js';\n\nimport { getSelectionAffectedTable } from '../utils/common.js';\n\n/**\n * Checks if the provided model element is a `table`.\n *\n * @param modelElement Element to check if it is a table.\n */\nexport function isTable( modelElement: Element | DocumentFragment | null ): boolean {\n\treturn !!modelElement && modelElement.is( 'element', 'table' );\n}\n\n/**\n * Returns the caption model element from a given table element. Returns `null` if no caption is found.\n *\n * @param tableModelElement Table element in which we will try to find a caption element.\n */\nexport function getCaptionFromTableModelElement( tableModelElement: Element ): Element | null {\n\tfor ( const node of tableModelElement.getChildren() ) {\n\t\tif ( node.is( 'element', 'caption' ) ) {\n\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns the caption model element for a model selection. Returns `null` if the selection has no caption element ancestor.\n *\n * @param selection The selection checked for caption presence.\n */\nexport function getCaptionFromModelSelection( selection: DocumentSelection ): Element | null {\n\tconst tableElement = getSelectionAffectedTable( selection );\n\n\tif ( !tableElement ) {\n\t\treturn null;\n\t}\n\n\treturn getCaptionFromTableModelElement( tableElement );\n}\n\n/**\n * {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a caption.\n *\n * There are two possible forms of the valid caption:\n *  - A `<figcaption>` element inside a `<figure class=\"table\">` element.\n *  - A `<caption>` inside a <table>.\n *\n * @returns Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element cannot be matched.\n */\nexport function matchTableCaptionViewElement( element: ViewElement ): { name: true } | null {\n\tconst parent = element.parent;\n\n\tif ( element.name == 'figcaption' && parent && parent.is( 'element', 'figure' ) && parent.hasClass( 'table' ) ) {\n\t\treturn { name: true };\n\t}\n\n\tif ( element.name == 'caption' && parent && parent.is( 'element', 'table' ) ) {\n\t\treturn { name: true };\n\t}\n\n\treturn null;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n* @module table/tablecaption/toggletablecaptioncommand\n*/\n\nimport { Command } from 'ckeditor5/src/core.js';\nimport type { Writer } from 'ckeditor5/src/engine.js';\nimport type TableCaptionEditing from './tablecaptionediting.js';\n\nimport { getCaptionFromTableModelElement } from './utils.js';\nimport { getSelectionAffectedTable } from '../utils/common.js';\n\n/**\n * The toggle table caption command.\n *\n * This command is registered by {@link module:table/tablecaption/tablecaptionediting~TableCaptionEditing} as the\n * `'toggleTableCaption'` editor command.\n *\n * Executing this command:\n *\n * * either adds or removes the table caption of a selected table (depending on whether the caption is present or not),\n * * removes the table caption if the selection is anchored in one.\n *\n * ```ts\n * // Toggle the presence of the caption.\n * editor.execute( 'toggleTableCaption' );\n * ```\n *\n * **Note**: You can move the selection to the caption right away as it shows up upon executing this command by using\n * the `focusCaptionOnShow` option:\n *\n * ```ts\n * editor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );\n * ```\n */\nexport default class ToggleTableCaptionCommand extends Command {\n\tdeclare public value: boolean;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\tconst editor = this.editor;\n\t\tconst tableElement = getSelectionAffectedTable( editor.model.document.selection );\n\n\t\tthis.isEnabled = !!tableElement;\n\n\t\tif ( !this.isEnabled ) {\n\t\t\tthis.value = false;\n\t\t} else {\n\t\t\tthis.value = !!getCaptionFromTableModelElement( tableElement );\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * ```ts\n\t * editor.execute( 'toggleTableCaption' );\n\t * ```\n\t *\n\t * @param options Options for the executed command.\n\t * @param options.focusCaptionOnShow When true and the caption shows up, the selection will be moved into it straight away.\n\t * @fires execute\n\t */\n\tpublic override execute( { focusCaptionOnShow = false }: { focusCaptionOnShow?: boolean } = {} ): void {\n\t\tthis.editor.model.change( writer => {\n\t\t\tif ( this.value ) {\n\t\t\t\tthis._hideTableCaption( writer );\n\t\t\t} else {\n\t\t\t\tthis._showTableCaption( writer, focusCaptionOnShow );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the table caption. Also:\n\t *\n\t * * it attempts to restore the caption content from the `TableCaptionEditing` caption registry,\n\t * * it moves the selection to the caption right away, it the `focusCaptionOnShow` option was set.\n\t *\n\t * @param focusCaptionOnShow Default focus behavior when showing the caption.\n\t */\n\tprivate _showTableCaption( writer: Writer, focusCaptionOnShow: boolean ) {\n\t\tconst model = this.editor.model;\n\t\tconst tableElement = getSelectionAffectedTable( model.document.selection );\n\t\tconst tableCaptionEditing: TableCaptionEditing = this.editor.plugins.get( 'TableCaptionEditing' );\n\t\tconst savedCaptionElement = tableCaptionEditing._getSavedCaption( tableElement );\n\n\t\t// Try restoring the caption from the TableCaptionEditing plugin storage.\n\t\tconst newCaptionElement = savedCaptionElement || writer.createElement( 'caption' );\n\n\t\tmodel.insertContent( newCaptionElement, tableElement, 'end' );\n\n\t\tif ( focusCaptionOnShow ) {\n\t\t\twriter.setSelection( newCaptionElement, 'in' );\n\t\t}\n\t}\n\n\t/**\n\t * Hides the caption of a selected table (or an table caption the selection is anchored to).\n\t *\n\t * The content of the caption is stored in the `TableCaptionEditing` caption registry to make this\n\t * a reversible action.\n\t */\n\tprivate _hideTableCaption( writer: Writer ) {\n\t\tconst model = this.editor.model;\n\t\tconst tableElement = getSelectionAffectedTable( model.document.selection );\n\t\tconst tableCaptionEditing: TableCaptionEditing = this.editor.plugins.get( 'TableCaptionEditing' );\n\t\tconst captionElement = getCaptionFromTableModelElement( tableElement )!;\n\n\t\t// Store the caption content so it can be restored quickly if the user changes their mind.\n\t\ttableCaptionEditing._saveCaption( tableElement, captionElement );\n\n\t\tmodel.deleteContent( writer.createSelection( captionElement, 'on' ) );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecaption/tablecaptionediting\n */\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\nimport { Element, enablePlaceholder } from 'ckeditor5/src/engine.js';\nimport { toWidgetEditable } from 'ckeditor5/src/widget.js';\n\nimport injectTableCaptionPostFixer from '../converters/table-caption-post-fixer.js';\nimport ToggleTableCaptionCommand from './toggletablecaptioncommand.js';\nimport { isTable, matchTableCaptionViewElement } from './utils.js';\n\n/**\n * The table caption editing plugin.\n */\nexport default class TableCaptionEditing extends Plugin {\n\t/**\n\t * A map that keeps saved JSONified table captions and table model elements they are\n\t * associated with.\n\t *\n\t * To learn more about this system, see {@link #_saveCaption}.\n\t */\n\tprivate _savedCaptionsMap: WeakMap<Element, unknown>;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableCaptionEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._savedCaptionsMap = new WeakMap();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst view = editor.editing.view;\n\t\tconst t = editor.t;\n\n\t\tif ( !schema.isRegistered( 'caption' ) ) {\n\t\t\tschema.register( 'caption', {\n\t\t\t\tallowIn: 'table',\n\t\t\t\tallowContentOf: '$block',\n\t\t\t\tisLimit: true\n\t\t\t} );\n\t\t} else {\n\t\t\tschema.extend( 'caption', {\n\t\t\t\tallowIn: 'table'\n\t\t\t} );\n\t\t}\n\n\t\teditor.commands.add( 'toggleTableCaption', new ToggleTableCaptionCommand( this.editor ) );\n\n\t\t// View -> model converter for the data pipeline.\n\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t\t\tview: matchTableCaptionViewElement,\n\t\t\tmodel: 'caption'\n\t\t} );\n\n\t\t// Model -> view converter for the data pipeline.\n\t\teditor.conversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\tmodel: 'caption',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tif ( !isTable( modelElement.parent ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn writer.createContainerElement( 'figcaption' );\n\t\t\t}\n\t\t} );\n\n\t\t// Model -> view converter for the editing pipeline.\n\t\teditor.conversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'caption',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tif ( !isTable( modelElement.parent ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst figcaptionElement = writer.createEditableElement( 'figcaption' );\n\t\t\t\twriter.setCustomProperty( 'tableCaption', true, figcaptionElement );\n\n\t\t\t\tfigcaptionElement.placeholder = t( 'Enter table caption' );\n\n\t\t\t\tenablePlaceholder( {\n\t\t\t\t\tview,\n\t\t\t\t\telement: figcaptionElement,\n\t\t\t\t\tkeepOnFocus: true\n\t\t\t\t} );\n\n\t\t\t\treturn toWidgetEditable( figcaptionElement, writer );\n\t\t\t}\n\t\t} );\n\n\t\tinjectTableCaptionPostFixer( editor.model );\n\t}\n\n\t/**\n\t * Returns the saved {@link module:engine/model/element~Element#toJSON JSONified} caption\n\t * of a table model element.\n\t *\n\t * See {@link #_saveCaption}.\n\t *\n\t * @internal\n\t * @param tableModelElement The model element the caption should be returned for.\n\t * @returns The model caption element or `null` if there is none.\n\t */\n\tpublic _getSavedCaption( tableModelElement: Element ): Element | null {\n\t\tconst jsonObject = this._savedCaptionsMap.get( tableModelElement );\n\n\t\treturn jsonObject ? Element.fromJSON( jsonObject ) : null;\n\t}\n\n\t/**\n\t * Saves a {@link module:engine/model/element~Element#toJSON JSONified} caption for\n\t * a table element to allow restoring it in the future.\n\t *\n\t * A caption is saved every time it gets hidden. The\n\t * user should be able to restore it on demand.\n\t *\n\t * **Note**: The caption cannot be stored in the table model element attribute because,\n\t * for instance, when the model state propagates to collaborators, the attribute would get\n\t * lost (mainly because it does not convert to anything when the caption is hidden) and\n\t * the states of collaborators' models would de-synchronize causing numerous issues.\n\t *\n\t * See {@link #_getSavedCaption}.\n\t *\n\t * @internal\n\t * @param tableModelElement The model element the caption is saved for.\n\t * @param caption The caption model element to be saved.\n\t */\n\tpublic _saveCaption( tableModelElement: Element, caption: Element ): void {\n\t\tthis._savedCaptionsMap.set( tableModelElement, caption.toJSON() );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n* @module table/tablecaption/tablecaptionui\n*/\n\nimport { Plugin, icons } from 'ckeditor5/src/core.js';\nimport { ButtonView } from 'ckeditor5/src/ui.js';\nimport type ToggleTableCaptionCommand from './toggletablecaptioncommand.js';\n\nimport { getCaptionFromModelSelection } from './utils.js';\n\n/**\n  * The table caption UI plugin. It introduces the `'toggleTableCaption'` UI button.\n  */\nexport default class TableCaptionUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableCaptionUI' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'toggleTableCaption', locale => {\n\t\t\tconst command: ToggleTableCaptionCommand = editor.commands.get( 'toggleTableCaption' )!;\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\ticon: icons.caption,\n\t\t\t\ttooltip: true,\n\t\t\t\tisToggleable: true\n\t\t\t} );\n\n\t\t\tview.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );\n\t\t\tview.bind( 'label' ).to( command, 'value', value => value ? t( 'Toggle caption off' ) : t( 'Toggle caption on' ) );\n\n\t\t\tthis.listenTo( view, 'execute', () => {\n\t\t\t\teditor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );\n\n\t\t\t\t// Scroll to the selection and highlight the caption if the caption showed up.\n\t\t\t\tif ( command.value ) {\n\t\t\t\t\tconst modelCaptionElement = getCaptionFromModelSelection( editor.model.document.selection )!;\n\t\t\t\t\tconst figcaptionElement = editor.editing.mapper.toViewElement( modelCaptionElement );\n\n\t\t\t\t\tif ( !figcaptionElement ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\teditingView.scrollToTheSelection();\n\t\t\t\t\teditingView.change( writer => {\n\t\t\t\t\t\twriter.addClass( 'table__caption_highlighted', figcaptionElement );\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\teditor.editing.view.focus();\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecaption\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport TableCaptionEditing from './tablecaption/tablecaptionediting.js';\nimport TableCaptionUI from './tablecaption/tablecaptionui.js';\n\nimport '../theme/tablecaption.css';\n\n/**\n * The table caption plugin.\n */\nexport default class TableCaption extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableCaption' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableCaptionEditing, TableCaptionUI ] as const;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecolumnresize/tablewidthscommand\n */\n\nimport type { Element } from 'ckeditor5/src/engine.js';\nimport { Command } from 'ckeditor5/src/core.js';\nimport { normalizeColumnWidths } from './utils.js';\n\n/**\n * Command used by the {@link module:table/tablecolumnresize~TableColumnResize Table column resize feature} that\n * updates the width of the whole table as well as its individual columns.\n */\nexport default class TableWidthsCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override refresh(): void {\n\t\t// The command is always enabled as it doesn't care about the actual selection - table can be resized\n\t\t// even if the selection is elsewhere.\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Updated the `tableWidth` attribute of the table and the `columnWidth` attribute of the columns of that table.\n\t */\n\tpublic override execute( options: TableWidthsCommandOptions = {} ): void {\n\t\tconst { model, plugins } = this.editor;\n\t\tlet {\n\t\t\ttable = model.document.selection.getSelectedElement()!,\n\t\t\tcolumnWidths,\n\t\t\ttableWidth\n\t\t} = options;\n\n\t\tif ( columnWidths ) {\n\t\t\t// For backwards compatibility, columnWidths might be an array or a string of comma-separated values.\n\t\t\tcolumnWidths = Array.isArray( columnWidths ) ?\n\t\t\t\tcolumnWidths :\n\t\t\t\tcolumnWidths.split( ',' );\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tif ( tableWidth ) {\n\t\t\t\twriter.setAttribute( 'tableWidth', tableWidth, table );\n\t\t\t} else {\n\t\t\t\twriter.removeAttribute( 'tableWidth', table );\n\t\t\t}\n\n\t\t\tconst tableColumnGroup = plugins\n\t\t\t\t.get( 'TableColumnResizeEditing' )\n\t\t\t\t.getColumnGroupElement( table )!;\n\n\t\t\tif ( !columnWidths && !tableColumnGroup ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !columnWidths ) {\n\t\t\t\treturn writer.remove( tableColumnGroup );\n\t\t\t}\n\n\t\t\tconst widths = normalizeColumnWidths( columnWidths as Array<string> );\n\n\t\t\tif ( !tableColumnGroup ) {\n\t\t\t\tconst colGroupElement = writer.createElement( 'tableColumnGroup' );\n\n\t\t\t\twidths.forEach( columnWidth => writer.appendElement( 'tableColumn', { columnWidth }, colGroupElement ) );\n\t\t\t\twriter.append( colGroupElement, table );\n\t\t\t} else {\n\t\t\t\tArray\n\t\t\t\t\t.from( tableColumnGroup.getChildren() )\n\t\t\t\t\t.forEach( ( column, index ) => writer.setAttribute( 'columnWidth', widths[ index ], column ) );\n\t\t\t}\n\t\t} );\n\t}\n}\n\nexport interface TableWidthsCommandOptions {\n\n\t/**\n\t * New value of the `columnWidths` attribute. Must be array of strings or string with comma-separated values.\n\t * If skipped, the column widths information will be deleted.\n\t */\n\tcolumnWidths?: Array<string> | string;\n\n\t/**\n\t * The new table width. If skipped, the model attribute will be removed.\n\t */\n\ttableWidth?: string;\n\n\t/**\n\t * The table that is having the columns resized.\n\t */\n\ttable?: Element;\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecolumnresize/converters\n */\n\nimport type {\n\tDowncastDispatcher,\n\tDowncastInsertEvent,\n\tElement,\n\tUpcastDispatcher,\n\tUpcastElementEvent,\n\tViewElement\n} from 'ckeditor5/src/engine.js';\nimport type TableUtils from '../tableutils.js';\nimport {\n\tnormalizeColumnWidths,\n\tupdateColumnElements,\n\tgetColumnGroupElement,\n\tgetTableColumnElements,\n\ttranslateColSpanAttribute\n} from './utils.js';\n\n/**\n * Returns a upcast helper that ensures the number of `<tableColumn>` elements corresponds to the actual number of columns in the table,\n * because the input data might have too few or too many <col> elements.\n */\nexport function upcastColgroupElement( tableUtilsPlugin: TableUtils ): ( dispatcher: UpcastDispatcher ) => void {\n\treturn dispatcher => dispatcher.on<UpcastElementEvent>( 'element:colgroup', ( evt, data, conversionApi ) => {\n\t\tconst modelTable = data.modelCursor.findAncestor( 'table' )!;\n\t\tconst tableColumnGroup = getColumnGroupElement( modelTable );\n\n\t\tif ( !tableColumnGroup ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst columnElements = getTableColumnElements( tableColumnGroup );\n\t\tconst columnsCount = tableUtilsPlugin.getColumns( modelTable );\n\t\tlet columnWidths = translateColSpanAttribute( tableColumnGroup, conversionApi.writer );\n\n\t\t// Fill the array with 'auto' values if the number of columns is higher than number of declared values.\n\t\tcolumnWidths = Array.from( { length: columnsCount }, ( _, index ) => columnWidths[ index ] || 'auto' );\n\n\t\tif ( columnWidths.length != columnElements.length || columnWidths.includes( 'auto' ) ) {\n\t\t\tupdateColumnElements( columnElements, tableColumnGroup, normalizeColumnWidths( columnWidths ), conversionApi.writer );\n\t\t}\n\t}, { priority: 'low' } );\n}\n\n/**\n * Returns downcast helper for adding `ck-table-resized` class if there is a `<tableColumnGroup>` element inside the table.\n */\nexport function downcastTableResizedClass(): ( dispatcher: DowncastDispatcher ) => void {\n\treturn dispatcher => dispatcher.on<DowncastInsertEvent>( 'insert:table', ( evt, data, conversionApi ) => {\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst modelTable = data.item as Element;\n\t\tconst viewElement: ViewElement = conversionApi.mapper.toViewElement( modelTable )!;\n\n\t\tconst viewTable = viewElement.is( 'element', 'table' ) ?\n\t\t\tviewElement :\n\t\t\tArray.from( viewElement.getChildren() ).find( viewChild => viewChild.is( 'element', 'table' ) )!;\n\n\t\tconst tableColumnGroup = getColumnGroupElement( modelTable );\n\n\t\tif ( tableColumnGroup ) {\n\t\t\tviewWriter.addClass( 'ck-table-resized', viewTable as ViewElement );\n\t\t} else {\n\t\t\tviewWriter.removeClass( 'ck-table-resized', viewTable as ViewElement );\n\t\t}\n\t}, { priority: 'low' } );\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecolumnresize/tablecolumnresizeediting\n */\n\nimport { throttle, isEqual } from 'lodash-es';\n\nimport {\n\tglobal,\n\tDomEmitterMixin,\n\ttype EventInfo,\n\ttype DomEmitter,\n\ttype ObservableChangeEvent\n} from 'ckeditor5/src/utils.js';\n\nimport { Plugin, type Editor } from 'ckeditor5/src/core.js';\n\nimport type {\n\tDiffer,\n\tDomEventData,\n\tDowncastInsertEvent,\n\tDowncastWriter,\n\tElement,\n\tViewElement,\n\tViewNode\n} from 'ckeditor5/src/engine.js';\n\nimport MouseEventsObserver from '../../src/tablemouse/mouseeventsobserver.js';\nimport TableEditing from '../tableediting.js';\nimport TableUtils from '../tableutils.js';\nimport TableWalker from '../tablewalker.js';\n\nimport TableWidthsCommand from './tablewidthscommand.js';\n\nimport { downcastTableResizedClass, upcastColgroupElement } from './converters.js';\n\nimport {\n\tclamp,\n\tcreateFilledArray,\n\tsumArray,\n\tgetColumnEdgesIndexes,\n\tgetChangedResizedTables,\n\tgetColumnMinWidthAsPercentage,\n\tgetElementWidthInPixels,\n\tgetTableWidthInPixels,\n\tnormalizeColumnWidths,\n\ttoPrecision,\n\tgetDomCellOuterWidth,\n\tupdateColumnElements,\n\tgetColumnGroupElement,\n\tgetTableColumnElements,\n\tgetTableColumnsWidths\n} from './utils.js';\n\nimport { COLUMN_MIN_WIDTH_IN_PIXELS } from './constants.js';\nimport type TableColumnResize from '../tablecolumnresize.js';\n\ntype ResizingData = {\n\tcolumnPosition: number;\n\tflags: {\n\t\tisRightEdge: boolean;\n\t\tisTableCentered: boolean;\n\t\tisLtrContent: boolean;\n\t};\n\telements: {\n\t\tviewResizer: ViewElement;\n\t\tmodelTable: Element;\n\t\tviewFigure: ViewElement;\n\t\tviewColgroup: ViewElement;\n\t\tviewLeftColumn: ViewElement;\n\t\tviewRightColumn?: ViewElement;\n\t};\n\twidths: {\n\t\tviewFigureParentWidth: number;\n\t\tviewFigureWidth: number;\n\t\ttableWidth: number;\n\t\tleftColumnWidth: number;\n\t\trightColumnWidth?: number;\n\t};\n};\n\n/**\n * The table column resize editing plugin.\n */\nexport default class TableColumnResizeEditing extends Plugin {\n\t/**\n\t * A flag indicating if the column resizing is in progress.\n\t */\n\tprivate _isResizingActive: boolean;\n\n\t/**\n\t * A flag indicating if the column resizing is allowed. It is not allowed if the editor is in read-only\n\t * or comments-only mode or the `TableColumnResize` plugin is disabled.\n\t *\n\t * @observable\n\t * @internal\n\t */\n\tpublic declare _isResizingAllowed: boolean;\n\n\t/**\n\t * A temporary storage for the required data needed to correctly calculate the widths of the resized columns. This storage is\n\t * initialized when column resizing begins, and is purged upon completion.\n\t */\n\tprivate _resizingData: ResizingData | null;\n\n\t/**\n\t * DOM emitter.\n\t */\n\tprivate _domEmitter: DomEmitter;\n\n\t/**\n\t * A local reference to the {@link module:table/tableutils~TableUtils} plugin.\n\t */\n\tprivate _tableUtilsPlugin: TableUtils;\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get requires() {\n\t\treturn [ TableEditing, TableUtils ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static get pluginName() {\n\t\treturn 'TableColumnResizeEditing' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor: Editor ) {\n\t\tsuper( editor );\n\n\t\tthis._isResizingActive = false;\n\t\tthis.set( '_isResizingAllowed', true );\n\t\tthis._resizingData = null;\n\t\tthis._domEmitter = new ( DomEmitterMixin() )();\n\t\tthis._tableUtilsPlugin = editor.plugins.get( 'TableUtils' );\n\n\t\tthis.on<ObservableChangeEvent<boolean>>( 'change:_isResizingAllowed', ( evt, name, value ) => {\n\t\t\t// Toggling the `ck-column-resize_disabled` class shows and hides the resizers through CSS.\n\t\t\tconst classAction = value ? 'removeClass' : 'addClass';\n\n\t\t\teditor.editing.view.change( writer => {\n\t\t\t\tfor ( const root of editor.editing.view.document.roots ) {\n\t\t\t\t\twriter[ classAction ]( 'ck-column-resize_disabled', editor.editing.view.document.getRoot( root.rootName )! );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic init(): void {\n\t\tthis._extendSchema();\n\t\tthis._registerPostFixer();\n\t\tthis._registerConverters();\n\t\tthis._registerResizingListeners();\n\t\tthis._registerResizerInserter();\n\n\t\tconst editor = this.editor;\n\t\tconst columnResizePlugin: TableColumnResize = editor.plugins.get( 'TableColumnResize' );\n\t\tconst tableEditing: TableEditing = editor.plugins.get( 'TableEditing' );\n\n\t\ttableEditing.registerAdditionalSlot( {\n\t\t\tfilter: element => element.is( 'element', 'tableColumnGroup' ),\n\t\t\tpositionOffset: 0\n\t\t} );\n\n\t\tconst tableWidthsCommand = new TableWidthsCommand( editor );\n\n\t\t// For backwards compatibility we have two commands that perform exactly the same operation.\n\t\teditor.commands.add( 'resizeTableWidth', tableWidthsCommand );\n\t\teditor.commands.add( 'resizeColumnWidths', tableWidthsCommand );\n\n\t\t// Currently the states of column resize and table resize (which is actually the last column resize) features\n\t\t// are bound together. They can be separated in the future by adding distinct listeners and applying\n\t\t// different CSS classes (e.g. `ck-column-resize_disabled` and `ck-table-resize_disabled`) to the editor root.\n\t\t// See #12148 for the details.\n\t\tthis.bind( '_isResizingAllowed' ).to(\n\t\t\teditor, 'isReadOnly',\n\t\t\tcolumnResizePlugin, 'isEnabled',\n\t\t\ttableWidthsCommand, 'isEnabled',\n\t\t\t( isEditorReadOnly, isPluginEnabled, isTableWidthsCommandCommandEnabled ) =>\n\t\t\t\t!isEditorReadOnly && isPluginEnabled && isTableWidthsCommandCommandEnabled\n\t\t);\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic override destroy(): void {\n\t\tthis._domEmitter.stopListening();\n\t\tsuper.destroy();\n\t}\n\n\t/**\n\t * Returns a 'tableColumnGroup' element from the 'table'.\n\t *\n\t * @param element A 'table' or 'tableColumnGroup' element.\n\t * @returns A 'tableColumnGroup' element.\n\t */\n\tpublic getColumnGroupElement( element: Element ): Element | undefined {\n\t\treturn getColumnGroupElement( element );\n\t}\n\n\t/**\n\t * Returns an array of 'tableColumn' elements.\n\t *\n\t * @param element A 'table' or 'tableColumnGroup' element.\n\t * @returns An array of 'tableColumn' elements.\n\t */\n\tpublic getTableColumnElements( element: Element ): Array<Element> {\n\t\treturn getTableColumnElements( element );\n\t}\n\n\t/**\n\t * Returns an array of table column widths.\n\t *\n\t * @param element A 'table' or 'tableColumnGroup' element.\n\t * @returns An array of table column widths.\n\t */\n\tpublic getTableColumnsWidths( element: Element ): Array<string> {\n\t\treturn getTableColumnsWidths( element );\n\t}\n\n\t/**\n\t * Registers new attributes for a table model element.\n\t */\n\tprivate _extendSchema() {\n\t\tthis.editor.model.schema.extend( 'table', {\n\t\t\tallowAttributes: [ 'tableWidth' ]\n\t\t} );\n\n\t\tthis.editor.model.schema.register( 'tableColumnGroup', {\n\t\t\tallowIn: 'table',\n\t\t\tisLimit: true\n\t\t} );\n\n\t\tthis.editor.model.schema.register( 'tableColumn', {\n\t\t\tallowIn: 'tableColumnGroup',\n\t\t\tallowAttributes: [ 'columnWidth', 'colSpan' ],\n\t\t\tisLimit: true\n\t\t} );\n\t}\n\n\t/**\n\t * Registers table column resize post-fixer.\n\t *\n\t * It checks if the change from the differ concerns a table-related element or attribute. For detected changes it:\n\t *  * Adjusts the `columnWidths` attribute to guarantee that the sum of the widths from all columns is 100%.\n\t *  * Checks if the `columnWidths` attribute gets updated accordingly after columns have been added or removed.\n\t */\n\tprivate _registerPostFixer() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tmodel.document.registerPostFixer( writer => {\n\t\t\tlet changed = false;\n\n\t\t\tfor ( const table of getChangedResizedTables( model ) ) {\n\t\t\t\tconst tableColumnGroup = this.getColumnGroupElement( table )!;\n\t\t\t\tconst columns = this.getTableColumnElements( tableColumnGroup );\n\t\t\t\tconst columnWidths = this.getTableColumnsWidths( tableColumnGroup );\n\n\t\t\t\t// Adjust the `columnWidths` attribute to guarantee that the sum of the widths from all columns is 100%.\n\t\t\t\tlet normalizedWidths = normalizeColumnWidths( columnWidths );\n\n\t\t\t\t// If the number of columns has changed, then we need to adjust the widths of the affected columns.\n\t\t\t\tnormalizedWidths = adjustColumnWidths( normalizedWidths, table, this );\n\n\t\t\t\tif ( isEqual( columnWidths, normalizedWidths ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tupdateColumnElements( columns, tableColumnGroup, normalizedWidths, writer );\n\n\t\t\t\tchanged = true;\n\t\t\t}\n\n\t\t\treturn changed;\n\t\t} );\n\n\t\t/**\n\t\t * Adjusts if necessary the `columnWidths` in case if the number of column has changed.\n\t\t *\n\t\t * @param columnWidths Note: this array **may be modified** by the function.\n\t\t * @param table Table to be checked.\n\t\t */\n\t\tfunction adjustColumnWidths( columnWidths: Array<string>, table: Element, plugin: TableColumnResizeEditing ): Array<string> {\n\t\t\tconst newTableColumnsCount = plugin._tableUtilsPlugin.getColumns( table );\n\t\t\tconst columnsCountDelta = newTableColumnsCount - columnWidths.length;\n\n\t\t\tif ( columnsCountDelta === 0 ) {\n\t\t\t\treturn columnWidths;\n\t\t\t}\n\n\t\t\tconst widths: Array<number> = columnWidths.map( width => Number( width.replace( '%', '' ) ) );\n\n\t\t\t// Collect all cells that are affected by the change.\n\t\t\tconst cellSet = getAffectedCells( plugin.editor.model.document.differ, table ) as Set<Element>;\n\n\t\t\tfor ( const cell of cellSet ) {\n\t\t\t\tconst currentColumnsDelta = newTableColumnsCount - widths.length;\n\n\t\t\t\tif ( currentColumnsDelta === 0 ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// If the column count in the table changed, adjust the widths of the affected columns.\n\t\t\t\tconst hasMoreColumns = currentColumnsDelta > 0;\n\t\t\t\tconst currentColumnIndex = plugin._tableUtilsPlugin.getCellLocation( cell ).column;\n\n\t\t\t\tif ( hasMoreColumns ) {\n\t\t\t\t\tconst columnMinWidthAsPercentage = getColumnMinWidthAsPercentage( table, plugin.editor );\n\t\t\t\t\tconst columnWidthsToInsert = createFilledArray( currentColumnsDelta, columnMinWidthAsPercentage );\n\n\t\t\t\t\twidths.splice( currentColumnIndex, 0, ...columnWidthsToInsert );\n\t\t\t\t} else {\n\t\t\t\t\t// Moves the widths of the removed columns to the preceding one.\n\t\t\t\t\t// Other editors either reduce the width of the whole table or adjust the widths\n\t\t\t\t\t// proportionally, so change of this behavior can be considered in the future.\n\t\t\t\t\tconst removedColumnWidths = widths.splice( currentColumnIndex, Math.abs( currentColumnsDelta ) );\n\n\t\t\t\t\twidths[ currentColumnIndex ] += sumArray( removedColumnWidths );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn widths.map( width => width + '%' );\n\t\t}\n\n\t\t/**\n\t\t * Returns a set of cells that have been changed in a given table.\n\t\t */\n\t\tfunction getAffectedCells( differ: Differ, table: Element ): Set<Element> {\n\t\t\tconst cellSet = new Set<Element>();\n\n\t\t\tfor ( const change of differ.getChanges() ) {\n\t\t\t\tif (\n\t\t\t\t\tchange.type == 'insert' &&\n\t\t\t\t\tchange.position.nodeAfter &&\n\t\t\t\t\t( change.position.nodeAfter as Element ).name == 'tableCell' &&\n\t\t\t\t\tchange.position.nodeAfter.getAncestors().includes( table )\n\t\t\t\t) {\n\t\t\t\t\tcellSet.add( change.position.nodeAfter as Element );\n\t\t\t\t} else if ( change.type == 'remove' ) {\n\t\t\t\t\t// If the first cell was removed, use the node after the change position instead.\n\t\t\t\t\tconst referenceNode = ( change.position.nodeBefore || change.position.nodeAfter ) as Element;\n\n\t\t\t\t\tif ( referenceNode.name == 'tableCell' && referenceNode.getAncestors().includes( table ) ) {\n\t\t\t\t\t\tcellSet.add( referenceNode );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn cellSet;\n\t\t}\n\t}\n\n\t/**\n\t * Registers table column resize converters.\n\t */\n\tprivate _registerConverters() {\n\t\tconst editor = this.editor;\n\t\tconst conversion = editor.conversion;\n\n\t\t// Table width style\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: 'figure',\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\twidth: /[\\s\\S]+/\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tkey: 'tableWidth',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => viewElement.getStyle( 'width' )\n\t\t\t}\n\t\t} );\n\n\t\tconversion.for( 'downcast' ).attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tkey: 'tableWidth'\n\t\t\t},\n\t\t\tview: ( width: string ) => ( {\n\t\t\t\tname: 'figure',\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\twidth\n\t\t\t\t}\n\t\t\t} )\n\t\t} );\n\n\t\tconversion.elementToElement( { model: 'tableColumnGroup', view: 'colgroup' } );\n\t\tconversion.elementToElement( { model: 'tableColumn', view: 'col' } );\n\t\tconversion.for( 'downcast' ).add( downcastTableResizedClass() );\n\t\tconversion.for( 'upcast' ).add( upcastColgroupElement( this._tableUtilsPlugin ) );\n\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: 'col',\n\t\t\t\tstyles: {\n\t\t\t\t\twidth: /.*/\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'columnWidth',\n\t\t\t\tvalue: ( viewElement: ViewElement ) => {\n\t\t\t\t\tconst viewColWidth = viewElement.getStyle( 'width' );\n\n\t\t\t\t\t// 'pt' is the default unit for table column width pasted from MS Office.\n\t\t\t\t\t// See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for more details.\n\t\t\t\t\tif ( !viewColWidth || ( !viewColWidth.endsWith( '%' ) && !viewColWidth.endsWith( 'pt' ) ) ) {\n\t\t\t\t\t\treturn 'auto';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn viewColWidth;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// The `col[span]` attribute is present in tables pasted from MS Excel. We use it to set the temporary `colSpan` model attribute,\n\t\t// which is consumed during the `colgroup` element upcast.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/14521#issuecomment-1662102889 for more details.\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: 'col',\n\t\t\t\tkey: 'span'\n\t\t\t},\n\t\t\tmodel: 'colSpan'\n\t\t} );\n\n\t\tconversion.for( 'downcast' ).attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'tableColumn',\n\t\t\t\tkey: 'columnWidth'\n\t\t\t},\n\t\t\tview: width => ( { key: 'style', value: { width } } )\n\t\t} );\n\t}\n\n\t/**\n\t * Registers listeners to handle resizing process.\n\t */\n\tprivate _registerResizingListeners() {\n\t\tconst editingView = this.editor.editing.view;\n\n\t\teditingView.addObserver( MouseEventsObserver );\n\t\teditingView.document.on( 'mousedown', this._onMouseDownHandler.bind( this ), { priority: 'high' } );\n\n\t\tthis._domEmitter.listenTo( global.window.document, 'mousemove', throttle( this._onMouseMoveHandler.bind( this ), 50 ) );\n\t\tthis._domEmitter.listenTo( global.window.document, 'mouseup', this._onMouseUpHandler.bind( this ) );\n\t}\n\n\t/**\n\t * Handles the `mousedown` event on column resizer element:\n\t *  * calculates the initial column pixel widths,\n\t *  * inserts the `<colgroup>` element if it is not present in the `<table>`,\n\t *  * puts the necessary data in the temporary storage,\n\t *  * applies the attributes to the `<table>` view element.\n\t *\n\t * @param eventInfo An object containing information about the fired event.\n\t * @param domEventData The data related to the DOM event.\n\t */\n\tprivate _onMouseDownHandler( eventInfo: EventInfo, domEventData: DomEventData ) {\n\t\tconst target = domEventData.target;\n\n\t\tif ( !target.hasClass( 'ck-table-column-resizer' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this._isResizingAllowed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst modelTable = editor.editing.mapper.toModelElement( target.findAncestor( 'figure' )! )!;\n\n\t\t// Do not resize if table model is in non-editable place.\n\t\tif ( !editor.model.canEditAt( modelTable ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdomEventData.preventDefault();\n\t\teventInfo.stop();\n\n\t\t// The column widths are calculated upon mousedown to allow lazy applying the `columnWidths` attribute on the table.\n\t\tconst columnWidthsInPx = _calculateDomColumnWidths( modelTable, this._tableUtilsPlugin, editor );\n\t\tconst viewTable = target.findAncestor( 'table' )!;\n\t\tconst editingView = editor.editing.view;\n\n\t\t// Insert colgroup for the table that is resized for the first time.\n\t\tif ( !Array.from( viewTable.getChildren() ).find( viewCol => viewCol.is( 'element', 'colgroup' ) ) ) {\n\t\t\teditingView.change( viewWriter => {\n\t\t\t\t_insertColgroupElement( viewWriter, columnWidthsInPx, viewTable );\n\t\t\t} );\n\t\t}\n\n\t\tthis._isResizingActive = true;\n\t\tthis._resizingData = this._getResizingData( domEventData, columnWidthsInPx );\n\n\t\t// At this point we change only the editor view - we don't want other users to see our changes yet,\n\t\t// so we can't apply them in the model.\n\t\teditingView.change( writer => _applyResizingAttributesToTable( writer, viewTable, this._resizingData! ) );\n\n\t\t/**\n\t\t * Calculates the DOM columns' widths. It is done by taking the width of the widest cell\n\t\t * from each table column (we rely on the  {@link module:table/tablewalker~TableWalker}\n\t\t * to determine which column the cell belongs to).\n\t\t *\n\t\t * @param modelTable A table which columns should be measured.\n\t\t * @param tableUtils The Table Utils plugin instance.\n\t\t * @param editor The editor instance.\n\t\t * @returns Columns' widths expressed in pixels (without unit).\n\t\t */\n\t\tfunction _calculateDomColumnWidths( modelTable: Element, tableUtilsPlugin: TableUtils, editor: Editor ) {\n\t\t\tconst columnWidthsInPx = Array( tableUtilsPlugin.getColumns( modelTable ) );\n\t\t\tconst tableWalker = new TableWalker( modelTable );\n\n\t\t\tfor ( const cellSlot of tableWalker ) {\n\t\t\t\tconst viewCell = editor.editing.mapper.toViewElement( cellSlot.cell )!;\n\t\t\t\tconst domCell = editor.editing.view.domConverter.mapViewToDom( viewCell )!;\n\t\t\t\tconst domCellWidth = getDomCellOuterWidth( domCell );\n\n\t\t\t\tif ( !columnWidthsInPx[ cellSlot.column ] || domCellWidth < columnWidthsInPx[ cellSlot.column ] ) {\n\t\t\t\t\tcolumnWidthsInPx[ cellSlot.column ] = toPrecision( domCellWidth );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn columnWidthsInPx;\n\t\t}\n\n\t\t/**\n\t\t * Creates a `<colgroup>` element with `<col>`s and inserts it into a given view table.\n\t\t *\n\t\t * @param viewWriter A writer instance.\n\t\t * @param columnWidthsInPx Column widths.\n\t\t * @param viewTable A table view element.\n\t\t */\n\t\tfunction _insertColgroupElement( viewWriter: DowncastWriter, columnWidthsInPx: Array<number>, viewTable: ViewElement ) {\n\t\t\tconst colgroup = viewWriter.createContainerElement( 'colgroup' );\n\n\t\t\tfor ( let i = 0; i < columnWidthsInPx.length; i++ ) {\n\t\t\t\tconst viewColElement = viewWriter.createEmptyElement( 'col' );\n\t\t\t\tconst columnWidthInPc = `${ toPrecision( columnWidthsInPx[ i ] / sumArray( columnWidthsInPx ) * 100 ) }%`;\n\n\t\t\t\tviewWriter.setStyle( 'width', columnWidthInPc, viewColElement );\n\t\t\t\tviewWriter.insert( viewWriter.createPositionAt( colgroup, 'end' ), viewColElement );\n\t\t\t}\n\n\t\t\tviewWriter.insert( viewWriter.createPositionAt( viewTable, 0 ), colgroup );\n\t\t}\n\n\t\t/**\n\t\t * Applies the style and classes to the view table as the resizing begun.\n\t\t *\n\t\t * @param viewWriter A writer instance.\n\t\t * @param viewTable A table containing the clicked resizer.\n\t\t * @param resizingData Data related to the resizing.\n\t\t */\n\t\tfunction _applyResizingAttributesToTable( viewWriter: DowncastWriter, viewTable: ViewElement, resizingData: ResizingData ) {\n\t\t\tconst figureInitialPcWidth = resizingData.widths.viewFigureWidth / resizingData.widths.viewFigureParentWidth;\n\n\t\t\tviewWriter.addClass( 'ck-table-resized', viewTable );\n\t\t\tviewWriter.addClass( 'ck-table-column-resizer__active', resizingData.elements.viewResizer );\n\t\t\tviewWriter.setStyle( 'width', `${ toPrecision( figureInitialPcWidth * 100 ) }%`, viewTable.findAncestor( 'figure' )! );\n\t\t}\n\t}\n\n\t/**\n\t * Handles the `mousemove` event.\n\t *  * If resizing process is not in progress, it does nothing.\n\t *  * If resizing is active but not allowed, it stops the resizing process instantly calling the `mousedown` event handler.\n\t *  * Otherwise it dynamically updates the widths of the resized columns.\n\t *\n\t * @param eventInfo An object containing information about the fired event.\n\t * @param mouseEventData The native DOM event.\n\t */\n\tprivate _onMouseMoveHandler( eventInfo: EventInfo, mouseEventData: MouseEvent ) {\n\t\tif ( !this._isResizingActive ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !this._isResizingAllowed ) {\n\t\t\tthis._onMouseUpHandler();\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst {\n\t\t\tcolumnPosition,\n\t\t\tflags: {\n\t\t\t\tisRightEdge,\n\t\t\t\tisTableCentered,\n\t\t\t\tisLtrContent\n\t\t\t},\n\t\t\telements: {\n\t\t\t\tviewFigure,\n\t\t\t\tviewLeftColumn,\n\t\t\t\tviewRightColumn\n\t\t\t},\n\t\t\twidths: {\n\t\t\t\tviewFigureParentWidth,\n\t\t\t\ttableWidth,\n\t\t\t\tleftColumnWidth,\n\t\t\t\trightColumnWidth\n\t\t\t}\n\t\t} = this._resizingData!;\n\n\t\tconst dxLowerBound = -leftColumnWidth + COLUMN_MIN_WIDTH_IN_PIXELS;\n\n\t\tconst dxUpperBound = isRightEdge ?\n\t\t\tviewFigureParentWidth - tableWidth :\n\t\t\trightColumnWidth! - COLUMN_MIN_WIDTH_IN_PIXELS;\n\n\t\t// The multiplier is needed for calculating the proper movement offset:\n\t\t// - it should negate the sign if content language direction is right-to-left,\n\t\t// - it should double the offset if the table edge is resized and table is centered.\n\t\tconst multiplier = ( isLtrContent ? 1 : -1 ) * ( isRightEdge && isTableCentered ? 2 : 1 );\n\n\t\tconst dx = clamp(\n\t\t\t( mouseEventData.clientX - columnPosition ) * multiplier,\n\t\t\tMath.min( dxLowerBound, 0 ),\n\t\t\tMath.max( dxUpperBound, 0 )\n\t\t);\n\n\t\tif ( dx === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.editor.editing.view.change( writer => {\n\t\t\tconst leftColumnWidthAsPercentage = toPrecision( ( leftColumnWidth + dx ) * 100 / tableWidth );\n\n\t\t\twriter.setStyle( 'width', `${ leftColumnWidthAsPercentage }%`, viewLeftColumn );\n\n\t\t\tif ( isRightEdge ) {\n\t\t\t\tconst tableWidthAsPercentage = toPrecision( ( tableWidth + dx ) * 100 / viewFigureParentWidth );\n\n\t\t\t\twriter.setStyle( 'width', `${ tableWidthAsPercentage }%`, viewFigure );\n\t\t\t} else {\n\t\t\t\tconst rightColumnWidthAsPercentage = toPrecision( ( rightColumnWidth! - dx ) * 100 / tableWidth );\n\n\t\t\t\twriter.setStyle( 'width', `${ rightColumnWidthAsPercentage }%`, viewRightColumn! );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Handles the `mouseup` event.\n\t *  * If resizing process is not in progress, it does nothing.\n\t *  * If resizing is active but not allowed, it cancels the resizing process restoring the original widths.\n\t *  * Otherwise it propagates the changes from view to the model by executing the adequate commands.\n\t */\n\tprivate _onMouseUpHandler() {\n\t\tif ( !this._isResizingActive ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst {\n\t\t\tviewResizer,\n\t\t\tmodelTable,\n\t\t\tviewFigure,\n\t\t\tviewColgroup\n\t\t} = this._resizingData!.elements;\n\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\n\t\tconst tableColumnGroup = this.getColumnGroupElement( modelTable );\n\t\tconst viewColumns: Array<ViewElement> = Array\n\t\t\t.from( viewColgroup.getChildren() )\n\t\t\t.filter( ( column: ViewNode ): column is ViewElement => column.is( 'view:element' ) );\n\n\t\tconst columnWidthsAttributeOld = tableColumnGroup ?\n\t\t\tthis.getTableColumnsWidths( tableColumnGroup )! :\n\t\t\tnull;\n\n\t\tconst columnWidthsAttributeNew = viewColumns.map( column => column.getStyle( 'width' ) );\n\n\t\tconst isColumnWidthsAttributeChanged = !isEqual( columnWidthsAttributeOld, columnWidthsAttributeNew );\n\n\t\tconst tableWidthAttributeOld = modelTable.getAttribute( 'tableWidth' ) as string;\n\t\tconst tableWidthAttributeNew = viewFigure.getStyle( 'width' )!;\n\n\t\tconst isTableWidthAttributeChanged = tableWidthAttributeOld !== tableWidthAttributeNew;\n\n\t\tif ( isColumnWidthsAttributeChanged || isTableWidthAttributeChanged ) {\n\t\t\tif ( this._isResizingAllowed ) {\n\t\t\t\teditor.execute( 'resizeTableWidth', {\n\t\t\t\t\ttable: modelTable,\n\t\t\t\t\ttableWidth: `${ toPrecision( tableWidthAttributeNew ) }%`,\n\t\t\t\t\tcolumnWidths: columnWidthsAttributeNew\n\t\t\t\t} );\n\t\t\t} else {\n\t\t\t\t// In read-only mode revert all changes in the editing view. The model is not touched so it does not need to be restored.\n\t\t\t\t// This case can occur if the read-only mode kicks in during the resizing process.\n\t\t\t\teditingView.change( writer => {\n\t\t\t\t\t// If table had resized columns before, restore the previous column widths.\n\t\t\t\t\t// Otherwise clean up the view from the temporary column resizing markup.\n\t\t\t\t\tif ( columnWidthsAttributeOld ) {\n\t\t\t\t\t\tfor ( const viewCol of viewColumns ) {\n\t\t\t\t\t\t\twriter.setStyle( 'width', columnWidthsAttributeOld.shift()!, viewCol );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.remove( viewColgroup );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( isTableWidthAttributeChanged ) {\n\t\t\t\t\t\t// If the whole table was already resized before, restore the previous table width.\n\t\t\t\t\t\t// Otherwise clean up the view from the temporary table resizing markup.\n\t\t\t\t\t\tif ( tableWidthAttributeOld ) {\n\t\t\t\t\t\t\twriter.setStyle( 'width', tableWidthAttributeOld, viewFigure );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twriter.removeStyle( 'width', viewFigure );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// If a table and its columns weren't resized before,\n\t\t\t\t\t// prune the remaining common resizing markup.\n\t\t\t\t\tif ( !columnWidthsAttributeOld && !tableWidthAttributeOld ) {\n\t\t\t\t\t\twriter.removeClass(\n\t\t\t\t\t\t\t'ck-table-resized',\n\t\t\t\t\t\t\t[ ... viewFigure.getChildren() as IterableIterator<ViewElement> ].find( element => element.name === 'table' )!\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\teditingView.change( writer => {\n\t\t\twriter.removeClass( 'ck-table-column-resizer__active', viewResizer );\n\t\t} );\n\n\t\tthis._isResizingActive = false;\n\t\tthis._resizingData = null;\n\t}\n\n\t/**\n\t * Retrieves and returns required data needed for the resizing process.\n\t *\n\t * @param domEventData The data of the `mousedown` event.\n\t * @param columnWidths The current widths of the columns.\n\t * @returns The data needed for the resizing process.\n\t */\n\tprivate _getResizingData( domEventData: DomEventData, columnWidths: Array<number> ): ResizingData {\n\t\tconst editor = this.editor;\n\n\t\tconst columnPosition = ( domEventData.domEvent as Event & { clientX: number } ).clientX;\n\n\t\tconst viewResizer = domEventData.target;\n\t\tconst viewLeftCell = viewResizer.findAncestor( 'td' )! || viewResizer.findAncestor( 'th' )!;\n\t\tconst modelLeftCell = editor.editing.mapper.toModelElement( viewLeftCell )!;\n\t\tconst modelTable = modelLeftCell.findAncestor( 'table' )!;\n\n\t\tconst leftColumnIndex = getColumnEdgesIndexes( modelLeftCell, this._tableUtilsPlugin ).rightEdge;\n\t\tconst lastColumnIndex = this._tableUtilsPlugin.getColumns( modelTable ) - 1;\n\n\t\tconst isRightEdge = leftColumnIndex === lastColumnIndex;\n\t\tconst isTableCentered = !modelTable.hasAttribute( 'tableAlignment' );\n\t\tconst isLtrContent = editor.locale.contentLanguageDirection !== 'rtl';\n\n\t\tconst viewTable = viewLeftCell.findAncestor( 'table' )!;\n\t\tconst viewFigure = viewTable.findAncestor( 'figure' ) as ViewElement;\n\t\tconst viewColgroup = [ ...viewTable.getChildren() as IterableIterator<ViewElement> ]\n\t\t\t.find( viewCol => viewCol.is( 'element', 'colgroup' ) )!;\n\t\tconst viewLeftColumn = viewColgroup.getChild( leftColumnIndex ) as ViewElement;\n\t\tconst viewRightColumn = isRightEdge ? undefined : viewColgroup.getChild( leftColumnIndex + 1 ) as ViewElement;\n\n\t\tconst viewFigureParentWidth = getElementWidthInPixels(\n\t\t\teditor.editing.view.domConverter.mapViewToDom( viewFigure.parent! ) as HTMLElement\n\t\t);\n\t\tconst viewFigureWidth = getElementWidthInPixels( editor.editing.view.domConverter.mapViewToDom( viewFigure )! );\n\t\tconst tableWidth = getTableWidthInPixels( modelTable, editor );\n\t\tconst leftColumnWidth = columnWidths[ leftColumnIndex ];\n\t\tconst rightColumnWidth = isRightEdge ? undefined : columnWidths[ leftColumnIndex + 1 ];\n\n\t\treturn {\n\t\t\tcolumnPosition,\n\t\t\tflags: {\n\t\t\t\tisRightEdge,\n\t\t\t\tisTableCentered,\n\t\t\t\tisLtrContent\n\t\t\t},\n\t\t\telements: {\n\t\t\t\tviewResizer,\n\t\t\t\tmodelTable,\n\t\t\t\tviewFigure,\n\t\t\t\tviewColgroup,\n\t\t\t\tviewLeftColumn,\n\t\t\t\tviewRightColumn\n\t\t\t},\n\t\t\twidths: {\n\t\t\t\tviewFigureParentWidth,\n\t\t\t\tviewFigureWidth,\n\t\t\t\ttableWidth,\n\t\t\t\tleftColumnWidth,\n\t\t\t\trightColumnWidth\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Registers a listener ensuring that each resizable cell have a resizer handle.\n\t */\n\tprivate _registerResizerInserter() {\n\t\tthis.editor.conversion.for( 'editingDowncast' ).add( dispatcher => {\n\t\t\tdispatcher.on<DowncastInsertEvent<Element>>( 'insert:tableCell', ( evt, data, conversionApi ) => {\n\t\t\t\tconst modelElement = data.item;\n\t\t\t\tconst viewElement = conversionApi.mapper.toViewElement( modelElement );\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\n\t\t\t\tviewWriter.insert(\n\t\t\t\t\tviewWriter.createPositionAt( viewElement!, 'end' ),\n\t\t\t\t\tviewWriter.createUIElement( 'div', { class: 'ck-table-column-resizer' } )\n\t\t\t\t);\n\t\t\t}, { priority: 'lowest' } );\n\t\t} );\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecolumnresize\n */\n\nimport { Plugin } from 'ckeditor5/src/core.js';\nimport TableColumnResizeEditing from './tablecolumnresize/tablecolumnresizeediting.js';\nimport TableCellWidthEditing from './tablecellwidth/tablecellwidthediting.js';\n\nimport '../theme/tablecolumnresize.css';\n\n/**\n * The table column resize feature.\n *\n * It provides the possibility to set the width of each column in a table using a resize handler.\n */\nexport default class TableColumnResize extends Plugin {\n\t/**\n\t * @inheritDoc\n \t */\n\tpublic static get requires() {\n\t\treturn [ TableColumnResizeEditing, TableCellWidthEditing ] as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n \t */\n\tpublic static get pluginName() {\n\t\treturn 'TableColumnResize' as const;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tpublic static override get isOfficialPlugin(): true {\n\t\treturn true;\n\t}\n}\n", "/**\n * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\nexport default {\"de\":{\"dictionary\":{\"Words: %0\":\"W\u00F6rter: %0 \",\"Characters: %0\":\"Zeichen: %0 \",\"Widget toolbar\":\"Widget Werkzeugleiste\",\"Insert paragraph before block\":\"Absatz vor Block einf\u00FCgen\",\"Insert paragraph after block\":\"Absatz nach Block einf\u00FCgen\",\"Press Enter to type after or press Shift + Enter to type before the widget\":\"Dr\u00FCcken Sie die Eingabetaste, um nach dem Widget zu tippen oder Shift + Eingabetaste, um vor dem Widget zu tippen.\",\"Keystrokes that can be used when a widget is selected (for example: image, table, etc.)\":\"Tastatureingaben, die verwendet werden k\u00F6nnen, wenn ein Widget ausgew\u00E4hlt wurde (zum Beispiel: Bilder, Tabellen etc.)\",\"Insert a new paragraph directly after a widget\":\"Einen neuen Abschnitt direkt nach einem Widget einf\u00FCgen\",\"Insert a new paragraph directly before a widget\":\"Einen neuen Abschnitt direkt vor einem Widget einf\u00FCgen\",\"Move the caret to allow typing directly before a widget\":\"Verschieben Sie den Textcursor, um die Eingabe direkt nach dem Widget zu erlauben\",\"Move the caret to allow typing directly after a widget\":\"Verschieben Sie den Textcursor, um die direkte Eingabe nach dem Widget zu erlauben\",\"Move focus from an editable area back to the parent widget\":\"Bewegen Sie den Fokus von einem bearbeitbaren Bereich zur\u00FCck zum \u00FCbergeordneten Widget\",\"Upload in progress\":\"Upload l\u00E4uft\",\"Undo\":\"R\u00FCckg\u00E4ngig\",\"Redo\":\"Wiederherstellen\",\"Rich Text Editor\":\"Rich Text Editor\",\"Edit block\":\"Absatz bearbeiten\",\"Click to edit block\":\"Zum Bearbeiten des Blocks klicken\",\"Drag to move\":\"Zum Verschieben ziehen\",\"Next\":\"N\u00E4chste\",\"Previous\":\"vorherige\",\"Editor toolbar\":\"Editor Werkzeugleiste\",\"Dropdown toolbar\":\"Dropdown-Liste Werkzeugleiste\",\"Dropdown menu\":\"Dropdown-Men\u00FC\",\"Black\":\"Schwarz\",\"Dim grey\":\"Dunkelgrau\",\"Grey\":\"Grau\",\"Light grey\":\"Hellgrau\",\"White\":\"Wei\u00DF\",\"Red\":\"Rot\",\"Orange\":\"Orange\",\"Yellow\":\"Gelb\",\"Light green\":\"Hellgr\u00FCn\",\"Green\":\"Gr\u00FCn\",\"Aquamarine\":\"Aquamarinblau\",\"Turquoise\":\"T\u00FCrkis\",\"Light blue\":\"Hellblau\",\"Blue\":\"Blau\",\"Purple\":\"Violett\",\"Editor block content toolbar\":\"Editor Blockinhalt-Toolbar\",\"Editor contextual toolbar\":\"Editor kontextuelle Toolbar\",\"HEX\":\"HEX\",\"No results found\":\"Keine Ergebnisse gefunden\",\"No searchable items\":\"Keine durchsuchbaren Elemente\",\"Editor dialog\":\"Editor-Dialog\",\"Close\":\"Schlie\u00DFen\",\"Help Contents. To close this dialog press ESC.\":\"Hilfe zum Inhalt. Dr\u00FCcken Sie die Esc-Taste, um dieses Dialogfenster zu schlie\u00DFen.\",\"Below, you can find a list of keyboard shortcuts that can be used in the editor.\":\"Unten finden Sie eine Liste mit Tastenkombinationen, die im Editor benutzt werden k\u00F6nnen.\",\"(may require <kbd>Fn</kbd>)\":\"(erfordert gegebenenfalls <kbd>Fn</kbd>)\",\"Accessibility\":\"Bedienungshilfen\",\"Accessibility help\":\"Hilfe zur Eingabe\",\"Press %0 for help.\":\"Dr\u00FCcken Sie %0 f\u00FCr Hilfe.\",\"Move focus in and out of an active dialog window\":\"Fokus auf ein aktives Dialogfenster richten oder aufheben\",\"MENU_BAR_MENU_FILE\":\"Datei\",\"MENU_BAR_MENU_EDIT\":\"Bearbeiten\",\"MENU_BAR_MENU_VIEW\":\"Anzeigen\",\"MENU_BAR_MENU_INSERT\":\"Einf\u00FCgen\",\"MENU_BAR_MENU_FORMAT\":\"Format\",\"MENU_BAR_MENU_TOOLS\":\"Werkzeuge\",\"MENU_BAR_MENU_HELP\":\"Hilfe\",\"MENU_BAR_MENU_TEXT\":\"Text\",\"MENU_BAR_MENU_FONT\":\"Schriftart\",\"Editor menu bar\":\"Men\u00FCleiste des Editors\",\"Please enter a valid color (e.g. \\\"ff0000\\\").\":\"Bitte geben Sie eine g\u00FCltige Farbe ein (z. B. \u201Eff0000\u201C).\",\"Insert table\":\"Tabelle einf\u00FCgen\",\"Header column\":\"Kopfspalte\",\"Insert column left\":\"Spalte links einf\u00FCgen\",\"Insert column right\":\"Spalte rechts einf\u00FCgen\",\"Delete column\":\"Spalte l\u00F6schen\",\"Select column\":\"Spalte ausw\u00E4hlen\",\"Column\":\"Spalte\",\"Header row\":\"Kopfzeile\",\"Insert row below\":\"Zeile unten einf\u00FCgen\",\"Insert row above\":\"Zeile oben einf\u00FCgen\",\"Delete row\":\"Zeile l\u00F6schen\",\"Select row\":\"Zeile ausw\u00E4hlen\",\"Row\":\"Zeile\",\"Merge cell up\":\"Zelle verbinden\",\"Merge cell right\":\"Zelle rechts verbinden\",\"Merge cell down\":\"Zelle unten verbinden\",\"Merge cell left\":\"Zelle links verbinden\",\"Split cell vertically\":\"Zelle vertikal teilen\",\"Split cell horizontally\":\"Zelle horizontal teilen\",\"Merge cells\":\"Zellen verbinden\",\"Table toolbar\":\"Tabelle Werkzeugleiste\",\"Table properties\":\"Tabelleneigenschaften\",\"Cell properties\":\"Zelleneigenschaften\",\"Border\":\"Rahmen\",\"Style\":\"Rahmenart\",\"Width\":\"Breite\",\"Height\":\"H\u00F6he\",\"Color\":\"Farbe\",\"Background\":\"Hintergrund\",\"Padding\":\"Innenabstand\",\"Dimensions\":\"Gr\u00F6\u00DFe\",\"Table cell text alignment\":\"Ausrichtung des Zellentextes\",\"Alignment\":\"Ausrichtung\",\"Horizontal text alignment toolbar\":\"Werkzeugleiste f\u00FCr die horizontale Zellentext-Ausrichtung\",\"Vertical text alignment toolbar\":\"Werkzeugleiste f\u00FCr die vertikale Zellentext-Ausrichtung\",\"Table alignment toolbar\":\"Werkzeugleiste f\u00FCr die Tabellen-Ausrichtung\",\"None\":\"Kein Rahmen\",\"Solid\":\"Durchgezogen\",\"Dotted\":\"Gepunktet\",\"Dashed\":\"Gestrichelt\",\"Double\":\"Doppelt\",\"Groove\":\"Eingeritzt\",\"Ridge\":\"Hervorgehoben\",\"Inset\":\"Eingelassen\",\"Outset\":\"Gepr\u00E4gt\",\"Align cell text to the left\":\"Zellentext linksb\u00FCndig ausrichten\",\"Align cell text to the center\":\"Zellentext zentriert ausrichten\",\"Align cell text to the right\":\"Zellentext rechtsb\u00FCndig ausrichten\",\"Justify cell text\":\"Zellentext als Blocksatz ausrichten\",\"Align cell text to the top\":\"Zellentext oben ausrichten\",\"Align cell text to the middle\":\"Zellentext mittig ausrichten\",\"Align cell text to the bottom\":\"Zellentext unten ausrichten\",\"Align table to the left\":\"Tabelle links ausrichten\",\"Center table\":\"Tabelle zentrieren\",\"Align table to the right\":\"Tabelle rechts ausrichten\",\"The color is invalid. Try \\\"#FF0000\\\" or \\\"rgb(255,0,0)\\\" or \\\"red\\\".\":\"Die Farbe ist ung\u00FCltig. Probieren Sie \u201E#FF0000\u201C oder \u201Ergb(255,0,0)\u201C oder \u201Ered\u201C.\",\"The value is invalid. Try \\\"10px\\\" or \\\"2em\\\" or simply \\\"2\\\".\":\"Der Wert ist ung\u00FCltig. Probieren Sie \u201E10px\u201C oder \u201E2em\u201C oder \u201E2\u201C.\",\"Enter table caption\":\"Tabellen\u00FCberschrift eingeben\",\"Keystrokes that can be used in a table cell\":\"Tastatureingaben, die in einer Tabelle benutz werden k\u00F6nnen.\",\"Move the selection to the next cell\":\"Auswahl in die n\u00E4chste Zelle verschieben\",\"Move the selection to the previous cell\":\"Auswahl in die vorherige Zelle verschieben\",\"Insert a new table row (when in the last cell of a table)\":\"Eine neue Tabellenspalte einf\u00FCgen (wenn in der letzten Tabellenzelle)\",\"Navigate through the table\":\"Tabellennavigation\",\"Table\":\"Tabelle\",\"Styles\":\"Stile\",\"Multiple styles\":\"Mehrere Stile\",\"Block styles\":\"Block-Stile\",\"Text styles\":\"Text-Stile\",\"Special characters\":\"Sonderzeichen\",\"Category\":\"Kategorie\",\"All\":\"Alle\",\"Arrows\":\"Pfeile\",\"Currency\":\"W\u00E4hrung\",\"Latin\":\"Lateinisch\",\"Mathematical\":\"Mathematisch\",\"Text\":\"Text\",\"leftwards simple arrow\":\"einfacher Linkspfeil\",\"rightwards simple arrow\":\"einfacher Rechtspfeil\",\"upwards simple arrow\":\"einfacher Aufw\u00E4rtspfeil\",\"downwards simple arrow\":\"einfacher Abw\u00E4rtspfeil\",\"leftwards double arrow\":\"Doppelpfeil nach links\",\"rightwards double arrow\":\"Doppelpfeil nach rechts\",\"upwards double arrow\":\"Doppelpfeil nach oben\",\"downwards double arrow\":\"Doppelpfeil nach unten\",\"leftwards dashed arrow\":\"Gestrichelter Pfeil nach links\",\"rightwards dashed arrow\":\"Gestrichelter Pfeil nach rechts\",\"upwards dashed arrow\":\"Gestrichelter Pfeil nach oben\",\"downwards dashed arrow\":\"Gestrichelter Pfeil nach unten\",\"leftwards arrow to bar\":\"Pfeil nach links zum Querstrich\",\"rightwards arrow to bar\":\"Pfeil nach rechts zum Querstrich\",\"upwards arrow to bar\":\"Pfeil nach oben zum Querstrich\",\"downwards arrow to bar\":\"Pfeil nach unten zum Querstrich\",\"up down arrow with base\":\"Unterstrichener Pfeil nach oben und unten\",\"back with leftwards arrow above\":\"\u201EBack\u201C dar\u00FCber Pfeil nach links\",\"end with leftwards arrow above\":\"\u201EEnd\u201C dar\u00FCber Pfeil nach links\",\"on with exclamation mark with left right arrow above\":\"\u201EOn\u201C mit Ausrufezeichen dar\u00FCber Pfeil nach links und rechts\",\"soon with rightwards arrow above\":\"\u201ESoon\u201C dar\u00FCber Pfeil nach rechts\",\"top with upwards arrow above\":\"\u201ETop\u201C dar\u00FCber Pfeil nach oben\",\"Dollar sign\":\"Dollar-Zeichen\",\"Euro sign\":\"Euro-Zeichen\",\"Yen sign\":\"Yen-Zeichen\",\"Pound sign\":\"Pfund-Zeichen\",\"Cent sign\":\"Cent-Zeichen\",\"Euro-currency sign\":\"Euro-W\u00E4hrungszeichen\",\"Colon sign\":\"Col\u00F3n-Zeichen\",\"Cruzeiro sign\":\"Cruzeiro-Zeichen\",\"French franc sign\":\"Franz\u00F6sischer Franc-Zeichen\",\"Lira sign\":\"Lira-Zeichen\",\"Currency sign\":\"W\u00E4hrungssymbol\",\"Bitcoin sign\":\"Bitcoin-Zeichen\",\"Mill sign\":\"Mill-Zeichen\",\"Naira sign\":\"Naira-Zeichen\",\"Peseta sign\":\"Peseta-Zeichen\",\"Rupee sign\":\"Rupie-Zeichen\",\"Won sign\":\"Won-Zeichen\",\"New sheqel sign\":\"Schekel-Zeichen\",\"Dong sign\":\"\u0110\u1ED3ng-Zeichen\",\"Kip sign\":\"Kip-Zeichen\",\"Tugrik sign\":\"Tugrik-Zeichen\",\"Drachma sign\":\"Drachme-Zeichen\",\"German penny sign\":\"Pfennig-Zeichen\",\"Peso sign\":\"Philippinischer Peso-Zeichen\",\"Guarani sign\":\"Guaran\u00ED-Zeichen\",\"Austral sign\":\"Austral-Zeichen\",\"Hryvnia sign\":\"Hrywnja-Zeichen\",\"Cedi sign\":\"Cedi-Zeichen\",\"Livre tournois sign\":\"Livre tournois-Zeichen\",\"Spesmilo sign\":\"Spesmilo-Zeichen\",\"Tenge sign\":\"Tenge-Zeichen\",\"Indian rupee sign\":\"Indische Rupie-Zeichen\",\"Turkish lira sign\":\"T\u00FCrkische Lira-Zeichen\",\"Nordic mark sign\":\"Nordische Mark-Zeichen\",\"Manat sign\":\"Manat-Zeichen\",\"Ruble sign\":\"Rubel-Zeichen\",\"Latin capital letter a with macron\":\"Lateinischer Gro\u00DFbuchstabe a mit Makron\",\"Latin small letter a with macron\":\"Lateinischer Kleinbuchstabe a mit Makron\",\"Latin capital letter a with breve\":\"Lateinischer Gro\u00DFbuchstabe a mit Breve\",\"Latin small letter a with breve\":\"Lateinischer Kleinbuchstabe a mit Breve\",\"Latin capital letter a with ogonek\":\"Lateinischer Gro\u00DFbuchstabe a mit Ogonek\",\"Latin small letter a with ogonek\":\"Lateinischer Kleinbuchstabe a mit Ogonek\",\"Latin capital letter c with acute\":\"Lateinischer Gro\u00DFbuchstabe c mit Akut\",\"Latin small letter c with acute\":\"Lateinischer Kleinbuchstabe c mit Akut\",\"Latin capital letter c with circumflex\":\"Lateinischer Gro\u00DFbuchstabe c mit Zirkumflex\",\"Latin small letter c with circumflex\":\"Lateinischer Kleinbuchstabe c mit Zirkumflex\",\"Latin capital letter c with dot above\":\"Lateinischer Gro\u00DFbuchstabe c mit Punkt dar\u00FCber\",\"Latin small letter c with dot above\":\"Lateinischer Kleinbuchstabe c mit Punkt dar\u00FCber\",\"Latin capital letter c with caron\":\"Lateinischer Gro\u00DFbuchstabe c mit Hatschek\",\"Latin small letter c with caron\":\"Lateinischer Kleinbuchstabe c mit Hatschek\",\"Latin capital letter d with caron\":\"Lateinischer Gro\u00DFbuchstabe d mit Hatschek\",\"Latin small letter d with caron\":\"Lateinischer Kleinbuchstabe d mit Hatschek\",\"Latin capital letter d with stroke\":\"Lateinischer Gro\u00DFbuchstabe d mit Querstrich\",\"Latin small letter d with stroke\":\"Lateinischer Kleinbuchstabe d mit Querstrich\",\"Latin capital letter e with macron\":\"Lateinischer Gro\u00DFbuchstabe e mit Makron\",\"Latin small letter e with macron\":\"Lateinischer Kleinbuchstabe e mit Makron\",\"Latin capital letter e with breve\":\"Lateinischer Gro\u00DFbuchstabe e mit Breve\",\"Latin small letter e with breve\":\"Lateinischer Kleinbuchstabe e mit Breve\",\"Latin capital letter e with dot above\":\"Lateinischer Gro\u00DFbuchstabe e mit Punkt dar\u00FCber\",\"Latin small letter e with dot above\":\"Lateinischer Kleinbuchstabe e mit Punkt dar\u00FCber\",\"Latin capital letter e with ogonek\":\"Lateinischer Gro\u00DFbuchstabe e mit Ogonek\",\"Latin small letter e with ogonek\":\"Lateinischer Kleinbuchstabe e mit Ogonek\",\"Latin capital letter e with caron\":\"Lateinischer Gro\u00DFbuchstabe e mit Hatschek\",\"Latin small letter e with caron\":\"Lateinischer Kleinbuchstabe e mit Hatschek\",\"Latin capital letter g with circumflex\":\"Lateinischer Gro\u00DFbuchstabe g mit Zirkumflex\",\"Latin small letter g with circumflex\":\"Lateinischer Kleinbuchstabe g mit Zirkumflex\",\"Latin capital letter g with breve\":\"Lateinischer Gro\u00DFbuchstabe g mit Breve\",\"Latin small letter g with breve\":\"Lateinischer Kleinbuchstabe g mit Breve\",\"Latin capital letter g with dot above\":\"Lateinischer Gro\u00DFbuchstabe g mit Punkt dar\u00FCber\",\"Latin small letter g with dot above\":\"Lateinischer Kleinbuchstabe g mit Punkt dar\u00FCber\",\"Latin capital letter g with cedilla\":\"Lateinischer Gro\u00DFbuchstabe g mit Cedille\",\"Latin small letter g with cedilla\":\"Lateinischer Kleinbuchstabe g mit Cedille\",\"Latin capital letter h with circumflex\":\"Lateinischer Gro\u00DFbuchstabe h mit Zirkumflex\",\"Latin small letter h with circumflex\":\"Lateinischer Kleinbuchstabe h mit Zirkumflex\",\"Latin capital letter h with stroke\":\"Lateinischer Gro\u00DFbuchstabe h mit Querstrich\",\"Latin small letter h with stroke\":\"Lateinischer Kleinbuchstabe h mit Querstrich\",\"Latin capital letter i with tilde\":\"Lateinischer Gro\u00DFbuchstabe i mit Tilde\",\"Latin small letter i with tilde\":\"Lateinischer Kleinbuchstabe i mit Tilde\",\"Latin capital letter i with macron\":\"Lateinischer Gro\u00DFbuchstabe i mit Makron\",\"Latin small letter i with macron\":\"Lateinischer Kleinbuchstabe i mit Makron\",\"Latin capital letter i with breve\":\"Lateinischer Gro\u00DFbuchstabe i mit Breve\",\"Latin small letter i with breve\":\"Lateinischer Kleinbuchstabe i mit Breve\",\"Latin capital letter i with ogonek\":\"Lateinischer Gro\u00DFbuchstabe i mit Ogonek\",\"Latin small letter i with ogonek\":\"Lateinischer Kleinbuchstabe i mit Ogonek\",\"Latin capital letter i with dot above\":\"Lateinischer Gro\u00DFbuchstabe i mit Punkt dar\u00FCber\",\"Latin small letter dotless i\":\"Lateinischer Kleinbuchstabe i ohne Punkt\",\"Latin capital ligature ij\":\"Gro\u00DFe lateinische Ligatur ij\",\"Latin small ligature ij\":\"Kleine lateinische Ligatur ij\",\"Latin capital letter j with circumflex\":\"Lateinischer Gro\u00DFbuchstabe j mit Zirkumflex\",\"Latin small letter j with circumflex\":\"Lateinischer Kleinbuchstabe j mit Zirkumflex\",\"Latin capital letter k with cedilla\":\"Lateinischer Gro\u00DFbuchstabe k mit Cedille\",\"Latin small letter k with cedilla\":\"Lateinischer Kleinbuchstabe k mit Cedille\",\"Latin small letter kra\":\"Lateinischer Kleinbuchstabe Kra\",\"Latin capital letter l with acute\":\"Lateinischer Gro\u00DFbuchstabe l mit Akut\",\"Latin small letter l with acute\":\"Lateinischer Kleinbuchstabe l mit Akut\",\"Latin capital letter l with cedilla\":\"Lateinischer Gro\u00DFbuchstabe l mit Cedille\",\"Latin small letter l with cedilla\":\"Lateinischer Kleinbuchstabe l mit Cedille\",\"Latin capital letter l with caron\":\"Lateinischer Gro\u00DFbuchstabe l mit Hatschek\",\"Latin small letter l with caron\":\"Lateinischer Kleinbuchstabe l mit Hatschek\",\"Latin capital letter l with middle dot\":\"Lateinischer Gro\u00DFbuchstabe l mit Mittelpunkt\",\"Latin small letter l with middle dot\":\"Lateinischer Kleinbuchstabe l mit Mittelpunkt\",\"Latin capital letter l with stroke\":\"Lateinischer Gro\u00DFbuchstabe l mit Querstrich\",\"Latin small letter l with stroke\":\"Lateinischer Kleinbuchstabe l mit Querstrich\",\"Latin capital letter n with acute\":\"Lateinischer Gro\u00DFbuchstabe n mit Akut\",\"Latin small letter n with acute\":\"Lateinischer Kleinbuchstabe n mit Akut\",\"Latin capital letter n with cedilla\":\"Lateinischer Gro\u00DFbuchstabe n mit Cedille\",\"Latin small letter n with cedilla\":\"Lateinischer Kleinbuchstabe n mit Cedille\",\"Latin capital letter n with caron\":\"Lateinischer Gro\u00DFbuchstabe n mit Hatschek\",\"Latin small letter n with caron\":\"Lateinischer Kleinbuchstabe n mit Hatschek\",\"Latin small letter n preceded by apostrophe\":\"Lateinischer Kleinbuchstabe n mit vorangestelltem Apostroph\",\"Latin capital letter eng\":\"Lateinischer Gro\u00DFbuchstabe Eng\",\"Latin small letter eng\":\"Lateinischer Kleinbuchstabe Eng\",\"Latin capital letter o with macron\":\"Lateinischer Gro\u00DFbuchstabe o mit Makron\",\"Latin small letter o with macron\":\"Lateinischer Kleinbuchstabe o mit Makron\",\"Latin capital letter o with breve\":\"Lateinischer Gro\u00DFbuchstabe o mit Breve\",\"Latin small letter o with breve\":\"Lateinischer Kleinbuchstabe o mit Breve\",\"Latin capital letter o with double acute\":\"Lateinischer Gro\u00DFbuchstabe o mit doppeltem Akut\",\"Latin small letter o with double acute\":\"Lateinischer Kleinbuchstabe o mit doppeltem Akut\",\"Latin capital ligature oe\":\"Gro\u00DFe lateinische Ligatur oe\",\"Latin small ligature oe\":\"Kleine lateinische Ligatur oe\",\"Latin capital letter r with acute\":\"Lateinischer Gro\u00DFbuchstabe r mit Akut\",\"Latin small letter r with acute\":\"Lateinischer Kleinbuchstabe r mit Akut\",\"Latin capital letter r with cedilla\":\"Lateinischer Gro\u00DFbuchstabe r mit Cedille\",\"Latin small letter r with cedilla\":\"Lateinischer Kleinbuchstabe r mit Cedille\",\"Latin capital letter r with caron\":\"Lateinischer Gro\u00DFbuchstabe r mit Hatschek\",\"Latin small letter r with caron\":\"Lateinischer Kleinbuchstabe r mit Hatschek\",\"Latin capital letter s with acute\":\"Lateinischer Gro\u00DFbuchstabe s mit Akut\",\"Latin small letter s with acute\":\"Lateinischer Kleinbuchstabe s mit Akut\",\"Latin capital letter s with circumflex\":\"Lateinischer Gro\u00DFbuchstabe s mit Zirkumflex\",\"Latin small letter s with circumflex\":\"Lateinischer Kleinbuchstabe s mit Zirkumflex\",\"Latin capital letter s with cedilla\":\"Lateinischer Gro\u00DFbuchstabe s mit Cedille\",\"Latin small letter s with cedilla\":\"Lateinischer Kleinbuchstabe s mit Cedille\",\"Latin capital letter s with caron\":\"Lateinischer Gro\u00DFbuchstabe s mit Hatschek\",\"Latin small letter s with caron\":\"Lateinischer Kleinbuchstabe s mit Hatschek\",\"Latin capital letter t with cedilla\":\"Lateinischer Gro\u00DFbuchstabe t mit Cedille\",\"Latin small letter t with cedilla\":\"Lateinischer Kleinbuchstabe t mit Cedille\",\"Latin capital letter t with caron\":\"Lateinischer Gro\u00DFbuchstabe t mit Hatschek\",\"Latin small letter t with caron\":\"Lateinischer Kleinbuchstabe t mit Hatschek\",\"Latin capital letter t with stroke\":\"Lateinischer Gro\u00DFbuchstabe t mit Querstrich\",\"Latin small letter t with stroke\":\"Lateinischer Kleinbuchstabe t mit Querstrich\",\"Latin capital letter u with tilde\":\"Lateinischer Gro\u00DFbuchstabe u mit Tilde\",\"Latin small letter u with tilde\":\"Lateinischer Kleinbuchstabe u mit Tilde\",\"Latin capital letter u with macron\":\"Lateinischer Gro\u00DFbuchstabe u mit Makron\",\"Latin small letter u with macron\":\"Lateinischer Kleinbuchstabe u mit Makron\",\"Latin capital letter u with breve\":\"Lateinischer Gro\u00DFbuchstabe u mit Breve\",\"Latin small letter u with breve\":\"Lateinischer Kleinbuchstabe u mit Breve\",\"Latin capital letter u with ring above\":\"Lateinischer Gro\u00DFbuchstabe u mit Krou\u017Eek dar\u00FCber\",\"Latin small letter u with ring above\":\"Lateinischer Kleinbuchstabe u mit Krou\u017Eek dar\u00FCber\",\"Latin capital letter u with double acute\":\"Lateinischer Gro\u00DFbuchstabe u mit doppeltem Akut\",\"Latin small letter u with double acute\":\"Lateinischer Kleinbuchstabe u mit doppeltem Akut\",\"Latin capital letter u with ogonek\":\"Lateinischer Gro\u00DFbuchstabe u mit Ogonek\",\"Latin small letter u with ogonek\":\"Lateinischer Kleinbuchstabe u mit Ogonek\",\"Latin capital letter w with circumflex\":\"Lateinischer Gro\u00DFbuchstabe w mit Zirkumflex\",\"Latin small letter w with circumflex\":\"Lateinischer Kleinbuchstabe w mit Zirkumflex\",\"Latin capital letter y with circumflex\":\"Lateinischer Gro\u00DFbuchstabe y mit Zirkumflex\",\"Latin small letter y with circumflex\":\"Lateinischer Kleinbuchstabe y mit Zirkumflex\",\"Latin capital letter y with diaeresis\":\"Lateinischer Gro\u00DFbuchstabe y mit Trema\",\"Latin capital letter z with acute\":\"Lateinischer Gro\u00DFbuchstabe z mit Akut\",\"Latin small letter z with acute\":\"Lateinischer Kleinbuchstabe z mit Akut\",\"Latin capital letter z with dot above\":\"Lateinischer Gro\u00DFbuchstabe z mit Punkt dar\u00FCber\",\"Latin small letter z with dot above\":\"Lateinischer Kleinbuchstabe z mit Punkt dar\u00FCber\",\"Latin capital letter z with caron\":\"Lateinischer Gro\u00DFbuchstabe z mit Hatschek\",\"Latin small letter z with caron\":\"Lateinischer Kleinbuchstabe z mit Hatschek\",\"Latin small letter long s\":\"Lateinischer Kleinbuchstabe langes s\",\"Less-than sign\":\"Kleiner-als-Zeichen\",\"Greater-than sign\":\"Gr\u00F6\u00DFer-als-Zeichen\",\"Less-than or equal to\":\"Kleiner als oder gleich\",\"Greater-than or equal to\":\"Gr\u00F6\u00DFer als oder gleich\",\"En dash\":\"Halbgeviertstrich\",\"Em dash\":\"Geviertstrich\",\"Macron\":\"Makron\",\"Overline\":\"\u00DCberstrich\",\"Degree sign\":\"Grad-Zeichen\",\"Minus sign\":\"Minus-Zeichen\",\"Plus-minus sign\":\"Plus-Minus-Zeichen\",\"Division sign\":\"Geteilt-Zeichen\",\"Fraction slash\":\"Schr\u00E4gstrich\",\"Multiplication sign\":\"Mal-Zeichen\",\"Latin small letter f with hook\":\"Lateinischer Kleinbuchstabe f mit Haken\",\"Integral\":\"Integral-Zeichen\",\"N-ary summation\":\"Summen-Zeichen\",\"Infinity\":\"Unendlich-Zeichen\",\"Square root\":\"Wurzel-Zeichen\",\"Tilde operator\":\"Tilde-Operator\",\"Approximately equal to\":\"Ungef\u00E4hr gleich\",\"Almost equal to\":\"Gerundet\",\"Not equal to\":\"Ungleich\",\"Identical to\":\"Identisch mit\",\"Element of\":\"Element von\",\"Not an element of\":\"Kein Element von\",\"Contains as member\":\"Enth\u00E4lt als Element\",\"N-ary product\":\"Produkt-Zeichen\",\"Logical and\":\"Logisches und\",\"Logical or\":\"Logisches oder\",\"Not sign\":\"Negations-Zeichen\",\"Intersection\":\"Schnitt\",\"Union\":\"Vereinigung\",\"Partial differential\":\"Partielle Ableitung\",\"For all\":\"Allquantor\",\"There exists\":\"Existenzquantor\",\"Empty set\":\"Leere Menge\",\"Nabla\":\"Nabla\",\"Asterisk operator\":\"Hodge-Stern-Operator\",\"Proportional to\":\"Proportional zu\",\"Angle\":\"Winkel-Zeichen\",\"Vulgar fraction one quarter\":\"Gemeiner Bruch ein Viertel\",\"Vulgar fraction one half\":\"Gemeiner Bruch ein Halb\",\"Vulgar fraction three quarters\":\"Gemeiner Bruch drei Viertel\",\"Single left-pointing angle quotation mark\":\"Einfache Guillemets nach links\",\"Single right-pointing angle quotation mark\":\"Einfache Guillemets nach rechts\",\"Left-pointing double angle quotation mark\":\"Doppelte Guillemets nach links\",\"Right-pointing double angle quotation mark\":\"Doppelte Guillemets nach rechts\",\"Left single quotation mark\":\"Einfache Anf\u00FChrungszeichen links\",\"Right single quotation mark\":\"Einfache Anf\u00FChrungszeichen rechts\",\"Left double quotation mark\":\"Doppelte Anf\u00FChrungszeichen links\",\"Right double quotation mark\":\"Doppelte Anf\u00FChrungszeichen rechts\",\"Single low-9 quotation mark\":\"Einfache Anf\u00FChrungszeichen links unten\",\"Double low-9 quotation mark\":\"Doppelte Anf\u00FChrungszeichen links unten\",\"Inverted exclamation mark\":\"Umgekehrtes Ausrufezeichen\",\"Inverted question mark\":\"Umgekehrtes Fragezeichen\",\"Two dot leader\":\"Doppel-Punktlinie\",\"Horizontal ellipsis\":\"Auslassungspunkte\",\"Double dagger\":\"Zweibalkenkreuz\",\"Per mille sign\":\"Promille-Zeichen\",\"Per ten thousand sign\":\"Pro-Zehntausend-Zeichen\",\"Double exclamation mark\":\"Doppeltes Ausrufezeichen\",\"Question exclamation mark\":\"Frage-Ruf-Zeichen\",\"Exclamation question mark\":\"Ruf-Frage-Zeichen\",\"Double question mark\":\"Doppeltes Fragezeichen\",\"Copyright sign\":\"Copyright-Zeichen\",\"Registered sign\":\"Registered-Trade-Mark-Zeichen\",\"Trade mark sign\":\"Unregistered-Trade-Mark-Zeichen\",\"Section sign\":\"Paragraphen-Zeichen\",\"Paragraph sign\":\"Absatz-Zeichen\",\"Reversed paragraph sign\":\"Umgedrehtes Absatz-Zeichen\",\"Source\":\"Quellcode\",\"Show source\":\"Quelle anzeigen\",\"Show blocks\":\"Bl\u00F6cke anzeigen\",\"Select all\":\"Alles ausw\u00E4hlen\",\"Disable editing\":\"Bearbeitung deaktivieren\",\"Enable editing\":\"Bearbeitung zulassen\",\"Previous editable region\":\"Vorheriger bearbeitbarer Bereich\",\"Next editable region\":\"N\u00E4chster bearbeitbarer Bereich\",\"Navigate editable regions\":\"Durch bearbeitbare Bereiche navigieren\",\"Remove Format\":\"Formatierung entfernen\",\"Page break\":\"Seitenumbruch\",\"media widget\":\"Medien-Widget\",\"Media URL\":\"Medien-URL\",\"Paste the media URL in the input.\":\"Medien-URL in das Eingabefeld einf\u00FCgen.\",\"Tip: Paste the URL into the content to embed faster.\":\"Tipp: Zum schnelleren Einbetten k\u00F6nnen Sie die Medien-URL in den Inhalt einf\u00FCgen.\",\"The URL must not be empty.\":\"Die URL darf nicht leer sein.\",\"This media URL is not supported.\":\"Diese Medien-URL wird nicht unterst\u00FCtzt.\",\"Insert media\":\"Medium einf\u00FCgen\",\"Media\":\"Medien\",\"Media toolbar\":\"Medien Werkzeugleiste\",\"Open media in new tab\":\"Medien in neuem Tab \u00F6ffnen\",\"Numbered List\":\"Nummerierte Liste\",\"Bulleted List\":\"Aufz\u00E4hlungsliste\",\"To-do List\":\"Aufgabenliste\",\"Bulleted list styles toolbar\":\"Darstellung der ungeordneten Liste\",\"Numbered list styles toolbar\":\"Darstellung der geordneten Liste\",\"Toggle the disc list style\":\"Gef\u00FCllten Kreis einstellen\",\"Toggle the circle list style\":\"Leeren Kreis einstellen\",\"Toggle the square list style\":\"Quadrat einstellen\",\"Toggle the decimal list style\":\"Dezimalzahlen einstellen\",\"Toggle the decimal with leading zero list style\":\"Dezimalzahlen mit vorangestellten Nullen einstellen\",\"Toggle the lower\u2013roman list style\":\"Kleingeschriebene r\u00F6mische Zahlen einstellen\",\"Toggle the upper\u2013roman list style\":\"Gro\u00DFgeschriebene r\u00F6mische Zahlen einstellen\",\"Toggle the lower\u2013latin list style\":\"Kleingeschriebene lateinische Buchstaben einstellen\",\"Toggle the upper\u2013latin list style\":\"Gro\u00DFgeschriebene lateinische Buchstaben einstellen\",\"Disc\":\"Gef\u00FCllter Kreis\",\"Circle\":\"Leerer Kreis\",\"Square\":\"Quadrat\",\"Decimal\":\"Dezimalzahlen\",\"Decimal with leading zero\":\"Dezimalzahlen mit vorangestellten Nullen\",\"Lower\u2013roman\":\"Kleingeschriebene r\u00F6mische Zahlen\",\"Upper-roman\":\"Gro\u00DFgeschriebene r\u00F6mische Zahlen\",\"Lower-latin\":\"Kleingeschriebene lateinische Buchstaben\",\"Upper-latin\":\"Gro\u00DFgeschriebene lateinische Buchstaben\",\"List properties\":\"Listeneigenschaften\",\"Start at\":\"Beginnen mit\",\"Invalid start index value.\":\"Ung\u00FCltiger Anfangsindexwert.\",\"Start index must be greater than 0.\":\"Der Startwert muss gr\u00F6\u00DFer als 0 sein.\",\"Reversed order\":\"Umgekehrte Reihenfolge\",\"Keystrokes that can be used in a list\":\"Tastatureingaben, die in einer Liste verwendet werden k\u00F6nnen.\",\"Increase list item indent\":\"Listeneinzug vergr\u00F6\u00DFern\",\"Decrease list item indent\":\"Listeneinzug verkleinern\",\"Entering a to-do list\":\"Eingabe einer Aufgabenliste\",\"Leaving a to-do list\":\"Verlassen einer Aufgabenliste\",\"Unlink\":\"Link entfernen\",\"Link\":\"Link\",\"Link URL\":\"Linkadresse\",\"Link URL must not be empty.\":\"Die Link-URL darf nicht leer sein.\",\"Link image\":\"Bild verlinken\",\"Edit link\":\"Link bearbeiten\",\"Open link in new tab\":\"Link im neuen Tab \u00F6ffnen\",\"This link has no URL\":\"Dieser Link hat keine Adresse\",\"Open in a new tab\":\"In neuem Tab \u00F6ffnen\",\"Downloadable\":\"Herunterladbar\",\"Create link\":\"Link erstellen\",\"Move out of a link\":\"Linkauswahl aufheben\",\"Language\":\"Sprache\",\"Choose language\":\"Sprache ausw\u00E4hlen\",\"Remove language\":\"Sprache entfernen\",\"Increase indent\":\"Einzug vergr\u00F6\u00DFern\",\"Decrease indent\":\"Einzug verkleinern\",\"image widget\":\"Bild-Steuerelement\",\"Wrap text\":\"Text umflie\u00DFt Bild\",\"Break text\":\"Bild teilt Text\",\"In line\":\"Text in Zeile\",\"Side image\":\"Seitenbild\",\"Full size image\":\"Bild in voller Gr\u00F6\u00DFe\",\"Left aligned image\":\"Linksb\u00FCndiges Bild\",\"Centered image\":\"Zentriertes Bild\",\"Right aligned image\":\"Rechtsb\u00FCndiges Bild\",\"Change image text alternative\":\"Alternativtext \u00E4ndern\",\"Text alternative\":\"Alternativtext\",\"Enter image caption\":\"Bildunterschrift eingeben\",\"Insert image\":\"Bild einf\u00FCgen\",\"Replace image\":\"Bild ersetzen\",\"Upload from computer\":\"Vom Computer hochladen\",\"Replace from computer\":\"Vom Computer ersetzen\",\"Upload image from computer\":\"Bild vom Computer hochladen\",\"Image from computer\":\"Bild vom Computer\",\"From computer\":\"Vom Computer\",\"Replace image from computer\":\"Bild vom Computer ersetzen\",\"Upload failed\":\"Hochladen fehlgeschlagen\",\"You have no image upload permissions.\":\"Sie haben keine Berechtigung zum Hochladen von Bildern.\",\"Image toolbar\":\"Bild Werkzeugleiste\",\"Resize image\":\"Bildgr\u00F6\u00DFe \u00E4ndern\",\"Resize image to %0\":\"Bildgr\u00F6\u00DFe \u00E4ndern in %0\",\"Resize image to the original size\":\"Bild in Originalgr\u00F6\u00DFe \u00E4ndern\",\"Resize image (in %0)\":\"Bildgr\u00F6\u00DFe \u00E4ndern (in %0)\",\"Original\":\"Original\",\"Custom image size\":\"Benutzerdefinierte Bildgr\u00F6\u00DFe\",\"Custom\":\"Benutzerdefiniert\",\"Image resize list\":\"Bildgr\u00F6\u00DFen-Liste\",\"Insert image via URL\":\"Bild von URL einf\u00FCgen\",\"Insert via URL\":\"Per URL einf\u00FCgen\",\"Image via URL\":\"Bild per URL\",\"Via URL\":\"Per URL\",\"Update image URL\":\"Bild-URL aktualisieren\",\"Caption for the image\":\"Bildunterschrift\",\"Caption for image: %0\":\"Bildunterschrift: %0\",\"The value must not be empty.\":\"Der Wert darf nicht leer sein.\",\"The value should be a plain number.\":\"Der Wert sollte eine einfache Zahl sein.\",\"Uploading image\":\"Bild hochladen\",\"Image upload complete\":\"Bild erfolgreich hochgeladen\",\"Error during image upload\":\"Fehler beim Hochladen des Bildes\",\"Image\":\"Bild\",\"HTML object\":\"HTML-Objekt\",\"Insert HTML\":\"HTML einf\u00FCgen\",\"HTML snippet\":\"HTML-Snippet\",\"Paste raw HTML here...\":\"Rohes HTML hier einf\u00FCgen \u2026\",\"Edit source\":\"Quelle bearbeiten\",\"Save changes\":\"\u00C4nderungen speichern\",\"No preview available\":\"Keine Vorschau verf\u00FCgbar\",\"Empty snippet content\":\"Leerer Snippet-Inhalt\",\"Horizontal line\":\"Horizontale Linie\",\"Yellow marker\":\"Gelber Marker\",\"Green marker\":\"Gr\u00FCner Marker\",\"Pink marker\":\"Pinker Marker\",\"Blue marker\":\"Blauer Marker\",\"Red pen\":\"Rote Schriftfarbe\",\"Green pen\":\"Gr\u00FCne Schriftfarbe\",\"Remove highlight\":\"Texthervorhebung entfernen\",\"Highlight\":\"Texthervorhebung\",\"Text highlight toolbar\":\"Text hervorheben Werkzeugleiste\",\"Heading\":\"\u00DCberschrift\",\"Choose heading\":\"\u00DCberschrift ausw\u00E4hlen\",\"Heading 1\":\"\u00DCberschrift 1\",\"Heading 2\":\"\u00DCberschrift 2\",\"Heading 3\":\"\u00DCberschrift 3\",\"Heading 4\":\"\u00DCberschrift 4\",\"Heading 5\":\"\u00DCberschrift 5\",\"Heading 6\":\"\u00DCberschrift 6\",\"Type your title\":\"Titel eingeben\",\"Type or paste your content here.\":\"Hier Inhalt einf\u00FCgen.\",\"Font Size\":\"Schriftgr\u00F6\u00DFe\",\"Tiny\":\"Sehr klein\",\"Small\":\"Klein\",\"Big\":\"Gro\u00DF\",\"Huge\":\"Sehr gro\u00DF\",\"Font Family\":\"Schriftart\",\"Default\":\"Standard\",\"Font Color\":\"Schriftfarbe\",\"Font Background Color\":\"Hintergrundfarbe\",\"Document colors\":\"Dokumentfarben\",\"Find and replace\":\"Suchen und ersetzen\",\"Find in text\u2026\":\"In Text suchen\u2026\",\"Find\":\"Suchen\",\"Previous result\":\"Vorheriges Ergebnis\",\"Next result\":\"N\u00E4chstes Ergebnis\",\"Replace\":\"Ersetzen\",\"Replace all\":\"Alle ersetzen\",\"Match case\":\"Gro\u00DF-/Kleinschreibung beachten\",\"Whole words only\":\"Nur ganze W\u00F6rter\",\"Replace with\u2026\":\"Ersetzen durch\u2026\",\"Text to find must not be empty.\":\"Der Suchtext darf nicht leer sein.\",\"Tip: Find some text first in order to replace it.\":\"Tipp: Zuerst nach Text suchen um diesen zu ersetzen.\",\"Advanced options\":\"Erweiterte Optionen\",\"Find in the document\":\"Dokument durchsuchen\",\"Insert a soft break (a <code>&lt;br&gt;</code> element)\":\"Einen weichen Zeilenumbruch einf\u00FCgen (ein <code>&lt;br&gt;</code>-Element)\",\"Insert a hard break (a new paragraph)\":\"Zeilenumbruch einf\u00FCgen (einen neuen Abschnitt)\",\"Cancel\":\"Abbrechen\",\"Clear\":\"L\u00F6schen\",\"Remove color\":\"Farbe entfernen\",\"Restore default\":\"Standard wiederherstellen\",\"Save\":\"Speichern\",\"Show more items\":\"Mehr anzeigen\",\"%0 of %1\":\"%0 von %1\",\"Cannot upload file:\":\"Die Datei kann nicht hochgeladen werden:\",\"Rich Text Editor. Editing area: %0\":\"Rich Text Editor. Bearbeitungsbereich: %0\",\"Insert with file manager\":\"Mit Dateimanager einf\u00FCgen\",\"Replace with file manager\":\"Mittels Dateimanager ersetzen\",\"Insert image with file manager\":\"Bild mit dem Dateimanager einf\u00FCgen\",\"Replace image with file manager\":\"Bild mittels Dateimanager ersetzen\",\"File\":\"Datei\",\"With file manager\":\"Mit dem Dateimanager\",\"Toggle caption off\":\"Tabellen\u00FCberschrift deaktivieren\",\"Toggle caption on\":\"Tabellen\u00FCberschrift aktivieren\",\"Content editing keystrokes\":\"Tastatureingaben zur Inhaltsverarbeitung\",\"These keyboard shortcuts allow for quick access to content editing features.\":\"Diese Tastenkombinationen erm\u00F6glichen einen schnellen Zugang zu den Inhaltsverarbeitungsfunktionen.\",\"User interface and content navigation keystrokes\":\"Benutzeroberfl\u00E4che und Inhaltsnavigationstasten\",\"Use the following keystrokes for more efficient navigation in the CKEditor 5 user interface.\":\"Verwenden Sie die folgenden Tastatureingaben f\u00FCr eine effizientere Navigation auf der CKEditor-5-Benutzeroberfl\u00E4che.\",\"Close contextual balloons, dropdowns, and dialogs\":\"Kontextsprechblasen, Dropdown-Men\u00FC und Dialoge schlie\u00DFen\",\"Open the accessibility help dialog\":\"Den Dialog zur Eingabehilfe \u00F6ffnen\",\"Move focus between form fields (inputs, buttons, etc.)\":\"Fokus zwischen Formularfeldern verschieben (Eingaben, Tastenfelder etc.)\",\"Move focus to the menu bar, navigate between menu bars\":\"Fokus auf die Men\u00FCleiste richten, zwischen Men\u00FCleisten navigieren\",\"Move focus to the toolbar, navigate between toolbars\":\"Fokus auf die Symbolleiste verschieben, zwischen den Symbolleisten navigieren\",\"Navigate through the toolbar or menu bar\":\"Durch die Werkzeugleiste oder Men\u00FCleiste navigieren\",\"Execute the currently focused button. Executing buttons that interact with the editor content moves the focus back to the content.\":\"Ausf\u00FChren der aktuell fokussierten Schaltfl\u00E4che. Das Ausf\u00FChren von Schaltfl\u00E4chen, die mit dem Inhalt des Editors interagieren, richtet den Fokus zur\u00FCck auf den Inhalt.\",\"Accept\":\"Akzeptieren\",\"Paragraph\":\"Absatz\",\"Color picker\":\"Farbw\u00E4hler\",\"Insert code block\":\"Code-Block einf\u00FCgen\",\"Plain text\":\"Nur Text\",\"Leaving %0 code snippet\":\"%0 Code-Ausschnitt verlassen\",\"Entering %0 code snippet\":\"%0 Code-Ausschnitt eingeben\",\"Entering code snippet\":\"Code-Ausschnit eingeben\",\"Leaving code snippet\":\"Code-Ausschnit verlassen\",\"Code block\":\"Codeblock\",\"Copy selected content\":\"Markierten Inhalt kopieren\",\"Paste content\":\"Inhalt einf\u00FCgen\",\"Paste content as plain text\":\"Inhalt als Klartext einf\u00FCgen\",\"Insert image or file\":\"Bild oder Datei einf\u00FCgen\",\"Could not obtain resized image URL.\":\"Die URL des angepassten Bildes konnte nicht abgerufen werden.\",\"Selecting resized image failed\":\"Das angepasste Bild konnte nicht ausgew\u00E4hlt werden.\",\"Could not insert image at the current position.\":\"Das Bild konnte an der aktuellen Position nicht eingef\u00FCgt werden.\",\"Inserting image failed\":\"Einf\u00FCgen des Bildes fehlgeschlagen\",\"Open file manager\":\"Dateimanager \u00F6ffnen\",\"Cannot determine a category for the uploaded file.\":\"Die Kategorie f\u00FCr die hochgeladene Datei konnte nicht bestimmt werden.\",\"Cannot access default workspace.\":\"Zugriff auf Standardarbeitsbereich nicht m\u00F6glich.\",\"You have no image editing permissions.\":\"Sie haben keine Berechtigung zum Bearbeiten von Bildern.\",\"Edit image\":\"Bild bearbeiten\",\"Processing the edited image.\":\"Das bearbeitete Bild wird verarbeitet.\",\"Server failed to process the image.\":\"Der Server konnte das Bild nicht verarbeiten.\",\"Failed to determine category of edited image.\":\"Es konnte f\u00FCr das bearbeitete Bild keine Kategorie ermittelt werden.\",\"Block quote\":\"Blockzitat\",\"Bold\":\"Fett\",\"Italic\":\"Kursiv\",\"Underline\":\"Unterstrichen\",\"Code\":\"Code\",\"Strikethrough\":\"Durchgestrichen\",\"Subscript\":\"Tiefgestellt\",\"Superscript\":\"Hochgestellt\",\"Italic text\":\"Kursivschrift\",\"Move out of an inline code style\":\"Inline Code Style verlassen\",\"Bold text\":\"Fettschrift\",\"Underline text\":\"Text hervorheben\",\"Strikethrough text\":\"Durchgestrichener Text\",\"Saving changes\":\"\u00C4nderungen werden gespeichert\",\"Revert autoformatting action\":\"Automatischen Formatierungsvorgang r\u00FCckg\u00E4ngig machen\",\"Align left\":\"Linksb\u00FCndig\",\"Align right\":\"Rechtsb\u00FCndig\",\"Align center\":\"Zentriert\",\"Justify\":\"Blocksatz\",\"Text alignment\":\"Textausrichtung\",\"Text alignment toolbar\":\"Text-Ausrichtung Toolbar\"},getPluralForm(n){return (n != 1);}}}", "// Because importing the editor multiple times causes errors ... ffs\n\nimport {\n  ClassicEditor,\n  BalloonToolbar,\n  BlockToolbar,\n  AutoLink,\n  BlockQuote,\n  Bold,\n  Essentials,\n  Paragraph,\n  ParagraphButtonUI,\n  Heading,\n  HeadingButtonsUI,\n  Image,\n  ImageCaption,\n  ImageStyle,\n  ImageToolbar,\n  ImageUpload,\n  ImageResize,\n  Indent,\n  Italic,\n  Link,\n  List,\n  RemoveFormat,\n  MediaEmbed,\n  MediaEmbedToolbar,\n  PasteFromOffice,\n  SimpleUploadAdapter,\n  Table,\n  TableCellProperties,\n  TableColumnResize,\n  TableToolbar,\n} from 'ckeditor5';\n\nimport coreTranslations from 'ckeditor5/translations/de.js';\n\nwindow.$CKEditor = {\n  ClassicEditor,\n  BalloonToolbar,\n  BlockToolbar,\n  AutoLink,\n  BlockQuote,\n  Bold,\n  Essentials,\n  Paragraph,\n  ParagraphButtonUI,\n  Heading,\n  HeadingButtonsUI,\n  Image,\n  ImageCaption,\n  ImageStyle,\n  ImageToolbar,\n  ImageUpload,\n  ImageResize,\n  Indent,\n  Italic,\n  Link,\n  List,\n  RemoveFormat,\n  MediaEmbed,\n  MediaEmbedToolbar,\n  PasteFromOffice,\n  SimpleUploadAdapter,\n  Table,\n  TableCellProperties,\n  TableColumnResize,\n  TableToolbar,\n  coreTranslations,\n};\n", "/*\nStimulus 3.2.1\nCopyright \u00A9 2023 Basecamp, LLC\n */\nclass EventListener {\n    constructor(eventTarget, eventName, eventOptions) {\n        this.eventTarget = eventTarget;\n        this.eventName = eventName;\n        this.eventOptions = eventOptions;\n        this.unorderedBindings = new Set();\n    }\n    connect() {\n        this.eventTarget.addEventListener(this.eventName, this, this.eventOptions);\n    }\n    disconnect() {\n        this.eventTarget.removeEventListener(this.eventName, this, this.eventOptions);\n    }\n    bindingConnected(binding) {\n        this.unorderedBindings.add(binding);\n    }\n    bindingDisconnected(binding) {\n        this.unorderedBindings.delete(binding);\n    }\n    handleEvent(event) {\n        const extendedEvent = extendEvent(event);\n        for (const binding of this.bindings) {\n            if (extendedEvent.immediatePropagationStopped) {\n                break;\n            }\n            else {\n                binding.handleEvent(extendedEvent);\n            }\n        }\n    }\n    hasBindings() {\n        return this.unorderedBindings.size > 0;\n    }\n    get bindings() {\n        return Array.from(this.unorderedBindings).sort((left, right) => {\n            const leftIndex = left.index, rightIndex = right.index;\n            return leftIndex < rightIndex ? -1 : leftIndex > rightIndex ? 1 : 0;\n        });\n    }\n}\nfunction extendEvent(event) {\n    if (\"immediatePropagationStopped\" in event) {\n        return event;\n    }\n    else {\n        const { stopImmediatePropagation } = event;\n        return Object.assign(event, {\n            immediatePropagationStopped: false,\n            stopImmediatePropagation() {\n                this.immediatePropagationStopped = true;\n                stopImmediatePropagation.call(this);\n            },\n        });\n    }\n}\n\nclass Dispatcher {\n    constructor(application) {\n        this.application = application;\n        this.eventListenerMaps = new Map();\n        this.started = false;\n    }\n    start() {\n        if (!this.started) {\n            this.started = true;\n            this.eventListeners.forEach((eventListener) => eventListener.connect());\n        }\n    }\n    stop() {\n        if (this.started) {\n            this.started = false;\n            this.eventListeners.forEach((eventListener) => eventListener.disconnect());\n        }\n    }\n    get eventListeners() {\n        return Array.from(this.eventListenerMaps.values()).reduce((listeners, map) => listeners.concat(Array.from(map.values())), []);\n    }\n    bindingConnected(binding) {\n        this.fetchEventListenerForBinding(binding).bindingConnected(binding);\n    }\n    bindingDisconnected(binding, clearEventListeners = false) {\n        this.fetchEventListenerForBinding(binding).bindingDisconnected(binding);\n        if (clearEventListeners)\n            this.clearEventListenersForBinding(binding);\n    }\n    handleError(error, message, detail = {}) {\n        this.application.handleError(error, `Error ${message}`, detail);\n    }\n    clearEventListenersForBinding(binding) {\n        const eventListener = this.fetchEventListenerForBinding(binding);\n        if (!eventListener.hasBindings()) {\n            eventListener.disconnect();\n            this.removeMappedEventListenerFor(binding);\n        }\n    }\n    removeMappedEventListenerFor(binding) {\n        const { eventTarget, eventName, eventOptions } = binding;\n        const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);\n        const cacheKey = this.cacheKey(eventName, eventOptions);\n        eventListenerMap.delete(cacheKey);\n        if (eventListenerMap.size == 0)\n            this.eventListenerMaps.delete(eventTarget);\n    }\n    fetchEventListenerForBinding(binding) {\n        const { eventTarget, eventName, eventOptions } = binding;\n        return this.fetchEventListener(eventTarget, eventName, eventOptions);\n    }\n    fetchEventListener(eventTarget, eventName, eventOptions) {\n        const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);\n        const cacheKey = this.cacheKey(eventName, eventOptions);\n        let eventListener = eventListenerMap.get(cacheKey);\n        if (!eventListener) {\n            eventListener = this.createEventListener(eventTarget, eventName, eventOptions);\n            eventListenerMap.set(cacheKey, eventListener);\n        }\n        return eventListener;\n    }\n    createEventListener(eventTarget, eventName, eventOptions) {\n        const eventListener = new EventListener(eventTarget, eventName, eventOptions);\n        if (this.started) {\n            eventListener.connect();\n        }\n        return eventListener;\n    }\n    fetchEventListenerMapForEventTarget(eventTarget) {\n        let eventListenerMap = this.eventListenerMaps.get(eventTarget);\n        if (!eventListenerMap) {\n            eventListenerMap = new Map();\n            this.eventListenerMaps.set(eventTarget, eventListenerMap);\n        }\n        return eventListenerMap;\n    }\n    cacheKey(eventName, eventOptions) {\n        const parts = [eventName];\n        Object.keys(eventOptions)\n            .sort()\n            .forEach((key) => {\n            parts.push(`${eventOptions[key] ? \"\" : \"!\"}${key}`);\n        });\n        return parts.join(\":\");\n    }\n}\n\nconst defaultActionDescriptorFilters = {\n    stop({ event, value }) {\n        if (value)\n            event.stopPropagation();\n        return true;\n    },\n    prevent({ event, value }) {\n        if (value)\n            event.preventDefault();\n        return true;\n    },\n    self({ event, value, element }) {\n        if (value) {\n            return element === event.target;\n        }\n        else {\n            return true;\n        }\n    },\n};\nconst descriptorPattern = /^(?:(?:([^.]+?)\\+)?(.+?)(?:\\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;\nfunction parseActionDescriptorString(descriptorString) {\n    const source = descriptorString.trim();\n    const matches = source.match(descriptorPattern) || [];\n    let eventName = matches[2];\n    let keyFilter = matches[3];\n    if (keyFilter && ![\"keydown\", \"keyup\", \"keypress\"].includes(eventName)) {\n        eventName += `.${keyFilter}`;\n        keyFilter = \"\";\n    }\n    return {\n        eventTarget: parseEventTarget(matches[4]),\n        eventName,\n        eventOptions: matches[7] ? parseEventOptions(matches[7]) : {},\n        identifier: matches[5],\n        methodName: matches[6],\n        keyFilter: matches[1] || keyFilter,\n    };\n}\nfunction parseEventTarget(eventTargetName) {\n    if (eventTargetName == \"window\") {\n        return window;\n    }\n    else if (eventTargetName == \"document\") {\n        return document;\n    }\n}\nfunction parseEventOptions(eventOptions) {\n    return eventOptions\n        .split(\":\")\n        .reduce((options, token) => Object.assign(options, { [token.replace(/^!/, \"\")]: !/^!/.test(token) }), {});\n}\nfunction stringifyEventTarget(eventTarget) {\n    if (eventTarget == window) {\n        return \"window\";\n    }\n    else if (eventTarget == document) {\n        return \"document\";\n    }\n}\n\nfunction camelize(value) {\n    return value.replace(/(?:[_-])([a-z0-9])/g, (_, char) => char.toUpperCase());\n}\nfunction namespaceCamelize(value) {\n    return camelize(value.replace(/--/g, \"-\").replace(/__/g, \"_\"));\n}\nfunction capitalize(value) {\n    return value.charAt(0).toUpperCase() + value.slice(1);\n}\nfunction dasherize(value) {\n    return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`);\n}\nfunction tokenize(value) {\n    return value.match(/[^\\s]+/g) || [];\n}\n\nfunction isSomething(object) {\n    return object !== null && object !== undefined;\n}\nfunction hasProperty(object, property) {\n    return Object.prototype.hasOwnProperty.call(object, property);\n}\n\nconst allModifiers = [\"meta\", \"ctrl\", \"alt\", \"shift\"];\nclass Action {\n    constructor(element, index, descriptor, schema) {\n        this.element = element;\n        this.index = index;\n        this.eventTarget = descriptor.eventTarget || element;\n        this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error(\"missing event name\");\n        this.eventOptions = descriptor.eventOptions || {};\n        this.identifier = descriptor.identifier || error(\"missing identifier\");\n        this.methodName = descriptor.methodName || error(\"missing method name\");\n        this.keyFilter = descriptor.keyFilter || \"\";\n        this.schema = schema;\n    }\n    static forToken(token, schema) {\n        return new this(token.element, token.index, parseActionDescriptorString(token.content), schema);\n    }\n    toString() {\n        const eventFilter = this.keyFilter ? `.${this.keyFilter}` : \"\";\n        const eventTarget = this.eventTargetName ? `@${this.eventTargetName}` : \"\";\n        return `${this.eventName}${eventFilter}${eventTarget}->${this.identifier}#${this.methodName}`;\n    }\n    shouldIgnoreKeyboardEvent(event) {\n        if (!this.keyFilter) {\n            return false;\n        }\n        const filters = this.keyFilter.split(\"+\");\n        if (this.keyFilterDissatisfied(event, filters)) {\n            return true;\n        }\n        const standardFilter = filters.filter((key) => !allModifiers.includes(key))[0];\n        if (!standardFilter) {\n            return false;\n        }\n        if (!hasProperty(this.keyMappings, standardFilter)) {\n            error(`contains unknown key filter: ${this.keyFilter}`);\n        }\n        return this.keyMappings[standardFilter].toLowerCase() !== event.key.toLowerCase();\n    }\n    shouldIgnoreMouseEvent(event) {\n        if (!this.keyFilter) {\n            return false;\n        }\n        const filters = [this.keyFilter];\n        if (this.keyFilterDissatisfied(event, filters)) {\n            return true;\n        }\n        return false;\n    }\n    get params() {\n        const params = {};\n        const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`, \"i\");\n        for (const { name, value } of Array.from(this.element.attributes)) {\n            const match = name.match(pattern);\n            const key = match && match[1];\n            if (key) {\n                params[camelize(key)] = typecast(value);\n            }\n        }\n        return params;\n    }\n    get eventTargetName() {\n        return stringifyEventTarget(this.eventTarget);\n    }\n    get keyMappings() {\n        return this.schema.keyMappings;\n    }\n    keyFilterDissatisfied(event, filters) {\n        const [meta, ctrl, alt, shift] = allModifiers.map((modifier) => filters.includes(modifier));\n        return event.metaKey !== meta || event.ctrlKey !== ctrl || event.altKey !== alt || event.shiftKey !== shift;\n    }\n}\nconst defaultEventNames = {\n    a: () => \"click\",\n    button: () => \"click\",\n    form: () => \"submit\",\n    details: () => \"toggle\",\n    input: (e) => (e.getAttribute(\"type\") == \"submit\" ? \"click\" : \"input\"),\n    select: () => \"change\",\n    textarea: () => \"input\",\n};\nfunction getDefaultEventNameForElement(element) {\n    const tagName = element.tagName.toLowerCase();\n    if (tagName in defaultEventNames) {\n        return defaultEventNames[tagName](element);\n    }\n}\nfunction error(message) {\n    throw new Error(message);\n}\nfunction typecast(value) {\n    try {\n        return JSON.parse(value);\n    }\n    catch (o_O) {\n        return value;\n    }\n}\n\nclass Binding {\n    constructor(context, action) {\n        this.context = context;\n        this.action = action;\n    }\n    get index() {\n        return this.action.index;\n    }\n    get eventTarget() {\n        return this.action.eventTarget;\n    }\n    get eventOptions() {\n        return this.action.eventOptions;\n    }\n    get identifier() {\n        return this.context.identifier;\n    }\n    handleEvent(event) {\n        const actionEvent = this.prepareActionEvent(event);\n        if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {\n            this.invokeWithEvent(actionEvent);\n        }\n    }\n    get eventName() {\n        return this.action.eventName;\n    }\n    get method() {\n        const method = this.controller[this.methodName];\n        if (typeof method == \"function\") {\n            return method;\n        }\n        throw new Error(`Action \"${this.action}\" references undefined method \"${this.methodName}\"`);\n    }\n    applyEventModifiers(event) {\n        const { element } = this.action;\n        const { actionDescriptorFilters } = this.context.application;\n        const { controller } = this.context;\n        let passes = true;\n        for (const [name, value] of Object.entries(this.eventOptions)) {\n            if (name in actionDescriptorFilters) {\n                const filter = actionDescriptorFilters[name];\n                passes = passes && filter({ name, value, event, element, controller });\n            }\n            else {\n                continue;\n            }\n        }\n        return passes;\n    }\n    prepareActionEvent(event) {\n        return Object.assign(event, { params: this.action.params });\n    }\n    invokeWithEvent(event) {\n        const { target, currentTarget } = event;\n        try {\n            this.method.call(this.controller, event);\n            this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName });\n        }\n        catch (error) {\n            const { identifier, controller, element, index } = this;\n            const detail = { identifier, controller, element, index, event };\n            this.context.handleError(error, `invoking action \"${this.action}\"`, detail);\n        }\n    }\n    willBeInvokedByEvent(event) {\n        const eventTarget = event.target;\n        if (event instanceof KeyboardEvent && this.action.shouldIgnoreKeyboardEvent(event)) {\n            return false;\n        }\n        if (event instanceof MouseEvent && this.action.shouldIgnoreMouseEvent(event)) {\n            return false;\n        }\n        if (this.element === eventTarget) {\n            return true;\n        }\n        else if (eventTarget instanceof Element && this.element.contains(eventTarget)) {\n            return this.scope.containsElement(eventTarget);\n        }\n        else {\n            return this.scope.containsElement(this.action.element);\n        }\n    }\n    get controller() {\n        return this.context.controller;\n    }\n    get methodName() {\n        return this.action.methodName;\n    }\n    get element() {\n        return this.scope.element;\n    }\n    get scope() {\n        return this.context.scope;\n    }\n}\n\nclass ElementObserver {\n    constructor(element, delegate) {\n        this.mutationObserverInit = { attributes: true, childList: true, subtree: true };\n        this.element = element;\n        this.started = false;\n        this.delegate = delegate;\n        this.elements = new Set();\n        this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));\n    }\n    start() {\n        if (!this.started) {\n            this.started = true;\n            this.mutationObserver.observe(this.element, this.mutationObserverInit);\n            this.refresh();\n        }\n    }\n    pause(callback) {\n        if (this.started) {\n            this.mutationObserver.disconnect();\n            this.started = false;\n        }\n        callback();\n        if (!this.started) {\n            this.mutationObserver.observe(this.element, this.mutationObserverInit);\n            this.started = true;\n        }\n    }\n    stop() {\n        if (this.started) {\n            this.mutationObserver.takeRecords();\n            this.mutationObserver.disconnect();\n            this.started = false;\n        }\n    }\n    refresh() {\n        if (this.started) {\n            const matches = new Set(this.matchElementsInTree());\n            for (const element of Array.from(this.elements)) {\n                if (!matches.has(element)) {\n                    this.removeElement(element);\n                }\n            }\n            for (const element of Array.from(matches)) {\n                this.addElement(element);\n            }\n        }\n    }\n    processMutations(mutations) {\n        if (this.started) {\n            for (const mutation of mutations) {\n                this.processMutation(mutation);\n            }\n        }\n    }\n    processMutation(mutation) {\n        if (mutation.type == \"attributes\") {\n            this.processAttributeChange(mutation.target, mutation.attributeName);\n        }\n        else if (mutation.type == \"childList\") {\n            this.processRemovedNodes(mutation.removedNodes);\n            this.processAddedNodes(mutation.addedNodes);\n        }\n    }\n    processAttributeChange(element, attributeName) {\n        if (this.elements.has(element)) {\n            if (this.delegate.elementAttributeChanged && this.matchElement(element)) {\n                this.delegate.elementAttributeChanged(element, attributeName);\n            }\n            else {\n                this.removeElement(element);\n            }\n        }\n        else if (this.matchElement(element)) {\n            this.addElement(element);\n        }\n    }\n    processRemovedNodes(nodes) {\n        for (const node of Array.from(nodes)) {\n            const element = this.elementFromNode(node);\n            if (element) {\n                this.processTree(element, this.removeElement);\n            }\n        }\n    }\n    processAddedNodes(nodes) {\n        for (const node of Array.from(nodes)) {\n            const element = this.elementFromNode(node);\n            if (element && this.elementIsActive(element)) {\n                this.processTree(element, this.addElement);\n            }\n        }\n    }\n    matchElement(element) {\n        return this.delegate.matchElement(element);\n    }\n    matchElementsInTree(tree = this.element) {\n        return this.delegate.matchElementsInTree(tree);\n    }\n    processTree(tree, processor) {\n        for (const element of this.matchElementsInTree(tree)) {\n            processor.call(this, element);\n        }\n    }\n    elementFromNode(node) {\n        if (node.nodeType == Node.ELEMENT_NODE) {\n            return node;\n        }\n    }\n    elementIsActive(element) {\n        if (element.isConnected != this.element.isConnected) {\n            return false;\n        }\n        else {\n            return this.element.contains(element);\n        }\n    }\n    addElement(element) {\n        if (!this.elements.has(element)) {\n            if (this.elementIsActive(element)) {\n                this.elements.add(element);\n                if (this.delegate.elementMatched) {\n                    this.delegate.elementMatched(element);\n                }\n            }\n        }\n    }\n    removeElement(element) {\n        if (this.elements.has(element)) {\n            this.elements.delete(element);\n            if (this.delegate.elementUnmatched) {\n                this.delegate.elementUnmatched(element);\n            }\n        }\n    }\n}\n\nclass AttributeObserver {\n    constructor(element, attributeName, delegate) {\n        this.attributeName = attributeName;\n        this.delegate = delegate;\n        this.elementObserver = new ElementObserver(element, this);\n    }\n    get element() {\n        return this.elementObserver.element;\n    }\n    get selector() {\n        return `[${this.attributeName}]`;\n    }\n    start() {\n        this.elementObserver.start();\n    }\n    pause(callback) {\n        this.elementObserver.pause(callback);\n    }\n    stop() {\n        this.elementObserver.stop();\n    }\n    refresh() {\n        this.elementObserver.refresh();\n    }\n    get started() {\n        return this.elementObserver.started;\n    }\n    matchElement(element) {\n        return element.hasAttribute(this.attributeName);\n    }\n    matchElementsInTree(tree) {\n        const match = this.matchElement(tree) ? [tree] : [];\n        const matches = Array.from(tree.querySelectorAll(this.selector));\n        return match.concat(matches);\n    }\n    elementMatched(element) {\n        if (this.delegate.elementMatchedAttribute) {\n            this.delegate.elementMatchedAttribute(element, this.attributeName);\n        }\n    }\n    elementUnmatched(element) {\n        if (this.delegate.elementUnmatchedAttribute) {\n            this.delegate.elementUnmatchedAttribute(element, this.attributeName);\n        }\n    }\n    elementAttributeChanged(element, attributeName) {\n        if (this.delegate.elementAttributeValueChanged && this.attributeName == attributeName) {\n            this.delegate.elementAttributeValueChanged(element, attributeName);\n        }\n    }\n}\n\nfunction add(map, key, value) {\n    fetch(map, key).add(value);\n}\nfunction del(map, key, value) {\n    fetch(map, key).delete(value);\n    prune(map, key);\n}\nfunction fetch(map, key) {\n    let values = map.get(key);\n    if (!values) {\n        values = new Set();\n        map.set(key, values);\n    }\n    return values;\n}\nfunction prune(map, key) {\n    const values = map.get(key);\n    if (values != null && values.size == 0) {\n        map.delete(key);\n    }\n}\n\nclass Multimap {\n    constructor() {\n        this.valuesByKey = new Map();\n    }\n    get keys() {\n        return Array.from(this.valuesByKey.keys());\n    }\n    get values() {\n        const sets = Array.from(this.valuesByKey.values());\n        return sets.reduce((values, set) => values.concat(Array.from(set)), []);\n    }\n    get size() {\n        const sets = Array.from(this.valuesByKey.values());\n        return sets.reduce((size, set) => size + set.size, 0);\n    }\n    add(key, value) {\n        add(this.valuesByKey, key, value);\n    }\n    delete(key, value) {\n        del(this.valuesByKey, key, value);\n    }\n    has(key, value) {\n        const values = this.valuesByKey.get(key);\n        return values != null && values.has(value);\n    }\n    hasKey(key) {\n        return this.valuesByKey.has(key);\n    }\n    hasValue(value) {\n        const sets = Array.from(this.valuesByKey.values());\n        return sets.some((set) => set.has(value));\n    }\n    getValuesForKey(key) {\n        const values = this.valuesByKey.get(key);\n        return values ? Array.from(values) : [];\n    }\n    getKeysForValue(value) {\n        return Array.from(this.valuesByKey)\n            .filter(([_key, values]) => values.has(value))\n            .map(([key, _values]) => key);\n    }\n}\n\nclass IndexedMultimap extends Multimap {\n    constructor() {\n        super();\n        this.keysByValue = new Map();\n    }\n    get values() {\n        return Array.from(this.keysByValue.keys());\n    }\n    add(key, value) {\n        super.add(key, value);\n        add(this.keysByValue, value, key);\n    }\n    delete(key, value) {\n        super.delete(key, value);\n        del(this.keysByValue, value, key);\n    }\n    hasValue(value) {\n        return this.keysByValue.has(value);\n    }\n    getKeysForValue(value) {\n        const set = this.keysByValue.get(value);\n        return set ? Array.from(set) : [];\n    }\n}\n\nclass SelectorObserver {\n    constructor(element, selector, delegate, details) {\n        this._selector = selector;\n        this.details = details;\n        this.elementObserver = new ElementObserver(element, this);\n        this.delegate = delegate;\n        this.matchesByElement = new Multimap();\n    }\n    get started() {\n        return this.elementObserver.started;\n    }\n    get selector() {\n        return this._selector;\n    }\n    set selector(selector) {\n        this._selector = selector;\n        this.refresh();\n    }\n    start() {\n        this.elementObserver.start();\n    }\n    pause(callback) {\n        this.elementObserver.pause(callback);\n    }\n    stop() {\n        this.elementObserver.stop();\n    }\n    refresh() {\n        this.elementObserver.refresh();\n    }\n    get element() {\n        return this.elementObserver.element;\n    }\n    matchElement(element) {\n        const { selector } = this;\n        if (selector) {\n            const matches = element.matches(selector);\n            if (this.delegate.selectorMatchElement) {\n                return matches && this.delegate.selectorMatchElement(element, this.details);\n            }\n            return matches;\n        }\n        else {\n            return false;\n        }\n    }\n    matchElementsInTree(tree) {\n        const { selector } = this;\n        if (selector) {\n            const match = this.matchElement(tree) ? [tree] : [];\n            const matches = Array.from(tree.querySelectorAll(selector)).filter((match) => this.matchElement(match));\n            return match.concat(matches);\n        }\n        else {\n            return [];\n        }\n    }\n    elementMatched(element) {\n        const { selector } = this;\n        if (selector) {\n            this.selectorMatched(element, selector);\n        }\n    }\n    elementUnmatched(element) {\n        const selectors = this.matchesByElement.getKeysForValue(element);\n        for (const selector of selectors) {\n            this.selectorUnmatched(element, selector);\n        }\n    }\n    elementAttributeChanged(element, _attributeName) {\n        const { selector } = this;\n        if (selector) {\n            const matches = this.matchElement(element);\n            const matchedBefore = this.matchesByElement.has(selector, element);\n            if (matches && !matchedBefore) {\n                this.selectorMatched(element, selector);\n            }\n            else if (!matches && matchedBefore) {\n                this.selectorUnmatched(element, selector);\n            }\n        }\n    }\n    selectorMatched(element, selector) {\n        this.delegate.selectorMatched(element, selector, this.details);\n        this.matchesByElement.add(selector, element);\n    }\n    selectorUnmatched(element, selector) {\n        this.delegate.selectorUnmatched(element, selector, this.details);\n        this.matchesByElement.delete(selector, element);\n    }\n}\n\nclass StringMapObserver {\n    constructor(element, delegate) {\n        this.element = element;\n        this.delegate = delegate;\n        this.started = false;\n        this.stringMap = new Map();\n        this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));\n    }\n    start() {\n        if (!this.started) {\n            this.started = true;\n            this.mutationObserver.observe(this.element, { attributes: true, attributeOldValue: true });\n            this.refresh();\n        }\n    }\n    stop() {\n        if (this.started) {\n            this.mutationObserver.takeRecords();\n            this.mutationObserver.disconnect();\n            this.started = false;\n        }\n    }\n    refresh() {\n        if (this.started) {\n            for (const attributeName of this.knownAttributeNames) {\n                this.refreshAttribute(attributeName, null);\n            }\n        }\n    }\n    processMutations(mutations) {\n        if (this.started) {\n            for (const mutation of mutations) {\n                this.processMutation(mutation);\n            }\n        }\n    }\n    processMutation(mutation) {\n        const attributeName = mutation.attributeName;\n        if (attributeName) {\n            this.refreshAttribute(attributeName, mutation.oldValue);\n        }\n    }\n    refreshAttribute(attributeName, oldValue) {\n        const key = this.delegate.getStringMapKeyForAttribute(attributeName);\n        if (key != null) {\n            if (!this.stringMap.has(attributeName)) {\n                this.stringMapKeyAdded(key, attributeName);\n            }\n            const value = this.element.getAttribute(attributeName);\n            if (this.stringMap.get(attributeName) != value) {\n                this.stringMapValueChanged(value, key, oldValue);\n            }\n            if (value == null) {\n                const oldValue = this.stringMap.get(attributeName);\n                this.stringMap.delete(attributeName);\n                if (oldValue)\n                    this.stringMapKeyRemoved(key, attributeName, oldValue);\n            }\n            else {\n                this.stringMap.set(attributeName, value);\n            }\n        }\n    }\n    stringMapKeyAdded(key, attributeName) {\n        if (this.delegate.stringMapKeyAdded) {\n            this.delegate.stringMapKeyAdded(key, attributeName);\n        }\n    }\n    stringMapValueChanged(value, key, oldValue) {\n        if (this.delegate.stringMapValueChanged) {\n            this.delegate.stringMapValueChanged(value, key, oldValue);\n        }\n    }\n    stringMapKeyRemoved(key, attributeName, oldValue) {\n        if (this.delegate.stringMapKeyRemoved) {\n            this.delegate.stringMapKeyRemoved(key, attributeName, oldValue);\n        }\n    }\n    get knownAttributeNames() {\n        return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)));\n    }\n    get currentAttributeNames() {\n        return Array.from(this.element.attributes).map((attribute) => attribute.name);\n    }\n    get recordedAttributeNames() {\n        return Array.from(this.stringMap.keys());\n    }\n}\n\nclass TokenListObserver {\n    constructor(element, attributeName, delegate) {\n        this.attributeObserver = new AttributeObserver(element, attributeName, this);\n        this.delegate = delegate;\n        this.tokensByElement = new Multimap();\n    }\n    get started() {\n        return this.attributeObserver.started;\n    }\n    start() {\n        this.attributeObserver.start();\n    }\n    pause(callback) {\n        this.attributeObserver.pause(callback);\n    }\n    stop() {\n        this.attributeObserver.stop();\n    }\n    refresh() {\n        this.attributeObserver.refresh();\n    }\n    get element() {\n        return this.attributeObserver.element;\n    }\n    get attributeName() {\n        return this.attributeObserver.attributeName;\n    }\n    elementMatchedAttribute(element) {\n        this.tokensMatched(this.readTokensForElement(element));\n    }\n    elementAttributeValueChanged(element) {\n        const [unmatchedTokens, matchedTokens] = this.refreshTokensForElement(element);\n        this.tokensUnmatched(unmatchedTokens);\n        this.tokensMatched(matchedTokens);\n    }\n    elementUnmatchedAttribute(element) {\n        this.tokensUnmatched(this.tokensByElement.getValuesForKey(element));\n    }\n    tokensMatched(tokens) {\n        tokens.forEach((token) => this.tokenMatched(token));\n    }\n    tokensUnmatched(tokens) {\n        tokens.forEach((token) => this.tokenUnmatched(token));\n    }\n    tokenMatched(token) {\n        this.delegate.tokenMatched(token);\n        this.tokensByElement.add(token.element, token);\n    }\n    tokenUnmatched(token) {\n        this.delegate.tokenUnmatched(token);\n        this.tokensByElement.delete(token.element, token);\n    }\n    refreshTokensForElement(element) {\n        const previousTokens = this.tokensByElement.getValuesForKey(element);\n        const currentTokens = this.readTokensForElement(element);\n        const firstDifferingIndex = zip(previousTokens, currentTokens).findIndex(([previousToken, currentToken]) => !tokensAreEqual(previousToken, currentToken));\n        if (firstDifferingIndex == -1) {\n            return [[], []];\n        }\n        else {\n            return [previousTokens.slice(firstDifferingIndex), currentTokens.slice(firstDifferingIndex)];\n        }\n    }\n    readTokensForElement(element) {\n        const attributeName = this.attributeName;\n        const tokenString = element.getAttribute(attributeName) || \"\";\n        return parseTokenString(tokenString, element, attributeName);\n    }\n}\nfunction parseTokenString(tokenString, element, attributeName) {\n    return tokenString\n        .trim()\n        .split(/\\s+/)\n        .filter((content) => content.length)\n        .map((content, index) => ({ element, attributeName, content, index }));\n}\nfunction zip(left, right) {\n    const length = Math.max(left.length, right.length);\n    return Array.from({ length }, (_, index) => [left[index], right[index]]);\n}\nfunction tokensAreEqual(left, right) {\n    return left && right && left.index == right.index && left.content == right.content;\n}\n\nclass ValueListObserver {\n    constructor(element, attributeName, delegate) {\n        this.tokenListObserver = new TokenListObserver(element, attributeName, this);\n        this.delegate = delegate;\n        this.parseResultsByToken = new WeakMap();\n        this.valuesByTokenByElement = new WeakMap();\n    }\n    get started() {\n        return this.tokenListObserver.started;\n    }\n    start() {\n        this.tokenListObserver.start();\n    }\n    stop() {\n        this.tokenListObserver.stop();\n    }\n    refresh() {\n        this.tokenListObserver.refresh();\n    }\n    get element() {\n        return this.tokenListObserver.element;\n    }\n    get attributeName() {\n        return this.tokenListObserver.attributeName;\n    }\n    tokenMatched(token) {\n        const { element } = token;\n        const { value } = this.fetchParseResultForToken(token);\n        if (value) {\n            this.fetchValuesByTokenForElement(element).set(token, value);\n            this.delegate.elementMatchedValue(element, value);\n        }\n    }\n    tokenUnmatched(token) {\n        const { element } = token;\n        const { value } = this.fetchParseResultForToken(token);\n        if (value) {\n            this.fetchValuesByTokenForElement(element).delete(token);\n            this.delegate.elementUnmatchedValue(element, value);\n        }\n    }\n    fetchParseResultForToken(token) {\n        let parseResult = this.parseResultsByToken.get(token);\n        if (!parseResult) {\n            parseResult = this.parseToken(token);\n            this.parseResultsByToken.set(token, parseResult);\n        }\n        return parseResult;\n    }\n    fetchValuesByTokenForElement(element) {\n        let valuesByToken = this.valuesByTokenByElement.get(element);\n        if (!valuesByToken) {\n            valuesByToken = new Map();\n            this.valuesByTokenByElement.set(element, valuesByToken);\n        }\n        return valuesByToken;\n    }\n    parseToken(token) {\n        try {\n            const value = this.delegate.parseValueForToken(token);\n            return { value };\n        }\n        catch (error) {\n            return { error };\n        }\n    }\n}\n\nclass BindingObserver {\n    constructor(context, delegate) {\n        this.context = context;\n        this.delegate = delegate;\n        this.bindingsByAction = new Map();\n    }\n    start() {\n        if (!this.valueListObserver) {\n            this.valueListObserver = new ValueListObserver(this.element, this.actionAttribute, this);\n            this.valueListObserver.start();\n        }\n    }\n    stop() {\n        if (this.valueListObserver) {\n            this.valueListObserver.stop();\n            delete this.valueListObserver;\n            this.disconnectAllActions();\n        }\n    }\n    get element() {\n        return this.context.element;\n    }\n    get identifier() {\n        return this.context.identifier;\n    }\n    get actionAttribute() {\n        return this.schema.actionAttribute;\n    }\n    get schema() {\n        return this.context.schema;\n    }\n    get bindings() {\n        return Array.from(this.bindingsByAction.values());\n    }\n    connectAction(action) {\n        const binding = new Binding(this.context, action);\n        this.bindingsByAction.set(action, binding);\n        this.delegate.bindingConnected(binding);\n    }\n    disconnectAction(action) {\n        const binding = this.bindingsByAction.get(action);\n        if (binding) {\n            this.bindingsByAction.delete(action);\n            this.delegate.bindingDisconnected(binding);\n        }\n    }\n    disconnectAllActions() {\n        this.bindings.forEach((binding) => this.delegate.bindingDisconnected(binding, true));\n        this.bindingsByAction.clear();\n    }\n    parseValueForToken(token) {\n        const action = Action.forToken(token, this.schema);\n        if (action.identifier == this.identifier) {\n            return action;\n        }\n    }\n    elementMatchedValue(element, action) {\n        this.connectAction(action);\n    }\n    elementUnmatchedValue(element, action) {\n        this.disconnectAction(action);\n    }\n}\n\nclass ValueObserver {\n    constructor(context, receiver) {\n        this.context = context;\n        this.receiver = receiver;\n        this.stringMapObserver = new StringMapObserver(this.element, this);\n        this.valueDescriptorMap = this.controller.valueDescriptorMap;\n    }\n    start() {\n        this.stringMapObserver.start();\n        this.invokeChangedCallbacksForDefaultValues();\n    }\n    stop() {\n        this.stringMapObserver.stop();\n    }\n    get element() {\n        return this.context.element;\n    }\n    get controller() {\n        return this.context.controller;\n    }\n    getStringMapKeyForAttribute(attributeName) {\n        if (attributeName in this.valueDescriptorMap) {\n            return this.valueDescriptorMap[attributeName].name;\n        }\n    }\n    stringMapKeyAdded(key, attributeName) {\n        const descriptor = this.valueDescriptorMap[attributeName];\n        if (!this.hasValue(key)) {\n            this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), descriptor.writer(descriptor.defaultValue));\n        }\n    }\n    stringMapValueChanged(value, name, oldValue) {\n        const descriptor = this.valueDescriptorNameMap[name];\n        if (value === null)\n            return;\n        if (oldValue === null) {\n            oldValue = descriptor.writer(descriptor.defaultValue);\n        }\n        this.invokeChangedCallback(name, value, oldValue);\n    }\n    stringMapKeyRemoved(key, attributeName, oldValue) {\n        const descriptor = this.valueDescriptorNameMap[key];\n        if (this.hasValue(key)) {\n            this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), oldValue);\n        }\n        else {\n            this.invokeChangedCallback(key, descriptor.writer(descriptor.defaultValue), oldValue);\n        }\n    }\n    invokeChangedCallbacksForDefaultValues() {\n        for (const { key, name, defaultValue, writer } of this.valueDescriptors) {\n            if (defaultValue != undefined && !this.controller.data.has(key)) {\n                this.invokeChangedCallback(name, writer(defaultValue), undefined);\n            }\n        }\n    }\n    invokeChangedCallback(name, rawValue, rawOldValue) {\n        const changedMethodName = `${name}Changed`;\n        const changedMethod = this.receiver[changedMethodName];\n        if (typeof changedMethod == \"function\") {\n            const descriptor = this.valueDescriptorNameMap[name];\n            try {\n                const value = descriptor.reader(rawValue);\n                let oldValue = rawOldValue;\n                if (rawOldValue) {\n                    oldValue = descriptor.reader(rawOldValue);\n                }\n                changedMethod.call(this.receiver, value, oldValue);\n            }\n            catch (error) {\n                if (error instanceof TypeError) {\n                    error.message = `Stimulus Value \"${this.context.identifier}.${descriptor.name}\" - ${error.message}`;\n                }\n                throw error;\n            }\n        }\n    }\n    get valueDescriptors() {\n        const { valueDescriptorMap } = this;\n        return Object.keys(valueDescriptorMap).map((key) => valueDescriptorMap[key]);\n    }\n    get valueDescriptorNameMap() {\n        const descriptors = {};\n        Object.keys(this.valueDescriptorMap).forEach((key) => {\n            const descriptor = this.valueDescriptorMap[key];\n            descriptors[descriptor.name] = descriptor;\n        });\n        return descriptors;\n    }\n    hasValue(attributeName) {\n        const descriptor = this.valueDescriptorNameMap[attributeName];\n        const hasMethodName = `has${capitalize(descriptor.name)}`;\n        return this.receiver[hasMethodName];\n    }\n}\n\nclass TargetObserver {\n    constructor(context, delegate) {\n        this.context = context;\n        this.delegate = delegate;\n        this.targetsByName = new Multimap();\n    }\n    start() {\n        if (!this.tokenListObserver) {\n            this.tokenListObserver = new TokenListObserver(this.element, this.attributeName, this);\n            this.tokenListObserver.start();\n        }\n    }\n    stop() {\n        if (this.tokenListObserver) {\n            this.disconnectAllTargets();\n            this.tokenListObserver.stop();\n            delete this.tokenListObserver;\n        }\n    }\n    tokenMatched({ element, content: name }) {\n        if (this.scope.containsElement(element)) {\n            this.connectTarget(element, name);\n        }\n    }\n    tokenUnmatched({ element, content: name }) {\n        this.disconnectTarget(element, name);\n    }\n    connectTarget(element, name) {\n        var _a;\n        if (!this.targetsByName.has(name, element)) {\n            this.targetsByName.add(name, element);\n            (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetConnected(element, name));\n        }\n    }\n    disconnectTarget(element, name) {\n        var _a;\n        if (this.targetsByName.has(name, element)) {\n            this.targetsByName.delete(name, element);\n            (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetDisconnected(element, name));\n        }\n    }\n    disconnectAllTargets() {\n        for (const name of this.targetsByName.keys) {\n            for (const element of this.targetsByName.getValuesForKey(name)) {\n                this.disconnectTarget(element, name);\n            }\n        }\n    }\n    get attributeName() {\n        return `data-${this.context.identifier}-target`;\n    }\n    get element() {\n        return this.context.element;\n    }\n    get scope() {\n        return this.context.scope;\n    }\n}\n\nfunction readInheritableStaticArrayValues(constructor, propertyName) {\n    const ancestors = getAncestorsForConstructor(constructor);\n    return Array.from(ancestors.reduce((values, constructor) => {\n        getOwnStaticArrayValues(constructor, propertyName).forEach((name) => values.add(name));\n        return values;\n    }, new Set()));\n}\nfunction readInheritableStaticObjectPairs(constructor, propertyName) {\n    const ancestors = getAncestorsForConstructor(constructor);\n    return ancestors.reduce((pairs, constructor) => {\n        pairs.push(...getOwnStaticObjectPairs(constructor, propertyName));\n        return pairs;\n    }, []);\n}\nfunction getAncestorsForConstructor(constructor) {\n    const ancestors = [];\n    while (constructor) {\n        ancestors.push(constructor);\n        constructor = Object.getPrototypeOf(constructor);\n    }\n    return ancestors.reverse();\n}\nfunction getOwnStaticArrayValues(constructor, propertyName) {\n    const definition = constructor[propertyName];\n    return Array.isArray(definition) ? definition : [];\n}\nfunction getOwnStaticObjectPairs(constructor, propertyName) {\n    const definition = constructor[propertyName];\n    return definition ? Object.keys(definition).map((key) => [key, definition[key]]) : [];\n}\n\nclass OutletObserver {\n    constructor(context, delegate) {\n        this.started = false;\n        this.context = context;\n        this.delegate = delegate;\n        this.outletsByName = new Multimap();\n        this.outletElementsByName = new Multimap();\n        this.selectorObserverMap = new Map();\n        this.attributeObserverMap = new Map();\n    }\n    start() {\n        if (!this.started) {\n            this.outletDefinitions.forEach((outletName) => {\n                this.setupSelectorObserverForOutlet(outletName);\n                this.setupAttributeObserverForOutlet(outletName);\n            });\n            this.started = true;\n            this.dependentContexts.forEach((context) => context.refresh());\n        }\n    }\n    refresh() {\n        this.selectorObserverMap.forEach((observer) => observer.refresh());\n        this.attributeObserverMap.forEach((observer) => observer.refresh());\n    }\n    stop() {\n        if (this.started) {\n            this.started = false;\n            this.disconnectAllOutlets();\n            this.stopSelectorObservers();\n            this.stopAttributeObservers();\n        }\n    }\n    stopSelectorObservers() {\n        if (this.selectorObserverMap.size > 0) {\n            this.selectorObserverMap.forEach((observer) => observer.stop());\n            this.selectorObserverMap.clear();\n        }\n    }\n    stopAttributeObservers() {\n        if (this.attributeObserverMap.size > 0) {\n            this.attributeObserverMap.forEach((observer) => observer.stop());\n            this.attributeObserverMap.clear();\n        }\n    }\n    selectorMatched(element, _selector, { outletName }) {\n        const outlet = this.getOutlet(element, outletName);\n        if (outlet) {\n            this.connectOutlet(outlet, element, outletName);\n        }\n    }\n    selectorUnmatched(element, _selector, { outletName }) {\n        const outlet = this.getOutletFromMap(element, outletName);\n        if (outlet) {\n            this.disconnectOutlet(outlet, element, outletName);\n        }\n    }\n    selectorMatchElement(element, { outletName }) {\n        const selector = this.selector(outletName);\n        const hasOutlet = this.hasOutlet(element, outletName);\n        const hasOutletController = element.matches(`[${this.schema.controllerAttribute}~=${outletName}]`);\n        if (selector) {\n            return hasOutlet && hasOutletController && element.matches(selector);\n        }\n        else {\n            return false;\n        }\n    }\n    elementMatchedAttribute(_element, attributeName) {\n        const outletName = this.getOutletNameFromOutletAttributeName(attributeName);\n        if (outletName) {\n            this.updateSelectorObserverForOutlet(outletName);\n        }\n    }\n    elementAttributeValueChanged(_element, attributeName) {\n        const outletName = this.getOutletNameFromOutletAttributeName(attributeName);\n        if (outletName) {\n            this.updateSelectorObserverForOutlet(outletName);\n        }\n    }\n    elementUnmatchedAttribute(_element, attributeName) {\n        const outletName = this.getOutletNameFromOutletAttributeName(attributeName);\n        if (outletName) {\n            this.updateSelectorObserverForOutlet(outletName);\n        }\n    }\n    connectOutlet(outlet, element, outletName) {\n        var _a;\n        if (!this.outletElementsByName.has(outletName, element)) {\n            this.outletsByName.add(outletName, outlet);\n            this.outletElementsByName.add(outletName, element);\n            (_a = this.selectorObserverMap.get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletConnected(outlet, element, outletName));\n        }\n    }\n    disconnectOutlet(outlet, element, outletName) {\n        var _a;\n        if (this.outletElementsByName.has(outletName, element)) {\n            this.outletsByName.delete(outletName, outlet);\n            this.outletElementsByName.delete(outletName, element);\n            (_a = this.selectorObserverMap\n                .get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletDisconnected(outlet, element, outletName));\n        }\n    }\n    disconnectAllOutlets() {\n        for (const outletName of this.outletElementsByName.keys) {\n            for (const element of this.outletElementsByName.getValuesForKey(outletName)) {\n                for (const outlet of this.outletsByName.getValuesForKey(outletName)) {\n                    this.disconnectOutlet(outlet, element, outletName);\n                }\n            }\n        }\n    }\n    updateSelectorObserverForOutlet(outletName) {\n        const observer = this.selectorObserverMap.get(outletName);\n        if (observer) {\n            observer.selector = this.selector(outletName);\n        }\n    }\n    setupSelectorObserverForOutlet(outletName) {\n        const selector = this.selector(outletName);\n        const selectorObserver = new SelectorObserver(document.body, selector, this, { outletName });\n        this.selectorObserverMap.set(outletName, selectorObserver);\n        selectorObserver.start();\n    }\n    setupAttributeObserverForOutlet(outletName) {\n        const attributeName = this.attributeNameForOutletName(outletName);\n        const attributeObserver = new AttributeObserver(this.scope.element, attributeName, this);\n        this.attributeObserverMap.set(outletName, attributeObserver);\n        attributeObserver.start();\n    }\n    selector(outletName) {\n        return this.scope.outlets.getSelectorForOutletName(outletName);\n    }\n    attributeNameForOutletName(outletName) {\n        return this.scope.schema.outletAttributeForScope(this.identifier, outletName);\n    }\n    getOutletNameFromOutletAttributeName(attributeName) {\n        return this.outletDefinitions.find((outletName) => this.attributeNameForOutletName(outletName) === attributeName);\n    }\n    get outletDependencies() {\n        const dependencies = new Multimap();\n        this.router.modules.forEach((module) => {\n            const constructor = module.definition.controllerConstructor;\n            const outlets = readInheritableStaticArrayValues(constructor, \"outlets\");\n            outlets.forEach((outlet) => dependencies.add(outlet, module.identifier));\n        });\n        return dependencies;\n    }\n    get outletDefinitions() {\n        return this.outletDependencies.getKeysForValue(this.identifier);\n    }\n    get dependentControllerIdentifiers() {\n        return this.outletDependencies.getValuesForKey(this.identifier);\n    }\n    get dependentContexts() {\n        const identifiers = this.dependentControllerIdentifiers;\n        return this.router.contexts.filter((context) => identifiers.includes(context.identifier));\n    }\n    hasOutlet(element, outletName) {\n        return !!this.getOutlet(element, outletName) || !!this.getOutletFromMap(element, outletName);\n    }\n    getOutlet(element, outletName) {\n        return this.application.getControllerForElementAndIdentifier(element, outletName);\n    }\n    getOutletFromMap(element, outletName) {\n        return this.outletsByName.getValuesForKey(outletName).find((outlet) => outlet.element === element);\n    }\n    get scope() {\n        return this.context.scope;\n    }\n    get schema() {\n        return this.context.schema;\n    }\n    get identifier() {\n        return this.context.identifier;\n    }\n    get application() {\n        return this.context.application;\n    }\n    get router() {\n        return this.application.router;\n    }\n}\n\nclass Context {\n    constructor(module, scope) {\n        this.logDebugActivity = (functionName, detail = {}) => {\n            const { identifier, controller, element } = this;\n            detail = Object.assign({ identifier, controller, element }, detail);\n            this.application.logDebugActivity(this.identifier, functionName, detail);\n        };\n        this.module = module;\n        this.scope = scope;\n        this.controller = new module.controllerConstructor(this);\n        this.bindingObserver = new BindingObserver(this, this.dispatcher);\n        this.valueObserver = new ValueObserver(this, this.controller);\n        this.targetObserver = new TargetObserver(this, this);\n        this.outletObserver = new OutletObserver(this, this);\n        try {\n            this.controller.initialize();\n            this.logDebugActivity(\"initialize\");\n        }\n        catch (error) {\n            this.handleError(error, \"initializing controller\");\n        }\n    }\n    connect() {\n        this.bindingObserver.start();\n        this.valueObserver.start();\n        this.targetObserver.start();\n        this.outletObserver.start();\n        try {\n            this.controller.connect();\n            this.logDebugActivity(\"connect\");\n        }\n        catch (error) {\n            this.handleError(error, \"connecting controller\");\n        }\n    }\n    refresh() {\n        this.outletObserver.refresh();\n    }\n    disconnect() {\n        try {\n            this.controller.disconnect();\n            this.logDebugActivity(\"disconnect\");\n        }\n        catch (error) {\n            this.handleError(error, \"disconnecting controller\");\n        }\n        this.outletObserver.stop();\n        this.targetObserver.stop();\n        this.valueObserver.stop();\n        this.bindingObserver.stop();\n    }\n    get application() {\n        return this.module.application;\n    }\n    get identifier() {\n        return this.module.identifier;\n    }\n    get schema() {\n        return this.application.schema;\n    }\n    get dispatcher() {\n        return this.application.dispatcher;\n    }\n    get element() {\n        return this.scope.element;\n    }\n    get parentElement() {\n        return this.element.parentElement;\n    }\n    handleError(error, message, detail = {}) {\n        const { identifier, controller, element } = this;\n        detail = Object.assign({ identifier, controller, element }, detail);\n        this.application.handleError(error, `Error ${message}`, detail);\n    }\n    targetConnected(element, name) {\n        this.invokeControllerMethod(`${name}TargetConnected`, element);\n    }\n    targetDisconnected(element, name) {\n        this.invokeControllerMethod(`${name}TargetDisconnected`, element);\n    }\n    outletConnected(outlet, element, name) {\n        this.invokeControllerMethod(`${namespaceCamelize(name)}OutletConnected`, outlet, element);\n    }\n    outletDisconnected(outlet, element, name) {\n        this.invokeControllerMethod(`${namespaceCamelize(name)}OutletDisconnected`, outlet, element);\n    }\n    invokeControllerMethod(methodName, ...args) {\n        const controller = this.controller;\n        if (typeof controller[methodName] == \"function\") {\n            controller[methodName](...args);\n        }\n    }\n}\n\nfunction bless(constructor) {\n    return shadow(constructor, getBlessedProperties(constructor));\n}\nfunction shadow(constructor, properties) {\n    const shadowConstructor = extend(constructor);\n    const shadowProperties = getShadowProperties(constructor.prototype, properties);\n    Object.defineProperties(shadowConstructor.prototype, shadowProperties);\n    return shadowConstructor;\n}\nfunction getBlessedProperties(constructor) {\n    const blessings = readInheritableStaticArrayValues(constructor, \"blessings\");\n    return blessings.reduce((blessedProperties, blessing) => {\n        const properties = blessing(constructor);\n        for (const key in properties) {\n            const descriptor = blessedProperties[key] || {};\n            blessedProperties[key] = Object.assign(descriptor, properties[key]);\n        }\n        return blessedProperties;\n    }, {});\n}\nfunction getShadowProperties(prototype, properties) {\n    return getOwnKeys(properties).reduce((shadowProperties, key) => {\n        const descriptor = getShadowedDescriptor(prototype, properties, key);\n        if (descriptor) {\n            Object.assign(shadowProperties, { [key]: descriptor });\n        }\n        return shadowProperties;\n    }, {});\n}\nfunction getShadowedDescriptor(prototype, properties, key) {\n    const shadowingDescriptor = Object.getOwnPropertyDescriptor(prototype, key);\n    const shadowedByValue = shadowingDescriptor && \"value\" in shadowingDescriptor;\n    if (!shadowedByValue) {\n        const descriptor = Object.getOwnPropertyDescriptor(properties, key).value;\n        if (shadowingDescriptor) {\n            descriptor.get = shadowingDescriptor.get || descriptor.get;\n            descriptor.set = shadowingDescriptor.set || descriptor.set;\n        }\n        return descriptor;\n    }\n}\nconst getOwnKeys = (() => {\n    if (typeof Object.getOwnPropertySymbols == \"function\") {\n        return (object) => [...Object.getOwnPropertyNames(object), ...Object.getOwnPropertySymbols(object)];\n    }\n    else {\n        return Object.getOwnPropertyNames;\n    }\n})();\nconst extend = (() => {\n    function extendWithReflect(constructor) {\n        function extended() {\n            return Reflect.construct(constructor, arguments, new.target);\n        }\n        extended.prototype = Object.create(constructor.prototype, {\n            constructor: { value: extended },\n        });\n        Reflect.setPrototypeOf(extended, constructor);\n        return extended;\n    }\n    function testReflectExtension() {\n        const a = function () {\n            this.a.call(this);\n        };\n        const b = extendWithReflect(a);\n        b.prototype.a = function () { };\n        return new b();\n    }\n    try {\n        testReflectExtension();\n        return extendWithReflect;\n    }\n    catch (error) {\n        return (constructor) => class extended extends constructor {\n        };\n    }\n})();\n\nfunction blessDefinition(definition) {\n    return {\n        identifier: definition.identifier,\n        controllerConstructor: bless(definition.controllerConstructor),\n    };\n}\n\nclass Module {\n    constructor(application, definition) {\n        this.application = application;\n        this.definition = blessDefinition(definition);\n        this.contextsByScope = new WeakMap();\n        this.connectedContexts = new Set();\n    }\n    get identifier() {\n        return this.definition.identifier;\n    }\n    get controllerConstructor() {\n        return this.definition.controllerConstructor;\n    }\n    get contexts() {\n        return Array.from(this.connectedContexts);\n    }\n    connectContextForScope(scope) {\n        const context = this.fetchContextForScope(scope);\n        this.connectedContexts.add(context);\n        context.connect();\n    }\n    disconnectContextForScope(scope) {\n        const context = this.contextsByScope.get(scope);\n        if (context) {\n            this.connectedContexts.delete(context);\n            context.disconnect();\n        }\n    }\n    fetchContextForScope(scope) {\n        let context = this.contextsByScope.get(scope);\n        if (!context) {\n            context = new Context(this, scope);\n            this.contextsByScope.set(scope, context);\n        }\n        return context;\n    }\n}\n\nclass ClassMap {\n    constructor(scope) {\n        this.scope = scope;\n    }\n    has(name) {\n        return this.data.has(this.getDataKey(name));\n    }\n    get(name) {\n        return this.getAll(name)[0];\n    }\n    getAll(name) {\n        const tokenString = this.data.get(this.getDataKey(name)) || \"\";\n        return tokenize(tokenString);\n    }\n    getAttributeName(name) {\n        return this.data.getAttributeNameForKey(this.getDataKey(name));\n    }\n    getDataKey(name) {\n        return `${name}-class`;\n    }\n    get data() {\n        return this.scope.data;\n    }\n}\n\nclass DataMap {\n    constructor(scope) {\n        this.scope = scope;\n    }\n    get element() {\n        return this.scope.element;\n    }\n    get identifier() {\n        return this.scope.identifier;\n    }\n    get(key) {\n        const name = this.getAttributeNameForKey(key);\n        return this.element.getAttribute(name);\n    }\n    set(key, value) {\n        const name = this.getAttributeNameForKey(key);\n        this.element.setAttribute(name, value);\n        return this.get(key);\n    }\n    has(key) {\n        const name = this.getAttributeNameForKey(key);\n        return this.element.hasAttribute(name);\n    }\n    delete(key) {\n        if (this.has(key)) {\n            const name = this.getAttributeNameForKey(key);\n            this.element.removeAttribute(name);\n            return true;\n        }\n        else {\n            return false;\n        }\n    }\n    getAttributeNameForKey(key) {\n        return `data-${this.identifier}-${dasherize(key)}`;\n    }\n}\n\nclass Guide {\n    constructor(logger) {\n        this.warnedKeysByObject = new WeakMap();\n        this.logger = logger;\n    }\n    warn(object, key, message) {\n        let warnedKeys = this.warnedKeysByObject.get(object);\n        if (!warnedKeys) {\n            warnedKeys = new Set();\n            this.warnedKeysByObject.set(object, warnedKeys);\n        }\n        if (!warnedKeys.has(key)) {\n            warnedKeys.add(key);\n            this.logger.warn(message, object);\n        }\n    }\n}\n\nfunction attributeValueContainsToken(attributeName, token) {\n    return `[${attributeName}~=\"${token}\"]`;\n}\n\nclass TargetSet {\n    constructor(scope) {\n        this.scope = scope;\n    }\n    get element() {\n        return this.scope.element;\n    }\n    get identifier() {\n        return this.scope.identifier;\n    }\n    get schema() {\n        return this.scope.schema;\n    }\n    has(targetName) {\n        return this.find(targetName) != null;\n    }\n    find(...targetNames) {\n        return targetNames.reduce((target, targetName) => target || this.findTarget(targetName) || this.findLegacyTarget(targetName), undefined);\n    }\n    findAll(...targetNames) {\n        return targetNames.reduce((targets, targetName) => [\n            ...targets,\n            ...this.findAllTargets(targetName),\n            ...this.findAllLegacyTargets(targetName),\n        ], []);\n    }\n    findTarget(targetName) {\n        const selector = this.getSelectorForTargetName(targetName);\n        return this.scope.findElement(selector);\n    }\n    findAllTargets(targetName) {\n        const selector = this.getSelectorForTargetName(targetName);\n        return this.scope.findAllElements(selector);\n    }\n    getSelectorForTargetName(targetName) {\n        const attributeName = this.schema.targetAttributeForScope(this.identifier);\n        return attributeValueContainsToken(attributeName, targetName);\n    }\n    findLegacyTarget(targetName) {\n        const selector = this.getLegacySelectorForTargetName(targetName);\n        return this.deprecate(this.scope.findElement(selector), targetName);\n    }\n    findAllLegacyTargets(targetName) {\n        const selector = this.getLegacySelectorForTargetName(targetName);\n        return this.scope.findAllElements(selector).map((element) => this.deprecate(element, targetName));\n    }\n    getLegacySelectorForTargetName(targetName) {\n        const targetDescriptor = `${this.identifier}.${targetName}`;\n        return attributeValueContainsToken(this.schema.targetAttribute, targetDescriptor);\n    }\n    deprecate(element, targetName) {\n        if (element) {\n            const { identifier } = this;\n            const attributeName = this.schema.targetAttribute;\n            const revisedAttributeName = this.schema.targetAttributeForScope(identifier);\n            this.guide.warn(element, `target:${targetName}`, `Please replace ${attributeName}=\"${identifier}.${targetName}\" with ${revisedAttributeName}=\"${targetName}\". ` +\n                `The ${attributeName} attribute is deprecated and will be removed in a future version of Stimulus.`);\n        }\n        return element;\n    }\n    get guide() {\n        return this.scope.guide;\n    }\n}\n\nclass OutletSet {\n    constructor(scope, controllerElement) {\n        this.scope = scope;\n        this.controllerElement = controllerElement;\n    }\n    get element() {\n        return this.scope.element;\n    }\n    get identifier() {\n        return this.scope.identifier;\n    }\n    get schema() {\n        return this.scope.schema;\n    }\n    has(outletName) {\n        return this.find(outletName) != null;\n    }\n    find(...outletNames) {\n        return outletNames.reduce((outlet, outletName) => outlet || this.findOutlet(outletName), undefined);\n    }\n    findAll(...outletNames) {\n        return outletNames.reduce((outlets, outletName) => [...outlets, ...this.findAllOutlets(outletName)], []);\n    }\n    getSelectorForOutletName(outletName) {\n        const attributeName = this.schema.outletAttributeForScope(this.identifier, outletName);\n        return this.controllerElement.getAttribute(attributeName);\n    }\n    findOutlet(outletName) {\n        const selector = this.getSelectorForOutletName(outletName);\n        if (selector)\n            return this.findElement(selector, outletName);\n    }\n    findAllOutlets(outletName) {\n        const selector = this.getSelectorForOutletName(outletName);\n        return selector ? this.findAllElements(selector, outletName) : [];\n    }\n    findElement(selector, outletName) {\n        const elements = this.scope.queryElements(selector);\n        return elements.filter((element) => this.matchesElement(element, selector, outletName))[0];\n    }\n    findAllElements(selector, outletName) {\n        const elements = this.scope.queryElements(selector);\n        return elements.filter((element) => this.matchesElement(element, selector, outletName));\n    }\n    matchesElement(element, selector, outletName) {\n        const controllerAttribute = element.getAttribute(this.scope.schema.controllerAttribute) || \"\";\n        return element.matches(selector) && controllerAttribute.split(\" \").includes(outletName);\n    }\n}\n\nclass Scope {\n    constructor(schema, element, identifier, logger) {\n        this.targets = new TargetSet(this);\n        this.classes = new ClassMap(this);\n        this.data = new DataMap(this);\n        this.containsElement = (element) => {\n            return element.closest(this.controllerSelector) === this.element;\n        };\n        this.schema = schema;\n        this.element = element;\n        this.identifier = identifier;\n        this.guide = new Guide(logger);\n        this.outlets = new OutletSet(this.documentScope, element);\n    }\n    findElement(selector) {\n        return this.element.matches(selector) ? this.element : this.queryElements(selector).find(this.containsElement);\n    }\n    findAllElements(selector) {\n        return [\n            ...(this.element.matches(selector) ? [this.element] : []),\n            ...this.queryElements(selector).filter(this.containsElement),\n        ];\n    }\n    queryElements(selector) {\n        return Array.from(this.element.querySelectorAll(selector));\n    }\n    get controllerSelector() {\n        return attributeValueContainsToken(this.schema.controllerAttribute, this.identifier);\n    }\n    get isDocumentScope() {\n        return this.element === document.documentElement;\n    }\n    get documentScope() {\n        return this.isDocumentScope\n            ? this\n            : new Scope(this.schema, document.documentElement, this.identifier, this.guide.logger);\n    }\n}\n\nclass ScopeObserver {\n    constructor(element, schema, delegate) {\n        this.element = element;\n        this.schema = schema;\n        this.delegate = delegate;\n        this.valueListObserver = new ValueListObserver(this.element, this.controllerAttribute, this);\n        this.scopesByIdentifierByElement = new WeakMap();\n        this.scopeReferenceCounts = new WeakMap();\n    }\n    start() {\n        this.valueListObserver.start();\n    }\n    stop() {\n        this.valueListObserver.stop();\n    }\n    get controllerAttribute() {\n        return this.schema.controllerAttribute;\n    }\n    parseValueForToken(token) {\n        const { element, content: identifier } = token;\n        return this.parseValueForElementAndIdentifier(element, identifier);\n    }\n    parseValueForElementAndIdentifier(element, identifier) {\n        const scopesByIdentifier = this.fetchScopesByIdentifierForElement(element);\n        let scope = scopesByIdentifier.get(identifier);\n        if (!scope) {\n            scope = this.delegate.createScopeForElementAndIdentifier(element, identifier);\n            scopesByIdentifier.set(identifier, scope);\n        }\n        return scope;\n    }\n    elementMatchedValue(element, value) {\n        const referenceCount = (this.scopeReferenceCounts.get(value) || 0) + 1;\n        this.scopeReferenceCounts.set(value, referenceCount);\n        if (referenceCount == 1) {\n            this.delegate.scopeConnected(value);\n        }\n    }\n    elementUnmatchedValue(element, value) {\n        const referenceCount = this.scopeReferenceCounts.get(value);\n        if (referenceCount) {\n            this.scopeReferenceCounts.set(value, referenceCount - 1);\n            if (referenceCount == 1) {\n                this.delegate.scopeDisconnected(value);\n            }\n        }\n    }\n    fetchScopesByIdentifierForElement(element) {\n        let scopesByIdentifier = this.scopesByIdentifierByElement.get(element);\n        if (!scopesByIdentifier) {\n            scopesByIdentifier = new Map();\n            this.scopesByIdentifierByElement.set(element, scopesByIdentifier);\n        }\n        return scopesByIdentifier;\n    }\n}\n\nclass Router {\n    constructor(application) {\n        this.application = application;\n        this.scopeObserver = new ScopeObserver(this.element, this.schema, this);\n        this.scopesByIdentifier = new Multimap();\n        this.modulesByIdentifier = new Map();\n    }\n    get element() {\n        return this.application.element;\n    }\n    get schema() {\n        return this.application.schema;\n    }\n    get logger() {\n        return this.application.logger;\n    }\n    get controllerAttribute() {\n        return this.schema.controllerAttribute;\n    }\n    get modules() {\n        return Array.from(this.modulesByIdentifier.values());\n    }\n    get contexts() {\n        return this.modules.reduce((contexts, module) => contexts.concat(module.contexts), []);\n    }\n    start() {\n        this.scopeObserver.start();\n    }\n    stop() {\n        this.scopeObserver.stop();\n    }\n    loadDefinition(definition) {\n        this.unloadIdentifier(definition.identifier);\n        const module = new Module(this.application, definition);\n        this.connectModule(module);\n        const afterLoad = definition.controllerConstructor.afterLoad;\n        if (afterLoad) {\n            afterLoad.call(definition.controllerConstructor, definition.identifier, this.application);\n        }\n    }\n    unloadIdentifier(identifier) {\n        const module = this.modulesByIdentifier.get(identifier);\n        if (module) {\n            this.disconnectModule(module);\n        }\n    }\n    getContextForElementAndIdentifier(element, identifier) {\n        const module = this.modulesByIdentifier.get(identifier);\n        if (module) {\n            return module.contexts.find((context) => context.element == element);\n        }\n    }\n    proposeToConnectScopeForElementAndIdentifier(element, identifier) {\n        const scope = this.scopeObserver.parseValueForElementAndIdentifier(element, identifier);\n        if (scope) {\n            this.scopeObserver.elementMatchedValue(scope.element, scope);\n        }\n        else {\n            console.error(`Couldn't find or create scope for identifier: \"${identifier}\" and element:`, element);\n        }\n    }\n    handleError(error, message, detail) {\n        this.application.handleError(error, message, detail);\n    }\n    createScopeForElementAndIdentifier(element, identifier) {\n        return new Scope(this.schema, element, identifier, this.logger);\n    }\n    scopeConnected(scope) {\n        this.scopesByIdentifier.add(scope.identifier, scope);\n        const module = this.modulesByIdentifier.get(scope.identifier);\n        if (module) {\n            module.connectContextForScope(scope);\n        }\n    }\n    scopeDisconnected(scope) {\n        this.scopesByIdentifier.delete(scope.identifier, scope);\n        const module = this.modulesByIdentifier.get(scope.identifier);\n        if (module) {\n            module.disconnectContextForScope(scope);\n        }\n    }\n    connectModule(module) {\n        this.modulesByIdentifier.set(module.identifier, module);\n        const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);\n        scopes.forEach((scope) => module.connectContextForScope(scope));\n    }\n    disconnectModule(module) {\n        this.modulesByIdentifier.delete(module.identifier);\n        const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);\n        scopes.forEach((scope) => module.disconnectContextForScope(scope));\n    }\n}\n\nconst defaultSchema = {\n    controllerAttribute: \"data-controller\",\n    actionAttribute: \"data-action\",\n    targetAttribute: \"data-target\",\n    targetAttributeForScope: (identifier) => `data-${identifier}-target`,\n    outletAttributeForScope: (identifier, outlet) => `data-${identifier}-${outlet}-outlet`,\n    keyMappings: Object.assign(Object.assign({ enter: \"Enter\", tab: \"Tab\", esc: \"Escape\", space: \" \", up: \"ArrowUp\", down: \"ArrowDown\", left: \"ArrowLeft\", right: \"ArrowRight\", home: \"Home\", end: \"End\", page_up: \"PageUp\", page_down: \"PageDown\" }, objectFromEntries(\"abcdefghijklmnopqrstuvwxyz\".split(\"\").map((c) => [c, c]))), objectFromEntries(\"0123456789\".split(\"\").map((n) => [n, n]))),\n};\nfunction objectFromEntries(array) {\n    return array.reduce((memo, [k, v]) => (Object.assign(Object.assign({}, memo), { [k]: v })), {});\n}\n\nclass Application {\n    constructor(element = document.documentElement, schema = defaultSchema) {\n        this.logger = console;\n        this.debug = false;\n        this.logDebugActivity = (identifier, functionName, detail = {}) => {\n            if (this.debug) {\n                this.logFormattedMessage(identifier, functionName, detail);\n            }\n        };\n        this.element = element;\n        this.schema = schema;\n        this.dispatcher = new Dispatcher(this);\n        this.router = new Router(this);\n        this.actionDescriptorFilters = Object.assign({}, defaultActionDescriptorFilters);\n    }\n    static start(element, schema) {\n        const application = new this(element, schema);\n        application.start();\n        return application;\n    }\n    async start() {\n        await domReady();\n        this.logDebugActivity(\"application\", \"starting\");\n        this.dispatcher.start();\n        this.router.start();\n        this.logDebugActivity(\"application\", \"start\");\n    }\n    stop() {\n        this.logDebugActivity(\"application\", \"stopping\");\n        this.dispatcher.stop();\n        this.router.stop();\n        this.logDebugActivity(\"application\", \"stop\");\n    }\n    register(identifier, controllerConstructor) {\n        this.load({ identifier, controllerConstructor });\n    }\n    registerActionOption(name, filter) {\n        this.actionDescriptorFilters[name] = filter;\n    }\n    load(head, ...rest) {\n        const definitions = Array.isArray(head) ? head : [head, ...rest];\n        definitions.forEach((definition) => {\n            if (definition.controllerConstructor.shouldLoad) {\n                this.router.loadDefinition(definition);\n            }\n        });\n    }\n    unload(head, ...rest) {\n        const identifiers = Array.isArray(head) ? head : [head, ...rest];\n        identifiers.forEach((identifier) => this.router.unloadIdentifier(identifier));\n    }\n    get controllers() {\n        return this.router.contexts.map((context) => context.controller);\n    }\n    getControllerForElementAndIdentifier(element, identifier) {\n        const context = this.router.getContextForElementAndIdentifier(element, identifier);\n        return context ? context.controller : null;\n    }\n    handleError(error, message, detail) {\n        var _a;\n        this.logger.error(`%s\\n\\n%o\\n\\n%o`, message, error, detail);\n        (_a = window.onerror) === null || _a === void 0 ? void 0 : _a.call(window, message, \"\", 0, 0, error);\n    }\n    logFormattedMessage(identifier, functionName, detail = {}) {\n        detail = Object.assign({ application: this }, detail);\n        this.logger.groupCollapsed(`${identifier} #${functionName}`);\n        this.logger.log(\"details:\", Object.assign({}, detail));\n        this.logger.groupEnd();\n    }\n}\nfunction domReady() {\n    return new Promise((resolve) => {\n        if (document.readyState == \"loading\") {\n            document.addEventListener(\"DOMContentLoaded\", () => resolve());\n        }\n        else {\n            resolve();\n        }\n    });\n}\n\nfunction ClassPropertiesBlessing(constructor) {\n    const classes = readInheritableStaticArrayValues(constructor, \"classes\");\n    return classes.reduce((properties, classDefinition) => {\n        return Object.assign(properties, propertiesForClassDefinition(classDefinition));\n    }, {});\n}\nfunction propertiesForClassDefinition(key) {\n    return {\n        [`${key}Class`]: {\n            get() {\n                const { classes } = this;\n                if (classes.has(key)) {\n                    return classes.get(key);\n                }\n                else {\n                    const attribute = classes.getAttributeName(key);\n                    throw new Error(`Missing attribute \"${attribute}\"`);\n                }\n            },\n        },\n        [`${key}Classes`]: {\n            get() {\n                return this.classes.getAll(key);\n            },\n        },\n        [`has${capitalize(key)}Class`]: {\n            get() {\n                return this.classes.has(key);\n            },\n        },\n    };\n}\n\nfunction OutletPropertiesBlessing(constructor) {\n    const outlets = readInheritableStaticArrayValues(constructor, \"outlets\");\n    return outlets.reduce((properties, outletDefinition) => {\n        return Object.assign(properties, propertiesForOutletDefinition(outletDefinition));\n    }, {});\n}\nfunction getOutletController(controller, element, identifier) {\n    return controller.application.getControllerForElementAndIdentifier(element, identifier);\n}\nfunction getControllerAndEnsureConnectedScope(controller, element, outletName) {\n    let outletController = getOutletController(controller, element, outletName);\n    if (outletController)\n        return outletController;\n    controller.application.router.proposeToConnectScopeForElementAndIdentifier(element, outletName);\n    outletController = getOutletController(controller, element, outletName);\n    if (outletController)\n        return outletController;\n}\nfunction propertiesForOutletDefinition(name) {\n    const camelizedName = namespaceCamelize(name);\n    return {\n        [`${camelizedName}Outlet`]: {\n            get() {\n                const outletElement = this.outlets.find(name);\n                const selector = this.outlets.getSelectorForOutletName(name);\n                if (outletElement) {\n                    const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);\n                    if (outletController)\n                        return outletController;\n                    throw new Error(`The provided outlet element is missing an outlet controller \"${name}\" instance for host controller \"${this.identifier}\"`);\n                }\n                throw new Error(`Missing outlet element \"${name}\" for host controller \"${this.identifier}\". Stimulus couldn't find a matching outlet element using selector \"${selector}\".`);\n            },\n        },\n        [`${camelizedName}Outlets`]: {\n            get() {\n                const outlets = this.outlets.findAll(name);\n                if (outlets.length > 0) {\n                    return outlets\n                        .map((outletElement) => {\n                        const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);\n                        if (outletController)\n                            return outletController;\n                        console.warn(`The provided outlet element is missing an outlet controller \"${name}\" instance for host controller \"${this.identifier}\"`, outletElement);\n                    })\n                        .filter((controller) => controller);\n                }\n                return [];\n            },\n        },\n        [`${camelizedName}OutletElement`]: {\n            get() {\n                const outletElement = this.outlets.find(name);\n                const selector = this.outlets.getSelectorForOutletName(name);\n                if (outletElement) {\n                    return outletElement;\n                }\n                else {\n                    throw new Error(`Missing outlet element \"${name}\" for host controller \"${this.identifier}\". Stimulus couldn't find a matching outlet element using selector \"${selector}\".`);\n                }\n            },\n        },\n        [`${camelizedName}OutletElements`]: {\n            get() {\n                return this.outlets.findAll(name);\n            },\n        },\n        [`has${capitalize(camelizedName)}Outlet`]: {\n            get() {\n                return this.outlets.has(name);\n            },\n        },\n    };\n}\n\nfunction TargetPropertiesBlessing(constructor) {\n    const targets = readInheritableStaticArrayValues(constructor, \"targets\");\n    return targets.reduce((properties, targetDefinition) => {\n        return Object.assign(properties, propertiesForTargetDefinition(targetDefinition));\n    }, {});\n}\nfunction propertiesForTargetDefinition(name) {\n    return {\n        [`${name}Target`]: {\n            get() {\n                const target = this.targets.find(name);\n                if (target) {\n                    return target;\n                }\n                else {\n                    throw new Error(`Missing target element \"${name}\" for \"${this.identifier}\" controller`);\n                }\n            },\n        },\n        [`${name}Targets`]: {\n            get() {\n                return this.targets.findAll(name);\n            },\n        },\n        [`has${capitalize(name)}Target`]: {\n            get() {\n                return this.targets.has(name);\n            },\n        },\n    };\n}\n\nfunction ValuePropertiesBlessing(constructor) {\n    const valueDefinitionPairs = readInheritableStaticObjectPairs(constructor, \"values\");\n    const propertyDescriptorMap = {\n        valueDescriptorMap: {\n            get() {\n                return valueDefinitionPairs.reduce((result, valueDefinitionPair) => {\n                    const valueDescriptor = parseValueDefinitionPair(valueDefinitionPair, this.identifier);\n                    const attributeName = this.data.getAttributeNameForKey(valueDescriptor.key);\n                    return Object.assign(result, { [attributeName]: valueDescriptor });\n                }, {});\n            },\n        },\n    };\n    return valueDefinitionPairs.reduce((properties, valueDefinitionPair) => {\n        return Object.assign(properties, propertiesForValueDefinitionPair(valueDefinitionPair));\n    }, propertyDescriptorMap);\n}\nfunction propertiesForValueDefinitionPair(valueDefinitionPair, controller) {\n    const definition = parseValueDefinitionPair(valueDefinitionPair, controller);\n    const { key, name, reader: read, writer: write } = definition;\n    return {\n        [name]: {\n            get() {\n                const value = this.data.get(key);\n                if (value !== null) {\n                    return read(value);\n                }\n                else {\n                    return definition.defaultValue;\n                }\n            },\n            set(value) {\n                if (value === undefined) {\n                    this.data.delete(key);\n                }\n                else {\n                    this.data.set(key, write(value));\n                }\n            },\n        },\n        [`has${capitalize(name)}`]: {\n            get() {\n                return this.data.has(key) || definition.hasCustomDefaultValue;\n            },\n        },\n    };\n}\nfunction parseValueDefinitionPair([token, typeDefinition], controller) {\n    return valueDescriptorForTokenAndTypeDefinition({\n        controller,\n        token,\n        typeDefinition,\n    });\n}\nfunction parseValueTypeConstant(constant) {\n    switch (constant) {\n        case Array:\n            return \"array\";\n        case Boolean:\n            return \"boolean\";\n        case Number:\n            return \"number\";\n        case Object:\n            return \"object\";\n        case String:\n            return \"string\";\n    }\n}\nfunction parseValueTypeDefault(defaultValue) {\n    switch (typeof defaultValue) {\n        case \"boolean\":\n            return \"boolean\";\n        case \"number\":\n            return \"number\";\n        case \"string\":\n            return \"string\";\n    }\n    if (Array.isArray(defaultValue))\n        return \"array\";\n    if (Object.prototype.toString.call(defaultValue) === \"[object Object]\")\n        return \"object\";\n}\nfunction parseValueTypeObject(payload) {\n    const { controller, token, typeObject } = payload;\n    const hasType = isSomething(typeObject.type);\n    const hasDefault = isSomething(typeObject.default);\n    const fullObject = hasType && hasDefault;\n    const onlyType = hasType && !hasDefault;\n    const onlyDefault = !hasType && hasDefault;\n    const typeFromObject = parseValueTypeConstant(typeObject.type);\n    const typeFromDefaultValue = parseValueTypeDefault(payload.typeObject.default);\n    if (onlyType)\n        return typeFromObject;\n    if (onlyDefault)\n        return typeFromDefaultValue;\n    if (typeFromObject !== typeFromDefaultValue) {\n        const propertyPath = controller ? `${controller}.${token}` : token;\n        throw new Error(`The specified default value for the Stimulus Value \"${propertyPath}\" must match the defined type \"${typeFromObject}\". The provided default value of \"${typeObject.default}\" is of type \"${typeFromDefaultValue}\".`);\n    }\n    if (fullObject)\n        return typeFromObject;\n}\nfunction parseValueTypeDefinition(payload) {\n    const { controller, token, typeDefinition } = payload;\n    const typeObject = { controller, token, typeObject: typeDefinition };\n    const typeFromObject = parseValueTypeObject(typeObject);\n    const typeFromDefaultValue = parseValueTypeDefault(typeDefinition);\n    const typeFromConstant = parseValueTypeConstant(typeDefinition);\n    const type = typeFromObject || typeFromDefaultValue || typeFromConstant;\n    if (type)\n        return type;\n    const propertyPath = controller ? `${controller}.${typeDefinition}` : token;\n    throw new Error(`Unknown value type \"${propertyPath}\" for \"${token}\" value`);\n}\nfunction defaultValueForDefinition(typeDefinition) {\n    const constant = parseValueTypeConstant(typeDefinition);\n    if (constant)\n        return defaultValuesByType[constant];\n    const hasDefault = hasProperty(typeDefinition, \"default\");\n    const hasType = hasProperty(typeDefinition, \"type\");\n    const typeObject = typeDefinition;\n    if (hasDefault)\n        return typeObject.default;\n    if (hasType) {\n        const { type } = typeObject;\n        const constantFromType = parseValueTypeConstant(type);\n        if (constantFromType)\n            return defaultValuesByType[constantFromType];\n    }\n    return typeDefinition;\n}\nfunction valueDescriptorForTokenAndTypeDefinition(payload) {\n    const { token, typeDefinition } = payload;\n    const key = `${dasherize(token)}-value`;\n    const type = parseValueTypeDefinition(payload);\n    return {\n        type,\n        key,\n        name: camelize(key),\n        get defaultValue() {\n            return defaultValueForDefinition(typeDefinition);\n        },\n        get hasCustomDefaultValue() {\n            return parseValueTypeDefault(typeDefinition) !== undefined;\n        },\n        reader: readers[type],\n        writer: writers[type] || writers.default,\n    };\n}\nconst defaultValuesByType = {\n    get array() {\n        return [];\n    },\n    boolean: false,\n    number: 0,\n    get object() {\n        return {};\n    },\n    string: \"\",\n};\nconst readers = {\n    array(value) {\n        const array = JSON.parse(value);\n        if (!Array.isArray(array)) {\n            throw new TypeError(`expected value of type \"array\" but instead got value \"${value}\" of type \"${parseValueTypeDefault(array)}\"`);\n        }\n        return array;\n    },\n    boolean(value) {\n        return !(value == \"0\" || String(value).toLowerCase() == \"false\");\n    },\n    number(value) {\n        return Number(value.replace(/_/g, \"\"));\n    },\n    object(value) {\n        const object = JSON.parse(value);\n        if (object === null || typeof object != \"object\" || Array.isArray(object)) {\n            throw new TypeError(`expected value of type \"object\" but instead got value \"${value}\" of type \"${parseValueTypeDefault(object)}\"`);\n        }\n        return object;\n    },\n    string(value) {\n        return value;\n    },\n};\nconst writers = {\n    default: writeString,\n    array: writeJSON,\n    object: writeJSON,\n};\nfunction writeJSON(value) {\n    return JSON.stringify(value);\n}\nfunction writeString(value) {\n    return `${value}`;\n}\n\nclass Controller {\n    constructor(context) {\n        this.context = context;\n    }\n    static get shouldLoad() {\n        return true;\n    }\n    static afterLoad(_identifier, _application) {\n        return;\n    }\n    get application() {\n        return this.context.application;\n    }\n    get scope() {\n        return this.context.scope;\n    }\n    get element() {\n        return this.scope.element;\n    }\n    get identifier() {\n        return this.scope.identifier;\n    }\n    get targets() {\n        return this.scope.targets;\n    }\n    get outlets() {\n        return this.scope.outlets;\n    }\n    get classes() {\n        return this.scope.classes;\n    }\n    get data() {\n        return this.scope.data;\n    }\n    initialize() {\n    }\n    connect() {\n    }\n    disconnect() {\n    }\n    dispatch(eventName, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true, } = {}) {\n        const type = prefix ? `${prefix}:${eventName}` : eventName;\n        const event = new CustomEvent(type, { detail, bubbles, cancelable });\n        target.dispatchEvent(event);\n        return event;\n    }\n}\nController.blessings = [\n    ClassPropertiesBlessing,\n    TargetPropertiesBlessing,\n    ValuePropertiesBlessing,\n    OutletPropertiesBlessing,\n];\nController.targets = [];\nController.outlets = [];\nController.values = {};\n\nexport { Application, AttributeObserver, Context, Controller, ElementObserver, IndexedMultimap, Multimap, SelectorObserver, StringMapObserver, TokenListObserver, ValueListObserver, add, defaultSchema, del, fetch, prune };\n", "import { Application } from \"@hotwired/stimulus\"\n\nconst application = Application.start()\n\n// Configure Stimulus development experience\napplication.debug = false\nwindow.Stimulus   = application\n\nexport { application }\n", "import { Controller } from '@hotwired/stimulus';\n\nclass Storage {\n  constructor () {\n    try {\n      window.localStorage.setItem('test', 'test');\n      window.localStorage.removeItem('test');\n      this.available = true;\n    } catch (e) {\n      this.available = false;\n    }\n  }\n\n  read () {\n    return this.available && window.localStorage.gunfinder ? JSON.parse(window.localStorage.gunfinder) : {};\n  }\n\n  write (data) {\n    if (!this.available) {\n      return;\n    }\n\n    window.localStorage.gunfinder = JSON.stringify(data);\n  }\n}\n\nexport default class extends Controller {\n  connect () {\n    this.$storage = new Storage();\n\n    this.$data = { searchHistory: [] };\n    \n    if (this.$storage.available) {\n      this.$data = this.$storage.read();\n    }\n\n    this.$data.searchHistory = this.$data.searchHistory || [];\n\n    this.scope.element.addEventListener('addSearchHistory', (e) => {\n      this.addSearchHistory(e.detail.query);\n    });\n\n    this.authFromUrl();\n\n    this.observeTurboFrames();\n  }\n\n  persist () {\n    this.$storage.write(this.$data);\n    window.$Gunfinder.storage = this.$data;\n  }\n\n  get authController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('#auth-modal'), 'auth');\n  }\n\n  auth (e) {\n    if (window.$Gunfinder.user.signedIn) {\n      return;\n    }\n\n    if (e) {\n      e.preventDefault();\n    }\n\n    this.authController.open({});\n  }\n\n  async signOut (e) {\n    e.preventDefault();\n    const token = await window.castle.createRequestToken();\n    window.location.href = e.params.url + '?castle_request_token=' + token;\n  }\n\n  addSearchHistory (query) {\n    const history = this.$data.searchHistory.map((query) => {\n      return query.toLowerCase();\n    });\n\n    if (query && query !== '' && history.indexOf(query.toLowerCase()) === -1) {\n      this.$data.searchHistory.unshift(query);\n      this.$data.searchHistory = this.$data.searchHistory.slice(0, 8);\n      this.persist();\n    }\n  }\n\n  authFromUrl () {\n    if (window.location.pathname === '/auth') {\n      window.setTimeout(() => {\n        this.auth();\n      }, 1000);\n    }\n  }\n\n  observeTurboFrames () {\n    let\n      href = null,\n      body = null\n    ;\n\n    for (const frame of document.querySelectorAll('turbo-frame')) {\n      frame.addEventListener('turbo:before-fetch-request', (e) => {\n        href = e.detail.url.href;\n        body = e.detail.fetchOptions?.body?.toString().split('&');\n      });\n\n      frame.addEventListener('turbo:frame-missing', async (e) => {\n        const data = {\n          status: e.detail.response.status,\n          redirected: e.detail.response.redirected,\n          redirected_url: e.detail.response.url,\n          text: await e.detail.response.text(),\n          frame: frame.id,\n          href,\n          body\n        };\n\n        if (!window.Sentry) {\n          console.log(data);\n          return;\n        }\n\n        console.log(data);\n        // window.Sentry.addBreadcrumb({\n        //   level: 'warning',\n        //   data,\n        // });\n      });\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['switcher'];\n\n  connect () {\n    this.updateSwitcher.bind(this);\n\n    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n      const scheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n\n      if (this.scheme === 'system')\n        this.colorScheme = scheme;\n    });\n\n    if (document.readyState !== 'loading') {\n      document.documentElement.setAttribute('data-bs-theme', this.colorScheme);\n    } else {\n      window.addEventListener('DOMContentLoaded', () => {\n        document.documentElement.setAttribute('data-bs-theme', this.colorScheme);\n      });\n    }\n    \n    this.updateSwitcher(this.scheme);\n  }\n\n  get schemes () {\n    return {\n      system: {\n        name: 'Auto',\n        icon: 'circle-half'\n      },\n      light: {\n        name: 'Light',\n        icon: 'sun-fill'\n      },\n      dark: {\n        name: 'Dark',\n        icon: 'moon-stars-fill'\n      }\n    }\n  }\n\n  get scheme () {\n    const scheme = window.localStorage.getItem('scheme');\n    return scheme ? scheme : 'system';\n  }\n\n  set scheme (scheme) {\n    window.localStorage.setItem('scheme', scheme);\n    this.colorScheme = scheme;\n  }\n\n  set colorScheme (scheme) {\n    const colorScheme = this.colorSchemeByName(scheme);\n    document.documentElement.setAttribute('data-bs-theme', colorScheme);\n  }\n\n  get colorScheme () {\n    return this.colorSchemeByName(this.scheme);\n  }\n\n  colorSchemeByName (name) {\n    return name !== 'system' ? name : window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n  }\n\n  update (e) {\n    const scheme = e.currentTarget.dataset.scheme;\n    this.scheme = scheme;\n    this.updateSwitcher(scheme);\n  }\n  \n  updateSwitcher (scheme) {\n    if (!this.hasSwitcherTarget) return;\n    \n    const el = this.element.querySelector(`[data-scheme=\"${scheme}\"]`);\n    this.switcherTarget.innerHTML = el.innerHTML;\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static targets = ['init', 'mode'];\n  static values = ['mode'];\n\n  connect () {\n    this.modal = Modal.getOrCreateInstance(this.element);\n    // Keep a stable reference so we can reliably remove it on disconnect.\n    this._boundEvalResponse = this.evalResponse.bind(this);\n    document.addEventListener('turbo:submit-end', this._boundEvalResponse);\n  }\n\n  open ({ mode, callback, redirectPath }) {\n    if (!navigator.cookieEnabled) {\n      return;\n    }\n\n    this.callback = callback;\n    this.redirectPath = redirectPath;\n\n    // Prevent stale auth modal content from being reused via Turbo's page/frame caching.\n    window.Turbo?.cache?.clear?.();\n    const frame = this.element.querySelector('turbo-frame#auth_modal_body');\n    if (frame) frame.innerHTML = '';\n\n    this.modeTarget.value = mode || 'regular';\n    this.initTarget.click();\n\n    this.modal.show();\n  }\n\n  evalResponse () {\n    window.setTimeout(() => {\n      if (this.element.querySelector('.auth-callback')) {\n        this.callCallback();\n      }\n\n      if (this.element.querySelector('.auth-reload-with-timer')) {\n        this.reloadWithTimer();\n      }\n    }, 1000);\n  }\n\n  callCallback () {\n    if (this.callback) {\n      this.callback();\n      this.callback = null;\n    }\n  }\n\n  reload () {\n    this.redirect();\n  }\n\n  reloadWithTimer () {\n    window.setTimeout(() => {\n      this.redirect();\n    }, 6000);\n  }\n\n  redirect () {\n    window.Turbo.cache.clear();\n    \n    if (this.redirectPath) {\n      window.location.href = this.redirectPath;\n    }\n\n    window.location.reload();\n  }\n\n  disconnect () {\n    document.removeEventListener('turbo:submit-end', this._boundEvalResponse);\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport Bss from '@erwinstone/bs-select';\nimport { Dropdown } from 'bootstrap/dist/js/bootstrap.bundle.min.js';\n\nDropdown.prototype.toggle = ((_orginal) => {\n  return function () {\n    if (this._parent.querySelectorAll('.dropdown').length > 0 && !this._parent.dataset.nestedDropdownsAttached) {\n      this._parent.dataset.nestedDropdownsAttached = true;\n      this._element.addEventListener('hide.bs.dropdown', (e) => {\n        if (e.clickEvent?.target?.querySelectorAll(':scope > .dropdown-menu').length > 0 || e.clickEvent?.target?.parentNode?.querySelectorAll(':scope > .dropdown-menu').length > 0) {\n          e.preventDefault();\n        }\n      })\n    }\n\n    return _orginal.call(this);\n  }\n})(Dropdown.prototype.toggle);\n\n\nexport default class extends Controller {\n  connect () {\n    (() => {\n      // bootstrap_form will add an empty option if the select is required and there is no prompt or default value\n      // so to avoid that, we remove the empty option if it exists\n      const option = this.element.querySelector('option');\n\n      if (option && option.value === '' && option.text === '') {\n        option.remove();\n      }\n    })();\n\n    this.dropdown = new Bss(this.element, {\n      labels: {\n        search: 'Suchen ...',\n        noResults: 'Keine Ergebnisse'\n      }\n    });\n\n    this.element.addEventListener('reset', () => {\n      this.dropdown.clear();\n    });\n\n    this.element.addEventListener('enable', () => {\n      this.dropdown.enable();\n    });\n\n    this.element.addEventListener('disable', () => {\n      this.dropdown.disable();\n    });\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static values = { url: String };\n  static targets = ['q', 'exact', 'exclude', 'url'];\n\n  submit (e) {\n    e.preventDefault();\n  }\n\n  search (e) {\n    e.preventDefault();\n\n    let query = this.qTarget.value;\n\n    if (this.exactTarget.value !== '') {\n      query += (query === '' ? '' : ' ') + '\"' + this.exactTarget.value + '\"';\n    }\n\n    if (this.excludeTarget.value !== '') {\n      query += (query === '' ? '' : ' ') + '-' + this.excludeTarget.value.split(' ').join(' -');\n    }\n\n    if (query && query !== '') {\n      Turbo.visit(this.urlValue.replace('_query_', encodeURIComponent(query)));\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  isLocalStorageAvailable () {\n    try {\n      window.localStorage.setItem('test', 'test');\n      window.localStorage.removeItem('test');\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n\n  connect () {\n    if (window.$Gunfinder.user.ua.bot || !this.isLocalStorageAvailable()) {\n      return;\n    }\n\n    this.modal   = Modal.getOrCreateInstance(this.element);\n    this.$policy = null;\n\n    if (window.localStorage.gunfinderCookies !== undefined) {\n      // positive consent is set as early as possible in _head_gf.html.erb\n      // if (window.localStorage.gunfinderCookies === 'true') {\n      //   window.$Gunfinder.gtag('consent', 'update', { 'analytics_storage': 'granted' });\n      // }\n\n      return;\n    }\n    \n    this.modal.show();\n  }\n\n  async loadPrivacyPolicy () {\n    if (!this.$privacyPolicy) {\n      const policy = await window.$Gunfinder.fetch('/privacy?vanilla=true');\n      this.element.querySelector('.cookie-consent-policy').innerHTML = await policy.text();\n      this.$privacyPolicy = true;\n    }\n  }\n\n  async more (e) {\n    e.preventDefault();\n\n    await this.loadPrivacyPolicy();\n    document.getElementById('cookie-consent-more').classList.toggle('d-none');\n    document.getElementById('cookie-consent-anchor').scrollIntoView();\n  }\n\n  accept () {\n    window.localStorage.gunfinderCookies = true;\n    this.modal.hide();\n    window.$Gunfinder.gtag('consent', 'update', { 'analytics_storage': 'granted' });\n  }\n\n  decline () {\n    window.localStorage.gunfinderCookies = false;\n    this.modal.hide();\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['noData'];\n\n  connect () {\n    this.$counter = this.element.querySelectorAll('.col').length;\n\n    if (this.$counter === 0) {\n      this.noDataTarget.classList.remove('d-none');\n    }\n  }\n\n  disappear (e) {\n    e.detail.el.parentElement.remove();\n\n    this.$counter -= 1;\n    if (this.$counter === 0) {\n      this.noDataTarget.classList.remove('d-none');\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['favoriteButton'];\n  static values = {\n    id: Number,\n    searchId: Number,\n    searchQuery: String,\n    fwd: {\n      type: Boolean,\n      default: false,\n    },\n  };\n\n  connect () {\n    this.evalFavorite();\n    this.element.addEventListener('click', this.click.bind(this)); // only execute if is a link\n  }\n\n  async click (e) {\n    if (!window.$Gunfinder.app && this.element.nodeName === 'A' && this.searchQueryValue) {\n      e.preventDefault();\n\n      const\n        url = `${this.element.getAttribute('href')}?query=${this.searchQueryValue}${this.fwdValue ? `&source=search_result` : ''}`,\n        tab = window.open(url, '_blank')\n      ;\n\n      if (tab) {\n        tab.focus();\n      } else {\n        window.Turbo.visit(url);\n      }\n    }\n\n    if (this.searchIdValue && this.searchIdValue > 0) {\n      await window.$Gunfinder.fetch(`/search/convert?search_id=${this.searchIdValue}&item_id=${this.idValue}`, { method: 'POST' });\n    }\n  }\n\n  isFavorite () {\n    return window.$Gunfinder.user.favorites.indexOf(this.idValue) > -1;\n  }\n\n  get appController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('body'), 'app');\n  }\n\n  ext (e) {\n    e.preventDefault();\n\n    const\n      url = `${e.params.href}`,\n      tab = window.open(url, '_blank')\n    ;\n\n    if (tab) {\n      tab.focus();\n    } else {\n      window.Turbo.visit(url);\n    }\n  }\n\n  toggleFavorite (e) {\n    e.preventDefault();\n\n    const exec = () => {\n      window.$Gunfinder.fetch(`/profile/favorites/${this.idValue}/toggle`);\n\n      let i;\n      if ((i = window.$Gunfinder.user.favorites.indexOf(this.idValue)) > -1) {\n        window.$Gunfinder.user.favorites.splice(i, 1);\n      } else {\n        window.$Gunfinder.user.favorites.push(this.idValue);\n      }\n    };\n\n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'favorite', callback: () => {\n        exec();\n        this.evalFavorite();\n      } });\n\n      return;\n    }\n    \n    exec();\n    this.evalFavorite();\n\n    if (!this.isFavorite()) {\n      this.dispatch('unfavorited', { detail: { el: this.element } });\n    }\n  }\n\n  evalFavorite () {\n    if (this.isFavorite()) {\n      this.element.classList.add('favorite');\n    } else {\n      this.element.classList.remove('favorite');\n    }\n  }\n\n  async share (e) {\n    e?.preventDefault?.();\n\n    if (!('share' in navigator)) return;\n\n    const { title, text, url } = e.params;\n\n    try {\n      await navigator.share({ title, text, url });\n    } catch (err) {\n      // User cancelled or share failed; ignore to avoid noisy UI.\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static values = { messagePath: String, meta: Object };\n\n  connect () {\n    if (window.$Gunfinder.user.signedIn) {\n      this.messageModal = Modal.getOrCreateInstance(document.getElementById('message-modal'));\n\n      if (document.getElementById('tx-buynow-modal')) {\n        this.buyModal = Modal.getOrCreateInstance(document.getElementById('tx-buynow-modal'));\n      }\n\n      document.getElementById('message-modal').addEventListener('show.bs.modal', () => {\n        window.setTimeout(() => { document.getElementById('message_body').focus() }, 500);\n      });\n    }\n    \n    if (window.$Gunfinder.user.signedIn && window.location.hash === '#message') {\n      this.messageModal.show();\n    }\n\n    if (window.$Gunfinder.user.signedIn && window.location.hash === '#buynow') {\n      this.buyModal.show();\n    }\n  }\n\n  get appController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('body'), 'app');\n  }\n\n  message () {\n    window.$Gunfinder.track('listings: internal clicked', this.metaValue);\n\n    if (this.messagePathValue != '') {\n      window.Turbo.visit(this.messagePathValue);\n      return;\n    }\n    \n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'listing-message', redirectPath: `${window.location.pathname}#message` });\n      return;\n    }\n\n    this.messageModal.show();\n  }\n\n  buyNow () {\n    window.$Gunfinder.track('listings: internal clicked', this.metaValue);\n\n    if (this.messagePathValue != '') {\n      window.Turbo.visit(this.messagePathValue);\n      return;\n    }\n\n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'listing-buynow', redirectPath: `${window.location.pathname}#buynow` });\n      return;\n    }\n\n    this.buyModal.show();\n  }\n\n  messageSuggestion (e) {\n    e.currentTarget.closest('.modal-body').querySelector('textarea').value = e.currentTarget.innerText;\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static values = { messagePath: String, meta: Object };\n\n  connect () {\n    if (window.$Gunfinder.user.signedIn) {\n      if (document.getElementById('bid-modal')) {\n        this.bidModal = Modal.getOrCreateInstance(document.getElementById('bid-modal'));\n\n        document.getElementById('bid-modal').addEventListener('shown.bs.modal', () => {\n          document.getElementById('bid_value')?.focus();\n        });\n      }\n\n      if (document.getElementById('tx-buynow-modal')) {\n        this.buyNowModal = Modal.getOrCreateInstance(document.getElementById('tx-buynow-modal'));\n      }\n      \n      this.messageModal = Modal.getOrCreateInstance(document.getElementById('message-modal'));\n\n      document.getElementById('message-modal').addEventListener('show.bs.modal', () => {\n        window.setTimeout(() => { document.getElementById('message_body').focus() }, 500);\n      });\n    }\n    \n    if (window.$Gunfinder.user.signedIn) {\n      if (window.location.hash === '#bid') {\n        this.bidModal?.show();\n      }\n\n      if (window.location.hash === '#message') {\n        this.messageModal?.show();\n      }\n    }\n  }\n\n  get appController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('body'), 'app');\n  }\n\n  message () {\n    if (this.messagePathValue != '') {\n      window.Turbo.visit(this.messagePathValue);\n      return;\n    }\n    \n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'auction-message', redirectPath: `${window.location.pathname}#message` });\n      return;\n    }\n\n    this.messageModal.show();\n  }\n\n  bid () {\n    window.$Gunfinder.track('auctions: internal clicked', this.metaValue);\n\n    if (this.messagePathValue != '') {\n      window.Turbo.visit(this.messagePathValue);\n      return;\n    }\n\n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'auction-bid', redirectPath: `${window.location.pathname}#bid` });\n      return;\n    }\n\n    this.bidModal.show();\n  }\n\n  buyNow () {\n    window.$Gunfinder.track('auctions: buynow clicked', this.metaValue);\n\n    if (this.messagePathValue != '') {\n      window.Turbo.visit(this.messagePathValue);\n      return;\n    }\n\n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'auction-buynow', redirectPath: `${window.location.pathname}#buynow` });\n      return;\n    }\n\n    this.buyNowModal.show();\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Offcanvas } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static targets = ['frame', 'orders', 'conversation', 'orderFrame', 'offcanvas'];\n  \n  connect () {\n    this.setHeights();\n    this.orderFrameTarget.addEventListener('turbo:frame-load', this.onFrameLoad.bind(this));\n  }\n\n  onFrameLoad (event) {\n    this.setHeights();\n\n    const titleEl = this.orderFrameTarget.querySelector('[data-turbo-title]');\n    if (titleEl) {\n      const title = titleEl.getAttribute('data-turbo-title');\n      document.title = title + ' - Gunfinder';\n    }\n  }\n\n  setHeights () {\n    if (this.hasConversationTarget) {\n      this.conversationTarget.style.height = (window.outerHeight / 2) + 'px';\n    }\n\n    // this.element.style.height = ''; // reset to allow for proper height calculation\n    // this.element.style.height = this.orderFrameTarget.scrollHeight + 'px';\n    this.frameTarget.style.height = ''; // reset to allow for proper height calculation\n    this.frameTarget.style.height = this.orderFrameTarget.scrollHeight + 'px';\n\n    // this.ordersTarget.scrollTop = this.ordersScrollPosition || 0;\n    // this.ordersTarget.scrollTo({ top: this.ordersScrollPosition, behavior: 'smooth' });\n\n    window.setTimeout(() => {\n      this.currentOrderElement?.scrollIntoView({ behavior: 'auto', block: 'center' });\n\n      if (this.hasConversationTarget) {\n        this.conversationTarget.scrollTop = this.conversationTarget.scrollHeight;\n      }\n    }, 100);\n  }\n\n  setOrder (event) {\n    this.currentOrderElement = event.currentTarget;\n\n    for (const orderTarget of this.ordersTargets) {\n      orderTarget.querySelectorAll('a.bg-body-secondary').forEach(a => {\n        a.classList.remove('bg-body-secondary');\n        a.classList.add('bg-body');\n      });\n    }\n\n    this.ordersTarget.querySelectorAll('a.bg-body-secondary').forEach(a => {\n      a.classList.remove('bg-body-secondary');\n      a.classList.add('bg-body');\n    });\n\n    event.currentTarget.classList.add('bg-body-secondary');\n    event.currentTarget.classList.remove('bg-body');\n\n    event.currentTarget.querySelector('.position-relative span.position-absolute')?.remove();\n\n    Offcanvas.getOrCreateInstance(this.offcanvasTarget).hide();\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  connect () {\n    this.shortcut();\n  }\n\n  shortcut () {\n    this.element.querySelector('textarea').addEventListener('keydown', (e) => {\n      if ((e.metaKey || e.ctrlKey) && e.keyCode === 13) {\n        this.element.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); // yes ...\n      }\n    });\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['button', 'ghost'];\n\n  connect () {\n    this.buttonTarget.addEventListener('click', (e) => {\n      this.ghostTarget.classList.remove('d-none');\n      this.buttonTarget.remove();\n    });  \n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static values = { modalId: String };\n\n  connect () {\n    if (this.hasModalIdValue) {\n      this.modal = Modal.getOrCreateInstance(document.getElementById(this.modalIdValue));\n    } else {\n      this.modal = Modal.getOrCreateInstance(document.getElementById('delete-modal'));\n    }\n\n    if (window.location.hash == '#delete') {\n      this.modal.show();\n    }\n\n    for (const el of this.element.querySelectorAll('input[type=\"radio\"]')) {\n      el.addEventListener('change', () => {\n        this.element.querySelector('button[type=\"submit\"]').disabled = false;\n      });\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  connect () {\n    this.modal = Modal.getOrCreateInstance(this.element);\n    \n    for (const el of this.element.querySelectorAll('input[type=\"radio\"]')) {\n      el.addEventListener('change', () => {\n        this.element.querySelector('button[type=\"submit\"]').disabled = false;\n      });\n    }\n\n    this.element.querySelector('form').addEventListener('turbo:submit-end', (e) => {\n      for (const obj of this.element.querySelectorAll('.step1')) {\n        obj.classList.add('d-none');\n      }\n\n      if (e.detail.fetchResponse.response.status === 200) {\n        this.element.querySelector('.step2').classList.remove('d-none');\n      } else {\n        this.element.querySelector('.step3').classList.remove('d-none');\n      }\n\n      window.setTimeout(() => {\n        this.modal.hide();\n      }, 6000);\n    });\n  }\n\n  open () {\n    this.modal.show();\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['moreButton', 'lessButton', 'shortComment', 'comment', 'ratings'];\n\n  open (e) {\n    e.preventDefault();\n\n    this.shortCommentTarget.classList.add('d-none');\n    this.commentTarget.classList.remove('d-none');\n    this.moreButtonTarget.classList.add('d-none');\n    this.lessButtonTarget.classList.remove('d-none');\n\n    if (this.hasRatingsTarget) {\n      this.ratingsTarget.classList.remove('d-none');\n    }\n  }\n\n  close (e) {\n    e.preventDefault();\n\n    this.shortCommentTarget.classList.remove('d-none');\n    this.commentTarget.classList.add('d-none');\n    this.moreButtonTarget.classList.remove('d-none');\n    this.lessButtonTarget.classList.add('d-none');\n\n    if (this.hasRatingsTarget) {\n      this.ratingsTarget.classList.add('d-none');\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['rating', 'details', 'comment'];\n\n  get appController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('body'), 'app');\n  }\n\n  connect () {\n    this.showDetails();\n  }\n\n  rate (e) {\n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'user' });\n      e.preventDefault();\n      return;\n    }\n\n    this.showDetails();\n  }\n\n  showDetails () {\n    let rated = true;\n    for (const rating of this.ratingTargets) {\n      if (rating.querySelectorAll('input:checked').length === 0){\n        rated = false;\n      }\n    }\n\n    if (rated) {\n      this.detailsTarget.classList.remove('d-none');\n\n      window.setTimeout(() => {\n        this.commentTarget.focus();\n      }, 100);\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  connect () {\n    this.oembed();\n    this.pdf();\n  }\n\n  script (src, onload) {\n    const script = document.createElement('script');\n    script.src = src;\n    script.setAttribute('async', true);\n    script.onload = onload;\n    document.head.appendChild(script);\n  }\n\n  pdf () {\n    const onload = () => {\n      for (const el of this.element.querySelectorAll('.pdfobject')) {\n        PDFObject.embed(el.getAttribute('data-url'), el, {\n          fallbackLink: `<div class=\"text-center\"><a href=\"${el.getAttribute('data-url')}\" class=\"btn btn-warning\">Datei ansehen</a></div>`,\n          height: '25rem'\n        });\n      }\n    };\n\n    if (this.element.querySelectorAll('.pdfobject').length > 0) {\n      this.script('https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.2.6/pdfobject.min.js', onload);\n    }\n  }\n\n  isInstagramUrl (url) {\n    try {\n      const urlObj = new URL(url);\n      return urlObj.hostname.includes('instagram.com') || urlObj.hostname.includes('instagr.am');\n    } catch (e) {\n      return false;\n    }\n  }\n\n  createInstagramEmbed (url) {\n    // Normalize Instagram URL (remove query params like ?img_index=1)\n    let normalizedUrl = url;\n    try {\n      const urlObj = new URL(url);\n      normalizedUrl = `${urlObj.protocol}//${urlObj.hostname}${urlObj.pathname}`;\n    } catch (e) {\n      // If URL parsing fails, use original\n    }\n\n    // Instagram uses blockquote embeds with their embed.js script\n    const blockquote = document.createElement('blockquote');\n    blockquote.className = 'instagram-media';\n    blockquote.setAttribute('data-instgrm-permalink', normalizedUrl);\n    blockquote.setAttribute('data-instgrm-version', '14');\n\n    // Load Instagram's embed script if not already loaded\n    if (!document.querySelector('script[src*=\"instagram.com/embed.js\"]')) {\n      this.script('https://www.instagram.com/embed.js', () => {\n        // Process embeds after script loads\n        if (window.instgrm && window.instgrm.Embeds) {\n          window.instgrm.Embeds.process();\n        }\n      });\n    } else if (window.instgrm && window.instgrm.Embeds) {\n      // Script already loaded, process immediately\n      setTimeout(() => {\n        if (window.instgrm && window.instgrm.Embeds) {\n          window.instgrm.Embeds.process();\n        }\n      }, 100);\n    }\n\n    return blockquote;\n  }\n\n  makeEmbedResponsive (htmlContent) {\n    // Create a temporary container to parse and modify the HTML\n    const tempDiv = document.createElement('div');\n    tempDiv.innerHTML = htmlContent;\n\n    // Find all iframes and other embed elements\n    const iframes = tempDiv.querySelectorAll('iframe');\n    iframes.forEach(iframe => {\n      // Remove width and height attributes\n      iframe.removeAttribute('width');\n      iframe.removeAttribute('height');\n      \n      // Set responsive styles - width 100%, height auto with aspect ratio\n      iframe.style.width = '100%';\n      iframe.style.height = 'auto';\n      iframe.style.aspectRatio = '16 / 9'; // Default aspect ratio for video embeds\n      iframe.style.display = 'block';\n      iframe.style.maxWidth = '100%';\n    });\n\n    // Also check for other common embed elements (embed, object, etc.)\n    const embedElements = tempDiv.querySelectorAll('embed, object, video');\n    embedElements.forEach(el => {\n      el.removeAttribute('width');\n      el.removeAttribute('height');\n      el.style.width = '100%';\n      el.style.height = 'auto';\n      el.style.aspectRatio = '16 / 9';\n      el.style.display = 'block';\n      el.style.maxWidth = '100%';\n    });\n\n    return tempDiv.innerHTML;\n  }\n\n  replaceOembedElement (oembed, htmlContent) {\n    // Make the embed responsive\n    const responsiveHtml = this.makeEmbedResponsive(htmlContent);\n    \n    // Create a wrapper div to replace the oembed element\n    const wrapper = document.createElement('div');\n    wrapper.innerHTML = responsiveHtml;\n    wrapper.style.width = '100%';\n    \n    // Replace the oembed element with the embedded content\n    if (oembed.parentNode.tagName === 'FIGURE') {\n      // If oembed is inside a figure, replace the oembed element within it\n      oembed.replaceWith(...wrapper.childNodes);\n    } else {\n      // Otherwise, replace the oembed element directly\n      oembed.replaceWith(wrapper.firstElementChild || wrapper);\n    }\n  }\n\n  async oembed () {\n    const oembedElements = this.element.querySelectorAll('oembed[url]');\n    \n    if (oembedElements.length === 0) {\n      return;\n    }\n\n    for (const oembed of oembedElements) {\n      const url = oembed.getAttribute('url');\n      if (!url) continue;\n\n      try {\n        const encodedUrl = encodeURIComponent(url);\n        const response = await fetch(`https://noembed.com/embed?url=${encodedUrl}`);\n        const data = await response.json();\n\n        // If noembed returns an error for Instagram URLs, use Instagram's native embed\n        if (data.error && this.isInstagramUrl(url)) {\n          const instagramEmbed = this.createInstagramEmbed(url);\n          oembed.replaceWith(instagramEmbed);\n          continue;\n        }\n\n        if (data.html) {\n          this.replaceOembedElement(oembed, data.html);\n        } else {\n          console.error('Noembed: No HTML content returned for', url, data);\n        }\n      } catch (error) {\n        console.error('Noembed: Failed to embed', url, error);\n      }\n    }\n  }\n}\n", "// https://github.com/Outleap/bootstrap-5-autocomplete\nimport { Dropdown } from \"bootstrap/dist/js/bootstrap.bundle.min\";\n\nconst DEFAULTS = {\n  threshold: 2,\n  maximumItems: 5,\n  highlightTyped: true,\n  highlightClass: 'text-primary',\n  label: 'label',\n  value: 'value',\n  showValue: false,\n  showValueBeforeLabel: false,\n};\n\nclass Autocomplete {\n  constructor(field, options) {\n    this.field = field;\n    this.options = Object.assign({}, DEFAULTS, options);\n    this.dropdown = null;\n\n    field.parentNode.classList.add('dropdown');\n    field.setAttribute('data-bs-toggle', 'dropdown');\n    field.classList.add('dropdown-toggle');\n\n    const dropdown = ce(`<div class=\"dropdown-menu\"></div>`);\n    if (this.options.dropdownClass)\n      dropdown.classList.add(this.options.dropdownClass);\n\n    insertAfter(dropdown, field);\n\n    this.dropdown = new Dropdown(field, this.options.dropdownOptions);\n\n    field.addEventListener('click', (e) => {\n      if (this.createItems() === 0) {\n        e.stopPropagation();\n        this.dropdown.hide();\n      }\n    });\n\n    field.addEventListener('input', () => {\n      if (this.options.onInput)\n        this.options.onInput(this.field.value);\n      this.renderIfNeeded();\n    });\n\n    field.addEventListener('keydown', (e) => {\n      if (e.keyCode === 27) {\n        this.dropdown.hide();\n        return;\n      }\n      if (e.keyCode === 40) {\n        this.dropdown._menu.children[0]?.focus();\n        return;\n      }\n    });\n  }\n\n  setData(data) {\n    this.options.data = data;\n    this.renderIfNeeded();\n  }\n\n  renderIfNeeded() {\n    if (this.createItems() > 0)\n      this.dropdown.show();\n    else\n      this.field.click();\n  }\n\n  createItem(lookup, item) {\n    let label;\n\n    const idx = removeDiacritics(item.value)\n      .toLowerCase()\n      .indexOf(removeDiacritics(lookup).toLowerCase())\n    ;\n\n    const className = Array.isArray(this.options.highlightClass) ? this.options.highlightClass.join(' ')\n      : (typeof this.options.highlightClass == 'string' ? this.options.highlightClass : '');\n\n    label = item.value.substring(0, idx)\n      + `<span class=\"${className}\">${item.value.substring(idx, idx + lookup.length)}</span>`\n      + item.value.substring(idx + lookup.length, item.value.length);\n\n    label = item.label.replace('%{label}', label);\n    return ce(`<button type=\"button\" class=\"dropdown-item\" data-value=\"${item.value}\">${label}</button>`);\n    // return ce(`<button type=\"button\" class=\"dropdown-item\" data-label=\"${item.label}\" data-value=\"${item.value}\">${label}</button>`);\n  }\n\n  createItems() {\n    const lookup = this.field.value;\n    if (lookup.length < this.options.threshold) {\n      this.dropdown.hide();\n      return 0;\n    }\n\n    const items = this.field.nextSibling;\n    items.innerHTML = '';\n\n    const keys = Object.keys(this.options.data);\n\n    let count = 0;\n    for (let i = 0; i < keys.length; i++) {\n      const key = keys[i];\n      const entry = this.options.data[key];\n      const item = {\n          label: this.options.label ? entry[this.options.label] : key,\n          value: this.options.value ? entry[this.options.value] : entry\n      };\n\n      if (removeDiacritics(item.value).toLowerCase().indexOf(removeDiacritics(lookup).toLowerCase()) >= 0) {\n        items.appendChild(this.createItem(lookup, item));\n        if (this.options.maximumItems > 0 && ++count >= this.options.maximumItems)\n          break;\n      }\n    }\n\n    this.field.nextSibling.querySelectorAll('.dropdown-item').forEach((item) => {\n      item.addEventListener('click', (e) => {\n        let dataLabel = e.currentTarget.getAttribute('data-label');\n        let dataValue = e.currentTarget.getAttribute('data-value');\n\n        this.field.value = dataLabel;\n\n        if (this.options.onSelectItem) {\n          this.options.onSelectItem({\n            value: dataValue,\n            label: dataLabel\n          });\n        }\n\n        this.dropdown.hide();\n      })\n    });\n\n    return items.childNodes.length;\n  }\n}\n\n/**\n * @param html\n * @returns {Node}\n */\nfunction ce(html) {\n  let div = document.createElement('div');\n  div.innerHTML = html;\n  return div.firstChild;\n}\n\n/**\n * @param elem\n * @param refElem\n * @returns {*}\n */\nfunction insertAfter(elem, refElem) {\n  return refElem.parentNode.insertBefore(elem, refElem.nextSibling);\n}\n\n/**\n * @param {String} str\n * @returns {String}\n */\nfunction removeDiacritics(str) {\n  return str\n      .normalize('NFD')\n      .replace(/[\\u0300-\\u036f]/g, '');\n}\n\nexport default Autocomplete;\n", "import { Controller } from '@hotwired/stimulus';\n\nimport Autocomplete from '../utils/autocomplete';\n\nexport default class extends Controller {\n  static values = { apiUrl: String };\n\n  get appController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('body'), 'app');\n  }\n\n  connect () {\n    const $this = this;\n\n    this.autocomplete = new Autocomplete(this.element, {\n      dropdownClass: 'w-100',\n      data: [],\n      threshold: 0,\n      maximumItems: 10,\n      onSelectItem ({ value }) {\n        $this.element.value = value;\n        $this.element.dispatchEvent(new Event('search-autocomplete.selected'));\n        \n        if ($this.element.closest('form')) {\n          $this.element.closest('form').submit();\n        }\n\n        $this.appController.addSearchHistory(value);\n      }\n    });\n\n    this.renderSuggestions();\n    this.element.addEventListener('input', this.renderSuggestions.bind(this));\n  }\n\n  async renderSuggestions (e) {\n    const suggestions = await this.fetchSuggestions();\n\n    if (!suggestions) return;\n\n    const data = suggestions.map((suggestion, i) => {\n      return {\n        label: `<i class=\"bi bi-${suggestion.id ? 'search' : 'clock-history'}\"></i> <span class=\"ms-1\">%{label}</span>`,\n        value: suggestion.query\n      };\n    });\n\n    if (!e) {\n      this.autocomplete.options.data = data;\n    } else {\n      this.autocomplete.setData(data);\n    }\n  }\n\n  async fetchSuggestions () {\n    const query = this.element.value;\n\n    if (!query || query === '') {\n      return this.appController.$data.searchHistory.map((query) => {\n        return { query };\n      });\n    }\n\n    const request = await window.$Gunfinder.fetch(this.apiUrlValue + '?query=' + encodeURIComponent(query));\n    return request?.status == 200 ? request.json() : null;\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport qs from 'qs';\nimport { Base64 } from 'js-base64';\n\nexport default class extends Controller {\n  static targets = ['suggestion', 'form', 'metaForm', 'results', 'marketplace', 'scategories', 'scope', 'category', 'condition', 'kind', 'restricted', 'calibers', 'dealers', 'price', 'country', 'geo', 'discount', 'availability', 'lefty', 'resetAll', 'sort', 'sortDistance', 'layoutGrid', 'layoutList'];\n  static values  = {\n    queriable: {\n      type: Boolean,\n      default: false,\n    },\n    windowTitle: String,\n  };\n\n  get appController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('body'), 'app');\n  }\n\n  connect () {\n    this.filters = [];\n    this.resets  = {};\n\n    this.searchbox = document.querySelector('.searchbox input');\n\n    this.useFilter.bind(this);\n    this.addReset.bind(this);\n\n    this.query();\n\n    this.suggestion();\n\n    this.marketplace();\n    this.condition();\n    this.kind();\n    this.restricted();\n    this.calibers();\n    this.dealers();\n    this.price();\n    this.country();\n    this.geo();\n    this.discount();\n    this.availability();\n    this.lefty();\n\n    this.scategories();\n\n    this.sort();\n\n    this.layout();\n\n    // this.autoPage();\n  }\n\n  resultsTargetConnected () {\n    !this.resultsTargetConnectedCounter ? this.resultsTargetConnectedCounter = 1 : this.resultsTargetConnectedCounter += 1;\n\n    window.$Gunfinder.Adhunter.load();\n    \n    this.page();\n\n    if (this.resultsTargetConnectedCounter > 1)\n      this.urlHistory();\n  }\n\n  urlHistory () {\n    const obj = JSON.parse(Base64.decode(this.resultsTarget.dataset.filter));\n\n    if (obj.query === '*')\n      delete obj.query;\n\n    if (Object.keys(obj).length === 0)\n      return;\n    \n    const query = qs.stringify(obj, { arrayFormat: 'brackets' });\n    window.history.replaceState(null, null, `${window.location.pathname}?${query}`)\n  }\n\n  addReset (name, exec) {\n    this.resets[name] = () => {\n      exec();\n      this.useFilter(name, false);\n    };\n\n    const el = this[`${name}Target`].querySelector('i.reset');\n\n    if (el) {\n      el.addEventListener('click', (e) => {\n        e.preventDefault();\n        this.resets[name]();\n        el.classList.add('d-none');\n        this.search();\n      });\n    }\n  }\n\n  useFilter (name, used) {\n    const target = name.charAt(0).toUpperCase() + name.slice(1);\n\n    if (this[`has${target}Target`]) {\n      const el = this[`${name}Target`].querySelector('i.reset');\n\n      if (used) {\n        if (el) {\n          el.classList.remove('d-none');\n        }\n\n        this.filters.push(name);\n      } else {\n        if (el) {\n          el.classList.add('d-none');\n        }\n        \n        this.filters = this.filters.filter((val) => { \n          return val !== name;\n        });\n      }\n    }\n\n    this.resetAllTarget.disabled = this.filters.length === 0;\n    if (this.resetAllTarget.disabled) {\n      this.resetAllTarget.classList.replace('btn-danger', 'btn-light');\n    } else {\n      this.resetAllTarget.classList.replace('btn-light', 'btn-danger');\n    }\n  }\n\n\n  setQueryValue () {\n    const value = (this.searchbox.value || '').trim();\n\n    if (value.length <= 1) return;\n\n    this.formTarget.querySelector('input[name=\"query\"]').value     = value;\n\n    if (this.hasMetaFormTarget) {\n      this.metaFormTarget.querySelector('input[name=\"query\"]').value = value;\n    }\n  }\n\n  query () {\n    if (!this.queriableValue)\n      return;\n\n    this.searchbox.addEventListener('input', () => {\n      this.setQueryValue();\n      this.search({ debounce: 300, scrollIntoView: false });\n      this.metaSearch({ debounce: 300 });\n    });\n\n    this.searchbox.addEventListener('search-autocomplete.selected', () => {\n      this.setQueryValue();\n      this.search();\n      this.metaSearch();\n    });\n  }\n\n  suggestion () {\n    if (!this.hasSuggestionTarget) return;\n\n    this.suggestionTarget.querySelector('a').addEventListener('click', (e) => {\n      e.preventDefault();\n\n      this.searchbox.value = e.currentTarget.innerText;\n      this.searchbox.dispatchEvent(new Event('input'));\n    });\n  }\n\n  setScope (e) {\n    this.scategoriesTarget.querySelector('input[name=\"category\"]').value = null;\n    this.scategoriesTarget.querySelector('input[name=\"scope\"]').value    = e.params.scope;\n\n    this.useFilter('scategories', true);\n\n    this.search();\n  }\n\n  setCategory (e) {\n    this.scategoriesTarget.querySelector('input[name=\"scope\"]').value    = null;\n    this.scategoriesTarget.querySelector('input[name=\"category\"]').value = e.params.categoryId ? e.params.categoryId : null;\n\n    this.useFilter('scategories', !!e.params.categoryId);\n\n    this.search();\n  }\n\n  scategories () {\n    this.scategoriesTarget.querySelector('turbo-frame').addEventListener('turbo:frame-load', () => {\n      this.scopesAndCategories();\n\n      this.addReset('scategories', () => {\n        this.scategoriesTarget.querySelector('a.reset').click();\n      });\n    });\n  }\n\n  scopesAndCategories () {\n    this.useFilter('scategories', this.hasScopeTarget || this.hasCategoryTarget);\n  }\n\n  marketplace () {\n    this.addReset('marketplace', () => {\n      this.marketplaceTarget.querySelector('input[type=\"checkbox\"]').checked = false;\n    });\n\n    this.useFilter('marketplace', this.marketplaceTarget.querySelector('input[type=\"checkbox\"]').checked);\n\n    this.marketplaceTarget.querySelector('input[type=\"checkbox\"]').addEventListener('change', () => {\n      this.useFilter('marketplace', this.marketplaceTarget.querySelector('input[type=\"checkbox\"]').checked);\n      this.search();\n    });\n  }\n\n  condition () {\n    this.addReset('condition', () => {\n      this.conditionTarget.querySelector('select').dispatchEvent(new Event('reset'));\n    });\n\n    this.useFilter('condition', this.conditionTarget.querySelector('select option:checked').value !== '');\n\n    this.conditionTarget.querySelector('select').addEventListener('change', () => {\n      this.useFilter('condition', this.conditionTarget.querySelector('select option:checked').value !== '');\n      this.search();\n    });\n  }\n\n  kind () {\n    this.addReset('kind', () => {\n      this.kindTarget.querySelector('select').dispatchEvent(new Event('reset'));\n    });\n\n    this.useFilter('kind', this.kindTarget.querySelector('select option:checked').value !== '');\n\n    this.kindTarget.querySelector('select').addEventListener('change', () => {\n      this.useFilter('kind', this.kindTarget.querySelector('select option:checked').value !== '');\n      this.search();\n    });\n  }\n\n  restricted () {\n    this.addReset('restricted', () => {\n      this.restrictedTarget.querySelector('select').dispatchEvent(new Event('reset'));\n    });\n\n    this.useFilter('restricted', this.restrictedTarget.querySelector('select option:checked').value !== '');\n\n    this.restrictedTarget.querySelector('select').addEventListener('change', () => {\n      this.useFilter('restricted', this.restrictedTarget.querySelector('select option:checked').value !== '');\n      this.search();\n    });\n  }\n\n  calibers () {\n    this.addReset('calibers', () => {\n      this.calibersTarget.querySelector('select').dispatchEvent(new Event('reset'));\n    });\n\n    this.useFilter('calibers', this.calibersTarget.querySelectorAll('select option:checked').length > 0);\n\n    this.calibersTarget.querySelector('select').addEventListener('change', () => {\n      this.useFilter('calibers', this.calibersTarget.querySelectorAll('select option:checked').length > 0);\n      this.search();\n    });\n  }\n\n  dealers () {\n    this.addReset('dealers', () => {\n      this.dealersTarget.querySelector('select').dispatchEvent(new Event('reset'));\n    });\n\n    this.useFilter('dealers', this.dealersTarget.querySelectorAll('select option:checked').length > 0);\n\n    this.dealersTarget.querySelector('select').addEventListener('change', () => {\n      this.useFilter('dealers', this.dealersTarget.querySelectorAll('select option:checked').length > 0);\n      this.search();\n    });\n  }\n\n  price () {\n    const\n      min   = this.priceTarget.querySelector('input[name=\"price[min]\"]'),\n      max   = this.priceTarget.querySelector('input[name=\"price[max]\"]')\n    ;\n\n    this.addReset('price', () => {\n      min.value = '';\n      max.value = '';\n    });\n\n    this.useFilter('price', min.value.length > 0 || max.value.length > 0);\n\n    for (const el of [min, max]) {\n      el.addEventListener('input', () => {\n        el.value = el.value.replace(/[^\\d]/, '');\n        this.useFilter('price', min.value.length > 0 || max.value.length > 0);\n\n        this.search();\n      });\n    }\n  }\n\n  country () {\n    const toggleGeo = (disable) => {\n      if (disable) {\n        this.geoTarget.querySelector('input[name=\"geo[postal_code]\"]').value = '';\n        this.resets.geo();\n      }\n\n      this.geoTarget.querySelector('input[name=\"geo[postal_code]\"]').disabled = disable;\n      this.geoTarget.querySelector('select[name=\"geo[radius]\"]').disabled     = disable;\n      this.geoTarget.querySelector('select[name=\"geo[radius]\"]').dispatchEvent(new Event(disable ? 'disable' : 'enable'));\n    };\n\n    this.addReset('country', () => {\n      this.countryTarget.querySelector('select').dispatchEvent(new Event('reset'));\n      toggleGeo(true);\n    });\n\n    this.useFilter('country', this.countryTarget.querySelector('select option:checked').value !== '');\n\n    if (this.countryTarget.querySelector('select option:checked').value != '') {\n      toggleGeo(false);\n    }\n\n    this.countryTarget.querySelector('select').addEventListener('change', () => {\n      const used = this.countryTarget.querySelector('select option:checked').value !== '';\n      this.useFilter('country', used);\n      toggleGeo(!used);\n\n      this.search();\n    });\n  }\n\n  geo () {\n    const\n      used = () => {\n        return this.geoTarget.querySelector('input').value.length > 0 ||\n          this.geoTarget.querySelector('select[name=\"geo[radius]\"] option:checked').value != '25'\n        ;\n      },\n      validPostalCode = () => {\n        const pattern = this.countryTarget.querySelector('select option:checked').value == 'DE' ? /^\\d{5}$/ : /^\\d{4}$/;\n        return pattern.test(this.geoTarget.querySelector('input').value.trim());\n      }\n    ;\n\n    this.addReset('geo', () => {\n      this.geoTarget.querySelector('input').value = '';\n      for (const el of this.geoTarget.querySelectorAll('select')) {\n        el.dispatchEvent(new Event('reset'));\n      }\n\n      this.sortDistanceTarget.disabled = true;\n      if (this.formTarget.querySelector('input[name=\"sort\"]').value === 'distance-asc') this.resets.sort();\n    });\n\n    this.useFilter('geo', used());\n\n    this.geoTarget.querySelector('input').addEventListener('input', () => {\n      this.useFilter('geo', used());\n\n      if (validPostalCode() || this.geoTarget.querySelector('input').value.length == 0) {\n        this.search();\n        \n        if (this.geoTarget.querySelector('input').value.length == 0) {\n          this.sortDistanceTarget.disabled = true;\n\n          if (this.formTarget.querySelector('input[name=\"sort\"]').value === 'distance-asc') this.resets.sort();\n        } else {\n          this.sortDistanceTarget.disabled = false;\n          this.sortDistanceTarget.parentNode.dispatchEvent(new Event('change'));\n        }\n      }\n    });\n\n    for (const el of this.geoTarget.querySelectorAll('select')) {\n      el.addEventListener('change', () => {\n        this.useFilter('geo', used());\n\n        if (validPostalCode()) {\n          this.search();\n        }\n      });\n    }\n  }\n\n  discount () {\n    this.addReset('discount', () => {\n      this.discountTarget.querySelector('select').dispatchEvent(new Event('reset'));\n    });\n\n    this.useFilter('discount', this.discountTarget.querySelector('select option:checked').value !== '');\n\n    this.discountTarget.querySelector('select').addEventListener('change', () => {\n      this.useFilter('discount', this.discountTarget.querySelector('select option:checked').value !== '');\n      this.search();\n    });\n  }\n\n  availability () {\n    this.addReset('availability', () => {\n      this.availabilityTarget.querySelector('input[type=\"checkbox\"]').checked = false;\n    });\n\n    this.useFilter('availability', this.availabilityTarget.querySelector('input[type=\"checkbox\"]').checked);\n\n    this.availabilityTarget.querySelector('input[type=\"checkbox\"]').addEventListener('change', () => {\n      this.useFilter('availability', this.availabilityTarget.querySelector('input[type=\"checkbox\"]').checked);\n      this.search();\n    });\n  }\n\n  lefty () {\n    this.addReset('lefty', () => {\n      this.leftyTarget.querySelector('input[type=\"checkbox\"]').checked = false;\n    });\n\n    this.useFilter('lefty', this.leftyTarget.querySelector('input[type=\"checkbox\"]').checked);\n\n    this.leftyTarget.querySelector('input[type=\"checkbox\"]').addEventListener('change', () => {\n      this.useFilter('lefty', this.leftyTarget.querySelector('input[type=\"checkbox\"]').checked);\n      this.search();\n    });\n  }\n\n  page () {\n    for (const el of document.querySelectorAll('.pagination a.page-link')) {\n      el.addEventListener('click', (e) => {\n        e.preventDefault();\n        const match = el.getAttribute('href').match(/page=(\\d+)/);\n        if (match) {\n          this.formTarget.querySelector('input[name=\"page\"]').value = match[1];\n          this.search({ resetPage: false });\n        }\n      });\n    }\n  }\n\n  autoPage () {\n    window.onscroll = (e) => {\n      if ((window.innerHeight + Math.round(window.scrollY)) >= document.body.offsetHeight) {\n        alert('bottom');\n      }\n    };\n  }\n\n  layout () {\n    const activate = (el) => {\n      el.classList.add('bg-light-subtle');\n      el.classList.remove('btn-light');\n    };\n\n    const deactivate = (el) => {\n      el.classList.remove('bg-light-subtle');\n      el.classList.add('btn-light');\n    };\n\n    this.layoutGridTarget.addEventListener('click', () => {\n      deactivate(this.layoutListTarget);\n      activate(this.layoutGridTarget);\n\n      this.formTarget.querySelector('input[name=\"layout\"]').value = 'grid';\n      this.search();\n    });\n\n    this.layoutListTarget.addEventListener('click', () => {\n      deactivate(this.layoutGridTarget);\n      activate(this.layoutListTarget);\n\n      this.formTarget.querySelector('input[name=\"layout\"]').value = 'list';\n      this.search();\n    });\n  }\n\n  sort () {\n    if (!this.hasSortTarget)\n      return;\n\n    this.addReset('sort', () => {\n      this.sortTarget.querySelector('select').dispatchEvent(new Event('reset'));\n    });\n\n    this.useFilter('sort', this.sortTarget.querySelector('select option:checked')?.value || '' !== '');\n\n    this.sortTarget.querySelector('select').addEventListener('change', () => {\n      this.useFilter('sort', this.sortTarget.querySelector('select option:checked').value !== '');\n      this.formTarget.querySelector('input[name=\"sort\"]').value = this.sortTarget.querySelector('select option:checked').value;\n      this.search();\n    });\n  }\n\n\n  search ({ debounce = 0, resetPage = true, scrollIntoView = true } = {}) {\n    window.clearTimeout(this.searchTimer);\n\n    this.searchTimer = window.setTimeout(() => {\n      if (resetPage) {\n        this.formTarget.querySelector('input[name=\"page\"]').value = undefined;\n      }\n\n      this.formTarget.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); // yes ...\n      \n      if (scrollIntoView) {\n        if (this.queriableValue) {\n          window.scrollTo({ top: 0 });\n        } else {\n          this.element.scrollIntoView();\n        }\n      }\n\n      document.body.dispatchEvent(new CustomEvent('addSearchHistory', { detail: { query: this.searchbox.value } }));\n\n      if (this.queriableValue) {\n        document.title = this.windowTitleValue.replace('%{query}', this.searchbox.value);\n      }\n    }, debounce);\n  }\n\n  metaSearch ({ debounce = 0 } = {}) {\n    if (!this.hasMetaFormTarget) return;\n    window.clearTimeout(this.metaSearchTimer);\n\n    this.metaSearchTimer = window.setTimeout(() => {\n      if(!this.hasMetaFormTarget) return;\n      this.metaFormTarget.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); // yes ...\n    }, debounce);\n  }\n\n  resetAll () {\n    for (const name of this.filters) {\n      this.resets[name]();\n    }\n\n    this.search();\n  }\n\n\n  save (e) {\n    const button = e.currentTarget;\n\n    const exec = () => {\n      button.disabled = true;\n\n      window.$Gunfinder.fetch('/profile/searches', {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json'\n        },\n        body: Base64.decode(this.resultsTarget.dataset.filter)\n      });\n\n      (() => {\n        const text = button.innerHTML;\n        button.innerHTML = button.dataset.successText;\n        window.setTimeout(() => {\n          button.innerHTML = text;\n          button.disabled = false;\n        }, 8000);\n      })();\n    };\n\n    if (!window.$Gunfinder.user.signedIn) {\n      this.appController.authController.open({ mode: 'search', callback: exec.bind(this) });\n      return;\n    }\n\n    exec();\n  }\n}\n", "/**\n *  base64.ts\n *\n *  Licensed under the BSD 3-Clause License.\n *    http://opensource.org/licenses/BSD-3-Clause\n *\n *  References:\n *    http://en.wikipedia.org/wiki/Base64\n *\n * @author Dan Kogai (https://github.com/dankogai)\n */\nconst version = '3.8.0';\n/**\n * @deprecated use lowercase `version`.\n */\nconst VERSION = version;\nconst _hasBuffer = typeof Buffer === 'function';\nconst _TD = typeof TextDecoder === 'function' ? new TextDecoder('utf-8', { ignoreBOM: true }) : undefined;\nconst _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined;\nconst b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\nconst b64chs = Array.prototype.slice.call(b64ch);\nconst b64tab = ((a) => {\n    let tab = {};\n    a.forEach((c, i) => tab[c] = i);\n    return tab;\n})(b64chs);\nconst b64re = /^(?:[A-Za-z\\d+\\/]{4})*?(?:[A-Za-z\\d+\\/]{2}(?:==)?|[A-Za-z\\d+\\/]{3}=?)?$/;\nconst _fromCC = String.fromCharCode.bind(String);\nconst _U8Afrom = typeof Uint8Array.from === 'function'\n    ? Uint8Array.from.bind(Uint8Array)\n    : (it) => new Uint8Array(Array.prototype.slice.call(it, 0));\nconst _mkUriSafe = (src) => src\n    .replace(/=/g, '').replace(/[+\\/]/g, (m0) => m0 == '+' ? '-' : '_');\nconst _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\\+\\/]/g, '');\n/**\n * polyfill version of `btoa`\n */\nconst btoaPolyfill = (bin) => {\n    // console.log('polyfilled');\n    let u32, c0, c1, c2, asc = '';\n    const pad = bin.length % 3;\n    for (let i = 0; i < bin.length;) {\n        if ((c0 = bin.charCodeAt(i++)) > 255 ||\n            (c1 = bin.charCodeAt(i++)) > 255 ||\n            (c2 = bin.charCodeAt(i++)) > 255)\n            throw new TypeError('invalid character found');\n        u32 = (c0 << 16) | (c1 << 8) | c2;\n        asc += b64chs[u32 >> 18 & 63]\n            + b64chs[u32 >> 12 & 63]\n            + b64chs[u32 >> 6 & 63]\n            + b64chs[u32 & 63];\n    }\n    return pad ? asc.slice(0, pad - 3) + \"===\".substring(pad) : asc;\n};\n/**\n * does what `window.btoa` of web browsers do.\n * @param {String} bin binary string\n * @returns {string} Base64-encoded string\n */\nconst _btoa = typeof btoa === 'function' ? (bin) => btoa(bin)\n    : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64')\n        : btoaPolyfill;\nconst _fromUint8Array = _hasBuffer\n    ? (u8a) => Buffer.from(u8a).toString('base64')\n    : (u8a) => {\n        // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326\n        const maxargs = 0x1000;\n        let strs = [];\n        for (let i = 0, l = u8a.length; i < l; i += maxargs) {\n            strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));\n        }\n        return _btoa(strs.join(''));\n    };\n/**\n * converts a Uint8Array to a Base64 string.\n * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 \u00A75\n * @returns {string} Base64 string\n */\nconst fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a);\n// This trick is found broken https://github.com/dankogai/js-base64/issues/130\n// const utob = (src: string) => unescape(encodeURIComponent(src));\n// reverting good old fationed regexp\nconst cb_utob = (c) => {\n    if (c.length < 2) {\n        var cc = c.charCodeAt(0);\n        return cc < 0x80 ? c\n            : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6))\n                + _fromCC(0x80 | (cc & 0x3f)))\n                : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f))\n                    + _fromCC(0x80 | ((cc >>> 6) & 0x3f))\n                    + _fromCC(0x80 | (cc & 0x3f)));\n    }\n    else {\n        var cc = 0x10000\n            + (c.charCodeAt(0) - 0xD800) * 0x400\n            + (c.charCodeAt(1) - 0xDC00);\n        return (_fromCC(0xf0 | ((cc >>> 18) & 0x07))\n            + _fromCC(0x80 | ((cc >>> 12) & 0x3f))\n            + _fromCC(0x80 | ((cc >>> 6) & 0x3f))\n            + _fromCC(0x80 | (cc & 0x3f)));\n    }\n};\nconst re_utob = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFFF]|[^\\x00-\\x7F]/g;\n/**\n * @deprecated should have been internal use only.\n * @param {string} src UTF-8 string\n * @returns {string} UTF-16 string\n */\nconst utob = (u) => u.replace(re_utob, cb_utob);\n//\nconst _encode = _hasBuffer\n    ? (s) => Buffer.from(s, 'utf8').toString('base64')\n    : _TE\n        ? (s) => _fromUint8Array(_TE.encode(s))\n        : (s) => _btoa(utob(s));\n/**\n * converts a UTF-8-encoded string to a Base64 string.\n * @param {boolean} [urlsafe] if `true` make the result URL-safe\n * @returns {string} Base64 string\n */\nconst encode = (src, urlsafe = false) => urlsafe\n    ? _mkUriSafe(_encode(src))\n    : _encode(src);\n/**\n * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 \u00A75.\n * @returns {string} Base64 string\n */\nconst encodeURI = (src) => encode(src, true);\n// This trick is found broken https://github.com/dankogai/js-base64/issues/130\n// const btou = (src: string) => decodeURIComponent(escape(src));\n// reverting good old fationed regexp\nconst re_btou = /[\\xC0-\\xDF][\\x80-\\xBF]|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xF7][\\x80-\\xBF]{3}/g;\nconst cb_btou = (cccc) => {\n    switch (cccc.length) {\n        case 4:\n            var cp = ((0x07 & cccc.charCodeAt(0)) << 18)\n                | ((0x3f & cccc.charCodeAt(1)) << 12)\n                | ((0x3f & cccc.charCodeAt(2)) << 6)\n                | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000;\n            return (_fromCC((offset >>> 10) + 0xD800)\n                + _fromCC((offset & 0x3FF) + 0xDC00));\n        case 3:\n            return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12)\n                | ((0x3f & cccc.charCodeAt(1)) << 6)\n                | (0x3f & cccc.charCodeAt(2)));\n        default:\n            return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6)\n                | (0x3f & cccc.charCodeAt(1)));\n    }\n};\n/**\n * @deprecated should have been internal use only.\n * @param {string} src UTF-16 string\n * @returns {string} UTF-8 string\n */\nconst btou = (b) => b.replace(re_btou, cb_btou);\n/**\n * polyfill version of `atob`\n */\nconst atobPolyfill = (asc) => {\n    // console.log('polyfilled');\n    asc = asc.replace(/\\s+/g, '');\n    if (!b64re.test(asc))\n        throw new TypeError('malformed base64.');\n    asc += '=='.slice(2 - (asc.length & 3));\n    let u24, r1, r2;\n    let binArray = []; // use array to avoid minor gc in loop\n    for (let i = 0; i < asc.length;) {\n        u24 = b64tab[asc.charAt(i++)] << 18\n            | b64tab[asc.charAt(i++)] << 12\n            | (r1 = b64tab[asc.charAt(i++)]) << 6\n            | (r2 = b64tab[asc.charAt(i++)]);\n        if (r1 === 64) {\n            binArray.push(_fromCC(u24 >> 16 & 255));\n        }\n        else if (r2 === 64) {\n            binArray.push(_fromCC(u24 >> 16 & 255, u24 >> 8 & 255));\n        }\n        else {\n            binArray.push(_fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255));\n        }\n    }\n    return binArray.join('');\n};\n/**\n * does what `window.atob` of web browsers do.\n * @param {String} asc Base64-encoded string\n * @returns {string} binary string\n */\nconst _atob = typeof atob === 'function' ? (asc) => atob(_tidyB64(asc))\n    : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary')\n        : atobPolyfill;\n//\nconst _toUint8Array = _hasBuffer\n    ? (a) => _U8Afrom(Buffer.from(a, 'base64'))\n    : (a) => _U8Afrom(_atob(a).split('').map(c => c.charCodeAt(0)));\n/**\n * converts a Base64 string to a Uint8Array.\n */\nconst toUint8Array = (a) => _toUint8Array(_unURI(a));\n//\nconst _decode = _hasBuffer\n    ? (a) => Buffer.from(a, 'base64').toString('utf8')\n    : _TD\n        ? (a) => _TD.decode(_toUint8Array(a))\n        : (a) => btou(_atob(a));\nconst _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/'));\n/**\n * converts a Base64 string to a UTF-8 string.\n * @param {String} src Base64 string.  Both normal and URL-safe are supported\n * @returns {string} UTF-8 string\n */\nconst decode = (src) => _decode(_unURI(src));\n/**\n * check if a value is a valid Base64 string\n * @param {String} src a value to check\n  */\nconst isValid = (src) => {\n    if (typeof src !== 'string')\n        return false;\n    const s = src.replace(/\\s+/g, '').replace(/={0,2}$/, '');\n    return !/[^\\s0-9a-zA-Z\\+/]/.test(s) || !/[^\\s0-9a-zA-Z\\-_]/.test(s);\n};\n//\nconst _noEnum = (v) => {\n    return {\n        value: v, enumerable: false, writable: true, configurable: true\n    };\n};\n/**\n * extend String.prototype with relevant methods\n */\nconst extendString = function () {\n    const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body));\n    _add('fromBase64', function () { return decode(this); });\n    _add('toBase64', function (urlsafe) { return encode(this, urlsafe); });\n    _add('toBase64URI', function () { return encode(this, true); });\n    _add('toBase64URL', function () { return encode(this, true); });\n    _add('toUint8Array', function () { return toUint8Array(this); });\n};\n/**\n * extend Uint8Array.prototype with relevant methods\n */\nconst extendUint8Array = function () {\n    const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body));\n    _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); });\n    _add('toBase64URI', function () { return fromUint8Array(this, true); });\n    _add('toBase64URL', function () { return fromUint8Array(this, true); });\n};\n/**\n * extend Builtin prototypes with relevant methods\n */\nconst extendBuiltins = () => {\n    extendString();\n    extendUint8Array();\n};\nconst gBase64 = {\n    version: version,\n    VERSION: VERSION,\n    atob: _atob,\n    atobPolyfill: atobPolyfill,\n    btoa: _btoa,\n    btoaPolyfill: btoaPolyfill,\n    fromBase64: decode,\n    toBase64: encode,\n    encode: encode,\n    encodeURI: encodeURI,\n    encodeURL: encodeURI,\n    utob: utob,\n    btou: btou,\n    decode: decode,\n    isValid: isValid,\n    fromUint8Array: fromUint8Array,\n    toUint8Array: toUint8Array,\n    extendString: extendString,\n    extendUint8Array: extendUint8Array,\n    extendBuiltins: extendBuiltins\n};\n// makecjs:CUT //\nexport { version };\nexport { VERSION };\nexport { _atob as atob };\nexport { atobPolyfill };\nexport { _btoa as btoa };\nexport { btoaPolyfill };\nexport { decode as fromBase64 };\nexport { encode as toBase64 };\nexport { utob };\nexport { encode };\nexport { encodeURI };\nexport { encodeURI as encodeURL };\nexport { btou };\nexport { decode };\nexport { isValid };\nexport { fromUint8Array };\nexport { toUint8Array };\nexport { extendString };\nexport { extendUint8Array };\nexport { extendBuiltins };\n// and finally,\nexport { gBase64 as Base64 };\n", "import { Controller } from '@hotwired/stimulus';\nimport { Toast } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  connect () {\n    for(const el of [].slice.call(document.querySelectorAll('.toast'))) {\n      const toast = new Toast(el);\n      toast.show();\n    }\n\n    document.addEventListener('toast:add', (e) => {\n      this.addToast(e.detail.type, e.detail.message, e.detail.delay || 10000);\n    });\n  }\n\n  addToast(type, message, delay = 10000) {\n    // Badge logic as in the Rails partial\n    const badges = { alert: 'info', error: 'danger', notice: 'info' };\n    const badge = badges[type] ? badges[type] : type;\n    const toastHtml = `\n      <div class=\"toast\" data-bs-autohide=\"true\" data-bs-delay=\"${delay}\">\n        <div class=\"toast-header\">\n          <b class=\"me-auto\">\n            <span class=\"badge bg-${badge} me-1\">&nbsp;</span>\n            Gunfinder\n          </b>\n          <small class=\"text-body-tertiary\">jetzt</small>\n          <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"toast\"></button>\n        </div>\n        <div class=\"toast-body\">\n          ${message}\n        </div>\n      </div>\n    `;\n    // Create a temporary element to parse the HTML\n    const temp = document.createElement('div');\n    temp.innerHTML = toastHtml;\n    const toastEl = temp.querySelector('.toast');\n    this.element.appendChild(toastEl);\n    const toast = new Toast(toastEl);\n    toast.show();\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['trigger', 'tab'];\n  static values = {\n    inactiveClass: {\n      type: Array,\n      default: ['btn-light']\n    },\n    activeClass: {\n      type: Array,\n      default: ['btn-primary']\n    }\n  };\n\n  connect () {\n    this.currentId = 0;\n\n    for (const [i, trigger] of this.triggerTargets.entries()) {\n      trigger.addEventListener('click', (e) => {\n        e.preventDefault();\n        this.toggle(i);\n      });\n    }\n\n    if (window.location.hash) {\n      const hashMatch = window.location.hash.match(/#tab(\\d)/i);\n      if (hashMatch) {\n        const hashTab = parseInt(hashMatch[1]);\n        if (hashTab > 0 && hashTab <= this.triggerTargets.length) {\n          this.triggerTargets[hashTab - 1].click();\n        }\n      }\n    }\n  }\n\n  toggle (id) {\n    if (this.currentId === id) return;\n\n    this.triggerTargets[id].classList.remove(...this.inactiveClassValue);\n    this.triggerTargets[id].classList.add(...this.activeClassValue);\n\n    this.triggerTargets[this.currentId].classList.add(...this.inactiveClassValue);\n    this.triggerTargets[this.currentId].classList.remove(...this.activeClassValue);\n\n\n    this.tabTargets[id].classList.remove('d-none');\n    this.tabTargets[this.currentId].classList.add('d-none');\n\n    this.currentId = id;\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  connect () {\n    this.mode = 'listing';\n  }\n\n  get appController () {\n    return this.application.getControllerForElementAndIdentifier(document.querySelector('body'), 'app');\n  }\n\n  auth (e) {\n    if (window.$Gunfinder.user.signedIn) {\n      return;\n    }\n\n    e.preventDefault();\n    this.mode = e.params.mode;\n\n    const path = e.currentTarget.href; // e is not available in callback\n    this.appController.authController.open({ mode: `sell-${this.mode}`, callback () {\n      window.Turbo.visit(path);\n    } });\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static values = { timestamp: String, i18nDay: String };\n  static targets = ['days', 'hours', 'minutes', 'seconds'];\n\n  connect () {\n    this.timestamp = (new Date()).setTime(parseInt(this.timestampValue));\n\n    this.nums = {};\n    this.i18nDay = this.i18nDayValue.split('|');\n\n    window.setInterval(this.calculcate.bind(this), 1000);\n    this.calculcate();\n  }\n\n  calculcate () {\n    const now = new Date().getTime();\n    let remaining = parseInt((now < this.timestamp ? (this.timestamp - now) : (now - this.timestamp)) / 1000);\n\n    if (remaining <= 0) return;\n    \n    this.nums.days = parseInt(remaining / 86400);\n    remaining = remaining % 86400;\n    \n    this.nums.hours = parseInt(remaining / 3600);\n    remaining = remaining % 3600;\n    \n    this.nums.minutes = parseInt(remaining / 60);\n    remaining = remaining % 60;\n    \n    this.nums.seconds = parseInt(remaining);\n    \n    this.nums.days    = parseInt(this.nums.days, 10);\n    this.nums.hours   = this.nums.hours < 10 ? `0${this.nums.hours}` : this.nums.hours;\n    this.nums.minutes = this.nums.minutes < 10 ? `0${this.nums.minutes}` : this.nums.minutes;\n    this.nums.seconds = this.nums.seconds < 10 ? `0${this.nums.seconds}` : this.nums.seconds;\n\n    this.draw();\n  }\n\n  draw () {\n    this.element.innerHTML = `${this.nums.days} ${this.i18nDay[this.nums.days == 1 ? 0 : 1]} ${this.nums.hours}:${this.nums.minutes}:${this.nums.seconds}`;\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  positive () {\n    window.$Gunfinder.track('feedback: do you like gf?', { answer: 'yes' });\n  }\n\n  negative () {\n    window.$Gunfinder.track('feedback: do you like gf?', { answer: 'no' });\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static values = {\n    latitude: Number,\n    longitude: Number\n  };\n\n  connect () {\n    window.initMap = () => {\n      var map = new google.maps.Map(this.element, {\n        gestureHandling: 'cooperative',\n        streetViewControl: false,\n        mapTypeControl: false,\n        keyboardShortcuts: false\n      });\n\n      const\n        marker = new google.maps.Marker({\n          position: {\n            lat: parseFloat(this.latitudeValue),\n            lng: parseFloat(this.longitudeValue)\n          },\n          map: map\n        })\n      ;\n\n      map.setZoom(10);\n      map.panTo(marker.position);\n    };\n  }\n\n  load (e) {\n    e.currentTarget.remove();\n    this.element.classList.remove('d-none');\n\n    var script = document.createElement('script');\n    script.type = 'text/javascript';\n    script.async = true;\n    script.src = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyDoVLuQiMGIQqkDifLemHODWVmrMNquCFM&callback=initMap';\n\n    document.getElementsByTagName('head')[0].appendChild(script);\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static values = {\n    max: Number,\n    step: {\n      type: Number,\n      default: 0\n    },\n    interval: {\n      type: Number,\n      default: 10\n    }\n  };\n\n  connect () {\n    const observer = new IntersectionObserver((entries) => {\n      if (!entries[0].isIntersecting) return;\n      observer.unobserve(this.element);\n      this.count();\n    }, { threshold: [1] });\n\n    observer.observe(this.element);\n  }\n\n  count () {\n    this.currentVal = 0;\n\n    const timer =  window.setInterval(() => {\n      let nextVal = this.currentVal + this.stepValue;\n\n      if (nextVal >= this.maxValue) {\n        nextVal = this.maxValue;\n        clearInterval(timer);\n      }\n\n      this.currentVal = nextVal;\n      this.element.innerText = new Intl.NumberFormat('de-DE', { minimumFractionDigits: Number.isInteger(this.maxValue) ? 0 : 1 }).format(this.currentVal);\n\n    }, this.intervalValue);\n  }\n}\n\n\n\n\n\n// const counters = document.querySelectorAll('.value');\n// const speed = 200;\n\n// counters.forEach( counter => {\n//    const animate = () => {\n//       const value = +counter.getAttribute('akhi');\n//       const data = +counter.innerText;\n     \n//       const time = value / speed;\n//      if(data < value) {\n//           counter.innerText = Math.ceil(data + time);\n//           setTimeout(animate, 1);\n//         }else{\n//           counter.innerText = value;\n//         }\n     \n//    }\n   \n//    animate();\n// });\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  connect () {\n    if (window.location.hash) {\n      const item = document.querySelector(`[data-bs-target=\"${window.location.hash}\"]`);\n      if (item) {\n        item.click();\n      }\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['chunk', 'left', 'right']\n\n  connect () {\n    this.chunk = 0;\n    this.buttons();\n  }\n\n  left () {\n    if (this.chunk === 0)\n      return;\n\n    this.chunk -= 1;\n    this.show();\n    this.buttons();\n  }\n\n  right () {\n    if (this.chunk === this.chunkTargets.length - 1)\n      return;\n\n    this.chunk += 1;\n    this.show();\n    this.buttons();\n  }\n\n  show () {\n    this.chunkTargets[this.chunk].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });\n  }\n\n  buttons () {\n    if (this.chunk === 0) {\n      this.leftTarget.classList.add('disabled');\n    } else {\n      this.leftTarget.classList.remove('disabled');\n    }\n\n    if (this.chunk === this.chunkTargets.length - 1) {\n      this.rightTarget.classList.add('disabled');\n    } else {\n      this.rightTarget.classList.remove('disabled');\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static values = {\n    autoOpen: false\n  }\n\n  connect () {\n    this.modal = Modal.getOrCreateInstance(this.element);\n    if (this.autoOpenValue) this.open();\n  }\n\n  open () {\n    this.modal.show();\n  }\n}\n\n", "import { Controller } from '@hotwired/stimulus';\n\n// expects to reconnect after every submit\nexport default class extends Controller {\n  static values = {\n    autosubmit: {\n      type: Boolean,\n      default: false\n    },\n    enableTurnstile: {\n      type: Boolean,\n      default: false\n    }\n  }\n\n  connect () {\n    this.initTurnstile();\n    this.handleTurnstileSuccess();\n\n    this.element.addEventListener('submit', this.signAndSubmit.bind(this), { once: true });\n    if (this.autosubmitValue) this.signAndSubmit();\n  }\n\n  initTurnstile() {\n    this.turnstileSuccess = true;\n\n    if (!this.enableTurnstileValue) return;\n\n    this.turnstileSuccess = false;\n\n    for (const el of this.element.querySelectorAll('button, input[type=\"button\"], input[type=\"submit\"]')) {\n      el.disabled = true;\n    }\n  }\n\n  handleTurnstileSuccess() {\n    if (!this.enableTurnstileValue) return;\n    this.element.addEventListener('turnstile:success', () => {\n      this.turnstileSuccess = true;\n\n      for (const el of this.element.querySelectorAll('button, input[type=\"button\"], input[type=\"submit\"]')) {\n        el.disabled = false;\n      }\n    });\n  }\n\n  async signAndSubmit (e) {\n    if (!this.turnstileSuccess) return;\n    e?.preventDefault();\n    // e.stopPropagation();\n    \n    // ppl double click and thereby fuck up the token generation\n    // for (const el of this.element.querySelectorAll('button, input[type=\"button\"], input[type=\"submit\"]')) {\n    //   el.disabled = true;\n    // }\n\n    const attach = (name, token) => {\n      if (this.element.querySelector(`input[name=\"${name}\"]`)) {\n        this.element.querySelector(`input[name=\"${name}\"]`).value = token;\n      } else {\n        const input = document.createElement('input');\n        input.type  = 'hidden';\n        input.name  = name;\n        input.value = token;\n        this.element.appendChild(input);\n      }\n    };\n\n    attach('castle_request_token', await window.castle.createRequestToken());\n    \n    window.setTimeout(() => {\n      this.element.requestSubmit(e?.submitter);\n    }, 0);\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static targets = ['input', 'form'];\n  static values = {\n    mode: {\n      type: String,\n      default: 'embed'\n    },\n    selection: Array\n  };\n\n  connect () {\n    this.selection = this.selectionValue;\n    this.select();\n\n    if (this.modeValue === 'modal') {\n      this.modal = Modal.getOrCreateInstance(this.element);\n      this.formTarget.addEventListener('submit', () => this.modal.hide());\n\n      this.modal.show();\n    }\n  }\n\n  select () {\n    for (const interest of this.selection) {\n      const target = this.element.querySelector(`[data-interest-cloud-interest-param=\"${interest}\"]`);\n      if (!target) continue; // ...\n\n      target.classList.remove('bg-primary-subtle');\n      target.classList.add('bg-primary');\n    }\n  }\n\n  toggle (e) {\n    const\n      intruder = e.params.interest,\n      target = e.currentTarget\n    ;\n\n    if (this.selection.indexOf(intruder) === -1) {\n      this.selection.push(intruder);\n    } else {\n      this.selection = this.selection.filter(interest => interest !== intruder);\n    }\n\n    target.classList.toggle('bg-primary-subtle');\n    target.classList.toggle('bg-primary');\n\n    this.inputTarget.value = this.selection.join(',');\n  }\n\n  save () {\n\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static values = {\n    type: {\n      type: String,\n      default: 'line'\n    },\n    data: Object,\n    options: Object,\n  }\n\n  connect () {\n    this.loadChartJs(this.init.bind(this));\n  }\n\n  init () {\n    this.setDefaults();\n\n    new window.Chart(this.element, {\n      type: this.typeValue,\n      data: this.dataValue,\n      options: this.optionsValue,\n    });\n  }\n\n  loadChartJs (onLoad) {\n    const el = document.createElement('script');\n    el.onload = onLoad;\n    el.src = 'https://cdn.jsdelivr.net/npm/chart.js';\n\n    document.body.append(el);\n  }\n\n  setDefaults () {\n    window.Chart.defaults.locale = 'de';\n    window.Chart.defaults.responsive = true;\n    window.Chart.defaults.font.family = 'Lato';\n    window.Chart.defaults.plugins.legend.align = 'start';\n    window.Chart.defaults.plugins.legend.position = 'bottom';\n    window.Chart.defaults.plugins.title.font.size = '16px';\n    window.Chart.defaults.plugins.title.padding = 0;\n    window.Chart.defaults.plugins.subtitle.padding = { bottom: 20 };\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['toggleA', 'toggleB', 'a', 'b'];\n\n  connect () {\n    this.activeToggle = 'a';\n  }\n\n  activateToggle (aorb) {\n    if (aorb === 'a' && this.activeToggle !== 'a') {\n      const classList = [...this.toggleATarget.classList];\n      this.toggleATarget.classList.remove(...classList);\n      this.toggleATarget.classList.add(...this.toggleBTarget.classList);\n      \n      this.toggleBTarget.classList.remove(...this.toggleBTarget.classList);\n      this.toggleBTarget.classList.add(...classList);\n\n      this.activeToggle = 'a';\n    }\n\n    if (aorb === 'b' && this.activeToggle !== 'b') {\n      const classList = [...this.toggleBTarget.classList];\n\n      this.toggleBTarget.classList.remove(...classList);\n      this.toggleBTarget.classList.add(...this.toggleATarget.classList);\n\n      this.toggleATarget.classList.remove(...this.toggleATarget.classList);\n      this.toggleATarget.classList.add(...classList);\n\n      this.activeToggle = 'b';\n    }\n  }\n\n  activateA () {\n    this.activateToggle('a');\n\n    for (const el of this.aTargets) {\n      el.classList.remove('d-none');\n    }\n\n    for (const el of this.bTargets) {\n      el.classList.add('d-none');\n    }\n  }\n\n  activateB () {\n    this.activateToggle('b');\n\n    for (const el of this.aTargets) {\n      el.classList.add('d-none');\n    }\n\n    for (const el of this.bTargets) {\n      el.classList.remove('d-none');\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static values = { dataName: String, fileName: String };\n\n  // connect () {\n  // }\n\n  dl (e) {\n    e.preventDefault();\n\n    const data = window.$Gunfinder.csvDl[this.dataNameValue].map((line) => line.join(',')).join('\\n');\n\n    const\n      blob = new Blob([data], { type: 'text/plain' }),\n      url  = URL.createObjectURL(blob),\n      link = document.createElement('a')\n    ;\n\n    link.href     = url;\n    link.download = `${this.fileNameValue}.csv`;\n\n    document.body.appendChild(link);\n    link.click();\n\n    document.body.removeChild(link);\n    URL.revokeObjectURL(url);\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['categoryId', 'calibers'];\n\n  connect () {\n    this.categoryIdTarget.addEventListener('change', () => {\n      this.toggleCaliber();\n    });\n  }\n\n  toggleCaliber (e) {\n    const group = this.categoryIdTarget.options[this.categoryIdTarget.selectedIndex].closest('optgroup')?.dataset.id;\n\n    if (['weapons', 'ammunition'].includes(group)) {\n      this.calibersTarget.classList.remove('d-none');\n    } else {\n      this.calibersTarget.classList.add('d-none');\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nfunction plainTextToHtml(text) {\n  text = text\n      // Encode &.\n      .replace(/&/g, '&amp;')\n      // Encode <>.\n      .replace(/</g, '&lt;')\n      .replace(/>/g, '&gt;')\n      // Creates a paragraph for each double line break.\n      .replace(/\\r?\\n\\r?\\n/g, '</p><p>')\n      // Creates a line break for each single line break.\n      .replace(/\\r?\\n/g, '<br>')\n      // Replace tabs with four spaces.\n      .replace(/\\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')\n      // Preserve trailing spaces (only the first and last one \u2013 the rest is handled below).\n      .replace(/^\\s/, '&nbsp;')\n      .replace(/\\s$/, '&nbsp;')\n      // Preserve other subsequent spaces now.\n      .replace(/\\s\\s/g, ' &nbsp;')\n    ;\n\n  if (text.includes('</p><p>') || text.includes('<br>')) {\n    // If we created paragraphs above, add the trailing ones.\n    text = `<p>${text}</p>`;\n  }\n\n  return text;\n}\n\nexport default class extends Controller {\n  static targets = ['form', 'reply', 'footer']\n  static values = { type: String }\n  static outlets = ['simple-editor']\n\n  connect () {\n    this.modal = Modal.getOrCreateInstance(this.element);\n\n    this.element.addEventListener('show.bs.modal', () => {\n      this.formTarget.querySelector('textarea').value = this.simpleEditorOutlet.getData()\n        .replace(/<br\\s*\\/?>/gi, '\\n')\n        .replace(/<\\/(p|div)>/gi, '\\n\\n')\n        .replace(/<[^>]+>/g, '')\n      ;\n\n      window.$Gunfinder.track('item ai optimiser: opened', { type: this.typeValue });\n    });\n  }\n\n  formTargetConnected () {\n    this.formTarget.addEventListener('turbo:submit-start', this.start.bind(this))\n  }\n\n  start () {\n    if (this.hasFooterTarget) {\n      this.footerTarget.classList.add('d-none');\n    }\n\n    window.$Gunfinder.track('item ai optimiser: submitted', { type: this.typeValue });\n  }\n\n  accept () {\n    this.modal.hide();\n\n    const data = plainTextToHtml(this.replyTarget.querySelector('.reply').textContent);\n    this.simpleEditorOutlet.setData(data);\n\n    window.$Gunfinder.track('item ai optimiser: accepted', { type: this.typeValue });\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n// import coreTranslations from 'ckeditor5/translations/de.js';\n\n// import {\n//   ClassicEditor,\n//   BalloonToolbar,\n//   BlockToolbar,\n//   Bold,\n//   Essentials,\n//   Paragraph,\n//   Indent,\n//   Italic,\n//   List,\n//   RemoveFormat,\n//   MediaEmbed,\n//   MediaEmbedToolbar,\n//   BlockQuote\n// } from 'ckeditor5';\n\nexport default class extends Controller {\n  static values = {\n    inputId: String,\n    uiLocale: 'de',\n    contentLocale: 'de',\n    enterMode: 'BR',\n    disabled: Boolean,\n    toolbar: {\n      type: Array,\n      default: [\n        'bold',\n        'italic',\n        '|',\n        'blockQuote',\n        'bulletedList',\n        'numberedList',\n        'mediaEmbed',\n        '|',\n        'undo',\n        'redo',\n        'removeFormat'\n      ]\n    }\n  };\n\n  async connect () {\n    await this.initCkeditor();\n    this.editor.setData(document.getElementById(this.inputIdValue).value);\n    \n    this.element.closest('form').addEventListener('submit', this.writeDataToForm.bind(this));\n\n    if (this.disabledValue) {\n      this.editor.enableReadOnlyMode(new Date().toISOString());\n    }\n  }\n\n  async initCkeditor () {\n    this.editor = await window.$CKEditor.ClassicEditor.create(this.scope.element, {\n      plugins: [\n        window.$CKEditor.ClassicEditor,\n        window.$CKEditor.BalloonToolbar,\n        window.$CKEditor.BlockToolbar,\n        window.$CKEditor.Bold,\n        window.$CKEditor.Essentials,\n        window.$CKEditor.Paragraph,\n        window.$CKEditor.Indent,\n        window.$CKEditor.Italic,\n        window.$CKEditor.List,\n        window.$CKEditor.RemoveFormat,\n        window.$CKEditor.MediaEmbed,\n        window.$CKEditor.MediaEmbedToolbar,\n        window.$CKEditor.BlockQuote,\n      ],\n      translations: [window.$CKEditor.coreTranslations],\n      language: {\n        ui: this.uiLocaleValue,\n        content: this.contentLocaleValue,\n      },\n      toolbar: {\n        items: this.toolbarValue\n      },\n      blockToolbar: this.toolbarValue,\n      balloonToolbar: this.toolbarValue,\n    });\n  }\n\n  setData (data) {\n    this.editor.setData(data);\n  }\n\n  getData () {\n    return this.editor.getData();\n  }\n\n  writeDataToForm () {\n    document.getElementById(this.inputIdValue).value = this.editor.getData();\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport * as FilePond from 'filepond';\nimport FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size';\nimport FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';\nimport FilePondPluginFilePoster from 'filepond-plugin-file-poster';\nimport FilePondPluginImageEditor from '@pqina/filepond-plugin-image-editor';\nimport { filePondLabelsForLocale } from '../i18n/filepond_labels';\nimport { pinturaLocalePackForLocale } from '../i18n/pintura_locale';\n\nimport {\n  openEditor,\n  createDefaultImageReader,\n  createDefaultImageWriter,\n  processImage,\n  getEditorDefaults,\n  setPlugins,\n  plugin_crop,\n  plugin_annotate,\n  plugin_redact,\n  markup_editor_defaults,\n} from '@pqina/pintura/pintura.js';\n\nFilePond.registerPlugin(\n  FilePondPluginFileValidateSize,\n  FilePondPluginFileValidateType,\n  FilePondPluginFilePoster,\n  FilePondPluginImageEditor,\n);\n\nsetPlugins(plugin_crop, plugin_annotate, plugin_redact);\n\n\nexport default class extends Controller {\n  static targets = ['input'];\n  static values = {\n    files: {\n      type: Array,\n      default: [],\n    },\n  };\n\n  gunfinderLocale () {\n    const raw = (window?.$Gunfinder?.locale || 'en').toString();\n    return raw.split(/[-_]/)[0].toLowerCase();\n  }\n\n  connect () {\n    this.processing = 0;\n    this.loading = 0;\n\n    this.filepond = FilePond.create(this.inputTarget, this.filePondConfig());\n    this.filepondRoot = this.element.querySelector('.filepond--root');\n\n    // Upload tracking:\n    // - New uploads and Pintura \"re-process\" both go through processfilestart/processfile.\n    this.filepondRoot.addEventListener('FilePond:processfilestart', () => {\n      this.processing += 1;\n      if (this.loading + this.processing === 1) this.dispatch('upload-started');\n    });\n\n    this.filepondRoot.addEventListener('FilePond:addfile', (e) => {\n      if (e.detail.error) {\n        this.processing = Math.max(0, this.processing - 1);\n      }\n\n      if (this.loading + this.processing === 0) {\n        this.dispatch('upload-finished');\n      }\n    });\n\n    this.filepondRoot.addEventListener('FilePond:processfile', () => {\n      this.processing = Math.max(0, this.processing - 1);\n\n      if (this.loading + this.processing === 0) {\n        this.dispatch('upload-finished');\n      }\n    });\n\n    this.filepondRoot.addEventListener('FilePond:processfileabort', () => {\n      this.processing = Math.max(0, this.processing - 1);\n      if (this.loading + this.processing === 0) this.dispatch('upload-finished');\n    });\n\n    this.filepondRoot.addEventListener('FilePond:processfileerror', () => {\n      this.processing = Math.max(0, this.processing - 1);\n      if (this.loading + this.processing === 0) this.dispatch('upload-finished');\n    });\n  }\n\n  filePondConfig () {\n    const pinturaLocale = pinturaLocalePackForLocale(window?.$Gunfinder?.locale);\n\n    return {\n      allowMultiple: true,\n      allowReorder: true,\n      maxFiles: 20,\n      credits: {},\n      itemInsertLocation: 'after',\n      files: this.filesValue.map((source) => { return { source, options: { type: 'local' } }; }),\n      ...filePondLabelsForLocale(window?.$Gunfinder?.locale),\n\n      allowFileSizeValidation: true,\n      maxFileSize: '10MB',\n      \n      allowFileTypeValidation: true,\n      acceptedFileTypes: ['image/*'],\n\n      allowFilePoster: true,\n      filePosterMaxHeight: window.$Gunfinder.mobile ? 217 : 305,\n\n      styleItemPanelAspectRatio: 0.7, // ensures equal height in filepond grid view. fucks up langwaffen pics though\n\n      imageEditor: {\n        createEditor: openEditor,\n        imageReader: [createDefaultImageReader, {}],\n        imageWriter: [createDefaultImageWriter, {}],\n\n        imageProcessor: processImage,\n\n        editorOptions: {\n          ...getEditorDefaults({\n             ...markup_editor_defaults,\n             locale: {\n              ...pinturaLocale.core,\n              ...pinturaLocale.markup,\n              ...pinturaLocale.crop,\n              ...pinturaLocale.annotate,\n              ...pinturaLocale.redact,\n              cropLabel: '',\n              redactLabel: '',\n              annotateLabel: '',\n             },\n             utils: ['crop', 'annotate', 'redact'],\n\n             cropEnableButtonRotateRight: true,\n          }),\n        },\n      },\n\n      server: {\n        instantUpload: false,\n        url: '/uploads',\n        process: {\n          url: `?folder=listings&field=${this.inputTarget.name}`,\n          headers: window.$Gunfinder.getDefaultHeaders()\n        },\n        revert: async (uniqueFileId, load, error) => {\n           await window.$Gunfinder.fetch(`/uploads/generic?file=${encodeURIComponent(uniqueFileId)}`, { method: 'DELETE' });\n          load();\n        },\n        load: async (source, load, error, progress, abort, headers) => {\n          // return;\n          // https://javascript.info/window.$Gunfinder.fetch-progress\n          this.loading += 1;\n          if (this.loading + this.processing === 1) this.dispatch('upload-started');\n\n          let finished = false;\n          const finish = () => {\n            if (finished) return;\n            finished = true;\n            this.loading -= 1;\n            if (this.loading + this.processing === 0) this.dispatch('upload-finished');\n          };\n\n          try {\n            const\n              response = await window.$Gunfinder.fetch(`/uploads/url?path=${source}`),\n              reader   = response.body.getReader(),\n              length   = { total: +response.headers.get('Content-Length'), received: 0 },\n              chunks   = []\n            ;\n\n            while (true) {\n              const { done, value } = await reader.read();\n\n              if (done) break;\n\n              length.received += value.length;\n              progress(true, length.received, length.total);\n              chunks.push(value);\n            }\n\n            load(new Blob(chunks, { type: response.headers.get('Content-Type') }));\n            finish();\n\n            return {\n              abort: () => {\n                abort();\n                finish();\n              },\n            };\n          } catch (e) {\n            error(e);\n            finish();\n            return {\n              abort: () => {\n                abort();\n                finish();\n              },\n            };\n          }\n        },\n      }\n    };\n  }\n}\n", "const Q = (e) => e instanceof File, te = (e) => /^image/.test(e.type), ie = (e) => typeof e == \"string\";\nfunction de(e, o) {\n  o.split(\";\").forEach((f) => {\n    const [_, s] = f.split(\":\");\n    if (!_.length || !s)\n      return;\n    const [c, h] = s.split(\"!important\");\n    e.style.setProperty(_, c, ie(h) ? \"important\" : void 0);\n  });\n}\nconst $ = (e, o, f = []) => {\n  const _ = document.createElement(e), s = Object.getOwnPropertyDescriptors(_.__proto__);\n  for (const c in o)\n    c === \"style\" ? de(_, o[c]) : s[c] && s[c].set || /textContent|innerHTML/.test(c) || typeof o[c] == \"function\" ? _[c] = o[c] : _.setAttribute(c, o[c]);\n  return f.forEach((c) => _.appendChild(c)), _;\n};\nlet j = null;\nconst w = () => (j === null && (j = typeof window < \"u\" && typeof window.document < \"u\"), j), ce = w() && !!Node.prototype.replaceChildren, le = ce ? (\n  // @ts-ignore\n  (e, o) => e.replaceChildren(o)\n) : (e, o) => {\n  for (; e.lastChild; )\n    e.removeChild(e.lastChild);\n  o !== void 0 && e.append(o);\n}, B = w() && $(\"div\", {\n  class: \"PinturaMeasure\",\n  style: \"position:absolute;left:0;top:0;width:99999px;height:0;pointer-events:none;contain:strict;margin:0;padding:0;\"\n});\nlet X;\nconst _e = (e) => (le(B, e), B.parentNode || document.body.append(B), clearTimeout(X), X = setTimeout(() => {\n  B.remove();\n}, 500), e);\nlet H = null;\nconst Ie = () => (H === null && (H = w() && /^((?!chrome|android).)*(safari|iphone|ipad)/i.test(navigator.userAgent)), H), Te = (e) => new Promise((o, f) => {\n  let _ = !1;\n  !e.parentNode && Ie() && (_ = !0, e.style.cssText = \"position:absolute;visibility:hidden;pointer-events:none;left:0;top:0;width:0;height:0;\", _e(e));\n  const s = () => {\n    const h = e.naturalWidth, y = e.naturalHeight;\n    h && y && (_ && e.remove(), clearInterval(c), o({ width: h, height: y }));\n  };\n  e.onerror = (h) => {\n    clearInterval(c), f(h);\n  };\n  const c = setInterval(s, 1);\n  s();\n}), ue = (e) => new Promise((o, f) => {\n  const _ = () => {\n    o({\n      width: e.videoWidth,\n      height: e.videoHeight\n    });\n  };\n  if (e.readyState >= 1)\n    return _();\n  e.onloadedmetadata = _, e.onerror = () => f(e.error);\n}), fe = (e) => new Promise((o) => {\n  const f = ie(e) ? e : URL.createObjectURL(e), _ = () => {\n    const c = new Image();\n    c.src = f, o(c);\n  };\n  if (e instanceof Blob && te(e))\n    return _();\n  const s = document.createElement(\"video\");\n  s.preload = \"metadata\", s.onloadedmetadata = () => o(s), s.onerror = _, s.src = f;\n}), ge = (e) => e.nodeName === \"VIDEO\", me = async (e) => {\n  let o;\n  e.src ? o = e : o = await fe(e);\n  let f;\n  try {\n    f = ge(o) ? await ue(o) : await Te(o);\n  } finally {\n    Q(e) && URL.revokeObjectURL(o.src);\n  }\n  return f;\n}, Z = (e) => e instanceof Blob && !(e instanceof File), q = (...e) => {\n}, ne = (e) => {\n  e.width = 1, e.height = 1;\n  const o = e.getContext(\"2d\");\n  o && o.clearRect(0, 0, 1, 1);\n};\nlet W = null;\nconst pe = () => {\n  if (W === null)\n    if (\"WebGL2RenderingContext\" in window) {\n      let e;\n      try {\n        e = $(\"canvas\"), W = !!e.getContext(\"webgl2\");\n      } catch {\n        W = !1;\n      }\n      e && ne(e), e = void 0;\n    } else\n      W = !1;\n  return W;\n}, Oe = (e, o) => pe() ? e.getContext(\"webgl2\", o) : e.getContext(\"webgl\", o) || e.getContext(\"experimental-webgl\", o);\nlet k = null;\nconst Re = () => {\n  if (k === null) {\n    let e = $(\"canvas\");\n    k = !!Oe(e), ne(e), e = void 0;\n  }\n  return k;\n}, he = () => Object.prototype.toString.call(window.operamini) === \"[object OperaMini]\", Ge = () => \"Promise\" in window, Ae = () => \"URL\" in window && \"createObjectURL\" in window.URL, Me = () => \"visibilityState\" in document, Le = () => \"performance\" in window, Se = () => \"File\" in window;\nlet z = null;\nconst ee = () => (z === null && (z = w() && // Can't run on Opera Mini due to lack of everything\n!he() && // Require these APIs to feature detect a modern browser\nMe() && Ge() && Se() && Ae() && Le()), z), Pe = (e) => {\n  const { addFilter: o, utils: f, views: _ } = e, { Type: s, createRoute: c } = f, { fileActionButton: h } = _, x = (({ parallel: i = 1, autoShift: n = !0 }) => {\n    const r = [];\n    let t = 0;\n    const E = () => {\n      if (!r.length)\n        return g.oncomplete();\n      t++, r.shift()(() => {\n        t--, t < i && I();\n      });\n    }, I = () => {\n      for (let T = 0; T < i - t; T++)\n        E();\n    }, g = {\n      queue: (T) => {\n        r.push(T), n && I();\n      },\n      runJobs: I,\n      oncomplete: () => {\n      }\n    };\n    return g;\n  })({ parallel: 1 }), v = (i) => i === null ? {} : i;\n  o(\n    \"SHOULD_REMOVE_ON_REVERT\",\n    (i, { item: n, query: r }) => new Promise((t) => {\n      const { file: E } = n, I = r(\"GET_ALLOW_IMAGE_EDITOR\") && r(\"GET_IMAGE_EDITOR_ALLOW_EDIT\") && r(\"GET_IMAGE_EDITOR_SUPPORT_EDIT\") && r(\"GET_IMAGE_EDITOR_SUPPORT_IMAGE\")(E);\n      t(!I);\n    })\n  ), o(\n    \"DID_LOAD_ITEM\",\n    (i, { query: n, dispatch: r }) => new Promise((t, E) => {\n      if (i.origin > 1) {\n        t(i);\n        return;\n      }\n      const { file: I } = i;\n      if (!n(\"GET_ALLOW_IMAGE_EDITOR\") || !n(\n        \"GET_IMAGE_EDITOR_INSTANT_EDIT\"\n      ) || !n(\"GET_IMAGE_EDITOR_SUPPORT_IMAGE\")(I))\n        return t(i);\n      const g = () => {\n        if (!b.length)\n          return;\n        const { item: p, resolve: m, reject: O } = b[0];\n        r(\"EDIT_ITEM\", {\n          id: p.id,\n          handleEditorResponse: T(p, m, O)\n        });\n      }, T = (p, m, O) => (G) => {\n        b.shift(), G ? m(p) : O(p), r(\"KICK\"), g();\n      };\n      oe({ item: i, resolve: t, reject: E }), b.length === 1 && g();\n    })\n  ), o(\"DID_CREATE_ITEM\", (i, { query: n, dispatch: r }) => {\n    i.getMetadata(\"color\") && i.setMetadata(\"colors\", i.getMetadata(\"color\")), i.extend(\"edit\", () => {\n      r(\"EDIT_ITEM\", { id: i.id });\n    });\n  });\n  const b = [], oe = (i) => (b.push(i), i), re = (i) => {\n    const { imageProcessor: n, imageReader: r, imageWriter: t } = v(\n      i(\"GET_IMAGE_EDITOR\")\n    );\n    return i(\"GET_IMAGE_EDITOR_WRITE_IMAGE\") && i(\"GET_IMAGE_EDITOR_SUPPORT_WRITE_IMAGE\") && n && r && t;\n  }, ae = (i, n) => {\n    const r = i(\"GET_FILE_POSTER_HEIGHT\"), t = i(\"GET_FILE_POSTER_MAX_HEIGHT\");\n    return r ? (n.width = r * 2, n.height = r * 2) : t && (n.width = t * 2, n.height = t * 2), n;\n  }, J = (i, n, r = () => {\n  }) => {\n    if (!n)\n      return;\n    if (!i(\"GET_FILE_POSTER_FILTER_ITEM\")(n))\n      return r();\n    const {\n      imageProcessor: t,\n      imageReader: E,\n      imageWriter: I,\n      editorOptions: g,\n      legacyDataToImageState: T,\n      imageState: p\n    } = v(i(\"GET_IMAGE_EDITOR\"));\n    if (!t)\n      return;\n    const [m, O] = E, [G = q, S] = I, P = n.file, A = n.getMetadata(\"imageState\"), D = ae(i, {\n      width: 512,\n      height: 512\n    }), U = {\n      ...g,\n      imageReader: m(O),\n      imageWriter: G({\n        // can optionally overwrite poster size\n        ...S || {},\n        // limit memory so poster is created quicker\n        canvasMemoryLimit: D.width * D.height * 2,\n        // apply legacy data if needed\n        preprocessImageState: (M, L, K, N) => !A && T ? {\n          ...M,\n          ...T(void 0, N.size, {\n            ...n.getMetadata()\n          })\n        } : M\n      }),\n      imageState: {\n        ...p,\n        ...A\n      }\n    };\n    x.queue((M) => {\n      t(P, U).then(({ dest: L }) => {\n        n.setMetadata(\"poster\", URL.createObjectURL(L), !0), M(), r();\n      });\n    });\n  };\n  o(\"CREATE_VIEW\", (i) => {\n    const { is: n, view: r, query: t } = i;\n    if (!t(\"GET_ALLOW_IMAGE_EDITOR\") || !t(\"GET_IMAGE_EDITOR_SUPPORT_WRITE_IMAGE\"))\n      return;\n    const E = t(\"GET_ALLOW_FILE_POSTER\");\n    if (!(n(\"file-info\") && !E || n(\"file\") && E))\n      return;\n    const {\n      createEditor: g,\n      imageReader: T,\n      imageWriter: p,\n      editorOptions: m,\n      legacyDataToImageState: O,\n      imageState: G\n    } = v(t(\"GET_IMAGE_EDITOR\"));\n    if (!T || !p || !m || !m.locale)\n      return;\n    delete m.imageReader, delete m.imageWriter;\n    const [S, P] = T, A = (a) => {\n      const { id: d } = a;\n      return t(\"GET_ITEM\", d);\n    }, D = (a) => {\n      if (!t(\"GET_ALLOW_FILE_POSTER\"))\n        return !1;\n      const d = A(a);\n      return d ? t(\"GET_FILE_POSTER_FILTER_ITEM\")(d) ? !!d.getMetadata(\"poster\") : !1 : void 0;\n    }, U = ({ root: a, props: d, action: l }) => {\n      const { handleEditorResponse: u } = l, R = A(d), Y = Q(R.file) || Z(R.file), Ee = Y ? R.file : R.source, C = g({\n        ...m,\n        imageReader: S(P),\n        src: Ee\n      });\n      C.on(\"load\", ({ size: V }) => {\n        let F = R.getMetadata(\"imageState\");\n        !F && O && (F = O(C, V, R.getMetadata())), C.imageState = {\n          ...G,\n          ...F\n        };\n      }), C.on(\"process\", ({ src: V, imageState: F }) => {\n        Y || R.setFile(V), R.setMetadata(\"imageState\", F), u && u(!0);\n      }), C.on(\"close\", () => {\n        u && u(!1);\n      });\n    }, M = ({ root: a, props: d }) => {\n      const { id: l } = d, u = t(\"GET_ITEM\", l);\n      if (!u)\n        return;\n      const R = u.file;\n      t(\"GET_IMAGE_EDITOR_SUPPORT_IMAGE\")(R) && (t(\"GET_ALLOW_FILE_POSTER\") && !u.getMetadata(\"poster\") && a.dispatch(\"REQUEST_CREATE_IMAGE_POSTER\", { id: l }), !(!t(\"GET_IMAGE_EDITOR_ALLOW_EDIT\") || !t(\"GET_IMAGE_EDITOR_SUPPORT_EDIT\")) && L(a, d));\n    }, L = (a, d) => {\n      if (a.ref.handleEdit || (a.ref.handleEdit = (l) => {\n        l.stopPropagation(), a.dispatch(\"EDIT_ITEM\", { id: d.id });\n      }), D(d)) {\n        a.ref.editButton && a.ref.editButton.parentNode && a.ref.editButton.parentNode.removeChild(a.ref.editButton);\n        const l = r.createChildView(h, {\n          label: t(\"GET_IMAGE_EDITOR_LABEL_EDIT\"),\n          icon: t(\"GET_IMAGE_EDITOR_ICON_EDIT\"),\n          opacity: 0\n        });\n        l.element.classList.add(\"filepond--action-edit-item\"), l.element.dataset.align = t(\n          \"GET_STYLE_IMAGE_EDITOR_BUTTON_EDIT_ITEM_POSITION\"\n        ), l.on(\"click\", a.ref.handleEdit), a.ref.buttonEditItem = r.appendChildView(l);\n      } else {\n        a.ref.buttonEditItem && a.removeChildView(a.ref.buttonEditItem);\n        const l = r.element.querySelector(\".filepond--file-info-main\"), u = document.createElement(\"button\");\n        u.className = \"filepond--action-edit-item-alt\", u.type = \"button\", u.innerHTML = t(\"GET_IMAGE_EDITOR_ICON_EDIT\") + \"<span>\" + t(\"GET_IMAGE_EDITOR_LABEL_EDIT\") + \"</span>\", u.addEventListener(\"click\", a.ref.handleEdit), l.appendChild(u), a.ref.editButton = u;\n      }\n    }, K = ({ root: a, props: d, action: l }) => {\n      if (/imageState/.test(l.change.key) && t(\"GET_ALLOW_FILE_POSTER\"))\n        return a.dispatch(\"REQUEST_CREATE_IMAGE_POSTER\", { id: d.id });\n      /poster/.test(l.change.key) && (!t(\"GET_IMAGE_EDITOR_ALLOW_EDIT\") || !t(\"GET_IMAGE_EDITOR_SUPPORT_EDIT\") || L(a, d));\n    };\n    r.registerDestroyer(({ root: a }) => {\n      a.ref.buttonEditItem && a.ref.buttonEditItem.off(\"click\", a.ref.handleEdit), a.ref.editButton && a.ref.editButton.removeEventListener(\"click\", a.ref.handleEdit);\n    });\n    const N = {\n      EDIT_ITEM: U,\n      DID_LOAD_ITEM: M,\n      DID_UPDATE_ITEM_METADATA: K,\n      DID_REMOVE_ITEM: ({ props: a }) => {\n        const { id: d } = a, l = t(\"GET_ITEM\", d);\n        if (!l)\n          return;\n        const u = l.getMetadata(\"poster\");\n        u && URL.revokeObjectURL(u);\n      },\n      REQUEST_CREATE_IMAGE_POSTER: ({ root: a, props: d }) => J(a.query, A(d)),\n      DID_FILE_POSTER_LOAD: void 0\n    };\n    if (E) {\n      const a = ({ root: d }) => {\n        d.ref.buttonEditItem && (d.ref.buttonEditItem.opacity = 1);\n      };\n      N.DID_FILE_POSTER_LOAD = a;\n    }\n    r.registerWriter(c(N));\n  }), o(\n    \"SHOULD_PREPARE_OUTPUT\",\n    (i, { query: n, change: r, item: t }) => new Promise((E) => {\n      if (!n(\"GET_IMAGE_EDITOR_SUPPORT_IMAGE\")(t.file) || r && !/imageState/.test(r.key))\n        return E(!1);\n      E(!n(\"IS_ASYNC\"));\n    })\n  );\n  const se = (i, n, r) => new Promise((t) => {\n    if (!re(i) || r.archived || !Q(n) && !Z(n) || !i(\"GET_IMAGE_EDITOR_SUPPORT_IMAGE\")(n))\n      return t(!1);\n    me(n).then(() => {\n      const E = i(\"GET_IMAGE_TRANSFORM_IMAGE_FILTER\");\n      if (E) {\n        const I = E(n);\n        if (typeof I == \"boolean\")\n          return t(I);\n        if (typeof I.then == \"function\")\n          return I.then(t);\n      }\n      t(!0);\n    }).catch(() => {\n      const E = i(\"GET_IMAGE_EDITOR_SUPPORT_IMAGE_FORMAT\");\n      if (E && E(n)) {\n        t(!0);\n        return;\n      }\n      t(!1);\n    });\n  });\n  return o(\"PREPARE_OUTPUT\", (i, { query: n, item: r }) => {\n    const t = (E) => new Promise((I, g) => {\n      const T = () => {\n        x.queue((p) => {\n          const m = r.getMetadata(\"imageState\"), {\n            imageProcessor: O,\n            imageReader: G,\n            imageWriter: S,\n            editorOptions: P,\n            imageState: A\n          } = v(n(\"GET_IMAGE_EDITOR\"));\n          if (!O || !G || !S || !P)\n            return;\n          const [D, U] = G, [M = q, L] = S;\n          O(E, {\n            ...P,\n            imageReader: D(U),\n            imageWriter: M(L),\n            imageState: {\n              ...A,\n              ...m\n            }\n          }).then(I).catch(g).finally(p);\n        });\n      };\n      n(\"GET_ALLOW_FILE_POSTER\") && !r.getMetadata(\"poster\") ? J(n, r, T) : T();\n    });\n    return new Promise((E) => {\n      se(n, i, r).then((I) => {\n        if (!I)\n          return E(i);\n        t(i).then((g) => {\n          const T = n(\"GET_IMAGE_EDITOR_AFTER_WRITE_IMAGE\");\n          if (T)\n            return Promise.resolve(T(g)).then(E);\n          E(g.dest);\n        });\n      });\n    });\n  }), {\n    options: {\n      // enable or disable image editing\n      allowImageEditor: [!0, s.BOOLEAN],\n      // open editor when image is dropped\n      imageEditorInstantEdit: [!1, s.BOOLEAN],\n      // allow editing\n      imageEditorAllowEdit: [!0, s.BOOLEAN],\n      // cannot edit if no WebGL or is <=IE11\n      imageEditorSupportEdit: [\n        w() && ee() && Re(),\n        s.BOOLEAN\n      ],\n      // receives file and should return true if can edit\n      imageEditorSupportImage: [te, s.FUNCTION],\n      // receives file, should return true if can be loaded with Pintura\n      imageEditorSupportImageFormat: [null, s.FUNCTION],\n      // cannot write if is <= IE11\n      imageEditorSupportWriteImage: [ee(), s.BOOLEAN],\n      // should output image\n      imageEditorWriteImage: [!0, s.BOOLEAN],\n      // receives written image and can return single or more images\n      imageEditorBeforeOpenImage: [void 0, s.FUNCTION],\n      // receives written image and can return single or more images\n      imageEditorAfterWriteImage: [void 0, s.FUNCTION],\n      // editor object\n      imageEditor: [null, s.OBJECT],\n      // the icon to use for the edit button\n      imageEditorIconEdit: [\n        '<svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M8.5 17h1.586l7-7L15.5 8.414l-7 7V17zm-1.707-2.707l8-8a1 1 0 0 1 1.414 0l3 3a1 1 0 0 1 0 1.414l-8 8A1 1 0 0 1 10.5 19h-3a1 1 0 0 1-1-1v-3a1 1 0 0 1 .293-.707z\" fill=\"currentColor\" fill-rule=\"nonzero\"/></svg>',\n        s.STRING\n      ],\n      // the icon to use for the edit button\n      imageEditorLabelEdit: [\"edit\", s.STRING],\n      // location of processing button\n      styleImageEditorButtonEditItemPosition: [\"bottom center\", s.STRING]\n    }\n  };\n};\nw() && document.dispatchEvent(new CustomEvent(\"FilePond:pluginloaded\", { detail: Pe }));\nexport {\n  Pe as default\n};\n", "export default {\n    labelIdle: 'Dateien ablegen oder <span class=\"filepond--label-action\"> ausw\u00E4hlen </span>',\n    labelInvalidField: 'Feld beinhaltet ung\u00FCltige Dateien',\n    labelFileWaitingForSize: 'Dateigr\u00F6\u00DFe berechnen',\n    labelFileSizeNotAvailable: 'Dateigr\u00F6\u00DFe nicht verf\u00FCgbar',\n    labelFileLoading: 'Laden',\n    labelFileLoadError: 'Fehler beim Laden',\n    labelFileProcessing: 'Upload l\u00E4uft',\n    labelFileProcessingComplete: 'Upload abgeschlossen',\n    labelFileProcessingAborted: 'Upload abgebrochen',\n    labelFileProcessingError: 'Fehler beim Upload',\n    labelFileProcessingRevertError: 'Fehler beim Wiederherstellen',\n    labelFileRemoveError: 'Fehler beim L\u00F6schen',\n    labelTapToCancel: 'abbrechen',\n    labelTapToRetry: 'erneut versuchen',\n    labelTapToUndo: 'r\u00FCckg\u00E4ngig',\n    labelButtonRemoveItem: 'Entfernen',\n    labelButtonAbortItemLoad: 'Verwerfen',\n    labelButtonRetryItemLoad: 'Erneut versuchen',\n    labelButtonAbortItemProcessing: 'Abbrechen',\n    labelButtonUndoItemProcessing: 'R\u00FCckg\u00E4ngig',\n    labelButtonRetryItemProcessing: 'Erneut versuchen',\n    labelButtonProcessItem: 'Upload',\n    labelMaxFileSizeExceeded: 'Datei ist zu gro\u00DF',\n    labelMaxFileSize: 'Maximale Dateigr\u00F6\u00DFe: {filesize}',\n    labelMaxTotalFileSizeExceeded: 'Maximale gesamte Dateigr\u00F6\u00DFe \u00FCberschritten',\n    labelMaxTotalFileSize: 'Maximale gesamte Dateigr\u00F6\u00DFe: {filesize}',\n    labelFileTypeNotAllowed: 'Dateityp ung\u00FCltig',\n    fileValidateTypeLabelExpectedTypes: 'Erwartet {allButLastType} oder {lastType}',\n    imageValidateSizeLabelFormatError: 'Bildtyp nicht unterst\u00FCtzt',\n    imageValidateSizeLabelImageSizeTooSmall: 'Bild ist zu klein',\n    imageValidateSizeLabelImageSizeTooBig: 'Bild ist zu gro\u00DF',\n    imageValidateSizeLabelExpectedMinSize: 'Mindestgr\u00F6\u00DFe: {minWidth} \u00D7 {minHeight}',\n    imageValidateSizeLabelExpectedMaxSize: 'Maximale Gr\u00F6\u00DFe: {maxWidth} \u00D7 {maxHeight}',\n    imageValidateSizeLabelImageResolutionTooLow: 'Aufl\u00F6sung ist zu niedrig',\n    imageValidateSizeLabelImageResolutionTooHigh: 'Aufl\u00F6sung ist zu hoch',\n    imageValidateSizeLabelExpectedMinResolution: 'Mindestaufl\u00F6sung: {minResolution}',\n    imageValidateSizeLabelExpectedMaxResolution: 'Maximale Aufl\u00F6sung: {maxResolution}'\n  };", "export default {\n    labelIdle: 'Drag & Drop your files or <span class=\"filepond--label-action\"> Browse </span>',\n    labelInvalidField: 'Field contains invalid files',\n    labelFileWaitingForSize: 'Waiting for size',\n    labelFileSizeNotAvailable: 'Size not available',\n    labelFileLoading: 'Loading',\n    labelFileLoadError: 'Error during load',\n    labelFileProcessing: 'Uploading',\n    labelFileProcessingComplete: 'Upload complete',\n    labelFileProcessingAborted: 'Upload cancelled',\n    labelFileProcessingError: 'Error during upload',\n    labelFileProcessingRevertError: 'Error during revert',\n    labelFileRemoveError: 'Error during remove',\n    labelTapToCancel: 'tap to cancel',\n    labelTapToRetry: 'tap to retry',\n    labelTapToUndo: 'tap to undo',\n    labelButtonRemoveItem: 'Remove',\n    labelButtonAbortItemLoad: 'Abort',\n    labelButtonRetryItemLoad: 'Retry',\n    labelButtonAbortItemProcessing: 'Cancel',\n    labelButtonUndoItemProcessing: 'Undo',\n    labelButtonRetryItemProcessing: 'Retry',\n    labelButtonProcessItem: 'Upload',\n    labelMaxFileSizeExceeded: 'File is too large',\n    labelMaxFileSize: 'Maximum file size is {filesize}',\n    labelMaxTotalFileSizeExceeded: 'Maximum total size exceeded',\n    labelMaxTotalFileSize: 'Maximum total file size is {filesize}',\n    labelFileTypeNotAllowed: 'File of invalid type',\n    fileValidateTypeLabelExpectedTypes: 'Expects {allButLastType} or {lastType}',\n    imageValidateSizeLabelFormatError: 'Image type not supported',\n    imageValidateSizeLabelImageSizeTooSmall: 'Image is too small',\n    imageValidateSizeLabelImageSizeTooBig: 'Image is too big',\n    imageValidateSizeLabelExpectedMinSize: 'Minimum size is {minWidth} \u00D7 {minHeight}',\n    imageValidateSizeLabelExpectedMaxSize: 'Maximum size is {maxWidth} \u00D7 {maxHeight}',\n    imageValidateSizeLabelImageResolutionTooLow: 'Resolution is too low',\n    imageValidateSizeLabelImageResolutionTooHigh: 'Resolution is too high',\n    imageValidateSizeLabelExpectedMinResolution: 'Minimum resolution is {minResolution}',\n    imageValidateSizeLabelExpectedMaxResolution: 'Maximum resolution is {maxResolution}'\n};\n", "export default {\n    labelIdle: 'Arrastra y suelta tus archivos o <span class = \"filepond--label-action\"> Examina <span>',\n    labelInvalidField: \"El campo contiene archivos inv\u00E1lidos\",\n    labelFileWaitingForSize: \"Esperando tama\u00F1o\",\n    labelFileSizeNotAvailable: \"Tama\u00F1o no disponible\",\n    labelFileLoading: \"Cargando\",\n    labelFileLoadError: \"Error durante la carga\",\n    labelFileProcessing: \"Subiendo\",\n    labelFileProcessingComplete: \"Subida completa\",\n    labelFileProcessingAborted: \"Subida cancelada\",\n    labelFileProcessingError: \"Error durante la subida\",\n    labelFileProcessingRevertError: \"Error durante la reversi\u00F3n\",\n    labelFileRemoveError: \"Error durante la eliminaci\u00F3n\",\n    labelTapToCancel: \"toca para cancelar\",\n    labelTapToRetry: \"tocar para reintentar\",\n    labelTapToUndo: \"tocar para deshacer\",\n    labelButtonRemoveItem: \"Eliminar\",\n    labelButtonAbortItemLoad: \"Cancelar\",\n    labelButtonRetryItemLoad: \"Reintentar\",\n    labelButtonAbortItemProcessing: \"Cancelar\",\n    labelButtonUndoItemProcessing: \"Deshacer\",\n    labelButtonRetryItemProcessing: \"Reintentar\",\n    labelButtonProcessItem: \"Subir\",\n    labelMaxFileSizeExceeded: \"El archivo es demasiado grande\",\n    labelMaxFileSize: \"El tama\u00F1o m\u00E1ximo del archivo es {filesize}\",\n    labelMaxTotalFileSizeExceeded: \"Tama\u00F1o total m\u00E1ximo excedido\",\n    labelMaxTotalFileSize: \"El tama\u00F1o total m\u00E1ximo del archivo es {filesize}\",\n    labelFileTypeNotAllowed: \"Archivo de tipo inv\u00E1lido\",\n    fileValidateTypeLabelExpectedTypes: \"Espera {allButLastType} o {lastType}\",\n    imageValidateSizeLabelFormatError: \"Tipo de imagen no soportada\",\n    imageValidateSizeLabelImageSizeTooSmall: \"La imagen es demasiado peque\u00F1a\",\n    imageValidateSizeLabelImageSizeTooBig: \"La imagen es demasiado grande\",\n    imageValidateSizeLabelExpectedMinSize: \"El tama\u00F1o m\u00EDnimo es {minWidth} x {minHeight}\",\n    imageValidateSizeLabelExpectedMaxSize: \"El tama\u00F1o m\u00E1ximo es {maxWidth} x {maxHeight}\",\n    imageValidateSizeLabelImageResolutionTooLow: \"La resoluci\u00F3n es demasiado baja\",\n    imageValidateSizeLabelImageResolutionTooHigh: \"La resoluci\u00F3n es demasiado alta\",\n    imageValidateSizeLabelExpectedMinResolution: \"La resoluci\u00F3n m\u00EDnima es {minResolution}\",\n    imageValidateSizeLabelExpectedMaxResolution: \"La resoluci\u00F3n m\u00E1xima es {maxResolution}\",\n};\n", "export default {\n    labelIdle: 'Faites glisser vos fichiers ou <span class = \"filepond--label-action\"> Parcourir </span>',\n    labelInvalidField: \"Le champ contient des fichiers invalides\",\n    labelFileWaitingForSize: \"En attente de taille\",\n    labelFileSizeNotAvailable: \"Taille non disponible\",\n    labelFileLoading: \"Chargement\",\n    labelFileLoadError: \"Erreur durant le chargement\",\n    labelFileProcessing: \"Traitement\",\n    labelFileProcessingComplete: \"Traitement effectu\u00E9\",\n    labelFileProcessingAborted: \"Traitement interrompu\",\n    labelFileProcessingError: \"Erreur durant le traitement\",\n    labelFileProcessingRevertError: \"Erreur durant la restauration\",\n    labelFileRemoveError: \"Erreur durant la suppression\",\n    labelTapToCancel: \"appuyer pour annuler\",\n    labelTapToRetry: \"appuyer pour r\u00E9essayer\",\n    labelTapToUndo: \"appuyer pour revenir en arri\u00E8re\",\n    labelButtonRemoveItem: \"Retirer\",\n    labelButtonAbortItemLoad: \"Annuler\",\n    labelButtonRetryItemLoad: \"Recommencer\",\n    labelButtonAbortItemProcessing: \"Annuler\",\n    labelButtonUndoItemProcessing: \"Revenir en arri\u00E8re\",\n    labelButtonRetryItemProcessing: \"Recommencer\",\n    labelButtonProcessItem: \"Transf\u00E9rer\",\n    labelMaxFileSizeExceeded: \"Le fichier est trop volumineux\",\n    labelMaxFileSize: \"La taille maximale de fichier est {filesize}\",\n    labelMaxTotalFileSizeExceeded: \"Taille totale maximale d\u00E9pass\u00E9e\",\n    labelMaxTotalFileSize: \"La taille totale maximale des fichiers est {filesize}\",\n    labelFileTypeNotAllowed: \"Fichier non valide\",\n    fileValidateTypeLabelExpectedTypes: \"Attendu {allButLastType} ou {lastType}\",\n    imageValidateSizeLabelFormatError: \"Type d'image non pris en charge\",\n    imageValidateSizeLabelImageSizeTooSmall: \"L'image est trop petite\",\n    imageValidateSizeLabelImageSizeTooBig: \"L'image est trop grande\",\n    imageValidateSizeLabelExpectedMinSize: \"La taille minimale est {minWidth} \u00D7 {minHeight}\",\n    imageValidateSizeLabelExpectedMaxSize: \"La taille maximale est {maxWidth} \u00D7 {maxHeight}\",\n    imageValidateSizeLabelImageResolutionTooLow: \"La r\u00E9solution est trop faible\",\n    imageValidateSizeLabelImageResolutionTooHigh: \"La r\u00E9solution est trop \u00E9lev\u00E9e\",\n    imageValidateSizeLabelExpectedMinResolution: \"La r\u00E9solution minimale est {minResolution}\",\n    imageValidateSizeLabelExpectedMaxResolution: \"La r\u00E9solution maximale est {maxResolution}\",\n};\n", "export default {\n    labelIdle: 'Trascina e rilascia i tuoi file oppure <span class=\"filepond--label-action\"> Sfoglia <span>',\n    labelInvalidField: \"Il campo contiene dei file non validi\",\n    labelFileWaitingForSize: \"In attesa della dimensione\",\n    labelFileSizeNotAvailable: \"Dimensione non disponibile\",\n    labelFileLoading: \"Caricamento\",\n    labelFileLoadError: \"Errore durante il caricamento\",\n    labelFileProcessing: \"Caricamento\",\n    labelFileProcessingComplete: \"Caricamento completato\",\n    labelFileProcessingAborted: \"Caricamento cancellato\",\n    labelFileProcessingError: \"Errore durante il caricamento\",\n    labelFileProcessingRevertError: \"Errore durante il ripristino\",\n    labelFileRemoveError: \"Errore durante l'eliminazione\",\n    labelTapToCancel: \"tocca per cancellare\",\n    labelTapToRetry: \"tocca per riprovare\",\n    labelTapToUndo: \"tocca per ripristinare\",\n    labelButtonRemoveItem: \"Elimina\",\n    labelButtonAbortItemLoad: \"Cancella\",\n    labelButtonRetryItemLoad: \"Ritenta\",\n    labelButtonAbortItemProcessing: \"Cancella\",\n    labelButtonUndoItemProcessing: \"Indietro\",\n    labelButtonRetryItemProcessing: \"Ritenta\",\n    labelButtonProcessItem: \"Carica\",\n    labelMaxFileSizeExceeded: \"La dimensione del file \u00E8 eccessiva\",\n    labelMaxFileSize: \"La dimensione massima del file \u00E8 {filesize}\",\n    labelMaxTotalFileSizeExceeded: \"Dimensione totale massima superata\",\n    labelMaxTotalFileSize: \"La dimensione massima totale dei file \u00E8 {filesize}\",\n    labelFileTypeNotAllowed: \"File non supportato\",\n    fileValidateTypeLabelExpectedTypes: \"Aspetta {allButLastType} o {lastType}\",\n    imageValidateSizeLabelFormatError: \"Tipo di immagine non supportata\",\n    imageValidateSizeLabelImageSizeTooSmall: \"L'immagine \u00E8 troppo piccola\",\n    imageValidateSizeLabelImageSizeTooBig: \"L'immagine \u00E8 troppo grande\",\n    imageValidateSizeLabelExpectedMinSize: \"La dimensione minima \u00E8 {minWidth} \u00D7 {minHeight}\",\n    imageValidateSizeLabelExpectedMaxSize: \"La dimensione massima \u00E8 {maxWidth} \u00D7 {maxHeight}\",\n    imageValidateSizeLabelImageResolutionTooLow: \"La risoluzione \u00E8 troppo bassa\",\n    imageValidateSizeLabelImageResolutionTooHigh: \"La risoluzione \u00E8 troppo alta\",\n    imageValidateSizeLabelExpectedMinResolution: \"La risoluzione minima \u00E8 {minResolution}\",\n    imageValidateSizeLabelExpectedMaxResolution: \"La risoluzione massima \u00E8 {maxResolution}\",\n};\n", "export default {\n    labelIdle: 'Drag & Drop je bestanden of <span class=\"filepond--label-action\"> Bladeren </span>',\n    labelInvalidField: 'Veld bevat ongeldige bestanden',\n    labelFileWaitingForSize: 'Wachten op grootte',\n    labelFileSizeNotAvailable: 'Grootte niet beschikbaar',\n    labelFileLoading: 'Laden',\n    labelFileLoadError: 'Fout tijdens laden',\n    labelFileProcessing: 'Uploaden',\n    labelFileProcessingComplete: 'Upload afgerond',\n    labelFileProcessingAborted: 'Upload geannuleerd',\n    labelFileProcessingError: 'Fout tijdens upload',\n    labelFileProcessingRevertError: 'Fout bij herstellen',\n    labelFileRemoveError: 'Fout bij verwijderen',\n    labelTapToCancel: 'tik om te annuleren',\n    labelTapToRetry: 'tik om opnieuw te proberen',\n    labelTapToUndo: 'tik om ongedaan te maken',\n    labelButtonRemoveItem: 'Verwijderen',\n    labelButtonAbortItemLoad: 'Afbreken',\n    labelButtonRetryItemLoad: 'Opnieuw proberen',\n    labelButtonAbortItemProcessing: 'Annuleren',\n    labelButtonUndoItemProcessing: 'Ongedaan maken',\n    labelButtonRetryItemProcessing: 'Opnieuw proberen',\n    labelButtonProcessItem: 'Upload',\n    labelMaxFileSizeExceeded: 'Bestand is te groot',\n    labelMaxFileSize: 'Maximale bestandsgrootte is {filesize}',\n    labelMaxTotalFileSizeExceeded: 'Maximale totale grootte overschreden',\n    labelMaxTotalFileSize: 'Maximale totale bestandsgrootte is {filesize}',\n    labelFileTypeNotAllowed: 'Ongeldig bestandstype',\n    fileValidateTypeLabelExpectedTypes: 'Verwacht {allButLastType} of {lastType}',\n    imageValidateSizeLabelFormatError: 'Afbeeldingstype niet ondersteund',\n    imageValidateSizeLabelImageSizeTooSmall: 'Afbeelding is te klein',\n    imageValidateSizeLabelImageSizeTooBig: 'Afbeelding is te groot',\n    imageValidateSizeLabelExpectedMinSize: 'Minimale afmeting is {minWidth} \u00D7 {minHeight}',\n    imageValidateSizeLabelExpectedMaxSize: 'Maximale afmeting is {maxWidth} \u00D7 {maxHeight}',\n    imageValidateSizeLabelImageResolutionTooLow: 'Resolutie is te laag',\n    imageValidateSizeLabelImageResolutionTooHigh: 'Resolution is too high',\n    imageValidateSizeLabelExpectedMinResolution: 'Minimale resolutie is {minResolution}',\n    imageValidateSizeLabelExpectedMaxResolution: 'Maximale resolutie is {maxResolution}'\n};\n", "export default {\n    labelIdle: 'Przeci\u0105gnij i upu\u015B\u0107 lub <span class=\"filepond--label-action\">wybierz</span> pliki',\n    labelInvalidField: 'Nieprawid\u0142owe pliki',\n    labelFileWaitingForSize: 'Pobieranie rozmiaru',\n    labelFileSizeNotAvailable: 'Nieznany rozmiar',\n    labelFileLoading: 'Wczytywanie',\n    labelFileLoadError: 'B\u0142\u0105d wczytywania',\n    labelFileProcessing: 'Przesy\u0142anie',\n    labelFileProcessingComplete: 'Przes\u0142ano',\n    labelFileProcessingAborted: 'Przerwano',\n    labelFileProcessingError: 'Przesy\u0142anie nie powiod\u0142o si\u0119',\n    labelFileProcessingRevertError: 'Co\u015B posz\u0142o nie tak',\n    labelFileRemoveError: 'Nieudane usuni\u0119cie',\n    labelTapToCancel: 'Anuluj',\n    labelTapToRetry: 'Pon\u00F3w',\n    labelTapToUndo: 'Cofnij',\n    labelButtonRemoveItem: 'Usu\u0144',\n    labelButtonAbortItemLoad: 'Przerwij',\n    labelButtonRetryItemLoad: 'Pon\u00F3w',\n    labelButtonAbortItemProcessing: 'Anuluj',\n    labelButtonUndoItemProcessing: 'Cofnij',\n    labelButtonRetryItemProcessing: 'Pon\u00F3w',\n    labelButtonProcessItem: 'Prze\u015Blij',\n    labelMaxFileSizeExceeded: 'Plik jest zbyt du\u017Cy',\n    labelMaxFileSize: 'Dopuszczalna wielko\u015B\u0107 pliku to {filesize}',\n    labelMaxTotalFileSizeExceeded: 'Przekroczono \u0142\u0105czny rozmiar plik\u00F3w',\n    labelMaxTotalFileSize: '\u0141\u0105czny rozmiar plik\u00F3w nie mo\u017Ce przekroczy\u0107 {filesize}',\n    labelFileTypeNotAllowed: 'Niedozwolony rodzaj pliku',\n    fileValidateTypeLabelExpectedTypes: 'Oczekiwano {allButLastType} lub {lastType}',\n    imageValidateSizeLabelFormatError: 'Nieobs\u0142ugiwany format obrazu',\n    imageValidateSizeLabelImageSizeTooSmall: 'Obraz jest zbyt ma\u0142y',\n    imageValidateSizeLabelImageSizeTooBig: 'Obraz jest zbyt du\u017Cy',\n    imageValidateSizeLabelExpectedMinSize: 'Minimalne wymiary obrazu to {minWidth}\u00D7{minHeight}',\n    imageValidateSizeLabelExpectedMaxSize: 'Maksymalna wymiary obrazu to {maxWidth}\u00D7{maxHeight}',\n    imageValidateSizeLabelImageResolutionTooLow: 'Rozdzielczo\u015B\u0107 jest zbyt niska',\n    imageValidateSizeLabelImageResolutionTooHigh: 'Rozdzielczo\u015B\u0107 jest zbyt wysoka',\n    imageValidateSizeLabelExpectedMinResolution: 'Minimalna rozdzielczo\u015B\u0107 to {minResolution}',\n    imageValidateSizeLabelExpectedMaxResolution: 'Maksymalna rozdzielczo\u015B\u0107 to {maxResolution}'\n};\n", "function normalizeLocale(locale) {\n  return (locale || 'en')\n    .toString()\n    .split(/[-_]/)[0]\n    .toLowerCase();\n}\n\nimport labels_de_DE from 'filepond/locale/de-de';\nimport labels_en_US from 'filepond/locale/en-en';\nimport labels_es_ES from 'filepond/locale/es-es';\nimport labels_fr_FR from 'filepond/locale/fr-fr';\nimport labels_it_IT from 'filepond/locale/it-it';\nimport labels_nl_NL from 'filepond/locale/nl-nl';\nimport labels_pl_PL from 'filepond/locale/pl-pl';\n\nconst NUMBER_FORMAT = {\n  de: { labelDecimalSeparator: ',', labelThousandsSeparator: '.' },\n  en: { labelDecimalSeparator: '.', labelThousandsSeparator: ',' },\n  es: { labelDecimalSeparator: ',', labelThousandsSeparator: '.' },\n  fr: { labelDecimalSeparator: ',', labelThousandsSeparator: ' ' },\n  it: { labelDecimalSeparator: ',', labelThousandsSeparator: '.' },\n  nl: { labelDecimalSeparator: ',', labelThousandsSeparator: '.' },\n  pl: { labelDecimalSeparator: ',', labelThousandsSeparator: ' ' },\n};\n\nexport function filePondLabelsForLocale(locale) {\n  const lang = normalizeLocale(locale);\n\n  // Only ship the locales we actually support in Rails. Unknown locales fall back to English.\n  const base =\n    lang === 'de' ? labels_de_DE :\n    lang === 'es' ? labels_es_ES :\n    lang === 'fr' ? labels_fr_FR :\n    lang === 'it' ? labels_it_IT :\n    lang === 'nl' ? labels_nl_NL :\n    lang === 'pl' ? labels_pl_PL :\n    labels_en_US;\n\n  return {\n    ...(NUMBER_FORMAT[lang] || NUMBER_FORMAT.en),\n    ...base,\n  };\n}\n\n", "const IconCross =\n    '<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"></path></path></g>';\n\nconst CharacterA =\n    '<path fill=\"none\" d=\"M9 15 L12 9 L15 15 M10 13.5 h3\" stroke=\"currentColor\" stroke-width=\".125em\"/>';\n\nexport default {\n    // generic\n    labelReset: 'Zur\u00FCcksetzen',\n    labelDefault: 'Standard',\n    labelAuto: 'Autom.',\n    labelNone: 'Keine',\n    labelEdit: 'Bearbeiten',\n    labelClose: 'Schlie\u00DFen',\n    labelSupportError: `{features} wird in diesem Browser nicht unterst\u00FCtzt`,\n    labelMemoryError: `Dem Browser ist der Arbeitsspeicher ausgegangen`,\n\n    // defaults\n    labelColor: 'Farbe',\n    labelWidth: 'Breite',\n    labelSize: 'Gr\u00F6\u00DFe',\n    labelOffset: 'Versatz',\n    labelAmount: 'Betragen',\n    labelInset: 'Vertiefung',\n    labelRadius: 'Radius',\n\n    // controls\n    labelColorPalette: 'Farbpalette',\n\n    // sizes\n    labelSizeExtraSmall: 'Extraklein',\n    labelSizeSmall: 'Klein',\n    labelSizeMediumSmall: 'Mittelklein',\n    labelSizeMedium: 'Mittel',\n    labelSizeMediumLarge: 'Mittelgro\u00DF',\n    labelSizeLarge: 'Gro\u00DF',\n    labelSizeExtraLarge: 'Extragro\u00DF',\n\n    // unused?\n    labelButtonRevert: 'R\u00FCckg\u00E4ngig',\n    labelButtonCancel: 'Abbrechen',\n    labelButtonUndo: 'Zur\u00FCcknehmen',\n    labelButtonRedo: 'Erneut durchf\u00FChren',\n    labelButtonExport: 'Fertig',\n\n    // zoom\n    labelZoom: 'Zoom',\n    labelZoomIn: 'Hineinzoomen',\n    labelZoomOut: 'Rauszoomen',\n    labelZoomFit: 'Zoom passen',\n    labelZoomActual: 'Tats\u00E4chlichen Gr\u00F6\u00DFe',\n    iconZoomIn: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M8 12 h8 M12 8 v8\" />',\n    iconZoomOut: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M9 12 h6\" />',\n\n    // icon\n    iconSupportError: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><g><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></g>`,\n    iconButtonClose: IconCross,\n    iconButtonRevert: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M7.388 18.538a8 8 0 10-2.992-9.03\"/><path fill=\"currentColor\" d=\"M2.794 11.696L2.37 6.714l5.088 3.18z\"/><path d=\"M12 8v4M12 12l4 2\"/></g>`,\n    iconButtonUndo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4\"/><path fill=\"currentColor\" d=\"M5 8l4-3v6z\"/></g>`,\n    iconButtonRedo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4\"/><path fill=\"currentColor\" d=\"M19 8l-4-3v6z\"/></g>`,\n    iconButtonExport: `<polyline points=\"20 6 9 17 4 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"></polyline>`,\n\n    // status\n    statusLabelButtonClose: 'Schlie\u00DFen',\n    statusIconButtonClose: IconCross,\n\n    // new status options\n    statusImageLoadNone: 'Warten auf Bild',\n    statusImageLoadMinSize: 'Mindestgr\u00F6\u00DFe ist {minWidth} &times; {minHeight}',\n    statusImageLoadError: 'Fehler beim Laden des Bilds',\n    statusImageLoadPrepare: 'Bild wird geladen&hellip;',\n    statusImageLoadBusy: 'Vorschau wird erstellt&hellip;',\n    statusImageUploadError: 'Fehler beim Hochladen des Bilds',\n    statusImageUploadBusy: 'Bild wird hochgeladen&hellip;',\n    statusImageProcessError: 'Fehler bei Bildverarbeitung',\n    statusImageProcessBusy: 'Bild wird verarbeitet&hellip;',\n};\n\nexport const MarkupEditor = {\n    shapeLabelButtonSelectSticker: 'Bild w\u00E4hlen',\n    shapeIconButtonSelectSticker: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.0625em\"><path d=\"M8 21 L15 11 L19 15\"/><path d=\"M15 2 v5 h5\"/><path d=\"M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z\"/></g><circle fill=\"currentColor\" cx=\"10\" cy=\"8\" r=\"1.5\"/>`,\n\n    shapeIconButtonFlipHorizontal: `<g stroke=\"currentColor\" stroke-width=\".125em\"><path fill=\"none\" d=\"M6 6.5h5v11H6z\"/><path fill=\"currentColor\" d=\"M15 6.5h3v11h-3z\"/><path d=\"M11 4v16\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonFlipVertical: `<g stroke=\"currentColor\" stroke-width=\".125em\"><rect x=\"7\" y=\"8\" width=\"11\" height=\"5\" fill=\"none\"/><rect x=\"7\" y=\"17\" width=\"11\" height=\"2\" fill=\"currentColor\"/><line x1=\"5\" y1=\"13\" x2=\"20\" y2=\"13\"/></g>`,\n    shapeIconButtonRemove: `<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 7h9z\"/><path d=\"M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z\" fill=\"currentColor\"/><rect fill=\"currentColor\" x=\"10\" y=\"5\" width=\"4\" height=\"3\" rx=\"1\"/></g>`,\n    shapeIconButtonDuplicate: `<g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142\" stroke=\"currentColor\" stroke-width=\".125em\"/><path d=\"M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonMoveToFront: `<g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"currentColor\" x=\"11\" y=\"13\" width=\"8\" height=\"2\" rx=\"1\"/><rect fill=\"currentColor\" x=\"9\" y=\"17\" width=\"10\" height=\"2\" rx=\"1\"/><path d=\"M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z\" stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\"/></g>`,\n\n    shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,\n    shapeIconButtonTextLayoutAutoHeight: `<g fill=\"currentColor\"><circle cx=\"4\" cy=\"12\" r=\"1.5\"/><circle cx=\"20\" cy=\"12\" r=\"1.5\"/></g>${CharacterA}`,\n    shapeIconButtonTextLayoutFixedSize: `<g fill=\"currentColor\"><circle cx=\"5\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"19\" r=\"1.5\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\"/></g>${CharacterA}`,\n\n    shapeTitleButtonTextLayoutAutoWidth: 'Autom. Breite',\n    shapeTitleButtonTextLayoutAutoHeight: 'Autom. H\u00F6he',\n    shapeTitleButtonTextLayoutFixedSize: 'Fixierte Gr\u00F6\u00DFe',\n\n    shapeTitleButtonFlipHorizontal: 'Horizontal spiegeln',\n    shapeTitleButtonFlipVertical: 'Vertikal spiegeln',\n    shapeTitleButtonRemove: 'Entfernen',\n    shapeTitleButtonDuplicate: 'Duplizieren',\n    shapeTitleButtonMoveToFront: 'Nach vorne bewegen',\n\n    shapeLabelInputText: 'Text bearbeiten',\n\n    shapeIconInputCancel: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"/></g>`,\n    shapeIconInputConfirm: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><polyline points=\"20 6 9 17 4 12\"/></g>`,\n    shapeLabelInputCancel: 'Abbrechen',\n    shapeLabelInputConfirm: 'Best\u00E4tigen',\n\n    shapeLabelStrokeNone: 'Keine Kontur',\n\n    shapeLabelFontStyleNormal: 'Normal',\n    shapeLabelFontStyleBold: 'Fett',\n    shapeLabelFontStyleItalic: 'Kursiv',\n    shapeLabelFontStyleItalicBold: 'Fett kursiv',\n\n    shapeTitleBackgroundColor: 'F\u00FCllfarbe',\n\n    shapeTitleCornerRadius: 'Eckenradius',\n\n    shapeTitleFontFamily: 'Schriftart',\n    shapeTitleFontSize: 'Schriftgr\u00F6\u00DFe',\n    shapeTitleFontStyle: 'Schriftstil',\n\n    shapeTitleLineHeight: 'Zeilenh\u00F6he',\n\n    shapeTitleLineStart: 'Start',\n    shapeTitleLineEnd: 'Ende',\n    shapeTitleStrokeWidth: 'Linienbreite',\n    shapeTitleStrokeColor: 'Linienfarbe',\n\n    shapeTitleLineDecorationBar: 'Balken',\n    shapeTitleLineDecorationCircle: 'Kreis',\n    shapeTitleLineDecorationSquare: 'Quadrat',\n    shapeTitleLineDecorationArrow: 'Pfeil',\n    shapeTitleLineDecorationCircleSolid: 'Vollfarbe-Kreis',\n    shapeTitleLineDecorationSquareSolid: 'Vollfarbe-Quadrat',\n    shapeTitleLineDecorationArrowSolid: 'Vollfarbe-Pfeil',\n\n    shapeIconLineDecorationBar: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M16,8 V16\"/></g>`,\n    shapeIconLineDecorationCircle: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"none\" stroke-width=\".125em\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquare: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"none\" stroke-width=\".125em\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrow: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16 M13,7 l6,5 l-6,5\" fill=\"none\"/></g>`,\n    shapeIconLineDecorationCircleSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"currentColor\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquareSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"currentColor\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrowSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M13,7 l6,5 l-6,5z\" fill=\"currentColor\"/></g>`,\n\n    shapeTitleColorTransparent: 'Transparent',\n    shapeTitleColorWhite: 'Wei\u00DF',\n    shapeTitleColorSilver: 'Silber',\n    shapeTitleColorGray: 'Grau',\n    shapeTitleColorBlack: 'Schwarz',\n    shapeTitleColorNavy: 'Marineblau',\n    shapeTitleColorBlue: 'Blau',\n    shapeTitleColorAqua: 'Aquamarin',\n    shapeTitleColorTeal: 'Blaugr\u00FCn',\n    shapeTitleColorOlive: 'Olive',\n    shapeTitleColorGreen: 'Gr\u00FCn',\n    shapeTitleColorYellow: 'Gelb',\n    shapeTitleColorOrange: 'Orange',\n    shapeTitleColorRed: 'Rot',\n    shapeTitleColorMaroon: 'Kastanienbraun',\n    shapeTitleColorFuchsia: 'Purpurrot',\n    shapeTitleColorPurple: 'Lila',\n\n    shapeTitleTextOutline: 'Textumriss',\n    shapeTitleTextOutlineWidth: 'Breite',\n    shapeTitleTextShadow: 'Textschatten',\n    shapeTitleTextShadowBlur: 'Unsch\u00E4rfe',\n\n    shapeTitleTextColor: 'Schriftfarbe',\n    shapeTitleTextAlign: 'Textausrichtung',\n    shapeTitleTextAlignLeft: 'Text links ausrichten',\n    shapeTitleTextAlignCenter: 'Text zentrieren',\n    shapeTitleTextAlignRight: 'Text rechts ausrichten',\n\n    shapeIconTextAlignLeft: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"5\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"5\" y1=\"16\" x2=\"14\" y2=\"16\"/></g>`,\n    shapeIconTextAlignCenter: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"7\" y1=\"8\" x2=\"17\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"8\" y1=\"16\" x2=\"16\" y2=\"16\"/></g>`,\n    shapeIconTextAlignRight: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"9\" y1=\"8\" x2=\"19\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"11\" y1=\"16\" x2=\"19\" y2=\"16\"/></g>`,\n\n    shapeLabelToolMove: 'Verschieben',\n    shapeLabelToolView: 'Sehen',\n    shapeLabelToolSharpie: 'Marker',\n    shapeLabelToolEraser: 'Radierer',\n    shapeLabelToolPath: 'Pfad',\n    shapeLabelToolRectangle: 'Rechteck',\n    shapeLabelToolEllipse: 'Ellipse',\n    shapeLabelToolArrow: 'Pfeil',\n    shapeLabelToolLine: 'Linie',\n    shapeLabelToolText: 'Text',\n    shapeLabelToolPreset: 'Sticker',\n\n    shapeIconToolView: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.98 9.703V2.567c0-1.19 1.19-1.785 1.784-1.785.595 0 1.784.595 1.784 1.785v3.568\"/><path d=\"M14.548 9.703V4.35c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.594 1.784 1.784v2.973\"/><path d=\"M18.116 10.244V7.271c0-1.19 1.19-1.784 1.784-1.784.595 0 1.785.595 1.785 1.784 0 1.19 0 8.92-1.19 12.488-1.19 3.569-10.704 4.758-13.678 0-2.973-4.757-2.973-4.757-4.163-6.541-1.189-1.784-1.153-2.974-.594-3.568.558-.595 1.784-1.19 2.973.594 1.277 1.916 2.07 2.907 2.379 2.974V5.487c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.595 1.784 1.784V8.46\"/></g>`,\n    shapeIconToolMove: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M6 2 L6 19 L18 13 Z M13 18 L16 24\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSharpie: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolEraser: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" fill=\"none\"><g transform=\"translate(3, 15) rotate(-45)\"><rect x=\"0\" y=\"0\" width=\"18\" height=\"10\" rx=\"3\"/></g><line x1=\"11\" y1=\"21\" x2=\"18\" y2=\"21\"/><line x1=\"20\" y1=\"21\" x2=\"22\" y2=\"21\"/></g>`,\n    shapeIconToolPath: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"><circle cx=\"21\" cy=\"3\" r=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><circle cx=\"3\" cy=\"21\" r=\"2\"/><path d=\"M19 4 11 8 M8 11 4 19\"/></g>`,\n    shapeIconToolRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"1\" y=\"1\" width=\"22\" height=\"22\" rx=\"4\"/></g>`,\n    shapeIconToolEllipse: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"11\"/></g>`,\n    shapeIconToolArrow: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/><path d=\"m10 6 L21.5 1 L20 13.5\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n    shapeIconToolLine: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/></g>`,\n    shapeIconToolText: `<g stroke=\"none\" fill=\"currentColor\" transform=\"translate(6,0)\"><path d=\"M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z\"/>`,\n    shapeIconToolPreset: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"></path><path d=\"M20 17c-3 3-5 5-8 5\"></path></g>`,\n\n    shapeTitleSelectionMode: 'Auswahlmodus',\n    shapeTitleBrushSize: 'Pinselgr\u00F6\u00DFe',\n\n    shapeLabelSelectionModeNew: 'Neu',\n    shapeLabelSelectionModeAdd: 'Hinzuf\u00FCgen',\n    shapeLabelSelectionModeSubtract: 'Entfernen',\n\n    shapeLabelToolSelectionBrush: 'Pinsel',\n    shapeLabelToolSelectionLassoo: 'Lasso',\n    shapeLabelToolSelectionRectangle: 'Rechteckauswahl',\n    shapeLabelToolSelectionEllipse: 'Ellipsenauswahl',\n    shapeLabelToolSelectionPolygon: 'Polygon-Auswahl',\n\n    shapeIconSelectionModeNew: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 17H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1.5\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" fill=\"currentColor\" fill-opacity=\".25\" rx=\"2\"/></g>`,\n    shapeIconSelectionModeAdd: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><path d=\"M13 15h4M15 13v4\"/></g>`,\n    shapeIconSelectionModeSubtract: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h-6a2 2 0 0 0-1.995 1.85L9 11v6H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" rx=\"2\"/><path d=\"M13 15h4\"/></g>`,\n    shapeIconToolSelectionBrush: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSelectionLassoo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-width=\".125em\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.428 17.702a18.46 18.46 0 0 0 4.085-1.595c5.851-3.112 9.019-8.599 7.074-12.256-1.945-3.657-8.265-4.1-14.116-.988C2.619 5.974-.55 11.46 1.396 15.118c.63 1.186 1.72 2.033 3.105 2.532\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.833\" transform=\"rotate(-15 8 18.5)\"/><path stroke-linecap=\"round\" d=\"M5 18c3.347 1.048 5.514 1.881 6.5 2.5.859.54 1.517.994 1.5 2.364\"/></g>`,\n    shapeIconToolSelectionRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\"><path d=\"M9 1 h6 m4 0 h4v4 m0 4 v6 m0 4 v4h-4 m-4 0 h-6 m-4 0 h-4v-4 m0 -4 v-6 m0 -4 v-4h4\" fill=\"none\" /></g>`,\n    shapeIconToolSelectionEllipse: `<path stroke-width=\".125em\" stroke=\"currentColor\" d=\"M1.21 9.853a11.054 11.054 0 0 0 0 4.294m1.643 3.965a11.054 11.054 0 0 0 3.035 3.035m3.965 1.644a11.054 11.054 0 0 0 4.294 0m3.965-1.644a11.054 11.054 0 0 0 3.035-3.035m1.644-3.965a11.054 11.054 0 0 0 0-4.294m-1.644-3.965a11.054 11.054 0 0 0-3.035-3.035m-3.965-1.644a11.054 11.054 0 0 0-4.294 0M5.888 2.853a11.054 11.054 0 0 0-3.035 3.035\"/>`,\n    shapeIconToolSelectionPolygon:\n        '<g fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18h11V1L13 9 1 6l5 9 3 6v2\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.8\" transform=\"rotate(-2 8 18)\"/></g>',\n};\n\n// deprecated\nexport const ShapeEditor = MarkupEditor;\n", "export default {\n    cropLabel: 'Zuschneiden',\n    cropIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3\"/></g>',\n    cropIconButtonRecenter: `<path stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linejoin=\"bevel\" d=\"M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\"/>`,\n    cropIconButtonRotateLeft:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><rect x=\"3\" rx=\"1\" height=\"12\" width=\"12\" y=\"9\"/><path d=\"M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z\"/></g>',\n    cropIconButtonRotateRight:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><path d=\"M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z\"/><rect rx=\"1\" height=\"12\" width=\"12\" y=\"9\" x=\"9\"/></g>',\n    cropIconButtonFlipVertical:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z\"/><path d=\"M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z\" opacity=\".6\"/></g>',\n    cropIconButtonFlipHorizontal:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z\"/><path d=\"M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z\" opacity=\".6\"/></g>',\n\n    cropIconSelectPreset: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"4\" width=\"10\" height=\"18\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"6\" y=\"12\" width=\"17\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropIconCropBoundary: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"3\" width=\"20\" height=\"20\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"7\" y=\"8\" width=\"10\" height=\"10\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{d}\" x=\"12\" y=\"4\" width=\"10\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropLabelButtonRecenter: 'Neu zentrieren',\n    cropLabelButtonRotateLeft: 'Nach links drehen',\n    cropLabelButtonRotateRight: 'Nach rechts drehen',\n    cropLabelButtonFlipHorizontal: 'Horizontal spiegeln',\n    cropLabelButtonFlipVertical: 'Vertikal spiegeln',\n\n    cropLabelSelectPreset: 'Form zuschneiden',\n\n    cropLabelCropBoundary: 'Rand zuschneiden',\n    cropLabelCropBoundaryEdge: 'Bildkante',\n    cropLabelCropBoundaryNone: 'Keine',\n\n    cropLabelTabRotation: 'Drehung',\n    cropLabelTabZoom: 'Skalieren',\n};\n", "export default {\n    annotateLabel: 'Anmerken',\n    annotateIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z\"/></g>',\n};\n", "export default {\n    redactLabel: 'Redigieren',\n    redactIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M 4 5 l 1 -1\"/><path d=\"M 4 10 l 6 -6\"/><path d=\"M 4 15 l 11 -11\"/><path d=\"M 4 20 l 16 -16\"/><path d=\"M 9 20 l 11 -11\"/><path d=\"M 14 20 l 6 -6\"/><path d=\"M 19 20 l 1 -1\"/></g>`,\n};\n", "const IconCross =\n    '<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"></path></path></g>';\n\nconst CharacterA =\n    '<path fill=\"none\" d=\"M9 15 L12 9 L15 15 M10 13.5 h3\" stroke=\"currentColor\" stroke-width=\".125em\"/>';\n\nexport default {\n    // generic\n    labelReset: 'Reset',\n    labelDefault: 'Default',\n    labelAuto: 'Auto',\n    labelNone: 'None',\n    labelEdit: 'Edit',\n    labelClose: 'Close',\n    labelSupportError: `{features} not supported on this browser`,\n    labelMemoryError: `The browser ran out of memory`,\n\n    // defaults\n    labelColor: 'Color',\n    labelWidth: 'Width',\n    labelSize: 'Size',\n    labelOffset: 'Offset',\n    labelAmount: 'Amount',\n    labelInset: 'Inset',\n    labelRadius: 'Radius',\n\n    // controls\n    labelColorPalette: 'Color palette',\n\n    // sizes\n    labelSizeExtraSmall: 'Extra small',\n    labelSizeSmall: 'Small',\n    labelSizeMediumSmall: 'Medium small',\n    labelSizeMedium: 'Medium',\n    labelSizeMediumLarge: 'Medium large',\n    labelSizeLarge: 'Large',\n    labelSizeExtraLarge: 'Extra large',\n\n    // default buttons\n\n    labelButtonCancel: 'Cancel',\n    labelButtonUndo: 'Undo',\n    labelButtonRedo: 'Redo',\n    labelButtonRevert: 'Revert',\n    labelButtonExport: 'Done',\n\n    // zoom\n    labelZoom: 'Zoom',\n    labelZoomIn: 'Zoom in',\n    labelZoomOut: 'Zoom out',\n    labelZoomFit: 'Fit to view',\n    labelZoomActual: 'Actual size',\n    iconZoomIn: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M8 12 h8 M12 8 v8\" />',\n    iconZoomOut: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M9 12 h6\" />',\n\n    // icons\n    iconSupportError: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><g><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></g>`,\n    iconButtonClose: IconCross,\n    iconButtonRevert: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M7.388 18.538a8 8 0 10-2.992-9.03\"/><path fill=\"currentColor\" d=\"M2.794 11.696L2.37 6.714l5.088 3.18z\"/><path d=\"M12 8v4M12 12l4 2\"/></g>`,\n    iconButtonUndo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4\"/><path fill=\"currentColor\" d=\"M5 8l4-3v6z\"/></g>`,\n    iconButtonRedo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4\"/><path fill=\"currentColor\" d=\"M19 8l-4-3v6z\"/></g>`,\n    iconButtonExport: `<polyline points=\"20 6 9 17 4 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"></polyline>`,\n\n    // status\n    statusLabelButtonClose: 'Close',\n    statusIconButtonClose: IconCross,\n\n    // new status options\n    statusImageLoadNone: 'Waiting for image',\n    statusImageLoadMinSize: 'Minimum image size is {minWidth} &times; {minHeight}',\n    statusImageLoadPrepare: 'Preparing image&hellip;',\n    statusImageLoadBusy: 'Loading image&hellip;',\n    statusImageLoadError: 'Error loading image',\n    statusImageProcessBusy: 'Processing image&hellip;',\n    statusImageProcessError: 'Error processing image',\n    statusImageUploadBusy: 'Uploading image&hellip;',\n    statusImageUploadError: 'Error uploading image',\n};\n\nexport const MarkupEditor = {\n    shapeLabelButtonSelectSticker: 'Select image',\n    shapeIconButtonSelectSticker: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.0625em\"><path d=\"M8 21 L15 11 L19 15\"/><path d=\"M15 2 v5 h5\"/><path d=\"M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z\"/></g><circle fill=\"currentColor\" cx=\"10\" cy=\"8\" r=\"1.5\"/>`,\n\n    shapeIconButtonFlipHorizontal: `<g stroke=\"currentColor\" stroke-width=\".125em\"><path fill=\"none\" d=\"M6 6.5h5v11H6z\"/><path fill=\"currentColor\" d=\"M15 6.5h3v11h-3z\"/><path d=\"M11 4v16\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonFlipVertical: `<g stroke=\"currentColor\" stroke-width=\".125em\"><rect x=\"7\" y=\"8\" width=\"11\" height=\"5\" fill=\"none\"/><rect x=\"7\" y=\"17\" width=\"11\" height=\"2\" fill=\"currentColor\"/><line x1=\"5\" y1=\"13\" x2=\"20\" y2=\"13\"/></g>`,\n    shapeIconButtonRemove: `<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 7h9z\"/><path d=\"M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z\" fill=\"currentColor\"/><rect fill=\"currentColor\" x=\"10\" y=\"5\" width=\"4\" height=\"3\" rx=\"1\"/></g>`,\n    shapeIconButtonDuplicate: `<g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142\" stroke=\"currentColor\" stroke-width=\".125em\"/><path d=\"M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonMoveToFront: `<g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"currentColor\" x=\"11\" y=\"13\" width=\"8\" height=\"2\" rx=\"1\"/><rect fill=\"currentColor\" x=\"9\" y=\"17\" width=\"10\" height=\"2\" rx=\"1\"/><path d=\"M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z\" stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\"/></g>`,\n\n    shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,\n    shapeIconButtonTextLayoutAutoHeight: `<g fill=\"currentColor\"><circle cx=\"4\" cy=\"12\" r=\"1.5\"/><circle cx=\"20\" cy=\"12\" r=\"1.5\"/></g>${CharacterA}`,\n    shapeIconButtonTextLayoutFixedSize: `<g fill=\"currentColor\"><circle cx=\"5\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"19\" r=\"1.5\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\"/></g>${CharacterA}`,\n\n    shapeTitleButtonTextLayoutAutoWidth: 'Auto width',\n    shapeTitleButtonTextLayoutAutoHeight: 'Auto height',\n    shapeTitleButtonTextLayoutFixedSize: 'Fixed size',\n\n    shapeTitleButtonFlipHorizontal: 'Flip Horizontal',\n    shapeTitleButtonFlipVertical: 'Flip Vertical',\n    shapeTitleButtonRemove: 'Remove',\n    shapeTitleButtonDuplicate: 'Duplicate',\n    shapeTitleButtonMoveToFront: 'Move to front',\n\n    shapeLabelInputText: 'Edit text',\n\n    shapeIconInputCancel: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"/></g>`,\n    shapeIconInputConfirm: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><polyline points=\"20 6 9 17 4 12\"/></g>`,\n    shapeLabelInputCancel: 'Cancel',\n    shapeLabelInputConfirm: 'Confirm',\n\n    shapeLabelStrokeNone: 'No outline',\n\n    shapeLabelFontStyleNormal: 'Normal',\n    shapeLabelFontStyleBold: 'Bold',\n    shapeLabelFontStyleItalic: 'Italic',\n    shapeLabelFontStyleItalicBold: 'Bold Italic',\n\n    shapeTitleBackgroundColor: 'Fill color',\n\n    shapeTitleCornerRadius: 'Corner radius',\n\n    shapeTitleFontFamily: 'Font',\n    shapeTitleFontSize: 'Font size',\n    shapeTitleFontStyle: 'Font style',\n    shapeTitleLineHeight: 'Line height',\n\n    shapeTitleLineStart: 'Start',\n    shapeTitleLineEnd: 'End',\n    shapeTitleStrokeWidth: 'Line width',\n    shapeTitleStrokeColor: 'Line color',\n\n    shapeTitleLineDecorationBar: 'Bar',\n    shapeTitleLineDecorationCircle: 'Circle',\n    shapeTitleLineDecorationSquare: 'Square',\n    shapeTitleLineDecorationArrow: 'Arrow',\n    shapeTitleLineDecorationCircleSolid: 'Circle solid',\n    shapeTitleLineDecorationSquareSolid: 'Square solid',\n    shapeTitleLineDecorationArrowSolid: 'Arrow solid',\n\n    shapeIconLineDecorationBar: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M16,8 V16\"/></g>`,\n    shapeIconLineDecorationCircle: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"none\" stroke-width=\".125em\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquare: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"none\" stroke-width=\".125em\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrow: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16 M13,7 l6,5 l-6,5\" fill=\"none\"/></g>`,\n    shapeIconLineDecorationCircleSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"currentColor\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquareSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"currentColor\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrowSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M13,7 l6,5 l-6,5z\" fill=\"currentColor\"/></g>`,\n\n    shapeTitleColorTransparent: 'Transparent',\n    shapeTitleColorWhite: 'White',\n    shapeTitleColorSilver: 'Silver',\n    shapeTitleColorGray: 'Gray',\n    shapeTitleColorBlack: 'Black',\n    shapeTitleColorNavy: 'Navy',\n    shapeTitleColorBlue: 'Blue',\n    shapeTitleColorAqua: 'Aqua',\n    shapeTitleColorTeal: 'Teal',\n    shapeTitleColorOlive: 'Olive',\n    shapeTitleColorGreen: 'Green',\n    shapeTitleColorYellow: 'Yellow',\n    shapeTitleColorOrange: 'Orange',\n    shapeTitleColorRed: 'Red',\n    shapeTitleColorMaroon: 'Maroon',\n    shapeTitleColorFuchsia: 'Fuchsia',\n    shapeTitleColorPurple: 'Purple',\n\n    shapeTitleTextOutline: 'Text outline',\n    shapeTitleTextOutlineWidth: 'Width',\n\n    shapeTitleTextShadow: 'Text shadow',\n    shapeTitleTextShadowBlur: 'Blur',\n\n    shapeTitleTextColor: 'Font color',\n    shapeTitleTextAlign: 'Text align',\n    shapeTitleTextAlignLeft: 'Left align text',\n    shapeTitleTextAlignCenter: 'Center align text',\n    shapeTitleTextAlignRight: 'Right align text',\n\n    shapeIconTextAlignLeft: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"5\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"5\" y1=\"16\" x2=\"14\" y2=\"16\"/></g>`,\n    shapeIconTextAlignCenter: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"7\" y1=\"8\" x2=\"17\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"8\" y1=\"16\" x2=\"16\" y2=\"16\"/></g>`,\n    shapeIconTextAlignRight: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"9\" y1=\"8\" x2=\"19\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"11\" y1=\"16\" x2=\"19\" y2=\"16\"/></g>`,\n\n    shapeLabelToolMove: 'Move',\n    shapeLabelToolView: 'View',\n    shapeLabelToolSharpie: 'Sharpie',\n    shapeLabelToolEraser: 'Eraser',\n    shapeLabelToolPath: 'Path',\n    shapeLabelToolRectangle: 'Rectangle',\n    shapeLabelToolEllipse: 'Ellipse',\n    shapeLabelToolArrow: 'Arrow',\n    shapeLabelToolLine: 'Line',\n    shapeLabelToolText: 'Text',\n    shapeLabelToolPreset: 'Stickers',\n\n    shapeIconToolView: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.98 9.703V2.567c0-1.19 1.19-1.785 1.784-1.785.595 0 1.784.595 1.784 1.785v3.568\"/><path d=\"M14.548 9.703V4.35c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.594 1.784 1.784v2.973\"/><path d=\"M18.116 10.244V7.271c0-1.19 1.19-1.784 1.784-1.784.595 0 1.785.595 1.785 1.784 0 1.19 0 8.92-1.19 12.488-1.19 3.569-10.704 4.758-13.678 0-2.973-4.757-2.973-4.757-4.163-6.541-1.189-1.784-1.153-2.974-.594-3.568.558-.595 1.784-1.19 2.973.594 1.277 1.916 2.07 2.907 2.379 2.974V5.487c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.595 1.784 1.784V8.46\"/></g>`,\n    shapeIconToolMove: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M6 2 L6 19 L18 13 Z M13 18 L16 24\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSharpie: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolEraser: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" fill=\"none\"><g transform=\"translate(3, 15) rotate(-45)\"><rect x=\"0\" y=\"0\" width=\"18\" height=\"10\" rx=\"3\"/></g><line x1=\"11\" y1=\"21\" x2=\"18\" y2=\"21\"/><line x1=\"20\" y1=\"21\" x2=\"22\" y2=\"21\"/></g>`,\n    shapeIconToolPath: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"><circle cx=\"21\" cy=\"3\" r=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><circle cx=\"3\" cy=\"21\" r=\"2\"/><path d=\"M19 4 11 8 M8 11 4 19\"/></g>`,\n    shapeIconToolRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"1\" y=\"1\" width=\"22\" height=\"22\" rx=\"4\"/></g>`,\n    shapeIconToolEllipse: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"11\"/></g>`,\n    shapeIconToolArrow: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/><path d=\"m10 6 L21.5 1 L20 13.5\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n    shapeIconToolLine: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/></g>`,\n    shapeIconToolText: `<g stroke=\"none\" fill=\"currentColor\" transform=\"translate(6,0)\"><path d=\"M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z\"/>`,\n    shapeIconToolPreset: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"></path><path d=\"M20 17c-3 3-5 5-8 5\"></path></g>`,\n\n    shapeTitleSelectionMode: 'Selection mode',\n    shapeTitleBrushSize: 'Brush size',\n\n    shapeLabelSelectionModeNew: 'New',\n    shapeLabelSelectionModeAdd: 'Add',\n    shapeLabelSelectionModeSubtract: 'Remove',\n\n    shapeLabelToolSelectionBrush: 'Brush',\n    shapeLabelToolSelectionLassoo: 'Lassoo',\n    shapeLabelToolSelectionRectangle: 'Rectangle marquee',\n    shapeLabelToolSelectionEllipse: 'Ellipse marquee',\n    shapeLabelToolSelectionPolygon: 'Polygon marquee',\n\n    shapeIconSelectionModeNew: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 17H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1.5\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" fill=\"currentColor\" fill-opacity=\".25\" rx=\"2\"/></g>`,\n    shapeIconSelectionModeAdd: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><path d=\"M13 15h4M15 13v4\"/></g>`,\n    shapeIconSelectionModeSubtract: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h-6a2 2 0 0 0-1.995 1.85L9 11v6H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" rx=\"2\"/><path d=\"M13 15h4\"/></g>`,\n    shapeIconToolSelectionBrush: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSelectionLassoo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-width=\".125em\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.428 17.702a18.46 18.46 0 0 0 4.085-1.595c5.851-3.112 9.019-8.599 7.074-12.256-1.945-3.657-8.265-4.1-14.116-.988C2.619 5.974-.55 11.46 1.396 15.118c.63 1.186 1.72 2.033 3.105 2.532\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.833\" transform=\"rotate(-15 8 18.5)\"/><path stroke-linecap=\"round\" d=\"M5 18c3.347 1.048 5.514 1.881 6.5 2.5.859.54 1.517.994 1.5 2.364\"/></g>`,\n    shapeIconToolSelectionRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\"><path d=\"M9 1 h6 m4 0 h4v4 m0 4 v6 m0 4 v4h-4 m-4 0 h-6 m-4 0 h-4v-4 m0 -4 v-6 m0 -4 v-4h4\" fill=\"none\" /></g>`,\n    shapeIconToolSelectionEllipse: `<path stroke-width=\".125em\" stroke=\"currentColor\" d=\"M1.21 9.853a11.054 11.054 0 0 0 0 4.294m1.643 3.965a11.054 11.054 0 0 0 3.035 3.035m3.965 1.644a11.054 11.054 0 0 0 4.294 0m3.965-1.644a11.054 11.054 0 0 0 3.035-3.035m1.644-3.965a11.054 11.054 0 0 0 0-4.294m-1.644-3.965a11.054 11.054 0 0 0-3.035-3.035m-3.965-1.644a11.054 11.054 0 0 0-4.294 0M5.888 2.853a11.054 11.054 0 0 0-3.035 3.035\"/>`,\n    shapeIconToolSelectionPolygon:\n        '<g fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18h11V1L13 9 1 6l5 9 3 6v2\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.8\" transform=\"rotate(-2 8 18)\"/></g>',\n};\n\n// deprecated\nexport const ShapeEditor = MarkupEditor;\n", "export default {\n    cropLabel: 'Crop',\n    cropIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3\"/></g>',\n    cropIconButtonRecenter: `<path stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linejoin=\"bevel\" d=\"M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\"/>`,\n    cropIconButtonRotateLeft:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><rect x=\"3\" rx=\"1\" height=\"12\" width=\"12\" y=\"9\"/><path d=\"M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z\"/></g>',\n    cropIconButtonRotateRight:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><path d=\"M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z\"/><rect rx=\"1\" height=\"12\" width=\"12\" y=\"9\" x=\"9\"/></g>',\n    cropIconButtonFlipVertical:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z\"/><path d=\"M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z\" opacity=\".6\"/></g>',\n    cropIconButtonFlipHorizontal:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z\"/><path d=\"M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z\" opacity=\".6\"/></g>',\n\n    cropIconSelectPreset: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"4\" width=\"10\" height=\"18\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"6\" y=\"12\" width=\"17\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropIconCropBoundary: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"3\" width=\"20\" height=\"20\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"7\" y=\"8\" width=\"10\" height=\"10\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{d}\" x=\"12\" y=\"4\" width=\"10\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropLabelButtonRecenter: 'Recenter',\n    cropLabelButtonRotateLeft: 'Rotate left',\n    cropLabelButtonRotateRight: 'Rotate right',\n    cropLabelButtonFlipHorizontal: 'Flip horizontal',\n    cropLabelButtonFlipVertical: 'Flip vertical',\n\n    cropLabelSelectPreset: 'Crop shape',\n\n    cropLabelCropBoundary: 'Crop boundary',\n    cropLabelCropBoundaryEdge: 'Edge of image',\n    cropLabelCropBoundaryNone: 'None',\n\n    cropLabelTabRotation: 'Rotation',\n    cropLabelTabZoom: 'Scale',\n};\n", "export default {\n    annotateLabel: 'Annotate',\n    annotateIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z\"/></g>',\n};\n", "export default {\n    redactLabel: 'Redact',\n    redactIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M 4 5 l 1 -1\"/><path d=\"M 4 10 l 6 -6\"/><path d=\"M 4 15 l 11 -11\"/><path d=\"M 4 20 l 16 -16\"/><path d=\"M 9 20 l 11 -11\"/><path d=\"M 14 20 l 6 -6\"/><path d=\"M 19 20 l 1 -1\"/></g>`,\n};\n", "const IconCross =\n    '<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"></path></path></g>';\n\nconst CharacterA =\n    '<path fill=\"none\" d=\"M9 15 L12 9 L15 15 M10 13.5 h3\" stroke=\"currentColor\" stroke-width=\".125em\"/>';\n\nexport default {\n    // generic\n    labelReset: 'Restaurar',\n    labelDefault: 'Predeterminado',\n    labelAuto: 'Autom\u00E1tico',\n    labelNone: 'Ninguno',\n    labelEdit: 'Editar',\n    labelClose: 'Cerrar',\n    labelSupportError: `Este navegador no soporta {features}`,\n    labelMemoryError: `El navegador se qued\u00F3 sin memoria`,\n\n    // defaults\n    labelColor: 'Color',\n    labelWidth: 'Ancho',\n    labelSize: 'Tama\u00F1o',\n    labelOffset: 'Desplazamiento',\n    labelAmount: 'Monto',\n    labelInset: 'Insertar',\n    labelRadius: 'Radio',\n\n    // controls\n    labelColorPalette: 'Paleta de color',\n\n    // sizes\n    labelSizeExtraSmall: 'Extra peque\u00F1a',\n    labelSizeSmall: 'Peque\u00F1a',\n    labelSizeMediumSmall: 'Mediana peque\u00F1a',\n    labelSizeMedium: 'Mediano',\n    labelSizeMediumLarge: 'Mediano grande',\n    labelSizeLarge: 'Grande',\n    labelSizeExtraLarge: 'Extra grande',\n\n    // unused?\n    labelButtonRevert: 'Revertir',\n    labelButtonCancel: 'Cancelar',\n    labelButtonUndo: 'Deshacer',\n    labelButtonRedo: 'Rehacer',\n    labelButtonExport: 'Finalizado',\n\n    // zoom\n    labelZoom: 'Zoom',\n    labelZoomIn: 'Dar un golpe de zoom',\n    labelZoomOut: 'Disminuir el zoom',\n    labelZoomFit: 'Zoom para ajustar',\n    labelZoomActual: 'Tama\u00F1o real',\n    iconZoomIn: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M8 12 h8 M12 8 v8\" />',\n    iconZoomOut: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M9 12 h6\" />',\n\n    iconSupportError: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><g><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></g>`,\n    iconButtonClose: IconCross,\n    iconButtonRevert: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M7.388 18.538a8 8 0 10-2.992-9.03\"/><path fill=\"currentColor\" d=\"M2.794 11.696L2.37 6.714l5.088 3.18z\"/><path d=\"M12 8v4M12 12l4 2\"/></g>`,\n    iconButtonUndo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4\"/><path fill=\"currentColor\" d=\"M5 8l4-3v6z\"/></g>`,\n    iconButtonRedo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4\"/><path fill=\"currentColor\" d=\"M19 8l-4-3v6z\"/></g>`,\n    iconButtonExport: `<polyline points=\"20 6 9 17 4 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"></polyline>`,\n\n    // status\n    statusLabelButtonClose: 'Cerrar',\n    statusIconButtonClose: IconCross,\n\n    // new status options\n    statusImageLoadNone: 'Esperando imagen',\n    statusImageLoadMinSize: 'Tama\u00F1o m\u00EDnmo de {minWidth} &times; {minHeight}',\n    statusImageLoadError: 'Error de carga de la imagen',\n    statusImageLoadPrepare: 'Preparando imagen&hellip;',\n    statusImageLoadBusy: 'Cargando imagen&hellip;',\n    statusImageUploadError: 'Error de subida de imagen',\n    statusImageUploadBusy: 'Subiendo imagen&hellip;',\n    statusImageProcessError: 'Error de proceso de imagen',\n    statusImageProcessBusy: 'Procesando imagen&hellip;',\n};\n\nexport const MarkupEditor = {\n    shapeLabelButtonSelectSticker: 'Seleccionar imagen',\n    shapeIconButtonSelectSticker: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.0625em\"><path d=\"M8 21 L15 11 L19 15\"/><path d=\"M15 2 v5 h5\"/><path d=\"M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z\"/></g><circle fill=\"currentColor\" cx=\"10\" cy=\"8\" r=\"1.5\"/>`,\n\n    shapeIconButtonFlipHorizontal: `<g stroke=\"currentColor\" stroke-width=\".125em\"><path fill=\"none\" d=\"M6 6.5h5v11H6z\"/><path fill=\"currentColor\" d=\"M15 6.5h3v11h-3z\"/><path d=\"M11 4v16\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonFlipVertical: `<g stroke=\"currentColor\" stroke-width=\".125em\"><rect x=\"7\" y=\"8\" width=\"11\" height=\"5\" fill=\"none\"/><rect x=\"7\" y=\"17\" width=\"11\" height=\"2\" fill=\"currentColor\"/><line x1=\"5\" y1=\"13\" x2=\"20\" y2=\"13\"/></g>`,\n    shapeIconButtonRemove: `<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 7h9z\"/><path d=\"M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z\" fill=\"currentColor\"/><rect fill=\"currentColor\" x=\"10\" y=\"5\" width=\"4\" height=\"3\" rx=\"1\"/></g>`,\n    shapeIconButtonDuplicate: `<g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142\" stroke=\"currentColor\" stroke-width=\".125em\"/><path d=\"M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonMoveToFront: `<g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"currentColor\" x=\"11\" y=\"13\" width=\"8\" height=\"2\" rx=\"1\"/><rect fill=\"currentColor\" x=\"9\" y=\"17\" width=\"10\" height=\"2\" rx=\"1\"/><path d=\"M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z\" stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\"/></g>`,\n\n    shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,\n    shapeIconButtonTextLayoutAutoHeight: `<g fill=\"currentColor\"><circle cx=\"4\" cy=\"12\" r=\"1.5\"/><circle cx=\"20\" cy=\"12\" r=\"1.5\"/></g>${CharacterA}`,\n    shapeIconButtonTextLayoutFixedSize: `<g fill=\"currentColor\"><circle cx=\"5\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"19\" r=\"1.5\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\"/></g>${CharacterA}`,\n\n    shapeTitleButtonTextLayoutAutoWidth: 'Ancho autom\u00E1tico',\n    shapeTitleButtonTextLayoutAutoHeight: 'Alto autom\u00E1tico',\n    shapeTitleButtonTextLayoutFixedSize: 'Tama\u00F1o fijo',\n\n    shapeTitleButtonFlipHorizontal: 'Posici\u00F3n horizontal',\n    shapeTitleButtonFlipVertical: 'Posici\u00F3n vertical',\n    shapeTitleButtonRemove: 'Eliminar',\n    shapeTitleButtonDuplicate: 'Duplicar',\n    shapeTitleButtonMoveToFront: 'Enviar al fondo',\n\n    shapeLabelInputText: 'Editar texto',\n\n    shapeIconInputCancel: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"/></g>`,\n    shapeIconInputConfirm: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><polyline points=\"20 6 9 17 4 12\"/></g>`,\n    shapeLabelInputCancel: 'Cancelar',\n    shapeLabelInputConfirm: 'Confirmar',\n\n    shapeLabelStrokeNone: 'Sin contorno',\n\n    shapeLabelFontStyleNormal: 'Normal',\n    shapeLabelFontStyleBold: 'Negrita',\n    shapeLabelFontStyleItalic: 'It\u00E1lica',\n    shapeLabelFontStyleItalicBold: 'Negrita it\u00E1lica',\n\n    shapeTitleBackgroundColor: 'Color de relleno',\n    shapeTitleCornerRadius: 'Radio de esquina',\n\n    shapeTitleFontFamily: 'Fuente',\n    shapeTitleFontSize: 'Tama\u00F1o de fuente',\n    shapeTitleFontStyle: 'Estilo de fuente',\n    shapeTitleLineHeight: 'Linipa\u015Do',\n\n    shapeTitleLineStart: 'Comienzo',\n    shapeTitleLineEnd: 'Fin',\n    shapeTitleStrokeWidth: 'Ancho de l\u00EDnea',\n    shapeTitleStrokeColor: 'Color de l\u00EDnea',\n\n    shapeTitleLineDecorationBar: 'Barra',\n    shapeTitleLineDecorationCircle: 'C\u00EDrculo',\n    shapeTitleLineDecorationSquare: 'Cuadrado',\n    shapeTitleLineDecorationArrow: 'Flecha',\n    shapeTitleLineDecorationCircleSolid: 'C\u00EDrculo s\u00F3lido',\n    shapeTitleLineDecorationSquareSolid: 'Cuadrado s\u00F3lido',\n    shapeTitleLineDecorationArrowSolid: 'Flecha s\u00F3lida',\n\n    shapeIconLineDecorationBar: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M16,8 V16\"/></g>`,\n    shapeIconLineDecorationCircle: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"none\" stroke-width=\".125em\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquare: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"none\" stroke-width=\".125em\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrow: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16 M13,7 l6,5 l-6,5\" fill=\"none\"/></g>`,\n    shapeIconLineDecorationCircleSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"currentColor\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquareSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"currentColor\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrowSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M13,7 l6,5 l-6,5z\" fill=\"currentColor\"/></g>`,\n\n    shapeTitleColorTransparent: 'Transparente',\n    shapeTitleColorWhite: 'Blanco',\n    shapeTitleColorSilver: 'Plateado',\n    shapeTitleColorGray: 'Gris',\n    shapeTitleColorBlack: 'Negro',\n    shapeTitleColorNavy: 'Azul marino',\n    shapeTitleColorBlue: 'Azul',\n    shapeTitleColorAqua: 'Cian v\u00EDvido',\n    shapeTitleColorTeal: 'Verde petr\u00F3leo',\n    shapeTitleColorOlive: 'Oliva',\n    shapeTitleColorGreen: 'Verde',\n    shapeTitleColorYellow: 'Amarillo',\n    shapeTitleColorOrange: 'Naranja',\n    shapeTitleColorRed: 'Rojo',\n    shapeTitleColorMaroon: 'Marr\u00F3n',\n    shapeTitleColorFuchsia: 'Fucsia',\n    shapeTitleColorPurple: 'Violeta',\n\n    shapeTitleTextOutline: 'Contorno del texto',\n    shapeTitleTextOutlineWidth: 'Anchura',\n    shapeTitleTextShadow: 'Sombra del texto',\n    shapeTitleTextShadowBlur: 'Desenfoque',\n\n    shapeTitleTextColor: 'Color de fuente',\n    shapeTitleTextAlign: 'Alinear texto',\n    shapeTitleTextAlignLeft: 'Alinear texto a la izquierda',\n    shapeTitleTextAlignCenter: 'Alinear texto al centro',\n    shapeTitleTextAlignRight: 'Alinear texto a la derecha',\n\n    shapeIconTextAlignLeft: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"5\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"5\" y1=\"16\" x2=\"14\" y2=\"16\"/></g>`,\n    shapeIconTextAlignCenter: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"7\" y1=\"8\" x2=\"17\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"8\" y1=\"16\" x2=\"16\" y2=\"16\"/></g>`,\n    shapeIconTextAlignRight: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"9\" y1=\"8\" x2=\"19\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"11\" y1=\"16\" x2=\"19\" y2=\"16\"/></g>`,\n\n    shapeLabelToolMove: 'Mover',\n    shapeLabelToolView: 'Mirar',\n    shapeLabelToolSharpie: 'Puntero',\n    shapeLabelToolEraser: 'Borrador',\n    shapeLabelToolPath: 'Camino',\n    shapeLabelToolRectangle: 'Rect\u00E1ngulo',\n    shapeLabelToolEllipse: 'Elipse',\n    shapeLabelToolArrow: 'Flecha',\n    shapeLabelToolLine: 'L\u00EDnea',\n    shapeLabelToolText: 'Texto',\n    shapeLabelToolPreset: 'Sticker',\n\n    shapeIconToolView: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.98 9.703V2.567c0-1.19 1.19-1.785 1.784-1.785.595 0 1.784.595 1.784 1.785v3.568\"/><path d=\"M14.548 9.703V4.35c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.594 1.784 1.784v2.973\"/><path d=\"M18.116 10.244V7.271c0-1.19 1.19-1.784 1.784-1.784.595 0 1.785.595 1.785 1.784 0 1.19 0 8.92-1.19 12.488-1.19 3.569-10.704 4.758-13.678 0-2.973-4.757-2.973-4.757-4.163-6.541-1.189-1.784-1.153-2.974-.594-3.568.558-.595 1.784-1.19 2.973.594 1.277 1.916 2.07 2.907 2.379 2.974V5.487c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.595 1.784 1.784V8.46\"/></g>`,\n    shapeIconToolMove: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M6 2 L6 19 L18 13 Z M13 18 L16 24\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSharpie: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolEraser: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" fill=\"none\"><g transform=\"translate(3, 15) rotate(-45)\"><rect x=\"0\" y=\"0\" width=\"18\" height=\"10\" rx=\"3\"/></g><line x1=\"11\" y1=\"21\" x2=\"18\" y2=\"21\"/><line x1=\"20\" y1=\"21\" x2=\"22\" y2=\"21\"/></g>`,\n    shapeIconToolPath: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"><circle cx=\"21\" cy=\"3\" r=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><circle cx=\"3\" cy=\"21\" r=\"2\"/><path d=\"M19 4 11 8 M8 11 4 19\"/></g>`,\n    shapeIconToolRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"1\" y=\"1\" width=\"22\" height=\"22\" rx=\"4\"/></g>`,\n    shapeIconToolEllipse: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"11\"/></g>`,\n    shapeIconToolArrow: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/><path d=\"m10 6 L21.5 1 L20 13.5\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n    shapeIconToolLine: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/></g>`,\n    shapeIconToolText: `<g stroke=\"none\" fill=\"currentColor\" transform=\"translate(6,0)\"><path d=\"M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z\"/>`,\n    shapeIconToolPreset: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"></path><path d=\"M20 17c-3 3-5 5-8 5\"></path></g>`,\n\n    shapeTitleSelectionMode: 'Modo de selecci\u00F3n',\n    shapeTitleBrushSize: 'Tama\u00F1o del pincel',\n\n    shapeLabelSelectionModeNew: 'Nuevo',\n    shapeLabelSelectionModeAdd: 'A\u00F1adir',\n    shapeLabelSelectionModeSubtract: 'Eliminar',\n\n    shapeLabelToolSelectionBrush: 'Pincel',\n    shapeLabelToolSelectionLassoo: 'Lazo',\n    shapeLabelToolSelectionRectangle: 'Selecci\u00F3n rectangular',\n    shapeLabelToolSelectionEllipse: 'Selecci\u00F3n el\u00EDptica',\n    shapeLabelToolSelectionPolygon: 'Selecci\u00F3n poligonal',\n\n    shapeIconSelectionModeNew: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 17H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1.5\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" fill=\"currentColor\" fill-opacity=\".25\" rx=\"2\"/></g>`,\n    shapeIconSelectionModeAdd: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><path d=\"M13 15h4M15 13v4\"/></g>`,\n    shapeIconSelectionModeSubtract: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h-6a2 2 0 0 0-1.995 1.85L9 11v6H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" rx=\"2\"/><path d=\"M13 15h4\"/></g>`,\n    shapeIconToolSelectionBrush: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSelectionLassoo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-width=\".125em\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.428 17.702a18.46 18.46 0 0 0 4.085-1.595c5.851-3.112 9.019-8.599 7.074-12.256-1.945-3.657-8.265-4.1-14.116-.988C2.619 5.974-.55 11.46 1.396 15.118c.63 1.186 1.72 2.033 3.105 2.532\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.833\" transform=\"rotate(-15 8 18.5)\"/><path stroke-linecap=\"round\" d=\"M5 18c3.347 1.048 5.514 1.881 6.5 2.5.859.54 1.517.994 1.5 2.364\"/></g>`,\n    shapeIconToolSelectionRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\"><path d=\"M9 1 h6 m4 0 h4v4 m0 4 v6 m0 4 v4h-4 m-4 0 h-6 m-4 0 h-4v-4 m0 -4 v-6 m0 -4 v-4h4\" fill=\"none\" /></g>`,\n    shapeIconToolSelectionEllipse: `<path stroke-width=\".125em\" stroke=\"currentColor\" d=\"M1.21 9.853a11.054 11.054 0 0 0 0 4.294m1.643 3.965a11.054 11.054 0 0 0 3.035 3.035m3.965 1.644a11.054 11.054 0 0 0 4.294 0m3.965-1.644a11.054 11.054 0 0 0 3.035-3.035m1.644-3.965a11.054 11.054 0 0 0 0-4.294m-1.644-3.965a11.054 11.054 0 0 0-3.035-3.035m-3.965-1.644a11.054 11.054 0 0 0-4.294 0M5.888 2.853a11.054 11.054 0 0 0-3.035 3.035\"/>`,\n    shapeIconToolSelectionPolygon:\n        '<g fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18h11V1L13 9 1 6l5 9 3 6v2\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.8\" transform=\"rotate(-2 8 18)\"/></g>',\n};\n\n// deprecated\nexport const ShapeEditor = MarkupEditor;\n", "export default {\n    cropLabel: 'Recortar',\n    cropIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3\"/></g>',\n    cropIconButtonRecenter: `<path stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linejoin=\"bevel\" d=\"M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\"/>`,\n    cropIconButtonRotateLeft:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><rect x=\"3\" rx=\"1\" height=\"12\" width=\"12\" y=\"9\"/><path d=\"M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z\"/></g>',\n    cropIconButtonRotateRight:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><path d=\"M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z\"/><rect rx=\"1\" height=\"12\" width=\"12\" y=\"9\" x=\"9\"/></g>',\n    cropIconButtonFlipVertical:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z\"/><path d=\"M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z\" opacity=\".6\"/></g>',\n    cropIconButtonFlipHorizontal:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z\"/><path d=\"M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z\" opacity=\".6\"/></g>',\n\n    cropIconSelectPreset: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"4\" width=\"10\" height=\"18\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"6\" y=\"12\" width=\"17\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropIconCropBoundary: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"3\" width=\"20\" height=\"20\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"7\" y=\"8\" width=\"10\" height=\"10\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{d}\" x=\"12\" y=\"4\" width=\"10\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropLabelButtonRecenter: 'Recentrar',\n    cropLabelButtonRotateLeft: 'Rotar a la izquierda',\n    cropLabelButtonRotateRight: 'Rotar a la derecha',\n    cropLabelButtonFlipHorizontal: 'Posici\u00F3n horizontal',\n    cropLabelButtonFlipVertical: 'Posici\u00F3n vertical',\n\n    cropLabelSelectPreset: 'Recortar forma',\n\n    cropLabelCropBoundary: 'L\u00EDmite de recorte',\n    cropLabelCropBoundaryEdge: 'Borde de imagen',\n    cropLabelCropBoundaryNone: 'Ninguno',\n\n    cropLabelTabRotation: 'Rotaci\u00F3n',\n    cropLabelTabZoom: 'Escalar',\n};\n", "export default {\n    annotateLabel: 'A\u00F1adir nota',\n    annotateIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z\"/></g>',\n};\n", "export default {\n    redactLabel: 'Redactar',\n    redactIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M 4 5 l 1 -1\"/><path d=\"M 4 10 l 6 -6\"/><path d=\"M 4 15 l 11 -11\"/><path d=\"M 4 20 l 16 -16\"/><path d=\"M 9 20 l 11 -11\"/><path d=\"M 14 20 l 6 -6\"/><path d=\"M 19 20 l 1 -1\"/></g>`,\n};\n", "const IconCross =\n    '<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"></path></path></g>';\n\nconst CharacterA =\n    '<path fill=\"none\" d=\"M9 15 L12 9 L15 15 M10 13.5 h3\" stroke=\"currentColor\" stroke-width=\".125em\"/>';\n\nexport default {\n    // generic\n    labelReset: 'R\u00E9initialiser',\n    labelDefault: 'Par d\u00E9faut',\n    labelAuto: 'Auto',\n    labelNone: 'Aucun',\n    labelEdit: 'Modifier',\n    labelClose: 'Fermer',\n    labelSupportError: `{features} non pris en charge dans ce navigateur`,\n    labelMemoryError: `Le navigateur a manqu\u00E9 de m\u00E9moire`,\n\n    // defaults\n    labelColor: 'Couleur',\n    labelWidth: 'Largeur',\n    labelSize: 'Taille',\n    labelOffset: 'D\u00E9calage',\n    labelAmount: 'Quantit\u00E9',\n    labelInset: 'Encart',\n    labelRadius: 'Radius',\n\n    // controls\n    labelColorPalette: 'Palette de couleurs',\n\n    // sizes\n    labelSizeExtraSmall: 'Extra petit',\n    labelSizeSmall: 'Petit',\n    labelSizeMediumSmall: 'Moyen petit',\n    labelSizeMedium: 'Moyen',\n    labelSizeMediumLarge: 'Moyen grand',\n    labelSizeLarge: 'Grand',\n    labelSizeExtraLarge: 'Extra grand',\n\n    // unused?\n    labelButtonRevert: 'R\u00E9tablir',\n    labelButtonCancel: 'Annuler',\n    labelButtonUndo: 'Annuler',\n    labelButtonRedo: 'Refaire',\n    labelButtonExport: 'Termin\u00E9',\n\n    // zoom\n    labelZoom: 'Zoom',\n    labelZoomIn: 'Zoomer',\n    labelZoomOut: 'D\u00E9zoomer',\n    labelZoomFit: 'taille adapt\u00E9e',\n    labelZoomActual: 'Grandeur r\u00E9elle',\n    iconZoomIn: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M8 12 h8 M12 8 v8\" />',\n    iconZoomOut: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M9 12 h6\" />',\n\n    iconSupportError: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><g><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></g>`,\n    iconButtonClose: IconCross,\n    iconButtonRevert: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M7.388 18.538a8 8 0 10-2.992-9.03\"/><path fill=\"currentColor\" d=\"M2.794 11.696L2.37 6.714l5.088 3.18z\"/><path d=\"M12 8v4M12 12l4 2\"/></g>`,\n    iconButtonUndo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4\"/><path fill=\"currentColor\" d=\"M5 8l4-3v6z\"/></g>`,\n    iconButtonRedo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4\"/><path fill=\"currentColor\" d=\"M19 8l-4-3v6z\"/></g>`,\n    iconButtonExport: `<polyline points=\"20 6 9 17 4 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"></polyline>`,\n\n    // status\n    statusLabelButtonClose: 'Fermer',\n    statusIconButtonClose: IconCross,\n\n    // new status options\n    statusImageLoadNone: `Attente de l'image`,\n    statusImageLoadMinSize: 'La taille minimale est de {minWidth} &times; {minHeight}',\n    statusImageLoadError: `Erreur de chargement de l'image`,\n    statusImageLoadPrepare: `Pr\u00E9parer l'image&hellip;`,\n    statusImageLoadBusy: `Chargement de l'image&hellip;`,\n    statusImageUploadError: `Erreur de transfert de l'image`,\n    statusImageUploadBusy: `Transfert de l'image&hellip;`,\n    statusImageProcessError: `Erreur de traitement de l'image`,\n    statusImageProcessBusy: `Traitement de l'image&hellip;`,\n};\n\nexport const MarkupEditor = {\n    shapeLabelButtonSelectSticker: `S\u00E9lection de l'image`,\n    shapeIconButtonSelectSticker: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.0625em\"><path d=\"M8 21 L15 11 L19 15\"/><path d=\"M15 2 v5 h5\"/><path d=\"M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z\"/></g><circle fill=\"currentColor\" cx=\"10\" cy=\"8\" r=\"1.5\"/>`,\n\n    shapeIconButtonFlipHorizontal: `<g stroke=\"currentColor\" stroke-width=\".125em\"><path fill=\"none\" d=\"M6 6.5h5v11H6z\"/><path fill=\"currentColor\" d=\"M15 6.5h3v11h-3z\"/><path d=\"M11 4v16\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonFlipVertical: `<g stroke=\"currentColor\" stroke-width=\".125em\"><rect x=\"7\" y=\"8\" width=\"11\" height=\"5\" fill=\"none\"/><rect x=\"7\" y=\"17\" width=\"11\" height=\"2\" fill=\"currentColor\"/><line x1=\"5\" y1=\"13\" x2=\"20\" y2=\"13\"/></g>`,\n    shapeIconButtonRemove: `<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 7h9z\"/><path d=\"M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z\" fill=\"currentColor\"/><rect fill=\"currentColor\" x=\"10\" y=\"5\" width=\"4\" height=\"3\" rx=\"1\"/></g>`,\n    shapeIconButtonDuplicate: `<g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142\" stroke=\"currentColor\" stroke-width=\".125em\"/><path d=\"M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonMoveToFront: `<g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"currentColor\" x=\"11\" y=\"13\" width=\"8\" height=\"2\" rx=\"1\"/><rect fill=\"currentColor\" x=\"9\" y=\"17\" width=\"10\" height=\"2\" rx=\"1\"/><path d=\"M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z\" stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\"/></g>`,\n\n    shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,\n    shapeIconButtonTextLayoutAutoHeight: `<g fill=\"currentColor\"><circle cx=\"4\" cy=\"12\" r=\"1.5\"/><circle cx=\"20\" cy=\"12\" r=\"1.5\"/></g>${CharacterA}`,\n    shapeIconButtonTextLayoutFixedSize: `<g fill=\"currentColor\"><circle cx=\"5\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"19\" r=\"1.5\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\"/></g>${CharacterA}`,\n\n    shapeTitleButtonTextLayoutAutoWidth: 'Largeur auto',\n    shapeTitleButtonTextLayoutAutoHeight: 'Hauteur auto',\n    shapeTitleButtonTextLayoutFixedSize: 'Taille fixe',\n\n    shapeTitleButtonFlipHorizontal: 'Retournement horizontal',\n    shapeTitleButtonFlipVertical: 'Retournement vertical',\n    shapeTitleButtonRemove: 'Supprimer',\n    shapeTitleButtonDuplicate: 'Dupliquer',\n    shapeTitleButtonMoveToFront: `D\u00E9placer vers l'avant`,\n\n    shapeLabelInputText: 'Modifier le texte',\n\n    shapeIconInputCancel: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"/></g>`,\n    shapeIconInputConfirm: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><polyline points=\"20 6 9 17 4 12\"/></g>`,\n    shapeLabelInputCancel: 'Annuler',\n    shapeLabelInputConfirm: 'Confirmer',\n\n    shapeLabelStrokeNone: 'Aucun contour',\n\n    shapeLabelFontStyleNormal: 'Normal',\n    shapeLabelFontStyleBold: 'Gras',\n    shapeLabelFontStyleItalic: 'Italique',\n    shapeLabelFontStyleItalicBold: 'Italique gras',\n\n    shapeTitleBackgroundColor: 'Couleur de remplissage',\n\n    shapeTitleCornerRadius: `Rayon d'angle`,\n\n    shapeTitleFontFamily: 'Police',\n    shapeTitleFontSize: 'Taille de police',\n    shapeTitleFontStyle: 'Style de police',\n    shapeTitleLineHeight: 'Interlignage',\n\n    shapeTitleLineStart: 'D\u00E9but',\n    shapeTitleLineEnd: 'Fin',\n    shapeTitleStrokeWidth: '\u00C9paisseur de trait',\n    shapeTitleStrokeColor: 'Couleur de trait',\n\n    shapeTitleLineDecorationBar: 'Barre',\n    shapeTitleLineDecorationCircle: 'Cercle',\n    shapeTitleLineDecorationSquare: 'Carr\u00E9',\n    shapeTitleLineDecorationArrow: 'Fl\u00E8che',\n    shapeTitleLineDecorationCircleSolid: 'Disque',\n    shapeTitleLineDecorationSquareSolid: 'Carr\u00E9 plein',\n    shapeTitleLineDecorationArrowSolid: 'Fl\u00E8che pleine',\n\n    shapeIconLineDecorationBar: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M16,8 V16\"/></g>`,\n    shapeIconLineDecorationCircle: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"none\" stroke-width=\".125em\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquare: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"none\" stroke-width=\".125em\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrow: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16 M13,7 l6,5 l-6,5\" fill=\"none\"/></g>`,\n    shapeIconLineDecorationCircleSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"currentColor\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquareSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"currentColor\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrowSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M13,7 l6,5 l-6,5z\" fill=\"currentColor\"/></g>`,\n\n    shapeTitleColorTransparent: 'Transparent',\n    shapeTitleColorWhite: 'Blanc',\n    shapeTitleColorSilver: 'Argent',\n    shapeTitleColorGray: 'Gris',\n    shapeTitleColorBlack: 'Noir',\n    shapeTitleColorNavy: 'Marine',\n    shapeTitleColorBlue: 'Bleu',\n    shapeTitleColorAqua: 'Eau',\n    shapeTitleColorTeal: 'Sarcelle',\n    shapeTitleColorOlive: 'Olive',\n    shapeTitleColorGreen: 'Vert',\n    shapeTitleColorYellow: 'Jaune',\n    shapeTitleColorOrange: 'Orange',\n    shapeTitleColorRed: 'Rouge',\n    shapeTitleColorMaroon: 'Maroon',\n    shapeTitleColorFuchsia: 'Fuchsia',\n    shapeTitleColorPurple: 'Violet',\n\n    shapeTitleTextOutline: 'Contour du texte',\n    shapeTitleTextOutlineWidth: 'Largeur',\n    shapeTitleTextShadow: 'Ombre du texte',\n    shapeTitleTextShadowBlur: 'Flou',\n\n    shapeTitleTextColor: 'Couleur de police',\n    shapeTitleTextAlign: 'Alignement du texte',\n    shapeTitleTextAlignLeft: 'Alignement gauche du texte',\n    shapeTitleTextAlignCenter: 'Alignement central du texte',\n    shapeTitleTextAlignRight: 'Alignement droite du texte',\n\n    shapeIconTextAlignLeft: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"5\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"5\" y1=\"16\" x2=\"14\" y2=\"16\"/></g>`,\n    shapeIconTextAlignCenter: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"7\" y1=\"8\" x2=\"17\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"8\" y1=\"16\" x2=\"16\" y2=\"16\"/></g>`,\n    shapeIconTextAlignRight: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"9\" y1=\"8\" x2=\"19\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"11\" y1=\"16\" x2=\"19\" y2=\"16\"/></g>`,\n\n    shapeLabelToolMove: 'D\u00E9placer',\n    shapeLabelToolView: 'Voir',\n    shapeLabelToolSharpie: 'Pointe',\n    shapeLabelToolEraser: 'Gomme',\n    shapeLabelToolPath: 'Chemin',\n    shapeLabelToolRectangle: 'Rectangle',\n    shapeLabelToolEllipse: 'Ellipse',\n    shapeLabelToolArrow: 'Fl\u00E8che',\n    shapeLabelToolLine: 'Trait',\n    shapeLabelToolText: 'Texte',\n    shapeLabelToolPreset: 'Autocollants',\n\n    shapeIconToolView: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.98 9.703V2.567c0-1.19 1.19-1.785 1.784-1.785.595 0 1.784.595 1.784 1.785v3.568\"/><path d=\"M14.548 9.703V4.35c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.594 1.784 1.784v2.973\"/><path d=\"M18.116 10.244V7.271c0-1.19 1.19-1.784 1.784-1.784.595 0 1.785.595 1.785 1.784 0 1.19 0 8.92-1.19 12.488-1.19 3.569-10.704 4.758-13.678 0-2.973-4.757-2.973-4.757-4.163-6.541-1.189-1.784-1.153-2.974-.594-3.568.558-.595 1.784-1.19 2.973.594 1.277 1.916 2.07 2.907 2.379 2.974V5.487c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.595 1.784 1.784V8.46\"/></g>`,\n    shapeIconToolMove: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M6 2 L6 19 L18 13 Z M13 18 L16 24\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSharpie: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolEraser: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" fill=\"none\"><g transform=\"translate(3, 15) rotate(-45)\"><rect x=\"0\" y=\"0\" width=\"18\" height=\"10\" rx=\"3\"/></g><line x1=\"11\" y1=\"21\" x2=\"18\" y2=\"21\"/><line x1=\"20\" y1=\"21\" x2=\"22\" y2=\"21\"/></g>`,\n    shapeIconToolPath: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"><circle cx=\"21\" cy=\"3\" r=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><circle cx=\"3\" cy=\"21\" r=\"2\"/><path d=\"M19 4 11 8 M8 11 4 19\"/></g>`,\n    shapeIconToolRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"1\" y=\"1\" width=\"22\" height=\"22\" rx=\"4\"/></g>`,\n    shapeIconToolEllipse: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"11\"/></g>`,\n    shapeIconToolArrow: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/><path d=\"m10 6 L21.5 1 L20 13.5\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n    shapeIconToolLine: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/></g>`,\n    shapeIconToolText: `<g stroke=\"none\" fill=\"currentColor\" transform=\"translate(6,0)\"><path d=\"M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z\"/>`,\n    shapeIconToolPreset: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"></path><path d=\"M20 17c-3 3-5 5-8 5\"></path></g>`,\n\n    shapeTitleSelectionMode: 'Mode de s\u00E9lection',\n    shapeTitleBrushSize: 'Taille du pinceau',\n\n    shapeLabelSelectionModeNew: 'Nouveau',\n    shapeLabelSelectionModeAdd: 'Ajouter',\n    shapeLabelSelectionModeSubtract: 'Retirer',\n\n    shapeLabelToolSelectionBrush: 'Brosse',\n    shapeLabelToolSelectionLassoo: 'Lasso',\n    shapeLabelToolSelectionRectangle: 'S\u00E9lection rectangulaire',\n    shapeLabelToolSelectionEllipse: 'S\u00E9lection elliptique',\n    shapeLabelToolSelectionPolygon: 'S\u00E9lection polygonale',\n\n    shapeIconSelectionModeNew: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 17H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1.5\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" fill=\"currentColor\" fill-opacity=\".25\" rx=\"2\"/></g>`,\n    shapeIconSelectionModeAdd: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><path d=\"M13 15h4M15 13v4\"/></g>`,\n    shapeIconSelectionModeSubtract: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h-6a2 2 0 0 0-1.995 1.85L9 11v6H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" rx=\"2\"/><path d=\"M13 15h4\"/></g>`,\n    shapeIconToolSelectionBrush: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSelectionLassoo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-width=\".125em\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.428 17.702a18.46 18.46 0 0 0 4.085-1.595c5.851-3.112 9.019-8.599 7.074-12.256-1.945-3.657-8.265-4.1-14.116-.988C2.619 5.974-.55 11.46 1.396 15.118c.63 1.186 1.72 2.033 3.105 2.532\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.833\" transform=\"rotate(-15 8 18.5)\"/><path stroke-linecap=\"round\" d=\"M5 18c3.347 1.048 5.514 1.881 6.5 2.5.859.54 1.517.994 1.5 2.364\"/></g>`,\n    shapeIconToolSelectionRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\"><path d=\"M9 1 h6 m4 0 h4v4 m0 4 v6 m0 4 v4h-4 m-4 0 h-6 m-4 0 h-4v-4 m0 -4 v-6 m0 -4 v-4h4\" fill=\"none\" /></g>`,\n    shapeIconToolSelectionEllipse: `<path stroke-width=\".125em\" stroke=\"currentColor\" d=\"M1.21 9.853a11.054 11.054 0 0 0 0 4.294m1.643 3.965a11.054 11.054 0 0 0 3.035 3.035m3.965 1.644a11.054 11.054 0 0 0 4.294 0m3.965-1.644a11.054 11.054 0 0 0 3.035-3.035m1.644-3.965a11.054 11.054 0 0 0 0-4.294m-1.644-3.965a11.054 11.054 0 0 0-3.035-3.035m-3.965-1.644a11.054 11.054 0 0 0-4.294 0M5.888 2.853a11.054 11.054 0 0 0-3.035 3.035\"/>`,\n    shapeIconToolSelectionPolygon:\n        '<g fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18h11V1L13 9 1 6l5 9 3 6v2\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.8\" transform=\"rotate(-2 8 18)\"/></g>',\n};\n\n// deprecated\nexport const ShapeEditor = MarkupEditor;\n", "export default {\n    cropLabel: 'Rogner',\n    cropIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3\"/></g>',\n    cropIconButtonRecenter: `<path stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linejoin=\"bevel\" d=\"M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\"/>`,\n    cropIconButtonRotateLeft:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><rect x=\"3\" rx=\"1\" height=\"12\" width=\"12\" y=\"9\"/><path d=\"M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z\"/></g>',\n    cropIconButtonRotateRight:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><path d=\"M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z\"/><rect rx=\"1\" height=\"12\" width=\"12\" y=\"9\" x=\"9\"/></g>',\n    cropIconButtonFlipVertical:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z\"/><path d=\"M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z\" opacity=\".6\"/></g>',\n    cropIconButtonFlipHorizontal:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z\"/><path d=\"M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z\" opacity=\".6\"/></g>',\n\n    cropIconSelectPreset: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"4\" width=\"10\" height=\"18\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"6\" y=\"12\" width=\"17\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropIconCropBoundary: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"3\" width=\"20\" height=\"20\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"7\" y=\"8\" width=\"10\" height=\"10\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{d}\" x=\"12\" y=\"4\" width=\"10\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropLabelButtonRecenter: 'Recentrer',\n    cropLabelButtonRotateLeft: 'Pivoter \u00E0 gauche',\n    cropLabelButtonRotateRight: 'Pivoter \u00E0 droite',\n    cropLabelButtonFlipHorizontal: 'Retournement horizontal',\n    cropLabelButtonFlipVertical: 'Retournement vertical',\n\n    cropLabelSelectPreset: 'Forme du rognage',\n\n    cropLabelCropBoundary: 'Limite de rognage',\n    cropLabelCropBoundaryEdge: `Limite de l'image`,\n    cropLabelCropBoundaryNone: 'Aucun',\n\n    cropLabelTabRotation: 'Rotation',\n    cropLabelTabZoom: '\u00C9chelonner',\n};\n", "export default {\n    annotateLabel: 'Annoter',\n    annotateIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z\"/></g>',\n};\n", "export default {\n    redactLabel: 'R\u00E9diger',\n    redactIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M 4 5 l 1 -1\"/><path d=\"M 4 10 l 6 -6\"/><path d=\"M 4 15 l 11 -11\"/><path d=\"M 4 20 l 16 -16\"/><path d=\"M 9 20 l 11 -11\"/><path d=\"M 14 20 l 6 -6\"/><path d=\"M 19 20 l 1 -1\"/></g>`,\n};\n", "const IconCross =\n    '<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"></path></path></g>';\n\nconst CharacterA =\n    '<path fill=\"none\" d=\"M9 15 L12 9 L15 15 M10 13.5 h3\" stroke=\"currentColor\" stroke-width=\".125em\"/>';\n\nexport default {\n    // generici\n    labelReset: 'Resetta',\n    labelDefault: 'Default',\n    labelAuto: 'Auto',\n    labelNone: 'Nessuno',\n    labelEdit: 'Modifica',\n    labelClose: 'Chiudi',\n    labelSupportError: `{features} non supportate su questo browser`,\n    labelMemoryError: `Il browser ha esaurito la memoria`,\n\n    // predefiniti\n    labelColor: 'Colore',\n    labelWidth: 'Larghezza',\n    labelSize: 'Dimensione',\n    labelOffset: 'Offset',\n    labelAmount: 'Quantit\u00E0',\n    labelInset: 'Inset',\n    labelRadius: 'Raggio',\n\n    // controls\n    labelColorPalette: 'Palette di colori',\n\n    // sizes\n    labelSizeExtraSmall: 'Extra piccolo',\n    labelSizeSmall: 'Piccolo',\n    labelSizeMediumSmall: 'Medio piccolo',\n    labelSizeMedium: 'Medio',\n    labelSizeMediumLarge: 'Medio grande',\n    labelSizeLarge: 'Grande',\n    labelSizeExtraLarge: 'Extra grande',\n\n    // default buttons\n    labelButtonCancel: 'Annulla',\n    labelButtonUndo: 'Disfare',\n    labelButtonRedo: 'Rifare',\n    labelButtonRevert: 'Ripristina',\n    labelButtonExport: 'Esportare',\n\n    // zoom\n    labelZoom: 'Zumata',\n    labelZoomIn: 'Ingrandisci',\n    labelZoomOut: 'Rimpicciolisci',\n    labelZoomFit: 'Adatta alla vista',\n    labelZoomActual: 'Dimensioni reali',\n    iconZoomIn: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M8 12 h8 M12 8 v8\" />',\n    iconZoomOut: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M9 12 h6\" />',\n\n    // icons\n    iconSupportError: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><g><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></g>`,\n    iconButtonClose: IconCross,\n    iconButtonRevert: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M7.388 18.538a8 8 0 10-2.992-9.03\"/><path fill=\"currentColor\" d=\"M2.794 11.696L2.37 6.714l5.088 3.18z\"/><path d=\"M12 8v4M12 12l4 2\"/></g>`,\n    iconButtonUndo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4\"/><path fill=\"currentColor\" d=\"M5 8l4-3v6z\"/></g>`,\n    iconButtonRedo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4\"/><path fill=\"currentColor\" d=\"M19 8l-4-3v6z\"/></g>`,\n    iconButtonExport: `<polyline points=\"20 6 9 17 4 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"></polyline>`,\n\n    // status\n    statusLabelButtonClose: 'Chiudi',\n    statusIconButtonClose: IconCross,\n\n    // new status options\n    statusImageLoadNone: 'In attesa di immagine',\n    statusImageLoadMinSize: \"La dimensione minima dell'immagine \u00E8 {minWidth} &times; {minHeight}\",\n    statusImageLoadError: \"Errore durante il caricamento dell'immagine\",\n    statusImageLoadPrepare: 'Preparazione immagine in corso&hellip;',\n    statusImageLoadBusy: 'Caricamento immagine in corso&hellip;',\n    statusImageUploadError: \"Errore durante il caricamento dell'immagine\",\n    statusImageUploadBusy: 'Caricamento immagine in corso&hellip;',\n    statusImageProcessError: \"Errore durante l'elaborazione dell'immagine\",\n    statusImageProcessBusy: 'Elaborazione immagine in corso&hellip;',\n};\n\nexport const MarkupEditor = {\n    shapeLabelButtonSelectSticker: 'Seleziona immagine',\n    shapeIconButtonSelectSticker: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.0625em\"><path d=\"M8 21 L15 11 L19 15\"/><path d=\"M15 2 v5 h5\"/><path d=\"M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z\"/></g><circle fill=\"currentColor\" cx=\"10\" cy=\"8\" r=\"1.5\"/>`,\n\n    shapeIconButtonFlipHorizontal: `<g stroke=\"currentColor\" stroke-width=\".125em\"><path fill=\"none\" d=\"M6 6.5h5v11H6z\"/><path fill=\"currentColor\" d=\"M15 6.5h3v11h-3z\"/><path d=\"M11 4v16\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonFlipVertical: `<g stroke=\"currentColor\" stroke-width=\".125em\"><rect x=\"7\" y=\"8\" width=\"11\" height=\"5\" fill=\"none\"/><rect x=\"7\" y=\"17\" width=\"11\" height=\"2\" fill=\"currentColor\"/><line x1=\"5\" y1=\"13\" x2=\"20\" y2=\"13\"/></g>`,\n    shapeIconButtonRemove: `<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 7h9z\"/><path d=\"M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z\" fill=\"currentColor\"/><rect fill=\"currentColor\" x=\"10\" y=\"5\" width=\"4\" height=\"3\" rx=\"1\"/></g>`,\n    shapeIconButtonDuplicate: `<g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142\" stroke=\"currentColor\" stroke-width=\".125em\"/><path d=\"M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonMoveToFront: `<g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"currentColor\" x=\"11\" y=\"13\" width=\"8\" height=\"2\" rx=\"1\"/><rect fill=\"currentColor\" x=\"9\" y=\"17\" width=\"10\" height=\"2\" rx=\"1\"/><path d=\"M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z\" stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\"/></g>`,\n\n    shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,\n    shapeIconButtonTextLayoutAutoHeight: `<g fill=\"currentColor\"><circle cx=\"4\" cy=\"12\" r=\"1.5\"/><circle cx=\"20\" cy=\"12\" r=\"1.5\"/></g>${CharacterA}`,\n    shapeIconButtonTextLayoutFixedSize: `<g fill=\"currentColor\"><circle cx=\"5\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"19\" r=\"1.5\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\"/></g>${CharacterA}`,\n\n    shapeTitleButtonTextLayoutAutoWidth: 'Larghezza automatica',\n    shapeTitleButtonTextLayoutAutoHeight: 'Altezza automatica',\n    shapeTitleButtonTextLayoutFixedSize: 'Dimensione fissa',\n\n    shapeTitleButtonFlipHorizontal: 'Capovolgi orizzontalmente',\n    shapeTitleButtonFlipVertical: 'Capovolgi verticalmente',\n    shapeTitleButtonRemove: 'Rimuovi',\n    shapeTitleButtonDuplicate: 'Duplica',\n    shapeTitleButtonMoveToFront: 'Sposta in primo piano',\n\n    shapeLabelInputText: 'Modifica',\n\n    shapeIconInputCancel: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"/></g>`,\n    shapeIconInputConfirm: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><polyline points=\"20 6 9 17 4 12\"/></g>`,\n    shapeLabelInputCancel: 'Annulla',\n    shapeLabelInputConfirm: 'Conferma',\n\n    shapeLabelStrokeNone: 'Nessun contorno',\n\n    shapeLabelFontStyleNormal: 'Normale',\n    shapeLabelFontStyleBold: 'Grassetto',\n    shapeLabelFontStyleItalic: 'Corsivo',\n    shapeLabelFontStyleItalicBold: 'Grassetto corsivo',\n\n    shapeTitleBackgroundColor: 'Colore di riempimento',\n\n    shapeTitleCornerRadius: \"Raggio dell'angolo\",\n\n    shapeTitleFontFamily: 'Font',\n    shapeTitleFontSize: 'Dimensione del font',\n    shapeTitleFontStyle: 'Stile del font',\n    shapeTitleLineHeight: 'Altezza della riga',\n\n    shapeTitleLineStart: 'Inizio',\n    shapeTitleLineEnd: 'Fine',\n    shapeTitleStrokeWidth: 'Spessore della linea',\n    shapeTitleStrokeColor: 'Colore della linea',\n\n    shapeTitleLineDecorationBar: 'Barra',\n    shapeTitleLineDecorationCircle: 'Cerchio',\n    shapeTitleLineDecorationSquare: 'Quadrato',\n    shapeTitleLineDecorationArrow: 'Freccia',\n    shapeTitleLineDecorationCircleSolid: 'Cerchio pieno',\n    shapeTitleLineDecorationSquareSolid: 'Quadrato pieno',\n    shapeTitleLineDecorationArrowSolid: 'Freccia piena',\n\n    shapeIconLineDecorationBar: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M16,8 V16\"/></g>`,\n    shapeIconLineDecorationCircle: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"none\" stroke-width=\".125em\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquare: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"none\" stroke-width=\".125em\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrow: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16 M13,7 l6,5 l-6,5\" fill=\"none\"/></g>`,\n    shapeIconLineDecorationCircleSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"currentColor\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquareSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"currentColor\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrowSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M13,7 l6,5 l-6,5z\" fill=\"currentColor\"/></g>`,\n\n    shapeTitleColorTransparent: 'Trasparente',\n    shapeTitleColorWhite: 'Bianco',\n    shapeTitleColorSilver: 'Argento',\n    shapeTitleColorGray: 'Grigio',\n    shapeTitleColorBlack: 'Nero',\n    shapeTitleColorNavy: 'Blu scuro',\n    shapeTitleColorBlue: 'Blu',\n    shapeTitleColorAqua: 'Acqua',\n    shapeTitleColorTeal: 'Teal',\n    shapeTitleColorOlive: 'Oliva',\n    shapeTitleColorGreen: 'Verde',\n    shapeTitleColorYellow: 'Giallo',\n    shapeTitleColorOrange: 'Arancione',\n    shapeTitleColorRed: 'Rosso',\n    shapeTitleColorMaroon: 'Marrone',\n    shapeTitleColorFuchsia: 'Fucsia',\n    shapeTitleColorPurple: 'Porpora',\n\n    shapeTitleTextOutline: 'Contorno testo',\n    shapeTitleTextOutlineWidth: 'Larghezza',\n    shapeTitleTextShadow: 'Ombra del testo',\n    shapeTitleTextShadowBlur: 'Sfocatura',\n\n    shapeTitleTextColor: 'Colore del font',\n    shapeTitleTextAlign: 'Allineamento del testo',\n    shapeTitleTextAlignLeft: 'Allinea a sinistra il testo',\n    shapeTitleTextAlignCenter: 'Centra il testo',\n    shapeTitleTextAlignRight: 'Allinea a destra il testo',\n\n    shapeIconTextAlignLeft: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"5\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"5\" y1=\"16\" x2=\"14\" y2=\"16\"/></g>`,\n    shapeIconTextAlignCenter: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"7\" y1=\"8\" x2=\"17\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"8\" y1=\"16\" x2=\"16\" y2=\"16\"/></g>`,\n    shapeIconTextAlignRight: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"9\" y1=\"8\" x2=\"19\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"11\" y1=\"16\" x2=\"19\" y2=\"16\"/></g>`,\n\n    shapeLabelToolMove: 'Sposta',\n    shapeLabelToolView: 'Visualizza',\n    shapeLabelToolSharpie: 'Pennarello',\n    shapeLabelToolEraser: 'Cancellino',\n    shapeLabelToolPath: 'Percorso',\n    shapeLabelToolRectangle: 'Rettangolo',\n    shapeLabelToolEllipse: 'Ellisse',\n    shapeLabelToolArrow: 'Freccia',\n    shapeLabelToolLine: 'Linea',\n    shapeLabelToolText: 'Testo',\n    shapeLabelToolPreset: 'Adesivi',\n\n    shapeIconToolView: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.98 9.703V2.567c0-1.19 1.19-1.785 1.784-1.785.595 0 1.784.595 1.784 1.785v3.568\"/><path d=\"M14.548 9.703V4.35c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.594 1.784 1.784v2.973\"/><path d=\"M18.116 10.244V7.271c0-1.19 1.19-1.784 1.784-1.784.595 0 1.785.595 1.785 1.784 0 1.19 0 8.92-1.19 12.488-1.19 3.569-10.704 4.758-13.678 0-2.973-4.757-2.973-4.757-4.163-6.541-1.189-1.784-1.153-2.974-.594-3.568.558-.595 1.784-1.19 2.973.594 1.277 1.916 2.07 2.907 2.379 2.974V5.487c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.595 1.784 1.784V8.46\"/></g>`,\n    shapeIconToolMove: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M6 2 L6 19 L18 13 Z M13 18 L16 24\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSharpie: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolEraser: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" fill=\"none\"><g transform=\"translate(3, 15) rotate(-45)\"><rect x=\"0\" y=\"0\" width=\"18\" height=\"10\" rx=\"3\"/></g><line x1=\"11\" y1=\"21\" x2=\"18\" y2=\"21\"/><line x1=\"20\" y1=\"21\" x2=\"22\" y2=\"21\"/></g>`,\n    shapeIconToolPath: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"><circle cx=\"21\" cy=\"3\" r=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><circle cx=\"3\" cy=\"21\" r=\"2\"/><path d=\"M19 4 11 8 M8 11 4 19\"/></g>`,\n    shapeIconToolRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"1\" y=\"1\" width=\"22\" height=\"22\" rx=\"4\"/></g>`,\n    shapeIconToolEllipse: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"11\"/></g>`,\n    shapeIconToolArrow: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/><path d=\"m10 6 L21.5 1 L20 13.5\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n    shapeIconToolLine: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/></g>`,\n    shapeIconToolText: `<g stroke=\"none\" fill=\"currentColor\" transform=\"translate(6,0)\"><path d=\"M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z\"/>`,\n    shapeIconToolPreset: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"></path><path d=\"M20 17c-3 3-5 5-8 5\"></path></g>`,\n\n    shapeTitleSelectionMode: 'Modalit\u00E0 di selezione',\n    shapeTitleBrushSize: 'Dimensione del pennello',\n\n    shapeLabelSelectionModeNew: 'Nuovo',\n    shapeLabelSelectionModeAdd: 'Aggiungi',\n    shapeLabelSelectionModeSubtract: 'Rimuovi',\n\n    shapeLabelToolSelectionBrush: 'Pennello',\n    shapeLabelToolSelectionLassoo: 'Lazo',\n    shapeLabelToolSelectionRectangle: 'Selezione rettangolare',\n    shapeLabelToolSelectionEllipse: 'Selezione ellittica',\n    shapeLabelToolSelectionPolygon: 'Selezione poligonale',\n\n    shapeIconSelectionModeNew: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 17H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1.5\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" fill=\"currentColor\" fill-opacity=\".25\" rx=\"2\"/></g>`,\n    shapeIconSelectionModeAdd: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><path d=\"M13 15h4M15 13v4\"/></g>`,\n    shapeIconSelectionModeSubtract: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h-6a2 2 0 0 0-1.995 1.85L9 11v6H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" rx=\"2\"/><path d=\"M13 15h4\"/></g>`,\n    shapeIconToolSelectionBrush: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSelectionLassoo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-width=\".125em\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.428 17.702a18.46 18.46 0 0 0 4.085-1.595c5.851-3.112 9.019-8.599 7.074-12.256-1.945-3.657-8.265-4.1-14.116-.988C2.619 5.974-.55 11.46 1.396 15.118c.63 1.186 1.72 2.033 3.105 2.532\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.833\" transform=\"rotate(-15 8 18.5)\"/><path stroke-linecap=\"round\" d=\"M5 18c3.347 1.048 5.514 1.881 6.5 2.5.859.54 1.517.994 1.5 2.364\"/></g>`,\n    shapeIconToolSelectionRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\"><path d=\"M9 1 h6 m4 0 h4v4 m0 4 v6 m0 4 v4h-4 m-4 0 h-6 m-4 0 h-4v-4 m0 -4 v-6 m0 -4 v-4h4\" fill=\"none\" /></g>`,\n    shapeIconToolSelectionEllipse: `<path stroke-width=\".125em\" stroke=\"currentColor\" d=\"M1.21 9.853a11.054 11.054 0 0 0 0 4.294m1.643 3.965a11.054 11.054 0 0 0 3.035 3.035m3.965 1.644a11.054 11.054 0 0 0 4.294 0m3.965-1.644a11.054 11.054 0 0 0 3.035-3.035m1.644-3.965a11.054 11.054 0 0 0 0-4.294m-1.644-3.965a11.054 11.054 0 0 0-3.035-3.035m-3.965-1.644a11.054 11.054 0 0 0-4.294 0M5.888 2.853a11.054 11.054 0 0 0-3.035 3.035\"/>`,\n    shapeIconToolSelectionPolygon:\n        '<g fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18h11V1L13 9 1 6l5 9 3 6v2\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.8\" transform=\"rotate(-2 8 18)\"/></g>',\n};\n\n// deprecated\nexport const ShapeEditor = MarkupEditor;\n", "export default {\n    cropLabel: 'Ritaglia',\n    cropIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3\"/></g>',\n    cropIconButtonRecenter: `<path stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linejoin=\"bevel\" d=\"M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\"/>`,\n    cropIconButtonRotateLeft:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><rect x=\"3\" rx=\"1\" height=\"12\" width=\"12\" y=\"9\"/><path d=\"M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z\"/></g>',\n    cropIconButtonRotateRight:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><path d=\"M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z\"/><rect rx=\"1\" height=\"12\" width=\"12\" y=\"9\" x=\"9\"/></g>',\n    cropIconButtonFlipVertical:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z\"/><path d=\"M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z\" opacity=\".6\"/></g>',\n    cropIconButtonFlipHorizontal:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z\"/><path d=\"M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z\" opacity=\".6\"/></g>',\n\n    cropIconSelectPreset: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"4\" width=\"10\" height=\"18\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"6\" y=\"12\" width=\"17\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropIconCropBoundary: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"3\" width=\"20\" height=\"20\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"7\" y=\"8\" width=\"10\" height=\"10\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{d}\" x=\"12\" y=\"4\" width=\"10\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropLabelButtonRecenter: 'Ricentra',\n    cropLabelButtonRotateLeft: 'Ruota a sinistra',\n    cropLabelButtonRotateRight: 'Ruota a destra',\n    cropLabelButtonFlipHorizontal: 'Capovolgi orizzontalmente',\n    cropLabelButtonFlipVertical: 'Capovolgi verticalmente',\n\n    cropLabelSelectPreset: 'Forma ritaglio',\n\n    cropLabelCropBoundary: 'Bordo del ritaglio',\n    cropLabelCropBoundaryEdge: \"Bordo dell'immagine\",\n    cropLabelCropBoundaryNone: 'Nessuno',\n\n    cropLabelTabRotation: 'Rotazione',\n    cropLabelTabZoom: 'Scala',\n};\n", "export default {\n    annotateLabel: 'Annotare',\n    annotateIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z\"/></g>',\n};\n", "export default {\n    redactLabel: 'Redigere',\n    redactIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M 4 5 l 1 -1\"/><path d=\"M 4 10 l 6 -6\"/><path d=\"M 4 15 l 11 -11\"/><path d=\"M 4 20 l 16 -16\"/><path d=\"M 9 20 l 11 -11\"/><path d=\"M 14 20 l 6 -6\"/><path d=\"M 19 20 l 1 -1\"/></g>`,\n};\n", "const IconCross =\n    '<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"></path></path></g>';\n\nconst CharacterA =\n    '<path fill=\"none\" d=\"M9 15 L12 9 L15 15 M10 13.5 h3\" stroke=\"currentColor\" stroke-width=\".125em\"/>';\n\nexport default {\n    // generic\n    labelReset: 'Resetten',\n    labelDefault: 'Standaard',\n    labelAuto: 'Automatisch',\n    labelNone: 'Geen',\n    labelEdit: 'Bewerken',\n    labelClose: 'Sluiten',\n    labelSupportError: `{features} niet ondersteund op deze browser`,\n    labelMemoryError: `De browser had onvoldoende geheugen`,\n\n    // defaults\n    labelColor: 'Kleur',\n    labelWidth: 'Breedte',\n    labelSize: 'Afmeting',\n    labelOffset: 'Offset',\n    labelAmount: 'Aantal',\n    labelInset: 'Inzet',\n    labelRadius: 'Straal',\n\n    // controls\n    labelColorPalette: 'Kleurenpalet',\n\n    // sizes\n    labelSizeExtraSmall: 'Extra klein',\n    labelSizeSmall: 'Klein',\n    labelSizeMediumSmall: 'Gemiddeld klein',\n    labelSizeMedium: 'Gemiddeld',\n    labelSizeMediumLarge: 'Gemiddeld groot',\n    labelSizeLarge: 'Groot',\n    labelSizeExtraLarge: 'Extra groot',\n\n    // default buttons\n    labelButtonCancel: 'Annuleren',\n    labelButtonUndo: 'ongedaan maken',\n    labelButtonRedo: 'Opnieuw doen',\n    labelButtonRevert: 'Terugdraaien',\n    labelButtonExport: 'Klaar',\n\n    // zoom\n    labelZoom: 'Zoom',\n    labelZoomIn: 'Zoom in',\n    labelZoomOut: 'Zoom uit',\n    labelZoomFit: 'Passend maken',\n    labelZoomActual: 'Echte grootte',\n    iconZoomIn: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M8 12 h8 M12 8 v8\" />',\n    iconZoomOut: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M9 12 h6\" />',\n\n    // icons\n    iconSupportError: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><g><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></g>`,\n    iconButtonClose: IconCross,\n    iconButtonRevert: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M7.388 18.538a8 8 0 10-2.992-9.03\"/><path fill=\"currentColor\" d=\"M2.794 11.696L2.37 6.714l5.088 3.18z\"/><path d=\"M12 8v4M12 12l4 2\"/></g>`,\n    iconButtonUndo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4\"/><path fill=\"currentColor\" d=\"M5 8l4-3v6z\"/></g>`,\n    iconButtonRedo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4\"/><path fill=\"currentColor\" d=\"M19 8l-4-3v6z\"/></g>`,\n    iconButtonExport: `<polyline points=\"20 6 9 17 4 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"></polyline>`,\n\n    // status\n    statusLabelButtonClose: 'Sluiten',\n    statusIconButtonClose: IconCross,\n\n    // new status options\n    statusImageLoadNone: 'Wacht op afbeelding',\n    statusImageLoadMinSize: 'Minimale afbeelding grootte is {minWidth} &times; {minHeight}',\n    statusImageLoadError: 'Probleem met laden afbeelding',\n    statusImageLoadPrepare: 'Bezig met voorbereiden afbeelding&hellip;',\n    statusImageLoadBusy: 'Bezig met laden afbeelding&hellip;',\n    statusImageUploadError: 'Probleem met uploaden van afbeelding',\n    statusImageUploadBusy: 'Afbeelding aan het uploaden&hellip;',\n    statusImageProcessError: 'Probleem met verwerken van afbeelding',\n    statusImageProcessBusy: 'Bezig met verwerken van afbeelding&hellip;',\n};\n\nexport const MarkupEditor = {\n    shapeLabelButtonSelectSticker: 'Afbeelding selecteren',\n\n    shapeIconButtonSelectSticker: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.0625em\"><path d=\"M8 21 L15 11 L19 15\"/><path d=\"M15 2 v5 h5\"/><path d=\"M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z\"/></g><circle fill=\"currentColor\" cx=\"10\" cy=\"8\" r=\"1.5\"/>`,\n\n    shapeIconButtonFlipHorizontal: `<g stroke=\"currentColor\" stroke-width=\".125em\"><path fill=\"none\" d=\"M6 6.5h5v11H6z\"/><path fill=\"currentColor\" d=\"M15 6.5h3v11h-3z\"/><path d=\"M11 4v16\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonFlipVertical: `<g stroke=\"currentColor\" stroke-width=\".125em\"><rect x=\"7\" y=\"8\" width=\"11\" height=\"5\" fill=\"none\"/><rect x=\"7\" y=\"17\" width=\"11\" height=\"2\" fill=\"currentColor\"/><line x1=\"5\" y1=\"13\" x2=\"20\" y2=\"13\"/></g>`,\n    shapeIconButtonRemove: `<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 7h9z\"/><path d=\"M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z\" fill=\"currentColor\"/><rect fill=\"currentColor\" x=\"10\" y=\"5\" width=\"4\" height=\"3\" rx=\"1\"/></g>`,\n    shapeIconButtonDuplicate: `<g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142\" stroke=\"currentColor\" stroke-width=\".125em\"/><path d=\"M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonMoveToFront: `<g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"currentColor\" x=\"11\" y=\"13\" width=\"8\" height=\"2\" rx=\"1\"/><rect fill=\"currentColor\" x=\"9\" y=\"17\" width=\"10\" height=\"2\" rx=\"1\"/><path d=\"M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z\" stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\"/></g>`,\n\n    shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,\n    shapeIconButtonTextLayoutAutoHeight: `<g fill=\"currentColor\"><circle cx=\"4\" cy=\"12\" r=\"1.5\"/><circle cx=\"20\" cy=\"12\" r=\"1.5\"/></g>${CharacterA}`,\n    shapeIconButtonTextLayoutFixedSize: `<g fill=\"currentColor\"><circle cx=\"5\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"19\" r=\"1.5\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\"/></g>${CharacterA}`,\n\n    shapeTitleButtonTextLayoutAutoWidth: 'Automatische breedte',\n    shapeTitleButtonTextLayoutAutoHeight: 'Automatische hoogte',\n    shapeTitleButtonTextLayoutFixedSize: 'Vaste afmetingen',\n\n    shapeTitleButtonFlipHorizontal: 'Spiegel Horizontaal',\n    shapeTitleButtonFlipVertical: 'Spiegel Verticaal',\n    shapeTitleButtonRemove: 'Verwijderen',\n    shapeTitleButtonDuplicate: 'Dupliceren',\n    shapeTitleButtonMoveToFront: 'Naar voren verplaatsen',\n\n    shapeLabelInputText: 'Text bewerken',\n\n    shapeIconInputCancel: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"/></g>`,\n    shapeIconInputConfirm: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><polyline points=\"20 6 9 17 4 12\"/></g>`,\n    shapeLabelInputCancel: 'Annuleren',\n    shapeLabelInputConfirm: 'Bevestigen',\n\n    shapeLabelStrokeNone: 'Geen rand',\n\n    shapeLabelFontStyleNormal: 'Normal',\n    shapeLabelFontStyleBold: 'Bold',\n    shapeLabelFontStyleItalic: 'Italic',\n    shapeLabelFontStyleItalicBold: 'Bold Italic',\n\n    shapeTitleBackgroundColor: 'Achtergrond kleur',\n    shapeTitleCornerRadius: 'Hoekradius',\n\n    shapeTitleFontFamily: 'Lettertype',\n    shapeTitleFontSize: 'Lettertype grootte',\n    shapeTitleFontStyle: 'Lettertype stijl',\n    shapeTitleLineHeight: 'Lijnhoogte',\n\n    shapeTitleLineStart: 'Start',\n    shapeTitleLineEnd: 'Eind',\n    shapeTitleStrokeWidth: 'Lijn dikte',\n    shapeTitleStrokeColor: 'Lijn kleur',\n\n    shapeTitleLineDecorationBar: 'Balk',\n    shapeTitleLineDecorationCircle: 'Circel',\n    shapeTitleLineDecorationSquare: 'Vierkant',\n    shapeTitleLineDecorationArrow: 'Pijl',\n    shapeTitleLineDecorationCircleSolid: 'Circel gevuld',\n    shapeTitleLineDecorationSquareSolid: 'Vierkant gevuld',\n    shapeTitleLineDecorationArrowSolid: 'Pijl gevuld',\n\n    shapeIconLineDecorationBar: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M16,8 V16\"/></g>`,\n    shapeIconLineDecorationCircle: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"none\" stroke-width=\".125em\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquare: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"none\" stroke-width=\".125em\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrow: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16 M13,7 l6,5 l-6,5\" fill=\"none\"/></g>`,\n    shapeIconLineDecorationCircleSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"currentColor\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquareSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"currentColor\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrowSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M13,7 l6,5 l-6,5z\" fill=\"currentColor\"/></g>`,\n\n    shapeTitleColorTransparent: 'Transparant',\n    shapeTitleColorWhite: 'Wit',\n    shapeTitleColorSilver: 'Zilver',\n    shapeTitleColorGray: 'Grijs',\n    shapeTitleColorBlack: 'Zwart',\n    shapeTitleColorNavy: 'Marine',\n    shapeTitleColorBlue: 'Blauw',\n    shapeTitleColorAqua: 'Water',\n    shapeTitleColorTeal: 'Groenblauw',\n    shapeTitleColorOlive: 'Olijf',\n    shapeTitleColorGreen: 'Groen',\n    shapeTitleColorYellow: 'Geel',\n    shapeTitleColorOrange: 'Oranje',\n    shapeTitleColorRed: 'Rood',\n    shapeTitleColorMaroon: 'Kastanjebruin',\n    shapeTitleColorFuchsia: 'Fuchsia',\n    shapeTitleColorPurple: 'Paars',\n\n    shapeTitleTextOutline: 'Tekstomlijning',\n    shapeTitleTextOutlineWidth: 'Breedte',\n    shapeTitleTextShadow: 'Tekstschaduw',\n    shapeTitleTextShadowBlur: 'Vervaging',\n\n    shapeTitleTextColor: 'Lettertype kleur',\n    shapeTitleTextAlign: 'Tekst uitlijning',\n    shapeTitleTextAlignLeft: 'Tekst links uitlijnen',\n    shapeTitleTextAlignCenter: 'Tekst midden uitlijnen',\n    shapeTitleTextAlignRight: 'Tekst rechts uitlijnen',\n\n    shapeIconTextAlignLeft: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"5\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"5\" y1=\"16\" x2=\"14\" y2=\"16\"/></g>`,\n    shapeIconTextAlignCenter: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"7\" y1=\"8\" x2=\"17\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"8\" y1=\"16\" x2=\"16\" y2=\"16\"/></g>`,\n    shapeIconTextAlignRight: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"9\" y1=\"8\" x2=\"19\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"11\" y1=\"16\" x2=\"19\" y2=\"16\"/></g>`,\n\n    shapeLabelToolMove: 'Verplaatsen',\n    shapeLabelToolView: 'Bekijken',\n    shapeLabelToolSharpie: 'Sharpie',\n    shapeLabelToolEraser: 'Gom',\n    shapeLabelToolPath: 'Pad',\n    shapeLabelToolRectangle: 'Rechthoek',\n    shapeLabelToolEllipse: 'Ovaal',\n    shapeLabelToolArrow: 'Pijl',\n    shapeLabelToolLine: 'Lijn',\n    shapeLabelToolText: 'Tekst',\n    shapeLabelToolPreset: 'Stickers',\n\n    shapeIconToolView: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.98 9.703V2.567c0-1.19 1.19-1.785 1.784-1.785.595 0 1.784.595 1.784 1.785v3.568\"/><path d=\"M14.548 9.703V4.35c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.594 1.784 1.784v2.973\"/><path d=\"M18.116 10.244V7.271c0-1.19 1.19-1.784 1.784-1.784.595 0 1.785.595 1.785 1.784 0 1.19 0 8.92-1.19 12.488-1.19 3.569-10.704 4.758-13.678 0-2.973-4.757-2.973-4.757-4.163-6.541-1.189-1.784-1.153-2.974-.594-3.568.558-.595 1.784-1.19 2.973.594 1.277 1.916 2.07 2.907 2.379 2.974V5.487c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.595 1.784 1.784V8.46\"/></g>`,\n    shapeIconToolMove: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M6 2 L6 19 L18 13 Z M13 18 L16 24\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSharpie: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolEraser: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" fill=\"none\"><g transform=\"translate(3, 15) rotate(-45)\"><rect x=\"0\" y=\"0\" width=\"18\" height=\"10\" rx=\"3\"/></g><line x1=\"11\" y1=\"21\" x2=\"18\" y2=\"21\"/><line x1=\"20\" y1=\"21\" x2=\"22\" y2=\"21\"/></g>`,\n    shapeIconToolPath: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"><circle cx=\"21\" cy=\"3\" r=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><circle cx=\"3\" cy=\"21\" r=\"2\"/><path d=\"M19 4 11 8 M8 11 4 19\"/></g>`,\n    shapeIconToolRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"1\" y=\"1\" width=\"22\" height=\"22\" rx=\"4\"/></g>`,\n    shapeIconToolEllipse: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"11\"/></g>`,\n    shapeIconToolArrow: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/><path d=\"m10 6 L21.5 1 L20 13.5\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n    shapeIconToolLine: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/></g>`,\n    shapeIconToolText: `<g stroke=\"none\" fill=\"currentColor\" transform=\"translate(6,0)\"><path d=\"M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z\"/>`,\n    shapeIconToolPreset: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"></path><path d=\"M20 17c-3 3-5 5-8 5\"></path></g>`,\n\n    shapeTitleSelectionMode: 'Selectiemodus',\n    shapeTitleBrushSize: 'Penseelgrootte',\n\n    shapeLabelSelectionModeNew: 'Nieuw',\n    shapeLabelSelectionModeAdd: 'Toevoegen',\n    shapeLabelSelectionModeSubtract: 'Verwijderen',\n\n    shapeLabelToolSelectionBrush: 'Penseel',\n    shapeLabelToolSelectionLassoo: 'Lasso',\n    shapeLabelToolSelectionRectangle: 'Rechthoekselectie',\n    shapeLabelToolSelectionEllipse: 'Ellipsselectie',\n    shapeLabelToolSelectionPolygon: 'Polygoonselectie',\n\n    shapeIconSelectionModeNew: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 17H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1.5\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" fill=\"currentColor\" fill-opacity=\".25\" rx=\"2\"/></g>`,\n    shapeIconSelectionModeAdd: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><path d=\"M13 15h4M15 13v4\"/></g>`,\n    shapeIconSelectionModeSubtract: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h-6a2 2 0 0 0-1.995 1.85L9 11v6H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" rx=\"2\"/><path d=\"M13 15h4\"/></g>`,\n    shapeIconToolSelectionBrush: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSelectionLassoo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-width=\".125em\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.428 17.702a18.46 18.46 0 0 0 4.085-1.595c5.851-3.112 9.019-8.599 7.074-12.256-1.945-3.657-8.265-4.1-14.116-.988C2.619 5.974-.55 11.46 1.396 15.118c.63 1.186 1.72 2.033 3.105 2.532\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.833\" transform=\"rotate(-15 8 18.5)\"/><path stroke-linecap=\"round\" d=\"M5 18c3.347 1.048 5.514 1.881 6.5 2.5.859.54 1.517.994 1.5 2.364\"/></g>`,\n    shapeIconToolSelectionRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\"><path d=\"M9 1 h6 m4 0 h4v4 m0 4 v6 m0 4 v4h-4 m-4 0 h-6 m-4 0 h-4v-4 m0 -4 v-6 m0 -4 v-4h4\" fill=\"none\" /></g>`,\n    shapeIconToolSelectionEllipse: `<path stroke-width=\".125em\" stroke=\"currentColor\" d=\"M1.21 9.853a11.054 11.054 0 0 0 0 4.294m1.643 3.965a11.054 11.054 0 0 0 3.035 3.035m3.965 1.644a11.054 11.054 0 0 0 4.294 0m3.965-1.644a11.054 11.054 0 0 0 3.035-3.035m1.644-3.965a11.054 11.054 0 0 0 0-4.294m-1.644-3.965a11.054 11.054 0 0 0-3.035-3.035m-3.965-1.644a11.054 11.054 0 0 0-4.294 0M5.888 2.853a11.054 11.054 0 0 0-3.035 3.035\"/>`,\n    shapeIconToolSelectionPolygon:\n        '<g fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18h11V1L13 9 1 6l5 9 3 6v2\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.8\" transform=\"rotate(-2 8 18)\"/></g>',\n};\n\n// deprecated\nexport const ShapeEditor = MarkupEditor;\n", "export default {\n    cropLabel: 'Bijsnijden',\n    cropIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3\"/></g>',\n    cropIconButtonRecenter: `<path stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linejoin=\"bevel\" d=\"M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\"/>`,\n    cropIconButtonRotateLeft:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><rect x=\"3\" rx=\"1\" height=\"12\" width=\"12\" y=\"9\"/><path d=\"M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z\"/></g>',\n    cropIconButtonRotateRight:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><path d=\"M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z\"/><rect rx=\"1\" height=\"12\" width=\"12\" y=\"9\" x=\"9\"/></g>',\n    cropIconButtonFlipVertical:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z\"/><path d=\"M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z\" opacity=\".6\"/></g>',\n    cropIconButtonFlipHorizontal:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z\"/><path d=\"M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z\" opacity=\".6\"/></g>',\n\n    cropIconSelectPreset: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"4\" width=\"10\" height=\"18\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"6\" y=\"12\" width=\"17\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropIconCropBoundary: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"3\" width=\"20\" height=\"20\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"7\" y=\"8\" width=\"10\" height=\"10\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{d}\" x=\"12\" y=\"4\" width=\"10\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropLabelButtonRecenter: 'Centreren',\n    cropLabelButtonRotateLeft: 'Roteer linksom',\n    cropLabelButtonRotateRight: 'Roteer rechtsom',\n    cropLabelButtonFlipHorizontal: 'Spiegel horizontaal',\n    cropLabelButtonFlipVertical: 'Spiegel verticaal',\n\n    cropLabelSelectPreset: 'Kies bijsnijdvorm',\n\n    cropLabelCropBoundary: 'Bijsnijd grens',\n    cropLabelCropBoundaryEdge: 'Rand van afbeelding',\n    cropLabelCropBoundaryNone: 'Geen',\n\n    cropLabelTabRotation: 'Rotatie',\n    cropLabelTabZoom: 'Schalen',\n};\n", "export default {\n    annotateLabel: 'Annoteren',\n    annotateIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z\"/></g>',\n};\n", "export default {\n    redactLabel: 'Redigeren',\n    redactIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M 4 5 l 1 -1\"/><path d=\"M 4 10 l 6 -6\"/><path d=\"M 4 15 l 11 -11\"/><path d=\"M 4 20 l 16 -16\"/><path d=\"M 9 20 l 11 -11\"/><path d=\"M 14 20 l 6 -6\"/><path d=\"M 19 20 l 1 -1\"/></g>`,\n};\n", "function normalizeLocale(locale) {\n  return (locale || 'en')\n    .toString()\n    .split(/[-_]/)[0]\n    .toLowerCase();\n}\n\n// Keep these imports explicit so esbuild includes the modules.\nimport locale_de_DE, { MarkupEditor as locale_markup_editor_de_DE } from '@pqina/pintura/locale/de_DE/core/de_DE.js';\nimport locale_crop_de_DE from '@pqina/pintura/locale/de_DE/crop/de_DE.js';\nimport locale_annotate_de_DE from '@pqina/pintura/locale/de_DE/annotate/de_DE.js';\nimport locale_redact_de_DE from '@pqina/pintura/locale/de_DE/redact/de_DE.js';\n\nimport locale_en_GB, { MarkupEditor as locale_markup_editor_en_GB } from '@pqina/pintura/locale/en_GB/core/en_GB.js';\nimport locale_crop_en_GB from '@pqina/pintura/locale/en_GB/crop/en_GB.js';\nimport locale_annotate_en_GB from '@pqina/pintura/locale/en_GB/annotate/en_GB.js';\nimport locale_redact_en_GB from '@pqina/pintura/locale/en_GB/redact/en_GB.js';\n\nimport locale_es_ES, { MarkupEditor as locale_markup_editor_es_ES } from '@pqina/pintura/locale/es_ES/core/es_ES.js';\nimport locale_crop_es_ES from '@pqina/pintura/locale/es_ES/crop/es_ES.js';\nimport locale_annotate_es_ES from '@pqina/pintura/locale/es_ES/annotate/es_ES.js';\nimport locale_redact_es_ES from '@pqina/pintura/locale/es_ES/redact/es_ES.js';\n\nimport locale_fr_FR, { MarkupEditor as locale_markup_editor_fr_FR } from '@pqina/pintura/locale/fr_FR/core/fr_FR.js';\nimport locale_crop_fr_FR from '@pqina/pintura/locale/fr_FR/crop/fr_FR.js';\nimport locale_annotate_fr_FR from '@pqina/pintura/locale/fr_FR/annotate/fr_FR.js';\nimport locale_redact_fr_FR from '@pqina/pintura/locale/fr_FR/redact/fr_FR.js';\n\nimport locale_it_IT, { MarkupEditor as locale_markup_editor_it_IT } from '@pqina/pintura/locale/it_IT/core/it_IT.js';\nimport locale_crop_it_IT from '@pqina/pintura/locale/it_IT/crop/it_IT.js';\nimport locale_annotate_it_IT from '@pqina/pintura/locale/it_IT/annotate/it_IT.js';\nimport locale_redact_it_IT from '@pqina/pintura/locale/it_IT/redact/it_IT.js';\n\nimport locale_nl_NL, { MarkupEditor as locale_markup_editor_nl_NL } from '@pqina/pintura/locale/nl_NL/core/nl_NL.js';\nimport locale_crop_nl_NL from '@pqina/pintura/locale/nl_NL/crop/nl_NL.js';\nimport locale_annotate_nl_NL from '@pqina/pintura/locale/nl_NL/annotate/nl_NL.js';\nimport locale_redact_nl_NL from '@pqina/pintura/locale/nl_NL/redact/nl_NL.js';\n\nexport function pinturaLocalePackForLocale(locale) {\n  // Rails available_locales: de, en, nl, pl, it, fr, es\n  // Pintura: no pl_PL in your install, so pl falls back to en_GB.\n  switch (normalizeLocale(locale)) {\n    case 'de': return { core: locale_de_DE, markup: locale_markup_editor_de_DE, crop: locale_crop_de_DE, annotate: locale_annotate_de_DE, redact: locale_redact_de_DE };\n    case 'es': return { core: locale_es_ES, markup: locale_markup_editor_es_ES, crop: locale_crop_es_ES, annotate: locale_annotate_es_ES, redact: locale_redact_es_ES };\n    case 'fr': return { core: locale_fr_FR, markup: locale_markup_editor_fr_FR, crop: locale_crop_fr_FR, annotate: locale_annotate_fr_FR, redact: locale_redact_fr_FR };\n    case 'it': return { core: locale_it_IT, markup: locale_markup_editor_it_IT, crop: locale_crop_it_IT, annotate: locale_annotate_it_IT, redact: locale_redact_it_IT };\n    case 'nl': return { core: locale_nl_NL, markup: locale_markup_editor_nl_NL, crop: locale_crop_nl_NL, annotate: locale_annotate_nl_NL, redact: locale_redact_nl_NL };\n    default:   return { core: locale_en_GB, markup: locale_markup_editor_en_GB, crop: locale_crop_en_GB, annotate: locale_annotate_en_GB, redact: locale_redact_en_GB };\n  }\n}\n\n", "/*!\n* Pintura v8.98.1 \n* (c) 2018-2026 Pintura Labs B.V. - All Rights Reserved\n* License: https://pqina.nl/pintura/license/\n*/\n/* eslint-disable */\n\nconst APP1_MARKER = 0xffe1;\nconst APP2_MARKER$1 = 0xffe2;\nconst APP1_EXIF_IDENTIFIER = 0x45786966;\nconst TIFF_MARKER = 0x002a;\nconst BYTE_ALIGN_MOTOROLA = 0x4d4d;\nconst BYTE_ALIGN_INTEL = 0x4949;\nconst dataViewGetApp2Tags = (view, offset) => {\n    // not app2\n    if (view.getUint16(offset) !== APP2_MARKER$1)\n        return undefined;\n    // get app2 marker size\n    const size = view.getUint16(offset + 2);\n    // test for ICC_PROFILE\n    const decoder = new TextDecoder();\n    const str = decoder.decode(view.buffer.slice(offset + 4, offset + 15));\n    // not a ICC profile\n    if (str !== 'ICC_PROFILE')\n        return;\n    // currently we only deal with one ICC chunk (should probably collect all app2 chunks in dataViewGetApplicationMarkers)\n    // const chunkIndex = view.getUint8(offset + 15);\n    // const chunkTotal = view.getUint8(offset + 16);\n    // const dataStart = offset + 17;\n    // const dataEnd = dataStart + size;\n    offset += 18;\n    // turns the next 4 bytes into a string\n    function bytesAsString(offset) {\n        return String.fromCharCode(iccDataView.getUint8(offset), iccDataView.getUint8(offset + 1), iccDataView.getUint8(offset + 2), iccDataView.getUint8(offset + 3));\n    }\n    function getTagValue(type, offset, size) {\n        // not interested in XYZ, para, or sf32 headers for now\n        const { buffer } = iccDataView;\n        let from, to;\n        if (type === 'text') {\n            from = offset + 8;\n            to = offset + size - 7;\n        }\n        else if (type === 'desc') {\n            const length = iccDataView.getUint32(offset + 8);\n            from = offset + 12;\n            to = offset + length + 12;\n        }\n        else if (type === 'mluc') {\n            // we only deal with one record entry for now\n            // const recordCount = iccDataView.getUint32(offset + 8);\n            // const recordSize = iccDataView.getUint32(offset + 12);\n            const itemLength = iccDataView.getUint32(offset + 20);\n            const itemOffset = iccDataView.getUint32(offset + 24);\n            from = offset + itemOffset;\n            to = offset + itemOffset + itemLength;\n        }\n        else {\n            return;\n        }\n        return new TextDecoder().decode(buffer.slice(from, to)).replace(/\\u0000|\\x00/g, '');\n    }\n    // icc profile\n    const iccDataView = new DataView(view.buffer.slice(offset, offset + size));\n    const tagCount = iccDataView.getUint32(128);\n    const tags = [];\n    // get tags\n    let tagHeaderOffset = 132;\n    for (let i = 0; i < tagCount; i++) {\n        const address = iccDataView.getUint32(tagHeaderOffset);\n        const offset = iccDataView.getUint32(tagHeaderOffset + 4);\n        // this is a guard against the offset falling outside of the DataView size, we limit the size of the dataview to speed up parsing, but sometimes tag offsets might end up outside of the dataview, in a future version we need to scale up the DataView size as we discover tags outside of it\n        if (offset > iccDataView.byteLength) {\n            break;\n        }\n        const size = iccDataView.getUint32(tagHeaderOffset + 8);\n        const type = bytesAsString(offset);\n        const value = getTagValue(type, offset, size);\n        // ignore all other tags for now\n        if (address === COLOR_SPACE_TAG) {\n            tags.push({ address, offset, size, type, value });\n            break;\n        }\n        tagHeaderOffset += 12;\n    }\n    return {\n        read: (address) => {\n            const result = tags.find((tag) => tag.address === address);\n            return result ? result.value : undefined;\n        },\n        write: (address, value) => {\n            // empty for now\n        },\n    };\n};\n// helper method to find tag offset by exif marker\nconst getExifTagOffsets = (view, offset, size, marker, storedAsLittleEndian = true) => {\n    const offsets = [];\n    let i = offset;\n    const max = Math.min(view.byteLength, offset + size - 16);\n    for (; i < max; i += 12) {\n        const tagOffset = i;\n        // see if is match, if not, next entry\n        if (view.getUint16(tagOffset, storedAsLittleEndian) !== marker)\n            continue;\n        // add offset\n        offsets.push(tagOffset);\n    }\n    return offsets;\n};\n// offset = start of APP1_MARKER\nconst dataViewGetExifTags = (view, offset) => {\n    // If no APP1 marker exit here because we're not going to find the EXIF id header outside of APP1\n    if (view.getUint16(offset) !== APP1_MARKER)\n        return undefined;\n    // get marker size\n    const size = view.getUint16(offset + 2); // 14197\n    // Let's skip over app1 marker and size marker (2 + 2 bytes)\n    offset += 4;\n    // We're now at the EXIF header marker (we'll only check the first 4 bytes, reads \"exif\"), if not there, exit\n    if (view.getUint32(offset) !== APP1_EXIF_IDENTIFIER)\n        return undefined;\n    // Let's skip over 6 byte EXIF marker\n    offset += 6;\n    // Read byte alignment\n    const byteAlignment = view.getUint16(offset);\n    if (byteAlignment !== BYTE_ALIGN_INTEL && byteAlignment !== BYTE_ALIGN_MOTOROLA)\n        return undefined;\n    const storedAsLittleEndian = byteAlignment === BYTE_ALIGN_INTEL;\n    // Skip over byte alignment\n    offset += 2;\n    // Test if valid tiff marker data, should always be 0x002a\n    if (view.getUint16(offset, storedAsLittleEndian) !== TIFF_MARKER)\n        return undefined;\n    // Skip to first IDF, position of IDF is read after tiff marker (offset 2)\n    offset += view.getUint32(offset + 2, storedAsLittleEndian);\n    return {\n        read: (address) => {\n            const tagOffsets = getExifTagOffsets(view, offset, size, address, storedAsLittleEndian);\n            if (!tagOffsets.length)\n                return undefined;\n            // only return first found tag\n            return view.getUint16(tagOffsets[0] + 8, storedAsLittleEndian);\n        },\n        write: (address, value) => {\n            const tagOffsets = getExifTagOffsets(view, offset, size, address, storedAsLittleEndian);\n            if (!tagOffsets.length)\n                return false;\n            // overwrite all found tags (sometimes images can have multiple tags with the same value, let's make sure they're all set)\n            tagOffsets.forEach((offset) => view.setUint16(offset + 8, value, storedAsLittleEndian));\n            return true;\n        },\n    };\n};\n\nvar noop$1 = (...args) => { };\n\nconst JFIF_MARKER = 0xffe0;\nconst EXIF_MARKER = 0xffe1;\nconst SOS_MARKER = 0xffda;\nconst XMP_MARKER = 0xffe1;\nconst MPF_MARKER = 0xffe2;\nconst APP2_MARKER = 0xffe2;\nconst Markers = [\n    { value: JFIF_MARKER, name: 'jfif', getTags: noop$1 },\n    { value: SOS_MARKER, name: 'sos', getTags: noop$1 },\n    { value: EXIF_MARKER, subvalue: 0x4578, name: 'exif', getTags: dataViewGetExifTags },\n    { value: XMP_MARKER, subvalue: 0x6874, name: 'xmp', getTags: noop$1 },\n    { value: MPF_MARKER, subvalue: 0x4d50, name: 'mpf', getTags: noop$1 },\n    { value: APP2_MARKER, name: 'app2', getTags: dataViewGetApp2Tags },\n];\nconst JPEG_SOI_MARKER = 0xffd8; // start of JPEG\nconst JPEG_MARKER_PREFIX = 0xff;\nvar dataViewGetApplicationMarkers = (view) => {\n    // If no SOI marker exit here because we're not going to find the APP1 header in a non-jpeg file\n    if (view.getUint16(0) !== JPEG_SOI_MARKER)\n        return undefined;\n    const length = view.byteLength; // cache the length here\n    let offset = 2; // start at 2 as we skip the SOI marker\n    let marker; // this will hold the current marker\n    // resulting markers\n    let res = undefined;\n    while (offset < length) {\n        // test if marker is valid JPEG marker (starts with ff)\n        if (view.getUint8(offset) !== JPEG_MARKER_PREFIX)\n            break;\n        // let's read the full marker\n        marker = view.getUint16(offset);\n        // read marker if included in marker types\n        const markerDescription = Markers.find((descriptor) => {\n            if (descriptor.value === marker) {\n                if (descriptor.subvalue) {\n                    return descriptor.subvalue === view.getUint16(offset + 2 + 2);\n                }\n                return true;\n            }\n            return false;\n        });\n        if (markerDescription) {\n            const { name, getTags } = markerDescription;\n            if (!res)\n                res = {};\n            // prevent overwriting by double markers\n            if (!res[name]) {\n                let currentOffset = offset;\n                res[name] = {\n                    offset,\n                    size: view.getUint16(offset + 2),\n                    getTags: () => getTags(view, currentOffset),\n                };\n            }\n            // TODO: an ICC profile can be spread over multiple APP2 segments, for now we're just looking at the first one\n        }\n        // Image stream starts here, no markers found\n        if (marker === SOS_MARKER)\n            break;\n        // next offset is 2 to skip over marker type and then we add marker data size to skip to next marker\n        offset += 2 + view.getUint16(offset + 2);\n    }\n    // no APP markers found\n    return res;\n};\n\nconst ORIENTATION_TAG = 0x0112;\nconst COLOR_SPACE_TAG = 0x64657363;\nconst getMarkers = (data) => {\n    // no data, no go!\n    if (!data)\n        return;\n    const view = new DataView(data);\n    // Get header markers\n    return dataViewGetApplicationMarkers(view);\n};\nconst arrayBufferImageTagsRead = (data, entries) => {\n    const markers = getMarkers(data);\n    if (!markers)\n        return;\n    return Object.entries(entries).reduce((res, [marker, tags]) => {\n        if (!markers[marker])\n            return res;\n        const markerTags = markers[marker].getTags();\n        if (!markerTags)\n            return res;\n        for (const tag of tags) {\n            const value = markerTags.read(tag);\n            res[marker] = {\n                ...res[marker],\n                [tag]: value,\n            };\n        }\n        return res;\n    }, {});\n};\nconst arrayBufferImageTagsWrite = (data, entries) => {\n    const markers = getMarkers(data);\n    if (!markers)\n        return;\n    Object.entries(entries).forEach(([marker, tags]) => {\n        if (!markers[marker])\n            return;\n        const markerTags = markers[marker].getTags();\n        if (!markerTags)\n            return;\n        tags.forEach(([key, value]) => {\n            markerTags.write(key, value);\n        });\n    });\n};\n\nconst backup = '__pqina_webapi__';\nvar getNativeAPIRef = (API) => (window[backup] ? window[backup][API] : window[API]);\n\nconst FileReaderDataFormat = {\n    ArrayBuffer: 'readAsArrayBuffer',\n};\nvar readFile = (file, onprogress = noop$1, options = {}) => new Promise((resolve, reject) => {\n    const { dataFormat = FileReaderDataFormat.ArrayBuffer } = options;\n    const reader = new (getNativeAPIRef('FileReader'))();\n    reader.onload = () => resolve(reader.result);\n    reader.onerror = () => reject(reader.error);\n    reader.onprogress = onprogress;\n    reader[dataFormat](file);\n});\n\nvar blobReadSection = async (blob, slice = [0, blob.size], onprogress) => (await readFile(blob.slice(...slice), onprogress));\n\nvar getImageTagsFromFile = async (file, tags, slice = [0, file.size], onprogress) => {\n    const head = await blobReadSection(file, slice, onprogress);\n    return arrayBufferImageTagsRead(head, tags);\n};\n\nlet result$e = null;\nvar isBrowser = () => {\n    if (result$e === null)\n        result$e = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n    return result$e;\n};\n\nlet result$d = null;\nvar canOrientImages = () => new Promise((resolve) => {\n    if (result$d === null) {\n        // 2x1 pixel image 90CW rotated with orientation EXIF header\n        const testSrc = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4QA6RXhpZgAATU0AKgAAAAgAAwESAAMAAAABAAYAAAEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////wAALCAABAAIBASIA/8QAJgABAAAAAAAAAAAAAAAAAAAAAxABAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQAAPwBH/9k=';\n        let testImage = isBrowser() ? new Image() : {};\n        testImage.onload = () => {\n            // should correct orientation if is presented in landscape,\n            // in which case the browser doesn't autocorrect\n            result$d = testImage.naturalWidth === 1;\n            testImage = undefined;\n            resolve(result$d);\n        };\n        testImage.src = testSrc;\n        return;\n    }\n    return resolve(result$d);\n});\n\nvar canvasToImageData = (canvas, options) => {\n    const { colorSpace = 'srgb' } = options || {};\n    const ctx = canvas.getContext('2d', { colorSpace });\n    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n    return imageData;\n};\n\nvar isString = (v) => typeof v === 'string';\n\nfunction setElementStyles(element, styles) {\n    styles.split(';').forEach((style) => {\n        const [prop, value] = style.split(':');\n        if (!prop.length || !value)\n            return;\n        const [cleanValue, important] = value.split('!important');\n        element.style.setProperty(prop, cleanValue, isString(important) ? 'important' : undefined);\n    });\n}\n\nvar h = (name, attributes, children = []) => {\n    const el = document.createElement(name);\n    // @ts-ignore\n    const descriptors = Object.getOwnPropertyDescriptors(el.__proto__);\n    for (const key in attributes) {\n        if (key === 'style') {\n            setElementStyles(el, attributes[key]);\n        }\n        else if ((descriptors[key] && descriptors[key].set) ||\n            /textContent|innerHTML/.test(key) ||\n            typeof attributes[key] === 'function') {\n            el[key] = attributes[key];\n        }\n        else {\n            el.setAttribute(key, attributes[key]);\n        }\n    }\n    children.forEach((child) => el.appendChild(child));\n    return el;\n};\n\nconst MATRICES = {\n    1: () => [1, 0, 0, 1, 0, 0],\n    2: (width) => [-1, 0, 0, 1, width, 0],\n    3: (width, height) => [-1, 0, 0, -1, width, height],\n    4: (width, height) => [1, 0, 0, -1, 0, height],\n    5: () => [0, 1, 1, 0, 0, 0],\n    6: (width, height) => [0, 1, -1, 0, height, 0],\n    7: (width, height) => [0, -1, -1, 0, height, width],\n    8: (width) => [0, -1, 1, 0, 0, width],\n};\nvar getImageOrientationMatrix = (width, height, orientation = -1) => {\n    if (orientation === -1)\n        orientation = 1;\n    return MATRICES[orientation](width, height);\n};\n\nvar releaseCanvas = (canvas) => {\n    canvas.width = 1;\n    canvas.height = 1;\n    const ctx = canvas.getContext('2d');\n    ctx && ctx.clearRect(0, 0, 1, 1);\n};\n\nvar isImageData = (obj) => 'data' in obj;\n\nvar isUserAgent = (test) => isBrowser() ? RegExp(test).test(window.navigator.userAgent) : undefined;\n\nlet result$c = null;\nvar isAndroid = () => {\n    if (result$c === null)\n        result$c = isUserAgent(/Android/);\n    return result$c;\n};\n\nvar canvasClone = (canvas, options) => {\n    const clone = h('canvas', { width: canvas.width, height: canvas.height });\n    clone.getContext('2d', options).drawImage(canvas, 0, 0);\n    return clone;\n};\n\nvar imageDataToCanvas = async (imageData, orientation = 1) => {\n    const colorSpace = imageData instanceof ImageData ? imageData.colorSpace || 'srgb' : 'srgb';\n    const canOrient = await canOrientImages();\n    const [width, height] = canOrient || orientation < 5\n        ? [imageData.width, imageData.height]\n        : [imageData.height, imageData.width];\n    const canvas = h('canvas', { width, height });\n    const ctx = canvas.getContext('2d', { willReadFrequently: true, colorSpace });\n    // transform image data ojects into in memory canvas elements so we can transform them (putImageData isn't affect by transforms)\n    if (isImageData(imageData) && !canOrient && orientation > 1) {\n        const inMemoryCanvas = h('canvas', {\n            width: imageData.width,\n            height: imageData.height,\n        });\n        const ctx = inMemoryCanvas.getContext('2d', { willReadFrequently: true, colorSpace });\n        ctx.putImageData(imageData, 0, 0);\n        imageData = inMemoryCanvas;\n    }\n    // get base transformation matrix\n    if (!canOrient && orientation > 1) {\n        ctx.transform.apply(ctx, getImageOrientationMatrix(imageData.width, imageData.height, orientation));\n    }\n    // can't test for instanceof ImageBitmap as Safari doesn't support it\n    // if still imageData object by this point, we'll use put\n    if (isImageData(imageData)) {\n        ctx.putImageData(imageData, 0, 0);\n        // Somehow on Android + Intel (not on M1) a toBlob call on the current canvas won't return a valid image blob, for some reason duplicating the canvas solves it #882\n        if (isAndroid())\n            return canvasClone(canvas);\n    }\n    else {\n        ctx.drawImage(imageData, 0, 0);\n    }\n    // if image data is of type canvas, clean it up\n    if (imageData instanceof HTMLCanvasElement)\n        releaseCanvas(imageData);\n    return canvas;\n};\n\nvar orientImageData = async (imageData, orientation = 1) => {\n    if (orientation === 1) {\n        return imageData;\n    }\n    // correct image data for when the browser does not correctly read exif orientation headers\n    if (!(await canOrientImages())) {\n        return canvasToImageData(await imageDataToCanvas(imageData, orientation));\n    }\n    return imageData;\n};\n\nvar isObject = (v) => typeof v === 'object';\n\nconst copy = (val) => {\n    // don't clone html elements\n    if (val instanceof HTMLElement)\n        return val;\n    // clone objects\n    return isObject(val) ? deepCopy(val) : val;\n};\nconst deepCopy = (src) => {\n    let dst;\n    if (Array.isArray(src)) {\n        dst = [];\n        src.forEach((val, i) => {\n            dst[i] = copy(val);\n        });\n    }\n    else {\n        dst = {};\n        src !== null &&\n            Object.keys(src).forEach((key) => {\n                const val = src[key];\n                dst[key] = copy(val);\n            });\n    }\n    return dst;\n};\n\nvar isFunction = (v) => typeof v === 'function';\n\nvar imageToCanvas = (image, options) => {\n    const { width, height, canvasMemoryLimit, contextOptions } = options || {};\n    let canvasWidth = width || image.naturalWidth;\n    let canvasHeight = height || image.naturalHeight;\n    // if no width and no height use defaults\n    if (!canvasWidth && !canvasHeight) {\n        // if these are 0 it's possible that we're trying to convert an SVG that doesn't have width or height attributes\n        // https://bugzilla.mozilla.org/show_bug.cgi?id=1328124\n        canvasWidth = 300;\n        canvasHeight = 150;\n    }\n    // determine if requires more memory than limit, if so limit target size\n    const requiredCanvasMemory = canvasWidth * canvasHeight;\n    if (canvasMemoryLimit && requiredCanvasMemory > canvasMemoryLimit) {\n        const canvasScalar = Math.sqrt(canvasMemoryLimit) / Math.sqrt(requiredCanvasMemory);\n        canvasWidth = Math.floor(canvasWidth * canvasScalar);\n        canvasHeight = Math.floor(canvasHeight * canvasScalar);\n    }\n    // create new canvas element\n    const canvas = h('canvas');\n    canvas.width = canvasWidth;\n    canvas.height = canvasHeight;\n    const ctx = canvas.getContext('2d', contextOptions);\n    ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);\n    return canvas;\n};\n\n// turns image into canvas only after it's fully loaded\nvar imageToCanvasSafe = (image, options) => new Promise((resolve, reject) => {\n    const ready = () => resolve(imageToCanvas(image, options));\n    if (image.complete && image.width) {\n        // need to test for image.width, on ie11 it will be 0 for object urls\n        ready();\n    }\n    else {\n        image.onload = ready;\n        image.onerror = () => reject(new Error('Failed to load image'));\n    }\n});\n\nvar blobToCanvas = async (imageBlob, options) => {\n    const imageElement = h('img', {\n        src: URL.createObjectURL(imageBlob),\n    });\n    const canvas = await imageToCanvasSafe(imageElement, options);\n    URL.revokeObjectURL(imageElement.src);\n    return canvas;\n};\n\nvar canCreateImageBitmap = () => 'createImageBitmap' in window;\n\nvar canCreateOffscreenCanvas = () => 'OffscreenCanvas' in window;\n\nvar isSVGFile = (blob) => /svg/.test(blob.type);\n\nvar getUniqueId = () => Math.random().toString(36).substring(2, 9);\n\nvar functionToBlob = (fn) => new Blob(['(', typeof fn === 'function' ? fn.toString() : fn, ')()'], {\n    type: 'application/javascript',\n});\n\nconst wrapFunction = (fn) => `function () {self.onmessage = function (message) {(${fn.toString()}).apply(null, message.data.content.concat([function (err, response) {\n    response = response || {};\n    const transfer = 'data' in response ? [response.data.buffer] : 'width' in response ? [response] : [];\n    return self.postMessage({ id: message.data.id, content: response, error: err }, transfer);\n}]))}}`;\nconst workerPool = new Map();\nvar thread = (fn, args, transferList) => new Promise((resolve, reject) => {\n    const workerKey = fn.toString();\n    let pooledWorker = workerPool.get(workerKey);\n    if (!pooledWorker) {\n        // create worker for this function\n        const workerFn = wrapFunction(fn);\n        // create a new web worker\n        const url = URL.createObjectURL(functionToBlob(workerFn));\n        const messages = new Map();\n        const worker = new Worker(url);\n        // create a pooled worker, this object will contain the worker and active messages\n        pooledWorker = {\n            url,\n            worker,\n            messages,\n            terminationTimeout: undefined,\n            terminate: () => {\n                clearTimeout(pooledWorker.terminationTimeout);\n                pooledWorker.worker.terminate();\n                URL.revokeObjectURL(url);\n                workerPool.delete(workerKey);\n            },\n        };\n        // handle received messages\n        worker.onmessage = function (e) {\n            // should receive message id and message\n            const { id, content, error } = e.data;\n            // automatically clean up workers after half a second\n            clearTimeout(pooledWorker.terminationTimeout);\n            pooledWorker.terminationTimeout = setTimeout(() => {\n                if (messages.size > 0)\n                    return;\n                pooledWorker.terminate();\n            }, 500);\n            // message route no longer valid\n            if (!messages.has(id))\n                return;\n            // get related thread and resolve with returned content\n            const message = messages.get(id);\n            // remove thread from threads cache\n            messages.delete(id);\n            // resolve or reject message based on response from worker\n            error != null ? message.reject(error) : message.resolve(content);\n        };\n        // pool this worker\n        workerPool.set(workerKey, pooledWorker);\n    }\n    // we need a way to remember this message so we generate a unique id and use that as a key for this request, that way we can link the response back to request in the pooledWorker.onmessage handler\n    const messageId = getUniqueId();\n    pooledWorker.messages.set(messageId, { resolve, reject });\n    // use pooled worker and await response\n    pooledWorker.worker.postMessage({ id: messageId, content: args }, transferList);\n});\n\nlet result$b = null;\nvar isFirefox = () => {\n    if (result$b === null)\n        result$b = isUserAgent(/Firefox/);\n    return result$b;\n};\n\nconst mainThreadBlobToImageData = async (imageBlob, options) => {\n    // get options\n    const { canvasMemoryLimit, colorSpace } = options || {};\n    const canvas = await blobToCanvas(imageBlob, {\n        colorSpace,\n        canvasMemoryLimit,\n        contextOptions: { willReadFrequently: true, colorSpace },\n    });\n    const imageData = canvasToImageData(canvas, { colorSpace });\n    releaseCanvas(canvas);\n    return imageData;\n};\nvar blobToImageData = async (imageBlob, options) => {\n    // get options\n    const { canvasMemoryLimit, colorSpace } = options || {};\n    // so we deal with display-p3, or just srgb\n    const sanitizedColorSpace = /p3/i.test(colorSpace) ? 'display-p3' : 'srgb';\n    // somehow there's a weird issue with Android where when it uses offscreen canvas\n    // the imagedata gets \"lost\" when turning a canvas with that imagedata back into a blob\n    // for now we can circumvent the issue by creating the imagedata in the main thread\n    // if we do this on Firefox we get a black image so we exclude firefox on android\n    if (isAndroid() && !isFirefox()) {\n        return await mainThreadBlobToImageData(imageBlob, {\n            canvasMemoryLimit,\n            colorSpace: sanitizedColorSpace,\n        });\n    }\n    let imageData;\n    // if can use OffscreenCanvas let's go for it as it will mean we can run this operation on a separate thread\n    if (canCreateImageBitmap() && !isSVGFile(imageBlob) && canCreateOffscreenCanvas()) {\n        try {\n            imageData = await thread((file, canvasMemoryLimit, colorSpace, done) => {\n                createImageBitmap(file)\n                    .then((bitmap) => {\n                    let canvasWidth = bitmap.width;\n                    let canvasHeight = bitmap.height;\n                    // determine if requires more memory than limit, if so limit target size\n                    const requiredCanvasMemory = canvasWidth * canvasHeight;\n                    if (canvasMemoryLimit && requiredCanvasMemory > canvasMemoryLimit) {\n                        const canvasScalar = Math.sqrt(canvasMemoryLimit) / Math.sqrt(requiredCanvasMemory);\n                        canvasWidth = Math.floor(canvasWidth * canvasScalar);\n                        canvasHeight = Math.floor(canvasHeight * canvasScalar);\n                    }\n                    const canvas = new OffscreenCanvas(canvasWidth, canvasHeight);\n                    const ctx = canvas.getContext('2d', {\n                        // set color space\n                        colorSpace,\n                        // we're going to read from this canvas, don't hardware accelerate\n                        willReadFrequently: true,\n                    });\n                    ctx.drawImage(bitmap, 0, 0, canvasWidth, canvasHeight);\n                    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n                    done(null, imageData);\n                })\n                    .catch((err) => {\n                    // fail silently\n                    done(err);\n                });\n            }, [imageBlob, canvasMemoryLimit, sanitizedColorSpace]);\n        }\n        catch (err) {\n            // fails silently on purpose, we'll try to turn the blob into image data in the main thread\n            // console.error(err);\n        }\n    }\n    // use main thread to generate ImageData\n    if (!imageData || !imageData.width) {\n        return await mainThreadBlobToImageData(imageBlob, {\n            canvasMemoryLimit,\n            colorSpace: sanitizedColorSpace,\n        });\n    }\n    return imageData;\n};\n\nvar canvasToBlob = (canvas, mimeType = undefined, quality = undefined) => new Promise((resolve, reject) => {\n    try {\n        canvas.toBlob((blob) => {\n            if (!blob)\n                return reject(new Error('Failed to create blob'));\n            resolve(blob);\n        }, mimeType, quality);\n    }\n    catch (err) {\n        reject(err);\n    }\n});\n\nvar imageDataToBlob = async (imageData, mimeType, quality) => {\n    const canvas = await imageDataToCanvas(imageData);\n    const blob = await canvasToBlob(canvas, mimeType, quality);\n    releaseCanvas(canvas);\n    return blob;\n};\n\nconst mimeTypes = {\n    matroska: 'mkv',\n};\nvar getExtensionFromMimeType = (mimeType) => {\n    const ext = (mimeType.match(/\\/([a-z0-9]+)/) || [])[1];\n    if (/^x/.test(ext)) {\n        const [, post = ''] = mimeType.split('/x-');\n        return mimeTypes[post];\n    }\n    return ext;\n};\n\nvar getFilenameWithoutExtension = (name) => name.substring(0, name.lastIndexOf('.')) || name;\n\nvar getExtensionFromFilename = (filename) => filename.split('.').pop();\n\nconst ImageExtensionsRegex = /avif|bmp|gif|jpg|jpeg|jpe|jif|jfif|png|svg|tiff|webp/;\n/*\nSupport image mime types\n- image/webp\n- image/gif\n- image/avif\n- image/jpeg\n- image/png\n- image/bmp\n- image/svg+xml\n*/\nvar getMimeTypeFromExtension = (ext) => {\n    // empty string returned if extension not found\n    if (!ImageExtensionsRegex.test(ext))\n        return '';\n    // return MimeType for this extension\n    return 'image/' + (/jfif|jif|jpe|jpg/.test(ext) ? 'jpeg' : ext === 'svg' ? 'svg+xml' : ext);\n};\n\nvar getMimeTypeFromFilename = (name) => name && getMimeTypeFromExtension(getExtensionFromFilename(name).toLowerCase());\n\nvar matchFilenameToMimeType = (filename, mimeType) => {\n    // get the mime type that matches this extension\n    const fileMimeType = getMimeTypeFromFilename(filename);\n    // test if type already matches current mime type, no need to change name\n    if (fileMimeType === mimeType)\n        return filename;\n    // get the extension for this mimetype (gets all characters after the \"image/\" part)\n    // if mimeType doesn't yield an extension, use the fileMimeType\n    const targetMimeTypeExtension = getExtensionFromMimeType(mimeType) || fileMimeType;\n    return `${getFilenameWithoutExtension(filename)}.${targetMimeTypeExtension}`;\n};\n\nvar blobToFile = (blob, filename, mimetype) => {\n    const lastModified = new Date().getTime();\n    const blobHasMimeType = blob.type.length && !/null|text/.test(blob.type);\n    const blobMimeType = blobHasMimeType ? blob.type : mimetype;\n    const name = matchFilenameToMimeType(filename, blobMimeType);\n    try {\n        return new (getNativeAPIRef('File'))([blob], name, {\n            lastModified,\n            type: blobHasMimeType ? blob.type : blobMimeType,\n        });\n    }\n    catch (err) {\n        const file = blobHasMimeType ? blob.slice() : blob.slice(0, blob.size, blobMimeType);\n        file.lastModified = lastModified;\n        file.name = name;\n        return file;\n    }\n};\n\nvar getAspectRatio = (w, h) => w / h;\n\nvar passthrough = (v) => (v);\n\nconst PI = Math.PI;\nconst HALF_PI = Math.PI / 2;\nconst QUART_PI = HALF_PI / 2;\n\nvar isRotatedSideways = (a) => {\n    const rotationLimited = Math.abs(a) % Math.PI;\n    return rotationLimited > QUART_PI && rotationLimited < Math.PI - QUART_PI;\n};\n\n// enum Direction {\n//     Top = 't',\n//     Right = 'r',\n//     Bottom = 'b',\n//     Left = 'l',\n//     TopLeft = 'tl',\n//     TopRight = 'tr',\n//     BottomRight = 'br',\n//     BottomLeft = 'bl',\n// }\n// export const { Top, Right, Bottom, Left, TopLeft, TopRight, BottomRight, BottomLeft } = Direction;\n// export default Direction;\nconst Direction = {\n    Top: 't',\n    Right: 'r',\n    Bottom: 'b',\n    Left: 'l',\n    TopLeft: 'tl',\n    TopRight: 'tr',\n    BottomRight: 'br',\n    BottomLeft: 'bl',\n};\nconst { Top, Right, Bottom, Left, TopLeft, TopRight, BottomRight, BottomLeft } = Direction;\n\nvar DirectionCoordinateTable = {\n    [Top]: [0.5, 0],\n    [Right]: [1, 0.5],\n    [Bottom]: [0.5, 1],\n    [Left]: [0, 0.5],\n    [TopLeft]: [0, 0],\n    [TopRight]: [1, 0],\n    [BottomRight]: [1, 1],\n    [BottomLeft]: [0, 1],\n};\n\nvar fixPrecision = (value, precision = 12) => parseFloat(value.toFixed(precision));\n\n//\n// generic\n//\nconst scale = (value, scalar, pivot) => pivot + (value - pivot) * scalar;\nconst ellipseCreateFromRect = (rect) => ({\n    x: rect.x + rect.width * 0.5,\n    y: rect.y + rect.height * 0.5,\n    rx: rect.width * 0.5,\n    ry: rect.height * 0.5,\n});\n//\n// vector\n//\nconst vectorCreateEmpty = () => vectorCreate(0, 0);\nconst vectorCreate = (x, y) => ({ x, y });\nconst vectorCreateFromSize = (size) => vectorCreate(size.width, size.height);\nconst vectorCreateFromAny = (obj) => vectorCreate(obj.x, obj.y);\nconst vectorCreateFromPointerEvent = (e) => vectorCreate(e.pageX, e.pageY);\nconst vectorCreateFromPointerEventOffset = (e) => vectorCreate(e.offsetX, e.offsetY);\nconst vectorClone = (v) => vectorCreate(v.x, v.y);\nconst vectorUpdate = (v, x, y) => {\n    v.x = x;\n    v.y = y;\n    return v;\n};\nconst vectorInvert = (v) => {\n    v.x = -v.x;\n    v.y = -v.y;\n    return v;\n};\nconst vectorPerpendicular = (v) => {\n    const x = v.x;\n    v.x = -v.y;\n    v.y = x;\n    return v;\n};\nconst vectorRotate = (v, radians, pivot = vectorCreateEmpty()) => {\n    const cos = Math.cos(radians);\n    const sin = Math.sin(radians);\n    const tx = v.x - pivot.x;\n    const ty = v.y - pivot.y;\n    v.x = pivot.x + cos * tx - sin * ty;\n    v.y = pivot.y + sin * tx + cos * ty;\n    return v;\n};\nconst vectorLength = (v) => Math.sqrt(v.x * v.x + v.y * v.y);\nconst vectorNormalize = (v) => {\n    const length = Math.sqrt(v.x * v.x + v.y * v.y);\n    if (length === 0)\n        return vectorCreateEmpty();\n    v.x /= length;\n    v.y /= length;\n    return v;\n};\nconst vectorAngle = (v) => Math.atan2(v.y, v.x);\nconst vectorAngleBetween = (a, b) => Math.atan2(b.y - a.y, b.x - a.x);\nconst vectorEqual = (a, b) => a.x === b.x && a.y === b.y;\nconst vectorApply = (v, fn) => {\n    v.x = fn(v.x);\n    v.y = fn(v.y);\n    return v;\n};\nconst vectorInSize = (v, size) => {\n    return v.x >= 0 && v.y >= 0 && v.x <= size.width && v.y <= size.height;\n};\nconst vectorAdd = (a, b) => {\n    a.x += b.x;\n    a.y += b.y;\n    return a;\n};\nconst vectorSubtract = (a, b) => {\n    a.x -= b.x;\n    a.y -= b.y;\n    return a;\n};\nconst vectorDivide = (v, l) => {\n    v.x /= l;\n    v.y /= l;\n    return v;\n};\nconst vectorMultiply = (v, f) => {\n    v.x *= f;\n    v.y *= f;\n    return v;\n};\nconst vectorDot = (a, b) => a.x * b.x + a.y * b.y;\nconst vectorCross = (a, b) => a.x * b.y - a.y * b.x;\nconst vectorDistanceSquared = (a, b = vectorCreateEmpty()) => {\n    const x = a.x - b.x;\n    const y = a.y - b.y;\n    return x * x + y * y;\n};\nconst vectorDistance = (a, b = vectorCreateEmpty()) => Math.sqrt(vectorDistanceSquared(a, b));\nconst vectorScale = (v, scalar, pivot) => {\n    v.x = scale(v.x, scalar, pivot.x);\n    v.y = scale(v.y, scalar, pivot.y);\n    return v;\n};\nconst vectorCenter = (v) => {\n    let x = 0;\n    let y = 0;\n    v.forEach((v) => {\n        x += v.x;\n        y += v.y;\n    });\n    return vectorCreate(x / v.length, y / v.length);\n};\nconst vectorsFlip = (points, flipX, flipY, cx, cy) => {\n    points.forEach((point) => {\n        point.x = flipX ? cx - (point.x - cx) : point.x;\n        point.y = flipY ? cy - (point.y - cy) : point.y;\n    });\n    return points;\n};\nconst vectorsRotate = (points, angle, cx, cy) => {\n    const s = Math.sin(angle);\n    const c = Math.cos(angle);\n    points.forEach((p) => {\n        p.x -= cx;\n        p.y -= cy;\n        const rx = p.x * c - p.y * s;\n        const ry = p.x * s + p.y * c;\n        p.x = cx + rx;\n        p.y = cy + ry;\n    });\n    return points;\n};\n//\n// size\n//\nconst toSize = (width, height) => ({ width, height });\nconst sizeClone = (size) => toSize(size.width, size.height);\nconst sizeCreateFromAny = (obj) => toSize(obj.width, obj.height);\nconst sizeCreateFromRect = (r) => toSize(r.width, r.height);\nconst sizeCreateFromArray = (a) => toSize(a[0], a[1]);\nconst sizeCreateFromImageNaturalSize = (image) => {\n    // this fixes issues with dimensionless SVGs on Firefox\n    if (!image.naturalWidth && !image.naturalHeight) {\n        return {\n            width: 300,\n            height: 150,\n        };\n    }\n    return toSize(image.naturalWidth, image.naturalHeight);\n};\nconst sizeCreateFromElement = (element) => {\n    if (/img/i.test(element.nodeName)) {\n        return sizeCreateFromImageNaturalSize(element);\n    }\n    return sizeCreateFromAny(element);\n};\nconst sizeCreate = (width, height) => toSize(width, height);\nconst sizeEqual = (a, b, format = passthrough) => format(a.width) === format(b.width) && format(a.height) === format(b.height);\nconst sizeScale = (size, scalar) => {\n    size.width *= scalar;\n    size.height *= scalar;\n    return size;\n};\nconst sizeCenter = (size) => vectorCreate(size.width * 0.5, size.height * 0.5);\nconst sizeRotate = (size, radians) => {\n    const r = Math.abs(radians);\n    const cos = Math.abs(Math.cos(r));\n    const sin = Math.abs(Math.sin(r));\n    const w = cos * size.width + sin * size.height;\n    const h = sin * size.width + cos * size.height;\n    size.width = w;\n    size.height = h;\n    return size;\n};\nconst sizeTurn = (size, radians) => {\n    const w = size.width;\n    const h = size.height;\n    if (isRotatedSideways(radians)) {\n        size.width = h;\n        size.height = w;\n    }\n    return size;\n};\nconst sizeContains = (a, b) => a.width >= b.width && a.height >= b.height;\nconst sizeApply = (size, fn) => {\n    size.width = fn(size.width);\n    size.height = fn(size.height);\n    return size;\n};\nconst sizeHypotenuse = (size) => Math.sqrt(size.width * size.width + size.height * size.height);\nconst sizeMin = (a, b) => sizeCreate(Math.min(a.width, b.width), Math.min(a.height, b.height));\n//\n// line\n//\nconst lineCreate = (start, end) => ({ start, end });\nconst lineClone = (line) => lineCreate(vectorClone(line.start), vectorClone(line.end));\nconst lineExtend = (line, amount) => {\n    if (amount === 0)\n        return line;\n    const v = vectorCreate(line.start.x - line.end.x, line.start.y - line.end.y);\n    const n = vectorNormalize(v);\n    const m = vectorMultiply(n, amount);\n    line.start.x += m.x;\n    line.start.y += m.y;\n    line.end.x -= m.x;\n    line.end.y -= m.y;\n    return line;\n};\nconst lineMultiply = (line, amount) => {\n    if (amount === 0)\n        return line;\n    const v = vectorCreate(line.start.x - line.end.x, line.start.y - line.end.y);\n    const n = vectorNormalize(v);\n    const m = vectorMultiply(n, amount);\n    line.end.x += m.x;\n    line.end.y += m.y;\n    return line;\n};\nconst lineExtrude = ({ start, end }, amount) => {\n    if (amount === 0)\n        return [\n            vectorCreate(start.x, start.y),\n            vectorCreate(start.x, start.y),\n            vectorCreate(end.x, end.y),\n            vectorCreate(end.x, end.y),\n        ];\n    const a = Math.atan2(end.y - start.y, end.x - start.x);\n    const sina = Math.sin(a) * amount;\n    const cosa = Math.cos(a) * amount;\n    return [\n        vectorCreate(sina + start.x, -cosa + start.y),\n        vectorCreate(-sina + start.x, cosa + start.y),\n        vectorCreate(-sina + end.x, cosa + end.y),\n        vectorCreate(sina + end.x, -cosa + end.y),\n    ];\n};\n//\n// rect\n//\nconst CornerSigns = [\n    vectorCreate(-1, -1),\n    vectorCreate(-1, 1),\n    vectorCreate(1, 1),\n    vectorCreate(1, -1),\n];\nconst toRect = (x, y, width, height) => ({\n    x,\n    y,\n    width,\n    height,\n});\nconst rectClone = (rect) => toRect(rect.x, rect.y, rect.width, rect.height);\nconst rectCreateEmpty = () => toRect(0, 0, 0, 0);\nconst rectCreateFromDimensions = (width, height) => toRect(0, 0, width, height);\nconst rectCreateFromSize = (size) => toRect(0, 0, size.width, size.height);\nconst rectCreateFromBounds = (bounds) => toRect(bounds[3], bounds[0], bounds[1] - bounds[3], bounds[2] - bounds[0]);\nconst rectCreateFromAny = (obj) => toRect(obj.x || 0, obj.y || 0, obj.width || 0, obj.height || 0);\nconst rectCreateFromPoints = (points) => {\n    let xMin = points[0].x;\n    let xMax = points[0].x;\n    let yMin = points[0].y;\n    let yMax = points[0].y;\n    points.forEach((point) => {\n        xMin = Math.min(xMin, point.x);\n        xMax = Math.max(xMax, point.x);\n        yMin = Math.min(yMin, point.y);\n        yMax = Math.max(yMax, point.y);\n    });\n    return toRect(xMin, yMin, xMax - xMin, yMax - yMin);\n};\nconst rectCreateFromEllipse = (ellipse) => rectCreate(ellipse.x - ellipse.rx, ellipse.y - ellipse.ry, ellipse.rx * 2, ellipse.ry * 2);\nconst rectCreateWithCenter = (center, size) => toRect(center.x - size.width * 0.5, center.y - size.height * 0.5, size.width, size.height);\nconst rectCreate = (x, y, width, height) => toRect(x, y, width, height);\nconst rectCenter = (rect) => vectorCreate(rect.x + rect.width * 0.5, rect.y + rect.height * 0.5);\nconst rectTranslate = (rect, t) => {\n    rect.x += t.x;\n    rect.y += t.y;\n    return rect;\n};\nconst rectScale = (rect, scalar, pivot) => {\n    pivot = pivot || rectCenter(rect);\n    rect.x = scalar * (rect.x - pivot.x) + pivot.x;\n    rect.y = scalar * (rect.y - pivot.y) + pivot.y;\n    rect.width = scalar * rect.width;\n    rect.height = scalar * rect.height;\n    return rect;\n};\nconst rectClamp = (rect, sizeMin, sizeMax, pivot) => {\n    const x = (pivot.x - rect.x) / rect.width;\n    const y = (pivot.y - rect.y) / rect.height;\n    let width = Math.max(sizeMin.width, rect.width);\n    let height = Math.max(sizeMin.height, rect.height);\n    width = Math.min(sizeMax.width, width);\n    height = Math.min(sizeMax.height, height);\n    rect.x = pivot.x - x * width;\n    rect.y = pivot.y - y * height;\n    rect.width = width;\n    rect.height = height;\n    return rect;\n};\nconst rectGetCornerByTarget = (rect, target) => {\n    const [xf, yf] = DirectionCoordinateTable[target];\n    const x = xf * rect.width;\n    const y = yf * rect.height;\n    return vectorCreate(rect.x + x, rect.y + y);\n};\nconst rectMultiply = (rect, factor) => {\n    rect.x *= factor;\n    rect.y *= factor;\n    rect.width *= factor;\n    rect.height *= factor;\n    return rect;\n};\nconst rectDivide = (rect, factor) => {\n    rect.x /= factor;\n    rect.y /= factor;\n    rect.width /= factor;\n    rect.height /= factor;\n    return rect;\n};\nconst rectSubtract = (a, b) => {\n    a.x -= b.x;\n    a.y -= b.y;\n    a.width -= b.width;\n    a.height -= b.height;\n    return a;\n};\nconst rectAdd = (a, b) => {\n    a.x += b.x;\n    a.y += b.y;\n    a.width += b.width;\n    a.height += b.height;\n    return a;\n};\nconst rectEqual = (a, b, format = passthrough) => format(a.x) === format(b.x) &&\n    format(a.y) === format(b.y) &&\n    format(a.width) === format(b.width) &&\n    format(a.height) === format(b.height);\nconst rectAspectRatio = (rect) => getAspectRatio(rect.width, rect.height);\nconst rectUpdate = (rect, x, y, width, height) => {\n    rect.x = x;\n    rect.y = y;\n    rect.width = width;\n    rect.height = height;\n    return rect;\n};\nconst rectUpdateWithRect = (a, b) => {\n    a.x = b.x;\n    a.y = b.y;\n    a.width = b.width;\n    a.height = b.height;\n    return a;\n};\nconst rectRotate = (rect, radians, pivot) => {\n    if (!pivot)\n        pivot = rectCenter(rect);\n    return rectGetCorners(rect).map((vertex) => vectorRotate(vertex, radians, pivot));\n};\nconst rectCenterRect = (a, b) => toRect(a.width * 0.5 - b.width * 0.5, a.height * 0.5 - b.height * 0.5, b.width, b.height);\nconst rectContainsPoint = (rect, point) => {\n    if (point.x < rect.x)\n        return false;\n    if (point.y < rect.y)\n        return false;\n    if (point.x > rect.x + rect.width)\n        return false;\n    if (point.y > rect.y + rect.height)\n        return false;\n    return true;\n};\nconst rectCoverRect = (rect, aspectRatio, offset = vectorCreateEmpty()) => {\n    if (rect.width === 0 || rect.height === 0)\n        return rectCreateEmpty();\n    const inputAspectRatio = rectAspectRatio(rect);\n    if (!aspectRatio)\n        aspectRatio = inputAspectRatio;\n    let width = rect.width;\n    let height = rect.height;\n    if (aspectRatio > inputAspectRatio) {\n        // height remains the same, width is expanded\n        width = height * aspectRatio;\n    }\n    else {\n        // width remains the same, height is expanded\n        height = width / aspectRatio;\n    }\n    return toRect(offset.x + (rect.width - width) * 0.5, offset.y + (rect.height - height) * 0.5, width, height);\n};\nconst rectLimitInRect = (childRect, parentRect, aspectRatio) => {\n    const [t, r, b, l] = rectToBounds(childRect);\n    const rectOrigin = { ...childRect };\n    if (t < parentRect.y) {\n        childRect.height = childRect.height - (parentRect.y - t);\n        childRect.y = parentRect.y;\n    }\n    if (r > parentRect.x + parentRect.width) {\n        childRect.width = parentRect.x + parentRect.width - childRect.x;\n    }\n    if (b > parentRect.y + parentRect.height) {\n        childRect.height = parentRect.y + parentRect.height - childRect.y;\n    }\n    if (l < parentRect.x) {\n        childRect.width = childRect.width - (parentRect.x - l);\n        childRect.x = parentRect.x;\n    }\n    if (aspectRatio) {\n        // scalar\n        const scalar = Math.min(1, rectOrigin.width / childRect.width, rectOrigin.height / childRect.height);\n        return rectMultiply(rectOrigin, scalar);\n    }\n    return childRect;\n};\nconst rectOffsetInRect = (childRect, parentRect) => {\n    const [t, r, b, l] = rectToBounds(childRect);\n    if (t < parentRect.y)\n        childRect.y = Math.max(parentRect.y, childRect.y);\n    if (r > parentRect.width)\n        childRect.x = parentRect.width - childRect.width;\n    if (b > parentRect.height)\n        childRect.y = parentRect.height - childRect.height;\n    if (l < parentRect.x)\n        childRect.x = Math.max(parentRect.x, childRect.x);\n    return childRect;\n};\nconst rectContainRect = (rect, aspectRatio = rectAspectRatio(rect), offset = vectorCreateEmpty()) => {\n    if (rect.width === 0 || rect.height === 0)\n        return rectCreateEmpty();\n    let width = rect.width;\n    let height = width / aspectRatio;\n    if (height > rect.height) {\n        height = rect.height;\n        width = height * aspectRatio;\n    }\n    return toRect(offset.x + (rect.width - width) * 0.5, offset.y + (rect.height - height) * 0.5, width, height);\n};\nconst rectToBounds = (rect) => [\n    Math.min(rect.y, rect.y + rect.height), // top\n    Math.max(rect.x, rect.x + rect.width), // right\n    Math.max(rect.y, rect.y + rect.height), // bottom\n    Math.min(rect.x, rect.x + rect.width), // left\n];\nconst rectGetCorners = (rect) => [\n    vectorCreate(rect.x, rect.y),\n    vectorCreate(rect.x + rect.width, rect.y),\n    vectorCreate(rect.x + rect.width, rect.y + rect.height),\n    vectorCreate(rect.x, rect.y + rect.height),\n];\nconst rectApply = (rect, fn) => {\n    if (!rect)\n        return;\n    rect.x = fn(rect.x);\n    rect.y = fn(rect.y);\n    rect.width = fn(rect.width);\n    rect.height = fn(rect.height);\n    return rect;\n};\nconst rectApplyPerspective = (rect, perspective, pivot = rectCenter(rect)) => rectGetCorners(rect).map((corner, index) => {\n    const sign = CornerSigns[index];\n    return vectorCreate(scale(corner.x, 1.0 + sign.x * perspective.x, pivot.x), scale(corner.y, 1.0 + sign.y * perspective.y, pivot.y));\n});\nconst rectNormalizeOffset = (rect) => {\n    rect.x = 0;\n    rect.y = 0;\n    return rect;\n};\nconst convexPolyCentroid = (vertices) => {\n    const first = vertices[0];\n    const last = vertices[vertices.length - 1];\n    // make sure is closed loop\n    vertices = vectorEqual(first, last) ? vertices : [...vertices, first];\n    const fx = first.x;\n    const fy = first.y;\n    let twiceArea = 0;\n    let i = 0;\n    let x = 0;\n    let y = 0;\n    let a;\n    let b;\n    let f;\n    const l = vertices.length;\n    for (; i < l; i++) {\n        // current vertex\n        a = vertices[i];\n        // next vertex\n        b = vertices[i + 1 > l - 1 ? 0 : i + 1];\n        f = (a.y - fy) * (b.x - fx) - (b.y - fy) * (a.x - fx);\n        twiceArea += f;\n        x += (a.x + b.x - 2 * fx) * f;\n        y += (a.y + b.y - 2 * fy) * f;\n    }\n    f = twiceArea * 3;\n    return vectorCreate(fx + x / f, fy + y / f);\n};\nconst lineLineIntersection = (a, b) => getLineLineIntersectionPoint(a.start, a.end, b.start, b.end);\nconst getLineLineIntersectionPoint = (a, b, c, d) => {\n    const denominator = (d.y - c.y) * (b.x - a.x) - (d.x - c.x) * (b.y - a.y);\n    // lines are parallel\n    if (denominator === 0)\n        return undefined;\n    const uA = ((d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x)) / denominator;\n    const uB = ((b.x - a.x) * (a.y - c.y) - (b.y - a.y) * (a.x - c.x)) / denominator;\n    // intersection is not on the line itself\n    if (uA < 0 || uA > 1 || uB < 0 || uB > 1)\n        return undefined;\n    // return intersection point\n    return vectorCreate(a.x + uA * (b.x - a.x), a.y + uA * (b.y - a.y));\n};\n// checks if line intersects with one of the lines that can be drawn between the points (in sequence)\nconst linePointsIntersection = (line, points, { ignoreIdenticalLines = false, breakOnIntersection = false } = {}) => {\n    const l = points.length;\n    const intersections = [];\n    for (let i = 0; i < l - 1; i++) {\n        if (ignoreIdenticalLines &&\n            (vectorEqual(line.start, points[i]) ||\n                vectorEqual(line.start, points[i + 1]) ||\n                vectorEqual(line.end, points[i]) ||\n                vectorEqual(line.end, points[i + 1])))\n            continue;\n        const intersection = getLineLineIntersectionPoint(line.start, line.end, points[i], points[i + 1]);\n        if (!intersection)\n            continue;\n        if (breakOnIntersection)\n            return [intersection];\n        intersections.push(intersection);\n    }\n    return intersections.length ? intersections : undefined;\n};\nconst pointInPoly$1 = (point, vertices) => {\n    let i = 0;\n    let j = 0;\n    let c = false;\n    const l = vertices.length;\n    for (i = 0, j = l - 1; i < l; j = i++) {\n        if (vertices[i].y > point.y != vertices[j].y > point.y &&\n            point.x <\n                ((vertices[j].x - vertices[i].x) * (point.y - vertices[i].y)) /\n                    (vertices[j].y - vertices[i].y) +\n                    vertices[i].x) {\n            c = !c;\n        }\n    }\n    return c;\n};\nconst getControlPoint = (p1, p2, p3, scale) => {\n    let dx = (p2.x - p1.x) * scale;\n    let dy = (p2.y - p1.y) * scale;\n    if (vectorDistance(p3, p2) < vectorDistance(p2, p1)) {\n        dx *= 0.15;\n        dy *= 0.15;\n    }\n    return {\n        x: p2.x + dx,\n        y: p2.y + dy,\n    };\n};\nconst bezier = (p1, c, p2, t) => {\n    const x = (1 - t) * (1 - t) * p1.x + 2 * (1 - t) * t * c.x + t * t * p2.x;\n    const y = (1 - t) * (1 - t) * p1.y + 2 * (1 - t) * t * c.y + t * t * p2.y;\n    return { x, y };\n};\nconst pointsInterpolate = (p1, p2, p3, numPoints, controlPointScale) => {\n    const controlPoint = getControlPoint(p1, p2, p3, controlPointScale);\n    const points = [];\n    for (let i = 0; i <= numPoints; i++) {\n        const t = i / numPoints;\n        points.push(bezier(p2, controlPoint, p3, t));\n    }\n    return points;\n};\n// first tests if points of a are to be found in b, then does the reverse\nconst polyIntersectsWithPoly = (a, b) => {\n    const bContainsCornerOfA = a.find((corner) => pointInPoly$1(corner, b));\n    if (bContainsCornerOfA)\n        return true;\n    const aContainsCornerOfB = b.find((corner) => pointInPoly$1(corner, a));\n    if (aContainsCornerOfB)\n        return true;\n    return false;\n};\nconst quadLines = (vertices) => {\n    const arr = [];\n    for (let i = 0; i < vertices.length; i++) {\n        let next = i + 1;\n        if (next === vertices.length)\n            next = 0;\n        arr.push(lineCreate(vectorClone(vertices[i]), vectorClone(vertices[next])));\n    }\n    return arr;\n};\nconst quadToLines = (vertices, extension = 0) => quadLines(vertices)\n    // extend the poly lines a tiny bit so we\n    // don't shoot rays between line gaps at corners\n    // this caused one intersection to be missing resulting\n    // in error while manipulating crop edges\n    // (rotate image 90degrees -> drag bottom edge) (2021-04-09)\n    .map((line) => lineExtend(line, extension));\nconst ellipseToPolygon = (center, rx, ry, rotation = 0, flipX = false, flipY = false, resolution = 12) => {\n    const points = [];\n    for (let i = 0; i < resolution; i++) {\n        points.push(vectorCreate(center.x + rx * Math.cos((i * (Math.PI * 2)) / resolution), center.y + ry * Math.sin((i * (Math.PI * 2)) / resolution)));\n    }\n    if (flipX || flipY)\n        vectorsFlip(points, flipX, flipY, center.x, center.y);\n    if (rotation)\n        vectorsRotate(points, rotation, center.x, center.y);\n    return points;\n};\nconst polyToBounds = (poly) => poly.reduce(([top, right, bottom, left], { x, y }) => {\n    left = Math.min(left, x);\n    right = Math.max(right, x);\n    top = Math.min(top, y);\n    bottom = Math.max(bottom, y);\n    return [top, right, bottom, left];\n}, [Infinity, -Infinity, -Infinity, Infinity]);\n// markup editor shape helpers\nconst circleOverlapsWithLine = (point, radius, from, to) => {\n    const ac = vectorCreate(point.x - from.x, point.y - from.y);\n    const ab = vectorCreate(to.x - from.x, to.y - from.y);\n    const ab2 = vectorDot(ab, ab);\n    const acab = vectorDot(ac, ab);\n    let t = acab / ab2;\n    t = t < 0 ? 0 : t;\n    t = t > 1 ? 1 : t;\n    const h = vectorCreate(ab.x * t + from.x - point.x, ab.y * t + from.y - point.y);\n    const h2 = vectorDot(h, h);\n    return h2 <= radius * radius;\n};\nconst circleOverlapsWithPath = (position, radius, points) => {\n    const l = points.length;\n    for (let i = 0; i < l - 1; i++) {\n        if (circleOverlapsWithLine(position, radius, points[i], points[i + 1]))\n            return true;\n    }\n    return false;\n};\nconst circleOverlapsWithPolygon = (position, radius, points) => {\n    if (pointInPoly$1(position, points))\n        return true;\n    if (circleOverlapsWithPath(position, radius, points))\n        return true;\n    return circleOverlapsWithLine(position, radius, points[0], points[points.length - 1]);\n};\nconst circleOverlapsWithEllipse = (position, radius, ellipse, rotation, flipX, flipY) => {\n    const points = ellipseToPolygon(vectorCreate(ellipse.x, ellipse.y), ellipse.rx, ellipse.ry, rotation, flipX, flipY, 12);\n    return circleOverlapsWithPolygon(position, radius, points);\n};\nconst circleOverlapsWithRect = (position, radius, rect, rotation, pivot) => circleOverlapsWithPolygon(position, radius, rectRotate(rect, rotation, pivot || rectCenter(rect)));\n\nvar getImageTransformedRect = (imageSize, imageRotation) => {\n    const imageRect = rectCreateFromSize(imageSize);\n    const imageCenter = rectCenter(imageRect);\n    const imageTransformedVertices = rectRotate(imageRect, imageRotation, imageCenter);\n    return rectNormalizeOffset(rectCreateFromPoints(imageTransformedVertices));\n};\n\nvar isElement = (v, name) => v instanceof HTMLElement && (name ? new RegExp(`^${name}$`, 'i').test(v.nodeName) : true);\n\nvar isFile = (v) => v instanceof File;\n\nvar canvasToFile = async (canvas, mimeType, quality) => {\n    const blob = await canvasToBlob(canvas, mimeType, quality);\n    return blobToFile(blob, 'canvas');\n};\n\nvar getFilenameFromURL = (url) => url\n    .split('/')\n    .pop()\n    .split(/\\?|\\#/)\n    .shift();\n\n// @ts-ignore\nconst supportsReplaceChildren = isBrowser() && !!Node.prototype.replaceChildren;\nconst fn$1 = supportsReplaceChildren\n    ? // @ts-ignore\n        (parent, newChildren) => parent.replaceChildren(newChildren)\n    : (parent, newChildren) => {\n        while (parent.lastChild) {\n            parent.removeChild(parent.lastChild);\n        }\n        if (newChildren !== undefined) {\n            parent.append(newChildren);\n        }\n    };\n\nconst container = isBrowser() &&\n    h('div', {\n        class: 'PinturaMeasure',\n        style: 'position:absolute;left:0;top:0;width:99999px;height:0;pointer-events:none;contain:strict;margin:0;padding:0;',\n    });\nlet timeoutId;\nvar appendForMeasuring = (element) => {\n    // replace element children with this child\n    fn$1(container, element);\n    // append to DOM if not in it atm\n    if (!container.parentNode)\n        document.body.append(container);\n    // auto detach from DOM after it isn't used for a little while\n    clearTimeout(timeoutId);\n    timeoutId = setTimeout(() => {\n        container.remove();\n    }, 500);\n    // return added element for measuring\n    return element;\n};\n\nlet result$a = null;\nvar isSafari = () => {\n    if (result$a === null)\n        result$a =\n            isBrowser() && /^((?!chrome|android).)*(safari|iphone|ipad)/i.test(navigator.userAgent); // added |iphone|ipad as safari is not present in WebView on React Native\n    return result$a;\n};\n\nvar getImageElementSize = (imageElement) => new Promise((resolve, reject) => {\n    let shouldAutoRemove = false;\n    // test if image is attached to DOM, if not attached, attach so measurement is correct on Safari\n    if (!imageElement.parentNode && isSafari()) {\n        shouldAutoRemove = true;\n        // has width 0 and height 0 to prevent rendering very big SVGs (without width and height) that will for one frame overflow the window and show a scrollbar\n        imageElement.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;left:0;top:0;width:0;height:0;`;\n        appendForMeasuring(imageElement);\n    }\n    // we don't use imageElement.complete as that is also true for error states\n    let didLoad = false;\n    // start testing size\n    const measure = () => {\n        let width = imageElement.naturalWidth;\n        let height = imageElement.naturalHeight;\n        const hasSize = width && height;\n        // still waiting for size\n        if (!hasSize) {\n            // still measuring\n            if (!didLoad) {\n                return;\n            }\n            // load fired and we still don't have a width & height\n            // let's fallback to 300x150 (this is to fix issue where firefox doesn't assign a default size to svg without a width & height)\n            width = 300;\n            height = 150;\n        }\n        // clear load handler\n        delete imageElement.onload;\n        // clean up image if was attached for measuring\n        if (shouldAutoRemove) {\n            imageElement.remove();\n        }\n        clearInterval(intervalId);\n        resolve({ width, height });\n    };\n    imageElement.onerror = (err) => {\n        clearInterval(intervalId);\n        reject(err);\n    };\n    imageElement.onload = () => {\n        didLoad = true;\n        // stop measuring\n        clearInterval(intervalId);\n        // so we can re-use measure logic\n        measure();\n    };\n    const intervalId = setInterval(measure, 1);\n    measure();\n});\n\nvar getVideoElementSize = (element) => new Promise((resolve, reject) => {\n    const done = () => {\n        resolve({\n            width: element.videoWidth,\n            height: element.videoHeight,\n        });\n    };\n    if (element.readyState >= 1)\n        return done();\n    element.onloadedmetadata = done;\n    element.onerror = () => reject(element.error);\n});\n\nvar isImage = (file) => /^image/.test(file.type);\n\nvar getAsVideoOrImageElement = (src) => new Promise((resolve) => {\n    // undetermined or is video\n    const elementSrc = (isString(src) ? src : URL.createObjectURL(src));\n    const createImage = () => {\n        const image = new Image();\n        image.src = elementSrc;\n        resolve(image);\n    };\n    // we can already know it's an image\n    if (src instanceof Blob && isImage(src))\n        return createImage();\n    // try video first\n    const element = document.createElement('video');\n    element.preload = 'metadata';\n    element.onloadedmetadata = () => resolve(element);\n    // when errors we switch to image\n    element.onerror = createImage;\n    element.src = elementSrc;\n});\n\nvar isVideoElement = (element) => element.nodeName === 'VIDEO';\n\n// TODO: video rename function\nvar getImageSize = async (src) => {\n    // the image element we'll use to load the image\n    let mediaElement;\n    // if is not an image or video element, it must be a valid image or video source\n    if (!src['src']) {\n        mediaElement = await getAsVideoOrImageElement(src);\n    }\n    else {\n        mediaElement = src;\n    }\n    let size;\n    try {\n        size = isVideoElement(mediaElement)\n            ? await getVideoElementSize(mediaElement)\n            : await getImageElementSize(mediaElement);\n    }\n    finally {\n        isFile(src) && URL.revokeObjectURL(mediaElement.src);\n    }\n    return size;\n};\n\nconst awaitComplete = (image) => new Promise((resolve, reject) => {\n    if (image.complete)\n        return resolve(image);\n    image.onload = () => resolve(image);\n    image.onerror = () => reject(new Error('Failed to load image'));\n});\nvar imageToFile = async (imageElement) => {\n    const size = await getImageSize(imageElement);\n    const image = await awaitComplete(imageElement);\n    const canvas = h('canvas', size);\n    const ctx = canvas.getContext('2d', { willReadFrequently: true });\n    ctx.drawImage(image, 0, 0);\n    const blob = await canvasToBlob(canvas);\n    return blobToFile(blob, getFilenameFromURL(image.src));\n};\n\nvar isDataURI = (str) => /^data:/.test(str);\n\nvar createProgressEvent = (loaded = 0, lengthComputable = true) => new (getNativeAPIRef('ProgressEvent'))('progress', {\n    loaded: loaded * 100,\n    total: 100,\n    lengthComputable,\n});\n\nvar dataURIToFile = async (dataURI, filename = 'data-uri', onprogress = noop$1) => {\n    // basic loader, no size info\n    onprogress(createProgressEvent(0));\n    const res = await fetch(dataURI);\n    onprogress(createProgressEvent(0.33));\n    const blob = await res.blob();\n    let mimeType;\n    if (!isImage(blob))\n        mimeType = `image/${dataURI.includes(',/9j/') ? 'jpeg' : 'png'}`;\n    onprogress(createProgressEvent(0.66));\n    const file = blobToFile(blob, filename, mimeType);\n    onprogress(createProgressEvent(1));\n    return file;\n};\n\nvar getResponseHeader = (xhr, header, parse = (header) => header) => xhr.getAllResponseHeaders().indexOf(header) >= 0\n    ? parse(xhr.getResponseHeader(header))\n    : undefined;\n\nvar getFilenameFromContentDisposition = (header) => {\n    if (!header)\n        return null;\n    const matches = header.split(/filename=|filename\\*=.+''/)\n        .splice(1)\n        .map(name => name.trim().replace(/^[\"']|[;\"']{0,2}$/g, ''))\n        .filter(name => name.length);\n    return matches.length ? decodeURI(matches[matches.length - 1]) : null;\n};\n\nconst EditorErrorCode = {\n    URL_REQUEST: 'URL_REQUEST',\n    DOCTYPE_MISSING: 'DOCTYPE_MISSING',\n};\nclass EditorError extends Error {\n    constructor(message, code, metadata) {\n        super(message);\n        this.name = 'EditorError';\n        this.code = code;\n        this.metadata = metadata;\n    }\n}\n\n// should be called after xhr.open\nvar configureXHR = (xhr, options) => {\n    // https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters\n    // only handles headers and credentials for now\n    const { headers = {}, credentials } = options || {};\n    // apply options to xhr\n    Object.entries(headers).forEach(([header, value]) => xhr.setRequestHeader(header, value));\n    // set xhr withCredentials\n    if (credentials)\n        xhr.withCredentials = credentials !== 'omit';\n};\n\nvar fetchFile = (url, onprogress, options) => new Promise((resolve, reject) => {\n    const handleError = () => reject(new EditorError('Error fetching image', EditorErrorCode.URL_REQUEST, xhr));\n    const xhr = new XMLHttpRequest();\n    xhr.onprogress = onprogress;\n    (xhr.onerror = handleError),\n        (xhr.onload = () => {\n            if (!xhr.response || xhr.status >= 300 || xhr.status < 200)\n                return handleError();\n            // we store the response mime type so we can add it to the blob later on, if it's missing (happens on Safari 10)\n            const mimetype = getResponseHeader(xhr, 'Content-Type');\n            // try to get filename and any file instructions as well\n            const filename = getResponseHeader(xhr, 'Content-Disposition', getFilenameFromContentDisposition) || getFilenameFromURL(url);\n            // convert to actual file if possible\n            resolve(blobToFile(xhr.response, filename, mimetype || getMimeTypeFromFilename(filename)));\n        });\n    // get helper\n    const { willRequest } = options;\n    Promise.resolve(willRequest && willRequest(url, { resourceType: 'image' }))\n        .then((requestInit) => {\n        // don't load image\n        if (requestInit === false)\n            return reject('Image load rejected');\n        // we're good to go (pass true explicitely on purpose)\n        xhr.open('GET', url, true);\n        // set props\n        configureXHR(xhr, requestInit);\n        // fire xhr\n        xhr.responseType = 'blob';\n        xhr.send();\n    })\n        .catch(console.error);\n});\n\nvar urlToFile = (url, onprogress, options) => {\n    // use fetch to create blob from data uri\n    if (isDataURI(url))\n        return dataURIToFile(url, undefined, onprogress);\n    // load file from url\n    return fetchFile(url, onprogress, options);\n};\n\nvar isBlob = (v) => v instanceof Blob && !(v instanceof File);\n\nvar isImageBitmap = (obj) => 'close' in obj;\n\nvar srcToFile = async (src, onprogress, options) => {\n    if (isFile(src) || isBlob(src))\n        return src;\n    else if (isString(src))\n        return await urlToFile(src, onprogress, options);\n    else if (isElement(src, 'canvas'))\n        return await canvasToFile(src);\n    else if (isElement(src, 'img'))\n        return await imageToFile(src);\n    else if (isImageData(src) || isImageBitmap(src))\n        return await canvasToFile(await imageDataToCanvas(src));\n    else {\n        throw new EditorError('Invalid image source', 'invalid-image-source');\n    }\n};\n\nlet result$9 = null;\nvar isMac = () => {\n    if (result$9 === null)\n        result$9 = isBrowser() && /^mac/i.test(navigator.platform);\n    return result$9;\n};\n\nlet result$8 = null;\nvar isIOS = () => {\n    if (result$8 === null)\n        // first part is for iPhones and iPads iOS 12 and below second part is for iPads with iOS 13 and up\n        result$8 =\n            isBrowser() &&\n                (isUserAgent(/iPhone|iPad|iPod/) || (isMac() && navigator.maxTouchPoints >= 1));\n    return result$8;\n};\n\nvar orientImageSize = async (size, orientation = 1) => {\n    // browser can handle image orientation\n    if ((await canOrientImages()) || isIOS())\n        return size;\n    // no need to correct size\n    if (orientation < 5)\n        return size;\n    // correct image size\n    return sizeCreate(size.height, size.width);\n};\n\nvar isJPEG = (file) => /jpeg/.test(file.type);\n\nvar isPlainObject = (obj) => typeof obj == 'object' && obj.constructor == Object;\n\nvar stringify = (value) => (!isPlainObject(value) ? value : JSON.stringify(value));\n\nvar post = (url, dataset, options) => new Promise((resolve, reject) => {\n    const { token = {}, beforeSend = noop$1, onprogress = noop$1 } = options;\n    token.cancel = () => request.abort();\n    const request = new XMLHttpRequest();\n    request.upload.onprogress = onprogress;\n    request.onload = () => request.status >= 200 && request.status < 300 ? resolve(request) : reject(request);\n    request.onerror = () => reject(request);\n    request.ontimeout = () => reject(request);\n    request.open('POST', encodeURI(url));\n    beforeSend(request);\n    request.send(\n    // if is FormData, we use that\n    dataset instanceof FormData\n        ? dataset\n        : // reduce the dataset to FormData\n            dataset.reduce((formData, args) => {\n                // @ts-ignore\n                formData.append(...args.map(stringify));\n                return formData;\n            }, new FormData()));\n});\n\nvar ctxRotate = (ctx, rotation = 0, pivot) => {\n    if (rotation === 0)\n        return ctx;\n    ctx.translate(pivot.x, pivot.y);\n    ctx.rotate(rotation);\n    ctx.translate(-pivot.x, -pivot.y);\n    return ctx;\n};\n\nvar ctxTranslate = (ctx, x, y) => {\n    ctx.translate(x, y);\n    return ctx;\n};\n\nvar ctxScale = (ctx, x, y) => {\n    ctx.scale(x, y);\n    return ctx;\n};\n\nvar cropImageData = async (imageData, options = {}) => {\n    const { flipX, flipY, rotation, crop } = options;\n    const imageSize = sizeCreateFromAny(imageData);\n    const shouldFlip = flipX || flipY;\n    const shouldRotate = !!rotation;\n    const cropDefined = crop && (crop.x || crop.y || crop.width || crop.height);\n    const cropCoversImage = cropDefined && rectEqual(crop, rectCreateFromSize(imageSize));\n    const shouldCrop = cropDefined && !cropCoversImage;\n    // skip!\n    if (!shouldFlip && !shouldRotate && !shouldCrop)\n        return imageData;\n    const defaultContextOptions = { willReadFrequently: true, colorSpace: imageData.colorSpace };\n    // create drawing context\n    let imageDataOut;\n    let image = h('canvas', {\n        width: imageData.width,\n        height: imageData.height,\n    });\n    const imageCtx = image.getContext('2d', defaultContextOptions);\n    imageCtx.putImageData(imageData, 0, 0);\n    // flip image data\n    if (shouldFlip) {\n        const ctx = h('canvas', {\n            width: image.width,\n            height: image.height,\n        }).getContext('2d', defaultContextOptions);\n        ctxScale(ctx, flipX ? -1 : 1, flipY ? -1 : 1);\n        ctx.drawImage(image, flipX ? -image.width : 0, flipY ? -image.height : 0);\n        ctx.restore();\n        releaseCanvas(image);\n        image = ctx.canvas;\n    }\n    // rotate image data\n    if (shouldRotate) {\n        // if shouldRotate is true we also receive a crop rect\n        const outputSize = sizeApply(sizeCreateFromRect(rectCreateFromPoints(rectRotate(rectCreateFromAny(image), rotation))), Math.floor);\n        const ctx = h('canvas', {\n            width: crop.width,\n            height: crop.height,\n        }).getContext('2d', defaultContextOptions);\n        ctxTranslate(ctx, -crop.x, -crop.y);\n        ctxRotate(ctx, rotation, sizeCenter(outputSize));\n        ctx.drawImage(image, (outputSize.width - image.width) * 0.5, (outputSize.height - image.height) * 0.5);\n        ctx.restore();\n        releaseCanvas(image);\n        image = ctx.canvas;\n    }\n    // crop image data\n    else if (shouldCrop) {\n        const ctx = image.getContext('2d', defaultContextOptions);\n        imageDataOut = ctx.getImageData(crop.x, crop.y, crop.width, crop.height);\n        releaseCanvas(image);\n        return imageDataOut;\n    }\n    // done, return resulting image data\n    const ctx = image.getContext('2d', defaultContextOptions);\n    imageDataOut = ctx.getImageData(0, 0, image.width, image.height);\n    releaseCanvas(image);\n    return imageDataOut;\n};\n\nvar resizeTransform = (options, done) => {\n    const { imageData, width, height } = options;\n    const inputWidth = imageData.width;\n    const inputHeight = imageData.height;\n    const inputColorSpace = imageData.colorSpace;\n    const outputWidth = Math.round(width);\n    const outputHeight = Math.round(height);\n    const inputData = imageData.data;\n    const outputData = new Uint8ClampedArray(outputWidth * outputHeight * 4);\n    const scaleX = inputWidth / outputWidth;\n    const scaleY = inputHeight / outputHeight;\n    const scaleXHalf = Math.ceil(scaleX * 0.5);\n    const scaleYHalf = Math.ceil(scaleY * 0.5);\n    for (let j = 0; j < outputHeight; j++) {\n        for (let i = 0; i < outputWidth; i++) {\n            const x2 = (i + j * outputWidth) * 4;\n            let weight = 0;\n            let weights = 0;\n            let weightsAlpha = 0;\n            let r = 0;\n            let g = 0;\n            let b = 0;\n            let a = 0;\n            const centerY = (j + 0.5) * scaleY;\n            for (let yy = Math.floor(j * scaleY); yy < (j + 1) * scaleY; yy++) {\n                const dy = Math.abs(centerY - (yy + 0.5)) / scaleYHalf;\n                const centerX = (i + 0.5) * scaleX;\n                const w0 = dy * dy;\n                for (let xx = Math.floor(i * scaleX); xx < (i + 1) * scaleX; xx++) {\n                    let dx = Math.abs(centerX - (xx + 0.5)) / scaleXHalf;\n                    const w = Math.sqrt(w0 + dx * dx);\n                    if (w < -1 || w > 1)\n                        continue;\n                    weight = 2 * w * w * w - 3 * w * w + 1;\n                    if (weight <= 0)\n                        continue;\n                    dx = 4 * (xx + yy * inputWidth);\n                    const ref = inputData[dx + 3];\n                    a += weight * ref;\n                    weightsAlpha += weight;\n                    if (ref < 255) {\n                        weight = (weight * ref) / 250;\n                    }\n                    r += weight * inputData[dx];\n                    g += weight * inputData[dx + 1];\n                    b += weight * inputData[dx + 2];\n                    weights += weight;\n                }\n            }\n            outputData[x2] = r / weights;\n            outputData[x2 + 1] = g / weights;\n            outputData[x2 + 2] = b / weights;\n            outputData[x2 + 3] = a / weightsAlpha;\n        }\n    }\n    // @ts-ignore\n    done(null, {\n        data: outputData,\n        width: outputWidth,\n        height: outputHeight,\n        colorSpace: inputColorSpace,\n    });\n};\n\nvar imageDataObjectToImageData = (obj) => {\n    if (obj instanceof ImageData) {\n        return obj;\n    }\n    let imageData;\n    try {\n        imageData = new ImageData(obj.width, obj.height, { colorSpace: obj.colorSpace || 'srgb' });\n    }\n    catch (err) {\n        // IE + Old EDGE (tested on 12)\n        const canvas = h('canvas');\n        imageData = canvas.getContext('2d').createImageData(obj.width, obj.height);\n    }\n    imageData.data.set(obj.data);\n    return imageData;\n};\n\nvar resizeImageData = async (imageData, options = {}, resizeImageData) => {\n    const { width, height, fit, upscale } = options;\n    // no need to rescale\n    if (!width && !height)\n        return imageData;\n    let targetWidth = width;\n    let targetHeight = height;\n    if (!width) {\n        targetWidth = height;\n    }\n    else if (!height) {\n        targetHeight = width;\n    }\n    if (fit !== 'force') {\n        const scalarWidth = targetWidth / imageData.width;\n        const scalarHeight = targetHeight / imageData.height;\n        let scalar = 1;\n        if (fit === 'cover') {\n            scalar = Math.max(scalarWidth, scalarHeight);\n        }\n        else if (fit === 'contain') {\n            scalar = Math.min(scalarWidth, scalarHeight);\n        }\n        // if image is too small, exit here with original image\n        if (scalar > 1 && upscale === false)\n            return imageData;\n        targetWidth = Math.round(imageData.width * scalar);\n        targetHeight = Math.round(imageData.height * scalar);\n        // correct for small rounding errors\n        if (width && height) {\n            if (Math.abs(targetWidth - width) <= 1)\n                targetWidth = width;\n            if (Math.abs(targetHeight - height) <= 1)\n                targetHeight = height;\n        }\n    }\n    // make sure canvas has a size\n    targetWidth = Math.max(targetWidth, 1);\n    targetHeight = Math.max(targetHeight, 1);\n    // no need to resize?\n    if (imageData.width === targetWidth && imageData.height === targetHeight)\n        return imageData;\n    // run custom image data resizer if defined\n    if (resizeImageData)\n        return resizeImageData(imageData, targetWidth, targetHeight);\n    // let's use the included resize method\n    imageData = await thread(resizeTransform, [\n        {\n            imageData: imageData,\n            width: targetWidth,\n            height: targetHeight,\n        },\n    ], [imageData.data.buffer]);\n    // the resizer returns a plain object, not an actual image data object, lets create one\n    return imageDataObjectToImageData(imageData);\n};\n\nvar colorEffect = (options, done) => {\n    const { imageData, matrix } = options;\n    if (!matrix || matrix.length !== 20)\n        return done(null, imageData);\n    const colorSpace = imageData.colorSpace;\n    const data = imageData.data;\n    const l = data.length;\n    const m11 = matrix[0];\n    const m12 = matrix[1];\n    const m13 = matrix[2];\n    const m14 = matrix[3];\n    const m15 = matrix[4];\n    const m21 = matrix[5];\n    const m22 = matrix[6];\n    const m23 = matrix[7];\n    const m24 = matrix[8];\n    const m25 = matrix[9];\n    const m31 = matrix[10];\n    const m32 = matrix[11];\n    const m33 = matrix[12];\n    const m34 = matrix[13];\n    const m35 = matrix[14];\n    const m41 = matrix[15];\n    const m42 = matrix[16];\n    const m43 = matrix[17];\n    const m44 = matrix[18];\n    const m45 = matrix[19];\n    let index = 0;\n    let r = 0.0;\n    let g = 0.0;\n    let b = 0.0;\n    let a = 0.0;\n    let mr = 0.0;\n    let mg = 0.0;\n    let mb = 0.0;\n    let ma = 0.0;\n    // let or = 0.0;\n    // let og = 0.0;\n    // let ob = 0.0;\n    const clamp = (v) => Math.max(0, Math.min(255, v * 255));\n    for (; index < l; index += 4) {\n        r = data[index] / 255;\n        g = data[index + 1] / 255;\n        b = data[index + 2] / 255;\n        a = data[index + 3] / 255;\n        if (a > 0) {\n            r /= a;\n            g /= a;\n            b /= a;\n        }\n        mr = r * m11 + g * m12 + b * m13 + a * m14 + m15;\n        mg = r * m21 + g * m22 + b * m23 + a * m24 + m25;\n        mb = r * m31 + g * m32 + b * m33 + a * m34 + m35;\n        ma = r * m41 + g * m42 + b * m43 + a * m44 + m45;\n        if (a > 0) {\n            r = mr * a;\n            g = mg * a;\n            b = mb * a;\n        }\n        else {\n            r = 0;\n            g = 0;\n            b = 0;\n        }\n        data[index] = clamp(mr * ma);\n        data[index + 1] = clamp(mg * ma);\n        data[index + 2] = clamp(mb * ma);\n        data[index + 3] = clamp(a);\n        // or = Math.max(0, mr * ma) + (1.0 - ma);\n        // og = Math.max(0, mg * ma) + (1.0 - ma);\n        // ob = Math.max(0, mb * ma) + (1.0 - ma);\n        // data[index] = Math.max(0.0, Math.min(1.0, or)) * 255;\n        // data[index + 1] = Math.max(0.0, Math.min(1.0, og)) * 255;\n        // data[index + 2] = Math.max(0.0, Math.min(1.0, ob)) * 255;\n        // data[index + 3] = a * 255;\n    }\n    // @ts-ignore\n    done(null, {\n        data,\n        width: imageData.width,\n        height: imageData.height,\n        colorSpace,\n    });\n};\n\nvar convolutionEffect = (options, done) => {\n    const { imageData, matrix } = options;\n    if (!matrix)\n        return done(null, imageData);\n    // calculate kernel weight\n    let kernelWeight = matrix.reduce((prev, curr) => prev + curr);\n    kernelWeight = kernelWeight <= 0 ? 1 : kernelWeight;\n    // input info\n    const inputWidth = imageData.width;\n    const inputHeight = imageData.height;\n    const inputData = imageData.data;\n    const inputColorSpace = imageData.colorSpace;\n    let i = 0;\n    let x = 0;\n    let y = 0;\n    const side = Math.round(Math.sqrt(matrix.length));\n    const sideHalf = Math.floor(side / 2);\n    let r = 0, g = 0, b = 0, a = 0, cx = 0, cy = 0, scy = 0, scx = 0, srcOff = 0, weight = 0;\n    const outputData = new Uint8ClampedArray(inputWidth * inputHeight * 4);\n    for (y = 0; y < inputHeight; y++) {\n        for (x = 0; x < inputWidth; x++) {\n            // calculate the weighed sum of the source image pixels that\n            // fall under the convolution matrix\n            r = 0;\n            g = 0;\n            b = 0;\n            a = 0;\n            for (cy = 0; cy < side; cy++) {\n                for (cx = 0; cx < side; cx++) {\n                    scy = y + cy - sideHalf;\n                    scx = x + cx - sideHalf;\n                    if (scy < 0) {\n                        scy = inputHeight - 1;\n                    }\n                    if (scy >= inputHeight) {\n                        scy = 0;\n                    }\n                    if (scx < 0) {\n                        scx = inputWidth - 1;\n                    }\n                    if (scx >= inputWidth) {\n                        scx = 0;\n                    }\n                    srcOff = (scy * inputWidth + scx) * 4;\n                    weight = matrix[cy * side + cx];\n                    r += inputData[srcOff] * weight;\n                    g += inputData[srcOff + 1] * weight;\n                    b += inputData[srcOff + 2] * weight;\n                    a += inputData[srcOff + 3] * weight;\n                }\n            }\n            outputData[i] = r / kernelWeight;\n            outputData[i + 1] = g / kernelWeight;\n            outputData[i + 2] = b / kernelWeight;\n            outputData[i + 3] = a / kernelWeight;\n            i += 4;\n        }\n    }\n    // @ts-ignore\n    done(null, {\n        data: outputData,\n        width: inputWidth,\n        height: inputHeight,\n        colorSpace: inputColorSpace,\n    });\n};\n\nvar vignetteEffect = (options, done) => {\n    let { imageData, strength } = options;\n    if (!strength)\n        return done(null, imageData);\n    const inputColorSpace = imageData.colorSpace;\n    const inputWidth = imageData.width;\n    const inputHeight = imageData.height;\n    const data = imageData.data;\n    const dist = (x, y) => {\n        dx = x - cx;\n        dy = y - cy;\n        return Math.sqrt(dx * dx + dy * dy);\n    };\n    let x = 0;\n    let y = 0;\n    let cx = inputWidth * 0.5;\n    let cy = inputHeight * 0.5;\n    let dx;\n    let dy;\n    let dm = dist(0, 0);\n    let fr, fg, fb;\n    let br, bg, bb, ba;\n    let fa;\n    let ca;\n    const blend = (index, input, output, alpha) => {\n        br = input[index] / 255;\n        bg = input[index + 1] / 255;\n        bb = input[index + 2] / 255;\n        ba = input[index + 3] / 255;\n        fa = 1.0 - alpha;\n        ca = fa * ba + alpha;\n        output[index] = ((fa * ba * br + alpha * fr) / ca) * 255;\n        output[index + 1] = ((fa * ba * bg + alpha * fg) / ca) * 255;\n        output[index + 2] = ((fa * ba * bb + alpha * fb) / ca) * 255;\n        output[index + 3] = ca * 255;\n    };\n    if (strength > 0) {\n        fr = 0;\n        fg = 0;\n        fb = 0;\n    }\n    else {\n        strength = Math.abs(strength);\n        fr = 1;\n        fg = 1;\n        fb = 1;\n    }\n    for (y = 0; y < inputHeight; y++) {\n        for (x = 0; x < inputWidth; x++) {\n            blend(\n            // index\n            (x + y * inputWidth) * 4, \n            // data in\n            data, \n            // data out\n            data, \n            // opacity\n            (dist(x, y) * strength) / dm);\n        }\n    }\n    // @ts-ignore\n    done(null, {\n        data,\n        width: imageData.width,\n        height: imageData.height,\n        colorSpace: inputColorSpace,\n    });\n};\n\nvar noiseEffect = (options, done) => {\n    const { imageData, level, monochrome = false } = options;\n    if (!level)\n        return done(null, imageData);\n    const colorSpace = imageData.colorSpace;\n    const data = imageData.data;\n    const l = data.length;\n    let index = 0;\n    let r;\n    let g;\n    let b;\n    const rand = () => (-1 + Math.random() * 2) * 255 * level;\n    const pixel = monochrome\n        ? () => {\n            const average = rand();\n            return [average, average, average];\n        }\n        : () => {\n            return [rand(), rand(), rand()];\n        };\n    for (; index < l; index += 4) {\n        [r, g, b] = pixel();\n        data[index] = data[index] + r;\n        data[index + 1] = data[index + 1] + g;\n        data[index + 2] = data[index + 2] + b;\n    }\n    // @ts-ignore\n    done(null, {\n        data,\n        width: imageData.width,\n        height: imageData.height,\n        colorSpace,\n    });\n};\n\nvar gammaEffect = (options, done) => {\n    const { imageData, level } = options;\n    if (!level)\n        return done(null, imageData);\n    const colorSpace = imageData.colorSpace;\n    const data = imageData.data;\n    const l = data.length;\n    let index = 0;\n    let r;\n    let g;\n    let b;\n    for (; index < l; index += 4) {\n        r = data[index] / 255;\n        g = data[index + 1] / 255;\n        b = data[index + 2] / 255;\n        data[index] = Math.pow(r, level) * 255;\n        data[index + 1] = Math.pow(g, level) * 255;\n        data[index + 2] = Math.pow(b, level) * 255;\n    }\n    // @ts-ignore\n    done(null, {\n        data,\n        width: imageData.width,\n        height: imageData.height,\n        colorSpace,\n    });\n};\n\nvar isIdentityMatrix = (matrix) => {\n    /*\n    [\n        1, 0, 0, 0, 0\n        0, 1, 0, 0, 0\n        0, 0, 1, 0, 0\n        0, 0, 0, 1, 0\n    ]\n    */\n    const l = matrix.length;\n    let v;\n    const s = l >= 20 ? 6 : l >= 16 ? 5 : 3;\n    for (let i = 0; i < l; i++) {\n        v = matrix[i];\n        if (v === 1 && i % s !== 0)\n            return false;\n        else if (v !== 0 && v !== 1)\n            return false;\n    }\n    return true;\n};\n\nvar filterImageData = async (imageData, options = {}) => {\n    const { colorMatrix, convolutionMatrix, gamma: gammaLevel, noise: noiseLevel, vignette: vignetteStrength, } = options;\n    // filters\n    const filters = [];\n    // apply convolution matrix\n    if (convolutionMatrix) {\n        filters.push([convolutionEffect, { matrix: convolutionMatrix.clarity }]);\n    }\n    // apply noise\n    if (gammaLevel > 0) {\n        filters.push([gammaEffect, { level: 1.0 / gammaLevel }]);\n    }\n    // apply color matrix\n    if (colorMatrix && !isIdentityMatrix(colorMatrix)) {\n        filters.push([colorEffect, { matrix: colorMatrix }]);\n    }\n    // apply noise\n    if (noiseLevel > 0 || noiseLevel < 0) {\n        filters.push([noiseEffect, { level: noiseLevel }]);\n    }\n    // apply vignette\n    if (vignetteStrength > 0 || vignetteStrength < 0) {\n        filters.push([vignetteEffect, { strength: vignetteStrength }]);\n    }\n    // no changes\n    if (!filters.length)\n        return imageData;\n    // builds effect chain\n    const chain = (transforms, i) => `(err, imageData) => {\n            (${transforms[i][0].toString()})(Object.assign({ imageData: imageData }, filterInstructions[${i}]), \n                ${transforms[i + 1] ? chain(transforms, i + 1) : 'done'})\n        }`;\n    const filterChain = `function (options, done) {\n        const filterInstructions = options.filterInstructions;\n        const imageData = options.imageData;\n        (${chain(filters, 0)})(null, imageData)\n    }`;\n    imageData = await thread(filterChain, [\n        {\n            imageData: imageData,\n            filterInstructions: filters.map((t) => t[1]),\n        },\n    ], [imageData.data.buffer]);\n    // the resizer returns a plain object, not an actual image data object, lets create one\n    return imageDataObjectToImageData(imageData);\n};\n\nvar isNumber = (v) => typeof v === 'number';\n\nvar isEmoji = (str) => isString(str) &&\n    str.match(/(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\u0023-\\u0039]\\ufe0f?\\u20e3|\\u3299|\\u3297|\\u303d|\\u3030|\\u24c2|\\ud83c[\\udd70-\\udd71]|\\ud83c[\\udd7e-\\udd7f]|\\ud83c\\udd8e|\\ud83c[\\udd91-\\udd9a]|\\ud83c[\\udde6-\\uddff]|\\ud83c[\\ude01-\\ude02]|\\ud83c\\ude1a|\\ud83c\\ude2f|\\ud83c[\\ude32-\\ude3a]|\\ud83c[\\ude50-\\ude51]|\\u203c|\\u2049|[\\u25aa-\\u25ab]|\\u25b6|\\u25c0|[\\u25fb-\\u25fe]|\\u00a9|\\u00ae|\\u2122|\\u2139|\\ud83c\\udc04|[\\u2600-\\u26FF]|\\u2b05|\\u2b06|\\u2b07|\\u2b1b|\\u2b1c|\\u2b50|\\u2b55|\\u231a|\\u231b|\\u2328|\\u23cf|[\\u23e9-\\u23f3]|[\\u23f8-\\u23fa]|\\ud83c\\udccf|\\u2934|\\u2935|[\\u2190-\\u21ff])/g) !== null;\n\nvar hasProp = (obj, key) => obj.hasOwnProperty(key);\n\nvar isArray = (arr) => Array.isArray(arr);\n\nvar isApple = () => isIOS() || isMac();\n\nvar isWindows = () => /^win/i.test(navigator.platform);\n\n// macos:   font-size: 123, x: 63.5, y: 110\n// windows: font-size: 112, x: 64, y: 103\n// android: font-size: 112, x: 64, y: 102\nlet x = 64;\nlet y = 102;\nlet fontSize = 112;\nlet hasSetValues = false;\nvar getEmojiSVG = (emoji, alt) => {\n    if (!hasSetValues && isBrowser()) {\n        if (isWindows())\n            y = 103;\n        if (isApple()) {\n            x = 63.5;\n            y = 110;\n            fontSize = 123;\n        }\n        hasSetValues = true;\n    }\n    return `<svg${alt ? ` aria-label=\"${alt}\"` : ''} width=\"128\" height=\"128\" viewBox=\"0 0 128 128\" preserveAspectRatio=\"xMinYMin meet\" xmlns=\"http://www.w3.org/2000/svg\"><text x=\"${x}\" y=\"${y}\" alignment-baseline=\"text-top\" dominant-baseline=\"text-top\" text-anchor=\"middle\" font-size=\"${fontSize}px\">${emoji}</text></svg>`;\n};\n\nvar SVGToDataURL = (svg) => `data:image/svg+xml,${svg.replace('<', '%3C').replace('>', '%3E')}`;\n\nvar isBinary = (v) => v instanceof Blob;\n\nvar toPercentage = (value, total) => `${(value / total) * 100}%`;\n\nvar colorArrayToRGBA = (color) => `rgba(${Math.round(color[0] * 255)}, ${Math.round(color[1] * 255)}, ${Math.round(color[2] * 255)}, ${isNumber(color[3]) ? color[3] : 1})`;\n\n// tested and this seems a tiny bit faster than JSON.stringify\nvar objectUID = (obj) => Object.values(obj).join('_');\n\nvar timeout = (timeout = 0) => new Promise((resolve) => {\n    setTimeout(resolve, timeout);\n});\n\n// cannot use a ObjectURL because of a webkit bug (throws error in chrome / safari)\n// returns true if every pixel's uint32 representation is 0 (or \"blank\")\nconst isContextBlank = (ctx) => {\n    const buffer = new Uint32Array(ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height).data.buffer);\n    return !buffer.some((color) => color !== 0);\n};\nconst width = 80;\nconst height = 80;\nconst whenSVGSafeForDrawing = async (img, delay = 0) => {\n    // Safari has some trouble with custom fonts\n    const canvas = h('canvas', { width, height });\n    const ctx = canvas.getContext('2d');\n    // always wait a short while because it's never ready on first draw\n    await timeout(delay);\n    // we draw the image so we can test if the content is drawn. If custom font isn't ready the canvas will be empty\n    ctx.drawImage(img, 0, 0, width, height);\n    if (isContextBlank(ctx) && delay <= 256)\n        return await whenSVGSafeForDrawing(img, delay + 16);\n    return true;\n};\n// store cached draw cycles here\nconst safariDrawCache = new Map();\nvar svgToImage = (svg, { safariCacheKey = '*' } = {}) => new Promise((resolve, reject) => {\n    const img = new Image();\n    img.onerror = () => reject(new Error('Failed to load SVG'));\n    img.onload = () => {\n        // uncomment to test difference between SVG as dataURL and SVG in page\n        // if (document.getElementById('svgdiv')) document.getElementById('svgdiv').remove();\n        // document.body.append(\n        //     h('div', {\n        //         id: 'svgdiv',\n        //         style: `\n        //         position:absolute;\n        //         top:0;\n        //         left:0;\n        //         display:flex;\n        //         pointer-events:none;\n        //         z-index:99999999999999;\n        //         filter:invert(100%);\n        //         opacity:.5;\n        //         outline:1px solid green;`,\n        //         innerHTML: svg,\n        //     })\n        // );\n        // We done!\n        if (!isSafari() || !svg.includes('@font-face') || safariDrawCache.has(safariCacheKey)) {\n            return resolve(img);\n        }\n        // wait for embedded fonts to load\n        whenSVGSafeForDrawing(img).then(() => {\n            safariDrawCache.set(safariCacheKey, true);\n            resolve(img);\n        });\n    };\n    img.src = 'data:image/svg+xml,' + svg;\n    // uncomment to test difference between SVG as dataURL and SVG in page\n    // const dupe = img.cloneNode() as HTMLElement;\n    // if (document.getElementById('svgimage')) document.getElementById('svgimage').remove();\n    // document.body.append(dupe);\n    // dupe.id = 'svgimage';\n    // dupe.style.cssText = `\n    // pointer-events:none;\n    // z-index:99999999999999;\n    // position:absolute;\n    // top:0;\n    // left:0;\n    // outline:1px solid purple;`;\n});\n\nvar blobToDataURL = (blob) => new Promise((resolve, reject) => {\n    const reader = new FileReader();\n    reader.onerror = () => reject(reader.error);\n    reader.onload = () => resolve(reader.result);\n    reader.readAsDataURL(blob);\n});\n\nvar pubsub = () => {\n    let subs = [];\n    return {\n        sub: (event, callback) => {\n            subs.push({ event, callback });\n            return () => (subs = subs.filter((subscriber) => subscriber.event !== event || subscriber.callback !== callback));\n        },\n        pub: (event, value) => {\n            subs\n                .filter((sub) => sub.event === event)\n                .forEach((sub) => sub.callback(value));\n        }\n    };\n};\n\n// used to make sure text is drawn outside of element in a correct way\nconst TextPadding = 32;\nconst textGetInitialLineOffset = ({ fontSize = 16, lineHeight = 20 } = {}) => Math.max(0, fontSize - lineHeight) * 0.5;\nconst textGetLineCount = (text = '') => {\n    return text.split('\\n').length;\n};\nconst textGetStyles = ({ color = [0, 0, 0], fontSize = 16, fontFamily = 'sans-serif', fontVariant = 'normal', fontWeight = 'normal', fontStyle = 'normal', textAlign = 'left', letterSpacing = 'normal', lineHeight = 20, }, scalar = 1) => `font-size:${fontSize * scalar}px;font-style:${fontStyle};font-weight:${fontWeight};font-family:${fontFamily};font-variant:${fontVariant};line-height:${lineHeight * scalar}px;text-align:${textAlign};letter-spacing:${isNumber(letterSpacing) ? letterSpacing + 'px' : 'normal'};color:${colorArrayToRGBA(color)};`;\nconst textGetContentEditableStyles = (text, options, scalar = 1) => {\n    const { width, height, disableNewline } = options;\n    const isAutoWidth = !width;\n    const allowNewline = disableNewline === false ? textGetLineCount(text) : undefined;\n    const widthValue = isAutoWidth ? 'auto' : `${width * scalar}px`;\n    const heightValue = height ? `${height * scalar}px` : 'auto';\n    const wordBreak = isAutoWidth ? 'normal' : 'break-word';\n    const whiteSpace = isAutoWidth && !allowNewline ? 'nowrap' : 'pre-line';\n    const paddingTop = textGetInitialLineOffset(options) * scalar;\n    return `max-width:none;min-width:auto;width:${widthValue};height:${heightValue};margin-top:0;margin-bottom:0;padding-top:${paddingTop}px;word-break:${wordBreak};word-wrap:normal;white-space:${whiteSpace};`;\n};\nconst TextMeasureCache = new Map();\nconst toParts = (node) => {\n    const parts = [];\n    for (const childNode of Array.from(node.childNodes)) {\n        if (childNode.nodeType === Node.TEXT_NODE) {\n            parts.push(textToLines(childNode));\n        }\n        else {\n            parts.push(...toParts(childNode));\n        }\n    }\n    return parts;\n};\nconst MeasureStyles = 'pointer-events:none;visibility:hidden;position:absolute;left:0;top:0;';\nconst textMeasure = (text = '', options) => {\n    // gather props that impact size and test if can be found in cache\n    let { width = 0, height = 'auto', fontSize, fontFamily, lineHeight, fontWeight, fontStyle, fontVariant, letterSpacing, } = options;\n    const uid = objectUID({\n        text,\n        fontFamily,\n        fontWeight,\n        fontStyle,\n        fontVariant,\n        fontSize,\n        lineHeight,\n        letterSpacing,\n        width,\n        height,\n    });\n    let measurement = TextMeasureCache.get(uid);\n    if (measurement)\n        return measurement;\n    // firefox limits font size to 1000px, so if we're above, we scale down before measuring and then scale up after measuring\n    let fontScalar = 1;\n    if (fontSize > 1000 && isFirefox()) {\n        fontScalar = fontSize / 1000;\n        fontSize = 1000;\n        lineHeight = lineHeight * fontScalar;\n    }\n    const element = appendForMeasuring(h('pre', {\n        contenteditable: 'true',\n        spellcheck: 'false',\n        style: `${MeasureStyles}${textGetStyles({\n            fontFamily,\n            fontWeight,\n            fontStyle,\n            fontVariant,\n            fontSize,\n            letterSpacing,\n            lineHeight,\n        })};${textGetContentEditableStyles(text, options)}\"`,\n        innerHTML: text,\n    }));\n    const elementRect = element.getBoundingClientRect();\n    // @ts-ignore\n    const elementTextParts = toParts(element).flat();\n    measurement = {\n        // @ts-ignore\n        signature: elementTextParts.map((line) => line.text).join('_;_'),\n        textSize: sizeApply(sizeCreateFromAny(elementRect), (v) => Math.ceil(v * fontScalar)),\n    };\n    TextMeasureCache.set(uid, measurement);\n    // clean up measured elements\n    element.remove();\n    return measurement;\n};\nconst textToLines = (node) => {\n    const text = node.nodeValue;\n    if (!text)\n        return [];\n    const textLength = text.length;\n    const range = document.createRange();\n    range.selectNodeContents(node);\n    const lines = [];\n    for (let i = 0; i < textLength; i++) {\n        range.setStart(node, 0);\n        range.setEnd(node, i + 1);\n        // which line are we at\n        const lineIndex = range.getClientRects().length - 1;\n        // get current character\n        const char = text.charAt(i);\n        // new line, or add to current line\n        if (!lines[lineIndex])\n            lines.push(char);\n        else\n            lines[lineIndex] += char;\n    }\n    // merge text and rects\n    const clientRects = range.getClientRects();\n    return lines.map((line, index) => ({\n        rect: clientRects[index],\n        text: line,\n    }));\n};\nconst TextSizeCache = new Map();\nconst textToSize = (text = '', options) => {\n    const { width, height } = options;\n    // if a size has been supplied we use that\n    if (isNumber(width) && isNumber(height))\n        return sizeCreate(width, height);\n    // gather props that impact size and test if can be found in cache\n    let { fontSize = 16, fontFamily, lineHeight = 20, fontWeight, fontStyle, fontVariant, letterSpacing, } = options;\n    const uid = objectUID({\n        text,\n        fontFamily,\n        fontWeight,\n        fontStyle,\n        fontVariant,\n        fontSize,\n        letterSpacing,\n        lineHeight,\n        width,\n    });\n    let size = TextSizeCache.get(uid);\n    if (size)\n        return size;\n    // firefox limits font size to 1000px, so if we're above, we scale down before measuring and then scale up after measuring\n    let fontScalar = 1;\n    if (fontSize > 1000 && isFirefox()) {\n        fontScalar = fontSize / 1000;\n        fontSize = 1000;\n        lineHeight = lineHeight / fontScalar;\n    }\n    // new measurement needed\n    const element = appendForMeasuring(h('pre', {\n        contenteditable: 'true',\n        spellcheck: 'false',\n        style: `${MeasureStyles}${textGetStyles({\n            ...options,\n            fontSize,\n            lineHeight,\n        })};${textGetContentEditableStyles(text, options)}\"`,\n        innerHTML: text,\n    }));\n    const rect = element.getBoundingClientRect();\n    size = sizeCreateFromAny(rect);\n    // cache measurement for next query\n    size = sizeApply(size, (v) => v * fontScalar);\n    // use fixed width if supplied\n    if (width)\n        size.width = width;\n    TextSizeCache.set(uid, size);\n    return size;\n};\nconst getPathFromURL = (url) => url.pathname.split('/').slice(0, -1).join('/');\nconst createStyleSheetLoader = (url, willRequest) => {\n    const { sub, pub } = pubsub();\n    let text;\n    let error;\n    Promise.resolve(willRequest && willRequest(url, { resourceType: 'stylesheet' })).then((requestInit) => {\n        // prevent load\n        if (requestInit === false) {\n            error = 'requestPrevented';\n            return pub('error', error);\n        }\n        // get props\n        const { headers, credentials } = requestInit || {};\n        // fetching\n        fetch(url, { headers, credentials })\n            .then((res) => res.text())\n            .then((txt) => {\n            text = txt;\n            pub('load', text);\n        })\n            .catch((err) => {\n            error = err;\n            pub('error', error);\n        });\n    });\n    return {\n        sub: (event, cb) => {\n            if (event === 'load' && text)\n                return cb(text);\n            if (event === 'error' && error)\n                return cb(error);\n            sub(event, cb);\n        },\n    };\n};\nconst StyleSheetLoaders = new Map();\nconst loadStylesheet = (url, willRequest) => new Promise((resolve, reject) => {\n    let loader = StyleSheetLoaders.get(url);\n    if (typeof loader === 'undefined') {\n        loader = createStyleSheetLoader(url, willRequest);\n        StyleSheetLoaders.set(url, loader);\n    }\n    loader.sub('load', resolve);\n    loader.sub('error', reject);\n});\n// use this method to access rules because when accessing third party stylesheetes like google fonts it will throw a warning\nconst getRulesRemote = async (src, willRequest, styleNonce) => {\n    // could not access, let's try to load\n    let styleSheetContent;\n    try {\n        styleSheetContent = await loadStylesheet(src, willRequest);\n    }\n    catch (err) {\n        return [];\n    }\n    const styleProps = {\n        innerHTML: styleSheetContent,\n        id: getUniqueId(),\n    };\n    if (styleNonce)\n        styleProps.nonce = styleNonce;\n    const styleElement = h('style', styleProps);\n    document.head.append(styleElement);\n    const tempStyleSheet = Array.from(document.styleSheets).find((styleSheet) => {\n        const node = styleSheet.ownerNode;\n        return node.id === styleElement.id;\n    });\n    styleElement.remove();\n    return Array.from(tempStyleSheet.cssRules);\n};\nconst RemoteStyleSheetRulesCache = new Map();\nconst filterFontFaceRules = (rules) => rules.filter((rule) => rule instanceof CSSFontFaceRule);\nconst filterImportRules = (rules) => rules.filter((rule) => rule instanceof CSSImportRule);\nconst getStyleSheetPath = (styleSheet) => {\n    if (!styleSheet.href) {\n        return null;\n    }\n    try {\n        return getPathFromURL(new URL(styleSheet.href));\n    }\n    catch (err) {\n        return null;\n    }\n};\nconst getImportRuleHref = (importRule, base) => {\n    if (!base ||\n        !importRule.href ||\n        importRule.href.startsWith('/') ||\n        importRule.href.startsWith('http')) {\n        return importRule.href;\n    }\n    return base + '/' + importRule.href.replace(/^\\.\\//, '');\n};\nconst getFontFaceRulesSafe = async (styleSheet, willRequest, styleNonce) => {\n    // if cached rules, return\n    if (RemoteStyleSheetRulesCache.has(styleSheet.href))\n        return RemoteStyleSheetRulesCache.get(styleSheet.href);\n    // try to get rules\n    let rules;\n    try {\n        // get all rules\n        rules = Array.from(styleSheet.cssRules);\n        // the path of the current stylesheet so we can correct relative import rules\n        const styleSheetPath = getStyleSheetPath(styleSheet);\n        // get @imports\n        for (const importRule of filterImportRules(rules)) {\n            const url = getImportRuleHref(importRule, styleSheetPath);\n            // already loaded this one before\n            if (RemoteStyleSheetRulesCache.has(url)) {\n                const remoteRules = RemoteStyleSheetRulesCache.get(url);\n                rules = [...rules, ...remoteRules];\n                continue;\n            }\n            // get remote rules for this @import\n            const remoteRules = await getRulesRemote(url, willRequest, styleNonce);\n            // remember returned rules for next run\n            RemoteStyleSheetRulesCache.set(url, remoteRules);\n            // add found rules\n            rules = [...rules, ...remoteRules];\n        }\n    }\n    catch (err) {\n        const url = styleSheet.href;\n        // this tries to load the styles with `fetch`\n        rules = await getRulesRemote(url, willRequest, styleNonce);\n        // remember returned rules for next run\n        RemoteStyleSheetRulesCache.set(url, rules);\n    }\n    // only interested in font face rules\n    return filterFontFaceRules(rules);\n};\nconst getCSSPropertyValue = (rule, name) => rule.style.getPropertyValue(name);\nconst isMatchingFontRule = (rule, fontFamily) => {\n    return getCSSPropertyValue(rule, 'font-family').replace(/^\"|\"$/g, '') == fontFamily;\n};\nconst isValidFontRule = (rule) => {\n    return (rule.style && getCSSPropertyValue(rule, 'src') && getCSSPropertyValue(rule, 'font-family'));\n};\nconst getMatchingFontRule = (rules, fontFamily) => {\n    const res = [];\n    for (const fontRule of rules) {\n        if (!isValidFontRule(fontRule))\n            continue;\n        if (!isMatchingFontRule(fontRule, fontFamily))\n            continue;\n        res.push(fontRule);\n    }\n    return res;\n};\nconst getDocumentStylesheetFontFaceRules = async (willRequest, styleNonce) => {\n    const styleSheets = Array.from(document.styleSheets).map((styleSheet) => getFontFaceRulesSafe(styleSheet, willRequest, styleNonce));\n    const ruleSets = await Promise.all(styleSheets);\n    const rules = [];\n    ruleSets.forEach((ruleSet) => rules.push(...ruleSet));\n    return rules;\n};\nconst getFontSources = async (fontFamily, willRequest, styleNonce) => {\n    // get matching font face rules\n    const fontFaceRules = await getDocumentStylesheetFontFaceRules(willRequest, styleNonce);\n    // rules matching this font\n    const matchingRules = getMatchingFontRule(fontFaceRules, fontFamily);\n    if (!matchingRules.length)\n        return [];\n    return matchingRules.map((rule) => {\n        // create stylesheet root path so we can determine font path\n        const url = rule.parentStyleSheet &&\n            rule.parentStyleSheet.href &&\n            new URL(rule.parentStyleSheet.href);\n        const styleSheetPath = url ? url.origin + getPathFromURL(url) + '/' : '';\n        // create font source\n        const fontSources = rule.style.getPropertyValue('src');\n        const fontSrcFirst = fontSources.match(/url\\(\"?(.*?)\"?\\)/)[1];\n        // get styles\n        const fontProps = Array.from(rule.style)\n            .filter((prop) => prop != 'src')\n            .reduce((props, key) => {\n            props += key + ':' + getCSSPropertyValue(rule, key) + ';';\n            return props;\n        }, '');\n        // merge together to create path (Safari font URL is absolute so if it is we only use that url)\n        return [\n            /^http/.test(fontSrcFirst) ? fontSrcFirst : styleSheetPath + fontSrcFirst,\n            fontProps,\n        ];\n    });\n};\nconst FontLocal = new Map();\nconst FontCache = new Map();\n// application/x-font-ttf\n// application/x-font-truetype\n// application/x-font-opentype\n// application/font-woff\n// application/font-woff2\n// font/otf\n// font/ttf\n// font/woff\n// font/woff2\nconst getFontFormatByMimeType = (type) => {\n    if (!type || /woff2/.test(type))\n        return 'woff2';\n    if (/woff/.test(type))\n        return 'woff';\n    if (/ttf|truetype/.test(type))\n        return 'truetype';\n    if (/otf|opentype/.test(type))\n        return 'opentype';\n    if (/svg/.test(type))\n        return 'svg';\n    return 'woff2';\n};\nconst getFontFaceEmbed = async (fontFamily, willRequest, styleNonce) => {\n    // todo test if is local font\n    if (FontLocal.get(fontFamily))\n        return;\n    let fontStyles = FontCache.get(fontFamily);\n    if (!fontStyles) {\n        // not cached yet, let's find the font source and turn it into a dataURL\n        const fontSources = await getFontSources(fontFamily, willRequest, styleNonce);\n        // no source found, is local font\n        if (!fontSources.length) {\n            FontLocal.set(fontFamily, true);\n            return;\n        }\n        const fontFaces = [];\n        for (const [fontSource, fontProps] of fontSources) {\n            const blob = await fetch(fontSource).then((res) => res.blob());\n            const dataType = getFontFormatByMimeType(blob.type);\n            const dataURL = await blobToDataURL(blob);\n            fontFaces.push(`@font-face { src:url(${dataURL}) format('${dataType}');${fontProps};font-display:block; }`);\n        }\n        fontStyles = fontFaces.join('');\n        // cache the font so it's super fast in next request\n        FontCache.set(fontFamily, fontStyles);\n    }\n    return fontStyles;\n};\nvar textToImage = async (text = '', options) => {\n    // exit if no text\n    if (!text.length)\n        return;\n    let { color, imageWidth = 300, imageHeight = 150, paddingTop = 0, paddingRight = TextPadding, paddingBottom = 0, paddingLeft = TextPadding, fontFamily, fontSize, pixelRatio = 1, willRequest, outline, blur, styleNonce, } = options;\n    // manage high font-size on firefox, don't blanket handle it here as Chrome has trouble scaling svg context\n    let fontScalar = 1;\n    let fontScalarStyles = '';\n    if (fontSize > 1000 && isFirefox()) {\n        fontScalar = fontSize / 1000;\n        fontScalarStyles = `transform-origin:0 0;transform:scale(${fontScalar})`;\n    }\n    const computedScalar = pixelRatio / fontScalar;\n    const width = (imageWidth + paddingLeft + paddingRight) * pixelRatio;\n    const height = (imageHeight + paddingBottom + paddingTop) * pixelRatio;\n    // build font style tag if should be embedded\n    const fontEmbed = await getFontFaceEmbed(fontFamily, willRequest, styleNonce);\n    let fontFaceStyleTag = '';\n    if (fontEmbed)\n        fontFaceStyleTag = `<style${styleNonce ? ` nonce=\"${styleNonce}\"` : ''}>${fontEmbed}</style>`;\n    // make sure text is encoded as characters before rendering in our SVG\n    let textEncoded = text\n        // these characters need to be encoded in an SVG dataURL\n        .replace(/%/g, '%25')\n        .replace(/#/g, '%23')\n        .replace(/&nbsp;/g, '\\u00a0')\n        // replace non escaped ampersands\n        .replace(/&(?!#\\d{4};|[a-z]+;)/gi, '&amp;');\n    // no non-closing tags allowed in foreignObject as is xhtml namespace,  safari and firefox don't draw newline character so replace with <br/>\n    const textFinal = textEncoded.replace(/<br>|\\n/g, '<br/>');\n    const computedPaddingTop = paddingTop * computedScalar;\n    const computedPaddingRight = paddingRight * computedScalar;\n    const computedPaddingBottom = paddingBottom * computedScalar;\n    const computedPaddingLeft = paddingLeft * computedScalar;\n    // define padding style\n    const paddingStyles = `top:${computedPaddingTop}px;right:${computedPaddingRight}px;bottom:${computedPaddingBottom}px;left:${computedPaddingLeft}px`;\n    // if shadow or outline\n    let fontColor = color;\n    let outlineStyles = '';\n    let blurStyles = '';\n    if (outline || blur) {\n        const computedColor = colorArrayToRGBA(color);\n        if (outline) {\n            // we hide text\n            fontColor = [0, 0, 0, 0];\n            // we use text color for outline\n            outlineStyles = `-webkit-text-stroke: ${outline * 2 * computedScalar}px ${computedColor}`;\n        }\n        if (blur) {\n            if (isSafari()) {\n                // Safari: somehow a text-shadow with a blur doesn't work when drawing the final image, so instead we use the blur()filter. The .4 approximates the amount of blur when using text-shadow.\n                blurStyles = `filter:blur(${blur * computedScalar * 0.4}px)`;\n            }\n            else {\n                // we hide text\n                fontColor = [0, 0, 0, 0];\n                // we use text color for shadow\n                blurStyles = `text-shadow: 0 0 ${blur * computedScalar}px ${computedColor}`;\n            }\n        }\n    }\n    const textStyles = textGetStyles({ ...options, color: fontColor, fontSize }, computedScalar);\n    const textContentEditableStyles = textGetContentEditableStyles(text, options, computedScalar);\n    // build svg string\n    const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${width}\" height=\"${height}\" viewBox=\"0 0 ${width} ${height}\"><foreignObject x=\"0\" y=\"0\" width=\"${width}\" height=\"${height}\"><div xmlns=\"http://www.w3.org/1999/xhtml\">${fontFaceStyleTag}<pre contenteditable=\"true\" spellcheck=\"false\" style=\"position:absolute;${paddingStyles};${textStyles};${textContentEditableStyles};${fontScalarStyles};${outlineStyles};${blurStyles}\">${textFinal}</pre></div></foreignObject></svg>`;\n    return svgToImage(svg, { safariCacheKey: fontFamily });\n};\n\nconst shapeEqual = (a, b) => {\n    return JSON.stringify(a) === JSON.stringify(b);\n};\nconst shapeDeepCopy = (shape) => {\n    const shapeShallowCopy = { ...shape };\n    const shapeDeepCopy = deepCopy(shapeShallowCopy);\n    return shapeDeepCopy;\n};\nconst getContextSize = (context, size = {}) => {\n    const contextAspectRatio = rectAspectRatio(context);\n    let xOut;\n    let yOut;\n    const xIn = size.width || size.rx;\n    const yIn = size.height || size.ry;\n    if (xIn && yIn)\n        return sizeClone(size);\n    if (xIn || yIn) {\n        xOut = parseFloat(xIn || Number.MAX_SAFE_INTEGER);\n        yOut = parseFloat(yIn || Number.MAX_SAFE_INTEGER);\n        const min = Math.min(xOut, yOut);\n        if (isString(xIn) || isString(yIn)) {\n            xOut = `${min}%`;\n            yOut = `${min * contextAspectRatio}%`;\n        }\n        else {\n            xOut = min;\n            yOut = min;\n        }\n    }\n    else {\n        const min = 10;\n        xOut = `${min}%`;\n        yOut = `${min * contextAspectRatio}%`;\n    }\n    const xProp = size.width ? 'width' : size.rx ? 'rx' : undefined;\n    const yProp = size.width ? 'height' : size.rx ? 'ry' : undefined;\n    return {\n        [xProp || 'width']: xOut,\n        [yProp || 'height']: yOut,\n    };\n};\nconst shapeCreateFromEmoji = (emoji, props = {}) => {\n    return {\n        width: undefined,\n        height: undefined,\n        ...props,\n        aspectRatio: 1,\n        backgroundImage: SVGToDataURL(getEmojiSVG(emoji)),\n    };\n};\nconst shapeCreateFromImage = (src, shapeProps = {}) => {\n    const shapeDefaultLayout = shapeIsEllipse(shapeProps)\n        ? {}\n        : {\n            width: undefined,\n            height: undefined,\n            aspectRatio: undefined,\n        };\n    const shape = {\n        // required/default image shape props\n        backgroundColor: [0, 0, 0, 0],\n        // set default layout props\n        ...shapeDefaultLayout,\n        // merge with custom props\n        ...shapeProps,\n        // set image\n        backgroundImage: \n        // is svg or URL\n        isString(src) ? src : isBinary(src) ? URL.createObjectURL(src) : src,\n    };\n    return shape;\n};\nconst shapeCreateFromPreset = (preset, parentRect) => {\n    let shape;\n    if (isString(preset) || isBinary(preset)) {\n        // default props for \"quick\" preset\n        const shapeOptions = {\n            ...getContextSize(parentRect),\n            backgroundSize: 'contain',\n        };\n        // if is emoji, create default markup,\n        if (isEmoji(preset)) {\n            shape = shapeCreateFromEmoji(preset, shapeOptions);\n        }\n        // is URL, create default markup for image\n        else {\n            shape = shapeCreateFromImage(preset, shapeOptions);\n        }\n    }\n    else {\n        // is using src shortcut\n        if (preset.src) {\n            const contextSize = getContextSize(parentRect, preset.shape || preset);\n            // shape options\n            const shapeOptions = {\n                // default shape styles\n                ...preset.shape,\n                // precalcualte size of shape in context\n                ...contextSize,\n            };\n            // should auto-fix aspect ratio\n            if (preset.width && preset.height && !hasProp(shapeOptions, 'aspectRatio')) {\n                const width = shapeGetPropPixelValue(contextSize, 'width', parentRect);\n                const height = shapeGetPropPixelValue(contextSize, 'height', parentRect);\n                shapeOptions.aspectRatio = getAspectRatio(width, height);\n            }\n            // should auto-contain sticker in container\n            if (!shapeOptions.backgroundSize && !preset.shape && (!preset.width || !preset.height))\n                shapeOptions.backgroundSize = 'contain';\n            // emoji markup\n            if (isEmoji(preset.src)) {\n                shape = shapeCreateFromEmoji(preset.src, shapeOptions);\n            }\n            // is url\n            else {\n                shape = shapeCreateFromImage(preset.src, shapeOptions);\n            }\n        }\n        // should have markup defined\n        else if (preset.shape) {\n            shape = shapeDeepCopy(preset.shape);\n        }\n    }\n    if (hasProp(shape, 'backgroundImage')) {\n        // set transparent background if no background color defined\n        if (!hasProp(shape, 'backgroundColor')) {\n            shape.backgroundColor = [0, 0, 0, 0];\n        }\n        // for rectangles with image presets, disable these styles by default\n        if (!hasProp(shape, 'disableStyle')) {\n            shape.disableStyle = ['cornerRadius', 'backgroundColor', 'strokeColor', 'strokeWidth'];\n        }\n    }\n    return parentRect ? shapeComputeDisplay(shape, parentRect) : shape;\n};\nconst shapeLineGetStartPoint = (line) => vectorCreate(line.x1, line.y1);\nconst shapeLineGetEndPoint = (line) => vectorCreate(line.x2, line.y2);\n//#endregion\n//#region shape testing\n// shape types\nconst shapeIsText = (shape) => hasProp(shape, 'text');\nconst shapeIsTextBlock = (shape) => shapeIsText(shape) && !(shapeHasRelativeSize(shape) || hasProp(shape, 'width'));\nconst shapeIsTextBox = (shape) => shapeIsText(shape) && (shapeHasRelativeSize(shape) || hasProp(shape, 'width'));\nconst shapeIsRect = (shape) => !shapeIsText(shape) && shapeHasComputedSize(shape);\nconst shapeIsEllipse = (shape) => hasProp(shape, 'rx');\nconst shapeIsLine = (shape) => hasProp(shape, 'x1');\nconst shapeIsPath = (shape) => hasProp(shape, 'points');\n// shape state\nconst shapeIsTextEmpty = (shape) => shapeIsText(shape) && !shape.text.length;\nconst shapeIsTextEditing = (shape) => shapeIsText(shape) && shape.isEditing;\nconst shapeIsVisible = (shape) => hasProp(shape, 'opacity') ? shape.opacity > 0 : true;\nconst shapeIsSelected = (shape) => shape.isSelected;\nconst shapeIsEditing = (shape) => shape.isEditing;\nconst shapeIsDraft = (shape) => shape._isDraft;\nconst shapeHasSize = (shape) => hasProp(shape, 'width') && hasProp(shape, 'height');\nconst shapeHasNumericStroke = (shape) => isNumber(shape.strokeWidth) && shape.strokeWidth > 0; // only relevant if is bigger than 0\nconst shapeHasRelativePosition = (shape) => {\n    const hasRight = hasProp(shape, 'right');\n    const hasBottom = hasProp(shape, 'bottom');\n    return hasRight || hasBottom;\n};\nconst shapeHasTexture = (shape) => hasProp(shape, 'backgroundImage') || hasProp(shape, 'text');\nconst shapeHasRelativeSize = (shape) => ((hasProp(shape, 'x') || hasProp(shape, 'left')) && hasProp(shape, 'right')) ||\n    ((hasProp(shape, 'y') || hasProp(shape, 'top')) && hasProp(shape, 'bottom'));\nconst shapeHasComputedSize = (shape) => shapeHasSize(shape) || shapeHasRelativeSize(shape);\nconst shapeIsVisibleColor = (shape, colorProp) => {\n    const value = shape[colorProp];\n    if (!value)\n        return false;\n    if (value.length === 3)\n        return true;\n    return value[3] > 0;\n};\nconst shapeHasStroke = (shape) => shape.strokeWidth && shapeIsVisibleColor(shape, 'strokeColor');\n// actions\nconst shapeSelect = (shape) => {\n    shape.isSelected = true;\n    return shape;\n};\nconst shapeMakeDraft = (shape) => {\n    shape._isDraft = true;\n    return shape;\n};\nconst shapeMakeFinal = (shape) => {\n    shape._isDraft = false;\n    return shape;\n};\n// rights\nconst shapeCanStyle = (shape, style) => {\n    if (shape.disableStyle === true)\n        return false;\n    if (isArray(shape.disableStyle) && style) {\n        return !shape.disableStyle.includes(style);\n    }\n    return true;\n};\nconst shapeCanAcceptSnap = (shape) => shape.disableAcceptSnap !== true;\nconst shapeCanErase = (shape) => shape.disableErase !== true;\nconst shapeCanSelect = (shape) => shape.disableSelect !== true;\nconst shapeCanRemove = (shape) => shape.disableRemove !== true;\nconst shapeCanDuplicate = (shape) => shape.disableDuplicate !== true && shapeCanMove(shape);\nconst shapeCanReorder = (shape) => shape.disableReorder !== true;\nconst shapeCanFlip = (shape) => {\n    if (shape.disableFlip)\n        return false;\n    if (shapeIsDraft(shape) || shapeHasRelativePosition(shape))\n        return false;\n    return shapeHasTexture(shape);\n};\nconst shapeCanInput = (shape, input) => {\n    if (!shapeIsText(shape))\n        return false;\n    if (shape.disableInput === true)\n        return false;\n    if (isFunction(shape.disableInput))\n        return shape.disableInput(input != null ? input : shape.text);\n    return input || true;\n};\nconst shapeCanChangeTextLayout = (shape, layout) => {\n    if (shape.disableTextLayout === true)\n        return false;\n    if (isArray(shape.disableTextLayout) && layout) {\n        return !shape.disableTextLayout.includes(layout);\n    }\n    return true;\n};\nconst shapeCanSelectPoint = (shape) => {\n    // can't select points if below 3\n    return shapeCanAddPoint(shape) && shape.points.length > 3;\n};\nconst shapeCanAddPoint = (shape) => {\n    if (!shapeIsPath(shape))\n        return false;\n    if (shape.disableAddPoints === undefined || shape.disableAddPoints === true)\n        return false;\n    return true;\n};\nconst shapeCanManipulate = (shape) => shape.disableManipulate !== true && !shapeIsDraft(shape) && !shapeHasRelativePosition(shape);\nconst shapeCanMove = (shape) => shapeCanManipulate(shape) && shape.disableMove !== true;\nconst shapeCanResize = (shape) => shapeCanManipulate(shape) &&\n    shapeCanMove(shape) &&\n    shape.disableResize !== true &&\n    (shapeHasSize(shape) ||\n        shapeIsTextBox(shape) ||\n        shapeIsEllipse(shape) ||\n        shapeIsLine(shape) ||\n        (shapeIsPath(shape) && hasProp(shape, 'pathClose')));\nconst shapeCanRotate = (shape) => shapeCanManipulate(shape) &&\n    shape.disableRotate !== true &&\n    (shapeHasSize(shape) || hasProp(shape, 'text') || shapeIsEllipse(shape));\n//#endregion\n//#region shape formatting\nconst shapeDeleteRelativeProps = (shape) => {\n    delete shape.left;\n    delete shape.right;\n    delete shape.top;\n    delete shape.bottom;\n    return shape;\n};\nconst shapeDeleteTransformProps = (shape) => {\n    delete shape.rotation;\n    return shape;\n};\nconst shapeFormatStroke = (shape) => {\n    shape.strokeWidth = shape.strokeWidth || 1;\n    shape.strokeColor = shape.strokeColor || [0, 0, 0];\n    return shape;\n};\nconst shapeFormatFill = (shape) => {\n    shape.backgroundColor = shape.backgroundColor\n        ? shape.backgroundColor\n        : shape.strokeWidth || shape.backgroundImage\n            ? undefined\n            : [0, 0, 0];\n    return shape;\n};\n// encode illegal characters\n// first replace entities, then encode characters that are left, then replace entities\nconst shapeFormatHTMLText = (shape) => {\n    let text = shape.text;\n    text = text.replace(/&(#[0-9]+|[a-z]+);/gi, (_, value) => `___${value}___`);\n    text = text.replace(/&/, '&amp;');\n    shape.text = text.replace(/___(#[0-9]+|[a-z]+)___/gi, (_, value) => `&${value};`);\n};\nconst shapeFormatPlainText = (shape) => {\n    shapeFormatHTMLText(shape);\n    let text = shape.text;\n    text = text.replace(/</g, '&gt;');\n    text = text.replace(/>/g, '&lt;');\n    shape.text = text;\n};\nconst shapeExpandTextShadow = (shape) => {\n    if (!shape.textShadow)\n        return shape;\n    const [x, y, blur, color] = shape.textShadow;\n    shape.textShadowX = x;\n    shape.textShadowY = y;\n    shape.textShadowBlur = blur;\n    shape.textShadowColor = color;\n    delete shape.textShadow;\n    return shape;\n};\nconst shapeExpandOutline = (shape) => {\n    if (!shape.textOutline)\n        return shape;\n    const [width, color] = shape.textOutline;\n    shape.textOutlineWidth = width;\n    shape.textOutlineColor = color;\n    delete shape.textOutline;\n};\nconst shapeFormatText = (shape) => {\n    shape.fontSize = shape.fontSize || '4%';\n    shape.fontFamily = shape.fontFamily || 'sans-serif';\n    shape.fontWeight = shape.fontWeight || 'normal';\n    shape.fontStyle = shape.fontStyle || 'normal';\n    shape.fontVariant = shape.fontVariant || 'normal';\n    shape.lineHeight = shape.lineHeight || '120%';\n    shape.color = shape.color || [0, 0, 0];\n    shape.format = shape.format === 'html' ? 'html' : 'text';\n    shapeExpandTextShadow(shape);\n    shapeExpandOutline(shape);\n    if (shape.format === 'html')\n        shapeFormatHTMLText(shape);\n    else\n        shapeFormatPlainText(shape);\n    return shapeIsTextBlock(shape) ? shapeFormatTextBlock(shape) : shapeFormatTextBox(shape);\n};\nconst shapeFormatTextBlock = (shape) => {\n    // for now can't align if not allowed to use newlines\n    if (shape.disableNewline !== false) {\n        delete shape.textAlign;\n        shape.text = shape.text.replace(/\\n/g, ' ');\n    }\n    return shapeDeleteRelativeProps(shape);\n};\nconst shapeFormatTextBox = (shape) => {\n    shape.textAlign = shape.textAlign || 'left';\n    return shape;\n};\nconst shapeFormatRect = (shape) => {\n    shape.cornerRadius = shape.cornerRadius || 0;\n    shape.strokeWidth = shape.strokeWidth || 0;\n    shape.strokeColor = shape.strokeColor || [0, 0, 0];\n    return shapeFormatFill(shape);\n};\nconst shapeFormatEllipse = (shape) => {\n    shape.strokeWidth = shape.strokeWidth || 0;\n    shape.strokeColor = shape.strokeColor || [0, 0, 0];\n    return shapeFormatFill(shape);\n};\nconst shapeFormatPath = (shape) => {\n    shapeFormatStroke(shape);\n    shapeDeleteTransformProps(shape);\n    if (!hasProp(shape, 'pathClose')) {\n        shape.disableResize = true;\n        if (!hasProp(shape, 'disableMove')) {\n            shape.disableMove = true;\n        }\n    }\n    return shapeDeleteRelativeProps(shape);\n};\nconst shapeFormatLine = (shape) => {\n    shapeFormatStroke(shape);\n    shape.lineStart = shape.lineStart || undefined;\n    shape.lineEnd = shape.lineEnd || undefined;\n    shapeDeleteTransformProps(shape);\n    return shapeDeleteRelativeProps(shape);\n};\nconst shapeFormatDefaults = (shape) => {\n    if (!isString(shape.id))\n        shape.id = getUniqueId();\n    if (!hasProp(shape, 'rotation'))\n        shape.rotation = 0;\n    if (!hasProp(shape, 'opacity'))\n        shape.opacity = 1;\n    if (!hasProp(shape, 'disableErase'))\n        shape.disableErase = true;\n};\nconst shapeFormat = (shape) => {\n    shapeFormatDefaults(shape);\n    if (shapeIsText(shape)) {\n        shapeFormatText(shape);\n    }\n    else if (shapeIsRect(shape)) {\n        shapeFormatRect(shape);\n    }\n    else if (shapeIsPath(shape)) {\n        shapeFormatPath(shape);\n    }\n    else if (shapeIsLine(shape)) {\n        shapeFormatLine(shape);\n    }\n    else if (shapeIsEllipse(shape)) {\n        shapeFormatEllipse(shape);\n    }\n    return shape;\n};\nconst shapeGetDescription = (shape) => {\n    if (shapeIsText(shape))\n        return 'text';\n    if (shapeIsRect(shape))\n        return 'rectangle';\n    if (shapeIsPath(shape))\n        return 'path';\n    if (shapeIsLine(shape))\n        return 'line';\n    if (shapeIsEllipse(shape))\n        return 'ellipse';\n    return;\n};\n//#endregion\nconst toPixelValue = (percentage, total) => (parseFloat(percentage) / 100) * total;\n//#region shape transforming\nconst xRegExp = new RegExp(/^x|left|right|^width|rx|fontSize|eraseRadius|feather|cornerRadius|strokeWidth|strokeDash/, 'i');\nconst yRegExp = new RegExp(/^y|top|bottom|^height|ry/, 'i');\nconst compute = (key, value, { width, height }) => {\n    // handle array of percentage values\n    if (Array.isArray(value)) {\n        return value.map((v) => {\n            if (isObject(v)) {\n                // update the object itself\n                computeProps(v, { width, height });\n            }\n            if (isString(v)) {\n                v = compute(key, v, { width, height });\n            }\n            return v;\n        });\n    }\n    // no need to compute (test with typeof instead of for perf)\n    if (typeof value !== 'string')\n        return value;\n    if (!value.endsWith('%'))\n        return value;\n    const f = parseFloat(value) / 100;\n    if (xRegExp.test(key))\n        return fixPrecision(width * f, 6);\n    if (yRegExp.test(key))\n        return fixPrecision(height * f, 6);\n    // dont auto-compute\n    return value;\n};\nconst shapeComputeProp = compute;\nconst computeRelativeToValue = (percentage, value) => {\n    return Math.round(value * (parseFloat(percentage) / 100));\n};\nconst PROPS_RELATIVE_TO_FONT_SIZE = [\n    'lineHeight',\n    'textOutlineWidth',\n    'textShadowX',\n    'textShadowY',\n    'textShadowBlur',\n];\nconst computeProps = (obj, context) => {\n    Object.entries(obj).map(([key, value]) => {\n        obj[key] = compute(key, value, context);\n    });\n    // no text, skip\n    if (!obj.text)\n        return;\n    // calculate props relative to font size\n    PROPS_RELATIVE_TO_FONT_SIZE.filter((key) => isString(obj[key])).forEach((key) => {\n        obj[key] = computeRelativeToValue(obj[key], obj.fontSize);\n    });\n};\nconst shapeComputeDisplay = (shape, context) => {\n    computeProps(shape, context);\n    shapeComputeRect(shape, context);\n    return shape;\n};\nconst shapeGetPropPixelTotal = (prop, parentRect) => {\n    let total;\n    if (/^x|width|rx|fontSize|strokeWidth|cornerRadius/.test(prop)) {\n        total = parentRect.width;\n    }\n    else if (/^y|height|ry/.test(prop)) {\n        total = parentRect.height;\n    }\n    return total;\n};\nconst shapeUpdateProp = (shape, prop, value, parentRect) => {\n    if (!isString(shape[prop])) {\n        shape[prop] = value;\n        return shape;\n    }\n    const total = shapeGetPropPixelTotal(prop, parentRect);\n    shape[prop] = total === undefined ? value : toPercentage(value, total);\n    return shape;\n};\nconst shapeGetPropPixelValue = (shape, prop, parentRect) => {\n    if (Array.isArray(shape[prop])) {\n        return shape[prop].map((item) => {\n            return Object.entries(item).reduce((mapped, [key, value]) => {\n                mapped[key] = isString(value)\n                    ? toPixelValue(value, shapeGetPropPixelTotal(key, parentRect))\n                    : value;\n                return mapped;\n            }, {});\n        });\n    }\n    if (!isString(shape[prop]))\n        return shape[prop];\n    return toPixelValue(shape[prop], shapeGetPropPixelTotal(prop, parentRect));\n};\nconst shapeGetPropsPixelValues = (shape, props, parentRect) => {\n    return props.reduce((prev, prop) => {\n        const value = shapeGetPropPixelValue(shape, prop, parentRect);\n        prev[prop] = value;\n        return prev;\n    }, {});\n};\nconst shapeUpdateProps = (shape, props, parentRect) => {\n    Object.keys(props).forEach((key) => shapeUpdateProp(shape, key, props[key], parentRect));\n    return shape;\n};\nconst shapeBounds = (shape) => {\n    const rect = rectCreateEmpty();\n    const strokeWidth = shape.strokeWidth || 0;\n    if (shapeIsRect(shape)) {\n        rect.x = shape.x - strokeWidth * 0.5;\n        rect.y = shape.y - strokeWidth * 0.5;\n        rect.width = shape.width + strokeWidth;\n        rect.height = shape.height + strokeWidth;\n    }\n    else if (shapeIsLine(shape)) {\n        const { x1, y1, x2, y2 } = shape;\n        const left = Math.abs(Math.min(x1, x2));\n        const right = Math.abs(Math.max(x1, x2));\n        const top = Math.abs(Math.min(y1, y2));\n        const bottom = Math.abs(Math.min(y1, y2));\n        rect.x = left + strokeWidth * 0.5;\n        rect.y = right + strokeWidth * 0.5;\n        rect.width = right - left + strokeWidth;\n        rect.height = bottom - top + strokeWidth;\n    }\n    else if (shapeIsEllipse(shape)) {\n        rect.x = shape.x - shape.rx + strokeWidth * 0.5;\n        rect.y = shape.y - shape.ry + strokeWidth * 0.5;\n        rect.width = shape.rx * 2 + strokeWidth;\n        rect.height = shape.ry * 2 + strokeWidth;\n    }\n    if (rect && hasProp(shape, 'rotation')) {\n        rectRotate(rect, shape.rotation);\n    }\n    return rectToBounds(rect);\n};\nconst shapesBounds = (shapes, parentRect) => {\n    const bounds = shapes\n        .filter((shape) => shape.x < 0 || shape.y < 0 || shape.x1 < 0 || shape.y1 < 0)\n        .reduce((bounds, shape) => {\n        const [top, right, bottom, left] = shapeBounds(shape);\n        bounds.top = Math.min(top, bounds.top);\n        bounds.left = Math.min(left, bounds.left);\n        bounds.bottom = Math.max(bottom, bounds.bottom);\n        bounds.right = Math.max(right, bounds.right);\n        return bounds;\n    }, {\n        top: 0,\n        right: 0,\n        bottom: 0,\n        left: 0,\n    });\n    if (bounds.right > 0)\n        bounds.right -= parentRect.width;\n    if (bounds.bottom > 0)\n        bounds.bottom -= parentRect.height;\n    return bounds;\n};\nconst shapesFromCompositShape = (shape, parentRect, parser) => {\n    const shapeCopy = shapeDeepCopy(shape);\n    shapeComputeDisplay(shapeCopy, parentRect);\n    const shapes = parser(shapeCopy);\n    return Array.isArray(shapes) ? shapes : [shapes];\n};\nconst shapeComputeRect = (shape, context) => {\n    if (hasProp(shape, 'left'))\n        shape.x = shape.left;\n    if (hasProp(shape, 'right') && !isString(shape.right)) {\n        const r = context.width - shape.right;\n        if (hasProp(shape, 'left')) {\n            shape.x = shape.left;\n            shape.width = Math.max(0, r - shape.left);\n        }\n        else if (hasProp(shape, 'width')) {\n            shape.x = r - shape.width;\n        }\n    }\n    if (hasProp(shape, 'top'))\n        shape.y = shape.top;\n    if (hasProp(shape, 'bottom') && !isString(shape.bottom)) {\n        const b = context.height - shape.bottom;\n        if (hasProp(shape, 'top')) {\n            shape.y = shape.top;\n            shape.height = Math.max(0, b - shape.top);\n        }\n        else if (hasProp(shape, 'height')) {\n            shape.y = b - shape.height;\n        }\n    }\n    return shape;\n};\n// currently only used for drawing to canvas in output\nconst shapeScale = (shape, scale) => {\n    if (shapeIsPath(shape)) {\n        shape.points\n            .filter((point) => isNumber(point.x))\n            .forEach((point) => {\n            point.x *= scale;\n            point.y *= scale;\n        });\n    }\n    if (shapeIsLine(shape) && isNumber(shape.x1)) {\n        shape.x1 *= scale;\n        shape.y1 *= scale;\n        shape.x2 *= scale;\n        shape.y2 *= scale;\n    }\n    if (isNumber(shape.x) && isNumber(shape.y)) {\n        shape.x *= scale;\n        shape.y *= scale;\n    }\n    if (isNumber(shape.width) && isNumber(shape.height)) {\n        shape.width *= scale;\n        shape.height *= scale;\n    }\n    if (isNumber(shape.rx) && isNumber(shape.ry)) {\n        shape.rx *= scale;\n        shape.ry *= scale;\n    }\n    if (shapeHasNumericStroke(shape)) {\n        shape.strokeWidth *= scale;\n    }\n    if (shapeIsText(shape)) {\n        shape._scale = scale;\n        if (isNumber(shape.fontSize)) {\n            shape.fontSize *= scale;\n        }\n        if (isNumber(shape.lineHeight)) {\n            shape.lineHeight *= scale;\n        }\n        if (isNumber(shape.width) && !isNumber(shape.height))\n            shape.width *= scale;\n    }\n    if (hasProp(shape, 'cornerRadius') && isNumber(shape.cornerRadius)) {\n        shape.cornerRadius *= scale;\n    }\n    return shape;\n};\nconst shapeGetLength = (shape) => {\n    if (!shape.x1)\n        return;\n    return vectorDistance(vectorCreate(shape.x1, shape.y1), vectorCreate(shape.x2, shape.y2));\n};\nconst shapeGetCenter = (shape) => {\n    if (shapeIsRect(shape)) {\n        return vectorCreate(shape.x + shape.width * 0.5, shape.y + shape.height * 0.5);\n    }\n    if (shapeIsEllipse(shape)) {\n        return vectorCreate(shape.x, shape.y);\n    }\n    if (shape.text) {\n        // if is text box we try to use width & height values\n        if (shapeIsTextBox(shape)) {\n            const height = shape.height || textToSize(shape.text, shape).height;\n            return vectorCreate(shape.x + shape.width * 0.5, shape.y + height * 0.5);\n        }\n        // else we calculate text size\n        const size = textToSize(shape.text, shape);\n        return vectorCreate(shape.x + size.width * 0.5, shape.y + size.height * 0.5);\n    }\n    if (shapeIsPath(shape)) {\n        return vectorCenter(shape.points);\n    }\n    if (shapeIsLine(shape)) {\n        return vectorCenter([\n            shapeLineGetStartPoint(shape),\n            shapeLineGetEndPoint(shape),\n        ]);\n    }\n    return undefined;\n};\n//#endregion\nconst shapeGetLevel = (shapeInitialState, imageCurrentState) => {\n    let flipX = false;\n    if (imageCurrentState.flipX && shapeInitialState.flipX) {\n        flipX = true;\n    }\n    else if (!imageCurrentState.flipX && shapeInitialState.flipX) {\n        flipX = false;\n    }\n    else if (imageCurrentState.flipX && !shapeInitialState.flipX) {\n        flipX = true;\n    }\n    let flipY = false;\n    if (imageCurrentState.flipY && shapeInitialState.flipY) {\n        flipY = true;\n    }\n    else if (!imageCurrentState.flipY && shapeInitialState.flipY) {\n        flipY = false;\n    }\n    else if (imageCurrentState.flipY && !shapeInitialState.flipY) {\n        flipY = true;\n    }\n    let rotation = -imageCurrentState.rotation;\n    if ((flipX || flipY) && !(flipX && flipY))\n        rotation = -rotation;\n    return {\n        flipX,\n        flipY,\n        rotation,\n    };\n};\n\nvar ctxRoundRect = (ctx, x, y, width, height, radius) => {\n    if (width < 2 * radius)\n        radius = width / 2;\n    if (height < 2 * radius)\n        radius = height / 2;\n    ctx.beginPath();\n    ctx.moveTo(x + radius, y);\n    ctx.arcTo(x + width, y, x + width, y + height, radius);\n    ctx.arcTo(x + width, y + height, x, y + height, radius);\n    ctx.arcTo(x, y + height, x, y, radius);\n    ctx.arcTo(x, y, x + width, y, radius);\n    ctx.closePath();\n    return ctx;\n};\n\nvar isCanvas = (element) => /canvas/i.test(element.nodeName);\n\nvar isRemoteURL = (url) => new URL(url, location.href).origin !== location.origin;\n\nvar loadImage = (image, onSize = undefined) => new Promise((resolve, reject) => {\n    // the image element we'll use to load the image\n    let imageElement = image;\n    let sizeCalculated = false;\n    const reportSize = () => {\n        if (sizeCalculated)\n            return;\n        sizeCalculated = true;\n        isFunction(onSize) &&\n            /* Use Promise.resolve to make async but place before resolve of parent promise */\n            Promise.resolve().then(() => onSize(sizeCreate(imageElement.naturalWidth, imageElement.naturalHeight)));\n    };\n    // if is not an image element, it must be a valid image source\n    if (!imageElement.src) {\n        imageElement = new Image();\n        // if is remote image, set crossOrigin\n        // why not always set crossOrigin? -> because when set this fires two requests,\n        // one for asking permission and one for downloading the image\n        if (isString(image) && isRemoteURL(image))\n            imageElement.crossOrigin = 'anonymous';\n        imageElement.src = isString(image) ? image : URL.createObjectURL(image);\n    }\n    if (imageElement.complete) {\n        reportSize();\n        return resolve(imageElement);\n    }\n    // try to calculate size faster\n    if (isFunction(onSize))\n        getImageElementSize(imageElement).then(reportSize).catch(reject);\n    imageElement.onload = () => {\n        reportSize();\n        resolve(imageElement);\n    };\n    imageElement.onerror = () => reject(new Error('Failed to load image'));\n});\n\nconst cache = new Map([]);\nconst getImage = (src, options = {}) => new Promise((resolve, reject) => {\n    const { onMetadata = noop$1, onLoad = resolve, onError = reject, onComplete = noop$1, } = options;\n    let imageLoadState = cache.get(src);\n    // start loading\n    if (!imageLoadState) {\n        imageLoadState = {\n            loading: false,\n            complete: false,\n            error: false,\n            image: undefined,\n            size: undefined,\n            bus: pubsub(),\n        };\n        // store\n        cache.set(src, imageLoadState);\n    }\n    // wait for load\n    imageLoadState.bus.sub('meta', onMetadata);\n    imageLoadState.bus.sub('load', onLoad);\n    imageLoadState.bus.sub('error', onError);\n    imageLoadState.bus.sub('complete', onComplete);\n    // if is canvas, it's already done\n    if (isCanvas(src)) {\n        const canvas = src;\n        // get image\n        const image = canvas.cloneNode();\n        // update state\n        imageLoadState.complete = true;\n        imageLoadState.image = image;\n        imageLoadState.size = sizeCreateFromElement(canvas);\n    }\n    // already loaded\n    if (imageLoadState.complete) {\n        imageLoadState.bus.pub('meta', { size: imageLoadState.size });\n        if (imageLoadState.error) {\n            imageLoadState.bus.pub('error', imageLoadState.error);\n        }\n        else {\n            imageLoadState.bus.pub('load', imageLoadState.image);\n        }\n        imageLoadState.bus.pub('complete');\n        // reset subscribers\n        imageLoadState.bus = pubsub();\n        return;\n    }\n    // already loading, exit here\n    if (imageLoadState.loading)\n        return;\n    // now loading\n    imageLoadState.loading = true;\n    // resource needs to be loaded\n    loadImage(src, (size) => {\n        imageLoadState.size = size;\n        imageLoadState.bus.pub('meta', { size });\n    })\n        .then((image) => {\n        imageLoadState.image = image;\n        imageLoadState.bus.pub('load', image);\n    })\n        .catch((err) => {\n        imageLoadState.error = err;\n        imageLoadState.bus.pub('error', err);\n    })\n        .finally(() => {\n        imageLoadState.complete = true;\n        imageLoadState.loading = false;\n        imageLoadState.bus.pub('complete');\n        // reset subscribers\n        imageLoadState.bus = pubsub();\n    });\n});\n\nconst drawCanvas = (ctx, image, srcRect, destRect) => ctx.drawImage(image, srcRect.x, srcRect.x, srcRect.width, srcRect.height, destRect.x, destRect.y, destRect.width, destRect.height);\nvar ctxDrawImage = async (ctx, image, srcRect, destRect, draw = drawCanvas, options) => {\n    ctx.save();\n    ctx.clip();\n    await draw(ctx, image, srcRect, destRect, options);\n    ctx.restore();\n};\nconst getDrawImageParams = (container, backgroundSize, imageSize, backgroundCorners, backgroundPosition) => {\n    // target is container\n    const destRect = rectClone(container);\n    // texture mapping\n    if (backgroundCorners) {\n        const srcRect = rectApply(rectCreateFromPoints(backgroundCorners), fixPrecision);\n        srcRect.x *= imageSize.width;\n        srcRect.width *= imageSize.width;\n        srcRect.y *= imageSize.height;\n        srcRect.height *= imageSize.height;\n        return {\n            srcRect,\n            destRect,\n        };\n    }\n    // by default use entire image\n    const srcRect = rectCreate(0, 0, imageSize.width, imageSize.height);\n    // css background positioning\n    if (backgroundSize === 'contain') {\n        const rect = rectContainRect(container, rectAspectRatio(srcRect));\n        destRect.width = rect.width;\n        destRect.height = rect.height;\n        if (backgroundPosition) {\n            destRect.x += backgroundPosition.x;\n            destRect.y += backgroundPosition.y;\n        }\n        else {\n            destRect.x += rect.x;\n            destRect.y += rect.y;\n        }\n    }\n    else if (backgroundSize === 'cover') {\n        const relativeRect = rectCoverRect(destRect, srcRect.width / srcRect.height);\n        destRect.width = relativeRect.width;\n        destRect.height = relativeRect.height;\n        if (backgroundPosition) {\n            destRect.x += backgroundPosition.x;\n            destRect.y += backgroundPosition.y;\n        }\n        else {\n            destRect.x += relativeRect.x;\n            destRect.y += relativeRect.y;\n        }\n    }\n    else if (backgroundSize) {\n        destRect.width = backgroundSize.width;\n        destRect.height = backgroundSize.height;\n        if (backgroundPosition) {\n            destRect.x += backgroundPosition.x;\n            destRect.y += backgroundPosition.y;\n        }\n    }\n    else if (backgroundPosition) {\n        destRect.width = imageSize.width;\n        destRect.height = imageSize.height;\n        destRect.x += backgroundPosition.x;\n        destRect.y += backgroundPosition.y;\n    }\n    return {\n        srcRect,\n        destRect,\n    };\n};\n\nconst defineRectShape = (ctx, shape) => {\n    shape.cornerRadius > 0\n        ? ctxRoundRect(ctx, shape.x, shape.y, shape.width, shape.height, shape.cornerRadius)\n        : ctx.rect(shape.x, shape.y, shape.width, shape.height);\n    return ctx;\n};\nconst fillRectShape = (ctx, shape) => {\n    shape.backgroundColor && ctx.fill();\n    return ctx;\n};\nconst strokeRectShape = (ctx, shape) => {\n    shape.strokeWidth && ctx.stroke();\n    return ctx;\n};\nvar drawRect = async (ctx, shape, options = {}) => {\n    const { drawImage } = options;\n    ctx.lineWidth = shape.strokeWidth ? shape.strokeWidth : 1; // 1 is default value for lineWidth prop\n    ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'none';\n    ctx.fillStyle = shape.backgroundColor ? colorArrayToRGBA(shape.backgroundColor) : 'none';\n    ctx.globalAlpha = shape.opacity;\n    if (shape.backgroundImage) {\n        let image;\n        if (isCanvas(shape.backgroundImage)) {\n            image = shape.backgroundImage;\n        }\n        else {\n            image = await getImage(shape.backgroundImage);\n        }\n        // draw background color first\n        defineRectShape(ctx, shape);\n        fillRectShape(ctx, shape);\n        // draw pattern OR draw normal image\n        if (shape.backgroundRepeat === 'repeat') {\n            const backgroundPosition = shape.backgroundPosition || { x: 0, y: 0 };\n            const { srcRect, destRect } = getDrawImageParams(shape, shape.backgroundSize || sizeCreateFromElement(image), sizeCreateFromElement(image), shape.backgroundCorners, { x: 0, y: 0 });\n            // create pattern canvas so we can scale image before creating pattern\n            const patternCanvas = document.createElement('canvas');\n            patternCanvas.width = destRect.width;\n            patternCanvas.height = destRect.height;\n            const patternCtx = patternCanvas.getContext('2d', {\n                willReadFrequently: false,\n                desynchronized: true,\n            });\n            await drawImage(patternCtx, image, srcRect, { ...destRect, x: 0, y: 0 });\n            // fill context with pattern\n            const pattern = ctx.createPattern(patternCanvas, 'repeat');\n            ctx.fillStyle = pattern;\n            ctx.save();\n            ctx.beginPath();\n            ctx.rect(shape.x + backgroundPosition.x, shape.y + backgroundPosition.y, shape.width - backgroundPosition.x, shape.height - backgroundPosition.y);\n            ctx.clip();\n            ctx.translate(destRect.x + backgroundPosition.x, destRect.y + backgroundPosition.y);\n            ctx.fill();\n            // release pattern canvas\n            releaseCanvas(patternCanvas);\n            ctx.restore();\n        }\n        else {\n            const { srcRect, destRect } = getDrawImageParams(shape, shape.backgroundSize, sizeCreateFromElement(image), shape.backgroundCorners, shape.backgroundPosition);\n            await ctxDrawImage(ctx, image, srcRect, destRect, drawImage, {\n                feather: shape.feather,\n            });\n        }\n        ctx.beginPath();\n        defineRectShape(ctx, shape);\n        strokeRectShape(ctx, shape);\n        return [];\n    }\n    // no image, only draw fill and stroke\n    defineRectShape(ctx, shape);\n    fillRectShape(ctx, shape);\n    strokeRectShape(ctx, shape);\n    return [];\n};\n\nvar drawEllipse = async (ctx, shape, options = {}) => new Promise(async (resolve, reject) => {\n    const { drawImage } = options;\n    ctx.lineWidth = shape.strokeWidth || 1; // 1 is default value for lineWidth prop\n    ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'none';\n    ctx.fillStyle = shape.backgroundColor ? colorArrayToRGBA(shape.backgroundColor) : 'none';\n    ctx.globalAlpha = shape.opacity;\n    ctx.ellipse(shape.x, shape.y, shape.rx, shape.ry, 0, 0, Math.PI * 2);\n    shape.backgroundColor && ctx.fill();\n    if (shape.backgroundImage) {\n        let image;\n        try {\n            image = await getImage(shape.backgroundImage);\n        }\n        catch (err) {\n            reject(err);\n        }\n        const bounds = rectCreate(shape.x - shape.rx, shape.y - shape.ry, shape.rx * 2, shape.ry * 2);\n        const { srcRect, destRect } = getDrawImageParams(bounds, shape.backgroundSize, sizeCreateFromElement(image), shape.backgroundCorners, shape.backgroundPosition);\n        // @ts-ignore\n        await ctxDrawImage(ctx, image, srcRect, destRect, drawImage);\n        shape.strokeWidth && ctx.stroke();\n        resolve([]);\n    }\n    else {\n        shape.strokeWidth && ctx.stroke();\n        resolve([]);\n    }\n});\n\nvar drawText = async (ctx, shape, options) => {\n    const width = isNumber(shape.width) ? Math.floor(shape.width) : undefined;\n    const height = isNumber(shape.height) ? Math.floor(shape.height) : undefined;\n    // calculate text size\n    const textSize = width && height\n        ? sizeCreateFromAny(shape)\n        : textToSize(shape.text, { ...shape, width, height });\n    const rect = {\n        x: shape.x,\n        y: shape.y,\n        width: textSize.width,\n        height: textSize.height,\n    };\n    drawRect(ctx, {\n        ...shape,\n        ...rect,\n        options,\n    });\n    // skip if no text\n    if (!shape.text.length)\n        return [];\n    // draw text effects first\n    const { textOutlineWidth = 0, textShadowX = 0, textShadowY = 0, textShadowBlur = 0, textShadowColor, \n    // remove outline and blur so don't interfere with text shape rendering\n    outline, blur, \n    // remaining styles for final text shape\n    ...plaintTextShape } = shape;\n    // if height set, clip to text box\n    const shouldClip = !!shape.height;\n    if (shouldClip) {\n        ctx.rect(rect.x, rect.y, rect.width, rect.height);\n        ctx.save();\n        ctx.clip();\n    }\n    // draw shadow\n    if (textShadowX || textShadowY || textShadowBlur) {\n        ctx.save();\n        // move translation based on text shadow\n        ctx.translate(textShadowX, textShadowY);\n        // adjust rect so we draw all shadow\n        const shadowRect = { ...rect };\n        if (!shouldClip) {\n            shadowRect.height += TextPadding + textShadowBlur;\n        }\n        // draw base shadow\n        await drawTextImage(ctx, shadowRect, { ...shape, width, height }, {\n            ...options,\n            paddingLeft: TextPadding + textShadowBlur,\n            paddingRight: TextPadding + textShadowBlur,\n            paddingTop: textShadowBlur,\n            paddingBottom: textShadowBlur + (shouldClip ? -1 * textShadowY : shape.fontSize),\n            shapeExtendedProps: {\n                color: textShadowColor,\n                blur: textShadowBlur,\n            },\n        });\n        ctx.restore();\n    }\n    // draw outline\n    if (textOutlineWidth) {\n        const outlineRect = { ...rect };\n        if (!shouldClip)\n            outlineRect.height += TextPadding + textOutlineWidth;\n        await drawTextImage(ctx, outlineRect, { ...shape, width, height }, {\n            ...options,\n            paddingLeft: TextPadding + textOutlineWidth,\n            paddingRight: TextPadding + textOutlineWidth,\n            paddingTop: textOutlineWidth,\n            paddingBottom: textOutlineWidth + shouldClip ? 0 : shape.fontSize,\n            shapeExtendedProps: {\n                color: shape.textOutlineColor,\n                outline: textOutlineWidth,\n            },\n        });\n    }\n    // restore text clipping\n    if (shouldClip) {\n        ctx.restore();\n    }\n    // draw text\n    await drawTextImage(ctx, rect, { ...plaintTextShape, width, height }, {\n        ...options,\n        paddingLeft: TextPadding,\n        paddingRight: TextPadding,\n        paddingTop: 0,\n        paddingBottom: shouldClip ? 0 : shape.fontSize,\n    });\n    return [];\n};\nconst drawTextImage = async (ctx, rect, shape, options) => {\n    const { willRequest, shapeExtendedProps, paddingLeft, paddingRight, paddingTop, paddingBottom, styleNonce, } = options;\n    // aligns with how canvas measured width/height\n    const width = isNumber(shape.width) ? Math.floor(rect.width) : undefined;\n    const height = isNumber(shape.height) ? Math.floor(rect.height) : undefined;\n    const imageWidth = Math.ceil(rect.width);\n    const imageHeight = Math.ceil(rect.height);\n    // maybe in future use same pixel ratio as device to better match preview text texture?\n    const image = await textToImage(shape.text, {\n        ...shape,\n        ...shapeExtendedProps,\n        ...rect,\n        width,\n        height,\n        paddingLeft,\n        paddingRight,\n        paddingTop,\n        paddingBottom,\n        imageWidth,\n        imageHeight,\n        willRequest,\n        styleNonce,\n    });\n    ctx.drawImage(image, shape.x - paddingLeft, shape.y - paddingTop, image.width, image.height);\n};\n\nvar drawLine = async (ctx, shape) => new Promise(async (resolve) => {\n    ctx.lineWidth = shape.strokeWidth || 1; // 1 is default value for lineWidth prop\n    ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'none';\n    ctx.globalAlpha = shape.opacity;\n    if (shape.bitmap) {\n        ctx.lineCap = shape.strokeCap;\n        ctx.lineJoin = shape.strokeJoin;\n        ctx.setLineDash(shape.strokeDash || []);\n    }\n    let lineStartPosition = shapeLineGetStartPoint(shape);\n    let lineEndPosition = shapeLineGetEndPoint(shape);\n    // draw line\n    ctx.moveTo(lineStartPosition.x, lineStartPosition.y);\n    ctx.lineTo(lineEndPosition.x, lineEndPosition.y);\n    shape.strokeWidth && ctx.stroke();\n    // draw other shapes\n    resolve([]);\n});\n\nvar drawPath = async (ctx, shape) => new Promise((resolve, reject) => {\n    // let's draw a dot instead\n    if (shape.bitmap && shape.points.length === 1) {\n        drawEllipse(ctx, {\n            x: shape.points[0].x,\n            y: shape.points[0].y,\n            rx: shape.strokeWidth * 0.5,\n            ry: shape.strokeWidth * 0.5,\n            backgroundColor: shape.strokeColor,\n        }).then(() => resolve([]));\n        return;\n    }\n    ctx.lineWidth = shape.strokeWidth || 1; // 1 is default value for lineWidth prop\n    ctx.strokeStyle = shape.strokeColor ? colorArrayToRGBA(shape.strokeColor) : 'transparent';\n    ctx.fillStyle =\n        shape.pathClose && shape.backgroundColor\n            ? colorArrayToRGBA(shape.backgroundColor)\n            : 'transparent';\n    ctx.globalAlpha = shape.opacity;\n    // draw line\n    const { points } = shape;\n    if (shape.bitmap) {\n        ctx.lineCap = shape.strokeCap;\n        ctx.lineJoin = shape.strokeJoin;\n        ctx.setLineDash(shape.strokeDash || []);\n    }\n    if (shape.pathClose) {\n        ctx.beginPath();\n    }\n    ctx.moveTo(points[0].x, points[0].y);\n    const l = points.length;\n    for (let i = 1; i < l; i++) {\n        ctx.lineTo(points[i].x, points[i].y);\n    }\n    if (shape.pathClose)\n        ctx.closePath();\n    shape.strokeWidth && ctx.stroke();\n    shape.backgroundColor && ctx.fill();\n    resolve([]);\n});\n\nvar ctxFlip = (ctx, flipX, flipY, pivot) => {\n    if (!flipX && !flipY)\n        return ctx;\n    ctx.translate(pivot.x, pivot.y);\n    ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);\n    ctx.translate(-pivot.x, -pivot.y);\n    return ctx;\n};\n\nconst drawShape = async (ctx, shape, options) => {\n    // add or subtract\n    ctx.globalCompositeOperation =\n        shape.drawMode === 'subtract' ? 'destination-out' : 'source-over';\n    // center, needed for transforms\n    const center = shapeGetCenter(shape);\n    // rotate context\n    ctxRotate(ctx, shape.rotation, center);\n    // flip context\n    ctxFlip(ctx, shape.flipX, shape.flipY, center);\n    let fn;\n    if (shapeIsRect(shape)) {\n        fn = drawRect;\n    }\n    else if (shapeIsEllipse(shape)) {\n        fn = drawEllipse;\n    }\n    else if (shapeIsLine(shape)) {\n        fn = drawLine;\n    }\n    else if (shapeIsPath(shape)) {\n        fn = drawPath;\n    }\n    else if (shapeIsText(shape)) {\n        fn = drawText;\n    }\n    if (fn) {\n        const subShapes = await fn(ctx, shape, options);\n        if (!subShapes.length)\n            return [];\n        const shapes = await drawShapes(ctx, subShapes, options);\n        return [shape, ...shapes];\n    }\n    return [];\n};\n\nvar drawShapes = async (ctx, shapes, options) => {\n    let drawnShapes = [];\n    for (const shape of shapes) {\n        ctx.save();\n        // clears previous shape's path\n        ctx.beginPath();\n        // wait for shape to draw before drawing next shape\n        drawnShapes = [...drawnShapes, ...(await drawShape(ctx, shape, options))];\n        ctx.restore();\n    }\n    return drawnShapes;\n};\n\nvar drawImageData = async (imageData, options = {}) => {\n    const { shapes = [], contextBounds = imageData, transform = noop$1, drawImage, willRequest, styleNonce, canvasMemoryLimit, computeShape = passthrough, preprocessShape = passthrough, } = options;\n    // no shapes to draw\n    if (!shapes.length)\n        return imageData;\n    const defaultContextOptions = { willReadFrequently: true, colorSpace: imageData.colorSpace };\n    // create drawing context\n    const canvas = h('canvas');\n    canvas.width = contextBounds.width;\n    canvas.height = contextBounds.height;\n    const ctx = canvas.getContext('2d', defaultContextOptions);\n    ctx.putImageData(imageData, contextBounds.x || 0, contextBounds.y || 0);\n    // compute the position of all shapes\n    const computedShapes = shapes\n        .map(shapeDeepCopy)\n        .map(computeShape)\n        .map(preprocessShape)\n        .flat()\n        .filter(Boolean);\n    // compute transforms for context\n    transform(ctx);\n    // draw shapes to canvas\n    await drawShapes(ctx, computedShapes, {\n        drawImage,\n        canvasMemoryLimit,\n        willRequest,\n        styleNonce,\n    });\n    const imageDataOut = ctx.getImageData(0, 0, canvas.width, canvas.height);\n    releaseCanvas(canvas);\n    return imageDataOut;\n};\n\nvar fillImageData = async (imageData, options = {}) => {\n    const { backgroundFilterMode, backgroundColor, backgroundImage } = options;\n    const hasBackgroundColor = !(!backgroundColor || (backgroundColor && backgroundColor[3] === 0));\n    // no background set\n    if (!backgroundImage && !hasBackgroundColor) {\n        return imageData;\n    }\n    const defaultContextOptions = { willReadFrequently: true, colorSpace: imageData.colorSpace };\n    // canvas to fill\n    const image = h('canvas');\n    image.width = imageData.width;\n    image.height = imageData.height;\n    const ctx = image.getContext('2d', defaultContextOptions);\n    ctx.putImageData(imageData, 0, 0);\n    // fill behind image\n    ctx.globalCompositeOperation = 'destination-over';\n    if (hasBackgroundColor) {\n        ctx.fillStyle = colorArrayToRGBA(backgroundColor);\n        ctx.fillRect(0, 0, image.width, image.height);\n    }\n    if (backgroundImage) {\n        let backgroundCanvas;\n        if (isCanvas(backgroundImage)) {\n            backgroundCanvas = backgroundImage;\n        }\n        else {\n            backgroundCanvas = await getImage(backgroundImage);\n            // turn into canvas because we're going to apply filters to the background\n            if (backgroundFilterMode === 'image') {\n                backgroundCanvas = imageToCanvas(backgroundCanvas, {\n                    contextOptions: defaultContextOptions,\n                });\n            }\n        }\n        // should we apply filters?\n        let backgroundCanvasFiltered;\n        if (backgroundFilterMode === 'image') {\n            const backgroundImageData = canvasToImageData(backgroundCanvas);\n            const backgroundImageDataFiltered = await filterImageData(backgroundImageData, options);\n            backgroundCanvasFiltered = await imageDataToCanvas(backgroundImageDataFiltered);\n        }\n        // determine where to draw\n        const { srcRect, destRect } = getDrawImageParams({\n            x: 0,\n            y: 0,\n            width: imageData.width,\n            height: imageData.height,\n        }, 'cover', {\n            width: backgroundCanvas.width || backgroundCanvas.naturalWidth,\n            height: backgroundCanvas.height || backgroundCanvas.naturalHeight,\n        });\n        // draw behind src image\n        ctx.drawImage(backgroundCanvasFiltered || backgroundCanvas, srcRect.x, srcRect.y, srcRect.width, srcRect.height, destRect.x, destRect.y, destRect.width, destRect.height);\n        if (backgroundCanvasFiltered)\n            releaseCanvas(backgroundCanvasFiltered);\n        if (backgroundFilterMode &&\n            backgroundFilterMode !== 'none' &&\n            backgroundCanvas &&\n            !isCanvas(backgroundImage))\n            releaseCanvas(backgroundCanvas);\n    }\n    const imageDataOut = ctx.getImageData(0, 0, image.width, image.height);\n    releaseCanvas(image);\n    return imageDataOut;\n};\n\nvar dotColorMatrix = (a, b) => {\n    const res = new Array(20);\n    // R\n    res[0] = a[0] * b[0] + a[1] * b[5] + a[2] * b[10] + a[3] * b[15];\n    res[1] = a[0] * b[1] + a[1] * b[6] + a[2] * b[11] + a[3] * b[16];\n    res[2] = a[0] * b[2] + a[1] * b[7] + a[2] * b[12] + a[3] * b[17];\n    res[3] = a[0] * b[3] + a[1] * b[8] + a[2] * b[13] + a[3] * b[18];\n    res[4] = a[0] * b[4] + a[1] * b[9] + a[2] * b[14] + a[3] * b[19] + a[4];\n    // G\n    res[5] = a[5] * b[0] + a[6] * b[5] + a[7] * b[10] + a[8] * b[15];\n    res[6] = a[5] * b[1] + a[6] * b[6] + a[7] * b[11] + a[8] * b[16];\n    res[7] = a[5] * b[2] + a[6] * b[7] + a[7] * b[12] + a[8] * b[17];\n    res[8] = a[5] * b[3] + a[6] * b[8] + a[7] * b[13] + a[8] * b[18];\n    res[9] = a[5] * b[4] + a[6] * b[9] + a[7] * b[14] + a[8] * b[19] + a[9];\n    // B\n    res[10] = a[10] * b[0] + a[11] * b[5] + a[12] * b[10] + a[13] * b[15];\n    res[11] = a[10] * b[1] + a[11] * b[6] + a[12] * b[11] + a[13] * b[16];\n    res[12] = a[10] * b[2] + a[11] * b[7] + a[12] * b[12] + a[13] * b[17];\n    res[13] = a[10] * b[3] + a[11] * b[8] + a[12] * b[13] + a[13] * b[18];\n    res[14] = a[10] * b[4] + a[11] * b[9] + a[12] * b[14] + a[13] * b[19] + a[14];\n    // A\n    res[15] = a[15] * b[0] + a[16] * b[5] + a[17] * b[10] + a[18] * b[15];\n    res[16] = a[15] * b[1] + a[16] * b[6] + a[17] * b[11] + a[18] * b[16];\n    res[17] = a[15] * b[2] + a[16] * b[7] + a[17] * b[12] + a[18] * b[17];\n    res[18] = a[15] * b[3] + a[16] * b[8] + a[17] * b[13] + a[18] * b[18];\n    res[19] = a[15] * b[4] + a[16] * b[9] + a[17] * b[14] + a[18] * b[19] + a[19];\n    return res;\n};\n\nvar getColorMatrixFromColorMatrices = (colorMatrices) => colorMatrices.length\n    ? colorMatrices.reduce((previous, current) => dotColorMatrix([...previous], current), colorMatrices.shift())\n    : [];\n\nvar roundFraction = (value, fr = 2) => Math.round(value * fr) / fr;\n\nvar getImageRedactionScaleFactor = (imageSize, redactionShapes) => {\n    const imageRes = imageSize.width * imageSize.height;\n    const maxShapeSize = redactionShapes.reduce((max, shape) => {\n        if (shape.width > max.width && shape.height > max.height) {\n            max.width = shape.width;\n            max.height = shape.height;\n        }\n        return max;\n    }, { width: 0, height: 0 });\n    const maxShapeRes = maxShapeSize.width * maxShapeSize.height;\n    const fraction = Math.max(0.5, 0.5 + (1 - maxShapeRes / imageRes) / 2);\n    return roundFraction(fraction, 5);\n};\n\n/** @returns {void} */\nfunction noop() {}\n\nconst identity = (x) => x;\n\n/**\n * @template T\n * @template S\n * @param {T} tar\n * @param {S} src\n * @returns {T & S}\n */\nfunction assign(tar, src) {\n\t// @ts-ignore\n\tfor (const k in src) tar[k] = src[k];\n\treturn /** @type {T & S} */ (tar);\n}\n\nfunction run(fn) {\n\treturn fn();\n}\n\nfunction blank_object() {\n\treturn Object.create(null);\n}\n\n/**\n * @param {Function[]} fns\n * @returns {void}\n */\nfunction run_all(fns) {\n\tfns.forEach(run);\n}\n\n/**\n * @param {any} thing\n * @returns {thing is Function}\n */\nfunction is_function(thing) {\n\treturn typeof thing === 'function';\n}\n\n/** @returns {boolean} */\nfunction safe_not_equal(a, b) {\n\treturn a != a ? b == b : a !== b || (a && typeof a === 'object') || typeof a === 'function';\n}\n\nlet src_url_equal_anchor;\n\n/**\n * @param {string} element_src\n * @param {string} url\n * @returns {boolean}\n */\nfunction src_url_equal(element_src, url) {\n\tif (element_src === url) return true;\n\tif (!src_url_equal_anchor) {\n\t\tsrc_url_equal_anchor = document.createElement('a');\n\t}\n\t// This is actually faster than doing URL(..).href\n\tsrc_url_equal_anchor.href = url;\n\treturn element_src === src_url_equal_anchor.href;\n}\n\n/** @returns {boolean} */\nfunction is_empty(obj) {\n\treturn Object.keys(obj).length === 0;\n}\n\nfunction subscribe(store, ...callbacks) {\n\tif (store == null) {\n\t\tfor (const callback of callbacks) {\n\t\t\tcallback(undefined);\n\t\t}\n\t\treturn noop;\n\t}\n\tconst unsub = store.subscribe(...callbacks);\n\treturn unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;\n}\n\n/**\n * Get the current value from a store by subscribing and immediately unsubscribing.\n *\n * https://svelte.dev/docs/svelte-store#get\n * @template T\n * @param {import('../store/public.js').Readable<T>} store\n * @returns {T}\n */\nfunction get_store_value(store) {\n\tlet value;\n\tsubscribe(store, (_) => (value = _))();\n\treturn value;\n}\n\n/** @returns {void} */\nfunction component_subscribe(component, store, callback) {\n\tcomponent.$$.on_destroy.push(subscribe(store, callback));\n}\n\nfunction create_slot(definition, ctx, $$scope, fn) {\n\tif (definition) {\n\t\tconst slot_ctx = get_slot_context(definition, ctx, $$scope, fn);\n\t\treturn definition[0](slot_ctx);\n\t}\n}\n\nfunction get_slot_context(definition, ctx, $$scope, fn) {\n\treturn definition[1] && fn ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) : $$scope.ctx;\n}\n\nfunction get_slot_changes(definition, $$scope, dirty, fn) {\n\tif (definition[2] && fn) {\n\t\tconst lets = definition[2](fn(dirty));\n\t\tif ($$scope.dirty === undefined) {\n\t\t\treturn lets;\n\t\t}\n\t\tif (typeof lets === 'object') {\n\t\t\tconst merged = [];\n\t\t\tconst len = Math.max($$scope.dirty.length, lets.length);\n\t\t\tfor (let i = 0; i < len; i += 1) {\n\t\t\t\tmerged[i] = $$scope.dirty[i] | lets[i];\n\t\t\t}\n\t\t\treturn merged;\n\t\t}\n\t\treturn $$scope.dirty | lets;\n\t}\n\treturn $$scope.dirty;\n}\n\n/** @returns {void} */\nfunction update_slot_base(\n\tslot,\n\tslot_definition,\n\tctx,\n\t$$scope,\n\tslot_changes,\n\tget_slot_context_fn\n) {\n\tif (slot_changes) {\n\t\tconst slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);\n\t\tslot.p(slot_context, slot_changes);\n\t}\n}\n\n/** @returns {any[] | -1} */\nfunction get_all_dirty_from_scope($$scope) {\n\tif ($$scope.ctx.length > 32) {\n\t\tconst dirty = [];\n\t\tconst length = $$scope.ctx.length / 32;\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tdirty[i] = -1;\n\t\t}\n\t\treturn dirty;\n\t}\n\treturn -1;\n}\n\n/** @returns {{}} */\nfunction exclude_internal_props(props) {\n\tconst result = {};\n\tfor (const k in props) if (k[0] !== '$') result[k] = props[k];\n\treturn result;\n}\n\n/** @returns {{}} */\nfunction compute_rest_props(props, keys) {\n\tconst rest = {};\n\tkeys = new Set(keys);\n\tfor (const k in props) if (!keys.has(k) && k[0] !== '$') rest[k] = props[k];\n\treturn rest;\n}\n\nfunction set_store_value(store, ret, value) {\n\tstore.set(value);\n\treturn ret;\n}\n\nfunction action_destroyer(action_result) {\n\treturn action_result && is_function(action_result.destroy) ? action_result.destroy : noop;\n}\n\nconst is_client = typeof window !== 'undefined';\n\n/** @type {() => number} */\nlet now = is_client ? () => window.performance.now() : () => Date.now();\n\nlet raf = is_client ? (cb) => requestAnimationFrame(cb) : noop;\n\nconst tasks = new Set();\n\n/**\n * @param {number} now\n * @returns {void}\n */\nfunction run_tasks(now) {\n\ttasks.forEach((task) => {\n\t\tif (!task.c(now)) {\n\t\t\ttasks.delete(task);\n\t\t\ttask.f();\n\t\t}\n\t});\n\tif (tasks.size !== 0) raf(run_tasks);\n}\n\n/**\n * Creates a new task that runs on each raf frame\n * until it returns a falsy value or is aborted\n * @param {import('./private.js').TaskCallback} callback\n * @returns {import('./private.js').Task}\n */\nfunction loop(callback) {\n\t/** @type {import('./private.js').TaskEntry} */\n\tlet task;\n\tif (tasks.size === 0) raf(run_tasks);\n\treturn {\n\t\tpromise: new Promise((fulfill) => {\n\t\t\ttasks.add((task = { c: callback, f: fulfill }));\n\t\t}),\n\t\tabort() {\n\t\t\ttasks.delete(task);\n\t\t}\n\t};\n}\n\n/** @type {typeof globalThis} */\nconst globals =\n\ttypeof window !== 'undefined'\n\t\t? window\n\t\t: typeof globalThis !== 'undefined'\n\t\t? globalThis\n\t\t: // @ts-ignore Node typings have this\n\t\t  global;\n\n/**\n * @param {Node} target\n * @param {Node} node\n * @returns {void}\n */\nfunction append(target, node) {\n\ttarget.appendChild(node);\n}\n\n/**\n * @param {Node} node\n * @returns {ShadowRoot | Document}\n */\nfunction get_root_for_style(node) {\n\tif (!node) return document;\n\tconst root = node.getRootNode ? node.getRootNode() : node.ownerDocument;\n\tif (root && /** @type {ShadowRoot} */ (root).host) {\n\t\treturn /** @type {ShadowRoot} */ (root);\n\t}\n\treturn node.ownerDocument;\n}\n\n/**\n * @param {Node} node\n * @returns {CSSStyleSheet}\n */\nfunction append_empty_stylesheet(node) {\n\tconst style_element = element('style');\n\t// For transitions to work without 'style-src: unsafe-inline' Content Security Policy,\n\t// these empty tags need to be allowed with a hash as a workaround until we move to the Web Animations API.\n\t// Using the hash for the empty string (for an empty tag) works in all browsers except Safari.\n\t// So as a workaround for the workaround, when we append empty style tags we set their content to /* empty */.\n\t// The hash 'sha256-9OlNO0DNEeaVzHL4RZwCLsBHA8WBQ8toBp/4F5XV2nc=' will then work even in Safari.\n\tstyle_element.textContent = '/* empty */';\n\tappend_stylesheet(get_root_for_style(node), style_element);\n\treturn style_element.sheet;\n}\n\n/**\n * @param {ShadowRoot | Document} node\n * @param {HTMLStyleElement} style\n * @returns {CSSStyleSheet}\n */\nfunction append_stylesheet(node, style) {\n\tappend(/** @type {Document} */ (node).head || node, style);\n\treturn style.sheet;\n}\n\n/**\n * @param {Node} target\n * @param {Node} node\n * @param {Node} [anchor]\n * @returns {void}\n */\nfunction insert(target, node, anchor) {\n\ttarget.insertBefore(node, anchor || null);\n}\n\n/**\n * @param {Node} node\n * @returns {void}\n */\nfunction detach(node) {\n\tif (node.parentNode) {\n\t\tnode.parentNode.removeChild(node);\n\t}\n}\n\n/**\n * @template {keyof HTMLElementTagNameMap} K\n * @param {K} name\n * @returns {HTMLElementTagNameMap[K]}\n */\nfunction element(name) {\n\treturn document.createElement(name);\n}\n\n/**\n * @template {keyof SVGElementTagNameMap} K\n * @param {K} name\n * @returns {SVGElement}\n */\nfunction svg_element(name) {\n\treturn document.createElementNS('http://www.w3.org/2000/svg', name);\n}\n\n/**\n * @param {string} data\n * @returns {Text}\n */\nfunction text(data) {\n\treturn document.createTextNode(data);\n}\n\n/**\n * @returns {Text} */\nfunction space() {\n\treturn text(' ');\n}\n\n/**\n * @returns {Text} */\nfunction empty() {\n\treturn text('');\n}\n\n/**\n * @param {EventTarget} node\n * @param {string} event\n * @param {EventListenerOrEventListenerObject} handler\n * @param {boolean | AddEventListenerOptions | EventListenerOptions} [options]\n * @returns {() => void}\n */\nfunction listen(node, event, handler, options) {\n\tnode.addEventListener(event, handler, options);\n\treturn () => node.removeEventListener(event, handler, options);\n}\n\n/**\n * @returns {(event: any) => any} */\nfunction prevent_default(fn) {\n\treturn function (event) {\n\t\tevent.preventDefault();\n\t\t// @ts-ignore\n\t\treturn fn.call(this, event);\n\t};\n}\n\n/**\n * @returns {(event: any) => any} */\nfunction stop_propagation(fn) {\n\treturn function (event) {\n\t\tevent.stopPropagation();\n\t\t// @ts-ignore\n\t\treturn fn.call(this, event);\n\t};\n}\n\n/**\n * @param {Element} node\n * @param {string} attribute\n * @param {string} [value]\n * @returns {void}\n */\nfunction attr(node, attribute, value) {\n\tif (value == null) node.removeAttribute(attribute);\n\telse if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value);\n}\n/**\n * List of attributes that should always be set through the attr method,\n * because updating them through the property setter doesn't work reliably.\n * In the example of `width`/`height`, the problem is that the setter only\n * accepts numeric values, but the attribute can also be set to a string like `50%`.\n * If this list becomes too big, rethink this approach.\n */\nconst always_set_through_set_attribute = ['width', 'height'];\n\n/**\n * @param {Element & ElementCSSInlineStyle} node\n * @param {{ [x: string]: string }} attributes\n * @returns {void}\n */\nfunction set_attributes(node, attributes) {\n\t// @ts-ignore\n\tconst descriptors = Object.getOwnPropertyDescriptors(node.__proto__);\n\tfor (const key in attributes) {\n\t\tif (attributes[key] == null) {\n\t\t\tnode.removeAttribute(key);\n\t\t} else if (key === 'style') {\n\t\t\tnode.style.cssText = attributes[key];\n\t\t} else if (key === '__value') {\n\t\t\t/** @type {any} */ (node).value = node[key] = attributes[key];\n\t\t} else if (\n\t\t\tdescriptors[key] &&\n\t\t\tdescriptors[key].set &&\n\t\t\talways_set_through_set_attribute.indexOf(key) === -1\n\t\t) {\n\t\t\tnode[key] = attributes[key];\n\t\t} else {\n\t\t\tattr(node, key, attributes[key]);\n\t\t}\n\t}\n}\n\n/**\n * @param {Record<string, unknown>} data_map\n * @returns {void}\n */\nfunction set_custom_element_data_map(node, data_map) {\n\tObject.keys(data_map).forEach((key) => {\n\t\tset_custom_element_data(node, key, data_map[key]);\n\t});\n}\n\n/**\n * @returns {void} */\nfunction set_custom_element_data(node, prop, value) {\n\tconst lower = prop.toLowerCase(); // for backwards compatibility with existing behavior we do lowercase first\n\tif (lower in node) {\n\t\tnode[lower] = typeof node[lower] === 'boolean' && value === '' ? true : value;\n\t} else if (prop in node) {\n\t\tnode[prop] = typeof node[prop] === 'boolean' && value === '' ? true : value;\n\t} else {\n\t\tattr(node, prop, value);\n\t}\n}\n\n/**\n * @param {string} tag\n */\nfunction set_dynamic_element_data(tag) {\n\treturn /-/.test(tag) ? set_custom_element_data_map : set_attributes;\n}\n\n/**\n * @param {Element} element\n * @returns {ChildNode[]}\n */\nfunction children(element) {\n\treturn Array.from(element.childNodes);\n}\n\n/**\n * @param {Text} text\n * @param {unknown} data\n * @returns {void}\n */\nfunction set_data(text, data) {\n\tdata = '' + data;\n\tif (text.data === data) return;\n\ttext.data = /** @type {string} */ (data);\n}\n\n/**\n * @returns {void} */\nfunction set_input_value(input, value) {\n\tinput.value = value == null ? '' : value;\n}\n\n/**\n * @returns {void} */\nfunction set_style(node, key, value, important) {\n\tif (value == null) {\n\t\tnode.style.removeProperty(key);\n\t} else {\n\t\tnode.style.setProperty(key, value, important ? 'important' : '');\n\t}\n}\n\n/**\n * @template T\n * @param {string} type\n * @param {T} [detail]\n * @param {{ bubbles?: boolean, cancelable?: boolean }} [options]\n * @returns {CustomEvent<T>}\n */\nfunction custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {\n\treturn new CustomEvent(type, { detail, bubbles, cancelable });\n}\n/** */\nclass HtmlTag {\n\t/**\n\t * @private\n\t * @default false\n\t */\n\tis_svg = false;\n\t/** parent for creating node */\n\te = undefined;\n\t/** html tag nodes */\n\tn = undefined;\n\t/** target */\n\tt = undefined;\n\t/** anchor */\n\ta = undefined;\n\tconstructor(is_svg = false) {\n\t\tthis.is_svg = is_svg;\n\t\tthis.e = this.n = null;\n\t}\n\n\t/**\n\t * @param {string} html\n\t * @returns {void}\n\t */\n\tc(html) {\n\t\tthis.h(html);\n\t}\n\n\t/**\n\t * @param {string} html\n\t * @param {HTMLElement | SVGElement} target\n\t * @param {HTMLElement | SVGElement} anchor\n\t * @returns {void}\n\t */\n\tm(html, target, anchor = null) {\n\t\tif (!this.e) {\n\t\t\tif (this.is_svg)\n\t\t\t\tthis.e = svg_element(/** @type {keyof SVGElementTagNameMap} */ (target.nodeName));\n\t\t\t/** #7364  target for <template> may be provided as #document-fragment(11) */ else\n\t\t\t\tthis.e = element(\n\t\t\t\t\t/** @type {keyof HTMLElementTagNameMap} */ (\n\t\t\t\t\t\ttarget.nodeType === 11 ? 'TEMPLATE' : target.nodeName\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\tthis.t =\n\t\t\t\ttarget.tagName !== 'TEMPLATE'\n\t\t\t\t\t? target\n\t\t\t\t\t: /** @type {HTMLTemplateElement} */ (target).content;\n\t\t\tthis.c(html);\n\t\t}\n\t\tthis.i(anchor);\n\t}\n\n\t/**\n\t * @param {string} html\n\t * @returns {void}\n\t */\n\th(html) {\n\t\tthis.e.innerHTML = html;\n\t\tthis.n = Array.from(\n\t\t\tthis.e.nodeName === 'TEMPLATE' ? this.e.content.childNodes : this.e.childNodes\n\t\t);\n\t}\n\n\t/**\n\t * @returns {void} */\n\ti(anchor) {\n\t\tfor (let i = 0; i < this.n.length; i += 1) {\n\t\t\tinsert(this.t, this.n[i], anchor);\n\t\t}\n\t}\n\n\t/**\n\t * @param {string} html\n\t * @returns {void}\n\t */\n\tp(html) {\n\t\tthis.d();\n\t\tthis.h(html);\n\t\tthis.i(this.a);\n\t}\n\n\t/**\n\t * @returns {void} */\n\td() {\n\t\tthis.n.forEach(detach);\n\t}\n}\n\nfunction construct_svelte_component(component, props) {\n\treturn new component(props);\n}\n\n/**\n * @typedef {Node & {\n * \tclaim_order?: number;\n * \thydrate_init?: true;\n * \tactual_end_child?: NodeEx;\n * \tchildNodes: NodeListOf<NodeEx>;\n * }} NodeEx\n */\n\n/** @typedef {ChildNode & NodeEx} ChildNodeEx */\n\n/** @typedef {NodeEx & { claim_order: number }} NodeEx2 */\n\n/**\n * @typedef {ChildNodeEx[] & {\n * \tclaim_info?: {\n * \t\tlast_index: number;\n * \t\ttotal_claimed: number;\n * \t};\n * }} ChildNodeArray\n */\n\n// we need to store the information for multiple documents because a Svelte application could also contain iframes\n// https://github.com/sveltejs/svelte/issues/3624\n/** @type {Map<Document | ShadowRoot, import('./private.d.ts').StyleInformation>} */\nconst managed_styles = new Map();\n\nlet active = 0;\n\n// https://github.com/darkskyapp/string-hash/blob/master/index.js\n/**\n * @param {string} str\n * @returns {number}\n */\nfunction hash(str) {\n\tlet hash = 5381;\n\tlet i = str.length;\n\twhile (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n\treturn hash >>> 0;\n}\n\n/**\n * @param {Document | ShadowRoot} doc\n * @param {Element & ElementCSSInlineStyle} node\n * @returns {{ stylesheet: any; rules: {}; }}\n */\nfunction create_style_information(doc, node) {\n\tconst info = { stylesheet: append_empty_stylesheet(node), rules: {} };\n\tmanaged_styles.set(doc, info);\n\treturn info;\n}\n\n/**\n * @param {Element & ElementCSSInlineStyle} node\n * @param {number} a\n * @param {number} b\n * @param {number} duration\n * @param {number} delay\n * @param {(t: number) => number} ease\n * @param {(t: number, u: number) => string} fn\n * @param {number} uid\n * @returns {string}\n */\nfunction create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {\n\tconst step = 16.666 / duration;\n\tlet keyframes = '{\\n';\n\tfor (let p = 0; p <= 1; p += step) {\n\t\tconst t = a + (b - a) * ease(p);\n\t\tkeyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n\t}\n\tconst rule = keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n\tconst name = `__svelte_${hash(rule)}_${uid}`;\n\tconst doc = get_root_for_style(node);\n\tconst { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node);\n\tif (!rules[name]) {\n\t\trules[name] = true;\n\t\tstylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);\n\t}\n\tconst animation = node.style.animation || '';\n\tnode.style.animation = `${\n\t\tanimation ? `${animation}, ` : ''\n\t}${name} ${duration}ms linear ${delay}ms 1 both`;\n\tactive += 1;\n\treturn name;\n}\n\n/**\n * @param {Element & ElementCSSInlineStyle} node\n * @param {string} [name]\n * @returns {void}\n */\nfunction delete_rule(node, name) {\n\tconst previous = (node.style.animation || '').split(', ');\n\tconst next = previous.filter(\n\t\tname\n\t\t\t? (anim) => anim.indexOf(name) < 0 // remove specific animation\n\t\t\t: (anim) => anim.indexOf('__svelte') === -1 // remove all Svelte animations\n\t);\n\tconst deleted = previous.length - next.length;\n\tif (deleted) {\n\t\tnode.style.animation = next.join(', ');\n\t\tactive -= deleted;\n\t\tif (!active) clear_rules();\n\t}\n}\n\n/** @returns {void} */\nfunction clear_rules() {\n\traf(() => {\n\t\tif (active) return;\n\t\tmanaged_styles.forEach((info) => {\n\t\t\tconst { ownerNode } = info.stylesheet;\n\t\t\t// there is no ownerNode if it runs on jsdom.\n\t\t\tif (ownerNode) detach(ownerNode);\n\t\t});\n\t\tmanaged_styles.clear();\n\t});\n}\n\nlet current_component;\n\n/** @returns {void} */\nfunction set_current_component(component) {\n\tcurrent_component = component;\n}\n\nfunction get_current_component() {\n\tif (!current_component) throw new Error('Function called outside component initialization');\n\treturn current_component;\n}\n\n/**\n * The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.\n * It must be called during the component's initialisation (but doesn't need to live *inside* the component;\n * it can be called from an external module).\n *\n * If a function is returned _synchronously_ from `onMount`, it will be called when the component is unmounted.\n *\n * `onMount` does not run inside a [server-side component](https://svelte.dev/docs#run-time-server-side-component-api).\n *\n * https://svelte.dev/docs/svelte#onmount\n * @template T\n * @param {() => import('./private.js').NotFunction<T> | Promise<import('./private.js').NotFunction<T>> | (() => any)} fn\n * @returns {void}\n */\nfunction onMount(fn) {\n\tget_current_component().$$.on_mount.push(fn);\n}\n\n/**\n * Schedules a callback to run immediately after the component has been updated.\n *\n * The first time the callback runs will be after the initial `onMount`\n *\n * https://svelte.dev/docs/svelte#afterupdate\n * @param {() => any} fn\n * @returns {void}\n */\nfunction afterUpdate(fn) {\n\tget_current_component().$$.after_update.push(fn);\n}\n\n/**\n * Schedules a callback to run immediately before the component is unmounted.\n *\n * Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the\n * only one that runs inside a server-side component.\n *\n * https://svelte.dev/docs/svelte#ondestroy\n * @param {() => any} fn\n * @returns {void}\n */\nfunction onDestroy(fn) {\n\tget_current_component().$$.on_destroy.push(fn);\n}\n\n/**\n * Creates an event dispatcher that can be used to dispatch [component events](https://svelte.dev/docs#template-syntax-component-directives-on-eventname).\n * Event dispatchers are functions that can take two arguments: `name` and `detail`.\n *\n * Component events created with `createEventDispatcher` create a\n * [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent).\n * These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture).\n * The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)\n * property and can contain any type of data.\n *\n * The event dispatcher can be typed to narrow the allowed event names and the type of the `detail` argument:\n * ```ts\n * const dispatch = createEventDispatcher<{\n *  loaded: never; // does not take a detail argument\n *  change: string; // takes a detail argument of type string, which is required\n *  optional: number | null; // takes an optional detail argument of type number\n * }>();\n * ```\n *\n * https://svelte.dev/docs/svelte#createeventdispatcher\n * @template {Record<string, any>} [EventMap=any]\n * @returns {import('./public.js').EventDispatcher<EventMap>}\n */\nfunction createEventDispatcher() {\n\tconst component = get_current_component();\n\treturn (type, detail, { cancelable = false } = {}) => {\n\t\tconst callbacks = component.$$.callbacks[type];\n\t\tif (callbacks) {\n\t\t\t// TODO are there situations where events could be dispatched\n\t\t\t// in a server (non-DOM) environment?\n\t\t\tconst event = custom_event(/** @type {string} */ (type), detail, { cancelable });\n\t\t\tcallbacks.slice().forEach((fn) => {\n\t\t\t\tfn.call(component, event);\n\t\t\t});\n\t\t\treturn !event.defaultPrevented;\n\t\t}\n\t\treturn true;\n\t};\n}\n\n/**\n * Associates an arbitrary `context` object with the current component and the specified `key`\n * and returns that object. The context is then available to children of the component\n * (including slotted content) with `getContext`.\n *\n * Like lifecycle functions, this must be called during component initialisation.\n *\n * https://svelte.dev/docs/svelte#setcontext\n * @template T\n * @param {any} key\n * @param {T} context\n * @returns {T}\n */\nfunction setContext(key, context) {\n\tget_current_component().$$.context.set(key, context);\n\treturn context;\n}\n\n/**\n * Retrieves the context that belongs to the closest parent component with the specified `key`.\n * Must be called during component initialisation.\n *\n * https://svelte.dev/docs/svelte#getcontext\n * @template T\n * @param {any} key\n * @returns {T}\n */\nfunction getContext(key) {\n\treturn get_current_component().$$.context.get(key);\n}\n\n/**\n * Retrieves the whole context map that belongs to the closest parent component.\n * Must be called during component initialisation. Useful, for example, if you\n * programmatically create a component and want to pass the existing context to it.\n *\n * https://svelte.dev/docs/svelte#getallcontexts\n * @template {Map<any, any>} [T=Map<any, any>]\n * @returns {T}\n */\nfunction getAllContexts() {\n\treturn get_current_component().$$.context;\n}\n\n// TODO figure out if we still want to support\n// shorthand events, or if we want to implement\n// a real bubbling mechanism\n/**\n * @param component\n * @param event\n * @returns {void}\n */\nfunction bubble(component, event) {\n\tconst callbacks = component.$$.callbacks[event.type];\n\tif (callbacks) {\n\t\t// @ts-ignore\n\t\tcallbacks.slice().forEach((fn) => fn.call(this, event));\n\t}\n}\n\nconst dirty_components = [];\nconst binding_callbacks = [];\n\nlet render_callbacks = [];\n\nconst flush_callbacks = [];\n\nconst resolved_promise = /* @__PURE__ */ Promise.resolve();\n\nlet update_scheduled = false;\n\n/** @returns {void} */\nfunction schedule_update() {\n\tif (!update_scheduled) {\n\t\tupdate_scheduled = true;\n\t\tresolved_promise.then(flush);\n\t}\n}\n\n/** @returns {Promise<void>} */\nfunction tick$1() {\n\tschedule_update();\n\treturn resolved_promise;\n}\n\n/** @returns {void} */\nfunction add_render_callback(fn) {\n\trender_callbacks.push(fn);\n}\n\n/** @returns {void} */\nfunction add_flush_callback(fn) {\n\tflush_callbacks.push(fn);\n}\n\n// flush() calls callbacks in this order:\n// 1. All beforeUpdate callbacks, in order: parents before children\n// 2. All bind:this callbacks, in reverse order: children before parents.\n// 3. All afterUpdate callbacks, in order: parents before children. EXCEPT\n//    for afterUpdates called during the initial onMount, which are called in\n//    reverse order: children before parents.\n// Since callbacks might update component values, which could trigger another\n// call to flush(), the following steps guard against this:\n// 1. During beforeUpdate, any updated components will be added to the\n//    dirty_components array and will cause a reentrant call to flush(). Because\n//    the flush index is kept outside the function, the reentrant call will pick\n//    up where the earlier call left off and go through all dirty components. The\n//    current_component value is saved and restored so that the reentrant call will\n//    not interfere with the \"parent\" flush() call.\n// 2. bind:this callbacks cannot trigger new flush() calls.\n// 3. During afterUpdate, any updated components will NOT have their afterUpdate\n//    callback called a second time; the seen_callbacks set, outside the flush()\n//    function, guarantees this behavior.\nconst seen_callbacks = new Set();\n\nlet flushidx = 0; // Do *not* move this inside the flush() function\n\n/** @returns {void} */\nfunction flush() {\n\t// Do not reenter flush while dirty components are updated, as this can\n\t// result in an infinite loop. Instead, let the inner flush handle it.\n\t// Reentrancy is ok afterwards for bindings etc.\n\tif (flushidx !== 0) {\n\t\treturn;\n\t}\n\tconst saved_component = current_component;\n\tdo {\n\t\t// first, call beforeUpdate functions\n\t\t// and update components\n\t\ttry {\n\t\t\twhile (flushidx < dirty_components.length) {\n\t\t\t\tconst component = dirty_components[flushidx];\n\t\t\t\tflushidx++;\n\t\t\t\tset_current_component(component);\n\t\t\t\tupdate(component.$$);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\t// reset dirty state to not end up in a deadlocked state and then rethrow\n\t\t\tdirty_components.length = 0;\n\t\t\tflushidx = 0;\n\t\t\tthrow e;\n\t\t}\n\t\tset_current_component(null);\n\t\tdirty_components.length = 0;\n\t\tflushidx = 0;\n\t\twhile (binding_callbacks.length) binding_callbacks.pop()();\n\t\t// then, once components are updated, call\n\t\t// afterUpdate functions. This may cause\n\t\t// subsequent updates...\n\t\tfor (let i = 0; i < render_callbacks.length; i += 1) {\n\t\t\tconst callback = render_callbacks[i];\n\t\t\tif (!seen_callbacks.has(callback)) {\n\t\t\t\t// ...so guard against infinite loops\n\t\t\t\tseen_callbacks.add(callback);\n\t\t\t\tcallback();\n\t\t\t}\n\t\t}\n\t\trender_callbacks.length = 0;\n\t} while (dirty_components.length);\n\twhile (flush_callbacks.length) {\n\t\tflush_callbacks.pop()();\n\t}\n\tupdate_scheduled = false;\n\tseen_callbacks.clear();\n\tset_current_component(saved_component);\n}\n\n/** @returns {void} */\nfunction update($$) {\n\tif ($$.fragment !== null) {\n\t\t$$.update();\n\t\trun_all($$.before_update);\n\t\tconst dirty = $$.dirty;\n\t\t$$.dirty = [-1];\n\t\t$$.fragment && $$.fragment.p($$.ctx, dirty);\n\t\t$$.after_update.forEach(add_render_callback);\n\t}\n}\n\n/**\n * Useful for example to execute remaining `afterUpdate` callbacks before executing `destroy`.\n * @param {Function[]} fns\n * @returns {void}\n */\nfunction flush_render_callbacks(fns) {\n\tconst filtered = [];\n\tconst targets = [];\n\trender_callbacks.forEach((c) => (fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c)));\n\ttargets.forEach((c) => c());\n\trender_callbacks = filtered;\n}\n\n/**\n * @type {Promise<void> | null}\n */\nlet promise;\n\n/**\n * @returns {Promise<void>}\n */\nfunction wait() {\n\tif (!promise) {\n\t\tpromise = Promise.resolve();\n\t\tpromise.then(() => {\n\t\t\tpromise = null;\n\t\t});\n\t}\n\treturn promise;\n}\n\n/**\n * @param {Element} node\n * @param {INTRO | OUTRO | boolean} direction\n * @param {'start' | 'end'} kind\n * @returns {void}\n */\nfunction dispatch(node, direction, kind) {\n\tnode.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`));\n}\n\nconst outroing = new Set();\n\n/**\n * @type {Outro}\n */\nlet outros;\n\n/**\n * @returns {void} */\nfunction group_outros() {\n\toutros = {\n\t\tr: 0,\n\t\tc: [],\n\t\tp: outros // parent group\n\t};\n}\n\n/**\n * @returns {void} */\nfunction check_outros() {\n\tif (!outros.r) {\n\t\trun_all(outros.c);\n\t}\n\toutros = outros.p;\n}\n\n/**\n * @param {import('./private.js').Fragment} block\n * @param {0 | 1} [local]\n * @returns {void}\n */\nfunction transition_in(block, local) {\n\tif (block && block.i) {\n\t\toutroing.delete(block);\n\t\tblock.i(local);\n\t}\n}\n\n/**\n * @param {import('./private.js').Fragment} block\n * @param {0 | 1} local\n * @param {0 | 1} [detach]\n * @param {() => void} [callback]\n * @returns {void}\n */\nfunction transition_out(block, local, detach, callback) {\n\tif (block && block.o) {\n\t\tif (outroing.has(block)) return;\n\t\toutroing.add(block);\n\t\toutros.c.push(() => {\n\t\t\toutroing.delete(block);\n\t\t\tif (callback) {\n\t\t\t\tif (detach) block.d(1);\n\t\t\t\tcallback();\n\t\t\t}\n\t\t});\n\t\tblock.o(local);\n\t} else if (callback) {\n\t\tcallback();\n\t}\n}\n\n/**\n * @type {import('../transition/public.js').TransitionConfig}\n */\nconst null_transition = { duration: 0 };\n\n/**\n * @param {Element & ElementCSSInlineStyle} node\n * @param {TransitionFn} fn\n * @param {any} params\n * @param {boolean} intro\n * @returns {{ run(b: 0 | 1): void; end(): void; }}\n */\nfunction create_bidirectional_transition(node, fn, params, intro) {\n\t/**\n\t * @type {TransitionOptions} */\n\tconst options = { direction: 'both' };\n\tlet config = fn(node, params, options);\n\tlet t = intro ? 0 : 1;\n\n\t/**\n\t * @type {Program | null} */\n\tlet running_program = null;\n\n\t/**\n\t * @type {PendingProgram | null} */\n\tlet pending_program = null;\n\tlet animation_name = null;\n\n\t/** @type {boolean} */\n\tlet original_inert_value;\n\n\t/**\n\t * @returns {void} */\n\tfunction clear_animation() {\n\t\tif (animation_name) delete_rule(node, animation_name);\n\t}\n\n\t/**\n\t * @param {PendingProgram} program\n\t * @param {number} duration\n\t * @returns {Program}\n\t */\n\tfunction init(program, duration) {\n\t\tconst d = /** @type {Program['d']} */ (program.b - t);\n\t\tduration *= Math.abs(d);\n\t\treturn {\n\t\t\ta: t,\n\t\t\tb: program.b,\n\t\t\td,\n\t\t\tduration,\n\t\t\tstart: program.start,\n\t\t\tend: program.start + duration,\n\t\t\tgroup: program.group\n\t\t};\n\t}\n\n\t/**\n\t * @param {INTRO | OUTRO} b\n\t * @returns {void}\n\t */\n\tfunction go(b) {\n\t\tconst {\n\t\t\tdelay = 0,\n\t\t\tduration = 300,\n\t\t\teasing = identity,\n\t\t\ttick = noop,\n\t\t\tcss\n\t\t} = config || null_transition;\n\n\t\t/**\n\t\t * @type {PendingProgram} */\n\t\tconst program = {\n\t\t\tstart: now() + delay,\n\t\t\tb\n\t\t};\n\n\t\tif (!b) {\n\t\t\t// @ts-ignore todo: improve typings\n\t\t\tprogram.group = outros;\n\t\t\toutros.r += 1;\n\t\t}\n\n\t\tif ('inert' in node) {\n\t\t\tif (b) {\n\t\t\t\tif (original_inert_value !== undefined) {\n\t\t\t\t\t// aborted/reversed outro \u2014 restore previous inert value\n\t\t\t\t\tnode.inert = original_inert_value;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toriginal_inert_value = /** @type {HTMLElement} */ (node).inert;\n\t\t\t\tnode.inert = true;\n\t\t\t}\n\t\t}\n\n\t\tif (running_program || pending_program) {\n\t\t\tpending_program = program;\n\t\t} else {\n\t\t\t// if this is an intro, and there's a delay, we need to do\n\t\t\t// an initial tick and/or apply CSS animation immediately\n\t\t\tif (css) {\n\t\t\t\tclear_animation();\n\t\t\t\tanimation_name = create_rule(node, t, b, duration, delay, easing, css);\n\t\t\t}\n\t\t\tif (b) tick(0, 1);\n\t\t\trunning_program = init(program, duration);\n\t\t\tadd_render_callback(() => dispatch(node, b, 'start'));\n\t\t\tloop((now) => {\n\t\t\t\tif (pending_program && now > pending_program.start) {\n\t\t\t\t\trunning_program = init(pending_program, duration);\n\t\t\t\t\tpending_program = null;\n\t\t\t\t\tdispatch(node, running_program.b, 'start');\n\t\t\t\t\tif (css) {\n\t\t\t\t\t\tclear_animation();\n\t\t\t\t\t\tanimation_name = create_rule(\n\t\t\t\t\t\t\tnode,\n\t\t\t\t\t\t\tt,\n\t\t\t\t\t\t\trunning_program.b,\n\t\t\t\t\t\t\trunning_program.duration,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\teasing,\n\t\t\t\t\t\t\tconfig.css\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (running_program) {\n\t\t\t\t\tif (now >= running_program.end) {\n\t\t\t\t\t\ttick((t = running_program.b), 1 - t);\n\t\t\t\t\t\tdispatch(node, running_program.b, 'end');\n\t\t\t\t\t\tif (!pending_program) {\n\t\t\t\t\t\t\t// we're done\n\t\t\t\t\t\t\tif (running_program.b) {\n\t\t\t\t\t\t\t\t// intro \u2014 we can tidy up immediately\n\t\t\t\t\t\t\t\tclear_animation();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// outro \u2014 needs to be coordinated\n\t\t\t\t\t\t\t\tif (!--running_program.group.r) run_all(running_program.group.c);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\trunning_program = null;\n\t\t\t\t\t} else if (now >= running_program.start) {\n\t\t\t\t\t\tconst p = now - running_program.start;\n\t\t\t\t\t\tt = running_program.a + running_program.d * easing(p / running_program.duration);\n\t\t\t\t\t\ttick(t, 1 - t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn !!(running_program || pending_program);\n\t\t\t});\n\t\t}\n\t}\n\treturn {\n\t\trun(b) {\n\t\t\tif (is_function(config)) {\n\t\t\t\twait().then(() => {\n\t\t\t\t\tconst opts = { direction: b ? 'in' : 'out' };\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tconfig = config(opts);\n\t\t\t\t\tgo(b);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tgo(b);\n\t\t\t}\n\t\t},\n\t\tend() {\n\t\t\tclear_animation();\n\t\t\trunning_program = pending_program = null;\n\t\t}\n\t};\n}\n\n/** @typedef {1} INTRO */\n/** @typedef {0} OUTRO */\n/** @typedef {{ direction: 'in' | 'out' | 'both' }} TransitionOptions */\n/** @typedef {(node: Element, params: any, options: TransitionOptions) => import('../transition/public.js').TransitionConfig} TransitionFn */\n\n/**\n * @typedef {Object} Outro\n * @property {number} r\n * @property {Function[]} c\n * @property {Object} p\n */\n\n/**\n * @typedef {Object} PendingProgram\n * @property {number} start\n * @property {INTRO|OUTRO} b\n * @property {Outro} [group]\n */\n\n/**\n * @typedef {Object} Program\n * @property {number} a\n * @property {INTRO|OUTRO} b\n * @property {1|-1} d\n * @property {number} duration\n * @property {number} start\n * @property {number} end\n * @property {Outro} [group]\n */\n\n// general each functions:\n\nfunction ensure_array_like(array_like_or_iterator) {\n\treturn array_like_or_iterator?.length !== undefined\n\t\t? array_like_or_iterator\n\t\t: Array.from(array_like_or_iterator);\n}\n\n// keyed each functions:\n\n/** @returns {void} */\nfunction destroy_block(block, lookup) {\n\tblock.d(1);\n\tlookup.delete(block.key);\n}\n\n/** @returns {void} */\nfunction outro_and_destroy_block(block, lookup) {\n\ttransition_out(block, 1, 1, () => {\n\t\tlookup.delete(block.key);\n\t});\n}\n\n/** @returns {any[]} */\nfunction update_keyed_each(\n\told_blocks,\n\tdirty,\n\tget_key,\n\tdynamic,\n\tctx,\n\tlist,\n\tlookup,\n\tnode,\n\tdestroy,\n\tcreate_each_block,\n\tnext,\n\tget_context\n) {\n\tlet o = old_blocks.length;\n\tlet n = list.length;\n\tlet i = o;\n\tconst old_indexes = {};\n\twhile (i--) old_indexes[old_blocks[i].key] = i;\n\tconst new_blocks = [];\n\tconst new_lookup = new Map();\n\tconst deltas = new Map();\n\tconst updates = [];\n\ti = n;\n\twhile (i--) {\n\t\tconst child_ctx = get_context(ctx, list, i);\n\t\tconst key = get_key(child_ctx);\n\t\tlet block = lookup.get(key);\n\t\tif (!block) {\n\t\t\tblock = create_each_block(key, child_ctx);\n\t\t\tblock.c();\n\t\t} else if (dynamic) {\n\t\t\t// defer updates until all the DOM shuffling is done\n\t\t\tupdates.push(() => block.p(child_ctx, dirty));\n\t\t}\n\t\tnew_lookup.set(key, (new_blocks[i] = block));\n\t\tif (key in old_indexes) deltas.set(key, Math.abs(i - old_indexes[key]));\n\t}\n\tconst will_move = new Set();\n\tconst did_move = new Set();\n\t/** @returns {void} */\n\tfunction insert(block) {\n\t\ttransition_in(block, 1);\n\t\tblock.m(node, next);\n\t\tlookup.set(block.key, block);\n\t\tnext = block.first;\n\t\tn--;\n\t}\n\twhile (o && n) {\n\t\tconst new_block = new_blocks[n - 1];\n\t\tconst old_block = old_blocks[o - 1];\n\t\tconst new_key = new_block.key;\n\t\tconst old_key = old_block.key;\n\t\tif (new_block === old_block) {\n\t\t\t// do nothing\n\t\t\tnext = new_block.first;\n\t\t\to--;\n\t\t\tn--;\n\t\t} else if (!new_lookup.has(old_key)) {\n\t\t\t// remove old block\n\t\t\tdestroy(old_block, lookup);\n\t\t\to--;\n\t\t} else if (!lookup.has(new_key) || will_move.has(new_key)) {\n\t\t\tinsert(new_block);\n\t\t} else if (did_move.has(old_key)) {\n\t\t\to--;\n\t\t} else if (deltas.get(new_key) > deltas.get(old_key)) {\n\t\t\tdid_move.add(new_key);\n\t\t\tinsert(new_block);\n\t\t} else {\n\t\t\twill_move.add(old_key);\n\t\t\to--;\n\t\t}\n\t}\n\twhile (o--) {\n\t\tconst old_block = old_blocks[o];\n\t\tif (!new_lookup.has(old_block.key)) destroy(old_block, lookup);\n\t}\n\twhile (n) insert(new_blocks[n - 1]);\n\trun_all(updates);\n\treturn new_blocks;\n}\n\n/** @returns {{}} */\nfunction get_spread_update(levels, updates) {\n\tconst update = {};\n\tconst to_null_out = {};\n\tconst accounted_for = { $$scope: 1 };\n\tlet i = levels.length;\n\twhile (i--) {\n\t\tconst o = levels[i];\n\t\tconst n = updates[i];\n\t\tif (n) {\n\t\t\tfor (const key in o) {\n\t\t\t\tif (!(key in n)) to_null_out[key] = 1;\n\t\t\t}\n\t\t\tfor (const key in n) {\n\t\t\t\tif (!accounted_for[key]) {\n\t\t\t\t\tupdate[key] = n[key];\n\t\t\t\t\taccounted_for[key] = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlevels[i] = n;\n\t\t} else {\n\t\t\tfor (const key in o) {\n\t\t\t\taccounted_for[key] = 1;\n\t\t\t}\n\t\t}\n\t}\n\tfor (const key in to_null_out) {\n\t\tif (!(key in update)) update[key] = undefined;\n\t}\n\treturn update;\n}\n\nfunction get_spread_object(spread_props) {\n\treturn typeof spread_props === 'object' && spread_props !== null ? spread_props : {};\n}\n\n/** @returns {void} */\nfunction bind(component, name, callback) {\n\tconst index = component.$$.props[name];\n\tif (index !== undefined) {\n\t\tcomponent.$$.bound[index] = callback;\n\t\tcallback(component.$$.ctx[index]);\n\t}\n}\n\n/** @returns {void} */\nfunction create_component(block) {\n\tblock && block.c();\n}\n\n/** @returns {void} */\nfunction mount_component(component, target, anchor) {\n\tconst { fragment, after_update } = component.$$;\n\tfragment && fragment.m(target, anchor);\n\t// onMount happens before the initial afterUpdate\n\tadd_render_callback(() => {\n\t\tconst new_on_destroy = component.$$.on_mount.map(run).filter(is_function);\n\t\t// if the component was destroyed immediately\n\t\t// it will update the `$$.on_destroy` reference to `null`.\n\t\t// the destructured on_destroy may still reference to the old array\n\t\tif (component.$$.on_destroy) {\n\t\t\tcomponent.$$.on_destroy.push(...new_on_destroy);\n\t\t} else {\n\t\t\t// Edge case - component was destroyed immediately,\n\t\t\t// most likely as a result of a binding initialising\n\t\t\trun_all(new_on_destroy);\n\t\t}\n\t\tcomponent.$$.on_mount = [];\n\t});\n\tafter_update.forEach(add_render_callback);\n}\n\n/** @returns {void} */\nfunction destroy_component(component, detaching) {\n\tconst $$ = component.$$;\n\tif ($$.fragment !== null) {\n\t\tflush_render_callbacks($$.after_update);\n\t\trun_all($$.on_destroy);\n\t\t$$.fragment && $$.fragment.d(detaching);\n\t\t// TODO null out other refs, including component.$$ (but need to\n\t\t// preserve final state?)\n\t\t$$.on_destroy = $$.fragment = null;\n\t\t$$.ctx = [];\n\t}\n}\n\n/** @returns {void} */\nfunction make_dirty(component, i) {\n\tif (component.$$.dirty[0] === -1) {\n\t\tdirty_components.push(component);\n\t\tschedule_update();\n\t\tcomponent.$$.dirty.fill(0);\n\t}\n\tcomponent.$$.dirty[(i / 31) | 0] |= 1 << i % 31;\n}\n\n// TODO: Document the other params\n/**\n * @param {SvelteComponent} component\n * @param {import('./public.js').ComponentConstructorOptions} options\n *\n * @param {import('./utils.js')['not_equal']} not_equal Used to compare props and state values.\n * @param {(target: Element | ShadowRoot) => void} [append_styles] Function that appends styles to the DOM when the component is first initialised.\n * This will be the `add_css` function from the compiled component.\n *\n * @returns {void}\n */\nfunction init(\n\tcomponent,\n\toptions,\n\tinstance,\n\tcreate_fragment,\n\tnot_equal,\n\tprops,\n\tappend_styles = null,\n\tdirty = [-1]\n) {\n\tconst parent_component = current_component;\n\tset_current_component(component);\n\t/** @type {import('./private.js').T$$} */\n\tconst $$ = (component.$$ = {\n\t\tfragment: null,\n\t\tctx: [],\n\t\t// state\n\t\tprops,\n\t\tupdate: noop,\n\t\tnot_equal,\n\t\tbound: blank_object(),\n\t\t// lifecycle\n\t\ton_mount: [],\n\t\ton_destroy: [],\n\t\ton_disconnect: [],\n\t\tbefore_update: [],\n\t\tafter_update: [],\n\t\tcontext: new Map(options.context || (parent_component ? parent_component.$$.context : [])),\n\t\t// everything else\n\t\tcallbacks: blank_object(),\n\t\tdirty,\n\t\tskip_bound: false,\n\t\troot: options.target || parent_component.$$.root\n\t});\n\tappend_styles && append_styles($$.root);\n\tlet ready = false;\n\t$$.ctx = instance\n\t\t? instance(component, options.props || {}, (i, ret, ...rest) => {\n\t\t\t\tconst value = rest.length ? rest[0] : ret;\n\t\t\t\tif ($$.ctx && not_equal($$.ctx[i], ($$.ctx[i] = value))) {\n\t\t\t\t\tif (!$$.skip_bound && $$.bound[i]) $$.bound[i](value);\n\t\t\t\t\tif (ready) make_dirty(component, i);\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t  })\n\t\t: [];\n\t$$.update();\n\tready = true;\n\trun_all($$.before_update);\n\t// `false` as a special case of no DOM component\n\t$$.fragment = create_fragment ? create_fragment($$.ctx) : false;\n\tif (options.target) {\n\t\tif (options.hydrate) {\n\t\t\t// TODO: what is the correct type here?\n\t\t\t// @ts-expect-error\n\t\t\tconst nodes = children(options.target);\n\t\t\t$$.fragment && $$.fragment.l(nodes);\n\t\t\tnodes.forEach(detach);\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t$$.fragment && $$.fragment.c();\n\t\t}\n\t\tif (options.intro) transition_in(component.$$.fragment);\n\t\tmount_component(component, options.target, options.anchor);\n\t\tflush();\n\t}\n\tset_current_component(parent_component);\n}\n\n/**\n * Base class for Svelte components. Used when dev=false.\n *\n * @template {Record<string, any>} [Props=any]\n * @template {Record<string, any>} [Events=any]\n */\nclass SvelteComponent {\n\t/**\n\t * ### PRIVATE API\n\t *\n\t * Do not use, may change at any time\n\t *\n\t * @type {any}\n\t */\n\t$$ = undefined;\n\t/**\n\t * ### PRIVATE API\n\t *\n\t * Do not use, may change at any time\n\t *\n\t * @type {any}\n\t */\n\t$$set = undefined;\n\n\t/** @returns {void} */\n\t$destroy() {\n\t\tdestroy_component(this, 1);\n\t\tthis.$destroy = noop;\n\t}\n\n\t/**\n\t * @template {Extract<keyof Events, string>} K\n\t * @param {K} type\n\t * @param {((e: Events[K]) => void) | null | undefined} callback\n\t * @returns {() => void}\n\t */\n\t$on(type, callback) {\n\t\tif (!is_function(callback)) {\n\t\t\treturn noop;\n\t\t}\n\t\tconst callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);\n\t\tcallbacks.push(callback);\n\t\treturn () => {\n\t\t\tconst index = callbacks.indexOf(callback);\n\t\t\tif (index !== -1) callbacks.splice(index, 1);\n\t\t};\n\t}\n\n\t/**\n\t * @param {Partial<Props>} props\n\t * @returns {void}\n\t */\n\t$set(props) {\n\t\tif (this.$$set && !is_empty(props)) {\n\t\t\tthis.$$.skip_bound = true;\n\t\t\tthis.$$set(props);\n\t\t\tthis.$$.skip_bound = false;\n\t\t}\n\t}\n}\n\n/**\n * @typedef {Object} CustomElementPropDefinition\n * @property {string} [attribute]\n * @property {boolean} [reflect]\n * @property {'String'|'Boolean'|'Number'|'Array'|'Object'} [type]\n */\n\n// generated during release, do not modify\nconst PUBLIC_VERSION = '4';\n\nconst subscriber_queue = [];\n\n/**\n * Creates a `Readable` store that allows reading by subscription.\n *\n * https://svelte.dev/docs/svelte-store#readable\n * @template T\n * @param {T} [value] initial value\n * @param {import('./public.js').StartStopNotifier<T>} [start]\n * @returns {import('./public.js').Readable<T>}\n */\nfunction readable(value, start) {\n\treturn {\n\t\tsubscribe: writable(value, start).subscribe\n\t};\n}\n\n/**\n * Create a `Writable` store that allows both updating and reading by subscription.\n *\n * https://svelte.dev/docs/svelte-store#writable\n * @template T\n * @param {T} [value] initial value\n * @param {import('./public.js').StartStopNotifier<T>} [start]\n * @returns {import('./public.js').Writable<T>}\n */\nfunction writable(value, start = noop) {\n\t/** @type {import('./public.js').Unsubscriber} */\n\tlet stop;\n\t/** @type {Set<import('./private.js').SubscribeInvalidateTuple<T>>} */\n\tconst subscribers = new Set();\n\t/** @param {T} new_value\n\t * @returns {void}\n\t */\n\tfunction set(new_value) {\n\t\tif (safe_not_equal(value, new_value)) {\n\t\t\tvalue = new_value;\n\t\t\tif (stop) {\n\t\t\t\t// store is ready\n\t\t\t\tconst run_queue = !subscriber_queue.length;\n\t\t\t\tfor (const subscriber of subscribers) {\n\t\t\t\t\tsubscriber[1]();\n\t\t\t\t\tsubscriber_queue.push(subscriber, value);\n\t\t\t\t}\n\t\t\t\tif (run_queue) {\n\t\t\t\t\tfor (let i = 0; i < subscriber_queue.length; i += 2) {\n\t\t\t\t\t\tsubscriber_queue[i][0](subscriber_queue[i + 1]);\n\t\t\t\t\t}\n\t\t\t\t\tsubscriber_queue.length = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @param {import('./public.js').Updater<T>} fn\n\t * @returns {void}\n\t */\n\tfunction update(fn) {\n\t\tset(fn(value));\n\t}\n\n\t/**\n\t * @param {import('./public.js').Subscriber<T>} run\n\t * @param {import('./private.js').Invalidator<T>} [invalidate]\n\t * @returns {import('./public.js').Unsubscriber}\n\t */\n\tfunction subscribe(run, invalidate = noop) {\n\t\t/** @type {import('./private.js').SubscribeInvalidateTuple<T>} */\n\t\tconst subscriber = [run, invalidate];\n\t\tsubscribers.add(subscriber);\n\t\tif (subscribers.size === 1) {\n\t\t\tstop = start(set, update) || noop;\n\t\t}\n\t\trun(value);\n\t\treturn () => {\n\t\t\tsubscribers.delete(subscriber);\n\t\t\tif (subscribers.size === 0 && stop) {\n\t\t\t\tstop();\n\t\t\t\tstop = null;\n\t\t\t}\n\t\t};\n\t}\n\treturn { set, update, subscribe };\n}\n\n/**\n * Derived value store by synchronizing one or more readable stores and\n * applying an aggregation function over its input values.\n *\n * https://svelte.dev/docs/svelte-store#derived\n * @template {import('./private.js').Stores} S\n * @template T\n * @overload\n * @param {S} stores - input stores\n * @param {(values: import('./private.js').StoresValues<S>, set: (value: T) => void, update: (fn: import('./public.js').Updater<T>) => void) => import('./public.js').Unsubscriber | void} fn - function callback that aggregates the values\n * @param {T} [initial_value] - initial value\n * @returns {import('./public.js').Readable<T>}\n */\n\n/**\n * Derived value store by synchronizing one or more readable stores and\n * applying an aggregation function over its input values.\n *\n * https://svelte.dev/docs/svelte-store#derived\n * @template {import('./private.js').Stores} S\n * @template T\n * @overload\n * @param {S} stores - input stores\n * @param {(values: import('./private.js').StoresValues<S>) => T} fn - function callback that aggregates the values\n * @param {T} [initial_value] - initial value\n * @returns {import('./public.js').Readable<T>}\n */\n\n/**\n * @template {import('./private.js').Stores} S\n * @template T\n * @param {S} stores\n * @param {Function} fn\n * @param {T} [initial_value]\n * @returns {import('./public.js').Readable<T>}\n */\nfunction derived(stores, fn, initial_value) {\n\tconst single = !Array.isArray(stores);\n\t/** @type {Array<import('./public.js').Readable<any>>} */\n\tconst stores_array = single ? [stores] : stores;\n\tif (!stores_array.every(Boolean)) {\n\t\tthrow new Error('derived() expects stores as input, got a falsy value');\n\t}\n\tconst auto = fn.length < 2;\n\treturn readable(initial_value, (set, update) => {\n\t\tlet started = false;\n\t\tconst values = [];\n\t\tlet pending = 0;\n\t\tlet cleanup = noop;\n\t\tconst sync = () => {\n\t\t\tif (pending) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcleanup();\n\t\t\tconst result = fn(single ? values[0] : values, set, update);\n\t\t\tif (auto) {\n\t\t\t\tset(result);\n\t\t\t} else {\n\t\t\t\tcleanup = is_function(result) ? result : noop;\n\t\t\t}\n\t\t};\n\t\tconst unsubscribers = stores_array.map((store, i) =>\n\t\t\tsubscribe(\n\t\t\t\tstore,\n\t\t\t\t(value) => {\n\t\t\t\t\tvalues[i] = value;\n\t\t\t\t\tpending &= ~(1 << i);\n\t\t\t\t\tif (started) {\n\t\t\t\t\t\tsync();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t() => {\n\t\t\t\t\tpending |= 1 << i;\n\t\t\t\t}\n\t\t\t)\n\t\t);\n\t\tstarted = true;\n\t\tsync();\n\t\treturn function stop() {\n\t\t\trun_all(unsubscribers);\n\t\t\tcleanup();\n\t\t\t// We need to set this to false because callbacks can still happen despite having unsubscribed:\n\t\t\t// Callbacks might already be placed in the queue which doesn't know it should no longer\n\t\t\t// invoke this derived store.\n\t\t\tstarted = false;\n\t\t};\n\t});\n}\n\nvar mergeObjects = (objects) => objects.reduce((prev, curr) => Object.assign(prev, curr), {});\n\n// @ts-ignore\nconst UPDATE_VALUE = (updateValue) => ({ updateValue });\nconst DEFAULT_VALUE = (defaultValue) => ({ defaultValue });\nconst CUSTOM_STORE = (fn) => ({ store: fn });\n// @ts-ignore (fixes error thrown in karma typescript)\nconst DERIVED_STORE = (fn) => ({ store: (defaultValue, stores) => derived(...fn(stores)) });\nconst UNIQUE_DERIVED_STORE = (fn) => ({\n    store: (defaultValue, stores) => {\n        const [selectedStores, update, isEqual = () => false] = fn(stores);\n        let isFirst = true;\n        let currentValue;\n        return derived(selectedStores, (storeValues, set) => {\n            update(storeValues, (value) => {\n                if (!isFirst && isEqual(currentValue, value))\n                    return;\n                currentValue = value;\n                isFirst = false;\n                set(value);\n            });\n        });\n    },\n});\nconst MAP_STORE = (fn) => ({\n    store: (defaultValue, stores) => {\n        const [valueMapper, observedStores = {}, sorter = undefined] = fn(stores);\n        let storedItems = [];\n        const $observedStores = {};\n        const mapValue = (item) => valueMapper(item, $observedStores);\n        // set default properties for each item\n        const setValue = (items) => {\n            // was empty, still empty\n            if (!storedItems.length && !items.length)\n                return;\n            // update value\n            storedItems = items;\n            updateValue();\n        };\n        const updateValue = () => {\n            const mappedItems = storedItems.map(mapValue);\n            if (sorter)\n                mappedItems.sort(sorter);\n            storedItems = [...mappedItems];\n            set(mappedItems);\n        };\n        // TODO: need to at some point unsub from these stores\n        Object.entries(observedStores).map(([name, store]) => {\n            return store.subscribe((value) => {\n                $observedStores[name] = value;\n                if (!value)\n                    return;\n                updateValue();\n            });\n        });\n        const { subscribe, set } = writable(defaultValue || []);\n        return {\n            set: setValue,\n            update: (fn) => setValue(fn(storedItems)),\n            subscribe,\n        };\n    },\n});\nconst createStore$1 = (accessors, stores, options) => {\n    const { store = (defaultValue) => writable(defaultValue), defaultValue = noop$1, // should be a function returning the default value\n    updateValue = undefined, } = options;\n    // create our private store\n    const storeInstance = store(defaultValue(), stores, accessors);\n    const { subscribe, update = noop$1 } = storeInstance; // update = noop because not all stores can be updated\n    // on update private store\n    let unsub;\n    const onUpdate = (cb) => {\n        let ignoreFirstCallback = true;\n        if (unsub)\n            unsub();\n        unsub = subscribe((value) => {\n            // need to ignore first callback because that returns current value\n            if (ignoreFirstCallback)\n                return (ignoreFirstCallback = false);\n            // now we have the newly assigned value\n            cb(value);\n            unsub();\n            unsub = undefined;\n        });\n    };\n    // create the value updater function, needs access to stores so can read all store values\n    const updateStoreValue = updateValue ? updateValue(accessors) : passthrough;\n    // set and validate value\n    storeInstance.set = (nextValue) => update((previousValue) => updateStoreValue(nextValue, previousValue, onUpdate));\n    // set default value for external reference\n    storeInstance.defaultValue = defaultValue;\n    // expose store api\n    return storeInstance;\n};\nvar createStores = (props) => {\n    const stores = {};\n    const accessors = {};\n    props.forEach(([name, ...options]) => {\n        const opts = mergeObjects(options);\n        const store = (stores[name] = createStore$1(accessors, stores, opts));\n        const property = {\n            get: () => get_store_value(store),\n            set: store.set,\n        };\n        Object.defineProperty(accessors, name, property);\n    });\n    return {\n        stores,\n        accessors,\n    };\n};\n\n// custom source store so we only trigger update when src changes\nconst sourceStore = () => {\n    // inner value\n    let value;\n    const { subscribe, set } = writable();\n    const _set = (newValue) => {\n        // is equal, bounce!\n        if (value === newValue)\n            return;\n        value = newValue;\n        set(value);\n    };\n    const _update = (fn) => _set(fn(value));\n    return {\n        set: _set,\n        subscribe,\n        update: _update,\n    };\n};\nvar props = [\n    // io\n    ['src', CUSTOM_STORE(sourceStore)], // takes source of image and loads it to images\n    ['imageReader'], // steps used to read the input image,\n    ['imageWriter'], // steps used to generate the output image\n    // will scramble image data for use with image redaction logic\n    ['imageScrambler'],\n    // should we render a smooth or pixelated redaction\n    ['imageRedactionRendering', DEFAULT_VALUE(() => 'pixelated')],\n    // current images\n    ['images', DEFAULT_VALUE(() => [])],\n    // will process markup items before rendering, used by arrows and frames\n    ['shapePreprocessor'],\n    // will be called when requesting a resource, return false to prevent loading, receives URL and XHR\n    ['willRequestResource'] /* deprecated */,\n    // will be called when requesting a resource, receives URL and requestType\n    // return false to prevent loading\n    // return object with options to update request\n    // return undefined to continue as normal\n    ['willRequest'],\n    // can contain `styleNonce`\n    ['csp'],\n];\n\nvar capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);\n\nvar defineMethods = (object, api) => {\n    Object.keys(api).forEach((name) => {\n        const descriptor = isFunction(api[name])\n            ? {\n                value: api[name],\n                writable: false,\n            }\n            : api[name];\n        Object.defineProperty(object, name, descriptor);\n    });\n};\n\n// TODO: replace with pointInPoly from geom, this function works correctly with \"offsetRectToFitPolygon\" but doesn't always work correctly, the pointInPoly from geom does work correctly but causes offsetRectToFitPolygon to sometimes work incorrectly, needs to be cleaned up in the future\nconst pointInPoly = (point, vertices) => {\n    let i;\n    let a;\n    let b;\n    let aX;\n    let aY;\n    let bX;\n    let bY;\n    let edgeX;\n    let edgeY;\n    let d;\n    const l = vertices.length;\n    for (i = 0; i < l; i++) {\n        // current vertex\n        a = vertices[i];\n        // next vertex\n        b = vertices[i + 1 > l - 1 ? 0 : i + 1];\n        // translate so that point is the origin of the calculation\n        aX = a.x - point.x;\n        aY = a.y - point.y;\n        bX = b.x - point.x;\n        bY = b.y - point.y;\n        edgeX = aX - bX;\n        edgeY = aY - bY;\n        d = edgeX * aY - edgeY * aX;\n        // 0 is ON the edge, but we check for -0.00001 to fix floating point errors\n        if (d < -0.00001)\n            return false;\n    }\n    return true;\n};\nconst scalar = 10000;\nvar offsetRectToFitPolygon = (rect, poly) => {\n    const polyLines = quadLines(poly);\n    const offset = vectorCreateEmpty();\n    const rectVertexes = rectGetCorners(rect);\n    // we can fit it\n    rectVertexes.forEach((vertex) => {\n        // we update each corner by adding the current offset\n        vectorAdd(vertex, offset);\n        // test if point lies in polygon, if so, all is fine and we can exit\n        if (pointInPoly(vertex, poly))\n            return;\n        polyLines.forEach((line) => {\n            // get angle of edge and draw a ray from the corner perpendicular to the edge\n            const a = Math.atan2(line.start.y - line.end.y, line.start.x - line.end.x);\n            const x = Math.sin(Math.PI - a) * scalar;\n            const y = Math.cos(Math.PI - a) * scalar;\n            const ray = vectorCreate(vertex.x + x, vertex.y + y);\n            // extend the poly line so even if we overshoot the polygon we hit it\n            const lineExtended = lineExtend(lineClone(line), scalar);\n            // get the resulting intersection (there's always an intersection)\n            const intersection = lineLineIntersection(lineCreate(vertex, ray), lineExtended);\n            // no intersection, no need to do anything\n            if (!intersection)\n                return;\n            // update offset to move towards image\n            vectorAdd(offset, vectorSubtract(vectorClone(intersection), vertex));\n        });\n    });\n    // test if any vertexes still fall outside of poly, if so, we can't fit the rect\n    const rectOffset = rectClone(rect);\n    vectorAdd(rectOffset, offset);\n    const rectOffsetVertices = rectGetCorners(rectOffset);\n    const fits = rectOffsetVertices.every((vertex) => pointInPoly(vertex, poly));\n    if (fits) {\n        rectUpdateWithRect(rect, rectOffset);\n        return true;\n    }\n    return false;\n};\n\nvar limitCropRectToImage = (rect, poly) => {\n    // get crop rect polygon vertexes\n    const rectVertexes = rectGetCorners(rect);\n    // if we end up here it doesn't fit, we might need to adjust\n    const polyLines = quadToLines(poly, 5);\n    const rectCenterPosition = rectCenter(rect);\n    const intersections = [];\n    rectVertexes.forEach((rectVertex) => {\n        const ray = lineMultiply(lineCreate(vectorClone(rectCenterPosition), vectorClone(rectVertex)), 1000000);\n        let intersectionFound = false;\n        polyLines.map(lineClone).forEach((line) => {\n            const intersection = lineLineIntersection(ray, line);\n            if (!intersection || intersectionFound)\n                return;\n            intersections.push(intersection);\n            intersectionFound = true;\n        });\n    });\n    // top left -> bottom right\n    const tlbr = vectorDistance(intersections[0], intersections[2]);\n    // top right -> bottom left\n    const trbl = vectorDistance(intersections[1], intersections[3]);\n    // calculate smallest rectangle we can make, use that\n    const rectLimitedVertices = tlbr < trbl ? [intersections[0], intersections[2]] : [intersections[1], intersections[3]];\n    const rectLimitedToPolygon = rectCreateFromPoints(rectLimitedVertices);\n    // only use our fitted crop rectangle if it's smaller than our current rectangle,\n    // this would mean that our current rectangle couldn't be moved to make it fit\n    if (rectLimitedToPolygon.width < rect.width) {\n        // need to center on previous rect\n        rectUpdateWithRect(rect, rectLimitedToPolygon);\n        return true;\n    }\n    return false;\n};\n\nvar getImagePolygon = (image, imageRotation, imagePerspective = { x: 0, y: 0 }) => {\n    const imageRect = rectCreateFromSize(image);\n    const imageCenter = rectCenter(imageRect);\n    const imagePoly = rectApplyPerspective(imageRect, imagePerspective, imageCenter).map((imageVertex) => vectorRotate(imageVertex, imageRotation, imageCenter));\n    // get image poly bounds, we need this to offset the poly vertices from 0,0\n    const imagePolyBounds = rectCreateFromPoints(imagePoly);\n    // get image polygon vertexes\n    return imagePoly.map((imageVertex) => vectorSubtract(imageVertex, imagePolyBounds));\n};\n\nvar getMaxSizeInRect = (size, rotation = 0, aspectRatio = rectAspectRatio(size)) => {\n    let width;\n    let height;\n    if (rotation !== 0) {\n        const innerAngle = Math.atan2(1, aspectRatio);\n        const rotationSigned = Math.sign(rotation) * rotation;\n        const rotationSignedMod = rotationSigned % Math.PI;\n        const rotationSignedModHalf = rotationSigned % HALF_PI;\n        // determine if is turned on side\n        let r;\n        if (rotationSignedMod > QUART_PI && rotationSignedMod < HALF_PI + QUART_PI) {\n            r = rotationSignedModHalf > QUART_PI ? rotationSigned : HALF_PI - rotationSignedModHalf;\n        }\n        else {\n            r = rotationSignedModHalf > QUART_PI ? HALF_PI - rotationSignedModHalf : rotationSigned;\n        }\n        const hyp = Math.min(Math.abs(size.height / Math.sin(innerAngle + r)), Math.abs(size.width / Math.cos(innerAngle - r)));\n        width = Math.cos(innerAngle) * hyp;\n        height = width / aspectRatio;\n    }\n    else {\n        width = size.width;\n        height = width / aspectRatio;\n        if (height > size.height) {\n            height = size.height;\n            width = height * aspectRatio;\n        }\n    }\n    return sizeCreate(width, height);\n};\n\nvar limitRectToImage = (rect, imageSize, imageRotation = 0, imagePerspective = vectorCreateEmpty(), minSize) => {\n    // rotation and/or perspective, let's use the \"advanced\" collision detection method\n    if ((isNumber(imageRotation) && imageRotation !== 0) ||\n        imagePerspective.x ||\n        imagePerspective.y) {\n        const inputAspectRatio = rectAspectRatio(rect);\n        // test if crop can fit image, if it can, offset the crop so it fits\n        const imagePolygon = getImagePolygon(imageSize, imageRotation, imagePerspective);\n        const maxSizeInRect = getMaxSizeInRect(imageSize, imageRotation, inputAspectRatio);\n        const canFit = rect.width < maxSizeInRect.width && rect.height < maxSizeInRect.height;\n        if (!canFit) {\n            const dx = rect.width * 0.5 - maxSizeInRect.width * 0.5;\n            const dy = rect.height * 0.5 - maxSizeInRect.height * 0.5;\n            // adjust crop rect to max size\n            if (rect.width > maxSizeInRect.width) {\n                rect.width = maxSizeInRect.width;\n                rect.x += dx;\n            }\n            if (rect.height > maxSizeInRect.height) {\n                rect.height = maxSizeInRect.height;\n                rect.y += dy;\n            }\n            // test if has exceeded min size, if so we need to limit the size and recalculate the other edge\n            /*\n                        -\\\n                       /  ---\\\n                      h2      ---\\\n                     /            ---\\\n                    +--------w---------+\\\n                   /|                  | ---\\\n                  / |                  |     ---\\\n                 /  |                  |         ---\\\n                /   |                  |             --\n               h1   |                  |             /\n              /     |                  |            /\n             /      |                  |           /\n            -\\      |                  |          /\n              ---\\  |                  |         /\n                  --+------------------+        /\n                      ---\\                     /\n                          --\\                 /\n                             ---\\            /\n                                 ---\\       /\n                                     ---\\  /\n                                         --\n            */\n        }\n        offsetRectToFitPolygon(rect, imagePolygon);\n        const wasLimited = limitCropRectToImage(rect, imagePolygon);\n        // this makes sure that after limiting the size, the crop rect is moved to a position that is inside the image\n        if (wasLimited)\n            offsetRectToFitPolygon(rect, imagePolygon);\n    }\n    // no rotation, no perspective, use simple bounds method\n    else {\n        // remember intended aspect ratio so we can try and recreate it\n        const intendedAspectRatio = rectAspectRatio(rect);\n        // limit to image size first, can never exceed that\n        rect.width = Math.min(rect.width, imageSize.width);\n        rect.height = Math.min(rect.height, imageSize.height);\n        // reposition rect so it's always inside image bounds\n        rect.x = Math.max(rect.x, 0);\n        if (rect.x + rect.width > imageSize.width) {\n            rect.x -= rect.x + rect.width - imageSize.width;\n        }\n        rect.y = Math.max(rect.y, 0);\n        if (rect.y + rect.height > imageSize.height) {\n            rect.y -= rect.y + rect.height - imageSize.height;\n        }\n        // we get the center of the current rect so we can center the contained rect to it\n        const intendedCenter = rectCenter(rect);\n        // make sure still adheres to aspect ratio\n        const containedRect = rectContainRect(rect, intendedAspectRatio);\n        containedRect.width = Math.max(minSize.width, containedRect.width);\n        containedRect.height = Math.max(minSize.height, containedRect.height);\n        containedRect.x = intendedCenter.x - containedRect.width * 0.5;\n        containedRect.y = intendedCenter.y - containedRect.height * 0.5;\n        rectUpdateWithRect(rect, containedRect);\n    }\n};\n\nvar applyCropRectAction = (cropRectPrevious, cropRectNext, imageSize, imageRotation, imagePerspective, cropLimitToImageBounds, cropMinSize, cropMaxSize) => {\n    // clone\n    const minSize = sizeClone(cropMinSize);\n    // set upper bounds to crop max size\n    const maxSize = sizeClone(cropMaxSize);\n    // limit max size (more important that min size is respected so first limit max size)\n    const maxScalar = fixPrecision(Math.max(cropRectNext.width / maxSize.width, cropRectNext.height / maxSize.height));\n    const minScalar = fixPrecision(Math.min(cropRectNext.width / minSize.width, cropRectNext.height / minSize.height));\n    // clone for resulting crop rect\n    const cropRectOut = rectClone(cropRectNext);\n    //\n    // if exceeds min or max scale correct next crop rectangle to conform to bounds\n    //\n    if (minScalar < 1 || maxScalar > 1) {\n        // center of both previous and next crop rects\n        const previousCropRectCenter = rectCenter(cropRectPrevious);\n        const nextCropRectCenter = rectCenter(cropRectNext);\n        // calculate scales\n        const scalar = minScalar < 1 ? minScalar : maxScalar;\n        const cx = (nextCropRectCenter.x + previousCropRectCenter.x) / 2;\n        const cy = (nextCropRectCenter.y + previousCropRectCenter.y) / 2;\n        const cw = cropRectOut.width / scalar;\n        const ch = cropRectOut.height / scalar;\n        rectUpdate(cropRectOut, cx - cw * 0.5, cy - ch * 0.5, cw, ch);\n    }\n    // no need to limit to bounds, let's go!\n    if (!cropLimitToImageBounds)\n        return {\n            crop: cropRectOut,\n        };\n    //\n    // make sure the crop is made inside the bounds of the image\n    //\n    limitRectToImage(cropRectOut, imageSize, imageRotation, imagePerspective, minSize);\n    return {\n        crop: cropRectOut,\n    };\n};\n\nvar getBaseCropRect = (imageSize, transformedCropRect, imageRotation) => {\n    const imageRect = rectCreateFromSize(imageSize);\n    const imageCenter = rectCenter(imageRect);\n    const imageTransformedVertices = rectRotate(imageRect, imageRotation, imageCenter);\n    // get the rotated image bounds center (offset isn't relevant as crop is relative to top left image position)\n    const imageRotatedBoundsCenter = rectCenter(rectNormalizeOffset(rectCreateFromPoints(imageTransformedVertices)));\n    // get the center of the crop inside the rotated image\n    const cropCenterInTransformedImage = rectCenter(transformedCropRect);\n    // invert the rotation of the crop center around the rotated image center\n    const deRotatedCropCenter = vectorRotate(cropCenterInTransformedImage, -imageRotation, imageRotatedBoundsCenter);\n    // calculate crop distance from rotated image center\n    const cropFromCenterOfTransformedImage = vectorSubtract(deRotatedCropCenter, imageRotatedBoundsCenter);\n    // calculate original crop offset (from untransformed image)\n    const originalCropCenterOffset = vectorApply(vectorAdd(imageCenter, cropFromCenterOfTransformedImage), fixPrecision);\n    return rectCreate(originalCropCenterOffset.x - transformedCropRect.width * 0.5, originalCropCenterOffset.y - transformedCropRect.height * 0.5, transformedCropRect.width, transformedCropRect.height);\n};\n\nvar clamp = (value, min, max) => Math.max(min, Math.min(value, max));\n\nvar applyRotationAction = (imageRotationPrevious, imageRotation, imageRotationRange, cropRect, imageSize, imagePerspective, cropLimitToImageBounds, cropRectOrigin, cropMinSize, cropMaxSize) => {\n    // clone\n    const minSize = sizeClone(cropMinSize);\n    // set upper bounds to crop max size if image is bigger than max size,\n    // else if should limit to image bounds use image size as limit\n    const maxSize = sizeClone(cropMaxSize);\n    if (cropLimitToImageBounds) {\n        maxSize.width = Math.min(cropMaxSize.width, imageSize.width);\n        maxSize.height = Math.min(cropMaxSize.height, imageSize.height);\n    }\n    let didAttemptDoubleTurn = false;\n    const rotate = (rotationPrevious, rotation) => {\n        // get the base crop rect (position of crop rect in untransformed image)\n        // if we have the base crop rect we can apply the new rotation to it\n        const cropRectBase = getBaseCropRect(imageSize, cropRect, rotationPrevious);\n        // calculate transforms based on new rotation and base crop rect\n        const imageRect = rectCreateFromSize(imageSize);\n        const imageCenter = rectCenter(imageRect);\n        const imageTransformedCorners = rectApplyPerspective(imageRect, imagePerspective, imageCenter);\n        // need this to correct for perspective centroid displacement\n        const perspectiveOffset = vectorSubtract(vectorClone(imageCenter), convexPolyCentroid(imageTransformedCorners));\n        // rotate around center of image\n        const cropCenter = vectorRotate(rectCenter(cropRectBase), rotation, imageCenter);\n        const rotateCropOffset = vectorSubtract(vectorClone(imageCenter), cropCenter);\n        // get center of image bounds and move to correct position\n        imageTransformedCorners.forEach((imageVertex) => vectorRotate(imageVertex, rotation, imageCenter));\n        const imageBoundsRect = rectCreateFromPoints(imageTransformedCorners);\n        const imageCentroid = convexPolyCentroid(imageTransformedCorners);\n        const cropOffset = vectorAdd(vectorSubtract(vectorSubtract(imageCentroid, rotateCropOffset), imageBoundsRect), perspectiveOffset);\n        // create output cropRect\n        const cropRectOut = rectCreate(cropOffset.x - cropRectBase.width * 0.5, cropOffset.y - cropRectBase.height * 0.5, cropRectBase.width, cropRectBase.height);\n        // if has size target, scale croprect to target size\n        if (cropRectOrigin) {\n            rectScale(cropRectOut, cropRectOrigin.width / cropRectOut.width);\n        }\n        // if should limit to image bounds\n        if (cropLimitToImageBounds) {\n            const imagePoly = getImagePolygon(imageSize, rotation, imagePerspective);\n            // offsetRectToFitPolygon(cropRectOut, imagePoly);\n            // commenting this fixes poly sliding problem when adjusting rotation\n            limitCropRectToImage(cropRectOut, imagePoly);\n        }\n        //#region if exceeds min or max adjust rotation to conform to bounds\n        const minScalar = fixPrecision(Math.min(cropRectOut.width / minSize.width, cropRectOut.height / minSize.height), 8);\n        const maxScalar = fixPrecision(Math.max(cropRectOut.width / maxSize.width, cropRectOut.height / maxSize.height), 8);\n        if (minScalar < 1 || maxScalar > 1) {\n            // determine if is full image turn\n            const isTurn = fixPrecision(Math.abs(rotation - rotationPrevious)) === fixPrecision(Math.PI / 2);\n            // try another turn if is turning image\n            if (isTurn && !didAttemptDoubleTurn) {\n                didAttemptDoubleTurn = true;\n                return rotate(imageRotationPrevious, imageRotationPrevious + Math.sign(rotation - rotationPrevious) * Math.PI);\n            }\n        }\n        //#endregion\n        return {\n            rotation,\n            crop: rectApply(cropRectOut, (v) => fixPrecision(v, 8)),\n        };\n    };\n    // amount of turns applied, we need this to correctly determine the allowed rotation range\n    const imageTurns = Math.sign(imageRotation) * Math.round(Math.abs(imageRotation) / HALF_PI) * HALF_PI;\n    const imageRotationClamped = clamp(imageRotation, imageTurns + imageRotationRange[0], imageTurns + imageRotationRange[1]);\n    // set new crop position\n    return rotate(imageRotationPrevious, imageRotationClamped);\n};\n\n// @ts-ignore\nconst ORDERED_STATE_PROPS = [\n    // requirements\n    'cropLimitToImage',\n    'cropMinSize',\n    'cropMaxSize',\n    'cropAspectRatio',\n    // selection -> flip -> rotate -> (perspective ->) crop\n    'flipX',\n    'flipY',\n    'rotation',\n    'crop',\n    // effects\n    'colorMatrix',\n    'convolutionMatrix',\n    'gamma',\n    'vignette',\n    // 'noise',\n    // shapes\n    'manipulation',\n    'redaction',\n    'annotation',\n    'decoration',\n    'selection',\n    'frame',\n    // other\n    'backgroundColor',\n    'backgroundImage',\n    'backgroundFilterMode',\n    'targetSize',\n    'metadata',\n    // video\n    'trim',\n    'volume',\n    'minDuration',\n    'maxDuration',\n    'currentTime',\n];\nconst clone = (value) => {\n    if (isArray(value)) {\n        return value.map(clone);\n    }\n    else if (isBlob(value) || isFile(value)) {\n        return value;\n    }\n    else if (isObject(value)) {\n        return { ...value };\n    }\n    return value;\n};\nconst filterShapeState = (shapes) => shapes.map((shape) => Object.entries(shape).reduce((copy, [key, value]) => {\n    if (key.startsWith('_'))\n        return copy;\n    copy[key] = value;\n    return copy;\n}, {}));\nvar stateStore = (_, stores, accessors) => {\n    const observedStores = ORDERED_STATE_PROPS.map((key) => stores[key]);\n    // used to wait with deriving state until new state is fully assigned\n    let isAssigningState = false;\n    const forceState = writable({});\n    // can only subscribe, setting is done directly through store accessors\n    // @ts-ignore (fixes error thrown in karma typescript)\n    const { subscribe } = derived([...observedStores, forceState], (values, set) => {\n        // is setting state\n        if (isAssigningState)\n            return;\n        // create new state by looping over props in certain order\n        const state = ORDERED_STATE_PROPS.reduce((prev, curr, i) => {\n            prev[curr] = clone(values[i]);\n            return prev;\n        }, {});\n        // round crop if defined\n        state.crop && rectApply(state.crop, Math.round);\n        // remove internal state props from decoration and annotation\n        state.manipulation = state.manipulation && filterShapeState(state.manipulation);\n        state.redaction = state.redaction && filterShapeState(state.redaction);\n        state.annotation = state.annotation && filterShapeState(state.annotation);\n        state.decoration = state.decoration && filterShapeState(state.decoration);\n        state.selection = state.selection && filterShapeState(state.selection);\n        // set new state\n        set(state);\n    });\n    const setState = (state) => {\n        // requires at least some state to be supplied\n        if (!state)\n            return;\n        // now assigning state so don't derive state object untill done\n        isAssigningState = true;\n        // make sure crop origin is reset\n        accessors.cropOrigin = undefined;\n        // apply new values\n        ORDERED_STATE_PROPS\n            // remove keys that weren't set\n            .filter((key) => hasProp(state, key))\n            // apply each key in order\n            .forEach((key) => {\n            const value = state[key];\n            accessors[key] = value === null ? undefined : clone(value);\n        });\n        // now refresh state\n        isAssigningState = false;\n        forceState.set({});\n    };\n    return {\n        set: setState,\n        update: (fn) => setState(fn(null)),\n        subscribe,\n    };\n};\n\nvar toNumericAspectRatio = (v) => {\n    if (!v)\n        return undefined;\n    if (/:/.test(v)) {\n        const [w, h] = v.split(':');\n        return w / h;\n    }\n    return parseFloat(v);\n};\n\nconst simpleEqual = (a, b) => a === b;\nvar arrayEqual = (a, b, itemEqual = simpleEqual) => {\n    // if length is different, it's always changed\n    if (a.length !== b.length)\n        return false;\n    // need to test item equality\n    for (let i = 0; i < a.length; i++) {\n        if (!itemEqual(a[i], b[i]))\n            return false;\n    }\n    return true;\n};\n\nvar padColorArray = (color = [0, 0, 0, 0], opacity = 1.0) => color.length === 4 ? color : [...color, opacity];\n\n//\n// helper methods\n//\nconst isCropCentered = (crop, imageSize, imageRotation) => {\n    const cropCenter = vectorApply(rectCenter(crop), (v) => fixPrecision(v, 8));\n    const imageRect = rectCreateFromSize(imageSize);\n    const imageCenter = rectCenter(imageRect);\n    const imageRotatedVertices = rectRotate(imageRect, imageRotation, imageCenter);\n    const imageBoundsCenter = vectorApply(sizeCenter(rectCreateFromPoints(imageRotatedVertices)), (v) => fixPrecision(v, 8));\n    const dx = Math.abs(imageBoundsCenter.x - cropCenter.x);\n    const dy = Math.abs(imageBoundsCenter.y - cropCenter.y);\n    return dx < 1 && dy < 1;\n};\nconst isCropMaxSize = (cropRect, imageSize, rotation) => {\n    const maxSize = getMaxSizeInRect(imageSize, rotation, rectAspectRatio(cropRect));\n    return sizeEqual(sizeApply(maxSize, Math.round), sizeApply(sizeClone(cropRect), Math.round));\n};\n//\n// updater methods\n//\nconst updateCropRect = (props) => (cropNext, cropPrevious = cropNext) => {\n    // wait for image to load\n    const { loadState, size, cropMinSize, cropMaxSize, cropLimitToImage, cropAspectRatio, rotation, perspective, } = props;\n    // image hasn't loaded yet, use supplied crop rect\n    if ((!cropNext && !cropPrevious) || !loadState || !loadState.beforeComplete)\n        return cropNext;\n    // crop previous set, crop next set to undefined, set crop to fit image\n    if (!cropNext)\n        cropNext = rectCreateFromSize(getMaxSizeInRect(size, rotation, cropAspectRatio || rectAspectRatio(size)));\n    // apply the action\n    const res = applyCropRectAction(cropPrevious, cropNext, size, rotation, perspective, cropLimitToImage, cropMinSize, cropMaxSize);\n    const cropOut = rectApply(res.crop, (v) => fixPrecision(v, 8));\n    if (rectEqual(cropPrevious, cropOut))\n        return cropPrevious;\n    return cropOut;\n};\nconst updateCropAspectRatio = (props) => (aspectRatioNext, aspectRatioPrevious) => {\n    const { loadState, crop, size, rotation, cropLimitToImage } = props;\n    const aspectRatio = toNumericAspectRatio(aspectRatioNext);\n    // no aspect ratio means custom aspect ratio so set to undefined\n    if (!aspectRatio)\n        return undefined;\n    // can't update crop if not defined yet\n    if (!crop || !loadState || !loadState.beforeComplete)\n        return aspectRatio;\n    // calculate difference between aspect ratios, if big difference, re-align in image\n    const aspectRatioDist = aspectRatioPrevious\n        ? Math.abs(aspectRatioNext - aspectRatioPrevious)\n        : 1;\n    // if crop centered scale up\n    if (isCropCentered(crop, size, rotation) && cropLimitToImage && aspectRatioDist >= 0.1) {\n        const imageSize = sizeTurn(sizeClone(size), rotation);\n        props.crop = rectApply(rectContainRect(rectCreateFromSize(imageSize), aspectRatioNext), fixPrecision);\n    }\n    else {\n        const cropSize = {\n            width: crop.height * aspectRatio,\n            height: crop.height,\n        };\n        const tx = (crop.width - cropSize.width) * 0.5;\n        const ty = (crop.height - cropSize.height) * 0.5;\n        props.crop = rectApply(rectCreate(crop.x + tx, crop.y + ty, cropSize.width, cropSize.height), fixPrecision);\n    }\n    return aspectRatio;\n};\nconst updateCropLimitToImage = (props) => (limitToImageNext, limitToImagePrevious, onUpdate) => {\n    // skip if no crop defined\n    const { crop } = props;\n    if (!crop)\n        return limitToImageNext;\n    // if was not limiting previously and now set limiting make sure crop fits bounds\n    if (!limitToImagePrevious && limitToImageNext) {\n        onUpdate(() => (props.crop = rectClone(props.crop)));\n    }\n    return limitToImageNext;\n};\nconst updateRotation = (props) => (rotationNext, rotationPrevious, onUpdate) => {\n    // when image rotation is updated we need to adjust the\n    // cropRect offset so rotation happens from cropRect center\n    // no change\n    if (rotationNext === rotationPrevious)\n        return rotationNext;\n    // get relevant data from store state\n    const { loadState, size, rotationRange, cropMinSize, cropMaxSize, crop, perspective, cropLimitToImage, cropOrigin, } = props;\n    // image not ready, exit!\n    if (!crop || !loadState || !loadState.beforeComplete)\n        return rotationNext;\n    // remember if current crop was at max size and centered, if so, resulting crop should also be at max size\n    const cropWasAtMaxSize = cropLimitToImage && isCropMaxSize(crop, size, rotationPrevious);\n    const cropWasCentered = cropLimitToImage && isCropCentered(crop, size, rotationPrevious);\n    // get new state\n    const res = applyRotationAction(rotationPrevious, rotationNext, rotationRange, crop, size, perspective, cropLimitToImage, cropOrigin, cropMinSize, cropMaxSize);\n    // if is centered, and initial crop was at max size expand crop to max size\n    if (cropWasAtMaxSize && cropWasCentered) {\n        const rect = getMaxSizeInRect(size, rotationNext, rectAspectRatio(res.crop));\n        // move top left corner\n        res.crop.x += res.crop.width * 0.5;\n        res.crop.y += res.crop.height * 0.5;\n        res.crop.x -= rect.width * 0.5;\n        res.crop.y -= rect.height * 0.5;\n        // update size to max size\n        res.crop.width = rect.width;\n        res.crop.height = rect.height;\n    }\n    // return validated rotation value, then, after we assign that value, we update the crop rect\n    // we may only call onUpdate if a change was made\n    onUpdate(() => {\n        props.crop = rectApply(res.crop, (v) => fixPrecision(v, 8));\n    });\n    // return result rotation (might have been rotated twice to fit crop rectangle)\n    return res.rotation;\n};\n// updates the range of valid rotation input\nconst updateRotationRange = (imageSize, imageIsRotatedSideways, cropMinSize, cropSize, cropLimitToImage) => {\n    if (!cropLimitToImage)\n        return [-Infinity, Infinity];\n    /*\n    - 'a' is angle between diagonal and image height\n    - 'b' is angle between diagonal and crop height\n    - 'c' is angle between diagonal and image width\n    - resulting range is then a - b\n    +----------/\\------------------------+\n    |         / \\ \\                      |\n    |        /   \\  \\                    |\n    |       /     \\   \\                  |\n    |       \\      \\    \\                |\n    |         \\     \\     \\              |\n    |           \\    \\      \\            |\n    |             \\   \\       /          |\n    |               \\  \\     /           |\n    |                 \\ \\   /            |\n    |                   \\\\a/b            |\n    +---------------------\\--------------+\n    */\n    const scalar = Math.max(cropMinSize.width / cropSize.width, cropMinSize.height / cropSize.height);\n    const minSize = sizeCreate(cropSize.width * scalar, cropSize.height * scalar);\n    // the hypotenus is the length of the diagonal of the min crop size\n    const requiredSpace = sizeHypotenuse(minSize);\n    // minimum space available in horizontal / vertical direction\n    const availableSpace = Math.min(imageSize.width, imageSize.height);\n    // if there's enough space available, we can return the max range\n    if (requiredSpace < availableSpace)\n        return [-Infinity, Infinity];\n    // if the image is turned we need to swap the width and height\n    const imageWidth = imageIsRotatedSideways ? imageSize.height : imageSize.width;\n    const imageHeight = imageIsRotatedSideways ? imageSize.width : imageSize.height;\n    // subtracting the angle between the hypotenuse and the crop itself\n    const a = Math.acos(minSize.height / requiredSpace);\n    const b = Math.acos(imageHeight / requiredSpace);\n    const c = Math.asin(imageWidth / requiredSpace);\n    const rangeHorizontal = a - b;\n    const rangeVertical = c - a;\n    // range is not a number, it means we can rotate as much as we want\n    if (Number.isNaN(rangeHorizontal) && Number.isNaN(rangeVertical))\n        return [-Infinity, Infinity];\n    // get minimum range\n    const range = Number.isNaN(rangeHorizontal)\n        ? rangeVertical\n        : Number.isNaN(rangeVertical)\n            ? rangeHorizontal\n            : Math.min(rangeHorizontal, rangeVertical);\n    // if not, limit range to min and max rotation\n    return [-range, range];\n};\n// updates the range of valid crop rectangle input\nconst updateCropRange = (imageSize, rotation, cropAspectRatio, cropMinSize, cropMaxSize, cropLimitToImage) => {\n    // ! rotation doesn't affect min size, only max size\n    // set lower bounds to crop min size\n    const minSize = sizeClone(cropMinSize);\n    // set upper bounds to crop max size\n    const maxSize = sizeClone(cropMaxSize);\n    // now we got basic bounds, let's see if we should limit to the image bounds, else we done\n    if (!cropLimitToImage)\n        return [minSize, maxSize];\n    return [minSize, sizeApply(getMaxSizeInRect(imageSize, rotation, cropAspectRatio), Math.round)];\n};\nconst formatShape = (shape, options) => {\n    const { context, props } = options;\n    // only auto-format once\n    if (!shape._isFormatted) {\n        shape = shapeFormat(shape);\n        shape._isFormatted = true;\n        Object.assign(shape, props);\n    }\n    // we need to make sure shape is still correctly positioned relative to parent context\n    // draft cannot be relative\n    // if context changed\n    // if has left top right or bottom\n    if (!shape._isDraft &&\n        shapeHasRelativeSize(shape) &&\n        (!shape._context || !rectEqual(context, shape._context))) {\n        shapeComputeRect(shape, context);\n        shape._context = { ...context };\n    }\n    return shape;\n};\nconst formatSelectionShape = (shape, options) => {\n    if (!shape._isFormatted) {\n        shape.disableMove = true;\n        shape.disableSelect = true;\n        shape.disableResize = true;\n        shape.disableRotate = true;\n    }\n    return formatShape(shape, options);\n};\nconst updateFrame = () => (frameShapeNext) => {\n    if (!frameShapeNext)\n        return;\n    const shape = {\n        frameStyle: undefined,\n        x: 0,\n        y: 0,\n        width: '100%',\n        height: '100%',\n        disableStyle: ['backgroundColor', 'strokeColor', 'strokeWidth'],\n    };\n    if (isString(frameShapeNext)) {\n        shape.frameStyle = frameShapeNext;\n    }\n    else {\n        Object.assign(shape, frameShapeNext);\n    }\n    return shape;\n};\nvar ImageStorePropDescriptors = [\n    // media info received from read\n    ['file'],\n    ['size'],\n    // loading and processing state\n    ['loadState'],\n    ['processState'],\n    // derived info\n    [\n        'aspectRatio',\n        DERIVED_STORE(({ size }) => [\n            size,\n            ($size) => ($size ? rectAspectRatio($size) : undefined),\n        ]),\n    ],\n    // image modifications\n    ['perspectiveX', DEFAULT_VALUE(() => 0)],\n    ['perspectiveY', DEFAULT_VALUE(() => 0)],\n    [\n        'perspective',\n        DERIVED_STORE(({ perspectiveX, perspectiveY }) => [\n            [perspectiveX, perspectiveY],\n            ([x, y]) => ({ x, y }),\n        ]),\n    ],\n    ['rotation', DEFAULT_VALUE(() => 0), UPDATE_VALUE(updateRotation)],\n    ['flipX', DEFAULT_VALUE(() => false)],\n    ['flipY', DEFAULT_VALUE(() => false)],\n    ['flip', DERIVED_STORE(({ flipX, flipY }) => [[flipX, flipY], ([x, y]) => ({ x, y })])],\n    [\n        'isRotatedSideways',\n        UNIQUE_DERIVED_STORE(({ rotation }) => [\n            [rotation],\n            ([$rotation], set) => set(isRotatedSideways($rotation)),\n            (prevValue, nextValue) => prevValue !== nextValue,\n        ]),\n    ],\n    ['crop', UPDATE_VALUE(updateCropRect)],\n    ['cropAspectRatio', UPDATE_VALUE(updateCropAspectRatio)],\n    ['cropOrigin'], // private, used to make different updates to the crop rect when manipulating the image\n    ['cropMinSize', DEFAULT_VALUE(() => ({ width: 1, height: 1 }))],\n    ['cropMaxSize', DEFAULT_VALUE(() => ({ width: 32768, height: 32768 }))],\n    ['cropLimitToImage', DEFAULT_VALUE(() => true), UPDATE_VALUE(updateCropLimitToImage)],\n    [\n        'cropSize',\n        UNIQUE_DERIVED_STORE(({ crop }) => [\n            [crop],\n            ([$crop], set) => {\n                if (!$crop)\n                    return;\n                set(sizeCreate($crop.width, $crop.height));\n            },\n            // if is same as previous size, don't trigger update (happens when updating only the crop offset)\n            (prevValue, nextValue) => sizeEqual(prevValue, nextValue),\n        ]),\n    ],\n    [\n        'cropRectAspectRatio',\n        DERIVED_STORE(({ cropSize }) => [\n            [cropSize],\n            ([$cropSize], set) => {\n                if (!$cropSize)\n                    return;\n                set(fixPrecision(rectAspectRatio($cropSize), 5));\n            },\n        ]),\n    ],\n    [\n        'cropRange',\n        UNIQUE_DERIVED_STORE(({ size, rotation, cropRectAspectRatio, cropMinSize, cropMaxSize, cropLimitToImage, }) => [\n            [size, rotation, cropRectAspectRatio, cropMinSize, cropMaxSize, cropLimitToImage],\n            ([$size, $rotation, $cropRectAspectRatio, $cropMinSize, $cropMaxSize, $cropLimitToImage,], set) => {\n                // wait for image size\n                if (!$size)\n                    return;\n                const range = updateCropRange($size, $rotation, $cropRectAspectRatio, $cropMinSize, $cropMaxSize, $cropLimitToImage);\n                set(range);\n            },\n            // if is same range as previous range, don't trigger update\n            (prevRange, nextRange) => arrayEqual(prevRange, nextRange),\n        ]),\n    ],\n    [\n        'rotationRange',\n        UNIQUE_DERIVED_STORE(({ size, isRotatedSideways, cropMinSize, cropSize, cropLimitToImage }) => [\n            [size, isRotatedSideways, cropMinSize, cropSize, cropLimitToImage],\n            ([$size, $isRotatedSideways, $cropMinSize, $cropSize, $cropLimitToImage], set) => {\n                // wait for image size\n                if (!$size || !$cropSize)\n                    return;\n                const range = updateRotationRange($size, $isRotatedSideways, $cropMinSize, $cropSize, $cropLimitToImage);\n                set(range);\n            },\n            // if is same range as previous range, don't trigger update\n            (prevRange, nextRange) => arrayEqual(prevRange, nextRange),\n        ]),\n    ],\n    // canvas\n    ['backgroundColor', UPDATE_VALUE(() => (color) => padColorArray(color))],\n    ['backgroundImage'],\n    ['backgroundFilterMode'],\n    // size\n    ['targetSize'],\n    // effects\n    ['colorMatrix'],\n    ['convolutionMatrix'],\n    ['gamma'],\n    ['noise'],\n    ['vignette'],\n    // video\n    ['duration'], // readonly duration\n    ['currentTime'], // tracks the video current time, we can use this in processing to snap a preview thumbnail\n    ['minDuration', DEFAULT_VALUE(() => 1 / 24)], // there has to be a duration, let's pick 24fps, about 1 frame\n    ['maxDuration', DEFAULT_VALUE(() => Infinity)], // no max length\n    ['volume', DEFAULT_VALUE(() => 1)], // 1 (normal volume) | 0 (remove audio track) | (any other number to increase or lower output volume)\n    ['trim'], // undefined | [from seconds, to seconds]\n    // redaction lives in image space\n    ['redaction', MAP_STORE(({ size }) => [formatShape, { context: size }])],\n    // modification lives in image space\n    ['manipulation', MAP_STORE(({ size }) => [formatShape, { context: size }])],\n    // annotation lives in image space\n    ['annotation', MAP_STORE(({ size }) => [formatShape, { context: size }])],\n    // decoration lives in crop space\n    ['decoration', MAP_STORE(({ crop }) => [formatShape, { context: crop }])],\n    // image selection\n    ['selection', MAP_STORE(({ size }) => [formatSelectionShape, { context: size }])],\n    // frame to render on top of the image (or outside)\n    ['frame', UPDATE_VALUE(updateFrame)],\n    // custom metadata\n    ['metadata'],\n    // state of image, used to restore a previous state or request the current state\n    ['state', CUSTOM_STORE(stateStore)],\n];\n\nvar process = async (value, chainTasks, chainOptions = {}, processOptions) => {\n    // options relevant to the process method itself\n    const { ontaskstart, ontaskprogress, ontaskend, token } = processOptions;\n    // has been cancelled\n    let cancelled = false;\n    // create token to pass to tasks\n    const taskCancelToken = {\n        cancel: noop$1,\n    };\n    // set cancel handler method\n    token.cancel = () => {\n        // cancel called from outside of the process method\n        cancelled = true;\n        // assign cancel method to task\n        taskCancelToken.cancel();\n    };\n    // step through chain\n    for (const [index, task] of chainTasks.entries()) {\n        // exit when cancelled\n        if (cancelled)\n            return;\n        // get the task function and the id so we can notify the callee of the task that is being started\n        const [fn, id] = task;\n        // start task\n        ontaskstart(index, id);\n        try {\n            value = await fn(value, { ...chainOptions, taskCancelToken }, (event) => ontaskprogress(index, id, event));\n        }\n        catch (err) {\n            // stop processing more items in the chain\n            cancelled = true;\n            // pass error back to parent\n            throw err;\n        }\n        ontaskend(index, id);\n    }\n    return value;\n};\n\n// TODO: find better location for minSize / file load validation\nvar createImageCore = ({ minSize = { width: 1, height: 1 }, minDuration = 0 } = {}) => {\n    // create default store\n    const { stores, accessors } = createStores(ImageStorePropDescriptors);\n    // pub/sub\n    const { pub, sub } = pubsub();\n    // processing handler\n    const createProcessingHandler = (stateProp, eventKey) => {\n        const getStore = () => accessors[stateProp] || {};\n        const setStore = (obj) => {\n            accessors[stateProp] = {\n                ...getStore(),\n                ...obj,\n                timeStamp: Date.now(),\n            };\n        };\n        const hasError = () => getStore().error;\n        const handleError = (error) => {\n            if (hasError())\n                return;\n            setStore({\n                error: error,\n            });\n            pub(`${eventKey}error`, { ...getStore() });\n        };\n        return {\n            start() {\n                pub(`${eventKey}start`);\n            },\n            onabort() {\n                setStore({\n                    abort: true,\n                });\n                pub(`${eventKey}abort`, { ...getStore() });\n            },\n            ontaskstart(index, id) {\n                if (hasError())\n                    return;\n                setStore({\n                    index,\n                    task: id,\n                    taskProgress: undefined,\n                    taskLengthComputable: undefined,\n                });\n                pub(`${eventKey}taskstart`, { ...getStore() });\n            },\n            ontaskprogress(index, id, event) {\n                if (hasError())\n                    return;\n                setStore({\n                    index,\n                    task: id,\n                    taskProgress: event.loaded / event.total,\n                    taskLengthComputable: event.lengthComputable,\n                });\n                pub(`${eventKey}taskprogress`, { ...getStore() });\n                pub(`${eventKey}progress`, { ...getStore() });\n            },\n            ontaskend(index, id) {\n                if (hasError())\n                    return;\n                setStore({\n                    index,\n                    task: id,\n                });\n                pub(`${eventKey}taskend`, { ...getStore() });\n            },\n            ontaskerror(error) {\n                handleError(error);\n            },\n            error(error) {\n                handleError(error);\n            },\n            beforeComplete(data) {\n                if (hasError())\n                    return;\n                setStore({ beforeComplete: true });\n                pub(`before${eventKey}`, data);\n            },\n            complete(data) {\n                if (hasError())\n                    return;\n                setStore({ complete: true });\n                pub(eventKey, data);\n            },\n        };\n    };\n    //#region read image\n    const read = (src, { reader }, readerOptions = {}) => {\n        // exit if no reader supplied\n        if (!reader)\n            return;\n        // reset file data to undefined as we're loading a new image\n        Object.assign(accessors, {\n            file: undefined,\n            size: undefined,\n            loadState: undefined,\n        });\n        // our cancel token so we can abort load if needed, cancel will be set by process\n        let imageReadToken = { cancel: noop$1 };\n        let imageReadCancelled = false;\n        const imageReadHandler = createProcessingHandler('loadState', 'load');\n        const processOptions = {\n            token: imageReadToken,\n            ...imageReadHandler,\n        };\n        const readerState = {\n            src,\n            size: undefined,\n            dest: undefined,\n            duration: undefined,\n        };\n        // wait a tick before starting image read so the read can be cancelled in loadstart\n        Promise.resolve().then(async () => {\n            try {\n                imageReadHandler.start();\n                if (imageReadCancelled) {\n                    return imageReadHandler.onabort();\n                }\n                const output = (await process(readerState, reader, readerOptions, processOptions));\n                // was cancelled\n                if (imageReadCancelled) {\n                    return imageReadHandler.onabort();\n                }\n                // get shortcuts for validation\n                const { size, duration, dest } = output || {};\n                // if we don't have a size\n                if (!size || !size.width || !size.height)\n                    throw new EditorError('Image size missing', 'IMAGE_SIZE_MISSING', output);\n                // if we have a duration and minDuration\n                if (duration > 0 && duration < minDuration)\n                    throw new EditorError('Video too short', 'VIDEO_TOO_SHORT', {\n                        ...output,\n                        minDuration,\n                    });\n                // size of image is too small\n                if (size.width < minSize.width || size.height < minSize.height)\n                    throw new EditorError('Image too small', 'IMAGE_TOO_SMALL', {\n                        ...output,\n                        minWidth: minSize.width,\n                        minHeight: minSize.height,\n                    });\n                // update internal data\n                Object.assign(accessors, {\n                    file: dest,\n                    size,\n                    duration,\n                });\n                // before load complete\n                imageReadHandler.beforeComplete(output);\n                // done loading image\n                imageReadHandler.complete(output);\n            }\n            catch (err) {\n                imageReadHandler.error(err);\n            }\n            finally {\n                imageReadToken = undefined;\n            }\n        });\n        // call to abort load\n        return () => {\n            imageReadCancelled = true;\n            imageReadToken && imageReadToken.cancel();\n            imageReadHandler.onabort();\n        };\n    };\n    //#endregion\n    //#region write image\n    const write = (writer, options) => {\n        // not ready to start processing\n        if (!accessors.loadState.complete)\n            return;\n        // reset process state to undefined\n        accessors.processState = undefined;\n        const imageWriteHandler = createProcessingHandler('processState', 'process');\n        const writerState = {\n            src: accessors.file,\n            imageState: accessors.state,\n            dest: undefined,\n        };\n        // writer is function, let's get the actual writer\n        if (isFunction(writer)) {\n            writer = writer(accessors.file, accessors.state);\n        }\n        // willProcessImageState\n        if (!writer) {\n            imageWriteHandler.start();\n            imageWriteHandler.complete(writerState);\n            return;\n        }\n        // we need this token to be a blet to cancel the processing operation\n        let imageWriteToken = { cancel: noop$1 };\n        let imageWriteCancelled = false;\n        const writerOptions = options;\n        const processOptions = {\n            token: imageWriteToken,\n            ...imageWriteHandler,\n        };\n        // wait a tick before starting image write so the write can be cancelled in processtart\n        Promise.resolve().then(async () => {\n            try {\n                imageWriteHandler.start();\n                // could be cancelled before processing started\n                if (imageWriteCancelled)\n                    return imageWriteHandler.onabort();\n                const output = (await process(writerState, writer, writerOptions, processOptions));\n                // cancelled during processing\n                if (imageWriteCancelled)\n                    return imageWriteHandler.onabort();\n                imageWriteHandler.complete(output);\n            }\n            catch (err) {\n                imageWriteHandler.error(err);\n            }\n            finally {\n                imageWriteToken = undefined;\n            }\n        });\n        // call to abort processing\n        return () => {\n            imageWriteCancelled = true;\n            imageWriteToken && imageWriteToken.cancel();\n            imageWriteHandler.onabort();\n        };\n    };\n    //#endregion\n    //#region api\n    defineMethods(accessors, {\n        read,\n        write,\n        on: sub,\n    });\n    //#endregion\n    // expose store API\n    return {\n        accessors,\n        stores,\n    };\n};\n\nconst warnRequiredProp = (prop) => console.warn(`Pintura: ${prop} is a required prop.`);\n\n// @ts-ignore\nconst editorEventsToBubble = [\n    'loadstart',\n    'loadabort',\n    'loaderror',\n    'loadprogress',\n    'load',\n    'processstart',\n    'processabort',\n    'processerror',\n    'processprogress',\n    'process',\n];\nconst imagePrivateProps = [\n    'flip',\n    'cropOrigin',\n    'isRotatedSideways',\n    'perspective',\n    'perspectiveX',\n    'perspectiveY',\n    'cropRange',\n];\nconst editorPrivateProps = ['images'];\nconst imagePublicProps = ImageStorePropDescriptors\n    .map(([prop]) => prop)\n    .filter((prop) => !imagePrivateProps.includes(prop));\nconst getImagePropGroupedName = (prop) => `image${capitalizeFirstLetter(prop)}`;\nconst getEditorProps$1 = () => {\n    const imageProperties = imagePublicProps.map(getImagePropGroupedName);\n    const editorProperties = props\n        .map(([prop]) => prop)\n        .filter((prop) => !editorPrivateProps.includes(prop));\n    return imageProperties.concat(editorProperties);\n};\nconst isImageSource = (src) => isString(src) || isBinary(src) || isElement(src);\nconst isImageState = (obj) => hasProp(obj, 'crop');\nvar createImageEditor = () => {\n    // create default stores\n    const { stores, accessors } = createStores(props);\n    // set up pub/sub for the app layer\n    const { sub, pub } = pubsub();\n    const bubble = (name) => (value) => pub(name, value);\n    // helper method\n    const getImageObjSafe = () => (accessors.images ? accessors.images[0] : {});\n    // initialImageProps is the list of transforms to apply when the image loads\n    let initialImageProps = {};\n    const initialImagePropsBackup = {};\n    // create shortcuts to image props : `crop` -> `imageCrop`\n    imagePublicProps.forEach((prop) => {\n        Object.defineProperty(accessors, getImagePropGroupedName(prop), {\n            get: () => {\n                // no image, can't get\n                const image = getImageObjSafe();\n                if (!image)\n                    return;\n                // return from image state\n                return image.accessors[prop];\n            },\n            set: (value) => {\n                // always use as initial prop when loading a new image without reset\n                initialImageProps[getImagePropGroupedName(prop)] = value;\n                // set to props backup so we can read it later when loading a new image\n                initialImagePropsBackup[getImagePropGroupedName(prop)] = value;\n                // no image, we can't update\n                const image = getImageObjSafe();\n                if (!image)\n                    return;\n                // update the image immidiately\n                image.accessors[prop] = value;\n            },\n        });\n    });\n    // internal helper method to get active image\n    const getImage = () => accessors.images && accessors.images[0];\n    // timeout for image reader warning\n    let imageReaderTestTimeout;\n    // handling loading an image if a src is set\n    const unsubSrc = stores.src.subscribe((src) => {\n        // no image set, means clear active image\n        if (!src)\n            return (accessors.images = []);\n        // exit here if we don't have an imageReader we'll wait for an imageReader to be defined\n        if (!accessors.imageReader) {\n            // we're setting a src without an image reader, need to warn\n            imageReaderTestTimeout = setTimeout(() => warnRequiredProp('imageReader'), 32);\n            return;\n        }\n        // reset initial image props if an image is already loaded, so props applied to previous image aren't applied to the new one\n        if (accessors.images.length)\n            initialImageProps = {};\n        // load image in src prop\n        loadSrc(src);\n    });\n    const unsubReader = stores.imageReader.subscribe((reader) => {\n        // can't do anything without an image reader\n        if (!reader)\n            return;\n        // image reader now set, no need to warn\n        clearTimeout(imageReaderTestTimeout);\n        // an image has already been loaded no need to load images that were set earlier\n        if (accessors.images.length)\n            return;\n        // no image to load, we'll wait for images to be set to the `src` prop\n        if (!accessors.src)\n            return;\n        // src is waiting to be loaded so let's pick it up,\n        loadSrc(accessors.src);\n    });\n    const loadSrc = (src) => {\n        // push it back a tick so we know initialImageProps are set\n        Promise.resolve()\n            .then(() => {\n            // load with initial props\n            return loadImage(src, initialImageProps);\n        })\n            .catch(() => {\n            // fail silently, any errors are handled with 'loaderror' event\n        });\n    };\n    //#endregion\n    //#region public method (note that these are also called from UI, name of method is name of dispatched event in UI)\n    const applyImageOptionsOrState = (image, options) => {\n        // test if options is image state, if so, apply and exit\n        if (isImageState(options)) {\n            accessors.imageState = options;\n            return;\n        }\n        // create an initial crop rect if no crop supplied\n        if (!options.imageCrop) {\n            const imageSize = image.accessors.size;\n            const imageRotation = options.imageRotation || 0;\n            const imageRotatedSize = sizeRotate(sizeClone(imageSize), imageRotation);\n            const cropRect = rectCreateFromSize(imageRotatedSize);\n            // prevent negative width/height\n            cropRect.width = fixPrecision(Math.abs(cropRect.width), 6);\n            cropRect.height = fixPrecision(Math.abs(cropRect.height), 6);\n            const aspectRatio = options.imageCropAspectRatio ||\n                (options.imageCropLimitToImage\n                    ? rectAspectRatio(imageSize) // use image size if should limit to image\n                    : rectAspectRatio(cropRect)); // use rotated crop rect bounds if no limit\n            let crop;\n            if (options.imageCropLimitToImage) {\n                crop = rectContainRect(cropRect, aspectRatio);\n            }\n            else {\n                crop = rectCoverRect(cropRect, aspectRatio);\n                // center the image in the crop rectangle\n                crop.x = (imageSize.width - crop.width) / 2;\n                crop.y = (imageSize.height - crop.height) / 2;\n            }\n            options.imageCrop = crop;\n        }\n        // trim not set, let's make sure we respect max duration\n        if (image.accessors.duration && !options.imageTrim && options.imageMaxDuration) {\n            const { duration } = image.accessors;\n            // if duration is longer than max duration we need to set a trim\n            options.imageTrim = [[0, Math.min(options.imageMaxDuration / duration, 1)]];\n        }\n        // we need to apply these props in the correct order\n        const propKeys = [\n            'imageCropLimitToImage',\n            'imageCrop',\n            'imageCropAspectRatio',\n            'imageRotation',\n        ];\n        propKeys\n            .filter((prop) => hasProp(options, prop))\n            .forEach((prop) => {\n            // assign to `image`\n            accessors[prop] = options[prop];\n            // remove from normalizedOptions so it's not set twice\n            delete options[prop];\n        });\n        // don't set the above options for a second time\n        const filteredOptions = Object.keys(options)\n            .filter((key) => !propKeys.includes(key))\n            .reduce((filtered, prop) => {\n            filtered[prop] = options[prop];\n            return filtered;\n        }, {});\n        // trigger setState\n        Object.assign(accessors, filteredOptions);\n    };\n    // load image, resolve when image is loaded\n    let imageLoadAbort;\n    const loadImage = (src, options = {}) => new Promise((resolve, reject) => {\n        // get current image\n        let image = getImage();\n        // determine min defined image size (is crop min size)\n        const cropLimitedToImage = !(options.cropLimitToImage === false ||\n            options.imageCropLimitToImage === false ||\n            initialImagePropsBackup.imageCropLmitedToImage === false);\n        const cropMinSize = options.cropMinSize ||\n            options.imageCropMinSize ||\n            initialImagePropsBackup.imageCropMinSize;\n        const minImageSize = cropLimitedToImage\n            ? cropMinSize\n            : image && image.accessors.cropMinSize;\n        const minVideoDuration = options.minDuration || options.imageMinDuration;\n        // if already has image, remove existing image\n        if (image)\n            removeImage();\n        // access image props and stores\n        image = createImageCore({ minSize: minImageSize, minDuration: minVideoDuration });\n        editorEventsToBubble.map((event) => image.accessors.on(event, bubble(event)));\n        // done, clean up listeners\n        const fin = () => {\n            // reset initial props (as now applied)\n            initialImageProps = {};\n            unsubs.forEach((unsub) => unsub());\n        };\n        const unsubs = [];\n        unsubs.push(image.accessors.on('loaderror', (error) => {\n            fin();\n            reject(error);\n        }));\n        unsubs.push(image.accessors.on('loadabort', () => {\n            fin();\n            reject({ name: 'AbortError' });\n        }));\n        unsubs.push(image.accessors.on('load', (output) => {\n            imageLoadAbort = undefined;\n            fin();\n            resolve(output);\n        }));\n        unsubs.push(image.accessors.on('beforeload', () => applyImageOptionsOrState(image, options)));\n        // set new image\n        accessors.images = [image];\n        // assign passed options to editor accessors, we ignore 'src'\n        if (options.imageReader)\n            accessors.imageReader = options.imageReader;\n        if (options.imageWriter)\n            accessors.imageWriter = options.imageWriter;\n        // start reading image\n        imageLoadAbort = image.accessors.read(src, {\n            reader: accessors.imageReader,\n        }, {\n            willRequest: accessors.willRequest,\n        });\n    });\n    // start processing a loaded image, resolve when image is processed\n    let imageProcessAbort;\n    const processImage = (src, options) => new Promise((resolve, reject) => {\n        try {\n            const unsubs = [];\n            // done, clean up listeners\n            const fin = () => {\n                unsubs.forEach((unsub) => unsub());\n            };\n            (async () => {\n                // if src supplied, first load src, then process\n                if (isImageSource(src)) {\n                    try {\n                        await loadImage(src, options);\n                    }\n                    catch (err) {\n                        reject(err);\n                    }\n                }\n                // if first argument is not `src` but is set it's an options object, so we'll update the options before generating the image\n                else if (src) {\n                    if (isImageState(src)) {\n                        accessors.imageState = src;\n                    }\n                    else {\n                        Object.assign(accessors, src);\n                    }\n                }\n                // get current active image\n                const image = getImage();\n                // needs image for processing\n                if (!image)\n                    return reject('no image');\n                unsubs.push(image.accessors.on('processerror', (error) => {\n                    fin();\n                    reject(error);\n                }));\n                unsubs.push(image.accessors.on('processabort', () => {\n                    fin();\n                    reject({ name: 'AbortError' });\n                }));\n                unsubs.push(image.accessors.on('process', (output) => {\n                    imageProcessAbort = undefined;\n                    fin();\n                    resolve(output);\n                }));\n                imageProcessAbort = image.accessors.write(accessors.imageWriter, {\n                    redactionRenderStyle: accessors.imageRedactionRendering,\n                    shapePreprocessor: accessors.shapePreprocessor || passthrough,\n                    imageScrambler: accessors.imageScrambler,\n                    willRequest: accessors.willRequest,\n                    csp: accessors.csp || {},\n                    willRequestResource: accessors.willRequestResource, // deprecated\n                });\n            })();\n        }\n        catch (err) {\n            reject(err);\n        }\n    });\n    const abortProcessImage = () => {\n        const image = getImage();\n        if (!image)\n            return;\n        if (imageProcessAbort)\n            imageProcessAbort();\n        image.accessors.processState = undefined;\n    };\n    // used internally (triggered by 'x' button when error loading image in UI)\n    const abortLoadImage = () => {\n        if (imageLoadAbort)\n            imageLoadAbort();\n        accessors.images = [];\n    };\n    // edit image, loads an image and resolve when image is processed\n    const editImage = (src, options) => new Promise((resolve, reject) => {\n        loadImage(src, options)\n            .then(() => {\n            // access image props and stores\n            const { images } = accessors;\n            const image = images[0];\n            // done, clean up listeners\n            const done = () => {\n                unsubReject();\n                unsubResolve();\n            };\n            const unsubReject = image.accessors.on('processerror', (error) => {\n                done();\n                reject(error);\n            });\n            const unsubResolve = image.accessors.on('process', (output) => {\n                done();\n                resolve(output);\n            });\n        })\n            .catch(reject);\n    });\n    const removeImage = () => {\n        // no images, nothing to remove\n        const image = getImage();\n        if (!image)\n            return;\n        // try to abort image load\n        if (imageLoadAbort)\n            imageLoadAbort();\n        image.accessors.loadState = undefined;\n        // clear images\n        accessors.images = [];\n    };\n    //#endregion\n    Object.defineProperty(accessors, 'stores', {\n        get: () => stores,\n    });\n    //#region API\n    defineMethods(accessors, {\n        on: sub,\n        loadImage,\n        abortLoadImage,\n        editImage,\n        removeImage,\n        processImage,\n        abortProcessImage,\n        destroy: () => {\n            unsubSrc && unsubSrc();\n            unsubReader && unsubReader();\n        },\n    });\n    return accessors;\n    //#endregion\n};\n\nconst processImage = (src, options) => {\n    const { processImage } = createImageEditor();\n    return processImage(src, options);\n};\n\nvar getCanvasMemoryLimit = () => {\n    if (!isSafari())\n        return Infinity;\n    if (isIOS()) {\n        // limit resolution a little bit further to prevent drawing issues on iOS Safari 15 and 16\n        if (/15_|16_/.test(navigator.userAgent))\n            return 3840 * 3840;\n        // old iOS can deal with 4096 * 4096 without issues\n        return 4096 * 4096;\n    }\n    // limit resolution a little bit further to prevent drawing issues on MacOS Safari 15 (no problems on 16)\n    return /15_/.test(navigator.userAgent) ? 4096 * 4096 : Infinity;\n};\n\nvar filterObjectProperties = (obj, props) => Object.keys(obj)\n    .filter((key) => !props.includes(key))\n    .reduce((prev, curr) => {\n    prev[curr] = obj[curr];\n    return prev;\n}, {});\n\nvar videoFixDuration = (video) => new Promise((resolve) => {\n    // https://bugs.chromium.org/p/chromium/issues/detail?id=656426\n    // https://bugs.chromium.org/p/chromium/issues/detail?id=642012\n    if (video.duration === Infinity) {\n        video.ontimeupdate = () => {\n            video.ontimeupdate = undefined;\n            resolve(video);\n        };\n        video.currentTime = Number.MAX_SAFE_INTEGER;\n        return;\n    }\n    resolve(video);\n});\n\nvar getVideoElementDuration = (element) => new Promise((resolve, reject) => {\n    const done = () => {\n        videoFixDuration(element).then(() => {\n            resolve(element.duration);\n        });\n    };\n    if (element.readyState >= 1)\n        return done();\n    element.onloadedmetadata = done;\n    element.onerror = () => reject(element.error);\n});\n\nvar arrayFlatten = (arr) => arr.reduce((flat, item) => {\n    const arr = Array.isArray(item) ? [...item] : [item];\n    return [...flat, ...arr];\n}, []);\n\nvar getVideoFileRotationMetadata = async (file) => {\n    const buffer = await blobToArrayBuffer(file);\n    const view = new DataView(buffer);\n    return getRotationMetadataInDataView(view);\n};\nconst blobToArrayBuffer = (blob) => new Promise((resolve) => {\n    const reader = new FileReader();\n    reader.onload = () => resolve(reader.result);\n    reader.readAsArrayBuffer(blob);\n});\n//#region mp4\nconst getRotationMetadataInMP4 = (view, offset, limit) => {\n    // Bytes for degree metadata\n    // 0 degrees\n    // 00010000 00000000 00000000 00000000\n    // 00010000 00000000 00000000 00000000\n    // 40\n    // 90 degrees\n    // 00000000 00010000 00000000 FFFF0000\n    // 00000000 00000000 00000000 00000000\n    // 40\n    // 180 degrees\n    // FFFF0000 00000000 00000000 00000000\n    // FFFF0000 00000000 00000000 00000000\n    // 40\n    // 270 degrees\n    // 00000000 FFFF0000 00000000 00010000\n    // 00000000 00000000 00000000 00000000\n    // 40\n    const TRAK_MARKER = 0x7472616b; // Video track\n    const ROTA_MARKER = 0x40; // Rotation byte\n    let inTrack = false;\n    // rotation marker offset\n    let r = -1;\n    for (let i = offset; i < limit; i++) {\n        // find start of video track\n        if (!inTrack && view.getUint32(i) === TRAK_MARKER) {\n            inTrack = true;\n            i += 4;\n        }\n        // not found yet, skip to next byte\n        if (!inTrack)\n            continue;\n        // found, let's search rotation marker\n        const value = view.getUint8(i);\n        // now looking for rotation marker offset\n        if (value == ROTA_MARKER) {\n            r = i;\n            break;\n        }\n    }\n    // rotation marker not found, exit\n    if (r < 0)\n        return 0;\n    // Let's read bytes preceding the rotation marker entry to check rotation value\n    const B = view.getUint32(r - 28);\n    const D = view.getUint32(r - 20);\n    const A = view.getUint32(r - 32);\n    const E = view.getUint32(r - 16);\n    if (B === 0x00010000 && D === 0xffff0000)\n        return 90;\n    else if (A === 0xffff0000 && E === 0xffff0000)\n        return 180;\n    else if (B === 0xffff0000 && D === 0x00010000)\n        return 270;\n    return 0;\n};\n//#endregion\n//#region mov\nconst MOOV_ATOM = 0x6d6f6f76;\nconst MVHD_ATOM = 0x6d766864;\nconst TKHD_ATOM = 0x746b6864;\nconst TRAK_ATOM = 0x7472616b;\nconst getAtoms = (view, offset = 0, size = view.byteLength) => {\n    const atoms = [];\n    const end = offset + size;\n    while (offset < end) {\n        const size = view.getUint32(offset);\n        if (size < 0)\n            break;\n        const type = view.getUint32(offset + 4);\n        atoms.push({\n            type,\n            size,\n            offset,\n            bodyOffset: offset + 8,\n            bodySize: size - 8,\n        });\n        if (size < 8)\n            break;\n        offset += size;\n    }\n    return atoms;\n};\nconst getRotationMetadataInMOV = (view) => {\n    // find container atoms\n    const atoms = getAtoms(view);\n    // exit no moov atom find\n    const moov = atoms.find((atom) => atom.type === MOOV_ATOM);\n    if (!moov)\n        return 0;\n    // get moov child atoms\n    const moovChildAtoms = getAtoms(view, moov.bodyOffset, moov.bodySize);\n    // get all relevant atoms\n    moovChildAtoms\n        .filter((atom) => atom.type === TRAK_ATOM)\n        .forEach((atom) => {\n        moovChildAtoms.push(...getAtoms(view, atom.bodyOffset, atom.bodySize));\n    });\n    // filter out irrelevant atoms\n    const neededAtoms = [MVHD_ATOM, TKHD_ATOM];\n    const relevantAtoms = moovChildAtoms.filter((atom) => neededAtoms.includes(atom.type));\n    for (const { type, bodyOffset } of relevantAtoms) {\n        // read first byte of body to get version\n        const version = view.getUint8(bodyOffset);\n        // skip version/tags header\n        let offset = bodyOffset + 4;\n        // move pointer based on atom type and version\n        offset += type === MVHD_ATOM ? 32 : 36; //  'mvhd'\n        offset += version === 1 ? 12 : 0;\n        // get relevant part of matrix\n        const A = view.getInt32(offset);\n        const B = view.getInt32(offset + 4);\n        if (A === 0 && B > 0)\n            return 90;\n        if (A < 0 && B === 0)\n            return 180;\n        if (A === 0 && B < 0)\n            return 270;\n    }\n    return 0;\n};\n//#endregion\nconst getRotationMetadataInDataView = (view, { limit = 1024 } = {}) => {\n    const FTYP_MARKER = 0x66747970; // QuickTime Container File Type\n    const MP42_MARKER = 0x6d703432; // MP4 format\n    const QT_MARKER = 0x71742020; // QT format\n    let offset = 0;\n    offset += 4;\n    const container = view.getUint32(offset);\n    if (container !== FTYP_MARKER)\n        return 0;\n    offset += 4;\n    const format = view.getUint32(offset);\n    if (format === MP42_MARKER)\n        return getRotationMetadataInMP4(view, offset, limit);\n    if (format === QT_MARKER)\n        return getRotationMetadataInMOV(view);\n    return 0;\n};\n\nvar blobToVideo = (src) => new Promise((resolve, reject) => {\n    // read metadata\n    const metadataReader = isFirefox() ? getVideoFileRotationMetadata(src) : Promise.resolve(0);\n    // if rotated need to correct video\n    metadataReader.then((rotation) => {\n        // let's load this source as a video file\n        const video = document.createElement('video');\n        video.onerror = () => reject(video.error);\n        video.playsInline = true;\n        video.preload = 'auto';\n        video.onseeked = () => {\n            video.onseeked = undefined;\n            resolve(video);\n        };\n        video.onloadeddata = () => {\n            video.onloadeddata = undefined;\n            video.dataset.rotation = rotation ? `${rotation}` : '0';\n            videoFixDuration(video).then(resolve);\n            // if we use onloadedmetadata safari doesn't render the frame\n            video.currentTime = 0;\n        };\n        // we need to do this otherwise video won't load on iOS Safari, tested up to iOS 17.5\n        // please note that using #t= will work in iOS Simulator but won't work on a real device\n        // we can use srcObject instead as it's only supported on Safari\n        if (isIOS() && isSafari()) {\n            video.srcObject = src;\n            video.load();\n        }\n        else {\n            video.src = URL.createObjectURL(src);\n        }\n    });\n});\n\nvar seekTo = (video, targetTime) => new Promise((resolve) => {\n    // already at target time\n    if (video.currentTime === targetTime)\n        return resolve(video);\n    // backup current fn\n    let onseeked = video.onseeked;\n    video.onseeked = () => {\n        // restore backup\n        video.onseeked = onseeked;\n        // done!\n        resolve(video);\n    };\n    video.currentTime = clamp(targetTime, 0, video.duration);\n});\n\n// TODO: VIDEO cleanup?\nvar videoToImageData = (file, currentTime = 0) => new Promise((resolve, reject) => {\n    // turn blob into video element\n    blobToVideo(file).then((video) => {\n        // now seek to the intended frame\n        seekTo(video, currentTime).then((video) => {\n            // let's turn that frame into a canvas\n            const frame = h('canvas');\n            getVideoElementSize(video).then(({ width, height }) => {\n                // resize canvas to fit video size\n                frame.width = width;\n                frame.height = height;\n                // get context to draw on, we're going to read from this canvas, no need to hardware accelerate it\n                const ctx = frame.getContext('2d', {\n                    willReadFrequently: true,\n                });\n                // draw to canvas context\n                const drawFrame = () => {\n                    ctx.drawImage(video, 0, 0, frame.width, frame.height);\n                    const imageData = ctx.getImageData(0, 0, frame.width, frame.height);\n                    // after draw release canvas memory\n                    releaseCanvas(frame);\n                    // after draw, release video file memory\n                    URL.revokeObjectURL(video.src);\n                    resolve(imageData);\n                };\n                // if we don't use setTimeout for safari sometimes it doesn't draw the frame\n                isSafari() ? setTimeout(drawFrame, 16) : drawFrame();\n            });\n        });\n    });\n});\n\nvar isVideoFile = (blob) => /video/.test(blob.type);\n\nlet result$7 = null;\nvar supportsImageDataColorSpace = () => {\n    if (result$7 === null) {\n        result$7 = new ImageData(1, 1).colorSpace !== undefined;\n    }\n    return result$7;\n};\n\n// custom method to draw images\nconst createCanvasImageDrawer = ({ imageDataResizer, canvasMemoryLimit } = {}) => async (ctx, image, srcRect, destRect, options) => {\n    // min size of src is 1x1\n    srcRect.width = Math.max(srcRect.width, 1);\n    srcRect.height = Math.max(srcRect.height, 1);\n    // min size of dest is 1x1\n    destRect.width = Math.max(destRect.width, 1);\n    destRect.height = Math.max(destRect.height, 1);\n    // get resized image\n    const { dest } = await processImage(image, {\n        imageReader: createDefaultImageReader$1(),\n        imageWriter: createDefaultImageWriter$1({\n            format: 'canvas',\n            targetSize: {\n                ...destRect,\n                upscale: true,\n            },\n            imageDataResizer,\n            canvasMemoryLimit,\n        }),\n        imageCrop: srcRect,\n    });\n    // feather the canvas\n    const { feather = 0 } = options || {};\n    if (feather > 0) {\n        const featherCanvas = h('canvas');\n        featherCanvas.width = dest.width;\n        featherCanvas.height = dest.height;\n        const featherCtx = featherCanvas.getContext('2d', {\n            // this prevents Chrome issue where Chrome doesn't correctly apply the mask in composition operation\n            willReadFrequently: true,\n        });\n        const opacityStep = 1 / feather;\n        let i = 0;\n        for (i = 0; i < feather; i++) {\n            const opacity = i * opacityStep;\n            featherCtx.strokeStyle = `rgba(0,0,0,${opacity * opacity})`;\n            featherCtx.strokeRect(i + 0.5, i + 0.5, dest.width - i * 2 - 1.0, dest.height - i * 2 - 1.0);\n        }\n        featherCtx.fillStyle = '#000';\n        featherCtx.fillRect(i, i, dest.width + 0.5 - i * 2, dest.height + 0.5 - i * 2);\n        const destCtx = dest.getContext('2d');\n        destCtx.globalCompositeOperation = 'destination-in';\n        destCtx.drawImage(featherCanvas, 0, 0);\n        // release image canvas to free up memory\n        releaseCanvas(featherCanvas);\n    }\n    // draw processed image\n    ctx.drawImage(dest, destRect.x, destRect.y, destRect.width, destRect.height);\n    // release image canvas to free up memory\n    releaseCanvas(dest);\n};\n// connect function in process chain\nconst connect = (fn, getter = (...args) => args, setter) => async (state, options, onprogress) => {\n    // will hold function result\n    // at this point we don't know if the length of this task can be computed\n    onprogress(createProgressEvent(0, false));\n    // try to run the function\n    let progressUpdated = false;\n    const res = await fn(...getter(state, options, (event) => {\n        progressUpdated = true;\n        onprogress(event);\n    }));\n    // a setter isn't required\n    setter && setter(state, res);\n    // if progress was updated, we expect the connected function to fire the 1/1 event, else we fire it here\n    if (!progressUpdated)\n        onprogress(createProgressEvent(1, false));\n    return state;\n};\n//\n// Reader/Writer Presets\n//\nconst AnyToFile = ({ willRequest = undefined, srcProp = 'src', destProp = 'dest' } = {}) => [\n    connect(srcToFile, (state, options, onprogress) => [\n        state[srcProp],\n        onprogress,\n        { ...options, willRequest },\n    ], (state, file) => (state[destProp] = file)),\n    'any-to-file',\n];\nconst BlobGuardMimeType = ({ srcProp = 'dest', destProp = 'dest' } = {}) => [\n    connect(async (src) => {\n        // attempt to fix octet stream\n        if (/octet-stream/.test(src.type)) {\n            console.warn(`Pintura: File has unknown mime type \"${src.type}\", make sure your server sets the correct Content-Type header.`);\n            // assume is image\n            let mediaType = 'image';\n            // test if is possibly video\n            const el = await getAsVideoOrImageElement(src);\n            if (/video/i.test(el.nodeName))\n                mediaType = 'video';\n            // set unknown media type\n            const propertyBag = { type: mediaType + '/unknown' };\n            return isFile(src)\n                ? new File([src], src.name, {\n                    ...propertyBag,\n                    lastModified: src.lastModified,\n                })\n                : new Blob([src], propertyBag);\n        }\n        // return original file\n        return src;\n    }, (state) => [state[srcProp]], (state, file) => (state[destProp] = file)),\n    'guard-mimetype',\n];\nconst BlobReadImageSize = ({ srcProp = 'src', destProp = 'size' } = {}) => [\n    connect(getImageSize, (state) => [state[srcProp]], (state, size) => (state[destProp] = size)),\n    'read-image-size',\n];\nconst getMediaDuration = async (src) => {\n    const mediaElement = await getAsVideoOrImageElement(src);\n    if (isVideoElement(mediaElement))\n        return await getVideoElementDuration(mediaElement);\n    return undefined;\n};\nconst BlobReadMediaDuration = ({ srcProp = 'src', destProp = 'duration' } = {}) => [\n    connect(getMediaDuration, (state) => [state[srcProp]], (state, duration) => (state[destProp] = duration)),\n    'read-media-duration',\n];\nconst ImageSizeMatchOrientation = ({ srcSize = 'size', srcOrientation = 'orientation', destSize = 'size', } = {}) => [\n    connect(orientImageSize, (state) => [state[srcSize], state[srcOrientation]], (state, size) => (state[destSize] = size)),\n    'image-size-match-orientation',\n];\nconst BlobCopy = ({ srcProp = 'src', destProp = 'copy' } = {}) => [\n    connect((blob, onprogress) => (isJPEG(blob) ? readFile(blob, onprogress) : undefined), (state) => [state[srcProp], onprogress], (state, head) => {\n        if (!head)\n            return;\n        state[destProp] = head;\n    }),\n    'read-image-head',\n];\nconst ImageHeadReadTags = ({ srcProp = 'copy', orientationProp = 'orientation', colorSpaceProp = 'colorSpace', } = {}) => [\n    connect((head, entries) => {\n        if (!head)\n            return;\n        return arrayBufferImageTagsRead(head, entries);\n    }, (state) => [\n        state[srcProp],\n        {\n            exif: [ORIENTATION_TAG],\n            app2: [COLOR_SPACE_TAG],\n        },\n    ], (state, results) => {\n        if (!results)\n            return;\n        state[orientationProp] = (results.exif && results.exif[ORIENTATION_TAG]) || 1;\n        state[colorSpaceProp] = ((results.app2 && results.app2[COLOR_SPACE_TAG]) ||\n            'sRGB').toLowerCase(); // always 'rgb' or 'display-p3'\n    }),\n    'read-image-head-tags',\n];\nconst ImageHeadClearExifOrientationTag = ({ srcProp = 'copy' } = {}) => [\n    connect((head, entries) => {\n        if (!head)\n            return;\n        return arrayBufferImageTagsWrite(head, entries);\n    }, (state) => [state[srcProp], { exif: [[ORIENTATION_TAG, 1]] }]),\n    'clear-exif-orientation-tag',\n];\nconst CalculateCanvasScalar = ({ srcImageSize = 'size', srcCanvasSize = 'imageData', srcImageState = 'imageState', destImageSize = 'size', destScalar = 'scalar', } = {}) => [\n    connect((naturalSize, canvasSize) => {\n        return [\n            Math.min(canvasSize.width / naturalSize.width, canvasSize.height / naturalSize.height),\n            sizeCreateFromAny(canvasSize),\n        ];\n    }, (state) => [state[srcImageSize], state[srcCanvasSize], state[srcImageState]], (state, [scalar, imageSize]) => {\n        state[destScalar] = scalar;\n        state[destImageSize] = imageSize;\n    }),\n    'calculate-canvas-scalar',\n];\nconst BlobToImageData = ({ srcProp = 'src', destProp = 'imageData', canvasMemoryLimit = undefined, colorSpaceProp = 'colorSpace', srcImageState = 'imageState', } = {}) => [\n    connect((src, canvasMemoryLimit, colorSpace, imageState) => {\n        // can now deal with video files\n        if (isVideoFile(src))\n            return videoToImageData(src, imageState.currentTime);\n        // handle images\n        return blobToImageData(src, { canvasMemoryLimit, colorSpace });\n    }, (state) => [\n        state[srcProp],\n        canvasMemoryLimit,\n        state[colorSpaceProp],\n        state[srcImageState],\n    ], (state, imageData) => (state[destProp] = imageData)),\n    'blob-to-image-data',\n];\nconst ImageDataMatchOrientation = ({ srcImageData = 'imageData', srcOrientation = 'orientation', } = {}) => [\n    connect(orientImageData, (state) => [state[srcImageData], state[srcOrientation]], (state, imageData) => (state.imageData = imageData)),\n    'image-data-match-orientation',\n];\nconst ImageDataFill = ({ srcImageData = 'imageData', srcImageState = 'imageState' } = {}) => [\n    connect(fillImageData, (state) => {\n        const { colorMatrix } = state[srcImageState];\n        const colorMatrices = colorMatrix &&\n            Object.keys(colorMatrix)\n                .map((name) => colorMatrix[name])\n                .filter(Boolean);\n        return [\n            state[srcImageData],\n            {\n                backgroundColor: state[srcImageState].backgroundColor,\n                backgroundImage: state[srcImageState].backgroundImage,\n                backgroundFilterMode: state[srcImageState].backgroundFilterMode,\n                colorMatrix: colorMatrices && getColorMatrixFromColorMatrices(colorMatrices),\n                convolutionMatrix: state[srcImageState].convolutionMatrix,\n                gamma: state[srcImageState].gamma,\n                noise: state[srcImageState].noise,\n                vignette: state[srcImageState].vignette,\n            },\n        ];\n    }, (state, imageData) => (state.imageData = imageData)),\n    'image-data-fill',\n];\nconst ImageDataCrop = ({ srcImageData = 'imageData', srcImageState = 'imageState', destScalar = 'scalar', } = {}) => [\n    connect(cropImageData, (state) => {\n        // scale crop if needed\n        const scalar = state[destScalar];\n        let { crop } = state[srcImageState];\n        if (crop && scalar !== 1) {\n            crop = rectScale(rectClone(crop), scalar, vectorCreateEmpty());\n        }\n        // apply crop\n        return [\n            state[srcImageData],\n            {\n                crop,\n                rotation: state[srcImageState].rotation,\n                flipX: state[srcImageState].flipX,\n                flipY: state[srcImageState].flipY,\n            },\n        ];\n    }, (state, imageData) => (state.imageData = imageData)),\n    'image-data-crop',\n];\nconst hasTargetSize = (imageState) => !!((imageState.targetSize && imageState.targetSize.width) ||\n    (imageState.targetSize && imageState.targetSize.height));\nconst ImageDataResize = ({ targetSize = {\n    width: undefined,\n    height: undefined,\n    fit: undefined,\n    upscale: undefined,\n}, imageDataResizer = undefined, srcProp = 'imageData', srcImageState = 'imageState', destImageScaledSize = 'imageScaledSize', }) => [\n    connect(resizeImageData, (state) => {\n        const width = Math.min(targetSize.width || Number.MAX_SAFE_INTEGER, (state[srcImageState].targetSize && state[srcImageState].targetSize.width) ||\n            Number.MAX_SAFE_INTEGER);\n        const height = Math.min(targetSize.height || Number.MAX_SAFE_INTEGER, (state[srcImageState].targetSize && state[srcImageState].targetSize.height) ||\n            Number.MAX_SAFE_INTEGER);\n        return [\n            state[srcProp],\n            {\n                width,\n                height,\n                fit: targetSize.fit || 'contain',\n                upscale: hasTargetSize(state[srcImageState])\n                    ? true\n                    : targetSize.upscale || false,\n            },\n            imageDataResizer,\n        ];\n    }, (state, imageData) => {\n        // if did resize we need to set scalar\n        if (!sizeEqual(state.imageData, imageData)) {\n            state[destImageScaledSize] = sizeCreateFromAny(imageData);\n        }\n        state.imageData = imageData;\n    }),\n    'image-data-resize',\n];\nconst ImageDataFilter = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', } = {}) => [\n    connect(filterImageData, (state) => {\n        const { colorMatrix } = state[srcImageState];\n        const colorMatrices = colorMatrix &&\n            Object.keys(colorMatrix)\n                .map((name) => colorMatrix[name])\n                .filter(Boolean);\n        return [\n            state[srcImageData],\n            {\n                colorMatrix: colorMatrices && getColorMatrixFromColorMatrices(colorMatrices),\n                convolutionMatrix: state[srcImageState].convolutionMatrix,\n                gamma: state[srcImageState].gamma,\n                noise: state[srcImageState].noise,\n                vignette: state[srcImageState].vignette,\n            },\n        ];\n    }, (state, imageData) => (state[destImageData] = imageData)),\n    'image-data-filter',\n];\nconst ImageDataRedact = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', destScalar = 'scalar', } = {}) => [\n    connect(async (imageData, imageScrambler, imageBackgroundColor, shapes, scalar, redactionRenderStyle) => {\n        // skip!\n        if (!imageScrambler || !shapes.length)\n            return imageData;\n        // create scrambled texture version\n        let scrambledCanvas;\n        try {\n            const options = {\n                dataSizeScalar: getImageRedactionScaleFactor(imageData, shapes),\n            };\n            if (imageBackgroundColor && imageBackgroundColor[3] > 0) {\n                options.backgroundColor = [...imageBackgroundColor];\n            }\n            scrambledCanvas = await imageScrambler(imageData, options);\n        }\n        catch (err) {\n            // log to console for debugging purposes\n        }\n        // create drawing context\n        const canvas = h('canvas');\n        canvas.width = imageData.width;\n        canvas.height = imageData.height;\n        const ctx = canvas.getContext('2d', {\n            willReadFrequently: true,\n            colorSpace: imageData.colorSpace,\n        });\n        ctx.putImageData(imageData, 0, 0);\n        // blur\n        if (redactionRenderStyle === 'auto') {\n            const size = Math.sqrt(imageData.width * imageData.height);\n            ctx.filter = `blur(${Math.round(size / 100)}px)`;\n        }\n        // set up a clip path so we only draw scrambled image within path\n        const path = new Path2D();\n        shapes.forEach((shape) => {\n            const rect = rectCreate(shape.x, shape.y, shape.width, shape.height);\n            rectMultiply(rect, scalar);\n            const corners = rectRotate(rectClone(rect), shape.rotation);\n            const poly = new Path2D();\n            corners.forEach((corner, i) => {\n                if (i === 0)\n                    return poly.moveTo(corner.x, corner.y);\n                poly.lineTo(corner.x, corner.y);\n            });\n            path.addPath(poly);\n        });\n        ctx.clip(path, 'nonzero');\n        ctx.imageSmoothingEnabled = false;\n        ctx.drawImage(scrambledCanvas, 0, 0, canvas.width, canvas.height);\n        releaseCanvas(scrambledCanvas);\n        // done\n        const imageDataOut = ctx.getImageData(0, 0, canvas.width, canvas.height);\n        // clean up memory usage\n        releaseCanvas(canvas);\n        return imageDataOut;\n    }, (state, { imageScrambler, redactionRenderStyle }) => [\n        state[srcImageData],\n        imageScrambler,\n        state[srcImageState].backgroundColor,\n        state[srcImageState].redaction,\n        state[destScalar],\n        redactionRenderStyle,\n    ], (state, imageData) => (state[destImageData] = imageData)),\n    'image-data-redact',\n];\nconst ImageDataAnnotate = ({ srcImageData = 'imageData', srcSize = 'size', srcImageState = 'imageState', srcShapes = 'annotation', destImageData = 'imageData', destImageScaledSize = 'imageScaledSize', destScalar = 'scalar', imageDataResizer = undefined, canvasMemoryLimit = undefined, shapeFilter = passthrough, shapeClip = true, destImageContext = 'imageContext', } = {}) => [\n    connect(drawImageData, (state, { shapePreprocessor, willRequestResource, csp, willRequest }) => {\n        // scale annotations if needed\n        const shapes = state[srcImageState][srcShapes].filter(shapeFilter);\n        // skip if no annotations\n        if (!shapes.length)\n            return [state[srcImageData]];\n        const canvasScalar = state[destScalar];\n        const { crop } = state[srcImageState];\n        const imageSize = state[srcSize];\n        // image is scaled\n        let imageSizeScalar = canvasScalar;\n        const imageTargetSize = state[destImageScaledSize];\n        if (imageTargetSize) {\n            // calculate shapes scalar\n            imageSizeScalar = Math.min(imageTargetSize.width / crop.width, imageTargetSize.height / crop.height);\n        }\n        const imageSizeScaled = {\n            width: imageSize.width / canvasScalar,\n            height: imageSize.height / canvasScalar,\n        };\n        // go\n        return [\n            state[srcImageData],\n            {\n                shapes,\n                computeShape: (shape) => {\n                    shape = shapeComputeDisplay(shape, imageSizeScaled);\n                    shape = filterObjectProperties(shape, ['left', 'right', 'top', 'bottom']);\n                    shape = shapeScale(shape, imageSizeScalar);\n                    return shape;\n                },\n                transform: (ctx) => {\n                    const imageSize = state[srcSize];\n                    const { rotation = 0, flipX, flipY, cropLimitToImage, } = state[srcImageState];\n                    // scale crop if needed\n                    const { crop = rectCreateFromSize(imageSize) } = state[srcImageState];\n                    // calculate image scalar so we can scale annotations accordingly\n                    const scaledSize = state[destImageScaledSize];\n                    let scalar = 1;\n                    if (scaledSize) {\n                        scalar = imageSizeScalar;\n                    }\n                    else {\n                        scalar = canvasScalar;\n                    }\n                    const imageScaledSize = {\n                        width: (imageSize.width / canvasScalar) * scalar,\n                        height: (imageSize.height / canvasScalar) * scalar,\n                    };\n                    const rotatedRect = getImageTransformedRect(imageScaledSize, rotation);\n                    const rotatedSize = {\n                        width: rotatedRect.width,\n                        height: rotatedRect.height,\n                    };\n                    // calculate center\n                    const dx = imageScaledSize.width * 0.5 - rotatedSize.width * 0.5;\n                    const dy = imageScaledSize.height * 0.5 - rotatedSize.height * 0.5;\n                    const center = sizeCenter(imageScaledSize);\n                    // offset\n                    ctx.translate(-dx, -dy);\n                    ctx.translate(-crop.x * scalar, -crop.y * scalar);\n                    // rotation\n                    ctx.translate(center.x, center.y);\n                    ctx.rotate(rotation);\n                    ctx.translate(-center.x, -center.y);\n                    // translate shapes if rendered in outside frame context (for example polaroid)\n                    const shapeTranslation = state[destImageContext] || { x: 0, y: 0 };\n                    ctx.translate(shapeTranslation.x, shapeTranslation.y);\n                    // flipping\n                    ctx.scale(flipX ? -1 : 1, flipY ? -1 : 1);\n                    ctx.translate(flipX ? -imageScaledSize.width * canvasScalar : 0, flipY ? -imageScaledSize.height * canvasScalar : 0);\n                    // annotations are clipped to image\n                    if (cropLimitToImage && shapeClip) {\n                        ctx.rect(0, 0, imageScaledSize.width, imageScaledSize.height);\n                        ctx.clip();\n                    }\n                },\n                drawImage: createCanvasImageDrawer({ imageDataResizer, canvasMemoryLimit }),\n                preprocessShape: (shape) => shapePreprocessor(shape, { isPreview: false, ...state[srcImageState] }),\n                canvasMemoryLimit,\n                willRequest: willRequest || willRequestResource,\n                styleNonce: csp.styleNonce,\n            },\n        ];\n    }, (state, imageData) => (state[destImageData] = imageData)),\n    'image-data-annotate',\n];\nconst ImageDataDecorate = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', destImageScaledSize = 'imageScaledSize', imageDataResizer = undefined, canvasMemoryLimit = undefined, destScalar = 'scalar', shapeFilter = passthrough, destImageContext = 'imageContext', } = {}) => [\n    connect(drawImageData, (state, { shapePreprocessor, willRequestResource, willRequest, csp }) => {\n        // scale annotations if needed\n        // is `let` on purpose\n        let decoration = state[srcImageState].decoration.filter(shapeFilter);\n        // skip if no annotations\n        if (!decoration.length)\n            return [state[srcImageData]];\n        // scale decoration and crop if needed\n        let scalar = state[destScalar];\n        const { crop } = state[srcImageState];\n        // image is scaled\n        const imageTargetSize = state[destImageScaledSize];\n        if (imageTargetSize) {\n            const imageSizeScalar = Math.min(imageTargetSize.width / crop.width, imageTargetSize.height / crop.height);\n            scalar = imageSizeScalar;\n        }\n        // go\n        return [\n            state[srcImageData],\n            {\n                shapes: decoration,\n                drawImage: createCanvasImageDrawer({ imageDataResizer, canvasMemoryLimit }),\n                computeShape: (shape) => {\n                    shape = shapeComputeDisplay(shape, crop);\n                    shape = filterObjectProperties(shape, ['left', 'right', 'top', 'bottom']);\n                    shape = shapeScale(shape, scalar);\n                    return shape;\n                },\n                preprocessShape: (shape) => shapePreprocessor(shape, { isPreview: false, ...state[srcImageState] }),\n                canvasMemoryLimit,\n                willRequest: willRequest || willRequestResource,\n                styleNonce: csp.styleNonce,\n                transform: (ctx) => {\n                    const shapeTranslation = state[destImageContext] || { x: 0, y: 0 };\n                    ctx.translate(shapeTranslation.x, shapeTranslation.y);\n                },\n            },\n        ];\n    }, (state, imageData) => (state[destImageData] = imageData)),\n    'image-data-decorate',\n];\nconst ImageDataFrame = ({ srcImageData = 'imageData', srcImageState = 'imageState', destImageData = 'imageData', destImageScaledSize = 'imageScaledSize', imageDataResizer = undefined, canvasMemoryLimit = undefined, destScalar = 'scalar', destImageContext = 'imageContext', } = {}) => [\n    connect((imageData, options) => new Promise((resolve) => {\n        if (!options)\n            return resolve([imageData]);\n        drawImageData(imageData, options).then((imageData) => {\n            resolve([imageData, options.contextBounds]);\n        });\n    }), (state, { shapePreprocessor, willRequestResource, willRequest, csp }) => {\n        const frame = state[srcImageState].frame;\n        if (!frame)\n            return [state[srcImageData]];\n        // scale crop if needed\n        const scalar = state[destScalar];\n        let { crop } = state[srcImageState];\n        if (crop && scalar !== 1) {\n            crop = rectScale(rectClone(crop), scalar, vectorCreateEmpty());\n        }\n        const context = { ...crop };\n        const bounds = shapesBounds(shapesFromCompositShape(frame, context, shapePreprocessor), context);\n        context.x = Math.abs(bounds.left);\n        context.y = Math.abs(bounds.top);\n        context.width += Math.abs(bounds.left) + Math.abs(bounds.right);\n        context.height += Math.abs(bounds.top) + Math.abs(bounds.bottom);\n        const scaledSize = state[destImageScaledSize];\n        const contextScalarX = scaledSize ? scaledSize.width / crop.width : 1;\n        const contextScalarY = scaledSize ? scaledSize.height / crop.height : 1;\n        context.x *= contextScalarX;\n        context.y *= contextScalarY;\n        context.width *= contextScalarX;\n        context.height *= contextScalarY;\n        // use round sizes because we can't fill half pixels\n        context.x = Math.round(context.x);\n        context.y = Math.round(context.y);\n        context.width = Math.round(context.width);\n        context.height = Math.round(context.height);\n        // correct for small rounding errors\n        if (scaledSize) {\n            if (Math.abs(context.width - scaledSize.width) <= 1) {\n                context.width = scaledSize.width;\n            }\n            if (Math.abs(context.height - scaledSize.height) <= 1) {\n                context.height = scaledSize.height;\n            }\n        }\n        return [\n            state[srcImageData],\n            {\n                shapes: [frame],\n                contextBounds: context,\n                computeShape: (shape) => shapeComputeDisplay(shape, state[srcImageData]),\n                transform: (ctx) => {\n                    ctx.translate(context.x, context.y);\n                },\n                drawImage: createCanvasImageDrawer({ imageDataResizer, canvasMemoryLimit }),\n                preprocessShape: (shape) => shapePreprocessor(shape, { isPreview: false, ...state[srcImageState] }),\n                canvasMemoryLimit,\n                willRequest: willRequest || willRequestResource,\n                styleNonce: csp.styleNonce,\n            },\n        ];\n    }, (state, [imageData, context]) => {\n        state[destImageContext] = context;\n        state[destImageData] = imageData;\n    }),\n    'image-data-frame',\n];\nconst ImageDataToBlob = ({ mimeType = undefined, quality = undefined, srcImageData = 'imageData', srcFile = 'src', destBlob = 'blob', } = {}) => [\n    connect(imageDataToBlob, (state) => [\n        state[srcImageData],\n        mimeType || getMimeTypeFromFilename(state[srcFile].name) || state[srcFile].type,\n        quality,\n    ], (state, blob) => (state[destBlob] = blob)),\n    'image-data-to-blob',\n];\nconst ImageDataToCanvas = ({ srcImageData = 'imageData', srcOrientation = 'orientation', destCanvas = 'dest', } = {}) => [\n    connect(imageDataToCanvas, (state) => [state[srcImageData], state[srcOrientation]], (state, canvas) => (state[destCanvas] = canvas)),\n    'image-data-to-canvas',\n];\nconst writeImageHead = async (blob, head, colorSpace) => {\n    if (!isJPEG(blob) || !head)\n        return blob;\n    const isDisplayP3 = /p3/i.test(colorSpace);\n    const eachMarker = (ab, cb) => {\n        // Skip JPEG identifier\n        let offset = 2;\n        const dataView = new DataView(ab);\n        const byteLength = dataView.byteLength;\n        // start\n        cb(dataView.getUint8(0), 0, 2, byteLength);\n        // loop over bytes\n        while (offset < byteLength) {\n            if (dataView.getUint8(offset) != 0xff)\n                break;\n            const marker = dataView.getUint8(offset + 1);\n            const length = dataView.getUint16(offset + 2) + 2;\n            // can exit if returns false\n            if (cb(marker, offset, length, byteLength) === false)\n                break;\n            offset += length;\n        }\n    };\n    const isAppHeader = (marker) => {\n        return marker >= 224 && marker <= 237; // APP0 to APP13\n    };\n    const getAppHeaders = (arrayBuffer) => {\n        const headers = [];\n        eachMarker(arrayBuffer, (marker, offset, length) => {\n            // start of scan\n            if (marker === 0xda)\n                return false;\n            // app header\n            if (isAppHeader(marker)) {\n                // we filter out APP2 (color profile) if we're not in p3 color space, other color profiles are applied to the image when loaded and copying them would result in multiplied colors\n                // is APP2 header\n                if (marker === 226) {\n                    // this isn't a display p3 color space, so we can skip the APP2 header\n                    if (!isDisplayP3) {\n                        return false;\n                    }\n                    // is display p3 color space, need to test if browser supports image data color space\n                    if (!supportsImageDataColorSpace()) {\n                        return false;\n                    }\n                }\n                // we keep other headers\n                headers.push(new Uint8Array(arrayBuffer, offset, length));\n            }\n        });\n        return headers;\n    };\n    const insertAppHeaders = (arrayBuffer, appHeaders) => {\n        const segments = [];\n        eachMarker(arrayBuffer, (marker, offset, length, totalLength) => {\n            // start of image marker\n            if (offset === 0) {\n                // add start header\n                segments.push(new Uint8Array(arrayBuffer, offset, length));\n                // add original app headers\n                segments.push(...appHeaders);\n                return;\n            }\n            // start of scan\n            if (marker === 0xda) {\n                segments.push(new Uint8Array(arrayBuffer, offset, totalLength - offset));\n                return false;\n            }\n            // app header\n            if (!isAppHeader(marker)) {\n                segments.push(new Uint8Array(arrayBuffer, offset, length));\n            }\n        });\n        // created new file\n        let combinedLength = segments.reduce((acc, seg) => acc + seg.length, 0);\n        let combinedArray = new Uint8Array(combinedLength);\n        let currentOffset = 0;\n        segments.forEach((segment) => {\n            combinedArray.set(segment, currentOffset);\n            currentOffset += segment.length;\n        });\n        return combinedArray;\n    };\n    // gets app headers from original file\n    const srcAppHeaders = getAppHeaders(head);\n    // removes any app headers from this file (Chrome recently (2024) started adding these)\n    const destUintArray = insertAppHeaders(await readFile(blob), srcAppHeaders);\n    return new Blob([destUintArray], { type: 'image/jpeg' });\n};\nconst BlobWriteImageHead = (srcBlob = 'blob', srcHead = 'copy', srcColorSpace = 'colorSpace', destBlob = 'blob') => [\n    connect((blob, head, colorSpace) => {\n        if (!head)\n            return;\n        return writeImageHead(blob, head, colorSpace);\n    }, (state) => [state[srcBlob], state[srcHead], state[srcColorSpace]], (state, blob) => {\n        if (!blob)\n            return;\n        state[destBlob] = blob;\n    }),\n    'blob-write-image-head',\n];\nconst BlobToFile = ({ renameFile = undefined, srcBlob = 'blob', srcFile = 'src', destFile = 'dest', defaultFilename = undefined, } = {}) => [\n    connect(blobToFile, (state) => [\n        state[srcBlob],\n        renameFile\n            ? renameFile(state[srcFile])\n            : state[srcFile].name ||\n                `${defaultFilename}.${getExtensionFromMimeType(state[srcBlob].type)}`,\n    ], (state, file) => (state[destFile] = file)),\n    'blob-to-file',\n];\nconst Store = ({ url = './', dataset = (state) => [\n    ['dest', state.dest, state.dest.name],\n    ['imageState', state.imageState],\n], destStore = 'store', credentials, headers = {}, }) => [\n    connect(\n    // upload function\n    async (dataset, onprogress) => await post(url, dataset, {\n        onprogress,\n        beforeSend: (xhr) => configureXHR(xhr, { headers, credentials }),\n    }), \n    // get state values\n    (state, options, onprogress) => [\n        dataset(state),\n        onprogress,\n    ], \n    // set state values\n    (state, xhr) => (state[destStore] = xhr) // logs XHR request returned by `post`\n    ),\n    'store',\n];\nconst PropFilter = (allowlist) => [\n    connect((state) => {\n        // if no allowlist suppleid or is empty array we don't filter\n        if (!allowlist || !allowlist.length)\n            return state;\n        // else we only allow the props defined in the list and delete non matching props\n        Object.keys(state).forEach((key) => {\n            if (allowlist.includes(key))\n                return;\n            delete state[key];\n        });\n        return state;\n    }),\n    'prop-filter',\n];\n// Generic image reader, suitable for most use cases\nconst createDefaultImageReader$1 = (options = {}) => {\n    const { \n    // add xhr Promise intercept here\n    orientImage = true, outputProps = ['src', 'dest', 'size', 'duration'], preprocessImageFile, request = {}, } = options;\n    return [\n        // can read most source files and turn them into blobs\n        AnyToFile({ willRequest: () => request }), // src -> dest\n        // test if supported mime/type\n        BlobGuardMimeType(),\n        // called when file created, can be used to read unrecognized files\n        preprocessImageFile && [\n            connect(preprocessImageFile, (state, options, onprogress) => [\n                state.dest,\n                options,\n                onprogress,\n            ], (state, file) => (state.dest = file)),\n            'preprocess-image-file',\n        ],\n        // quickly read size (only reads first part of image)\n        BlobReadImageSize({ srcProp: 'dest' }), // default is 'src', dest -> size\n        // quickly read duration\n        BlobReadMediaDuration({ srcProp: 'dest' }), // default is 'src', dest -> duration\n        // fix image orientation\n        orientImage && BlobCopy({ srcProp: 'dest' }), // dest -> head\n        orientImage && ImageHeadReadTags(), // head -> orientation\n        orientImage && ImageSizeMatchOrientation(), // [size, orientation] -> size\n        // remove unwanted props\n        PropFilter(outputProps),\n    ].filter(Boolean);\n};\nconst createStore = (store) => store &&\n    (isString(store)\n        ? // a basic store to post to\n            Store({ url: store })\n        : // see if is fully custom or store config\n            isFunction(store)\n                ? // fully custom store function\n                    [store, 'store']\n                : // a store configuration object\n                    Store(store));\nconst createDefaultImageWriter$1 = (options = {}) => (src, imageState, genericOptions = {}) => {\n    // let's go!\n    let { canvasMemoryLimit = getCanvasMemoryLimit(), orientImage = true, copyImageHead = true, mimeType = undefined, quality = undefined, renameFile = undefined, targetSize = undefined, imageDataResizer = undefined, store = undefined, format = 'file', outputProps = ['src', 'dest', 'imageState', 'store'], preprocessImageSource = undefined, preprocessImageState = undefined, postprocessImageData = undefined, postprocessImageBlob = undefined, \n    // by default doesn't test if should process, this prop is set to true by media writer\n    testSrcSupport = false, } = { ...options, ...genericOptions };\n    // if doesn't pass src filter, skip\n    if (testSrcSupport && !isImage(src))\n        return;\n    // use 'file' format if defined as 'blob'\n    if (format === 'blob')\n        format = 'file';\n    return [\n        // allow preprocessing of image blob, should return a new blob, for example to automatically make image background transparent\n        preprocessImageSource && [\n            connect(preprocessImageSource, (state, options, onprogress) => [state.src, options, onprogress, state.imageState], (state, src) => (state.src = src)),\n            'preprocess-image-source',\n        ],\n        // get orientation info (if is jpeg)\n        (orientImage || copyImageHead) && BlobCopy(), // src -> head\n        ImageHeadReadTags(), // head -> orientation, colorSpace\n        // get image size\n        BlobReadImageSize(), // src -> size\n        // allow preproccesing of image state for example to replace placeholders\n        preprocessImageState && [\n            connect(preprocessImageState, (state, options, onprogress, metadata) => [\n                state.imageState,\n                options,\n                onprogress,\n                { size: state.size, orientation: state.orientation },\n            ], (state, imageState) => (state.imageState = imageState)),\n            'preprocess-image-state',\n        ],\n        // get image data\n        BlobToImageData({ canvasMemoryLimit }), // src -> imageData\n        // fix image orientation\n        orientImage && ImageSizeMatchOrientation(), // [size, orientation] -> size\n        orientImage && ImageDataMatchOrientation(),\n        // apply canvas scalar to data\n        CalculateCanvasScalar(),\n        // apply image state\n        ImageDataRedact(),\n        ImageDataCrop(),\n        ImageDataResize({ imageDataResizer, targetSize }),\n        ImageDataAnnotate({ imageDataResizer, canvasMemoryLimit, srcShapes: 'manipulation' }),\n        ImageDataFilter(),\n        ImageDataFill(),\n        ImageDataAnnotate({\n            imageDataResizer,\n            canvasMemoryLimit,\n            srcShapes: 'annotation',\n            shapeFilter: (shape) => !shape.aboveFrame,\n        }),\n        ImageDataDecorate({\n            imageDataResizer,\n            canvasMemoryLimit,\n            shapeFilter: (shape) => !shape.aboveFrame,\n        }),\n        ImageDataFrame({ imageDataResizer, canvasMemoryLimit }),\n        // Draw on top of frame\n        ImageDataAnnotate({\n            imageDataResizer,\n            canvasMemoryLimit,\n            srcShapes: 'annotation',\n            shapeFilter: (shape) => shape.aboveFrame,\n            shapeClip: false,\n        }),\n        ImageDataDecorate({\n            imageDataResizer,\n            canvasMemoryLimit,\n            shapeFilter: (shape) => shape.aboveFrame,\n        }),\n        // run post processing on image data, for example to apply circular crop\n        postprocessImageData && [\n            connect(postprocessImageData, (state, options, onprogress) => [state.imageData, options, onprogress], (state, imageData) => (state.imageData = imageData)),\n            'postprocess-image-data',\n        ],\n        // convert to correct output format\n        format === 'file'\n            ? ImageDataToBlob({ mimeType, quality })\n            : format === 'canvas'\n                ? ImageDataToCanvas()\n                : [\n                    (state) => {\n                        state.dest = state.imageData;\n                        return state;\n                    },\n                ],\n        // we overwite the exif orientation tag so the image is oriented correctly\n        format === 'file' && orientImage && ImageHeadClearExifOrientationTag(),\n        // we write the new image head to the target blob\n        format === 'file' && copyImageHead && BlobWriteImageHead(),\n        // allow converting the blob to a different format\n        postprocessImageBlob && [\n            connect(postprocessImageBlob, ({ blob, imageData, src }, options, onprogress) => [{ blob, imageData, src }, options, onprogress], (state, blob) => (state.blob = blob)),\n            'postprocess-image-file',\n        ],\n        // turn the image blob into a file, will also rename the file\n        format === 'file' && BlobToFile({ defaultFilename: 'image', renameFile }),\n        // upload or process data if is a file\n        format === 'file'\n            ? // used for file output formats\n                createStore(store)\n            : // used for imageData and canvas output formats\n                isFunction(store) && [store, 'store'],\n        // remove unwanted props\n        PropFilter(outputProps),\n    ].filter(Boolean);\n};\nconst isWriter = (param) => Array.isArray(param) || isFunction(param);\nconst createDefaultMediaWriter$1 = (genericWriterOptions, ...writers) => (src, imageState) => {\n    // no generic options passed\n    if (isWriter(genericWriterOptions))\n        writers = [genericWriterOptions, ...writers];\n    const genericOptions = (isObject(genericWriterOptions) ? genericWriterOptions : {});\n    // if used in media writer the sub writers need to test if they support the source file\n    genericOptions.testSrcSupport = true;\n    // currently assigned writers\n    writers = Array.isArray(writers) ? arrayFlatten(writers) : writers;\n    // loop over writers and return first that is a match\n    for (let i = 0; i < writers.length; i++) {\n        const res = writers[i](src, imageState, genericOptions);\n        if (Array.isArray(res))\n            return res;\n    }\n};\n\nvar calculateImageTransforms = (stageRect, rootRect, imageSize, cropRect, imageSelectionRect, imageSelectionRectScalar, imageSelectionRectTranslation, imageScale, imageRotation, imageFlipX, imageFlipY) => {\n    if (!stageRect || !rootRect || !imageSize || !cropRect || !imageScale)\n        return undefined;\n    // scale presentation\n    imageScale *= imageSelectionRectScalar;\n    const viewRect = rectNormalizeOffset(rectClone(rootRect));\n    const viewCenter = rectCenter(viewRect);\n    const stageCenter = rectCenter(stageRect);\n    const imageRect = rectCreateFromSize(imageSize);\n    const imageCenter = rectCenter(imageRect);\n    // get base crop rect so we can correctly apply transforms\n    const cropRectBase = getBaseCropRect(imageSize, cropRect, imageRotation);\n    const cropRectBaseCenter = rectCenter(cropRectBase);\n    const imageTranslation = vectorSubtract(vectorClone(imageCenter), cropRectBaseCenter);\n    // calculate stage center offset from view center\n    const imageOffset = vectorSubtract(vectorClone(stageCenter), viewCenter);\n    // correct for stage offset\n    imageTranslation.x += imageOffset.x;\n    imageTranslation.y += imageOffset.y;\n    // set origin of translation (so rotates around center of selection)\n    const imageOrigin = vectorInvert(vectorClone(imageTranslation));\n    // correct for stage offset\n    imageOrigin.x += imageOffset.x;\n    imageOrigin.y += imageOffset.y;\n    // correct for image selection offset relative to view\n    const imageSelectionCenter = rectCenter(rectTranslate(rectTranslate(rectClone(imageSelectionRect), imageSelectionRectTranslation), stageRect));\n    const imageSelectionOffset = vectorSubtract(imageSelectionCenter, stageCenter);\n    vectorAdd(imageTranslation, imageSelectionOffset);\n    return {\n        origin: imageOrigin,\n        translation: imageTranslation,\n        rotation: {\n            x: imageFlipY ? Math.PI : 0,\n            y: imageFlipX ? Math.PI : 0,\n            z: imageRotation,\n        },\n        scale: imageScale,\n    };\n};\n\nlet result$6 = null;\nvar supportsWebGL2 = () => {\n    if (result$6 === null) {\n        if ('WebGL2RenderingContext' in window) {\n            let canvas;\n            try {\n                canvas = h('canvas');\n                result$6 = !!canvas.getContext('webgl2');\n            }\n            catch (err) {\n                result$6 = false;\n            }\n            canvas && releaseCanvas(canvas);\n            canvas = undefined;\n        }\n        else {\n            result$6 = false;\n        }\n    }\n    return result$6;\n};\n\nvar isPowerOf2 = (value) => (value & (value - 1)) === 0;\n\nvar stringReplace = (str, entries = {}, prefix = '', postfix = '') => {\n    return Object.keys(entries)\n        .filter((key) => !isObject(entries[key]))\n        .reduce((prev, curr) => {\n        return prev.replace(new RegExp(prefix + curr + postfix), entries[curr]);\n    }, str);\n};\n\nvar SHADER_FRAG_HEAD = \"#version 300 es\\nprecision highp float;\\n\\nout vec4 fragColor;\"; // eslint-disable-line\n\nvar SHADER_FRAG_INIT = \"\\nfloat a=1.0;vec4 fillColor=uColor;vec4 textureColor=texture(uTexture,vTexCoord);textureColor*=(1.0-step(uRepeat.y,vTexCoord.y))*step(0.0,vTexCoord.y)*(1.0-step(uRepeat.x,vTexCoord.x))*step(0.0,vTexCoord.x);\"; // eslint-disable-line\n\nvar SHADER_FRAG_MASK = \"\\nuniform float uMaskFeather[8];uniform float uMaskBounds[4];uniform float uMaskOpacity;float mask(float x,float y,float bounds[4],float opacity){return 1.0-(1.0-(smoothstep(bounds[3],bounds[3]+1.0,x)*(1.0-smoothstep(bounds[1]-1.0,bounds[1],x))*(1.0-step(bounds[0],y))*step(bounds[2],y)))*(1.0-opacity);}\"; // eslint-disable-line\n\nvar SHADER_FRAG_MASK_APPLY = \"\\nfloat m=mask(gl_FragCoord.x,gl_FragCoord.y,uMaskBounds,uMaskOpacity);\"; // eslint-disable-line\n\nvar SHADER_FRAG_MASK_FEATHER_APPLY = \"\\nfloat leftFeatherOpacity=step(uMaskFeather[1],gl_FragCoord.x)*uMaskFeather[0]+((1.0-uMaskFeather[0])*smoothstep(uMaskFeather[1],uMaskFeather[3],gl_FragCoord.x));float rightFeatherOpacity=(1.0-step(uMaskFeather[7],gl_FragCoord.x))*uMaskFeather[4]+((1.0-uMaskFeather[4])*smoothstep(uMaskFeather[7],uMaskFeather[5],gl_FragCoord.x));a*=leftFeatherOpacity*rightFeatherOpacity;\"; // eslint-disable-line\n\nvar SHADER_FRAG_RECT_AA = \"\\nvec2 scaledPoint=vec2(vRectCoord.x*uSize.x,vRectCoord.y*uSize.y);a*=smoothstep(0.0,uEdgeFeather,uSize.x-scaledPoint.x);a*=smoothstep(0.0,uEdgeFeather,uSize.y-scaledPoint.y);a*=smoothstep(0.0,uEdgeFeather,scaledPoint.x);a*=smoothstep(0.0,uEdgeFeather,scaledPoint.y);\"; // eslint-disable-line\n\nvar SHADER_FRAG_CORNER_RADIUS = \"\\nvec2 s=(uSize-2.0)*.5;vec2 r=(vRectCoord*uSize)-1.0;vec2 p=r-s;float cornerRadius=uCornerRadius[0];bool left=r.x<s.x;bool top=r.y<s.y;if(!left&&top){cornerRadius=uCornerRadius[1];}if(!left&&!top){cornerRadius=uCornerRadius[3];}if(left&&!top){cornerRadius=uCornerRadius[2];}a*=1.0-clamp(length(max(abs(p)-(s-cornerRadius),0.0))-cornerRadius,0.0,1.0);\"; // eslint-disable-line\n\nvar SHADER_FRAG_SHAPE_BLEND_COLOR = \"\\nif(m<=0.0)discard;fillColor.a*=a;fillColor.rgb*=fillColor.a;fillColor.rgb*=m;fillColor.rgb+=(1.0-m)*(uCanvasColor.rgb*fillColor.a);textureColor*=uTextureOpacity;textureColor.a*=a;textureColor.rgb*=m*a;textureColor.rgb+=(1.0-m)*(uCanvasColor.rgb*textureColor.a);fragColor=textureColor+(fillColor*(1.0-textureColor.a));\"; // eslint-disable-line\n\nvar SHADER_FRAG_TEXTURE_COLORIZE = \"\\nif(uTextureColor.a!=0.0&&textureColor.a>0.0){vec3 colorFlattened=textureColor.rgb/textureColor.a;if(colorFlattened.r>=.9999&&colorFlattened.g==0.0&&colorFlattened.b>=.9999){textureColor.rgb=uTextureColor.rgb*textureColor.a;}textureColor*=uTextureColor.a;}\"; // eslint-disable-line\n\nvar SHADER_VERT_HEAD = \"#version 300 es\\n\\nin vec4 aPosition;uniform mat4 uMatrix;\"; // eslint-disable-line\n\nvar SHADER_VERT_MULTIPLY_MATRUX = \"\\ngl_Position=uMatrix*vec4(aPosition.x,aPosition.y,0,1);\"; // eslint-disable-line\n\nvar SHADER_VERT_TEXTURE = \"\\nin vec2 aTexCoord;out vec2 vTexCoord;\"; // eslint-disable-line\n\nconst SHADER_VERT_SNIPPETS = {\n    head: SHADER_VERT_HEAD,\n    text: SHADER_VERT_TEXTURE,\n    matrix: SHADER_VERT_MULTIPLY_MATRUX,\n};\nconst SHADER_FRAG_SNIPPETS = {\n    head: SHADER_FRAG_HEAD,\n    mask: SHADER_FRAG_MASK,\n    init: SHADER_FRAG_INIT,\n    colorize: SHADER_FRAG_TEXTURE_COLORIZE,\n    maskapply: SHADER_FRAG_MASK_APPLY,\n    maskfeatherapply: SHADER_FRAG_MASK_FEATHER_APPLY,\n    rectaa: SHADER_FRAG_RECT_AA,\n    cornerradius: SHADER_FRAG_CORNER_RADIUS,\n    fragcolor: SHADER_FRAG_SHAPE_BLEND_COLOR,\n};\nconst transpileShader = (gl, src, type) => {\n    src = stringReplace(src, type === gl.VERTEX_SHADER ? SHADER_VERT_SNIPPETS : SHADER_FRAG_SNIPPETS, '##').trim();\n    // ready if supports webgl\n    if (supportsWebGL2())\n        return src;\n    src = src.replace(/#version.+/gm, '').trim();\n    src = src.replace(/^\\/\\/\\#/gm, '#');\n    if (type === gl.VERTEX_SHADER) {\n        src = src.replace(/in /gm, 'attribute ').replace(/out /g, 'varying ');\n    }\n    if (type === gl.FRAGMENT_SHADER) {\n        src = src\n            .replace(/in /gm, 'varying ')\n            .replace(/out.*?;/gm, '')\n            .replace(/texture\\(/g, 'texture2D(')\n            .replace(/fragColor/g, 'gl_FragColor');\n    }\n    return `${src}`;\n};\nconst compileShader = (gl, src, type) => {\n    const shader = gl.createShader(type);\n    if (!shader) {\n        return null;\n    }\n    const transpiledSrc = transpileShader(gl, src, type);\n    gl.shaderSource(shader, transpiledSrc);\n    gl.compileShader(shader);\n    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n        console.error(gl.getShaderInfoLog(shader));\n    }\n    return shader;\n};\nconst createShader = (gl, vertexShaderCode, fragmentShaderCode, attribs, uniforms) => {\n    const vertexShader = compileShader(gl, vertexShaderCode, gl.VERTEX_SHADER);\n    const fragmentShader = compileShader(gl, fragmentShaderCode, gl.FRAGMENT_SHADER);\n    if (!vertexShader || !fragmentShader) {\n        return null;\n    }\n    const program = gl.createProgram();\n    gl.attachShader(program, vertexShader);\n    gl.attachShader(program, fragmentShader);\n    gl.linkProgram(program);\n    const locations = {};\n    attribs.forEach((name) => {\n        locations[name] = gl.getAttribLocation(program, name);\n    });\n    uniforms.forEach((name) => {\n        locations[name] = gl.getUniformLocation(program, name);\n    });\n    return {\n        program,\n        locations,\n        destroy() {\n            gl.detachShader(program, vertexShader);\n            gl.detachShader(program, fragmentShader);\n            gl.deleteShader(vertexShader);\n            gl.deleteShader(fragmentShader);\n            gl.deleteProgram(program);\n        },\n    };\n};\nconst canMipMap = (source) => {\n    if (source['nodeName'] === 'VIDEO')\n        return false;\n    if (supportsWebGL2())\n        return true;\n    return isPowerOf2(source.width) && isPowerOf2(source.height);\n};\nconst applyTextureProperties = (gl, source, options) => {\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, canMipMap(source) ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, options.filterParam);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, options.wrapParam);\n    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, options.wrapParam);\n    if (canMipMap(source)) {\n        gl.generateMipmap(gl.TEXTURE_2D);\n    }\n};\nconst updateTexture = (gl, texture, source, options) => {\n    const { premultiply = true } = options;\n    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiply);\n    gl.bindTexture(gl.TEXTURE_2D, texture);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n    applyTextureProperties(gl, source, options);\n    gl.bindTexture(gl.TEXTURE_2D, null);\n    return texture;\n};\nconst applyOpacity = (color, opacity = 1) => color\n    ? [color[0], color[1], color[2], isNumber(color[3]) ? opacity * color[3] : opacity]\n    : [0, 0, 0, 0];\n\nconst mat4Create = () => {\n    const mat = new Float32Array(16);\n    mat[0] = 1;\n    mat[5] = 1;\n    mat[10] = 1;\n    mat[15] = 1;\n    return mat;\n};\nconst mat4Perspective = (mat, fovy, aspect, near, far) => {\n    const f = 1.0 / Math.tan(fovy / 2);\n    const nf = 1 / (near - far);\n    mat[0] = f / aspect;\n    mat[1] = 0;\n    mat[2] = 0;\n    mat[3] = 0;\n    mat[4] = 0;\n    mat[5] = f;\n    mat[6] = 0;\n    mat[7] = 0;\n    mat[8] = 0;\n    mat[9] = 0;\n    mat[10] = (far + near) * nf;\n    mat[11] = -1;\n    mat[12] = 0;\n    mat[13] = 0;\n    mat[14] = 2 * far * near * nf;\n    mat[15] = 0;\n};\nconst mat4Ortho = (mat, left, right, bottom, top, near, far) => {\n    const lr = 1 / (left - right);\n    const bt = 1 / (bottom - top);\n    const nf = 1 / (near - far);\n    mat[0] = -2 * lr;\n    mat[1] = 0;\n    mat[2] = 0;\n    mat[3] = 0;\n    mat[4] = 0;\n    mat[5] = -2 * bt;\n    mat[6] = 0;\n    mat[7] = 0;\n    mat[8] = 0;\n    mat[9] = 0;\n    mat[10] = 2 * nf;\n    mat[11] = 0;\n    mat[12] = (left + right) * lr;\n    mat[13] = (top + bottom) * bt;\n    mat[14] = (far + near) * nf;\n    mat[15] = 1;\n};\nconst mat4Translate = (mat, x, y, z) => {\n    mat[12] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];\n    mat[13] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];\n    mat[14] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];\n    mat[15] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15];\n};\nconst mat4Scale = (mat, s) => {\n    mat[0] *= s;\n    mat[1] *= s;\n    mat[2] *= s;\n    mat[3] *= s;\n    mat[4] *= s;\n    mat[5] *= s;\n    mat[6] *= s;\n    mat[7] *= s;\n    mat[8] *= s;\n    mat[9] *= s;\n    mat[10] *= s;\n    mat[11] *= s;\n};\nconst mat4ScaleX = (mat, s) => {\n    mat[0] *= s;\n    mat[1] *= s;\n    mat[2] *= s;\n    mat[3] *= s;\n};\nconst mat4ScaleY = (mat, s) => {\n    mat[4] *= s;\n    mat[5] *= s;\n    mat[6] *= s;\n    mat[7] *= s;\n};\nconst mat4RotateX = (mat, rad) => {\n    const s = Math.sin(rad);\n    const c = Math.cos(rad);\n    const a10 = mat[4];\n    const a11 = mat[5];\n    const a12 = mat[6];\n    const a13 = mat[7];\n    const a20 = mat[8];\n    const a21 = mat[9];\n    const a22 = mat[10];\n    const a23 = mat[11];\n    mat[4] = a10 * c + a20 * s;\n    mat[5] = a11 * c + a21 * s;\n    mat[6] = a12 * c + a22 * s;\n    mat[7] = a13 * c + a23 * s;\n    mat[8] = a20 * c - a10 * s;\n    mat[9] = a21 * c - a11 * s;\n    mat[10] = a22 * c - a12 * s;\n    mat[11] = a23 * c - a13 * s;\n};\nconst mat4RotateY = (mat, rad) => {\n    const s = Math.sin(rad);\n    const c = Math.cos(rad);\n    const a00 = mat[0];\n    const a01 = mat[1];\n    const a02 = mat[2];\n    const a03 = mat[3];\n    const a20 = mat[8];\n    const a21 = mat[9];\n    const a22 = mat[10];\n    const a23 = mat[11];\n    mat[0] = a00 * c - a20 * s;\n    mat[1] = a01 * c - a21 * s;\n    mat[2] = a02 * c - a22 * s;\n    mat[3] = a03 * c - a23 * s;\n    mat[8] = a00 * s + a20 * c;\n    mat[9] = a01 * s + a21 * c;\n    mat[10] = a02 * s + a22 * c;\n    mat[11] = a03 * s + a23 * c;\n};\nconst mat4RotateZ = (mat, rad) => {\n    const s = Math.sin(rad);\n    const c = Math.cos(rad);\n    const a00 = mat[0];\n    const a01 = mat[1];\n    const a02 = mat[2];\n    const a03 = mat[3];\n    const a10 = mat[4];\n    const a11 = mat[5];\n    const a12 = mat[6];\n    const a13 = mat[7];\n    mat[0] = a00 * c + a10 * s;\n    mat[1] = a01 * c + a11 * s;\n    mat[2] = a02 * c + a12 * s;\n    mat[3] = a03 * c + a13 * s;\n    mat[4] = a10 * c - a00 * s;\n    mat[5] = a11 * c - a01 * s;\n    mat[6] = a12 * c - a02 * s;\n    mat[7] = a13 * c - a03 * s;\n};\n\nvar degToRad = (degrees) => degrees * Math.PI / 180;\n\nvar getWebGLContext = (canvas, attrs) => {\n    if (supportsWebGL2())\n        return canvas.getContext('webgl2', attrs);\n    return (canvas.getContext('webgl', attrs) ||\n        canvas.getContext('experimental-webgl', attrs));\n};\n\nvar imageFragmentShader = \"\\n##head\\nin vec2 vTexCoord;uniform sampler2D uTexture;uniform sampler2D uTextureOverlay;uniform sampler2D uTextureBlend;uniform vec2 uTextureSize;uniform float uOpacity;uniform int uAntialias;uniform vec4 uOverlayColor;uniform mat4 uColorMatrix;uniform vec4 uColorOffset;uniform float uClarityKernel[9];uniform float uClarityKernelWeight;uniform float uColorGamma;uniform float uColorVignette;uniform float uMaskClip;uniform float uMaskOpacity;uniform float uMaskBounds[4];uniform float uMaskCornerRadius[4];uniform float uMaskFeather[8];vec4 applyGamma(vec4 c,float g){c.r=pow(c.r,g);c.g=pow(c.g,g);c.b=pow(c.b,g);return c;}vec4 applyColorMatrix(vec4 c,mat4 m,vec4 o){vec4 res=(c*m)+(o*c.a);res=clamp(res,0.0,1.0);return res;}vec4 applyConvolutionMatrix(vec4 c,float k0,float k1,float k2,float k3,float k4,float k5,float k6,float k7,float k8,float w){vec2 pixel=vec2(1)/uTextureSize;vec4 colorSum=texture(uTexture,vTexCoord-pixel)*k0+texture(uTexture,vTexCoord+pixel*vec2(0.0,-1.0))*k1+texture(uTexture,vTexCoord+pixel*vec2(1.0,-1.0))*k2+texture(uTexture,vTexCoord+pixel*vec2(-1.0,0.0))*k3+texture(uTexture,vTexCoord)*k4+texture(uTexture,vTexCoord+pixel*vec2(1.0,0.0))*k5+texture(uTexture,vTexCoord+pixel*vec2(-1.0,1.0))*k6+texture(uTexture,vTexCoord+pixel*vec2(0.0,1.0))*k7+texture(uTexture,vTexCoord+pixel)*k8;vec4 color=vec4(clamp((colorSum/w),0.0,1.0).rgb,c.a);return color;}vec4 blendPremultipliedAlpha(vec4 back,vec4 front){return front+(back*(1.0-front.a));}vec4 applyVignette(vec4 c,vec2 pos,vec2 center,float v){float d=distance(pos,center)/length(center);float f=1.0-(d*abs(v));if(v>0.0){c.rgb*=f;}else if(v<0.0){c.rgb+=(1.0-f)*(1.0-c.rgb);}return c;}void main(){float x=gl_FragCoord.x;float y=gl_FragCoord.y;float a=1.0;float maskTop=uMaskBounds[0];float maskRight=uMaskBounds[1];float maskBottom=uMaskBounds[2];float maskLeft=uMaskBounds[3];float leftFeatherOpacity=step(uMaskFeather[1],x)*uMaskFeather[0]+((1.0-uMaskFeather[0])*smoothstep(uMaskFeather[1],uMaskFeather[3],x));float rightFeatherOpacity=(1.0-step(uMaskFeather[7],x))*uMaskFeather[4]+((1.0-uMaskFeather[4])*smoothstep(uMaskFeather[7],uMaskFeather[5],x));a*=leftFeatherOpacity*rightFeatherOpacity;float overlayColorAlpha=(smoothstep(maskLeft,maskLeft+1.0,x)*(1.0-smoothstep(maskRight-1.0,maskRight,x))*(1.0-step(maskTop,y))*step(maskBottom,y));if(uOverlayColor.a==0.0){a*=overlayColorAlpha;}vec2 offset=vec2(maskLeft,maskBottom);vec2 size=vec2(maskRight-maskLeft,maskTop-maskBottom)*.5;vec2 center=offset.xy+size.xy;int pixelX=int(step(center.x,x));int pixelY=int(step(y,center.y));float cornerRadius=0.0;if(pixelX==0&&pixelY==0)cornerRadius=uMaskCornerRadius[0];if(pixelX==1&&pixelY==0)cornerRadius=uMaskCornerRadius[1];if(pixelX==0&&pixelY==1)cornerRadius=uMaskCornerRadius[2];if(pixelX==1&&pixelY==1)cornerRadius=uMaskCornerRadius[3];float cornerOffset=sign(cornerRadius)*length(max(abs(gl_FragCoord.xy-size-offset)-size+cornerRadius,0.0))-cornerRadius;float cornerOpacity=1.0-smoothstep(0.0,1.0,cornerOffset);a*=cornerOpacity;if(uAntialias==1){vec2 scaledPoint=vec2(vTexCoord.x*uTextureSize.x,vTexCoord.y*uTextureSize.y);a*=smoothstep(0.0,1.0,uTextureSize.x-scaledPoint.x);a*=smoothstep(0.0,1.0,uTextureSize.y-scaledPoint.y);a*=smoothstep(0.0,1.0,scaledPoint.x);a*=smoothstep(0.0,1.0,scaledPoint.y);}vec4 color=texture(uTexture,vTexCoord);if(uClarityKernelWeight!=-1.0){color=applyConvolutionMatrix(color,uClarityKernel[0],uClarityKernel[1],uClarityKernel[2],uClarityKernel[3],uClarityKernel[4],uClarityKernel[5],uClarityKernel[6],uClarityKernel[7],uClarityKernel[8],uClarityKernelWeight);}color=blendPremultipliedAlpha(color,texture(uTextureBlend,vTexCoord));color=applyGamma(color,uColorGamma);color=applyColorMatrix(color,uColorMatrix,uColorOffset);color*=a;if(uColorVignette!=0.0){vec2 pos=gl_FragCoord.xy-offset;color=applyVignette(color,pos,center-offset,uColorVignette);}color=blendPremultipliedAlpha(color,texture(uTextureOverlay,vTexCoord));if(overlayColorAlpha<=0.0){color*=1.0-uOverlayColor.a;}color*=uOpacity;fragColor=color;}\"; // eslint-disable-line\n\nvar imageVertexShader = \"\\n##head\\n##text\\nvoid main(){vTexCoord=aTexCoord;gl_Position=uMatrix*aPosition;}\"; // eslint-disable-line\n\nvar pathVertexShader = \"#version 300 es\\n\\nin vec4 aPosition;in vec2 aNormal;in float aMiter;out vec2 vNormal;out float vMiter;out float vWidth;uniform float uWidth;uniform float uSharpness;uniform mat4 uMatrix;void main(){vMiter=aMiter;vNormal=aNormal;vWidth=(uWidth*.5)+uSharpness;gl_Position=uMatrix*vec4(aPosition.x+(aNormal.x*vWidth*aMiter),aPosition.y+(aNormal.y*vWidth*aMiter),0,1);}\"; // eslint-disable-line\n\nvar pathFragmentShader = \"\\n##head\\n##mask\\nin vec2 vNormal;in float vMiter;in float vWidth;uniform float uWidth;uniform vec4 uColor;uniform vec4 uCanvasColor;void main(){vec4 fillColor=uColor;float m=mask(gl_FragCoord.x,gl_FragCoord.y,uMaskBounds,uMaskOpacity);if(m<=0.0)discard;fillColor.a*=clamp(smoothstep(vWidth-.5,vWidth-1.0,abs(vMiter)*vWidth),0.0,1.0);fillColor.rgb*=fillColor.a;fillColor.rgb*=m;fillColor.rgb+=(1.0-m)*(uCanvasColor.rgb*fillColor.a);fragColor=fillColor;}\"; // eslint-disable-line\n\nvar rectVertexShader = \"\\n##head\\n##text\\nin vec2 aRectCoord;out vec2 vRectCoord;void main(){vTexCoord=aTexCoord;vRectCoord=aRectCoord;\\n##matrix\\n}\"; // eslint-disable-line\n\nvar rectFragmentShader = \"\\n##head\\n##mask\\nin vec2 vTexCoord;in vec2 vRectCoord;uniform sampler2D uTexture;uniform vec4 uTextureColor;uniform float uTextureOpacity;uniform vec2 uRepeat;uniform vec4 uColor;uniform float uCornerRadius[4];uniform vec2 uSize;uniform vec2 uPosition;uniform vec4 uCanvasColor;uniform int uInverted;uniform float uEdgeFeather;void main(){\\n##init\\n##colorize\\n##rectaa\\n##cornerradius\\n##maskfeatherapply\\nif(uInverted==1)a=1.0-a;\\n##maskapply\\n##fragcolor\\n}\"; // eslint-disable-line\n\nvar ellipseVertexShader = \"\\n##head\\n##text\\nout vec2 vTexCoordDouble;void main(){vTexCoordDouble=vec2(aTexCoord.x*2.0-1.0,aTexCoord.y*2.0-1.0);vTexCoord=aTexCoord;\\n##matrix\\n}\"; // eslint-disable-line\n\nvar ellipseFragmentShader = \"\\n##head\\n##mask\\nin vec2 vTexCoord;in vec2 vTexCoordDouble;uniform sampler2D uTexture;uniform float uTextureOpacity;uniform vec2 uTextureAdjust;uniform vec2 uRepeat;uniform vec2 uRadius;uniform vec4 uColor;uniform int uInverted;uniform vec4 uCanvasColor;void main(){\\n##init\\nfloat ar=uRadius.x/uRadius.y;vec2 rAA=vec2(uRadius.x-1.0,uRadius.y-(1.0/ar));vec2 scaledPointSq=vec2((vTexCoordDouble.x*uTextureAdjust.x*uRadius.x)*(vTexCoordDouble.x*uTextureAdjust.x*uRadius.x),(vTexCoordDouble.y*uTextureAdjust.y*uRadius.y)*(vTexCoordDouble.y*uTextureAdjust.y*uRadius.y));float p=(scaledPointSq.x/(uRadius.x*uRadius.x))+(scaledPointSq.y/(uRadius.y*uRadius.y));float pAA=(scaledPointSq.x/(rAA.x*rAA.x))+(scaledPointSq.y/(rAA.y*rAA.y));a=smoothstep(1.0,p/pAA,p);if(uInverted==1)a=1.0-a;\\n##maskapply\\n##fragcolor\\n}\"; // eslint-disable-line\n\nvar triangleVertexShader = \"\\n##head\\nvoid main(){\\n##matrix\\n}\"; // eslint-disable-line\n\nvar triangleFragmentShader = \"\\n##head\\n##mask\\nuniform vec4 uColor;uniform vec4 uCanvasColor;void main(){vec4 fillColor=uColor;\\n##maskapply\\nif(m<=0.0)discard;fillColor.rgb*=fillColor.a;fillColor.rgb*=m;fillColor.rgb+=(1.0-m)*(uCanvasColor.rgb*fillColor.a);fragColor=fillColor;}\"; // eslint-disable-line\n\nconst getIndex = (arr, index) => {\n    const l = arr.length;\n    if (index >= l)\n        return arr[index % l];\n    if (index < 0)\n        return arr[(index % l) + l];\n    return arr[index];\n};\nconst getPolygonArea = (vertices) => {\n    let area = 0, i, va, vb, w, h;\n    const l = vertices.length;\n    for (i = 0; i < l; i++) {\n        va = vertices[i];\n        vb = vertices[(i + 1) % l];\n        w = vb.x - va.x;\n        h = (vb.y + va.y) / 2;\n        area += w * h;\n    }\n    return area;\n};\nconst isPointInTriangle = (p, a, b, c) => {\n    const ab = vectorCreate(b.x - a.x, b.y - a.y);\n    const bc = vectorCreate(c.x - b.x, c.y - b.y);\n    const ca = vectorCreate(a.x - c.x, a.y - c.y);\n    const ap = vectorCreate(p.x - a.x, p.y - a.y);\n    const bp = vectorCreate(p.x - b.x, p.y - b.y);\n    const cp = vectorCreate(p.x - c.x, p.y - c.y);\n    const c1 = vectorCross(ab, ap);\n    const c2 = vectorCross(bc, bp);\n    const c3 = vectorCross(ca, cp);\n    return c1 <= 0 && c2 <= 0 && c3 <= 0;\n};\nconst isIntersectingSelf = (vertices) => {\n    // test if lines intersect\n    const l = vertices.length;\n    for (let i = 0; i < l; i++) {\n        const line = lineCreate(vertices[i], getIndex(vertices, i + 1));\n        const intersections = linePointsIntersection(line, vertices, {\n            ignoreIdenticalLines: true,\n            breakOnIntersection: true,\n        });\n        // is intersecting\n        if (intersections)\n            return true;\n    }\n    return false;\n};\nconst triangulate = (vertices) => {\n    // not enough vertices\n    if (vertices.length < 3)\n        return [];\n    // test if is simple polygon\n    if (isIntersectingSelf(vertices))\n        return [];\n    // if vertices aren't clockwise, reverse\n    if (getPolygonArea(vertices) < 0)\n        vertices.reverse();\n    // TODO: remove 180 degree corners, vertices should either be convex (< 180) or reflex (> 180), this happens when three vertices are in the same line\n    // triangulate\n    const totalVertices = vertices.length;\n    const indexList = [...Array(totalVertices).keys()];\n    const triangles = [];\n    // faster to declare vars out of loop\n    let i, j, a, b, c, va, vb, vc, vaToVb, vaToVc, isEar, p;\n    let safe = 1024;\n    while (indexList.length > 3) {\n        // safeguard against infinite loops\n        if (safe <= 0)\n            return [];\n        // lower safeguard\n        safe--;\n        // start calculating triangles\n        for (i = 0; i < indexList.length; i++) {\n            a = indexList[i];\n            b = getIndex(indexList, i - 1);\n            c = getIndex(indexList, i + 1);\n            va = vertices[a];\n            vb = vertices[b];\n            vc = vertices[c];\n            vaToVb = vectorCreate(vb.x - va.x, vb.y - va.y);\n            vaToVc = vectorCreate(vc.x - va.x, vc.y - va.y);\n            // is not an ear if is reflex corner (angle > 180)\n            if (vectorCross(vaToVb, vaToVc) < 0)\n                continue;\n            isEar = true;\n            for (j = 0; j < totalVertices; j++) {\n                // skip as is me\n                if (j === a || j === b || j === c)\n                    continue;\n                // is not an ear if another vertex falls in this triangle\n                p = vertices[j];\n                if (isPointInTriangle(p, vb, va, vc)) {\n                    isEar = false;\n                    break;\n                }\n            }\n            // skip\n            if (!isEar)\n                continue;\n            // found ear\n            triangles.push([vb, va, vc]);\n            // no longer interested in this index\n            indexList.splice(i, 1);\n            break;\n        }\n    }\n    // finale triangle\n    triangles.push([vertices[indexList[0]], vertices[indexList[1]], vertices[indexList[2]]]);\n    return triangles;\n};\nconst createPathSegment = (vertices, index, a, b, c) => {\n    const ab = vectorNormalize(vectorCreate(b.x - a.x, b.y - a.y));\n    const bc = vectorNormalize(vectorCreate(c.x - b.x, c.y - b.y));\n    const tangent = vectorNormalize(vectorCreate(ab.x + bc.x, ab.y + bc.y));\n    const miter = vectorCreate(-tangent.y, tangent.x);\n    const normal = vectorCreate(-ab.y, ab.x);\n    // limit miter length (TEMP fix to prevent spikes, should eventually add caps)\n    const miterLength = Math.min(1 / vectorDot(miter, normal), 5);\n    vertices[index] = b.x;\n    vertices[index + 1] = b.y;\n    vertices[index + 2] = miter.x * miterLength;\n    vertices[index + 3] = miter.y * miterLength;\n    vertices[index + 4] = -1;\n    vertices[index + 5] = b.x;\n    vertices[index + 6] = b.y;\n    vertices[index + 7] = miter.x * miterLength;\n    vertices[index + 8] = miter.y * miterLength;\n    vertices[index + 9] = 1;\n};\nconst createPathVertices = (points, close) => {\n    let a, b, c, i = 0;\n    const l = points.length;\n    const stride = 10;\n    const vertices = new Float32Array((close ? l + 1 : l) * stride);\n    const first = points[0];\n    const last = points[l - 1];\n    for (i = 0; i < l; i++) {\n        a = points[i - 1];\n        b = points[i];\n        c = points[i + 1];\n        // if previous point not available use inverse vector to next point\n        if (!a)\n            a = close ? last : vectorCreate(b.x + (b.x - c.x), b.y + (b.y - c.y));\n        // if next point not available use inverse vector from previous point\n        if (!c)\n            c = close ? first : vectorCreate(b.x + (b.x - a.x), b.y + (b.y - a.y));\n        createPathSegment(vertices, i * stride, a, b, c);\n    }\n    if (close)\n        createPathSegment(vertices, l * stride, last, first, points[1]);\n    return vertices;\n};\nconst rectPointsToVertices = (points) => {\n    // [tl, tr, br, bl]\n    // B   D\n    // | \\ |\n    // A  C\n    const vertices = new Float32Array(8);\n    vertices[0] = points[3].x;\n    vertices[1] = points[3].y;\n    vertices[2] = points[0].x;\n    vertices[3] = points[0].y;\n    vertices[4] = points[2].x;\n    vertices[5] = points[2].y;\n    vertices[6] = points[1].x;\n    vertices[7] = points[1].y;\n    return vertices;\n};\nconst createRectPoints = (rect, rotation = 0, flipX, flipY) => {\n    const corners = rectGetCorners(rect);\n    const cx = rect.x + rect.width * 0.5;\n    const cy = rect.y + rect.height * 0.5;\n    if (flipX || flipY)\n        vectorsFlip(corners, flipX, flipY, cx, cy);\n    if (rotation !== 0)\n        vectorsRotate(corners, rotation, cx, cy);\n    return corners;\n};\nconst createEllipseOutline = (x, y, width, height, rotation, flipX, flipY) => {\n    const rx = Math.abs(width) * 0.5;\n    const ry = Math.abs(height) * 0.5;\n    const size = Math.abs(width) + Math.abs(height);\n    const precision = Math.max(20, Math.round(size / 6));\n    return ellipseToPolygon(vectorCreate(x + rx, y + ry), rx, ry, rotation, flipX, flipY, precision);\n};\nconst createRectOutline = (x, y, width, height, rotation, cornerRadius, flipX, flipY) => {\n    const points = [];\n    if (cornerRadius.every((v) => v === 0)) {\n        points.push(vectorCreate(x, y), // top left corner\n        vectorCreate(x + width, y), // top right corner\n        vectorCreate(x + width, y + height), // bottom right corner\n        vectorCreate(x, y + height) // bottom left corner\n        );\n    }\n    else {\n        const [tl, tr, bl, br] = cornerRadius;\n        const l = x;\n        const r = x + width;\n        const t = y;\n        const b = y + height;\n        // start at end of top left corner\n        points.push(vectorCreate(l + tl, t));\n        pushRectCornerPoints(points, r - tr, t + tr, tr, -1);\n        // move to bottom right corner\n        points.push(vectorCreate(r, t + tr));\n        pushRectCornerPoints(points, r - br, b - br, br, 0);\n        // move to bottom left corner\n        points.push(vectorCreate(r - br, b));\n        pushRectCornerPoints(points, l + bl, b - bl, bl, 1);\n        // move to top left corner\n        points.push(vectorCreate(l, b - bl));\n        pushRectCornerPoints(points, l + tl, t + tl, tl, 2);\n    }\n    if (flipX || flipY)\n        vectorsFlip(points, flipX, flipY, x + width * 0.5, y + height * 0.5);\n    if (rotation)\n        vectorsRotate(points, rotation, x + width * 0.5, y + height * 0.5);\n    return points;\n};\nconst pushRectCornerPoints = (points, x, y, radius, offset) => {\n    const precision = Math.min(20, Math.max(4, Math.round(radius / 2)));\n    let p = 0;\n    let s = 0;\n    let rx = 0;\n    let ry = 0;\n    let i = 0;\n    for (; i < precision; i++) {\n        p = i / precision;\n        s = offset * HALF_PI + p * HALF_PI;\n        rx = radius * Math.cos(s);\n        ry = radius * Math.sin(s);\n        points.push(vectorCreate(x + rx, y + ry));\n    }\n};\n\nlet limit = null;\nvar getWebGLTextureSizeLimit = () => {\n    if (limit !== null)\n        return limit;\n    let canvas = h('canvas');\n    const gl = getWebGLContext(canvas);\n    limit = gl ? gl.getParameter(gl.MAX_TEXTURE_SIZE) : undefined;\n    releaseCanvas(canvas);\n    canvas = undefined;\n    return limit;\n};\n\nvar isChrome = () => isBrowser() && !!window['chrome'];\n\n// prettier-ignore\n// B   D\n// | \\ |\n// A  C\nconst RECT_UV = new Float32Array([\n    0.0, 1.0, // A\n    0.0, 0.0, // B\n    1.0, 1.0, // C\n    1.0, 0.0, // D\n]);\n// prettier-ignore\n// BROWSER BUG FIX: Here to fix Firefox video texture rotation issue\nconst RECT_UV_ROTATED = new Float32Array([\n    1.0, 0.0, // A\n    0.0, 0.0, // B\n    1.0, 1.0, // C\n    0.0, 1.0, // D\n]);\nconst SHOULD_APPLY_ROTATED_UV_TO_VIDEO_TEXTURES = isBrowser() && isFirefox();\nconst CLARITY_IDENTITY = [0, 0, 0, 0, 1, 0, 0, 0, 0];\nconst COLOR_MATRIX_IDENTITY$1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\nconst TEXTURE_TRANSPARENT_INDEX = 0;\nconst TEXTURE_PREVIEW_BLEND_INDEX = 1;\nconst TEXTURE_PREVIEW_OVERLAY_INDEX = 2;\nconst TEXTURE_PREVIEW_INDEX = 3;\nconst TEXTURE_SHAPE_INDEX = 4;\nconst COLOR_TRANSPARENT = [0, 0, 0, 0];\nconst NO_CORNERS = [0, 0, 0, 0];\nconst calculateBackgroundUVMap = (width, height, backgroundSize, backgroundPosition, viewPixelDensity) => {\n    if (!backgroundSize || !backgroundPosition)\n        return RECT_UV;\n    let x = backgroundPosition.x / backgroundSize.width;\n    let y = backgroundPosition.y / backgroundSize.height;\n    let w = width / backgroundSize.width / viewPixelDensity;\n    let h = height / backgroundSize.height / viewPixelDensity;\n    w -= x;\n    h -= y;\n    // prettier-ignore\n    // B   D\n    // | \\ |\n    // A  C\n    // bottom left\n    const ax = -x;\n    const ay = h;\n    // top left\n    const bx = -x;\n    const by = -y;\n    // bottom right\n    const cx = w;\n    const cy = h;\n    // top right\n    const dx = w;\n    const dy = -y;\n    return new Float32Array([\n        ax,\n        ay, // A\n        bx,\n        by, // B\n        cx,\n        cy, // C\n        dx,\n        dy, // D\n    ]);\n};\nconst limitCornerRadius = (r, size) => {\n    return Math.floor(clamp(r, 0, Math.min((size.width - 1) * 0.5, (size.height - 1) * 0.5)));\n};\nvar createWebGLCanvas = (canvas, options = {}) => {\n    // defaults\n    const { alpha = false, onContextExhausted = noop$1 } = options;\n    // go\n    const viewSize = { width: 0, height: 0 };\n    const viewSizeVisual = { width: 0, height: 0 };\n    const textureSizeLimit = getWebGLTextureSizeLimit() || 1024;\n    let viewAspectRatio;\n    let viewPixelDensity;\n    let pathSharpness;\n    const overlayMatrixCanvas = mat4Create();\n    const imageFrameBuffer = mat4Create();\n    let overlayMatrix;\n    let maskTop;\n    let maskRight;\n    let maskBottom;\n    let maskLeft;\n    let maskOpacity;\n    let maskBounds;\n    let IMAGE_MASK_FEATHER; // updated when viewport is resized\n    let RECT_MASK_FEATHER;\n    let CANVAS_COLOR_R = 0;\n    let CANVAS_COLOR_G = 0;\n    let CANVAS_COLOR_B = 0;\n    let CANVAS_COLOR_A = 1;\n    const indexTextureMap = new Map([]);\n    // resize view\n    const resize = (width, height, pixelDensity) => {\n        // density (min is 1 to prevent draw issues when zooming out webview)\n        viewPixelDensity = Math.max(1, pixelDensity);\n        // set path sharpness factor so paths look a little nicer on low res displays\n        pathSharpness = viewPixelDensity === 1 ? 0.75 : 1;\n        // visual size\n        viewSizeVisual.width = width;\n        viewSizeVisual.height = height;\n        // size\n        viewSize.width = width * viewPixelDensity;\n        viewSize.height = height * viewPixelDensity;\n        // calculate the aspect ratio, we use this to determine quad size\n        viewAspectRatio = getAspectRatio(viewSize.width, viewSize.height);\n        // sync dimensions with image data\n        canvas.width = viewSize.width;\n        canvas.height = viewSize.height;\n        // update canvas markup matrix\n        mat4Ortho(overlayMatrixCanvas, 0, viewSize.width, viewSize.height, 0, -1, 1);\n        IMAGE_MASK_FEATHER = [1, 0, 1, 0, 1, viewSizeVisual.width, 1, viewSizeVisual.width];\n    };\n    const enablePreviewStencil = () => {\n        gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);\n        gl.stencilFunc(gl.ALWAYS, 1, 0xff);\n        gl.stencilMask(0xff);\n    };\n    const applyPreviewStencil = () => {\n        gl.stencilFunc(gl.EQUAL, 1, 0xff);\n        gl.stencilMask(0x00);\n    };\n    const disablePreviewStencil = () => {\n        gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);\n        gl.stencilFunc(gl.ALWAYS, 1, 0xff);\n        gl.stencilMask(0xff);\n    };\n    // fov is fixed\n    const FOV = degToRad(30);\n    const FOV_TAN_HALF = Math.tan(FOV / 2);\n    // get gl drawing context\n    const gl = getWebGLContext(canvas, {\n        alpha,\n        antialias: false,\n        premultipliedAlpha: true,\n        stencil: true,\n    });\n    // no drawing context received, exit\n    if (!gl)\n        return;\n    // enable derivatives\n    gl.getExtension('OES_standard_derivatives');\n    // toggle gl settings\n    gl.disable(gl.DEPTH_TEST);\n    // need stencil to draw overlay on preview only\n    gl.enable(gl.STENCIL_TEST);\n    // set blend mode, we need it for alpha blending\n    gl.enable(gl.BLEND);\n    // alpha blending\n    gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n    // Disabled for now as this also requires the magenta text and selection placeholder color to be in P3 color space.\n    // Use p3 color space on p3 display (if unpackColorSpace is supported)\n    // if (supportsMonitorDisplayP3() && supportsWebGLDisplayP3()) {\n    //     // @ts-ignore\n    //     gl.drawingBufferColorSpace = 'display-p3';\n    //     // @ts-ignore\n    //     gl.unpackColorSpace = 'display-p3';\n    // }\n    // stencil test always passes\n    disablePreviewStencil();\n    // let's create textures\n    const transparentTexture = gl.createTexture();\n    gl.bindTexture(gl.TEXTURE_2D, transparentTexture);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, // width\n    1, // height\n    0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(COLOR_TRANSPARENT) // transparent background\n    );\n    indexTextureMap.set(TEXTURE_TRANSPARENT_INDEX, transparentTexture);\n    // create image markup texture and framebuffer\n    const imageOverlayTexture = gl.createTexture();\n    indexTextureMap.set(TEXTURE_PREVIEW_OVERLAY_INDEX, imageOverlayTexture);\n    const overlayFramebuffer = gl.createFramebuffer();\n    // create image blend texture and framebuffer\n    const imageBlendTexture = gl.createTexture();\n    indexTextureMap.set(TEXTURE_PREVIEW_BLEND_INDEX, imageBlendTexture);\n    const blendFramebuffer = gl.createFramebuffer();\n    // #region image\n    // create default pixel drawing program, supports what we need\n    const imageShader = createShader(gl, imageVertexShader, imageFragmentShader, ['aPosition', 'aTexCoord'], [\n        'uMatrix',\n        'uTexture',\n        'uTextureBlend',\n        'uTextureOverlay',\n        'uTextureSize',\n        'uColorGamma',\n        'uColorVignette',\n        'uColorOffset',\n        'uColorMatrix',\n        'uClarityKernel',\n        'uClarityKernelWeight',\n        'uOpacity',\n        'uMaskOpacity',\n        'uMaskBounds',\n        'uMaskCornerRadius',\n        'uMaskFeather',\n        'uOverlayColor',\n        'uAntialias',\n    ]);\n    if (!imageShader) {\n        onContextExhausted();\n        return;\n    }\n    // create image buffers\n    const imagePositionsBuffer = gl.createBuffer();\n    const texturePositionsBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, texturePositionsBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, RECT_UV, gl.STATIC_DRAW);\n    // BROWSER BUG FIX: here to fix firefox video texture rotation issue\n    const texturePositionsRotatedBuffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, texturePositionsRotatedBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, RECT_UV_ROTATED, gl.STATIC_DRAW);\n    const drawImage = (texture, textureSize, originX, originY, translateX, translateY, rotateX, rotateY, rotateZ, scale, colorMatrix = COLOR_MATRIX_IDENTITY$1, opacity = 1, clarity, gamma = 1, vignette = 0, maskFeather = IMAGE_MASK_FEATHER, maskCornerRadius = NO_CORNERS, imageOverlayColor = COLOR_TRANSPARENT, enableOverlay = false, enableBlend = false, enableAntialiasing = true, enableSnapToPixels = false) => {\n        // update image texture\n        const imageWidth = textureSize.width * viewPixelDensity;\n        const imageHeight = textureSize.height * viewPixelDensity;\n        const l = imageWidth * -0.5;\n        const t = imageHeight * 0.5;\n        const r = imageWidth * 0.5;\n        const b = imageHeight * -0.5;\n        // prettier-ignore\n        // B   D\n        // | \\ |\n        // A  C\n        const imagePositions = new Float32Array([\n            l, b, 0, // A\n            l, t, 0, // B\n            r, b, 0, // C\n            r, t, 0, // D\n        ]);\n        gl.bindBuffer(gl.ARRAY_BUFFER, imagePositionsBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, enableSnapToPixels ? imagePositions.map((v) => Math.round(v)) : imagePositions, gl.STATIC_DRAW);\n        // move image backwards so it's presented in actual pixel size\n        const viewZ = // 1. we calculate the z offset required to have the\n         \n        //    image height match the view height\n        /*        /|\n                 / |\n                /  | height / 2\n               /   |\n        f / 2 /__z_|\n              \\    |\n               \\   |\n                \\  |\n                 \\ |\n                  \\|\n        */\n        (textureSize.height / 2 / FOV_TAN_HALF) *\n            // 2. we want to render the image at the actual height, viewsize / height gets us results in a 1:1 presentation\n            (viewSize.height / textureSize.height) *\n            // 3. z has to be negative, therefor multiply by -1\n            -1;\n        // convert to pixel density\n        translateX *= viewPixelDensity;\n        translateY *= viewPixelDensity;\n        originX *= viewPixelDensity;\n        originY *= viewPixelDensity;\n        // get shader params\n        const { program, locations } = imageShader;\n        // apply\n        const matrix = mat4Create();\n        mat4Perspective(matrix, FOV, viewAspectRatio, 1, -viewZ * 2);\n        // move image\n        mat4Translate(matrix, translateX, -translateY, viewZ);\n        // set rotation origin in view\n        mat4Translate(matrix, originX, -originY, 0);\n        // rotate image\n        mat4RotateZ(matrix, -rotateZ);\n        // resize\n        mat4Scale(matrix, scale);\n        // reset rotation origin\n        mat4Translate(matrix, -originX, originY, 0);\n        // flip\n        mat4RotateY(matrix, rotateY);\n        mat4RotateX(matrix, rotateX);\n        //\n        // tell context to draw preview\n        //\n        gl.useProgram(program);\n        gl.enableVertexAttribArray(locations.aPosition);\n        gl.enableVertexAttribArray(locations.aTexCoord);\n        // set up texture\n        gl.uniform1i(locations.uTexture, TEXTURE_PREVIEW_INDEX);\n        gl.uniform2f(locations.uTextureSize, textureSize.width, textureSize.height);\n        gl.activeTexture(gl.TEXTURE0 + TEXTURE_PREVIEW_INDEX);\n        gl.bindTexture(gl.TEXTURE_2D, texture);\n        // set up blend texture\n        const blendTextureIndex = enableBlend\n            ? TEXTURE_PREVIEW_BLEND_INDEX\n            : TEXTURE_TRANSPARENT_INDEX;\n        const blendTexture = indexTextureMap.get(blendTextureIndex);\n        gl.uniform1i(locations.uTextureBlend, blendTextureIndex);\n        gl.activeTexture(gl.TEXTURE0 + blendTextureIndex);\n        gl.bindTexture(gl.TEXTURE_2D, blendTexture);\n        // set up markup texture\n        const overlayTextureIndex = enableOverlay\n            ? TEXTURE_PREVIEW_OVERLAY_INDEX\n            : TEXTURE_TRANSPARENT_INDEX;\n        const overlayTexture = indexTextureMap.get(overlayTextureIndex);\n        gl.uniform1i(locations.uTextureOverlay, overlayTextureIndex);\n        gl.activeTexture(gl.TEXTURE0 + overlayTextureIndex);\n        gl.bindTexture(gl.TEXTURE_2D, overlayTexture);\n        // set up buffers\n        gl.bindBuffer(gl.ARRAY_BUFFER, imagePositionsBuffer);\n        gl.vertexAttribPointer(locations.aPosition, 3, gl.FLOAT, false, 0, 0);\n        // BROWSER BUG FIX: Here to fix Firefox bug with rotated video textures\n        const rotateUV = SHOULD_APPLY_ROTATED_UV_TO_VIDEO_TEXTURES && textureIsRotatedVideo(texture);\n        gl.bindBuffer(gl.ARRAY_BUFFER, rotateUV ? texturePositionsRotatedBuffer : texturePositionsBuffer);\n        gl.vertexAttribPointer(locations.aTexCoord, 2, gl.FLOAT, false, 0, 0);\n        // update matrix\n        gl.uniformMatrix4fv(locations.uMatrix, false, matrix);\n        // overlay color\n        gl.uniform4fv(locations.uOverlayColor, imageOverlayColor);\n        // convolution\n        let clarityWeight;\n        if (!clarity || arrayEqual(clarity, CLARITY_IDENTITY)) {\n            clarity = CLARITY_IDENTITY;\n            clarityWeight = -1;\n        }\n        else {\n            clarityWeight = clarity.reduce((prev, curr) => prev + curr, 0);\n            clarityWeight = clarityWeight <= 0 ? 1 : clarityWeight;\n        }\n        gl.uniform1fv(locations.uClarityKernel, clarity);\n        gl.uniform1f(locations.uClarityKernelWeight, clarityWeight);\n        gl.uniform1f(locations.uColorGamma, 1.0 / gamma);\n        gl.uniform1f(locations.uColorVignette, vignette);\n        gl.uniform1i(locations.uAntialias, enableAntialiasing ? 1 : 0);\n        // set color matrix values\n        gl.uniform4f(locations.uColorOffset, colorMatrix[4], colorMatrix[9], colorMatrix[14], colorMatrix[19]);\n        gl.uniformMatrix4fv(locations.uColorMatrix, false, [\n            colorMatrix[0],\n            colorMatrix[1],\n            colorMatrix[2],\n            colorMatrix[3],\n            colorMatrix[5],\n            colorMatrix[6],\n            colorMatrix[7],\n            colorMatrix[8],\n            colorMatrix[10],\n            colorMatrix[11],\n            colorMatrix[12],\n            colorMatrix[13],\n            colorMatrix[15],\n            colorMatrix[16],\n            colorMatrix[17],\n            colorMatrix[18],\n        ]);\n        // opacity level\n        gl.uniform1f(locations.uOpacity, opacity);\n        // mask\n        gl.uniform1f(locations.uMaskOpacity, maskOpacity);\n        gl.uniform1fv(locations.uMaskBounds, maskBounds);\n        gl.uniform1fv(locations.uMaskCornerRadius, maskCornerRadius.map((v) => v * viewPixelDensity));\n        gl.uniform1fv(locations.uMaskFeather, maskFeather.map((v, i) => (i % 2 === 0 ? v : v * viewPixelDensity)));\n        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n        gl.disableVertexAttribArray(locations.aPosition);\n        gl.disableVertexAttribArray(locations.aTexCoord);\n    };\n    //#endregion\n    // #region path\n    const pathShader = createShader(gl, pathVertexShader, pathFragmentShader, ['aPosition', 'aNormal', 'aMiter'], ['uColor', 'uCanvasColor', 'uMatrix', 'uWidth', 'uSharpness', 'uMaskBounds', 'uMaskOpacity']);\n    if (!pathShader) {\n        onContextExhausted();\n        return;\n    }\n    const pathBuffer = gl.createBuffer();\n    // this fixes a render issue with Chrome 113 (#1176)\n    // issue was that a line is drawn from crop corner to top left\n    if (isChrome()) {\n        gl.bindBuffer(gl.ARRAY_BUFFER, pathBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, 1, gl.DYNAMIC_DRAW);\n    }\n    const strokePath = (points, width, color, close = false) => {\n        const { program, locations } = pathShader;\n        gl.useProgram(program);\n        gl.enableVertexAttribArray(locations.aPosition);\n        gl.enableVertexAttribArray(locations.aNormal);\n        gl.enableVertexAttribArray(locations.aMiter);\n        const vertices = createPathVertices(points, close);\n        const stride = Float32Array.BYTES_PER_ELEMENT * 5;\n        const normalOffset = Float32Array.BYTES_PER_ELEMENT * 2; // at position 2\n        const miterOffset = Float32Array.BYTES_PER_ELEMENT * 4; // at position 4\n        gl.uniform1f(locations.uWidth, width);\n        gl.uniform1f(locations.uSharpness, pathSharpness);\n        gl.uniform4fv(locations.uColor, color);\n        gl.uniformMatrix4fv(locations.uMatrix, false, overlayMatrix);\n        gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, CANVAS_COLOR_A);\n        gl.uniform1fv(locations.uMaskBounds, maskBounds);\n        gl.uniform1f(locations.uMaskOpacity, maskOpacity);\n        gl.bindBuffer(gl.ARRAY_BUFFER, pathBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, stride, 0);\n        gl.vertexAttribPointer(locations.aNormal, 2, gl.FLOAT, false, stride, normalOffset);\n        gl.vertexAttribPointer(locations.aMiter, 1, gl.FLOAT, false, stride, miterOffset);\n        gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 5);\n        gl.disableVertexAttribArray(locations.aPosition);\n        gl.disableVertexAttribArray(locations.aNormal);\n        gl.disableVertexAttribArray(locations.aMiter);\n    };\n    //#endregion\n    // #region triangle\n    const triangleShader = createShader(gl, triangleVertexShader, triangleFragmentShader, ['aPosition'], ['uColor', 'uCanvasColor', 'uMatrix', 'uMaskBounds', 'uMaskOpacity']);\n    if (!triangleShader) {\n        onContextExhausted();\n        return;\n    }\n    const trianglesBuffer = gl.createBuffer();\n    const fillTriangles = (vertices, backgroundColor) => {\n        const { program, locations } = triangleShader;\n        gl.useProgram(program);\n        gl.enableVertexAttribArray(locations.aPosition);\n        gl.uniform4fv(locations.uColor, backgroundColor);\n        gl.uniformMatrix4fv(locations.uMatrix, false, overlayMatrix);\n        gl.uniform1fv(locations.uMaskBounds, maskBounds);\n        gl.uniform1f(locations.uMaskOpacity, maskOpacity);\n        gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, CANVAS_COLOR_A);\n        gl.bindBuffer(gl.ARRAY_BUFFER, trianglesBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, 0, 0);\n        gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2);\n        gl.disableVertexAttribArray(locations.aPosition);\n        return vertices;\n    };\n    // const fillTriangles: (vertices: Float32Array, backgroundColor: number[]) => {};\n    //#endregion\n    // #region rect\n    const rectShaderAttributes = ['aPosition', 'aTexCoord', 'aRectCoord'];\n    const rectShaderUniforms = [\n        'uTexture',\n        'uColor',\n        'uMatrix',\n        'uCanvasColor',\n        'uTextureColor',\n        'uTextureOpacity',\n        'uRepeat',\n        'uPosition',\n        'uSize',\n        'uMaskBounds',\n        'uMaskOpacity',\n        'uMaskFeather',\n        'uCornerRadius',\n        'uInverted',\n        'uEdgeFeather',\n    ];\n    const rectShader = createShader(gl, rectVertexShader, rectFragmentShader, rectShaderAttributes, rectShaderUniforms);\n    if (!rectShader) {\n        onContextExhausted();\n        return;\n    }\n    const rectBuffer = gl.createBuffer();\n    const rectTextureBuffer = gl.createBuffer();\n    const rectCornerBuffer = gl.createBuffer();\n    const fillRect = (vertices, width, height, cornerRadius, backgroundColor, backgroundImage = transparentTexture, backgroundRepeat, opacity = 1.0, colorFilter = COLOR_TRANSPARENT, uv = RECT_UV, maskFeather = RECT_MASK_FEATHER, feather = 1, inverted) => {\n        const { program, locations } = rectShader;\n        gl.useProgram(program);\n        gl.enableVertexAttribArray(locations.aPosition);\n        gl.enableVertexAttribArray(locations.aTexCoord);\n        gl.enableVertexAttribArray(locations.aRectCoord);\n        gl.uniform4fv(locations.uColor, backgroundColor);\n        gl.uniform2fv(locations.uSize, [width, height]);\n        gl.uniform2fv(locations.uPosition, [vertices[2], vertices[3]]);\n        gl.uniform2fv(locations.uRepeat, backgroundRepeat);\n        gl.uniform1i(locations.uInverted, inverted ? 1 : 0);\n        gl.uniform1fv(locations.uCornerRadius, cornerRadius);\n        gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, CANVAS_COLOR_A);\n        // mask\n        gl.uniform1fv(locations.uMaskFeather, maskFeather.map((v, i) => (i % 2 === 0 ? v : v * viewPixelDensity)));\n        gl.uniform1fv(locations.uMaskBounds, maskBounds);\n        gl.uniform1f(locations.uMaskOpacity, maskOpacity);\n        gl.uniform1f(locations.uEdgeFeather, Math.max(0, feather));\n        gl.uniformMatrix4fv(locations.uMatrix, false, overlayMatrix);\n        gl.uniform1i(locations.uTexture, TEXTURE_SHAPE_INDEX);\n        gl.uniform4fv(locations.uTextureColor, colorFilter);\n        gl.uniform1f(locations.uTextureOpacity, opacity);\n        gl.activeTexture(gl.TEXTURE0 + TEXTURE_SHAPE_INDEX);\n        gl.bindTexture(gl.TEXTURE_2D, backgroundImage);\n        gl.bindBuffer(gl.ARRAY_BUFFER, rectTextureBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, uv, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(locations.aTexCoord, 2, gl.FLOAT, false, 0, 0);\n        // we use these coordinates combined with the size of the rect to interpolate and alias edges\n        gl.bindBuffer(gl.ARRAY_BUFFER, rectCornerBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, RECT_UV, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(locations.aRectCoord, 2, gl.FLOAT, false, 0, 0);\n        gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, 0, 0);\n        gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 2);\n        gl.disableVertexAttribArray(locations.aPosition);\n        gl.disableVertexAttribArray(locations.aTexCoord);\n        gl.disableVertexAttribArray(locations.aRectCoord);\n        return vertices;\n    };\n    //#endregion\n    // #region ellipse\n    const ellipseShader = createShader(gl, ellipseVertexShader, ellipseFragmentShader, ['aPosition', 'aTexCoord'], [\n        'uTexture',\n        'uTextureOpacity',\n        'uTextureAdjust',\n        'uRepeat',\n        'uColor',\n        'uCanvasColor',\n        'uMatrix',\n        'uRadius',\n        'uInverted',\n        'uMaskBounds',\n        'uMaskOpacity',\n    ]);\n    if (!ellipseShader) {\n        onContextExhausted();\n        return;\n    }\n    const ellipseBuffer = gl.createBuffer();\n    const ellipseTextureBuffer = gl.createBuffer();\n    const fillEllipse = (vertices, width, height, backgroundColor, backgroundImage = transparentTexture, backgroundSize, uv = RECT_UV, opacity = 1.0, inverted = false) => {\n        const { program, locations } = ellipseShader;\n        gl.useProgram(program);\n        gl.enableVertexAttribArray(locations.aPosition);\n        gl.enableVertexAttribArray(locations.aTexCoord);\n        gl.uniformMatrix4fv(locations.uMatrix, false, overlayMatrix);\n        gl.uniform2fv(locations.uRadius, [width * 0.5, height * 0.5]);\n        gl.uniform2fv(locations.uTextureAdjust, [\n            backgroundSize.width / (width / viewPixelDensity),\n            backgroundSize.height / (height / viewPixelDensity),\n        ]);\n        gl.uniform1i(locations.uInverted, inverted ? 1 : 0);\n        gl.uniform4fv(locations.uColor, backgroundColor);\n        gl.uniform4f(locations.uCanvasColor, CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, CANVAS_COLOR_A);\n        gl.uniform2fv(locations.uRepeat, [1, 1]);\n        gl.uniform1fv(locations.uMaskBounds, maskBounds);\n        gl.uniform1f(locations.uMaskOpacity, maskOpacity);\n        gl.uniform1i(locations.uTexture, TEXTURE_SHAPE_INDEX);\n        gl.uniform1f(locations.uTextureOpacity, opacity);\n        gl.activeTexture(gl.TEXTURE0 + TEXTURE_SHAPE_INDEX);\n        gl.bindTexture(gl.TEXTURE_2D, backgroundImage);\n        gl.bindBuffer(gl.ARRAY_BUFFER, ellipseTextureBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, uv, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(locations.aTexCoord, 2, gl.FLOAT, false, 0, 0);\n        gl.bindBuffer(gl.ARRAY_BUFFER, ellipseBuffer);\n        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n        gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, 0, 0);\n        gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 2);\n        gl.disableVertexAttribArray(locations.aPosition);\n        gl.disableVertexAttribArray(locations.aTexCoord);\n    };\n    //#endregion\n    //\n    // draw calls\n    //\n    const drawPath = (points, rotation = 0, // not implemented yet\n    flipX = false, // not implemented yet\n    flipY = false, // not implemented yet\n    strokeWidth, strokeColor, strokeClose, backgroundColor, opacity) => {\n        // is no line\n        if (points.length < 2)\n            return;\n        // manipulate points\n        const computedPoints = points.map((p) => ({\n            x: p.x * viewPixelDensity,\n            y: p.y * viewPixelDensity,\n        }));\n        const computedStrokeWidth = strokeWidth * viewPixelDensity;\n        // stroke\n        if (computedStrokeWidth > 0)\n            strokePath(computedPoints, computedStrokeWidth, applyOpacity(strokeColor, opacity), strokeClose);\n        // need to fill polygon?\n        if (computedPoints.length < 3 ||\n            !backgroundColor ||\n            backgroundColor[3] === 0 ||\n            !strokeClose)\n            return;\n        const triangles = triangulate(computedPoints);\n        const vertices = new Float32Array(triangles.length * 6);\n        triangles.forEach(([a, b, c], i) => {\n            const index = i * 6;\n            vertices[index + 0] = a.x;\n            vertices[index + 1] = a.y;\n            vertices[index + 2] = b.x;\n            vertices[index + 3] = b.y;\n            vertices[index + 4] = c.x;\n            vertices[index + 5] = c.y;\n        });\n        fillTriangles(vertices, applyOpacity(backgroundColor, opacity));\n    };\n    const drawRect = (rect, rotation = 0, flipX = false, flipY = false, cornerRadius, backgroundColor, backgroundImage, backgroundSize = undefined, backgroundPosition = undefined, backgroundRepeat = false, backgroundUVMap = undefined, strokeWidth, strokeColor, opacity, maskFeather = undefined, feather = 1 / viewPixelDensity, colorize, inverted) => {\n        // clone first\n        const rectOut = rectMultiply(rectClone(rect), viewPixelDensity);\n        // has radius, doesn't matter for coordinates\n        const cornerRadiusOut = cornerRadius\n            .map((r) => limitCornerRadius(r || 0, rect))\n            .map((r) => r * viewPixelDensity);\n        // should fill\n        if (backgroundColor || backgroundImage) {\n            // adjust for edge anti-aliasing, if we don't do this the\n            // visible rectangle will be 1 pixel smaller than the actual rectangle\n            const rectFill = rectClone(rectOut);\n            rectFill.x -= 0.5;\n            rectFill.y -= 0.5;\n            rectFill.width += 1;\n            rectFill.height += 1;\n            const points = createRectPoints(rectFill, rotation, flipX, flipY);\n            const vertices = rectPointsToVertices(points);\n            let color;\n            if (colorize) {\n                color = applyOpacity(colorize);\n                // as 0 transparancy is used to test if the colorize filter should be applied we set it to 0.001\n                if (color[3] === 0) {\n                    color[3] = 0.001;\n                }\n            }\n            // calculate repeat count\n            const fillRepeat = backgroundSize && backgroundRepeat\n                ? [\n                    rectFill.width / backgroundSize.width,\n                    rectFill.height / backgroundSize.height,\n                ]\n                : [1, 1];\n            fillRect(vertices, rectFill.width, rectFill.height, cornerRadiusOut, applyOpacity(backgroundColor, opacity), backgroundImage, fillRepeat, opacity, color, backgroundUVMap\n                ? new Float32Array(backgroundUVMap)\n                : calculateBackgroundUVMap(rectFill.width, rectFill.height, backgroundSize, backgroundPosition, viewPixelDensity), maskFeather, feather * viewPixelDensity, inverted);\n        }\n        // should draw outline\n        if (strokeWidth) {\n            // fixes issue where stroke would render weirdly\n            strokeWidth = Math.min(strokeWidth, rectOut.width, rectOut.height);\n            strokePath(\n            // rect out is already multiplied by pixel density\n            createRectOutline(rectOut.x, rectOut.y, rectOut.width, rectOut.height, rotation, cornerRadiusOut, flipX, flipY), strokeWidth * viewPixelDensity, applyOpacity(strokeColor, opacity), true);\n        }\n    };\n    const drawEllipse = (center, rx, ry, rotation, flipX, flipY, backgroundColor, backgroundImage, backgroundSize = undefined, backgroundPosition = undefined, backgroundUVMap = undefined, strokeWidth, strokeColor, opacity, inverted) => {\n        const rectOut = rectMultiply(rectCreate(center.x - rx, center.y - ry, rx * 2, ry * 2), viewPixelDensity);\n        if (backgroundColor || backgroundImage) {\n            // adjust for edge anti-aliasing, if we don't do this the\n            // visible rectangle will be 1 pixel smaller than the actual rectangle\n            const rectFill = rectClone(rectOut);\n            if (!inverted) {\n                rectFill.x -= 0.5;\n                rectFill.y -= 0.5;\n                rectFill.width += 1.0;\n                rectFill.height += 1.0;\n            }\n            const points = createRectPoints(rectFill, rotation, flipX, flipY);\n            const vertices = rectPointsToVertices(points);\n            fillEllipse(vertices, rectFill.width, rectFill.height, applyOpacity(backgroundColor, opacity), backgroundImage, backgroundSize ||\n                sizeCreate(rectFill.width / viewPixelDensity, rectFill.height / viewPixelDensity), backgroundUVMap\n                ? new Float32Array(backgroundUVMap)\n                : calculateBackgroundUVMap(rectFill.width, rectFill.height, backgroundSize, backgroundPosition, viewPixelDensity), opacity, inverted);\n        }\n        if (strokeWidth) {\n            strokePath(\n            // rect out is already multiplied by pixeldensity\n            createEllipseOutline(rectOut.x, rectOut.y, rectOut.width, rectOut.height, rotation, flipX, flipY), strokeWidth * viewPixelDensity, applyOpacity(strokeColor, opacity), true);\n        }\n    };\n    //#endregion\n    const glTextures = new Map();\n    const imageFramebufferSize = {};\n    imageFramebufferSize[TEXTURE_PREVIEW_OVERLAY_INDEX] = { width: 0, height: 0 };\n    imageFramebufferSize[TEXTURE_PREVIEW_BLEND_INDEX] = { width: 0, height: 0 };\n    const imageFrameBufferMaxSize = 4096;\n    const drawToImageFramebuffer = (index, buffer, imageSize, pixelDensity = 1) => {\n        const textureScalar = Math.min(Math.min(imageFrameBufferMaxSize, textureSizeLimit) / imageSize.width, Math.min(imageFrameBufferMaxSize, textureSizeLimit) / imageSize.height, pixelDensity);\n        const textureWidth = Math.floor(textureScalar * imageSize.width);\n        const textureHeight = Math.floor(textureScalar * imageSize.height);\n        if (!sizeEqual(imageSize, imageFramebufferSize[index])) {\n            // update preview markup texture\n            gl.bindTexture(gl.TEXTURE_2D, indexTextureMap.get(index));\n            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, textureWidth, textureHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n            // set the filtering, we don't need mips\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n            gl.bindFramebuffer(gl.FRAMEBUFFER, buffer);\n            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, indexTextureMap.get(index), 0);\n            // remember so we know when to update the framebuffer\n            imageFramebufferSize[index] = imageSize;\n        }\n        else {\n            gl.bindFramebuffer(gl.FRAMEBUFFER, buffer);\n        }\n        // switch transformMatrix\n        const w = imageSize.width * viewPixelDensity;\n        const h = imageSize.height * viewPixelDensity;\n        mat4Ortho(imageFrameBuffer, 0, w, h, 0, -1, 1);\n        mat4Translate(imageFrameBuffer, 0, h, 0);\n        mat4ScaleX(imageFrameBuffer, 1);\n        mat4ScaleY(imageFrameBuffer, -1);\n        overlayMatrix = imageFrameBuffer;\n        // framebuffer lives in image space\n        gl.viewport(0, 0, textureWidth, textureHeight);\n        // always transparent\n        gl.colorMask(true, true, true, true);\n        gl.clearColor(0, 0, 0, 0);\n        gl.clear(gl.COLOR_BUFFER_BIT);\n        // update rect mask\n        RECT_MASK_FEATHER = [\n            1,\n            0,\n            1,\n            0,\n            1,\n            Math.max(viewSize.width, imageSize.width),\n            1,\n            Math.max(viewSize.width, imageSize.width),\n        ];\n    };\n    const textureDelete = (texture, options) => {\n        const { forceRelease = false } = options || {};\n        const { src } = glTextures.get(texture);\n        // need to force release canvas elements when they're no longer used\n        if (src instanceof HTMLCanvasElement) {\n            if (!forceRelease && !src.dataset.retain) {\n                releaseCanvas(src);\n            }\n        }\n        glTextures.delete(texture);\n        gl.deleteTexture(texture);\n    };\n    const resetCanvasMatrix = () => {\n        mat4Ortho(overlayMatrixCanvas, 0, viewSize.width, viewSize.height, 0, -1, 1);\n    };\n    const textureIsRotatedVideo = (texture) => glTextures.get(texture).isRotatedVideo;\n    return {\n        // draw api\n        drawPath,\n        drawRect,\n        drawEllipse,\n        drawImage,\n        // texture filters\n        textureFilterNearest: gl.NEAREST,\n        textureFilterLinear: gl.LINEAR,\n        textureClamp: gl.CLAMP_TO_EDGE,\n        textureRepeat: gl.REPEAT,\n        //#region texture management\n        textureCreate: () => {\n            return gl.createTexture();\n        },\n        textureUpdate: (texture, source, options) => {\n            glTextures.set(texture, {\n                src: source,\n                options,\n                isRotatedVideo: source.nodeName === 'VIDEO' &&\n                    ((source.dataset && source.dataset.rotation == 90) ||\n                        source.dataset.rotation == 270),\n            });\n            return updateTexture(gl, texture, source, options);\n        },\n        textureGetSize: (texture) => {\n            const { src, options } = glTextures.get(texture);\n            const size = sizeCreateFromAny(src);\n            if (options.scalar)\n                return sizeApply(size, (v) => v / options.scalar);\n            return size;\n        },\n        textureDelete,\n        //#endregion\n        enablePreviewStencil,\n        applyPreviewStencil,\n        disablePreviewStencil,\n        setCanvasColor(color) {\n            CANVAS_COLOR_R = color[0];\n            CANVAS_COLOR_G = color[1];\n            CANVAS_COLOR_B = color[2];\n            CANVAS_COLOR_A = alpha ? color[3] : 1;\n            gl.clear(gl.COLOR_BUFFER_BIT);\n        },\n        resetCanvasMatrix,\n        updateCanvasMatrix(imageSize, origin, translation, scale, rotate) {\n            const imageWidth = imageSize.width;\n            const imageHeight = imageSize.height;\n            const originX = viewSize.width * (0.5 / viewPixelDensity);\n            const originY = viewSize.height * (0.5 / viewPixelDensity);\n            const imageOrigin = {\n                x: originX + (translation.x + origin.x),\n                y: originY + (translation.y + origin.y),\n            };\n            const imageVisualCenter = {\n                x: imageOrigin.x - origin.x,\n                y: imageOrigin.y - origin.y,\n            };\n            const imageAbsoluteCenter = {\n                x: imageWidth * 0.5,\n                y: imageHeight * 0.5,\n            };\n            vectorRotate(imageVisualCenter, rotate.z, imageOrigin);\n            vectorScale(imageVisualCenter, scale, imageOrigin);\n            const imageTranslation = {\n                x: imageVisualCenter.x - imageAbsoluteCenter.x,\n                y: imageVisualCenter.y - imageAbsoluteCenter.y,\n            };\n            mat4Translate(overlayMatrixCanvas, imageTranslation.x * viewPixelDensity, imageTranslation.y * viewPixelDensity, 0);\n            // we apply transforms from center of image\n            mat4Translate(overlayMatrixCanvas, imageAbsoluteCenter.x * viewPixelDensity, imageAbsoluteCenter.y * viewPixelDensity, 0);\n            mat4RotateZ(overlayMatrixCanvas, rotate.z);\n            const flipX = rotate.x > Math.PI / 2;\n            mat4RotateX(overlayMatrixCanvas, flipX ? Math.PI : 0);\n            const flipY = rotate.y > Math.PI / 2;\n            mat4RotateY(overlayMatrixCanvas, flipY ? Math.PI : 0);\n            mat4Scale(overlayMatrixCanvas, scale);\n            mat4Translate(overlayMatrixCanvas, -imageAbsoluteCenter.x * viewPixelDensity, -imageAbsoluteCenter.y * viewPixelDensity, 0);\n        },\n        drawToCanvas() {\n            gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n            // switch transformMatrix\n            overlayMatrix = overlayMatrixCanvas;\n            // tell webgl about the viewport\n            gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n            // black (or other color depending on background)\n            gl.colorMask(true, true, true, true);\n            gl.clearColor(CANVAS_COLOR_R, CANVAS_COLOR_G, CANVAS_COLOR_B, CANVAS_COLOR_A);\n            // gl.clearColor(0.25, 0.25, 0.25, 1); // for debugging\n            gl.clear(gl.COLOR_BUFFER_BIT);\n            // update rect mask\n            RECT_MASK_FEATHER = [1, 0, 1, 0, 1, viewSize.width, 1, viewSize.width];\n        },\n        drawToImageBlendBuffer(imageSize, pixelDensity) {\n            drawToImageFramebuffer(TEXTURE_PREVIEW_BLEND_INDEX, blendFramebuffer, imageSize, pixelDensity);\n        },\n        drawToImageOverlayBuffer(imageSize, pixelDensity) {\n            drawToImageFramebuffer(TEXTURE_PREVIEW_OVERLAY_INDEX, overlayFramebuffer, imageSize, pixelDensity);\n        },\n        // set mask\n        enableMask(rect, opacity) {\n            const maskX = rect.x * viewPixelDensity;\n            const maskY = rect.y * viewPixelDensity;\n            const maskWidth = rect.width * viewPixelDensity;\n            const maskHeight = rect.height * viewPixelDensity;\n            maskLeft = maskX;\n            maskRight = maskLeft + maskWidth;\n            maskTop = viewSize.height - maskY;\n            maskBottom = viewSize.height - (maskY + maskHeight);\n            maskOpacity = 1.0 - opacity;\n            maskBounds = [maskTop, maskRight, maskBottom, maskLeft];\n        },\n        disableMask() {\n            maskLeft = 0;\n            maskRight = viewSize.width;\n            maskTop = viewSize.height;\n            maskBottom = 0;\n            maskOpacity = 1;\n            maskBounds = [maskTop, maskRight, maskBottom, maskLeft];\n        },\n        // canvas\n        resize,\n        release() {\n            // remove all stored textures\n            const textures = Array.from(glTextures.keys());\n            textures.forEach((texture) => textureDelete(texture, { forceRelease: true }));\n            glTextures.clear();\n            // remove indexed textures\n            indexTextureMap.forEach((texture) => {\n                gl.deleteTexture(texture);\n            });\n            indexTextureMap.clear();\n            // clean up shaders\n            imageShader.destroy();\n            pathShader.destroy();\n            triangleShader.destroy();\n            rectShader.destroy();\n            ellipseShader.destroy();\n            // clear canvas\n            canvas.width = 1;\n            canvas.height = 1;\n            canvas = undefined;\n        },\n    };\n};\n\nvar numberToEven = (n) => (n % 2 == 0 ? n : n + 1);\n\n// quickly reads canvas data to editor state, replaces createDefaultImageReader\nconst createCanvasReader = () => {\n    return [\n        [\n            async (state, options, onprogress) => {\n                const { src } = state;\n                const width = parseInt(src.width, 10);\n                const height = parseInt(src.height, 10);\n                const dest = await canvasToBlob(src);\n                return {\n                    ...state,\n                    dest,\n                    size: {\n                        width,\n                        height,\n                    },\n                };\n            },\n            'read-canvas',\n        ],\n    ];\n};\nvar imageStateToCanvas = (src, imageState, options) => {\n    const isVideoSrc = isVideoElement(src);\n    const { targetCanvas, targetSize, disableDraw = false, shapePreprocessor, forceEvenSize = isVideoSrc, } = options || {};\n    const canvas = targetCanvas || document.createElement('canvas');\n    const { crop, colorMatrix, convolutionMatrix } = imageState;\n    const srcSize = {\n        width: isVideoSrc ? src.videoWidth : src.width,\n        height: isVideoSrc ? src.videoHeight : src.height,\n    };\n    // calculate target bounds dimensions\n    const { upscale = false, fit = 'contain', width: targetWidth, height: targetHeight, } = targetSize || {};\n    // scale canvas\n    let canvasScalar = 1;\n    // for 'contain'\n    if (fit === 'contain') {\n        canvasScalar = Math.min((targetWidth || Number.MAX_SAFE_INTEGER) / crop.width, (targetHeight || Number.MAX_SAFE_INTEGER) / crop.height);\n    }\n    // for 'cover' and 'force'\n    else {\n        canvasScalar = Math.max((targetWidth || crop.width) / crop.width, (targetHeight || crop.height) / crop.height);\n    }\n    // can't upscale, let's limit scalar to 1\n    if (!upscale)\n        canvasScalar = Math.min(canvasScalar, 1);\n    const canvasScaledWidth = fit === 'force' ? targetWidth : Math.floor(crop.width * canvasScalar);\n    const canvasScaledHeight = fit === 'force' ? targetHeight : Math.floor(crop.height * canvasScalar);\n    const canvasWidth = forceEvenSize ? numberToEven(canvasScaledWidth) : canvasScaledWidth;\n    const canvasHeight = forceEvenSize ? numberToEven(canvasScaledHeight) : canvasScaledHeight;\n    const glCanvas = createWebGLCanvas(canvas, { alpha: true });\n    glCanvas.resize(canvasWidth, canvasHeight, 1);\n    const glTexture = glCanvas.textureCreate();\n    glCanvas.setCanvasColor([0, 0, 0, 0]);\n    glCanvas.drawToCanvas();\n    glCanvas.disableMask();\n    glCanvas.disablePreviewStencil();\n    // color matrix\n    let computedColorMatrix;\n    {\n        const colorMatrices = Object.values(colorMatrix || {}).filter(Boolean);\n        if (colorMatrices.length)\n            computedColorMatrix = getColorMatrixFromColorMatrices(colorMatrices);\n    }\n    const canvasRect = { x: 0, y: 0, width: canvasWidth, height: canvasHeight };\n    const { origin, translation, rotation, scale } = calculateImageTransforms(canvasRect, canvasRect, srcSize, crop, {\n        x: 0,\n        y: 0,\n        width: canvasWidth,\n        height: canvasHeight,\n    }, canvasScalar, { x: 0, y: 0 }, 1, imageState.rotation, imageState.flipX, imageState.flipY);\n    const glTransforms = [\n        srcSize,\n        origin.x,\n        origin.y,\n        translation.x,\n        translation.y,\n        rotation.x,\n        rotation.y,\n        rotation.z,\n        scale,\n        computedColorMatrix,\n        1,\n        // @ts-ignore\n        convolutionMatrix && convolutionMatrix.clarity,\n        isNumber(imageState.gamma) ? imageState.gamma : 1,\n        imageState.vignette || 0,\n        [1, 0, 1, 0, 1, canvasHeight, 1, canvasWidth],\n        undefined,\n        undefined,\n        undefined,\n        undefined,\n        false,\n    ];\n    // shapes\n    let shapesOverlayDrawn = false;\n    const hasShapes = imageState.decoration.length || imageState.annotation.length;\n    const glShapeTexture = hasShapes && glCanvas.textureCreate();\n    // api\n    const updateTexture = () => {\n        glCanvas.textureUpdate(glTexture, src, {\n            filterParam: glCanvas.textureFilterLinear,\n            wrapParam: glCanvas.textureClamp,\n        });\n    };\n    const draw = () => {\n        // make sure texture is at the correct frame when it's a video\n        updateTexture();\n        // draw to the canvas\n        glCanvas.drawImage(glTexture, ...glTransforms);\n        // draw to the canvas\n        if (!hasShapes || !shapesOverlayDrawn)\n            return;\n        glCanvas.drawRect(canvasRect, 0, false, false, [0, 0, 0, 0], undefined, glShapeTexture);\n    };\n    const prepare = async () => {\n        if (!hasShapes)\n            return;\n        // draw shapes on transparent canvas that has size of input\n        const { dest } = await processImage(h('canvas', srcSize), {\n            shapePreprocessor,\n            imageReader: createCanvasReader(),\n            imageWriter: createDefaultImageWriter$1({\n                format: 'canvas',\n            }),\n            imageState: {\n                ...imageState,\n                redaction: [],\n                frame: undefined,\n                gamma: undefined,\n                convolutionMatrix: undefined,\n                colorMatrix: undefined,\n                backgroundColor: [0, 0, 0, 0],\n                backgroundImage: undefined,\n                trim: undefined,\n                vignette: undefined,\n                volume: undefined,\n            },\n        });\n        // only needs to run once\n        glCanvas.textureUpdate(glShapeTexture, dest, {\n            filterParam: glCanvas.textureFilterLinear,\n            wrapParam: glCanvas.textureClamp,\n        });\n        // now ready to draw shapes texture\n        shapesOverlayDrawn = true;\n        // first draw\n        !disableDraw && draw();\n    };\n    // load texture\n    updateTexture();\n    // first draw\n    !disableDraw && draw();\n    return {\n        canvas,\n        prepare,\n        redraw: draw,\n        destroy: () => {\n            glCanvas.release();\n        },\n    };\n};\n\nvar scrambleEffect = (options, done) => {\n    const { imageData, amount = 1 } = options;\n    const intensity = Math.round(Math.max(1, amount) * 2);\n    const range = Math.round(intensity * 0.5);\n    const inputWidth = imageData.width;\n    const inputHeight = imageData.height;\n    const inputColorSpace = imageData.colorSpace;\n    const outputData = new Uint8ClampedArray(inputWidth * inputHeight * 4);\n    const inputData = imageData.data;\n    let randomData;\n    let i = 0, x, y, r;\n    let xoffset = 0;\n    let yoffset = 0;\n    let index;\n    const l = inputWidth * inputHeight * 4 - 4;\n    for (y = 0; y < inputHeight; y++) {\n        randomData = crypto.getRandomValues(new Uint8ClampedArray(inputHeight));\n        for (x = 0; x < inputWidth; x++) {\n            r = randomData[y] / 255;\n            xoffset = 0;\n            yoffset = 0;\n            if (r < 0.5) {\n                xoffset = (-range + Math.round(Math.random() * intensity)) * 4;\n            }\n            if (r > 0.5) {\n                yoffset = (-range + Math.round(Math.random() * intensity)) * (inputWidth * 4);\n            }\n            // limit to image data\n            index = Math.min(Math.max(0, i + xoffset + yoffset), l);\n            outputData[i] = inputData[index];\n            outputData[i + 1] = inputData[index + 1];\n            outputData[i + 2] = inputData[index + 2];\n            outputData[i + 3] = inputData[index + 3];\n            i += 4;\n        }\n    }\n    // @ts-ignore\n    done(null, {\n        data: outputData,\n        width: imageData.width,\n        height: imageData.height,\n        colorSpace: inputColorSpace,\n    });\n};\n\n// basic blur covolution matrix\nconst BLUR_MATRIX = [0.0625, 0.125, 0.0625, 0.125, 0.25, 0.125, 0.0625, 0.125, 0.0625];\nvar imageDataScramble = async (inputData, options = {}) => {\n    if (!inputData)\n        return;\n    // @ts-ignore\n    const { width, height, colorSpace = 'srgb' } = inputData;\n    const { dataSize = 96, dataSizeScalar = 1, scrambleAmount = 4, blurAmount = 6, outputFormat = 'canvas', backgroundColor = [0, 0, 0], } = options;\n    const size = Math.round(dataSize * dataSizeScalar);\n    const scalar = Math.min(size / width, size / height);\n    const outputWidth = Math.floor(width * scalar);\n    const outputHeight = Math.floor(height * scalar);\n    // draw low res preview, add margin so blur isn't transparent\n    const scaledOutputCanvas = (h('canvas', { width: outputWidth, height: outputHeight }));\n    const ctx = (scaledOutputCanvas.getContext('2d', { willReadFrequently: true, colorSpace }));\n    // fill background on transparent images\n    backgroundColor.length = 3; // prevent transparent colors\n    ctx.fillStyle = colorArrayToRGBA(backgroundColor);\n    ctx.fillRect(0, 0, outputWidth, outputHeight);\n    if (isImageData(inputData)) {\n        // temporarily draw to canvas so we can draw image data to scaled context\n        const transferCanvas = h('canvas', { width, height });\n        const transferCtx = (transferCanvas.getContext('2d', { willReadFrequently: true, colorSpace }));\n        transferCtx.putImageData(inputData, 0, 0);\n        // draw to scaled context\n        ctx.drawImage(transferCanvas, 0, 0, outputWidth, outputHeight);\n        // release memory\n        releaseCanvas(transferCanvas);\n    }\n    else {\n        // bitmap data\n        ctx.drawImage(inputData, 0, 0, outputWidth, outputHeight);\n    }\n    // get scaled image data for scrambling\n    const imageData = ctx.getImageData(0, 0, outputWidth, outputHeight);\n    // filters to apply\n    const filters = [];\n    // add scramble filter\n    if (scrambleAmount > 0) {\n        filters.push([scrambleEffect, { amount: scrambleAmount }]);\n    }\n    // add blur filters\n    if (blurAmount > 0) {\n        for (let i = 0; i < blurAmount; i++) {\n            filters.push([convolutionEffect, { matrix: BLUR_MATRIX }]);\n        }\n    }\n    let imageDataScrambled;\n    if (filters.length) {\n        // builds effect chain\n        const chain = (transforms, i) => `(err, imageData) => {\n(${transforms[i][0].toString()})(Object.assign({ imageData: imageData }, filterInstructions[${i}]), \n${transforms[i + 1] ? chain(transforms, i + 1) : 'done'})\n}`;\n        const filterChain = `function (options, done) {\nconst filterInstructions = options.filterInstructions;\nconst imageData = options.imageData;\n(${chain(filters, 0)})(null, imageData)\n}`;\n        // scramble image data in separate thread\n        const imageDataObjectScrambled = await thread(filterChain, [\n            {\n                imageData: imageData,\n                filterInstructions: filters.map((t) => t[1]),\n            },\n        ], [imageData.data.buffer]);\n        imageDataScrambled = imageDataObjectToImageData(imageDataObjectScrambled);\n    }\n    else {\n        imageDataScrambled = imageData;\n    }\n    if (outputFormat === 'canvas') {\n        // put back scrambled data\n        ctx.putImageData(imageDataScrambled, 0, 0);\n        // return canvas\n        return scaledOutputCanvas;\n    }\n    return imageDataScrambled;\n};\n\nif (typeof window !== 'undefined')\n\t// @ts-ignore\n\t(window.__svelte || (window.__svelte = { v: new Set() })).v.add(PUBLIC_VERSION);\n\n/**\n * @param {any} obj\n * @returns {boolean}\n */\nfunction is_date(obj) {\n\treturn Object.prototype.toString.call(obj) === '[object Date]';\n}\n\n/*\nAdapted from https://github.com/mattdesl\nDistributed under MIT License https://github.com/mattdesl/eases/blob/master/LICENSE.md\n*/\n\n/**\n * https://svelte.dev/docs/svelte-easing\n * @param {number} t\n * @returns {number}\n */\nfunction circOut(t) {\n\treturn Math.sqrt(1 - --t * t);\n}\n\n/** @returns {(t: any) => any} */\nfunction get_interpolator(a, b) {\n\tif (a === b || a !== a) return () => a;\n\tconst type = typeof a;\n\tif (type !== typeof b || Array.isArray(a) !== Array.isArray(b)) {\n\t\tthrow new Error('Cannot interpolate values of different type');\n\t}\n\tif (Array.isArray(a)) {\n\t\tconst arr = b.map((bi, i) => {\n\t\t\treturn get_interpolator(a[i], bi);\n\t\t});\n\t\treturn (t) => arr.map((fn) => fn(t));\n\t}\n\tif (type === 'object') {\n\t\tif (!a || !b) throw new Error('Object cannot be null');\n\t\tif (is_date(a) && is_date(b)) {\n\t\t\ta = a.getTime();\n\t\t\tb = b.getTime();\n\t\t\tconst delta = b - a;\n\t\t\treturn (t) => new Date(a + t * delta);\n\t\t}\n\t\tconst keys = Object.keys(b);\n\t\tconst interpolators = {};\n\t\tkeys.forEach((key) => {\n\t\t\tinterpolators[key] = get_interpolator(a[key], b[key]);\n\t\t});\n\t\treturn (t) => {\n\t\t\tconst result = {};\n\t\t\tkeys.forEach((key) => {\n\t\t\t\tresult[key] = interpolators[key](t);\n\t\t\t});\n\t\t\treturn result;\n\t\t};\n\t}\n\tif (type === 'number') {\n\t\tconst delta = b - a;\n\t\treturn (t) => a + t * delta;\n\t}\n\tthrow new Error(`Cannot interpolate ${type} values`);\n}\n\n/**\n * A tweened store in Svelte is a special type of store that provides smooth transitions between state values over time.\n *\n * https://svelte.dev/docs/svelte-motion#tweened\n * @template T\n * @param {T} [value]\n * @param {import('./private.js').TweenedOptions<T>} [defaults]\n * @returns {import('./public.js').Tweened<T>}\n */\nfunction tweened(value, defaults = {}) {\n\tconst store = writable(value);\n\t/** @type {import('../internal/private.js').Task} */\n\tlet task;\n\tlet target_value = value;\n\t/**\n\t * @param {T} new_value\n\t * @param {import('./private.js').TweenedOptions<T>} [opts]\n\t */\n\tfunction set(new_value, opts) {\n\t\tif (value == null) {\n\t\t\tstore.set((value = new_value));\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\ttarget_value = new_value;\n\t\tlet previous_task = task;\n\t\tlet started = false;\n\t\tlet {\n\t\t\tdelay = 0,\n\t\t\tduration = 400,\n\t\t\teasing = identity,\n\t\t\tinterpolate = get_interpolator\n\t\t} = assign(assign({}, defaults), opts);\n\t\tif (duration === 0) {\n\t\t\tif (previous_task) {\n\t\t\t\tprevious_task.abort();\n\t\t\t\tprevious_task = null;\n\t\t\t}\n\t\t\tstore.set((value = target_value));\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\tconst start = now() + delay;\n\t\tlet fn;\n\t\ttask = loop((now) => {\n\t\t\tif (now < start) return true;\n\t\t\tif (!started) {\n\t\t\t\tfn = interpolate(value, new_value);\n\t\t\t\tif (typeof duration === 'function') duration = duration(value, new_value);\n\t\t\t\tstarted = true;\n\t\t\t}\n\t\t\tif (previous_task) {\n\t\t\t\tprevious_task.abort();\n\t\t\t\tprevious_task = null;\n\t\t\t}\n\t\t\tconst elapsed = now - start;\n\t\t\tif (elapsed > /** @type {number} */ (duration)) {\n\t\t\t\tstore.set((value = new_value));\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// @ts-ignore\n\t\t\tstore.set((value = fn(easing(elapsed / duration))));\n\t\t\treturn true;\n\t\t});\n\t\treturn task.promise;\n\t}\n\treturn {\n\t\tset,\n\t\tupdate: (fn, opts) => set(fn(target_value, value), opts),\n\t\tsubscribe: store.subscribe\n\t};\n}\n\n// @ts-ignore\nfunction tick_spring(ctx, last_value, current_value, target_value) {\n    if (typeof current_value === 'number') {\n        // @ts-ignore\n        const delta = target_value - current_value;\n        // @ts-ignore\n        const velocity = (current_value - last_value) / (ctx.dt || 1 / 60); // guard div by 0\n        const spring = ctx.opts.stiffness * delta;\n        const damper = ctx.opts.damping * velocity;\n        const acceleration = (spring - damper) * ctx.inv_mass;\n        const d = (velocity + acceleration) * ctx.dt;\n        if (Math.abs(d) < ctx.opts.precision && Math.abs(delta) < ctx.opts.precision) {\n            return target_value; // settled\n        }\n        else {\n            ctx.settled = false; // signal loop to keep ticking\n            // @ts-ignore\n            return current_value + d;\n        }\n    }\n    else if (isArray(current_value)) {\n        // @ts-ignore\n        return current_value.map((_, i) => tick_spring(ctx, last_value[i], current_value[i], target_value[i]));\n    }\n    else if (typeof current_value === 'object') {\n        const next_value = {};\n        // @ts-ignore\n        for (const k in current_value) {\n            // @ts-ignore\n            next_value[k] = tick_spring(ctx, last_value[k], current_value[k], target_value[k]);\n        }\n        // @ts-ignore\n        return next_value;\n    }\n    else {\n        throw new Error(`Cannot spring ${typeof current_value} values`);\n    }\n}\n// export interface Spring {\n//     set: (new_value: any, opts?: SpringUpdateOpts) => Promise<void>;\n//     update: (fn: Function, opts?: SpringUpdateOpts) => Promise<void>;\n//     subscribe: Function;\n//     precision: number;\n//     damping: number;\n//     stiffness: number;\n// }\nfunction spring(value, opts = {}) {\n    const store = writable(value);\n    const { stiffness = 0.15, damping = 0.8, precision = 0.01 } = opts;\n    let last_time;\n    let task;\n    let current_token;\n    let last_value = value;\n    let target_value = value;\n    let inv_mass = 1;\n    let inv_mass_recovery_rate = 0;\n    let cancel_task = false;\n    function set(new_value, opts = {}) {\n        target_value = new_value;\n        const token = (current_token = {});\n        if (value == null || opts.hard || (spring.stiffness >= 1 && spring.damping >= 1)) {\n            cancel_task = true; // cancel any running animation\n            last_time = null;\n            last_value = new_value;\n            store.set((value = target_value));\n            return Promise.resolve();\n        }\n        else if (opts.soft) {\n            const rate = opts.soft === true ? 0.5 : +opts.soft;\n            inv_mass_recovery_rate = 1 / (rate * 60);\n            inv_mass = 0; // infinite mass, unaffected by spring forces\n        }\n        if (!task) {\n            last_time = null;\n            cancel_task = false;\n            const ctx = {\n                inv_mass: undefined,\n                opts: spring,\n                settled: true,\n                dt: undefined,\n            };\n            task = loop((now) => {\n                if (last_time === null)\n                    last_time = now;\n                if (cancel_task) {\n                    cancel_task = false;\n                    task = null;\n                    return false;\n                }\n                inv_mass = Math.min(inv_mass + inv_mass_recovery_rate, 1);\n                // altered so doesn't create a new object\n                ctx.inv_mass = inv_mass;\n                ctx.opts = spring;\n                ctx.settled = true; // tick_spring may signal false\n                ctx.dt = ((now - last_time) * 60) / 1000;\n                const next_value = tick_spring(ctx, last_value, value, target_value);\n                last_time = now;\n                last_value = value;\n                store.set((value = next_value));\n                if (ctx.settled)\n                    task = null;\n                return !ctx.settled;\n            });\n        }\n        return new Promise((fulfil) => {\n            task.promise.then(() => {\n                if (token === current_token)\n                    fulfil();\n            });\n        });\n    }\n    const spring = {\n        set,\n        update: (fn, opts) => set(fn(target_value, value), opts),\n        subscribe: store.subscribe,\n        stiffness,\n        damping,\n        precision,\n    };\n    return spring;\n}\n\nvar prefersReducedMotion = readable(false, (set) => {\n    const mql = window.matchMedia('(prefers-reduced-motion:reduce)');\n    const test = () => set(mql.matches);\n    test();\n    mql.addListener(test);\n    return () => mql.removeListener(test);\n});\n\nvar hasResizeObserver = () => 'ResizeObserver' in window;\n\n//\nconst rectNext = rectCreateEmpty();\nconst updateNodeRect = (node, x, y, width, height) => {\n    if (!node.rect)\n        node.rect = rectCreateEmpty();\n    const rect = node.rect;\n    rectUpdate(rectNext, x, y, width, height);\n    if (rectEqual(rect, rectNext))\n        return;\n    rectUpdateWithRect(rect, rectNext);\n    node.dispatchEvent(new CustomEvent('measure', { detail: rect }));\n};\n// measures the element\nconst r = Math.round;\nconst measureViewRect = (node) => {\n    const clientRect = node.getBoundingClientRect();\n    // no frame because root has zero size\n    if (!frame)\n        return;\n    updateNodeRect(node, r(clientRect.x), r(clientRect.y), r(clientRect.width), r(clientRect.height));\n};\nconst measureOffset = (node) => {\n    // no frame because root has zero size\n    if (!frame)\n        return;\n    updateNodeRect(node, node.offsetLeft, node.offsetTop, node.offsetWidth, node.offsetHeight);\n};\n// holds all the elements to measure using requestAnimationFrame\nconst elements = [];\n// draw loop\nlet frame = undefined; /* is false when paused, is undefined when not initialised */\nfunction tick() {\n    if (!elements.length) {\n        frame = undefined;\n        return;\n    }\n    elements.forEach((node) => node.measure(node));\n    frame = requestAnimationFrame(tick);\n}\nlet observer; // ResizeObserver API not known by TypeScript\n// root observer\nlet rootObserver;\nlet rootRects = new Map([]);\nlet observedRoots = 0;\n// total observed elements so we know when we can unload observer\nlet observedNodes = 0;\nvar measurable = (node, options = {}) => {\n    const { observePosition = false, observeViewRect = false, once = false, disabled = false, isMeasureRoot = false, } = options;\n    // if is measure root we pause all measuring if this element doesn't have a size and no other roots actively measuring\n    if (hasResizeObserver() && isMeasureRoot) {\n        if (!rootObserver) {\n            rootObserver = new ResizeObserver((entries) => {\n                // update root rects\n                entries.forEach((entry) => {\n                    rootRects.set(entry.target, entry.contentRect);\n                });\n                // loop over all observed roots, if all roots don't have a size we pause measuring\n                const someVisible = Array.from(rootRects.values()).some(({ width, height }) => {\n                    return width > 0 && height > 0;\n                });\n                // if no roots visible, halt draw loop\n                if (!someVisible) {\n                    frame && cancelAnimationFrame(frame);\n                    frame = false;\n                }\n                // if no draw loop and a root became visible\n                else if (someVisible && frame === false) {\n                    tick();\n                }\n            });\n        }\n        // increase amount of observed roots so we know when no more roots are observed\n        rootObserver.observe(node);\n        observedRoots++;\n    }\n    // exit\n    if (disabled)\n        return;\n    // use resize observe if available\n    if (hasResizeObserver() && !observePosition && !observeViewRect) {\n        // we only create one observer, it will observe all registered elements\n        if (!observer) {\n            observer = new ResizeObserver((entries) => {\n                entries.forEach((entry) => {\n                    // no frame because root has zero size\n                    if (!frame)\n                        return;\n                    measureOffset(entry.target);\n                });\n            });\n        }\n        // start observing this node\n        observer.observe(node);\n        // measure our node for the first time\n        measureOffset(node);\n        // if should only measure once, remove now\n        if (once) {\n            observer.unobserve(node);\n        }\n        else {\n            observedNodes++;\n        }\n        // and we done, need to return a clean up method for when our node is destroyed\n        return {\n            destroy() {\n                // if is root\n                if (isMeasureRoot && rootObserver) {\n                    rootRects.delete(node);\n                    rootObserver.unobserve(node);\n                    observedRoots--;\n                    if (observedRoots === 0) {\n                        rootObserver.disconnect();\n                        rootObserver = undefined;\n                    }\n                }\n                // already unobserved this node\n                if (once)\n                    return;\n                // stop observing this node\n                observer.unobserve(node);\n                // test if all nodes have been removed, if so, remove observer\n                observedNodes--;\n                if (observedNodes === 0) {\n                    observer.disconnect();\n                    observer = undefined;\n                }\n            },\n        };\n    }\n    // set measure function\n    node.measure = observeViewRect ? measureViewRect : measureOffset;\n    // add so the element is measured\n    elements.push(node);\n    // start measuring on next frame, we set up a single measure loop,\n    // the loop will check if there's still elements that need to be measured,\n    // else it will stop running\n    if (frame === undefined)\n        frame = requestAnimationFrame(tick);\n    // measure this element now\n    node.measure(node);\n    // remove method\n    return {\n        destroy() {\n            // if is root\n            if (isMeasureRoot && rootObserver) {\n                rootRects.delete(node);\n                rootObserver.unobserve(node);\n                observedRoots--;\n                if (observedRoots === 0) {\n                    rootObserver.disconnect();\n                    rootObserver = undefined;\n                }\n            }\n            // clean up element\n            const index = elements.indexOf(node);\n            elements.splice(index, 1);\n            delete node.measure;\n        },\n    };\n};\n\nvar focusvisible = (element) => {\n    let isKeyboardInteraction = undefined;\n    const handlePointerdown = () => {\n        isKeyboardInteraction = false;\n    };\n    const handleKeydown = () => {\n        isKeyboardInteraction = true;\n    };\n    const handleKeyup = () => {\n        isKeyboardInteraction = false;\n    };\n    const handleFocus = (e) => {\n        if (isKeyboardInteraction === false)\n            return;\n        e.target.dataset.focusVisible = '';\n    };\n    const handleBlur = (e) => {\n        delete e.target.dataset.focusVisible;\n    };\n    const map = {\n        pointerdown: handlePointerdown,\n        keydown: handleKeydown,\n        keyup: handleKeyup,\n        focus: handleFocus,\n        blur: handleBlur,\n    };\n    Object.keys(map).forEach((event) => element.addEventListener(event, map[event], true));\n    return {\n        destroy() {\n            Object.keys(map).forEach((event) => element.removeEventListener(event, map[event], true));\n        },\n    };\n};\n\nconst isURL = (str) => /^http/.test(str);\nconst getResourceFromItem = (item) => new Promise((resolve, reject) => {\n    if (item.kind === 'file')\n        return resolve(item.getAsFile());\n    if (item.kind === 'string')\n        return item.getAsString(resolve);\n    // can't handle other kinds right now\n    reject();\n});\nconst getResourcesFromEvent = (e) => new Promise((resolve, reject) => {\n    const { items } = e.dataTransfer;\n    if (!items)\n        return resolve([]);\n    // if is URI list we only return one URL or one FILE\n    const isUriList = Array.from(items).some((item) => item.type === 'text/uri-list');\n    const itemPromises = Array.from(items)\n        .filter((item) => (item.kind === 'file' || item.kind === 'string') &&\n        // this contains two urls which messes with the isURL test\n        item.type !== 'text/x-moz-url')\n        .map(getResourceFromItem);\n    Promise.all(itemPromises)\n        .then((res) => {\n        // if is URI list we only use first URL, when dragging dropping an image tag on Windows Chrome we receive 3 URLs and a File\n        if (isUriList)\n            return resolve([res.find(isURL)].filter(Boolean));\n        // filter out non images\n        const resources = res.filter((item) => (isBinary(item) && (isImage(item) || isVideoFile(item))) ||\n            isURL(item));\n        // only urls\n        resolve(resources);\n    })\n        .catch(reject);\n});\nvar dropable = (node, options = {}) => {\n    const handleDragOver = (e) => {\n        // need to be prevent default to allow drop\n        e.preventDefault();\n    };\n    const handleDrop = async (e) => {\n        e.preventDefault();\n        e.stopPropagation(); // prevents parents from catching this drop\n        try {\n            const resources = await getResourcesFromEvent(e);\n            node.dispatchEvent(new CustomEvent('dropfiles', {\n                detail: {\n                    event: e,\n                    resources,\n                },\n                ...options,\n            }));\n        }\n        catch (err) {\n            // silent, wasn't able to catch\n        }\n    };\n    // listen and unlisten to drag/drop events\n    function unsub() {\n        node.removeEventListener('drop', handleDrop);\n        node.removeEventListener('dragover', handleDragOver);\n    }\n    function sub() {\n        node.addEventListener('drop', handleDrop);\n        node.addEventListener('dragover', handleDragOver);\n    }\n    // update state\n    function update(options) {\n        const { disabled = false } = options || {};\n        unsub();\n        // don't attach new listeners if disabled\n        if (disabled) {\n            return;\n        }\n        sub();\n    }\n    // init\n    update(options);\n    // remove method\n    return {\n        update,\n        destroy() {\n            unsub();\n        },\n    };\n};\n\nlet result$5 = null;\nvar isSoftwareRendering = () => {\n    if (result$5 === null) {\n        if (isBrowser()) {\n            const canvas = h('canvas');\n            result$5 = !getWebGLContext(canvas, {\n                failIfMajorPerformanceCaveat: true,\n            });\n            releaseCanvas(canvas);\n        }\n        else {\n            result$5 = false;\n        }\n    }\n    return result$5;\n};\n\nvar createTransparencyGrid = (size) => {\n    const sizeHalf = size * 0.5;\n    const canvas = h('canvas', {\n        'data-retain': true,\n        width: size,\n        height: size,\n    });\n    const ctx = canvas.getContext('2d');\n    ctx.fillStyle = '#f0f';\n    ctx.fillRect(0, 0, sizeHalf, sizeHalf);\n    ctx.fillRect(sizeHalf, sizeHalf, sizeHalf, sizeHalf);\n    return canvas;\n};\n\nvar durationToMilliseconds = (duration) => {\n    let f = parseFloat(duration);\n    if (/^[0-9]+s$/.test(duration))\n        return f * 1000;\n    return f;\n};\n\nvar isTexture = (texture) => texture instanceof WebGLTexture;\n\nvar backgroundCornersToUVMap = ([tl, tr, br, bl]) => {\n    // tl, tr, br, bl -> bl, tl, br, tr\n    // prettier-ignore\n    // B   D\n    // | \\ |\n    // A  C\n    return [\n        bl.x,\n        bl.y,\n        tl.x,\n        tl.y,\n        br.x,\n        br.y,\n        tr.x,\n        tr.y\n    ];\n};\n\nvar isVideoPlaying = (video) => video.currentTime > 0 && !video.paused && !video.ended && video.readyState > 2;\n\nvar ctxDrawSelection = (ctx, shapes, options) => {\n    const { selectionColor = [1, 1, 1], scalar = 1 } = options || {};\n    const shapesToDraw = [...shapes];\n    let didDraw = false;\n    for (const shape of shapesToDraw) {\n        const shouldSubtract = shape.drawMode === 'subtract';\n        // skip if can't subtract (this prevents first shape from drawing when subtract is set to true)\n        if (shouldSubtract && !didDraw) {\n            continue;\n        }\n        ctx.globalCompositeOperation = shouldSubtract ? 'destination-out' : 'source-over';\n        // remember context state\n        ctx.save();\n        // clears previous shape's path\n        ctx.beginPath();\n        // center, needed for transforms\n        const center = shapeGetCenter(shape);\n        // scale context so we adjust for scaled down selection canvas (2048 max size)\n        ctxScale(ctx, scalar, scalar);\n        // rotate context\n        ctxRotate(ctx, shape.rotation, center);\n        // flip context\n        ctxFlip(ctx, shape.flipX, shape.flipY, center);\n        // draw rect\n        if (shape.width) {\n            drawRect(ctx, { ...shape, backgroundColor: selectionColor });\n        }\n        // draw line\n        else if (shape.points) {\n            let pathShape;\n            if (shape.pathClose) {\n                // lasso\n                pathShape = {\n                    backgroundColor: selectionColor,\n                    strokeColor: selectionColor,\n                    // prevent spikes\n                    strokeJoin: 'round',\n                    bitmap: true,\n                };\n            }\n            else {\n                // brush\n                pathShape = {\n                    strokeColor: selectionColor,\n                    strokeJoin: 'round',\n                    strokeCap: 'round',\n                };\n            }\n            const points = shape.pointerPoint\n                ? [...shape.points, shape.pointerPoint]\n                : shape.points;\n            drawPath(ctx, Object.assign({}, shape, { points }, pathShape));\n            if (shape.pathClose && shape.strokeWidth) {\n                const outer = shape.strokeWidth * 3;\n                const inner = shape.strokeWidth * 2;\n                shapesToDraw.push({\n                    ...shape.points[0],\n                    rx: outer,\n                    ry: outer,\n                    drawMode: 'add',\n                }, {\n                    ...shape.points[0],\n                    rx: inner,\n                    ry: inner,\n                    drawMode: 'subtract',\n                });\n            }\n        }\n        // draw circle\n        else if (shape.rx) {\n            drawEllipse(ctx, {\n                ...shape,\n                backgroundColor: selectionColor,\n                strokeColor: [0, 0, 0, 0],\n                strokeJoin: 'round',\n                strokeCap: 'round',\n            });\n        }\n        ctx.restore();\n        didDraw = true;\n    }\n};\n\n/* src/core/ui/components/Canvas.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$T(ctx) {\n\tlet div;\n\tlet canvas_1;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcanvas_1 = element(\"canvas\");\n\t\t\tattr(div, \"class\", \"PinturaCanvas\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, canvas_1);\n\t\t\t/*canvas_1_binding*/ ctx[38](canvas_1);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(canvas_1, \"measure\", /*measure_handler*/ ctx[39]),\n\t\t\t\t\taction_destroyer(measurable.call(null, canvas_1))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp: noop,\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\t/*canvas_1_binding*/ ctx[38](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nconst SELECTION_MAX_SIZE = 2048;\nconst BitmapTexturePadding = 2;\nlet throttledMinRedrawDist = 48;\n\nfunction instance$U($$self, $$props, $$invalidate) {\n\tlet canDraw;\n\tlet drawUpdate;\n\tlet $maskFrameOpacityStore;\n\tlet $imageOverlayColor;\n\tlet $maskOpacityStore;\n\tlet $mask;\n\tlet $background;\n\tconst Vec4Empty = [0, 0, 0, 0];\n\n\t// just so we can re-use one empty vector\n\tconst EmptyVector = vectorCreateEmpty();\n\n\t// create grid texture\n\tconst TransparencyGrid = isBrowser() && createTransparencyGrid(128);\n\n\t// used to dispatch the 'measure' event\n\tconst dispatch = createEventDispatcher();\n\n\tlet { isAnimated } = $$props;\n\tlet { isTransparent } = $$props;\n\tlet { maskRect } = $$props;\n\tlet { maskOpacity = 1 } = $$props;\n\tlet { maskFrameOpacity = 0.95 } = $$props;\n\tlet { maskMarkupOpacity = 1 } = $$props;\n\tlet { clipAnnotationsToImage = true } = $$props;\n\tlet { pixelRatio = 1 } = $$props;\n\tlet { textPixelRatio = pixelRatio } = $$props;\n\tlet { backgroundColor } = $$props;\n\tlet { willRender = passthrough } = $$props;\n\tlet { didRender = passthrough } = $$props;\n\tlet { willRequest = undefined } = $$props;\n\tlet { csp = undefined } = $$props;\n\tlet { loadImageData = passthrough } = $$props;\n\tlet { enableGrid = false } = $$props;\n\tlet { gridColors = undefined } = $$props;\n\tlet { gridSize = undefined } = $$props;\n\tlet { gridOpacity = 0 } = $$props;\n\tlet { images = [] } = $$props;\n\tlet { interfaceImages = [] } = $$props;\n\tlet { selectionColor = undefined } = $$props;\n\tlet { onerror = noop$1 } = $$props;\n\n\t// internal props\n\tlet canvas;\n\n\tlet canvasGL = null;\n\tlet width = null;\n\tlet height = null;\n\n\t// springyness for main preview\n\tconst updateSpring = (spring, value) => spring.set(value, { hard: !isAnimated });\n\n\tconst SPRING_PROPS = { precision: 0.0001 };\n\tconst SPRING_PROPS_FRACTION = { precision: SPRING_PROPS.precision * 0.01 };\n\n\t// Editor UI\n\tlet backgroundColorAnimationDuration = 0;\n\n\tconst background = tweened(undefined, { duration: 0 });\n\tcomponent_subscribe($$self, background, value => $$invalidate(37, $background = value));\n\tconst maskOpacityStore = spring(1, SPRING_PROPS_FRACTION);\n\tcomponent_subscribe($$self, maskOpacityStore, value => $$invalidate(36, $maskOpacityStore = value));\n\tconst maskFrameOpacityStore = spring(1, SPRING_PROPS_FRACTION);\n\tcomponent_subscribe($$self, maskFrameOpacityStore, value => $$invalidate(52, $maskFrameOpacityStore = value));\n\tconst mask = writable();\n\tcomponent_subscribe($$self, mask, value => $$invalidate(54, $mask = value));\n\tconst imageOverlayColor = writable();\n\tcomponent_subscribe($$self, imageOverlayColor, value => $$invalidate(53, $imageOverlayColor = value));\n\n\t//#region selection\n\tconst selectionCache = {};\n\n\tconst shouldRedrawSelection = (previousActions, currentActions) => {\n\t\t// length change, always redraw\n\t\tif (previousActions.total !== currentActions.length) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// we only have to compare last shape\n\t\tconst previousLast = previousActions.last;\n\n\t\tconst currentLast = currentActions[currentActions.length - 1];\n\n\t\t// if not the same shape, redraw\n\t\tif (previousLast.drawMode !== currentLast.drawMode) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (shapeIsRect(previousLast) && (!shapeIsRect(currentLast) || !rectEqual(previousLast, currentLast))) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (shapeIsEllipse(previousLast) && (!shapeIsEllipse(currentLast) || !(previousLast.x === currentLast.x && previousLast.y === currentLast.y && previousLast.rx === currentLast.rx && previousLast.ry === currentLast.ry))) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (shapeIsPath(previousLast) && (!shapeIsPath(currentLast) || // different shapes\n\t\tpreviousLast.id !== currentLast.id || // different amount of points\n\t\tpreviousLast.points.length !== currentLast.points.length || // pointer point differs\n\t\tpreviousLast.pointerPoint && currentLast.pointerPoint && !vectorEqual(previousLast.pointerPoint, currentLast.pointerPoint))) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// no change\n\t\treturn false;\n\t};\n\n\tconst mapSelectionToShape = (selection, imageSize) => {\n\t\t// reference to cached state\n\t\tlet cachedSelection = selectionCache[selection.id];\n\n\t\t// calculate selection scalar, this speeds up performance\n\t\tconst scalar = Math.min(1, SELECTION_MAX_SIZE / imageSize.width);\n\n\t\tlet selectionCanvas = cachedSelection\n\t\t? cachedSelection.element\n\t\t: h('canvas', {\n\t\t\t\twidth: imageSize.width * scalar,\n\t\t\t\theight: imageSize.height * scalar,\n\t\t\t\t'data-retain': true\n\t\t\t});\n\n\t\t// new actions, need to redraw\n\t\tif (!cachedSelection || shouldRedrawSelection(cachedSelection, selection.actions)) {\n\t\t\t// clone so texture is redrawn (TODO: make live canvas texture possible)\n\t\t\tselectionCanvas = selectionCanvas.cloneNode();\n\n\t\t\t// draw actions\n\t\t\tctxDrawSelection(selectionCanvas.getContext('2d'), selection.actions, {\n\t\t\t\t// magenta, is replaced in webgl layer\n\t\t\t\tselectionColor: [1, 0, 1],\n\t\t\t\t// scale of canvas relative to image\n\t\t\t\tscalar\n\t\t\t});\n\n\t\t\t// store for next draw\n\t\t\tconst total = selection.actions.length;\n\n\t\t\tselectionCache[selection.id] = {\n\t\t\t\ttotal,\n\t\t\t\tlast: { ...selection.actions[total - 1] },\n\t\t\t\telement: selectionCanvas\n\t\t\t};\n\t\t}\n\n\t\t// create shape to hold texture\n\t\treturn {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\t...imageSize,\n\t\t\tfillColor: selection.color || [1, 1, 1],\n\t\t\tbackgroundImage: selectionCanvas\n\t\t};\n\t};\n\n\t//#endregion\n\t//#region texture loading and binding\n\tlet redrawRequest;\n\n\tconst requestRedraw = () => {\n\t\tcancelAnimationFrame(redrawRequest);\n\n\t\tredrawRequest = requestAnimationFrame(() => {\n\t\t\t// this triggers redraw of items marked as non-dirty\n\t\t\tredrawForce = true;\n\n\t\t\t// this makes sure delayed redraw also works\n\t\t\tthrottledLastDrawTime = 0;\n\n\t\t\t// draw the update\n\t\t\tdrawUpdate();\n\t\t});\n\t};\n\n\tconst Textures = new Map([]);\n\tconst PlaceholderTextures = new Map([]);\n\n\tconst isTextureResourceLoaded = resource => // not is url or dataurl\n\t!isString(resource) && (// is something that is accepted as webgl texture\n\tisImageBitmap(resource) || isImageData(resource) || isCanvas(resource) || isVideoElement(resource));\n\n\tconst getTextureParams = (imageRendering, textureWrapping) => {\n\t\t// get texture filter mode\n\t\tconst filterParam = imageRendering === 'pixelated'\n\t\t? canvasGL.textureFilterNearest\n\t\t: canvasGL.textureFilterLinear;\n\n\t\tconst wrapParam = textureWrapping === 'repeat'\n\t\t? canvasGL.textureRepeat\n\t\t: canvasGL.textureClamp;\n\n\t\treturn { filterParam, wrapParam };\n\t};\n\n\tconst getImageTexture = (image, imageRendering, textureWrapping) => {\n\t\t// no texture yet for this source\n\t\tif (!Textures.has(image)) {\n\t\t\t// is in loading state when is same as source\n\t\t\tTextures.set(image, image);\n\n\t\t\t// get texture filter mode\n\t\t\tconst textureParams = getTextureParams(imageRendering, textureWrapping);\n\n\t\t\t// already loaded\n\t\t\tif (isTextureResourceLoaded(image)) {\n\t\t\t\t// create texture\n\t\t\t\tconst texture = canvasGL.textureCreate();\n\n\t\t\t\t// udpate texture in gl canvas\n\t\t\t\tcanvasGL.textureUpdate(texture, image, textureParams);\n\n\t\t\t\t// update state we now have a texture\n\t\t\t\tTextures.set(image, texture);\n\t\t\t} else // need to load the image\n\t\t\t{\n\t\t\t\t// start loading the image\n\t\t\t\tloadImageData(image).then(data => {\n\t\t\t\t\t// canvas destroyed while loading texture data, or no data returned\n\t\t\t\t\tif (!canvasGL || !data) return;\n\n\t\t\t\t\t// create texture\n\t\t\t\t\tconst texture = canvasGL.textureCreate();\n\n\t\t\t\t\t// udpate texture in gl canvas\n\t\t\t\t\tcanvasGL.textureUpdate(texture, data, textureParams);\n\n\t\t\t\t\t// update state we now have a texture\n\t\t\t\t\tTextures.set(image, texture);\n\n\t\t\t\t\t// need to redraw because texture is now available\n\t\t\t\t\trequestRedraw();\n\t\t\t\t}).catch(err => {\n\t\t\t\t\tTextures.set(image, err);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// texture is a video and should be updated\n\t\tif (isVideoElement(image) && (isVideoPlaying(image) || image.dataset.redraw === 'true')) {\n\t\t\tconst texture = Textures.get(image);\n\n\t\t\t// get texture filter mode\n\t\t\tconst textureParams = getTextureParams(imageRendering, textureWrapping);\n\n\t\t\t// udpate texture in gl canvas\n\t\t\tcanvasGL.textureUpdate(texture, image, textureParams);\n\n\t\t\t// done drawing\n\t\t\timage.dataset.redraw = false;\n\n\t\t\t// done!\n\t\t\treturn texture;\n\t\t}\n\n\t\t// get texture to return\n\t\treturn Textures.get(image);\n\t};\n\n\tconst getTextTexture = (shape, shapeExtendedProps = {}) => {\n\t\t// this allows setting a custom id (for use with shadow and outline)\n\t\tconst shapeId = shapeExtendedProps.id || shape.id;\n\n\t\t// skip very small shapes and shapes with not text\n\t\tif (shape.width && shape.width < 1 || shape.height && shape.height < 1 || !shape.text.length) {\n\t\t\tPlaceholderTextures.delete(shapeId);\n\t\t\treturn undefined;\n\t\t}\n\n\t\tlet { text, textAlign, fontFamily, fontSize = 16, fontWeight, fontVariant, fontStyle, letterSpacing, lineHeight = fontSize, width, height } = shape;\n\t\tlet { outline = 0, blur = 0, paddingTop = 0, paddingRight = 0, paddingBottom = 0, paddingLeft = 0 } = shapeExtendedProps;\n\n\t\t// this is the same as how contenteditable floors width/height\n\t\twidth = isNumber(width) ? Math.floor(width) : width;\n\n\t\theight = isNumber(height) ? Math.floor(height) : height;\n\n\t\tconst { textSize, signature } = textMeasure(text, {\n\t\t\t...shape,\n\t\t\twidth,\n\t\t\t// we don't want to limit height so the texture can contain all vertical text,\n\t\t\t// when switching between text modes this makes it possible to use same texture\n\t\t\t// for auto-height and fixed-height\n\t\t\theight: undefined\n\t\t});\n\n\t\tconst textUID = objectUID({\n\t\t\ttext,\n\t\t\ttextAlign,\n\t\t\tfontFamily,\n\t\t\tfontSize,\n\t\t\tfontWeight,\n\t\t\tfontVariant,\n\t\t\tfontStyle,\n\t\t\tlineHeight,\n\t\t\tletterSpacing,\n\t\t\toutline,\n\t\t\tblur,\n\t\t\tsignature\n\t\t});\n\n\t\t// get texture unit assigned to this specific text shape\n\t\tif (!Textures.has(textUID)) {\n\t\t\t// is in loading state when is same as source\n\t\t\tTextures.set(textUID, text);\n\n\t\t\t// defined size of text box\n\t\t\t// - line: undefined, undefined\n\t\t\t// - auto: width, undefined\n\t\t\t// - box:  width, height\n\t\t\tconst imageWidth = Math.ceil(textSize.width);\n\n\t\t\tconst imageHeight = Math.ceil(textSize.height);\n\n\t\t\t// skip\n\t\t\tif (imageWidth === 0 || imageHeight === 0) return;\n\n\t\t\t// check if needs to scale texture\n\t\t\tconst textureSizeLimit = getWebGLTextureSizeLimit();\n\n\t\t\tconst textureSizeScalar = Math.min(\n\t\t\t\t1,\n\t\t\t\t// x\n\t\t\t\t(textureSizeLimit - (paddingLeft + paddingRight) * textPixelRatio) / (imageWidth * textPixelRatio),\n\t\t\t\t// y\n\t\t\t\t(textureSizeLimit - (paddingTop + paddingBottom) * textPixelRatio) / (imageHeight * textPixelRatio)\n\t\t\t);\n\n\t\t\t// create texture\n\t\t\ttextToImage(text, {\n\t\t\t\tfontSize,\n\t\t\t\tfontFamily,\n\t\t\t\tfontWeight,\n\t\t\t\tfontVariant,\n\t\t\t\tfontStyle,\n\t\t\t\tletterSpacing,\n\t\t\t\ttextAlign,\n\t\t\t\tlineHeight,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\timageWidth,\n\t\t\t\timageHeight,\n\t\t\t\tpaddingLeft,\n\t\t\t\tpaddingTop,\n\t\t\t\tpaddingRight,\n\t\t\t\tpaddingBottom,\n\t\t\t\tpixelRatio: textPixelRatio * textureSizeScalar,\n\t\t\t\twillRequest,\n\t\t\t\toutline,\n\t\t\t\tblur,\n\t\t\t\tstyleNonce: csp.styleNonce,\n\t\t\t\tcolor: [1, 0, 1], // purple will be replaced in render method\n\t\t\t\t\n\t\t\t}).then(image => {\n\t\t\t\t// canvas destroyed while loading texture data\n\t\t\t\tif (!canvasGL) return;\n\n\t\t\t\t// create texture\n\t\t\t\tconst texture = canvasGL.textureCreate();\n\n\t\t\t\t// update texture in gl canvas\n\t\t\t\tcanvasGL.textureUpdate(texture, image, {\n\t\t\t\t\tfilterParam: canvasGL.textureFilterLinear,\n\t\t\t\t\twrapParam: canvasGL.textureClamp,\n\t\t\t\t\tscalar: textureSizeScalar,\n\t\t\t\t\t// for some reason the Firefox source image is rendered differently if we don't do this, color replacement then doesn't work correctly\n\t\t\t\t\tpremultiply: isFirefox() ? false : true\n\t\t\t\t});\n\n\t\t\t\t// update state we now have a texture\n\t\t\t\tTextures.set(textUID, texture);\n\n\t\t\t\t// use as fallback texture for next update\n\t\t\t\tPlaceholderTextures.set(shapeId, texture);\n\n\t\t\t\t// need to redraw because texture is now available\n\t\t\t\trequestRedraw();\n\t\t\t}).catch(console.error);\n\t\t}\n\n\t\tconst texture = Textures.get(textUID);\n\n\t\treturn isTexture(texture)\n\t\t? texture\n\t\t: PlaceholderTextures.get(shapeId);\n\t};\n\n\tconst canvasCache = new Map();\n\n\tconst getBitmapTexture = shape => {\n\t\tconst { id, points, strokeWidth, strokeCap, strokeJoin, strokeColor, strokeDash, pathClose, backgroundColor } = shape;\n\t\tlet texture = Textures.get(id);\n\t\tlet canvasState = canvasCache.get(id);\n\n\t\t// unique id for shape (currently only supports path)\n\t\tconst hash = objectUID({\n\t\t\tpoints: points.map(p => `${p.x},${p.y}`).join(','),\n\t\t\tstrokeWidth,\n\t\t\tstrokeCap,\n\t\t\tstrokeJoin,\n\t\t\tstrokeColor,\n\t\t\tstrokeDash: (strokeDash || []).join(','),\n\t\t\tpathClose,\n\t\t\tbackgroundColor: pathClose\n\t\t\t? (backgroundColor || []).join(',')\n\t\t\t: undefined\n\t\t});\n\n\t\t// test if should redraw\n\t\tif (canvasState) {\n\t\t\tconst { hash: previousHash } = canvasState;\n\n\t\t\t// it's possible the texture has been removed so in that case\n\t\t\t// we need to reset canvas state so the texture is recreated\n\t\t\tif (!Textures.has(id)) {\n\t\t\t\tcanvasState = undefined;\n\t\t\t} else // same texture\n\t\t\tif (hash === previousHash) {\n\t\t\t\treturn Textures.get(id);\n\t\t\t}\n\t\t}\n\n\t\t// if is new bitmap shape we need to add a canvas\n\t\tif (!canvasState) {\n\t\t\t// initial canvas\n\t\t\tconst canvas = h('canvas', { width: 1, height: 1 });\n\n\t\t\tcanvasState = { canvas, hash: undefined };\n\n\t\t\t// remember\n\t\t\tcanvasCache.set(shape.id, canvasState);\n\n\t\t\t// create texture\n\t\t\ttexture = canvasGL.textureCreate();\n\n\t\t\t// udpate texture in gl canvas\n\t\t\tcanvasGL.textureUpdate(texture, canvas, {\n\t\t\t\tfilterParam: canvasGL.textureFilterLinear,\n\t\t\t\twrapParam: canvasGL.textureClamp\n\t\t\t});\n\n\t\t\t// store texture\n\t\t\tTextures.set(id, texture);\n\t\t}\n\n\t\t// get canvas reference\n\t\tconst { canvas } = canvasState;\n\n\t\t// calculate canvas rectangle\n\t\tconst padding = Math.ceil(shape.strokeWidth) + BitmapTexturePadding;\n\n\t\tconst rect = rectCreateFromPoints(points);\n\t\tconst x = Math.floor(rect.x - padding * 0.5);\n\t\tconst y = Math.floor(rect.y - padding * 0.5);\n\t\tconst width = Math.ceil(rect.width + padding);\n\t\tconst height = Math.ceil(rect.height + padding);\n\t\tcanvas.width = Math.max(width, 1);\n\t\tcanvas.height = Math.max(height, 1);\n\t\tconst ctx = canvas.getContext('2d');\n\t\tctx.clearRect(0, 0, canvas.width, canvas.height);\n\n\t\tif (width >= 1 && height >= 1) {\n\t\t\tctx.translate(-x, -y);\n\t\t\tdrawPath(ctx, shape);\n\t\t\tctx.resetTransform();\n\t\t}\n\n\t\t// redraw texture in webgl\n\t\tcanvasGL.textureUpdate(texture, canvas, {\n\t\t\tfilterParam: canvasGL.textureFilterLinear,\n\t\t\twrapParam: canvasGL.textureClamp\n\t\t});\n\n\t\t// cache new state\n\t\tcanvasCache.set(id, { canvas, hash });\n\n\t\treturn Textures.get(id);\n\t};\n\n\tconst getShapeTexture = shape => {\n\t\tlet texture;\n\n\t\t// let's create textures for backgrounds\n\t\tif (shape.backgroundImage) {\n\t\t\ttexture = getImageTexture(shape.backgroundImage, shape.backgroundImageRendering, shape.backgroundRepeat === 'repeat'\n\t\t\t? 'repeat'\n\t\t\t: undefined);\n\t\t} else // is bitmap drawn shape (path only for now)\n\t\tif (shape.bitmap && shape.points) {\n\t\t\ttexture = getBitmapTexture(shape);\n\t\t}\n\n\t\treturn texture;\n\t};\n\n\tconst releaseUnusedTextures = usedTextures => {\n\t\tTextures.forEach((registeredTexture, key) => {\n\t\t\tconst isUsed = !!usedTextures.find(usedTexture => usedTexture === registeredTexture);\n\n\t\t\t// stil used, no need to release\n\t\t\tif (isUsed || !isTexture(registeredTexture)) return;\n\n\t\t\t// skip if used as placeholder texture\n\t\t\tif (Array.from(PlaceholderTextures.values()).includes(registeredTexture)) return;\n\n\t\t\t// remove this texture\n\t\t\tTextures.delete(key);\n\n\t\t\tcanvasGL.textureDelete(registeredTexture);\n\t\t});\n\t};\n\n\t//#endregion\n\t//#region drawing\n\tconst drawImage = ({ texture, size, origin, translation, rotation, scale, colorMatrix, opacity, convolutionMatrix, gamma, vignette, maskFeather, maskCornerRadius, overlayColor, enableOverlay, enableManipulation, enableAntialiasing }) => {\n\t\t// this makes sure the image renders extra crisp on low res screens\n\t\tlet enableSnapToPixels = pixelRatio === 1;\n\n\t\tlet sharpenOffsetX = 0;\n\t\tlet sharpenOffsetY = 0;\n\n\t\tif (pixelRatio === 1) {\n\t\t\tconst atActualSize = Math.abs(1 - scale) < Number.EPSILON;\n\t\t\tsharpenOffsetX = atActualSize && width % 2 !== 0 ? 0.5 : 0;\n\t\t\tsharpenOffsetY = atActualSize && height % 2 !== 0 ? 0.5 : 0;\n\t\t}\n\n\t\t// draw the image\n\t\tcanvasGL.drawImage(texture, size, origin.x, origin.y, translation.x + sharpenOffsetX, translation.y + sharpenOffsetY, rotation.x, rotation.y, rotation.z, scale, colorMatrix, clamp(opacity, 0, 1), convolutionMatrix, gamma, vignette, maskFeather, maskCornerRadius, overlayColor, enableOverlay, enableManipulation, enableAntialiasing, enableSnapToPixels);\n\n\t\treturn texture;\n\t};\n\n\tconst getTextRotationTranslation = (textboxRect, shapeRect, rotation) => {\n\t\tconst shapeRectCenter = rectCenter(shapeRect);\n\t\tconst textboxRectCenter = rectCenter(textboxRect);\n\n\t\tconst shapeTranslation = {\n\t\t\tx: shapeRectCenter.x - textboxRectCenter.x,\n\t\t\ty: shapeRectCenter.y - textboxRectCenter.y\n\t\t};\n\n\t\tconst rotatedTranslation = vectorRotate(shapeRectCenter, rotation, textboxRectCenter);\n\n\t\treturn {\n\t\t\tx: rotatedTranslation.x - textboxRectCenter.x - shapeTranslation.x,\n\t\t\ty: rotatedTranslation.y - textboxRectCenter.y - shapeTranslation.y\n\t\t};\n\t};\n\n\tconst getTextAlignTranslation = (textboxRect, padding, backgroundSize, textAlign, flipX) => {\n\t\tif (textAlign === 'left' && !flipX) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tconst currentWidth = textboxRect.width + padding * 2;\n\t\tconst currentWidthDiff = currentWidth - backgroundSize.width;\n\n\t\t// flipX is true\n\t\tif (textAlign === 'left') {\n\t\t\treturn currentWidthDiff;\n\t\t}\n\n\t\t// flipX can be ignored\n\t\tif (textAlign === 'center') {\n\t\t\treturn currentWidthDiff * 0.5;\n\t\t}\n\n\t\t// if flipX is true invert\n\t\tif (textAlign === 'right') {\n\t\t\treturn flipX ? 0 : currentWidthDiff;\n\t\t}\n\n\t\treturn 0;\n\t};\n\n\tconst transformCornerRadius = (cornerRadius, scalar) => [cornerRadius, cornerRadius, cornerRadius, cornerRadius].map(v => v * scalar);\n\n\tconst computeBackgroundProps = (shape, shapeRect, textureSize) => {\n\t\tlet backgroundSize = undefined;\n\t\tlet backgroundPosition = undefined;\n\n\t\t// always respect texture aspect ratio\n\t\tconst textureAspectRatio = getAspectRatio(textureSize.width, textureSize.height);\n\n\t\t// if repeat is set, set position to 0,0  and size to textures size\n\t\tif (shape.backgroundRepeat === 'repeat') {\n\t\t\tbackgroundSize = { ...textureSize };\n\t\t\tbackgroundPosition = { x: 0, y: 0 };\n\t\t}\n\n\t\t// contain in rect\n\t\tif (shape.backgroundSize === 'contain') {\n\t\t\tconst rect = rectContainRect(shapeRect, textureAspectRatio, shapeRect);\n\t\t\tbackgroundSize = sizeCreateFromRect(rect);\n\n\t\t\tif (shape.backgroundPosition) {\n\t\t\t\tbackgroundPosition = shape.backgroundPosition;\n\t\t\t} else {\n\t\t\t\tbackgroundPosition = vectorCreate((shapeRect.width - backgroundSize.width) * 0.5, (shapeRect.height - backgroundSize.height) * 0.5);\n\t\t\t}\n\t\t} else // cover rect\n\t\tif (shape.backgroundSize === 'cover') {\n\t\t\tconst rect = rectCoverRect(shapeRect, textureAspectRatio, shapeRect);\n\t\t\tbackgroundSize = sizeCreateFromRect(rect);\n\n\t\t\tif (shape.backgroundPosition) {\n\t\t\t\tbackgroundPosition = shape.backgroundPosition;\n\t\t\t} else {\n\t\t\t\tbackgroundPosition = vectorCreate(rect.x, rect.y);\n\t\t\t\tbackgroundPosition = vectorCreate((shapeRect.width - backgroundSize.width) * 0.5, (shapeRect.height - backgroundSize.height) * 0.5);\n\t\t\t}\n\t\t} else // fixed size\n\t\tif (shape.backgroundSize) {\n\t\t\tbackgroundSize = shape.backgroundSize;\n\t\t\tbackgroundPosition = shape.backgroundPosition || { x: 0, y: 0 };\n\t\t} else // no size set but position is set\n\t\tif (shape.backgroundPosition) {\n\t\t\tbackgroundSize = { ...textureSize };\n\t\t\tbackgroundPosition = shape.backgroundPosition;\n\t\t}\n\n\t\treturn { backgroundSize, backgroundPosition };\n\t};\n\n\tconst drawShapes = (shapes = [], usedTextures) => {\n\t\t// return\n\t\tshapes.forEach(shape => {\n\t\t\t// only show texture if shape is finished loading\n\t\t\tlet shapeTexture = getShapeTexture(shape);\n\n\t\t\t// is loading texture\n\t\t\tconst isLoadingBackgroundImage = shape.status === 'complete'\n\t\t\t? false\n\t\t\t: shape.status === 'loading'\n\t\t\t\t? true\n\t\t\t\t: shape.backgroundImage && shapeTexture === shape.backgroundImage;\n\n\t\t\tif (isLoadingBackgroundImage) requestRedraw();\n\n\t\t\tconst isBackgroundLoadError = shape.status === 'error'\n\t\t\t? true\n\t\t\t: shape.backgroundImage && shapeTexture instanceof Error;\n\n\t\t\t// get the webgl texture\n\t\t\tlet texture = isTexture(shapeTexture) ? shapeTexture : undefined;\n\n\t\t\t// transforms\n\t\t\tconst scalar = shape._scale || 1;\n\n\t\t\tconst translation = shape._translate || EmptyVector;\n\n\t\t\t// scale stroke width\n\t\t\tconst strokeWidth = shape.strokeWidth && shape.strokeWidth * scalar;\n\n\t\t\tconst cornerRadius = shape.cornerRadius\n\t\t\t? transformCornerRadius(shape.cornerRadius, scalar)\n\t\t\t: Vec4Empty;\n\n\t\t\tconst isRect = !!shape.width;\n\t\t\tconst isText = isString(shape.text);\n\t\t\tconst isPath = isArray(shape.points);\n\t\t\tconst isEllipse = shapeIsEllipse(shape);\n\n\t\t\tif (isPath) {\n\t\t\t\t// transform points\n\t\t\t\tconst points = shape.points.map(point => vectorCreate(point.x * scalar + translation.x, point.y * scalar + translation.y));\n\n\t\t\t\t// if is bitmap\n\t\t\t\tif (shape.bitmap) {\n\t\t\t\t\t// need to add to used textures so we can know when no longer used\n\t\t\t\t\tif (shapeTexture) usedTextures.push(shapeTexture);\n\n\t\t\t\t\tconst rect = rectCreateFromPoints(points);\n\t\t\t\t\tconst padding = Math.ceil(shape.strokeWidth * scalar) + BitmapTexturePadding;\n\n\t\t\t\t\tcanvasGL.drawRect(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tx: Math.floor(rect.x - padding * 0.5),\n\t\t\t\t\t\t\ty: Math.floor(rect.y - padding * 0.5),\n\t\t\t\t\t\t\twidth: Math.ceil(rect.width + padding),\n\t\t\t\t\t\t\theight: Math.ceil(rect.height + padding)\n\t\t\t\t\t\t},\n\t\t\t\t\t\tshape.rotation,\n\t\t\t\t\t\tshape.flipX,\n\t\t\t\t\t\tshape.flipY,\n\t\t\t\t\t\t[0, 0, 0, 0],\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\ttexture,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tshape.opacity,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tcanvasGL.drawPath(points, shape.rotation, shape.flipX, shape.flipY, strokeWidth, shape.strokeColor, shape.pathClose, shape.backgroundColor, shape.opacity);\n\t\t\t\t}\n\t\t\t} else if (isEllipse) {\n\t\t\t\tlet x = shape.x;\n\t\t\t\tlet y = shape.y;\n\t\t\t\tx *= scalar;\n\t\t\t\ty *= scalar;\n\t\t\t\tx += translation.x;\n\t\t\t\ty += translation.y;\n\n\t\t\t\t// apply shape transforms\n\t\t\t\tconst shapeRect = rectCreateFromEllipse({\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\trx: shape.rx * scalar,\n\t\t\t\t\try: shape.ry * scalar\n\t\t\t\t});\n\n\t\t\t\tconst center = vectorCreate(x, y);\n\t\t\t\tconst textureSize = texture && canvasGL.textureGetSize(texture);\n\t\t\t\tlet backgroundSize;\n\t\t\t\tlet backgroundPosition;\n\n\t\t\t\tif (textureSize && shape.backgroundImage && (shape.backgroundSize || shape.backgroundPosition || shape.backgroundRepeat)) {\n\t\t\t\t\tconst backgroundProps = computeBackgroundProps(shape, shapeRect, textureSize);\n\t\t\t\t\tbackgroundSize = backgroundProps.backgroundSize;\n\t\t\t\t\tbackgroundPosition = backgroundProps.backgroundPosition;\n\t\t\t\t}\n\n\t\t\t\tcanvasGL.drawEllipse(center, shape.rx * scalar, shape.ry * scalar, shape.rotation, shape.flipX, shape.flipY, shape.backgroundColor, texture, backgroundSize, backgroundPosition, shape.backgroundCorners && backgroundCornersToUVMap(shape.backgroundCorners), strokeWidth, shape.strokeColor, shape.opacity, shape.inverted);\n\n\t\t\t\t// need to add to used textures so we can know when no longer used\n\t\t\t\tif (shapeTexture) usedTextures.push(shapeTexture);\n\n\t\t\t\t// draw loading indicator\n\t\t\t\tif (isLoadingBackgroundImage || isBackgroundLoadError) {\n\t\t\t\t\tif (!shape.backgroundColor && (!shape.strokeColor || !shape.strokeWidth)) {\n\t\t\t\t\t\tconst opacity = shape.opacity || 1;\n\n\t\t\t\t\t\tcanvasGL.drawEllipse(center, shape.rx * scalar, shape.ry * scalar, shape.rotation, shape.flipX, shape.flipY, isBackgroundLoadError\n\t\t\t\t\t\t? [1, 0.2549, 0.2118, 0.25 * opacity]\n\t\t\t\t\t\t: [0, 0, 0, 0.25 * opacity]);\n\t\t\t\t\t}\n\n\t\t\t\t\tisBackgroundLoadError && drawErrorIndicator(center);\n\t\t\t\t\tisLoadingBackgroundImage && drawLoadingIndicator(center);\n\t\t\t\t}\n\t\t\t} else if (isText) {\n\t\t\t\t// get fontsize ref and fallback to default\n\t\t\t\tconst { fontSize = 16 } = shape;\n\n\t\t\t\t// adjust font scalar\n\t\t\t\tconst fontScalar = fontSize > 1000 && isFirefox() ? fontSize / 1000 : 1;\n\n\t\t\t\t// calculate text padding\n\t\t\t\tconst textPadding = Math.max(16, Math.ceil(fontSize / fontScalar * 0.25));\n\n\t\t\t\t// get text size\n\t\t\t\tconst textboxIsRotated = Math.abs(shape.rotation) > 0;\n\n\t\t\t\tconst width = isNumber(shape.width)\n\t\t\t\t? Math.floor(shape.width)\n\t\t\t\t: shape.width;\n\n\t\t\t\tconst height = isNumber(shape.height)\n\t\t\t\t? Math.floor(shape.height)\n\t\t\t\t: shape.height;\n\n\t\t\t\tconst textboxSize = textToSize(shape.text, { ...shape, width, height });\n\t\t\t\tconst textboxWidth = Math.ceil(textboxSize.width);\n\t\t\t\tconst textboxHeight = Math.ceil(textboxSize.height);\n\n\t\t\t\tconst textboxRect = {\n\t\t\t\t\tx: shape.x * scalar + translation.x,\n\t\t\t\t\ty: shape.y * scalar + translation.y,\n\t\t\t\t\twidth: textboxWidth * scalar,\n\t\t\t\t\theight: textboxHeight * scalar\n\t\t\t\t};\n\n\t\t\t\t// should clip\n\t\t\t\tconst shouldClipTextEffects = !!shape.height;\n\n\t\t\t\t//\n\t\t\t\t// 1. Draw text background\n\t\t\t\t//\n\t\t\t\tif (shape.backgroundColor || shape.strokeColor) {\n\t\t\t\t\t// draw background\n\t\t\t\t\tcanvasGL.drawRect(textboxRect, shape.rotation, shape.flipX, shape.flipY, cornerRadius, shape.backgroundColor, undefined, undefined, undefined, false, undefined, strokeWidth, shape.strokeColor, shape.opacity, undefined, undefined, undefined, shape.inverted);\n\t\t\t\t}\n\n\t\t\t\t//\n\t\t\t\t// 2. Draw text shadow\n\t\t\t\t//\n\t\t\t\tconst { textShadowX, textShadowY, textShadowBlur } = shape;\n\n\t\t\t\tif (textShadowX || textShadowY || textShadowBlur) {\n\t\t\t\t\t// generate texture\n\t\t\t\t\tconst textShadowBlurHalf = Math.ceil(textShadowBlur * 0.5);\n\n\t\t\t\t\tconst padding = Math.max(textPadding, shouldClipTextEffects ? 0 : textShadowBlurHalf);\n\n\t\t\t\t\tconst shadowTexture = getTextTexture(shape, {\n\t\t\t\t\t\tid: shape.id + 'shadow',\n\t\t\t\t\t\tblur: textShadowBlur,\n\t\t\t\t\t\tpaddingTop: padding,\n\t\t\t\t\t\tpaddingRight: padding,\n\t\t\t\t\t\tpaddingBottom: padding,\n\t\t\t\t\t\tpaddingLeft: padding\n\t\t\t\t\t});\n\n\t\t\t\t\t// when received texture\n\t\t\t\t\tif (shadowTexture && !shape._prerender) {\n\t\t\t\t\t\tusedTextures.push(shadowTexture);\n\t\t\t\t\t\tconst shadowTextureSize = canvasGL.textureGetSize(shadowTexture);\n\n\t\t\t\t\t\t// where to position\n\t\t\t\t\t\tconst backgroundPosition = { x: 0, y: 0 };\n\n\t\t\t\t\t\t// size of background\n\t\t\t\t\t\tconst backgroundSize = {\n\t\t\t\t\t\t\twidth: shadowTextureSize.width / textPixelRatio * scalar,\n\t\t\t\t\t\t\theight: shadowTextureSize.height / textPixelRatio * scalar\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst scaledPadding = textPadding * scalar / fontScalar;\n\n\t\t\t\t\t\t// will hold shape rect to draw\n\t\t\t\t\t\tlet shapeRect;\n\n\t\t\t\t\t\t// when clipping text effects the shadow texture rect is the same as the text box rect so we done\n\t\t\t\t\t\tif (shouldClipTextEffects) {\n\t\t\t\t\t\t\tshapeRect = { ...textboxRect };\n\n\t\t\t\t\t\t\t// adjust position based on shadow offset\n\t\t\t\t\t\t\tbackgroundPosition.x = textShadowX - scaledPadding;\n\n\t\t\t\t\t\t\tbackgroundPosition.y = textShadowY - scaledPadding;\n\n\t\t\t\t\t\t\t// fix right text alignment\n\t\t\t\t\t\t\tif (shape.textAlign === 'right') {\n\t\t\t\t\t\t\t\tbackgroundPosition.x += shapeRect.width - (backgroundSize.width - scaledPadding * 2);\n\t\t\t\t\t\t\t} else // fix center text alignment\n\t\t\t\t\t\t\tif (shape.textAlign === 'center') {\n\t\t\t\t\t\t\t\tbackgroundPosition.x += (shapeRect.width - (backgroundSize.width - scaledPadding * 2)) * 0.5;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else // offset shape rect\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tshapeRect = {\n\t\t\t\t\t\t\t\tx: shape.x * scalar + translation.x - scaledPadding,\n\t\t\t\t\t\t\t\ty: shape.y * scalar + translation.y - scaledPadding,\n\t\t\t\t\t\t\t\twidth: backgroundSize.width,\n\t\t\t\t\t\t\t\theight: backgroundSize.height\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// reposition based on text alignment\n\t\t\t\t\t\t\tconst textAlignTranslation = getTextAlignTranslation(textboxRect, scaledPadding, backgroundSize, shape.textAlign, shape.flipX);\n\n\t\t\t\t\t\t\tshapeRect.x += textAlignTranslation;\n\n\t\t\t\t\t\t\t// find offset so we can calculate correct text shape position when rotated (texture rotates around different point than textbox)\n\t\t\t\t\t\t\tif (textboxIsRotated) {\n\t\t\t\t\t\t\t\tconst rotationTranslation = getTextRotationTranslation(textboxRect, shapeRect, shape.rotation);\n\t\t\t\t\t\t\t\tshapeRect.x += rotationTranslation.x;\n\t\t\t\t\t\t\t\tshapeRect.y += rotationTranslation.y;\n\n\t\t\t\t\t\t\t\t// calculate shadow offset\n\t\t\t\t\t\t\t\tconst shadowOffset = vectorRotate(vectorCreate(textShadowX, textShadowY), shape.rotation);\n\n\t\t\t\t\t\t\t\t// apply shadow transforms\n\t\t\t\t\t\t\t\tshapeRect.x += shadowOffset.x;\n\n\t\t\t\t\t\t\t\tshapeRect.y += shadowOffset.y;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tshapeRect.x += textShadowX;\n\t\t\t\t\t\t\t\tshapeRect.y += textShadowY;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// draw shadow\n\t\t\t\t\t\tcanvasGL.drawRect(shapeRect, shape.rotation, shape.flipX, shape.flipY, [0, 0, 0, 0], undefined, shadowTexture, backgroundSize, backgroundPosition, false, undefined, undefined, undefined, shape.opacity, undefined, 0, shape.textShadowColor);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t//\n\t\t\t\t// 3. Draw text outline\n\t\t\t\t//\n\t\t\t\tif (shape.textOutlineWidth) {\n\t\t\t\t\tconst textOutlineWidthHalf = Math.ceil(shape.textOutlineWidth * 0.5);\n\t\t\t\t\tconst outlinePadding = textPadding + textOutlineWidthHalf;\n\n\t\t\t\t\tconst outlineTexture = getTextTexture(shape, {\n\t\t\t\t\t\tid: shape.id + 'outline',\n\t\t\t\t\t\toutline: shape.textOutlineWidth,\n\t\t\t\t\t\tpaddingTop: outlinePadding,\n\t\t\t\t\t\tpaddingRight: outlinePadding,\n\t\t\t\t\t\tpaddingBottom: outlinePadding,\n\t\t\t\t\t\tpaddingLeft: outlinePadding\n\t\t\t\t\t});\n\n\t\t\t\t\tif (outlineTexture && !shape._prerender) {\n\t\t\t\t\t\tusedTextures.push(outlineTexture);\n\t\t\t\t\t\tconst outlineTextureSize = canvasGL.textureGetSize(outlineTexture);\n\n\t\t\t\t\t\t// where to position\n\t\t\t\t\t\tconst backgroundPosition = { x: 0, y: 0 };\n\n\t\t\t\t\t\t// size of background\n\t\t\t\t\t\tconst backgroundSize = {\n\t\t\t\t\t\t\twidth: outlineTextureSize.width / textPixelRatio * scalar,\n\t\t\t\t\t\t\theight: outlineTextureSize.height / textPixelRatio * scalar\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// build scaled shape rect\n\t\t\t\t\t\tconst scaledPadding = (textPadding + textOutlineWidthHalf) * scalar / fontScalar;\n\n\t\t\t\t\t\tconst shapeRect = {\n\t\t\t\t\t\t\tx: shape.x * scalar + translation.x - scaledPadding,\n\t\t\t\t\t\t\ty: shape.y * scalar + translation.y - scaledPadding,\n\t\t\t\t\t\t\twidth: backgroundSize.width,\n\t\t\t\t\t\t\t// need to clip shape if height is set\n\t\t\t\t\t\t\theight: shape.height\n\t\t\t\t\t\t\t? textboxHeight + scaledPadding\n\t\t\t\t\t\t\t: backgroundSize.height\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t// reposition based on text alignment\n\t\t\t\t\t\tconst textAlignTranslation = getTextAlignTranslation(textboxRect, scaledPadding, backgroundSize, shape.textAlign, shape.flipX);\n\n\t\t\t\t\t\tshapeRect.x += textAlignTranslation;\n\n\t\t\t\t\t\t// apply rotation translation\n\t\t\t\t\t\tif (textboxIsRotated) {\n\t\t\t\t\t\t\tconst rotationTranslation = getTextRotationTranslation(textboxRect, shapeRect, shape.rotation);\n\t\t\t\t\t\t\tshapeRect.x += rotationTranslation.x;\n\t\t\t\t\t\t\tshapeRect.y += rotationTranslation.y;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcanvasGL.drawRect(shapeRect, shape.rotation, shape.flipX, shape.flipY, [0, 0, 0, 0], undefined, outlineTexture, backgroundSize, backgroundPosition, false, undefined, undefined, undefined, shape.opacity, undefined, 0, shape.textOutlineColor);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t//\n\t\t\t\t// 4. Draw text itself\n\t\t\t\t//\n\t\t\t\tconst textTexture = getTextTexture(shape, {\n\t\t\t\t\tid: shape.id + 'text',\n\t\t\t\t\tpaddingTop: textPadding,\n\t\t\t\t\tpaddingRight: textPadding,\n\t\t\t\t\tpaddingBottom: textPadding,\n\t\t\t\t\tpaddingLeft: textPadding\n\t\t\t\t});\n\n\t\t\t\tif (textTexture && !shape._prerender) {\n\t\t\t\t\tusedTextures.push(textTexture);\n\t\t\t\t\tconst textTextureSize = canvasGL.textureGetSize(textTexture);\n\n\t\t\t\t\t// where to position\n\t\t\t\t\tconst backgroundPosition = { x: 0, y: 0 };\n\n\t\t\t\t\t// size of background\n\t\t\t\t\tconst backgroundSize = {\n\t\t\t\t\t\twidth: textTextureSize.width / textPixelRatio * scalar,\n\t\t\t\t\t\theight: textTextureSize.height / textPixelRatio * scalar\n\t\t\t\t\t};\n\n\t\t\t\t\tconst scaledPadding = textPadding * scalar / fontScalar;\n\n\t\t\t\t\tconst shapeRect = {\n\t\t\t\t\t\tx: shape.x * scalar + translation.x - scaledPadding,\n\t\t\t\t\t\ty: shape.y * scalar + translation.y - scaledPadding,\n\t\t\t\t\t\twidth: backgroundSize.width,\n\t\t\t\t\t\t// need to clip shape if height is set\n\t\t\t\t\t\theight: shape.height\n\t\t\t\t\t\t? textboxHeight + scaledPadding\n\t\t\t\t\t\t: backgroundSize.height\n\t\t\t\t\t};\n\n\t\t\t\t\t// reposition based on text alignment\n\t\t\t\t\tconst textAlignTranslation = getTextAlignTranslation(textboxRect, scaledPadding, backgroundSize, shape.textAlign, shape.flipX);\n\n\t\t\t\t\tshapeRect.x += textAlignTranslation;\n\n\t\t\t\t\t// find offset so we can calculate correct text shape position when rotated (texture rotates around different point than textbox)\n\t\t\t\t\tif (textboxIsRotated) {\n\t\t\t\t\t\tconst rotationTranslation = getTextRotationTranslation(textboxRect, shapeRect, shape.rotation);\n\t\t\t\t\t\tshapeRect.x += rotationTranslation.x;\n\t\t\t\t\t\tshapeRect.y += rotationTranslation.y;\n\t\t\t\t\t}\n\n\t\t\t\t\t// The text texture needs to be colorized (we don't regenerate it on color change as that would be too slow)\n\t\t\t\t\tconst colorize = shape.color || [0, 0, 0];\n\n\t\t\t\t\t// If we're pre-rendering we do request drawing the texture but we hide it from view\n\t\t\t\t\tif (shape._prerender) colorize[3] = 0;\n\n\t\t\t\t\tcanvasGL.drawRect(shapeRect, shape.rotation, shape.flipX, shape.flipY, Vec4Empty, false, textTexture, backgroundSize, backgroundPosition, false, false, undefined, undefined, shape.opacity, undefined, shape.feather, colorize, shape.inverted);\n\t\t\t\t}\n\t\t\t} else if (isRect) {\n\t\t\t\t// need to add to used textures so we can know when no longer used\n\t\t\t\tif (shapeTexture) {\n\t\t\t\t\tusedTextures.push(shapeTexture);\n\t\t\t\t}\n\n\t\t\t\t// apply shape transforms\n\t\t\t\tconst shapeRect = rectCreateFromAny(shape);\n\n\t\t\t\tif (scalar && translation) {\n\t\t\t\t\tshapeRect.x *= scalar;\n\t\t\t\t\tshapeRect.y *= scalar;\n\t\t\t\t\tshapeRect.x += translation.x;\n\t\t\t\t\tshapeRect.y += translation.y;\n\t\t\t\t\tshapeRect.width *= scalar;\n\t\t\t\t\tshapeRect.height *= scalar;\n\t\t\t\t}\n\n\t\t\t\t// get texture\n\t\t\t\tlet backgroundSize, backgroundPosition;\n\n\t\t\t\tconst { backgroundRepeat = 'no-repeat' } = shape;\n\t\t\t\tconst textureSize = texture && canvasGL.textureGetSize(texture);\n\n\t\t\t\tif (textureSize && shape.backgroundImage && (shape.backgroundSize || shape.backgroundPosition || shape.backgroundRepeat)) {\n\t\t\t\t\tconst backgroundProps = computeBackgroundProps(shape, shapeRect, textureSize);\n\t\t\t\t\tbackgroundSize = backgroundProps.backgroundSize;\n\t\t\t\t\tbackgroundPosition = backgroundProps.backgroundPosition;\n\t\t\t\t}\n\n\t\t\t\t// draw the rect\n\t\t\t\tcanvasGL.drawRect(shapeRect, shape.rotation, shape.flipX, shape.flipY, cornerRadius, shape.backgroundColor || [0, 0, 0, 0], texture, backgroundSize, backgroundPosition, backgroundRepeat === 'repeat', shape.backgroundCorners && backgroundCornersToUVMap(shape.backgroundCorners), strokeWidth, shape.strokeColor, shape.opacity, undefined, shape.feather, shape.fillColor, shape.inverted);\n\n\t\t\t\t// draw loading indicator\n\t\t\t\tif (isLoadingBackgroundImage || isBackgroundLoadError) {\n\t\t\t\t\tif ((!shape.backgroundColor || shape.backgroundColor[3] === 0) && (!shape.strokeColor || !shape.strokeWidth)) {\n\t\t\t\t\t\tconst opacity = shape.opacity || 1;\n\n\t\t\t\t\t\tcanvasGL.drawRect(shapeRect, shape.rotation, shape.flipX, shape.flipY, cornerRadius, isBackgroundLoadError\n\t\t\t\t\t\t? [1, 0.2549, 0.2118, 0.25 * opacity]\n\t\t\t\t\t\t: [0, 0, 0, 0.25 * opacity]);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst position = rectCenter(shapeRect);\n\t\t\t\t\tisBackgroundLoadError && drawErrorIndicator(position);\n\t\t\t\t\tisLoadingBackgroundImage && drawLoadingIndicator(position);\n\t\t\t\t}\n\t\t\t} else if (shapeTexture) {\n\t\t\t\t// rect might have no width but we still want to remember texture for when it has a width in next draw cycle\n\t\t\t\tusedTextures.push(shapeTexture);\n\t\t\t}\n\t\t});\n\t};\n\n\t// loading indicator\n\tlet spinnerRotation = 0;\n\n\tconst errorPointsTLBR = [{ x: -5, y: -5 }, { x: 5, y: 5 }];\n\tconst errorPointsTRBL = [{ x: 5, y: -5 }, { x: -5, y: 5 }];\n\tconst spinnerPoints = ellipseToPolygon({ x: 0, y: 0 }, 10, 10, 0, false, false, 16);\n\tspinnerPoints.length = 9;\n\n\tconst drawLoadingIndicator = position => {\n\t\t// rotate based on date offset\n\t\tspinnerRotation = Date.now() / 50;\n\n\t\t// background fill\n\t\tcanvasGL.drawEllipse(position, 15, 15, 0, false, false, [0, 0, 0, 0.5]);\n\n\t\t// animate infinity spinner points positions\n\t\tconst points = vectorsRotate(spinnerPoints.map(p => ({ x: p.x + position.x, y: p.y + position.y })), spinnerRotation, position.x, position.y);\n\n\t\t// draw the points\n\t\tcanvasGL.drawPath(points, 0, false, false, 2, [1, 1, 1]);\n\t};\n\n\tconst drawErrorIndicator = position => {\n\t\t// background fill\n\t\tcanvasGL.drawEllipse(position, 13, 13, 0, false, false, [1, 0.2549, 0.2118, 0.75]);\n\n\t\tconst tlbr = errorPointsTLBR.map(p => ({ x: p.x + position.x, y: p.y + position.y }));\n\t\tconst trbl = errorPointsTRBL.map(p => ({ x: p.x + position.x, y: p.y + position.y }));\n\n\t\t// draw the points\n\t\tcanvasGL.drawPath(tlbr, 0, false, false, 3, [1, 1, 1]);\n\n\t\tcanvasGL.drawPath(trbl, 0, false, false, 3, [1, 1, 1]);\n\t};\n\n\tconst drawTransparencyGridLayer = (texture, rect, pos, size, color, opacity) => canvasGL.drawRect(\n\t\trect,\n\t\t0,\n\t\tfalse,\n\t\tfalse,\n\t\tVec4Empty,\n\t\tVec4Empty,\n\t\ttexture,\n\t\t// size\n\t\tsize,\n\t\t// pos\n\t\tpos,\n\t\t// repeat\n\t\ttrue,\n\t\tundefined,\n\t\t0,\n\t\tundefined,\n\t\topacity,\n\t\tundefined,\n\t\tundefined,\n\t\tcolor\n\t);\n\n\tconst drawTransparencyGrid = (rect, gridSize, colorEven, colorOdd, opacity) => {\n\t\tconst size = sizeCreate(gridSize, gridSize);\n\t\tconst texture = getImageTexture(TransparencyGrid, 'pixelated', 'repeat');\n\t\tconst posA = vectorCreate(-rect.x % gridSize, -rect.y % gridSize);\n\t\tconst posB = vectorCreate(posA.x + size.width * 0.5, posA.y);\n\t\tdrawTransparencyGridLayer(texture, rect, posA, size, colorEven, opacity);\n\t\tdrawTransparencyGridLayer(texture, rect, posB, size, colorOdd, opacity);\n\t};\n\n\t// redraws state\n\tlet redrawForce = false; // forces a redraw of dirty shapes\n\n\tlet isFirstDraw = true;\n\tlet wasFlipping = false;\n\n\t// textures\n\tconst usedManipulationTextures = [];\n\n\tconst usedAnnotationTextures = [];\n\tconst usedTextures = [];\n\tconst removeShapesAboveFrame = shape => !shape.aboveFrame;\n\tconst retainShapesAboveFrame = shape => shape.aboveFrame;\n\n\tconst redraw = () => {\n\t\t// reset array of textures used in this draw call\n\t\tusedTextures.length = 0;\n\n\t\t// get top image shortcut\n\t\tconst imagesTop = images[0];\n\n\t\t// allow dev to inject more shapes\n\t\tconst { manipulationShapes, manipulationShapesDirty, annotationShapes, annotationShapesDirty, interfaceShapes, decorationShapes, frameShapes, selectionShapes } = willRender({\n\t\t\t// top image state shortcut\n\t\t\topacity: imagesTop.opacity,\n\t\t\trotation: imagesTop.rotation,\n\t\t\tscale: imagesTop.scale,\n\t\t\t// active images\n\t\t\timages,\n\t\t\t// canvas size\n\t\t\tsize: sizeCreate(width, height),\n\t\t\t// canvas background\n\t\t\tbackgroundColor: [...$background],\n\t\t\t// preview selection rect\n\t\t\tselectionRect: $mask\n\t\t});\n\n\t\tconst canvasBackgroundColor = [...$background];\n\n\t\t// adjust mask a bit so bacckground color doesn't bleed through\n\t\tconst imagesMask = $mask;\n\n\t\tconst imagesMaskOpacity = clamp($maskOpacityStore, 0, 1);\n\t\tconst imagesOverlayColor = $imageOverlayColor;\n\t\tconst xFlipProgress = Math.abs(-1 + imagesTop.rotation.x / Math.PI * 2);\n\t\tconst yFlipProgress = Math.abs(-1 + imagesTop.rotation.y / Math.PI * 2);\n\t\tconst isFlipping = xFlipProgress < 0.99 || yFlipProgress < 0.99;\n\t\tconst imagesSize = { ...imagesTop.size };\n\t\tconst imagesBackgroundColor = imagesTop.backgroundColor;\n\t\tconst imagesBackgroundImage = imagesTop.backgroundImage;\n\t\tconst imagesBackgroundFilterMode = imagesTop.backgroundFilterMode;\n\n\t\t// no need to draw to blend framebuffer if no redactions\n\t\tconst hasManipulationShapes = manipulationShapes.length > 0;\n\n\t\t// no need to draw to markup framebuffer if no annotations\n\t\tconst hasAnnotations = annotationShapes.length > 0;\n\n\t\tconst hasAnnotationsAboveFrame = annotationShapes.filter(retainShapesAboveFrame).length > 0;\n\t\tconst hasDecorationsAboveFrame = decorationShapes.filter(retainShapesAboveFrame).length > 0;\n\n\t\t// if image has background color\n\t\tconst hasImageBackgroundColor = imagesBackgroundColor[3] > 0.0;\n\n\t\t// if the overlay is transparent so we can see the canvas\n\t\tconst hasTransparentOverlay = imagesMaskOpacity < 1.0;\n\n\t\t// should mask annotations outside of preview\n\t\tconst hasPreviewStencil = clipAnnotationsToImage ? maskMarkupOpacity >= 1 : false; //clipAnnotationsToImage || maskMarkupOpacity >= 1;\n\n\t\t// set canvas background color to image background color if is defined\n\t\tif (hasTransparentOverlay && hasImageBackgroundColor) {\n\t\t\tconst backR = canvasBackgroundColor[0];\n\t\t\tconst backG = canvasBackgroundColor[1];\n\t\t\tconst backB = canvasBackgroundColor[2];\n\t\t\tconst frontA = 1.0 - imagesMaskOpacity;\n\t\t\tconst frontR = imagesBackgroundColor[0] * frontA;\n\t\t\tconst frontG = imagesBackgroundColor[1] * frontA;\n\t\t\tconst frontB = imagesBackgroundColor[2] * frontA;\n\t\t\tconst fA = 1.0 - frontA;\n\t\t\tcanvasBackgroundColor[0] = frontR + backR * fA;\n\t\t\tcanvasBackgroundColor[1] = frontG + backG * fA;\n\t\t\tcanvasBackgroundColor[2] = frontB + backB * fA;\n\t\t\tcanvasBackgroundColor[3] = 1;\n\t\t}\n\n\t\t// make background transparent\n\t\tcanvasGL.setCanvasColor(isTransparent ? Vec4Empty : canvasBackgroundColor);\n\n\t\t// if has blend shapes draw blend shapes to framebuffer\n\t\tconst shouldDrawManipulations = hasManipulationShapes && (manipulationShapesDirty || redrawForce);\n\n\t\tif (shouldDrawManipulations) {\n\t\t\tcanvasGL.disableMask();\n\t\t\tcanvasGL.drawToImageBlendBuffer(imagesSize);\n\t\t\tusedManipulationTextures.length = 0;\n\t\t\tdrawShapes(manipulationShapes, usedManipulationTextures);\n\t\t} else if (!hasManipulationShapes) {\n\t\t\tusedManipulationTextures.length = 0;\n\t\t}\n\n\t\tusedTextures.push(...usedManipulationTextures);\n\n\t\t// prepare overlay frame buffer\n\t\tif (isFirstDraw) {\n\t\t\tcanvasGL.drawToImageOverlayBuffer(imagesSize, textPixelRatio);\n\t\t\tisFirstDraw = false;\n\t\t}\n\n\t\t// if has annotations draw annotation shapes to framebuffer\n\t\tconst shouldDrawAnnotations = hasAnnotations && (annotationShapesDirty || redrawForce);\n\n\t\tif (isFlipping) {\n\t\t\tif (shouldDrawAnnotations || !wasFlipping) {\n\t\t\t\tcanvasGL.disableMask();\n\t\t\t\tcanvasGL.drawToImageOverlayBuffer(imagesSize, textPixelRatio);\n\t\t\t\tusedAnnotationTextures.length = 0;\n\n\t\t\t\tconst filteredAnnotationShapes = hasAnnotationsAboveFrame\n\t\t\t\t? annotationShapes.filter(removeShapesAboveFrame)\n\t\t\t\t: annotationShapes;\n\n\t\t\t\tdrawShapes(filteredAnnotationShapes, usedAnnotationTextures);\n\t\t\t} else if (!hasAnnotations) {\n\t\t\t\tusedAnnotationTextures.length = 0;\n\t\t\t}\n\n\t\t\t// we use wasFlipping so we know when we should redraw the overlay framebuffer\n\t\t\twasFlipping = true;\n\t\t} else {\n\t\t\twasFlipping = false;\n\t\t}\n\n\t\t// switch to canvas drawing for other elements\n\t\tcanvasGL.drawToCanvas();\n\n\t\tcanvasGL.enableMask(imagesMask, imagesMaskOpacity);\n\n\t\tif (enableGrid && gridSize >= 1 && gridColors.length === 2 && gridOpacity) {\n\t\t\tdrawTransparencyGrid(imagesMask, gridSize, gridColors[0], gridColors[1], gridOpacity);\n\t\t}\n\n\t\t// draw a colored rectangle behind main preview image\n\t\tif (hasImageBackgroundColor) {\n\t\t\tcanvasGL.drawRect(imagesMask, 0, false, false, Vec4Empty, imagesBackgroundColor);\n\t\t}\n\n\t\tif (imagesBackgroundImage) {\n\t\t\t// hide background image outside of crop area\n\t\t\tcanvasGL.enableMask(imagesMask, 1.0);\n\n\t\t\tconst scalar = Math.max(maskRect.width / imagesBackgroundImage.width, maskRect.height / imagesBackgroundImage.height);\n\t\t\tconst bgWidth = imagesBackgroundImage.width * scalar;\n\t\t\tconst bgHeight = imagesBackgroundImage.height * scalar;\n\n\t\t\tconst rect = {\n\t\t\t\tx: maskRect.x + maskRect.width * 0.5,\n\t\t\t\ty: maskRect.y + maskRect.height * 0.5,\n\t\t\t\twidth: bgWidth,\n\t\t\t\theight: bgHeight\n\t\t\t};\n\n\t\t\tconst [image] = images;\n\n\t\t\tconst texture = drawImage({\n\t\t\t\t...image,\n\t\t\t\tvignette: imagesBackgroundFilterMode === 'image'\n\t\t\t\t? image.vignette\n\t\t\t\t: undefined,\n\t\t\t\tgamma: imagesBackgroundFilterMode === 'image'\n\t\t\t\t? image.gamma\n\t\t\t\t: undefined,\n\t\t\t\tconvolutionMatrix: imagesBackgroundFilterMode === 'image'\n\t\t\t\t? image.convolutionMatrix\n\t\t\t\t: undefined,\n\t\t\t\tcolorMatrix: imagesBackgroundFilterMode === 'image'\n\t\t\t\t? image.colorMatrix\n\t\t\t\t: undefined,\n\t\t\t\tsize: {\n\t\t\t\t\twidth: imagesBackgroundImage.width,\n\t\t\t\t\theight: imagesBackgroundImage.height\n\t\t\t\t},\n\t\t\t\ttranslation: {\n\t\t\t\t\tx: rect.x - width * 0.5,\n\t\t\t\t\ty: rect.y - height * 0.5\n\t\t\t\t},\n\t\t\t\tscale: scalar,\n\t\t\t\torigin: { x: 0, y: 0 },\n\t\t\t\trotation: { x: 0, y: 0, z: 0 },\n\t\t\t\tbackgroundColor: [0, 0, 0, 0],\n\t\t\t\tbackgroundImage: null,\n\t\t\t\tenableAntialiasing: false,\n\t\t\t\ttexture: getImageTexture(imagesBackgroundImage)\n\t\t\t});\n\n\t\t\tusedTextures.push(texture);\n\t\t\tcanvasGL.enableMask(imagesMask, imagesMaskOpacity);\n\t\t}\n\n\t\thasPreviewStencil && canvasGL.enablePreviewStencil();\n\n\t\t// draw main image(s)\n\t\tusedTextures.push(...[...images].reverse().map(image => {\n\t\t\treturn drawImage({\n\t\t\t\t...image,\n\t\t\t\t// the image texture\n\t\t\t\ttexture: getImageTexture(image.data),\n\t\t\t\t// enable drawing markup if defined\n\t\t\t\tenableOverlay: isFlipping && hasAnnotations,\n\t\t\t\t// enable drawing redactions if defined\n\t\t\t\tenableManipulation: hasManipulationShapes,\n\t\t\t\t// antialias image edges\n\t\t\t\tenableAntialiasing: true,\n\t\t\t\t// mask and overlay positions\n\t\t\t\tmask: imagesMask,\n\t\t\t\tmaskOpacity: imagesMaskOpacity,\n\t\t\t\t// overlay\n\t\t\t\toverlayColor: imagesOverlayColor\n\t\t\t});\n\t\t}));\n\n\t\t// TODO: move vignette here (draw with colorized circular gradient texture instead of in shader)\n\t\t// set markup mask\n\t\tcanvasGL.enableMask(imagesMask, maskMarkupOpacity);\n\n\t\t// draw shapes in UI instead of framebuffer\n\t\tif (!isFlipping) {\n\t\t\t// only draw in image area\n\t\t\thasPreviewStencil && canvasGL.applyPreviewStencil();\n\n\t\t\t// draw shapes\n\t\t\tcanvasGL.resetCanvasMatrix();\n\n\t\t\tcanvasGL.updateCanvasMatrix(imagesSize, imagesTop.origin, imagesTop.translation, imagesTop.scale, imagesTop.rotation);\n\n\t\t\t// draw shapes\n\t\t\tusedAnnotationTextures.length = 0;\n\n\t\t\tconst filteredAnnotationShapes = hasAnnotationsAboveFrame\n\t\t\t? annotationShapes.filter(removeShapesAboveFrame)\n\t\t\t: annotationShapes;\n\n\t\t\tdrawShapes(filteredAnnotationShapes, usedAnnotationTextures);\n\n\t\t\t// stencil no longer needed\n\t\t\thasPreviewStencil && canvasGL.disablePreviewStencil();\n\t\t}\n\n\t\tusedTextures.push(...usedAnnotationTextures);\n\n\t\t// draw decorations shapes relative to crop\n\t\tcanvasGL.resetCanvasMatrix();\n\n\t\tcanvasGL.enableMask(imagesMask, maskMarkupOpacity);\n\n\t\tdrawShapes(\n\t\t\thasDecorationsAboveFrame\n\t\t\t? decorationShapes.filter(removeShapesAboveFrame)\n\t\t\t: decorationShapes,\n\t\t\tusedTextures\n\t\t);\n\n\t\t// draw frames\n\t\tif (frameShapes.length) {\n\t\t\t// set frame mask\n\t\t\tcanvasGL.enableMask(imagesMask, 1);\n\n\t\t\tconst shapesInside = frameShapes.filter(shape => !shape.expandsCanvas);\n\t\t\tconst shapesOutside = frameShapes.filter(shape => shape.expandsCanvas);\n\n\t\t\tif (shapesInside.length) {\n\t\t\t\tdrawShapes(shapesInside, usedTextures);\n\t\t\t}\n\n\t\t\tif (shapesOutside.length) {\n\t\t\t\t// the half pixel helps mask the outside shapes at the correct position\n\t\t\t\tcanvasGL.enableMask(\n\t\t\t\t\t{\n\t\t\t\t\t\tx: imagesMask.x + 0.5,\n\t\t\t\t\t\ty: imagesMask.y + 0.5,\n\t\t\t\t\t\twidth: imagesMask.width - 1,\n\t\t\t\t\t\theight: imagesMask.height - 1\n\t\t\t\t\t},\n\t\t\t\t\t$maskFrameOpacityStore\n\t\t\t\t);\n\n\t\t\t\tdrawShapes(shapesOutside, usedTextures);\n\t\t\t}\n\t\t}\n\n\t\t// draw annotation shapes on top of frames\n\t\tif (hasAnnotationsAboveFrame) {\n\t\t\tcanvasGL.resetCanvasMatrix();\n\t\t\tcanvasGL.updateCanvasMatrix(imagesSize, imagesTop.origin, imagesTop.translation, imagesTop.scale, imagesTop.rotation);\n\t\t\tdrawShapes(annotationShapes.filter(retainShapesAboveFrame), usedTextures);\n\t\t\tcanvasGL.resetCanvasMatrix();\n\t\t}\n\n\t\t// draw decoration shapes on top of frames\n\t\tif (hasDecorationsAboveFrame) {\n\t\t\tcanvasGL.resetCanvasMatrix();\n\t\t\tdrawShapes(decorationShapes.filter(retainShapesAboveFrame), usedTextures);\n\t\t\tcanvasGL.resetCanvasMatrix();\n\t\t}\n\n\t\t// draw selection (but not when flipping)\n\t\tif (selectionColor && selectionShapes.length && !isFlipping) {\n\t\t\t// draw shapes\n\t\t\tcanvasGL.resetCanvasMatrix();\n\n\t\t\tcanvasGL.updateCanvasMatrix(imagesSize, imagesTop.origin, imagesTop.translation, imagesTop.scale, imagesTop.rotation);\n\n\t\t\t// selection color\n\t\t\tconst color = [...selectionColor];\n\n\t\t\tcolor[3] = 0.5;\n\n\t\t\t// convert selections to shapes\n\t\t\tconst selectionRectShapes = [\n\t\t\t\t{\n\t\t\t\t\tid: 'selection',\n\t\t\t\t\tcolor,\n\t\t\t\t\tactions: [...selectionShapes]\n\t\t\t\t}\n\t\t\t].map(selectionGroup => mapSelectionToShape(selectionGroup, imagesSize));\n\n\t\t\t// draw selections\n\t\t\tdrawShapes(selectionRectShapes, usedTextures);\n\n\t\t\t// done\n\t\t\tcanvasGL.resetCanvasMatrix();\n\t\t}\n\n\t\t// crop mask not used for interface\n\t\tcanvasGL.disableMask();\n\n\t\t// draw custom interface shapes\n\t\tdrawShapes(interfaceShapes, usedTextures);\n\n\t\t// draw preview images (filters and video frame previews)\n\t\tinterfaceImages.forEach(image => {\n\t\t\tcanvasGL.enableMask(image.mask, image.maskOpacity);\n\n\t\t\t// background image\n\t\t\tif (imagesBackgroundImage) {\n\t\t\t\tconst texture = drawImage({\n\t\t\t\t\t...image,\n\t\t\t\t\tvignette: imagesBackgroundFilterMode === 'image'\n\t\t\t\t\t? image.vignette\n\t\t\t\t\t: undefined,\n\t\t\t\t\tgamma: imagesBackgroundFilterMode === 'image'\n\t\t\t\t\t? image.gamma\n\t\t\t\t\t: undefined,\n\t\t\t\t\tconvolutionMatrix: imagesBackgroundFilterMode === 'image'\n\t\t\t\t\t? image.convolutionMatrix\n\t\t\t\t\t: undefined,\n\t\t\t\t\tcolorMatrix: imagesBackgroundFilterMode === 'image'\n\t\t\t\t\t? image.colorMatrix\n\t\t\t\t\t: undefined,\n\t\t\t\t\ttexture: getImageTexture(imagesBackgroundImage),\n\t\t\t\t\t// antialias edges\n\t\t\t\t\tenableAntialiasing: false,\n\t\t\t\t\t// update translation to apply `offset` from top left\n\t\t\t\t\ttranslation: {\n\t\t\t\t\t\tx: image.translation.x + image.offset.x - width * 0.5,\n\t\t\t\t\t\ty: image.translation.y + image.offset.y - height * 0.5\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tusedTextures.push(texture);\n\t\t\t} else // background fill\n\t\t\tif (image.backgroundColor) {\n\t\t\t\tcanvasGL.drawRect(image.mask, 0, false, false, image.maskCornerRadius, image.backgroundColor, undefined, undefined, undefined, undefined, undefined, undefined, undefined, image.opacity, image.maskFeather);\n\t\t\t}\n\n\t\t\t// draw image\n\t\t\tconst texture = drawImage({\n\t\t\t\t...image,\n\t\t\t\ttexture: getImageTexture(image.data),\n\t\t\t\t// antialias edges\n\t\t\t\tenableAntialiasing: false,\n\t\t\t\t// update translation to apply `offset` from top left\n\t\t\t\ttranslation: {\n\t\t\t\t\tx: image.translation.x + image.offset.x - width * 0.5,\n\t\t\t\t\ty: image.translation.y + image.offset.y - height * 0.5\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tusedTextures.push(texture);\n\t\t});\n\n\t\tcanvasGL.disableMask();\n\n\t\t// determine which textures can be dropped\n\t\treleaseUnusedTextures(usedTextures);\n\n\t\t// done rendering\n\t\tdidRender();\n\n\t\t// redraw force flag\n\t\tredrawForce = false;\n\t};\n\n\t//#endregion\n\t//#region set up\n\t// throttled redrawer\n\tlet throttledLastDrawTime = 0;\n\n\tlet throttledFinalRedrawTimeout;\n\n\tconst redrawThrottled = () => {\n\t\tclearTimeout(throttledFinalRedrawTimeout);\n\t\tconst now = Date.now();\n\t\tconst dist = now - throttledLastDrawTime;\n\n\t\tif (dist < throttledMinRedrawDist) {\n\t\t\tthrottledFinalRedrawTimeout = setTimeout(redrawThrottled, throttledMinRedrawDist);\n\t\t\treturn;\n\t\t}\n\n\t\tthrottledLastDrawTime = now;\n\t\tredraw();\n\t};\n\n\t// returns the render function to use for this browser context\n\tconst selectFittingRenderFunction = () => isSoftwareRendering() ? redrawThrottled : redraw;\n\n\t// after DOM has been altered, redraw to canvas\n\tafterUpdate(() => drawUpdate());\n\n\t// hook up canvas to WebGL drawer\n\tonMount(() => $$invalidate(32, canvasGL = createWebGLCanvas(canvas, {\n\t\talpha: isTransparent,\n\t\tonContextExhausted: () => {\n\t\t\tonerror('EXHAUSTED');\n\t\t}\n\t})));\n\n\t// clean up canvas\n\tonDestroy(() => {\n\t\t// if canvas wasn't created we don't need to release it\n\t\tif (!canvasGL) return;\n\n\t\t// clear canvas cache\n\t\tcanvasCache.forEach(({ canvas }) => releaseCanvas(canvas));\n\n\t\tcanvasCache.clear();\n\n\t\t// done drawing\n\t\tcanvasGL.release();\n\n\t\t// remove reference\n\t\t$$invalidate(32, canvasGL = undefined);\n\n\t\t$$invalidate(0, canvas = undefined);\n\t});\n\n\tfunction canvas_1_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tcanvas = $$value;\n\t\t\t$$invalidate(0, canvas);\n\t\t});\n\t}\n\n\tconst measure_handler = e => {\n\t\t$$invalidate(1, width = e.detail.width);\n\t\t$$invalidate(2, height = e.detail.height);\n\t\tdispatch('measure', { width, height });\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('isAnimated' in $$props) $$invalidate(9, isAnimated = $$props.isAnimated);\n\t\tif ('isTransparent' in $$props) $$invalidate(10, isTransparent = $$props.isTransparent);\n\t\tif ('maskRect' in $$props) $$invalidate(11, maskRect = $$props.maskRect);\n\t\tif ('maskOpacity' in $$props) $$invalidate(12, maskOpacity = $$props.maskOpacity);\n\t\tif ('maskFrameOpacity' in $$props) $$invalidate(13, maskFrameOpacity = $$props.maskFrameOpacity);\n\t\tif ('maskMarkupOpacity' in $$props) $$invalidate(14, maskMarkupOpacity = $$props.maskMarkupOpacity);\n\t\tif ('clipAnnotationsToImage' in $$props) $$invalidate(15, clipAnnotationsToImage = $$props.clipAnnotationsToImage);\n\t\tif ('pixelRatio' in $$props) $$invalidate(16, pixelRatio = $$props.pixelRatio);\n\t\tif ('textPixelRatio' in $$props) $$invalidate(17, textPixelRatio = $$props.textPixelRatio);\n\t\tif ('backgroundColor' in $$props) $$invalidate(18, backgroundColor = $$props.backgroundColor);\n\t\tif ('willRender' in $$props) $$invalidate(19, willRender = $$props.willRender);\n\t\tif ('didRender' in $$props) $$invalidate(20, didRender = $$props.didRender);\n\t\tif ('willRequest' in $$props) $$invalidate(21, willRequest = $$props.willRequest);\n\t\tif ('csp' in $$props) $$invalidate(22, csp = $$props.csp);\n\t\tif ('loadImageData' in $$props) $$invalidate(23, loadImageData = $$props.loadImageData);\n\t\tif ('enableGrid' in $$props) $$invalidate(24, enableGrid = $$props.enableGrid);\n\t\tif ('gridColors' in $$props) $$invalidate(25, gridColors = $$props.gridColors);\n\t\tif ('gridSize' in $$props) $$invalidate(26, gridSize = $$props.gridSize);\n\t\tif ('gridOpacity' in $$props) $$invalidate(27, gridOpacity = $$props.gridOpacity);\n\t\tif ('images' in $$props) $$invalidate(28, images = $$props.images);\n\t\tif ('interfaceImages' in $$props) $$invalidate(29, interfaceImages = $$props.interfaceImages);\n\t\tif ('selectionColor' in $$props) $$invalidate(30, selectionColor = $$props.selectionColor);\n\t\tif ('onerror' in $$props) $$invalidate(31, onerror = $$props.onerror);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*canvas*/ 1) {\n\t\t\tif (canvas) {\n\t\t\t\tconst propertyValue = getComputedStyle(canvas).getPropertyValue('--color-transition-duration');\n\t\t\t\t$$invalidate(33, backgroundColorAnimationDuration = durationToMilliseconds(propertyValue));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*backgroundColor, isAnimated*/ 262656 | $$self.$$.dirty[1] & /*backgroundColorAnimationDuration*/ 4) {\n\t\t\tbackgroundColor && background.set(backgroundColor, {\n\t\t\t\tduration: isAnimated ? backgroundColorAnimationDuration : 0\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*maskOpacity*/ 4096) {\n\t\t\tupdateSpring(maskOpacityStore, isNumber(maskOpacity) ? maskOpacity : 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*maskFrameOpacity*/ 8192) {\n\t\t\tupdateSpring(maskFrameOpacityStore, isNumber(maskFrameOpacity) ? maskFrameOpacity : 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*maskRect*/ 2048) {\n\t\t\tmaskRect && mask.set(maskRect);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$background, $maskOpacityStore*/ 96) {\n\t\t\t$background && imageOverlayColor.set([\n\t\t\t\t$background[0],\n\t\t\t\t$background[1],\n\t\t\t\t$background[2],\n\t\t\t\tclamp($maskOpacityStore, 0, 1)\n\t\t\t]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*width, height, images*/ 268435462 | $$self.$$.dirty[1] & /*canvasGL*/ 2) {\n\t\t\t// can draw view\n\t\t\t$$invalidate(35, canDraw = !!(canvasGL && width && height && images.length));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*width, height, pixelRatio*/ 65542 | $$self.$$.dirty[1] & /*canvasGL*/ 2) {\n\t\t\t// observe width and height changes and resize the canvas proportionally\n\t\t\tif (width && height && canvasGL) {\n\t\t\t\t// need to reset last draw date so throttled redraw always runs redraw logic after resize\n\t\t\t\tthrottledLastDrawTime = 0;\n\n\t\t\t\t// resize canvas\n\t\t\t\tcanvasGL.resize(width, height, pixelRatio);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*canDraw*/ 16) {\n\t\t\t// switch to draw method when can draw\n\t\t\t$$invalidate(34, drawUpdate = canDraw ? selectFittingRenderFunction() : noop$1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*canDraw, drawUpdate*/ 24) {\n\t\t\t// if can draw state is updated and we have a draw update function, time to redraw\n\t\t\tcanDraw && drawUpdate && drawUpdate();\n\t\t}\n\t};\n\n\treturn [\n\t\tcanvas,\n\t\twidth,\n\t\theight,\n\t\tdispatch,\n\t\tbackground,\n\t\tmaskOpacityStore,\n\t\tmaskFrameOpacityStore,\n\t\tmask,\n\t\timageOverlayColor,\n\t\tisAnimated,\n\t\tisTransparent,\n\t\tmaskRect,\n\t\tmaskOpacity,\n\t\tmaskFrameOpacity,\n\t\tmaskMarkupOpacity,\n\t\tclipAnnotationsToImage,\n\t\tpixelRatio,\n\t\ttextPixelRatio,\n\t\tbackgroundColor,\n\t\twillRender,\n\t\tdidRender,\n\t\twillRequest,\n\t\tcsp,\n\t\tloadImageData,\n\t\tenableGrid,\n\t\tgridColors,\n\t\tgridSize,\n\t\tgridOpacity,\n\t\timages,\n\t\tinterfaceImages,\n\t\tselectionColor,\n\t\tonerror,\n\t\tcanvasGL,\n\t\tbackgroundColorAnimationDuration,\n\t\tdrawUpdate,\n\t\tcanDraw,\n\t\t$maskOpacityStore,\n\t\t$background,\n\t\tcanvas_1_binding,\n\t\tmeasure_handler\n\t];\n}\n\nclass Canvas extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$U,\n\t\t\tcreate_fragment$T,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tisAnimated: 9,\n\t\t\t\tisTransparent: 10,\n\t\t\t\tmaskRect: 11,\n\t\t\t\tmaskOpacity: 12,\n\t\t\t\tmaskFrameOpacity: 13,\n\t\t\t\tmaskMarkupOpacity: 14,\n\t\t\t\tclipAnnotationsToImage: 15,\n\t\t\t\tpixelRatio: 16,\n\t\t\t\ttextPixelRatio: 17,\n\t\t\t\tbackgroundColor: 18,\n\t\t\t\twillRender: 19,\n\t\t\t\tdidRender: 20,\n\t\t\t\twillRequest: 21,\n\t\t\t\tcsp: 22,\n\t\t\t\tloadImageData: 23,\n\t\t\t\tenableGrid: 24,\n\t\t\t\tgridColors: 25,\n\t\t\t\tgridSize: 26,\n\t\t\t\tgridOpacity: 27,\n\t\t\t\timages: 28,\n\t\t\t\tinterfaceImages: 29,\n\t\t\t\tselectionColor: 30,\n\t\t\t\tonerror: 31\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1]\n\t\t);\n\t}\n}\n\nvar arrayJoin = (arr, filter = Boolean, str = ' ') => arr.filter(filter).join(str);\n\n/* src/core/ui/components/TabList.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context$8(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[17] = list[i];\n\treturn child_ctx;\n}\n\nconst get_default_slot_changes$1 = dirty => ({ tab: dirty & /*tabNodes*/ 4 });\nconst get_default_slot_context$1 = ctx => ({ tab: /*tab*/ ctx[17] });\n\n// (59:0) {#if shouldRender}\nfunction create_if_block$n(ctx) {\n\tlet div;\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet div_class_value;\n\tlet current;\n\tlet each_value = ensure_array_like(/*tabNodes*/ ctx[2]);\n\tconst get_key = ctx => /*tab*/ ctx[17].id;\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$8(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$8(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tattr(div, \"class\", div_class_value = arrayJoin(['PinturaTabList', /*klass*/ ctx[0]]));\n\t\t\tattr(div, \"role\", \"tablist\");\n\t\t\tattr(div, \"data-layout\", /*layout*/ ctx[1]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(div, null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/*div_binding*/ ctx[14](div);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*tabNodes, handleKeyTab, handleClickTab, $$scope*/ 1124) {\n\t\t\t\teach_value = ensure_array_like(/*tabNodes*/ ctx[2]);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block$8, null, get_each_context$8);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*klass*/ 1 && div_class_value !== (div_class_value = arrayJoin(['PinturaTabList', /*klass*/ ctx[0]]))) {\n\t\t\t\tattr(div, \"class\", div_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*layout*/ 2) {\n\t\t\t\tattr(div, \"data-layout\", /*layout*/ ctx[1]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d();\n\t\t\t}\n\n\t\t\t/*div_binding*/ ctx[14](null);\n\t\t}\n\t};\n}\n\n// (66:8) {#each tabNodes as tab (tab.id)}\nfunction create_each_block$8(key_1, ctx) {\n\tlet button;\n\tlet t;\n\tlet button_title_value;\n\tlet button_id_value;\n\tlet button_aria_controls_value;\n\tlet button_aria_selected_value;\n\tlet button_disabled_value;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[11].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[10], get_default_slot_context$1);\n\n\tfunction keydown_handler(...args) {\n\t\treturn /*keydown_handler*/ ctx[12](/*tab*/ ctx[17], ...args);\n\t}\n\n\tfunction click_handler(...args) {\n\t\treturn /*click_handler*/ ctx[13](/*tab*/ ctx[17], ...args);\n\t}\n\n\treturn {\n\t\tkey: key_1,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tbutton = element(\"button\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tt = space();\n\t\t\tattr(button, \"role\", \"tab\");\n\t\t\tattr(button, \"title\", button_title_value = /*tab*/ ctx[17].title);\n\t\t\tattr(button, \"id\", button_id_value = /*tab*/ ctx[17].tabId);\n\t\t\tattr(button, \"aria-controls\", button_aria_controls_value = /*tab*/ ctx[17].href.substring(1));\n\t\t\tattr(button, \"aria-selected\", button_aria_selected_value = /*tab*/ ctx[17].selected);\n\t\t\tbutton.disabled = button_disabled_value = /*tab*/ ctx[17].disabled;\n\t\t\tattr(button, \"type\", \"button\");\n\t\t\tthis.first = button;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, button, anchor);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(button, null);\n\t\t\t}\n\n\t\t\tappend(button, t);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(button, \"keydown\", keydown_handler),\n\t\t\t\t\tlisten(button, \"click\", click_handler)\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope, tabNodes*/ 1028)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[10],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[10])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[10], dirty, get_default_slot_changes$1),\n\t\t\t\t\t\tget_default_slot_context$1\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*tabNodes*/ 4 && button_title_value !== (button_title_value = /*tab*/ ctx[17].title)) {\n\t\t\t\tattr(button, \"title\", button_title_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*tabNodes*/ 4 && button_id_value !== (button_id_value = /*tab*/ ctx[17].tabId)) {\n\t\t\t\tattr(button, \"id\", button_id_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*tabNodes*/ 4 && button_aria_controls_value !== (button_aria_controls_value = /*tab*/ ctx[17].href.substring(1))) {\n\t\t\t\tattr(button, \"aria-controls\", button_aria_controls_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*tabNodes*/ 4 && button_aria_selected_value !== (button_aria_selected_value = /*tab*/ ctx[17].selected)) {\n\t\t\t\tattr(button, \"aria-selected\", button_aria_selected_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*tabNodes*/ 4 && button_disabled_value !== (button_disabled_value = /*tab*/ ctx[17].disabled)) {\n\t\t\t\tbutton.disabled = button_disabled_value;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(button);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$S(ctx) {\n\tlet if_block_anchor;\n\tlet current;\n\tlet if_block = /*shouldRender*/ ctx[4] && create_if_block$n(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block) if_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block) if_block.m(target, anchor);\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (/*shouldRender*/ ctx[4]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*shouldRender*/ 16) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$n(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance$T($$self, $$props, $$invalidate) {\n\tlet tabNodes;\n\tlet shouldRender;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet root;\n\tlet { class: klass = undefined } = $$props;\n\tlet { name } = $$props;\n\tlet { selected } = $$props;\n\tlet { tabs = [] } = $$props;\n\tlet { layout = undefined } = $$props;\n\tconst dispatch = createEventDispatcher();\n\n\tconst focusTab = index => {\n\t\tconst tab = root.querySelectorAll('[role=\"tab\"] button')[index];\n\t\tif (!tab) return;\n\t\ttab.focus();\n\t};\n\n\tconst handleClickTab = (e, id) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\t// Safari doesn't focus buttons when they're clicked (Firefox and Chrome do), this fixes that for tabs\n\t\tif (isSafari()) {\n\t\t\te.target.focus();\n\t\t}\n\n\t\tdispatch('select', id);\n\t};\n\n\tconst handleKeyTab = ({ key }, id) => {\n\t\tif (!(/arrow/i).test(key)) return;\n\t\tconst index = tabs.findIndex(tab => tab.id === id);\n\n\t\t// next\n\t\tif ((/right|down/i).test(key)) return focusTab(index < tabs.length - 1 ? index + 1 : 0);\n\n\t\t// prev\n\t\tif ((/left|up/i).test(key)) return focusTab(index > 0 ? index - 1 : tabs.length - 1);\n\t};\n\n\tconst keydown_handler = (tab, e) => handleKeyTab(e, tab.id);\n\tconst click_handler = (tab, e) => handleClickTab(e, tab.id);\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\troot = $$value;\n\t\t\t$$invalidate(3, root);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(0, klass = $$props.class);\n\t\tif ('name' in $$props) $$invalidate(7, name = $$props.name);\n\t\tif ('selected' in $$props) $$invalidate(8, selected = $$props.selected);\n\t\tif ('tabs' in $$props) $$invalidate(9, tabs = $$props.tabs);\n\t\tif ('layout' in $$props) $$invalidate(1, layout = $$props.layout);\n\t\tif ('$$scope' in $$props) $$invalidate(10, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*tabs, selected, name*/ 896) {\n\t\t\t$$invalidate(2, tabNodes = tabs.map(tab => {\n\t\t\t\tconst isActive = tab.id === selected;\n\n\t\t\t\treturn {\n\t\t\t\t\t...tab,\n\t\t\t\t\ttabId: `tab-${name}-${tab.id}`,\n\t\t\t\t\thref: `#panel-${name}-${tab.id}`,\n\t\t\t\t\tselected: isActive\n\t\t\t\t};\n\t\t\t}));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*tabNodes*/ 4) {\n\t\t\t$$invalidate(4, shouldRender = tabNodes.length > 1);\n\t\t}\n\t};\n\n\treturn [\n\t\tklass,\n\t\tlayout,\n\t\ttabNodes,\n\t\troot,\n\t\tshouldRender,\n\t\thandleClickTab,\n\t\thandleKeyTab,\n\t\tname,\n\t\tselected,\n\t\ttabs,\n\t\t$$scope,\n\t\tslots,\n\t\tkeydown_handler,\n\t\tclick_handler,\n\t\tdiv_binding\n\t];\n}\n\nclass TabList extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$T, create_fragment$S, safe_not_equal, {\n\t\t\tclass: 0,\n\t\t\tname: 7,\n\t\t\tselected: 8,\n\t\t\ttabs: 9,\n\t\t\tlayout: 1\n\t\t});\n\t}\n}\n\nvar styleable = (element, styles) => {\n    if (!styles)\n        return;\n    const update = (styles) => {\n        setElementStyles(element, styles);\n    };\n    update(styles);\n    return {\n        update,\n    };\n};\n\n/* src/core/ui/components/TabPanels.svelte generated by Svelte v4.2.20 */\nconst get_default_slot_changes_1 = dirty => ({ panel: dirty & /*panelNodes*/ 16 });\n\nconst get_default_slot_context_1 = ctx => ({\n\tpanel: /*panelNodes*/ ctx[4][0].id,\n\tpanelIsActive: true\n});\n\nfunction get_each_context$7(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[14] = list[i].id;\n\tchild_ctx[15] = list[i].shouldDraw;\n\tchild_ctx[16] = list[i].panelId;\n\tchild_ctx[17] = list[i].labelledBy;\n\tchild_ctx[18] = list[i].isActive;\n\tchild_ctx[19] = list[i].hidden;\n\tchild_ctx[3] = list[i].visible;\n\treturn child_ctx;\n}\n\nconst get_default_slot_changes = dirty => ({\n\tpanel: dirty & /*panelNodes*/ 16,\n\tpanelIsActive: dirty & /*panelNodes*/ 16\n});\n\nconst get_default_slot_context = ctx => ({\n\tpanel: /*id*/ ctx[14],\n\tpanelIsActive: /*isActive*/ ctx[18]\n});\n\n// (63:0) {:else}\nfunction create_else_block$b(ctx) {\n\tlet div1;\n\tlet div0;\n\tlet div0_class_value;\n\tlet styleable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[11].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[10], get_default_slot_context_1);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv1 = element(\"div\");\n\t\t\tdiv0 = element(\"div\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tattr(div0, \"class\", div0_class_value = arrayJoin([/*panelClass*/ ctx[1]]));\n\t\t\tattr(div1, \"class\", /*klass*/ ctx[0]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div1, anchor);\n\t\t\tappend(div1, div0);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(div0, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\taction_destroyer(styleable_action = styleable.call(null, div1, /*style*/ ctx[2])),\n\t\t\t\t\tlisten(div1, \"measure\", /*measure_handler_1*/ ctx[13]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div1))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope, panelNodes*/ 1040)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[10],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[10])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[10], dirty, get_default_slot_changes_1),\n\t\t\t\t\t\tget_default_slot_context_1\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*panelClass*/ 2 && div0_class_value !== (div0_class_value = arrayJoin([/*panelClass*/ ctx[1]]))) {\n\t\t\t\tattr(div0, \"class\", div0_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*klass*/ 1) {\n\t\t\t\tattr(div1, \"class\", /*klass*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty & /*style*/ 4) styleable_action.update.call(null, /*style*/ ctx[2]);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div1);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (42:0) {#if shouldRender}\nfunction create_if_block$m(ctx) {\n\tlet div;\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet div_class_value;\n\tlet styleable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tlet each_value = ensure_array_like(/*panelNodes*/ ctx[4]);\n\tconst get_key = ctx => /*id*/ ctx[14];\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$7(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$7(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tattr(div, \"class\", div_class_value = arrayJoin(['PinturaTabPanels', /*klass*/ ctx[0]]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(div, null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\taction_destroyer(styleable_action = styleable.call(null, div, /*style*/ ctx[2])),\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler*/ ctx[12]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div, { observePosition: true }))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*panelNodes, panelClass, $$scope*/ 1042) {\n\t\t\t\teach_value = ensure_array_like(/*panelNodes*/ ctx[4]);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block$7, null, get_each_context$7);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*klass*/ 1 && div_class_value !== (div_class_value = arrayJoin(['PinturaTabPanels', /*klass*/ ctx[0]]))) {\n\t\t\t\tattr(div, \"class\", div_class_value);\n\t\t\t}\n\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty & /*style*/ 4) styleable_action.update.call(null, /*style*/ ctx[2]);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d();\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (59:16) {#if shouldDraw}\nfunction create_if_block_1$h(ctx) {\n\tlet current;\n\tconst default_slot_template = /*#slots*/ ctx[11].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[10], get_default_slot_context);\n\n\treturn {\n\t\tc() {\n\t\t\tif (default_slot) default_slot.c();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(target, anchor);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope, panelNodes*/ 1040)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[10],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[10])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[10], dirty, get_default_slot_changes),\n\t\t\t\t\t\tget_default_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t}\n\t};\n}\n\n// (50:8) {#each panelNodes as { id, shouldDraw, panelId, labelledBy, isActive, hidden, visible }\nfunction create_each_block$7(key_1, ctx) {\n\tlet div;\n\tlet t;\n\tlet div_id_value;\n\tlet div_class_value;\n\tlet div_aria_hidden_value;\n\tlet div_aria_labelledby_value;\n\tlet div_data_inert_value;\n\tlet current;\n\tlet if_block = /*shouldDraw*/ ctx[15] && create_if_block_1$h(ctx);\n\n\treturn {\n\t\tkey: key_1,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tt = space();\n\t\t\tattr(div, \"id\", div_id_value = /*panelId*/ ctx[16]);\n\t\t\tattr(div, \"class\", div_class_value = arrayJoin(['PinturaTabPanel', /*panelClass*/ ctx[1]]));\n\t\t\tattr(div, \"aria-hidden\", div_aria_hidden_value = /*hidden*/ ctx[19]);\n\t\t\tattr(div, \"aria-labelledby\", div_aria_labelledby_value = /*labelledBy*/ ctx[17]);\n\t\t\tattr(div, \"data-inert\", div_data_inert_value = !/*visible*/ ctx[3]);\n\t\t\tattr(div, \"role\", \"tabpanel\");\n\t\t\tthis.first = div;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\tappend(div, t);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (/*shouldDraw*/ ctx[15]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*panelNodes*/ 16) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_1$h(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, t);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*panelNodes*/ 16 && div_id_value !== (div_id_value = /*panelId*/ ctx[16])) {\n\t\t\t\tattr(div, \"id\", div_id_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*panelClass*/ 2 && div_class_value !== (div_class_value = arrayJoin(['PinturaTabPanel', /*panelClass*/ ctx[1]]))) {\n\t\t\t\tattr(div, \"class\", div_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*panelNodes*/ 16 && div_aria_hidden_value !== (div_aria_hidden_value = /*hidden*/ ctx[19])) {\n\t\t\t\tattr(div, \"aria-hidden\", div_aria_hidden_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*panelNodes*/ 16 && div_aria_labelledby_value !== (div_aria_labelledby_value = /*labelledBy*/ ctx[17])) {\n\t\t\t\tattr(div, \"aria-labelledby\", div_aria_labelledby_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*panelNodes*/ 16 && div_data_inert_value !== (div_data_inert_value = !/*visible*/ ctx[3])) {\n\t\t\t\tattr(div, \"data-inert\", div_data_inert_value);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t}\n\t};\n}\n\nfunction create_fragment$R(ctx) {\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet if_block_anchor;\n\tlet current;\n\tconst if_block_creators = [create_if_block$m, create_else_block$b];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*shouldRender*/ ctx[5]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance$S($$self, $$props, $$invalidate) {\n\tlet panelNodes;\n\tlet shouldRender;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\tlet { name } = $$props;\n\tlet { selected } = $$props;\n\tlet { panelClass = undefined } = $$props;\n\tlet { panels = [] } = $$props;\n\tlet { visible = undefined } = $$props;\n\tlet { style = undefined } = $$props;\n\tconst drawCache = {};\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\tfunction measure_handler_1(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(0, klass = $$props.class);\n\t\tif ('name' in $$props) $$invalidate(6, name = $$props.name);\n\t\tif ('selected' in $$props) $$invalidate(7, selected = $$props.selected);\n\t\tif ('panelClass' in $$props) $$invalidate(1, panelClass = $$props.panelClass);\n\t\tif ('panels' in $$props) $$invalidate(8, panels = $$props.panels);\n\t\tif ('visible' in $$props) $$invalidate(3, visible = $$props.visible);\n\t\tif ('style' in $$props) $$invalidate(2, style = $$props.style);\n\t\tif ('$$scope' in $$props) $$invalidate(10, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*panels, selected, visible, name, drawCache*/ 968) {\n\t\t\t$$invalidate(4, panelNodes = panels.map(id => {\n\t\t\t\tconst isActive = id === selected;\n\n\t\t\t\t// remember that this tab was active so we keep it in DOM even when it's inactive, prevents constructing the node tree on re-render\n\t\t\t\tif (isActive) $$invalidate(9, drawCache[id] = true, drawCache);\n\n\t\t\t\tconst isVisible = visible ? visible.indexOf(id) !== -1 : isActive;\n\n\t\t\t\treturn {\n\t\t\t\t\tid,\n\t\t\t\t\tpanelId: `panel-${name}-${id}`,\n\t\t\t\t\tlabelledBy: `tab-${name}-${id}`,\n\t\t\t\t\tisActive,\n\t\t\t\t\thidden: !isActive,\n\t\t\t\t\tvisible: isVisible,\n\t\t\t\t\tshouldDraw: isActive || drawCache[id]\n\t\t\t\t}; // remove tabindex for now as every tab has elements to focus\n\t\t\t\t// tabindex: isActive ? 0 : -1,\n\t\t\t}));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*panelNodes*/ 16) {\n\t\t\t$$invalidate(5, shouldRender = panelNodes.length > 1);\n\t\t}\n\t};\n\n\treturn [\n\t\tklass,\n\t\tpanelClass,\n\t\tstyle,\n\t\tvisible,\n\t\tpanelNodes,\n\t\tshouldRender,\n\t\tname,\n\t\tselected,\n\t\tpanels,\n\t\tdrawCache,\n\t\t$$scope,\n\t\tslots,\n\t\tmeasure_handler,\n\t\tmeasure_handler_1\n\t];\n}\n\nclass TabPanels extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$S, create_fragment$R, safe_not_equal, {\n\t\t\tclass: 0,\n\t\t\tname: 6,\n\t\t\tselected: 7,\n\t\t\tpanelClass: 1,\n\t\t\tpanels: 8,\n\t\t\tvisible: 3,\n\t\t\tstyle: 2\n\t\t});\n\t}\n}\n\nvar getComponentExportedProps = (Component) => {\n    const descriptors = Object.getOwnPropertyDescriptors(Component.prototype);\n    return Object.keys(descriptors).filter((key) => !!descriptors[key]['get']);\n};\n\n/* src/core/ui/components/UtilPanel.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block$l(ctx) {\n\tlet switch_instance;\n\tlet updating_name;\n\tlet switch_instance_anchor;\n\tlet current;\n\tconst switch_instance_spread_levels = [/*componentProps*/ ctx[5], { locale: /*locale*/ ctx[1] }];\n\n\tfunction switch_instance_name_binding(value) {\n\t\t/*switch_instance_name_binding*/ ctx[22](value);\n\t}\n\n\tvar switch_value = /*ComponentView*/ ctx[10];\n\n\tfunction switch_props(ctx, dirty) {\n\t\tlet switch_instance_props = {};\n\n\t\tfor (let i = 0; i < switch_instance_spread_levels.length; i += 1) {\n\t\t\tswitch_instance_props = assign(switch_instance_props, switch_instance_spread_levels[i]);\n\t\t}\n\n\t\tif (dirty !== undefined && dirty[0] & /*componentProps, locale*/ 34) {\n\t\t\tswitch_instance_props = assign(switch_instance_props, get_spread_update(switch_instance_spread_levels, [\n\t\t\t\tdirty[0] & /*componentProps*/ 32 && get_spread_object(/*componentProps*/ ctx[5]),\n\t\t\t\tdirty[0] & /*locale*/ 2 && { locale: /*locale*/ ctx[1] }\n\t\t\t]));\n\t\t}\n\n\t\tif (/*panelName*/ ctx[3] !== void 0) {\n\t\t\tswitch_instance_props.name = /*panelName*/ ctx[3];\n\t\t}\n\n\t\treturn { props: switch_instance_props };\n\t}\n\n\tif (switch_value) {\n\t\tswitch_instance = construct_svelte_component(switch_value, switch_props(ctx));\n\t\tbinding_callbacks.push(() => bind(switch_instance, 'name', switch_instance_name_binding));\n\t\t/*switch_instance_binding*/ ctx[23](switch_instance);\n\t\tswitch_instance.$on(\"measure\", /*handleMeasure*/ ctx[11]);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tif (switch_instance) create_component(switch_instance.$$.fragment);\n\t\t\tswitch_instance_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (switch_instance) mount_component(switch_instance, target, anchor);\n\t\t\tinsert(target, switch_instance_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (switch_value !== (switch_value = /*ComponentView*/ ctx[10])) {\n\t\t\t\tif (switch_instance) {\n\t\t\t\t\tgroup_outros();\n\t\t\t\t\tconst old_component = switch_instance;\n\n\t\t\t\t\ttransition_out(old_component.$$.fragment, 1, 0, () => {\n\t\t\t\t\t\tdestroy_component(old_component, 1);\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (switch_value) {\n\t\t\t\t\tswitch_instance = construct_svelte_component(switch_value, switch_props(ctx, dirty));\n\t\t\t\t\tbinding_callbacks.push(() => bind(switch_instance, 'name', switch_instance_name_binding));\n\t\t\t\t\t/*switch_instance_binding*/ ctx[23](switch_instance);\n\t\t\t\t\tswitch_instance.$on(\"measure\", /*handleMeasure*/ ctx[11]);\n\t\t\t\t\tcreate_component(switch_instance.$$.fragment);\n\t\t\t\t\ttransition_in(switch_instance.$$.fragment, 1);\n\t\t\t\t\tmount_component(switch_instance, switch_instance_anchor.parentNode, switch_instance_anchor);\n\t\t\t\t} else {\n\t\t\t\t\tswitch_instance = null;\n\t\t\t\t}\n\t\t\t} else if (switch_value) {\n\t\t\t\tconst switch_instance_changes = (dirty[0] & /*componentProps, locale*/ 34)\n\t\t\t\t? get_spread_update(switch_instance_spread_levels, [\n\t\t\t\t\t\tdirty[0] & /*componentProps*/ 32 && get_spread_object(/*componentProps*/ ctx[5]),\n\t\t\t\t\t\tdirty[0] & /*locale*/ 2 && { locale: /*locale*/ ctx[1] }\n\t\t\t\t\t])\n\t\t\t\t: {};\n\n\t\t\t\tif (!updating_name && dirty[0] & /*panelName*/ 8) {\n\t\t\t\t\tupdating_name = true;\n\t\t\t\t\tswitch_instance_changes.name = /*panelName*/ ctx[3];\n\t\t\t\t\tadd_flush_callback(() => updating_name = false);\n\t\t\t\t}\n\n\t\t\t\tswitch_instance.$set(switch_instance_changes);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\tif (switch_instance) transition_in(switch_instance.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tif (switch_instance) transition_out(switch_instance.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(switch_instance_anchor);\n\t\t\t}\n\n\t\t\t/*switch_instance_binding*/ ctx[23](null);\n\t\t\tif (switch_instance) destroy_component(switch_instance, detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$Q(ctx) {\n\tlet div;\n\tlet div_class_value;\n\tlet current;\n\tlet if_block = /*isLocal*/ ctx[6] && create_if_block$l(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(div, \"data-util\", /*panelName*/ ctx[3]);\n\t\t\tattr(div, \"class\", div_class_value = arrayJoin(['PinturaUtilPanel', /*klass*/ ctx[2]]));\n\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[7]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\t/*div_binding*/ ctx[24](div);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*isLocal*/ ctx[6]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*isLocal*/ 64) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$l(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*panelName*/ 8) {\n\t\t\t\tattr(div, \"data-util\", /*panelName*/ ctx[3]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*klass*/ 4 && div_class_value !== (div_class_value = arrayJoin(['PinturaUtilPanel', /*klass*/ ctx[2]]))) {\n\t\t\t\tattr(div, \"class\", div_class_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleOpacity*/ 128) {\n\t\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[7]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t\t/*div_binding*/ ctx[24](null);\n\t\t}\n\t};\n}\n\nfunction instance$R($$self, $$props, $$invalidate) {\n\tlet styleOpacity;\n\tlet componentProps;\n\tlet isLocal;\n\tlet $opacityClamped;\n\tlet $isAnimated;\n\tconst dispatch = createEventDispatcher();\n\tlet { isActive = true } = $$props;\n\tlet { stores } = $$props;\n\tlet { view } = $$props;\n\tlet { props } = $$props;\n\tlet { component } = $$props;\n\tlet { locale } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\n\t// context\n\tconst isAnimated = getContext('isAnimated');\n\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(21, $isAnimated = value));\n\n\t// we remember the view rect in this variable\n\tlet rect;\n\n\tconst opacity = spring(0);\n\tconst opacityClamped = derived(opacity, $opacity => clamp($opacity, 0, 1));\n\tcomponent_subscribe($$self, opacityClamped, value => $$invalidate(20, $opacityClamped = value));\n\n\t// throw hide / show events\n\tlet isHidden = !isActive;\n\n\t// create active store so can be used in derived stores\n\tconst isActivePrivateStore = writable(isActive);\n\n\tconst isActiveStore = derived(\n\t\tisActivePrivateStore,\n\t\tasync ($isActivePrivateStore, set) => {\n\t\t\t// set to false immidiately\n\t\t\tif (!$isActivePrivateStore) return set($isActivePrivateStore);\n\n\t\t\t// wait for next tick when setting to true, this helps deactivating\n\t\t\t// current panel before activing next one\n\t\t\tawait tick$1();\n\n\t\t\tset($isActivePrivateStore);\n\t\t},\n\t\t// needs to be fale initially for the above to work\n\t\tfalse\n\t);\n\n\tconst isActiveFractionStore = derived(opacityClamped, $opacityClamped => $opacityClamped);\n\tconst isVisibleStore = derived(opacityClamped, $opacityClamped => $opacityClamped > 0);\n\n\tconst stateProps = {\n\t\t// derived store to make isActive private\n\t\tisActive: isActiveStore,\n\t\tisActiveFraction: isActiveFractionStore,\n\t\tisVisible: isVisibleStore\n\t};\n\n\t// build the component props\n\t// const ComponentView = content.view;\n\tconst ComponentView = view;\n\n\tconst componentExportedProps = getComponentExportedProps(ComponentView);\n\n\tconst componentComputedProps = Object.keys(props || {}).reduce(\n\t\t(computedProps, key) => {\n\t\t\t// const componentComputedProps = Object.keys(content.props || {}).reduce((computedProps, key) => {\n\t\t\tif (!componentExportedProps.includes(key)) return computedProps;\n\n\t\t\t// computedProps[key] = content.props[key];\n\t\t\tcomputedProps[key] = props[key];\n\n\t\t\treturn computedProps;\n\t\t},\n\t\t{}\n\t);\n\n\tconst componentComputedStateProps = Object.keys(stateProps).reduce(\n\t\t(computedStateProps, key) => {\n\t\t\tif (!componentExportedProps.includes(key)) return computedStateProps;\n\t\t\tcomputedStateProps[key] = stateProps[key];\n\t\t\treturn computedStateProps;\n\t\t},\n\t\t{}\n\t);\n\n\t// class used on panel element\n\tlet panelName;\n\n\t// used when loading external plugin\n\tlet rootElement;\n\n\tconst handleMeasure = e => {\n\t\t// not fully hidden, so store rect for next render\n\t\t$$invalidate(17, rect = { ...e.detail });\n\n\t\tif (!hasBeenMounted || !isActive) return;\n\t\tdispatch('measure', { ...rect });\n\t};\n\n\t// we expose measurable in the context map\n\tsetContext('measurable', measurable);\n\n\t// we get all context so we can pass them to external plugins\n\tconst contextMap = getAllContexts();\n\n\t// we use the `hasBeenMounted` bool to block rect updates until the entire panel is ready\n\tlet hasBeenMounted = false;\n\n\tonMount(() => {\n\t\t$$invalidate(19, hasBeenMounted = true);\n\n\t\t// no special needs for local modules\n\t\tif (isLocal) return;\n\n\t\t$$invalidate(0, component = new ComponentView({\n\t\t\t\ttarget: rootElement,\n\t\t\t\t// pass custom props to external plugin\n\t\t\t\tprops: { ...componentProps, locale },\n\t\t\t\t// pass context to external plugin\n\t\t\t\tcontext: contextMap\n\t\t\t}));\n\n\t\t$$invalidate(3, panelName = component.name);\n\t\tconst unsub = component.$on('measure', handleMeasure);\n\n\t\treturn () => {\n\t\t\tunsub();\n\t\t\tcomponent.$destroy();\n\t\t};\n\t});\n\n\tfunction switch_instance_name_binding(value) {\n\t\tpanelName = value;\n\t\t$$invalidate(3, panelName);\n\t}\n\n\tfunction switch_instance_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tcomponent = $$value;\n\t\t\t$$invalidate(0, component);\n\t\t});\n\t}\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\trootElement = $$value;\n\t\t\t$$invalidate(4, rootElement);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$invalidate(12, isActive = $$props.isActive);\n\t\tif ('stores' in $$props) $$invalidate(13, stores = $$props.stores);\n\t\tif ('view' in $$props) $$invalidate(14, view = $$props.view);\n\t\tif ('props' in $$props) $$invalidate(15, props = $$props.props);\n\t\tif ('component' in $$props) $$invalidate(0, component = $$props.component);\n\t\tif ('locale' in $$props) $$invalidate(1, locale = $$props.locale);\n\t\tif ('class' in $$props) $$invalidate(2, klass = $$props.class);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*rect, isActive, component*/ 135169) {\n\t\t\t// when the view rect changes and the panel is in active state or became active, dispatch measure event\n\t\t\tif (rect && isActive && component) dispatch('measure', rect);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive, $isAnimated*/ 2101248) {\n\t\t\topacity.set(isActive ? 1 : 0, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$opacityClamped, isHidden*/ 1310720) {\n\t\t\tif ($opacityClamped <= 0 && !isHidden) {\n\t\t\t\t$$invalidate(18, isHidden = true);\n\t\t\t} else if ($opacityClamped > 0 && isHidden) {\n\t\t\t\t$$invalidate(18, isHidden = false);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*hasBeenMounted, isHidden*/ 786432) {\n\t\t\thasBeenMounted && dispatch(isHidden ? 'hide' : 'show');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$opacityClamped*/ 1048576) {\n\t\t\tdispatch('fade', $opacityClamped);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$opacityClamped*/ 1048576) {\n\t\t\t// only set opacity prop if is below 0\n\t\t\t$$invalidate(7, styleOpacity = $opacityClamped);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive*/ 4096) {\n\t\t\tisActivePrivateStore.set(isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*stores*/ 8192) {\n\t\t\t$$invalidate(5, componentProps = {\n\t\t\t\t...componentComputedProps,\n\t\t\t\t...componentComputedStateProps,\n\t\t\t\tstores\n\t\t\t});\n\t\t}\n\t};\n\n\t$$invalidate(6, isLocal = !componentExportedProps.includes('external'));\n\n\treturn [\n\t\tcomponent,\n\t\tlocale,\n\t\tklass,\n\t\tpanelName,\n\t\trootElement,\n\t\tcomponentProps,\n\t\tisLocal,\n\t\tstyleOpacity,\n\t\tisAnimated,\n\t\topacityClamped,\n\t\tComponentView,\n\t\thandleMeasure,\n\t\tisActive,\n\t\tstores,\n\t\tview,\n\t\tprops,\n\t\topacity,\n\t\trect,\n\t\tisHidden,\n\t\thasBeenMounted,\n\t\t$opacityClamped,\n\t\t$isAnimated,\n\t\tswitch_instance_name_binding,\n\t\tswitch_instance_binding,\n\t\tdiv_binding\n\t];\n}\n\nclass UtilPanel extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$R,\n\t\t\tcreate_fragment$Q,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tisActive: 12,\n\t\t\t\tstores: 13,\n\t\t\t\tview: 14,\n\t\t\t\tprops: 15,\n\t\t\t\tcomponent: 0,\n\t\t\t\tlocale: 1,\n\t\t\t\tclass: 2,\n\t\t\t\topacity: 16\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget opacity() {\n\t\treturn this.$$.ctx[16];\n\t}\n}\n\n/* src/core/ui/components/Icon.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$P(ctx) {\n\tlet svg;\n\tlet svg_viewBox_value;\n\tlet styleable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[5].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[4], null);\n\n\treturn {\n\t\tc() {\n\t\t\tsvg = svg_element(\"svg\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tattr(svg, \"class\", /*klass*/ ctx[3]);\n\t\t\tattr(svg, \"width\", /*width*/ ctx[0]);\n\t\t\tattr(svg, \"height\", /*height*/ ctx[1]);\n\t\t\tattr(svg, \"viewBox\", svg_viewBox_value = \"0 0 \" + /*width*/ ctx[0] + \"\\n    \" + /*height*/ ctx[1]);\n\t\t\tattr(svg, \"xmlns\", \"http://www.w3.org/2000/svg\");\n\t\t\tattr(svg, \"aria-hidden\", \"true\");\n\t\t\tattr(svg, \"focusable\", \"false\");\n\t\t\tattr(svg, \"stroke-linecap\", \"round\");\n\t\t\tattr(svg, \"stroke-linejoin\", \"round\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, svg, anchor);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(svg, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = action_destroyer(styleable_action = styleable.call(null, svg, /*style*/ ctx[2]));\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope*/ 16)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[4],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[4])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[4], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*klass*/ 8) {\n\t\t\t\tattr(svg, \"class\", /*klass*/ ctx[3]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*width*/ 1) {\n\t\t\t\tattr(svg, \"width\", /*width*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*height*/ 2) {\n\t\t\t\tattr(svg, \"height\", /*height*/ ctx[1]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*width, height*/ 3 && svg_viewBox_value !== (svg_viewBox_value = \"0 0 \" + /*width*/ ctx[0] + \"\\n    \" + /*height*/ ctx[1])) {\n\t\t\t\tattr(svg, \"viewBox\", svg_viewBox_value);\n\t\t\t}\n\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty & /*style*/ 4) styleable_action.update.call(null, /*style*/ ctx[2]);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(svg);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\nfunction instance$Q($$self, $$props, $$invalidate) {\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { width = 24 } = $$props;\n\tlet { height = 24 } = $$props;\n\tlet { style = undefined } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\n\t$$self.$$set = $$props => {\n\t\tif ('width' in $$props) $$invalidate(0, width = $$props.width);\n\t\tif ('height' in $$props) $$invalidate(1, height = $$props.height);\n\t\tif ('style' in $$props) $$invalidate(2, style = $$props.style);\n\t\tif ('class' in $$props) $$invalidate(3, klass = $$props.class);\n\t\tif ('$$scope' in $$props) $$invalidate(4, $$scope = $$props.$$scope);\n\t};\n\n\treturn [width, height, style, klass, $$scope, slots];\n}\n\nclass Icon extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$Q, create_fragment$P, safe_not_equal, { width: 0, height: 1, style: 2, class: 3 });\n\t}\n}\n\nvar _isEventTarget = (e, element) => element === e.target || element.contains(e.target);\n\nvar toKeyboardShortcut = (keys) => keys.map((key) => (key === 'CMD' ? (isMac() ? '\u2318' : 'Ctrl') : key)).join('+');\n\n/**\n * @param { string } label\n * @param { string } title\n * @param { string[] } shortcut\n * @returns { string }\n */\nvar toTitle = (label, title, shortcut) => {\n    const text = isString(title) ? title : label;\n    if (shortcut)\n        return `${text} (${toKeyboardShortcut(shortcut)})`;\n    return text;\n};\n\n/* src/core/ui/components/ImageButton.svelte generated by Svelte v4.2.20 */\n\nconst { document: document_1$1 } = globals;\n\nfunction create_fragment$O(ctx) {\n\tlet t;\n\tlet button;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tt = space();\n\t\t\tbutton = element(\"button\");\n\t\t\tattr(button, \"class\", \"PinturaImageButton\");\n\t\t\tattr(button, \"type\", \"button\");\n\t\t\tattr(button, \"title\", /*title*/ ctx[1]);\n\t\t\tbutton.disabled = /*disabled*/ ctx[2];\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, t, anchor);\n\t\t\tinsert(target, button, anchor);\n\t\t\tbutton.innerHTML = /*html*/ ctx[0];\n\t\t\t/*button_binding*/ ctx[11](button);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(document_1$1.body, \"load\", /*handleLoad*/ ctx[5], true),\n\t\t\t\t\tlisten(document_1$1.body, \"error\", /*handleError*/ ctx[6], true),\n\t\t\t\t\tlisten(button, \"pointerdown\", /*handleDown*/ ctx[4])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*html*/ 1) button.innerHTML = /*html*/ ctx[0];\n\t\t\tif (dirty & /*title*/ 2) {\n\t\t\t\tattr(button, \"title\", /*title*/ ctx[1]);\n\t\t\t}\n\n\t\t\tif (dirty & /*disabled*/ 4) {\n\t\t\t\tbutton.disabled = /*disabled*/ ctx[2];\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(button);\n\t\t\t}\n\n\t\t\t/*button_binding*/ ctx[11](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$P($$self, $$props, $$invalidate) {\n\tlet { html } = $$props;\n\tlet { title } = $$props;\n\tlet { onclick } = $$props;\n\tlet { disabled = false } = $$props;\n\tlet { ongrab = noop$1 } = $$props;\n\tlet { ondrag = noop$1 } = $$props;\n\tlet { ondrop = noop$1 } = $$props;\n\tlet element;\n\tconst isOverButton = e => vectorDistanceSquared(downPosition, vectorCreate(e.pageX, e.pageY)) < 256;\n\tlet downPosition;\n\n\tconst handleDown = e => {\n\t\tdownPosition = vectorCreate(e.pageX, e.pageY);\n\t\tongrab(e);\n\t\tdocument.documentElement.addEventListener('pointermove', handleMove);\n\t\tdocument.documentElement.addEventListener('pointerup', handleUp);\n\t};\n\n\tconst handleUp = e => {\n\t\tdocument.documentElement.removeEventListener('pointermove', handleMove);\n\t\tdocument.documentElement.removeEventListener('pointerup', handleUp);\n\t\tconst upPosition = vectorCreate(e.pageX, e.pageY);\n\n\t\t// must have moved enough distance to drop\n\t\tif (vectorDistanceSquared(downPosition, upPosition) < 32) return onclick(e);\n\n\t\t// cant drop in button\n\t\tif (isOverButton(e)) return;\n\n\t\t// was dragging\n\t\tondrop(e);\n\t};\n\n\tconst handleMove = e => {\n\t\t// must have moved enough distance from button\n\t\tif (isOverButton(e)) return;\n\n\t\t// dragging out of button\n\t\tondrag(e);\n\t};\n\n\t// image loading\n\tconst isImageTarget = target => element && element.contains(target) && target.nodeName === 'IMG';\n\n\tconst handleLoad = ({ target }) => {\n\t\tif (!isImageTarget(target)) return;\n\t\t$$invalidate(3, element.dataset.load = true, element);\n\t};\n\n\tconst handleError = ({ target }) => {\n\t\tif (!isImageTarget(target)) return;\n\t\t$$invalidate(3, element.dataset.error = true, element);\n\t};\n\n\tfunction button_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\telement = $$value;\n\t\t\t$$invalidate(3, element);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('html' in $$props) $$invalidate(0, html = $$props.html);\n\t\tif ('title' in $$props) $$invalidate(1, title = $$props.title);\n\t\tif ('onclick' in $$props) $$invalidate(7, onclick = $$props.onclick);\n\t\tif ('disabled' in $$props) $$invalidate(2, disabled = $$props.disabled);\n\t\tif ('ongrab' in $$props) $$invalidate(8, ongrab = $$props.ongrab);\n\t\tif ('ondrag' in $$props) $$invalidate(9, ondrag = $$props.ondrag);\n\t\tif ('ondrop' in $$props) $$invalidate(10, ondrop = $$props.ondrop);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*element*/ 8) {\n\t\t\tif (element && element.querySelector('img')) $$invalidate(3, element.dataset.loader = true, element);\n\t\t}\n\t};\n\n\treturn [\n\t\thtml,\n\t\ttitle,\n\t\tdisabled,\n\t\telement,\n\t\thandleDown,\n\t\thandleLoad,\n\t\thandleError,\n\t\tonclick,\n\t\tongrab,\n\t\tondrag,\n\t\tondrop,\n\t\tbutton_binding\n\t];\n}\n\nclass ImageButton extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$P, create_fragment$O, safe_not_equal, {\n\t\t\thtml: 0,\n\t\t\ttitle: 1,\n\t\t\tonclick: 7,\n\t\t\tdisabled: 2,\n\t\t\tongrab: 8,\n\t\t\tondrag: 9,\n\t\t\tondrop: 10\n\t\t});\n\t}\n}\n\n/* src/core/ui/components/ImageButtonList.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context$6(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[13] = list[i];\n\treturn child_ctx;\n}\n\n// (23:4) {#each items as item (item.id)}\nfunction create_each_block$6(key_1, ctx) {\n\tlet li;\n\tlet imagebutton;\n\tlet t;\n\tlet didMountAction_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tfunction func() {\n\t\treturn /*func*/ ctx[9](/*item*/ ctx[13]);\n\t}\n\n\tfunction func_1(...args) {\n\t\treturn /*func_1*/ ctx[10](/*item*/ ctx[13], ...args);\n\t}\n\n\tfunction func_2(...args) {\n\t\treturn /*func_2*/ ctx[11](/*item*/ ctx[13], ...args);\n\t}\n\n\tfunction func_3(...args) {\n\t\treturn /*func_3*/ ctx[12](/*item*/ ctx[13], ...args);\n\t}\n\n\timagebutton = new ImageButton({\n\t\t\tprops: {\n\t\t\t\tonclick: func,\n\t\t\t\tongrab: func_1,\n\t\t\t\tondrag: func_2,\n\t\t\t\tondrop: func_3,\n\t\t\t\tdisabled: /*disabled*/ ctx[1] || /*item*/ ctx[13].disabled,\n\t\t\t\ttitle: /*item*/ ctx[13].title,\n\t\t\t\thtml: /*item*/ ctx[13].thumb\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tkey: key_1,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tli = element(\"li\");\n\t\t\tcreate_component(imagebutton.$$.fragment);\n\t\t\tt = space();\n\t\t\tset_style(li, \"opacity\", /*$opacity*/ ctx[6]);\n\t\t\tthis.first = li;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, li, anchor);\n\t\t\tmount_component(imagebutton, li, null);\n\t\t\tappend(li, t);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = action_destroyer(didMountAction_action = /*didMountAction*/ ctx[8].call(null, li, /*item*/ ctx[13]));\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tconst imagebutton_changes = {};\n\t\t\tif (dirty & /*onclickitem, items*/ 5) imagebutton_changes.onclick = func;\n\t\t\tif (dirty & /*ongrabitem, items*/ 9) imagebutton_changes.ongrab = func_1;\n\t\t\tif (dirty & /*ondragitem, items*/ 17) imagebutton_changes.ondrag = func_2;\n\t\t\tif (dirty & /*ondropitem, items*/ 33) imagebutton_changes.ondrop = func_3;\n\t\t\tif (dirty & /*disabled, items*/ 3) imagebutton_changes.disabled = /*disabled*/ ctx[1] || /*item*/ ctx[13].disabled;\n\t\t\tif (dirty & /*items*/ 1) imagebutton_changes.title = /*item*/ ctx[13].title;\n\t\t\tif (dirty & /*items*/ 1) imagebutton_changes.html = /*item*/ ctx[13].thumb;\n\t\t\timagebutton.$set(imagebutton_changes);\n\t\t\tif (didMountAction_action && is_function(didMountAction_action.update) && dirty & /*items*/ 1) didMountAction_action.update.call(null, /*item*/ ctx[13]);\n\n\t\t\tif (dirty & /*$opacity*/ 64) {\n\t\t\t\tset_style(li, \"opacity\", /*$opacity*/ ctx[6]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(imagebutton.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(imagebutton.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(li);\n\t\t\t}\n\n\t\t\tdestroy_component(imagebutton);\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\nfunction create_fragment$N(ctx) {\n\tlet ul;\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet current;\n\tlet each_value = ensure_array_like(/*items*/ ctx[0]);\n\tconst get_key = ctx => /*item*/ ctx[13].id;\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$6(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$6(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tul = element(\"ul\");\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tattr(ul, \"class\", \"PinturaImageButtonList\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, ul, anchor);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(ul, null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*items, $opacity, onclickitem, ongrabitem, ondragitem, ondropitem, disabled*/ 127) {\n\t\t\t\teach_value = ensure_array_like(/*items*/ ctx[0]);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$6, null, get_each_context$6);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(ul);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d();\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction instance$O($$self, $$props, $$invalidate) {\n\tlet $opacity;\n\tlet { items } = $$props;\n\tlet { disabled = undefined } = $$props;\n\tlet { onclickitem } = $$props;\n\tlet { ongrabitem = undefined } = $$props;\n\tlet { ondragitem = undefined } = $$props;\n\tlet { ondropitem = undefined } = $$props;\n\tconst opacity = spring(0, { stiffness: 0.25, damping: 0.9 });\n\tcomponent_subscribe($$self, opacity, value => $$invalidate(6, $opacity = value));\n\tconst didMountAction = (element, item) => item.mount && item.mount(element.firstChild, item);\n\tonMount(() => opacity.set(1));\n\tconst func = item => onclickitem(item.id);\n\tconst func_1 = (item, e) => ongrabitem && ongrabitem(item.id, e);\n\tconst func_2 = (item, e) => ondragitem && ondragitem(item.id, e);\n\tconst func_3 = (item, e) => ondropitem && ondropitem(item.id, e);\n\n\t$$self.$$set = $$props => {\n\t\tif ('items' in $$props) $$invalidate(0, items = $$props.items);\n\t\tif ('disabled' in $$props) $$invalidate(1, disabled = $$props.disabled);\n\t\tif ('onclickitem' in $$props) $$invalidate(2, onclickitem = $$props.onclickitem);\n\t\tif ('ongrabitem' in $$props) $$invalidate(3, ongrabitem = $$props.ongrabitem);\n\t\tif ('ondragitem' in $$props) $$invalidate(4, ondragitem = $$props.ondragitem);\n\t\tif ('ondropitem' in $$props) $$invalidate(5, ondropitem = $$props.ondropitem);\n\t};\n\n\treturn [\n\t\titems,\n\t\tdisabled,\n\t\tonclickitem,\n\t\tongrabitem,\n\t\tondragitem,\n\t\tondropitem,\n\t\t$opacity,\n\t\topacity,\n\t\tdidMountAction,\n\t\tfunc,\n\t\tfunc_1,\n\t\tfunc_2,\n\t\tfunc_3\n\t];\n}\n\nclass ImageButtonList extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$O, create_fragment$N, safe_not_equal, {\n\t\t\titems: 0,\n\t\t\tdisabled: 1,\n\t\t\tonclickitem: 2,\n\t\t\tongrabitem: 3,\n\t\t\tondragitem: 4,\n\t\t\tondropitem: 5\n\t\t});\n\t}\n}\n\nvar getDevicePixelRatio = () => (isBrowser() && window.devicePixelRatio) || 1;\n\n// if this is a non retina display snap to pixel\nlet fn = null;\nvar snapToPixel = (v) => {\n    if (fn === null)\n        fn = getDevicePixelRatio() === 1 ? Math.round : (v) => v;\n    return fn(v);\n};\n\nvar focus = (element, options = {}) => {\n    if (!element)\n        return;\n    if (options.preventScroll && isSafari()) {\n        const scrollTop = document.body.scrollTop;\n        element.focus();\n        document.body.scrollTop = scrollTop;\n        return;\n    }\n    element.focus(options);\n};\n\nvar isTextarea = (element) => /textarea/i.test(element.nodeName);\n\nvar isTextInput = (node) => /date|email|number|search|text|url/.test(node.type);\n\nvar isTextField = (node) => isTextarea(node) || isTextInput(node) || node.isContentEditable;\n\n/* src/core/ui/components/Panel.svelte generated by Svelte v4.2.20 */\nconst get_details_slot_changes = dirty => ({});\nconst get_details_slot_context = ctx => ({});\nconst get_label_slot_changes = dirty => ({});\nconst get_label_slot_context = ctx => ({});\n\n// (254:0) {:else}\nfunction create_else_block$a(ctx) {\n\tlet button;\n\tlet current;\n\tconst button_spread_levels = [/*buttonProps*/ ctx[7]];\n\n\tlet button_props = {\n\t\t$$slots: { default: [create_default_slot$h] },\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < button_spread_levels.length; i += 1) {\n\t\tbutton_props = assign(button_props, button_spread_levels[i]);\n\t}\n\n\tbutton = new Button({ props: button_props });\n\t/*button_binding_1*/ ctx[54](button);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(button.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(button, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst button_changes = (dirty[0] & /*buttonProps*/ 128)\n\t\t\t? get_spread_update(button_spread_levels, [get_spread_object(/*buttonProps*/ ctx[7])])\n\t\t\t: {};\n\n\t\t\tif (dirty[1] & /*$$scope*/ 134217728) {\n\t\t\t\tbutton_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tbutton.$set(button_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\t/*button_binding_1*/ ctx[54](null);\n\t\t\tdestroy_component(button, detaching);\n\t\t}\n\t};\n}\n\n// (252:0) {#if buttonLabel}\nfunction create_if_block_2$c(ctx) {\n\tlet button;\n\tlet current;\n\tconst button_spread_levels = [/*buttonProps*/ ctx[7]];\n\tlet button_props = {};\n\n\tfor (let i = 0; i < button_spread_levels.length; i += 1) {\n\t\tbutton_props = assign(button_props, button_spread_levels[i]);\n\t}\n\n\tbutton = new Button({ props: button_props });\n\t/*button_binding*/ ctx[53](button);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(button.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(button, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst button_changes = (dirty[0] & /*buttonProps*/ 128)\n\t\t\t? get_spread_update(button_spread_levels, [get_spread_object(/*buttonProps*/ ctx[7])])\n\t\t\t: {};\n\n\t\t\tbutton.$set(button_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\t/*button_binding*/ ctx[53](null);\n\t\t\tdestroy_component(button, detaching);\n\t\t}\n\t};\n}\n\n// (255:4) <Button bind:this={buttonComponent} {...buttonProps}>\nfunction create_default_slot$h(ctx) {\n\tlet current;\n\tconst label_slot_template = /*#slots*/ ctx[52].label;\n\tconst label_slot = create_slot(label_slot_template, ctx, /*$$scope*/ ctx[58], get_label_slot_context);\n\n\treturn {\n\t\tc() {\n\t\t\tif (label_slot) label_slot.c();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (label_slot) {\n\t\t\t\tlabel_slot.m(target, anchor);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (label_slot) {\n\t\t\t\tif (label_slot.p && (!current || dirty[1] & /*$$scope*/ 134217728)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tlabel_slot,\n\t\t\t\t\t\tlabel_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[58],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[58])\n\t\t\t\t\t\t: get_slot_changes(label_slot_template, /*$$scope*/ ctx[58], dirty, get_label_slot_changes),\n\t\t\t\t\t\tget_label_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(label_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(label_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (label_slot) label_slot.d(detaching);\n\t\t}\n\t};\n}\n\n// (260:0) {#if isVisible}\nfunction create_if_block_1$g(ctx) {\n\tlet div;\n\tlet t;\n\tlet span;\n\tlet div_class_value;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst details_slot_template = /*#slots*/ ctx[52].details;\n\tconst details_slot = create_slot(details_slot_template, ctx, /*$$scope*/ ctx[58], get_details_slot_context);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (details_slot) details_slot.c();\n\t\t\tt = space();\n\t\t\tspan = element(\"span\");\n\t\t\tattr(span, \"class\", \"PinturaPanelTip\");\n\t\t\tattr(span, \"data-top\", /*dataTop*/ ctx[10]);\n\t\t\tset_style(span, \"opacity\", /*styleTipOpacity*/ ctx[14]);\n\t\t\tset_style(span, \"transform\", /*styleTipTransform*/ ctx[13]);\n\t\t\tset_style(span, \"top\", /*styleTipTop*/ ctx[12]);\n\t\t\tset_style(span, \"left\", /*styleTipLeft*/ ctx[11]);\n\t\t\tattr(div, \"class\", div_class_value = arrayJoin(['PinturaPanel', 'pintura-editor-panel', /*panelClass*/ ctx[2]]));\n\t\t\tattr(div, \"tabindex\", \"-1\");\n\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[18]);\n\t\t\tset_style(div, \"pointer-events\", /*stylePointerEvents*/ ctx[17]);\n\t\t\tset_style(div, \"transform\", /*styleTransform*/ ctx[16]);\n\t\t\tset_style(div, \"--panel-max-height\", /*styleMaxHeight*/ ctx[15]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (details_slot) {\n\t\t\t\tdetails_slot.m(div, null);\n\t\t\t}\n\n\t\t\tappend(div, t);\n\t\t\tappend(div, span);\n\t\t\t/*div_binding*/ ctx[55](div);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"close\", /*close_handler*/ ctx[56]),\n\t\t\t\t\tlisten(div, \"keydown\", /*handlePanelKeydown*/ ctx[25]),\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler*/ ctx[57]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (details_slot) {\n\t\t\t\tif (details_slot.p && (!current || dirty[1] & /*$$scope*/ 134217728)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdetails_slot,\n\t\t\t\t\t\tdetails_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[58],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[58])\n\t\t\t\t\t\t: get_slot_changes(details_slot_template, /*$$scope*/ ctx[58], dirty, get_details_slot_changes),\n\t\t\t\t\t\tget_details_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*dataTop*/ 1024) {\n\t\t\t\tattr(span, \"data-top\", /*dataTop*/ ctx[10]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleTipOpacity*/ 16384) {\n\t\t\t\tset_style(span, \"opacity\", /*styleTipOpacity*/ ctx[14]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleTipTransform*/ 8192) {\n\t\t\t\tset_style(span, \"transform\", /*styleTipTransform*/ ctx[13]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleTipTop*/ 4096) {\n\t\t\t\tset_style(span, \"top\", /*styleTipTop*/ ctx[12]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleTipLeft*/ 2048) {\n\t\t\t\tset_style(span, \"left\", /*styleTipLeft*/ ctx[11]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*panelClass*/ 4 && div_class_value !== (div_class_value = arrayJoin(['PinturaPanel', 'pintura-editor-panel', /*panelClass*/ ctx[2]]))) {\n\t\t\t\tattr(div, \"class\", div_class_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleOpacity*/ 262144) {\n\t\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[18]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*stylePointerEvents*/ 131072) {\n\t\t\t\tset_style(div, \"pointer-events\", /*stylePointerEvents*/ ctx[17]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleTransform*/ 65536) {\n\t\t\t\tset_style(div, \"transform\", /*styleTransform*/ ctx[16]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleMaxHeight*/ 32768) {\n\t\t\t\tset_style(div, \"--panel-max-height\", /*styleMaxHeight*/ ctx[15]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(details_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(details_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (details_slot) details_slot.d(detaching);\n\t\t\t/*div_binding*/ ctx[55](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$M(ctx) {\n\tlet t0;\n\tlet current_block_type_index;\n\tlet if_block0;\n\tlet t1;\n\tlet t2;\n\tlet if_block2_anchor;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst if_block_creators = [create_if_block_2$c, create_else_block$a];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*buttonLabel*/ ctx[1]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx);\n\tif_block0 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\tlet if_block1 = /*isVisible*/ ctx[6] && create_if_block_1$g(ctx);\n\tlet if_block2 = false ;\n\n\treturn {\n\t\tc() {\n\t\t\tt0 = space();\n\t\t\tif_block0.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt2 = space();\n\t\t\tif_block2_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, t0, anchor);\n\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, t2, anchor);\n\t\t\tinsert(target, if_block2_anchor, anchor);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(document.body, \"pointerdown\", function () {\n\t\t\t\t\t\tif (is_function(/*handleDown*/ ctx[9])) /*handleDown*/ ctx[9].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(document.body, \"pointerup\", function () {\n\t\t\t\t\t\tif (is_function(/*handleUp*/ ctx[8])) /*handleUp*/ ctx[8].apply(this, arguments);\n\t\t\t\t\t})\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block0 = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block0) {\n\t\t\t\t\tif_block0 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\tif_block0.m(t1.parentNode, t1);\n\t\t\t}\n\n\t\t\tif (/*isVisible*/ ctx[6]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*isVisible*/ 64) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_1$g(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(t2.parentNode, t2);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\ttransition_in(if_block2);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\ttransition_out(if_block2);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(t1);\n\t\t\t\tdetach(t2);\n\t\t\t\tdetach(if_block2_anchor);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nlet panelMargin = 12;\n\nfunction instance$N($$self, $$props, $$invalidate) {\n\tlet buttonElement;\n\tlet offsetProgress;\n\tlet isVisible;\n\tlet transform;\n\tlet styleOpacity;\n\tlet stylePointerEvents;\n\tlet styleTransform;\n\tlet styleMaxHeight;\n\tlet tipScale;\n\tlet tipOpacity;\n\tlet styleTip;\n\tlet styleTipOpacity;\n\tlet styleTipTransform;\n\tlet styleTipTop;\n\tlet styleTipLeft;\n\tlet dataTop;\n\tlet handleDown;\n\tlet handleUp;\n\tlet buttonProps;\n\tlet $portal;\n\tlet $position;\n\tlet $portalRootRect;\n\tlet $opacity;\n\tlet $offset;\n\tlet $isAnimated;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { buttonClass = undefined } = $$props;\n\tlet { buttonLabel = undefined } = $$props;\n\tlet { buttonLabelClass = undefined } = $$props;\n\tlet { buttonHideLabel = undefined } = $$props;\n\tlet { buttonIcon = undefined } = $$props;\n\tlet { buttonTitle = undefined } = $$props;\n\tlet { buttonOnClick = undefined } = $$props;\n\tlet { panelClass = undefined } = $$props;\n\tlet { isActive = false } = $$props;\n\tlet { onshow = noop$1 } = $$props;\n\tlet { onhide = noop$1 } = $$props;\n\tlet { canConfirm = false } = $$props;\n\tconst isAnimated = getContext('isAnimated');\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(51, $isAnimated = value));\n\tconst portal = getContext('rootPortal');\n\tcomponent_subscribe($$self, portal, value => $$invalidate(46, $portal = value));\n\tconst portalRootRect = getContext('rootRect');\n\tcomponent_subscribe($$self, portalRootRect, value => $$invalidate(48, $portalRootRect = value));\n\tlet panelSize;\n\tlet buttonComponent;\n\tlet buttonRect;\n\tconst syncButtonRect = () => $$invalidate(35, buttonRect = buttonElement && buttonElement.getBoundingClientRect());\n\tlet dir = vectorCreateEmpty();\n\tlet opacity = spring(0);\n\tcomponent_subscribe($$self, opacity, value => $$invalidate(49, $opacity = value));\n\tlet shift = vectorCreateEmpty();\n\tconst position = writable({ x: 0, y: 0 });\n\tcomponent_subscribe($$self, position, value => $$invalidate(47, $position = value));\n\n\tconst offset = spring(-5, {\n\t\tstiffness: 0.1,\n\t\tdamping: 0.35,\n\t\tprecision: 0.001\n\t});\n\n\tcomponent_subscribe($$self, offset, value => $$invalidate(50, $offset = value));\n\tlet showPanelTip = true;\n\tconst isTargetSelf = e => _isEventTarget(e, $portal) || buttonComponent.isEventTarget(e);\n\tlet downOutsidePanel = false;\n\n\t// move detail panel to portal\n\tlet detailPanel;\n\n\tlet trigger;\n\n\t// test keydown press to open\n\tconst handleClick = e => {\n\t\tif (isTextField(e.target)) return;\n\t\tif (isFunction(buttonOnClick)) buttonOnClick();\n\t\tif (!isActive) syncButtonRect();\n\t\t$$invalidate(40, trigger = e);\n\t\t$$invalidate(0, isActive = !isActive);\n\t};\n\n\tconst handleButtonKeydown = e => {\n\t\tif (!(/down/i).test(e.key)) return;\n\t\tif (e.target && isTextField(e.target)) return;\n\t\t$$invalidate(0, isActive = true);\n\t\t$$invalidate(40, trigger = e);\n\t};\n\n\tconst handlePanelKeydown = e => {\n\t\t// is escape key, or can confirm and is return key\n\t\tif ((/esc/i).test(e.key) || canConfirm && (/enter/i).test(e.key)) {\n\t\t\t// need to prevent default on enter if was used to confirm\n\t\t\tif ((/enter/i).test(e.key)) {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\n\t\t\t$$invalidate(0, isActive = false);\n\t\t\tbuttonElement.focus();\n\t\t}\n\t};\n\n\t// clean up panel if it was appended to a portal\n\tonDestroy(() => {\n\t\t// no panel or portal, exit\n\t\tif (!$portal) return;\n\n\t\tif (!detailPanel) return;\n\n\t\t// store a ref\n\t\tconst detailPanelRef = detailPanel;\n\n\t\t// clean up \"manually\" if svelte failed to detach, this sometimes happens if parent element is removed from DOM\n\t\ttick$1().then(() => {\n\t\t\tif (!detailPanelRef.parentNode) return;\n\t\t\tdetailPanelRef.remove();\n\t\t});\n\t});\n\n\tfunction button_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tbuttonComponent = $$value;\n\t\t\t$$invalidate(4, buttonComponent);\n\t\t});\n\t}\n\n\tfunction button_binding_1($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tbuttonComponent = $$value;\n\t\t\t$$invalidate(4, buttonComponent);\n\t\t});\n\t}\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tdetailPanel = $$value;\n\t\t\t$$invalidate(5, detailPanel);\n\t\t});\n\t}\n\n\tconst close_handler = e => {\n\t\te.stopPropagation();\n\t\t$$invalidate(0, isActive = false);\n\t};\n\n\tconst measure_handler = e => $$invalidate(3, panelSize = sizeCreateFromAny(e.detail));\n\n\t$$self.$$set = $$props => {\n\t\tif ('buttonClass' in $$props) $$invalidate(26, buttonClass = $$props.buttonClass);\n\t\tif ('buttonLabel' in $$props) $$invalidate(1, buttonLabel = $$props.buttonLabel);\n\t\tif ('buttonLabelClass' in $$props) $$invalidate(27, buttonLabelClass = $$props.buttonLabelClass);\n\t\tif ('buttonHideLabel' in $$props) $$invalidate(28, buttonHideLabel = $$props.buttonHideLabel);\n\t\tif ('buttonIcon' in $$props) $$invalidate(29, buttonIcon = $$props.buttonIcon);\n\t\tif ('buttonTitle' in $$props) $$invalidate(30, buttonTitle = $$props.buttonTitle);\n\t\tif ('buttonOnClick' in $$props) $$invalidate(31, buttonOnClick = $$props.buttonOnClick);\n\t\tif ('panelClass' in $$props) $$invalidate(2, panelClass = $$props.panelClass);\n\t\tif ('isActive' in $$props) $$invalidate(0, isActive = $$props.isActive);\n\t\tif ('onshow' in $$props) $$invalidate(32, onshow = $$props.onshow);\n\t\tif ('onhide' in $$props) $$invalidate(33, onhide = $$props.onhide);\n\t\tif ('canConfirm' in $$props) $$invalidate(34, canConfirm = $$props.canConfirm);\n\t\tif ('$$scope' in $$props) $$invalidate(58, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*buttonComponent*/ 16) {\n\t\t\tbuttonElement = buttonComponent && buttonComponent.getElement();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive*/ 1 | $$self.$$.dirty[1] & /*downOutsidePanel*/ 256) {\n\t\t\t$$invalidate(8, handleUp = isActive\n\t\t\t? e => {\n\t\t\t\t\tif (!downOutsidePanel) return;\n\t\t\t\t\t$$invalidate(39, downOutsidePanel = false);\n\t\t\t\t\tif (isTargetSelf(e)) return;\n\t\t\t\t\t$$invalidate(0, isActive = false);\n\t\t\t\t}\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive*/ 1 | $$self.$$.dirty[1] & /*$isAnimated*/ 1048576) {\n\t\t\topacity.set(isActive ? 1 : 0, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive*/ 1 | $$self.$$.dirty[1] & /*$isAnimated*/ 1048576) {\n\t\t\toffset.set(isActive ? 0 : -5, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$offset*/ 524288) {\n\t\t\t$$invalidate(44, offsetProgress = 1 - $offset / -5);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive*/ 1 | $$self.$$.dirty[1] & /*$portalRootRect*/ 131072) {\n\t\t\tif ($portalRootRect && isActive) syncButtonRect();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*panelSize, isActive*/ 9 | $$self.$$.dirty[1] & /*$portalRootRect, buttonRect*/ 131088) {\n\t\t\tif ($portalRootRect && panelSize && buttonRect && isActive) {\n\t\t\t\t$$invalidate(38, showPanelTip = true);\n\n\t\t\t\t// as a starting point we'll align panel to center of button and position below\n\t\t\t\tlet x = buttonRect.x - $portalRootRect.x + buttonRect.width * 0.5 - panelSize.width * 0.5;\n\n\t\t\t\tlet y = buttonRect.y - $portalRootRect.y + buttonRect.height;\n\t\t\t\tconst parentLeft = panelMargin;\n\t\t\t\tconst parentTop = panelMargin;\n\t\t\t\tconst parentRight = $portalRootRect.width - panelMargin;\n\t\t\t\tconst parentBottom = $portalRootRect.height - panelMargin;\n\t\t\t\tconst panelLeft = x;\n\t\t\t\tconst panelTop = y;\n\t\t\t\tconst panelRight = panelLeft + panelSize.width;\n\t\t\t\tconst panelBottom = panelTop + panelSize.height;\n\n\t\t\t\t// move to right\n\t\t\t\tif (panelLeft < parentLeft) {\n\t\t\t\t\t$$invalidate(37, shift.x = panelLeft - parentLeft, shift);\n\t\t\t\t\tx = parentLeft;\n\t\t\t\t}\n\n\t\t\t\t// move to left\n\t\t\t\tif (panelRight > parentRight) {\n\t\t\t\t\t$$invalidate(37, shift.x = panelRight - parentRight, shift);\n\t\t\t\t\tx = parentRight - panelSize.width;\n\t\t\t\t}\n\n\t\t\t\tif (panelBottom > parentBottom) {\n\t\t\t\t\t// doesn't fit vertically, push up\n\t\t\t\t\t$$invalidate(36, dir.y = -1, dir);\n\n\t\t\t\t\tconst positionedAboveButtonY = y - panelSize.height - buttonRect.height;\n\t\t\t\t\tconst panelFitsAboveButton = parentTop < positionedAboveButtonY;\n\n\t\t\t\t\tif (panelFitsAboveButton) {\n\t\t\t\t\t\t$$invalidate(37, shift.y = 0, shift);\n\t\t\t\t\t\ty -= panelSize.height + buttonRect.height;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// overlap with button\n\t\t\t\t\t\t$$invalidate(37, shift.y = y - (panelBottom - parentBottom), shift);\n\n\t\t\t\t\t\ty -= panelBottom - parentBottom - panelMargin;\n\t\t\t\t\t\t$$invalidate(38, showPanelTip = false);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// all is fine\n\t\t\t\t\t$$invalidate(36, dir.y = 1, dir);\n\t\t\t\t}\n\n\t\t\t\tset_store_value(position, $position = vectorApply(vectorCreate(x, y), snapToPixel), $position);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$opacity*/ 262144) {\n\t\t\t$$invalidate(6, isVisible = $opacity > 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$position, dir, $offset*/ 589856) {\n\t\t\t$$invalidate(45, transform = `translateX(${Math.round($position.x) + dir.x * panelMargin}px) translateY(${Math.round($position.y) + dir.y * panelMargin + dir.y * $offset}px)`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$opacity*/ 262144) {\n\t\t\t$$invalidate(18, styleOpacity = $opacity);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$opacity*/ 262144) {\n\t\t\t$$invalidate(17, stylePointerEvents = $opacity < 1 ? 'none' : 'all');\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*transform*/ 16384) {\n\t\t\t$$invalidate(16, styleTransform = transform);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$portalRootRect*/ 131072) {\n\t\t\t$$invalidate(15, styleMaxHeight = `${$portalRootRect.height - panelMargin * 2}px`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*offsetProgress*/ 8192) {\n\t\t\t$$invalidate(42, tipScale = 0.5 + offsetProgress * 0.5);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*offsetProgress*/ 8192) {\n\t\t\t$$invalidate(43, tipOpacity = offsetProgress);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*panelSize*/ 8 | $$self.$$.dirty[1] & /*$position*/ 65536) {\n\t\t\t$$invalidate(41, styleTip = panelSize && $position);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*styleTip, showPanelTip, tipOpacity*/ 5248) {\n\t\t\t$$invalidate(14, styleTipOpacity = styleTip && showPanelTip ? tipOpacity : 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*styleTip, tipScale*/ 3072) {\n\t\t\t$$invalidate(13, styleTipTransform = styleTip ? `scaleX(${tipScale})rotate(45deg)` : 'none');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*panelSize*/ 8 | $$self.$$.dirty[1] & /*styleTip, dir, shift*/ 1120) {\n\t\t\t$$invalidate(12, styleTipTop = styleTip\n\t\t\t? `${dir.y < 0 ? shift.y + panelSize.height : 0}px`\n\t\t\t: '0');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*panelSize*/ 8 | $$self.$$.dirty[1] & /*styleTip, shift*/ 1088) {\n\t\t\t$$invalidate(11, styleTipLeft = styleTip ? `${shift.x + panelSize.width * 0.5}px` : '0');\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*dir*/ 32) {\n\t\t\t$$invalidate(10, dataTop = dir.y >= 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive*/ 1) {\n\t\t\t$$invalidate(9, handleDown = isActive\n\t\t\t? e => {\n\t\t\t\t\tif (isTargetSelf(e)) return;\n\t\t\t\t\t$$invalidate(39, downOutsidePanel = true);\n\t\t\t\t}\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isVisible, detailPanel*/ 96 | $$self.$$.dirty[1] & /*$portal*/ 32768) {\n\t\t\tif (isVisible && $portal && detailPanel && detailPanel.parentNode !== $portal) $portal.append(detailPanel);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive*/ 1) {\n\t\t\tif (!isActive) {\n\t\t\t\t$$invalidate(40, trigger = undefined);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isActive, isVisible, detailPanel*/ 97 | $$self.$$.dirty[1] & /*onshow, trigger*/ 514) {\n\t\t\tif (isActive && isVisible && detailPanel) {\n\t\t\t\tlet preventFocus = false;\n\n\t\t\t\tonshow({\n\t\t\t\t\te: trigger,\n\t\t\t\t\tpanel: detailPanel,\n\t\t\t\t\tpreventFocus() {\n\t\t\t\t\t\tpreventFocus = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// if focus wasn't prevented we move focus to the panel itself\n\t\t\t\tif (!preventFocus) {\n\t\t\t\t\tfocus(detailPanel, { preventScroll: true });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isVisible, isActive*/ 65 | $$self.$$.dirty[1] & /*onhide*/ 4) {\n\t\t\tif (isVisible && !isActive) {\n\t\t\t\tonhide();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*buttonLabel, buttonIcon, buttonClass, buttonHideLabel, buttonLabelClass, buttonTitle*/ 2080374786) {\n\t\t\t// calculate button props for both types of buttons\n\t\t\t$$invalidate(7, buttonProps = {\n\t\t\t\tlabel: buttonLabel,\n\t\t\t\ticon: buttonIcon,\n\t\t\t\tclass: arrayJoin(['PinturaPanelButton', buttonClass]),\n\t\t\t\tonkeydown: handleButtonKeydown,\n\t\t\t\tonclick: handleClick,\n\t\t\t\thideLabel: buttonHideLabel,\n\t\t\t\tlabelClass: buttonLabelClass,\n\t\t\t\ttitle: buttonTitle\n\t\t\t});\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tbuttonLabel,\n\t\tpanelClass,\n\t\tpanelSize,\n\t\tbuttonComponent,\n\t\tdetailPanel,\n\t\tisVisible,\n\t\tbuttonProps,\n\t\thandleUp,\n\t\thandleDown,\n\t\tdataTop,\n\t\tstyleTipLeft,\n\t\tstyleTipTop,\n\t\tstyleTipTransform,\n\t\tstyleTipOpacity,\n\t\tstyleMaxHeight,\n\t\tstyleTransform,\n\t\tstylePointerEvents,\n\t\tstyleOpacity,\n\t\tisAnimated,\n\t\tportal,\n\t\tportalRootRect,\n\t\topacity,\n\t\tposition,\n\t\toffset,\n\t\thandlePanelKeydown,\n\t\tbuttonClass,\n\t\tbuttonLabelClass,\n\t\tbuttonHideLabel,\n\t\tbuttonIcon,\n\t\tbuttonTitle,\n\t\tbuttonOnClick,\n\t\tonshow,\n\t\tonhide,\n\t\tcanConfirm,\n\t\tbuttonRect,\n\t\tdir,\n\t\tshift,\n\t\tshowPanelTip,\n\t\tdownOutsidePanel,\n\t\ttrigger,\n\t\tstyleTip,\n\t\ttipScale,\n\t\ttipOpacity,\n\t\toffsetProgress,\n\t\ttransform,\n\t\t$portal,\n\t\t$position,\n\t\t$portalRootRect,\n\t\t$opacity,\n\t\t$offset,\n\t\t$isAnimated,\n\t\tslots,\n\t\tbutton_binding,\n\t\tbutton_binding_1,\n\t\tdiv_binding,\n\t\tclose_handler,\n\t\tmeasure_handler,\n\t\t$$scope\n\t];\n}\n\nclass Panel extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$N,\n\t\t\tcreate_fragment$M,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tbuttonClass: 26,\n\t\t\t\tbuttonLabel: 1,\n\t\t\t\tbuttonLabelClass: 27,\n\t\t\t\tbuttonHideLabel: 28,\n\t\t\t\tbuttonIcon: 29,\n\t\t\t\tbuttonTitle: 30,\n\t\t\t\tbuttonOnClick: 31,\n\t\t\t\tpanelClass: 2,\n\t\t\t\tisActive: 0,\n\t\t\t\tonshow: 32,\n\t\t\t\tonhide: 33,\n\t\t\t\tcanConfirm: 34\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1]\n\t\t);\n\t}\n}\n\nvar ArrowKeys = {\n    Up: 38,\n    Down: 40,\n    Left: 37,\n    Right: 39,\n};\n\n/* src/core/ui/components/RadioItem.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$L(ctx) {\n\tlet li;\n\tlet input;\n\tlet t;\n\tlet label_1;\n\tlet li_class_value;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[16].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[15], null);\n\n\treturn {\n\t\tc() {\n\t\t\tli = element(\"li\");\n\t\t\tinput = element(\"input\");\n\t\t\tt = space();\n\t\t\tlabel_1 = element(\"label\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tattr(input, \"type\", \"radio\");\n\t\t\tattr(input, \"class\", \"implicit\");\n\t\t\tattr(input, \"id\", /*inputId*/ ctx[7]);\n\t\t\tattr(input, \"name\", /*name*/ ctx[0]);\n\t\t\tinput.value = /*value*/ ctx[3];\n\t\t\tinput.disabled = /*disabled*/ ctx[6];\n\t\t\tinput.hidden = /*hidden*/ ctx[5];\n\t\t\tinput.checked = /*checked*/ ctx[4];\n\t\t\tattr(label_1, \"for\", /*inputId*/ ctx[7]);\n\t\t\tattr(label_1, \"title\", /*title*/ ctx[2]);\n\t\t\tattr(li, \"class\", li_class_value = arrayJoin(['PinturaRadioGroupOption', /*klass*/ ctx[1]]));\n\t\t\tattr(li, \"data-hidden\", /*hidden*/ ctx[5]);\n\t\t\tattr(li, \"data-disabled\", /*disabled*/ ctx[6]);\n\t\t\tattr(li, \"data-selected\", /*checked*/ ctx[4]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, li, anchor);\n\t\t\tappend(li, input);\n\t\t\tappend(li, t);\n\t\t\tappend(li, label_1);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(label_1, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(input, \"change\", stop_propagation(/*change_handler*/ ctx[17])),\n\t\t\t\t\tlisten(input, \"keydown\", /*handleKeydown*/ ctx[9]),\n\t\t\t\t\tlisten(input, \"click\", /*handleClick*/ ctx[10])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (!current || dirty & /*inputId*/ 128) {\n\t\t\t\tattr(input, \"id\", /*inputId*/ ctx[7]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*name*/ 1) {\n\t\t\t\tattr(input, \"name\", /*name*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*value*/ 8) {\n\t\t\t\tinput.value = /*value*/ ctx[3];\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*disabled*/ 64) {\n\t\t\t\tinput.disabled = /*disabled*/ ctx[6];\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*hidden*/ 32) {\n\t\t\t\tinput.hidden = /*hidden*/ ctx[5];\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*checked*/ 16) {\n\t\t\t\tinput.checked = /*checked*/ ctx[4];\n\t\t\t}\n\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope*/ 32768)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[15],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[15])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[15], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*inputId*/ 128) {\n\t\t\t\tattr(label_1, \"for\", /*inputId*/ ctx[7]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*title*/ 4) {\n\t\t\t\tattr(label_1, \"title\", /*title*/ ctx[2]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*klass*/ 2 && li_class_value !== (li_class_value = arrayJoin(['PinturaRadioGroupOption', /*klass*/ ctx[1]]))) {\n\t\t\t\tattr(li, \"class\", li_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*hidden*/ 32) {\n\t\t\t\tattr(li, \"data-hidden\", /*hidden*/ ctx[5]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*disabled*/ 64) {\n\t\t\t\tattr(li, \"data-disabled\", /*disabled*/ ctx[6]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*checked*/ 16) {\n\t\t\t\tattr(li, \"data-selected\", /*checked*/ ctx[4]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(li);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$M($$self, $$props, $$invalidate) {\n\tlet inputId;\n\tlet $keysPressedStored;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { name } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\tlet { label } = $$props;\n\tlet { title = undefined } = $$props;\n\tlet { id } = $$props;\n\tlet { value } = $$props;\n\tlet { checked } = $$props;\n\tlet { onkeydown } = $$props;\n\tlet { onclick } = $$props;\n\tlet { hidden = false } = $$props;\n\tlet { disabled = false } = $$props;\n\tconst ArrowKeyCodes = Object.values(ArrowKeys);\n\tconst keysPressedStored = getContext('keysPressed');\n\tcomponent_subscribe($$self, keysPressedStored, value => $$invalidate(18, $keysPressedStored = value));\n\n\tconst handleKeydown = e => {\n\t\tonkeydown(e);\n\t};\n\n\tconst handleClick = e => {\n\t\t// if pressed arrow key -> ignore so navigation with arrow keys works\n\t\tif ($keysPressedStored.some(key => ArrowKeyCodes.includes(key))) return;\n\n\t\t// just a normal click\n\t\tonclick(e);\n\t};\n\n\tfunction change_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('name' in $$props) $$invalidate(0, name = $$props.name);\n\t\tif ('class' in $$props) $$invalidate(1, klass = $$props.class);\n\t\tif ('label' in $$props) $$invalidate(11, label = $$props.label);\n\t\tif ('title' in $$props) $$invalidate(2, title = $$props.title);\n\t\tif ('id' in $$props) $$invalidate(12, id = $$props.id);\n\t\tif ('value' in $$props) $$invalidate(3, value = $$props.value);\n\t\tif ('checked' in $$props) $$invalidate(4, checked = $$props.checked);\n\t\tif ('onkeydown' in $$props) $$invalidate(13, onkeydown = $$props.onkeydown);\n\t\tif ('onclick' in $$props) $$invalidate(14, onclick = $$props.onclick);\n\t\tif ('hidden' in $$props) $$invalidate(5, hidden = $$props.hidden);\n\t\tif ('disabled' in $$props) $$invalidate(6, disabled = $$props.disabled);\n\t\tif ('$$scope' in $$props) $$invalidate(15, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*name, id*/ 4097) {\n\t\t\t$$invalidate(7, inputId = `${name}-${id}`);\n\t\t}\n\t};\n\n\treturn [\n\t\tname,\n\t\tklass,\n\t\ttitle,\n\t\tvalue,\n\t\tchecked,\n\t\thidden,\n\t\tdisabled,\n\t\tinputId,\n\t\tkeysPressedStored,\n\t\thandleKeydown,\n\t\thandleClick,\n\t\tlabel,\n\t\tid,\n\t\tonkeydown,\n\t\tonclick,\n\t\t$$scope,\n\t\tslots,\n\t\tchange_handler\n\t];\n}\n\nclass RadioItem extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$M, create_fragment$L, safe_not_equal, {\n\t\t\tname: 0,\n\t\t\tclass: 1,\n\t\t\tlabel: 11,\n\t\t\ttitle: 2,\n\t\t\tid: 12,\n\t\t\tvalue: 3,\n\t\t\tchecked: 4,\n\t\t\tonkeydown: 13,\n\t\t\tonclick: 14,\n\t\t\thidden: 5,\n\t\t\tdisabled: 6\n\t\t});\n\t}\n}\n\nvar flattenOptions = (options = []) => options.reduce((prev, current) => {\n    const isGroup = isArray(current) ? isArray(current[1]) : !!current.options;\n    if (isGroup) {\n        return prev.concat(isArray(current) ? current[1] : current.options);\n    }\n    prev.push(current);\n    return prev;\n}, []);\n\nconst mapOption = (option, index, optionMapper) => {\n    let mappedOption;\n    if (isArray(option)) {\n        mappedOption = {\n            id: index,\n            value: option[0],\n            label: option[1],\n            ...(option[2] || {}),\n        };\n    }\n    else {\n        mappedOption = option;\n        mappedOption.id = mappedOption.id != null ? mappedOption.id : index;\n    }\n    return optionMapper ? optionMapper(mappedOption) : mappedOption;\n};\nvar mapOptions = (options = [], optionMapper) => {\n    let index = 0;\n    return options.map((option) => {\n        index++;\n        if (isArray(option)) {\n            // is either [label, options] or [value, label]\n            if (isArray(option[1])) {\n                return {\n                    id: index,\n                    label: option[0],\n                    options: option[1].map((option) => mapOption(option, ++index, optionMapper)),\n                };\n            }\n            return mapOption(option, index, optionMapper);\n        }\n        else {\n            // is either { id?, label, options } or { id?, value, label }\n            if (option.options) {\n                return {\n                    id: option.id || index,\n                    label: option.label,\n                    options: option.options.map((option) => mapOption(option, ++index, optionMapper)),\n                };\n            }\n            return mapOption(option, index, optionMapper);\n        }\n    });\n};\n\nvar opop = (fn, ...args) => fn && fn(...args);\n\nvar localize = (prop, locale, params) => isFunction(prop) ? prop(locale, params) : prop;\n\nconst localizeOptions = (options, locale) => options.map(([value, label, props]) => {\n    if (isArray(label)) {\n        return [localize(value, locale), localizeOptions(label, locale)];\n    }\n    else {\n        const res = [value, localize(label, locale)];\n        if (props) {\n            let obj = { ...props };\n            if (props.icon)\n                obj.icon = localize(props.icon, locale);\n            res.push(obj);\n        }\n        return res;\n    }\n});\nvar localizeOptions$1 = (options, locale) => localizeOptions(options, locale);\n\nvar isConfirmKey = (key) => /enter| /i.test(key);\n\nvar isDeepEqual = (a, b) => {\n    if (Array.isArray(a) && Array.isArray(b))\n        return arrayEqual(a, b);\n    return a === b;\n};\n\n/* src/core/ui/components/RadioGroup.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context$5(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[27] = list[i];\n\treturn child_ctx;\n}\n\nconst get_option_slot_changes_1 = dirty => ({\n\toption: dirty[0] & /*mappedOptions*/ 1024\n});\n\nconst get_option_slot_context_1 = ctx => ({ option: /*option*/ ctx[27] });\n\nfunction get_each_context_1(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[27] = list[i];\n\treturn child_ctx;\n}\n\nconst get_option_slot_changes = dirty => ({\n\toption: dirty[0] & /*mappedOptions*/ 1024\n});\n\nconst get_option_slot_context = ctx => ({ option: /*option*/ ctx[27] });\n\nconst get_group_slot_changes = dirty => ({\n\toption: dirty[0] & /*mappedOptions*/ 1024\n});\n\nconst get_group_slot_context = ctx => ({ option: /*option*/ ctx[27] });\n\n// (78:0) {#if localizedOptions.length}\nfunction create_if_block_1$f(ctx) {\n\tlet fieldset;\n\tlet t;\n\tlet ul;\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet fieldset_class_value;\n\tlet current;\n\tlet if_block = /*label*/ ctx[1] && create_if_block_7$2(ctx);\n\tlet each_value = ensure_array_like(/*mappedOptions*/ ctx[10]);\n\tconst get_key = ctx => /*option*/ ctx[27].id;\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$5(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$5(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tfieldset = element(\"fieldset\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tt = space();\n\t\t\tul = element(\"ul\");\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tattr(ul, \"class\", \"PinturaRadioGroupOptions\");\n\t\t\tattr(fieldset, \"class\", fieldset_class_value = arrayJoin(['PinturaRadioGroup', /*klass*/ ctx[3]]));\n\t\t\tattr(fieldset, \"data-layout\", /*layout*/ ctx[5]);\n\t\t\tattr(fieldset, \"title\", /*title*/ ctx[7]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, fieldset, anchor);\n\t\t\tif (if_block) if_block.m(fieldset, null);\n\t\t\tappend(fieldset, t);\n\t\t\tappend(fieldset, ul);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(ul, null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*label*/ ctx[1]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_7$2(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(fieldset, t);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*optionGroupClass, mappedOptions, name, optionClass, getOptionIndex, selectedIndex, handleRadioKeydown, handleRadioClick, optionLabelClass, $$scope*/ 8419153) {\n\t\t\t\teach_value = ensure_array_like(/*mappedOptions*/ ctx[10]);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$5, null, get_each_context$5);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*klass*/ 8 && fieldset_class_value !== (fieldset_class_value = arrayJoin(['PinturaRadioGroup', /*klass*/ ctx[3]]))) {\n\t\t\t\tattr(fieldset, \"class\", fieldset_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*layout*/ 32) {\n\t\t\t\tattr(fieldset, \"data-layout\", /*layout*/ ctx[5]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*title*/ 128) {\n\t\t\t\tattr(fieldset, \"title\", /*title*/ ctx[7]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(fieldset);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d();\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (80:8) {#if label}\nfunction create_if_block_7$2(ctx) {\n\tlet legend;\n\tlet t;\n\tlet legend_class_value;\n\n\treturn {\n\t\tc() {\n\t\t\tlegend = element(\"legend\");\n\t\t\tt = text(/*label*/ ctx[1]);\n\t\t\tattr(legend, \"class\", legend_class_value = /*hideLabel*/ ctx[2] && 'implicit');\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, legend, anchor);\n\t\t\tappend(legend, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*label*/ 2) set_data(t, /*label*/ ctx[1]);\n\n\t\t\tif (dirty[0] & /*hideLabel*/ 4 && legend_class_value !== (legend_class_value = /*hideLabel*/ ctx[2] && 'implicit')) {\n\t\t\t\tattr(legend, \"class\", legend_class_value);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(legend);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (119:16) {:else}\nfunction create_else_block$9(ctx) {\n\tlet radioitem;\n\tlet current;\n\n\tradioitem = new RadioItem({\n\t\t\tprops: {\n\t\t\t\tname: /*name*/ ctx[4],\n\t\t\t\tlabel: /*option*/ ctx[27].label,\n\t\t\t\ttitle: /*option*/ ctx[27].hideLabel\n\t\t\t\t? /*option*/ ctx[27].title || /*option*/ ctx[27].label\n\t\t\t\t: /*option*/ ctx[27].title,\n\t\t\t\tid: /*option*/ ctx[27].id,\n\t\t\t\tvalue: /*option*/ ctx[27].value,\n\t\t\t\tdisabled: /*option*/ ctx[27].disabled,\n\t\t\t\thidden: /*option*/ ctx[27].hidden,\n\t\t\t\tclass: /*optionClass*/ ctx[8],\n\t\t\t\tchecked: /*getOptionIndex*/ ctx[12](/*option*/ ctx[27]) === /*selectedIndex*/ ctx[0],\n\t\t\t\tonkeydown: /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[27]),\n\t\t\t\tonclick: /*handleRadioClick*/ ctx[14](/*option*/ ctx[27]),\n\t\t\t\t$$slots: { default: [create_default_slot_2$5] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radioitem.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radioitem, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radioitem_changes = {};\n\t\t\tif (dirty[0] & /*name*/ 16) radioitem_changes.name = /*name*/ ctx[4];\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.label = /*option*/ ctx[27].label;\n\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.title = /*option*/ ctx[27].hideLabel\n\t\t\t? /*option*/ ctx[27].title || /*option*/ ctx[27].label\n\t\t\t: /*option*/ ctx[27].title;\n\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.id = /*option*/ ctx[27].id;\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.value = /*option*/ ctx[27].value;\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.disabled = /*option*/ ctx[27].disabled;\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.hidden = /*option*/ ctx[27].hidden;\n\t\t\tif (dirty[0] & /*optionClass*/ 256) radioitem_changes.class = /*optionClass*/ ctx[8];\n\t\t\tif (dirty[0] & /*mappedOptions, selectedIndex*/ 1025) radioitem_changes.checked = /*getOptionIndex*/ ctx[12](/*option*/ ctx[27]) === /*selectedIndex*/ ctx[0];\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.onkeydown = /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[27]);\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.onclick = /*handleRadioClick*/ ctx[14](/*option*/ ctx[27]);\n\n\t\t\tif (dirty[0] & /*$$scope, optionLabelClass, mappedOptions*/ 8389696) {\n\t\t\t\tradioitem_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradioitem.$set(radioitem_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radioitem.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radioitem.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radioitem, detaching);\n\t\t}\n\t};\n}\n\n// (85:16) {#if option.options}\nfunction create_if_block_2$b(ctx) {\n\tlet li;\n\tlet t0;\n\tlet ul;\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet t1;\n\tlet li_class_value;\n\tlet current;\n\tconst group_slot_template = /*#slots*/ ctx[22].group;\n\tconst group_slot = create_slot(group_slot_template, ctx, /*$$scope*/ ctx[23], get_group_slot_context);\n\tconst group_slot_or_fallback = group_slot || fallback_block_1(ctx);\n\tlet each_value_1 = ensure_array_like(/*option*/ ctx[27].options);\n\tconst get_key = ctx => /*option*/ ctx[27].id;\n\n\tfor (let i = 0; i < each_value_1.length; i += 1) {\n\t\tlet child_ctx = get_each_context_1(ctx, each_value_1, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block_1(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tli = element(\"li\");\n\t\t\tif (group_slot_or_fallback) group_slot_or_fallback.c();\n\t\t\tt0 = space();\n\t\t\tul = element(\"ul\");\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tt1 = space();\n\t\t\tattr(ul, \"class\", \"PinturaRadioGroupOptions\");\n\t\t\tattr(li, \"class\", li_class_value = arrayJoin(['PinturaRadioGroupOptionGroup', /*optionGroupClass*/ ctx[9]]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, li, anchor);\n\n\t\t\tif (group_slot_or_fallback) {\n\t\t\t\tgroup_slot_or_fallback.m(li, null);\n\t\t\t}\n\n\t\t\tappend(li, t0);\n\t\t\tappend(li, ul);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(ul, null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tappend(li, t1);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (group_slot) {\n\t\t\t\tif (group_slot.p && (!current || dirty[0] & /*$$scope, mappedOptions*/ 8389632)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tgroup_slot,\n\t\t\t\t\t\tgroup_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[23],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[23])\n\t\t\t\t\t\t: get_slot_changes(group_slot_template, /*$$scope*/ ctx[23], dirty, get_group_slot_changes),\n\t\t\t\t\t\tget_group_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (group_slot_or_fallback && group_slot_or_fallback.p && (!current || dirty[0] & /*mappedOptions*/ 1024)) {\n\t\t\t\t\tgroup_slot_or_fallback.p(ctx, !current ? [-1, -1] : dirty);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*name, mappedOptions, optionClass, getOptionIndex, selectedIndex, handleRadioKeydown, handleRadioClick, optionLabelClass, $$scope*/ 8418641) {\n\t\t\t\teach_value_1 = ensure_array_like(/*option*/ ctx[27].options);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value_1, each_1_lookup, ul, outro_and_destroy_block, create_each_block_1, null, get_each_context_1);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*optionGroupClass*/ 512 && li_class_value !== (li_class_value = arrayJoin(['PinturaRadioGroupOptionGroup', /*optionGroupClass*/ ctx[9]]))) {\n\t\t\t\tattr(li, \"class\", li_class_value);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(group_slot_or_fallback, local);\n\n\t\t\tfor (let i = 0; i < each_value_1.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(group_slot_or_fallback, local);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(li);\n\t\t\t}\n\n\t\t\tif (group_slot_or_fallback) group_slot_or_fallback.d(detaching);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d();\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (133:28) {#if option.icon}\nfunction create_if_block_6$4(ctx) {\n\tlet icon;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_3$3] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty[0] & /*$$scope, mappedOptions*/ 8389632) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (134:32) <Icon>\nfunction create_default_slot_3$3(ctx) {\n\tlet g;\n\tlet raw_value = /*option*/ ctx[27].icon + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024 && raw_value !== (raw_value = /*option*/ ctx[27].icon + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (136:28) {#if !option.hideLabel}\nfunction create_if_block_5$5(ctx) {\n\tlet span;\n\tlet t_value = /*option*/ ctx[27].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"class\", /*optionLabelClass*/ ctx[6]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024 && t_value !== (t_value = /*option*/ ctx[27].label + \"\")) set_data(t, t_value);\n\n\t\t\tif (dirty[0] & /*optionLabelClass*/ 64) {\n\t\t\t\tattr(span, \"class\", /*optionLabelClass*/ ctx[6]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (132:54)                              \nfunction fallback_block_2(ctx) {\n\tlet t0;\n\tlet t1;\n\tlet current;\n\tlet if_block0 = /*option*/ ctx[27].icon && create_if_block_6$4(ctx);\n\tlet if_block1 = !/*option*/ ctx[27].hideLabel && create_if_block_5$5(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt1 = space();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t0, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*option*/ ctx[27].icon) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_6$4(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t0.parentNode, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!/*option*/ ctx[27].hideLabel) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_5$5(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(t1.parentNode, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(t1);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (120:20) <RadioItem                         {name}                         label={option.label}                         title={option.hideLabel ? option.title || option.label : option.title}                         id={option.id}                         value={option.value}                         disabled={option.disabled}                         hidden={option.hidden}                         class={optionClass}                         checked={getOptionIndex(option) === selectedIndex}                         onkeydown={handleRadioKeydown(option)}                         onclick={handleRadioClick(option)}                         >\nfunction create_default_slot_2$5(ctx) {\n\tlet current;\n\tconst option_slot_template = /*#slots*/ ctx[22].option;\n\tconst option_slot = create_slot(option_slot_template, ctx, /*$$scope*/ ctx[23], get_option_slot_context_1);\n\tconst option_slot_or_fallback = option_slot || fallback_block_2(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (option_slot_or_fallback) option_slot_or_fallback.c();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (option_slot_or_fallback) {\n\t\t\t\toption_slot_or_fallback.m(target, anchor);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (option_slot) {\n\t\t\t\tif (option_slot.p && (!current || dirty[0] & /*$$scope, mappedOptions*/ 8389632)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\toption_slot,\n\t\t\t\t\t\toption_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[23],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[23])\n\t\t\t\t\t\t: get_slot_changes(option_slot_template, /*$$scope*/ ctx[23], dirty, get_option_slot_changes_1),\n\t\t\t\t\t\tget_option_slot_context_1\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (option_slot_or_fallback && option_slot_or_fallback.p && (!current || dirty[0] & /*optionLabelClass, mappedOptions*/ 1088)) {\n\t\t\t\t\toption_slot_or_fallback.p(ctx, !current ? [-1, -1] : dirty);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(option_slot_or_fallback, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(option_slot_or_fallback, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (option_slot_or_fallback) option_slot_or_fallback.d(detaching);\n\t\t}\n\t};\n}\n\n// (88:29) <span class=\"PinturaRadioGroupOptionGroupLabel\">\nfunction fallback_block_1(ctx) {\n\tlet span;\n\tlet t_value = /*option*/ ctx[27].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"class\", \"PinturaRadioGroupOptionGroupLabel\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024 && t_value !== (t_value = /*option*/ ctx[27].label + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (108:40) {#if option.icon}\nfunction create_if_block_4$7(ctx) {\n\tlet icon;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_1$7] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty[0] & /*$$scope, mappedOptions*/ 8389632) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (109:44) <Icon>\nfunction create_default_slot_1$7(ctx) {\n\tlet g;\n\tlet raw_value = /*option*/ ctx[27].icon + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024 && raw_value !== (raw_value = /*option*/ ctx[27].icon + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (111:40) {#if !option.hideLabel}\nfunction create_if_block_3$8(ctx) {\n\tlet span;\n\tlet t_value = /*option*/ ctx[27].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"class\", /*optionLabelClass*/ ctx[6]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024 && t_value !== (t_value = /*option*/ ctx[27].label + \"\")) set_data(t, t_value);\n\n\t\t\tif (dirty[0] & /*optionLabelClass*/ 64) {\n\t\t\t\tattr(span, \"class\", /*optionLabelClass*/ ctx[6]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (107:66)                                          \nfunction fallback_block$2(ctx) {\n\tlet t0;\n\tlet t1;\n\tlet current;\n\tlet if_block0 = /*option*/ ctx[27].icon && create_if_block_4$7(ctx);\n\tlet if_block1 = !/*option*/ ctx[27].hideLabel && create_if_block_3$8(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt1 = space();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t0, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*option*/ ctx[27].icon) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_4$7(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t0.parentNode, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!/*option*/ ctx[27].hideLabel) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_3$8(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(t1.parentNode, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(t1);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (93:32) <RadioItem                                     {name}                                     label={option.label}                                     title={option.hideLabel                                         ? option.title || option.label                                         : option.title}                                     id={option.id}                                     value={option.value}                                     disabled={option.disabled}                                     hidden={option.hidden}                                     class={optionClass}                                     checked={getOptionIndex(option) === selectedIndex}                                     onkeydown={handleRadioKeydown(option)}                                     onclick={handleRadioClick(option)}                                     >\nfunction create_default_slot$g(ctx) {\n\tlet current;\n\tconst option_slot_template = /*#slots*/ ctx[22].option;\n\tconst option_slot = create_slot(option_slot_template, ctx, /*$$scope*/ ctx[23], get_option_slot_context);\n\tconst option_slot_or_fallback = option_slot || fallback_block$2(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (option_slot_or_fallback) option_slot_or_fallback.c();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (option_slot_or_fallback) {\n\t\t\t\toption_slot_or_fallback.m(target, anchor);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (option_slot) {\n\t\t\t\tif (option_slot.p && (!current || dirty[0] & /*$$scope, mappedOptions*/ 8389632)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\toption_slot,\n\t\t\t\t\t\toption_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[23],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[23])\n\t\t\t\t\t\t: get_slot_changes(option_slot_template, /*$$scope*/ ctx[23], dirty, get_option_slot_changes),\n\t\t\t\t\t\tget_option_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (option_slot_or_fallback && option_slot_or_fallback.p && (!current || dirty[0] & /*optionLabelClass, mappedOptions*/ 1088)) {\n\t\t\t\t\toption_slot_or_fallback.p(ctx, !current ? [-1, -1] : dirty);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(option_slot_or_fallback, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(option_slot_or_fallback, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (option_slot_or_fallback) option_slot_or_fallback.d(detaching);\n\t\t}\n\t};\n}\n\n// (92:28) {#each option.options as option (option.id)}\nfunction create_each_block_1(key_1, ctx) {\n\tlet first;\n\tlet radioitem;\n\tlet current;\n\n\tradioitem = new RadioItem({\n\t\t\tprops: {\n\t\t\t\tname: /*name*/ ctx[4],\n\t\t\t\tlabel: /*option*/ ctx[27].label,\n\t\t\t\ttitle: /*option*/ ctx[27].hideLabel\n\t\t\t\t? /*option*/ ctx[27].title || /*option*/ ctx[27].label\n\t\t\t\t: /*option*/ ctx[27].title,\n\t\t\t\tid: /*option*/ ctx[27].id,\n\t\t\t\tvalue: /*option*/ ctx[27].value,\n\t\t\t\tdisabled: /*option*/ ctx[27].disabled,\n\t\t\t\thidden: /*option*/ ctx[27].hidden,\n\t\t\t\tclass: /*optionClass*/ ctx[8],\n\t\t\t\tchecked: /*getOptionIndex*/ ctx[12](/*option*/ ctx[27]) === /*selectedIndex*/ ctx[0],\n\t\t\t\tonkeydown: /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[27]),\n\t\t\t\tonclick: /*handleRadioClick*/ ctx[14](/*option*/ ctx[27]),\n\t\t\t\t$$slots: { default: [create_default_slot$g] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tkey: key_1,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tfirst = empty();\n\t\t\tcreate_component(radioitem.$$.fragment);\n\t\t\tthis.first = first;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, first, anchor);\n\t\t\tmount_component(radioitem, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tconst radioitem_changes = {};\n\t\t\tif (dirty[0] & /*name*/ 16) radioitem_changes.name = /*name*/ ctx[4];\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.label = /*option*/ ctx[27].label;\n\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.title = /*option*/ ctx[27].hideLabel\n\t\t\t? /*option*/ ctx[27].title || /*option*/ ctx[27].label\n\t\t\t: /*option*/ ctx[27].title;\n\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.id = /*option*/ ctx[27].id;\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.value = /*option*/ ctx[27].value;\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.disabled = /*option*/ ctx[27].disabled;\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.hidden = /*option*/ ctx[27].hidden;\n\t\t\tif (dirty[0] & /*optionClass*/ 256) radioitem_changes.class = /*optionClass*/ ctx[8];\n\t\t\tif (dirty[0] & /*mappedOptions, selectedIndex*/ 1025) radioitem_changes.checked = /*getOptionIndex*/ ctx[12](/*option*/ ctx[27]) === /*selectedIndex*/ ctx[0];\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.onkeydown = /*handleRadioKeydown*/ ctx[13](/*option*/ ctx[27]);\n\t\t\tif (dirty[0] & /*mappedOptions*/ 1024) radioitem_changes.onclick = /*handleRadioClick*/ ctx[14](/*option*/ ctx[27]);\n\n\t\t\tif (dirty[0] & /*$$scope, optionLabelClass, mappedOptions*/ 8389696) {\n\t\t\t\tradioitem_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradioitem.$set(radioitem_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radioitem.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radioitem.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(first);\n\t\t\t}\n\n\t\t\tdestroy_component(radioitem, detaching);\n\t\t}\n\t};\n}\n\n// (84:12) {#each mappedOptions as option (option.id)}\nfunction create_each_block$5(key_1, ctx) {\n\tlet first;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet if_block_anchor;\n\tlet current;\n\tconst if_block_creators = [create_if_block_2$b, create_else_block$9];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*option*/ ctx[27].options) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tkey: key_1,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tfirst = empty();\n\t\t\tif_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t\tthis.first = first;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, first, anchor);\n\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(first);\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$K(ctx) {\n\tlet t;\n\tlet if_block1_anchor;\n\tlet current;\n\tlet if_block0 = /*localizedOptions*/ ctx[11].length && create_if_block_1$f(ctx);\n\tlet if_block1 = false ;\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*localizedOptions*/ ctx[11].length) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*localizedOptions*/ 2048) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_1$f(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance$L($$self, $$props, $$invalidate) {\n\tlet localizedOptions;\n\tlet mappedOptions;\n\tlet flattenedOptions;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tconst dispatch = createEventDispatcher();\n\tlet { label = undefined } = $$props;\n\tlet { hideLabel = true } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\tlet { name = `radio-group-${getUniqueId()}` } = $$props;\n\tlet { selectedIndex = -1 } = $$props;\n\tlet { options = [] } = $$props;\n\tlet { onchange = undefined } = $$props;\n\tlet { layout = undefined } = $$props;\n\tlet { optionMapper = undefined } = $$props;\n\tlet { optionFilter = undefined } = $$props;\n\tlet { value = undefined } = $$props;\n\tlet { optionLabelClass = undefined } = $$props;\n\tlet { title = undefined } = $$props;\n\tlet { locale = undefined } = $$props;\n\tlet { optionClass = undefined } = $$props;\n\tlet { optionGroupClass = undefined } = $$props;\n\tconst getUndefinedOptionIndex = options => options.findIndex(option => option[0] === undefined);\n\tconst getOptionIndex = option => flattenedOptions.findIndex(flattenedOption => flattenedOption.id === option.id);\n\n\tconst changeSelection = (option, e) => {\n\t\t$$invalidate(0, selectedIndex = getOptionIndex(option));\n\t\tconst payload = { index: selectedIndex, ...option };\n\t\topop(onchange, payload, e);\n\t\tdispatch('change', payload);\n\t};\n\n\tconst handleRadioKeydown = option => e => {\n\t\t// is confirm key ([enter] or [space])\n\t\tif (!isConfirmKey(e.key)) return;\n\n\t\tchangeSelection(option, e);\n\t};\n\n\tconst handleRadioClick = option => e => {\n\t\tchangeSelection(option, e);\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('label' in $$props) $$invalidate(1, label = $$props.label);\n\t\tif ('hideLabel' in $$props) $$invalidate(2, hideLabel = $$props.hideLabel);\n\t\tif ('class' in $$props) $$invalidate(3, klass = $$props.class);\n\t\tif ('name' in $$props) $$invalidate(4, name = $$props.name);\n\t\tif ('selectedIndex' in $$props) $$invalidate(0, selectedIndex = $$props.selectedIndex);\n\t\tif ('options' in $$props) $$invalidate(15, options = $$props.options);\n\t\tif ('onchange' in $$props) $$invalidate(16, onchange = $$props.onchange);\n\t\tif ('layout' in $$props) $$invalidate(5, layout = $$props.layout);\n\t\tif ('optionMapper' in $$props) $$invalidate(17, optionMapper = $$props.optionMapper);\n\t\tif ('optionFilter' in $$props) $$invalidate(18, optionFilter = $$props.optionFilter);\n\t\tif ('value' in $$props) $$invalidate(19, value = $$props.value);\n\t\tif ('optionLabelClass' in $$props) $$invalidate(6, optionLabelClass = $$props.optionLabelClass);\n\t\tif ('title' in $$props) $$invalidate(7, title = $$props.title);\n\t\tif ('locale' in $$props) $$invalidate(20, locale = $$props.locale);\n\t\tif ('optionClass' in $$props) $$invalidate(8, optionClass = $$props.optionClass);\n\t\tif ('optionGroupClass' in $$props) $$invalidate(9, optionGroupClass = $$props.optionGroupClass);\n\t\tif ('$$scope' in $$props) $$invalidate(23, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*optionFilter, options, locale*/ 1343488) {\n\t\t\t$$invalidate(11, localizedOptions = localizeOptions$1(optionFilter ? options.filter(optionFilter) : options, locale));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*localizedOptions, optionMapper*/ 133120) {\n\t\t\t$$invalidate(10, mappedOptions = mapOptions(localizedOptions, optionMapper));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*mappedOptions*/ 1024) {\n\t\t\t$$invalidate(21, flattenedOptions = flattenOptions(mappedOptions));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*selectedIndex, flattenedOptions, value, options*/ 2654209) {\n\t\t\t// can optionally pass value to have radio button group try to auto-select the right option\n\t\t\tif (selectedIndex < 0) {\n\t\t\t\t$$invalidate(0, selectedIndex = flattenedOptions.findIndex(option => isDeepEqual(option.value, value)));\n\n\t\t\t\tif (selectedIndex < 0) {\n\t\t\t\t\t$$invalidate(0, selectedIndex = getUndefinedOptionIndex(options));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\treturn [\n\t\tselectedIndex,\n\t\tlabel,\n\t\thideLabel,\n\t\tklass,\n\t\tname,\n\t\tlayout,\n\t\toptionLabelClass,\n\t\ttitle,\n\t\toptionClass,\n\t\toptionGroupClass,\n\t\tmappedOptions,\n\t\tlocalizedOptions,\n\t\tgetOptionIndex,\n\t\thandleRadioKeydown,\n\t\thandleRadioClick,\n\t\toptions,\n\t\tonchange,\n\t\toptionMapper,\n\t\toptionFilter,\n\t\tvalue,\n\t\tlocale,\n\t\tflattenedOptions,\n\t\tslots,\n\t\t$$scope\n\t];\n}\n\nclass RadioGroup extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$L,\n\t\t\tcreate_fragment$K,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tlabel: 1,\n\t\t\t\thideLabel: 2,\n\t\t\t\tclass: 3,\n\t\t\t\tname: 4,\n\t\t\t\tselectedIndex: 0,\n\t\t\t\toptions: 15,\n\t\t\t\tonchange: 16,\n\t\t\t\tlayout: 5,\n\t\t\t\toptionMapper: 17,\n\t\t\t\toptionFilter: 18,\n\t\t\t\tvalue: 19,\n\t\t\t\toptionLabelClass: 6,\n\t\t\t\ttitle: 7,\n\t\t\t\tlocale: 20,\n\t\t\t\toptionClass: 8,\n\t\t\t\toptionGroupClass: 9\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n}\n\n/* src/core/ui/components/Input.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block$k(ctx) {\n\tlet div;\n\tlet button0;\n\tlet t0;\n\tlet button0_aria_label_value;\n\tlet t1;\n\tlet button1;\n\tlet t2;\n\tlet button1_aria_label_value;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tbutton0 = element(\"button\");\n\t\t\tt0 = text(\"\u25B2\");\n\t\t\tt1 = space();\n\t\t\tbutton1 = element(\"button\");\n\t\t\tt2 = text(\"\u25BC\");\n\t\t\tattr(button0, \"type\", \"button\");\n\t\t\tattr(button0, \"tabindex\", \"-1\");\n\t\t\tattr(button0, \"aria-label\", button0_aria_label_value = `increase ${/*title*/ ctx[7]}`);\n\t\t\tattr(button1, \"type\", \"button\");\n\t\t\tattr(button1, \"tabindex\", \"-1\");\n\t\t\tattr(button1, \"aria-label\", button1_aria_label_value = `decrease ${/*title*/ ctx[7]}`);\n\t\t\tattr(div, \"class\", \"PinturaInputSpinners\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, button0);\n\t\t\tappend(button0, t0);\n\t\t\tappend(div, t1);\n\t\t\tappend(div, button1);\n\t\t\tappend(button1, t2);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(button0, \"click\", /*handleIncrease*/ ctx[18]),\n\t\t\t\t\tlisten(button1, \"click\", /*handleDecrease*/ ctx[19])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*title*/ 128 && button0_aria_label_value !== (button0_aria_label_value = `increase ${/*title*/ ctx[7]}`)) {\n\t\t\t\tattr(button0, \"aria-label\", button0_aria_label_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*title*/ 128 && button1_aria_label_value !== (button1_aria_label_value = `decrease ${/*title*/ ctx[7]}`)) {\n\t\t\t\tattr(button1, \"aria-label\", button1_aria_label_value);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$J(ctx) {\n\tlet div;\n\tlet input_1;\n\tlet input_1_value_value;\n\tlet t;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block = /*canSpin*/ ctx[14] && /*enableSpinButtons*/ ctx[9] && create_if_block$k(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tinput_1 = element(\"input\");\n\t\t\tt = space();\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(input_1, \"class\", \"PinturaInputField\");\n\t\t\tattr(input_1, \"title\", /*title*/ ctx[7]);\n\t\t\tattr(input_1, \"type\", /*type*/ ctx[1]);\n\t\t\tattr(input_1, \"min\", /*min*/ ctx[4]);\n\t\t\tattr(input_1, \"max\", /*max*/ ctx[5]);\n\t\t\tattr(input_1, \"step\", /*step*/ ctx[6]);\n\t\t\tattr(input_1, \"inputmode\", /*inputmode*/ ctx[3]);\n\n\t\t\tinput_1.value = input_1_value_value = /*isClamped*/ ctx[12]\n\t\t\t? /*currentValue*/ ctx[15]\n\t\t\t: /*value*/ ctx[0];\n\n\t\t\tattr(input_1, \"placeholder\", /*placeholder*/ ctx[8]);\n\t\t\tattr(input_1, \"maxlength\", /*maxlength*/ ctx[13]);\n\t\t\tinput_1.disabled = /*disabled*/ ctx[2];\n\t\t\tattr(input_1, \"spellcheck\", \"false\");\n\t\t\tattr(input_1, \"autocorrect\", \"off\");\n\t\t\tattr(input_1, \"autocapitalize\", \"off\");\n\n\t\t\tset_style(input_1, \"min-width\", /*maxCharCount*/ ctx[11]\n\t\t\t? `${/*maxCharCount*/ ctx[11]}em`\n\t\t\t: undefined);\n\n\t\t\tattr(div, \"class\", \"PinturaInput\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, input_1);\n\t\t\t/*input_1_binding*/ ctx[30](input_1);\n\t\t\tappend(div, t);\n\t\t\tif (if_block) if_block.m(div, null);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(input_1, \"input\", /*handleInput*/ ctx[17]),\n\t\t\t\t\tlisten(input_1, \"blur\", function () {\n\t\t\t\t\t\tif (is_function(/*isClamped*/ ctx[12] && /*handleBlur*/ ctx[16])) (/*isClamped*/ ctx[12] && /*handleBlur*/ ctx[16]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(input_1, \"keydown\", /*handleKeydown*/ ctx[20]),\n\t\t\t\t\tlisten(input_1, \"keyup\", /*handleKeyup*/ ctx[21])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (dirty[0] & /*title*/ 128) {\n\t\t\t\tattr(input_1, \"title\", /*title*/ ctx[7]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*type*/ 2) {\n\t\t\t\tattr(input_1, \"type\", /*type*/ ctx[1]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*min*/ 16) {\n\t\t\t\tattr(input_1, \"min\", /*min*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*max*/ 32) {\n\t\t\t\tattr(input_1, \"max\", /*max*/ ctx[5]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*step*/ 64) {\n\t\t\t\tattr(input_1, \"step\", /*step*/ ctx[6]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*inputmode*/ 8) {\n\t\t\t\tattr(input_1, \"inputmode\", /*inputmode*/ ctx[3]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*isClamped, currentValue, value*/ 36865 && input_1_value_value !== (input_1_value_value = /*isClamped*/ ctx[12]\n\t\t\t? /*currentValue*/ ctx[15]\n\t\t\t: /*value*/ ctx[0]) && input_1.value !== input_1_value_value) {\n\t\t\t\tinput_1.value = input_1_value_value;\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*placeholder*/ 256) {\n\t\t\t\tattr(input_1, \"placeholder\", /*placeholder*/ ctx[8]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*maxlength*/ 8192) {\n\t\t\t\tattr(input_1, \"maxlength\", /*maxlength*/ ctx[13]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*disabled*/ 4) {\n\t\t\t\tinput_1.disabled = /*disabled*/ ctx[2];\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*maxCharCount*/ 2048) {\n\t\t\t\tset_style(input_1, \"min-width\", /*maxCharCount*/ ctx[11]\n\t\t\t\t? `${/*maxCharCount*/ ctx[11]}em`\n\t\t\t\t: undefined);\n\t\t\t}\n\n\t\t\tif (/*canSpin*/ ctx[14] && /*enableSpinButtons*/ ctx[9]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$k(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\t/*input_1_binding*/ ctx[30](null);\n\t\t\tif (if_block) if_block.d();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$K($$self, $$props, $$invalidate) {\n\tlet isNumberInput;\n\tlet isClamped;\n\tlet isStepped;\n\tlet canSpin;\n\tlet currentValue;\n\tlet maxCharCount;\n\tlet maxlength;\n\tlet { value = undefined } = $$props;\n\tlet { type = 'text' } = $$props;\n\tlet { disabled = false } = $$props;\n\tlet { inputmode = undefined } = $$props;\n\tlet { min = undefined } = $$props;\n\tlet { max = undefined } = $$props;\n\tlet { step = undefined } = $$props;\n\tlet { onchange = noop$1 } = $$props;\n\tlet { onkeydown = noop$1 } = $$props;\n\tlet { onkeyup = noop$1 } = $$props;\n\tlet { title = undefined } = $$props;\n\tlet { stepMultiplier = 10 } = $$props;\n\tlet { placeholder = undefined } = $$props;\n\tlet { enableSpinButtons = true } = $$props;\n\tlet { enableStopPropagation = false } = $$props;\n\tlet input;\n\tlet isShiftPressed;\n\n\tconst getFormattedValue = () => {\n\t\tlet value = input.value;\n\n\t\tif (type === 'number') {\n\t\t\tvalue = inputmode === 'numeric'\n\t\t\t? parseInt(value, 10)\n\t\t\t: parseFloat(value);\n\n\t\t\tif (!isNumber(value) || Number.isNaN(value)) {\n\t\t\t\tvalue = min || 0;\n\t\t\t} else if (isClamped) {\n\t\t\t\tvalue = clamp(value, min, max);\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t};\n\n\tconst handleBlur = () => {\n\t\t// make sure value is valid\n\t\t$$invalidate(27, inputValue = getFormattedValue());\n\n\t\tonchange(value);\n\t};\n\n\tlet inputValue = value;\n\n\tconst handleInput = () => {\n\t\t$$invalidate(27, inputValue = input.value);\n\t\tonchange(getFormattedValue());\n\t};\n\n\tconst handleIncrease = () => {\n\t\tconst newValue = clamp(getFormattedValue() + (isShiftPressed ? step * stepMultiplier : step), min, max);\n\t\tif (newValue === value) return;\n\t\t$$invalidate(27, inputValue = newValue);\n\t\t$$invalidate(0, value = newValue);\n\t\tonchange(value);\n\t};\n\n\tconst handleDecrease = () => {\n\t\tconst newValue = clamp(getFormattedValue() - (isShiftPressed ? step * stepMultiplier : step), min, max);\n\t\tif (newValue === value) return;\n\t\t$$invalidate(27, inputValue = newValue);\n\t\t$$invalidate(0, value = newValue);\n\t\tonchange(value);\n\t};\n\n\tconst handleKeydown = e => {\n\t\tonkeydown(e);\n\t\tif (!canSpin) return;\n\t\tisShiftPressed = e.shiftKey;\n\t\tconst { key } = e;\n\t\tif (enableStopPropagation) e.stopPropagation();\n\t\tif (!(/up|down/i).test(key)) return;\n\t\tif ((/up/i).test(key)) handleIncrease();\n\t\tif ((/down/i).test(key)) handleDecrease();\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t};\n\n\tconst handleKeyup = e => {\n\t\tonkeyup(e);\n\t\tif (!canSpin) return;\n\t\tconst { key } = e;\n\t\tif (!(/up|down/i).test(key)) return;\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t};\n\n\tfunction input_1_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tinput = $$value;\n\t\t\t$$invalidate(10, input);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('value' in $$props) $$invalidate(0, value = $$props.value);\n\t\tif ('type' in $$props) $$invalidate(1, type = $$props.type);\n\t\tif ('disabled' in $$props) $$invalidate(2, disabled = $$props.disabled);\n\t\tif ('inputmode' in $$props) $$invalidate(3, inputmode = $$props.inputmode);\n\t\tif ('min' in $$props) $$invalidate(4, min = $$props.min);\n\t\tif ('max' in $$props) $$invalidate(5, max = $$props.max);\n\t\tif ('step' in $$props) $$invalidate(6, step = $$props.step);\n\t\tif ('onchange' in $$props) $$invalidate(22, onchange = $$props.onchange);\n\t\tif ('onkeydown' in $$props) $$invalidate(23, onkeydown = $$props.onkeydown);\n\t\tif ('onkeyup' in $$props) $$invalidate(24, onkeyup = $$props.onkeyup);\n\t\tif ('title' in $$props) $$invalidate(7, title = $$props.title);\n\t\tif ('stepMultiplier' in $$props) $$invalidate(25, stepMultiplier = $$props.stepMultiplier);\n\t\tif ('placeholder' in $$props) $$invalidate(8, placeholder = $$props.placeholder);\n\t\tif ('enableSpinButtons' in $$props) $$invalidate(9, enableSpinButtons = $$props.enableSpinButtons);\n\t\tif ('enableStopPropagation' in $$props) $$invalidate(26, enableStopPropagation = $$props.enableStopPropagation);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*type*/ 2) {\n\t\t\t$$invalidate(29, isNumberInput = type === 'number');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*min, max*/ 48) {\n\t\t\t$$invalidate(12, isClamped = isNumber(min) && isNumber(max));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*step*/ 64) {\n\t\t\t$$invalidate(28, isStepped = isNumber(step));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isNumberInput, isClamped, isStepped*/ 805310464) {\n\t\t\t$$invalidate(14, canSpin = isNumberInput && isClamped && isStepped);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*input, inputValue, value*/ 134218753) {\n\t\t\t$$invalidate(15, currentValue = input === document.activeElement ? inputValue : value);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*max*/ 32) {\n\t\t\t$$invalidate(11, maxCharCount = max ? (max + '').length : undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*inputmode, maxCharCount*/ 2056) {\n\t\t\t$$invalidate(13, maxlength = inputmode === 'numeric' && maxCharCount\n\t\t\t? maxCharCount\n\t\t\t: undefined);\n\t\t}\n\t};\n\n\treturn [\n\t\tvalue,\n\t\ttype,\n\t\tdisabled,\n\t\tinputmode,\n\t\tmin,\n\t\tmax,\n\t\tstep,\n\t\ttitle,\n\t\tplaceholder,\n\t\tenableSpinButtons,\n\t\tinput,\n\t\tmaxCharCount,\n\t\tisClamped,\n\t\tmaxlength,\n\t\tcanSpin,\n\t\tcurrentValue,\n\t\thandleBlur,\n\t\thandleInput,\n\t\thandleIncrease,\n\t\thandleDecrease,\n\t\thandleKeydown,\n\t\thandleKeyup,\n\t\tonchange,\n\t\tonkeydown,\n\t\tonkeyup,\n\t\tstepMultiplier,\n\t\tenableStopPropagation,\n\t\tinputValue,\n\t\tisStepped,\n\t\tisNumberInput,\n\t\tinput_1_binding\n\t];\n}\n\nclass Input extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$K,\n\t\t\tcreate_fragment$J,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tvalue: 0,\n\t\t\t\ttype: 1,\n\t\t\t\tdisabled: 2,\n\t\t\t\tinputmode: 3,\n\t\t\t\tmin: 4,\n\t\t\t\tmax: 5,\n\t\t\t\tstep: 6,\n\t\t\t\tonchange: 22,\n\t\t\t\tonkeydown: 23,\n\t\t\t\tonkeyup: 24,\n\t\t\t\ttitle: 7,\n\t\t\t\tstepMultiplier: 25,\n\t\t\t\tplaceholder: 8,\n\t\t\t\tenableSpinButtons: 9,\n\t\t\t\tenableStopPropagation: 26\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n}\n\n/* src/core/ui/components/Dropdown.svelte generated by Svelte v4.2.20 */\nconst get_controls_slot_changes = dirty => ({});\nconst get_controls_slot_context = ctx => ({});\n\n// (123:8) {:else}\nfunction create_else_block$8(ctx) {\n\tlet t;\n\tlet span;\n\tlet raw_value = (/*label*/ ctx[2] || /*selectedLabel*/ ctx[21]) + \"\";\n\tlet span_class_value;\n\tlet current;\n\tlet if_block = /*icon*/ ctx[6] && create_if_block_4$6(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block) if_block.c();\n\t\t\tt = space();\n\t\t\tspan = element(\"span\");\n\n\t\t\tattr(span, \"class\", span_class_value = arrayJoin([\n\t\t\t\t'PinturaButtonLabel',\n\t\t\t\t/*labelClass*/ ctx[3],\n\t\t\t\t/*hideLabel*/ ctx[5] && 'implicit'\n\t\t\t]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block) if_block.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tinsert(target, span, anchor);\n\t\t\tspan.innerHTML = raw_value;\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*icon*/ ctx[6]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*icon*/ 64) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_4$6(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif ((!current || dirty[0] & /*label, selectedLabel*/ 2097156) && raw_value !== (raw_value = (/*label*/ ctx[2] || /*selectedLabel*/ ctx[21]) + \"\")) span.innerHTML = raw_value;\n\t\t\tif (!current || dirty[0] & /*labelClass, hideLabel*/ 40 && span_class_value !== (span_class_value = arrayJoin([\n\t\t\t\t'PinturaButtonLabel',\n\t\t\t\t/*labelClass*/ ctx[3],\n\t\t\t\t/*hideLabel*/ ctx[5] && 'implicit'\n\t\t\t]))) {\n\t\t\t\tattr(span, \"class\", span_class_value);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d(detaching);\n\t\t}\n\t};\n}\n\n// (106:8) {#if enableInput}\nfunction create_if_block_3$7(ctx) {\n\tlet input;\n\tlet current;\n\n\tinput = new Input({\n\t\t\tprops: {\n\t\t\t\tvalue: parseFloat(/*value*/ ctx[10]),\n\t\t\t\tonchange: /*onchange*/ ctx[17],\n\t\t\t\tenableStopPropagation: true,\n\t\t\t\ttype: \"number\",\n\t\t\t\tinputmode: \"numeric\",\n\t\t\t\tmin: /*options*/ ctx[8].reduce(/*func*/ ctx[29], Infinity),\n\t\t\t\tmax: /*options*/ ctx[8].reduce(/*func_1*/ ctx[30], -Infinity),\n\t\t\t\tenableSpinButtons: false\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(input.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(input, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst input_changes = {};\n\t\t\tif (dirty[0] & /*value*/ 1024) input_changes.value = parseFloat(/*value*/ ctx[10]);\n\t\t\tif (dirty[0] & /*onchange*/ 131072) input_changes.onchange = /*onchange*/ ctx[17];\n\t\t\tif (dirty[0] & /*options*/ 256) input_changes.min = /*options*/ ctx[8].reduce(/*func*/ ctx[29], Infinity);\n\t\t\tif (dirty[0] & /*options*/ 256) input_changes.max = /*options*/ ctx[8].reduce(/*func_1*/ ctx[30], -Infinity);\n\t\t\tinput.$set(input_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(input.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(input.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(input, detaching);\n\t\t}\n\t};\n}\n\n// (124:12) {#if icon}\nfunction create_if_block_4$6(ctx) {\n\tlet icon_1;\n\tlet current;\n\n\ticon_1 = new Icon({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaButtonIcon\",\n\t\t\t\t$$slots: { default: [create_default_slot_1$6] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon_1.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon_1, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_1_changes = {};\n\n\t\t\tif (dirty[0] & /*icon*/ 64 | dirty[1] & /*$$scope*/ 2) {\n\t\t\t\ticon_1_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon_1.$set(icon_1_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon_1.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon_1.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon_1, detaching);\n\t\t}\n\t};\n}\n\n// (125:16) <Icon class=\"PinturaButtonIcon\">\nfunction create_default_slot_1$6(ctx) {\n\tlet g;\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = /*icon*/ ctx[6];\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*icon*/ 64) g.innerHTML = /*icon*/ ctx[6];\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (102:4) \nfunction create_label_slot$2(ctx) {\n\tlet span;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet span_class_value;\n\tlet current;\n\tconst if_block_creators = [create_if_block_3$7, create_else_block$8];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*enableInput*/ ctx[18]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tif_block.c();\n\t\t\tattr(span, \"slot\", \"label\");\n\n\t\t\tattr(span, \"class\", span_class_value = arrayJoin([\n\t\t\t\t'PinturaButtonInner',\n\t\t\t\t/*enableInput*/ ctx[18] && 'PinturaComboBox',\n\t\t\t\t/*innerClass*/ ctx[4]\n\t\t\t]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tif_blocks[current_block_type_index].m(span, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(span, null);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*enableInput, innerClass*/ 262160 && span_class_value !== (span_class_value = arrayJoin([\n\t\t\t\t'PinturaButtonInner',\n\t\t\t\t/*enableInput*/ ctx[18] && 'PinturaComboBox',\n\t\t\t\t/*innerClass*/ ctx[4]\n\t\t\t]))) {\n\t\t\t\tattr(span, \"class\", span_class_value);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d();\n\t\t}\n\t};\n}\n\n// (148:12) \nfunction create_group_slot$1(ctx) {\n\tlet span;\n\tlet t_value = /*option*/ ctx[34].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"slot\", \"group\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 8 && t_value !== (t_value = /*option*/ ctx[34].label + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (150:16) {#if option.icon}\nfunction create_if_block_2$a(ctx) {\n\tlet icon_1;\n\tlet current;\n\n\ticon_1 = new Icon({\n\t\t\tprops: {\n\t\t\t\tstyle: isFunction(/*optionIconStyle*/ ctx[14])\n\t\t\t\t? /*optionIconStyle*/ ctx[14](/*option*/ ctx[34].value)\n\t\t\t\t: /*optionIconStyle*/ ctx[14],\n\t\t\t\t$$slots: { default: [create_default_slot$f] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon_1.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon_1, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_1_changes = {};\n\n\t\t\tif (dirty[0] & /*optionIconStyle*/ 16384 | dirty[1] & /*option*/ 8) icon_1_changes.style = isFunction(/*optionIconStyle*/ ctx[14])\n\t\t\t? /*optionIconStyle*/ ctx[14](/*option*/ ctx[34].value)\n\t\t\t: /*optionIconStyle*/ ctx[14];\n\n\t\t\tif (dirty[1] & /*$$scope, option*/ 10) {\n\t\t\t\ticon_1_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon_1.$set(icon_1_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon_1.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon_1.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon_1, detaching);\n\t\t}\n\t};\n}\n\n// (151:20) <Icon                         style={isFunction(optionIconStyle)                             ? optionIconStyle(option.value)                             : optionIconStyle}>\nfunction create_default_slot$f(ctx) {\n\tlet g;\n\tlet raw_value = /*option*/ ctx[34].icon + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 8 && raw_value !== (raw_value = /*option*/ ctx[34].icon + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (157:16) {#if !option.hideLabel}\nfunction create_if_block$j(ctx) {\n\tlet span;\n\tlet html_tag;\n\tlet raw_value = /*option*/ ctx[34].label + \"\";\n\tlet t;\n\tlet span_class_value;\n\tlet styleable_action;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block = /*option*/ ctx[34].sublabel && create_if_block_1$e(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\thtml_tag = new HtmlTag(false);\n\t\t\tt = space();\n\t\t\tif (if_block) if_block.c();\n\t\t\thtml_tag.a = t;\n\t\t\tattr(span, \"class\", span_class_value = arrayJoin(['PinturaDropdownOptionLabel', /*optionLabelClass*/ ctx[11]]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\thtml_tag.m(raw_value, span);\n\t\t\tappend(span, t);\n\t\t\tif (if_block) if_block.m(span, null);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = action_destroyer(styleable_action = styleable.call(null, span, isFunction(/*optionLabelStyle*/ ctx[15])\n\t\t\t\t? /*optionLabelStyle*/ ctx[15](/*option*/ ctx[34].value)\n\t\t\t\t: /*optionLabelStyle*/ ctx[15]));\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 8 && raw_value !== (raw_value = /*option*/ ctx[34].label + \"\")) html_tag.p(raw_value);\n\n\t\t\tif (/*option*/ ctx[34].sublabel) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_1$e(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(span, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*optionLabelClass*/ 2048 && span_class_value !== (span_class_value = arrayJoin(['PinturaDropdownOptionLabel', /*optionLabelClass*/ ctx[11]]))) {\n\t\t\t\tattr(span, \"class\", span_class_value);\n\t\t\t}\n\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty[0] & /*optionLabelStyle*/ 32768 | dirty[1] & /*option*/ 8) styleable_action.update.call(null, isFunction(/*optionLabelStyle*/ ctx[15])\n\t\t\t? /*optionLabelStyle*/ ctx[15](/*option*/ ctx[34].value)\n\t\t\t: /*optionLabelStyle*/ ctx[15]);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\n// (165:24) {#if option.sublabel}\nfunction create_if_block_1$e(ctx) {\n\tlet span;\n\tlet raw_value = /*option*/ ctx[34].sublabel + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tattr(span, \"class\", \"PinturaDropdownOptionSublabel\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tspan.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 8 && raw_value !== (raw_value = /*option*/ ctx[34].sublabel + \"\")) span.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (149:12) \nfunction create_option_slot$5(ctx) {\n\tlet span;\n\tlet t;\n\tlet current;\n\tlet if_block0 = /*option*/ ctx[34].icon && create_if_block_2$a(ctx);\n\tlet if_block1 = !/*option*/ ctx[34].hideLabel && create_if_block$j(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(span, \"slot\", \"option\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tif (if_block0) if_block0.m(span, null);\n\t\t\tappend(span, t);\n\t\t\tif (if_block1) if_block1.m(span, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*option*/ ctx[34].icon) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*option*/ 8) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_2$a(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(span, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!/*option*/ ctx[34].hideLabel) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block$j(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(span, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t}\n\t};\n}\n\n// (133:4) \nfunction create_details_slot$3(ctx) {\n\tlet div;\n\tlet t;\n\tlet radiogroup;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst controls_slot_template = /*#slots*/ ctx[28].controls;\n\tconst controls_slot = create_slot(controls_slot_template, ctx, /*$$scope*/ ctx[32], get_controls_slot_context);\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaOptionsList PinturaScrollableContent\",\n\t\t\t\tname: /*name*/ ctx[7],\n\t\t\t\tvalue: /*value*/ ctx[10],\n\t\t\t\tselectedIndex: /*selectedIndex*/ ctx[9],\n\t\t\t\toptionFilter: /*optionFilter*/ ctx[12],\n\t\t\t\toptionMapper: /*optionMapper*/ ctx[13],\n\t\t\t\toptionLabelClass: arrayJoin(['PinturaDropdownOptionLabel', /*optionLabelClass*/ ctx[11]]),\n\t\t\t\toptionGroupClass: \"PinturaListOptionGroup\",\n\t\t\t\toptionClass: \"PinturaListOption\",\n\t\t\t\toptions: /*localizedOptions*/ ctx[19],\n\t\t\t\tonchange: /*handleSelect*/ ctx[22],\n\t\t\t\t$$slots: {\n\t\t\t\t\toption: [\n\t\t\t\t\t\tcreate_option_slot$5,\n\t\t\t\t\t\t({ option }) => ({ 34: option }),\n\t\t\t\t\t\t({ option }) => [0, option ? 8 : 0]\n\t\t\t\t\t],\n\t\t\t\t\tgroup: [\n\t\t\t\t\t\tcreate_group_slot$1,\n\t\t\t\t\t\t({ option }) => ({ 34: option }),\n\t\t\t\t\t\t({ option }) => [0, option ? 8 : 0]\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (controls_slot) controls_slot.c();\n\t\t\tt = space();\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t\tattr(div, \"slot\", \"details\");\n\t\t\tattr(div, \"class\", \"PinturaOptionsListWrapper\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (controls_slot) {\n\t\t\t\tcontrols_slot.m(div, null);\n\t\t\t}\n\n\t\t\tappend(div, t);\n\t\t\tmount_component(radiogroup, div, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = listen(div, \"keydown\", /*handleKeydown*/ ctx[24]);\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (controls_slot) {\n\t\t\t\tif (controls_slot.p && (!current || dirty[1] & /*$$scope*/ 2)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tcontrols_slot,\n\t\t\t\t\t\tcontrols_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[32],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[32])\n\t\t\t\t\t\t: get_slot_changes(controls_slot_template, /*$$scope*/ ctx[32], dirty, get_controls_slot_changes),\n\t\t\t\t\t\tget_controls_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty[0] & /*name*/ 128) radiogroup_changes.name = /*name*/ ctx[7];\n\t\t\tif (dirty[0] & /*value*/ 1024) radiogroup_changes.value = /*value*/ ctx[10];\n\t\t\tif (dirty[0] & /*selectedIndex*/ 512) radiogroup_changes.selectedIndex = /*selectedIndex*/ ctx[9];\n\t\t\tif (dirty[0] & /*optionFilter*/ 4096) radiogroup_changes.optionFilter = /*optionFilter*/ ctx[12];\n\t\t\tif (dirty[0] & /*optionMapper*/ 8192) radiogroup_changes.optionMapper = /*optionMapper*/ ctx[13];\n\t\t\tif (dirty[0] & /*optionLabelClass*/ 2048) radiogroup_changes.optionLabelClass = arrayJoin(['PinturaDropdownOptionLabel', /*optionLabelClass*/ ctx[11]]);\n\t\t\tif (dirty[0] & /*localizedOptions*/ 524288) radiogroup_changes.options = /*localizedOptions*/ ctx[19];\n\n\t\t\tif (dirty[0] & /*optionLabelClass, optionLabelStyle, optionIconStyle*/ 51200 | dirty[1] & /*$$scope, option*/ 10) {\n\t\t\t\tradiogroup_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(controls_slot, local);\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(controls_slot, local);\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (controls_slot) controls_slot.d(detaching);\n\t\t\tdestroy_component(radiogroup);\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\nfunction create_fragment$I(ctx) {\n\tlet panel;\n\tlet updating_isActive;\n\tlet current;\n\n\tfunction panel_isActive_binding(value) {\n\t\t/*panel_isActive_binding*/ ctx[31](value);\n\t}\n\n\tlet panel_props = {\n\t\tonshow: /*handleShowPanel*/ ctx[23],\n\t\tbuttonTitle: toTitle(/*label*/ ctx[2], /*title*/ ctx[1]),\n\t\tbuttonClass: arrayJoin([\n\t\t\t'PinturaDropdownButton',\n\t\t\t/*klass*/ ctx[0],\n\t\t\t/*hideLabel*/ ctx[5] && 'PinturaDropdownIconOnly'\n\t\t]),\n\t\tbuttonOnClick: /*onclick*/ ctx[16],\n\t\t$$slots: {\n\t\t\tdetails: [create_details_slot$3],\n\t\t\tlabel: [create_label_slot$2]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tif (/*dropdownVisible*/ ctx[20] !== void 0) {\n\t\tpanel_props.isActive = /*dropdownVisible*/ ctx[20];\n\t}\n\n\tpanel = new Panel({ props: panel_props });\n\tbinding_callbacks.push(() => bind(panel, 'isActive', panel_isActive_binding));\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(panel.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(panel, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst panel_changes = {};\n\t\t\tif (dirty[0] & /*label, title*/ 6) panel_changes.buttonTitle = toTitle(/*label*/ ctx[2], /*title*/ ctx[1]);\n\n\t\t\tif (dirty[0] & /*klass, hideLabel*/ 33) panel_changes.buttonClass = arrayJoin([\n\t\t\t\t'PinturaDropdownButton',\n\t\t\t\t/*klass*/ ctx[0],\n\t\t\t\t/*hideLabel*/ ctx[5] && 'PinturaDropdownIconOnly'\n\t\t\t]);\n\n\t\t\tif (dirty[0] & /*onclick*/ 65536) panel_changes.buttonOnClick = /*onclick*/ ctx[16];\n\n\t\t\tif (dirty[0] & /*name, value, selectedIndex, optionFilter, optionMapper, optionLabelClass, localizedOptions, optionLabelStyle, optionIconStyle, enableInput, innerClass, onchange, options, labelClass, hideLabel, label, selectedLabel, icon*/ 3080188 | dirty[1] & /*$$scope*/ 2) {\n\t\t\t\tpanel_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tif (!updating_isActive && dirty[0] & /*dropdownVisible*/ 1048576) {\n\t\t\t\tupdating_isActive = true;\n\t\t\t\tpanel_changes.isActive = /*dropdownVisible*/ ctx[20];\n\t\t\t\tadd_flush_callback(() => updating_isActive = false);\n\t\t\t}\n\n\t\t\tpanel.$set(panel_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(panel.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(panel.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(panel, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$J($$self, $$props, $$invalidate) {\n\tlet localizedOptions;\n\tlet selectedLabel;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\tlet { title = undefined } = $$props;\n\tlet { label = undefined } = $$props;\n\tlet { labelClass = undefined } = $$props;\n\tlet { innerClass = undefined } = $$props;\n\tlet { hideLabel = false } = $$props;\n\tlet { icon = undefined } = $$props;\n\tlet { name = undefined } = $$props;\n\tlet { options = [] } = $$props;\n\tlet { selectedIndex = -1 } = $$props;\n\tlet { value = undefined } = $$props;\n\tlet { optionLabelClass = undefined } = $$props;\n\tlet { optionFilter = undefined } = $$props;\n\tlet { optionMapper = undefined } = $$props;\n\tlet { optionIconStyle = undefined } = $$props;\n\tlet { optionLabelStyle = undefined } = $$props;\n\tlet { locale = undefined } = $$props;\n\tlet { onclick = undefined } = $$props;\n\tlet { onchange = noop$1 } = $$props;\n\tlet { onload = noop$1 } = $$props;\n\tlet { ondestroy = noop$1 } = $$props;\n\tlet { enableInput = false } = $$props;\n\n\tconst getUndefinedOptionLabel = options => {\n\t\tconst option = options.find(option => option[0] === undefined);\n\t\tif (!option) return undefined;\n\t\treturn option[1];\n\t};\n\n\tlet dropdownVisible;\n\n\tconst handleSelect = detail => {\n\t\t// triggers label update\n\t\t$$invalidate(21, selectedLabel = detail.value);\n\n\t\t// update value\n\t\tonchange(detail);\n\n\t\t// hide details\n\t\t$$invalidate(20, dropdownVisible = false);\n\t};\n\n\tconst handleShowPanel = ({ e, panel, preventFocus }) => {\n\t\tpreventFocus();\n\n\t\tif (e && e.key && (/up|down/i).test(e.key)) {\n\t\t\treturn focus(panel.querySelector('input:not([disabled])'));\n\t\t}\n\n\t\tfocus(panel.querySelector('fieldset'));\n\t};\n\n\tconst handleKeydown = e => {\n\t\t// don't allow tabbing ([tab] is also blocked in normal <select>)\n\t\tif ((/tab/i).test(e.key)) e.preventDefault();\n\t};\n\n\tonMount(() => onload({ options }));\n\tonDestroy(() => ondestroy({ options }));\n\n\tconst func = (min, [v]) => {\n\t\tv = parseFloat(v);\n\t\treturn v < min ? v : min;\n\t};\n\n\tconst func_1 = (max, [v]) => {\n\t\tv = parseFloat(v);\n\t\treturn v > max ? v : max;\n\t};\n\n\tfunction panel_isActive_binding(value) {\n\t\tdropdownVisible = value;\n\t\t$$invalidate(20, dropdownVisible);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(0, klass = $$props.class);\n\t\tif ('title' in $$props) $$invalidate(1, title = $$props.title);\n\t\tif ('label' in $$props) $$invalidate(2, label = $$props.label);\n\t\tif ('labelClass' in $$props) $$invalidate(3, labelClass = $$props.labelClass);\n\t\tif ('innerClass' in $$props) $$invalidate(4, innerClass = $$props.innerClass);\n\t\tif ('hideLabel' in $$props) $$invalidate(5, hideLabel = $$props.hideLabel);\n\t\tif ('icon' in $$props) $$invalidate(6, icon = $$props.icon);\n\t\tif ('name' in $$props) $$invalidate(7, name = $$props.name);\n\t\tif ('options' in $$props) $$invalidate(8, options = $$props.options);\n\t\tif ('selectedIndex' in $$props) $$invalidate(9, selectedIndex = $$props.selectedIndex);\n\t\tif ('value' in $$props) $$invalidate(10, value = $$props.value);\n\t\tif ('optionLabelClass' in $$props) $$invalidate(11, optionLabelClass = $$props.optionLabelClass);\n\t\tif ('optionFilter' in $$props) $$invalidate(12, optionFilter = $$props.optionFilter);\n\t\tif ('optionMapper' in $$props) $$invalidate(13, optionMapper = $$props.optionMapper);\n\t\tif ('optionIconStyle' in $$props) $$invalidate(14, optionIconStyle = $$props.optionIconStyle);\n\t\tif ('optionLabelStyle' in $$props) $$invalidate(15, optionLabelStyle = $$props.optionLabelStyle);\n\t\tif ('locale' in $$props) $$invalidate(25, locale = $$props.locale);\n\t\tif ('onclick' in $$props) $$invalidate(16, onclick = $$props.onclick);\n\t\tif ('onchange' in $$props) $$invalidate(17, onchange = $$props.onchange);\n\t\tif ('onload' in $$props) $$invalidate(26, onload = $$props.onload);\n\t\tif ('ondestroy' in $$props) $$invalidate(27, ondestroy = $$props.ondestroy);\n\t\tif ('enableInput' in $$props) $$invalidate(18, enableInput = $$props.enableInput);\n\t\tif ('$$scope' in $$props) $$invalidate(32, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*locale, options*/ 33554688) {\n\t\t\t$$invalidate(19, localizedOptions = locale ? localizeOptions$1(options, locale) : options);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*localizedOptions, value*/ 525312) {\n\t\t\t$$invalidate(21, selectedLabel = localizedOptions.reduce(\n\t\t\t\t(prev, curr) => {\n\t\t\t\t\tif (prev) return prev;\n\t\t\t\t\tconst item = Array.isArray(curr) ? curr : [curr, curr];\n\t\t\t\t\tconst [optionValue, optionLabel] = item;\n\t\t\t\t\tif (isDeepEqual(optionValue, value)) return optionLabel;\n\t\t\t\t},\n\t\t\t\tundefined\n\t\t\t) || getUndefinedOptionLabel(localizedOptions) || value);\n\t\t}\n\t};\n\n\treturn [\n\t\tklass,\n\t\ttitle,\n\t\tlabel,\n\t\tlabelClass,\n\t\tinnerClass,\n\t\thideLabel,\n\t\ticon,\n\t\tname,\n\t\toptions,\n\t\tselectedIndex,\n\t\tvalue,\n\t\toptionLabelClass,\n\t\toptionFilter,\n\t\toptionMapper,\n\t\toptionIconStyle,\n\t\toptionLabelStyle,\n\t\tonclick,\n\t\tonchange,\n\t\tenableInput,\n\t\tlocalizedOptions,\n\t\tdropdownVisible,\n\t\tselectedLabel,\n\t\thandleSelect,\n\t\thandleShowPanel,\n\t\thandleKeydown,\n\t\tlocale,\n\t\tonload,\n\t\tondestroy,\n\t\tslots,\n\t\tfunc,\n\t\tfunc_1,\n\t\tpanel_isActive_binding,\n\t\t$$scope\n\t];\n}\n\nclass Dropdown extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$J,\n\t\t\tcreate_fragment$I,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tclass: 0,\n\t\t\t\ttitle: 1,\n\t\t\t\tlabel: 2,\n\t\t\t\tlabelClass: 3,\n\t\t\t\tinnerClass: 4,\n\t\t\t\thideLabel: 5,\n\t\t\t\ticon: 6,\n\t\t\t\tname: 7,\n\t\t\t\toptions: 8,\n\t\t\t\tselectedIndex: 9,\n\t\t\t\tvalue: 10,\n\t\t\t\toptionLabelClass: 11,\n\t\t\t\toptionFilter: 12,\n\t\t\t\toptionMapper: 13,\n\t\t\t\toptionIconStyle: 14,\n\t\t\t\toptionLabelStyle: 15,\n\t\t\t\tlocale: 25,\n\t\t\t\tonclick: 16,\n\t\t\t\tonchange: 17,\n\t\t\t\tonload: 26,\n\t\t\t\tondestroy: 27,\n\t\t\t\tenableInput: 18\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n}\n\n/* src/core/ui/components/DynamicPanel.svelte generated by Svelte v4.2.20 */\n\nfunction create_details_slot$2(ctx) {\n\tlet div;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"slot\", \"details\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\t/*div_binding*/ ctx[14](div);\n\t\t},\n\t\tp: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\t/*div_binding*/ ctx[14](null);\n\t\t}\n\t};\n}\n\nfunction create_fragment$H(ctx) {\n\tlet panel;\n\tlet updating_isActive;\n\tlet current;\n\n\tfunction panel_isActive_binding(value) {\n\t\t/*panel_isActive_binding*/ ctx[15](value);\n\t}\n\n\tlet panel_props = {\n\t\tbuttonLabel: /*buttonLabel*/ ctx[1],\n\t\tbuttonClass: /*buttonClass*/ ctx[2],\n\t\tbuttonIcon: /*buttonIcon*/ ctx[3],\n\t\tbuttonHideLabel: /*buttonHideLabel*/ ctx[4],\n\t\tbuttonTitle: /*buttonTitle*/ ctx[5],\n\t\tbuttonLabelClass: /*buttonLabelClass*/ ctx[6],\n\t\tonshow: /*onshow*/ ctx[7],\n\t\tonhide: /*onhide*/ ctx[8],\n\t\t$$slots: { details: [create_details_slot$2] },\n\t\t$$scope: { ctx }\n\t};\n\n\tif (/*isActive*/ ctx[0] !== void 0) {\n\t\tpanel_props.isActive = /*isActive*/ ctx[0];\n\t}\n\n\tpanel = new Panel({ props: panel_props });\n\tbinding_callbacks.push(() => bind(panel, 'isActive', panel_isActive_binding));\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(panel.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(panel, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tconst panel_changes = {};\n\t\t\tif (dirty & /*buttonLabel*/ 2) panel_changes.buttonLabel = /*buttonLabel*/ ctx[1];\n\t\t\tif (dirty & /*buttonClass*/ 4) panel_changes.buttonClass = /*buttonClass*/ ctx[2];\n\t\t\tif (dirty & /*buttonIcon*/ 8) panel_changes.buttonIcon = /*buttonIcon*/ ctx[3];\n\t\t\tif (dirty & /*buttonHideLabel*/ 16) panel_changes.buttonHideLabel = /*buttonHideLabel*/ ctx[4];\n\t\t\tif (dirty & /*buttonTitle*/ 32) panel_changes.buttonTitle = /*buttonTitle*/ ctx[5];\n\t\t\tif (dirty & /*buttonLabelClass*/ 64) panel_changes.buttonLabelClass = /*buttonLabelClass*/ ctx[6];\n\t\t\tif (dirty & /*onshow*/ 128) panel_changes.onshow = /*onshow*/ ctx[7];\n\t\t\tif (dirty & /*onhide*/ 256) panel_changes.onhide = /*onhide*/ ctx[8];\n\n\t\t\tif (dirty & /*$$scope, container*/ 66048) {\n\t\t\t\tpanel_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tif (!updating_isActive && dirty & /*isActive*/ 1) {\n\t\t\t\tupdating_isActive = true;\n\t\t\t\tpanel_changes.isActive = /*isActive*/ ctx[0];\n\t\t\t\tadd_flush_callback(() => updating_isActive = false);\n\t\t\t}\n\n\t\t\tpanel.$set(panel_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(panel.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(panel.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(panel, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$I($$self, $$props, $$invalidate) {\n\tlet { buttonLabel = undefined } = $$props;\n\tlet { buttonClass = undefined } = $$props;\n\tlet { buttonIcon = undefined } = $$props;\n\tlet { buttonHideLabel = undefined } = $$props;\n\tlet { buttonTitle = undefined } = $$props;\n\tlet { buttonLabelClass = undefined } = $$props;\n\tlet { isActive = false } = $$props;\n\tlet { root = undefined } = $$props;\n\tlet { ondestroy = noop$1 } = $$props;\n\tlet { onshow = noop$1 } = $$props;\n\tlet { onhide = noop$1 } = $$props;\n\tconst hide = () => $$invalidate(0, isActive = false);\n\tconst show = () => $$invalidate(0, isActive = true);\n\tlet container;\n\tonDestroy(ondestroy);\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tcontainer = $$value;\n\t\t\t$$invalidate(9, container);\n\t\t});\n\t}\n\n\tfunction panel_isActive_binding(value) {\n\t\tisActive = value;\n\t\t$$invalidate(0, isActive);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('buttonLabel' in $$props) $$invalidate(1, buttonLabel = $$props.buttonLabel);\n\t\tif ('buttonClass' in $$props) $$invalidate(2, buttonClass = $$props.buttonClass);\n\t\tif ('buttonIcon' in $$props) $$invalidate(3, buttonIcon = $$props.buttonIcon);\n\t\tif ('buttonHideLabel' in $$props) $$invalidate(4, buttonHideLabel = $$props.buttonHideLabel);\n\t\tif ('buttonTitle' in $$props) $$invalidate(5, buttonTitle = $$props.buttonTitle);\n\t\tif ('buttonLabelClass' in $$props) $$invalidate(6, buttonLabelClass = $$props.buttonLabelClass);\n\t\tif ('isActive' in $$props) $$invalidate(0, isActive = $$props.isActive);\n\t\tif ('root' in $$props) $$invalidate(10, root = $$props.root);\n\t\tif ('ondestroy' in $$props) $$invalidate(11, ondestroy = $$props.ondestroy);\n\t\tif ('onshow' in $$props) $$invalidate(7, onshow = $$props.onshow);\n\t\tif ('onhide' in $$props) $$invalidate(8, onhide = $$props.onhide);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*container, root*/ 1536) {\n\t\t\tif (container && root && container.firstChild !== root) {\n\t\t\t\tcontainer.hasChildNodes()\n\t\t\t\t? container.replaceChild(root, container.firstChild)\n\t\t\t\t: container.append(root);\n\t\t\t}\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tbuttonLabel,\n\t\tbuttonClass,\n\t\tbuttonIcon,\n\t\tbuttonHideLabel,\n\t\tbuttonTitle,\n\t\tbuttonLabelClass,\n\t\tonshow,\n\t\tonhide,\n\t\tcontainer,\n\t\troot,\n\t\tondestroy,\n\t\thide,\n\t\tshow,\n\t\tdiv_binding,\n\t\tpanel_isActive_binding\n\t];\n}\n\nclass DynamicPanel extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$I, create_fragment$H, safe_not_equal, {\n\t\t\tbuttonLabel: 1,\n\t\t\tbuttonClass: 2,\n\t\t\tbuttonIcon: 3,\n\t\t\tbuttonHideLabel: 4,\n\t\t\tbuttonTitle: 5,\n\t\t\tbuttonLabelClass: 6,\n\t\t\tisActive: 0,\n\t\t\troot: 10,\n\t\t\tondestroy: 11,\n\t\t\tonshow: 7,\n\t\t\tonhide: 8,\n\t\t\thide: 12,\n\t\t\tshow: 13\n\t\t});\n\t}\n\n\tget hide() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tget show() {\n\t\treturn this.$$.ctx[13];\n\t}\n}\n\nvar nudgeable = (element, options = {}) => {\n    // if added as action on non focusable element you should add tabindex=0 attribute\n    const { direction = undefined, shiftMultiplier = 10, bubbles = false, preventDefault = false, stopKeydownPropagation = true, } = options;\n    const isHorizontalDirection = direction === 'horizontal';\n    const isVerticalDirection = direction === 'vertical';\n    const handleKeydown = (e) => {\n        const { key } = e;\n        const isShift = e.shiftKey;\n        const isVerticalAction = /up|down/i.test(key);\n        const isHorizontalAction = /left|right/i.test(key);\n        // no directional key\n        if (!isHorizontalAction && !isVerticalAction)\n            return;\n        // is horizontal but up or down pressed\n        if (isHorizontalDirection && isVerticalAction)\n            return;\n        // is vertical but left or right pressed\n        if (isVerticalDirection && isHorizontalAction)\n            return;\n        // if holding shift move by a factor 10\n        const multiplier = isShift ? shiftMultiplier : 1;\n        if (stopKeydownPropagation)\n            e.stopPropagation();\n        if (preventDefault)\n            e.preventDefault();\n        element.dispatchEvent(new CustomEvent('nudge', {\n            bubbles,\n            detail: vectorCreate((/left/i.test(key) ? -1 : /right/i.test(key) ? 1 : 0) * multiplier, (/up/i.test(key) ? -1 : /down/i.test(key) ? 1 : 0) * multiplier),\n        }));\n    };\n    element.addEventListener('keydown', handleKeydown);\n    return {\n        destroy() {\n            element.removeEventListener('keydown', handleKeydown);\n        },\n    };\n};\n\nvar numberRoundTo = (value, fraction) => {\n    fraction = 1 / fraction;\n    return Math.round(value * fraction) / fraction;\n};\n\nvar toFraction = (value, min, max) => (value - min) / (max - min);\n\nfunction isInt(value) {\n    return value % 1 === 0;\n}\nfunction getDelta(deltaX, deltaY) {\n    let d = 0;\n    if (Math.abs(deltaX) > Math.abs(deltaY)) {\n        d = deltaX;\n    }\n    else {\n        d = deltaY;\n    }\n    return d * -1;\n}\nvar getWheelDelta = (e, options) => {\n    const { fixScrollDirection = false } = options || {};\n    const { deltaX, deltaY } = e;\n    let delta = getDelta(deltaX, deltaY);\n    // try to normalize delta values on mac\n    if (isMac()) {\n        if (!isInt(delta)) {\n            // webkit/blink mousewheel on mac is a float, this lowers the amount per step\n            delta *= 0.05;\n        }\n        else {\n            if (isFirefox()) {\n                // scroll is bit fast on firefox mac\n                delta *= 0.1;\n            }\n            else {\n                // regular slow down\n                delta *= 0.25;\n            }\n        }\n    }\n    // try to normalize delta values on other systems\n    else {\n        // attempt to limit mousewheel jumps size (deltaX is 0 and deltaY is super large)\n        if (Math.abs(deltaX) === 0 && Math.abs(deltaY) >= 100) {\n            delta *= 0.05;\n        }\n        // just scale down the delta somewhat\n        else {\n            delta *= 0.25;\n        }\n    }\n    // limit step size so never get too big, this is basically to prevent browser differences from getting out of control\n    delta = clamp(delta, -10, 10);\n    // fix scroll direction on MacOS (scroll up should be zoom out)\n    if (isMac() && !fixScrollDirection) {\n        delta *= -1;\n    }\n    return delta;\n};\n\n/* src/core/ui/components/Slider.svelte generated by Svelte v4.2.20 */\nconst get_knob_slot_changes = dirty => ({});\nconst get_knob_slot_context = ctx => ({});\n\n// (246:8) {#if label}\nfunction create_if_block_1$d(ctx) {\n\tlet label_1;\n\tlet t;\n\tlet label_1_class_value;\n\n\treturn {\n\t\tc() {\n\t\t\tlabel_1 = element(\"label\");\n\t\t\tt = text(/*label*/ ctx[0]);\n\t\t\tattr(label_1, \"for\", /*inputId*/ ctx[17]);\n\t\t\tattr(label_1, \"class\", label_1_class_value = /*hideLabel*/ ctx[1] ? 'implicit' : undefined);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, label_1, anchor);\n\t\t\tappend(label_1, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*label*/ 1) set_data(t, /*label*/ ctx[0]);\n\n\t\t\tif (dirty[0] & /*inputId*/ 131072) {\n\t\t\t\tattr(label_1, \"for\", /*inputId*/ ctx[17]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*hideLabel*/ 2 && label_1_class_value !== (label_1_class_value = /*hideLabel*/ ctx[1] ? 'implicit' : undefined)) {\n\t\t\t\tattr(label_1, \"class\", label_1_class_value);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(label_1);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (271:4) {#if enableSpinButtons}\nfunction create_if_block$i(ctx) {\n\tlet button0;\n\tlet icon0;\n\tlet t;\n\tlet button1;\n\tlet icon1;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\ticon0 = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_1$5] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\ticon1 = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot$e] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tbutton0 = element(\"button\");\n\t\t\tcreate_component(icon0.$$.fragment);\n\t\t\tt = space();\n\t\t\tbutton1 = element(\"button\");\n\t\t\tcreate_component(icon1.$$.fragment);\n\t\t\tattr(button0, \"type\", \"button\");\n\t\t\tattr(button0, \"aria-label\", \"Increase\");\n\t\t\tattr(button1, \"type\", \"button\");\n\t\t\tattr(button1, \"aria-label\", \"Decrease\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, button0, anchor);\n\t\t\tmount_component(icon0, button0, null);\n\t\t\tinsert(target, t, anchor);\n\t\t\tinsert(target, button1, anchor);\n\t\t\tmount_component(icon1, button1, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(button0, \"pointerdown\", /*handleUpdaterDown*/ ctx[20](1)),\n\t\t\t\t\tlisten(button0, \"keydown\", /*handleUpdaterDown*/ ctx[20](1)),\n\t\t\t\t\tlisten(button1, \"pointerdown\", /*handleUpdaterDown*/ ctx[20](-1)),\n\t\t\t\t\tlisten(button1, \"keydown\", /*handleUpdaterDown*/ ctx[20](-1))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon0_changes = {};\n\n\t\t\tif (dirty[1] & /*$$scope*/ 512) {\n\t\t\t\ticon0_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon0.$set(icon0_changes);\n\t\t\tconst icon1_changes = {};\n\n\t\t\tif (dirty[1] & /*$$scope*/ 512) {\n\t\t\t\ticon1_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon1.$set(icon1_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon0.$$.fragment, local);\n\t\t\ttransition_in(icon1.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon0.$$.fragment, local);\n\t\t\ttransition_out(icon1.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(button0);\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(button1);\n\t\t\t}\n\n\t\t\tdestroy_component(icon0);\n\t\t\tdestroy_component(icon1);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (278:12) <Icon>\nfunction create_default_slot_1$5(ctx) {\n\tlet path;\n\n\treturn {\n\t\tc() {\n\t\t\tpath = svg_element(\"path\");\n\t\t\tattr(path, \"d\", \"M8 12 h8 M12 8 v8\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, path, anchor);\n\t\t},\n\t\tp: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(path);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (286:12) <Icon>\nfunction create_default_slot$e(ctx) {\n\tlet path;\n\n\treturn {\n\t\tc() {\n\t\t\tpath = svg_element(\"path\");\n\t\t\tattr(path, \"d\", \"M9 12 h6\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, path, anchor);\n\t\t},\n\t\tp: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(path);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction create_fragment$G(ctx) {\n\tlet div4;\n\tlet div3;\n\tlet t0;\n\tlet input_1;\n\tlet t1;\n\tlet div0;\n\tlet div0_class_value;\n\tlet t2;\n\tlet div2;\n\tlet div1;\n\tlet div1_class_value;\n\tlet t3;\n\tlet div4_class_value;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block0 = /*label*/ ctx[0] && create_if_block_1$d(ctx);\n\tconst default_slot_template = /*#slots*/ ctx[38].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[40], null);\n\tconst knob_slot_template = /*#slots*/ ctx[38].knob;\n\tconst knob_slot = create_slot(knob_slot_template, ctx, /*$$scope*/ ctx[40], get_knob_slot_context);\n\tlet if_block1 = /*enableSpinButtons*/ ctx[8] && create_if_block$i(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv4 = element(\"div\");\n\t\t\tdiv3 = element(\"div\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tinput_1 = element(\"input\");\n\t\t\tt1 = space();\n\t\t\tdiv0 = element(\"div\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tt2 = space();\n\t\t\tdiv2 = element(\"div\");\n\t\t\tdiv1 = element(\"div\");\n\t\t\tif (knob_slot) knob_slot.c();\n\t\t\tt3 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(input_1, \"type\", \"range\");\n\t\t\tattr(input_1, \"id\", /*inputId*/ ctx[17]);\n\t\t\tattr(input_1, \"min\", /*min*/ ctx[2]);\n\t\t\tattr(input_1, \"max\", /*max*/ ctx[3]);\n\t\t\tattr(input_1, \"step\", /*step*/ ctx[4]);\n\t\t\tinput_1.value = /*numberValue*/ ctx[13];\n\t\t\tset_style(input_1, \"pointer-events\", /*enableForceUseKnob*/ ctx[9] ? 'none' : undefined);\n\t\t\tattr(div0, \"class\", div0_class_value = arrayJoin(['PinturaSliderTrack', /*trackClass*/ ctx[5]]));\n\t\t\tattr(div1, \"class\", div1_class_value = arrayJoin(['PinturaSliderKnob', /*knobClass*/ ctx[6]]));\n\t\t\tattr(div2, \"class\", \"PinturaSliderKnobController\");\n\t\t\tset_style(div2, \"transform\", /*styleKnobTransform*/ ctx[16]);\n\t\t\tattr(div3, \"class\", \"PinturaSliderControl\");\n\t\t\tset_style(div3, \"--slider-position\", Math.round(/*position*/ ctx[14]));\n\t\t\tattr(div4, \"class\", div4_class_value = arrayJoin(['PinturaSlider', /*klass*/ ctx[11]]));\n\t\t\tattr(div4, \"data-direction\", /*direction*/ ctx[7]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div4, anchor);\n\t\t\tappend(div4, div3);\n\t\t\tif (if_block0) if_block0.m(div3, null);\n\t\t\tappend(div3, t0);\n\t\t\tappend(div3, input_1);\n\t\t\t/*input_1_binding*/ ctx[39](input_1);\n\t\t\tappend(div3, t1);\n\t\t\tappend(div3, div0);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(div0, null);\n\t\t\t}\n\n\t\t\tappend(div3, t2);\n\t\t\tappend(div3, div2);\n\t\t\tappend(div2, div1);\n\n\t\t\tif (knob_slot) {\n\t\t\t\tknob_slot.m(div1, null);\n\t\t\t}\n\n\t\t\tappend(div4, t3);\n\t\t\tif (if_block1) if_block1.m(div4, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(input_1, \"input\", /*handleInput*/ ctx[18]),\n\t\t\t\t\tlisten(input_1, \"nudge\", /*handleNudge*/ ctx[19]),\n\t\t\t\t\tlisten(input_1, \"wheel\", /*handleWheel*/ ctx[21]),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, input_1)),\n\t\t\t\t\tlisten(div3, \"pointerdown\", function () {\n\t\t\t\t\t\tif (is_function(/*enablePointerdownListener*/ ctx[10] && /*handlePointerDown*/ ctx[12])) (/*enablePointerdownListener*/ ctx[10] && /*handlePointerDown*/ ctx[12]).apply(this, arguments);\n\t\t\t\t\t})\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (/*label*/ ctx[0]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_1$d(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\tif_block0.m(div3, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tif_block0.d(1);\n\t\t\t\tif_block0 = null;\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*inputId*/ 131072) {\n\t\t\t\tattr(input_1, \"id\", /*inputId*/ ctx[17]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*min*/ 4) {\n\t\t\t\tattr(input_1, \"min\", /*min*/ ctx[2]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*max*/ 8) {\n\t\t\t\tattr(input_1, \"max\", /*max*/ ctx[3]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*step*/ 16) {\n\t\t\t\tattr(input_1, \"step\", /*step*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*numberValue*/ 8192) {\n\t\t\t\tinput_1.value = /*numberValue*/ ctx[13];\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*enableForceUseKnob*/ 512) {\n\t\t\t\tset_style(input_1, \"pointer-events\", /*enableForceUseKnob*/ ctx[9] ? 'none' : undefined);\n\t\t\t}\n\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty[1] & /*$$scope*/ 512)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[40],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[40])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[40], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*trackClass*/ 32 && div0_class_value !== (div0_class_value = arrayJoin(['PinturaSliderTrack', /*trackClass*/ ctx[5]]))) {\n\t\t\t\tattr(div0, \"class\", div0_class_value);\n\t\t\t}\n\n\t\t\tif (knob_slot) {\n\t\t\t\tif (knob_slot.p && (!current || dirty[1] & /*$$scope*/ 512)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tknob_slot,\n\t\t\t\t\t\tknob_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[40],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[40])\n\t\t\t\t\t\t: get_slot_changes(knob_slot_template, /*$$scope*/ ctx[40], dirty, get_knob_slot_changes),\n\t\t\t\t\t\tget_knob_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*knobClass*/ 64 && div1_class_value !== (div1_class_value = arrayJoin(['PinturaSliderKnob', /*knobClass*/ ctx[6]]))) {\n\t\t\t\tattr(div1, \"class\", div1_class_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleKnobTransform*/ 65536) {\n\t\t\t\tset_style(div2, \"transform\", /*styleKnobTransform*/ ctx[16]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*position*/ 16384) {\n\t\t\t\tset_style(div3, \"--slider-position\", Math.round(/*position*/ ctx[14]));\n\t\t\t}\n\n\t\t\tif (/*enableSpinButtons*/ ctx[8]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*enableSpinButtons*/ 256) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block$i(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(div4, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*klass*/ 2048 && div4_class_value !== (div4_class_value = arrayJoin(['PinturaSlider', /*klass*/ ctx[11]]))) {\n\t\t\t\tattr(div4, \"class\", div4_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*direction*/ 128) {\n\t\t\t\tattr(div4, \"data-direction\", /*direction*/ ctx[7]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\ttransition_in(knob_slot, local);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\ttransition_out(knob_slot, local);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div4);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\t/*input_1_binding*/ ctx[39](null);\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tif (knob_slot) knob_slot.d(detaching);\n\t\t\tif (if_block1) if_block1.d();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$H($$self, $$props, $$invalidate) {\n\tlet inputId;\n\tlet numberValue;\n\tlet range;\n\tlet fraction;\n\tlet position;\n\tlet axis;\n\tlet dimension;\n\tlet offsetSizeProp;\n\tlet pageAxisProp;\n\tlet styleKnobTransform;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { id = undefined } = $$props;\n\tlet { label = undefined } = $$props;\n\tlet { hideLabel = false } = $$props;\n\tlet { min = 0 } = $$props;\n\tlet { max = 100 } = $$props;\n\tlet { step = 1 } = $$props;\n\tlet { value = 0 } = $$props;\n\tlet { valueMin = undefined } = $$props;\n\tlet { valueMax = undefined } = $$props;\n\tlet { trackClass = undefined } = $$props;\n\tlet { knobClass = undefined } = $$props;\n\tlet { ongrab = noop$1 } = $$props;\n\tlet { onchange = noop$1 } = $$props;\n\tlet { onrelease = noop$1 } = $$props;\n\tlet { onexceed = noop$1 } = $$props;\n\tlet { direction = 'x' } = $$props;\n\tlet { getValue = passthrough } = $$props;\n\tlet { setValue = passthrough } = $$props;\n\tlet { enableSpinButtons = true } = $$props;\n\tlet { enableForceUseKnob = false } = $$props;\n\tlet { enableStopPropagation = true } = $$props;\n\tlet { enablePointerdownListener = true } = $$props;\n\tlet { maxInteractionDistance = 6 } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\tlet input;\n\tlet inputSize;\n\tlet inputOffset;\n\tlet pageOffset;\n\tlet valuePrev;\n\tlet valuePrevIntended;\n\tconst formatValue = v => setValue(numberRoundTo(clamp(v, min, max), step), value);\n\n\tconst setValueByOffset = (offset, size, options = {}) => {\n\t\tconst { grabbed = false, released = false } = options;\n\t\tconst intendedValue = formatValue(min + offset / size * range);\n\t\tconst minValue = valueMin || min;\n\t\tconst maxValue = valueMax || max;\n\n\t\t$$invalidate(22, value = isString(intendedValue)\n\t\t? intendedValue\n\t\t: clamp(intendedValue, minValue, maxValue));\n\n\t\t// skip\n\t\tif (valuePrevIntended === intendedValue) return;\n\n\t\tvaluePrevIntended = intendedValue;\n\n\t\tif (!isString(intendedValue) && (intendedValue < minValue || intendedValue > maxValue)) {\n\t\t\tonexceed(value, intendedValue);\n\t\t}\n\n\t\tif (value === valuePrev) {\n\t\t\treturn;\n\t\t}\n\n\t\tvaluePrev = value;\n\t\tif (grabbed) ongrab(value);\n\t\tonchange(value);\n\t\tif (released) onrelease(value);\n\t};\n\n\tconst handleInput = e => {\n\t\t// already handled by pointer events\n\t\tif (inputSize) return;\n\n\t\t$$invalidate(22, value = setValue(parseFloat(e.target.value)));\n\t\tif (value === valuePrev) return;\n\t\tvaluePrev = value;\n\t\tonchange(value);\n\t};\n\n\tlet nudgeTimer;\n\n\tconst handleNudge = e => {\n\t\tconst size = input[offsetSizeProp];\n\t\tconst offset = (numberValue - min) / range * size;\n\t\tsetValueByOffset(offset + e.detail[direction], size);\n\t\tclearTimeout(nudgeTimer);\n\n\t\tnudgeTimer = setTimeout(\n\t\t\t() => {\n\t\t\t\tonrelease(value);\n\t\t\t},\n\t\t\t250\n\t\t);\n\t};\n\n\tconst eventDistanceToKnob = e => {\n\t\tconst clientRect = input.getBoundingClientRect();\n\t\tconst pageOffset = e[pageAxisProp];\n\t\tconst inputOffset = pageOffset - clientRect[direction];\n\t\tconst inputSize = input[offsetSizeProp];\n\t\treturn Math.abs(inputOffset - fraction * inputSize);\n\t};\n\n\tlet inputSizeTimeout;\n\n\tconst handlePointerDown = e => {\n\t\tclearTimeout(inputSizeTimeout);\n\t\tlet stopPropagation = false;\n\t\tenableStopPropagation && e.stopPropagation();\n\t\tclearTimeout(nudgeTimer);\n\t\tconst clientRect = input.getBoundingClientRect();\n\t\tinputSize = input[offsetSizeProp];\n\t\tpageOffset = e[pageAxisProp];\n\t\tinputOffset = pageOffset - clientRect[direction];\n\n\t\tif (enableForceUseKnob) {\n\t\t\tconst dist = Math.abs(inputOffset - fraction * inputSize);\n\t\t\tif (dist > maxInteractionDistance) return;\n\t\t\tstopPropagation = true;\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\tif (document.activeElement !== input) input.focus();\n\t\tsetValueByOffset(inputOffset, inputSize, { grabbed: true });\n\t\tdocument.documentElement.addEventListener('pointermove', handlePointerMove);\n\t\tdocument.documentElement.addEventListener('pointerup', handlePointerUp);\n\t\treturn stopPropagation;\n\t};\n\n\tconst handlePointerMove = e => {\n\t\tconst d = e[pageAxisProp] - pageOffset;\n\t\tsetValueByOffset(inputOffset + d, inputSize);\n\t};\n\n\tconst handlePointerUp = e => {\n\t\t// reset next frame so inputSize isn't undefined when handleInput fires on iOS\n\t\tinputSizeTimeout = setTimeout(\n\t\t\t() => {\n\t\t\t\tinputSize = undefined;\n\t\t\t},\n\t\t\t50\n\t\t);\n\n\t\tdocument.documentElement.removeEventListener('pointermove', handlePointerMove);\n\t\tdocument.documentElement.removeEventListener('pointerup', handlePointerUp);\n\t\tonchange(value);\n\t\tonrelease(value);\n\t};\n\n\tconst update = () => {\n\t\t$$invalidate(22, value = formatValue(numberValue + updateDir * step));\n\t\tonchange(value);\n\t};\n\n\tlet updateTimer = null;\n\tlet updateDir = 1;\n\tlet didUpdate = false;\n\n\tconst handleUpdaterDown = dir => e => {\n\t\tif (e.type === 'keydown') {\n\t\t\t// didn't press return, or already updating\n\t\t\tif (!isConfirmKey(e.key) || updateTimer !== null) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tclearTimeout(nudgeTimer);\n\t\tupdateDir = dir;\n\t\tdidUpdate = false;\n\n\t\tupdateTimer = setInterval(\n\t\t\t() => {\n\t\t\t\tdidUpdate = true;\n\t\t\t\tupdate();\n\t\t\t},\n\t\t\t100\n\t\t);\n\n\t\tif (e.type === 'pointerdown') {\n\t\t\tdocument.addEventListener('pointercancel', handleUpdaterUp);\n\t\t\tdocument.addEventListener('pointerup', handleUpdaterUp);\n\t\t} else {\n\t\t\tdocument.addEventListener('keyup', handleUpdaterUp);\n\t\t}\n\t};\n\n\tconst handleUpdaterUp = e => {\n\t\tclearTimeout(updateTimer);\n\t\tupdateTimer = null;\n\t\tif (!didUpdate) update();\n\t\tonrelease(value);\n\t\tdocument.removeEventListener('pointerup', handleUpdaterUp);\n\t\tdocument.removeEventListener('keyup', handleUpdaterUp);\n\t};\n\n\tconst handleWheel = e => {\n\t\tconst delta = getWheelDelta(e);\n\n\t\t// always min steps of 1\n\t\tconst roundedDelta = delta < 0 ? Math.floor(delta) : Math.ceil(delta);\n\n\t\t$$invalidate(22, value = formatValue(numberValue + roundedDelta * step));\n\t\tonchange(value);\n\t};\n\n\tfunction input_1_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tinput = $$value;\n\t\t\t$$invalidate(15, input);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('id' in $$props) $$invalidate(23, id = $$props.id);\n\t\tif ('label' in $$props) $$invalidate(0, label = $$props.label);\n\t\tif ('hideLabel' in $$props) $$invalidate(1, hideLabel = $$props.hideLabel);\n\t\tif ('min' in $$props) $$invalidate(2, min = $$props.min);\n\t\tif ('max' in $$props) $$invalidate(3, max = $$props.max);\n\t\tif ('step' in $$props) $$invalidate(4, step = $$props.step);\n\t\tif ('value' in $$props) $$invalidate(22, value = $$props.value);\n\t\tif ('valueMin' in $$props) $$invalidate(24, valueMin = $$props.valueMin);\n\t\tif ('valueMax' in $$props) $$invalidate(25, valueMax = $$props.valueMax);\n\t\tif ('trackClass' in $$props) $$invalidate(5, trackClass = $$props.trackClass);\n\t\tif ('knobClass' in $$props) $$invalidate(6, knobClass = $$props.knobClass);\n\t\tif ('ongrab' in $$props) $$invalidate(26, ongrab = $$props.ongrab);\n\t\tif ('onchange' in $$props) $$invalidate(27, onchange = $$props.onchange);\n\t\tif ('onrelease' in $$props) $$invalidate(28, onrelease = $$props.onrelease);\n\t\tif ('onexceed' in $$props) $$invalidate(29, onexceed = $$props.onexceed);\n\t\tif ('direction' in $$props) $$invalidate(7, direction = $$props.direction);\n\t\tif ('getValue' in $$props) $$invalidate(30, getValue = $$props.getValue);\n\t\tif ('setValue' in $$props) $$invalidate(31, setValue = $$props.setValue);\n\t\tif ('enableSpinButtons' in $$props) $$invalidate(8, enableSpinButtons = $$props.enableSpinButtons);\n\t\tif ('enableForceUseKnob' in $$props) $$invalidate(9, enableForceUseKnob = $$props.enableForceUseKnob);\n\t\tif ('enableStopPropagation' in $$props) $$invalidate(32, enableStopPropagation = $$props.enableStopPropagation);\n\t\tif ('enablePointerdownListener' in $$props) $$invalidate(10, enablePointerdownListener = $$props.enablePointerdownListener);\n\t\tif ('maxInteractionDistance' in $$props) $$invalidate(33, maxInteractionDistance = $$props.maxInteractionDistance);\n\t\tif ('class' in $$props) $$invalidate(11, klass = $$props.class);\n\t\tif ('$$scope' in $$props) $$invalidate(40, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*id, label*/ 8388609) {\n\t\t\t$$invalidate(17, inputId = id\n\t\t\t? id\n\t\t\t: label ? `PinturaSlider_${getUniqueId()}` : undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*value, getValue*/ 1077936128) {\n\t\t\t$$invalidate(13, numberValue = value !== undefined ? getValue(value) : 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*max, min*/ 12) {\n\t\t\trange = max - min;\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*numberValue, min, max*/ 8204) {\n\t\t\t$$invalidate(35, fraction = toFraction(numberValue, min, max));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*fraction*/ 16) {\n\t\t\t$$invalidate(14, position = fraction * 100);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*direction*/ 128) {\n\t\t\t$$invalidate(36, axis = direction.toUpperCase());\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*direction*/ 128) {\n\t\t\t$$invalidate(37, dimension = direction === 'x' ? 'Width' : 'Height');\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*dimension*/ 64) {\n\t\t\toffsetSizeProp = `offset${dimension}`;\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*axis*/ 32) {\n\t\t\tpageAxisProp = `page${axis}`;\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*position*/ 16384 | $$self.$$.dirty[1] & /*axis*/ 32) {\n\t\t\t$$invalidate(16, styleKnobTransform = `translate${axis}(${position}%)`);\n\t\t}\n\t};\n\n\treturn [\n\t\tlabel,\n\t\thideLabel,\n\t\tmin,\n\t\tmax,\n\t\tstep,\n\t\ttrackClass,\n\t\tknobClass,\n\t\tdirection,\n\t\tenableSpinButtons,\n\t\tenableForceUseKnob,\n\t\tenablePointerdownListener,\n\t\tklass,\n\t\thandlePointerDown,\n\t\tnumberValue,\n\t\tposition,\n\t\tinput,\n\t\tstyleKnobTransform,\n\t\tinputId,\n\t\thandleInput,\n\t\thandleNudge,\n\t\thandleUpdaterDown,\n\t\thandleWheel,\n\t\tvalue,\n\t\tid,\n\t\tvalueMin,\n\t\tvalueMax,\n\t\tongrab,\n\t\tonchange,\n\t\tonrelease,\n\t\tonexceed,\n\t\tgetValue,\n\t\tsetValue,\n\t\tenableStopPropagation,\n\t\tmaxInteractionDistance,\n\t\teventDistanceToKnob,\n\t\tfraction,\n\t\taxis,\n\t\tdimension,\n\t\tslots,\n\t\tinput_1_binding,\n\t\t$$scope\n\t];\n}\n\nclass Slider extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$H,\n\t\t\tcreate_fragment$G,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tid: 23,\n\t\t\t\tlabel: 0,\n\t\t\t\thideLabel: 1,\n\t\t\t\tmin: 2,\n\t\t\t\tmax: 3,\n\t\t\t\tstep: 4,\n\t\t\t\tvalue: 22,\n\t\t\t\tvalueMin: 24,\n\t\t\t\tvalueMax: 25,\n\t\t\t\ttrackClass: 5,\n\t\t\t\tknobClass: 6,\n\t\t\t\tongrab: 26,\n\t\t\t\tonchange: 27,\n\t\t\t\tonrelease: 28,\n\t\t\t\tonexceed: 29,\n\t\t\t\tdirection: 7,\n\t\t\t\tgetValue: 30,\n\t\t\t\tsetValue: 31,\n\t\t\t\tenableSpinButtons: 8,\n\t\t\t\tenableForceUseKnob: 9,\n\t\t\t\tenableStopPropagation: 32,\n\t\t\t\tenablePointerdownListener: 10,\n\t\t\t\tmaxInteractionDistance: 33,\n\t\t\t\tclass: 11,\n\t\t\t\teventDistanceToKnob: 34,\n\t\t\t\thandlePointerDown: 12\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget eventDistanceToKnob() {\n\t\treturn this.$$.ctx[34];\n\t}\n\n\tget handlePointerDown() {\n\t\treturn this.$$.ctx[12];\n\t}\n}\n\n/* src/core/ui/components/ToggleSlider.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block_1$c(ctx) {\n\tlet icon_1;\n\tlet current;\n\n\ticon_1 = new Icon({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaButtonIcon\",\n\t\t\t\t$$slots: { default: [create_default_slot$d] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon_1.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon_1, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_1_changes = {};\n\n\t\t\tif (dirty & /*$$scope, icon*/ 1048580) {\n\t\t\t\ticon_1_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon_1.$set(icon_1_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon_1.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon_1.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon_1, detaching);\n\t\t}\n\t};\n}\n\n// (59:12) <Icon class=\"PinturaButtonIcon\">\nfunction create_default_slot$d(ctx) {\n\tlet g;\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = /*icon*/ ctx[2];\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*icon*/ 4) g.innerHTML = /*icon*/ ctx[2];\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (61:8) {#if labelPrefix}\nfunction create_if_block$h(ctx) {\n\tlet span;\n\tlet t_value = localize(/*labelPrefix*/ ctx[8], /*locale*/ ctx[6]) + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"class\", \"PinturaButtonLabelPrefix\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*labelPrefix, locale*/ 320 && t_value !== (t_value = localize(/*labelPrefix*/ ctx[8], /*locale*/ ctx[6]) + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (53:4) \nfunction create_label_slot$1(ctx) {\n\tlet span1;\n\tlet t0;\n\tlet t1;\n\tlet span0;\n\tlet t2;\n\tlet span0_class_value;\n\tlet span1_title_value;\n\tlet span1_class_value;\n\tlet current;\n\tlet if_block0 = /*icon*/ ctx[2] && create_if_block_1$c(ctx);\n\tlet if_block1 = /*labelPrefix*/ ctx[8] && create_if_block$h(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tspan1 = element(\"span\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt1 = space();\n\t\t\tspan0 = element(\"span\");\n\t\t\tt2 = text(/*currentLabel*/ ctx[9]);\n\n\t\t\tattr(span0, \"class\", span0_class_value = arrayJoin([\n\t\t\t\t'PinturaButtonLabel',\n\t\t\t\t/*labelClass*/ ctx[3],\n\t\t\t\t/*hideLabel*/ ctx[5] && 'implicit'\n\t\t\t]));\n\n\t\t\tattr(span1, \"slot\", \"label\");\n\t\t\tattr(span1, \"title\", span1_title_value = localize(/*title*/ ctx[1], /*locale*/ ctx[6]));\n\t\t\tattr(span1, \"class\", span1_class_value = arrayJoin(['PinturaButtonInner', /*innerClass*/ ctx[4]]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span1, anchor);\n\t\t\tif (if_block0) if_block0.m(span1, null);\n\t\t\tappend(span1, t0);\n\t\t\tif (if_block1) if_block1.m(span1, null);\n\t\t\tappend(span1, t1);\n\t\t\tappend(span1, span0);\n\t\t\tappend(span0, t2);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*icon*/ ctx[2]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*icon*/ 4) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_1$c(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(span1, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*labelPrefix*/ ctx[8]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block$h(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(span1, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*currentLabel*/ 512) set_data(t2, /*currentLabel*/ ctx[9]);\n\n\t\t\tif (!current || dirty & /*labelClass, hideLabel*/ 40 && span0_class_value !== (span0_class_value = arrayJoin([\n\t\t\t\t'PinturaButtonLabel',\n\t\t\t\t/*labelClass*/ ctx[3],\n\t\t\t\t/*hideLabel*/ ctx[5] && 'implicit'\n\t\t\t]))) {\n\t\t\t\tattr(span0, \"class\", span0_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*title, locale*/ 66 && span1_title_value !== (span1_title_value = localize(/*title*/ ctx[1], /*locale*/ ctx[6]))) {\n\t\t\t\tattr(span1, \"title\", span1_title_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*innerClass*/ 16 && span1_class_value !== (span1_class_value = arrayJoin(['PinturaButtonInner', /*innerClass*/ ctx[4]]))) {\n\t\t\t\tattr(span1, \"class\", span1_class_value);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span1);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t}\n\t};\n}\n\n// (69:4) \nfunction create_details_slot$1(ctx) {\n\tlet div;\n\tlet slider;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tconst slider_spread_levels = [\n\t\t{\n\t\t\tlabel: localize(/*title*/ ctx[1], /*locale*/ ctx[6])\n\t\t},\n\t\t{ hideLabel: true },\n\t\t/*$$restProps*/ ctx[12],\n\t\t{ value: /*value*/ ctx[7] },\n\t\t{ onchange: /*handleChangeValue*/ ctx[11] }\n\t];\n\n\tlet slider_props = {};\n\n\tfor (let i = 0; i < slider_spread_levels.length; i += 1) {\n\t\tslider_props = assign(slider_props, slider_spread_levels[i]);\n\t}\n\n\tslider = new Slider({ props: slider_props });\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(slider.$$.fragment);\n\t\t\tattr(div, \"slot\", \"details\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(slider, div, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = listen(div, \"keydown\", /*handleKeydown*/ ctx[10]);\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst slider_changes = (dirty & /*title, locale, $$restProps, value, handleChangeValue*/ 6338)\n\t\t\t? get_spread_update(slider_spread_levels, [\n\t\t\t\t\tdirty & /*title, locale*/ 66 && {\n\t\t\t\t\t\tlabel: localize(/*title*/ ctx[1], /*locale*/ ctx[6])\n\t\t\t\t\t},\n\t\t\t\t\tslider_spread_levels[1],\n\t\t\t\t\tdirty & /*$$restProps*/ 4096 && get_spread_object(/*$$restProps*/ ctx[12]),\n\t\t\t\t\tdirty & /*value*/ 128 && { value: /*value*/ ctx[7] },\n\t\t\t\t\tdirty & /*handleChangeValue*/ 2048 && { onchange: /*handleChangeValue*/ ctx[11] }\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tslider.$set(slider_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(slider.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(slider.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(slider);\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\nfunction create_fragment$F(ctx) {\n\tlet panel;\n\tlet current;\n\n\tpanel = new Panel({\n\t\t\tprops: {\n\t\t\t\tcanConfirm: true,\n\t\t\t\tpanelClass: \"PinturaSliderPanel\",\n\t\t\t\tbuttonClass: arrayJoin([\n\t\t\t\t\t'PinturaSliderButton',\n\t\t\t\t\t/*klass*/ ctx[0],\n\t\t\t\t\t/*hideLabel*/ ctx[5] && 'PinturaSliderIconOnly'\n\t\t\t\t]),\n\t\t\t\t$$slots: {\n\t\t\t\t\tdetails: [create_details_slot$1],\n\t\t\t\t\tlabel: [create_label_slot$1]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(panel.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(panel, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tconst panel_changes = {};\n\n\t\t\tif (dirty & /*klass, hideLabel*/ 33) panel_changes.buttonClass = arrayJoin([\n\t\t\t\t'PinturaSliderButton',\n\t\t\t\t/*klass*/ ctx[0],\n\t\t\t\t/*hideLabel*/ ctx[5] && 'PinturaSliderIconOnly'\n\t\t\t]);\n\n\t\t\tif (dirty & /*$$scope, title, locale, $$restProps, value, innerClass, labelClass, hideLabel, currentLabel, labelPrefix, icon*/ 1053694) {\n\t\t\t\tpanel_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tpanel.$set(panel_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(panel.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(panel.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(panel, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$G($$self, $$props, $$invalidate) {\n\tconst omit_props_names = [\n\t\t\"class\",\"title\",\"label\",\"icon\",\"labelClass\",\"innerClass\",\"hideLabel\",\"locale\",\"value\",\"onchange\",\"labelPrefix\"\n\t];\n\n\tlet $$restProps = compute_rest_props($$props, omit_props_names);\n\tlet { class: klass = undefined } = $$props;\n\tlet { title = undefined } = $$props;\n\tlet { label = Math.round } = $$props;\n\tlet { icon = undefined } = $$props;\n\tlet { labelClass = undefined } = $$props;\n\tlet { innerClass = undefined } = $$props;\n\tlet { hideLabel = false } = $$props;\n\tlet { locale = undefined } = $$props;\n\tlet { value = undefined } = $$props;\n\tlet { onchange = noop$1 } = $$props;\n\tlet { labelPrefix = undefined } = $$props;\n\tconst { min, max, getValue = passthrough } = $$restProps;\n\tlet currentLabel;\n\n\tconst handleKeydown = e => {\n\t\t// don't allow tabbing ([tab] is also blocked in normal <select>)\n\t\tif ((/tab/i).test(e.key)) e.preventDefault();\n\t};\n\n\tconst getLabel = value => isFunction(label)\n\t? label(getValue(value), min, max, value)\n\t: label;\n\n\tconst handleChangeValue = value => {\n\t\tsyncLabel(value);\n\t\tonchange(value);\n\t};\n\n\tconst syncLabel = value => $$invalidate(9, currentLabel = getLabel(value));\n\n\t$$self.$$set = $$new_props => {\n\t\t$$props = assign(assign({}, $$props), exclude_internal_props($$new_props));\n\t\t$$invalidate(12, $$restProps = compute_rest_props($$props, omit_props_names));\n\t\tif ('class' in $$new_props) $$invalidate(0, klass = $$new_props.class);\n\t\tif ('title' in $$new_props) $$invalidate(1, title = $$new_props.title);\n\t\tif ('label' in $$new_props) $$invalidate(13, label = $$new_props.label);\n\t\tif ('icon' in $$new_props) $$invalidate(2, icon = $$new_props.icon);\n\t\tif ('labelClass' in $$new_props) $$invalidate(3, labelClass = $$new_props.labelClass);\n\t\tif ('innerClass' in $$new_props) $$invalidate(4, innerClass = $$new_props.innerClass);\n\t\tif ('hideLabel' in $$new_props) $$invalidate(5, hideLabel = $$new_props.hideLabel);\n\t\tif ('locale' in $$new_props) $$invalidate(6, locale = $$new_props.locale);\n\t\tif ('value' in $$new_props) $$invalidate(7, value = $$new_props.value);\n\t\tif ('onchange' in $$new_props) $$invalidate(14, onchange = $$new_props.onchange);\n\t\tif ('labelPrefix' in $$new_props) $$invalidate(8, labelPrefix = $$new_props.labelPrefix);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*value, label*/ 8320) {\n\t\t\tsyncLabel(value);\n\t\t}\n\t};\n\n\treturn [\n\t\tklass,\n\t\ttitle,\n\t\ticon,\n\t\tlabelClass,\n\t\tinnerClass,\n\t\thideLabel,\n\t\tlocale,\n\t\tvalue,\n\t\tlabelPrefix,\n\t\tcurrentLabel,\n\t\thandleKeydown,\n\t\thandleChangeValue,\n\t\t$$restProps,\n\t\tlabel,\n\t\tonchange\n\t];\n}\n\nclass ToggleSlider extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$G, create_fragment$F, safe_not_equal, {\n\t\t\tclass: 0,\n\t\t\ttitle: 1,\n\t\t\tlabel: 13,\n\t\t\ticon: 2,\n\t\t\tlabelClass: 3,\n\t\t\tinnerClass: 4,\n\t\t\thideLabel: 5,\n\t\t\tlocale: 6,\n\t\t\tvalue: 7,\n\t\t\tonchange: 14,\n\t\t\tlabelPrefix: 8\n\t\t});\n\t}\n}\n\n/* src/core/ui/components/ProgressIndicator.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$E(ctx) {\n\tlet span1;\n\tlet svg;\n\tlet g;\n\tlet circle0;\n\tlet circle1;\n\tlet t0;\n\tlet span0;\n\tlet t1;\n\n\treturn {\n\t\tc() {\n\t\t\tspan1 = element(\"span\");\n\t\t\tsvg = svg_element(\"svg\");\n\t\t\tg = svg_element(\"g\");\n\t\t\tcircle0 = svg_element(\"circle\");\n\t\t\tcircle1 = svg_element(\"circle\");\n\t\t\tt0 = space();\n\t\t\tspan0 = element(\"span\");\n\t\t\tt1 = text(/*formattedValue*/ ctx[3]);\n\t\t\tattr(circle0, \"class\", \"PinturaProgressIndicatorBar\");\n\t\t\tattr(circle0, \"r\", \"8.5\");\n\t\t\tattr(circle0, \"cx\", \"10\");\n\t\t\tattr(circle0, \"cy\", \"10\");\n\t\t\tattr(circle0, \"stroke-linecap\", \"round\");\n\t\t\tattr(circle0, \"opacity\", \".25\");\n\t\t\tattr(circle1, \"class\", \"PinturaProgressIndicatorFill\");\n\t\t\tattr(circle1, \"r\", \"8.5\");\n\t\t\tattr(circle1, \"stroke-dasharray\", /*circleValue*/ ctx[2]);\n\t\t\tattr(circle1, \"cx\", \"10\");\n\t\t\tattr(circle1, \"cy\", \"10\");\n\t\t\tattr(circle1, \"transform\", \"rotate(-90) translate(-20)\");\n\t\t\tattr(g, \"fill\", \"none\");\n\t\t\tattr(g, \"stroke\", \"currentColor\");\n\t\t\tattr(g, \"stroke-width\", \"2.5\");\n\t\t\tattr(g, \"stroke-linecap\", \"round\");\n\t\t\tattr(g, \"opacity\", /*circleOpacity*/ ctx[1]);\n\t\t\tattr(svg, \"width\", \"20\");\n\t\t\tattr(svg, \"height\", \"20\");\n\t\t\tattr(svg, \"viewBox\", \"0 0 20 20\");\n\t\t\tattr(svg, \"xmlns\", \"http://www.w3.org/2000/svg\");\n\t\t\tattr(svg, \"aria-hidden\", \"true\");\n\t\t\tattr(svg, \"focusable\", \"false\");\n\t\t\tattr(span0, \"class\", \"implicit\");\n\t\t\tattr(span1, \"class\", \"PinturaProgressIndicator\");\n\t\t\tattr(span1, \"data-status\", /*status*/ ctx[0]);\n\t\t\tset_style(span1, \"opacity\", /*$componentOpacity*/ ctx[4]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span1, anchor);\n\t\t\tappend(span1, svg);\n\t\t\tappend(svg, g);\n\t\t\tappend(g, circle0);\n\t\t\tappend(g, circle1);\n\t\t\tappend(span1, t0);\n\t\t\tappend(span1, span0);\n\t\t\tappend(span0, t1);\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*circleValue*/ 4) {\n\t\t\t\tattr(circle1, \"stroke-dasharray\", /*circleValue*/ ctx[2]);\n\t\t\t}\n\n\t\t\tif (dirty & /*circleOpacity*/ 2) {\n\t\t\t\tattr(g, \"opacity\", /*circleOpacity*/ ctx[1]);\n\t\t\t}\n\n\t\t\tif (dirty & /*formattedValue*/ 8) set_data(t1, /*formattedValue*/ ctx[3]);\n\n\t\t\tif (dirty & /*status*/ 1) {\n\t\t\t\tattr(span1, \"data-status\", /*status*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (dirty & /*$componentOpacity*/ 16) {\n\t\t\t\tset_style(span1, \"opacity\", /*$componentOpacity*/ ctx[4]);\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span1);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction instance$F($$self, $$props, $$invalidate) {\n\tlet formattedValue;\n\tlet circleValue;\n\tlet circleOpacity;\n\tlet status;\n\tlet $isAnimated;\n\tlet $animatedOpacity;\n\tlet $animatedProgressClamped;\n\tlet $componentOpacity;\n\tconst dispatch = createEventDispatcher();\n\tlet { progress } = $$props;\n\tlet { min = 0 } = $$props;\n\tlet { max = 100 } = $$props;\n\tlet { labelBusy = 'Busy' } = $$props;\n\tlet { opacity = undefined } = $$props;\n\tconst isAnimated = getContext('isAnimated');\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(14, $isAnimated = value));\n\tconst componentOpacity = spring(opacity, { precision: 0.01 });\n\tcomponent_subscribe($$self, componentOpacity, value => $$invalidate(4, $componentOpacity = value));\n\tconst animatedValue = spring(0, { precision: 0.01 });\n\tconst animatedOpacity = spring(0, { precision: 0.01 });\n\tcomponent_subscribe($$self, animatedOpacity, value => $$invalidate(15, $animatedOpacity = value));\n\tconst animatedProgressClamped = derived([animatedValue], $animatedValue => clamp($animatedValue, min, max));\n\tcomponent_subscribe($$self, animatedProgressClamped, value => $$invalidate(16, $animatedProgressClamped = value));\n\n\tconst animatedProgressClampedUnsub = animatedProgressClamped.subscribe(value => {\n\t\tif (progress === 1 && Math.round(value) >= 100) dispatch('complete');\n\t});\n\n\tonMount(() => {\n\t\tanimatedOpacity.set(1, { hard: !$isAnimated });\n\t});\n\n\tonDestroy(() => {\n\t\tanimatedProgressClampedUnsub();\n\t});\n\n\t$$self.$$set = $$props => {\n\t\tif ('progress' in $$props) $$invalidate(9, progress = $$props.progress);\n\t\tif ('min' in $$props) $$invalidate(10, min = $$props.min);\n\t\tif ('max' in $$props) $$invalidate(11, max = $$props.max);\n\t\tif ('labelBusy' in $$props) $$invalidate(12, labelBusy = $$props.labelBusy);\n\t\tif ('opacity' in $$props) $$invalidate(13, opacity = $$props.opacity);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*opacity, $isAnimated*/ 24576) {\n\t\t\tisNumber(opacity) && componentOpacity.set(opacity, { hard: !$isAnimated });\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*progress, $isAnimated*/ 16896) {\n\t\t\tprogress && progress !== Infinity && animatedValue.set(progress * 100, { hard: !$isAnimated });\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*progress, labelBusy, $animatedProgressClamped*/ 70144) {\n\t\t\t$$invalidate(3, formattedValue = progress === Infinity\n\t\t\t? labelBusy\n\t\t\t: `${Math.round($animatedProgressClamped)}%`);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*progress, $animatedProgressClamped*/ 66048) {\n\t\t\t$$invalidate(2, circleValue = progress === Infinity\n\t\t\t? '26.5 53'\n\t\t\t: `${$animatedProgressClamped / 100 * 53} 53`);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*$animatedOpacity*/ 32768) {\n\t\t\t$$invalidate(1, circleOpacity = $animatedOpacity); // Math.min(1, progress === Infinity ? 1 : $animatedProgressClamped / 10);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*progress*/ 512) {\n\t\t\t$$invalidate(0, status = progress === Infinity ? 'busy' : 'loading');\n\t\t}\n\t};\n\n\treturn [\n\t\tstatus,\n\t\tcircleOpacity,\n\t\tcircleValue,\n\t\tformattedValue,\n\t\t$componentOpacity,\n\t\tisAnimated,\n\t\tcomponentOpacity,\n\t\tanimatedOpacity,\n\t\tanimatedProgressClamped,\n\t\tprogress,\n\t\tmin,\n\t\tmax,\n\t\tlabelBusy,\n\t\topacity,\n\t\t$isAnimated,\n\t\t$animatedOpacity,\n\t\t$animatedProgressClamped\n\t];\n}\n\nclass ProgressIndicator extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$F, create_fragment$E, safe_not_equal, {\n\t\t\tprogress: 9,\n\t\t\tmin: 10,\n\t\t\tmax: 11,\n\t\t\tlabelBusy: 12,\n\t\t\topacity: 13\n\t\t});\n\t}\n}\n\n/* src/core/ui/components/ShapeStyle.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block$g(ctx) {\n\tlet span;\n\tlet t_value = localize(/*title*/ ctx[0], /*locale*/ ctx[1]) + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"class\", /*klass*/ ctx[3]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*title, locale*/ 3 && t_value !== (t_value = localize(/*title*/ ctx[0], /*locale*/ ctx[1]) + \"\")) set_data(t, t_value);\n\n\t\t\tif (dirty & /*klass*/ 8) {\n\t\t\t\tattr(span, \"class\", /*klass*/ ctx[3]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction create_fragment$D(ctx) {\n\tlet li;\n\tlet t;\n\tlet dynamiccomponenttree;\n\tlet current;\n\tlet if_block = /*title*/ ctx[0] && create_if_block$g(ctx);\n\tdynamiccomponenttree = new DynamicComponentTree_1({ props: { items: /*items*/ ctx[2] } });\n\n\treturn {\n\t\tc() {\n\t\t\tli = element(\"li\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tt = space();\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tattr(li, \"class\", \"PinturaShapeStyle\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, li, anchor);\n\t\t\tif (if_block) if_block.m(li, null);\n\t\t\tappend(li, t);\n\t\t\tmount_component(dynamiccomponenttree, li, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (/*title*/ ctx[0]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$g(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(li, t);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*items*/ 4) dynamiccomponenttree_changes.items = /*items*/ ctx[2];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(li);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t}\n\t};\n}\n\nfunction instance$E($$self, $$props, $$invalidate) {\n\tlet klass;\n\tlet { title } = $$props;\n\tlet { locale } = $$props;\n\tlet { items } = $$props;\n\tlet { hideTitle = false } = $$props;\n\n\t$$self.$$set = $$props => {\n\t\tif ('title' in $$props) $$invalidate(0, title = $$props.title);\n\t\tif ('locale' in $$props) $$invalidate(1, locale = $$props.locale);\n\t\tif ('items' in $$props) $$invalidate(2, items = $$props.items);\n\t\tif ('hideTitle' in $$props) $$invalidate(4, hideTitle = $$props.hideTitle);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*hideTitle*/ 16) {\n\t\t\t$$invalidate(3, klass = 'PinturaShapeStyleLabel' + (hideTitle ? ' implicit' : ''));\n\t\t}\n\t};\n\n\treturn [title, locale, items, klass, hideTitle];\n}\n\nclass ShapeStyle extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$E, create_fragment$D, safe_not_equal, {\n\t\t\ttitle: 0,\n\t\t\tlocale: 1,\n\t\t\titems: 2,\n\t\t\thideTitle: 4\n\t\t});\n\t}\n}\n\nvar RGBToHSV = (r, g, b) => {\n    let v = Math.max(r, g, b), n = v - Math.min(r, g, b);\n    let h = n && (v == r ? (g - b) / n : v == g ? 2 + (b - r) / n : 4 + (r - g) / n);\n    return [(60 * (h < 0 ? h + 6 : h)) / 360, v && n / v, v];\n};\n\nvar HSVToRGB = (h, s, v) => {\n    let r, g, b;\n    const i = Math.floor(h * 6);\n    const f = h * 6 - i;\n    const p = v * (1 - s);\n    const q = v * (1 - f * s);\n    const t = v * (1 - (1 - f) * s);\n    switch (i % 6) {\n        case 0:\n            (r = v), (g = t), (b = p);\n            break;\n        case 1:\n            (r = q), (g = v), (b = p);\n            break;\n        case 2:\n            (r = p), (g = v), (b = t);\n            break;\n        case 3:\n            (r = p), (g = q), (b = v);\n            break;\n        case 4:\n            (r = t), (g = p), (b = v);\n            break;\n        case 5:\n            (r = v), (g = p), (b = q);\n            break;\n    }\n    return [r, g, b];\n};\n\n/* src/core/ui/components/ColorPreview.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$C(ctx) {\n\tlet div;\n\tlet span;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tspan = element(\"span\");\n\t\t\tattr(div, \"class\", \"PinturaColorPreview\");\n\t\t\tattr(div, \"title\", /*title*/ ctx[0]);\n\t\t\tset_style(div, \"--color\", /*colorValue*/ ctx[1]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, span);\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*title*/ 1) {\n\t\t\t\tattr(div, \"title\", /*title*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (dirty & /*colorValue*/ 2) {\n\t\t\t\tset_style(div, \"--color\", /*colorValue*/ ctx[1]);\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction instance$D($$self, $$props, $$invalidate) {\n\tlet colorValue;\n\tlet { color = undefined } = $$props;\n\tlet { title = undefined } = $$props;\n\n\t$$self.$$set = $$props => {\n\t\tif ('color' in $$props) $$invalidate(2, color = $$props.color);\n\t\tif ('title' in $$props) $$invalidate(0, title = $$props.title);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*color*/ 4) {\n\t\t\t$$invalidate(1, colorValue = color ? colorArrayToRGBA(color) : 'transparent');\n\t\t}\n\t};\n\n\treturn [title, colorValue, color];\n}\n\nclass ColorPreview extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$D, create_fragment$C, safe_not_equal, { color: 2, title: 0 });\n\t}\n}\n\nvar hexToRGB = (str) => {\n    const [, q, w, e, f] = str.split('');\n    // is shorthand hex #f00(f) (last is opacity) convert to hex\n    str =\n        str.length >= 4 && str.length <= 5\n            ? `#${q}${q}${w}${w}${e}${e}${f ? `${f}${f}` : ''}`\n            : str;\n    // split normalized hex into parts\n    const [match, r, g, b, a] = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})?$/i.exec(str) || [];\n    if (!match)\n        return;\n    return [r, g, b, a].filter((v) => v !== undefined).map((v) => parseInt(v, 16) / 255);\n};\n\nvar colorStringToColorArray = (color) => {\n    color = color.trim();\n    // if rgba(128, 128, 128, .5)\n    if (/^rgba/.test(color)) {\n        return color\n            .substring(5)\n            .split(',')\n            .map(parseFloat)\n            .map((v, i) => v / (i === 3 ? 1 : 255));\n    }\n    // if rgb(128, 128, 128)\n    if (/^rgb/.test(color)) {\n        return color\n            .substring(4)\n            .split(',')\n            .map(parseFloat)\n            .map((v) => v / 255);\n    }\n    // if #777\n    if (/^#/.test(color)) {\n        return hexToRGB(color);\n    }\n    // is possibly 255, 0, 0\n    if (/[0-9]{1,3}\\s?,\\s?[0-9]{1,3}\\s?,\\s?[0-9]{1,3}/.test(color)) {\n        return color\n            .split(',')\n            .map((v) => parseInt(v, 10))\n            .map((v) => v / 255);\n    }\n    // undefined if no idea\n};\n\nlet result$4 = null;\nvar supportsEyeDropper = () => {\n    if (result$4 === null) {\n        result$4 = isBrowser() && 'EyeDropper' in window;\n    }\n    return result$4;\n};\n\n/* src/core/ui/components/ColorPicker.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block_6$3(ctx) {\n\tlet span;\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(/*label*/ ctx[0]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*label*/ 1) set_data(t, /*label*/ ctx[0]);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (287:4) \nfunction create_label_slot(ctx) {\n\tlet span;\n\tlet colorpreview;\n\tlet t;\n\tlet current;\n\n\tcolorpreview = new ColorPreview({\n\t\t\tprops: {\n\t\t\t\tcolor: /*value*/ ctx[4],\n\t\t\t\ttitle: localize(/*title*/ ctx[8], /*locale*/ ctx[10])\n\t\t\t}\n\t\t});\n\n\tlet if_block = !/*hidePresetLabel*/ ctx[9] && create_if_block_6$3(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tcreate_component(colorpreview.$$.fragment);\n\t\t\tt = space();\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(span, \"slot\", \"label\");\n\t\t\tattr(span, \"class\", \"PinturaButtonLabel\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tmount_component(colorpreview, span, null);\n\t\t\tappend(span, t);\n\t\t\tif (if_block) if_block.m(span, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst colorpreview_changes = {};\n\t\t\tif (dirty[0] & /*value*/ 16) colorpreview_changes.color = /*value*/ ctx[4];\n\t\t\tif (dirty[0] & /*title, locale*/ 1280) colorpreview_changes.title = localize(/*title*/ ctx[8], /*locale*/ ctx[10]);\n\t\t\tcolorpreview.$set(colorpreview_changes);\n\n\t\t\tif (!/*hidePresetLabel*/ ctx[9]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_6$3(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(span, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(colorpreview.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(colorpreview.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tdestroy_component(colorpreview);\n\t\t\tif (if_block) if_block.d();\n\t\t}\n\t};\n}\n\n// (298:8) {#if enablePicker}\nfunction create_if_block_2$9(ctx) {\n\tlet div4;\n\tlet div2;\n\tlet div1;\n\tlet div0;\n\tlet t0;\n\tlet div3;\n\tlet slider;\n\tlet t1;\n\tlet t2;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tslider = new Slider({\n\t\t\tprops: {\n\t\t\t\tlabel: \"Hue\",\n\t\t\t\thideLabel: true,\n\t\t\t\tclass: \"PinturaHuePicker\",\n\t\t\t\tonchange: /*updateHue*/ ctx[27],\n\t\t\t\tvalue: /*hue*/ ctx[16],\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 1,\n\t\t\t\tstep: 0.01\n\t\t\t}\n\t\t});\n\n\tlet if_block0 = /*enableOpacity*/ ctx[11] && create_if_block_5$4(ctx);\n\tlet if_block1 = (/*enableInput*/ ctx[14] || /*canUseEyeDropper*/ ctx[15]) && create_if_block_3$6(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv4 = element(\"div\");\n\t\t\tdiv2 = element(\"div\");\n\t\t\tdiv1 = element(\"div\");\n\t\t\tdiv0 = element(\"div\");\n\t\t\tt0 = space();\n\t\t\tdiv3 = element(\"div\");\n\t\t\tcreate_component(slider.$$.fragment);\n\t\t\tt1 = space();\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt2 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(div0, \"role\", \"button\");\n\t\t\tattr(div0, \"aria-label\", \"Saturation slider\");\n\t\t\tattr(div0, \"class\", \"PinturaPickerKnob\");\n\t\t\tattr(div0, \"tabindex\", \"0\");\n\t\t\tset_style(div0, \"background-color\", /*valueAsRGBAFullyOpaque*/ ctx[20]);\n\t\t\tattr(div1, \"class\", \"PinturaPickerKnobController\");\n\t\t\tset_style(div1, \"transform\", `translate(${/*sx*/ ctx[25]}%,${/*sy*/ ctx[24]}%)`);\n\t\t\tattr(div2, \"class\", \"PinturaSaturationPicker\");\n\t\t\tset_style(div2, \"background-color\", /*valueAsRGBAFullySaturated*/ ctx[21]);\n\t\t\tset_style(div3, \"--knob-background\", /*valueAsRGBAFullySaturated*/ ctx[21]);\n\t\t\tattr(div4, \"class\", \"PinturaPicker\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div4, anchor);\n\t\t\tappend(div4, div2);\n\t\t\tappend(div2, div1);\n\t\t\tappend(div1, div0);\n\t\t\t/*div2_binding*/ ctx[42](div2);\n\t\t\tappend(div4, t0);\n\t\t\tappend(div4, div3);\n\t\t\tmount_component(slider, div3, null);\n\t\t\tappend(div4, t1);\n\t\t\tif (if_block0) if_block0.m(div4, null);\n\t\t\tappend(div4, t2);\n\t\t\tif (if_block1) if_block1.m(div4, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div0, \"nudge\", /*handleNudge*/ ctx[30]),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, div0, { preventDefault: true })),\n\t\t\t\t\tlisten(div2, \"pointerdown\", /*handlePointerDown*/ ctx[29])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*valueAsRGBAFullyOpaque*/ 1048576) {\n\t\t\t\tset_style(div0, \"background-color\", /*valueAsRGBAFullyOpaque*/ ctx[20]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*sx, sy*/ 50331648) {\n\t\t\t\tset_style(div1, \"transform\", `translate(${/*sx*/ ctx[25]}%,${/*sy*/ ctx[24]}%)`);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*valueAsRGBAFullySaturated*/ 2097152) {\n\t\t\t\tset_style(div2, \"background-color\", /*valueAsRGBAFullySaturated*/ ctx[21]);\n\t\t\t}\n\n\t\t\tconst slider_changes = {};\n\t\t\tif (dirty[0] & /*hue*/ 65536) slider_changes.value = /*hue*/ ctx[16];\n\t\t\tslider.$set(slider_changes);\n\n\t\t\tif (dirty[0] & /*valueAsRGBAFullySaturated*/ 2097152) {\n\t\t\t\tset_style(div3, \"--knob-background\", /*valueAsRGBAFullySaturated*/ ctx[21]);\n\t\t\t}\n\n\t\t\tif (/*enableOpacity*/ ctx[11]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*enableOpacity*/ 2048) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_5$4(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div4, t2);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*enableInput*/ ctx[14] || /*canUseEyeDropper*/ ctx[15]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*enableInput, canUseEyeDropper*/ 49152) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_3$6(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(div4, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(slider.$$.fragment, local);\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(slider.$$.fragment, local);\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div4);\n\t\t\t}\n\n\t\t\t/*div2_binding*/ ctx[42](null);\n\t\t\tdestroy_component(slider);\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (335:16) {#if enableOpacity}\nfunction create_if_block_5$4(ctx) {\n\tlet div;\n\tlet slider;\n\tlet current;\n\n\tslider = new Slider({\n\t\t\tprops: {\n\t\t\t\tlabel: \"Opacity\",\n\t\t\t\thideLabel: true,\n\t\t\t\tclass: \"PinturaOpacityPicker\",\n\t\t\t\tonchange: /*updateOpacity*/ ctx[28],\n\t\t\t\tvalue: /*opacity*/ ctx[17],\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 1,\n\t\t\t\tstep: 0.01\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(slider.$$.fragment);\n\t\t\tset_style(div, \"--knob-background\", /*valueAsRGBA*/ ctx[18]);\n\t\t\tset_style(div, \"--track-background\", `linear-gradient(to right,${/*valueAsRGBAFullyTransparent*/ ctx[19]},${/*valueAsRGBAFullyOpaque*/ ctx[20]})`);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(slider, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst slider_changes = {};\n\t\t\tif (dirty[0] & /*opacity*/ 131072) slider_changes.value = /*opacity*/ ctx[17];\n\t\t\tslider.$set(slider_changes);\n\n\t\t\tif (dirty[0] & /*valueAsRGBA*/ 262144) {\n\t\t\t\tset_style(div, \"--knob-background\", /*valueAsRGBA*/ ctx[18]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*valueAsRGBAFullyTransparent, valueAsRGBAFullyOpaque*/ 1572864) {\n\t\t\t\tset_style(div, \"--track-background\", `linear-gradient(to right,${/*valueAsRGBAFullyTransparent*/ ctx[19]},${/*valueAsRGBAFullyOpaque*/ ctx[20]})`);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(slider.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(slider.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(slider);\n\t\t}\n\t};\n}\n\n// (353:16) {#if enableInput || canUseEyeDropper}\nfunction create_if_block_3$6(ctx) {\n\tlet div;\n\tlet input_1;\n\tlet input_1_disabled_value;\n\tlet t;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block = /*canUseEyeDropper*/ ctx[15] && create_if_block_4$5(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tinput_1 = element(\"input\");\n\t\t\tt = space();\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(input_1, \"class\", \"PinturaColorPickerInput\");\n\t\t\tattr(input_1, \"type\", \"text\");\n\t\t\tinput_1.disabled = input_1_disabled_value = !/*enableInput*/ ctx[14];\n\t\t\tinput_1.value = /*valueAsHex*/ ctx[23];\n\t\t\tattr(div, \"class\", \"PinturColorPickerInputGroup\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, input_1);\n\t\t\tappend(div, t);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(input_1, \"keydown\", /*handleInputKeydown*/ ctx[32]),\n\t\t\t\t\tlisten(input_1, \"input\", /*handleInput*/ ctx[31])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (!current || dirty[0] & /*enableInput*/ 16384 && input_1_disabled_value !== (input_1_disabled_value = !/*enableInput*/ ctx[14])) {\n\t\t\t\tinput_1.disabled = input_1_disabled_value;\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*valueAsHex*/ 8388608 && input_1.value !== /*valueAsHex*/ ctx[23]) {\n\t\t\t\tinput_1.value = /*valueAsHex*/ ctx[23];\n\t\t\t}\n\n\t\t\tif (/*canUseEyeDropper*/ ctx[15]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*canUseEyeDropper*/ 32768) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_4$5(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (363:24) {#if canUseEyeDropper}\nfunction create_if_block_4$5(ctx) {\n\tlet button;\n\tlet current;\n\n\tbutton = new Button({\n\t\t\tprops: {\n\t\t\t\ticon: '<path stroke=\"currentColor\" stroke-linecap=\"square\" d=\"m13 14-7 7a2.704 2.704 0 0 1-3 0 2.704 2.704 0 0 1 0-3l7-7\"/><path fill=\"currentColor\" d=\"M9.475 9.475 14.5 14.5c.263.263.69.265.955.005l.783-.767a4.209 4.209 0 0 0 1.262-3.006V10l4-4c.5-.5.375-2.125-.5-3s-2.5-1-3-.5l-4 4h-.732a4.329 4.329 0 0 0-3.03 1.238l-.758.742a.7.7 0 0 0-.005.995Z\"/>',\n\t\t\t\thideLabel: true,\n\t\t\t\tlabel: \"Pick a color\",\n\t\t\t\tclass: \"PinturaEyeDropper\",\n\t\t\t\tonclick: /*handleEyeDropper*/ ctx[33]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(button.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(button, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp: noop,\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(button, detaching);\n\t\t}\n\t};\n}\n\n// (378:8) {#if enablePresets}\nfunction create_if_block$f(ctx) {\n\tlet radiogroup;\n\tlet current;\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tlabel: localize(/*locale*/ ctx[10].labelColorPalette, /*locale*/ ctx[10]),\n\t\t\t\tclass: arrayJoin([\n\t\t\t\t\t'PinturaColorPresets',\n\t\t\t\t\t/*hidePresetLabel*/ ctx[9]\n\t\t\t\t\t? 'PinturaColorPresetsGrid'\n\t\t\t\t\t: 'PinturaColorPresetsList'\n\t\t\t\t]),\n\t\t\t\thideLabel: false,\n\t\t\t\tname: /*name*/ ctx[1],\n\t\t\t\tvalue: /*value*/ ctx[4],\n\t\t\t\toptionGroupClass: \"PinturaListOptionGroup\",\n\t\t\t\toptionClass: \"PinturaListOption\",\n\t\t\t\toptions: /*options*/ ctx[2].map(/*func*/ ctx[43]),\n\t\t\t\tselectedIndex: /*selectedIndex*/ ctx[3],\n\t\t\t\toptionMapper: /*optionMapper*/ ctx[7],\n\t\t\t\toptionLabelClass: /*optionLabelClass*/ ctx[6],\n\t\t\t\tonchange: /*func_1*/ ctx[44],\n\t\t\t\t$$slots: {\n\t\t\t\t\toption: [\n\t\t\t\t\t\tcreate_option_slot$4,\n\t\t\t\t\t\t({ option }) => ({ 60: option }),\n\t\t\t\t\t\t({ option }) => [0, option ? 536870912 : 0]\n\t\t\t\t\t],\n\t\t\t\t\tgroup: [\n\t\t\t\t\t\tcreate_group_slot,\n\t\t\t\t\t\t({ option }) => ({ 60: option }),\n\t\t\t\t\t\t({ option }) => [0, option ? 536870912 : 0]\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radiogroup, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 1024) radiogroup_changes.label = localize(/*locale*/ ctx[10].labelColorPalette, /*locale*/ ctx[10]);\n\n\t\t\tif (dirty[0] & /*hidePresetLabel*/ 512) radiogroup_changes.class = arrayJoin([\n\t\t\t\t'PinturaColorPresets',\n\t\t\t\t/*hidePresetLabel*/ ctx[9]\n\t\t\t\t? 'PinturaColorPresetsGrid'\n\t\t\t\t: 'PinturaColorPresetsList'\n\t\t\t]);\n\n\t\t\tif (dirty[0] & /*name*/ 2) radiogroup_changes.name = /*name*/ ctx[1];\n\t\t\tif (dirty[0] & /*value*/ 16) radiogroup_changes.value = /*value*/ ctx[4];\n\t\t\tif (dirty[0] & /*options*/ 4) radiogroup_changes.options = /*options*/ ctx[2].map(/*func*/ ctx[43]);\n\t\t\tif (dirty[0] & /*selectedIndex*/ 8) radiogroup_changes.selectedIndex = /*selectedIndex*/ ctx[3];\n\t\t\tif (dirty[0] & /*optionMapper*/ 128) radiogroup_changes.optionMapper = /*optionMapper*/ ctx[7];\n\t\t\tif (dirty[0] & /*optionLabelClass*/ 64) radiogroup_changes.optionLabelClass = /*optionLabelClass*/ ctx[6];\n\n\t\t\tif (dirty[0] & /*hidePresetLabel*/ 512 | dirty[1] & /*$$scope, option*/ 1610612736) {\n\t\t\t\tradiogroup_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radiogroup, detaching);\n\t\t}\n\t};\n}\n\n// (402:16) \nfunction create_group_slot(ctx) {\n\tlet span;\n\tlet t_value = /*option*/ ctx[60].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"slot\", \"group\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 536870912 && t_value !== (t_value = /*option*/ ctx[60].label + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (407:20) {#if !hidePresetLabel}\nfunction create_if_block_1$b(ctx) {\n\tlet span;\n\tlet t_value = /*option*/ ctx[60].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t\tattr(span, \"class\", \"PinturaButtonLabel\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 536870912 && t_value !== (t_value = /*option*/ ctx[60].label + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (405:16) \nfunction create_option_slot$4(ctx) {\n\tlet span;\n\tlet colorpreview;\n\tlet t;\n\tlet current;\n\n\tcolorpreview = new ColorPreview({\n\t\t\tprops: { color: /*option*/ ctx[60].value }\n\t\t});\n\n\tlet if_block = !/*hidePresetLabel*/ ctx[9] && create_if_block_1$b(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tcreate_component(colorpreview.$$.fragment);\n\t\t\tt = space();\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(span, \"slot\", \"option\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tmount_component(colorpreview, span, null);\n\t\t\tappend(span, t);\n\t\t\tif (if_block) if_block.m(span, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst colorpreview_changes = {};\n\t\t\tif (dirty[1] & /*option*/ 536870912) colorpreview_changes.color = /*option*/ ctx[60].value;\n\t\t\tcolorpreview.$set(colorpreview_changes);\n\n\t\t\tif (!/*hidePresetLabel*/ ctx[9]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_1$b(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(span, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(colorpreview.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(colorpreview.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tdestroy_component(colorpreview);\n\t\t\tif (if_block) if_block.d();\n\t\t}\n\t};\n}\n\n// (296:4) \nfunction create_details_slot(ctx) {\n\tlet div;\n\tlet t;\n\tlet current;\n\tlet if_block0 = /*enablePicker*/ ctx[13] && create_if_block_2$9(ctx);\n\tlet if_block1 = /*enablePresets*/ ctx[12] && create_if_block$f(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(div, \"slot\", \"details\");\n\t\t\tattr(div, \"class\", \"PinturaColorPickerPanel\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block0) if_block0.m(div, null);\n\t\t\tappend(div, t);\n\t\t\tif (if_block1) if_block1.m(div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*enablePicker*/ ctx[13]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*enablePicker*/ 8192) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_2$9(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*enablePresets*/ ctx[12]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*enablePresets*/ 4096) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block$f(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t}\n\t};\n}\n\nfunction create_fragment$B(ctx) {\n\tlet panel;\n\tlet current;\n\n\tpanel = new Panel({\n\t\t\tprops: {\n\t\t\t\tbuttonClass: arrayJoin(['PinturaColorPickerButton', /*buttonClass*/ ctx[5]]),\n\t\t\t\t$$slots: {\n\t\t\t\t\tdetails: [create_details_slot],\n\t\t\t\t\tlabel: [create_label_slot]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(panel.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(panel, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst panel_changes = {};\n\t\t\tif (dirty[0] & /*buttonClass*/ 32) panel_changes.buttonClass = arrayJoin(['PinturaColorPickerButton', /*buttonClass*/ ctx[5]]);\n\n\t\t\tif (dirty[0] & /*locale, hidePresetLabel, name, value, options, selectedIndex, optionMapper, optionLabelClass, enablePresets, canUseEyeDropper, enableInput, valueAsHex, valueAsRGBA, valueAsRGBAFullyTransparent, valueAsRGBAFullyOpaque, opacity, enableOpacity, valueAsRGBAFullySaturated, hue, input, sx, sy, enablePicker, label, title*/ 67108831 | dirty[1] & /*$$scope*/ 1073741824) {\n\t\t\t\tpanel_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tpanel.$set(panel_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(panel.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(panel.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(panel, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$C($$self, $$props, $$invalidate) {\n\tlet canUseEyeDropper;\n\tlet sx;\n\tlet sy;\n\tlet isPossibleShortHand;\n\tlet valueAsHex;\n\tlet { label = undefined } = $$props;\n\tlet { name = undefined } = $$props;\n\tlet { options = [] } = $$props;\n\tlet { selectedIndex = -1 } = $$props;\n\tlet { value = undefined } = $$props;\n\tlet { buttonClass = undefined } = $$props;\n\tlet { optionLabelClass = undefined } = $$props;\n\tlet { optionMapper = undefined } = $$props;\n\tlet { onchange = undefined } = $$props;\n\tlet { title = undefined } = $$props;\n\tlet { hidePresetLabel = true } = $$props;\n\tlet { locale = undefined } = $$props;\n\tlet { enableOpacity = true } = $$props;\n\tlet { enablePresets = true } = $$props;\n\tlet { enablePicker = true } = $$props;\n\tlet { enableInput = false } = $$props;\n\tlet { enableEyeDropper = false } = $$props;\n\n\t// inputs\n\tlet hue;\n\n\tlet saturation;\n\tlet brightness;\n\tlet opacity;\n\n\t// shortcuts\n\tlet valueAsRGB;\n\n\tlet valueAsRGBA;\n\tlet valueAsRGBAFullyTransparent;\n\tlet valueAsRGBAFullyOpaque = 'transparent';\n\tlet valueAsRGBAFullySaturated = 'transparent';\n\n\t// remember previous value\n\tlet valuePrev;\n\n\tconst updateProps = (color, syncControls) => {\n\t\tvalueAsRGB = [color[0], color[1], color[2]];\n\n\t\tif (syncControls) {\n\t\t\tlet valueAsHSV = RGBToHSV(...valueAsRGB);\n\t\t\tlet hueValue = valueAsHSV[0];\n\t\t\tlet saturationValue = valueAsHSV[1];\n\t\t\tlet brightnessValue = valueAsHSV[2];\n\n\t\t\t// need to know if user set these values otherwise they might jump to other locations when setting full red or full black\n\t\t\tif (isNumber(hueUserOffset)) hueValue = hueUserOffset;\n\n\t\t\tif (isNumber(saturationUserOffset)) saturationValue = saturationUserOffset;\n\t\t\tif (isNumber(brightnessUserOffset)) brightnessValue = brightnessUserOffset;\n\t\t\t$$invalidate(16, hue = hueValue);\n\t\t\t$$invalidate(37, saturation = saturationValue);\n\t\t\t$$invalidate(38, brightness = brightnessValue);\n\t\t\t$$invalidate(17, opacity = isNumber(color[3]) ? color[3] : 1);\n\t\t}\n\n\t\t$$invalidate(18, valueAsRGBA = colorArrayToRGBA(color));\n\t\t$$invalidate(19, valueAsRGBAFullyTransparent = colorArrayToRGBA([...valueAsRGB, 0]));\n\t\t$$invalidate(20, valueAsRGBAFullyOpaque = colorArrayToRGBA([...valueAsRGB, 1]));\n\t\t$$invalidate(21, valueAsRGBAFullySaturated = colorArrayToRGBA(HSVToRGB(hue, 1, 1)));\n\t};\n\n\tconst update = () => {\n\t\tconst rgb = HSVToRGB(hue, saturation, brightness);\n\t\tconst rgba = [...rgb, opacity];\n\t\tupdateProps(rgba);\n\t\tonchange(rgba);\n\t};\n\n\tconst updateColorArray = arr => {\n\t\tconst rgba = arr.length === 3 ? [...arr, 1] : arr;\n\t\tresetUserOffsets();\n\t\tupdateProps(rgba, true);\n\t\tonchange(rgba);\n\t};\n\n\t// we track this so the hue slider stays at it's position even for full black or white colors\n\tconst resetUserOffsets = () => {\n\t\tsaturationUserOffset = undefined;\n\t\tbrightnessUserOffset = undefined;\n\t\thueUserOffset = undefined;\n\t};\n\n\tlet saturationUserOffset;\n\tlet brightnessUserOffset;\n\tlet hueUserOffset;\n\n\tconst updateHue = h => {\n\t\t$$invalidate(16, hue = h);\n\t\thueUserOffset = h;\n\t\tupdate();\n\t};\n\n\tconst updateSaturationAndBrightness = (s, b) => {\n\t\t$$invalidate(37, saturation = s);\n\t\t$$invalidate(38, brightness = b);\n\t\tsaturationUserOffset = s;\n\t\tbrightnessUserOffset = b;\n\t\tupdate();\n\t};\n\n\tconst updateOpacity = o => {\n\t\t$$invalidate(17, opacity = o);\n\t\tupdate();\n\t};\n\n\tconst setValueByOffset = (offset, inputSize) => {\n\t\tconst x = clamp(offset.x / inputSize.width, 0, 1);\n\t\tconst y = clamp(offset.y / inputSize.height, 0, 1);\n\t\tupdateSaturationAndBrightness(x, 1 - y);\n\t};\n\n\tlet input;\n\tlet inputSize;\n\tlet inputOffset;\n\tlet inputPageOffset;\n\n\tconst handlePointerDown = e => {\n\t\te.stopPropagation();\n\t\tinputSize = sizeCreate(input.offsetWidth, input.offsetHeight);\n\t\tinputOffset = vectorCreateFromPointerEventOffset(e);\n\t\tinputPageOffset = vectorCreateFromPointerEvent(e);\n\t\tsetValueByOffset(inputOffset, inputSize);\n\t\tdocument.documentElement.addEventListener('pointermove', handlePointerMove);\n\t\tdocument.documentElement.addEventListener('pointerup', handlePointerUp);\n\t};\n\n\tconst handlePointerMove = e => {\n\t\tconst d = vectorSubtract(vectorCreateFromPointerEvent(e), inputPageOffset);\n\t\tsetValueByOffset(vectorAdd(vectorClone(inputOffset), d), inputSize);\n\t};\n\n\tconst handlePointerUp = e => {\n\t\tinputSize = undefined;\n\t\tdocument.documentElement.removeEventListener('pointermove', handlePointerMove);\n\t\tdocument.documentElement.removeEventListener('pointerup', handlePointerUp);\n\t};\n\n\tconst handleNudge = e => {\n\t\tinputSize = sizeCreate(input.offsetWidth, input.offsetHeight);\n\t\tconst x = sx / 100 * inputSize.width;\n\t\tconst y = sy / 100 * inputSize.height;\n\t\tsetValueByOffset({ x: x + e.detail.x, y: y + e.detail.y }, inputSize);\n\t};\n\n\t//\n\t// hex input\n\t//\n\tlet currentInput;\n\n\tconst colorArrayToHex = (color, opacityEnabled, isShorthand) => {\n\t\tlet parts = color.map(v => Math.round(v * 255).toString(16).toLowerCase().padStart(2, '0'));\n\t\tif (!opacityEnabled && parts.length > 3 || parts[3] === 'ff') parts.pop();\n\t\tif (isShorthand) parts = parts.map(p => p.substring(0, 1));\n\t\treturn `#${parts.join('')}`;\n\t};\n\n\t/*\n#f -> false\n#f0 -> false\n#f00 \u2192 true (l=4)\n#f009 \u2192 true (l=5)\n#f0099 \u2192 false\n#ff0000 \u2192 true (l=7)\n#ff00009 \u2192 false\n#ff000099 \u2192 true (l=9)\n*/\n\tconst handleInput = e => {\n\t\tconst { value } = e.target;\n\n\t\t// no # at start or is invalid length\n\t\tconst l = value.length;\n\n\t\tif (!value.startsWith('#') || l < 4 || l === 6 || l === 8 || l > 9) return;\n\n\t\t// can't handle opacity input\n\t\tif (!enableOpacity && l > 7) return;\n\n\t\t// convert to rgba\n\t\tconst rgba = colorStringToColorArray(value);\n\n\t\tif (!rgba) return;\n\n\t\t// store current value so we know if we are typing a short hand\n\t\t$$invalidate(40, currentInput = value);\n\n\t\tresetUserOffsets();\n\t\tupdateProps(rgba);\n\t\tonchange(rgba);\n\t};\n\n\tconst handleInputKeydown = e => {\n\t\te.stopPropagation();\n\t};\n\n\tconst handleEyeDropper = e => {\n\t\tnew EyeDropper().open().then(({ sRGBHex }) => {\n\t\t\t// color\n\t\t\tconst rgba = colorStringToColorArray(sRGBHex);\n\n\t\t\tif (!rgba) return;\n\n\t\t\t// make sure opacity is set to 1, can be zero on Linux+Chrome\n\t\t\trgba[3] = 1;\n\n\t\t\t// store current value so we know if we are typing a short hand\n\t\t\t$$invalidate(40, currentInput = value);\n\n\t\t\tresetUserOffsets();\n\t\t\tupdateProps(rgba);\n\t\t\tonchange(rgba);\n\t\t}).catch(err => {\n\t\t\t\n\t\t}); // cancelled\n\t};\n\n\tfunction getLabel(label) {\n\t\treturn isFunction(label) ? label(locale) : label;\n\t}\n\n\tfunction div2_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tinput = $$value;\n\t\t\t$$invalidate(22, input);\n\t\t});\n\t}\n\n\tconst func = ([color, label]) => [color, getLabel(label), { title: getLabel(label) }];\n\tconst func_1 = detail => updateColorArray(detail.value);\n\n\t$$self.$$set = $$props => {\n\t\tif ('label' in $$props) $$invalidate(0, label = $$props.label);\n\t\tif ('name' in $$props) $$invalidate(1, name = $$props.name);\n\t\tif ('options' in $$props) $$invalidate(2, options = $$props.options);\n\t\tif ('selectedIndex' in $$props) $$invalidate(3, selectedIndex = $$props.selectedIndex);\n\t\tif ('value' in $$props) $$invalidate(4, value = $$props.value);\n\t\tif ('buttonClass' in $$props) $$invalidate(5, buttonClass = $$props.buttonClass);\n\t\tif ('optionLabelClass' in $$props) $$invalidate(6, optionLabelClass = $$props.optionLabelClass);\n\t\tif ('optionMapper' in $$props) $$invalidate(7, optionMapper = $$props.optionMapper);\n\t\tif ('onchange' in $$props) $$invalidate(35, onchange = $$props.onchange);\n\t\tif ('title' in $$props) $$invalidate(8, title = $$props.title);\n\t\tif ('hidePresetLabel' in $$props) $$invalidate(9, hidePresetLabel = $$props.hidePresetLabel);\n\t\tif ('locale' in $$props) $$invalidate(10, locale = $$props.locale);\n\t\tif ('enableOpacity' in $$props) $$invalidate(11, enableOpacity = $$props.enableOpacity);\n\t\tif ('enablePresets' in $$props) $$invalidate(12, enablePresets = $$props.enablePresets);\n\t\tif ('enablePicker' in $$props) $$invalidate(13, enablePicker = $$props.enablePicker);\n\t\tif ('enableInput' in $$props) $$invalidate(14, enableInput = $$props.enableInput);\n\t\tif ('enableEyeDropper' in $$props) $$invalidate(36, enableEyeDropper = $$props.enableEyeDropper);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[1] & /*enableEyeDropper*/ 32) {\n\t\t\t$$invalidate(15, canUseEyeDropper = enableEyeDropper && supportsEyeDropper());\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*value*/ 16 | $$self.$$.dirty[1] & /*valuePrev*/ 256) {\n\t\t\t// update initial value if supplied\n\t\t\tif (value && (!valuePrev || !arrayEqual(value, valuePrev))) {\n\t\t\t\t$$invalidate(39, valuePrev = [...value]);\n\t\t\t\tupdateProps(value, true);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*saturation*/ 64) {\n\t\t\t$$invalidate(25, sx = saturation * 100);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*brightness*/ 128) {\n\t\t\t$$invalidate(24, sy = 100 - brightness * 100);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*currentInput*/ 512) {\n\t\t\t$$invalidate(41, isPossibleShortHand = currentInput\n\t\t\t? currentInput.length >= 4 && currentInput.length <= 5\n\t\t\t: false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*enableInput, canUseEyeDropper, value, enableOpacity*/ 51216 | $$self.$$.dirty[1] & /*isPossibleShortHand*/ 1024) {\n\t\t\t$$invalidate(23, valueAsHex = (enableInput || canUseEyeDropper) && value\n\t\t\t? colorArrayToHex(value, enableOpacity, isPossibleShortHand)\n\t\t\t: undefined);\n\t\t}\n\t};\n\n\treturn [\n\t\tlabel,\n\t\tname,\n\t\toptions,\n\t\tselectedIndex,\n\t\tvalue,\n\t\tbuttonClass,\n\t\toptionLabelClass,\n\t\toptionMapper,\n\t\ttitle,\n\t\thidePresetLabel,\n\t\tlocale,\n\t\tenableOpacity,\n\t\tenablePresets,\n\t\tenablePicker,\n\t\tenableInput,\n\t\tcanUseEyeDropper,\n\t\thue,\n\t\topacity,\n\t\tvalueAsRGBA,\n\t\tvalueAsRGBAFullyTransparent,\n\t\tvalueAsRGBAFullyOpaque,\n\t\tvalueAsRGBAFullySaturated,\n\t\tinput,\n\t\tvalueAsHex,\n\t\tsy,\n\t\tsx,\n\t\tupdateColorArray,\n\t\tupdateHue,\n\t\tupdateOpacity,\n\t\thandlePointerDown,\n\t\thandleNudge,\n\t\thandleInput,\n\t\thandleInputKeydown,\n\t\thandleEyeDropper,\n\t\tgetLabel,\n\t\tonchange,\n\t\tenableEyeDropper,\n\t\tsaturation,\n\t\tbrightness,\n\t\tvaluePrev,\n\t\tcurrentInput,\n\t\tisPossibleShortHand,\n\t\tdiv2_binding,\n\t\tfunc,\n\t\tfunc_1\n\t];\n}\n\nclass ColorPicker extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$C,\n\t\t\tcreate_fragment$B,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tlabel: 0,\n\t\t\t\tname: 1,\n\t\t\t\toptions: 2,\n\t\t\t\tselectedIndex: 3,\n\t\t\t\tvalue: 4,\n\t\t\t\tbuttonClass: 5,\n\t\t\t\toptionLabelClass: 6,\n\t\t\t\toptionMapper: 7,\n\t\t\t\tonchange: 35,\n\t\t\t\ttitle: 8,\n\t\t\t\thidePresetLabel: 9,\n\t\t\t\tlocale: 10,\n\t\t\t\tenableOpacity: 11,\n\t\t\t\tenablePresets: 12,\n\t\t\t\tenablePicker: 13,\n\t\t\t\tenableInput: 14,\n\t\t\t\tenableEyeDropper: 36\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n}\n\n/* src/core/ui/components/ShorthandControl.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$A(ctx) {\n\tlet div;\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*subcontrolLinked*/ ctx[0] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaShorthandControl PinturaShapeStyle\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(dynamiccomponenttree, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*subcontrolLinked*/ 1) dynamiccomponenttree_changes.items = /*subcontrolLinked*/ ctx[0];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t}\n\t};\n}\n\nfunction instance$B($$self, $$props, $$invalidate) {\n\tlet subcontrolProps;\n\tlet subcontrolLinked;\n\tlet { value } = $$props;\n\tlet { onchange } = $$props;\n\tlet { controls = [] } = $$props;\n\n\tconst filterSubcontrolProps = props => {\n\t\tconst { controls, ...filteredProps } = props;\n\t\treturn filteredProps;\n\t};\n\n\t$$self.$$set = $$new_props => {\n\t\t$$invalidate(6, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)));\n\t\tif ('value' in $$new_props) $$invalidate(1, value = $$new_props.value);\n\t\tif ('onchange' in $$new_props) $$invalidate(2, onchange = $$new_props.onchange);\n\t\tif ('controls' in $$new_props) $$invalidate(3, controls = $$new_props.controls);\n\t};\n\n\t$$self.$$.update = () => {\n\t\t$$invalidate(4, subcontrolProps = filterSubcontrolProps($$props));\n\n\t\tif ($$self.$$.dirty & /*controls, subcontrolProps, value, onchange*/ 30) {\n\t\t\t$$invalidate(0, subcontrolLinked = controls.map((control, index) => {\n\t\t\t\tconst [id, name, props] = control;\n\n\t\t\t\treturn [\n\t\t\t\t\tid,\n\t\t\t\t\tname,\n\t\t\t\t\t{\n\t\t\t\t\t\t...subcontrolProps,\n\t\t\t\t\t\t...props,\n\t\t\t\t\t\tvalue: value[index],\n\t\t\t\t\t\tonchange: controlValue => {\n\t\t\t\t\t\t\tconst newValue = [...value];\n\t\t\t\t\t\t\tnewValue[index] = controlValue;\n\t\t\t\t\t\t\tonchange(newValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t];\n\t\t\t}));\n\t\t}\n\t};\n\n\t$$props = exclude_internal_props($$props);\n\treturn [subcontrolLinked, value, onchange, controls, subcontrolProps];\n}\n\nclass ShorthandControl extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$B, create_fragment$A, safe_not_equal, { value: 1, onchange: 2, controls: 3 });\n\t}\n}\n\n/* src/core/ui/components/Select.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$z(ctx) {\n\tlet dropdown;\n\tlet current;\n\n\tdropdown = new Dropdown({\n\t\t\tprops: {\n\t\t\t\tlabel: /*dropdownLabel*/ ctx[4],\n\t\t\t\toptions: /*options*/ ctx[1],\n\t\t\t\ttitle: /*title*/ ctx[2],\n\t\t\t\tselectedIndex: /*selectedOptionIndex*/ ctx[5],\n\t\t\t\tonchange: /*func*/ ctx[10]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dropdown.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dropdown, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tconst dropdown_changes = {};\n\t\t\tif (dirty & /*dropdownLabel*/ 16) dropdown_changes.label = /*dropdownLabel*/ ctx[4];\n\t\t\tif (dirty & /*options*/ 2) dropdown_changes.options = /*options*/ ctx[1];\n\t\t\tif (dirty & /*title*/ 4) dropdown_changes.title = /*title*/ ctx[2];\n\t\t\tif (dirty & /*selectedOptionIndex*/ 32) dropdown_changes.selectedIndex = /*selectedOptionIndex*/ ctx[5];\n\t\t\tif (dirty & /*selectedIndex, onchange*/ 9) dropdown_changes.onchange = /*func*/ ctx[10];\n\t\t\tdropdown.$set(dropdown_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dropdown.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dropdown.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dropdown, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$A($$self, $$props, $$invalidate) {\n\tlet selectedOption;\n\tlet selectedOptionIndex;\n\tlet selectedLabel;\n\tlet dropdownLabel;\n\tlet { options } = $$props;\n\tlet { title } = $$props;\n\tlet { onchange } = $$props;\n\tlet { selectedIndex = -1 } = $$props;\n\tlet { value = undefined } = $$props;\n\tlet { label = undefined } = $$props;\n\n\t// select by value or select first option\n\tconst getSelectedOption = (options, selectedIndex, value) => {\n\t\tif (!options) return;\n\n\t\tif (selectedIndex > -1) {\n\t\t\treturn options[selectedIndex];\n\t\t}\n\n\t\tif (value !== undefined) {\n\t\t\treturn options.find(option => option[0] === value);\n\t\t}\n\n\t\treturn options[0];\n\t};\n\n\tconst func = item => {\n\t\t$$invalidate(0, selectedIndex = item.index);\n\t\tonchange && onchange(item);\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('options' in $$props) $$invalidate(1, options = $$props.options);\n\t\tif ('title' in $$props) $$invalidate(2, title = $$props.title);\n\t\tif ('onchange' in $$props) $$invalidate(3, onchange = $$props.onchange);\n\t\tif ('selectedIndex' in $$props) $$invalidate(0, selectedIndex = $$props.selectedIndex);\n\t\tif ('value' in $$props) $$invalidate(6, value = $$props.value);\n\t\tif ('label' in $$props) $$invalidate(7, label = $$props.label);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*options, selectedIndex, value*/ 67) {\n\t\t\t// currently active option\n\t\t\t$$invalidate(9, selectedOption = getSelectedOption(options, selectedIndex, value));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*options, selectedOption*/ 514) {\n\t\t\t$$invalidate(5, selectedOptionIndex = options && options.findIndex(option => option === selectedOption));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*selectedOption*/ 512) {\n\t\t\t// label to show\n\t\t\t$$invalidate(8, selectedLabel = selectedOption && selectedOption[1]);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*label, selectedLabel*/ 384) {\n\t\t\t$$invalidate(4, dropdownLabel = label || selectedLabel);\n\t\t}\n\t};\n\n\treturn [\n\t\tselectedIndex,\n\t\toptions,\n\t\ttitle,\n\t\tonchange,\n\t\tdropdownLabel,\n\t\tselectedOptionIndex,\n\t\tvalue,\n\t\tlabel,\n\t\tselectedLabel,\n\t\tselectedOption,\n\t\tfunc\n\t];\n}\n\nclass Select extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$A, create_fragment$z, safe_not_equal, {\n\t\t\toptions: 1,\n\t\t\ttitle: 2,\n\t\t\tonchange: 3,\n\t\t\tselectedIndex: 0,\n\t\t\tvalue: 6,\n\t\t\tlabel: 7\n\t\t});\n\t}\n}\n\n/* src/core/ui/components/DynamicComponentTree.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context$4(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[9] = list[i][0];\n\tchild_ctx[0] = list[i][1];\n\tchild_ctx[10] = list[i][2];\n\tchild_ctx[2] = list[i][3];\n\treturn child_ctx;\n}\n\n// (78:4) {:else}\nfunction create_else_block$7(ctx) {\n\tlet switch_instance;\n\tlet switch_instance_anchor;\n\tlet current;\n\tconst switch_instance_spread_levels = [/*props*/ ctx[10]];\n\tvar switch_value = /*ComponentMap*/ ctx[3][/*node*/ ctx[9]] || /*node*/ ctx[9];\n\n\tfunction switch_props(ctx, dirty) {\n\t\tlet switch_instance_props = {};\n\n\t\tfor (let i = 0; i < switch_instance_spread_levels.length; i += 1) {\n\t\t\tswitch_instance_props = assign(switch_instance_props, switch_instance_spread_levels[i]);\n\t\t}\n\n\t\tif (dirty !== undefined && dirty & /*children*/ 4) {\n\t\t\tswitch_instance_props = assign(switch_instance_props, get_spread_update(switch_instance_spread_levels, [get_spread_object(/*props*/ ctx[10])]));\n\t\t}\n\n\t\treturn { props: switch_instance_props };\n\t}\n\n\tif (switch_value) {\n\t\tswitch_instance = construct_svelte_component(switch_value, switch_props(ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tif (switch_instance) create_component(switch_instance.$$.fragment);\n\t\t\tswitch_instance_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (switch_instance) mount_component(switch_instance, target, anchor);\n\t\t\tinsert(target, switch_instance_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*children*/ 4 && switch_value !== (switch_value = /*ComponentMap*/ ctx[3][/*node*/ ctx[9]] || /*node*/ ctx[9])) {\n\t\t\t\tif (switch_instance) {\n\t\t\t\t\tgroup_outros();\n\t\t\t\t\tconst old_component = switch_instance;\n\n\t\t\t\t\ttransition_out(old_component.$$.fragment, 1, 0, () => {\n\t\t\t\t\t\tdestroy_component(old_component, 1);\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (switch_value) {\n\t\t\t\t\tswitch_instance = construct_svelte_component(switch_value, switch_props(ctx, dirty));\n\t\t\t\t\tcreate_component(switch_instance.$$.fragment);\n\t\t\t\t\ttransition_in(switch_instance.$$.fragment, 1);\n\t\t\t\t\tmount_component(switch_instance, switch_instance_anchor.parentNode, switch_instance_anchor);\n\t\t\t\t} else {\n\t\t\t\t\tswitch_instance = null;\n\t\t\t\t}\n\t\t\t} else if (switch_value) {\n\t\t\t\tconst switch_instance_changes = (dirty & /*children*/ 4)\n\t\t\t\t? get_spread_update(switch_instance_spread_levels, [get_spread_object(/*props*/ ctx[10])])\n\t\t\t\t: {};\n\n\t\t\t\tswitch_instance.$set(switch_instance_changes);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\tif (switch_instance) transition_in(switch_instance.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tif (switch_instance) transition_out(switch_instance.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(switch_instance_anchor);\n\t\t\t}\n\n\t\t\tif (switch_instance) destroy_component(switch_instance, detaching);\n\t\t}\n\t};\n}\n\n// (68:4) {#if !isComponent(node)}\nfunction create_if_block$e(ctx) {\n\tlet previous_tag = /*node*/ ctx[9];\n\tlet svelte_element_anchor;\n\tlet svelte_element = /*node*/ ctx[9] && create_dynamic_element(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (svelte_element) svelte_element.c();\n\t\t\tsvelte_element_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (svelte_element) svelte_element.m(target, anchor);\n\t\t\tinsert(target, svelte_element_anchor, anchor);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*node*/ ctx[9]) {\n\t\t\t\tif (!previous_tag) {\n\t\t\t\t\tsvelte_element = create_dynamic_element(ctx);\n\t\t\t\t\tprevious_tag = /*node*/ ctx[9];\n\t\t\t\t\tsvelte_element.c();\n\t\t\t\t\tsvelte_element.m(svelte_element_anchor.parentNode, svelte_element_anchor);\n\t\t\t\t} else if (safe_not_equal(previous_tag, /*node*/ ctx[9])) {\n\t\t\t\t\tsvelte_element.d(1);\n\t\t\t\t\tsvelte_element = create_dynamic_element(ctx);\n\t\t\t\t\tprevious_tag = /*node*/ ctx[9];\n\t\t\t\t\tsvelte_element.c();\n\t\t\t\t\tsvelte_element.m(svelte_element_anchor.parentNode, svelte_element_anchor);\n\t\t\t\t} else {\n\t\t\t\t\tsvelte_element.p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else if (previous_tag) {\n\t\t\t\tsvelte_element.d(1);\n\t\t\t\tsvelte_element = null;\n\t\t\t\tprevious_tag = /*node*/ ctx[9];\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to(local) {\n\t\t\ttransition_out(svelte_element, local);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(svelte_element_anchor);\n\t\t\t}\n\n\t\t\tif (svelte_element) svelte_element.d(detaching);\n\t\t}\n\t};\n}\n\n// (74:38) \nfunction create_if_block_3$5(ctx) {\n\tlet html_tag;\n\tlet raw_value = /*props*/ ctx[10].innerHTML + \"\";\n\tlet html_anchor;\n\n\treturn {\n\t\tc() {\n\t\t\thtml_tag = new HtmlTag(false);\n\t\t\thtml_anchor = empty();\n\t\t\thtml_tag.a = html_anchor;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\thtml_tag.m(raw_value, target, anchor);\n\t\t\tinsert(target, html_anchor, anchor);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*children*/ 4 && raw_value !== (raw_value = /*props*/ ctx[10].innerHTML + \"\")) html_tag.p(raw_value);\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(html_anchor);\n\t\t\t\thtml_tag.d();\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (72:40) \nfunction create_if_block_2$8(ctx) {\n\tlet t_value = /*props*/ ctx[10].textContent + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tt = text(t_value);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, t, anchor);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*children*/ 4 && t_value !== (t_value = /*props*/ ctx[10].textContent + \"\")) set_data(t, t_value);\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (70:12) {#if children && children.length}\nfunction create_if_block_1$a(ctx) {\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: {\n\t\t\t\titems: /*children*/ ctx[2],\n\t\t\t\tdiscardEmptyItems: true\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*children*/ 4) dynamiccomponenttree_changes.items = /*children*/ ctx[2];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t}\n\t};\n}\n\n// (69:8) <svelte:element this={node} {...getElementAttributes(props)}>\nfunction create_dynamic_element(ctx) {\n\tlet svelte_element;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet t;\n\tlet current;\n\tconst if_block_creators = [create_if_block_1$a, create_if_block_2$8, create_if_block_3$5];\n\tconst if_blocks = [];\n\n\tfunction select_block_type_1(ctx, dirty) {\n\t\tif (/*children*/ ctx[2] && /*children*/ ctx[2].length) return 0;\n\t\tif (/*props*/ ctx[10].textContent) return 1;\n\t\tif (/*props*/ ctx[10].innerHTML) return 2;\n\t\treturn -1;\n\t}\n\n\tif (~(current_block_type_index = select_block_type_1(ctx))) {\n\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t}\n\n\tlet svelte_element_levels = [/*getElementAttributes*/ ctx[4](/*props*/ ctx[10])];\n\tlet svelte_element_data = {};\n\n\tfor (let i = 0; i < svelte_element_levels.length; i += 1) {\n\t\tsvelte_element_data = assign(svelte_element_data, svelte_element_levels[i]);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tsvelte_element = element(/*node*/ ctx[9]);\n\t\t\tif (if_block) if_block.c();\n\t\t\tt = space();\n\t\t\tset_dynamic_element_data(/*node*/ ctx[9])(svelte_element, svelte_element_data);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, svelte_element, anchor);\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].m(svelte_element, null);\n\t\t\t}\n\n\t\t\tappend(svelte_element, t);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type_1(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tgroup_outros();\n\n\t\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\t\tif (!if_block) {\n\t\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\t\tif_block.c();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t\t}\n\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(svelte_element, t);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tset_dynamic_element_data(/*node*/ ctx[9])(svelte_element, svelte_element_data = get_spread_update(svelte_element_levels, [\n\t\t\t\tdirty & /*children*/ 4 && /*getElementAttributes*/ ctx[4](/*props*/ ctx[10])\n\t\t\t]));\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(svelte_element);\n\t\t\t}\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].d();\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (67:0) {#each children as [node, key, props, children] (key + treeUniqueKey)}\nfunction create_each_block$4(key_2, ctx) {\n\tlet first;\n\tlet show_if;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet if_block_anchor;\n\tlet current;\n\tconst if_block_creators = [create_if_block$e, create_else_block$7];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (dirty & /*children*/ 4) show_if = null;\n\t\tif (show_if == null) show_if = !!!/*isComponent*/ ctx[5](/*node*/ ctx[9]);\n\t\tif (show_if) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx, -1);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tkey: key_2,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tfirst = empty();\n\t\t\tif_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t\tthis.first = first;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, first, anchor);\n\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx, dirty);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(first);\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$y(ctx) {\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet each_1_anchor;\n\tlet current;\n\tlet each_value = ensure_array_like(/*children*/ ctx[2]);\n\tconst get_key = ctx => /*key*/ ctx[0] + /*treeUniqueKey*/ ctx[1];\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$4(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$4(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\teach_1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(target, anchor);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinsert(target, each_1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*getElementAttributes, children, isComponent, ComponentMap, treeUniqueKey*/ 62) {\n\t\t\t\teach_value = ensure_array_like(/*children*/ ctx[2]);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, outro_and_destroy_block, create_each_block$4, each_1_anchor, get_each_context$4);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(each_1_anchor);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d(detaching);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction instance$z($$self, $$props, $$invalidate) {\n\tlet treeUniqueKey;\n\tlet children;\n\tlet { items } = $$props;\n\tlet { discardEmptyItems = true } = $$props;\n\tlet { key = '' } = $$props;\n\n\tconst ComponentMap = {\n\t\tButton,\n\t\tImageButton,\n\t\tImageButtonList,\n\t\tDropdown,\n\t\tSelect,\n\t\tRadioGroup,\n\t\tInput,\n\t\tPanel: DynamicPanel,\n\t\tProgressIndicator,\n\t\tShapeStyle,\n\t\tToggleSlider,\n\t\tColorPicker,\n\t\tShorthandControl\n\t};\n\n\tconst getElementAttributes = (props = {}) => {\n\t\tconst { textContent, innerHTML, ...attributes } = props;\n\t\treturn attributes;\n\t};\n\n\tconst isComponent = node => !isString(node) || !!ComponentMap[node];\n\n\tconst shouldRenderItem = item => {\n\t\t// don't render falsy items\n\t\tif (!item) return false;\n\n\t\t// get relevant props\n\t\tconst [node, ,props, children = []] = item;\n\n\t\t// if item is component, we always render it\n\t\tif (isComponent(node)) return true;\n\n\t\t// item is tag, we have to check if it has content\n\t\treturn children.some(shouldRenderItem) || props.textContent || props.innerHTML;\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('items' in $$props) $$invalidate(6, items = $$props.items);\n\t\tif ('discardEmptyItems' in $$props) $$invalidate(7, discardEmptyItems = $$props.discardEmptyItems);\n\t\tif ('key' in $$props) $$invalidate(0, key = $$props.key);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*key*/ 1) {\n\t\t\t$$invalidate(1, treeUniqueKey = key);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*items, discardEmptyItems*/ 192) {\n\t\t\t$$invalidate(2, children = (items && discardEmptyItems\n\t\t\t? items.filter(shouldRenderItem)\n\t\t\t: items) || []);\n\t\t}\n\t};\n\n\treturn [\n\t\tkey,\n\t\ttreeUniqueKey,\n\t\tchildren,\n\t\tComponentMap,\n\t\tgetElementAttributes,\n\t\tisComponent,\n\t\titems,\n\t\tdiscardEmptyItems\n\t];\n}\n\nclass DynamicComponentTree_1 extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$z, create_fragment$y, safe_not_equal, { items: 6, discardEmptyItems: 7, key: 0 });\n\t}\n\n\tget items() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset items(items) {\n\t\tthis.$$set({ items });\n\t\tflush();\n\t}\n\n\tget discardEmptyItems() {\n\t\treturn this.$$.ctx[7];\n\t}\n\n\tset discardEmptyItems(discardEmptyItems) {\n\t\tthis.$$set({ discardEmptyItems });\n\t\tflush();\n\t}\n\n\tget key() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset key(key) {\n\t\tthis.$$set({ key });\n\t\tflush();\n\t}\n}\n\n/* src/core/ui/components/Button.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block_1$9(ctx) {\n\tlet icon_1;\n\tlet current;\n\n\ticon_1 = new Icon({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaButtonIcon\",\n\t\t\t\t$$slots: { default: [create_default_slot$c] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon_1.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon_1, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_1_changes = {};\n\n\t\t\tif (dirty & /*$$scope, icon*/ 536870920) {\n\t\t\t\ticon_1_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon_1.$set(icon_1_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon_1.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon_1.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon_1, detaching);\n\t\t}\n\t};\n}\n\n// (85:16) <Icon class=\"PinturaButtonIcon\">\nfunction create_default_slot$c(ctx) {\n\tlet g;\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = /*icon*/ ctx[3];\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*icon*/ 8) g.innerHTML = /*icon*/ ctx[3];\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (95:12) {:else}\nfunction create_else_block$6(ctx) {\n\tlet span;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tattr(span, \"class\", /*elLabelClass*/ ctx[11]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tspan.innerHTML = /*label*/ ctx[0];\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*label*/ 1) span.innerHTML = /*label*/ ctx[0];\n\t\t\tif (dirty & /*elLabelClass*/ 2048) {\n\t\t\t\tattr(span, \"class\", /*elLabelClass*/ ctx[11]);\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (91:12) {#if isArray(label)}\nfunction create_if_block$d(ctx) {\n\tlet span;\n\tlet dynamiccomponenttree;\n\tlet current;\n\tdynamiccomponenttree = new DynamicComponentTree_1({ props: { items: /*label*/ ctx[0] } });\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tattr(span, \"class\", /*elLabelClass*/ ctx[11]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tmount_component(dynamiccomponenttree, span, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*label*/ 1) dynamiccomponenttree_changes.items = /*label*/ ctx[0];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\n\t\t\tif (!current || dirty & /*elLabelClass*/ 2048) {\n\t\t\t\tattr(span, \"class\", /*elLabelClass*/ ctx[11]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t}\n\t};\n}\n\n// (82:10)          \nfunction fallback_block$1(ctx) {\n\tlet span;\n\tlet t;\n\tlet show_if;\n\tlet current_block_type_index;\n\tlet if_block1;\n\tlet current;\n\tlet if_block0 = /*icon*/ ctx[3] && create_if_block_1$9(ctx);\n\tconst if_block_creators = [create_if_block$d, create_else_block$6];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (dirty & /*label*/ 1) show_if = null;\n\t\tif (show_if == null) show_if = !!isArray(/*label*/ ctx[0]);\n\t\tif (show_if) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx, -1);\n\tif_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif_block1.c();\n\t\t\tattr(span, \"class\", /*elButtonInnerClass*/ ctx[13]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tif (if_block0) if_block0.m(span, null);\n\t\t\tappend(span, t);\n\t\t\tif_blocks[current_block_type_index].m(span, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*icon*/ ctx[3]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*icon*/ 8) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_1$9(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(span, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx, dirty);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block1 = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block1) {\n\t\t\t\t\tif_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\tif_block1.m(span, null);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*elButtonInnerClass*/ 8192) {\n\t\t\t\tattr(span, \"class\", /*elButtonInnerClass*/ ctx[13]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif_blocks[current_block_type_index].d();\n\t\t}\n\t};\n}\n\nfunction create_fragment$x(ctx) {\n\tlet button;\n\tlet button_title_value;\n\tlet styleable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[27].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[29], null);\n\tconst default_slot_or_fallback = default_slot || fallback_block$1(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tbutton = element(\"button\");\n\t\t\tif (default_slot_or_fallback) default_slot_or_fallback.c();\n\t\t\tattr(button, \"type\", /*type*/ ctx[6]);\n\t\t\tbutton.disabled = /*disabled*/ ctx[5];\n\t\t\tattr(button, \"class\", /*elButtonClass*/ ctx[12]);\n\t\t\tattr(button, \"title\", button_title_value = toTitle(/*label*/ ctx[0], /*title*/ ctx[1], /*shortcut*/ ctx[2]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, button, anchor);\n\n\t\t\tif (default_slot_or_fallback) {\n\t\t\t\tdefault_slot_or_fallback.m(button, null);\n\t\t\t}\n\n\t\t\t/*button_binding*/ ctx[28](button);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(button, \"keydown\", function () {\n\t\t\t\t\t\tif (is_function(/*onkeydown*/ ctx[8])) /*onkeydown*/ ctx[8].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(button, \"click\", function () {\n\t\t\t\t\t\tif (is_function(/*onclick*/ ctx[7])) /*onclick*/ ctx[7].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(button, \"pointerdown\", function () {\n\t\t\t\t\t\tif (is_function(/*handleDown*/ ctx[14])) /*handleDown*/ ctx[14].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(styleable_action = styleable.call(null, button, /*style*/ ctx[4])),\n\t\t\t\t\taction_destroyer(/*action*/ ctx[9].call(null, button))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, [dirty]) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope*/ 536870912)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[29],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[29])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[29], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (default_slot_or_fallback && default_slot_or_fallback.p && (!current || dirty & /*elButtonInnerClass, elLabelClass, label, icon*/ 10249)) {\n\t\t\t\t\tdefault_slot_or_fallback.p(ctx, !current ? -1 : dirty);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*type*/ 64) {\n\t\t\t\tattr(button, \"type\", /*type*/ ctx[6]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*disabled*/ 32) {\n\t\t\t\tbutton.disabled = /*disabled*/ ctx[5];\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*elButtonClass*/ 4096) {\n\t\t\t\tattr(button, \"class\", /*elButtonClass*/ ctx[12]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*label, title, shortcut*/ 7 && button_title_value !== (button_title_value = toTitle(/*label*/ ctx[0], /*title*/ ctx[1], /*shortcut*/ ctx[2]))) {\n\t\t\t\tattr(button, \"title\", button_title_value);\n\t\t\t}\n\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty & /*style*/ 16) styleable_action.update.call(null, /*style*/ ctx[4]);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot_or_fallback, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot_or_fallback, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(button);\n\t\t\t}\n\n\t\t\tif (default_slot_or_fallback) default_slot_or_fallback.d(detaching);\n\t\t\t/*button_binding*/ ctx[28](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$y($$self, $$props, $$invalidate) {\n\tlet handleDown;\n\tlet handleUp;\n\tlet elButtonInnerClass;\n\tlet elButtonClass;\n\tlet elLabelClass;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\tlet { label = undefined } = $$props;\n\tlet { title = undefined } = $$props;\n\tlet { shortcut = undefined } = $$props;\n\tlet { labelClass = undefined } = $$props;\n\tlet { innerClass = undefined } = $$props;\n\tlet { hideLabel = false } = $$props;\n\tlet { icon = undefined } = $$props;\n\tlet { style = undefined } = $$props;\n\tlet { disabled = undefined } = $$props;\n\tlet { type = 'button' } = $$props;\n\tlet { onclick = undefined } = $$props;\n\tlet { onkeydown = undefined } = $$props;\n\tlet { onhold = undefined } = $$props;\n\n\tlet { action = () => {\n\t\t\n\t} } = $$props;\n\n\tlet { holdThreshold = 500 } = $$props;\n\tlet { holdSpeedUpFactor = 0.5 } = $$props;\n\tlet { holdSpeedMin = 20 } = $$props;\n\tlet holdTimer;\n\n\tconst hold = holdStep => {\n\t\t$$invalidate(25, holdTimer = setTimeout(\n\t\t\t() => {\n\t\t\t\tonhold();\n\t\t\t\thold(Math.max(holdStep * holdSpeedUpFactor, holdSpeedMin));\n\t\t\t},\n\t\t\tholdStep\n\t\t));\n\t};\n\n\tlet root;\n\tconst isEventTarget = e => _isEventTarget(e, root);\n\tconst getElement = () => root;\n\n\tfunction button_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\troot = $$value;\n\t\t\t$$invalidate(10, root);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(15, klass = $$props.class);\n\t\tif ('label' in $$props) $$invalidate(0, label = $$props.label);\n\t\tif ('title' in $$props) $$invalidate(1, title = $$props.title);\n\t\tif ('shortcut' in $$props) $$invalidate(2, shortcut = $$props.shortcut);\n\t\tif ('labelClass' in $$props) $$invalidate(16, labelClass = $$props.labelClass);\n\t\tif ('innerClass' in $$props) $$invalidate(17, innerClass = $$props.innerClass);\n\t\tif ('hideLabel' in $$props) $$invalidate(18, hideLabel = $$props.hideLabel);\n\t\tif ('icon' in $$props) $$invalidate(3, icon = $$props.icon);\n\t\tif ('style' in $$props) $$invalidate(4, style = $$props.style);\n\t\tif ('disabled' in $$props) $$invalidate(5, disabled = $$props.disabled);\n\t\tif ('type' in $$props) $$invalidate(6, type = $$props.type);\n\t\tif ('onclick' in $$props) $$invalidate(7, onclick = $$props.onclick);\n\t\tif ('onkeydown' in $$props) $$invalidate(8, onkeydown = $$props.onkeydown);\n\t\tif ('onhold' in $$props) $$invalidate(19, onhold = $$props.onhold);\n\t\tif ('action' in $$props) $$invalidate(9, action = $$props.action);\n\t\tif ('holdThreshold' in $$props) $$invalidate(20, holdThreshold = $$props.holdThreshold);\n\t\tif ('holdSpeedUpFactor' in $$props) $$invalidate(21, holdSpeedUpFactor = $$props.holdSpeedUpFactor);\n\t\tif ('holdSpeedMin' in $$props) $$invalidate(22, holdSpeedMin = $$props.holdSpeedMin);\n\t\tif ('$$scope' in $$props) $$invalidate(29, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*onhold, holdTimer, handleUp*/ 101187584) {\n\t\t\t$$invalidate(26, handleUp = onhold\n\t\t\t? () => {\n\t\t\t\t\tif (!holdTimer) return;\n\n\t\t\t\t\t// clean up\n\t\t\t\t\tclearTimeout(holdTimer);\n\n\t\t\t\t\t$$invalidate(25, holdTimer = undefined);\n\n\t\t\t\t\t// no longer holder\n\t\t\t\t\tdocument.documentElement.removeEventListener('pointerup', handleUp);\n\t\t\t\t}\n\t\t\t: noop$1);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*onhold, handleUp, holdThreshold*/ 68681728) {\n\t\t\t$$invalidate(14, handleDown = onhold\n\t\t\t? () => {\n\t\t\t\t\tdocument.documentElement.addEventListener('pointerup', handleUp);\n\t\t\t\t\thold(holdThreshold);\n\t\t\t\t}\n\t\t\t: noop$1);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*innerClass*/ 131072) {\n\t\t\t$$invalidate(13, elButtonInnerClass = arrayJoin(['PinturaButtonInner', innerClass]));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*hideLabel, klass*/ 294912) {\n\t\t\t$$invalidate(12, elButtonClass = arrayJoin(['PinturaButton', hideLabel && 'PinturaButtonIconOnly', klass]));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*hideLabel, labelClass*/ 327680) {\n\t\t\t$$invalidate(11, elLabelClass = arrayJoin([hideLabel ? 'implicit' : 'PinturaButtonLabel', labelClass]));\n\t\t}\n\t};\n\n\treturn [\n\t\tlabel,\n\t\ttitle,\n\t\tshortcut,\n\t\ticon,\n\t\tstyle,\n\t\tdisabled,\n\t\ttype,\n\t\tonclick,\n\t\tonkeydown,\n\t\taction,\n\t\troot,\n\t\telLabelClass,\n\t\telButtonClass,\n\t\telButtonInnerClass,\n\t\thandleDown,\n\t\tklass,\n\t\tlabelClass,\n\t\tinnerClass,\n\t\thideLabel,\n\t\tonhold,\n\t\tholdThreshold,\n\t\tholdSpeedUpFactor,\n\t\tholdSpeedMin,\n\t\tisEventTarget,\n\t\tgetElement,\n\t\tholdTimer,\n\t\thandleUp,\n\t\tslots,\n\t\tbutton_binding,\n\t\t$$scope\n\t];\n}\n\nclass Button extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$y, create_fragment$x, safe_not_equal, {\n\t\t\tclass: 15,\n\t\t\tlabel: 0,\n\t\t\ttitle: 1,\n\t\t\tshortcut: 2,\n\t\t\tlabelClass: 16,\n\t\t\tinnerClass: 17,\n\t\t\thideLabel: 18,\n\t\t\ticon: 3,\n\t\t\tstyle: 4,\n\t\t\tdisabled: 5,\n\t\t\ttype: 6,\n\t\t\tonclick: 7,\n\t\t\tonkeydown: 8,\n\t\t\tonhold: 19,\n\t\t\taction: 9,\n\t\t\tholdThreshold: 20,\n\t\t\tholdSpeedUpFactor: 21,\n\t\t\tholdSpeedMin: 22,\n\t\t\tisEventTarget: 23,\n\t\t\tgetElement: 24\n\t\t});\n\t}\n\n\tget isEventTarget() {\n\t\treturn this.$$.ctx[23];\n\t}\n\n\tget getElement() {\n\t\treturn this.$$.ctx[24];\n\t}\n}\n\nvar arrayRemove = (array, predicate) => {\n    const index = array.findIndex(predicate);\n    if (index >= 0)\n        return array.splice(index, 1);\n    return undefined;\n};\n\n// svelte\n// constants\nconst INERTIA_THRESHOLD = 0.25; // when force of velocity exceeds this value we drift\nconst INERTIA_DISTANCE_MULTIPLIER = 50;\nconst INERTIA_DURATION_MULTIPLIER = 80;\nconst TAP_DURATION_MAX = 300;\nconst TAP_DISTANCE_MAX = 64;\nconst DOUBLE_TAP_DURATION_MAX = 700;\nconst DOUBLE_TAP_DISTANCE_MAX = 128;\nconst isContextMenuAction = (e) => isNumber(e.button) && e.button !== 0;\nvar interactable = (node, options = {}) => {\n    // set defaults\n    const { inertia = false, inertiaDurationMultiplier = INERTIA_DURATION_MULTIPLIER, shouldStartInteraction = () => true, pinch = false, multiTouch = undefined, getEventPosition = (e) => vectorCreate(e.clientX, e.clientY), observeKeys = false, } = options;\n    //\n    // helpers\n    //\n    function dispatch(type, detail) {\n        node.dispatchEvent(new CustomEvent(type, { detail }));\n    }\n    function resetInertia() {\n        if (inertiaTweenUnsubscribe)\n            inertiaTweenUnsubscribe();\n        inertiaTweenUnsubscribe = undefined;\n    }\n    //#region pointer registry\n    const pointers = [];\n    const getPointerTimestamp = (e) => {\n        return e.timeStamp === 0 ? Date.now() : e.timeStamp;\n    };\n    const addPointer = (e) => {\n        const timeStamp = getPointerTimestamp(e);\n        const pointer = {\n            timeStamp,\n            timeStampInitial: timeStamp,\n            position: getEventPosition(e),\n            origin: getEventPosition(e),\n            velocity: vectorCreateEmpty(),\n            velocityHistory: [],\n            velocityAverage: vectorCreateEmpty(),\n            translation: vectorCreateEmpty(),\n            interactionState: undefined,\n            event: e,\n        };\n        pointers.push(pointer);\n        pointer.interactionState = getInteractionState(pointers);\n    };\n    const removePointer = (e) => {\n        const pointer = arrayRemove(pointers, (pointer) => pointer.event.pointerId === e.pointerId);\n        if (pointer)\n            return pointer[0];\n    };\n    const removePointers = () => {\n        pointers.length = 0;\n    };\n    const getPointerIndex = (e) => pointers.findIndex((pointer) => pointer.event.pointerId === e.pointerId);\n    const getPointersCenter = () => {\n        const position = vectorClone(pointers[0].position);\n        if (pointers[1]) {\n            const dx = (pointers[1].position.x - position.x) * 0.5;\n            const dy = (pointers[1].position.y - position.y) * 0.5;\n            position.x += dx;\n            position.y += dy;\n        }\n        return position;\n    };\n    const flattenPointerOrigin = (pointer) => {\n        pointer.origin.x = pointer.position.x;\n        pointer.origin.y = pointer.position.y;\n        pointer.translation.x = 0;\n        pointer.translation.y = 0;\n    };\n    const updatePointer = (e) => {\n        const pointer = getPointer(e);\n        if (!pointer)\n            return;\n        const timeStamp = getPointerTimestamp(e);\n        // position\n        const eventPosition = getEventPosition(e);\n        // duration between previous interaction and new interaction, an interaction duration cannot be faster than 1 millisecond\n        const interactionDuration = Math.max(1, timeStamp - pointer.timeStamp);\n        // calculate velocity\n        pointer.velocity.x = (eventPosition.x - pointer.position.x) / interactionDuration;\n        pointer.velocity.y = (eventPosition.y - pointer.position.y) / interactionDuration;\n        pointer.velocityHistory.push(vectorClone(pointer.velocity));\n        pointer.velocityHistory = pointer.velocityHistory.slice(-3);\n        pointer.velocityAverage = pointer.velocityHistory.reduce((v, c, index, arr) => {\n            v.x += c.x / arr.length;\n            v.y += c.y / arr.length;\n            return v;\n        }, vectorCreateEmpty());\n        // update the translation\n        pointer.translation.x = eventPosition.x - pointer.origin.x;\n        pointer.translation.y = eventPosition.y - pointer.origin.y;\n        // set new state\n        pointer.timeStamp = timeStamp;\n        pointer.position.x = eventPosition.x;\n        pointer.position.y = eventPosition.y;\n        pointer.event = e;\n    };\n    const getPointer = (e) => {\n        const i = getPointerIndex(e);\n        if (i < 0)\n            return;\n        return pointers[i];\n    };\n    const isSingleTouching = () => pointers.length === 1;\n    const isMultiTouching = () => pointers.length === 2;\n    const getDistance = (pointers, position) => {\n        const distanceTotal = pointers.reduce((prev, curr) => {\n            prev += vectorDistance(position, curr.position);\n            return prev;\n        }, 0);\n        return distanceTotal / pointers.length;\n    };\n    const getInteractionState = (pointers) => {\n        const center = vectorCenter(pointers.map((pointer) => pointer.position));\n        const distance = getDistance(pointers, center);\n        return {\n            center,\n            distance,\n            velocity: vectorCenter(pointers.map((pointer) => pointer.velocity)),\n            translation: vectorCenter(pointers.map((pointer) => pointer.translation)),\n        };\n    };\n    //#endregion\n    let inertiaTween;\n    let inertiaOrigin;\n    let inertiaTranslation;\n    let inertiaTweenUnsubscribe;\n    let pinchOffsetDistance;\n    let currentTranslation;\n    let currentScale;\n    let isGesture;\n    let lastTapTimeStamp = 0;\n    let lastTapPosition = undefined;\n    // start handling interactions\n    node.addEventListener('pointerdown', handlePointerdown);\n    // if keys\n    const RelevantKeys = ['Meta', 'Control', 'Alt', 'Shift'];\n    function handleKeys(e) {\n        if (!RelevantKeys.includes(e.key))\n            return;\n        const { metaKey, ctrlKey, altKey, shiftKey } = e;\n        onPointerUpdated({ metaKey, ctrlKey, altKey, shiftKey });\n    }\n    let lastPointerUpdate = Date.now();\n    const onPointerUpdated = (pressedKeys) => {\n        const translation = vectorClone(pointers[0].translation);\n        let scalar = currentScale;\n        if (pinch && isMultiTouching()) {\n            // current pinch distance\n            const pinchCurrentDistance = vectorDistance(pointers[0].position, pointers[1].position);\n            // to find out scalar we calculate the difference between the pinch offset and the new pinch\n            const pinchScalar = pinchCurrentDistance / pinchOffsetDistance;\n            // add to existing scalar\n            scalar *= pinchScalar;\n            // current offset\n            vectorAdd(translation, pointers[1].translation);\n        }\n        vectorAdd(translation, currentTranslation);\n        // skip update event if last interaction was less than 16 ms ago\n        const now = Date.now();\n        const dist = now - lastPointerUpdate;\n        if (dist < 16)\n            return;\n        lastPointerUpdate = now;\n        dispatch('interactionupdate', {\n            position: getPointersCenter(),\n            translation: translation,\n            scalar: pinch ? scalar : undefined,\n            isMultiTouching: isMultiTouching(),\n            ...pressedKeys,\n        });\n    };\n    function handlePointerdown(e) {\n        // ignore more than two pointers for now\n        if (isMultiTouching())\n            return;\n        // not interested in context menu\n        if (isContextMenuAction(e))\n            return;\n        // target should equal node, if it doesn't user might have clicked one of the nodes children\n        if (!shouldStartInteraction(e, node))\n            return;\n        // stop any previous inertia tweens\n        resetInertia();\n        // register this pointer\n        addPointer(e);\n        // listen for keys if needed\n        if (observeKeys) {\n            window.addEventListener('keydown', handleKeys);\n            window.addEventListener('keyup', handleKeys);\n        }\n        // if is first pointer we need to init the drag gesture\n        if (isSingleTouching()) {\n            // handle pointer events\n            document.documentElement.addEventListener('pointermove', handlePointermove);\n            document.documentElement.addEventListener('pointerup', handlePointerup);\n            document.documentElement.addEventListener('pointercancel', handlePointerup);\n            document.addEventListener('visibilitychange', handleVisibilityChange);\n            // clear vars\n            isGesture = false;\n            currentScale = 1;\n            currentTranslation = vectorCreateEmpty();\n            pinchOffsetDistance = undefined;\n            dispatch('interactionstart', {\n                origin: vectorClone(getPointer(e).origin),\n            });\n        }\n        // is pinch\n        else if (pinch) {\n            isGesture = true;\n            pinchOffsetDistance = vectorDistance(pointers[0].position, pointers[1].position);\n            currentTranslation.x += pointers[0].translation.x;\n            currentTranslation.y += pointers[0].translation.y;\n            flattenPointerOrigin(pointers[0]);\n        }\n        // is multitouch and we're not allowed to multitouch\n        else if (multiTouch === false) {\n            // remove all pointers\n            removePointers();\n            // clean up\n            unlisten();\n            // cancelled\n            return dispatch('interactioncancel');\n        }\n    }\n    //\n    // pointer move can only be a primary event (other pointers are not handled)\n    //\n    function handlePointermove(e) {\n        // prevent selection of text (Safari)\n        e.preventDefault();\n        // update pointer state\n        updatePointer(e);\n        const { metaKey = false, ctrlKey = false, altKey = false, shiftKey = false, } = observeKeys ? e : {};\n        onPointerUpdated({ metaKey, ctrlKey, altKey, shiftKey });\n    }\n    //\n    // pointer up can only be a primary event (other pointers are not handled)\n    //\n    function handlePointerup(e) {\n        // test if is my pointer that was released, as we're listining on document it could be other pointers\n        if (!getPointer(e))\n            return;\n        // calculate center between active pointers\n        const centerBetweenPointers = getPointersCenter();\n        // remove pointer from active pointers array\n        const removedPointer = removePointer(e);\n        // store current size\n        if (pinch && isSingleTouching()) {\n            // calculate current scale\n            const pinchCurrentDistance = vectorDistance(pointers[0].position, removedPointer.position);\n            currentScale *= pinchCurrentDistance / pinchOffsetDistance;\n            currentTranslation.x += pointers[0].translation.x + removedPointer.translation.x;\n            currentTranslation.y += pointers[0].translation.y + removedPointer.translation.y;\n            flattenPointerOrigin(pointers[0]);\n        }\n        // check if this was a tap\n        let isTap = false;\n        let isDoubleTap = false;\n        if (!isGesture && removedPointer) {\n            const interactionEnd = performance.now();\n            const interactionDuration = interactionEnd - removedPointer.timeStampInitial;\n            const interactionDistanceSquared = vectorDistanceSquared(removedPointer.translation);\n            isTap =\n                interactionDistanceSquared < TAP_DISTANCE_MAX &&\n                    interactionDuration < TAP_DURATION_MAX;\n            isDoubleTap = !!(lastTapPosition &&\n                isTap &&\n                interactionEnd - lastTapTimeStamp < DOUBLE_TAP_DURATION_MAX &&\n                vectorDistanceSquared(lastTapPosition, removedPointer.position) <\n                    DOUBLE_TAP_DISTANCE_MAX);\n            if (isTap) {\n                lastTapPosition = vectorClone(removedPointer.position);\n                lastTapTimeStamp = interactionEnd;\n            }\n        }\n        // we wait till last multi-touch interaction is finished, all pointers need to be de-registered before proceeding\n        if (pointers.length > 0)\n            return;\n        // stop listening\n        unlisten();\n        const translation = vectorClone(removedPointer.translation);\n        const velocity = vectorClone(removedPointer.velocityAverage);\n        // allows cancelling inertia from release handler\n        let inertiaPrevented = false;\n        // user has released interaction\n        dispatch('interactionrelease', {\n            isTap,\n            isDoubleTap,\n            position: centerBetweenPointers,\n            translation,\n            scalar: currentScale,\n            preventInertia: () => (inertiaPrevented = true),\n        });\n        // stop intantly if not a lot of force applied\n        const force = vectorDistance(velocity);\n        if (inertiaPrevented || !inertia || force < INERTIA_THRESHOLD) {\n            return handleEnd(translation, { isTap, isDoubleTap });\n        }\n        // drift\n        inertiaOrigin = vectorClone(centerBetweenPointers);\n        inertiaTranslation = vectorClone(translation);\n        inertiaTween = tweened(vectorClone(translation), {\n            easing: circOut,\n            duration: force * inertiaDurationMultiplier,\n        });\n        inertiaTween\n            .set({\n            x: translation.x + velocity.x * INERTIA_DISTANCE_MULTIPLIER,\n            y: translation.y + velocity.y * INERTIA_DISTANCE_MULTIPLIER,\n        })\n            .then(() => {\n            // if has unsubscribed (tween was reset)\n            if (!inertiaTweenUnsubscribe)\n                return;\n            // go!\n            handleEnd(get_store_value(inertiaTween), { isTap, isDoubleTap });\n        });\n        inertiaTweenUnsubscribe = inertiaTween.subscribe(handleInertiaUpdate);\n    }\n    function handleInertiaUpdate(translation) {\n        // if is same as previous position, ignore\n        if (!translation)\n            return;\n        // this will handle drift interactions\n        dispatch('interactionupdate', {\n            position: vectorCreate(inertiaOrigin.x + (translation.x - inertiaTranslation.x), inertiaOrigin.y + (translation.y - inertiaTranslation.y)),\n            translation: translation,\n            scalar: pinch ? currentScale : undefined,\n        });\n    }\n    function handleVisibilityChange(e) {\n        if (document.visibilityState === 'visible' || !pointers.length)\n            return;\n        const state = getInteractionState(pointers);\n        // done\n        resetInertia();\n        // done\n        dispatch('interactionend', {\n            ...state,\n        });\n        // reset pointers so we can try again\n        pointers.length = 0;\n        // document hidden, let's clean up\n        unlisten();\n    }\n    function handleEnd(translation, tapState) {\n        resetInertia();\n        dispatch('interactionend', {\n            ...tapState,\n            translation,\n            scalar: pinch ? currentScale : undefined,\n        });\n    }\n    function unlisten() {\n        if (observeKeys)\n            window.removeEventListener('keydown', handleKeys);\n        if (observeKeys)\n            window.removeEventListener('keyup', handleKeys);\n        document.documentElement.removeEventListener('pointermove', handlePointermove);\n        document.documentElement.removeEventListener('pointerup', handlePointerup);\n        document.documentElement.removeEventListener('pointercancel', handlePointerup);\n        document.removeEventListener('visibilitychange', handleVisibilityChange);\n    }\n    return {\n        destroy() {\n            resetInertia();\n            node.removeEventListener('pointerdown', handlePointerdown);\n        },\n    };\n};\n\nfunction elastify(translation, dist) {\n    return dist\n        ? dist * Math.sign(translation) * Math.log10(1 + Math.abs(translation) / dist)\n        : translation;\n}\nconst elastifyRects = (a, b, dist) => {\n    if (!b || !dist)\n        return { ...a };\n    const left = a.x + elastify(b.x - a.x, dist);\n    const right = a.x + a.width + elastify(b.x + b.width - (a.x + a.width), dist);\n    const top = a.y + elastify(b.y - a.y, dist);\n    const bottom = a.y + a.height + elastify(b.y + b.height - (a.y + a.height), dist);\n    return {\n        x: left,\n        y: top,\n        width: right - left,\n        height: bottom - top,\n    };\n};\nconst elastifyVectors = (a, b, dist) => {\n    if (!b || !dist)\n        return { ...a };\n    return vectorCreate(a.x + elastify(b.x - a.x, dist), a.y + elastify(b.y - a.y, dist));\n};\n\nvar unitToPixels = (value, element) => {\n    if (!value)\n        return;\n    if (/em/.test(value))\n        return parseInt(value, 10) * 16;\n    if (/px/.test(value))\n        return parseInt(value, 10);\n};\n\n/* src/core/ui/components/Scrollable.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$w(ctx) {\n\tlet div1;\n\tlet div0;\n\tlet div1_class_value;\n\tlet nudgeable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[40].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[39], null);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv1 = element(\"div\");\n\t\t\tdiv0 = element(\"div\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tset_style(div0, \"transform\", /*styleTransform*/ ctx[6]);\n\t\t\tattr(div1, \"class\", div1_class_value = arrayJoin(['PinturaScrollable', /*klass*/ ctx[0]]));\n\t\t\tattr(div1, \"data-direction\", /*scrollDirection*/ ctx[1]);\n\t\t\tattr(div1, \"data-state\", /*containerState*/ ctx[7]);\n\t\t\tset_style(div1, \"--scrollable-feather-start-opacity\", /*styleScrollableFeatherStartOpacity*/ ctx[4]);\n\t\t\tset_style(div1, \"--scrollable-feather-end-opacity\", /*styleScrollableFeatherEndOpacity*/ ctx[5]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div1, anchor);\n\t\t\tappend(div1, div0);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(div0, null);\n\t\t\t}\n\n\t\t\t/*div1_binding*/ ctx[42](div1);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div0, \"interactionstart\", /*handleDragStart*/ ctx[10]),\n\t\t\t\t\tlisten(div0, \"interactionupdate\", /*handleDragMove*/ ctx[12]),\n\t\t\t\t\tlisten(div0, \"interactionend\", /*handleDragEnd*/ ctx[13]),\n\t\t\t\t\tlisten(div0, \"interactionrelease\", /*handleDragRelease*/ ctx[11]),\n\t\t\t\t\taction_destroyer(interactable.call(null, div0, { inertia: true })),\n\t\t\t\t\tlisten(div0, \"measure\", /*measure_handler*/ ctx[41]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div0)),\n\t\t\t\t\tlisten(div1, \"wheel\", /*handleWheel*/ ctx[15], { passive: false }),\n\t\t\t\t\tlisten(div1, \"scroll\", /*handleScroll*/ ctx[17]),\n\t\t\t\t\tlisten(div1, \"focusin\", /*focusin_handler*/ ctx[43]),\n\t\t\t\t\tlisten(div1, \"nudge\", /*handleNudge*/ ctx[18]),\n\t\t\t\t\tlisten(div1, \"measure\", /*handleResizeScrollContainer*/ ctx[14]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div1, { observePosition: true })),\n\t\t\t\t\taction_destroyer(nudgeable_action = nudgeable.call(null, div1, {\n\t\t\t\t\t\tdirection: /*scrollDirection*/ ctx[1] === 'x'\n\t\t\t\t\t\t? 'horizontal'\n\t\t\t\t\t\t: 'vertical',\n\t\t\t\t\t\tstopKeydownPropagation: false\n\t\t\t\t\t}))\n\t\t\t\t]; // preventDefault is not enabled as keyboard interaction is needed to select nodes\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty[1] & /*$$scope*/ 256)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[39],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[39])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[39], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleTransform*/ 64) {\n\t\t\t\tset_style(div0, \"transform\", /*styleTransform*/ ctx[6]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*klass*/ 1 && div1_class_value !== (div1_class_value = arrayJoin(['PinturaScrollable', /*klass*/ ctx[0]]))) {\n\t\t\t\tattr(div1, \"class\", div1_class_value);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*scrollDirection*/ 2) {\n\t\t\t\tattr(div1, \"data-direction\", /*scrollDirection*/ ctx[1]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*containerState*/ 128) {\n\t\t\t\tattr(div1, \"data-state\", /*containerState*/ ctx[7]);\n\t\t\t}\n\n\t\t\tif (nudgeable_action && is_function(nudgeable_action.update) && dirty[0] & /*scrollDirection*/ 2) nudgeable_action.update.call(null, {\n\t\t\t\tdirection: /*scrollDirection*/ ctx[1] === 'x'\n\t\t\t\t? 'horizontal'\n\t\t\t\t: 'vertical',\n\t\t\t\tstopKeydownPropagation: false\n\t\t\t}); // preventDefault is not enabled as keyboard interaction is needed to select nodes\n\n\t\t\tif (dirty[0] & /*styleScrollableFeatherStartOpacity*/ 16) {\n\t\t\t\tset_style(div1, \"--scrollable-feather-start-opacity\", /*styleScrollableFeatherStartOpacity*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleScrollableFeatherEndOpacity*/ 32) {\n\t\t\t\tset_style(div1, \"--scrollable-feather-end-opacity\", /*styleScrollableFeatherEndOpacity*/ ctx[5]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div1);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\t/*div1_binding*/ ctx[42](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$x($$self, $$props, $$invalidate) {\n\tlet size;\n\tlet axis;\n\tlet containerStyle;\n\tlet containerFeatherSize;\n\tlet overflows;\n\tlet overflowsBegin;\n\tlet overflowsEnd;\n\tlet containerState;\n\tlet styleTransform;\n\tlet $scrollOffset;\n\tlet $fixScrollDirectionStore;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tconst dispatch = createEventDispatcher();\n\tlet scrollState = 'idle';\n\tlet scrollOrigin;\n\tlet scrollRect;\n\tlet scrollContainerRect;\n\tlet scrollReleased;\n\tlet scrollOffset = spring(0);\n\tcomponent_subscribe($$self, scrollOffset, value => $$invalidate(38, $scrollOffset = value));\n\tlet { class: klass = undefined } = $$props;\n\tlet { scrollBlockInteractionDist = 5 } = $$props;\n\tlet { scrollStep = 10 } = $$props;\n\tlet { scrollFocusMargin = 64 } = $$props;\n\tlet { scrollDirection = 'x' } = $$props;\n\tlet { scrollAutoCancel = false } = $$props;\n\tlet { elasticity = 0 } = $$props;\n\tlet { onscroll = noop$1 } = $$props;\n\tlet { maskFeatherSize = undefined } = $$props;\n\tlet { maskFeatherStartOpacity = undefined } = $$props;\n\tlet { maskFeatherEndOpacity = undefined } = $$props;\n\tlet { scroll = undefined } = $$props;\n\n\t// context\n\tconst fixScrollDirectionStore = getContext('fixScrollDirection');\n\n\tcomponent_subscribe($$self, fixScrollDirectionStore, value => $$invalidate(50, $fixScrollDirectionStore = value));\n\n\t// logic\n\tlet container;\n\n\t// let overflowStyle = '';\n\tlet styleScrollableFeatherStartOpacity = undefined;\n\n\tlet styleScrollableFeatherEndOpacity = undefined;\n\n\t// is scroll in reset state\n\tlet scrollAtRest = true;\n\n\t// triggers onscroll callback\n\tconst scrollOffsetUnsub = scrollOffset.subscribe(value => {\n\t\tconst pos = vectorCreateEmpty();\n\t\tpos[scrollDirection] = value;\n\t\tonscroll(pos);\n\t});\n\n\tconst limitOffsetToContainer = offset => Math.max(Math.min(0, offset), scrollContainerRect[size] - scrollRect[size]);\n\tlet scrollFirstMove;\n\tlet scrollCancelled;\n\tlet scrollTranslationPrev;\n\n\tconst isHorizontalTranslation = translation => {\n\t\tconst velocity = vectorApply(vectorCreate(translation.x - scrollTranslationPrev.x, translation.y - scrollTranslationPrev.y), Math.abs);\n\t\tscrollTranslationPrev = vectorClone(translation);\n\t\tconst speed = vectorDistanceSquared(velocity);\n\t\tconst diff = velocity.x - velocity.y;\n\t\treturn !(speed > 1 && diff < -0.5);\n\t};\n\n\tconst handleDragStart = () => {\n\t\t// not overflowing so no need to handle\n\t\tif (!overflows) return;\n\n\t\tscrollCancelled = false;\n\t\tscrollFirstMove = true;\n\t\tscrollTranslationPrev = vectorCreate(0, 0);\n\t\tscrollReleased = false;\n\t\t$$invalidate(29, scrollState = 'idle');\n\t\tscrollOrigin = get_store_value(scrollOffset);\n\t};\n\n\tconst handleDragRelease = ({ detail }) => {\n\t\tif (!overflows) return;\n\t\tscrollReleased = true;\n\t\t$$invalidate(29, scrollState = 'idle');\n\t};\n\n\tconst handleDragMove = ({ detail }) => {\n\t\tif (!overflows) return;\n\t\tif (scrollCancelled) return;\n\n\t\t// fixes problem with single move event fired when clicking\n\t\tif (scrollFirstMove) {\n\t\t\tscrollFirstMove = false;\n\t\t\tif (vectorDistanceSquared(detail.translation) < 0.1) return;\n\t\t}\n\n\t\tif (scrollAutoCancel && scrollDirection === 'x' && !isHorizontalTranslation(detail.translation)) {\n\t\t\tscrollCancelled = true;\n\t\t\treturn;\n\t\t}\n\n\t\tsetScrollOffset(scrollOrigin + detail.translation[scrollDirection], { elastic: true });\n\t};\n\n\tconst handleDragEnd = ({ detail }) => {\n\t\tif (!overflows) return;\n\t\tif (scrollCancelled) return;\n\t\tconst offset = scrollOrigin + detail.translation[scrollDirection];\n\t\tconst offsetLimited = limitOffsetToContainer(offset);\n\t\tscrollAtRest = false;\n\n\t\tscrollOffset.set(offsetLimited).then(res => {\n\t\t\tif (!scrollReleased) return;\n\t\t\tscrollAtRest = true;\n\t\t});\n\t};\n\n\tconst handleResizeScrollContainer = ({ detail }) => {\n\t\t$$invalidate(30, scrollContainerRect = detail);\n\n\t\tdispatch('measure', {\n\t\t\tx: detail.x,\n\t\t\ty: detail.y,\n\t\t\twidth: detail.width,\n\t\t\theight: detail.height\n\t\t});\n\t};\n\n\tconst setScrollOffset = (offset, options = {}) => {\n\t\tconst { elastic = false, animate = false, preventScrollState = false } = options;\n\n\t\t// prevents clicks on child elements if the container is being scrolled\n\t\tif (Math.abs(offset - scrollOrigin) > scrollBlockInteractionDist && scrollState === 'idle' && !scrollReleased && !preventScrollState) {\n\t\t\t$$invalidate(29, scrollState = 'scrolling');\n\t\t}\n\n\t\tconst offsetLimited = limitOffsetToContainer(offset);\n\n\t\tconst offsetVisual = elastic && elasticity && !scrollReleased\n\t\t? offsetLimited + elastify(offset - offsetLimited, elasticity)\n\t\t: offsetLimited;\n\n\t\tlet snapToPosition = true;\n\n\t\tif (animate) {\n\t\t\tsnapToPosition = false;\n\t\t} else if (!scrollAtRest) {\n\t\t\tsnapToPosition = !scrollReleased;\n\t\t}\n\n\t\tscrollAtRest = false;\n\n\t\tscrollOffset.set(offsetVisual, { hard: snapToPosition }).then(res => {\n\t\t\tif (!scrollReleased) return;\n\t\t\tscrollAtRest = true;\n\t\t});\n\t};\n\n\tconst handleWheel = e => {\n\t\t// don't do anything if isn't overflowing\n\t\tif (!overflows) return;\n\n\t\t// hold shift scroll up -> move to begin\n\t\t// hold shift scroll down -> move to end\n\t\t// scroll down -> move to right/down\n\t\t// scroll up -> move to left/up\n\t\t// don't run default actions, prevent other actions from running\n\t\te.preventDefault();\n\n\t\te.stopPropagation();\n\n\t\t// detect if is holding shift\n\t\tconst isHoldingShift = e.shiftKey;\n\n\t\t// apply wheel delta to offset\n\t\tconst delta = getWheelDelta(e, {\n\t\t\tfixScrollDirection: $fixScrollDirectionStore\n\t\t}) * (isHoldingShift ? -1 : 1);\n\n\t\tconst offset = get_store_value(scrollOffset);\n\t\tsetScrollOffset(offset + delta * scrollStep, { animate: true });\n\t};\n\n\tconst handleFocus = e => {\n\t\t// don't do anything if isn't overflowing\n\t\tif (!overflows) return;\n\n\t\t// ignore this handler if is dragging\n\t\tif (!scrollReleased) return;\n\n\t\tlet target = e.target;\n\n\t\t// when a target is marked as implicit we use its parent element\n\t\tif (e.target.classList.contains('implicit')) target = target.parentNode;\n\n\t\t// get bounds\n\t\tconst start = target[scrollDirection === 'x' ? 'offsetLeft' : 'offsetTop']; //.offsetLeft;\n\n\t\tconst space = target[scrollDirection === 'x' ? 'offsetWidth' : 'offsetHeight']; //.offsetWidth;\n\t\tconst end = start + space;\n\n\t\t// we need to know the current offset of the scroll so we can determine if the target is in view\n\t\tconst currentScrollOffset = get_store_value(scrollOffset);\n\n\t\t// the margin around elements to keep in mind when focussing items\n\t\tconst margin = scrollFocusMargin + maskFeatherSize;\n\n\t\tif (currentScrollOffset + start < margin) {\n\t\t\tsetScrollOffset(-start + margin);\n\t\t} else if (currentScrollOffset + end > scrollContainerRect[size] - margin) {\n\t\t\tsetScrollOffset(scrollContainerRect[size] - end - margin, { animate: true });\n\t\t}\n\t};\n\n\tconst handleScroll = () => {\n\t\t// the scroll handler corrects auto browser scroll,\n\t\t// is triggered when browser tries to focus an\n\t\t// element outside of the scrollcontiner\n\t\t$$invalidate(3, container[scrollDirection === 'x' ? 'scrollLeft' : 'scrollTop'] = 0, container);\n\t};\n\n\tconst handleNudge = ({ detail }) => {\n\t\t// no nudging if arrows are used to switch between buttons\n\t\tif (container.querySelector('[data-focus-visible]')) return;\n\n\t\t// apply nudge\n\t\tconst delta = -2 * detail[scrollDirection];\n\n\t\tconst offset = get_store_value(scrollOffset);\n\t\tsetScrollOffset(offset + delta * scrollStep, { animate: true, preventScrollState: true });\n\t};\n\n\tonDestroy(() => {\n\t\tscrollOffsetUnsub();\n\t});\n\n\tconst measure_handler = e => $$invalidate(2, scrollRect = e.detail);\n\n\tfunction div1_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tcontainer = $$value;\n\t\t\t$$invalidate(3, container);\n\t\t});\n\t}\n\n\tconst focusin_handler = e => {\n\t\t// this small delay forces the focus event handler to fires after dragrelease in case of a tap\n\t\tsetTimeout(() => handleFocus(e), 32);\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(0, klass = $$props.class);\n\t\tif ('scrollBlockInteractionDist' in $$props) $$invalidate(22, scrollBlockInteractionDist = $$props.scrollBlockInteractionDist);\n\t\tif ('scrollStep' in $$props) $$invalidate(23, scrollStep = $$props.scrollStep);\n\t\tif ('scrollFocusMargin' in $$props) $$invalidate(24, scrollFocusMargin = $$props.scrollFocusMargin);\n\t\tif ('scrollDirection' in $$props) $$invalidate(1, scrollDirection = $$props.scrollDirection);\n\t\tif ('scrollAutoCancel' in $$props) $$invalidate(25, scrollAutoCancel = $$props.scrollAutoCancel);\n\t\tif ('elasticity' in $$props) $$invalidate(26, elasticity = $$props.elasticity);\n\t\tif ('onscroll' in $$props) $$invalidate(27, onscroll = $$props.onscroll);\n\t\tif ('maskFeatherSize' in $$props) $$invalidate(21, maskFeatherSize = $$props.maskFeatherSize);\n\t\tif ('maskFeatherStartOpacity' in $$props) $$invalidate(19, maskFeatherStartOpacity = $$props.maskFeatherStartOpacity);\n\t\tif ('maskFeatherEndOpacity' in $$props) $$invalidate(20, maskFeatherEndOpacity = $$props.maskFeatherEndOpacity);\n\t\tif ('scroll' in $$props) $$invalidate(28, scroll = $$props.scroll);\n\t\tif ('$$scope' in $$props) $$invalidate(39, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*scrollDirection*/ 2) {\n\t\t\t$$invalidate(35, size = scrollDirection === 'x' ? 'width' : 'height');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*scrollDirection*/ 2) {\n\t\t\t$$invalidate(31, axis = scrollDirection.toUpperCase());\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*container*/ 8) {\n\t\t\t$$invalidate(37, containerStyle = container && getComputedStyle(container));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*container*/ 8 | $$self.$$.dirty[1] & /*containerStyle*/ 64) {\n\t\t\t$$invalidate(36, containerFeatherSize = containerStyle && unitToPixels(containerStyle.getPropertyValue('--scrollable-feather-size')));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*scrollContainerRect, scrollRect, maskFeatherStartOpacity, maskFeatherEndOpacity*/ 1075314692 | $$self.$$.dirty[1] & /*$scrollOffset, containerFeatherSize, size*/ 176) {\n\t\t\tif ($scrollOffset != null && scrollContainerRect && containerFeatherSize != null && scrollRect) {\n\t\t\t\tconst startOffset = -1 * $scrollOffset / containerFeatherSize;\n\t\t\t\tconst endOffset = -(scrollContainerRect[size] - scrollRect[size] - $scrollOffset) / containerFeatherSize;\n\t\t\t\t$$invalidate(19, maskFeatherStartOpacity = clamp(1 - startOffset, 0, 1));\n\t\t\t\t$$invalidate(20, maskFeatherEndOpacity = clamp(1 - endOffset, 0, 1));\n\t\t\t\t$$invalidate(21, maskFeatherSize = containerFeatherSize);\n\t\t\t\t$$invalidate(4, styleScrollableFeatherStartOpacity = maskFeatherStartOpacity);\n\t\t\t\t$$invalidate(5, styleScrollableFeatherEndOpacity = maskFeatherEndOpacity);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*container, scroll*/ 268435464) {\n\t\t\t// update scroll position\n\t\t\tif (container && scroll !== undefined) {\n\t\t\t\tif (isNumber(scroll)) setScrollOffset(scroll); else setScrollOffset(scroll.scrollOffset, scroll);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*scrollContainerRect, scrollRect*/ 1073741828 | $$self.$$.dirty[1] & /*size*/ 16) {\n\t\t\t$$invalidate(32, overflows = scrollContainerRect && scrollRect\n\t\t\t? scrollRect[size] > scrollContainerRect[size]\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$scrollOffset*/ 128) {\n\t\t\t$$invalidate(34, overflowsBegin = $scrollOffset < 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*scrollRect, scrollContainerRect*/ 1073741828 | $$self.$$.dirty[1] & /*$scrollOffset, size*/ 144) {\n\t\t\t$$invalidate(33, overflowsEnd = scrollRect && scrollContainerRect\n\t\t\t? $scrollOffset + scrollRect[size] > scrollContainerRect[size]\n\t\t\t: false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*scrollState*/ 536870912 | $$self.$$.dirty[1] & /*overflows, overflowsBegin, overflowsEnd*/ 14) {\n\t\t\t$$invalidate(7, containerState = arrayJoin([\n\t\t\t\tscrollState,\n\t\t\t\toverflows ? 'overflows' : undefined,\n\t\t\t\toverflowsBegin ? 'overflows-start' : undefined,\n\t\t\t\toverflowsEnd ? 'overflows-end' : undefined\n\t\t\t]));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*overflows, axis, $scrollOffset*/ 131) {\n\t\t\t$$invalidate(6, styleTransform = overflows\n\t\t\t? `translate${axis}(${$scrollOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\treturn [\n\t\tklass,\n\t\tscrollDirection,\n\t\tscrollRect,\n\t\tcontainer,\n\t\tstyleScrollableFeatherStartOpacity,\n\t\tstyleScrollableFeatherEndOpacity,\n\t\tstyleTransform,\n\t\tcontainerState,\n\t\tscrollOffset,\n\t\tfixScrollDirectionStore,\n\t\thandleDragStart,\n\t\thandleDragRelease,\n\t\thandleDragMove,\n\t\thandleDragEnd,\n\t\thandleResizeScrollContainer,\n\t\thandleWheel,\n\t\thandleFocus,\n\t\thandleScroll,\n\t\thandleNudge,\n\t\tmaskFeatherStartOpacity,\n\t\tmaskFeatherEndOpacity,\n\t\tmaskFeatherSize,\n\t\tscrollBlockInteractionDist,\n\t\tscrollStep,\n\t\tscrollFocusMargin,\n\t\tscrollAutoCancel,\n\t\telasticity,\n\t\tonscroll,\n\t\tscroll,\n\t\tscrollState,\n\t\tscrollContainerRect,\n\t\taxis,\n\t\toverflows,\n\t\toverflowsEnd,\n\t\toverflowsBegin,\n\t\tsize,\n\t\tcontainerFeatherSize,\n\t\tcontainerStyle,\n\t\t$scrollOffset,\n\t\t$$scope,\n\t\tslots,\n\t\tmeasure_handler,\n\t\tdiv1_binding,\n\t\tfocusin_handler\n\t];\n}\n\nclass Scrollable extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$x,\n\t\t\tcreate_fragment$w,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tclass: 0,\n\t\t\t\tscrollBlockInteractionDist: 22,\n\t\t\t\tscrollStep: 23,\n\t\t\t\tscrollFocusMargin: 24,\n\t\t\t\tscrollDirection: 1,\n\t\t\t\tscrollAutoCancel: 25,\n\t\t\t\telasticity: 26,\n\t\t\t\tonscroll: 27,\n\t\t\t\tmaskFeatherSize: 21,\n\t\t\t\tmaskFeatherStartOpacity: 19,\n\t\t\t\tmaskFeatherEndOpacity: 20,\n\t\t\t\tscroll: 28\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n}\n\n/* src/core/ui/components/StatusMessage.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$v(ctx) {\n\tlet span;\n\tlet span_transition;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tattr(span, \"class\", \"PinturaStatusMessage\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tspan.innerHTML = /*text*/ ctx[0];\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(span, \"measure\", function () {\n\t\t\t\t\t\tif (is_function(/*onmeasure*/ ctx[1])) /*onmeasure*/ ctx[1].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(measurable.call(null, span))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, [dirty]) {\n\t\t\tctx = new_ctx;\n\t\t\tif (!current || dirty & /*text*/ 1) span.innerHTML = /*text*/ ctx[0];\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tadd_render_callback(() => {\n\t\t\t\tif (!current) return;\n\t\t\t\tif (!span_transition) span_transition = create_bidirectional_transition(span, /*fadeTick*/ ctx[4], { duration: /*duration*/ ctx[2] }, true);\n\t\t\t\tspan_transition.run(1);\n\t\t\t});\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tif (!span_transition) span_transition = create_bidirectional_transition(span, /*fadeTick*/ ctx[4], { duration: /*duration*/ ctx[2] }, false);\n\t\t\tspan_transition.run(0);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tif (detaching && span_transition) span_transition.end();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$w($$self, $$props, $$invalidate) {\n\tlet duration;\n\tlet $isAnimated;\n\tlet { text } = $$props;\n\tlet { onmeasure = noop$1 } = $$props;\n\tconst isAnimated = getContext('isAnimated');\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(5, $isAnimated = value));\n\n\t// we fade with tick instead of css so svelte doesn't generate a style tag\n\tfunction fadeTick(node, { duration }) {\n\t\treturn {\n\t\t\tduration,\n\t\t\ttick: t => {\n\t\t\t\tnode.style.opacity = t;\n\t\t\t}\n\t\t};\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('text' in $$props) $$invalidate(0, text = $$props.text);\n\t\tif ('onmeasure' in $$props) $$invalidate(1, onmeasure = $$props.onmeasure);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*$isAnimated*/ 32) {\n\t\t\t$$invalidate(2, duration = $isAnimated ? 500 : 0);\n\t\t}\n\t};\n\n\treturn [text, onmeasure, duration, isAnimated, fadeTick, $isAnimated];\n}\n\nclass StatusMessage extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$w, create_fragment$v, safe_not_equal, { text: 0, onmeasure: 1 });\n\t}\n}\n\n/* src/core/ui/components/StatusAside.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$u(ctx) {\n\tlet span;\n\tlet span_class_value;\n\tlet current;\n\tconst default_slot_template = /*#slots*/ ctx[5].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[4], null);\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tattr(span, \"class\", span_class_value = `PinturaStatusAside ${/*klass*/ ctx[1]}`);\n\t\t\tset_style(span, \"transform\", /*transform*/ ctx[2]);\n\t\t\tset_style(span, \"opacity\", /*opacity*/ ctx[0]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(span, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope*/ 16)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[4],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[4])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[4], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*klass*/ 2 && span_class_value !== (span_class_value = `PinturaStatusAside ${/*klass*/ ctx[1]}`)) {\n\t\t\t\tattr(span, \"class\", span_class_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*transform*/ 4) {\n\t\t\t\tset_style(span, \"transform\", /*transform*/ ctx[2]);\n\t\t\t}\n\n\t\t\tif (dirty & /*opacity*/ 1) {\n\t\t\t\tset_style(span, \"opacity\", /*opacity*/ ctx[0]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance$v($$self, $$props, $$invalidate) {\n\tlet transform;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { offset = 0 } = $$props;\n\tlet { opacity = 0 } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\n\t$$self.$$set = $$props => {\n\t\tif ('offset' in $$props) $$invalidate(3, offset = $$props.offset);\n\t\tif ('opacity' in $$props) $$invalidate(0, opacity = $$props.opacity);\n\t\tif ('class' in $$props) $$invalidate(1, klass = $$props.class);\n\t\tif ('$$scope' in $$props) $$invalidate(4, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*offset*/ 8) {\n\t\t\t$$invalidate(2, transform = `translateX(${offset}px)`);\n\t\t}\n\t};\n\n\treturn [opacity, klass, transform, offset, $$scope, slots];\n}\n\nclass StatusAside extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$v, create_fragment$u, safe_not_equal, { offset: 3, opacity: 0, class: 1 });\n\t}\n}\n\nvar cursorMoveToEnd = (field) => (field.selectionStart = field.selectionEnd = field.value.length);\n\nlet result$3 = null;\nvar supportsVisualViewport = () => {\n    if (result$3 === null) {\n        result$3 = isBrowser() && 'visualViewport' in window;\n    }\n    return result$3;\n};\n\nvar createSoftKeyboardObserver = (cb) => {\n    if (!supportsVisualViewport())\n        return false;\n    const heightNormal = visualViewport.height;\n    const testState = () => {\n        cb(visualViewport.height < heightNormal ? 'visible' : 'hidden');\n    };\n    visualViewport.addEventListener('resize', testState);\n    return () => visualViewport.removeEventListener('resize', testState);\n};\n\n/* src/core/ui/components/InputForm.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block_1$8(ctx) {\n\tlet button;\n\tlet current;\n\tconst button_spread_levels = [{ onclick: /*oncancel*/ ctx[1] }, /*buttonCancel*/ ctx[3]];\n\tlet button_props = {};\n\n\tfor (let i = 0; i < button_spread_levels.length; i += 1) {\n\t\tbutton_props = assign(button_props, button_spread_levels[i]);\n\t}\n\n\tbutton = new Button({ props: button_props });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(button.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(button, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst button_changes = (dirty[0] & /*oncancel, buttonCancel*/ 10)\n\t\t\t? get_spread_update(button_spread_levels, [\n\t\t\t\t\tdirty[0] & /*oncancel*/ 2 && { onclick: /*oncancel*/ ctx[1] },\n\t\t\t\t\tdirty[0] & /*buttonCancel*/ 8 && get_spread_object(/*buttonCancel*/ ctx[3])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tbutton.$set(button_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(button, detaching);\n\t\t}\n\t};\n}\n\n// (283:8) {#if buttonConfirm}\nfunction create_if_block$c(ctx) {\n\tlet button;\n\tlet current;\n\n\tconst button_spread_levels = [\n\t\t{ onclick: /*onconfirm*/ ctx[0] },\n\t\t{ class: \"PinturaInputFormButtonConfirm\" },\n\t\t/*buttonConfirm*/ ctx[2]\n\t];\n\n\tlet button_props = {};\n\n\tfor (let i = 0; i < button_spread_levels.length; i += 1) {\n\t\tbutton_props = assign(button_props, button_spread_levels[i]);\n\t}\n\n\tbutton = new Button({ props: button_props });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(button.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(button, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst button_changes = (dirty[0] & /*onconfirm, buttonConfirm*/ 5)\n\t\t\t? get_spread_update(button_spread_levels, [\n\t\t\t\t\tdirty[0] & /*onconfirm*/ 1 && { onclick: /*onconfirm*/ ctx[0] },\n\t\t\t\t\tbutton_spread_levels[1],\n\t\t\t\t\tdirty[0] & /*buttonConfirm*/ 4 && get_spread_object(/*buttonConfirm*/ ctx[2])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tbutton.$set(button_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(button, detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$t(ctx) {\n\tlet div2;\n\tlet div1;\n\tlet t0;\n\tlet div0;\n\tlet t1;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block0 = /*buttonCancel*/ ctx[3] && create_if_block_1$8(ctx);\n\tconst default_slot_template = /*#slots*/ ctx[29].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[28], null);\n\tlet if_block1 = /*buttonConfirm*/ ctx[2] && create_if_block$c(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv2 = element(\"div\");\n\t\t\tdiv1 = element(\"div\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tdiv0 = element(\"div\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(div0, \"class\", \"PinturaInputFormFields\");\n\t\t\tattr(div1, \"class\", \"PinturaInputFormInner\");\n\t\t\tattr(div2, \"class\", \"PinturaInputForm\");\n\t\t\tattr(div2, \"data-layout\", /*layout*/ ctx[4]);\n\t\t\tset_style(div2, \"opacity\", /*styleOpacity*/ ctx[6]);\n\t\t\tset_style(div2, \"left\", /*styleLeft*/ ctx[7]);\n\t\t\tset_style(div2, \"top\", /*styleTop*/ ctx[8]);\n\t\t\tset_style(div2, \"right\", /*styleRight*/ ctx[9]);\n\t\t\tset_style(div2, \"bottom\", /*styleBottom*/ ctx[10]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div2, anchor);\n\t\t\tappend(div2, div1);\n\t\t\tif (if_block0) if_block0.m(div1, null);\n\t\t\tappend(div1, t0);\n\t\t\tappend(div1, div0);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(div0, null);\n\t\t\t}\n\n\t\t\tappend(div1, t1);\n\t\t\tif (if_block1) if_block1.m(div1, null);\n\t\t\t/*div2_binding*/ ctx[30](div2);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div0, \"keydown\", /*handleKeydown*/ ctx[14]),\n\t\t\t\t\tlisten(div2, \"focusin\", /*handleFocusIn*/ ctx[11]),\n\t\t\t\t\tlisten(div2, \"focusout\", /*handleFocusOut*/ ctx[12]),\n\t\t\t\t\tlisten(div2, \"measure\", /*handleMeasure*/ ctx[13]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div2))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*buttonCancel*/ ctx[3]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*buttonCancel*/ 8) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_1$8(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div1, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty[0] & /*$$scope*/ 268435456)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[28],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[28])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[28], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (/*buttonConfirm*/ ctx[2]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*buttonConfirm*/ 4) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block$c(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(div1, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*layout*/ 16) {\n\t\t\t\tattr(div2, \"data-layout\", /*layout*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleOpacity*/ 64) {\n\t\t\t\tset_style(div2, \"opacity\", /*styleOpacity*/ ctx[6]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleLeft*/ 128) {\n\t\t\t\tset_style(div2, \"left\", /*styleLeft*/ ctx[7]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleTop*/ 256) {\n\t\t\t\tset_style(div2, \"top\", /*styleTop*/ ctx[8]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleRight*/ 512) {\n\t\t\t\tset_style(div2, \"right\", /*styleRight*/ ctx[9]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleBottom*/ 1024) {\n\t\t\t\tset_style(div2, \"bottom\", /*styleBottom*/ ctx[10]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(default_slot, local);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(default_slot, local);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div2);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tif (if_block1) if_block1.d();\n\t\t\t/*div2_binding*/ ctx[30](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nconst panelDelay = 200;\n\nfunction instance$u($$self, $$props, $$invalidate) {\n\tlet shouldForcePosition;\n\tlet panelForcedPosition;\n\tlet computedStyle;\n\tlet shouldStickToKeyboard;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { onconfirm } = $$props;\n\tlet { oncancel } = $$props;\n\tlet { autoFocus = true } = $$props;\n\tlet { autoPositionCursor = true } = $$props;\n\tlet { buttonConfirm = undefined } = $$props;\n\tlet { buttonCancel = undefined } = $$props;\n\tlet { layout = 'stack' } = $$props;\n\tlet { parentRect = undefined } = $$props;\n\tlet { align = undefined } = $$props;\n\tlet { justify = undefined } = $$props;\n\tlet { parentMargin = 16 } = $$props;\n\tlet { panelOffset = vectorCreateEmpty() } = $$props;\n\tlet { willHandleKeydown = () => true } = $$props;\n\tlet panelVisible = false;\n\tlet panelSize = undefined;\n\tlet panelRevealTimeout = undefined;\n\n\t// let panelPositionStyle = '';\n\tlet panelVerticalPosition = { top: undefined, bottom: undefined };\n\n\tlet styleOpacity = 0;\n\tlet styleLeft = undefined;\n\tlet styleTop = undefined;\n\tlet styleRight = undefined;\n\tlet styleBottom = undefined;\n\tlet root;\n\n\tconst getForcedPosition = (parentRect, panelSize, align, justify, margin) => {\n\t\tlet x;\n\t\tlet y;\n\n\t\tif (justify === 'center') {\n\t\t\tx = parentRect.x + parentRect.width * 0.5 - panelSize.width * 0.5;\n\t\t} else if (justify === 'right') {\n\t\t\tx = parentRect.x + parentRect.width - panelSize.width - margin;\n\t\t} else {\n\t\t\tx = parentRect.x + margin;\n\t\t}\n\n\t\tif (align === 'center') {\n\t\t\ty = parentRect.y + parentRect.height * 0.5 - panelSize.height * 0.5;\n\t\t} else if (align === 'bottom') {\n\t\t\ty = parentRect.y + parentRect.height - panelSize.height - margin;\n\t\t} else {\n\t\t\ty = parentRect.y + margin;\n\t\t}\n\n\t\treturn {\n\t\t\ttop: `${y}px`,\n\t\t\tright: 'auto',\n\t\t\tbottom: 'auto',\n\t\t\tleft: `${x}px`\n\t\t};\n\t};\n\n\tconst isTextarea = element => (/textarea/i).test(element);\n\n\tconst preventTextAreaScrollingOnIOS = element => {\n\t\t// preventsDefault on textarea events when can no longer scroll up or down in textarea\n\t\tlet lastScreenY;\n\n\t\tconst handleTouchStart = e => lastScreenY = e.touches[0].screenY;\n\n\t\tconst handleTouchMove = e => {\n\t\t\tconst currentScreenY = e.touches[0].screenY;\n\t\t\tconst target = e.target;\n\n\t\t\tif ((/textarea/i).test(target.nodeName)) {\n\t\t\t\t// moving down\n\t\t\t\tif (currentScreenY > lastScreenY) {\n\t\t\t\t\tif (target.scrollTop == 0) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t} else // moving up\n\t\t\t\tif (currentScreenY < lastScreenY) {\n\t\t\t\t\tif (target.scrollTop + target.offsetHeight == target.scrollHeight) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}\n\n\t\t\t\tlastScreenY = currentScreenY;\n\t\t\t} else {\n\t\t\t\te.preventDefault();\n\t\t\t}\n\t\t};\n\n\t\telement.addEventListener('touchstart', handleTouchStart);\n\t\telement.addEventListener('touchmove', handleTouchMove);\n\n\t\treturn () => {\n\t\t\telement.removeEventListener('touchstart', handleTouchStart);\n\t\t\telement.removeEventListener('touchmove', handleTouchMove);\n\t\t};\n\t};\n\n\tconst focus = () => {\n\t\t// focus field\n\t\tconst field = root.querySelector('input, textarea');\n\n\t\tfield.focus();\n\n\t\t// only select when showing for first time\n\t\tif (styleOpacity >= 1) return;\n\n\t\tfield.select();\n\t};\n\n\tconst show = () => {\n\t\tpanelVisible = true;\n\n\t\t// browser does not support keyboard listener, place modal at top of view\n\t\tif (!unsubSoftKeyboardListener && (isIOS() || isAndroid())) {\n\t\t\t$$invalidate(24, panelVerticalPosition = { top: '1em', bottom: 'auto' });\n\t\t}\n\n\t\t// prevent interacting with the root element\n\t\tif (isIOS()) preventTextAreaScrollingOnIOS(root);\n\n\t\t// reveal\n\t\t$$invalidate(6, styleOpacity = 1);\n\t};\n\n\tconst hide = () => {\n\t\tpanelVisible = false;\n\t\t$$invalidate(6, styleOpacity = 0);\n\t};\n\n\tconst handleSoftKeyboard = keyboardState => {\n\t\t// shouldn't stick, we'll stick it to the top of the viewport so the keyboard doesn't obscure the input field\n\t\tif (!shouldStickToKeyboard) {\n\t\t\t$$invalidate(24, panelVerticalPosition = { top: '4.5em', bottom: 'auto' });\n\t\t\treturn;\n\t\t}\n\n\t\t// no need to continue, already hidden\n\t\tif (keyboardState === 'hidden' && !panelVisible) {\n\t\t\tfocus();\n\t\t\treturn;\n\t\t}\n\n\t\t// gonna update position here\n\t\tclearTimeout(panelRevealTimeout);\n\n\t\tpanelRevealTimeout = undefined;\n\n\t\t// position\n\t\t$$invalidate(24, panelVerticalPosition = {\n\t\t\ttop: `${visualViewport.height - panelSize.height - panelOffset.y}px`\n\t\t});\n\n\t\t// if a soft keyboard is detected, turn into modal mode\n\t\tif (keyboardState === 'visible') {\n\t\t\t// stick to keyboard\n\t\t\t$$invalidate(5, root.dataset.stick = true, root);\n\n\t\t\t// need to refocus\n\t\t\tfocus();\n\n\t\t\t// place above keyboard\n\t\t\tshow();\n\t\t} else // keyboard is hidden\n\t\t{\n\t\t\thide();\n\t\t}\n\t};\n\n\tlet focusDateTime;\n\n\tconst handleFocusIn = e => {\n\t\tif (!isTextarea(e.target) && !isTextInput(e.target)) return;\n\n\t\t// we need to remember focus time so we can detect unrealistic blur event caused by soft keyboard shenanigans\n\t\tfocusDateTime = Date.now();\n\n\t\t// move cursor\n\t\tif (autoPositionCursor) cursorMoveToEnd(e.target);\n\n\t\t// wait a couple milliseconds\n\t\tclearTimeout(panelRevealTimeout);\n\n\t\tpanelRevealTimeout = setTimeout(show, panelDelay);\n\t};\n\n\tconst handleFocusOut = e => {\n\t\tconst focusDuration = Date.now() - focusDateTime;\n\t\tif (focusDuration > 50) return;\n\n\t\t// unrealistic blur, refocus\n\t\te.stopPropagation();\n\n\t\tfocus();\n\t};\n\n\tconst unsubSoftKeyboardListener = createSoftKeyboardObserver(handleSoftKeyboard);\n\n\tconst handleMeasure = ({ detail }) => {\n\t\t$$invalidate(23, panelSize = {\n\t\t\twidth: detail.width,\n\t\t\theight: detail.height\n\t\t});\n\t};\n\n\tconst handleKeydown = e => {\n\t\tif (!willHandleKeydown(e)) return;\n\t\tif (e.key === 'Enter') return onconfirm();\n\t\tif (e.key === 'Escape') return oncancel();\n\t};\n\n\tonMount(() => {\n\t\tif (!autoFocus) return;\n\t\tfocus();\n\t});\n\n\tonDestroy(() => {\n\t\tunsubSoftKeyboardListener && unsubSoftKeyboardListener();\n\t});\n\n\tfunction div2_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\troot = $$value;\n\t\t\t$$invalidate(5, root);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('onconfirm' in $$props) $$invalidate(0, onconfirm = $$props.onconfirm);\n\t\tif ('oncancel' in $$props) $$invalidate(1, oncancel = $$props.oncancel);\n\t\tif ('autoFocus' in $$props) $$invalidate(15, autoFocus = $$props.autoFocus);\n\t\tif ('autoPositionCursor' in $$props) $$invalidate(16, autoPositionCursor = $$props.autoPositionCursor);\n\t\tif ('buttonConfirm' in $$props) $$invalidate(2, buttonConfirm = $$props.buttonConfirm);\n\t\tif ('buttonCancel' in $$props) $$invalidate(3, buttonCancel = $$props.buttonCancel);\n\t\tif ('layout' in $$props) $$invalidate(4, layout = $$props.layout);\n\t\tif ('parentRect' in $$props) $$invalidate(17, parentRect = $$props.parentRect);\n\t\tif ('align' in $$props) $$invalidate(18, align = $$props.align);\n\t\tif ('justify' in $$props) $$invalidate(19, justify = $$props.justify);\n\t\tif ('parentMargin' in $$props) $$invalidate(20, parentMargin = $$props.parentMargin);\n\t\tif ('panelOffset' in $$props) $$invalidate(21, panelOffset = $$props.panelOffset);\n\t\tif ('willHandleKeydown' in $$props) $$invalidate(22, willHandleKeydown = $$props.willHandleKeydown);\n\t\tif ('$$scope' in $$props) $$invalidate(28, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*parentRect, panelSize*/ 8519680) {\n\t\t\t$$invalidate(27, shouldForcePosition = parentRect && panelSize);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldForcePosition, parentRect, panelSize, align, justify, parentMargin*/ 144572416) {\n\t\t\t$$invalidate(26, panelForcedPosition = shouldForcePosition\n\t\t\t? getForcedPosition(parentRect, panelSize, align, justify, parentMargin)\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldForcePosition, panelForcedPosition*/ 201326592) {\n\t\t\t$$invalidate(7, styleLeft = shouldForcePosition\n\t\t\t? panelForcedPosition.left\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldForcePosition, panelForcedPosition, panelVerticalPosition*/ 218103808) {\n\t\t\t$$invalidate(8, styleTop = shouldForcePosition\n\t\t\t? panelForcedPosition.top\n\t\t\t: panelVerticalPosition.top);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldForcePosition, panelForcedPosition*/ 201326592) {\n\t\t\t$$invalidate(9, styleRight = shouldForcePosition\n\t\t\t? panelForcedPosition.right\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldForcePosition, panelForcedPosition, panelVerticalPosition*/ 218103808) {\n\t\t\t$$invalidate(10, styleBottom = shouldForcePosition\n\t\t\t? panelForcedPosition.bottom\n\t\t\t: panelVerticalPosition.bottom);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 32) {\n\t\t\t$$invalidate(25, computedStyle = root && getComputedStyle(root));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*computedStyle*/ 33554432) {\n\t\t\tshouldStickToKeyboard = computedStyle && computedStyle.getPropertyValue('--editor-modal') === '1';\n\t\t}\n\t};\n\n\treturn [\n\t\tonconfirm,\n\t\toncancel,\n\t\tbuttonConfirm,\n\t\tbuttonCancel,\n\t\tlayout,\n\t\troot,\n\t\tstyleOpacity,\n\t\tstyleLeft,\n\t\tstyleTop,\n\t\tstyleRight,\n\t\tstyleBottom,\n\t\thandleFocusIn,\n\t\thandleFocusOut,\n\t\thandleMeasure,\n\t\thandleKeydown,\n\t\tautoFocus,\n\t\tautoPositionCursor,\n\t\tparentRect,\n\t\talign,\n\t\tjustify,\n\t\tparentMargin,\n\t\tpanelOffset,\n\t\twillHandleKeydown,\n\t\tpanelSize,\n\t\tpanelVerticalPosition,\n\t\tcomputedStyle,\n\t\tpanelForcedPosition,\n\t\tshouldForcePosition,\n\t\t$$scope,\n\t\tslots,\n\t\tdiv2_binding\n\t];\n}\n\nclass InputForm extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$u,\n\t\t\tcreate_fragment$t,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tonconfirm: 0,\n\t\t\t\toncancel: 1,\n\t\t\t\tautoFocus: 15,\n\t\t\t\tautoPositionCursor: 16,\n\t\t\t\tbuttonConfirm: 2,\n\t\t\t\tbuttonCancel: 3,\n\t\t\t\tlayout: 4,\n\t\t\t\tparentRect: 17,\n\t\t\t\talign: 18,\n\t\t\t\tjustify: 19,\n\t\t\t\tparentMargin: 20,\n\t\t\t\tpanelOffset: 21,\n\t\t\t\twillHandleKeydown: 22\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n}\n\nvar fastSeek = (video, time) => {\n    if (video.fastSeek) {\n        video.fastSeek(time);\n    }\n    video.currentTime = time;\n};\n\nvar isApplePencilEvent = (e) => {\n    return e.touches && e.touches.length && e.touches[0].touchType === 'stylus';\n};\n\n// these are derived stores, we can filter them out\nconst ImagePropsDerived = ['aspectRatio', 'isRotatedSideways', 'flip', 'cropSize'];\n// map descriptors to props\nconst ImageStoreProps = ImageStorePropDescriptors.map(([name]) => name).filter((name) => !ImagePropsDerived.includes(name));\nconst proxy = function (get, set, update) {\n    let subscribers = [];\n    return {\n        set,\n        update,\n        publish: (value) => {\n            subscribers.forEach((cb) => cb(value));\n        },\n        subscribe: (cb) => {\n            subscribers.push(cb);\n            get(cb);\n            return () => {\n                subscribers = subscribers.filter((item) => item !== cb);\n            };\n        },\n    };\n};\nvar createImageProxy = () => {\n    let unsubs;\n    let image;\n    const proxyStores = ImageStoreProps.reduce((prev, curr) => {\n        prev[curr] = proxy(\n        // getter\n        (cb) => {\n            // subscribe\n            if (!image)\n                return cb();\n            const unsub = image.stores[curr].subscribe(cb);\n            unsub();\n        }, \n        // setter\n        (value) => {\n            // set value on actual store if is defined\n            if (!image)\n                return;\n            image.stores[curr].set(value);\n        }, \n        // updater\n        (cb) => {\n            if (!image)\n                return;\n            image.stores[curr].update(cb);\n        });\n        return prev;\n    }, {});\n    const update = (newImage) => {\n        image = newImage;\n        if (unsubs) {\n            // remove subscribers\n            unsubs.forEach((unsub) => unsub());\n            unsubs = undefined;\n        }\n        if (!newImage) {\n            // need to reset load state\n            proxyStores['file'].publish(undefined);\n            proxyStores['loadState'].publish(undefined);\n            return;\n        }\n        unsubs = ImageStoreProps.map((prop) => newImage.stores[prop].subscribe((value) => {\n            proxyStores[prop].publish(value);\n        }));\n    };\n    return {\n        update,\n        stores: proxyStores,\n        destroy: () => {\n            if (unsubs)\n                unsubs.forEach((unsub) => unsub());\n        },\n    };\n};\n\nvar createPingRouter = (route, cancel = true) => (e) => {\n    if (e.type !== 'ping')\n        return;\n    if (cancel)\n        e.stopPropagation();\n    route(e.detail.type, e.detail.data);\n};\n\nvar createPing = (type, data) => new CustomEvent('ping', {\n    detail: {\n        type,\n        data,\n    },\n    cancelable: true,\n    bubbles: true,\n});\n\nvar toKebabCase = (str, abbr) => {\n    return (abbr ? stringReplace(str, abbr) : str)\n        .replace(/([a-z])([A-Z])/g, '$1-$2')\n        .replace(/\\s+/g, '-')\n        .toLowerCase();\n};\n\nvar matchMedia$1 = (query, cb) => {\n    const mql = matchMedia(query);\n    mql.addListener(cb);\n    cb(mql);\n    return {\n        get matches() { return mql.matches; },\n        destroy: () => mql.removeListener(cb)\n    };\n};\n\nvar mediaQueryStore = (query, formatValue = passthrough) => {\n    const { subscribe, set } = writable(undefined);\n    const mm = matchMedia$1(query, ({ matches }) => set(formatValue(matches)));\n    return {\n        subscribe,\n        destroy: mm.destroy,\n    };\n};\n\nvar canPreventNavSwipe = () => {\n    // if not iOS we can't prevent swipe because it probably isn't a thing\n    if (!isIOS())\n        return false;\n    // extract version number\n    const matches = navigator.userAgent.match(/OS (\\d+)_(\\d+)_?(\\d+)?/i) || [];\n    const [, major, minor] = matches.map((v) => parseInt(v, 10) || 0);\n    // is atleast version 13.4+\n    return major > 13 || (major === 13 && minor >= 4);\n};\n\n// @ts-ignore\nvar historyCreate = (getState, setState, options) => {\n    // set up pub/sub for history object\n    const { sub, pub } = pubsub();\n    const { willUndo = () => true } = options || {};\n    // current history state\n    const entries = [];\n    const index = writable(0);\n    const subs = [];\n    const updateSubs = () => subs.forEach((cb) => cb({ index: get_store_value(index), length: entries.length }));\n    const history = {\n        get index() {\n            return get_store_value(index);\n        },\n        set index(i) {\n            // validate new index\n            i = Number.isInteger(i) ? i : 0;\n            i = clamp(i, 0, entries.length - 1);\n            // remember\n            index.set(i);\n            setState(entries[history.index]);\n            // update subs\n            updateSubs();\n        },\n        get state() {\n            return entries[entries.length - 1];\n        },\n        length() {\n            return entries.length;\n        },\n        undo() {\n            if (willUndo() === false)\n                return;\n            const newIndex = history.index--;\n            pub('undo', newIndex);\n            return newIndex;\n        },\n        redo() {\n            const newIndex = history.index++;\n            pub('redo', history.index);\n            return newIndex;\n        },\n        revert() {\n            entries.length = 1; // retain first state\n            history.index = 0;\n            pub('revert');\n        },\n        write(state) {\n            // write history entry\n            if (state) {\n                setState({\n                    ...getState(),\n                    ...state,\n                });\n            }\n            const newState = getState();\n            const lastState = entries[entries.length - 1];\n            // don't update if new state isn't different\n            if (JSON.stringify(newState) === JSON.stringify(lastState))\n                return;\n            // reset length to current index\n            entries.length = history.index + 1;\n            // add new entry\n            entries.push(newState);\n            // move pointer to last added index\n            index.set(entries.length - 1);\n            updateSubs();\n            pub('writehistory');\n        },\n        set(state = {}) {\n            // set clears all entries\n            entries.length = 0;\n            history.index = 0;\n            // set new entries\n            const newStateEntries = !Array.isArray(state) ? [state] : state;\n            // add new entries\n            entries.push(...newStateEntries);\n            // move pointer to last added index\n            history.index = entries.length - 1;\n        },\n        get() {\n            return [...entries];\n        },\n        subscribe(cb) {\n            subs.push(cb);\n            cb({ index: history.index, length: entries.length });\n            return () => subs.splice(subs.indexOf(cb), 1);\n        },\n        on: sub,\n    };\n    return history;\n};\n\nvar imageBitmapToImageData = async (imageBitmap) => canvasToImageData(await imageDataToCanvas(imageBitmap));\n\nvar blobToImageBitmap = (file, options) => new Promise((resolve, reject) => {\n    (async () => {\n        const { imageOrienter: ImageOrienter, canvasMemoryLimit } = options || {};\n        // if is video we turn first video frame into image data\n        if (isVideoFile(file))\n            resolve(await videoToImageData(file));\n        // get orientation of image, should return 1 for normal orientation\n        const orientation = await ImageOrienter.read(file);\n        // helper method to apply orientation fix if needed\n        const toImageData = (file) => blobToImageData(file, { canvasMemoryLimit })\n            .then((imageData) => ImageOrienter.apply(imageData, orientation))\n            .then(resolve)\n            .catch(reject);\n        // if cannot create image bitmaps in worker\n        // Safari 15 cannot correctly apply orientation, also it will choke on very big images\n        // when trying to createImageBitmap in thread, so lets just do it on the main thread\n        // we'll ignore Safari and iOS for now\n        if (isSVGFile(file) || !canCreateImageBitmap() || isSafari() || isIOS()) {\n            return toImageData(file);\n        }\n        // create image bitmap in thread\n        let imageBitmap;\n        try {\n            imageBitmap = await thread((file, done) => createImageBitmap(file, {\n                // lock in default color space conversion\n                colorSpaceConversion: 'default',\n            })\n                .then((bitmap) => done(null, bitmap))\n                .catch(done), [file]);\n        }\n        catch (err) {\n            // fails silently on purpose, we'll try to turn the blob into image data in the main thread\n            // console.error(err);\n        }\n        // no bitmap returned, something went wrong in `createImageBitmap` logic\n        if (!imageBitmap || !imageBitmap.width) {\n            return toImageData(file);\n        }\n        // if the browser can't orient images, we need to correct the orientation now\n        if (!(await canOrientImages())) {\n            return resolve(ImageOrienter.apply(imageBitmap, orientation));\n        }\n        // need to convert so oriented image can be used as WebGL texture\n        // converting ImageBitmap to <canvas> (and then optionally to image data) fixes a Chrome render bug where the\n        // ImageBitmap when used in WebGL doesn't render in the correct orientation\n        // https://bugs.chromium.org/p/chromium/issues/detail?id=1082451&q=orientation%20imagebitmap&can=2\n        if (isChrome() && orientation > 1) {\n            return resolve(await imageBitmapToImageData(imageBitmap));\n        }\n        // yay we got our bitmap\n        resolve(imageBitmap);\n    })();\n});\n\nvar imageDataContain = (imageData, size) => new Promise(async (resolve) => {\n    if (imageData.width < size.width && imageData.height < size.height)\n        return resolve(imageData);\n    const scalar = Math.min(size.width / imageData.width, size.height / imageData.height);\n    // scale\n    const targetWidth = scalar * imageData.width;\n    const targetHeight = scalar * imageData.height;\n    const canvas = h('canvas', {\n        width: targetWidth,\n        height: targetHeight,\n    });\n    const ctx = canvas.getContext('2d', { willReadFrequently: true });\n    const data = isImageData(imageData)\n        ? (await imageDataToCanvas(imageData))\n        : imageData;\n    ctx.drawImage(data, 0, 0, targetWidth, targetHeight);\n    resolve(canvasToImageData(canvas));\n});\n\nlet result$2 = null;\nvar supportsWebGL = () => {\n    if (result$2 === null) {\n        let canvas = h('canvas');\n        const ctx = getWebGLContext(canvas);\n        result$2 = ctx ? !ctx.isContextLost() : false;\n        releaseCanvas(canvas);\n        canvas = undefined;\n    }\n    return result$2;\n};\n\nvar isBitmap = (file) => /^image/.test(file.type) && !/svg/.test(file.type);\n\n// @ts-ignore\nconst COLOR_MATRIX_IDENTITY = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\nconst SPRING_PROPS = { precision: 0.0001 };\nconst SPRING_PROPS_FRACTION = { precision: SPRING_PROPS.precision * 0.01 };\nvar createImage = (data, size, options = {}) => {\n    const { resize: resizeInitial = 1, opacity: opacityInitial = 0 } = options;\n    const stores = {\n        // interface\n        opacity: [spring(opacityInitial, { ...SPRING_PROPS, stiffness: 0.1 }), passthrough],\n        resize: [spring(resizeInitial, { ...SPRING_PROPS, stiffness: 0.1 }), passthrough],\n        // transforms\n        translation: [spring(undefined, SPRING_PROPS), passthrough],\n        rotation: [spring(undefined, SPRING_PROPS_FRACTION), passthrough],\n        origin: [spring(undefined, SPRING_PROPS), passthrough],\n        scale: [spring(undefined, SPRING_PROPS_FRACTION), passthrough],\n        gamma: [spring(undefined, SPRING_PROPS_FRACTION), (v) => v || 1],\n        vignette: [spring(undefined, SPRING_PROPS_FRACTION), (v) => v || 0],\n        colorMatrix: [\n            spring([...COLOR_MATRIX_IDENTITY], SPRING_PROPS),\n            (v) => v || [...COLOR_MATRIX_IDENTITY],\n        ],\n        convolutionMatrix: [writable(undefined), (v) => (v && v.clarity) || undefined],\n        backgroundColor: [\n            spring(undefined, SPRING_PROPS),\n            (newValue, currentValue, setHard) => {\n                if (!Array.isArray(newValue))\n                    return undefined;\n                // makes sure\n                if (Array.isArray(currentValue)) {\n                    const newColor = [...newValue];\n                    // if going from transparent to opaque\n                    if (currentValue[3] === 0) {\n                        newColor[3] = 0;\n                        setHard(newColor);\n                    }\n                    // if going from opaque to transparent\n                    else if (newColor[3] === 0) {\n                        newValue = [...currentValue];\n                        newValue[3] = 0;\n                    }\n                }\n                return newValue;\n            },\n        ],\n        backgroundImage: [writable(undefined), passthrough],\n        backgroundFilterMode: [writable(undefined), passthrough],\n    };\n    // shortcut to quickly get all stores from the stores object\n    const storeEntries = Object.entries(stores).map(([key, value]) => [key, value[0]]);\n    const storeArray = storeEntries.map(([, store]) => store);\n    // create quick accessors to store value setter functions, best to do ones on creation instead of on each update\n    const storeSetters = Object.entries(stores).reduce((prev, [key, value]) => {\n        const [store, getValue] = value;\n        prev[key] = (value, opts) => store.set(getValue(value, stateCache[key], (value) => {\n            store.set(value, { hard: true });\n        }), opts);\n        return prev;\n    }, {});\n    // holds current derived state so can be easily read from from the outside\n    let stateCache;\n    //\n    const state = derived(storeArray, (storeValues) => {\n        // get new state\n        stateCache = storeValues.reduce((calculatedState, value, index) => {\n            const key = storeEntries[index][0];\n            calculatedState[key] = value;\n            return calculatedState;\n        }, {});\n        // set base image props\n        stateCache.data = data;\n        stateCache.size = size;\n        // apply resize modifier (is at index 1 of storeValues)\n        stateCache.scale *= storeValues[1];\n        return stateCache;\n    });\n    state.get = () => stateCache;\n    state.set = (props, animate) => {\n        const opts = { hard: !animate };\n        Object.entries(props).forEach(([key, value]) => {\n            if (!storeSetters[key])\n                return;\n            storeSetters[key](value, opts);\n        });\n    };\n    return state;\n};\n\nvar storeList = () => {\n    const stores = [];\n    const subscribers = [];\n    const state = [];\n    const storeDidUpdate = (store, value) => {\n        const index = stores.indexOf(store);\n        if (index < 0)\n            return;\n        state[index] = value;\n        triggerUpdate();\n    };\n    const triggerUpdate = () => {\n        subscribers.forEach((fn) => fn(state));\n    };\n    const addStore = (store) => {\n        store.unsub = store.subscribe((value) => storeDidUpdate(store, value));\n        triggerUpdate();\n    };\n    const unshift = (store) => {\n        stores.unshift(store);\n        addStore(store);\n    };\n    const push = (store) => {\n        stores.push(store);\n        addStore(store);\n    };\n    const clear = () => {\n        stores.forEach((store) => store.unsub());\n        stores.length = 0;\n        state.length = 0;\n    };\n    const remove = (store) => {\n        store.unsub();\n        const index = stores.indexOf(store);\n        stores.splice(index, 1);\n        state.splice(index, 1);\n    };\n    const subscribe = (fn) => {\n        subscribers.push(fn);\n        fn(state);\n        return () => {\n            subscribers.splice(subscribers.indexOf(fn), 1);\n        };\n    };\n    const forEach = (fn) => stores.forEach(fn);\n    const filter = (fn) => stores.filter(fn);\n    const get = (index) => stores[index];\n    return {\n        get length() {\n            return stores.length;\n        },\n        clear,\n        unshift,\n        get,\n        push,\n        remove,\n        forEach,\n        filter,\n        subscribe,\n    };\n};\n\nvar isDarkColor = (color) => color[0] < 0.25 && color[1] < 0.25 && color[2] < 0.25;\n\nvar browse = (options = {}) => new Promise((resolve) => {\n    // can now pass options\n    const { accept = 'image/*' } = options;\n    // create file input box\n    const fileInput = h('input', {\n        style: 'position:absolute;visibility:hidden;width:0;height:0;',\n        type: 'file',\n        accept,\n    });\n    // listen for file changes on input\n    const handleFileChange = () => {\n        // get file, if one was selected\n        const [file] = fileInput.files;\n        // clean up\n        fileInput.parentNode && fileInput.remove();\n        fileInput.removeEventListener('change', handleFileChange);\n        // done\n        resolve(file);\n    };\n    // listen for changes\n    fileInput.addEventListener('change', handleFileChange);\n    // need to attach to DOM for Safari 15+\n    isIOS() && document.body.append(fileInput);\n    // open browse window\n    fileInput.click();\n    // there is no way to reliably detect \"cancel\" event on browsers so we'll leave it be for now\n});\n\nvar runSafe = (cb) => {\n    try {\n        return cb();\n    }\n    catch (err) {\n        console.error(err);\n    }\n};\n\nvar getRangeCenter = ([min, max]) => min + (max - min) * 0.5;\n\nvar toPercentageNumber = (v) => Math.round(v * 100);\n\nvar getEventPositionInViewport = (e) => vectorCreate(e.clientX, e.clientY);\n\nvar getEventPositionInStage = (e, viewOffset, stageOffset) => {\n    const positionInViewport = getEventPositionInViewport(e);\n    return vectorSubtract(vectorSubtract(positionInViewport, viewOffset), stageOffset);\n};\n\n/* src/core/ui/components/CanvasPanAndZoom.svelte generated by Svelte v4.2.20 */\n\nfunction instance$t($$self, $$props, $$invalidate) {\n\tlet canZoom;\n\tlet canPan;\n\tlet imageFitsOnStage;\n\tlet zoomLevels;\n\tlet zoomMin;\n\tlet zoomMax;\n\tlet zoomLevelSelectedIndex;\n\tlet zoomLevelCurrent;\n\tlet zoomLevelLabel;\n\tlet $imageSelectionZoom;\n\tlet $imageSelectionPan;\n\tlet $imageSelectionStageFitScalar;\n\tlet $imagePreviewUpscale;\n\tlet $stageRect;\n\tlet $rootRect;\n\tlet $imageSelectionRect;\n\tlet $fixScrollDirectionStore;\n\tlet $isInteracting;\n\tlet $stageScalar;\n\n\tlet $isAnimated,\n\t\t$$unsubscribe_isAnimated = noop,\n\t\t$$subscribe_isAnimated = () => ($$unsubscribe_isAnimated(), $$unsubscribe_isAnimated = subscribe(isAnimated, $$value => $$invalidate(74, $isAnimated = $$value)), isAnimated);\n\n\tlet $zoomAdjust;\n\tlet $imageSelectionStoredState;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isAnimated());\n\tlet { root } = $$props;\n\tlet { locale } = $$props;\n\tlet { stores } = $$props;\n\tlet { isAnimated } = $$props;\n\t$$subscribe_isAnimated();\n\tlet { allowPan = true } = $$props;\n\tlet { allowZoom = true } = $$props;\n\tlet { enablePan = true } = $$props;\n\tlet { enableZoom = true } = $$props;\n\tlet { enableZoomControls = enableZoom } = $$props;\n\tlet { enableZoomInput = true } = $$props;\n\tlet { enablePanInput = true } = $$props;\n\tlet { enablePanLimit = true } = $$props;\n\tlet { panLimitGutterScalar = 0 } = $$props;\n\tlet { zoomOptions = [0.25, 0.5, 1, 1.25, 1.5, 2, 3, 4, 6, 8, 16] } = $$props;\n\tlet { zoomAdjustStep = 0.25 } = $$props;\n\tlet { zoomAdjustFactor = 0.1 } = $$props;\n\tlet { zoomAdjustWheelFactor = 1 } = $$props;\n\tlet { elasticity = 5 } = $$props;\n\tlet { imageSelectionRectCentered = undefined } = $$props;\n\tlet { imageSelectionRectScalar = undefined } = $$props;\n\tlet { zoomLevel = null } = $$props;\n\tlet { zoomControls } = $$props;\n\tlet { zoomMultiTouching = false } = $$props;\n\tconst { isInteracting, rootRect, stageRect, stageScalar, imageSelectionPan, imageSelectionZoom, imageSelectionStageFitScalar, imageSelectionRect, imageSelectionStoredState, imagePreviewUpscale } = stores;\n\tcomponent_subscribe($$self, isInteracting, value => $$invalidate(73, $isInteracting = value));\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(70, $rootRect = value));\n\tcomponent_subscribe($$self, stageRect, value => $$invalidate(69, $stageRect = value));\n\tcomponent_subscribe($$self, stageScalar, value => $$invalidate(47, $stageScalar = value));\n\tcomponent_subscribe($$self, imageSelectionPan, value => $$invalidate(68, $imageSelectionPan = value));\n\tcomponent_subscribe($$self, imageSelectionZoom, value => $$invalidate(44, $imageSelectionZoom = value));\n\tcomponent_subscribe($$self, imageSelectionStageFitScalar, value => $$invalidate(45, $imageSelectionStageFitScalar = value));\n\tcomponent_subscribe($$self, imageSelectionRect, value => $$invalidate(71, $imageSelectionRect = value));\n\tcomponent_subscribe($$self, imageSelectionStoredState, value => $$invalidate(76, $imageSelectionStoredState = value));\n\tcomponent_subscribe($$self, imagePreviewUpscale, value => $$invalidate(46, $imagePreviewUpscale = value));\n\n\t// context\n\tconst fixScrollDirectionStore = getContext('fixScrollDirection');\n\n\tcomponent_subscribe($$self, fixScrollDirectionStore, value => $$invalidate(72, $fixScrollDirectionStore = value));\n\n\t// to toggle mouse cursor\n\tlet isPanning = false;\n\n\tlet panOrigin = undefined;\n\tlet zoomOrigin = undefined;\n\tlet isPanningToCenter = undefined;\n\tlet currentDistanceToCenter = undefined;\n\n\tconst shouldStartInteraction = e => {\n\t\t// currently active stage panel\n\t\tconst main = root.querySelector('.PinturaMain > .PinturaUtilMain') || root.querySelector('div[data-inert=\"false\"] .PinturaUtilMain');\n\n\t\t// somehow main not found\n\t\tif (!main) return false;\n\n\t\t// only handle if is interaction in main stage\n\t\tif (!main.contains(e.target)) return false;\n\n\t\t// never on text fields\n\t\tif (isTextField(e.target)) return false;\n\n\t\treturn true;\n\t};\n\n\tconst storePanAndZoom = (options = {}) => {\n\t\tconst { pan = $imageSelectionPan, zoom = $imageSelectionZoom } = options;\n\t\tset_store_value(imageSelectionStoredState, $imageSelectionStoredState = { translation: pan, zoom }, $imageSelectionStoredState);\n\t};\n\n\tconst isImageSelectionPanCentered = () => {\n\t\treturn $imageSelectionPan && $imageSelectionPan.x === 0 && $imageSelectionPan.y === 0;\n\t};\n\n\tconst resetPanToCenter = () => {\n\t\tif (isImageSelectionPanCentered()) return;\n\t\tset_store_value(imageSelectionPan, $imageSelectionPan = vectorCreateEmpty(), $imageSelectionPan);\n\t};\n\n\tconst restorePanAndZoom = () => {\n\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = enableZoom ? $imageSelectionStoredState.zoom : undefined, $imageSelectionZoom);\n\n\t\tset_store_value(\n\t\t\timageSelectionPan,\n\t\t\t$imageSelectionPan = enablePan\n\t\t\t? vectorClone($imageSelectionStoredState.translation)\n\t\t\t: isImageSelectionPanCentered()\n\t\t\t\t? $imageSelectionPan\n\t\t\t\t: vectorCreateEmpty(),\n\t\t\t$imageSelectionPan\n\t\t);\n\n\t\tzoomAdjust.set($imageSelectionZoom);\n\t};\n\n\tconst resetPanAndZoom = () => {\n\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = undefined, $imageSelectionZoom);\n\t\tresetPanToCenter();\n\t\tresetZoomAdjustControl();\n\t};\n\n\t// resets zoom adjust (will be auto updated to latest zoom value when using the dropdown or buttons)\n\tconst resetZoomAdjustControl = () => {\n\t\tzoomAdjust.set(undefined, { hard: true });\n\t};\n\n\tconst snapToCenter = () => {\n\t\tresetPanAndZoom();\n\t\tstorePanAndZoom();\n\t};\n\n\t// this smoothens updates to the zoom level\n\tconst zoomAdjust = spring(undefined, { precision: 0.01 });\n\n\tcomponent_subscribe($$self, zoomAdjust, value => $$invalidate(75, $zoomAdjust = value));\n\n\tconst getImageSelectionPan = (currentTranslation, position, currentZoom, nextZoom) => {\n\t\tconst newTranslation = vectorCreateEmpty();\n\n\t\t// get position so we can zoom to specific area of image\n\t\tconst originSelectionRect = rectClone($imageSelectionRect);\n\n\t\trectScale(originSelectionRect, currentZoom);\n\t\trectTranslate(originSelectionRect, currentTranslation);\n\t\tconst originSelectionRectCenter = rectCenter(originSelectionRect);\n\t\tconst zoomedSelectionRect = rectClone(originSelectionRect);\n\t\trectScale(zoomedSelectionRect, 1 + (nextZoom - currentZoom), position);\n\t\tconst zoomedSelectionRectCenter = rectCenter(zoomedSelectionRect);\n\t\tconst rectTranslation = vectorDivide(vectorSubtract(zoomedSelectionRectCenter, originSelectionRectCenter), currentZoom);\n\t\tvectorUpdate(newTranslation, currentTranslation.x + rectTranslation.x, currentTranslation.y + rectTranslation.y);\n\t\treturn getPanLimitedTranslation(newTranslation, currentZoom);\n\t};\n\n\tzoomAdjust.subscribe(newValue => {\n\t\tconst currentValue = $imageSelectionZoom || $imageSelectionStageFitScalar;\n\n\t\t// stop here\n\t\tif (newValue === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// when zooming out beyond view, we snap image to center of stage\n\t\tif (newValue <= $imageSelectionStageFitScalar) {\n\t\t\tif (!isImageSelectionPanCentered()) {\n\t\t\t\tset_store_value(imageSelectionPan, $imageSelectionPan = vectorCreateEmpty(), $imageSelectionPan);\n\t\t\t}\n\t\t} else // else we zoom towards center of stage (which is the center of the part of the image that is visible)\n\t\t{\n\t\t\tset_store_value(\n\t\t\t\timageSelectionPan,\n\t\t\t\t$imageSelectionPan = getImageSelectionPan(\n\t\t\t\t\t$imageSelectionPan,\n\t\t\t\t\trectCenter({\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 0,\n\t\t\t\t\t\twidth: $stageRect.width,\n\t\t\t\t\t\theight: $stageRect.height\n\t\t\t\t\t}),\n\t\t\t\t\tcurrentValue,\n\t\t\t\t\tnewValue\n\t\t\t\t),\n\t\t\t\t$imageSelectionPan\n\t\t\t);\n\t\t}\n\n\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = newValue, $imageSelectionZoom);\n\t});\n\n\tconst updateZoomAdjust = update => {\n\t\tzoomAdjust.update(\n\t\t\tcurrentValue => {\n\t\t\t\tconst value = currentValue || $imageSelectionZoom || $imageSelectionStageFitScalar;\n\n\t\t\t\tif (currentValue === undefined) {\n\t\t\t\t\tzoomAdjust.set(value, { hard: true });\n\t\t\t\t}\n\n\t\t\t\tconst newValue = update(value);\n\n\t\t\t\t// remember new value\n\t\t\t\tstorePanAndZoom({ zoom: newValue });\n\n\t\t\t\treturn newValue;\n\t\t\t},\n\t\t\t{ hard: !$isAnimated }\n\t\t);\n\t};\n\n\tconst setZoomAdjust = newValue => {\n\t\tif (!newValue) {\n\t\t\tnewValue = undefined;\n\t\t\tzoomAdjust.set(undefined, { hard: true });\n\t\t} else {\n\t\t\t// auto set initial value\n\t\t\tif ($zoomAdjust === undefined) {\n\t\t\t\tzoomAdjust.set($imageSelectionZoom || $imageSelectionStageFitScalar, { hard: true });\n\t\t\t}\n\n\t\t\tzoomAdjust.set(newValue, { hard: $isAnimated === false });\n\t\t}\n\n\t\t// remember\n\t\tstorePanAndZoom({ zoom: newValue });\n\t};\n\n\t// reset zoom on double click\n\tlet lastClickTime;\n\n\tfunction handleDropdownClick() {\n\t\tconst now = Date.now();\n\n\t\t// not a double click\n\t\tif (!isNumber(lastClickTime) || now - lastClickTime > 500) {\n\t\t\tlastClickTime = now;\n\t\t\treturn;\n\t\t}\n\n\t\t// reset double click timer\n\t\tlastClickTime = undefined;\n\n\t\t// check if we should zoom to fit or zoom to actual size\n\t\tif (imageFitsOnStage) {\n\t\t\tif (zoomLevelCurrent === 1) {\n\t\t\t\tsetZoomAdjust($imageSelectionStageFitScalar);\n\t\t\t} else {\n\t\t\t\tsetZoomAdjust(1);\n\t\t\t}\n\t\t} else {\n\t\t\t//\n\t\t\tif (zoomLevelCurrent === $imageSelectionStageFitScalar) {\n\t\t\t\tsetZoomAdjust(1);\n\t\t\t} else {\n\t\t\t\tsetZoomAdjust($imageSelectionStageFitScalar);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst getSelectedZoomLevel = (levels, currentScalar) => levels.findIndex(level => level === currentScalar);\n\n\t//\n\t// interaction\n\t//\n\tconst getPanLimitedTranslation = (pan, zoom) => {\n\t\tconst scalar = imageSelectionRectScalar * zoom;\n\n\t\t// this is the current image centered on the stage which we'll use as drag bounds\n\t\tconst safeRect = { ...imageSelectionRectCentered };\n\n\t\t// apply gutter\n\t\tconst gutterScalar = 1.0 - clamp(panLimitGutterScalar, 0.0, 1.0);\n\n\t\trectScale(safeRect, scalar < gutterScalar ? scalar : gutterScalar);\n\n\t\t// here we need to\n\t\tconst nextRect = { ...imageSelectionRectCentered };\n\n\t\trectScale(nextRect, scalar);\n\t\trectTranslate(nextRect, pan);\n\t\tconst nextRectLimited = { ...nextRect };\n\t\tif (nextRect.x > safeRect.x) nextRectLimited.x = safeRect.x;\n\t\tif (nextRect.y > safeRect.y) nextRectLimited.y = safeRect.y;\n\t\tif (nextRect.x + nextRect.width < safeRect.x + safeRect.width) nextRectLimited.x = safeRect.x + safeRect.width - nextRect.width;\n\t\tif (nextRect.y + nextRect.height < safeRect.y + safeRect.height) nextRectLimited.y = safeRect.y + safeRect.height - nextRect.height;\n\t\treturn vectorSubtract(rectCenter(nextRectLimited), rectCenter(safeRect));\n\t};\n\n\tconst manipulatePan = ({ origin, translation, zoom = 1, elastify = true }) => {\n\t\tif (!origin) return;\n\t\tlet panTranslation = translation;\n\t\tconst nextPan = vectorCreate(origin.x + panTranslation.x, origin.y + panTranslation.y);\n\t\tif (!enablePanLimit) return nextPan;\n\t\tconst nextPanLimited = getPanLimitedTranslation(nextPan, zoom);\n\n\t\treturn elastify\n\t\t? elastifyVectors(nextPanLimited, nextPan, elasticity)\n\t\t: nextPanLimited;\n\t};\n\n\tlet didPan;\n\tlet didMultiTouch;\n\tlet lastDragInteraction;\n\n\tconst handleDragStart = e => {\n\t\tlastDragInteraction = undefined;\n\n\t\t// get position of drag start\n\t\tconst { origin } = e;\n\n\t\tvectorSubtract(vectorSubtract({ ...origin }, $rootRect), $stageRect);\n\n\t\t// set to true so updates aren't animated\n\t\tset_store_value(isInteracting, $isInteracting = true, $isInteracting);\n\n\t\t// set to true so grab cursor is shown\n\t\t$$invalidate(35, isPanning = enablePanInput);\n\n\t\t// did interact with canvas\n\t\tdidPan = false;\n\n\t\t// did zoom with multi-touch\n\t\tdidMultiTouch = false;\n\n\t\t// we need to determine if panning to center so we can snap zoom\n\t\tisPanningToCenter = false;\n\n\t\t// so we can correctly apply drag translation\n\t\tpanOrigin = { ...$imageSelectionPan };\n\n\t\t// so we can correctly apply zoom adjustment\n\t\tzoomOrigin = $imagePreviewUpscale\n\t\t? $imageSelectionZoom || $imageSelectionStageFitScalar\n\t\t: imageFitsOnStage\n\t\t\t? $imageSelectionZoom || 1\n\t\t\t: $imageSelectionZoom || $imageSelectionStageFitScalar;\n\n\t\tzoomPrevious = zoomOrigin;\n\t};\n\n\tlet zoomPrevious;\n\n\tconst handleDrag = e => {\n\t\tconst { position, scalar, translation, isMultiTouching } = e.detail;\n\n\t\tif (isMultiTouching) {\n\t\t\tdidMultiTouch = true;\n\t\t}\n\n\t\tconst stagePosition = vectorSubtract(vectorSubtract({ ...position }, $rootRect), $stageRect);\n\n\t\tif (!panOrigin || !(isMultiTouching || enablePanInput)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// TODO: research why this is needed. this makes movement of image better align with touch,\n\t\t// misalignment problem originates in `interactable`\n\t\t// this \"fix\" works here because we can only multitouch, it doesn't work in crop util because user can switch between single and multi input\n\t\t// if (isMultiTouching) {\n\t\t// vectorMultiply(translation, 0.5);\n\t\t// }\n\t\tif (enablePanInput || isMultiTouching) {\n\t\t\tdidPan = true;\n\t\t}\n\n\t\t// set to true when multiple fingers detected\n\t\tif (!zoomMultiTouching) {\n\t\t\t$$invalidate(14, zoomMultiTouching = isMultiTouching);\n\t\t}\n\n\t\t// next zoom\n\t\tconst nextZoom = canZoom\n\t\t? clamp(zoomOrigin * scalar, zoomMin, zoomMax)\n\t\t: 1;\n\n\t\t// need this info to determine if we're panning to center\n\t\tconst nextPan = manipulatePan({\n\t\t\torigin: panOrigin,\n\t\t\ttranslation,\n\t\t\tzoom: nextZoom,\n\t\t\telastify: true\n\t\t});\n\n\t\t// calculate if is panning to center, we'll look at the result when user is done interacting with the canvas\n\t\tconst nextDistanceToCenter = vectorLength(nextPan);\n\n\t\tconst currentPan = $imageSelectionPan;\n\t\tcurrentDistanceToCenter = vectorLength(currentPan);\n\t\tisPanningToCenter = nextDistanceToCenter < currentDistanceToCenter;\n\n\t\t// assign new pan/zoom values\n\t\tif (canZoom) {\n\t\t\tresetZoomAdjustControl();\n\t\t\timageSelectionZoom.set(nextZoom);\n\t\t}\n\n\t\tif (didMultiTouch) {\n\t\t\t// we're zooming in on a specific part of the image\n\t\t\tset_store_value(imageSelectionPan, $imageSelectionPan = getImageSelectionPan($imageSelectionPan, stagePosition, zoomPrevious, nextZoom), $imageSelectionPan);\n\t\t} else {\n\t\t\t// we're panning\n\t\t\tset_store_value(imageSelectionPan, $imageSelectionPan = nextPan, $imageSelectionPan);\n\t\t}\n\n\t\tlastDragInteraction = zoomMultiTouching && {\n\t\t\ttranslation: e.detail.translation,\n\t\t\tscalar\n\t\t};\n\n\t\tzoomPrevious = nextZoom;\n\t};\n\n\tconst handleDragRelease = e => {\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\t\t$$invalidate(35, isPanning = false);\n\t\t$$invalidate(14, zoomMultiTouching = false);\n\n\t\t// if is panning to center snap to center\n\t\tif (!didMultiTouch && isPanningToCenter && currentDistanceToCenter < 50) {\n\t\t\t// stop drag action\n\t\t\tpanOrigin = undefined;\n\n\t\t\tzoomOrigin = undefined;\n\t\t\timageSelectionPan.set(vectorCreateEmpty());\n\t\t}\n\t};\n\n\tconst handleDragEnd = e => {\n\t\t// done interacting\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t// clean up\n\t\t$$invalidate(35, isPanning = false);\n\n\t\t$$invalidate(14, zoomMultiTouching = false);\n\n\t\t// to make sure interaction is turned off before pan is updated we set it on next tick\n\t\t// this is a bit of a hack.\n\t\t// TODO: look into queueing interaction and ui updates so we can reliably disable/enable isInteracting and then run ui updates so they're properly animated\n\t\tPromise.resolve().then(() => {\n\t\t\tif (didPan && panOrigin) {\n\t\t\t\tif (didMultiTouch) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst interaction = lastDragInteraction || e.detail;\n\n\t\t\t\t// next zoom\n\t\t\t\tconst nextZoom = canZoom\n\t\t\t\t? clamp(zoomOrigin * interaction.scalar, zoomMin, zoomMax)\n\t\t\t\t: 1;\n\n\t\t\t\t// snap back to center if needed\n\t\t\t\tconst nextPan = manipulatePan({\n\t\t\t\t\torigin: panOrigin,\n\t\t\t\t\telastify: false,\n\t\t\t\t\ttranslation: interaction.translation,\n\t\t\t\t\tzoom: nextZoom\n\t\t\t\t});\n\n\t\t\t\timageSelectionPan.set(nextPan);\n\t\t\t}\n\n\t\t\tpanOrigin = undefined;\n\t\t\tzoomOrigin = undefined;\n\n\t\t\t// reset zoom\n\t\t\tif (enablePanInput && e.detail.isDoubleTap) {\n\t\t\t\tsnapToCenter();\n\t\t\t}\n\n\t\t\t// store for future\n\t\t\tstorePanAndZoom();\n\t\t});\n\t};\n\n\t// wheel input\n\tlet lastWheelEventTimestamp = Date.now();\n\n\tlet wheelSnapZoomTimer;\n\tlet wheelFastZoomCounter = 0;\n\tlet wheelFastZoomShouldHandle = false;\n\tlet didSnap = false;\n\n\tconst handleWheel = e => {\n\t\t// determine if wheel position is over image, else ignore\n\t\tif (!shouldStartInteraction(e)) return;\n\n\t\t// don't run default actions, prevent other actions from running\n\t\te.preventDefault();\n\n\t\te.stopPropagation();\n\t\tif (didSnap) return;\n\t\tclearTimeout(wheelSnapZoomTimer);\n\n\t\t// convert wheel delta to scalar\n\t\tconst wheelDelta = getWheelDelta(e, {\n\t\t\tfixScrollDirection: $fixScrollDirectionStore\n\t\t});\n\n\t\t// for determining if fast zooming\n\t\tconst now = Date.now();\n\n\t\tconst wheelInterval = now - lastWheelEventTimestamp;\n\t\tlastWheelEventTimestamp = now;\n\t\tconst isZoomingFast = Math.abs(wheelDelta / wheelInterval) > 0.2;\n\t\twheelFastZoomCounter = isZoomingFast ? wheelFastZoomCounter + 1 : 0;\n\t\tconst delta = wheelDelta * -1 * zoomAdjustWheelFactor;\n\t\tconst scalar = 1 + delta / (isZoomingFast ? 50 : 100);\n\t\tconst stageWheelPosition = getEventPositionInStage(e, $rootRect, $stageRect);\n\n\t\t// update zoom\n\t\tupdateZoom(stageWheelPosition, scalar, { isZoomingFast });\n\t};\n\n\tconst updateZoom = (stagePosition, scalar, { isZoomingFast }) => {\n\t\tconst currentZoom = $imagePreviewUpscale\n\t\t? $imageSelectionZoom || $imageSelectionStageFitScalar\n\t\t: imageFitsOnStage\n\t\t\t? $imageSelectionZoom || 1\n\t\t\t: $imageSelectionZoom || $imageSelectionStageFitScalar;\n\n\t\tconst nextZoom = clamp(currentZoom * scalar, zoomMin, zoomMax);\n\n\t\tconst zoomCenter = $imagePreviewUpscale\n\t\t? $imageSelectionStageFitScalar\n\t\t: imageFitsOnStage ? 1 : $imageSelectionStageFitScalar;\n\n\t\tconst nextZoomDistanceToCenter = Math.abs(nextZoom - zoomCenter);\n\n\t\t// zoom state\n\t\tconst isZoomedIn = currentZoom > zoomCenter;\n\n\t\tconst isZoomedOut = currentZoom < zoomCenter;\n\t\tconst isZoomingIn = nextZoom > currentZoom;\n\t\tconst isZoomingOut = nextZoom < currentZoom;\n\t\tconst isZoomingToCenter = isZoomedIn && isZoomingOut || isZoomedOut && isZoomingIn;\n\t\tconst isZoomingFlick = wheelFastZoomCounter >= 5;\n\n\t\tif (!isZoomingFast) {\n\t\t\twheelFastZoomShouldHandle = false;\n\t\t}\n\n\t\tif (wheelFastZoomCounter > 0 && !wheelFastZoomShouldHandle) {\n\t\t\twheelFastZoomShouldHandle = isZoomingToCenter;\n\t\t}\n\n\t\t// quick snap to place\n\t\tif (isZoomingFlick && wheelFastZoomShouldHandle) {\n\t\t\tsnapToCenter();\n\t\t\tdidSnap = true;\n\n\t\t\tsetTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tdidSnap = false;\n\t\t\t\t},\n\t\t\t\t100\n\t\t\t);\n\n\t\t\treturn;\n\t\t}\n\n\t\t// stop here, if flicks wheel we're not going to handle it\n\t\tif (isZoomingFlick) {\n\t\t\treturn;\n\t\t}\n\n\t\t// snap when positioned very close to center\n\t\tif (!isZoomingFast && isZoomingToCenter && nextZoomDistanceToCenter <= 0.05) {\n\t\t\twheelSnapZoomTimer = setTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tsnapToCenter();\n\t\t\t\t},\n\t\t\t\t250\n\t\t\t);\n\t\t}\n\n\t\t// update zoom\n\t\tresetZoomAdjustControl();\n\n\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = clamp(nextZoom, zoomMin, zoomMax), $imageSelectionZoom);\n\t\tset_store_value(imageSelectionPan, $imageSelectionPan = getImageSelectionPan($imageSelectionPan, stagePosition, currentZoom, nextZoom), $imageSelectionPan);\n\n\t\t// store for future\n\t\tstorePanAndZoom();\n\t};\n\n\t// toggle listeners\n\tconst getListenerFunction = enable => {\n\t\treturn (enable ? 'add' : 'remove') + 'EventListener';\n\t};\n\n\tlet gestureZoomOffset;\n\tlet gesturePanOffset;\n\tlet gestureStagePosition;\n\tlet gestureSelectionRect;\n\n\tconst handleGestureStart = e => {\n\t\te.preventDefault();\n\n\t\t// so we can correctly apply drag translation\n\t\tgesturePanOffset = { ...$imageSelectionPan };\n\n\t\tgestureSelectionRect = rectClone($imageSelectionRect);\n\t\tgestureStagePosition = getEventPositionInStage(e, $rootRect, $stageRect);\n\n\t\tgestureZoomOffset = $imagePreviewUpscale\n\t\t? $imageSelectionZoom || $imageSelectionStageFitScalar\n\t\t: imageFitsOnStage\n\t\t\t? $imageSelectionZoom || 1\n\t\t\t: $imageSelectionZoom || $imageSelectionStageFitScalar;\n\t};\n\n\tconst handleGesture = e => {\n\t\te.preventDefault();\n\t\tresetZoomAdjustControl();\n\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = clamp(e.scale * gestureZoomOffset, zoomMin, zoomMax), $imageSelectionZoom);\n\t\tconst originSelectionRect = rectClone(gestureSelectionRect);\n\t\trectScale(originSelectionRect, gestureZoomOffset);\n\t\trectTranslate(originSelectionRect, gesturePanOffset);\n\t\tconst originSelectionRectCenter = rectCenter(originSelectionRect);\n\t\tconst zoomedSelectionRect = rectClone(originSelectionRect);\n\t\trectScale(zoomedSelectionRect, 1 + ($imageSelectionZoom - gestureZoomOffset), gestureStagePosition);\n\t\tconst zoomedSelectionRectCenter = rectCenter(zoomedSelectionRect);\n\t\tconst rectTranslation = vectorDivide(vectorSubtract(zoomedSelectionRectCenter, originSelectionRectCenter), gestureZoomOffset);\n\n\t\tconst pan = {\n\t\t\tx: gesturePanOffset.x + rectTranslation.x,\n\t\t\ty: gesturePanOffset.y + rectTranslation.y\n\t\t};\n\n\t\tset_store_value(imageSelectionPan, $imageSelectionPan = getPanLimitedTranslation(pan, $imageSelectionZoom), $imageSelectionPan);\n\t};\n\n\tconst handleGestureEnd = e => {\n\t\te.preventDefault();\n\t};\n\n\tconst toggleZoomInput = enable => {\n\t\t// wheel zooming\n\t\troot[getListenerFunction(enable)]('wheel', handleWheel);\n\n\t\t// macos touchpad zooming, not on iOS as will conflict with handling of multitouch pointer events\n\t\tif (isIOS()) return;\n\n\t\troot[getListenerFunction(enable)]('gesturestart', handleGestureStart);\n\t\troot[getListenerFunction(enable)]('gesturechange', handleGesture);\n\t\troot[getListenerFunction(enable)]('gestureend', handleGestureEnd);\n\t};\n\n\tconst togglePanInput = enable => {\n\t\tconst fn = getListenerFunction(enable);\n\t\troot[fn]('interactionstart', handleDragStart);\n\t\troot[fn]('interactionupdate', handleDrag);\n\t\troot[fn]('interactionrelease', handleDragRelease);\n\t\troot[fn]('interactionend', handleDragEnd);\n\t};\n\n\t// mount & destroy\n\tlet interactableInstance;\n\n\tonMount(() => {\n\t\tinteractableInstance = interactable(root, {\n\t\t\tdrag: true,\n\t\t\tpinch: true,\n\t\t\tinertia: true,\n\t\t\tinertiaDurationMultiplier: 10,\n\t\t\tshouldStartInteraction\n\t\t});\n\t});\n\n\tonDestroy(() => {\n\t\ttoggleZoomInput(false);\n\t\ttogglePanInput(false);\n\t\tinteractableInstance.destroy();\n\t\tinteractableInstance = undefined;\n\t});\n\n\t$$self.$$set = $$props => {\n\t\tif ('root' in $$props) $$invalidate(15, root = $$props.root);\n\t\tif ('locale' in $$props) $$invalidate(16, locale = $$props.locale);\n\t\tif ('stores' in $$props) $$invalidate(17, stores = $$props.stores);\n\t\tif ('isAnimated' in $$props) $$subscribe_isAnimated($$invalidate(0, isAnimated = $$props.isAnimated));\n\t\tif ('allowPan' in $$props) $$invalidate(18, allowPan = $$props.allowPan);\n\t\tif ('allowZoom' in $$props) $$invalidate(19, allowZoom = $$props.allowZoom);\n\t\tif ('enablePan' in $$props) $$invalidate(20, enablePan = $$props.enablePan);\n\t\tif ('enableZoom' in $$props) $$invalidate(21, enableZoom = $$props.enableZoom);\n\t\tif ('enableZoomControls' in $$props) $$invalidate(22, enableZoomControls = $$props.enableZoomControls);\n\t\tif ('enableZoomInput' in $$props) $$invalidate(23, enableZoomInput = $$props.enableZoomInput);\n\t\tif ('enablePanInput' in $$props) $$invalidate(24, enablePanInput = $$props.enablePanInput);\n\t\tif ('enablePanLimit' in $$props) $$invalidate(25, enablePanLimit = $$props.enablePanLimit);\n\t\tif ('panLimitGutterScalar' in $$props) $$invalidate(26, panLimitGutterScalar = $$props.panLimitGutterScalar);\n\t\tif ('zoomOptions' in $$props) $$invalidate(27, zoomOptions = $$props.zoomOptions);\n\t\tif ('zoomAdjustStep' in $$props) $$invalidate(28, zoomAdjustStep = $$props.zoomAdjustStep);\n\t\tif ('zoomAdjustFactor' in $$props) $$invalidate(29, zoomAdjustFactor = $$props.zoomAdjustFactor);\n\t\tif ('zoomAdjustWheelFactor' in $$props) $$invalidate(30, zoomAdjustWheelFactor = $$props.zoomAdjustWheelFactor);\n\t\tif ('elasticity' in $$props) $$invalidate(31, elasticity = $$props.elasticity);\n\t\tif ('imageSelectionRectCentered' in $$props) $$invalidate(32, imageSelectionRectCentered = $$props.imageSelectionRectCentered);\n\t\tif ('imageSelectionRectScalar' in $$props) $$invalidate(33, imageSelectionRectScalar = $$props.imageSelectionRectScalar);\n\t\tif ('zoomLevel' in $$props) $$invalidate(34, zoomLevel = $$props.zoomLevel);\n\t\tif ('zoomControls' in $$props) $$invalidate(13, zoomControls = $$props.zoomControls);\n\t\tif ('zoomMultiTouching' in $$props) $$invalidate(14, zoomMultiTouching = $$props.zoomMultiTouching);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*allowZoom, enableZoom, enableZoomInput*/ 11010048) {\n\t\t\t$$invalidate(37, canZoom = allowZoom && enableZoom && enableZoomInput);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*allowPan, enablePan*/ 1310720) {\n\t\t\t$$invalidate(36, canPan = allowPan && enablePan);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*allowPan, allowZoom*/ 786432) {\n\t\t\t// restore when becomes active\n\t\t\tallowPan || allowZoom\n\t\t\t? restorePanAndZoom()\n\t\t\t: resetPanAndZoom();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$stageScalar*/ 65536) {\n\t\t\timageFitsOnStage = $stageScalar >= 1;\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale, zoomOptions*/ 134283264 | $$self.$$.dirty[1] & /*$imagePreviewUpscale, $stageScalar, $imageSelectionStageFitScalar*/ 114688) {\n\t\t\t// the list of zoom levels\n\t\t\t$$invalidate(41, zoomLevels = [\n\t\t\t\t// zoom level need to fit to view\n\t\t\t\t($imagePreviewUpscale || $stageScalar < 1) && [\n\t\t\t\t\t$imageSelectionStageFitScalar,\n\t\t\t\t\ttoPercentageNumber($imageSelectionStageFitScalar) + '%',\n\t\t\t\t\t{ sublabel: locale.labelZoomFit }\n\t\t\t\t],\n\t\t\t\t// custom zoom levels\n\t\t\t\t...zoomOptions.map(value => [value, toPercentageNumber(value) + '%'])\n\t\t\t].filter(Boolean).map(level => {\n\t\t\t\tif (level[0] === 1) level[2] = { sublabel: locale.labelZoomActual };\n\t\t\t\treturn level;\n\t\t\t}).sort((a, b) => {\n\t\t\t\tconst av = a[0] || $imageSelectionStageFitScalar;\n\t\t\t\tconst bv = b[0] || $imageSelectionStageFitScalar;\n\t\t\t\tif (av < bv) return -1;\n\t\t\t\tif (bv < av) return 1;\n\t\t\t\treturn 0;\n\t\t\t}));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*zoomLevels, $imageSelectionStageFitScalar*/ 17408) {\n\t\t\t$$invalidate(39, zoomMin = Math.min(zoomLevels.reduce((min, [level]) => level < min ? level : min, Number.MAX_SAFE_INTEGER), $imageSelectionStageFitScalar));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*zoomLevels*/ 1024) {\n\t\t\t$$invalidate(38, zoomMax = zoomLevels.reduce((max, [level]) => level > max ? level : max, Number.MIN_SAFE_INTEGER));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*zoomLevel*/ 8) {\n\t\t\tzoomLevel !== null && setZoomAdjust(zoomLevel);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageSelectionZoom, $imagePreviewUpscale, $stageScalar, $imageSelectionStageFitScalar*/ 122880) {\n\t\t\t$$invalidate(43, zoomLevelCurrent = $imageSelectionZoom\n\t\t\t? $imageSelectionZoom\n\t\t\t: $imagePreviewUpscale || $stageScalar < 1\n\t\t\t\t? $imageSelectionStageFitScalar\n\t\t\t\t: 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*zoomLevels, zoomLevelCurrent*/ 5120) {\n\t\t\t$$invalidate(40, zoomLevelSelectedIndex = getSelectedZoomLevel(zoomLevels.map(([level]) => level), zoomLevelCurrent));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*zoomLevelCurrent*/ 4096) {\n\t\t\t$$invalidate(42, zoomLevelLabel = toPercentageNumber(zoomLevelCurrent) + '%');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*allowZoom, enableZoomControls, locale, zoomAdjustStep, zoomAdjustFactor*/ 810090496 | $$self.$$.dirty[1] & /*$imageSelectionZoom, zoomMin, zoomLevelLabel, zoomLevels, zoomLevelSelectedIndex, zoomMax*/ 12160) {\n\t\t\t$$invalidate(13, zoomControls = (allowZoom || allowZoom) && enableZoomControls\n\t\t\t? [\n\t\t\t\t\t[\n\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t'zoom-out',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thideLabel: true,\n\t\t\t\t\t\t\tlabel: locale.labelZoomOut,\n\t\t\t\t\t\t\ticon: locale.iconZoomOut,\n\t\t\t\t\t\t\tdisabled: $imageSelectionZoom === zoomMin,\n\t\t\t\t\t\t\tonclick: () => updateZoomAdjust(value => Math.max(zoomMin, value - zoomAdjustStep)),\n\t\t\t\t\t\t\tonhold: () => updateZoomAdjust(value => Math.max(zoomMin, value * (1 - zoomAdjustFactor)))\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t'Dropdown',\n\t\t\t\t\t\t'zoom-level',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: zoomLevelLabel,\n\t\t\t\t\t\t\ttitle: locale.labelZoom,\n\t\t\t\t\t\t\tlabelClass: 'PinturaFixedWidthCharacters',\n\t\t\t\t\t\t\toptions: zoomLevels,\n\t\t\t\t\t\t\tselectedIndex: zoomLevelSelectedIndex,\n\t\t\t\t\t\t\tonchange: item => setZoomAdjust(item.value),\n\t\t\t\t\t\t\tonclick: handleDropdownClick\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t'zoom-in',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thideLabel: true,\n\t\t\t\t\t\t\tlabel: locale.labelZoomIn,\n\t\t\t\t\t\t\ticon: locale.iconZoomIn,\n\t\t\t\t\t\t\tdisabled: $imageSelectionZoom === zoomMax,\n\t\t\t\t\t\t\tonclick: () => updateZoomAdjust(value => Math.min(zoomMax, value + zoomAdjustStep)),\n\t\t\t\t\t\t\tonhold: () => updateZoomAdjust(value => Math.min(zoomMax, value * (1 + zoomAdjustFactor)))\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t]\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 32768 | $$self.$$.dirty[1] & /*canZoom*/ 64) {\n\t\t\troot && toggleZoomInput(canZoom);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 32768 | $$self.$$.dirty[1] & /*canPan*/ 32) {\n\t\t\troot && togglePanInput(canPan);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root, enablePanInput*/ 16809984 | $$self.$$.dirty[1] & /*canPan, isPanning*/ 48) {\n\t\t\troot && root.style.setProperty('--cursor', canPan && enablePanInput\n\t\t\t? isPanning ? 'grabbing' : 'grab'\n\t\t\t: '');\n\t\t}\n\t};\n\n\treturn [\n\t\tisAnimated,\n\t\tisInteracting,\n\t\trootRect,\n\t\tstageRect,\n\t\tstageScalar,\n\t\timageSelectionPan,\n\t\timageSelectionZoom,\n\t\timageSelectionStageFitScalar,\n\t\timageSelectionRect,\n\t\timageSelectionStoredState,\n\t\timagePreviewUpscale,\n\t\tfixScrollDirectionStore,\n\t\tzoomAdjust,\n\t\tzoomControls,\n\t\tzoomMultiTouching,\n\t\troot,\n\t\tlocale,\n\t\tstores,\n\t\tallowPan,\n\t\tallowZoom,\n\t\tenablePan,\n\t\tenableZoom,\n\t\tenableZoomControls,\n\t\tenableZoomInput,\n\t\tenablePanInput,\n\t\tenablePanLimit,\n\t\tpanLimitGutterScalar,\n\t\tzoomOptions,\n\t\tzoomAdjustStep,\n\t\tzoomAdjustFactor,\n\t\tzoomAdjustWheelFactor,\n\t\telasticity,\n\t\timageSelectionRectCentered,\n\t\timageSelectionRectScalar,\n\t\tzoomLevel,\n\t\tisPanning,\n\t\tcanPan,\n\t\tcanZoom,\n\t\tzoomMax,\n\t\tzoomMin,\n\t\tzoomLevelSelectedIndex,\n\t\tzoomLevels,\n\t\tzoomLevelLabel,\n\t\tzoomLevelCurrent,\n\t\t$imageSelectionZoom,\n\t\t$imageSelectionStageFitScalar,\n\t\t$imagePreviewUpscale,\n\t\t$stageScalar\n\t];\n}\n\nclass CanvasPanAndZoom extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$t,\n\t\t\tnull,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\troot: 15,\n\t\t\t\tlocale: 16,\n\t\t\t\tstores: 17,\n\t\t\t\tisAnimated: 0,\n\t\t\t\tallowPan: 18,\n\t\t\t\tallowZoom: 19,\n\t\t\t\tenablePan: 20,\n\t\t\t\tenableZoom: 21,\n\t\t\t\tenableZoomControls: 22,\n\t\t\t\tenableZoomInput: 23,\n\t\t\t\tenablePanInput: 24,\n\t\t\t\tenablePanLimit: 25,\n\t\t\t\tpanLimitGutterScalar: 26,\n\t\t\t\tzoomOptions: 27,\n\t\t\t\tzoomAdjustStep: 28,\n\t\t\t\tzoomAdjustFactor: 29,\n\t\t\t\tzoomAdjustWheelFactor: 30,\n\t\t\t\telasticity: 31,\n\t\t\t\timageSelectionRectCentered: 32,\n\t\t\t\timageSelectionRectScalar: 33,\n\t\t\t\tzoomLevel: 34,\n\t\t\t\tzoomControls: 13,\n\t\t\t\tzoomMultiTouching: 14\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1, -1]\n\t\t);\n\t}\n}\n\n/* src/core/ui/index.svelte generated by Svelte v4.2.20 */\n\nconst { window: window_1$1 } = globals;\n\nfunction create_if_block_2$7(ctx) {\n\tlet t;\n\tlet if_block1_anchor;\n\tlet current;\n\tlet if_block0 = /*isStatusVisible*/ ctx[41] && create_if_block_8$1(ctx);\n\tlet if_block1 = /*isReady*/ ctx[38] && create_if_block_3$4(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*isStatusVisible*/ ctx[41]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*isStatusVisible*/ 1024) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_8$1(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*isReady*/ ctx[38]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*isReady*/ 128) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_3$4(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(if_block1_anchor.parentNode, if_block1_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (3988:8) {#if isStatusVisible}\nfunction create_if_block_8$1(ctx) {\n\tlet div;\n\tlet p;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet current;\n\tconst if_block_creators = [create_if_block_9$1, create_if_block_10$1];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*isSupportsError*/ ctx[39]) return 0;\n\t\tif (/*statusState*/ ctx[35]) return 1;\n\t\treturn -1;\n\t}\n\n\tif (~(current_block_type_index = select_block_type(ctx))) {\n\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tp = element(\"p\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tset_style(p, \"transform\", /*statusTransform*/ ctx[72]);\n\t\t\tattr(div, \"class\", \"PinturaStatus\");\n\t\t\tset_style(div, \"opacity\", /*$statusOpacity*/ ctx[54]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, p);\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].m(p, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tgroup_outros();\n\n\t\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\t\tif (!if_block) {\n\t\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\t\tif_block.c();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t\t}\n\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(p, null);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (dirty[2] & /*statusTransform*/ 1024) {\n\t\t\t\tset_style(p, \"transform\", /*statusTransform*/ ctx[72]);\n\t\t\t}\n\n\t\t\tif (dirty[1] & /*$statusOpacity*/ 8388608) {\n\t\t\t\tset_style(div, \"opacity\", /*$statusOpacity*/ ctx[54]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].d();\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (4001:42) \nfunction create_if_block_10$1(ctx) {\n\tlet statusmessage;\n\tlet t0;\n\tlet t1;\n\tlet if_block1_anchor;\n\tlet current;\n\n\tstatusmessage = new StatusMessage({\n\t\t\tprops: {\n\t\t\t\ttext: /*statusState*/ ctx[35].text || '',\n\t\t\t\tonmeasure: /*offsetAside*/ ctx[222]\n\t\t\t}\n\t\t});\n\n\tlet if_block0 = /*statusState*/ ctx[35].aside && create_if_block_12(ctx);\n\tlet if_block1 = /*statusState*/ ctx[35].icon && create_if_block_11$1(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(statusmessage.$$.fragment);\n\t\t\tt0 = space();\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(statusmessage, target, anchor);\n\t\t\tinsert(target, t0, anchor);\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst statusmessage_changes = {};\n\t\t\tif (dirty[1] & /*statusState*/ 16) statusmessage_changes.text = /*statusState*/ ctx[35].text || '';\n\t\t\tstatusmessage.$set(statusmessage_changes);\n\n\t\t\tif (/*statusState*/ ctx[35].aside) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*statusState*/ 16) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_12(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t1.parentNode, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*statusState*/ ctx[35].icon) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*statusState*/ 16) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_11$1(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(if_block1_anchor.parentNode, if_block1_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(statusmessage.$$.fragment, local);\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(statusmessage.$$.fragment, local);\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(t1);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tdestroy_component(statusmessage, detaching);\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (3991:20) {#if isSupportsError}\nfunction create_if_block_9$1(ctx) {\n\tlet statusmessage;\n\tlet t;\n\tlet statusaside;\n\tlet current;\n\n\tstatusmessage = new StatusMessage({\n\t\t\tprops: {\n\t\t\t\ttext: /*isSupportsError*/ ctx[39],\n\t\t\t\tonmeasure: /*offsetAside*/ ctx[222]\n\t\t\t}\n\t\t});\n\n\tstatusaside = new StatusAside({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaStatusIcon\",\n\t\t\t\toffset: /*$asideOffset*/ ctx[82],\n\t\t\t\topacity: /*$asideOpacity*/ ctx[83],\n\t\t\t\t$$slots: { default: [create_default_slot_5$1] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(statusmessage.$$.fragment);\n\t\t\tt = space();\n\t\t\tcreate_component(statusaside.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(statusmessage, target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tmount_component(statusaside, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst statusmessage_changes = {};\n\t\t\tif (dirty[1] & /*isSupportsError*/ 256) statusmessage_changes.text = /*isSupportsError*/ ctx[39];\n\t\t\tstatusmessage.$set(statusmessage_changes);\n\t\t\tconst statusaside_changes = {};\n\t\t\tif (dirty[2] & /*$asideOffset*/ 1048576) statusaside_changes.offset = /*$asideOffset*/ ctx[82];\n\t\t\tif (dirty[2] & /*$asideOpacity*/ 2097152) statusaside_changes.opacity = /*$asideOpacity*/ ctx[83];\n\n\t\t\tif (dirty[0] & /*locale*/ 8 | dirty[20] & /*$$scope*/ 16) {\n\t\t\t\tstatusaside_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tstatusaside.$set(statusaside_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(statusmessage.$$.fragment, local);\n\t\t\ttransition_in(statusaside.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(statusmessage.$$.fragment, local);\n\t\t\ttransition_out(statusaside.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t}\n\n\t\t\tdestroy_component(statusmessage, detaching);\n\t\t\tdestroy_component(statusaside, detaching);\n\t\t}\n\t};\n}\n\n// (4004:24) {#if statusState.aside}\nfunction create_if_block_12(ctx) {\n\tlet statusaside;\n\tlet current;\n\n\tstatusaside = new StatusAside({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaStatusButton\",\n\t\t\t\toffset: /*$asideOffset*/ ctx[82],\n\t\t\t\topacity: /*$asideOpacity*/ ctx[83],\n\t\t\t\t$$slots: { default: [create_default_slot_9] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(statusaside.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(statusaside, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst statusaside_changes = {};\n\t\t\tif (dirty[2] & /*$asideOffset*/ 1048576) statusaside_changes.offset = /*$asideOffset*/ ctx[82];\n\t\t\tif (dirty[2] & /*$asideOpacity*/ 2097152) statusaside_changes.opacity = /*$asideOpacity*/ ctx[83];\n\n\t\t\tif (dirty[1] & /*statusState*/ 16 | dirty[20] & /*$$scope*/ 16) {\n\t\t\t\tstatusaside_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tstatusaside.$set(statusaside_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(statusaside.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(statusaside.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(statusaside, detaching);\n\t\t}\n\t};\n}\n\n// (4010:32) {#if statusState.progressIndicator.visible}\nfunction create_if_block_14(ctx) {\n\tlet progressindicator;\n\tlet current;\n\n\tprogressindicator = new ProgressIndicator({\n\t\t\tprops: {\n\t\t\t\tprogress: /*statusState*/ ctx[35].progressIndicator.progress\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(progressindicator.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(progressindicator, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst progressindicator_changes = {};\n\t\t\tif (dirty[1] & /*statusState*/ 16) progressindicator_changes.progress = /*statusState*/ ctx[35].progressIndicator.progress;\n\t\t\tprogressindicator.$set(progressindicator_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(progressindicator.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(progressindicator.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(progressindicator, detaching);\n\t\t}\n\t};\n}\n\n// (4016:32) {#if statusState.closeButton && statusState.text}\nfunction create_if_block_13(ctx) {\n\tlet button;\n\tlet current;\n\tconst button_spread_levels = [/*statusState*/ ctx[35].closeButton, { hideLabel: true }];\n\tlet button_props = {};\n\n\tfor (let i = 0; i < button_spread_levels.length; i += 1) {\n\t\tbutton_props = assign(button_props, button_spread_levels[i]);\n\t}\n\n\tbutton = new Button({ props: button_props });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(button.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(button, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst button_changes = (dirty[1] & /*statusState*/ 16)\n\t\t\t? get_spread_update(button_spread_levels, [\n\t\t\t\t\tget_spread_object(/*statusState*/ ctx[35].closeButton),\n\t\t\t\t\tbutton_spread_levels[1]\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tbutton.$set(button_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(button, detaching);\n\t\t}\n\t};\n}\n\n// (4005:28) <StatusAside                                 class=\"PinturaStatusButton\"                                 offset={$asideOffset}                                 opacity={$asideOpacity}                             >\nfunction create_default_slot_9(ctx) {\n\tlet t;\n\tlet if_block1_anchor;\n\tlet current;\n\tlet if_block0 = /*statusState*/ ctx[35].progressIndicator.visible && create_if_block_14(ctx);\n\tlet if_block1 = /*statusState*/ ctx[35].closeButton && /*statusState*/ ctx[35].text && create_if_block_13(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*statusState*/ ctx[35].progressIndicator.visible) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*statusState*/ 16) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_14(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*statusState*/ ctx[35].closeButton && /*statusState*/ ctx[35].text) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*statusState*/ 16) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_13(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(if_block1_anchor.parentNode, if_block1_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (4022:24) {#if statusState.icon}\nfunction create_if_block_11$1(ctx) {\n\tlet statusaside;\n\tlet current;\n\n\tstatusaside = new StatusAside({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaStatusIcon\",\n\t\t\t\toffset: /*$asideOffset*/ ctx[82],\n\t\t\t\topacity: /*$asideOpacity*/ ctx[83],\n\t\t\t\t$$slots: { default: [create_default_slot_7] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(statusaside.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(statusaside, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst statusaside_changes = {};\n\t\t\tif (dirty[2] & /*$asideOffset*/ 1048576) statusaside_changes.offset = /*$asideOffset*/ ctx[82];\n\t\t\tif (dirty[2] & /*$asideOpacity*/ 2097152) statusaside_changes.opacity = /*$asideOpacity*/ ctx[83];\n\n\t\t\tif (dirty[1] & /*statusState*/ 16 | dirty[20] & /*$$scope*/ 16) {\n\t\t\t\tstatusaside_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tstatusaside.$set(statusaside_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(statusaside.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(statusaside.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(statusaside, detaching);\n\t\t}\n\t};\n}\n\n// (4028:32) <Icon>\nfunction create_default_slot_8(ctx) {\n\tlet g;\n\tlet raw_value = /*statusState*/ ctx[35].icon + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*statusState*/ 16 && raw_value !== (raw_value = /*statusState*/ ctx[35].icon + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (4023:28) <StatusAside                                 class=\"PinturaStatusIcon\"                                 offset={$asideOffset}                                 opacity={$asideOpacity}                             >\nfunction create_default_slot_7(ctx) {\n\tlet icon;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_8] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty[1] & /*statusState*/ 16 | dirty[20] & /*$$scope*/ 16) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (3999:28) <Icon>\nfunction create_default_slot_6(ctx) {\n\tlet g;\n\tlet raw_value = /*locale*/ ctx[3].iconSupportError + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*locale*/ 8 && raw_value !== (raw_value = /*locale*/ ctx[3].iconSupportError + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (3994:24) <StatusAside                             class=\"PinturaStatusIcon\"                             offset={$asideOffset}                             opacity={$asideOpacity}                         >\nfunction create_default_slot_5$1(ctx) {\n\tlet icon;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_6] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty[0] & /*locale*/ 8 | dirty[20] & /*$$scope*/ 16) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (4036:8) {#if isReady}\nfunction create_if_block_3$4(ctx) {\n\tlet t0;\n\tlet t1;\n\tlet current_block_type_index;\n\tlet if_block2;\n\tlet t2;\n\tlet canvas;\n\tlet t3;\n\tlet div;\n\tlet t4;\n\tlet canvaspanandzoom;\n\tlet updating_zoomLevel;\n\tlet updating_zoomControls;\n\tlet updating_zoomMultiTouching;\n\tlet current;\n\tlet if_block0 = /*enableToolbar*/ ctx[10] && create_if_block_7$1(ctx);\n\tlet if_block1 = /*shouldRenderTabs*/ ctx[46] && /*showUtils*/ ctx[45] && create_if_block_5$3(ctx);\n\tconst if_block_creators = [create_if_block_4$4, create_else_block$5];\n\tconst if_blocks = [];\n\n\tfunction select_block_type_2(ctx, dirty) {\n\t\tif (/*shouldRenderTabs*/ ctx[46]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type_2(ctx);\n\n\tif_block2 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\tcanvas = new Canvas({\n\t\t\tprops: {\n\t\t\t\tonerror: /*handleCanvasError*/ ctx[215],\n\t\t\t\tisAnimated: /*$isAnimated*/ ctx[53],\n\t\t\t\tisTransparent: /*enableCanvasAlpha*/ ctx[20],\n\t\t\t\tpixelRatio: /*$pixelRatio*/ ctx[57],\n\t\t\t\ttextPixelRatio: /*previewImageTextPixelRatio*/ ctx[6],\n\t\t\t\tbackgroundColor: /*$rootBackgroundColor*/ ctx[56],\n\t\t\t\tmaskRect: /*$imageSelectionRectPresentation*/ ctx[58],\n\t\t\t\tmaskOpacity: /*imageCanvasState*/ ctx[73]\n\t\t\t\t? /*imageCanvasState*/ ctx[73].maskOpacity\n\t\t\t\t: 1,\n\t\t\t\tmaskMarkupOpacity: /*markupMaskOpacity*/ ctx[7],\n\t\t\t\tmaskFrameOpacity: /*previewMaskOpacity*/ ctx[5],\n\t\t\t\tclipAnnotationsToImage: /*$imageCropLimitToImage*/ ctx[85],\n\t\t\t\timages: /*$activeImages*/ ctx[55],\n\t\t\t\tinterfaceImages: /*$interfaceImages*/ ctx[86],\n\t\t\t\tloadImageData: /*imageSourceToImageData*/ ctx[28],\n\t\t\t\tenableGrid: /*enableTransparencyGrid*/ ctx[11],\n\t\t\t\tgridSize: /*$gridSize*/ ctx[87],\n\t\t\t\tgridColors: [/*$gridColorEven*/ ctx[88], /*$gridColorOdd*/ ctx[89]],\n\t\t\t\tgridOpacity: /*$gridOpacity*/ ctx[90],\n\t\t\t\tselectionColor: /*$rootColorPrimary*/ ctx[91],\n\t\t\t\tcsp: /*$csp*/ ctx[92] || {},\n\t\t\t\twillRequest: /*$willRequest*/ ctx[81] || /*$willRequestResource*/ ctx[93],\n\t\t\t\twillRender: /*func*/ ctx[446],\n\t\t\t\tdidRender: /*func_1*/ ctx[447]\n\t\t\t}\n\t\t});\n\n\tfunction canvaspanandzoom_zoomLevel_binding(value) {\n\t\t/*canvaspanandzoom_zoomLevel_binding*/ ctx[449](value);\n\t}\n\n\tfunction canvaspanandzoom_zoomControls_binding(value) {\n\t\t/*canvaspanandzoom_zoomControls_binding*/ ctx[450](value);\n\t}\n\n\tfunction canvaspanandzoom_zoomMultiTouching_binding(value) {\n\t\t/*canvaspanandzoom_zoomMultiTouching_binding*/ ctx[451](value);\n\t}\n\n\tlet canvaspanandzoom_props = {\n\t\troot: /*root*/ ctx[2],\n\t\tlocale: /*locale*/ ctx[3],\n\t\tisAnimated: /*isAnimated*/ ctx[163],\n\t\tstores: /*utilStores*/ ctx[202],\n\t\tallowPan: /*$allowPan*/ ctx[95],\n\t\tenablePan: /*enablePan*/ ctx[17],\n\t\tenablePanLimit: /*enablePanLimit*/ ctx[21],\n\t\tpanLimitGutterScalar: /*panLimitGutterScalar*/ ctx[22],\n\t\tenablePanInput: /*$enablePanInputStatus*/ ctx[96],\n\t\tallowZoom: /*$allowZoom*/ ctx[97],\n\t\tenableZoom: /*enableZoom*/ ctx[18],\n\t\tenableZoomInput: /*enableZoomInput*/ ctx[19] !== undefined\n\t\t? /*enableZoomInput*/ ctx[19]\n\t\t: /*$enableZoomInputStore*/ ctx[98],\n\t\tenableZoomControls: /*$enableZoomControlsProp*/ ctx[99],\n\t\tzoomOptions: /*markupEditorZoomLevels*/ ctx[13] || /*zoomPresetOptions*/ ctx[23],\n\t\tzoomAdjustStep: /*markupEditorZoomAdjustStep*/ ctx[14] || /*zoomAdjustStep*/ ctx[24],\n\t\tzoomAdjustFactor: /*markupEditorZoomAdjustFactor*/ ctx[15] || /*zoomAdjustFactor*/ ctx[25],\n\t\tzoomAdjustWheelFactor: /*markupEditorZoomAdjustWheelFactor*/ ctx[16] || /*zoomAdjustWheelFactor*/ ctx[26],\n\t\timageSelectionRectCentered: /*$imageSelectionRectCentered*/ ctx[100],\n\t\timageSelectionRectScalar: /*$imageSelectionRectScalar*/ ctx[101],\n\t\telasticity: imageSelectionRectElasticity * /*elasticityMultiplier*/ ctx[8]\n\t};\n\n\tif (/*zoomLevel*/ ctx[0] !== void 0) {\n\t\tcanvaspanandzoom_props.zoomLevel = /*zoomLevel*/ ctx[0];\n\t}\n\n\tif (/*zoomControls*/ ctx[33] !== void 0) {\n\t\tcanvaspanandzoom_props.zoomControls = /*zoomControls*/ ctx[33];\n\t}\n\n\tif (/*zoomMultiTouching*/ ctx[34] !== void 0) {\n\t\tcanvaspanandzoom_props.zoomMultiTouching = /*zoomMultiTouching*/ ctx[34];\n\t}\n\n\tcanvaspanandzoom = new CanvasPanAndZoom({ props: canvaspanandzoom_props });\n\tbinding_callbacks.push(() => bind(canvaspanandzoom, 'zoomLevel', canvaspanandzoom_zoomLevel_binding));\n\tbinding_callbacks.push(() => bind(canvaspanandzoom, 'zoomControls', canvaspanandzoom_zoomControls_binding));\n\tbinding_callbacks.push(() => bind(canvaspanandzoom, 'zoomMultiTouching', canvaspanandzoom_zoomMultiTouching_binding));\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt1 = space();\n\t\t\tif_block2.c();\n\t\t\tt2 = space();\n\t\t\tcreate_component(canvas.$$.fragment);\n\t\t\tt3 = space();\n\t\t\tdiv = element(\"div\");\n\t\t\tt4 = space();\n\t\t\tcreate_component(canvaspanandzoom.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaRootPortal\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t0, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\tinsert(target, t2, anchor);\n\t\t\tmount_component(canvas, target, anchor);\n\t\t\tinsert(target, t3, anchor);\n\t\t\tinsert(target, div, anchor);\n\t\t\t/*div_binding*/ ctx[448](div);\n\t\t\tinsert(target, t4, anchor);\n\t\t\tmount_component(canvaspanandzoom, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*enableToolbar*/ ctx[10]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*enableToolbar*/ 1024) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_7$1(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t0.parentNode, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*shouldRenderTabs*/ ctx[46] && /*showUtils*/ ctx[45]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*shouldRenderTabs, showUtils*/ 49152) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_5$3(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(t1.parentNode, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type_2(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block2 = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block2) {\n\t\t\t\t\tif_block2 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block2.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block2.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block2, 1);\n\t\t\t\tif_block2.m(t2.parentNode, t2);\n\t\t\t}\n\n\t\t\tconst canvas_changes = {};\n\t\t\tif (dirty[1] & /*$isAnimated*/ 4194304) canvas_changes.isAnimated = /*$isAnimated*/ ctx[53];\n\t\t\tif (dirty[0] & /*enableCanvasAlpha*/ 1048576) canvas_changes.isTransparent = /*enableCanvasAlpha*/ ctx[20];\n\t\t\tif (dirty[1] & /*$pixelRatio*/ 67108864) canvas_changes.pixelRatio = /*$pixelRatio*/ ctx[57];\n\t\t\tif (dirty[0] & /*previewImageTextPixelRatio*/ 64) canvas_changes.textPixelRatio = /*previewImageTextPixelRatio*/ ctx[6];\n\t\t\tif (dirty[1] & /*$rootBackgroundColor*/ 33554432) canvas_changes.backgroundColor = /*$rootBackgroundColor*/ ctx[56];\n\t\t\tif (dirty[1] & /*$imageSelectionRectPresentation*/ 134217728) canvas_changes.maskRect = /*$imageSelectionRectPresentation*/ ctx[58];\n\n\t\t\tif (dirty[2] & /*imageCanvasState*/ 2048) canvas_changes.maskOpacity = /*imageCanvasState*/ ctx[73]\n\t\t\t? /*imageCanvasState*/ ctx[73].maskOpacity\n\t\t\t: 1;\n\n\t\t\tif (dirty[0] & /*markupMaskOpacity*/ 128) canvas_changes.maskMarkupOpacity = /*markupMaskOpacity*/ ctx[7];\n\t\t\tif (dirty[0] & /*previewMaskOpacity*/ 32) canvas_changes.maskFrameOpacity = /*previewMaskOpacity*/ ctx[5];\n\t\t\tif (dirty[2] & /*$imageCropLimitToImage*/ 8388608) canvas_changes.clipAnnotationsToImage = /*$imageCropLimitToImage*/ ctx[85];\n\t\t\tif (dirty[1] & /*$activeImages*/ 16777216) canvas_changes.images = /*$activeImages*/ ctx[55];\n\t\t\tif (dirty[2] & /*$interfaceImages*/ 16777216) canvas_changes.interfaceImages = /*$interfaceImages*/ ctx[86];\n\t\t\tif (dirty[0] & /*imageSourceToImageData*/ 268435456) canvas_changes.loadImageData = /*imageSourceToImageData*/ ctx[28];\n\t\t\tif (dirty[0] & /*enableTransparencyGrid*/ 2048) canvas_changes.enableGrid = /*enableTransparencyGrid*/ ctx[11];\n\t\t\tif (dirty[2] & /*$gridSize*/ 33554432) canvas_changes.gridSize = /*$gridSize*/ ctx[87];\n\t\t\tif (dirty[2] & /*$gridColorEven, $gridColorOdd*/ 201326592) canvas_changes.gridColors = [/*$gridColorEven*/ ctx[88], /*$gridColorOdd*/ ctx[89]];\n\t\t\tif (dirty[2] & /*$gridOpacity*/ 268435456) canvas_changes.gridOpacity = /*$gridOpacity*/ ctx[90];\n\t\t\tif (dirty[2] & /*$rootColorPrimary*/ 536870912) canvas_changes.selectionColor = /*$rootColorPrimary*/ ctx[91];\n\t\t\tif (dirty[2] & /*$csp*/ 1073741824) canvas_changes.csp = /*$csp*/ ctx[92] || {};\n\t\t\tif (dirty[2] & /*$willRequest*/ 524288 | dirty[3] & /*$willRequestResource*/ 1) canvas_changes.willRequest = /*$willRequest*/ ctx[81] || /*$willRequestResource*/ ctx[93];\n\t\t\tif (dirty[0] & /*willRenderCanvas*/ 512 | dirty[1] & /*$redrawTrigger, $imageAnnotation, $imageDecoration, $imageFrame, $imageSelection, manipulationShapes*/ 270991424 | dirty[3] & /*$imageOverlay*/ 2) canvas_changes.willRender = /*func*/ ctx[446];\n\t\t\tif (dirty[2] & /*imageAnnotationShapesDirty, imageAnnotationRequiresPreprocessing, imageDecorationShapesDirty, imageFrameShapesDirty, imageManipulationShapesDirty*/ 62) canvas_changes.didRender = /*func_1*/ ctx[447];\n\t\t\tcanvas.$set(canvas_changes);\n\t\t\tconst canvaspanandzoom_changes = {};\n\t\t\tif (dirty[0] & /*root*/ 4) canvaspanandzoom_changes.root = /*root*/ ctx[2];\n\t\t\tif (dirty[0] & /*locale*/ 8) canvaspanandzoom_changes.locale = /*locale*/ ctx[3];\n\t\t\tif (dirty[3] & /*$allowPan*/ 4) canvaspanandzoom_changes.allowPan = /*$allowPan*/ ctx[95];\n\t\t\tif (dirty[0] & /*enablePan*/ 131072) canvaspanandzoom_changes.enablePan = /*enablePan*/ ctx[17];\n\t\t\tif (dirty[0] & /*enablePanLimit*/ 2097152) canvaspanandzoom_changes.enablePanLimit = /*enablePanLimit*/ ctx[21];\n\t\t\tif (dirty[0] & /*panLimitGutterScalar*/ 4194304) canvaspanandzoom_changes.panLimitGutterScalar = /*panLimitGutterScalar*/ ctx[22];\n\t\t\tif (dirty[3] & /*$enablePanInputStatus*/ 8) canvaspanandzoom_changes.enablePanInput = /*$enablePanInputStatus*/ ctx[96];\n\t\t\tif (dirty[3] & /*$allowZoom*/ 16) canvaspanandzoom_changes.allowZoom = /*$allowZoom*/ ctx[97];\n\t\t\tif (dirty[0] & /*enableZoom*/ 262144) canvaspanandzoom_changes.enableZoom = /*enableZoom*/ ctx[18];\n\n\t\t\tif (dirty[0] & /*enableZoomInput*/ 524288 | dirty[3] & /*$enableZoomInputStore*/ 32) canvaspanandzoom_changes.enableZoomInput = /*enableZoomInput*/ ctx[19] !== undefined\n\t\t\t? /*enableZoomInput*/ ctx[19]\n\t\t\t: /*$enableZoomInputStore*/ ctx[98];\n\n\t\t\tif (dirty[3] & /*$enableZoomControlsProp*/ 64) canvaspanandzoom_changes.enableZoomControls = /*$enableZoomControlsProp*/ ctx[99];\n\t\t\tif (dirty[0] & /*markupEditorZoomLevels, zoomPresetOptions*/ 8396800) canvaspanandzoom_changes.zoomOptions = /*markupEditorZoomLevels*/ ctx[13] || /*zoomPresetOptions*/ ctx[23];\n\t\t\tif (dirty[0] & /*markupEditorZoomAdjustStep, zoomAdjustStep*/ 16793600) canvaspanandzoom_changes.zoomAdjustStep = /*markupEditorZoomAdjustStep*/ ctx[14] || /*zoomAdjustStep*/ ctx[24];\n\t\t\tif (dirty[0] & /*markupEditorZoomAdjustFactor, zoomAdjustFactor*/ 33587200) canvaspanandzoom_changes.zoomAdjustFactor = /*markupEditorZoomAdjustFactor*/ ctx[15] || /*zoomAdjustFactor*/ ctx[25];\n\t\t\tif (dirty[0] & /*markupEditorZoomAdjustWheelFactor, zoomAdjustWheelFactor*/ 67174400) canvaspanandzoom_changes.zoomAdjustWheelFactor = /*markupEditorZoomAdjustWheelFactor*/ ctx[16] || /*zoomAdjustWheelFactor*/ ctx[26];\n\t\t\tif (dirty[3] & /*$imageSelectionRectCentered*/ 128) canvaspanandzoom_changes.imageSelectionRectCentered = /*$imageSelectionRectCentered*/ ctx[100];\n\t\t\tif (dirty[3] & /*$imageSelectionRectScalar*/ 256) canvaspanandzoom_changes.imageSelectionRectScalar = /*$imageSelectionRectScalar*/ ctx[101];\n\t\t\tif (dirty[0] & /*elasticityMultiplier*/ 256) canvaspanandzoom_changes.elasticity = imageSelectionRectElasticity * /*elasticityMultiplier*/ ctx[8];\n\n\t\t\tif (!updating_zoomLevel && dirty[0] & /*zoomLevel*/ 1) {\n\t\t\t\tupdating_zoomLevel = true;\n\t\t\t\tcanvaspanandzoom_changes.zoomLevel = /*zoomLevel*/ ctx[0];\n\t\t\t\tadd_flush_callback(() => updating_zoomLevel = false);\n\t\t\t}\n\n\t\t\tif (!updating_zoomControls && dirty[1] & /*zoomControls*/ 4) {\n\t\t\t\tupdating_zoomControls = true;\n\t\t\t\tcanvaspanandzoom_changes.zoomControls = /*zoomControls*/ ctx[33];\n\t\t\t\tadd_flush_callback(() => updating_zoomControls = false);\n\t\t\t}\n\n\t\t\tif (!updating_zoomMultiTouching && dirty[1] & /*zoomMultiTouching*/ 8) {\n\t\t\t\tupdating_zoomMultiTouching = true;\n\t\t\t\tcanvaspanandzoom_changes.zoomMultiTouching = /*zoomMultiTouching*/ ctx[34];\n\t\t\t\tadd_flush_callback(() => updating_zoomMultiTouching = false);\n\t\t\t}\n\n\t\t\tcanvaspanandzoom.$set(canvaspanandzoom_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\ttransition_in(if_block2);\n\t\t\ttransition_in(canvas.$$.fragment, local);\n\t\t\ttransition_in(canvaspanandzoom.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\ttransition_out(if_block2);\n\t\t\ttransition_out(canvas.$$.fragment, local);\n\t\t\ttransition_out(canvaspanandzoom.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(t1);\n\t\t\t\tdetach(t2);\n\t\t\t\tdetach(t3);\n\t\t\t\tdetach(div);\n\t\t\t\tdetach(t4);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t\tdestroy_component(canvas, detaching);\n\t\t\t/*div_binding*/ ctx[448](null);\n\t\t\tdestroy_component(canvaspanandzoom, detaching);\n\t\t}\n\t};\n}\n\n// (4037:12) {#if enableToolbar}\nfunction create_if_block_7$1(ctx) {\n\tlet div;\n\tlet dynamiccomponenttree;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*toolbarItems*/ ctx[69] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaNav PinturaNavTools\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(dynamiccomponenttree, div, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler*/ ctx[435]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty[2] & /*toolbarItems*/ 128) dynamiccomponenttree_changes.items = /*toolbarItems*/ ctx[69];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (4047:12) {#if shouldRenderTabs && showUtils}\nfunction create_if_block_5$3(ctx) {\n\tlet div;\n\tlet scrollable;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\telasticity: /*elasticityMultiplier*/ ctx[8] * scrollElasticity,\n\t\t\t\tscrollDirection: /*isLandscape*/ ctx[76] ? 'y' : 'x',\n\t\t\t\t$$slots: { default: [create_default_slot_2$4] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaNav PinturaNavMain\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(scrollable, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty[0] & /*elasticityMultiplier*/ 256) scrollable_changes.elasticity = /*elasticityMultiplier*/ ctx[8] * scrollElasticity;\n\t\t\tif (dirty[2] & /*isLandscape*/ 16384) scrollable_changes.scrollDirection = /*isLandscape*/ ctx[76] ? 'y' : 'x';\n\n\t\t\tif (dirty[1] & /*tabsAfterWillRender, utilSelected*/ 12288 | dirty[2] & /*tabsAreNodes, tabsConfig*/ 135168 | dirty[20] & /*$$scope*/ 16) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(scrollable);\n\t\t}\n\t};\n}\n\n// (4055:24) {:else}\nfunction create_else_block_1(ctx) {\n\tlet tablist;\n\tlet current;\n\tconst tablist_spread_levels = [/*tabsConfig*/ ctx[79], { tabs: /*tabsAfterWillRender*/ ctx[44] }];\n\n\tlet tablist_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot_3$2,\n\t\t\t\t({ tab }) => ({ 623: tab }),\n\t\t\t\t({ tab }) => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, tab ? 8 : 0]\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tablist_spread_levels.length; i += 1) {\n\t\ttablist_props = assign(tablist_props, tablist_spread_levels[i]);\n\t}\n\n\ttablist = new TabList({ props: tablist_props });\n\ttablist.$on(\"select\", /*select_handler*/ ctx[436]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(tablist.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(tablist, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst tablist_changes = (dirty[1] & /*tabsAfterWillRender*/ 8192 | dirty[2] & /*tabsConfig*/ 131072)\n\t\t\t? get_spread_update(tablist_spread_levels, [\n\t\t\t\t\tdirty[2] & /*tabsConfig*/ 131072 && get_spread_object(/*tabsConfig*/ ctx[79]),\n\t\t\t\t\tdirty[1] & /*tabsAfterWillRender*/ 8192 && { tabs: /*tabsAfterWillRender*/ ctx[44] }\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty[20] & /*$$scope, tab*/ 24) {\n\t\t\t\ttablist_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttablist.$set(tablist_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(tablist.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(tablist.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(tablist, detaching);\n\t\t}\n\t};\n}\n\n// (4053:24) {#if tabsAreNodes}\nfunction create_if_block_6$2(ctx) {\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*tabsAfterWillRender*/ ctx[44] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty[1] & /*tabsAfterWillRender*/ 8192) dynamiccomponenttree_changes.items = /*tabsAfterWillRender*/ ctx[44];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t}\n\t};\n}\n\n// (4062:32) <Icon>\nfunction create_default_slot_4$2(ctx) {\n\tlet g;\n\tlet raw_value = /*tab*/ ctx[623].icon + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[20] & /*tab*/ 8 && raw_value !== (raw_value = /*tab*/ ctx[623].icon + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (4056:28) <TabList                                 {...tabsConfig}                                 tabs={tabsAfterWillRender}                                 on:select={({ detail }) => (utilSelected = detail)}                                 let:tab                             >\nfunction create_default_slot_3$2(ctx) {\n\tlet icon;\n\tlet t0;\n\tlet span;\n\tlet t1_value = /*tab*/ ctx[623].label + \"\";\n\tlet t1;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_4$2] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t\tt0 = space();\n\t\t\tspan = element(\"span\");\n\t\t\tt1 = text(t1_value);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tinsert(target, t0, anchor);\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t1);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty[20] & /*$$scope, tab*/ 24) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t\tif ((!current || dirty[20] & /*tab*/ 8) && t1_value !== (t1_value = /*tab*/ ctx[623].label + \"\")) set_data(t1, t1_value);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(span);\n\t\t\t}\n\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (4049:20) <Scrollable                         elasticity={elasticityMultiplier * scrollElasticity}                         scrollDirection={isLandscape ? 'y' : 'x'}                     >\nfunction create_default_slot_2$4(ctx) {\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet if_block_anchor;\n\tlet current;\n\tconst if_block_creators = [create_if_block_6$2, create_else_block_1];\n\tconst if_blocks = [];\n\n\tfunction select_block_type_1(ctx, dirty) {\n\t\tif (/*tabsAreNodes*/ ctx[74]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type_1(ctx);\n\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type_1(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t}\n\t};\n}\n\n// (4093:12) {:else}\nfunction create_else_block$5(ctx) {\n\tlet utilpanel;\n\tlet updating_component;\n\tlet current;\n\n\tfunction utilpanel_component_binding_1(value) {\n\t\t/*utilpanel_component_binding_1*/ ctx[442](value);\n\t}\n\n\tlet utilpanel_props = {\n\t\tlocale: /*locale*/ ctx[3],\n\t\tclass: \"PinturaMain\",\n\t\tview: /*getUtilPanelView*/ ctx[207](/*utilSelected*/ ctx[43]),\n\t\tprops: /*getUtilPanelProps*/ ctx[206](/*utilSelected*/ ctx[43], /*pluginOptions*/ ctx[27]),\n\t\tstores: /*utilStores*/ ctx[202]\n\t};\n\n\tif (/*pluginInterface*/ ctx[1][/*utilSelected*/ ctx[43]] !== void 0) {\n\t\tutilpanel_props.component = /*pluginInterface*/ ctx[1][/*utilSelected*/ ctx[43]];\n\t}\n\n\tutilpanel = new UtilPanel({ props: utilpanel_props });\n\tbinding_callbacks.push(() => bind(utilpanel, 'component', utilpanel_component_binding_1));\n\tutilpanel.$on(\"measure\", /*handleMeasureUtil*/ ctx[234]);\n\tutilpanel.$on(\"show\", /*show_handler_1*/ ctx[443]);\n\tutilpanel.$on(\"hide\", /*hide_handler_1*/ ctx[444]);\n\tutilpanel.$on(\"fade\", /*fade_handler_1*/ ctx[445]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(utilpanel.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(utilpanel, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst utilpanel_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 8) utilpanel_changes.locale = /*locale*/ ctx[3];\n\t\t\tif (dirty[1] & /*utilSelected*/ 4096) utilpanel_changes.view = /*getUtilPanelView*/ ctx[207](/*utilSelected*/ ctx[43]);\n\t\t\tif (dirty[0] & /*pluginOptions*/ 134217728 | dirty[1] & /*utilSelected*/ 4096) utilpanel_changes.props = /*getUtilPanelProps*/ ctx[206](/*utilSelected*/ ctx[43], /*pluginOptions*/ ctx[27]);\n\n\t\t\tif (!updating_component && dirty[0] & /*pluginInterface*/ 2 | dirty[1] & /*utilSelected*/ 4096) {\n\t\t\t\tupdating_component = true;\n\t\t\t\tutilpanel_changes.component = /*pluginInterface*/ ctx[1][/*utilSelected*/ ctx[43]];\n\t\t\t\tadd_flush_callback(() => updating_component = false);\n\t\t\t}\n\n\t\t\tutilpanel.$set(utilpanel_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(utilpanel.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(utilpanel.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(utilpanel, detaching);\n\t\t}\n\t};\n}\n\n// (4070:12) {#if shouldRenderTabs}\nfunction create_if_block_4$4(ctx) {\n\tlet tabpanels;\n\tlet current;\n\n\tconst tabpanels_spread_levels = [\n\t\t{ class: \"PinturaMain\" },\n\t\t{ visible: /*utilsVisible*/ ctx[62] },\n\t\t/*tabsConfig*/ ctx[79],\n\t\t{ panels: /*panels*/ ctx[78] }\n\t];\n\n\tlet tabpanels_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot_1$4,\n\t\t\t\t({ panel, panelIsActive }) => ({ 621: panel, 622: panelIsActive }),\n\t\t\t\t({ panel, panelIsActive }) => [\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\t(panel ? 2 : 0) | (panelIsActive ? 4 : 0)\n\t\t\t\t]\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tabpanels_spread_levels.length; i += 1) {\n\t\ttabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);\n\t}\n\n\ttabpanels = new TabPanels({ props: tabpanels_props });\n\ttabpanels.$on(\"measure\", /*measure_handler_1*/ ctx[441]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(tabpanels.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(tabpanels, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst tabpanels_changes = (dirty[2] & /*utilsVisible, tabsConfig, panels*/ 196609)\n\t\t\t? get_spread_update(tabpanels_spread_levels, [\n\t\t\t\t\ttabpanels_spread_levels[0],\n\t\t\t\t\tdirty[2] & /*utilsVisible*/ 1 && { visible: /*utilsVisible*/ ctx[62] },\n\t\t\t\t\tdirty[2] & /*tabsConfig*/ 131072 && get_spread_object(/*tabsConfig*/ ctx[79]),\n\t\t\t\t\tdirty[2] & /*panels*/ 65536 && { panels: /*panels*/ ctx[78] }\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty[0] & /*locale, pluginOptions, pluginInterface*/ 134217738 | dirty[20] & /*$$scope, panel, panelIsActive*/ 22) {\n\t\t\t\ttabpanels_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttabpanels.$set(tabpanels_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(tabpanels.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(tabpanels.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(tabpanels, detaching);\n\t\t}\n\t};\n}\n\n// (4071:16) <TabPanels                     class=\"PinturaMain\"                     visible={utilsVisible}                     {...tabsConfig}                     {panels}                     let:panel                     let:panelIsActive                     on:measure={(e) => ($tabRect = e.detail)}                 >\nfunction create_default_slot_1$4(ctx) {\n\tlet utilpanel;\n\tlet updating_component;\n\tlet current;\n\n\tfunction utilpanel_component_binding(value) {\n\t\t/*utilpanel_component_binding*/ ctx[437](value, /*panel*/ ctx[621]);\n\t}\n\n\tfunction show_handler() {\n\t\treturn /*show_handler*/ ctx[438](/*panel*/ ctx[621]);\n\t}\n\n\tfunction hide_handler() {\n\t\treturn /*hide_handler*/ ctx[439](/*panel*/ ctx[621]);\n\t}\n\n\tfunction fade_handler(...args) {\n\t\treturn /*fade_handler*/ ctx[440](/*panel*/ ctx[621], ...args);\n\t}\n\n\tlet utilpanel_props = {\n\t\tlocale: /*locale*/ ctx[3],\n\t\tview: /*getUtilPanelView*/ ctx[207](/*panel*/ ctx[621]),\n\t\tprops: /*getUtilPanelProps*/ ctx[206](/*panel*/ ctx[621], /*pluginOptions*/ ctx[27]),\n\t\tisActive: /*panelIsActive*/ ctx[622],\n\t\tstores: /*utilStores*/ ctx[202]\n\t};\n\n\tif (/*pluginInterface*/ ctx[1][/*panel*/ ctx[621]] !== void 0) {\n\t\tutilpanel_props.component = /*pluginInterface*/ ctx[1][/*panel*/ ctx[621]];\n\t}\n\n\tutilpanel = new UtilPanel({ props: utilpanel_props });\n\tbinding_callbacks.push(() => bind(utilpanel, 'component', utilpanel_component_binding));\n\tutilpanel.$on(\"measure\", /*handleMeasureUtil*/ ctx[234]);\n\tutilpanel.$on(\"show\", show_handler);\n\tutilpanel.$on(\"hide\", hide_handler);\n\tutilpanel.$on(\"fade\", fade_handler);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(utilpanel.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(utilpanel, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tconst utilpanel_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 8) utilpanel_changes.locale = /*locale*/ ctx[3];\n\t\t\tif (dirty[20] & /*panel*/ 2) utilpanel_changes.view = /*getUtilPanelView*/ ctx[207](/*panel*/ ctx[621]);\n\t\t\tif (dirty[0] & /*pluginOptions*/ 134217728 | dirty[20] & /*panel*/ 2) utilpanel_changes.props = /*getUtilPanelProps*/ ctx[206](/*panel*/ ctx[621], /*pluginOptions*/ ctx[27]);\n\t\t\tif (dirty[20] & /*panelIsActive*/ 4) utilpanel_changes.isActive = /*panelIsActive*/ ctx[622];\n\n\t\t\tif (!updating_component && dirty[0] & /*pluginInterface*/ 2 | dirty[20] & /*panel*/ 2) {\n\t\t\t\tupdating_component = true;\n\t\t\t\tutilpanel_changes.component = /*pluginInterface*/ ctx[1][/*panel*/ ctx[621]];\n\t\t\t\tadd_flush_callback(() => updating_component = false);\n\t\t\t}\n\n\t\t\tutilpanel.$set(utilpanel_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(utilpanel.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(utilpanel.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(utilpanel, detaching);\n\t\t}\n\t};\n}\n\n// (4208:4) {#if $disabledTransition > 0}\nfunction create_if_block_1$7(ctx) {\n\tlet span;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tattr(span, \"class\", \"PinturaEditorOverlay\");\n\t\t\tset_style(span, \"opacity\", /*$disabledTransition*/ ctx[102]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[3] & /*$disabledTransition*/ 512) {\n\t\t\t\tset_style(span, \"opacity\", /*$disabledTransition*/ ctx[102]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (4211:4) {#if userTextInput}\nfunction create_if_block$b(ctx) {\n\tlet inputform;\n\tlet current;\n\n\tconst inputform_spread_levels = [\n\t\t{ layout: 'row' },\n\t\t{ parentRect: /*$stageRect*/ ctx[50] },\n\t\t/*userTextInput*/ ctx[60]\n\t];\n\n\tlet inputform_props = {\n\t\t$$slots: { default: [create_default_slot$b] },\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < inputform_spread_levels.length; i += 1) {\n\t\tinputform_props = assign(inputform_props, inputform_spread_levels[i]);\n\t}\n\n\tinputform = new InputForm({ props: inputform_props });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(inputform.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(inputform, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst inputform_changes = (dirty[1] & /*$stageRect, userTextInput*/ 537395200)\n\t\t\t? get_spread_update(inputform_spread_levels, [\n\t\t\t\t\tinputform_spread_levels[0],\n\t\t\t\t\tdirty[1] & /*$stageRect*/ 524288 && { parentRect: /*$stageRect*/ ctx[50] },\n\t\t\t\t\tdirty[1] & /*userTextInput*/ 536870912 && get_spread_object(/*userTextInput*/ ctx[60])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty[1] & /*userTextInput, userTextInputField*/ 1610612736 | dirty[20] & /*$$scope*/ 16) {\n\t\t\t\tinputform_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tinputform.$set(inputform_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(inputform.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(inputform.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(inputform, detaching);\n\t\t}\n\t};\n}\n\n// (4212:8) <InputForm layout={'row'} parentRect={$stageRect} {...userTextInput}>\nfunction create_default_slot$b(ctx) {\n\tlet input;\n\tlet input_value_value;\n\tlet input_placeholder_value;\n\n\treturn {\n\t\tc() {\n\t\t\tinput = element(\"input\");\n\t\t\tinput.value = input_value_value = /*userTextInput*/ ctx[60].text;\n\t\t\tattr(input, \"placeholder\", input_placeholder_value = /*userTextInput*/ ctx[60].placeholder);\n\t\t\tattr(input, \"type\", \"text\");\n\t\t\tattr(input, \"spellcheck\", \"false\");\n\t\t\tattr(input, \"autocorrect\", \"off\");\n\t\t\tattr(input, \"autocapitalize\", \"off\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, input, anchor);\n\t\t\t/*input_binding*/ ctx[452](input);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*userTextInput*/ 536870912 && input_value_value !== (input_value_value = /*userTextInput*/ ctx[60].text) && input.value !== input_value_value) {\n\t\t\t\tinput.value = input_value_value;\n\t\t\t}\n\n\t\t\tif (dirty[1] & /*userTextInput*/ 536870912 && input_placeholder_value !== (input_placeholder_value = /*userTextInput*/ ctx[60].placeholder)) {\n\t\t\t\tattr(input, \"placeholder\", input_placeholder_value);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(input);\n\t\t\t}\n\n\t\t\t/*input_binding*/ ctx[452](null);\n\t\t}\n\t};\n}\n\nfunction create_fragment$s(ctx) {\n\tlet div;\n\tlet t0;\n\tlet t1;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tadd_render_callback(/*onwindowresize*/ ctx[434]);\n\tlet if_block0 = /*canRender*/ ctx[40] && create_if_block_2$7(ctx);\n\tlet if_block1 = /*$disabledTransition*/ ctx[102] > 0 && create_if_block_1$7(ctx);\n\tlet if_block2 = /*userTextInput*/ ctx[60] && create_if_block$b(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block2) if_block2.c();\n\t\t\tattr(div, \"id\", /*id*/ ctx[4]);\n\t\t\tattr(div, \"class\", /*className*/ ctx[77]);\n\t\t\tattr(div, \"data-env\", /*envStr*/ ctx[75]);\n\t\t\tattr(div, \"dir\", /*textDirection*/ ctx[12]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block0) if_block0.m(div, null);\n\t\t\tappend(div, t0);\n\t\t\tif (if_block1) if_block1.m(div, null);\n\t\t\tappend(div, t1);\n\t\t\tif (if_block2) if_block2.m(div, null);\n\t\t\t/*div_binding_1*/ ctx[453](div);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(window_1$1, \"keydown\", /*handleKeydown*/ ctx[225]),\n\t\t\t\t\tlisten(window_1$1, \"keyup\", /*handleKeyup*/ ctx[226]),\n\t\t\t\t\tlisten(window_1$1, \"blur\", /*handleWindowBlur*/ ctx[227]),\n\t\t\t\t\tlisten(window_1$1, \"paste\", /*handlePaste*/ ctx[231]),\n\t\t\t\t\tlisten(window_1$1, \"resize\", /*onwindowresize*/ ctx[434]),\n\t\t\t\t\tlisten(div, \"ping\", function () {\n\t\t\t\t\t\tif (is_function(/*routePing*/ ctx[68])) /*routePing*/ ctx[68].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"contextmenu\", /*handleContextMenu*/ ctx[228]),\n\t\t\t\t\tlisten(div, \"touchstart\", /*handleTouchStart*/ ctx[223], { passive: false }),\n\t\t\t\t\tlisten(div, \"touchmove\", function () {\n\t\t\t\t\t\tif (is_function(/*handleTouchMove*/ ctx[71])) /*handleTouchMove*/ ctx[71].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"pointermove\", function () {\n\t\t\t\t\t\tif (is_function(/*handlePointerMove*/ ctx[70])) /*handlePointerMove*/ ctx[70].apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"transitionend\", /*handleTransitionEnd*/ ctx[212]),\n\t\t\t\t\tlisten(div, \"dropfiles\", /*handleDropFiles*/ ctx[229]),\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler_2*/ ctx[454]),\n\t\t\t\t\tlisten(div, \"click\", function () {\n\t\t\t\t\t\tif (is_function(/*isWaitingForImage*/ ctx[42]\n\t\t\t\t\t\t? /*browseFileSystem*/ ctx[230]\n\t\t\t\t\t\t: noop$1)) (/*isWaitingForImage*/ ctx[42]\n\t\t\t\t\t\t? /*browseFileSystem*/ ctx[230]\n\t\t\t\t\t\t: noop$1).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(measurable.call(null, div, {\n\t\t\t\t\t\tobserveViewRect: true,\n\t\t\t\t\t\tisMeasureRoot: true\n\t\t\t\t\t})),\n\t\t\t\t\taction_destroyer(focusvisible.call(null, div)),\n\t\t\t\t\taction_destroyer(dropable.call(null, div))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (/*canRender*/ ctx[40]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*canRender*/ 512) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_2$7(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*$disabledTransition*/ ctx[102] > 0) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_1$7(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(div, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\n\t\t\tif (/*userTextInput*/ ctx[60]) {\n\t\t\t\tif (if_block2) {\n\t\t\t\t\tif_block2.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*userTextInput*/ 536870912) {\n\t\t\t\t\t\ttransition_in(if_block2, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block2 = create_if_block$b(ctx);\n\t\t\t\t\tif_block2.c();\n\t\t\t\t\ttransition_in(if_block2, 1);\n\t\t\t\t\tif_block2.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block2) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block2, 1, 1, () => {\n\t\t\t\t\tif_block2 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*id*/ 16) {\n\t\t\t\tattr(div, \"id\", /*id*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[2] & /*className*/ 32768) {\n\t\t\t\tattr(div, \"class\", /*className*/ ctx[77]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[2] & /*envStr*/ 8192) {\n\t\t\t\tattr(div, \"data-env\", /*envStr*/ ctx[75]);\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*textDirection*/ 4096) {\n\t\t\t\tattr(div, \"dir\", /*textDirection*/ ctx[12]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block2);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block2);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t\tif (if_block2) if_block2.d();\n\t\t\t/*div_binding_1*/ ctx[453](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nconst VIEWPORT_HEIGHT_VS_CLIENT_HEIGHT_RATIO = 0.75;\nlet frameUpdateRequestDist = 16;\n\n// dragging & zooming / the inteded crop rect, combined with actual crop rect, used to render elasticity visualisation\nconst imageCropRectElasticity = 5;\n\n// updating crop selection / the intended selection rect, combined with actual selection rect, used to render elasticity visualisation\nconst imageSelectionRectElasticity = 1;\n\nconst OVERLAY_ID = 'stage-overlay';\nconst OVERLAY_OPACITY_TWEEN_DIST = 64;\nconst scrollElasticity = 10;\nconst rangeInputElasticity = 5;\n\nfunction instance$s($$self, $$props, $$invalidate) {\n\tlet hasLocale;\n\tlet isTrimPluginLoaded;\n\tlet isVideoSupported;\n\tlet videoFrameOffsetFixed;\n\tlet videoTrim;\n\tlet videoTrimFirst;\n\tlet videoTrimLast;\n\tlet videoTrimFixed;\n\tlet videoTrimCurrentIndex;\n\tlet videoTrimNextIndex;\n\tlet isOverlayModeEnabled;\n\tlet showUtils;\n\tlet maxImageDataSize;\n\tlet preprocessShape;\n\tlet supportsAnimations;\n\tlet canAnimate;\n\tlet acceptsAnimations;\n\tlet OVERLAY_OPACITY_MAX;\n\tlet overlayMin;\n\tlet overlayOverlap;\n\tlet overlayLeft;\n\tlet overlayTop;\n\tlet overlayRight;\n\tlet overlayBottom;\n\tlet gradientOverlays;\n\tlet imageTransformsSnapPixels;\n\tlet canUndo;\n\tlet canRedo;\n\tlet shapeCollections;\n\tlet utilsFiltered;\n\tlet utilsAvailable;\n\tlet utilsDefined;\n\tlet utilsMerged;\n\tlet utilSelected;\n\tlet utilsVisibleFraction;\n\tlet tabsConfig;\n\tlet tabs;\n\tlet panels;\n\tlet shouldRenderTabs;\n\tlet className;\n\tlet horizontalSpace;\n\tlet hasLimitedSpace;\n\tlet verticalSpace;\n\tlet isModal;\n\tlet isCenteredHorizontally;\n\tlet isCenteredVertically;\n\tlet isCentered;\n\tlet isTransparent;\n\tlet isNarrow;\n\tlet orientation;\n\tlet isLandscape;\n\tlet isCompact;\n\tlet hasSwipeNavigation;\n\tlet activeUtilTools;\n\tlet navigationHorizontalPreference;\n\tlet navigationVerticalPreference;\n\tlet toolbarVerticalPreference;\n\tlet controlGroupsVerticalPreference;\n\tlet controlTabsVerticalpreference;\n\tlet rootRectDefined;\n\tlet rootElementComputedStyle;\n\tlet envStr;\n\tlet tabsAfterWillRender;\n\tlet tabsAreNodes;\n\tlet imageCanvasState;\n\tlet hasProps;\n\tlet missingFeatures;\n\tlet isSupportsError;\n\tlet isMemoryError;\n\tlet isStartLoadingImageSource;\n\tlet isImageLoadError;\n\tlet isWaitingForImage;\n\tlet imageLoadProgress;\n\tlet isLoadingImageData;\n\tlet isCreatingImagePreview;\n\tlet isProcessingImage;\n\tlet imageLoadShowProgressIndicator;\n\tlet imageLoadStatusLabel;\n\tlet imageProcessStatusLabel;\n\tlet imageProcessProgress;\n\tlet imageProcessShowProgressIndicator;\n\tlet isImageProcessingError;\n\tlet isCustomStatus;\n\tlet isStatusActive;\n\tlet isStatusVisible;\n\tlet hasAside;\n\tlet statusIndent;\n\tlet statusTransform;\n\tlet needsInteractionLock;\n\tlet preventTouchHandler;\n\tlet handleTouchMove;\n\tlet handlePointerMove;\n\tlet toolbarItems;\n\tlet hasClientRect;\n\tlet canRender;\n\tlet hasImageRedaction;\n\tlet imageRedactionScalar;\n\tlet manipulationShapes;\n\tlet routePing;\n\tlet isReady;\n\tlet hasHeight;\n\tlet $rootRect;\n\tlet $utilRect;\n\n\tlet $imagePreview,\n\t\t$$unsubscribe_imagePreview = noop,\n\t\t$$subscribe_imagePreview = () => ($$unsubscribe_imagePreview(), $$unsubscribe_imagePreview = subscribe(imagePreview, $$value => $$invalidate(379, $imagePreview = $$value)), imagePreview);\n\n\tlet $imageFrame;\n\tlet $imageDecoration;\n\tlet $imageSize;\n\tlet $imageFlipY;\n\tlet $imageFlipX;\n\tlet $imageRotation;\n\tlet $imageAnnotation;\n\tlet $stageRect;\n\tlet $isInteractingFraction;\n\tlet $isInteracting;\n\tlet $rootLineColor;\n\tlet $rootForegroundColor;\n\tlet $imageManipulation;\n\tlet $imageRedaction;\n\tlet $imageRedactionRendering;\n\tlet $imageBackgroundColor;\n\tlet $imageScrambler;\n\tlet $pressedKeysStore;\n\tlet $allowPlayPause;\n\tlet $clientRect;\n\tlet $env;\n\tlet $redrawTrigger;\n\tlet $imageProcessingPreparing;\n\tlet $isAnimated;\n\tlet $statusOffset;\n\tlet $asideWidth;\n\tlet $statusWidth;\n\tlet $statusOpacity;\n\tlet $wasProcessingImage;\n\tlet $imageVisualLoadComplete;\n\tlet $imageProcessState;\n\tlet $imageLoadState;\n\tlet $imagePreviewSource;\n\tlet $activeImages;\n\tlet $imageProps;\n\tlet $shouldAnimate;\n\tlet $imagePreviewModifiers;\n\tlet $imageTransforms;\n\tlet $pointerHoverable;\n\tlet $pointerAccuracy;\n\tlet $utilTools;\n\tlet $imageFile;\n\tlet $previewShouldUpscale;\n\n\tlet $history,\n\t\t$$unsubscribe_history = noop,\n\t\t$$subscribe_history = () => ($$unsubscribe_history(), $$unsubscribe_history = subscribe(history, $$value => $$invalidate(408, $history = $$value)), history);\n\n\tlet $imageState;\n\tlet $tabRect;\n\tlet $imageOverlayMarkup;\n\tlet $overlayBottomRect;\n\tlet $overlayOpacity;\n\tlet $rootBackgroundColor;\n\tlet $overlayRightRect;\n\tlet $overlayTopRect;\n\tlet $overlayLeftRect;\n\tlet $pixelRatio;\n\tlet $imageSelectionRectPresentation;\n\tlet $stagePadding;\n\tlet $stagePadded;\n\tlet $imageSelectionRectStaticScalar;\n\tlet $imageSelectionRect;\n\tlet $imageCropRect;\n\tlet $imageCropRectIntent;\n\tlet $imageSelectionRectSnapshot;\n\tlet $imageIsStatic;\n\tlet $imageCropRectSnapshot;\n\tlet $presentationScalar;\n\tlet $stageScalar;\n\tlet $imageStaticBounds;\n\tlet $imageSelectionScalar;\n\tlet $imageSelectionPan;\n\tlet $imageSelectionRectIntent;\n\tlet $imageSelectionRectOffset;\n\tlet $imageSelectionZoom;\n\tlet $prefersReducedMotion;\n\tlet $rootInsetTop;\n\tlet $imageCropAspectRatio;\n\tlet $enablePanInputStore;\n\tlet $enablePanInputProp;\n\tlet $allowZoomControls;\n\tlet $imageSelection;\n\tlet $shapePreprocessor;\n\tlet $images;\n\tlet $mediaTrim;\n\tlet $mediaCurrentTime;\n\tlet $willRequest;\n\tlet $elasticityMultiplierStore;\n\tlet $mediaVolume;\n\tlet $videoFrameOffset;\n\tlet $mediaDuration;\n\tlet $isMuted;\n\tlet $videoFramePeekOffset;\n\tlet $mediaMaxDuration;\n\tlet $asideOffset;\n\tlet $asideOpacity;\n\tlet $toolRect;\n\tlet $imageCropLimitToImage;\n\tlet $interfaceImages;\n\tlet $gridSize;\n\tlet $gridColorEven;\n\tlet $gridColorOdd;\n\tlet $gridOpacity;\n\tlet $rootColorPrimary;\n\tlet $csp;\n\tlet $willRequestResource;\n\tlet $imageOverlay;\n\tlet $allowPan;\n\tlet $enablePanInputStatus;\n\tlet $allowZoom;\n\tlet $enableZoomInputStore;\n\tlet $enableZoomControlsProp;\n\tlet $imageSelectionRectCentered;\n\tlet $imageSelectionRectScalar;\n\tlet $disabledTransition;\n\tcomponent_subscribe($$self, prefersReducedMotion, $$value => $$invalidate(422, $prefersReducedMotion = $$value));\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_imagePreview());\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_history());\n\tconst eventProxy = pubsub();\n\tconst dispatch = createEventDispatcher();\n\tlet { class: klass = undefined } = $$props;\n\tlet { layout: layoutMode = undefined } = $$props;\n\tlet { stores } = $$props;\n\tlet { locale = undefined } = $$props;\n\tlet { id = undefined } = $$props;\n\tlet { util = undefined } = $$props;\n\tlet { utils = undefined } = $$props;\n\tlet { animations = 'auto' } = $$props;\n\tlet { disabled = false } = $$props;\n\tlet { previewUpscale = false } = $$props;\n\tlet { previewPad = false } = $$props;\n\tlet { previewMaskOpacity = 0.95 } = $$props;\n\tlet { previewImageDataMaxSize = undefined } = $$props;\n\tlet { previewImageTextPixelRatio = undefined } = $$props;\n\tlet { markupMaskOpacity = 1 } = $$props;\n\tlet { zoomMaskOpacity = 0.85 } = $$props;\n\tlet { elasticityMultiplier = 10 } = $$props;\n\tlet { willRevert = () => Promise.resolve(true) } = $$props;\n\tlet { willProcessImage = () => Promise.resolve(true) } = $$props;\n\tlet { willRenderCanvas = passthrough } = $$props;\n\tlet { willRenderToolbar = passthrough } = $$props;\n\tlet { willRenderUtilTabs = passthrough } = $$props;\n\tlet { willSetHistoryInitialState = passthrough } = $$props;\n\tlet { enableButtonExport = true } = $$props;\n\tlet { enableButtonRevert = true } = $$props;\n\tlet { enableNavigateHistory = true } = $$props;\n\tlet { enableToolbar = true } = $$props;\n\tlet { enableUtils = true } = $$props;\n\tlet { enableButtonClose = false } = $$props;\n\tlet { enableDropImage = false } = $$props;\n\tlet { enablePasteImage = false } = $$props;\n\tlet { enableBrowseImage = false } = $$props;\n\tlet { accept = 'image/*' } = $$props;\n\tlet { enableTransparencyGrid = false } = $$props;\n\tlet { layoutDirectionPreference = 'auto' } = $$props;\n\tlet { layoutHorizontalUtilsPreference = 'left' } = $$props;\n\tlet { layoutVerticalUtilsPreference = 'bottom' } = $$props;\n\tlet { layoutVerticalToolbarPreference = 'top' } = $$props;\n\tlet { layoutVerticalControlGroupsPreference = 'bottom' } = $$props;\n\tlet { layoutVerticalControlTabsPreference = 'bottom' } = $$props;\n\tlet { supportedMediaTypes = ['image'] } = $$props;\n\tlet { status = undefined } = $$props;\n\n\tlet { formatStatusImageLoading = function (values, locale) {\n\t\tconst { state } = values;\n\n\t\tif (!state || !state.task) {\n\t\t\treturn locale.statusImageLoadNone;\n\t\t}\n\n\t\tif (state.error) {\n\t\t\tif (state.error.code === 'IMAGE_TOO_SMALL') {\n\t\t\t\treturn locale.statusImageLoadMinSize;\n\t\t\t}\n\n\t\t\tif (state.error.code === 'VIDEO_TOO_SHORT') {\n\t\t\t\tconst seconds = Array.isArray(locale.unitSeconds)\n\t\t\t\t? state.error.metadata.minDuration === 1\n\t\t\t\t\t? locale.unitSeconds[0]\n\t\t\t\t\t: locale.unitSeconds[1]\n\t\t\t\t: locale.unitSeconds;\n\n\t\t\t\treturn stringReplace(locale.statusImageLoadMinDuration, { seconds }, '{', '}');\n\t\t\t}\n\n\t\t\treturn locale.statusImageLoadError;\n\t\t}\n\n\t\tif (state.task === 'blob-to-bitmap') {\n\t\t\treturn locale.statusImageLoadPrepare;\n\t\t}\n\n\t\treturn locale.statusImageLoadBusy;\n\t} } = $$props;\n\n\tlet { formatStatusImageProcessing = function (values, locale) {\n\t\tconst { state } = values;\n\n\t\tif (!state || !state.task) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (state.task === 'store') {\n\t\t\tif (state.error) {\n\t\t\t\treturn locale.statusImageUploadError; //'Error uploading image';\n\t\t\t}\n\n\t\t\treturn locale.statusImageUploadBusy; //'Uploading image&hellip;';\n\t\t}\n\n\t\tif (state.error) {\n\t\t\treturn locale.statusImageProcessError; // 'Error processing image';\n\t\t}\n\n\t\treturn locale.statusImageProcessBusy; // 'Processing image&hellip;';\n\t} } = $$props;\n\n\tlet { formatStatusSupportError = function (values, locale) {\n\t\tconst { features } = values;\n\t\treturn { features: features.join(', ') };\n\t} } = $$props;\n\n\tlet { textDirection = undefined } = $$props;\n\tlet { markupEditorZoomLevel = null } = $$props;\n\tlet { markupEditorZoomLevels = undefined } = $$props;\n\tlet { markupEditorZoomAdjustStep = undefined } = $$props;\n\tlet { markupEditorZoomAdjustFactor = undefined } = $$props;\n\tlet { markupEditorZoomAdjustWheelFactor = undefined } = $$props;\n\tlet { markupEditorInteractionMode = false } = $$props;\n\tlet { muteAudio = true } = $$props;\n\tlet { willSetMediaInitialTimeOffset = (duration, trim) => duration * getRangeCenter(trim[0]) } = $$props;\n\tlet { enablePan = true } = $$props;\n\tlet { enableZoom = true } = $$props;\n\tlet { enableZoomControls = true } = $$props;\n\tlet { enableZoomInput = undefined } = $$props;\n\tlet { enablePanInput = undefined } = $$props;\n\tlet { enableCanvasAlpha = false } = $$props;\n\tlet { enablePanLimit = undefined } = $$props;\n\tlet { panLimitGutterScalar = undefined } = $$props;\n\tlet { pan = null } = $$props;\n\tlet { zoomPresetOptions = [0.25, 0.5, 1, 1.25, 1.5, 2, 3, 4, 6, 8, 16] } = $$props;\n\tlet { zoomAdjustStep = 0.25 } = $$props;\n\tlet { zoomAdjustFactor = 0.1 } = $$props;\n\tlet { zoomAdjustWheelFactor = 1 } = $$props;\n\tlet { zoomLevel = null } = $$props;\n\tlet { fixScrollDirection = false } = $$props;\n\tconst fixScrollDirectionStore = writable(fixScrollDirection);\n\tsetContext('fixScrollDirection', fixScrollDirectionStore);\n\n\t// try to detect softkeyboard state on mobile devices\n\tconst canObserveSoftKeyboard = isBrowser() && 'visualViewport' in window;\n\n\tconst softKeyboardState = writable('hidden');\n\tsetContext('softKeyboardState', softKeyboardState);\n\n\tfunction handleVisualViewportResize(e) {\n\t\tconst { height, scale } = e.target;\n\t\tconst ratio = height * scale / window.screen.height;\n\n\t\tconst state = ratio < VIEWPORT_HEIGHT_VS_CLIENT_HEIGHT_RATIO\n\t\t? 'visible'\n\t\t: 'hidden';\n\n\t\tsoftKeyboardState.set(state);\n\t}\n\n\tif (canObserveSoftKeyboard) {\n\t\twindow.visualViewport.addEventListener('resize', handleVisualViewportResize);\n\t}\n\n\t// toggle text input\n\tlet userTextInput;\n\n\tlet userTextInputField;\n\tconst hideTextInput = () => $$invalidate(60, userTextInput = undefined);\n\n\tconst showTextInput = (confirm, cancel, options) => {\n\t\tconst { text = '', placeholder = '', autoClose = true, align = 'top', justify = 'center', buttonConfirm, buttonCancel } = options;\n\n\t\t$$invalidate(60, userTextInput = {\n\t\t\t// settings\n\t\t\talign,\n\t\t\tjustify,\n\t\t\ttext,\n\t\t\tplaceholder,\n\t\t\tbuttonConfirm,\n\t\t\tbuttonCancel,\n\t\t\t// resolve with entered text\n\t\t\tonconfirm: () => {\n\t\t\t\t// no error, pass text\n\t\t\t\tconfirm(userTextInputField.value);\n\n\t\t\t\tif (autoClose) $$invalidate(60, userTextInput = undefined);\n\t\t\t},\n\t\t\t// close on reject\n\t\t\toncancel: () => {\n\t\t\t\t// no error, pass undefined for cancel\n\t\t\t\tcancel(undefined);\n\n\t\t\t\t// always auto closes on cancel\n\t\t\t\t$$invalidate(60, userTextInput = undefined);\n\t\t\t}\n\t\t});\n\t};\n\n\tlet { imagePreviewSrc = undefined } = $$props;\n\tlet { imageOrienter = { read: () => 1, apply: v => v } } = $$props;\n\tlet { pluginComponents = undefined } = $$props;\n\tlet { pluginOptions = {} } = $$props;\n\tconst sub = eventProxy.sub;\n\tconst pluginInterface = {};\n\tlet { root } = $$props;\n\n\t// used to update the image preview texture to show the current frame\n\tconst redrawPreview = () => {\n\t\t$imagePreview.setAttribute('data-redraw', 'true');\n\t\tredrawTrigger.set({});\n\t};\n\n\tconst allowPlayPause = writable(true);\n\tcomponent_subscribe($$self, allowPlayPause, value => $$invalidate(489, $allowPlayPause = value));\n\tconst videoFramePeekOffset = writable(undefined);\n\tcomponent_subscribe($$self, videoFramePeekOffset, value => $$invalidate(432, $videoFramePeekOffset = value));\n\tconst videoFrameOffset = writable(0);\n\tcomponent_subscribe($$self, videoFrameOffset, value => $$invalidate(429, $videoFrameOffset = value));\n\tconst videoIsPlaying = writable(false);\n\tconst initFrameOffset = () => videoFrameOffset.set(getCurrentTime() / getDuration());\n\n\tconst updatePlayState = e => {\n\t\tvideoIsPlaying.set(e.type === 'play');\n\t\teventProxy.pub(e.type);\n\t};\n\n\tlet prevTime;\n\tlet prevUpdateFrameRequestTimestamp;\n\n\tconst didUpdateFrame = offset => {\n\t\t// in play mode updating the frame is done without seeking\n\t\tif (!isPaused()) return;\n\n\t\tconst updateFrameRequestTimestamp = Date.now();\n\t\tif (prevUpdateFrameRequestTimestamp && updateFrameRequestTimestamp - prevUpdateFrameRequestTimestamp < frameUpdateRequestDist) return;\n\t\tprevUpdateFrameRequestTimestamp = updateFrameRequestTimestamp;\n\n\t\t// selected time in video\n\t\tconst time = $mediaDuration * offset;\n\n\t\t// only accept frame offset with a certain precision\n\t\tif (time.toFixed(1) === prevTime) return;\n\n\t\t// remember so we can skip duplicate offsets\n\t\tprevTime = time.toFixed(1);\n\n\t\t// when frame found, update preview\n\t\tconst video = $imagePreview;\n\n\t\tconst onseeked = () => {\n\t\t\tvideo.removeEventListener('seeked', onseeked);\n\t\t\tredrawPreview();\n\t\t};\n\n\t\tvideo.addEventListener('seeked', onseeked);\n\n\t\t// seek new point\n\t\tfastSeek(video, time);\n\t};\n\n\tlet videoDidEnterClip = false;\n\tlet videoAnimationFrame;\n\tlet videoPlayStartClipIndex;\n\n\tconst play = () => {\n\t\tif (!isVideoSupported || !isPaused()) return;\n\n\t\t// we store this so we know if we need to stop when reaching end of clip\n\t\tvideoPlayStartClipIndex = videoTrimCurrentIndex;\n\n\t\t// stop using peek offset\n\t\tset_store_value(videoFramePeekOffset, $videoFramePeekOffset = undefined, $videoFramePeekOffset);\n\n\t\t// reference to prevent issues with svelte set store value function\n\t\tconst video = $imagePreview;\n\n\t\t// start outside clip if current clip index is not set\n\t\tvideoDidEnterClip = false;\n\n\t\t// start from beginning if is at the end of video clip when pressing play\n\t\tconst frameDist = 1 / 24;\n\n\t\tconst duration = getDuration();\n\t\tconst isAtEdgeOfLastTrim = Math.abs(videoTrimLast * duration - $videoFrameOffset * duration) <= frameDist;\n\t\tconst isAtEndOfVideo = duration - duration * $videoFrameOffset <= frameDist;\n\n\t\tif (isAtEdgeOfLastTrim) {\n\t\t\tset_store_value(videoFrameOffset, $videoFrameOffset = videoTrimFirst, $videoFrameOffset);\n\t\t} else if (isAtEndOfVideo) {\n\t\t\tset_store_value(videoFrameOffset, $videoFrameOffset = 0, $videoFrameOffset);\n\t\t}\n\n\t\t// skip to frame location\n\t\tsetCurrentTime($videoFrameOffset * getDuration());\n\n\t\t// start playing\n\t\tvideo.play().catch(() => {\n\t\t\t\n\t\t}); // paused before could start playing, silence this error for now\n\n\t\t// draw loop\n\t\tconst draw = () => {\n\t\t\t// is paused\n\t\t\tif (isPaused()) return;\n\n\t\t\tconst stickToClips = videoPlayStartClipIndex >= 0;\n\n\t\t\t// next loop\n\t\t\tvideoAnimationFrame = requestAnimationFrame(draw);\n\n\t\t\t// get now\n\t\t\tconst currentTime = getCurrentTime();\n\n\t\t\t// update ui\n\t\t\tset_store_value(videoFrameOffset, $videoFrameOffset = Math.min(currentTime / getDuration(), 1), $videoFrameOffset);\n\n\t\t\tif (stickToClips && $videoFrameOffset >= videoTrimLast) {\n\t\t\t\t// pause when hits last frame\n\t\t\t\tset_store_value(videoFrameOffset, $videoFrameOffset = videoTrimLast, $videoFrameOffset);\n\n\t\t\t\tpause();\n\t\t\t}\n\n\t\t\t// we played a clip so we'll now skip to next clips when reaching end of clip\n\t\t\tif (videoTrimCurrentIndex > -1) {\n\t\t\t\tvideoDidEnterClip = true;\n\t\t\t}\n\n\t\t\t// skip to next clip if at end of current clip\n\t\t\tif (stickToClips && videoDidEnterClip && videoTrimCurrentIndex === -1 && videoTrimNextIndex > 0) {\n\t\t\t\tset_store_value(videoFrameOffset, $videoFrameOffset = videoTrim[videoTrimNextIndex][0], $videoFrameOffset);\n\t\t\t\tsetCurrentTime($videoFrameOffset * getDuration());\n\t\t\t}\n\n\t\t\t// pause when hits end of video\n\t\t\tif ($videoFrameOffset >= 1) {\n\t\t\t\tpause();\n\t\t\t}\n\n\t\t\t// update image state prop\n\t\t\tset_store_value(mediaCurrentTime, $mediaCurrentTime = $videoFrameOffset * getDuration(), $mediaCurrentTime);\n\n\t\t\t// draw frame\n\t\t\tredrawPreview();\n\t\t};\n\n\t\t// go!\n\t\tdraw();\n\t};\n\n\tconst pause = () => {\n\t\tif (!isVideoSupported || isPaused()) return;\n\t\tset_store_value(videoFramePeekOffset, $videoFramePeekOffset = undefined, $videoFramePeekOffset);\n\t\tvideoPlayStartClipIndex = undefined;\n\t\t$imagePreview.pause();\n\t\tcancelAnimationFrame(videoAnimationFrame);\n\t\tredrawPreview();\n\t};\n\n\tconst isPaused = () => $imagePreview && $imagePreview.paused;\n\n\tconst togglePlayPause = () => {\n\t\tif (!isVideoSupported) return;\n\t\treturn isPaused() ? play() : pause();\n\t};\n\n\tconst mute = () => {\n\t\tif (!isVideoSupported) return;\n\t\tconst video = $imagePreview;\n\t\tvideo.muted = true;\n\t};\n\n\tconst unmute = () => {\n\t\tif (!isVideoSupported) return;\n\t\tconst video = $imagePreview;\n\t\tvideo.muted = false;\n\t};\n\n\tconst toggleMute = () => {\n\t\tif (!isVideoSupported) return;\n\t\tset_store_value(isMuted, $isMuted = !$isMuted, $isMuted);\n\t};\n\n\tconst isMuted = writable(muteAudio);\n\tcomponent_subscribe($$self, isMuted, value => $$invalidate(431, $isMuted = value));\n\n\tconst getDuration = () => {\n\t\tif (!isVideoSupported) return;\n\t\treturn $imagePreview.duration;\n\t};\n\n\tconst getCurrentTime = () => {\n\t\tif (!isVideoSupported) return;\n\t\tconst video = $imagePreview;\n\t\treturn video.currentTime;\n\t};\n\n\tconst setCurrentTime = time => {\n\t\tif (!isVideoSupported) return;\n\t\tfastSeek($imagePreview, time);\n\t\tset_store_value(videoFrameOffset, $videoFrameOffset = time / $mediaDuration, $videoFrameOffset);\n\t};\n\n\tconst setVolume = volume => {\n\t\tif (!isVideoSupported) return;\n\t\tconst video = $imagePreview;\n\t\tvideo.volume = Math.min(1, volume);\n\t};\n\n\t// setup redraw store\n\tconst redrawTrigger = writable({});\n\n\tcomponent_subscribe($$self, redrawTrigger, value => $$invalidate(52, $redrawTrigger = value));\n\tsetContext('redrawTrigger', redrawTrigger);\n\tconst elasticityMultiplierStore = writable(elasticityMultiplier);\n\tcomponent_subscribe($$self, elasticityMultiplierStore, value => $$invalidate(506, $elasticityMultiplierStore = value));\n\tsetContext('elasticityMultiplier', elasticityMultiplierStore);\n\tlet registeredPluginsComponents = [];\n\n\t// editor disabled spring for animating in and out disabled state\n\tconst disabledTransition = spring();\n\n\tcomponent_subscribe($$self, disabledTransition, value => $$invalidate(102, $disabledTransition = value));\n\n\t// this method is used to read image resources (preview image / shape images)\n\tconst glMaxTextureSize = getWebGLTextureSizeLimit() || 1024;\n\n\tconst maxTextureSize = sizeCreate(glMaxTextureSize, glMaxTextureSize);\n\tconst canvasMemoryLimit = getCanvasMemoryLimit();\n\n\tconst fetchSrc = src => Promise.resolve($willRequest && $willRequest(src, { resourceType: 'image' })).then(requestInit => {\n\t\t// do something with options\n\t\tif (requestInit === false) return;\n\n\t\t// get props\n\t\tconst { headers, credentials } = requestInit || {};\n\n\t\t// fetch\n\t\treturn fetch(src, { headers, credentials }).then(res => {\n\t\t\tif (res.status !== 200) throw `${res.status} (${res.statusText})`;\n\t\t\treturn res.blob();\n\t\t}).then(blob => blobToImageBitmap(blob, { imageOrienter, canvasMemoryLimit })).then(imageData => imageDataContain(imageData, maxImageDataSize));\n\t});\n\n\tlet { imageSourceToImageData = src => isString(src)\n\t? // it's a url src\n\t\tfetchSrc(src)\n\t: isElement(src)\n\t\t? // assume src is a <canvas>\n\t\t\tnew Promise(resolve => resolve(canvasToImageData(src)))\n\t\t: // assume src is a File or Blob\n\t\t\tisBlob(src) || isFile(src)\n\t\t\t? blobToImageBitmap(src, { imageOrienter, canvasMemoryLimit }).then(imageData => imageDataContain(imageData, maxImageDataSize))\n\t\t\t: undefined } = $$props;\n\n\tconst imageProxy = createImageProxy();\n\tconst { file: imageFile, size: imageSize, duration: mediaDuration, currentTime: mediaCurrentTime, trim: mediaTrim, volume: mediaVolume, minDuration: mediaMinDuration, maxDuration: mediaMaxDuration, loadState: imageLoadState, processState: imageProcessState, cropAspectRatio: imageCropAspectRatio, cropLimitToImage: imageCropLimitToImage, crop: imageCropRect, cropMinSize: imageCropMinSize, cropMaxSize: imageCropMaxSize, cropRange: imageCropRange, cropOrigin: imageCropRectOrigin, cropRectAspectRatio: imageCropRectAspectRatio, rotation: imageRotation, rotationRange: imageRotationRange, targetSize: imageOutputSize, flipX: imageFlipX, flipY: imageFlipY, backgroundColor: imageBackgroundColor, backgroundImage: imageBackgroundImageSrc, backgroundFilterMode: imageBackgroundFilterMode, colorMatrix: imageColorMatrix, convolutionMatrix: imageConvolutionMatrix, gamma: imageGamma, vignette: imageVignette, noise: imageNoise, decoration: imageDecoration, annotation: imageAnnotation, manipulation: imageManipulation, redaction: imageRedaction, frame: imageFrame, selection: imageSelection, state: imageState } = imageProxy.stores;\n\tcomponent_subscribe($$self, imageFile, value => $$invalidate(406, $imageFile = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(380, $imageSize = value));\n\tcomponent_subscribe($$self, mediaDuration, value => $$invalidate(430, $mediaDuration = value));\n\tcomponent_subscribe($$self, mediaCurrentTime, value => $$invalidate(505, $mediaCurrentTime = value));\n\tcomponent_subscribe($$self, mediaTrim, value => $$invalidate(427, $mediaTrim = value));\n\tcomponent_subscribe($$self, mediaVolume, value => $$invalidate(428, $mediaVolume = value));\n\tcomponent_subscribe($$self, mediaMaxDuration, value => $$invalidate(433, $mediaMaxDuration = value));\n\tcomponent_subscribe($$self, imageLoadState, value => $$invalidate(398, $imageLoadState = value));\n\tcomponent_subscribe($$self, imageProcessState, value => $$invalidate(397, $imageProcessState = value));\n\tcomponent_subscribe($$self, imageCropAspectRatio, value => $$invalidate(502, $imageCropAspectRatio = value));\n\tcomponent_subscribe($$self, imageCropLimitToImage, value => $$invalidate(85, $imageCropLimitToImage = value));\n\tcomponent_subscribe($$self, imageCropRect, value => $$invalidate(417, $imageCropRect = value));\n\tcomponent_subscribe($$self, imageRotation, value => $$invalidate(383, $imageRotation = value));\n\tcomponent_subscribe($$self, imageFlipX, value => $$invalidate(382, $imageFlipX = value));\n\tcomponent_subscribe($$self, imageFlipY, value => $$invalidate(381, $imageFlipY = value));\n\tcomponent_subscribe($$self, imageBackgroundColor, value => $$invalidate(388, $imageBackgroundColor = value));\n\tcomponent_subscribe($$self, imageDecoration, value => $$invalidate(48, $imageDecoration = value));\n\tcomponent_subscribe($$self, imageAnnotation, value => $$invalidate(49, $imageAnnotation = value));\n\tcomponent_subscribe($$self, imageManipulation, value => $$invalidate(385, $imageManipulation = value));\n\tcomponent_subscribe($$self, imageRedaction, value => $$invalidate(386, $imageRedaction = value));\n\tcomponent_subscribe($$self, imageFrame, value => $$invalidate(47, $imageFrame = value));\n\tcomponent_subscribe($$self, imageSelection, value => $$invalidate(59, $imageSelection = value));\n\tcomponent_subscribe($$self, imageState, value => $$invalidate(491, $imageState = value));\n\n\t// allows sharing components with externally loaded plugins (video extension)\n\tsetContext('components', { DynamicComponentTree: DynamicComponentTree_1 });\n\n\t// share video controls with video extension\n\tsetContext('previewcontrols', {\n\t\tplay,\n\t\tpause,\n\t\ttogglePlayPause,\n\t\tmute,\n\t\tunmute,\n\t\ttoggleMute,\n\t\tsetCurrentTime,\n\t\tgetCurrentTime,\n\t\tgetDuration,\n\t\tframeOffset: videoFrameOffset,\n\t\tframePeekOffset: videoFramePeekOffset,\n\t\tisPlaying: videoIsPlaying,\n\t\tisMuted\n\t});\n\n\tconst createImageSrcLoader = (src, token, minDuration = 0) => new Promise((resolve, reject) => {\n\t\t\t// is a video\n\t\t\tif (isVideoFile(src)) {\n\t\t\t\tblobToVideo(src).then(video => {\n\t\t\t\t\t// get time offset\n\t\t\t\t\tconst time = isNumber($mediaCurrentTime)\n\t\t\t\t\t? $mediaCurrentTime\n\t\t\t\t\t: willSetMediaInitialTimeOffset(video.duration, $mediaTrim || [[0, 1]]);\n\n\t\t\t\t\t// seek to initial time\n\t\t\t\t\tseekTo(video, time).then(resolve);\n\t\t\t\t}).catch(reject);\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet cancelled = false;\n\t\t\tlet timer;\n\t\t\ttoken.cancel = () => cancelled = true;\n\t\t\tconst now = Date.now();\n\n\t\t\timageSourceToImageData(src).then(imageData => {\n\t\t\t\tconst dist = Date.now() - now;\n\t\t\t\tclearTimeout(timer);\n\n\t\t\t\ttimer = setTimeout(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tresolve(imageData);\n\t\t\t\t\t},\n\t\t\t\t\tMath.max(0, minDuration - dist)\n\t\t\t\t);\n\t\t\t}).catch(reject);\n\t\t});\n\n\tconst { images, shapePreprocessor, imageScrambler, imageRedactionRendering, willRequest, willRequestResource, csp } = stores;\n\tcomponent_subscribe($$self, images, value => $$invalidate(426, $images = value));\n\tcomponent_subscribe($$self, shapePreprocessor, value => $$invalidate(425, $shapePreprocessor = value));\n\tcomponent_subscribe($$self, imageScrambler, value => $$invalidate(389, $imageScrambler = value));\n\tcomponent_subscribe($$self, imageRedactionRendering, value => $$invalidate(387, $imageRedactionRendering = value));\n\tcomponent_subscribe($$self, willRequest, value => $$invalidate(81, $willRequest = value));\n\tcomponent_subscribe($$self, willRequestResource, value => $$invalidate(93, $willRequestResource = value));\n\tcomponent_subscribe($$self, csp, value => $$invalidate(92, $csp = value));\n\tlet backgroundImageDataCancelToken;\n\n\tconst imageBackgroundImageData = derived(imageBackgroundImageSrc, ($backgroundImageSrc, set) => {\n\t\tif (!$backgroundImageSrc) return set(undefined);\n\n\t\t// cancel existing loader\n\t\tif (backgroundImageDataCancelToken) {\n\t\t\tbackgroundImageDataCancelToken.cancel();\n\t\t\tbackgroundImageDataCancelToken = undefined;\n\t\t}\n\n\t\t// new cancel token\n\t\tbackgroundImageDataCancelToken = { cancel: noop$1 };\n\n\t\tcreateImageSrcLoader($backgroundImageSrc, backgroundImageDataCancelToken).then(set).catch(err => {\n\t\t\t// log to console for debugging purposes\n\t\t});\n\t});\n\n\t// let the world know about state changes\n\tconst imageStateUnsub = imageState.subscribe(state => eventProxy.pub('update', state));\n\n\t// this will hold the currently selected util\n\tconst utilSelectedStore = writable();\n\n\t// current editor UI state\n\tconst uiState = writable({});\n\n\tsetContext('ui', uiState);\n\n\t// image selection state\n\tsetContext('selection', imageSelection);\n\n\t// utils can toggle pan and zoom\n\tconst allowPan = writable(true);\n\n\tcomponent_subscribe($$self, allowPan, value => $$invalidate(95, $allowPan = value));\n\tconst allowZoom = writable(true);\n\tcomponent_subscribe($$self, allowZoom, value => $$invalidate(97, $allowZoom = value));\n\tconst allowZoomControls = writable(true);\n\tcomponent_subscribe($$self, allowZoomControls, value => $$invalidate(424, $allowZoomControls = value));\n\tconst enablePanInputStore = writable(true);\n\tcomponent_subscribe($$self, enablePanInputStore, value => $$invalidate(503, $enablePanInputStore = value));\n\tconst enableZoomInputStore = writable(true);\n\tcomponent_subscribe($$self, enableZoomInputStore, value => $$invalidate(98, $enableZoomInputStore = value));\n\n\t// so controls can be disabled from other component\n\tconst enableZoomControlsProp = writable();\n\n\tcomponent_subscribe($$self, enableZoomControlsProp, value => $$invalidate(99, $enableZoomControlsProp = value));\n\n\t// so we can derive pan input status\n\tconst enablePanInputProp = writable();\n\n\tcomponent_subscribe($$self, enablePanInputProp, value => $$invalidate(504, $enablePanInputProp = value));\n\n\t// current pan input status\n\tconst enablePanInputStatus = derived([enablePanInputProp, enablePanInputStore], (() => $enablePanInputProp !== undefined\n\t? $enablePanInputProp\n\t: $enablePanInputStore));\n\n\tcomponent_subscribe($$self, enablePanInputStatus, value => $$invalidate(96, $enablePanInputStatus = value));\n\n\t//\n\t// handles the view rect size, makes sure it is offset from the top\n\t//\n\t// root element reference used to read styles\n\tconst rootBackgroundColor = writable([0, 0, 0]);\n\n\tcomponent_subscribe($$self, rootBackgroundColor, value => $$invalidate(56, $rootBackgroundColor = value));\n\tconst rootForegroundColor = writable([1, 1, 1]);\n\tcomponent_subscribe($$self, rootForegroundColor, value => $$invalidate(487, $rootForegroundColor = value));\n\tconst rootLineColor = spring([1, 1, 1]);\n\tcomponent_subscribe($$self, rootLineColor, value => $$invalidate(486, $rootLineColor = value));\n\tconst rootColorPrimary = writable();\n\tcomponent_subscribe($$self, rootColorPrimary, value => $$invalidate(91, $rootColorPrimary = value));\n\tconst rootColorSecondary = writable();\n\n\t// client rect is the editor rect excluding scroll offset\n\tconst clientRect = writable();\n\n\tcomponent_subscribe($$self, clientRect, value => $$invalidate(51, $clientRect = value));\n\n\t// root rect is the editor rect including scroll offset\n\tconst rootRect = writable();\n\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(378, $rootRect = value));\n\n\t// when in overlay mode force aspect ratio to aspect ratio of editor root\n\tconst syncRootAspectRatio = () => {\n\t\t// get current aspect ratio and get next aspect ratio, compare, if different, reset\n\t\tconst currentAspectRatio = $imageCropAspectRatio;\n\n\t\tconst nextAspectRatio = rectAspectRatio($rootRect);\n\t\tif (currentAspectRatio && currentAspectRatio === nextAspectRatio) return;\n\n\t\t// set aspect ratio\n\t\timageCropAspectRatio.set(rectAspectRatio($rootRect));\n\n\t\t// need to set history 0 point to this state\n\t\tsetInitialHistoryState();\n\t};\n\n\tconst tabRect = writable(rectCreateEmpty());\n\tcomponent_subscribe($$self, tabRect, value => $$invalidate(80, $tabRect = value));\n\tconst rootInsetTop = writable(0);\n\tcomponent_subscribe($$self, rootInsetTop, value => $$invalidate(423, $rootInsetTop = value));\n\n\t// const rootInsetBottom = writable(0); // not needed yet\n\tconst toolRect = writable(rectCreateEmpty());\n\n\tcomponent_subscribe($$self, toolRect, value => $$invalidate(84, $toolRect = value));\n\tconst utilRect = writable(); // is undefined because we wait till util is set before defining stage rect\n\tcomponent_subscribe($$self, utilRect, value => $$invalidate(484, $utilRect = value));\n\n\t//\n\t// environment\n\t//\n\tconst pointerAccuracy = mediaQueryStore('(pointer: fine)', matches => matches ? 'pointer-fine' : 'pointer-coarse');\n\n\tcomponent_subscribe($$self, pointerAccuracy, value => $$invalidate(404, $pointerAccuracy = value));\n\tconst pointerHoverable = mediaQueryStore('(hover: hover)', matches => matches ? 'pointer-hover' : 'pointer-no-hover');\n\tcomponent_subscribe($$self, pointerHoverable, value => $$invalidate(403, $pointerHoverable = value));\n\n\t//\n\t// app API\n\t//\n\tconst isTransformingImage = writable(false);\n\n\tconst isInteracting = writable(false);\n\tcomponent_subscribe($$self, isInteracting, value => $$invalidate(384, $isInteracting = value));\n\n\tconst isInteractingFraction = readable(undefined, set => {\n\t\tconst animator = spring(0);\n\n\t\tconst updater = value => {\n\t\t\tanimator.set(value ? 1 : 0, { hard: !$isAnimated });\n\t\t};\n\n\t\tconst subs = [isInteracting.subscribe(updater), animator.subscribe(set)];\n\n\t\t// destroy subs\n\t\treturn () => subs.forEach(unsub => unsub());\n\t});\n\n\tcomponent_subscribe($$self, isInteractingFraction, value => $$invalidate(485, $isInteractingFraction = value));\n\n\t// create animation stores\n\tconst shouldAnimate = writable();\n\n\tcomponent_subscribe($$self, shouldAnimate, value => $$invalidate(490, $shouldAnimate = value));\n\tconst isAnimated = writable();\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(53, $isAnimated = value));\n\n\t// Animations based on prefers-reduced-motion, automatically checks if user prefers reduced animations\n\tsetContext('isAnimated', isAnimated);\n\n\t// this makes sure animations don't run right after the editor is recovering from zero size state\n\tlet canRenderDelayed;\n\n\tconst previewShouldUpscale = writable(previewUpscale);\n\tcomponent_subscribe($$self, previewShouldUpscale, value => $$invalidate(407, $previewShouldUpscale = value));\n\n\t//\n\t// image related\n\t//\n\tconst imageIsStatic = writable(false); // if is set to true image is selection is dragged\n\n\tcomponent_subscribe($$self, imageIsStatic, value => $$invalidate(496, $imageIsStatic = value));\n\tsetContext('imageIsStatic', imageIsStatic);\n\tconst imageCropRectSnapshot = writable();\n\tcomponent_subscribe($$self, imageCropRectSnapshot, value => $$invalidate(497, $imageCropRectSnapshot = value));\n\tconst imageCropRectIntent = writable(); // should always be set before setting `imageCropRect`\n\tcomponent_subscribe($$self, imageCropRectIntent, value => $$invalidate(494, $imageCropRectIntent = value));\n\n\tconst imageCropRectPresentation = readable(undefined, set => {\n\t\tconst animator = writable(undefined);\n\n\t\tconst update = () => {\n\t\t\tif (!$imageCropRect) return;\n\n\t\t\t// no elasticity needed when dragging crop selection\n\t\t\tif ($imageIsStatic) return animator.set(rectClone($imageCropRect));\n\n\t\t\t// apply elasticity\n\t\t\tconst elasticRect = elastifyRects($imageCropRect, $imageCropRectIntent, imageCropRectElasticity * elasticityMultiplier);\n\n\t\t\tanimator.set(elasticRect);\n\t\t};\n\n\t\tconst subs = [\n\t\t\t// need to update presentation rect when crop rect is updated\n\t\t\timageCropRect.subscribe(update),\n\t\t\t// update parent store\n\t\t\tanimator.subscribe(set)\n\t\t];\n\n\t\treturn () => subs.forEach(unsub => unsub());\n\t});\n\n\tconst imageSelectionRect = writable();\n\tcomponent_subscribe($$self, imageSelectionRect, value => $$invalidate(493, $imageSelectionRect = value));\n\tconst imageSelectionRectSnapshot = writable();\n\tcomponent_subscribe($$self, imageSelectionRectSnapshot, value => $$invalidate(495, $imageSelectionRectSnapshot = value));\n\tconst imageSelectionRectIntent = writable(undefined); // should always be set before setting `imageSelectionRect`\n\tcomponent_subscribe($$self, imageSelectionRectIntent, value => $$invalidate(500, $imageSelectionRectIntent = value));\n\tconst imageSelectionRectOffset = writable(vectorCreateEmpty());\n\tcomponent_subscribe($$self, imageSelectionRectOffset, value => $$invalidate(501, $imageSelectionRectOffset = value));\n\n\tconst getFrameOutset = (presentationRect, imageFrame) => {\n\t\tif (!imageFrame || !presentationRect) return { top: 0, right: 0, bottom: 0, left: 0 };\n\t\tconst shapes = shapesFromCompositShape(imageFrame, presentationRect, preprocessShape);\n\t\tconst bounds = shapesBounds(shapes, presentationRect);\n\n\t\treturn {\n\t\t\ttop: Math.abs(bounds.top),\n\t\t\tright: Math.abs(bounds.right),\n\t\t\tbottom: Math.abs(bounds.bottom),\n\t\t\tleft: Math.abs(bounds.left)\n\t\t};\n\t};\n\n\t// let stageRecenterPrev;\n\tconst stageRecenter = writable({});\n\n\tconst stageRectBase = derived([utilRect, tabRect, toolRect, stageRecenter], ([$utilRect, $tabRect, $toolRect, $stageRecenter], set) => {\n\t\tif (!$utilRect) return set(undefined);\n\t\tlet utilOffsetY = 0;\n\n\t\t// if only one util active, we don't have util tabs, so add additional offset\n\t\tif (utilsFiltered.length === 1 && !isOverlayModeEnabled && layoutVerticalToolbarPreference !== 'bottom') {\n\t\t\tutilOffsetY = $toolRect.y + $toolRect.height;\n\t\t}\n\n\t\tset(rectCreate($utilRect.x + $tabRect.x, $utilRect.y + $tabRect.y + utilOffsetY, $utilRect.width, $utilRect.height));\n\t});\n\n\tlet prevStagePadding = { left: 0, right: 0, top: 0, bottom: 0 };\n\tconst shouldPadPreview = writable(false);\n\n\tconst stagePadding = derived([shouldPadPreview, imageFrame, stageRectBase, isInteracting], ([$shouldPadPreview, $imageFrame, $stageRectBase, $isInteracting], set) => {\n\t\tif (!$stageRectBase) {\n\t\t\treturn set({ left: 0, right: 0, top: 0, bottom: 0 });\n\t\t}\n\n\t\t// exit\n\t\tif (!$shouldPadPreview) return;\n\n\t\t// a sane default padding around a frame\n\t\tconst size = Math.min($stageRectBase.width, $stageRectBase.height);\n\n\t\t// set frame padding\n\t\tconst newStagePadding = getFrameOutset({ width: size, height: size }, $imageFrame);\n\n\t\t// exit if no value changes\n\t\tif (fixPrecision(prevStagePadding.top, 4) === fixPrecision(newStagePadding.top, 4) && fixPrecision(prevStagePadding.bottom, 4) === fixPrecision(newStagePadding.bottom, 4) && fixPrecision(prevStagePadding.right, 4) === fixPrecision(newStagePadding.right, 4) && fixPrecision(prevStagePadding.left, 4) === fixPrecision(newStagePadding.left, 4)) return;\n\n\t\tprevStagePadding = newStagePadding;\n\t\tset(newStagePadding);\n\t});\n\n\tcomponent_subscribe($$self, stagePadding, value => $$invalidate(415, $stagePadding = value));\n\n\tconst stagePadded = derived([shouldPadPreview, stagePadding], ([$shouldPadPreview, $stagePadding], set) => {\n\t\tif (!$shouldPadPreview) return set(false);\n\t\tset(Object.values($stagePadding).some(value => value > 0));\n\t});\n\n\tcomponent_subscribe($$self, stagePadded, value => $$invalidate(416, $stagePadded = value));\n\n\tconst utilRectPadded = derived([shouldPadPreview, utilRect, stagePadded, stagePadding], ([$shouldPadPreview, $utilRect, $stagePadded, $stagePadding], set) => {\n\t\tif (!$utilRect) return;\n\t\tif (!$shouldPadPreview || !$stagePadded) return set({ ...$utilRect });\n\t\tset(rectCreate($utilRect.x + $stagePadding.left, $utilRect.y + $stagePadding.top, $utilRect.width - $stagePadding.left - $stagePadding.right, $utilRect.height - $stagePadding.top - $stagePadding.bottom));\n\t});\n\n\tconst stageRect = derived([stageRectBase, stagePadded, stagePadding], ([$stageRectBase, $stagePadded, $stagePadding], set) => {\n\t\tif (!$stageRectBase) return set(undefined);\n\t\tif (!$stagePadded) return set($stageRectBase);\n\t\tset(rectCreate($stageRectBase.x + $stagePadding.left, $stageRectBase.y + $stagePadding.top, $stageRectBase.width - $stagePadding.left - $stagePadding.right, $stageRectBase.height - $stagePadding.top - $stagePadding.bottom));\n\t});\n\n\tcomponent_subscribe($$self, stageRect, value => $$invalidate(50, $stageRect = value));\n\n\tconst imageStaticCorners = derived([imageIsStatic, imageSize, imageRotation], ([$imageIsStatic, $imageSize, $imageRotation], set) => {\n\t\t// no need for bounds measuring if is not static image\n\t\tif (!$imageIsStatic || !$imageSize) return set(undefined);\n\n\t\tconst rect = rectCreateFromSize($imageSize);\n\t\tconst rectRotatedCorners = rectRotate(rect, $imageRotation);\n\t\tset(rectRotatedCorners);\n\t});\n\n\tconst imageStaticBounds = derived([imageStaticCorners], ([$imageStaticCorners], set) => {\n\t\tif (!$imageStaticCorners) return set(undefined);\n\t\tconst rectRotated = rectCreateFromPoints($imageStaticCorners);\n\t\tset(rectNormalizeOffset(rectRotated));\n\t});\n\n\tcomponent_subscribe($$self, imageStaticBounds, value => $$invalidate(419, $imageStaticBounds = value));\n\n\tconst stageScalar = derived([stageRect, imageCropRect, imageStaticBounds, previewShouldUpscale], ([$stageRect, $imageCropRect, $imageStaticBounds, $previewShouldUpscale], set) => {\n\t\tconst isManipulatingImageCropRect = !!($imageCropRectSnapshot || $imageCropRectIntent);\n\n\t\t// update stage scalar, the crop output size relative to the stage, if image fits it's 1\n\t\tif (!$stageRect || !$imageCropRect || isManipulatingImageCropRect) return;\n\n\t\t// use image bounds instead of crop\n\t\tconst { width, height } = $imageStaticBounds || $imageCropRect;\n\n\t\t// calculate scale factor needed to fit crop rect to stage\n\t\tconst scalar = Math.min($stageRect.width / width, $stageRect.height / height);\n\n\t\t// always scaled down to fit stage, if is allowed to upscale, zoom to fit stage\n\t\tconst scale = $previewShouldUpscale ? scalar : Math.min(1, scalar);\n\n\t\tset(scale);\n\t});\n\n\tcomponent_subscribe($$self, stageScalar, value => $$invalidate(418, $stageScalar = value));\n\n\tconst imageStaticVisualCorners = derived([imageIsStatic, imageSize, imageRotation, stageRect, utilRect, stageScalar], ([\n\t\t\t$imageIsStatic,\n\t\t\t$imageSize,\n\t\t\t$imageRotation,\n\t\t\t$stageRect,\n\t\t\t$utilRect,\n\t\t\t$stageScalar\n\t\t], set) => {\n\t\t// no need for bounds measuring if is not static image\n\t\tif (!$imageIsStatic || !$stageRect || !$utilRect || !$imageSize) return set(undefined);\n\n\t\tconst rect = rectCreateFromSize($imageSize);\n\t\tconst rectScaled = rectNormalizeOffset(rectScale(rect, $stageScalar));\n\t\tconst rectCentered = rectCenterRect($stageRect, rectScaled);\n\t\trectScaled.x = rectCentered.x;\n\t\trectScaled.y = rectCentered.y;\n\t\tconst rectRotatedCorners = rectRotate(rectScaled, $imageRotation);\n\t\tset(rectRotatedCorners);\n\t});\n\n\tsetContext('imageStaticVisualCorners', imageStaticVisualCorners);\n\n\t//\n\t// Image selection\n\t//\n\tconst imageSelectionZoom = writable(undefined);\n\n\tcomponent_subscribe($$self, imageSelectionZoom, value => $$invalidate(421, $imageSelectionZoom = value));\n\n\tconst imageSelectionStageFitScalar = derived([imageCropRect, stageRect], ([$imageCropRect, $stageRect]) => {\n\t\t// wait a bit\n\t\tif (!$stageRect || !$imageCropRect) return undefined;\n\n\t\treturn Math.min($stageRect.width / $imageCropRect.width, $stageRect.height / $imageCropRect.height);\n\t});\n\n\tconst imageSelectionRectScalar = derived([imageCropRect, imageSelectionRect], ([$imageCropRect, $imageSelectionRect]) => {\n\t\t// wait a bit\n\t\tif (!$imageCropRect || !$imageSelectionRect) return 1;\n\n\t\treturn Math.min($imageCropRect.width / $imageSelectionRect.width, $imageCropRect.height / $imageSelectionRect.height);\n\t});\n\n\tcomponent_subscribe($$self, imageSelectionRectScalar, value => $$invalidate(101, $imageSelectionRectScalar = value));\n\n\tconst imageSelectionScalar = derived([imageSelectionZoom, imageSelectionRectScalar], ([$imageSelectionZoom, $imageSelectionRectScalar]) => {\n\t\t// wait a bit\n\t\tif (!$imageSelectionZoom || !$imageSelectionRectScalar) return 1;\n\n\t\t// calculate scalar  to get actual image size\n\t\treturn $imageSelectionRectScalar * $imageSelectionZoom;\n\t});\n\n\tcomponent_subscribe($$self, imageSelectionScalar, value => $$invalidate(499, $imageSelectionScalar = value));\n\tconst imageSelectionPan = writable(vectorCreateEmpty());\n\tcomponent_subscribe($$self, imageSelectionPan, value => $$invalidate(420, $imageSelectionPan = value));\n\n\tconst imageSelectionStoredState = writable({\n\t\tscalar: $imageSelectionScalar,\n\t\ttranslation: $imageSelectionPan\n\t});\n\n\tconst imageSelectionStoredStateReset = () => {\n\t\timageSelectionStoredState.set({\n\t\t\tscalar: undefined,\n\t\t\ttranslation: vectorCreateEmpty()\n\t\t});\n\t};\n\n\tconst imageSelectionRectPresentation = readable(undefined, set => {\n\t\tconst animator = spring(undefined, { precision: 0.0001 });\n\n\t\tconst snapPixels = getDevicePixelRatio() === 1\n\t\t? rect => rectApply(rect, Math.round)\n\t\t: passthrough;\n\n\t\tconst updater = () => {\n\t\t\tif (!$imageSelectionRect) return;\n\t\t\tconst instantUpdate = $isInteracting || !$shouldAnimate;\n\n\t\t\t// no elasticity needed if image is fixed\n\t\t\tif ($imageIsStatic) {\n\t\t\t\tconst rect = rectClone($imageSelectionRect);\n\t\t\t\trectTranslate(rect, $imageSelectionRectOffset);\n\t\t\t\trectTranslate(rect, $stageRect);\n\t\t\t\treturn animator.set(rect, { hard: instantUpdate });\n\t\t\t}\n\n\t\t\tconst elasticRect = elastifyRects($imageSelectionRect, $imageSelectionRectIntent, imageSelectionRectElasticity * elasticityMultiplier);\n\n\t\t\t// prevent negative size (can happen because of elastics)\n\t\t\tif (elasticRect.width < 0) {\n\t\t\t\telasticRect.width = 0;\n\t\t\t\telasticRect.x = $imageSelectionRect.x;\n\t\t\t}\n\n\t\t\tif (elasticRect.height < 0) {\n\t\t\t\telasticRect.height = 0;\n\t\t\t\telasticRect.y = $imageSelectionRect.y;\n\t\t\t}\n\n\t\t\t// translate elastic rect x,y by stage rect x,y\n\t\t\trectTranslate(elasticRect, $stageRect);\n\n\t\t\t// translate\n\t\t\trectTranslate(elasticRect, $imageSelectionPan);\n\n\t\t\t// scale to zoom in view\n\t\t\trectScale(elasticRect, $imageSelectionScalar);\n\n\t\t\t// round to pixels on low res displays\n\t\t\t!instantUpdate && snapPixels(elasticRect);\n\n\t\t\tanimator.set(elasticRect, { hard: instantUpdate });\n\t\t};\n\n\t\tconst subs = [\n\t\t\t// need to update selection rect when stage is resized\n\t\t\tstageRect.subscribe(updater),\n\t\t\t// listen for selection rect changes (as is assigned rect will always trigger, even if assigned same rect, this is needed to also update when intent changes)\n\t\t\timageSelectionRect.subscribe(updater),\n\t\t\t// if selection scalar changes need to update presentation\n\t\t\timageSelectionScalar.subscribe(updater),\n\t\t\timageSelectionPan.subscribe(updater),\n\t\t\t// need to update if frame exceeds bounds\n\t\t\timageFrame.subscribe(updater),\n\t\t\t// update parent store\n\t\t\tanimator.subscribe(set)\n\t\t];\n\n\t\t// destroy subs\n\t\treturn () => subs.forEach(unsub => unsub());\n\t});\n\n\tcomponent_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(58, $imageSelectionRectPresentation = value));\n\tconst imageSelectionRectStaticScalar = writable(1);\n\tcomponent_subscribe($$self, imageSelectionRectStaticScalar, value => $$invalidate(492, $imageSelectionRectStaticScalar = value));\n\n\tconst centerImageStaticBounds = () => {\n\t\tif (!$imageCropRect || !$stageRect) return;\n\t\tlet rect = rectMultiply(rectClone($imageCropRect), $stageScalar || 1);\n\t\tconst rectOffset = rectCenterRect($stageRect, rectMultiply(rectClone($imageStaticBounds), $stageScalar));\n\t\trectTranslate(rect, rectOffset);\n\t\tconst selectionScaledWidth = $utilRect.width / rect.width;\n\t\tconst selectionScaledHeight = $utilRect.height / rect.height;\n\t\tconst scalar = Math.min(1, selectionScaledWidth, selectionScaledHeight);\n\t\timageSelectionRectStaticScalar.set(scalar);\n\t\trectScale(rect, scalar);\n\n\t\t// limit selection rect to util bounds\n\t\trectOffsetInRect(rect, { ...$utilRect, x: 0, y: 0 });\n\n\t\timageSelectionRect.set(rect);\n\t};\n\n\t//\n\tconst imageSelectionRectCentered = derived([stageRect, stageScalar, imageCropRect, imageSize], ([$stageRect, $stageScalar, $imageCropRect, $imageSize], set) => {\n\t\t// not ready yet\n\t\tif (!$stageRect || !$imageCropRect && !$imageSize) return;\n\n\t\tset(getImageSelectionRectCentered($stageRect, $stageScalar || 1, $imageCropRect || $imageSize));\n\t});\n\n\tcomponent_subscribe($$self, imageSelectionRectCentered, value => $$invalidate(100, $imageSelectionRectCentered = value));\n\n\tconst getImageSelectionRectCentered = (stageRect, stageScalar, cropRect) => {\n\t\tconst imageCropRectFitsStage = cropRect.width <= stageRect.width && cropRect.height <= stageRect.height;\n\n\t\t// if we have a crop rect and it fits the stage, center it\n\t\treturn imageCropRectFitsStage\n\t\t? // center the crop rectangle to the stage\n\t\t\trectCenterRect(stageRect, rectMultiply(rectClone(cropRect), stageScalar))\n\t\t: // render a rectangle based on the fixed crop aspect ratio, or the aspect ratio of the current crop rectangle, or as a last resort the input image\n\t\t\trectContainRect(stageRect, rectAspectRatio(cropRect));\n\t};\n\n\t// when scaling the stage we need to recenter the image selection\n\tlet stageRectPrev;\n\n\tlet stageScalePrev;\n\n\tconst calculateImageSelectionRect = stageRectCurrent => {\n\t\t// don't recalculate if no change\n\t\tif (isOverlayModeEnabled && stageRectPrev && rectEqual(stageRectPrev, stageRectCurrent) && stageScalePrev === $stageScalar) return;\n\n\t\t// position relative to image itself\n\t\tif ($imageIsStatic) return centerImageStaticBounds();\n\n\t\t// remember so we can compare later on if has changed\n\t\tstageRectPrev = stageRectCurrent;\n\n\t\tstageScalePrev = $stageScalar;\n\t\tconst centeredImageSelectionRect = getImageSelectionRectCentered(stageRectCurrent, $stageScalar, $imageCropRect || $imageSize);\n\t\timageSelectionRect.set(centeredImageSelectionRect);\n\t};\n\n\t// this runs once so we use the correct scale for the initial image selection rect\n\tlet hasSetInitialStageScalar = false;\n\n\tconst stageScalarUnsub = stageScalar.subscribe(scalar => {\n\t\t// can't recalculate without these prosp\n\t\tif (hasSetInitialStageScalar || scalar === undefined || !$imageCropRect) return;\n\n\t\tcalculateImageSelectionRect($stageRect);\n\t\thasSetInitialStageScalar = true;\n\t});\n\n\t// this recenters the crop when the window/stage is resized\n\tconst stageRectUnsub = stageRect.subscribe(rect => {\n\t\t// can't recalculate without these prosp\n\t\tif (!rect || $stageScalar === undefined || !$imageCropRect) return;\n\n\t\tcalculateImageSelectionRect(rect);\n\t});\n\n\tconst imageIsStaticUnsub = imageIsStatic.subscribe(isStatic => {\n\t\tif (!isStatic && $stageRect) calculateImageSelectionRect($stageRect);\n\t});\n\n\t// if we've taken a snapshot of the selection, also take a snapshot of the crop rect and the presentationScalar\n\t// - cropRect so we can adjust it based on the adjustments to the imageSelectionRect\n\t// - presentationScalar so we can use the snapshot for the calculation of the cropRect scale relative to the original imageSelectionRect (if we use the live $presentationScalar small rounding errors of the scalar result in weird glitches)\n\tlet presentationScalarSnapshot;\n\n\tconst imageSelectionRectSnapshotUnsub = imageSelectionRectSnapshot.subscribe(rect => {\n\t\tif (!rect) {\n\t\t\tpresentationScalarSnapshot = undefined;\n\t\t\tset_store_value(imageCropRectSnapshot, $imageCropRectSnapshot = undefined, $imageCropRectSnapshot);\n\t\t\treturn;\n\t\t}\n\n\t\tpresentationScalarSnapshot = $presentationScalar;\n\t\tconst cropRectClone = rectClone($imageCropRect);\n\t\timageCropRectSnapshot.set(cropRectClone);\n\t});\n\n\t// if image selection rect is being manipulated, and imageSelectionRectSnapshot has been defined, we also need to update the crop rect\n\tconst imageSelectionRectUnsub = imageSelectionRect.subscribe(rect => {\n\t\t// only sync crop rect with image selection rect when no longer manipulating\n\t\tif (!rect || !$imageSelectionRectSnapshot) return;\n\n\t\tconst offset = rectSubtract(rectClone(rect), $imageSelectionRectSnapshot);\n\t\trectDivide(offset, presentationScalarSnapshot);\n\t\tconst crop = rectAdd(rectClone($imageCropRectSnapshot), offset);\n\t\timageCropRect.set(crop);\n\t});\n\n\tconst updateImageSelectionRect = rect => {\n\t\t// if no rect, we can't do anything\n\t\t// if no selection rect yet, we wait for a selection rect to be loaded\n\t\tif (!rect || !$imageSelectionRect) return;\n\n\t\t// if image is static we only have to keep centering it\n\t\tif ($imageIsStatic) {\n\t\t\tif (!$imageSelectionRectSnapshot) centerImageStaticBounds();\n\t\t\treturn;\n\t\t}\n\n\t\t// don't update image selection rect while we're intertacting with the view, this prevents feedback loop from cropRect model updates\n\t\tif ($isInteracting || $imageSelectionRectSnapshot || $imageCropRectIntent) return;\n\n\t\t// only if crop aspect ratio differs from image selection aspect ratio we update image selection rectangle\n\t\tconst imageSelectionRectAspectRatio = rectAspectRatio($imageSelectionRect);\n\n\t\tconst cropRectAspectRatio = rectAspectRatio(rect);\n\t\tif (fixPrecision(imageSelectionRectAspectRatio, 6) === fixPrecision(cropRectAspectRatio, 6)) return;\n\n\t\t// TEMP DUPLICATE OF STAGESCALAR DERIVED STORE TO FIX ZOOM OUT AFTER WHEEL ISSUE\n\t\t// reproduce -> crop view => resize selection rect vertically, tap recenter, zoom out with scroll wheel\n\t\tconst { width, height } = $imageCropRect;\n\n\t\tconst scalar = Math.min($stageRect.width / width, $stageRect.height / height);\n\t\tconst size = sizeCreate(rect.width * scalar, rect.height * scalar);\n\t\tconst tx = ($imageSelectionRect.width - size.width) * 0.5;\n\t\tconst ty = ($imageSelectionRect.height - size.height) * 0.5;\n\t\tconst selectionRect = rectCreate(Math.max(0, Math.min($stageRect.width - size.width, $imageSelectionRect.x + tx)), Math.max(0, Math.min($stageRect.height - size.height, $imageSelectionRect.y + ty)), size.width, size.height);\n\t\timageSelectionRect.set(selectionRect);\n\t};\n\n\tconst imageCropRectUnsub = imageCropRect.subscribe(updateImageSelectionRect);\n\n\tconst imageScalar = derived([stageScalar, imageCropRect, imageSelectionRect, imageIsStatic], ([$stageScalar, $imageCropRect, $imageSelectionRect, $imageIsStatic], set) => {\n\t\t// update the image scalar, the image zoom calculated by the image selection and the actual crop coordinates\n\t\tif (!$stageScalar || !$imageCropRect || !$imageSelectionRect) return;\n\n\t\t// if image static bound set, the image is always centered in view\n\t\tif ($imageIsStatic) return set($imageSelectionRectStaticScalar);\n\n\t\tconst selectionScaledWidth = $imageSelectionRect.width / $imageCropRect.width;\n\t\tconst selectionScaledHeight = $imageSelectionRect.height / $imageCropRect.height;\n\t\tconst scalar = Math.max(selectionScaledWidth, selectionScaledHeight) / $stageScalar;\n\t\tset(scalar);\n\t});\n\n\tconst presentationScalar = derived([stageScalar, imageScalar], ([$stageScalar, $imageScalar], set) => {\n\t\t// can't scale presentation if no image scalar defined\n\t\tif (!$imageScalar) return;\n\n\t\tconst scalar = $stageScalar * $imageScalar;\n\t\tset(scalar);\n\t});\n\n\tcomponent_subscribe($$self, presentationScalar, value => $$invalidate(498, $presentationScalar = value));\n\n\t//\n\t// UI Elements\n\t//\n\tlet prevFrameOutset = { left: 0, right: 0, top: 0, bottom: 0 };\n\n\tconst frameOutset = derived([imageFrame, imageSelectionRect], ([$imageFrame, $imageSelectionRect], set) => {\n\t\t// exit\n\t\tif (!$imageSelectionRect) return set(prevFrameOutset);\n\n\t\t// set frame padding\n\t\tconst newFrameOutset = getFrameOutset($imageSelectionRect, $imageFrame);\n\n\t\t// exit if no value changes\n\t\tif (fixPrecision(prevFrameOutset.top, 4) === fixPrecision(newFrameOutset.top, 4) && fixPrecision(prevFrameOutset.bottom, 4) === fixPrecision(newFrameOutset.bottom, 4) && fixPrecision(prevFrameOutset.right, 4) === fixPrecision(newFrameOutset.right, 4) && fixPrecision(prevFrameOutset.left, 4) === fixPrecision(newFrameOutset.left, 4)) return;\n\n\t\tprevFrameOutset = newFrameOutset;\n\t\tset(newFrameOutset);\n\t});\n\n\tconst frameHasOutset = derived([frameOutset], ([$frameOutset], set) => {\n\t\tset(Object.values($frameOutset).some(value => value > 0));\n\t});\n\n\tconst imageOutlineOpacity = spring(0.075, {\n\t\tstiffness: 0.03,\n\t\tdamping: 0.4,\n\t\tprecision: 0.001\n\t});\n\n\tconst imageOutline = derived(\n\t\t[\n\t\t\trootLineColor,\n\t\t\trootBackgroundColor,\n\t\t\timageOutlineOpacity,\n\t\t\timageSelectionRectPresentation,\n\t\t\timageSelectionScalar,\n\t\t\timageFrame,\n\t\t\tframeHasOutset,\n\t\t\tframeOutset,\n\t\t\tstagePadded\n\t\t],\n\t\t([\n\t\t\t\t$rootLineColor,\n\t\t\t\t$rootBackgroundColor,\n\t\t\t\t$colorOpacity,\n\t\t\t\t$rect,\n\t\t\t\t$rectScalar,\n\t\t\t\t$imageFrame,\n\t\t\t\t$frameHasOutset,\n\t\t\t\t$frameOutset,\n\t\t\t\t$stagePadded\n\t\t\t], set) => {\n\t\t\tif (!$rect || isOverlayModeEnabled) return set([]);\n\t\t\tlet { x, y, width, height } = $rect;\n\t\t\tx += 0.5;\n\t\t\ty += 0.5;\n\t\t\twidth -= 0.5;\n\t\t\theight -= 0.5;\n\t\t\tconst shapes = [];\n\n\t\t\tif ($imageFrame) {\n\t\t\t\t// draw dark or bright line around frame to make it stand out from background\n\t\t\t\tif ($frameHasOutset) {\n\t\t\t\t\tlet { left, right, top, bottom } = $frameOutset;\n\t\t\t\t\tleft *= $rectScalar;\n\t\t\t\t\tright *= $rectScalar;\n\t\t\t\t\ttop *= $rectScalar;\n\t\t\t\t\tbottom *= $rectScalar;\n\t\t\t\t\tconst isDarkBackground = isDarkColor($rootBackgroundColor);\n\t\t\t\t\tconst shadeColor = isDarkBackground ? [1, 1, 1, 0.125] : [0, 0, 0, 0.075];\n\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\tx: x - left - 0.5,\n\t\t\t\t\t\ty: y - top - 0.5,\n\t\t\t\t\t\twidth: width + left + right + 1,\n\t\t\t\t\t\theight: height + top + bottom + 1,\n\t\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\t\tstrokeColor: shadeColor,\n\t\t\t\t\t\topacity: $stagePadded ? 1 : 0.5\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// draw extra shading around edge so crop controls are extra visible\n\t\t\t\tconst isDarkOutline = isDarkColor($rootLineColor);\n\n\t\t\t\tconst isDarkFrame = $imageFrame && $imageFrame.frameColor && isDarkColor($imageFrame.frameColor);\n\n\t\t\t\tif (!isDarkFrame && !isDarkOutline) {\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\tx: x - 1,\n\t\t\t\t\t\ty: y - 1,\n\t\t\t\t\t\twidth: width + 2,\n\t\t\t\t\t\theight: height + 2,\n\t\t\t\t\t\tstrokeWidth: 2,\n\t\t\t\t\t\tstrokeColor: [0, 0, 0, 0.1],\n\t\t\t\t\t\topacity: $colorOpacity\n\t\t\t\t\t});\n\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\tx: x + 1,\n\t\t\t\t\t\ty: y + 1,\n\t\t\t\t\t\twidth: width - 2,\n\t\t\t\t\t\theight: height - 2,\n\t\t\t\t\t\tstrokeWidth: 2,\n\t\t\t\t\t\tstrokeColor: [0, 0, 0, 0.1],\n\t\t\t\t\t\topacity: $colorOpacity\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tset([\n\t\t\t\t// added shapes\n\t\t\t\t...shapes,\n\t\t\t\t// default outline\n\t\t\t\t{\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\twidth,\n\t\t\t\t\theight,\n\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\tstrokeColor: $rootLineColor,\n\t\t\t\t\topacity: $colorOpacity\n\t\t\t\t}\n\t\t\t]);\n\t\t}\n\t);\n\n\t// custom markup rendered on top of image\n\tconst imageOverlayMarkup = writable([]);\n\n\tcomponent_subscribe($$self, imageOverlayMarkup, value => $$invalidate(409, $imageOverlayMarkup = value));\n\n\t// the resulting overlay markup\n\tconst imageOverlay = derived([imageOutline, imageOverlayMarkup], ([$imageOutline, $imageOverlayMarkup], set) => {\n\t\tset([...$imageOutline, ...$imageOverlayMarkup]);\n\t});\n\n\tcomponent_subscribe($$self, imageOverlay, value => $$invalidate(94, $imageOverlay = value));\n\n\t//\n\t// Stage overlay\n\t//\n\tconst overlayOpacity = spring(0, { precision: 0.001 });\n\n\tcomponent_subscribe($$self, overlayOpacity, value => $$invalidate(411, $overlayOpacity = value));\n\tconst overlayLeftRect = spring();\n\tcomponent_subscribe($$self, overlayLeftRect, value => $$invalidate(414, $overlayLeftRect = value));\n\tconst overlayTopRect = spring();\n\tcomponent_subscribe($$self, overlayTopRect, value => $$invalidate(413, $overlayTopRect = value));\n\tconst overlayRightRect = spring();\n\tcomponent_subscribe($$self, overlayRightRect, value => $$invalidate(412, $overlayRightRect = value));\n\tconst overlayBottomRect = spring();\n\tcomponent_subscribe($$self, overlayBottomRect, value => $$invalidate(410, $overlayBottomRect = value));\n\n\t//\n\t// Loading the preview\n\t//\n\tconst imageVisualLoadComplete = writable(false);\n\n\tcomponent_subscribe($$self, imageVisualLoadComplete, value => $$invalidate(396, $imageVisualLoadComplete = value));\n\tconst imagePreviewSource = writable();\n\tcomponent_subscribe($$self, imagePreviewSource, value => $$invalidate(399, $imagePreviewSource = value));\n\tlet imagePreviewLoaderCancelToken;\n\n\tconst imagePreview = derived([imageVisualLoadComplete, imagePreviewSource], ([$imageVisualLoadComplete, $imagePreviewSource], set) => {\n\t\t// no data, reset preview data\n\t\tif (!$imageVisualLoadComplete || !$imagePreviewSource) {\n\t\t\tset(undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// cancel existing loader\n\t\tif (imagePreviewLoaderCancelToken) {\n\t\t\timagePreviewLoaderCancelToken.cancel();\n\t\t\t$$invalidate(298, imagePreviewLoaderCancelToken = undefined);\n\t\t}\n\n\t\t// if image preview source is a canvas we can update immediately\n\t\tif (isCanvas($imagePreviewSource)) {\n\t\t\t// update image preview to canvas\n\t\t\treturn set(canvasClone($imagePreviewSource));\n\t\t}\n\n\t\t// try not to show preview loader if updating active images array\n\t\tconst minPreviewLoaderDuration = activeImages.length ? 0 : $isAnimated ? 250 : 0;\n\n\t\t// load preview\n\t\t$$invalidate(298, imagePreviewLoaderCancelToken = { cancel: noop$1 });\n\n\t\tcreateImageSrcLoader($imagePreviewSource, imagePreviewLoaderCancelToken, minPreviewLoaderDuration).then(set).catch(err => {\n\t\t\t// update load state\n\t\t\tset_store_value(imageLoadState, $imageLoadState.error = err, $imageLoadState);\n\n\t\t\t// log to console for debugging purposes\n\t\t}).finally(() => {\n\t\t\t// no longer loading\n\t\t\t$$invalidate(298, imagePreviewLoaderCancelToken = undefined);\n\t\t});\n\t});\n\n\t$$subscribe_imagePreview();\n\tlet { imagePreviewCurrent = undefined } = $$props;\n\n\t//\n\t// Calculates the image transforms and effects necessary for the preview\n\t//\n\tconst imagePreviewModifiers = writable({});\n\n\tcomponent_subscribe($$self, imagePreviewModifiers, value => $$invalidate(401, $imagePreviewModifiers = value));\n\tconst interfaceImages = writable([]);\n\tcomponent_subscribe($$self, interfaceImages, value => $$invalidate(86, $interfaceImages = value));\n\n\t// reset image UI previews when new file is loaded\n\tconst resetPreviews = () => {\n\t\timageSelectionPan.set(vectorCreateEmpty());\n\t\timageSelectionZoom.set(undefined);\n\t\timageSelectionStoredStateReset();\n\t\tinterfaceImages.set([]);\n\t};\n\n\tconst imageTransforms = derived(\n\t\t[\n\t\t\tstageRect,\n\t\t\trootRect,\n\t\t\timageSize,\n\t\t\timageCropRectPresentation,\n\t\t\timageSelectionRect,\n\t\t\tpresentationScalar,\n\t\t\timageRotation,\n\t\t\timageFlipX,\n\t\t\timageFlipY,\n\t\t\timageSelectionScalar,\n\t\t\timageSelectionPan,\n\t\t\tisTransformingImage\n\t\t],\n\t\t([\n\t\t\t\t$stageRect,\n\t\t\t\t$rootRect,\n\t\t\t\t$imageSize,\n\t\t\t\t$imageCropRectPresentation,\n\t\t\t\t$imageSelectionRect,\n\t\t\t\t$presentationScalar,\n\t\t\t\t$imageRotation,\n\t\t\t\t$imageFlipX,\n\t\t\t\t$imageFlipY,\n\t\t\t\t$imageSelectionScalar,\n\t\t\t\t$imageSelectionPan,\n\t\t\t\t$isTransformingImage\n\t\t\t], set) => {\n\t\t\tif (!$stageRect || !$imageSelectionRect) return;\n\t\t\tconst calculatedTransforms = calculateImageTransforms($stageRect, $rootRect, $imageSize, $imageCropRectPresentation, $imageSelectionRect, $imageSelectionScalar, $imageSelectionPan, $presentationScalar, $imageRotation, $imageFlipX, $imageFlipY);\n\t\t\t!$isTransformingImage && imageTransformsSnapPixels(calculatedTransforms);\n\t\t\tset(calculatedTransforms);\n\t\t}\n\t);\n\n\tcomponent_subscribe($$self, imageTransforms, value => $$invalidate(402, $imageTransforms = value));\n\n\tconst imageEffects = derived(\n\t\t[\n\t\t\timageColorMatrix,\n\t\t\timageConvolutionMatrix,\n\t\t\timageGamma,\n\t\t\timageVignette,\n\t\t\timageNoise\n\t\t],\n\t\t([$colorMatrix, $convolutionMatrix, $gamma, $vignette, $noise], set) => {\n\t\t\tconst colorMatrices = $colorMatrix && Object.keys($colorMatrix).map(name => $colorMatrix[name]).filter(Boolean);\n\n\t\t\tconst effects = {\n\t\t\t\tgamma: $gamma || undefined,\n\t\t\t\tvignette: $vignette || undefined,\n\t\t\t\tnoise: $noise || undefined,\n\t\t\t\tconvolutionMatrix: $convolutionMatrix || undefined,\n\t\t\t\tcolorMatrix: colorMatrices && colorMatrices.length && getColorMatrixFromColorMatrices(colorMatrices)\n\t\t\t};\n\n\t\t\tset(effects);\n\t\t}\n\t);\n\n\t//\n\t// current environment variables\n\t//\n\tlet windowWidth;\n\n\tlet windowHeight;\n\tconst shouldPreventSwipe = canPreventNavSwipe();\n\tconst env = writable({});\n\tcomponent_subscribe($$self, env, value => $$invalidate(390, $env = value));\n\tsetContext('env', env);\n\tconst initialPixelRatio = getDevicePixelRatio();\n\n\tconst pixelRatio = readable(initialPixelRatio, set => {\n\t\tconst handleResolutionChange = () => set(getDevicePixelRatio());\n\t\tconst resolutionObserver = matchMedia(`(resolution: ${initialPixelRatio}dppx)`);\n\t\tresolutionObserver.addListener(handleResolutionChange);\n\t\treturn () => resolutionObserver.removeListener(handleResolutionChange);\n\t});\n\n\tcomponent_subscribe($$self, pixelRatio, value => $$invalidate(57, $pixelRatio = value));\n\n\tconst history = historyCreate(\n\t\t() => {\n\t\t\t// $imageState is always a clone of the current state\n\t\t\treturn $imageState;\n\t\t},\n\t\tstate => {\n\t\t\t// set new state from history, $imageState will store a clone of the received state\n\t\t\tset_store_value(imageState, $imageState = state, $imageState);\n\n\t\t\t// trigger recenter of image selection rect\n\t\t\ttabRect.set($tabRect);\n\t\t},\n\t\t{\n\t\t\t// test if may undo, can't undo while editing draft\n\t\t\twillUndo: () => {\n\t\t\t\t// all good if not is editing draft\n\t\t\t\tif (!isEditingDraft()) return true;\n\n\t\t\t\t// if is editing draft, discard draft and prevent undo\n\t\t\t\tdiscardCurrentShapeDraft();\n\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t);\n\n\t$$subscribe_history();\n\n\tconst setInitialHistoryState = () => {\n\t\t// set history state\n\t\tconst baseRect = { x: 0, y: 0, ...$imageSize };\n\n\t\tconst baseCropRect = rectApply(rectContainRect(baseRect, $imageState.cropAspectRatio), Math.round);\n\n\t\t// note:\n\t\t//\n\t\t// currently undo doesn't step back to base state,\n\t\t// that's why the hook willSetHistoryInitialState below as introduced\n\t\t// will be fixed in version next major release of the editor\n\t\t//\n\t\tconst baseEditorState = willSetHistoryInitialState(\n\t\t\t{\n\t\t\t\t// the base state is the image state but the `rotation` and `crop` are reset\n\t\t\t\t...$imageState,\n\t\t\t\t// should be read from imageInitialProps?\n\t\t\t\trotation: 0,\n\t\t\t\tcrop: baseCropRect\n\t\t\t}, //\n\t\t\t// add other reset values here?\n\t\t\t//\n\t\t\t// see note above\n\t\t\t$imageState\n\t\t);\n\n\t\t// this will be the base state\n\t\tconst editorInitialHistoryState = [baseEditorState];\n\n\t\t// only add additional entry if base state and current state are different\n\t\tif (JSON.stringify(baseEditorState) !== JSON.stringify($imageState)) {\n\t\t\teditorInitialHistoryState.push({ ...$imageState });\n\t\t}\n\n\t\t// loading done, set this as base state\n\t\thistory.set(editorInitialHistoryState);\n\t};\n\n\tconst imageLoadStateUnsub = imageLoadState.subscribe(state => {\n\t\t// no state yet\n\t\tif (!state) return;\n\n\t\t// not ready yet\n\t\tif (!state.complete) return;\n\n\t\t// set initial state after image load has completed\n\t\tsetInitialHistoryState();\n\t});\n\n\tconst revert = () => willRevert().then(shouldReset => shouldReset && history.revert());\n\n\t//\n\tconst shapeStoreCollections = [imageAnnotation, imageDecoration, imageRedaction, imageManipulation];\n\n\t// discards a draft in any of the shape arrays, used to remove a draft when undoing history\n\tconst discardCurrentShapeDraft = () => {\n\t\tshapeStoreCollections.forEach(collection => {\n\t\t\tcollection.update(items => {\n\t\t\t\t// if contains draft, remove draft\n\t\t\t\tif (items.length && shapeIsDraft(items[items.length - 1])) {\n\t\t\t\t\treturn items.slice(0, -1);\n\t\t\t\t}\n\n\t\t\t\t// else return items\n\t\t\t\treturn items;\n\t\t\t});\n\t\t});\n\t};\n\n\t// tests if a draft is being edited in any of the shape arrays, used to test if is editing a draft while pressing undo\n\tconst isEditingDraft = () => shapeCollections.// only interest in collections that have shapes\n\tfilter(collection => collection.length).// test if some of these collections have a last items that is a draft\n\tsome(collection => shapeIsDraft(collection[collection.length - 1]));\n\n\t//\n\t// Visual processing of the image\n\t//\n\tconst imageProcessingPreparing = writable(false);\n\n\tcomponent_subscribe($$self, imageProcessingPreparing, value => $$invalidate(391, $imageProcessingPreparing = value));\n\n\tconst handleExport = () => {\n\t\t// this will trigger status overlay fade in\n\t\tset_store_value(imageProcessingPreparing, $imageProcessingPreparing = true, $imageProcessingPreparing);\n\n\t\twillProcessImage().then(shouldProcess => {\n\t\t\t// nope, restore hide processing overlay and back to editing\n\t\t\tif (!shouldProcess) {\n\t\t\t\tset_store_value(imageProcessingPreparing, $imageProcessingPreparing = false, $imageProcessingPreparing);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// wait for status to be done fading in, then requests image writing\n\t\t\tlet unsub;\n\n\t\t\tunsub = statusOpacity.subscribe(value => {\n\t\t\t\tif (value !== 1) return;\n\n\t\t\t\t// stop listening for\n\t\t\t\tunsub && unsub();\n\n\t\t\t\t// request write image\n\t\t\t\tdispatch('processImage');\n\t\t\t});\n\t\t});\n\t};\n\n\tconst imageProcessStateUnsub = imageProcessState.subscribe(state => {\n\t\tif (!state) {\n\t\t\tset_store_value(imageProcessingPreparing, $imageProcessingPreparing = false, $imageProcessingPreparing);\n\t\t\treturn;\n\t\t}\n\n\t\tset_store_value(imageProcessingPreparing, $imageProcessingPreparing = true, $imageProcessingPreparing);\n\t\tconst { complete, abort } = state;\n\t\tif (complete || abort) set_store_value(imageProcessingPreparing, $imageProcessingPreparing = false, $imageProcessingPreparing);\n\t});\n\n\tconst activeImages = storeList();\n\tcomponent_subscribe($$self, activeImages, value => $$invalidate(55, $activeImages = value));\n\n\tconst imageTransformsInterpolated = derived([activeImages], ([$activeImages], set) => {\n\t\tif (!$activeImages.length) return set();\n\t\tconst { origin, translation, rotation, scale } = $activeImages[0];\n\t\tset({ origin, translation, rotation, scale });\n\t});\n\n\tconst utilTools = writable();\n\tcomponent_subscribe($$self, utilTools, value => $$invalidate(405, $utilTools = value));\n\n\t// bind from pan/zoom control\n\tlet zoomControls = [];\n\n\t// bind from pan/zoom control\n\tlet zoomMultiTouching;\n\n\tconst imageSelectionMultiTouching = writable();\n\tconst imagePreviewUpscale = writable();\n\n\tconst imageSelectionZoomCurrent = derived(\n\t\t[\n\t\t\timageSelectionZoom,\n\t\t\timagePreviewUpscale,\n\t\t\tstageScalar,\n\t\t\timageSelectionStageFitScalar\n\t\t],\n\t\t([\n\t\t\t\t$imageSelectionZoom,\n\t\t\t\t$imagePreviewUpscale,\n\t\t\t\t$stageScalar,\n\t\t\t\t$imageSelectionStageFitScalar\n\t\t\t]) => {\n\t\t\treturn $imageSelectionZoom\n\t\t\t? $imageSelectionZoom\n\t\t\t: $imagePreviewUpscale || $stageScalar < 1\n\t\t\t\t? $imageSelectionStageFitScalar\n\t\t\t\t: 1;\n\t\t}\n\t);\n\n\t//\n\t// Configure the available views\n\t//\n\tconst utilStores = {\n\t\t// model stores\n\t\t...stores,\n\t\t// image\n\t\timageFile,\n\t\timageSize,\n\t\t// video / animated gif\n\t\tmediaDuration,\n\t\tmediaMinDuration,\n\t\tmediaMaxDuration,\n\t\tmediaTrim,\n\t\timageBackgroundColor,\n\t\timageBackgroundImage: imageBackgroundImageSrc,\n\t\timageBackgroundFilterMode,\n\t\timageCropAspectRatio,\n\t\timageCropMinSize,\n\t\timageCropMaxSize,\n\t\timageCropLimitToImage,\n\t\timageCropRect,\n\t\timageCropRectOrigin,\n\t\timageCropRectSnapshot,\n\t\timageCropRectAspectRatio,\n\t\timageCropRange,\n\t\timageRotation,\n\t\timageRotationRange,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\timageOutputSize,\n\t\t// effects\n\t\timageColorMatrix,\n\t\timageConvolutionMatrix,\n\t\timageGamma,\n\t\timageVignette,\n\t\timageNoise,\n\t\t// markup\n\t\timageManipulation,\n\t\timageDecoration,\n\t\timageAnnotation,\n\t\timageRedaction,\n\t\timageFrame,\n\t\t// image preview for utils that need access to pixel data\n\t\timagePreview,\n\t\t// image preview source so utils can update preview\n\t\timagePreviewSource,\n\t\t// top left position of image preview\n\t\timageTransforms,\n\t\t// allows utils to control how the preview is presented (for example more opacity for mask)\n\t\timagePreviewModifiers,\n\t\t// history state and update\n\t\thistory,\n\t\t// static env info\n\t\tanimation: shouldAnimate,\n\t\tpixelRatio,\n\t\telasticityMultiplier,\n\t\tscrollElasticity,\n\t\trangeInputElasticity,\n\t\tredrawTrigger,\n\t\t// dynamic env info\n\t\tpointerAccuracy,\n\t\tpointerHoverable,\n\t\tenv,\n\t\trootRect,\n\t\tstageRect,\n\t\tstageRectBase,\n\t\tstageRecenter,\n\t\tstageScalar,\n\t\tstagePadding,\n\t\tstagePadded,\n\t\tpresentationScalar,\n\t\timagePreviewUpscale,\n\t\tutilRect,\n\t\tutilRectPadded,\n\t\tallowPlayPause,\n\t\tallowPan,\n\t\tallowZoom,\n\t\tallowZoomControls,\n\t\tenableZoomInput: enableZoomInputStore,\n\t\tenablePanInput: enablePanInputStore,\n\t\tenablePanInputStatus,\n\t\timageSelectionMultiTouching,\n\t\trootBackgroundColor,\n\t\trootForegroundColor,\n\t\trootLineColor,\n\t\trootColorSecondary,\n\t\timageOutlineOpacity,\n\t\t// add tools to interface\n\t\tutilTools,\n\t\t// interaction\n\t\timageSelectionPan,\n\t\timageSelectionZoom,\n\t\timageSelectionZoomCurrent,\n\t\timageSelectionStageFitScalar,\n\t\timageSelectionStoredState,\n\t\t// toggle audio\n\t\t// muteAudioStore,\n\t\t// (write) add guides to ui (for example is used by markup util to add lines for shape manipulator)\n\t\timageOverlayMarkup,\n\t\t// (write) interface images to render\n\t\tinterfaceImages,\n\t\t// (write) set to true to disable animations\n\t\tisInteracting,\n\t\t// (write) set to true when transforming image (move, translate, scale, rotate)\n\t\tisTransformingImage,\n\t\t// (read) goes from 0 to 1 while interacting\n\t\tisInteractingFraction,\n\t\t// (write) the current intended crop rect\n\t\timageCropRectIntent,\n\t\t// (read) the current presented crop rect\n\t\timageCropRectPresentation,\n\t\t// (write) the current limited size of the image selection rect\n\t\timageSelectionRect,\n\t\t// (write) the inteded rectangle by the user\n\t\timageSelectionRectIntent,\n\t\t// (read) the current presentation of the image selection rect, includes elasticity etc.\n\t\timageSelectionRectPresentation,\n\t\t// (read) a snapshot of the image selection rectangle, use to store the rectangle before manipulation so alterations to the rectangle can be applied to the snapshot\n\t\timageSelectionRectSnapshot,\n\t\t// scalar of image in view\n\t\timageScalar,\n\t\t// current image interpolated state\n\t\timageTransformsInterpolated,\n\t\t// effects applied to the image\n\t\timageEffects\n\t};\n\n\t// don't expose image store\n\tdelete utilStores.image;\n\n\tconst utilsUniqueId = `util-${getUniqueId()}`;\n\tlet previousUtilsAvailable = [];\n\n\tconst getAvailableUtils = (utils, pluginComponents, pluginOptions, props) => {\n\t\tconst utilsAvailable = pluginComponents.filter(([id]) => utils.includes(id)).filter(([id, { isSupported }]) => isSupported({ ...props, ...pluginOptions[id] })).map(([id, util]) => [id, util.Component]);\n\n\t\tconst isEqualToPreviousUtils = arrayEqual(utilsAvailable, previousUtilsAvailable, (a, b) => {\n\t\t\treturn a[0] === b[0] && a[1] === b[1];\n\t\t});\n\n\t\tif (isEqualToPreviousUtils) return previousUtilsAvailable;\n\t\tpreviousUtilsAvailable = utilsAvailable;\n\t\treturn utilsAvailable;\n\t};\n\n\tconst getAvailableUtilById = utilId => utilsAvailable.find(([id]) => utilId === id);\n\tconst getFirstAvailableUtil = () => utilsAvailable[0][0];\n\tlet utilsVisible = [];\n\n\tconst handleShowUtil = panel => {\n\t\t$$invalidate(62, utilsVisible = utilsVisible.concat(panel));\n\t};\n\n\tconst handleHideUtil = panel => {\n\t\t$$invalidate(62, utilsVisible = utilsVisible.filter(util => util !== panel));\n\t};\n\n\tconst handleFadeUtil = (panel, opacity) => {\n\t\t$$invalidate(308, utilsVisibleFraction[panel] = opacity, utilsVisibleFraction);\n\t};\n\n\tconst getUtilPanelProps = (panel, pluginOptions) => pluginOptions[panel];\n\tconst getUtilPanelView = panel => utilsMerged.find(util => util.id === panel).view;\n\n\t// env\n\tlet iOS = isIOS();\n\n\tconst getOrientation = (rect, layoutPreference) => {\n\t\tif (!$rootRect) return 'landscape';\n\t\tif (layoutPreference === 'auto') return rect.width > rect.height ? 'landscape' : 'portrait';\n\t\tif (layoutPreference === 'horizontal') return rect.width < 500 ? 'portrait' : 'landscape';\n\t\tif (layoutPreference === 'vertical') return rect.height < 400 ? 'landscape' : 'portrait';\n\t};\n\n\tconst getColorPropertyValue = name => {\n\t\tconst colorString = rootElementComputedStyle.getPropertyValue(name);\n\t\treturn colorStringToColorArray(colorString);\n\t};\n\n\tconst syncValue = (name, store, parseValue) => {\n\t\tlet value = rootElementComputedStyle.getPropertyValue(name);\n\n\t\tvalue = parseValue\n\t\t? parseValue(value)\n\t\t: (/^[0-9]+$/).test(value) ? parseFloat(value) : undefined;\n\n\t\tstore.set(value, { hard: !$isAnimated });\n\t};\n\n\tconst syncColor = (property, store, enableAlpha = false) => {\n\t\tconst colorArray = getColorPropertyValue(property);\n\n\t\t// hide transparent color\n\t\tif (!colorArray || colorArray[3] === 0) return;\n\n\t\t// limit to opaque colors\n\t\tif (!enableAlpha) colorArray.length = 3;\n\n\t\t// update store\n\t\tstore.set(colorArray, { hard: !$isAnimated });\n\t};\n\n\tconst gridSize = writable();\n\tcomponent_subscribe($$self, gridSize, value => $$invalidate(87, $gridSize = value));\n\tconst gridColorEven = writable();\n\tcomponent_subscribe($$self, gridColorEven, value => $$invalidate(88, $gridColorEven = value));\n\tconst gridColorOdd = writable();\n\tcomponent_subscribe($$self, gridColorOdd, value => $$invalidate(89, $gridColorOdd = value));\n\tconst gridOpacity = spring(0, { damping: 0.9 });\n\tcomponent_subscribe($$self, gridOpacity, value => $$invalidate(90, $gridOpacity = value));\n\n\tconst syncCSSProps = () => {\n\t\tsyncColor('color', rootForegroundColor);\n\n\t\tenableCanvasAlpha\n\t\t? syncColor('--color-background', rootBackgroundColor)\n\t\t: syncColor('background-color', rootBackgroundColor);\n\n\t\tsyncColor('outline-color', rootLineColor);\n\t\tsyncColor('--color-primary', rootColorPrimary);\n\t\tsyncColor('--color-secondary', rootColorSecondary);\n\t\tsyncColor('--grid-color-even', gridColorEven, true);\n\t\tsyncColor('--grid-color-odd', gridColorOdd, true);\n\t\tsyncValue('--grid-size', gridSize);\n\t\tsyncValue('--editor-inset-top', rootInsetTop, v => parseInt(v, 10));\n\t};\n\n\tconst handleTransitionEnd = ({ target, propertyName }) => {\n\t\tif (target !== root || !(/background|outline/).test(propertyName)) return;\n\t\tif (rootElementComputedStyle) syncCSSProps();\n\t};\n\n\tconst imageProps = derived(\n\t\t[\n\t\t\timageTransforms,\n\t\t\timageEffects,\n\t\t\timageBackgroundColor,\n\t\t\timageBackgroundImageData,\n\t\t\timageBackgroundFilterMode\n\t\t],\n\t\t([\n\t\t\t\t$imageTransforms,\n\t\t\t\t$imageEffects,\n\t\t\t\tbackgroundColor,\n\t\t\t\tbackgroundImageData,\n\t\t\t\tbackgroundFilterMode\n\t\t\t]) => {\n\t\t\treturn $imageTransforms && {\n\t\t\t\t...$imageTransforms,\n\t\t\t\t...$imageEffects,\n\t\t\t\tbackgroundColor,\n\t\t\t\tbackgroundImage: backgroundImageData,\n\t\t\t\tbackgroundFilterMode: backgroundFilterMode || 'none'\n\t\t\t};\n\t\t}\n\t);\n\n\tcomponent_subscribe($$self, imageProps, value => $$invalidate(400, $imageProps = value));\n\n\tconst addImagePreview = () => {\n\t\t// if is first image scale up slightly on entrance\n\t\tconst imageIntro = activeImages.length ? undefined : { resize: 1.05 };\n\n\t\t// create the new image\n\t\tconst image = createImage($imagePreview, $imageSize, imageIntro);\n\n\t\t// new image on top\n\t\tactiveImages.unshift(image);\n\n\t\t// update images in activeImages array\n\t\tupdateImagePreviews($imageProps);\n\t};\n\n\tconst updateImagePreviews = currentImageProps => {\n\t\tactiveImages.forEach((image, index) => {\n\t\t\tconst opacity = index === 0 ? 1 : 0;\n\t\t\tconst resize = 1;\n\t\t\timage.set({ ...currentImageProps, opacity, resize }, $shouldAnimate);\n\t\t});\n\t};\n\n\t// if image preview changes, push it on the stack\n\tlet lastImagePreview;\n\n\tconst statusOpacity = tweened(undefined, { duration: 500 });\n\tcomponent_subscribe($$self, statusOpacity, value => $$invalidate(54, $statusOpacity = value));\n\n\t//\n\t// support test status\n\t//\n\tfunction getLabelSupportError(missingFeatures, locale) {\n\t\tif (isFunction(locale.labelSupportError)) {\n\t\t\treturn locale.labelSupportError(missingFeatures);\n\t\t}\n\n\t\tconst replacements = formatStatusSupportError({ features: missingFeatures }, locale);\n\t\treturn stringReplace(locale.labelSupportError, replacements, '{', '}');\n\t}\n\n\tlet webGLContextFailed = false;\n\n\tfunction handleCanvasError() {\n\t\t$$invalidate(300, webGLContextFailed = true);\n\t}\n\n\tlet loadTimer;\n\n\tfunction getImageLoadStatusLabel(loadState, locale) {\n\t\t// determine state\n\t\tconst state = loadState\n\t\t? !loadState.complete || loadState.error\n\t\t\t? loadState\n\t\t\t: {\n\t\t\t\t\ttask: 'blob-to-bitmap',\n\t\t\t\t\tprogress: Infinity\n\t\t\t\t}\n\t\t: undefined;\n\n\t\t// use 'modern' status label formatter\n\t\tlet label = isFunction(locale.statusLabelLoadImage)\n\t\t? // deprecated function in locale\n\t\t\tlocale.statusLabelLoadImage(state)\n\t\t: // using format prop\n\t\t\tformatStatusImageLoading({ state }, locale);\n\n\t\t// has values to replace in label\n\t\tif (loadState && loadState.error && loadState.error.metadata) {\n\t\t\tlabel = stringReplace(label, loadState.error.metadata, '{', '}');\n\t\t}\n\n\t\t// done!\n\t\treturn label;\n\t}\n\n\tfunction getImageProcessStatusLabel(processState, locale) {\n\t\treturn isFunction(locale.statusLabelProcessImage)\n\t\t? locale.statusLabelProcessImage(processState)\n\t\t: formatStatusImageProcessing({ state: processState }, locale);\n\t}\n\n\t// this adds a little delay to the status fade out after an image was processed\n\t// needed because when the modal fades out this would otherwise create a weird flash (modal fade out, but status fade out as well showing interface)\n\tconst wasProcessingImage = writable(false);\n\n\tcomponent_subscribe($$self, wasProcessingImage, value => $$invalidate(395, $wasProcessingImage = value));\n\tlet statusState;\n\n\tconst asideOffset = spring(undefined, {\n\t\tstiffness: 0.1,\n\t\tdamping: 0.7,\n\t\tprecision: 0.25\n\t});\n\n\tcomponent_subscribe($$self, asideOffset, value => $$invalidate(82, $asideOffset = value));\n\tconst asideOpacity = spring(0, { stiffness: 0.1, precision: 0.05 });\n\tcomponent_subscribe($$self, asideOpacity, value => $$invalidate(83, $asideOpacity = value));\n\n\tconst asideWidth = spring(0, {\n\t\tstiffness: 0.02,\n\t\tdamping: 0.5,\n\t\tprecision: 0.25\n\t});\n\n\tcomponent_subscribe($$self, asideWidth, value => $$invalidate(393, $asideWidth = value));\n\n\tconst statusWidth = spring(undefined, {\n\t\tstiffness: 0.02,\n\t\tdamping: 0.5,\n\t\tprecision: 0.25\n\t});\n\n\tcomponent_subscribe($$self, statusWidth, value => $$invalidate(394, $statusWidth = value));\n\n\tconst statusOffset = spring(undefined, {\n\t\tstiffness: 0.02,\n\t\tdamping: 0.5,\n\t\tprecision: 0.25\n\t});\n\n\tcomponent_subscribe($$self, statusOffset, value => $$invalidate(392, $statusOffset = value));\n\tlet asideWidthUpdateTimer;\n\n\tconst offsetAside = e => {\n\t\t// if error occured, or not animating, snap in possition\n\t\tconst hard = !!(statusState && (statusState.closeButton || statusState.error)) || !$isAnimated;\n\n\t\t// where to render the progress indicator or close button\n\t\tstatusWidth.set(e.detail.width, { hard });\n\n\t\t// offsets text so it's better centered to the viewport\n\t\tstatusOffset.set(Math.round(-e.detail.width * 0.5), { hard });\n\t};\n\n\tconst handleCloseImageLoadError = () => {\n\t\tdispatch('abortLoadImage');\n\t};\n\n\tconst handleCloseImageProcessError = () => {\n\t\tdispatch('abortProcessImage');\n\t\tset_store_value(imageProcessingPreparing, $imageProcessingPreparing = false, $imageProcessingPreparing);\n\t};\n\n\t// helper to block iOS and Firefox Android events so don't toggle nav\n\tconst preventDefault = e => {\n\t\tif (e.target && e.target.dataset.touchScroll === 'true') {\n\t\t\treturn;\n\t\t}\n\n\t\t// fixes issues on Apple Pencil\n\t\tif (isApplePencilEvent(e)) {\n\t\t\treturn;\n\t\t}\n\n\t\te.preventDefault();\n\t};\n\n\t// prevents swipe to navigate back on iOS >= 13.4+\n\tconst handleTouchStart = shouldPreventSwipe\n\t? e => {\n\t\t\t// get touch or event itself (fixes issue with chrome dev tools)\n\t\t\tconst event = e.touches ? e.touches[0] : e;\n\n\t\t\t// if is not an attempt to swipe back or forward\n\t\t\tif (event.pageX > 20 && event.pageX < window.innerWidth - 20) return;\n\n\t\t\t// stop the navigation attempt\n\t\t\tpreventDefault(e);\n\t\t}\n\t: noop$1;\n\n\t// context for children to know if a key is down\n\tconst pressedKeysStore = writable([]);\n\n\tcomponent_subscribe($$self, pressedKeysStore, value => $$invalidate(488, $pressedKeysStore = value));\n\tsetContext('keysPressed', pressedKeysStore);\n\n\tconst handleKeydown = e => {\n\t\tconst { keyCode, metaKey, ctrlKey, shiftKey } = e;\n\n\t\t// prevent tabbing through fields if editor is disabled\n\t\tif (keyCode === 9 && disabled) {\n\t\t\te.preventDefault();\n\t\t\treturn;\n\t\t}\n\n\t\t// prevent spacebar from scrolling page\n\t\tif (e.target && keyCode === 32 && root.contains(e.target) && !isTextField(e.target)) {\n\t\t\tif ($allowPlayPause && isVideoSupported) togglePlayPause();\n\t\t\te.preventDefault();\n\t\t}\n\n\t\t// undo/redo\n\t\tif (keyCode === 90 && (metaKey || ctrlKey)) {\n\t\t\tif (shiftKey && metaKey) {\n\t\t\t\t// redo on MacOS\n\t\t\t\thistory.redo();\n\t\t\t} else {\n\t\t\t\t// undo\n\t\t\t\thistory.undo();\n\t\t\t}\n\n\t\t\treturn;\n\t\t} else if (keyCode === 89 && ctrlKey) {\n\t\t\t// redo on Windows\n\t\t\thistory.redo();\n\n\t\t\treturn;\n\t\t}\n\n\t\t// ignore IME popup keycode, fixes keycode 229 sticking around, as it's not triggered in keyup \"If an Input Method Editor is processing key input and the event is keydown, return 229.\"\n\t\t// https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html\n\t\tif (keyCode === 229) {\n\t\t\treturn;\n\t\t}\n\n\t\t// prevent capturing backspace / delete when focus is in non editor text input\n\t\tif (e.target && (keyCode === 8 || keyCode === 46) && !root.contains(e.target) && isTextField(e.target)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// add to set\n\t\tconst keySet = new Set([...$pressedKeysStore, keyCode]);\n\n\t\tpressedKeysStore.set(Array.from(keySet));\n\t};\n\n\tconst handleKeyup = ({ key, keyCode }) => {\n\t\t// this prevents holding the command key while panning image from resutling in sticky keys\n\t\tif (key === 'Meta') return pressedKeysStore.set([]);\n\n\t\tpressedKeysStore.set($pressedKeysStore.filter(pressedKey => pressedKey !== keyCode));\n\t};\n\n\t// so no keys get stuck when user cmd-tabs out of the window, or when dev-tools open by key-press\n\tconst handleWindowBlur = () => {\n\t\tpressedKeysStore.set([]);\n\t};\n\n\t// block context menu on everything but text input fields\n\tconst handleContextMenu = e => {\n\t\tif (isTextField(e.target)) return;\n\t\te.preventDefault();\n\t};\n\n\tconst isValidFile = (file, accept) => {\n\t\tif (isBitmap(file) && (/image/).test(accept)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (isVideoFile(file) && (/video/).test(accept)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\t// handle files being dropped on the editor\n\tconst handleUserFile = file => {\n\t\t// no file received, isn't an image or video file, is not a URL\n\t\tif (// no file received\n\t\t!file || // if it's a file object it should be a bitmap or a video\n\t\tisBinary(file) && !isValidFile(file, accept) || // if it's not a file object it should be a URL\n\t\t!isBinary(file) && !(/^http/).test(file)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// request load image\n\t\tdispatch('loadImage', file);\n\t};\n\n\tconst handleDropFiles = e => {\n\t\t// not allowed to drop\n\t\tif (!enableDropImage) return;\n\n\t\thandleUserFile(e.detail.resources[0]);\n\t};\n\n\tconst handleSelectFile = file => {\n\t\tif (!file) return;\n\t\thandleUserFile(file);\n\t};\n\n\tconst browseFileSystem = e => {\n\t\tif (!enableBrowseImage || e.target && e.target.tagName === 'BUTTON') return;\n\t\tbrowse({ accept }).then(handleSelectFile);\n\t};\n\n\tconst handlePaste = e => {\n\t\t// not allowed to paste\n\t\tif (!enablePasteImage) return;\n\n\t\t// calculate percentage of editor that is in view\n\t\tconst xPercentage = clamp((window.innerWidth - Math.abs($rootRect.x)) / $rootRect.width, 0, 1);\n\n\t\tconst yPercentage = clamp((window.innerHeight - Math.abs($rootRect.y)) / $rootRect.height, 0, 1);\n\n\t\t// editor needs to be in view\n\t\tif (xPercentage < 0.75 && yPercentage < 0.75) return;\n\n\t\t// request load image\n\t\thandleUserFile((e.clipboardData || window.clipboardData).files[0]);\n\t};\n\n\t//\n\t// canvas drawing\n\t//\n\tlet scrambledPreviewImage = undefined;\n\n\tlet previousImageScrambler = undefined;\n\tlet previousImagepreviewData = undefined;\n\n\tconst updateScrambledPreview = (imagePreviewData, imageScrambler, imageRedactionScalar, imageBackgroundColor) => {\n\t\t// don't have required input\n\t\tif (!imageScrambler || !imagePreviewData) {\n\t\t\treturn;\n\t\t}\n\n\t\t// no change to scrambler and data\n\t\tif (previousImageScrambler === imageScrambler && previousImagepreviewData === imagePreviewData) {\n\t\t\treturn;\n\t\t}\n\n\t\t// remember so we don't redraw if the same input is passed\n\t\tpreviousImagepreviewData = imagePreviewData;\n\n\t\tpreviousImageScrambler = imageScrambler;\n\n\t\t// remove transparency\n\t\tconst scrambleOptions = { dataSizeScalar: imageRedactionScalar };\n\n\t\tif (imageBackgroundColor && imageBackgroundColor[3] > 0) {\n\t\t\tscrambleOptions.backgroundColor = [...imageBackgroundColor];\n\t\t}\n\n\t\timageScrambler(imagePreviewData, scrambleOptions).then(scrambledCanvas => {\n\t\t\t// we've created a new scrambled preview so force release memory of old one\n\t\t\tif (scrambledPreviewImage) {\n\t\t\t\treleaseCanvas(scrambledPreviewImage);\n\t\t\t}\n\n\t\t\t// prevents rendered from releasing canvas\n\t\t\tscrambledCanvas.setAttribute('data-retain', true);\n\n\t\t\t// update scrambled preview with new image\n\t\t\t$$invalidate(303, scrambledPreviewImage = scrambledCanvas);\n\t\t});\n\t};\n\n\tlet computedRedactionShapes = [];\n\n\t// setup root portal for detail panel dropdown\n\tlet rootPortal;\n\n\tconst rootPortalStore = writable();\n\tsetContext('rootPortal', rootPortalStore);\n\n\t// setup root rect store for global access\n\tsetContext('rootRect', rootRect);\n\n\tconst getStageState = () => ({\n\t\t// add foreground color\n\t\tforegroundColor: [...$rootForegroundColor],\n\t\t// add line color\n\t\tlineColor: [...$rootLineColor],\n\t\t// add information on which util is active\n\t\tutilVisibility: { ...utilsVisibleFraction },\n\t\t// used to fade in elements when interacting\n\t\tisInteracting: $isInteracting,\n\t\tisInteractingFraction: $isInteractingFraction,\n\t\t// add the root rectangle so will render can use width/height of root element\n\t\trootRect: rectClone($rootRect),\n\t\t// add the stage rectangle so will render knows where stage starts and ends\n\t\tstageRect: rectClone($stageRect),\n\t\t// allows overriding dirty state\n\t\tmanipulationShapesDirty: imageManipulationShapesDirty,\n\t\tannotationShapesDirty: imageAnnotationShapesDirty,\n\t\tdecorationShapesDirty: imageDecorationShapesDirty,\n\t\tframeShapesDirty: imageFrameShapesDirty\n\t});\n\n\t// test if some shapes have left/top/bottom/right offsets, if so, convert to crop space\n\t// updates original shape (which at this point is a flattened shape (clone))\n\tconst positionDecorationShape = (shape, selectionRect, scale) => {\n\t\t// need to calculate intermediate sizes so relative shapes are animated when the interface updates\n\t\t// this calculation should result in a \"springed\" $imageCropRect\n\t\treturn shapeComputeDisplay(shape, sizeCreate(Math.round(selectionRect.width / scale), Math.round(selectionRect.height / scale)));\n\t};\n\n\t// decoration is drawn relative to view space, so we need to translate relative to crop presentation rect\n\tconst transformDecorationShape = (shape, selectionRect, scale) => {\n\t\tshape._translate = vectorCreateFromAny(selectionRect);\n\t\tshape._scale = scale;\n\t\treturn shape;\n\t};\n\n\tconst flattenShapes = shapes => {\n\t\tconst flattenedShapes = [];\n\t\tshapes.forEach(shape => flattenedShapes.push(flattenShape(shape)));\n\t\treturn flattenedShapes.filter(Boolean);\n\t};\n\n\tconst flattenShape = shape => {\n\t\t// at this point shape is a copy of the original shape\n\t\tif (shapeIsLine(shape)) {\n\t\t\tshape.points = [vectorCreate(shape.x1, shape.y1), vectorCreate(shape.x2, shape.y2)];\n\t\t\treturn shape;\n\t\t}\n\n\t\t// is empty text\n\t\tif (shapeIsTextEmpty(shape) && (!shape.backgroundColor || shape.backgroundColor[3] === 0)) {\n\t\t\t// make sure shape is still visible\n\t\t\tif (shapeIsTextBlock(shape)) {\n\t\t\t\tshape.width = 5;\n\t\t\t\tshape.height = shape.lineHeight;\n\t\t\t}\n\n\t\t\t// set to empty text style\n\t\t\tshape.strokeWidth = 1;\n\n\t\t\tshape.strokeColor = [1, 1, 1, 0.5];\n\t\t\tshape.backgroundColor = [0, 0, 0, 0.1];\n\t\t\treturn shape;\n\t\t}\n\n\t\treturn shape;\n\t};\n\n\t// these hold computes shapes, so we don't have to compute on each frame if no changes\n\tlet canvasComputedAnnotationBaseShapes = [];\n\n\tlet canvasComputedAnnotationShapes = [];\n\tlet canvasComputedManipulationShapes = [];\n\tlet canvasComputedDecorationShapes = [];\n\tlet canvasComputedFrameShapes = [];\n\tlet canvasComputedScale;\n\tlet canvasComputedSelectionRect = {};\n\n\tconst createCanvasState = (canvasState, manipulationShapesToDraw, annotationShapesToDraw, decorationShapesToDraw, interfaceShapesToDraw, frameShapesToDraw, selectionShapes) => {\n\t\tconst { manipulationShapesDirty, annotationShapesDirty, decorationShapesDirty, frameShapesDirty, selectionRect, scale } = canvasState;\n\n\t\t// determine if canvas is dirty, if so, we need to recalculate shapes that rely on canvas\n\t\tconst canvasScaleChanged = canvasComputedScale !== scale;\n\n\t\tconst canvasDirty = canvasScaleChanged || !rectEqual(canvasComputedSelectionRect, selectionRect);\n\n\t\t// remember dirty state so we can compare next draw\n\t\tif (canvasDirty) {\n\t\t\tcanvasComputedScale = scale;\n\t\t\tcanvasComputedSelectionRect = selectionRect;\n\t\t}\n\n\t\t// blend shapes changed\n\t\tif (manipulationShapesDirty) {\n\t\t\tcanvasComputedManipulationShapes = manipulationShapesToDraw.filter(shapeIsVisible).map(shapeDeepCopy).map(shape => shapeComputeDisplay(shape, $imageSize));\n\t\t}\n\n\t\t// annotation shapes changed, or user changed annotation shapes in willRenderCanvas hook\n\t\tif (annotationShapesDirty || annotationShapesToDraw !== $imageAnnotation) {\n\t\t\tcanvasComputedAnnotationBaseShapes = annotationShapesToDraw.filter(shapeIsVisible).map(shapeDeepCopy).sort((a, b) => {\n\t\t\t\tif (a.alwaysOnTop) return 1;\n\t\t\t\tif (b.alwaysOnTop) return -1;\n\t\t\t\treturn 0;\n\t\t\t}).map(shape => shapeComputeDisplay(shape, $imageSize));\n\t\t}\n\n\t\tif (canvasScaleChanged || imageAnnotationRequiresPreprocessing || annotationShapesDirty || annotationShapesToDraw !== $imageAnnotation) {\n\t\t\tcanvasComputedAnnotationShapes = flattenShapes(canvasComputedAnnotationBaseShapes.map(shape => preprocessShape(shape, {\n\t\t\t\tflipX: $imageFlipX,\n\t\t\t\tflipY: $imageFlipY,\n\t\t\t\trotation: $imageRotation,\n\t\t\t\tscale,\n\t\t\t\tcontext: rectCreateFromSize($imageSize)\n\t\t\t})).flat());\n\t\t}\n\n\t\t// decoration shapes changed, or user changed decoration shapes in willRenderCanvs hook, or canvas updated and decorations need to be recomputed\n\t\tif (decorationShapesDirty || decorationShapesToDraw !== $imageDecoration || canvasDirty) {\n\t\t\tcanvasComputedDecorationShapes = flattenShapes(decorationShapesToDraw.filter(shapeIsVisible).map(shapeDeepCopy).sort((a, b) => {\n\t\t\t\tif (a.alwaysOnTop) return 1;\n\t\t\t\tif (b.alwaysOnTop) return -1;\n\t\t\t\treturn 0;\n\t\t\t}).map(shape => positionDecorationShape(shape, selectionRect, scale)).map(shape => preprocessShape(shape, { context: selectionRect })).flat().map(shape => transformDecorationShape(shape, selectionRect, scale)));\n\t\t}\n\n\t\t// only recompute frame shapes if frame changed or selection rect changed\n\t\tif (frameShapesDirty || frameShapesToDraw !== $imageFrame || canvasDirty) {\n\t\t\tcanvasComputedFrameShapes = frameShapesToDraw\n\t\t\t? flattenShapes([frameShapesToDraw].map(shapeDeepCopy).map(shape => positionDecorationShape(shape, selectionRect, scale)).map(preprocessShape).flat().map(shape => transformDecorationShape(shape, selectionRect, scale)))\n\t\t\t: [];\n\t\t}\n\n\t\tlet canvasComputedInterfaceShapes = flattenShapes(interfaceShapesToDraw.filter(shapeIsVisible));\n\n\t\treturn {\n\t\t\t// only redraw if annotations are dirty\n\t\t\tmanipulationShapesDirty,\n\t\t\tmanipulationShapes: canvasComputedManipulationShapes,\n\t\t\t// only redraw if annotations are dirty\n\t\t\tannotationShapesDirty,\n\t\t\tannotationShapes: canvasComputedAnnotationShapes,\n\t\t\t// prepare decoration shapes (percentages to absolute values)\n\t\t\tdecorationShapesDirty,\n\t\t\tdecorationShapes: canvasComputedDecorationShapes,\n\t\t\t// prepare frame shapes (percentages to absolute values)\n\t\t\tframeShapesDirty,\n\t\t\tframeShapes: canvasComputedFrameShapes,\n\t\t\t// prepare interface shapes (percentages to absolute values)\n\t\t\tinterfaceShapes: canvasComputedInterfaceShapes,\n\t\t\t// selection\n\t\t\tselectionShapes: selectionShapes.map(shapeDeepCopy).map(shape => shapeComputeDisplay(shape, $imageSize))\n\t\t};\n\t};\n\n\t//\n\t// for optimizing canvas calls\n\t//\n\t// mark image annotations as dirrty if the image annotations array is changed\n\tlet imageAnnotationShapesDirty = true;\n\n\tconst markAnnotationShapesAsDirty = () => $$invalidate(63, imageAnnotationShapesDirty = true);\n\tlet imageAnnotationRequiresPreprocessing = true;\n\tconst markAnnotationRequiresPreprocessing = () => $$invalidate(64, imageAnnotationRequiresPreprocessing = true);\n\n\t// mark image decorations as dirty if the image decorations array is changed\n\tlet imageDecorationShapesDirty = true;\n\n\tconst markDecorationShapesAsDirty = () => $$invalidate(65, imageDecorationShapesDirty = true);\n\n\t// mark image frames as dirrty if the image frames array is changed\n\tlet imageFrameShapesDirty = true;\n\n\tconst markFrameShapesAsDirty = () => $$invalidate(66, imageFrameShapesDirty = true);\n\n\t// mark blend shapes as dirty if the image blend shapes array is changed\n\tlet imageManipulationShapesDirty = true;\n\n\tconst markManipulationShapesAsDirty = () => $$invalidate(67, imageManipulationShapesDirty = true);\n\n\t// clean up so memory is released correctly\n\tonDestroy(() => {\n\t\t// make sure video is paused\n\t\tpause();\n\n\t\t// if image preview src is an object url we need to release it\n\t\tif ($imagePreview && isString($imagePreview.src) && (/^blob:/).test($imagePreview.src)) {\n\t\t\tURL.revokeObjectURL($imagePreview.src);\n\t\t}\n\n\t\timageStateUnsub();\n\t\tstageRectUnsub();\n\t\tstageScalarUnsub();\n\t\timageIsStaticUnsub();\n\t\timageSelectionRectSnapshotUnsub();\n\t\timageSelectionRectUnsub();\n\t\timageCropRectUnsub();\n\t\timageLoadStateUnsub();\n\t\timageProcessStateUnsub();\n\t\tpointerAccuracy.destroy();\n\t\tpointerHoverable.destroy();\n\t\timageProxy.destroy();\n\t\tactiveImages.clear();\n\n\t\t// clear shape cache\n\t\tcanvasComputedAnnotationBaseShapes.length = 0;\n\n\t\tcanvasComputedAnnotationShapes.length = 0;\n\t\tcanvasComputedManipulationShapes.length = 0;\n\t\tcanvasComputedDecorationShapes.length = 0;\n\t\tcanvasComputedFrameShapes.length = 0;\n\n\t\tif (scrambledPreviewImage) {\n\t\t\treleaseCanvas(scrambledPreviewImage);\n\t\t}\n\n\t\tif (canObserveSoftKeyboard) {\n\t\t\twindow.visualViewport.removeEventListener('resize', handleVisualViewportResize);\n\t\t}\n\n\t\ttry {\n\t\t\t$$invalidate(236, imagePreviewCurrent = undefined);\n\t\t\t$$invalidate(299, lastImagePreview = undefined);\n\t\t} catch(err) {\n\t\t\t\n\t\t} // this sometimes throws a Svelte $$invalidate error, not sure why\n\t});\n\n\tconst handleMeasureUtil = e => {\n\t\t// no change\n\t\tif ($utilRect && rectEqual(e.detail, $utilRect)) return;\n\n\t\t// update rect\n\t\tset_store_value(utilRect, $utilRect = e.detail, $utilRect);\n\t};\n\n\tlet localeTestTimeout;\n\n\tfunction onwindowresize() {\n\t\t$$invalidate(31, windowWidth = window_1$1.innerWidth);\n\t\t$$invalidate(32, windowHeight = window_1$1.innerHeight);\n\t}\n\n\tconst measure_handler = e => set_store_value(toolRect, $toolRect = e.detail, $toolRect);\n\tconst select_handler = ({ detail }) => $$invalidate(43, utilSelected = detail);\n\n\tfunction utilpanel_component_binding(value, panel) {\n\t\tif ($$self.$$.not_equal(pluginInterface[panel], value)) {\n\t\t\tpluginInterface[panel] = value;\n\t\t\t(($$invalidate(1, pluginInterface), $$invalidate(284, pluginComponents)), $$invalidate(27, pluginOptions));\n\t\t}\n\t}\n\n\tconst show_handler = panel => handleShowUtil(panel);\n\tconst hide_handler = panel => handleHideUtil(panel);\n\tconst fade_handler = (panel, { detail }) => handleFadeUtil(panel, detail);\n\tconst measure_handler_1 = e => set_store_value(tabRect, $tabRect = e.detail, $tabRect);\n\n\tfunction utilpanel_component_binding_1(value) {\n\t\tif ($$self.$$.not_equal(pluginInterface[utilSelected], value)) {\n\t\t\tpluginInterface[utilSelected] = value;\n\t\t\t(($$invalidate(1, pluginInterface), $$invalidate(284, pluginComponents)), $$invalidate(27, pluginOptions));\n\t\t}\n\t}\n\n\tconst show_handler_1 = () => handleShowUtil(utilSelected);\n\tconst hide_handler_1 = () => handleHideUtil(utilSelected);\n\tconst fade_handler_1 = ({ detail }) => handleFadeUtil(utilSelected, detail);\n\n\tconst func = canvasState => {\n\n\t\t// current draw state\n\t\tconst drawState = { ...canvasState, ...getStageState() };\n\n\t\t// allow devs to add custom overlay to `imageOverlay`\n\t\tconst { annotationShapes, decorationShapes, interfaceShapes, frameShapes, selectionShapes } = willRenderCanvas(\n\t\t\t{\n\t\t\t\tannotationShapes: $imageAnnotation,\n\t\t\t\tdecorationShapes: $imageDecoration,\n\t\t\t\tinterfaceShapes: $imageOverlay,\n\t\t\t\tframeShapes: $imageFrame,\n\t\t\t\tselectionShapes: $imageSelection\n\t\t\t},\n\t\t\tdrawState\n\t\t);\n\n\t\t// need to map shapes\n\t\treturn createCanvasState(drawState, manipulationShapes, annotationShapes, decorationShapes, interfaceShapes, frameShapes, selectionShapes);\n\t};\n\n\tconst func_1 = () => {\n\t\t// we've just drawn the shapes so mark as clean\n\t\t$$invalidate(63, imageAnnotationShapesDirty = false);\n\n\t\t$$invalidate(64, imageAnnotationRequiresPreprocessing = false);\n\t\t$$invalidate(65, imageDecorationShapesDirty = false);\n\t\t$$invalidate(66, imageFrameShapesDirty = false);\n\t\t$$invalidate(67, imageManipulationShapesDirty = false);\n\t};\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\trootPortal = $$value;\n\t\t\t$$invalidate(36, rootPortal);\n\t\t});\n\t}\n\n\tfunction canvaspanandzoom_zoomLevel_binding(value) {\n\t\tzoomLevel = value;\n\t\t($$invalidate(0, zoomLevel), $$invalidate(272, markupEditorZoomLevel));\n\t}\n\n\tfunction canvaspanandzoom_zoomControls_binding(value) {\n\t\tzoomControls = value;\n\t\t$$invalidate(33, zoomControls);\n\t}\n\n\tfunction canvaspanandzoom_zoomMultiTouching_binding(value) {\n\t\tzoomMultiTouching = value;\n\t\t$$invalidate(34, zoomMultiTouching);\n\t}\n\n\tfunction input_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tuserTextInputField = $$value;\n\t\t\t$$invalidate(61, userTextInputField);\n\t\t});\n\t}\n\n\tfunction div_binding_1($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\troot = $$value;\n\t\t\t$$invalidate(2, root);\n\t\t});\n\t}\n\n\tconst measure_handler_2 = e => set_store_value(clientRect, $clientRect = e.detail, $clientRect);\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(237, klass = $$props.class);\n\t\tif ('layout' in $$props) $$invalidate(238, layoutMode = $$props.layout);\n\t\tif ('stores' in $$props) $$invalidate(239, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(3, locale = $$props.locale);\n\t\tif ('id' in $$props) $$invalidate(4, id = $$props.id);\n\t\tif ('util' in $$props) $$invalidate(240, util = $$props.util);\n\t\tif ('utils' in $$props) $$invalidate(241, utils = $$props.utils);\n\t\tif ('animations' in $$props) $$invalidate(242, animations = $$props.animations);\n\t\tif ('disabled' in $$props) $$invalidate(243, disabled = $$props.disabled);\n\t\tif ('previewUpscale' in $$props) $$invalidate(244, previewUpscale = $$props.previewUpscale);\n\t\tif ('previewPad' in $$props) $$invalidate(245, previewPad = $$props.previewPad);\n\t\tif ('previewMaskOpacity' in $$props) $$invalidate(5, previewMaskOpacity = $$props.previewMaskOpacity);\n\t\tif ('previewImageDataMaxSize' in $$props) $$invalidate(246, previewImageDataMaxSize = $$props.previewImageDataMaxSize);\n\t\tif ('previewImageTextPixelRatio' in $$props) $$invalidate(6, previewImageTextPixelRatio = $$props.previewImageTextPixelRatio);\n\t\tif ('markupMaskOpacity' in $$props) $$invalidate(7, markupMaskOpacity = $$props.markupMaskOpacity);\n\t\tif ('zoomMaskOpacity' in $$props) $$invalidate(247, zoomMaskOpacity = $$props.zoomMaskOpacity);\n\t\tif ('elasticityMultiplier' in $$props) $$invalidate(8, elasticityMultiplier = $$props.elasticityMultiplier);\n\t\tif ('willRevert' in $$props) $$invalidate(248, willRevert = $$props.willRevert);\n\t\tif ('willProcessImage' in $$props) $$invalidate(249, willProcessImage = $$props.willProcessImage);\n\t\tif ('willRenderCanvas' in $$props) $$invalidate(9, willRenderCanvas = $$props.willRenderCanvas);\n\t\tif ('willRenderToolbar' in $$props) $$invalidate(250, willRenderToolbar = $$props.willRenderToolbar);\n\t\tif ('willRenderUtilTabs' in $$props) $$invalidate(251, willRenderUtilTabs = $$props.willRenderUtilTabs);\n\t\tif ('willSetHistoryInitialState' in $$props) $$invalidate(252, willSetHistoryInitialState = $$props.willSetHistoryInitialState);\n\t\tif ('enableButtonExport' in $$props) $$invalidate(253, enableButtonExport = $$props.enableButtonExport);\n\t\tif ('enableButtonRevert' in $$props) $$invalidate(254, enableButtonRevert = $$props.enableButtonRevert);\n\t\tif ('enableNavigateHistory' in $$props) $$invalidate(255, enableNavigateHistory = $$props.enableNavigateHistory);\n\t\tif ('enableToolbar' in $$props) $$invalidate(10, enableToolbar = $$props.enableToolbar);\n\t\tif ('enableUtils' in $$props) $$invalidate(256, enableUtils = $$props.enableUtils);\n\t\tif ('enableButtonClose' in $$props) $$invalidate(257, enableButtonClose = $$props.enableButtonClose);\n\t\tif ('enableDropImage' in $$props) $$invalidate(258, enableDropImage = $$props.enableDropImage);\n\t\tif ('enablePasteImage' in $$props) $$invalidate(259, enablePasteImage = $$props.enablePasteImage);\n\t\tif ('enableBrowseImage' in $$props) $$invalidate(260, enableBrowseImage = $$props.enableBrowseImage);\n\t\tif ('accept' in $$props) $$invalidate(261, accept = $$props.accept);\n\t\tif ('enableTransparencyGrid' in $$props) $$invalidate(11, enableTransparencyGrid = $$props.enableTransparencyGrid);\n\t\tif ('layoutDirectionPreference' in $$props) $$invalidate(262, layoutDirectionPreference = $$props.layoutDirectionPreference);\n\t\tif ('layoutHorizontalUtilsPreference' in $$props) $$invalidate(263, layoutHorizontalUtilsPreference = $$props.layoutHorizontalUtilsPreference);\n\t\tif ('layoutVerticalUtilsPreference' in $$props) $$invalidate(264, layoutVerticalUtilsPreference = $$props.layoutVerticalUtilsPreference);\n\t\tif ('layoutVerticalToolbarPreference' in $$props) $$invalidate(265, layoutVerticalToolbarPreference = $$props.layoutVerticalToolbarPreference);\n\t\tif ('layoutVerticalControlGroupsPreference' in $$props) $$invalidate(266, layoutVerticalControlGroupsPreference = $$props.layoutVerticalControlGroupsPreference);\n\t\tif ('layoutVerticalControlTabsPreference' in $$props) $$invalidate(267, layoutVerticalControlTabsPreference = $$props.layoutVerticalControlTabsPreference);\n\t\tif ('supportedMediaTypes' in $$props) $$invalidate(268, supportedMediaTypes = $$props.supportedMediaTypes);\n\t\tif ('status' in $$props) $$invalidate(235, status = $$props.status);\n\t\tif ('formatStatusImageLoading' in $$props) $$invalidate(269, formatStatusImageLoading = $$props.formatStatusImageLoading);\n\t\tif ('formatStatusImageProcessing' in $$props) $$invalidate(270, formatStatusImageProcessing = $$props.formatStatusImageProcessing);\n\t\tif ('formatStatusSupportError' in $$props) $$invalidate(271, formatStatusSupportError = $$props.formatStatusSupportError);\n\t\tif ('textDirection' in $$props) $$invalidate(12, textDirection = $$props.textDirection);\n\t\tif ('markupEditorZoomLevel' in $$props) $$invalidate(272, markupEditorZoomLevel = $$props.markupEditorZoomLevel);\n\t\tif ('markupEditorZoomLevels' in $$props) $$invalidate(13, markupEditorZoomLevels = $$props.markupEditorZoomLevels);\n\t\tif ('markupEditorZoomAdjustStep' in $$props) $$invalidate(14, markupEditorZoomAdjustStep = $$props.markupEditorZoomAdjustStep);\n\t\tif ('markupEditorZoomAdjustFactor' in $$props) $$invalidate(15, markupEditorZoomAdjustFactor = $$props.markupEditorZoomAdjustFactor);\n\t\tif ('markupEditorZoomAdjustWheelFactor' in $$props) $$invalidate(16, markupEditorZoomAdjustWheelFactor = $$props.markupEditorZoomAdjustWheelFactor);\n\t\tif ('markupEditorInteractionMode' in $$props) $$invalidate(273, markupEditorInteractionMode = $$props.markupEditorInteractionMode);\n\t\tif ('muteAudio' in $$props) $$invalidate(274, muteAudio = $$props.muteAudio);\n\t\tif ('willSetMediaInitialTimeOffset' in $$props) $$invalidate(275, willSetMediaInitialTimeOffset = $$props.willSetMediaInitialTimeOffset);\n\t\tif ('enablePan' in $$props) $$invalidate(17, enablePan = $$props.enablePan);\n\t\tif ('enableZoom' in $$props) $$invalidate(18, enableZoom = $$props.enableZoom);\n\t\tif ('enableZoomControls' in $$props) $$invalidate(276, enableZoomControls = $$props.enableZoomControls);\n\t\tif ('enableZoomInput' in $$props) $$invalidate(19, enableZoomInput = $$props.enableZoomInput);\n\t\tif ('enablePanInput' in $$props) $$invalidate(277, enablePanInput = $$props.enablePanInput);\n\t\tif ('enableCanvasAlpha' in $$props) $$invalidate(20, enableCanvasAlpha = $$props.enableCanvasAlpha);\n\t\tif ('enablePanLimit' in $$props) $$invalidate(21, enablePanLimit = $$props.enablePanLimit);\n\t\tif ('panLimitGutterScalar' in $$props) $$invalidate(22, panLimitGutterScalar = $$props.panLimitGutterScalar);\n\t\tif ('pan' in $$props) $$invalidate(278, pan = $$props.pan);\n\t\tif ('zoomPresetOptions' in $$props) $$invalidate(23, zoomPresetOptions = $$props.zoomPresetOptions);\n\t\tif ('zoomAdjustStep' in $$props) $$invalidate(24, zoomAdjustStep = $$props.zoomAdjustStep);\n\t\tif ('zoomAdjustFactor' in $$props) $$invalidate(25, zoomAdjustFactor = $$props.zoomAdjustFactor);\n\t\tif ('zoomAdjustWheelFactor' in $$props) $$invalidate(26, zoomAdjustWheelFactor = $$props.zoomAdjustWheelFactor);\n\t\tif ('zoomLevel' in $$props) $$invalidate(0, zoomLevel = $$props.zoomLevel);\n\t\tif ('fixScrollDirection' in $$props) $$invalidate(279, fixScrollDirection = $$props.fixScrollDirection);\n\t\tif ('imagePreviewSrc' in $$props) $$invalidate(282, imagePreviewSrc = $$props.imagePreviewSrc);\n\t\tif ('imageOrienter' in $$props) $$invalidate(283, imageOrienter = $$props.imageOrienter);\n\t\tif ('pluginComponents' in $$props) $$invalidate(284, pluginComponents = $$props.pluginComponents);\n\t\tif ('pluginOptions' in $$props) $$invalidate(27, pluginOptions = $$props.pluginOptions);\n\t\tif ('root' in $$props) $$invalidate(2, root = $$props.root);\n\t\tif ('imageSourceToImageData' in $$props) $$invalidate(28, imageSourceToImageData = $$props.imageSourceToImageData);\n\t\tif ('imagePreviewCurrent' in $$props) $$invalidate(236, imagePreviewCurrent = $$props.imagePreviewCurrent);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[9] & /*fixScrollDirection*/ 1) {\n\t\t\tfixScrollDirectionStore.set(fixScrollDirection);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8) {\n\t\t\t// is true if has locale\n\t\t\t$$invalidate(306, hasLocale = !!locale);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*zoomLevel*/ 1 | $$self.$$.dirty[8] & /*markupEditorZoomLevel*/ 16777216) {\n\t\t\t// @deprecated, remove in v9\n\t\t\t$$invalidate(0, zoomLevel = zoomLevel === null ? markupEditorZoomLevel : zoomLevel);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*pluginInterface*/ 2 | $$self.$$.dirty[9] & /*pluginComponents*/ 32) {\n\t\t\t{\n\t\t\t\tlet changed = false;\n\n\t\t\t\t// create plugin interfaces\n\t\t\t\tpluginComponents.forEach(([key]) => {\n\t\t\t\t\tif (pluginInterface[key]) return;\n\t\t\t\t\t$$invalidate(1, pluginInterface[key] = {}, pluginInterface);\n\t\t\t\t\tchanged = true;\n\t\t\t\t});\n\n\t\t\t\tif (changed) {\n\t\t\t\t\t$$invalidate(296, registeredPluginsComponents = [...pluginComponents]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*utils*/ 16777216 | $$self.$$.dirty[9] & /*hasLocale, registeredPluginsComponents*/ 134348800) {\n\t\t\t$$invalidate(359, utilsFiltered = hasLocale && registeredPluginsComponents.length\n\t\t\t? utils || registeredPluginsComponents.map(([id]) => id)\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*pluginOptions*/ 134217728 | $$self.$$.dirty[9] & /*registeredPluginsComponents*/ 131072 | $$self.$$.dirty[11] & /*utilsFiltered*/ 262144 | $$self.$$.dirty[13] & /*$imageFile*/ 8) {\n\t\t\t$$invalidate(360, utilsAvailable = getAvailableUtils(utilsFiltered, registeredPluginsComponents, pluginOptions, { src: $imageFile }));\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*utilsAvailable*/ 524288) {\n\t\t\t$$invalidate(313, utilsDefined = utilsAvailable.length);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[10] & /*utilsDefined*/ 8 | $$self.$$.dirty[11] & /*utilsFiltered*/ 262144) {\n\t\t\t$$invalidate(358, utilsMerged = utilsDefined && utilsFiltered.map(utilId => {\n\t\t\t\tconst availableUtil = getAvailableUtilById(utilId);\n\t\t\t\tif (!availableUtil) return;\n\t\t\t\tconst label = locale[`${utilId}Label`];\n\t\t\t\tconst title = locale[`${utilId}Title`];\n\n\t\t\t\treturn {\n\t\t\t\t\tid: utilId,\n\t\t\t\t\tview: availableUtil[1],\n\t\t\t\t\ttabIcon: locale[`${utilId}Icon`],\n\t\t\t\t\ttabLabel: label,\n\t\t\t\t\ttabTitle: isString(title) ? title : label\n\t\t\t\t};\n\t\t\t}).filter(Boolean) || []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*utilsMerged*/ 131072) {\n\t\t\t// is video content\n\t\t\t$$invalidate(377, isTrimPluginLoaded = !!utilsMerged.find(util => util.id === 'trim'));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imagePreview, isTrimPluginLoaded*/ 160 | $$self.$$.dirty[13] & /*$mediaDuration*/ 134217728) {\n\t\t\t$$invalidate(312, isVideoSupported = !!($mediaDuration && $imagePreview && isTrimPluginLoaded));\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*util*/ 8388608 | $$self.$$.dirty[10] & /*utilsDefined*/ 8) {\n\t\t\t$$invalidate(43, utilSelected = utilsDefined && util && typeof util === 'string' && getAvailableUtilById(util)\n\t\t\t? util\n\t\t\t: utilsDefined > 0 ? getFirstAvailableUtil() : undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*utilSelected*/ 4096 | $$self.$$.dirty[10] & /*isVideoSupported*/ 4) {\n\t\t\t// pause video when util changes\n\t\t\tif (isVideoSupported && utilSelected) pause();\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isVideoSupported*/ 4 | $$self.$$.dirty[12] & /*$imagePreview*/ 128) {\n\t\t\t// handle video events\n\t\t\tif (isVideoSupported) {\n\t\t\t\t$imagePreview.addEventListener('play', updatePlayState);\n\t\t\t\t$imagePreview.addEventListener('pause', updatePlayState);\n\t\t\t} else if ($imagePreview && $imagePreview.nodeName === 'video') {\n\t\t\t\t$imagePreview.removeEventListener('play', updatePlayState);\n\t\t\t\t$imagePreview.removeEventListener('pause', updatePlayState);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isVideoSupported*/ 4) {\n\t\t\tif (isVideoSupported) initFrameOffset();\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$videoFramePeekOffset, $videoFrameOffset*/ 603979776) {\n\t\t\tdidUpdateFrame($videoFramePeekOffset || $videoFrameOffset);\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$videoFrameOffset*/ 67108864) {\n\t\t\t$$invalidate(375, videoFrameOffsetFixed = $videoFrameOffset && fixPrecision($videoFrameOffset, 6));\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$mediaTrim, $mediaDuration, $mediaMaxDuration*/ 1224736768) {\n\t\t\t$$invalidate(373, videoTrim = $mediaTrim || [[0, Math.min($mediaDuration, $mediaMaxDuration) / $mediaDuration]]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*videoTrim*/ 2) {\n\t\t\tvideoTrimFirst = videoTrim[0][0];\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*videoTrim*/ 2) {\n\t\t\tvideoTrimLast = videoTrim[videoTrim.length - 1][1];\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*videoTrim*/ 2) {\n\t\t\t$$invalidate(376, videoTrimFixed = videoTrim.map(([from, to]) => [fixPrecision(from, 6), fixPrecision(to, 6)]));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*videoTrimFixed, videoFrameOffsetFixed*/ 24) {\n\t\t\t$$invalidate(374, videoTrimCurrentIndex = videoTrimFixed.findIndex(([from, to]) => {\n\t\t\t\treturn videoFrameOffsetFixed >= from && videoFrameOffsetFixed <= to;\n\t\t\t}));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*videoTrimCurrentIndex, videoTrimFixed, videoFrameOffsetFixed*/ 28) {\n\t\t\tvideoTrimNextIndex = videoTrimCurrentIndex === -1 && videoTrimFixed.findIndex((currentClip, index, arr) => {\n\t\t\t\tconst prevClip = arr[index - 1];\n\n\t\t\t\tif (!prevClip) {\n\t\t\t\t\treturn videoFrameOffsetFixed <= currentClip[0];\n\t\t\t\t}\n\n\t\t\t\treturn videoFrameOffsetFixed <= currentClip[0] && videoFrameOffsetFixed >= prevClip[1];\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*muteAudio*/ 67108864) {\n\t\t\tisMuted.set(muteAudio);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imagePreview*/ 128 | $$self.$$.dirty[13] & /*$isMuted*/ 268435456) {\n\t\t\t$imagePreview && $isMuted ? mute() : unmute();\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isVideoSupported*/ 4 | $$self.$$.dirty[13] & /*$videoFrameOffset*/ 67108864) {\n\t\t\t// sync current time with frame offset\n\t\t\tif (isVideoSupported) mediaCurrentTime.set(getDuration() * $videoFrameOffset);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imagePreview*/ 128 | $$self.$$.dirty[13] & /*$mediaVolume*/ 33554432) {\n\t\t\t$imagePreview && setVolume($mediaVolume);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*elasticityMultiplier*/ 256) {\n\t\t\tset_store_value(elasticityMultiplierStore, $elasticityMultiplierStore = elasticityMultiplier, $elasticityMultiplierStore);\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*layoutMode*/ 2097152) {\n\t\t\t// set to new object to force redraw\n\t\t\t$$invalidate(369, isOverlayModeEnabled = layoutMode === 'overlay');\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*enableUtils*/ 256 | $$self.$$.dirty[11] & /*isOverlayModeEnabled*/ 268435456) {\n\t\t\t$$invalidate(45, showUtils = enableUtils && !isOverlayModeEnabled);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*pluginOptions, pluginInterface*/ 134217730) {\n\t\t\t// map plugin options to plugin interface\n\t\t\tif (pluginOptions) {\n\t\t\t\t// for every plugin in plugin options\n\t\t\t\tObject.entries(pluginOptions).forEach(([name, plugin]) => {\n\t\t\t\t\t// for every prop defined for this plugin\n\t\t\t\t\tObject.entries(plugin).forEach(([prop, value]) => {\n\t\t\t\t\t\t// set value to interface if available\n\t\t\t\t\t\tif (!pluginInterface[name]) return;\n\n\t\t\t\t\t\t// set prop value\n\t\t\t\t\t\t$$invalidate(1, pluginInterface[name][prop] = value, pluginInterface);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$prefersReducedMotion*/ 524288) {\n\t\t\t$$invalidate(370, acceptsAnimations = !$prefersReducedMotion);\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*animations*/ 33554432 | $$self.$$.dirty[11] & /*supportsAnimations, acceptsAnimations*/ 1610612736) {\n\t\t\t// if the browser _can_ run animations when the dev wants to run animations\n\t\t\tset_store_value(\n\t\t\t\tisAnimated,\n\t\t\t\t$isAnimated = animations === 'always'\n\t\t\t\t? supportsAnimations\n\t\t\t\t: animations === 'never'\n\t\t\t\t\t? false\n\t\t\t\t\t: supportsAnimations && acceptsAnimations,\n\t\t\t\t$isAnimated\n\t\t\t);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isAnimated*/ 4194304 | $$self.$$.dirty[7] & /*disabled*/ 67108864) {\n\t\t\tdisabledTransition.set(disabled ? 1 : 0, { hard: !$isAnimated });\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*previewImageDataMaxSize*/ 536870912) {\n\t\t\tmaxImageDataSize = previewImageDataMaxSize\n\t\t\t? sizeMin(previewImageDataMaxSize, maxTextureSize)\n\t\t\t: maxTextureSize;\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$images*/ 8388608) {\n\t\t\timageProxy.update($images[0]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$shapePreprocessor*/ 4194304) {\n\t\t\tpreprocessShape = $shapePreprocessor\n\t\t\t? (shape, options) => $shapePreprocessor(shape, {\n\t\t\t\t\tflipX: undefined,\n\t\t\t\t\tflipY: undefined,\n\t\t\t\t\trotation: undefined,\n\t\t\t\t\t...options,\n\t\t\t\t\tisPreview: true\n\t\t\t\t})\n\t\t\t: passthrough;\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageSelection*/ 268435456) {\n\t\t\tArray.isArray($imageSelection) && dispatch('selectionchange', [...$imageSelection]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*enableZoomControls*/ 268435456 | $$self.$$.dirty[13] & /*$allowZoomControls*/ 2097152) {\n\t\t\tenableZoomControlsProp.set($allowZoomControls && enableZoomControls);\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*markupEditorInteractionMode, enablePanInput*/ 570425344) {\n\t\t\tenablePanInputProp.set(markupEditorInteractionMode === 'pan'\n\t\t\t? true\n\t\t\t: enablePanInput);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$clientRect*/ 1048576) {\n\t\t\t$clientRect && rootRect.set(rectCreate($clientRect.x, $clientRect.y, $clientRect.width, $clientRect.height));\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*isOverlayModeEnabled*/ 268435456 | $$self.$$.dirty[12] & /*$rootRect, $imageLoadState*/ 67108928) {\n\t\t\t$rootRect && isOverlayModeEnabled && $imageLoadState && $imageLoadState.complete && syncRootAspectRatio();\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*utilsFiltered*/ 262144) {\n\t\t\t$$invalidate(46, shouldRenderTabs = utilsFiltered.length > 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*shouldRenderTabs*/ 32768) {\n\t\t\tif (!shouldRenderTabs) tabRect.set(rectCreateEmpty());\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*enableToolbar*/ 1024 | $$self.$$.dirty[13] & /*$rootInsetTop*/ 1048576) {\n\t\t\tif (!enableToolbar) toolRect.set(rectCreate(0, $rootInsetTop, 0, 0));\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*supportsAnimations*/ 1073741824 | $$self.$$.dirty[12] & /*$isInteracting*/ 4096) {\n\t\t\t$$invalidate(372, canAnimate = !$isInteracting && supportsAnimations);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$clientRect*/ 1048576) {\n\t\t\t$$invalidate(314, hasClientRect = $clientRect && $clientRect.width > 0 && $clientRect.height > 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[10] & /*hasClientRect, utilsDefined*/ 24) {\n\t\t\t$$invalidate(40, canRender = hasClientRect && locale && !!utilsDefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*canRender*/ 512) {\n\t\t\tsetTimeout(() => $$invalidate(297, canRenderDelayed = canRender), 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*animations*/ 33554432 | $$self.$$.dirty[9] & /*canRenderDelayed*/ 262144 | $$self.$$.dirty[11] & /*acceptsAnimations*/ 536870912 | $$self.$$.dirty[12] & /*canAnimate*/ 1) {\n\t\t\t// if the dev wants to run animations\n\t\t\tset_store_value(\n\t\t\t\tshouldAnimate,\n\t\t\t\t$shouldAnimate = animations === 'always'\n\t\t\t\t? canAnimate\n\t\t\t\t: animations === 'never'\n\t\t\t\t\t? false\n\t\t\t\t\t: canAnimate && canRenderDelayed && acceptsAnimations,\n\t\t\t\t$shouldAnimate\n\t\t\t);\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*previewUpscale*/ 134217728 | $$self.$$.dirty[11] & /*isOverlayModeEnabled*/ 268435456) {\n\t\t\tpreviewShouldUpscale.set(previewUpscale || isOverlayModeEnabled);\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*previewPad*/ 268435456) {\n\t\t\tshouldPadPreview.set(previewPad);\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*pan*/ 1073741824) {\n\t\t\tif (pan) {\n\t\t\t\timageSelectionPan.set(pan);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 4 | $$self.$$.dirty[13] & /*$imageSelectionZoom, $stageScalar*/ 294912) {\n\t\t\tif (root) {\n\t\t\t\troot.dispatchEvent(createPing('markupzoom', $imageSelectionZoom)); // @deprecated\n\n\t\t\t\troot.dispatchEvent(createPing('zoom', isNumber($imageSelectionZoom)\n\t\t\t\t? $imageSelectionZoom\n\t\t\t\t: $stageScalar));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 4 | $$self.$$.dirty[13] & /*$imageSelectionPan*/ 131072) {\n\t\t\tif (root) {\n\t\t\t\troot.dispatchEvent(createPing('markuppan', $imageSelectionPan)); // @deprecated\n\t\t\t\troot.dispatchEvent(createPing('pan', $imageSelectionPan));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$imageCropRect*/ 16384) {\n\t\t\t// reset selection stored state when crop rect is updated\n\t\t\tif ($imageCropRect) imageSelectionStoredStateReset();\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$imageStaticBounds*/ 65536) {\n\t\t\t$imageStaticBounds && centerImageStaticBounds();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*utilSelected, $isAnimated*/ 4198400) {\n\t\t\tutilSelected && imageOutlineOpacity.set(0.075, { hard: !$isAnimated });\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*zoomMaskOpacity*/ 1073741824) {\n\t\t\t$$invalidate(367, OVERLAY_OPACITY_MAX = zoomMaskOpacity);\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$stagePadded, $stagePadding*/ 12288) {\n\t\t\t$$invalidate(368, overlayMin = $stagePadded\n\t\t\t? -Math.max(...Object.values($stagePadding))\n\t\t\t: 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageSelectionRectPresentation, $stageRect, $isAnimated*/ 138936320 | $$self.$$.dirty[11] & /*overlayMin, OVERLAY_OPACITY_MAX*/ 201326592) {\n\t\t\tif ($imageSelectionRectPresentation) {\n\t\t\t\tlet l = $imageSelectionRectPresentation.x - $stageRect.x;\n\t\t\t\tlet r = $stageRect.x + $stageRect.width - ($imageSelectionRectPresentation.x + $imageSelectionRectPresentation.width);\n\t\t\t\tlet t = $imageSelectionRectPresentation.y - $stageRect.y;\n\t\t\t\tlet b = $stageRect.y + $stageRect.height - ($imageSelectionRectPresentation.y + $imageSelectionRectPresentation.height);\n\t\t\t\tlet d = Math.min(l, t, r, b);\n\n\t\t\t\toverlayOpacity.set(\n\t\t\t\t\td > overlayMin\n\t\t\t\t\t? 0\n\t\t\t\t\t: Math.min(OVERLAY_OPACITY_MAX, Math.abs(d / OVERLAY_OPACITY_TWEEN_DIST)),\n\t\t\t\t\t{ hard: !$isAnimated }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$pixelRatio*/ 67108864) {\n\t\t\t// this slightly overlaps the overlay parts preventing bright background colors from shining through\n\t\t\t$$invalidate(366, overlayOverlap = 0.55 / $pixelRatio);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$stageRect, $isAnimated*/ 4718592 | $$self.$$.dirty[11] & /*overlayOverlap*/ 33554432) {\n\t\t\t$stageRect && overlayLeftRect.set(\n\t\t\t\t{\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: $stageRect.y,\n\t\t\t\t\twidth: $stageRect.x < OVERLAY_OPACITY_TWEEN_DIST\n\t\t\t\t\t? 0\n\t\t\t\t\t: $stageRect.x,\n\t\t\t\t\theight: $stageRect.height + overlayOverlap\n\t\t\t\t},\n\t\t\t\t{ hard: !$isAnimated }\n\t\t\t);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$stageRect, $isAnimated*/ 4718592 | $$self.$$.dirty[11] & /*overlayOverlap*/ 33554432 | $$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$stageRect && overlayTopRect.set(\n\t\t\t\t{\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: 0,\n\t\t\t\t\twidth: $rootRect.width,\n\t\t\t\t\theight: $stageRect.y + overlayOverlap\n\t\t\t\t},\n\t\t\t\t{ hard: !$isAnimated }\n\t\t\t);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$stageRect, $isAnimated*/ 4718592 | $$self.$$.dirty[11] & /*overlayOverlap*/ 33554432 | $$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\tif ($stageRect) {\n\t\t\t\tlet x = $stageRect.x + $stageRect.width;\n\t\t\t\tlet width = $rootRect.width - ($stageRect.x + $stageRect.width);\n\n\t\t\t\tif (width < OVERLAY_OPACITY_TWEEN_DIST) {\n\t\t\t\t\tx += width;\n\t\t\t\t\twidth = 0;\n\t\t\t\t}\n\n\t\t\t\toverlayRightRect.set(\n\t\t\t\t\t{\n\t\t\t\t\t\tx,\n\t\t\t\t\t\ty: $stageRect.y,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight: $stageRect.height + overlayOverlap\n\t\t\t\t\t},\n\t\t\t\t\t{ hard: !$isAnimated }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$stageRect, $isAnimated*/ 4718592 | $$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$stageRect && overlayBottomRect.set(\n\t\t\t\t{\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: $stageRect.y + $stageRect.height,\n\t\t\t\t\twidth: $rootRect.width,\n\t\t\t\t\theight: $rootRect.height - ($stageRect.y + $stageRect.height)\n\t\t\t\t},\n\t\t\t\t{ hard: !$isAnimated }\n\t\t\t);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$rootBackgroundColor*/ 33554432 | $$self.$$.dirty[13] & /*$overlayLeftRect, $overlayOpacity*/ 2304) {\n\t\t\t$$invalidate(362, overlayLeft = $overlayLeftRect && {\n\t\t\t\tid: OVERLAY_ID,\n\t\t\t\tbackgroundColor: $rootBackgroundColor,\n\t\t\t\topacity: $overlayOpacity,\n\t\t\t\t...$overlayLeftRect\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$rootBackgroundColor*/ 33554432 | $$self.$$.dirty[13] & /*$overlayTopRect, $overlayOpacity*/ 1280) {\n\t\t\t$$invalidate(365, overlayTop = $overlayTopRect && {\n\t\t\t\tid: OVERLAY_ID,\n\t\t\t\tbackgroundColor: $rootBackgroundColor,\n\t\t\t\topacity: $overlayOpacity,\n\t\t\t\t...$overlayTopRect\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$rootBackgroundColor*/ 33554432 | $$self.$$.dirty[13] & /*$overlayRightRect, $overlayOpacity*/ 768) {\n\t\t\t$$invalidate(364, overlayRight = $overlayRightRect && {\n\t\t\t\tid: OVERLAY_ID,\n\t\t\t\tbackgroundColor: $rootBackgroundColor,\n\t\t\t\topacity: $overlayOpacity,\n\t\t\t\t...$overlayRightRect\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$rootBackgroundColor*/ 33554432 | $$self.$$.dirty[13] & /*$overlayBottomRect, $overlayOpacity*/ 384) {\n\t\t\t$$invalidate(363, overlayBottom = $overlayBottomRect && {\n\t\t\t\tid: OVERLAY_ID,\n\t\t\t\tbackgroundColor: $rootBackgroundColor,\n\t\t\t\topacity: $overlayOpacity,\n\t\t\t\t...$overlayBottomRect\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*overlayTop, overlayRight, overlayBottom, overlayLeft*/ 31457280) {\n\t\t\t$$invalidate(361, gradientOverlays = [overlayTop, overlayRight, overlayBottom, overlayLeft].filter(Boolean));\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*gradientOverlays*/ 1048576 | $$self.$$.dirty[13] & /*$imageOverlayMarkup*/ 64) {\n\t\t\t// if overlay top changes\n\t\t\tif (gradientOverlays && $imageOverlayMarkup) {\n\t\t\t\timageOverlayMarkup.update(shapes => {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...shapes.filter(markup => markup.id !== OVERLAY_ID),\n\t\t\t\t\t\t...gradientOverlays\n\t\t\t\t\t];\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[9] & /*imagePreviewSrc*/ 8 | $$self.$$.dirty[13] & /*$imageFile*/ 8) {\n\t\t\timagePreviewSource.set(imagePreviewSrc\n\t\t\t? imagePreviewSrc\n\t\t\t: $imageFile || undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 4 | $$self.$$.dirty[7] & /*imagePreviewCurrent*/ 524288 | $$self.$$.dirty[12] & /*$imagePreview*/ 128) {\n\t\t\t{\n\t\t\t\t$$invalidate(236, imagePreviewCurrent = $imagePreview);\n\t\t\t\tif ($imagePreview) root.dispatchEvent(createPing('loadpreview', imagePreviewCurrent));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imagePreviewSource*/ 134217728) {\n\t\t\tif ($imagePreviewSource) resetPreviews();\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$history*/ 32) {\n\t\t\t$$invalidate(318, canUndo = $history.index > 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$history*/ 32) {\n\t\t\t$$invalidate(317, canRedo = $history.index < $history.length - 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageAnnotation, $imageDecoration*/ 393216 | $$self.$$.dirty[12] & /*$imageRedaction, $imageManipulation*/ 24576) {\n\t\t\tshapeCollections = [$imageAnnotation, $imageDecoration, $imageRedaction, $imageManipulation];\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*zoomMultiTouching*/ 8) {\n\t\t\timageSelectionMultiTouching.set(zoomMultiTouching);\n\t\t}\n\n\t\tif ($$self.$$.dirty[13] & /*$previewShouldUpscale*/ 16) {\n\t\t\timagePreviewUpscale.set($previewShouldUpscale);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*utilSelected*/ 4096) {\n\t\t\tutilSelectedStore.set(utilSelected);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*utilSelected*/ 4096 | $$self.$$.dirty[9] & /*utilsVisibleFraction*/ 536870912 | $$self.$$.dirty[11] & /*utilsMerged*/ 131072) {\n\t\t\t$$invalidate(308, utilsVisibleFraction = utilsMerged.reduce(\n\t\t\t\t(prev, curr) => {\n\t\t\t\t\tconst value = utilsVisibleFraction && utilsVisibleFraction[curr.id];\n\n\t\t\t\t\tif (value !== undefined) {\n\t\t\t\t\t\tprev[curr.id] = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprev[curr.id] = curr.id === utilSelected ? 1 : 0;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn prev;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*utilSelected*/ 4096) {\n\t\t\t$$invalidate(79, tabsConfig = {\n\t\t\t\tname: utilsUniqueId,\n\t\t\t\tselected: utilSelected\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*utilsMerged*/ 131072) {\n\t\t\t$$invalidate(340, tabs = utilsMerged.map(util => ({\n\t\t\t\tid: util.id,\n\t\t\t\ticon: util.tabIcon,\n\t\t\t\tlabel: util.tabLabel,\n\t\t\t\ttitle: util.tabTitle\n\t\t\t})));\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*utilsMerged*/ 131072) {\n\t\t\t$$invalidate(78, panels = utilsMerged.map(util => util.id));\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*klass*/ 1048576) {\n\t\t\t$$invalidate(77, className = arrayJoin(['PinturaRoot', 'PinturaRootComponent', klass]));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$$invalidate(354, horizontalSpace = $rootRect && ($rootRect.width > 1000\n\t\t\t? 'wide'\n\t\t\t: $rootRect.width < 600 ? 'narrow' : undefined));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$$invalidate(341, hasLimitedSpace = $rootRect && ($rootRect.width <= 320 || $rootRect.height <= 460));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$$invalidate(353, verticalSpace = $rootRect && ($rootRect.height > 1000\n\t\t\t? 'tall'\n\t\t\t: $rootRect.height < 600 ? 'short' : undefined));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 4) {\n\t\t\t$$invalidate(320, isModal = root && root.parentNode && root.parentNode.classList.contains('PinturaModal'));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*windowWidth*/ 1 | $$self.$$.dirty[10] & /*isModal*/ 1024 | $$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$$invalidate(346, isCenteredHorizontally = isModal && $rootRect && windowWidth > $rootRect.width);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*windowHeight*/ 2 | $$self.$$.dirty[10] & /*isModal*/ 1024 | $$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$$invalidate(345, isCenteredVertically = isModal && $rootRect && windowHeight > $rootRect.height);\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*isCenteredHorizontally, isCenteredVertically*/ 48) {\n\t\t\t$$invalidate(347, isCentered = isCenteredHorizontally && isCenteredVertically);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*enableCanvasAlpha*/ 1048576) {\n\t\t\t$$invalidate(344, isTransparent = enableCanvasAlpha);\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*horizontalSpace*/ 8192) {\n\t\t\t$$invalidate(315, isNarrow = horizontalSpace === 'narrow');\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*layoutDirectionPreference*/ 16384 | $$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$$invalidate(355, orientation = getOrientation($rootRect, layoutDirectionPreference));\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*orientation*/ 16384) {\n\t\t\t$$invalidate(76, isLandscape = orientation === 'landscape');\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isNarrow*/ 32 | $$self.$$.dirty[11] & /*verticalSpace*/ 4096) {\n\t\t\t$$invalidate(343, isCompact = isNarrow || verticalSpace === 'short');\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*windowWidth*/ 1 | $$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t$$invalidate(342, hasSwipeNavigation = iOS && $rootRect && windowWidth === $rootRect.width && !shouldPreventSwipe);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*zoomControls*/ 4 | $$self.$$.dirty[13] & /*$utilTools*/ 4) {\n\t\t\t$$invalidate(316, activeUtilTools = [...$utilTools || [], ...zoomControls].filter(Boolean));\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*layoutHorizontalUtilsPreference*/ 32768) {\n\t\t\t$$invalidate(352, navigationHorizontalPreference = `has-navigation-preference-${layoutHorizontalUtilsPreference}`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*layoutVerticalUtilsPreference*/ 65536) {\n\t\t\t$$invalidate(351, navigationVerticalPreference = `has-navigation-preference-${layoutVerticalUtilsPreference}`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*layoutVerticalToolbarPreference*/ 131072) {\n\t\t\t$$invalidate(348, toolbarVerticalPreference = `has-toolbar-preference-${layoutVerticalToolbarPreference}`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*layoutVerticalControlGroupsPreference*/ 262144) {\n\t\t\t$$invalidate(350, controlGroupsVerticalPreference = `has-controlgroups-preference-${layoutVerticalControlGroupsPreference}`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[8] & /*layoutVerticalControlTabsPreference*/ 524288) {\n\t\t\t$$invalidate(349, controlTabsVerticalpreference = `has-controltabs-preference-${layoutVerticalControlTabsPreference}`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t// will update when root element is available (computed style is live, so is updated when the style is updated)\n\t\t\t$$invalidate(357, rootRectDefined = $rootRect !== undefined && $rootRect.width > 0 && $rootRect.height > 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 4 | $$self.$$.dirty[11] & /*rootRectDefined*/ 65536) {\n\t\t\t$$invalidate(356, rootElementComputedStyle = rootRectDefined && root && getComputedStyle(root));\n\t\t}\n\n\t\tif ($$self.$$.dirty[11] & /*rootElementComputedStyle*/ 32768) {\n\t\t\t// sync for first time\n\t\t\tif (rootElementComputedStyle) syncCSSProps();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*enableToolbar*/ 1024 | $$self.$$.dirty[1] & /*$isAnimated, shouldRenderTabs, showUtils*/ 4243456 | $$self.$$.dirty[7] & /*layoutMode, disabled*/ 69206016 | $$self.$$.dirty[10] & /*isModal*/ 1024 | $$self.$$.dirty[11] & /*orientation, horizontalSpace, verticalSpace, navigationHorizontalPreference, navigationVerticalPreference, controlGroupsVerticalPreference, controlTabsVerticalpreference, toolbarVerticalPreference, isCentered, isCenteredHorizontally, isCenteredVertically, isTransparent, isCompact, hasSwipeNavigation, hasLimitedSpace*/ 32767 | $$self.$$.dirty[12] & /*$env*/ 262144 | $$self.$$.dirty[13] & /*$pointerAccuracy, $pointerHoverable*/ 3) {\n\t\t\tenv.set({\n\t\t\t\t...$env,\n\t\t\t\tlayoutMode,\n\t\t\t\torientation,\n\t\t\t\thorizontalSpace,\n\t\t\t\tverticalSpace,\n\t\t\t\tnavigationHorizontalPreference,\n\t\t\t\tnavigationVerticalPreference,\n\t\t\t\tcontrolGroupsVerticalPreference,\n\t\t\t\tcontrolTabsVerticalpreference,\n\t\t\t\ttoolbarVerticalPreference,\n\t\t\t\tisModal,\n\t\t\t\tisDisabled: disabled,\n\t\t\t\tisCentered,\n\t\t\t\tisCenteredHorizontally,\n\t\t\t\tisCenteredVertically,\n\t\t\t\tisAnimated: $isAnimated,\n\t\t\t\tisTransparent,\n\t\t\t\tpointerAccuracy: $pointerAccuracy,\n\t\t\t\tpointerHoverable: $pointerHoverable,\n\t\t\t\tisCompact,\n\t\t\t\thasSwipeNavigation,\n\t\t\t\thasLimitedSpace,\n\t\t\t\thasToolbar: enableToolbar,\n\t\t\t\thasNavigation: shouldRenderTabs && showUtils,\n\t\t\t\tisIOS: iOS,\n\t\t\t\tbrowserVersion: isChrome()\n\t\t\t\t? `chrome-${(navigator.userAgent.match(/Chrome\\/([0-9]+)/) || [])[1]}`\n\t\t\t\t: undefined\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$env*/ 262144) {\n\t\t\t$$invalidate(75, envStr = Object.entries($env).map(([key, value]) => {\n\t\t\t\t// is true boolean prop, use key\n\t\t\t\tif ((/^is|has/).test(key)) {\n\t\t\t\t\treturn value ? toKebabCase(key) : undefined;\n\t\t\t\t}\n\n\t\t\t\t// use value\n\t\t\t\treturn value;\n\t\t\t}).filter(Boolean).join(' '));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*utilSelected*/ 4096) {\n\t\t\t// clear util tools when selected tool changes, when tool becomes active it will update the tools (if needed)\n\t\t\tutilSelected && utilTools.set([]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*utilSelected*/ 4096 | $$self.$$.dirty[8] & /*willRenderUtilTabs*/ 8 | $$self.$$.dirty[10] & /*tabs*/ 1073741824 | $$self.$$.dirty[12] & /*$env*/ 262144) {\n\t\t\t$$invalidate(44, tabsAfterWillRender = willRenderUtilTabs(\n\t\t\t\ttabs.map(tab => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...tab,\n\t\t\t\t\t\tselected: utilSelected === tab.id\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t\t{ ...$env },\n\t\t\t\t() => redrawTrigger.set({})\n\t\t\t));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*tabsAfterWillRender*/ 8192) {\n\t\t\t$$invalidate(74, tabsAreNodes = !!tabsAfterWillRender.find(tab => Array.isArray(tab)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageTransforms, $imagePreviewModifiers*/ 1610612736) {\n\t\t\t$$invalidate(73, imageCanvasState = $imageTransforms && Object.entries($imagePreviewModifiers).filter(([,value]) => value != null).reduce(\n\t\t\t\t(prev, [,value]) => {\n\t\t\t\t\tprev = { ...prev, ...value };\n\t\t\t\t\treturn prev;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageLoadState*/ 67108864) {\n\t\t\t//\n\t\t\t// loading status\n\t\t\t//\n\t\t\t$$invalidate(337, isStartLoadingImageSource = $imageLoadState && $imageLoadState.task === 'any-to-file');\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isStartLoadingImageSource*/ 134217728) {\n\t\t\t// reset active images when loading a new image source\n\t\t\tif (isStartLoadingImageSource && activeImages) {\n\t\t\t\tactiveImages.clear();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageProps*/ 268435456) {\n\t\t\t// if image props are ready\n\t\t\t$$invalidate(339, hasProps = !!$imageProps && !!$imageProps.translation);\n\t\t}\n\n\t\tif ($$self.$$.dirty[9] & /*lastImagePreview*/ 1048576 | $$self.$$.dirty[10] & /*hasProps*/ 536870912 | $$self.$$.dirty[12] & /*$imagePreview*/ 128) {\n\t\t\tif (hasProps && $imagePreview && $imagePreview !== lastImagePreview) {\n\t\t\t\t$$invalidate(299, lastImagePreview = $imagePreview);\n\t\t\t\taddImagePreview();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*hasProps*/ 536870912 | $$self.$$.dirty[12] & /*$imageProps*/ 268435456) {\n\t\t\t// update images when image props change\n\t\t\thasProps && updateImagePreviews($imageProps);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$activeImages*/ 16777216) {\n\t\t\t// clean active images array, removes 'inactive' images when their opacity is 0\n\t\t\tif ($activeImages && $activeImages.length > 1) {\n\t\t\t\tlet imagesToRemove = [];\n\n\t\t\t\tactiveImages.forEach((image, index) => {\n\t\t\t\t\tif (index === 0) return;\n\t\t\t\t\tif (image.get().opacity <= 0) imagesToRemove.push(image);\n\t\t\t\t});\n\n\t\t\t\timagesToRemove.forEach(image => activeImages.remove(image));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[10] & /*missingFeatures*/ 268435456) {\n\t\t\t$$invalidate(39, isSupportsError = locale && missingFeatures.length && getLabelSupportError(missingFeatures, locale));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[9] & /*webGLContextFailed*/ 2097152) {\n\t\t\t$$invalidate(309, isMemoryError = locale && webGLContextFailed && locale.labelMemoryError);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageLoadState*/ 67108864) {\n\t\t\t$$invalidate(329, isImageLoadError = $imageLoadState && !!$imageLoadState.error);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageLoadState*/ 67108864) {\n\t\t\t$$invalidate(42, isWaitingForImage = !$imageLoadState || !$imageLoadState.complete && $imageLoadState.task === undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageLoadState*/ 67108864) {\n\t\t\t$$invalidate(330, imageLoadProgress = $imageLoadState && ($imageLoadState.taskLengthComputable\n\t\t\t? $imageLoadState.taskProgress\n\t\t\t: Infinity));\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isStartLoadingImageSource*/ 134217728) {\n\t\t\tif (isStartLoadingImageSource) set_store_value(imageVisualLoadComplete, $imageVisualLoadComplete = false, $imageVisualLoadComplete);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isAnimated*/ 4194304 | $$self.$$.dirty[9] & /*loadTimer*/ 4194304 | $$self.$$.dirty[12] & /*$imageLoadState*/ 67108864) {\n\t\t\tif ($imageLoadState && $imageLoadState.complete) {\n\t\t\t\tconst minLoaderDuration = $isAnimated ? 250 : 0;\n\n\t\t\t\t// TODO: derive visual load complete from interface rest state instead of arbitrary timer\n\t\t\t\tclearTimeout(loadTimer);\n\n\t\t\t\t$$invalidate(301, loadTimer = setTimeout(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tset_store_value(imageVisualLoadComplete, $imageVisualLoadComplete = true, $imageVisualLoadComplete);\n\t\t\t\t\t},\n\t\t\t\t\tminLoaderDuration\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*isWaitingForImage*/ 2048 | $$self.$$.dirty[10] & /*isImageLoadError*/ 524288 | $$self.$$.dirty[12] & /*$imageLoadState, $imageVisualLoadComplete*/ 83886080) {\n\t\t\t$$invalidate(334, isLoadingImageData = $imageLoadState && !isImageLoadError && !isWaitingForImage && !$imageVisualLoadComplete);\n\t\t}\n\n\t\tif ($$self.$$.dirty[9] & /*imagePreviewLoaderCancelToken*/ 524288 | $$self.$$.dirty[12] & /*$imagePreviewSource, $imagePreview*/ 134217856) {\n\t\t\t// is creating a preview while an image source is set and the preview isn't ready or when a cancel token is found\n\t\t\t$$invalidate(333, isCreatingImagePreview = !!$imagePreviewSource && (!$imagePreview || !!imagePreviewLoaderCancelToken));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isAnimated*/ 4194304 | $$self.$$.dirty[12] & /*$imageVisualLoadComplete*/ 16777216) {\n\t\t\tif ($imageVisualLoadComplete) {\n\t\t\t\tconst gridOpacityFadeDuration = $isAnimated ? 500 : 0;\n\t\t\t\tsetTimeout(() => gridOpacity.set(1, { hard: !$isAnimated }), gridOpacityFadeDuration);\n\t\t\t} else {\n\t\t\t\tgridOpacity.set(0, { hard: !$isAnimated });\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageProcessingPreparing, $imageProcessState*/ 34078720) {\n\t\t\t//\n\t\t\t// processing status\n\t\t\t//\n\t\t\t$$invalidate(328, isProcessingImage = !!($imageProcessingPreparing || $imageProcessState && $imageProcessState.progress !== undefined && !$imageProcessState.complete));\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isProcessingImage*/ 262144) {\n\t\t\tif (isProcessingImage) pause();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*isWaitingForImage*/ 2048 | $$self.$$.dirty[12] & /*$imageLoadState*/ 67108864) {\n\t\t\t$$invalidate(331, imageLoadShowProgressIndicator = $imageLoadState && !($imageLoadState.error || isWaitingForImage));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[12] & /*$imageLoadState*/ 67108864) {\n\t\t\t$$invalidate(332, imageLoadStatusLabel = locale && getImageLoadStatusLabel($imageLoadState, locale));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[12] & /*$imageProcessState*/ 33554432) {\n\t\t\t$$invalidate(327, imageProcessStatusLabel = $imageProcessState && locale && getImageProcessStatusLabel($imageProcessState, locale));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageProcessState*/ 33554432) {\n\t\t\t$$invalidate(325, imageProcessProgress = $imageProcessState && ($imageProcessState.taskLengthComputable\n\t\t\t? $imageProcessState.taskProgress\n\t\t\t: Infinity));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageProcessState*/ 33554432) {\n\t\t\t$$invalidate(326, imageProcessShowProgressIndicator = $imageProcessState && !$imageProcessState.error);\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageProcessState*/ 33554432) {\n\t\t\t$$invalidate(324, isImageProcessingError = !!($imageProcessState && $imageProcessState.error));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[1] & /*isWaitingForImage*/ 2048 | $$self.$$.dirty[7] & /*status*/ 262144 | $$self.$$.dirty[9] & /*isMemoryError*/ 1073741824 | $$self.$$.dirty[10] & /*isImageLoadError, isLoadingImageData, isCreatingImagePreview, imageLoadStatusLabel, imageLoadShowProgressIndicator, imageLoadProgress, isProcessingImage, imageProcessStatusLabel, isImageProcessingError, imageProcessShowProgressIndicator, imageProcessProgress*/ 33538048) {\n\t\t\tif (status) {\n\t\t\t\tlet label;\n\t\t\t\tlet progress;\n\t\t\t\tlet showProgress;\n\t\t\t\tlet isError;\n\t\t\t\tlet errorCallback;\n\t\t\t\tif (isString(status)) label = status;\n\n\t\t\t\tif (isNumber(status)) progress = status; else if (Array.isArray(status)) {\n\t\t\t\t\t[label, progress, errorCallback] = status;\n\t\t\t\t\tif (progress === false) isError = true;\n\t\t\t\t\tif (isNumber(progress)) showProgress = true;\n\t\t\t\t}\n\n\t\t\t\t$$invalidate(35, statusState = (label || progress) && {\n\t\t\t\t\ttext: label,\n\t\t\t\t\taside: isError || showProgress,\n\t\t\t\t\tprogressIndicator: { visible: showProgress, progress },\n\t\t\t\t\tcloseButton: isError && {\n\t\t\t\t\t\tlabel: locale.statusLabelButtonClose,\n\t\t\t\t\t\ticon: locale.statusIconButtonClose,\n\t\t\t\t\t\tonclick: errorCallback || (() => $$invalidate(235, status = undefined))\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else if (locale && isWaitingForImage || isImageLoadError || isLoadingImageData || isCreatingImagePreview) {\n\t\t\t\t$$invalidate(35, statusState = {\n\t\t\t\t\ttext: imageLoadStatusLabel,\n\t\t\t\t\taside: isImageLoadError || imageLoadShowProgressIndicator,\n\t\t\t\t\tprogressIndicator: {\n\t\t\t\t\t\tvisible: imageLoadShowProgressIndicator,\n\t\t\t\t\t\tprogress: imageLoadProgress\n\t\t\t\t\t},\n\t\t\t\t\tcloseButton: isImageLoadError && {\n\t\t\t\t\t\tlabel: locale.statusLabelButtonClose,\n\t\t\t\t\t\ticon: locale.statusIconButtonClose,\n\t\t\t\t\t\tonclick: handleCloseImageLoadError\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else if (locale && isProcessingImage && imageProcessStatusLabel) {\n\t\t\t\t$$invalidate(35, statusState = {\n\t\t\t\t\ttext: imageProcessStatusLabel,\n\t\t\t\t\taside: isImageProcessingError || imageProcessShowProgressIndicator,\n\t\t\t\t\tprogressIndicator: {\n\t\t\t\t\t\tvisible: imageProcessShowProgressIndicator,\n\t\t\t\t\t\tprogress: imageProcessProgress\n\t\t\t\t\t},\n\t\t\t\t\tcloseButton: isImageProcessingError && {\n\t\t\t\t\t\tlabel: locale.statusLabelButtonClose,\n\t\t\t\t\t\ticon: locale.statusIconButtonClose,\n\t\t\t\t\t\tonclick: handleCloseImageProcessError\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else if (isMemoryError) {\n\t\t\t\t$$invalidate(35, statusState = {\n\t\t\t\t\ttext: isMemoryError,\n\t\t\t\t\taside: true,\n\t\t\t\t\terror: true,\n\t\t\t\t\tprogressIndicator: { visible: false },\n\t\t\t\t\ticon: locale.iconSupportError\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t$$invalidate(35, statusState = undefined);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[7] & /*status*/ 262144) {\n\t\t\t$$invalidate(336, isCustomStatus = status !== undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isAnimated*/ 4194304 | $$self.$$.dirty[10] & /*isModal*/ 1024 | $$self.$$.dirty[12] & /*$imageProcessState*/ 33554432) {\n\t\t\tif (isModal && $imageProcessState && $imageProcessState.complete) {\n\t\t\t\twasProcessingImage.set(true);\n\t\t\t\tsetTimeout(() => wasProcessingImage.set(false), $isAnimated ? 100 : 0);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 4 | $$self.$$.dirty[1] & /*utilSelected*/ 4096 | $$self.$$.dirty[12] & /*$imageVisualLoadComplete*/ 16777216) {\n\t\t\t$imageVisualLoadComplete && root && root.dispatchEvent(createPing('selectutil', utilSelected));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*isSupportsError, isWaitingForImage*/ 2304 | $$self.$$.dirty[9] & /*isMemoryError*/ 1073741824 | $$self.$$.dirty[10] & /*isImageLoadError, isLoadingImageData, isCreatingImagePreview, isProcessingImage, isCustomStatus*/ 93061120 | $$self.$$.dirty[12] & /*$wasProcessingImage*/ 8388608) {\n\t\t\t$$invalidate(335, isStatusActive = $wasProcessingImage || isSupportsError || isMemoryError || isWaitingForImage || isImageLoadError || isLoadingImageData || isCreatingImagePreview || isProcessingImage || isCustomStatus);\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*isStatusActive*/ 33554432) {\n\t\t\tset_store_value(statusOpacity, $statusOpacity = isStatusActive ? 1 : 0, $statusOpacity);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isAnimated*/ 4194304 | $$self.$$.dirty[10] & /*isStatusActive*/ 33554432) {\n\t\t\tstatusOpacity.set(isStatusActive ? 1 : 0, { duration: $isAnimated ? 500 : 1 });\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$statusOpacity*/ 8388608) {\n\t\t\t$$invalidate(41, isStatusVisible = $statusOpacity > 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*statusState*/ 16) {\n\t\t\t$$invalidate(323, hasAside = !!(statusState && statusState.aside));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*isStatusVisible, statusState, $isAnimated*/ 4195344 | $$self.$$.dirty[9] & /*asideWidthUpdateTimer*/ 8388608 | $$self.$$.dirty[10] & /*hasAside*/ 8192 | $$self.$$.dirty[12] & /*$statusWidth*/ 4194304) {\n\t\t\tif (isStatusVisible && statusState) {\n\t\t\t\tclearTimeout(asideWidthUpdateTimer);\n\t\t\t\tconst springProps = { hard: $isAnimated === false };\n\n\t\t\t\t// has aside\n\t\t\t\tif (hasAside) {\n\t\t\t\t\t// if error occured, or not animating, snap in possition\n\t\t\t\t\tconst hard = !!statusState.error || !$isAnimated;\n\n\t\t\t\t\tasideOpacity.set(1, springProps);\n\n\t\t\t\t\t// update offset of aside\n\t\t\t\t\tasideOffset.set($statusWidth, { hard });\n\n\t\t\t\t\t// update width of aside, this pushes message to left so it stays centered\n\t\t\t\t\t$$invalidate(302, asideWidthUpdateTimer = setTimeout(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tasideWidth.set(16, springProps);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t1\n\t\t\t\t\t));\n\t\t\t\t} else {\n\t\t\t\t\tasideOpacity.set(0, springProps);\n\n\t\t\t\t\t$$invalidate(302, asideWidthUpdateTimer = setTimeout(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tasideWidth.set(0, springProps);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t1\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*isStatusVisible*/ 1024) {\n\t\t\tif (!isStatusVisible) {\n\t\t\t\tstatusOffset.set(undefined, { hard: true });\n\t\t\t\tasideOffset.set(undefined, { hard: true });\n\t\t\t\tasideWidth.set(0, { hard: true });\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$asideWidth*/ 2097152) {\n\t\t\t$$invalidate(322, statusIndent = $asideWidth * 0.5);\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*statusIndent*/ 4096 | $$self.$$.dirty[12] & /*$statusOffset*/ 1048576) {\n\t\t\t$$invalidate(72, statusTransform = `translateX(${$statusOffset - statusIndent}px)`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*isSupportsError*/ 256 | $$self.$$.dirty[9] & /*isMemoryError*/ 1073741824 | $$self.$$.dirty[12] & /*$imagePreview, $imageSize*/ 384) {\n\t\t\t// ready bool\n\t\t\t$$invalidate(38, isReady = $imagePreview && $imageSize && !isSupportsError && !isMemoryError);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*isReady*/ 128 | $$self.$$.dirty[10] & /*needsInteractionLock, isModal*/ 3072) {\n\t\t\t$$invalidate(319, preventTouchHandler = needsInteractionLock && (isReady || isModal)\n\t\t\t? preventDefault\n\t\t\t: noop$1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*preventTouchHandler*/ 512) {\n\t\t\t$$invalidate(71, handleTouchMove = preventTouchHandler);\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*preventTouchHandler*/ 512) {\n\t\t\t$$invalidate(70, handlePointerMove = preventTouchHandler);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 8 | $$self.$$.dirty[1] & /*$redrawTrigger*/ 2097152 | $$self.$$.dirty[8] & /*willRenderToolbar, enableButtonClose, enableButtonRevert, enableNavigateHistory, enableButtonExport*/ 740 | $$self.$$.dirty[10] & /*canUndo, canRedo, activeUtilTools, isNarrow*/ 480 | $$self.$$.dirty[12] & /*$env*/ 262144) {\n\t\t\t// dynamic IO menu\n\t\t\t$$invalidate(69, toolbarItems = locale && $redrawTrigger && runSafe(() => willRenderToolbar(\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t'div',\n\t\t\t\t\t\t'alpha',\n\t\t\t\t\t\t{ class: 'PinturaNavGroup' },\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t'alpha-set',\n\t\t\t\t\t\t\t\t{ class: 'PinturaNavSet' },\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t// button close\n\t\t\t\t\t\t\t\t\tenableButtonClose && [\n\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t'close',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: locale.labelClose,\n\t\t\t\t\t\t\t\t\t\t\ticon: locale.iconButtonClose,\n\t\t\t\t\t\t\t\t\t\t\tonclick: () => dispatch('close'),\n\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t// button revert\n\t\t\t\t\t\t\t\t\tenableButtonRevert && [\n\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t'revert',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: locale.labelButtonRevert,\n\t\t\t\t\t\t\t\t\t\t\ticon: locale.iconButtonRevert,\n\t\t\t\t\t\t\t\t\t\t\tdisabled: !canUndo,\n\t\t\t\t\t\t\t\t\t\t\tonclick: revert,\n\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t]\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t'div',\n\t\t\t\t\t\t'beta',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclass: 'PinturaNavGroup PinturaNavGroupFloat'\n\t\t\t\t\t\t},\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tenableNavigateHistory && [\n\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t'history',\n\t\t\t\t\t\t\t\t{ class: 'PinturaNavSet' },\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t'undo',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: locale.labelButtonUndo,\n\t\t\t\t\t\t\t\t\t\t\ticon: locale.iconButtonUndo,\n\t\t\t\t\t\t\t\t\t\t\tdisabled: !canUndo,\n\t\t\t\t\t\t\t\t\t\t\tonclick: history.undo,\n\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t'redo',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: locale.labelButtonRedo,\n\t\t\t\t\t\t\t\t\t\t\ticon: locale.iconButtonRedo,\n\t\t\t\t\t\t\t\t\t\t\tdisabled: !canRedo,\n\t\t\t\t\t\t\t\t\t\t\tonclick: history.redo,\n\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tactiveUtilTools.length && [\n\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t'plugin-tools',\n\t\t\t\t\t\t\t\t{ class: 'PinturaNavSet' },\n\t\t\t\t\t\t\t\tactiveUtilTools.filter(Boolean).map(// in\n\t\t\t\t\t\t\t\t([component, key, props]) => // out\n\t\t\t\t\t\t\t\t[component, key, { ...props }])\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t]\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t'div',\n\t\t\t\t\t\t'gamma',\n\t\t\t\t\t\t{ class: 'PinturaNavGroup' },\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tenableButtonExport && [\n\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t'export',\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tlabel: locale.labelButtonExport,\n\t\t\t\t\t\t\t\t\ticon: isNarrow && locale.iconButtonExport,\n\t\t\t\t\t\t\t\t\tclass: 'PinturaButtonExport',\n\t\t\t\t\t\t\t\t\tonclick: handleExport,\n\t\t\t\t\t\t\t\t\thideLabel: isNarrow\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t]\n\t\t\t\t\t]\n\t\t\t\t],\n\t\t\t\t{ ...$env },\n\t\t\t\t() => redrawTrigger.set({})\n\t\t\t)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageRedaction*/ 16384) {\n\t\t\t// toggles on/off depending on active redaction shapes\n\t\t\t$$invalidate(311, hasImageRedaction = $imageRedaction && !!$imageRedaction.length);\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*hasImageRedaction*/ 2 | $$self.$$.dirty[12] & /*$imageSize, $imageRedaction*/ 16640) {\n\t\t\t// scales down resolution of scrambled image if redaction takes up more than half of view\n\t\t\t$$invalidate(310, imageRedactionScalar = hasImageRedaction && getImageRedactionScaleFactor($imageSize, $imageRedaction));\n\t\t}\n\n\t\tif ($$self.$$.dirty[10] & /*hasImageRedaction, imageRedactionScalar*/ 3 | $$self.$$.dirty[12] & /*$imagePreview, $imageScrambler, $imageBackgroundColor*/ 196736) {\n\t\t\t// only update/render preview if image redaction shapes are found\n\t\t\thasImageRedaction && updateScrambledPreview($imagePreview, $imageScrambler, imageRedactionScalar, $imageBackgroundColor);\n\t\t}\n\n\t\tif ($$self.$$.dirty[9] & /*scrambledPreviewImage*/ 16777216 | $$self.$$.dirty[12] & /*$imageRedaction, $imageSize, $imageRedactionRendering*/ 49408) {\n\t\t\tif ($imageRedaction && scrambledPreviewImage && $imageSize) {\n\t\t\t\t// used to calculate fraction x y coordinates of shape corners\n\t\t\t\tconst { width, height } = $imageSize;\n\n\t\t\t\t// set rendering for redactions\n\t\t\t\tconst backgroundImageRendering = isSafari()\n\t\t\t\t? 'pixelated'\n\t\t\t\t: $imageRedactionRendering === 'auto'\n\t\t\t\t\t? 'auto'\n\t\t\t\t\t: 'pixelated';\n\n\t\t\t\t// to blended shapes\n\t\t\t\t$$invalidate(304, computedRedactionShapes = $imageRedaction.map(shape => {\n\t\t\t\t\t// calculate shapes\n\t\t\t\t\tconst rect = rectCreate(shape.x, shape.y, shape.width, shape.height);\n\n\t\t\t\t\tconst corners = rectRotate(rectClone(rect), shape.rotation);\n\t\t\t\t\tconst backgroundCorners = corners.map(corner => vectorCreate(corner.x / width, corner.y / height));\n\n\t\t\t\t\t// new shape\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tid: 'redaction',\n\t\t\t\t\t\tflipX: false,\n\t\t\t\t\t\tflipY: false,\n\t\t\t\t\t\tcornerRadius: 0,\n\t\t\t\t\t\tstrokeWidth: 0,\n\t\t\t\t\t\tstrokeColor: undefined,\n\t\t\t\t\t\tbackgroundColor: [0, 0, 0, 0],\n\t\t\t\t\t\tbackgroundImage: scrambledPreviewImage,\n\t\t\t\t\t\tbackgroundImageRendering,\n\t\t\t\t\t\tbackgroundCorners\n\t\t\t\t\t};\n\t\t\t\t}));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[9] & /*computedRedactionShapes*/ 33554432 | $$self.$$.dirty[12] & /*$imageManipulation*/ 8192) {\n\t\t\t// merge redaction and manipulation\n\t\t\t$$invalidate(37, manipulationShapes = [...computedRedactionShapes, ...$imageManipulation || []]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*rootPortal*/ 32) {\n\t\t\trootPortal && rootPortalStore.set(rootPortal);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*root*/ 4 | $$self.$$.dirty[1] & /*isReady*/ 128) {\n\t\t\t// now ready for interaction\n\t\t\tisReady && root && root.dispatchEvent(createPing('ready'));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageAnnotation*/ 262144) {\n\t\t\tmarkAnnotationShapesAsDirty();\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$imageRotation, $imageFlipX, $imageFlipY, $imageSize*/ 3840) {\n\t\t\tmarkAnnotationRequiresPreprocessing();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageDecoration*/ 131072) {\n\t\t\tmarkDecorationShapesAsDirty();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageFrame*/ 65536) {\n\t\t\tmarkFrameShapesAsDirty();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*manipulationShapes*/ 64) {\n\t\t\tmarkManipulationShapesAsDirty();\n\t\t}\n\n\t\tif ($$self.$$.dirty[12] & /*$rootRect*/ 64) {\n\t\t\t// Show warning if no locale loaded\n\t\t\t$$invalidate(307, hasHeight = $rootRect ? $rootRect.height > 0 : false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[9] & /*hasLocale, hasHeight, localeTestTimeout*/ 469762048) {\n\t\t\tif (!hasLocale && hasHeight) {\n\t\t\t\tclearTimeout(localeTestTimeout);\n\n\t\t\t\t$$invalidate(305, localeTestTimeout = setTimeout(\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (!hasLocale) warnRequiredProp('locale');\n\t\t\t\t\t},\n\t\t\t\t\t32\n\t\t\t\t));\n\t\t\t}\n\t\t}\n\t};\n\n\t$$invalidate(371, supportsAnimations = !isSoftwareRendering());\n\n\timageTransformsSnapPixels = getDevicePixelRatio() === 1\n\t? transforms => {\n\t\t\tif (!transforms) return;\n\t\t\tvectorApply(transforms.origin, Math.round);\n\t\t\tvectorApply(transforms.translation, Math.round);\n\t\t}\n\t: passthrough;\n\n\t$$invalidate(338, missingFeatures = [!supportsWebGL() && 'WebGL'].filter(Boolean));\n\n\t// These are again needed since iOS 15 (was needed for 12 and lower, but  wasn't needed for 13, 14)\n\t// Now also needed for Firefox on Android\n\t$$invalidate(321, needsInteractionLock = isIOS() || isAndroid() && isFirefox());\n\n\t// used to route ping events\n\t$$invalidate(68, routePing = createPingRouter(eventProxy.pub));\n\n\treturn [\n\t\tzoomLevel,\n\t\tpluginInterface,\n\t\troot,\n\t\tlocale,\n\t\tid,\n\t\tpreviewMaskOpacity,\n\t\tpreviewImageTextPixelRatio,\n\t\tmarkupMaskOpacity,\n\t\telasticityMultiplier,\n\t\twillRenderCanvas,\n\t\tenableToolbar,\n\t\tenableTransparencyGrid,\n\t\ttextDirection,\n\t\tmarkupEditorZoomLevels,\n\t\tmarkupEditorZoomAdjustStep,\n\t\tmarkupEditorZoomAdjustFactor,\n\t\tmarkupEditorZoomAdjustWheelFactor,\n\t\tenablePan,\n\t\tenableZoom,\n\t\tenableZoomInput,\n\t\tenableCanvasAlpha,\n\t\tenablePanLimit,\n\t\tpanLimitGutterScalar,\n\t\tzoomPresetOptions,\n\t\tzoomAdjustStep,\n\t\tzoomAdjustFactor,\n\t\tzoomAdjustWheelFactor,\n\t\tpluginOptions,\n\t\timageSourceToImageData,\n\t\timagePreview,\n\t\thistory,\n\t\twindowWidth,\n\t\twindowHeight,\n\t\tzoomControls,\n\t\tzoomMultiTouching,\n\t\tstatusState,\n\t\trootPortal,\n\t\tmanipulationShapes,\n\t\tisReady,\n\t\tisSupportsError,\n\t\tcanRender,\n\t\tisStatusVisible,\n\t\tisWaitingForImage,\n\t\tutilSelected,\n\t\ttabsAfterWillRender,\n\t\tshowUtils,\n\t\tshouldRenderTabs,\n\t\t$imageFrame,\n\t\t$imageDecoration,\n\t\t$imageAnnotation,\n\t\t$stageRect,\n\t\t$clientRect,\n\t\t$redrawTrigger,\n\t\t$isAnimated,\n\t\t$statusOpacity,\n\t\t$activeImages,\n\t\t$rootBackgroundColor,\n\t\t$pixelRatio,\n\t\t$imageSelectionRectPresentation,\n\t\t$imageSelection,\n\t\tuserTextInput,\n\t\tuserTextInputField,\n\t\tutilsVisible,\n\t\timageAnnotationShapesDirty,\n\t\timageAnnotationRequiresPreprocessing,\n\t\timageDecorationShapesDirty,\n\t\timageFrameShapesDirty,\n\t\timageManipulationShapesDirty,\n\t\troutePing,\n\t\ttoolbarItems,\n\t\thandlePointerMove,\n\t\thandleTouchMove,\n\t\tstatusTransform,\n\t\timageCanvasState,\n\t\ttabsAreNodes,\n\t\tenvStr,\n\t\tisLandscape,\n\t\tclassName,\n\t\tpanels,\n\t\ttabsConfig,\n\t\t$tabRect,\n\t\t$willRequest,\n\t\t$asideOffset,\n\t\t$asideOpacity,\n\t\t$toolRect,\n\t\t$imageCropLimitToImage,\n\t\t$interfaceImages,\n\t\t$gridSize,\n\t\t$gridColorEven,\n\t\t$gridColorOdd,\n\t\t$gridOpacity,\n\t\t$rootColorPrimary,\n\t\t$csp,\n\t\t$willRequestResource,\n\t\t$imageOverlay,\n\t\t$allowPan,\n\t\t$enablePanInputStatus,\n\t\t$allowZoom,\n\t\t$enableZoomInputStore,\n\t\t$enableZoomControlsProp,\n\t\t$imageSelectionRectCentered,\n\t\t$imageSelectionRectScalar,\n\t\t$disabledTransition,\n\t\tallowPlayPause,\n\t\tvideoFramePeekOffset,\n\t\tvideoFrameOffset,\n\t\tisMuted,\n\t\tredrawTrigger,\n\t\telasticityMultiplierStore,\n\t\tdisabledTransition,\n\t\timageFile,\n\t\timageSize,\n\t\tmediaDuration,\n\t\tmediaCurrentTime,\n\t\tmediaTrim,\n\t\tmediaVolume,\n\t\tmediaMaxDuration,\n\t\timageLoadState,\n\t\timageProcessState,\n\t\timageCropAspectRatio,\n\t\timageCropLimitToImage,\n\t\timageCropRect,\n\t\timageRotation,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\timageBackgroundColor,\n\t\timageDecoration,\n\t\timageAnnotation,\n\t\timageManipulation,\n\t\timageRedaction,\n\t\timageFrame,\n\t\timageSelection,\n\t\timageState,\n\t\timages,\n\t\tshapePreprocessor,\n\t\timageScrambler,\n\t\timageRedactionRendering,\n\t\twillRequest,\n\t\twillRequestResource,\n\t\tcsp,\n\t\tallowPan,\n\t\tallowZoom,\n\t\tallowZoomControls,\n\t\tenablePanInputStore,\n\t\tenableZoomInputStore,\n\t\tenableZoomControlsProp,\n\t\tenablePanInputProp,\n\t\tenablePanInputStatus,\n\t\trootBackgroundColor,\n\t\trootForegroundColor,\n\t\trootLineColor,\n\t\trootColorPrimary,\n\t\tclientRect,\n\t\trootRect,\n\t\ttabRect,\n\t\trootInsetTop,\n\t\ttoolRect,\n\t\tutilRect,\n\t\tpointerAccuracy,\n\t\tpointerHoverable,\n\t\tisInteracting,\n\t\tisInteractingFraction,\n\t\tshouldAnimate,\n\t\tisAnimated,\n\t\tpreviewShouldUpscale,\n\t\timageIsStatic,\n\t\timageCropRectSnapshot,\n\t\timageCropRectIntent,\n\t\timageSelectionRect,\n\t\timageSelectionRectSnapshot,\n\t\timageSelectionRectIntent,\n\t\timageSelectionRectOffset,\n\t\tstagePadding,\n\t\tstagePadded,\n\t\tstageRect,\n\t\timageStaticBounds,\n\t\tstageScalar,\n\t\timageSelectionZoom,\n\t\timageSelectionRectScalar,\n\t\timageSelectionScalar,\n\t\timageSelectionPan,\n\t\timageSelectionRectPresentation,\n\t\timageSelectionRectStaticScalar,\n\t\timageSelectionRectCentered,\n\t\tpresentationScalar,\n\t\timageOverlayMarkup,\n\t\timageOverlay,\n\t\toverlayOpacity,\n\t\toverlayLeftRect,\n\t\toverlayTopRect,\n\t\toverlayRightRect,\n\t\toverlayBottomRect,\n\t\timageVisualLoadComplete,\n\t\timagePreviewSource,\n\t\timagePreviewModifiers,\n\t\tinterfaceImages,\n\t\timageTransforms,\n\t\tenv,\n\t\tpixelRatio,\n\t\timageProcessingPreparing,\n\t\tactiveImages,\n\t\tutilTools,\n\t\tutilStores,\n\t\thandleShowUtil,\n\t\thandleHideUtil,\n\t\thandleFadeUtil,\n\t\tgetUtilPanelProps,\n\t\tgetUtilPanelView,\n\t\tgridSize,\n\t\tgridColorEven,\n\t\tgridColorOdd,\n\t\tgridOpacity,\n\t\thandleTransitionEnd,\n\t\timageProps,\n\t\tstatusOpacity,\n\t\thandleCanvasError,\n\t\twasProcessingImage,\n\t\tasideOffset,\n\t\tasideOpacity,\n\t\tasideWidth,\n\t\tstatusWidth,\n\t\tstatusOffset,\n\t\toffsetAside,\n\t\thandleTouchStart,\n\t\tpressedKeysStore,\n\t\thandleKeydown,\n\t\thandleKeyup,\n\t\thandleWindowBlur,\n\t\thandleContextMenu,\n\t\thandleDropFiles,\n\t\tbrowseFileSystem,\n\t\thandlePaste,\n\t\tgetStageState,\n\t\tcreateCanvasState,\n\t\thandleMeasureUtil,\n\t\tstatus,\n\t\timagePreviewCurrent,\n\t\tklass,\n\t\tlayoutMode,\n\t\tstores,\n\t\tutil,\n\t\tutils,\n\t\tanimations,\n\t\tdisabled,\n\t\tpreviewUpscale,\n\t\tpreviewPad,\n\t\tpreviewImageDataMaxSize,\n\t\tzoomMaskOpacity,\n\t\twillRevert,\n\t\twillProcessImage,\n\t\twillRenderToolbar,\n\t\twillRenderUtilTabs,\n\t\twillSetHistoryInitialState,\n\t\tenableButtonExport,\n\t\tenableButtonRevert,\n\t\tenableNavigateHistory,\n\t\tenableUtils,\n\t\tenableButtonClose,\n\t\tenableDropImage,\n\t\tenablePasteImage,\n\t\tenableBrowseImage,\n\t\taccept,\n\t\tlayoutDirectionPreference,\n\t\tlayoutHorizontalUtilsPreference,\n\t\tlayoutVerticalUtilsPreference,\n\t\tlayoutVerticalToolbarPreference,\n\t\tlayoutVerticalControlGroupsPreference,\n\t\tlayoutVerticalControlTabsPreference,\n\t\tsupportedMediaTypes,\n\t\tformatStatusImageLoading,\n\t\tformatStatusImageProcessing,\n\t\tformatStatusSupportError,\n\t\tmarkupEditorZoomLevel,\n\t\tmarkupEditorInteractionMode,\n\t\tmuteAudio,\n\t\twillSetMediaInitialTimeOffset,\n\t\tenableZoomControls,\n\t\tenablePanInput,\n\t\tpan,\n\t\tfixScrollDirection,\n\t\thideTextInput,\n\t\tshowTextInput,\n\t\timagePreviewSrc,\n\t\timageOrienter,\n\t\tpluginComponents,\n\t\tsub,\n\t\tplay,\n\t\tpause,\n\t\tisPaused,\n\t\ttogglePlayPause,\n\t\tmute,\n\t\tunmute,\n\t\ttoggleMute,\n\t\tgetDuration,\n\t\tgetCurrentTime,\n\t\tsetCurrentTime,\n\t\tregisteredPluginsComponents,\n\t\tcanRenderDelayed,\n\t\timagePreviewLoaderCancelToken,\n\t\tlastImagePreview,\n\t\twebGLContextFailed,\n\t\tloadTimer,\n\t\tasideWidthUpdateTimer,\n\t\tscrambledPreviewImage,\n\t\tcomputedRedactionShapes,\n\t\tlocaleTestTimeout,\n\t\thasLocale,\n\t\thasHeight,\n\t\tutilsVisibleFraction,\n\t\tisMemoryError,\n\t\timageRedactionScalar,\n\t\thasImageRedaction,\n\t\tisVideoSupported,\n\t\tutilsDefined,\n\t\thasClientRect,\n\t\tisNarrow,\n\t\tactiveUtilTools,\n\t\tcanRedo,\n\t\tcanUndo,\n\t\tpreventTouchHandler,\n\t\tisModal,\n\t\tneedsInteractionLock,\n\t\tstatusIndent,\n\t\thasAside,\n\t\tisImageProcessingError,\n\t\timageProcessProgress,\n\t\timageProcessShowProgressIndicator,\n\t\timageProcessStatusLabel,\n\t\tisProcessingImage,\n\t\tisImageLoadError,\n\t\timageLoadProgress,\n\t\timageLoadShowProgressIndicator,\n\t\timageLoadStatusLabel,\n\t\tisCreatingImagePreview,\n\t\tisLoadingImageData,\n\t\tisStatusActive,\n\t\tisCustomStatus,\n\t\tisStartLoadingImageSource,\n\t\tmissingFeatures,\n\t\thasProps,\n\t\ttabs,\n\t\thasLimitedSpace,\n\t\thasSwipeNavigation,\n\t\tisCompact,\n\t\tisTransparent,\n\t\tisCenteredVertically,\n\t\tisCenteredHorizontally,\n\t\tisCentered,\n\t\ttoolbarVerticalPreference,\n\t\tcontrolTabsVerticalpreference,\n\t\tcontrolGroupsVerticalPreference,\n\t\tnavigationVerticalPreference,\n\t\tnavigationHorizontalPreference,\n\t\tverticalSpace,\n\t\thorizontalSpace,\n\t\torientation,\n\t\trootElementComputedStyle,\n\t\trootRectDefined,\n\t\tutilsMerged,\n\t\tutilsFiltered,\n\t\tutilsAvailable,\n\t\tgradientOverlays,\n\t\toverlayLeft,\n\t\toverlayBottom,\n\t\toverlayRight,\n\t\toverlayTop,\n\t\toverlayOverlap,\n\t\tOVERLAY_OPACITY_MAX,\n\t\toverlayMin,\n\t\tisOverlayModeEnabled,\n\t\tacceptsAnimations,\n\t\tsupportsAnimations,\n\t\tcanAnimate,\n\t\tvideoTrim,\n\t\tvideoTrimCurrentIndex,\n\t\tvideoFrameOffsetFixed,\n\t\tvideoTrimFixed,\n\t\tisTrimPluginLoaded,\n\t\t$rootRect,\n\t\t$imagePreview,\n\t\t$imageSize,\n\t\t$imageFlipY,\n\t\t$imageFlipX,\n\t\t$imageRotation,\n\t\t$isInteracting,\n\t\t$imageManipulation,\n\t\t$imageRedaction,\n\t\t$imageRedactionRendering,\n\t\t$imageBackgroundColor,\n\t\t$imageScrambler,\n\t\t$env,\n\t\t$imageProcessingPreparing,\n\t\t$statusOffset,\n\t\t$asideWidth,\n\t\t$statusWidth,\n\t\t$wasProcessingImage,\n\t\t$imageVisualLoadComplete,\n\t\t$imageProcessState,\n\t\t$imageLoadState,\n\t\t$imagePreviewSource,\n\t\t$imageProps,\n\t\t$imagePreviewModifiers,\n\t\t$imageTransforms,\n\t\t$pointerHoverable,\n\t\t$pointerAccuracy,\n\t\t$utilTools,\n\t\t$imageFile,\n\t\t$previewShouldUpscale,\n\t\t$history,\n\t\t$imageOverlayMarkup,\n\t\t$overlayBottomRect,\n\t\t$overlayOpacity,\n\t\t$overlayRightRect,\n\t\t$overlayTopRect,\n\t\t$overlayLeftRect,\n\t\t$stagePadding,\n\t\t$stagePadded,\n\t\t$imageCropRect,\n\t\t$stageScalar,\n\t\t$imageStaticBounds,\n\t\t$imageSelectionPan,\n\t\t$imageSelectionZoom,\n\t\t$prefersReducedMotion,\n\t\t$rootInsetTop,\n\t\t$allowZoomControls,\n\t\t$shapePreprocessor,\n\t\t$images,\n\t\t$mediaTrim,\n\t\t$mediaVolume,\n\t\t$videoFrameOffset,\n\t\t$mediaDuration,\n\t\t$isMuted,\n\t\t$videoFramePeekOffset,\n\t\t$mediaMaxDuration,\n\t\tonwindowresize,\n\t\tmeasure_handler,\n\t\tselect_handler,\n\t\tutilpanel_component_binding,\n\t\tshow_handler,\n\t\thide_handler,\n\t\tfade_handler,\n\t\tmeasure_handler_1,\n\t\tutilpanel_component_binding_1,\n\t\tshow_handler_1,\n\t\thide_handler_1,\n\t\tfade_handler_1,\n\t\tfunc,\n\t\tfunc_1,\n\t\tdiv_binding,\n\t\tcanvaspanandzoom_zoomLevel_binding,\n\t\tcanvaspanandzoom_zoomControls_binding,\n\t\tcanvaspanandzoom_zoomMultiTouching_binding,\n\t\tinput_binding,\n\t\tdiv_binding_1,\n\t\tmeasure_handler_2\n\t];\n}\n\nclass Ui extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$s,\n\t\t\tcreate_fragment$s,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tclass: 237,\n\t\t\t\tlayout: 238,\n\t\t\t\tstores: 239,\n\t\t\t\tlocale: 3,\n\t\t\t\tid: 4,\n\t\t\t\tutil: 240,\n\t\t\t\tutils: 241,\n\t\t\t\tanimations: 242,\n\t\t\t\tdisabled: 243,\n\t\t\t\tpreviewUpscale: 244,\n\t\t\t\tpreviewPad: 245,\n\t\t\t\tpreviewMaskOpacity: 5,\n\t\t\t\tpreviewImageDataMaxSize: 246,\n\t\t\t\tpreviewImageTextPixelRatio: 6,\n\t\t\t\tmarkupMaskOpacity: 7,\n\t\t\t\tzoomMaskOpacity: 247,\n\t\t\t\telasticityMultiplier: 8,\n\t\t\t\twillRevert: 248,\n\t\t\t\twillProcessImage: 249,\n\t\t\t\twillRenderCanvas: 9,\n\t\t\t\twillRenderToolbar: 250,\n\t\t\t\twillRenderUtilTabs: 251,\n\t\t\t\twillSetHistoryInitialState: 252,\n\t\t\t\tenableButtonExport: 253,\n\t\t\t\tenableButtonRevert: 254,\n\t\t\t\tenableNavigateHistory: 255,\n\t\t\t\tenableToolbar: 10,\n\t\t\t\tenableUtils: 256,\n\t\t\t\tenableButtonClose: 257,\n\t\t\t\tenableDropImage: 258,\n\t\t\t\tenablePasteImage: 259,\n\t\t\t\tenableBrowseImage: 260,\n\t\t\t\taccept: 261,\n\t\t\t\tenableTransparencyGrid: 11,\n\t\t\t\tlayoutDirectionPreference: 262,\n\t\t\t\tlayoutHorizontalUtilsPreference: 263,\n\t\t\t\tlayoutVerticalUtilsPreference: 264,\n\t\t\t\tlayoutVerticalToolbarPreference: 265,\n\t\t\t\tlayoutVerticalControlGroupsPreference: 266,\n\t\t\t\tlayoutVerticalControlTabsPreference: 267,\n\t\t\t\tsupportedMediaTypes: 268,\n\t\t\t\tstatus: 235,\n\t\t\t\tformatStatusImageLoading: 269,\n\t\t\t\tformatStatusImageProcessing: 270,\n\t\t\t\tformatStatusSupportError: 271,\n\t\t\t\ttextDirection: 12,\n\t\t\t\tmarkupEditorZoomLevel: 272,\n\t\t\t\tmarkupEditorZoomLevels: 13,\n\t\t\t\tmarkupEditorZoomAdjustStep: 14,\n\t\t\t\tmarkupEditorZoomAdjustFactor: 15,\n\t\t\t\tmarkupEditorZoomAdjustWheelFactor: 16,\n\t\t\t\tmarkupEditorInteractionMode: 273,\n\t\t\t\tmuteAudio: 274,\n\t\t\t\twillSetMediaInitialTimeOffset: 275,\n\t\t\t\tenablePan: 17,\n\t\t\t\tenableZoom: 18,\n\t\t\t\tenableZoomControls: 276,\n\t\t\t\tenableZoomInput: 19,\n\t\t\t\tenablePanInput: 277,\n\t\t\t\tenableCanvasAlpha: 20,\n\t\t\t\tenablePanLimit: 21,\n\t\t\t\tpanLimitGutterScalar: 22,\n\t\t\t\tpan: 278,\n\t\t\t\tzoomPresetOptions: 23,\n\t\t\t\tzoomAdjustStep: 24,\n\t\t\t\tzoomAdjustFactor: 25,\n\t\t\t\tzoomAdjustWheelFactor: 26,\n\t\t\t\tzoomLevel: 0,\n\t\t\t\tfixScrollDirection: 279,\n\t\t\t\thideTextInput: 280,\n\t\t\t\tshowTextInput: 281,\n\t\t\t\timagePreviewSrc: 282,\n\t\t\t\timageOrienter: 283,\n\t\t\t\tpluginComponents: 284,\n\t\t\t\tpluginOptions: 27,\n\t\t\t\tsub: 285,\n\t\t\t\tpluginInterface: 1,\n\t\t\t\troot: 2,\n\t\t\t\tplay: 286,\n\t\t\t\tpause: 287,\n\t\t\t\tisPaused: 288,\n\t\t\t\ttogglePlayPause: 289,\n\t\t\t\tmute: 290,\n\t\t\t\tunmute: 291,\n\t\t\t\ttoggleMute: 292,\n\t\t\t\tgetDuration: 293,\n\t\t\t\tgetCurrentTime: 294,\n\t\t\t\tsetCurrentTime: 295,\n\t\t\t\timageSourceToImageData: 28,\n\t\t\t\timagePreview: 29,\n\t\t\t\timagePreviewCurrent: 236,\n\t\t\t\thistory: 30\n\t\t\t},\n\t\t\tnull,\n\t\t\t[\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1,\n\t\t\t\t-1\n\t\t\t]\n\t\t);\n\t}\n\n\tget class() {\n\t\treturn this.$$.ctx[237];\n\t}\n\n\tset class(klass) {\n\t\tthis.$$set({ class: klass });\n\t\tflush();\n\t}\n\n\tget layout() {\n\t\treturn this.$$.ctx[238];\n\t}\n\n\tset layout(layoutMode) {\n\t\tthis.$$set({ layout: layoutMode });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[239];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget id() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset id(id) {\n\t\tthis.$$set({ id });\n\t\tflush();\n\t}\n\n\tget util() {\n\t\treturn this.$$.ctx[240];\n\t}\n\n\tset util(util) {\n\t\tthis.$$set({ util });\n\t\tflush();\n\t}\n\n\tget utils() {\n\t\treturn this.$$.ctx[241];\n\t}\n\n\tset utils(utils) {\n\t\tthis.$$set({ utils });\n\t\tflush();\n\t}\n\n\tget animations() {\n\t\treturn this.$$.ctx[242];\n\t}\n\n\tset animations(animations) {\n\t\tthis.$$set({ animations });\n\t\tflush();\n\t}\n\n\tget disabled() {\n\t\treturn this.$$.ctx[243];\n\t}\n\n\tset disabled(disabled) {\n\t\tthis.$$set({ disabled });\n\t\tflush();\n\t}\n\n\tget previewUpscale() {\n\t\treturn this.$$.ctx[244];\n\t}\n\n\tset previewUpscale(previewUpscale) {\n\t\tthis.$$set({ previewUpscale });\n\t\tflush();\n\t}\n\n\tget previewPad() {\n\t\treturn this.$$.ctx[245];\n\t}\n\n\tset previewPad(previewPad) {\n\t\tthis.$$set({ previewPad });\n\t\tflush();\n\t}\n\n\tget previewMaskOpacity() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset previewMaskOpacity(previewMaskOpacity) {\n\t\tthis.$$set({ previewMaskOpacity });\n\t\tflush();\n\t}\n\n\tget previewImageDataMaxSize() {\n\t\treturn this.$$.ctx[246];\n\t}\n\n\tset previewImageDataMaxSize(previewImageDataMaxSize) {\n\t\tthis.$$set({ previewImageDataMaxSize });\n\t\tflush();\n\t}\n\n\tget previewImageTextPixelRatio() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset previewImageTextPixelRatio(previewImageTextPixelRatio) {\n\t\tthis.$$set({ previewImageTextPixelRatio });\n\t\tflush();\n\t}\n\n\tget markupMaskOpacity() {\n\t\treturn this.$$.ctx[7];\n\t}\n\n\tset markupMaskOpacity(markupMaskOpacity) {\n\t\tthis.$$set({ markupMaskOpacity });\n\t\tflush();\n\t}\n\n\tget zoomMaskOpacity() {\n\t\treturn this.$$.ctx[247];\n\t}\n\n\tset zoomMaskOpacity(zoomMaskOpacity) {\n\t\tthis.$$set({ zoomMaskOpacity });\n\t\tflush();\n\t}\n\n\tget elasticityMultiplier() {\n\t\treturn this.$$.ctx[8];\n\t}\n\n\tset elasticityMultiplier(elasticityMultiplier) {\n\t\tthis.$$set({ elasticityMultiplier });\n\t\tflush();\n\t}\n\n\tget willRevert() {\n\t\treturn this.$$.ctx[248];\n\t}\n\n\tset willRevert(willRevert) {\n\t\tthis.$$set({ willRevert });\n\t\tflush();\n\t}\n\n\tget willProcessImage() {\n\t\treturn this.$$.ctx[249];\n\t}\n\n\tset willProcessImage(willProcessImage) {\n\t\tthis.$$set({ willProcessImage });\n\t\tflush();\n\t}\n\n\tget willRenderCanvas() {\n\t\treturn this.$$.ctx[9];\n\t}\n\n\tset willRenderCanvas(willRenderCanvas) {\n\t\tthis.$$set({ willRenderCanvas });\n\t\tflush();\n\t}\n\n\tget willRenderToolbar() {\n\t\treturn this.$$.ctx[250];\n\t}\n\n\tset willRenderToolbar(willRenderToolbar) {\n\t\tthis.$$set({ willRenderToolbar });\n\t\tflush();\n\t}\n\n\tget willRenderUtilTabs() {\n\t\treturn this.$$.ctx[251];\n\t}\n\n\tset willRenderUtilTabs(willRenderUtilTabs) {\n\t\tthis.$$set({ willRenderUtilTabs });\n\t\tflush();\n\t}\n\n\tget willSetHistoryInitialState() {\n\t\treturn this.$$.ctx[252];\n\t}\n\n\tset willSetHistoryInitialState(willSetHistoryInitialState) {\n\t\tthis.$$set({ willSetHistoryInitialState });\n\t\tflush();\n\t}\n\n\tget enableButtonExport() {\n\t\treturn this.$$.ctx[253];\n\t}\n\n\tset enableButtonExport(enableButtonExport) {\n\t\tthis.$$set({ enableButtonExport });\n\t\tflush();\n\t}\n\n\tget enableButtonRevert() {\n\t\treturn this.$$.ctx[254];\n\t}\n\n\tset enableButtonRevert(enableButtonRevert) {\n\t\tthis.$$set({ enableButtonRevert });\n\t\tflush();\n\t}\n\n\tget enableNavigateHistory() {\n\t\treturn this.$$.ctx[255];\n\t}\n\n\tset enableNavigateHistory(enableNavigateHistory) {\n\t\tthis.$$set({ enableNavigateHistory });\n\t\tflush();\n\t}\n\n\tget enableToolbar() {\n\t\treturn this.$$.ctx[10];\n\t}\n\n\tset enableToolbar(enableToolbar) {\n\t\tthis.$$set({ enableToolbar });\n\t\tflush();\n\t}\n\n\tget enableUtils() {\n\t\treturn this.$$.ctx[256];\n\t}\n\n\tset enableUtils(enableUtils) {\n\t\tthis.$$set({ enableUtils });\n\t\tflush();\n\t}\n\n\tget enableButtonClose() {\n\t\treturn this.$$.ctx[257];\n\t}\n\n\tset enableButtonClose(enableButtonClose) {\n\t\tthis.$$set({ enableButtonClose });\n\t\tflush();\n\t}\n\n\tget enableDropImage() {\n\t\treturn this.$$.ctx[258];\n\t}\n\n\tset enableDropImage(enableDropImage) {\n\t\tthis.$$set({ enableDropImage });\n\t\tflush();\n\t}\n\n\tget enablePasteImage() {\n\t\treturn this.$$.ctx[259];\n\t}\n\n\tset enablePasteImage(enablePasteImage) {\n\t\tthis.$$set({ enablePasteImage });\n\t\tflush();\n\t}\n\n\tget enableBrowseImage() {\n\t\treturn this.$$.ctx[260];\n\t}\n\n\tset enableBrowseImage(enableBrowseImage) {\n\t\tthis.$$set({ enableBrowseImage });\n\t\tflush();\n\t}\n\n\tget accept() {\n\t\treturn this.$$.ctx[261];\n\t}\n\n\tset accept(accept) {\n\t\tthis.$$set({ accept });\n\t\tflush();\n\t}\n\n\tget enableTransparencyGrid() {\n\t\treturn this.$$.ctx[11];\n\t}\n\n\tset enableTransparencyGrid(enableTransparencyGrid) {\n\t\tthis.$$set({ enableTransparencyGrid });\n\t\tflush();\n\t}\n\n\tget layoutDirectionPreference() {\n\t\treturn this.$$.ctx[262];\n\t}\n\n\tset layoutDirectionPreference(layoutDirectionPreference) {\n\t\tthis.$$set({ layoutDirectionPreference });\n\t\tflush();\n\t}\n\n\tget layoutHorizontalUtilsPreference() {\n\t\treturn this.$$.ctx[263];\n\t}\n\n\tset layoutHorizontalUtilsPreference(layoutHorizontalUtilsPreference) {\n\t\tthis.$$set({ layoutHorizontalUtilsPreference });\n\t\tflush();\n\t}\n\n\tget layoutVerticalUtilsPreference() {\n\t\treturn this.$$.ctx[264];\n\t}\n\n\tset layoutVerticalUtilsPreference(layoutVerticalUtilsPreference) {\n\t\tthis.$$set({ layoutVerticalUtilsPreference });\n\t\tflush();\n\t}\n\n\tget layoutVerticalToolbarPreference() {\n\t\treturn this.$$.ctx[265];\n\t}\n\n\tset layoutVerticalToolbarPreference(layoutVerticalToolbarPreference) {\n\t\tthis.$$set({ layoutVerticalToolbarPreference });\n\t\tflush();\n\t}\n\n\tget layoutVerticalControlGroupsPreference() {\n\t\treturn this.$$.ctx[266];\n\t}\n\n\tset layoutVerticalControlGroupsPreference(layoutVerticalControlGroupsPreference) {\n\t\tthis.$$set({ layoutVerticalControlGroupsPreference });\n\t\tflush();\n\t}\n\n\tget layoutVerticalControlTabsPreference() {\n\t\treturn this.$$.ctx[267];\n\t}\n\n\tset layoutVerticalControlTabsPreference(layoutVerticalControlTabsPreference) {\n\t\tthis.$$set({ layoutVerticalControlTabsPreference });\n\t\tflush();\n\t}\n\n\tget supportedMediaTypes() {\n\t\treturn this.$$.ctx[268];\n\t}\n\n\tset supportedMediaTypes(supportedMediaTypes) {\n\t\tthis.$$set({ supportedMediaTypes });\n\t\tflush();\n\t}\n\n\tget status() {\n\t\treturn this.$$.ctx[235];\n\t}\n\n\tset status(status) {\n\t\tthis.$$set({ status });\n\t\tflush();\n\t}\n\n\tget formatStatusImageLoading() {\n\t\treturn this.$$.ctx[269];\n\t}\n\n\tset formatStatusImageLoading(formatStatusImageLoading) {\n\t\tthis.$$set({ formatStatusImageLoading });\n\t\tflush();\n\t}\n\n\tget formatStatusImageProcessing() {\n\t\treturn this.$$.ctx[270];\n\t}\n\n\tset formatStatusImageProcessing(formatStatusImageProcessing) {\n\t\tthis.$$set({ formatStatusImageProcessing });\n\t\tflush();\n\t}\n\n\tget formatStatusSupportError() {\n\t\treturn this.$$.ctx[271];\n\t}\n\n\tset formatStatusSupportError(formatStatusSupportError) {\n\t\tthis.$$set({ formatStatusSupportError });\n\t\tflush();\n\t}\n\n\tget textDirection() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tset textDirection(textDirection) {\n\t\tthis.$$set({ textDirection });\n\t\tflush();\n\t}\n\n\tget markupEditorZoomLevel() {\n\t\treturn this.$$.ctx[272];\n\t}\n\n\tset markupEditorZoomLevel(markupEditorZoomLevel) {\n\t\tthis.$$set({ markupEditorZoomLevel });\n\t\tflush();\n\t}\n\n\tget markupEditorZoomLevels() {\n\t\treturn this.$$.ctx[13];\n\t}\n\n\tset markupEditorZoomLevels(markupEditorZoomLevels) {\n\t\tthis.$$set({ markupEditorZoomLevels });\n\t\tflush();\n\t}\n\n\tget markupEditorZoomAdjustStep() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tset markupEditorZoomAdjustStep(markupEditorZoomAdjustStep) {\n\t\tthis.$$set({ markupEditorZoomAdjustStep });\n\t\tflush();\n\t}\n\n\tget markupEditorZoomAdjustFactor() {\n\t\treturn this.$$.ctx[15];\n\t}\n\n\tset markupEditorZoomAdjustFactor(markupEditorZoomAdjustFactor) {\n\t\tthis.$$set({ markupEditorZoomAdjustFactor });\n\t\tflush();\n\t}\n\n\tget markupEditorZoomAdjustWheelFactor() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset markupEditorZoomAdjustWheelFactor(markupEditorZoomAdjustWheelFactor) {\n\t\tthis.$$set({ markupEditorZoomAdjustWheelFactor });\n\t\tflush();\n\t}\n\n\tget markupEditorInteractionMode() {\n\t\treturn this.$$.ctx[273];\n\t}\n\n\tset markupEditorInteractionMode(markupEditorInteractionMode) {\n\t\tthis.$$set({ markupEditorInteractionMode });\n\t\tflush();\n\t}\n\n\tget muteAudio() {\n\t\treturn this.$$.ctx[274];\n\t}\n\n\tset muteAudio(muteAudio) {\n\t\tthis.$$set({ muteAudio });\n\t\tflush();\n\t}\n\n\tget willSetMediaInitialTimeOffset() {\n\t\treturn this.$$.ctx[275];\n\t}\n\n\tset willSetMediaInitialTimeOffset(willSetMediaInitialTimeOffset) {\n\t\tthis.$$set({ willSetMediaInitialTimeOffset });\n\t\tflush();\n\t}\n\n\tget enablePan() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset enablePan(enablePan) {\n\t\tthis.$$set({ enablePan });\n\t\tflush();\n\t}\n\n\tget enableZoom() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset enableZoom(enableZoom) {\n\t\tthis.$$set({ enableZoom });\n\t\tflush();\n\t}\n\n\tget enableZoomControls() {\n\t\treturn this.$$.ctx[276];\n\t}\n\n\tset enableZoomControls(enableZoomControls) {\n\t\tthis.$$set({ enableZoomControls });\n\t\tflush();\n\t}\n\n\tget enableZoomInput() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset enableZoomInput(enableZoomInput) {\n\t\tthis.$$set({ enableZoomInput });\n\t\tflush();\n\t}\n\n\tget enablePanInput() {\n\t\treturn this.$$.ctx[277];\n\t}\n\n\tset enablePanInput(enablePanInput) {\n\t\tthis.$$set({ enablePanInput });\n\t\tflush();\n\t}\n\n\tget enableCanvasAlpha() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset enableCanvasAlpha(enableCanvasAlpha) {\n\t\tthis.$$set({ enableCanvasAlpha });\n\t\tflush();\n\t}\n\n\tget enablePanLimit() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset enablePanLimit(enablePanLimit) {\n\t\tthis.$$set({ enablePanLimit });\n\t\tflush();\n\t}\n\n\tget panLimitGutterScalar() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tset panLimitGutterScalar(panLimitGutterScalar) {\n\t\tthis.$$set({ panLimitGutterScalar });\n\t\tflush();\n\t}\n\n\tget pan() {\n\t\treturn this.$$.ctx[278];\n\t}\n\n\tset pan(pan) {\n\t\tthis.$$set({ pan });\n\t\tflush();\n\t}\n\n\tget zoomPresetOptions() {\n\t\treturn this.$$.ctx[23];\n\t}\n\n\tset zoomPresetOptions(zoomPresetOptions) {\n\t\tthis.$$set({ zoomPresetOptions });\n\t\tflush();\n\t}\n\n\tget zoomAdjustStep() {\n\t\treturn this.$$.ctx[24];\n\t}\n\n\tset zoomAdjustStep(zoomAdjustStep) {\n\t\tthis.$$set({ zoomAdjustStep });\n\t\tflush();\n\t}\n\n\tget zoomAdjustFactor() {\n\t\treturn this.$$.ctx[25];\n\t}\n\n\tset zoomAdjustFactor(zoomAdjustFactor) {\n\t\tthis.$$set({ zoomAdjustFactor });\n\t\tflush();\n\t}\n\n\tget zoomAdjustWheelFactor() {\n\t\treturn this.$$.ctx[26];\n\t}\n\n\tset zoomAdjustWheelFactor(zoomAdjustWheelFactor) {\n\t\tthis.$$set({ zoomAdjustWheelFactor });\n\t\tflush();\n\t}\n\n\tget zoomLevel() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset zoomLevel(zoomLevel) {\n\t\tthis.$$set({ zoomLevel });\n\t\tflush();\n\t}\n\n\tget fixScrollDirection() {\n\t\treturn this.$$.ctx[279];\n\t}\n\n\tset fixScrollDirection(fixScrollDirection) {\n\t\tthis.$$set({ fixScrollDirection });\n\t\tflush();\n\t}\n\n\tget hideTextInput() {\n\t\treturn this.$$.ctx[280];\n\t}\n\n\tget showTextInput() {\n\t\treturn this.$$.ctx[281];\n\t}\n\n\tget imagePreviewSrc() {\n\t\treturn this.$$.ctx[282];\n\t}\n\n\tset imagePreviewSrc(imagePreviewSrc) {\n\t\tthis.$$set({ imagePreviewSrc });\n\t\tflush();\n\t}\n\n\tget imageOrienter() {\n\t\treturn this.$$.ctx[283];\n\t}\n\n\tset imageOrienter(imageOrienter) {\n\t\tthis.$$set({ imageOrienter });\n\t\tflush();\n\t}\n\n\tget pluginComponents() {\n\t\treturn this.$$.ctx[284];\n\t}\n\n\tset pluginComponents(pluginComponents) {\n\t\tthis.$$set({ pluginComponents });\n\t\tflush();\n\t}\n\n\tget pluginOptions() {\n\t\treturn this.$$.ctx[27];\n\t}\n\n\tset pluginOptions(pluginOptions) {\n\t\tthis.$$set({ pluginOptions });\n\t\tflush();\n\t}\n\n\tget sub() {\n\t\treturn this.$$.ctx[285];\n\t}\n\n\tget pluginInterface() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tget root() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset root(root) {\n\t\tthis.$$set({ root });\n\t\tflush();\n\t}\n\n\tget play() {\n\t\treturn this.$$.ctx[286];\n\t}\n\n\tget pause() {\n\t\treturn this.$$.ctx[287];\n\t}\n\n\tget isPaused() {\n\t\treturn this.$$.ctx[288];\n\t}\n\n\tget togglePlayPause() {\n\t\treturn this.$$.ctx[289];\n\t}\n\n\tget mute() {\n\t\treturn this.$$.ctx[290];\n\t}\n\n\tget unmute() {\n\t\treturn this.$$.ctx[291];\n\t}\n\n\tget toggleMute() {\n\t\treturn this.$$.ctx[292];\n\t}\n\n\tget getDuration() {\n\t\treturn this.$$.ctx[293];\n\t}\n\n\tget getCurrentTime() {\n\t\treturn this.$$.ctx[294];\n\t}\n\n\tget setCurrentTime() {\n\t\treturn this.$$.ctx[295];\n\t}\n\n\tget imageSourceToImageData() {\n\t\treturn this.$$.ctx[28];\n\t}\n\n\tset imageSourceToImageData(imageSourceToImageData) {\n\t\tthis.$$set({ imageSourceToImageData });\n\t\tflush();\n\t}\n\n\tget imagePreview() {\n\t\treturn this.$$.ctx[29];\n\t}\n\n\tget imagePreviewCurrent() {\n\t\treturn this.$$.ctx[236];\n\t}\n\n\tset imagePreviewCurrent(imagePreviewCurrent) {\n\t\tthis.$$set({ imagePreviewCurrent });\n\t\tflush();\n\t}\n\n\tget history() {\n\t\treturn this.$$.ctx[30];\n\t}\n}\n\n// which props to filter out of exported props\nconst utilPrivateProps = ['klass', 'stores', 'isVisible', 'isActive', 'isActiveFraction', 'locale'];\nconst viewPrivateProps = [\n    // methods\n    'history',\n    // props\n    'klass',\n    'stores',\n    'navButtons',\n    'pluginComponents',\n    'pluginInterface',\n    'pluginOptions',\n    'sub',\n    'imagePreviewSrc',\n    'imagePreview',\n    'imagePreviewCurrent',\n];\n// properties that should be merged with current value if set\nconst mergeProps = ['locale'];\n// view options array\nlet editorProps;\nconst pluginProps = new Set([]);\nconst propPluginRef = {};\n// loops over plugins and registers all available options so we can define getters/setters\nconst pluginComponents = new Map();\nconst setEditorViewPlugins = (...args) => {\n    args\n        // remove invalid plugins\n        .filter((plugin) => !!plugin.util)\n        // register valid plugins\n        .forEach((plugin) => {\n        const [id, Component, isSupported = () => true] = plugin.util;\n        // already set\n        if (pluginComponents.has(id))\n            return;\n        // store\n        pluginComponents.set(id, { Component, isSupported });\n        // get props\n        getComponentExportedProps(Component)\n            .filter((prop) => !utilPrivateProps.includes(prop))\n            .forEach((prop) => {\n            pluginProps.add(prop);\n            if (propPluginRef[prop]) {\n                propPluginRef[prop].push(id);\n                return;\n            }\n            propPluginRef[prop] = [id];\n        });\n    });\n};\nconst getEditorViewProps = () => {\n    editorProps = new Set(getComponentExportedProps(Ui).filter((prop) => !viewPrivateProps.includes(prop)));\n    return [...editorProps, ...pluginProps];\n};\nconst attachEditorView = (target, stores) => {\n    const accessors = {};\n    // a map of values already set to the editor. This helps us compare if the value we're about to set is different than the already set value.\n    const valueRefs = new Map();\n    // creates the editor component instance\n    const editor = new Ui({\n        target,\n        props: {\n            stores,\n            pluginComponents: Array.from(pluginComponents),\n        },\n    });\n    // destroys the editor component instance\n    let isDestroyed = false;\n    const destroy = () => {\n        if (isDestroyed)\n            return;\n        if (!editor)\n            return;\n        isDestroyed = true;\n        editor.$destroy();\n    };\n    // set up accessors for editor props\n    if (!editorProps)\n        editorProps = new Set(getComponentExportedProps(Ui).filter((prop) => !viewPrivateProps.includes(prop)));\n    // test if this prop is already set to this value, else we don't set it again, we added this to prevent spreading of getEditorDefaultProps from constantly overriding props in (for example) React\n    function didAlreadySet(prop, value) {\n        // if we already merged this value don't set it\n        if (valueRefs.get(prop) === value)\n            return true;\n        // store value so we can compare next time\n        valueRefs.set(prop, value);\n        return false;\n    }\n    editorProps.forEach((prop) => {\n        Object.defineProperty(accessors, prop, {\n            get: () => editor[prop],\n            set: mergeProps.includes(prop)\n                ? // merge new value with existing value\n                    (value) => {\n                        if (didAlreadySet(prop, value))\n                            return;\n                        editor[prop] = {\n                            ...editor[prop],\n                            ...value,\n                        };\n                    }\n                : // overwrite current value\n                    (value) => {\n                        if (didAlreadySet(prop, value))\n                            return;\n                        editor[prop] = value;\n                    },\n        });\n    });\n    // this reads the imagePreview store so third parties can interact with image data\n    Object.defineProperty(accessors, 'previewImageData', {\n        get: () => editor.imagePreviewCurrent,\n    });\n    // set up accessors for plugin props\n    pluginProps.forEach((prop) => {\n        const plugins = propPluginRef[prop];\n        const plugin = plugins[0]; // will always get value from first plugin, when plugins share a property the value will be in sync when set\n        Object.defineProperty(accessors, prop, {\n            get: () => editor.pluginInterface[plugin][prop],\n            set: (value) => {\n                if (didAlreadySet(prop, value))\n                    return;\n                const opts = plugins.reduce((prev, plugin) => {\n                    prev[plugin] = {\n                        ...editor.pluginOptions[plugin],\n                        [prop]: value,\n                    };\n                    return prev;\n                }, {});\n                editor.pluginOptions = {\n                    ...editor.pluginOptions,\n                    ...opts,\n                };\n            },\n        });\n    });\n    // add `element` root query\n    Object.defineProperty(accessors, 'element', {\n        get: () => editor.root,\n        set: () => undefined,\n    });\n    // history shortcut\n    const history = editor.history;\n    defineMethods(accessors, {\n        on: (event, cb) => {\n            // exit if editor was destroyed, will return stub function so unsubs can be called without issues\n            if (isDestroyed)\n                return () => {\n                    // Do nothing\n                };\n            // catch history events and route to history object\n            if (/undo|redo|revert|writehistory/.test(event))\n                return history.on(event, cb);\n            // gather unsub methods\n            const unsubs = [\n                editor.sub(event, cb),\n                editor.$on(event, (e) => cb(e instanceof CustomEvent && !e.detail ? undefined : e)),\n            ].filter(Boolean);\n            // set up unsubscribe group\n            return () => unsubs.forEach((unsub) => unsub());\n        },\n        updateImagePreview: (src) => {\n            editor.imagePreviewSrc = src;\n        },\n        close: () => !isDestroyed && editor.pub('close'),\n        destroy,\n    });\n    Object.defineProperty(accessors, 'history', {\n        get: () => ({\n            undo: () => history.undo(),\n            redo: () => history.redo(),\n            revert: () => history.revert(),\n            get: () => history.get(),\n            getCollapsed: () => {\n                const entries = history.get();\n                return entries.splice(0, history.index + 1);\n            },\n            set: (entries) => history.set(entries),\n            write: (state) => history.write(state),\n            get length() {\n                return history.length();\n            },\n            get index() {\n                return history.index;\n            },\n            set index(index) {\n                history.index = index;\n            },\n        }),\n    });\n    return accessors;\n};\n\nvar editorEvents = [\n    // core editor events that should be re-dispatched\n    ...editorEventsToBubble,\n    // ui editor events\n    'init',\n    'update',\n    'undo',\n    'redo',\n    'revert',\n    'writehistory',\n    'destroy',\n    'show',\n    'hide',\n    'close',\n    'ready',\n    'zoom',\n    'pan',\n    'loadpreview',\n    'selectshape',\n    'blurshape',\n    'updateshape',\n    'addshape',\n    'removeshape',\n    'selectstyle',\n    'markuptap',\n    'markupzoom',\n    'markuppan',\n    'selectutil',\n    'selectcontrol',\n    'selectiondown',\n    'selectionup',\n    'selectionchange',\n];\n\nconst dispatchElementEvent = (target, event, detail) => target.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, cancelable: true }));\nvar dispatchEditorEvents = (editor, handler, options = {}) => {\n    const { prefix = 'pintura:' } = options;\n    return editorEvents.map((event) => editor.on(event, (value) => isElement(handler)\n        ? dispatchElementEvent(handler, `${prefix}${event}`, value)\n        : handler(event, value)));\n};\n\nvar naturalAspectRatioToNumber = (value) => {\n    // already valid value\n    if (value === undefined || isNumber(value))\n        return value;\n    // invalid\n    if (!isString(value))\n        return false;\n    // convert string to aspect ratio fraction\n    const str = value;\n    // we interpret empty string as undefined\n    if (!str.length)\n        return undefined;\n    // get numbers\n    const [w, h] = str\n        .split(/\\/|:/g)\n        .map((value) => parseFloat(value.replace(/,/, '.')))\n        .filter(Boolean);\n    // invalid\n    if (!w)\n        return false;\n    // single value received\n    if (!h)\n        return w;\n    // lets convert to fraction\n    return Math.abs(w / h);\n};\n\nvar arrayInsert = (array, index, item) => {\n    array.splice(index, 0, item);\n    return array;\n};\n\n// first index is always id, so if is string, it's a node\nconst isNode = (item) => isString(item[0]);\n// if it's not a node, it's a nodelist\nconst isNodeList = (item) => !isNode(item);\nconst getNodeId = (node) => node[1];\nconst getNodeChildren = (node) => node[3] || [];\nfunction createNode(instance, id, props, children) {\n    // if three arguments received, props can be children\n    if (Array.isArray(props)) {\n        children = props;\n        props = {};\n    }\n    // node is always array of four entries\n    return [instance, id, props || {}, children || []];\n}\nconst insertNode = (node, needle, haystack, getIndex = (index) => index) => {\n    const nodeList = findNodeList(needle, haystack);\n    const targetIndex = nodeList.findIndex((item) => getNodeId(item) === needle);\n    arrayInsert(nodeList, getIndex(targetIndex), node);\n};\nconst insertNodeBefore = (node, needle, haystack) => insertNode(node, needle, haystack);\nconst insertNodeAfter = (node, needle, haystack) => insertNode(node, needle, haystack, (index) => index + 1);\nconst appendNode = (node, haystack) => {\n    // if is list, add to list\n    if (isNodeList(haystack))\n        return haystack.push(node);\n    // else it's a node, add to node children\n    haystack[3] = [...getNodeChildren(haystack), node];\n};\nconst removeNode = (needle, haystack) => {\n    const nodeList = findNodeList(needle, haystack);\n    arrayRemove(nodeList, (item) => getNodeId(item) === needle);\n    return nodeList;\n};\nconst findNode = (needle, haystack) => {\n    if (!haystack || !haystack.length)\n        return;\n    // haystack is a node, maybe node is a match or one of children is a match\n    if (isNode(haystack)) {\n        if (getNodeId(haystack) === needle) {\n            return haystack;\n        }\n        const res = findNode(needle, getNodeChildren(haystack));\n        if (res)\n            return res;\n    }\n    if (isNodeList(haystack)) {\n        for (const child of haystack) {\n            const res = findNode(needle, child);\n            if (res)\n                return res;\n        }\n    }\n};\nconst findNodeList = (needle, haystack) => {\n    // haystack is node list\n    if (isNodeList(haystack)) {\n        // lets search nodes in this haystack\n        if (haystack.find((item) => getNodeId(item) === needle))\n            return haystack;\n        // not found, lets move the search to the childnodes\n        const item = haystack.find((item) => findNodeList(needle, getNodeChildren(item)));\n        return item && item[3];\n    }\n    // is node, lets find in children\n    return findNodeList(needle, getNodeChildren(haystack));\n};\nconst updateNode = (node, props) => {\n    const [, , nodeProps] = node;\n    Object.assign(nodeProps, props);\n};\n\nconst pastel = () => \n// prettier-ignore\n[\n    0.75, 0.25, 0.25, 0, 0,\n    0.25, 0.75, 0.25, 0, 0,\n    0.25, 0.25, 0.75, 0, 0,\n    0, 0, 0, 1, 0\n];\nconst chrome = () => \n// prettier-ignore\n[\n    1.398, -0.316, 0.065, -0.273, 0.201,\n    -0.051, 1.278, -0.080, -0.273, 0.201,\n    -0.051, 0.119, 1.151, -0.290, 0.215,\n    0, 0, 0, 1, 0\n];\nconst fade = () => \n// prettier-ignore\n[\n    1.073, -0.015, 0.092, -0.115, -0.017,\n    0.107, 0.859, 0.184, -0.115, -0.017,\n    0.015, 0.077, 1.104, -0.115, -0.017,\n    0, 0, 0, 1, 0\n];\nconst warm = () => \n// prettier-ignore\n[\n    1.06, 0, 0, 0, 0,\n    0, 1.01, 0, 0, 0,\n    0, 0, 0.93, 0, 0,\n    0, 0, 0, 1, 0,\n];\nconst cold = () => \n// prettier-ignore\n[\n    1.1, 0, 0, 0, -.1,\n    0, 1.1, 0, 0, -.1,\n    0, 0, 1.2, 0, -.1,\n    0, 0, 0, 1, 0,\n];\nconst invert = () => \n// prettier-ignore\n[\n    -1, 0, 0, 1, 0,\n    0, -1, 0, 1, 0,\n    0, 0, -1, 1, 0,\n    0, 0, 0, 1, 0,\n];\nconst monoDefault = () => \n// prettier-ignore\n[\n    0.212, 0.715, 0.114, 0, 0,\n    0.212, 0.715, 0.114, 0, 0,\n    0.212, 0.715, 0.114, 0, 0,\n    0, 0, 0, 1, 0\n];\nconst monoNoir = () => \n// prettier-ignore\n[\n    0.15, 1.3, -0.25, 0.1, -0.2,\n    0.15, 1.3, -0.25, 0.1, -0.2,\n    0.15, 1.3, -0.25, 0.1, -0.2,\n    0, 0, 0, 1, 0\n];\nconst monoWash = () => \n// prettier-ignore\n[\n    0.163, 0.518, 0.084, -0.010, 0.208,\n    0.163, 0.529, 0.082, -0.020, 0.210,\n    0.171, 0.529, 0.084, 0.000, 0.214,\n    0, 0, 0, 1, 0\n];\nconst monoStark = () => \n// prettier-ignore\n[\n    0.338, 0.991, 0.117, 0.093, -0.196,\n    0.302, 1.049, 0.096, 0.078, -0.196,\n    0.286, 1.016, 0.146, 0.101, -0.196,\n    0, 0, 0, 1, 0\n];\nconst sepiaDefault = () => \n// prettier-ignore\n[\n    0.393, 0.768, 0.188, 0, 0,\n    0.349, 0.685, 0.167, 0, 0,\n    0.272, 0.533, 0.130, 0, 0,\n    0, 0, 0, 1, 0,\n];\nconst sepiaBlues = () => \n// prettier-ignore\n[\n    0.289, 0.620, 0.185, 0.000, 0.077,\n    0.257, 0.566, 0.163, 0.000, 0.115,\n    0.200, 0.430, 0.128, 0.000, 0.188,\n    0, 0, 0, 1, 0\n];\nconst sepiaRust = () => \n// prettier-ignore\n[\n    0.269, 0.764, 0.172, 0.050, 0.100,\n    0.239, 0.527, 0.152, 0.000, 0.176,\n    0.186, 0.400, 0.119, 0.000, 0.159,\n    0, 0, 0, 1, 0\n];\nconst sepiaColor = () => \n// prettier-ignore\n[\n    0.547, 0.764, 0.134, 0.000, -0.147,\n    0.281, 0.925, 0.120, 0.000, -0.135,\n    0.225, 0.558, 0.330, 0.000, -0.113,\n    0, 0, 0, 1, 0\n];\n//\n// default filter set\n//\nconst filterFunctionsDefault = {\n    chrome,\n    fade,\n    pastel,\n    cold,\n    warm,\n    monoDefault,\n    monoWash,\n    monoNoir,\n    monoStark,\n    sepiaDefault,\n    sepiaRust,\n    sepiaBlues,\n    sepiaColor,\n};\nconst filterOptionsDefault = [\n    ['Default', [[undefined, (locale) => locale.labelDefault]]],\n    [\n        'Classic',\n        [\n            ['chrome', (locale) => locale.filterLabelChrome],\n            ['fade', (locale) => locale.filterLabelFade],\n            ['cold', (locale) => locale.filterLabelCold],\n            ['warm', (locale) => locale.filterLabelWarm],\n            ['pastel', (locale) => locale.filterLabelPastel],\n        ],\n    ],\n    [\n        'Monochrome',\n        [\n            ['monoDefault', (locale) => locale.filterLabelMonoDefault],\n            ['monoNoir', (locale) => locale.filterLabelMonoNoir],\n            ['monoStark', (locale) => locale.filterLabelMonoStark],\n            ['monoWash', (locale) => locale.filterLabelMonoWash],\n        ],\n    ],\n    [\n        'Sepia',\n        [\n            ['sepiaDefault', (locale) => locale.filterLabelSepiaDefault],\n            ['sepiaRust', (locale) => locale.filterLabelSepiaRust],\n            ['sepiaBlues', (locale) => locale.filterLabelSepiaBlues],\n            ['sepiaColor', (locale) => locale.filterLabelSepiaColor],\n        ],\n    ],\n];\nvar _plugin_filter_defaults = {\n    filterFunctions: filterFunctionsDefault,\n    filterOptions: filterOptionsDefault,\n};\n\n//#region markup\nconst propertyMap = {\n    borderColor: 'strokeColor',\n    borderWidth: 'strokeWidth',\n    lineWidth: 'strokeWidth',\n    fontColor: 'color',\n    lineColor: 'strokeColor',\n    src: 'backgroundImage',\n    fit: 'backgroundSize',\n};\nconst convertValue = (value) => {\n    if (value === 0)\n        return 0;\n    if (value === '0%')\n        return 0;\n    if (value === '0px')\n        return 0;\n    if (/px$/.test(value))\n        return parseInt(value, 10);\n    if (/\\%$/.test(value))\n        return value;\n    if (value <= 1)\n        return `${value * 100}%`;\n};\nconst addValues = (a, b) => {\n    let _a, _b;\n    if (/%$/.test(a)) {\n        _a = parseFloat(a);\n        _b = parseFloat(b);\n        return `${_a + _b}%`;\n    }\n    if (/px$/.test(a)) {\n        _a = parseInt(a, 10);\n        _b = parseInt(b, 10);\n        return `${_a + _b}px`;\n    }\n};\nconst shapeFromLegacyMarkup = (crop, type, style) => {\n    const shape = Object.keys(style).reduce((res, prop) => {\n        let value = style[prop];\n        // rename prop\n        prop = propertyMap[prop] || prop;\n        // if is px value\n        if (/px$/.test(value)) {\n            value = convertValue(value);\n        }\n        // if is number convert to percentage\n        else if (/^(?:x|y|left|right|top|bottom|width|height|fontSize|borderWidth|strokeWidth)$/.test(prop) &&\n            typeof value === 'number') {\n            // except for widths and font sizes, change to those to absolute values\n            if (prop === 'strokeWidth' || prop === 'borderWidth' || prop === 'fontSize') {\n                const minAxis = Math.min(crop.width, crop.height);\n                value = `${minAxis * value}px`;\n            }\n            value = convertValue(value);\n        }\n        // if is color value\n        if (/color/i.test(prop) && value)\n            value = colorStringToColorArray(value);\n        if (value === null)\n            value = undefined;\n        res[prop] = value;\n        return res;\n    }, {});\n    if (type === 'line') {\n        if (shape.lineDecoration.length >= 1)\n            shape.lineEnd = 'arrow';\n        if (shape.lineDecoration.length === 2)\n            shape.lineStart = 'arrow';\n        shape.x1 = shape.x;\n        shape.y1 = shape.y;\n        shape.x2 = addValues(shape.x, shape.width);\n        shape.y2 = addValues(shape.y, shape.height);\n        delete shape.x;\n        delete shape.y;\n        delete shape.width;\n        delete shape.height;\n        delete shape.lineDecoration;\n        delete shape.lineStyle;\n    }\n    if (type === 'text') {\n        // need y to be absolute to calculate correct sizes\n        if (!isNumber(shape.y)) {\n            const minAxis = Math.min(crop.width, crop.height);\n            shape.y = minAxis * (parseFloat(shape.y) / 100);\n        }\n        shape.y = shape.y - shape.fontSize;\n        delete shape.width;\n        delete shape.height;\n        delete shape.borderStyle;\n        shape.lineHeight = shape.lineHeight || '120%';\n    }\n    if (type === 'ellipse') {\n        let w, h;\n        // calculate `rx` and `ry` based on `width` and `h`eight`\n        if (/%$/.test(shape.width)) {\n            w = parseFloat(shape.width) / 100;\n            h = parseFloat(shape.height) / 100;\n            const widthAbsolute = w * crop.width;\n            const heightAbsolute = h * crop.height;\n            w = (widthAbsolute / crop.width) * 100;\n            h = (heightAbsolute / crop.height) * 100;\n        }\n        else {\n            w = shape.width;\n            h = shape.height;\n        }\n        shape.rx = w * 0.5;\n        shape.ry = h * 0.5;\n        if (/%$/.test(shape.width)) {\n            shape.rx += '%';\n            shape.ry += '%';\n        }\n        shape.x = addValues(shape.x, shape.rx);\n        shape.y = addValues(shape.y, shape.ry);\n        delete shape.width;\n        delete shape.height;\n        delete shape.borderStyle;\n    }\n    if (type === 'rect') {\n        delete shape.borderStyle;\n    }\n    if (type === 'path') {\n        // remove points that are too close\n        let out = [];\n        let lastAdded;\n        for (const point of shape.points) {\n            // always add first\n            if (!lastAdded) {\n                out.push(point);\n                lastAdded = point;\n                continue;\n            }\n            // if too far, skip\n            const dist = vectorDistanceSquared(lastAdded, point);\n            if (dist < 0.000000001)\n                continue;\n            // add!\n            out.push(point);\n            lastAdded = point;\n            // set new last point\n            lastAdded = point;\n        }\n        //\n        shape.points = out.map((point) => {\n            return {\n                x: convertValue(point.x),\n                y: convertValue(point.y),\n            };\n        });\n    }\n    return shape;\n};\n//#endregion\n//#region crop\nconst getOffsetPointOnEdge = (length, rotation) => {\n    const a = length;\n    const A = 1.5707963267948966;\n    const B = rotation;\n    const C = 1.5707963267948966 - rotation;\n    const sinA = Math.sin(A);\n    const sinB = Math.sin(B);\n    const sinC = Math.sin(C);\n    const cosC = Math.cos(C);\n    const ratio = a / sinA;\n    const b = ratio * sinB;\n    const c = ratio * sinC;\n    return vectorCreate(cosC * b, cosC * c);\n};\nconst getRotatedRectSize = (rect, rotation) => {\n    const w = rect.width;\n    const h = rect.height;\n    const hor = getOffsetPointOnEdge(w, rotation);\n    const ver = getOffsetPointOnEdge(h, rotation);\n    const tl = vectorCreate(rect.x + Math.abs(hor.x), rect.y - Math.abs(hor.y));\n    const tr = vectorCreate(rect.x + rect.width + Math.abs(ver.y), rect.y + Math.abs(ver.x));\n    const bl = vectorCreate(rect.x - Math.abs(ver.y), rect.y + rect.height - Math.abs(ver.x));\n    return {\n        width: vectorDistance(tl, tr),\n        height: vectorDistance(tl, bl),\n    };\n};\nconst getBoundsAroundCenter = (imageSize, center) => {\n    const cx = center.x > 0.5 ? 1 - center.x : center.x;\n    const cy = center.y > 0.5 ? 1 - center.y : center.y;\n    return sizeCreate(cx * 2 * imageSize.width, cy * 2 * imageSize.height);\n};\nconst getCanvasSize = (imageSize, canvasAspectRatio, zoom = 1) => {\n    const imageAspectRatio = imageSize.height / imageSize.width;\n    // determine actual pixels on x and y axis\n    const canvasWidth = 1;\n    const canvasHeight = canvasAspectRatio;\n    let imgWidth = 1;\n    let imgHeight = imageAspectRatio;\n    if (imgHeight > canvasHeight) {\n        imgHeight = canvasHeight;\n        imgWidth = imgHeight / imageAspectRatio;\n    }\n    const scalar = Math.max(canvasWidth / imgWidth, canvasHeight / imgHeight);\n    const width = imageSize.width / (zoom * scalar * imgWidth);\n    const height = width * canvasAspectRatio;\n    return {\n        width: width,\n        height: height,\n    };\n};\nconst getCenteredCropRect = (imageSize, aspectRatio) => {\n    let width = imageSize.width;\n    let height = width * aspectRatio;\n    if (height > imageSize.height) {\n        height = imageSize.height;\n        width = height / aspectRatio;\n    }\n    const x = (imageSize.width - width) * 0.5;\n    const y = (imageSize.height - height) * 0.5;\n    return rectCreate(x, y, width, height);\n};\nconst getCorrectedLegacyAspectRatio = (imageSize, aspectRatio) => aspectRatio != null\n    ? // fix the aspect ratio\n        1 / aspectRatio\n    : // set image aspect ratio\n        imageSize.width / imageSize.height;\nconst imagePropertiesFromLegacyCrop = (imageSize, { flip, aspectRatio, rotation, center, zoom, scaleToFit }) => {\n    const res = {\n        flipX: false,\n        flipY: false,\n    };\n    // is centered crop\n    const isCenteredCrop = !center || (center && center.x === 0.5 && center.y === 0.5);\n    // handle basic props\n    if (flip && flip.horizontal)\n        res.flipX = flip.horizontal;\n    if (flip && flip.vertical)\n        res.flipY = flip.vertical;\n    // fix aspect ratio, in FilePond and editor v6 it's height/width instead of width/height\n    const correctedAspectRatio = getCorrectedLegacyAspectRatio(imageSize, aspectRatio);\n    // image bounds\n    const cropLimit = !(scaleToFit === false);\n    const canvasSize = getCanvasSize(imageSize, aspectRatio, zoom);\n    const cropSize = isCenteredCrop\n        ? imageSize\n        : getBoundsAroundCenter(imageSize, cropLimit ? center : { x: 0.5, y: 0.5 });\n    const cropCentered = getCenteredCropRect(imageSize, aspectRatio);\n    // has different aspect ratio than image\n    if (aspectRatio || !isCenteredCrop || zoom) {\n        res.crop = rectContainRect(rectCreateFromSize(cropSize), correctedAspectRatio);\n    }\n    if (typeof rotation === 'number' && rotation !== null && rotation !== 0) {\n        if (rotation != null)\n            res.rotation = rotation;\n        const rotatedCropSize = getRotatedRectSize(cropCentered, rotation);\n        const scalar = Math.max(rotatedCropSize.width / cropSize.width, rotatedCropSize.height / cropSize.height);\n        // crop position in non-rotated image\n        const cropCenter = vectorCreate(center.x * imageSize.width, center.y * imageSize.height);\n        // get rotated image center\n        const rotatedImageSize = getImageTransformedRect(imageSize, rotation);\n        const rotatedImageCenter = sizeCenter(rotatedImageSize);\n        const rotatedImageOffset = vectorCreate((rotatedImageSize.width - imageSize.width) * 0.5, (rotatedImageSize.height - imageSize.height) * 0.5);\n        const cropPoints = rectRotate({\n            x: rotatedImageOffset.x + cropCenter.x - (canvasSize.width / scalar) * 0.5,\n            y: rotatedImageOffset.y + cropCenter.y - (canvasSize.height / scalar) * 0.5,\n            width: canvasSize.width / scalar,\n            height: canvasSize.height / scalar,\n        }, rotation);\n        const cropBoundsPoints = vectorsRotate(cropPoints.map(vectorClone), rotation, rotatedImageCenter.x, rotatedImageCenter.y);\n        const cropBoundsPointsCenter = rectCenter(rectCreateFromPoints(cropBoundsPoints));\n        const deRotatedCropBoundsPoints = vectorsRotate(cropBoundsPoints.map(vectorClone), -(rotation * 2), cropBoundsPointsCenter.x, cropBoundsPointsCenter.y);\n        res.crop = rectCreateFromPoints(deRotatedCropBoundsPoints);\n    }\n    else if (zoom != null) {\n        rectScale(res.crop, 1 / zoom);\n    }\n    if (!cropLimit) {\n        res.cropLimitToImage = false;\n    }\n    return res;\n};\n//#endregion\nconst isLegacyData = (data = {}) => {\n    if ('markup' in data || 'color' in data || 'filter' in data)\n        return true;\n    const { crop } = data;\n    if (crop && ('flip' in crop || 'center' in crop || 'aspectRatio' in crop || 'rotation' in crop))\n        return true;\n    return false;\n};\nvar legacyDataToImageState = (editor, imageSize, data = {}) => {\n    const res = {};\n    // test if isn't legacy data\n    if (!isLegacyData(data))\n        return data;\n    if (data.crop) {\n        Object.assign(res, imagePropertiesFromLegacyCrop(imageSize, data.crop));\n    }\n    if (data.markup) {\n        const markup = Array.isArray(data.markup) ? data.markup : Object.values(data.markup);\n        res.decoration = markup.map((markup) => shapeFromLegacyMarkup(res.crop || imageSize, markup[0], markup[1]));\n    }\n    if (data.color || data.colors) {\n        const colors = data.color || data.colors;\n        Object.keys(colors)\n            .filter((key) => colors[key])\n            .map((key) => [\n            key,\n            Array.isArray(colors[key].matrix)\n                ? colors[key].matrix\n                : Object.values(colors[key].matrix),\n        ])\n            .forEach(([key, value]) => {\n            if (!res.colorMatrix)\n                res.colorMatrix = {};\n            res.colorMatrix[key] = value;\n        });\n    }\n    if (data.filter || data.filters) {\n        const filter = data.filters || data.filter;\n        if (!res.colorMatrix)\n            res.colorMatrix = {};\n        const filterFunctions = editor ? editor['filterFunctions'] : filterFunctionsDefault;\n        res.colorMatrix.filter =\n            typeof filter === 'string' && filterFunctions[filter]\n                ? filterFunctions[filter]()\n                : filter.matrix;\n    }\n    const resize = data.size ? data.size : data.resize ? data.resize.size : false;\n    if (resize && resize.width && resize.height) {\n        res.targetSize = {\n            width: resize.width,\n            height: resize.height,\n        };\n    }\n    return res;\n};\n\nconst isOperaMini = () => Object.prototype.toString.call(window['operamini']) === '[object OperaMini]';\nconst hasPromises = () => 'Promise' in window;\nconst hasCreateObjectURL = () => 'URL' in window && 'createObjectURL' in window.URL;\nconst hasVisibility = () => 'visibilityState' in document;\nconst hasTiming = () => 'performance' in window; // iOS 8.x\nconst hasFileConstructor = () => 'File' in window; // excludes IE11\nlet result$1 = null;\nvar isModernBrowser = () => {\n    if (result$1 === null)\n        result$1 =\n            isBrowser() &&\n                // Can't run on Opera Mini due to lack of everything\n                !isOperaMini() &&\n                // Require these APIs to feature detect a modern browser\n                hasVisibility() &&\n                hasPromises() &&\n                hasFileConstructor() &&\n                hasCreateObjectURL() &&\n                hasTiming();\n    return result$1;\n};\n\nconst brightness = {\n    base: 0,\n    min: -0.25,\n    max: 0.25,\n    getLabel: (value) => toPercentageNumber(value / 0.25),\n    getStore: ({ imageColorMatrix }) => imageColorMatrix,\n    getValue: (store) => {\n        if (!store.brightness)\n            return;\n        return store.brightness[4];\n    },\n    setValue: (store, v) => store.update((matrices) => ({\n        // clone existing matrices\n        ...matrices,\n        // prettier-ignore\n        brightness: [\n            1, 0, 0, 0, v,\n            0, 1, 0, 0, v,\n            0, 0, 1, 0, v,\n            0, 0, 0, 1, 0\n        ],\n    })),\n};\nconst contrast = {\n    base: 1,\n    min: 0.5,\n    max: 1.5,\n    getLabel: (value) => toPercentageNumber(-1 + (value - 0.5) * 2),\n    getStore: ({ imageColorMatrix }) => imageColorMatrix,\n    getValue: (store) => {\n        if (!store.contrast)\n            return;\n        return store.contrast[0];\n    },\n    setValue: (store, v) => store.update((matrices) => ({\n        // clone existing matrices\n        ...matrices,\n        // prettier-ignore\n        contrast: [\n            v, 0, 0, 0, .5 * (1 - v),\n            0, v, 0, 0, .5 * (1 - v),\n            0, 0, v, 0, .5 * (1 - v),\n            0, 0, 0, 1, 0\n        ],\n    })),\n};\nconst saturation = {\n    base: 1,\n    min: 0,\n    max: 2,\n    getLabel: (value) => toPercentageNumber(value - 1),\n    getStore: ({ imageColorMatrix }) => imageColorMatrix,\n    getValue: (store) => {\n        if (!store.saturation)\n            return;\n        return (store.saturation[0] - 0.213) / 0.787;\n    },\n    setValue: (store, v) => store.update((matrices) => ({\n        ...matrices,\n        // prettier-ignore\n        saturation: [\n            .213 + .787 * v, .715 - .715 * v, .072 - .072 * v, 0, 0,\n            .213 - .213 * v, .715 + .285 * v, .072 - .072 * v, 0, 0,\n            .213 - .213 * v, .715 - .715 * v, .072 + .928 * v, 0, 0,\n            0, 0, 0, 1, 0\n        ],\n    })),\n};\nconst exposure = {\n    base: 1,\n    min: 0.5,\n    max: 1.5,\n    getLabel: (value) => toPercentageNumber(-1 + (value - 0.5) * 2),\n    getStore: ({ imageColorMatrix }) => imageColorMatrix,\n    getValue: (store) => {\n        if (!store.exposure)\n            return;\n        return store.exposure[0];\n    },\n    setValue: (store, v) => store.update((matrices) => ({\n        ...matrices,\n        // prettier-ignore\n        exposure: [\n            v, 0, 0, 0, 0,\n            0, v, 0, 0, 0,\n            0, 0, v, 0, 0,\n            0, 0, 0, 1, 0\n        ],\n    })),\n};\nconst gamma = {\n    base: 1,\n    min: 0.15,\n    max: 4,\n    getLabel: (value) => {\n        if (value < 1) {\n            return toPercentageNumber((value - 0.15) / 0.85 - 1);\n        }\n        return toPercentageNumber((value - 1) / 3);\n    },\n    getStore: ({ imageGamma }) => imageGamma,\n};\nconst vignette = {\n    base: 0,\n    min: -1,\n    max: 1,\n    getStore: ({ imageVignette }) => imageVignette,\n};\nconst clarity = {\n    base: 0,\n    min: -1,\n    max: 1,\n    getStore: ({ imageConvolutionMatrix }) => imageConvolutionMatrix,\n    getValue: (store) => {\n        if (!store.clarity)\n            return;\n        if (store.clarity[0] === 0) {\n            return store.clarity[1] / -1;\n        }\n        else {\n            return store.clarity[1] / -2;\n        }\n    },\n    setValue: (store, v) => {\n        store.update((matrices) => ({\n            ...matrices,\n            // prettier-ignore\n            clarity: v >= 0\n                ? [0, -1 * v, 0,\n                    -1 * v, 1 + 4 * v, -1 * v,\n                    0, -1 * v, 0\n                ]\n                : [-1 * v, -2 * v, -1 * v,\n                    -2 * v, 1 + -3 * v, -2 * v,\n                    -1 * v, -2 * v, -1 * v\n                ],\n        }));\n    },\n};\nconst temperature = {\n    base: 0,\n    min: -1,\n    max: 1,\n    getStore: ({ imageColorMatrix }) => imageColorMatrix,\n    getValue: (store) => {\n        if (!store.temperature)\n            return;\n        const v = store.temperature[0];\n        if (v >= 1) {\n            return (v - 1) / 0.1;\n        }\n        return (1 - v) / -0.15;\n    },\n    setValue: (store, v) => store.update((matrices) => ({\n        ...matrices,\n        // prettier-ignore\n        temperature: v > 0 ? [\n            1 + (v * .1), 0, 0, 0, 0,\n            0, 1, 0, 0, 0,\n            0, 0, 1 + (-v * .1), 0, 0,\n            0, 0, 0, 1, 0\n        ] : [\n            1 + (v * .15), 0, 0, 0, 0,\n            0, 1 + (v * .05), 0, 0, 0,\n            0, 0, 1 + (-v * .15), 0, 0,\n            0, 0, 0, 1, 0\n        ],\n    })),\n};\nconst finetuneControlConfigurationDefault = {\n    gamma,\n    brightness,\n    contrast,\n    saturation,\n    exposure,\n    temperature,\n    clarity,\n    vignette,\n};\nconst finetuneOptionsDefault = [\n    ['brightness', (locale) => locale.finetuneLabelBrightness],\n    ['contrast', (locale) => locale.finetuneLabelContrast],\n    ['saturation', (locale) => locale.finetuneLabelSaturation],\n    ['exposure', (locale) => locale.finetuneLabelExposure],\n    ['temperature', (locale) => locale.finetuneLabelTemperature],\n    ['gamma', (locale) => locale.finetuneLabelGamma],\n    !isSoftwareRendering() && ['clarity', (locale) => locale.finetuneLabelClarity],\n    ['vignette', (locale) => locale.finetuneLabelVignette],\n].filter(Boolean);\nvar _plugin_finetune_defaults = {\n    finetuneControlConfiguration: finetuneControlConfigurationDefault,\n    finetuneOptions: finetuneOptionsDefault,\n};\n/*\nTODO: fix inverse fn in getValue\nexport const hue = {\n    base: 0,\n    min: 0,\n    max: Math.PI,\n    getStore: ({ imageColorMatrix }) => imageColorMatrix,\n    getValue: (store) => {\n        if (!store.hue) return;\n\n        const v = store.hue[1];\n\n        const o = -(Math.acos((0.715 - v) / Math.sqrt(2) / 0.715) - Math.PI / 4);\n\n        return o;\n    },\n    setValue: (store, v: number) => {\n        store.update((matrices) => {\n            // const value = v * (Math.PI);\n\n            const cos = Math.cos(v);\n            const sin = Math.sin(v);\n\n            const a00 = 0.213 + cos * 0.787 - sin * 0.213;\n            const a01 = 0.715 - cos * 0.715 - sin * 0.715;\n            const a02 = 0.072 - cos * 0.072 + sin * 0.928;\n            const a10 = 0.213 - cos * 0.213 + sin * 0.143;\n            const a11 = 0.715 + cos * 0.285 + sin * 0.14;\n            const a12 = 0.072 - cos * 0.072 - sin * 0.283;\n            const a20 = 0.213 - cos * 0.213 - sin * 0.787;\n            const a21 = 0.715 - cos * 0.715 + sin * 0.715;\n            const a22 = 0.072 + cos * 0.928 + sin * 0.072;\n\n            return {\n                ...matrices,\n\n                // prettier-ignore\n                hue: [\n                    a00, a01, a02, 0, 0,\n                    a10, a11, a12, 0, 0,\n                    a20, a21, a22, 0, 0,\n                      0,   0,   0, 1, 0,\n                ]\n            };\n        });\n    },\n};\n*/\n\nconst createDivThumb = (style, id = 'thumb') => [\n    'div',\n    id,\n    {\n        style,\n        textContent: ' ',\n    },\n];\nconst solidSharp = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'solid',\n        frameSize: '2.5%',\n    },\n    thumb: '<rect stroke-width=\"5\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\"/>',\n};\nconst solidRound = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'solid',\n        frameSize: '2.5%',\n        frameRound: true,\n    },\n    thumb: '<rect stroke-width=\"5\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" rx=\"12%\"/>',\n};\nconst lineSingle = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'line',\n        frameInset: '2.5%',\n        frameSize: '.3125%',\n        frameRadius: 0,\n    },\n    thumb: [\n        createDivThumb('top:.5em;left:.5em;right:.5em;bottom:.5em;box-shadow:inset 0 0 0 1px currentColor'),\n    ],\n};\nconst lineMultiple = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'line',\n        frameAmount: 2,\n        frameInset: '2.5%',\n        frameSize: '.3125%',\n        frameOffset: '1.25%',\n        frameRadius: 0,\n    },\n    thumb: [createDivThumb('top:.75em;left:.75em;right:.75em;bottom:.75em; outline: 3px double')],\n};\nconst edgeSeparate = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'edge',\n        frameInset: '2.5%',\n        frameOffset: '5%',\n        frameSize: '.3125%',\n    },\n    thumb: [\n        createDivThumb('top:.75em;left:.5em;bottom:.75em;border-left:1px solid', 'a'),\n        createDivThumb('top:.75em;right:.5em;bottom:.75em;border-right:1px solid', 'b'),\n        createDivThumb('top:.5em;left:.75em;right:.75em;border-top:1px solid', 'c'),\n        createDivThumb('bottom:.5em;left:.75em;right:.75em;border-bottom:1px solid', 'd'),\n    ],\n    // `<div style=\"top:.75em;left:.5em;bottom:.75em;border-left:1px solid\"></div>\n    //  <div style=\"top:.75em;right:.5em;bottom:.75em;border-right:1px solid\"></div>\n    //  <div style=\"top:.5em;left:.75em;right:.75em;border-top:1px solid\"></div>\n    //  <div style=\"bottom:.5em;left:.75em;right:.75em;border-bottom:1px solid\"></div>`,\n};\nconst edgeCross = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'edge',\n        frameInset: '2.5%',\n        frameSize: '.3125%',\n    },\n    thumb: [\n        createDivThumb('top:-.5em;left:.5em;right:.5em;bottom:-.5em; box-shadow: inset 0 0 0 1px currentColor', 'a'),\n        createDivThumb('top:.5em;left:-.5em;right:-.5em;bottom:.5em;box-shadow:inset 0 0 0 1px currentColor', 'b'),\n    ],\n};\nconst edgeOverlap = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'edge',\n        frameOffset: '1.5%',\n        frameSize: '.3125%',\n    },\n    thumb: [\n        createDivThumb('top:.3125em;left:.5em;bottom:.3125em;border-left:1px solid', 'a'),\n        createDivThumb('top:.3125em;right:.5em;bottom:.3125em;border-right:1px solid', 'b'),\n        createDivThumb('top:.5em;left:.3125em;right:.3125em;border-top:1px solid', 'c'),\n        createDivThumb('bottom:.5em;left:.3125em;right:.3125em;border-bottom:1px solid', 'd'),\n    ],\n};\nconst hook = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'hook',\n        frameInset: '2.5%',\n        frameSize: '.3125%',\n        frameLength: '5%',\n    },\n    thumb: [\n        createDivThumb('top:.5em;left:.5em;width:.75em;height:.75em; border-left: 1px solid;border-top: 1px solid', 'a'),\n        createDivThumb('top:.5em;right:.5em;width:.75em;height:.75em; border-right: 1px solid;border-top: 1px solid', 'b'),\n        createDivThumb('bottom:.5em;left:.5em;width:.75em;height:.75em; border-left: 1px solid;border-bottom: 1px solid', 'c'),\n        createDivThumb('bottom:.5em;right:.5em;width:.75em;height:.75em; border-right: 1px solid;border-bottom: 1px solid', 'd'),\n    ],\n};\nconst polaroid = {\n    shape: {\n        frameColor: [1, 1, 1],\n        frameStyle: 'polaroid',\n    },\n    thumb: '<rect stroke-width=\"20%\" x=\"-5%\" y=\"-5%\" width=\"110%\" height=\"96%\"/>',\n};\nconst frameStylesDefault = {\n    solidSharp,\n    solidRound,\n    lineSingle,\n    lineMultiple,\n    edgeSeparate,\n    edgeCross,\n    edgeOverlap,\n    hook,\n    polaroid,\n};\nconst frameOptionsDefault = [\n    [undefined, (locale) => locale.labelNone],\n    ['solidSharp', (locale) => locale.frameLabelMatSharp],\n    ['solidRound', (locale) => locale.frameLabelMatRound],\n    ['lineSingle', (locale) => locale.frameLabelLineSingle],\n    ['lineMultiple', (locale) => locale.frameLabelLineMultiple],\n    ['edgeCross', (locale) => locale.frameLabelEdgeCross],\n    ['edgeSeparate', (locale) => locale.frameLabelEdgeSeparate],\n    ['edgeOverlap', (locale) => locale.frameLabelEdgeOverlap],\n    ['hook', (locale) => locale.frameLabelCornerHooks],\n    ['polaroid', (locale) => locale.frameLabelPolaroid],\n];\nvar _plugin_frame_defaults = {\n    frameStyles: frameStylesDefault,\n    frameOptions: frameOptionsDefault,\n};\n\nvar upperCaseFirstLetter = (str) => str.charAt(0).toUpperCase() + str.slice(1);\n\nlet result = null;\nvar canCheckFontAvailability = () => {\n    if (result === null) {\n        if (!isBrowser())\n            result = false;\n        else {\n            try {\n                // if browser can detect font as non existend then it supports font checking (only chrome)\n                // @ts-ignore\n                result = document.fonts.check('16px TestNonExistingFont') === false;\n            }\n            catch (err) {\n                // if throws assume can't check\n                result = false;\n            }\n        }\n    }\n    return result;\n};\n\nconst toLocaleFn = (key, localePrefix) => (locale) => locale[localePrefix ? `${localePrefix}${upperCaseFirstLetter(key)}` : key];\nconst mapToSizeOption = (v) => [v, `${v}`];\nconst createLocaleMapper = (options, localePrefix) => (key) => [options[key], toLocaleFn(key, localePrefix)];\nconst autoFormatNumberItems = (arr) => arr.map(mapToSizeOption);\nconst maybeAutoFormatNumberItems = (items) => {\n    if (Array.isArray(items) && items.every(isNumber)) {\n        return autoFormatNumberItems(items);\n    }\n    return items;\n};\nconst toolColorDefault = [1, 0.2549, 0.2118];\nconst toolStrokeWidthDefault = '0.5%';\nconst toolStrokeColorDefault = [1, 1, 1, 0];\n//#region selection\nconst SELECTION_TOOL_DEFAULTS = {\n    brush: [\n        'path',\n        {\n            bitmap: true,\n            drawMode: 'add', // default is add\n            strokeWidth: '5%',\n            // cursor is circle\n            cursorStyle: 'ellipse',\n            cursorSize: 'strokeWidth',\n            // can't adjust color\n            disableStyle: ['strokeColor'],\n            // use brush size control\n            settings: {\n                strokeWidth: {\n                    control: 'brushSize',\n                },\n            },\n        },\n    ],\n    lassoo: [\n        'path',\n        {\n            drawMode: 'add',\n            disableStyle: ['strokeWidth', 'strokeColor'],\n            strokeWidth: '.25%',\n            pathClose: true,\n        },\n    ],\n    polygon: [\n        'path',\n        {\n            drawMode: 'add',\n            disableStyle: ['strokeWidth', 'strokeColor'],\n            strokeWidth: '.25%',\n            pathClose: true,\n        },\n        {\n            inputMode: 'step',\n        },\n    ],\n    rectangle: [\n        'rectangle',\n        {\n            disableStyle: ['backgroundColor', 'strokeWidth', 'strokeColor', 'cornerRadius'],\n            drawMode: 'add',\n        },\n    ],\n    ellipse: [\n        'ellipse',\n        {\n            disableStyle: ['backgroundColor', 'strokeWidth', 'strokeColor'],\n            drawMode: 'add',\n        },\n    ],\n};\nconst SELECTION_TOOL_DEFAULT_LIST = ['brush', 'lassoo', 'polygon', 'rectangle', 'ellipse'];\nconst createSelectionToolStyles = (action, options) => {\n    const { tools = SELECTION_TOOL_DEFAULT_LIST } = options || {};\n    const res = tools.reduce((res, tool) => {\n        const [shape, style, options] = SELECTION_TOOL_DEFAULTS[tool];\n        const toolStyle = createToolStyle(shape, { ...style, action }, {\n            ...options,\n            position: 'absolute',\n            isSelection: true,\n        });\n        return Object.assign(res, {\n            [`selection-${tool}-${action}`]: toolStyle,\n        });\n    }, {});\n    return res;\n};\nconst createSelectionTools = (action, options) => {\n    const { tools = SELECTION_TOOL_DEFAULT_LIST, hideLabel = true } = options || {};\n    return tools.map((tool) => {\n        return [\n            `selection-${tool}-${action}`,\n            toLocaleFn(tool, 'shapeLabelToolSelection'),\n            {\n                hideLabel,\n                icon: toLocaleFn(tool, 'shapeIconToolSelection'),\n            },\n        ];\n    });\n};\nconst createSelectionModeControl = (options) => {\n    const { hideLabel = true } = options || {};\n    return createOptionControl(['new', 'add', 'subtract'].map((key) => [\n        key,\n        toLocaleFn(key, 'shapeLabelSelectionMode'),\n        { icon: toLocaleFn(key, 'shapeIconSelectionMode'), hideLabel },\n    ]), {\n        title: (locale) => locale.shapeTitleSelectionMode,\n        layout: 'radio',\n    });\n};\nconst createBrushSizeControl = (items) => createStrokeWidthControl(items, {\n    title: (locale) => locale.shapeTitleBrushSize,\n    layout: 'radio',\n    optionHideLabel: true,\n    optionIcon: (_, fraction) => `<circle fill=\"currentColor\" stroke-width=\".05em\" stroke=\"currentColor\" fill-opacity=\".25\" cx=\"12\" cy=\"12\" r=\"${2 + fraction * 8}\"/>`,\n});\n//#endregion\n//#region tools\nconst toolShapeDefaults = {\n    eraser: () => ({\n        eraseRadius: 8,\n        cursorStyle: 'ellipse',\n        cursorSize: 'eraseRadius',\n    }),\n    path: () => ({\n        points: [],\n        disableAddPoints: false,\n    }),\n    line: () => ({\n        x1: 0,\n        y1: 0,\n        x2: 0,\n        y2: 0,\n        disableErase: false,\n    }),\n    rectangle: () => ({\n        x: 0,\n        y: 0,\n        width: 0,\n        height: 0,\n    }),\n    ellipse: () => ({\n        x: 0,\n        y: 0,\n        rx: 0,\n        ry: 0,\n    }),\n    text: () => ({\n        x: 0,\n        y: 0,\n        text: 'Text',\n        disableTextScale: true,\n    }),\n};\nconst createToolStyle = (type, shape = {}, options) => {\n    if (!toolShapeDefaults[type])\n        return;\n    const { position = 'relative', inputMode = 'drag', isSelection = false, interpolateInput = false, } = options || {};\n    const shapeDef = {\n        ...toolShapeDefaults[type](),\n        ...shape,\n    };\n    return [shapeDef, { position, inputMode, isSelection, interpolateInput }];\n};\nconst createToolStyles = (tools) => {\n    const styles = {\n        sharpie: createToolStyle('path', {\n            bitmap: true,\n            strokeJoin: 'round',\n            strokeCap: 'round',\n            strokeWidth: toolStrokeWidthDefault,\n            strokeColor: [...toolColorDefault],\n            cursorStyle: 'ellipse',\n            cursorSize: 'strokeWidth',\n            disableErase: false,\n            disableResize: true,\n            disableMove: true,\n        }, {\n            interpolateInput: true,\n        }),\n        eraser: createToolStyle('eraser'),\n        path: createToolStyle('path', {\n            pathClose: undefined,\n            strokeWidth: toolStrokeWidthDefault,\n            strokeColor: [...toolColorDefault],\n            backgroundColor: [0, 0, 0, 0],\n        }, {\n            inputMode: 'step',\n        }),\n        line: createToolStyle('line', {\n            strokeColor: [...toolColorDefault],\n            strokeWidth: toolStrokeWidthDefault,\n        }),\n        arrow: createToolStyle('line', {\n            lineStart: 'none',\n            lineEnd: 'arrow-solid',\n            strokeColor: [...toolColorDefault],\n            strokeWidth: toolStrokeWidthDefault,\n        }),\n        rectangle: createToolStyle('rectangle', {\n            strokeColor: [...toolStrokeColorDefault],\n            backgroundColor: [...toolColorDefault],\n        }),\n        ellipse: createToolStyle('ellipse', {\n            strokeColor: [...toolStrokeColorDefault],\n            backgroundColor: [...toolColorDefault],\n        }),\n        text: createToolStyle('text', {\n            color: [...toolColorDefault],\n            fontSize: '2%',\n        }),\n    };\n    // assign new tools\n    tools &&\n        Object.entries(tools).forEach(([toolKey, toolStyle]) => {\n            // is array overrule, old style of override props, but still needed when creating a new tool style\n            if (Array.isArray(toolStyle)) {\n                styles[toolKey] = toolStyle;\n            }\n            // is object merge, easy way to quickly change styles on default tools\n            else if (isObject(toolStyle) && styles[toolKey]) {\n                styles[toolKey] = [\n                    // @ts-ignore\n                    { ...styles[toolKey][0], ...toolStyle },\n                    // default tool options\n                    styles[toolKey][1],\n                ];\n            }\n        });\n    return styles;\n};\n//#endregion\n//#region toolbar\nconst createToolbarItem = (tool, label, props) => [\n    tool,\n    label || toLocaleFn(tool, 'shapeLabelTool'),\n    {\n        icon: toLocaleFn(tool, 'shapeIconTool'),\n        ...props,\n    },\n];\nconst createToolbar = (tools = [\n    'move',\n    'view',\n    'sharpie',\n    'eraser',\n    'path',\n    'line',\n    'arrow',\n    'rectangle',\n    'ellipse',\n    'text',\n    'preset',\n]) => tools\n    .map((tool) => {\n    // default tool definition, assume locale in\n    if (isString(tool))\n        return createToolbarItem(tool);\n    // tool def with propery\n    if (Array.isArray(tool)) {\n        // state update of tool with key in locale object\n        if (isObject(tool[1]))\n            return createToolbarItem(tool[0], undefined, tool[1]);\n        // should be string, string\n        return createToolbarItem(tool[0], tool[1], tool[2]);\n    }\n})\n    .filter(Boolean);\n//#endregion\n//#region style option defaults\nconst createDefaultColorOptions = () => ({\n    transparent: [1, 1, 1, 0],\n    white: [1, 1, 1],\n    silver: [0.8667, 0.8667, 0.8667],\n    gray: [0.6667, 0.6667, 0.6667],\n    black: [0, 0, 0],\n    navy: [0, 0.1216, 0.2471],\n    blue: [0, 0.4549, 0.851],\n    aqua: [0.498, 0.8588, 1],\n    teal: [0.2235, 0.8, 0.8],\n    olive: [0.2392, 0.6, 0.4392],\n    green: [0.1804, 0.8, 0.251],\n    yellow: [1, 0.8627, 0],\n    orange: [1, 0.5216, 0.1059],\n    red: [1, 0.2549, 0.2118],\n    maroon: [0.5216, 0.0784, 0.2941],\n    fuchsia: [0.9412, 0.0706, 0.7451],\n    purple: [0.6941, 0.051, 0.7882],\n});\nconst createDefaultFontSizeOptions = () => [\n    16, 18, 20, 24, 30, 36, 48, 64, 72, 96, 128, 144,\n];\nconst createDefaultLineHeightOptions = createDefaultFontSizeOptions;\nconst createDefaultFontScaleOptions = () => ({\n    extraSmall: '2%',\n    small: '4%',\n    mediumSmall: '8%',\n    medium: '10%',\n    mediumLarge: '15%',\n    large: '20%',\n    extraLarge: '25%',\n});\nconst createDefaultLineHeightScaleOptions = () => ({\n    extraSmall: '40%',\n    small: '60%',\n    mediumSmall: '100%',\n    medium: '120%',\n    mediumLarge: '140%',\n    large: '180%',\n    extraLarge: '220%',\n});\nconst createDefaultStrokeWidthOptions = () => [\n    1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 48, 64,\n];\nconst createDefaultStrokeScaleOptions = () => ({\n    extraSmall: '0.25%',\n    small: '0.5%',\n    mediumSmall: '1%',\n    medium: '1.75%',\n    mediumLarge: '2.5%',\n    large: '3.5%',\n    extraLarge: '5%',\n});\nconst createDefaultLineEndStyleOptions = () => [\n    'bar',\n    'arrow',\n    'arrowSolid',\n    'circle',\n    'circleSolid',\n    'square',\n    'squareSolid',\n];\nconst createDefaultFontFamilyOptions = () => [\n    [`Helvetica, Arial, Verdana, 'Droid Sans', sans-serif`, 'Sans Serif'],\n    [`'Arial Black', 'Avenir-Black', 'Arial Bold'`, 'Black'],\n    [`'Arial Narrow', 'Futura-CondensedMedium'`, 'Narrow'],\n    [`'Trebuchet MS'`, 'Humanist'],\n    [`Georgia, 'Avenir-Black', 'Times New Roman', 'Droid Serif', serif`, 'Serif'],\n    [`Palatino`, 'Old-Style'],\n    [`'Times New Roman', 'TimesNewRomanPSMT'`, 'Transitional'],\n    [`Menlo, Monaco, 'Lucida Console', monospace`, 'Monospaced'],\n    [`'Courier New', monospace`, 'Slab Serif'],\n];\nconst createDefaultTextAlignOptions = () => ['left', 'center', 'right'];\nconst createDefaultFontStyleOptions = () => [\n    ['normal', 'bold'],\n    ['italic', 'normal'],\n    ['italic', 'bold'],\n];\n//#endregion\n//#region style options\nconst createColorOptions = (colors) => Object.keys(colors).map(createLocaleMapper(colors, 'shapeTitleColor'));\nconst createFontSizeOptions = (sizes) => sizes.map(mapToSizeOption);\nconst createFontScaleOptions = (scales) => Object.keys(scales).map(createLocaleMapper(scales, 'labelSize'));\nconst createLineHeightOptions = (sizes) => sizes.map(mapToSizeOption);\nconst createLineHeightScaleOptions = (scales) => Object.keys(scales).map(createLocaleMapper(scales, 'labelSize'));\nconst createStrokeWidthOptions = (sizes) => sizes.map(mapToSizeOption);\nconst createStrokeScaleOptions = (scales) => Object.keys(scales).map(createLocaleMapper(scales, 'labelSize'));\nconst createFontFamilyOptions = (fonts) => [...fonts];\nconst createFontStyleOptions = (styles) => styles.map((style) => [\n    style,\n    (locale) => locale[`shapeLabelFontStyle${style\n        .filter((v) => v !== 'normal')\n        .map(upperCaseFirstLetter)\n        .join('')}`],\n]);\nconst createLineEndStyleOptions = (styles) => styles.map((style) => [\n    toKebabCase(style),\n    (locale) => locale[`shapeTitleLineDecoration${upperCaseFirstLetter(style)}`],\n    { icon: (locale) => locale[`shapeIconLineDecoration${upperCaseFirstLetter(style)}`] },\n]);\nconst createTextAlignOptions = (options) => options.map((align) => [\n    align,\n    (locale) => locale[`shapeTitleTextAlign${upperCaseFirstLetter(align)}`],\n    {\n        hideLabel: true,\n        icon: (locale) => locale[`shapeIconTextAlign${upperCaseFirstLetter(align)}`],\n    },\n]);\nconst createControlOptions = (items, options) => {\n    const { defaultKey, defaultValue, defaultOptions } = options || {};\n    const arr = [];\n    if (defaultKey)\n        arr[0] = [defaultValue, (locale) => locale[defaultKey], { ...defaultOptions }];\n    return [...arr, ...items];\n};\n//#endregion\n//#region shape style controls\nconst someFontsAvailableInStack = (stack) => stack\n    .split(',')\n    .map((name) => name.trim())\n    .some((name) => {\n    return document.fonts.check(`16px ${name}`);\n});\nconst createSliderControl = (options = {}) => [\n    'ToggleSlider',\n    {\n        ...options,\n    },\n];\nconst createOptionsControl = (items, options = {}) => [\n    'Dropdown',\n    { ...options, options: items },\n];\nconst FontTestClass = 'PinturaFontTest';\nconst createFontFamilyControl = (fontFamilies, options = { defaultKey: 'labelDefault' }) => [\n    'Dropdown',\n    {\n        title: (locale) => locale.shapeTitleFontFamily,\n        onload: ({ options = [] }) => {\n            // can't check for font availability so don't try\n            if (!canCheckFontAvailability())\n                return;\n            options\n                // map to font stack (option value)\n                .map(([stack]) => stack)\n                // filter out undefined\n                .filter(Boolean)\n                // filter out fonts that are available\n                .filter((stack) => !someFontsAvailableInStack(stack))\n                // remaining fonts should have dom elements for future check\n                .forEach((stack) => {\n                // get as id\n                const testId = `${FontTestClass}-${stack\n                    .replace(/[^a-zA-Z0-9]+/g, '')\n                    .toLowerCase()}`;\n                // already added this tester\n                if (document.getElementById(testId))\n                    return;\n                // add font tester, this triggers browser to download font\n                document.body.append(h('span', {\n                    textContent: ' ',\n                    id: testId,\n                    class: FontTestClass,\n                    style: `font-family:${stack};font-size:0;color:transparent;`,\n                }));\n            });\n        },\n        ondestroy: () => {\n            // can't check for font availability so no need to clean up\n            if (!canCheckFontAvailability())\n                return;\n            // clean up testers\n            const testers = document.querySelectorAll('.PinturaFontTest');\n            testers.forEach((tester) => tester.remove());\n        },\n        optionLabelStyle: (value) => `font-family: ${value}`,\n        options: createControlOptions(fontFamilies, options),\n        optionFilter: (fontFamilyOption) => {\n            // don't filter if not in browser context\n            if (!canCheckFontAvailability())\n                return true;\n            // get font stack\n            const [stack] = fontFamilyOption;\n            // allow if undefined\n            if (!stack)\n                return true;\n            // filter out fonts that aren't available\n            const res = someFontsAvailableInStack(stack);\n            return res;\n        },\n    },\n];\nconst createColorPickerControl = (items, options = {}) => [\n    'ColorPicker',\n    {\n        options: createControlOptions(items),\n        ...options,\n    },\n];\nconst createColorControl = (items, options = {}) => createColorPickerControl(items, {\n    title: (locale) => locale.labelColor,\n    ...options,\n});\nconst createLabeledColorControl = (key) => {\n    return (items, options = {}) => createColorPickerControl(items, {\n        title: (locale) => locale[key],\n        ...options,\n    });\n};\nconst createBackgroundColorControl = createLabeledColorControl('shapeTitleBackgroundColor');\nconst createFontColorControl = createLabeledColorControl('shapeTitleTextColor');\nconst createStrokeColorControl = (items, options = {}) => createColorPickerControl(items, {\n    title: (locale) => locale.shapeTitleStrokeColor,\n    options: createControlOptions(items),\n    buttonClass: 'PinturaColorPickerButtonStroke',\n    onchange: (value, shape) => {\n        // get shape strokeWidth as number\n        const strokeWidth = shape.strokeWidth;\n        const strokeWidthParsed = isNumber(strokeWidth) || isString(strokeWidth) ? parseFloat(strokeWidth) : 0;\n        // already has outline\n        if (strokeWidthParsed > 0)\n            return;\n        // set outline to first stroke width\n        shape.strokeWidth = (options && options.defaultStrokeWidth) || '0.5%';\n    },\n    ...options,\n});\nconst createStrokeWidthControl = (items, options) => {\n    const { title, optionHideLabel: hideLabel = false, layout, optionIcon = false } = options || {};\n    const formattedItems = maybeAutoFormatNumberItems(items);\n    // get as numbers so we can correctly scale dynamic icons\n    const itemsAsNumbers = items.map(([value]) => (isString(value) ? parseFloat(value) : value));\n    const itemsMaxValue = Math.max(...itemsAsNumbers);\n    const itemsMinValue = Math.min(...itemsAsNumbers);\n    const itemsRange = itemsMaxValue - itemsMinValue;\n    return [\n        layout === 'radio' ? 'RadioGroup' : 'Dropdown',\n        {\n            title: title === false\n                ? undefined\n                : title\n                    ? title\n                    : (locale) => locale.shapeTitleStrokeWidth,\n            options: (shape) => {\n                const mappedItems = options\n                    ? formattedItems.map((item) => {\n                        // @ts-ignore\n                        const [value, label, itemOptions = {}] = item;\n                        const itemValue = isString(value) ? parseFloat(value) : value;\n                        const itemFraction = (itemValue - itemsMinValue) / itemsRange;\n                        let icon = undefined;\n                        if (optionIcon === 'line') {\n                            icon = `<path stroke=\"currentColor\" stroke-linecap=\"square\" stroke-width=\"${0.1 + itemFraction * 0.875}em\" d=\"M3,12 H20\"/>`;\n                        }\n                        else if (optionIcon === 'dot') {\n                            icon = `<circle fill=\"currentColor\" cx=\"12\" cy=\"12\" r=\"${2 + itemFraction * 8}\"/>`;\n                        }\n                        else if (isString(optionIcon)) {\n                            icon = optionIcon;\n                        }\n                        else if (isFunction(optionIcon)) {\n                            icon = optionIcon(itemValue, itemFraction);\n                        }\n                        return [\n                            value,\n                            label,\n                            {\n                                icon,\n                                hideLabel,\n                                ...itemOptions,\n                            },\n                        ];\n                    })\n                    : formattedItems;\n                if (hasProp(shape, 'backgroundColor'))\n                    return createControlOptions(mappedItems, {\n                        defaultKey: 'shapeLabelStrokeNone',\n                    });\n                return createControlOptions(mappedItems);\n            },\n            onchange: (value, shape) => {\n                // no width selected\n                if (!value)\n                    return;\n                // get shape strokeColor\n                const strokeColor = shape.strokeColor || [];\n                // already has visible stroke color or has no stroke color\n                if (strokeColor[3])\n                    return;\n                // duplicate color and assign to shape\n                const color = [...strokeColor];\n                color[3] = 1;\n                shape.strokeColor = color;\n            },\n        },\n    ];\n};\nconst createOptionControl = (items, options) => {\n    const { title, layout } = options || {};\n    return [\n        layout === 'radio' ? 'RadioGroup' : 'Dropdown',\n        {\n            title,\n            options: createControlOptions(items),\n        },\n    ];\n};\nconst createLineControl = (items, titleKey, optionIconStyle) => [\n    'Dropdown',\n    {\n        title: (locale) => locale[titleKey],\n        options: createControlOptions(items, {\n            defaultKey: 'labelNone',\n            defaultOptions: {\n                icon: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H14\"/></g>`,\n            },\n        }),\n        optionIconStyle,\n    },\n];\nconst createLineStartStyleControl = (items) => createLineControl(items, 'shapeTitleLineStart', `transform: scaleX(-1)`);\nconst createLineEndStyleControl = (items) => createLineControl(items, 'shapeTitleLineEnd');\nconst createFontStyleControl = (items) => [\n    'Dropdown',\n    {\n        title: (locale) => locale.shapeTitleFontStyle,\n        optionLabelStyle: (value) => value && `font-style:${value[0]};font-weight:${value[1]}`,\n        options: createControlOptions(items, {\n            defaultKey: 'shapeLabelFontStyleNormal',\n        }),\n    },\n];\nconst createShorthandControl = (options) => ['ShorthandControl', options];\nfunction getPrecision(value) {\n    let e = 1;\n    let digits = 0;\n    while (Math.round(value * e) / e !== value) {\n        e *= 10;\n        digits++;\n        if (digits > 10)\n            break;\n    }\n    return digits;\n}\nfunction isExactNumber(value) {\n    const digits = getPrecision(isString(value) ? parseFloat(value) : value);\n    return digits < 4;\n}\nconst createSizeControl = (items, title, defaultValue, options) => {\n    if (!options && !items.find(([value]) => value === defaultValue)) {\n        options = { defaultKey: 'labelAuto', defaultValue };\n    }\n    const formattedItems = maybeAutoFormatNumberItems(items);\n    const isPercentageItems = formattedItems.some(([value]) => isString(value) && value.endsWith('%'));\n    return [\n        'Dropdown',\n        {\n            title,\n            options: createControlOptions(formattedItems, options),\n            formatValue: (value) => {\n                // test if has lots of digits\n                if (!isExactNumber(value)) {\n                    if (isNumber(value) && !isPercentageItems) {\n                        return Math.floor(value);\n                    }\n                    return `${Math.floor(parseFloat(value))}%`;\n                }\n                return isPercentageItems ? `${parseFloat(value)}%` : value;\n            },\n            ...options,\n        },\n    ];\n};\nconst createFontSizeControl = (items, options) => {\n    // TODO: in future remove default percentage value from this control\n    return createSizeControl(items, (locale) => locale.shapeTitleFontSize, '4%', options);\n};\nconst createLineHeightControl = (items, options) => \n// TODO: in future remove default percentage value from this control\ncreateSizeControl(items, (locale) => locale.shapeTitleLineHeight, '120%', options);\nconst createTextAlignControl = (items) => [\n    'RadioGroup',\n    {\n        title: (locale) => locale.shapeTitleTextAlign,\n        options: createControlOptions(items),\n    },\n];\n// these create default options\nconst DefaultShapeOptionFactories = {\n    colorOptions: () => createColorOptions(createDefaultColorOptions()),\n    lineEndStyleOptions: () => createLineEndStyleOptions(createDefaultLineEndStyleOptions()),\n    fontFamilyOptions: () => createFontFamilyOptions(createDefaultFontFamilyOptions()),\n    fontStyleOptions: () => createFontStyleOptions(createDefaultFontStyleOptions()),\n    textAlignOptions: () => createTextAlignOptions(createDefaultTextAlignOptions()),\n    strokeWidthOptions: () => createStrokeScaleOptions(createDefaultStrokeScaleOptions()),\n    brushSizeOptions: () => createStrokeScaleOptions(Object.entries(createDefaultStrokeScaleOptions()).reduce((res, [key, value]) => {\n        res[key] = `${parseFloat(value) * 2}%`;\n        return res;\n    }, {})),\n    fontSizeOptions: () => createFontScaleOptions(createDefaultFontScaleOptions()),\n    lineHeightOptions: () => createLineHeightScaleOptions(createDefaultLineHeightScaleOptions()),\n};\n// Outline / Shadow sliders\nconst sliderNumberFormatter = new Intl.NumberFormat('default', {\n    minimumFractionDigits: 1,\n    maximumFractionDigits: 1,\n});\nconst setSliderOptionalPercentageValue = (value, inputValue) => {\n    return isString(inputValue) ? `${value}%` : value;\n};\nconst getSliderOptionalPercentageLabel = (value, _, max, inputValue) => {\n    if (isString(inputValue)) {\n        return `${Math.round((value / max) * 100)}%`;\n    }\n    return `${sliderNumberFormatter.format(value)}`;\n};\nconst TextShadowSliderOptions = {\n    getValue: (value) => parseFloat(value),\n    setValue: setSliderOptionalPercentageValue,\n    label: getSliderOptionalPercentageLabel,\n    step: 0.05,\n    labelClass: 'PinturaPercentageLabel',\n};\nconst TextShadowControl = {\n    factory: createShorthandControl,\n    options: {\n        title: 'Text shadow',\n        controls: [\n            [\n                'ToggleSlider',\n                'x',\n                {\n                    ...TextShadowSliderOptions,\n                    min: -100,\n                    max: 100,\n                    labelPrefix: 'X',\n                },\n            ],\n            [\n                'ToggleSlider',\n                'y',\n                {\n                    ...TextShadowSliderOptions,\n                    min: -100,\n                    max: 100,\n                    labelPrefix: 'Y',\n                },\n            ],\n            [\n                'ToggleSlider',\n                'blur',\n                {\n                    ...TextShadowSliderOptions,\n                    min: 0,\n                    max: 25,\n                    labelPrefix: (locale) => locale.shapeTitleTextShadowBlur,\n                },\n            ],\n            [\n                'ColorPicker',\n                'color',\n                {\n                    enablePresets: false,\n                },\n            ],\n        ],\n    },\n};\nconst TextOutlineControl = {\n    factory: createShorthandControl,\n    options: {\n        title: 'Text outline',\n        controls: [\n            [\n                'ToggleSlider',\n                'width',\n                {\n                    getValue: (value) => parseFloat(value),\n                    setValue: setSliderOptionalPercentageValue,\n                    label: getSliderOptionalPercentageLabel,\n                    min: 0,\n                    max: 15,\n                    step: 0.05,\n                    labelClass: 'PinturaPercentageLabel',\n                    labelPrefix: (locale) => locale.shapeTitleTextOutlineWidth,\n                },\n            ],\n            [\n                'ColorPicker',\n                'color',\n                {\n                    enablePresets: false,\n                },\n            ],\n        ],\n    },\n};\nconst DefaultShapeControls = {\n    defaultColor: {\n        factory: createColorControl,\n        items: 'colorOptions',\n    },\n    defaultNumber: { factory: createSliderControl },\n    defaultPercentage: {\n        factory: createSliderControl,\n        options: {\n            getValue: (value) => parseFloat(value),\n            setValue: (value) => `${value}%`,\n            step: 0.05,\n            label: (value, min, max) => `${Math.round((value / max) * 100)}%`,\n            labelClass: 'PinturaPercentageLabel',\n        },\n    },\n    backgroundColor: {\n        items: 'colorOptions',\n        factory: createBackgroundColorControl,\n    },\n    strokeColor: {\n        items: 'colorOptions',\n        factory: createStrokeColorControl,\n    },\n    strokeWidth: {\n        items: 'strokeWidthOptions',\n        factory: createStrokeWidthControl,\n    },\n    brushSize: {\n        items: 'brushSizeOptions',\n        factory: createBrushSizeControl,\n    },\n    drawMode: {\n        factory: createSelectionModeControl,\n    },\n    lineStart: {\n        items: 'lineEndStyleOptions',\n        factory: createLineStartStyleControl,\n    },\n    lineEnd: {\n        items: 'lineEndStyleOptions',\n        factory: createLineEndStyleControl,\n    },\n    color: {\n        items: 'colorOptions',\n        factory: createFontColorControl,\n    },\n    fontFamily: {\n        items: 'fontFamilyOptions',\n        factory: createFontFamilyControl,\n    },\n    fontStyle_fontWeight: {\n        items: 'fontStyleOptions',\n        factory: createFontStyleControl,\n    },\n    fontSize: {\n        items: 'fontSizeOptions',\n        factory: createFontSizeControl,\n    },\n    lineHeight: {\n        items: 'lineHeightOptions',\n        factory: createLineHeightControl,\n    },\n    textAlign: {\n        items: 'textAlignOptions',\n        factory: createTextAlignControl,\n    },\n    textShadowX_textShadowY_textShadowBlur_textShadowColor: TextShadowControl,\n    textOutlineWidth_textOutlineColor: TextOutlineControl,\n    cornerRadius: {\n        factory: 'defaultPercentage',\n        options: {\n            min: 0,\n            max: 50,\n            title: (locale) => locale.shapeTitleCornerRadius,\n        },\n    },\n    frameColor: {\n        factory: 'defaultColor',\n    },\n    frameSize: {\n        factory: 'defaultPercentage',\n        options: {\n            min: 0.2,\n            max: 10,\n            title: (locale) => locale.labelSize,\n        },\n    },\n    frameInset: {\n        factory: 'defaultPercentage',\n        options: { min: 0.5, max: 10, title: (locale) => locale.labelOffset },\n    },\n    frameOffset: {\n        factory: 'defaultPercentage',\n        options: { min: 0.5, max: 10, title: (locale) => locale.labelOffset },\n    },\n    frameRadius: {\n        factory: 'defaultPercentage',\n        options: { min: 0.5, max: 10, title: (locale) => locale.labelRadius },\n    },\n    frameAmount: {\n        factory: 'defaultNumber',\n        options: { min: 1, max: 5, step: 1, title: (locale) => locale.labelAmount },\n    },\n};\nconst createShapeStyleControls = (options = {}) => {\n    // default controls\n    const input = {\n        ...DefaultShapeControls,\n        ...options,\n    };\n    // resulting controls\n    const output = {};\n    // assign custom entries (eraseRadius), maybe expand in future to assign all items this way\n    Object.entries(input).forEach(([key, value]) => {\n        // skip options shorthand\n        if (/Options$/.test(key))\n            return;\n        // is control\n        if (DefaultShapeControls[key] && isObject(value) && !isArray(value)) {\n            const { component, factory, items, options = {} } = input[key];\n            // this is a reference to another component\n            if (isString(factory)) {\n                output[key] = [factory, options];\n            }\n            // this is a factory or custom component\n            else {\n                // get default items key\n                const defaultItems = DefaultShapeControls[key].items;\n                let factoryItems = isString(defaultItems)\n                    ? input[defaultItems] || DefaultShapeOptionFactories[defaultItems]()\n                    : undefined;\n                if (isString(items) && DefaultShapeOptionFactories[items]) {\n                    if (input[items]) {\n                        if (input[items].every((item) => !Array.isArray(item))) {\n                            factoryItems = input[items].map((item) => [item, item]);\n                        }\n                        else {\n                            factoryItems = input[items];\n                        }\n                    }\n                    else {\n                        factoryItems = DefaultShapeOptionFactories[items]();\n                    }\n                }\n                // else override with custom items\n                else if (items || options.items) {\n                    factoryItems = items || options.items;\n                }\n                // fallback to default factory if not supplied\n                let factoryFn = factory || DefaultShapeControls[key].factory;\n                // is default factory\n                if (isFunction(factoryFn)) {\n                    output[key] = factoryItems\n                        ? factoryFn(factoryItems, options)\n                        : factoryFn(options);\n                }\n                // use custom component\n                else if (component) {\n                    output[key] = [\n                        component,\n                        {\n                            ...options,\n                            items,\n                        },\n                    ];\n                }\n            }\n        }\n        else {\n            output[key] = value;\n        }\n    });\n    return output;\n};\n//#endregion\n\n/* src/core/ui/components/Toolbar.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$r(ctx) {\n\tlet div1;\n\tlet div0;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[7].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[6], null);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv1 = element(\"div\");\n\t\t\tdiv0 = element(\"div\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tattr(div0, \"class\", \"PinturaToolbarInner\");\n\t\t\tattr(div1, \"class\", \"PinturaToolbar\");\n\t\t\tattr(div1, \"data-layout\", /*layout*/ ctx[1]);\n\t\t\tattr(div1, \"data-overflow\", /*overflow*/ ctx[0]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div1, anchor);\n\t\t\tappend(div1, div0);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(div0, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div0, \"measure\", /*handleChildResizeEvent*/ ctx[3]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div0)),\n\t\t\t\t\tlisten(div1, \"measure\", /*handleParentResizeEvent*/ ctx[2]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div1))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope*/ 64)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[6],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[6])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[6], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*layout*/ 2) {\n\t\t\t\tattr(div1, \"data-layout\", /*layout*/ ctx[1]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*overflow*/ 1) {\n\t\t\t\tattr(div1, \"data-overflow\", /*overflow*/ ctx[0]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div1);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$r($$self, $$props, $$invalidate) {\n\tlet layout;\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet childWidth = 0;\n\tlet childMaxWidth = 0;\n\tlet parentWidth = 0;\n\tlet overflow;\n\n\tconst testOverflow = () => {\n\t\t$$invalidate(0, overflow = layout === 'compact' && childWidth > parentWidth\n\t\t? 'overflow'\n\t\t: undefined);\n\t};\n\n\tconst handleParentResizeEvent = ({ detail }) => {\n\t\tconst { width } = detail;\n\t\t$$invalidate(5, parentWidth = width);\n\t\ttestOverflow();\n\t};\n\n\tconst handleChildResizeEvent = ({ detail }) => {\n\t\tconst { width } = detail;\n\n\t\tif (width > childMaxWidth) {\n\t\t\t$$invalidate(4, childMaxWidth = width);\n\t\t}\n\n\t\tchildWidth = width;\n\t\tif (!overflow) testOverflow();\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('$$scope' in $$props) $$invalidate(6, $$scope = $$props.$$scope);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*childMaxWidth, parentWidth*/ 48) {\n\t\t\t$$invalidate(1, layout = childMaxWidth > parentWidth ? 'compact' : 'default');\n\t\t}\n\t};\n\n\treturn [\n\t\toverflow,\n\t\tlayout,\n\t\thandleParentResizeEvent,\n\t\thandleChildResizeEvent,\n\t\tchildMaxWidth,\n\t\tparentWidth,\n\t\t$$scope,\n\t\tslots\n\t];\n}\n\nclass Toolbar extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$r, create_fragment$r, safe_not_equal, {});\n\t}\n}\n\n/* src/core/ui/components/Measure.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$q(ctx) {\n\tlet div;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tconst default_slot_template = /*#slots*/ ctx[5].default;\n\tconst default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[4], null);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (default_slot) default_slot.c();\n\t\t\tattr(div, \"class\", /*klass*/ ctx[0]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (default_slot) {\n\t\t\t\tdefault_slot.m(div, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"measure\", function () {\n\t\t\t\t\t\tif (is_function(/*didMount*/ ctx[1] && /*handleResize*/ ctx[3])) (/*didMount*/ ctx[1] && /*handleResize*/ ctx[3]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(/*measurable*/ ctx[2].call(null, div))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, [dirty]) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (default_slot) {\n\t\t\t\tif (default_slot.p && (!current || dirty & /*$$scope*/ 16)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tdefault_slot,\n\t\t\t\t\t\tdefault_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[4],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[4])\n\t\t\t\t\t\t: get_slot_changes(default_slot_template, /*$$scope*/ ctx[4], dirty, null),\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*klass*/ 1) {\n\t\t\t\tattr(div, \"class\", /*klass*/ ctx[0]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(default_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(default_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (default_slot) default_slot.d(detaching);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$q($$self, $$props, $$invalidate) {\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tconst dispatch = createEventDispatcher();\n\tlet { class: klass = null } = $$props;\n\n\t// context\n\tconst measurable = getContext('measurable');\n\n\tlet didMount = false;\n\tconst handleResize = ({ detail }) => dispatch('measure', detail);\n\tonMount(() => $$invalidate(1, didMount = true));\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(0, klass = $$props.class);\n\t\tif ('$$scope' in $$props) $$invalidate(4, $$scope = $$props.$$scope);\n\t};\n\n\treturn [klass, didMount, measurable, handleResize, $$scope, slots];\n}\n\nclass Measure extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$q, create_fragment$q, safe_not_equal, { class: 0 });\n\t}\n}\n\n/* src/core/ui/components/Util.svelte generated by Svelte v4.2.20 */\nconst get_footer_slot_changes = dirty => ({});\nconst get_footer_slot_context = ctx => ({});\nconst get_main_slot_changes = dirty => ({});\nconst get_main_slot_context = ctx => ({});\nconst get_header_slot_changes = dirty => ({});\nconst get_header_slot_context = ctx => ({});\n\n// (10:0) {#if hasHeader}\nfunction create_if_block_2$6(ctx) {\n\tlet div;\n\tlet current;\n\tconst header_slot_template = /*#slots*/ ctx[4].header;\n\tconst header_slot = create_slot(header_slot_template, ctx, /*$$scope*/ ctx[3], get_header_slot_context);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (header_slot) header_slot.c();\n\t\t\tattr(div, \"class\", \"PinturaUtilHeader\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (header_slot) {\n\t\t\t\theader_slot.m(div, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (header_slot) {\n\t\t\t\tif (header_slot.p && (!current || dirty & /*$$scope*/ 8)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\theader_slot,\n\t\t\t\t\t\theader_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[3],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[3])\n\t\t\t\t\t\t: get_slot_changes(header_slot_template, /*$$scope*/ ctx[3], dirty, get_header_slot_changes),\n\t\t\t\t\t\tget_header_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(header_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(header_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (header_slot) header_slot.d(detaching);\n\t\t}\n\t};\n}\n\n// (17:22) <Measure class=\"PinturaStage\" on:measure />\nfunction fallback_block(ctx) {\n\tlet measure;\n\tlet current;\n\tmeasure = new Measure({ props: { class: \"PinturaStage\" } });\n\tmeasure.$on(\"measure\", /*measure_handler*/ ctx[5]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(measure.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(measure, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp: noop,\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(measure.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(measure.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(measure, detaching);\n\t\t}\n\t};\n}\n\n// (20:0) {#if hasFooter}\nfunction create_if_block_1$6(ctx) {\n\tlet div;\n\tlet current;\n\tconst footer_slot_template = /*#slots*/ ctx[4].footer;\n\tconst footer_slot = create_slot(footer_slot_template, ctx, /*$$scope*/ ctx[3], get_footer_slot_context);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (footer_slot) footer_slot.c();\n\t\t\tattr(div, \"class\", \"PinturaUtilFooter\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (footer_slot) {\n\t\t\t\tfooter_slot.m(div, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (footer_slot) {\n\t\t\t\tif (footer_slot.p && (!current || dirty & /*$$scope*/ 8)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tfooter_slot,\n\t\t\t\t\t\tfooter_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[3],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[3])\n\t\t\t\t\t\t: get_slot_changes(footer_slot_template, /*$$scope*/ ctx[3], dirty, get_footer_slot_changes),\n\t\t\t\t\t\tget_footer_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(footer_slot, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(footer_slot, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (footer_slot) footer_slot.d(detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$p(ctx) {\n\tlet t0;\n\tlet div;\n\tlet t1;\n\tlet t2;\n\tlet if_block2_anchor;\n\tlet current;\n\tlet if_block0 = /*hasHeader*/ ctx[1] && create_if_block_2$6(ctx);\n\tconst main_slot_template = /*#slots*/ ctx[4].main;\n\tconst main_slot = create_slot(main_slot_template, ctx, /*$$scope*/ ctx[3], get_main_slot_context);\n\tconst main_slot_or_fallback = main_slot || fallback_block(ctx);\n\tlet if_block1 = /*hasFooter*/ ctx[2] && create_if_block_1$6(ctx);\n\tlet if_block2 = false ;\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tdiv = element(\"div\");\n\t\t\tif (main_slot_or_fallback) main_slot_or_fallback.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt2 = space();\n\t\t\tif_block2_anchor = empty();\n\t\t\tattr(div, \"class\", \"PinturaUtilMain\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t0, anchor);\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (main_slot_or_fallback) {\n\t\t\t\tmain_slot_or_fallback.m(div, null);\n\t\t\t}\n\n\t\t\t/*div_binding*/ ctx[6](div);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, t2, anchor);\n\t\t\tinsert(target, if_block2_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (/*hasHeader*/ ctx[1]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*hasHeader*/ 2) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_2$6(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t0.parentNode, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (main_slot) {\n\t\t\t\tif (main_slot.p && (!current || dirty & /*$$scope*/ 8)) {\n\t\t\t\t\tupdate_slot_base(\n\t\t\t\t\t\tmain_slot,\n\t\t\t\t\t\tmain_slot_template,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t/*$$scope*/ ctx[3],\n\t\t\t\t\t\t!current\n\t\t\t\t\t\t? get_all_dirty_from_scope(/*$$scope*/ ctx[3])\n\t\t\t\t\t\t: get_slot_changes(main_slot_template, /*$$scope*/ ctx[3], dirty, get_main_slot_changes),\n\t\t\t\t\t\tget_main_slot_context\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (/*hasFooter*/ ctx[2]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*hasFooter*/ 4) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_1$6(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(t2.parentNode, t2);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(main_slot_or_fallback, local);\n\t\t\ttransition_in(if_block1);\n\t\t\ttransition_in(if_block2);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(main_slot_or_fallback, local);\n\t\t\ttransition_out(if_block1);\n\t\t\ttransition_out(if_block2);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(div);\n\t\t\t\tdetach(t1);\n\t\t\t\tdetach(t2);\n\t\t\t\tdetach(if_block2_anchor);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (main_slot_or_fallback) main_slot_or_fallback.d(detaching);\n\t\t\t/*div_binding*/ ctx[6](null);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance$p($$self, $$props, $$invalidate) {\n\tlet { $$slots: slots = {}, $$scope } = $$props;\n\tlet { hasHeader = !!$$props.$$slots.header } = $$props;\n\tlet { hasFooter = !!$$props.$$slots.footer } = $$props;\n\tlet { root = undefined } = $$props;\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\troot = $$value;\n\t\t\t$$invalidate(0, root);\n\t\t});\n\t}\n\n\t$$self.$$set = $$new_props => {\n\t\t$$invalidate(7, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props)));\n\t\tif ('hasHeader' in $$new_props) $$invalidate(1, hasHeader = $$new_props.hasHeader);\n\t\tif ('hasFooter' in $$new_props) $$invalidate(2, hasFooter = $$new_props.hasFooter);\n\t\tif ('root' in $$new_props) $$invalidate(0, root = $$new_props.root);\n\t\tif ('$$scope' in $$new_props) $$invalidate(3, $$scope = $$new_props.$$scope);\n\t};\n\n\t$$props = exclude_internal_props($$props);\n\treturn [root, hasHeader, hasFooter, $$scope, slots, measure_handler, div_binding];\n}\n\nclass Util extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\t\tinit(this, options, instance$p, create_fragment$p, safe_not_equal, { hasHeader: 1, hasFooter: 2, root: 0 });\n\t}\n}\n\n/* src/core/ui/components/RangeInput.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block$a(ctx) {\n\tlet div;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"class\", \"PinturaRangeInputMeter\");\n\t\t\tset_style(div, \"transform\", `translateX(${/*$position*/ ctx[10].x - /*svgPadding*/ ctx[13].x}px) translateY(${/*$position*/ ctx[10].y - /*svgPadding*/ ctx[13].y}px)`);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tdiv.innerHTML = /*svg*/ ctx[7];\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*svg*/ 128) div.innerHTML = /*svg*/ ctx[7];\n\t\t\tif (dirty[0] & /*$position*/ 1024) {\n\t\t\t\tset_style(div, \"transform\", `translateX(${/*$position*/ ctx[10].x - /*svgPadding*/ ctx[13].x}px) translateY(${/*$position*/ ctx[10].y - /*svgPadding*/ ctx[13].y}px)`);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction create_fragment$o(ctx) {\n\tlet div1;\n\tlet span;\n\tlet t0;\n\tlet button;\n\tlet t1;\n\tlet button_disabled_value;\n\tlet t2;\n\tlet div0;\n\tlet interactable_action;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block = /*$position*/ ctx[10] && create_if_block$a(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv1 = element(\"div\");\n\t\t\tspan = element(\"span\");\n\t\t\tt0 = space();\n\t\t\tbutton = element(\"button\");\n\t\t\tt1 = text(/*labelReset*/ ctx[1]);\n\t\t\tt2 = space();\n\t\t\tdiv0 = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(span, \"class\", \"PinturaRangeInputValue\");\n\t\t\tattr(button, \"class\", \"PinturaRangeInputReset\");\n\t\t\tattr(button, \"type\", \"button\");\n\t\t\tbutton.disabled = button_disabled_value = /*value*/ ctx[0] === /*base*/ ctx[2];\n\t\t\tattr(div0, \"class\", \"PinturaRangeInputInner\");\n\t\t\tattr(div0, \"data-value-limited\", /*isLimited*/ ctx[5]);\n\t\t\tset_style(div0, \"--range-mask-from\", /*styleRangeMaskFrom*/ ctx[9]);\n\t\t\tset_style(div0, \"--range-mask-to\", /*styleRangeMaskTo*/ ctx[8]);\n\t\t\tattr(div1, \"class\", \"PinturaRangeInput\");\n\t\t\tattr(div1, \"tabindex\", \"0\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div1, anchor);\n\t\t\tappend(div1, span);\n\t\t\tspan.innerHTML = /*valueLabel*/ ctx[3];\n\t\t\tappend(div1, t0);\n\t\t\tappend(div1, button);\n\t\t\tappend(button, t1);\n\t\t\tappend(div1, t2);\n\t\t\tappend(div1, div0);\n\t\t\tif (if_block) if_block.m(div0, null);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(button, \"click\", /*handleReset*/ ctx[18]),\n\t\t\t\t\tlisten(div0, \"interactionstart\", /*handleDragStart*/ ctx[14]),\n\t\t\t\t\tlisten(div0, \"interactionupdate\", /*handleDragMove*/ ctx[16]),\n\t\t\t\t\tlisten(div0, \"interactionend\", /*handleDragEnd*/ ctx[17]),\n\t\t\t\t\tlisten(div0, \"interactionrelease\", /*handleDragRelease*/ ctx[15]),\n\t\t\t\t\taction_destroyer(interactable_action = interactable.call(null, div0, { inertia: /*$isAnimated*/ ctx[6] })),\n\t\t\t\t\tlisten(div0, \"measure\", /*measure_handler*/ ctx[39]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div0)),\n\t\t\t\t\tlisten(div1, \"wheel\", /*handleWheel*/ ctx[20], { passive: false }),\n\t\t\t\t\tlisten(div1, \"nudge\", /*handleNudge*/ ctx[21]),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, div1, {\n\t\t\t\t\t\tdirection: 'horizontal',\n\t\t\t\t\t\tpreventDefault: true\n\t\t\t\t\t}))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*valueLabel*/ 8) span.innerHTML = /*valueLabel*/ ctx[3];\t\t\tif (dirty[0] & /*labelReset*/ 2) set_data(t1, /*labelReset*/ ctx[1]);\n\n\t\t\tif (dirty[0] & /*value, base*/ 5 && button_disabled_value !== (button_disabled_value = /*value*/ ctx[0] === /*base*/ ctx[2])) {\n\t\t\t\tbutton.disabled = button_disabled_value;\n\t\t\t}\n\n\t\t\tif (/*$position*/ ctx[10]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$a(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(div0, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*isLimited*/ 32) {\n\t\t\t\tattr(div0, \"data-value-limited\", /*isLimited*/ ctx[5]);\n\t\t\t}\n\n\t\t\tif (interactable_action && is_function(interactable_action.update) && dirty[0] & /*$isAnimated*/ 64) interactable_action.update.call(null, { inertia: /*$isAnimated*/ ctx[6] });\n\n\t\t\tif (dirty[0] & /*styleRangeMaskFrom*/ 512) {\n\t\t\t\tset_style(div0, \"--range-mask-from\", /*styleRangeMaskFrom*/ ctx[9]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleRangeMaskTo*/ 256) {\n\t\t\t\tset_style(div0, \"--range-mask-to\", /*styleRangeMaskTo*/ ctx[8]);\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div1);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nconst radiusBig = 2; // 2\nconst radiusSmall = 0.75; // .75\nconst indicatorSpacing = 10;\nconst indicatorInterval = 5;\nconst indicatorCount = 40; // must be even\n\nfunction instance$o($$self, $$props, $$invalidate) {\n\tlet range;\n\tlet valueMinLimited;\n\tlet valueMaxLimited;\n\tlet barSize;\n\tlet baseFraction;\n\tlet isLimited;\n\tlet rangeMask;\n\tlet styleRangeMaskFrom;\n\tlet styleRangeMaskTo;\n\tlet $isAnimated;\n\tlet $fixScrollDirectionStore;\n\tlet $position;\n\tlet { labelReset = 'Reset' } = $$props;\n\tlet { direction = 'x' } = $$props;\n\tlet { min = 0 } = $$props;\n\tlet { max = 1 } = $$props;\n\tlet { base = min } = $$props;\n\tlet { value = 0 } = $$props;\n\tlet { valueLabel = 0 } = $$props;\n\tlet { valueMin = undefined } = $$props;\n\tlet { valueMax = undefined } = $$props;\n\tlet { oninputstart = noop$1 } = $$props;\n\tlet { oninputmove = noop$1 } = $$props;\n\tlet { oninputend = noop$1 } = $$props;\n\tlet { elasticity = 0 } = $$props;\n\tlet { nudgeMultiplier = undefined } = $$props;\n\tlet { step = 8 } = $$props;\n\n\t//\n\t// context\n\t//\n\tconst isAnimated = getContext('isAnimated');\n\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(6, $isAnimated = value));\n\tconst fixScrollDirectionStore = getContext('fixScrollDirection');\n\tcomponent_subscribe($$self, fixScrollDirectionStore, value => $$invalidate(45, $fixScrollDirectionStore = value));\n\tconst round = (number, increment, offset) => Math.ceil((number - offset) / increment) * increment + offset;\n\tlet size;\n\tlet svg;\n\tlet svgSize;\n\tconst svgPadding = { x: 2, y: 0 };\n\tconst createPathCircle = (cx, cy, r) => `M ${cx - r} ${cy} a ${r} ${r} 0 1 0 0 -1`;\n\n\tfunction getMask(limitedMin, limitedMax) {\n\t\tconst step = 1 / indicatorCount;\n\t\tconst from = toFraction(limitedMin, min, max);\n\t\tconst to = toFraction(limitedMax, min, max);\n\t\tconst fromSnapped = fixPrecision(round(from, step, 0) - step * 0.5);\n\t\tconst toSnapped = fixPrecision(round(to, step, 0) - step * 0.5);\n\t\treturn [`${fromSnapped * 100}%`, `${toSnapped * 100}%`];\n\t} // return `--range-mask-from:${fromSnapped * 100}%;--range-mask-to:${toSnapped * 100}%`;\n\n\t//\n\t// Dragging related\n\t//\n\tlet interactionOrigin = undefined;\n\n\tlet interactionReleased = false;\n\tlet interactionRange;\n\tlet interactionOptions = { snap: false, elastic: false };\n\n\tconst handleDragStart = () => {\n\t\tinteractionReleased = false;\n\t\tinteractionOrigin = get_store_value(position);\n\n\t\tinteractionRange = [\n\t\t\tvalueToPosition(valueMin != null ? valueMin : min, direction),\n\t\t\tvalueToPosition(valueMax != null ? valueMax : max, direction)\n\t\t];\n\n\t\toninputstart();\n\t};\n\n\tconst handleDragRelease = () => {\n\t\tinteractionReleased = true;\n\t};\n\n\tconst handleDragMove = ({ detail }) => {\n\t\tinteractionOptions.snap = !interactionReleased;\n\t\tinteractionOptions.elastic = !interactionReleased;\n\t\ttranslatePosition(interactionOrigin, detail.translation, interactionOptions);\n\t};\n\n\tconst handleDragEnd = ({ detail }) => {\n\t\tinteractionOptions.snap = false;\n\t\tinteractionOptions.elastic = false;\n\t\tconst valueAtPosition = translatePosition(interactionOrigin, detail.translation, interactionOptions);\n\t\tinteractionOrigin = undefined;\n\t\tinteractionRange = undefined;\n\n\t\t// if is near base position, set to base\n\t\tif (Math.abs(valueAtPosition - base) < 0.01) return oninputend(base);\n\n\t\toninputend(valueAtPosition);\n\t};\n\n\tconst translatePosition = (origin, translation, options) => {\n\t\tconst target = origin[direction] + translation[direction];\n\t\tconst targetLimited = clamp(target, interactionRange[1][direction], interactionRange[0][direction]);\n\n\t\tconst targetElastic = elasticity\n\t\t? targetLimited + elastify(target - targetLimited, elasticity)\n\t\t: targetLimited;\n\n\t\tconst targetVisual = options.elastic ? targetElastic : targetLimited;\n\n\t\t// set position\n\t\tconst targetValid = vectorCreate(0, 0);\n\n\t\ttargetValid[direction] = targetVisual;\n\t\tposition.set(targetValid, { hard: options.snap });\n\t\treturn clamp(positionToValue(targetValid, direction), min, max);\n\t};\n\n\tconst handleReset = () => {\n\t\t$$invalidate(0, value = clamp(base, valueMinLimited, valueMaxLimited));\n\t\toninputstart();\n\t\toninputend(value);\n\t};\n\n\t//\n\t// Meter position and value updates\n\t//\n\tconst position = spring();\n\n\tcomponent_subscribe($$self, position, value => $$invalidate(10, $position = value));\n\n\tconst valueToPosition = (value, axis) => {\n\t\tconst offset = (size[axis] - barSize[axis]) * 0.5;\n\t\tconst fraction = toFraction(value, min, max);\n\t\tconst v = fraction * barSize[axis] - barSize[axis] * 0.5;\n\t\tconst pos = offset - v;\n\n\t\treturn {\n\t\t\tx: axis === 'x' ? pos : 0,\n\t\t\ty: axis === 'y' ? pos : 0\n\t\t};\n\t};\n\n\tconst positionToValue = (position, axis) => {\n\t\tconst dist = position[axis] - size[axis] * 0.5;\n\t\tconst fraction = -(dist / barSize[axis]);\n\t\treturn min + fraction * range;\n\t};\n\n\tconst positionUnsub = position.subscribe(currentPosition => {\n\t\t// if not positioned yet or is not interacting we're not interested in this event\n\t\tif (!currentPosition || !interactionOrigin) return;\n\n\t\toninputmove(clamp(positionToValue(currentPosition, direction), min, max));\n\t});\n\n\tconst updatePosition = value => {\n\t\tconst interactionRange = [\n\t\t\tvalueToPosition(valueMin != null ? valueMin : min, direction),\n\t\t\tvalueToPosition(valueMax != null ? valueMax : max, direction)\n\t\t];\n\n\t\tconst target = {\n\t\t\tx: direction === 'x' ? $position.x + value : 0,\n\t\t\ty: direction === 'y' ? $position.y + value : 0\n\t\t};\n\n\t\tconst targetLimited = clamp(target[direction], interactionRange[1][direction], interactionRange[0][direction]);\n\t\tconst positionTarget = { ...$position, [direction]: targetLimited };\n\t\tset_store_value(position, $position = positionTarget, $position);\n\t\tconst result = clamp(positionToValue(positionTarget, direction), min, max);\n\t\toninputstart();\n\t\toninputmove(result);\n\t\toninputend(result);\n\t};\n\n\tconst handleWheel = e => {\n\t\t// don't run default actions, prevent other actions from running\n\t\te.preventDefault();\n\n\t\te.stopPropagation();\n\n\t\t// apply wheel delta to offset\n\t\tconst delta = getWheelDelta(e, {\n\t\t\tfixScrollDirection: $fixScrollDirectionStore\n\t\t}) * step;\n\n\t\tupdatePosition(delta);\n\t};\n\n\tconst handleNudge = ({ detail }) => {\n\t\tupdatePosition(detail[direction] * Math.abs(nudgeMultiplier || 8));\n\t};\n\n\tonDestroy(() => {\n\t\tpositionUnsub();\n\t});\n\n\tconst measure_handler = e => $$invalidate(4, size = vectorCreateFromSize(e.detail));\n\n\t$$self.$$set = $$props => {\n\t\tif ('labelReset' in $$props) $$invalidate(1, labelReset = $$props.labelReset);\n\t\tif ('direction' in $$props) $$invalidate(22, direction = $$props.direction);\n\t\tif ('min' in $$props) $$invalidate(23, min = $$props.min);\n\t\tif ('max' in $$props) $$invalidate(24, max = $$props.max);\n\t\tif ('base' in $$props) $$invalidate(2, base = $$props.base);\n\t\tif ('value' in $$props) $$invalidate(0, value = $$props.value);\n\t\tif ('valueLabel' in $$props) $$invalidate(3, valueLabel = $$props.valueLabel);\n\t\tif ('valueMin' in $$props) $$invalidate(25, valueMin = $$props.valueMin);\n\t\tif ('valueMax' in $$props) $$invalidate(26, valueMax = $$props.valueMax);\n\t\tif ('oninputstart' in $$props) $$invalidate(27, oninputstart = $$props.oninputstart);\n\t\tif ('oninputmove' in $$props) $$invalidate(28, oninputmove = $$props.oninputmove);\n\t\tif ('oninputend' in $$props) $$invalidate(29, oninputend = $$props.oninputend);\n\t\tif ('elasticity' in $$props) $$invalidate(30, elasticity = $$props.elasticity);\n\t\tif ('nudgeMultiplier' in $$props) $$invalidate(31, nudgeMultiplier = $$props.nudgeMultiplier);\n\t\tif ('step' in $$props) $$invalidate(32, step = $$props.step);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*max, min*/ 25165824) {\n\t\t\t//\n\t\t\t// derived\n\t\t\t//\n\t\t\t$$invalidate(34, range = max - min);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*valueMin, min*/ 41943040) {\n\t\t\t$$invalidate(36, valueMinLimited = valueMin != null ? Math.max(valueMin, min) : min);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*valueMax, max*/ 83886080) {\n\t\t\t$$invalidate(35, valueMaxLimited = valueMax != null ? Math.min(valueMax, max) : max);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*base, min, max*/ 25165828) {\n\t\t\t$$invalidate(38, baseFraction = toFraction(base, min, max));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*size*/ 16 | $$self.$$.dirty[1] & /*baseFraction*/ 128) {\n\t\t\tif (size) {\n\t\t\t\tconst centerY = size.y * 0.5;\n\t\t\t\tlet indicatorCenter = indicatorCount * baseFraction;\n\t\t\t\tlet d = '';\n\t\t\t\tlet svgWidth;\n\t\t\t\tlet svgHeight = size.y;\n\t\t\t\tlet centerShape = '';\n\n\t\t\t\tfor (let i = 0; i <= indicatorCount; i++) {\n\t\t\t\t\tconst x = svgPadding.x + i * indicatorSpacing;\n\t\t\t\t\tconst y = centerY;\n\t\t\t\t\tconst r = i % indicatorInterval === 0 ? radiusBig : radiusSmall;\n\t\t\t\t\td += createPathCircle(x, y, r) + ' ';\n\t\t\t\t\tsvgWidth = x + svgPadding.x;\n\n\t\t\t\t\tif (i === indicatorCenter) {\n\t\t\t\t\t\tcenterShape = `<path d=\"M${x} ${y - 4} l2 3 l-2 -1 l-2 1 z\"/>`;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$$invalidate(7, svg = `<svg width=\"${svgWidth}\" height=\"${svgHeight}\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${svgWidth} ${svgHeight}\" aria-hidden=\"true\" focusable=\"false\">\n        ${centerShape}\n        <rect rx=\"4\" ry=\"4\" y=\"${centerY - 4}\"\" height=\"8\"/>\n        <path fill-rule=\"evenodd\" d=\"${d.trim()}\"/></svg>`);\n\n\t\t\t\t$$invalidate(33, svgSize = {\n\t\t\t\t\tx: svgWidth - svgPadding.x * 2,\n\t\t\t\t\ty: svgHeight\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*size*/ 16 | $$self.$$.dirty[1] & /*svgSize*/ 4) {\n\t\t\tbarSize = size && svgSize;\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*min, max*/ 25165824 | $$self.$$.dirty[1] & /*valueMinLimited, valueMaxLimited*/ 48) {\n\t\t\t$$invalidate(5, isLimited = valueMinLimited !== min || valueMaxLimited !== max);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isLimited*/ 32 | $$self.$$.dirty[1] & /*valueMinLimited, valueMaxLimited*/ 48) {\n\t\t\t$$invalidate(37, rangeMask = isLimited\n\t\t\t? getMask(valueMinLimited, valueMaxLimited)\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*rangeMask*/ 64) {\n\t\t\t$$invalidate(9, styleRangeMaskFrom = rangeMask ? rangeMask[0] : '');\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*rangeMask*/ 64) {\n\t\t\t$$invalidate(8, styleRangeMaskTo = rangeMask ? rangeMask[1] : '');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*size, value, direction, $isAnimated*/ 4194385 | $$self.$$.dirty[1] & /*range*/ 8) {\n\t\t\t// if has size (range is in here so the position is updated if the range is changed)\n\t\t\tif (range && size && size.x && size.y) {\n\t\t\t\tposition.set(valueToPosition(value, direction), { hard: $isAnimated === false });\n\t\t\t}\n\t\t}\n\t};\n\n\treturn [\n\t\tvalue,\n\t\tlabelReset,\n\t\tbase,\n\t\tvalueLabel,\n\t\tsize,\n\t\tisLimited,\n\t\t$isAnimated,\n\t\tsvg,\n\t\tstyleRangeMaskTo,\n\t\tstyleRangeMaskFrom,\n\t\t$position,\n\t\tisAnimated,\n\t\tfixScrollDirectionStore,\n\t\tsvgPadding,\n\t\thandleDragStart,\n\t\thandleDragRelease,\n\t\thandleDragMove,\n\t\thandleDragEnd,\n\t\thandleReset,\n\t\tposition,\n\t\thandleWheel,\n\t\thandleNudge,\n\t\tdirection,\n\t\tmin,\n\t\tmax,\n\t\tvalueMin,\n\t\tvalueMax,\n\t\toninputstart,\n\t\toninputmove,\n\t\toninputend,\n\t\telasticity,\n\t\tnudgeMultiplier,\n\t\tstep,\n\t\tsvgSize,\n\t\trange,\n\t\tvalueMaxLimited,\n\t\tvalueMinLimited,\n\t\trangeMask,\n\t\tbaseFraction,\n\t\tmeasure_handler\n\t];\n}\n\nclass RangeInput extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$o,\n\t\t\tcreate_fragment$o,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tlabelReset: 1,\n\t\t\t\tdirection: 22,\n\t\t\t\tmin: 23,\n\t\t\t\tmax: 24,\n\t\t\t\tbase: 2,\n\t\t\t\tvalue: 0,\n\t\t\t\tvalueLabel: 3,\n\t\t\t\tvalueMin: 25,\n\t\t\t\tvalueMax: 26,\n\t\t\t\toninputstart: 27,\n\t\t\t\toninputmove: 28,\n\t\t\t\toninputend: 29,\n\t\t\t\telasticity: 30,\n\t\t\t\tnudgeMultiplier: 31,\n\t\t\t\tstep: 32\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n}\n\nvar DirectionRectMap = {\n    [Top]: (rect) => ({ x: rect.x, y: rect.y }),\n    [TopRight]: (rect) => ({ x: rect.x + rect.width, y: rect.y }),\n    [Right]: (rect) => ({ x: rect.x + rect.width, y: rect.y }),\n    [BottomRight]: (rect) => ({ x: rect.x + rect.width, y: rect.y + rect.height }),\n    [Bottom]: (rect) => ({ x: rect.x, y: rect.y + rect.height }),\n    [BottomLeft]: (rect) => ({ x: rect.x, y: rect.y + rect.height }),\n    [Left]: (rect) => ({ x: rect.x, y: rect.y }),\n    [TopLeft]: (rect) => ({ x: rect.x, y: rect.y }),\n};\n\n// accessibility labels\nconst SliderLabel = {\n    t: 'top',\n    r: 'right',\n    b: 'bottom',\n    l: 'left',\n};\nconst orientationHorizontal = 'horizontal';\nconst orientationVertical = 'vertical';\nconst SliderOrientation = {\n    t: orientationVertical,\n    b: orientationVertical,\n    r: orientationHorizontal,\n    l: orientationHorizontal,\n};\n\n/* src/core/ui/components/RectManipulator.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context$3(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[15] = list[i].key;\n\tchild_ctx[16] = list[i].translate;\n\tchild_ctx[17] = list[i].scale;\n\tchild_ctx[18] = list[i].type;\n\tchild_ctx[19] = list[i].opacity;\n\tchild_ctx[20] = list[i].role;\n\tchild_ctx[21] = list[i].tabindex;\n\tchild_ctx[22] = list[i].label;\n\tchild_ctx[23] = list[i].orientation;\n\tchild_ctx[24] = list[i].valuemin;\n\tchild_ctx[25] = list[i].valuemax;\n\tchild_ctx[26] = list[i].valuenow;\n\treturn child_ctx;\n}\n\n// (152:0) {#each mappedDirections as { key, translate, scale, type, opacity, role, tabindex, label, orientation, valuemin, valuemax, valuenow }\nfunction create_each_block$3(key_2, ctx) {\n\tlet div;\n\tlet div_role_value;\n\tlet div_tabindex_value;\n\tlet div_aria_label_value;\n\tlet div_aria_orientation_value;\n\tlet div_aria_valuemin_value;\n\tlet div_aria_valuemax_value;\n\tlet div_aria_valuenow_value;\n\tlet div_data_direction_value;\n\tlet div_data_shape_value;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tkey: key_2,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"role\", div_role_value = /*role*/ ctx[20]);\n\t\t\tattr(div, \"tabindex\", div_tabindex_value = /*tabindex*/ ctx[21]);\n\t\t\tattr(div, \"aria-label\", div_aria_label_value = /*label*/ ctx[22]);\n\t\t\tattr(div, \"aria-orientation\", div_aria_orientation_value = /*orientation*/ ctx[23]);\n\t\t\tattr(div, \"aria-valuemin\", div_aria_valuemin_value = /*valuemin*/ ctx[24]);\n\t\t\tattr(div, \"aria-valuemax\", div_aria_valuemax_value = /*valuemax*/ ctx[25]);\n\t\t\tattr(div, \"aria-valuenow\", div_aria_valuenow_value = /*valuenow*/ ctx[26]);\n\t\t\tattr(div, \"class\", \"PinturaRectManipulator\");\n\t\t\tattr(div, \"data-direction\", div_data_direction_value = /*key*/ ctx[15]);\n\n\t\t\tattr(div, \"data-shape\", div_data_shape_value = `${/*type*/ ctx[18] === 'edge'\n\t\t\t? 'edge'\n\t\t\t: `${/*cornerStyle*/ ctx[0]}`}`);\n\n\t\t\tset_style(div, \"--tx\", /*translate*/ ctx[16].x);\n\t\t\tset_style(div, \"--ty\", /*translate*/ ctx[16].y);\n\t\t\tset_style(div, \"--sx\", /*scale*/ ctx[17].x);\n\t\t\tset_style(div, \"--sy\", /*scale*/ ctx[17].y);\n\t\t\tset_style(div, \"opacity\", /*opacity*/ ctx[19]);\n\t\t\tthis.first = div;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"nudge\", function () {\n\t\t\t\t\t\tif (is_function(/*nudge*/ ctx[6](/*key*/ ctx[15]))) /*nudge*/ ctx[6](/*key*/ ctx[15]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, div, { preventDefault: true })),\n\t\t\t\t\tlisten(div, \"interactionstart\", function () {\n\t\t\t\t\t\tif (is_function(/*route*/ ctx[5]('resizestart', /*key*/ ctx[15]))) /*route*/ ctx[5]('resizestart', /*key*/ ctx[15]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionupdate\", function () {\n\t\t\t\t\t\tif (is_function(/*route*/ ctx[5]('resizemove', /*key*/ ctx[15]))) /*route*/ ctx[5]('resizemove', /*key*/ ctx[15]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionend\", function () {\n\t\t\t\t\t\tif (is_function(/*route*/ ctx[5]('resizeend', /*key*/ ctx[15]))) /*route*/ ctx[5]('resizeend', /*key*/ ctx[15]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(interactable.call(null, div))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_role_value !== (div_role_value = /*role*/ ctx[20])) {\n\t\t\t\tattr(div, \"role\", div_role_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_tabindex_value !== (div_tabindex_value = /*tabindex*/ ctx[21])) {\n\t\t\t\tattr(div, \"tabindex\", div_tabindex_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_aria_label_value !== (div_aria_label_value = /*label*/ ctx[22])) {\n\t\t\t\tattr(div, \"aria-label\", div_aria_label_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_aria_orientation_value !== (div_aria_orientation_value = /*orientation*/ ctx[23])) {\n\t\t\t\tattr(div, \"aria-orientation\", div_aria_orientation_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_aria_valuemin_value !== (div_aria_valuemin_value = /*valuemin*/ ctx[24])) {\n\t\t\t\tattr(div, \"aria-valuemin\", div_aria_valuemin_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_aria_valuemax_value !== (div_aria_valuemax_value = /*valuemax*/ ctx[25])) {\n\t\t\t\tattr(div, \"aria-valuemax\", div_aria_valuemax_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_aria_valuenow_value !== (div_aria_valuenow_value = /*valuenow*/ ctx[26])) {\n\t\t\t\tattr(div, \"aria-valuenow\", div_aria_valuenow_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2 && div_data_direction_value !== (div_data_direction_value = /*key*/ ctx[15])) {\n\t\t\t\tattr(div, \"data-direction\", div_data_direction_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections, cornerStyle*/ 3 && div_data_shape_value !== (div_data_shape_value = `${/*type*/ ctx[18] === 'edge'\n\t\t\t? 'edge'\n\t\t\t: `${/*cornerStyle*/ ctx[0]}`}`)) {\n\t\t\t\tattr(div, \"data-shape\", div_data_shape_value);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2) {\n\t\t\t\tset_style(div, \"--tx\", /*translate*/ ctx[16].x);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2) {\n\t\t\t\tset_style(div, \"--ty\", /*translate*/ ctx[16].y);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2) {\n\t\t\t\tset_style(div, \"--sx\", /*scale*/ ctx[17].x);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2) {\n\t\t\t\tset_style(div, \"--sy\", /*scale*/ ctx[17].y);\n\t\t\t}\n\n\t\t\tif (dirty & /*mappedDirections*/ 2) {\n\t\t\t\tset_style(div, \"opacity\", /*opacity*/ ctx[19]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$n(ctx) {\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet each_1_anchor;\n\tlet each_value = ensure_array_like(/*mappedDirections*/ ctx[1]);\n\tconst get_key = ctx => /*key*/ ctx[15];\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$3(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$3(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\teach_1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(target, anchor);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinsert(target, each_1_anchor, anchor);\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*mappedDirections, cornerStyle, nudge, route*/ 99) {\n\t\t\t\teach_value = ensure_array_like(/*mappedDirections*/ ctx[1]);\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, each_1_anchor.parentNode, destroy_block, create_each_block$3, each_1_anchor, get_each_context$3);\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(each_1_anchor);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d(detaching);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction instance$n($$self, $$props, $$invalidate) {\n\tlet mappedDirections;\n\tlet $selectionOpacity;\n\tlet $selectionScale;\n\tlet $isAnimated;\n\tlet { rect = null } = $$props;\n\tlet { bounds = null } = $$props;\n\tlet { visible = false } = $$props;\n\tlet { cornerStyle = undefined } = $$props;\n\n\t// contex\n\tconst isAnimated = getContext('isAnimated');\n\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(12, $isAnimated = value));\n\n\t// is `undefined` to prevent bounce when first rendering view\n\tconst selectionScale = spring(undefined, {\n\t\tprecision: 0.0001,\n\t\tstiffness: 0.2,\n\t\tdamping: 0.4\n\t});\n\n\tcomponent_subscribe($$self, selectionScale, value => $$invalidate(11, $selectionScale = value));\n\tconst selectionOpacity = spring(0, { precision: 0.001 });\n\tcomponent_subscribe($$self, selectionOpacity, value => $$invalidate(10, $selectionOpacity = value));\n\n\t//\n\t// dragging\n\t//\n\tlet currentDirection;\n\n\tconst dispatch = createEventDispatcher();\n\n\tconst route = (type, direction) => ({ detail }) => {\n\t\t// don't handle other interactions while manipulating on axis\n\t\tif (currentDirection && direction !== currentDirection) return;\n\n\t\t// ignore move and end events if no direction has been set\n\t\tif (type !== 'resizestart' && currentDirection === undefined) return;\n\n\t\t// set new direction\n\t\tif (type === 'resizestart') currentDirection = direction;\n\n\t\t// release direction\n\t\tif (type === 'resizeend') currentDirection = undefined;\n\n\t\tdispatch(type, {\n\t\t\tdirection,\n\t\t\ttranslation: detail && detail.translation\n\t\t});\n\t};\n\n\tconst nudge = direction => ({ detail }) => {\n\t\tdispatch(`resizestart`, { direction, translation: { x: 0, y: 0 } });\n\t\tdispatch(`resizemove`, { direction, translation: detail });\n\t\tdispatch(`resizeend`, { direction, translation: { x: 0, y: 0 } });\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('rect' in $$props) $$invalidate(7, rect = $$props.rect);\n\t\tif ('bounds' in $$props) $$invalidate(8, bounds = $$props.bounds);\n\t\tif ('visible' in $$props) $$invalidate(9, visible = $$props.visible);\n\t\tif ('cornerStyle' in $$props) $$invalidate(0, cornerStyle = $$props.cornerStyle);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*visible, $isAnimated*/ 4608) {\n\t\t\tselectionScale.set(visible ? 1 : 0.5, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*visible, $isAnimated*/ 4608) {\n\t\t\tselectionOpacity.set(visible ? 1 : 0, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*rect, bounds, $selectionScale, $selectionOpacity*/ 3456) {\n\t\t\t//\n\t\t\t// rendering\n\t\t\t//\n\t\t\t$$invalidate(1, mappedDirections = Object.keys(Direction).map((key, i) => {\n\t\t\t\t// get direction enum\n\t\t\t\tconst direction = Direction[key];\n\n\t\t\t\t// get position from direction\n\t\t\t\tconst position = DirectionRectMap[direction](rect);\n\n\t\t\t\t// corner or edge\n\t\t\t\tconst type = direction.length === 1 ? 'edge' : 'corner';\n\n\t\t\t\tconst isCorner = type === 'corner';\n\t\t\t\tlet a11y;\n\n\t\t\t\tif (type === 'edge' && bounds) {\n\t\t\t\t\tlet valuemin;\n\t\t\t\t\tlet valuemax;\n\t\t\t\t\tlet valuenow;\n\n\t\t\t\t\tif (direction === 'l') {\n\t\t\t\t\t\tvaluemin = bounds.x;\n\t\t\t\t\t\tvaluemax = Math.min(bounds.width, rect.x + rect.width);\n\t\t\t\t\t\tvaluenow = rect.x;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (direction === 't') {\n\t\t\t\t\t\tvaluemin = bounds.y;\n\t\t\t\t\t\tvaluemax = Math.min(bounds.height, rect.y + rect.height);\n\t\t\t\t\t\tvaluenow = rect.y;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (direction === 'r') {\n\t\t\t\t\t\tvaluemin = rect.x;\n\t\t\t\t\t\tvaluemax = bounds.width;\n\t\t\t\t\t\tvaluenow = rect.x + rect.width;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (direction === 'b') {\n\t\t\t\t\t\tvaluemin = rect.y;\n\t\t\t\t\t\tvaluemax = bounds.height;\n\t\t\t\t\t\tvaluenow = rect.y + rect.height;\n\t\t\t\t\t}\n\n\t\t\t\t\ta11y = {\n\t\t\t\t\t\trole: 'slider',\n\t\t\t\t\t\ttabindex: 0,\n\t\t\t\t\t\tlabel: `Drag ${SliderLabel[direction]}`,\n\t\t\t\t\t\torientation: `${SliderOrientation[direction]}`,\n\t\t\t\t\t\tvaluemin: Math.round(valuemin),\n\t\t\t\t\t\tvaluemax: Math.round(valuemax),\n\t\t\t\t\t\tvaluenow: Math.round(valuenow)\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tkey: direction,\n\t\t\t\t\ttype,\n\t\t\t\t\tscale: {\n\t\t\t\t\t\tx: (/^(t|b)$/).test(direction)\n\t\t\t\t\t\t? rect.width\n\t\t\t\t\t\t: isCorner ? clamp($selectionScale, 0.5, 1.25) : 1,\n\t\t\t\t\t\ty: (/^(r|l)$/).test(direction)\n\t\t\t\t\t\t? rect.height\n\t\t\t\t\t\t: isCorner ? clamp($selectionScale, 0.5, 1.25) : 1\n\t\t\t\t\t},\n\t\t\t\t\ttranslate: { x: position.x, y: position.y },\n\t\t\t\t\topacity: $selectionOpacity,\n\t\t\t\t\t...a11y\n\t\t\t\t};\n\t\t\t}));\n\t\t}\n\t};\n\n\treturn [\n\t\tcornerStyle,\n\t\tmappedDirections,\n\t\tisAnimated,\n\t\tselectionScale,\n\t\tselectionOpacity,\n\t\troute,\n\t\tnudge,\n\t\trect,\n\t\tbounds,\n\t\tvisible,\n\t\t$selectionOpacity,\n\t\t$selectionScale,\n\t\t$isAnimated\n\t];\n}\n\nclass RectManipulator extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$n, create_fragment$n, safe_not_equal, {\n\t\t\trect: 7,\n\t\t\tbounds: 8,\n\t\t\tvisible: 9,\n\t\t\tcornerStyle: 0\n\t\t});\n\t}\n}\n\nvar gesturable = (element) => {\n    function dispatch(type, detail) {\n        element.dispatchEvent(new CustomEvent(type, { detail }));\n    }\n    const handleGestureStart = (e) => {\n        e.preventDefault();\n        element.addEventListener('gesturechange', handleGestureChange);\n        element.addEventListener('gestureend', handleGestureEnd);\n        dispatch('gesturedown');\n    };\n    const handleGestureChange = (e) => {\n        e.preventDefault();\n        dispatch('gestureupdate', e.scale);\n    };\n    const handleGestureEnd = (e) => {\n        dispatch('gestureup', e.scale);\n        e.preventDefault();\n        clean();\n    };\n    const clean = () => {\n        element.removeEventListener('gesturechange', handleGestureChange);\n        element.removeEventListener('gestureend', handleGestureEnd);\n    };\n    element.addEventListener('gesturestart', handleGestureStart);\n    return {\n        destroy: () => {\n            clean();\n            element.removeEventListener('gesturestart', handleGestureStart);\n        },\n    };\n};\n\nvar DirectionInversionTable = {\n    [Top]: Bottom,\n    [Right]: Left,\n    [Bottom]: Top,\n    [Left]: Right,\n    [TopLeft]: BottomRight,\n    [TopRight]: BottomLeft,\n    [BottomRight]: TopLeft,\n    [BottomLeft]: TopRight,\n};\n\nvar getTranslationInfo = (target) => {\n    const translateToRight = target === Right || target === TopRight || target === BottomRight;\n    const translateToLeft = target === Left || target === BottomLeft || target === TopLeft;\n    const translateToTop = target === Top || target === TopRight || target === TopLeft;\n    const translateToBottom = target === Bottom || target === BottomRight || target === BottomLeft;\n    const translateHorizontally = target === Left || target === Right;\n    const translateVertically = target === Top || target === Bottom;\n    const translateAxis = translateHorizontally || translateVertically;\n    return [\n        translateToRight,\n        translateToLeft,\n        translateToTop,\n        translateToBottom,\n        translateHorizontally,\n        translateVertically,\n        translateAxis,\n    ];\n};\n\nvar limitRectDirectionTranslation = (rect, transform, bounds, options = {}) => {\n    // the transforms to apply\n    const { target, translate } = transform;\n    // the transform requirements\n    const { aspectRatio, minSize, maxSize } = options;\n    // get anchor coordinates and x,y position we need this for relative scaling of the view rectangle\n    const anchor = DirectionInversionTable[target];\n    const anchorDirectionCoordinates = DirectionCoordinateTable[anchor];\n    const anchorPosition = vectorAdd(vectorCreate(rect.x, rect.y), vectorCreate(anchorDirectionCoordinates[0] * rect.width, anchorDirectionCoordinates[1] * rect.height));\n    // get coordinate of direction\n    const targetDirectionCoordinates = DirectionCoordinateTable[target];\n    const targetPosition = vectorAdd(rectClone(rect), vectorCreate(targetDirectionCoordinates[0] * rect.width, targetDirectionCoordinates[1] * rect.height));\n    // bools to determine which direction the interaction is moving in\n    const [translateToRight, translateToLeft, translateToTop, translateToBottom, translateHorizontally, translateVertically, translateAxis,] = getTranslationInfo(target);\n    let tx = translate.x;\n    let ty = translate.y;\n    if (translateHorizontally)\n        ty = 0;\n    else if (translateVertically)\n        tx = 0;\n    const { inner: innerBounds, outer: outerBounds } = getInteractionBounds(anchorPosition, target, bounds, {\n        aspectRatio,\n        minSize,\n        maxSize,\n    });\n    // current bounds\n    let [t, r, b, l] = rectToBounds(rect);\n    // update view bounds with anchor based on translation direction (one side is always locked)\n    if (translateToRight)\n        l = anchorPosition.x;\n    else if (translateToLeft)\n        r = anchorPosition.x;\n    if (translateToBottom)\n        t = anchorPosition.y;\n    else if (translateToTop)\n        b = anchorPosition.y;\n    // update view bounds with interaction limits\n    if (translateToRight) {\n        const innerR = innerBounds.x + innerBounds.width;\n        const outerR = outerBounds.x + outerBounds.width;\n        r = clamp(targetPosition.x + tx, innerR, outerR);\n    }\n    else if (translateToLeft) {\n        const innerL = outerBounds.x;\n        const outerL = innerBounds.x;\n        l = clamp(targetPosition.x + tx, innerL, outerL);\n    }\n    if (translateToBottom) {\n        const innerB = innerBounds.y + innerBounds.height;\n        const outerB = outerBounds.y + outerBounds.height;\n        b = clamp(targetPosition.y + ty, innerB, outerB);\n    }\n    else if (translateToTop) {\n        const innerT = outerBounds.y;\n        const outerT = innerBounds.y;\n        t = clamp(targetPosition.y + ty, innerT, outerT);\n    }\n    // min size is respected\n    if (l > innerBounds.x) {\n        l = innerBounds.x;\n    }\n    if (r < innerBounds.x + innerBounds.width) {\n        r = innerBounds.x + innerBounds.width;\n    }\n    if (t > innerBounds.y) {\n        t = innerBounds.y;\n    }\n    if (b < innerBounds.y + innerBounds.height) {\n        b = innerBounds.y + innerBounds.height;\n    }\n    // max size is respected\n    if (l < outerBounds.x) {\n        const dx = outerBounds.x - l;\n        l = outerBounds.x;\n        r += dx;\n    }\n    if (r > outerBounds.x + outerBounds.width) {\n        const dx = r - (outerBounds.x + outerBounds.width);\n        r = outerBounds.x + outerBounds.width;\n        l -= dx;\n    }\n    if (t < outerBounds.y) {\n        const dy = outerBounds.y - t;\n        t = outerBounds.y;\n        b += dy;\n    }\n    if (b > outerBounds.y + outerBounds.height) {\n        const dy = b - (outerBounds.y + outerBounds.height);\n        b = outerBounds.y + outerBounds.height;\n        t -= dy;\n    }\n    // if aspect ratio is set we need to scale both axis\n    if (aspectRatio) {\n        // if translating over horizontal or vertical axis we need to update the other axis based on the aspect ratio as well\n        if (translateAxis) {\n            let dx = r - l;\n            let dy = b - t;\n            if (translateHorizontally) {\n                dy = dx / aspectRatio;\n                t = anchorPosition.y - dy * 0.5;\n                b = anchorPosition.y + dy * 0.5;\n            }\n            else if (translateVertically) {\n                dx = dy * aspectRatio;\n                l = anchorPosition.x - dx * 0.5;\n                r = anchorPosition.x + dx * 0.5;\n            }\n        }\n        // we're translating one of the corners in both the x and y direction, need to make sure it conforms to aspect ratio\n        else {\n            const pointer = vectorCreate(targetPosition.x + tx - anchorPosition.x, targetPosition.y + ty - anchorPosition.y);\n            // translations cannot be inverted, limited by anchor position\n            if (target === TopRight) {\n                pointer.x = Math.max(0, pointer.x);\n                pointer.y = Math.min(0, pointer.y);\n            }\n            else if (target === BottomRight) {\n                pointer.x = Math.max(0, pointer.x);\n                pointer.y = Math.max(0, pointer.y);\n            }\n            else if (target === BottomLeft) {\n                pointer.x = Math.min(0, pointer.x);\n                pointer.y = Math.max(0, pointer.y);\n            }\n            else if (target === TopLeft) {\n                pointer.x = Math.min(0, pointer.x);\n                pointer.y = Math.min(0, pointer.y);\n            }\n            // calculate the translation pointer, then get its length, now create a new pointer based on the aspect ratio, and scale it based on the original (limited) length\n            const pointerLength = vectorLength(pointer);\n            const pointerLengthMin = vectorLength(vectorCreate(innerBounds.width, innerBounds.height));\n            const pointerLengthMax = vectorLength(vectorCreate(outerBounds.width, outerBounds.height));\n            const pointerLengthLimited = clamp(pointerLength, pointerLengthMin, pointerLengthMax);\n            const pointerAspectRatio = vectorCreate(aspectRatio, 1);\n            const pointerScaled = vectorMultiply(vectorNormalize(pointerAspectRatio), pointerLengthLimited);\n            if (target === TopRight) {\n                r = anchorPosition.x + pointerScaled.x;\n                t = anchorPosition.y - pointerScaled.y;\n            }\n            else if (target === BottomRight) {\n                r = anchorPosition.x + pointerScaled.x;\n                b = anchorPosition.y + pointerScaled.y;\n            }\n            else if (target === BottomLeft) {\n                l = anchorPosition.x - pointerScaled.x;\n                b = anchorPosition.y + pointerScaled.y;\n            }\n            else if (target === TopLeft) {\n                l = anchorPosition.x - pointerScaled.x;\n                t = anchorPosition.y - pointerScaled.y;\n            }\n        }\n    }\n    return rectCreate(l, t, r - l, b - t);\n};\nconst getInteractionBounds = (anchor, dir, bounds, options) => {\n    const { aspectRatio, minSize, maxSize } = options;\n    const translateToRight = dir === Right || dir === TopRight || dir === BottomRight;\n    const translateToLeft = dir === Left || dir === BottomLeft || dir === TopLeft;\n    const translateToTop = dir === Top || dir === TopRight || dir === TopLeft;\n    const translateToBottom = dir === Bottom || dir === BottomRight || dir === BottomLeft;\n    const translateHorizontally = dir === Left || dir === Right;\n    const translateVertically = dir === Top || dir === Bottom;\n    // limit bounds based on anchor and direction\n    const limitedBounds = rectClone(bounds);\n    if (translateToRight) {\n        limitedBounds.x = anchor.x;\n        limitedBounds.width -= anchor.x;\n    }\n    else if (translateToLeft) {\n        limitedBounds.width = anchor.x;\n    }\n    if (translateToBottom) {\n        limitedBounds.y = anchor.y;\n        limitedBounds.height -= anchor.y;\n    }\n    else if (translateToTop) {\n        limitedBounds.height = anchor.y;\n    }\n    // limit max size based on bounds\n    const maxSizeLimitedToBounds = rectCreateFromDimensions(Math.min(limitedBounds.width, maxSize.width), Math.min(limitedBounds.height, maxSize.height));\n    if (aspectRatio) {\n        // limit height\n        if (translateHorizontally) {\n            const verticalSpace = Math.min(anchor.y, bounds.height - anchor.y);\n            maxSizeLimitedToBounds.height = Math.min(verticalSpace * 2, maxSizeLimitedToBounds.height);\n        }\n        // limit width\n        else if (translateVertically) {\n            const horizontalSpace = Math.min(anchor.x, bounds.width - anchor.x);\n            maxSizeLimitedToBounds.width = Math.min(horizontalSpace * 2, maxSizeLimitedToBounds.width);\n        }\n    }\n    const minSizeLimited = aspectRatio\n        ? sizeCreateFromRect(rectCoverRect(rectCreateFromSize(minSize), aspectRatio))\n        : minSize;\n    const maxSizeLimited = aspectRatio\n        ? sizeCreateFromRect(rectContainRect(maxSizeLimitedToBounds, aspectRatio))\n        : maxSizeLimitedToBounds;\n    let l, r, t, b;\n    // set bounds\n    if (translateToRight)\n        l = anchor.x;\n    else if (translateToLeft)\n        r = anchor.x;\n    if (translateToBottom)\n        t = anchor.y;\n    else if (translateToTop)\n        b = anchor.y;\n    // inner\n    if (translateToRight) {\n        r = l + minSizeLimited.width;\n    }\n    else if (translateToLeft) {\n        l = r - minSizeLimited.width;\n    }\n    if (translateToBottom) {\n        b = t + minSizeLimited.height;\n    }\n    else if (translateToTop) {\n        t = b - minSizeLimited.height;\n    }\n    if (translateHorizontally) {\n        t = anchor.y - minSizeLimited.height * 0.5;\n        b = anchor.y + minSizeLimited.height * 0.5;\n    }\n    else if (translateVertically) {\n        l = anchor.x - minSizeLimited.width * 0.5;\n        r = anchor.x + minSizeLimited.width * 0.5;\n    }\n    const inner = rectCreateFromPoints([vectorCreate(l, t), vectorCreate(r, b)]);\n    // outer\n    if (translateToRight) {\n        r = l + maxSizeLimited.width;\n    }\n    else if (translateToLeft) {\n        l = r - maxSizeLimited.width;\n    }\n    if (translateToBottom) {\n        b = t + maxSizeLimited.height;\n    }\n    else if (translateToTop) {\n        t = b - maxSizeLimited.height;\n    }\n    if (translateHorizontally) {\n        t = anchor.y - maxSizeLimited.height * 0.5;\n        b = anchor.y + maxSizeLimited.height * 0.5;\n    }\n    else if (translateVertically) {\n        l = anchor.x - maxSizeLimited.width * 0.5;\n        r = anchor.x + maxSizeLimited.width * 0.5;\n    }\n    // limit outer to stage\n    l = Math.max(bounds.x, l);\n    r = Math.min(bounds.x + bounds.width, r);\n    t = Math.max(bounds.y, t);\n    b = Math.min(bounds.y + bounds.height, b);\n    const outer = rectCreateFromPoints([vectorCreate(l, t), vectorCreate(r, b)]);\n    return {\n        inner,\n        outer,\n    };\n};\n\nvar applyRectDirectionTranslation = (rect, transform, options = {}) => {\n    // the transforms to apply\n    const { target, translate } = transform;\n    // the transform requirements\n    const { aspectRatio, minSize } = options;\n    // get anchor coordinates and x,y position we need this for relative scaling of the view rectangle\n    const anchor = DirectionInversionTable[target];\n    const anchorDirectionCoordinates = DirectionCoordinateTable[anchor];\n    const anchorPosition = vectorAdd(rectClone(rect), vectorCreate(anchorDirectionCoordinates[0] * rect.width, anchorDirectionCoordinates[1] * rect.height));\n    // get coordinate of direction\n    const targetDirectionCoordinates = DirectionCoordinateTable[target];\n    const targetPosition = vectorAdd(rectClone(rect), vectorCreate(targetDirectionCoordinates[0] * rect.width, targetDirectionCoordinates[1] * rect.height));\n    // bools to determine which direction the interaction is moving in\n    const [translateToRight, translateToLeft, translateToTop, translateToBottom, translateHorizontally, translateVertically, translateAxis,] = getTranslationInfo(target);\n    let tx = translate.x;\n    let ty = translate.y;\n    if (translateHorizontally)\n        ty = 0;\n    else if (translateVertically)\n        tx = 0;\n    // current bounds\n    let [t, r, b, l] = rectToBounds(rect);\n    // update view bounds with anchor based on translation direction (one side is always locked)\n    if (translateToRight)\n        l = anchorPosition.x;\n    else if (translateToLeft)\n        r = anchorPosition.x;\n    if (translateToBottom)\n        t = anchorPosition.y;\n    else if (translateToTop)\n        b = anchorPosition.y;\n    // update view bounds with interaction limits\n    if (translateToRight) {\n        r = targetPosition.x + tx;\n    }\n    else if (translateToLeft) {\n        l = targetPosition.x + tx;\n    }\n    if (translateToBottom) {\n        b = targetPosition.y + ty;\n    }\n    else if (translateToTop) {\n        t = targetPosition.y + ty;\n    }\n    if (minSize && translateHorizontally && b - t < minSize.height) {\n        const dy = minSize.height - (b - t);\n        t -= dy * 0.5;\n        b += dy * 0.5;\n    }\n    // make sure min size is respected\n    if (minSize && translateVertically && r - l < minSize.width) {\n        const dx = minSize.width - (r - l);\n        l -= dx * 0.5;\n        r += dx * 0.5;\n    }\n    // if aspect ratio is set we need to scale both axis\n    if (aspectRatio) {\n        // if translating over horizontal or vertical axis we need to update the other axis based on the aspect ratio as well\n        if (translateAxis) {\n            let dx = r - l;\n            let dy = b - t;\n            if (translateHorizontally) {\n                dy = dx / aspectRatio;\n                t = anchorPosition.y - dy * 0.5;\n                b = anchorPosition.y + dy * 0.5;\n            }\n            else if (translateVertically) {\n                dx = dy * aspectRatio;\n                l = anchorPosition.x - dx * 0.5;\n                r = anchorPosition.x + dx * 0.5;\n            }\n        }\n        // we're translating one of the corners in both the x and y direction, need to make sure it conforms to aspect ratio\n        else {\n            const pointer = vectorCreate(targetPosition.x + tx - anchorPosition.x, targetPosition.y + ty - anchorPosition.y);\n            // translations cannot be inverted, limited by anchor position\n            if (target === TopRight) {\n                pointer.x = Math.max(0, pointer.x);\n                pointer.y = Math.min(0, pointer.y);\n            }\n            else if (target === BottomRight) {\n                pointer.x = Math.max(0, pointer.x);\n                pointer.y = Math.max(0, pointer.y);\n            }\n            else if (target === BottomLeft) {\n                pointer.x = Math.min(0, pointer.x);\n                pointer.y = Math.max(0, pointer.y);\n            }\n            else if (target === TopLeft) {\n                pointer.x = Math.min(0, pointer.x);\n                pointer.y = Math.min(0, pointer.y);\n            }\n            // calculate the translation pointer, then get its length, now create a new pointer based on the aspect ratio, and scale it based on the original (limited) length\n            const pointerLength = vectorLength(pointer);\n            const pointerAspectRatio = vectorCreate(aspectRatio, 1);\n            const pointerScaled = vectorMultiply(vectorNormalize(pointerAspectRatio), pointerLength);\n            if (target === TopRight) {\n                r = anchorPosition.x + pointerScaled.x;\n                t = anchorPosition.y - pointerScaled.y;\n            }\n            else if (target === BottomRight) {\n                r = anchorPosition.x + pointerScaled.x;\n                b = anchorPosition.y + pointerScaled.y;\n            }\n            else if (target === BottomLeft) {\n                l = anchorPosition.x - pointerScaled.x;\n                b = anchorPosition.y + pointerScaled.y;\n            }\n            else if (target === TopLeft) {\n                l = anchorPosition.x - pointerScaled.x;\n                t = anchorPosition.y - pointerScaled.y;\n            }\n        }\n    }\n    return rectCreate(l, t, r - l, b - t);\n};\n\nvar radToDeg = (rad) => rad * 180 / Math.PI;\n\n/* src/core/ui/plugins/crop/components/ImageRotator.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$m(ctx) {\n\tlet div;\n\tlet rangeinput;\n\tlet current;\n\n\trangeinput = new RangeInput({\n\t\t\tprops: {\n\t\t\t\telasticity: /*elasticity*/ ctx[5],\n\t\t\t\tmin: /*min*/ ctx[9],\n\t\t\t\tmax: /*max*/ ctx[10],\n\t\t\t\tvalue: /*value*/ ctx[11],\n\t\t\t\tvalueMin: Math.max(/*min*/ ctx[9], /*valueMin*/ ctx[0]),\n\t\t\t\tvalueMax: Math.min(/*max*/ ctx[10], /*valueMax*/ ctx[1]),\n\t\t\t\tlabelReset: /*labelReset*/ ctx[6],\n\t\t\t\tbase: /*center*/ ctx[12],\n\t\t\t\tvalueLabel: `${Math.round(radToDeg(/*value*/ ctx[11]))}&deg;`,\n\t\t\t\toninputstart: /*oninputstart*/ ctx[2],\n\t\t\t\toninputmove: /*func*/ ctx[17],\n\t\t\t\toninputend: /*func_1*/ ctx[18]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(rangeinput.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaImageRotator\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(rangeinput, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tconst rangeinput_changes = {};\n\t\t\tif (dirty & /*elasticity*/ 32) rangeinput_changes.elasticity = /*elasticity*/ ctx[5];\n\t\t\tif (dirty & /*min*/ 512) rangeinput_changes.min = /*min*/ ctx[9];\n\t\t\tif (dirty & /*max*/ 1024) rangeinput_changes.max = /*max*/ ctx[10];\n\t\t\tif (dirty & /*value*/ 2048) rangeinput_changes.value = /*value*/ ctx[11];\n\t\t\tif (dirty & /*min, valueMin*/ 513) rangeinput_changes.valueMin = Math.max(/*min*/ ctx[9], /*valueMin*/ ctx[0]);\n\t\t\tif (dirty & /*max, valueMax*/ 1026) rangeinput_changes.valueMax = Math.min(/*max*/ ctx[10], /*valueMax*/ ctx[1]);\n\t\t\tif (dirty & /*labelReset*/ 64) rangeinput_changes.labelReset = /*labelReset*/ ctx[6];\n\t\t\tif (dirty & /*center*/ 4096) rangeinput_changes.base = /*center*/ ctx[12];\n\t\t\tif (dirty & /*value*/ 2048) rangeinput_changes.valueLabel = `${Math.round(radToDeg(/*value*/ ctx[11]))}&deg;`;\n\t\t\tif (dirty & /*oninputstart*/ 4) rangeinput_changes.oninputstart = /*oninputstart*/ ctx[2];\n\t\t\tif (dirty & /*oninputmove, sign, turns*/ 392) rangeinput_changes.oninputmove = /*func*/ ctx[17];\n\t\t\tif (dirty & /*oninputend, sign, turns*/ 400) rangeinput_changes.oninputend = /*func_1*/ ctx[18];\n\t\t\trangeinput.$set(rangeinput_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(rangeinput.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(rangeinput.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(rangeinput);\n\t\t}\n\t};\n}\n\nconst MARGIN = 0.000000001;\n\nfunction instance$m($$self, $$props, $$invalidate) {\n\tlet min;\n\tlet max;\n\tlet center;\n\tlet range;\n\tlet sign;\n\tlet turns;\n\tlet value;\n\tlet { rotation } = $$props;\n\tlet { valueMin } = $$props;\n\tlet { valueMax } = $$props;\n\tlet { oninputstart = noop$1 } = $$props;\n\tlet { oninputmove = noop$1 } = $$props;\n\tlet { oninputend = noop$1 } = $$props;\n\tlet { elasticity = 0 } = $$props;\n\tlet { labelReset = undefined } = $$props;\n\tlet { rotationMin = undefined } = $$props;\n\tlet { rotationMax = undefined } = $$props;\n\tconst func = value => oninputmove(sign * turns + value);\n\tconst func_1 = value => oninputend(sign * turns + value);\n\n\t$$self.$$set = $$props => {\n\t\tif ('rotation' in $$props) $$invalidate(13, rotation = $$props.rotation);\n\t\tif ('valueMin' in $$props) $$invalidate(0, valueMin = $$props.valueMin);\n\t\tif ('valueMax' in $$props) $$invalidate(1, valueMax = $$props.valueMax);\n\t\tif ('oninputstart' in $$props) $$invalidate(2, oninputstart = $$props.oninputstart);\n\t\tif ('oninputmove' in $$props) $$invalidate(3, oninputmove = $$props.oninputmove);\n\t\tif ('oninputend' in $$props) $$invalidate(4, oninputend = $$props.oninputend);\n\t\tif ('elasticity' in $$props) $$invalidate(5, elasticity = $$props.elasticity);\n\t\tif ('labelReset' in $$props) $$invalidate(6, labelReset = $$props.labelReset);\n\t\tif ('rotationMin' in $$props) $$invalidate(14, rotationMin = $$props.rotationMin);\n\t\tif ('rotationMax' in $$props) $$invalidate(15, rotationMax = $$props.rotationMax);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*rotationMin*/ 16384) {\n\t\t\t$$invalidate(9, min = rotationMin + MARGIN);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*rotationMax*/ 32768) {\n\t\t\t$$invalidate(10, max = rotationMax - MARGIN);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*min, max*/ 1536) {\n\t\t\t$$invalidate(12, center = min + (max - min) * 0.5);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*rotationMax*/ 32768) {\n\t\t\t$$invalidate(16, range = rotationMax * 2);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*rotation*/ 8192) {\n\t\t\t$$invalidate(8, sign = Math.sign(rotation));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*rotation, range*/ 73728) {\n\t\t\t$$invalidate(7, turns = Math.round(Math.abs(rotation) / range) * range);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*rotation, sign, turns*/ 8576) {\n\t\t\t$$invalidate(11, value = rotation - sign * turns);\n\t\t}\n\t};\n\n\treturn [\n\t\tvalueMin,\n\t\tvalueMax,\n\t\toninputstart,\n\t\toninputmove,\n\t\toninputend,\n\t\telasticity,\n\t\tlabelReset,\n\t\tturns,\n\t\tsign,\n\t\tmin,\n\t\tmax,\n\t\tvalue,\n\t\tcenter,\n\t\trotation,\n\t\trotationMin,\n\t\trotationMax,\n\t\trange,\n\t\tfunc,\n\t\tfunc_1\n\t];\n}\n\nclass ImageRotator extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$m, create_fragment$m, safe_not_equal, {\n\t\t\trotation: 13,\n\t\t\tvalueMin: 0,\n\t\t\tvalueMax: 1,\n\t\t\toninputstart: 2,\n\t\t\toninputmove: 3,\n\t\t\toninputend: 4,\n\t\t\telasticity: 5,\n\t\t\tlabelReset: 6,\n\t\t\trotationMin: 14,\n\t\t\trotationMax: 15\n\t\t});\n\t}\n}\n\nvar getSelectionPresetOptionIcon = (value, options = {}) => {\n    const { width = 24, height = 24, bounds = 16, radius = 3 } = options;\n    let aspectRatio = isArray(value) ? getAspectRatio(value[0], value[1]) : value;\n    let aspectRatioDefined = !!aspectRatio;\n    aspectRatio = aspectRatioDefined ? aspectRatio : 1;\n    let x;\n    let y;\n    let w;\n    let h;\n    w = aspectRatio > 1 ? bounds : aspectRatio * bounds;\n    h = w / aspectRatio;\n    x = Math.round((width - w) * 0.5);\n    y = Math.round((height - h) * 0.5);\n    const fill = aspectRatioDefined ? 'currentColor' : 'none';\n    const stroke = aspectRatioDefined ? 'none' : 'currentColor';\n    const strokeWidth = width / 16;\n    const strokeDashArray = [width / 12, width / 6].join(' ');\n    return `<rect fill=\"${fill}\" stroke=\"${stroke}\" stroke-width=\"${strokeWidth}\" stroke-dasharray=\"${strokeDashArray}\" x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\" rx=\"${radius}\"/>`;\n};\n\n/* src/core/ui/plugins/crop/components/CropPresetList.svelte generated by Svelte v4.2.20 */\n\nfunction create_controls_slot(ctx) {\n\tlet radiogroup;\n\tlet current;\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaPresetListFilter\",\n\t\t\t\tlayout: \"row\",\n\t\t\t\toptions: /*filterOptions*/ ctx[8],\n\t\t\t\tselectedIndex: /*selectedFilterIndex*/ ctx[7],\n\t\t\t\tonchange: /*handleChangeFilter*/ ctx[10]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radiogroup, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty & /*filterOptions*/ 256) radiogroup_changes.options = /*filterOptions*/ ctx[8];\n\t\t\tif (dirty & /*selectedFilterIndex*/ 128) radiogroup_changes.selectedIndex = /*selectedFilterIndex*/ ctx[7];\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radiogroup, detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$l(ctx) {\n\tlet dropdown;\n\tlet current;\n\n\tdropdown = new Dropdown({\n\t\t\tprops: {\n\t\t\t\ticon: /*icon*/ ctx[0],\n\t\t\t\tlabel: /*label*/ ctx[1],\n\t\t\t\tlabelClass: /*labelClass*/ ctx[2],\n\t\t\t\thideLabel: /*hideLabel*/ ctx[3],\n\t\t\t\toptions: /*filteredOptions*/ ctx[9],\n\t\t\t\tselectedIndex: /*selectedIndex*/ ctx[4],\n\t\t\t\tonchange: /*onchange*/ ctx[5],\n\t\t\t\toptionMapper: /*optionMapper*/ ctx[6],\n\t\t\t\t$$slots: { controls: [create_controls_slot] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dropdown.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dropdown, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tconst dropdown_changes = {};\n\t\t\tif (dirty & /*icon*/ 1) dropdown_changes.icon = /*icon*/ ctx[0];\n\t\t\tif (dirty & /*label*/ 2) dropdown_changes.label = /*label*/ ctx[1];\n\t\t\tif (dirty & /*labelClass*/ 4) dropdown_changes.labelClass = /*labelClass*/ ctx[2];\n\t\t\tif (dirty & /*hideLabel*/ 8) dropdown_changes.hideLabel = /*hideLabel*/ ctx[3];\n\t\t\tif (dirty & /*filteredOptions*/ 512) dropdown_changes.options = /*filteredOptions*/ ctx[9];\n\t\t\tif (dirty & /*selectedIndex*/ 16) dropdown_changes.selectedIndex = /*selectedIndex*/ ctx[4];\n\t\t\tif (dirty & /*onchange*/ 32) dropdown_changes.onchange = /*onchange*/ ctx[5];\n\t\t\tif (dirty & /*optionMapper*/ 64) dropdown_changes.optionMapper = /*optionMapper*/ ctx[6];\n\n\t\t\tif (dirty & /*$$scope, filterOptions, selectedFilterIndex*/ 262528) {\n\t\t\t\tdropdown_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tdropdown.$set(dropdown_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dropdown.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dropdown.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dropdown, detaching);\n\t\t}\n\t};\n}\n\nconst style = 'fill=\"none\" stroke=\"currentColor\"';\n\nfunction instance$l($$self, $$props, $$invalidate) {\n\tlet filteredOptions;\n\tlet selectedFilterIndex;\n\tlet filterOptions;\n\tlet { icon } = $$props;\n\tlet { label } = $$props;\n\tlet { labelClass } = $$props;\n\tlet { hideLabel } = $$props;\n\tlet { options } = $$props;\n\tlet { selectedIndex } = $$props;\n\tlet { onchange } = $$props;\n\tlet { optionMapper } = $$props;\n\tlet { filter = 'landscape' } = $$props;\n\tlet { onfilterchange = noop$1 } = $$props;\n\n\tconst getIcon = (x, y, width, height, r) => `\n    <rect ${style} x=\"${x}\" y=\"${y}\" width=\"${width}\" height=\"${height}\" rx=\"${r}\"/>`;\n\n\tconst getCheckmark = (x, y) => `<path ${style} d=\"M${x} ${y} l2 2 l3 -4\"/>`;\n\n\tconst mapGroupedOptions = (options, map) => (options || []).map(option => {\n\t\t// group\n\t\tif (isString(option[0])) {\n\t\t\toption[1] = option[1].map(map);\n\t\t\treturn option;\n\t\t}\n\n\t\t// single\n\t\treturn map(option);\n\t});\n\n\tconst createOptionMapper = filter => item => {\n\t\tconst [value, label, options = {}] = item;\n\n\t\tif (isNumber(value)) {\n\t\t\toptions.hidden = filter === 'landscape' ? value < 1 : value > 1;\n\t\t}\n\n\t\treturn [value, label, options];\n\t};\n\n\tconst handleChangeFilter = item => {\n\t\t$$invalidate(11, filter = item.value);\n\t\tonfilterchange(item.value);\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('icon' in $$props) $$invalidate(0, icon = $$props.icon);\n\t\tif ('label' in $$props) $$invalidate(1, label = $$props.label);\n\t\tif ('labelClass' in $$props) $$invalidate(2, labelClass = $$props.labelClass);\n\t\tif ('hideLabel' in $$props) $$invalidate(3, hideLabel = $$props.hideLabel);\n\t\tif ('options' in $$props) $$invalidate(12, options = $$props.options);\n\t\tif ('selectedIndex' in $$props) $$invalidate(4, selectedIndex = $$props.selectedIndex);\n\t\tif ('onchange' in $$props) $$invalidate(5, onchange = $$props.onchange);\n\t\tif ('optionMapper' in $$props) $$invalidate(6, optionMapper = $$props.optionMapper);\n\t\tif ('filter' in $$props) $$invalidate(11, filter = $$props.filter);\n\t\tif ('onfilterchange' in $$props) $$invalidate(13, onfilterchange = $$props.onfilterchange);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*options, filter*/ 6144) {\n\t\t\t$$invalidate(9, filteredOptions = mapGroupedOptions(options, createOptionMapper(filter)));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*filter*/ 2048) {\n\t\t\t$$invalidate(7, selectedFilterIndex = filter === 'landscape' ? 0 : 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*selectedFilterIndex*/ 128) {\n\t\t\t$$invalidate(8, filterOptions = [\n\t\t\t\t[\n\t\t\t\t\t'landscape',\n\t\t\t\t\t'Landscape',\n\t\t\t\t\t{\n\t\t\t\t\t\thideLabel: true,\n\t\t\t\t\t\ticon: getIcon(2, 6, 19, 12, 2) + (selectedFilterIndex === 0 ? getCheckmark(9, 12) : '')\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t[\n\t\t\t\t\t'portrait',\n\t\t\t\t\t'Portrait',\n\t\t\t\t\t{\n\t\t\t\t\t\thideLabel: true,\n\t\t\t\t\t\ticon: getIcon(5, 3, 13, 18, 2) + (selectedFilterIndex === 1 ? getCheckmark(9, 12) : '')\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t]);\n\t\t}\n\t};\n\n\treturn [\n\t\ticon,\n\t\tlabel,\n\t\tlabelClass,\n\t\thideLabel,\n\t\tselectedIndex,\n\t\tonchange,\n\t\toptionMapper,\n\t\tselectedFilterIndex,\n\t\tfilterOptions,\n\t\tfilteredOptions,\n\t\thandleChangeFilter,\n\t\tfilter,\n\t\toptions,\n\t\tonfilterchange\n\t];\n}\n\nclass CropPresetList extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$l, create_fragment$l, safe_not_equal, {\n\t\t\ticon: 0,\n\t\t\tlabel: 1,\n\t\t\tlabelClass: 2,\n\t\t\thideLabel: 3,\n\t\t\toptions: 12,\n\t\t\tselectedIndex: 4,\n\t\t\tonchange: 5,\n\t\t\toptionMapper: 6,\n\t\t\tfilter: 11,\n\t\t\tonfilterchange: 13\n\t\t});\n\t}\n}\n\n// this makes sure that the new rectangle doesn't have corners outside of the quad\nconst EDGE_DISTANCE_FACTOR = 0.9999;\nconst PRECISION = 6;\nconst fixVectorPrecision = (v) => vectorApply(v, (v) => fixPrecision(v, PRECISION));\nconst rectFixPrecision = (r) => rectApply(r, (v) => fixPrecision(v, PRECISION));\nconst quadFixPrecision = (q) => q.map(fixVectorPrecision);\nconst floatEquals = (a, b, margin = 0.0001) => Math.abs(a - b) < margin;\nvar getRectLimitedToQuad = (rectOrigin, rectTarget, transform, quad, options = {}) => {\n    const { aspectRatio } = options;\n    rectOrigin = rectFixPrecision(rectOrigin);\n    quad = quadFixPrecision(quad);\n    const anchor = rectGetCornerByTarget(rectOrigin, DirectionInversionTable[transform.target]);\n    const anchorFixed = vectorApply(anchor, (v) => fixPrecision(v, PRECISION));\n    const minSize = aspectRatio ? rectCoverRect(options.minSize, aspectRatio) : options.minSize;\n    const maxSize = aspectRatio ? rectContainRect(options.maxSize, aspectRatio) : options.maxSize;\n    const rectTargetCorner = rectGetCornerByTarget(rectTarget, transform.target);\n    // prevent scaling the target size smaller than 0\n    const dist = vectorDistance(rectTargetCorner, anchor);\n    if (dist < 1) {\n        rectTarget = rectClone(rectOrigin);\n        const scalar = Math.min(minSize.width / rectOrigin.width, minSize.height / rectOrigin.height);\n        rectScale(rectTarget, scalar, anchor);\n    }\n    // clamp between min and max size\n    rectTarget = rectClamp(rectClone(rectTarget), minSize, maxSize, anchor);\n    let rect = rectClone(rectTarget);\n    rectTarget = rectFixPrecision(rectTarget);\n    const quadEdges = quadToLines(quad, 1);\n    const cornersOrigin = rectGetCorners(rectOrigin);\n    const cornersTarget = rectGetCorners(rectTarget);\n    const anchorIndex = cornersOrigin.findIndex((corner) => vectorEqual(vectorApply(corner, (v) => fixPrecision(v, PRECISION)), anchorFixed));\n    const getLineIntersectionWithQuad = (line) => quadEdges\n        .map((quadEdge) => lineLineIntersection(quadEdge, line))\n        .filter(Boolean)\n        .pop();\n    // when aspect ratio is locked we can scale the original rectangle relatively to closest intersectionpoint\n    if (aspectRatio) {\n        const intersections = cornersTarget\n            .map((target, index) => {\n            // skip anchor\n            if (index === anchorIndex)\n                return;\n            // start ray slightly away from anchor so we don't intersect with quad edge\n            const dir = vectorCreate(anchor.x - target.x, anchor.y - target.y);\n            vectorNormalize(dir);\n            vectorMultiply(dir, 0.5);\n            // draw line from anchor to target to find intersection with quad edge\n            const rayOrigin = vectorCreate(anchor.x - dir.x, anchor.y - dir.y);\n            const ray = lineCreate(rayOrigin, fixVectorPrecision(target));\n            const intersection = getLineIntersectionWithQuad(ray);\n            if (!intersection)\n                return;\n            const origin = cornersOrigin[index];\n            return {\n                intersection,\n                cornerDist: vectorDistance(anchor, origin),\n                intersectionDist: vectorDistance(anchor, intersection),\n            };\n        })\n            .filter(Boolean);\n        if (intersections.length) {\n            const scalar = intersections.reduce((scalar, current) => {\n                const currentScalar = current.intersectionDist / current.cornerDist;\n                return currentScalar < scalar ? currentScalar : scalar;\n            }, Number.MAX_SAFE_INTEGER);\n            rect = rectClone(rectOrigin);\n            rectScale(rect, scalar, anchor);\n        }\n    }\n    else {\n        // if not a fixed aspect ratio\n        const isManipulatingEdge = transform.target.length === 1;\n        // is true if quad is rotated\n        const isRotated = !(quad[0].y === quad[1].y || quad[0].x === quad[1].x);\n        // get intersections\n        const intersections = cornersOrigin\n            .map((cornerOrigin, index) => {\n            // skip anchor\n            if (index === anchorIndex)\n                return;\n            const cornerTarget = cornersTarget[index];\n            const isDiagonal = !floatEquals(cornerTarget.x, anchorFixed.x) &&\n                !floatEquals(cornerTarget.y, anchorFixed.y);\n            // we ignore the diagonal ray if the quad isn't rotated this makes for better ux\n            if (!isManipulatingEdge && !isRotated && isDiagonal)\n                return;\n            if (isManipulatingEdge &&\n                (floatEquals(cornerTarget.x, anchorFixed.x) ||\n                    floatEquals(cornerTarget.y, anchorFixed.y)))\n                return;\n            const rayOrigin = vectorClone(isManipulatingEdge ? cornerOrigin : anchor);\n            // start ray slightly away from anchor so we don't intersect with quad edge\n            const dir = vectorSubtract(vectorClone(rayOrigin), cornerTarget);\n            vectorNormalize(dir);\n            vectorMultiply(dir, 0.5);\n            if (isManipulatingEdge) {\n                vectorAdd(rayOrigin, dir);\n            }\n            else {\n                vectorSubtract(rayOrigin, dir);\n            }\n            const ray = lineCreate(rayOrigin, cornerTarget);\n            const intersection = getLineIntersectionWithQuad(ray);\n            if (!intersection)\n                return;\n            return intersection;\n        })\n            .filter(Boolean);\n        if (intersections.length) {\n            const [translateToRight, translateToLeft, translateToTop, translateToBottom] = getTranslationInfo(transform.target);\n            let [t, r, b, l] = rectToBounds(rectTarget);\n            intersections.forEach(({ x, y }) => {\n                const pX = fixPrecision(x, PRECISION);\n                const pY = fixPrecision(y, PRECISION);\n                if (translateToTop && !floatEquals(pY, anchorFixed.y)) {\n                    t = Math.max(t, y);\n                }\n                if (translateToRight && !floatEquals(pX, anchorFixed.x)) {\n                    r = Math.min(r, x);\n                }\n                if (translateToBottom && !floatEquals(pY, anchorFixed.y)) {\n                    b = Math.min(b, y);\n                }\n                if (translateToLeft && !floatEquals(pX, anchorFixed.x)) {\n                    l = Math.max(l, x);\n                }\n            });\n            // new rect\n            rect = rectCreateFromBounds([t, r, b, l]);\n            // scale back a bit so doesn't overlap with quad\n            rectScale(rect, EDGE_DISTANCE_FACTOR, anchor);\n        }\n    }\n    // make sure is at least one pixel wide and high\n    rectClamp(rect, minSize, maxSize, anchor);\n    return rect;\n};\n\n/* src/core/ui/plugins/crop/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_default_slot_2$3(ctx) {\n\tlet dynamiccomponenttree;\n\tlet current;\n\tdynamiccomponenttree = new DynamicComponentTree_1({ props: { items: /*cropTools*/ ctx[12] } });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty[0] & /*cropTools*/ 4096) dynamiccomponenttree_changes.items = /*cropTools*/ ctx[12];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t}\n\t};\n}\n\n// (1631:4) \nfunction create_header_slot$1(ctx) {\n\tlet div;\n\tlet toolbar;\n\tlet current;\n\n\ttoolbar = new Toolbar({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_2$3] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(toolbar.$$.fragment);\n\t\t\tattr(div, \"slot\", \"header\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(toolbar, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst toolbar_changes = {};\n\n\t\t\tif (dirty[0] & /*cropTools*/ 4096 | dirty[7] & /*$$scope*/ 4096) {\n\t\t\t\ttoolbar_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttoolbar.$set(toolbar_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(toolbar.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(toolbar.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(toolbar);\n\t\t}\n\t};\n}\n\n// (1661:12) {#if shouldRenderImageSelection && shouldRenderImageSelectionRecenterButton}\nfunction create_if_block_5$2(ctx) {\n\tlet button;\n\tlet current;\n\n\tbutton = new Button({\n\t\t\tprops: {\n\t\t\t\tonclick: /*handleRecenterAction*/ ctx[91],\n\t\t\t\tlabel: /*locale*/ ctx[4].cropLabelButtonRecenter,\n\t\t\t\ticon: /*locale*/ ctx[4].cropIconButtonRecenter,\n\t\t\t\tdisabled: !/*canCenter*/ ctx[9],\n\t\t\t\thideLabel: true,\n\t\t\t\tclass: \"PinturaButtonCenter\",\n\t\t\t\tstyle: `opacity:${/*$recenterOpacity*/ ctx[31]};transform:translate3d(${/*$recenterOffset*/ ctx[32].x}px, ${/*$recenterOffset*/ ctx[32].y}px,0)`\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(button.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(button, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst button_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) button_changes.label = /*locale*/ ctx[4].cropLabelButtonRecenter;\n\t\t\tif (dirty[0] & /*locale*/ 16) button_changes.icon = /*locale*/ ctx[4].cropIconButtonRecenter;\n\t\t\tif (dirty[0] & /*canCenter*/ 512) button_changes.disabled = !/*canCenter*/ ctx[9];\n\t\t\tif (dirty[1] & /*$recenterOpacity, $recenterOffset*/ 3) button_changes.style = `opacity:${/*$recenterOpacity*/ ctx[31]};transform:translate3d(${/*$recenterOffset*/ ctx[32].x}px, ${/*$recenterOffset*/ ctx[32].y}px,0)`;\n\t\t\tbutton.$set(button_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(button, detaching);\n\t\t}\n\t};\n}\n\n// (1673:12) {#if shouldRenderImageSelection}\nfunction create_if_block_4$3(ctx) {\n\tlet rectmanipulator;\n\tlet current;\n\n\trectmanipulator = new RectManipulator({\n\t\t\tprops: {\n\t\t\t\trect: /*imageSelectionRectOffset*/ ctx[8],\n\t\t\t\tbounds: /*$utilRectPadded*/ ctx[14],\n\t\t\t\tvisible: /*$isActive*/ ctx[13],\n\t\t\t\tcornerStyle: /*cropImageSelectionCornerStyle*/ ctx[1]\n\t\t\t}\n\t\t});\n\n\trectmanipulator.$on(\"resizestart\", /*handleSelectionGrab*/ ctx[71]);\n\trectmanipulator.$on(\"resizemove\", /*handleSelectionDrag*/ ctx[72]);\n\trectmanipulator.$on(\"resizeend\", /*handleSelectionRelease*/ ctx[73]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(rectmanipulator.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(rectmanipulator, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst rectmanipulator_changes = {};\n\t\t\tif (dirty[0] & /*imageSelectionRectOffset*/ 256) rectmanipulator_changes.rect = /*imageSelectionRectOffset*/ ctx[8];\n\t\t\tif (dirty[0] & /*$utilRectPadded*/ 16384) rectmanipulator_changes.bounds = /*$utilRectPadded*/ ctx[14];\n\t\t\tif (dirty[0] & /*$isActive*/ 8192) rectmanipulator_changes.visible = /*$isActive*/ ctx[13];\n\t\t\tif (dirty[0] & /*cropImageSelectionCornerStyle*/ 2) rectmanipulator_changes.cornerStyle = /*cropImageSelectionCornerStyle*/ ctx[1];\n\t\t\trectmanipulator.$set(rectmanipulator_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(rectmanipulator.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(rectmanipulator.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(rectmanipulator, detaching);\n\t\t}\n\t};\n}\n\n// (1687:8) {#if shouldRenderInfoIndicator}\nfunction create_if_block_3$3(ctx) {\n\tlet div;\n\tlet p;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tp = element(\"p\");\n\t\t\tattr(div, \"class\", \"PinturaImageInfo\");\n\t\t\tattr(div, \"data-custom\", /*isImageInfoCustom*/ ctx[24]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, p);\n\t\t\tp.innerHTML = /*imageInfo*/ ctx[23];\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*imageInfo*/ 8388608) p.innerHTML = /*imageInfo*/ ctx[23];\n\t\t\tif (dirty[0] & /*isImageInfoCustom*/ 16777216) {\n\t\t\t\tattr(div, \"data-custom\", /*isImageInfoCustom*/ ctx[24]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (1637:4) \nfunction create_main_slot$1(ctx) {\n\tlet div1;\n\tlet div0;\n\tlet t0;\n\tlet interactable_action;\n\tlet t1;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block0 = /*shouldRenderImageSelection*/ ctx[22] && /*shouldRenderImageSelectionRecenterButton*/ ctx[10] && create_if_block_5$2(ctx);\n\tlet if_block1 = /*shouldRenderImageSelection*/ ctx[22] && create_if_block_4$3(ctx);\n\tlet if_block2 = /*shouldRenderInfoIndicator*/ ctx[11] && create_if_block_3$3(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv1 = element(\"div\");\n\t\t\tdiv0 = element(\"div\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt0 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block2) if_block2.c();\n\t\t\tattr(div0, \"class\", \"PinturaStage\");\n\t\t\tattr(div1, \"slot\", \"main\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div1, anchor);\n\t\t\tappend(div1, div0);\n\t\t\tif (if_block0) if_block0.m(div0, null);\n\t\t\tappend(div0, t0);\n\t\t\tif (if_block1) if_block1.m(div0, null);\n\t\t\t/*div0_binding*/ ctx[170](div0);\n\t\t\tappend(div1, t1);\n\t\t\tif (if_block2) if_block2.m(div1, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\taction_destroyer(measurable.call(null, div0)),\n\t\t\t\t\tlisten(div0, \"measure\", /*measure_handler_1*/ ctx[168]),\n\t\t\t\t\tlisten(\n\t\t\t\t\t\tdiv0,\n\t\t\t\t\t\t\"wheel\",\n\t\t\t\t\t\tfunction () {\n\t\t\t\t\t\t\tif (is_function(/*cropEnableZoom*/ ctx[2] && /*handleWheel*/ ctx[90])) (/*cropEnableZoom*/ ctx[2] && /*handleWheel*/ ctx[90]).apply(this, arguments);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ passive: false }\n\t\t\t\t\t),\n\t\t\t\t\tlisten(div0, \"interactionstart\", /*handleImageDragStart*/ ctx[77]),\n\t\t\t\t\tlisten(div0, \"interactionupdate\", /*handleImageDrag*/ ctx[78]),\n\t\t\t\t\tlisten(div0, \"interactionrelease\", /*handleImageDragRelease*/ ctx[80]),\n\t\t\t\t\tlisten(div0, \"interactionend\", /*handleImageDragEnd*/ ctx[79]),\n\t\t\t\t\taction_destroyer(interactable_action = interactable.call(null, div0, {\n\t\t\t\t\t\tdrag: true,\n\t\t\t\t\t\tinertia: true,\n\t\t\t\t\t\tpinch: /*cropEnableZoom*/ ctx[2],\n\t\t\t\t\t\tshouldStartInteraction: interactable_function$1,\n\t\t\t\t\t\tgetEventPosition: /*interactable_function_1*/ ctx[171]\n\t\t\t\t\t})),\n\t\t\t\t\tlisten(div0, \"gesturedown\", /*handleGestureStart*/ ctx[87]),\n\t\t\t\t\tlisten(div0, \"gestureupdate\", /*handleGestureUpdate*/ ctx[88]),\n\t\t\t\t\tlisten(div0, \"gestureup\", /*handleGestureEnd*/ ctx[89]),\n\t\t\t\t\taction_destroyer(gesturable.call(null, div0))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (/*shouldRenderImageSelection*/ ctx[22] && /*shouldRenderImageSelectionRecenterButton*/ ctx[10]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*shouldRenderImageSelection, shouldRenderImageSelectionRecenterButton*/ 4195328) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_5$2(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div0, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*shouldRenderImageSelection*/ ctx[22]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*shouldRenderImageSelection*/ 4194304) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_4$3(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(div0, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (interactable_action && is_function(interactable_action.update) && dirty[0] & /*cropEnableZoom, $rootRect*/ 67108868) interactable_action.update.call(null, {\n\t\t\t\tdrag: true,\n\t\t\t\tinertia: true,\n\t\t\t\tpinch: /*cropEnableZoom*/ ctx[2],\n\t\t\t\tshouldStartInteraction: interactable_function$1,\n\t\t\t\tgetEventPosition: /*interactable_function_1*/ ctx[171]\n\t\t\t});\n\n\t\t\tif (/*shouldRenderInfoIndicator*/ ctx[11]) {\n\t\t\t\tif (if_block2) {\n\t\t\t\t\tif_block2.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block2 = create_if_block_3$3(ctx);\n\t\t\t\t\tif_block2.c();\n\t\t\t\t\tif_block2.m(div1, null);\n\t\t\t\t}\n\t\t\t} else if (if_block2) {\n\t\t\t\tif_block2.d(1);\n\t\t\t\tif_block2 = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div1);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t\t/*div0_binding*/ ctx[170](null);\n\t\t\tif (if_block2) if_block2.d();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (1694:8) {#if shouldRenderFooter}\nfunction create_if_block$9(ctx) {\n\tlet tablist;\n\tlet t;\n\tlet tabpanels;\n\tlet current;\n\n\tconst tablist_spread_levels = [\n\t\t{ class: \"PinturaControlList\" },\n\t\t{ tabs: /*tabs*/ ctx[7] },\n\t\t/*tabsConfig*/ ctx[19]\n\t];\n\n\tlet tablist_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot_1$3,\n\t\t\t\t({ tab }) => ({ 228: tab }),\n\t\t\t\t({ tab }) => [0, 0, 0, 0, 0, 0, 0, tab ? 2048 : 0]\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tablist_spread_levels.length; i += 1) {\n\t\ttablist_props = assign(tablist_props, tablist_spread_levels[i]);\n\t}\n\n\ttablist = new TabList({ props: tablist_props });\n\ttablist.$on(\"select\", /*select_handler*/ ctx[169]);\n\n\tconst tabpanels_spread_levels = [\n\t\t{ class: \"PinturaControlPanels\" },\n\t\t{ panelClass: \"PinturaControlPanel\" },\n\t\t{ panels: /*panels*/ ctx[18] },\n\t\t/*tabsConfig*/ ctx[19]\n\t];\n\n\tlet tabpanels_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot$a,\n\t\t\t\t({ panel }) => ({ 227: panel }),\n\t\t\t\t({ panel }) => [0, 0, 0, 0, 0, 0, 0, panel ? 1024 : 0]\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tabpanels_spread_levels.length; i += 1) {\n\t\ttabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);\n\t}\n\n\ttabpanels = new TabPanels({ props: tabpanels_props });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(tablist.$$.fragment);\n\t\t\tt = space();\n\t\t\tcreate_component(tabpanels.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(tablist, target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tmount_component(tabpanels, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst tablist_changes = (dirty[0] & /*tabs, tabsConfig*/ 524416)\n\t\t\t? get_spread_update(tablist_spread_levels, [\n\t\t\t\t\ttablist_spread_levels[0],\n\t\t\t\t\tdirty[0] & /*tabs*/ 128 && { tabs: /*tabs*/ ctx[7] },\n\t\t\t\t\tdirty[0] & /*tabsConfig*/ 524288 && get_spread_object(/*tabsConfig*/ ctx[19])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty[7] & /*$$scope, tab*/ 6144) {\n\t\t\t\ttablist_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttablist.$set(tablist_changes);\n\n\t\t\tconst tabpanels_changes = (dirty[0] & /*panels, tabsConfig*/ 786432)\n\t\t\t? get_spread_update(tabpanels_spread_levels, [\n\t\t\t\t\ttabpanels_spread_levels[0],\n\t\t\t\t\ttabpanels_spread_levels[1],\n\t\t\t\t\tdirty[0] & /*panels*/ 262144 && { panels: /*panels*/ ctx[18] },\n\t\t\t\t\tdirty[0] & /*tabsConfig*/ 524288 && get_spread_object(/*tabsConfig*/ ctx[19])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty[0] & /*$elasticityMultiplier, $imageRotation, locale, $imageRotationRange, cropRotationRange, imageZoomLevelMin, $imageZoomLevelRange, $imageZoomLevel*/ 2046853144 | dirty[7] & /*$$scope, panel*/ 5120) {\n\t\t\t\ttabpanels_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttabpanels.$set(tabpanels_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(tablist.$$.fragment, local);\n\t\t\ttransition_in(tabpanels.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(tablist.$$.fragment, local);\n\t\t\ttransition_out(tabpanels.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t}\n\n\t\t\tdestroy_component(tablist, detaching);\n\t\t\tdestroy_component(tabpanels, detaching);\n\t\t}\n\t};\n}\n\n// (1695:12) <TabList                 class=\"PinturaControlList\"                 {tabs}                 {...tabsConfig}                 on:select={({ detail }) => (transformSelected = detail)}                 let:tab             >\nfunction create_default_slot_1$3(ctx) {\n\tlet span;\n\tlet t_value = /*tab*/ ctx[228].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[7] & /*tab*/ 2048 && t_value !== (t_value = /*tab*/ ctx[228].label + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (1725:59) \nfunction create_if_block_2$5(ctx) {\n\tlet rangeinput;\n\tlet current;\n\n\trangeinput = new RangeInput({\n\t\t\tprops: {\n\t\t\t\telasticity: /*$elasticityMultiplier*/ ctx[27] * /*rangeInputElasticity*/ ctx[46],\n\t\t\t\tbase: imageZoomLevelBase,\n\t\t\t\tmin: /*imageZoomLevelMin*/ ctx[25],\n\t\t\t\tmax: imageZoomLevelMax,\n\t\t\t\tvalueMin: /*$imageZoomLevelRange*/ ctx[29][0],\n\t\t\t\tvalueMax: /*$imageZoomLevelRange*/ ctx[29][1],\n\t\t\t\tvalue: /*$imageZoomLevel*/ ctx[30],\n\t\t\t\tlabelReset: /*locale*/ ctx[4].labelReset,\n\t\t\t\tvalueLabel: `${Math.round(/*$imageZoomLevel*/ ctx[30] * 100)}%`,\n\t\t\t\toninputstart: /*handleResizeStart*/ ctx[84],\n\t\t\t\toninputmove: /*handleResizeMove*/ ctx[85],\n\t\t\t\toninputend: /*handleResizeEnd*/ ctx[86]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(rangeinput.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(rangeinput, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst rangeinput_changes = {};\n\t\t\tif (dirty[0] & /*$elasticityMultiplier*/ 134217728) rangeinput_changes.elasticity = /*$elasticityMultiplier*/ ctx[27] * /*rangeInputElasticity*/ ctx[46];\n\t\t\tif (dirty[0] & /*imageZoomLevelMin*/ 33554432) rangeinput_changes.min = /*imageZoomLevelMin*/ ctx[25];\n\t\t\tif (dirty[0] & /*$imageZoomLevelRange*/ 536870912) rangeinput_changes.valueMin = /*$imageZoomLevelRange*/ ctx[29][0];\n\t\t\tif (dirty[0] & /*$imageZoomLevelRange*/ 536870912) rangeinput_changes.valueMax = /*$imageZoomLevelRange*/ ctx[29][1];\n\t\t\tif (dirty[0] & /*$imageZoomLevel*/ 1073741824) rangeinput_changes.value = /*$imageZoomLevel*/ ctx[30];\n\t\t\tif (dirty[0] & /*locale*/ 16) rangeinput_changes.labelReset = /*locale*/ ctx[4].labelReset;\n\t\t\tif (dirty[0] & /*$imageZoomLevel*/ 1073741824) rangeinput_changes.valueLabel = `${Math.round(/*$imageZoomLevel*/ ctx[30] * 100)}%`;\n\t\t\trangeinput.$set(rangeinput_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(rangeinput.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(rangeinput.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(rangeinput, detaching);\n\t\t}\n\t};\n}\n\n// (1712:16) {#if panel === cropUniqueId + '-rotation'}\nfunction create_if_block_1$5(ctx) {\n\tlet imagerotator;\n\tlet current;\n\n\timagerotator = new ImageRotator({\n\t\t\tprops: {\n\t\t\t\telasticity: /*$elasticityMultiplier*/ ctx[27] * /*rangeInputElasticity*/ ctx[46],\n\t\t\t\trotation: /*$imageRotation*/ ctx[15],\n\t\t\t\tlabelReset: /*locale*/ ctx[4].labelReset,\n\t\t\t\tvalueMin: /*$imageRotationRange*/ ctx[28][0],\n\t\t\t\tvalueMax: /*$imageRotationRange*/ ctx[28][1],\n\t\t\t\trotationMin: -/*cropRotationRange*/ ctx[3],\n\t\t\t\trotationMax: /*cropRotationRange*/ ctx[3],\n\t\t\t\toninputstart: /*handleRotateStart*/ ctx[74],\n\t\t\t\toninputmove: /*handleRotateMove*/ ctx[75],\n\t\t\t\toninputend: /*handleRotateEnd*/ ctx[76]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(imagerotator.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(imagerotator, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst imagerotator_changes = {};\n\t\t\tif (dirty[0] & /*$elasticityMultiplier*/ 134217728) imagerotator_changes.elasticity = /*$elasticityMultiplier*/ ctx[27] * /*rangeInputElasticity*/ ctx[46];\n\t\t\tif (dirty[0] & /*$imageRotation*/ 32768) imagerotator_changes.rotation = /*$imageRotation*/ ctx[15];\n\t\t\tif (dirty[0] & /*locale*/ 16) imagerotator_changes.labelReset = /*locale*/ ctx[4].labelReset;\n\t\t\tif (dirty[0] & /*$imageRotationRange*/ 268435456) imagerotator_changes.valueMin = /*$imageRotationRange*/ ctx[28][0];\n\t\t\tif (dirty[0] & /*$imageRotationRange*/ 268435456) imagerotator_changes.valueMax = /*$imageRotationRange*/ ctx[28][1];\n\t\t\tif (dirty[0] & /*cropRotationRange*/ 8) imagerotator_changes.rotationMin = -/*cropRotationRange*/ ctx[3];\n\t\t\tif (dirty[0] & /*cropRotationRange*/ 8) imagerotator_changes.rotationMax = /*cropRotationRange*/ ctx[3];\n\t\t\timagerotator.$set(imagerotator_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(imagerotator.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(imagerotator.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(imagerotator, detaching);\n\t\t}\n\t};\n}\n\n// (1705:12) <TabPanels                 class=\"PinturaControlPanels\"                 panelClass=\"PinturaControlPanel\"                 {panels}                 {...tabsConfig}                 let:panel             >\nfunction create_default_slot$a(ctx) {\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet if_block_anchor;\n\tlet current;\n\tconst if_block_creators = [create_if_block_1$5, create_if_block_2$5];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*panel*/ ctx[227] === /*cropUniqueId*/ ctx[96] + '-rotation') return 0;\n\t\tif (/*panel*/ ctx[227] === /*cropUniqueId*/ ctx[96] + '-zoom') return 1;\n\t\treturn -1;\n\t}\n\n\tif (~(current_block_type_index = select_block_type(ctx))) {\n\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block) if_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\t}\n\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tgroup_outros();\n\n\t\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\t\tif (!if_block) {\n\t\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\t\tif_block.c();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t\t}\n\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = null;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (1693:4) \nfunction create_footer_slot$6(ctx) {\n\tlet div;\n\tlet current;\n\tlet if_block = /*shouldRenderFooter*/ ctx[20] && create_if_block$9(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(div, \"slot\", \"footer\");\n\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[17]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*shouldRenderFooter*/ ctx[20]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*shouldRenderFooter*/ 1048576) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$9(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleFooterTransform*/ 131072) {\n\t\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[17]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t}\n\t};\n}\n\nfunction create_fragment$k(ctx) {\n\tlet util;\n\tlet updating_root;\n\tlet current;\n\n\tfunction util_root_binding(value) {\n\t\t/*util_root_binding*/ ctx[172](value);\n\t}\n\n\tlet util_props = {\n\t\thasHeader: /*shouldRenderToolbar*/ ctx[21],\n\t\t$$slots: {\n\t\t\tfooter: [create_footer_slot$6],\n\t\t\tmain: [create_main_slot$1],\n\t\t\theader: [create_header_slot$1]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tif (/*root*/ ctx[16] !== void 0) {\n\t\tutil_props.root = /*root*/ ctx[16];\n\t}\n\n\tutil = new Util({ props: util_props });\n\tbinding_callbacks.push(() => bind(util, 'root', util_root_binding));\n\tutil.$on(\"measure\", /*measure_handler*/ ctx[173]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(util.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(util, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst util_changes = {};\n\t\t\tif (dirty[0] & /*shouldRenderToolbar*/ 2097152) util_changes.hasHeader = /*shouldRenderToolbar*/ ctx[21];\n\n\t\t\tif (dirty[0] & /*styleFooterTransform, panels, tabsConfig, $elasticityMultiplier, $imageRotation, locale, $imageRotationRange, cropRotationRange, imageZoomLevelMin, $imageZoomLevelRange, $imageZoomLevel, tabs, transformSelected, shouldRenderFooter, isImageInfoCustom, imageInfo, shouldRenderInfoIndicator, stageRef, cropEnableZoom, $rootRect, imageSelectionRectOffset, $utilRectPadded, $isActive, cropImageSelectionCornerStyle, shouldRenderImageSelection, canCenter, shouldRenderImageSelectionRecenterButton, cropTools*/ 2145320958 | dirty[1] & /*$recenterOpacity, $recenterOffset*/ 3 | dirty[7] & /*$$scope*/ 4096) {\n\t\t\t\tutil_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tif (!updating_root && dirty[0] & /*root*/ 65536) {\n\t\t\t\tupdating_root = true;\n\t\t\t\tutil_changes.root = /*root*/ ctx[16];\n\t\t\t\tadd_flush_callback(() => updating_root = false);\n\t\t\t}\n\n\t\t\tutil.$set(util_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(util.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(util.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(util, detaching);\n\t\t}\n\t};\n}\n\nconst imageZoomLevelMax = 1;\nconst imageZoomLevelBase = 0;\nconst interactable_function$1 = (e, element) => e.target === element;\n\nfunction instance$k($$self, $$props, $$invalidate) {\n\tlet hasCropSelectPresetOptions;\n\tlet cropTools;\n\tlet imageZoomLevelMin;\n\tlet imageSelectionOffset;\n\tlet imageSelectionCenter;\n\tlet imageSelectionCenteredRect;\n\tlet isImageSelectionDisplayed;\n\tlet isImageSelectionCentered;\n\tlet isResizingSelection;\n\tlet isMaxSelectionRect;\n\tlet isOverlayMode;\n\tlet canZoomToCenter;\n\tlet canCenter;\n\tlet shouldRenderInfoIndicator;\n\tlet isImageInfoCustom;\n\tlet imageInfo;\n\tlet shouldRenderImageSelection;\n\tlet shouldRenderImageSelectionRecenterButton;\n\tlet imageSelectionRectOffset;\n\tlet hasPlentyVerticalSpace;\n\tlet shouldRenderPresetSelect;\n\tlet shouldRenderToolbar;\n\tlet couldRenderZoomInput;\n\tlet shouldRenderZoomInput;\n\tlet shouldRenderFooter;\n\tlet tabsConfig;\n\tlet tabs;\n\tlet panels;\n\tlet styleFooterTransform;\n\tlet $footerOffset;\n\n\tlet $isActive,\n\t\t$$unsubscribe_isActive = noop,\n\t\t$$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(13, $isActive = $$value)), isActive);\n\n\tlet $isAnimated;\n\tlet $env;\n\tlet $imageSelectionGuides;\n\tlet $stagePadded;\n\tlet $imagePreviewModifiers;\n\tlet $imageSelectionRectPresentation;\n\tlet $isInteracting;\n\tlet $imageIsStatic;\n\tlet $imageOutputSize;\n\tlet $imageCropRect;\n\tlet $imageScalar;\n\tlet $presentationScalar;\n\tlet $utilRectPadded;\n\tlet $imageSelectionRectSnapshot;\n\tlet $imageSelectionRect;\n\tlet $stageRect;\n\tlet $isTransformingImage;\n\tlet $imageCropRangeAspectRatio;\n\tlet $imageSize;\n\tlet $imageRotation;\n\tlet $imageCropLimitToImage;\n\tlet $imageCropMinSize;\n\tlet $fixScrollDirectionStore;\n\tlet $rootRect;\n\tlet $imageCropRectIntent;\n\tlet $imageCropRange;\n\tlet $imageCropRectOrigin;\n\tlet $imageCropAspectRatio;\n\tlet $imageCropMaxSize;\n\tlet $imageStaticVisualCorners;\n\tlet $imageSelectionRectIntent;\n\tlet $utilTools;\n\tlet $selectedPresetIndex;\n\tlet $currentPresetFilter;\n\tlet $formattedCropPresetOptions;\n\tlet $imageFlipY;\n\tlet $imageFlipX;\n\tlet $redrawTrigger;\n\tlet $elasticityMultiplier;\n\tlet $imageRotationRange;\n\tlet $imageZoomLevelRange;\n\tlet $imageZoomLevel;\n\tlet $recenterOpacity;\n\tlet $recenterOffset;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActive());\n\tconst name = 'crop';\n\tlet { isActive } = $$props;\n\t$$subscribe_isActive();\n\tlet { stores } = $$props;\n\tlet { cropImageSelectionCornerStyle = 'circle' } = $$props;\n\n\tlet { cropWillRenderImageSelectionGuides = (interaction, interactionFraction) => {\n\t\tconst isRotating = interaction == 'rotate';\n\n\t\treturn {\n\t\t\trows: isRotating ? 5 : 3,\n\t\t\tcols: isRotating ? 5 : 3,\n\t\t\topacity: interactionFraction * 0.25\n\t\t};\n\t} } = $$props;\n\n\tlet { cropAutoCenterImageSelectionTimeout = undefined } = $$props;\n\tlet { cropEnableZoomMatchImageAspectRatio = true } = $$props;\n\tlet { cropEnableRotateMatchImageAspectRatio = 'never' } = $$props;\n\tlet { cropEnableRotationInput = true } = $$props;\n\tlet { cropEnableZoom = true } = $$props;\n\tlet { cropEnableZoomInput = true } = $$props;\n\tlet { cropEnableZoomAutoHide = true } = $$props;\n\tlet { cropEnableImageSelection = true } = $$props;\n\tlet { cropEnableInfoIndicator = false } = $$props;\n\tlet { cropEnableZoomTowardsWheelPosition = true } = $$props;\n\tlet { cropEnableLimitWheelInputToCropSelection = true } = $$props;\n\tlet { cropEnableCenterImageSelection = true } = $$props;\n\tlet { cropEnableButtonRotateLeft = true } = $$props;\n\tlet { cropEnableButtonRotateRight = false } = $$props;\n\tlet { cropEnableButtonFlipHorizontal = true } = $$props;\n\tlet { cropEnableButtonFlipVertical = false } = $$props;\n\tlet { cropSelectPresetOptions = undefined } = $$props;\n\tlet { cropEnableSelectPreset = true } = $$props;\n\tlet { cropEnableFilterMatchAspectRatio = true } = $$props;\n\tlet { cropSelectPresetFilter = false } = $$props;\n\tlet { cropEnableButtonToggleCropLimit = false } = $$props;\n\tlet { cropWillRenderTools = passthrough } = $$props;\n\tlet { cropWillRenderInfoIndicator = undefined } = $$props;\n\tlet { cropActiveTransformTool = 'rotation' } = $$props;\n\tlet { cropMinimizeToolbar = 'auto' } = $$props;\n\tlet { cropInteractionFocus = 'image' } = $$props;\n\tlet { cropRotationRange = QUART_PI } = $$props;\n\tlet { cropMaskOpacity = 0.85 } = $$props;\n\tlet { locale = {} } = $$props;\n\n\tlet { cropFormatIconSelectPreset = function (values) {\n\t\tconst { aspectRatio } = values;\n\n\t\tconst [a, b, c] = !aspectRatio\n\t\t? [0.2, 0.3, 0.4]\n\t\t: [\n\t\t\t\taspectRatio < 1 ? 1 : 0.3,\n\t\t\t\taspectRatio === 1 ? 0.85 : 0.5,\n\t\t\t\taspectRatio > 1 ? 1 : 0.3\n\t\t\t];\n\n\t\treturn { a, b, c };\n\t} } = $$props;\n\n\tlet { cropFormatIconCropBoundary = function (values) {\n\t\tconst { isBoundToImage } = values;\n\t\tconst [a, b, c, d] = isBoundToImage ? [0.3, 1, 0, 0] : [0, 0, 0.3, 1];\n\t\treturn { a, b, c, d };\n\t} } = $$props;\n\n\t// context\n\tconst isAnimated = getContext('isAnimated');\n\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(145, $isAnimated = value));\n\tconst elasticityMultiplier = getContext('elasticityMultiplier');\n\tcomponent_subscribe($$self, elasticityMultiplier, value => $$invalidate(27, $elasticityMultiplier = value));\n\tconst redrawTrigger = getContext('redrawTrigger');\n\tcomponent_subscribe($$self, redrawTrigger, value => $$invalidate(167, $redrawTrigger = value));\n\tconst imageIsStatic = getContext('imageIsStatic');\n\tcomponent_subscribe($$self, imageIsStatic, value => $$invalidate(151, $imageIsStatic = value));\n\tconst imageStaticVisualCorners = getContext('imageStaticVisualCorners');\n\tcomponent_subscribe($$self, imageStaticVisualCorners, value => $$invalidate(189, $imageStaticVisualCorners = value));\n\tconst fixScrollDirectionStore = getContext('fixScrollDirection');\n\tcomponent_subscribe($$self, fixScrollDirectionStore, value => $$invalidate(183, $fixScrollDirectionStore = value));\n\n\t// state\n\tlet interaction = 'idle';\n\n\t// formatted crop select options\n\tconst formattedCropPresetOptions = writable();\n\n\tcomponent_subscribe($$self, formattedCropPresetOptions, value => $$invalidate(164, $formattedCropPresetOptions = value));\n\n\t// #region helpers\n\tconst isCustomCrop = () => $imageCropAspectRatio === undefined;\n\n\tconst turnAspectRatio = aspectRatio => 1 / aspectRatio;\n\n\tconst applyCropPresetFilter = filter => {\n\t\t// no change\n\t\tif (!cropEnableFilterMatchAspectRatio || $currentPresetFilter === filter) return;\n\n\t\t// change\n\t\tcurrentPresetFilter.set(filter);\n\n\t\t// square or free, exit\n\t\tif (!$imageCropAspectRatio || $imageCropAspectRatio === 1) return;\n\n\t\tif (!hasValidRotatedCropAspectRatio()) return;\n\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = turnAspectRatio($imageCropAspectRatio), $imageCropAspectRatio);\n\t\thistory.write();\n\t};\n\n\tconst hasValidRotatedCropAspectRatio = () => {\n\t\t// no options available, forced crop aspect ratio\n\t\tif ($imageCropAspectRatio === 1 || !hasCropSelectPresetOptions) return false;\n\n\t\t// get rotated\n\t\tconst rotatedImageCropAspectRatio = turnAspectRatio($imageCropAspectRatio);\n\n\t\t// options available but no valid option in list\n\t\tif (!flattenOptions($formattedCropPresetOptions).find(([aspectRatio]) => aspectRatio === rotatedImageCropAspectRatio)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tconst isCropMaxSize = (imageCropRect, imageSize, imageRotation) => isRotatedSideways(imageRotation)\n\t? imageSize.width === Math.round(imageCropRect.height) || imageSize.height === Math.round(imageCropRect.width)\n\t: imageSize.width === Math.round(imageCropRect.width) || imageSize.height === Math.round(imageCropRect.height);\n\n\tconst isCropCentered = (imageCropRect, imageSize, imageRotation) => {\n\t\tconst imageSizeRotated = sizeApply(sizeRotate(sizeClone(imageSize), imageRotation), v => Math.abs(Math.round(v)));\n\t\tconst imageCenter = sizeCenter(imageSizeRotated);\n\t\tconst cropCenter = rectCenter(imageCropRect);\n\t\treturn vectorEqual(imageCenter, cropCenter);\n\t};\n\n\tconst canMatchCropAspectRatioToRotation = () => // is custom crop mode\n\t(isCustomCrop() || // can match preset crop and preset is available\n\tcropEnableRotateMatchImageAspectRatio === 'always' && hasValidRotatedCropAspectRatio()) && isCropCentered($imageCropRect, $imageSize, $imageRotation) && isCropMaxSize($imageCropRect, $imageSize, $imageRotation);\n\n\tconst applyRotation = value => {\n\t\tif (cropEnableRotateMatchImageAspectRatio !== 'never' && canMatchCropAspectRatioToRotation()) {\n\t\t\tset_store_value(imageRotation, $imageRotation += value, $imageRotation);\n\t\t\tconst isRotated = isRotatedSideways($imageRotation);\n\t\t\tconst w = isRotated ? $imageSize.height : $imageSize.width;\n\t\t\tconst h = isRotated ? $imageSize.width : $imageSize.height;\n\t\t\tset_store_value(imageCropRect, $imageCropRect = rectCreate(0, 0, w, h), $imageCropRect);\n\t\t\tif (!isCustomCrop()) set_store_value(imageCropAspectRatio, $imageCropAspectRatio = getAspectRatio(w, h), $imageCropAspectRatio);\n\t\t} else {\n\t\t\tset_store_value(imageRotation, $imageRotation += value, $imageRotation);\n\t\t}\n\t};\n\n\t//#endregion\n\tconst { history, env, isInteracting, isInteractingFraction, isTransformingImage, rootRect, stageRect, utilRect, utilRectPadded, rootLineColor, allowPan, allowZoom, allowPlayPause, rangeInputElasticity, presentationScalar, utilTools, // effect filtering\n\timagePreviewModifiers, imageOutlineOpacity, // crop selection\n\timageFlipX, imageFlipY, imageRotation, imageRotationRange, imageOutputSize, imageSelectionRect, imageSelectionRectSnapshot, imageSelectionRectIntent, imageSelectionRectPresentation, imageCropRectIntent, imageCropRectOrigin, imageCropRect, imageCropMinSize, imageCropMaxSize, imageCropRange, imageCropAspectRatio, imageCropLimitToImage, imageSize, imageScalar, imageOverlayMarkup, stagePadded, stageRecenter } = stores;\n\n\tcomponent_subscribe($$self, env, value => $$invalidate(146, $env = value));\n\tcomponent_subscribe($$self, isInteracting, value => $$invalidate(150, $isInteracting = value));\n\tcomponent_subscribe($$self, isTransformingImage, value => $$invalidate(181, $isTransformingImage = value));\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(26, $rootRect = value));\n\tcomponent_subscribe($$self, stageRect, value => $$invalidate(158, $stageRect = value));\n\tcomponent_subscribe($$self, utilRectPadded, value => $$invalidate(14, $utilRectPadded = value));\n\tcomponent_subscribe($$self, presentationScalar, value => $$invalidate(155, $presentationScalar = value));\n\tcomponent_subscribe($$self, utilTools, value => $$invalidate(191, $utilTools = value));\n\tcomponent_subscribe($$self, imagePreviewModifiers, value => $$invalidate(180, $imagePreviewModifiers = value));\n\tcomponent_subscribe($$self, imageFlipX, value => $$invalidate(166, $imageFlipX = value));\n\tcomponent_subscribe($$self, imageFlipY, value => $$invalidate(165, $imageFlipY = value));\n\tcomponent_subscribe($$self, imageRotation, value => $$invalidate(15, $imageRotation = value));\n\tcomponent_subscribe($$self, imageRotationRange, value => $$invalidate(28, $imageRotationRange = value));\n\tcomponent_subscribe($$self, imageOutputSize, value => $$invalidate(152, $imageOutputSize = value));\n\tcomponent_subscribe($$self, imageSelectionRect, value => $$invalidate(157, $imageSelectionRect = value));\n\tcomponent_subscribe($$self, imageSelectionRectSnapshot, value => $$invalidate(156, $imageSelectionRectSnapshot = value));\n\tcomponent_subscribe($$self, imageSelectionRectIntent, value => $$invalidate(190, $imageSelectionRectIntent = value));\n\tcomponent_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(149, $imageSelectionRectPresentation = value));\n\tcomponent_subscribe($$self, imageCropRectIntent, value => $$invalidate(184, $imageCropRectIntent = value));\n\tcomponent_subscribe($$self, imageCropRectOrigin, value => $$invalidate(186, $imageCropRectOrigin = value));\n\tcomponent_subscribe($$self, imageCropRect, value => $$invalidate(153, $imageCropRect = value));\n\tcomponent_subscribe($$self, imageCropMinSize, value => $$invalidate(161, $imageCropMinSize = value));\n\tcomponent_subscribe($$self, imageCropMaxSize, value => $$invalidate(188, $imageCropMaxSize = value));\n\tcomponent_subscribe($$self, imageCropRange, value => $$invalidate(185, $imageCropRange = value));\n\tcomponent_subscribe($$self, imageCropAspectRatio, value => $$invalidate(187, $imageCropAspectRatio = value));\n\tcomponent_subscribe($$self, imageCropLimitToImage, value => $$invalidate(160, $imageCropLimitToImage = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(159, $imageSize = value));\n\tcomponent_subscribe($$self, imageScalar, value => $$invalidate(154, $imageScalar = value));\n\tcomponent_subscribe($$self, stagePadded, value => $$invalidate(148, $stagePadded = value));\n\n\tfunction getCropSelectPresetIcon(locale, aspectRatio) {\n\t\treturn isFunction(locale.cropIconSelectPreset)\n\t\t? localize(locale.cropIconSelectPreset, locale, aspectRatio)\n\t\t: stringReplace(locale.cropIconSelectPreset, cropFormatIconSelectPreset({ aspectRatio }), '{', '}');\n\t}\n\n\tfunction getCropLimitIcon(locale, isBoundToImage) {\n\t\treturn isFunction(locale.cropIconCropBoundary)\n\t\t? localize(locale.cropIconCropBoundary, locale, isBoundToImage)\n\t\t: stringReplace(locale.cropIconCropBoundary, cropFormatIconCropBoundary({ isBoundToImage }), '{', '}');\n\t}\n\n\t// which preset filter to use\n\tconst currentPresetFilter = writable(cropSelectPresetFilter);\n\n\tcomponent_subscribe($$self, currentPresetFilter, value => $$invalidate(163, $currentPresetFilter = value));\n\n\t// #endregion\n\t// #region adjusting crop selection\n\tlet imageSelectionTranslator;\n\n\tconst handleSelectionGrab = () => {\n\t\tinteraction = 'select';\n\n\t\t// now interacting\n\t\tset_store_value(isInteracting, $isInteracting = true, $isInteracting);\n\n\t\t// we remember the current view rect and crop rect, because that is the crop rect we use as a starting point to transform while dragging\n\t\tset_store_value(imageSelectionRectSnapshot, $imageSelectionRectSnapshot = rectClone($imageSelectionRect), $imageSelectionRectSnapshot);\n\n\t\t// which translator to use\n\t\timageSelectionTranslator = $imageIsStatic\n\t\t? translateStaticSelection\n\t\t: translateImageSelection;\n\t};\n\n\tconst handleSelectionDrag = ({ detail }) => {\n\t\tconst { boundsLimited, boundsIntent } = imageSelectionTranslator(detail.direction, detail.translation);\n\n\t\t// now transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = true, $isTransformingImage);\n\n\t\t// update actual image selection rectangle\n\t\tset_store_value(imageSelectionRectIntent, $imageSelectionRectIntent = boundsIntent, $imageSelectionRectIntent); // intent needs to be updated first because has no listeners attached\n\n\t\tset_store_value(imageSelectionRect, $imageSelectionRect = boundsLimited, $imageSelectionRect);\n\t};\n\n\tconst handleSelectionRelease = ({ detail }) => {\n\t\tconst { boundsLimited } = imageSelectionTranslator(detail.direction, detail.translation);\n\n\t\t// no longer transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t// we're no longer interacting with the image selection, we need to set this here so the image selection presentation is animated when applying the new bounds below\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t// no more intent as we're finalizing the selection, so before setting the final selection, we set this to undefined | intent needs to be updated first because has no listeners attached\n\t\tset_store_value(imageSelectionRectIntent, $imageSelectionRectIntent = undefined, $imageSelectionRectIntent);\n\n\t\t// confirm the limited rect if actually made a change\n\t\tif (vectorLength(detail.translation)) {\n\t\t\tset_store_value(imageSelectionRect, $imageSelectionRect = boundsLimited, $imageSelectionRect);\n\t\t\thistory.write();\n\t\t}\n\n\t\t// need to set this to undefined after setting the final rect, the snapshot is used to calculate the crop rect transform\n\t\tset_store_value(imageSelectionRectSnapshot, $imageSelectionRectSnapshot = undefined, $imageSelectionRectSnapshot);\n\n\t\t// done interacting with selection\n\t\tinteraction = undefined;\n\t};\n\n\tconst translateStaticSelection = (target, translate) => {\n\t\t// - selection may grow to max bounds (util bounds when _not_ static image)\n\t\t// - when image is static selection may grow to image polygon edges\n\t\t// - when not static image the image preview(!) is scaled to fit the selection, actual image size is not affected\n\t\t// - we always need to make sure the selection adheres to the aspect ratio of the min size\n\t\tconst directionTranslation = { target, translate };\n\n\t\tconst imageSelectionRectMinSize = sizeScale(sizeClone($imageCropMinSize), $presentationScalar);\n\t\tconst imageSelectionRectMaxSize = sizeScale(sizeClone($imageCropMaxSize), $presentationScalar);\n\n\t\t// make sure not smaller\n\t\tlet rectIntended = limitRectDirectionTranslation($imageSelectionRectSnapshot, directionTranslation, { ...$utilRectPadded, x: 0, y: 0 }, {\n\t\t\taspectRatio: $imageCropAspectRatio,\n\t\t\tminSize: imageSelectionRectMinSize,\n\t\t\tmaxSize: imageSelectionRectMaxSize\n\t\t});\n\n\t\t// limit selection rect to util bounds\n\t\trectIntended = rectLimitInRect(rectIntended, { ...$utilRectPadded, x: 0, y: 0 }, $imageCropAspectRatio);\n\n\t\t// no limits\n\t\tif (!$imageCropLimitToImage) {\n\t\t\treturn {\n\t\t\t\tboundsLimited: rectIntended,\n\t\t\t\tboundsIntent: rectIntended\n\t\t\t};\n\t\t}\n\n\t\t// limit to image\n\t\tlet rectLimited = getRectLimitedToQuad($imageSelectionRectSnapshot, rectIntended, directionTranslation, $imageStaticVisualCorners, {\n\t\t\taspectRatio: $imageCropAspectRatio,\n\t\t\tminSize: imageSelectionRectMinSize,\n\t\t\tmaxSize: imageSelectionRectMaxSize\n\t\t});\n\n\t\treturn {\n\t\t\tboundsLimited: rectLimited,\n\t\t\tboundsIntent: rectLimited\n\t\t};\n\t};\n\n\tconst translateImageSelection = (target, translate) => {\n\t\tconst directionTranslation = { target, translate };\n\t\tconst imageSelectionRectMinSize = sizeScale(sizeClone($imageCropMinSize), $presentationScalar);\n\t\tconst imageSelectionRectMaxSize = sizeScale(sizeClone($imageCropMaxSize), $presentationScalar);\n\n\t\tconst rectIntended = applyRectDirectionTranslation($imageSelectionRectSnapshot, directionTranslation, {\n\t\t\taspectRatio: $imageCropAspectRatio,\n\t\t\t// used to make sure that min size is respected when dragging from centered anchor point (dragging edge), if we don't do this we get unwanted elastic effects when the presented image is scaled while dragging an edge\n\t\t\tminSize: imageSelectionRectMinSize\n\t\t});\n\n\t\t// limit rectangle to util bounds\n\t\tconst rectLimited = limitRectDirectionTranslation($imageSelectionRectSnapshot, directionTranslation, { ...$utilRectPadded, x: 0, y: 0 }, {\n\t\t\taspectRatio: $imageCropAspectRatio,\n\t\t\tminSize: imageSelectionRectMinSize,\n\t\t\tmaxSize: imageSelectionRectMaxSize\n\t\t});\n\n\t\treturn {\n\t\t\tboundsLimited: rectLimited,\n\t\t\tboundsIntent: rectIntended\n\t\t};\n\t};\n\n\t// #endregion\n\t// #region rotating\n\tconst handleRotateStart = () => {\n\t\tinteraction = 'rotate';\n\n\t\t// now interacting with view\n\t\tset_store_value(isInteracting, $isInteracting = true, $isInteracting);\n\n\t\t// we need to know the origin of the crop so we can \"shrink\" the image to fit the crop rect while rotating\n\t\tset_store_value(imageCropRectOrigin, $imageCropRectOrigin = rectClone($imageCropRect), $imageCropRectOrigin);\n\t};\n\n\tconst handleRotateMove = value => {\n\t\t// now transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = true, $isTransformingImage);\n\n\t\tset_store_value(imageRotation, $imageRotation = value, $imageRotation); // will auto validate\n\t};\n\n\tconst handleRotateEnd = value => {\n\t\t// no longer transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t// we're done interacting\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t// apply our final rotation value\n\t\tset_store_value(imageRotation, $imageRotation = value, $imageRotation);\n\n\t\thistory.write();\n\n\t\t// done, so we no longer need to \"shrink\" the image\n\t\tset_store_value(imageCropRectOrigin, $imageCropRectOrigin = undefined, $imageCropRectOrigin);\n\t};\n\n\t// #endregion\n\t// #region moving\n\tlet interactionCropRect = undefined;\n\n\tlet interactionCropRectForce = undefined;\n\n\tconst handleImageDragStart = () => {\n\t\tinteraction = 'pan';\n\t\tinteractionCropRectForce = undefined;\n\t\tset_store_value(isInteracting, $isInteracting = true, $isInteracting);\n\t\tinteractionCropRect = rectClone($imageCropRect);\n\t};\n\n\tconst handleImageDrag = ({ detail }) => {\n\t\t// now transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = true, $isTransformingImage);\n\n\t\tmanipulateImage(detail);\n\t};\n\n\tconst handleImageDragEnd = ({ detail }) => {\n\t\t// no longer transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t// done interacting\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t// apply translation to the crop rect only if did make changes\n\t\tif (vectorLength(detail.translation) > 0 || detail.scalar !== 0) {\n\t\t\tmanipulateImage(detail);\n\t\t\thistory.write();\n\t\t}\n\n\t\t// no intent (needs to be set before crop rect is updated)\n\t\tset_store_value(imageCropRectIntent, $imageCropRectIntent = undefined, $imageCropRectIntent);\n\n\t\t// now done\n\t\tinteractionCropRect = undefined;\n\t};\n\n\tconst handleImageDragRelease = ({ detail: { translation } }) => {\n\t\t// flip translation direction as we are dragging crop selection\n\t\tif ($imageIsStatic) translation = vectorInvert(vectorClone(translation));\n\n\t\tinteractionCropRectForce = translation;\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\t};\n\n\tconst manipulateImage = ({ translation, scalar }) => {\n\t\t// flip translation direction as we are dragging crop selection\n\t\tif ($imageIsStatic) {\n\t\t\tscalar = 1;\n\t\t\ttranslation = vectorInvert(vectorClone(translation));\n\t\t}\n\n\t\tconst imageSelectionRectZoomFactor = Math.min($imageSelectionRect.width / $imageCropRect.width, $imageSelectionRect.height / $imageCropRect.height);\n\t\tconst scaledTranslation = vectorMultiply(vectorClone(translation), 1 / imageSelectionRectZoomFactor);\n\n\t\t// while we're interacting we apply changes to the original crop rectangle, after we apply a force\n\t\tlet cropIntent;\n\n\t\tif (!interactionCropRectForce) {\n\t\t\tcropIntent = rectTranslate(rectClone(interactionCropRect), vectorInvert(vectorClone(scaledTranslation)));\n\t\t\tif (scalar !== undefined) rectScale(cropIntent, 1 / scalar);\n\t\t} else {\n\t\t\t// we apply the force to the existing crop rect so animation is not borked\n\t\t\tconst forceTranslation = vectorSubtract(vectorClone(interactionCropRectForce), translation);\n\n\t\t\tinteractionCropRectForce = translation;\n\t\t\tcropIntent = rectTranslate(rectClone($imageCropRect), forceTranslation);\n\t\t}\n\n\t\t// update crop rect\n\t\tset_store_value(imageCropRectIntent, $imageCropRectIntent = cropIntent, $imageCropRectIntent); // auto calculates an elastic effect if bounds exceeded (needs to be set before crop rect is updated)\n\n\t\tset_store_value(imageCropRect, $imageCropRect = cropIntent, $imageCropRect); // auto limits to bounds if needed\n\t};\n\n\t// #endregion\n\t// #region resize with range input\n\tconst IMAGE_ZOOM_LEVEL_MIN = -1;\n\n\tconst calculateZoomLevel = (imageSize, size, imageRotation) => {\n\t\tif (isRotatedSideways(imageRotation)) {\n\t\t\treturn 1 - 1 / Math.min(imageSize.height / size.width, imageSize.width / size.height);\n\t\t}\n\n\t\treturn 1 - 1 / Math.min(imageSize.width / size.width, imageSize.height / size.height);\n\t};\n\n\tconst imageCropRangeAspectRatio = derived([imageCropRange, imageCropRect], ([$imageCropRange, $imageCropRect], set) => {\n\t\tif (!$imageCropRect) return;\n\t\tconst [minSize, maxSize] = $imageCropRange;\n\t\tconst aspectRatio = rectAspectRatio($imageCropRect);\n\n\t\tset([\n\t\t\tsizeCreateFromRect(rectApply(rectCoverRect(minSize, aspectRatio), fixPrecision)),\n\t\t\tsizeCreateFromRect(rectApply(rectContainRect(maxSize, aspectRatio), fixPrecision))\n\t\t]);\n\t});\n\n\tcomponent_subscribe($$self, imageCropRangeAspectRatio, value => $$invalidate(182, $imageCropRangeAspectRatio = value));\n\n\t// this is the max value range that can be set (triggers white range indicator bar)\n\tconst imageZoomLevelRange = derived(\n\t\t[\n\t\t\timageSize,\n\t\t\timageCropLimitToImage,\n\t\t\timageCropMinSize,\n\t\t\timageCropMaxSize,\n\t\t\timageCropRange,\n\t\t\timageRotation\n\t\t],\n\t\t([\n\t\t\t\t$imageSize,\n\t\t\t\t$imageCropLimitToImage,\n\t\t\t\t$imageCropMinSize,\n\t\t\t\t$imageCropMaxSize,\n\t\t\t\t$imageCropRange,\n\t\t\t\t$imageRotation\n\t\t\t], set) => {\n\t\t\tif (!$imageSize) return;\n\t\t\tconst rangeMinSize = $imageCropRange[0];\n\t\t\tconst rangeMaxSize = $imageCropRange[1];\n\t\t\tlet minZoom;\n\t\t\tlet maxZoom;\n\n\t\t\t// can't zoom out\n\t\t\tif ($imageCropLimitToImage) {\n\t\t\t\tminZoom = calculateZoomLevel($imageSize, rangeMaxSize, $imageRotation);\n\t\t\t\tmaxZoom = Math.min(rangeMinSize.width / $imageCropMinSize.width, rangeMinSize.height / $imageCropMinSize.height);\n\t\t\t} else {\n\t\t\t\tminZoom = IMAGE_ZOOM_LEVEL_MIN;\n\t\t\t\tmaxZoom = 1;\n\t\t\t}\n\n\t\t\tconst range = [minZoom, maxZoom].map(v => fixPrecision(v));\n\t\t\tset(range);\n\t\t}\n\t);\n\n\tcomponent_subscribe($$self, imageZoomLevelRange, value => $$invalidate(29, $imageZoomLevelRange = value));\n\n\tconst imageZoomLevel = derived([imageSize, imageCropRect, imageCropRange, imageRotation], ([$imageSize, $imageCropRect, $imageCropRange, $imageRotation], set) => {\n\t\t// need to check if this value is set, could be that it's empty while loading a new image\n\t\tif (!$imageSize || !$imageCropRect) return set(0);\n\n\t\tlet z;\n\t\tconst rangeMinSize = $imageCropRange[0];\n\t\tconst rangeMaxSize = $imageCropRange[1];\n\t\tconst currentCropWidth = $imageCropRect.width;\n\t\tconst currentCropHeight = $imageCropRect.height;\n\t\tconst currentCropAspectRatio = rectAspectRatio($imageCropRect);\n\n\t\tconst imageRect = isRotatedSideways($imageRotation)\n\t\t? sizeCreate($imageSize.height, $imageSize.width)\n\t\t: $imageSize;\n\n\t\tconst imageCropMaxRect = rectContainRect(imageRect, currentCropAspectRatio);\n\n\t\tif (currentCropWidth <= imageCropMaxRect.width || currentCropHeight <= imageCropMaxRect.height) {\n\t\t\t// zoomed in\n\t\t\tconst w = imageCropMaxRect.width - rangeMinSize.width;\n\n\t\t\tconst h = imageCropMaxRect.height - rangeMinSize.height;\n\n\t\t\t// cannot zoom in\n\t\t\tif (w === 0 || h === 0) {\n\t\t\t\tz = 1;\n\t\t\t} else {\n\t\t\t\tz = 1 - Math.min((currentCropWidth - rangeMinSize.width) / w, (currentCropHeight - rangeMinSize.height) / h);\n\t\t\t}\n\t\t} else {\n\t\t\t// zoomed out\n\t\t\tconst w = rangeMaxSize.width - imageCropMaxRect.width;\n\n\t\t\tconst h = rangeMaxSize.height - imageCropMaxRect.height;\n\t\t\tconst r = rectContainRect({ width: w, height: h }, currentCropAspectRatio);\n\t\t\tz = -Math.min((currentCropWidth - imageCropMaxRect.width) / r.width, (currentCropHeight - imageCropMaxRect.height) / r.height);\n\t\t}\n\n\t\tset(z);\n\t});\n\n\tcomponent_subscribe($$self, imageZoomLevel, value => $$invalidate(30, $imageZoomLevel = value));\n\n\tconst snapshotCropRect = () => {\n\t\tinteractionCropRect = rectClone($imageCropRect);\n\t};\n\n\tconst resizeImage = zoom => {\n\t\tconst aspectRatio = rectAspectRatio(interactionCropRect);\n\t\tlet targetWidth;\n\t\tlet targetHeight;\n\t\tlet r;\n\n\t\tconst imageRect = isRotatedSideways($imageRotation)\n\t\t? sizeCreate($imageSize.height, $imageSize.width)\n\t\t: $imageSize;\n\n\t\tconst imageCropMaxRect = rectContainRect(imageRect, aspectRatio);\n\n\t\tif (zoom >= 0) {\n\t\t\t// zoom in\n\t\t\tconst rangeWidth = imageCropMaxRect.width - $imageCropRange[0].width;\n\n\t\t\tconst rangeHeight = imageCropMaxRect.height - $imageCropRange[0].height;\n\t\t\ttargetWidth = imageCropMaxRect.width - rangeWidth * zoom;\n\t\t\ttargetHeight = imageCropMaxRect.height - rangeHeight * zoom;\n\t\t\tr = rectCoverRect({ width: targetWidth, height: targetHeight }, aspectRatio);\n\t\t} else {\n\t\t\t// zoom out\n\t\t\tconst rangeWidth = $imageCropRange[1].width - imageCropMaxRect.width;\n\n\t\t\tconst rangeHeight = $imageCropRange[1].height - imageCropMaxRect.height;\n\t\t\ttargetWidth = imageCropMaxRect.width + rangeWidth * -zoom;\n\t\t\ttargetHeight = imageCropMaxRect.height + rangeHeight * -zoom;\n\t\t\tr = rectContainRect({ width: targetWidth, height: targetHeight }, aspectRatio);\n\t\t}\n\n\t\ttargetWidth = r.width;\n\t\ttargetHeight = r.height;\n\t\tconst targetX = interactionCropRect.x + interactionCropRect.width * 0.5 - targetWidth * 0.5;\n\t\tconst targetY = interactionCropRect.y + interactionCropRect.height * 0.5 - targetHeight * 0.5;\n\n\t\tset_store_value(\n\t\t\timageCropRect,\n\t\t\t$imageCropRect = {\n\t\t\t\tx: targetX,\n\t\t\t\ty: targetY,\n\t\t\t\twidth: targetWidth,\n\t\t\t\theight: targetHeight\n\t\t\t},\n\t\t\t$imageCropRect\n\t\t);\n\t};\n\n\tconst handleResizeStart = () => {\n\t\tinteraction = 'zoom';\n\n\t\t// now interacting with view\n\t\tset_store_value(isInteracting, $isInteracting = true, $isInteracting);\n\n\t\tsnapshotCropRect();\n\t};\n\n\tconst handleResizeMove = value => {\n\t\t// now transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t// value range from 0 (no zoom) to 1 (100% zoom, 1x1 pixel)\n\t\tresizeImage(value);\n\t};\n\n\tconst handleResizeEnd = value => {\n\t\tresizeImage(value);\n\t\thistory.write();\n\n\t\t// no longer transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t// we're done interacting\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t// now done\n\t\tinteractionCropRect = undefined;\n\t};\n\n\t//#endregion\n\t// #region resize with gesture (MacBook trackpad Safari)\n\tlet gestureOriginCropRect;\n\n\tconst handleGestureStart = () => {\n\t\tinteraction = 'zoom';\n\n\t\t// don't handle gesture as we're already handling input with interactable\n\t\tif (interactionCropRect) return;\n\n\t\tgestureOriginCropRect = rectClone($imageCropRect);\n\n\t\t// now interacting\n\t\tset_store_value(isInteracting, $isInteracting = true, $isInteracting);\n\t};\n\n\tconst handleGestureUpdate = ({ detail }) => {\n\t\t// don't handle gesture as we're already handling input with interactable\n\t\tif (!gestureOriginCropRect) return;\n\n\t\t// now transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = true, $isTransformingImage);\n\n\t\thandleScaleGesture(detail);\n\t};\n\n\tconst handleScaleGesture = scale => {\n\t\tconst cropIntent = rectScale(rectClone(gestureOriginCropRect), 1 / scale);\n\t\tset_store_value(imageCropRectIntent, $imageCropRectIntent = cropIntent, $imageCropRectIntent);\n\t\tset_store_value(imageCropRect, $imageCropRect = cropIntent, $imageCropRect);\n\t};\n\n\tconst handleGestureEnd = ({ detail }) => {\n\t\t// don't handle gesture as we're already handling input with interactable\n\t\tif (!gestureOriginCropRect) return;\n\n\t\t// no longer transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t// no longer interacting\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\thandleScaleGesture(detail);\n\n\t\t// no intent (needs to be set before crop rect is updated)\n\t\tset_store_value(imageCropRectIntent, $imageCropRectIntent = undefined, $imageCropRectIntent);\n\n\t\tgestureOriginCropRect = undefined;\n\t\thistory.write();\n\t};\n\n\t// #endregion\n\t// #region resizing with wheel\n\tlet zoomHistoryTimeoutId;\n\n\tconst handleWheel = e => {\n\t\tconst stageWheelPosition = getEventPositionInStage(e, $rootRect, $stageRect);\n\n\t\t// only block input if wheel is used within image rectangle\n\t\tif (cropEnableLimitWheelInputToCropSelection && !rectContainsPoint($imageSelectionRect, stageWheelPosition)) return;\n\n\t\tinteraction = 'zoom';\n\n\t\t// now interacting\n\t\tset_store_value(isInteracting, $isInteracting = true, $isInteracting);\n\n\t\t// transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = true, $isTransformingImage);\n\n\t\t// don't run default actions, prevent other actions from running\n\t\te.preventDefault();\n\n\t\te.stopPropagation();\n\n\t\t// convert wheel delta to scalar\n\t\tconst delta = getWheelDelta(e, {\n\t\t\tfixScrollDirection: $fixScrollDirectionStore\n\t\t});\n\n\t\tconst scalar = 1 + delta / 100;\n\n\t\t// get current crop rect\n\t\tconst currentCropRect = rectClone($imageCropRect);\n\n\t\t// if already zoomed in, block further zoom in instructions\n\t\tconst isMinSize = Math.min($imageCropRect.width / $imageCropMinSize.width, $imageCropRect.height / $imageCropMinSize.height) === 1;\n\n\t\t// if is fully zoomed out and trying to zoom out more and crop shape is free, fit image aspect ratio\n\t\tif (cropEnableZoomMatchImageAspectRatio && $imageCropLimitToImage) {\n\t\t\tconst isAtMaxCropSize = isCropMaxSize($imageCropRect, $imageSize, $imageRotation);\n\n\t\t\tif (isCustomCrop() && isAtMaxCropSize && delta > 0 && isImageSelectionCentered) {\n\t\t\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t\t\t// no longer transforming image\n\t\t\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t\t\tconst newCropRect = isRotatedSideways($imageRotation)\n\t\t\t\t? rectCreateFromSize({\n\t\t\t\t\t\theight: $imageSize.width,\n\t\t\t\t\t\twidth: $imageSize.height\n\t\t\t\t\t})\n\t\t\t\t: rectCreateFromSize($imageSize);\n\n\t\t\t\t// no change, exit\n\t\t\t\tif (rectEqual(currentCropRect, newCropRect)) return;\n\n\t\t\t\t// if we were previously zooming in we need to clear the timeout to prevent two history entries\n\t\t\t\tclearTimeout(zoomHistoryTimeoutId);\n\n\t\t\t\t// test if crop rect in history is same as new crop rect, this is possible when zooming in and out real quick\n\t\t\t\tif (rectEqual(history.state.crop, newCropRect)) return;\n\n\t\t\t\t// store new crop rect\n\t\t\t\tset_store_value(imageCropRect, $imageCropRect = newCropRect, $imageCropRect);\n\n\t\t\t\thistory.write();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// by default when zooming, zoom from center of crop rectangle\n\t\tlet origin = rectCenter($imageCropRect);\n\n\t\t// when zooming in, zoom in on the part of the image below the mouse cursor\n\t\tconst shouldZoomTowardsWheelPosition = cropEnableZoomTowardsWheelPosition && cropInteractionFocus !== 'selection';\n\n\t\tif (shouldZoomTowardsWheelPosition && delta < 0 && !isMinSize) {\n\t\t\tconst selectionOffset = vectorSubtract(vectorClone(stageWheelPosition), $imageSelectionRect);\n\t\t\tconst imageSelectionScale = Math.min($imageSelectionRect.width / $imageCropRect.width, $imageSelectionRect.height / $imageCropRect.height);\n\n\t\t\t// if wheel is inside image selection rectangle (slightly expanded version), we zoom based on position in the rectangle, if not, we use the selection center\n\t\t\tconst expandedImageSelection = rectScale(rectClone($imageSelectionRect), 1.1);\n\n\t\t\torigin = rectContainsPoint(expandedImageSelection, stageWheelPosition)\n\t\t\t? vectorAdd(rectClone($imageCropRect), vectorMultiply(selectionOffset, 1 / imageSelectionScale))\n\t\t\t: origin;\n\t\t}\n\n\t\tlet newCropRect = rectScale(rectClone($imageCropRect), scalar, origin);\n\n\t\t// determin if is new crop rect exceeds min or max size, if so, limit\n\t\tif (!sizeContains($imageCropRangeAspectRatio[1], newCropRect)) {\n\t\t\t// exceeds max size, limit to max size and position at new crop rect center\n\t\t\tnewCropRect = rectCreateWithCenter(rectCenter(newCropRect), $imageCropRangeAspectRatio[1]);\n\t\t}\n\n\t\tif (!sizeContains(newCropRect, $imageCropRangeAspectRatio[0])) {\n\t\t\t// exceeds min size, limit to min size and position at new crop rect center\n\t\t\tnewCropRect = rectCreateWithCenter(rectCenter(newCropRect), $imageCropRangeAspectRatio[0]);\n\t\t}\n\n\t\t// no change, exit\n\t\tif (rectEqual(currentCropRect, newCropRect, fixPrecision)) {\n\t\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t\t// no longer transforming image\n\t\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t\treturn;\n\t\t}\n\n\t\t// attempt to update the rectangle, we use fixPrecision so the width and height are nice integers when at max zoom (this makes sure the `isMinSize` variable is set to true at this point)\n\t\tset_store_value(imageCropRect, $imageCropRect = rectApply(newCropRect, v => fixPrecision(v, 5)), $imageCropRect);\n\n\t\t// done!\n\t\tset_store_value(isInteracting, $isInteracting = false, $isInteracting);\n\n\t\t// no longer transforming image\n\t\tset_store_value(isTransformingImage, $isTransformingImage = false, $isTransformingImage);\n\n\t\t// write history timer\n\t\tclearTimeout(zoomHistoryTimeoutId);\n\n\t\tzoomHistoryTimeoutId = setTimeout(\n\t\t\t() => {\n\t\t\t\thistory.write();\n\t\t\t},\n\t\t\t500\n\t\t);\n\t};\n\n\t// #endregion\n\t// #region recenter\n\t// triggers the editor to center and scale up the crop\n\tconst handleRecenterAction = () => {\n\t\t// force recenter\n\t\tstageRecenter.set({});\n\t};\n\n\tfunction getImageInfo(crop, outputSize) {\n\t\tlet info = {};\n\n\t\tif (outputSize) {\n\t\t\tconst cropAspectRatio = crop.width / crop.height;\n\n\t\t\tif (outputSize.width && !outputSize.height) {\n\t\t\t\tinfo = sizeCreate(outputSize.width, outputSize.width / cropAspectRatio);\n\t\t\t} else if (outputSize.height && !outputSize.width) {\n\t\t\t\tinfo = sizeCreate(outputSize.height * cropAspectRatio, outputSize.height);\n\t\t\t} else {\n\t\t\t\tinfo = sizeClone(outputSize);\n\t\t\t}\n\t\t} else {\n\t\t\tinfo = sizeCreate(crop.width, crop.height);\n\t\t}\n\n\t\treturn `${Math.round(info.width)} &times; ${Math.round(info.height)}`;\n\t}\n\n\t// auto recenter after timeout\n\tlet cropAutoCenterImageSelectionTimeoutId;\n\n\t// animations\n\tconst recenterOpacity = spring(0, { precision: 0.0001 });\n\n\tcomponent_subscribe($$self, recenterOpacity, value => $$invalidate(31, $recenterOpacity = value));\n\tconst recenterOffset = spring();\n\tcomponent_subscribe($$self, recenterOffset, value => $$invalidate(32, $recenterOffset = value));\n\n\t//\n\t// enable seeing the image outside of the crop area, and disable the vignette effect\n\t//\n\tconst setPreviewModifiers = () => {\n\t\tset_store_value(\n\t\t\timagePreviewModifiers,\n\t\t\t$imagePreviewModifiers['crop'] = {\n\t\t\t\tmaskOpacity: cropMaskOpacity,\n\t\t\t\tmaskMarkupOpacity: cropMaskOpacity\n\t\t\t},\n\t\t\t$imagePreviewModifiers\n\t\t);\n\n\t\t// trigger store update\n\t\timagePreviewModifiers.set($imagePreviewModifiers);\n\t};\n\n\tconst clearPreviewModifiers = () => {\n\t\tdelete $imagePreviewModifiers['crop'];\n\n\t\t// trigger store update\n\t\timagePreviewModifiers.set($imagePreviewModifiers);\n\t};\n\n\t// #region crop selection presets\n\tconst selectedPresetIndex = derived([imageCropAspectRatio, imageOutputSize, formattedCropPresetOptions], ([$cropAspectRatio, $imageOutputSize, $formattedCropPresetOptions], set) => {\n\t\tif (!hasCropSelectPresetOptions) return;\n\t\tconst options = flattenOptions($formattedCropPresetOptions);\n\n\t\tconst matchedOptionValue = [...options].// to value\n\t\tmap(option => option[0]).// sort sizes first\n\t\tsort((a, b) => {\n\t\t\tif (isArray(a[0]) && !isArray(b[0])) return 1;\n\t\t\treturn -1;\n\t\t}).// match value\n\t\tfind(value => {\n\t\t\tif (isArray(value) && $imageOutputSize) {\n\t\t\t\t// size + aspect ratio\n\t\t\t\tconst [width, height] = value;\n\n\t\t\t\tconst outputSizeMatches = $imageOutputSize.width === width && $imageOutputSize.height === height;\n\t\t\t\tconst aspectRatioMatches = $cropAspectRatio === getAspectRatio(width, height);\n\t\t\t\treturn outputSizeMatches && aspectRatioMatches;\n\t\t\t}\n\n\t\t\t// aspect ratio\n\t\t\treturn value === $cropAspectRatio;\n\t\t});\n\n\t\t// no options found, exit\n\t\tif (!matchedOptionValue) return set(undefined);\n\n\t\tconst index = options.// to value\n\t\tmap(option => option[0]).// find index of matching value\n\t\tfindIndex(value => isArray(value)\n\t\t? arrayEqual(value, matchedOptionValue)\n\t\t: value === matchedOptionValue);\n\n\t\tset(index);\n\t});\n\n\tcomponent_subscribe($$self, selectedPresetIndex, value => $$invalidate(162, $selectedPresetIndex = value));\n\n\tconst getAspectRatioBySelectedIndex = (selectedIndex, options) => {\n\t\tif (!hasCropSelectPresetOptions || selectedIndex === -1 || selectedIndex === undefined) return;\n\t\tconst selectedValue = flattenOptions(options)[selectedIndex][0];\n\n\t\treturn !selectedValue\n\t\t? undefined\n\t\t: isArray(selectedValue)\n\t\t\t? getAspectRatio(selectedValue[0], selectedValue[1])\n\t\t\t: selectedValue;\n\t};\n\n\t// #endregion\n\t// #region crop guides\n\tconst imageSelectionGuides = derived([rootLineColor, imageSelectionRectPresentation, isInteractingFraction], ([$rootLineColor, $rect, $isInteractingFraction], set) => {\n\t\tconst { rows, cols, opacity } = cropWillRenderImageSelectionGuides(interaction, $isInteractingFraction);\n\t\tif (!$rect || opacity <= 0) return set([]);\n\t\tconst { x, y, width, height } = $rect;\n\t\tconst w = width / cols;\n\t\tconst h = height / rows;\n\t\tconst shapes = [];\n\n\t\t// rows\n\t\tfor (let r = 1; r <= rows - 1; r++) {\n\t\t\tconst yo = y + h * r;\n\n\t\t\tshapes.push({\n\t\t\t\tid: `image-selection-guide-row-${r}`,\n\t\t\t\tpoints: [vectorCreate(x, yo), vectorCreate(x + width, yo)],\n\t\t\t\topacity,\n\t\t\t\tstrokeWidth: 1,\n\t\t\t\tstrokeColor: $rootLineColor\n\t\t\t});\n\t\t}\n\n\t\t// cols\n\t\tfor (let c = 1; c <= cols - 1; c++) {\n\t\t\tconst xo = x + w * c;\n\n\t\t\tshapes.push({\n\t\t\t\tid: `image-selection-guide-col-${c}`,\n\t\t\t\tpoints: [vectorCreate(xo, y), vectorCreate(xo, y + height)],\n\t\t\t\topacity,\n\t\t\t\tstrokeWidth: 1,\n\t\t\t\tstrokeColor: $rootLineColor\n\t\t\t});\n\t\t}\n\n\t\tset(shapes);\n\t});\n\n\tcomponent_subscribe($$self, imageSelectionGuides, value => $$invalidate(147, $imageSelectionGuides = value));\n\n\tconst syncGuides = () => {\n\t\t// remove existing guides\n\t\timageOverlayMarkup.update(shapes => {\n\t\t\tconst overlayMarkup = shapes.filter(markup => !(/^image\\-selection\\-guide/).test(markup.id));\n\n\t\t\tif ($isActive) {\n\t\t\t\treturn [...overlayMarkup, ...$imageSelectionGuides];\n\t\t\t}\n\n\t\t\treturn overlayMarkup;\n\t\t});\n\t};\n\n\tconst cropUniqueId = `crop-${getUniqueId()}`;\n\n\tlet transformInitial = cropEnableRotationInput\n\t? cropActiveTransformTool\n\t: 'zoom';\n\n\tlet transformToolInitial = cropUniqueId + '-' + transformInitial;\n\tlet transformSelected = transformToolInitial;\n\tlet root = undefined;\n\n\t// fixes rendering issue with stage being empty in overlay mode, this basically redispatches the measure event so the stage is correctly measured\n\tlet stageRef;\n\n\tconst footerOffset = spring($isAnimated ? 20 : 0);\n\tcomponent_subscribe($$self, footerOffset, value => $$invalidate(144, $footerOffset = value));\n\n\tfunction measure_handler_1(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\tconst select_handler = ({ detail }) => $$invalidate(5, transformSelected = detail);\n\n\tfunction div0_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tstageRef = $$value;\n\t\t\t$$invalidate(6, stageRef);\n\t\t});\n\t}\n\n\tconst interactable_function_1 = e => getEventPositionInViewport(e);\n\n\tfunction util_root_binding(value) {\n\t\troot = value;\n\t\t$$invalidate(16, root);\n\t}\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));\n\t\tif ('stores' in $$props) $$invalidate(99, stores = $$props.stores);\n\t\tif ('cropImageSelectionCornerStyle' in $$props) $$invalidate(1, cropImageSelectionCornerStyle = $$props.cropImageSelectionCornerStyle);\n\t\tif ('cropWillRenderImageSelectionGuides' in $$props) $$invalidate(100, cropWillRenderImageSelectionGuides = $$props.cropWillRenderImageSelectionGuides);\n\t\tif ('cropAutoCenterImageSelectionTimeout' in $$props) $$invalidate(101, cropAutoCenterImageSelectionTimeout = $$props.cropAutoCenterImageSelectionTimeout);\n\t\tif ('cropEnableZoomMatchImageAspectRatio' in $$props) $$invalidate(102, cropEnableZoomMatchImageAspectRatio = $$props.cropEnableZoomMatchImageAspectRatio);\n\t\tif ('cropEnableRotateMatchImageAspectRatio' in $$props) $$invalidate(103, cropEnableRotateMatchImageAspectRatio = $$props.cropEnableRotateMatchImageAspectRatio);\n\t\tif ('cropEnableRotationInput' in $$props) $$invalidate(104, cropEnableRotationInput = $$props.cropEnableRotationInput);\n\t\tif ('cropEnableZoom' in $$props) $$invalidate(2, cropEnableZoom = $$props.cropEnableZoom);\n\t\tif ('cropEnableZoomInput' in $$props) $$invalidate(105, cropEnableZoomInput = $$props.cropEnableZoomInput);\n\t\tif ('cropEnableZoomAutoHide' in $$props) $$invalidate(106, cropEnableZoomAutoHide = $$props.cropEnableZoomAutoHide);\n\t\tif ('cropEnableImageSelection' in $$props) $$invalidate(107, cropEnableImageSelection = $$props.cropEnableImageSelection);\n\t\tif ('cropEnableInfoIndicator' in $$props) $$invalidate(108, cropEnableInfoIndicator = $$props.cropEnableInfoIndicator);\n\t\tif ('cropEnableZoomTowardsWheelPosition' in $$props) $$invalidate(109, cropEnableZoomTowardsWheelPosition = $$props.cropEnableZoomTowardsWheelPosition);\n\t\tif ('cropEnableLimitWheelInputToCropSelection' in $$props) $$invalidate(110, cropEnableLimitWheelInputToCropSelection = $$props.cropEnableLimitWheelInputToCropSelection);\n\t\tif ('cropEnableCenterImageSelection' in $$props) $$invalidate(111, cropEnableCenterImageSelection = $$props.cropEnableCenterImageSelection);\n\t\tif ('cropEnableButtonRotateLeft' in $$props) $$invalidate(112, cropEnableButtonRotateLeft = $$props.cropEnableButtonRotateLeft);\n\t\tif ('cropEnableButtonRotateRight' in $$props) $$invalidate(113, cropEnableButtonRotateRight = $$props.cropEnableButtonRotateRight);\n\t\tif ('cropEnableButtonFlipHorizontal' in $$props) $$invalidate(114, cropEnableButtonFlipHorizontal = $$props.cropEnableButtonFlipHorizontal);\n\t\tif ('cropEnableButtonFlipVertical' in $$props) $$invalidate(115, cropEnableButtonFlipVertical = $$props.cropEnableButtonFlipVertical);\n\t\tif ('cropSelectPresetOptions' in $$props) $$invalidate(116, cropSelectPresetOptions = $$props.cropSelectPresetOptions);\n\t\tif ('cropEnableSelectPreset' in $$props) $$invalidate(117, cropEnableSelectPreset = $$props.cropEnableSelectPreset);\n\t\tif ('cropEnableFilterMatchAspectRatio' in $$props) $$invalidate(118, cropEnableFilterMatchAspectRatio = $$props.cropEnableFilterMatchAspectRatio);\n\t\tif ('cropSelectPresetFilter' in $$props) $$invalidate(119, cropSelectPresetFilter = $$props.cropSelectPresetFilter);\n\t\tif ('cropEnableButtonToggleCropLimit' in $$props) $$invalidate(120, cropEnableButtonToggleCropLimit = $$props.cropEnableButtonToggleCropLimit);\n\t\tif ('cropWillRenderTools' in $$props) $$invalidate(121, cropWillRenderTools = $$props.cropWillRenderTools);\n\t\tif ('cropWillRenderInfoIndicator' in $$props) $$invalidate(122, cropWillRenderInfoIndicator = $$props.cropWillRenderInfoIndicator);\n\t\tif ('cropActiveTransformTool' in $$props) $$invalidate(123, cropActiveTransformTool = $$props.cropActiveTransformTool);\n\t\tif ('cropMinimizeToolbar' in $$props) $$invalidate(124, cropMinimizeToolbar = $$props.cropMinimizeToolbar);\n\t\tif ('cropInteractionFocus' in $$props) $$invalidate(125, cropInteractionFocus = $$props.cropInteractionFocus);\n\t\tif ('cropRotationRange' in $$props) $$invalidate(3, cropRotationRange = $$props.cropRotationRange);\n\t\tif ('cropMaskOpacity' in $$props) $$invalidate(126, cropMaskOpacity = $$props.cropMaskOpacity);\n\t\tif ('locale' in $$props) $$invalidate(4, locale = $$props.locale);\n\t\tif ('cropFormatIconSelectPreset' in $$props) $$invalidate(127, cropFormatIconSelectPreset = $$props.cropFormatIconSelectPreset);\n\t\tif ('cropFormatIconCropBoundary' in $$props) $$invalidate(128, cropFormatIconCropBoundary = $$props.cropFormatIconCropBoundary);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 8192 | $$self.$$.dirty[4] & /*cropInteractionFocus*/ 2) {\n\t\t\timageIsStatic.set(cropInteractionFocus === 'selection' && $isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropSelectPresetOptions*/ 8388608) {\n\t\t\t$$invalidate(135, hasCropSelectPresetOptions = cropSelectPresetOptions && Array.isArray(cropSelectPresetOptions) && cropSelectPresetOptions.length);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropSelectPresetOptions*/ 8388608 | $$self.$$.dirty[4] & /*hasCropSelectPresetOptions*/ 2048) {\n\t\t\tformattedCropPresetOptions.set(hasCropSelectPresetOptions\n\t\t\t? cropSelectPresetOptions\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 8192 | $$self.$$.dirty[4] & /*$isAnimated*/ 2097152) {\n\t\t\t$isActive && imageOutlineOpacity.set(1, { hard: !$isAnimated });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 8192) {\n\t\t\t// fully disable pan and zoom when crop tool is active\n\t\t\tallowPan.set(!$isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 8192) {\n\t\t\tallowZoom.set(!$isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 8192) {\n\t\t\t$isActive && allowPlayPause.set(true);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropSelectPresetFilter*/ 67108864 | $$self.$$.dirty[5] & /*$imageSize*/ 16) {\n\t\t\t// sync current preset when cropSelectPresetFilter is updated or when image changes\n\t\t\t{\n\t\t\t\tif (cropSelectPresetFilter === 'auto') {\n\t\t\t\t\tif ($imageSize.width >= $imageSize.height) {\n\t\t\t\t\t\tcurrentPresetFilter.set('landscape');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrentPresetFilter.set('portrait');\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcurrentPresetFilter.set(cropSelectPresetFilter);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$env*/ 4194304) {\n\t\t\t$$invalidate(130, isOverlayMode = $env.layoutMode === 'overlay');\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropEnableSelectPreset*/ 16777216 | $$self.$$.dirty[4] & /*isOverlayMode*/ 64) {\n\t\t\t$$invalidate(134, shouldRenderPresetSelect = cropEnableSelectPreset && !isOverlayMode);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$utilRectPadded*/ 16384 | $$self.$$.dirty[5] & /*$imageSelectionRect*/ 4) {\n\t\t\t// determine if we can center the crop, if we can, show the crop center button\n\t\t\t$$invalidate(143, imageSelectionCenteredRect = $utilRectPadded && $imageSelectionRect && rectCenterRect($utilRectPadded, $imageSelectionRect));\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*imageSelectionCenteredRect*/ 524288 | $$self.$$.dirty[5] & /*$imageSelectionRect*/ 4) {\n\t\t\t$$invalidate(141, isImageSelectionDisplayed = !!($imageSelectionRect && imageSelectionCenteredRect));\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*isImageSelectionDisplayed, imageSelectionCenteredRect*/ 655360 | $$self.$$.dirty[5] & /*$imageSelectionRect*/ 4) {\n\t\t\t$$invalidate(139, isImageSelectionCentered = isImageSelectionDisplayed && rectEqual($imageSelectionRect, imageSelectionCenteredRect, value => fixPrecision(value, 5)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale, $imageRotation*/ 32784 | $$self.$$.dirty[3] & /*cropWillRenderTools, cropEnableButtonRotateLeft, cropEnableButtonRotateRight, cropEnableButtonFlipHorizontal, cropEnableButtonFlipVertical, cropSelectPresetFilter, cropEnableButtonToggleCropLimit*/ 477626368 | $$self.$$.dirty[4] & /*shouldRenderPresetSelect, hasCropSelectPresetOptions, isImageSelectionCentered, $env*/ 4230144 | $$self.$$.dirty[5] & /*$redrawTrigger, $imageFlipY, $imageFlipX, $selectedPresetIndex, $formattedCropPresetOptions, $currentPresetFilter, $imageSize, $imageCropMinSize, $imageCropLimitToImage*/ 8176) {\n\t\t\t// #region dynamic toolbar\n\t\t\t$$invalidate(12, cropTools = $redrawTrigger && cropWillRenderTools(\n\t\t\t\t[\n\t\t\t\t\tcropEnableButtonRotateLeft && [\n\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t'rotate-left',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: locale.cropLabelButtonRotateLeft,\n\t\t\t\t\t\t\tlabelClass: 'PinturaToolbarContentWide',\n\t\t\t\t\t\t\ticon: locale.cropIconButtonRotateLeft,\n\t\t\t\t\t\t\tonclick: () => {\n\t\t\t\t\t\t\t\tapplyRotation(-Math.PI / 2);\n\t\t\t\t\t\t\t\thistory.write();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcropEnableButtonRotateRight && [\n\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t'rotate-right',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: locale.cropLabelButtonRotateRight,\n\t\t\t\t\t\t\tlabelClass: 'PinturaToolbarContentWide',\n\t\t\t\t\t\t\ticon: locale.cropIconButtonRotateRight,\n\t\t\t\t\t\t\tonclick: () => {\n\t\t\t\t\t\t\t\tapplyRotation(Math.PI / 2);\n\t\t\t\t\t\t\t\thistory.write();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcropEnableButtonFlipHorizontal && [\n\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t'flip-horizontal',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: locale.cropLabelButtonFlipHorizontal,\n\t\t\t\t\t\t\tlabelClass: 'PinturaToolbarContentWide',\n\t\t\t\t\t\t\ticon: locale.cropIconButtonFlipHorizontal,\n\t\t\t\t\t\t\tonclick: () => {\n\t\t\t\t\t\t\t\tif (isRotatedSideways($imageRotation)) {\n\t\t\t\t\t\t\t\t\tset_store_value(imageFlipY, $imageFlipY = !$imageFlipY, $imageFlipY);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tset_store_value(imageFlipX, $imageFlipX = !$imageFlipX, $imageFlipX);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\thistory.write();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcropEnableButtonFlipVertical && [\n\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t'flip-vertical',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: locale.cropLabelButtonFlipVertical,\n\t\t\t\t\t\t\tlabelClass: 'PinturaToolbarContentWide',\n\t\t\t\t\t\t\ticon: locale.cropIconButtonFlipVertical,\n\t\t\t\t\t\t\tonclick: () => {\n\t\t\t\t\t\t\t\tif (isRotatedSideways($imageRotation)) {\n\t\t\t\t\t\t\t\t\tset_store_value(imageFlipX, $imageFlipX = !$imageFlipX, $imageFlipX);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tset_store_value(imageFlipY, $imageFlipY = !$imageFlipY, $imageFlipY);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\thistory.write();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tshouldRenderPresetSelect && hasCropSelectPresetOptions && [\n\t\t\t\t\t\tcropSelectPresetFilter === false\n\t\t\t\t\t\t? 'Dropdown'\n\t\t\t\t\t\t: CropPresetList,\n\t\t\t\t\t\t'select-preset',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thideLabel: undefined,\n\t\t\t\t\t\t\ticon: getCropSelectPresetIcon(locale, getAspectRatioBySelectedIndex($selectedPresetIndex, $formattedCropPresetOptions)),\n\t\t\t\t\t\t\tlabel: localize(locale.cropLabelSelectPreset, locale, getAspectRatioBySelectedIndex($selectedPresetIndex, $formattedCropPresetOptions)),\n\t\t\t\t\t\t\tlabelClass: 'PinturaToolbarContentWide',\n\t\t\t\t\t\t\toptions: $formattedCropPresetOptions,\n\t\t\t\t\t\t\tfilter: $currentPresetFilter,\n\t\t\t\t\t\t\tonfilterchange: applyCropPresetFilter,\n\t\t\t\t\t\t\tselectedIndex: $selectedPresetIndex,\n\t\t\t\t\t\t\tonchange: ({ value }) => {\n\t\t\t\t\t\t\t\tif (isArray(value)) {\n\t\t\t\t\t\t\t\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = getAspectRatio(value[0], value[1]), $imageCropAspectRatio);\n\t\t\t\t\t\t\t\t\tset_store_value(imageOutputSize, $imageOutputSize = sizeCreateFromArray(value), $imageOutputSize);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = value, $imageCropAspectRatio);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isImageSelectionCentered) {\n\t\t\t\t\t\t\t\t\thandleRecenterAction();\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\thistory.write();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toptionMapper: option => {\n\t\t\t\t\t\t\t\t// if no aspect ratio found we enable the option by default\n\t\t\t\t\t\t\t\tlet disabled = false;\n\n\t\t\t\t\t\t\t\t// get aspect ratio for this option\n\t\t\t\t\t\t\t\tconst optionAspectRatio = isArray(option.value)\n\t\t\t\t\t\t\t\t? option.value[0] / option.value[1]\n\t\t\t\t\t\t\t\t: option.value;\n\n\t\t\t\t\t\t\t\t// can be undefined in which case we don't need to check anything\n\t\t\t\t\t\t\t\tif (optionAspectRatio) {\n\t\t\t\t\t\t\t\t\tconst maxCropSize = getMaxSizeInRect($imageSize, $imageRotation, optionAspectRatio);\n\t\t\t\t\t\t\t\t\tdisabled = maxCropSize.width < $imageCropMinSize.width || maxCropSize.height < $imageCropMinSize.height;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// add icon for this option\n\t\t\t\t\t\t\t\toption.icon = getSelectionPresetOptionIcon(option.value, { bounds: 14 });\n\n\t\t\t\t\t\t\t\treturn { ...option, disabled };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcropEnableButtonToggleCropLimit && [\n\t\t\t\t\t\t'Dropdown',\n\t\t\t\t\t\t'select-crop-limit',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ticon: getCropLimitIcon(locale, $imageCropLimitToImage),\n\t\t\t\t\t\t\tlabel: locale.cropLabelCropBoundary,\n\t\t\t\t\t\t\tlabelClass: 'PinturaToolbarContentWide',\n\t\t\t\t\t\t\tonchange: ({ value }) => {\n\t\t\t\t\t\t\t\tset_store_value(imageCropLimitToImage, $imageCropLimitToImage = value, $imageCropLimitToImage);\n\t\t\t\t\t\t\t\thistory.write();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t\t\tlocale.cropLabelCropBoundaryEdge,\n\t\t\t\t\t\t\t\t\t{ icon: getCropLimitIcon(locale, true) }\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\t\tlocale.cropLabelCropBoundaryNone,\n\t\t\t\t\t\t\t\t\t{ icon: getCropLimitIcon(locale, false) }\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t].filter(Boolean),\n\t\t\t\t$env,\n\t\t\t\t() => redrawTrigger.set({})\n\t\t\t).filter(Boolean));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive, cropTools*/ 12288 | $$self.$$.dirty[4] & /*cropMinimizeToolbar, $env, isOverlayMode*/ 4194369) {\n\t\t\tset_store_value(\n\t\t\t\tutilTools,\n\t\t\t\t$utilTools = $isActive && // should always minimize OR no room OR is overlay mode\n\t\t\t\tcropMinimizeToolbar !== 'never' && (cropMinimizeToolbar === 'always' || $env.verticalSpace === 'short' || isOverlayMode)\n\t\t\t\t? cropTools.map(([name, id, props]) => {\n\t\t\t\t\t\t// is node children\n\t\t\t\t\t\tif (Array.isArray(props)) return [name, id, props];\n\n\t\t\t\t\t\t// is props\n\t\t\t\t\t\treturn [name, id, { ...props, hideLabel: true }];\n\t\t\t\t\t})\n\t\t\t\t: [],\n\t\t\t\t$utilTools\n\t\t\t);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*$imageCropLimitToImage*/ 32) {\n\t\t\t$$invalidate(25, imageZoomLevelMin = $imageCropLimitToImage ? 0 : IMAGE_ZOOM_LEVEL_MIN);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$utilRectPadded*/ 16384 | $$self.$$.dirty[5] & /*$stageRect*/ 8) {\n\t\t\t// #endregion\n\t\t\t$$invalidate(136, imageSelectionOffset = $utilRectPadded && vectorCreate(-($stageRect.x - $utilRectPadded.x), -($stageRect.y - $utilRectPadded.y)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$imageSelectionRectPresentation, imageSelectionOffset*/ 33558528) {\n\t\t\t// normalized crop bounds, we use these to limit the crop interactions to the view\n\t\t\t$$invalidate(137, imageSelectionCenter = $imageSelectionRectPresentation && imageSelectionOffset && vectorCreate(snapToPixel($imageSelectionRectPresentation.x + $imageSelectionRectPresentation.width * 0.5 + imageSelectionOffset.x), snapToPixel($imageSelectionRectPresentation.y + $imageSelectionRectPresentation.height * 0.5 + imageSelectionOffset.y)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*$imageSelectionRectSnapshot*/ 2) {\n\t\t\t$$invalidate(140, isResizingSelection = $imageSelectionRectSnapshot != null);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$utilRectPadded*/ 16384 | $$self.$$.dirty[4] & /*imageSelectionCenteredRect*/ 524288) {\n\t\t\t$$invalidate(142, isMaxSelectionRect = $utilRectPadded && imageSelectionCenteredRect && (imageSelectionCenteredRect.height === $utilRectPadded.height || imageSelectionCenteredRect.width === $utilRectPadded.width));\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*isMaxSelectionRect, $imageScalar*/ 1074003968 | $$self.$$.dirty[5] & /*$presentationScalar*/ 1) {\n\t\t\t$$invalidate(138, canZoomToCenter = !isMaxSelectionRect && $presentationScalar < 1 && $imageScalar < 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*isImageSelectionDisplayed, isResizingSelection, isImageSelectionCentered, canZoomToCenter*/ 245760) {\n\t\t\t$$invalidate(9, canCenter = isImageSelectionDisplayed && !isResizingSelection && (!isImageSelectionCentered || canZoomToCenter));\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropEnableInfoIndicator*/ 32768 | $$self.$$.dirty[4] & /*$imageCropRect, isOverlayMode*/ 536870976) {\n\t\t\t$$invalidate(11, shouldRenderInfoIndicator = cropEnableInfoIndicator && !!$imageCropRect && !isOverlayMode);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropWillRenderInfoIndicator*/ 536870912) {\n\t\t\t$$invalidate(24, isImageInfoCustom = cropWillRenderInfoIndicator ? true : undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderInfoIndicator*/ 2048 | $$self.$$.dirty[3] & /*cropWillRenderInfoIndicator*/ 536870912 | $$self.$$.dirty[4] & /*$imageCropRect, $imageOutputSize*/ 805306368) {\n\t\t\t$$invalidate(23, imageInfo = shouldRenderInfoIndicator && cropWillRenderInfoIndicator\n\t\t\t? cropWillRenderInfoIndicator($imageCropRect, $imageOutputSize)\n\t\t\t: shouldRenderInfoIndicator && getImageInfo($imageCropRect, $imageOutputSize));\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$imageSelectionRectPresentation, imageSelectionOffset*/ 33558528) {\n\t\t\t$$invalidate(8, imageSelectionRectOffset = $imageSelectionRectPresentation && imageSelectionOffset && {\n\t\t\t\tx: $imageSelectionRectPresentation.x + imageSelectionOffset.x,\n\t\t\t\ty: $imageSelectionRectPresentation.y + imageSelectionOffset.y,\n\t\t\t\twidth: $imageSelectionRectPresentation.width,\n\t\t\t\theight: $imageSelectionRectPresentation.height\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*imageSelectionRectOffset*/ 256 | $$self.$$.dirty[3] & /*cropEnableImageSelection*/ 16384 | $$self.$$.dirty[4] & /*isOverlayMode*/ 64) {\n\t\t\t$$invalidate(22, shouldRenderImageSelection = cropEnableImageSelection && !!imageSelectionRectOffset && !isOverlayMode);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropEnableCenterImageSelection, cropAutoCenterImageSelectionTimeout*/ 262400 | $$self.$$.dirty[4] & /*imageSelectionCenter, $imageIsStatic*/ 134225920) {\n\t\t\t$$invalidate(10, shouldRenderImageSelectionRecenterButton = cropEnableCenterImageSelection && !!imageSelectionCenter && !cropAutoCenterImageSelectionTimeout && !$imageIsStatic);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*canCenter*/ 512 | $$self.$$.dirty[3] & /*cropAutoCenterImageSelectionTimeout*/ 256 | $$self.$$.dirty[4] & /*$isInteracting, cropAutoCenterImageSelectionTimeoutId*/ 67108896) {\n\t\t\tif (canCenter && cropAutoCenterImageSelectionTimeout && !$isInteracting) {\n\t\t\t\tclearTimeout(cropAutoCenterImageSelectionTimeoutId);\n\t\t\t\t$$invalidate(129, cropAutoCenterImageSelectionTimeoutId = setTimeout(handleRecenterAction, cropAutoCenterImageSelectionTimeout));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$isInteracting, cropAutoCenterImageSelectionTimeoutId*/ 67108896) {\n\t\t\tif ($isInteracting) clearTimeout(cropAutoCenterImageSelectionTimeoutId);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderImageSelectionRecenterButton, canCenter*/ 1536 | $$self.$$.dirty[4] & /*$isAnimated*/ 2097152) {\n\t\t\trecenterOpacity.set(\n\t\t\t\tshouldRenderImageSelectionRecenterButton && canCenter\n\t\t\t\t? 1\n\t\t\t\t: 0,\n\t\t\t\t{ hard: $isAnimated === false }\n\t\t\t);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*imageSelectionCenter, $isAnimated*/ 2105344) {\n\t\t\trecenterOffset.set(imageSelectionCenter, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 8192 | $$self.$$.dirty[4] & /*$stagePadded*/ 16777216) {\n\t\t\tif ($isActive && !$stagePadded) {\n\t\t\t\tsetPreviewModifiers();\n\t\t\t} else {\n\t\t\t\tclearPreviewModifiers();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$imageSelectionGuides*/ 8388608) {\n\t\t\t// if overlay top changes\n\t\t\t$imageSelectionGuides && syncGuides();\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$env*/ 4194304) {\n\t\t\t// #endregion\n\t\t\t//\n\t\t\t// Transform tabs\n\t\t\t//\n\t\t\t$$invalidate(133, hasPlentyVerticalSpace = $env.verticalSpace !== 'short');\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*cropMinimizeToolbar, isOverlayMode, hasPlentyVerticalSpace*/ 577) {\n\t\t\t$$invalidate(21, shouldRenderToolbar = // should show if is not allowed to hide and is not in overlay mode\n\t\t\tcropMinimizeToolbar === 'never' && !isOverlayMode || // or if plenty space and should not force hide\n\t\t\thasPlentyVerticalSpace && cropMinimizeToolbar !== 'always');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*cropEnableZoom*/ 4 | $$self.$$.dirty[3] & /*cropEnableZoomInput*/ 4096) {\n\t\t\t$$invalidate(132, couldRenderZoomInput = cropEnableZoom && cropEnableZoomInput);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropEnableZoomAutoHide*/ 8192 | $$self.$$.dirty[4] & /*hasPlentyVerticalSpace, couldRenderZoomInput*/ 768) {\n\t\t\t$$invalidate(131, shouldRenderZoomInput = cropEnableZoomAutoHide\n\t\t\t? hasPlentyVerticalSpace && couldRenderZoomInput\n\t\t\t: couldRenderZoomInput);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*cropEnableRotationInput*/ 2048 | $$self.$$.dirty[4] & /*shouldRenderZoomInput*/ 128) {\n\t\t\t$$invalidate(20, shouldRenderFooter = cropEnableRotationInput || shouldRenderZoomInput);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*shouldRenderZoomInput*/ 128) {\n\t\t\tif (!shouldRenderZoomInput) {\n\t\t\t\t$$invalidate(5, transformSelected = transformToolInitial);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*transformSelected*/ 32) {\n\t\t\t$$invalidate(19, tabsConfig = {\n\t\t\t\tname: cropUniqueId,\n\t\t\t\tselected: transformSelected\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 16 | $$self.$$.dirty[3] & /*cropEnableRotationInput*/ 2048 | $$self.$$.dirty[4] & /*shouldRenderZoomInput*/ 128) {\n\t\t\t$$invalidate(7, tabs = [\n\t\t\t\tcropEnableRotationInput && {\n\t\t\t\t\tid: cropUniqueId + '-rotation',\n\t\t\t\t\tlabel: locale.cropLabelTabRotation\n\t\t\t\t},\n\t\t\t\tshouldRenderZoomInput && {\n\t\t\t\t\tid: cropUniqueId + '-zoom',\n\t\t\t\t\tlabel: locale.cropLabelTabZoom\n\t\t\t\t}\n\t\t\t].filter(Boolean));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*tabs*/ 128) {\n\t\t\t$$invalidate(18, panels = tabs.map(tab => tab.id));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*stageRef*/ 64 | $$self.$$.dirty[4] & /*isOverlayMode*/ 64) {\n\t\t\tif (stageRef && !stageRef.children.length && isOverlayMode) {\n\t\t\t\tstageRef.dispatchEvent(new CustomEvent('measure', { detail: stageRef.rect }));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 8192 | $$self.$$.dirty[4] & /*$isAnimated*/ 2097152) {\n\t\t\t$isAnimated && footerOffset.set($isActive ? 0 : 20);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$footerOffset*/ 1048576) {\n\t\t\t$$invalidate(17, styleFooterTransform = $footerOffset\n\t\t\t? `translateY(${$footerOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tcropImageSelectionCornerStyle,\n\t\tcropEnableZoom,\n\t\tcropRotationRange,\n\t\tlocale,\n\t\ttransformSelected,\n\t\tstageRef,\n\t\ttabs,\n\t\timageSelectionRectOffset,\n\t\tcanCenter,\n\t\tshouldRenderImageSelectionRecenterButton,\n\t\tshouldRenderInfoIndicator,\n\t\tcropTools,\n\t\t$isActive,\n\t\t$utilRectPadded,\n\t\t$imageRotation,\n\t\troot,\n\t\tstyleFooterTransform,\n\t\tpanels,\n\t\ttabsConfig,\n\t\tshouldRenderFooter,\n\t\tshouldRenderToolbar,\n\t\tshouldRenderImageSelection,\n\t\timageInfo,\n\t\tisImageInfoCustom,\n\t\timageZoomLevelMin,\n\t\t$rootRect,\n\t\t$elasticityMultiplier,\n\t\t$imageRotationRange,\n\t\t$imageZoomLevelRange,\n\t\t$imageZoomLevel,\n\t\t$recenterOpacity,\n\t\t$recenterOffset,\n\t\tisAnimated,\n\t\telasticityMultiplier,\n\t\tredrawTrigger,\n\t\timageIsStatic,\n\t\timageStaticVisualCorners,\n\t\tfixScrollDirectionStore,\n\t\tformattedCropPresetOptions,\n\t\tenv,\n\t\tisInteracting,\n\t\tisTransformingImage,\n\t\trootRect,\n\t\tstageRect,\n\t\tutilRectPadded,\n\t\trangeInputElasticity,\n\t\tpresentationScalar,\n\t\tutilTools,\n\t\timagePreviewModifiers,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\timageRotation,\n\t\timageRotationRange,\n\t\timageOutputSize,\n\t\timageSelectionRect,\n\t\timageSelectionRectSnapshot,\n\t\timageSelectionRectIntent,\n\t\timageSelectionRectPresentation,\n\t\timageCropRectIntent,\n\t\timageCropRectOrigin,\n\t\timageCropRect,\n\t\timageCropMinSize,\n\t\timageCropMaxSize,\n\t\timageCropRange,\n\t\timageCropAspectRatio,\n\t\timageCropLimitToImage,\n\t\timageSize,\n\t\timageScalar,\n\t\tstagePadded,\n\t\tcurrentPresetFilter,\n\t\thandleSelectionGrab,\n\t\thandleSelectionDrag,\n\t\thandleSelectionRelease,\n\t\thandleRotateStart,\n\t\thandleRotateMove,\n\t\thandleRotateEnd,\n\t\thandleImageDragStart,\n\t\thandleImageDrag,\n\t\thandleImageDragEnd,\n\t\thandleImageDragRelease,\n\t\timageCropRangeAspectRatio,\n\t\timageZoomLevelRange,\n\t\timageZoomLevel,\n\t\thandleResizeStart,\n\t\thandleResizeMove,\n\t\thandleResizeEnd,\n\t\thandleGestureStart,\n\t\thandleGestureUpdate,\n\t\thandleGestureEnd,\n\t\thandleWheel,\n\t\thandleRecenterAction,\n\t\trecenterOpacity,\n\t\trecenterOffset,\n\t\tselectedPresetIndex,\n\t\timageSelectionGuides,\n\t\tcropUniqueId,\n\t\tfooterOffset,\n\t\tname,\n\t\tstores,\n\t\tcropWillRenderImageSelectionGuides,\n\t\tcropAutoCenterImageSelectionTimeout,\n\t\tcropEnableZoomMatchImageAspectRatio,\n\t\tcropEnableRotateMatchImageAspectRatio,\n\t\tcropEnableRotationInput,\n\t\tcropEnableZoomInput,\n\t\tcropEnableZoomAutoHide,\n\t\tcropEnableImageSelection,\n\t\tcropEnableInfoIndicator,\n\t\tcropEnableZoomTowardsWheelPosition,\n\t\tcropEnableLimitWheelInputToCropSelection,\n\t\tcropEnableCenterImageSelection,\n\t\tcropEnableButtonRotateLeft,\n\t\tcropEnableButtonRotateRight,\n\t\tcropEnableButtonFlipHorizontal,\n\t\tcropEnableButtonFlipVertical,\n\t\tcropSelectPresetOptions,\n\t\tcropEnableSelectPreset,\n\t\tcropEnableFilterMatchAspectRatio,\n\t\tcropSelectPresetFilter,\n\t\tcropEnableButtonToggleCropLimit,\n\t\tcropWillRenderTools,\n\t\tcropWillRenderInfoIndicator,\n\t\tcropActiveTransformTool,\n\t\tcropMinimizeToolbar,\n\t\tcropInteractionFocus,\n\t\tcropMaskOpacity,\n\t\tcropFormatIconSelectPreset,\n\t\tcropFormatIconCropBoundary,\n\t\tcropAutoCenterImageSelectionTimeoutId,\n\t\tisOverlayMode,\n\t\tshouldRenderZoomInput,\n\t\tcouldRenderZoomInput,\n\t\thasPlentyVerticalSpace,\n\t\tshouldRenderPresetSelect,\n\t\thasCropSelectPresetOptions,\n\t\timageSelectionOffset,\n\t\timageSelectionCenter,\n\t\tcanZoomToCenter,\n\t\tisImageSelectionCentered,\n\t\tisResizingSelection,\n\t\tisImageSelectionDisplayed,\n\t\tisMaxSelectionRect,\n\t\timageSelectionCenteredRect,\n\t\t$footerOffset,\n\t\t$isAnimated,\n\t\t$env,\n\t\t$imageSelectionGuides,\n\t\t$stagePadded,\n\t\t$imageSelectionRectPresentation,\n\t\t$isInteracting,\n\t\t$imageIsStatic,\n\t\t$imageOutputSize,\n\t\t$imageCropRect,\n\t\t$imageScalar,\n\t\t$presentationScalar,\n\t\t$imageSelectionRectSnapshot,\n\t\t$imageSelectionRect,\n\t\t$stageRect,\n\t\t$imageSize,\n\t\t$imageCropLimitToImage,\n\t\t$imageCropMinSize,\n\t\t$selectedPresetIndex,\n\t\t$currentPresetFilter,\n\t\t$formattedCropPresetOptions,\n\t\t$imageFlipY,\n\t\t$imageFlipX,\n\t\t$redrawTrigger,\n\t\tmeasure_handler_1,\n\t\tselect_handler,\n\t\tdiv0_binding,\n\t\tinteractable_function_1,\n\t\tutil_root_binding,\n\t\tmeasure_handler\n\t];\n}\n\nclass Crop extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$k,\n\t\t\tcreate_fragment$k,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 98,\n\t\t\t\tisActive: 0,\n\t\t\t\tstores: 99,\n\t\t\t\tcropImageSelectionCornerStyle: 1,\n\t\t\t\tcropWillRenderImageSelectionGuides: 100,\n\t\t\t\tcropAutoCenterImageSelectionTimeout: 101,\n\t\t\t\tcropEnableZoomMatchImageAspectRatio: 102,\n\t\t\t\tcropEnableRotateMatchImageAspectRatio: 103,\n\t\t\t\tcropEnableRotationInput: 104,\n\t\t\t\tcropEnableZoom: 2,\n\t\t\t\tcropEnableZoomInput: 105,\n\t\t\t\tcropEnableZoomAutoHide: 106,\n\t\t\t\tcropEnableImageSelection: 107,\n\t\t\t\tcropEnableInfoIndicator: 108,\n\t\t\t\tcropEnableZoomTowardsWheelPosition: 109,\n\t\t\t\tcropEnableLimitWheelInputToCropSelection: 110,\n\t\t\t\tcropEnableCenterImageSelection: 111,\n\t\t\t\tcropEnableButtonRotateLeft: 112,\n\t\t\t\tcropEnableButtonRotateRight: 113,\n\t\t\t\tcropEnableButtonFlipHorizontal: 114,\n\t\t\t\tcropEnableButtonFlipVertical: 115,\n\t\t\t\tcropSelectPresetOptions: 116,\n\t\t\t\tcropEnableSelectPreset: 117,\n\t\t\t\tcropEnableFilterMatchAspectRatio: 118,\n\t\t\t\tcropSelectPresetFilter: 119,\n\t\t\t\tcropEnableButtonToggleCropLimit: 120,\n\t\t\t\tcropWillRenderTools: 121,\n\t\t\t\tcropWillRenderInfoIndicator: 122,\n\t\t\t\tcropActiveTransformTool: 123,\n\t\t\t\tcropMinimizeToolbar: 124,\n\t\t\t\tcropInteractionFocus: 125,\n\t\t\t\tcropRotationRange: 3,\n\t\t\t\tcropMaskOpacity: 126,\n\t\t\t\tlocale: 4,\n\t\t\t\tcropFormatIconSelectPreset: 127,\n\t\t\t\tcropFormatIconCropBoundary: 128\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1, -1, -1, -1, -1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[98];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[99];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget cropImageSelectionCornerStyle() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset cropImageSelectionCornerStyle(cropImageSelectionCornerStyle) {\n\t\tthis.$$set({ cropImageSelectionCornerStyle });\n\t\tflush();\n\t}\n\n\tget cropWillRenderImageSelectionGuides() {\n\t\treturn this.$$.ctx[100];\n\t}\n\n\tset cropWillRenderImageSelectionGuides(cropWillRenderImageSelectionGuides) {\n\t\tthis.$$set({ cropWillRenderImageSelectionGuides });\n\t\tflush();\n\t}\n\n\tget cropAutoCenterImageSelectionTimeout() {\n\t\treturn this.$$.ctx[101];\n\t}\n\n\tset cropAutoCenterImageSelectionTimeout(cropAutoCenterImageSelectionTimeout) {\n\t\tthis.$$set({ cropAutoCenterImageSelectionTimeout });\n\t\tflush();\n\t}\n\n\tget cropEnableZoomMatchImageAspectRatio() {\n\t\treturn this.$$.ctx[102];\n\t}\n\n\tset cropEnableZoomMatchImageAspectRatio(cropEnableZoomMatchImageAspectRatio) {\n\t\tthis.$$set({ cropEnableZoomMatchImageAspectRatio });\n\t\tflush();\n\t}\n\n\tget cropEnableRotateMatchImageAspectRatio() {\n\t\treturn this.$$.ctx[103];\n\t}\n\n\tset cropEnableRotateMatchImageAspectRatio(cropEnableRotateMatchImageAspectRatio) {\n\t\tthis.$$set({ cropEnableRotateMatchImageAspectRatio });\n\t\tflush();\n\t}\n\n\tget cropEnableRotationInput() {\n\t\treturn this.$$.ctx[104];\n\t}\n\n\tset cropEnableRotationInput(cropEnableRotationInput) {\n\t\tthis.$$set({ cropEnableRotationInput });\n\t\tflush();\n\t}\n\n\tget cropEnableZoom() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset cropEnableZoom(cropEnableZoom) {\n\t\tthis.$$set({ cropEnableZoom });\n\t\tflush();\n\t}\n\n\tget cropEnableZoomInput() {\n\t\treturn this.$$.ctx[105];\n\t}\n\n\tset cropEnableZoomInput(cropEnableZoomInput) {\n\t\tthis.$$set({ cropEnableZoomInput });\n\t\tflush();\n\t}\n\n\tget cropEnableZoomAutoHide() {\n\t\treturn this.$$.ctx[106];\n\t}\n\n\tset cropEnableZoomAutoHide(cropEnableZoomAutoHide) {\n\t\tthis.$$set({ cropEnableZoomAutoHide });\n\t\tflush();\n\t}\n\n\tget cropEnableImageSelection() {\n\t\treturn this.$$.ctx[107];\n\t}\n\n\tset cropEnableImageSelection(cropEnableImageSelection) {\n\t\tthis.$$set({ cropEnableImageSelection });\n\t\tflush();\n\t}\n\n\tget cropEnableInfoIndicator() {\n\t\treturn this.$$.ctx[108];\n\t}\n\n\tset cropEnableInfoIndicator(cropEnableInfoIndicator) {\n\t\tthis.$$set({ cropEnableInfoIndicator });\n\t\tflush();\n\t}\n\n\tget cropEnableZoomTowardsWheelPosition() {\n\t\treturn this.$$.ctx[109];\n\t}\n\n\tset cropEnableZoomTowardsWheelPosition(cropEnableZoomTowardsWheelPosition) {\n\t\tthis.$$set({ cropEnableZoomTowardsWheelPosition });\n\t\tflush();\n\t}\n\n\tget cropEnableLimitWheelInputToCropSelection() {\n\t\treturn this.$$.ctx[110];\n\t}\n\n\tset cropEnableLimitWheelInputToCropSelection(cropEnableLimitWheelInputToCropSelection) {\n\t\tthis.$$set({ cropEnableLimitWheelInputToCropSelection });\n\t\tflush();\n\t}\n\n\tget cropEnableCenterImageSelection() {\n\t\treturn this.$$.ctx[111];\n\t}\n\n\tset cropEnableCenterImageSelection(cropEnableCenterImageSelection) {\n\t\tthis.$$set({ cropEnableCenterImageSelection });\n\t\tflush();\n\t}\n\n\tget cropEnableButtonRotateLeft() {\n\t\treturn this.$$.ctx[112];\n\t}\n\n\tset cropEnableButtonRotateLeft(cropEnableButtonRotateLeft) {\n\t\tthis.$$set({ cropEnableButtonRotateLeft });\n\t\tflush();\n\t}\n\n\tget cropEnableButtonRotateRight() {\n\t\treturn this.$$.ctx[113];\n\t}\n\n\tset cropEnableButtonRotateRight(cropEnableButtonRotateRight) {\n\t\tthis.$$set({ cropEnableButtonRotateRight });\n\t\tflush();\n\t}\n\n\tget cropEnableButtonFlipHorizontal() {\n\t\treturn this.$$.ctx[114];\n\t}\n\n\tset cropEnableButtonFlipHorizontal(cropEnableButtonFlipHorizontal) {\n\t\tthis.$$set({ cropEnableButtonFlipHorizontal });\n\t\tflush();\n\t}\n\n\tget cropEnableButtonFlipVertical() {\n\t\treturn this.$$.ctx[115];\n\t}\n\n\tset cropEnableButtonFlipVertical(cropEnableButtonFlipVertical) {\n\t\tthis.$$set({ cropEnableButtonFlipVertical });\n\t\tflush();\n\t}\n\n\tget cropSelectPresetOptions() {\n\t\treturn this.$$.ctx[116];\n\t}\n\n\tset cropSelectPresetOptions(cropSelectPresetOptions) {\n\t\tthis.$$set({ cropSelectPresetOptions });\n\t\tflush();\n\t}\n\n\tget cropEnableSelectPreset() {\n\t\treturn this.$$.ctx[117];\n\t}\n\n\tset cropEnableSelectPreset(cropEnableSelectPreset) {\n\t\tthis.$$set({ cropEnableSelectPreset });\n\t\tflush();\n\t}\n\n\tget cropEnableFilterMatchAspectRatio() {\n\t\treturn this.$$.ctx[118];\n\t}\n\n\tset cropEnableFilterMatchAspectRatio(cropEnableFilterMatchAspectRatio) {\n\t\tthis.$$set({ cropEnableFilterMatchAspectRatio });\n\t\tflush();\n\t}\n\n\tget cropSelectPresetFilter() {\n\t\treturn this.$$.ctx[119];\n\t}\n\n\tset cropSelectPresetFilter(cropSelectPresetFilter) {\n\t\tthis.$$set({ cropSelectPresetFilter });\n\t\tflush();\n\t}\n\n\tget cropEnableButtonToggleCropLimit() {\n\t\treturn this.$$.ctx[120];\n\t}\n\n\tset cropEnableButtonToggleCropLimit(cropEnableButtonToggleCropLimit) {\n\t\tthis.$$set({ cropEnableButtonToggleCropLimit });\n\t\tflush();\n\t}\n\n\tget cropWillRenderTools() {\n\t\treturn this.$$.ctx[121];\n\t}\n\n\tset cropWillRenderTools(cropWillRenderTools) {\n\t\tthis.$$set({ cropWillRenderTools });\n\t\tflush();\n\t}\n\n\tget cropWillRenderInfoIndicator() {\n\t\treturn this.$$.ctx[122];\n\t}\n\n\tset cropWillRenderInfoIndicator(cropWillRenderInfoIndicator) {\n\t\tthis.$$set({ cropWillRenderInfoIndicator });\n\t\tflush();\n\t}\n\n\tget cropActiveTransformTool() {\n\t\treturn this.$$.ctx[123];\n\t}\n\n\tset cropActiveTransformTool(cropActiveTransformTool) {\n\t\tthis.$$set({ cropActiveTransformTool });\n\t\tflush();\n\t}\n\n\tget cropMinimizeToolbar() {\n\t\treturn this.$$.ctx[124];\n\t}\n\n\tset cropMinimizeToolbar(cropMinimizeToolbar) {\n\t\tthis.$$set({ cropMinimizeToolbar });\n\t\tflush();\n\t}\n\n\tget cropInteractionFocus() {\n\t\treturn this.$$.ctx[125];\n\t}\n\n\tset cropInteractionFocus(cropInteractionFocus) {\n\t\tthis.$$set({ cropInteractionFocus });\n\t\tflush();\n\t}\n\n\tget cropRotationRange() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset cropRotationRange(cropRotationRange) {\n\t\tthis.$$set({ cropRotationRange });\n\t\tflush();\n\t}\n\n\tget cropMaskOpacity() {\n\t\treturn this.$$.ctx[126];\n\t}\n\n\tset cropMaskOpacity(cropMaskOpacity) {\n\t\tthis.$$set({ cropMaskOpacity });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget cropFormatIconSelectPreset() {\n\t\treturn this.$$.ctx[127];\n\t}\n\n\tset cropFormatIconSelectPreset(cropFormatIconSelectPreset) {\n\t\tthis.$$set({ cropFormatIconSelectPreset });\n\t\tflush();\n\t}\n\n\tget cropFormatIconCropBoundary() {\n\t\treturn this.$$.ctx[128];\n\t}\n\n\tset cropFormatIconCropBoundary(cropFormatIconCropBoundary) {\n\t\tthis.$$set({ cropFormatIconCropBoundary });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_crop = { util: ['crop', Crop] };\n\n/* src/core/ui/plugins/filter/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_option_slot$3(ctx) {\n\tlet div1;\n\tlet div0;\n\tlet option = /*option*/ ctx[77];\n\tlet t0;\n\tlet span;\n\n\tlet t1_value = (isFunction(/*option*/ ctx[77].label)\n\t? /*option*/ ctx[77].label(/*locale*/ ctx[2])\n\t: /*option*/ ctx[77].label) + \"\";\n\n\tlet t1;\n\tlet mounted;\n\tlet dispose;\n\n\tfunction measure_handler_1(...args) {\n\t\treturn /*measure_handler_1*/ ctx[51](/*option*/ ctx[77], ...args);\n\t}\n\n\tconst assign_div0 = () => /*div0_binding*/ ctx[52](div0, option);\n\tconst unassign_div0 = () => /*div0_binding*/ ctx[52](null, option);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv1 = element(\"div\");\n\t\t\tdiv0 = element(\"div\");\n\t\t\tt0 = space();\n\t\t\tspan = element(\"span\");\n\t\t\tt1 = text(t1_value);\n\t\t\tattr(div0, \"class\", FILTER_PREVIEW_CLASS_NAME);\n\t\t\tattr(div1, \"slot\", \"option\");\n\t\t\tattr(div1, \"class\", \"PinturaFilterOption\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div1, anchor);\n\t\t\tappend(div1, div0);\n\t\t\tassign_div0();\n\t\t\tappend(div1, t0);\n\t\t\tappend(div1, span);\n\t\t\tappend(span, t1);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div0, \"measure\", measure_handler_1),\n\t\t\t\t\taction_destroyer(measurable.call(null, div0))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (option !== /*option*/ ctx[77]) {\n\t\t\t\tunassign_div0();\n\t\t\t\toption = /*option*/ ctx[77];\n\t\t\t\tassign_div0();\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*locale*/ 4 | dirty[2] & /*option*/ 32768 && t1_value !== (t1_value = (isFunction(/*option*/ ctx[77].label)\n\t\t\t? /*option*/ ctx[77].label(/*locale*/ ctx[2])\n\t\t\t: /*option*/ ctx[77].label) + \"\")) set_data(t1, t1_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div1);\n\t\t\t}\n\n\t\t\tunassign_div0();\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (394:8) <Scrollable             elasticity={$elasticityMultiplier * scrollElasticity}             onscroll={(offset) => (tileScrollOffset = offset)}             bind:maskFeatherStartOpacity={tileLeftOpacity}             bind:maskFeatherEndOpacity={tileRightOpacity}             bind:maskFeatherSize={tileMargin}             on:measure={(e) => (tileScrollContainerRect = e.detail)}         >\nfunction create_default_slot$9(ctx) {\n\tlet radiogroup;\n\tlet current;\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[2],\n\t\t\t\tlayout: \"row\",\n\t\t\t\toptions: /*filterOptions*/ ctx[3],\n\t\t\t\tselectedIndex: /*selectedFilterIndex*/ ctx[12],\n\t\t\t\tonchange: /*handleChangeFilter*/ ctx[32],\n\t\t\t\t$$slots: {\n\t\t\t\t\toption: [\n\t\t\t\t\t\tcreate_option_slot$3,\n\t\t\t\t\t\t({ option }) => ({ 77: option }),\n\t\t\t\t\t\t({ option }) => [0, 0, option ? 32768 : 0]\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radiogroup, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 4) radiogroup_changes.locale = /*locale*/ ctx[2];\n\t\t\tif (dirty[0] & /*filterOptions*/ 8) radiogroup_changes.options = /*filterOptions*/ ctx[3];\n\t\t\tif (dirty[0] & /*selectedFilterIndex*/ 4096) radiogroup_changes.selectedIndex = /*selectedFilterIndex*/ ctx[12];\n\n\t\t\tif (dirty[0] & /*locale, tileElements*/ 1028 | dirty[2] & /*$$scope, option*/ 98304) {\n\t\t\t\tradiogroup_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radiogroup, detaching);\n\t\t}\n\t};\n}\n\n// (385:4) \nfunction create_footer_slot$5(ctx) {\n\tlet div;\n\tlet scrollable;\n\tlet updating_maskFeatherStartOpacity;\n\tlet updating_maskFeatherEndOpacity;\n\tlet updating_maskFeatherSize;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tfunction scrollable_maskFeatherStartOpacity_binding(value) {\n\t\t/*scrollable_maskFeatherStartOpacity_binding*/ ctx[54](value);\n\t}\n\n\tfunction scrollable_maskFeatherEndOpacity_binding(value) {\n\t\t/*scrollable_maskFeatherEndOpacity_binding*/ ctx[55](value);\n\t}\n\n\tfunction scrollable_maskFeatherSize_binding(value) {\n\t\t/*scrollable_maskFeatherSize_binding*/ ctx[56](value);\n\t}\n\n\tlet scrollable_props = {\n\t\telasticity: /*$elasticityMultiplier*/ ctx[13] * /*scrollElasticity*/ ctx[19],\n\t\tonscroll: /*func*/ ctx[53],\n\t\t$$slots: { default: [create_default_slot$9] },\n\t\t$$scope: { ctx }\n\t};\n\n\tif (/*tileLeftOpacity*/ ctx[4] !== void 0) {\n\t\tscrollable_props.maskFeatherStartOpacity = /*tileLeftOpacity*/ ctx[4];\n\t}\n\n\tif (/*tileRightOpacity*/ ctx[5] !== void 0) {\n\t\tscrollable_props.maskFeatherEndOpacity = /*tileRightOpacity*/ ctx[5];\n\t}\n\n\tif (/*tileMargin*/ ctx[6] !== void 0) {\n\t\tscrollable_props.maskFeatherSize = /*tileMargin*/ ctx[6];\n\t}\n\n\tscrollable = new Scrollable({ props: scrollable_props });\n\tbinding_callbacks.push(() => bind(scrollable, 'maskFeatherStartOpacity', scrollable_maskFeatherStartOpacity_binding));\n\tbinding_callbacks.push(() => bind(scrollable, 'maskFeatherEndOpacity', scrollable_maskFeatherEndOpacity_binding));\n\tbinding_callbacks.push(() => bind(scrollable, 'maskFeatherSize', scrollable_maskFeatherSize_binding));\n\tscrollable.$on(\"measure\", /*measure_handler_2*/ ctx[57]);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t\tattr(div, \"slot\", \"footer\");\n\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[11]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(scrollable, div, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"transitionend\", /*handleTransitionEnd*/ ctx[30]),\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler_3*/ ctx[58]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div, { observePosition: true }))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty[0] & /*$elasticityMultiplier*/ 8192) scrollable_changes.elasticity = /*$elasticityMultiplier*/ ctx[13] * /*scrollElasticity*/ ctx[19];\n\t\t\tif (dirty[0] & /*tileScrollOffset*/ 128) scrollable_changes.onscroll = /*func*/ ctx[53];\n\n\t\t\tif (dirty[0] & /*locale, filterOptions, selectedFilterIndex, tileElements*/ 5132 | dirty[2] & /*$$scope*/ 65536) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tif (!updating_maskFeatherStartOpacity && dirty[0] & /*tileLeftOpacity*/ 16) {\n\t\t\t\tupdating_maskFeatherStartOpacity = true;\n\t\t\t\tscrollable_changes.maskFeatherStartOpacity = /*tileLeftOpacity*/ ctx[4];\n\t\t\t\tadd_flush_callback(() => updating_maskFeatherStartOpacity = false);\n\t\t\t}\n\n\t\t\tif (!updating_maskFeatherEndOpacity && dirty[0] & /*tileRightOpacity*/ 32) {\n\t\t\t\tupdating_maskFeatherEndOpacity = true;\n\t\t\t\tscrollable_changes.maskFeatherEndOpacity = /*tileRightOpacity*/ ctx[5];\n\t\t\t\tadd_flush_callback(() => updating_maskFeatherEndOpacity = false);\n\t\t\t}\n\n\t\t\tif (!updating_maskFeatherSize && dirty[0] & /*tileMargin*/ 64) {\n\t\t\t\tupdating_maskFeatherSize = true;\n\t\t\t\tscrollable_changes.maskFeatherSize = /*tileMargin*/ ctx[6];\n\t\t\t\tadd_flush_callback(() => updating_maskFeatherSize = false);\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\n\t\t\tif (dirty[0] & /*styleFooterTransform*/ 2048) {\n\t\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[11]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(scrollable);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$j(ctx) {\n\tlet util;\n\tlet current;\n\n\tutil = new Util({\n\t\t\tprops: {\n\t\t\t\t$$slots: { footer: [create_footer_slot$5] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tutil.$on(\"measure\", /*measure_handler*/ ctx[59]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(util.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(util, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst util_changes = {};\n\n\t\t\tif (dirty[0] & /*styleFooterTransform, footerRect, $elasticityMultiplier, tileScrollOffset, tileLeftOpacity, tileRightOpacity, tileMargin, tileScrollContainerRect, locale, filterOptions, selectedFilterIndex, tileElements*/ 16380 | dirty[2] & /*$$scope*/ 65536) {\n\t\t\t\tutil_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tutil.$set(util_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(util.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(util.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(util, detaching);\n\t\t}\n\t};\n}\n\nlet FILTER_PREVIEW_CLASS_NAME = 'PinturaFilterPreview';\n\nfunction instance$j($$self, $$props, $$invalidate) {\n\tlet filterOptionsFlattened;\n\tlet selectedFilterIndex;\n\tlet styleFooterTransform;\n\tlet $footerOffset;\n\tlet $imageColorMatrix;\n\tlet $imageTiles;\n\tlet $imagePreview;\n\n\tlet $isActiveFraction,\n\t\t$$unsubscribe_isActiveFraction = noop,\n\t\t$$subscribe_isActiveFraction = () => ($$unsubscribe_isActiveFraction(), $$unsubscribe_isActiveFraction = subscribe(isActiveFraction, $$value => $$invalidate(43, $isActiveFraction = $$value)), isActiveFraction);\n\n\tlet $interfaceImages;\n\tlet $imageBackgroundColor;\n\tlet $imageSize;\n\tlet $imageGamma;\n\tlet $imageTransforms;\n\tlet $tileRects;\n\tlet $utilRect;\n\tlet $stageRectBase;\n\n\tlet $isActive,\n\t\t$$unsubscribe_isActive = noop,\n\t\t$$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(49, $isActive = $$value)), isActive);\n\n\tlet $animation;\n\tlet $canvasSize;\n\tlet $elasticityMultiplier;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActiveFraction());\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActive());\n\tconst name = 'filter';\n\tlet { isActive } = $$props;\n\t$$subscribe_isActive();\n\tlet { isActiveFraction } = $$props;\n\t$$subscribe_isActiveFraction();\n\tlet { stores } = $$props;\n\tlet { locale } = $$props;\n\tlet { filterFunctions } = $$props;\n\tlet { filterOptions } = $$props;\n\n\t// context\n\tconst elasticityMultiplier = getContext('elasticityMultiplier');\n\n\tcomponent_subscribe($$self, elasticityMultiplier, value => $$invalidate(13, $elasticityMultiplier = value));\n\n\t// connect filter choice to stores\n\tconst { history, interfaceImages, stageRectBase, utilRect, animation, scrollElasticity, imageSize, imagePreview, imageCropRect, imageRotation, imageFlipX, imageFlipY, imageBackgroundColor, imageGamma, imageColorMatrix, allowPan, allowZoom, allowZoomControls, allowPlayPause } = stores;\n\n\tcomponent_subscribe($$self, interfaceImages, value => $$invalidate(60, $interfaceImages = value));\n\tcomponent_subscribe($$self, stageRectBase, value => $$invalidate(48, $stageRectBase = value));\n\tcomponent_subscribe($$self, utilRect, value => $$invalidate(47, $utilRect = value));\n\tcomponent_subscribe($$self, animation, value => $$invalidate(50, $animation = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(62, $imageSize = value));\n\tcomponent_subscribe($$self, imagePreview, value => $$invalidate(42, $imagePreview = value));\n\tcomponent_subscribe($$self, imageBackgroundColor, value => $$invalidate(61, $imageBackgroundColor = value));\n\tcomponent_subscribe($$self, imageGamma, value => $$invalidate(44, $imageGamma = value));\n\tcomponent_subscribe($$self, imageColorMatrix, value => $$invalidate(40, $imageColorMatrix = value));\n\n\tconst getFilterIndex = (imageColorMatrix, filterOptionsFlattened) => {\n\t\tif (!imageColorMatrix || !imageColorMatrix['filter'] || !filterOptionsFlattened) return 0;\n\t\tconst filterColorMatrix = imageColorMatrix['filter'];\n\n\t\treturn filterOptionsFlattened.// get id and compare matrices\n\t\tfindIndex(([id]) => {\n\t\t\tif (!filterFunctions[id]) return false;\n\t\t\tconst matrix = filterFunctions[id]();\n\t\t\treturn arrayEqual(matrix, filterColorMatrix);\n\t\t});\n\t};\n\n\tconst tileRects = writable({});\n\tcomponent_subscribe($$self, tileRects, value => $$invalidate(46, $tileRects = value));\n\tconst handleTileResize = (item, rect) => set_store_value(tileRects, $tileRects[item.value] = rect, $tileRects);\n\n\tconst canvasSize = derived(tileRects, $tileRects => {\n\t\tif (!$tileRects[undefined]) return;\n\t\tconst tileRectFirst = $tileRects[undefined];\n\t\tif ($canvasSize && sizeEqual($canvasSize, tileRectFirst)) return $canvasSize;\n\t\treturn sizeClone(tileRectFirst);\n\t});\n\n\tcomponent_subscribe($$self, canvasSize, value => $$invalidate(63, $canvasSize = value));\n\n\tconst imageTransforms = derived(\n\t\t[\n\t\t\tisActive,\n\t\t\tcanvasSize,\n\t\t\timageCropRect,\n\t\t\timageSize,\n\t\t\timageRotation,\n\t\t\timageFlipX,\n\t\t\timageFlipY\n\t\t],\n\t\t([\n\t\t\t\t$isActive,\n\t\t\t\t$canvasSize,\n\t\t\t\t$imageCropRect,\n\t\t\t\t$imageSize,\n\t\t\t\t$imageRotation,\n\t\t\t\t$imageFlipX,\n\t\t\t\t$imageFlipY\n\t\t\t], set) => {\n\t\t\tif (!$isActive || !$canvasSize || !$imageSize) return $imageTransforms;\n\t\t\tconst imageRect = rectCreateFromSize($imageSize);\n\t\t\tconst imageCenter = rectCenter(imageRect);\n\n\t\t\t// get base crop rect so we can correctly apply transforms\n\t\t\tconst cropRectBase = getBaseCropRect($imageSize, $imageCropRect, $imageRotation);\n\n\t\t\tconst cropRectBaseCenter = rectCenter(cropRectBase);\n\t\t\tconst imageTranslation = vectorSubtract(vectorClone(imageCenter), cropRectBaseCenter);\n\t\t\tconst imageOrigin = vectorInvert(vectorClone(imageTranslation));\n\n\t\t\t// scalar\n\t\t\tconst imageScalar = Math.max($canvasSize.width / $imageCropRect.width, $canvasSize.height / $imageCropRect.height);\n\n\t\t\t// update preview transforms\n\t\t\tset({\n\t\t\t\torigin: imageOrigin,\n\t\t\t\ttranslation: imageTranslation,\n\t\t\t\trotation: {\n\t\t\t\t\tx: $imageFlipY ? Math.PI : 0,\n\t\t\t\t\ty: $imageFlipX ? Math.PI : 0,\n\t\t\t\t\tz: $imageRotation\n\t\t\t\t},\n\t\t\t\tscale: imageScalar\n\t\t\t});\n\t\t}\n\t);\n\n\tcomponent_subscribe($$self, imageTransforms, value => $$invalidate(45, $imageTransforms = value));\n\n\tconst cloneImageTransforms = imageTransforms => ({\n\t\torigin: vectorClone(imageTransforms.origin),\n\t\ttranslation: vectorClone(imageTransforms.translation),\n\t\trotation: { ...imageTransforms.rotation },\n\t\t// perspective: vectorClone(imageTransforms.perspective),\n\t\tscale: imageTransforms.scale\n\t});\n\n\t//\n\t// Footer\n\t//\n\tconst footerOffset = spring($animation ? 20 : 0);\n\n\tcomponent_subscribe($$self, footerOffset, value => $$invalidate(39, $footerOffset = value));\n\tlet tileCornerRadius;\n\tconst tileElements = {};\n\n\tconst handleTransitionEnd = e => {\n\t\tif (e.target.className !== FILTER_PREVIEW_CLASS_NAME) return;\n\n\t\t$$invalidate(36, tileCornerRadius = Object.keys(tileElements).reduce(\n\t\t\t(prev, curr) => {\n\t\t\t\tconst element = tileElements[curr];\n\t\t\t\tconst style = getComputedStyle(element);\n\n\t\t\t\tconst corners = ['top-left', 'top-right', 'bottom-left', 'bottom-right'].map(corner => style.getPropertyValue(`border-${corner}-radius`)).map(unitToPixels).// this better aligns WebGL rounded corner with css rounded corner\n\t\t\t\tmap(v => v * 1.25);\n\n\t\t\t\tprev[curr] = corners;\n\t\t\t\treturn prev;\n\t\t\t},\n\t\t\t{}\n\t\t));\n\t};\n\n\tlet tileLeftOpacity; // set by Scrollable\n\tlet tileRightOpacity; // set by Scrollable\n\tlet tileMargin; // set by Scrollable\n\tlet tileScrollOffset = { x: 0, y: 0 };\n\tlet tileScrollContainerRect;\n\tlet tileWrapperOffset;\n\tlet footerRect;\n\tconst imageTiles = writable([]);\n\tcomponent_subscribe($$self, imageTiles, value => $$invalidate(41, $imageTiles = value));\n\n\t// clones an image tile for use in canvas\n\tconst cloneImageTile = tile => {\n\t\tconst clone = {\n\t\t\t// doesn't clone everything but should be enough\n\t\t\t...tile,\n\t\t\tdata: $imagePreview,\n\t\t\tsize: $imageSize,\n\t\t\toffset: { ...tile.offset },\n\t\t\tmask: { ...tile.mask },\n\t\t\tbackgroundColor: $imageBackgroundColor\n\t\t};\n\n\t\tclone.opacity = $isActiveFraction;\n\t\tclone.offset.y += $footerOffset;\n\t\tclone.mask.y += $footerOffset;\n\t\tclone.id = 'filter';\n\t\treturn clone;\n\t};\n\n\tconst filterInterfaceImages = () => $interfaceImages.filter(tile => tile.id !== 'filter');\n\n\tconst handleChangeFilter = ({ value }) => {\n\t\tset_store_value(\n\t\t\timageColorMatrix,\n\t\t\t$imageColorMatrix = {\n\t\t\t\t// add other keys\n\t\t\t\t...$imageColorMatrix,\n\t\t\t\t// filter is always last\n\t\t\t\tfilter: isFunction(filterFunctions[value])\n\t\t\t\t? filterFunctions[value]()\n\t\t\t\t: undefined\n\t\t\t},\n\t\t\t$imageColorMatrix\n\t\t);\n\n\t\thistory.write();\n\t};\n\n\t// when destroyed we need to make sure all filter image previews are cleared\n\tonDestroy(() => {\n\t\tinterfaceImages.set([]);\n\t});\n\n\tconst measure_handler_1 = (option, e) => handleTileResize(option, e.detail);\n\n\tfunction div0_binding($$value, option) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\ttileElements[option.value] = $$value;\n\t\t\t$$invalidate(10, tileElements);\n\t\t});\n\t}\n\n\tconst func = offset => $$invalidate(7, tileScrollOffset = offset);\n\n\tfunction scrollable_maskFeatherStartOpacity_binding(value) {\n\t\ttileLeftOpacity = value;\n\t\t$$invalidate(4, tileLeftOpacity);\n\t}\n\n\tfunction scrollable_maskFeatherEndOpacity_binding(value) {\n\t\ttileRightOpacity = value;\n\t\t$$invalidate(5, tileRightOpacity);\n\t}\n\n\tfunction scrollable_maskFeatherSize_binding(value) {\n\t\ttileMargin = value;\n\t\t$$invalidate(6, tileMargin);\n\t}\n\n\tconst measure_handler_2 = e => $$invalidate(8, tileScrollContainerRect = e.detail);\n\tconst measure_handler_3 = e => $$invalidate(9, footerRect = e.detail);\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));\n\t\tif ('isActiveFraction' in $$props) $$subscribe_isActiveFraction($$invalidate(1, isActiveFraction = $$props.isActiveFraction));\n\t\tif ('stores' in $$props) $$invalidate(34, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(2, locale = $$props.locale);\n\t\tif ('filterFunctions' in $$props) $$invalidate(35, filterFunctions = $$props.filterFunctions);\n\t\tif ('filterOptions' in $$props) $$invalidate(3, filterOptions = $$props.filterOptions);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 262144) {\n\t\t\t// enable pan and zoom\n\t\t\tallowPan.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 262144) {\n\t\t\tallowZoom.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 262144) {\n\t\t\tallowZoomControls.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 262144) {\n\t\t\t$isActive && allowPlayPause.set(false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*filterOptions*/ 8) {\n\t\t\t$$invalidate(38, filterOptionsFlattened = flattenOptions(filterOptions));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageColorMatrix, filterOptionsFlattened*/ 640) {\n\t\t\t$$invalidate(12, selectedFilterIndex = getFilterIndex($imageColorMatrix, filterOptionsFlattened));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$animation, $isActive*/ 786432) {\n\t\t\t$animation && footerOffset.set($isActive ? 0 : 20);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*footerRect*/ 512 | $$self.$$.dirty[1] & /*$isActive, $utilRect, $stageRectBase*/ 458752) {\n\t\t\tif ($isActive && $utilRect && $stageRectBase && footerRect) {\n\t\t\t\t$$invalidate(37, tileWrapperOffset = {\n\t\t\t\t\tx: $stageRectBase.x - $utilRect.x,\n\t\t\t\t\ty: $stageRectBase.y - $utilRect.y + footerRect.y\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*tileScrollOffset, tileScrollContainerRect, tileMargin, tileLeftOpacity, tileRightOpacity*/ 496 | $$self.$$.dirty[1] & /*$imageTransforms, tileWrapperOffset, tileCornerRadius, filterOptionsFlattened, $tileRects, $imageColorMatrix, filterFunctions, $imageGamma*/ 58096) {\n\t\t\tif ($imageTransforms && tileWrapperOffset && tileScrollOffset && tileScrollContainerRect && tileCornerRadius) {\n\t\t\t\tconst boundsX = tileWrapperOffset.x + tileScrollContainerRect.x;\n\t\t\t\tconst offsetX = boundsX + tileScrollOffset.x;\n\t\t\t\tconst offsetY = tileWrapperOffset.y;\n\t\t\t\tconst containerLeft = tileScrollContainerRect.x + tileWrapperOffset.x;\n\t\t\t\tconst containerRight = containerLeft + tileScrollContainerRect.width;\n\n\t\t\t\timageTiles.set(filterOptionsFlattened.map(([id], i) => {\n\t\t\t\t\tconst tileRect = $tileRects[id];\n\n\t\t\t\t\t// test if is outside of view\n\t\t\t\t\tconst tileLeft = tileScrollOffset.x + tileRect.x;\n\n\t\t\t\t\tconst tileRight = tileLeft + tileRect.width;\n\t\t\t\t\tif (tileRight < 0 || tileLeft > tileScrollContainerRect.width) return false;\n\t\t\t\t\tconst x = offsetX + tileRect.x;\n\t\t\t\t\tconst y = offsetY + tileRect.y;\n\t\t\t\t\tconst preview = cloneImageTransforms($imageTransforms);\n\t\t\t\t\tpreview.offset = vectorCreate(tileRect.width * 0.5 + x, tileRect.height * 0.5 + y);\n\t\t\t\t\tlet clipX = 0;\n\t\t\t\t\tlet clipWidth = 0;\n\t\t\t\t\tpreview.maskOpacity = 1;\n\t\t\t\t\tpreview.mask = rectCreate(x + clipX, y, tileRect.width + clipWidth, tileRect.height);\n\t\t\t\t\tpreview.maskFeather = [1, 0, 1, 0, 1, containerRight, 1, containerRight];\n\n\t\t\t\t\tif (tileLeft < tileMargin && tileLeftOpacity < 1) {\n\t\t\t\t\t\tpreview.maskFeather[0] = tileLeftOpacity;\n\t\t\t\t\t\tpreview.maskFeather[1] = containerLeft;\n\t\t\t\t\t\tpreview.maskFeather[2] = 1;\n\t\t\t\t\t\tpreview.maskFeather[3] = containerLeft + tileMargin;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (tileRight > tileScrollContainerRect.width - tileMargin && tileRightOpacity < 1) {\n\t\t\t\t\t\tpreview.maskFeather[4] = tileRightOpacity;\n\t\t\t\t\t\tpreview.maskFeather[5] = containerRight - tileMargin;\n\t\t\t\t\t\tpreview.maskFeather[6] = 1;\n\t\t\t\t\t\tpreview.maskFeather[7] = containerRight;\n\t\t\t\t\t}\n\n\t\t\t\t\tpreview.maskCornerRadius = tileCornerRadius[id];\n\t\t\t\t\tlet colorMatrices = $imageColorMatrix && Object.keys($imageColorMatrix).filter(name => name != 'filter').map(name => $imageColorMatrix[name]) || [];\n\n\t\t\t\t\tif (isFunction(filterFunctions[id])) {\n\t\t\t\t\t\tcolorMatrices.push(filterFunctions[id]());\n\t\t\t\t\t}\n\n\t\t\t\t\tpreview.colorMatrix = colorMatrices.length\n\t\t\t\t\t? getColorMatrixFromColorMatrices(colorMatrices)\n\t\t\t\t\t: undefined;\n\n\t\t\t\t\tpreview.gamma = $imageGamma;\n\t\t\t\t\treturn preview;\n\t\t\t\t}).filter(Boolean));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActiveFraction, $imageTiles, $footerOffset, $imagePreview*/ 7424) {\n\t\t\t// Will update `interfaceImages` store when\n\t\t\t// - $isActiveFraction is updated\n\t\t\t// - $imageTiles is updated\n\t\t\t// - $footerOffset is updated\n\t\t\tif ($isActiveFraction > 0 && $imageTiles) {\n\n\t\t\t\tconst images = [\n\t\t\t\t\t// remove filter tiles\n\t\t\t\t\t...filterInterfaceImages(),\n\t\t\t\t\t// add new filter tiles\n\t\t\t\t\t...$imageTiles.map(cloneImageTile)\n\t\t\t\t];\n\n\t\t\t\t// images\n\t\t\t\tinterfaceImages.set(images);\n\t\t\t} else {\n\t\t\t\tinterfaceImages.set(// remove filter tiles\n\t\t\t\tfilterInterfaceImages());\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$footerOffset*/ 256) {\n\t\t\t$$invalidate(11, styleFooterTransform = $footerOffset\n\t\t\t? `translateY(${$footerOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tisActiveFraction,\n\t\tlocale,\n\t\tfilterOptions,\n\t\ttileLeftOpacity,\n\t\ttileRightOpacity,\n\t\ttileMargin,\n\t\ttileScrollOffset,\n\t\ttileScrollContainerRect,\n\t\tfooterRect,\n\t\ttileElements,\n\t\tstyleFooterTransform,\n\t\tselectedFilterIndex,\n\t\t$elasticityMultiplier,\n\t\telasticityMultiplier,\n\t\tinterfaceImages,\n\t\tstageRectBase,\n\t\tutilRect,\n\t\tanimation,\n\t\tscrollElasticity,\n\t\timageSize,\n\t\timagePreview,\n\t\timageBackgroundColor,\n\t\timageGamma,\n\t\timageColorMatrix,\n\t\ttileRects,\n\t\thandleTileResize,\n\t\tcanvasSize,\n\t\timageTransforms,\n\t\tfooterOffset,\n\t\thandleTransitionEnd,\n\t\timageTiles,\n\t\thandleChangeFilter,\n\t\tname,\n\t\tstores,\n\t\tfilterFunctions,\n\t\ttileCornerRadius,\n\t\ttileWrapperOffset,\n\t\tfilterOptionsFlattened,\n\t\t$footerOffset,\n\t\t$imageColorMatrix,\n\t\t$imageTiles,\n\t\t$imagePreview,\n\t\t$isActiveFraction,\n\t\t$imageGamma,\n\t\t$imageTransforms,\n\t\t$tileRects,\n\t\t$utilRect,\n\t\t$stageRectBase,\n\t\t$isActive,\n\t\t$animation,\n\t\tmeasure_handler_1,\n\t\tdiv0_binding,\n\t\tfunc,\n\t\tscrollable_maskFeatherStartOpacity_binding,\n\t\tscrollable_maskFeatherEndOpacity_binding,\n\t\tscrollable_maskFeatherSize_binding,\n\t\tmeasure_handler_2,\n\t\tmeasure_handler_3,\n\t\tmeasure_handler\n\t];\n}\n\nclass Filter extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$j,\n\t\t\tcreate_fragment$j,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 33,\n\t\t\t\tisActive: 0,\n\t\t\t\tisActiveFraction: 1,\n\t\t\t\tstores: 34,\n\t\t\t\tlocale: 2,\n\t\t\t\tfilterFunctions: 35,\n\t\t\t\tfilterOptions: 3\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[33];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget isActiveFraction() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset isActiveFraction(isActiveFraction) {\n\t\tthis.$$set({ isActiveFraction });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[34];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget filterFunctions() {\n\t\treturn this.$$.ctx[35];\n\t}\n\n\tset filterFunctions(filterFunctions) {\n\t\tthis.$$set({ filterFunctions });\n\t\tflush();\n\t}\n\n\tget filterOptions() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset filterOptions(filterOptions) {\n\t\tthis.$$set({ filterOptions });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_filter = { util: ['filter', Filter] };\n\n/* src/core/ui/plugins/finetune/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block$8(ctx) {\n\tlet scrollable;\n\tlet t;\n\tlet tabpanels;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\telasticity: /*$elasticityMultiplier*/ ctx[6] * /*scrollElasticity*/ ctx[9],\n\t\t\t\tclass: \"PinturaControlListScroller\",\n\t\t\t\t$$slots: { default: [create_default_slot_1$2] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tconst tabpanels_spread_levels = [\n\t\t{ class: \"PinturaControlPanels\" },\n\t\t{ panelClass: \"PinturaControlPanel\" },\n\t\t{ panels: /*panels*/ ctx[4] },\n\t\t/*tabsConfig*/ ctx[5]\n\t];\n\n\tlet tabpanels_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot$8,\n\t\t\t\t({ panel }) => ({ 44: panel }),\n\t\t\t\t({ panel }) => [0, panel ? 8192 : 0]\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tabpanels_spread_levels.length; i += 1) {\n\t\ttabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);\n\t}\n\n\ttabpanels = new TabPanels({ props: tabpanels_props });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t\tt = space();\n\t\t\tcreate_component(tabpanels.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(scrollable, target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tmount_component(tabpanels, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty[0] & /*$elasticityMultiplier*/ 64) scrollable_changes.elasticity = /*$elasticityMultiplier*/ ctx[6] * /*scrollElasticity*/ ctx[9];\n\n\t\t\tif (dirty[0] & /*tabs, tabsConfig, tabSelected*/ 38 | dirty[1] & /*$$scope*/ 32768) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\n\t\t\tconst tabpanels_changes = (dirty[0] & /*panels, tabsConfig*/ 48)\n\t\t\t? get_spread_update(tabpanels_spread_levels, [\n\t\t\t\t\ttabpanels_spread_levels[0],\n\t\t\t\t\ttabpanels_spread_levels[1],\n\t\t\t\t\tdirty[0] & /*panels*/ 16 && { panels: /*panels*/ ctx[4] },\n\t\t\t\t\tdirty[0] & /*tabsConfig*/ 32 && get_spread_object(/*tabsConfig*/ ctx[5])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty[0] & /*$rangeInputConfig*/ 128 | dirty[1] & /*$$scope, panel*/ 40960) {\n\t\t\t\ttabpanels_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttabpanels.$set(tabpanels_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\ttransition_in(tabpanels.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\ttransition_out(tabpanels.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t}\n\n\t\t\tdestroy_component(scrollable, detaching);\n\t\t\tdestroy_component(tabpanels, detaching);\n\t\t}\n\t};\n}\n\n// (192:16) <TabList                     class=\"PinturaControlList\"                     {tabs}                     {...tabsConfig}                     on:select={({ detail }) => (tabSelected = detail)}                     let:tab                 >\nfunction create_default_slot_2$2(ctx) {\n\tlet span;\n\tlet t_value = /*tab*/ ctx[45].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*tab*/ 16384 && t_value !== (t_value = /*tab*/ ctx[45].label + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (188:12) <Scrollable                 elasticity={$elasticityMultiplier * scrollElasticity}                 class=\"PinturaControlListScroller\"             >\nfunction create_default_slot_1$2(ctx) {\n\tlet tablist;\n\tlet current;\n\n\tconst tablist_spread_levels = [\n\t\t{ class: \"PinturaControlList\" },\n\t\t{ tabs: /*tabs*/ ctx[1] },\n\t\t/*tabsConfig*/ ctx[5]\n\t];\n\n\tlet tablist_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot_2$2,\n\t\t\t\t({ tab }) => ({ 45: tab }),\n\t\t\t\t({ tab }) => [0, tab ? 16384 : 0]\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tablist_spread_levels.length; i += 1) {\n\t\ttablist_props = assign(tablist_props, tablist_spread_levels[i]);\n\t}\n\n\ttablist = new TabList({ props: tablist_props });\n\ttablist.$on(\"select\", /*select_handler*/ ctx[24]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(tablist.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(tablist, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst tablist_changes = (dirty[0] & /*tabs, tabsConfig*/ 34)\n\t\t\t? get_spread_update(tablist_spread_levels, [\n\t\t\t\t\ttablist_spread_levels[0],\n\t\t\t\t\tdirty[0] & /*tabs*/ 2 && { tabs: /*tabs*/ ctx[1] },\n\t\t\t\t\tdirty[0] & /*tabsConfig*/ 32 && get_spread_object(/*tabsConfig*/ ctx[5])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty[1] & /*$$scope, tab*/ 49152) {\n\t\t\t\ttablist_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttablist.$set(tablist_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(tablist.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(tablist.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(tablist, detaching);\n\t\t}\n\t};\n}\n\n// (203:12) <TabPanels                 class=\"PinturaControlPanels\"                 panelClass=\"PinturaControlPanel\"                 {panels}                 {...tabsConfig}                 let:panel             >\nfunction create_default_slot$8(ctx) {\n\tlet rangeinput;\n\tlet current;\n\tconst rangeinput_spread_levels = [/*$rangeInputConfig*/ ctx[7][/*panel*/ ctx[44]]];\n\tlet rangeinput_props = {};\n\n\tfor (let i = 0; i < rangeinput_spread_levels.length; i += 1) {\n\t\trangeinput_props = assign(rangeinput_props, rangeinput_spread_levels[i]);\n\t}\n\n\trangeinput = new RangeInput({ props: rangeinput_props });\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(rangeinput.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(rangeinput, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst rangeinput_changes = (dirty[0] & /*$rangeInputConfig*/ 128 | dirty[1] & /*panel*/ 8192)\n\t\t\t? get_spread_update(rangeinput_spread_levels, [get_spread_object(/*$rangeInputConfig*/ ctx[7][/*panel*/ ctx[44]])])\n\t\t\t: {};\n\n\t\t\trangeinput.$set(rangeinput_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(rangeinput.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(rangeinput.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(rangeinput, detaching);\n\t\t}\n\t};\n}\n\n// (186:4) \nfunction create_footer_slot$4(ctx) {\n\tlet div;\n\tlet current;\n\tlet if_block = /*tabsConfig*/ ctx[5] && create_if_block$8(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(div, \"slot\", \"footer\");\n\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[3]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*tabsConfig*/ ctx[5]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*tabsConfig*/ 32) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$8(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleFooterTransform*/ 8) {\n\t\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[3]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t}\n\t};\n}\n\nfunction create_fragment$i(ctx) {\n\tlet util;\n\tlet current;\n\n\tutil = new Util({\n\t\t\tprops: {\n\t\t\t\t$$slots: { footer: [create_footer_slot$4] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tutil.$on(\"measure\", /*measure_handler*/ ctx[25]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(util.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(util, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst util_changes = {};\n\n\t\t\tif (dirty[0] & /*styleFooterTransform, panels, tabsConfig, $rangeInputConfig, $elasticityMultiplier, tabs, tabSelected*/ 254 | dirty[1] & /*$$scope*/ 32768) {\n\t\t\t\tutil_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tutil.$set(util_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(util.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(util.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(util, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$i($$self, $$props, $$invalidate) {\n\tlet tabs;\n\tlet tabSelected;\n\tlet tabsConfig;\n\tlet panels;\n\tlet colorMatrixKeyOrder;\n\tlet styleFooterTransform;\n\tlet $footerOffset;\n\n\tlet $isActive,\n\t\t$$unsubscribe_isActive = noop,\n\t\t$$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(21, $isActive = $$value)), isActive);\n\n\tlet $animation;\n\tlet $panelValues;\n\tlet $elasticityMultiplier;\n\tlet $rangeInputConfig;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActive());\n\tconst name = 'finetune';\n\tlet { stores } = $$props;\n\tlet { isActive } = $$props;\n\t$$subscribe_isActive();\n\tlet { locale = {} } = $$props;\n\tlet { finetuneControlConfiguration } = $$props;\n\tlet { finetuneOptions } = $$props;\n\tlet { finetuneNudgePrecision = undefined } = $$props;\n\tconst { history, animation, scrollElasticity, rangeInputElasticity, imageColorMatrix, imageConvolutionMatrix, imageGamma, imageVignette, imageNoise, allowPan, allowZoom, allowZoomControls, allowPlayPause } = stores;\n\tcomponent_subscribe($$self, animation, value => $$invalidate(22, $animation = value));\n\n\tconst imageEffectStores = {\n\t\timageColorMatrix,\n\t\timageConvolutionMatrix,\n\t\timageGamma,\n\t\timageVignette,\n\t\timageNoise\n\t};\n\n\t//\n\t// context\n\t//\n\tconst elasticityMultiplier = getContext('elasticityMultiplier');\n\n\tcomponent_subscribe($$self, elasticityMultiplier, value => $$invalidate(6, $elasticityMultiplier = value));\n\n\t//\n\t// Tabs\n\t//\n\tconst uid = `finetune-${getUniqueId()}`;\n\n\t//\n\t// Range inputs\n\t//\n\tconst panelValues = writable({});\n\n\tcomponent_subscribe($$self, panelValues, value => $$invalidate(23, $panelValues = value));\n\tconst rangeInputConfig = writable({});\n\tcomponent_subscribe($$self, rangeInputConfig, value => $$invalidate(7, $rangeInputConfig = value));\n\n\tconst orderStoreKeys = (store, order) => {\n\t\tstore.update(state => {\n\t\t\tconst out = {};\n\n\t\t\torder.forEach(key => {\n\t\t\t\tif (!state[key]) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tout[key] = state[key];\n\t\t\t});\n\n\t\t\treturn out;\n\t\t});\n\t};\n\n\tconst updateRangeInputState = () => {\n\t\tset_store_value(\n\t\t\trangeInputConfig,\n\t\t\t$rangeInputConfig = Object.keys($panelValues).reduce(\n\t\t\t\t(config, id) => {\n\t\t\t\t\tconst { base, min, max, getLabel, getStore, setValue = (store, v) => store.set(v) } = finetuneControlConfiguration[id];\n\t\t\t\t\tconst store = getStore(imageEffectStores);\n\t\t\t\t\tconst value = $panelValues[id] != null ? $panelValues[id] : base;\n\n\t\t\t\t\tconfig[id] = {\n\t\t\t\t\t\tbase,\n\t\t\t\t\t\tmin,\n\t\t\t\t\t\tmax,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\tvalueLabel: getLabel\n\t\t\t\t\t\t? getLabel(value, min, max, max - min)\n\t\t\t\t\t\t: Math.round(100 * value),\n\t\t\t\t\t\toninputmove: v => {\n\t\t\t\t\t\t\tsetValue(store, v);\n\n\t\t\t\t\t\t\tif (store === imageColorMatrix) {\n\t\t\t\t\t\t\t\torderStoreKeys(store, colorMatrixKeyOrder);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\toninputend: v => {\n\t\t\t\t\t\t\tsetValue(store, v);\n\n\t\t\t\t\t\t\tif (store === imageColorMatrix) {\n\t\t\t\t\t\t\t\torderStoreKeys(store, colorMatrixKeyOrder);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\thistory.write();\n\t\t\t\t\t\t},\n\t\t\t\t\t\telasticity: $elasticityMultiplier * rangeInputElasticity,\n\t\t\t\t\t\tlabelReset: locale.labelReset,\n\t\t\t\t\t\tnudgeMultiplier: finetuneNudgePrecision\n\t\t\t\t\t};\n\n\t\t\t\t\treturn config;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t),\n\t\t\t$rangeInputConfig\n\t\t);\n\t};\n\n\t// need to unsubscribe when redrawing view\n\tlet unsubs = [];\n\n\tconst subscribePanelStores = config => {\n\t\tif (unsubs) unsubs.forEach(unsub => unsub());\n\n\t\tunsubs = panels.map(id => {\n\t\t\tconst { getStore, getValue = passthrough } = config[id];\n\t\t\tconst store = getStore(imageEffectStores);\n\n\t\t\treturn store.subscribe(value => {\n\t\t\t\tconst currentValue = value != null ? getValue(value) : value;\n\t\t\t\tset_store_value(panelValues, $panelValues = { ...$panelValues, [id]: currentValue }, $panelValues);\n\t\t\t});\n\t\t});\n\t};\n\n\t//\n\t// Footer\n\t//\n\tconst footerOffset = spring($animation ? 20 : 0);\n\n\tcomponent_subscribe($$self, footerOffset, value => $$invalidate(20, $footerOffset = value));\n\tconst select_handler = ({ detail }) => $$invalidate(2, tabSelected = detail);\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('stores' in $$props) $$invalidate(15, stores = $$props.stores);\n\t\tif ('isActive' in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));\n\t\tif ('locale' in $$props) $$invalidate(16, locale = $$props.locale);\n\t\tif ('finetuneControlConfiguration' in $$props) $$invalidate(17, finetuneControlConfiguration = $$props.finetuneControlConfiguration);\n\t\tif ('finetuneOptions' in $$props) $$invalidate(18, finetuneOptions = $$props.finetuneOptions);\n\t\tif ('finetuneNudgePrecision' in $$props) $$invalidate(19, finetuneNudgePrecision = $$props.finetuneNudgePrecision);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 2097152) {\n\t\t\t// enable pan and zoom\n\t\t\tallowPan.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 2097152) {\n\t\t\tallowZoom.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 2097152) {\n\t\t\tallowZoomControls.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 2097152) {\n\t\t\t$isActive && allowPlayPause.set(true);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*finetuneOptions, locale*/ 327680) {\n\t\t\t$$invalidate(1, tabs = finetuneOptions\n\t\t\t? finetuneOptions.map(([id, label]) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tlabel: isFunction(label) ? label(locale) : label\n\t\t\t\t}))\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*tabs*/ 2) {\n\t\t\t$$invalidate(2, tabSelected = tabs.length ? tabs[0].id : undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*tabSelected*/ 4) {\n\t\t\t$$invalidate(5, tabsConfig = tabSelected && { name: uid, selected: tabSelected });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*tabs*/ 2) {\n\t\t\t$$invalidate(4, panels = tabs.map(tab => tab.id));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*finetuneControlConfiguration*/ 131072) {\n\t\t\tcolorMatrixKeyOrder = [...Object.keys(finetuneControlConfiguration || {}), 'filter'];\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*finetuneControlConfiguration*/ 131072) {\n\t\t\tfinetuneControlConfiguration && subscribePanelStores(finetuneControlConfiguration);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*finetuneControlConfiguration, $panelValues*/ 8519680) {\n\t\t\tfinetuneControlConfiguration && $panelValues && updateRangeInputState();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$animation, $isActive*/ 6291456) {\n\t\t\t$animation && footerOffset.set($isActive ? 0 : 20);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$footerOffset*/ 1048576) {\n\t\t\t$$invalidate(3, styleFooterTransform = $footerOffset\n\t\t\t? `translateY(${$footerOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\ttabs,\n\t\ttabSelected,\n\t\tstyleFooterTransform,\n\t\tpanels,\n\t\ttabsConfig,\n\t\t$elasticityMultiplier,\n\t\t$rangeInputConfig,\n\t\tanimation,\n\t\tscrollElasticity,\n\t\telasticityMultiplier,\n\t\tpanelValues,\n\t\trangeInputConfig,\n\t\tfooterOffset,\n\t\tname,\n\t\tstores,\n\t\tlocale,\n\t\tfinetuneControlConfiguration,\n\t\tfinetuneOptions,\n\t\tfinetuneNudgePrecision,\n\t\t$footerOffset,\n\t\t$isActive,\n\t\t$animation,\n\t\t$panelValues,\n\t\tselect_handler,\n\t\tmeasure_handler\n\t];\n}\n\nclass Finetune extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$i,\n\t\t\tcreate_fragment$i,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 14,\n\t\t\t\tstores: 15,\n\t\t\t\tisActive: 0,\n\t\t\t\tlocale: 16,\n\t\t\t\tfinetuneControlConfiguration: 17,\n\t\t\t\tfinetuneOptions: 18,\n\t\t\t\tfinetuneNudgePrecision: 19\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[15];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget finetuneControlConfiguration() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset finetuneControlConfiguration(finetuneControlConfiguration) {\n\t\tthis.$$set({ finetuneControlConfiguration });\n\t\tflush();\n\t}\n\n\tget finetuneOptions() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset finetuneOptions(finetuneOptions) {\n\t\tthis.$$set({ finetuneOptions });\n\t\tflush();\n\t}\n\n\tget finetuneNudgePrecision() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset finetuneNudgePrecision(finetuneNudgePrecision) {\n\t\tthis.$$set({ finetuneNudgePrecision });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_finetune = { util: ['finetune', Finetune] };\n\nvar arrayIndexWrap = (index, arr) => {\n    const l = arr.length;\n    if (index < 0)\n        return (index % l) + l;\n    if (index >= l)\n        return index % l;\n    return index;\n};\n\n/* src/core/ui/components/ShapeManipulator.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context$2(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[51] = list[i].key;\n\tchild_ctx[52] = list[i].index;\n\tchild_ctx[53] = list[i].translate;\n\tchild_ctx[16] = list[i].scale;\n\tchild_ctx[54] = list[i].selected;\n\tchild_ctx[15] = list[i].rotate;\n\tchild_ctx[55] = list[i].dir;\n\tchild_ctx[56] = list[i].center;\n\tchild_ctx[57] = list[i].type;\n\tchild_ctx[4] = list[i].visible;\n\tchild_ctx[58] = list[i].role;\n\tchild_ctx[59] = list[i].tabindex;\n\tchild_ctx[60] = list[i].label;\n\tchild_ctx[61] = list[i].orientation;\n\tchild_ctx[62] = list[i].valuemin;\n\tchild_ctx[63] = list[i].valuemax;\n\tchild_ctx[64] = list[i].valuenow;\n\treturn child_ctx;\n}\n\n// (321:4) {#if type === 'edge' && visible}\nfunction create_if_block_2$4(ctx) {\n\tlet div;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"class\", \"PinturaShapeManipulator\");\n\t\t\tattr(div, \"data-control\", \"point\");\n\t\t\tset_style(div, \"pointer-events\", 'none');\n\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t\tset_style(div, \"transform\", `translate3d(${/*center*/ ctx[56].x}px, ${/*center*/ ctx[56].y}px, 0) scale(${/*$selectionScale*/ ctx[7]}, ${/*$selectionScale*/ ctx[7]})`);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*$selectionOpacity*/ 64) {\n\t\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls, $selectionScale*/ 160) {\n\t\t\t\tset_style(div, \"transform\", `translate3d(${/*center*/ ctx[56].x}px, ${/*center*/ ctx[56].y}px, 0) scale(${/*$selectionScale*/ ctx[7]}, ${/*$selectionScale*/ ctx[7]})`);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (293:0) {#each resizeControls as { key, index, translate, scale, selected, rotate, dir, center, type, visible, role, tabindex, label, orientation, valuemin, valuemax, valuenow }\nfunction create_each_block$2(key_2, ctx) {\n\tlet div;\n\tlet div_role_value;\n\tlet div_tabindex_value;\n\tlet div_aria_label_value;\n\tlet div_aria_orientation_value;\n\tlet div_aria_valuemin_value;\n\tlet div_aria_valuemax_value;\n\tlet div_aria_valuenow_value;\n\tlet div_data_control_value;\n\tlet div_data_selected_value;\n\tlet t;\n\tlet if_block_anchor;\n\tlet mounted;\n\tlet dispose;\n\n\tfunction nudge_handler(...args) {\n\t\treturn /*nudge_handler*/ ctx[23](/*index*/ ctx[52], ...args);\n\t}\n\n\tlet if_block = /*type*/ ctx[57] === 'edge' && /*visible*/ ctx[4] && create_if_block_2$4(ctx);\n\n\treturn {\n\t\tkey: key_2,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tt = space();\n\t\t\tif (if_block) if_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t\tattr(div, \"role\", div_role_value = /*role*/ ctx[58]);\n\t\t\tattr(div, \"tabindex\", div_tabindex_value = /*tabindex*/ ctx[59]);\n\t\t\tattr(div, \"aria-label\", div_aria_label_value = /*label*/ ctx[60]);\n\t\t\tattr(div, \"aria-orientation\", div_aria_orientation_value = /*orientation*/ ctx[61]);\n\t\t\tattr(div, \"aria-valuemin\", div_aria_valuemin_value = /*valuemin*/ ctx[62]);\n\t\t\tattr(div, \"aria-valuemax\", div_aria_valuemax_value = /*valuemax*/ ctx[63]);\n\t\t\tattr(div, \"aria-valuenow\", div_aria_valuenow_value = /*valuenow*/ ctx[64]);\n\t\t\tattr(div, \"class\", \"PinturaShapeManipulator\");\n\t\t\tattr(div, \"data-control\", div_data_control_value = /*type*/ ctx[57]);\n\t\t\tattr(div, \"data-selected\", div_data_selected_value = /*selected*/ ctx[54]);\n\t\t\tset_style(div, \"cursor\", /*dir*/ ctx[55] ? /*dir*/ ctx[55] + '-resize' : 'move');\n\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t\tset_style(div, \"--tx\", /*translate*/ ctx[53].x);\n\t\t\tset_style(div, \"--ty\", /*translate*/ ctx[53].y);\n\t\t\tset_style(div, \"--r\", `${/*type*/ ctx[57] === 'edge' ? /*rotate*/ ctx[15] : 0}rad`);\n\n\t\t\tset_style(div, \"--sx\", /*type*/ ctx[57] === 'point'\n\t\t\t? /*$selectionScale*/ ctx[7]\n\t\t\t: /*scale*/ ctx[16].x);\n\n\t\t\tset_style(div, \"--sy\", /*type*/ ctx[57] === 'point'\n\t\t\t? /*$selectionScale*/ ctx[7]\n\t\t\t: /*scale*/ ctx[16].y);\n\n\t\t\tthis.first = div;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tif (if_block) if_block.m(target, anchor);\n\t\t\tinsert(target, if_block_anchor, anchor);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"nudge\", nudge_handler),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, div, { preventDefault: true })),\n\t\t\t\t\tlisten(div, \"interactionstart\", function () {\n\t\t\t\t\t\tif (is_function(/*resize*/ ctx[11]('start', /*index*/ ctx[52]))) /*resize*/ ctx[11]('start', /*index*/ ctx[52]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionupdate\", function () {\n\t\t\t\t\t\tif (is_function(/*resize*/ ctx[11]('move', /*index*/ ctx[52]))) /*resize*/ ctx[11]('move', /*index*/ ctx[52]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionend\", function () {\n\t\t\t\t\t\tif (is_function(/*resize*/ ctx[11]('end', /*index*/ ctx[52]))) /*resize*/ ctx[11]('end', /*index*/ ctx[52]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(interactable.call(null, div, { observeKeys: true }))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_role_value !== (div_role_value = /*role*/ ctx[58])) {\n\t\t\t\tattr(div, \"role\", div_role_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_tabindex_value !== (div_tabindex_value = /*tabindex*/ ctx[59])) {\n\t\t\t\tattr(div, \"tabindex\", div_tabindex_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_aria_label_value !== (div_aria_label_value = /*label*/ ctx[60])) {\n\t\t\t\tattr(div, \"aria-label\", div_aria_label_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_aria_orientation_value !== (div_aria_orientation_value = /*orientation*/ ctx[61])) {\n\t\t\t\tattr(div, \"aria-orientation\", div_aria_orientation_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_aria_valuemin_value !== (div_aria_valuemin_value = /*valuemin*/ ctx[62])) {\n\t\t\t\tattr(div, \"aria-valuemin\", div_aria_valuemin_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_aria_valuemax_value !== (div_aria_valuemax_value = /*valuemax*/ ctx[63])) {\n\t\t\t\tattr(div, \"aria-valuemax\", div_aria_valuemax_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_aria_valuenow_value !== (div_aria_valuenow_value = /*valuenow*/ ctx[64])) {\n\t\t\t\tattr(div, \"aria-valuenow\", div_aria_valuenow_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_data_control_value !== (div_data_control_value = /*type*/ ctx[57])) {\n\t\t\t\tattr(div, \"data-control\", div_data_control_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32 && div_data_selected_value !== (div_data_selected_value = /*selected*/ ctx[54])) {\n\t\t\t\tattr(div, \"data-selected\", div_data_selected_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32) {\n\t\t\t\tset_style(div, \"cursor\", /*dir*/ ctx[55] ? /*dir*/ ctx[55] + '-resize' : 'move');\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*$selectionOpacity*/ 64) {\n\t\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32) {\n\t\t\t\tset_style(div, \"--tx\", /*translate*/ ctx[53].x);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32) {\n\t\t\t\tset_style(div, \"--ty\", /*translate*/ ctx[53].y);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls*/ 32) {\n\t\t\t\tset_style(div, \"--r\", `${/*type*/ ctx[57] === 'edge' ? /*rotate*/ ctx[15] : 0}rad`);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls, $selectionScale*/ 160) {\n\t\t\t\tset_style(div, \"--sx\", /*type*/ ctx[57] === 'point'\n\t\t\t\t? /*$selectionScale*/ ctx[7]\n\t\t\t\t: /*scale*/ ctx[16].x);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*resizeControls, $selectionScale*/ 160) {\n\t\t\t\tset_style(div, \"--sy\", /*type*/ ctx[57] === 'point'\n\t\t\t\t? /*$selectionScale*/ ctx[7]\n\t\t\t\t: /*scale*/ ctx[16].y);\n\t\t\t}\n\n\t\t\tif (/*type*/ ctx[57] === 'edge' && /*visible*/ ctx[4]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_2$4(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d(detaching);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (334:0) {#if enableRotatePoints && rotatorPoint}\nfunction create_if_block_1$4(ctx) {\n\tlet div;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"role\", \"button\");\n\t\t\tattr(div, \"aria-label\", \"Drag rotator\");\n\t\t\tattr(div, \"tabindex\", \"0\");\n\t\t\tattr(div, \"class\", \"PinturaShapeManipulator\");\n\t\t\tattr(div, \"data-control\", \"rotate\");\n\t\t\tset_style(div, \"transform\", `translate3d(${/*rotatorPoint*/ ctx[0].x}px, ${/*rotatorPoint*/ ctx[0].y}px, 0) scale(${/*$selectionScale*/ ctx[7]}, ${/*$selectionScale*/ ctx[7]})`);\n\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"nudge\", /*handleRotateNudge*/ ctx[13]),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, div, { preventDefault: true })),\n\t\t\t\t\tlisten(div, \"interactionstart\", /*rotate*/ ctx[15]('start')),\n\t\t\t\t\tlisten(div, \"interactionupdate\", /*rotate*/ ctx[15]('move')),\n\t\t\t\t\tlisten(div, \"interactionend\", /*rotate*/ ctx[15]('end')),\n\t\t\t\t\taction_destroyer(interactable.call(null, div, { observeKeys: true }))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*rotatorPoint, $selectionScale*/ 129) {\n\t\t\t\tset_style(div, \"transform\", `translate3d(${/*rotatorPoint*/ ctx[0].x}px, ${/*rotatorPoint*/ ctx[0].y}px, 0) scale(${/*$selectionScale*/ ctx[7]}, ${/*$selectionScale*/ ctx[7]})`);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*$selectionOpacity*/ 64) {\n\t\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (355:0) {#if enableScalePoints && scalarPoint}\nfunction create_if_block$7(ctx) {\n\tlet div;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"role\", \"button\");\n\t\t\tattr(div, \"aria-label\", \"Drag scalar\");\n\t\t\tattr(div, \"tabindex\", \"0\");\n\t\t\tattr(div, \"class\", \"PinturaShapeManipulator\");\n\t\t\tattr(div, \"data-control\", \"scale\");\n\t\t\tset_style(div, \"transform\", `translate3d(${/*scalarPoint*/ ctx[1].x}px, ${/*scalarPoint*/ ctx[1].y}px, 0) scale(${/*$selectionScale*/ ctx[7]}, ${/*$selectionScale*/ ctx[7]})`);\n\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"nudge\", /*handleScaleNudge*/ ctx[14]),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, div, { preventDefault: true })),\n\t\t\t\t\tlisten(div, \"interactionstart\", /*scale*/ ctx[16]('start')),\n\t\t\t\t\tlisten(div, \"interactionupdate\", /*scale*/ ctx[16]('move')),\n\t\t\t\t\tlisten(div, \"interactionend\", /*scale*/ ctx[16]('end')),\n\t\t\t\t\taction_destroyer(interactable.call(null, div, { observeKeys: true }))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*scalarPoint, $selectionScale*/ 130) {\n\t\t\t\tset_style(div, \"transform\", `translate3d(${/*scalarPoint*/ ctx[1].x}px, ${/*scalarPoint*/ ctx[1].y}px, 0) scale(${/*$selectionScale*/ ctx[7]}, ${/*$selectionScale*/ ctx[7]})`);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*$selectionOpacity*/ 64) {\n\t\t\t\tset_style(div, \"opacity\", /*$selectionOpacity*/ ctx[6]);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$h(ctx) {\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet t0;\n\tlet t1;\n\tlet if_block1_anchor;\n\tlet each_value = ensure_array_like(/*resizeControls*/ ctx[5]);\n\tconst get_key = ctx => /*key*/ ctx[51];\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$2(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$2(key, child_ctx));\n\t}\n\n\tlet if_block0 = /*enableRotatePoints*/ ctx[2] && /*rotatorPoint*/ ctx[0] && create_if_block_1$4(ctx);\n\tlet if_block1 = /*enableScalePoints*/ ctx[3] && /*scalarPoint*/ ctx[1] && create_if_block$7(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tt0 = space();\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(target, anchor);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinsert(target, t0, anchor);\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*$selectionOpacity, resizeControls, $selectionScale, handleResizeNudge, resize*/ 6368) {\n\t\t\t\teach_value = ensure_array_like(/*resizeControls*/ ctx[5]);\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, t0.parentNode, destroy_block, create_each_block$2, t0, get_each_context$2);\n\t\t\t}\n\n\t\t\tif (/*enableRotatePoints*/ ctx[2] && /*rotatorPoint*/ ctx[0]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_1$4(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\tif_block0.m(t1.parentNode, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tif_block0.d(1);\n\t\t\t\tif_block0 = null;\n\t\t\t}\n\n\t\t\tif (/*enableScalePoints*/ ctx[3] && /*scalarPoint*/ ctx[1]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block$7(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(if_block1_anchor.parentNode, if_block1_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(t1);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d(detaching);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance$h($$self, $$props, $$invalidate) {\n\tlet resizeControls;\n\tlet $isAnimated;\n\tlet $selectionOpacity;\n\tlet $selectionScale;\n\tconst dispatch = createEventDispatcher();\n\n\t// which cursor to render\n\tconst EIGTH_PI = QUART_PI * 0.5;\n\n\tconst N = HALF_PI;\n\tconst N0 = N - EIGTH_PI;\n\tconst N1 = N + EIGTH_PI;\n\tconst S = -HALF_PI;\n\tconst S0 = S - EIGTH_PI;\n\tconst S1 = S + EIGTH_PI;\n\tconst E = PI;\n\tconst E0 = E - EIGTH_PI;\n\tconst E1 = -PI + EIGTH_PI;\n\tconst W0 = EIGTH_PI;\n\tconst W1 = -EIGTH_PI;\n\tconst NW = N - QUART_PI;\n\tconst NW0 = NW - EIGTH_PI;\n\tconst NW1 = NW + EIGTH_PI;\n\tconst NE = PI - QUART_PI;\n\tconst NE0 = NE - EIGTH_PI;\n\tconst NE1 = NE + EIGTH_PI;\n\tconst SE = S - QUART_PI;\n\tconst SE0 = SE + EIGTH_PI;\n\tconst SE1 = SE - EIGTH_PI;\n\tconst SW = S + QUART_PI;\n\tconst SW0 = SW + EIGTH_PI;\n\tconst SW1 = SW - EIGTH_PI;\n\tlet { visible = false } = $$props;\n\tlet { points = [] } = $$props;\n\tlet { rotatorPoint = undefined } = $$props;\n\tlet { bounds = null } = $$props;\n\tlet { scalarPoint = undefined } = $$props;\n\tlet { selectedPoint = undefined } = $$props;\n\tlet { enableDragEdges = true } = $$props;\n\tlet { enableDragPoints = true } = $$props;\n\tlet { enableRotatePoints = true } = $$props;\n\tlet { enableScalePoints = true } = $$props;\n\n\t// contex\n\tconst isAnimated = getContext('isAnimated');\n\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(22, $isAnimated = value));\n\n\t// state\n\tconst selectionScale = spring(0.5, {\n\t\tprecision: 0.0001,\n\t\tstiffness: 0.3,\n\t\tdamping: 0.7\n\t});\n\n\tcomponent_subscribe($$self, selectionScale, value => $$invalidate(7, $selectionScale = value));\n\n\tconst selectionOpacity = spring(0, {\n\t\tprecision: 0.001,\n\t\tstiffness: 0.3,\n\t\tdamping: 0.7\n\t});\n\n\tcomponent_subscribe($$self, selectionOpacity, value => $$invalidate(6, $selectionOpacity = value));\n\n\tconst rotate = type => ({ detail }) => {\n\t\t// always make sure we have a translation to work with\n\t\tconst translation = detail && detail.translation\n\t\t? detail.translation\n\t\t: vectorCreate(0, 0);\n\n\t\tdispatch(`rotate${type}`, { ...detail, translation });\n\t};\n\n\tconst scale = type => ({ detail }) => {\n\t\t// always make sure we have a translation to work with\n\t\tconst translation = detail && detail.translation\n\t\t? detail.translation\n\t\t: vectorCreate(0, 0);\n\n\t\tdispatch(`scale${type}`, { ...detail, translation });\n\t};\n\n\tconst resize = (type, indexes) => ({ detail }) => {\n\t\t// always make sure we have a translation to work with\n\t\tconst translation = detail && detail.translation\n\t\t? detail.translation\n\t\t: vectorCreate(0, 0);\n\n\t\t// done transforming the points\n\t\tdispatch(`resize${type}`, { ...detail, indexes, translation });\n\t};\n\n\t// https://en.wikipedia.org/wiki/Radian#/media/File:Degree-Radian_Conversion.svg\n\tconst getDirectionByAngle = angle => {\n\t\tlet dir = '';\n\t\tconst isNorth = angle <= N1 && angle >= N0;\n\t\tconst isSouth = angle >= S0 && angle <= S1;\n\t\tconst isEast = angle <= E1 || angle >= E0;\n\t\tconst isWest = angle >= W1 && angle <= W0;\n\t\tconst isNorthEast = angle >= NE0 && angle <= NE1;\n\t\tconst isNorthWest = angle >= NW0 && angle <= NW1;\n\t\tconst isSouthEast = angle <= SE0 && angle >= SE1;\n\t\tconst isSouthWest = angle <= SW0 && angle >= SW1;\n\t\tif (isNorth || isSouth) dir = 'ns';\n\t\tif (isEast || isWest) dir = 'ew';\n\t\tif (isNorthEast || isSouthWest) dir = 'nesw';\n\t\tif (isNorthWest || isSouthEast) dir = 'nwse';\n\t\treturn dir;\n\t};\n\n\t// 2 points -> [corner, corner]\n\t// 3 points => [corner, edge, corner, edge, corner, edge],\n\t// 4 points => [corner, edge, corner, edge, corner, edge, corner, edge]\n\tconst mapPointsToControls = (points, axis) => {\n\t\tlet i = 0;\n\t\tconst center = vectorCenter(points);\n\t\tconst out = [];\n\t\tconst l = points.length;\n\t\tconst [top, right, bottom, left] = polyToBounds(points);\n\n\t\tfor (; i < l; i++) {\n\t\t\tconst i0 = arrayIndexWrap(i - 1, points);\n\n\t\t\t// const i1 = i;\n\t\t\tconst i2 = arrayIndexWrap(i + 1, points);\n\n\t\t\tconst p0 = points[i0];\n\t\t\tconst p1 = points[i];\n\t\t\tconst p2 = points[i2];\n\t\t\tconst dir = Math.atan2(p2.y - p1.y, p2.x - p1.x);\n\n\t\t\t// can drag vertices\n\t\t\tif (enableDragPoints) {\n\t\t\t\tconst a = vectorNormalize(vectorCreate(p0.x - p1.x, p0.y - p1.y));\n\t\t\t\tconst b = vectorNormalize(vectorCreate(p2.x - p1.x, p2.y - p1.y));\n\t\t\t\tconst cornerVector = vectorCreate(a.x + b.x, a.y + b.y);\n\n\t\t\t\tconst dir = !enableDragEdges\n\t\t\t\t? undefined\n\t\t\t\t: enableDragPoints && getDirectionByAngle(Math.atan2(cornerVector.y, cornerVector.x));\n\n\t\t\t\tout.push({\n\t\t\t\t\tindex: [i],\n\t\t\t\t\tkey: `point-${i}`,\n\t\t\t\t\ttype: 'point',\n\t\t\t\t\tselected: selectedPoint === i,\n\t\t\t\t\tscale: { x: 1, y: 1 },\n\t\t\t\t\ttranslate: { x: p1.x, y: p1.y },\n\t\t\t\t\tangle: undefined,\n\t\t\t\t\trotate: enableRotatePoints,\n\t\t\t\t\tcenter: p1,\n\t\t\t\t\tdir\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// skip edge dragging\n\t\t\tif (!enableDragEdges) continue;\n\n\t\t\tif (Array.isArray(enableDragEdges) && !enableDragEdges.some(([indexFrom, indexTo]) => {\n\t\t\t\treturn i === indexFrom && i2 === indexTo;\n\t\t\t})) continue;\n\n\t\t\tconst mid = vectorCreate(p1.x + (p2.x - p1.x) * 0.5, p1.y + (p2.y - p1.y) * 0.5);\n\n\t\t\t// a11y direction key\n\t\t\tconst direction = ['t', 'r', 'b', 'l'][i];\n\n\t\t\t// a11y ranges\n\t\t\tlet valuemin;\n\n\t\t\tlet valuemax;\n\t\t\tlet valuenow;\n\n\t\t\tif (direction === 'l') {\n\t\t\t\tvaluemin = bounds.x;\n\t\t\t\tvaluemax = right;\n\t\t\t\tvaluenow = left;\n\t\t\t}\n\n\t\t\tif (direction === 't') {\n\t\t\t\tvaluemin = bounds.y;\n\t\t\t\tvaluemax = bottom;\n\t\t\t\tvaluenow = top;\n\t\t\t}\n\n\t\t\tif (direction === 'r') {\n\t\t\t\tvaluemin = left;\n\t\t\t\tvaluemax = bounds.width;\n\t\t\t\tvaluenow = right;\n\t\t\t}\n\n\t\t\tif (direction === 'b') {\n\t\t\t\tvaluemin = top;\n\t\t\t\tvaluemax = bounds.height;\n\t\t\t\tvaluenow = bottom;\n\t\t\t}\n\n\t\t\t// create edge\n\t\t\tout.push({\n\t\t\t\tindex: [i, i2],\n\t\t\t\tkey: `edge-${i}`,\n\t\t\t\ttype: 'edge',\n\t\t\t\tscale: { x: vectorDistance(p1, p2), y: 1 },\n\t\t\t\ttranslate: { x: p1.x, y: p1.y },\n\t\t\t\tangle: dir,\n\t\t\t\trotate: dir,\n\t\t\t\tcenter: mid,\n\t\t\t\tvisible: Array.isArray(enableDragEdges),\n\t\t\t\tdir: getDirectionByAngle(Math.atan2(center.y - mid.y, center.x - mid.x)),\n\t\t\t\t// a11y\n\t\t\t\trole: 'slider',\n\t\t\t\ttabindex: 0,\n\t\t\t\tlabel: `Drag ${SliderLabel[direction]}`,\n\t\t\t\torientation: `${SliderOrientation[direction]}`,\n\t\t\t\tvaluemin: Math.round(valuemin),\n\t\t\t\tvaluemax: Math.round(valuemax),\n\t\t\t\tvaluenow: Math.round(valuenow)\n\t\t\t});\n\t\t}\n\n\t\treturn out;\n\t};\n\n\tconst handleResizeNudge = (indexes, translation) => {\n\t\tdispatch(`resizestart`, {\n\t\t\tindexes,\n\t\t\ttranslation: vectorCreateEmpty(),\n\t\t\tisNudge: true\n\t\t});\n\n\t\tdispatch(`resizemove`, { indexes, translation, isNudge: true });\n\n\t\tdispatch(`resizeend`, {\n\t\t\tindexes,\n\t\t\ttranslation: vectorCreateEmpty(),\n\t\t\tisNudge: true\n\t\t});\n\t};\n\n\tconst handleRotateNudge = ({ detail }) => {\n\t\tdispatch(`rotatestart`, {\n\t\t\ttranslation: vectorCreateEmpty(),\n\t\t\tisNudge: true\n\t\t});\n\n\t\tdispatch(`rotatemove`, { translation: detail, isNudge: true });\n\n\t\tdispatch(`rotateend`, {\n\t\t\ttranslation: vectorCreateEmpty(),\n\t\t\tisNudge: true\n\t\t});\n\t};\n\n\tconst handleScaleNudge = ({ detail }) => {\n\t\tdispatch(`scalestart`, {\n\t\t\ttranslation: vectorCreateEmpty(),\n\t\t\tisNudge: true\n\t\t});\n\n\t\tdispatch(`scalemove`, { translation: detail, isNudge: true });\n\n\t\tdispatch(`scaleend`, {\n\t\t\ttranslation: vectorCreateEmpty(),\n\t\t\tisNudge: true\n\t\t});\n\t};\n\n\tconst nudge_handler = (index, { detail }) => handleResizeNudge(index, detail);\n\n\t$$self.$$set = $$props => {\n\t\tif ('visible' in $$props) $$invalidate(4, visible = $$props.visible);\n\t\tif ('points' in $$props) $$invalidate(17, points = $$props.points);\n\t\tif ('rotatorPoint' in $$props) $$invalidate(0, rotatorPoint = $$props.rotatorPoint);\n\t\tif ('bounds' in $$props) $$invalidate(18, bounds = $$props.bounds);\n\t\tif ('scalarPoint' in $$props) $$invalidate(1, scalarPoint = $$props.scalarPoint);\n\t\tif ('selectedPoint' in $$props) $$invalidate(19, selectedPoint = $$props.selectedPoint);\n\t\tif ('enableDragEdges' in $$props) $$invalidate(20, enableDragEdges = $$props.enableDragEdges);\n\t\tif ('enableDragPoints' in $$props) $$invalidate(21, enableDragPoints = $$props.enableDragPoints);\n\t\tif ('enableRotatePoints' in $$props) $$invalidate(2, enableRotatePoints = $$props.enableRotatePoints);\n\t\tif ('enableScalePoints' in $$props) $$invalidate(3, enableScalePoints = $$props.enableScalePoints);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*visible, $isAnimated*/ 4194320) {\n\t\t\tselectionScale.set(visible ? 1 : 0.5, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*visible, $isAnimated*/ 4194320) {\n\t\t\tselectionOpacity.set(visible ? 1 : 0, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*points*/ 131072) {\n\t\t\t$$invalidate(5, resizeControls = mapPointsToControls(points));\n\t\t}\n\t};\n\n\treturn [\n\t\trotatorPoint,\n\t\tscalarPoint,\n\t\tenableRotatePoints,\n\t\tenableScalePoints,\n\t\tvisible,\n\t\tresizeControls,\n\t\t$selectionOpacity,\n\t\t$selectionScale,\n\t\tisAnimated,\n\t\tselectionScale,\n\t\tselectionOpacity,\n\t\tresize,\n\t\thandleResizeNudge,\n\t\thandleRotateNudge,\n\t\thandleScaleNudge,\n\t\trotate,\n\t\tscale,\n\t\tpoints,\n\t\tbounds,\n\t\tselectedPoint,\n\t\tenableDragEdges,\n\t\tenableDragPoints,\n\t\t$isAnimated,\n\t\tnudge_handler\n\t];\n}\n\nclass ShapeManipulator extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$h,\n\t\t\tcreate_fragment$h,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tvisible: 4,\n\t\t\t\tpoints: 17,\n\t\t\t\trotatorPoint: 0,\n\t\t\t\tbounds: 18,\n\t\t\t\tscalarPoint: 1,\n\t\t\t\tselectedPoint: 19,\n\t\t\t\tenableDragEdges: 20,\n\t\t\t\tenableDragPoints: 21,\n\t\t\t\tenableRotatePoints: 2,\n\t\t\t\tenableScalePoints: 3\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1]\n\t\t);\n\t}\n}\n\nvar getEventPositionInEditor = (e, viewOffset) => {\n    const positionInViewport = getEventPositionInViewport(e);\n    return vectorSubtract(positionInViewport, viewOffset);\n};\n\nvar t = (text) => document.createTextNode(text);\n\nvar replaceDivWithBr = (html) => (isSafari() && html.endsWith('<div><br></div>')\n    ? html.replace(/<div><br><\\/div>$/, '<br><br>')\n    : html)\n    .replace(/<div><br><\\/div>/g, '<br>')\n    .replace(/<\\/div>/g, '')\n    .replace(/<div>/g, '<br>');\n\n/* src/core/ui/components/ContentEditable.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block$6(ctx) {\n\tlet pre;\n\tlet styleable_action;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tpre = element(\"pre\");\n\t\t\tattr(pre, \"class\", \"PinturaContentEditable\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, pre, anchor);\n\t\t\tpre.innerHTML = /*innerHTML*/ ctx[0];\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = action_destroyer(styleable_action = styleable.call(null, pre, `${/*contentStyle*/ ctx[7]};position:absolute;z-index:-1;pointer-events:none;`));\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*innerHTML*/ 1) pre.innerHTML = /*innerHTML*/ ctx[0];\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty[0] & /*contentStyle*/ 128) styleable_action.update.call(null, `${/*contentStyle*/ ctx[7]};position:absolute;z-index:-1;pointer-events:none;`);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(pre);\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\nfunction create_fragment$g(ctx) {\n\tlet t_1;\n\tlet pre;\n\tlet pre_data_wrap_content_value;\n\tlet styleable_action;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block = /*shouldSimulateTextEffects*/ ctx[8] && create_if_block$6(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block) if_block.c();\n\t\t\tt_1 = space();\n\t\t\tpre = element(\"pre\");\n\t\t\tattr(pre, \"class\", \"PinturaContentEditable\");\n\n\t\t\tattr(pre, \"data-wrap-content\", pre_data_wrap_content_value = !/*wrapLines*/ ctx[4] && !/*allowNewline*/ ctx[5]\n\t\t\t? 'nowrap'\n\t\t\t: 'wrap');\n\n\t\t\tattr(pre, \"contenteditable\", \"\");\n\t\t\tattr(pre, \"spellcheck\", /*spellcheck*/ ctx[1]);\n\t\t\tattr(pre, \"autocorrect\", /*autocorrect*/ ctx[2]);\n\t\t\tattr(pre, \"autocapitalize\", /*autocapitalize*/ ctx[3]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block) if_block.m(target, anchor);\n\t\t\tinsert(target, t_1, anchor);\n\t\t\tinsert(target, pre, anchor);\n\t\t\t/*pre_binding*/ ctx[26](pre);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\taction_destroyer(styleable_action = styleable.call(null, pre, /*shouldSimulateTextEffects*/ ctx[8]\n\t\t\t\t\t? /*removeTextEffects*/ ctx[15](/*contentStyle*/ ctx[7])\n\t\t\t\t\t: /*contentStyle*/ ctx[7])),\n\t\t\t\t\tlisten(pre, \"input\", /*handleInput*/ ctx[13]),\n\t\t\t\t\tlisten(pre, \"compositionend\", /*handleCompositionEnd*/ ctx[12]),\n\t\t\t\t\tlisten(pre, \"paste\", /*handlePaste*/ ctx[14]),\n\t\t\t\t\tlisten(pre, \"keydown\", /*handleKeydown*/ ctx[10]),\n\t\t\t\t\tlisten(pre, \"keyup\", /*handleKeyup*/ ctx[11]),\n\t\t\t\t\tlisten(pre, \"blur\", /*handleBlur*/ ctx[9])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*shouldSimulateTextEffects*/ ctx[8]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block$6(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\tif_block.m(t_1.parentNode, t_1);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tif_block.d(1);\n\t\t\t\tif_block = null;\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*wrapLines, allowNewline*/ 48 && pre_data_wrap_content_value !== (pre_data_wrap_content_value = !/*wrapLines*/ ctx[4] && !/*allowNewline*/ ctx[5]\n\t\t\t? 'nowrap'\n\t\t\t: 'wrap')) {\n\t\t\t\tattr(pre, \"data-wrap-content\", pre_data_wrap_content_value);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*spellcheck*/ 2) {\n\t\t\t\tattr(pre, \"spellcheck\", /*spellcheck*/ ctx[1]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*autocorrect*/ 4) {\n\t\t\t\tattr(pre, \"autocorrect\", /*autocorrect*/ ctx[2]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*autocapitalize*/ 8) {\n\t\t\t\tattr(pre, \"autocapitalize\", /*autocapitalize*/ ctx[3]);\n\t\t\t}\n\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty[0] & /*shouldSimulateTextEffects, contentStyle*/ 384) styleable_action.update.call(null, /*shouldSimulateTextEffects*/ ctx[8]\n\t\t\t? /*removeTextEffects*/ ctx[15](/*contentStyle*/ ctx[7])\n\t\t\t: /*contentStyle*/ ctx[7]);\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t_1);\n\t\t\t\tdetach(pre);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d(detaching);\n\t\t\t/*pre_binding*/ ctx[26](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction instance$g($$self, $$props, $$invalidate) {\n\tlet isReady;\n\tlet shouldSimulateTextEffects;\n\tlet { spellcheck = 'false' } = $$props;\n\tlet { autocorrect = 'off' } = $$props;\n\tlet { autocapitalize = 'off' } = $$props;\n\tlet { wrapLines = true } = $$props;\n\tlet { allowNewline = true } = $$props;\n\tlet { textFormat = 'text' } = $$props;\n\tlet { formatInput = passthrough } = $$props;\n\tlet { formatPaste = passthrough } = $$props;\n\tlet { styles = undefined } = $$props;\n\tlet { innerHTML = undefined } = $$props;\n\tlet { oninput = noop$1 } = $$props;\n\tlet { enableTextStyleShortcuts = false } = $$props;\n\tconst confirm = () => confirmInputState();\n\tconst focus = () => element && element.focus();\n\n\tconst select = () => {\n\t\tif (!element) return;\n\t\tconst range = document.createRange();\n\t\trange.selectNodeContents(element);\n\t\tconst selection = getSelectionSafe();\n\t\tselection.removeAllRanges();\n\t\tselection.addRange(range);\n\t};\n\n\t// events\n\tconst dispatchEvent = createEventDispatcher();\n\n\t// reference to contenteditable element\n\tlet element;\n\n\t// use <br> for line breaks\n\tdocument.execCommand('defaultParagraphSeparator', false, 'br');\n\n\tconst setInnerHTML = html => {\n\t\tif (html === element.innerHTML) return;\n\t\t$$invalidate(6, element.innerHTML = html, element);\n\t\tif (element === document.activeElement) select();\n\t};\n\n\tconst removeTextStyles = html => {\n\t\treturn html.replace(/<\\/?(?:i|b|em|u|s|strike|strong|font)>/, '').replace(/style=\".*?\"/g, '').replace(/\\n/gim, '<br>');\n\t};\n\n\tconst updateInnerHTML = () => {\n\t\t// sync property\n\t\t$$invalidate(0, innerHTML = element.innerHTML);\n\n\t\t// let others know\n\t\tconst currentValue = replaceDivWithBr(innerHTML);\n\n\t\tdispatchEvent('input', currentValue);\n\t\toninput(currentValue);\n\n\t\t// always scroll to top\n\t\trequestAnimationFrame(() => element && element.scrollTo(0, 0));\n\t};\n\n\tconst confirmInputState = () => {\n\t\t// bookmark caret positions\n\t\tinsertBookmarks(element);\n\n\t\t// remove styles\n\t\tconst html = textFormat === 'html'\n\t\t? element.innerHTML\n\t\t: removeTextStyles(element.innerHTML);\n\n\t\t// update HTML (don't remove caret positions)\n\t\t$$invalidate(6, element.innerHTML = formatInput(html), element);\n\n\t\t// select bookmarks and remove from DOM\n\t\tselectBookmarks(element);\n\n\t\t// content updated\n\t\tupdateInnerHTML();\n\t};\n\n\tconst handleBlur = () => {\n\t\tdispatchEvent('blur');\n\t};\n\n\tconst handleConfirm = () => {\n\t\tdispatchEvent('confirm');\n\t};\n\n\tconst handleCancel = () => {\n\t\tdispatchEvent('cancel');\n\t};\n\n\tconst styleKeys = {\n\t\tb: 'bold',\n\t\ti: 'italic',\n\t\tu: 'underline',\n\t\ts: 'strikethrough'\n\t};\n\n\tconst handleStyleShortcut = key => {\n\t\tconst cmd = styleKeys[key];\n\t\tcmd && document.execCommand(cmd);\n\t};\n\n\tconst handleKeydown = e => {\n\t\t// is escape key, cancel\n\t\tif ((/escape/i).test(e.code)) {\n\t\t\te.stopPropagation();\n\t\t\treturn handleCancel();\n\t\t}\n\n\t\tconst cmdPressed = e.ctrlKey || e.metaKey;\n\n\t\t// prevent text style keys\n\t\tif (textFormat === 'html' && cmdPressed) {\n\t\t\tif ((/b|i|u|s/).test(e.key)) {\n\t\t\t\tenableTextStyleShortcuts && handleStyleShortcut(e.key);\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// stop here\n\t\tif (!(/enter/i).test(e.key)) return;\n\n\t\t// don't let others handle return while in text area\n\t\te.stopPropagation();\n\n\t\t// is enter but is composing (confirm predictive selection)\n\t\tif (e.isComposing) return;\n\n\t\t// is cmd + enter or ctrl + enter\n\t\tif (cmdPressed) return handleConfirm();\n\n\t\t// block return when newlines not allowed\n\t\tif (!allowNewline) e.preventDefault();\n\n\t\tdocument.execCommand('insertLineBreak');\n\t\te.preventDefault();\n\t};\n\n\tconst handleKeyup = () => {\n\t\t\n\t}; // intentionally blank for now\n\n\tconst handleCompositionEnd = e => {\n\t\tif (e.data === '') return;\n\t\tconfirmInputState();\n\t};\n\n\tconst handleInput = e => {\n\t\tconst { inputType } = e;\n\n\t\t// more info on when inputType is which value\n\t\t// https://rawgit.com/w3c/input-events/v1/index.html#interface-InputEvent-Attributes\n\t\tif (inputType === 'insertCompositionText' || inputType === 'deleteCompositionText') {\n\t\t\t// we're composing (to for example write \u00E9, or Japanese characters),\n\t\t\t// if so, wait for composition end before formatting content\n\t\t\treturn;\n\t\t}\n\n\t\tconfirmInputState();\n\t};\n\n\tconst handlePaste = e => {\n\t\te.preventDefault();\n\n\t\t// remove styles\n\t\tconst plainText = e.clipboardData.getData('text/plain');\n\n\t\tconst html = textFormat === 'html'\n\t\t? plainText\n\t\t: removeTextStyles(plainText);\n\n\t\t// format the pasted text before adding\n\t\tconst text = formatPaste(html);\n\n\t\tif (!text.length) return;\n\n\t\t// get range for current selection and replace with text\n\t\tconst range = getSelectionSafe().getRangeAt(0);\n\n\t\trange.deleteContents();\n\t\trange.insertNode(document.createTextNode(text));\n\n\t\t// content updated\n\t\tupdateInnerHTML();\n\t};\n\n\t//#region bookmarks\n\tconst createBookmark = name => {\n\t\tconst bookmarkNode = h('span');\n\t\tbookmarkNode.dataset.bookmark = name;\n\t\treturn bookmarkNode;\n\t};\n\n\tconst insertBookmark = (node, offset, name) => {\n\t\t// create the bookmark element\n\t\tconst bookmarkNode = createBookmark(name);\n\n\t\t// split up in two text nodes and insert\n\t\tif (node.nodeType === Node.TEXT_NODE) {\n\t\t\tconst text = node.textContent;\n\n\t\t\tif (name === 'start') {\n\t\t\t\tconst before = t(text.substring(0, offset));\n\t\t\t\tconst after = t(text.substring(offset));\n\t\t\t\tnode.replaceWith(before, bookmarkNode, after);\n\t\t\t} else {\n\t\t\t\tconst before = t(text.substring(0, offset));\n\t\t\t\tconst after = t(text.substring(offset));\n\t\t\t\tnode.replaceWith(before, bookmarkNode, after);\n\t\t\t}\n\t\t} else // is node\n\t\tif (node.nodeType === Node.ELEMENT_NODE) {\n\t\t\tnode.insertBefore(bookmarkNode, node.childNodes[offset]);\n\t\t}\n\t};\n\n\tconst getSelectionSafe = () => {\n\t\tconst root = element.getRootNode();\n\n\t\t// chrome needs to select from shadowRoot if in Shadow DOM\n\t\t// firefox can select from document and doesn't have getSelection support on shadowRoot\n\t\t// safari cannot deal with text selection in shadowRoot at this time (MacOS Safari 16)\n\t\treturn 'getSelection' in root\n\t\t? root.getSelection()\n\t\t: document.getSelection();\n\t};\n\n\tconst insertBookmarks = element => {\n\t\tconst selection = getSelectionSafe();\n\t\tif (!(selection.getRangeAt && selection.rangeCount)) return;\n\t\tconst range = selection.getRangeAt(0);\n\t\tconst { startOffset, endOffset, startContainer, endContainer } = range;\n\n\t\t// range needs to be in element\n\t\tif (!element.contains(range.startContainer) || !element.contains(range.endContainer)) return;\n\n\t\t// should break up one text container\n\t\tif (startContainer.nodeType === Node.TEXT_NODE && startContainer === endContainer) {\n\t\t\tconst text = startContainer.textContent;\n\t\t\tconst before = text.substring(0, startOffset);\n\t\t\tconst bookmarkStart = createBookmark('start');\n\n\t\t\tconst selected = endOffset - startOffset > 0\n\t\t\t? text.substring(startOffset, endOffset)\n\t\t\t: '';\n\n\t\t\tconst bookmarkEnd = createBookmark('end');\n\t\t\tconst after = text.substring(endOffset);\n\t\t\tstartContainer.replaceWith(before, bookmarkStart, selected, bookmarkEnd, after);\n\t\t} else // should add to separate containers\n\t\t{\n\t\t\tinsertBookmark(startContainer, startOffset, 'start');\n\n\t\t\tinsertBookmark(\n\t\t\t\tendContainer,\n\t\t\t\t// if is same container need to move to next index as we've just added start bookmark\n\t\t\t\tendOffset + (startContainer === endContainer ? 1 : 0),\n\t\t\t\t'end'\n\t\t\t);\n\t\t}\n\t};\n\n\tconst selectBookmarks = element => {\n\t\t// get locations of bookmarks\n\t\tconst bookmarkStart = findBookmark(element, 'start');\n\n\t\tconst bookmarkEnd = findBookmark(element, 'end');\n\n\t\t// remove bookmarks (if found)\n\t\tif (!bookmarkStart || !bookmarkEnd) return;\n\n\t\t// set caret positions\n\t\tconst range = document.createRange();\n\n\t\trange.setStart(bookmarkStart, 0);\n\t\trange.setEnd(bookmarkEnd, 0);\n\t\tconst selection = getSelectionSafe();\n\t\tselection.removeAllRanges();\n\t\tselection.addRange(range);\n\n\t\t// remove bookmarks\n\t\tbookmarkStart.remove();\n\n\t\tbookmarkEnd.remove();\n\t};\n\n\tconst findBookmark = (element, name) => {\n\t\tconst children = element.children;\n\n\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\tconst node = children[i];\n\t\t\tif (node.dataset.bookmark === name) return node;\n\n\t\t\tif (node.children.length) {\n\t\t\t\tconst bookmarkNode = findBookmark(node, name);\n\t\t\t\tif (bookmarkNode) return bookmarkNode;\n\t\t\t}\n\t\t}\n\n\t\treturn;\n\t};\n\n\t// add extra space on left or right side of content input so special symbols\n\t// are rendered on correct line while waiting for completion\n\tlet contentStyle;\n\n\t// we \"disable\" shadow and text styles because both are drawn in the stroke layer\n\tconst removeTextEffects = str => str.replace('-webkit-text-stroke', '--text-stroke').replace('text-shadow', '--text-shadow');\n\n\tfunction pre_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\telement = $$value;\n\t\t\t$$invalidate(6, element);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('spellcheck' in $$props) $$invalidate(1, spellcheck = $$props.spellcheck);\n\t\tif ('autocorrect' in $$props) $$invalidate(2, autocorrect = $$props.autocorrect);\n\t\tif ('autocapitalize' in $$props) $$invalidate(3, autocapitalize = $$props.autocapitalize);\n\t\tif ('wrapLines' in $$props) $$invalidate(4, wrapLines = $$props.wrapLines);\n\t\tif ('allowNewline' in $$props) $$invalidate(5, allowNewline = $$props.allowNewline);\n\t\tif ('textFormat' in $$props) $$invalidate(16, textFormat = $$props.textFormat);\n\t\tif ('formatInput' in $$props) $$invalidate(17, formatInput = $$props.formatInput);\n\t\tif ('formatPaste' in $$props) $$invalidate(18, formatPaste = $$props.formatPaste);\n\t\tif ('styles' in $$props) $$invalidate(19, styles = $$props.styles);\n\t\tif ('innerHTML' in $$props) $$invalidate(0, innerHTML = $$props.innerHTML);\n\t\tif ('oninput' in $$props) $$invalidate(20, oninput = $$props.oninput);\n\t\tif ('enableTextStyleShortcuts' in $$props) $$invalidate(21, enableTextStyleShortcuts = $$props.enableTextStyleShortcuts);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*element*/ 64) {\n\t\t\t// set value when html property is set and element reference is bound\n\t\t\t$$invalidate(25, isReady = !!element);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isReady, innerHTML*/ 33554433) {\n\t\t\tif (isReady && innerHTML) setInnerHTML(innerHTML);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*wrapLines, allowNewline, styles*/ 524336) {\n\t\t\tif (!wrapLines && allowNewline) {\n\t\t\t\t// TODO: no fix for center text yet\n\t\t\t\tconst contentStyleAdditional = styles.includes(':right')\n\t\t\t\t? 'text-indent:-100px!important'\n\t\t\t\t: !styles.includes(':center')\n\t\t\t\t\t? 'min-width:calc(100% + 100px)!important'\n\t\t\t\t\t: '';\n\n\t\t\t\t$$invalidate(7, contentStyle = styles + ';overflow:visible;' + contentStyleAdditional);\n\t\t\t} else {\n\t\t\t\t$$invalidate(7, contentStyle = styles);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*styles*/ 524288) {\n\t\t\t//#endregion\n\t\t\t// if text-stroke is set we need to render an extra text layer to simulate an outside stroke effect\n\t\t\t$$invalidate(8, shouldSimulateTextEffects = styles.includes('text-stroke'));\n\t\t}\n\t};\n\n\treturn [\n\t\tinnerHTML,\n\t\tspellcheck,\n\t\tautocorrect,\n\t\tautocapitalize,\n\t\twrapLines,\n\t\tallowNewline,\n\t\telement,\n\t\tcontentStyle,\n\t\tshouldSimulateTextEffects,\n\t\thandleBlur,\n\t\thandleKeydown,\n\t\thandleKeyup,\n\t\thandleCompositionEnd,\n\t\thandleInput,\n\t\thandlePaste,\n\t\tremoveTextEffects,\n\t\ttextFormat,\n\t\tformatInput,\n\t\tformatPaste,\n\t\tstyles,\n\t\toninput,\n\t\tenableTextStyleShortcuts,\n\t\tconfirm,\n\t\tfocus,\n\t\tselect,\n\t\tisReady,\n\t\tpre_binding\n\t];\n}\n\nclass ContentEditable extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$g,\n\t\t\tcreate_fragment$g,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tspellcheck: 1,\n\t\t\t\tautocorrect: 2,\n\t\t\t\tautocapitalize: 3,\n\t\t\t\twrapLines: 4,\n\t\t\t\tallowNewline: 5,\n\t\t\t\ttextFormat: 16,\n\t\t\t\tformatInput: 17,\n\t\t\t\tformatPaste: 18,\n\t\t\t\tstyles: 19,\n\t\t\t\tinnerHTML: 0,\n\t\t\t\toninput: 20,\n\t\t\t\tenableTextStyleShortcuts: 21,\n\t\t\t\tconfirm: 22,\n\t\t\t\tfocus: 23,\n\t\t\t\tselect: 24\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget spellcheck() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset spellcheck(spellcheck) {\n\t\tthis.$$set({ spellcheck });\n\t\tflush();\n\t}\n\n\tget autocorrect() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset autocorrect(autocorrect) {\n\t\tthis.$$set({ autocorrect });\n\t\tflush();\n\t}\n\n\tget autocapitalize() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset autocapitalize(autocapitalize) {\n\t\tthis.$$set({ autocapitalize });\n\t\tflush();\n\t}\n\n\tget wrapLines() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset wrapLines(wrapLines) {\n\t\tthis.$$set({ wrapLines });\n\t\tflush();\n\t}\n\n\tget allowNewline() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset allowNewline(allowNewline) {\n\t\tthis.$$set({ allowNewline });\n\t\tflush();\n\t}\n\n\tget textFormat() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset textFormat(textFormat) {\n\t\tthis.$$set({ textFormat });\n\t\tflush();\n\t}\n\n\tget formatInput() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset formatInput(formatInput) {\n\t\tthis.$$set({ formatInput });\n\t\tflush();\n\t}\n\n\tget formatPaste() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset formatPaste(formatPaste) {\n\t\tthis.$$set({ formatPaste });\n\t\tflush();\n\t}\n\n\tget styles() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset styles(styles) {\n\t\tthis.$$set({ styles });\n\t\tflush();\n\t}\n\n\tget innerHTML() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset innerHTML(innerHTML) {\n\t\tthis.$$set({ innerHTML });\n\t\tflush();\n\t}\n\n\tget oninput() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset oninput(oninput) {\n\t\tthis.$$set({ oninput });\n\t\tflush();\n\t}\n\n\tget enableTextStyleShortcuts() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset enableTextStyleShortcuts(enableTextStyleShortcuts) {\n\t\tthis.$$set({ enableTextStyleShortcuts });\n\t\tflush();\n\t}\n\n\tget confirm() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tget focus() {\n\t\treturn this.$$.ctx[23];\n\t}\n\n\tget select() {\n\t\treturn this.$$.ctx[24];\n\t}\n}\n\nconst DefaultFormattingTags = ['i', 'b', 'u', 'strike'].map((tag) => ({\n    tag,\n    tagOpen: new RegExp(`<${tag}>`, 'g'),\n    tagClose: new RegExp(`<\\/${tag}>`, 'g'),\n    placeholderOpen: new RegExp(`___${tag}O___`, 'g'),\n    placeholderClose: new RegExp(`___${tag}C___`, 'g'),\n}));\nconst replaceFormattingTags = (str, tags = DefaultFormattingTags) => {\n    tags.forEach(({ tag, tagOpen, tagClose }) => {\n        str = str.replace(tagOpen, `___${tag}O___`).replace(tagClose, `___${tag}C___`);\n    });\n    return str;\n};\nconst restoreFormattingTags = (str, tags = DefaultFormattingTags) => {\n    tags.forEach(({ tag, placeholderOpen, placeholderClose }) => {\n        str = str.replace(placeholderOpen, `<${tag}>`).replace(placeholderClose, `</${tag}>`);\n    });\n    return str;\n};\nvar textToHTML = (text) => {\n    // temporary replace bold italic\n    text = replaceFormattingTags(text);\n    // now encode\n    text = text\n        // collapse space sequences\n        .replace(/ {2,}/g, ' ')\n        // handle non breaking space characters\n        .replace(/\\u00a0/g, '&nbsp;')\n        // lines\n        .split('\\n')\n        // to br's\n        .join('<br>');\n    // put back bold and italic\n    text = restoreFormattingTags(text);\n    return text;\n};\n\nvar htmlToText = (html) => {\n    const lines = replaceDivWithBr(html).split(/<br>|<br\\/>/g);\n    return lines\n        .join('\\n')\n        .replace(/&nbsp;/g, String.fromCharCode(160))\n        .replace(/&amp;/g, '&');\n};\n\nvar fromPercentage = (value, context) => isString(value) ? (parseFloat(value) / 100) * context : value;\n\nvar toPercentagePoint = (point, context) => ({\n    x: toPercentage(point.x, context.width),\n    y: toPercentage(point.y, context.height),\n});\n\n/* src/core/ui/components/ShapeLayoutEditor.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context$1(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[323] = list[i];\n\tchild_ctx[325] = i;\n\treturn child_ctx;\n}\n\n// (5245:12) {#each shapeNavList as item, index (item.id)}\nfunction create_each_block$1(key_1, ctx) {\n\tlet li;\n\tlet button;\n\tlet colorpreview;\n\tlet t0;\n\tlet span;\n\tlet t1_value = /*item*/ ctx[323].name + \"\";\n\tlet t1;\n\tlet button_aria_label_value;\n\tlet t2;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tcolorpreview = new ColorPreview({\n\t\t\tprops: { color: /*item*/ ctx[323].color }\n\t\t});\n\n\tfunction click_handler() {\n\t\treturn /*click_handler*/ ctx[205](/*index*/ ctx[325]);\n\t}\n\n\treturn {\n\t\tkey: key_1,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tli = element(\"li\");\n\t\t\tbutton = element(\"button\");\n\t\t\tcreate_component(colorpreview.$$.fragment);\n\t\t\tt0 = space();\n\t\t\tspan = element(\"span\");\n\t\t\tt1 = text(t1_value);\n\t\t\tt2 = space();\n\t\t\tattr(button, \"class\", \"PinturaShapeListItem\");\n\t\t\tattr(button, \"type\", \"button\");\n\t\t\tattr(button, \"aria-label\", button_aria_label_value = \"Select shape \" + /*item*/ ctx[323].name);\n\t\t\tthis.first = li;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, li, anchor);\n\t\t\tappend(li, button);\n\t\t\tmount_component(colorpreview, button, null);\n\t\t\tappend(button, t0);\n\t\t\tappend(button, span);\n\t\t\tappend(span, t1);\n\t\t\tappend(li, t2);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = listen(button, \"click\", click_handler);\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tconst colorpreview_changes = {};\n\t\t\tif (dirty[0] & /*shapeNavList*/ 16777216) colorpreview_changes.color = /*item*/ ctx[323].color;\n\t\t\tcolorpreview.$set(colorpreview_changes);\n\t\t\tif ((!current || dirty[0] & /*shapeNavList*/ 16777216) && t1_value !== (t1_value = /*item*/ ctx[323].name + \"\")) set_data(t1, t1_value);\n\n\t\t\tif (!current || dirty[0] & /*shapeNavList*/ 16777216 && button_aria_label_value !== (button_aria_label_value = \"Select shape \" + /*item*/ ctx[323].name)) {\n\t\t\t\tattr(button, \"aria-label\", button_aria_label_value);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(colorpreview.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(colorpreview.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(li);\n\t\t\t}\n\n\t\t\tdestroy_component(colorpreview);\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\n// (5261:4) {#if shouldRenderShapeManipulator}\nfunction create_if_block_4$2(ctx) {\n\tlet shapemanipulator;\n\tlet current;\n\n\tshapemanipulator = new ShapeManipulator({\n\t\t\tprops: {\n\t\t\t\tvisible: true,\n\t\t\t\tpoints: /*shapeManipulatorPoints*/ ctx[15],\n\t\t\t\tbounds: /*utilRect*/ ctx[5],\n\t\t\t\trotatorPoint: /*shapeManipulatorRotationPointPosition*/ ctx[32],\n\t\t\t\tscalarPoint: /*shapeManipulatorScalarPointPosition*/ ctx[31],\n\t\t\t\tselectedPoint: /*shapeSelectedPointIndex*/ ctx[20],\n\t\t\t\tenableDragEdges: /*allowEdgeControls*/ ctx[21],\n\t\t\t\tenableDragPoints: /*allowCornerControls*/ ctx[34],\n\t\t\t\tenableRotatePoints: /*allowRotateControls*/ ctx[19],\n\t\t\t\tenableScalePoints: /*allowScaleControls*/ ctx[17]\n\t\t\t}\n\t\t});\n\n\tshapemanipulator.$on(\"resizestart\", /*handleManipulatorResizeGrab*/ ctx[43]);\n\tshapemanipulator.$on(\"resizemove\", /*handleManipulatorResizeDrag*/ ctx[44]);\n\tshapemanipulator.$on(\"resizeend\", /*handleManipulatorResizeEnd*/ ctx[45]);\n\tshapemanipulator.$on(\"rotatestart\", /*handleManipulatorRotateGrab*/ ctx[46]);\n\tshapemanipulator.$on(\"rotatemove\", /*handleManipulatorRotateDrag*/ ctx[47]);\n\tshapemanipulator.$on(\"rotateend\", /*handleManipulatorRotateEnd*/ ctx[48]);\n\tshapemanipulator.$on(\"scalestart\", /*handleManipulatorScaleGrab*/ ctx[49]);\n\tshapemanipulator.$on(\"scalemove\", /*handleManipulatorScaleDrag*/ ctx[50]);\n\tshapemanipulator.$on(\"scaleend\", /*handleManipulatorScaleEnd*/ ctx[51]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapemanipulator.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapemanipulator, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapemanipulator_changes = {};\n\t\t\tif (dirty[0] & /*shapeManipulatorPoints*/ 32768) shapemanipulator_changes.points = /*shapeManipulatorPoints*/ ctx[15];\n\t\t\tif (dirty[0] & /*utilRect*/ 32) shapemanipulator_changes.bounds = /*utilRect*/ ctx[5];\n\t\t\tif (dirty[1] & /*shapeManipulatorRotationPointPosition*/ 2) shapemanipulator_changes.rotatorPoint = /*shapeManipulatorRotationPointPosition*/ ctx[32];\n\t\t\tif (dirty[1] & /*shapeManipulatorScalarPointPosition*/ 1) shapemanipulator_changes.scalarPoint = /*shapeManipulatorScalarPointPosition*/ ctx[31];\n\t\t\tif (dirty[0] & /*shapeSelectedPointIndex*/ 1048576) shapemanipulator_changes.selectedPoint = /*shapeSelectedPointIndex*/ ctx[20];\n\t\t\tif (dirty[0] & /*allowEdgeControls*/ 2097152) shapemanipulator_changes.enableDragEdges = /*allowEdgeControls*/ ctx[21];\n\t\t\tif (dirty[1] & /*allowCornerControls*/ 8) shapemanipulator_changes.enableDragPoints = /*allowCornerControls*/ ctx[34];\n\t\t\tif (dirty[0] & /*allowRotateControls*/ 524288) shapemanipulator_changes.enableRotatePoints = /*allowRotateControls*/ ctx[19];\n\t\t\tif (dirty[0] & /*allowScaleControls*/ 131072) shapemanipulator_changes.enableScalePoints = /*allowScaleControls*/ ctx[17];\n\t\t\tshapemanipulator.$set(shapemanipulator_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapemanipulator.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapemanipulator.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapemanipulator, detaching);\n\t\t}\n\t};\n}\n\n// (5285:4) {#if shouldRenderTextInput}\nfunction create_if_block_1$3(ctx) {\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet if_block_anchor;\n\tlet current;\n\tconst if_block_creators = [create_if_block_2$3, create_if_block_3$2];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*textInputMode*/ ctx[6] === 'modal') return 0;\n\t\tif (/*textInputMode*/ ctx[6] === 'inline') return 1;\n\t\treturn -1;\n\t}\n\n\tif (~(current_block_type_index = select_block_type(ctx))) {\n\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block) if_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\t}\n\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tgroup_outros();\n\n\t\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\t\tif (!if_block) {\n\t\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\t\tif_block.c();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t\t}\n\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = null;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (5329:45) \nfunction create_if_block_3$2(ctx) {\n\tlet div;\n\tlet contenteditable;\n\tlet styleable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tlet contenteditable_props = {\n\t\tformatInput: /*formatContentEditable*/ ctx[53],\n\t\twrapLines: !!/*activeMarkupComputed*/ ctx[16].width,\n\t\ttextFormat: /*activeMarkupComputed*/ ctx[16].format,\n\t\tenableTextStyleShortcuts: /*enableTextStyleControls*/ ctx[7],\n\t\tallowNewline: /*shapeAllowNewline*/ ctx[33],\n\t\tstyles: /*textInputTextStyles*/ ctx[30]\n\t};\n\n\tcontenteditable = new ContentEditable({ props: contenteditable_props });\n\t/*contenteditable_binding*/ ctx[209](contenteditable);\n\tcontenteditable.$on(\"input\", /*handleTextInput*/ ctx[54]);\n\tcontenteditable.$on(\"keyup\", /*handleTextInputKeyUp*/ ctx[58]);\n\tcontenteditable.$on(\"cancel\", /*handleTextCancel*/ ctx[60]);\n\tcontenteditable.$on(\"confirm\", /*handleTextConfirm*/ ctx[59]);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(contenteditable.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaInlineInput\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(contenteditable, div, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\taction_destroyer(styleable_action = styleable.call(null, div, /*textInputPositionStyles*/ ctx[29])),\n\t\t\t\t\tlisten(div, \"focusout\", /*focusout_handler*/ ctx[210])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst contenteditable_changes = {};\n\t\t\tif (dirty[0] & /*activeMarkupComputed*/ 65536) contenteditable_changes.wrapLines = !!/*activeMarkupComputed*/ ctx[16].width;\n\t\t\tif (dirty[0] & /*activeMarkupComputed*/ 65536) contenteditable_changes.textFormat = /*activeMarkupComputed*/ ctx[16].format;\n\t\t\tif (dirty[0] & /*enableTextStyleControls*/ 128) contenteditable_changes.enableTextStyleShortcuts = /*enableTextStyleControls*/ ctx[7];\n\t\t\tif (dirty[1] & /*shapeAllowNewline*/ 4) contenteditable_changes.allowNewline = /*shapeAllowNewline*/ ctx[33];\n\t\t\tif (dirty[0] & /*textInputTextStyles*/ 1073741824) contenteditable_changes.styles = /*textInputTextStyles*/ ctx[30];\n\t\t\tcontenteditable.$set(contenteditable_changes);\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty[0] & /*textInputPositionStyles*/ 536870912) styleable_action.update.call(null, /*textInputPositionStyles*/ ctx[29]);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(contenteditable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(contenteditable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\t/*contenteditable_binding*/ ctx[209](null);\n\t\t\tdestroy_component(contenteditable);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (5286:8) {#if textInputMode === 'modal'}\nfunction create_if_block_2$3(ctx) {\n\tlet inputform;\n\tlet current;\n\n\tinputform = new InputForm({\n\t\t\tprops: {\n\t\t\t\tpanelOffset: /*offset*/ ctx[3],\n\t\t\t\tonconfirm: /*handleTextConfirm*/ ctx[59],\n\t\t\t\toncancel: /*handleTextCancel*/ ctx[60],\n\t\t\t\tbuttonCancel: {\n\t\t\t\t\ticon: /*locale*/ ctx[8].shapeIconInputCancel,\n\t\t\t\t\tlabel: /*locale*/ ctx[8].shapeLabelInputCancel\n\t\t\t\t},\n\t\t\t\tbuttonConfirm: {\n\t\t\t\t\ticon: /*locale*/ ctx[8].shapeIconInputConfirm,\n\t\t\t\t\tlabel: /*locale*/ ctx[8].shapeLabelInputConfirm,\n\t\t\t\t\thideLabel: true\n\t\t\t\t},\n\t\t\t\twillHandleKeydown: /*func*/ ctx[208],\n\t\t\t\t$$slots: { default: [create_default_slot$7] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(inputform.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(inputform, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst inputform_changes = {};\n\t\t\tif (dirty[0] & /*offset*/ 8) inputform_changes.panelOffset = /*offset*/ ctx[3];\n\n\t\t\tif (dirty[0] & /*locale*/ 256) inputform_changes.buttonCancel = {\n\t\t\t\ticon: /*locale*/ ctx[8].shapeIconInputCancel,\n\t\t\t\tlabel: /*locale*/ ctx[8].shapeLabelInputCancel\n\t\t\t};\n\n\t\t\tif (dirty[0] & /*locale*/ 256) inputform_changes.buttonConfirm = {\n\t\t\t\ticon: /*locale*/ ctx[8].shapeIconInputConfirm,\n\t\t\t\tlabel: /*locale*/ ctx[8].shapeLabelInputConfirm,\n\t\t\t\thideLabel: true\n\t\t\t};\n\n\t\t\tif (dirty[0] & /*activeMarkup*/ 8192) inputform_changes.willHandleKeydown = /*func*/ ctx[208];\n\n\t\t\tif (dirty[0] & /*textInput, textInputText, textInputTextStyles*/ 1342177792 | dirty[10] & /*$$scope*/ 65536) {\n\t\t\t\tinputform_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tinputform.$set(inputform_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(inputform.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(inputform.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(inputform, detaching);\n\t\t}\n\t};\n}\n\n// (5287:12) <InputForm                 panelOffset={offset}                 onconfirm={handleTextConfirm}                 oncancel={handleTextCancel}                 buttonCancel={{                     icon: locale.shapeIconInputCancel,                     label: locale.shapeLabelInputCancel,                 }}                 buttonConfirm={{                     icon: locale.shapeIconInputConfirm,                     label: locale.shapeLabelInputConfirm,                     hideLabel: true,                 }}                 willHandleKeydown={(e) => {                     const { key } = e;                     if (key === 'Enter') {                         // if is combo, always confirm                         if (isTextConfirmKeyCombination(e)) {                             return true;                         }                          // if can enter newlines a normal return doesn't confirm the text input                         if (activeMarkup.disableNewline === false) {                             return false;                         }                     }                     return true;                 }}             >\nfunction create_default_slot$7(ctx) {\n\tlet textarea;\n\tlet styleable_action;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\ttextarea = element(\"textarea\");\n\t\t\tattr(textarea, \"spellcheck\", \"false\");\n\t\t\tattr(textarea, \"autocorrect\", \"off\");\n\t\t\tattr(textarea, \"autocapitalize\", \"off\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, textarea, anchor);\n\t\t\t/*textarea_binding*/ ctx[206](textarea);\n\t\t\tset_input_value(textarea, /*textInputText*/ ctx[28]);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(textarea, \"keydown\", /*handleTextInputKeyDown*/ ctx[56]),\n\t\t\t\t\tlisten(textarea, \"keypress\", /*handleTextInputAttempt*/ ctx[55]),\n\t\t\t\t\tlisten(textarea, \"keyup\", /*handleTextInputKeyUp*/ ctx[58]),\n\t\t\t\t\tlisten(textarea, \"input\", /*handleTextInput*/ ctx[54]),\n\t\t\t\t\tlisten(textarea, \"input\", /*textarea_input_handler*/ ctx[207]),\n\t\t\t\t\taction_destroyer(styleable_action = styleable.call(null, textarea, /*textInputTextStyles*/ ctx[30]))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*textInputText*/ 268435456) {\n\t\t\t\tset_input_value(textarea, /*textInputText*/ ctx[28]);\n\t\t\t}\n\n\t\t\tif (styleable_action && is_function(styleable_action.update) && dirty[0] & /*textInputTextStyles*/ 1073741824) styleable_action.update.call(null, /*textInputTextStyles*/ ctx[30]);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(textarea);\n\t\t\t}\n\n\t\t\t/*textarea_binding*/ ctx[206](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (5355:4) {#if $markupControlsOpacity > 0}\nfunction create_if_block$5(ctx) {\n\tlet div;\n\tlet dynamiccomponenttree;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: {\n\t\t\t\titems: /*shapeControls*/ ctx[25],\n\t\t\t\tkey: /*activeShapeId*/ ctx[12]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaShapeControls\");\n\t\t\tset_style(div, \"transform\", /*styleMarkupControlTransform*/ ctx[27]);\n\t\t\tset_style(div, \"opacity\", /*styleMarkupControlOpacity*/ ctx[26]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(dynamiccomponenttree, div, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler_1*/ ctx[211]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty[0] & /*shapeControls*/ 33554432) dynamiccomponenttree_changes.items = /*shapeControls*/ ctx[25];\n\t\t\tif (dirty[0] & /*activeShapeId*/ 4096) dynamiccomponenttree_changes.key = /*activeShapeId*/ ctx[12];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\n\t\t\tif (dirty[0] & /*styleMarkupControlTransform*/ 134217728) {\n\t\t\t\tset_style(div, \"transform\", /*styleMarkupControlTransform*/ ctx[27]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleMarkupControlOpacity*/ 67108864) {\n\t\t\t\tset_style(div, \"opacity\", /*styleMarkupControlOpacity*/ ctx[26]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$f(ctx) {\n\tlet div;\n\tlet nav;\n\tlet ul;\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet t0;\n\tlet t1;\n\tlet t2;\n\tlet interactable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tlet each_value = ensure_array_like(/*shapeNavList*/ ctx[24]);\n\tconst get_key = ctx => /*item*/ ctx[323].id;\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context$1(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block$1(key, child_ctx));\n\t}\n\n\tlet if_block0 = /*shouldRenderShapeManipulator*/ ctx[18] && create_if_block_4$2(ctx);\n\tlet if_block1 = /*shouldRenderTextInput*/ ctx[14] && create_if_block_1$3(ctx);\n\tlet if_block2 = /*$markupControlsOpacity*/ ctx[22] > 0 && create_if_block$5(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tnav = element(\"nav\");\n\t\t\tul = element(\"ul\");\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tt0 = space();\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt1 = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tt2 = space();\n\t\t\tif (if_block2) if_block2.c();\n\t\t\tattr(nav, \"class\", \"PinturaShapeList\");\n\t\t\tattr(nav, \"data-visible\", /*showShapeList*/ ctx[23]);\n\t\t\tattr(div, \"class\", \"PinturaShapeEditor\");\n\t\t\tattr(div, \"tabindex\", \"0\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, nav);\n\t\t\tappend(nav, ul);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(ul, null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tappend(div, t0);\n\t\t\tif (if_block0) if_block0.m(div, null);\n\t\t\tappend(div, t1);\n\t\t\tif (if_block1) if_block1.m(div, null);\n\t\t\tappend(div, t2);\n\t\t\tif (if_block2) if_block2.m(div, null);\n\t\t\t/*div_binding*/ ctx[212](div);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(nav, \"focusin\", /*handleFocusIn*/ ctx[63]),\n\t\t\t\t\tlisten(nav, \"focusout\", /*handleFocusOut*/ ctx[64]),\n\t\t\t\t\tlisten(div, \"keydown\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0] ? noop$1 : /*handleKeyDown*/ ctx[52])) (/*disabled*/ ctx[0] ? noop$1 : /*handleKeyDown*/ ctx[52]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"nudge\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0] ? noop$1 : /*handleNudge*/ ctx[62])) (/*disabled*/ ctx[0] ? noop$1 : /*handleNudge*/ ctx[62]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler*/ ctx[204]),\n\t\t\t\t\tlisten(div, \"pointermove\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handlePointerMove*/ ctx[65])) (/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handlePointerMove*/ ctx[65]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"pointerleave\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handlePointerLeave*/ ctx[66])) (/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handlePointerLeave*/ ctx[66]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionstart\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionStart*/ ctx[37])) (/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionStart*/ ctx[37]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionupdate\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionUpdate*/ ctx[39])) (/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionUpdate*/ ctx[39]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactioncancel\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionCancel*/ ctx[38])) (/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionCancel*/ ctx[38]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionrelease\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionRelease*/ ctx[40])) (/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionRelease*/ ctx[40]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(div, \"interactionend\", function () {\n\t\t\t\t\t\tif (is_function(/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionEnd*/ ctx[41])) (/*disabled*/ ctx[0]\n\t\t\t\t\t\t? noop$1\n\t\t\t\t\t\t: /*handleInteractionEnd*/ ctx[41]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\taction_destroyer(measurable.call(null, div)),\n\t\t\t\t\taction_destroyer(nudgeable.call(null, div)),\n\t\t\t\t\taction_destroyer(interactable_action = interactable.call(null, div, {\n\t\t\t\t\t\tdrag: true,\n\t\t\t\t\t\tinertia: true,\n\t\t\t\t\t\tmultiTouch: false,\n\t\t\t\t\t\tobserveKeys: true,\n\t\t\t\t\t\tshouldStartInteraction: interactable_function,\n\t\t\t\t\t\tgetEventPosition: /*interactable_function_1*/ ctx[213]\n\t\t\t\t\t}))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (dirty[0] & /*shapeNavList*/ 16777216 | dirty[2] & /*selectShapeByIndex*/ 32) {\n\t\t\t\teach_value = ensure_array_like(/*shapeNavList*/ ctx[24]);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ul, outro_and_destroy_block, create_each_block$1, null, get_each_context$1);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty[0] & /*showShapeList*/ 8388608) {\n\t\t\t\tattr(nav, \"data-visible\", /*showShapeList*/ ctx[23]);\n\t\t\t}\n\n\t\t\tif (/*shouldRenderShapeManipulator*/ ctx[18]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*shouldRenderShapeManipulator*/ 262144) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_4$2(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div, t1);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*shouldRenderTextInput*/ ctx[14]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*shouldRenderTextInput*/ 16384) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_1$3(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(div, t2);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*$markupControlsOpacity*/ ctx[22] > 0) {\n\t\t\t\tif (if_block2) {\n\t\t\t\t\tif_block2.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*$markupControlsOpacity*/ 4194304) {\n\t\t\t\t\t\ttransition_in(if_block2, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block2 = create_if_block$5(ctx);\n\t\t\t\t\tif_block2.c();\n\t\t\t\t\ttransition_in(if_block2, 1);\n\t\t\t\t\tif_block2.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block2) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block2, 1, 1, () => {\n\t\t\t\t\tif_block2 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (interactable_action && is_function(interactable_action.update) && dirty[0] & /*rootRect*/ 16) interactable_action.update.call(null, {\n\t\t\t\tdrag: true,\n\t\t\t\tinertia: true,\n\t\t\t\tmultiTouch: false,\n\t\t\t\tobserveKeys: true,\n\t\t\t\tshouldStartInteraction: interactable_function,\n\t\t\t\tgetEventPosition: /*interactable_function_1*/ ctx[213]\n\t\t\t});\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\ttransition_in(if_block2);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\ttransition_out(if_block2);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d();\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t\tif (if_block2) if_block2.d();\n\t\t\t/*div_binding*/ ctx[212](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nconst POLYGON_END_PATH_DISTANCE_SQUARED = 256;\nconst POLYGON_VERTEX_MIN_DISTANCE_SQUARED = 100;\nconst SHAPE_CONTROL_OFFSET = 20;\n\n// UI hover shapes\nconst HoverShapeId = 'markup-hover';\n\nconst interactable_function = (e, element) => {\n\treturn e.target === element || e.target.className === 'PinturaContentEditable';\n};\n\nfunction instance$f($$self, $$props, $$invalidate) {\n\tlet gridRect;\n\tlet activeMarkup;\n\tlet multiSelection;\n\tlet isMultiSelection;\n\tlet multiSelectionComputed;\n\tlet activeMarkupSelected;\n\tlet activeShapeIsDraft;\n\tlet activeShapeId;\n\tlet activeMarkupComputed;\n\tlet activeMarkupItemIsDraft;\n\tlet shapeActivePoints;\n\tlet multiSelectionShapePoints;\n\tlet allowResizeControls;\n\tlet allowRotateControls;\n\tlet allowScaleControls;\n\tlet allowEdgeControls;\n\tlet allowCornerControls;\n\tlet multiSelectionPoints;\n\tlet shouldRenderShapeManipulator;\n\tlet selectionScreenPoints;\n\tlet shapeManipulatorPoints;\n\tlet shapeSelectedPointIndex;\n\tlet hasSelectedShapePoint;\n\tlet shapeSelectedManipulatorPoint;\n\tlet shapeAllowNewline;\n\tlet shapeManipulatorRotationPoint;\n\tlet shapeManipulatorRotationPointPosition;\n\tlet shapeManipulatorScalarPoint;\n\tlet shapeManipulatorScalarPointPosition;\n\tlet shouldSnapPointer;\n\tlet activeSelectionShape;\n\tlet isHoveringShape;\n\tlet isManagingShape;\n\tlet disableSnapping;\n\tlet isTextMarkupSelected;\n\tlet shouldRenderTextInput;\n\tlet textShapeOrigin;\n\tlet textShapeDisplayOrigin;\n\tlet textSizeDisplayOrigin;\n\tlet textRectDisplayOrigin;\n\tlet textInputText;\n\tlet activeTextShapeComputed;\n\tlet textInputTextStyles;\n\tlet textInputPositionStyles;\n\tlet caretColorRGBA;\n\tlet controlledMarkupItem;\n\tlet allowShapeFlip;\n\tlet allowShapeChangeTextLayout;\n\tlet allowShapeDuplicate;\n\tlet allowShapeRemove;\n\tlet allowShapeReorder;\n\tlet allowShapeInput;\n\tlet allowShapeAdjustOpacity;\n\tlet allowShapeStyleText;\n\tlet shouldShowMarkupControls;\n\tlet markupControlsAnchorPosition;\n\tlet shapeControlsPosition;\n\tlet styleMarkupControlTransform;\n\tlet styleMarkupControlOpacity;\n\tlet shapeControlsMode;\n\tlet shapeControls;\n\tlet shapeNavList;\n\n\tlet $shapes,\n\t\t$$unsubscribe_shapes = noop,\n\t\t$$subscribe_shapes = () => ($$unsubscribe_shapes(), $$unsubscribe_shapes = subscribe(shapes, $$value => $$invalidate(199, $shapes = $$value)), shapes);\n\n\tlet $markupControlsOpacity;\n\tlet $isAnimated;\n\tlet $keysPressedStored;\n\tlet $gridOpacity;\n\n\tlet $selection,\n\t\t$$unsubscribe_selection = noop,\n\t\t$$subscribe_selection = () => ($$unsubscribe_selection(), $$unsubscribe_selection = subscribe(selection, $$value => $$invalidate(203, $selection = $$value)), selection);\n\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_shapes());\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_selection());\n\tlet { uid = getUniqueId() } = $$props;\n\tlet { ui } = $$props;\n\tlet { disabled = false } = $$props;\n\tlet { shapes } = $$props;\n\t$$subscribe_shapes();\n\tlet { selection } = $$props;\n\t$$subscribe_selection();\n\tlet { offset } = $$props;\n\tlet { contextRotation = 0 } = $$props;\n\tlet { contextFlipX = false } = $$props;\n\tlet { contextFlipY = false } = $$props;\n\tlet { contextZoom = 1 } = $$props;\n\tlet { active = false } = $$props;\n\tlet { opacity = 1 } = $$props;\n\tlet { parentRect } = $$props;\n\tlet { rootRect } = $$props;\n\tlet { utilRect } = $$props;\n\tlet { hoverColor } = $$props;\n\tlet { caretColor } = $$props;\n\tlet { gridColor } = $$props;\n\tlet { snapColor } = $$props;\n\tlet { textInputMode = 'inline' } = $$props;\n\tlet { oninteractionstart = noop$1 } = $$props;\n\tlet { oninteractionupdate = noop$1 } = $$props;\n\tlet { oninteractionrelease = noop$1 } = $$props;\n\tlet { oninteractionend = noop$1 } = $$props;\n\tlet { oninteractioncancel = noop$1 } = $$props;\n\tlet { onaddshape = noop$1 } = $$props;\n\tlet { onupdateshape = noop$1 } = $$props;\n\tlet { onselectshape = noop$1 } = $$props;\n\tlet { onblurshape = noop$1 } = $$props;\n\tlet { onremoveshape = noop$1 } = $$props;\n\tlet { ontapshape = noop$1 } = $$props;\n\tlet { onhovershape = noop$1 } = $$props;\n\tlet { ontriggerhistorywrite = noop$1 } = $$props;\n\tlet { onhovercanvas = noop$1 } = $$props;\n\tlet { ontapcanvas = noop$1 } = $$props;\n\tlet { onleavecanvas = noop$1 } = $$props;\n\tlet { beforeSelectShape = () => true } = $$props;\n\tlet { beforeDeselectShape = () => true } = $$props;\n\tlet { beforeRemoveShape = () => true } = $$props;\n\tlet { beforeUpdateShape = (shape, props, rect) => props } = $$props;\n\tlet { willRenderShapeControls = passthrough } = $$props;\n\tlet { willRenderShapeTextControls = passthrough } = $$props;\n\tlet { willStartInteraction = (position, rect) => true } = $$props;\n\tlet { mapEditorPointToImagePoint } = $$props;\n\tlet { mapImagePointToEditorPoint } = $$props;\n\tlet { eraseRadius = undefined } = $$props;\n\tlet { selectRadius = undefined } = $$props;\n\tlet { enableButtonFlipVertical = false } = $$props;\n\tlet { enableTapToAddText = true } = $$props;\n\tlet { enableMultiSelect = false } = $$props;\n\tlet { enableTextStyleControls = true } = $$props;\n\tlet { locale } = $$props;\n\tlet { snapThreshold = 0 } = $$props;\n\tlet { snapPointer = true } = $$props;\n\tlet { enableSnapToContext = true } = $$props;\n\tlet { gridSize = 0 } = $$props;\n\n\t// returns currently relevant snap targets, excludes \"excludedShape\" from targets\n\tconst getSnapTargets = excludedShape => {\n\t\t// no targets if not snapping\n\t\tif (snapThreshold === 0) return [];\n\n\t\t// create context\n\t\tlet contextShape;\n\n\t\tif (enableSnapToContext) {\n\t\t\tcontextShape = { ...parentRect, x: 0, y: 0 };\n\t\t}\n\n\t\treturn [\n\t\t\t// exclude interaction shape\n\t\t\t...$shapes.// don't include self\n\t\t\tfilter(shape => shape !== excludedShape).// don't include drafts\n\t\t\tfilter(shape => !shapeIsDraft(shape)).// exclude shapes that are not snap targets\n\t\t\tfilter(shape => shapeCanAcceptSnap(shape)).// only useful when we have computed shapes\n\t\t\tmap(shape => shapeComputeDisplay({ ...shape }, parentRect)),\n\t\t\t// also snap to context edges and center\n\t\t\tcontextShape\n\t\t].filter(Boolean);\n\t};\n\n\t// helper function to get snap options when resizing or translating shapes\n\tconst getSnapOptions = (snapThreshold, gridSize, gridRect, excludedShape) => {\n\t\t// no snapping\n\t\tif (snapThreshold === 0) return { snapTargets: [] };\n\n\t\t// let's define snap options\n\t\treturn {\n\t\t\tsnapThreshold,\n\t\t\tgridSize,\n\t\t\tgridRect,\n\t\t\tsnapTargets: getSnapTargets(excludedShape)\n\t\t};\n\t};\n\n\tconst isAnimated = getContext('isAnimated');\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(200, $isAnimated = value));\n\tconst softKeyboardState = getContext('softKeyboardState');\n\tconst syncShapeCollection = collection => collection.set(get_store_value(collection));\n\tconst getShapeDraft = collection => get_store_value(collection).find(shapeIsDraft);\n\n\tconst addShapeDraft = (shape, collection) => {\n\t\t// collection already contains a shape, exit\n\t\tif (getShapeDraft(collection)) return;\n\n\t\t// turn shape intro draft\n\t\tshapeMakeDraft(shape);\n\n\t\t// add to collection\n\t\treturn addShape(shape, collection);\n\t};\n\n\tconst discardShapeDraft = collection => {\n\t\t// don't trigger update if no draft in array\n\t\tif (!getShapeDraft(collection)) return;\n\n\t\t// update!\n\t\tcollection.update(items => items.filter(shape => !shapeIsDraft(shape)));\n\t};\n\n\tconst confirmShapeDraft = collection => {\n\t\t// don't trigger update if no draft in array\n\t\tconst draft = getShapeDraft(collection);\n\n\t\tif (!draft) {\n\t\t\treturn;\n\t\t}\n\n\t\tshapeMakeFinal(draft);\n\t\tsyncShapeCollection(collection);\n\t\treturn draft;\n\t};\n\n\tconst updateShapeDraft = (props, collection, update = (item, props) => ({ ...item, ...props })) => {\n\t\t// don't trigger update if no draft in array\n\t\tconst draft = getShapeDraft(collection);\n\n\t\tif (!draft) {\n\t\t\treturn;\n\t\t}\n\n\t\tcollection.update(items => items.map(item => {\n\t\t\tif (!shapeIsDraft(item)) {\n\t\t\t\treturn item;\n\t\t\t}\n\n\t\t\treturn update(item, props);\n\t\t}));\n\t};\n\n\tconst addShape = (shape, collection = shapes) => {\n\t\tcollection.update(items => [...items, shape]);\n\t\treturn shape;\n\t};\n\n\t// helpers\n\tconst updateShape = (shape, props, parentRect) => {\n\t\tconst propsToUpdate = beforeUpdateShape({ ...shape }, props, { ...parentRect });\n\t\tshapeUpdateProps(shape, propsToUpdate, parentRect);\n\t\treturn shape;\n\t};\n\n\tconst positionRelativeToAnchor = (anchor, target) => {\n\t\tconst length = vectorDistance(anchor, target);\n\t\tconst angle = vectorAngleBetween(anchor, target);\n\t\tconst angleSnapInterval = Math.PI / 8;\n\t\tconst angleSnapped = angleSnapInterval * Math.round(angle / angleSnapInterval) - contextRotation % angleSnapInterval;\n\t\ttarget.x = anchor.x + length * Math.cos(angleSnapped);\n\t\ttarget.y = anchor.y + length * Math.sin(angleSnapped);\n\t};\n\n\tconst shapeToPoly = (computedShape, resolution = 12) => {\n\t\t// rect to poly\n\t\tif (shapeIsRect(computedShape)) {\n\t\t\treturn rectRotate(computedShape, computedShape.rotation, rectCenter(computedShape));\n\t\t} else // text to poly\n\t\tif (shapeIsText(computedShape)) {\n\t\t\tconst computedRect = getMarkupShapeRect(computedShape);\n\t\t\treturn rectRotate(computedRect, computedShape.rotation, rectCenter(computedRect));\n\t\t} else // ellipse\n\t\tif (shapeIsEllipse(computedShape)) {\n\t\t\treturn ellipseToPolygon(vectorCreate(computedShape.x, computedShape.y), computedShape.rx, computedShape.ry, computedShape.rotation, computedShape.flipX, computedShape.flipY, resolution);\n\t\t}\n\n\t\treturn [];\n\t};\n\n\t//#region createShape eraseShape\n\tconst keysPressedStored = getContext('keysPressed');\n\n\tcomponent_subscribe($$self, keysPressedStored, value => $$invalidate(201, $keysPressedStored = value));\n\n\t// draw shape manipulator edges\n\tconst getShapeUpdateRotation = (rotation, flipX, flipY) => {\n\t\tif (rotation === 0) return rotation;\n\t\tif (flipX && flipY) return rotation;\n\t\tif (flipX) return -rotation;\n\t\tif (flipY) return -rotation;\n\t\treturn rotation;\n\t};\n\n\tconst setInteractionSnapLines = snapLines => {\n\t\tif (snapLines.x === null && snapLines.y === null) return clearInteractionSnapLines();\n\t\tif (snapLines.x) $$invalidate(152, interactionSnapLineX = mapEditorPointToImagePoint({ x: snapLines.x, y: 0 }).x);\n\t\tif (snapLines.y) $$invalidate(153, interactionSnapLineY = mapEditorPointToImagePoint({ x: 0, y: snapLines.y }).y);\n\t};\n\n\tconst clearInteractionSnapLines = () => {\n\t\t$$invalidate(152, interactionSnapLineX = null);\n\t\t$$invalidate(153, interactionSnapLineY = null);\n\t};\n\n\tlet interactionSnapLineX = null;\n\tlet interactionSnapLineY = null;\n\tlet interactionStepped = false;\n\n\tconst createShape = (shapeDefault, options = {}) => {\n\t\t// state\n\t\t$$invalidate(154, interactionStepped = false);\n\n\t\tlet interactionOrigin;\n\t\tlet interactionRadius;\n\t\tlet interactionPosition;\n\t\tlet interactionPositions = [];\n\t\tlet isEllipse = shapeIsEllipse(shapeDefault);\n\t\tlet isText = shapeIsText(shapeDefault);\n\t\tlet isRelative = options.position === 'relative';\n\t\tconst shouldInterpolate = options.interpolateInput;\n\n\t\t// get snap targets\n\t\tconst snapTargets = getSnapTargets();\n\n\t\t// snap point to targets\n\t\tconst snapPoint = point => {\n\t\t\t// do nothing if doens't need to snap\n\t\t\tif (!snapThreshold) return point;\n\n\t\t\t// snap point to shapes/grid\n\t\t\tconst imagePoint = mapEditorPointToImagePoint(point);\n\n\t\t\tconst { snapTranslation, snapLines } = snapLinesToTargets(getShapeSnapLines(imagePoint), snapTargets, snapThreshold, gridSize, gridRect);\n\t\t\tupdateWithSnapTranslation(point, snapTranslation);\n\t\t\tsetInteractionSnapLines(snapLines);\n\t\t\treturn point;\n\t\t};\n\n\t\t// a shape is selected\n\t\tconst hasSelectedShape = !!getSelectedShape();\n\n\t\t// target shapes list or collection\n\t\tconst collection = options.isSelection ? selection : shapes;\n\n\t\tconst isSteppedInputMode = options.inputMode === 'step';\n\n\t\tif (shapeIsPath(shapeDefault)) {\n\t\t\t// stepped input mode\n\t\t\tif (isSteppedInputMode) {\n\t\t\t\t$$invalidate(154, interactionStepped = true);\n\t\t\t\tlet isFirstPoint = false;\n\n\t\t\t\tconst getPoint = (previousPoint, pointerPosition) => {\n\t\t\t\t\t// has started drawing? only handle end\n\t\t\t\t\tconst draft = getShapeDraft(collection);\n\n\t\t\t\t\tconst currentPoints = draft.points;\n\n\t\t\t\t\t// if has previous point\n\t\t\t\t\tconst previousPointComputed = previousPoint && vectorCreate(fromPercentage(previousPoint.x, parentRect.width), fromPercentage(previousPoint.y, parentRect.height));\n\n\t\t\t\t\t// point in editor view\n\t\t\t\t\tconst previousPointInEditor = previousPointComputed && mapImagePointToEditorPoint(previousPointComputed);\n\n\t\t\t\t\t// if shift is held snap to last point\n\t\t\t\t\tif ($keysPressedStored.includes(16) && previousPointInEditor) positionRelativeToAnchor(previousPointInEditor, pointerPosition);\n\n\t\t\t\t\tconst currentPoint = mapEditorPointToImagePoint(pointerPosition);\n\n\t\t\t\t\t// get first point as absolute\n\t\t\t\t\tconst originPoint = currentPoints.length ? currentPoints[0] : currentPoint;\n\n\t\t\t\t\tconst originPointComputed = vectorCreate(fromPercentage(originPoint.x, parentRect.width), fromPercentage(originPoint.y, parentRect.height));\n\n\t\t\t\t\t// point in editor view\n\t\t\t\t\tconst originPointInEditor = mapImagePointToEditorPoint(originPointComputed);\n\n\t\t\t\t\t// distance between origin and new point\n\t\t\t\t\tconst distFromOriginSquared = vectorDistanceSquared(originPointInEditor, pointerPosition);\n\n\t\t\t\t\t// clicked second point at same location, discard draft\n\t\t\t\t\tif (!isFirstPoint && currentPoints.length === 1 && distFromOriginSquared < 36) {\n\t\t\t\t\t\treturn discardShapeDraft(collection);\n\t\t\t\t\t}\n\n\t\t\t\t\t// minimum of three points to create a polygon\n\t\t\t\t\tif (currentPoints.length > 2 && distFromOriginSquared <= POLYGON_END_PATH_DISTANCE_SQUARED) {\n\t\t\t\t\t\tdraft.pathClose = true;\n\n\t\t\t\t\t\t// without pointer pointer\n\t\t\t\t\t\tdelete draft.pointerPoint;\n\n\t\t\t\t\t\t// select the draft\n\t\t\t\t\t\tshapeCanSelect(draft) && selectShape(draft);\n\n\t\t\t\t\t\tconst shape = confirmShapeDraft(collection);\n\t\t\t\t\t\tonaddshape(shape);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// clicked at same location as previous point, confirm as line\n\t\t\t\t\tconst hasVisibleStroke = draft.strokeWidth && draft.strokeColor && (draft.strokeColor[3] === undefined || draft.strokeColor[3] > 0);\n\n\t\t\t\t\tconst distFromPreviousSquared = vectorDistanceSquared(previousPointInEditor, pointerPosition);\n\n\t\t\t\t\tif (hasVisibleStroke && draft.pathClose !== true && currentPoints.length > 1 && distFromPreviousSquared < POLYGON_END_PATH_DISTANCE_SQUARED) {\n\t\t\t\t\t\t// without pointer pointer\n\t\t\t\t\t\tdelete draft.pointerPoint;\n\n\t\t\t\t\t\t// open path\n\t\t\t\t\t\tdraft.pathClose = false;\n\n\t\t\t\t\t\tdraft.backgroundColor = [0, 0, 0, 0];\n\n\t\t\t\t\t\t// select the draft\n\t\t\t\t\t\tshapeCanSelect(draft) && selectShape(draft);\n\n\t\t\t\t\t\tconst shape = confirmShapeDraft(collection);\n\t\t\t\t\t\tonaddshape(shape);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// distance between previous and new point needs to be sufficient\n\t\t\t\t\tif (currentPoints.length > 0) {\n\t\t\t\t\t\tif (distFromPreviousSquared < POLYGON_VERTEX_MIN_DISTANCE_SQUARED) return;\n\t\t\t\t\t}\n\n\t\t\t\t\t// return new point!\n\t\t\t\t\treturn isRelative\n\t\t\t\t\t? toPercentagePoint(currentPoint, parentRect)\n\t\t\t\t\t: currentPoint;\n\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tstart: e => {\n\t\t\t\t\t\tconst draft = getShapeDraft(collection);\n\t\t\t\t\t\tconst { origin } = e.detail;\n\t\t\t\t\t\tinteractionRadius = 4;\n\t\t\t\t\t\tinteractionOrigin = snapPoint(vectorClone(origin));\n\t\t\t\t\t\tinteractionPosition = vectorClone(interactionOrigin);\n\n\t\t\t\t\t\t// has started drawing? only handle end\n\t\t\t\t\t\tif (draft) {\n\t\t\t\t\t\t\t// add next point\n\t\t\t\t\t\t\tconst currentPoints = draft.points;\n\n\t\t\t\t\t\t\tconst previousPoint = currentPoints[currentPoints.length - 1];\n\t\t\t\t\t\t\tconst computedPoint = getPoint(previousPoint, interactionOrigin);\n\n\t\t\t\t\t\t\tif (computedPoint) {\n\t\t\t\t\t\t\t\tdraft.points = [...currentPoints, computedPoint];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tupdateShapeDraft({ points: draft.points }, collection);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// first point\n\t\t\t\t\t\tisFirstPoint = true;\n\t\t\t\t\t},\n\t\t\t\t\tupdate: e => {\n\t\t\t\t\t\t// this only runs for first point so we can drag to start AND tap to start a path\n\t\t\t\t\t\tif (!isFirstPoint) return;\n\n\t\t\t\t\t\t// get draft ref\n\t\t\t\t\t\tconst draft = getShapeDraft(collection);\n\n\t\t\t\t\t\tif (!draft) return;\n\n\t\t\t\t\t\t// get next point\n\t\t\t\t\t\tconst previousPoint = draft.points[0];\n\n\t\t\t\t\t\tconst computedPoint = getPoint(previousPoint, vectorCreate(interactionOrigin.x + e.detail.translation.x, interactionOrigin.y + e.detail.translation.y));\n\t\t\t\t\t\tif (!computedPoint) return;\n\n\t\t\t\t\t\t// first point is pointerdown, keep overwriting next point\n\t\t\t\t\t\tdraft.points[1] = computedPoint;\n\n\t\t\t\t\t\tupdateShapeDraft({ points: draft.points }, collection);\n\t\t\t\t\t},\n\t\t\t\t\trelease: e => {\n\t\t\t\t\t\te.detail.preventInertia();\n\t\t\t\t\t},\n\t\t\t\t\tcancel: () => {\n\t\t\t\t\t\tdiscardShapeDraft(collection);\n\t\t\t\t\t},\n\t\t\t\t\tend: e => {\n\t\t\t\t\t\tif (!isFirstPoint) return;\n\n\t\t\t\t\t\t// hasn't started drawing yet, let's add origin\n\t\t\t\t\t\tconst originPoint = mapEditorPointToImagePoint(interactionOrigin);\n\n\t\t\t\t\t\tconst computedPoint = isRelative\n\t\t\t\t\t\t? toPercentagePoint(originPoint, parentRect)\n\t\t\t\t\t\t: originPoint;\n\n\t\t\t\t\t\t// if is tap\n\t\t\t\t\t\tconst { isTap } = e.detail;\n\n\t\t\t\t\t\tif (isTap) {\n\t\t\t\t\t\t\t// if any shape below pointer select the shape and discard the path\n\t\t\t\t\t\t\tconst foundShapes = getShapesNearPosition($shapes, originPoint, 0, shapeCanSelect);\n\n\t\t\t\t\t\t\tif (foundShapes.length) {\n\t\t\t\t\t\t\t\treturn discardShapeDraft(collection);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// add to markup so it's drawn\n\t\t\t\t\t\taddShapeDraft({ ...shapeDefault, points: [computedPoint] }, collection);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// drag input mode\n\t\t\treturn {\n\t\t\t\tstart: e => {\n\t\t\t\t\tconst { origin } = e.detail;\n\t\t\t\t\tinteractionRadius = 4;\n\t\t\t\t\tinteractionOrigin = vectorClone(origin);\n\t\t\t\t\tinteractionPosition = vectorClone(interactionOrigin);\n\n\t\t\t\t\t// add first point\n\t\t\t\t\tinteractionPositions.push({ ...interactionPosition });\n\n\t\t\t\t\t// to shape point\n\t\t\t\t\tconst originPoint = mapEditorPointToImagePoint(interactionOrigin);\n\n\t\t\t\t\tconst computedPoint = isRelative\n\t\t\t\t\t? toPercentagePoint(originPoint, parentRect)\n\t\t\t\t\t: originPoint;\n\n\t\t\t\t\t// add to markup so it's drawn\n\t\t\t\t\taddShapeDraft({ ...shapeDefault, points: [computedPoint] }, collection);\n\t\t\t\t},\n\t\t\t\tupdate: e => {\n\t\t\t\t\tconst draft = getShapeDraft(collection);\n\t\t\t\t\tif (!draft) return;\n\t\t\t\t\tconst { translation } = e.detail;\n\n\t\t\t\t\t// position\n\t\t\t\t\tconst pointerPosition = vectorCreate(interactionOrigin.x + translation.x, interactionOrigin.y + translation.y);\n\n\t\t\t\t\t// distance between interaction and pointer if it's too close, we don't draw this point\n\t\t\t\t\tconst dist = vectorDistance(interactionPosition, pointerPosition);\n\n\t\t\t\t\tif (fixPrecision(dist, 5) <= interactionRadius) return;\n\n\t\t\t\t\t// final points to add to shape\n\t\t\t\t\tconst pointsToAdd = [];\n\n\t\t\t\t\t// create smoothed target position\n\t\t\t\t\tconst angle = vectorAngleBetween(pointerPosition, interactionPosition);\n\n\t\t\t\t\tconst moveDist = interactionRadius - dist;\n\n\t\t\t\t\tconst targetPosition = {\n\t\t\t\t\t\tx: interactionPosition.x + moveDist * Math.cos(angle),\n\t\t\t\t\t\ty: interactionPosition.y + moveDist * Math.sin(angle)\n\t\t\t\t\t};\n\n\t\t\t\t\t// remember\n\t\t\t\t\tinteractionPositions.push({ ...targetPosition });\n\n\t\t\t\t\t// need more than two positions to start smoothing process\n\t\t\t\t\tif (shouldInterpolate && draft.points.length > 1) {\n\t\t\t\t\t\tconst totalPositions = interactionPositions.length;\n\t\t\t\t\t\tconst steps = Math.ceil(dist / 10);\n\t\t\t\t\t\tlet scale = dist / 30;\n\t\t\t\t\t\tconst a = interactionPositions[totalPositions - 3];\n\t\t\t\t\t\tconst b = interactionPositions[totalPositions - 2];\n\t\t\t\t\t\tconst c = interactionPositions[totalPositions - 1];\n\n\t\t\t\t\t\t// scale first segment, as it doesn't have smoothed points it's relatively long\n\t\t\t\t\t\tif (!interactionPositions[totalPositions - 4]) {\n\t\t\t\t\t\t\tscale *= 0.1;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpointsToAdd.push(...pointsInterpolate(a, b, c, steps, scale).slice(1, -1));\n\t\t\t\t\t\tinteractionPositions.splice(totalPositions - 1, 0, ...pointsToAdd);\n\t\t\t\t\t}\n\n\t\t\t\t\t// add target\n\t\t\t\t\tpointsToAdd.push(targetPosition);\n\n\t\t\t\t\t// remember so we can determine how far we moved from previous interaction\n\t\t\t\t\tinteractionPosition.x = targetPosition.x;\n\n\t\t\t\t\tinteractionPosition.y = targetPosition.y;\n\n\t\t\t\t\tupdateShapeDraft(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpoints: draft.points.concat(pointsToAdd.map(pointToAdd => {\n\t\t\t\t\t\t\t\tconst point = mapEditorPointToImagePoint(pointToAdd);\n\n\t\t\t\t\t\t\t\tconst computedPoint = isRelative\n\t\t\t\t\t\t\t\t? toPercentagePoint(point, parentRect)\n\t\t\t\t\t\t\t\t: point;\n\n\t\t\t\t\t\t\t\treturn computedPoint;\n\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcollection\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\trelease: e => e.detail.preventInertia(),\n\t\t\t\tcancel: () => {\n\t\t\t\t\tdiscardShapeDraft(collection);\n\t\t\t\t},\n\t\t\t\tend: e => {\n\t\t\t\t\tconst draft = getShapeDraft(collection);\n\t\t\t\t\tif (!draft) return;\n\n\t\t\t\t\t// if is bitmap we've just drawn a dot\n\t\t\t\t\tif (e.detail.isTap) {\n\t\t\t\t\t\tlet shouldDiscard = false;\n\n\t\t\t\t\t\t// if is bitmap can draw dots\n\t\t\t\t\t\tif (draft.bitmap) {\n\t\t\t\t\t\t\tif (interactionTarget) shouldDiscard = true;\n\t\t\t\t\t\t\tif (hasSelectedShape) shouldDiscard = true;\n\t\t\t\t\t\t} else // non-bitmap cannot create 1 point lines\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tshouldDiscard = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shouldDiscard) return discardShapeDraft(collection);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shape = confirmShapeDraft(collection);\n\t\t\t\t\tonaddshape(shape);\n\t\t\t\t}\n\t\t\t};\n\t\t} else if (isEllipse || isText || shapeIsRect(shapeDefault)) {\n\t\t\treturn {\n\t\t\t\tstart: e => {\n\t\t\t\t\tconst { origin } = e.detail;\n\n\t\t\t\t\t// need to remember origin so we can correctly apply interaction translation\n\t\t\t\t\tinteractionOrigin = snapPoint(vectorClone(origin));\n\n\t\t\t\t\tconst mappedOriginPosition = mapEditorPointToImagePoint(interactionOrigin);\n\n\t\t\t\t\tconst computedOriginPosition = isRelative\n\t\t\t\t\t? toPercentagePoint(mappedOriginPosition, parentRect)\n\t\t\t\t\t: mappedOriginPosition;\n\n\t\t\t\t\tconst rotation = -1 * getShapeUpdateRotation(contextRotation, contextFlipX, contextFlipY);\n\n\t\t\t\t\t// add to markup so it's drawn\n\t\t\t\t\tconst draft = {\n\t\t\t\t\t\t...shapeDefault,\n\t\t\t\t\t\trotation,\n\t\t\t\t\t\t...computedOriginPosition\n\t\t\t\t\t};\n\n\t\t\t\t\t// de-flip shape\n\t\t\t\t\tdraft.flipX = contextFlipX;\n\n\t\t\t\t\tdraft.flipY = contextFlipY;\n\n\t\t\t\t\t// remove position\n\t\t\t\t\tdelete draft.position;\n\n\t\t\t\t\t// hide initially\n\t\t\t\t\tdraft.opacity = 0;\n\n\t\t\t\t\t// set base position props\n\t\t\t\t\tconst initProps = isEllipse ? ['rx', 'ry'] : ['width', 'height'];\n\n\t\t\t\t\tinitProps.forEach(prop => {\n\t\t\t\t\t\t// set base props\n\t\t\t\t\t\tdraft[prop] = isRelative ? '0%' : 0;\n\t\t\t\t\t});\n\n\t\t\t\t\taddShapeDraft(draft, collection);\n\t\t\t\t},\n\t\t\t\tupdate: e => {\n\t\t\t\t\tconst draft = getShapeDraft(collection);\n\t\t\t\t\tif (!draft) return;\n\t\t\t\t\tdraft.opacity = 1;\n\t\t\t\t\tlet { aspectRatio } = draft;\n\t\t\t\t\tlet { translation, shiftKey, ctrlKey } = e.detail;\n\n\t\t\t\t\t// always draw squares when holding shift\n\t\t\t\t\tif (!aspectRatio && shiftKey) aspectRatio = 1;\n\n\t\t\t\t\t// position\n\t\t\t\t\tconst pointerPosition = snapPoint(vectorCreate(interactionOrigin.x + translation.x, interactionOrigin.y + translation.y));\n\n\t\t\t\t\tconst mappedOriginPosition = mapEditorPointToImagePoint(interactionOrigin);\n\t\t\t\t\tconst mappedPointerPosition = mapEditorPointToImagePoint(pointerPosition);\n\n\t\t\t\t\t// force pointer position to fixed aspect ratio\n\t\t\t\t\tif (aspectRatio) {\n\t\t\t\t\t\tconst pointerArea = rectCreateFromPoints([mappedOriginPosition, mappedPointerPosition]);\n\t\t\t\t\t\tconst pointerAreaSnapped = rectContainRect(pointerArea, aspectRatio);\n\n\t\t\t\t\t\tconst mx = mappedPointerPosition.x < mappedOriginPosition.x\n\t\t\t\t\t\t? -1\n\t\t\t\t\t\t: 1;\n\n\t\t\t\t\t\tconst my = mappedPointerPosition.y < mappedOriginPosition.y\n\t\t\t\t\t\t? -1\n\t\t\t\t\t\t: 1;\n\n\t\t\t\t\t\tmappedPointerPosition.x = mappedOriginPosition.x + pointerAreaSnapped.width * mx;\n\t\t\t\t\t\tmappedPointerPosition.y = mappedOriginPosition.y + pointerAreaSnapped.height * my;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst pivot = {\n\t\t\t\t\t\tx: mappedOriginPosition.x + (mappedPointerPosition.x - mappedOriginPosition.x) * 0.5,\n\t\t\t\t\t\ty: mappedOriginPosition.y + (mappedPointerPosition.y - mappedOriginPosition.y) * 0.5\n\t\t\t\t\t};\n\n\t\t\t\t\tconst rotation = getShapeUpdateRotation(contextRotation, contextFlipX, contextFlipY);\n\t\t\t\t\tvectorRotate(mappedOriginPosition, rotation, pivot);\n\t\t\t\t\tvectorRotate(mappedPointerPosition, rotation, pivot);\n\t\t\t\t\tconst l = Math.min(mappedOriginPosition.x, mappedPointerPosition.x);\n\t\t\t\t\tconst t = Math.min(mappedOriginPosition.y, mappedPointerPosition.y);\n\t\t\t\t\tconst r = Math.max(mappedOriginPosition.x, mappedPointerPosition.x);\n\t\t\t\t\tconst b = Math.max(mappedOriginPosition.y, mappedPointerPosition.y);\n\t\t\t\t\tlet width = r - l;\n\t\t\t\t\tlet height = b - t;\n\t\t\t\t\tlet props = {};\n\n\t\t\t\t\tif (isEllipse) {\n\t\t\t\t\t\tif (ctrlKey) {\n\t\t\t\t\t\t\tprops.x = mappedOriginPosition.x;\n\t\t\t\t\t\t\tprops.y = mappedOriginPosition.y;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprops.x = l + width * 0.5;\n\t\t\t\t\t\t\tprops.y = t + height * 0.5;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tprops.rx = width * 0.5;\n\t\t\t\t\t\tprops.ry = height * 0.5;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (ctrlKey) {\n\t\t\t\t\t\t\tprops.x = mappedOriginPosition.x - width * 0.5;\n\t\t\t\t\t\t\tprops.y = mappedOriginPosition.y - height * 0.5;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprops.x = l;\n\t\t\t\t\t\t\tprops.y = t;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tprops.width = width;\n\t\t\t\t\t\tprops.height = height;\n\t\t\t\t\t}\n\n\t\t\t\t\tupdateShapeDraft(props, collection, (item, props) => {\n\t\t\t\t\t\treturn updateShape(item, props, parentRect);\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\trelease: e => {\n\t\t\t\t\te.detail.preventInertia();\n\t\t\t\t},\n\t\t\t\tcancel: () => {\n\t\t\t\t\tdiscardShapeDraft(collection);\n\t\t\t\t},\n\t\t\t\tend: e => {\n\t\t\t\t\tconst draft = getShapeDraft(collection);\n\t\t\t\t\tif (!draft) return;\n\n\t\t\t\t\tif (e.detail.isTap) {\n\t\t\t\t\t\t// will discard a new text shape when created by tap and a previous text shape was just confirmed\n\t\t\t\t\t\tif (shapeIsText(draft) && enableTapToAddText && interactionShapeWasConfirmed) {\n\t\t\t\t\t\t\treturn discardShapeDraft(collection);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// will cancel if is not text shape\n\t\t\t\t\t\tif (!shapeIsText(draft) || !enableTapToAddText || interactionTarget) {\n\t\t\t\t\t\t\treturn discardShapeDraft(collection);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// will add 'auto' text shape if not targetting other shape\n\t\t\t\t\t\tdelete draft.width;\n\n\t\t\t\t\t\tdelete draft.height;\n\n\t\t\t\t\t\tif (draft.disableNewline !== false) {\n\t\t\t\t\t\t\tdelete draft.textAlign;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// position the shape correctly\n\t\t\t\t\t\tconst draftComputedShape = shapeComputeDisplay({ ...draft }, parentRect);\n\n\t\t\t\t\t\tconst size = textToSize(draft.text, draftComputedShape);\n\n\t\t\t\t\t\tconst mappedOriginPosition = mapEditorPointToImagePoint({\n\t\t\t\t\t\t\tx: interactionOrigin.x,\n\t\t\t\t\t\t\ty: interactionOrigin.y - size.height * 0.5\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst mappedPointerPosition = mapEditorPointToImagePoint({\n\t\t\t\t\t\t\tx: interactionOrigin.x + size.width,\n\t\t\t\t\t\t\ty: interactionOrigin.y + size.height * 0.5\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tconst pivot = {\n\t\t\t\t\t\t\tx: mappedOriginPosition.x + (mappedPointerPosition.x - mappedOriginPosition.x) * 0.5,\n\t\t\t\t\t\t\ty: mappedOriginPosition.y + (mappedPointerPosition.y - mappedOriginPosition.y) * 0.5\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst rotation = getShapeUpdateRotation(contextRotation, contextFlipX, contextFlipY);\n\t\t\t\t\t\tvectorRotate(mappedOriginPosition, rotation, pivot);\n\t\t\t\t\t\tvectorRotate(mappedPointerPosition, rotation, pivot);\n\t\t\t\t\t\tlet l = Math.min(mappedOriginPosition.x, mappedPointerPosition.x);\n\t\t\t\t\t\tlet t = Math.min(mappedOriginPosition.y, mappedPointerPosition.y);\n\t\t\t\t\t\tif (l < 0) l = 0;\n\t\t\t\t\t\tif (t < 0) t = 0;\n\t\t\t\t\t\tif (l + size.width > parentRect.width) l = parentRect.width - size.width;\n\t\t\t\t\t\tif (t + size.height > parentRect.height) t = parentRect.height - size.height;\n\n\t\t\t\t\t\tdraft.x = isString(draft.x)\n\t\t\t\t\t\t? toPercentage(l, parentRect.width)\n\t\t\t\t\t\t: l;\n\n\t\t\t\t\t\tdraft.y = isString(draft.y)\n\t\t\t\t\t\t? toPercentage(t, parentRect.height)\n\t\t\t\t\t\t: t;\n\t\t\t\t\t}\n\n\t\t\t\t\t// reveal\n\t\t\t\t\tdraft.opacity = 1;\n\n\t\t\t\t\t// finish markup\n\t\t\t\t\tif (!shapeIsText(draft)) {\n\t\t\t\t\t\tconst shape = confirmShapeDraft(collection);\n\t\t\t\t\t\tonaddshape(shape);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// is text\n\t\t\t\t\t\tconst draftComputedShape = shapeComputeDisplay({ ...draft }, parentRect);\n\n\t\t\t\t\t\t// discard if is just too small\n\t\t\t\t\t\tif (isNumber(draftComputedShape.width) && draftComputedShape.width < 1 || isNumber(draftComputedShape.height) && draftComputedShape.height < 1) {\n\t\t\t\t\t\t\treturn discardShapeDraft(collection);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tonaddshape(draft);\n\t\t\t\t\t}\n\n\t\t\t\t\t// select the draft\n\t\t\t\t\tshapeCanSelect(draft) && selectShape(draft);\n\n\t\t\t\t\t// also enable editing the text\n\t\t\t\t\tif (shapeIsText(draft)) editMarkupItem(draft);\n\t\t\t\t}\n\t\t\t};\n\t\t} else if (shapeIsLine(shapeDefault)) {\n\t\t\treturn {\n\t\t\t\tstart: e => {\n\t\t\t\t\tconst { origin } = e.detail;\n\t\t\t\t\tconst originMapped = mapEditorPointToImagePoint(snapPoint(origin));\n\t\t\t\t\tconst originSnapped = vectorApply(originMapped, snapToPixel);\n\t\t\t\t\tinteractionOrigin = vectorClone(origin);\n\n\t\t\t\t\t// add to markup so it's drawn\n\t\t\t\t\taddShapeDraft(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...shapeDefault,\n\t\t\t\t\t\t\tx1: isRelative\n\t\t\t\t\t\t\t? toPercentage(originSnapped.x, parentRect.width)\n\t\t\t\t\t\t\t: originSnapped.x,\n\t\t\t\t\t\t\ty1: isRelative\n\t\t\t\t\t\t\t? toPercentage(originSnapped.y, parentRect.height)\n\t\t\t\t\t\t\t: originSnapped.y,\n\t\t\t\t\t\t\tx2: isRelative\n\t\t\t\t\t\t\t? toPercentage(originSnapped.x, parentRect.width)\n\t\t\t\t\t\t\t: originSnapped.x,\n\t\t\t\t\t\t\ty2: isRelative\n\t\t\t\t\t\t\t? toPercentage(originSnapped.y, parentRect.height)\n\t\t\t\t\t\t\t: originSnapped.y,\n\t\t\t\t\t\t\topacity: 0\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcollection\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tupdate: e => {\n\t\t\t\t\t// we only get the draft to test if it's still there (might be removed by undo function)\n\t\t\t\t\tconst draft = getShapeDraft(collection);\n\n\t\t\t\t\tif (!draft) return;\n\t\t\t\t\tconst { translation } = e.detail;\n\t\t\t\t\tconst interactionTarget = snapPoint(vectorAdd(vectorClone(interactionOrigin), translation));\n\n\t\t\t\t\t// shift pressed\n\t\t\t\t\tif ($keysPressedStored.includes(16)) {\n\t\t\t\t\t\tconst length = vectorDistance(interactionOrigin, interactionTarget);\n\t\t\t\t\t\tconst angle = vectorAngleBetween(interactionOrigin, interactionTarget);\n\t\t\t\t\t\tconst angleSnapInterval = Math.PI / 4;\n\t\t\t\t\t\tconst angleSnapped = angleSnapInterval * Math.round(angle / angleSnapInterval);\n\t\t\t\t\t\tinteractionTarget.x = interactionOrigin.x + length * Math.cos(angleSnapped);\n\t\t\t\t\t\tinteractionTarget.y = interactionOrigin.y + length * Math.sin(angleSnapped);\n\t\t\t\t\t}\n\n\t\t\t\t\t// update line end position\n\t\t\t\t\tconst point = mapEditorPointToImagePoint(interactionTarget);\n\n\t\t\t\t\tupdateShapeDraft(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tx2: isRelative\n\t\t\t\t\t\t\t? toPercentage(point.x, parentRect.width)\n\t\t\t\t\t\t\t: point.x,\n\t\t\t\t\t\t\ty2: isRelative\n\t\t\t\t\t\t\t? toPercentage(point.y, parentRect.height)\n\t\t\t\t\t\t\t: point.y,\n\t\t\t\t\t\t\topacity: 1\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcollection\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\trelease: e => e.detail.preventInertia(),\n\t\t\t\tcancel: () => {\n\t\t\t\t\tdiscardShapeDraft(collection);\n\t\t\t\t},\n\t\t\t\tend: e => {\n\t\t\t\t\tconst draft = getShapeDraft(collection);\n\t\t\t\t\tif (!draft) return;\n\t\t\t\t\tif (e.detail.isTap) return discardShapeDraft(collection);\n\t\t\t\t\tdraft.opacity = 1;\n\n\t\t\t\t\t// finish markup\n\t\t\t\t\tconst shape = confirmShapeDraft(collection);\n\n\t\t\t\t\tonaddshape(shape);\n\n\t\t\t\t\t// select the draft\n\t\t\t\t\tshapeCanSelect(draft) && selectShape(shape);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n\n\tconst eraseShape = () => {\n\t\tlet origin;\n\t\tlet positionPrevious;\n\t\tconst eraseRadiusSquared = eraseRadius * eraseRadius;\n\n\t\tconst erase = (positionA, positionB, forceErase = false) => {\n\t\t\tconst d2 = vectorDistanceSquared(positionA, positionB);\n\n\t\t\t// skip, too close to previous point\n\t\t\tif (!forceErase && d2 < 2) return false;\n\n\t\t\t// find shapes that can be erased\n\t\t\tconst shapesThatCanBeErased = $shapes.filter(shapeCanErase);\n\n\t\t\t// if line is shorter than radius do simple erase operation, find all points within range from current position\n\t\t\tlet shapesFound;\n\n\t\t\tif (d2 < eraseRadiusSquared) {\n\t\t\t\tshapesFound = getShapesNearPosition(shapesThatCanBeErased, mapEditorPointToImagePoint(positionB), eraseRadius);\n\t\t\t} else {\n\t\t\t\tshapesFound = getShapesBetweenPoints(shapesThatCanBeErased, mapEditorPointToImagePoint(positionA), mapEditorPointToImagePoint(positionB), eraseRadius);\n\t\t\t}\n\n\t\t\tconst shapesRemoved = removeMarkupItems(shapesFound);\n\t\t\tshapesRemoved.forEach(onremoveshape);\n\t\t\treturn true;\n\t\t};\n\n\t\treturn {\n\t\t\tstart: e => {\n\t\t\t\torigin = vectorCreate(Math.round(e.detail.origin.x), Math.round(e.detail.origin.y));\n\t\t\t\terase(origin, origin, true);\n\t\t\t\tpositionPrevious = origin;\n\t\t\t},\n\t\t\tupdate: e => {\n\t\t\t\tconst { translation } = e.detail;\n\t\t\t\tconst positionCurrent = vectorCreate(Math.round(origin.x + translation.x), Math.round(origin.y + translation.y));\n\n\t\t\t\tif (erase(positionPrevious, positionCurrent)) {\n\t\t\t\t\tpositionPrevious = vectorClone(positionCurrent);\n\t\t\t\t}\n\t\t\t},\n\t\t\trelease: e => e.detail.preventInertia(),\n\t\t\tcancel: () => {\n\t\t\t\tdiscardShapeDraft(collection);\n\t\t\t},\n\t\t\tend: () => {\n\t\t\t\t\n\t\t\t}\n\t\t};\n\t};\n\n\t//#endregion\n\t//\n\t// Mapping coordinates\n\t//\n\tconst getImagePointWithScreenTranslation = (point, translation) => {\n\t\tconst pointInScreenSpace = mapImagePointToEditorPoint(point);\n\t\treturn mapEditorPointToImagePoint(vectorAdd(pointInScreenSpace, translation));\n\t};\n\n\tconst getNumberSequence = (interval, min, max) => {\n\t\tconst length = (max - min) / interval + 1;\n\t\treturn Array.from({ length }, (_, i) => min + i * interval);\n\t};\n\n\tconst getShapeSnapLines = shape => {\n\t\tlet linesX = [];\n\t\tlet linesY = [];\n\n\t\t// Handle line as points\n\t\tlet points = shape.points;\n\n\t\tif (shape.x1 !== undefined) {\n\t\t\tpoints = [{ x: shape.x1, y: shape.y1 }, { x: shape.x2, y: shape.y2 }];\n\t\t}\n\n\t\t// Path \u2192 start & end + bounds + center\n\t\tif (points) {\n\t\t\tconst mappedPoints = points.map(mapImagePointToEditorPoint);\n\t\t\tconst rect = rectCreateFromPoints(mappedPoints);\n\t\t\tconst firstPoint = mappedPoints[0];\n\t\t\tconst lastPoint = mappedPoints[mappedPoints.length - 1];\n\n\t\t\tlinesX = [\n\t\t\t\trect.x,\n\t\t\t\trect.x + rect.width * 0.5,\n\t\t\t\trect.x + rect.width,\n\t\t\t\tfirstPoint.x,\n\t\t\t\tlastPoint.x\n\t\t\t];\n\n\t\t\tlinesY = [\n\t\t\t\trect.y,\n\t\t\t\trect.y + rect.height * 0.5,\n\t\t\t\trect.y + rect.height,\n\t\t\t\tfirstPoint.y,\n\t\t\t\tlastPoint.y\n\t\t\t];\n\t\t} else //  Rect \u2192 bounds + center\n\t\tif (shape.text || shape.width !== undefined || shape.rx !== undefined) {\n\t\t\t// make sure is rect\n\t\t\tlet rect;\n\n\t\t\tif (shape.text && shape.height === undefined) {\n\t\t\t\t// calculate rect\n\t\t\t\tconst size = textToSize(shape.text, shape);\n\n\t\t\t\trect = rectCreate(shape.x, shape.y, size.width, size.height);\n\t\t\t} else {\n\t\t\t\t// ellipse and rectangle\n\t\t\t\trect = shape.width !== undefined\n\t\t\t\t? rectCreateFromAny(shape)\n\t\t\t\t: rectCreateFromAny({\n\t\t\t\t\t\tx: shape.x - shape.rx,\n\t\t\t\t\t\ty: shape.y - shape.ry,\n\t\t\t\t\t\twidth: shape.rx * 2,\n\t\t\t\t\t\theight: shape.ry * 2\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst rectAlignedCorners = rectGetCorners(rect).map(mapImagePointToEditorPoint);\n\n\t\t\tconst rectRotatedCorners = Math.abs(shape.rotation) > 0\n\t\t\t? rectRotate(rect, shape.rotation).map(mapImagePointToEditorPoint)\n\t\t\t: rectAlignedCorners;\n\n\t\t\tconst rectBounds = rectCreateFromPoints(rectRotatedCorners);\n\t\t\tconst center = rectCenter(rectBounds);\n\t\t\tconst width = rectBounds.width;\n\t\t\tconst height = rectBounds.height;\n\t\t\tconst cw = width * 0.5;\n\t\t\tconst ch = height * 0.5;\n\t\t\tlinesX = [center.x - cw, center.x, center.x + cw];\n\t\t\tlinesY = [center.y - ch, center.y, center.y + ch];\n\t\t} else // Just a point\n\t\tif (shape.x !== undefined) {\n\t\t\tconst point = mapImagePointToEditorPoint(shape);\n\t\t\tlinesX = [point.x];\n\t\t\tlinesY = [point.y];\n\t\t}\n\n\t\treturn { x: linesX, y: linesY };\n\t};\n\n\tconst getSnapTarget = (originLines, targetLines, snapThreshold) => {\n\t\tlet dist;\n\t\tlet previousSnapDist = Number.Infinity;\n\t\tlet origin = null;\n\t\tlet target = null;\n\t\tlet a, b;\n\n\t\tfor (let i = 0; i < originLines.length; i++) {\n\t\t\ta = originLines[i];\n\n\t\t\tfor (let j = 0; j < targetLines.length; j++) {\n\t\t\t\tb = targetLines[j];\n\t\t\t\tdist = Math.abs(a - b);\n\n\t\t\t\tif (dist < snapThreshold && (target === null || dist < previousSnapDist)) {\n\t\t\t\t\tpreviousSnapDist = dist;\n\t\t\t\t\torigin = a;\n\t\t\t\t\ttarget = b;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { origin, target };\n\t};\n\n\tconst snapToShape = (originSnapLines, targetSnapLines, snapThreshold) => {\n\t\tconst snapLine = { x: null, y: null };\n\t\tconst snapTranslation = { x: null, y: null };\n\t\tconst snapX = getSnapTarget(originSnapLines.x, targetSnapLines.x, snapThreshold);\n\n\t\tif (snapX.target !== null) {\n\t\t\tsnapLine.x = snapX.target;\n\t\t\tsnapTranslation.x = snapX.target - snapX.origin;\n\t\t}\n\n\t\tconst snapY = getSnapTarget(originSnapLines.y, targetSnapLines.y, snapThreshold);\n\n\t\tif (snapY.target !== null) {\n\t\t\tsnapLine.y = snapY.target;\n\t\t\tsnapTranslation.y = snapY.target - snapY.origin;\n\t\t}\n\n\t\treturn { snapTranslation, snapLine };\n\t};\n\n\tconst snapLinesToTargets = (snapLines, snapTargets, snapThreshold, gridSize, gridRect) => {\n\t\tconst lines = { x: null, y: null };\n\t\tconst translation = { x: null, y: null };\n\n\t\t// create snap lines\n\t\tconst targetSnapLines = snapTargets.map(getShapeSnapLines);\n\n\t\t// add grid snapping\n\t\tif (gridSize > 0) {\n\t\t\tconst editorPointA = mapImagePointToEditorPoint({ x: 0, y: 0 });\n\t\t\tconst editorPointB = mapImagePointToEditorPoint({ x: gridSize, y: gridSize });\n\t\t\tconst editorPointC = mapImagePointToEditorPoint({ x: gridRect.width, y: gridRect.height });\n\t\t\tconst projectedSize = editorPointB.x - editorPointA.x;\n\t\t\tconst linesX = getNumberSequence(projectedSize, editorPointA.x, editorPointC.x);\n\t\t\tconst linesY = getNumberSequence(projectedSize, editorPointA.y, editorPointC.y);\n\t\t\ttargetSnapLines.push({ x: linesX, y: linesY });\n\t\t}\n\n\t\t// snap to targets\n\t\ttargetSnapLines.forEach(targetSnapLines => {\n\t\t\t// get snap results\n\t\t\tconst { snapTranslation, snapLine } = snapToShape(snapLines, targetSnapLines, snapThreshold);\n\n\t\t\t// determine if results are better than previous snap results\n\t\t\tif (snapTranslation.x !== null && (translation.x === null || Math.abs(snapTranslation.x) < Math.abs(translation.x))) {\n\t\t\t\ttranslation.x = snapTranslation.x || 0;\n\t\t\t\tlines.x = snapLine.x;\n\t\t\t}\n\n\t\t\tif (snapTranslation.y !== null && (translation.y === null || Math.abs(snapTranslation.y) < Math.abs(translation.y))) {\n\t\t\t\ttranslation.y = snapTranslation.y || 0;\n\t\t\t\tlines.y = snapLine.y;\n\t\t\t}\n\t\t});\n\n\t\treturn {\n\t\t\tsnapTranslation: translation,\n\t\t\tsnapLines: lines\n\t\t};\n\t};\n\n\tconst updateWithSnapTranslation = (vector, translation) => {\n\t\tif (translation.x !== null) vector.x += translation.x;\n\t\tif (translation.y !== null) vector.y += translation.y;\n\t\treturn vector;\n\t};\n\n\t//\n\t// Interaction\n\t//\n\t//#region translateShape rotateShape resizeShape\n\tconst translateShape = (shapeCurrent, shapeOriginComputed, translation, options) => {\n\t\t// get snap info\n\t\tconst { snapThreshold = 0, gridSize = 0, gridRect, snapTargets = [] } = options || {};\n\n\t\t// will hold props we will update in target shape\n\t\tlet propsToUpdate = null;\n\n\t\t// if is line\n\t\tif (shapeIsLine(shapeCurrent)) {\n\t\t\tif (snapThreshold) {\n\t\t\t\tconst shapeComputed = shapeComputeDisplay({ ...shapeCurrent }, parentRect);\n\t\t\t\tconst beginImageOffset = getImagePointWithScreenTranslation(shapeLineGetStartPoint(shapeOriginComputed), translation);\n\t\t\t\tconst endImageOffset = getImagePointWithScreenTranslation(shapeLineGetEndPoint(shapeOriginComputed), translation);\n\n\t\t\t\tconst shapeSnapLines = getShapeSnapLines({\n\t\t\t\t\t...shapeComputed,\n\t\t\t\t\tx1: beginImageOffset.x,\n\t\t\t\t\ty1: beginImageOffset.y,\n\t\t\t\t\tx2: endImageOffset.x,\n\t\t\t\t\ty2: endImageOffset.y\n\t\t\t\t});\n\n\t\t\t\tconst { snapTranslation, snapLines } = snapLinesToTargets(shapeSnapLines, snapTargets, snapThreshold, gridSize, gridRect);\n\t\t\t\tupdateWithSnapTranslation(translation, snapTranslation);\n\t\t\t\tsetInteractionSnapLines(snapLines);\n\t\t\t}\n\n\t\t\tconst beginImageOffset = getImagePointWithScreenTranslation(shapeLineGetStartPoint(shapeOriginComputed), translation);\n\t\t\tconst endImageOffset = getImagePointWithScreenTranslation(shapeLineGetEndPoint(shapeOriginComputed), translation);\n\n\t\t\t// move shape\n\t\t\tpropsToUpdate = {\n\t\t\t\tx1: beginImageOffset.x,\n\t\t\t\ty1: beginImageOffset.y,\n\t\t\t\tx2: endImageOffset.x,\n\t\t\t\ty2: endImageOffset.y\n\t\t\t};\n\t\t} else if (shapeCurrent.points) {\n\t\t\t// deselect on move\n\t\t\tif (shapeCanSelectPoint(interactionShape)) {\n\t\t\t\tupdateMarkupShape(interactionShape, { selectedPoint: undefined });\n\t\t\t}\n\n\t\t\t// snap it!\n\t\t\tif (snapThreshold) {\n\t\t\t\tconst shapeComputed = shapeComputeDisplay({ ...shapeCurrent }, parentRect);\n\n\t\t\t\tconst shapeSnapLines = getShapeSnapLines({\n\t\t\t\t\t...shapeComputed,\n\t\t\t\t\tpoints: shapeOriginComputed.points.map(point => getImagePointWithScreenTranslation(point, translation))\n\t\t\t\t});\n\n\t\t\t\tconst { snapTranslation, snapLines } = snapLinesToTargets(shapeSnapLines, snapTargets, snapThreshold, gridSize, gridRect);\n\t\t\t\tupdateWithSnapTranslation(translation, snapTranslation);\n\t\t\t\tsetInteractionSnapLines(snapLines);\n\t\t\t}\n\n\t\t\tpropsToUpdate = {\n\t\t\t\tpoints: shapeOriginComputed.points.map(point => getImagePointWithScreenTranslation(point, translation))\n\t\t\t};\n\t\t} else if (shapeIsRect(shapeCurrent) || shapeIsText(shapeCurrent) || shapeIsEllipse(shapeCurrent)) {\n\t\t\tif (snapThreshold) {\n\t\t\t\tconst shapeComputed = shapeComputeDisplay({ ...shapeCurrent }, parentRect);\n\t\t\t\tconst shapeTranslatedPosition = getImagePointWithScreenTranslation(shapeOriginComputed, translation);\n\n\t\t\t\tconst shapeSnapLines = getShapeSnapLines({\n\t\t\t\t\t...shapeComputed,\n\t\t\t\t\t...shapeTranslatedPosition\n\t\t\t\t});\n\n\t\t\t\tconst { snapTranslation, snapLines } = snapLinesToTargets(shapeSnapLines, snapTargets, snapThreshold, gridSize, gridRect);\n\t\t\t\tupdateWithSnapTranslation(translation, snapTranslation);\n\t\t\t\tsetInteractionSnapLines(snapLines);\n\t\t\t}\n\n\t\t\tpropsToUpdate = getImagePointWithScreenTranslation(shapeOriginComputed, translation);\n\t\t}\n\n\t\tif (!propsToUpdate) return;\n\t\tupdateShape(shapeCurrent, propsToUpdate, parentRect);\n\t\tsyncShapes();\n\t};\n\n\tconst IndexFlipXMap = { 0: 1, 1: 0, 2: 3, 3: 2 };\n\tconst IndexFlipYMap = { 0: 3, 1: 2, 2: 1, 3: 0 };\n\n\tconst resizeShape = (shapeCurrent, shapeOriginComputed, indexes, translation, options) => {\n\t\tconst { shiftKey, snapThreshold = 0, gridSize = 0, gridRect, snapTargets = [], aspectRatio = undefined, beforeResizeShape = noop$1 } = options || {};\n\n\t\t// snap point\n\t\tconst snapPoint = snapThreshold\n\t\t? (point, translation, getPoint) => {\n\t\t\t\tconst { snapTranslation, snapLines } = snapLinesToTargets(getShapeSnapLines(point), snapTargets, snapThreshold, gridSize, gridRect);\n\t\t\t\tupdateWithSnapTranslation(translation, snapTranslation);\n\t\t\t\tsetInteractionSnapLines(snapLines);\n\t\t\t\tconst snappedPoint = getImagePointWithScreenTranslation(getPoint(), translation);\n\t\t\t\tpoint.x = snappedPoint.x;\n\t\t\t\tpoint.y = snappedPoint.y;\n\t\t\t}\n\t\t: noop$1;\n\n\t\t// is a line of points\n\t\tif (shapeIsLine(shapeCurrent) || shapeIsPath(shapeCurrent) && hasProp(shapeCurrent, 'pathClose')) {\n\t\t\tconst [targetIndex] = indexes;\n\n\t\t\t// shift pressed\n\t\t\tconst anchor = shiftKey\n\t\t\t? positionRelativeToAnchor\n\t\t\t: (_, target) => target;\n\n\t\t\tlet getPoint;\n\t\t\tlet anchorPoint;\n\t\t\tlet setPoint;\n\n\t\t\tif (shapeIsLine(shapeCurrent)) {\n\t\t\t\t// start\n\t\t\t\tif (targetIndex === 0) {\n\t\t\t\t\tgetPoint = () => shapeLineGetStartPoint(shapeOriginComputed);\n\n\t\t\t\t\t// snap angle relative to opposite point\n\t\t\t\t\tanchorPoint = point => anchor(shapeLineGetEndPoint(shapeOriginComputed), point);\n\n\t\t\t\t\tsetPoint = (shape, point) => {\n\t\t\t\t\t\tupdateShape(shape, { x1: point.x, y1: point.y }, parentRect);\n\t\t\t\t\t};\n\t\t\t\t} else // end\n\t\t\t\tif (targetIndex === 1) {\n\t\t\t\t\tgetPoint = () => shapeLineGetEndPoint(shapeOriginComputed);\n\n\t\t\t\t\t// snap angle relative to opposite point\n\t\t\t\t\tanchorPoint = point => anchor(shapeLineGetStartPoint(shapeOriginComputed), point);\n\n\t\t\t\t\tsetPoint = (shape, point) => {\n\t\t\t\t\t\tupdateShape(shape, { x2: point.x, y2: point.y }, parentRect);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst computedPoints = shapeOriginComputed.points;\n\t\t\t\tgetPoint = () => ({ ...computedPoints[targetIndex] });\n\n\t\t\t\tanchorPoint = point => {\n\t\t\t\t\tconst pointBefore = computedPoints[arrayIndexWrap(targetIndex - 1, computedPoints)];\n\t\t\t\t\tconst pointAfter = computedPoints[arrayIndexWrap(targetIndex + 1, computedPoints)];\n\t\t\t\t\tanchor(pointBefore, point);\n\t\t\t\t\tanchor(pointAfter, point);\n\t\t\t\t};\n\n\t\t\t\tsetPoint = (shape, point) => {\n\t\t\t\t\tupdateShape(\n\t\t\t\t\t\tshape,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpoints: shape.points.map((p, index) => {\n\t\t\t\t\t\t\t\tif (targetIndex === index) return point;\n\t\t\t\t\t\t\t\treturn p;\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t\tparentRect\n\t\t\t\t\t);\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst point = getImagePointWithScreenTranslation(getPoint(), translation);\n\t\t\tsnapPoint(point, translation, getPoint);\n\t\t\tanchorPoint(point);\n\t\t\tsetPoint(shapeCurrent, point);\n\t\t} else // is a box\n\t\tif (shapeHasSize(shapeCurrent) || shapeIsEllipse(shapeCurrent) || // shapeIsTextBox(shapeCurrent) ||\n\t\tshapeIsText(shapeCurrent)) {\n\t\t\tlet hasAutoHeight = false;\n\t\t\tlet hasAutoWidthAndHeight = false;\n\t\t\tlet shapeOriginRect;\n\n\t\t\tif (shapeIsEllipse(shapeOriginComputed)) {\n\t\t\t\tshapeOriginRect = rectCreateFromEllipse(shapeOriginComputed);\n\t\t\t} else if (shapeHasSize(shapeOriginComputed)) {\n\t\t\t\tshapeOriginRect = rectCreateFromAny(shapeOriginComputed);\n\t\t\t} else if (hasProp(shapeOriginComputed, 'width')) {\n\t\t\t\t// is text with 'width' only\n\t\t\t\thasAutoHeight = true;\n\n\t\t\t\tshapeOriginRect = rectCreateFromAny(shapeOriginComputed);\n\t\t\t\tconst size = textToSize(shapeOriginComputed.text, shapeOriginComputed);\n\t\t\t\tshapeOriginRect.height = size.height;\n\t\t\t} else {\n\t\t\t\t// is text with no width and height set\n\t\t\t\thasAutoWidthAndHeight = true;\n\n\t\t\t\tshapeOriginRect = rectCreateFromAny(shapeOriginComputed);\n\t\t\t\tconst size = textToSize(shapeOriginComputed.text, shapeOriginComputed);\n\t\t\t\tshapeOriginRect.width = size.width;\n\t\t\t\tshapeOriginRect.height = size.height;\n\t\t\t}\n\n\t\t\tlet shapeAspectRatio = aspectRatio;\n\n\t\t\tif (shapeCurrent.aspectRatio) {\n\t\t\t\tshapeAspectRatio = shapeCurrent.aspectRatio;\n\t\t\t} else if (options.shiftKey && !(hasAutoHeight || hasAutoWidthAndHeight)) {\n\t\t\t\tshapeAspectRatio = shapeOriginRect.width / shapeOriginRect.height;\n\t\t\t}\n\n\t\t\t// current shape\n\t\t\tconst rectAligned = rectCreateFromAny(shapeOriginRect);\n\n\t\t\tconst rectAlignedCenterPosition = rectCenter(rectAligned);\n\t\t\tconst rectRotation = shapeCurrent.rotation;\n\t\t\tconst rectAlignedCorners = rectGetCorners(rectAligned);\n\t\t\tconst rectCorners = rectRotate(rectAligned, rectRotation);\n\n\t\t\t// is translating one corner\n\t\t\tif (indexes.length === 1) {\n\t\t\t\t// corner\n\t\t\t\tlet cornerIndex = indexes[0];\n\n\t\t\t\tif (shapeCurrent.flipX) cornerIndex = IndexFlipXMap[cornerIndex];\n\t\t\t\tif (shapeCurrent.flipY) cornerIndex = IndexFlipYMap[cornerIndex];\n\t\t\t\tconst [tl, tr, br, bl] = rectAlignedCorners;\n\t\t\t\tconst screenCornerPosition = mapImagePointToEditorPoint(rectCorners[cornerIndex]);\n\t\t\t\tconst screenTargetPosition = vectorAdd({ ...screenCornerPosition }, translation);\n\t\t\t\tconst imageTargetPosition = mapEditorPointToImagePoint(screenTargetPosition);\n\t\t\t\tsnapPoint(imageTargetPosition, translation, () => mapEditorPointToImagePoint(screenCornerPosition));\n\t\t\t\tconst imageTargetTranslation = vectorCreate(imageTargetPosition.x - rectCorners[cornerIndex].x, imageTargetPosition.y - rectCorners[cornerIndex].y);\n\t\t\t\tconst imageTargetTranslationAligned = vectorRotate(vectorClone(imageTargetTranslation), -rectRotation);\n\t\t\t\tconst imageTargetPositionAligned = vectorCreate(rectAlignedCorners[cornerIndex].x + imageTargetTranslationAligned.x, rectAlignedCorners[cornerIndex].y + imageTargetTranslationAligned.y);\n\t\t\t\tlet anchor;\n\t\t\t\tif (cornerIndex === 0) anchor = br;\n\t\t\t\tif (cornerIndex === 1) anchor = bl;\n\t\t\t\tif (cornerIndex === 2) anchor = tl;\n\t\t\t\tif (cornerIndex === 3) anchor = tr;\n\n\t\t\t\t// create an aligned and updated rectangle\n\t\t\t\tconst rectAlignedResized = rectCreateFromPoints([anchor, imageTargetPositionAligned]);\n\n\t\t\t\t// limit rect\n\t\t\t\tif (shapeAspectRatio) {\n\t\t\t\t\t// get size that adheres to aspect ratio but still fits current rectangle\n\t\t\t\t\tconst { width, height } = rectContainRect(rectAlignedResized, shapeAspectRatio);\n\n\t\t\t\t\tconst [t, r, b, l] = rectToBounds(rectAlignedResized);\n\n\t\t\t\t\t// update size\n\t\t\t\t\trectAlignedResized.width = width;\n\n\t\t\t\t\trectAlignedResized.height = height;\n\n\t\t\t\t\t// align to anchor\n\t\t\t\t\tif (imageTargetPositionAligned.y < anchor.y) {\n\t\t\t\t\t\trectAlignedResized.y = b - height;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (imageTargetPositionAligned.x < anchor.x) {\n\t\t\t\t\t\trectAlignedResized.x = r - width;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// rotate the aligned rectangle around it's original pivot point\n\t\t\t\tconst rr = rectRotate(rectAlignedResized, rectRotation, rectAlignedCenterPosition);\n\n\t\t\t\t// now calculate the new center and then rotate the tl and br corners around that center to find their new positions\n\t\t\t\tconst rrc = vectorCenter(rr);\n\n\t\t\t\tconst p1 = vectorRotate(rr[0], -rectRotation, rrc);\n\t\t\t\tconst p2 = vectorRotate(rr[2], -rectRotation, rrc);\n\t\t\t\tconst rectUpdated = rectCreateFromPoints([p1, p2]);\n\t\t\t\tbeforeResizeShape(rectUpdated);\n\n\t\t\t\tupdateShape(\n\t\t\t\t\tshapeCurrent,\n\t\t\t\t\tshapeIsEllipse(shapeCurrent)\n\t\t\t\t\t? ellipseCreateFromRect(rectUpdated)\n\t\t\t\t\t: rectUpdated,\n\t\t\t\t\tparentRect\n\t\t\t\t);\n\t\t\t} else // is translating two corner points\n\t\t\t{\n\t\t\t\t// 0-1 -> 2-3\n\t\t\t\t// 1-2 -> 3-0\n\t\t\t\t// 2-3 -> 0-1\n\t\t\t\t// 3-0 -> 1-2\n\t\t\t\tindexes = indexes.map(index => {\n\t\t\t\t\tif (shapeCurrent.flipX) index = IndexFlipXMap[index];\n\t\t\t\t\tif (shapeCurrent.flipY) index = IndexFlipYMap[index];\n\t\t\t\t\treturn index;\n\t\t\t\t});\n\n\t\t\t\tconst [cornerA, cornerB] = indexes.map(index => rectCorners[index]);\n\n\t\t\t\tconst mid = {\n\t\t\t\t\tx: cornerA.x + (cornerB.x - cornerA.x) * 0.5,\n\t\t\t\t\ty: cornerA.y + (cornerB.y - cornerA.y) * 0.5\n\t\t\t\t};\n\n\t\t\t\tconst [cornerAlignedA, cornerAlignedB] = indexes.map(index => rectAlignedCorners[index]);\n\n\t\t\t\tconst [cornerAlignedC, cornerAlignedD] = indexes.map(index => {\n\t\t\t\t\tconst mappedIndex = index + 2;\n\t\t\t\t\tif (mappedIndex < 4) return rectAlignedCorners[mappedIndex];\n\t\t\t\t\treturn rectAlignedCorners[mappedIndex - 4];\n\t\t\t\t});\n\n\t\t\t\t// const midAligned = {\n\t\t\t\t//     x: cornerAlignedA.x + (cornerAlignedB.x - cornerAlignedA.x) * .5,\n\t\t\t\t//     y: cornerAlignedA.y + (cornerAlignedB.y - cornerAlignedA.y) * .5\n\t\t\t\t// };\n\t\t\t\tconst midAnchorAligned = {\n\t\t\t\t\tx: cornerAlignedC.x + (cornerAlignedD.x - cornerAlignedC.x) * 0.5,\n\t\t\t\t\ty: cornerAlignedC.y + (cornerAlignedD.y - cornerAlignedC.y) * 0.5\n\t\t\t\t};\n\n\t\t\t\tconst screenMidPosition = mapImagePointToEditorPoint(mid);\n\t\t\t\tconst screenTargetPosition = vectorAdd({ ...screenMidPosition }, translation);\n\t\t\t\tconst imageTargetPosition = mapEditorPointToImagePoint(screenTargetPosition);\n\t\t\t\tsnapPoint(imageTargetPosition, translation, () => mapEditorPointToImagePoint(screenMidPosition));\n\t\t\t\tconst imageTargetTranslation = vectorCreate(imageTargetPosition.x - mid.x, imageTargetPosition.y - mid.y);\n\t\t\t\tconst imageTargetTranslationAligned = vectorRotate(vectorClone(imageTargetTranslation), -rectRotation);\n\t\t\t\tconst d = vectorSubtract(vectorClone(cornerAlignedA), cornerAlignedB);\n\t\t\t\tconst f = vectorApply(d, v => 1 - Math.abs(Math.sign(v)));\n\t\t\t\tconst t = vectorCreate(imageTargetTranslationAligned.x * f.x, imageTargetTranslationAligned.y * f.y);\n\t\t\t\tvectorAdd(cornerAlignedA, t);\n\t\t\t\tvectorAdd(cornerAlignedB, t);\n\t\t\t\tconst rectAlignedResized = rectCreateFromPoints(rectAlignedCorners);\n\n\t\t\t\t// limit rect\n\t\t\t\tif (shapeAspectRatio) {\n\t\t\t\t\tlet width = rectAlignedResized.width;\n\t\t\t\t\tlet height = rectAlignedResized.height;\n\n\t\t\t\t\tif (f.y === 0) {\n\t\t\t\t\t\theight = width / shapeAspectRatio;\n\t\t\t\t\t} else {\n\t\t\t\t\t\twidth = height * shapeAspectRatio;\n\t\t\t\t\t}\n\n\t\t\t\t\t// update size\n\t\t\t\t\trectAlignedResized.width = width;\n\n\t\t\t\t\trectAlignedResized.height = height;\n\n\t\t\t\t\t// align to anchor\n\t\t\t\t\tif (f.y === 0) {\n\t\t\t\t\t\trectAlignedResized.y = midAnchorAligned.y - height * 0.5;\n\t\t\t\t\t} else {\n\t\t\t\t\t\trectAlignedResized.x = midAnchorAligned.x - width * 0.5;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// rotate the aligned rectangle around it's original pivot point\n\t\t\t\tconst rr = rectRotate(rectAlignedResized, rectRotation, rectAlignedCenterPosition);\n\n\t\t\t\t// now calculate the new center and then rotate the tl and br corners around that center to find their new positions\n\t\t\t\tconst rrc = vectorCenter(rr);\n\n\t\t\t\tconst p1 = vectorRotate(rr[0], -rectRotation, rrc);\n\t\t\t\tconst p2 = vectorRotate(rr[2], -rectRotation, rrc);\n\t\t\t\tconst rectUpdated = rectCreateFromPoints([p1, p2]);\n\t\t\t\tlet props;\n\n\t\t\t\tif (shapeIsEllipse(shapeCurrent)) {\n\t\t\t\t\tprops = ellipseCreateFromRect(rectUpdated);\n\t\t\t\t} else if (shapeHasSize(shapeCurrent)) {\n\t\t\t\t\tprops = rectUpdated;\n\t\t\t\t} else if (hasAutoHeight) {\n\t\t\t\t\tprops = {\n\t\t\t\t\t\tx: rectUpdated.x,\n\t\t\t\t\t\ty: rectUpdated.y,\n\t\t\t\t\t\twidth: rectUpdated.width\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tupdateShape(shapeCurrent, props, parentRect);\n\t\t\t}\n\t\t}\n\n\t\t// redraw\n\t\tsyncShapes();\n\t};\n\n\tlet rotatorInitialPosition;\n\n\tconst rotateShape = (shapeCurrent, shapeOriginComputed, translation, options) => {\n\t\t// calculate angle between translated rotation control and origin\n\t\tconst shapeRect = getMarkupShapeRect(shapeComputeDisplay(shapeDeepCopy(shapeCurrent), parentRect));\n\n\t\tconst shapeCenter = rectCenter(shapeRect);\n\t\tconst p = getImagePointWithScreenTranslation(rotatorInitialPosition, translation);\n\t\tlet shapeRotation = vectorAngleBetween(p, shapeCenter) + Math.PI / 2;\n\n\t\tif (options.shiftKey) {\n\t\t\tconst rotatorSnapInterval = Math.PI / 16;\n\t\t\tshapeRotation = rotatorSnapInterval * Math.round(shapeRotation / rotatorSnapInterval) - contextRotation % rotatorSnapInterval;\n\t\t}\n\n\t\tupdateShape(shapeCurrent, { rotation: shapeRotation }, parentRect);\n\t\tsyncShapes();\n\t};\n\n\tconst scaleShape = (shapeCurrent, shapeOriginComputed, translation, options) => {\n\t\t// calculate current size\n\t\tconst shapeOriginRect = rectCreateFromAny(shapeOriginComputed);\n\n\t\tconst textSize = textToSize(shapeOriginComputed.text, shapeOriginComputed);\n\t\tif (!shapeOriginRect.width) shapeOriginRect.width = textSize.width;\n\t\tif (!shapeOriginRect.height) shapeOriginRect.height = textSize.height;\n\n\t\t// get corner index\n\t\tlet index = 2;\n\n\t\tif (shapeCurrent.flipX && shapeCurrent.flipY) {\n\t\t\tindex = 0;\n\t\t} else if (shapeCurrent.flipX) {\n\t\t\tindex = 3;\n\t\t} else if (shapeCurrent.flipY) {\n\t\t\tindex = 1;\n\t\t}\n\n\t\t// resize from bottom right corner\n\t\tresizeShape(shapeCurrent, shapeOriginComputed, [index], translation, {\n\t\t\t// pass base options\n\t\t\t...options,\n\t\t\t// we fix the aspect ratio\n\t\t\taspectRatio: shapeOriginRect.width / shapeOriginRect.height,\n\t\t\t// before we update the shape we scale the text\n\t\t\tbeforeResizeShape: shape => {\n\t\t\t\tconst scalar = shape.width / shapeOriginRect.width;\n\t\t\t\tshape.fontSize = shapeOriginComputed.fontSize * scalar;\n\t\t\t\tif (!shapeOriginComputed.width) delete shape.width;\n\t\t\t\tif (!shapeOriginComputed.height) delete shape.height;\n\t\t\t}\n\t\t});\n\t};\n\n\t//#endregion\n\tconst addPointToPath = (shape, point) => {\n\t\t// poly to edges\n\t\tconst points = shape.points;\n\n\t\tconst edges = [];\n\n\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\tedges.push([points[i], points[i + 1]]);\n\t\t}\n\n\t\tedges.push([points[points.length - 1], points[0]]);\n\n\t\t// find edge closest to position\n\t\tconst closestEdgeIndex = edges.findIndex(([from, to]) => {\n\t\t\treturn circleOverlapsWithLine(point, 6, from, to);\n\t\t});\n\n\t\t// insert point\n\t\tlet selectedPoint;\n\n\t\tconst newPoints = [];\n\n\t\tfor (let i = 0; i < edges.length; i++) {\n\t\t\tnewPoints.push(edges[i][0]);\n\n\t\t\tif (i === closestEdgeIndex) {\n\t\t\t\tselectedPoint = i + 1;\n\t\t\t\tnewPoints.push(point);\n\t\t\t}\n\t\t}\n\n\t\t// redraw shape\n\t\tupdateShape(shape, { points: newPoints, selectedPoint }, parentRect);\n\n\t\tsyncShapes();\n\t};\n\n\tconst removePointFromPath = (shape, pointIndex) => {\n\t\tconst newPoints = shape.points.filter((shape, index) => index !== pointIndex);\n\n\t\t// redraw shape\n\t\tupdateShape(\n\t\t\tshape,\n\t\t\t{\n\t\t\t\tpoints: newPoints,\n\t\t\t\tselectedPoint: undefined\n\t\t\t},\n\t\t\tparentRect\n\t\t);\n\n\t\tsyncShapes();\n\t};\n\n\tconst getSelectionItemDraft = () => {\n\t\tif (!$selection.length) return;\n\t\treturn $selection.find(shapeIsDraft);\n\t};\n\n\tconst getSelectionItemDraftIndex = () => {\n\t\tif (!$selection.length) return;\n\t\treturn $selection.findIndex(shapeIsDraft);\n\t};\n\n\tconst discardSelectionItemDraft = () => {\n\t\tif (!getSelectionItemDraft()) return;\n\t\tconst arrayClone = [...$selection];\n\t\tarrayClone.splice(getSelectionItemDraftIndex(), 1);\n\t\tselection.set(arrayClone);\n\t};\n\n\tconst getMarkupItemDraft = () => {\n\t\tif (!$shapes.length) return;\n\t\treturn $shapes.find(shapeIsDraft);\n\t};\n\n\tconst getMarkupItemDraftIndex = () => {\n\t\tif (!$shapes.length) return;\n\t\treturn $shapes.findIndex(shapeIsDraft);\n\t};\n\n\tconst addMarkupItemDraft = shape => {\n\t\tif (getMarkupItemDraft()) return;\n\t\tshapeMakeDraft(shape);\n\t\treturn addShape(shape);\n\t};\n\n\tconst confirmMarkupItemDraft = () => {\n\t\tconst markupItem = getMarkupItemDraft();\n\t\tif (!markupItem) return;\n\t\tshapeMakeFinal(markupItem);\n\t\tsyncShapes();\n\t\treturn markupItem;\n\t};\n\n\tconst discardMarkupItemDraft = () => {\n\t\tif (!getMarkupItemDraft()) return;\n\t\tconst arrayClone = [...$shapes];\n\t\tarrayClone.splice(getMarkupItemDraftIndex(), 1);\n\t\tshapes.set(arrayClone);\n\t};\n\n\tconst createMarkupItem = (props = {}) => ({ id: getUniqueId(), ...props });\n\n\tconst syncShapes = () => {\n\t\tshapes.set($shapes);\n\t};\n\n\tconst removeMarkupShapeProps = (shape, props = [], sync = true) => {\n\t\tprops.filter(Boolean).forEach(prop => delete shape[prop]);\n\n\t\t// sync markup array\n\t\tif (!sync) return;\n\n\t\tsyncShapes();\n\t};\n\n\tconst updateMarkupShape = (shape, props, sync = true) => {\n\t\t// update markup\n\t\tshape = Object.assign(shape, props);\n\n\t\t// sync markup array\n\t\tif (!sync) return;\n\n\t\tsyncShapes();\n\t};\n\n\tconst updateMarkupShapeProperty = (shape, name, value, sync = true) => {\n\t\tshape[name] = value;\n\n\t\t// sync markup array\n\t\tif (!sync) return;\n\n\t\tsyncShapes();\n\t};\n\n\tconst updateMarkupItemsShapeProperty = (name, value, sync = true) => {\n\t\t$shapes.forEach(shape => updateMarkupShapeProperty(shape, name, value, false));\n\n\t\t// sync markup array\n\t\tif (!sync) return;\n\n\t\tsyncShapes();\n\t};\n\n\tconst updateMarkupShapeItems = (props, sync = true) => {\n\t\t$shapes.forEach(markupItem => updateMarkupShape(markupItem, props, false));\n\n\t\t// sync markup array\n\t\tif (!sync) return;\n\n\t\tsyncShapes();\n\t};\n\n\tconst getActiveMarkupItems = () => [...$shapes].reverse().filter(shapeIsSelected);\n\tconst getActiveMarkupItem = () => [...$shapes].reverse().find(shapeIsSelected);\n\tconst hasActiveMarkupItem = () => !!getActiveMarkupItem();\n\n\tconst removeShape = (shapeToRemove, silent = false) => {\n\t\tif (!beforeRemoveShape(shapeToRemove)) return false;\n\t\tshapes.set($shapes.filter(shape => shape !== shapeToRemove));\n\t\tif (!silent) onremoveshape(shapeToRemove);\n\t};\n\n\tconst removeMarkupItem = (shapeToRemove, autoSelectNextShape = true, silent = false) => {\n\t\t// get removable markup items,\n\t\tconst removableShapes = $shapes.filter(shape => shapeCanRemove(shape) && shapeCanSelect(shape));\n\n\t\t// find index of active shape so we can select the next active shape on removal\n\t\tconst index = removableShapes.findIndex(shape => shape === shapeToRemove);\n\n\t\t// remove the active ship from the shape array\n\t\tconst didRemove = removeShape(shapeToRemove, silent);\n\n\t\tif (didRemove === false) return;\n\n\t\t// remember selection\n\t\tpreviousSelectedShape = shapeToRemove;\n\n\t\t// if no more markup items, release active shape\n\t\tif (removableShapes.length - 1 <= 0) return blurShapes();\n\n\t\t// if we shouldn't select the next available shape, bail\n\t\tif (!autoSelectNextShape) return true;\n\n\t\t// select next active markup item\n\t\tconst indexNext = index - 1 < 0 ? removableShapes.length - 1 : index - 1;\n\n\t\tselectShape(removableShapes[indexNext]);\n\n\t\t// did remove shape\n\t\treturn true;\n\t};\n\n\tconst removeActiveMarkupItem = () => {\n\t\t// multiple shapes selected\n\t\tif (isMultiSelection) {\n\t\t\tconst removedShapes = [];\n\n\t\t\tmultiSelection.forEach((shape, index) => {\n\t\t\t\tif (!shapeCanRemove(shape)) return;\n\t\t\t\tconst removed = removeMarkupItem(shape, index === multiSelection.length - 1, true);\n\t\t\t\tif (removed) removedShapes.push(shape);\n\t\t\t});\n\n\t\t\tif (removedShapes.length) ontriggerhistorywrite();\n\t\t\treturn;\n\t\t}\n\n\t\t// single shape selected\n\t\tconst activeShape = getActiveMarkupItem();\n\n\t\tif (!activeShape) return;\n\t\tremoveMarkupItem(activeShape);\n\t};\n\n\tlet previousSelectedShape = undefined;\n\n\tconst blurShapes = (options = {}) => {\n\t\tconst { storePrevious = true } = options;\n\n\t\t// clear text state cache, when a text shape is blurred the changes are confirmed\n\t\tObject.keys(ShapeTextStateCache).forEach(key => ShapeTextStateCache[key] = {});\n\n\t\t// get selected shape\n\t\tconst selectedShape = getSelectedShape();\n\n\t\t// remember shape\n\t\tif (storePrevious) previousSelectedShape = selectedShape;\n\n\t\tupdateMarkupShapeItems({\n\t\t\tisSelected: false,\n\t\t\tisEditing: false,\n\t\t\t_prerender: false\n\t\t});\n\n\t\tselectedShape && onblurshape(selectedShape);\n\t};\n\n\tconst getSelectedShape = () => $shapes.find(shapeIsSelected);\n\n\tconst selectShape = (shape, sync = true, multi = false) => {\n\t\t// can't select draft\n\t\tif (shapeIsDraft(shape)) return;\n\n\t\t// get currently selected shape\n\t\tconst selectedShapeCurrent = getSelectedShape();\n\n\t\tconst selectedShape = selectedShapeCurrent || previousSelectedShape;\n\n\t\t// was already selected\n\t\tconst wasSelectedShape = shapeIsSelected(shape);\n\n\t\t// reset previous selected shape\n\t\tpreviousSelectedShape = undefined;\n\n\t\t// if is returned false will cancel select operation\n\t\tif (!beforeSelectShape(selectedShape, shape)) return;\n\n\t\t// remove selected state from other markup\n\t\tif (!multi) blurShapes();\n\n\t\t// select\n\t\tshapeSelect(shape);\n\n\t\t// selected this shape\n\t\t!wasSelectedShape && onselectshape(shape);\n\n\t\t// sync\n\t\tif (!sync) return;\n\n\t\tsyncShapes();\n\t};\n\n\tconst deselectMarkupItem = markupItem => {\n\t\t// we're blurring an active text field, should confirm state if inline text editing\n\t\tif (textInput && textInput.confirm && markupItem.isEditing) textInput.confirm();\n\n\t\tconst newProps = {\n\t\t\tisSelected: false,\n\t\t\tisEditing: false,\n\t\t\t_prerender: false\n\t\t};\n\n\t\t// clear any selected points\n\t\tif (markupItem.selectedPoint > -1) {\n\t\t\tnewProps.selectedPoint = undefined;\n\t\t}\n\n\t\tupdateMarkupShape(markupItem, newProps);\n\t\tonblurshape(markupItem);\n\t};\n\n\tconst editMarkupItem = markupItem => {\n\t\tupdateMarkupShape(markupItem, {\n\t\t\tisSelected: true,\n\t\t\tisEditing: true,\n\t\t\t_prerender: textInputMode === 'inline'\n\t\t});\n\t};\n\n\tconst finishEditMarkupItem = markupItem => {\n\t\tupdateMarkupShape(markupItem, {\n\t\t\tisSelected: true,\n\t\t\tisEditing: false,\n\t\t\t_prerender: false\n\t\t});\n\t};\n\n\tconst removeMarkupItems = shapesToRemove => {\n\t\tif (!shapesToRemove.length) return [];\n\t\tconst shapesToRemoveFiltered = shapesToRemove.filter(beforeRemoveShape);\n\t\tshapes.set($shapes.filter(shape => !shapesToRemoveFiltered.includes(shape)));\n\t\treturn shapesToRemoveFiltered;\n\t};\n\n\tconst getTextShapeRect = shape => {\n\t\tconst size = textToSize(shape.text, shape);\n\n\t\treturn rectCreate(\n\t\t\tshape.x,\n\t\t\tshape.y,\n\t\t\tshape.width\n\t\t\t? Math.min(shape.width, size.width)\n\t\t\t: size.width,\n\t\t\tshape.height\n\t\t\t? Math.min(shape.height, size.height)\n\t\t\t: size.height\n\t\t);\n\t};\n\n\tconst getMarkupShapeRect = shape => {\n\t\t// has own rect\n\t\tif (shapeHasSize(shape)) return rectCreateFromAny(shape);\n\n\t\tif (shapeIsEllipse(shape)) return rectCreateFromEllipse(shape);\n\n\t\t// calculate the size on canvas\n\t\tconst rect = getTextShapeRect(shape);\n\n\t\trect.width = Math.max(0, shape.width || rect.width);\n\t\treturn rect;\n\t};\n\n\tconst getShapesNearPosition = (shapes, position, range = 0, shapeFilter = () => true) => [...shapes].// reverse the array, want to select from top to bottom\n\treverse().// filter out shapes we're not interested in\n\tfilter(shapeFilter).// need priority indicator\n\tmap(shape => ({ shape, priority: 1 })).// find markup near pointer\n\tfilter(result => {\n\t\t// get shape\n\t\tconst { shape } = result;\n\n\t\t// we need to know where the shape will end up\n\t\tconst computedShape = shapeComputeDisplay(shapeDeepCopy(shape), parentRect);\n\n\t\t// add stroke width to range\n\t\tconst r = range + (computedShape.strokeWidth || 0) * 0.5;\n\n\t\t// test if clicked in rect\n\t\tif (shapeIsRect(computedShape)) {\n\t\t\treturn circleOverlapsWithRect(position, r, computedShape, shape.rotation);\n\t\t}\n\n\t\t// test if clicked on text\n\t\tif (shapeIsText(computedShape)) {\n\t\t\tconst shapeRect = getMarkupShapeRect(computedShape);\n\t\t\tconst isPositionInBounds = circleOverlapsWithRect(position, r, shapeRect, shape.rotation);\n\t\t\tlet isPositionInVisual = false;\n\n\t\t\tif (isPositionInBounds && !shapeIsSelected(shape)) {\n\t\t\t\tconst visualRect = getTextShapeRect(computedShape);\n\n\t\t\t\tif (shape.textAlign === 'right' && !shape.flipX) {\n\t\t\t\t\tvisualRect.x = shapeRect.x + shapeRect.width - visualRect.width;\n\t\t\t\t}\n\n\t\t\t\tif (shape.textAlign === 'center') {\n\t\t\t\t\tvisualRect.x = shapeRect.x + shapeRect.width * 0.5 - visualRect.width * 0.5;\n\t\t\t\t}\n\n\t\t\t\tisPositionInVisual = circleOverlapsWithRect(position, r, visualRect, shape.rotation, rectCenter(shapeRect));\n\t\t\t\tif (!isPositionInVisual) result.priority = -1;\n\t\t\t}\n\n\t\t\treturn isPositionInBounds;\n\t\t}\n\n\t\t// test if click on ellipse\n\t\tif (shapeIsEllipse(computedShape)) {\n\t\t\treturn circleOverlapsWithEllipse(position, r, computedShape, shape.rotation, shape.flipX, shape.flipY);\n\t\t}\n\n\t\t// test if clicked on line\n\t\tif (shapeIsLine(computedShape)) {\n\t\t\t// radius around click position, test if line intersects\n\t\t\treturn circleOverlapsWithLine(\n\t\t\t\tposition,\n\t\t\t\tMath.max(16, r), // always increase range when selecting lines\n\t\t\t\tshapeLineGetStartPoint(computedShape),\n\t\t\t\tshapeLineGetEndPoint(computedShape)\n\t\t\t);\n\t\t}\n\n\t\t// test if clicked inside polygon\n\t\tif (shapeIsPath(computedShape) && computedShape.pathClose) {\n\t\t\treturn circleOverlapsWithPolygon(position, r, computedShape.points);\n\t\t}\n\n\t\t// test if clicked on path\n\t\tif (shapeIsPath(computedShape)) {\n\t\t\t// is a dot\n\t\t\tif (computedShape.points.length === 1) {\n\t\t\t\treturn vectorDistanceSquared(position, computedShape.points[0]) < r * r;\n\t\t\t}\n\n\t\t\t// radius around click position, test if line intersects\n\t\t\treturn circleOverlapsWithPath(\n\t\t\t\tposition,\n\t\t\t\tMath.max(16, r), // always increase range when selecting lines\n\t\t\t\tcomputedShape.points\n\t\t\t);\n\t\t}\n\n\t\treturn false;\n\t}).sort((a, b) => {\n\t\tif (a.priority < b.priority) return 1;\n\t\tif (a.priority > b.priority) return -1;\n\t\treturn 0;\n\t}).map(item => item.shape);\n\n\tconst getShapesBetweenPoints = (shapes, a, b, range = 0) => {\n\t\t// make sure range is not negative\n\t\tconst r = Math.abs(range);\n\n\t\t// create line\n\t\tconst line = lineCreate(a, b);\n\n\t\t// eraseLine should be in image space\n\t\tconst eraseLine = lineExtend(line, r);\n\n\t\t// create line polygon\n\t\tconst erasePoly = lineExtrude(eraseLine, r);\n\n\t\t// loop over shapes and find intersecting shapes\n\t\tconst res = shapes.filter(shape => {\n\t\t\tconst computedShape = shapeComputeDisplay(shapeDeepCopy(shape), parentRect);\n\n\t\t\t// if shape is line or path\n\t\t\tif (shapeIsLine(computedShape) || shapeIsPath(computedShape)) {\n\t\t\t\tconst points = computedShape.points\n\t\t\t\t? [...computedShape.points]\n\t\t\t\t: [\n\t\t\t\t\t\tshapeLineGetStartPoint(computedShape),\n\t\t\t\t\t\tshapeLineGetEndPoint(computedShape)\n\t\t\t\t\t];\n\n\t\t\t\treturn !!linePointsIntersection(eraseLine, points);\n\t\t\t}\n\n\t\t\t// else turn into polygon and compare polygons\n\t\t\treturn polyIntersectsWithPoly(erasePoly, shapeToPoly(computedShape));\n\t\t});\n\n\t\treturn res;\n\t};\n\n\t//#region shape base interaction\n\tlet interactionPoint = undefined;\n\n\tlet interactionTimer = undefined;\n\tlet interactionTarget = undefined;\n\tlet interactionShape = undefined;\n\tlet interactionShapeOrigin = undefined;\n\tlet interactionShapeOriginComputed = undefined;\n\tlet interactionShapeWasSelected = false;\n\tlet interactionShapeWasConfirmed = false;\n\tlet interactionShapeTextDrag = false;\n\tlet isInteracting = false;\n\tlet multiSelectionInteraction = undefined;\n\n\tconst initMultiSelectionInteraction = shapes => {\n\t\tmultiSelectionInteraction = shapes.map(shape => {\n\t\t\treturn {\n\t\t\t\tshape,\n\t\t\t\tshapeOrigin: shapeDeepCopy(shape),\n\t\t\t\tshapeOriginComputed: shapeComputeDisplay(shapeDeepCopy(shape), parentRect)\n\t\t\t};\n\t\t});\n\t};\n\n\tconst handleInteractionStart = e => {\n\t\tconst { origin } = e.detail;\n\t\tconst isMultiSelecting = enableMultiSelect && $keysPressedStored.includes(16);\n\t\tmultiSelectionInteraction = undefined;\n\t\t$$invalidate(155, interactionShape = undefined);\n\t\tinteractionShapeOrigin = undefined;\n\t\tinteractionShapeOriginComputed = undefined;\n\t\tinteractionShapeWasSelected = false;\n\t\tinteractionTarget = undefined;\n\t\tinteractionShapeWasConfirmed = false;\n\t\tinteractionShapeTextDrag = false;\n\t\tclearInteractionSnapLines();\n\t\tclearTimeout(interactionTimer);\n\t\tinteractionTimer = setTimeout(() => $$invalidate(156, isInteracting = true), 250);\n\n\t\t// if is editing text\n\t\tconst draft = getMarkupItemDraft();\n\n\t\tif (draft && !(shapeIsPath(draft) && hasProp(draft, 'pathClose'))) {\n\t\t\tconfirmMarkupItemDraft();\n\t\t}\n\n\t\t// test if target is a shape, if not, run interaction handler\n\t\tinteractionPoint = mapEditorPointToImagePoint(vectorClone(origin));\n\n\t\t// if is shape path, we need to first finish path before we can do other actions\n\t\tif (draft && shapeIsPath(draft) && hasProp(draft, 'pathClose')) {\n\t\t\treturn oninteractionstart(e);\n\t\t}\n\n\t\tconst foundShapes = getShapesNearPosition($shapes, interactionPoint, selectRadius, shape => shapeCanSelect(shape));\n\t\tconst targettedMarkupItem = foundShapes.length && foundShapes.shift();\n\n\t\t// confirm text when moving between shapes\n\t\tif (activeMarkup && shapeIsTextEditing(activeMarkup)) {\n\t\t\tif (targettedMarkupItem !== activeMarkup) {\n\t\t\t\thandleTextConfirm();\n\t\t\t} else {\n\t\t\t\tconst isFixedBox = hasProp(activeMarkup, 'height');\n\t\t\t\tconst isAutoHeightBox = !isFixedBox && hasProp(activeMarkup, 'width');\n\n\t\t\t\t// auto-width cannot be dragged\n\t\t\t\tif (isFixedBox || isAutoHeightBox) {\n\t\t\t\t\t// test if is trying to drag fixed with shape?\n\t\t\t\t\tconst textTester = shapeDeepCopy(activeMarkup);\n\n\t\t\t\t\tconst textTesterComputed = shapeDeepCopy(textTester);\n\t\t\t\t\tshapeComputeDisplay(textTesterComputed, parentRect);\n\n\t\t\t\t\t// need current size\n\t\t\t\t\tconst textCurrentShapeSize = sizeApply(textToSize(textTester.text, textTesterComputed), v => Math.ceil(v));\n\n\t\t\t\t\tconst sizeFrom = sizeCreate(textTesterComputed.width, textTesterComputed.height || textCurrentShapeSize.height);\n\t\t\t\t\ttoAutoWidth(sizeFrom, textTester, textTesterComputed);\n\n\t\t\t\t\t// uncomment to see the auto-width shape (for debugging purposes)\n\t\t\t\t\t// addShape({\n\t\t\t\t\t//     ...textTester,\n\t\t\t\t\t//     disableSelect: true,\n\t\t\t\t\t//     backgroundColor: [1, 0, 0, 0.25],\n\t\t\t\t\t//     isSelected: false,\n\t\t\t\t\t//     isEditing: false,\n\t\t\t\t\t// });\n\t\t\t\t\tconst shapesUnderCursor = getShapesNearPosition([{ ...textTester, strokeWidth: '5%' }], interactionPoint, 0);\n\n\t\t\t\t\tinteractionShapeTextDrag = shapesUnderCursor.length === 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// don't add new text shape when just confirmed another inline text shape\n\t\tif (activeMarkup && enableTapToAddText) {\n\t\t\tinteractionShapeWasConfirmed = true;\n\t\t}\n\n\t\t// deselect\n\t\tif (!targettedMarkupItem && activeMarkup && shapeIsTextEditing(activeMarkup)) {\n\t\t\tdeselectMarkupItem(activeMarkup);\n\t\t}\n\n\t\t// if is clicking outside of canvas, don't create new shape\n\t\tif (!willStartInteraction(origin)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// check if markup was targetted\n\t\tif (targettedMarkupItem && shapeIsSelected(targettedMarkupItem)) {\n\t\t\tinteractionShapeWasSelected = true;\n\t\t\t$$invalidate(155, interactionShape = targettedMarkupItem);\n\n\t\t\t// there's a multiselection if is holding shift we need to deselect this shape\n\t\t\tif (isMultiSelection) {\n\t\t\t\t// is holding shift\n\t\t\t\tif (isMultiSelecting) deselectMarkupItem(targettedMarkupItem);\n\n\t\t\t\t// reset multiselection\n\t\t\t\tinitMultiSelectionInteraction(multiSelection);\n\n\t\t\t\t// exit\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// create a deep copy so we can check on end interaction if the shape was changed\n\t\t\tinteractionShapeOrigin = shapeDeepCopy(interactionShape);\n\n\t\t\t// clone shape we're interacting with so we can update it properly\n\t\t\tinteractionShapeOriginComputed = shapeComputeDisplay(shapeDeepCopy(interactionShape), parentRect);\n\n\t\t\treturn;\n\t\t}\n\n\t\t// set target\n\t\tinteractionTarget = getSelectionItemDraft()\n\t\t? undefined\n\t\t: targettedMarkupItem || undefined;\n\n\t\t// started interacting\n\t\tconst didStartInteraction = oninteractionstart(e);\n\n\t\t// drag current targetted it as fallback interaction,\n\t\t// helps make sticker interaction easier\n\t\tif (!didStartInteraction && targettedMarkupItem) {\n\t\t\t// select\n\t\t\tselectShape(targettedMarkupItem, true, isMultiSelecting);\n\n\t\t\t$$invalidate(155, interactionShape = targettedMarkupItem);\n\n\t\t\t// handle multiselection\n\t\t\tif (isMultiSelection) return initMultiSelectionInteraction(multiSelection);\n\n\t\t\t// create a deep copy so we can check on end interaction if the shape was changed\n\t\t\tinteractionShapeOrigin = shapeDeepCopy(interactionShape);\n\n\t\t\t// clone shape we're interacting with so we can update it properly\n\t\t\tinteractionShapeOriginComputed = shapeComputeDisplay(shapeDeepCopy(interactionShape), parentRect);\n\t\t}\n\t};\n\n\tconst resetInteraction = () => {\n\t\tclearTimeout(interactionTimer);\n\t\tinteractionTimer = undefined;\n\t\t$$invalidate(156, isInteracting = false);\n\t\tclearInteractionSnapLines();\n\t};\n\n\tconst handleInteractionCancel = e => {\n\t\tresetInteraction();\n\t\toninteractioncancel(e);\n\t};\n\n\tlet axisOverride = null;\n\n\tconst handleInteractionUpdate = e => {\n\t\tconst { translation, ctrlKey, metaKey, shiftKey, position } = e.detail;\n\n\t\t// is interacting with shape\n\t\tif (interactionShape) {\n\t\t\t// prevent moving if not allowed\n\t\t\tif (!shapeCanMove(interactionShape)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// prevent moving if is editing text\n\t\t\tif (shapeIsTextEditing(interactionShape)) {\n\t\t\t\tif (!interactionShapeTextDrag) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\thandleTextConfirm();\n\t\t\t}\n\n\t\t\t// if shift pressed, we pick biggest axis translation and use that\n\t\t\tif (shiftKey) {\n\t\t\t\tlet tx = Math.abs(translation.x);\n\t\t\t\tlet ty = Math.abs(translation.y);\n\t\t\t\tif (axisOverride === 'x') ty -= 64;\n\t\t\t\tif (axisOverride === 'y') tx -= 64;\n\n\t\t\t\tif (tx > ty) {\n\t\t\t\t\ttranslation.y = 0;\n\t\t\t\t\taxisOverride = 'x';\n\t\t\t\t} else if (ty > tx) {\n\t\t\t\t\ttranslation.x = 0;\n\t\t\t\t\taxisOverride = 'y';\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\taxisOverride = null;\n\t\t\t}\n\n\t\t\t// if control or cmd pressed, prevent snapping\n\t\t\tconst preventSnap = ctrlKey || metaKey;\n\n\t\t\t// is interacting with multiple shapes\n\t\t\tif (multiSelectionInteraction) {\n\t\t\t\t// cannot move all shapes in multi selection\n\t\t\t\tif (!multiSelection.every(shapeCanMove)) return;\n\n\t\t\t\t// let's move shapes\n\t\t\t\tmultiSelectionInteraction.forEach(({ shape, shapeOriginComputed }) => {\n\t\t\t\t\ttranslateShape(shape, shapeOriginComputed, translation, {\n\t\t\t\t\t\t...getSnapOptions(\n\t\t\t\t\t\t\t0, // (TODO: implement snapping for multi selection) preventSnap ? 0 : snapThreshold,\n\t\t\t\t\t\t\tgridSize,\n\t\t\t\t\t\t\tgridRect,\n\t\t\t\t\t\t\tshape\n\t\t\t\t\t\t)\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn translateShape(interactionShape, interactionShapeOriginComputed, translation, {\n\t\t\t\t...getSnapOptions(preventSnap ? 0 : snapThreshold, gridSize, gridRect, interactionShape)\n\t\t\t});\n\t\t}\n\n\t\toninteractionupdate(e);\n\t};\n\n\tconst handleInteractionRelease = e => {\n\t\tresetInteraction();\n\n\t\tif (!interactionShape) {\n\t\t\toninteractionrelease(e);\n\t\t\treturn;\n\t\t}\n\n\t\t// test if is text and if we double tapped, if so, switch to text edit mode\n\t\t// don't run these interactions if we've selected multiple items\n\t\tif (isMultiSelection) return;\n\n\t\t// tapped on path shape\n\t\tif (e.detail.isTap && shapeIsPath(interactionShape) && shapeCanAddPoint(interactionShape)) {\n\t\t\tconst { position } = e.detail;\n\t\t\tconst imagePoint = mapEditorPointToImagePoint(vectorClone(position));\n\t\t\taddPointToPath(interactionShape, imagePoint);\n\t\t\treturn;\n\t\t} else // if tapped shape, and shape is text, and shape was selected\n\t\tif (e.detail.isTap && interactionShapeWasSelected && shapeIsText(interactionShape) && shapeCanInput(interactionShape) !== false) {\n\t\t\teditMarkupItem(interactionShape);\n\t\t}\n\t};\n\n\tconst handleInteractionEnd = e => {\n\t\tconst isSelectInteraction = interactionTarget && e.detail.isTap;\n\t\tconst isMultiSelecting = enableMultiSelect && $keysPressedStored.includes(16);\n\n\t\tif (e.detail.isTap) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tontapcanvas(\n\t\t\t\t\t{\n\t\t\t\t\t\ttarget: interactionShape || interactionTarget,\n\t\t\t\t\t\tposition: interactionPoint\n\t\t\t\t\t},\n\t\t\t\t\t0\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\t// shape remains active so user can resize, rotate\n\t\tif (interactionShape) {\n\t\t\tontapshape(interactionShape);\n\n\t\t\tif (!shapeEqual(interactionShape, interactionShapeOrigin)) {\n\t\t\t\tonupdateshape(interactionShape);\n\t\t\t}\n\n\t\t\t$$invalidate(155, interactionShape = undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t// if we're not multiselecting we have to deselect currently selected shape\n\t\tlet allowDeselectShape = true;\n\n\t\tif (!isMultiSelecting) {\n\t\t\t// can we deselect the current shape?\n\t\t\tconst currentSelectedShape = getSelectedShape();\n\n\t\t\tallowDeselectShape = currentSelectedShape\n\t\t\t? beforeDeselectShape(currentSelectedShape, interactionTarget || undefined)\n\t\t\t: true;\n\n\t\t\tif (allowDeselectShape) {\n\t\t\t\tblurShapes({ storePrevious: false });\n\t\t\t}\n\t\t}\n\n\t\toninteractionend(e);\n\n\t\tif (allowDeselectShape && isSelectInteraction) {\n\t\t\tselectShape(interactionTarget, true, isMultiSelecting);\n\t\t}\n\t};\n\n\t//#endregion\n\tconst getMultiSelectionPoints = shapes => {\n\t\tconst shapePoints = shapes.map(shape => getMarkupShapePoints(shapeComputeDisplay(shape, parentRect))).flat();\n\t\tconst selectionRect = rectCreateFromPoints(shapePoints);\n\t\treturn rectGetCorners(selectionRect);\n\t};\n\n\t//\n\t// Shape manipulation\n\t//\n\tconst getMarkupShapePoints = shape => {\n\t\tconst hasRotation = isNumber(shape.rotation) && shape.rotation !== 0;\n\n\t\tif (shapeIsRect(shape)) {\n\t\t\tconst center = rectCenter(shape);\n\t\t\tconst points = rectGetCorners(shape);\n\n\t\t\tif (shape.flipX || shape.flipY) {\n\t\t\t\tvectorsFlip(points, shape.flipX, shape.flipY, center.x, center.y);\n\t\t\t}\n\n\t\t\treturn hasRotation\n\t\t\t? vectorsRotate(points, shape.rotation, center.x, center.y)\n\t\t\t: points;\n\t\t}\n\n\t\tif (shapeIsEllipse(shape)) {\n\t\t\tconst center = shape;\n\t\t\tconst points = rectGetCorners(rectCreateFromEllipse(shape));\n\n\t\t\tif (shape.flipX || shape.flipY) {\n\t\t\t\tvectorsFlip(points, shape.flipX, shape.flipY, center.x, center.y);\n\t\t\t}\n\n\t\t\treturn hasRotation\n\t\t\t? vectorsRotate(points, shape.rotation, center.x, center.y)\n\t\t\t: points;\n\t\t}\n\n\t\tif (shapeIsLine(shape)) {\n\t\t\treturn [shapeLineGetStartPoint(shape), shapeLineGetEndPoint(shape)];\n\t\t}\n\n\t\tif (shapeIsPath(shape)) {\n\t\t\tif (shape.bitmap && !hasProp(shape, 'pathClose')) {\n\t\t\t\tconst rect = rectCreateFromPoints(shape.points);\n\t\t\t\trect.x -= shape.strokeWidth * 0.5;\n\t\t\t\trect.y -= shape.strokeWidth * 0.5;\n\t\t\t\trect.width += shape.strokeWidth;\n\t\t\t\trect.height += shape.strokeWidth;\n\t\t\t\tconst points = getMarkupShapePoints({ ...shape, ...rect });\n\t\t\t\treturn points;\n\t\t\t}\n\n\t\t\treturn [...shape.points];\n\t\t}\n\n\t\tif (shapeIsText(shape)) {\n\t\t\tconst rect = getMarkupShapeRect(shape);\n\n\t\t\t// rect.width = Math.max(MIN_TEXT_MARKUP_WIDTH, rect.width);\n\t\t\tconst center = rectCenter(rect);\n\n\t\t\tconst points = rectGetCorners(rect);\n\n\t\t\tif (shape.flipX || shape.flipY) {\n\t\t\t\tvectorsFlip(points, shape.flipX, shape.flipY, center.x, center.y);\n\t\t\t}\n\n\t\t\treturn hasRotation\n\t\t\t? vectorsRotate(points, shape.rotation, center.x, center.y)\n\t\t\t: points;\n\t\t}\n\n\t\treturn [];\n\t};\n\n\tconst getShapeRotationPoint = shape => {\n\t\tconst points = getMarkupShapePoints(shape);\n\t\tlet origin;\n\t\tlet dir;\n\n\t\tif (shape.flipY) {\n\t\t\torigin = vectorCenter([points[0], points[1]]);\n\t\t\tdir = vectorNormalize(vectorCreate(points[1].x - points[2].x, points[1].y - points[2].y));\n\t\t} else {\n\t\t\torigin = vectorCenter([points[2], points[3]]);\n\t\t\tdir = vectorNormalize(vectorCreate(points[2].x - points[1].x, points[2].y - points[1].y));\n\t\t}\n\n\t\tvectorMultiply(dir, SHAPE_CONTROL_OFFSET / contextZoom);\n\t\treturn { origin, dir };\n\t};\n\n\tconst getShapeRotationPointOnScreen = shape => {\n\t\tconst markupPoint = getShapeRotationPoint(shape);\n\n\t\tconst screenPosition = mapImagePointToEditorPoint({\n\t\t\tx: markupPoint.origin.x + markupPoint.dir.x,\n\t\t\ty: markupPoint.origin.y + markupPoint.dir.y\n\t\t});\n\n\t\tconst screenOrigin = mapImagePointToEditorPoint(markupPoint.origin);\n\n\t\treturn {\n\t\t\torigin: screenOrigin,\n\t\t\tposition: screenPosition\n\t\t};\n\t};\n\n\tconst getShapeScalarPointOnScreen = shape => {\n\t\tconst points = getMarkupShapePoints(shape);\n\t\tlet index = 2;\n\n\t\tif (shape.flipX && shape.flipY) {\n\t\t\tindex = 0;\n\t\t} else if (shape.flipX) {\n\t\t\tindex = 3;\n\t\t} else if (shape.flipY) {\n\t\t\tindex = 1;\n\t\t}\n\n\t\tconst markupPoint = { ...points[index] };\n\t\tconst screenPosition = mapImagePointToEditorPoint({ x: markupPoint.x, y: markupPoint.y });\n\t\treturn screenPosition;\n\t};\n\n\tfunction getAllowEdgeControls(activeMarkup) {\n\t\tif (!activeMarkup) return false;\n\n\t\t// if is non width & height text, we render controls on edges\n\t\tif (shapeIsText(activeMarkup) && !activeMarkup.height) {\n\t\t\t// for auto-height\n\t\t\treturn [[1, 2], [3, 0]];\n\t\t}\n\n\t\t// never on lines and paths\n\t\tif (shapeIsLine(activeMarkup) || shapeIsPath(activeMarkup)) return false;\n\n\t\t// allowed\n\t\treturn true;\n\t}\n\n\t// UI manipulator functions\n\tconst createIsNotComparison = fn => shape => !fn(shape);\n\n\tconst createShapeComparison = id => shape => shape.id === id;\n\n\tconst createShapeFilter = id => {\n\t\tconst isShapeMatchingId = createShapeComparison(id);\n\t\treturn shapes => shapes.filter(createIsNotComparison(isShapeMatchingId));\n\t};\n\n\tconst createShapeRemover = id => {\n\t\tconst isShapeMatchingId = createShapeComparison(id);\n\t\tconst shapeFilter = createShapeFilter(id);\n\n\t\treturn () => ui.update(shapes => {\n\t\t\tif (!shapes.some(isShapeMatchingId)) return shapes;\n\t\t\treturn shapeFilter(shapes);\n\t\t});\n\t};\n\n\tconst createShapePusher = id => {\n\t\tconst shapeFilter = createShapeFilter(id);\n\n\t\treturn (...newShapes) => {\n\t\t\tui.update(shapes => [...shapeFilter(shapes), ...newShapes.filter(Boolean)]);\n\t\t};\n\t};\n\n\tconst popHoverShapes = createShapeRemover(HoverShapeId);\n\tconst pushHoverShapes = createShapePusher(HoverShapeId);\n\n\tconst redrawHoverShapes = shape => {\n\t\tconst shapePoints = getMarkupShapePoints(shapeComputeDisplay(shapeDeepCopy(shape), parentRect));\n\t\tif (!shapePoints) return;\n\t\tconst screenPoints = shapePoints.map(mapImagePointToEditorPoint);\n\n\t\t// should we close the selection path\n\t\tlet pathClose = false;\n\n\t\tif (shape.pathClose === true) {\n\t\t\tpathClose = true;\n\t\t} else {\n\t\t\tif (shapeIsPath(shape)) {\n\t\t\t\tpathClose = !hasProp(shape, 'pathClose');\n\t\t\t} else // other shapes\n\t\t\tif (screenPoints.length > 2) {\n\t\t\t\tpathClose = true;\n\t\t\t}\n\t\t}\n\n\t\tconst isHookStyle = shape.selectionStyle === 'hook';\n\n\t\tconst outlineShadow = isHookStyle\n\t\t? screenPoints.map((p, index, arr) => ({\n\t\t\t\tid: HoverShapeId,\n\t\t\t\tpoints: getManipulatorSelectionHookShape(arr, index),\n\t\t\t\tstrokeColor: [0, 0, 0, 0.1],\n\t\t\t\tstrokeWidth: 2\n\t\t\t}))\n\t\t: [\n\t\t\t\t{\n\t\t\t\t\tid: HoverShapeId,\n\t\t\t\t\tpoints: screenPoints.map(p => vectorCreate(p.x + 1, p.y + 1)),\n\t\t\t\t\tstrokeColor: [0, 0, 0, 0.1],\n\t\t\t\t\tstrokeWidth: 2,\n\t\t\t\t\tpathClose\n\t\t\t\t}\n\t\t\t];\n\n\t\tconst outline = isHookStyle\n\t\t? screenPoints.map((p, index, arr) => ({\n\t\t\t\tid: HoverShapeId,\n\t\t\t\tpoints: getManipulatorSelectionHookShape(arr, index),\n\t\t\t\tstrokeColor: hoverColor,\n\t\t\t\tstrokeWidth: 2\n\t\t\t}))\n\t\t: [\n\t\t\t\t{\n\t\t\t\t\tid: HoverShapeId,\n\t\t\t\t\tpoints: screenPoints,\n\t\t\t\t\tstrokeColor: hoverColor,\n\t\t\t\t\tstrokeWidth: 2,\n\t\t\t\t\tpathClose\n\t\t\t\t}\n\t\t\t];\n\n\t\tpushHoverShapes(...outlineShadow, ...outline);\n\t};\n\n\tlet hoverShape;\n\n\t// draw shape manipulator edges\n\tconst ManipulatorShapeId = `markup-manipulator-segment-` + uid;\n\n\tconst popManipulatorShapes = createShapeRemover(ManipulatorShapeId);\n\tconst pushManipulatorShapes = createShapePusher(ManipulatorShapeId);\n\n\tconst getManipulatorSelectionHookShape = (points, index) => {\n\t\tconst currentPoint = points[index];\n\n\t\tconst previousPoint = index - 1 < 0\n\t\t? points[points.length - 1]\n\t\t: points[index - 1];\n\n\t\tconst nextPoint = index + 1 < points.length\n\t\t? points[index + 1]\n\t\t: points[0];\n\n\t\t// line from currentPoint to previous point\n\t\tconst cp = vectorSubtract(vectorClone(previousPoint), currentPoint);\n\n\t\tvectorNormalize(cp);\n\t\tconst start = vectorAdd(vectorMultiply(cp, 10), currentPoint);\n\n\t\t// line from currentPoint to next point\n\t\tconst cn = vectorSubtract(vectorClone(nextPoint), currentPoint);\n\n\t\tvectorNormalize(cn);\n\t\tconst end = vectorAdd(vectorMultiply(cn, 10), currentPoint);\n\t\treturn [start, currentPoint, end];\n\t};\n\n\tconst redrawManipulatorShapes = (opacity, shape, pointerPosition) => {\n\t\tif (!shapeCanSelect(shape)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst isPath = shapeIsPath(shape);\n\t\tconst isPolygon = isPath && hasProp(shape, 'pathClose');\n\t\tconst hasStroke = isPolygon && shapeHasStroke(shape);\n\t\tconst isDraft = shapeIsDraft(shape);\n\t\tconst isTextEditing = shapeIsTextEditing(shape);\n\t\tconst isHookStyle = shape.selectionStyle === 'hook';\n\t\tconst shouldDrawPoints = shape.disableShowPoints !== true;\n\t\tconst { selectionOpacity = 1 } = shape;\n\n\t\t// don't draw line manipulator on sharpie draft\n\t\tif (isDraft && isPath && !isPolygon) return;\n\n\t\t// create manipulator outline segments\n\t\tconst segments = [];\n\n\t\tconst screenPoints = [...selectionScreenPoints];\n\t\tconst screenPointsLast = screenPoints[screenPoints.length - 1];\n\t\tconst screenPointsFirst = screenPoints[0];\n\t\tconst shadowOpacity = (isTextEditing ? 0.05 : 0.1) * opacity * selectionOpacity;\n\t\tconst shadowVisible = shadowOpacity > 0;\n\t\tconst lineOpacity = (isTextEditing ? 0.5 : 1) * opacity * selectionOpacity;\n\t\tconst lineVisible = lineOpacity > 0;\n\t\tconst strokeColorShadow = [0, 0, 0];\n\t\tconst strokeColor = [1, 1, 1];\n\t\tconst strokeWidth = isTextEditing ? 1 : 1.5;\n\n\t\t// if shift is held snap to last point\n\t\tif ($keysPressedStored.includes(16) && screenPointsLast && pointerPosition) positionRelativeToAnchor(screenPointsLast, pointerPosition);\n\n\t\tconst distToOriginSquared = screenPoints.length && isPolygon && isDraft && pointerPosition\n\t\t? vectorDistanceSquared(screenPointsFirst, pointerPosition)\n\t\t: Infinity;\n\n\t\tconst distToLastSquared = screenPoints.length && isPolygon && isDraft && pointerPosition\n\t\t? vectorDistanceSquared(screenPointsLast, pointerPosition)\n\t\t: Infinity;\n\n\t\tconst canClosePath = distToOriginSquared <= POLYGON_END_PATH_DISTANCE_SQUARED;\n\t\tconst canEndPath = distToLastSquared <= POLYGON_END_PATH_DISTANCE_SQUARED;\n\n\t\t// if we can't close the path we draw a line from the last point to the pointer position\n\t\tif (!canClosePath && pointerPosition) screenPoints.push(pointerPosition);\n\n\t\tconst canDrawLine = screenPoints.length > 1;\n\n\t\t// should we close the selection path\n\t\tlet closeSelectionPath = false;\n\n\t\tif (shape.pathClose === true) {\n\t\t\tcloseSelectionPath = true;\n\t\t} else {\n\t\t\tif (shapeIsPath(shape)) {\n\t\t\t\t// we're drawing a path shape, only close if can close (indicate close line in UI)\n\t\t\t\tif (shapeIsDraft(shape)) {\n\t\t\t\t\tcloseSelectionPath = canClosePath;\n\t\t\t\t} else // we're not drawing a shape, only close path if shape doesn'thave pathClose prop\n\t\t\t\t{\n\t\t\t\t\tcloseSelectionPath = !hasProp(shape, 'pathClose');\n\t\t\t\t}\n\t\t\t} else // other shapes\n\t\t\tif (screenPoints.length > 2) {\n\t\t\t\tcloseSelectionPath = true;\n\t\t\t}\n\t\t}\n\n\t\t// shadows\n\t\tif (canDrawLine && shadowVisible) {\n\t\t\t// draw corner hooks\n\t\t\tisHookStyle\n\t\t\t? segments.push(...screenPoints.map((p, index, arr) => ({\n\t\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\t\tpoints: getManipulatorSelectionHookShape(arr, index),\n\t\t\t\t\tstrokeColor: strokeColorShadow,\n\t\t\t\t\topacity: shadowOpacity\n\t\t\t\t})))\n\t\t\t: // draw rectangle\n\t\t\t\tsegments.push({\n\t\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\t\tpoints: screenPoints.map(p => vectorCreate(p.x + 1, p.y + 1)),\n\t\t\t\t\tpathClose: closeSelectionPath,\n\t\t\t\t\tstrokeColor: strokeColorShadow,\n\t\t\t\t\tstrokeWidth: 2,\n\t\t\t\t\topacity: shadowOpacity\n\t\t\t\t});\n\t\t}\n\n\t\tisPolygon && shadowVisible && shouldDrawPoints && segments.push(...screenPoints.map(point => {\n\t\t\treturn {\n\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\t...point,\n\t\t\t\trx: strokeWidth * 2,\n\t\t\t\try: strokeWidth * 2,\n\t\t\t\tbackgroundColor: strokeColorShadow,\n\t\t\t\topacity: shadowOpacity\n\t\t\t};\n\t\t}));\n\n\t\tif (shapeManipulatorRotationPoint && shadowVisible) {\n\t\t\t// add rotator line shadow\n\t\t\tsegments.push({\n\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\tpoints: [\n\t\t\t\t\tvectorCreate(shapeManipulatorRotationPoint.origin.x + 1, shapeManipulatorRotationPoint.origin.y + 1),\n\t\t\t\t\tvectorCreate(shapeManipulatorRotationPoint.position.x + 1, shapeManipulatorRotationPoint.position.y + 1)\n\t\t\t\t],\n\t\t\t\tstrokeColor: strokeColorShadow,\n\t\t\t\tstrokeWidth: 2,\n\t\t\t\topacity: shadowOpacity\n\t\t\t});\n\t\t}\n\n\t\t// lines\n\t\tif (canDrawLine && lineVisible) {\n\t\t\t// draw corner hooks\n\t\t\tisHookStyle\n\t\t\t? segments.push(...screenPoints.map((p, index, arr) => ({\n\t\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\t\tpoints: getManipulatorSelectionHookShape(arr, index),\n\t\t\t\t\tstrokeColor,\n\t\t\t\t\tstrokeWidth,\n\t\t\t\t\topacity: lineOpacity\n\t\t\t\t})))\n\t\t\t: // draw rectangle\n\t\t\t\tsegments.push({\n\t\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\t\tpoints: screenPoints,\n\t\t\t\t\tpathClose: closeSelectionPath,\n\t\t\t\t\tstrokeColor,\n\t\t\t\t\tstrokeWidth,\n\t\t\t\t\tbackgroundColor: isDraft && isPolygon && shape.backgroundColor && shape.backgroundColor[3] > 0\n\t\t\t\t\t? shape.backgroundColor\n\t\t\t\t\t: [0, 0, 0, 0],\n\t\t\t\t\topacity: lineOpacity\n\t\t\t\t});\n\t\t}\n\n\t\tisPolygon && shouldDrawPoints && segments.push(...screenPoints.map(point => {\n\t\t\treturn {\n\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\t...point,\n\t\t\t\trx: strokeWidth * 3,\n\t\t\t\try: strokeWidth * 3,\n\t\t\t\tbackgroundColor: [0.5, 0.5, 0.5],\n\t\t\t\tstrokeWidth,\n\t\t\t\tstrokeColor\n\t\t\t};\n\t\t}));\n\n\t\t// draft mode\n\t\tisPolygon && isDraft && shouldDrawPoints && selectionScreenPoints.length >= 3 && segments.push({\n\t\t\t...screenPointsFirst,\n\t\t\tid: ManipulatorShapeId,\n\t\t\trx: strokeWidth * (canClosePath ? 5 : 4),\n\t\t\try: strokeWidth * (canClosePath ? 5 : 4),\n\t\t\tbackgroundColor: canClosePath ? hoverColor : [0.5, 0.5, 0.5],\n\t\t\tstrokeWidth,\n\t\t\tstrokeColor\n\t\t});\n\n\t\tisPolygon && isDraft && hasStroke && shouldDrawPoints && !canClosePath && shapeActivePoints.length >= 2 && segments.push({\n\t\t\t...screenPointsLast,\n\t\t\tid: ManipulatorShapeId,\n\t\t\trx: strokeWidth * (canEndPath ? 5 : 4),\n\t\t\try: strokeWidth * (canEndPath ? 5 : 4),\n\t\t\tbackgroundColor: canEndPath ? hoverColor : [0.5, 0.5, 0.5],\n\t\t\tstrokeWidth,\n\t\t\tstrokeColor\n\t\t});\n\n\t\tif (shapeManipulatorRotationPoint && lineVisible && !isHookStyle) {\n\t\t\t// add rotator line\n\t\t\tsegments.push({\n\t\t\t\tid: ManipulatorShapeId,\n\t\t\t\tpoints: [\n\t\t\t\t\t{\n\t\t\t\t\t\tx: shapeManipulatorRotationPoint.origin.x,\n\t\t\t\t\t\ty: shapeManipulatorRotationPoint.origin.y\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tx: shapeManipulatorRotationPoint.position.x,\n\t\t\t\t\t\ty: shapeManipulatorRotationPoint.position.y\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\tstrokeColor,\n\t\t\t\tstrokeWidth,\n\t\t\t\topacity: lineOpacity\n\t\t\t});\n\t\t}\n\n\t\t// replace existing segments\n\t\tpushManipulatorShapes(...segments);\n\t};\n\n\t// add contextPresentationRect so we redraw active markup each frame\n\tconst clearHoverShapeIfActive = () => {\n\t\tif (activeMarkup !== hoverShape) return;\n\t\tclearHoverShape();\n\t};\n\n\tconst clearHoverShape = () => {\n\t\t$$invalidate(157, hoverShape = undefined);\n\t\tpopHoverShapes();\n\t};\n\n\t// multi selection shapes (drawn at shapes edges when multiselecting)\n\tconst MultiSelectionShapeId = `markup-multi-selection-segment-` + uid;\n\n\tconst popMultiSelectionShapes = createShapeRemover(MultiSelectionShapeId);\n\tconst pushMultiSelectionShapes = createShapePusher(MultiSelectionShapeId);\n\n\t// snap pointer so we can show where initial point is going to be\n\tconst snapPointerPosition = (pointerPosition, disableSnapping) => {\n\t\tif (snapThreshold <= 0) return pointerPosition;\n\n\t\tif (disableSnapping) {\n\t\t\tclearInteractionSnapLines();\n\t\t\treturn pointerPosition;\n\t\t}\n\n\t\tconst imagePoint = mapEditorPointToImagePoint(pointerPosition);\n\t\tconst snapTargets = getSnapTargets();\n\t\tconst { snapTranslation, snapLines } = snapLinesToTargets(getShapeSnapLines(imagePoint), snapTargets, snapThreshold, gridSize, gridRect);\n\t\tsetInteractionSnapLines(snapLines);\n\t\tupdateWithSnapTranslation(pointerPosition, snapTranslation);\n\t\treturn pointerPosition;\n\t};\n\n\t// draw grid lines\n\tconst gridOpacity = spring(0);\n\n\tcomponent_subscribe($$self, gridOpacity, value => $$invalidate(202, $gridOpacity = value));\n\tconst GridShapeId = `markup-grid-line-${uid}`;\n\tconst popGridShapes = createShapeRemover(GridShapeId);\n\tconst pushGridShapes = createShapePusher(GridShapeId);\n\n\tconst redrawGridShapes = (cellSize, gridRect, strokeColor, opacity) => {\n\t\tconst editorPointA = mapImagePointToEditorPoint({ x: 0, y: 0 });\n\t\tconst editorPointB = mapImagePointToEditorPoint({ x: cellSize, y: cellSize });\n\t\tconst editorPointC = mapImagePointToEditorPoint({ x: gridRect.width, y: gridRect.height });\n\t\tconst projectedCellSize = editorPointB.x - editorPointA.x;\n\n\t\t// animate grid opacity\n\t\tgridOpacity.set(projectedCellSize > 6 ? 1 : 0);\n\n\t\t// no need tor ender\n\t\tif (opacity <= 0) return popGridShapes();\n\n\t\tconst linesVertical = getNumberSequence(projectedCellSize, editorPointA.x, editorPointC.x).map(line => ({\n\t\t\tid: GridShapeId,\n\t\t\topacity,\n\t\t\tpoints: [{ x: line, y: editorPointA.y }, { x: line, y: editorPointC.y }],\n\t\t\tstrokeWidth: 1,\n\t\t\tstrokeColor\n\t\t}));\n\n\t\tconst linesHorizontal = getNumberSequence(projectedCellSize, editorPointA.y, editorPointC.y).map(line => ({\n\t\t\tid: GridShapeId,\n\t\t\topacity,\n\t\t\tpoints: [{ x: editorPointA.x, y: line }, { x: editorPointC.x, y: line }],\n\t\t\tstrokeWidth: 1,\n\t\t\tstrokeColor\n\t\t}));\n\n\t\t// update UI\n\t\tpushGridShapes(...linesHorizontal, ...linesVertical);\n\t}; // ui.update((shapes) => [...filterGridLines(shapes), ...linesHorizontal, ...linesVertical]);\n\n\t//#region snap lines\n\tconst SnapShapeId = `markup-snap-line`;\n\n\tconst popSnapShapes = createShapeRemover(SnapShapeId);\n\tconst pushSnapShapes = createShapePusher(SnapShapeId);\n\n\tconst redrawSnapShapes = (linesX, linesY, strokeColor) => {\n\t\tif (linesX === null && linesY === null) {\n\t\t\treturn popSnapShapes();\n\t\t}\n\n\t\tlet xLine;\n\t\tlet yLine;\n\n\t\tif (linesX !== null) {\n\t\t\txLine = {\n\t\t\t\tid: SnapShapeId,\n\t\t\t\tstrokeColor,\n\t\t\t\tstrokeWidth: 1.5,\n\t\t\t\tpoints: [\n\t\t\t\t\tmapImagePointToEditorPoint({ x: linesX, y: 0 }),\n\t\t\t\t\tmapImagePointToEditorPoint({ x: linesX, y: parentRect.height })\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\n\t\tif (linesY !== null) {\n\t\t\tyLine = {\n\t\t\t\tid: SnapShapeId,\n\t\t\t\tstrokeColor,\n\t\t\t\tstrokeWidth: 1.5,\n\t\t\t\tpoints: [\n\t\t\t\t\tmapImagePointToEditorPoint({ x: 0, y: linesY }),\n\t\t\t\t\tmapImagePointToEditorPoint({ x: parentRect.width, y: linesY })\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\n\t\tpushSnapShapes(xLine, yLine);\n\t};\n\n\t//#endregion\n\tconst togglePrerender = isActive => {\n\t\tif (!isActive) return updateMarkupShapeItems({ _prerender: false });\n\t\tconst shape = $shapes.find(markupItem => markupItem.isEditing);\n\t\tif (!shape) return;\n\t\tupdateMarkupShape(shape, { _prerender: textInputMode === 'inline' });\n\t};\n\n\tconst handleManipulatorResizeGrab = e => {\n\t\t$$invalidate(156, isInteracting = true);\n\t\t$$invalidate(155, interactionShape = activeMarkup);\n\t\tinteractionShapeOriginComputed = activeMarkupComputed;\n\t};\n\n\tconst handleManipulatorResizeDrag = e => {\n\t\t// is possible when using multiple fingers (scale canvas + drag / resize)\n\t\tif (!interactionShape) {\n\t\t\t$$invalidate(156, isInteracting = false);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { translation, indexes, shiftKey, ctrlKey, metaKey, isNudge } = e.detail;\n\n\t\t// if control or cmd pressed, prevent snapping\n\t\tconst preventSnap = ctrlKey || metaKey;\n\n\t\tresizeShape(interactionShape, interactionShapeOriginComputed, indexes, translation, {\n\t\t\t// anchor to opposite point\n\t\t\tshiftKey: isNudge ? false : shiftKey,\n\t\t\t// snap\n\t\t\t...getSnapOptions(preventSnap ? 0 : snapThreshold, gridSize, gridRect, interactionShape)\n\t\t});\n\n\t\t// deselect on move\n\t\tif (shapeCanSelectPoint(interactionShape) && vectorDistanceSquared(translation) > 16) {\n\t\t\tupdateMarkupShape(interactionShape, { selectedPoint: undefined });\n\t\t}\n\t};\n\n\tconst handleManipulatorResizeEnd = e => {\n\t\t// is possible when using multiple fingers (scale canvas + drag / resize)\n\t\tif (!interactionShape) {\n\t\t\t$$invalidate(156, isInteracting = false);\n\t\t\treturn;\n\t\t}\n\n\t\tselectShape(interactionShape);\n\t\tconst { isTap, translation, indexes } = e.detail;\n\n\t\tif (isTap) {\n\t\t\t// explicitely (de)select corner\n\t\t\tif (shapeCanSelectPoint(interactionShape)) {\n\t\t\t\tupdateMarkupShape(interactionShape, {\n\t\t\t\t\tselectedPoint: interactionShape.selectedPoint === indexes[0]\n\t\t\t\t\t? undefined\n\t\t\t\t\t: indexes[0]\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// tapped!\n\t\t\tontapshape(interactionShape);\n\t\t}\n\n\t\t$$invalidate(155, interactionShape = undefined);\n\t\t$$invalidate(156, isInteracting = false);\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\t// rotate\n\tconst handleManipulatorRotateGrab = e => {\n\t\trotatorInitialPosition = getShapeRotationPoint(activeMarkupComputed).origin;\n\t\t$$invalidate(156, isInteracting = true);\n\t\t$$invalidate(155, interactionShape = activeMarkup);\n\t\tinteractionShapeOriginComputed = activeMarkupComputed;\n\t};\n\n\tconst handleManipulatorRotateDrag = e => {\n\t\t// is possible when using multiple fingers (scale canvas + drag / resize)\n\t\tif (!interactionShape) {\n\t\t\t$$invalidate(156, isInteracting = false);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { translation, shiftKey } = e.detail;\n\t\trotateShape(interactionShape, interactionShapeOriginComputed, translation, { shiftKey });\n\t};\n\n\tconst handleManipulatorRotateEnd = () => {\n\t\t// is possible when using multiple fingers (scale canvas + drag / resize)\n\t\tif (!interactionShape) {\n\t\t\t$$invalidate(156, isInteracting = false);\n\t\t\treturn;\n\t\t}\n\n\t\tselectShape(interactionShape);\n\t\t$$invalidate(155, interactionShape = undefined);\n\t\t$$invalidate(156, isInteracting = false);\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\t// scale\n\tconst handleManipulatorScaleGrab = e => {\n\t\t$$invalidate(156, isInteracting = true);\n\t\t$$invalidate(155, interactionShape = activeMarkup);\n\t\tinteractionShapeOriginComputed = activeMarkupComputed;\n\t};\n\n\tconst handleManipulatorScaleDrag = e => {\n\t\t// is possible when using multiple fingers (scale canvas + drag / resize)\n\t\tif (!interactionShape) {\n\t\t\t$$invalidate(156, isInteracting = false);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { translation, ctrlKey, metaKey } = e.detail;\n\n\t\t// if control or cmd pressed, prevent snapping\n\t\tconst preventSnap = ctrlKey || metaKey;\n\n\t\tscaleShape(interactionShape, interactionShapeOriginComputed, translation, {\n\t\t\t// snap\n\t\t\t...getSnapOptions(preventSnap ? 0 : snapThreshold, gridSize, gridRect, interactionShape)\n\t\t});\n\t};\n\n\tconst handleManipulatorScaleEnd = () => {\n\t\t// is possible when using multiple fingers (scale canvas + drag / resize)\n\t\tif (!interactionShape) {\n\t\t\t$$invalidate(156, isInteracting = false);\n\t\t\treturn;\n\t\t}\n\n\t\tselectShape(interactionShape);\n\t\t$$invalidate(155, interactionShape = undefined);\n\t\t$$invalidate(156, isInteracting = false);\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\tconst handleKeyPressedStore = () => {\n\t\tconst [keyCode] = $keysPressedStored;\n\n\t\t// is not backspace or delete\n\t\tif (keyCode !== 8 && keyCode !== 46) return;\n\n\t\t// only handle key input if a shape has been selected\n\t\tif (!hasActiveMarkupItem()) return;\n\n\t\t// dont remove if is editing\n\t\tif (activeMarkup.isEditing) return;\n\n\t\t// can't remove this shape\n\t\tif (!shapeCanRemove(activeMarkup)) return;\n\n\t\t// ignore if focus is in text input\n\t\tif (isTextField(document.activeElement)) return;\n\n\t\t// if is path and has selected point\n\t\tif (shapeIsPath(activeMarkup) && isNumber(activeMarkup.selectedPoint)) {\n\t\t\tsetTimeout(() => removePointFromPath(activeMarkup, activeMarkup.selectedPoint), 0);\n\t\t\treturn;\n\t\t}\n\n\t\t// remove item\n\t\tsetTimeout(() => removeActiveMarkupItem(), 0);\n\t};\n\n\tconst handleKeyDown = e => {\n\t\t// get key type\n\t\tconst { key } = e;\n\n\t\tconst isEscape = (/escape/i).test(key);\n\t\t(/enter/i).test(key);\n\n\t\t// only handle key input if a shape has been selected\n\t\tif (!hasActiveMarkupItem()) return;\n\n\t\t// if is escape deselect active item\n\t\tif (isEscape) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\treturn deselectMarkupItem(activeMarkup);\n\t\t}\n\n\t\t// if is duplicate active shape keyboard shortcut\n\t\tif (allowShapeDuplicate && key === 'd' && (e.metaKey || e.ctrlKey)) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tduplicateActiveMarkup();\n\t\t}\n\t};\n\n\t//\n\t// Text input\n\t//\n\tlet textInput;\n\n\tconst getTextShapeOriginSnapshot = () => ({ ...activeMarkup });\n\n\t// when softkeyboard closes while text editing we confirm text\n\tsoftKeyboardState.subscribe(keyboardState => {\n\t\t// need to be in inline mode\n\t\tif (textInputMode !== 'inline') return;\n\n\t\t// confirm text if switching from visible to hidden while editing text\n\t\tif (activeMarkup && activeMarkup.isEditing && keyboardState === 'hidden') {\n\t\t\thandleTextConfirm();\n\t\t}\n\t});\n\n\tconst getTextInputTextStyles = (shapeComputed, mode) => {\n\t\tconst { textAlign = 'left', fontFamily = 'sans-serif', fontWeight = 'normal', fontStyle = 'normal', letterSpacing = 'normal', textShadowX = 0, textShadowY = 0, textShadowBlur = 0, textShadowColor = undefined, textOutlineWidth = 0, textOutlineColor = undefined } = shapeComputed;\n\t\tconst imp = '!important';\n\n\t\tconst cosmetic = `caret-color:${caretColorRGBA};text-align:${textAlign}${imp};font-family:${fontFamily}${imp};font-weight:${fontWeight}${imp};font-style:${fontStyle}${imp};letter-spacing:${isNumber(letterSpacing)\n\t\t? letterSpacing + 'px'\n\t\t: 'normal'}${imp}`;\n\n\t\tif (mode === 'modal') return cosmetic;\n\n\t\tconst textOutline = textOutlineWidth\n\t\t? `;-webkit-text-stroke:${textOutlineWidth * 2}px ${colorArrayToRGBA(textOutlineColor)} ${imp}`\n\t\t: '';\n\n\t\tconst textShadow = textShadowBlur || textShadowX || textShadowY\n\t\t? `;text-shadow:${textShadowX}px ${textShadowY}px ${textShadowBlur}px ${colorArrayToRGBA(textShadowColor)} ${imp}`\n\t\t: '';\n\n\t\tlet fontSize = shapeComputed.fontSize;\n\n\t\t// this is to work around Firefox 1000px limit on font-size\n\t\tlet fontScalar = 1;\n\n\t\tlet fontScalarStyles = '';\n\n\t\tif (fontSize > 1000 && isFirefox()) {\n\t\t\tfontScalar = fontSize / 1000;\n\t\t\tfontScalarStyles = `transform-origin:0 0;transform:scale(${fontScalar})`;\n\t\t\tfontSize = 1000;\n\t\t}\n\n\t\tlet lineHeight = shapeComputed.lineHeight / fontScalar;\n\t\tconst color = colorArrayToRGBA(shapeComputed.color);\n\t\tconst initialLineOffset = Math.max(0, fontSize - lineHeight) * 0.5;\n\t\treturn `--font-scalar:${fontScalar};--bottom-inset:${initialLineOffset}px;padding:${initialLineOffset}px 0 0${imp};color:${color}${imp};font-size:${fontSize}px${imp};line-height:${lineHeight}px${imp};${cosmetic};${fontScalarStyles}${textOutline}${textShadow}`;\n\t};\n\n\tconst getTextInputPositionStyles = (shapeComputed, offset, contextZoom, contextRotation) => {\n\t\tlet center;\n\t\tlet size;\n\n\t\tif (shapeComputed.width && shapeComputed.height) {\n\t\t\t// text box\n\t\t\tcenter = rectCenter(shapeComputed);\n\n\t\t\tsize = sizeCreateFromAny(shapeComputed);\n\t\t} else {\n\t\t\t// text line\n\t\t\tsize = textToSize(activeMarkup.text, activeMarkupComputed);\n\n\t\t\t// if has fix width, we'll use that\n\t\t\tsize.width = activeMarkupComputed.width || size.width;\n\n\t\t\tcenter = vectorCreate(shapeComputed.x + size.width * 0.5, shapeComputed.y + size.height * 0.5);\n\t\t}\n\n\t\tconst lineHeight = Math.max(0, shapeComputed.fontSize - shapeComputed.lineHeight) + shapeComputed.lineHeight;\n\t\tconst position = mapImagePointToEditorPoint(center);\n\t\tlet tx = position.x - offset.x - size.width * 0.5;\n\t\tlet ty = position.y - offset.y - size.height * 0.5;\n\t\tlet flipX = shapeComputed.flipX;\n\t\tlet flipY = shapeComputed.flipY;\n\t\tlet r = shapeComputed.rotation;\n\n\t\tif (contextFlipX && contextFlipY) {\n\t\t\tflipX = !flipX;\n\t\t\tflipY = !flipY;\n\t\t} else if (contextFlipX) {\n\t\t\tflipX = !flipX;\n\t\t\tr = -r;\n\t\t} else if (contextFlipY) {\n\t\t\tflipY = !flipY;\n\t\t\tr = -r;\n\t\t}\n\n\t\tr += contextRotation;\n\t\tconst sx = contextZoom * (flipX ? -1 : 1);\n\t\tconst sy = contextZoom * (flipY ? -1 : 1);\n\t\treturn `--line-height:${lineHeight}px;width:${size.width}px;height:${size.height}px;transform:translate(${tx}px,${ty}px) rotate(${r}rad) scale(${sx}, ${sy})`;\n\t};\n\n\t// sets the contenteditable text when user clicks text shape\n\tconst syncTextInput = () => updateTextInputValue(textInputText);\n\n\tconst updateTextInputValue = text => {\n\t\t$$invalidate(9, textInput.innerHTML = textToHTML(text), textInput);\n\t};\n\n\t// cleans up single line text\n\tconst removeLineBreaks = text => {\n\t\tconst lines = text.// split on lines so we can create compressed normal line of text\n\t\tsplit(/[\\n\\r]/g);\n\n\t\tif (lines.length > 1) {\n\t\t\treturn lines.// remove spaces around lines\n\t\t\tmap(str => str.trim()).// remove empty strings\n\t\t\tfilter(str => str.length).// create new line\n\t\t\tjoin(' ');\n\t\t}\n\n\t\t// just return line\n\t\treturn lines[0];\n\t};\n\n\tconst getTextInputValue = inputElement => {\n\t\tconst elementValue = inputElement.value === undefined\n\t\t? inputElement.innerHTML\n\t\t: inputElement.value;\n\n\t\tconst elementValueClean = activeMarkup.format === 'text'\n\t\t? htmlToText(elementValue)\n\t\t: elementValue;\n\n\t\tconst value = shapeIsTextBlock(activeMarkup) && activeMarkup.disableNewline !== false\n\t\t? removeLineBreaks(elementValueClean)\n\t\t: elementValueClean;\n\n\t\treturn value;\n\t};\n\n\tconst formatContentEditable = html => {\n\t\t// check if can input\n\t\tconst canInput = shapeCanInput(activeMarkup, html);\n\n\t\treturn canInput === true ? html : canInput;\n\t};\n\n\tconst handleTextInput = () => {\n\t\tconst value = getTextInputValue(textInput);\n\t\tconst canInput = shapeCanInput(activeMarkup, value);\n\t\tconst text = canInput === true ? value : canInput;\n\t\tlet x = textShapeDisplayOrigin.x;\n\t\tlet y = textShapeDisplayOrigin.y;\n\n\t\t// if does not have height we need to adjust offset if is rotated\n\t\tif (!activeMarkup.height) {\n\t\t\t// draw origin rect\n\t\t\tconst originRotatedRect = rectRotate({ ...textRectDisplayOrigin }, activeMarkup.rotation);\n\n\t\t\t// draw current rect\n\t\t\tconst size = textToSize(text, activeMarkupComputed);\n\n\t\t\tconst currentRotatedRect = rectRotate({ x, y, ...size }, activeMarkup.rotation);\n\t\t\tconst [originTopLeft, ,originBottomRight] = originRotatedRect;\n\t\t\tconst [currentTopLeft, ,currentBottomRight] = currentRotatedRect;\n\t\t\tlet a = originTopLeft;\n\t\t\tlet b = currentTopLeft;\n\n\t\t\t// if flipped we need to 'extend' the text field in the opposite direction\n\t\t\tif (activeMarkup.flipX) {\n\t\t\t\ta = originBottomRight;\n\t\t\t\tb = currentBottomRight;\n\t\t\t}\n\n\t\t\t// move\n\t\t\tconst d = vectorSubtract(vectorClone(a), b);\n\n\t\t\tx += d.x;\n\t\t\ty += d.y;\n\t\t}\n\n\t\tupdateShape(activeMarkup, { x, y, text }, parentRect);\n\t\tsyncShapes();\n\t};\n\n\tconst handleTextInputAttempt = e => {\n\t\tconst { target, key } = e;\n\t\tconst currentValue = target.value || target.innerText;\n\t\tconst selectionStart = target.selectionStart || 0;\n\t\tconst selectionEnd = target.selectionEnd || currentValue.length;\n\t\tconst currentValueStart = currentValue.substring(0, selectionStart);\n\t\tconst currentValueEnd = currentValue.substring(selectionEnd);\n\t\tconst intendedValue = currentValueStart + key + currentValueEnd;\n\t\tconst filteredValue = shapeCanInput(activeMarkup, intendedValue);\n\t\tif (filteredValue !== intendedValue) return e.preventDefault();\n\t};\n\n\t// prevent moving shape when focusing text field, and close field if escape pressed\n\tconst handleTextInputKeyDown = e => {\n\t\t// block newlines for auto width text that doesn't allow newlines\n\t\tif (shapeIsTextBlock(activeMarkup) && (/enter/i).test(e.key) && activeMarkup.disableNewline !== false) {\n\t\t\treturn e.preventDefault();\n\t\t}\n\n\t\tif ((/arrow/i).test(e.code)) {\n\t\t\treturn e.stopPropagation();\n\t\t}\n\n\t\tif ((/escape/i).test(e.key)) {\n\t\t\treturn handleTextCancel();\n\t\t}\n\t};\n\n\tconst isTextConfirmKeyCombination = e => {\n\t\tconst { key, ctrlKey, metaKey, altKey } = e;\n\t\treturn key === 'Enter' && (ctrlKey || altKey || metaKey);\n\t};\n\n\t// handle alt/ctrl/cmd + return\n\tconst handleTextInputKeyUp = e => {\n\t\t// is confirm text combo\n\t\tif (!isTextConfirmKeyCombination(e)) return;\n\n\t\t// confirm multi line text elements\n\t\treturn handleTextConfirm();\n\t};\n\n\tconst handleTextConfirm = () => {\n\t\tif (activeShapeIsDraft) confirmMarkupItemDraft();\n\n\t\t// final text input check\n\t\ttextInput && textInput.confirm && textInput.confirm();\n\n\t\ttextInput && handleTextInput();\n\n\t\t// done\n\t\tfinishEditMarkupItem(activeMarkup);\n\n\t\t// if (wasDraft) onaddshape(activeMarkup);\n\t\t// else\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\tconst handleTextCancel = () => {\n\t\tif (activeShapeIsDraft) {\n\t\t\tdiscardMarkupItemDraft();\n\t\t} else {\n\t\t\tupdateMarkupShape(activeMarkup, {\n\t\t\t\ttext: textShapeOrigin.text,\n\t\t\t\tx: textShapeOrigin.x,\n\t\t\t\ty: textShapeOrigin.y\n\t\t\t});\n\n\t\t\tfinishEditMarkupItem(activeMarkup);\n\t\t}\n\t};\n\n\t//#region shape popup menu actions\n\tconst getShapeSizeTranslation = (originRect, targetRect, { flipX, flipY, rotation }, anchor = 'top left') => {\n\t\tlet a, b;\n\n\t\t// draw origin rect\n\t\tconst [originTopLeft, originTopRight, originBottomRight, originBottomLeft] = rectRotate(originRect, rotation);\n\n\t\t// draw target rect\n\t\tconst [targetTopLeft, targetTopRight, targetBottomRight, targetBottomLeft] = rectRotate(targetRect, rotation);\n\n\t\tif (anchor === 'top center') {\n\t\t\t// for now doesn't matter if it's flipped horizontal\n\t\t\tconst originMid = vectorCenter(flipY\n\t\t\t? [originBottomLeft, originBottomRight]\n\t\t\t: [originTopLeft, originTopRight]);\n\n\t\t\tconst targetMid = vectorCenter(flipY\n\t\t\t? [targetBottomLeft, targetBottomRight]\n\t\t\t: [targetTopLeft, targetTopRight]);\n\n\t\t\ta = originMid;\n\t\t\tb = targetMid;\n\t\t} else if (anchor === 'top right' && !flipX || anchor === 'top left' && flipX) {\n\t\t\t// tr\n\t\t\ta = flipY ? originBottomRight : originTopRight;\n\n\t\t\tb = flipY ? targetBottomRight : targetTopRight;\n\t\t} else {\n\t\t\t// tl\n\t\t\ta = flipY ? originBottomLeft : originTopLeft;\n\n\t\t\tb = flipY ? targetBottomLeft : targetTopLeft;\n\t\t}\n\n\t\treturn vectorSubtract(vectorClone(a), b);\n\t};\n\n\tconst translateRelative = (current, position, translation) => vectorCreate(\n\t\tisString(current.x)\n\t\t? toPercentage(position.x + translation.x, parentRect.width)\n\t\t: position.x + translation.x,\n\t\tisString(current.y)\n\t\t? toPercentage(position.y + translation.y, parentRect.height)\n\t\t: position.y + translation.y\n\t);\n\n\tconst ShapeTextStateCache = {};\n\tconst handleRemovePointActiveMarkup = () => removePointFromPath(activeMarkup, activeMarkup.selectedPoint);\n\tconst handleEditTextActiveMarkup = () => editMarkupItem(activeMarkup);\n\n\tconst toAutoWidth = (sizeFrom, target, targetComputed) => {\n\t\t// remove width and height props\n\t\tconst { width, height, ...autoSizeProps } = targetComputed;\n\n\t\tconst sizeTo = textToSize(target.text, autoSizeProps);\n\n\t\t// this will change dimensions so if rotated we have to calculate new position\n\t\tconst translation = getShapeSizeTranslation(rectCreate(targetComputed.x, targetComputed.y, sizeFrom.width, sizeFrom.height), rectCreate(targetComputed.x, targetComputed.y, sizeTo.width, sizeTo.height), targetComputed, `top ${target.textAlign}`);\n\n\t\tconst shouldRemoveTextAlign = targetComputed.disableNewline !== false;\n\n\t\t// switch to auto mode\n\t\tremoveMarkupShapeProps(target, ['width', 'height', shouldRemoveTextAlign && 'textAlign']);\n\n\t\t// update position based on size translation\n\t\tupdateMarkupShape(target, {\n\t\t\t...translateRelative(target, targetComputed, translation)\n\t\t});\n\t};\n\n\tconst toAutoHeight = (sizeFrom, target, targetComputed, shapeSize, cache = {}) => {\n\t\t// -> switch to auto height mode\n\t\tconst { height, ...computedMarkup } = targetComputed;\n\n\t\tconst shapeAutoTextSize = sizeApply(textToSize(target.text, computedMarkup), v => Math.ceil(v));\n\t\tconst sizeTo = sizeCreate(cache.width || targetComputed.width || shapeSize.width, shapeAutoTextSize.height);\n\t\tconst textAlign = cache.textAlign || 'left';\n\n\t\t// this will change dimensions so if rotated we have to calculate new position\n\t\tconst translation = getShapeSizeTranslation(rectCreate(targetComputed.x, targetComputed.y, sizeFrom.width, sizeFrom.height), rectCreate(targetComputed.x, targetComputed.y, sizeTo.width, sizeTo.height), targetComputed, `top ${textAlign}`);\n\n\t\t// switch to auto-height mode\n\t\tremoveMarkupShapeProps(target, ['height']);\n\n\t\t// update position based on size translation\n\t\tupdateMarkupShape(target, {\n\t\t\t...translateRelative(target, targetComputed, translation),\n\t\t\twidth: isString(target.width)\n\t\t\t? toPercentage(sizeTo.width, parentRect.width)\n\t\t\t: sizeTo.width,\n\t\t\ttextAlign\n\t\t});\n\t};\n\n\tconst toFixedSize = (sizeFrom, target, targetComputed, shapeSize, cache = {}) => {\n\t\t// this can change dimensions so we need to recalculate position\n\t\tconst sizeTo = sizeCreate(cache.width || shapeSize.width, cache.height || shapeSize.height);\n\n\t\tconst textAlign = cache.textAlign || 'left';\n\n\t\t// this will change dimensions so if rotated we have to calculate new position\n\t\tconst translation = getShapeSizeTranslation(rectCreate(targetComputed.x, targetComputed.y, sizeFrom.width, sizeFrom.height), rectCreate(targetComputed.x, targetComputed.y, sizeTo.width, sizeTo.height), targetComputed, `top ${textAlign}`);\n\n\t\t// switch to fixed box, use stored alignment or default to left text align\n\t\tupdateMarkupShape(target, {\n\t\t\t...translateRelative(target, targetComputed, translation),\n\t\t\twidth: isString(target.width)\n\t\t\t? toPercentage(sizeTo.width, parentRect.width)\n\t\t\t: sizeTo.width,\n\t\t\theight: isString(target.width)\n\t\t\t? toPercentage(sizeTo.height, parentRect.height)\n\t\t\t: sizeTo.height,\n\t\t\ttextAlign\n\t\t});\n\t};\n\n\tconst handleTextSwitchLayout = () => {\n\t\tconst currentShapeSize = sizeApply(textToSize(activeMarkup.text, activeMarkupComputed), v => Math.ceil(v));\n\t\tconst isFixedBox = hasProp(activeMarkup, 'height');\n\t\tconst isAutoHeightBox = !isFixedBox && hasProp(activeMarkup, 'width');\n\n\t\t// set/get cache entries for this text shape\n\t\tconst key = activeMarkup.id;\n\n\t\tlet cache = ShapeTextStateCache[key];\n\n\t\tif (!cache) {\n\t\t\tShapeTextStateCache[key] = {};\n\t\t\tcache = ShapeTextStateCache[key];\n\t\t}\n\n\t\tif (isFixedBox) {\n\t\t\t// store size so we can restore it later\n\t\t\tcache.textAlign = activeMarkup.textAlign;\n\n\t\t\tcache.width = activeMarkupComputed.width;\n\t\t\tcache.height = activeMarkupComputed.height;\n\t\t\tconst sizeFrom = sizeCreate(activeMarkupComputed.width, activeMarkupComputed.height);\n\n\t\t\tif (shapeCanChangeTextLayout(activeMarkup, 'auto-height')) {\n\t\t\t\ttoAutoHeight(sizeFrom, activeMarkup, activeMarkupComputed, currentShapeSize, cache);\n\t\t\t} else if (shapeCanChangeTextLayout(activeMarkup, 'auto-width')) {\n\t\t\t\ttoAutoWidth(sizeFrom, activeMarkup, activeMarkupComputed);\n\t\t\t}\n\t\t} else if (isAutoHeightBox) {\n\t\t\t// store alignment so we can restore it later\n\t\t\tcache.textAlign = activeMarkup.textAlign;\n\n\t\t\tcache.width = activeMarkupComputed.width;\n\n\t\t\t// -> switch to auto width\n\t\t\tconst sizeFrom = sizeCreate(activeMarkupComputed.width, currentShapeSize.height);\n\n\t\t\tif (shapeCanChangeTextLayout(activeMarkup, 'auto-width')) {\n\t\t\t\ttoAutoWidth(sizeFrom, activeMarkup, activeMarkupComputed);\n\t\t\t} else if (shapeCanChangeTextLayout(activeMarkup, 'fixed-size')) {\n\t\t\t\ttoFixedSize(sizeFrom, activeMarkup, activeMarkupComputed, currentShapeSize, cache);\n\t\t\t}\n\t\t} else {\n\t\t\t// -> switch to fixed size or auto height\n\t\t\tcache.textAlign = activeMarkup.textAlign || cache.textAlign;\n\n\t\t\tconst sizeFrom = sizeCreate(Math.ceil(currentShapeSize.width), Math.ceil(currentShapeSize.height));\n\n\t\t\tif (shapeCanChangeTextLayout(activeMarkup, 'fixed-size')) {\n\t\t\t\ttoFixedSize(sizeFrom, activeMarkup, activeMarkupComputed, currentShapeSize, cache);\n\t\t\t} else if (shapeCanChangeTextLayout(activeMarkup, 'auto-height')) {\n\t\t\t\ttoAutoHeight(sizeFrom, activeMarkup, activeMarkupComputed, currentShapeSize, cache);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleFlipX = e => {\n\t\te.stopPropagation();\n\t\tconst flipX = activeMarkup.flipX || false;\n\t\tupdateMarkupShapeProperty(activeMarkup, 'flipX', !flipX);\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\tconst handleFlipY = e => {\n\t\te.stopPropagation();\n\t\tconst flipY = activeMarkup.flipY || false;\n\t\tupdateMarkupShapeProperty(activeMarkup, 'flipY', !flipY);\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\tconst handleAdjustOpacity = value => {\n\t\tupdateMarkupShapeProperty(activeMarkup, 'opacity', value);\n\t};\n\n\tconst handleConfirmOpacity = value => {\n\t\thandleAdjustOpacity(value);\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\tconst handleRemoveActiveMarkup = e => {\n\t\te.stopPropagation();\n\t\te.target.blur(); // cancels focus of remove button\n\t\tremoveActiveMarkupItem();\n\t};\n\n\tconst handleMoveToFrontActiveMarkup = e => {\n\t\te.stopPropagation();\n\n\t\t// test if is not already at top of stack, if so, exit\n\t\tconst index = $shapes.findIndex(shape => shape === activeMarkup);\n\n\t\tif (index === $shapes.length - 1) return;\n\n\t\t// add to last index\n\t\tshapes.set($shapes.filter(markupItem => markupItem !== activeMarkup).concat([activeMarkup]));\n\n\t\tonupdateshape(activeMarkup);\n\t};\n\n\tconst handleDuplicateActiveMarkup = e => {\n\t\te.stopPropagation();\n\t\tduplicateActiveMarkup();\n\t};\n\n\tconst duplicateActiveMarkup = () => {\n\t\tconst originals = isMultiSelection ? multiSelection : [activeMarkup];\n\n\t\tconst duplicates = originals.filter(shapeCanDuplicate).map(originalShape => {\n\t\t\t// create clone\n\t\t\tconst clone = shapeDeepCopy(originalShape);\n\n\t\t\tclone.id = getUniqueId();\n\t\t\tconst duplicationOffset = vectorCreate(50, -50);\n\n\t\t\t// offset\n\t\t\tif (hasProp(clone, 'points')) {\n\t\t\t\tconst computedProps = shapeGetPropsPixelValues(clone, ['points'], parentRect);\n\n\t\t\t\tcomputedProps.points.forEach(point => {\n\t\t\t\t\tpoint.x += duplicationOffset.x;\n\t\t\t\t\tpoint.y += duplicationOffset.y;\n\t\t\t\t});\n\n\t\t\t\tshapeUpdateProps(clone, computedProps, parentRect);\n\t\t\t} else if (shapeIsLine(clone)) {\n\t\t\t\tconst computedProps = shapeGetPropsPixelValues(clone, ['x1', 'y1', 'x2', 'y2'], parentRect);\n\t\t\t\tcomputedProps.x1 += duplicationOffset.x;\n\t\t\t\tcomputedProps.y1 += duplicationOffset.y;\n\t\t\t\tcomputedProps.x2 += duplicationOffset.x;\n\t\t\t\tcomputedProps.y2 += duplicationOffset.y;\n\t\t\t\tshapeUpdateProps(clone, computedProps, parentRect);\n\t\t\t} else {\n\t\t\t\tconst currentPosition = shapeGetPropsPixelValues(clone, ['x', 'y'], parentRect);\n\t\t\t\tcurrentPosition.x += 50;\n\t\t\t\tcurrentPosition.y -= 50;\n\t\t\t\tshapeUpdateProps(clone, currentPosition, parentRect);\n\t\t\t}\n\n\t\t\t// add clone\n\t\t\tshapes.set([...$shapes, clone]);\n\n\t\t\t// added\n\t\t\tonaddshape(clone);\n\n\t\t\treturn clone;\n\t\t});\n\n\t\tif (duplicates.length > 1) {\n\t\t\tblurShapes();\n\n\t\t\tduplicates.forEach(shape => {\n\t\t\t\tselectShape(shape, true, true);\n\t\t\t});\n\n\t\t\treturn;\n\t\t}\n\n\t\t// select clone\n\t\tselectShape(duplicates[0]);\n\t};\n\n\t//#endregion\n\t//\n\t// show & position markup controls panel\n\t//\n\tconst markupControlsOpacity = spring(0, { stiffness: 0.2, damping: 0.7 });\n\n\tcomponent_subscribe($$self, markupControlsOpacity, value => $$invalidate(22, $markupControlsOpacity = value));\n\n\tconst getMarkupControlsAnchorPosition = rect => {\n\t\treturn vectorApply(vectorCreate(rect.x + rect.width * 0.5, rect.y), snapToPixel);\n\t};\n\n\tlet shapeControlsSize;\n\n\tconst getShapeControlPositionOnCanvas = (utilRect, position, controlSize, yOffset) => {\n\t\tconst left = utilRect.x;\n\t\tconst top = utilRect.y;\n\t\tconst right = left + utilRect.width;\n\t\tlet x = Math.max(position.x - controlSize.width * 0.5, left);\n\t\tlet y = Math.max(position.y - controlSize.height + yOffset, top);\n\t\tif (x + controlSize.width > right) x = right - controlSize.width;\n\t\treturn vectorCreate(x, y);\n\t};\n\n\tconst TextLayoutChangeIcon = (locale, shape) => {\n\t\tconst { disableTextLayout = [] } = shape;\n\n\t\t// is fixed size\n\t\tif ('height' in shape) {\n\t\t\tif (disableTextLayout.includes('auto-height')) {\n\t\t\t\t// next is auto-width, no need to set as is empty\n\t\t\t\treturn locale.shapeIconButtonTextLayoutAutoWidth;\n\t\t\t} else {\n\t\t\t\t// next is auto-height\n\t\t\t\treturn locale.shapeIconButtonTextLayoutAutoHeight;\n\t\t\t}\n\t\t} else // is auto-height\n\t\tif ('width' in shape) {\n\t\t\tif (disableTextLayout.includes('auto-width')) {\n\t\t\t\t// next is fixed-size\n\t\t\t\treturn locale.shapeIconButtonTextLayoutFixedSize;\n\t\t\t} else {\n\t\t\t\t// next is auto-width, no need to set as is empty\n\t\t\t\treturn locale.shapeIconButtonTextLayoutAutoWidth;\n\t\t\t}\n\t\t} else // is auto-width\n\t\t{\n\t\t\t// next is fixed-size\n\t\t\tif (disableTextLayout.includes('fixed-size')) {\n\t\t\t\t// next is fixed-size\n\t\t\t\treturn locale.shapeIconButtonTextLayoutAutoHeight;\n\t\t\t} else {\n\t\t\t\t// next is auto-width, no need to set as is empty\n\t\t\t\treturn locale.shapeIconButtonTextLayoutFixedSize;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst TextLayoutChangeLabel = (locale, shape) => {\n\t\tconst { disableTextLayout = [] } = shape;\n\n\t\t// is fixed size\n\t\tif ('height' in shape) {\n\t\t\tif (disableTextLayout.includes('auto-height')) {\n\t\t\t\t// next is auto-width, no need to set as is empty\n\t\t\t\treturn locale.shapeTitleButtonTextLayoutAutoWidth;\n\t\t\t} else {\n\t\t\t\t// next is auto-height\n\t\t\t\treturn locale.shapeTitleButtonTextLayoutAutoHeight;\n\t\t\t}\n\t\t} else // is auto-height\n\t\tif ('width' in shape) {\n\t\t\tif (disableTextLayout.includes('auto-width')) {\n\t\t\t\t// next is fixed-size\n\t\t\t\treturn locale.shapeTitleButtonTextLayoutFixedSize;\n\t\t\t} else {\n\t\t\t\t// next is auto-width, no need to set as is empty\n\t\t\t\treturn locale.shapeTitleButtonTextLayoutAutoWidth;\n\t\t\t}\n\t\t} else // is auto-width\n\t\t{\n\t\t\t// next is fixed-size\n\t\t\tif (disableTextLayout.includes('fixed-size')) {\n\t\t\t\t// next is fixed-size\n\t\t\t\treturn locale.shapeTitleButtonTextLayoutAutoHeight;\n\t\t\t} else {\n\t\t\t\t// next is auto-width, no need to set as is empty\n\t\t\t\treturn locale.shapeTitleButtonTextLayoutFixedSize;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleNudge = e => {\n\t\tconst shapes = getActiveMarkupItems();\n\t\tif (!shapes) return;\n\t\tif (shapes.find(shapeIsTextEditing)) return;\n\t\tif (shapes.find(shape => !shapeCanMove(shape))) return;\n\n\t\tshapes.forEach(shape => {\n\t\t\t$$invalidate(155, interactionShape = shape);\n\t\t\tinteractionShapeOriginComputed = shapeComputeDisplay(shapeDeepCopy(interactionShape), parentRect);\n\t\t\ttranslateShape(interactionShape, interactionShapeOriginComputed, e.detail);\n\t\t});\n\t};\n\n\t// shape navigator\n\tlet showShapeList = false;\n\n\tconst handleFocusIn = e => {\n\t\t$$invalidate(23, showShapeList = true);\n\t};\n\n\tconst handleFocusOut = ({ relatedTarget }) => {\n\t\t// still in list\n\t\tif (relatedTarget && relatedTarget.classList.contains('shape-selector__button')) return;\n\n\t\t$$invalidate(23, showShapeList = false);\n\t};\n\n\t// change cursor style\n\tlet lastImagePosition = vectorCreateEmpty();\n\n\tlet pointerPositionInEditor = undefined;\n\n\tconst handlePointerMove = e => {\n\t\t// not handled for touch interaction\n\t\tif (e.pointerType === 'touch' || e.target.className !== 'PinturaShapeEditor') {\n\t\t\tonleavecanvas();\n\t\t\treturn;\n\t\t}\n\n\t\t// if interactionTimer is set an interaction was started\n\t\tif (isInteracting || interactionTimer) {\n\t\t\tsetHoverShape(undefined);\n\t\t}\n\n\t\tconst editorPosition = getEventPositionInEditor(e, rootRect);\n\n\t\t// current position in editor\n\t\t$$invalidate(159, pointerPositionInEditor = vectorClone(editorPosition));\n\n\t\tconst imagePosition = vectorApply(mapEditorPointToImagePoint(editorPosition), v => Math.round(v));\n\n\t\tif (vectorEqual(imagePosition, lastImagePosition)) {\n\t\t\treturn;\n\t\t}\n\n\t\t$$invalidate(158, lastImagePosition = vectorClone(imagePosition));\n\t\tonhovercanvas(isInteracting, editorPosition, imagePosition);\n\n\t\tif (isInteracting || interactionTimer) {\n\t\t\treturn;\n\t\t}\n\n\t\t// no hover effect when creating markup\n\t\tif (activeMarkupItemIsDraft || getSelectionItemDraft()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst [shape] = getShapesNearPosition($shapes, imagePosition, 0, shapeCanSelect);\n\n\t\t// can't hover draft\n\t\tif (shape && shapeIsDraft(shape)) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetHoverShape(shape);\n\t};\n\n\tconst setHoverShape = shape => {\n\t\t// let others know we're hovering this shape\n\t\tonhovershape(shape);\n\n\t\t// update interface\n\t\t$$invalidate(157, hoverShape = shape);\n\t};\n\n\tconst handlePointerLeave = e => {\n\t\t// not handled for touch interaction\n\t\tif (e.pointerType === 'touch') return;\n\n\t\tonleavecanvas();\n\t};\n\n\tconst selectShapeByIndex = index => {\n\t\tselectShape($shapes[index]);\n\t};\n\n\t//\n\t// handle Apple Pencil, without this hack there's a delay between taps\n\t//\n\tlet element;\n\n\tfunction handleTouchmove(e) {\n\t\tif (isApplePencilEvent(e) && e.target === element) {\n\t\t\te.preventDefault();\n\t\t}\n\t}\n\n\t// clean up\n\tonDestroy(() => {\n\t\tpopSnapShapes();\n\t\tpopGridShapes();\n\t\tpopManipulatorShapes();\n\t\tpopHoverShapes();\n\t\telement.removeEventListener('touchmove', handleTouchmove, false);\n\t});\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\tconst click_handler = index => selectShapeByIndex(index);\n\n\tfunction textarea_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\ttextInput = $$value;\n\t\t\t$$invalidate(9, textInput);\n\t\t});\n\t}\n\n\tfunction textarea_input_handler() {\n\t\ttextInputText = this.value;\n\t\t((((($$invalidate(28, textInputText), $$invalidate(14, shouldRenderTextInput)), $$invalidate(13, activeMarkup)), $$invalidate(183, isTextMarkupSelected)), $$invalidate(0, disabled)), $$invalidate(199, $shapes));\n\t}\n\n\tconst func = e => {\n\t\tconst { key } = e;\n\n\t\tif (key === 'Enter') {\n\t\t\t// if is combo, always confirm\n\t\t\tif (isTextConfirmKeyCombination(e)) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\t// if can enter newlines a normal return doesn't confirm the text input\n\t\t\tif (activeMarkup.disableNewline === false) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tfunction contenteditable_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\ttextInput = $$value;\n\t\t\t$$invalidate(9, textInput);\n\t\t});\n\t}\n\n\tconst focusout_handler = () => {\n\t\t// need to focus root shape editor node as otherwise next escape press closes modal when in modal\n\t\telement && element.focus();\n\t};\n\n\tconst measure_handler_1 = e => $$invalidate(10, shapeControlsSize = e.detail);\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\telement = $$value;\n\t\t\t$$invalidate(11, element);\n\t\t});\n\t}\n\n\tconst interactable_function_1 = e => getEventPositionInEditor(e, rootRect);\n\n\t$$self.$$set = $$props => {\n\t\tif ('uid' in $$props) $$invalidate(68, uid = $$props.uid);\n\t\tif ('ui' in $$props) $$invalidate(69, ui = $$props.ui);\n\t\tif ('disabled' in $$props) $$invalidate(0, disabled = $$props.disabled);\n\t\tif ('shapes' in $$props) $$subscribe_shapes($$invalidate(1, shapes = $$props.shapes));\n\t\tif ('selection' in $$props) $$subscribe_selection($$invalidate(2, selection = $$props.selection));\n\t\tif ('offset' in $$props) $$invalidate(3, offset = $$props.offset);\n\t\tif ('contextRotation' in $$props) $$invalidate(70, contextRotation = $$props.contextRotation);\n\t\tif ('contextFlipX' in $$props) $$invalidate(71, contextFlipX = $$props.contextFlipX);\n\t\tif ('contextFlipY' in $$props) $$invalidate(72, contextFlipY = $$props.contextFlipY);\n\t\tif ('contextZoom' in $$props) $$invalidate(73, contextZoom = $$props.contextZoom);\n\t\tif ('active' in $$props) $$invalidate(74, active = $$props.active);\n\t\tif ('opacity' in $$props) $$invalidate(75, opacity = $$props.opacity);\n\t\tif ('parentRect' in $$props) $$invalidate(76, parentRect = $$props.parentRect);\n\t\tif ('rootRect' in $$props) $$invalidate(4, rootRect = $$props.rootRect);\n\t\tif ('utilRect' in $$props) $$invalidate(5, utilRect = $$props.utilRect);\n\t\tif ('hoverColor' in $$props) $$invalidate(77, hoverColor = $$props.hoverColor);\n\t\tif ('caretColor' in $$props) $$invalidate(78, caretColor = $$props.caretColor);\n\t\tif ('gridColor' in $$props) $$invalidate(79, gridColor = $$props.gridColor);\n\t\tif ('snapColor' in $$props) $$invalidate(80, snapColor = $$props.snapColor);\n\t\tif ('textInputMode' in $$props) $$invalidate(6, textInputMode = $$props.textInputMode);\n\t\tif ('oninteractionstart' in $$props) $$invalidate(81, oninteractionstart = $$props.oninteractionstart);\n\t\tif ('oninteractionupdate' in $$props) $$invalidate(82, oninteractionupdate = $$props.oninteractionupdate);\n\t\tif ('oninteractionrelease' in $$props) $$invalidate(83, oninteractionrelease = $$props.oninteractionrelease);\n\t\tif ('oninteractionend' in $$props) $$invalidate(84, oninteractionend = $$props.oninteractionend);\n\t\tif ('oninteractioncancel' in $$props) $$invalidate(85, oninteractioncancel = $$props.oninteractioncancel);\n\t\tif ('onaddshape' in $$props) $$invalidate(86, onaddshape = $$props.onaddshape);\n\t\tif ('onupdateshape' in $$props) $$invalidate(87, onupdateshape = $$props.onupdateshape);\n\t\tif ('onselectshape' in $$props) $$invalidate(88, onselectshape = $$props.onselectshape);\n\t\tif ('onblurshape' in $$props) $$invalidate(89, onblurshape = $$props.onblurshape);\n\t\tif ('onremoveshape' in $$props) $$invalidate(90, onremoveshape = $$props.onremoveshape);\n\t\tif ('ontapshape' in $$props) $$invalidate(91, ontapshape = $$props.ontapshape);\n\t\tif ('onhovershape' in $$props) $$invalidate(92, onhovershape = $$props.onhovershape);\n\t\tif ('ontriggerhistorywrite' in $$props) $$invalidate(93, ontriggerhistorywrite = $$props.ontriggerhistorywrite);\n\t\tif ('onhovercanvas' in $$props) $$invalidate(94, onhovercanvas = $$props.onhovercanvas);\n\t\tif ('ontapcanvas' in $$props) $$invalidate(95, ontapcanvas = $$props.ontapcanvas);\n\t\tif ('onleavecanvas' in $$props) $$invalidate(96, onleavecanvas = $$props.onleavecanvas);\n\t\tif ('beforeSelectShape' in $$props) $$invalidate(97, beforeSelectShape = $$props.beforeSelectShape);\n\t\tif ('beforeDeselectShape' in $$props) $$invalidate(98, beforeDeselectShape = $$props.beforeDeselectShape);\n\t\tif ('beforeRemoveShape' in $$props) $$invalidate(99, beforeRemoveShape = $$props.beforeRemoveShape);\n\t\tif ('beforeUpdateShape' in $$props) $$invalidate(100, beforeUpdateShape = $$props.beforeUpdateShape);\n\t\tif ('willRenderShapeControls' in $$props) $$invalidate(101, willRenderShapeControls = $$props.willRenderShapeControls);\n\t\tif ('willRenderShapeTextControls' in $$props) $$invalidate(102, willRenderShapeTextControls = $$props.willRenderShapeTextControls);\n\t\tif ('willStartInteraction' in $$props) $$invalidate(103, willStartInteraction = $$props.willStartInteraction);\n\t\tif ('mapEditorPointToImagePoint' in $$props) $$invalidate(104, mapEditorPointToImagePoint = $$props.mapEditorPointToImagePoint);\n\t\tif ('mapImagePointToEditorPoint' in $$props) $$invalidate(105, mapImagePointToEditorPoint = $$props.mapImagePointToEditorPoint);\n\t\tif ('eraseRadius' in $$props) $$invalidate(106, eraseRadius = $$props.eraseRadius);\n\t\tif ('selectRadius' in $$props) $$invalidate(107, selectRadius = $$props.selectRadius);\n\t\tif ('enableButtonFlipVertical' in $$props) $$invalidate(108, enableButtonFlipVertical = $$props.enableButtonFlipVertical);\n\t\tif ('enableTapToAddText' in $$props) $$invalidate(109, enableTapToAddText = $$props.enableTapToAddText);\n\t\tif ('enableMultiSelect' in $$props) $$invalidate(110, enableMultiSelect = $$props.enableMultiSelect);\n\t\tif ('enableTextStyleControls' in $$props) $$invalidate(7, enableTextStyleControls = $$props.enableTextStyleControls);\n\t\tif ('locale' in $$props) $$invalidate(8, locale = $$props.locale);\n\t\tif ('snapThreshold' in $$props) $$invalidate(111, snapThreshold = $$props.snapThreshold);\n\t\tif ('snapPointer' in $$props) $$invalidate(112, snapPointer = $$props.snapPointer);\n\t\tif ('enableSnapToContext' in $$props) $$invalidate(113, enableSnapToContext = $$props.enableSnapToContext);\n\t\tif ('gridSize' in $$props) $$invalidate(114, gridSize = $$props.gridSize);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[2] & /*parentRect*/ 16384 | $$self.$$.dirty[3] & /*gridSize*/ 2097152) {\n\t\t\t// redraw grid lines\n\t\t\t$$invalidate(185, gridRect = gridSize > 0 ? { x: 0, y: 0, ...parentRect } : undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*disabled*/ 1 | $$self.$$.dirty[6] & /*$shapes*/ 8192) {\n\t\t\t$$invalidate(13, activeMarkup = !disabled && $shapes && (getMarkupItemDraft() || getActiveMarkupItem()));\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*enableMultiSelect*/ 131072 | $$self.$$.dirty[6] & /*$shapes*/ 8192) {\n\t\t\t$$invalidate(177, multiSelection = enableMultiSelect ? $shapes.filter(shapeIsSelected) : []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*multiSelection*/ 4194304) {\n\t\t\t$$invalidate(176, isMultiSelection = multiSelection.length > 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[2] & /*parentRect*/ 16384 | $$self.$$.dirty[5] & /*isMultiSelection, multiSelection*/ 6291456) {\n\t\t\t$$invalidate(198, multiSelectionComputed = isMultiSelection\n\t\t\t? multiSelection.map(shape => shapeComputeDisplay(shapeDeepCopy(shape), parentRect))\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192) {\n\t\t\t$$invalidate(195, activeMarkupSelected = !!activeMarkup);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192) {\n\t\t\t$$invalidate(179, activeShapeIsDraft = activeMarkup && shapeIsDraft(activeMarkup));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*activeShapeIsDraft*/ 16777216) {\n\t\t\t$$invalidate(12, activeShapeId = activeMarkup && !activeShapeIsDraft\n\t\t\t? activeMarkup.id\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*rootRect, activeMarkup*/ 8208 | $$self.$$.dirty[2] & /*parentRect*/ 16384) {\n\t\t\t// rootRect is in there so it recomputes the shape when the editor is resized\n\t\t\t$$invalidate(16, activeMarkupComputed = rootRect && activeMarkup && shapeComputeDisplay(shapeDeepCopy(activeMarkup), parentRect));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*activeShapeIsDraft*/ 16777216) {\n\t\t\t$$invalidate(160, activeMarkupItemIsDraft = !!(activeMarkup && activeShapeIsDraft));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup, activeMarkupComputed*/ 73728 | $$self.$$.dirty[2] & /*opacity*/ 8192) {\n\t\t\t// $: shapeProps = activeMarkup || undefined;\n\t\t\t// TODO: we use opacity to trigger a redraw of the active points, this should be changed to the image zoom factor in a future release\n\t\t\t//  && !shapeIsPath(activeMarkupComputed)\n\t\t\t$$invalidate(193, shapeActivePoints = activeMarkup && opacity && getMarkupShapePoints(activeMarkupComputed) || []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*isMultiSelection*/ 2097152 | $$self.$$.dirty[6] & /*multiSelectionComputed*/ 4096) {\n\t\t\t$$invalidate(189, multiSelectionShapePoints = isMultiSelection\n\t\t\t? multiSelectionComputed.map(getMarkupShapePoints)\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*isMultiSelection*/ 2097152) {\n\t\t\t$$invalidate(197, allowResizeControls = !isMultiSelection && activeMarkup && shapeCanResize(activeMarkup) && !shapeIsTextEditing(activeMarkup));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*isMultiSelection*/ 2097152) {\n\t\t\t$$invalidate(19, allowRotateControls = !isMultiSelection && activeMarkup && shapeCanRotate(activeMarkup) && !shapeIsTextEditing(activeMarkup));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192) {\n\t\t\t$$invalidate(17, allowScaleControls = activeMarkup && shapeIsText(activeMarkup) && !shapeIsTextBox(activeMarkup) && !shapeIsTextEditing(activeMarkup) && activeMarkup.disableTextScale === false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[6] & /*allowResizeControls*/ 2048) {\n\t\t\t$$invalidate(21, allowEdgeControls = allowResizeControls\n\t\t\t? getAllowEdgeControls(activeMarkup)\n\t\t\t: false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup, allowEdgeControls*/ 2105344 | $$self.$$.dirty[6] & /*allowResizeControls*/ 2048) {\n\t\t\t$$invalidate(34, allowCornerControls = activeMarkup\n\t\t\t? Array.isArray(allowEdgeControls)\n\t\t\t\t? false\n\t\t\t\t: allowResizeControls\n\t\t\t: false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*isMultiSelection, multiSelection*/ 6291456) {\n\t\t\t$$invalidate(196, multiSelectionPoints = isMultiSelection\n\t\t\t? getMultiSelectionPoints(multiSelection)\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*isMultiSelection*/ 2097152 | $$self.$$.dirty[6] & /*shapeActivePoints*/ 128) {\n\t\t\t$$invalidate(18, shouldRenderShapeManipulator = activeMarkup && shapeActivePoints.length > 1 || isMultiSelection);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*mapImagePointToEditorPoint*/ 4096 | $$self.$$.dirty[5] & /*isMultiSelection*/ 2097152 | $$self.$$.dirty[6] & /*multiSelectionPoints, shapeActivePoints*/ 1152) {\n\t\t\t$$invalidate(191, selectionScreenPoints = isMultiSelection\n\t\t\t? multiSelectionPoints.map(mapImagePointToEditorPoint)\n\t\t\t: shapeActivePoints.map(mapImagePointToEditorPoint));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*offset*/ 8 | $$self.$$.dirty[6] & /*selectionScreenPoints*/ 32) {\n\t\t\t$$invalidate(15, shapeManipulatorPoints = selectionScreenPoints.map(point => vectorCreate(point.x - offset.x, point.y - offset.y)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192) {\n\t\t\t$$invalidate(20, shapeSelectedPointIndex = activeMarkup && activeMarkup.points && isNumber(activeMarkup.selectedPoint)\n\t\t\t? activeMarkup.selectedPoint\n\t\t\t: -1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shapeSelectedPointIndex*/ 1048576) {\n\t\t\t$$invalidate(169, hasSelectedShapePoint = shapeSelectedPointIndex >= 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shapeManipulatorPoints, shapeSelectedPointIndex*/ 1081344 | $$self.$$.dirty[5] & /*hasSelectedShapePoint*/ 16384) {\n\t\t\t$$invalidate(174, shapeSelectedManipulatorPoint = hasSelectedShapePoint\n\t\t\t? shapeManipulatorPoints[shapeSelectedPointIndex]\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[6] & /*activeMarkupSelected*/ 512) {\n\t\t\t$$invalidate(33, shapeAllowNewline = activeMarkupSelected && (shapeIsTextBox(activeMarkup)\n\t\t\t? // has selected text box, if text box has disableNewline property, follow setting, else allow new lines\n\t\t\t\thasProp(activeMarkup, 'disableNewline')\n\t\t\t\t? !activeMarkup.disableNewline\n\t\t\t\t: true\n\t\t\t: // has selected something else, only disable new lines if disableNewline is explicitly set to false\n\t\t\t\tactiveMarkup.disableNewline === false));\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*mapImagePointToEditorPoint*/ 4096 | $$self.$$.dirty[5] & /*hoverShape*/ 4) {\n\t\t\thoverShape && mapImagePointToEditorPoint && !shapeIsSelected(hoverShape) && shapeCanSelect(hoverShape)\n\t\t\t? redrawHoverShapes(hoverShape)\n\t\t\t: popHoverShapes();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderShapeManipulator, allowRotateControls, shapeManipulatorPoints, activeMarkupComputed*/ 884736 | $$self.$$.dirty[2] & /*opacity*/ 8192) {\n\t\t\t// TODO: we use opacity to trigger a redraw of the active points,\n\t\t\t// this should be changed to the image zoom factor in a future release\n\t\t\t$$invalidate(192, shapeManipulatorRotationPoint = shouldRenderShapeManipulator && allowRotateControls && opacity && shapeManipulatorPoints\n\t\t\t? getShapeRotationPointOnScreen(activeMarkupComputed)\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*offset*/ 8 | $$self.$$.dirty[6] & /*shapeManipulatorRotationPoint*/ 64) {\n\t\t\t$$invalidate(32, shapeManipulatorRotationPointPosition = shapeManipulatorRotationPoint && vectorCreate(shapeManipulatorRotationPoint.position.x - offset.x, shapeManipulatorRotationPoint.position.y - offset.y));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderShapeManipulator, allowScaleControls, shapeManipulatorPoints, activeMarkupComputed*/ 491520 | $$self.$$.dirty[2] & /*opacity*/ 8192) {\n\t\t\t$$invalidate(194, shapeManipulatorScalarPoint = shouldRenderShapeManipulator && allowScaleControls && opacity && shapeManipulatorPoints\n\t\t\t? getShapeScalarPointOnScreen(activeMarkupComputed)\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*offset*/ 8 | $$self.$$.dirty[6] & /*shapeManipulatorScalarPoint*/ 256) {\n\t\t\t$$invalidate(31, shapeManipulatorScalarPointPosition = shapeManipulatorScalarPoint && vectorCreate(shapeManipulatorScalarPoint.x - offset.x, shapeManipulatorScalarPoint.y - offset.y));\n\t\t}\n\n\t\tif ($$self.$$.dirty[6] & /*$keysPressedStored*/ 32768) {\n\t\t\t// hold cmd or control to disable snapping\n\t\t\t$$invalidate(184, disableSnapping = !!($keysPressedStored || []).find(keyCode => [91, 93, 17].includes(keyCode)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*snapPointer*/ 524288 | $$self.$$.dirty[5] & /*disableSnapping*/ 536870912) {\n\t\t\t$$invalidate(186, shouldSnapPointer = !(disableSnapping || !snapPointer));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[2] & /*opacity*/ 8192 | $$self.$$.dirty[5] & /*activeShapeIsDraft, pointerPositionInEditor*/ 16777232 | $$self.$$.dirty[6] & /*selectionScreenPoints, shouldSnapPointer*/ 33) {\n\t\t\tif (activeMarkup && selectionScreenPoints && opacity > 0) {\n\t\t\t\tclearHoverShapeIfActive();\n\n\t\t\t\tredrawManipulatorShapes(opacity, activeMarkup, // use snapped pointer position when we're drawing path\n\t\t\t\tactiveShapeIsDraft && shapeIsPath(activeMarkup)\n\t\t\t\t? snapPointerPosition({ ...pointerPositionInEditor }, !shouldSnapPointer)\n\t\t\t\t: undefined);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192) {\n\t\t\tif (!activeMarkup) {\n\t\t\t\tclearHoverShape();\n\t\t\t\tpopManipulatorShapes();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[6] & /*$selection*/ 131072) {\n\t\t\t$$invalidate(190, activeSelectionShape = $selection.length && $selection[$selection.length - 1]._isDraft\n\t\t\t? $selection[$selection.length - 1]\n\t\t\t: null);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*selection*/ 4 | $$self.$$.dirty[4] & /*interactionStepped*/ 1073741824 | $$self.$$.dirty[5] & /*lastImagePosition*/ 8 | $$self.$$.dirty[6] & /*activeSelectionShape*/ 16) {\n\t\t\t// add live pointer position to selection points array when in stepped interaction mode\n\t\t\tif (activeSelectionShape && activeSelectionShape.points && activeSelectionShape.points.length >= 1 && activeSelectionShape.pathClose && lastImagePosition && interactionStepped) {\n\t\t\t\tselection.update(items => items.map(item => {\n\t\t\t\t\tif (item.id !== activeSelectionShape.id) {\n\t\t\t\t\t\treturn item;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...item,\n\t\t\t\t\t\tpointerPoint: { ...lastImagePosition }\n\t\t\t\t\t};\n\t\t\t\t}));\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*mapImagePointToEditorPoint*/ 4096 | $$self.$$.dirty[6] & /*multiSelectionShapePoints*/ 8) {\n\t\t\tif (multiSelectionShapePoints.length) {\n\t\t\t\tpopMultiSelectionShapes();\n\n\t\t\t\tconst multiSelectionShapes = multiSelectionShapePoints.map(points => ({\n\t\t\t\t\tid: MultiSelectionShapeId,\n\t\t\t\t\tpoints: points.map(mapImagePointToEditorPoint),\n\t\t\t\t\tstrokeWidth: 1,\n\t\t\t\t\tstrokeColor: [1, 1, 1, 0.5],\n\t\t\t\t\tpathClose: true\n\t\t\t\t}));\n\n\t\t\t\tpushMultiSelectionShapes(...multiSelectionShapes);\n\t\t\t} else {\n\t\t\t\tpopMultiSelectionShapes();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*hoverShape*/ 4) {\n\t\t\t$$invalidate(187, isHoveringShape = !!hoverShape);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*interactionShape*/ 1) {\n\t\t\t$$invalidate(188, isManagingShape = !!interactionShape);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*pointerPositionInEditor*/ 16 | $$self.$$.dirty[6] & /*isManagingShape, isHoveringShape, shouldSnapPointer*/ 7) {\n\t\t\tif (// when pointer is available / updated\n\t\t\tpointerPositionInEditor && // when we're not interacting\n\t\t\t!isManagingShape && // and not hovering shape\n\t\t\t!isHoveringShape) {\n\t\t\t\tsnapPointerPosition({ ...pointerPositionInEditor }, !shouldSnapPointer);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[2] & /*gridColor*/ 131072 | $$self.$$.dirty[3] & /*gridSize, mapImagePointToEditorPoint*/ 2101248 | $$self.$$.dirty[5] & /*gridRect*/ 1073741824 | $$self.$$.dirty[6] & /*$gridOpacity*/ 65536) {\n\t\t\tif (gridSize > 0 && gridRect && mapImagePointToEditorPoint) {\n\t\t\t\tredrawGridShapes(gridSize, gridRect, gridColor, $gridOpacity);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[2] & /*snapColor*/ 262144 | $$self.$$.dirty[3] & /*mapImagePointToEditorPoint*/ 4096 | $$self.$$.dirty[4] & /*interactionSnapLineX, interactionSnapLineY*/ 805306368 | $$self.$$.dirty[5] & /*disableSnapping*/ 536870912) {\n\t\t\tif (mapImagePointToEditorPoint) {\n\t\t\t\tif (disableSnapping) {\n\t\t\t\t\tpopSnapShapes();\n\t\t\t\t} else {\n\t\t\t\t\tredrawSnapShapes(interactionSnapLineX, interactionSnapLineY, snapColor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[2] & /*active*/ 4096) {\n\t\t\ttogglePrerender(active);\n\t\t}\n\n\t\tif ($$self.$$.dirty[6] & /*$keysPressedStored*/ 32768) {\n\t\t\t//\n\t\t\t// Keyboard\n\t\t\t//\n\t\t\tif ($keysPressedStored && $keysPressedStored.length) handleKeyPressedStore();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*textInput, textInputMode*/ 576) {\n\t\t\t// auto focus text input when created and in inline mode\n\t\t\tif (textInput && textInputMode === 'inline') textInput.focus();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192) {\n\t\t\t$$invalidate(183, isTextMarkupSelected = activeMarkup && shapeIsText(activeMarkup));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*isTextMarkupSelected*/ 268435456) {\n\t\t\t$$invalidate(14, shouldRenderTextInput = isTextMarkupSelected && shapeCanInput(activeMarkup) !== false && shapeIsTextEditing(activeMarkup));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderTextInput*/ 16384) {\n\t\t\t$$invalidate(178, textShapeOrigin = shouldRenderTextInput\n\t\t\t? getTextShapeOriginSnapshot()\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[2] & /*parentRect*/ 16384 | $$self.$$.dirty[5] & /*textShapeOrigin*/ 8388608) {\n\t\t\t$$invalidate(180, textShapeDisplayOrigin = textShapeOrigin && shapeComputeDisplay({ ...textShapeOrigin }, parentRect));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*textShapeDisplayOrigin*/ 33554432) {\n\t\t\t$$invalidate(182, textSizeDisplayOrigin = textShapeDisplayOrigin && textToSize(textShapeDisplayOrigin.text, textShapeDisplayOrigin));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*textShapeDisplayOrigin, textSizeDisplayOrigin*/ 167772160) {\n\t\t\ttextRectDisplayOrigin = textShapeDisplayOrigin && rectCreate(textShapeDisplayOrigin.x, textShapeDisplayOrigin.y, textSizeDisplayOrigin.width, textSizeDisplayOrigin.height);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderTextInput, activeMarkup*/ 24576) {\n\t\t\t$$invalidate(28, textInputText = shouldRenderTextInput ? activeMarkup.text : '');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*rootRect, activeMarkup, shouldRenderTextInput*/ 24592 | $$self.$$.dirty[2] & /*parentRect*/ 16384) {\n\t\t\t$$invalidate(181, activeTextShapeComputed = rootRect && activeMarkup && shouldRenderTextInput && shapeComputeDisplay(\n\t\t\t\t{\n\t\t\t\t\t...shapeDeepCopy(activeMarkup),\n\t\t\t\t\t// this is the same as how canvas floors shape width/height\n\t\t\t\t\twidth: isNumber(activeMarkup.width)\n\t\t\t\t\t? Math.floor(activeMarkup.width)\n\t\t\t\t\t: undefined,\n\t\t\t\t\theight: isNumber(activeMarkup.height)\n\t\t\t\t\t? Math.floor(activeMarkup.height)\n\t\t\t\t\t: undefined\n\t\t\t\t},\n\t\t\t\tparentRect\n\t\t\t));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderTextInput, textInputMode*/ 16448 | $$self.$$.dirty[5] & /*activeTextShapeComputed*/ 67108864) {\n\t\t\t$$invalidate(30, textInputTextStyles = shouldRenderTextInput && getTextInputTextStyles(activeTextShapeComputed, textInputMode));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderTextInput, offset*/ 16392 | $$self.$$.dirty[2] & /*contextZoom, contextRotation*/ 2304 | $$self.$$.dirty[5] & /*activeTextShapeComputed*/ 67108864) {\n\t\t\t$$invalidate(29, textInputPositionStyles = shouldRenderTextInput && getTextInputPositionStyles(activeTextShapeComputed, offset, contextZoom, contextRotation));\n\t\t}\n\n\t\tif ($$self.$$.dirty[2] & /*caretColor*/ 65536) {\n\t\t\tcaretColorRGBA = caretColor ? colorArrayToRGBA(caretColor) : 'auto';\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderTextInput, textInput, textInputMode*/ 16960) {\n\t\t\tif (shouldRenderTextInput && textInput && textInputMode === 'inline') syncTextInput();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*activeMarkupItemIsDraft, controlledMarkupItem*/ 1056) {\n\t\t\t$$invalidate(165, controlledMarkupItem = activeMarkup && !activeMarkupItemIsDraft\n\t\t\t? activeMarkup\n\t\t\t: controlledMarkupItem);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*controlledMarkupItem*/ 1024) {\n\t\t\t$$invalidate(167, allowShapeFlip = controlledMarkupItem && shapeCanFlip(controlledMarkupItem));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*controlledMarkupItem*/ 1024) {\n\t\t\t$$invalidate(162, allowShapeChangeTextLayout = controlledMarkupItem && shapeCanChangeTextLayout(controlledMarkupItem));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*controlledMarkupItem*/ 1024) {\n\t\t\t$$invalidate(164, allowShapeDuplicate = controlledMarkupItem && shapeCanDuplicate(controlledMarkupItem));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*controlledMarkupItem*/ 1024) {\n\t\t\t$$invalidate(163, allowShapeRemove = controlledMarkupItem && shapeCanRemove(controlledMarkupItem));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*isMultiSelection, controlledMarkupItem*/ 2098176) {\n\t\t\t$$invalidate(166, allowShapeReorder = !isMultiSelection && controlledMarkupItem && shapeCanReorder(controlledMarkupItem));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*controlledMarkupItem*/ 1024) {\n\t\t\t$$invalidate(161, allowShapeInput = controlledMarkupItem && shapeCanInput(controlledMarkupItem) !== false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*controlledMarkupItem*/ 1024) {\n\t\t\t$$invalidate(168, allowShapeAdjustOpacity = controlledMarkupItem && hasProp(controlledMarkupItem, 'backgroundImage') && shapeCanStyle(controlledMarkupItem, 'opacity'));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup, textInputMode*/ 8256) {\n\t\t\t$$invalidate(171, allowShapeStyleText = activeMarkup && activeMarkup.format === 'html' && textInputMode === 'inline');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeMarkup*/ 8192 | $$self.$$.dirty[5] & /*activeMarkupItemIsDraft, allowShapeStyleText*/ 65568) {\n\t\t\t$$invalidate(175, shouldShowMarkupControls = activeMarkup && (!activeMarkupItemIsDraft || allowShapeStyleText));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*shouldShowMarkupControls, isInteracting*/ 1048578 | $$self.$$.dirty[6] & /*$isAnimated*/ 16384) {\n\t\t\t// show controls if markup is active, but not in draft mode, except for when editing text\n\t\t\tmarkupControlsOpacity.set(shouldShowMarkupControls && !isInteracting ? 1 : 0, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shapeManipulatorPoints*/ 32768 | $$self.$$.dirty[5] & /*shouldShowMarkupControls, markupControlsAnchorPosition*/ 1310720) {\n\t\t\t$$invalidate(173, markupControlsAnchorPosition = shouldShowMarkupControls && shapeManipulatorPoints.length\n\t\t\t? getMarkupControlsAnchorPosition(rectCreateFromPoints(shapeManipulatorPoints))\n\t\t\t: markupControlsAnchorPosition);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shapeControlsSize, utilRect*/ 1056 | $$self.$$.dirty[5] & /*shapeSelectedManipulatorPoint, markupControlsAnchorPosition*/ 786432) {\n\t\t\t$$invalidate(172, shapeControlsPosition = (shapeSelectedManipulatorPoint || markupControlsAnchorPosition) && shapeControlsSize && utilRect && getShapeControlPositionOnCanvas(utilRect, shapeSelectedManipulatorPoint || markupControlsAnchorPosition, shapeControlsSize, -16));\n\t\t}\n\n\t\tif ($$self.$$.dirty[5] & /*shapeControlsPosition*/ 131072) {\n\t\t\t// $: markupControlsStyle =\n\t\t\t//     shapeControlsPosition &&\n\t\t\t//     `transform: translate(${shapeControlsPosition.x}px, ${shapeControlsPosition.y}px);opacity:${$markupControlsOpacity}`;\n\t\t\t$$invalidate(27, styleMarkupControlTransform = shapeControlsPosition\n\t\t\t? `translate(${shapeControlsPosition.x}px, ${shapeControlsPosition.y}px)`\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$markupControlsOpacity*/ 4194304 | $$self.$$.dirty[5] & /*shapeControlsPosition*/ 131072) {\n\t\t\t$$invalidate(26, styleMarkupControlOpacity = shapeControlsPosition\n\t\t\t? $markupControlsOpacity\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shouldRenderTextInput*/ 16384) {\n\t\t\t$$invalidate(170, shapeControlsMode = shouldRenderTextInput ? 'text' : 'shape');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*activeShapeId, locale, activeMarkup*/ 12544 | $$self.$$.dirty[3] & /*willRenderShapeTextControls, willRenderShapeControls, enableButtonFlipVertical*/ 33536 | $$self.$$.dirty[5] & /*shapeControlsMode, allowShapeStyleText, hasSelectedShapePoint, allowShapeAdjustOpacity, allowShapeFlip, allowShapeReorder, controlledMarkupItem, allowShapeDuplicate, allowShapeRemove, allowShapeInput, allowShapeChangeTextLayout*/ 131008 | $$self.$$.dirty[6] & /*$shapes*/ 8192) {\n\t\t\t$$invalidate(25, shapeControls = // render text controls\n\t\t\tshapeControlsMode === 'text' && willRenderShapeTextControls && allowShapeStyleText\n\t\t\t? runSafe(() => willRenderShapeTextControls(\n\t\t\t\t\t[\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t'text-styles',\n\t\t\t\t\t\t\t{ class: 'PinturaShapeControlsGroup' },\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t...[\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t'bold',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: 'B',\n\t\t\t\t\t\t\t\t\t\t\tstyle: 'font-weight:900;',\n\t\t\t\t\t\t\t\t\t\t\ttitle: 'Bold',\n\t\t\t\t\t\t\t\t\t\t\tshortcut: ['CMD', 'B']\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t'italic',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: 'I',\n\t\t\t\t\t\t\t\t\t\t\tstyle: 'font-family:Times New Roman;font-style:italic;',\n\t\t\t\t\t\t\t\t\t\t\ttitle: 'Italic',\n\t\t\t\t\t\t\t\t\t\t\tshortcut: ['CMD', 'I']\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t'underline',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: 'U',\n\t\t\t\t\t\t\t\t\t\t\tstyle: 'text-decoration:underline;',\n\t\t\t\t\t\t\t\t\t\t\ttitle: 'Underline',\n\t\t\t\t\t\t\t\t\t\t\tshortcut: ['CMD', 'U']\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t'strikeThrough',\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: 'S',\n\t\t\t\t\t\t\t\t\t\t\tstyle: 'text-decoration:line-through;',\n\t\t\t\t\t\t\t\t\t\t\ttitle: 'Strikethrough',\n\t\t\t\t\t\t\t\t\t\t\tshortcut: ['CMD', 'S']\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t].map(([style, props]) => {\n\t\t\t\t\t\t\t\t\treturn [\n\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t'style-' + style,\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tonclick: () => document.execCommand(style),\n\t\t\t\t\t\t\t\t\t\t\t...props,\n\t\t\t\t\t\t\t\t\t\t\tstyle: 'font-size:1.25em;text-underline-offset:1px;text-decoration-thickness:1.5px;font-weight:400;' + props.style\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t],\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t'text-reset',\n\t\t\t\t\t\t\t{ class: 'PinturaShapeControlsGroup' },\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t'style-reset',\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tonclick: () => document.execCommand('removeFormat'),\n\t\t\t\t\t\t\t\t\t\tstyle: 'font-weight:400',\n\t\t\t\t\t\t\t\t\t\ttitle: 'Remove styles',\n\t\t\t\t\t\t\t\t\t\tlabel: [\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t'span',\n\t\t\t\t\t\t\t\t\t\t\t\t'T',\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyle: 'font-size:1.25em;font-style:italic;font-family:Times New Roman;text-decoration:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\ttextContent: 'T'\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t'span',\n\t\t\t\t\t\t\t\t\t\t\t\t'x',\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyle: 'position:relative;top:.175rem;',\n\t\t\t\t\t\t\t\t\t\t\t\t\tinnerHTML: '&times;'\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t]\n\t\t\t\t\t],\n\t\t\t\t\tactiveShapeId\n\t\t\t\t))\n\t\t\t: // render shape controls\n\t\t\t\tshapeControlsMode === 'shape' && willRenderShapeControls && activeShapeId\n\t\t\t\t? runSafe(() => willRenderShapeControls(\n\t\t\t\t\t\thasSelectedShapePoint\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t\t'epsilon',\n\t\t\t\t\t\t\t\t\t{ class: 'PinturaShapeControlsGroup' },\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'remove-point',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleRemovePointActiveMarkup,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: locale.shapeTitleButtonRemove,\n\t\t\t\t\t\t\t\t\t\t\t\ticon: locale.shapeIconButtonRemove,\n\t\t\t\t\t\t\t\t\t\t\t\tshortcut: ['Backspace'],\n\t\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\tallowShapeAdjustOpacity && [\n\t\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t\t'alpha',\n\t\t\t\t\t\t\t\t\t{ class: 'PinturaShapeControlsGroup' },\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t'ToggleSlider',\n\t\t\t\t\t\t\t\t\t\t\t'adjust-opacity',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonrelease: handleConfirmOpacity,\n\t\t\t\t\t\t\t\t\t\t\t\tonchange: handleAdjustOpacity,\n\t\t\t\t\t\t\t\t\t\t\t\tstep: 0.01,\n\t\t\t\t\t\t\t\t\t\t\t\tvalue: hasProp(activeMarkup, 'opacity')\n\t\t\t\t\t\t\t\t\t\t\t\t? activeMarkup.opacity\n\t\t\t\t\t\t\t\t\t\t\t\t: 1,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: (value, min, max) => `${Math.round(value / max * 100)}%`,\n\t\t\t\t\t\t\t\t\t\t\t\tmin: 0,\n\t\t\t\t\t\t\t\t\t\t\t\tmax: 1,\n\t\t\t\t\t\t\t\t\t\t\t\tdirection: 'x'\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t\t'beta',\n\t\t\t\t\t\t\t\t\t{ class: 'PinturaShapeControlsGroup' },\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\tallowShapeFlip && [\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'flip-horizontal',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleFlipX,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: locale.shapeTitleButtonFlipHorizontal,\n\t\t\t\t\t\t\t\t\t\t\t\ticon: locale.shapeIconButtonFlipHorizontal,\n\t\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tallowShapeFlip && enableButtonFlipVertical && [\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'flip-vertical',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleFlipY,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: locale.shapeTitleButtonFlipVertical,\n\t\t\t\t\t\t\t\t\t\t\t\ticon: locale.shapeIconButtonFlipVertical,\n\t\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tallowShapeReorder && [\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'to-front',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleMoveToFrontActiveMarkup,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: locale.shapeTitleButtonMoveToFront,\n\t\t\t\t\t\t\t\t\t\t\t\ticon: locale.shapeIconButtonMoveToFront,\n\t\t\t\t\t\t\t\t\t\t\t\thideLabel: true,\n\t\t\t\t\t\t\t\t\t\t\t\tdisabled: $shapes[$shapes.length - 1] === controlledMarkupItem\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tallowShapeDuplicate && [\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'duplicate',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleDuplicateActiveMarkup,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: locale.shapeTitleButtonDuplicate,\n\t\t\t\t\t\t\t\t\t\t\t\ticon: locale.shapeIconButtonDuplicate,\n\t\t\t\t\t\t\t\t\t\t\t\tshortcut: ['CMD', 'D'],\n\t\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tallowShapeRemove && [\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'remove',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleRemoveActiveMarkup,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: locale.shapeTitleButtonRemove,\n\t\t\t\t\t\t\t\t\t\t\t\ticon: locale.shapeIconButtonRemove,\n\t\t\t\t\t\t\t\t\t\t\t\tshortcut: ['Backspace'],\n\t\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t].filter(Boolean)\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tallowShapeInput && allowShapeChangeTextLayout && [\n\t\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t\t'gamma',\n\t\t\t\t\t\t\t\t\t{ class: 'PinturaShapeControlsGroup' },\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'text-layout',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleTextSwitchLayout,\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: localize(TextLayoutChangeLabel, locale, activeMarkup),\n\t\t\t\t\t\t\t\t\t\t\t\ticon: localize(TextLayoutChangeIcon, locale, activeMarkup),\n\t\t\t\t\t\t\t\t\t\t\t\thideLabel: true\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tallowShapeInput && [\n\t\t\t\t\t\t\t\t\t'div',\n\t\t\t\t\t\t\t\t\t'delta',\n\t\t\t\t\t\t\t\t\t{ class: 'PinturaShapeControlsGroup' },\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t'Button',\n\t\t\t\t\t\t\t\t\t\t\t'edit-text',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tlabel: locale.shapeLabelInputText,\n\t\t\t\t\t\t\t\t\t\t\t\tonclick: handleEditTextActiveMarkup\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t].filter(Boolean),\n\t\t\t\t\t\tactiveShapeId\n\t\t\t\t\t))\n\t\t\t\t: // fallback to empty array\n\t\t\t\t\t[]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale*/ 256 | $$self.$$.dirty[6] & /*$shapes*/ 8192) {\n\t\t\t$$invalidate(24, shapeNavList = $shapes.filter(shapeCanSelect).filter(shape => shape.id).filter(shape => !shapeIsDraft(shape)).map(shape => ({\n\t\t\t\tid: shape.id,\n\t\t\t\tcolor: shapeIsText(shape)\n\t\t\t\t? shape.color\n\t\t\t\t: shapeIsLine(shape)\n\t\t\t\t\t? shape.strokeColor\n\t\t\t\t\t: shape.backgroundColor,\n\t\t\t\tname: shape.name || locale[`shapeLabelTool${capitalizeFirstLetter(shapeGetDescription(shape))}`]\n\t\t\t})));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*element*/ 2048) {\n\t\t\tif (element) {\n\t\t\t\telement.addEventListener('touchmove', handleTouchmove, false);\n\t\t\t}\n\t\t}\n\t};\n\n\treturn [\n\t\tdisabled,\n\t\tshapes,\n\t\tselection,\n\t\toffset,\n\t\trootRect,\n\t\tutilRect,\n\t\ttextInputMode,\n\t\tenableTextStyleControls,\n\t\tlocale,\n\t\ttextInput,\n\t\tshapeControlsSize,\n\t\telement,\n\t\tactiveShapeId,\n\t\tactiveMarkup,\n\t\tshouldRenderTextInput,\n\t\tshapeManipulatorPoints,\n\t\tactiveMarkupComputed,\n\t\tallowScaleControls,\n\t\tshouldRenderShapeManipulator,\n\t\tallowRotateControls,\n\t\tshapeSelectedPointIndex,\n\t\tallowEdgeControls,\n\t\t$markupControlsOpacity,\n\t\tshowShapeList,\n\t\tshapeNavList,\n\t\tshapeControls,\n\t\tstyleMarkupControlOpacity,\n\t\tstyleMarkupControlTransform,\n\t\ttextInputText,\n\t\ttextInputPositionStyles,\n\t\ttextInputTextStyles,\n\t\tshapeManipulatorScalarPointPosition,\n\t\tshapeManipulatorRotationPointPosition,\n\t\tshapeAllowNewline,\n\t\tallowCornerControls,\n\t\tisAnimated,\n\t\tkeysPressedStored,\n\t\thandleInteractionStart,\n\t\thandleInteractionCancel,\n\t\thandleInteractionUpdate,\n\t\thandleInteractionRelease,\n\t\thandleInteractionEnd,\n\t\tgridOpacity,\n\t\thandleManipulatorResizeGrab,\n\t\thandleManipulatorResizeDrag,\n\t\thandleManipulatorResizeEnd,\n\t\thandleManipulatorRotateGrab,\n\t\thandleManipulatorRotateDrag,\n\t\thandleManipulatorRotateEnd,\n\t\thandleManipulatorScaleGrab,\n\t\thandleManipulatorScaleDrag,\n\t\thandleManipulatorScaleEnd,\n\t\thandleKeyDown,\n\t\tformatContentEditable,\n\t\thandleTextInput,\n\t\thandleTextInputAttempt,\n\t\thandleTextInputKeyDown,\n\t\tisTextConfirmKeyCombination,\n\t\thandleTextInputKeyUp,\n\t\thandleTextConfirm,\n\t\thandleTextCancel,\n\t\tmarkupControlsOpacity,\n\t\thandleNudge,\n\t\thandleFocusIn,\n\t\thandleFocusOut,\n\t\thandlePointerMove,\n\t\thandlePointerLeave,\n\t\tselectShapeByIndex,\n\t\tuid,\n\t\tui,\n\t\tcontextRotation,\n\t\tcontextFlipX,\n\t\tcontextFlipY,\n\t\tcontextZoom,\n\t\tactive,\n\t\topacity,\n\t\tparentRect,\n\t\thoverColor,\n\t\tcaretColor,\n\t\tgridColor,\n\t\tsnapColor,\n\t\toninteractionstart,\n\t\toninteractionupdate,\n\t\toninteractionrelease,\n\t\toninteractionend,\n\t\toninteractioncancel,\n\t\tonaddshape,\n\t\tonupdateshape,\n\t\tonselectshape,\n\t\tonblurshape,\n\t\tonremoveshape,\n\t\tontapshape,\n\t\tonhovershape,\n\t\tontriggerhistorywrite,\n\t\tonhovercanvas,\n\t\tontapcanvas,\n\t\tonleavecanvas,\n\t\tbeforeSelectShape,\n\t\tbeforeDeselectShape,\n\t\tbeforeRemoveShape,\n\t\tbeforeUpdateShape,\n\t\twillRenderShapeControls,\n\t\twillRenderShapeTextControls,\n\t\twillStartInteraction,\n\t\tmapEditorPointToImagePoint,\n\t\tmapImagePointToEditorPoint,\n\t\teraseRadius,\n\t\tselectRadius,\n\t\tenableButtonFlipVertical,\n\t\tenableTapToAddText,\n\t\tenableMultiSelect,\n\t\tsnapThreshold,\n\t\tsnapPointer,\n\t\tenableSnapToContext,\n\t\tgridSize,\n\t\tsyncShapeCollection,\n\t\tgetShapeDraft,\n\t\taddShapeDraft,\n\t\tdiscardShapeDraft,\n\t\tconfirmShapeDraft,\n\t\tupdateShapeDraft,\n\t\taddShape,\n\t\tcreateShape,\n\t\teraseShape,\n\t\tgetSelectionItemDraft,\n\t\tgetSelectionItemDraftIndex,\n\t\tdiscardSelectionItemDraft,\n\t\tgetMarkupItemDraft,\n\t\tgetMarkupItemDraftIndex,\n\t\taddMarkupItemDraft,\n\t\tconfirmMarkupItemDraft,\n\t\tdiscardMarkupItemDraft,\n\t\tcreateMarkupItem,\n\t\tsyncShapes,\n\t\tremoveMarkupShapeProps,\n\t\tupdateMarkupShape,\n\t\tupdateMarkupShapeProperty,\n\t\tupdateMarkupItemsShapeProperty,\n\t\tupdateMarkupShapeItems,\n\t\tgetActiveMarkupItems,\n\t\tgetActiveMarkupItem,\n\t\thasActiveMarkupItem,\n\t\tblurShapes,\n\t\tselectShape,\n\t\tdeselectMarkupItem,\n\t\teditMarkupItem,\n\t\tfinishEditMarkupItem,\n\t\tremoveMarkupItems,\n\t\tgetTextShapeRect,\n\t\tgetMarkupShapeRect,\n\t\tgetShapesNearPosition,\n\t\tgetShapesBetweenPoints,\n\t\tinteractionSnapLineX,\n\t\tinteractionSnapLineY,\n\t\tinteractionStepped,\n\t\tinteractionShape,\n\t\tisInteracting,\n\t\thoverShape,\n\t\tlastImagePosition,\n\t\tpointerPositionInEditor,\n\t\tactiveMarkupItemIsDraft,\n\t\tallowShapeInput,\n\t\tallowShapeChangeTextLayout,\n\t\tallowShapeRemove,\n\t\tallowShapeDuplicate,\n\t\tcontrolledMarkupItem,\n\t\tallowShapeReorder,\n\t\tallowShapeFlip,\n\t\tallowShapeAdjustOpacity,\n\t\thasSelectedShapePoint,\n\t\tshapeControlsMode,\n\t\tallowShapeStyleText,\n\t\tshapeControlsPosition,\n\t\tmarkupControlsAnchorPosition,\n\t\tshapeSelectedManipulatorPoint,\n\t\tshouldShowMarkupControls,\n\t\tisMultiSelection,\n\t\tmultiSelection,\n\t\ttextShapeOrigin,\n\t\tactiveShapeIsDraft,\n\t\ttextShapeDisplayOrigin,\n\t\tactiveTextShapeComputed,\n\t\ttextSizeDisplayOrigin,\n\t\tisTextMarkupSelected,\n\t\tdisableSnapping,\n\t\tgridRect,\n\t\tshouldSnapPointer,\n\t\tisHoveringShape,\n\t\tisManagingShape,\n\t\tmultiSelectionShapePoints,\n\t\tactiveSelectionShape,\n\t\tselectionScreenPoints,\n\t\tshapeManipulatorRotationPoint,\n\t\tshapeActivePoints,\n\t\tshapeManipulatorScalarPoint,\n\t\tactiveMarkupSelected,\n\t\tmultiSelectionPoints,\n\t\tallowResizeControls,\n\t\tmultiSelectionComputed,\n\t\t$shapes,\n\t\t$isAnimated,\n\t\t$keysPressedStored,\n\t\t$gridOpacity,\n\t\t$selection,\n\t\tmeasure_handler,\n\t\tclick_handler,\n\t\ttextarea_binding,\n\t\ttextarea_input_handler,\n\t\tfunc,\n\t\tcontenteditable_binding,\n\t\tfocusout_handler,\n\t\tmeasure_handler_1,\n\t\tdiv_binding,\n\t\tinteractable_function_1\n\t];\n}\n\nclass ShapeLayoutEditor extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$f,\n\t\t\tcreate_fragment$f,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tuid: 68,\n\t\t\t\tui: 69,\n\t\t\t\tdisabled: 0,\n\t\t\t\tshapes: 1,\n\t\t\t\tselection: 2,\n\t\t\t\toffset: 3,\n\t\t\t\tcontextRotation: 70,\n\t\t\t\tcontextFlipX: 71,\n\t\t\t\tcontextFlipY: 72,\n\t\t\t\tcontextZoom: 73,\n\t\t\t\tactive: 74,\n\t\t\t\topacity: 75,\n\t\t\t\tparentRect: 76,\n\t\t\t\trootRect: 4,\n\t\t\t\tutilRect: 5,\n\t\t\t\thoverColor: 77,\n\t\t\t\tcaretColor: 78,\n\t\t\t\tgridColor: 79,\n\t\t\t\tsnapColor: 80,\n\t\t\t\ttextInputMode: 6,\n\t\t\t\toninteractionstart: 81,\n\t\t\t\toninteractionupdate: 82,\n\t\t\t\toninteractionrelease: 83,\n\t\t\t\toninteractionend: 84,\n\t\t\t\toninteractioncancel: 85,\n\t\t\t\tonaddshape: 86,\n\t\t\t\tonupdateshape: 87,\n\t\t\t\tonselectshape: 88,\n\t\t\t\tonblurshape: 89,\n\t\t\t\tonremoveshape: 90,\n\t\t\t\tontapshape: 91,\n\t\t\t\tonhovershape: 92,\n\t\t\t\tontriggerhistorywrite: 93,\n\t\t\t\tonhovercanvas: 94,\n\t\t\t\tontapcanvas: 95,\n\t\t\t\tonleavecanvas: 96,\n\t\t\t\tbeforeSelectShape: 97,\n\t\t\t\tbeforeDeselectShape: 98,\n\t\t\t\tbeforeRemoveShape: 99,\n\t\t\t\tbeforeUpdateShape: 100,\n\t\t\t\twillRenderShapeControls: 101,\n\t\t\t\twillRenderShapeTextControls: 102,\n\t\t\t\twillStartInteraction: 103,\n\t\t\t\tmapEditorPointToImagePoint: 104,\n\t\t\t\tmapImagePointToEditorPoint: 105,\n\t\t\t\teraseRadius: 106,\n\t\t\t\tselectRadius: 107,\n\t\t\t\tenableButtonFlipVertical: 108,\n\t\t\t\tenableTapToAddText: 109,\n\t\t\t\tenableMultiSelect: 110,\n\t\t\t\tenableTextStyleControls: 7,\n\t\t\t\tlocale: 8,\n\t\t\t\tsnapThreshold: 111,\n\t\t\t\tsnapPointer: 112,\n\t\t\t\tenableSnapToContext: 113,\n\t\t\t\tgridSize: 114,\n\t\t\t\tsyncShapeCollection: 115,\n\t\t\t\tgetShapeDraft: 116,\n\t\t\t\taddShapeDraft: 117,\n\t\t\t\tdiscardShapeDraft: 118,\n\t\t\t\tconfirmShapeDraft: 119,\n\t\t\t\tupdateShapeDraft: 120,\n\t\t\t\taddShape: 121,\n\t\t\t\tcreateShape: 122,\n\t\t\t\teraseShape: 123,\n\t\t\t\tgetSelectionItemDraft: 124,\n\t\t\t\tgetSelectionItemDraftIndex: 125,\n\t\t\t\tdiscardSelectionItemDraft: 126,\n\t\t\t\tgetMarkupItemDraft: 127,\n\t\t\t\tgetMarkupItemDraftIndex: 128,\n\t\t\t\taddMarkupItemDraft: 129,\n\t\t\t\tconfirmMarkupItemDraft: 130,\n\t\t\t\tdiscardMarkupItemDraft: 131,\n\t\t\t\tcreateMarkupItem: 132,\n\t\t\t\tsyncShapes: 133,\n\t\t\t\tremoveMarkupShapeProps: 134,\n\t\t\t\tupdateMarkupShape: 135,\n\t\t\t\tupdateMarkupShapeProperty: 136,\n\t\t\t\tupdateMarkupItemsShapeProperty: 137,\n\t\t\t\tupdateMarkupShapeItems: 138,\n\t\t\t\tgetActiveMarkupItems: 139,\n\t\t\t\tgetActiveMarkupItem: 140,\n\t\t\t\thasActiveMarkupItem: 141,\n\t\t\t\tblurShapes: 142,\n\t\t\t\tselectShape: 143,\n\t\t\t\tdeselectMarkupItem: 144,\n\t\t\t\teditMarkupItem: 145,\n\t\t\t\tfinishEditMarkupItem: 146,\n\t\t\t\tremoveMarkupItems: 147,\n\t\t\t\tgetTextShapeRect: 148,\n\t\t\t\tgetMarkupShapeRect: 149,\n\t\t\t\tgetShapesNearPosition: 150,\n\t\t\t\tgetShapesBetweenPoints: 151\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]\n\t\t);\n\t}\n\n\tget syncShapeCollection() {\n\t\treturn this.$$.ctx[115];\n\t}\n\n\tget getShapeDraft() {\n\t\treturn this.$$.ctx[116];\n\t}\n\n\tget addShapeDraft() {\n\t\treturn this.$$.ctx[117];\n\t}\n\n\tget discardShapeDraft() {\n\t\treturn this.$$.ctx[118];\n\t}\n\n\tget confirmShapeDraft() {\n\t\treturn this.$$.ctx[119];\n\t}\n\n\tget updateShapeDraft() {\n\t\treturn this.$$.ctx[120];\n\t}\n\n\tget addShape() {\n\t\treturn this.$$.ctx[121];\n\t}\n\n\tget createShape() {\n\t\treturn this.$$.ctx[122];\n\t}\n\n\tget eraseShape() {\n\t\treturn this.$$.ctx[123];\n\t}\n\n\tget getSelectionItemDraft() {\n\t\treturn this.$$.ctx[124];\n\t}\n\n\tget getSelectionItemDraftIndex() {\n\t\treturn this.$$.ctx[125];\n\t}\n\n\tget discardSelectionItemDraft() {\n\t\treturn this.$$.ctx[126];\n\t}\n\n\tget getMarkupItemDraft() {\n\t\treturn this.$$.ctx[127];\n\t}\n\n\tget getMarkupItemDraftIndex() {\n\t\treturn this.$$.ctx[128];\n\t}\n\n\tget addMarkupItemDraft() {\n\t\treturn this.$$.ctx[129];\n\t}\n\n\tget confirmMarkupItemDraft() {\n\t\treturn this.$$.ctx[130];\n\t}\n\n\tget discardMarkupItemDraft() {\n\t\treturn this.$$.ctx[131];\n\t}\n\n\tget createMarkupItem() {\n\t\treturn this.$$.ctx[132];\n\t}\n\n\tget syncShapes() {\n\t\treturn this.$$.ctx[133];\n\t}\n\n\tget removeMarkupShapeProps() {\n\t\treturn this.$$.ctx[134];\n\t}\n\n\tget updateMarkupShape() {\n\t\treturn this.$$.ctx[135];\n\t}\n\n\tget updateMarkupShapeProperty() {\n\t\treturn this.$$.ctx[136];\n\t}\n\n\tget updateMarkupItemsShapeProperty() {\n\t\treturn this.$$.ctx[137];\n\t}\n\n\tget updateMarkupShapeItems() {\n\t\treturn this.$$.ctx[138];\n\t}\n\n\tget getActiveMarkupItems() {\n\t\treturn this.$$.ctx[139];\n\t}\n\n\tget getActiveMarkupItem() {\n\t\treturn this.$$.ctx[140];\n\t}\n\n\tget hasActiveMarkupItem() {\n\t\treturn this.$$.ctx[141];\n\t}\n\n\tget blurShapes() {\n\t\treturn this.$$.ctx[142];\n\t}\n\n\tget selectShape() {\n\t\treturn this.$$.ctx[143];\n\t}\n\n\tget deselectMarkupItem() {\n\t\treturn this.$$.ctx[144];\n\t}\n\n\tget editMarkupItem() {\n\t\treturn this.$$.ctx[145];\n\t}\n\n\tget finishEditMarkupItem() {\n\t\treturn this.$$.ctx[146];\n\t}\n\n\tget removeMarkupItems() {\n\t\treturn this.$$.ctx[147];\n\t}\n\n\tget getTextShapeRect() {\n\t\treturn this.$$.ctx[148];\n\t}\n\n\tget getMarkupShapeRect() {\n\t\treturn this.$$.ctx[149];\n\t}\n\n\tget getShapesNearPosition() {\n\t\treturn this.$$.ctx[150];\n\t}\n\n\tget getShapesBetweenPoints() {\n\t\treturn this.$$.ctx[151];\n\t}\n}\n\n/* src/core/ui/components/ShapeStyleControls.svelte generated by Svelte v4.2.20 */\n\nfunction create_else_block$4(ctx) {\n\tlet ul;\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*mappedControls*/ ctx[2] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tul = element(\"ul\");\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tattr(ul, \"class\", \"PinturaShapeStyleList\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, ul, anchor);\n\t\t\tmount_component(dynamiccomponenttree, ul, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*mappedControls*/ 4) dynamiccomponenttree_changes.items = /*mappedControls*/ ctx[2];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(ul);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t}\n\t};\n}\n\n// (51:4) {#if scrollEnable}\nfunction create_if_block$4(ctx) {\n\tlet scrollable;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaShapeStyles\",\n\t\t\t\telasticity: /*scrollElasticity*/ ctx[0],\n\t\t\t\t$$slots: { default: [create_default_slot$6] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(scrollable, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty & /*scrollElasticity*/ 1) scrollable_changes.elasticity = /*scrollElasticity*/ ctx[0];\n\n\t\t\tif (dirty & /*$$scope, mappedControls*/ 524292) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(scrollable, detaching);\n\t\t}\n\t};\n}\n\n// (52:8) <Scrollable class=\"PinturaShapeStyles\" elasticity={scrollElasticity}>\nfunction create_default_slot$6(ctx) {\n\tlet ul;\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*mappedControls*/ ctx[2] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tul = element(\"ul\");\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tattr(ul, \"class\", \"PinturaShapeStyleList\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, ul, anchor);\n\t\t\tmount_component(dynamiccomponenttree, ul, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*mappedControls*/ 4) dynamiccomponenttree_changes.items = /*mappedControls*/ ctx[2];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(ul);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t}\n\t};\n}\n\nfunction create_fragment$e(ctx) {\n\tlet div;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet current;\n\tconst if_block_creators = [create_if_block$4, create_else_block$4];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*scrollEnable*/ ctx[1]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif_block.c();\n\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[5]);\n\t\t\tset_style(div, \"pointer-events\", /*stylePointerEvents*/ ctx[4]);\n\t\t\tset_style(div, \"visibility\", /*styleVisibility*/ ctx[3]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif_blocks[current_block_type_index].m(div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(div, null);\n\t\t\t}\n\n\t\t\tif (dirty & /*styleOpacity*/ 32) {\n\t\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[5]);\n\t\t\t}\n\n\t\t\tif (dirty & /*stylePointerEvents*/ 16) {\n\t\t\t\tset_style(div, \"pointer-events\", /*stylePointerEvents*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (dirty & /*styleVisibility*/ 8) {\n\t\t\t\tset_style(div, \"visibility\", /*styleVisibility*/ ctx[3]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d();\n\t\t}\n\t};\n}\n\nfunction instance$e($$self, $$props, $$invalidate) {\n\tlet styleOpacity;\n\tlet stylePointerEvents;\n\tlet styleVisibility;\n\tlet mappedControls;\n\tlet $env;\n\tlet $redrawTrigger;\n\tlet $opacity;\n\tlet $isAnimated;\n\tlet { isActive = false } = $$props;\n\tlet { controls = [] } = $$props;\n\tlet { locale } = $$props;\n\tlet { scrollElasticity } = $$props;\n\tlet { scrollEnable = true } = $$props;\n\tlet { hideTitles = false } = $$props;\n\tlet { willRenderControls = passthrough } = $$props;\n\n\t// context\n\tconst redrawTrigger = getContext('redrawTrigger');\n\n\tcomponent_subscribe($$self, redrawTrigger, value => $$invalidate(16, $redrawTrigger = value));\n\tconst env = getContext('env');\n\tcomponent_subscribe($$self, env, value => $$invalidate(15, $env = value));\n\tconst isAnimated = getContext('isAnimated');\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(18, $isAnimated = value));\n\tconst opacity = spring(0, { stiffness: 0.25, damping: 0.9 });\n\tcomponent_subscribe($$self, opacity, value => $$invalidate(17, $opacity = value));\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$invalidate(10, isActive = $$props.isActive);\n\t\tif ('controls' in $$props) $$invalidate(11, controls = $$props.controls);\n\t\tif ('locale' in $$props) $$invalidate(12, locale = $$props.locale);\n\t\tif ('scrollElasticity' in $$props) $$invalidate(0, scrollElasticity = $$props.scrollElasticity);\n\t\tif ('scrollEnable' in $$props) $$invalidate(1, scrollEnable = $$props.scrollEnable);\n\t\tif ('hideTitles' in $$props) $$invalidate(13, hideTitles = $$props.hideTitles);\n\t\tif ('willRenderControls' in $$props) $$invalidate(14, willRenderControls = $$props.willRenderControls);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*isActive, $isAnimated*/ 263168) {\n\t\t\topacity.set(isActive ? 1 : 0, { hard: $isAnimated === false });\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*$opacity*/ 131072) {\n\t\t\t$$invalidate(5, styleOpacity = $opacity);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*isActive*/ 1024) {\n\t\t\t$$invalidate(4, stylePointerEvents = isActive ? 'auto' : 'none');\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*$opacity*/ 131072) {\n\t\t\t$$invalidate(3, styleVisibility = $opacity <= 0 ? 'hidden' : 'visible');\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*$redrawTrigger, willRenderControls, controls, locale, hideTitles, $env*/ 129024) {\n\t\t\t$$invalidate(2, mappedControls = $redrawTrigger && willRenderControls(\n\t\t\t\tcontrols.map(control => [\n\t\t\t\t\t'ShapeStyle',\n\t\t\t\t\tcontrol.id,\n\t\t\t\t\t{\n\t\t\t\t\t\ttitle: control.componentProps.title,\n\t\t\t\t\t\tlocale,\n\t\t\t\t\t\thideTitle: hideTitles,\n\t\t\t\t\t\titems: [[control.component, control.id, control.componentProps]]\n\t\t\t\t\t}\n\t\t\t\t]),\n\t\t\t\t$env,\n\t\t\t\t() => redrawTrigger.set({})\n\t\t\t));\n\t\t}\n\t};\n\n\treturn [\n\t\tscrollElasticity,\n\t\tscrollEnable,\n\t\tmappedControls,\n\t\tstyleVisibility,\n\t\tstylePointerEvents,\n\t\tstyleOpacity,\n\t\tredrawTrigger,\n\t\tenv,\n\t\tisAnimated,\n\t\topacity,\n\t\tisActive,\n\t\tcontrols,\n\t\tlocale,\n\t\thideTitles,\n\t\twillRenderControls,\n\t\t$env,\n\t\t$redrawTrigger,\n\t\t$opacity,\n\t\t$isAnimated\n\t];\n}\n\nclass ShapeStyleControls extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$e, create_fragment$e, safe_not_equal, {\n\t\t\tisActive: 10,\n\t\t\tcontrols: 11,\n\t\t\tlocale: 12,\n\t\t\tscrollElasticity: 0,\n\t\t\tscrollEnable: 1,\n\t\t\thideTitles: 13,\n\t\t\twillRenderControls: 14\n\t\t});\n\t}\n}\n\n/* src/core/ui/components/ShapeStyleEditor.svelte generated by Svelte v4.2.20 */\n\nfunction get_each_context(ctx, list, i) {\n\tconst child_ctx = ctx.slice();\n\tchild_ctx[15] = list[i].key;\n\tchild_ctx[6] = list[i].controls;\n\tchild_ctx[16] = list[i].isActive;\n\treturn child_ctx;\n}\n\n// (189:4) {#each currentStyleControlSets as { key, controls, isActive }\nfunction create_each_block(key_2, ctx) {\n\tlet first;\n\tlet shapestylecontrols;\n\tlet current;\n\n\tshapestylecontrols = new ShapeStyleControls({\n\t\t\tprops: {\n\t\t\t\tisActive: /*isActive*/ ctx[16],\n\t\t\t\tcontrols: /*controls*/ ctx[6],\n\t\t\t\tlocale: /*locale*/ ctx[1],\n\t\t\t\tscrollElasticity: /*scrollElasticity*/ ctx[2],\n\t\t\t\tscrollEnable: /*scrollEnable*/ ctx[3],\n\t\t\t\thideTitles: /*hideTitles*/ ctx[4],\n\t\t\t\twillRenderControls: /*willRenderControls*/ ctx[5]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tkey: key_2,\n\t\tfirst: null,\n\t\tc() {\n\t\t\tfirst = empty();\n\t\t\tcreate_component(shapestylecontrols.$$.fragment);\n\t\t\tthis.first = first;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, first, anchor);\n\t\t\tmount_component(shapestylecontrols, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\t\t\tconst shapestylecontrols_changes = {};\n\t\t\tif (dirty & /*currentStyleControlSets*/ 128) shapestylecontrols_changes.isActive = /*isActive*/ ctx[16];\n\t\t\tif (dirty & /*currentStyleControlSets*/ 128) shapestylecontrols_changes.controls = /*controls*/ ctx[6];\n\t\t\tif (dirty & /*locale*/ 2) shapestylecontrols_changes.locale = /*locale*/ ctx[1];\n\t\t\tif (dirty & /*scrollElasticity*/ 4) shapestylecontrols_changes.scrollElasticity = /*scrollElasticity*/ ctx[2];\n\t\t\tif (dirty & /*scrollEnable*/ 8) shapestylecontrols_changes.scrollEnable = /*scrollEnable*/ ctx[3];\n\t\t\tif (dirty & /*hideTitles*/ 16) shapestylecontrols_changes.hideTitles = /*hideTitles*/ ctx[4];\n\t\t\tif (dirty & /*willRenderControls*/ 32) shapestylecontrols_changes.willRenderControls = /*willRenderControls*/ ctx[5];\n\t\t\tshapestylecontrols.$set(shapestylecontrols_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapestylecontrols.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapestylecontrols.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(first);\n\t\t\t}\n\n\t\t\tdestroy_component(shapestylecontrols, detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$d(ctx) {\n\tlet div;\n\tlet each_blocks = [];\n\tlet each_1_lookup = new Map();\n\tlet div_class_value;\n\tlet current;\n\tlet each_value = ensure_array_like(/*currentStyleControlSets*/ ctx[7]);\n\tconst get_key = ctx => /*key*/ ctx[15];\n\n\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\tlet child_ctx = get_each_context(ctx, each_value, i);\n\t\tlet key = get_key(child_ctx);\n\t\teach_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx));\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].c();\n\t\t\t}\n\n\t\t\tattr(div, \"class\", div_class_value = arrayJoin([\n\t\t\t\t'PinturaShapeStyleEditor',\n\t\t\t\t!/*scrollEnable*/ ctx[3] && 'PinturaShapeStyleEditorOverflow',\n\t\t\t\t/*klass*/ ctx[0]\n\t\t\t]));\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\tif (each_blocks[i]) {\n\t\t\t\t\teach_blocks[i].m(div, null);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*currentStyleControlSets, locale, scrollElasticity, scrollEnable, hideTitles, willRenderControls*/ 190) {\n\t\t\t\teach_value = ensure_array_like(/*currentStyleControlSets*/ ctx[7]);\n\t\t\t\tgroup_outros();\n\t\t\t\teach_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block, null, get_each_context);\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*scrollEnable, klass*/ 9 && div_class_value !== (div_class_value = arrayJoin([\n\t\t\t\t'PinturaShapeStyleEditor',\n\t\t\t\t!/*scrollEnable*/ ctx[3] && 'PinturaShapeStyleEditorOverflow',\n\t\t\t\t/*klass*/ ctx[0]\n\t\t\t]))) {\n\t\t\t\tattr(div, \"class\", div_class_value);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\n\t\t\tfor (let i = 0; i < each_value.length; i += 1) {\n\t\t\t\ttransition_in(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\ttransition_out(each_blocks[i]);\n\t\t\t}\n\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tfor (let i = 0; i < each_blocks.length; i += 1) {\n\t\t\t\teach_blocks[i].d();\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction instance$d($$self, $$props, $$invalidate) {\n\tlet controlKeys;\n\tlet activeControls;\n\tlet currentStyleControlSets;\n\tlet { class: klass = undefined } = $$props;\n\tlet { controls = {} } = $$props;\n\tlet { shapeProps = undefined } = $$props;\n\tlet { onchange } = $$props;\n\tlet { locale } = $$props;\n\tlet { scrollElasticity } = $$props;\n\tlet { scrollEnable = true } = $$props;\n\tlet { hideTitles = false } = $$props;\n\tlet { willRenderControls } = $$props;\n\n\tconst getShapeControls = shapeProps => {\n\t\tconst activeControls = controlKeys.filter(styleKey => styleKey.split('_').every(styleKey => // shapeProps needs to have the property\n\t\thasProp(shapeProps, styleKey) && // shapeProps needs to be able to style the property\n\t\tshapeCanStyle(shapeProps, styleKey))).map(styleKey => {\n\t\t\t// map to controlKey\n\t\t\tconst styleSettings = shapeProps.settings && shapeProps.settings[styleKey] || {};\n\n\t\t\tconst controlKey = styleSettings.control || styleKey;\n\n\t\t\t// handle multistyle keys\n\t\t\tconst styleKeys = styleKey.split('_');\n\n\t\t\tlet currentValue = styleKeys.length > 1\n\t\t\t? styleKeys.map(key => shapeProps[key])\n\t\t\t: shapeProps[styleKey];\n\n\t\t\t// get control\n\t\t\tif (isFunction(controls[controlKey])) {\n\t\t\t\tconst { title, component } = controls[controlKey](\n\t\t\t\t\tcurrentValue,\n\t\t\t\t\tnewValue => {\n\t\t\t\t\t\tonchange({ [styleKey]: newValue });\n\t\t\t\t\t},\n\t\t\t\t\t{ selectedShapeId: shapeProps.id }\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\tid: controlKey,\n\t\t\t\t\tcomponent: DynamicComponentTree_1,\n\t\t\t\t\tcomponentProps: { title, items: component }\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tlet [component, componentProps] = controls[controlKey];\n\n\t\t\t// is reference to other control or string representation of component\n\t\t\tif (isString(component)) {\n\t\t\t\t// exif if not a valid default control\n\t\t\t\tif (controls[component]) {\n\t\t\t\t\t// create component based on reference\n\t\t\t\t\tconst componentCustomProps = { ...componentProps };\n\n\t\t\t\t\t[component, componentProps] = controls[component];\n\n\t\t\t\t\tcomponentProps = {\n\t\t\t\t\t\t...componentProps,\n\t\t\t\t\t\t...componentCustomProps\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst options = isFunction(componentProps.options)\n\t\t\t? componentProps.options(shapeProps)\n\t\t\t: componentProps.options;\n\n\t\t\tif (component === 'RadioGroup') componentProps.selectedIndex = -1;\n\n\t\t\tif (isFunction(componentProps.formatValue)) {\n\t\t\t\tcurrentValue = componentProps.formatValue(currentValue);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tid: controlKey,\n\t\t\t\tcomponent,\n\t\t\t\tcomponentProps: {\n\t\t\t\t\t...componentProps,\n\t\t\t\t\t// set the options prop\n\t\t\t\t\toptions,\n\t\t\t\t\t// defaults\n\t\t\t\t\tlocale,\n\t\t\t\t\tvalue: currentValue,\n\t\t\t\t\toptionLabelClass: 'PinturaButtonLabel',\n\t\t\t\t\tonchange: detail => {\n\t\t\t\t\t\tlet value = isObject(detail) && !isArray(detail)\n\t\t\t\t\t\t? detail.value\n\t\t\t\t\t\t: detail;\n\n\t\t\t\t\t\t// need to format the output value same as the input value\n\t\t\t\t\t\tif (isFunction(componentProps.formatValue)) {\n\t\t\t\t\t\t\tvalue = componentProps.formatValue(value);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// allow custom changes\n\t\t\t\t\t\tif (componentProps.onchange) {\n\t\t\t\t\t\t\tcomponentProps.onchange(value, shapeProps);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// internal change\n\t\t\t\t\t\tconst props = styleKeys.length > 1\n\t\t\t\t\t\t? styleKeys.reduce(\n\t\t\t\t\t\t\t\t(prev, key, index) => {\n\t\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\t\t...prev,\n\t\t\t\t\t\t\t\t\t\t[key]: Array.isArray(value) ? value[index] : value\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{}\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: { [styleKey]: value };\n\n\t\t\t\t\t\tonchange(props);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}).filter(Boolean);\n\n\t\treturn activeControls;\n\t};\n\n\tconst styleControlSets = [];\n\n\tconst getStyleControlSets = (key, controls) => {\n\t\tlet controlSet = styleControlSets.find(controlSet => controlSet.key === key);\n\n\t\tif (!controlSet) {\n\t\t\t// create\n\t\t\tcontrolSet = { key, controls };\n\n\t\t\t// add\n\t\t\tstyleControlSets.push(controlSet);\n\t\t}\n\n\t\t// hide all\n\t\tstyleControlSets.forEach(controlSet => controlSet.isActive = false);\n\n\t\t// update active controls\n\t\tcontrolSet.controls = controls;\n\n\t\t// show active\n\t\tcontrolSet.isActive = true;\n\n\t\treturn styleControlSets;\n\t};\n\n\t$$self.$$set = $$props => {\n\t\tif ('class' in $$props) $$invalidate(0, klass = $$props.class);\n\t\tif ('controls' in $$props) $$invalidate(6, controls = $$props.controls);\n\t\tif ('shapeProps' in $$props) $$invalidate(8, shapeProps = $$props.shapeProps);\n\t\tif ('onchange' in $$props) $$invalidate(9, onchange = $$props.onchange);\n\t\tif ('locale' in $$props) $$invalidate(1, locale = $$props.locale);\n\t\tif ('scrollElasticity' in $$props) $$invalidate(2, scrollElasticity = $$props.scrollElasticity);\n\t\tif ('scrollEnable' in $$props) $$invalidate(3, scrollEnable = $$props.scrollEnable);\n\t\tif ('hideTitles' in $$props) $$invalidate(4, hideTitles = $$props.hideTitles);\n\t\tif ('willRenderControls' in $$props) $$invalidate(5, willRenderControls = $$props.willRenderControls);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*controls*/ 64) {\n\t\t\t// finds the controls needed to style the selected shapeProps\n\t\t\t$$invalidate(11, controlKeys = Object.keys(controls).filter(key => controls[key]));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*shapeProps, controlKeys*/ 2304) {\n\t\t\t$$invalidate(10, activeControls = shapeProps && Object.keys(shapeProps).length && controlKeys && shapeCanStyle(shapeProps)\n\t\t\t? getShapeControls(shapeProps)\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*shapeProps, activeControls*/ 1280) {\n\t\t\t$$invalidate(7, currentStyleControlSets = getStyleControlSets(\n\t\t\t\tshapeProps && Object.keys(shapeProps).length\n\t\t\t\t? Object.keys(shapeProps).join('_')\n\t\t\t\t: 'none',\n\t\t\t\tactiveControls || []\n\t\t\t));\n\t\t}\n\t};\n\n\treturn [\n\t\tklass,\n\t\tlocale,\n\t\tscrollElasticity,\n\t\tscrollEnable,\n\t\thideTitles,\n\t\twillRenderControls,\n\t\tcontrols,\n\t\tcurrentStyleControlSets,\n\t\tshapeProps,\n\t\tonchange,\n\t\tactiveControls,\n\t\tcontrolKeys\n\t];\n}\n\nclass ShapeStyleEditor extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$d, create_fragment$d, safe_not_equal, {\n\t\t\tclass: 0,\n\t\t\tcontrols: 6,\n\t\t\tshapeProps: 8,\n\t\t\tonchange: 9,\n\t\t\tlocale: 1,\n\t\t\tscrollElasticity: 2,\n\t\t\tscrollEnable: 3,\n\t\t\thideTitles: 4,\n\t\t\twillRenderControls: 5\n\t\t});\n\t}\n}\n\nvar isSVGMarkup = (str) => /<svg /.test(str);\n\n/* src/core/ui/components/ShapePresetsPalette.svelte generated by Svelte v4.2.20 */\n\nfunction create_if_block_6$1(ctx) {\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*presetToolbar*/ ctx[10] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*presetToolbar*/ 1024) dynamiccomponenttree_changes.items = /*presetToolbar*/ ctx[10];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t}\n\t};\n}\n\n// (159:4) {#if shouldRenderPresets}\nfunction create_if_block$3(ctx) {\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet if_block_anchor;\n\tlet current;\n\tconst if_block_creators = [create_if_block_1$2, create_else_block$3];\n\tconst if_blocks = [];\n\n\tfunction select_block_type_1(ctx, dirty) {\n\t\tif (/*shouldGroupPresets*/ ctx[8]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type_1(ctx);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif_block.c();\n\t\t\tif_block_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif_blocks[current_block_type_index].m(target, anchor);\n\t\t\tinsert(target, if_block_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type_1(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(if_block_anchor.parentNode, if_block_anchor);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(if_block_anchor);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d(detaching);\n\t\t}\n\t};\n}\n\n// (208:8) {:else}\nfunction create_else_block$3(ctx) {\n\tlet div;\n\tlet t;\n\tlet scrollable;\n\tlet current;\n\tlet if_block = /*presetToolbar*/ ctx[10] && create_if_block_5$1(ctx);\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\tscrollAutoCancel: /*shouldRenderPresets*/ ctx[9],\n\t\t\t\telasticity: /*scrollElasticity*/ ctx[0],\n\t\t\t\t$$slots: { default: [create_default_slot_5] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tt = space();\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaShapePresetsFlat\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\tappend(div, t);\n\t\t\tmount_component(scrollable, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*presetToolbar*/ ctx[10]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*presetToolbar*/ 1024) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_5$1(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, t);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty & /*shouldRenderPresets*/ 512) scrollable_changes.scrollAutoCancel = /*shouldRenderPresets*/ ctx[9];\n\t\t\tif (dirty & /*scrollElasticity*/ 1) scrollable_changes.elasticity = /*scrollElasticity*/ ctx[0];\n\n\t\t\tif (dirty & /*$$scope, presetsMapped, onaddpreset, ongrabpreset, ondragpreset, ondroppreset*/ 536871070) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t\tdestroy_component(scrollable);\n\t\t}\n\t};\n}\n\n// (161:8) {#if shouldGroupPresets}\nfunction create_if_block_1$2(ctx) {\n\tlet div;\n\tlet scrollable;\n\tlet t;\n\tlet tabpanels;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\telasticity: /*scrollElasticity*/ ctx[0],\n\t\t\t\tclass: \"PinturaShapePresetsGroups\",\n\t\t\t\t$$slots: { default: [create_default_slot_2$1] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tconst tabpanels_spread_levels = [\n\t\t{ class: \"PinturaControlPanels\" },\n\t\t{ panelClass: \"PinturaControlPanel\" },\n\t\t{ panels: /*panels*/ ctx[11] },\n\t\t/*tabsConfig*/ ctx[12]\n\t];\n\n\tlet tabpanels_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot$5,\n\t\t\t\t({ panel, panelIsActive }) => ({ 26: panel, 27: panelIsActive }),\n\t\t\t\t({ panel, panelIsActive }) => (panel ? 67108864 : 0) | (panelIsActive ? 134217728 : 0)\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tabpanels_spread_levels.length; i += 1) {\n\t\ttabpanels_props = assign(tabpanels_props, tabpanels_spread_levels[i]);\n\t}\n\n\ttabpanels = new TabPanels({ props: tabpanels_props });\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t\tt = space();\n\t\t\tcreate_component(tabpanels.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaShapePresetsGrouped\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(scrollable, div, null);\n\t\t\tappend(div, t);\n\t\t\tmount_component(tabpanels, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty & /*scrollElasticity*/ 1) scrollable_changes.elasticity = /*scrollElasticity*/ ctx[0];\n\n\t\t\tif (dirty & /*$$scope, tabs, tabsConfig, tabSelected, presetToolbar*/ 536876128) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\n\t\t\tconst tabpanels_changes = (dirty & /*panels, tabsConfig*/ 6144)\n\t\t\t? get_spread_update(tabpanels_spread_levels, [\n\t\t\t\t\ttabpanels_spread_levels[0],\n\t\t\t\t\ttabpanels_spread_levels[1],\n\t\t\t\t\tdirty & /*panels*/ 2048 && { panels: /*panels*/ ctx[11] },\n\t\t\t\t\tdirty & /*tabsConfig*/ 4096 && get_spread_object(/*tabsConfig*/ ctx[12])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty & /*$$scope, panelIsActive, shouldRenderPresets, scrollElasticity, presetTabs, panel, onaddpreset, ongrabpreset, ondragpreset, ondroppreset*/ 738206239) {\n\t\t\t\ttabpanels_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttabpanels.$set(tabpanels_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\ttransition_in(tabpanels.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\ttransition_out(tabpanels.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(scrollable);\n\t\t\tdestroy_component(tabpanels);\n\t\t}\n\t};\n}\n\n// (211:16) {#if presetToolbar}\nfunction create_if_block_5$1(ctx) {\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*presetToolbar*/ ctx[10] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*presetToolbar*/ 1024) dynamiccomponenttree_changes.items = /*presetToolbar*/ ctx[10];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t}\n\t};\n}\n\n// (215:16) <Scrollable scrollAutoCancel={shouldRenderPresets} elasticity={scrollElasticity}>\nfunction create_default_slot_5(ctx) {\n\tlet imagebuttonlist;\n\tlet current;\n\n\timagebuttonlist = new ImageButtonList({\n\t\t\tprops: {\n\t\t\t\titems: /*presetsMapped*/ ctx[7],\n\t\t\t\tonclickitem: /*onaddpreset*/ ctx[1],\n\t\t\t\tongrabitem: /*ongrabpreset*/ ctx[2],\n\t\t\t\tondragitem: /*ondragpreset*/ ctx[3],\n\t\t\t\tondropitem: /*ondroppreset*/ ctx[4]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(imagebuttonlist.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(imagebuttonlist, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst imagebuttonlist_changes = {};\n\t\t\tif (dirty & /*presetsMapped*/ 128) imagebuttonlist_changes.items = /*presetsMapped*/ ctx[7];\n\t\t\tif (dirty & /*onaddpreset*/ 2) imagebuttonlist_changes.onclickitem = /*onaddpreset*/ ctx[1];\n\t\t\tif (dirty & /*ongrabpreset*/ 4) imagebuttonlist_changes.ongrabitem = /*ongrabpreset*/ ctx[2];\n\t\t\tif (dirty & /*ondragpreset*/ 8) imagebuttonlist_changes.ondragitem = /*ondragpreset*/ ctx[3];\n\t\t\tif (dirty & /*ondroppreset*/ 16) imagebuttonlist_changes.ondropitem = /*ondroppreset*/ ctx[4];\n\t\t\timagebuttonlist.$set(imagebuttonlist_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(imagebuttonlist.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(imagebuttonlist.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(imagebuttonlist, detaching);\n\t\t}\n\t};\n}\n\n// (164:20) {#if presetToolbar}\nfunction create_if_block_4$1(ctx) {\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*presetToolbar*/ ctx[10] }\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty & /*presetToolbar*/ 1024) dynamiccomponenttree_changes.items = /*presetToolbar*/ ctx[10];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t}\n\t};\n}\n\n// (175:24) {#if tab.icon}\nfunction create_if_block_3$1(ctx) {\n\tlet icon;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_4$1] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty & /*$$scope, tab*/ 805306368) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (176:28) <Icon>\nfunction create_default_slot_4$1(ctx) {\n\tlet g;\n\tlet raw_value = /*tab*/ ctx[28].icon + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*tab*/ 268435456 && raw_value !== (raw_value = /*tab*/ ctx[28].icon + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (178:24) {#if !tab.hideLabel}\nfunction create_if_block_2$2(ctx) {\n\tlet span;\n\tlet t_value = /*tab*/ ctx[28].label + \"\";\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*tab*/ 268435456 && t_value !== (t_value = /*tab*/ ctx[28].label + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (167:20) <TabList                         class=\"PinturaControlList\"                         {tabs}                         {...tabsConfig}                         layout=\"compact\"                         on:select={({ detail }) => (tabSelected = detail)}                         let:tab                     >\nfunction create_default_slot_3$1(ctx) {\n\tlet t;\n\tlet if_block1_anchor;\n\tlet current;\n\tlet if_block0 = /*tab*/ ctx[28].icon && create_if_block_3$1(ctx);\n\tlet if_block1 = !/*tab*/ ctx[28].hideLabel && create_if_block_2$2(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*tab*/ ctx[28].icon) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*tab*/ 268435456) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_3$1(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!/*tab*/ ctx[28].hideLabel) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_2$2(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(if_block1_anchor.parentNode, if_block1_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (163:16) <Scrollable elasticity={scrollElasticity} class=\"PinturaShapePresetsGroups\">\nfunction create_default_slot_2$1(ctx) {\n\tlet t;\n\tlet tablist;\n\tlet current;\n\tlet if_block = /*presetToolbar*/ ctx[10] && create_if_block_4$1(ctx);\n\n\tconst tablist_spread_levels = [\n\t\t{ class: \"PinturaControlList\" },\n\t\t{ tabs: /*tabs*/ ctx[5] },\n\t\t/*tabsConfig*/ ctx[12],\n\t\t{ layout: \"compact\" }\n\t];\n\n\tlet tablist_props = {\n\t\t$$slots: {\n\t\t\tdefault: [\n\t\t\t\tcreate_default_slot_3$1,\n\t\t\t\t({ tab }) => ({ 28: tab }),\n\t\t\t\t({ tab }) => tab ? 268435456 : 0\n\t\t\t]\n\t\t},\n\t\t$$scope: { ctx }\n\t};\n\n\tfor (let i = 0; i < tablist_spread_levels.length; i += 1) {\n\t\ttablist_props = assign(tablist_props, tablist_spread_levels[i]);\n\t}\n\n\ttablist = new TabList({ props: tablist_props });\n\ttablist.$on(\"select\", /*select_handler*/ ctx[18]);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block) if_block.c();\n\t\t\tt = space();\n\t\t\tcreate_component(tablist.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block) if_block.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tmount_component(tablist, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*presetToolbar*/ ctx[10]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty & /*presetToolbar*/ 1024) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_4$1(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tconst tablist_changes = (dirty & /*tabs, tabsConfig*/ 4128)\n\t\t\t? get_spread_update(tablist_spread_levels, [\n\t\t\t\t\ttablist_spread_levels[0],\n\t\t\t\t\tdirty & /*tabs*/ 32 && { tabs: /*tabs*/ ctx[5] },\n\t\t\t\t\tdirty & /*tabsConfig*/ 4096 && get_spread_object(/*tabsConfig*/ ctx[12]),\n\t\t\t\t\ttablist_spread_levels[3]\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tif (dirty & /*$$scope, tab*/ 805306368) {\n\t\t\t\ttablist_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttablist.$set(tablist_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\ttransition_in(tablist.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\ttransition_out(tablist.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d(detaching);\n\t\t\tdestroy_component(tablist, detaching);\n\t\t}\n\t};\n}\n\n// (192:20) <Scrollable                         scroll={panelIsActive ? { scrollOffset: 0, animate: false } : undefined}                         scrollAutoCancel={shouldRenderPresets}                         elasticity={scrollElasticity}                     >\nfunction create_default_slot_1$1(ctx) {\n\tlet imagebuttonlist;\n\tlet current;\n\n\timagebuttonlist = new ImageButtonList({\n\t\t\tprops: {\n\t\t\t\titems: /*presetTabs*/ ctx[13][/*panel*/ ctx[26]].items,\n\t\t\t\tdisabled: /*presetTabs*/ ctx[13][/*panel*/ ctx[26]].disabled,\n\t\t\t\tonclickitem: /*onaddpreset*/ ctx[1],\n\t\t\t\tongrabitem: /*ongrabpreset*/ ctx[2],\n\t\t\t\tondragitem: /*ondragpreset*/ ctx[3],\n\t\t\t\tondropitem: /*ondroppreset*/ ctx[4]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(imagebuttonlist.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(imagebuttonlist, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst imagebuttonlist_changes = {};\n\t\t\tif (dirty & /*presetTabs, panel*/ 67117056) imagebuttonlist_changes.items = /*presetTabs*/ ctx[13][/*panel*/ ctx[26]].items;\n\t\t\tif (dirty & /*presetTabs, panel*/ 67117056) imagebuttonlist_changes.disabled = /*presetTabs*/ ctx[13][/*panel*/ ctx[26]].disabled;\n\t\t\tif (dirty & /*onaddpreset*/ 2) imagebuttonlist_changes.onclickitem = /*onaddpreset*/ ctx[1];\n\t\t\tif (dirty & /*ongrabpreset*/ 4) imagebuttonlist_changes.ongrabitem = /*ongrabpreset*/ ctx[2];\n\t\t\tif (dirty & /*ondragpreset*/ 8) imagebuttonlist_changes.ondragitem = /*ondragpreset*/ ctx[3];\n\t\t\tif (dirty & /*ondroppreset*/ 16) imagebuttonlist_changes.ondropitem = /*ondroppreset*/ ctx[4];\n\t\t\timagebuttonlist.$set(imagebuttonlist_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(imagebuttonlist.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(imagebuttonlist.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(imagebuttonlist, detaching);\n\t\t}\n\t};\n}\n\n// (184:16) <TabPanels                     class=\"PinturaControlPanels\"                     panelClass=\"PinturaControlPanel\"                     {panels}                     {...tabsConfig}                     let:panel                     let:panelIsActive                 >\nfunction create_default_slot$5(ctx) {\n\tlet scrollable;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\tscroll: /*panelIsActive*/ ctx[27]\n\t\t\t\t? { scrollOffset: 0, animate: false }\n\t\t\t\t: undefined,\n\t\t\t\tscrollAutoCancel: /*shouldRenderPresets*/ ctx[9],\n\t\t\t\telasticity: /*scrollElasticity*/ ctx[0],\n\t\t\t\t$$slots: { default: [create_default_slot_1$1] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(scrollable, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\n\t\t\tif (dirty & /*panelIsActive*/ 134217728) scrollable_changes.scroll = /*panelIsActive*/ ctx[27]\n\t\t\t? { scrollOffset: 0, animate: false }\n\t\t\t: undefined;\n\n\t\t\tif (dirty & /*shouldRenderPresets*/ 512) scrollable_changes.scrollAutoCancel = /*shouldRenderPresets*/ ctx[9];\n\t\t\tif (dirty & /*scrollElasticity*/ 1) scrollable_changes.elasticity = /*scrollElasticity*/ ctx[0];\n\n\t\t\tif (dirty & /*$$scope, presetTabs, panel, onaddpreset, ongrabpreset, ondragpreset, ondroppreset*/ 603987998) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(scrollable, detaching);\n\t\t}\n\t};\n}\n\nfunction create_fragment$c(ctx) {\n\tlet div;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet current;\n\tconst if_block_creators = [create_if_block$3, create_if_block_6$1];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*shouldRenderPresets*/ ctx[9]) return 0;\n\t\tif (/*presetToolbar*/ ctx[10]) return 1;\n\t\treturn -1;\n\t}\n\n\tif (~(current_block_type_index = select_block_type(ctx))) {\n\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(div, \"class\", \"PinturaShapePresetsPalette\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].m(div, null);\n\t\t\t}\n\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tgroup_outros();\n\n\t\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\t\tif (!if_block) {\n\t\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\t\tif_block.c();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t\t}\n\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, null);\n\t\t\t\t} else {\n\t\t\t\t\tif_block = null;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].d();\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction instance$c($$self, $$props, $$invalidate) {\n\tlet presetsMapped;\n\tlet shouldRenderPresets;\n\tlet shouldGroupPresets;\n\tlet tabs;\n\tlet presetTabs;\n\tlet tabSelected;\n\tlet tabsConfig;\n\tlet panels;\n\tlet presetToolbar;\n\tlet { locale } = $$props;\n\tlet { presets } = $$props;\n\tlet { scrollElasticity } = $$props;\n\tlet { enableSelectImage = true } = $$props;\n\tlet { willRenderPresetToolbar = passthrough } = $$props;\n\tlet { onaddpreset = noop$1 } = $$props;\n\tlet { ongrabpreset = undefined } = $$props;\n\tlet { ondragpreset = undefined } = $$props;\n\tlet { ondroppreset = undefined } = $$props;\n\tconst uid = `presets-${getUniqueId()}`;\n\tconst isPresetGroup = item => isArray(item) && isString(item[0]) && isArray(item[1]);\n\n\tconst getPresetThumb = (value, alt = '') => {\n\t\t// could be svg\n\t\tif (isSVGMarkup(value)) return value;\n\n\t\t// test if is emoji\n\t\tif (isEmoji(value)) return getEmojiSVG(value, alt);\n\n\t\t// must be URL\n\t\treturn `<img src=\"${value}\" alt=\"${alt}\"/>`;\n\t};\n\n\tconst getAltFromSrc = src => getFilenameWithoutExtension(getFilenameFromURL(src));\n\tconst excludedStickerItemProps = ['src', 'alt', 'thumb', 'shape', 'id', 'mount', 'disabled'];\n\n\tconst mapPreset = item => {\n\t\tlet id = item;\n\t\tlet src;\n\t\tlet shape;\n\t\tlet shapeProps;\n\t\tlet thumb;\n\t\tlet alt;\n\t\tlet mount;\n\t\tlet disabled;\n\n\t\t// if item is a string, it's either an emoji or a URL\n\t\tif (isString(item)) {\n\t\t\t// is emoji\n\t\t\tif (isEmoji(item)) {\n\t\t\t\tsrc = item;\n\t\t\t\talt = item;\n\t\t\t\tthumb = getPresetThumb(src, alt);\n\t\t\t} else // must be URL\n\t\t\t{\n\t\t\t\tsrc = item;\n\t\t\t\talt = getAltFromSrc(src);\n\t\t\t\tthumb = getPresetThumb(src, alt);\n\t\t\t}\n\t\t} else {\n\t\t\t// set custom thumbnail if defined\n\t\t\tsrc = item.src;\n\n\t\t\talt = item.alt || (isString(src)\n\t\t\t? getAltFromSrc(src)\n\t\t\t: isString(item.thumb)\n\t\t\t\t? getAltFromSrc(item.thumb)\n\t\t\t\t: undefined);\n\n\t\t\tthumb = getPresetThumb(item.thumb || src, alt);\n\t\t\tshape = item.shape;\n\t\t\tmount = item.mount;\n\t\t\tdisabled = item.disabled;\n\n\t\t\tshapeProps = Object.keys(item).reduce(\n\t\t\t\t(prev, curr) => {\n\t\t\t\t\tif (excludedStickerItemProps.includes(curr)) return prev;\n\t\t\t\t\tprev[curr] = item[curr];\n\t\t\t\t\treturn prev;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\tsrc,\n\t\t\tthumb,\n\t\t\tshape,\n\t\t\tshapeProps,\n\t\t\talt,\n\t\t\ttitle: alt,\n\t\t\tmount,\n\t\t\tdisabled\n\t\t};\n\t};\n\n\tconst mapPresets = items => items.map(item => {\n\t\tif (isPresetGroup(item)) {\n\t\t\treturn {\n\t\t\t\t...item[2],\n\t\t\t\tid: `${uid}-${item[0].toLowerCase()}`,\n\t\t\t\tlabel: item[0],\n\t\t\t\titems: mapPresets(item[1])\n\t\t\t};\n\t\t}\n\n\t\treturn mapPreset(item);\n\t});\n\n\tconst select_handler = ({ detail }) => $$invalidate(6, tabSelected = detail);\n\n\t$$self.$$set = $$props => {\n\t\tif ('locale' in $$props) $$invalidate(14, locale = $$props.locale);\n\t\tif ('presets' in $$props) $$invalidate(15, presets = $$props.presets);\n\t\tif ('scrollElasticity' in $$props) $$invalidate(0, scrollElasticity = $$props.scrollElasticity);\n\t\tif ('enableSelectImage' in $$props) $$invalidate(16, enableSelectImage = $$props.enableSelectImage);\n\t\tif ('willRenderPresetToolbar' in $$props) $$invalidate(17, willRenderPresetToolbar = $$props.willRenderPresetToolbar);\n\t\tif ('onaddpreset' in $$props) $$invalidate(1, onaddpreset = $$props.onaddpreset);\n\t\tif ('ongrabpreset' in $$props) $$invalidate(2, ongrabpreset = $$props.ongrabpreset);\n\t\tif ('ondragpreset' in $$props) $$invalidate(3, ondragpreset = $$props.ondragpreset);\n\t\tif ('ondroppreset' in $$props) $$invalidate(4, ondroppreset = $$props.ondroppreset);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*presets*/ 32768) {\n\t\t\t$$invalidate(7, presetsMapped = mapPresets(presets));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*presetsMapped*/ 128) {\n\t\t\t$$invalidate(9, shouldRenderPresets = presetsMapped.length);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*shouldRenderPresets, presetsMapped*/ 640) {\n\t\t\t$$invalidate(8, shouldGroupPresets = shouldRenderPresets && presetsMapped.some(preset => !!preset.items));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*shouldGroupPresets, presetsMapped*/ 384) {\n\t\t\t$$invalidate(5, tabs = shouldGroupPresets && presetsMapped);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*shouldGroupPresets, presetsMapped*/ 384) {\n\t\t\t$$invalidate(13, presetTabs = shouldGroupPresets && presetsMapped.reduce(\n\t\t\t\t(prev, curr) => {\n\t\t\t\t\tprev[curr.id] = curr;\n\t\t\t\t\treturn prev;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*tabSelected, tabs*/ 96) {\n\t\t\t$$invalidate(6, tabSelected = tabSelected || tabs && (tabs.find(tab => !tab.disabled) || {}).id);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*tabSelected*/ 64) {\n\t\t\t$$invalidate(12, tabsConfig = { name: uid, selected: tabSelected });\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*tabs*/ 32) {\n\t\t\t$$invalidate(11, panels = tabs && tabs.map(tab => tab.id));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*locale, willRenderPresetToolbar, enableSelectImage, onaddpreset*/ 212994) {\n\t\t\t$$invalidate(10, presetToolbar = locale && willRenderPresetToolbar([\n\t\t\t\tenableSelectImage && [\n\t\t\t\t\t'Button',\n\t\t\t\t\t'browse',\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: locale.shapeLabelButtonSelectSticker,\n\t\t\t\t\t\ticon: locale.shapeIconButtonSelectSticker,\n\t\t\t\t\t\tonclick: () => {\n\t\t\t\t\t\t\tbrowse().then(file => {\n\t\t\t\t\t\t\t\tif (!file) return;\n\t\t\t\t\t\t\t\tonaddpreset(file);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t]));\n\t\t}\n\t};\n\n\treturn [\n\t\tscrollElasticity,\n\t\tonaddpreset,\n\t\tongrabpreset,\n\t\tondragpreset,\n\t\tondroppreset,\n\t\ttabs,\n\t\ttabSelected,\n\t\tpresetsMapped,\n\t\tshouldGroupPresets,\n\t\tshouldRenderPresets,\n\t\tpresetToolbar,\n\t\tpanels,\n\t\ttabsConfig,\n\t\tpresetTabs,\n\t\tlocale,\n\t\tpresets,\n\t\tenableSelectImage,\n\t\twillRenderPresetToolbar,\n\t\tselect_handler\n\t];\n}\n\nclass ShapePresetsPalette extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$c, create_fragment$c, safe_not_equal, {\n\t\t\tlocale: 14,\n\t\t\tpresets: 15,\n\t\t\tscrollElasticity: 0,\n\t\t\tenableSelectImage: 16,\n\t\t\twillRenderPresetToolbar: 17,\n\t\t\tonaddpreset: 1,\n\t\t\tongrabpreset: 2,\n\t\t\tondragpreset: 3,\n\t\t\tondroppreset: 4\n\t\t});\n\t}\n}\n\nvar createPingDispatcher = (node) => (type, data) => {\n    node.dispatchEvent(createPing(type, data));\n};\n\n/* src/core/ui/components/ShapeUtil.svelte generated by Svelte v4.2.20 */\n\nfunction create_default_slot_4(ctx) {\n\tlet dynamiccomponenttree;\n\tlet t;\n\tlet shapestyleeditor;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: { items: /*headerTools*/ ctx[30] }\n\t\t});\n\n\tshapestyleeditor = new ShapeStyleEditor({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tshapeProps: /*shapeStyleShape*/ ctx[49],\n\t\t\t\tonchange: /*handleUpdateSelectedMarkupShape*/ ctx[85],\n\t\t\t\tcontrols: /*shapeControls*/ ctx[9],\n\t\t\t\tscrollEnable: false,\n\t\t\t\thideTitles: true,\n\t\t\t\twillRenderControls: /*func_10*/ ctx[165]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tt = space();\n\t\t\tcreate_component(shapestyleeditor.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tmount_component(shapestyleeditor, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty[0] & /*headerTools*/ 1073741824) dynamiccomponenttree_changes.items = /*headerTools*/ ctx[30];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t\tconst shapestyleeditor_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) shapestyleeditor_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[1] & /*shapeStyleShape*/ 262144) shapestyleeditor_changes.shapeProps = /*shapeStyleShape*/ ctx[49];\n\t\t\tif (dirty[0] & /*shapeControls*/ 512) shapestyleeditor_changes.controls = /*shapeControls*/ ctx[9];\n\t\t\tshapestyleeditor.$set(shapestyleeditor_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\ttransition_in(shapestyleeditor.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\ttransition_out(shapestyleeditor.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t\tdestroy_component(shapestyleeditor, detaching);\n\t\t}\n\t};\n}\n\n// (1361:4) \nfunction create_header_slot(ctx) {\n\tlet div;\n\tlet toolbar_1;\n\tlet current;\n\n\ttoolbar_1 = new Toolbar({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_4] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(toolbar_1.$$.fragment);\n\t\t\tattr(div, \"slot\", \"header\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(toolbar_1, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst toolbar_1_changes = {};\n\n\t\t\tif (dirty[0] & /*locale, shapeControls, headerTools*/ 1073742352 | dirty[1] & /*shapeStyleShape*/ 262144 | dirty[6] & /*$$scope*/ 268435456) {\n\t\t\t\ttoolbar_1_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ttoolbar_1.$set(toolbar_1_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(toolbar_1.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(toolbar_1.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(toolbar_1);\n\t\t}\n\t};\n}\n\n// (1388:8) {#if shouldRenderShapeEditor}\nfunction create_if_block_11(ctx) {\n\tlet shapelayouteditor;\n\tlet current;\n\n\tconst shapelayouteditor_spread_levels = [\n\t\t{ locale: /*locale*/ ctx[4] },\n\t\t{ ui: /*imageOverlayMarkup*/ ctx[69] },\n\t\t{ shapes: /*shapes*/ ctx[5] },\n\t\t{ selection: /*selection*/ ctx[58] },\n\t\t{ uid: /*utilKey*/ ctx[20] },\n\t\t{ parentRect: /*$parentRect*/ ctx[37] },\n\t\t{ rootRect: /*$rootRect*/ ctx[55] },\n\t\t{ utilRect: /*$utilRectPadded*/ ctx[39] },\n\t\t{ offset: /*markupOffset*/ ctx[50] },\n\t\t{\n\t\t\tdisabled: /*$enablePanInputStatus*/ ctx[38]\n\t\t},\n\t\t{\n\t\t\tcontextRotation: /*imageRotation*/ ctx[23]\n\t\t},\n\t\t{ contextFlipX: /*imageFlipX*/ ctx[24] },\n\t\t{ contextFlipY: /*imageFlipY*/ ctx[25] },\n\t\t{\n\t\t\tcontextZoom: /*$imageTransformsInterpolated*/ ctx[36]\n\t\t\t? /*$imageTransformsInterpolated*/ ctx[36].scale\n\t\t\t: undefined\n\t\t},\n\t\t{ active: /*$isActive*/ ctx[35] },\n\t\t{ opacity: /*$isActiveFraction*/ ctx[56] },\n\t\t{\n\t\t\thoverColor: /*$rootColorSecondary*/ ctx[57]\n\t\t},\n\t\t{\n\t\t\tcaretColor: /*$rootColorSecondary*/ ctx[57]\n\t\t},\n\t\t{\n\t\t\tsnapColor: /*$rootColorSecondary*/ ctx[57]\n\t\t},\n\t\t{ gridColor: [1, 1, 1, 0.125] },\n\t\t{ eraseRadius: /*toolEraseRadius*/ ctx[47] },\n\t\t{\n\t\t\tselectRadius: /*toolSelectRadius*/ ctx[6]\n\t\t},\n\t\t{\n\t\t\tenableButtonFlipVertical: /*enableButtonFlipVertical*/ ctx[10]\n\t\t},\n\t\t{\n\t\t\tenableMultiSelect: /*enableMultiSelect*/ ctx[14]\n\t\t},\n\t\t{\n\t\t\tmapEditorPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[21]\n\t\t},\n\t\t{\n\t\t\tmapImagePointToEditorPoint: /*mapImagePointToScreenPoint*/ ctx[22]\n\t\t},\n\t\t{\n\t\t\tenableTapToAddText: /*enableTapToAddText*/ ctx[13]\n\t\t},\n\t\t{ textInputMode: /*textInputMode*/ ctx[8] },\n\t\t{ snapThreshold: /*snapThreshold*/ ctx[16] },\n\t\t{\n\t\t\tsnapPointer: !/*preventPointerSnapping*/ ctx[48]\n\t\t},\n\t\t{\n\t\t\tenableSnapToContext: /*enableSnapToContext*/ ctx[17]\n\t\t},\n\t\t{ gridSize: /*gridSize*/ ctx[15] },\n\t\t{\n\t\t\twillStartInteraction: /*handleWillStartInteraction*/ ctx[95]\n\t\t},\n\t\t{\n\t\t\toninteractionstart: /*handleInteractionStart*/ ctx[79]\n\t\t},\n\t\t{\n\t\t\toninteractionupdate: /*handleInteractionUpdate*/ ctx[80]\n\t\t},\n\t\t{\n\t\t\toninteractionrelease: /*handleInteractionRelease*/ ctx[81]\n\t\t},\n\t\t{\n\t\t\toninteractionend: /*handleInteractionEnd*/ ctx[83]\n\t\t},\n\t\t{\n\t\t\toninteractioncancel: /*handleInteractionCancel*/ ctx[82]\n\t\t},\n\t\t{\n\t\t\tonleavecanvas: /*handleLeaveCanvas*/ ctx[87]\n\t\t},\n\t\t{\n\t\t\tonhovercanvas: /*handleHoverCanvas*/ ctx[86]\n\t\t},\n\t\t{\n\t\t\tonhovershape: /*handleHoverShape*/ ctx[89]\n\t\t},\n\t\t{ ontapcanvas: /*handleTapCanvas*/ ctx[88] },\n\t\t{ onaddshape: /*func_3*/ ctx[156] },\n\t\t{ onselectshape: /*func_4*/ ctx[157] },\n\t\t{ onblurshape: /*func_5*/ ctx[158] },\n\t\t{ ontapshape: /*func_6*/ ctx[159] },\n\t\t{ onupdateshape: /*func_7*/ ctx[160] },\n\t\t{ onremoveshape: /*func_8*/ ctx[161] },\n\t\t{\n\t\t\tontriggerhistorywrite: /*func_9*/ ctx[162]\n\t\t},\n\t\t/*layoutEditorHooks*/ ctx[42]\n\t];\n\n\tlet shapelayouteditor_props = {};\n\n\tfor (let i = 0; i < shapelayouteditor_spread_levels.length; i += 1) {\n\t\tshapelayouteditor_props = assign(shapelayouteditor_props, shapelayouteditor_spread_levels[i]);\n\t}\n\n\tshapelayouteditor = new ShapeLayoutEditor({ props: shapelayouteditor_props });\n\t/*shapelayouteditor_binding*/ ctx[163](shapelayouteditor);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapelayouteditor.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapelayouteditor, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapelayouteditor_changes = (dirty[0] & /*locale, shapes, utilKey, imageRotation, imageFlipX, imageFlipY, toolSelectRadius, enableButtonFlipVertical, enableMultiSelect, mapScreenPointToImagePoint, mapImagePointToScreenPoint, enableTapToAddText, textInputMode, snapThreshold, enableSnapToContext, gridSize*/ 66315632 | dirty[1] & /*selection, $parentRect, $rootRect, $utilRectPadded, markupOffset, $enablePanInputStatus, $imageTransformsInterpolated, $isActive, $isActiveFraction, $rootColorSecondary, toolEraseRadius, preventPointerSnapping, ping, layoutEditorHooks*/ 252381681 | dirty[2] & /*imageOverlayMarkup, handleInteractionStart, handleInteractionUpdate, handleInteractionRelease, handleInteractionEnd, handleInteractionCancel, handleLeaveCanvas, handleHoverCanvas, handleHoverShape, handleTapCanvas*/ 255721600 | dirty[3] & /*handleWillStartInteraction, handleMarkupUpdate*/ 12)\n\t\t\t? get_spread_update(shapelayouteditor_spread_levels, [\n\t\t\t\t\tdirty[0] & /*locale*/ 16 && { locale: /*locale*/ ctx[4] },\n\t\t\t\t\tdirty[2] & /*imageOverlayMarkup*/ 128 && { ui: /*imageOverlayMarkup*/ ctx[69] },\n\t\t\t\t\tdirty[0] & /*shapes*/ 32 && { shapes: /*shapes*/ ctx[5] },\n\t\t\t\t\tdirty[1] & /*selection*/ 134217728 && { selection: /*selection*/ ctx[58] },\n\t\t\t\t\tdirty[0] & /*utilKey*/ 1048576 && { uid: /*utilKey*/ ctx[20] },\n\t\t\t\t\tdirty[1] & /*$parentRect*/ 64 && { parentRect: /*$parentRect*/ ctx[37] },\n\t\t\t\t\tdirty[1] & /*$rootRect*/ 16777216 && { rootRect: /*$rootRect*/ ctx[55] },\n\t\t\t\t\tdirty[1] & /*$utilRectPadded*/ 256 && { utilRect: /*$utilRectPadded*/ ctx[39] },\n\t\t\t\t\tdirty[1] & /*markupOffset*/ 524288 && { offset: /*markupOffset*/ ctx[50] },\n\t\t\t\t\tdirty[1] & /*$enablePanInputStatus*/ 128 && {\n\t\t\t\t\t\tdisabled: /*$enablePanInputStatus*/ ctx[38]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*imageRotation*/ 8388608 && {\n\t\t\t\t\t\tcontextRotation: /*imageRotation*/ ctx[23]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*imageFlipX*/ 16777216 && { contextFlipX: /*imageFlipX*/ ctx[24] },\n\t\t\t\t\tdirty[0] & /*imageFlipY*/ 33554432 && { contextFlipY: /*imageFlipY*/ ctx[25] },\n\t\t\t\t\tdirty[1] & /*$imageTransformsInterpolated*/ 32 && {\n\t\t\t\t\t\tcontextZoom: /*$imageTransformsInterpolated*/ ctx[36]\n\t\t\t\t\t\t? /*$imageTransformsInterpolated*/ ctx[36].scale\n\t\t\t\t\t\t: undefined\n\t\t\t\t\t},\n\t\t\t\t\tdirty[1] & /*$isActive*/ 16 && { active: /*$isActive*/ ctx[35] },\n\t\t\t\t\tdirty[1] & /*$isActiveFraction*/ 33554432 && { opacity: /*$isActiveFraction*/ ctx[56] },\n\t\t\t\t\tdirty[1] & /*$rootColorSecondary*/ 67108864 && {\n\t\t\t\t\t\thoverColor: /*$rootColorSecondary*/ ctx[57]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[1] & /*$rootColorSecondary*/ 67108864 && {\n\t\t\t\t\t\tcaretColor: /*$rootColorSecondary*/ ctx[57]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[1] & /*$rootColorSecondary*/ 67108864 && {\n\t\t\t\t\t\tsnapColor: /*$rootColorSecondary*/ ctx[57]\n\t\t\t\t\t},\n\t\t\t\t\tshapelayouteditor_spread_levels[19],\n\t\t\t\t\tdirty[1] & /*toolEraseRadius*/ 65536 && { eraseRadius: /*toolEraseRadius*/ ctx[47] },\n\t\t\t\t\tdirty[0] & /*toolSelectRadius*/ 64 && {\n\t\t\t\t\t\tselectRadius: /*toolSelectRadius*/ ctx[6]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*enableButtonFlipVertical*/ 1024 && {\n\t\t\t\t\t\tenableButtonFlipVertical: /*enableButtonFlipVertical*/ ctx[10]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*enableMultiSelect*/ 16384 && {\n\t\t\t\t\t\tenableMultiSelect: /*enableMultiSelect*/ ctx[14]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*mapScreenPointToImagePoint*/ 2097152 && {\n\t\t\t\t\t\tmapEditorPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[21]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*mapImagePointToScreenPoint*/ 4194304 && {\n\t\t\t\t\t\tmapImagePointToEditorPoint: /*mapImagePointToScreenPoint*/ ctx[22]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*enableTapToAddText*/ 8192 && {\n\t\t\t\t\t\tenableTapToAddText: /*enableTapToAddText*/ ctx[13]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*textInputMode*/ 256 && { textInputMode: /*textInputMode*/ ctx[8] },\n\t\t\t\t\tdirty[0] & /*snapThreshold*/ 65536 && { snapThreshold: /*snapThreshold*/ ctx[16] },\n\t\t\t\t\tdirty[1] & /*preventPointerSnapping*/ 131072 && {\n\t\t\t\t\t\tsnapPointer: !/*preventPointerSnapping*/ ctx[48]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*enableSnapToContext*/ 131072 && {\n\t\t\t\t\t\tenableSnapToContext: /*enableSnapToContext*/ ctx[17]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[0] & /*gridSize*/ 32768 && { gridSize: /*gridSize*/ ctx[15] },\n\t\t\t\t\tdirty[3] & /*handleWillStartInteraction*/ 4 && {\n\t\t\t\t\t\twillStartInteraction: /*handleWillStartInteraction*/ ctx[95]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleInteractionStart*/ 131072 && {\n\t\t\t\t\t\toninteractionstart: /*handleInteractionStart*/ ctx[79]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleInteractionUpdate*/ 262144 && {\n\t\t\t\t\t\toninteractionupdate: /*handleInteractionUpdate*/ ctx[80]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleInteractionRelease*/ 524288 && {\n\t\t\t\t\t\toninteractionrelease: /*handleInteractionRelease*/ ctx[81]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleInteractionEnd*/ 2097152 && {\n\t\t\t\t\t\toninteractionend: /*handleInteractionEnd*/ ctx[83]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleInteractionCancel*/ 1048576 && {\n\t\t\t\t\t\toninteractioncancel: /*handleInteractionCancel*/ ctx[82]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleLeaveCanvas*/ 33554432 && {\n\t\t\t\t\t\tonleavecanvas: /*handleLeaveCanvas*/ ctx[87]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleHoverCanvas*/ 16777216 && {\n\t\t\t\t\t\tonhovercanvas: /*handleHoverCanvas*/ ctx[86]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleHoverShape*/ 134217728 && {\n\t\t\t\t\t\tonhovershape: /*handleHoverShape*/ ctx[89]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[2] & /*handleTapCanvas*/ 67108864 && { ontapcanvas: /*handleTapCanvas*/ ctx[88] },\n\t\t\t\t\tdirty[1] & /*ping*/ 1 | dirty[3] & /*handleMarkupUpdate*/ 8 && { onaddshape: /*func_3*/ ctx[156] },\n\t\t\t\t\tdirty[1] & /*ping*/ 1 && { onselectshape: /*func_4*/ ctx[157] },\n\t\t\t\t\tdirty[1] & /*ping*/ 1 && { onblurshape: /*func_5*/ ctx[158] },\n\t\t\t\t\tdirty[1] & /*ping*/ 1 && { ontapshape: /*func_6*/ ctx[159] },\n\t\t\t\t\tdirty[1] & /*ping*/ 1 | dirty[3] & /*handleMarkupUpdate*/ 8 && { onupdateshape: /*func_7*/ ctx[160] },\n\t\t\t\t\tdirty[1] & /*ping*/ 1 | dirty[3] & /*handleMarkupUpdate*/ 8 && { onremoveshape: /*func_8*/ ctx[161] },\n\t\t\t\t\tdirty[3] & /*handleMarkupUpdate*/ 8 && {\n\t\t\t\t\t\tontriggerhistorywrite: /*func_9*/ ctx[162]\n\t\t\t\t\t},\n\t\t\t\t\tdirty[1] & /*layoutEditorHooks*/ 2048 && get_spread_object(/*layoutEditorHooks*/ ctx[42])\n\t\t\t\t])\n\t\t\t: {};\n\n\t\t\tshapelayouteditor.$set(shapelayouteditor_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapelayouteditor.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapelayouteditor.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\t/*shapelayouteditor_binding*/ ctx[163](null);\n\t\t\tdestroy_component(shapelayouteditor, detaching);\n\t\t}\n\t};\n}\n\n// (1378:4) \nfunction create_main_slot(ctx) {\n\tlet div;\n\tlet dropable_action;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tlet if_block = /*shouldRenderShapeEditor*/ ctx[51] && create_if_block_11(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tattr(div, \"slot\", \"main\");\n\t\t\tset_style(div, \"cursor\", /*cursorStyle*/ ctx[46]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\t/*div_binding*/ ctx[164](div);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div, \"keydown\", /*handleKey*/ ctx[84]),\n\t\t\t\t\taction_destroyer(dropable_action = dropable.call(null, div, {\n\t\t\t\t\t\tdisabled: !/*enablePresetDropImage*/ ctx[12]\n\t\t\t\t\t})),\n\t\t\t\t\tlisten(div, \"dropfiles\", /*handleDropFiles*/ ctx[94]),\n\t\t\t\t\taction_destroyer(measurable.call(null, div)),\n\t\t\t\t\tlisten(div, \"measure\", /*measure_handler_1*/ ctx[152])\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*shouldRenderShapeEditor*/ ctx[51]) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*shouldRenderShapeEditor*/ 1048576) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_11(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (dropable_action && is_function(dropable_action.update) && dirty[0] & /*enablePresetDropImage*/ 4096) dropable_action.update.call(null, {\n\t\t\t\tdisabled: !/*enablePresetDropImage*/ ctx[12]\n\t\t\t});\n\n\t\t\tif (dirty[1] & /*cursorStyle*/ 32768) {\n\t\t\t\tset_style(div, \"cursor\", /*cursorStyle*/ ctx[46]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t\t/*div_binding*/ ctx[164](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\n// (1558:38) \nfunction create_if_block_10(ctx) {\n\tlet shapepresetspalette;\n\tlet current;\n\n\tshapepresetspalette = new ShapePresetsPalette({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tpresets: /*shapePresets*/ ctx[19],\n\t\t\t\tenableSelectImage: /*enablePresetSelectImage*/ ctx[11],\n\t\t\t\twillRenderPresetToolbar: /*runWillRenderPresetToolbarHook*/ ctx[43],\n\t\t\t\tonaddpreset: /*handleAddPreset*/ ctx[93],\n\t\t\t\tongrabpreset: /*handleGrabPreset*/ ctx[90],\n\t\t\t\tondragpreset: /*handleDragPreset*/ ctx[91],\n\t\t\t\tondroppreset: /*handleDropPreset*/ ctx[92],\n\t\t\t\tscrollElasticity: /*computedScrollElasticity*/ ctx[44]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapepresetspalette.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapepresetspalette, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapepresetspalette_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) shapepresetspalette_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[0] & /*shapePresets*/ 524288) shapepresetspalette_changes.presets = /*shapePresets*/ ctx[19];\n\t\t\tif (dirty[0] & /*enablePresetSelectImage*/ 2048) shapepresetspalette_changes.enableSelectImage = /*enablePresetSelectImage*/ ctx[11];\n\t\t\tif (dirty[1] & /*runWillRenderPresetToolbarHook*/ 4096) shapepresetspalette_changes.willRenderPresetToolbar = /*runWillRenderPresetToolbarHook*/ ctx[43];\n\t\t\tif (dirty[1] & /*computedScrollElasticity*/ 8192) shapepresetspalette_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[44];\n\t\t\tshapepresetspalette.$set(shapepresetspalette_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapepresetspalette.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapepresetspalette.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapepresetspalette, detaching);\n\t\t}\n\t};\n}\n\n// (1469:8) {#if shouldRenderControls}\nfunction create_if_block_2$1(ctx) {\n\tlet t;\n\tlet if_block1_anchor;\n\tlet current;\n\tlet if_block0 = /*toolbarLayout*/ ctx[7] === 'stack' && create_if_block_8(ctx);\n\tlet if_block1 = (/*showToolbar*/ ctx[53] && /*hasMultipleTools*/ ctx[34] || /*toolbarLayout*/ ctx[7] === 'row') && create_if_block_3(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*toolbarLayout*/ ctx[7] === 'stack') {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*toolbarLayout*/ 128) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_8(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*showToolbar*/ ctx[53] && /*hasMultipleTools*/ ctx[34] || /*toolbarLayout*/ ctx[7] === 'row') {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*toolbarLayout*/ 128 | dirty[1] & /*showToolbar, hasMultipleTools*/ 4194312) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_3(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(if_block1_anchor.parentNode, if_block1_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (1470:12) {#if toolbarLayout === 'stack'}\nfunction create_if_block_8(ctx) {\n\tlet div;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet current;\n\tconst if_block_creators = [create_if_block_9, create_else_block$2];\n\tconst if_blocks = [];\n\n\tfunction select_block_type_1(ctx, dirty) {\n\t\tif (/*shouldRenderPresets*/ ctx[45]) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type_1(ctx);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif_block.c();\n\t\t\tattr(div, \"class\", \"PinturaControlPanels\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif_blocks[current_block_type_index].m(div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type_1(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(div, null);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d();\n\t\t}\n\t};\n}\n\n// (1486:20) {:else}\nfunction create_else_block$2(ctx) {\n\tlet div;\n\tlet shapestyleeditor;\n\tlet current;\n\n\tshapestyleeditor = new ShapeStyleEditor({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tshapeProps: /*shapeStyleShape*/ ctx[49],\n\t\t\t\tonchange: /*handleUpdateSelectedMarkupShape*/ ctx[85],\n\t\t\t\tcontrols: /*shapeControls*/ ctx[9],\n\t\t\t\tscrollElasticity: /*computedScrollElasticity*/ ctx[44],\n\t\t\t\twillRenderControls: /*willRenderShapeStyleControls*/ ctx[18]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(shapestyleeditor.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaControlPanel\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(shapestyleeditor, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapestyleeditor_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) shapestyleeditor_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[1] & /*shapeStyleShape*/ 262144) shapestyleeditor_changes.shapeProps = /*shapeStyleShape*/ ctx[49];\n\t\t\tif (dirty[0] & /*shapeControls*/ 512) shapestyleeditor_changes.controls = /*shapeControls*/ ctx[9];\n\t\t\tif (dirty[1] & /*computedScrollElasticity*/ 8192) shapestyleeditor_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[44];\n\t\t\tif (dirty[0] & /*willRenderShapeStyleControls*/ 262144) shapestyleeditor_changes.willRenderControls = /*willRenderShapeStyleControls*/ ctx[18];\n\t\t\tshapestyleeditor.$set(shapestyleeditor_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapestyleeditor.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapestyleeditor.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(shapestyleeditor);\n\t\t}\n\t};\n}\n\n// (1472:20) {#if shouldRenderPresets}\nfunction create_if_block_9(ctx) {\n\tlet div;\n\tlet shapepresetspalette;\n\tlet current;\n\n\tshapepresetspalette = new ShapePresetsPalette({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tpresets: /*shapePresets*/ ctx[19],\n\t\t\t\tenableSelectImage: /*enablePresetSelectImage*/ ctx[11],\n\t\t\t\twillRenderPresetToolbar: /*runWillRenderPresetToolbarHook*/ ctx[43],\n\t\t\t\tonaddpreset: /*handleAddPreset*/ ctx[93],\n\t\t\t\tongrabpreset: /*handleGrabPreset*/ ctx[90],\n\t\t\t\tondragpreset: /*handleDragPreset*/ ctx[91],\n\t\t\t\tondroppreset: /*handleDropPreset*/ ctx[92],\n\t\t\t\tscrollElasticity: /*computedScrollElasticity*/ ctx[44]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(shapepresetspalette.$$.fragment);\n\t\t\tattr(div, \"class\", \"PinturaControlPanel\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(shapepresetspalette, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapepresetspalette_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) shapepresetspalette_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[0] & /*shapePresets*/ 524288) shapepresetspalette_changes.presets = /*shapePresets*/ ctx[19];\n\t\t\tif (dirty[0] & /*enablePresetSelectImage*/ 2048) shapepresetspalette_changes.enableSelectImage = /*enablePresetSelectImage*/ ctx[11];\n\t\t\tif (dirty[1] & /*runWillRenderPresetToolbarHook*/ 4096) shapepresetspalette_changes.willRenderPresetToolbar = /*runWillRenderPresetToolbarHook*/ ctx[43];\n\t\t\tif (dirty[1] & /*computedScrollElasticity*/ 8192) shapepresetspalette_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[44];\n\t\t\tshapepresetspalette.$set(shapepresetspalette_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapepresetspalette.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapepresetspalette.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(shapepresetspalette);\n\t\t}\n\t};\n}\n\n// (1500:12) {#if (showToolbar && hasMultipleTools) || toolbarLayout === 'row'}\nfunction create_if_block_3(ctx) {\n\tlet scrollable;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaControlListScroller\",\n\t\t\t\telasticity: /*computedScrollElasticity*/ ctx[44],\n\t\t\t\t$$slots: { default: [create_default_slot_2] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(scrollable, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty[1] & /*computedScrollElasticity*/ 8192) scrollable_changes.elasticity = /*computedScrollElasticity*/ ctx[44];\n\n\t\t\tif (dirty[0] & /*locale, shapeControls, willRenderShapeStyleControls, toolbarLayout, toolActive*/ 262801 | dirty[1] & /*shapeStyleShape, toolsFiltered, hasMultipleTools*/ 262154 | dirty[6] & /*$$scope*/ 268435456) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(scrollable, detaching);\n\t\t}\n\t};\n}\n\n// (1505:20) {#if hasMultipleTools}\nfunction create_if_block_5(ctx) {\n\tlet radiogroup;\n\tlet current;\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tclass: \"PinturaControlList\",\n\t\t\t\toptionClass: \"PinturaControlListOption\",\n\t\t\t\tlayout: \"row\",\n\t\t\t\toptions: /*toolsFiltered*/ ctx[32],\n\t\t\t\tselectedIndex: /*toolsFiltered*/ ctx[32].findIndex(/*func*/ ctx[153]),\n\t\t\t\tonchange: /*updateActiveTool*/ ctx[78],\n\t\t\t\t$$slots: {\n\t\t\t\t\toption: [\n\t\t\t\t\t\tcreate_option_slot_1,\n\t\t\t\t\t\t({ option }) => ({ 213: option }),\n\t\t\t\t\t\t({ option }) => [0, 0, 0, 0, 0, 0, option ? 134217728 : 0]\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radiogroup, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) radiogroup_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[1] & /*toolsFiltered*/ 2) radiogroup_changes.options = /*toolsFiltered*/ ctx[32];\n\t\t\tif (dirty[0] & /*toolActive*/ 1 | dirty[1] & /*toolsFiltered*/ 2) radiogroup_changes.selectedIndex = /*toolsFiltered*/ ctx[32].findIndex(/*func*/ ctx[153]);\n\n\t\t\tif (dirty[0] & /*locale*/ 16 | dirty[6] & /*$$scope, option*/ 402653184) {\n\t\t\t\tradiogroup_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radiogroup, detaching);\n\t\t}\n\t};\n}\n\n// (1518:32) {#if option.icon}\nfunction create_if_block_7(ctx) {\n\tlet icon;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_3] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty[0] & /*locale*/ 16 | dirty[6] & /*$$scope, option*/ 402653184) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (1519:36) <Icon                                         >\nfunction create_default_slot_3(ctx) {\n\tlet g;\n\n\tlet raw_value = (isFunction(/*option*/ ctx[213].icon)\n\t? /*option*/ ctx[213].icon(/*locale*/ ctx[4])\n\t: /*option*/ ctx[213].icon) + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*locale*/ 16 | dirty[6] & /*option*/ 134217728 && raw_value !== (raw_value = (isFunction(/*option*/ ctx[213].icon)\n\t\t\t? /*option*/ ctx[213].icon(/*locale*/ ctx[4])\n\t\t\t: /*option*/ ctx[213].icon) + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (1527:32) {#if !option.hideLabel}\nfunction create_if_block_6(ctx) {\n\tlet span;\n\n\tlet t_value = (isFunction(/*option*/ ctx[213].label)\n\t? /*option*/ ctx[213].label(/*locale*/ ctx[4])\n\t: /*option*/ ctx[213].label) + \"\";\n\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*locale*/ 16 | dirty[6] & /*option*/ 134217728 && t_value !== (t_value = (isFunction(/*option*/ ctx[213].label)\n\t\t\t? /*option*/ ctx[213].label(/*locale*/ ctx[4])\n\t\t\t: /*option*/ ctx[213].label) + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (1517:28) \nfunction create_option_slot_1(ctx) {\n\tlet div;\n\tlet t;\n\tlet current;\n\tlet if_block0 = /*option*/ ctx[213].icon && create_if_block_7(ctx);\n\tlet if_block1 = !/*option*/ ctx[213].hideLabel && create_if_block_6(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(div, \"slot\", \"option\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block0) if_block0.m(div, null);\n\t\t\tappend(div, t);\n\t\t\tif (if_block1) if_block1.m(div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*option*/ ctx[213].icon) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[6] & /*option*/ 134217728) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_7(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (!/*option*/ ctx[213].hideLabel) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_6(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t}\n\t};\n}\n\n// (1538:20) {#if toolbarLayout === 'row'}\nfunction create_if_block_4(ctx) {\n\tlet shapestyleeditor;\n\tlet current;\n\n\tshapestyleeditor = new ShapeStyleEditor({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tshapeProps: /*shapeStyleShape*/ ctx[49],\n\t\t\t\tonchange: /*handleUpdateSelectedMarkupShape*/ ctx[85],\n\t\t\t\tcontrols: /*shapeControls*/ ctx[9],\n\t\t\t\tscrollEnable: false,\n\t\t\t\thideTitles: true,\n\t\t\t\twillRenderControls: /*func_1*/ ctx[154]\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapestyleeditor.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapestyleeditor, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapestyleeditor_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) shapestyleeditor_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[1] & /*shapeStyleShape*/ 262144) shapestyleeditor_changes.shapeProps = /*shapeStyleShape*/ ctx[49];\n\t\t\tif (dirty[0] & /*shapeControls*/ 512) shapestyleeditor_changes.controls = /*shapeControls*/ ctx[9];\n\t\t\tif (dirty[0] & /*willRenderShapeStyleControls*/ 262144) shapestyleeditor_changes.willRenderControls = /*func_1*/ ctx[154];\n\t\t\tshapestyleeditor.$set(shapestyleeditor_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapestyleeditor.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapestyleeditor.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapestyleeditor, detaching);\n\t\t}\n\t};\n}\n\n// (1501:16) <Scrollable                     class=\"PinturaControlListScroller\"                     elasticity={computedScrollElasticity}                 >\nfunction create_default_slot_2(ctx) {\n\tlet t;\n\tlet if_block1_anchor;\n\tlet current;\n\tlet if_block0 = /*hasMultipleTools*/ ctx[34] && create_if_block_5(ctx);\n\tlet if_block1 = /*toolbarLayout*/ ctx[7] === 'row' && create_if_block_4(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tif_block1_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (if_block0) if_block0.m(target, anchor);\n\t\t\tinsert(target, t, anchor);\n\t\t\tif (if_block1) if_block1.m(target, anchor);\n\t\t\tinsert(target, if_block1_anchor, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*hasMultipleTools*/ ctx[34]) {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*hasMultipleTools*/ 8) {\n\t\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = create_if_block_5(ctx);\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(t.parentNode, t);\n\t\t\t\t}\n\t\t\t} else if (if_block0) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block0, 1, 1, () => {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (/*toolbarLayout*/ ctx[7] === 'row') {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[0] & /*toolbarLayout*/ 128) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block_4(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(if_block1_anchor.parentNode, if_block1_anchor);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t\tdetach(if_block1_anchor);\n\t\t\t}\n\n\t\t\tif (if_block0) if_block0.d(detaching);\n\t\t\tif (if_block1) if_block1.d(detaching);\n\t\t}\n\t};\n}\n\n// (1571:8) {#if hasToolbarGroups}\nfunction create_if_block$2(ctx) {\n\tlet scrollable;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\tclass: \"PinturaControlListScroller\",\n\t\t\t\telasticity: /*computedScrollElasticity*/ ctx[44],\n\t\t\t\t$$slots: { default: [create_default_slot$4] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(scrollable, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty[1] & /*computedScrollElasticity*/ 8192) scrollable_changes.elasticity = /*computedScrollElasticity*/ ctx[44];\n\n\t\t\tif (dirty[0] & /*locale, toolGroupActiveIndex*/ 134217744 | dirty[1] & /*toolbarGroups*/ 8388608 | dirty[6] & /*$$scope*/ 268435456) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(scrollable, detaching);\n\t\t}\n\t};\n}\n\n// (1585:24) {#if option.icon}\nfunction create_if_block_1$1(ctx) {\n\tlet icon;\n\tlet current;\n\n\ticon = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot_1] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(icon.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(icon, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst icon_changes = {};\n\n\t\t\tif (dirty[0] & /*locale*/ 16 | dirty[6] & /*$$scope, option*/ 402653184) {\n\t\t\t\ticon_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon.$set(icon_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(icon, detaching);\n\t\t}\n\t};\n}\n\n// (1586:28) <Icon                                 >\nfunction create_default_slot_1(ctx) {\n\tlet g;\n\n\tlet raw_value = (isFunction(/*option*/ ctx[213].icon)\n\t? /*option*/ ctx[213].icon(/*locale*/ ctx[4])\n\t: /*option*/ ctx[213].icon) + \"\";\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = raw_value;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*locale*/ 16 | dirty[6] & /*option*/ 134217728 && raw_value !== (raw_value = (isFunction(/*option*/ ctx[213].icon)\n\t\t\t? /*option*/ ctx[213].icon(/*locale*/ ctx[4])\n\t\t\t: /*option*/ ctx[213].icon) + \"\")) g.innerHTML = raw_value;\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (1584:20) \nfunction create_option_slot$2(ctx) {\n\tlet div;\n\tlet t0;\n\tlet span;\n\n\tlet t1_value = (isFunction(/*option*/ ctx[213].label)\n\t? /*option*/ ctx[213].label(/*locale*/ ctx[4])\n\t: /*option*/ ctx[213].label) + \"\";\n\n\tlet t1;\n\tlet current;\n\tlet if_block = /*option*/ ctx[213].icon && create_if_block_1$1(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block) if_block.c();\n\t\t\tt0 = space();\n\t\t\tspan = element(\"span\");\n\t\t\tt1 = text(t1_value);\n\t\t\tattr(div, \"slot\", \"option\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif (if_block) if_block.m(div, null);\n\t\t\tappend(div, t0);\n\t\t\tappend(div, span);\n\t\t\tappend(span, t1);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (/*option*/ ctx[213].icon) {\n\t\t\t\tif (if_block) {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[6] & /*option*/ 134217728) {\n\t\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block = create_if_block_1$1(ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\t\tif_block.m(div, t0);\n\t\t\t\t}\n\t\t\t} else if (if_block) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block, 1, 1, () => {\n\t\t\t\t\tif_block = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif ((!current || dirty[0] & /*locale*/ 16 | dirty[6] & /*option*/ 134217728) && t1_value !== (t1_value = (isFunction(/*option*/ ctx[213].label)\n\t\t\t? /*option*/ ctx[213].label(/*locale*/ ctx[4])\n\t\t\t: /*option*/ ctx[213].label) + \"\")) set_data(t1, t1_value);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (if_block) if_block.d();\n\t\t}\n\t};\n}\n\n// (1572:12) <Scrollable class=\"PinturaControlListScroller\" elasticity={computedScrollElasticity}>\nfunction create_default_slot$4(ctx) {\n\tlet radiogroup;\n\tlet current;\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tclass: \"PinturaControlList\",\n\t\t\t\toptionClass: \"PinturaControlListOption\",\n\t\t\t\tlayout: \"row\",\n\t\t\t\toptions: /*toolbarGroups*/ ctx[54],\n\t\t\t\tselectedIndex: /*toolbarGroups*/ ctx[54].findIndex(/*func_2*/ ctx[155]),\n\t\t\t\tonchange: /*updateActiveToolGroup*/ ctx[77],\n\t\t\t\t$$slots: {\n\t\t\t\t\toption: [\n\t\t\t\t\t\tcreate_option_slot$2,\n\t\t\t\t\t\t({ option }) => ({ 213: option }),\n\t\t\t\t\t\t({ option }) => [0, 0, 0, 0, 0, 0, option ? 134217728 : 0]\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radiogroup, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 16) radiogroup_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[1] & /*toolbarGroups*/ 8388608) radiogroup_changes.options = /*toolbarGroups*/ ctx[54];\n\t\t\tif (dirty[0] & /*toolGroupActiveIndex*/ 134217728 | dirty[1] & /*toolbarGroups*/ 8388608) radiogroup_changes.selectedIndex = /*toolbarGroups*/ ctx[54].findIndex(/*func_2*/ ctx[155]);\n\n\t\t\tif (dirty[0] & /*locale*/ 16 | dirty[6] & /*$$scope, option*/ 402653184) {\n\t\t\t\tradiogroup_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radiogroup, detaching);\n\t\t}\n\t};\n}\n\n// (1468:4) \nfunction create_footer_slot$3(ctx) {\n\tlet div;\n\tlet current_block_type_index;\n\tlet if_block0;\n\tlet t;\n\tlet current;\n\tconst if_block_creators = [create_if_block_2$1, create_if_block_10];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (/*shouldRenderControls*/ ctx[52]) return 0;\n\t\tif (/*shouldRenderPresets*/ ctx[45]) return 1;\n\t\treturn -1;\n\t}\n\n\tif (~(current_block_type_index = select_block_type(ctx))) {\n\t\tif_block0 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t}\n\n\tlet if_block1 = /*hasToolbarGroups*/ ctx[33] && create_if_block$2(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif (if_block0) if_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(div, \"slot\", \"footer\");\n\t\t\tset_style(div, \"transform\", /*styleTransform*/ ctx[40]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].m(div, null);\n\t\t\t}\n\n\t\t\tappend(div, t);\n\t\t\tif (if_block1) if_block1.m(div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tgroup_outros();\n\n\t\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t\t});\n\n\t\t\t\t\tcheck_outros();\n\t\t\t\t}\n\n\t\t\t\tif (~current_block_type_index) {\n\t\t\t\t\tif_block0 = if_blocks[current_block_type_index];\n\n\t\t\t\t\tif (!if_block0) {\n\t\t\t\t\t\tif_block0 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\t\tif_block0.c();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif_block0.p(ctx, dirty);\n\t\t\t\t\t}\n\n\t\t\t\t\ttransition_in(if_block0, 1);\n\t\t\t\t\tif_block0.m(div, t);\n\t\t\t\t} else {\n\t\t\t\t\tif_block0 = null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (/*hasToolbarGroups*/ ctx[33]) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\n\t\t\t\t\tif (dirty[1] & /*hasToolbarGroups*/ 4) {\n\t\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block$2(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\ttransition_in(if_block1, 1);\n\t\t\t\t\tif_block1.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_block1, 1, 1, () => {\n\t\t\t\t\tif_block1 = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t}\n\n\t\t\tif (dirty[1] & /*styleTransform*/ 512) {\n\t\t\t\tset_style(div, \"transform\", /*styleTransform*/ ctx[40]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block0);\n\t\t\ttransition_in(if_block1);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block0);\n\t\t\ttransition_out(if_block1);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif (~current_block_type_index) {\n\t\t\t\tif_blocks[current_block_type_index].d();\n\t\t\t}\n\n\t\t\tif (if_block1) if_block1.d();\n\t\t}\n\t};\n}\n\nfunction create_fragment$b(ctx) {\n\tlet util;\n\tlet current;\n\n\tutil = new Util({\n\t\t\tprops: {\n\t\t\t\thasHeader: /*shouldRenderHeaderTools*/ ctx[41],\n\t\t\t\t$$slots: {\n\t\t\t\t\tfooter: [create_footer_slot$3],\n\t\t\t\t\tmain: [create_main_slot],\n\t\t\t\t\theader: [create_header_slot]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tutil.$on(\"measure\", /*measure_handler*/ ctx[166]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(util.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(util, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst util_changes = {};\n\t\t\tif (dirty[1] & /*shouldRenderHeaderTools*/ 1024) util_changes.hasHeader = /*shouldRenderHeaderTools*/ ctx[41];\n\n\t\t\tif (dirty[0] & /*locale, toolGroupActiveIndex, shapeControls, willRenderShapeStyleControls, toolbarLayout, toolActive, shapePresets, enablePresetSelectImage, pingHub, enablePresetDropImage, shapes, utilKey, imageRotation, imageFlipX, imageFlipY, toolSelectRadius, enableButtonFlipVertical, enableMultiSelect, mapScreenPointToImagePoint, mapImagePointToScreenPoint, enableTapToAddText, textInputMode, snapThreshold, enableSnapToContext, gridSize, markupEditor, headerTools*/ 2080374769 | dirty[1] & /*styleTransform, computedScrollElasticity, toolbarGroups, hasToolbarGroups, shapeStyleShape, toolsFiltered, hasMultipleTools, showToolbar, runWillRenderPresetToolbarHook, shouldRenderPresets, shouldRenderControls, cursorStyle, $parentRect, $rootRect, $utilRectPadded, markupOffset, $enablePanInputStatus, $imageTransformsInterpolated, $isActive, $isActiveFraction, $rootColorSecondary, toolEraseRadius, preventPointerSnapping, ping, layoutEditorHooks, shouldRenderShapeEditor*/ 134216703 | dirty[6] & /*$$scope*/ 268435456) {\n\t\t\t\tutil_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tutil.$set(util_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(util.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(util.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(util, detaching);\n\t\t}\n\t};\n}\n\nlet isPanning = false;\n\nfunction instance$b($$self, $$props, $$invalidate) {\n\tlet holdingOptionKey;\n\tlet hasToolbarGroups;\n\tlet toolbarGroups;\n\tlet activeToolbar;\n\tlet toolsFiltered;\n\tlet hasShapeControls;\n\tlet hasMultipleTools;\n\tlet hasTools;\n\tlet showToolbar;\n\tlet hasActiveTool;\n\tlet shouldRenderControls;\n\tlet toolOptions;\n\tlet interactionMode;\n\tlet shouldRenderShapeEditor;\n\tlet markupOffset;\n\tlet markupShapeKeys;\n\tlet multiSelection;\n\tlet isMultiSelection;\n\tlet markupSelected;\n\tlet markupEditing;\n\tlet markupDraft;\n\tlet markupToolShape;\n\tlet markupToolStylesComputed;\n\tlet markupShapeSelected;\n\tlet shapeStyleShape;\n\tlet preventPointerSnapping;\n\tlet toolEraseRadius;\n\tlet userEnabledPanModeWithKeyboard;\n\tlet userEnabledPanModeWithButton;\n\tlet enablePanMode;\n\tlet isEditingText;\n\tlet customCursor;\n\tlet isHoveringOverImage;\n\tlet cursorStyle;\n\tlet shouldRenderPresets;\n\tlet shouldStickToImage;\n\tlet ping;\n\tlet computedScrollElasticity;\n\tlet runWillRenderPresetToolbarHook;\n\tlet layoutEditorHooks;\n\tlet headerTools;\n\tlet shouldRenderHeaderTools;\n\tlet styleTransform;\n\tlet $footerOffset;\n\n\tlet $isActive,\n\t\t$$unsubscribe_isActive = noop,\n\t\t$$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(35, $isActive = $$value)), isActive);\n\n\tlet $isAnimated;\n\tlet $env;\n\tlet $redrawTrigger;\n\n\tlet $shapes,\n\t\t$$unsubscribe_shapes = noop,\n\t\t$$subscribe_shapes = () => ($$unsubscribe_shapes(), $$unsubscribe_shapes = subscribe(shapes, $$value => $$invalidate(145, $shapes = $$value)), shapes);\n\n\tlet $elasticityMultiplier;\n\tlet $stageRect;\n\tlet $imageTransformsInterpolated;\n\tlet $imageSelectionPan;\n\tlet $stageScalar;\n\tlet $imageSelectionRect;\n\n\tlet $parentRect,\n\t\t$$unsubscribe_parentRect = noop,\n\t\t$$subscribe_parentRect = () => ($$unsubscribe_parentRect(), $$unsubscribe_parentRect = subscribe(parentRect, $$value => $$invalidate(37, $parentRect = $$value)), parentRect);\n\n\tlet $imageCropRect;\n\tlet $enablePanInputStatus;\n\tlet $imageSize;\n\tlet $keysPressedStore;\n\tlet $selection;\n\tlet $ui;\n\tlet $utilRectPadded;\n\n\tlet $isVisible,\n\t\t$$unsubscribe_isVisible = noop,\n\t\t$$subscribe_isVisible = () => ($$unsubscribe_isVisible(), $$unsubscribe_isVisible = subscribe(isVisible, $$value => $$invalidate(151, $isVisible = $$value)), isVisible);\n\n\tlet $imagePreviewModifiers;\n\tlet $rootRect;\n\n\tlet $isActiveFraction,\n\t\t$$unsubscribe_isActiveFraction = noop,\n\t\t$$subscribe_isActiveFraction = () => ($$unsubscribe_isActiveFraction(), $$unsubscribe_isActiveFraction = subscribe(isActiveFraction, $$value => $$invalidate(56, $isActiveFraction = $$value)), isActiveFraction);\n\n\tlet $rootColorSecondary;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActive());\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_shapes());\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_parentRect());\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isVisible());\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActiveFraction());\n\tlet { isActive } = $$props;\n\t$$subscribe_isActive();\n\tlet { isActiveFraction } = $$props;\n\t$$subscribe_isActiveFraction();\n\tlet { isVisible } = $$props;\n\t$$subscribe_isVisible();\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { shapes } = $$props;\n\t$$subscribe_shapes();\n\tlet { toolbar = [] } = $$props;\n\tlet { toolShapes = {} } = $$props;\n\tlet { toolActive = undefined } = $$props;\n\tlet { toolSelectRadius = undefined } = $$props;\n\tlet { toolRetainStyles = false } = $$props;\n\tlet { toolbarLayout = 'stack' } = $$props;\n\tlet { textInputMode = undefined } = $$props;\n\tlet { shapeControls = {} } = $$props;\n\tlet { enableButtonFlipVertical = false } = $$props;\n\tlet { enablePresetSelectImage = true } = $$props;\n\tlet { enablePresetDropImage = true } = $$props;\n\tlet { enableSelectToolToAddShape = false } = $$props;\n\tlet { enableAutoSelectMoveTool = ['line', 'arrow', 'path', 'rectangle', 'ellipse', 'text'] } = $$props;\n\tlet { enableTapToAddText = false } = $$props;\n\tlet { enableMoveTool = false } = $$props;\n\tlet { enableViewTool = false } = $$props;\n\tlet { enableToolShareStyles = true } = $$props;\n\tlet { enableMultiSelect = false } = $$props;\n\tlet { gridSize = 0 } = $$props;\n\tlet { snapThreshold = 0 } = $$props;\n\tlet { enableSnapToContext = true } = $$props;\n\tlet { willRenderHeaderTools = passthrough } = $$props;\n\tlet { willRenderPresetToolbar = undefined } = $$props;\n\tlet { willRenderShapeStyleControls = undefined } = $$props;\n\tlet { willStartInteraction = undefined } = $$props;\n\tlet { shapePresets = [] } = $$props;\n\tlet { utilKey } = $$props;\n\tlet { mapScreenPointToImagePoint } = $$props;\n\tlet { mapImagePointToScreenPoint } = $$props;\n\tlet { imageRotation = 0 } = $$props;\n\tlet { imageFlipX = false } = $$props;\n\tlet { imageFlipY = false } = $$props;\n\tlet { parentRect } = $$props;\n\t$$subscribe_parentRect();\n\tlet { hooks = {} } = $$props;\n\n\t// context\n\tconst selection = getContext('selection');\n\n\tcomponent_subscribe($$self, selection, value => $$invalidate(150, $selection = value));\n\tconst isAnimated = getContext('isAnimated');\n\tcomponent_subscribe($$self, isAnimated, value => $$invalidate(142, $isAnimated = value));\n\tconst elasticityMultiplier = getContext('elasticityMultiplier');\n\tcomponent_subscribe($$self, elasticityMultiplier, value => $$invalidate(146, $elasticityMultiplier = value));\n\tconst ui = getContext('ui');\n\tcomponent_subscribe($$self, ui, value => $$invalidate(177, $ui = value));\n\tconst keysPressedStore = getContext('keysPressed');\n\tcomponent_subscribe($$self, keysPressedStore, value => $$invalidate(149, $keysPressedStore = value));\n\n\t// this makes sure tool shapes are only updated when a new tool shapes object is set\n\tlet activeToolShapes;\n\n\t// stores\n\tconst { env, history, rootRect, rootColorSecondary, enablePanInput, enablePanInputStatus, enableZoomInput, stageRect, utilRectPadded, scrollElasticity, imageOverlayMarkup, imagePreviewModifiers, imageCropRect, stageScalar, imageSelectionRect, imageTransformsInterpolated, imageSelectionPan, imageSize, allowPan, allowZoom, allowZoomControls, allowPlayPause } = stores;\n\n\tcomponent_subscribe($$self, env, value => $$invalidate(143, $env = value));\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(55, $rootRect = value));\n\tcomponent_subscribe($$self, rootColorSecondary, value => $$invalidate(57, $rootColorSecondary = value));\n\tcomponent_subscribe($$self, enablePanInputStatus, value => $$invalidate(38, $enablePanInputStatus = value));\n\tcomponent_subscribe($$self, stageRect, value => $$invalidate(147, $stageRect = value));\n\tcomponent_subscribe($$self, utilRectPadded, value => $$invalidate(39, $utilRectPadded = value));\n\tcomponent_subscribe($$self, imagePreviewModifiers, value => $$invalidate(178, $imagePreviewModifiers = value));\n\tcomponent_subscribe($$self, imageCropRect, value => $$invalidate(176, $imageCropRect = value));\n\tcomponent_subscribe($$self, stageScalar, value => $$invalidate(174, $stageScalar = value));\n\tcomponent_subscribe($$self, imageSelectionRect, value => $$invalidate(175, $imageSelectionRect = value));\n\tcomponent_subscribe($$self, imageTransformsInterpolated, value => $$invalidate(36, $imageTransformsInterpolated = value));\n\tcomponent_subscribe($$self, imageSelectionPan, value => $$invalidate(173, $imageSelectionPan = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(148, $imageSize = value));\n\n\t// remove presets tool if no shape presets defined\n\tconst filterToolbarItems = (toolbarItems, { willRenderPresetToolbar, shapePresets, enableViewTool, enableMoveTool }) => {\n\t\tlet tools = shapePresets.length === 0 && !willRenderPresetToolbar\n\t\t? toolbarItems.filter(tool => tool[0] !== 'preset')\n\t\t: toolbarItems;\n\n\t\tif (hasToolbarGroups) {\n\t\t\ttools = [\n\t\t\t\t// add move tool\n\t\t\t\t[\n\t\t\t\t\t'move',\n\t\t\t\t\tlocale => locale['shapeLabelToolMove'],\n\t\t\t\t\t{\n\t\t\t\t\t\ticon: locale => locale['shapeIconToolMove']\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t// add view tool\n\t\t\t\t[\n\t\t\t\t\t'view',\n\t\t\t\t\tlocale => locale['shapeLabelToolView'],\n\t\t\t\t\t{\n\t\t\t\t\t\ticon: locale => locale['shapeIconToolView']\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t// rest of tools\n\t\t\t\t...tools\n\t\t\t];\n\t\t}\n\n\t\t// filter move tool\n\t\ttools = enableMoveTool\n\t\t? tools\n\t\t: tools.filter(tool => tool[0] !== 'move');\n\n\t\t// filter view tool\n\t\treturn enableViewTool\n\t\t? tools\n\t\t: tools.filter(tool => tool[0] !== 'view');\n\t};\n\n\tlet toolGroupActiveIndex = 0;\n\tlet groupToolActive = {};\n\n\tconst updateActiveToolGroup = ({ index }, event) => {\n\t\t$$invalidate(27, toolGroupActiveIndex = index);\n\t\t$$invalidate(0, toolActive = groupToolActive[index]);\n\t};\n\n\tconst updateActiveTool = ({ value }, event) => {\n\t\t$$invalidate(0, toolActive = value);\n\n\t\t// if is keyboard navigating or should add shape\n\t\tif (enableSelectToolToAddShape || (/enter/i).test(event.key)) {\n\t\t\tAddToolDefaultShape(value);\n\t\t}\n\t};\n\n\tconst AddToolDefaultShape = tool => {\n\t\tconst [shape, options] = activeToolShapes[tool];\n\t\tlet isRelative = options.position === 'relative';\n\t\tlet shapeToAdd;\n\t\tlet size;\n\t\tconst x = isRelative ? '0%' : 0;\n\t\tconst y = isRelative ? '0%' : 0;\n\n\t\tif (shapeIsRect(shape) || shapeIsText(shape)) {\n\t\t\tsize = isRelative ? '20%' : $parentRect.width * 0.2;\n\t\t\tshapeToAdd = shapeDeepCopy(shape);\n\t\t\tshapeExpandTextShadow(shapeToAdd);\n\t\t\tshapeExpandOutline(shapeToAdd);\n\t\t\tshapeToAdd.x = x;\n\t\t\tshapeToAdd.y = y;\n\t\t\tshapeUpdateProps(shapeToAdd, { width: size, height: size }, $parentRect);\n\t\t} else if (shapeIsEllipse(shape)) {\n\t\t\tsize = isRelative ? '10%' : $parentRect.width * 0.1;\n\t\t\tshapeToAdd = shapeDeepCopy(shape);\n\t\t\tshapeToAdd.x = x;\n\t\t\tshapeToAdd.y = y;\n\t\t\tshapeUpdateProps(shapeToAdd, { rx: size, ry: size }, $parentRect);\n\t\t} else if (shapeIsLine(shape)) {\n\t\t\tsize = isRelative ? '10%' : $parentRect.width * 0.1;\n\t\t\tshapeToAdd = shapeDeepCopy(shape);\n\t\t\tshapeToAdd.x1 = x;\n\t\t\tshapeToAdd.y1 = y;\n\t\t\tshapeToAdd.x2 = x;\n\t\t\tshapeToAdd.y2 = y;\n\t\t}\n\n\t\tif (!shapeToAdd) return;\n\n\t\tPromise.resolve().then(() => {\n\t\t\taddShape(createShapeAtPosition(shapeToAdd, undefined, size));\n\t\t});\n\t};\n\n\tconst mapScreenEventToImagePoint = e => mapScreenPointToImagePoint(getEventPositionInEditor(e, $rootRect));\n\n\t// A reference to the markup editor, we need this so we can call exported functions\n\tlet markupEditor;\n\n\t// the current tool styles\n\tlet markupToolStyles = {};\n\n\t//\n\t// enable seeing the markup outlines outside of the crop area\n\t//\n\tconst setPreviewModifiers = () => {\n\t\tset_store_value(imagePreviewModifiers, $imagePreviewModifiers[utilKey] = { maskMarkupOpacity: 0.85 }, $imagePreviewModifiers);\n\t};\n\n\tconst clearPreviewModifiers = () => {\n\t\tdelete $imagePreviewModifiers[utilKey];\n\t};\n\n\t// toggle seleciton remove mode\n\tlet storedSelectionMode;\n\n\tconst toggleSelectionDraftRemoveMode = isRemoveMode => {\n\t\tif (!markupEditor) return;\n\t\tconst draft = markupEditor.getShapeDraft(selection);\n\t\tif (!draft) return;\n\n\t\tif (isRemoveMode) {\n\t\t\tstoredSelectionMode = draft.drawMode;\n\t\t}\n\n\t\tmarkupEditor.updateShapeDraft(\n\t\t\t{\n\t\t\t\tdrawMode: isRemoveMode ? 'subtract' : storedSelectionMode\n\t\t\t},\n\t\t\tselection\n\t\t);\n\t};\n\n\t//\n\t// Create new shape\n\t//\n\tlet interactionHandler;\n\n\tconst handleInteractionStart = e => {\n\t\t// is erasing\n\t\tif (toolActive === 'eraser') {\n\t\t\tinteractionHandler = markupEditor.eraseShape();\n\t\t} else // is creating or extending shapes\n\t\tif (toolActive && activeToolShapes[toolActive]) {\n\t\t\tconst [shape, options = {}] = activeToolShapes[toolActive];\n\n\t\t\t// clone shape\n\t\t\tconst toolShape = shapeDeepCopy(shape);\n\n\t\t\tshapeExpandTextShadow(toolShape);\n\t\t\tshapeExpandOutline(toolShape);\n\n\t\t\t// if is new selection we need to clear target list\n\t\t\tconst { drawMode } = markupShapeSelected;\n\n\t\t\tif (interactionMode === 'selection' && drawMode === 'new') {\n\t\t\t\t// clear selection\n\t\t\t\tselection.set([]);\n\t\t\t}\n\n\t\t\tlet shapeOverrides = {};\n\n\t\t\tif (interactionMode === 'selection') {\n\t\t\t\tping('selectiondown', [...$selection]);\n\n\t\t\t\t// adjust shape if option key held down\n\t\t\t\tif (holdingOptionKey) {\n\t\t\t\t\tstoredSelectionMode = toolShape.drawMode;\n\t\t\t\t\tshapeOverrides.drawMode = 'subtract';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start creating shape\n\t\t\tinteractionHandler = markupEditor.createShape(\n\t\t\t\t{\n\t\t\t\t\t...toolShape,\n\t\t\t\t\t...markupToolStylesComputed,\n\t\t\t\t\t...shapeOverrides\n\t\t\t\t},\n\t\t\t\toptions\n\t\t\t);\n\t\t} else // something else\n\t\t{\n\t\t\tinteractionHandler = undefined;\n\t\t}\n\n\t\tif (!interactionHandler) return false;\n\t\tinteractionHandler.start(e);\n\t\treturn true;\n\t};\n\n\tconst handleInteractionUpdate = e => {\n\t\tif (!interactionHandler) return false;\n\t\tinteractionHandler.update(e);\n\t\treturn true;\n\t};\n\n\tconst handleInteractionRelease = e => {\n\t\tif (!interactionHandler) return false;\n\t\tinteractionHandler.release(e);\n\t\treturn true;\n\t};\n\n\tconst handleInteractionCancel = e => {\n\t\tif (!interactionHandler) return false;\n\t\tinteractionHandler.cancel(e);\n\t\tinteractionHandler = undefined;\n\t\treturn true;\n\t};\n\n\tconst handleInteractionEnd = e => {\n\t\tif (!interactionHandler) {\n\t\t\treturn false;\n\t\t}\n\n\t\tinteractionHandler.end(e);\n\t\tinteractionHandler = undefined;\n\n\t\tif (interactionMode === 'selection') {\n\t\t\t// clear selection if not is brush or stepped input mode\n\t\t\tif (e.detail.isTap) {\n\t\t\t\tconst [toolShape, toolShapeOptions] = activeToolShapes[toolActive];\n\n\t\t\t\tif (!toolShape.bitmap && toolShapeOptions.inputMode !== 'step') {\n\t\t\t\t\tselection.set([]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// selection up\n\t\t\tping('selectionup', [...$selection]);\n\t\t}\n\n\t\t// when a shape is built with multiple clicks a draft might still be active\n\t\tconst draft = markupEditor.getMarkupItemDraft();\n\n\t\t// always fall back to move when done with current tool\n\t\tconst canSwitchToMoveTool = enableMoveTool && (enableAutoSelectMoveTool === true || Array.isArray(enableAutoSelectMoveTool) && enableAutoSelectMoveTool.includes(toolActive));\n\n\t\t// should switch back to move tool if draft is finished OR if draft is there and is text editing\n\t\tif ((!draft || draft.isEditing) && canSwitchToMoveTool) {\n\t\t\t$$invalidate(0, toolActive = 'move');\n\t\t}\n\n\t\treturn true;\n\t};\n\n\tconst confirmSelectionDraft = draft => {\n\t\tif (draft.pointerPoint) {\n\t\t\tdraft.points.push(draft.pointerPoint);\n\t\t}\n\n\t\tmarkupEditor.confirmShapeDraft(selection);\n\n\t\t// selection up\n\t\tping('selectionup', [...$selection]);\n\n\t\tselection.set([]);\n\t};\n\n\tconst confirmMarkupDraft = draft => {\n\t\tconst isPolygon = shapeIsPath(draft) && hasProp(draft, 'pathClose');\n\n\t\tif (!isPolygon) {\n\t\t\treturn;\n\t\t}\n\n\t\t//  show stroke color\n\t\tconst strokeColor = [...draft.strokeColor];\n\n\t\tstrokeColor[3] = 1;\n\n\t\t// update the draft shape\n\t\tmarkupEditor.updateMarkupShape(\n\t\t\tdraft, // wait with sync till confirm\n\t\t\t{\n\t\t\t\t// don't close this path\n\t\t\t\tpathClose: false,\n\t\t\t\t// set opaque stroke color\n\t\t\t\tstrokeColor\n\t\t\t},\n\t\t\tfalse // wait with sync till confirm\n\t\t);\n\n\t\tmarkupEditor.removeMarkupShapeProps(draft, ['backgroundColor'], false); // wait with sync till confirm\n\t\tmarkupEditor.confirmMarkupItemDraft();\n\t\tmarkupEditor.selectShape(draft);\n\t\tping('addshape', draft);\n\t\thistory.write();\n\t};\n\n\tconst handleKey = e => {\n\t\tconst { key } = e;\n\t\tconst markupDraft = markupEditor.getMarkupItemDraft();\n\t\tconst selectionDraft = markupEditor.getSelectionItemDraft();\n\t\tconst hasDraft = markupDraft || selectionDraft;\n\n\t\tif ((/escape/i).test(key) && hasDraft) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\tif (markupDraft) {\n\t\t\t\tmarkupEditor.discardMarkupItemDraft();\n\t\t\t} else {\n\t\t\t\tmarkupEditor.discardSelectionItemDraft();\n\t\t\t}\n\n\t\t\tinteractionHandler = undefined;\n\t\t}\n\n\t\tif ((/enter/i).test(key) && hasDraft) {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\tif (markupDraft) {\n\t\t\t\tconfirmMarkupDraft(markupDraft);\n\t\t\t} else {\n\t\t\t\tconfirmSelectionDraft(selectionDraft);\n\t\t\t}\n\n\t\t\tinteractionHandler = undefined;\n\t\t}\n\t};\n\n\tconst blurOnToolSwitch = () => {\n\t\tif (!markupEditor || toolActive === 'move') return;\n\t\tmarkupEditor.blurShapes();\n\t};\n\n\tconst getStoredStyles = () => {\n\t\treturn $ui[utilKey] ? $ui[utilKey][toolActive] : {};\n\t};\n\n\tconst createMarkupToolShape = activeToolShape => {\n\t\tconst toolShape = shapeDeepCopy(activeToolShape);\n\t\tObject.assign(toolShape, getStoredStyles());\n\t\tshapeFormat(toolShape);\n\t\treturn toolShape;\n\t};\n\n\t// if toolShapes are updated we reset the current tool styles as chose by the user, this allows us to set styles programatically\n\tconst didUpdateToolShapes = () => {\n\t\t$$invalidate(115, markupToolStyles = {});\n\t};\n\n\tconst updateInterfaceState = (util, tool, computedStyles) => {\n\t\tconst utilObj = $ui[util];\n\t\tconst toolObj = utilObj ? utilObj[tool] : {};\n\n\t\tui.set({\n\t\t\t...$ui,\n\t\t\t[util]: {\n\t\t\t\t...utilObj,\n\t\t\t\t[tool]: { ...toolObj, ...computedStyles }\n\t\t\t}\n\t\t});\n\t};\n\n\tconst resetInterfaceState = util => {\n\t\tui.set({ [util]: {} });\n\t};\n\n\tfunction getMultiSelectionSharedStyleProps(shapes) {\n\t\tconst res = {};\n\n\t\tshapes.forEach(shape => {\n\t\t\tObject.entries(shape).filter(([key]) => !key.startsWith('_')).forEach(([key, value]) => {\n\t\t\t\tif (hasProp(res, key)) {\n\t\t\t\t\tif (key === 'disableStyle' && isArray(value)) res[key].push(...value);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres[key] = value;\n\t\t\t});\n\t\t});\n\n\t\treturn res;\n\t}\n\n\tlet updateWriteHistoryTimeoutId;\n\n\tfunction handleUpdateSelectedMarkupShape(props) {\n\t\t// remember style for when creating or styling other element\n\t\tObject.keys(props).forEach(key => {\n\t\t\tconst { retain = true, share = true } = markupToolShape.settings && markupToolShape.settings[key] || {};\n\n\t\t\t// don't save this style\n\t\t\tif (!retain) return;\n\n\t\t\t// should we share this style with other tools? by setting `share` to false we can exclude specific styles\n\t\t\tif (enableToolShareStyles && share) {\n\t\t\t\t$$invalidate(115, markupToolStyles[key] = props[key], markupToolStyles);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// create tool styles island\n\t\t\tif (!markupToolStyles[toolActive]) $$invalidate(115, markupToolStyles[toolActive] = {}, markupToolStyles);\n\n\t\t\t// save style\n\t\t\t$$invalidate(115, markupToolStyles[toolActive][key] = props[key], markupToolStyles);\n\t\t});\n\n\t\t// fire event\n\t\tping('selectstyle', props);\n\n\t\t// it's possible we're only updating tool styles\n\t\tif (!markupSelected) return;\n\n\t\t// if is multiselection we only update props that are defined on the shape\n\t\tif (isMultiSelection) {\n\t\t\tmultiSelection.forEach(shape => {\n\t\t\t\tmarkupEditor.updateMarkupShape(shape, filterPropsByShape(props, shape));\n\t\t\t});\n\t\t} else // else we update all props\n\t\t{\n\t\t\tmarkupEditor.updateMarkupShape(markupSelected, props);\n\t\t}\n\n\t\t// update markup style with delay so we don't write every state change to history (mainly relevant for color changes when dragging color)\n\t\tclearTimeout(updateWriteHistoryTimeoutId);\n\n\t\tupdateWriteHistoryTimeoutId = setTimeout(\n\t\t\t() => {\n\t\t\t\thandleMarkupUpdate();\n\t\t\t},\n\t\t\t200\n\t\t);\n\t}\n\n\t// this removes props that aren't available on the passed shape\n\tconst filterPropsByShape = (props, shape) => {\n\t\tconst filteredProps = {};\n\n\t\tObject.entries(props).forEach(([key, value]) => {\n\t\t\tif (!hasProp(shape, key)) return;\n\t\t\tfilteredProps[key] = value;\n\t\t});\n\n\t\treturn filteredProps;\n\t};\n\n\t// eraser\n\tconst getValueInContext = (value, context) => {\n\t\tif (isNumber(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\tif (value.endsWith('%')) {\n\t\t\tconst f = parseFloat(value) / 100;\n\t\t\treturn f * context.width;\n\t\t}\n\n\t\treturn undefined;\n\t};\n\n\tlet shapeUnderPointer = undefined;\n\tlet canvasHoverPosition = undefined;\n\tlet imageHoverPosition = undefined;\n\n\tconst updateCustomCursor = cursorShapes => {\n\t\timageOverlayMarkup.update(shapes => {\n\t\t\treturn [\n\t\t\t\t// remove previous cursor shapes\n\t\t\t\t...shapes.filter(shape => shape.id !== `cursor-${utilKey}`),\n\t\t\t\t// add new cursor shapes\n\t\t\t\t...cursorShapes\n\t\t\t];\n\t\t});\n\t};\n\n\tconst removeCustomCursor = () => {\n\t\timageOverlayMarkup.update(shapes => {\n\t\t\treturn shapes.filter(shape => shape.id !== `cursor-${utilKey}`);\n\t\t});\n\t};\n\n\tconst handleHoverCanvas = (_, canvasPosition, imagePosition) => {\n\t\t$$invalidate(117, canvasHoverPosition = canvasPosition);\n\t\t$$invalidate(118, imageHoverPosition = imagePosition);\n\t};\n\n\tconst handleLeaveCanvas = () => {\n\t\t$$invalidate(118, imageHoverPosition = undefined);\n\t\t$$invalidate(117, canvasHoverPosition = undefined);\n\t};\n\n\tconst getCustomCursorDescription = ({ cursorStyle, cursorSize }, computedToolStyles, context) => {\n\t\tlet size;\n\t\tconst propValue = computedToolStyles[cursorSize];\n\n\t\t// cursor size itself is percentage\n\t\tif (propValue === undefined) {\n\t\t\tsize = getValueInContext(cursorSize, context);\n\t\t} else // cursor size prop has pixel value\n\t\tif (isNumber(propValue)) {\n\t\t\tsize = propValue;\n\t\t} else // cursor size prop has percentage, compute value based on key\n\t\tif (isString(propValue)) {\n\t\t\tsize = shapeComputeProp(cursorSize, computedToolStyles[cursorSize], context);\n\n\t\t\tif (cursorSize === 'strokeWidth') {\n\t\t\t\tsize *= 0.5;\n\t\t\t}\n\t\t}\n\n\t\t// no size\n\t\tif (size <= 0 || size === undefined) return;\n\n\t\treturn { size, style: cursorStyle };\n\t};\n\n\tconst getCursorStyle = (customCursor, shapeUnderPointer, shapeSelected, panInputEnabled, isPanning, currentTool) => {\n\t\t// hide cursor if eraser radius is set\n\t\tif (panInputEnabled) return isPanning ? 'grabbing' : 'grab';\n\n\t\t// hide cursor\n\t\tif (customCursor && !shapeUnderPointer) return 'none';\n\n\t\t// no shape, return crosshair\n\t\tif (!shapeUnderPointer) return currentTool === 'move' ? 'default' : 'crosshair';\n\n\t\t// treat both as the same shape\n\t\tlet shape = shapeUnderPointer || shapeSelected;\n\n\t\t// can select (else won't hover)\n\t\tif (!shapeIsSelected(shape)) return 'default';\n\n\t\t// show text input cursor\n\t\tif (shapeIsEditing(shape)) {\n\t\t\tif (textInputMode === 'modal') return 'default';\n\t\t\treturn 'text';\n\t\t}\n\n\t\t// show move cursor\n\t\tif (shapeCanMove(shape) && (!isMultiSelection || multiSelection.every(shapeCanMove))) return 'move';\n\n\t\t// can't move\n\t\treturn 'default';\n\t};\n\n\t//#endregion\n\tconst handleTapCanvas = details => {\n\t\tping('markuptap', details);\n\t};\n\n\tconst handleHoverShape = shape => $$invalidate(116, shapeUnderPointer = shape);\n\n\tconst createShapeAtPosition = (shape, position, size) => {\n\t\t// position defaults to crop center\n\t\tlet positionIsCenter = false;\n\n\t\tif (!position) {\n\t\t\t// is centering to stage\n\t\t\tpositionIsCenter = true;\n\n\t\t\t// calculate image or rect position\n\t\t\tposition = shouldStickToImage\n\t\t\t? mapScreenPointToImagePoint(rectCenter($stageRect))\n\t\t\t: rectCenter($imageCropRect);\n\t\t}\n\n\t\t// adjust offset if parent rect is image crop rect\n\t\tposition.x -= $parentRect.x || 0;\n\n\t\tposition.y -= $parentRect.y || 0;\n\n\t\t// de-flip shape\n\t\tif (imageFlipX || imageFlipY) {\n\t\t\tshape.flipX = imageFlipX;\n\t\t\tshape.flipY = imageFlipY;\n\t\t}\n\n\t\t// reposition if there's already shapes at position and shape isn't full screen\n\t\tconst shapesAlreadyAtPosition = markupEditor.getShapesNearPosition($shapes, position);\n\n\t\tif (positionIsCenter && shapesAlreadyAtPosition.length) {\n\t\t\tconst dist = Math.min($imageCropRect.width, $imageCropRect.height) * 0.1;\n\t\t\tposition.x += Math.round(-dist + Math.random() * dist * 2);\n\t\t\tposition.y += Math.round(-dist + Math.random() * dist * 2);\n\t\t}\n\n\t\t// de-rotate shape\n\t\tif (imageRotation !== 0) {\n\t\t\tif (imageFlipX && imageFlipY) shape.rotation = -imageRotation; else if (imageFlipX) shape.rotation = imageRotation; else if (imageFlipY) shape.rotation = imageRotation; else shape.rotation = -imageRotation;\n\t\t}\n\n\t\tif (hasProp(shape, 'width') && hasProp(shape, 'height')) {\n\t\t\tconst { width, height } = shapeGetPropsPixelValues(shape, ['width', 'height'], $parentRect);\n\n\t\t\tshapeUpdateProps(\n\t\t\t\tshape,\n\t\t\t\t{\n\t\t\t\t\tx: position.x - width * 0.5,\n\t\t\t\t\ty: position.y - height * 0.5\n\t\t\t\t},\n\t\t\t\t$parentRect\n\t\t\t);\n\t\t} else if (shapeIsEllipse(shape)) {\n\t\t\tshapeUpdateProps(shape, { x: position.x, y: position.y }, $parentRect);\n\t\t} else if (shapeIsLine(shape)) {\n\t\t\tconst { x1, y1, x2, y2 } = shapeGetPropsPixelValues(shape, ['x1', 'y1', 'x2', 'y2'], $parentRect);\n\t\t\tconst dist = vectorDistance(vectorCreate(x1, y1), vectorCreate(x2, y2));\n\n\t\t\tconst l = isString(size)\n\t\t\t? toPixelValue(size, $parentRect.width)\n\t\t\t: dist;\n\n\t\t\tshapeUpdateProps(\n\t\t\t\tshape,\n\t\t\t\t{\n\t\t\t\t\tx1: position.x - l,\n\t\t\t\t\ty1: position.y + l,\n\t\t\t\t\tx2: position.x + l,\n\t\t\t\t\ty2: position.y - l\n\t\t\t\t},\n\t\t\t\t$parentRect\n\t\t\t);\n\t\t} else if (shapeIsPath(shape)) {\n\t\t\tconst { points } = shapeGetPropsPixelValues(shape, ['points'], $parentRect);\n\t\t\tconst center = vectorCenter(points);\n\n\t\t\tshapeUpdateProps(\n\t\t\t\tshape,\n\t\t\t\t{\n\t\t\t\t\tpoints: points.map(point => ({\n\t\t\t\t\t\tx: point.x + position.x - center.x,\n\t\t\t\t\t\ty: point.y + position.y - center.y\n\t\t\t\t\t}))\n\t\t\t\t},\n\t\t\t\t$parentRect\n\t\t\t);\n\t\t}\n\n\t\treturn shape;\n\t};\n\n\tconst addPreset = (preset, position) => {\n\t\tconst shape = createShapeAtPosition(shapeCreateFromPreset(preset, $imageCropRect), position);\n\n\t\t// force position\n\t\tif (preset.shape) {\n\t\t\tif (hasProp(preset.shape, 'x')) shape.x = preset.shape.x;\n\t\t\tif (hasProp(preset.shape, 'y')) shape.y = preset.shape.y;\n\t\t}\n\n\t\treturn addShape(shape);\n\t};\n\n\tconst addShape = shape => {\n\t\tconst { beforeAddShape = () => true } = hooks;\n\t\tif (!beforeAddShape(shape)) return;\n\t\tmarkupEditor.addShape(shape);\n\t\tmarkupEditor.selectShape(shape);\n\t\tping('addshape', shape);\n\t\thistory.write();\n\t\treturn shape;\n\t};\n\n\tlet dragCancelled = false;\n\n\tconst handleGrabPreset = () => {\n\t\tdragCancelled = false;\n\t};\n\n\tconst handleDragPreset = (preset, e) => {\n\t\tif (dragCancelled) return;\n\t\tconst { beforeAddShape = () => true } = hooks;\n\t\tconst position = mapScreenEventToImagePoint(e);\n\n\t\t// create or update if is inside image\n\t\tconst draft = markupEditor.getMarkupItemDraft();\n\n\t\tconst inCropRect = rectContainsPoint($imageCropRect, {\n\t\t\t// adjust offset if parent rect is image crop rect\n\t\t\tx: position.x + ($parentRect.x || 0),\n\t\t\ty: position.y + ($parentRect.y || 0)\n\t\t});\n\n\t\t// remove draft if not dragging inside image\n\t\tif (draft && !inCropRect) markupEditor.discardMarkupItemDraft();\n\n\t\t// stop here if we're not in the crop rect\n\t\tif (!inCropRect) return;\n\n\t\t// create draft shape\n\t\tif (!draft) {\n\t\t\tconst presetShape = shapeCreateFromPreset(preset, $imageCropRect);\n\t\t\tconst shape = createShapeAtPosition(presetShape, position);\n\n\t\t\tif (!beforeAddShape(shape)) {\n\t\t\t\tdragCancelled = true;\n\t\t\t\te.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tshapeMakeDraft(shape);\n\t\t\tmarkupEditor.addShape(shape);\n\t\t\treturn;\n\t\t}\n\n\t\t// center shape on pointer if it has dimensions\n\t\tif (shapeIsRect(draft)) {\n\t\t\tposition.x -= draft.width * 0.5;\n\t\t\tposition.y -= draft.height * 0.5;\n\t\t}\n\n\t\t// force position\n\t\tif (preset.shape) {\n\t\t\tif (hasProp(preset.shape, 'x')) position.x = preset.shape.x;\n\t\t\tif (hasProp(preset.shape, 'y')) position.y = preset.shape.y;\n\t\t}\n\n\t\t// update the draft shape\n\t\tmarkupEditor.updateMarkupShape(draft, position);\n\t};\n\n\tconst handleDropPreset = (_, e) => {\n\t\tif (dragCancelled) return;\n\t\tconst position = mapScreenEventToImagePoint(e);\n\n\t\tif (!rectContainsPoint($imageCropRect, {\n\t\t\tx: position.x + ($parentRect.x || 0),\n\t\t\ty: position.y + ($parentRect.y || 0)\n\t\t})) {\n\t\t\tmarkupEditor.discardMarkupItemDraft();\n\t\t\treturn;\n\t\t}\n\n\t\t// confirm shape\n\t\tconst shape = markupEditor.confirmMarkupItemDraft();\n\n\t\tmarkupEditor.selectShape(shape);\n\n\t\t// shape added\n\t\tping('addshape', shape);\n\n\t\t// update history\n\t\thistory.write();\n\t};\n\n\tconst handleAddPreset = preset => addPreset(preset);\n\tconst handleAddFiles = (files, position) => files.filter(file => isImage(file)).forEach(file => addPreset(file, position));\n\tconst handleDropFiles = e => handleAddFiles(e.detail.resources, mapScreenEventToImagePoint(e.detail.event));\n\n\tconst handleWillStartInteraction = position => {\n\t\tif (!willStartInteraction) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// calculate current image selection rect\n\t\tconst selectionRect = rectClone($imageSelectionRect);\n\n\t\trectScale(selectionRect, 1 / $stageScalar);\n\t\trectTranslate(selectionRect, $imageSelectionPan);\n\t\trectScale(selectionRect, $imageTransformsInterpolated.scale);\n\n\t\t// should return true if interaction is allowed\n\t\treturn willStartInteraction(position, {\n\t\t\t...selectionRect,\n\t\t\tx: selectionRect.x + $stageRect.x,\n\t\t\ty: selectionRect.y + $stageRect.y\n\t\t});\n\t};\n\n\t//\n\t// History\n\t//\n\tconst handleMarkupUpdate = () => {\n\t\thistory.write();\n\t};\n\n\t// used to fire ping events from\n\tlet pingHub;\n\n\t//\n\t// preset toolbar\n\t//\n\tconst redrawTrigger = getContext('redrawTrigger');\n\n\tcomponent_subscribe($$self, redrawTrigger, value => $$invalidate(144, $redrawTrigger = value));\n\n\t//\n\t// confirm draft text when leaving view\n\t//\n\tconst toggleShapePrerendering = active => {\n\t\tif (!$shapes) return;\n\n\t\tshapes.update(shapes => {\n\t\t\treturn shapes.map(shape => {\n\t\t\t\tshape._prerender = active ? shapeIsEditing(shape) : false;\n\t\t\t\treturn shape;\n\t\t\t});\n\t\t});\n\t};\n\n\t//\n\t// Header style\n\t//\n\tconst headerToolbarStyles = [];\n\n\t//\n\t// Footer style\n\t//\n\tconst footerOffset = spring($isAnimated ? 20 : 0);\n\n\tcomponent_subscribe($$self, footerOffset, value => $$invalidate(141, $footerOffset = value));\n\n\tfunction measure_handler_1(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\tconst func = option => option[0] === toolActive;\n\n\tconst func_1 = (controls, env, redraw) => {\n\t\tconst filteredControls = controls.filter(([,key]) => !headerToolbarStyles.includes(key));\n\n\t\treturn willRenderShapeStyleControls\n\t\t? willRenderShapeStyleControls(filteredControls, env, redraw)\n\t\t: filteredControls;\n\t};\n\n\tconst func_2 = option => option[0] === toolGroupActiveIndex;\n\n\tconst func_3 = shape => {\n\t\tPromise.resolve().then(() => {\n\t\t\tping('addshape', shape);\n\t\t\thandleMarkupUpdate();\n\t\t});\n\t};\n\n\tconst func_4 = shape => {\n\t\tping('selectshape', shape);\n\t};\n\n\tconst func_5 = shape => {\n\t\tPromise.resolve().then(() => {\n\t\t\tping('blurshape', shape);\n\t\t});\n\t};\n\n\tconst func_6 = shape => {\n\t\tping('tapshape', shape);\n\t};\n\n\tconst func_7 = shape => {\n\t\tping('updateshape', shape);\n\t\thandleMarkupUpdate();\n\t};\n\n\tconst func_8 = shape => {\n\t\tping('removeshape', shape);\n\t\thandleMarkupUpdate();\n\t};\n\n\tconst func_9 = () => {\n\t\thandleMarkupUpdate();\n\t};\n\n\tfunction shapelayouteditor_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tmarkupEditor = $$value;\n\t\t\t$$invalidate(28, markupEditor);\n\t\t});\n\t}\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tpingHub = $$value;\n\t\t\t$$invalidate(29, pingHub);\n\t\t});\n\t}\n\n\tconst func_10 = controls => {\n\t\treturn controls.filter(([,key]) => headerToolbarStyles.includes(key));\n\t};\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$subscribe_isActive($$invalidate(1, isActive = $$props.isActive));\n\t\tif ('isActiveFraction' in $$props) $$subscribe_isActiveFraction($$invalidate(2, isActiveFraction = $$props.isActiveFraction));\n\t\tif ('isVisible' in $$props) $$subscribe_isVisible($$invalidate(3, isVisible = $$props.isVisible));\n\t\tif ('stores' in $$props) $$invalidate(100, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(4, locale = $$props.locale);\n\t\tif ('shapes' in $$props) $$subscribe_shapes($$invalidate(5, shapes = $$props.shapes));\n\t\tif ('toolbar' in $$props) $$invalidate(101, toolbar = $$props.toolbar);\n\t\tif ('toolShapes' in $$props) $$invalidate(102, toolShapes = $$props.toolShapes);\n\t\tif ('toolActive' in $$props) $$invalidate(0, toolActive = $$props.toolActive);\n\t\tif ('toolSelectRadius' in $$props) $$invalidate(6, toolSelectRadius = $$props.toolSelectRadius);\n\t\tif ('toolRetainStyles' in $$props) $$invalidate(103, toolRetainStyles = $$props.toolRetainStyles);\n\t\tif ('toolbarLayout' in $$props) $$invalidate(7, toolbarLayout = $$props.toolbarLayout);\n\t\tif ('textInputMode' in $$props) $$invalidate(8, textInputMode = $$props.textInputMode);\n\t\tif ('shapeControls' in $$props) $$invalidate(9, shapeControls = $$props.shapeControls);\n\t\tif ('enableButtonFlipVertical' in $$props) $$invalidate(10, enableButtonFlipVertical = $$props.enableButtonFlipVertical);\n\t\tif ('enablePresetSelectImage' in $$props) $$invalidate(11, enablePresetSelectImage = $$props.enablePresetSelectImage);\n\t\tif ('enablePresetDropImage' in $$props) $$invalidate(12, enablePresetDropImage = $$props.enablePresetDropImage);\n\t\tif ('enableSelectToolToAddShape' in $$props) $$invalidate(104, enableSelectToolToAddShape = $$props.enableSelectToolToAddShape);\n\t\tif ('enableAutoSelectMoveTool' in $$props) $$invalidate(105, enableAutoSelectMoveTool = $$props.enableAutoSelectMoveTool);\n\t\tif ('enableTapToAddText' in $$props) $$invalidate(13, enableTapToAddText = $$props.enableTapToAddText);\n\t\tif ('enableMoveTool' in $$props) $$invalidate(106, enableMoveTool = $$props.enableMoveTool);\n\t\tif ('enableViewTool' in $$props) $$invalidate(107, enableViewTool = $$props.enableViewTool);\n\t\tif ('enableToolShareStyles' in $$props) $$invalidate(108, enableToolShareStyles = $$props.enableToolShareStyles);\n\t\tif ('enableMultiSelect' in $$props) $$invalidate(14, enableMultiSelect = $$props.enableMultiSelect);\n\t\tif ('gridSize' in $$props) $$invalidate(15, gridSize = $$props.gridSize);\n\t\tif ('snapThreshold' in $$props) $$invalidate(16, snapThreshold = $$props.snapThreshold);\n\t\tif ('enableSnapToContext' in $$props) $$invalidate(17, enableSnapToContext = $$props.enableSnapToContext);\n\t\tif ('willRenderHeaderTools' in $$props) $$invalidate(109, willRenderHeaderTools = $$props.willRenderHeaderTools);\n\t\tif ('willRenderPresetToolbar' in $$props) $$invalidate(110, willRenderPresetToolbar = $$props.willRenderPresetToolbar);\n\t\tif ('willRenderShapeStyleControls' in $$props) $$invalidate(18, willRenderShapeStyleControls = $$props.willRenderShapeStyleControls);\n\t\tif ('willStartInteraction' in $$props) $$invalidate(111, willStartInteraction = $$props.willStartInteraction);\n\t\tif ('shapePresets' in $$props) $$invalidate(19, shapePresets = $$props.shapePresets);\n\t\tif ('utilKey' in $$props) $$invalidate(20, utilKey = $$props.utilKey);\n\t\tif ('mapScreenPointToImagePoint' in $$props) $$invalidate(21, mapScreenPointToImagePoint = $$props.mapScreenPointToImagePoint);\n\t\tif ('mapImagePointToScreenPoint' in $$props) $$invalidate(22, mapImagePointToScreenPoint = $$props.mapImagePointToScreenPoint);\n\t\tif ('imageRotation' in $$props) $$invalidate(23, imageRotation = $$props.imageRotation);\n\t\tif ('imageFlipX' in $$props) $$invalidate(24, imageFlipX = $$props.imageFlipX);\n\t\tif ('imageFlipY' in $$props) $$invalidate(25, imageFlipY = $$props.imageFlipY);\n\t\tif ('parentRect' in $$props) $$subscribe_parentRect($$invalidate(26, parentRect = $$props.parentRect));\n\t\tif ('hooks' in $$props) $$invalidate(112, hooks = $$props.hooks);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[4] & /*$keysPressedStore*/ 33554432) {\n\t\t\t// is holding option key so we can invert selection controls\n\t\t\t$$invalidate(124, holdingOptionKey = $keysPressedStore.includes(18));\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*activeToolShapes, toolShapes*/ 1049088) {\n\t\t\tif (!activeToolShapes || toolShapes !== activeToolShapes) {\n\t\t\t\t$$invalidate(113, activeToolShapes = toolShapes);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16) {\n\t\t\t// enable pan and zoom for shape manipulation plugins\n\t\t\tallowPan.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16) {\n\t\t\tallowZoom.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16) {\n\t\t\tallowZoomControls.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*toolbar*/ 256) {\n\t\t\t$$invalidate(33, hasToolbarGroups = Array.isArray(toolbar) && toolbar.length > 1 && Array.isArray(toolbar[0][1]));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*hasToolbarGroups*/ 4 | $$self.$$.dirty[3] & /*toolbar*/ 256) {\n\t\t\t$$invalidate(54, toolbarGroups = hasToolbarGroups\n\t\t\t? toolbar.map((item, index) => [index, item[0]])\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolGroupActiveIndex*/ 134217728 | $$self.$$.dirty[1] & /*hasToolbarGroups*/ 4 | $$self.$$.dirty[3] & /*toolbar*/ 256) {\n\t\t\t$$invalidate(140, activeToolbar = hasToolbarGroups\n\t\t\t? toolbar[toolGroupActiveIndex][1]\n\t\t\t: toolbar);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shapePresets*/ 524288 | $$self.$$.dirty[3] & /*willRenderPresetToolbar, enableMoveTool, enableViewTool*/ 155648 | $$self.$$.dirty[4] & /*activeToolbar*/ 65536) {\n\t\t\t$$invalidate(32, toolsFiltered = filterToolbarItems(activeToolbar, {\n\t\t\t\twillRenderPresetToolbar,\n\t\t\t\tshapePresets,\n\t\t\t\tenableMoveTool,\n\t\t\t\tenableViewTool\n\t\t\t}));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*toolsFiltered*/ 2) {\n\t\t\t$$invalidate(138, hasTools = !!toolsFiltered.length);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[1] & /*toolsFiltered*/ 2 | $$self.$$.dirty[4] & /*hasTools*/ 16384) {\n\t\t\t// set to first tool in tool bar list if not defined\n\t\t\tif (hasTools && toolActive === undefined) {\n\t\t\t\t$$invalidate(0, toolActive = toolsFiltered[0][0]);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolGroupActiveIndex, toolActive*/ 134217729 | $$self.$$.dirty[1] & /*hasToolbarGroups*/ 4 | $$self.$$.dirty[3] & /*groupToolActive*/ 2097152 | $$self.$$.dirty[4] & /*activeToolbar*/ 65536) {\n\t\t\tif (hasToolbarGroups) {\n\t\t\t\t$$invalidate(114, groupToolActive = {\n\t\t\t\t\t...groupToolActive,\n\t\t\t\t\t[toolGroupActiveIndex]: activeToolbar.map(([key]) => key).includes(toolActive)\n\t\t\t\t\t? // use active tool key\n\t\t\t\t\t\ttoolActive\n\t\t\t\t\t: // the currently selected tool in this group OR the first tool key we find\n\t\t\t\t\t\tgroupToolActive[toolGroupActiveIndex] || activeToolbar[0][0]\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shapeControls*/ 512) {\n\t\t\t$$invalidate(137, hasShapeControls = !!Object.keys(shapeControls).length);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*toolsFiltered*/ 2) {\n\t\t\t$$invalidate(34, hasMultipleTools = toolsFiltered.length > 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*hasMultipleTools, hasToolbarGroups*/ 12) {\n\t\t\t$$invalidate(53, showToolbar = hasMultipleTools || hasToolbarGroups);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1) {\n\t\t\t$$invalidate(139, hasActiveTool = toolActive !== undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*hasActiveTool, hasTools, hasShapeControls*/ 57344) {\n\t\t\t$$invalidate(52, shouldRenderControls = (!hasActiveTool || hasTools) && hasShapeControls);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*pingHub*/ 536870912) {\n\t\t\t$$invalidate(31, ping = pingHub && createPingDispatcher(pingHub));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[1] & /*$isActive, ping*/ 17) {\n\t\t\t$isActive && ping && ping('selectcontrol', toolActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16) {\n\t\t\tif ($isActive) {\n\t\t\t\tsetPreviewModifiers();\n\t\t\t} else {\n\t\t\t\tclearPreviewModifiers();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[3] & /*activeToolShapes*/ 1048576) {\n\t\t\t//\n\t\t\t// Select correct shape collection\n\t\t\t//\n\t\t\t$$invalidate(136, toolOptions = toolActive && activeToolShapes[toolActive]\n\t\t\t? activeToolShapes[toolActive][1]\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*toolOptions*/ 4096) {\n\t\t\t$$invalidate(125, interactionMode = toolOptions && toolOptions.isSelection\n\t\t\t? 'selection'\n\t\t\t: 'shapes');\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*interactionMode, holdingOptionKey*/ 3) {\n\t\t\ttoggleSelectionDraftRemoveMode(interactionMode === 'selection' && holdingOptionKey);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive, markupEditor*/ 268435457) {\n\t\t\tif (toolActive && markupEditor) {\n\t\t\t\tconst draft = markupEditor.getMarkupItemDraft();\n\n\t\t\t\tif (draft) {\n\t\t\t\t\tconfirmMarkupDraft(draft);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1) {\n\t\t\tif (toolActive) blurOnToolSwitch();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*$isVisible*/ 134217728) {\n\t\t\t$$invalidate(51, shouldRenderShapeEditor = $isVisible && $isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$utilRectPadded*/ 256 | $$self.$$.dirty[4] & /*$stageRect*/ 8388608) {\n\t\t\t$$invalidate(50, markupOffset = $utilRectPadded && vectorCreate($stageRect.x - $utilRectPadded.x, $stageRect.y - $utilRectPadded.y));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*shapeControls*/ 512) {\n\t\t\t$$invalidate(135, markupShapeKeys = Object.keys(shapeControls));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*enableMultiSelect*/ 16384 | $$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*$shapes*/ 2097152) {\n\t\t\t$$invalidate(122, multiSelection = enableMultiSelect\n\t\t\t? $isActive && $shapes.filter(shapeIsSelected)\n\t\t\t: []);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*multiSelection*/ 536870912) {\n\t\t\t$$invalidate(123, isMultiSelection = multiSelection.length > 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*$shapes*/ 2097152) {\n\t\t\t$$invalidate(119, markupSelected = $isActive && $shapes.filter(shapeIsSelected)[0]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*$shapes*/ 2097152) {\n\t\t\t$$invalidate(130, markupEditing = $isActive && $shapes.find(shape => shapeIsEditing(shape)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*$shapes*/ 2097152) {\n\t\t\t$$invalidate(133, markupDraft = $isActive && $shapes.find(shape => shapeIsDraft(shape)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[3] & /*activeToolShapes*/ 1048576) {\n\t\t\t$$invalidate(127, markupToolShape = $isActive && activeToolShapes[toolActive]\n\t\t\t? createMarkupToolShape(activeToolShapes[toolActive][0])\n\t\t\t: {});\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*activeToolShapes*/ 1048576) {\n\t\t\tif (activeToolShapes) didUpdateToolShapes();\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[3] & /*markupToolStyles, enableToolShareStyles*/ 4227072 | $$self.$$.dirty[4] & /*markupToolShape, markupShapeKeys*/ 2056) {\n\t\t\t// compute markup styles\n\t\t\t$$invalidate(126, markupToolStylesComputed = markupToolShape && Object.keys(markupToolShape).reduce(\n\t\t\t\t(prev, key) => {\n\t\t\t\t\t// is styling prevented\n\t\t\t\t\tconst isDisableStyleProp = key === 'disableStyle';\n\n\t\t\t\t\tconst isStyleSettingsProp = key === 'settings';\n\n\t\t\t\t\t// can this prop be styled\n\t\t\t\t\tconst isStylableProp = !!markupShapeKeys.find(shapeKey => shapeKey.split('_').includes(key));\n\n\t\t\t\t\t// skip props that can't be styled, but keep all `disable` props\n\t\t\t\t\tif (!isDisableStyleProp && !isStyleSettingsProp && !isStylableProp) return prev;\n\n\t\t\t\t\t// skip props that are set to undefined, this means they won't auto-inherit current styles (line won't inherit line ends)\n\t\t\t\t\tif (markupToolShape[key] === undefined) return prev;\n\n\t\t\t\t\t// if all styling is disabled we use original shape value\n\t\t\t\t\tif (markupToolShape.disableStyle === true) return prev;\n\n\t\t\t\t\t// if this style key is in disabled list we always use original value\n\t\t\t\t\tif (markupToolShape.disableStyle && markupToolShape.disableStyle.includes(key)) return prev;\n\n\t\t\t\t\t// if is trying to assign undefined strokeWidth to path\n\t\t\t\t\tif (key === 'strokeWidth' && Object.keys(markupToolStyles).includes('strokeWidth') && markupToolStyles[key] === undefined && hasProp(markupToolShape, 'points')) {\n\t\t\t\t\t\tprev[key] = markupToolShape[key];\n\t\t\t\t\t\treturn prev;\n\t\t\t\t\t}\n\n\t\t\t\t\t// get options for this style\n\t\t\t\t\tconst { share = true } = markupToolShape.settings && markupToolShape.settings[key] || {};\n\n\t\t\t\t\t// where to get styles\n\t\t\t\t\tconst styles = enableToolShareStyles && share\n\t\t\t\t\t? markupToolStyles\n\t\t\t\t\t: markupToolStyles[toolActive] || {};\n\n\t\t\t\t\t// set style\n\t\t\t\t\tprev[key] = hasProp(styles, key)\n\t\t\t\t\t? // use merged styles\n\t\t\t\t\t\tstyles[key]\n\t\t\t\t\t: // tool default styles\n\t\t\t\t\t\tmarkupToolShape[key];\n\n\t\t\t\t\treturn prev;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*utilKey, toolActive*/ 1048577 | $$self.$$.dirty[3] & /*toolRetainStyles*/ 1024 | $$self.$$.dirty[4] & /*markupToolStylesComputed*/ 4) {\n\t\t\ttoolRetainStyles\n\t\t\t? updateInterfaceState(utilKey, toolActive, markupToolStylesComputed)\n\t\t\t: resetInterfaceState(utilKey);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[3] & /*markupSelected*/ 67108864 | $$self.$$.dirty[4] & /*$selection, markupToolStylesComputed*/ 67108868) {\n\t\t\t$$invalidate(134, markupShapeSelected = $selection && $isActive\n\t\t\t? markupSelected || markupToolStylesComputed\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*isMultiSelection, multiSelection*/ 1610612736 | $$self.$$.dirty[4] & /*markupShapeSelected, markupDraft*/ 1536) {\n\t\t\t// props presented to shapestyleeditor\n\t\t\t$$invalidate(49, shapeStyleShape = isMultiSelection\n\t\t\t? getMultiSelectionSharedStyleProps(multiSelection)\n\t\t\t: markupShapeSelected || markupDraft);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[4] & /*markupToolShape*/ 8) {\n\t\t\t// don't enable snapping for eraser\n\t\t\t$$invalidate(48, preventPointerSnapping = hasProp(markupToolShape, 'eraseRadius') || hasProp(markupToolShape, 'points') && !hasProp(markupToolShape, 'pathClose') || toolActive === 'move' || toolActive === 'view');\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$parentRect*/ 64 | $$self.$$.dirty[4] & /*markupToolShape*/ 8) {\n\t\t\t$$invalidate(47, toolEraseRadius = markupToolShape && markupToolShape.eraseRadius !== undefined\n\t\t\t? getValueInContext(markupToolShape.eraseRadius, $parentRect)\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*$keysPressedStore*/ 33554432) {\n\t\t\t//#region Pan and Zoom\n\t\t\t$$invalidate(131, userEnabledPanModeWithKeyboard = $isActive && $keysPressedStore.includes(32)); // is holding space\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[1] & /*$isActive*/ 16) {\n\t\t\t$$invalidate(132, userEnabledPanModeWithButton = $isActive && toolActive === 'view');\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*userEnabledPanModeWithButton, userEnabledPanModeWithKeyboard*/ 384) {\n\t\t\t$$invalidate(129, enablePanMode = userEnabledPanModeWithButton || userEnabledPanModeWithKeyboard);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*enablePanMode, markupEditing*/ 96) {\n\t\t\t$$invalidate(128, isEditingText = enablePanMode\n\t\t\t? !!markupEditing || isTextField(document.activeElement)\n\t\t\t: false);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*enablePanMode, isEditingText*/ 48) {\n\t\t\tenablePanInput.set($isActive ? enablePanMode && !isEditingText : true);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*isEditingText*/ 16) {\n\t\t\tenableZoomInput.set($isActive ? !isEditingText : true);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$parentRect*/ 64 | $$self.$$.dirty[4] & /*markupToolShape, markupToolStylesComputed*/ 12) {\n\t\t\t$$invalidate(120, customCursor = markupToolShape.cursorStyle\n\t\t\t? getCustomCursorDescription(\n\t\t\t\t\tmarkupToolShape,\n\t\t\t\t\t{\n\t\t\t\t\t\t...markupToolShape,\n\t\t\t\t\t\t...markupToolStylesComputed\n\t\t\t\t\t},\n\t\t\t\t\t$parentRect\n\t\t\t\t)\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*imageHoverPosition*/ 33554432 | $$self.$$.dirty[4] & /*$imageSize*/ 16777216) {\n\t\t\t$$invalidate(121, isHoveringOverImage = imageHoverPosition && vectorInSize(imageHoverPosition, $imageSize));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*utilKey*/ 1048576 | $$self.$$.dirty[1] & /*$enablePanInputStatus, $imageTransformsInterpolated*/ 160 | $$self.$$.dirty[3] & /*isHoveringOverImage, shapeUnderPointer, customCursor, canvasHoverPosition*/ 427819008 | $$self.$$.dirty[4] & /*interactionMode, holdingOptionKey*/ 3) {\n\t\t\tif (isHoveringOverImage && !shapeUnderPointer && customCursor && !$enablePanInputStatus) {\n\t\t\t\tconst size = customCursor.size * $imageTransformsInterpolated.scale;\n\n\t\t\t\tconst shape = {\n\t\t\t\t\tid: `cursor-${utilKey}`,\n\t\t\t\t\tx: canvasHoverPosition.x,\n\t\t\t\t\ty: canvasHoverPosition.y,\n\t\t\t\t\tstrokeWidth: 0.5,\n\t\t\t\t\tstrokeColor: [0, 0, 0]\n\t\t\t\t};\n\n\t\t\t\tif (customCursor.style === 'ellipse') {\n\t\t\t\t\tshape.rx = size;\n\t\t\t\t\tshape.ry = size;\n\t\t\t\t}\n\n\t\t\t\tconst shadowShape = {\n\t\t\t\t\tstrokeWidth: 2.5,\n\t\t\t\t\tstrokeColor: [1, 1, 1],\n\t\t\t\t\topacity: 0.75\n\t\t\t\t};\n\n\t\t\t\tconst shadow = { ...shape, ...shadowShape };\n\t\t\t\tconst cursorShapes = [shadow, shape];\n\n\t\t\t\tif (interactionMode === 'selection' && holdingOptionKey) {\n\t\t\t\t\tconst s = size;\n\t\t\t\t\tconst x = canvasHoverPosition.x + s;\n\t\t\t\t\tconst y = canvasHoverPosition.y + s + 4;\n\n\t\t\t\t\tconst minus = {\n\t\t\t\t\t\tid: `cursor-${utilKey}`,\n\t\t\t\t\t\tstrokeWidth: 0.75,\n\t\t\t\t\t\tstrokeColor: [0, 0, 0],\n\t\t\t\t\t\tpoints: [{ x, y }, { x: x + 4, y }]\n\t\t\t\t\t};\n\n\t\t\t\t\tcursorShapes.push(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...minus,\n\t\t\t\t\t\t\t...shadowShape,\n\t\t\t\t\t\t\tstrokeWidth: 2,\n\t\t\t\t\t\t\tpoints: [{ x: x - 0.5, y }, { x: x + 4.5, y }]\n\t\t\t\t\t\t},\n\t\t\t\t\t\tminus\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tupdateCustomCursor(cursorShapes);\n\t\t\t} else {\n\t\t\t\tremoveCustomCursor();\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive*/ 1 | $$self.$$.dirty[1] & /*$enablePanInputStatus*/ 128 | $$self.$$.dirty[3] & /*isHoveringOverImage, customCursor, shapeUnderPointer, markupSelected*/ 478150656) {\n\t\t\t$$invalidate(46, cursorStyle = isHoveringOverImage\n\t\t\t? getCursorStyle(customCursor, shapeUnderPointer, markupSelected, $enablePanInputStatus, isPanning, toolActive)\n\t\t\t: // render default cursor\n\t\t\t\t'default');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*toolActive, shapePresets, enablePresetSelectImage*/ 526337 | $$self.$$.dirty[3] & /*willRenderPresetToolbar*/ 131072) {\n\t\t\t//\n\t\t\t// presets\n\t\t\t//\n\t\t\t$$invalidate(45, shouldRenderPresets = toolActive === 'preset' && (shapePresets.length > 0 || enablePresetSelectImage || willRenderPresetToolbar));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$parentRect*/ 64) {\n\t\t\t// if parent rect is a `Size` we're sticking presets to the image context\n\t\t\tshouldStickToImage = !hasProp($parentRect, 'x') && !hasProp($parentRect, 'y');\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$elasticityMultiplier*/ 4194304) {\n\t\t\t//\n\t\t\t// scroll components\n\t\t\t//\n\t\t\t$$invalidate(44, computedScrollElasticity = $elasticityMultiplier * scrollElasticity);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*willRenderPresetToolbar*/ 131072 | $$self.$$.dirty[4] & /*$redrawTrigger, $env*/ 1572864) {\n\t\t\t$$invalidate(43, runWillRenderPresetToolbarHook = $redrawTrigger && willRenderPresetToolbar\n\t\t\t? items => runSafe(() => willRenderPresetToolbar(items, addPreset, { ...$env }, () => redrawTrigger.set({})))\n\t\t\t: passthrough);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*hooks*/ 524288) {\n\t\t\t//\n\t\t\t// filter out beforeAdd hook\n\t\t\t//\n\t\t\t$$invalidate(42, layoutEditorHooks = Object.keys(hooks).reduce(\n\t\t\t\t(prev, curr) => {\n\t\t\t\t\tif (curr === 'beforeAddShape' || hooks[curr] === undefined) return prev;\n\t\t\t\t\tprev[curr] = hooks[curr];\n\t\t\t\t\treturn prev;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16) {\n\t\t\ttoggleShapePrerendering($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[3] & /*willRenderHeaderTools*/ 65536 | $$self.$$.dirty[4] & /*$redrawTrigger, $env*/ 1572864) {\n\t\t\t$$invalidate(30, headerTools = $redrawTrigger && willRenderHeaderTools([], $env, () => redrawTrigger.set({})));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*headerTools, shapeControls*/ 1073742336) {\n\t\t\t// we should render the header if header tools are defined or if a shape style has been propagated to the toolbar\n\t\t\t$$invalidate(41, shouldRenderHeaderTools = !!headerTools.length || !!Object.keys(shapeControls).some(key => headerToolbarStyles.includes(key)));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 16 | $$self.$$.dirty[4] & /*$isAnimated*/ 262144) {\n\t\t\t$isAnimated && footerOffset.set($isActive ? 0 : 20);\n\t\t}\n\n\t\tif ($$self.$$.dirty[4] & /*$footerOffset*/ 131072) ;\n\n\t\tif ($$self.$$.dirty[4] & /*$footerOffset*/ 131072) {\n\t\t\t$$invalidate(40, styleTransform = $footerOffset\n\t\t\t? `translateY(${$footerOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\tallowPlayPause.set(false);\n\n\treturn [\n\t\ttoolActive,\n\t\tisActive,\n\t\tisActiveFraction,\n\t\tisVisible,\n\t\tlocale,\n\t\tshapes,\n\t\ttoolSelectRadius,\n\t\ttoolbarLayout,\n\t\ttextInputMode,\n\t\tshapeControls,\n\t\tenableButtonFlipVertical,\n\t\tenablePresetSelectImage,\n\t\tenablePresetDropImage,\n\t\tenableTapToAddText,\n\t\tenableMultiSelect,\n\t\tgridSize,\n\t\tsnapThreshold,\n\t\tenableSnapToContext,\n\t\twillRenderShapeStyleControls,\n\t\tshapePresets,\n\t\tutilKey,\n\t\tmapScreenPointToImagePoint,\n\t\tmapImagePointToScreenPoint,\n\t\timageRotation,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\tparentRect,\n\t\ttoolGroupActiveIndex,\n\t\tmarkupEditor,\n\t\tpingHub,\n\t\theaderTools,\n\t\tping,\n\t\ttoolsFiltered,\n\t\thasToolbarGroups,\n\t\thasMultipleTools,\n\t\t$isActive,\n\t\t$imageTransformsInterpolated,\n\t\t$parentRect,\n\t\t$enablePanInputStatus,\n\t\t$utilRectPadded,\n\t\tstyleTransform,\n\t\tshouldRenderHeaderTools,\n\t\tlayoutEditorHooks,\n\t\trunWillRenderPresetToolbarHook,\n\t\tcomputedScrollElasticity,\n\t\tshouldRenderPresets,\n\t\tcursorStyle,\n\t\ttoolEraseRadius,\n\t\tpreventPointerSnapping,\n\t\tshapeStyleShape,\n\t\tmarkupOffset,\n\t\tshouldRenderShapeEditor,\n\t\tshouldRenderControls,\n\t\tshowToolbar,\n\t\ttoolbarGroups,\n\t\t$rootRect,\n\t\t$isActiveFraction,\n\t\t$rootColorSecondary,\n\t\tselection,\n\t\tisAnimated,\n\t\telasticityMultiplier,\n\t\tui,\n\t\tkeysPressedStore,\n\t\tenv,\n\t\trootRect,\n\t\trootColorSecondary,\n\t\tenablePanInputStatus,\n\t\tstageRect,\n\t\tutilRectPadded,\n\t\timageOverlayMarkup,\n\t\timagePreviewModifiers,\n\t\timageCropRect,\n\t\tstageScalar,\n\t\timageSelectionRect,\n\t\timageTransformsInterpolated,\n\t\timageSelectionPan,\n\t\timageSize,\n\t\tupdateActiveToolGroup,\n\t\tupdateActiveTool,\n\t\thandleInteractionStart,\n\t\thandleInteractionUpdate,\n\t\thandleInteractionRelease,\n\t\thandleInteractionCancel,\n\t\thandleInteractionEnd,\n\t\thandleKey,\n\t\thandleUpdateSelectedMarkupShape,\n\t\thandleHoverCanvas,\n\t\thandleLeaveCanvas,\n\t\thandleTapCanvas,\n\t\thandleHoverShape,\n\t\thandleGrabPreset,\n\t\thandleDragPreset,\n\t\thandleDropPreset,\n\t\thandleAddPreset,\n\t\thandleDropFiles,\n\t\thandleWillStartInteraction,\n\t\thandleMarkupUpdate,\n\t\tredrawTrigger,\n\t\theaderToolbarStyles,\n\t\tfooterOffset,\n\t\tstores,\n\t\ttoolbar,\n\t\ttoolShapes,\n\t\ttoolRetainStyles,\n\t\tenableSelectToolToAddShape,\n\t\tenableAutoSelectMoveTool,\n\t\tenableMoveTool,\n\t\tenableViewTool,\n\t\tenableToolShareStyles,\n\t\twillRenderHeaderTools,\n\t\twillRenderPresetToolbar,\n\t\twillStartInteraction,\n\t\thooks,\n\t\tactiveToolShapes,\n\t\tgroupToolActive,\n\t\tmarkupToolStyles,\n\t\tshapeUnderPointer,\n\t\tcanvasHoverPosition,\n\t\timageHoverPosition,\n\t\tmarkupSelected,\n\t\tcustomCursor,\n\t\tisHoveringOverImage,\n\t\tmultiSelection,\n\t\tisMultiSelection,\n\t\tholdingOptionKey,\n\t\tinteractionMode,\n\t\tmarkupToolStylesComputed,\n\t\tmarkupToolShape,\n\t\tisEditingText,\n\t\tenablePanMode,\n\t\tmarkupEditing,\n\t\tuserEnabledPanModeWithKeyboard,\n\t\tuserEnabledPanModeWithButton,\n\t\tmarkupDraft,\n\t\tmarkupShapeSelected,\n\t\tmarkupShapeKeys,\n\t\ttoolOptions,\n\t\thasShapeControls,\n\t\thasTools,\n\t\thasActiveTool,\n\t\tactiveToolbar,\n\t\t$footerOffset,\n\t\t$isAnimated,\n\t\t$env,\n\t\t$redrawTrigger,\n\t\t$shapes,\n\t\t$elasticityMultiplier,\n\t\t$stageRect,\n\t\t$imageSize,\n\t\t$keysPressedStore,\n\t\t$selection,\n\t\t$isVisible,\n\t\tmeasure_handler_1,\n\t\tfunc,\n\t\tfunc_1,\n\t\tfunc_2,\n\t\tfunc_3,\n\t\tfunc_4,\n\t\tfunc_5,\n\t\tfunc_6,\n\t\tfunc_7,\n\t\tfunc_8,\n\t\tfunc_9,\n\t\tshapelayouteditor_binding,\n\t\tdiv_binding,\n\t\tfunc_10,\n\t\tmeasure_handler\n\t];\n}\n\nclass ShapeUtil extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$b,\n\t\t\tcreate_fragment$b,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tisActive: 1,\n\t\t\t\tisActiveFraction: 2,\n\t\t\t\tisVisible: 3,\n\t\t\t\tstores: 100,\n\t\t\t\tlocale: 4,\n\t\t\t\tshapes: 5,\n\t\t\t\ttoolbar: 101,\n\t\t\t\ttoolShapes: 102,\n\t\t\t\ttoolActive: 0,\n\t\t\t\ttoolSelectRadius: 6,\n\t\t\t\ttoolRetainStyles: 103,\n\t\t\t\ttoolbarLayout: 7,\n\t\t\t\ttextInputMode: 8,\n\t\t\t\tshapeControls: 9,\n\t\t\t\tenableButtonFlipVertical: 10,\n\t\t\t\tenablePresetSelectImage: 11,\n\t\t\t\tenablePresetDropImage: 12,\n\t\t\t\tenableSelectToolToAddShape: 104,\n\t\t\t\tenableAutoSelectMoveTool: 105,\n\t\t\t\tenableTapToAddText: 13,\n\t\t\t\tenableMoveTool: 106,\n\t\t\t\tenableViewTool: 107,\n\t\t\t\tenableToolShareStyles: 108,\n\t\t\t\tenableMultiSelect: 14,\n\t\t\t\tgridSize: 15,\n\t\t\t\tsnapThreshold: 16,\n\t\t\t\tenableSnapToContext: 17,\n\t\t\t\twillRenderHeaderTools: 109,\n\t\t\t\twillRenderPresetToolbar: 110,\n\t\t\t\twillRenderShapeStyleControls: 18,\n\t\t\t\twillStartInteraction: 111,\n\t\t\t\tshapePresets: 19,\n\t\t\t\tutilKey: 20,\n\t\t\t\tmapScreenPointToImagePoint: 21,\n\t\t\t\tmapImagePointToScreenPoint: 22,\n\t\t\t\timageRotation: 23,\n\t\t\t\timageFlipX: 24,\n\t\t\t\timageFlipY: 25,\n\t\t\t\tparentRect: 26,\n\t\t\t\thooks: 112\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1, -1, -1, -1, -1]\n\t\t);\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget isActiveFraction() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset isActiveFraction(isActiveFraction) {\n\t\tthis.$$set({ isActiveFraction });\n\t\tflush();\n\t}\n\n\tget isVisible() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset isVisible(isVisible) {\n\t\tthis.$$set({ isVisible });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[100];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget shapes() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset shapes(shapes) {\n\t\tthis.$$set({ shapes });\n\t\tflush();\n\t}\n\n\tget toolbar() {\n\t\treturn this.$$.ctx[101];\n\t}\n\n\tset toolbar(toolbar) {\n\t\tthis.$$set({ toolbar });\n\t\tflush();\n\t}\n\n\tget toolShapes() {\n\t\treturn this.$$.ctx[102];\n\t}\n\n\tset toolShapes(toolShapes) {\n\t\tthis.$$set({ toolShapes });\n\t\tflush();\n\t}\n\n\tget toolActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset toolActive(toolActive) {\n\t\tthis.$$set({ toolActive });\n\t\tflush();\n\t}\n\n\tget toolSelectRadius() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset toolSelectRadius(toolSelectRadius) {\n\t\tthis.$$set({ toolSelectRadius });\n\t\tflush();\n\t}\n\n\tget toolRetainStyles() {\n\t\treturn this.$$.ctx[103];\n\t}\n\n\tset toolRetainStyles(toolRetainStyles) {\n\t\tthis.$$set({ toolRetainStyles });\n\t\tflush();\n\t}\n\n\tget toolbarLayout() {\n\t\treturn this.$$.ctx[7];\n\t}\n\n\tset toolbarLayout(toolbarLayout) {\n\t\tthis.$$set({ toolbarLayout });\n\t\tflush();\n\t}\n\n\tget textInputMode() {\n\t\treturn this.$$.ctx[8];\n\t}\n\n\tset textInputMode(textInputMode) {\n\t\tthis.$$set({ textInputMode });\n\t\tflush();\n\t}\n\n\tget shapeControls() {\n\t\treturn this.$$.ctx[9];\n\t}\n\n\tset shapeControls(shapeControls) {\n\t\tthis.$$set({ shapeControls });\n\t\tflush();\n\t}\n\n\tget enableButtonFlipVertical() {\n\t\treturn this.$$.ctx[10];\n\t}\n\n\tset enableButtonFlipVertical(enableButtonFlipVertical) {\n\t\tthis.$$set({ enableButtonFlipVertical });\n\t\tflush();\n\t}\n\n\tget enablePresetSelectImage() {\n\t\treturn this.$$.ctx[11];\n\t}\n\n\tset enablePresetSelectImage(enablePresetSelectImage) {\n\t\tthis.$$set({ enablePresetSelectImage });\n\t\tflush();\n\t}\n\n\tget enablePresetDropImage() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tset enablePresetDropImage(enablePresetDropImage) {\n\t\tthis.$$set({ enablePresetDropImage });\n\t\tflush();\n\t}\n\n\tget enableSelectToolToAddShape() {\n\t\treturn this.$$.ctx[104];\n\t}\n\n\tset enableSelectToolToAddShape(enableSelectToolToAddShape) {\n\t\tthis.$$set({ enableSelectToolToAddShape });\n\t\tflush();\n\t}\n\n\tget enableAutoSelectMoveTool() {\n\t\treturn this.$$.ctx[105];\n\t}\n\n\tset enableAutoSelectMoveTool(enableAutoSelectMoveTool) {\n\t\tthis.$$set({ enableAutoSelectMoveTool });\n\t\tflush();\n\t}\n\n\tget enableTapToAddText() {\n\t\treturn this.$$.ctx[13];\n\t}\n\n\tset enableTapToAddText(enableTapToAddText) {\n\t\tthis.$$set({ enableTapToAddText });\n\t\tflush();\n\t}\n\n\tget enableMoveTool() {\n\t\treturn this.$$.ctx[106];\n\t}\n\n\tset enableMoveTool(enableMoveTool) {\n\t\tthis.$$set({ enableMoveTool });\n\t\tflush();\n\t}\n\n\tget enableViewTool() {\n\t\treturn this.$$.ctx[107];\n\t}\n\n\tset enableViewTool(enableViewTool) {\n\t\tthis.$$set({ enableViewTool });\n\t\tflush();\n\t}\n\n\tget enableToolShareStyles() {\n\t\treturn this.$$.ctx[108];\n\t}\n\n\tset enableToolShareStyles(enableToolShareStyles) {\n\t\tthis.$$set({ enableToolShareStyles });\n\t\tflush();\n\t}\n\n\tget enableMultiSelect() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tset enableMultiSelect(enableMultiSelect) {\n\t\tthis.$$set({ enableMultiSelect });\n\t\tflush();\n\t}\n\n\tget gridSize() {\n\t\treturn this.$$.ctx[15];\n\t}\n\n\tset gridSize(gridSize) {\n\t\tthis.$$set({ gridSize });\n\t\tflush();\n\t}\n\n\tget snapThreshold() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset snapThreshold(snapThreshold) {\n\t\tthis.$$set({ snapThreshold });\n\t\tflush();\n\t}\n\n\tget enableSnapToContext() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset enableSnapToContext(enableSnapToContext) {\n\t\tthis.$$set({ enableSnapToContext });\n\t\tflush();\n\t}\n\n\tget willRenderHeaderTools() {\n\t\treturn this.$$.ctx[109];\n\t}\n\n\tset willRenderHeaderTools(willRenderHeaderTools) {\n\t\tthis.$$set({ willRenderHeaderTools });\n\t\tflush();\n\t}\n\n\tget willRenderPresetToolbar() {\n\t\treturn this.$$.ctx[110];\n\t}\n\n\tset willRenderPresetToolbar(willRenderPresetToolbar) {\n\t\tthis.$$set({ willRenderPresetToolbar });\n\t\tflush();\n\t}\n\n\tget willRenderShapeStyleControls() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset willRenderShapeStyleControls(willRenderShapeStyleControls) {\n\t\tthis.$$set({ willRenderShapeStyleControls });\n\t\tflush();\n\t}\n\n\tget willStartInteraction() {\n\t\treturn this.$$.ctx[111];\n\t}\n\n\tset willStartInteraction(willStartInteraction) {\n\t\tthis.$$set({ willStartInteraction });\n\t\tflush();\n\t}\n\n\tget shapePresets() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset shapePresets(shapePresets) {\n\t\tthis.$$set({ shapePresets });\n\t\tflush();\n\t}\n\n\tget utilKey() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset utilKey(utilKey) {\n\t\tthis.$$set({ utilKey });\n\t\tflush();\n\t}\n\n\tget mapScreenPointToImagePoint() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset mapScreenPointToImagePoint(mapScreenPointToImagePoint) {\n\t\tthis.$$set({ mapScreenPointToImagePoint });\n\t\tflush();\n\t}\n\n\tget mapImagePointToScreenPoint() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tset mapImagePointToScreenPoint(mapImagePointToScreenPoint) {\n\t\tthis.$$set({ mapImagePointToScreenPoint });\n\t\tflush();\n\t}\n\n\tget imageRotation() {\n\t\treturn this.$$.ctx[23];\n\t}\n\n\tset imageRotation(imageRotation) {\n\t\tthis.$$set({ imageRotation });\n\t\tflush();\n\t}\n\n\tget imageFlipX() {\n\t\treturn this.$$.ctx[24];\n\t}\n\n\tset imageFlipX(imageFlipX) {\n\t\tthis.$$set({ imageFlipX });\n\t\tflush();\n\t}\n\n\tget imageFlipY() {\n\t\treturn this.$$.ctx[25];\n\t}\n\n\tset imageFlipY(imageFlipY) {\n\t\tthis.$$set({ imageFlipY });\n\t\tflush();\n\t}\n\n\tget parentRect() {\n\t\treturn this.$$.ctx[26];\n\t}\n\n\tset parentRect(parentRect) {\n\t\tthis.$$set({ parentRect });\n\t\tflush();\n\t}\n\n\tget hooks() {\n\t\treturn this.$$.ctx[112];\n\t}\n\n\tset hooks(hooks) {\n\t\tthis.$$set({ hooks });\n\t\tflush();\n\t}\n}\n\nvar _mapImagePointToScreenPoint = (imagePoint, canvasSize, imageSize, imageOrigin, imageTranslation, imageRotation, imageScalar, imageFlipX, imageFlipY) => {\n    const mappedPoint = vectorClone(imagePoint);\n    const imageCenterX = imageSize.width * 0.5;\n    const imageCenterY = imageSize.height * 0.5;\n    const canvasCenterX = canvasSize.width * 0.5;\n    const canvasCenterY = canvasSize.height * 0.5;\n    const imageOffsetX = imageTranslation.x + imageOrigin.x;\n    const imageOffsetY = imageTranslation.y + imageOrigin.y;\n    if (imageFlipX)\n        mappedPoint.x = imageSize.width - mappedPoint.x;\n    if (imageFlipY)\n        mappedPoint.y = imageSize.height - mappedPoint.y;\n    // rotate around image center based on if image is rotated\n    const c = Math.cos(imageRotation);\n    const s = Math.sin(imageRotation);\n    mappedPoint.x -= imageCenterX;\n    mappedPoint.y -= imageCenterY;\n    const rx = mappedPoint.x * c - mappedPoint.y * s;\n    const ry = mappedPoint.x * s + mappedPoint.y * c;\n    mappedPoint.x = imageCenterX + rx;\n    mappedPoint.y = imageCenterY + ry;\n    // position based on screen transforms\n    mappedPoint.x *= imageScalar;\n    mappedPoint.y *= imageScalar;\n    mappedPoint.x += canvasCenterX;\n    mappedPoint.y += canvasCenterY;\n    mappedPoint.x += imageOffsetX;\n    mappedPoint.y += imageOffsetY;\n    mappedPoint.x -= imageCenterX * imageScalar;\n    mappedPoint.y -= imageCenterY * imageScalar;\n    const tx = (imageTranslation.x - imageOffsetX) * imageScalar;\n    const ty = (imageTranslation.y - imageOffsetY) * imageScalar;\n    const rtx = tx * c - ty * s;\n    const rty = tx * s + ty * c;\n    mappedPoint.x += rtx;\n    mappedPoint.y += rty;\n    return mappedPoint;\n};\n\nvar _mapScreenPointToImagePoint = (screenPoint, canvasSize, imageSize, imageOrigin, imageTranslation, imageRotation, imageScalar, imageFlipX, imageFlipY) => {\n    const mappedPoint = vectorClone(screenPoint);\n    const imageCenter = sizeCenter(imageSize);\n    const canvasCenter = sizeCenter(canvasSize);\n    const imageOffset = vectorCreate(imageTranslation.x + imageOrigin.x, imageTranslation.y + imageOrigin.y);\n    const c = Math.cos(imageRotation);\n    const s = Math.sin(imageRotation);\n    mappedPoint.x -= canvasCenter.x;\n    mappedPoint.y -= canvasCenter.y;\n    const tx = (imageTranslation.x - imageOffset.x) * imageScalar;\n    const ty = (imageTranslation.y - imageOffset.y) * imageScalar;\n    const rtx = tx * c - ty * s;\n    const rty = tx * s + ty * c;\n    mappedPoint.x -= rtx;\n    mappedPoint.y -= rty;\n    mappedPoint.x -= imageOffset.x;\n    mappedPoint.y -= imageOffset.y;\n    mappedPoint.x /= imageScalar;\n    mappedPoint.y /= imageScalar;\n    const rx = mappedPoint.x * c + mappedPoint.y * s;\n    const ry = mappedPoint.x * s - mappedPoint.y * c;\n    mappedPoint.x = rx;\n    mappedPoint.y = -ry;\n    mappedPoint.x += imageCenter.x;\n    mappedPoint.y += imageCenter.y;\n    if (imageFlipX)\n        mappedPoint.x = imageSize.width - mappedPoint.x;\n    if (imageFlipY)\n        mappedPoint.y = imageSize.height - mappedPoint.y;\n    return mappedPoint;\n};\n\nvar isBoolean = (value) => typeof value === 'boolean';\n\n/* src/core/ui/plugins/annotate/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$a(ctx) {\n\tlet shapeutil;\n\tlet updating_toolActive;\n\tlet current;\n\n\tfunction shapeutil_toolActive_binding(value) {\n\t\t/*shapeutil_toolActive_binding*/ ctx[61](value);\n\t}\n\n\tlet shapeutil_props = {\n\t\tutilKey: /*name*/ ctx[1],\n\t\tstores: /*stores*/ ctx[5],\n\t\tlocale: /*locale*/ ctx[6],\n\t\tisActive: /*isActive*/ ctx[2],\n\t\tisActiveFraction: /*isActiveFraction*/ ctx[3],\n\t\tisVisible: /*isVisible*/ ctx[4],\n\t\tmapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[46],\n\t\tmapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[45],\n\t\timageRotation: /*$imageRotation*/ ctx[47],\n\t\timageFlipX: /*$imageFlipX*/ ctx[44],\n\t\timageFlipY: /*$imageFlipY*/ ctx[43],\n\t\tshapes: /*imageAnnotation*/ ctx[49],\n\t\ttoolbar: /*annotateTools*/ ctx[21] || /*markupEditorToolbar*/ ctx[7],\n\t\ttoolShapes: /*annotateToolShapes*/ ctx[22] || /*markupEditorToolStyles*/ ctx[8],\n\t\ttoolRetainStyles: /*markupEditorToolRetainStyles*/ ctx[9],\n\t\tenableSelectToolToAddShape: /*enableSelectToolToAddShape*/ ctx[31],\n\t\tenableTapToAddText: /*enableTapToAddText*/ ctx[32],\n\t\tenableViewTool: /*enableViewTool*/ ctx[30],\n\t\tenableMoveTool: /*enableMoveTool*/ ctx[34],\n\t\tenableAutoSelectMoveTool: /*enableAutoSelectMoveTool*/ ctx[33],\n\t\tenableMultiSelect: /*enableMultiSelect*/ ctx[35],\n\t\tsnapThreshold: /*markupEditorSnapThreshold*/ ctx[16],\n\t\tgridSize: isNumber(/*annotateGridSize*/ ctx[18])\n\t\t? /*annotateGridSize*/ ctx[18]\n\t\t: /*markupEditorGridSize*/ ctx[15],\n\t\tenableSnapToContext: isBoolean(/*annotateSnapToContext*/ ctx[19])\n\t\t? /*annotateSnapToContext*/ ctx[19]\n\t\t: /*markupEditorSnapToContext*/ ctx[17],\n\t\tenableToolShareStyles: /*markupEditorToolShareStyles*/ ctx[13],\n\t\tshapeControls: /*annotateShapeControls*/ ctx[23] || /*markupEditorShapeStyleControls*/ ctx[10],\n\t\tshapePresets: /*annotatePresets*/ ctx[27],\n\t\tenableButtonFlipVertical: /*annotateEnableButtonFlipVertical*/ ctx[24],\n\t\tparentRect: /*imageSize*/ ctx[50],\n\t\tenablePresetDropImage: /*annotateEnableDropImagePreset*/ ctx[26],\n\t\tenablePresetSelectImage: /*annotateEnableSelectImagePreset*/ ctx[25],\n\t\ttoolSelectRadius: /*markupEditorToolSelectRadius*/ ctx[11],\n\t\ttextInputMode: /*markupEditorTextInputMode*/ ctx[12],\n\t\twillStartInteraction: /*markupEditorWillStartInteraction*/ ctx[14],\n\t\twillRenderPresetToolbar: /*annotateWillRenderShapePresetToolbar*/ ctx[28] || /*willRenderShapePresetToolbar*/ ctx[20],\n\t\twillRenderShapeStyleControls: /*annotateWillRenderShapeStyleControls*/ ctx[29],\n\t\thooks: {\n\t\t\twillRenderShapeControls: /*willRenderShapeControls*/ ctx[36],\n\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[37],\n\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[38],\n\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[39],\n\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[40],\n\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[41],\n\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[42]\n\t\t}\n\t};\n\n\tif (/*annotateActiveTool*/ ctx[0] !== void 0) {\n\t\tshapeutil_props.toolActive = /*annotateActiveTool*/ ctx[0];\n\t}\n\n\tshapeutil = new ShapeUtil({ props: shapeutil_props });\n\tbinding_callbacks.push(() => bind(shapeutil, 'toolActive', shapeutil_toolActive_binding));\n\tshapeutil.$on(\"measure\", /*measure_handler*/ ctx[62]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapeutil.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapeutil, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapeutil_changes = {};\n\t\t\tif (dirty[0] & /*stores*/ 32) shapeutil_changes.stores = /*stores*/ ctx[5];\n\t\t\tif (dirty[0] & /*locale*/ 64) shapeutil_changes.locale = /*locale*/ ctx[6];\n\t\t\tif (dirty[0] & /*isActive*/ 4) shapeutil_changes.isActive = /*isActive*/ ctx[2];\n\t\t\tif (dirty[0] & /*isActiveFraction*/ 8) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[3];\n\t\t\tif (dirty[0] & /*isVisible*/ 16) shapeutil_changes.isVisible = /*isVisible*/ ctx[4];\n\t\t\tif (dirty[1] & /*mapScreenPointToImagePoint*/ 32768) shapeutil_changes.mapScreenPointToImagePoint = /*mapScreenPointToImagePoint*/ ctx[46];\n\t\t\tif (dirty[1] & /*mapImagePointToScreenPoint*/ 16384) shapeutil_changes.mapImagePointToScreenPoint = /*mapImagePointToScreenPoint*/ ctx[45];\n\t\t\tif (dirty[1] & /*$imageRotation*/ 65536) shapeutil_changes.imageRotation = /*$imageRotation*/ ctx[47];\n\t\t\tif (dirty[1] & /*$imageFlipX*/ 8192) shapeutil_changes.imageFlipX = /*$imageFlipX*/ ctx[44];\n\t\t\tif (dirty[1] & /*$imageFlipY*/ 4096) shapeutil_changes.imageFlipY = /*$imageFlipY*/ ctx[43];\n\t\t\tif (dirty[0] & /*annotateTools, markupEditorToolbar*/ 2097280) shapeutil_changes.toolbar = /*annotateTools*/ ctx[21] || /*markupEditorToolbar*/ ctx[7];\n\t\t\tif (dirty[0] & /*annotateToolShapes, markupEditorToolStyles*/ 4194560) shapeutil_changes.toolShapes = /*annotateToolShapes*/ ctx[22] || /*markupEditorToolStyles*/ ctx[8];\n\t\t\tif (dirty[0] & /*markupEditorToolRetainStyles*/ 512) shapeutil_changes.toolRetainStyles = /*markupEditorToolRetainStyles*/ ctx[9];\n\t\t\tif (dirty[1] & /*enableSelectToolToAddShape*/ 1) shapeutil_changes.enableSelectToolToAddShape = /*enableSelectToolToAddShape*/ ctx[31];\n\t\t\tif (dirty[1] & /*enableTapToAddText*/ 2) shapeutil_changes.enableTapToAddText = /*enableTapToAddText*/ ctx[32];\n\t\t\tif (dirty[0] & /*enableViewTool*/ 1073741824) shapeutil_changes.enableViewTool = /*enableViewTool*/ ctx[30];\n\t\t\tif (dirty[1] & /*enableMoveTool*/ 8) shapeutil_changes.enableMoveTool = /*enableMoveTool*/ ctx[34];\n\t\t\tif (dirty[1] & /*enableAutoSelectMoveTool*/ 4) shapeutil_changes.enableAutoSelectMoveTool = /*enableAutoSelectMoveTool*/ ctx[33];\n\t\t\tif (dirty[1] & /*enableMultiSelect*/ 16) shapeutil_changes.enableMultiSelect = /*enableMultiSelect*/ ctx[35];\n\t\t\tif (dirty[0] & /*markupEditorSnapThreshold*/ 65536) shapeutil_changes.snapThreshold = /*markupEditorSnapThreshold*/ ctx[16];\n\n\t\t\tif (dirty[0] & /*annotateGridSize, markupEditorGridSize*/ 294912) shapeutil_changes.gridSize = isNumber(/*annotateGridSize*/ ctx[18])\n\t\t\t? /*annotateGridSize*/ ctx[18]\n\t\t\t: /*markupEditorGridSize*/ ctx[15];\n\n\t\t\tif (dirty[0] & /*annotateSnapToContext, markupEditorSnapToContext*/ 655360) shapeutil_changes.enableSnapToContext = isBoolean(/*annotateSnapToContext*/ ctx[19])\n\t\t\t? /*annotateSnapToContext*/ ctx[19]\n\t\t\t: /*markupEditorSnapToContext*/ ctx[17];\n\n\t\t\tif (dirty[0] & /*markupEditorToolShareStyles*/ 8192) shapeutil_changes.enableToolShareStyles = /*markupEditorToolShareStyles*/ ctx[13];\n\t\t\tif (dirty[0] & /*annotateShapeControls, markupEditorShapeStyleControls*/ 8389632) shapeutil_changes.shapeControls = /*annotateShapeControls*/ ctx[23] || /*markupEditorShapeStyleControls*/ ctx[10];\n\t\t\tif (dirty[0] & /*annotatePresets*/ 134217728) shapeutil_changes.shapePresets = /*annotatePresets*/ ctx[27];\n\t\t\tif (dirty[0] & /*annotateEnableButtonFlipVertical*/ 16777216) shapeutil_changes.enableButtonFlipVertical = /*annotateEnableButtonFlipVertical*/ ctx[24];\n\t\t\tif (dirty[0] & /*annotateEnableDropImagePreset*/ 67108864) shapeutil_changes.enablePresetDropImage = /*annotateEnableDropImagePreset*/ ctx[26];\n\t\t\tif (dirty[0] & /*annotateEnableSelectImagePreset*/ 33554432) shapeutil_changes.enablePresetSelectImage = /*annotateEnableSelectImagePreset*/ ctx[25];\n\t\t\tif (dirty[0] & /*markupEditorToolSelectRadius*/ 2048) shapeutil_changes.toolSelectRadius = /*markupEditorToolSelectRadius*/ ctx[11];\n\t\t\tif (dirty[0] & /*markupEditorTextInputMode*/ 4096) shapeutil_changes.textInputMode = /*markupEditorTextInputMode*/ ctx[12];\n\t\t\tif (dirty[0] & /*markupEditorWillStartInteraction*/ 16384) shapeutil_changes.willStartInteraction = /*markupEditorWillStartInteraction*/ ctx[14];\n\t\t\tif (dirty[0] & /*annotateWillRenderShapePresetToolbar, willRenderShapePresetToolbar*/ 269484032) shapeutil_changes.willRenderPresetToolbar = /*annotateWillRenderShapePresetToolbar*/ ctx[28] || /*willRenderShapePresetToolbar*/ ctx[20];\n\t\t\tif (dirty[0] & /*annotateWillRenderShapeStyleControls*/ 536870912) shapeutil_changes.willRenderShapeStyleControls = /*annotateWillRenderShapeStyleControls*/ ctx[29];\n\n\t\t\tif (dirty[1] & /*willRenderShapeControls, willRenderShapeTextControls, beforeAddShape, beforeRemoveShape, beforeDeselectShape, beforeSelectShape, beforeUpdateShape*/ 4064) shapeutil_changes.hooks = {\n\t\t\t\twillRenderShapeControls: /*willRenderShapeControls*/ ctx[36],\n\t\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[37],\n\t\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[38],\n\t\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[39],\n\t\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[40],\n\t\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[41],\n\t\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[42]\n\t\t\t};\n\n\t\t\tif (!updating_toolActive && dirty[0] & /*annotateActiveTool*/ 1) {\n\t\t\t\tupdating_toolActive = true;\n\t\t\t\tshapeutil_changes.toolActive = /*annotateActiveTool*/ ctx[0];\n\t\t\t\tadd_flush_callback(() => updating_toolActive = false);\n\t\t\t}\n\n\t\t\tshapeutil.$set(shapeutil_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapeutil.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapeutil.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapeutil, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$a($$self, $$props, $$invalidate) {\n\tlet presentationRotation;\n\tlet mapScreenPointToImagePoint;\n\tlet mapImagePointToScreenPoint;\n\tlet $imageFlipY;\n\tlet $imageFlipX;\n\tlet $imageTransformsInterpolated;\n\tlet $imageSize;\n\tlet $rootRect;\n\tlet $imageTransforms;\n\tlet $imageRotation;\n\tconst name = 'annotate';\n\tlet { isActive } = $$props;\n\tlet { isActiveFraction } = $$props;\n\tlet { isVisible } = $$props;\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { markupEditorToolbar = undefined } = $$props;\n\tlet { markupEditorToolStyles = undefined } = $$props;\n\tlet { markupEditorToolRetainStyles = undefined } = $$props;\n\tlet { markupEditorShapeStyleControls = undefined } = $$props;\n\tlet { markupEditorToolSelectRadius = undefined } = $$props;\n\tlet { markupEditorTextInputMode = undefined } = $$props;\n\tlet { markupEditorToolShareStyles = undefined } = $$props;\n\tlet { markupEditorWillStartInteraction = undefined } = $$props;\n\tlet { markupEditorGridSize = 0 } = $$props;\n\tlet { markupEditorSnapThreshold = 0 } = $$props;\n\tlet { markupEditorSnapToContext = false } = $$props;\n\tlet { annotateGridSize = undefined } = $$props;\n\tlet { annotateSnapToContext = undefined } = $$props;\n\tlet { willRenderShapePresetToolbar = undefined } = $$props;\n\tlet { annotateTools = undefined } = $$props;\n\tlet { annotateToolShapes = undefined } = $$props;\n\tlet { annotateShapeControls = undefined } = $$props;\n\tlet { annotateActiveTool = undefined } = $$props;\n\tlet { annotateEnableButtonFlipVertical = false } = $$props;\n\tlet { annotateEnableSelectImagePreset = false } = $$props;\n\tlet { annotateEnableDropImagePreset = true } = $$props;\n\tlet { annotatePresets = [] } = $$props;\n\tlet { annotateWillRenderShapePresetToolbar = undefined } = $$props;\n\tlet { annotateWillRenderShapeStyleControls = undefined } = $$props;\n\tlet { enableViewTool = undefined } = $$props;\n\tlet { enableSelectToolToAddShape = undefined } = $$props;\n\tlet { enableTapToAddText = undefined } = $$props;\n\tlet { enableAutoSelectMoveTool = undefined } = $$props;\n\tlet { enableMoveTool = undefined } = $$props;\n\tlet { enableMultiSelect = undefined } = $$props;\n\tlet { willRenderShapeControls = undefined } = $$props;\n\tlet { willRenderShapeTextControls = undefined } = $$props;\n\tlet { beforeAddShape = undefined } = $$props;\n\tlet { beforeRemoveShape = undefined } = $$props;\n\tlet { beforeDeselectShape = undefined } = $$props;\n\tlet { beforeSelectShape = undefined } = $$props;\n\tlet { beforeUpdateShape = undefined } = $$props;\n\n\t// connect filter choice to stores\n\tconst { rootRect, imageAnnotation, imageSize, imageRotation, imageFlipX, imageFlipY, imageTransforms, imageTransformsInterpolated } = stores;\n\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(59, $rootRect = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(58, $imageSize = value));\n\tcomponent_subscribe($$self, imageRotation, value => $$invalidate(47, $imageRotation = value));\n\tcomponent_subscribe($$self, imageFlipX, value => $$invalidate(44, $imageFlipX = value));\n\tcomponent_subscribe($$self, imageFlipY, value => $$invalidate(43, $imageFlipY = value));\n\tcomponent_subscribe($$self, imageTransforms, value => $$invalidate(60, $imageTransforms = value));\n\tcomponent_subscribe($$self, imageTransformsInterpolated, value => $$invalidate(57, $imageTransformsInterpolated = value));\n\n\tfunction shapeutil_toolActive_binding(value) {\n\t\tannotateActiveTool = value;\n\t\t$$invalidate(0, annotateActiveTool);\n\t}\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$invalidate(2, isActive = $$props.isActive);\n\t\tif ('isActiveFraction' in $$props) $$invalidate(3, isActiveFraction = $$props.isActiveFraction);\n\t\tif ('isVisible' in $$props) $$invalidate(4, isVisible = $$props.isVisible);\n\t\tif ('stores' in $$props) $$invalidate(5, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(6, locale = $$props.locale);\n\t\tif ('markupEditorToolbar' in $$props) $$invalidate(7, markupEditorToolbar = $$props.markupEditorToolbar);\n\t\tif ('markupEditorToolStyles' in $$props) $$invalidate(8, markupEditorToolStyles = $$props.markupEditorToolStyles);\n\t\tif ('markupEditorToolRetainStyles' in $$props) $$invalidate(9, markupEditorToolRetainStyles = $$props.markupEditorToolRetainStyles);\n\t\tif ('markupEditorShapeStyleControls' in $$props) $$invalidate(10, markupEditorShapeStyleControls = $$props.markupEditorShapeStyleControls);\n\t\tif ('markupEditorToolSelectRadius' in $$props) $$invalidate(11, markupEditorToolSelectRadius = $$props.markupEditorToolSelectRadius);\n\t\tif ('markupEditorTextInputMode' in $$props) $$invalidate(12, markupEditorTextInputMode = $$props.markupEditorTextInputMode);\n\t\tif ('markupEditorToolShareStyles' in $$props) $$invalidate(13, markupEditorToolShareStyles = $$props.markupEditorToolShareStyles);\n\t\tif ('markupEditorWillStartInteraction' in $$props) $$invalidate(14, markupEditorWillStartInteraction = $$props.markupEditorWillStartInteraction);\n\t\tif ('markupEditorGridSize' in $$props) $$invalidate(15, markupEditorGridSize = $$props.markupEditorGridSize);\n\t\tif ('markupEditorSnapThreshold' in $$props) $$invalidate(16, markupEditorSnapThreshold = $$props.markupEditorSnapThreshold);\n\t\tif ('markupEditorSnapToContext' in $$props) $$invalidate(17, markupEditorSnapToContext = $$props.markupEditorSnapToContext);\n\t\tif ('annotateGridSize' in $$props) $$invalidate(18, annotateGridSize = $$props.annotateGridSize);\n\t\tif ('annotateSnapToContext' in $$props) $$invalidate(19, annotateSnapToContext = $$props.annotateSnapToContext);\n\t\tif ('willRenderShapePresetToolbar' in $$props) $$invalidate(20, willRenderShapePresetToolbar = $$props.willRenderShapePresetToolbar);\n\t\tif ('annotateTools' in $$props) $$invalidate(21, annotateTools = $$props.annotateTools);\n\t\tif ('annotateToolShapes' in $$props) $$invalidate(22, annotateToolShapes = $$props.annotateToolShapes);\n\t\tif ('annotateShapeControls' in $$props) $$invalidate(23, annotateShapeControls = $$props.annotateShapeControls);\n\t\tif ('annotateActiveTool' in $$props) $$invalidate(0, annotateActiveTool = $$props.annotateActiveTool);\n\t\tif ('annotateEnableButtonFlipVertical' in $$props) $$invalidate(24, annotateEnableButtonFlipVertical = $$props.annotateEnableButtonFlipVertical);\n\t\tif ('annotateEnableSelectImagePreset' in $$props) $$invalidate(25, annotateEnableSelectImagePreset = $$props.annotateEnableSelectImagePreset);\n\t\tif ('annotateEnableDropImagePreset' in $$props) $$invalidate(26, annotateEnableDropImagePreset = $$props.annotateEnableDropImagePreset);\n\t\tif ('annotatePresets' in $$props) $$invalidate(27, annotatePresets = $$props.annotatePresets);\n\t\tif ('annotateWillRenderShapePresetToolbar' in $$props) $$invalidate(28, annotateWillRenderShapePresetToolbar = $$props.annotateWillRenderShapePresetToolbar);\n\t\tif ('annotateWillRenderShapeStyleControls' in $$props) $$invalidate(29, annotateWillRenderShapeStyleControls = $$props.annotateWillRenderShapeStyleControls);\n\t\tif ('enableViewTool' in $$props) $$invalidate(30, enableViewTool = $$props.enableViewTool);\n\t\tif ('enableSelectToolToAddShape' in $$props) $$invalidate(31, enableSelectToolToAddShape = $$props.enableSelectToolToAddShape);\n\t\tif ('enableTapToAddText' in $$props) $$invalidate(32, enableTapToAddText = $$props.enableTapToAddText);\n\t\tif ('enableAutoSelectMoveTool' in $$props) $$invalidate(33, enableAutoSelectMoveTool = $$props.enableAutoSelectMoveTool);\n\t\tif ('enableMoveTool' in $$props) $$invalidate(34, enableMoveTool = $$props.enableMoveTool);\n\t\tif ('enableMultiSelect' in $$props) $$invalidate(35, enableMultiSelect = $$props.enableMultiSelect);\n\t\tif ('willRenderShapeControls' in $$props) $$invalidate(36, willRenderShapeControls = $$props.willRenderShapeControls);\n\t\tif ('willRenderShapeTextControls' in $$props) $$invalidate(37, willRenderShapeTextControls = $$props.willRenderShapeTextControls);\n\t\tif ('beforeAddShape' in $$props) $$invalidate(38, beforeAddShape = $$props.beforeAddShape);\n\t\tif ('beforeRemoveShape' in $$props) $$invalidate(39, beforeRemoveShape = $$props.beforeRemoveShape);\n\t\tif ('beforeDeselectShape' in $$props) $$invalidate(40, beforeDeselectShape = $$props.beforeDeselectShape);\n\t\tif ('beforeSelectShape' in $$props) $$invalidate(41, beforeSelectShape = $$props.beforeSelectShape);\n\t\tif ('beforeUpdateShape' in $$props) $$invalidate(42, beforeUpdateShape = $$props.beforeUpdateShape);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[1] & /*$imageTransforms*/ 536870912) {\n\t\t\t$$invalidate(56, presentationRotation = $imageTransforms ? $imageTransforms.rotation.z : 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation, $imageFlipX, $imageFlipY*/ 503328768) {\n\t\t\t//\n\t\t\t// Mapping coordinates\n\t\t\t//\n\t\t\t$$invalidate(46, mapScreenPointToImagePoint = point => _mapScreenPointToImagePoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY));\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation, $imageFlipX, $imageFlipY*/ 503328768) {\n\t\t\t$$invalidate(45, mapImagePointToScreenPoint = point => _mapImagePointToScreenPoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY));\n\t\t}\n\t};\n\n\treturn [\n\t\tannotateActiveTool,\n\t\tname,\n\t\tisActive,\n\t\tisActiveFraction,\n\t\tisVisible,\n\t\tstores,\n\t\tlocale,\n\t\tmarkupEditorToolbar,\n\t\tmarkupEditorToolStyles,\n\t\tmarkupEditorToolRetainStyles,\n\t\tmarkupEditorShapeStyleControls,\n\t\tmarkupEditorToolSelectRadius,\n\t\tmarkupEditorTextInputMode,\n\t\tmarkupEditorToolShareStyles,\n\t\tmarkupEditorWillStartInteraction,\n\t\tmarkupEditorGridSize,\n\t\tmarkupEditorSnapThreshold,\n\t\tmarkupEditorSnapToContext,\n\t\tannotateGridSize,\n\t\tannotateSnapToContext,\n\t\twillRenderShapePresetToolbar,\n\t\tannotateTools,\n\t\tannotateToolShapes,\n\t\tannotateShapeControls,\n\t\tannotateEnableButtonFlipVertical,\n\t\tannotateEnableSelectImagePreset,\n\t\tannotateEnableDropImagePreset,\n\t\tannotatePresets,\n\t\tannotateWillRenderShapePresetToolbar,\n\t\tannotateWillRenderShapeStyleControls,\n\t\tenableViewTool,\n\t\tenableSelectToolToAddShape,\n\t\tenableTapToAddText,\n\t\tenableAutoSelectMoveTool,\n\t\tenableMoveTool,\n\t\tenableMultiSelect,\n\t\twillRenderShapeControls,\n\t\twillRenderShapeTextControls,\n\t\tbeforeAddShape,\n\t\tbeforeRemoveShape,\n\t\tbeforeDeselectShape,\n\t\tbeforeSelectShape,\n\t\tbeforeUpdateShape,\n\t\t$imageFlipY,\n\t\t$imageFlipX,\n\t\tmapImagePointToScreenPoint,\n\t\tmapScreenPointToImagePoint,\n\t\t$imageRotation,\n\t\trootRect,\n\t\timageAnnotation,\n\t\timageSize,\n\t\timageRotation,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\timageTransforms,\n\t\timageTransformsInterpolated,\n\t\tpresentationRotation,\n\t\t$imageTransformsInterpolated,\n\t\t$imageSize,\n\t\t$rootRect,\n\t\t$imageTransforms,\n\t\tshapeutil_toolActive_binding,\n\t\tmeasure_handler\n\t];\n}\n\nclass Annotate extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$a,\n\t\t\tcreate_fragment$a,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 1,\n\t\t\t\tisActive: 2,\n\t\t\t\tisActiveFraction: 3,\n\t\t\t\tisVisible: 4,\n\t\t\t\tstores: 5,\n\t\t\t\tlocale: 6,\n\t\t\t\tmarkupEditorToolbar: 7,\n\t\t\t\tmarkupEditorToolStyles: 8,\n\t\t\t\tmarkupEditorToolRetainStyles: 9,\n\t\t\t\tmarkupEditorShapeStyleControls: 10,\n\t\t\t\tmarkupEditorToolSelectRadius: 11,\n\t\t\t\tmarkupEditorTextInputMode: 12,\n\t\t\t\tmarkupEditorToolShareStyles: 13,\n\t\t\t\tmarkupEditorWillStartInteraction: 14,\n\t\t\t\tmarkupEditorGridSize: 15,\n\t\t\t\tmarkupEditorSnapThreshold: 16,\n\t\t\t\tmarkupEditorSnapToContext: 17,\n\t\t\t\tannotateGridSize: 18,\n\t\t\t\tannotateSnapToContext: 19,\n\t\t\t\twillRenderShapePresetToolbar: 20,\n\t\t\t\tannotateTools: 21,\n\t\t\t\tannotateToolShapes: 22,\n\t\t\t\tannotateShapeControls: 23,\n\t\t\t\tannotateActiveTool: 0,\n\t\t\t\tannotateEnableButtonFlipVertical: 24,\n\t\t\t\tannotateEnableSelectImagePreset: 25,\n\t\t\t\tannotateEnableDropImagePreset: 26,\n\t\t\t\tannotatePresets: 27,\n\t\t\t\tannotateWillRenderShapePresetToolbar: 28,\n\t\t\t\tannotateWillRenderShapeStyleControls: 29,\n\t\t\t\tenableViewTool: 30,\n\t\t\t\tenableSelectToolToAddShape: 31,\n\t\t\t\tenableTapToAddText: 32,\n\t\t\t\tenableAutoSelectMoveTool: 33,\n\t\t\t\tenableMoveTool: 34,\n\t\t\t\tenableMultiSelect: 35,\n\t\t\t\twillRenderShapeControls: 36,\n\t\t\t\twillRenderShapeTextControls: 37,\n\t\t\t\tbeforeAddShape: 38,\n\t\t\t\tbeforeRemoveShape: 39,\n\t\t\t\tbeforeDeselectShape: 40,\n\t\t\t\tbeforeSelectShape: 41,\n\t\t\t\tbeforeUpdateShape: 42\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget isActiveFraction() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset isActiveFraction(isActiveFraction) {\n\t\tthis.$$set({ isActiveFraction });\n\t\tflush();\n\t}\n\n\tget isVisible() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset isVisible(isVisible) {\n\t\tthis.$$set({ isVisible });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget markupEditorToolbar() {\n\t\treturn this.$$.ctx[7];\n\t}\n\n\tset markupEditorToolbar(markupEditorToolbar) {\n\t\tthis.$$set({ markupEditorToolbar });\n\t\tflush();\n\t}\n\n\tget markupEditorToolStyles() {\n\t\treturn this.$$.ctx[8];\n\t}\n\n\tset markupEditorToolStyles(markupEditorToolStyles) {\n\t\tthis.$$set({ markupEditorToolStyles });\n\t\tflush();\n\t}\n\n\tget markupEditorToolRetainStyles() {\n\t\treturn this.$$.ctx[9];\n\t}\n\n\tset markupEditorToolRetainStyles(markupEditorToolRetainStyles) {\n\t\tthis.$$set({ markupEditorToolRetainStyles });\n\t\tflush();\n\t}\n\n\tget markupEditorShapeStyleControls() {\n\t\treturn this.$$.ctx[10];\n\t}\n\n\tset markupEditorShapeStyleControls(markupEditorShapeStyleControls) {\n\t\tthis.$$set({ markupEditorShapeStyleControls });\n\t\tflush();\n\t}\n\n\tget markupEditorToolSelectRadius() {\n\t\treturn this.$$.ctx[11];\n\t}\n\n\tset markupEditorToolSelectRadius(markupEditorToolSelectRadius) {\n\t\tthis.$$set({ markupEditorToolSelectRadius });\n\t\tflush();\n\t}\n\n\tget markupEditorTextInputMode() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tset markupEditorTextInputMode(markupEditorTextInputMode) {\n\t\tthis.$$set({ markupEditorTextInputMode });\n\t\tflush();\n\t}\n\n\tget markupEditorToolShareStyles() {\n\t\treturn this.$$.ctx[13];\n\t}\n\n\tset markupEditorToolShareStyles(markupEditorToolShareStyles) {\n\t\tthis.$$set({ markupEditorToolShareStyles });\n\t\tflush();\n\t}\n\n\tget markupEditorWillStartInteraction() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tset markupEditorWillStartInteraction(markupEditorWillStartInteraction) {\n\t\tthis.$$set({ markupEditorWillStartInteraction });\n\t\tflush();\n\t}\n\n\tget markupEditorGridSize() {\n\t\treturn this.$$.ctx[15];\n\t}\n\n\tset markupEditorGridSize(markupEditorGridSize) {\n\t\tthis.$$set({ markupEditorGridSize });\n\t\tflush();\n\t}\n\n\tget markupEditorSnapThreshold() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset markupEditorSnapThreshold(markupEditorSnapThreshold) {\n\t\tthis.$$set({ markupEditorSnapThreshold });\n\t\tflush();\n\t}\n\n\tget markupEditorSnapToContext() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset markupEditorSnapToContext(markupEditorSnapToContext) {\n\t\tthis.$$set({ markupEditorSnapToContext });\n\t\tflush();\n\t}\n\n\tget annotateGridSize() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset annotateGridSize(annotateGridSize) {\n\t\tthis.$$set({ annotateGridSize });\n\t\tflush();\n\t}\n\n\tget annotateSnapToContext() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset annotateSnapToContext(annotateSnapToContext) {\n\t\tthis.$$set({ annotateSnapToContext });\n\t\tflush();\n\t}\n\n\tget willRenderShapePresetToolbar() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset willRenderShapePresetToolbar(willRenderShapePresetToolbar) {\n\t\tthis.$$set({ willRenderShapePresetToolbar });\n\t\tflush();\n\t}\n\n\tget annotateTools() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset annotateTools(annotateTools) {\n\t\tthis.$$set({ annotateTools });\n\t\tflush();\n\t}\n\n\tget annotateToolShapes() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tset annotateToolShapes(annotateToolShapes) {\n\t\tthis.$$set({ annotateToolShapes });\n\t\tflush();\n\t}\n\n\tget annotateShapeControls() {\n\t\treturn this.$$.ctx[23];\n\t}\n\n\tset annotateShapeControls(annotateShapeControls) {\n\t\tthis.$$set({ annotateShapeControls });\n\t\tflush();\n\t}\n\n\tget annotateActiveTool() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset annotateActiveTool(annotateActiveTool) {\n\t\tthis.$$set({ annotateActiveTool });\n\t\tflush();\n\t}\n\n\tget annotateEnableButtonFlipVertical() {\n\t\treturn this.$$.ctx[24];\n\t}\n\n\tset annotateEnableButtonFlipVertical(annotateEnableButtonFlipVertical) {\n\t\tthis.$$set({ annotateEnableButtonFlipVertical });\n\t\tflush();\n\t}\n\n\tget annotateEnableSelectImagePreset() {\n\t\treturn this.$$.ctx[25];\n\t}\n\n\tset annotateEnableSelectImagePreset(annotateEnableSelectImagePreset) {\n\t\tthis.$$set({ annotateEnableSelectImagePreset });\n\t\tflush();\n\t}\n\n\tget annotateEnableDropImagePreset() {\n\t\treturn this.$$.ctx[26];\n\t}\n\n\tset annotateEnableDropImagePreset(annotateEnableDropImagePreset) {\n\t\tthis.$$set({ annotateEnableDropImagePreset });\n\t\tflush();\n\t}\n\n\tget annotatePresets() {\n\t\treturn this.$$.ctx[27];\n\t}\n\n\tset annotatePresets(annotatePresets) {\n\t\tthis.$$set({ annotatePresets });\n\t\tflush();\n\t}\n\n\tget annotateWillRenderShapePresetToolbar() {\n\t\treturn this.$$.ctx[28];\n\t}\n\n\tset annotateWillRenderShapePresetToolbar(annotateWillRenderShapePresetToolbar) {\n\t\tthis.$$set({ annotateWillRenderShapePresetToolbar });\n\t\tflush();\n\t}\n\n\tget annotateWillRenderShapeStyleControls() {\n\t\treturn this.$$.ctx[29];\n\t}\n\n\tset annotateWillRenderShapeStyleControls(annotateWillRenderShapeStyleControls) {\n\t\tthis.$$set({ annotateWillRenderShapeStyleControls });\n\t\tflush();\n\t}\n\n\tget enableViewTool() {\n\t\treturn this.$$.ctx[30];\n\t}\n\n\tset enableViewTool(enableViewTool) {\n\t\tthis.$$set({ enableViewTool });\n\t\tflush();\n\t}\n\n\tget enableSelectToolToAddShape() {\n\t\treturn this.$$.ctx[31];\n\t}\n\n\tset enableSelectToolToAddShape(enableSelectToolToAddShape) {\n\t\tthis.$$set({ enableSelectToolToAddShape });\n\t\tflush();\n\t}\n\n\tget enableTapToAddText() {\n\t\treturn this.$$.ctx[32];\n\t}\n\n\tset enableTapToAddText(enableTapToAddText) {\n\t\tthis.$$set({ enableTapToAddText });\n\t\tflush();\n\t}\n\n\tget enableAutoSelectMoveTool() {\n\t\treturn this.$$.ctx[33];\n\t}\n\n\tset enableAutoSelectMoveTool(enableAutoSelectMoveTool) {\n\t\tthis.$$set({ enableAutoSelectMoveTool });\n\t\tflush();\n\t}\n\n\tget enableMoveTool() {\n\t\treturn this.$$.ctx[34];\n\t}\n\n\tset enableMoveTool(enableMoveTool) {\n\t\tthis.$$set({ enableMoveTool });\n\t\tflush();\n\t}\n\n\tget enableMultiSelect() {\n\t\treturn this.$$.ctx[35];\n\t}\n\n\tset enableMultiSelect(enableMultiSelect) {\n\t\tthis.$$set({ enableMultiSelect });\n\t\tflush();\n\t}\n\n\tget willRenderShapeControls() {\n\t\treturn this.$$.ctx[36];\n\t}\n\n\tset willRenderShapeControls(willRenderShapeControls) {\n\t\tthis.$$set({ willRenderShapeControls });\n\t\tflush();\n\t}\n\n\tget willRenderShapeTextControls() {\n\t\treturn this.$$.ctx[37];\n\t}\n\n\tset willRenderShapeTextControls(willRenderShapeTextControls) {\n\t\tthis.$$set({ willRenderShapeTextControls });\n\t\tflush();\n\t}\n\n\tget beforeAddShape() {\n\t\treturn this.$$.ctx[38];\n\t}\n\n\tset beforeAddShape(beforeAddShape) {\n\t\tthis.$$set({ beforeAddShape });\n\t\tflush();\n\t}\n\n\tget beforeRemoveShape() {\n\t\treturn this.$$.ctx[39];\n\t}\n\n\tset beforeRemoveShape(beforeRemoveShape) {\n\t\tthis.$$set({ beforeRemoveShape });\n\t\tflush();\n\t}\n\n\tget beforeDeselectShape() {\n\t\treturn this.$$.ctx[40];\n\t}\n\n\tset beforeDeselectShape(beforeDeselectShape) {\n\t\tthis.$$set({ beforeDeselectShape });\n\t\tflush();\n\t}\n\n\tget beforeSelectShape() {\n\t\treturn this.$$.ctx[41];\n\t}\n\n\tset beforeSelectShape(beforeSelectShape) {\n\t\tthis.$$set({ beforeSelectShape });\n\t\tflush();\n\t}\n\n\tget beforeUpdateShape() {\n\t\treturn this.$$.ctx[42];\n\t}\n\n\tset beforeUpdateShape(beforeUpdateShape) {\n\t\tthis.$$set({ beforeUpdateShape });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_annotate = { util: ['annotate', Annotate] };\n\n/* src/core/ui/plugins/decorate/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$9(ctx) {\n\tlet shapeutil;\n\tlet updating_toolActive;\n\tlet current;\n\n\tfunction shapeutil_toolActive_binding(value) {\n\t\t/*shapeutil_toolActive_binding*/ ctx[52](value);\n\t}\n\n\tlet shapeutil_props = {\n\t\tutilKey: /*name*/ ctx[1],\n\t\tstores: /*stores*/ ctx[5],\n\t\tlocale: /*locale*/ ctx[6],\n\t\tisActive: /*isActive*/ ctx[2],\n\t\tisActiveFraction: /*isActiveFraction*/ ctx[3],\n\t\tisVisible: /*isVisible*/ ctx[4],\n\t\tmapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[44],\n\t\tmapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[43],\n\t\tshapes: /*imageDecoration*/ ctx[46],\n\t\ttoolbar: /*decorateTools*/ ctx[20] || /*markupEditorToolbar*/ ctx[7],\n\t\ttoolShapes: /*decorateToolShapes*/ ctx[21] || /*markupEditorToolStyles*/ ctx[8],\n\t\ttoolRetainStyles: /*markupEditorToolRetainStyles*/ ctx[9],\n\t\tshapeControls: /*decorateShapeControls*/ ctx[22] || /*markupEditorShapeStyleControls*/ ctx[10],\n\t\tshapePresets: /*decoratePresets*/ ctx[26],\n\t\tenableSelectToolToAddShape: /*enableSelectToolToAddShape*/ ctx[29],\n\t\tenableTapToAddText: /*enableTapToAddText*/ ctx[30],\n\t\tenableViewTool: /*enableViewTool*/ ctx[31],\n\t\tenableMoveTool: /*enableMoveTool*/ ctx[32],\n\t\tenableAutoSelectMoveTool: /*enableAutoSelectMoveTool*/ ctx[33],\n\t\tenableMultiSelect: /*enableMultiSelect*/ ctx[34],\n\t\tsnapThreshold: /*markupEditorSnapThreshold*/ ctx[16],\n\t\tgridSize: isNumber(/*decorateGridSize*/ ctx[18])\n\t\t? /*decorateGridSize*/ ctx[18]\n\t\t: /*markupEditorGridSize*/ ctx[15],\n\t\tenableSnapToContext: isBoolean(/*decorateSnapToContext*/ ctx[19])\n\t\t? /*decorateSnapToContext*/ ctx[19]\n\t\t: /*markupEditorSnapToContext*/ ctx[17],\n\t\tenableToolShareStyles: /*markupEditorToolShareStyles*/ ctx[13],\n\t\tenablePresetSelectImage: /*decorateEnableSelectImagePreset*/ ctx[24],\n\t\tenablePresetDropImage: /*decorateEnableDropImagePreset*/ ctx[25],\n\t\tenableButtonFlipVertical: /*decorateEnableButtonFlipVertical*/ ctx[23],\n\t\tparentRect: /*imageCropRect*/ ctx[45],\n\t\ttoolSelectRadius: /*markupEditorToolSelectRadius*/ ctx[11],\n\t\ttextInputMode: /*markupEditorTextInputMode*/ ctx[12],\n\t\twillStartInteraction: /*markupEditorWillStartInteraction*/ ctx[42],\n\t\twillRenderPresetToolbar: /*decorateWillRenderShapePresetToolbar*/ ctx[27] || /*willRenderShapePresetToolbar*/ ctx[14],\n\t\twillRenderShapeStyleControls: /*decorateWillRenderShapeStyleControls*/ ctx[28],\n\t\thooks: {\n\t\t\twillRenderShapeControls: /*willRenderShapeControls*/ ctx[35],\n\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[36],\n\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[37],\n\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[38],\n\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[39],\n\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[40],\n\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[41]\n\t\t}\n\t};\n\n\tif (/*decorateActiveTool*/ ctx[0] !== void 0) {\n\t\tshapeutil_props.toolActive = /*decorateActiveTool*/ ctx[0];\n\t}\n\n\tshapeutil = new ShapeUtil({ props: shapeutil_props });\n\tbinding_callbacks.push(() => bind(shapeutil, 'toolActive', shapeutil_toolActive_binding));\n\tshapeutil.$on(\"measure\", /*measure_handler*/ ctx[53]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapeutil.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapeutil, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapeutil_changes = {};\n\t\t\tif (dirty[0] & /*stores*/ 32) shapeutil_changes.stores = /*stores*/ ctx[5];\n\t\t\tif (dirty[0] & /*locale*/ 64) shapeutil_changes.locale = /*locale*/ ctx[6];\n\t\t\tif (dirty[0] & /*isActive*/ 4) shapeutil_changes.isActive = /*isActive*/ ctx[2];\n\t\t\tif (dirty[0] & /*isActiveFraction*/ 8) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[3];\n\t\t\tif (dirty[0] & /*isVisible*/ 16) shapeutil_changes.isVisible = /*isVisible*/ ctx[4];\n\t\t\tif (dirty[1] & /*mapScreenPointToImagePoint*/ 8192) shapeutil_changes.mapScreenPointToImagePoint = /*mapScreenPointToImagePoint*/ ctx[44];\n\t\t\tif (dirty[1] & /*mapImagePointToScreenPoint*/ 4096) shapeutil_changes.mapImagePointToScreenPoint = /*mapImagePointToScreenPoint*/ ctx[43];\n\t\t\tif (dirty[0] & /*decorateTools, markupEditorToolbar*/ 1048704) shapeutil_changes.toolbar = /*decorateTools*/ ctx[20] || /*markupEditorToolbar*/ ctx[7];\n\t\t\tif (dirty[0] & /*decorateToolShapes, markupEditorToolStyles*/ 2097408) shapeutil_changes.toolShapes = /*decorateToolShapes*/ ctx[21] || /*markupEditorToolStyles*/ ctx[8];\n\t\t\tif (dirty[0] & /*markupEditorToolRetainStyles*/ 512) shapeutil_changes.toolRetainStyles = /*markupEditorToolRetainStyles*/ ctx[9];\n\t\t\tif (dirty[0] & /*decorateShapeControls, markupEditorShapeStyleControls*/ 4195328) shapeutil_changes.shapeControls = /*decorateShapeControls*/ ctx[22] || /*markupEditorShapeStyleControls*/ ctx[10];\n\t\t\tif (dirty[0] & /*decoratePresets*/ 67108864) shapeutil_changes.shapePresets = /*decoratePresets*/ ctx[26];\n\t\t\tif (dirty[0] & /*enableSelectToolToAddShape*/ 536870912) shapeutil_changes.enableSelectToolToAddShape = /*enableSelectToolToAddShape*/ ctx[29];\n\t\t\tif (dirty[0] & /*enableTapToAddText*/ 1073741824) shapeutil_changes.enableTapToAddText = /*enableTapToAddText*/ ctx[30];\n\t\t\tif (dirty[1] & /*enableViewTool*/ 1) shapeutil_changes.enableViewTool = /*enableViewTool*/ ctx[31];\n\t\t\tif (dirty[1] & /*enableMoveTool*/ 2) shapeutil_changes.enableMoveTool = /*enableMoveTool*/ ctx[32];\n\t\t\tif (dirty[1] & /*enableAutoSelectMoveTool*/ 4) shapeutil_changes.enableAutoSelectMoveTool = /*enableAutoSelectMoveTool*/ ctx[33];\n\t\t\tif (dirty[1] & /*enableMultiSelect*/ 8) shapeutil_changes.enableMultiSelect = /*enableMultiSelect*/ ctx[34];\n\t\t\tif (dirty[0] & /*markupEditorSnapThreshold*/ 65536) shapeutil_changes.snapThreshold = /*markupEditorSnapThreshold*/ ctx[16];\n\n\t\t\tif (dirty[0] & /*decorateGridSize, markupEditorGridSize*/ 294912) shapeutil_changes.gridSize = isNumber(/*decorateGridSize*/ ctx[18])\n\t\t\t? /*decorateGridSize*/ ctx[18]\n\t\t\t: /*markupEditorGridSize*/ ctx[15];\n\n\t\t\tif (dirty[0] & /*decorateSnapToContext, markupEditorSnapToContext*/ 655360) shapeutil_changes.enableSnapToContext = isBoolean(/*decorateSnapToContext*/ ctx[19])\n\t\t\t? /*decorateSnapToContext*/ ctx[19]\n\t\t\t: /*markupEditorSnapToContext*/ ctx[17];\n\n\t\t\tif (dirty[0] & /*markupEditorToolShareStyles*/ 8192) shapeutil_changes.enableToolShareStyles = /*markupEditorToolShareStyles*/ ctx[13];\n\t\t\tif (dirty[0] & /*decorateEnableSelectImagePreset*/ 16777216) shapeutil_changes.enablePresetSelectImage = /*decorateEnableSelectImagePreset*/ ctx[24];\n\t\t\tif (dirty[0] & /*decorateEnableDropImagePreset*/ 33554432) shapeutil_changes.enablePresetDropImage = /*decorateEnableDropImagePreset*/ ctx[25];\n\t\t\tif (dirty[0] & /*decorateEnableButtonFlipVertical*/ 8388608) shapeutil_changes.enableButtonFlipVertical = /*decorateEnableButtonFlipVertical*/ ctx[23];\n\t\t\tif (dirty[0] & /*markupEditorToolSelectRadius*/ 2048) shapeutil_changes.toolSelectRadius = /*markupEditorToolSelectRadius*/ ctx[11];\n\t\t\tif (dirty[0] & /*markupEditorTextInputMode*/ 4096) shapeutil_changes.textInputMode = /*markupEditorTextInputMode*/ ctx[12];\n\t\t\tif (dirty[1] & /*markupEditorWillStartInteraction*/ 2048) shapeutil_changes.willStartInteraction = /*markupEditorWillStartInteraction*/ ctx[42];\n\t\t\tif (dirty[0] & /*decorateWillRenderShapePresetToolbar, willRenderShapePresetToolbar*/ 134234112) shapeutil_changes.willRenderPresetToolbar = /*decorateWillRenderShapePresetToolbar*/ ctx[27] || /*willRenderShapePresetToolbar*/ ctx[14];\n\t\t\tif (dirty[0] & /*decorateWillRenderShapeStyleControls*/ 268435456) shapeutil_changes.willRenderShapeStyleControls = /*decorateWillRenderShapeStyleControls*/ ctx[28];\n\n\t\t\tif (dirty[1] & /*willRenderShapeControls, willRenderShapeTextControls, beforeAddShape, beforeRemoveShape, beforeDeselectShape, beforeSelectShape, beforeUpdateShape*/ 2032) shapeutil_changes.hooks = {\n\t\t\t\twillRenderShapeControls: /*willRenderShapeControls*/ ctx[35],\n\t\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[36],\n\t\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[37],\n\t\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[38],\n\t\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[39],\n\t\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[40],\n\t\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[41]\n\t\t\t};\n\n\t\t\tif (!updating_toolActive && dirty[0] & /*decorateActiveTool*/ 1) {\n\t\t\t\tupdating_toolActive = true;\n\t\t\t\tshapeutil_changes.toolActive = /*decorateActiveTool*/ ctx[0];\n\t\t\t\tadd_flush_callback(() => updating_toolActive = false);\n\t\t\t}\n\n\t\t\tshapeutil.$set(shapeutil_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapeutil.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapeutil.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapeutil, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$9($$self, $$props, $$invalidate) {\n\tlet presentationZoom;\n\tlet mapScreenPointToImagePoint;\n\tlet mapImagePointToScreenPoint;\n\tlet $imageSelectionRectPresentation;\n\tlet $imageTransformsInterpolated;\n\tconst name = 'decorate';\n\tlet { isActive } = $$props;\n\tlet { isActiveFraction } = $$props;\n\tlet { isVisible } = $$props;\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { markupEditorToolbar = undefined } = $$props;\n\tlet { markupEditorToolStyles = undefined } = $$props;\n\tlet { markupEditorToolRetainStyles = undefined } = $$props;\n\tlet { markupEditorShapeStyleControls = undefined } = $$props;\n\tlet { markupEditorToolSelectRadius = undefined } = $$props;\n\tlet { markupEditorTextInputMode = undefined } = $$props;\n\tlet { markupEditorToolShareStyles = undefined } = $$props;\n\tlet { willRenderShapePresetToolbar = undefined } = $$props;\n\tlet { markupEditorGridSize = undefined } = $$props;\n\tlet { markupEditorSnapThreshold = undefined } = $$props;\n\tlet { markupEditorSnapToContext = true } = $$props;\n\tlet { decorateGridSize = undefined } = $$props;\n\tlet { decorateSnapToContext = undefined } = $$props;\n\tlet { decorateTools = undefined } = $$props;\n\tlet { decorateToolShapes = undefined } = $$props;\n\tlet { decorateShapeControls = undefined } = $$props;\n\tlet { decorateActiveTool = undefined } = $$props;\n\tlet { decorateEnableButtonFlipVertical = false } = $$props;\n\tlet { decorateEnableSelectImagePreset = false } = $$props;\n\tlet { decorateEnableDropImagePreset = true } = $$props;\n\tlet { decoratePresets = [] } = $$props;\n\tlet { decorateWillRenderShapePresetToolbar = undefined } = $$props;\n\tlet { decorateWillRenderShapeStyleControls = undefined } = $$props;\n\tlet { enableSelectToolToAddShape = undefined } = $$props;\n\tlet { enableTapToAddText = undefined } = $$props;\n\tlet { enableViewTool = undefined } = $$props;\n\tlet { enableMoveTool = undefined } = $$props;\n\tlet { enableAutoSelectMoveTool = undefined } = $$props;\n\tlet { enableMultiSelect = undefined } = $$props;\n\tlet { willRenderShapeControls = undefined } = $$props;\n\tlet { willRenderShapeTextControls = undefined } = $$props;\n\tlet { beforeAddShape = undefined } = $$props;\n\tlet { beforeRemoveShape = undefined } = $$props;\n\tlet { beforeDeselectShape = undefined } = $$props;\n\tlet { beforeSelectShape = undefined } = $$props;\n\tlet { beforeUpdateShape = undefined } = $$props;\n\tlet { markupEditorWillStartInteraction = undefined } = $$props;\n\tconst { imageCropRect, imageDecoration, imageSelectionRectPresentation, imageTransformsInterpolated } = stores;\n\tcomponent_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(50, $imageSelectionRectPresentation = value));\n\tcomponent_subscribe($$self, imageTransformsInterpolated, value => $$invalidate(51, $imageTransformsInterpolated = value));\n\n\tfunction shapeutil_toolActive_binding(value) {\n\t\tdecorateActiveTool = value;\n\t\t$$invalidate(0, decorateActiveTool);\n\t}\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$invalidate(2, isActive = $$props.isActive);\n\t\tif ('isActiveFraction' in $$props) $$invalidate(3, isActiveFraction = $$props.isActiveFraction);\n\t\tif ('isVisible' in $$props) $$invalidate(4, isVisible = $$props.isVisible);\n\t\tif ('stores' in $$props) $$invalidate(5, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(6, locale = $$props.locale);\n\t\tif ('markupEditorToolbar' in $$props) $$invalidate(7, markupEditorToolbar = $$props.markupEditorToolbar);\n\t\tif ('markupEditorToolStyles' in $$props) $$invalidate(8, markupEditorToolStyles = $$props.markupEditorToolStyles);\n\t\tif ('markupEditorToolRetainStyles' in $$props) $$invalidate(9, markupEditorToolRetainStyles = $$props.markupEditorToolRetainStyles);\n\t\tif ('markupEditorShapeStyleControls' in $$props) $$invalidate(10, markupEditorShapeStyleControls = $$props.markupEditorShapeStyleControls);\n\t\tif ('markupEditorToolSelectRadius' in $$props) $$invalidate(11, markupEditorToolSelectRadius = $$props.markupEditorToolSelectRadius);\n\t\tif ('markupEditorTextInputMode' in $$props) $$invalidate(12, markupEditorTextInputMode = $$props.markupEditorTextInputMode);\n\t\tif ('markupEditorToolShareStyles' in $$props) $$invalidate(13, markupEditorToolShareStyles = $$props.markupEditorToolShareStyles);\n\t\tif ('willRenderShapePresetToolbar' in $$props) $$invalidate(14, willRenderShapePresetToolbar = $$props.willRenderShapePresetToolbar);\n\t\tif ('markupEditorGridSize' in $$props) $$invalidate(15, markupEditorGridSize = $$props.markupEditorGridSize);\n\t\tif ('markupEditorSnapThreshold' in $$props) $$invalidate(16, markupEditorSnapThreshold = $$props.markupEditorSnapThreshold);\n\t\tif ('markupEditorSnapToContext' in $$props) $$invalidate(17, markupEditorSnapToContext = $$props.markupEditorSnapToContext);\n\t\tif ('decorateGridSize' in $$props) $$invalidate(18, decorateGridSize = $$props.decorateGridSize);\n\t\tif ('decorateSnapToContext' in $$props) $$invalidate(19, decorateSnapToContext = $$props.decorateSnapToContext);\n\t\tif ('decorateTools' in $$props) $$invalidate(20, decorateTools = $$props.decorateTools);\n\t\tif ('decorateToolShapes' in $$props) $$invalidate(21, decorateToolShapes = $$props.decorateToolShapes);\n\t\tif ('decorateShapeControls' in $$props) $$invalidate(22, decorateShapeControls = $$props.decorateShapeControls);\n\t\tif ('decorateActiveTool' in $$props) $$invalidate(0, decorateActiveTool = $$props.decorateActiveTool);\n\t\tif ('decorateEnableButtonFlipVertical' in $$props) $$invalidate(23, decorateEnableButtonFlipVertical = $$props.decorateEnableButtonFlipVertical);\n\t\tif ('decorateEnableSelectImagePreset' in $$props) $$invalidate(24, decorateEnableSelectImagePreset = $$props.decorateEnableSelectImagePreset);\n\t\tif ('decorateEnableDropImagePreset' in $$props) $$invalidate(25, decorateEnableDropImagePreset = $$props.decorateEnableDropImagePreset);\n\t\tif ('decoratePresets' in $$props) $$invalidate(26, decoratePresets = $$props.decoratePresets);\n\t\tif ('decorateWillRenderShapePresetToolbar' in $$props) $$invalidate(27, decorateWillRenderShapePresetToolbar = $$props.decorateWillRenderShapePresetToolbar);\n\t\tif ('decorateWillRenderShapeStyleControls' in $$props) $$invalidate(28, decorateWillRenderShapeStyleControls = $$props.decorateWillRenderShapeStyleControls);\n\t\tif ('enableSelectToolToAddShape' in $$props) $$invalidate(29, enableSelectToolToAddShape = $$props.enableSelectToolToAddShape);\n\t\tif ('enableTapToAddText' in $$props) $$invalidate(30, enableTapToAddText = $$props.enableTapToAddText);\n\t\tif ('enableViewTool' in $$props) $$invalidate(31, enableViewTool = $$props.enableViewTool);\n\t\tif ('enableMoveTool' in $$props) $$invalidate(32, enableMoveTool = $$props.enableMoveTool);\n\t\tif ('enableAutoSelectMoveTool' in $$props) $$invalidate(33, enableAutoSelectMoveTool = $$props.enableAutoSelectMoveTool);\n\t\tif ('enableMultiSelect' in $$props) $$invalidate(34, enableMultiSelect = $$props.enableMultiSelect);\n\t\tif ('willRenderShapeControls' in $$props) $$invalidate(35, willRenderShapeControls = $$props.willRenderShapeControls);\n\t\tif ('willRenderShapeTextControls' in $$props) $$invalidate(36, willRenderShapeTextControls = $$props.willRenderShapeTextControls);\n\t\tif ('beforeAddShape' in $$props) $$invalidate(37, beforeAddShape = $$props.beforeAddShape);\n\t\tif ('beforeRemoveShape' in $$props) $$invalidate(38, beforeRemoveShape = $$props.beforeRemoveShape);\n\t\tif ('beforeDeselectShape' in $$props) $$invalidate(39, beforeDeselectShape = $$props.beforeDeselectShape);\n\t\tif ('beforeSelectShape' in $$props) $$invalidate(40, beforeSelectShape = $$props.beforeSelectShape);\n\t\tif ('beforeUpdateShape' in $$props) $$invalidate(41, beforeUpdateShape = $$props.beforeUpdateShape);\n\t\tif ('markupEditorWillStartInteraction' in $$props) $$invalidate(42, markupEditorWillStartInteraction = $$props.markupEditorWillStartInteraction);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[1] & /*$imageTransformsInterpolated*/ 1048576) {\n\t\t\t$$invalidate(49, presentationZoom = $imageTransformsInterpolated\n\t\t\t? $imageTransformsInterpolated.scale\n\t\t\t: 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageSelectionRectPresentation, presentationZoom*/ 786432) {\n\t\t\t$$invalidate(44, mapScreenPointToImagePoint = screenPoint => {\n\t\t\t\tconst mappedPoint = vectorClone(screenPoint);\n\t\t\t\tmappedPoint.x -= $imageSelectionRectPresentation.x;\n\t\t\t\tmappedPoint.y -= $imageSelectionRectPresentation.y;\n\t\t\t\tmappedPoint.x /= presentationZoom;\n\t\t\t\tmappedPoint.y /= presentationZoom;\n\t\t\t\treturn mappedPoint;\n\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*presentationZoom, $imageSelectionRectPresentation*/ 786432) {\n\t\t\t$$invalidate(43, mapImagePointToScreenPoint = imagePoint => {\n\t\t\t\tconst mappedPoint = vectorClone(imagePoint);\n\t\t\t\tmappedPoint.x *= presentationZoom;\n\t\t\t\tmappedPoint.y *= presentationZoom;\n\t\t\t\tmappedPoint.x += $imageSelectionRectPresentation.x;\n\t\t\t\tmappedPoint.y += $imageSelectionRectPresentation.y;\n\t\t\t\treturn mappedPoint;\n\t\t\t});\n\t\t}\n\t};\n\n\treturn [\n\t\tdecorateActiveTool,\n\t\tname,\n\t\tisActive,\n\t\tisActiveFraction,\n\t\tisVisible,\n\t\tstores,\n\t\tlocale,\n\t\tmarkupEditorToolbar,\n\t\tmarkupEditorToolStyles,\n\t\tmarkupEditorToolRetainStyles,\n\t\tmarkupEditorShapeStyleControls,\n\t\tmarkupEditorToolSelectRadius,\n\t\tmarkupEditorTextInputMode,\n\t\tmarkupEditorToolShareStyles,\n\t\twillRenderShapePresetToolbar,\n\t\tmarkupEditorGridSize,\n\t\tmarkupEditorSnapThreshold,\n\t\tmarkupEditorSnapToContext,\n\t\tdecorateGridSize,\n\t\tdecorateSnapToContext,\n\t\tdecorateTools,\n\t\tdecorateToolShapes,\n\t\tdecorateShapeControls,\n\t\tdecorateEnableButtonFlipVertical,\n\t\tdecorateEnableSelectImagePreset,\n\t\tdecorateEnableDropImagePreset,\n\t\tdecoratePresets,\n\t\tdecorateWillRenderShapePresetToolbar,\n\t\tdecorateWillRenderShapeStyleControls,\n\t\tenableSelectToolToAddShape,\n\t\tenableTapToAddText,\n\t\tenableViewTool,\n\t\tenableMoveTool,\n\t\tenableAutoSelectMoveTool,\n\t\tenableMultiSelect,\n\t\twillRenderShapeControls,\n\t\twillRenderShapeTextControls,\n\t\tbeforeAddShape,\n\t\tbeforeRemoveShape,\n\t\tbeforeDeselectShape,\n\t\tbeforeSelectShape,\n\t\tbeforeUpdateShape,\n\t\tmarkupEditorWillStartInteraction,\n\t\tmapImagePointToScreenPoint,\n\t\tmapScreenPointToImagePoint,\n\t\timageCropRect,\n\t\timageDecoration,\n\t\timageSelectionRectPresentation,\n\t\timageTransformsInterpolated,\n\t\tpresentationZoom,\n\t\t$imageSelectionRectPresentation,\n\t\t$imageTransformsInterpolated,\n\t\tshapeutil_toolActive_binding,\n\t\tmeasure_handler\n\t];\n}\n\nclass Decorate extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$9,\n\t\t\tcreate_fragment$9,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 1,\n\t\t\t\tisActive: 2,\n\t\t\t\tisActiveFraction: 3,\n\t\t\t\tisVisible: 4,\n\t\t\t\tstores: 5,\n\t\t\t\tlocale: 6,\n\t\t\t\tmarkupEditorToolbar: 7,\n\t\t\t\tmarkupEditorToolStyles: 8,\n\t\t\t\tmarkupEditorToolRetainStyles: 9,\n\t\t\t\tmarkupEditorShapeStyleControls: 10,\n\t\t\t\tmarkupEditorToolSelectRadius: 11,\n\t\t\t\tmarkupEditorTextInputMode: 12,\n\t\t\t\tmarkupEditorToolShareStyles: 13,\n\t\t\t\twillRenderShapePresetToolbar: 14,\n\t\t\t\tmarkupEditorGridSize: 15,\n\t\t\t\tmarkupEditorSnapThreshold: 16,\n\t\t\t\tmarkupEditorSnapToContext: 17,\n\t\t\t\tdecorateGridSize: 18,\n\t\t\t\tdecorateSnapToContext: 19,\n\t\t\t\tdecorateTools: 20,\n\t\t\t\tdecorateToolShapes: 21,\n\t\t\t\tdecorateShapeControls: 22,\n\t\t\t\tdecorateActiveTool: 0,\n\t\t\t\tdecorateEnableButtonFlipVertical: 23,\n\t\t\t\tdecorateEnableSelectImagePreset: 24,\n\t\t\t\tdecorateEnableDropImagePreset: 25,\n\t\t\t\tdecoratePresets: 26,\n\t\t\t\tdecorateWillRenderShapePresetToolbar: 27,\n\t\t\t\tdecorateWillRenderShapeStyleControls: 28,\n\t\t\t\tenableSelectToolToAddShape: 29,\n\t\t\t\tenableTapToAddText: 30,\n\t\t\t\tenableViewTool: 31,\n\t\t\t\tenableMoveTool: 32,\n\t\t\t\tenableAutoSelectMoveTool: 33,\n\t\t\t\tenableMultiSelect: 34,\n\t\t\t\twillRenderShapeControls: 35,\n\t\t\t\twillRenderShapeTextControls: 36,\n\t\t\t\tbeforeAddShape: 37,\n\t\t\t\tbeforeRemoveShape: 38,\n\t\t\t\tbeforeDeselectShape: 39,\n\t\t\t\tbeforeSelectShape: 40,\n\t\t\t\tbeforeUpdateShape: 41,\n\t\t\t\tmarkupEditorWillStartInteraction: 42\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget isActiveFraction() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset isActiveFraction(isActiveFraction) {\n\t\tthis.$$set({ isActiveFraction });\n\t\tflush();\n\t}\n\n\tget isVisible() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset isVisible(isVisible) {\n\t\tthis.$$set({ isVisible });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget markupEditorToolbar() {\n\t\treturn this.$$.ctx[7];\n\t}\n\n\tset markupEditorToolbar(markupEditorToolbar) {\n\t\tthis.$$set({ markupEditorToolbar });\n\t\tflush();\n\t}\n\n\tget markupEditorToolStyles() {\n\t\treturn this.$$.ctx[8];\n\t}\n\n\tset markupEditorToolStyles(markupEditorToolStyles) {\n\t\tthis.$$set({ markupEditorToolStyles });\n\t\tflush();\n\t}\n\n\tget markupEditorToolRetainStyles() {\n\t\treturn this.$$.ctx[9];\n\t}\n\n\tset markupEditorToolRetainStyles(markupEditorToolRetainStyles) {\n\t\tthis.$$set({ markupEditorToolRetainStyles });\n\t\tflush();\n\t}\n\n\tget markupEditorShapeStyleControls() {\n\t\treturn this.$$.ctx[10];\n\t}\n\n\tset markupEditorShapeStyleControls(markupEditorShapeStyleControls) {\n\t\tthis.$$set({ markupEditorShapeStyleControls });\n\t\tflush();\n\t}\n\n\tget markupEditorToolSelectRadius() {\n\t\treturn this.$$.ctx[11];\n\t}\n\n\tset markupEditorToolSelectRadius(markupEditorToolSelectRadius) {\n\t\tthis.$$set({ markupEditorToolSelectRadius });\n\t\tflush();\n\t}\n\n\tget markupEditorTextInputMode() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tset markupEditorTextInputMode(markupEditorTextInputMode) {\n\t\tthis.$$set({ markupEditorTextInputMode });\n\t\tflush();\n\t}\n\n\tget markupEditorToolShareStyles() {\n\t\treturn this.$$.ctx[13];\n\t}\n\n\tset markupEditorToolShareStyles(markupEditorToolShareStyles) {\n\t\tthis.$$set({ markupEditorToolShareStyles });\n\t\tflush();\n\t}\n\n\tget willRenderShapePresetToolbar() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tset willRenderShapePresetToolbar(willRenderShapePresetToolbar) {\n\t\tthis.$$set({ willRenderShapePresetToolbar });\n\t\tflush();\n\t}\n\n\tget markupEditorGridSize() {\n\t\treturn this.$$.ctx[15];\n\t}\n\n\tset markupEditorGridSize(markupEditorGridSize) {\n\t\tthis.$$set({ markupEditorGridSize });\n\t\tflush();\n\t}\n\n\tget markupEditorSnapThreshold() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset markupEditorSnapThreshold(markupEditorSnapThreshold) {\n\t\tthis.$$set({ markupEditorSnapThreshold });\n\t\tflush();\n\t}\n\n\tget markupEditorSnapToContext() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset markupEditorSnapToContext(markupEditorSnapToContext) {\n\t\tthis.$$set({ markupEditorSnapToContext });\n\t\tflush();\n\t}\n\n\tget decorateGridSize() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset decorateGridSize(decorateGridSize) {\n\t\tthis.$$set({ decorateGridSize });\n\t\tflush();\n\t}\n\n\tget decorateSnapToContext() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset decorateSnapToContext(decorateSnapToContext) {\n\t\tthis.$$set({ decorateSnapToContext });\n\t\tflush();\n\t}\n\n\tget decorateTools() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset decorateTools(decorateTools) {\n\t\tthis.$$set({ decorateTools });\n\t\tflush();\n\t}\n\n\tget decorateToolShapes() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset decorateToolShapes(decorateToolShapes) {\n\t\tthis.$$set({ decorateToolShapes });\n\t\tflush();\n\t}\n\n\tget decorateShapeControls() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tset decorateShapeControls(decorateShapeControls) {\n\t\tthis.$$set({ decorateShapeControls });\n\t\tflush();\n\t}\n\n\tget decorateActiveTool() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset decorateActiveTool(decorateActiveTool) {\n\t\tthis.$$set({ decorateActiveTool });\n\t\tflush();\n\t}\n\n\tget decorateEnableButtonFlipVertical() {\n\t\treturn this.$$.ctx[23];\n\t}\n\n\tset decorateEnableButtonFlipVertical(decorateEnableButtonFlipVertical) {\n\t\tthis.$$set({ decorateEnableButtonFlipVertical });\n\t\tflush();\n\t}\n\n\tget decorateEnableSelectImagePreset() {\n\t\treturn this.$$.ctx[24];\n\t}\n\n\tset decorateEnableSelectImagePreset(decorateEnableSelectImagePreset) {\n\t\tthis.$$set({ decorateEnableSelectImagePreset });\n\t\tflush();\n\t}\n\n\tget decorateEnableDropImagePreset() {\n\t\treturn this.$$.ctx[25];\n\t}\n\n\tset decorateEnableDropImagePreset(decorateEnableDropImagePreset) {\n\t\tthis.$$set({ decorateEnableDropImagePreset });\n\t\tflush();\n\t}\n\n\tget decoratePresets() {\n\t\treturn this.$$.ctx[26];\n\t}\n\n\tset decoratePresets(decoratePresets) {\n\t\tthis.$$set({ decoratePresets });\n\t\tflush();\n\t}\n\n\tget decorateWillRenderShapePresetToolbar() {\n\t\treturn this.$$.ctx[27];\n\t}\n\n\tset decorateWillRenderShapePresetToolbar(decorateWillRenderShapePresetToolbar) {\n\t\tthis.$$set({ decorateWillRenderShapePresetToolbar });\n\t\tflush();\n\t}\n\n\tget decorateWillRenderShapeStyleControls() {\n\t\treturn this.$$.ctx[28];\n\t}\n\n\tset decorateWillRenderShapeStyleControls(decorateWillRenderShapeStyleControls) {\n\t\tthis.$$set({ decorateWillRenderShapeStyleControls });\n\t\tflush();\n\t}\n\n\tget enableSelectToolToAddShape() {\n\t\treturn this.$$.ctx[29];\n\t}\n\n\tset enableSelectToolToAddShape(enableSelectToolToAddShape) {\n\t\tthis.$$set({ enableSelectToolToAddShape });\n\t\tflush();\n\t}\n\n\tget enableTapToAddText() {\n\t\treturn this.$$.ctx[30];\n\t}\n\n\tset enableTapToAddText(enableTapToAddText) {\n\t\tthis.$$set({ enableTapToAddText });\n\t\tflush();\n\t}\n\n\tget enableViewTool() {\n\t\treturn this.$$.ctx[31];\n\t}\n\n\tset enableViewTool(enableViewTool) {\n\t\tthis.$$set({ enableViewTool });\n\t\tflush();\n\t}\n\n\tget enableMoveTool() {\n\t\treturn this.$$.ctx[32];\n\t}\n\n\tset enableMoveTool(enableMoveTool) {\n\t\tthis.$$set({ enableMoveTool });\n\t\tflush();\n\t}\n\n\tget enableAutoSelectMoveTool() {\n\t\treturn this.$$.ctx[33];\n\t}\n\n\tset enableAutoSelectMoveTool(enableAutoSelectMoveTool) {\n\t\tthis.$$set({ enableAutoSelectMoveTool });\n\t\tflush();\n\t}\n\n\tget enableMultiSelect() {\n\t\treturn this.$$.ctx[34];\n\t}\n\n\tset enableMultiSelect(enableMultiSelect) {\n\t\tthis.$$set({ enableMultiSelect });\n\t\tflush();\n\t}\n\n\tget willRenderShapeControls() {\n\t\treturn this.$$.ctx[35];\n\t}\n\n\tset willRenderShapeControls(willRenderShapeControls) {\n\t\tthis.$$set({ willRenderShapeControls });\n\t\tflush();\n\t}\n\n\tget willRenderShapeTextControls() {\n\t\treturn this.$$.ctx[36];\n\t}\n\n\tset willRenderShapeTextControls(willRenderShapeTextControls) {\n\t\tthis.$$set({ willRenderShapeTextControls });\n\t\tflush();\n\t}\n\n\tget beforeAddShape() {\n\t\treturn this.$$.ctx[37];\n\t}\n\n\tset beforeAddShape(beforeAddShape) {\n\t\tthis.$$set({ beforeAddShape });\n\t\tflush();\n\t}\n\n\tget beforeRemoveShape() {\n\t\treturn this.$$.ctx[38];\n\t}\n\n\tset beforeRemoveShape(beforeRemoveShape) {\n\t\tthis.$$set({ beforeRemoveShape });\n\t\tflush();\n\t}\n\n\tget beforeDeselectShape() {\n\t\treturn this.$$.ctx[39];\n\t}\n\n\tset beforeDeselectShape(beforeDeselectShape) {\n\t\tthis.$$set({ beforeDeselectShape });\n\t\tflush();\n\t}\n\n\tget beforeSelectShape() {\n\t\treturn this.$$.ctx[40];\n\t}\n\n\tset beforeSelectShape(beforeSelectShape) {\n\t\tthis.$$set({ beforeSelectShape });\n\t\tflush();\n\t}\n\n\tget beforeUpdateShape() {\n\t\treturn this.$$.ctx[41];\n\t}\n\n\tset beforeUpdateShape(beforeUpdateShape) {\n\t\tthis.$$set({ beforeUpdateShape });\n\t\tflush();\n\t}\n\n\tget markupEditorWillStartInteraction() {\n\t\treturn this.$$.ctx[42];\n\t}\n\n\tset markupEditorWillStartInteraction(markupEditorWillStartInteraction) {\n\t\tthis.$$set({ markupEditorWillStartInteraction });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_decorate = { util: ['decorate', Decorate] };\n\n/* src/core/ui/plugins/sticker/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$8(ctx) {\n\tlet shapeutil;\n\tlet current;\n\n\tshapeutil = new ShapeUtil({\n\t\t\tprops: {\n\t\t\t\tstores: /*stores*/ ctx[3],\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tisActive: /*isActive*/ ctx[0],\n\t\t\t\tisActiveFraction: /*isActiveFraction*/ ctx[1],\n\t\t\t\tisVisible: /*isVisible*/ ctx[2],\n\t\t\t\tmapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[26],\n\t\t\t\tmapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[25],\n\t\t\t\tutilKey: 'sticker',\n\t\t\t\tshapePresets: /*stickers*/ ctx[5],\n\t\t\t\tshapes: /*stickerStickToImage*/ ctx[6]\n\t\t\t\t? /*imageAnnotation*/ ctx[35]\n\t\t\t\t: /*imageDecoration*/ ctx[36],\n\t\t\t\ttoolActive: 'preset',\n\t\t\t\timageFlipX: /*stickerStickToImage*/ ctx[6]\n\t\t\t\t? /*$imageFlipX*/ ctx[24]\n\t\t\t\t: false,\n\t\t\t\timageFlipY: /*stickerStickToImage*/ ctx[6]\n\t\t\t\t? /*$imageFlipY*/ ctx[23]\n\t\t\t\t: false,\n\t\t\t\timageRotation: /*stickerStickToImage*/ ctx[6]\n\t\t\t\t? /*$imageRotation*/ ctx[31]\n\t\t\t\t: 0,\n\t\t\t\tparentRect: /*stickerStickToImage*/ ctx[6]\n\t\t\t\t? /*imageSize*/ ctx[37]\n\t\t\t\t: /*imageCropRect*/ ctx[33],\n\t\t\t\tsnapThreshold: /*snapThreshold*/ ctx[29],\n\t\t\t\tgridSize: /*gridSize*/ ctx[28],\n\t\t\t\tenableMultiSelect: /*enableMultiSelect*/ ctx[12],\n\t\t\t\tenableSnapToContext: /*enableSnapToContext*/ ctx[27],\n\t\t\t\tenablePresetDropImage: /*stickerEnableDropImagePreset*/ ctx[7],\n\t\t\t\tenablePresetSelectImage: /*enablePresetSelectImage*/ ctx[30],\n\t\t\t\tenableButtonFlipVertical: /*stickersEnableButtonFlipVertical*/ ctx[10] || /*stickerEnableButtonFlipVertical*/ ctx[8],\n\t\t\t\ttoolSelectRadius: /*markupEditorToolSelectRadius*/ ctx[15],\n\t\t\t\twillStartInteraction: /*markupEditorWillStartInteraction*/ ctx[22],\n\t\t\t\twillRenderPresetToolbar: /*stickersWillRenderShapePresetToolbar*/ ctx[11] || /*stickerWillRenderShapePresetToolbar*/ ctx[9] || /*willRenderShapePresetToolbar*/ ctx[16],\n\t\t\t\thooks: {\n\t\t\t\t\twillRenderShapeControls: /*willRenderShapeControls*/ ctx[13],\n\t\t\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[14],\n\t\t\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[17],\n\t\t\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[18],\n\t\t\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[19],\n\t\t\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[20],\n\t\t\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[21]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\tshapeutil.$on(\"measure\", /*measure_handler*/ ctx[61]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapeutil.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapeutil, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapeutil_changes = {};\n\t\t\tif (dirty[0] & /*stores*/ 8) shapeutil_changes.stores = /*stores*/ ctx[3];\n\t\t\tif (dirty[0] & /*locale*/ 16) shapeutil_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty[0] & /*isActive*/ 1) shapeutil_changes.isActive = /*isActive*/ ctx[0];\n\t\t\tif (dirty[0] & /*isActiveFraction*/ 2) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[1];\n\t\t\tif (dirty[0] & /*isVisible*/ 4) shapeutil_changes.isVisible = /*isVisible*/ ctx[2];\n\t\t\tif (dirty[0] & /*mapScreenPointToImagePoint*/ 67108864) shapeutil_changes.mapScreenPointToImagePoint = /*mapScreenPointToImagePoint*/ ctx[26];\n\t\t\tif (dirty[0] & /*mapImagePointToScreenPoint*/ 33554432) shapeutil_changes.mapImagePointToScreenPoint = /*mapImagePointToScreenPoint*/ ctx[25];\n\t\t\tif (dirty[0] & /*stickers*/ 32) shapeutil_changes.shapePresets = /*stickers*/ ctx[5];\n\n\t\t\tif (dirty[0] & /*stickerStickToImage*/ 64) shapeutil_changes.shapes = /*stickerStickToImage*/ ctx[6]\n\t\t\t? /*imageAnnotation*/ ctx[35]\n\t\t\t: /*imageDecoration*/ ctx[36];\n\n\t\t\tif (dirty[0] & /*stickerStickToImage, $imageFlipX*/ 16777280) shapeutil_changes.imageFlipX = /*stickerStickToImage*/ ctx[6]\n\t\t\t? /*$imageFlipX*/ ctx[24]\n\t\t\t: false;\n\n\t\t\tif (dirty[0] & /*stickerStickToImage, $imageFlipY*/ 8388672) shapeutil_changes.imageFlipY = /*stickerStickToImage*/ ctx[6]\n\t\t\t? /*$imageFlipY*/ ctx[23]\n\t\t\t: false;\n\n\t\t\tif (dirty[0] & /*stickerStickToImage*/ 64 | dirty[1] & /*$imageRotation*/ 1) shapeutil_changes.imageRotation = /*stickerStickToImage*/ ctx[6]\n\t\t\t? /*$imageRotation*/ ctx[31]\n\t\t\t: 0;\n\n\t\t\tif (dirty[0] & /*stickerStickToImage*/ 64) shapeutil_changes.parentRect = /*stickerStickToImage*/ ctx[6]\n\t\t\t? /*imageSize*/ ctx[37]\n\t\t\t: /*imageCropRect*/ ctx[33];\n\n\t\t\tif (dirty[0] & /*snapThreshold*/ 536870912) shapeutil_changes.snapThreshold = /*snapThreshold*/ ctx[29];\n\t\t\tif (dirty[0] & /*gridSize*/ 268435456) shapeutil_changes.gridSize = /*gridSize*/ ctx[28];\n\t\t\tif (dirty[0] & /*enableMultiSelect*/ 4096) shapeutil_changes.enableMultiSelect = /*enableMultiSelect*/ ctx[12];\n\t\t\tif (dirty[0] & /*enableSnapToContext*/ 134217728) shapeutil_changes.enableSnapToContext = /*enableSnapToContext*/ ctx[27];\n\t\t\tif (dirty[0] & /*stickerEnableDropImagePreset*/ 128) shapeutil_changes.enablePresetDropImage = /*stickerEnableDropImagePreset*/ ctx[7];\n\t\t\tif (dirty[0] & /*enablePresetSelectImage*/ 1073741824) shapeutil_changes.enablePresetSelectImage = /*enablePresetSelectImage*/ ctx[30];\n\t\t\tif (dirty[0] & /*stickersEnableButtonFlipVertical, stickerEnableButtonFlipVertical*/ 1280) shapeutil_changes.enableButtonFlipVertical = /*stickersEnableButtonFlipVertical*/ ctx[10] || /*stickerEnableButtonFlipVertical*/ ctx[8];\n\t\t\tif (dirty[0] & /*markupEditorToolSelectRadius*/ 32768) shapeutil_changes.toolSelectRadius = /*markupEditorToolSelectRadius*/ ctx[15];\n\t\t\tif (dirty[0] & /*markupEditorWillStartInteraction*/ 4194304) shapeutil_changes.willStartInteraction = /*markupEditorWillStartInteraction*/ ctx[22];\n\t\t\tif (dirty[0] & /*stickersWillRenderShapePresetToolbar, stickerWillRenderShapePresetToolbar, willRenderShapePresetToolbar*/ 68096) shapeutil_changes.willRenderPresetToolbar = /*stickersWillRenderShapePresetToolbar*/ ctx[11] || /*stickerWillRenderShapePresetToolbar*/ ctx[9] || /*willRenderShapePresetToolbar*/ ctx[16];\n\n\t\t\tif (dirty[0] & /*willRenderShapeControls, willRenderShapeTextControls, beforeAddShape, beforeRemoveShape, beforeDeselectShape, beforeSelectShape, beforeUpdateShape*/ 4087808) shapeutil_changes.hooks = {\n\t\t\t\twillRenderShapeControls: /*willRenderShapeControls*/ ctx[13],\n\t\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[14],\n\t\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[17],\n\t\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[18],\n\t\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[19],\n\t\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[20],\n\t\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[21]\n\t\t\t};\n\n\t\t\tshapeutil.$set(shapeutil_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapeutil.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapeutil.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapeutil, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$8($$self, $$props, $$invalidate) {\n\tlet presentationZoom;\n\tlet presentationRotation;\n\tlet enablePresetSelectImage;\n\tlet snapThreshold;\n\tlet gridSize;\n\tlet enableSnapToContext;\n\tlet mapScreenPointToImagePoint;\n\tlet mapImagePointToScreenPoint;\n\tlet $imageSelectionRectPresentation;\n\tlet $imageFlipY;\n\tlet $imageFlipX;\n\tlet $imageTransformsInterpolated;\n\tlet $imageSize;\n\tlet $rootRect;\n\tlet $imageTransforms;\n\tlet $imageRotation;\n\tconst name = 'sticker';\n\tlet { isActive } = $$props;\n\tlet { isActiveFraction } = $$props;\n\tlet { isVisible } = $$props;\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { stickers = [] } = $$props;\n\tlet { stickerForceEnable = false } = $$props;\n\tlet { stickerStickToImage = false } = $$props;\n\tlet { stickerEnableSelectImagePreset = true } = $$props;\n\tlet { stickerEnableDropImagePreset = true } = $$props;\n\tlet { stickerEnableButtonFlipVertical = false } = $$props;\n\tlet { stickerWillRenderShapePresetToolbar = undefined } = $$props;\n\tlet { stickerEnableSelectImage = true } = $$props;\n\tlet { stickersEnableButtonFlipVertical = false } = $$props;\n\tlet { stickersWillRenderShapePresetToolbar = undefined } = $$props;\n\tlet { markupEditorGridSize = 0 } = $$props;\n\tlet { markupEditorSnapThreshold = 0 } = $$props;\n\tlet { markupEditorSnapToContext = false } = $$props;\n\tlet { enableMultiSelect = undefined } = $$props;\n\tlet { annotateGridSize = undefined } = $$props;\n\tlet { annotateSnapToContext = undefined } = $$props;\n\tlet { decorateGridSize = undefined } = $$props;\n\tlet { decorateSnapToContext = undefined } = $$props;\n\tlet { willRenderShapeControls = undefined } = $$props;\n\tlet { willRenderShapeTextControls = undefined } = $$props;\n\tlet { markupEditorToolSelectRadius = undefined } = $$props;\n\tlet { willRenderShapePresetToolbar = undefined } = $$props;\n\tlet { beforeAddShape = undefined } = $$props;\n\tlet { beforeRemoveShape = undefined } = $$props;\n\tlet { beforeDeselectShape = undefined } = $$props;\n\tlet { beforeSelectShape = undefined } = $$props;\n\tlet { beforeUpdateShape = undefined } = $$props;\n\tlet { markupEditorWillStartInteraction = undefined } = $$props;\n\n\t// connect filter choice to stores\n\tconst { rootRect, imageCropRect, imageSelectionRectPresentation, imageAnnotation, imageDecoration, imageSize, imageTransforms, imageTransformsInterpolated, imageRotation, imageFlipX, imageFlipY } = stores;\n\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(59, $rootRect = value));\n\tcomponent_subscribe($$self, imageSelectionRectPresentation, value => $$invalidate(56, $imageSelectionRectPresentation = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(58, $imageSize = value));\n\tcomponent_subscribe($$self, imageTransforms, value => $$invalidate(60, $imageTransforms = value));\n\tcomponent_subscribe($$self, imageTransformsInterpolated, value => $$invalidate(57, $imageTransformsInterpolated = value));\n\tcomponent_subscribe($$self, imageRotation, value => $$invalidate(31, $imageRotation = value));\n\tcomponent_subscribe($$self, imageFlipX, value => $$invalidate(24, $imageFlipX = value));\n\tcomponent_subscribe($$self, imageFlipY, value => $$invalidate(23, $imageFlipY = value));\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$invalidate(0, isActive = $$props.isActive);\n\t\tif ('isActiveFraction' in $$props) $$invalidate(1, isActiveFraction = $$props.isActiveFraction);\n\t\tif ('isVisible' in $$props) $$invalidate(2, isVisible = $$props.isVisible);\n\t\tif ('stores' in $$props) $$invalidate(3, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(4, locale = $$props.locale);\n\t\tif ('stickers' in $$props) $$invalidate(5, stickers = $$props.stickers);\n\t\tif ('stickerForceEnable' in $$props) $$invalidate(44, stickerForceEnable = $$props.stickerForceEnable);\n\t\tif ('stickerStickToImage' in $$props) $$invalidate(6, stickerStickToImage = $$props.stickerStickToImage);\n\t\tif ('stickerEnableSelectImagePreset' in $$props) $$invalidate(45, stickerEnableSelectImagePreset = $$props.stickerEnableSelectImagePreset);\n\t\tif ('stickerEnableDropImagePreset' in $$props) $$invalidate(7, stickerEnableDropImagePreset = $$props.stickerEnableDropImagePreset);\n\t\tif ('stickerEnableButtonFlipVertical' in $$props) $$invalidate(8, stickerEnableButtonFlipVertical = $$props.stickerEnableButtonFlipVertical);\n\t\tif ('stickerWillRenderShapePresetToolbar' in $$props) $$invalidate(9, stickerWillRenderShapePresetToolbar = $$props.stickerWillRenderShapePresetToolbar);\n\t\tif ('stickerEnableSelectImage' in $$props) $$invalidate(46, stickerEnableSelectImage = $$props.stickerEnableSelectImage);\n\t\tif ('stickersEnableButtonFlipVertical' in $$props) $$invalidate(10, stickersEnableButtonFlipVertical = $$props.stickersEnableButtonFlipVertical);\n\t\tif ('stickersWillRenderShapePresetToolbar' in $$props) $$invalidate(11, stickersWillRenderShapePresetToolbar = $$props.stickersWillRenderShapePresetToolbar);\n\t\tif ('markupEditorGridSize' in $$props) $$invalidate(47, markupEditorGridSize = $$props.markupEditorGridSize);\n\t\tif ('markupEditorSnapThreshold' in $$props) $$invalidate(48, markupEditorSnapThreshold = $$props.markupEditorSnapThreshold);\n\t\tif ('markupEditorSnapToContext' in $$props) $$invalidate(49, markupEditorSnapToContext = $$props.markupEditorSnapToContext);\n\t\tif ('enableMultiSelect' in $$props) $$invalidate(12, enableMultiSelect = $$props.enableMultiSelect);\n\t\tif ('annotateGridSize' in $$props) $$invalidate(50, annotateGridSize = $$props.annotateGridSize);\n\t\tif ('annotateSnapToContext' in $$props) $$invalidate(51, annotateSnapToContext = $$props.annotateSnapToContext);\n\t\tif ('decorateGridSize' in $$props) $$invalidate(52, decorateGridSize = $$props.decorateGridSize);\n\t\tif ('decorateSnapToContext' in $$props) $$invalidate(53, decorateSnapToContext = $$props.decorateSnapToContext);\n\t\tif ('willRenderShapeControls' in $$props) $$invalidate(13, willRenderShapeControls = $$props.willRenderShapeControls);\n\t\tif ('willRenderShapeTextControls' in $$props) $$invalidate(14, willRenderShapeTextControls = $$props.willRenderShapeTextControls);\n\t\tif ('markupEditorToolSelectRadius' in $$props) $$invalidate(15, markupEditorToolSelectRadius = $$props.markupEditorToolSelectRadius);\n\t\tif ('willRenderShapePresetToolbar' in $$props) $$invalidate(16, willRenderShapePresetToolbar = $$props.willRenderShapePresetToolbar);\n\t\tif ('beforeAddShape' in $$props) $$invalidate(17, beforeAddShape = $$props.beforeAddShape);\n\t\tif ('beforeRemoveShape' in $$props) $$invalidate(18, beforeRemoveShape = $$props.beforeRemoveShape);\n\t\tif ('beforeDeselectShape' in $$props) $$invalidate(19, beforeDeselectShape = $$props.beforeDeselectShape);\n\t\tif ('beforeSelectShape' in $$props) $$invalidate(20, beforeSelectShape = $$props.beforeSelectShape);\n\t\tif ('beforeUpdateShape' in $$props) $$invalidate(21, beforeUpdateShape = $$props.beforeUpdateShape);\n\t\tif ('markupEditorWillStartInteraction' in $$props) $$invalidate(22, markupEditorWillStartInteraction = $$props.markupEditorWillStartInteraction);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[1] & /*$imageTransformsInterpolated*/ 67108864) {\n\t\t\t$$invalidate(54, presentationZoom = $imageTransformsInterpolated\n\t\t\t? $imageTransformsInterpolated.scale\n\t\t\t: 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$imageTransforms*/ 536870912) {\n\t\t\t$$invalidate(55, presentationRotation = $imageTransforms ? $imageTransforms.rotation.z : 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*stickerEnableSelectImagePreset, stickerEnableSelectImage*/ 49152) {\n\t\t\t$$invalidate(30, enablePresetSelectImage = stickerEnableSelectImagePreset === false\n\t\t\t? false\n\t\t\t: stickerEnableSelectImage);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*markupEditorSnapThreshold*/ 131072) {\n\t\t\t// props\n\t\t\t$$invalidate(29, snapThreshold = markupEditorSnapThreshold);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*stickerStickToImage*/ 64 | $$self.$$.dirty[1] & /*annotateGridSize, markupEditorGridSize, decorateGridSize*/ 2686976) {\n\t\t\t$$invalidate(28, gridSize = stickerStickToImage\n\t\t\t? isNumber(annotateGridSize)\n\t\t\t\t? annotateGridSize\n\t\t\t\t: markupEditorGridSize\n\t\t\t: isNumber(decorateGridSize)\n\t\t\t\t? decorateGridSize\n\t\t\t\t: markupEditorGridSize);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*stickerStickToImage*/ 64 | $$self.$$.dirty[1] & /*annotateSnapToContext, markupEditorSnapToContext, decorateSnapToContext*/ 5505024) {\n\t\t\t$$invalidate(27, enableSnapToContext = stickerStickToImage\n\t\t\t? isBoolean(annotateSnapToContext)\n\t\t\t\t? annotateSnapToContext\n\t\t\t\t: markupEditorSnapToContext\n\t\t\t: isBoolean(decorateSnapToContext)\n\t\t\t\t? decorateSnapToContext\n\t\t\t\t: markupEditorSnapToContext);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*stickerStickToImage, $imageFlipX, $imageFlipY*/ 25165888 | $$self.$$.dirty[1] & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation, $imageSelectionRectPresentation, presentationZoom*/ 528482304) {\n\t\t\t//\n\t\t\t// Mapping coordinates\n\t\t\t//\n\t\t\t$$invalidate(26, mapScreenPointToImagePoint = stickerStickToImage\n\t\t\t? point => _mapScreenPointToImagePoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY)\n\t\t\t: point => {\n\t\t\t\t\tconst mappedPoint = vectorClone(point);\n\t\t\t\t\tmappedPoint.x -= $imageSelectionRectPresentation.x;\n\t\t\t\t\tmappedPoint.y -= $imageSelectionRectPresentation.y;\n\t\t\t\t\tmappedPoint.x /= presentationZoom;\n\t\t\t\t\tmappedPoint.y /= presentationZoom;\n\t\t\t\t\treturn mappedPoint;\n\t\t\t\t});\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*stickerStickToImage, $imageFlipX, $imageFlipY*/ 25165888 | $$self.$$.dirty[1] & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation, presentationZoom, $imageSelectionRectPresentation*/ 528482304) {\n\t\t\t$$invalidate(25, mapImagePointToScreenPoint = stickerStickToImage\n\t\t\t? point => _mapImagePointToScreenPoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY)\n\t\t\t: point => {\n\t\t\t\t\tconst mappedPoint = vectorClone(point);\n\t\t\t\t\tmappedPoint.x *= presentationZoom;\n\t\t\t\t\tmappedPoint.y *= presentationZoom;\n\t\t\t\t\tmappedPoint.x += $imageSelectionRectPresentation.x;\n\t\t\t\t\tmappedPoint.y += $imageSelectionRectPresentation.y;\n\t\t\t\t\treturn mappedPoint;\n\t\t\t\t});\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tisActiveFraction,\n\t\tisVisible,\n\t\tstores,\n\t\tlocale,\n\t\tstickers,\n\t\tstickerStickToImage,\n\t\tstickerEnableDropImagePreset,\n\t\tstickerEnableButtonFlipVertical,\n\t\tstickerWillRenderShapePresetToolbar,\n\t\tstickersEnableButtonFlipVertical,\n\t\tstickersWillRenderShapePresetToolbar,\n\t\tenableMultiSelect,\n\t\twillRenderShapeControls,\n\t\twillRenderShapeTextControls,\n\t\tmarkupEditorToolSelectRadius,\n\t\twillRenderShapePresetToolbar,\n\t\tbeforeAddShape,\n\t\tbeforeRemoveShape,\n\t\tbeforeDeselectShape,\n\t\tbeforeSelectShape,\n\t\tbeforeUpdateShape,\n\t\tmarkupEditorWillStartInteraction,\n\t\t$imageFlipY,\n\t\t$imageFlipX,\n\t\tmapImagePointToScreenPoint,\n\t\tmapScreenPointToImagePoint,\n\t\tenableSnapToContext,\n\t\tgridSize,\n\t\tsnapThreshold,\n\t\tenablePresetSelectImage,\n\t\t$imageRotation,\n\t\trootRect,\n\t\timageCropRect,\n\t\timageSelectionRectPresentation,\n\t\timageAnnotation,\n\t\timageDecoration,\n\t\timageSize,\n\t\timageTransforms,\n\t\timageTransformsInterpolated,\n\t\timageRotation,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\tname,\n\t\tstickerForceEnable,\n\t\tstickerEnableSelectImagePreset,\n\t\tstickerEnableSelectImage,\n\t\tmarkupEditorGridSize,\n\t\tmarkupEditorSnapThreshold,\n\t\tmarkupEditorSnapToContext,\n\t\tannotateGridSize,\n\t\tannotateSnapToContext,\n\t\tdecorateGridSize,\n\t\tdecorateSnapToContext,\n\t\tpresentationZoom,\n\t\tpresentationRotation,\n\t\t$imageSelectionRectPresentation,\n\t\t$imageTransformsInterpolated,\n\t\t$imageSize,\n\t\t$rootRect,\n\t\t$imageTransforms,\n\t\tmeasure_handler\n\t];\n}\n\nclass Sticker extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$8,\n\t\t\tcreate_fragment$8,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 43,\n\t\t\t\tisActive: 0,\n\t\t\t\tisActiveFraction: 1,\n\t\t\t\tisVisible: 2,\n\t\t\t\tstores: 3,\n\t\t\t\tlocale: 4,\n\t\t\t\tstickers: 5,\n\t\t\t\tstickerForceEnable: 44,\n\t\t\t\tstickerStickToImage: 6,\n\t\t\t\tstickerEnableSelectImagePreset: 45,\n\t\t\t\tstickerEnableDropImagePreset: 7,\n\t\t\t\tstickerEnableButtonFlipVertical: 8,\n\t\t\t\tstickerWillRenderShapePresetToolbar: 9,\n\t\t\t\tstickerEnableSelectImage: 46,\n\t\t\t\tstickersEnableButtonFlipVertical: 10,\n\t\t\t\tstickersWillRenderShapePresetToolbar: 11,\n\t\t\t\tmarkupEditorGridSize: 47,\n\t\t\t\tmarkupEditorSnapThreshold: 48,\n\t\t\t\tmarkupEditorSnapToContext: 49,\n\t\t\t\tenableMultiSelect: 12,\n\t\t\t\tannotateGridSize: 50,\n\t\t\t\tannotateSnapToContext: 51,\n\t\t\t\tdecorateGridSize: 52,\n\t\t\t\tdecorateSnapToContext: 53,\n\t\t\t\twillRenderShapeControls: 13,\n\t\t\t\twillRenderShapeTextControls: 14,\n\t\t\t\tmarkupEditorToolSelectRadius: 15,\n\t\t\t\twillRenderShapePresetToolbar: 16,\n\t\t\t\tbeforeAddShape: 17,\n\t\t\t\tbeforeRemoveShape: 18,\n\t\t\t\tbeforeDeselectShape: 19,\n\t\t\t\tbeforeSelectShape: 20,\n\t\t\t\tbeforeUpdateShape: 21,\n\t\t\t\tmarkupEditorWillStartInteraction: 22\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[43];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget isActiveFraction() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset isActiveFraction(isActiveFraction) {\n\t\tthis.$$set({ isActiveFraction });\n\t\tflush();\n\t}\n\n\tget isVisible() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset isVisible(isVisible) {\n\t\tthis.$$set({ isVisible });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget stickers() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset stickers(stickers) {\n\t\tthis.$$set({ stickers });\n\t\tflush();\n\t}\n\n\tget stickerForceEnable() {\n\t\treturn this.$$.ctx[44];\n\t}\n\n\tset stickerForceEnable(stickerForceEnable) {\n\t\tthis.$$set({ stickerForceEnable });\n\t\tflush();\n\t}\n\n\tget stickerStickToImage() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset stickerStickToImage(stickerStickToImage) {\n\t\tthis.$$set({ stickerStickToImage });\n\t\tflush();\n\t}\n\n\tget stickerEnableSelectImagePreset() {\n\t\treturn this.$$.ctx[45];\n\t}\n\n\tset stickerEnableSelectImagePreset(stickerEnableSelectImagePreset) {\n\t\tthis.$$set({ stickerEnableSelectImagePreset });\n\t\tflush();\n\t}\n\n\tget stickerEnableDropImagePreset() {\n\t\treturn this.$$.ctx[7];\n\t}\n\n\tset stickerEnableDropImagePreset(stickerEnableDropImagePreset) {\n\t\tthis.$$set({ stickerEnableDropImagePreset });\n\t\tflush();\n\t}\n\n\tget stickerEnableButtonFlipVertical() {\n\t\treturn this.$$.ctx[8];\n\t}\n\n\tset stickerEnableButtonFlipVertical(stickerEnableButtonFlipVertical) {\n\t\tthis.$$set({ stickerEnableButtonFlipVertical });\n\t\tflush();\n\t}\n\n\tget stickerWillRenderShapePresetToolbar() {\n\t\treturn this.$$.ctx[9];\n\t}\n\n\tset stickerWillRenderShapePresetToolbar(stickerWillRenderShapePresetToolbar) {\n\t\tthis.$$set({ stickerWillRenderShapePresetToolbar });\n\t\tflush();\n\t}\n\n\tget stickerEnableSelectImage() {\n\t\treturn this.$$.ctx[46];\n\t}\n\n\tset stickerEnableSelectImage(stickerEnableSelectImage) {\n\t\tthis.$$set({ stickerEnableSelectImage });\n\t\tflush();\n\t}\n\n\tget stickersEnableButtonFlipVertical() {\n\t\treturn this.$$.ctx[10];\n\t}\n\n\tset stickersEnableButtonFlipVertical(stickersEnableButtonFlipVertical) {\n\t\tthis.$$set({ stickersEnableButtonFlipVertical });\n\t\tflush();\n\t}\n\n\tget stickersWillRenderShapePresetToolbar() {\n\t\treturn this.$$.ctx[11];\n\t}\n\n\tset stickersWillRenderShapePresetToolbar(stickersWillRenderShapePresetToolbar) {\n\t\tthis.$$set({ stickersWillRenderShapePresetToolbar });\n\t\tflush();\n\t}\n\n\tget markupEditorGridSize() {\n\t\treturn this.$$.ctx[47];\n\t}\n\n\tset markupEditorGridSize(markupEditorGridSize) {\n\t\tthis.$$set({ markupEditorGridSize });\n\t\tflush();\n\t}\n\n\tget markupEditorSnapThreshold() {\n\t\treturn this.$$.ctx[48];\n\t}\n\n\tset markupEditorSnapThreshold(markupEditorSnapThreshold) {\n\t\tthis.$$set({ markupEditorSnapThreshold });\n\t\tflush();\n\t}\n\n\tget markupEditorSnapToContext() {\n\t\treturn this.$$.ctx[49];\n\t}\n\n\tset markupEditorSnapToContext(markupEditorSnapToContext) {\n\t\tthis.$$set({ markupEditorSnapToContext });\n\t\tflush();\n\t}\n\n\tget enableMultiSelect() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tset enableMultiSelect(enableMultiSelect) {\n\t\tthis.$$set({ enableMultiSelect });\n\t\tflush();\n\t}\n\n\tget annotateGridSize() {\n\t\treturn this.$$.ctx[50];\n\t}\n\n\tset annotateGridSize(annotateGridSize) {\n\t\tthis.$$set({ annotateGridSize });\n\t\tflush();\n\t}\n\n\tget annotateSnapToContext() {\n\t\treturn this.$$.ctx[51];\n\t}\n\n\tset annotateSnapToContext(annotateSnapToContext) {\n\t\tthis.$$set({ annotateSnapToContext });\n\t\tflush();\n\t}\n\n\tget decorateGridSize() {\n\t\treturn this.$$.ctx[52];\n\t}\n\n\tset decorateGridSize(decorateGridSize) {\n\t\tthis.$$set({ decorateGridSize });\n\t\tflush();\n\t}\n\n\tget decorateSnapToContext() {\n\t\treturn this.$$.ctx[53];\n\t}\n\n\tset decorateSnapToContext(decorateSnapToContext) {\n\t\tthis.$$set({ decorateSnapToContext });\n\t\tflush();\n\t}\n\n\tget willRenderShapeControls() {\n\t\treturn this.$$.ctx[13];\n\t}\n\n\tset willRenderShapeControls(willRenderShapeControls) {\n\t\tthis.$$set({ willRenderShapeControls });\n\t\tflush();\n\t}\n\n\tget willRenderShapeTextControls() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tset willRenderShapeTextControls(willRenderShapeTextControls) {\n\t\tthis.$$set({ willRenderShapeTextControls });\n\t\tflush();\n\t}\n\n\tget markupEditorToolSelectRadius() {\n\t\treturn this.$$.ctx[15];\n\t}\n\n\tset markupEditorToolSelectRadius(markupEditorToolSelectRadius) {\n\t\tthis.$$set({ markupEditorToolSelectRadius });\n\t\tflush();\n\t}\n\n\tget willRenderShapePresetToolbar() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset willRenderShapePresetToolbar(willRenderShapePresetToolbar) {\n\t\tthis.$$set({ willRenderShapePresetToolbar });\n\t\tflush();\n\t}\n\n\tget beforeAddShape() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset beforeAddShape(beforeAddShape) {\n\t\tthis.$$set({ beforeAddShape });\n\t\tflush();\n\t}\n\n\tget beforeRemoveShape() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset beforeRemoveShape(beforeRemoveShape) {\n\t\tthis.$$set({ beforeRemoveShape });\n\t\tflush();\n\t}\n\n\tget beforeDeselectShape() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset beforeDeselectShape(beforeDeselectShape) {\n\t\tthis.$$set({ beforeDeselectShape });\n\t\tflush();\n\t}\n\n\tget beforeSelectShape() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset beforeSelectShape(beforeSelectShape) {\n\t\tthis.$$set({ beforeSelectShape });\n\t\tflush();\n\t}\n\n\tget beforeUpdateShape() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset beforeUpdateShape(beforeUpdateShape) {\n\t\tthis.$$set({ beforeUpdateShape });\n\t\tflush();\n\t}\n\n\tget markupEditorWillStartInteraction() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tset markupEditorWillStartInteraction(markupEditorWillStartInteraction) {\n\t\tthis.$$set({ markupEditorWillStartInteraction });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_sticker = {\n    util: [\n        'sticker',\n        Sticker,\n        ({ stickers, stickerEnableSelectImage, stickerEnableSelectImagePreset, stickerEnableDropImagePreset, stickerForceEnable, }) => (stickers && stickers.length) ||\n            stickerEnableSelectImage ||\n            stickerEnableSelectImagePreset ||\n            stickerEnableDropImagePreset ||\n            stickerForceEnable,\n    ],\n};\n\n/* src/core/ui/plugins/frame/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_else_block$1(ctx) {\n\tlet html_tag;\n\tlet raw_value = (/*getOptionThumb*/ ctx[14](/*option*/ ctx[36].value) || '') + \"\";\n\tlet html_anchor;\n\n\treturn {\n\t\tc() {\n\t\t\thtml_tag = new HtmlTag(false);\n\t\t\thtml_anchor = empty();\n\t\t\thtml_tag.a = html_anchor;\n\t\t},\n\t\tm(target, anchor) {\n\t\t\thtml_tag.m(raw_value, target, anchor);\n\t\t\tinsert(target, html_anchor, anchor);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 32 && raw_value !== (raw_value = (/*getOptionThumb*/ ctx[14](/*option*/ ctx[36].value) || '') + \"\")) html_tag.p(raw_value);\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(html_anchor);\n\t\t\t\thtml_tag.d();\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (182:20) {#if isDynamicTreeThumb(option.value)}\nfunction create_if_block$1(ctx) {\n\tlet dynamiccomponenttree;\n\tlet current;\n\n\tdynamiccomponenttree = new DynamicComponentTree_1({\n\t\t\tprops: {\n\t\t\t\titems: /*getThumbTree*/ ctx[16](/*option*/ ctx[36].value)\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(dynamiccomponenttree, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty[1] & /*option*/ 32) dynamiccomponenttree_changes.items = /*getThumbTree*/ ctx[16](/*option*/ ctx[36].value);\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(dynamiccomponenttree, detaching);\n\t\t}\n\t};\n}\n\n// (181:16) \nfunction create_option_slot$1(ctx) {\n\tlet div;\n\tlet show_if;\n\tlet current_block_type_index;\n\tlet if_block;\n\tlet t0;\n\tlet span;\n\n\tlet t1_value = (isFunction(/*option*/ ctx[36].label)\n\t? /*option*/ ctx[36].label(/*locale*/ ctx[1])\n\t: /*option*/ ctx[36].label) + \"\";\n\n\tlet t1;\n\tlet current;\n\tconst if_block_creators = [create_if_block$1, create_else_block$1];\n\tconst if_blocks = [];\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (dirty[1] & /*option*/ 32) show_if = null;\n\t\tif (show_if == null) show_if = !!/*isDynamicTreeThumb*/ ctx[15](/*option*/ ctx[36].value);\n\t\tif (show_if) return 0;\n\t\treturn 1;\n\t}\n\n\tcurrent_block_type_index = select_block_type(ctx, [-1, -1]);\n\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif_block.c();\n\t\t\tt0 = space();\n\t\t\tspan = element(\"span\");\n\t\t\tt1 = text(t1_value);\n\t\t\tattr(div, \"slot\", \"option\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif_blocks[current_block_type_index].m(div, null);\n\t\t\tappend(div, t0);\n\t\t\tappend(div, span);\n\t\t\tappend(span, t1);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tlet previous_block_index = current_block_type_index;\n\t\t\tcurrent_block_type_index = select_block_type(ctx, dirty);\n\n\t\t\tif (current_block_type_index === previous_block_index) {\n\t\t\t\tif_blocks[current_block_type_index].p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tgroup_outros();\n\n\t\t\t\ttransition_out(if_blocks[previous_block_index], 1, 1, () => {\n\t\t\t\t\tif_blocks[previous_block_index] = null;\n\t\t\t\t});\n\n\t\t\t\tcheck_outros();\n\t\t\t\tif_block = if_blocks[current_block_type_index];\n\n\t\t\t\tif (!if_block) {\n\t\t\t\t\tif_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);\n\t\t\t\t\tif_block.c();\n\t\t\t\t} else {\n\t\t\t\t\tif_block.p(ctx, dirty);\n\t\t\t\t}\n\n\t\t\t\ttransition_in(if_block, 1);\n\t\t\t\tif_block.m(div, t0);\n\t\t\t}\n\n\t\t\tif ((!current || dirty[0] & /*locale*/ 2 | dirty[1] & /*option*/ 32) && t1_value !== (t1_value = (isFunction(/*option*/ ctx[36].label)\n\t\t\t? /*option*/ ctx[36].label(/*locale*/ ctx[1])\n\t\t\t: /*option*/ ctx[36].label) + \"\")) set_data(t1, t1_value);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(if_block);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(if_block);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif_blocks[current_block_type_index].d();\n\t\t}\n\t};\n}\n\n// (172:8) <Scrollable elasticity={scrollElasticity}>\nfunction create_default_slot$3(ctx) {\n\tlet radiogroup;\n\tlet current;\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[1],\n\t\t\t\tclass: \"PinturaControlList\",\n\t\t\t\tlayout: \"row\",\n\t\t\t\toptions: /*frameOptions*/ ctx[2],\n\t\t\t\tselectedIndex: /*selectedFrameIndex*/ ctx[6],\n\t\t\t\tonchange: /*handleChangeFrame*/ ctx[12],\n\t\t\t\t$$slots: {\n\t\t\t\t\toption: [\n\t\t\t\t\t\tcreate_option_slot$1,\n\t\t\t\t\t\t({ option }) => ({ 36: option }),\n\t\t\t\t\t\t({ option }) => [0, option ? 32 : 0]\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radiogroup, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 2) radiogroup_changes.locale = /*locale*/ ctx[1];\n\t\t\tif (dirty[0] & /*frameOptions*/ 4) radiogroup_changes.options = /*frameOptions*/ ctx[2];\n\t\t\tif (dirty[0] & /*selectedFrameIndex*/ 64) radiogroup_changes.selectedIndex = /*selectedFrameIndex*/ ctx[6];\n\n\t\t\tif (dirty[0] & /*locale*/ 2 | dirty[1] & /*$$scope, option*/ 96) {\n\t\t\t\tradiogroup_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radiogroup, detaching);\n\t\t}\n\t};\n}\n\n// (163:4) \nfunction create_footer_slot$2(ctx) {\n\tlet div;\n\tlet shapestyleeditor;\n\tlet t;\n\tlet scrollable;\n\tlet current;\n\n\tshapestyleeditor = new ShapeStyleEditor({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[1],\n\t\t\t\tclass: \"PinturaControlPanels\",\n\t\t\t\tshapeProps: /*$imageFrame*/ ctx[4],\n\t\t\t\tonchange: /*handleUpdateSelectedFrameShape*/ ctx[13],\n\t\t\t\tcontrols: /*markupEditorShapeStyleControls*/ ctx[3],\n\t\t\t\tscrollElasticity: /*computedScrollElasticity*/ ctx[7]\n\t\t\t}\n\t\t});\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\telasticity: /*scrollElasticity*/ ctx[10],\n\t\t\t\t$$slots: { default: [create_default_slot$3] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(shapestyleeditor.$$.fragment);\n\t\t\tt = space();\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t\tattr(div, \"slot\", \"footer\");\n\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[5]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(shapestyleeditor, div, null);\n\t\t\tappend(div, t);\n\t\t\tmount_component(scrollable, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapestyleeditor_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 2) shapestyleeditor_changes.locale = /*locale*/ ctx[1];\n\t\t\tif (dirty[0] & /*$imageFrame*/ 16) shapestyleeditor_changes.shapeProps = /*$imageFrame*/ ctx[4];\n\t\t\tif (dirty[0] & /*markupEditorShapeStyleControls*/ 8) shapestyleeditor_changes.controls = /*markupEditorShapeStyleControls*/ ctx[3];\n\t\t\tif (dirty[0] & /*computedScrollElasticity*/ 128) shapestyleeditor_changes.scrollElasticity = /*computedScrollElasticity*/ ctx[7];\n\t\t\tshapestyleeditor.$set(shapestyleeditor_changes);\n\t\t\tconst scrollable_changes = {};\n\n\t\t\tif (dirty[0] & /*locale, frameOptions, selectedFrameIndex*/ 70 | dirty[1] & /*$$scope*/ 64) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\n\t\t\tif (dirty[0] & /*styleFooterTransform*/ 32) {\n\t\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[5]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapestyleeditor.$$.fragment, local);\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapestyleeditor.$$.fragment, local);\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(shapestyleeditor);\n\t\t\tdestroy_component(scrollable);\n\t\t}\n\t};\n}\n\nfunction create_fragment$7(ctx) {\n\tlet util;\n\tlet current;\n\n\tutil = new Util({\n\t\t\tprops: {\n\t\t\t\t$$slots: { footer: [create_footer_slot$2] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tutil.$on(\"measure\", /*measure_handler*/ ctx[25]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(util.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(util, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst util_changes = {};\n\n\t\t\tif (dirty[0] & /*styleFooterTransform, locale, frameOptions, selectedFrameIndex, $imageFrame, markupEditorShapeStyleControls, computedScrollElasticity*/ 254 | dirty[1] & /*$$scope*/ 64) {\n\t\t\t\tutil_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tutil.$set(util_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(util.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(util.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(util, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$7($$self, $$props, $$invalidate) {\n\tlet computedScrollElasticity;\n\tlet selectedFrameIndex;\n\tlet styleFooterTransform;\n\tlet $footerOffset;\n\n\tlet $isActive,\n\t\t$$unsubscribe_isActive = noop,\n\t\t$$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(22, $isActive = $$value)), isActive);\n\n\tlet $animation;\n\tlet $imageFrame;\n\tlet $elasticityMultiplier;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActive());\n\tconst name = 'frame';\n\tlet { isActive } = $$props;\n\t$$subscribe_isActive();\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { frameStyles = {} } = $$props;\n\tlet { frameOptions = [] } = $$props;\n\tlet { markupEditorShapeStyleControls = undefined } = $$props;\n\n\t//\n\t// context\n\t//\n\tconst elasticityMultiplier = getContext('elasticityMultiplier');\n\n\tcomponent_subscribe($$self, elasticityMultiplier, value => $$invalidate(24, $elasticityMultiplier = value));\n\n\t// connect filter choice to stores\n\tconst { history, animation, scrollElasticity, imageFrame, allowPan, allowZoom, allowZoomControls, allowPlayPause } = stores;\n\n\tcomponent_subscribe($$self, animation, value => $$invalidate(23, $animation = value));\n\tcomponent_subscribe($$self, imageFrame, value => $$invalidate(4, $imageFrame = value));\n\n\t// default frame styles\n\tlet frameActiveStyles = {};\n\n\tconst handleChangeFrame = ({ value }) => {\n\t\t// get new frame\n\t\tconst frameBase = frameStyles[value];\n\n\t\t// no new frame selected\n\t\tif (!frameBase || !frameBase.shape) {\n\t\t\timageFrame.set(undefined);\n\t\t\thistory.write();\n\t\t\treturn;\n\t\t}\n\n\t\tconst { shape } = frameBase;\n\n\t\t// create new base frame\n\t\tconst frame = {\n\t\t\tid: value,\n\t\t\t// copy the frame base, it's possible that this frame has a different layout\n\t\t\t...shapeDeepCopy(shape),\n\t\t\t// set base styles\n\t\t\t...Object.keys(frameActiveStyles).reduce(\n\t\t\t\t(frameStyles, prop) => {\n\t\t\t\t\tif (!shape[prop]) return frameStyles;\n\t\t\t\t\tframeStyles[prop] = frameActiveStyles[prop];\n\t\t\t\t\treturn frameStyles;\n\t\t\t\t},\n\t\t\t\t{}\n\t\t\t)\n\t\t};\n\n\t\timageFrame.set(frame);\n\t\thistory.write();\n\t};\n\n\tlet updateWriteHistoryTimeoutId;\n\n\tfunction handleUpdateSelectedFrameShape(props) {\n\t\t// remember color style for when creating or styling other element\n\t\tif (hasProp(props, 'frameColor')) frameActiveStyles.frameColor = props.frameColor;\n\n\t\t// it's possible we're only updating default styles\n\t\tif (!$imageFrame) return;\n\n\t\t// frameSelected\n\t\tshapeUpdateProps($imageFrame, props);\n\n\t\t// update shape so ui shape controls are updated\n\t\timageFrame.set($imageFrame);\n\n\t\t// so we don't write every state change to history\n\t\tclearTimeout(updateWriteHistoryTimeoutId);\n\n\t\tupdateWriteHistoryTimeoutId = setTimeout(\n\t\t\t() => {\n\t\t\t\thistory.write();\n\t\t\t},\n\t\t\t200\n\t\t);\n\t}\n\n\tconst isIncompleteSVGMarkup = str => (/rect|path|circle|line|<g>/i).test(str);\n\tconst isHTML = str => (/div/i).test(str);\n\n\tconst getThumb = value => {\n\t\tif (isHTML(value)) return value;\n\n\t\t// could be full svg\n\t\tif (isSVGMarkup(value)) return value;\n\n\t\t// could be a partial svg in which case we turn it into a full svg\n\t\tif (isIncompleteSVGMarkup(value)) return `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" stroke-width=\"1\" stroke=\"currentColor\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${value}</svg>`;\n\n\t\t// if not, must be URL\n\t\treturn `<img src=\"${value}\" alt=\"\"/>`;\n\t};\n\n\tconst getOptionThumb = key => {\n\t\tconst frameStyle = frameStyles[key];\n\t\tif (!frameStyle || !frameStyle.thumb) return;\n\t\treturn getThumb(frameStyle.thumb);\n\t};\n\n\tconst isDynamicTreeThumb = key => {\n\t\tconst frameStyle = frameStyles[key];\n\t\tif (!frameStyle || !frameStyle.thumb) return false;\n\t\treturn isArray(frameStyle.thumb);\n\t};\n\n\tconst getThumbTree = key => {\n\t\treturn frameStyles[key].thumb;\n\t};\n\n\t//\n\t// Footer style\n\t//\n\tconst footerOffset = spring($animation ? 20 : 0);\n\n\tcomponent_subscribe($$self, footerOffset, value => $$invalidate(21, $footerOffset = value));\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));\n\t\tif ('stores' in $$props) $$invalidate(19, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(1, locale = $$props.locale);\n\t\tif ('frameStyles' in $$props) $$invalidate(20, frameStyles = $$props.frameStyles);\n\t\tif ('frameOptions' in $$props) $$invalidate(2, frameOptions = $$props.frameOptions);\n\t\tif ('markupEditorShapeStyleControls' in $$props) $$invalidate(3, markupEditorShapeStyleControls = $$props.markupEditorShapeStyleControls);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 4194304) {\n\t\t\t// enable pan and zoom\n\t\t\tallowPan.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 4194304) {\n\t\t\tallowZoom.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 4194304) {\n\t\t\tallowZoomControls.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 4194304) {\n\t\t\t$isActive && allowPlayPause.set(true);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$elasticityMultiplier*/ 16777216) {\n\t\t\t//\n\t\t\t// scroll components\n\t\t\t//\n\t\t\t$$invalidate(7, computedScrollElasticity = $elasticityMultiplier * scrollElasticity);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$imageFrame, frameOptions*/ 20) {\n\t\t\t// current index in frame list\n\t\t\t$$invalidate(6, selectedFrameIndex = $imageFrame\n\t\t\t? frameOptions.findIndex(([id]) => id === $imageFrame.id)\n\t\t\t: 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$animation, $isActive*/ 12582912) {\n\t\t\t$animation && footerOffset.set($isActive ? 0 : 20);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$footerOffset*/ 2097152) {\n\t\t\t$$invalidate(5, styleFooterTransform = $footerOffset\n\t\t\t? `translateY(${$footerOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tlocale,\n\t\tframeOptions,\n\t\tmarkupEditorShapeStyleControls,\n\t\t$imageFrame,\n\t\tstyleFooterTransform,\n\t\tselectedFrameIndex,\n\t\tcomputedScrollElasticity,\n\t\telasticityMultiplier,\n\t\tanimation,\n\t\tscrollElasticity,\n\t\timageFrame,\n\t\thandleChangeFrame,\n\t\thandleUpdateSelectedFrameShape,\n\t\tgetOptionThumb,\n\t\tisDynamicTreeThumb,\n\t\tgetThumbTree,\n\t\tfooterOffset,\n\t\tname,\n\t\tstores,\n\t\tframeStyles,\n\t\t$footerOffset,\n\t\t$isActive,\n\t\t$animation,\n\t\t$elasticityMultiplier,\n\t\tmeasure_handler\n\t];\n}\n\nclass Frame extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$7,\n\t\t\tcreate_fragment$7,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 18,\n\t\t\t\tisActive: 0,\n\t\t\t\tstores: 19,\n\t\t\t\tlocale: 1,\n\t\t\t\tframeStyles: 20,\n\t\t\t\tframeOptions: 2,\n\t\t\t\tmarkupEditorShapeStyleControls: 3\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget frameStyles() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset frameStyles(frameStyles) {\n\t\tthis.$$set({ frameStyles });\n\t\tflush();\n\t}\n\n\tget frameOptions() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset frameOptions(frameOptions) {\n\t\tthis.$$set({ frameOptions });\n\t\tflush();\n\t}\n\n\tget markupEditorShapeStyleControls() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset markupEditorShapeStyleControls(markupEditorShapeStyleControls) {\n\t\tthis.$$set({ markupEditorShapeStyleControls });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_frame = { util: ['frame', Frame, ({ src }) => src && !isVideoFile(src)] };\n\n/* src/core/ui/plugins/resize/DimensionInput.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$6(ctx) {\n\tlet div;\n\tlet input;\n\tlet input_value_value;\n\tlet t0;\n\tlet label_1;\n\tlet t1;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tinput = element(\"input\");\n\t\t\tt0 = space();\n\t\t\tlabel_1 = element(\"label\");\n\t\t\tt1 = text(/*label*/ ctx[1]);\n\t\t\tattr(input, \"id\", /*id*/ ctx[0]);\n\t\t\tattr(input, \"type\", \"number\");\n\t\t\tattr(input, \"min\", \"1\");\n\t\t\tattr(input, \"inputmode\", \"numeric\");\n\t\t\tattr(input, \"pattern\", \"[0-9]*\");\n\t\t\tattr(input, \"data-state\", /*state*/ ctx[3]);\n\t\t\tattr(input, \"autocomplete\", \"off\");\n\t\t\tattr(input, \"placeholder\", /*placeholder*/ ctx[4]);\n\n\t\t\tinput.value = input_value_value = /*value*/ ctx[5] === undefined\n\t\t\t? ''\n\t\t\t: /*format*/ ctx[7](/*value*/ ctx[5] + '');\n\n\t\t\tattr(label_1, \"for\", /*id*/ ctx[0]);\n\t\t\tattr(label_1, \"title\", /*title*/ ctx[2]);\n\t\t\tattr(label_1, \"aria-label\", /*title*/ ctx[2]);\n\t\t\tattr(div, \"class\", \"PinturaInputDimension\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, input);\n\t\t\tappend(div, t0);\n\t\t\tappend(div, label_1);\n\t\t\tappend(label_1, t1);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = listen(input, \"input\", /*input_handler*/ ctx[8]);\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (dirty & /*id*/ 1) {\n\t\t\t\tattr(input, \"id\", /*id*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (dirty & /*state*/ 8) {\n\t\t\t\tattr(input, \"data-state\", /*state*/ ctx[3]);\n\t\t\t}\n\n\t\t\tif (dirty & /*placeholder*/ 16) {\n\t\t\t\tattr(input, \"placeholder\", /*placeholder*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (dirty & /*value, format*/ 160 && input_value_value !== (input_value_value = /*value*/ ctx[5] === undefined\n\t\t\t? ''\n\t\t\t: /*format*/ ctx[7](/*value*/ ctx[5] + '')) && input.value !== input_value_value) {\n\t\t\t\tinput.value = input_value_value;\n\t\t\t}\n\n\t\t\tif (dirty & /*label*/ 2) set_data(t1, /*label*/ ctx[1]);\n\n\t\t\tif (dirty & /*id*/ 1) {\n\t\t\t\tattr(label_1, \"for\", /*id*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (dirty & /*title*/ 4) {\n\t\t\t\tattr(label_1, \"title\", /*title*/ ctx[2]);\n\t\t\t}\n\n\t\t\tif (dirty & /*title*/ 4) {\n\t\t\t\tattr(label_1, \"aria-label\", /*title*/ ctx[2]);\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\nfunction instance$6($$self, $$props, $$invalidate) {\n\tlet { id } = $$props;\n\tlet { label } = $$props;\n\tlet { title } = $$props;\n\tlet { state } = $$props;\n\tlet { placeholder } = $$props;\n\tlet { value } = $$props;\n\tlet { onchange } = $$props;\n\tlet { format = str => str.replace(/\\D/g, '') } = $$props;\n\tconst input_handler = e => onchange(format(e.currentTarget.value));\n\n\t$$self.$$set = $$props => {\n\t\tif ('id' in $$props) $$invalidate(0, id = $$props.id);\n\t\tif ('label' in $$props) $$invalidate(1, label = $$props.label);\n\t\tif ('title' in $$props) $$invalidate(2, title = $$props.title);\n\t\tif ('state' in $$props) $$invalidate(3, state = $$props.state);\n\t\tif ('placeholder' in $$props) $$invalidate(4, placeholder = $$props.placeholder);\n\t\tif ('value' in $$props) $$invalidate(5, value = $$props.value);\n\t\tif ('onchange' in $$props) $$invalidate(6, onchange = $$props.onchange);\n\t\tif ('format' in $$props) $$invalidate(7, format = $$props.format);\n\t};\n\n\treturn [id, label, title, state, placeholder, value, onchange, format, input_handler];\n}\n\nclass DimensionInput extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$6, create_fragment$6, safe_not_equal, {\n\t\t\tid: 0,\n\t\t\tlabel: 1,\n\t\t\ttitle: 2,\n\t\t\tstate: 3,\n\t\t\tplaceholder: 4,\n\t\t\tvalue: 5,\n\t\t\tonchange: 6,\n\t\t\tformat: 7\n\t\t});\n\t}\n}\n\n/* src/core/ui/plugins/resize/DimensionLock.svelte generated by Svelte v4.2.20 */\n\nfunction create_default_slot$2(ctx) {\n\tlet g;\n\n\treturn {\n\t\tc() {\n\t\t\tg = svg_element(\"g\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, g, anchor);\n\t\t\tg.innerHTML = /*icon*/ ctx[2];\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty & /*icon*/ 4) g.innerHTML = /*icon*/ ctx[2];\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(g);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction create_fragment$5(ctx) {\n\tlet div;\n\tlet input;\n\tlet t;\n\tlet label;\n\tlet icon_1;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\n\ticon_1 = new Icon({\n\t\t\tprops: {\n\t\t\t\t$$slots: { default: [create_default_slot$2] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tinput = element(\"input\");\n\t\t\tt = space();\n\t\t\tlabel = element(\"label\");\n\t\t\tcreate_component(icon_1.$$.fragment);\n\t\t\tattr(input, \"id\", /*id*/ ctx[0]);\n\t\t\tattr(input, \"class\", \"implicit\");\n\t\t\tattr(input, \"type\", \"checkbox\");\n\t\t\tinput.checked = /*locked*/ ctx[1];\n\t\t\tattr(label, \"for\", /*id*/ ctx[0]);\n\t\t\tattr(label, \"title\", /*title*/ ctx[3]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, input);\n\t\t\tappend(div, t);\n\t\t\tappend(div, label);\n\t\t\tmount_component(icon_1, label, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = listen(input, \"change\", /*change_handler*/ ctx[5]);\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (!current || dirty & /*id*/ 1) {\n\t\t\t\tattr(input, \"id\", /*id*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*locked*/ 2) {\n\t\t\t\tinput.checked = /*locked*/ ctx[1];\n\t\t\t}\n\n\t\t\tconst icon_1_changes = {};\n\n\t\t\tif (dirty & /*$$scope, icon*/ 68) {\n\t\t\t\ticon_1_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\ticon_1.$set(icon_1_changes);\n\n\t\t\tif (!current || dirty & /*id*/ 1) {\n\t\t\t\tattr(label, \"for\", /*id*/ ctx[0]);\n\t\t\t}\n\n\t\t\tif (!current || dirty & /*title*/ 8) {\n\t\t\t\tattr(label, \"title\", /*title*/ ctx[3]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(icon_1.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(icon_1.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(icon_1);\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\nfunction instance$5($$self, $$props, $$invalidate) {\n\tlet { id } = $$props;\n\tlet { locked } = $$props;\n\tlet { icon } = $$props;\n\tlet { title } = $$props;\n\tlet { onchange } = $$props;\n\tconst change_handler = e => onchange(e.currentTarget.checked);\n\n\t$$self.$$set = $$props => {\n\t\tif ('id' in $$props) $$invalidate(0, id = $$props.id);\n\t\tif ('locked' in $$props) $$invalidate(1, locked = $$props.locked);\n\t\tif ('icon' in $$props) $$invalidate(2, icon = $$props.icon);\n\t\tif ('title' in $$props) $$invalidate(3, title = $$props.title);\n\t\tif ('onchange' in $$props) $$invalidate(4, onchange = $$props.onchange);\n\t};\n\n\treturn [id, locked, icon, title, onchange, change_handler];\n}\n\nclass DimensionLock extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$5, create_fragment$5, safe_not_equal, {\n\t\t\tid: 0,\n\t\t\tlocked: 1,\n\t\t\ticon: 2,\n\t\t\ttitle: 3,\n\t\t\tonchange: 4\n\t\t});\n\t}\n}\n\n/* src/core/ui/plugins/resize/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_default_slot$1(ctx) {\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tt = text(\"Save\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, t, anchor);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (631:4) \nfunction create_footer_slot$1(ctx) {\n\tlet form;\n\tlet div1;\n\tlet fieldset;\n\tlet legend;\n\tlet t0_value = /*locale*/ ctx[1].resizeLabelFormCaption + \"\";\n\tlet t0;\n\tlet t1;\n\tlet div0;\n\tlet dynamiccomponenttree;\n\tlet t2;\n\tlet button;\n\tlet current;\n\tlet mounted;\n\tlet dispose;\n\tdynamiccomponenttree = new DynamicComponentTree_1({ props: { items: /*tools*/ ctx[4] } });\n\n\tbutton = new Button({\n\t\t\tprops: {\n\t\t\t\ttype: \"submit\",\n\t\t\t\tclass: \"implicit\",\n\t\t\t\t$$slots: { default: [create_default_slot$1] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tform = element(\"form\");\n\t\t\tdiv1 = element(\"div\");\n\t\t\tfieldset = element(\"fieldset\");\n\t\t\tlegend = element(\"legend\");\n\t\t\tt0 = text(t0_value);\n\t\t\tt1 = space();\n\t\t\tdiv0 = element(\"div\");\n\t\t\tcreate_component(dynamiccomponenttree.$$.fragment);\n\t\t\tt2 = space();\n\t\t\tcreate_component(button.$$.fragment);\n\t\t\tattr(legend, \"class\", \"implicit\");\n\t\t\tattr(div0, \"class\", \"PinturaFieldsetInner\");\n\t\t\tattr(div1, \"class\", \"PinturaFormInner\");\n\t\t\tattr(form, \"slot\", \"footer\");\n\t\t\tset_style(form, \"transform\", /*styleFooterTransform*/ ctx[3]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, form, anchor);\n\t\t\tappend(form, div1);\n\t\t\tappend(div1, fieldset);\n\t\t\tappend(fieldset, legend);\n\t\t\tappend(legend, t0);\n\t\t\tappend(fieldset, t1);\n\t\t\tappend(fieldset, div0);\n\t\t\tmount_component(dynamiccomponenttree, div0, null);\n\t\t\t/*div0_binding*/ ctx[66](div0);\n\t\t\tappend(div1, t2);\n\t\t\tmount_component(button, div1, null);\n\t\t\tcurrent = true;\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(div0, \"focusin\", /*handleFocusIn*/ ctx[15]),\n\t\t\t\t\tlisten(div0, \"focusout\", /*handleFocusOut*/ ctx[16]),\n\t\t\t\t\tlisten(form, \"submit\", prevent_default(/*handleSubmit*/ ctx[17]))\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif ((!current || dirty[0] & /*locale*/ 2) && t0_value !== (t0_value = /*locale*/ ctx[1].resizeLabelFormCaption + \"\")) set_data(t0, t0_value);\n\t\t\tconst dynamiccomponenttree_changes = {};\n\t\t\tif (dirty[0] & /*tools*/ 16) dynamiccomponenttree_changes.items = /*tools*/ ctx[4];\n\t\t\tdynamiccomponenttree.$set(dynamiccomponenttree_changes);\n\t\t\tconst button_changes = {};\n\n\t\t\tif (dirty[3] & /*$$scope*/ 32) {\n\t\t\t\tbutton_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tbutton.$set(button_changes);\n\n\t\t\tif (dirty[0] & /*styleFooterTransform*/ 8) {\n\t\t\t\tset_style(form, \"transform\", /*styleFooterTransform*/ ctx[3]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(dynamiccomponenttree.$$.fragment, local);\n\t\t\ttransition_in(button.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(dynamiccomponenttree.$$.fragment, local);\n\t\t\ttransition_out(button.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(form);\n\t\t\t}\n\n\t\t\tdestroy_component(dynamiccomponenttree);\n\t\t\t/*div0_binding*/ ctx[66](null);\n\t\t\tdestroy_component(button);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nfunction create_fragment$4(ctx) {\n\tlet util;\n\tlet current;\n\n\tutil = new Util({\n\t\t\tprops: {\n\t\t\t\t$$slots: { footer: [create_footer_slot$1] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tutil.$on(\"measure\", /*measure_handler*/ ctx[67]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(util.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(util, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst util_changes = {};\n\n\t\t\tif (dirty[0] & /*styleFooterTransform, fieldsGroup, tools, locale*/ 30 | dirty[3] & /*$$scope*/ 32) {\n\t\t\t\tutil_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tutil.$set(util_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(util.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(util.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(util, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$4($$self, $$props, $$invalidate) {\n\tlet sizePresetLabel;\n\tlet widthPresetLabel;\n\tlet heightPresetLabel;\n\tlet canRenderSizePresets;\n\tlet canRenderWidthPresets;\n\tlet canRenderHeightPresets;\n\tlet canRenderSizeInputs;\n\tlet tools;\n\tlet styleFooterTransform;\n\tlet $footerOffset;\n\n\tlet $isActive,\n\t\t$$unsubscribe_isActive = noop,\n\t\t$$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(50, $isActive = $$value)), isActive);\n\n\tlet $animation;\n\tlet $env;\n\tlet $imageCropRect;\n\tlet $imageCropRectAspectRatio;\n\tlet $iconActiveFraction;\n\tlet $heightPresetSelectedIndex;\n\tlet $formattedResizeHeightPresetOptions;\n\tlet $widthPresetSelectedIndex;\n\tlet $formattedResizeWidthPresetOptions;\n\tlet $sizePresetSelectedIndex;\n\tlet $formattedResizeSizePresetOptions;\n\tlet $imageOutputSize;\n\tlet $imageCropAspectRatio;\n\tlet $formattedResizeHeightPresetOptionsFlattened;\n\tlet $formattedResizeWidthPresetOptionsFlattened;\n\tlet $formattedResizeSizePresetOptionsFlattened;\n\tlet $imageSize;\n\tlet $imageSelectionZoom;\n\tlet $imageSelectionPan;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActive());\n\n\tconst formatValue = (value, min = 0, max = 9999) => {\n\t\tif (isString(value)) {\n\t\t\tvalue = value.replace(/\\D/g, '');\n\t\t\tif (!value.length) return;\n\t\t}\n\n\t\tconst v = Math.round(value);\n\t\tif (Number.isNaN(v)) return;\n\t\treturn clamp(v, min, max);\n\t};\n\n\tconst name = 'resize';\n\tlet { isActive } = $$props;\n\t$$subscribe_isActive();\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { resizeMinSize = sizeCreate(1, 1) } = $$props;\n\tlet { resizeMaxSize = sizeCreate(9999, 9999) } = $$props;\n\tlet { resizeAspectRatioLocked = false } = $$props;\n\tlet { resizeEnableButtonLockAspectRatio = true } = $$props;\n\tlet { resizeSizePresetOptions = undefined } = $$props;\n\tlet { resizeWidthPresetOptions = undefined } = $$props;\n\tlet { resizeHeightPresetOptions = undefined } = $$props;\n\tlet { resizeWillRenderFooter = passthrough } = $$props;\n\n\tlet { resizeFormatIconButtonMaintainAspectRatio = function (values) {\n\t\tconst { active, activeFraction } = values;\n\n\t\treturn {\n\t\t\tactive,\n\t\t\tactiveFraction: (activeFraction - 1) * 3\n\t\t};\n\t} } = $$props;\n\n\t// offset\n\tconst iconActiveFraction = spring(0, { stiffness: 0.15, damping: 0.3 });\n\n\tcomponent_subscribe($$self, iconActiveFraction, value => $$invalidate(55, $iconActiveFraction = value));\n\tconst { animation, imageSize, imageCropRect, imageCropRectAspectRatio, imageCropAspectRatio, imageOutputSize, imageSelectionZoom, imageSelectionPan, history, env, allowPan, allowZoom, allowZoomControls, allowPlayPause } = stores;\n\tcomponent_subscribe($$self, animation, value => $$invalidate(51, $animation = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(74, $imageSize = value));\n\tcomponent_subscribe($$self, imageCropRect, value => $$invalidate(53, $imageCropRect = value));\n\tcomponent_subscribe($$self, imageCropRectAspectRatio, value => $$invalidate(54, $imageCropRectAspectRatio = value));\n\tcomponent_subscribe($$self, imageCropAspectRatio, value => $$invalidate(73, $imageCropAspectRatio = value));\n\tcomponent_subscribe($$self, imageOutputSize, value => $$invalidate(62, $imageOutputSize = value));\n\tcomponent_subscribe($$self, imageSelectionZoom, value => $$invalidate(75, $imageSelectionZoom = value));\n\tcomponent_subscribe($$self, imageSelectionPan, value => $$invalidate(76, $imageSelectionPan = value));\n\tcomponent_subscribe($$self, env, value => $$invalidate(52, $env = value));\n\tconst formId = getUniqueId();\n\tlet fieldsGroup;\n\tlet width;\n\tlet height;\n\tlet activeField;\n\tlet lastActiveField;\n\tlet storedImageSelectionPan = vectorCreateEmpty();\n\tlet storedImageSelectionZoom;\n\n\tconst rememberPanZoom = () => {\n\t\tstoredImageSelectionPan = $imageSelectionPan;\n\t\tstoredImageSelectionZoom = $imageSelectionZoom;\n\t};\n\n\t// zoom image preview so it scales to show the actual image output size\n\tconst updateSelectionScale = outputSize => {\n\t\t// always reset to center\n\t\tset_store_value(imageSelectionPan, $imageSelectionPan = vectorCreateEmpty(), $imageSelectionPan);\n\n\t\t// no resizing, zoom to actual size\n\t\tif (!outputSize || !$imageCropRect) {\n\t\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = 1, $imageSelectionZoom);\n\t\t\treturn;\n\t\t}\n\n\t\t// zoom image to fit image target size\n\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = outputSize.width / $imageCropRect.width || outputSize.height / $imageCropRect.height, $imageSelectionZoom);\n\t};\n\n\tconst resetSelectionScale = () => {\n\t\tset_store_value(imageSelectionPan, $imageSelectionPan = storedImageSelectionPan, $imageSelectionPan);\n\t\tset_store_value(imageSelectionZoom, $imageSelectionZoom = storedImageSelectionZoom, $imageSelectionZoom);\n\t};\n\n\tconst getState = (value, field, activeField, resizeMinSize, resizeMaxSize) => value != null && activeField !== field\n\t? value >= resizeMinSize[field] && value <= resizeMaxSize[field]\n\t\t? 'valid'\n\t\t: 'invalid'\n\t: 'undetermined';\n\n\tconst getWidthPlaceholder = (value, cropAspectRatio, cropRect) => Math.round(value != null ? value * cropAspectRatio : cropRect.width);\n\n\tconst getHeightPlaceholder = (value, cropAspectRatio, cropRect) => Math.round(value != null\n\t? value / cropAspectRatio\n\t: cropRect.height);\n\n\t// populate active field\n\tconst handleFocusIn = e => {\n\t\tconst id = e.target.id;\n\n\t\tif ((/width/).test(id)) {\n\t\t\t$$invalidate(41, activeField = 'width');\n\t\t} else if ((/height/).test(id)) {\n\t\t\t$$invalidate(41, activeField = 'height');\n\t\t} else if ((/aspectRatio/i).test(id)) {\n\t\t\t$$invalidate(41, activeField = 'lock');\n\t\t} else {\n\t\t\t$$invalidate(41, activeField = undefined);\n\t\t}\n\t};\n\n\tconst handleFocusOut = e => {\n\t\tif (!fieldsGroup.contains(e.relatedTarget)) handleSubmit();\n\t\t$$invalidate(41, activeField = undefined);\n\t};\n\n\t// sync fields if one has a value and aspect ratio should be maintained\n\tconst syncFields = () => {\n\t\tif (!resizeAspectRatioLocked || !width || !height) return;\n\n\t\tif (activeField === 'width') {\n\t\t\t// sync height field\n\t\t\t$$invalidate(40, height = Math.round(width / $imageCropRectAspectRatio));\n\t\t} else if (activeField === 'height') {\n\t\t\t// sync width field\n\t\t\t$$invalidate(39, width = Math.round(height * $imageCropRectAspectRatio));\n\t\t} else {\n\t\t\tif (lastActiveField === 'width') {\n\t\t\t\t$$invalidate(40, height = Math.round(width / $imageCropRectAspectRatio));\n\t\t\t} else if (lastActiveField === 'height') {\n\t\t\t\t$$invalidate(39, width = Math.round(height * $imageCropRectAspectRatio));\n\t\t\t}\n\n\t\t\tconsolidateSize();\n\t\t}\n\t};\n\n\tconst consolidateSize = forcedAspectRatio => {\n\t\t// first need to limit values\n\t\tlet inputWidth = formatValue(width);\n\n\t\tlet inputHeight = formatValue(height);\n\t\tlet currentWidth = inputWidth;\n\t\tlet currentHeight = inputHeight;\n\t\tlet bothAxisDefined = currentWidth && currentHeight;\n\t\tlet aspectRatio = forcedAspectRatio || $imageCropRectAspectRatio;\n\n\t\t// done, no consolidation needed\n\t\tif (!currentWidth && !currentHeight) return;\n\n\t\t// need to fill in missing values\n\t\tif (currentWidth && !currentHeight) {\n\t\t\tcurrentHeight = Math.round(currentWidth / aspectRatio);\n\t\t} else if (currentHeight && !currentWidth) {\n\t\t\tcurrentWidth = Math.round(currentHeight * aspectRatio);\n\t\t}\n\n\t\taspectRatio = forcedAspectRatio || bothAxisDefined\n\t\t? getAspectRatio(currentWidth, currentHeight)\n\t\t: $imageCropRectAspectRatio;\n\n\t\t// now we have both width and height let's re-fit the min max size\n\t\tlet currentSize = sizeCreate(currentWidth, currentHeight);\n\n\t\tif (!sizeContains(resizeMaxSize, currentSize)) {\n\t\t\t// too big\n\t\t\tcurrentSize = rectContainRect(resizeMaxSize, aspectRatio);\n\t\t}\n\n\t\tif (!sizeContains(currentSize, resizeMinSize)) {\n\t\t\t// too small\n\t\t\tcurrentSize = rectCoverRect(resizeMinSize, aspectRatio);\n\t\t}\n\n\t\t$$invalidate(39, width = inputWidth != null\n\t\t? Math.round(currentSize.width)\n\t\t: undefined);\n\n\t\t$$invalidate(40, height = inputHeight != null\n\t\t? Math.round(currentSize.height)\n\t\t: undefined);\n\t};\n\n\tconst handleSubmit = () => {\n\t\t// calculate correct values\n\t\tconsolidateSize();\n\n\t\t// get curent values so we can check if they were changed (if not, no need to write history or update)\n\t\tconst { width: currentWidth, height: currentHeight } = $imageOutputSize || {};\n\n\t\t// no need to update\n\t\tif (currentWidth === width && currentHeight === height) {\n\t\t\treturn;\n\t\t}\n\n\t\t// no size defined\n\t\tif (!width && !height) {\n\t\t\t// reset image crop\n\t\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = $imageSize.width / $imageSize.height, $imageCropAspectRatio);\n\n\t\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = undefined, $imageCropAspectRatio);\n\n\t\t\t// reset output size\n\t\t\tset_store_value(imageOutputSize, $imageOutputSize = undefined, $imageOutputSize);\n\t\t} else // we have all dimensions\n\t\t{\n\t\t\tif (width && height) {\n\t\t\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = width / height, $imageCropAspectRatio);\n\t\t\t}\n\n\t\t\tset_store_value(imageOutputSize, $imageOutputSize = sizeCreate(width, height), $imageOutputSize);\n\t\t}\n\n\t\thistory.write();\n\t};\n\n\t// handle external updates to outputSize\n\tconst imageOutputSizeUnsub = imageOutputSize.subscribe(size => {\n\t\tif (!size) {\n\t\t\t$$invalidate(39, width = undefined);\n\t\t\t$$invalidate(40, height = undefined);\n\t\t\treturn;\n\t\t}\n\n\t\t$$invalidate(39, width = size.width);\n\t\t$$invalidate(40, height = size.height);\n\n\t\t// make sure the size conforms to min max\n\t\tconsolidateSize();\n\t});\n\n\t// if the crop aspect ratio is changed we need to align width/height\n\tconst imageCropAspectRatioUnsub = imageCropAspectRatio.subscribe(cropAspectRatio => {\n\t\t// exit if no dimensions supplied\n\t\tif (!width && !height) return;\n\n\t\t// no crop aspect ratio has been selected, so all is fine\n\t\tif (!cropAspectRatio) return;\n\n\t\t// fix size to match new aspect ratio of the crop\n\t\tif (width && height && getAspectRatio(width, height) !== cropAspectRatio) {\n\t\t\t$$invalidate(40, height = width / cropAspectRatio);\n\t\t\tconsolidateSize(cropAspectRatio);\n\t\t} else {\n\t\t\tconsolidateSize();\n\t\t}\n\t});\n\n\t//\n\t// size presets\n\t//\n\tconst formatPresetDimensionOption = option => {\n\t\tif (isString(option[0])) {\n\t\t\toption[1] = option[1].map(formatPresetDimensionOption);\n\t\t\treturn option;\n\t\t}\n\n\t\treturn isNumber(option) ? [option, '' + option] : option;\n\t};\n\n\tconst formatPresetSizeOption = option => {\n\t\tif (isString(option[0])) {\n\t\t\toption[1] = option[1].map(formatPresetSizeOption);\n\t\t\treturn option;\n\t\t}\n\n\t\tlet [value, label] = option;\n\n\t\t// Size only\n\t\tif (isNumber(value) && isNumber(label)) {\n\t\t\tconst [w, h] = [value, label];\n\t\t\tlabel = `${w} &times; ${h}`;\n\t\t\tvalue = [w, h];\n\t\t}\n\n\t\treturn [value, label];\n\t};\n\n\tconst formattedResizeSizePresetOptions = writable();\n\tcomponent_subscribe($$self, formattedResizeSizePresetOptions, value => $$invalidate(61, $formattedResizeSizePresetOptions = value));\n\tconst formattedResizeSizePresetOptionsFlattened = writable();\n\tcomponent_subscribe($$self, formattedResizeSizePresetOptionsFlattened, value => $$invalidate(65, $formattedResizeSizePresetOptionsFlattened = value));\n\tconst formattedResizeWidthPresetOptions = writable();\n\tcomponent_subscribe($$self, formattedResizeWidthPresetOptions, value => $$invalidate(59, $formattedResizeWidthPresetOptions = value));\n\tconst formattedResizeWidthPresetOptionsFlattened = writable();\n\tcomponent_subscribe($$self, formattedResizeWidthPresetOptionsFlattened, value => $$invalidate(64, $formattedResizeWidthPresetOptionsFlattened = value));\n\tconst formattedResizeHeightPresetOptions = writable();\n\tcomponent_subscribe($$self, formattedResizeHeightPresetOptions, value => $$invalidate(57, $formattedResizeHeightPresetOptions = value));\n\tconst formattedResizeHeightPresetOptionsFlattened = writable();\n\tcomponent_subscribe($$self, formattedResizeHeightPresetOptionsFlattened, value => $$invalidate(63, $formattedResizeHeightPresetOptionsFlattened = value));\n\n\tconst sizePresetSelectedIndex = derived([imageOutputSize, formattedResizeSizePresetOptionsFlattened], ([$imageOutputSize, $formattedResizeSizePresetOptionsFlattened], set) => {\n\t\tif (!$formattedResizeSizePresetOptionsFlattened) return set(-1);\n\n\t\tconst index = $formattedResizeSizePresetOptionsFlattened.findIndex(([value]) => {\n\t\t\tif (!value && !$imageOutputSize) return true;\n\t\t\tif (!value) return false;\n\t\t\tconst [width, height] = value;\n\t\t\treturn $imageOutputSize.width === width && $imageOutputSize.height === height;\n\t\t});\n\n\t\tset(index < 0 ? 0 : index);\n\t});\n\n\tcomponent_subscribe($$self, sizePresetSelectedIndex, value => $$invalidate(60, $sizePresetSelectedIndex = value));\n\n\tconst widthPresetSelectedIndex = derived([imageOutputSize, formattedResizeWidthPresetOptionsFlattened], ([$imageOutputSize, $formattedResizeWidthPresetOptionsFlattened], set) => {\n\t\tif (!$formattedResizeWidthPresetOptionsFlattened) return set(-1);\n\n\t\tconst index = $formattedResizeWidthPresetOptionsFlattened.findIndex(([value]) => {\n\t\t\tif (!value && !$imageOutputSize) return true;\n\t\t\tif (!value) return false;\n\t\t\treturn $imageOutputSize.width === value;\n\t\t});\n\n\t\tset(index < 0 ? 0 : index);\n\t});\n\n\tcomponent_subscribe($$self, widthPresetSelectedIndex, value => $$invalidate(58, $widthPresetSelectedIndex = value));\n\n\tconst heightPresetSelectedIndex = derived([imageOutputSize, formattedResizeHeightPresetOptionsFlattened], ([$imageOutputSize, $formattedResizeHeightPresetOptionsFlattened], set) => {\n\t\tif (!$formattedResizeHeightPresetOptionsFlattened) return set(-1);\n\n\t\tconst index = $formattedResizeHeightPresetOptionsFlattened.findIndex(([value]) => {\n\t\t\tif (!value && !$imageOutputSize) return true;\n\t\t\tif (!value) return false;\n\t\t\treturn $imageOutputSize.height === value;\n\t\t});\n\n\t\tset(index < 0 ? 0 : index);\n\t});\n\n\tcomponent_subscribe($$self, heightPresetSelectedIndex, value => $$invalidate(56, $heightPresetSelectedIndex = value));\n\tlet storedCropRect = undefined;\n\tlet storedCropAspectRatio = undefined;\n\n\tconst setImageOutputSizeWithArray = size => {\n\t\tif (size && !storedCropRect) {\n\t\t\tstoredCropRect = { ...$imageCropRect };\n\t\t\tstoredCropAspectRatio = $imageCropAspectRatio;\n\t\t}\n\n\t\tif (!size) {\n\t\t\tset_store_value(imageCropRect, $imageCropRect = storedCropRect, $imageCropRect);\n\t\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = storedCropAspectRatio, $imageCropAspectRatio);\n\t\t\tset_store_value(imageOutputSize, $imageOutputSize = undefined, $imageOutputSize);\n\t\t\tstoredCropRect = undefined;\n\t\t\tstoredCropAspectRatio = undefined;\n\t\t} else {\n\t\t\tset_store_value(imageCropAspectRatio, $imageCropAspectRatio = getAspectRatio(size[0], size[1]), $imageCropAspectRatio);\n\t\t\tset_store_value(imageOutputSize, $imageOutputSize = sizeCreateFromArray(size), $imageOutputSize);\n\t\t}\n\n\t\thistory.write();\n\t};\n\n\t//\n\t// toolbar\n\t//\n\tconst redrawTrigger = getContext('redrawTrigger');\n\n\t//\n\t// Footer\n\t//\n\tconst footerOffset = spring($animation ? 20 : 0);\n\n\tcomponent_subscribe($$self, footerOffset, value => $$invalidate(49, $footerOffset = value));\n\n\t//\n\t// Clean up\n\t//\n\tonDestroy(() => {\n\t\timageOutputSizeUnsub();\n\t\timageCropAspectRatioUnsub();\n\t});\n\n\tfunction div0_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tfieldsGroup = $$value;\n\t\t\t$$invalidate(2, fieldsGroup);\n\t\t});\n\t}\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));\n\t\tif ('stores' in $$props) $$invalidate(30, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(1, locale = $$props.locale);\n\t\tif ('resizeMinSize' in $$props) $$invalidate(31, resizeMinSize = $$props.resizeMinSize);\n\t\tif ('resizeMaxSize' in $$props) $$invalidate(32, resizeMaxSize = $$props.resizeMaxSize);\n\t\tif ('resizeAspectRatioLocked' in $$props) $$invalidate(28, resizeAspectRatioLocked = $$props.resizeAspectRatioLocked);\n\t\tif ('resizeEnableButtonLockAspectRatio' in $$props) $$invalidate(33, resizeEnableButtonLockAspectRatio = $$props.resizeEnableButtonLockAspectRatio);\n\t\tif ('resizeSizePresetOptions' in $$props) $$invalidate(34, resizeSizePresetOptions = $$props.resizeSizePresetOptions);\n\t\tif ('resizeWidthPresetOptions' in $$props) $$invalidate(35, resizeWidthPresetOptions = $$props.resizeWidthPresetOptions);\n\t\tif ('resizeHeightPresetOptions' in $$props) $$invalidate(36, resizeHeightPresetOptions = $$props.resizeHeightPresetOptions);\n\t\tif ('resizeWillRenderFooter' in $$props) $$invalidate(37, resizeWillRenderFooter = $$props.resizeWillRenderFooter);\n\t\tif ('resizeFormatIconButtonMaintainAspectRatio' in $$props) $$invalidate(38, resizeFormatIconButtonMaintainAspectRatio = $$props.resizeFormatIconButtonMaintainAspectRatio);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 524288) {\n\t\t\t// fully disable pan and zoom when resize tool is active\n\t\t\tallowPan.set(!$isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 524288) {\n\t\t\tallowZoom.set(!$isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 524288) {\n\t\t\tallowZoomControls.set(!$isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 524288) {\n\t\t\tif ($isActive) {\n\t\t\t\tallowPlayPause.set(true);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*resizeSizePresetOptions, $formattedResizeSizePresetOptions*/ 1073741832) {\n\t\t\tif (resizeSizePresetOptions) {\n\t\t\t\tset_store_value(formattedResizeSizePresetOptions, $formattedResizeSizePresetOptions = resizeSizePresetOptions.map(formatPresetSizeOption), $formattedResizeSizePresetOptions);\n\t\t\t\tset_store_value(formattedResizeSizePresetOptionsFlattened, $formattedResizeSizePresetOptionsFlattened = flattenOptions($formattedResizeSizePresetOptions), $formattedResizeSizePresetOptionsFlattened);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$formattedResizeSizePresetOptions*/ 1073741824) {\n\t\t\t//\n\t\t\t// helper bools\n\t\t\t//\n\t\t\t$$invalidate(48, canRenderSizePresets = !!$formattedResizeSizePresetOptions);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$sizePresetSelectedIndex*/ 536870912 | $$self.$$.dirty[2] & /*$formattedResizeSizePresetOptionsFlattened*/ 8) {\n\t\t\t$$invalidate(47, sizePresetLabel = $sizePresetSelectedIndex > -1 && $formattedResizeSizePresetOptionsFlattened[$sizePresetSelectedIndex][1]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*resizeWidthPresetOptions, $formattedResizeWidthPresetOptions*/ 268435472) {\n\t\t\tif (resizeWidthPresetOptions) {\n\t\t\t\tset_store_value(formattedResizeWidthPresetOptions, $formattedResizeWidthPresetOptions = resizeWidthPresetOptions.map(formatPresetDimensionOption), $formattedResizeWidthPresetOptions);\n\t\t\t\tset_store_value(formattedResizeWidthPresetOptionsFlattened, $formattedResizeWidthPresetOptionsFlattened = flattenOptions($formattedResizeWidthPresetOptions), $formattedResizeWidthPresetOptionsFlattened);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*canRenderSizePresets, $formattedResizeWidthPresetOptions*/ 268566528) {\n\t\t\t$$invalidate(45, canRenderWidthPresets = !canRenderSizePresets && $formattedResizeWidthPresetOptions);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$widthPresetSelectedIndex*/ 134217728 | $$self.$$.dirty[2] & /*$formattedResizeWidthPresetOptionsFlattened*/ 4) {\n\t\t\t$$invalidate(46, widthPresetLabel = $widthPresetSelectedIndex > -1 && $formattedResizeWidthPresetOptionsFlattened[$widthPresetSelectedIndex][1]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*resizeHeightPresetOptions, $formattedResizeHeightPresetOptions*/ 67108896) {\n\t\t\tif (resizeHeightPresetOptions) {\n\t\t\t\tset_store_value(formattedResizeHeightPresetOptions, $formattedResizeHeightPresetOptions = resizeHeightPresetOptions.map(formatPresetDimensionOption), $formattedResizeHeightPresetOptions);\n\t\t\t\tset_store_value(formattedResizeHeightPresetOptionsFlattened, $formattedResizeHeightPresetOptionsFlattened = flattenOptions($formattedResizeHeightPresetOptions), $formattedResizeHeightPresetOptionsFlattened);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*canRenderSizePresets, $formattedResizeHeightPresetOptions*/ 67239936) {\n\t\t\t$$invalidate(44, canRenderHeightPresets = !canRenderSizePresets && $formattedResizeHeightPresetOptions);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$heightPresetSelectedIndex*/ 33554432 | $$self.$$.dirty[2] & /*$formattedResizeHeightPresetOptionsFlattened*/ 2) {\n\t\t\t$$invalidate(43, heightPresetLabel = $heightPresetSelectedIndex > -1 && $formattedResizeHeightPresetOptionsFlattened[$heightPresetSelectedIndex][1]);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*canRenderSizePresets, canRenderWidthPresets, canRenderHeightPresets*/ 155648) {\n\t\t\t$$invalidate(42, canRenderSizeInputs = !canRenderSizePresets && !canRenderWidthPresets && !canRenderHeightPresets);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*locale, resizeAspectRatioLocked*/ 268435458 | $$self.$$.dirty[1] & /*resizeWillRenderFooter, canRenderSizePresets, sizePresetLabel, $formattedResizeSizePresetOptions, $sizePresetSelectedIndex, canRenderWidthPresets, widthPresetLabel, $formattedResizeWidthPresetOptions, $widthPresetSelectedIndex, canRenderHeightPresets, heightPresetLabel, $formattedResizeHeightPresetOptions, $heightPresetSelectedIndex, canRenderSizeInputs, height, $imageCropRectAspectRatio, $imageCropRect, width, activeField, resizeMinSize, resizeMaxSize, resizeEnableButtonLockAspectRatio, $iconActiveFraction, resizeFormatIconButtonMaintainAspectRatio, $env*/ 2145648583) {\n\t\t\t$$invalidate(4, tools = redrawTrigger && runSafe(() => resizeWillRenderFooter(\n\t\t\t\t[\n\t\t\t\t\tcanRenderSizePresets && [\n\t\t\t\t\t\t'Dropdown',\n\t\t\t\t\t\t'size-presets',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: sizePresetLabel,\n\t\t\t\t\t\t\toptions: $formattedResizeSizePresetOptions,\n\t\t\t\t\t\t\tonchange: item => setImageOutputSizeWithArray(item.value),\n\t\t\t\t\t\t\tselectedIndex: $sizePresetSelectedIndex\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcanRenderWidthPresets && [\n\t\t\t\t\t\t'Dropdown',\n\t\t\t\t\t\t'width-presets',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: widthPresetLabel,\n\t\t\t\t\t\t\toptions: $formattedResizeWidthPresetOptions,\n\t\t\t\t\t\t\tonchange: item => {\n\t\t\t\t\t\t\t\t$$invalidate(39, width = item.value);\n\t\t\t\t\t\t\t\thandleSubmit();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tselectedIndex: $widthPresetSelectedIndex\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcanRenderWidthPresets && canRenderHeightPresets && [\n\t\t\t\t\t\t'span',\n\t\t\t\t\t\t'times',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tclass: 'PinturaResizeLabel',\n\t\t\t\t\t\t\tinnerHTML: '&times;'\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcanRenderHeightPresets && [\n\t\t\t\t\t\t'Dropdown',\n\t\t\t\t\t\t'height-presets',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: heightPresetLabel,\n\t\t\t\t\t\t\toptions: $formattedResizeHeightPresetOptions,\n\t\t\t\t\t\t\tonchange: item => {\n\t\t\t\t\t\t\t\t$$invalidate(40, height = item.value);\n\t\t\t\t\t\t\t\thandleSubmit();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tselectedIndex: $heightPresetSelectedIndex\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcanRenderSizeInputs && [\n\t\t\t\t\t\tDimensionInput,\n\t\t\t\t\t\t'width-input',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: `width-${formId}`,\n\t\t\t\t\t\t\ttitle: locale.resizeTitleInputWidth,\n\t\t\t\t\t\t\tlabel: locale.resizeLabelInputWidth,\n\t\t\t\t\t\t\tplaceholder: getWidthPlaceholder(formatValue(height), $imageCropRectAspectRatio, $imageCropRect),\n\t\t\t\t\t\t\tvalue: width,\n\t\t\t\t\t\t\tstate: getState(formatValue(width), 'width', activeField, resizeMinSize, resizeMaxSize),\n\t\t\t\t\t\t\tonchange: value => {\n\t\t\t\t\t\t\t\t$$invalidate(39, width = value);\n\t\t\t\t\t\t\t\tsyncFields();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcanRenderSizeInputs && resizeEnableButtonLockAspectRatio && [\n\t\t\t\t\t\tDimensionLock,\n\t\t\t\t\t\t'aspect-ratio-lock',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: `aspect-ratio-lock-${formId}`,\n\t\t\t\t\t\t\ttitle: locale.resizeTitleButtonMaintainAspectRatio,\n\t\t\t\t\t\t\ticon: isFunction(locale.resizeIconButtonMaintainAspectRatio)\n\t\t\t\t\t\t\t? locale.resizeIconButtonMaintainAspectRatio(resizeAspectRatioLocked, $iconActiveFraction)\n\t\t\t\t\t\t\t: stringReplace(\n\t\t\t\t\t\t\t\t\tlocale.resizeIconButtonMaintainAspectRatio,\n\t\t\t\t\t\t\t\t\tresizeFormatIconButtonMaintainAspectRatio({\n\t\t\t\t\t\t\t\t\t\tactive: resizeAspectRatioLocked,\n\t\t\t\t\t\t\t\t\t\tactiveFraction: $iconActiveFraction\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t'{',\n\t\t\t\t\t\t\t\t\t'}'\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tlocked: resizeAspectRatioLocked,\n\t\t\t\t\t\t\tonchange: locked => {\n\t\t\t\t\t\t\t\t$$invalidate(28, resizeAspectRatioLocked = locked);\n\t\t\t\t\t\t\t\tsyncFields();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\tcanRenderSizeInputs && [\n\t\t\t\t\t\tDimensionInput,\n\t\t\t\t\t\t'height-input',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: `height-${formId}`,\n\t\t\t\t\t\t\ttitle: locale.resizeTitleInputHeight,\n\t\t\t\t\t\t\tlabel: locale.resizeLabelInputHeight,\n\t\t\t\t\t\t\tplaceholder: getHeightPlaceholder(formatValue(width), $imageCropRectAspectRatio, $imageCropRect),\n\t\t\t\t\t\t\tvalue: height,\n\t\t\t\t\t\t\tstate: getState(formatValue(height), 'height', activeField, resizeMinSize, resizeMaxSize),\n\t\t\t\t\t\t\tonchange: value => {\n\t\t\t\t\t\t\t\t$$invalidate(40, height = value);\n\t\t\t\t\t\t\t\tsyncFields();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t].filter(Boolean),\n\t\t\t\t{ ...$env },\n\t\t\t\t() => redrawTrigger.set({})\n\t\t\t)).filter(Boolean));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*resizeAspectRatioLocked*/ 268435456) {\n\t\t\ticonActiveFraction.set(resizeAspectRatioLocked ? 1 : 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*activeField*/ 1024) {\n\t\t\tif (activeField) lastActiveField = activeField;\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 524288) {\n\t\t\tif ($isActive) rememberPanZoom();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$isActive*/ 524288 | $$self.$$.dirty[2] & /*$imageOutputSize*/ 1) {\n\t\t\t$isActive\n\t\t\t? setTimeout(() => updateSelectionScale($imageOutputSize), 0)\n\t\t\t: resetSelectionScale();\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$animation, $isActive*/ 1572864) {\n\t\t\t$animation && footerOffset.set($isActive ? 0 : 20);\n\t\t}\n\n\t\tif ($$self.$$.dirty[1] & /*$footerOffset*/ 262144) {\n\t\t\t$$invalidate(3, styleFooterTransform = $footerOffset\n\t\t\t? `translateY(${$footerOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tlocale,\n\t\tfieldsGroup,\n\t\tstyleFooterTransform,\n\t\ttools,\n\t\ticonActiveFraction,\n\t\tanimation,\n\t\timageSize,\n\t\timageCropRect,\n\t\timageCropRectAspectRatio,\n\t\timageCropAspectRatio,\n\t\timageOutputSize,\n\t\timageSelectionZoom,\n\t\timageSelectionPan,\n\t\tenv,\n\t\thandleFocusIn,\n\t\thandleFocusOut,\n\t\thandleSubmit,\n\t\tformattedResizeSizePresetOptions,\n\t\tformattedResizeSizePresetOptionsFlattened,\n\t\tformattedResizeWidthPresetOptions,\n\t\tformattedResizeWidthPresetOptionsFlattened,\n\t\tformattedResizeHeightPresetOptions,\n\t\tformattedResizeHeightPresetOptionsFlattened,\n\t\tsizePresetSelectedIndex,\n\t\twidthPresetSelectedIndex,\n\t\theightPresetSelectedIndex,\n\t\tfooterOffset,\n\t\tresizeAspectRatioLocked,\n\t\tname,\n\t\tstores,\n\t\tresizeMinSize,\n\t\tresizeMaxSize,\n\t\tresizeEnableButtonLockAspectRatio,\n\t\tresizeSizePresetOptions,\n\t\tresizeWidthPresetOptions,\n\t\tresizeHeightPresetOptions,\n\t\tresizeWillRenderFooter,\n\t\tresizeFormatIconButtonMaintainAspectRatio,\n\t\twidth,\n\t\theight,\n\t\tactiveField,\n\t\tcanRenderSizeInputs,\n\t\theightPresetLabel,\n\t\tcanRenderHeightPresets,\n\t\tcanRenderWidthPresets,\n\t\twidthPresetLabel,\n\t\tsizePresetLabel,\n\t\tcanRenderSizePresets,\n\t\t$footerOffset,\n\t\t$isActive,\n\t\t$animation,\n\t\t$env,\n\t\t$imageCropRect,\n\t\t$imageCropRectAspectRatio,\n\t\t$iconActiveFraction,\n\t\t$heightPresetSelectedIndex,\n\t\t$formattedResizeHeightPresetOptions,\n\t\t$widthPresetSelectedIndex,\n\t\t$formattedResizeWidthPresetOptions,\n\t\t$sizePresetSelectedIndex,\n\t\t$formattedResizeSizePresetOptions,\n\t\t$imageOutputSize,\n\t\t$formattedResizeHeightPresetOptionsFlattened,\n\t\t$formattedResizeWidthPresetOptionsFlattened,\n\t\t$formattedResizeSizePresetOptionsFlattened,\n\t\tdiv0_binding,\n\t\tmeasure_handler\n\t];\n}\n\nclass Resize extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$4,\n\t\t\tcreate_fragment$4,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 29,\n\t\t\t\tisActive: 0,\n\t\t\t\tstores: 30,\n\t\t\t\tlocale: 1,\n\t\t\t\tresizeMinSize: 31,\n\t\t\t\tresizeMaxSize: 32,\n\t\t\t\tresizeAspectRatioLocked: 28,\n\t\t\t\tresizeEnableButtonLockAspectRatio: 33,\n\t\t\t\tresizeSizePresetOptions: 34,\n\t\t\t\tresizeWidthPresetOptions: 35,\n\t\t\t\tresizeHeightPresetOptions: 36,\n\t\t\t\tresizeWillRenderFooter: 37,\n\t\t\t\tresizeFormatIconButtonMaintainAspectRatio: 38\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1, -1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[29];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[30];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget resizeMinSize() {\n\t\treturn this.$$.ctx[31];\n\t}\n\n\tset resizeMinSize(resizeMinSize) {\n\t\tthis.$$set({ resizeMinSize });\n\t\tflush();\n\t}\n\n\tget resizeMaxSize() {\n\t\treturn this.$$.ctx[32];\n\t}\n\n\tset resizeMaxSize(resizeMaxSize) {\n\t\tthis.$$set({ resizeMaxSize });\n\t\tflush();\n\t}\n\n\tget resizeAspectRatioLocked() {\n\t\treturn this.$$.ctx[28];\n\t}\n\n\tset resizeAspectRatioLocked(resizeAspectRatioLocked) {\n\t\tthis.$$set({ resizeAspectRatioLocked });\n\t\tflush();\n\t}\n\n\tget resizeEnableButtonLockAspectRatio() {\n\t\treturn this.$$.ctx[33];\n\t}\n\n\tset resizeEnableButtonLockAspectRatio(resizeEnableButtonLockAspectRatio) {\n\t\tthis.$$set({ resizeEnableButtonLockAspectRatio });\n\t\tflush();\n\t}\n\n\tget resizeSizePresetOptions() {\n\t\treturn this.$$.ctx[34];\n\t}\n\n\tset resizeSizePresetOptions(resizeSizePresetOptions) {\n\t\tthis.$$set({ resizeSizePresetOptions });\n\t\tflush();\n\t}\n\n\tget resizeWidthPresetOptions() {\n\t\treturn this.$$.ctx[35];\n\t}\n\n\tset resizeWidthPresetOptions(resizeWidthPresetOptions) {\n\t\tthis.$$set({ resizeWidthPresetOptions });\n\t\tflush();\n\t}\n\n\tget resizeHeightPresetOptions() {\n\t\treturn this.$$.ctx[36];\n\t}\n\n\tset resizeHeightPresetOptions(resizeHeightPresetOptions) {\n\t\tthis.$$set({ resizeHeightPresetOptions });\n\t\tflush();\n\t}\n\n\tget resizeWillRenderFooter() {\n\t\treturn this.$$.ctx[37];\n\t}\n\n\tset resizeWillRenderFooter(resizeWillRenderFooter) {\n\t\tthis.$$set({ resizeWillRenderFooter });\n\t\tflush();\n\t}\n\n\tget resizeFormatIconButtonMaintainAspectRatio() {\n\t\treturn this.$$.ctx[38];\n\t}\n\n\tset resizeFormatIconButtonMaintainAspectRatio(resizeFormatIconButtonMaintainAspectRatio) {\n\t\tthis.$$set({\n\t\t\tresizeFormatIconButtonMaintainAspectRatio\n\t\t});\n\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_resize = { util: ['resize', Resize] };\n\n/* src/core/ui/plugins/redact/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$3(ctx) {\n\tlet shapeutil;\n\tlet current;\n\n\tshapeutil = new ShapeUtil({\n\t\t\tprops: {\n\t\t\t\tstores: /*stores*/ ctx[3],\n\t\t\t\tlocale: /*locale*/ ctx[4],\n\t\t\t\tisActive: /*isActive*/ ctx[0],\n\t\t\t\tisActiveFraction: /*isActiveFraction*/ ctx[1],\n\t\t\t\tisVisible: /*isVisible*/ ctx[2],\n\t\t\t\tmapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[10],\n\t\t\t\tmapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[9],\n\t\t\t\tenableMultiSelect: /*enableMultiSelect*/ ctx[6],\n\t\t\t\tutilKey: 'redact',\n\t\t\t\timageRotation: /*$imageRotation*/ ctx[11],\n\t\t\t\timageFlipX: /*$imageFlipX*/ ctx[8],\n\t\t\t\timageFlipY: /*$imageFlipY*/ ctx[7],\n\t\t\t\tshapes: /*imageRedaction*/ ctx[12],\n\t\t\t\ttoolbar: ['rect'],\n\t\t\t\ttoolShapes: {\n\t\t\t\t\trectangle: [{ x: 0, y: 0, width: 0, height: 0 }]\n\t\t\t\t},\n\t\t\t\ttoolActive: 'rectangle',\n\t\t\t\tparentRect: /*imageSize*/ ctx[14],\n\t\t\t\tenablePresetDropImage: false,\n\t\t\t\tenablePresetSelectImage: false,\n\t\t\t\twillStartInteraction: /*markupEditorWillStartInteraction*/ ctx[5],\n\t\t\t\thooks: {\n\t\t\t\t\twillRenderShapeControls: /*func*/ ctx[26]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\tshapeutil.$on(\"measure\", /*measure_handler*/ ctx[27]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapeutil.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapeutil, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tconst shapeutil_changes = {};\n\t\t\tif (dirty & /*stores*/ 8) shapeutil_changes.stores = /*stores*/ ctx[3];\n\t\t\tif (dirty & /*locale*/ 16) shapeutil_changes.locale = /*locale*/ ctx[4];\n\t\t\tif (dirty & /*isActive*/ 1) shapeutil_changes.isActive = /*isActive*/ ctx[0];\n\t\t\tif (dirty & /*isActiveFraction*/ 2) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[1];\n\t\t\tif (dirty & /*isVisible*/ 4) shapeutil_changes.isVisible = /*isVisible*/ ctx[2];\n\t\t\tif (dirty & /*mapScreenPointToImagePoint*/ 1024) shapeutil_changes.mapScreenPointToImagePoint = /*mapScreenPointToImagePoint*/ ctx[10];\n\t\t\tif (dirty & /*mapImagePointToScreenPoint*/ 512) shapeutil_changes.mapImagePointToScreenPoint = /*mapImagePointToScreenPoint*/ ctx[9];\n\t\t\tif (dirty & /*enableMultiSelect*/ 64) shapeutil_changes.enableMultiSelect = /*enableMultiSelect*/ ctx[6];\n\t\t\tif (dirty & /*$imageRotation*/ 2048) shapeutil_changes.imageRotation = /*$imageRotation*/ ctx[11];\n\t\t\tif (dirty & /*$imageFlipX*/ 256) shapeutil_changes.imageFlipX = /*$imageFlipX*/ ctx[8];\n\t\t\tif (dirty & /*$imageFlipY*/ 128) shapeutil_changes.imageFlipY = /*$imageFlipY*/ ctx[7];\n\t\t\tif (dirty & /*markupEditorWillStartInteraction*/ 32) shapeutil_changes.willStartInteraction = /*markupEditorWillStartInteraction*/ ctx[5];\n\t\t\tshapeutil.$set(shapeutil_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapeutil.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapeutil.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapeutil, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$3($$self, $$props, $$invalidate) {\n\tlet presentationRotation;\n\tlet mapScreenPointToImagePoint;\n\tlet mapImagePointToScreenPoint;\n\tlet $imageFlipY;\n\tlet $imageFlipX;\n\tlet $imageTransformsInterpolated;\n\tlet $imageSize;\n\tlet $rootRect;\n\tlet $imageTransforms;\n\tlet $imageRotation;\n\tconst name = 'redact';\n\tlet { isActive } = $$props;\n\tlet { isActiveFraction } = $$props;\n\tlet { isVisible } = $$props;\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { markupEditorWillStartInteraction = undefined } = $$props;\n\tlet { enableMultiSelect = undefined } = $$props;\n\n\t// connect filter choice to stores\n\tconst { imageRedaction, rootRect, imageSize, imageRotation, imageFlipX, imageFlipY, imageTransforms, imageTransformsInterpolated } = stores;\n\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(24, $rootRect = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(23, $imageSize = value));\n\tcomponent_subscribe($$self, imageRotation, value => $$invalidate(11, $imageRotation = value));\n\tcomponent_subscribe($$self, imageFlipX, value => $$invalidate(8, $imageFlipX = value));\n\tcomponent_subscribe($$self, imageFlipY, value => $$invalidate(7, $imageFlipY = value));\n\tcomponent_subscribe($$self, imageTransforms, value => $$invalidate(25, $imageTransforms = value));\n\tcomponent_subscribe($$self, imageTransformsInterpolated, value => $$invalidate(22, $imageTransformsInterpolated = value));\n\n\tconst func = controls => {\n\t\tconst children = getNodeChildren(controls[0]);\n\t\tremoveNode('to-front', children);\n\t\treturn controls;\n\t};\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$invalidate(0, isActive = $$props.isActive);\n\t\tif ('isActiveFraction' in $$props) $$invalidate(1, isActiveFraction = $$props.isActiveFraction);\n\t\tif ('isVisible' in $$props) $$invalidate(2, isVisible = $$props.isVisible);\n\t\tif ('stores' in $$props) $$invalidate(3, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(4, locale = $$props.locale);\n\t\tif ('markupEditorWillStartInteraction' in $$props) $$invalidate(5, markupEditorWillStartInteraction = $$props.markupEditorWillStartInteraction);\n\t\tif ('enableMultiSelect' in $$props) $$invalidate(6, enableMultiSelect = $$props.enableMultiSelect);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*$imageTransforms*/ 33554432) {\n\t\t\t$$invalidate(21, presentationRotation = $imageTransforms ? $imageTransforms.rotation.z : 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation, $imageFlipX, $imageFlipY*/ 31457664) {\n\t\t\t//\n\t\t\t// Mapping coordinates\n\t\t\t//\n\t\t\t$$invalidate(10, mapScreenPointToImagePoint = point => _mapScreenPointToImagePoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY));\n\t\t}\n\n\t\tif ($$self.$$.dirty & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation, $imageFlipX, $imageFlipY*/ 31457664) {\n\t\t\t$$invalidate(9, mapImagePointToScreenPoint = point => _mapImagePointToScreenPoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY));\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tisActiveFraction,\n\t\tisVisible,\n\t\tstores,\n\t\tlocale,\n\t\tmarkupEditorWillStartInteraction,\n\t\tenableMultiSelect,\n\t\t$imageFlipY,\n\t\t$imageFlipX,\n\t\tmapImagePointToScreenPoint,\n\t\tmapScreenPointToImagePoint,\n\t\t$imageRotation,\n\t\timageRedaction,\n\t\trootRect,\n\t\timageSize,\n\t\timageRotation,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\timageTransforms,\n\t\timageTransformsInterpolated,\n\t\tname,\n\t\tpresentationRotation,\n\t\t$imageTransformsInterpolated,\n\t\t$imageSize,\n\t\t$rootRect,\n\t\t$imageTransforms,\n\t\tfunc,\n\t\tmeasure_handler\n\t];\n}\n\nclass Redact extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance$3, create_fragment$3, safe_not_equal, {\n\t\t\tname: 20,\n\t\t\tisActive: 0,\n\t\t\tisActiveFraction: 1,\n\t\t\tisVisible: 2,\n\t\t\tstores: 3,\n\t\t\tlocale: 4,\n\t\t\tmarkupEditorWillStartInteraction: 5,\n\t\t\tenableMultiSelect: 6\n\t\t});\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget isActiveFraction() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset isActiveFraction(isActiveFraction) {\n\t\tthis.$$set({ isActiveFraction });\n\t\tflush();\n\t}\n\n\tget isVisible() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset isVisible(isVisible) {\n\t\tthis.$$set({ isVisible });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget markupEditorWillStartInteraction() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset markupEditorWillStartInteraction(markupEditorWillStartInteraction) {\n\t\tthis.$$set({ markupEditorWillStartInteraction });\n\t\tflush();\n\t}\n\n\tget enableMultiSelect() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset enableMultiSelect(enableMultiSelect) {\n\t\tthis.$$set({ enableMultiSelect });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_redact = { util: ['redact', Redact, ({ src }) => src && !isVideoFile(src)] };\n\n/* src/core/ui/plugins/fill/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_else_block(ctx) {\n\tlet div;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t},\n\t\tp: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (138:52) \nfunction create_if_block_2(ctx) {\n\tlet div;\n\tlet tile_action;\n\tlet mounted;\n\tlet dispose;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"class\", \"PinturaFillTile\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = action_destroyer(tile_action = tile.call(null, div, /*option*/ ctx[31].value));\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (tile_action && is_function(tile_action.update) && dirty[1] & /*option*/ 1) tile_action.update.call(null, /*option*/ ctx[31].value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tmounted = false;\n\t\t\tdispose();\n\t\t}\n\t};\n}\n\n// (134:20) {#if isString(option.value)}\nfunction create_if_block_1(ctx) {\n\tlet div;\n\tlet img;\n\tlet img_src_value;\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\timg = element(\"img\");\n\t\t\tif (!src_url_equal(img.src, img_src_value = /*option*/ ctx[31].value)) attr(img, \"src\", img_src_value);\n\t\t\tattr(img, \"alt\", \"\");\n\t\t\tattr(img, \"width\", \"48\");\n\t\t\tattr(img, \"height\", \"64\");\n\t\t\tattr(div, \"class\", \"PinturaFillTile\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tappend(div, img);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[1] & /*option*/ 1 && !src_url_equal(img.src, img_src_value = /*option*/ ctx[31].value)) {\n\t\t\t\tattr(img, \"src\", img_src_value);\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (144:20) {#if option.label}\nfunction create_if_block(ctx) {\n\tlet span;\n\n\tlet t_value = (isFunction(/*option*/ ctx[31].label)\n\t? /*option*/ ctx[31].label(/*locale*/ ctx[1])\n\t: /*option*/ ctx[31].label) + \"\";\n\n\tlet t;\n\n\treturn {\n\t\tc() {\n\t\t\tspan = element(\"span\");\n\t\t\tt = text(t_value);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, span, anchor);\n\t\t\tappend(span, t);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (dirty[0] & /*locale*/ 2 | dirty[1] & /*option*/ 1 && t_value !== (t_value = (isFunction(/*option*/ ctx[31].label)\n\t\t\t? /*option*/ ctx[31].label(/*locale*/ ctx[1])\n\t\t\t: /*option*/ ctx[31].label) + \"\")) set_data(t, t_value);\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(span);\n\t\t\t}\n\t\t}\n\t};\n}\n\n// (133:16) \nfunction create_option_slot(ctx) {\n\tlet div;\n\tlet show_if;\n\tlet show_if_1;\n\tlet t;\n\n\tfunction select_block_type(ctx, dirty) {\n\t\tif (dirty[1] & /*option*/ 1) show_if = null;\n\t\tif (dirty[1] & /*option*/ 1) show_if_1 = null;\n\t\tif (show_if == null) show_if = !!isString(/*option*/ ctx[31].value);\n\t\tif (show_if) return create_if_block_1;\n\t\tif (show_if_1 == null) show_if_1 = !!isArray(/*option*/ ctx[31].value);\n\t\tif (show_if_1) return create_if_block_2;\n\t\treturn create_else_block;\n\t}\n\n\tlet current_block_type = select_block_type(ctx, [-1, -1]);\n\tlet if_block0 = current_block_type(ctx);\n\tlet if_block1 = /*option*/ ctx[31].label && create_if_block(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tif_block0.c();\n\t\t\tt = space();\n\t\t\tif (if_block1) if_block1.c();\n\t\t\tattr(div, \"slot\", \"option\");\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tif_block0.m(div, null);\n\t\t\tappend(div, t);\n\t\t\tif (if_block1) if_block1.m(div, null);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tif (current_block_type === (current_block_type = select_block_type(ctx, dirty)) && if_block0) {\n\t\t\t\tif_block0.p(ctx, dirty);\n\t\t\t} else {\n\t\t\t\tif_block0.d(1);\n\t\t\t\tif_block0 = current_block_type(ctx);\n\n\t\t\t\tif (if_block0) {\n\t\t\t\t\tif_block0.c();\n\t\t\t\t\tif_block0.m(div, t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (/*option*/ ctx[31].label) {\n\t\t\t\tif (if_block1) {\n\t\t\t\t\tif_block1.p(ctx, dirty);\n\t\t\t\t} else {\n\t\t\t\t\tif_block1 = create_if_block(ctx);\n\t\t\t\t\tif_block1.c();\n\t\t\t\t\tif_block1.m(div, null);\n\t\t\t\t}\n\t\t\t} else if (if_block1) {\n\t\t\t\tif_block1.d(1);\n\t\t\t\tif_block1 = null;\n\t\t\t}\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tif_block0.d();\n\t\t\tif (if_block1) if_block1.d();\n\t\t}\n\t};\n}\n\n// (124:8) <Scrollable elasticity={computedScrollElasticity}>\nfunction create_default_slot(ctx) {\n\tlet radiogroup;\n\tlet current;\n\n\tradiogroup = new RadioGroup({\n\t\t\tprops: {\n\t\t\t\tlocale: /*locale*/ ctx[1],\n\t\t\t\tclass: \"PinturaControlList\",\n\t\t\t\tlayout: \"row\",\n\t\t\t\toptions: /*fillOptionsMapped*/ ctx[2],\n\t\t\t\tselectedIndex: /*selectedFillIndex*/ ctx[4],\n\t\t\t\tonchange: /*handleChangeFill*/ ctx[10],\n\t\t\t\t$$slots: {\n\t\t\t\t\toption: [\n\t\t\t\t\t\tcreate_option_slot,\n\t\t\t\t\t\t({ option }) => ({ 31: option }),\n\t\t\t\t\t\t({ option }) => [0, option ? 1 : 0]\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(radiogroup.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(radiogroup, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst radiogroup_changes = {};\n\t\t\tif (dirty[0] & /*locale*/ 2) radiogroup_changes.locale = /*locale*/ ctx[1];\n\t\t\tif (dirty[0] & /*fillOptionsMapped*/ 4) radiogroup_changes.options = /*fillOptionsMapped*/ ctx[2];\n\t\t\tif (dirty[0] & /*selectedFillIndex*/ 16) radiogroup_changes.selectedIndex = /*selectedFillIndex*/ ctx[4];\n\n\t\t\tif (dirty[0] & /*locale*/ 2 | dirty[1] & /*$$scope, option*/ 3) {\n\t\t\t\tradiogroup_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tradiogroup.$set(radiogroup_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(radiogroup.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(radiogroup.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(radiogroup, detaching);\n\t\t}\n\t};\n}\n\n// (123:4) \nfunction create_footer_slot(ctx) {\n\tlet div;\n\tlet scrollable;\n\tlet current;\n\n\tscrollable = new Scrollable({\n\t\t\tprops: {\n\t\t\t\telasticity: /*computedScrollElasticity*/ ctx[5],\n\t\t\t\t$$slots: { default: [create_default_slot] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\treturn {\n\t\tc() {\n\t\t\tdiv = element(\"div\");\n\t\t\tcreate_component(scrollable.$$.fragment);\n\t\t\tattr(div, \"slot\", \"footer\");\n\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[3]);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, div, anchor);\n\t\t\tmount_component(scrollable, div, null);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst scrollable_changes = {};\n\t\t\tif (dirty[0] & /*computedScrollElasticity*/ 32) scrollable_changes.elasticity = /*computedScrollElasticity*/ ctx[5];\n\n\t\t\tif (dirty[0] & /*locale, fillOptionsMapped, selectedFillIndex*/ 22 | dirty[1] & /*$$scope*/ 2) {\n\t\t\t\tscrollable_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tscrollable.$set(scrollable_changes);\n\n\t\t\tif (dirty[0] & /*styleFooterTransform*/ 8) {\n\t\t\t\tset_style(div, \"transform\", /*styleFooterTransform*/ ctx[3]);\n\t\t\t}\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(scrollable.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(scrollable.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\tdestroy_component(scrollable);\n\t\t}\n\t};\n}\n\nfunction create_fragment$2(ctx) {\n\tlet util;\n\tlet current;\n\n\tutil = new Util({\n\t\t\tprops: {\n\t\t\t\t$$slots: { footer: [create_footer_slot] },\n\t\t\t\t$$scope: { ctx }\n\t\t\t}\n\t\t});\n\n\tutil.$on(\"measure\", /*measure_handler*/ ctx[21]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(util.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(util, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst util_changes = {};\n\n\t\t\tif (dirty[0] & /*styleFooterTransform, computedScrollElasticity, locale, fillOptionsMapped, selectedFillIndex*/ 62 | dirty[1] & /*$$scope*/ 2) {\n\t\t\t\tutil_changes.$$scope = { dirty, ctx };\n\t\t\t}\n\n\t\t\tutil.$set(util_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(util.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(util.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(util, detaching);\n\t\t}\n\t};\n}\n\nfunction tile(element) {\n\tconst fill = document.createElement('div');\n\telement.append(fill);\n\n\treturn {\n\t\tupdate(value) {\n\t\t\tconst [r, g, b, a] = value.map((v, i) => i < 3 ? Math.round(v * 255) : v);\n\t\t\telement.dataset.transparent = a < 1;\n\t\t\tfill.style.backgroundColor = `rgba(${r},${g},${b},${a})`;\n\t\t}\n\t};\n}\n\nfunction instance$2($$self, $$props, $$invalidate) {\n\tlet fillOptionsMapped;\n\tlet computedScrollElasticity;\n\tlet selectedFillIndex;\n\tlet styleFooterTransform;\n\tlet $footerOffset;\n\n\tlet $isActive,\n\t\t$$unsubscribe_isActive = noop,\n\t\t$$subscribe_isActive = () => ($$unsubscribe_isActive(), $$unsubscribe_isActive = subscribe(isActive, $$value => $$invalidate(16, $isActive = $$value)), isActive);\n\n\tlet $animation;\n\tlet $imageBackgroundImage;\n\tlet $imageBackgroundColor;\n\tlet $elasticityMultiplier;\n\t$$self.$$.on_destroy.push(() => $$unsubscribe_isActive());\n\tconst name = 'fill';\n\tlet { isActive } = $$props;\n\t$$subscribe_isActive();\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { fillOptions = [] } = $$props;\n\tconst isItemGroup = item => isArray(item) && isString(item[0]) && isArray(item[1]);\n\n\tconst mapItem = item => [\n\t\t// to rgba color\n\t\tArray.isArray(item) && item.length === 3\n\t\t? [...item, 1]\n\t\t: item,\n\t\tundefined,\n\t\t{ disabled: false }\n\t];\n\n\tconst mapItems = items => items.map(item => {\n\t\tif (isItemGroup(item)) {\n\t\t\treturn [item[0], mapItems(item[1]), item[2]];\n\t\t}\n\n\t\treturn mapItem(item);\n\t});\n\n\t//\n\t// context\n\t//\n\tconst elasticityMultiplier = getContext('elasticityMultiplier');\n\n\tcomponent_subscribe($$self, elasticityMultiplier, value => $$invalidate(20, $elasticityMultiplier = value));\n\n\t// connect filter choice to stores\n\tconst { history, animation, scrollElasticity, imageBackgroundColor, imageBackgroundImage, allowPan, allowZoom, allowZoomControls, allowPlayPause } = stores;\n\n\tcomponent_subscribe($$self, animation, value => $$invalidate(17, $animation = value));\n\tcomponent_subscribe($$self, imageBackgroundColor, value => $$invalidate(19, $imageBackgroundColor = value));\n\tcomponent_subscribe($$self, imageBackgroundImage, value => $$invalidate(18, $imageBackgroundImage = value));\n\n\tconst handleChangeFill = ({ value }) => {\n\t\tif (isString(value)) {\n\t\t\tset_store_value(imageBackgroundColor, $imageBackgroundColor = undefined, $imageBackgroundColor);\n\t\t\tset_store_value(imageBackgroundImage, $imageBackgroundImage = value, $imageBackgroundImage);\n\t\t}\n\n\t\tif (isArray(value)) {\n\t\t\tset_store_value(imageBackgroundColor, $imageBackgroundColor = value, $imageBackgroundColor);\n\t\t\tset_store_value(imageBackgroundImage, $imageBackgroundImage = undefined, $imageBackgroundImage);\n\t\t}\n\n\t\t// store\n\t\thistory.write();\n\t};\n\n\t//\n\t// Footer style\n\t//\n\tconst footerOffset = spring($animation ? 20 : 0);\n\n\tcomponent_subscribe($$self, footerOffset, value => $$invalidate(15, $footerOffset = value));\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$subscribe_isActive($$invalidate(0, isActive = $$props.isActive));\n\t\tif ('stores' in $$props) $$invalidate(13, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(1, locale = $$props.locale);\n\t\tif ('fillOptions' in $$props) $$invalidate(14, fillOptions = $$props.fillOptions);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*fillOptions*/ 16384) {\n\t\t\t$$invalidate(2, fillOptionsMapped = mapItems(fillOptions));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 65536) {\n\t\t\t// enable pan and zoom\n\t\t\tallowPan.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 65536) {\n\t\t\tallowZoom.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 65536) {\n\t\t\tallowZoomControls.set($isActive);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$isActive*/ 65536) {\n\t\t\t$isActive && allowPlayPause.set(true);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$elasticityMultiplier*/ 1048576) {\n\t\t\t//\n\t\t\t// scroll components\n\t\t\t//\n\t\t\t$$invalidate(5, computedScrollElasticity = $elasticityMultiplier * scrollElasticity);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*fillOptionsMapped, $imageBackgroundImage, $imageBackgroundColor*/ 786436) {\n\t\t\t// we check background image first as [0,0,0,0] is background color default value so otherwise images are never selected\n\t\t\t$$invalidate(4, selectedFillIndex = fillOptionsMapped.findIndex(([value]) => {\n\t\t\t\tif ($imageBackgroundImage) {\n\t\t\t\t\treturn value === $imageBackgroundImage;\n\t\t\t\t}\n\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\treturn arrayEqual(value, $imageBackgroundColor);\n\t\t\t\t}\n\t\t\t}) || 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$animation, $isActive*/ 196608) {\n\t\t\t$animation && footerOffset.set($isActive ? 0 : 20);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$footerOffset*/ 32768) {\n\t\t\t$$invalidate(3, styleFooterTransform = $footerOffset\n\t\t\t? `translateY(${$footerOffset}px)`\n\t\t\t: 'none');\n\t\t}\n\t};\n\n\treturn [\n\t\tisActive,\n\t\tlocale,\n\t\tfillOptionsMapped,\n\t\tstyleFooterTransform,\n\t\tselectedFillIndex,\n\t\tcomputedScrollElasticity,\n\t\telasticityMultiplier,\n\t\tanimation,\n\t\timageBackgroundColor,\n\t\timageBackgroundImage,\n\t\thandleChangeFill,\n\t\tfooterOffset,\n\t\tname,\n\t\tstores,\n\t\tfillOptions,\n\t\t$footerOffset,\n\t\t$isActive,\n\t\t$animation,\n\t\t$imageBackgroundImage,\n\t\t$imageBackgroundColor,\n\t\t$elasticityMultiplier,\n\t\tmeasure_handler\n\t];\n}\n\nclass Fill extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$2,\n\t\t\tcreate_fragment$2,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 12,\n\t\t\t\tisActive: 0,\n\t\t\t\tstores: 13,\n\t\t\t\tlocale: 1,\n\t\t\t\tfillOptions: 14\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[13];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget fillOptions() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tset fillOptions(fillOptions) {\n\t\tthis.$$set({ fillOptions });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_fill = {\n    util: [\n        'fill',\n        Fill,\n        ({ src, fillOptions }) => \n        // src needs to be an image\n        src &&\n            !isVideoFile(src) &&\n            // fill options need to be defined\n            fillOptions &&\n            fillOptions.length,\n    ],\n};\n\n/* src/core/ui/plugins/retouch/index.svelte generated by Svelte v4.2.20 */\n\nfunction create_fragment$1(ctx) {\n\tlet shapeutil;\n\tlet updating_toolActive;\n\tlet current;\n\n\tfunction shapeutil_toolActive_binding(value) {\n\t\t/*shapeutil_toolActive_binding*/ ctx[43](value);\n\t}\n\n\tlet shapeutil_props = {\n\t\tutilKey: 'retouch',\n\t\tstores: /*stores*/ ctx[4],\n\t\tlocale: /*locale*/ ctx[5],\n\t\tisActive: /*isActive*/ ctx[1],\n\t\tisActiveFraction: /*isActiveFraction*/ ctx[2],\n\t\tisVisible: /*isVisible*/ ctx[3],\n\t\tmapScreenPointToImagePoint: /*mapScreenPointToImagePoint*/ ctx[27],\n\t\tmapImagePointToScreenPoint: /*mapImagePointToScreenPoint*/ ctx[26],\n\t\timageRotation: /*$imageRotation*/ ctx[28],\n\t\timageFlipX: /*$imageFlipX*/ ctx[25],\n\t\timageFlipY: /*$imageFlipY*/ ctx[24],\n\t\ttoolbar: /*retouchTools*/ ctx[6],\n\t\ttoolbarLayout: 'stack',\n\t\tshapes: /*imageManipulation*/ ctx[30],\n\t\ttoolShapes: /*retouchToolShapes*/ ctx[7],\n\t\tenableMultiSelect: /*enableMultiSelect*/ ctx[23],\n\t\tenableViewTool: /*retouchEnableViewTool*/ ctx[14],\n\t\tenableMoveTool: /*retouchEnableMoveTool*/ ctx[13],\n\t\tenableToolShareStyles: false,\n\t\tshapeControls: /*retouchShapeControls*/ ctx[8],\n\t\tenablePresetSelectImage: false,\n\t\tenablePresetDropImage: false,\n\t\tparentRect: /*imageSize*/ ctx[31],\n\t\twillStartInteraction: /*markupEditorWillStartInteraction*/ ctx[12],\n\t\twillRenderHeaderTools: /*retouchWillRenderHeaderTools*/ ctx[10] || /*willRenderHeaderTools*/ ctx[17],\n\t\twillRenderShapeStyleControls: /*retouchWillRenderShapeStyleControls*/ ctx[9],\n\t\thooks: {\n\t\t\twillRenderShapeControls: /*retouchWillRenderShapeControls*/ ctx[11] || /*willRenderShapeControls*/ ctx[15],\n\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[16],\n\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[18],\n\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[19],\n\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[20],\n\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[21],\n\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[22]\n\t\t}\n\t};\n\n\tif (/*retouchActiveTool*/ ctx[0] !== void 0) {\n\t\tshapeutil_props.toolActive = /*retouchActiveTool*/ ctx[0];\n\t}\n\n\tshapeutil = new ShapeUtil({ props: shapeutil_props });\n\tbinding_callbacks.push(() => bind(shapeutil, 'toolActive', shapeutil_toolActive_binding));\n\tshapeutil.$on(\"measure\", /*measure_handler*/ ctx[44]);\n\n\treturn {\n\t\tc() {\n\t\t\tcreate_component(shapeutil.$$.fragment);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tmount_component(shapeutil, target, anchor);\n\t\t\tcurrent = true;\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tconst shapeutil_changes = {};\n\t\t\tif (dirty[0] & /*stores*/ 16) shapeutil_changes.stores = /*stores*/ ctx[4];\n\t\t\tif (dirty[0] & /*locale*/ 32) shapeutil_changes.locale = /*locale*/ ctx[5];\n\t\t\tif (dirty[0] & /*isActive*/ 2) shapeutil_changes.isActive = /*isActive*/ ctx[1];\n\t\t\tif (dirty[0] & /*isActiveFraction*/ 4) shapeutil_changes.isActiveFraction = /*isActiveFraction*/ ctx[2];\n\t\t\tif (dirty[0] & /*isVisible*/ 8) shapeutil_changes.isVisible = /*isVisible*/ ctx[3];\n\t\t\tif (dirty[0] & /*mapScreenPointToImagePoint*/ 134217728) shapeutil_changes.mapScreenPointToImagePoint = /*mapScreenPointToImagePoint*/ ctx[27];\n\t\t\tif (dirty[0] & /*mapImagePointToScreenPoint*/ 67108864) shapeutil_changes.mapImagePointToScreenPoint = /*mapImagePointToScreenPoint*/ ctx[26];\n\t\t\tif (dirty[0] & /*$imageRotation*/ 268435456) shapeutil_changes.imageRotation = /*$imageRotation*/ ctx[28];\n\t\t\tif (dirty[0] & /*$imageFlipX*/ 33554432) shapeutil_changes.imageFlipX = /*$imageFlipX*/ ctx[25];\n\t\t\tif (dirty[0] & /*$imageFlipY*/ 16777216) shapeutil_changes.imageFlipY = /*$imageFlipY*/ ctx[24];\n\t\t\tif (dirty[0] & /*retouchTools*/ 64) shapeutil_changes.toolbar = /*retouchTools*/ ctx[6];\n\t\t\tif (dirty[0] & /*retouchToolShapes*/ 128) shapeutil_changes.toolShapes = /*retouchToolShapes*/ ctx[7];\n\t\t\tif (dirty[0] & /*enableMultiSelect*/ 8388608) shapeutil_changes.enableMultiSelect = /*enableMultiSelect*/ ctx[23];\n\t\t\tif (dirty[0] & /*retouchEnableViewTool*/ 16384) shapeutil_changes.enableViewTool = /*retouchEnableViewTool*/ ctx[14];\n\t\t\tif (dirty[0] & /*retouchEnableMoveTool*/ 8192) shapeutil_changes.enableMoveTool = /*retouchEnableMoveTool*/ ctx[13];\n\t\t\tif (dirty[0] & /*retouchShapeControls*/ 256) shapeutil_changes.shapeControls = /*retouchShapeControls*/ ctx[8];\n\t\t\tif (dirty[0] & /*markupEditorWillStartInteraction*/ 4096) shapeutil_changes.willStartInteraction = /*markupEditorWillStartInteraction*/ ctx[12];\n\t\t\tif (dirty[0] & /*retouchWillRenderHeaderTools, willRenderHeaderTools*/ 132096) shapeutil_changes.willRenderHeaderTools = /*retouchWillRenderHeaderTools*/ ctx[10] || /*willRenderHeaderTools*/ ctx[17];\n\t\t\tif (dirty[0] & /*retouchWillRenderShapeStyleControls*/ 512) shapeutil_changes.willRenderShapeStyleControls = /*retouchWillRenderShapeStyleControls*/ ctx[9];\n\n\t\t\tif (dirty[0] & /*retouchWillRenderShapeControls, willRenderShapeControls, willRenderShapeTextControls, beforeAddShape, beforeRemoveShape, beforeDeselectShape, beforeSelectShape, beforeUpdateShape*/ 8226816) shapeutil_changes.hooks = {\n\t\t\t\twillRenderShapeControls: /*retouchWillRenderShapeControls*/ ctx[11] || /*willRenderShapeControls*/ ctx[15],\n\t\t\t\twillRenderShapeTextControls: /*willRenderShapeTextControls*/ ctx[16],\n\t\t\t\tbeforeAddShape: /*beforeAddShape*/ ctx[18],\n\t\t\t\tbeforeRemoveShape: /*beforeRemoveShape*/ ctx[19],\n\t\t\t\tbeforeDeselectShape: /*beforeDeselectShape*/ ctx[20],\n\t\t\t\tbeforeSelectShape: /*beforeSelectShape*/ ctx[21],\n\t\t\t\tbeforeUpdateShape: /*beforeUpdateShape*/ ctx[22]\n\t\t\t};\n\n\t\t\tif (!updating_toolActive && dirty[0] & /*retouchActiveTool*/ 1) {\n\t\t\t\tupdating_toolActive = true;\n\t\t\t\tshapeutil_changes.toolActive = /*retouchActiveTool*/ ctx[0];\n\t\t\t\tadd_flush_callback(() => updating_toolActive = false);\n\t\t\t}\n\n\t\t\tshapeutil.$set(shapeutil_changes);\n\t\t},\n\t\ti(local) {\n\t\t\tif (current) return;\n\t\t\ttransition_in(shapeutil.$$.fragment, local);\n\t\t\tcurrent = true;\n\t\t},\n\t\to(local) {\n\t\t\ttransition_out(shapeutil.$$.fragment, local);\n\t\t\tcurrent = false;\n\t\t},\n\t\td(detaching) {\n\t\t\tdestroy_component(shapeutil, detaching);\n\t\t}\n\t};\n}\n\nfunction instance$1($$self, $$props, $$invalidate) {\n\tlet presentationRotation;\n\tlet mapScreenPointToImagePoint;\n\tlet mapImagePointToScreenPoint;\n\tlet $imageFlipY;\n\tlet $imageFlipX;\n\tlet $imageTransformsInterpolated;\n\tlet $imageSize;\n\tlet $rootRect;\n\tlet $imageTransforms;\n\tlet $imageRotation;\n\tconst name = 'retouch';\n\tlet { isActive } = $$props;\n\tlet { isActiveFraction } = $$props;\n\tlet { isVisible } = $$props;\n\tlet { stores } = $$props;\n\tlet { locale = {} } = $$props;\n\tlet { retouchTools = undefined } = $$props;\n\tlet { retouchToolShapes = undefined } = $$props;\n\tlet { retouchShapeControls = undefined } = $$props;\n\tlet { retouchActiveTool = undefined } = $$props;\n\tlet { retouchWillRenderShapeStyleControls = undefined } = $$props;\n\tlet { retouchWillRenderHeaderTools = undefined } = $$props;\n\tlet { retouchWillRenderShapeControls = undefined } = $$props;\n\tlet { markupEditorWillStartInteraction = undefined } = $$props;\n\tlet { retouchEnableMoveTool = undefined } = $$props;\n\tlet { retouchEnableViewTool = undefined } = $$props;\n\tlet { willRenderShapeControls = undefined } = $$props;\n\tlet { willRenderShapeTextControls = undefined } = $$props;\n\tlet { willRenderHeaderTools = undefined } = $$props;\n\tlet { beforeAddShape = undefined } = $$props;\n\tlet { beforeRemoveShape = undefined } = $$props;\n\tlet { beforeDeselectShape = undefined } = $$props;\n\tlet { beforeSelectShape = undefined } = $$props;\n\tlet { beforeUpdateShape = undefined } = $$props;\n\tlet { enableMultiSelect = undefined } = $$props;\n\n\t// connect filter choice to stores\n\tconst { rootRect, imageManipulation, imageSize, imageRotation, imageFlipX, imageFlipY, imageTransforms, imageTransformsInterpolated } = stores;\n\n\tcomponent_subscribe($$self, rootRect, value => $$invalidate(41, $rootRect = value));\n\tcomponent_subscribe($$self, imageSize, value => $$invalidate(40, $imageSize = value));\n\tcomponent_subscribe($$self, imageRotation, value => $$invalidate(28, $imageRotation = value));\n\tcomponent_subscribe($$self, imageFlipX, value => $$invalidate(25, $imageFlipX = value));\n\tcomponent_subscribe($$self, imageFlipY, value => $$invalidate(24, $imageFlipY = value));\n\tcomponent_subscribe($$self, imageTransforms, value => $$invalidate(42, $imageTransforms = value));\n\tcomponent_subscribe($$self, imageTransformsInterpolated, value => $$invalidate(39, $imageTransformsInterpolated = value));\n\n\tfunction shapeutil_toolActive_binding(value) {\n\t\tretouchActiveTool = value;\n\t\t$$invalidate(0, retouchActiveTool);\n\t}\n\n\tfunction measure_handler(event) {\n\t\tbubble.call(this, $$self, event);\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('isActive' in $$props) $$invalidate(1, isActive = $$props.isActive);\n\t\tif ('isActiveFraction' in $$props) $$invalidate(2, isActiveFraction = $$props.isActiveFraction);\n\t\tif ('isVisible' in $$props) $$invalidate(3, isVisible = $$props.isVisible);\n\t\tif ('stores' in $$props) $$invalidate(4, stores = $$props.stores);\n\t\tif ('locale' in $$props) $$invalidate(5, locale = $$props.locale);\n\t\tif ('retouchTools' in $$props) $$invalidate(6, retouchTools = $$props.retouchTools);\n\t\tif ('retouchToolShapes' in $$props) $$invalidate(7, retouchToolShapes = $$props.retouchToolShapes);\n\t\tif ('retouchShapeControls' in $$props) $$invalidate(8, retouchShapeControls = $$props.retouchShapeControls);\n\t\tif ('retouchActiveTool' in $$props) $$invalidate(0, retouchActiveTool = $$props.retouchActiveTool);\n\t\tif ('retouchWillRenderShapeStyleControls' in $$props) $$invalidate(9, retouchWillRenderShapeStyleControls = $$props.retouchWillRenderShapeStyleControls);\n\t\tif ('retouchWillRenderHeaderTools' in $$props) $$invalidate(10, retouchWillRenderHeaderTools = $$props.retouchWillRenderHeaderTools);\n\t\tif ('retouchWillRenderShapeControls' in $$props) $$invalidate(11, retouchWillRenderShapeControls = $$props.retouchWillRenderShapeControls);\n\t\tif ('markupEditorWillStartInteraction' in $$props) $$invalidate(12, markupEditorWillStartInteraction = $$props.markupEditorWillStartInteraction);\n\t\tif ('retouchEnableMoveTool' in $$props) $$invalidate(13, retouchEnableMoveTool = $$props.retouchEnableMoveTool);\n\t\tif ('retouchEnableViewTool' in $$props) $$invalidate(14, retouchEnableViewTool = $$props.retouchEnableViewTool);\n\t\tif ('willRenderShapeControls' in $$props) $$invalidate(15, willRenderShapeControls = $$props.willRenderShapeControls);\n\t\tif ('willRenderShapeTextControls' in $$props) $$invalidate(16, willRenderShapeTextControls = $$props.willRenderShapeTextControls);\n\t\tif ('willRenderHeaderTools' in $$props) $$invalidate(17, willRenderHeaderTools = $$props.willRenderHeaderTools);\n\t\tif ('beforeAddShape' in $$props) $$invalidate(18, beforeAddShape = $$props.beforeAddShape);\n\t\tif ('beforeRemoveShape' in $$props) $$invalidate(19, beforeRemoveShape = $$props.beforeRemoveShape);\n\t\tif ('beforeDeselectShape' in $$props) $$invalidate(20, beforeDeselectShape = $$props.beforeDeselectShape);\n\t\tif ('beforeSelectShape' in $$props) $$invalidate(21, beforeSelectShape = $$props.beforeSelectShape);\n\t\tif ('beforeUpdateShape' in $$props) $$invalidate(22, beforeUpdateShape = $$props.beforeUpdateShape);\n\t\tif ('enableMultiSelect' in $$props) $$invalidate(23, enableMultiSelect = $$props.enableMultiSelect);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[1] & /*$imageTransforms*/ 2048) {\n\t\t\t$$invalidate(38, presentationRotation = $imageTransforms ? $imageTransforms.rotation.z : 0);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$imageFlipX, $imageFlipY*/ 50331648 | $$self.$$.dirty[1] & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation*/ 1920) {\n\t\t\t//\n\t\t\t// Mapping coordinates\n\t\t\t//\n\t\t\t$$invalidate(27, mapScreenPointToImagePoint = point => _mapScreenPointToImagePoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*$imageFlipX, $imageFlipY*/ 50331648 | $$self.$$.dirty[1] & /*$rootRect, $imageSize, $imageTransformsInterpolated, presentationRotation*/ 1920) {\n\t\t\t$$invalidate(26, mapImagePointToScreenPoint = point => _mapImagePointToScreenPoint(point, $rootRect, $imageSize, $imageTransformsInterpolated.origin, $imageTransformsInterpolated.translation, presentationRotation, $imageTransformsInterpolated.scale, $imageFlipX, $imageFlipY));\n\t\t}\n\t};\n\n\treturn [\n\t\tretouchActiveTool,\n\t\tisActive,\n\t\tisActiveFraction,\n\t\tisVisible,\n\t\tstores,\n\t\tlocale,\n\t\tretouchTools,\n\t\tretouchToolShapes,\n\t\tretouchShapeControls,\n\t\tretouchWillRenderShapeStyleControls,\n\t\tretouchWillRenderHeaderTools,\n\t\tretouchWillRenderShapeControls,\n\t\tmarkupEditorWillStartInteraction,\n\t\tretouchEnableMoveTool,\n\t\tretouchEnableViewTool,\n\t\twillRenderShapeControls,\n\t\twillRenderShapeTextControls,\n\t\twillRenderHeaderTools,\n\t\tbeforeAddShape,\n\t\tbeforeRemoveShape,\n\t\tbeforeDeselectShape,\n\t\tbeforeSelectShape,\n\t\tbeforeUpdateShape,\n\t\tenableMultiSelect,\n\t\t$imageFlipY,\n\t\t$imageFlipX,\n\t\tmapImagePointToScreenPoint,\n\t\tmapScreenPointToImagePoint,\n\t\t$imageRotation,\n\t\trootRect,\n\t\timageManipulation,\n\t\timageSize,\n\t\timageRotation,\n\t\timageFlipX,\n\t\timageFlipY,\n\t\timageTransforms,\n\t\timageTransformsInterpolated,\n\t\tname,\n\t\tpresentationRotation,\n\t\t$imageTransformsInterpolated,\n\t\t$imageSize,\n\t\t$rootRect,\n\t\t$imageTransforms,\n\t\tshapeutil_toolActive_binding,\n\t\tmeasure_handler\n\t];\n}\n\nclass Retouch extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance$1,\n\t\t\tcreate_fragment$1,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\tname: 37,\n\t\t\t\tisActive: 1,\n\t\t\t\tisActiveFraction: 2,\n\t\t\t\tisVisible: 3,\n\t\t\t\tstores: 4,\n\t\t\t\tlocale: 5,\n\t\t\t\tretouchTools: 6,\n\t\t\t\tretouchToolShapes: 7,\n\t\t\t\tretouchShapeControls: 8,\n\t\t\t\tretouchActiveTool: 0,\n\t\t\t\tretouchWillRenderShapeStyleControls: 9,\n\t\t\t\tretouchWillRenderHeaderTools: 10,\n\t\t\t\tretouchWillRenderShapeControls: 11,\n\t\t\t\tmarkupEditorWillStartInteraction: 12,\n\t\t\t\tretouchEnableMoveTool: 13,\n\t\t\t\tretouchEnableViewTool: 14,\n\t\t\t\twillRenderShapeControls: 15,\n\t\t\t\twillRenderShapeTextControls: 16,\n\t\t\t\twillRenderHeaderTools: 17,\n\t\t\t\tbeforeAddShape: 18,\n\t\t\t\tbeforeRemoveShape: 19,\n\t\t\t\tbeforeDeselectShape: 20,\n\t\t\t\tbeforeSelectShape: 21,\n\t\t\t\tbeforeUpdateShape: 22,\n\t\t\t\tenableMultiSelect: 23\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget name() {\n\t\treturn this.$$.ctx[37];\n\t}\n\n\tget isActive() {\n\t\treturn this.$$.ctx[1];\n\t}\n\n\tset isActive(isActive) {\n\t\tthis.$$set({ isActive });\n\t\tflush();\n\t}\n\n\tget isActiveFraction() {\n\t\treturn this.$$.ctx[2];\n\t}\n\n\tset isActiveFraction(isActiveFraction) {\n\t\tthis.$$set({ isActiveFraction });\n\t\tflush();\n\t}\n\n\tget isVisible() {\n\t\treturn this.$$.ctx[3];\n\t}\n\n\tset isVisible(isVisible) {\n\t\tthis.$$set({ isVisible });\n\t\tflush();\n\t}\n\n\tget stores() {\n\t\treturn this.$$.ctx[4];\n\t}\n\n\tset stores(stores) {\n\t\tthis.$$set({ stores });\n\t\tflush();\n\t}\n\n\tget locale() {\n\t\treturn this.$$.ctx[5];\n\t}\n\n\tset locale(locale) {\n\t\tthis.$$set({ locale });\n\t\tflush();\n\t}\n\n\tget retouchTools() {\n\t\treturn this.$$.ctx[6];\n\t}\n\n\tset retouchTools(retouchTools) {\n\t\tthis.$$set({ retouchTools });\n\t\tflush();\n\t}\n\n\tget retouchToolShapes() {\n\t\treturn this.$$.ctx[7];\n\t}\n\n\tset retouchToolShapes(retouchToolShapes) {\n\t\tthis.$$set({ retouchToolShapes });\n\t\tflush();\n\t}\n\n\tget retouchShapeControls() {\n\t\treturn this.$$.ctx[8];\n\t}\n\n\tset retouchShapeControls(retouchShapeControls) {\n\t\tthis.$$set({ retouchShapeControls });\n\t\tflush();\n\t}\n\n\tget retouchActiveTool() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset retouchActiveTool(retouchActiveTool) {\n\t\tthis.$$set({ retouchActiveTool });\n\t\tflush();\n\t}\n\n\tget retouchWillRenderShapeStyleControls() {\n\t\treturn this.$$.ctx[9];\n\t}\n\n\tset retouchWillRenderShapeStyleControls(retouchWillRenderShapeStyleControls) {\n\t\tthis.$$set({ retouchWillRenderShapeStyleControls });\n\t\tflush();\n\t}\n\n\tget retouchWillRenderHeaderTools() {\n\t\treturn this.$$.ctx[10];\n\t}\n\n\tset retouchWillRenderHeaderTools(retouchWillRenderHeaderTools) {\n\t\tthis.$$set({ retouchWillRenderHeaderTools });\n\t\tflush();\n\t}\n\n\tget retouchWillRenderShapeControls() {\n\t\treturn this.$$.ctx[11];\n\t}\n\n\tset retouchWillRenderShapeControls(retouchWillRenderShapeControls) {\n\t\tthis.$$set({ retouchWillRenderShapeControls });\n\t\tflush();\n\t}\n\n\tget markupEditorWillStartInteraction() {\n\t\treturn this.$$.ctx[12];\n\t}\n\n\tset markupEditorWillStartInteraction(markupEditorWillStartInteraction) {\n\t\tthis.$$set({ markupEditorWillStartInteraction });\n\t\tflush();\n\t}\n\n\tget retouchEnableMoveTool() {\n\t\treturn this.$$.ctx[13];\n\t}\n\n\tset retouchEnableMoveTool(retouchEnableMoveTool) {\n\t\tthis.$$set({ retouchEnableMoveTool });\n\t\tflush();\n\t}\n\n\tget retouchEnableViewTool() {\n\t\treturn this.$$.ctx[14];\n\t}\n\n\tset retouchEnableViewTool(retouchEnableViewTool) {\n\t\tthis.$$set({ retouchEnableViewTool });\n\t\tflush();\n\t}\n\n\tget willRenderShapeControls() {\n\t\treturn this.$$.ctx[15];\n\t}\n\n\tset willRenderShapeControls(willRenderShapeControls) {\n\t\tthis.$$set({ willRenderShapeControls });\n\t\tflush();\n\t}\n\n\tget willRenderShapeTextControls() {\n\t\treturn this.$$.ctx[16];\n\t}\n\n\tset willRenderShapeTextControls(willRenderShapeTextControls) {\n\t\tthis.$$set({ willRenderShapeTextControls });\n\t\tflush();\n\t}\n\n\tget willRenderHeaderTools() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset willRenderHeaderTools(willRenderHeaderTools) {\n\t\tthis.$$set({ willRenderHeaderTools });\n\t\tflush();\n\t}\n\n\tget beforeAddShape() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset beforeAddShape(beforeAddShape) {\n\t\tthis.$$set({ beforeAddShape });\n\t\tflush();\n\t}\n\n\tget beforeRemoveShape() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset beforeRemoveShape(beforeRemoveShape) {\n\t\tthis.$$set({ beforeRemoveShape });\n\t\tflush();\n\t}\n\n\tget beforeDeselectShape() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset beforeDeselectShape(beforeDeselectShape) {\n\t\tthis.$$set({ beforeDeselectShape });\n\t\tflush();\n\t}\n\n\tget beforeSelectShape() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset beforeSelectShape(beforeSelectShape) {\n\t\tthis.$$set({ beforeSelectShape });\n\t\tflush();\n\t}\n\n\tget beforeUpdateShape() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tset beforeUpdateShape(beforeUpdateShape) {\n\t\tthis.$$set({ beforeUpdateShape });\n\t\tflush();\n\t}\n\n\tget enableMultiSelect() {\n\t\treturn this.$$.ctx[23];\n\t}\n\n\tset enableMultiSelect(enableMultiSelect) {\n\t\tthis.$$set({ enableMultiSelect });\n\t\tflush();\n\t}\n}\n\n// @ts-ignore\nvar _plugin_retouch = {\n    util: ['retouch', Retouch, ({ src }) => src && !isVideoFile(src)],\n};\n\nconst IconCross =\n    '<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"></path></path></g>';\n\nconst CharacterA =\n    '<path fill=\"none\" d=\"M9 15 L12 9 L15 15 M10 13.5 h3\" stroke=\"currentColor\" stroke-width=\".125em\"/>';\n\nvar _locale_en_gb = {\n    // generic\n    labelReset: 'Reset',\n    labelDefault: 'Default',\n    labelAuto: 'Auto',\n    labelNone: 'None',\n    labelEdit: 'Edit',\n    labelClose: 'Close',\n    labelSupportError: `{features} not supported on this browser`,\n    labelMemoryError: `The browser ran out of memory`,\n\n    // defaults\n    labelColor: 'Color',\n    labelWidth: 'Width',\n    labelSize: 'Size',\n    labelOffset: 'Offset',\n    labelAmount: 'Amount',\n    labelInset: 'Inset',\n    labelRadius: 'Radius',\n\n    // controls\n    labelColorPalette: 'Color palette',\n\n    // sizes\n    labelSizeExtraSmall: 'Extra small',\n    labelSizeSmall: 'Small',\n    labelSizeMediumSmall: 'Medium small',\n    labelSizeMedium: 'Medium',\n    labelSizeMediumLarge: 'Medium large',\n    labelSizeLarge: 'Large',\n    labelSizeExtraLarge: 'Extra large',\n\n    // default buttons\n\n    labelButtonCancel: 'Cancel',\n    labelButtonUndo: 'Undo',\n    labelButtonRedo: 'Redo',\n    labelButtonRevert: 'Revert',\n    labelButtonExport: 'Done',\n\n    // zoom\n    labelZoom: 'Zoom',\n    labelZoomIn: 'Zoom in',\n    labelZoomOut: 'Zoom out',\n    labelZoomFit: 'Fit to view',\n    labelZoomActual: 'Actual size',\n    iconZoomIn: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M8 12 h8 M12 8 v8\" />',\n    iconZoomOut: '<path stroke=\"currentColor\" stroke-width=\".125em\" d=\"M9 12 h6\" />',\n\n    // icons\n    iconSupportError: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"/><g><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"/><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"/></g>`,\n    iconButtonClose: IconCross,\n    iconButtonRevert: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M7.388 18.538a8 8 0 10-2.992-9.03\"/><path fill=\"currentColor\" d=\"M2.794 11.696L2.37 6.714l5.088 3.18z\"/><path d=\"M12 8v4M12 12l4 2\"/></g>`,\n    iconButtonUndo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M10 8h4c2.485 0 5 2 5 5s-2.515 5-5 5h-4\"/><path fill=\"currentColor\" d=\"M5 8l4-3v6z\"/></g>`,\n    iconButtonRedo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M14 8h-4c-2.485 0-5 2-5 5s2.515 5 5 5h4\"/><path fill=\"currentColor\" d=\"M19 8l-4-3v6z\"/></g>`,\n    iconButtonExport: `<polyline points=\"20 6 9 17 4 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"></polyline>`,\n\n    // status\n    statusLabelButtonClose: 'Close',\n    statusIconButtonClose: IconCross,\n\n    // new status options\n    statusImageLoadNone: 'Waiting for image',\n    statusImageLoadMinSize: 'Minimum image size is {minWidth} &times; {minHeight}',\n    statusImageLoadPrepare: 'Preparing image&hellip;',\n    statusImageLoadBusy: 'Loading image&hellip;',\n    statusImageLoadError: 'Error loading image',\n    statusImageProcessBusy: 'Processing image&hellip;',\n    statusImageProcessError: 'Error processing image',\n    statusImageUploadBusy: 'Uploading image&hellip;',\n    statusImageUploadError: 'Error uploading image',\n};\n\nconst MarkupEditor = {\n    shapeLabelButtonSelectSticker: 'Select image',\n    shapeIconButtonSelectSticker: `<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"0.0625em\"><path d=\"M8 21 L15 11 L19 15\"/><path d=\"M15 2 v5 h5\"/><path d=\"M8 2 h8 l4 4 v12 q0 4 -4 4 h-8 q-4 0 -4 -4 v-12 q0 -4 4 -4z\"/></g><circle fill=\"currentColor\" cx=\"10\" cy=\"8\" r=\"1.5\"/>`,\n\n    shapeIconButtonFlipHorizontal: `<g stroke=\"currentColor\" stroke-width=\".125em\"><path fill=\"none\" d=\"M6 6.5h5v11H6z\"/><path fill=\"currentColor\" d=\"M15 6.5h3v11h-3z\"/><path d=\"M11 4v16\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonFlipVertical: `<g stroke=\"currentColor\" stroke-width=\".125em\"><rect x=\"7\" y=\"8\" width=\"11\" height=\"5\" fill=\"none\"/><rect x=\"7\" y=\"17\" width=\"11\" height=\"2\" fill=\"currentColor\"/><line x1=\"5\" y1=\"13\" x2=\"20\" y2=\"13\"/></g>`,\n    shapeIconButtonRemove: `<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M7.5 7h9z\"/><path d=\"M7.916 9h8.168a1 1 0 01.99 1.14l-.972 6.862a2 2 0 01-1.473 1.653c-.877.23-1.753.345-2.629.345-.876 0-1.752-.115-2.628-.345a2 2 0 01-1.473-1.653l-.973-6.862A1 1 0 017.916 9z\" fill=\"currentColor\"/><rect fill=\"currentColor\" x=\"10\" y=\"5\" width=\"4\" height=\"3\" rx=\"1\"/></g>`,\n    shapeIconButtonDuplicate: `<g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M15 13.994V16a2 2 0 01-2 2H8a2 2 0 01-2-2v-5a2 2 0 012-2h2.142\" stroke=\"currentColor\" stroke-width=\".125em\"/><path d=\"M15 9V8a1 1 0 00-2 0v1h-1a1 1 0 000 2h1v1a1 1 0 002 0v-1h1a1 1 0 000-2h-1zm-4-4h6a2 2 0 012 2v6a2 2 0 01-2 2h-6a2 2 0 01-2-2V7a2 2 0 012-2z\" fill=\"currentColor\"/></g>`,\n    shapeIconButtonMoveToFront: `<g fill=\"none\" fill-rule=\"evenodd\"><rect fill=\"currentColor\" x=\"11\" y=\"13\" width=\"8\" height=\"2\" rx=\"1\"/><rect fill=\"currentColor\" x=\"9\" y=\"17\" width=\"10\" height=\"2\" rx=\"1\"/><path d=\"M11.364 8H10a5 5 0 000 10M12 6.5L14.5 8 12 9.5z\" stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\"/></g>`,\n\n    shapeIconButtonTextLayoutAutoWidth: `${CharacterA}`,\n    shapeIconButtonTextLayoutAutoHeight: `<g fill=\"currentColor\"><circle cx=\"4\" cy=\"12\" r=\"1.5\"/><circle cx=\"20\" cy=\"12\" r=\"1.5\"/></g>${CharacterA}`,\n    shapeIconButtonTextLayoutFixedSize: `<g fill=\"currentColor\"><circle cx=\"5\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"6\" r=\"1.5\"/><circle cx=\"19\" cy=\"19\" r=\"1.5\"/><circle cx=\"5\" cy=\"19\" r=\"1.5\"/></g>${CharacterA}`,\n\n    shapeTitleButtonTextLayoutAutoWidth: 'Auto width',\n    shapeTitleButtonTextLayoutAutoHeight: 'Auto height',\n    shapeTitleButtonTextLayoutFixedSize: 'Fixed size',\n\n    shapeTitleButtonFlipHorizontal: 'Flip Horizontal',\n    shapeTitleButtonFlipVertical: 'Flip Vertical',\n    shapeTitleButtonRemove: 'Remove',\n    shapeTitleButtonDuplicate: 'Duplicate',\n    shapeTitleButtonMoveToFront: 'Move to front',\n\n    shapeLabelInputText: 'Edit text',\n\n    shapeIconInputCancel: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M18 6L6 18M6 6l12 12\"/></g>`,\n    shapeIconInputConfirm: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><polyline points=\"20 6 9 17 4 12\"/></g>`,\n    shapeLabelInputCancel: 'Cancel',\n    shapeLabelInputConfirm: 'Confirm',\n\n    shapeLabelStrokeNone: 'No outline',\n\n    shapeLabelFontStyleNormal: 'Normal',\n    shapeLabelFontStyleBold: 'Bold',\n    shapeLabelFontStyleItalic: 'Italic',\n    shapeLabelFontStyleItalicBold: 'Bold Italic',\n\n    shapeTitleBackgroundColor: 'Fill color',\n\n    shapeTitleCornerRadius: 'Corner radius',\n\n    shapeTitleFontFamily: 'Font',\n    shapeTitleFontSize: 'Font size',\n    shapeTitleFontStyle: 'Font style',\n    shapeTitleLineHeight: 'Line height',\n\n    shapeTitleLineStart: 'Start',\n    shapeTitleLineEnd: 'End',\n    shapeTitleStrokeWidth: 'Line width',\n    shapeTitleStrokeColor: 'Line color',\n\n    shapeTitleLineDecorationBar: 'Bar',\n    shapeTitleLineDecorationCircle: 'Circle',\n    shapeTitleLineDecorationSquare: 'Square',\n    shapeTitleLineDecorationArrow: 'Arrow',\n    shapeTitleLineDecorationCircleSolid: 'Circle solid',\n    shapeTitleLineDecorationSquareSolid: 'Square solid',\n    shapeTitleLineDecorationArrowSolid: 'Arrow solid',\n\n    shapeIconLineDecorationBar: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M16,8 V16\"/></g>`,\n    shapeIconLineDecorationCircle: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"none\" stroke-width=\".125em\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquare: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"none\" stroke-width=\".125em\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrow: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16 M13,7 l6,5 l-6,5\" fill=\"none\"/></g>`,\n    shapeIconLineDecorationCircleSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><circle fill=\"currentColor\" cx=\"16\" cy=\"12\" r=\"4\"/></g>`,\n    shapeIconLineDecorationSquareSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\"><path stroke-width=\".125em\" d=\"M5,12 H12\"/><rect fill=\"currentColor\" x=\"12\" y=\"8\" width=\"8\" height=\"8\"/></g>`,\n    shapeIconLineDecorationArrowSolid: `<g stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\".125em\"><path d=\"M5,12 H16\"/><path d=\"M13,7 l6,5 l-6,5z\" fill=\"currentColor\"/></g>`,\n\n    shapeTitleColorTransparent: 'Transparent',\n    shapeTitleColorWhite: 'White',\n    shapeTitleColorSilver: 'Silver',\n    shapeTitleColorGray: 'Gray',\n    shapeTitleColorBlack: 'Black',\n    shapeTitleColorNavy: 'Navy',\n    shapeTitleColorBlue: 'Blue',\n    shapeTitleColorAqua: 'Aqua',\n    shapeTitleColorTeal: 'Teal',\n    shapeTitleColorOlive: 'Olive',\n    shapeTitleColorGreen: 'Green',\n    shapeTitleColorYellow: 'Yellow',\n    shapeTitleColorOrange: 'Orange',\n    shapeTitleColorRed: 'Red',\n    shapeTitleColorMaroon: 'Maroon',\n    shapeTitleColorFuchsia: 'Fuchsia',\n    shapeTitleColorPurple: 'Purple',\n\n    shapeTitleTextOutline: 'Text outline',\n    shapeTitleTextOutlineWidth: 'Width',\n\n    shapeTitleTextShadow: 'Text shadow',\n    shapeTitleTextShadowBlur: 'Blur',\n\n    shapeTitleTextColor: 'Font color',\n    shapeTitleTextAlign: 'Text align',\n    shapeTitleTextAlignLeft: 'Left align text',\n    shapeTitleTextAlignCenter: 'Center align text',\n    shapeTitleTextAlignRight: 'Right align text',\n\n    shapeIconTextAlignLeft: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"5\" y1=\"8\" x2=\"15\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"5\" y1=\"16\" x2=\"14\" y2=\"16\"/></g>`,\n    shapeIconTextAlignCenter: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"7\" y1=\"8\" x2=\"17\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"8\" y1=\"16\" x2=\"16\" y2=\"16\"/></g>`,\n    shapeIconTextAlignRight: `<g stroke-width=\".125em\" stroke=\"currentColor\"><line x1=\"9\" y1=\"8\" x2=\"19\" y2=\"8\"/><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/><line x1=\"11\" y1=\"16\" x2=\"19\" y2=\"16\"/></g>`,\n\n    shapeLabelToolMove: 'Move',\n    shapeLabelToolView: 'View',\n    shapeLabelToolSharpie: 'Sharpie',\n    shapeLabelToolEraser: 'Eraser',\n    shapeLabelToolPath: 'Path',\n    shapeLabelToolRectangle: 'Rectangle',\n    shapeLabelToolEllipse: 'Ellipse',\n    shapeLabelToolArrow: 'Arrow',\n    shapeLabelToolLine: 'Line',\n    shapeLabelToolText: 'Text',\n    shapeLabelToolPreset: 'Stickers',\n\n    shapeIconToolView: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10.98 9.703V2.567c0-1.19 1.19-1.785 1.784-1.785.595 0 1.784.595 1.784 1.785v3.568\"/><path d=\"M14.548 9.703V4.35c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.594 1.784 1.784v2.973\"/><path d=\"M18.116 10.244V7.271c0-1.19 1.19-1.784 1.784-1.784.595 0 1.785.595 1.785 1.784 0 1.19 0 8.92-1.19 12.488-1.19 3.569-10.704 4.758-13.678 0-2.973-4.757-2.973-4.757-4.163-6.541-1.189-1.784-1.153-2.974-.594-3.568.558-.595 1.784-1.19 2.973.594 1.277 1.916 2.07 2.907 2.379 2.974V5.487c0-1.19 1.19-1.784 1.784-1.784.595 0 1.784.595 1.784 1.784V8.46\"/></g>`,\n    shapeIconToolMove: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M6 2 L6 19 L18 13 Z M13 18 L16 24\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSharpie: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" stroke-width=\".125em\" fill=\"none\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolEraser: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" fill=\"none\"><g transform=\"translate(3, 15) rotate(-45)\"><rect x=\"0\" y=\"0\" width=\"18\" height=\"10\" rx=\"3\"/></g><line x1=\"11\" y1=\"21\" x2=\"18\" y2=\"21\"/><line x1=\"20\" y1=\"21\" x2=\"22\" y2=\"21\"/></g>`,\n    shapeIconToolPath: `<g stroke-width=\".125em\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\"><circle cx=\"21\" cy=\"3\" r=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"2\"/><circle cx=\"3\" cy=\"21\" r=\"2\"/><path d=\"M19 4 11 8 M8 11 4 19\"/></g>`,\n    shapeIconToolRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"1\" y=\"1\" width=\"22\" height=\"22\" rx=\"4\"/></g>`,\n    shapeIconToolEllipse: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"11\"/></g>`,\n    shapeIconToolArrow: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/><path d=\"m10 6 L21.5 1 L20 13.5\" fill=\"currentColor\" stroke=\"none\"/></g>`,\n    shapeIconToolLine: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><line x1=\"20\" y1=\"3\" x2=\"6\" y2=\"21\"/></g>`,\n    shapeIconToolText: `<g stroke=\"none\" fill=\"currentColor\" transform=\"translate(6,0)\"><path d=\"M8.14 20.085c.459 0 .901-.034 1.329-.102a8.597 8.597 0 001.015-.21v1.984c-.281.135-.695.247-1.242.336a9.328 9.328 0 01-1.477.133c-3.312 0-4.968-1.745-4.968-5.235V6.804H.344v-1.25l2.453-1.078L3.89.819h1.5v3.97h4.97v2.015H5.39v10.078c0 1.031.245 1.823.735 2.375s1.161.828 2.015.828z\"/>`,\n    shapeIconToolPreset: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"></path><path d=\"M20 17c-3 3-5 5-8 5\"></path></g>`,\n\n    shapeTitleSelectionMode: 'Selection mode',\n    shapeTitleBrushSize: 'Brush size',\n\n    shapeLabelSelectionModeNew: 'New',\n    shapeLabelSelectionModeAdd: 'Add',\n    shapeLabelSelectionModeSubtract: 'Remove',\n\n    shapeLabelToolSelectionBrush: 'Brush',\n    shapeLabelToolSelectionLassoo: 'Lassoo',\n    shapeLabelToolSelectionRectangle: 'Rectangle marquee',\n    shapeLabelToolSelectionEllipse: 'Ellipse marquee',\n    shapeLabelToolSelectionPolygon: 'Polygon marquee',\n\n    shapeIconSelectionModeNew: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.5 17H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v1.5\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" fill=\"currentColor\" fill-opacity=\".25\" rx=\"2\"/></g>`,\n    shapeIconSelectionModeAdd: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><path d=\"M13 15h4M15 13v4\"/></g>`,\n    shapeIconSelectionModeSubtract: `<g fill=\"none\" fill-rule=\"evenodd\" stroke=\"currentColor\"><path fill=\"currentColor\" fill-opacity=\".25\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 3a2 2 0 0 1 2 2v4h-6a2 2 0 0 0-1.995 1.85L9 11v6H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h10Z\"/><rect width=\"12\" height=\"12\" x=\"9\" y=\"9\" stroke-linecap=\"round\" stroke-linejoin=\"round\" rx=\"2\"/><path d=\"M13 15h4\"/></g>`,\n    shapeIconToolSelectionBrush: `<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M2.025 5c5.616-2.732 8.833-3.857 9.65-3.374C12.903 2.351.518 12.666 2.026 14 3.534 15.334 16.536.566 17.73 2.566 18.924 4.566 3.98 17.187 4.831 18c.851.813 9.848-6 11.643-6 1.087 0-2.53 5.11-2.92 7-.086.41 3.323-1.498 4.773-1 .494.17.64 2.317 1.319 3 .439.443 1.332.776 2.679 1\" stroke=\"currentColor\" fill-rule=\"evenodd\" stroke-linejoin=\"round\"/></g>`,\n    shapeIconToolSelectionLassoo: `<g fill=\"none\" fill-rule=\"evenodd\" stroke-width=\".125em\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M11.428 17.702a18.46 18.46 0 0 0 4.085-1.595c5.851-3.112 9.019-8.599 7.074-12.256-1.945-3.657-8.265-4.1-14.116-.988C2.619 5.974-.55 11.46 1.396 15.118c.63 1.186 1.72 2.033 3.105 2.532\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.833\" transform=\"rotate(-15 8 18.5)\"/><path stroke-linecap=\"round\" d=\"M5 18c3.347 1.048 5.514 1.881 6.5 2.5.859.54 1.517.994 1.5 2.364\"/></g>`,\n    shapeIconToolSelectionRectangle: `<g stroke-width=\".125em\" stroke=\"currentColor\"><path d=\"M9 1 h6 m4 0 h4v4 m0 4 v6 m0 4 v4h-4 m-4 0 h-6 m-4 0 h-4v-4 m0 -4 v-6 m0 -4 v-4h4\" fill=\"none\" /></g>`,\n    shapeIconToolSelectionEllipse: `<path stroke-width=\".125em\" stroke=\"currentColor\" d=\"M1.21 9.853a11.054 11.054 0 0 0 0 4.294m1.643 3.965a11.054 11.054 0 0 0 3.035 3.035m3.965 1.644a11.054 11.054 0 0 0 4.294 0m3.965-1.644a11.054 11.054 0 0 0 3.035-3.035m1.644-3.965a11.054 11.054 0 0 0 0-4.294m-1.644-3.965a11.054 11.054 0 0 0-3.035-3.035m-3.965-1.644a11.054 11.054 0 0 0-4.294 0M5.888 2.853a11.054 11.054 0 0 0-3.035 3.035\"/>`,\n    shapeIconToolSelectionPolygon:\n        '<g fill=\"none\" stroke=\"currentColor\" stroke-width=\".125em\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18h11V1L13 9 1 6l5 9 3 6v2\"/><ellipse cx=\"8\" cy=\"18.5\" rx=\"3.5\" ry=\"2.8\" transform=\"rotate(-2 8 18)\"/></g>',\n};\n\nvar _plugin_crop_locale_en_gb = {\n    cropLabel: 'Crop',\n    cropIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M23 17H9a2 2 0 0 1-2-2v-5m0-3V1 M1 7h14a2 2 0 0 1 2 2v7m0 4v3\"/></g>',\n    cropIconButtonRecenter: `<path stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linejoin=\"bevel\" d=\"M1.5 7.5v-6h6M1.5 16.5v6h6M22.5 16.5v6h-6M22.5 7.5v-6h-6\"/><circle cx=\"12\" cy=\"12\" r=\"3.5\" fill=\"currentColor\" stroke=\"none\"/>`,\n    cropIconButtonRotateLeft:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><rect x=\"3\" rx=\"1\" height=\"12\" width=\"12\" y=\"9\"/><path d=\"M15 5h-1a5 5 0 015 5 1 1 0 002 0 7 7 0 00-7-7h-1.374l.747-.747A1 1 0 0011.958.84L9.603 3.194a1 1 0 000 1.415l2.355 2.355a1 1 0 001.415-1.414l-.55-.55H15z\"/></g>',\n    cropIconButtonRotateRight:\n        '<g stroke=\"none\" fill=\"currentColor\"><path fill=\"none\" d=\"M-1-1h582v402H-1z\"/><path d=\"M11.177 5H10a5 5 0 00-5 5 1 1 0 01-2 0 7 7 0 017-7h1.374l-.747-.747A1 1 0 0112.042.84l2.355 2.355a1 1 0 010 1.415l-2.355 2.354a1 1 0 01-1.415-1.414l.55-.55z\"/><rect rx=\"1\" height=\"12\" width=\"12\" y=\"9\" x=\"9\"/></g>',\n    cropIconButtonFlipVertical:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M19.993 12.143H7a1 1 0 0 1-1-1V5.994a1 1 0 0 1 1.368-.93l12.993 5.15a1 1 0 0 1-.368 1.93z\"/><path d=\"M19.993 14a1 1 0 0 1 .368 1.93L7.368 21.078A1 1 0 0 1 6 20.148V15a1 1 0 0 1 1-1h12.993z\" opacity=\".6\"/></g>',\n    cropIconButtonFlipHorizontal:\n        '<g stroke=\"none\" fill=\"currentColor\"><path d=\"M11.93 7.007V20a1 1 0 0 1-1 1H5.78a1 1 0 0 1-.93-1.368l5.15-12.993a1 1 0 0 1 1.929.368z\"/><path d=\"M14 7.007V20a1 1 0 0 0 1 1h5.149a1 1 0 0 0 .93-1.368l-5.15-12.993A1 1 0 0 0 14 7.007z\" opacity=\".6\"/></g>',\n\n    cropIconSelectPreset: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"4\" width=\"10\" height=\"18\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"6\" y=\"12\" width=\"17\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropIconCropBoundary: `<g fill=\"currentColor\">\n        <rect opacity=\"{a}\" x=\"2\" y=\"3\" width=\"20\" height=\"20\" rx=\"1\"/>\n        <rect opacity=\"{b}\" x=\"7\" y=\"8\" width=\"10\" height=\"10\" rx=\"1\"/>\n        <rect opacity=\"{c}\" x=\"4\" y=\"8\" width=\"14\" height=\"14\" rx=\"1\"/>\n        <rect opacity=\"{d}\" x=\"12\" y=\"4\" width=\"10\" height=\"10\" rx=\"1\"/>\n    </g>`,\n\n    cropLabelButtonRecenter: 'Recenter',\n    cropLabelButtonRotateLeft: 'Rotate left',\n    cropLabelButtonRotateRight: 'Rotate right',\n    cropLabelButtonFlipHorizontal: 'Flip horizontal',\n    cropLabelButtonFlipVertical: 'Flip vertical',\n\n    cropLabelSelectPreset: 'Crop shape',\n\n    cropLabelCropBoundary: 'Crop boundary',\n    cropLabelCropBoundaryEdge: 'Edge of image',\n    cropLabelCropBoundaryNone: 'None',\n\n    cropLabelTabRotation: 'Rotation',\n    cropLabelTabZoom: 'Scale',\n};\n\nvar _plugin_fill_locale_en_gb = {\n    fillLabel: 'Fill',\n    fillIcon: `\n    <g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\">\n        <g transform=\"rotate(60, 12, 12)\">\n            <rect x=\"4\" y=\"4\" width=\"14\" height=\"16\" rx=\"3\"/>\n        </g>\n        <path d=\"M21 13 L21 21\"></path>\n        <path d=\"M4.5 12.5 L19 12.5\"></path>\n    </g>\n    `,\n};\n\nvar _plugin_filter_locale_en_gb = {\n    filterLabel: 'Filter',\n    filterIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M18.347 9.907a6.5 6.5 0 1 0-1.872 3.306M3.26 11.574a6.5 6.5 0 1 0 2.815-1.417 M10.15 17.897A6.503 6.503 0 0 0 16.5 23a6.5 6.5 0 1 0-6.183-8.51\"/></g>',\n    filterLabelChrome: 'Chrome',\n    filterLabelFade: 'Fade',\n    filterLabelCold: 'Cold',\n    filterLabelWarm: 'Warm',\n    filterLabelPastel: 'Pastel',\n    filterLabelMonoDefault: 'Mono',\n    filterLabelMonoNoir: 'Noir',\n    filterLabelMonoWash: 'Wash',\n    filterLabelMonoStark: 'Stark',\n    filterLabelSepiaDefault: 'Sepia',\n    filterLabelSepiaBlues: 'Blues',\n    filterLabelSepiaRust: 'Rust',\n    filterLabelSepiaColor: 'Color',\n};\n\nvar _plugin_finetune_locale_en_gb = {\n    finetuneLabel: 'Finetune',\n    finetuneIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M4 1v5.5m0 3.503V23M12 1v10.5m0 3.5v8M20 1v15.5m0 3.5v3M2 7h4M10 12h4M18 17h4\"/></g>',\n\n    finetuneLabelBrightness: 'Brightness',\n    finetuneLabelContrast: 'Contrast',\n    finetuneLabelSaturation: 'Saturation',\n    finetuneLabelExposure: 'Exposure',\n    finetuneLabelTemperature: 'Temperature',\n    finetuneLabelGamma: 'Gamma',\n    finetuneLabelClarity: 'Clarity',\n    finetuneLabelVignette: 'Vignette',\n};\n\nvar _plugin_resize_locale_en_gb = {\n    resizeLabel: 'Resize',\n    resizeIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><rect x=\"2\" y=\"12\" width=\"10\" height=\"10\" rx=\"2\"/><path d=\"M4 11.5V4a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-5.5\"/><path d=\"M14 10l3.365-3.365M14 6h4v4\"/></g>',\n\n    resizeLabelFormCaption: 'Image output size',\n\n    resizeLabelInputWidth: 'w',\n    resizeTitleInputWidth: 'Width',\n    resizeLabelInputHeight: 'h',\n    resizeTitleInputHeight: 'Height',\n\n    resizeTitleButtonMaintainAspectRatio: 'Maintain aspect ratio',\n\n    resizeIconButtonMaintainAspectRatio: `<defs><mask id=\"mask1\" x=\"-2\" y=\"-2\" width=\"24\" height=\"24\"><rect x=\"0\" y=\"0\" width=\"24\" height=\"10\" fill=\"#fff\" stroke=\"none\"/></mask></defs><g fill=\"none\" fill-rule=\"evenodd\"><g mask=\"url(#mask1)\"><path transform=\"translate(0 {activeFraction})\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" d=\"M9.401 10.205v-.804a2.599 2.599 0 0 1 5.198 0V17\"/></g><rect fill=\"currentColor\" x=\"7\" y=\"10\" width=\"10\" height=\"7\" rx=\"1.5\"/></g>`,\n};\n\nvar _plugin_decorate_locale_en_gb = {\n    decorateLabel: 'Decorate',\n    decorateIcon:\n        '<g fill=\"none\" fill-rule=\"evenodd\"><path stroke=\"currentColor\" stroke-width=\".125em\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 18.5l-6.466 3.4 1.235-7.2-5.23-5.1 7.228-1.05L12 2l3.233 6.55 7.229 1.05-5.231 5.1 1.235 7.2z\"/></g>',\n};\n\nvar _plugin_annotate_locale_en_gb = {\n    annotateLabel: 'Annotate',\n    annotateIcon:\n        '<g stroke-width=\".125em\" stroke=\"currentColor\" fill=\"none\"><path d=\"M17.086 2.914a2.828 2.828 0 1 1 4 4l-14.5 14.5-5.5 1.5 1.5-5.5 14.5-14.5z\"/></g>',\n};\n\nvar _plugin_sticker_locale_en_gb = {\n    stickerLabel: 'Sticker',\n    stickerIcon:\n        '<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M12 22c2.773 0 1.189-5.177 3-7 1.796-1.808 7-.25 7-3 0-5.523-4.477-10-10-10S2 6.477 2 12s4.477 10 10 10z\"/><path d=\"M20 17c-3 3-5 5-8 5\"/></g>',\n};\n\nvar _plugin_frame_locale_en_gb = {\n    frameLabel: 'Frame',\n    frameIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\">\n            <rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"4\"/>\n            <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"1\"/>\n        </g>`,\n\n    frameLabelMatSharp: 'Mat',\n    frameLabelMatRound: 'Bevel',\n    frameLabelLineSingle: 'Line',\n    frameLabelLineMultiple: 'Zebra',\n    frameLabelEdgeSeparate: 'Inset',\n    frameLabelEdgeOverlap: 'Plus',\n    frameLabelEdgeCross: 'Lumber',\n    frameLabelCornerHooks: 'Hook',\n    frameLabelPolaroid: 'Polaroid',\n};\n\nvar _plugin_redact_locale_en_gb = {\n    redactLabel: 'Redact',\n    redactIcon: `<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke=\"currentColor\" stroke-width=\".125em\"><path d=\"M 4 5 l 1 -1\"/><path d=\"M 4 10 l 6 -6\"/><path d=\"M 4 15 l 11 -11\"/><path d=\"M 4 20 l 16 -16\"/><path d=\"M 9 20 l 11 -11\"/><path d=\"M 14 20 l 6 -6\"/><path d=\"M 19 20 l 1 -1\"/></g>`,\n};\n\nvar _plugin_retouch_locale_en_gb = {\n    retouchLabel: 'Retouch',\n    retouchIcon: `\n    <g fill=\"none\" fill-rule=\"evenodd\"><path fill=\"currentColor\" d=\"m17 6-2-1-2 1 1-2-1-2 2 1 2-1-1 2zM5.5 5.5 3 4 .5 5.5 2 3 .5.5 3 2 5.5.5 4 3zM9 21l-3-1.5L3 21l1.5-3L3 15l3 1.5L9 15l-1.5 3z\"/><path stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"m9.266 6.705 13.529 13.529c-.071.78-.34 1.371-.765 1.796-.425.425-1.015.694-1.796.765h0L6.705 9.266c.071-.78.34-1.371.765-1.796.425-.425 1.015-.694 1.796-.765h0Z\"/><path stroke=\"currentColor\" stroke-width=\"1.5\" d=\"M12 9.5c-.657.323-1.157.657-1.5 1-.343.343-.677.843-1 1.5\"/></g>\n    `,\n};\n\nvar hasDefinedCustomElement = (name) => document.createElement(name).constructor !== HTMLElement;\n\nvar linkAccessors = (destination, origin) => {\n    const descriptors = Object.getOwnPropertyDescriptors(destination);\n    Object.keys(descriptors).forEach((key) => {\n        // props, set new setter and getter\n        if (!!descriptors[key]['get']) {\n            Object.defineProperty(origin, key, {\n                get: () => destination[key],\n                set: (value) => (destination[key] = value),\n            });\n        }\n        // method, copy reference\n        else {\n            origin[key] = destination[key];\n        }\n    });\n};\n\nvar hasDoctype = () => isBrowser() && document.doctype !== null;\n\nvar initEditorView = (target) => {\n    const accessors = {};\n    const { sub, pub } = pubsub();\n    // catch missing doctype\n    if (!hasDoctype())\n        console.warn('Browser is in quirks mode, add <!DOCTYPE html> to page to fix render issues');\n    // create editor core\n    const core = createImageEditor();\n    linkAccessors(core, accessors);\n    // create editor view\n    const view = attachEditorView(target, core.stores);\n    linkAccessors(view, accessors);\n    // listen for UI interaction and link to editor API (internals)\n    const unsubs = ['loadImage', 'processImage', 'abortProcessImage', 'abortLoadImage'].map((event) => view.on(event, (e) => {\n        // run core method, if returns a promise, we silence errors as those are passed to the UI via stores\n        const returned = core[event](e && e.detail);\n        if (returned instanceof Promise)\n            returned.catch(noop$1);\n    }));\n    // auto subscribes on each possible publisher\n    const subscribe = (event, cb) => {\n        const unsubInit = sub(event, cb);\n        const unsubCore = core.on(event, cb);\n        const unsubView = view.on(event, cb);\n        return () => {\n            unsubInit();\n            unsubCore();\n            unsubView();\n        };\n    };\n    // handles every event, useful for routing events from the options object\n    accessors.handleEvent = noop$1;\n    const handleEventUnsubs = editorEvents.map((type) => subscribe(type, (res) => accessors.handleEvent(type, res)));\n    // set up new api\n    defineMethods(accessors, {\n        on: subscribe,\n        updateImage: (src) => new Promise((resolve, reject) => {\n            // save history\n            const storedHistory = accessors.history.get();\n            const storedHistoryIndex = accessors.history.index;\n            // save state\n            const storedState = accessors.imageState;\n            // update image\n            core.loadImage(src)\n                .then((res) => {\n                // restore history\n                accessors.history.set(storedHistory);\n                accessors.history.index = storedHistoryIndex;\n                // restore state\n                accessors.imageState = storedState;\n                // done!\n                resolve(res);\n            })\n                .catch(reject);\n        }),\n        close: () => {\n            pub('close');\n        },\n        destroy: () => {\n            // unsub\n            [...unsubs, ...handleEventUnsubs].forEach((unsub) => unsub());\n            // destroy\n            view.destroy();\n            core.destroy();\n            // destroyed\n            pub('destroy');\n        },\n    });\n    setTimeout(() => pub('init', accessors), 0);\n    return accessors;\n};\n\nconst TAG = 'pintura-editor';\nvar _defineCustomElements = () => new Promise((resolve) => {\n    if (!PinturaImageEditorElement)\n        return resolve([]);\n    !hasDefinedCustomElement(TAG) && customElements.define(TAG, PinturaImageEditorElement);\n    customElements.whenDefined(TAG).then(() => resolve(document.querySelectorAll(TAG)));\n});\nconst PinturaImageEditorElement = isBrowser() &&\n    class extends HTMLElement {\n        static get observedAttributes() {\n            return ['src'];\n        }\n        constructor() {\n            super();\n            this._editor = undefined;\n            this._unsubs = undefined;\n        }\n        attributeChangedCallback(attrName, oldValue, newValue) {\n            this[attrName] = newValue;\n        }\n        connectedCallback() {\n            this._editor = initEditorView(this);\n            linkAccessors(this._editor, this);\n            this._editor.src = this.getAttribute('src');\n            this._unsubs = dispatchEditorEvents(this._editor, this);\n        }\n        disconnectedCallback() {\n            this._editor.destroy();\n            this._unsubs.forEach((unsub) => unsub());\n        }\n    };\n\nconst CSS_CLASS_NAME = 'pintura-editor';\nvar _appendEditor = (target, options = {}) => {\n    const element = isString(target)\n        ? document.querySelector(target)\n        : target;\n    if (!isElement(element))\n        return undefined;\n    options.class = options.class ? `${CSS_CLASS_NAME} ${options.class}` : CSS_CLASS_NAME;\n    const accessors = initEditorView(element);\n    return Object.assign(accessors, options);\n};\n\n/* src/core/ui/modal/index.svelte generated by Svelte v4.2.20 */\n\nconst { document: document_1, window: window_1 } = globals;\n\nfunction create_fragment(ctx) {\n\tlet t0;\n\tlet t1;\n\tlet div;\n\tlet mounted;\n\tlet dispose;\n\tadd_render_callback(/*onwindowresize*/ ctx[32]);\n\n\treturn {\n\t\tc() {\n\t\t\tt0 = space();\n\t\t\tt1 = space();\n\t\t\tdiv = element(\"div\");\n\t\t\tattr(div, \"class\", /*className*/ ctx[4]);\n\t\t\tattr(div, \"aria-modal\", \"true\");\n\t\t\tattr(div, \"aria-label\", \"Pintura\");\n\t\t\tattr(div, \"role\", \"dialog\");\n\t\t\tattr(div, \"tabindex\", \"-1\");\n\t\t\tset_style(div, \"--editor-modal\", 1);\n\t\t\tset_style(div, \"--viewport-pad-footer\", /*stylePadFooter*/ ctx[5]);\n\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[7]);\n\n\t\t\tset_style(div, \"height\", /*shouldSetHeight*/ ctx[14]\n\t\t\t? /*styleHeight*/ ctx[6]\n\t\t\t: undefined);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, t0, anchor);\n\t\t\tinsert(target, t1, anchor);\n\t\t\tinsert(target, div, anchor);\n\t\t\t/*div_binding*/ ctx[33](div);\n\n\t\t\tif (!mounted) {\n\t\t\t\tdispose = [\n\t\t\t\t\tlisten(window_1, \"keydown\", /*handleKey*/ ctx[13]),\n\t\t\t\t\tlisten(window_1, \"orientationchange\", /*spawnMeasureElement*/ ctx[16]),\n\t\t\t\t\tlisten(window_1, \"resize\", /*onwindowresize*/ ctx[32]),\n\t\t\t\t\tlisten(document_1, \"readystatechange\", /*handleReadyStateChange*/ ctx[15]),\n\t\t\t\t\tlisten(document_1.body, \"focusin\", function () {\n\t\t\t\t\t\tif (is_function(!/*hidden*/ ctx[1] && /*handleFocusIn*/ ctx[10])) (!/*hidden*/ ctx[1] && /*handleFocusIn*/ ctx[10]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(document_1.body, \"focusout\", function () {\n\t\t\t\t\t\tif (is_function(/*hasFocussedTextField*/ ctx[2] && /*handleFocusOut*/ ctx[11])) (/*hasFocussedTextField*/ ctx[2] && /*handleFocusOut*/ ctx[11]).apply(this, arguments);\n\t\t\t\t\t}),\n\t\t\t\t\tlisten(document_1.body, \"keydown\", /*handleTab*/ ctx[9]),\n\t\t\t\t\tlisten(div, \"wheel\", /*handleWheel*/ ctx[12], { passive: false })\n\t\t\t\t];\n\n\t\t\t\tmounted = true;\n\t\t\t}\n\t\t},\n\t\tp(new_ctx, dirty) {\n\t\t\tctx = new_ctx;\n\n\t\t\tif (dirty[0] & /*className*/ 16) {\n\t\t\t\tattr(div, \"class\", /*className*/ ctx[4]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*stylePadFooter*/ 32) {\n\t\t\t\tset_style(div, \"--viewport-pad-footer\", /*stylePadFooter*/ ctx[5]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleOpacity*/ 128) {\n\t\t\t\tset_style(div, \"opacity\", /*styleOpacity*/ ctx[7]);\n\t\t\t}\n\n\t\t\tif (dirty[0] & /*styleHeight*/ 64) {\n\t\t\t\tset_style(div, \"height\", /*shouldSetHeight*/ ctx[14]\n\t\t\t\t? /*styleHeight*/ ctx[6]\n\t\t\t\t: undefined);\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(t0);\n\t\t\t\tdetach(t1);\n\t\t\t\tdetach(div);\n\t\t\t}\n\n\t\t\t/*div_binding*/ ctx[33](null);\n\t\t\tmounted = false;\n\t\t\trun_all(dispose);\n\t\t}\n\t};\n}\n\nconst excludeDisabled = ':not([disabled])';\n\nfunction instance($$self, $$props, $$invalidate) {\n\tlet o;\n\tlet viewportRules;\n\tlet isOpaque;\n\tlet styleOpacity;\n\tlet styleHeight;\n\tlet stylePadFooter;\n\tlet className;\n\tlet scrollsBodyOnInteraction;\n\tlet $opacity;\n\tconst dispatch = createEventDispatcher();\n\tlet { root } = $$props;\n\tlet { preventZoomViewport = true } = $$props;\n\tlet { preventScrollBodyIfNeeded = true } = $$props;\n\tlet { preventFooterOverlapIfNeeded = true } = $$props;\n\tlet { preventModalAutoFocus = false } = $$props;\n\tlet { class: klass = undefined } = $$props;\n\tlet hidden = true;\n\tlet hiding = false;\n\tlet showing = false;\n\tlet doc = isBrowser() && document.documentElement;\n\tlet body = isBrowser() && document.body;\n\tlet head = isBrowser() && document.head;\n\tconst opacity = spring(0, { precision: 0.001, damping: 0.5 });\n\tcomponent_subscribe($$self, opacity, value => $$invalidate(31, $opacity = value));\n\n\t// animate hide and show\n\tconst opacityUnsub = opacity.subscribe(o => {\n\t\tif (showing && o >= 1) {\n\t\t\t$$invalidate(25, showing = false); // now shown\n\t\t\t$$invalidate(1, hidden = false);\n\t\t\tdispatch('show');\n\t\t} else if (hiding && o <= 0) {\n\t\t\t$$invalidate(24, hiding = false); // now hidden\n\t\t\t$$invalidate(1, hidden = true);\n\t\t\tdispatch('hide');\n\t\t}\n\t});\n\n\tlet hasFocussedTextField = false;\n\tlet viewportDefaults = undefined;\n\tlet themeDefaults = undefined;\n\tlet showTimeoutId = undefined;\n\tconst getViewPortElement = () => document.querySelector('meta[name=viewport]');\n\tconst getThemeElements = () => Array.from(document.querySelectorAll('meta[name=theme-color]'));\n\n\tconst show = () => {\n\t\t// is visible, or busy becoming visible\n\t\tif (showing || !hidden) return;\n\n\t\t// now in 'showing' transition\n\t\t$$invalidate(25, showing = true);\n\n\t\t// store default viewport element values\n\t\tconst viewportElement = getViewPortElement() || h('meta', { name: 'viewport' });\n\n\t\tviewportDefaults = !viewportDefaults && viewportElement.getAttribute('content');\n\n\t\tviewportElement.setAttribute('content', viewportRules + ((/cover/).test(viewportDefaults)\n\t\t? ',viewport-fit=cover'\n\t\t: ''));\n\n\t\tif (!viewportElement.parentNode) head.append(viewportElement);\n\n\t\t// store default theme element values\n\t\tconst backgroundColor = getComputedStyle(root).getPropertyValue('--color-background');\n\n\t\tconst themeElements = getThemeElements();\n\n\t\tif (themeElements.length) {\n\t\t\t// store defaults\n\t\t\tthemeDefaults = themeElements.map(element => element.getAttribute('content'));\n\t\t} else {\n\t\t\t// create element\n\t\t\tconst themeElement = h('meta', { name: 'theme-color' });\n\n\t\t\thead.append(themeElement);\n\t\t\tthemeElements.push(themeElement);\n\t\t}\n\n\t\t// update colors\n\t\tthemeElements.forEach(element => element.setAttribute('content', `rgb(${backgroundColor})`));\n\n\t\tclearTimeout(showTimeoutId);\n\t\tshowTimeoutId = setTimeout(() => opacity.set(1), 250);\n\t};\n\n\tconst hide = () => {\n\t\t// is hiding or already hidden\n\t\tif (hiding || hidden) return;\n\n\t\t// if previous command was show, we need to prevent the timeout from kicking off\n\t\tclearTimeout(showTimeoutId);\n\n\t\t// now in 'hiding' transition\n\t\t$$invalidate(24, hiding = true);\n\n\t\t// get a reference to the viewport element, it should be there as we created it earlier,\n\t\t// we restore defaults if the viewport metatag was defined, if not, we destroy it\n\t\tconst viewportElement = getViewPortElement();\n\n\t\tif (viewportDefaults) viewportElement.setAttribute('content', viewportDefaults); else viewportElement.remove();\n\n\t\t// restore colors\n\t\tconst themeElements = getThemeElements();\n\n\t\tif (themeDefaults) {\n\t\t\tthemeElements.forEach((element, index) => {\n\t\t\t\telement.setAttribute('content', themeDefaults[index]);\n\t\t\t});\n\t\t} else themeElements.forEach(element => element.remove());\n\n\t\t// let's hide!\n\t\topacity.set(0);\n\t};\n\n\tconst focusableElementSelector = `button${excludeDisabled},textarea${excludeDisabled},input${excludeDisabled},select${excludeDisabled},[tabindex=\"0\"]`;\n\n\t// if the focusable element is a radio we select all the radios\n\tconst toFocusableElements = element => {\n\t\tif (element.type === 'radio') return Array.from(root.querySelectorAll(`input[name=\"${element.name}\"]`));\n\t\treturn [element];\n\t};\n\n\tconst handleTab = e => {\n\t\tif (e.key !== 'Tab') return;\n\t\tconst activeElement = document.activeElement;\n\n\t\t// find the focusable elements, then we find the first and last focusable element groups (with for example radio buttons we need to get all the radios as only the first one will be selected on tab)\n\t\tconst focusableElements = root.querySelectorAll(focusableElementSelector);\n\n\t\tconst firstFocusableElements = toFocusableElements(focusableElements[0]);\n\t\tconst lastFocusableElements = toFocusableElements(focusableElements[focusableElements.length - 1]);\n\n\t\t// find new active element\n\t\tlet newActiveElement;\n\n\t\tif (e.shiftKey && firstFocusableElements.includes(activeElement)) {\n\t\t\tnewActiveElement = lastFocusableElements[0];\n\t\t} else if (!e.shiftKey && lastFocusableElements.includes(activeElement)) {\n\t\t\tnewActiveElement = firstFocusableElements[0];\n\t\t}\n\n\t\t// no new active element found so didnt reach end or begin of focus loop\n\t\tif (!newActiveElement) return;\n\n\t\t// focus new active element\n\t\tnewActiveElement.focus();\n\n\t\t// prevent focussing original target\n\t\te.preventDefault();\n\t};\n\n\t//\n\t// handle soft keyboard impact on window height\n\t//\n\tlet focusOutTimer;\n\n\tlet focusInWindowHeight;\n\n\tconst handleFocusIn = e => {\n\t\t// test if is text input element\n\t\tif (!isTextField(e.target)) return;\n\n\t\t// now focussing a field\n\t\t$$invalidate(2, hasFocussedTextField = true);\n\n\t\tfocusInWindowHeight = windowHeight;\n\t};\n\n\tconst handleFocusOut = e => {\n\t\t// test if is text input element\n\t\tif (!isTextField(e.target)) return;\n\n\t\t// prevent accidentally setting two timers\n\t\tclearTimeout(focusOutTimer);\n\n\t\t// test if window height changed, if not, no soft keyboard appeared and we can set false to focus state immidiately\n\t\tif (focusInWindowHeight === windowHeight) {\n\t\t\t$$invalidate(2, hasFocussedTextField = false);\n\t\t} else // soft keyboard might have appeared, test for window height change before setting unfocus state\n\t\t{\n\t\t\tconst windowCurrentHeight = windowHeight;\n\t\t\trunWhen(() => windowHeight !== windowCurrentHeight, () => $$invalidate(2, hasFocussedTextField = false));\n\t\t}\n\t};\n\n\tconst runWhen = (test, cb) => {\n\t\tconst frame = () => {\n\t\t\tif (test()) {\n\t\t\t\tcb();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\trequestAnimationFrame(frame);\n\t\t};\n\n\t\trequestAnimationFrame(frame);\n\t};\n\n\t//\n\t// end soft keyboard logic\n\t//\n\t// prevent mousewheel from scrolling content behind modal\n\tconst handleWheel = e => {\n\t\tif (e.target && (/PinturaStage/).test(e.target.className)) e.preventDefault();\n\t};\n\n\t// handle escape to close modal\n\tconst handleKey = e => {\n\t\t// get key type\n\t\tconst { key } = e;\n\n\t\t// only deal with escape key\n\t\tif (!(/escape/i).test(key)) return;\n\n\t\t// don't close when in an input or textuarea\n\t\tconst targetElement = e.target;\n\n\t\tif (targetElement && (/input|textarea/i).test(targetElement.nodeName)) return;\n\n\t\t// only close if I'm the top modal\n\t\tconst modals = document.querySelectorAll('.PinturaModal');\n\n\t\tif (modals[modals.length - 1] !== root) return;\n\n\t\t// request close\n\t\tdispatch('close');\n\t};\n\n\t// this logic scales modal to fit viewport height\n\tlet windowHeight = 0;\n\n\tlet windowHeightComputed;\n\n\t// if can't set dvh units we'll set height manually\n\tconst shouldSetHeight = isBrowser() ? !CSS.supports('height:100dvh') : false;\n\n\t// make sure window height is correct, this fixes issue when editor opens immidiately and the window height is too high on iOS\n\tfunction handleReadyStateChange() {\n\t\t$$invalidate(3, windowHeight = window.innerHeight);\n\t}\n\n\t// iOS measure actual page height so we can make optional use of available space\n\tlet measureElement;\n\n\tlet measureElementHeight = undefined;\n\n\tconst spawnMeasureElement = () => {\n\t\t// can't spawn more than one\n\t\tif (measureElement) return;\n\n\t\t// create measure element and append to body\n\t\tmeasureElement = h('div', {\n\t\t\tstyle: 'position:fixed;height:100vh;top:0'\n\t\t});\n\n\t\tbody.append(measureElement);\n\t};\n\n\tonMount(() => {\n\t\t// move focus to modal\n\t\tif (!preventModalAutoFocus) root.focus();\n\n\t\t// no need to run this logic if is not on iOS\n\t\tif (!preventFooterOverlapIfNeeded || !isIOS()) return;\n\n\t\t// will be used in first read to determine page height and bottom padding\n\t\tspawnMeasureElement();\n\n\t\t// position modal so it can be closed if viewport is zoomed in\n\t\tif (supportsVisualViewport() && visualViewport.scale > 1) {\n\t\t\t$$invalidate(0, root.style.left = `${visualViewport.offsetLeft}px`, root);\n\t\t\t$$invalidate(0, root.style.top = `${visualViewport.offsetTop}px`, root);\n\t\t}\n\t});\n\n\tafterUpdate(() => {\n\t\t// will only run on iOS\n\t\tif (!measureElement) return;\n\n\t\t// get height and store\n\t\t$$invalidate(27, measureElementHeight = measureElement.offsetHeight);\n\n\t\t// remove measure element\n\t\tmeasureElement.remove();\n\n\t\tmeasureElement = undefined;\n\t});\n\n\t//\n\t// document scrollbar\n\t//\n\tconst toggleDocumentStyles = isOpaque => {\n\t\tif (isOpaque) {\n\t\t\tdoc.classList.add('PinturaDocumentStyles');\n\t\t} else {\n\t\t\tdoc.classList.remove('PinturaDocumentStyles');\n\t\t}\n\t};\n\n\t//\n\t// document lock style for iOS 15.0\n\t//\n\tlet scrollOffsetY = undefined;\n\n\t// syncs height of doc lock with window\n\tconst syncHeight = () => doc.style.setProperty('--pintura-document-height', `${window.innerHeight}px`);\n\n\tconst toggleDocumentLock = isOpaque => {\n\t\tif (isOpaque) {\n\t\t\tscrollOffsetY = window.scrollY;\n\n\t\t\t// prevents safari on iOS 15.0 from scrolling body and showing footer on drag interaction\n\t\t\tdoc.classList.add('PinturaDocumentLock');\n\n\t\t\t// need to do this to sync height of initial window\n\t\t\tsyncHeight();\n\n\t\t\t// also sync on resize\n\t\t\twindow.addEventListener('resize', syncHeight);\n\t\t} else {\n\t\t\t// stop syncing height\n\t\t\twindow.removeEventListener('resize', syncHeight);\n\n\t\t\t// clean up\n\t\t\tdoc.classList.remove('PinturaDocumentLock');\n\n\t\t\tisNumber(scrollOffsetY) && window.scrollTo(0, scrollOffsetY);\n\t\t\tscrollOffsetY = undefined;\n\t\t}\n\t};\n\n\t//\n\t// clean up when removed\n\t//\n\tonDestroy(() => {\n\t\t// make sure no longer locking body element\n\t\tdoc.classList.remove('PinturaModalBodyLock');\n\n\t\t// clean up subs\n\t\topacityUnsub();\n\t});\n\n\tfunction onwindowresize() {\n\t\t$$invalidate(3, windowHeight = window_1.innerHeight);\n\t}\n\n\tfunction div_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\troot = $$value;\n\t\t\t$$invalidate(0, root);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('root' in $$props) $$invalidate(0, root = $$props.root);\n\t\tif ('preventZoomViewport' in $$props) $$invalidate(17, preventZoomViewport = $$props.preventZoomViewport);\n\t\tif ('preventScrollBodyIfNeeded' in $$props) $$invalidate(18, preventScrollBodyIfNeeded = $$props.preventScrollBodyIfNeeded);\n\t\tif ('preventFooterOverlapIfNeeded' in $$props) $$invalidate(19, preventFooterOverlapIfNeeded = $$props.preventFooterOverlapIfNeeded);\n\t\tif ('preventModalAutoFocus' in $$props) $$invalidate(20, preventModalAutoFocus = $$props.preventModalAutoFocus);\n\t\tif ('class' in $$props) $$invalidate(21, klass = $$props.class);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty[0] & /*showing, hiding, hidden*/ 50331650 | $$self.$$.dirty[1] & /*$opacity*/ 1) {\n\t\t\t$$invalidate(30, o = showing || hiding ? $opacity : hidden ? 0 : 1);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*preventZoomViewport*/ 131072) {\n\t\t\tviewportRules = 'width=device-width,height=device-height,initial-scale=1' + (preventZoomViewport\n\t\t\t? ',maximum-scale=1,user-scalable=0'\n\t\t\t: '');\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*showing, hidden, hiding*/ 50331650) {\n\t\t\t$$invalidate(28, isOpaque = !showing && !hidden && !hiding);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*hasFocussedTextField, windowHeight*/ 12) {\n\t\t\tif (!hasFocussedTextField) {\n\t\t\t\t$$invalidate(26, windowHeightComputed = windowHeight);\n\t\t\t}\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*o*/ 1073741824) {\n\t\t\t$$invalidate(7, styleOpacity = o);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*windowHeightComputed*/ 67108864) {\n\t\t\t$$invalidate(6, styleHeight = `${windowHeightComputed}px`);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*measureElementHeight, windowHeight*/ 134217736) {\n\t\t\t$$invalidate(5, stylePadFooter = isNumber(measureElementHeight)\n\t\t\t? `--viewport-pad-footer:${measureElementHeight > windowHeight ? 0 : 1}`\n\t\t\t: undefined);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*klass*/ 2097152) {\n\t\t\t$$invalidate(4, className = arrayJoin(['pintura-editor', 'PinturaModal', klass]));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*isOpaque*/ 268435456) {\n\t\t\ttoggleDocumentStyles(isOpaque);\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*preventScrollBodyIfNeeded*/ 262144) {\n\t\t\t$$invalidate(29, scrollsBodyOnInteraction = preventScrollBodyIfNeeded && isIOS() && (/15_/).test(navigator.userAgent));\n\t\t}\n\n\t\tif ($$self.$$.dirty[0] & /*scrollsBodyOnInteraction, isOpaque*/ 805306368) {\n\t\t\tscrollsBodyOnInteraction && toggleDocumentLock(isOpaque);\n\t\t}\n\t};\n\n\treturn [\n\t\troot,\n\t\thidden,\n\t\thasFocussedTextField,\n\t\twindowHeight,\n\t\tclassName,\n\t\tstylePadFooter,\n\t\tstyleHeight,\n\t\tstyleOpacity,\n\t\topacity,\n\t\thandleTab,\n\t\thandleFocusIn,\n\t\thandleFocusOut,\n\t\thandleWheel,\n\t\thandleKey,\n\t\tshouldSetHeight,\n\t\thandleReadyStateChange,\n\t\tspawnMeasureElement,\n\t\tpreventZoomViewport,\n\t\tpreventScrollBodyIfNeeded,\n\t\tpreventFooterOverlapIfNeeded,\n\t\tpreventModalAutoFocus,\n\t\tklass,\n\t\tshow,\n\t\thide,\n\t\thiding,\n\t\tshowing,\n\t\twindowHeightComputed,\n\t\tmeasureElementHeight,\n\t\tisOpaque,\n\t\tscrollsBodyOnInteraction,\n\t\to,\n\t\t$opacity,\n\t\tonwindowresize,\n\t\tdiv_binding\n\t];\n}\n\nclass Modal extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(\n\t\t\tthis,\n\t\t\toptions,\n\t\t\tinstance,\n\t\t\tcreate_fragment,\n\t\t\tsafe_not_equal,\n\t\t\t{\n\t\t\t\troot: 0,\n\t\t\t\tpreventZoomViewport: 17,\n\t\t\t\tpreventScrollBodyIfNeeded: 18,\n\t\t\t\tpreventFooterOverlapIfNeeded: 19,\n\t\t\t\tpreventModalAutoFocus: 20,\n\t\t\t\tclass: 21,\n\t\t\t\tshow: 22,\n\t\t\t\thide: 23\n\t\t\t},\n\t\t\tnull,\n\t\t\t[-1, -1]\n\t\t);\n\t}\n\n\tget root() {\n\t\treturn this.$$.ctx[0];\n\t}\n\n\tset root(root) {\n\t\tthis.$$set({ root });\n\t\tflush();\n\t}\n\n\tget preventZoomViewport() {\n\t\treturn this.$$.ctx[17];\n\t}\n\n\tset preventZoomViewport(preventZoomViewport) {\n\t\tthis.$$set({ preventZoomViewport });\n\t\tflush();\n\t}\n\n\tget preventScrollBodyIfNeeded() {\n\t\treturn this.$$.ctx[18];\n\t}\n\n\tset preventScrollBodyIfNeeded(preventScrollBodyIfNeeded) {\n\t\tthis.$$set({ preventScrollBodyIfNeeded });\n\t\tflush();\n\t}\n\n\tget preventFooterOverlapIfNeeded() {\n\t\treturn this.$$.ctx[19];\n\t}\n\n\tset preventFooterOverlapIfNeeded(preventFooterOverlapIfNeeded) {\n\t\tthis.$$set({ preventFooterOverlapIfNeeded });\n\t\tflush();\n\t}\n\n\tget preventModalAutoFocus() {\n\t\treturn this.$$.ctx[20];\n\t}\n\n\tset preventModalAutoFocus(preventModalAutoFocus) {\n\t\tthis.$$set({ preventModalAutoFocus });\n\t\tflush();\n\t}\n\n\tget class() {\n\t\treturn this.$$.ctx[21];\n\t}\n\n\tset class(klass) {\n\t\tthis.$$set({ class: klass });\n\t\tflush();\n\t}\n\n\tget show() {\n\t\treturn this.$$.ctx[22];\n\t}\n\n\tget hide() {\n\t\treturn this.$$.ctx[23];\n\t}\n}\n\n// we export a function that renders the view as to not export svelte component related code to outside the ui dir\nvar createModal = (options = {}, parent) => new Modal({\n    target: parent || document.body,\n    props: {\n        class: options.class,\n        preventModalAutoFocus: options.preventModalAutoFocus,\n        preventZoomViewport: options.preventZoomViewport,\n        preventScrollBodyIfNeeded: options.preventScrollBodyIfNeeded,\n        preventFooterOverlapIfNeeded: options.preventFooterOverlapIfNeeded,\n    },\n});\n\nvar _openEditor = (options = {}, parent) => {\n    // set up pub/sub for the app layer\n    const { sub, pub } = pubsub();\n    const accessors = {};\n    const modal = createModal(options, parent);\n    const hide = () => {\n        if (!modal.hide)\n            return; // was destroyed\n        modal.hide();\n    };\n    const show = () => {\n        if (!modal.show)\n            return; // was destroyed\n        modal.show();\n    };\n    const view = initEditorView(modal.root);\n    linkAccessors(view, accessors);\n    // link up handle event\n    accessors.handleEvent = noop$1;\n    view.handleEvent = (type, detail) => {\n        // need to do this so we pass correct accessors\n        if (type === 'init')\n            return accessors.handleEvent(type, accessors);\n        // other events\n        accessors.handleEvent(type, detail);\n    };\n    // route close request from view to modal\n    view.on('close', async () => {\n        const { willClose } = options;\n        if (!willClose)\n            return hide();\n        const shouldClose = await willClose();\n        if (shouldClose)\n            hide();\n    });\n    const subscribe = (event, cb) => {\n        // capture modal related events\n        if (/show|hide/.test(event))\n            return sub(event, cb);\n        // route rest of events to view\n        return view.on(event, cb);\n    };\n    const modalHandleEventUnsubs = ['show', 'hide'].map((type) => subscribe(type, (detail) => accessors.handleEvent(type, detail)));\n    // cleans up view\n    const destroy = () => {\n        // unsub\n        modalHandleEventUnsubs.forEach((unsub) => unsub());\n        // remove\n        hide();\n        modal.$destroy();\n        view.destroy();\n    };\n    defineMethods(accessors, {\n        on: subscribe,\n        destroy,\n        hide,\n        show,\n    });\n    // add element root query\n    Object.defineProperty(accessors, 'modal', {\n        get: () => modal.root,\n        set: () => undefined,\n    });\n    // route modal events\n    modal.$on('close', view.close);\n    modal.$on('show', () => pub('show'));\n    modal.$on('hide', () => {\n        pub('hide');\n        if (options.enableAutoDestroy !== false)\n            destroy();\n    });\n    // modal behavior\n    if (options.enableAutoHide !== false)\n        view.on('process', hide);\n    view.on('loadstart', show);\n    // test if should\n    if (options.enableButtonClose !== false)\n        options.enableButtonClose = true;\n    // delete class\n    delete options.class;\n    // update props\n    Object.assign(accessors, options);\n    return accessors;\n};\n\nvar _overlayEditor = (target, options) => {\n    const editor = _appendEditor(target, {\n        ...options,\n        layout: 'overlay',\n    });\n    return editor;\n};\n\n// helper method to calculate end style params that are passed to lineEnd style functions\nconst getLineEndParams = (start, end, strokeWidth, scalar = 5, isSolid) => {\n    const direction = vectorCreate(end.x - start.x, end.y - start.y);\n    const normal = vectorNormalize(direction);\n    const scaledSize = scalar * strokeWidth;\n    let scaledSizeHalf;\n    // solid\n    if (isSolid) {\n        scaledSizeHalf = scaledSize * 0.5;\n    }\n    // stroke\n    else {\n        scaledSizeHalf = Math.ceil((scaledSize - 1) * 0.5);\n    }\n    const offset = vectorMultiply(vectorClone(normal), scaledSizeHalf);\n    return {\n        anchor: vectorClone(start),\n        offset,\n        normal,\n        solid: isSolid,\n        size: scaledSize,\n        sizeHalf: scaledSizeHalf,\n    };\n};\n// various available styles\nconst lineEndStyleArrow = (shape, options, anchorRef) => {\n    const { strokeWidth, strokeColor, strokeJoin, strokeCap, ...shapePropsRest } = shape;\n    const { anchor, offset, normal, solid, size, sizeHalf } = options;\n    const x = anchor.x;\n    const y = anchor.y;\n    const tipOffset = vectorMultiply(vectorClone(normal), size);\n    const inset = vectorCreate(x + tipOffset.x, y + tipOffset.y);\n    vectorMultiply(tipOffset, 0.55);\n    if (solid && !shape.bitmap) {\n        // move back so arrow triangle overlaps with end of line (otherwise line sticks out of triangle tip)\n        vectorAdd(anchorRef, offset);\n        const arrowOffset = vectorMultiply(vectorClone(normal), sizeHalf * 0.5);\n        return [\n            {\n                ...shapePropsRest,\n                points: [\n                    vectorCreate(x - arrowOffset.x, y - arrowOffset.y),\n                    vectorCreate(inset.x - tipOffset.y, inset.y + tipOffset.x),\n                    vectorCreate(inset.x + tipOffset.y, inset.y - tipOffset.x),\n                ],\n                pathClose: true,\n                backgroundColor: strokeColor,\n            },\n        ];\n    }\n    // this prevents trouble with sharp line rendering in webgl\n    const p = vectorMultiply(vectorPerpendicular(vectorClone(normal)), 0.5);\n    const tipLeft = vectorCreate(x - p.x, y - p.y);\n    const tipRight = vectorCreate(x + p.x, y + p.y);\n    return [\n        {\n            ...shapePropsRest,\n            points: [\n                vectorCreate(inset.x + tipOffset.y, inset.y - tipOffset.x),\n                tipLeft,\n                vectorCreate(x, y),\n                tipRight,\n                vectorCreate(inset.x - tipOffset.y, inset.y + tipOffset.x),\n            ],\n            backgroundColor: solid ? strokeColor : undefined,\n            pathClose: solid,\n            strokeWidth,\n            strokeColor,\n            strokeJoin,\n            strokeCap,\n        },\n    ];\n};\nconst lineEndStyleCircle = (shape, options, anchorRef) => {\n    const { strokeWidth, strokeColor, ...shapePropsRest } = shape;\n    const { anchor, solid, offset, normal, sizeHalf } = options;\n    // update anchor point position\n    vectorAdd(anchorRef, offset);\n    // if solid, move line slightly towards circle as to make them overlap\n    if (solid)\n        vectorAdd(anchorRef, vectorInvert(vectorClone(normal)));\n    return [\n        {\n            ...shapePropsRest,\n            x: anchor.x,\n            y: anchor.y,\n            rx: sizeHalf,\n            ry: sizeHalf,\n            backgroundColor: solid ? strokeColor : undefined,\n            strokeWidth: solid ? undefined : strokeWidth,\n            strokeColor: solid ? undefined : strokeColor,\n        },\n    ];\n};\nconst lineEndStyleBar = (shape, options) => {\n    const { strokeWidth, strokeColor, strokeJoin, strokeCap, ...shapePropsRest } = shape;\n    const { anchor, offset } = options;\n    return [\n        {\n            ...shapePropsRest,\n            points: [\n                vectorCreate(anchor.x - offset.y, anchor.y + offset.x),\n                vectorCreate(anchor.x + offset.y, anchor.y - offset.x),\n            ],\n            strokeWidth,\n            strokeColor,\n            strokeJoin,\n            strokeCap,\n        },\n    ];\n};\nconst lineEndStyleSquare = (shape, options, anchorRef) => {\n    const { strokeWidth, strokeColor, ...shapePropsRest } = shape;\n    const { anchor, solid, offset, normal, sizeHalf } = options;\n    // update anchor point position\n    vectorAdd(anchorRef, offset);\n    return [\n        {\n            ...shapePropsRest,\n            x: anchor.x - sizeHalf,\n            y: anchor.y - sizeHalf,\n            width: sizeHalf * 2,\n            height: sizeHalf * 2,\n            rotation: vectorAngle(normal),\n            backgroundColor: solid ? strokeColor : undefined,\n            strokeWidth: solid ? undefined : strokeWidth,\n            strokeColor: solid ? undefined : strokeColor,\n        },\n    ];\n};\n// this method parses the shape and checks if lineStart or lineEnd is being used\nconst createLineEndProcessor = (styles = {}) => (shape) => {\n    if (!shape.lineStart && !shape.lineEnd)\n        return;\n    // resulting shapes\n    const res = [];\n    const { x1, y1, x2, y2, lineStart, lineEnd, strokeWidth, strokeColor, strokeJoin, strokeCap, strokeDash, lineStartScalar, lineEndScalar, bitmap, aboveFrame, opacity, } = shape;\n    const start = vectorCreate(x1, y1);\n    const end = vectorCreate(x2, y2);\n    const points = [start, end];\n    const sharedStyles = {\n        // ...shapeRestParams,\n        bitmap,\n        aboveFrame,\n        opacity,\n        strokeColor,\n        strokeWidth,\n        strokeJoin,\n        strokeCap,\n        lineStartScalar,\n        lineEndScalar,\n    };\n    // handle lineStart\n    if (lineStart) {\n        const [style, solid] = lineStart.split('-');\n        const process = styles[style];\n        if (process) {\n            const lineStartParams = getLineEndParams(start, end, strokeWidth, lineStartScalar || lineEndScalar, !!solid);\n            res.push(...process(sharedStyles, lineStartParams, start));\n        }\n    }\n    // handle lineEnd\n    if (lineEnd) {\n        const [style, solid] = lineEnd.split('-');\n        const process = styles[style];\n        if (process) {\n            const lineEndParams = getLineEndParams(end, start, strokeWidth, lineEndScalar, !!solid);\n            res.push(...process(sharedStyles, lineEndParams, end));\n        }\n    }\n    return [\n        // return inner path\n        {\n            ...sharedStyles,\n            strokeDash,\n            points,\n        },\n        // add line end styles\n        ...res,\n    ];\n};\n// the default line end styles available, can import and extend\nconst createDefaultLineEndStyles = () => ({\n    arrow: lineEndStyleArrow,\n    circle: lineEndStyleCircle,\n    square: lineEndStyleSquare,\n    bar: lineEndStyleBar,\n});\n\nconst safeFactor = (value, factor) => {\n    const v = parseFloat(value) * factor;\n    return isString(value) ? `${v}%` : v;\n};\nconst toValue = (value, total) => (isString(value) ? toPixelValue(value, total) : value);\nconst frameStyleSolid = (shape) => [\n    {\n        ...shape,\n        frameStyle: 'line',\n        frameInset: 0,\n        frameOffset: 0,\n        frameSize: shape.frameSize ? safeFactor(shape.frameSize, 2) : '2.5%',\n        frameRadius: shape.frameRound ? safeFactor(shape.frameSize, 2) : 0,\n    },\n];\nconst frameStyleNine = ({ width: contextWidth, height: contextHeight, frameImage, frameSize = '15%', frameOutset = 0, frameSlices = {\n    x1: 0.15,\n    y1: 0.15,\n    x2: 0.85,\n    y2: 0.85,\n}, }, { isPreview }) => {\n    // need a frame image to render a frame\n    if (!frameImage)\n        return [];\n    const contextSize = Math.sqrt(contextWidth * contextHeight);\n    const size = toValue(frameSize, contextSize);\n    const width = isPreview ? size : Math.round(size);\n    const height = width;\n    const outset = toValue(frameOutset, contextSize);\n    const outsetDouble = outset * 2;\n    const { x1, x2, y1, y2 } = frameSlices;\n    const shapeCoordinates = {\n        x0: 0,\n        y0: 0,\n        x1: width,\n        y1: height,\n        x2: contextWidth - width,\n        y2: contextHeight - height,\n        x3: contextWidth,\n        y3: contextHeight,\n        cw: width,\n        ch: height,\n        ew: contextWidth - width - width,\n        eh: contextHeight - height - height,\n    };\n    const overlap = isPreview ? 1 : 0;\n    const overlapDouble = overlap * 2;\n    const expandsCanvas = outset > 0;\n    const cornerGeneric = {\n        expandsCanvas,\n        width: shapeCoordinates.cw,\n        height: shapeCoordinates.ch,\n        backgroundImage: frameImage,\n    };\n    return [\n        // edges\n        {\n            // t\n            expandsCanvas,\n            x: shapeCoordinates.x1 - overlap - outset,\n            y: shapeCoordinates.y0 - outset,\n            width: shapeCoordinates.ew + overlapDouble + outsetDouble,\n            height: shapeCoordinates.ch,\n            backgroundCorners: [\n                { x: x1, y: 0 },\n                { x: x2, y: 0 },\n                { x: x2, y: y1 },\n                { x: x1, y: y1 },\n            ],\n            backgroundImage: frameImage,\n        },\n        {\n            // b\n            expandsCanvas,\n            x: shapeCoordinates.x1 - overlap - outset,\n            y: shapeCoordinates.y2 + outset,\n            width: shapeCoordinates.ew + overlapDouble + outsetDouble,\n            height: shapeCoordinates.ch,\n            backgroundCorners: [\n                { x: x1, y: y2 },\n                { x: x2, y: y2 },\n                { x: x2, y: 1 },\n                { x: x1, y: 1 },\n            ],\n            backgroundImage: frameImage,\n        },\n        {\n            // l\n            expandsCanvas,\n            x: shapeCoordinates.x0 - outset,\n            y: shapeCoordinates.y1 - overlap - outset,\n            width: shapeCoordinates.cw,\n            height: shapeCoordinates.eh + overlapDouble + outsetDouble,\n            backgroundCorners: [\n                { x: 0, y: y1 },\n                { x: x1, y: y1 },\n                { x: x1, y: y2 },\n                { x: 0, y: y2 },\n            ],\n            backgroundImage: frameImage,\n        },\n        {\n            // r\n            expandsCanvas,\n            x: shapeCoordinates.x2 + outset,\n            y: shapeCoordinates.y1 - overlap - outset,\n            width: shapeCoordinates.cw,\n            height: shapeCoordinates.eh + overlapDouble + outsetDouble,\n            backgroundCorners: [\n                { x: x2, y: y1 },\n                { x: 1, y: y1 },\n                { x: 1, y: y2 },\n                { x: x2, y: y2 },\n            ],\n            backgroundImage: frameImage,\n        },\n        // corners\n        {\n            // tl\n            ...cornerGeneric,\n            x: shapeCoordinates.x0 - outset,\n            y: shapeCoordinates.y0 - outset,\n            backgroundCorners: [\n                { x: 0, y: 0 },\n                { x: x1, y: 0 },\n                { x: x1, y: y1 },\n                { x: 0, y: y1 },\n            ],\n        },\n        {\n            // tr\n            ...cornerGeneric,\n            x: shapeCoordinates.x2 + outset,\n            y: shapeCoordinates.y0 - outset,\n            backgroundCorners: [\n                { x: x2, y: 0 },\n                { x: 1, y: 0 },\n                { x: 1, y: y1 },\n                { x: x2, y: y1 },\n            ],\n        },\n        {\n            // br\n            ...cornerGeneric,\n            x: shapeCoordinates.x2 + outset,\n            y: shapeCoordinates.y2 + outset,\n            backgroundCorners: [\n                { x: x2, y: y2 },\n                { x: 1, y: y2 },\n                { x: 1, y: 1 },\n                { x: x2, y: 1 },\n            ],\n        },\n        {\n            // bl\n            ...cornerGeneric,\n            x: shapeCoordinates.x0 - outset,\n            y: shapeCoordinates.y2 + outset,\n            backgroundCorners: [\n                { x: 0, y: y2 },\n                { x: x1, y: y2 },\n                { x: x1, y: 1 },\n                { x: 0, y: 1 },\n            ],\n        },\n    ];\n};\nconst frameStyleLine = ({ x, y, width, height, frameInset = '3.5%', frameSize = '.25%', frameColor = [1, 1, 1], frameOffset = '5%', frameAmount = 1, frameRadius = 0, expandsCanvas = false, }, { isPreview }) => {\n    const size = Math.sqrt(width * height);\n    let frameSizeValue = toValue(frameSize, size);\n    const frameInsetValue = toValue(frameInset, size);\n    const frameOffsetValue = toValue(frameOffset, size);\n    let center = 0;\n    if (!isPreview) {\n        frameSizeValue = Math.max(1, Math.round(frameSizeValue));\n        center = frameSizeValue % 2 == 0 ? 0 : 0.5;\n    }\n    const r = toValue(safeFactor(frameRadius, frameAmount), size);\n    return new Array(frameAmount).fill(undefined).map((_, index) => {\n        const offset = frameOffsetValue * index;\n        let left = x + frameInsetValue + offset;\n        let top = y + frameInsetValue + offset;\n        let right = x + width - frameInsetValue - offset;\n        let bottom = y + height - frameInsetValue - offset;\n        if (!isPreview) {\n            left = Math.round(left);\n            top = Math.round(top);\n            right = Math.round(right);\n            bottom = Math.round(bottom);\n        }\n        const radius = r > 0 ? r - offset : 0;\n        return {\n            x: left + center,\n            y: top + center,\n            width: right - left, // - (center ? 1 : 0),\n            height: bottom - top, // - (center ? 1 : 0),\n            cornerRadius: radius,\n            strokeWidth: frameSizeValue,\n            strokeColor: frameColor,\n            expandsCanvas,\n        };\n    });\n};\nconst frameStyleEdge = ({ x, y, width, height, frameSize = '.25%', frameOffset = 0, frameInset = '2.5%', frameColor = [1, 1, 1], }, { isPreview }) => {\n    const size = Math.sqrt(width * height);\n    let frameSizeValue = toValue(frameSize, size);\n    let frameInsetValue = toValue(frameInset, size);\n    let frameOffsetValue = toValue(frameOffset, size);\n    let center = 0;\n    if (!isPreview) {\n        frameSizeValue = Math.max(1, Math.round(frameSizeValue));\n        frameInsetValue = Math.round(frameInsetValue);\n        frameOffsetValue = Math.round(frameOffsetValue);\n        center = frameSizeValue % 2 == 0 ? 0 : 0.5;\n    }\n    const offset = frameOffsetValue - frameInsetValue;\n    const left = x + frameInsetValue + center;\n    const top = y + frameInsetValue + center;\n    const right = x + width - frameInsetValue - center;\n    const bottom = y + height - frameInsetValue - center;\n    return [\n        // top\n        {\n            points: [vectorCreate(left + offset, top), vectorCreate(right - offset, top)],\n        },\n        {\n            points: [vectorCreate(right, top + offset), vectorCreate(right, bottom - offset)],\n        },\n        {\n            points: [vectorCreate(right - offset, bottom), vectorCreate(left + offset, bottom)],\n        },\n        {\n            points: [vectorCreate(left, bottom - offset), vectorCreate(left, top + offset)],\n        },\n    ].map((shape) => {\n        shape.strokeWidth = frameSizeValue;\n        shape.strokeColor = frameColor;\n        return shape;\n    });\n};\nconst frameStyleHook = ({ x, y, width, height, frameSize = '.25%', frameInset = '2.5%', frameLength = '2.5%', frameColor = [1, 1, 1], }, { isPreview }) => {\n    const size = Math.sqrt(width * height);\n    let frameSizeValue = toValue(frameSize, size);\n    let frameInsetValue = toValue(frameInset, size);\n    let frameLengthValue = toValue(frameLength, size);\n    let center = 0;\n    if (!isPreview) {\n        frameSizeValue = Math.max(1, Math.round(frameSizeValue));\n        frameInsetValue = Math.round(frameInsetValue);\n        frameLengthValue = Math.round(frameLengthValue);\n        center = frameSizeValue % 2 == 0 ? 0 : 0.5;\n    }\n    const left = x + frameInsetValue + center;\n    const top = y + frameInsetValue + center;\n    const right = x + width - frameInsetValue - center;\n    const bottom = y + height - frameInsetValue - center;\n    return [\n        // top\n        {\n            points: [\n                vectorCreate(left, top + frameLengthValue),\n                vectorCreate(left, top),\n                vectorCreate(left + frameLengthValue, top),\n            ],\n        },\n        {\n            points: [\n                vectorCreate(right - frameLengthValue, top),\n                vectorCreate(right, top),\n                vectorCreate(right, top + frameLengthValue),\n            ],\n        },\n        {\n            points: [\n                vectorCreate(right, bottom - frameLengthValue),\n                vectorCreate(right, bottom),\n                vectorCreate(right - frameLengthValue, bottom),\n            ],\n        },\n        {\n            points: [\n                vectorCreate(left + frameLengthValue, bottom),\n                vectorCreate(left, bottom),\n                vectorCreate(left, bottom - frameLengthValue),\n            ],\n        },\n    ].map((shape) => {\n        shape.strokeWidth = frameSizeValue;\n        shape.strokeColor = frameColor;\n        return shape;\n    });\n};\nconst frameStylePolaroid = ({ x, y, width, height, frameColor = [1, 1, 1] }, { isPreview }) => {\n    const size = Math.sqrt(width * height);\n    const borderWidth = 0.1 * size;\n    let chinHeight = 0.2 * size;\n    let overlap = 0;\n    const borderWidthHalf = 0.5 * borderWidth;\n    if (!isPreview) {\n        chinHeight = Math.ceil(chinHeight);\n    }\n    else {\n        overlap = 1;\n    }\n    // always remove opacity\n    frameColor.length = 3;\n    return [\n        // border\n        {\n            id: 'border',\n            x: x - borderWidthHalf + overlap,\n            y: y - borderWidthHalf + overlap,\n            width: width + borderWidth - overlap * 2,\n            height: height + chinHeight - overlap * 2,\n            frameStyle: 'line',\n            frameInset: 0,\n            frameOffset: 0,\n            frameSize: borderWidth,\n            frameColor,\n            expandsCanvas: true,\n        },\n        // chin\n        {\n            id: 'chin',\n            x: x - borderWidthHalf,\n            y: height - overlap,\n            width: width + borderWidth,\n            height: chinHeight,\n            backgroundColor: frameColor,\n            expandsCanvas: true,\n        },\n    ].filter(Boolean);\n};\nconst createFrameStyleProcessor = (styles = {}) => (shape, options) => {\n    // handle solid frameStyle\n    if (!hasProp(shape, 'frameStyle'))\n        return;\n    const style = shape.frameStyle;\n    // get parser for style\n    const process = styles[style];\n    if (!process)\n        return;\n    // remove frameStyle property so we don't get endless loops\n    const { frameStyle, ...shapeReadyToParse } = shape;\n    return process(shapeReadyToParse, options);\n};\n// the default frame styles available, can import and extend\nconst createDefaultFrameStyles = () => ({\n    solid: frameStyleSolid,\n    hook: frameStyleHook,\n    line: frameStyleLine,\n    edge: frameStyleEdge,\n    polaroid: frameStylePolaroid,\n    nine: frameStyleNine,\n});\n\n// the default lineEnd parser to use\nconst createDefaultLineEndProcessors = () => createLineEndProcessor(createDefaultLineEndStyles());\nconst createDefaultFrameStyleProcessor = () => createFrameStyleProcessor(createDefaultFrameStyles());\nconst createDefaultShapeProcessors = () => [\n    createDefaultFrameStyleProcessor(),\n    createDefaultLineEndProcessors(),\n];\nconst createShapePreprocessor$1 = (processors) => {\n    const processShape = (shape, options = { isPreview: true }) => {\n        const res = processors\n            .map((process) => {\n            const res = process(shape, options);\n            // processor wasn't a match?\n            if (!res)\n                return;\n            return res.map((shape) => processShape(shape, options));\n        })\n            .filter(Boolean)\n            .flat();\n        return !res.length\n            ? shape\n            : res.flat().map((subshape, index) => {\n                subshape.id = shape.id + '_' + index;\n                return subshape;\n            });\n    };\n    return processShape;\n};\n\n// prettier-ignore\n\nconst createDefaultImageReader = createDefaultImageReader$1;\nconst createDefaultImageWriter = createDefaultImageWriter$1;\nconst createDefaultMediaWriter = createDefaultMediaWriter$1;\n\nconst createDefaultImageOrienter = () => ({\n    read: async (file, onprogress) => {\n        const res = await getImageTagsFromFile(\n            file,\n            { exif: [ORIENTATION_TAG] },\n            // perhaps we should just read the entire file?\n            [0, 64 * 4096],\n            onprogress\n        );\n        return (res && res.exif && res.exif[ORIENTATION_TAG]) || 1;\n    },\n    apply: orientImageData,\n});\nconst createDefaultImageScrambler = (configurationOptions = {}) => {\n    // default configuration\n    const { blurAmount, dataSizeScalar, scrambleAmount, backgroundColor } = configurationOptions;\n\n    // as called from editor ui\n    return (imageData, uiOptions) => {\n        return imageDataScramble(imageData, {\n            blurAmount,\n            scrambleAmount,\n            backgroundColor,\n            ...uiOptions,\n            dataSizeScalar: dataSizeScalar || uiOptions.dataSizeScalar,\n        });\n    };\n};\nconst createEditor = createImageEditor;\nconst getEditorProps = () => getEditorProps$1().concat(getEditorViewProps()); // private api for framework components\n\nconst createMarkupEditorToolbar = createToolbar;\nconst createMarkupEditorToolStyles = createToolStyles;\n\n// markup editor style controls\nconst createMarkupEditorShapeStyleControls = createShapeStyleControls;\n\n// a set of helper methods to handle shapes in a shape list\nconst getShapeById = (shapeList, shapeId) => shapeList.find((shape) => shape.id === shapeId);\n\nconst updateShapeById = (shapeList, shapeId, updater) =>\n    shapeList.map((shape) => {\n        if (shape.id !== shapeId) return shape;\n        return updater(shape);\n    });\n\nconst markup_editor_defaults = {\n    markupEditorToolbar: createToolbar(),\n    markupEditorToolStyles: createToolStyles(),\n    markupEditorShapeStyleControls: createShapeStyleControls(),\n};\nconst setPlugins = setEditorViewPlugins;\n\nconst plugin_crop = _plugin_crop;\nconst plugin_filter = _plugin_filter;\nconst plugin_finetune = _plugin_finetune;\nconst plugin_annotate = _plugin_annotate;\nconst plugin_decorate = _plugin_decorate;\nconst plugin_sticker = _plugin_sticker;\nconst plugin_frame = _plugin_frame;\nconst plugin_redact = _plugin_redact;\nconst plugin_resize = _plugin_resize;\nconst plugin_fill = _plugin_fill;\nconst plugin_retouch = _plugin_retouch;\n\nconst plugin_finetune_defaults = _plugin_finetune_defaults;\nconst plugin_filter_defaults = _plugin_filter_defaults;\nconst plugin_frame_defaults = _plugin_frame_defaults;\n\nconst locale_en_gb = _locale_en_gb;\nconst markup_editor_locale_en_gb = MarkupEditor;\n\nconst plugin_crop_locale_en_gb = _plugin_crop_locale_en_gb;\nconst plugin_fill_locale_en_gb = _plugin_fill_locale_en_gb;\nconst plugin_filter_locale_en_gb = _plugin_filter_locale_en_gb;\nconst plugin_finetune_locale_en_gb = _plugin_finetune_locale_en_gb;\nconst plugin_resize_locale_en_gb = _plugin_resize_locale_en_gb;\nconst plugin_decorate_locale_en_gb = _plugin_decorate_locale_en_gb;\nconst plugin_annotate_locale_en_gb = _plugin_annotate_locale_en_gb;\nconst plugin_sticker_locale_en_gb = _plugin_sticker_locale_en_gb;\nconst plugin_frame_locale_en_gb = _plugin_frame_locale_en_gb;\nconst plugin_redact_locale_en_gb = _plugin_redact_locale_en_gb;\nconst plugin_retouch_locale_en_gb = _plugin_retouch_locale_en_gb;\n\nconst elementsToEditor = (factory, targets, options = {}) => {\n    const elements = isString(targets) ? Array.from(document.querySelectorAll(targets)) : targets;\n    return elements.filter(Boolean).map((element) => factory(element, deepCopy(options)));\n};\n\nconst appendEditor = _appendEditor;\nconst openEditor = _openEditor;\nconst overlayEditor = _overlayEditor;\nconst appendEditors = (targets, options) => elementsToEditor(appendEditor, targets, options);\n\nconst createShapePreprocessor = createShapePreprocessor$1;\n\nconst createDefaultShapePreprocessor = (customProcessors = []) => {\n    return createShapePreprocessor$1([...createDefaultShapeProcessors(), ...customProcessors]);\n};\n\n//\n// creating default editors\n//\n\nconst getEditorDefaultReadWriteOptions = (options = {}) => {\n    let readerProps = undefined;\n    if (!Array.isArray(options.imageReader)) {\n        readerProps = options.imageReader;\n        delete options.imageReader;\n    }\n\n    let imageWriter;\n    if (!Array.isArray(options.imageWriter)) {\n        if (isFunction(options.imageWriter)) {\n            imageWriter = options.imageWriter;\n        } else {\n            imageWriter = createDefaultImageWriter(options.imageWriter);\n        }\n        delete options.imageWriter;\n    } else {\n        imageWriter = createDefaultImageWriter();\n    }\n\n    let scramblerProps = undefined;\n    if (!isFunction(options.imageScrambler)) {\n        scramblerProps = options.imageScrambler;\n        delete options.imageScrambler;\n    }\n\n    return {\n        // default handling of images\n        imageReader: createDefaultImageReader(readerProps),\n        imageWriter,\n        imageOrienter: createDefaultImageOrienter(),\n        imageScrambler: createDefaultImageScrambler(scramblerProps),\n    };\n};\n\nconst processDefaultImage = (src, options = {}) => {\n    // get default read/write options object\n    const defaultReadWriteOptions = getEditorDefaultReadWriteOptions(options);\n\n    // handle custom shape preprocessorss\n    const shapePreprocessor =\n        typeof options.shapePreprocessor === 'function'\n            ? options.shapePreprocessor\n            : createDefaultShapePreprocessor(options.shapePreprocessor);\n    delete options.shapePreprocessor;\n\n    // create huge config object\n    options = mergeObjects([\n        {\n            // set reader / writer / orienter\n            ...defaultReadWriteOptions,\n\n            // shape preprocessor\n            shapePreprocessor,\n\n            // stickers stick to image by default\n            stickerStickToImage: true,\n        },\n        options,\n    ]);\n    return processImage(src, options);\n};\n\nconst getCropperDefaults = (options = {}) => {\n    setEditorViewPlugins(plugin_crop);\n\n    // get default read/write options object\n    const defaultReadWriteOptions = getEditorDefaultReadWriteOptions(options);\n\n    // locale\n    const locale = {\n        ...locale_en_gb,\n        ...plugin_crop_locale_en_gb,\n        ...options.locale,\n    };\n    delete options.locale;\n\n    // create huge config object\n    return mergeObjects([\n        {\n            // set reader / writer / orienter\n            ...defaultReadWriteOptions,\n\n            // default utils\n            utils: ['crop'],\n\n            // locale\n            locale,\n        },\n        options,\n    ]);\n};\n\nconst getEditorDefaults = (options = {}) => {\n    // load all plugins\n    setEditorViewPlugins(\n        plugin_crop,\n        plugin_filter,\n        plugin_finetune,\n        plugin_annotate,\n        plugin_decorate,\n        plugin_sticker,\n        plugin_frame,\n        plugin_redact,\n        plugin_resize,\n        plugin_fill\n    );\n\n    const utils = [\n        'trim',\n        'crop',\n        'filter',\n        'finetune',\n        'retouch',\n        'annotate',\n        'decorate',\n        'sticker',\n        'fill',\n        'frame',\n        'redact',\n        'resize',\n    ];\n\n    // get default read/write options object\n    const defaultReadWriteOptions = getEditorDefaultReadWriteOptions(options);\n\n    // locale\n    const locale = {\n        ...locale_en_gb,\n        ...markup_editor_locale_en_gb,\n        ...plugin_crop_locale_en_gb,\n        ...plugin_fill_locale_en_gb,\n        ...plugin_filter_locale_en_gb,\n        ...plugin_finetune_locale_en_gb,\n        ...plugin_frame_locale_en_gb,\n        ...plugin_redact_locale_en_gb,\n        ...plugin_resize_locale_en_gb,\n        ...plugin_decorate_locale_en_gb,\n        ...plugin_annotate_locale_en_gb,\n        ...plugin_sticker_locale_en_gb,\n        ...options.locale,\n    };\n    delete options.locale;\n\n    // handle custom shape preprocessorss\n    const shapePreprocessor =\n        typeof options.shapePreprocessor === 'function'\n            ? options.shapePreprocessor\n            : createDefaultShapePreprocessor(options.shapePreprocessor);\n    delete options.shapePreprocessor;\n\n    // no functions in markupEditorShapeStyleControls, need to init\n    if (options.markupEditorShapeStyleControls) {\n        // is shorthand when every value is either an array (item, options) or object and all options are non functions\n        const isShorthand = Object.entries(options.markupEditorShapeStyleControls).every(\n            ([key, value]) => /Options$/.test(key) || !Array.isArray(value)\n        );\n\n        if (isShorthand) {\n            options.markupEditorShapeStyleControls = createMarkupEditorShapeStyleControls({\n                ...options.markupEditorShapeStyleControls,\n            });\n        }\n    }\n\n    if (options.markupEditorToolStyles) {\n        const isShorthand = Object.values(options.markupEditorToolStyles).every(\n            (value) => !Array.isArray(value)\n        );\n\n        if (isShorthand) {\n            options.markupEditorToolStyles = Object.entries(options.markupEditorToolStyles).reduce(\n                (prev, [key, value]) => {\n                    prev[key] = createToolStyle(key, value);\n                    return prev;\n                },\n                createMarkupEditorToolStyles()\n            );\n        }\n    }\n\n    // create huge config object\n    return mergeObjects([\n        {\n            // set reader / writer / orienter\n            ...defaultReadWriteOptions,\n\n            // shape preprocessor\n            shapePreprocessor,\n\n            // default utils\n            utils,\n\n            // default plugin options\n            ...plugin_finetune_defaults,\n            ...plugin_filter_defaults,\n            ...plugin_frame_defaults,\n            ...markup_editor_defaults,\n\n            // stickers stick to image by default\n            stickerStickToImage: true,\n\n            // locale\n            locale,\n        },\n        options,\n    ]);\n};\n\nconst defineCustomElements = async (options = {}) => {\n    const elements = await _defineCustomElements();\n    elements.forEach((editor) => Object.assign(editor, deepCopy(options)));\n    return elements;\n};\n\nconst defineDefaultCustomElements = (options) =>\n    defineCustomElements(getEditorDefaults(options));\n\nconst openDefaultEditor = (options, parent) =>\n    openEditor(getEditorDefaults(options), parent);\n\nconst appendDefaultEditor = (element, options) =>\n    appendEditor(element, getEditorDefaults(options));\n\nconst overlayDefaultEditor = (element, options) =>\n    overlayEditor(element, getEditorDefaults(options));\n\nconst appendDefaultEditors = (targets, options) =>\n    elementsToEditor(appendDefaultEditor, targets, options);\n\n// selection to mask related\nconst toSelectionShape = (shape, scalar, fill) => {\n    const clone = { ...shape };\n    shapeScale(clone, scalar);\n    if (clone.width || clone.rx) {\n        clone.backgroundColor = fill;\n    } else if (clone.points && !clone.pathClose) {\n        clone.strokeJoin = 'round';\n        clone.strokeCap = 'round';\n        clone.strokeColor = fill;\n    } else if (clone.points) {\n        clone.backgroundColor = fill;\n        clone.strokeColor = [0, 0, 0, 0];\n    }\n    return clone;\n};\n\nconst selectionToMask = (selection, imageSize, imageState, options) =>\n    new Promise(async (resolve, reject) => {\n        const {\n            // or 'blob'\n            format = 'canvas',\n\n            // default black background\n            backgroundColor = [0, 0, 0],\n\n            // default white fill, set to undefined or [x,x,x,0] for transparent\n            foregroundColor = [1, 1, 1],\n\n            // if is 'mask' returns mask canvas, if is 'image', returns image size canvas\n            scope = 'mask',\n\n            // no padding around mask\n            padding = 0,\n\n            // maximum size of the mask image\n            maxSize = imageSize,\n\n            // resize to this size\n            targetSize = undefined,\n\n            // force output to square\n            forceSquareCanvas = false,\n\n            // higher is faster but less precise\n            precision = 7,\n        } = options || {};\n\n        const { flipX, flipY, rotation } = imageState;\n\n        const SELECTION_MAX_SIZE = 2048;\n        const selectionScalar = Math.min(1, SELECTION_MAX_SIZE / imageSize.width);\n\n        const imageSizeScaled = sizeScale({ ...imageSize }, selectionScalar);\n\n        const rotatedSize = sizeRotate({ ...imageSize }, rotation);\n\n        const rotatedSizeScaled = sizeRotate({ ...imageSizeScaled }, rotation);\n\n        const rotatedCrop = {\n            x: (imageSizeScaled.width - rotatedSizeScaled.width) * 0.5,\n            y: (imageSizeScaled.height - rotatedSizeScaled.height) * 0.5,\n            ...rotatedSizeScaled,\n        };\n\n        // shared canvas options\n        const isTransparentMaskFill = foregroundColor === undefined || foregroundColor[3] === 0;\n        const selectionFill = isTransparentMaskFill ? [1, 1, 1] : foregroundColor;\n        const canvasOptions = {\n            imageAnnotation: selection.map((shape) =>\n                toSelectionShape(shape, selectionScalar, selectionFill)\n            ),\n            imageBackgroundColor: scope === 'image' ? backgroundColor : undefined,\n            imageCropLimitToImage: false,\n            imageCrop: rotatedCrop,\n            imageFlipX: flipX,\n            imageFlipY: flipY,\n            imageRotation: rotation,\n            imageWriter: {\n                format: 'canvas',\n            },\n        };\n\n        const { dest: canvas } = await processDefaultImage(h('canvas', imageSizeScaled), {\n            ...canvasOptions,\n        });\n\n        const ctx = canvas.getContext('2d', {\n            desynchronized: true,\n            willReadFrequently: true,\n        });\n\n        // get rect bounds\n        let maskRect;\n        {\n            const MSI = Number.MAX_SAFE_INTEGER;\n\n            const { width, height } = canvas;\n            const imageData = ctx.getImageData(0, 0, width, height);\n            const data = imageData.data;\n\n            let p = Math.max(1, parseInt(precision, 10));\n            let y, x;\n            let xMax = width - p;\n            let yMax = height - p;\n            let [t, r, b, l] = [MSI, -MSI, -MSI, MSI];\n\n            for (y = 0; y <= yMax; y += p) {\n                for (x = 0; x <= xMax; x += p) {\n                    const index = (x + y * width) * 4;\n                    const a = data[index + 3];\n\n                    // is transparent skip to next pixel (use 32 because 0 is too strict when taking into account Pintura watermark)\n                    if (a <= 32) continue;\n\n                    // opaque\n                    if (x < l) l = x;\n                    else if (x > r) r = x;\n                    if (y < t) t = y;\n                    else if (y > b) b = y;\n                }\n            }\n\n            const boundsRect = rectCreateFromBounds([\n                t - precision,\n                r + precision,\n                b + precision,\n                l - precision,\n            ]);\n\n            const boundsRectCenter = rectCenter(boundsRect);\n\n            const maskWidth = Math.min(boundsRect.width, maxSize.width);\n            const maskHeight = Math.min(boundsRect.height, maxSize.height);\n\n            maskRect = rectCreate(\n                boundsRectCenter.x - maskWidth * 0.5,\n                boundsRectCenter.y - maskHeight * 0.5,\n                maskWidth,\n                maskHeight\n            );\n        }\n\n        // scale\n        rectScale(maskRect, 1 / selectionScalar, vectorCreateEmpty());\n\n        let outputCanvas;\n        let paddingX = padding;\n        let paddingY = padding;\n\n        if (scope === 'mask') {\n            // create mask canvas for rect\n            const canvasSize = sizeCreateFromRect(maskRect);\n\n            // apply default padding\n            canvasSize.width += paddingX * 2;\n            canvasSize.height += paddingY * 2;\n\n            // should force canvas to square\n            if (forceSquareCanvas) {\n                const size = Math.max(canvasSize.width, canvasSize.height);\n                paddingX += (size - canvasSize.width) * 0.5;\n                paddingY += (size - canvasSize.height) * 0.5;\n                canvasSize.width = size;\n                canvasSize.height = size;\n            }\n\n            // scale mask rect\n            let scalar = 1;\n            if (targetSize) {\n                scalar = Math.min(\n                    targetSize.width / canvasSize.width,\n                    targetSize.height / canvasSize.height,\n                    1\n                );\n            }\n\n            sizeScale(canvasSize, scalar);\n            const maskCanvas = h('canvas', canvasSize);\n            const maskCtx = maskCanvas.getContext('2d');\n            maskCtx.fillStyle = colorArrayToRGBA(backgroundColor);\n            maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);\n            if (isTransparentMaskFill) maskCtx.globalCompositeOperation = 'destination-out';\n            maskCtx.scale(scalar, scalar);\n            maskCtx.drawImage(\n                canvas,\n                -maskRect.x + paddingX,\n                -maskRect.y + paddingY,\n                rotatedSize.width,\n                rotatedSize.height\n            );\n            outputCanvas = maskCanvas;\n        } else {\n            // use image as mask\n            outputCanvas = canvas;\n        }\n\n        const sizeRect = rectCreateFromSize(imageSize);\n        sizeRect.x += (rotatedSize.width - imageSize.width) * 0.5;\n        sizeRect.y += (rotatedSize.height - imageSize.height) * 0.5;\n        const [tl] = rectRotate(sizeRect, rotation);\n        const maskRectCenter = rectCenter({ ...maskRect });\n        const maskRectOffset = vectorCreate(maskRectCenter.x - tl.x, maskRectCenter.y - tl.y);\n\n        maskRect.x =\n            Math.cos(rotation) * maskRectOffset.x +\n            Math.sin(rotation) * maskRectOffset.y -\n            maskRect.width * 0.5;\n\n        maskRect.y =\n            Math.cos(rotation) * maskRectOffset.y -\n            Math.sin(rotation) * maskRectOffset.x -\n            maskRect.height * 0.5;\n\n        // Now create shape\n        const maskShape = { ...maskRect };\n        maskShape.x = maskRect.x;\n        maskShape.y = maskRect.y;\n        maskShape.flipX = false;\n        maskShape.flipY = false;\n        maskShape.backgroundCorners = undefined;\n\n        // Apply flip and rotation\n        if (flipX && flipY) {\n            maskShape.flipX = true;\n            maskShape.flipY = true;\n            maskShape.rotation = -rotation;\n        } else if (flipX) {\n            maskShape.flipX = true;\n            maskShape.rotation = rotation;\n        } else if (flipY) {\n            maskShape.flipY = true;\n            maskShape.rotation = rotation;\n        } else {\n            maskShape.rotation = -rotation;\n        }\n\n        // Correct offset based on flip\n        if (flipX || flipY) {\n            const computedMaskRectCenter = {\n                x: maskShape.x + maskShape.width * 0.5,\n                y: maskShape.y + maskShape.height * 0.5,\n            };\n\n            if (flipX) {\n                computedMaskRectCenter.x = Math.abs(imageSize.width - computedMaskRectCenter.x);\n                maskShape.x = computedMaskRectCenter.x - maskShape.width * 0.5; // maskShape.flipX = true;\n            }\n\n            if (flipY) {\n                computedMaskRectCenter.y = Math.abs(imageSize.height - computedMaskRectCenter.y);\n                maskShape.y = computedMaskRectCenter.y - maskShape.height * 0.5;\n            }\n        }\n\n        // apply padding\n        if (paddingX || paddingY) {\n            const xo = paddingX / (maskRect.width + paddingX * 2);\n            const yo = paddingY / (maskRect.height + paddingY * 2);\n\n            maskShape.backgroundCorners = [\n                { x: xo, y: yo },\n                { x: 1 - xo, y: yo },\n                { x: 1 - xo, y: 1 - yo },\n                { x: xo, y: 1 - yo },\n            ];\n\n            maskRect.x -= paddingX;\n            maskRect.y -= paddingY;\n            maskRect.width += paddingX * 2;\n            maskRect.height += paddingY * 2;\n        }\n\n        // result\n        const res = {\n            canvas: outputCanvas,\n            rect: maskRect,\n            shape: maskShape,\n        };\n\n        // return as blob\n        if (format === 'blob') {\n            outputCanvas.toBlob((blob) =>\n                resolve({\n                    ...res,\n                    blob,\n                })\n            );\n            return;\n        }\n\n        // restore\n        resolve({\n            ...res,\n            blob: undefined,\n        });\n    });\n\nconst createRetouchShapeDraft = (id = undefined, rect = {}) => ({\n    // id of shape\n    id,\n\n    // set rect to bounds of selection\n    ...rect,\n\n    // style of selection\n    selectionStyle: 'hook',\n\n    // disable everything\n    disableStyle: ['backgroundColor', 'cornerRadius', 'opacity', 'strokeWidth', 'strokeColor'],\n    disableFlip: true,\n    disableReorder: true,\n    disableMove: true,\n    disableRotate: true,\n    disableDuplicate: true,\n    disableSelect: true,\n});\n\nconst applyLoadStartState = (shape) => {\n    // now loading\n    Object.assign(shape, {\n        status: 'loading',\n        cornerRadius: 15,\n        strokeWidth: 1.5,\n        strokeColor: [0, 0, 0, 0.25],\n        backgroundColor: [0, 0, 0, 0.1],\n        selectionOpacity: 0,\n    });\n\n    return shape;\n};\n\nconst applyLoadCompleteState = (shape) => {\n    Object.assign(shape, {\n        selectionOpacity: 1,\n        cornerRadius: 0,\n        strokeWidth: 0,\n        strokeColor: [0, 0, 0, 0],\n        backgroundColor: [0, 0, 0, 0],\n    });\n\n    // status no longer needed\n    if (shape.status !== 'error') delete shape.status;\n\n    return shape;\n};\n\nconst createRetouchShape = async (\n    imageFile,\n    imageSize,\n    imageState,\n    selection,\n    inpaint,\n    options\n) => {\n    const {\n        // current\n        retouches = [],\n\n        // limit mask to this size (from center of mask shapes)\n        maxSize = imageSize,\n\n        // resize mask to this size if is bigger\n        targetSize = undefined,\n\n        // extra padding around mask area\n        padding = 0,\n\n        // image format (png or empty for use input)\n        mimeType = undefined,\n\n        // foreground color of mask\n        foregroundColor,\n\n        // mask format\n        maskFormat = 'blob', // or 'canvas'\n\n        // image format\n        imageFormat = 'blob', // or 'canvas'\n\n        // enforces a square image data canvas\n        forceSquareCanvas = false,\n\n        // hooks for ui updates\n        didCreateDraft = () => undefined,\n    } = options || {};\n\n    const imageSelection = [...selection];\n    const imageRetouches = [...retouches];\n\n    // so we can cancel the process\n    const controller = new AbortController();\n\n    // draw mask\n    const {\n        blob: maskBlob,\n        canvas: maskCanvas,\n        rect: computedMaskRect,\n        shape: maskShape,\n    } = await selectionToMask(imageSelection, imageSize, imageState, {\n        scope: 'mask',\n        format: maskFormat,\n        padding,\n        maxSize,\n        targetSize,\n        forceSquareCanvas,\n        foregroundColor,\n    });\n\n    const retouchShape = createRetouchShapeDraft(getUniqueId(), {\n        ...maskShape,\n    });\n\n    applyLoadStartState(retouchShape);\n\n    // shape is ready\n    didCreateDraft(retouchShape, {\n        selection: imageSelection,\n    });\n\n    // format\n    let imageWriterDefinition = {};\n    if (mimeType || targetSize || imageFormat === 'canvas') {\n        imageWriterDefinition = {\n            imageWriter: {},\n        };\n        if (mimeType) imageWriterDefinition.imageWriter.mimeType = mimeType;\n        if (targetSize) imageWriterDefinition.imageWriter.targetSize = targetSize;\n        if (imageFormat) imageWriterDefinition.imageWriter.format = imageFormat;\n    }\n\n    // generate image\n    const { flipX, flipY, rotation } = imageState;\n    const { dest: imageOutput } = await processDefaultImage(imageFile, {\n        // need to apply transforms so image data is oriented correctly (might impact inpainting)\n        imageFlipX: flipX,\n        imageFlipY: flipY,\n        imageRotation: rotation,\n\n        // rect to crop\n        imageCrop: computedMaskRect,\n\n        // we draw current manipulation shapes\n        imageManipulation: imageRetouches,\n\n        // can crop outside image\n        imageCropLimitToImage: false,\n\n        // optional image writer\n        ...imageWriterDefinition,\n    });\n\n    // get results\n    let status;\n    try {\n        await inpaint(imageOutput, maskBlob || maskCanvas, {\n            shape: retouchShape,\n            controller,\n        });\n        status = 'ok';\n    } catch {\n        status = 'error';\n    }\n\n    // done!\n    return applyLoadCompleteState({\n        ...retouchShape,\n\n        // now ready\n        status,\n\n        // can now select the shape\n        disableSelect: false,\n    });\n};\n\nexport { appendDefaultEditor, appendDefaultEditors, appendEditor, appendEditors, appendNode, blobToFile, canvasToBlob, colorStringToColorArray, createDefaultColorOptions, createDefaultFontFamilyOptions, createDefaultFontScaleOptions, createDefaultFontSizeOptions, createDefaultFontStyleOptions, createDefaultFrameStyles, createDefaultImageOrienter, createDefaultImageReader, createDefaultImageScrambler, createDefaultImageWriter, createDefaultLineEndStyleOptions, createDefaultLineEndStyles, createDefaultLineHeightOptions, createDefaultLineHeightScaleOptions, createDefaultMediaWriter, createDefaultShapePreprocessor, createDefaultStrokeScaleOptions, createDefaultStrokeWidthOptions, createDefaultTextAlignOptions, createEditor, createFrameStyleProcessor, createLineEndProcessor, createBackgroundColorControl as createMarkupEditorBackgroundColorControl, createBrushSizeControl as createMarkupEditorBrushSizeControl, createColorControl as createMarkupEditorColorControl, createColorOptions as createMarkupEditorColorOptions, createFontColorControl as createMarkupEditorFontColorControl, createFontFamilyControl as createMarkupEditorFontFamilyControl, createFontFamilyOptions as createMarkupEditorFontFamilyOptions, createFontScaleOptions as createMarkupEditorFontScaleOptions, createFontSizeControl as createMarkupEditorFontSizeControl, createFontSizeOptions as createMarkupEditorFontSizeOptions, createFontStyleControl as createMarkupEditorFontStyleControl, createFontStyleOptions as createMarkupEditorFontStyleOptions, createLineEndStyleControl as createMarkupEditorLineEndStyleControl, createLineEndStyleOptions as createMarkupEditorLineEndStyleOptions, createLineHeightControl as createMarkupEditorLineHeightControl, createLineHeightOptions as createMarkupEditorLineHeightOptions, createLineHeightScaleOptions as createMarkupEditorLineHeightScaleOptions, createLineStartStyleControl as createMarkupEditorLineStartStyleControl, createOptionControl as createMarkupEditorOptionControl, createOptionsControl as createMarkupEditorOptionsControl, createSelectionModeControl as createMarkupEditorSelectionModeControl, createSelectionToolStyles as createMarkupEditorSelectionToolStyles, createSelectionTools as createMarkupEditorSelectionTools, createMarkupEditorShapeStyleControls, createStrokeColorControl as createMarkupEditorStrokeColorControl, createStrokeScaleOptions as createMarkupEditorStrokeScaleOptions, createStrokeWidthControl as createMarkupEditorStrokeWidthControl, createStrokeWidthOptions as createMarkupEditorStrokeWidthOptions, createTextAlignControl as createMarkupEditorTextAlignControl, createToolStyle as createMarkupEditorToolStyle, createMarkupEditorToolStyles, createMarkupEditorToolbar, createNode, createRetouchShape, createShapePreprocessor, defineCustomElements, defineDefaultCustomElements, degToRad, dispatchEditorEvents, brightness as effectBrightness, clarity as effectClarity, contrast as effectContrast, exposure as effectExposure, gamma as effectGamma, saturation as effectSaturation, temperature as effectTemperature, vignette as effectVignette, chrome as filterChrome, cold as filterCold, fade as filterFade, invert as filterInvert, monoDefault as filterMonoDefault, monoNoir as filterMonoNoir, monoStark as filterMonoStark, monoWash as filterMonoWash, pastel as filterPastel, sepiaBlues as filterSepiaBlues, sepiaColor as filterSepiaColor, sepiaDefault as filterSepiaDefault, sepiaRust as filterSepiaRust, warm as filterWarm, findNode, edgeCross as frameEdgeCross, edgeOverlap as frameEdgeOverlap, edgeSeparate as frameEdgeSeparate, hook as frameHook, lineMultiple as frameLineMultiple, lineSingle as frameLineSingle, polaroid as framePolaroid, solidRound as frameSolidRound, solidSharp as frameSolidSharp, getCropperDefaults, getEditorDefaults, getEditorProps, getShapeById, getUniqueId, imageStateToCanvas, insertNodeAfter, insertNodeBefore, isModernBrowser as isSupported, legacyDataToImageState, locale_en_gb, markup_editor_defaults, markup_editor_locale_en_gb, naturalAspectRatioToNumber, openDefaultEditor, openEditor, overlayDefaultEditor, overlayEditor, plugin_annotate, plugin_annotate_locale_en_gb, plugin_crop, plugin_crop_locale_en_gb, plugin_decorate, plugin_decorate_locale_en_gb, plugin_fill, plugin_fill_locale_en_gb, plugin_filter, plugin_filter_defaults, plugin_filter_locale_en_gb, plugin_finetune, plugin_finetune_defaults, plugin_finetune_locale_en_gb, plugin_frame, plugin_frame_defaults, plugin_frame_locale_en_gb, plugin_redact, plugin_redact_locale_en_gb, plugin_resize, plugin_resize_locale_en_gb, plugin_retouch, plugin_retouch_locale_en_gb, plugin_sticker, plugin_sticker_locale_en_gb, processDefaultImage, processImage, removeNode, selectionToMask, setPlugins, shapeGetCenter, shapeGetLength, shapeGetLevel, supportsWebGL, updateNode, updateShapeById };\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static values = { form: String, listingModal: Boolean };\n  static targets = ['simpleFormButton', 'simpleForm', 'advancedFormButton', 'advancedForm'];\n\n  connect () {\n    if (this.formValue == 'simple') {\n      this.enableSimpleForm();\n    } else {\n      this.enableAdvancedForm();\n    }\n\n\n    if (this.listingModalValue) {\n      const modal = Modal.getOrCreateInstance(document.getElementById('listing-modal'));\n      modal.show();\n    }\n  }\n\n  enableSimpleForm () {\n    this.simpleFormButtonTarget.classList.remove('btn-light');\n    this.simpleFormButtonTarget.classList.add('btn-primary');\n\n    this.advancedFormButtonTarget.classList.add('btn-light');\n    this.advancedFormButtonTarget.classList.remove('btn-primary');\n\n    this.simpleFormTarget.classList.remove('d-none');\n    this.advancedFormTarget.classList.add('d-none');\n  }\n\n  enableAdvancedForm () {\n    this.advancedFormButtonTarget.classList.remove('btn-light');\n    this.advancedFormButtonTarget.classList.add('btn-primary');\n\n    this.simpleFormButtonTarget.classList.add('btn-light');\n    this.simpleFormButtonTarget.classList.remove('btn-primary');\n\n    this.advancedFormTarget.classList.remove('d-none');\n    this.simpleFormTarget.classList.add('d-none');\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Popover } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static values = {\n    id: Number,\n    statusUrl: String,\n  }\n\n  connect() {\n    const popoverTriggerList = document.querySelectorAll('[data-bs-toggle=\"popover\"]');\n    [...popoverTriggerList].map(popoverTriggerEl => new Popover(popoverTriggerEl));\n\n    if (this.hasWinnerTarget) {\n      this.winnerTarget.addEventListener('click', (e) => {\n        document.querySelector('#address-modal .modal-body').innerHTML = this.winnerTarget.dataset.address;\n      });\n    }\n  }\n\n  async selectStatus(e) {\n    let notify = false;\n    if (e.target.dataset.notifyValue) {\n      notify = confirm(e.target.dataset.notifyValue);\n    }\n\n    await window.$Gunfinder.fetch(\n      `${this.statusUrlValue}?ids=${this.idValue}&status=${e.target.dataset.statusValue}&notify=${notify}`\n    );\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['selectAll', 'selectOne', 'actionButton', 'actionLink', 'actionForm'];\n\n  connect () {\n    this.selection = [];\n    this.selecting = false;\n\n    for (const el of this.selectAllTargets) {\n      el.addEventListener('change', this.selectAll.bind(this));\n    }\n\n    for (const el of this.selectOneTargets) {\n      el.addEventListener('change', this.selectOne.bind(this));\n    }\n  }\n\n  selectAll (e) {\n    for (const el of this.selectAllTargets) {\n      el.checked = e.currentTarget.checked;\n    }\n\n    if (e.currentTarget.checked) { // is true when it was just checked\n      for (const el of this.selectOneTargets) {\n        el.checked = true;\n        if (!this.selection.includes(el.value)) this.selection.push(el.value);\n      }\n    } else {\n      for (const el of this.selectOneTargets) {\n        el.checked = false;\n      }\n\n      this.selection = [];\n    }\n\n    this.updateSelectionParams();\n    this.toggleActionButtonsAndLinks();\n  }\n\n  selectOne (e) {\n    const\n      id = e.currentTarget.value,\n      i  = this.selection.indexOf(id)\n    ;\n\n    i === -1 ? this.selection.push(id) : this.selection.splice(i, 1);\n\n    for (const el of this.selectAllTargets) {\n      el.checked = this.selection.length === this.selectOneTargets.length;\n    }\n\n    this.updateSelectionParams();\n    this.toggleActionButtonsAndLinks();\n  }\n\n  updateSelectionParams () {\n    for (const el of this.actionFormTargets) {\n      el.querySelector('input[name=\"ids\"]').value = this.selection.join(',');\n    }\n\n    for (const el of this.actionLinkTargets) {\n      el.href += '&ids=' + this.selection.join(',');\n    }\n  }\n\n  toggleActionButtonsAndLinks () {\n    const selecting = this.selection.length > 0;\n\n    if (this.selecting === selecting) return;\n\n    for (const el of [...this.actionButtonTargets, ...this.actionLinkTargets]) {\n      el.disabled = !selecting;\n      el.classList.toggle('btn-light');\n      el.classList.toggle('btn-info');\n      el.classList.toggle('disabled');\n    }\n\n    this.selecting = selecting;\n  }\n\n  confirmAndBlock (e) {\n    e.preventDefault();\n    if (!confirm(e.currentTarget.dataset.confirmValue)) return;\n\n    let notify = false;\n    if (e.currentTarget.dataset.notifyValue) {\n      notify = confirm(e.currentTarget.dataset.notifyValue);\n    }\n\n    // document.addEventListener(\"turbo:load\", () => { document.dispatchEvent(new CustomEvent('screen-blocker:unblock')); } , { once: true });\n\n    document.dispatchEvent(new CustomEvent('screen-blocker:block'));\n    Turbo.visit(e.currentTarget.href + '&notify=' + notify);\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  connect() {\n    if (document.querySelector('.cf-turnstile') && window.turnstile) {\n      window.turnstile.render('.cf-turnstile', {\n        callback: (token) => {\n          // This function is called when turnstile verification is complete\n          console.log('Turnstile verification completed');\n          // You can dispatch a custom event if needed\n          this.element.dispatchEvent(new CustomEvent('turnstile:success', { \n            detail: { token }, \n            bubbles: true \n          }));\n        }\n      });\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static values = { id: String, followUp: { type: Number, default: 14 } };\n  static targets = ['close'];\n\n  connect () {\n    this.bannerId = `banner_${this.idValue}`;\n\n    let dateShown = window.localStorage.getItem(this.bannerId)\n    if (dateShown) {\n      dateShown = new Date(parseInt(dateShown));\n      // dateShown.setMinutes(dateShown.getMinutes() + 2);\n      dateShown.setDate(dateShown.getDate() + this.followUpValue); // Date = Days\n      if (dateShown.valueOf() > new Date().valueOf()) return;\n    }\n\n    this.element.classList.remove('d-none');\n  }\n\n  close () {\n    this.element.classList.add('d-none');\n    window.localStorage.setItem(this.bannerId, new Date().valueOf());\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['form', 'select', 'close'];\n  static values = { cookieKey: String, days: { type: Number, default: 14 } };\n\n  submit (event) {\n    event.preventDefault();\n\n    const locale = (this.selectTarget?.value || '').trim();\n    if (!locale) return;\n\n    const currentUrl = new URL(window.location.href);\n    const currentPath = currentUrl.pathname || '/';\n\n    const normalizedLocale = locale.toLowerCase();\n    const pathWithoutLocale = this.stripLeadingLocale(currentPath);\n\n    const host = normalizedLocale === 'de' ? 'www.gunfinder.de' : 'www.gunfinder.com';\n    const localePrefix = (normalizedLocale === 'de' || normalizedLocale === 'en') ? '' : `/${normalizedLocale}`;\n\n    const nextUrl = new URL(`https://${host}`);\n    nextUrl.pathname = `${localePrefix}${pathWithoutLocale}`.replace(/\\/{2,}/g, '/');\n\n    const params = new URLSearchParams(currentUrl.search);\n    params.delete('locale');\n    nextUrl.search = params.toString();\n\n    window.location.assign(nextUrl.toString());\n  }\n\n  close () {\n    this.element.classList.add('d-none');\n    this.setClosedCookie();\n  }\n\n  setClosedCookie () {\n    if (!this.hasCookieKeyValue || !this.cookieKeyValue) return;\n\n    const maxAgeSeconds = Math.max(1, (this.daysValue || 14) * 24 * 60 * 60);\n    const encodedKey = encodeURIComponent(this.cookieKeyValue);\n    document.cookie = `${encodedKey}=1; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;\n  }\n\n  stripLeadingLocale (pathname) {\n    const clean = (pathname || '/').startsWith('/') ? pathname : `/${pathname}`;\n    const parts = clean.split('/').filter(Boolean);\n    if (parts.length === 0) return '/';\n\n    const first = parts[0].toLowerCase();\n    // only strip if it looks like a locale segment (e.g. fr, fr-FR, pt_BR)\n    if (/^[a-z]{2}([_-][a-z]{2})?$/.test(first)) {\n      const rest = parts.slice(1).join('/');\n      return `/${rest}`.replace(/\\/{2,}/g, '/') || '/';\n    }\n\n    return clean;\n  }\n}\n\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['select'];\n\n  update (event) {\n    event.preventDefault();\n\n    const locale = (event.params?.locale || '').toString().trim();\n    if (!locale) return;\n    this.redirectToLocale(locale);\n  }\n\n  submit (event) {\n    event.preventDefault();\n\n    const locale = (this.selectTarget?.value || '').trim();\n    if (!locale) return;\n    this.redirectToLocale(locale);\n  }\n\n  redirectToLocale (locale) {\n    const currentUrl = new URL(window.location.href);\n    const currentPath = currentUrl.pathname || '/';\n\n    const normalizedLocale = locale.toLowerCase();\n    const pathWithoutLocale = this.stripLeadingLocale(currentPath);\n\n    const host = normalizedLocale === 'de' ? 'www.gunfinder.de' : 'www.gunfinder.com';\n    const localePrefix = (normalizedLocale === 'de' || normalizedLocale === 'en') ? '' : `/${normalizedLocale}`;\n\n    const nextUrl = new URL(`https://${host}`);\n    nextUrl.pathname = `${localePrefix}${pathWithoutLocale}`.replace(/\\/{2,}/g, '/');\n\n    const params = new URLSearchParams(currentUrl.search);\n    params.delete('locale');\n    nextUrl.search = params.toString();\n\n    window.location.assign(nextUrl.toString());\n  }\n\n  stripLeadingLocale (pathname) {\n    const clean = (pathname || '/').startsWith('/') ? pathname : `/${pathname}`;\n    const parts = clean.split('/').filter(Boolean);\n    if (parts.length === 0) return '/';\n\n    const first = parts[0].toLowerCase();\n    if (/^[a-z]{2}([_-][a-z]{2})?$/.test(first)) {\n      const rest = parts.slice(1).join('/');\n      return `/${rest}`.replace(/\\/{2,}/g, '/') || '/';\n    }\n\n    return clean;\n  }\n}\n\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['country', 'postalCode', 'city'];\n  static values = { attrName: String, geodataPlaceId: Number };\n\n  connect () {\n    this.maxlengths = {\n      DE: 5,  // 5 digits\n      AT: 4,  // 4 digits\n      CH: 4,  // 4 digits\n      IT: 5,  // 5 digits\n      NL: 7,  // 4 digits + 2 letters (e.g., 1234 AB)\n      PL: 6,  // 2 digits + hyphen + 3 digits (e.g., 00-001)\n      ES: 5,  // 5 digits\n      FR: 5,  // 5 digits\n      US: 5,  // 5 digits\n      GB: 8,  // Max for common formats (e.g., SW1A 0AA, including space)\n      CA: 7   // 3 alphanumeric + space + 3 alphanumeric (e.g., A1A 1A1)\n      // US: 10, // Max for ZIP+4 (5 digits + hyphen + 4 digits); 5 for basic ZIP\n    };\n\n    window.setTimeout(() => {\n      this.countryChanged();\n      this.postalCodeChanged();\n    });\n\n    this.countryTarget.addEventListener('change', this.countryChanged.bind(this));\n\n    this.postalCodeTarget.addEventListener('input', this.postalCodeChanged.bind(this));\n  }\n\n  countryChanged (e) {\n    this.postalCodeTarget.maxLength = this.maxlengths[this.countryTarget.value];\n\n    if (!e) return;\n\n    this.appendInputElement();\n    this.postalCodeTarget.value = '';\n  }\n\n  async postalCodeChanged () {\n    if (this.postalCodeTarget.value.length != this.maxlengths[this.countryTarget.value]) {\n      this.appendInputElement();\n      return;\n    }\n\n    const places = await (await window.$Gunfinder.fetch(\n      `/api/v3/geocode?country=${this.countryTarget.value}&postal_code=${this.postalCodeTarget.value}`,\n      { method: 'POST'}\n    )).json();\n\n    if (places.length === 0) {\n      this.appendInputElement({ name: 'Nicht gefunden', id: '' });\n      return;\n    }\n\n    if (places.length === 1) {\n      this.appendInputElement(places[0]);\n      return;\n    }\n\n    this.appendDropdownElement(places);\n  }\n\n  clearInputElements () {\n    while (this.cityTarget.firstChild) {\n      this.cityTarget.removeChild(this.cityTarget.firstChild);\n    }\n  }\n\n  appendInputElement (place) {\n    this.clearInputElements();\n    const textEl = document.createElement('input');\n    textEl.type = 'text';\n    textEl.value = place?.name || '';\n    textEl.disabled = true;\n    textEl.classList.add('form-control');\n    this.cityTarget.appendChild(textEl);\n\n    const hiddenEl = document.createElement('input');\n    hiddenEl.type = 'hidden';\n    hiddenEl.name = this.attrNameValue;\n    hiddenEl.value = place?.id || '';\n    this.cityTarget.appendChild(hiddenEl);\n  }\n\n  appendDropdownElement (places) {\n    this.clearInputElements();\n\n    const el = document.createElement('select');\n    el.classList.add('form-select');\n    el.name = this.attrNameValue;\n\n    places.forEach(place => {\n      const option = document.createElement('option');\n      option.value = place.id;\n      option.textContent = place.name;\n      option.selected = place.id === this.geodataPlaceIdValue;\n      el.appendChild(option);\n    });\n    this.cityTarget.appendChild(el);\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  connect () {\n    document.addEventListener('screen-blocker:block', this.block.bind(this));\n    document.addEventListener('screen-blocker:unblock', this.unblock.bind(this));\n  }\n\n  block () {\n    this.blocker = document.createElement('div');\n    this.blocker.classList.add('modal-backdrop', 'fade', 'show', 'd-flex', 'justify-content-center', 'align-items-center');\n\n    const spinner = document.createElement('div')\n    spinner.classList.add('spinner-border', 'text-primary');\n    this.blocker.appendChild(spinner);\n\n    document.body.appendChild(this.blocker);\n  }\n\n  unblock () {\n    this.blocker.remove();\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['toggle', 'menu'];\n\n  connect() {\n    this.menuTarget.querySelectorAll('.dropdown-item').forEach(item => {\n      item.addEventListener('click', (e) => {\n        const activeItem = this.menuTarget.querySelector('.dropdown-item.active');\n\n        if (activeItem) {\n          this.toggleTarget.classList.remove(...activeItem.dataset.toggleClassValue.split(' '));\n          activeItem.classList.remove('active');\n        }\n\n        this.toggleTarget.innerHTML = item.innerHTML;\n        this.toggleTarget.classList.add(...item.dataset.toggleClassValue.split(' '));\n\n        item.classList.add('active');\n      });\n    });\n\n    let selectedItem = this.menuTarget.querySelector('.dropdown-item.active');\n    if (selectedItem) {\n      this.toggleTarget.innerHTML = selectedItem.innerHTML;\n      this.toggleTarget.classList.add(...selectedItem.dataset.toggleClassValue.split(' '));\n    }\n  }\n}\n", "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['lineItemsTable'];\n\n  static values = {\n    toastType: String,\n    toastMessage: String,\n  }\n\n  connect () {\n    if (this.hasToastTypeValue) {\n      document.dispatchEvent(new CustomEvent('toast:add', { \n        detail: {\n          type: this.toastTypeValue,\n          message: this.toastMessageValue,\n        }\n      }));\n    }\n  }\n\n  removeLineItem (event) {\n    const row = event.target.closest('tr');\n    row.remove();\n  }\n\n  addLineItem (event) {\n    const row = this.lineItemsTableTarget.insertRow();\n    row.classList.add('align-middle');\n    row.innerHTML = `\n      <td>\n        <input type=\"text\" class=\"form-control\" name=\"order[invoice_line_items][][title]\">\n      </td>\n      <td>\n        <div class=\"input-group flex-nowrap\">\n          <input type=\"text\" class=\"form-control\" name=\"order[invoice_line_items][][price]\" style=\"width: 80px;\">\n          <span class=\"input-group-text\">\u20AC</span>\n        </div>\n      </td>\n      <td>\n        <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" data-action=\"invoice-manager#removeLineItem\">\n          <i class=\"bi bi-trash\"></i>\n        </button>\n      </td>\n    `;\n  }\n\n  reloadPreview () {\n    const iframe = document.getElementById('invoice-preview-iframe');\n    iframe.src = iframe.src;\n  }\n}\n", "import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap/dist/js/bootstrap.bundle.min';\n\nexport default class extends Controller {\n  static targets = ['card', 'modal', 'vielMehrButton', 'otherButtons'];\n  static values = {\n    easterEgg: Boolean,\n    mobile: Boolean\n  };\n\n  connect() {\n    this.jollyColors = false;\n    this.discoMode = false;\n    this.discoInterval = null;\n    this.shakeMode = false;\n    this.snowClickCount = 0;\n    this.originalBackgroundColor = document.body.style.backgroundColor || '';\n    this.updateButtonVisibility();\n    this.spawnSnowflakes(this.mobileValue ? 20 : 40);\n  }\n\n  disconnect() {\n    // Clean up disco interval when controller disconnects\n    if (this.discoInterval) {\n      clearInterval(this.discoInterval);\n      this.discoInterval = null;\n    }\n  }\n\n  openCard(event) {\n    // Prevent opening future doors\n    const available = event.currentTarget.dataset.available === 'true';\n    if (!available) {\n      return;\n    }\n    \n    const day = event.currentTarget.dataset.day;\n    const modalElement = document.getElementById(`advent-modal-day-${day}`);\n    \n    if (modalElement) {\n      const modal = Modal.getOrCreateInstance(modalElement);\n      modal.show();\n\n      window.$Gunfinder.track(\"advent-calendar: door-opened\", { day: day });\n      console.log(\"advent-calendar: door-opened\", { day: day });\n    }\n  }\n\n  moreSnowflakes(e) {\n    const count = e?.params?.count || (this.mobileValue ? 20 : 40);\n    this.spawnSnowflakes(count);\n\n    // Increment count for any snowflake button click\n    this.snowClickCount++;\n    this.updateButtonVisibility();\n\n    window.$Gunfinder.track('advent-calendar: more-snowflakes');\n  }\n\n  updateButtonVisibility() {\n    // Show \"Viel mehr Schnee\" button after 3 clicks\n    this.vielMehrButtonTargets.forEach(button => {\n      button.style.display = this.snowClickCount >= 3 ? 'inline-block' : 'none';\n    });\n\n    // Show other buttons after 5 clicks\n    this.otherButtonsTargets.forEach(button => {\n      button.style.display = this.snowClickCount >= 8 ? 'inline-block' : 'none';\n    });\n  }\n\n  toggleJollyColors() {\n    this.jollyColors = !this.jollyColors;\n    \n    // Update existing snowflakes\n    const snowflakes = document.querySelectorAll('.snowflake');\n    const colors = this.getJollyColors();\n    snowflakes.forEach(snowflake => {\n      if (this.jollyColors) {\n        snowflake.style.color = colors[Math.floor(Math.random() * colors.length)];\n      } else {\n        snowflake.style.color = '#ffffff';\n      }\n    });\n\n    window.$Gunfinder.track('advent-calendar: toggle-jolly-colors', { enabled: this.jollyColors });\n  }\n\n  toggleDisco() {\n    this.discoMode = !this.discoMode;\n    \n    if (this.discoMode) {\n      // Start disco mode\n      this.startDisco();\n      window.$Gunfinder.track('advent-calendar: disco-mode', { enabled: true });\n    } else {\n      // Stop disco mode\n      this.stopDisco();\n      window.$Gunfinder.track('advent-calendar: disco-mode', { enabled: false });\n    }\n  }\n\n  startDisco() {\n    // Change color immediately\n    this.changeDiscoColor();\n    \n    // Change color every 100ms for fast disco effect\n    this.discoInterval = setInterval(() => {\n      this.changeDiscoColor();\n    }, 100);\n  }\n\n  stopDisco() {\n    if (this.discoInterval) {\n      clearInterval(this.discoInterval);\n      this.discoInterval = null;\n    }\n    // Restore original background\n    document.body.style.backgroundColor = this.originalBackgroundColor;\n  }\n\n  changeDiscoColor() {\n    const colors = this.getJollyColors();\n    const randomColor = colors[Math.floor(Math.random() * colors.length)];\n    document.body.style.backgroundColor = randomColor;\n  }\n\n  getJollyColors() {\n    return [\n      '#ff0000', // Bright red\n      '#dc143c', // Crimson\n      '#c41e3a', // Deep red\n      '#00ff00', // Bright green\n      '#228b22', // Forest green\n      '#32cd32', // Lime green\n      '#ffd700', // Gold\n      '#ffa500', // Orange\n      '#ff69b4', // Hot pink\n      '#ff1493', // Deep pink\n      '#00ced1', // Dark turquoise\n      '#9370db'  // Medium purple\n    ];\n  }\n\n  spawnSnowflakes(count = 40) {\n    const sizes = this.easterEggValue \n      ? [60, 70, 80, 90, 100] \n      : [10, 12, 8, 14, 16, 9];\n    const symbols = this.easterEggValue \n      ? ['\uD83D\uDD2B'] \n      : ['\u2726', '\u2744'];\n    const colors = this.jollyColors ? this.getJollyColors() : ['#ffffff'];\n    \n    for (let i = 0; i < count; i++) {\n      const size = sizes[Math.floor(Math.random() * sizes.length)];\n      const symbol = symbols[Math.floor(Math.random() * symbols.length)];\n      const s = document.createElement('div');\n      s.className = 'snowflake';\n      s.style.top = -size + 'px';\n      s.textContent = symbol;\n      s.style.left = Math.random() * 100 + 'vw';\n      \n      s.style.fontSize = size + 'px';\n      s.style.color = colors[Math.floor(Math.random() * colors.length)];\n      const fall = 10 + Math.random() * 18; // seconds\n      const sway = 4 + Math.random() * 6; // seconds\n      s.style.animationDuration = `${fall}s, ${sway}s`;\n      s.style.animationDelay = `${Math.random() * 10}s, ${Math.random() * 4}s`;\n      document.body.appendChild(s);\n    }\n  }\n\n  toggleShake() {\n    this.shakeMode = !this.shakeMode;\n    \n    if (this.shakeMode) {\n      document.body.classList.add('screen-shake');\n      window.$Gunfinder.track('advent-calendar: screen-shake', { enabled: true });\n    } else {\n      document.body.classList.remove('screen-shake');\n      window.$Gunfinder.track('advent-calendar: screen-shake', { enabled: false });\n    }\n  }\n}\n\n", "import { Controller } from '@hotwired/stimulus';\n\nexport default class extends Controller {\n  static targets = ['submitButton'];\n\n  connect () {\n    for (const el of this.submitButtonTargets) {\n      el.addEventListener('click', () => {\n        const $el = document.createElement('input')\n        $el.type = 'hidden';\n        $el.name = el.name;\n        $el.value = el.value;\n\n        el.closest('form').append($el);\n      });\n    }\n  }\n\n  disable () {\n    for (const el of this.submitButtonTargets) {\n      el.disabled = true;\n    }\n  }\n\n  enable () {\n    for (const el of this.submitButtonTargets) {\n      el.disabled = false;\n    }\n  }\n}\n", "import { application } from './application';\n\nimport AppController from './app_controller.js';\napplication.register('app', AppController);\n\nimport ColorSchemeController from './color_scheme_controller.js';\napplication.register('color-scheme', ColorSchemeController);\n\nimport AuthController from './auth_controller.js';\napplication.register('auth', AuthController);\n\nimport DropdownController from './dropdown_controller.js';\napplication.register('dropdown', DropdownController);\n\nimport AdvancedSearchController from './advanced_search_controller.js';\napplication.register('advanced-search', AdvancedSearchController);\n\nimport CookiesController from './cookies_controller.js';\napplication.register('cookies', CookiesController);\n\nimport FavoritesController from './favorites_controller.js';\napplication.register('favorites', FavoritesController);\n\nimport ItemController from './item_controller.js';\napplication.register('item', ItemController);\n\nimport ListingController from './listing_controller.js';\napplication.register('listing', ListingController);\n\nimport AuctionController from './auction_controller.js';\napplication.register('auction', AuctionController);\n\nimport MessagesController from './messages_controller.js';\napplication.register('messages', MessagesController);\n\nimport MessageFormController from './message_form_controller.js';\napplication.register('message-form', MessageFormController);\n\nimport MiniCollapseController from './mini_collapse_controller.js';\napplication.register('mini-collapse', MiniCollapseController);\n\nimport ListingManagerController from './listing_manager_controller.js';\napplication.register('listing-manager', ListingManagerController);\n\nimport ReportController from './report_controller.js';\napplication.register('report', ReportController);\n\nimport ReviewController from './review_controller.js';\napplication.register('review', ReviewController);\n\nimport ReviewFormController from './review_form_controller.js';\napplication.register('review-form', ReviewFormController);\n\nimport RichContentController from './rich_content_controller.js';\napplication.register('rich-content', RichContentController);\n\nimport SearchAutocompleteController from './search_autocomplete_controller.js';\napplication.register('search-autocomplete', SearchAutocompleteController);\n\nimport SearchController from './search_controller.js';\napplication.register('search', SearchController);\n\nimport ToastsController from './toasts_controller.js';\napplication.register('toasts', ToastsController);\n\nimport TabsController from './tabs_controller.js';\napplication.register('tabs', TabsController);\n\nimport SellSwitchController from './sell_switch_controller.js';\napplication.register('sell-switch', SellSwitchController);\n\nimport CountdownController from './countdown_controller.js';\napplication.register('countdown', CountdownController);\n\nimport FeedbackController from './feedback_controller.js';\napplication.register('feedback', FeedbackController);\n\nimport MapsLoaderController from './maps_loader_controller.js';\napplication.register('maps-loader', MapsLoaderController);\n\nimport AnimatedCounterController from './animated_counter_controller.js';\napplication.register('animated-counter', AnimatedCounterController);\n\n// import PopupController from './popup_controller.js';\n// application.register('popup', PopupController);\n\nimport AccordionController from './accordion_controller.js';\napplication.register('accordion', AccordionController);\n\nimport ItemGallery from './item_gallery.js';\napplication.register('item-gallery', ItemGallery);\n\nimport Modal from './modal_controller.js';\napplication.register('modal', Modal);\n\nimport SecureFormController from './secure_form_controller.js';\napplication.register('secure-form', SecureFormController);\n\nimport InterestCloud from './interest_cloud_controller.js';\napplication.register('interest-cloud', InterestCloud);\n\nimport ChartController from './chart_controller.js';\napplication.register('chart', ChartController);\n\nimport AorBController from './aorb_controler.js';\napplication.register('aorb', AorBController);\n\nimport CSDVDLControler from './csv_dl_controller.js';\napplication.register('csv-dl', CSDVDLControler);\n\nimport CategoryCalibersController from './category_calibers_controller.js';\napplication.register('category-calibers', CategoryCalibersController);\n\nimport ClassifiedOptimiserController from './classified_optimiser_controller.js';\napplication.register('classified-optimiser', ClassifiedOptimiserController);\n\nimport SimpleEditorController from './simple_editor_controller.js';\napplication.register('simple-editor', SimpleEditorController);\n\nimport PictureManagerController from './picture_manager_controller.js';\napplication.register('picture-manager', PictureManagerController);\n\nimport PurchaseController from './purchase_controller.js';\napplication.register('purchase', PurchaseController);\n\nimport AuctionSoldController from './auction_sold_controller.js';\napplication.register('auction-sold', AuctionSoldController);\n\nimport AuctionTableController from './auction_table_controller.js';\napplication.register('auction-table', AuctionTableController);\n\nimport CloudflareTurnstileController from './cloudflare_turnstile_controller.js';\napplication.register('cloudflare-turnstile', CloudflareTurnstileController);\n\nimport HeaderBannerController from './header_banner_controller.js';\napplication.register('header-banner', HeaderBannerController);\n\nimport LocaleBannerController from './locale_banner_controller.js';\napplication.register('locale-banner', LocaleBannerController);\n\nimport LocaleSwitcherController from './locale_switcher_controller.js';\napplication.register('locale-switcher', LocaleSwitcherController);\n\nimport PlaceController from './place_controller.js';\napplication.register('place', PlaceController);\n\nimport ScreenBlockerController from './screen_blocker_controller.js';\napplication.register('screen-blocker', ScreenBlockerController);\n\nimport DynamicDropdownController from './dynamic_dropdown_controller.js';\napplication.register('dynamic-dropdown', DynamicDropdownController);\n\nimport InvoiceManagerController from './invoice_manager_controller.js';\napplication.register('invoice-manager', InvoiceManagerController);\n\nimport AdventCalendarController from './advent_calendar_controller.js';\napplication.register('advent-calendar', AdventCalendarController);\n\nimport FormManagerController from './form_manager_controller.js';\napplication.register('form-manager', FormManagerController);\n", "import initSentry from './utils/sentry';\nif (window.$Gunfinder.env !== 'development' && window.$Gunfinder.user.ua.supported) {\n  initSentry('https://13504e9b86444989aa9927e19bb99755@o128241.ingest.sentry.io/5599126');\n}\n\nimport '@hotwired/turbo-rails';\n\nimport './utils/fetch';\nimport './utils/castle';\nimport './utils/tracker';\nimport './utils/adhunter';\nimport './utils/ckeditor5';\n\ndocument.addEventListener('turbo:render', () => {\n  window.$Gunfinder.Adhunter.load();\n\n  if (window.Trustpilot) {\n    window.Trustpilot.Modules.WidgetManagement.findAndApplyWidgets();\n  }\n});\n\nimport './controllers';\n"],
  "mappings": "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E,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UACtf,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,EAAE,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,IAAGvH,GAAEuH,GAAE,GAAG,GAAG,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,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,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UACtf,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UACvf,CAACA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UAAE,CAACA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,GAAEA,GAAE,GAAG,GAAG,CAAC,CAAC;AAAA,UA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O;IACPoZ,QAAQ;MACP;QACCC,SAAS;QACT3W,OAAO;UACN;UACA;UACA;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;UACA;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;UACA;UACA;UACA;UACA;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;UACA;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;QACA;MACF;IACA;EACF;EACA;IACCyW,QAAQ;IACRnZ,OAAO;IACPoZ,QAAQ;MACP;QACCC,SAAS;QACT3W,OAAO;UACN;YACCyW,QAAQ;YACRnZ,OAAO;YACPoZ,QAAQ;cACP;gBACCC,SAAS;gBACT3W,OAAO;kBACN;kBACA;kBACA;kBACA;kBACA;kBACA;kBACA;gBACA;cACF;cACA;gBACC2W,SAAS;gBACT3W,OAAO;kBACN;gBACA;cACF;YACA;UACF;UACA;YACCyW,QAAQ;YACRnZ,OAAO;YACPoZ,QAAQ;cACP;gBACCC,SAAS;gBACT3W,OAAO;kBACN;kBACA;gBACA;cACF;cACA;gBACC2W,SAAS;gBACT3W,OAAO;kBACN;kBACA;gBACA;cACF;cACA;gBACC2W,SAAS;gBACT3W,OAAO;kBACN;gBACA;cACF;YACA;UACF;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;UACA;UACA;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;UACA;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;QACA;MACF;IACA;EACF;EACA;IACCyW,QAAQ;IACRnZ,OAAO;IACPoZ,QAAQ;MACP;QACCC,SAAS;QACT3W,OAAO;UACN;UACA;QACA;MACF;MACA;QACC2W,SAAS;QACT3W,OAAO;UACN;UACA;QACA;MACF;IACA;EACF;EACA;IACCyW,QAAQ;IACRnZ,OAAO;IACPoZ,QAAQ;MACP;QACCC,SAAS;QACT3W,OA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ACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA8C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACAvC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACAI;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;A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AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACAuD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACAgB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,I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",
  "names": ["consumer", "error", "consumer", "s", "consumer", "s", "subscription", "a", "element", "exports", "module", "n", "t", "M", "O", "I", "r", "k", "u", "e", "W", "q", "c", "i", "o", "f", "V", "z", "Z", "B", "N", "A", "Q", "$", "on", "fn", "m", "w", "p", "y", "g", "s", "H", "d", "l", "x", "ne", "te", "ue", "ee", "ce", "ie", "fe", "_e", "le", "b", "de", "he", "pe", "me", "ge", "Te", "Pe", "Le", "Se", "Re", "Me", "Oe", "Ie", "Ae", "Ge", "a", "Ui", "po", "_a", "sn", "_", "v", "n2", "t2", "r2", "e2", "c2", "i2", "o2", "f2", "a2", "_2", "v2", "s2", "l2", "d2", "h2", "p2", "y2", "m2", "w2", "g2", "H2", "h", "x2", "F", "b2", "F2", "j2", "I2", "k2", "W2", "q2", "V2", "z2", "Z2", "B2", "N2", "A2", "Q2", "$2", "is", "qs", "t4", "r4", "h4", "w4", "x4", "T", "t3", "r3", "e3", "a3", "s3", "l3", "d3", "h3", "y3", "w3", "x3", "T3", "I3", "k3", "q3", "z3", "j", "B3", "$3", "X", "P", "U", "G", "J", "K", "Y", "nn", "tn", "rn", "un", "en", "cn", "L", "C", "D", "E", "S", "an", "R", "_n", "r6", "o6", "j6", "u7", "X7", "P7", "L7", "C7", "D7", "S7", "M7", "O7", "n8", "getUntaintedPrototype", "untaintedBasePrototype", "testableAccessors", "_a", "testableMethods", "isAngularZonePresent", "e", "getUntaintedAccessor", "instance", "untaintedAccessorCache", "getUntaintedMethod", "untaintedMethodCache", "ownerDocument", "n", "childNodes", "parentNode", "parentElement", "textContent", "contains", "getRootNode", "host", "styleSheets", "shadowRoot", "querySelector", "querySelectorAll", "mutationObserverCtor", "patch", "isElement", "isShadowRoot", "index", "isNativeShadowDom", "fixBrowserCompatibilityIssuesInCSS", "escapeImportStatement", "stringifyStylesheet", "s", "rules", "stringifyRule", "error", "isCSSImportRule", "isCSSStyleRule", "fixSafariColons", "createMirror", "Mirror", "maskInputValue", "element", "text", "toLowerCase", "is2DCanvasBlank", "x2", "y", "ORIGINAL_ATTRIBUTE_NAME", "getInputType", "extractFileExtension", "extractOrigin", "URL_IN_CSS_REF", "URL_PROTOCOL_MATCH", "URL_WWW_MATCH", "DATA_URI", "style", "i", "j", "k", "genId", "_id", "getValidTagName", "tagNameRegex", "getAbsoluteSrcsetString", "chars", "SRCSET_COMMAS_OR_SPACES", "SRCSET_NOT_SPACES", "absoluteToDoc", "c", "getHref", "isSVGElement", "a", "cachedDocument", "transformAttribute", "ignoreAttribute", "_isBlockedElement", "needMaskingText", "onceIframeLoaded", "onceStylesheetLoaded", "serializeNode", "options", "mirror", "getRootId", "NodeType", "serializeElementNode", "serializeTextNode", "parent", "attr", "canvasService", "canvasCtx", "image", "width", "height", "lowerIfExists", "slimDOMExcluded", "serializeNodeWithId", "IGNORED_NODE", "snapshot", "getDefaultExportFromCjs", "getAugmentedNamespace", "f", "a2", "d", "capitalize", "stringify$4", "Stringifier$1", "cloneNode", "fromBase64", "cleanSource", "markDirtyUp", "isClean$1", "findLastWithPosition", "parse$3", "Input$2", "parser2", "Parser2", "isPromise", "getEvents", "TYPE_TO_CLASS_NAME", "CHILDREN", "toStack", "cleanMarks", "isClean", "fromJSON$1", "defaults", "Input$1", "PreviousMap2", "Root$1", "Declaration$1", "Rule$1", "Comment$1", "AtRule$1", "postcss", "Processor2", "on", "fn", "throttle", "wait", "timeout", "now", "hookSetter", "getWindowScroll", "dom", "getWindowHeight", "getWindowWidth", "closestElementOfNode", "node", "isBlocked", "isSerialized", "isIgnored", "isAncestorRemoved", "legacy_isTouchEvent", "polyfill", "isSerializedIframe", "isSerializedStylesheet", "hasShadowRoot", "getShadowHost", "getRootShadowHost", "shadowHostInDom", "inDom", "isNodeInLinkedList", "deepDelete", "cache", "next", "isParentRemoved", "_isParentRemoved", "_mirror", "isAncestorInSet", "set", "_isAncestorInSet", "registerErrorHandler", "errorHandler", "unregisterErrorHandler", "getEventTarget", "initMutationObserver", "MutationBuffer", "mutationBuffers", "observer", "callbackWrapper", "initMoveObserver", "p", "nowTimestamp", "IncrementalSource", "handlers", "h", "initMouseInteractionObserver", "PointerTypes", "MouseInteractions", "initScrollObserver", "initViewportResizeObserver", "initInputObserver", "INPUT_TAGS", "v", "lastInputValueMap", "getNestedCSSRulePositions", "rule", "hasNestedCSSRule", "getIdAndStyleId", "initStyleSheetObserver", "canMonkeyPatchNestedCSSRule", "initAdoptedStyleSheetObserver", "result", "initStyleDeclarationObserver", "property", "initMediaInteractionObserver", "loop", "initFontObserver", "FontFace", "initSelectionObserver", "updateSelection", "count", "initCustomElementObserver", "o", "hooks", "initObservers", "plugin", "b", "variableListFor", "canvasVarMap", "serializeArg", "encode", "isInstanceOfWebGLObject", "saveWebGLVar", "initCanvas2DMutationObserver", "serializeArgs", "CanvasContext", "getNormalizedContextName", "initCanvasContextObserver", "patchGLPrototype", "props", "initCanvasWebGLMutationObserver", "record", "wrappedEmit", "r", "EventType", "takeFullSnapshot", "m", "StylesheetManager", "IframeManager", "ProcessedNodeManager", "CanvasManager", "ShadowDomManager", "observe", "init", "__defProp", "__defNormalProp", "__publicField", "picocolors_browser", "x", "create", "picocolors_browserExports", "__viteBrowserExternal", "__viteBrowserExternal$1", "require$$2", "pico", "terminalHighlight$1", "CssSyntaxError$3", "cssSyntaxError", "symbols", "DEFAULT_RAW", "Stringifier$2", "stringifier", "stringify_1", "isClean$2", "my$2", "CssSyntaxError$2", "Stringifier2", "stringify$3", "Node$4", "Node$3", "Declaration$4", "declaration", "urlAlphabet", "customAlphabet", "nanoid$1", "nonSecure", "SourceMapConsumer$2", "SourceMapGenerator$2", "existsSync", "readFileSync", "dirname$1", "join", "PreviousMap$2", "previousMap", "SourceMapConsumer$1", "SourceMapGenerator$1", "fileURLToPath", "pathToFileURL$1", "isAbsolute", "resolve$1", "nanoid", "terminalHighlight", "CssSyntaxError$1", "PreviousMap$1", "fromOffsetCache", "sourceMapAvailable$1", "pathAvailable$1", "Input$4", "input", "SourceMapConsumer", "SourceMapGenerator", "dirname", "relative", "resolve", "sep", "pathToFileURL", "Input$3", "sourceMapAvailable", "pathAvailable", "MapGenerator$2", "mapGenerator", "Node$2", "Comment$4", "comment", "my$1", "Declaration$3", "Comment$3", "Node$1", "parse$4", "Rule$4", "AtRule$4", "Root$6", "Container$7", "container", "Container$6", "LazyResult$4", "Processor$3", "Document$3", "document$1", "printed", "warnOnce$2", "Warning$2", "warning", "Warning$1", "Result$3", "SINGLE_QUOTE", "DOUBLE_QUOTE", "BACKSLASH", "SLASH", "NEWLINE", "SPACE", "FEED", "TAB", "CR", "OPEN_SQUARE", "CLOSE_SQUARE", "OPEN_PARENTHESES", "CLOSE_PARENTHESES", "OPEN_CURLY", "CLOSE_CURLY", "SEMICOLON", "ASTERISK", "COLON", "AT", "RE_AT_END", "RE_WORD_END", "RE_BAD_BRACKET", "RE_HEX_ESCAPE", "tokenize", "Container$5", "AtRule$3", "atRule", "Container$4", "LazyResult$3", "Processor$2", "Root$5", "root", "list$2", "list_1", "Container$3", "list$1", "Rule$3", "Declaration$2", "tokenizer2", "Comment$2", "AtRule$2", "Root$4", "Rule$2", "SAFE_COMMENT_NEIGHBOR", "Parser$1", "parser", "Container$2", "parse_1", "my", "MapGenerator$1", "stringify$2", "Container$1", "Document$2", "warnOnce$1", "Result$2", "parse$2", "Root$3", "PLUGIN_PROPS", "NOT_VISITORS", "postcss$2", "LazyResult$2", "lazyResult", "MapGenerator2", "stringify$1", "warnOnce2", "parse$1", "Result$1", "NoWorkResult$1", "noWorkResult", "NoWorkResult2", "LazyResult$1", "Document$1", "Root$2", "Processor$1", "processor", "fromJSON_1", "CssSyntaxError2", "Declaration2", "LazyResult2", "Container2", "stringify", "fromJSON", "Document2", "Warning2", "Comment2", "AtRule2", "Result2", "Input2", "parse", "list", "Rule2", "Root2", "Node2", "postcss_1", "postcss$1", "Document22", "DEPARTED_MIRROR_ACCESS_WARNING", "StyleSheetMirror", "DoubleLinkedList", "moveKey", "CrossOriginIframeMirror", "lookup", "NodeType2", "plugin2", "start", "bold", "indent", "last", "root2", "Node", "add", "result2", "_", "map", "l", "consumer", "stringify2", "children", "Document", "quote", "escape", "shift", "promise", "visit2", "self", "CssSyntaxError", "Stringifier", "Declaration", "PreviousMap", "Input", "MapGenerator", "Comment", "Container", "warnOnce", "Warning", "Result", "tokenizer", "AtRule", "Root", "Rule", "Parser", "LazyResult", "NoWorkResult", "Processor", "EventType2", "IncrementalSource2", "MouseInteractions2", "PointerTypes2", "CanvasContext2", "parentId", "keys", "option", "ImageBitmapDataURLWorker", "type", "t", "I", "w", "o", "f", "_a", "_e", "s", "v", "i", "k", "e", "d", "r", "l", "t", "n", "a", "y", "_", "T", "x", "S", "g", "m", "c", "u", "b", "record", "p", "h", "exports", "module", "exports", "module", "convert", "r", "g", "b", "h", "s", "l", "v", "diff", "c", "w", "k", "m", "y", "x", "z", "a", "t2", "t3", "i", "f", "p", "q", "t", "n", "y2", "x2", "z2", "saturation", "exports", "module", "i", "node", "fn", "exports", "module", "convert", "fn", "result", "i", "elementMap", "Map", "Data", "set", "element", "key", "instance", "has", "instanceMap", "get", "size", "console", "error", "Array", "from", "keys", "remove", "delete", "TRANSITION_END", "parseSelector", "selector", "window", "CSS", "escape", "replace", "match", "id", "toType", "object", "Object", "prototype", "toString", "call", "toLowerCase", "triggerTransitionEnd", "dispatchEvent", "Event", "isElement", "jquery", "nodeType", "getElement", "length", "document", "querySelector", "isVisible", "getClientRects", "elementIsVisible", "getComputedStyle", "getPropertyValue", "closedDetails", "closest", "summary", "parentNode", "isDisabled", "Node", "ELEMENT_NODE", "classList", "contains", "disabled", "hasAttribute", "getAttribute", "findShadowRoot", "documentElement", "attachShadow", "getRootNode", "root", "ShadowRoot", "noop", "reflow", "offsetHeight", "getjQuery", "jQuery", "body", "DOMContentLoadedCallbacks", "isRTL", "dir", "defineJQueryPlugin", "plugin", "callback", "$", "name", "NAME", "JQUERY_NO_CONFLICT", "fn", "jQueryInterface", "Constructor", "noConflict", "readyState", "addEventListener", "push", "execute", "possibleCallback", "args", "defaultValue", "executeAfterTransition", "transitionElement", "waitForTransition", "emulatedDuration", "transitionDuration", "transitionDelay", "floatTransitionDuration", "Number", "parseFloat", "floatTransitionDelay", "split", "called", "handler", "target", "removeEventListener", "setTimeout", "getNextActiveElement", "list", "activeElement", "shouldGetNext", "isCycleAllowed", "listLength", "index", "indexOf", "Math", "max", "min", "namespaceRegex", "stripNameRegex", "stripUidRegex", "eventRegistry", "uidEvent", "customEvents", "mouseenter", "mouseleave", "nativeEvents", "Set", "makeEventUid", "uid", "getElementEvents", "findHandler", "events", "callable", "delegationSelector", "values", "find", "event", "normalizeParameters", "originalTypeEvent", "delegationFunction", "isDelegated", "typeEvent", "getTypeEvent", "addHandler", "oneOff", "wrapFunction", "relatedTarget", "delegateTarget", "this", "handlers", "previousFunction", "domElements", "querySelectorAll", "domElement", "hydrateObj", "EventHandler", "off", "type", "apply", "removeHandler", "Boolean", "removeNamespacedHandlers", "namespace", "storeElementEvent", "handlerKey", "entries", "includes", "on", "one", "inNamespace", "isNamespace", "startsWith", "elementEvent", "slice", "keyHandlers", "trigger", "jQueryEvent", "bubbles", "nativeDispatch", "defaultPrevented", "isPropagationStopped", "isImmediatePropagationStopped", "isDefaultPrevented", "evt", "cancelable", "preventDefault", "obj", "meta", "value", "_unused", "defineProperty", "configurable", "normalizeData", "JSON", "parse", "decodeURIComponent", "normalizeDataKey", "chr", "Manipulator", "setDataAttribute", "setAttribute", "removeDataAttribute", "removeAttribute", "getDataAttributes", "attributes", "bsKeys", "dataset", "filter", "pureKey", "charAt", "getDataAttribute", "Config", "Default", "DefaultType", "Error", "_getConfig", "config", "_mergeConfigObj", "_configAfterMerge", "_typeCheckConfig", "jsonConfig", "constructor", "configTypes", "property", "expectedTypes", "valueType", "RegExp", "test", "TypeError", "toUpperCase", "BaseComponent", "super", "_element", "_config", "DATA_KEY", "dispose", "EVENT_KEY", "propertyName", "getOwnPropertyNames", "_queueCallback", "isAnimated", "getInstance", "VERSION", "getSelector", "hrefAttribute", "trim", "map", "sel", "join", "SelectorEngine", "concat", "Element", "findOne", "children", "child", "matches", "parents", "ancestor", "prev", "previous", "previousElementSibling", "next", "nextElementSibling", "focusableChildren", "focusables", "el", "getSelectorFromElement", "getElementFromSelector", "getMultipleElementsFromSelector", "enableDismissTrigger", "component", "method", "clickEvent", "tagName", "getOrCreateInstance", "EVENT_CLOSE", "EVENT_CLOSED", "Alert", "close", "_destroyElement", "each", "data", "SELECTOR_DATA_TOGGLE", "Button", "toggle", "button", "EVENT_TOUCHSTART", "EVENT_TOUCHMOVE", "EVENT_TOUCHEND", "EVENT_POINTERDOWN", "EVENT_POINTERUP", "endCallback", "leftCallback", "rightCallback", "Swipe", "isSupported", "_deltaX", "_supportPointerEvents", "PointerEvent", "_initEvents", "_start", "_eventIsPointerPenTouch", "clientX", "touches", "_end", "_handleSwipe", "_move", "absDeltaX", "abs", "direction", "add", "pointerType", "navigator", "maxTouchPoints", "DATA_API_KEY", "ARROW_LEFT_KEY", "ARROW_RIGHT_KEY", "ORDER_NEXT", "ORDER_PREV", "DIRECTION_LEFT", "DIRECTION_RIGHT", "EVENT_SLIDE", "EVENT_SLID", "EVENT_KEYDOWN", "EVENT_MOUSEENTER", "EVENT_MOUSELEAVE", "EVENT_DRAG_START", "EVENT_LOAD_DATA_API", "EVENT_CLICK_DATA_API", "CLASS_NAME_CAROUSEL", "CLASS_NAME_ACTIVE", "SELECTOR_ACTIVE", "SELECTOR_ITEM", "SELECTOR_ACTIVE_ITEM", "KEY_TO_DIRECTION", "ARROW_LEFT_KEY$1", "ARROW_RIGHT_KEY$1", "interval", "keyboard", "pause", "ride", "touch", "wrap", "Carousel", "_interval", "_activeElement", "_isSliding", "touchTimeout", "_swipeHelper", "_indicatorsElement", "_addEventListeners", "cycle", "_slide", "nextWhenVisible", "hidden", "_clearInterval", "_updateInterval", "setInterval", "_maybeEnableCycle", "to", "items", "_getItems", "activeIndex", "_getItemIndex", "_getActive", "order", "defaultInterval", "_keydown", "_addTouchEventListeners", "img", "swipeConfig", "_directionToOrder", "endCallBack", "clearTimeout", "_setActiveIndicatorElement", "activeIndicator", "newActiveIndicator", "elementInterval", "parseInt", "isNext", "nextElement", "nextElementIndex", "triggerEvent", "eventName", "_orderToDirection", "isCycling", "directionalClassName", "orderClassName", "completeCallBack", "_isAnimated", "clearInterval", "carousel", "slideIndex", "carousels", "EVENT_SHOW", "EVENT_SHOWN", "EVENT_HIDE", "EVENT_HIDDEN", "CLASS_NAME_SHOW", "CLASS_NAME_COLLAPSE", "CLASS_NAME_COLLAPSING", "CLASS_NAME_DEEPER_CHILDREN", "parent", "Collapse", "_isTransitioning", "_triggerArray", "toggleList", "elem", "filterElement", "foundElement", "_initializeChildren", "_addAriaAndCollapsedClass", "_isShown", "hide", "show", "activeChildren", "_getFirstLevelChildren", "activeInstance", "dimension", "_getDimension", "style", "scrollSize", "complete", "getBoundingClientRect", "selected", "triggerArray", "isOpen", "top", "bottom", "right", "left", "auto", "basePlacements", "start", "end", "clippingParents", "viewport", "popper", "reference", "variationPlacements", "reduce", "acc", "placement", "placements", "beforeRead", "read", "afterRead", "beforeMain", "main", "afterMain", "beforeWrite", "write", "afterWrite", "modifierPhases", "getNodeName", "nodeName", "getWindow", "node", "ownerDocument", "defaultView", "isHTMLElement", "HTMLElement", "isShadowRoot", "applyStyles$1", "enabled", "phase", "_ref", "state", "elements", "forEach", "styles", "assign", "effect", "_ref2", "initialStyles", "position", "options", "strategy", "margin", "arrow", "hasOwnProperty", "attribute", "requires", "getBasePlacement", "round", "getUAString", "uaData", "userAgentData", "brands", "isArray", "item", "brand", "version", "userAgent", "isLayoutViewport", "includeScale", "isFixedStrategy", "clientRect", "scaleX", "scaleY", "offsetWidth", "width", "height", "visualViewport", "addVisualOffsets", "x", "offsetLeft", "y", "offsetTop", "getLayoutRect", "rootNode", "isSameNode", "host", "isTableElement", "getDocumentElement", "getParentNode", "assignedSlot", "getTrueOffsetParent", "offsetParent", "getOffsetParent", "isFirefox", "currentNode", "css", "transform", "perspective", "contain", "willChange", "getMainAxisFromPlacement", "within", "mathMax", "mathMin", "mergePaddingObject", "paddingObject", "expandToHashMap", "hashMap", "arrow$1", "_state$modifiersData$", "arrowElement", "popperOffsets", "modifiersData", "basePlacement", "axis", "len", "padding", "rects", "arrowRect", "minProp", "maxProp", "endDiff", "startDiff", "arrowOffsetParent", "clientSize", "clientHeight", "clientWidth", "centerToReference", "center", "offset", "axisProp", "centerOffset", "_options$element", "requiresIfExists", "getVariation", "unsetSides", "mapToStyles", "_Object$assign2", "popperRect", "variation", "offsets", "gpuAcceleration", "adaptive", "roundOffsets", "isFixed", "_offsets$x", "_offsets$y", "_ref3", "hasX", "hasY", "sideX", "sideY", "win", "heightProp", "widthProp", "_Object$assign", "commonStyles", "_ref4", "dpr", "devicePixelRatio", "computeStyles$1", "_ref5", "_options$gpuAccelerat", "_options$adaptive", "_options$roundOffsets", "passive", "eventListeners", "_options$scroll", "scroll", "_options$resize", "resize", "scrollParents", "scrollParent", "update", "hash", "getOppositePlacement", "matched", "getOppositeVariationPlacement", "getWindowScroll", "scrollLeft", "pageXOffset", "scrollTop", "pageYOffset", "getWindowScrollBarX", "isScrollParent", "_getComputedStyle", "overflow", "overflowX", "overflowY", "getScrollParent", "listScrollParents", "_element$ownerDocumen", "isBody", "updatedList", "rectToClientRect", "rect", "getClientRectFromMixedType", "clippingParent", "html", "layoutViewport", "clientTop", "clientLeft", "winScroll", "scrollWidth", "scrollHeight", "computeOffsets", "commonX", "commonY", "mainAxis", "detectOverflow", "_options", "_options$placement", "_options$strategy", "_options$boundary", "boundary", "_options$rootBoundary", "rootBoundary", "_options$elementConte", "elementContext", "_options$altBoundary", "altBoundary", "_options$padding", "altContext", "clippingClientRect", "mainClippingParents", "clipperElement", "firstClippingParent", "clippingRect", "accRect", "contextElement", "referenceClientRect", "popperClientRect", "elementClientRect", "overflowOffsets", "offsetData", "multiply", "computeAutoPlacement", "flipVariations", "_options$allowedAutoP", "allowedAutoPlacements", "allPlacements", "allowedPlacements", "overflows", "sort", "a", "b", "flip$1", "_skip", "_options$mainAxis", "checkMainAxis", "_options$altAxis", "altAxis", "checkAltAxis", "specifiedFallbackPlacements", "fallbackPlacements", "_options$flipVariatio", "preferredPlacement", "oppositePlacement", "referenceRect", "checksMap", "makeFallbackChecks", "firstFittingPlacement", "i", "_basePlacement", "isStartVariation", "isVertical", "mainVariationSide", "altVariationSide", "checks", "every", "check", "_loop", "_i", "fittingPlacement", "reset", "getSideOffsets", "preventedOffsets", "isAnySideFullyClipped", "some", "side", "hide$1", "preventOverflow", "referenceOverflow", "popperAltOverflow", "referenceClippingOffsets", "popperEscapeOffsets", "isReferenceHidden", "hasPopperEscaped", "offset$1", "_options$offset", "invertDistance", "skidding", "distance", "_data$state$placement", "popperOffsets$1", "preventOverflow$1", "_options$tether", "tether", "_options$tetherOffset", "tetherOffset", "isBasePlacement", "tetherOffsetValue", "normalizedTetherOffsetValue", "offsetModifierState", "_offsetModifierState$", "mainSide", "altSide", "additive", "minLen", "maxLen", "arrowPaddingObject", "arrowPaddingMin", "arrowPaddingMax", "arrowLen", "minOffset", "maxOffset", "clientOffset", "offsetModifierValue", "tetherMax", "preventedOffset", "_offsetModifierState$2", "_mainSide", "_altSide", "_offset", "_len", "_min", "_max", "isOriginSide", "_offsetModifierValue", "_tetherMin", "_tetherMax", "_preventedOffset", "v", "getCompositeRect", "elementOrVirtualElement", "isOffsetParentAnElement", "offsetParentIsScaled", "modifiers", "visited", "result", "modifier", "dep", "depModifier", "DEFAULT_OPTIONS", "areValidElements", "arguments", "_key", "popperGenerator", "generatorOptions", "_generatorOptions", "_generatorOptions$def", "defaultModifiers", "_generatorOptions$def2", "defaultOptions", "pending", "orderedModifiers", "effectCleanupFns", "isDestroyed", "setOptions", "setOptionsAction", "cleanupModifierEffects", "merged", "current", "existing", "m", "_ref$options", "cleanupFn", "forceUpdate", "_state$elements", "_state$orderedModifie", "_state$orderedModifie2", "Promise", "resolve", "then", "destroy", "onFirstUpdate", "createPopper", "computeStyles", "applyStyles", "flip", "ARROW_UP_KEY", "ARROW_DOWN_KEY", "EVENT_KEYDOWN_DATA_API", "EVENT_KEYUP_DATA_API", "SELECTOR_DATA_TOGGLE_SHOWN", "SELECTOR_MENU", "PLACEMENT_TOP", "PLACEMENT_TOPEND", "PLACEMENT_BOTTOM", "PLACEMENT_BOTTOMEND", "PLACEMENT_RIGHT", "PLACEMENT_LEFT", "autoClose", "display", "popperConfig", "Dropdown", "_popper", "_parent", "_menu", "_inNavbar", "_detectNavbar", "_createPopper", "focus", "_completeHide", "Popper", "referenceElement", "_getPopperConfig", "_getPlacement", "parentDropdown", "isEnd", "_getOffset", "popperData", "defaultBsPopperConfig", "_selectMenuItem", "openToggles", "context", "composedPath", "isMenuTarget", "isInput", "isEscapeEvent", "isUpOrDownEvent", "getToggleButton", "stopPropagation", "dataApiKeydownHandler", "clearMenus", "EVENT_MOUSEDOWN", "className", "clickCallback", "rootElement", "Backdrop", "_isAppended", "_append", "_getElement", "_emulateAnimation", "backdrop", "createElement", "append", "EVENT_FOCUSIN", "EVENT_KEYDOWN_TAB", "TAB_NAV_BACKWARD", "autofocus", "trapElement", "FocusTrap", "_isActive", "_lastTabNavDirection", "activate", "_handleFocusin", "_handleKeydown", "deactivate", "shiftKey", "SELECTOR_FIXED_CONTENT", "SELECTOR_STICKY_CONTENT", "PROPERTY_PADDING", "PROPERTY_MARGIN", "ScrollBarHelper", "getWidth", "documentWidth", "innerWidth", "_disableOverFlow", "_setElementAttributes", "calculatedValue", "_resetElementAttributes", "isOverflowing", "_saveInitialAttribute", "styleProperty", "scrollbarWidth", "_applyManipulationCallback", "setProperty", "actualValue", "removeProperty", "callBack", "EVENT_HIDE_PREVENTED", "EVENT_RESIZE", "EVENT_CLICK_DISMISS", "EVENT_MOUSEDOWN_DISMISS", "EVENT_KEYDOWN_DISMISS", "CLASS_NAME_OPEN", "CLASS_NAME_STATIC", "Modal", "_dialog", "_backdrop", "_initializeBackDrop", "_focustrap", "_initializeFocusTrap", "_scrollBar", "_adjustDialog", "_showElement", "_hideModal", "handleUpdate", "modalBody", "transitionComplete", "_triggerBackdropTransition", "event2", "_resetAdjustments", "isModalOverflowing", "initialOverflowY", "isBodyOverflowing", "paddingLeft", "paddingRight", "showEvent", "alreadyOpen", "CLASS_NAME_SHOWING", "CLASS_NAME_HIDING", "OPEN_SELECTOR", "Offcanvas", "blur", "completeCallback", "DefaultAllowlist", "area", "br", "col", "code", "dd", "div", "dl", "dt", "em", "hr", "h1", "h2", "h3", "h4", "h5", "h6", "li", "ol", "p", "pre", "s", "small", "span", "sub", "sup", "strong", "u", "ul", "uriAttributes", "SAFE_URL_PATTERN", "allowedAttribute", "allowedAttributeList", "attributeName", "nodeValue", "attributeRegex", "regex", "allowList", "content", "extraClass", "sanitize", "sanitizeFn", "template", "DefaultContentType", "entry", "TemplateFactory", "getContent", "_resolvePossibleFunction", "hasContent", "changeContent", "_checkContent", "toHtml", "templateWrapper", "innerHTML", "_maybeSanitize", "text", "_setContent", "arg", "templateElement", "_putElementInTemplate", "textContent", "unsafeHtml", "sanitizeFunction", "createdDocument", "DOMParser", "parseFromString", "elementName", "attributeList", "allowedAttributes", "DISALLOWED_ATTRIBUTES", "CLASS_NAME_FADE", "SELECTOR_TOOLTIP_INNER", "SELECTOR_MODAL", "EVENT_MODAL_HIDE", "TRIGGER_HOVER", "TRIGGER_FOCUS", "TRIGGER_CLICK", "AttachmentMap", "AUTO", "TOP", "RIGHT", "BOTTOM", "LEFT", "animation", "container", "customClass", "delay", "title", "Tooltip", "_isEnabled", "_timeout", "_isHovered", "_activeTrigger", "_templateFactory", "_newContent", "tip", "_setListeners", "_fixTitle", "enable", "disable", "toggleEnabled", "_leave", "_enter", "_hideModalHandler", "_disposePopper", "_isWithContent", "isInTheDom", "_getTipElement", "_isWithActiveTrigger", "_getTitle", "_createTipElement", "_getContentForTemplate", "_getTemplateFactory", "tipId", "prefix", "floor", "random", "getElementById", "setContent", "_initializeOnDelegatedTarget", "_getDelegateConfig", "attachment", "triggers", "eventIn", "eventOut", "_setTimeout", "timeout", "dataAttributes", "dataAttribute", "SELECTOR_TITLE", "SELECTOR_CONTENT", "Popover", "_getContent", "EVENT_ACTIVATE", "EVENT_CLICK", "SELECTOR_TARGET_LINKS", "SELECTOR_NAV_LINKS", "SELECTOR_LINK_ITEMS", "rootMargin", "smoothScroll", "threshold", "ScrollSpy", "_targetLinks", "_observableSections", "_rootElement", "_activeTarget", "_observer", "_previousScrollData", "visibleEntryTop", "parentScrollTop", "refresh", "_initializeTargetsAndObservables", "_maybeEnableSmoothScroll", "disconnect", "_getNewObserver", "section", "observe", "observableSection", "scrollTo", "behavior", "IntersectionObserver", "_observerCallback", "targetElement", "_process", "userScrollsDown", "isIntersecting", "_clearActiveClass", "entryIsLowerThanPrevious", "targetLinks", "anchor", "decodeURI", "_activateParents", "listGroup", "activeNodes", "spy", "HOME_KEY", "END_KEY", "SELECTOR_DROPDOWN_TOGGLE", "NOT_SELECTOR_DROPDOWN_TOGGLE", "SELECTOR_INNER_ELEM", "SELECTOR_DATA_TOGGLE_ACTIVE", "Tab", "_setInitialAttributes", "_getChildren", "innerElem", "_elemIsActive", "active", "_getActiveElem", "hideEvent", "_deactivate", "_activate", "relatedElem", "_toggleDropDown", "nextActiveElement", "preventScroll", "_setAttributeIfNotExists", "_setInitialAttributesOnChild", "_getInnerElement", "isActive", "outerElem", "_getOuterElement", "_setInitialAttributesOnTargetPanel", "open", "EVENT_MOUSEOVER", "EVENT_MOUSEOUT", "EVENT_FOCUSOUT", "CLASS_NAME_HIDE", "autohide", "Toast", "_hasMouseInteraction", "_hasKeyboardInteraction", "_clearTimeout", "_maybeScheduleHide", "isShown", "_onInteraction", "isInteracting", "exports", "module", "global", "Bss", "options", "_a", "i", "active", "e", "option", "exports", "module", "exports", "module", "objectToString", "O", "isSymbol", "options", "has", "isArray", "indent", "indexOf", "isRegExp", "keys", "isElement", "s", "i", "quote", "isError", "isMap", "isSet", "isNumber", "isBoolean", "isString", "isPlainObject", "stringTag", "style", "e", "f", "m", "x", "l", "c", "n", "k", "j", "exports", "module", "list", "node", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "isNaN", "a", "exports", "module", "exports", "module", "exports", "module", "e", "exports", "module", "e", "exports", "module", "_", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "concatty", "a", "b", "i", "j", "slicy", "bind", "result", "Empty", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "bind", "exports", "module", "bind", "exports", "module", "e", "exports", "module", "O", "exports", "module", "bind", "exports", "module", "undefined", "round", "e", "doEval", "fn", "bind", "rePropName", "reEscapeChar", "stringToPath", "first", "last", "result", "quote", "getBaseIntrinsic", "i", "exports", "module", "exports", "module", "result", "exports", "module", "exports", "module", "exports", "module", "exports", "module", "defineProperty", "has", "isArray", "markOverflow", "isOverflow", "getMaxIndex", "setMaxIndex", "i", "compactQueue", "j", "arrayToObject", "options", "setProperty", "merge", "result", "m", "assign", "decode", "e", "limit", "encode", "format", "last", "c", "compact", "keys", "isRegExp", "isBuffer", "combine", "a", "b", "maybeMap", "fn", "exports", "module", "utils", "has", "repeat", "isArray", "push", "defaults", "isNonNullishPrimitive", "v", "stringify", "format", "value", "keys", "j", "normalizeStringifyOptions", "options", "i", "exports", "module", "utils", "has", "isArray", "defaults", "options", "limit", "i", "root", "index", "splitKeyIntoSegments", "first", "parent", "n", "close", "keys", "normalizeParseOptions", "exports", "module", "stringify", "parse", "exports", "module", "global", "isNode", "createStore", "queries", "actions", "state", "getState", "processActionQueue", "processDispatchQueue", "data", "dispatch", "query", "defineProperty", "property", "forin", "createObject", "attr", "node", "name", "isSVGElement", "createElement", "element", "appendChild", "parent", "index", "appendChildView", "removeChildView", "isBrowser", "getViewRect", "scale", "expandRect", "calculateRectSize", "isNumber", "thereYet", "spring", "interpolate", "f", "setTarget", "get", "easeLinear", "t", "easeInOutQuad", "tween", "delay", "start", "p", "set", "createAnimator", "props", "addGetSet", "keys", "o", "getter", "setter", "animations", "animator", "write", "addEvent", "fn", "removeEvent", "listeners", "add", "remove", "apis", "isDefined", "defaults", "styles", "getOffset", "getScale", "getRect", "propsHaveChanged", "applyStyles", "width", "height", "updateRect", "style", "createView", "create", "writers", "readers", "getElement", "getChildViews", "getReference", "createChildView", "store", "getStyle", "_read", "_write", "_destroy", "is", "a", "b", "createPainter", "last", "id", "setTimerType", "requestTick", "tick", "cancelTick", "read", "createRoute", "root", "insertBefore", "insertAfter", "isArray", "isEmpty", "trim", "toString", "toArray", "isBoolean", "toBoolean", "isString", "toNumber", "toInt", "toFloat", "isInt", "toBytes", "isFunction", "toFunctionReference", "createServerAPI", "createAction", "timeout", "toServerAPI", "isNull", "isObject", "isAPI", "getType", "replaceSingleQuotes", "e", "convertTo", "getValueByType", "createOption", "createOptions", "options", "createInitialState", "fromCamels", "createOptionAPI", "createOptionActions", "createOptionQueries", "getUniqueId", "obj", "children", "i", "resolve", "result", "arg", "error", "self", "instance", "ownKeys", "symbols", "_getPrototypeOf", "_setPrototypeOf", "_construct", "Parent", "args", "Class", "_wrapNativeSuper", "_get", "target", "receiver", "value", "s", "_e", "input", "res", "desc", "v", "r", "O", "elements", "F", "j", "k", "other", "re", "groups", "_", "g", "arrayRemove", "run", "on", "off", "fire", "copyObjectPropertiesToObject", "createItemAPI", "item", "removeReleasedItems", "getNonNumeric", "getDecimalSeparator", "getThousandsSeparator", "applyFilterChain", "utils", "next", "applyFilters", "addFilter", "extendDefaultOptions", "defaultOptions", "getOptions", "setOptions", "getItemByQuery", "getNumericAspectRatioFromString", "getActiveItems", "canUpdateFileInput", "isItemInErrorState", "isItemInBusyState", "isItemInReadyState", "isAsync", "option", "hasRoomForItem", "count", "limit", "arrayInsert", "insertItem", "isBase64DataURI", "getFilenameFromURL", "getExtensionFromFilename", "guesstimateExtension", "leftPad", "getDateString", "getFileFromBlob", "blob", "file", "getBlobBuilder", "createBlob", "getBlobFromByteStringWithMimeType", "getMimeTypeFromBase64DataURI", "getBase64DataFromBase64DataURI", "getByteStringFromBase64DataURI", "getBlobFromBase64DataURI", "getFileFromBase64DataURI", "getFileNameFromHeader", "getFileSizeFromHeader", "getTranfserIdFromHeader", "getFileInfoFromHeaders", "createFileLoader", "getProgress", "abort", "load", "loadURL", "isGet", "sendRequest", "onprogress", "process", "createResponse", "createTimeoutResponse", "hasQS", "buildURL", "createFetchFunction", "headers", "processFileChunked", "requestTransferId", "requestTransferOffset", "completeProcessingChunks", "canProcessChunk", "processChunk", "chunk", "ondata", "onerror", "onload", "retryProcessChunk", "updateTotalProgress", "processChunks", "abortChunks", "offset", "createFileProcessorFunction", "createProcessorFunction", "createRevertFunction", "getRandomNumber", "createPerceivedPerformanceUpdater", "clear", "createFileProcessor", "progressFn", "completeFn", "reset", "getFilenameWithoutExtension", "createFileStub", "isFile", "deepCloneObject", "createItem", "setStatus", "getFileExtension", "getFileType", "getFileSize", "getFile", "success", "retryLoad", "abortLoad", "processor", "serverFileReference", "requestProcessing", "abortProcessing", "abortProcessingRequestComplete", "revert", "key", "getMetadata", "extend", "getItemIndexByQuery", "getItemById", "fetchBlob", "getDomainFromURL", "isExternalURL", "dynamicLabel", "isMockItem", "listUpdated", "optionalPromise", "sortItems", "getItemByQueryFromState", "upload", "isValidFile", "handleAdd", "loadComplete", "fetch", "processNow", "processNext", "failure", "noop", "removeFromView", "handleRevert", "formatFilename", "text", "polarToCartesian", "describeArc", "x", "y", "percentageArc", "create$1", "toNaturalFileSize", "removeDecimalsWhenZero", "updateFile", "updateFileSizeOnError", "toPercentage", "didSetItemLoadProgress", "didSetItemProcessProgress", "didRequestItemProcessing", "didAbortItemProcessing", "didCompleteItemProcessing", "calculateFileInfoOffset", "calculateButtonWidth", "calculateFileVerticalCenterOffset", "calculateFileHorizontalCenterOffset", "getLoadIndicatorAlignment", "getProcessIndicatorAlignment", "getRemoveIndicatorAligment", "buttonFilter", "map", "action", "didLoadItem", "createSection", "createDragHelper", "getIndex", "grab", "drag", "drop", "cancel", "getItemIndexByPosition", "l", "addItemView", "now", "moveItem", "introItemView", "removeItemView", "getItemHeight", "getItemWidth", "dragItem", "location", "currentIndex", "dragHeight", "itemHeight", "offsetY", "filterSetItemActions", "list", "storeDragCoordinates", "clearDragCoordinates", "attrToggle", "resetFileInput", "parentNode", "setAcceptedFileTypes", "toggleAllowMultiple", "toggleDirectoryFilter", "toggleDisabled", "toggleRequired", "setCaptureMethod", "updateRequiredStatus", "updateFieldValidityStatus", "updateLabelValue", "addBlob", "moveBlob", "hideBlob", "explodeBlob", "setInputFiles", "getField", "syncFieldPositionsWithItems", "didReorderItems", "didAddItem", "didPrepareOutput", "didSetDisabled", "didRemoveItem", "didDefineValue", "getRootNode", "guesstimateMimeType", "requestDataTransferItems", "getFiles", "hasFiles", "isFileSystemItem", "getFilesFromItem", "getFilesInDirectory", "resolveIfDone", "readEntries", "readBatch", "entry", "correctMissingFileType", "isDirectoryEntry", "isEntry", "getAsEntry", "getLinks", "getLinksFromTransferURLData", "getLinksFromTransferMetaData", "eventPosition", "createDragNDropClient", "observer", "getDragNDropObserver", "createDragNDropObserver", "handlers", "elementFromPoint", "isEventTarget", "setDropEffect", "dragenter", "dragover", "dragleave", "createHopper", "handlePaste", "listen", "unlisten", "createPaster", "cb", "assist", "listModified", "isUsingFilePond", "itemAdded", "itemRemoved", "itemProcessed", "itemProcessedUndo", "itemError", "toCamels", "debounce", "prevent", "panel", "history", "calculateListItemMargin", "calculateListHeight", "calculateRootBoundingBoxHeight", "exceedsMaxFiles", "getDragIndex", "toggleDrop", "toggleBrowse", "togglePaste", "createApp", "visibilityHandler", "resizeHandler", "createEvent", "exposeEvent", "routeActionsToEvents", "route", "prepareFile", "addFile", "isFilePondFile", "removeFile", "addFiles", "processFile", "prepareFiles", "processFiles", "removeFiles", "q", "browse", "createAppObject", "lowerCaseFirstLetter", "attributeNameToPropertyName", "mapObject", "getAttributesAsObject", "createAppAtElement", "createAppAPI", "replaceInString", "createWorker", "post", "loadImage", "renameFile", "copyFile", "createAppPlugin", "plugin", "isOperaMini", "hasPromises", "hasBlobSlice", "hasCreateObjectURL", "hasVisibility", "hasTiming", "hasCSSSupports", "isIE11", "updateOptionTypes", "hook", "app", "parse", "registerPlugin", "exports", "module", "global", "plugin", "utils", "sizeMin", "resolve", "isBrowser", "exports", "module", "global", "plugin", "utils", "isString", "getExtensionFromFilename", "getFilenameFromURL", "mimeTypeMatchesWildCard", "isValidMimeType", "getItemType", "validateFile", "resolve", "applyMimeTypeMap", "map", "handleRejection", "index", "isBrowser", "exports", "module", "global", "createPosterView", "_", "create", "root", "props", "applyTemplate", "createPosterOverlayView", "getImageSize", "image", "width", "height", "easeInOutSine", "t", "addGradientSteps", "i", "p", "calculateAverageColor", "scalar", "e", "l", "r", "g", "b", "averageColor", "c", "drawTemplate", "loadImage", "resolve", "createPosterWrapperView", "didCreatePreviewContainer", "previewImageLoaded", "didLoadPreview", "didDrawPreview", "restoreOverlay", "didThrowError", "didCompleteProcessing", "plugin", "utils", "is", "didLoadItem", "didUpdateItemMetadata", "updateItemPoster", "didCalculatePreviewSize", "getPosterHeight", "isBrowser", "WINDOW", "metrics", "withIsolationScope", "withScope", "DEBUG_BUILD", "console", "logger", "DEBUG_BUILD", "a", "b", "p", "i", "parser", "frame", "fn", "e", "e", "DEBUG_BUILD", "error", "e", "_e", "options", "height", "c", "k", "attr", "i", "start", "input", "i", "e", "e", "DEBUG_BUILD", "property", "keys", "input", "e2", "performance", "crypto", "_", "c", "frame", "e", "States", "resolve", "_", "e", "result", "session", "lastEventId", "session", "ScopeClass", "e", "ScopeClass", "withScope", "withIsolationScope", "DEBUG_BUILD", "op", "input", "e", "span", "options", "fn", "e", "options", "op", "description", "options", "protocol", "host", "DEBUG_BUILD", "memoize", "i", "input", "memoize", "result", "_", "input", "append", "next", "e", "env", "i", "version", "session", "dsc", "a", "b", "input", "options", "withScope", "options", "span", "timestamp", "index", "resolve", "processor", "result", "result", "i", "options", "i", "result", "frame", "e", "b", "timeout", "userAgent", "session", "protocol", "options", "processor", "fn", "options", "option", "session", "timeout", "result", "env", "promise", "count", "hook", "hooks", "resolve", "tick", "isError", "isErrorEvent", "e", "options", "limit", "remove", "add", "timeout", "resolve", "now", "limit", "delay", "options", "flush", "timeout", "error", "result", "createTransport", "options", "env", "error", "retryDelay", "delay", "e", "result", "timeout", "env", "createTransport", "options", "result", "t", "flush", "timeout", "r", "options", "names", "name", "options", "e", "INTEGRATION_NAME", "options", "e", "i", "frame", "parser", "limit", "error", "i", "parser", "frame", "_", "INTEGRATION_NAME", "options", "withScope", "message", "error", "INTEGRATION_NAME", "options", "INTEGRATION_NAME", "_shouldDropEvent", "i", "INTEGRATION_NAME", "options", "error", "nativeKeys", "i", "last", "p", "start", "toParts", "f", "INTEGRATION_NAME", "options", "root", "isBrowser", "f", "frame", "INTEGRATION_NAME", "now", "INTEGRATION_NAME", "p", "limit", "e", "options", "options", "keys", "frame", "a", "b", "s", "i", "c", "input", "first", "shouldAttachHeaders", "span", "host", "options", "e", "withScope", "_sendSessionUpdate", "session", "WINDOW", "WINDOW", "e", "result", "DEBUG_BUILD", "error", "e", "options", "process", "WINDOW", "i", "op", "fn", "WINDOW", "fn", "options", "isFunction", "e", "withScope", "property", "e2", "DEBUG_BUILD", "e", "keys", "options", "WINDOW", "DEBUG_BUILD", "DEBUG_BUILD", "WINDOW", "WINDOW", "WINDOW", "po", "list", "e", "WINDOW", "WINDOW", "WINDOW", "po", "po", "po", "e", "a", "b", "i", "WINDOW", "WINDOW", "po", "po", "WINDOW", "WINDOW", "handlers", "instrumented", "addHandler", "triggerHandlers", "e", "DEBUG_BUILD", "options", "index", "_a", "options", "e", "WINDOW", "version", "DEBUG_BUILD", "e", "performance", "WINDOW", "parent", "observer", "list", "options", "op", "start", "version", "navigator", "index", "_measurements", "WINDOW", "options", "handlers", "e", "WINDOW", "WINDOW", "document", "e", "DEBUG_BUILD", "setTimeout", "WINDOW", "parseUrl", "e", "e2", "performance", "entry", "last", "options", "e", "frame", "line", "INTEGRATION_NAME", "options", "DEBUG_BUILD", "element", "e", "WINDOW", "INTEGRATION_NAME", "options", "WINDOW", "fn", "e2", "e", "WINDOW", "DEBUG_BUILD", "INTEGRATION_NAME", "options", "error", "e", "e2", "DEBUG_BUILD", "WINDOW", "userAgent", "DEFAULT_LIMIT", "INTEGRATION_NAME", "options", "limit", "options", "defaultOptions", "WINDOW", "protocol", "DEBUG_BUILD", "WINDOW", "waitForLoad", "resolve", "parent", "e", "options", "WINDOW", "INTEGRATION_NAME", "SETUP_CLIENTS", "options", "withScope", "observer", "INTEGRATION_NAME", "options", "_wrapXHR", "error", "e2", "result", "e", "DEBUG_BUILD", "WINDOW", "INTEGRATION_NAME", "options", "html", "frame", "WINDOW", "_nullishCoalesce", "_optionalChain", "i", "op", "fn", "NodeType", "isElement", "n", "host", "_", "shadowRoot", "rule", "s", "rules", "error", "node", "isMasked", "element", "text", "x", "y", "cachedImplementations", "getImplementation", "document", "e", "setTimeout", "clearTimeout", "chars", "c", "a", "limit", "e2", "options", "mirror", "textContent", "isTextarea", "attr", "image", "width", "height", "throttle", "wait", "timeout", "now", "d", "EventType2", "IncrementalSource2", "MouseInteractions2", "PointerTypes2", "index", "parentId", "m", "r", "set", "parentNode", "getEventTarget", "mutationObserverCtor", "observer", "p", "handlers", "h", "el", "v", "result", "property", "FontFace", "updateSelection", "count", "o", "plugin", "b", "map", "style", "keys", "option", "errorHandler", "takeFullSnapshot", "canvasManager", "observe", "init", "start", "DEBUG_BUILD", "CONSOLE_LEVELS", "PREFIX", "coreLogger", "logger", "resolve", "getWorkerURL", "makeSession", "session", "isErrorEvent", "isTransactionEvent", "dsc", "warning", "first", "last", "input", "request", "response", "flush", "version", "err", "block", "NodeType", "elementClassMatchesRegex", "distanceToMatch", "node", "limit", "createMatchPredicate", "e2", "DEPARTED_MIRROR_ACCESS_WARNING", "_mirror", "hookSetter", "d", "setTimeout", "patch", "closestElementOfNode", "isBlocked", "cachedImplementations", "getImplementation", "document", "e", "onRequestAnimationFrame", "CanvasContext2", "errorHandler", "registerErrorHandler", "callbackWrapper", "error", "i", "list", "index", "handlers", "v", "h", "mirror", "props", "result", "r", "t", "_", "options", "shadowRoot", "width", "height", "canvasElement", "root", "window", "_a", "type", "INTEGRATION_NAME", "resolve", "canvasManager", "WINDOW", "NAVIGATOR", "resolve", "timeout", "DEBUG_BUILD", "defaultOptions", "error", "style", "XMLNS", "g", "shadow", "lazyLoadIntegration", "options", "host", "e", "e2", "handleClick", "l", "u", "i", "o", "r", "f", "c", "s", "a", "h", "v", "n", "p", "y", "t", "d", "b", "m", "w", "k", "x", "C", "j", "P", "_", "T", "A", "D", "S", "$", "H", "I", "q", "z", "B", "useMemo", "props", "useState", "useCallback", "_a", "timeoutId", "Fragment", "sendFeedback", "shadowRoot", "render", "hooks", "width", "height", "container", "blob", "increment", "metricsCore", "distribution", "set", "gauge", "timing", "metrics", "_", "getFullURL", "host", "getAbsoluteTime", "version", "WINDOW", "e", "shouldAttachHeaders", "span", "e2", "WINDOW", "op", "DEBUG_BUILD", "WINDOW", "DEBUG_BUILD", "op", "resolve", "store", "keys", "options", "env", "_", "createTransport", "WINDOW", "WINDOW", "e", "DEBUG_BUILD", "input", "start", "i", "frame", "j", "options", "last", "DEBUG_BUILD", "WINDOW", "error", "INTEGRATION_NAME", "DEBUG_BUILD", "INTEGRATION_NAME", "options", "DEBUG_BUILD", "DEBUG_BUILD", "index", "f", "result", "DEBUG_BUILD", "visit", "_a", "style", "element", "html", "resolve", "indent", "result", "i", "_", "elements", "getMetaContent", "debounce", "fn", "delay", "timeoutId", "submitter", "config", "location", "options", "error", "toCacheKey", "index", "input", "cookie", "snapshot", "node", "x", "y", "clone", "block", "defaults", "ctx", "morphChildren", "removeNode", "findBestMatch", "parentNode", "e", "morphNode", "ignoreAttribute", "attr", "promise", "createMorphContext", "root", "normalizeElement", "normalizeParent", "parser", "option", "session", "visit", "frame", "Navigator", "recentRequests", "timing", "container", "Turbo", "findFrameElement_fn", "document", "c", "createConsumer", "m", "x", "submitter", "options", "Castle", "o", "e", "_a", "r", "t", "s", "i", "n", "l", "a", "d", "h", "o", "p", "l", "a", "t", "_a", "e", "n", "r", "s", "i", "c", "l", "_a", "root", "Symbol", "e", "result", "objectProto", "nativeObjectToString", "objectToString", "symToStringTag", "index", "result", "result", "index", "isBinary", "identity", "uid", "e", "funcProto", "objectProto", "funcToString", "hasOwnProperty", "WeakMap", "result", "index", "count", "e", "index", "objectProto", "hasOwnProperty", "props", "index", "start", "transform", "index", "start", "MAX_SAFE_INTEGER", "index", "index", "objectProto", "n", "index", "result", "objectProto", "hasOwnProperty", "Buffer", "argsTag", "funcTag", "setTag", "freeExports", "freeModule", "moduleExports", "e", "objectProto", "hasOwnProperty", "result", "transform", "objectProto", "hasOwnProperty", "result", "keys", "result", "objectProto", "hasOwnProperty", "result", "result", "objectProto", "hasOwnProperty", "result", "objectProto", "hasOwnProperty", "HASH_UNDEFINED", "index", "index", "index", "index", "index", "Map", "map", "result", "index", "cache", "result", "result", "cache", "result", "quote", "INFINITY", "result", "index", "result", "index", "objectTag", "funcProto", "objectProto", "funcToString", "hasOwnProperty", "isPlainObject", "start", "index", "result", "start", "rsAstralRange", "rsComboMarksRange", "reComboHalfMarksRange", "rsComboSymbolsRange", "rsComboRange", "rsVarRange", "rsZWJ", "result", "freeExports", "freeModule", "moduleExports", "Buffer", "result", "index", "result", "objectProto", "propertyIsEnumerable", "nativeGetSymbols", "result", "result", "DataView", "Promise", "Set", "mapTag", "objectTag", "setTag", "weakMapTag", "dataViewTag", "result", "objectProto", "hasOwnProperty", "result", "Uint8Array", "result", "result", "symbolProto", "boolTag", "dateTag", "mapTag", "numberTag", "regexpTag", "setTag", "stringTag", "symbolTag", "arrayBufferTag", "dataViewTag", "float32Tag", "float64Tag", "int8Tag", "int16Tag", "int32Tag", "uint8Tag", "uint8ClampedTag", "uint16Tag", "uint32Tag", "mapTag", "setTag", "argsTag", "arrayTag", "boolTag", "dateTag", "errorTag", "funcTag", "genTag", "mapTag", "numberTag", "objectTag", "regexpTag", "setTag", "stringTag", "symbolTag", "weakMapTag", "arrayBufferTag", "dataViewTag", "float32Tag", "float64Tag", "int8Tag", "int16Tag", "int32Tag", "uint8Tag", "uint8ClampedTag", "uint16Tag", "uint32Tag", "result", "key", "props", "CLONE_SYMBOLS_FLAG", "CLONE_DEEP_FLAG", "CLONE_SYMBOLS_FLAG", "CLONE_DEEP_FLAG", "CLONE_SYMBOLS_FLAG", "HASH_UNDEFINED", "index", "index", "cache", "index", "result", "othValue", "map", "index", "result", "set", "index", "result", "COMPARE_PARTIAL_FLAG", "COMPARE_UNORDERED_FLAG", "boolTag", "dateTag", "errorTag", "mapTag", "numberTag", "regexpTag", "setTag", "stringTag", "symbolTag", "arrayBufferTag", "dataViewTag", "symbolProto", "symbolValueOf", "convert", "result", "COMPARE_PARTIAL_FLAG", "objectProto", "hasOwnProperty", "index", "result", "COMPARE_PARTIAL_FLAG", "argsTag", "arrayTag", "objectTag", "objectProto", "hasOwnProperty", "COMPARE_PARTIAL_FLAG", "COMPARE_UNORDERED_FLAG", "index", "result", "result", "index", "result", "COMPARE_PARTIAL_FLAG", "COMPARE_UNORDERED_FLAG", "index", "props", "collection", "index", "now", "FUNC_ERROR_TEXT", "nativeMax", "debounce", "wait", "options", "result", "cancel", "flush", "collection", "index", "result", "collection", "stringTag", "isString", "isElement", "result", "result", "object", "merge", "index", "set", "FUNC_ERROR_TEXT", "throttle", "wait", "options", "globalVar", "window", "document", "e", "global", "getUserAgent", "navigator", "userAgent", "toLowerCase", "env", "isMac", "isWindows", "isGecko", "isSafari", "isiOS", "isAndroid", "isBlink", "isMediaForcedColors", "isMotionReduced", "features", "isRegExpUnicodePropertySupported", "indexOf", "match", "maxTouchPoints", "isSupported", "search", "RegExp", "error", "matchMedia", "matches", "fastDiff", "a", "b", "cmp", "atomicChanges", "arrayA", "Array", "isArray", "prototype", "slice", "call", "arrayB", "changeIndexes", "findChangeBoundaryIndexes", "result", "changeIndexesToAtomicChanges", "length", "changeIndexesToChanges", "arr1", "arr2", "firstIndex", "findFirstDifferenceIndex", "lastIndexOld", "lastIndexNew", "oldArrayReversed", "cutAndReverse", "newArrayReversed", "lastIndex", "i", "Math", "max", "undefined", "arr", "howMany", "reverse", "newArray", "push", "index", "type", "values", "newLength", "fill", "concat", "diff", "aLength", "bLength", "_insert", "_delete", "tmp", "m", "n", "delta", "es", "fp", "snake", "k", "y1", "y2", "dir", "y", "x", "p", "spy", "called", "EventInfo", "constructor", "source", "name", "path", "stop", "off", "HEX_NUMBERS", "Array", "fill", "map", "_", "index", "toString", "slice", "uid", "r1", "r2", "r3", "r4", "crypto", "getRandomValues", "Uint32Array", "priorities", "get", "priority", "normal", "highest", "high", "low", "lowest", "insertToPriorityArray", "objects", "objectToInsert", "i", "length", "splice", "push", "DOCUMENTATION_URL", "CKEditorError", "Error", "errorName", "context", "data", "getErrorMessage", "is", "type", "rethrowUnexpectedError", "err", "error", "message", "stack", "logWarning", "console", "warn", "formatConsoleArguments", "getLinkToDocumentationMessage", "errorName", "DOCUMENTATION_URL", "getErrorMessage", "data", "processedObjects", "WeakSet", "circularReferencesReplacer", "key", "value", "has", "constructor", "name", "add", "stringifiedData", "JSON", "stringify", "documentationLink", "formatConsoleArguments", "documentationMessage", "version", "releaseDate", "Date", "globalThis", "CKEDITOR_VERSION", "CKEditorError", "_listeningTo", "Symbol", "_emitterId", "_delegations", "defaultEmitterClass", "EmitterMixin", "Object", "base", "Mixin", "on", "event", "callback", "options", "listenTo", "once", "wasFired", "onceCallback", "args", "off", "call", "stopListening", "emitter", "emitterInfo", "eventCallbacks", "emitters", "_getEmitterId", "_setEmitterId", "emitterId", "callbacks", "push", "addEventListener", "undefined", "removeEventListener", "index", "indexOf", "length", "pop", "fire", "eventOrInfo", "eventInfo", "EventInfo", "getCallbacksForEvent", "path", "callbackArgs", "Array", "from", "i", "apply", "called", "_removeEventListener", "stop", "delegations", "destinations", "get", "passAllDestinations", "fireDelegatedEvents", "return", "err", "rethrowUnexpectedError", "delegate", "events", "to", "nameOrFunction", "Map", "forEach", "eventName", "set", "stopDelegating", "clear", "delete", "_addEventListener", "createEventNamespace", "lists", "getCallbacksListsForNamespace", "priority", "priorities", "callbackDefinition", "insertToPriorityArray", "splice", "prototype", "_getEmitterListenedTo", "listeningEmitter", "listenedToEmitterId", "listeningTo", "id", "uid", "getEvents", "source", "_events", "defineProperty", "makeEventNode", "childEvents", "childEventName", "newEventNodes", "substr", "lastIndexOf", "node", "slice", "eventNode", "callbacksLists", "childCallbacksLists", "concat", "fireArgs", "delegatedInfo", "listener", "observablePropertiesSymbol", "boundObservablesSymbol", "boundPropertiesSymbol", "decoratedMethods", "decoratedOriginal", "defaultObservableClass", "ObservableMixin", "isObject", "keys", "property", "initObservable", "properties", "enumerable", "configurable", "oldValue", "newValue", "bind", "bindProperties", "isStringArray", "Set", "size", "boundProperties", "propertyName", "bindings", "a", "binding", "bindTo", "toMany", "bindToMany", "_observable", "_bindProperties", "_to", "_bindings", "unbind", "unbindProperties", "boundObservables", "toObservable", "toProperty", "toProperties", "toPropertyBindings", "boundObservable", "decorate", "methodName", "originalMethod", "object", "evt", "observable", "parsedArgs", "parseBindToArgs", "bindingsKeys", "numberOfBindings", "attachBindToListeners", "updateBindToBound", "updateBoundObservableProperty", "observables", "attribute", "getBindingTargets", "observableAndAttributePairs", "map", "arr", "every", "parsed", "lastObservable", "updateBoundObservables", "toPropertyName", "bindingsToObservable", "chain", "propertyValue", "hasOwnProperty", "toBindings", "ElementReplacer", "_replacedElements", "element", "newElement", "style", "display", "parentNode", "insertBefore", "nextSibling", "remove", "count", "iterable", "_", "compareArrays", "a", "b", "minLen", "Math", "min", "length", "i", "isIterable", "value", "Symbol", "iterator", "createElement", "doc", "name", "attributes", "children", "namespace", "xmlns", "element", "createElementNS", "key", "setAttribute", "isString", "child", "createTextNode", "appendChild", "Config", "constructor", "configurations", "defaultConfigurations", "_config", "Object", "create", "define", "cloneConfig", "_setObjectToTarget", "set", "_setToTarget", "isDefine", "get", "_getFromSource", "names", "keys", "target", "isPlainObject", "parts", "split", "pop", "part", "source", "undefined", "configuration", "forEach", "cloneDeepWith", "leaveItemReferences", "isElement", "isNode", "obj", "defaultView", "Document", "ownerDocument", "Node", "isWindow", "stringifiedObject", "prototype", "toString", "apply", "defaultEmitterClass", "DomEmitterMixin", "EmitterMixin", "base", "Mixin", "listenTo", "emitter", "event", "callback", "options", "proxyOptions", "capture", "useCapture", "passive", "usePassive", "proxyEmitter", "_getProxyEmitter", "ProxyEmitter", "stopListening", "proxyEmitters", "_getAllProxyEmitters", "proxy", "node", "_getEmitterListenedTo", "getProxyEmitterId", "map", "filter", "_domNode", "_options", "_setEmitterId", "attach", "_domListeners", "domListener", "_createDomListener", "addEventListener", "detach", "events", "_events", "callbacks", "removeListener", "_addEventListener", "call", "_removeEventListener", "domEvt", "fire", "removeEventListener", "getNodeUID", "uid", "id", "option", "sort", "getAncestors", "node", "nodes", "currentNode", "nodeType", "Node", "DOCUMENT_NODE", "unshift", "parentNode", "getDataFromElement", "el", "HTMLTextAreaElement", "value", "innerHTML", "getBorderWidths", "element", "style", "ownerDocument", "defaultView", "getComputedStyle", "top", "parseInt", "borderTopWidth", "right", "borderRightWidth", "bottom", "borderBottomWidth", "left", "borderLeftWidth", "getRangeFromMouseEvent", "domEvent", "target", "domDoc", "x", "clientX", "y", "clientY", "domRange", "caretRangeFromPoint", "rangeParent", "createRange", "setStart", "rangeOffset", "collapse", "isText", "obj", "Object", "prototype", "toString", "call", "isRange", "apply", "getPositionedAncestor", "offsetParent", "global", "document", "body", "rectProperties", "Rect", "constructor", "source", "isSourceRange", "defineProperty", "_source", "writable", "enumerable", "isDomElement", "rangeRects", "getDomRangeRects", "copyRectProperties", "getBoundingRect", "getBoundingClientRect", "isWindow", "innerWidth", "innerHeight", "width", "height", "getIntersection", "anotherRect", "rect", "Math", "max", "min", "newRect", "getIntersectionArea", "getArea", "visibleRect", "clone", "isBody", "child", "parent", "commonAncestorContainer", "absolutelyPositionedChildElement", "isParentOverflowVisible", "getElementOverflow", "HTMLElement", "getElementPosition", "parentElementPosition", "parentRect", "intersectionRect", "isEqual", "prop", "contains", "intersectRect", "scrollX", "scrollY", "window", "absoluteRect", "moveBy", "positionedAncestor", "shiftRectToCompensatePositionedAncestor", "scrollBarWidth", "scrollBarHeight", "direction", "documentElement", "clientWidth", "clientHeight", "borderWidths", "offsetWidth", "offsetHeight", "range", "rects", "clientRects", "Array", "from", "getClientRects", "length", "push", "startContainer", "boundingRectData", "Number", "POSITIVE_INFINITY", "NEGATIVE_INFINITY", "rectangleCount", "p", "position", "overflow", "positionedElementAncestor", "ancestorPosition", "ancestorBorderWidths", "moveX", "moveY", "scrollLeft", "scrollTop", "ResizeObserver", "callback", "_observerInstance", "_createObserver", "_element", "_callback", "_addElementCallback", "observe", "_deleteElementCallback", "_elementCallbacks", "Map", "callbacks", "get", "Set", "set", "add", "_getElementCallbacks", "delete", "size", "unobserve", "entries", "entry", "setDataInElement", "data", "toUnit", "unit", "indexOf", "index", "previousSibling", "insertAt", "parentElement", "nodeToInsert", "insertBefore", "childNodes", "isComment", "COMMENT_NODE", "isValidAttributeName", "name", "createAttribute", "error", "isVisible", "getOptimalPosition", "positions", "limiter", "fitInViewport", "viewportOffsetConfig", "isFunction", "constrainedViewportRect", "getConstrainedViewportRect", "elementRect", "visibleTargetRect", "getVisibleViewportIntersectionRect", "bestPosition", "positionOptions", "targetRect", "viewportRect", "PositionObject", "visibleLimiterRect", "limiterRect", "getBestPosition", "visibleSourceRect", "getVisible", "assign", "options", "elementRectArea", "positionInstances", "map", "positioningFunction", "filter", "maxFitFactor", "limiterIntersectionArea", "viewportIntersectionArea", "fitFactor", "config", "_positioningFunctionCoordinates", "_options", "_cachedRect", "_cachedAbsoluteRect", "positioningFunctionOutput", "_absoluteRect", "_rect", "moveTo", "toAbsoluteRect", "remove", "removeChild", "scrollViewportToShowTarget", "viewportOffset", "ancestorOffset", "alignToTop", "forceScroll", "targetWindow", "getWindow", "currentWindow", "currentFrame", "normalizeViewportOffset", "firstAncestorToScroll", "getParentElement", "scrollAncestorsToShowRect", "getRect", "getRectRelativeToWindow", "scrollWindowToShowRect", "frameElement", "scrollWindowToShowRect", "window", "rect", "alignToTop", "forceScroll", "viewportOffset", "targetShiftedDownRect", "clone", "moveBy", "bottom", "targetShiftedUpRect", "top", "viewportRect", "Rect", "excludeScrollbarsAndBorders", "rects", "forceScrollToTop", "allRectsFitInViewport", "every", "contains", "scrollX", "scrollY", "initialScrollX", "initialScrollY", "isAbove", "isBelow", "isLeftOf", "left", "isRightOf", "right", "scrollTo", "scrollAncestorsToShowRect", "parent", "getRect", "ancestorOffset", "limiterElement", "parentWindow", "getWindow", "parentRect", "targetRect", "targetFitsInTarget", "limiter", "document", "body", "scrollTop", "scrollLeft", "parentNode", "firstRect", "secondRect", "elementOrRange", "isRange", "startContainer", "ownerDocument", "defaultView", "getParentElement", "commonAncestorContainer", "isText", "getRectRelativeToWindow", "target", "relativeWindow", "targetWindow", "currentWindow", "frame", "frameElement", "frameRect", "normalizeViewportOffset", "modifiersToGlyphsMac", "ctrl", "cmd", "alt", "shift", "modifiersToGlyphsNonMac", "keyCodesToGlyphs", "keyCodes", "generateKnownKeyCodes", "keyCodeNames", "Object", "fromEntries", "entries", "map", "name", "code", "prettyKeyName", "charAt", "toUpperCase", "slice", "getCode", "key", "keyCode", "toLowerCase", "CKEditorError", "altKey", "ctrlKey", "shiftKey", "metaKey", "parseKeystroke", "keystroke", "splitKeystrokeText", "getEnvKeyCode", "reduce", "sum", "getEnvKeystrokeText", "keystrokeCode", "modifiersToGlyphs", "env", "isMac", "isiOS", "modifiers", "glyph", "isArrowKeyCode", "arrowright", "arrowleft", "arrowup", "arrowdown", "getLocalizedArrowKeyCodeDirection", "contentLanguageDirection", "isLtrContent", "endsWith", "isForwardArrowKeyCode", "localizedKeyCodeDirection", "pageup", "pagedown", "backspace", "delete", "enter", "space", "esc", "tab", "letter", "String", "fromCharCode", "assign", "split", "trim", "RTL_LANGUAGE_CODES", "getLanguageDirection", "languageCode", "includes", "toArray", "data", "Array", "isArray", "global", "CKEDITOR_TRANSLATIONS", "_translate", "language", "message", "quantity", "translations", "normalizedTranslations", "numberOfLanguages", "getNumberOfLanguages", "keys", "messageId", "id", "string", "hasTranslation", "plural", "dictionary", "getPluralForm", "n", "translation", "pluralFormIndex", "Number", "_unifyTranslations", "acc", "merge", "length", "Locale", "constructor", "uiLanguage", "contentLanguage", "uiLanguageDirection", "t", "values", "_t", "console", "warn", "hasPluralForm", "translatedString", "interpolateString", "replace", "match", "index", "Collection", "EmitterMixin", "initialItemsOrOptions", "options", "hasInitialItems", "isIterable", "_items", "_itemMap", "Map", "_idProperty", "idProperty", "_bindToExternalToInternalMap", "WeakMap", "_bindToInternalToExternalMap", "_skippedIndexesFromExternal", "item", "push", "set", "_getItemIdBeforeAdding", "first", "last", "addMany", "items", "undefined", "offset", "itemId", "currentItemIndex", "splice", "fire", "added", "removed", "get", "idOrIndex", "has", "itemOrId", "getIndex", "indexOf", "remove", "subject", "_remove", "callback", "ctx", "forEach", "find", "filter", "_bindToCollection", "stopListening", "removedItems", "from", "bindTo", "externalCollection", "as", "Class", "_setUpBindToBinding", "using", "callbackOrProperty", "factory", "addItem", "evt", "externalItem", "isExternalBoundToThis", "externalItemBound", "finalIndex", "skipped", "add", "i", "listenTo", "result", "uid", "itemDoesNotExist", "Symbol", "iterator", "iteratorItem", "next", "done", "value", "FocusTracker", "DomEmitterMixin", "ObservableMixin", "_elements", "Set", "_externalViews", "_blurTimeout", "elements", "externalViews", "elementOrView", "isElement", "_addElement", "isViewWithFocusTracker", "_addView", "element", "focusTracker", "view", "_removeElement", "_removeView", "externalFocusedViewInSubtree", "isExternalViewSubtreeFocused", "_focus", "useCapture", "_blur", "focusedElement", "clear", "isFocused", "_clearBlurTimeout", "isAnyElementFocused", "activeElement", "isAnyExternalViewFocused", "setTimeout", "clearTimeout", "_isElement", "subTreeRoot", "isFocusedView", "KeystrokeHandler", "_listener", "emitter", "keyEvtData", "priority", "preventDefault", "stopPropagation", "stop", "return", "press", "objectToMap", "obj", "toMap", "BIG_CHUNK_SIZE", "spliceArray", "target", "source", "start", "count", "Math", "max", "length", "slice", "concat", "newTarget", "Array", "from", "splice", "delay", "func", "wait", "timer", "delayed", "args", "cancel", "setTimeout", "clearTimeout", "verifyLicense", "token", "oldTokenCheck", "decryptedData", "atob", "e", "splittedDecryptedData", "split", "firstElement", "secondElement", "decryptedSecondElement", "year", "Number", "substring", "monthIndex", "day", "date", "Date", "releaseDate", "isNaN", "isCombiningMark", "character", "test", "isHighSurrogateHalf", "isLowSurrogateHalf", "isInsideSurrogatePair", "string", "offset", "charAt", "isInsideCombinedSymbol", "EMOJI_PATTERN", "buildEmojiRegexp", "isInsideEmojiSequence", "matches", "String", "matchAll", "some", "match", "index", "parts", "flagSequence", "emoji", "map", "part", "join", "sequence", "RegExp", "documentPlaceholders", "WeakMap", "hasDisplayedPlaceholderDeprecationWarning", "enablePlaceholder", "view", "element", "text", "isDirectHost", "keepOnFocus", "doc", "document", "has", "set", "Map", "registerPostFixer", "writer", "updateDocumentPlaceholders", "on", "change", "priority", "is", "evtInfo", "evt", "setPlaceholder", "placeholder", "showPlaceholderTextDeprecationWarning", "get", "hostElement", "showPlaceholder", "writer", "element", "hasClass", "addClass", "hidePlaceholder", "removeClass", "needsPlaceholder", "keepOnFocus", "isAttached", "hasContent", "Array", "from", "getChildren", "some", "is", "doc", "document", "viewSelection", "selection", "selectionAnchor", "anchor", "isComposing", "parent", "isFocused", "updateDocumentPlaceholders", "placeholders", "documentPlaceholders", "get", "directHostElements", "wasViewModified", "config", "isDirectHost", "push", "updatePlaceholder", "hostElement", "getChildPlaceholderHostSubstitute", "includes", "text", "getAttribute", "setAttribute", "isOnlyChild", "childCount", "firstChild", "getChild", "showPlaceholderTextDeprecationWarning", "hasDisplayedPlaceholderDeprecationWarning", "logWarning", "TypeCheckable", "Error", "Node$2", "Node", "EmitterMixin", "index", "pos", "getChildIndex", "CKEditorError", "nextSibling", "previousSibling", "root", "path", "node", "unshift", "options", "ancestors", "includeSelf", "parentFirst", "ancestorsA", "getAncestors", "ancestorsB", "i", "isBefore", "thisPath", "getPath", "nodePath", "result", "compareArrays", "isAfter", "_removeChildren", "type", "fire", "_fireChange", "json", "clone", "prototype", "Text", "constructor", "data", "_textData", "_data", "isSimilar", "otherNode", "TextProxy", "textNode", "offsetInText", "length", "substring", "offsetSize", "isPartial", "Matcher", "pattern", "_patterns", "add", "item", "RegExp", "name", "singleElement", "match", "isElementMatching", "results", "matchName", "attributes", "matchAttributes", "classes", "matchClasses", "styles", "matchStyles", "matchPatterns", "patterns", "keys", "valueGetter", "normalizedPatterns", "normalizePatterns", "normalizedItems", "forEach", "patternKey", "patternValue", "itemKey", "isKeyMatched", "isValueMatched", "undefined", "isArray", "map", "isPlainObject", "key", "value", "Object", "entries", "itemValue", "String", "attributeKeys", "Set", "getAttributeKeys", "style", "class", "delete", "getClassNames", "getStyleNames", "getStyle", "StylesMap", "styleProcessor", "_styles", "_styleProcessor", "isEmpty", "size", "setTo", "inlineStyle", "clear", "parsedStyles", "parseInlineStyles", "toNormalizedForm", "has", "getReducedForm", "propertyDescriptor", "find", "property", "set", "nameOrObject", "valueOrObject", "isObject", "remove", "toPath", "unset", "_cleanEmptyObjectsOnPath", "getNormalized", "getStylesEntries", "arr", "join", "sort", "getAsString", "propertyName", "expand", "parsed", "pathParts", "split", "isChildPath", "parentPath", "splice", "parentObject", "isParentEmpty", "StylesProcessor", "_normalizers", "_extractors", "_reducers", "_consumables", "Map", "propertyValue", "appendStyleValue", "normalizer", "merge", "extractor", "normalizedValue", "reducer", "styleNamesKeysSet", "getRelatedStyles", "callback", "callbackOrPath", "shorthandName", "styleNames", "_mapStyleNames", "alsoName", "stylesString", "quoteType", "propertyNameStart", "propertyValueStart", "stylesMap", "charAt", "char", "substr", "trim", "replace", "stylesObject", "nameOrPath", "valueToSet", "Element", "attrs", "children", "_unsafeAttributesToRender", "_customProperties", "_attrs", "parseAttributes", "_children", "_insertChild", "_classes", "classString", "parseClasses", "stylesProcessor", "indexOf", "Symbol", "iterator", "getAttributes", "toString", "hasAttribute", "otherElement", "className", "getNormalizedStyle", "matcher", "getCustomProperty", "getCustomProperties", "shouldRenderUnsafeAttribute", "attributeName", "deep", "childrenClone", "child", "_clone", "cloned", "getFillerOffset", "_appendChild", "items", "count", "nodes", "normalize", "_remove", "howMany", "stringValue", "_removeAttribute", "_addClass", "toArray", "_removeClass", "_setStyle", "_removeStyle", "_removeCustomProperty", "attrsMap", "toMap", "classesSet", "classesString", "classArray", "isIterable", "ContainerElement", "lastChild", "EditableElement", "ObservableMixin", "bind", "to", "editableElement", "listenTo", "destroy", "stopListening", "rootNameSymbol", "RootEditableElement", "rootName", "_setCustomProperty", "_name", "TreeWalker", "boundaries", "startPosition", "direction", "_position", "Position", "_createAt", "singleCharacters", "shallow", "ignoreElementEnd", "_boundaryStartParent", "start", "_boundaryEndParent", "end", "position", "skip", "nextResult", "prevPosition", "next", "done", "_next", "_previous", "previousPosition", "offset", "isAtEnd", "_createAfter", "_formatReturnValue", "charactersCount", "textLength", "endOffset", "textProxy", "isAtStart", "_createBefore", "startOffset", "nextPosition", "isEqual", "nodeAfter", "nodeBefore", "editable", "getShiftedBy", "shift", "shifted", "treeWalker", "getCommonAncestor", "otherPosition", "compareWith", "otherPath", "itemOrPosition", "Range", "isCollapsed", "isFlat", "getLastMatchingPosition", "enlargeTrimSkip", "nodeAfterStart", "nodeBeforeEnd", "otherRange", "containsPosition", "loose", "containsStart", "containsEnd", "getDifference", "ranges", "isIntersecting", "getIntersection", "commonRangeStart", "commonRangeEnd", "getItems", "getPositions", "_createFromParentsAndOffsets", "startElement", "endElement", "_createFromPositionAndShift", "_createIn", "_createOn", "Selection", "args", "_ranges", "_lastRangeBackward", "_isFake", "_fakeSelectionLabel", "isFake", "fakeSelectionLabel", "range", "focus", "rangeCount", "isBackward", "getRanges", "first", "last", "firstRange", "getFirstRange", "lastRange", "getLastRange", "otherSelection", "thisRange", "found", "numOfRangesA", "numOfRangesB", "rangeA", "getTrimmed", "rangeB", "getContainedElement", "selectable", "placeOrOffset", "_setRanges", "_setFakeOptions", "DocumentSelection", "fake", "label", "backward", "newFocus", "pop", "_addRange", "newRanges", "isLastBackward", "_pushRange", "storedRange", "addedRange", "intersectingRange", "_selection", "delegate", "getFirstPosition", "getLastPosition", "getSelectedElement", "setFocus", "BubblingEventInfo", "EventInfo", "source", "startRange", "_eventPhase", "_currentTarget", "eventPhase", "currentTarget", "contextsSymbol", "BubblingEmitterMixin", "base", "Mixin", "eventOrInfo", "eventArgs", "eventInfo", "eventContexts", "getBubblingContexts", "updateEventInfo", "fireListenerFor", "return", "selectedElement", "isCustomContext", "Boolean", "getCustomContext", "getDeeperRangeParent", "err", "rethrowUnexpectedError", "_addEventListener", "event", "contexts", "context", "emitter", "_removeEventListener", "values", "mixin", "stop", "called", "startParent", "endParent", "startPath", "endPath", "Document$1", "Document", "_postFixers", "roots", "Collection", "idProperty", "registerPostFixer", "postFixer", "_callPostFixers", "wasFixed", "DEFAULT_PRIORITY", "AttributeElement", "_priority", "_id", "_clonesGroup", "priority", "id", "nonUiChildrenCount", "filter", "EmptyElement", "UIElement", "domDocument", "domConverter", "toDomElement", "domElement", "createElement", "injectUiElementHandling", "view", "on", "evt", "jumpOverUiElement", "keyCode", "keyCodes", "arrowright", "domSelection", "domTarget", "ownerDocument", "defaultView", "getSelection", "domSelectionCollapsed", "getRangeAt", "collapsed", "shiftKey", "domParent", "focusNode", "domOffset", "focusOffset", "viewPosition", "domPositionToView", "jumpedOverAnyUiElement", "nextViewPosition", "newDomPosition", "viewPositionToDom", "collapse", "extend", "RawElement", "DocumentFragment", "DowncastWriter", "_cloneGroups", "_slotFactory", "setSelection", "_setTo", "_setFocus", "createDocumentFragment", "createText", "createAttributeElement", "attributeElement", "renderUnsafeAttributes", "createContainerElement", "childrenOrOptions", "containerElement", "createEditableElement", "createEmptyElement", "emptyElement", "renderFunction", "uiElement", "render", "createRawElement", "rawElement", "_setAttribute", "setStyle", "breakAttributes", "positionOrRange", "_breakAttributes", "_breakAttributesRange", "breakContainer", "newElement", "insert", "sourceRange", "targetPosition", "move", "mergeAttributes", "positionOffset", "positionParent", "_removeFromClonedElementsGroup", "mergeTextNodes", "mergeContainers", "prev", "newPosition", "validateNodesToInsert", "nodeGroups", "reduce", "groups", "lastGroup", "_insertNodes", "rangeOrItem", "validateRangeContainer", "breakStart", "breakEnd", "parentContainer", "removed", "mergePosition", "walker", "getWalker", "current", "rangeToRemove", "parentElement", "ancestor", "countBefore", "attribute", "_wrapRange", "_hasNonUiChildren", "_wrapPosition", "newRange", "_unwrapChildren", "newName", "viewElement", "clearClonedElementsGroup", "groupName", "createPositionAfter", "createPositionBefore", "createRangeOn", "createRangeIn", "createSelection", "modeOrFilter", "_registerSlotFactory", "slotFactory", "getParentContainer", "insertionPosition", "breakTextNode", "_addToClonedElementsGroup", "endPosition", "_wrapChildren", "wrapElement", "wrapPositions", "isText", "isAttribute", "_wrapAttributeElement", "shouldABeOutsideB", "newAttribute", "offsetChange", "unwrapElement", "unwrapPositions", "unwrapped", "_unwrapAttributeElement", "movePositionToTextNode", "fakeElement", "Number", "POSITIVE_INFINITY", "wrapRange", "wrap", "wrapper", "toWrap", "canBeJoined", "hasStyle", "toUnwrap", "removeAttribute", "removeStyle", "forceSplitText", "rangeStart", "rangeEnd", "isContainerOrFragment", "offsetAfter", "clonedNode", "nodesToMove", "group", "a", "b", "getIdentity", "textToMove", "slice", "t1", "t2", "nodeBeforeLength", "validNodesToInsert", "errorContext", "validNode", "startContainer", "endContainer", "NBSP_FILLER", "createTextNode", "MARKED_NBSP_FILLER", "span", "dataset", "ckeFiller", "innerText", "BR_FILLER", "fillerBr", "INLINE_FILLER_LENGTH", "INLINE_FILLER", "repeat", "startsWithFiller", "domNode", "isInlineFiller", "domText", "getDataWithoutFiller", "injectQuirksHandling", "jumpOverInlineFiller", "arrowleft", "Renderer", "domDocuments", "markedAttributes", "markedChildren", "markedTexts", "_inlineFiller", "_fakeSelectionContainer", "env", "isBlink", "isAndroid", "isSelecting", "mapViewToDom", "inlineFillerPosition", "isInlineFillerRenderingPossible", "_updateChildrenMappings", "_isSelectionInInlineFiller", "_removeInlineFiller", "_getInlineFillerPosition", "_needsInlineFillerAtSelection", "parentNode", "ViewPosition", "_updateAttrs", "_updateChildren", "_updateText", "fillerDomPosition", "addInlineFiller", "_updateFocus", "_updateSelection", "_clearTemporaryCustomProperties", "actualDomChildren", "childNodes", "expectedDomChildren", "viewChildrenToDom", "withChildren", "diff", "_diffNodeLists", "actions", "_findUpdateActions", "areSimilarElements", "counter", "equal", "action", "insertIndex", "deleteIndex", "viewChild", "_updateElementMappings", "unbindDomElement", "bindElements", "firstPos", "selectionPosition", "domFillerNode", "selectionParent", "selectionOffset", "isEditable", "ViewText", "viewText", "findCorrespondingDomText", "newDomText", "viewToDom", "expectedText", "filler", "_updateTextNode", "domAttr", "removeDomElementAttribute", "setDomElementAttribute", "previousDomNode", "areTextNodes", "nodesToUnbind", "insertAt", "_markDescendantTextToSync", "domToView", "filterOutFakeSelectionContainer", "sameNodes", "actualDom", "expectedDom", "comparator", "newActions", "actualSlice", "expectedSlice", "concat", "actualText", "_updateTextNodeInternal", "fastDiff", "insertData", "deleteData", "viewNode", "_removeDomSelection", "_removeFakeSelection", "domRoot", "_updateFakeSelection", "isConnected", "_updateDomSelection", "createFakeSelectionContainer", "container", "bindFakeSelection", "_fakeSelectionNeedsUpdate", "appendChild", "textContent", "domRange", "createRange", "removeAllRanges", "selectNodeContents", "addRange", "_domSelectionNeedsUpdate", "setBaseAndExtent", "isGecko", "fixGeckoSelectionAfterBr", "isDomSelectionCorrect", "oldViewSelection", "domSelectionToView", "anchorNode", "contains", "activeDomElement", "activeElement", "mapDomToView", "findAncestor", "domParentOrArray", "nodeAfterFiller", "fillerNode", "node1", "node2", "isNode", "isComment", "tagName", "toLowerCase", "actualDomChild", "expectedDomChild", "isBlockFiller", "nodeType", "ELEMENT_NODE", "childAtOffset", "domChildList", "fakeSelectionContainer", "childList", "assign", "top", "left", "width", "BR_FILLER_REF", "global", "NBSP_FILLER_REF", "MARKED_NBSP_FILLER_REF", "UNSAFE_ATTRIBUTE_NAME_PREFIX", "UNSAFE_ELEMENT_REPLACEMENT_ATTRIBUTE", "DomConverter", "blockFillerMode", "renderingMode", "_domToViewMapping", "WeakMap", "_viewToDomMapping", "_fakeSelectionMapping", "_rawContentElementMatcher", "_inlineObjectElementMatcher", "_elementsWithTemporaryCustomProperties", "preElements", "blockElements", "inlineObjectElements", "unsafeElements", "_domDocument", "implementation", "createHTMLDocument", "viewDocumentSelection", "ViewSelection", "fakeSelectionToView", "domFragment", "viewFragment", "attributeKey", "attributeValue", "elementName", "startsWith", "html", "innerHTML", "DOMParser", "parseFromString", "fragment", "bodyChildNodes", "body", "createTreeWalker", "NodeFilter", "SHOW_ELEMENT", "currentNode", "nextNode", "getAttributeNames", "_shouldRenameElement", "_logUnsafeElement", "replaceWith", "_createReplacementDomElement", "append", "textData", "_processDataFromViewText", "viewElementOrFragment", "bindDocumentFragments", "createComment", "createElementNS", "HTMLTemplateElement", "content", "relatedViewElement", "shouldRenderAttribute", "isValidAttributeName", "fillerPositionOffset", "childView", "_getBlockFiller", "transparentRendering", "tempElement", "viewRangeToDom", "viewRange", "domStart", "domEnd", "setStart", "setEnd", "viewParent", "domBefore", "domAfter", "inlineNodes", "generator", "_domToView", "_processDomInlineNodes", "domChildrenToView", "domChild", "_isBlockViewElement", "isGeckoRestrictedDomSelection", "isDomSelectionBackward", "viewRanges", "domRangeToView", "viewStart", "viewEnd", "ViewRange", "findCorrespondingViewText", "viewBefore", "domElementOrDocumentFragment", "getHostViewElement", "isElement", "documentFragmentOrElement", "viewEditable", "domEditable", "scrollX", "scrollY", "window", "scrollPositions", "forEachDomElementAncestor", "scrollLeft", "scrollTop", "scrollTo", "newViewSelection", "selectionInEditable", "isDocumentFragment", "DOCUMENT_FRAGMENT_NODE", "isEqualNode", "hasBlockParent", "isNbspBlockFiller", "anchorOffset", "e", "detach", "_isDomSelectionPositionCorrect", "registerRawContentMatcher", "registerInlineObjectMatcher", "skipComments", "_isInlineObjectElement", "ViewDocumentFragment", "_createViewElement", "l", "_isViewElementWithRawContent", "nestedInlineNodes", "inlineNode", "_isBlockDomElement", "prevNodeEndsWithSpace", "nodeEndsWithSpace", "_isPreFormatted", "test", "prevNode", "shouldLeftTrim", "shouldRightTrim", "isNextNodeInlineObjectElement", "isNextNodeStartingWithSpace", "_getTouchingInlineViewNode", "prevEndsWithSpace", "_nodeEndsWithSpace", "nextStartsWithSpace", "_hasViewParentOfType", "getNext", "ViewTreeWalker", "ViewUIElement", "viewName", "keepOriginalCase", "ViewElement", "originalDomElement", "newDomElement", "types", "isNBSP", "call", "error", "Observer", "DomEmitterMixin", "_isEnabled", "isEnabled", "disable", "checkShouldIgnoreEventFromTarget", "matches", "DomEventData", "domEvent", "additionalData", "target", "preventDefault", "stopPropagation", "DomEventObserver", "useCapture", "usePassive", "observe", "domEventType", "onDomEvent", "stopObserving", "eventType", "KeyObserver", "domEvt", "altKey", "ctrlKey", "metaKey", "keystroke", "getCode", "FakeSelectionObserver", "_fireSelectionChangeDoneDebounced", "debounce", "_handleSelectionMove", "cancel", "newSelection", "arrowup", "arrowdown", "oldSelection", "MutationObserver", "_config", "characterData", "subtree", "_domElements", "_mutationObserver", "_onMutations", "takeRecords", "disconnect", "enable", "domMutations", "mutatedTextNodes", "elementsWithMutatedChildren", "mutation", "_isBogusBrMutation", "mutations", "viewChildren", "newViewChildren", "isEqualWith", "addedNode", "removedNodes", "addedNodes", "child1", "child2", "FocusObserver", "_renderTimeoutId", "_isFocusChanging", "_handleFocus", "_handleBlur", "_clearTimeout", "setTimeout", "flush", "change", "selectedEditable", "clearTimeout", "SelectionObserver", "mutationObserver", "getObserver", "focusObserver", "_documents", "WeakSet", "_clearInfiniteLoopInterval", "setInterval", "_clearInfiniteLoop", "_documentIsSelectingInactivityTimeoutDebounced", "_loopbackCounter", "startDocumentIsSelecting", "endDocumentIsSelecting", "_handleSelectionChange", "clearInterval", "hasDomSelection", "_reportInfiniteLoop", "forceRender", "CompositionObserver", "DataTransfer", "nativeDataTransfer", "_files", "cacheFiles", "getFiles", "_native", "files", "getData", "setData", "effectAllowed", "dropEffect", "image", "x", "y", "setDragImage", "isCanceled", "mozUserCancelled", "kind", "getAsFile", "InputObserver", "domTargetRanges", "getTargetRanges", "viewDocument", "dataTransfer", "targetRanges", "inputType", "endsWith", "parts", "partTargetRanges", "dataPart", "ArrowKeysObserver", "isArrowKeyCode", "TabObserver", "tab", "View", "domRoots", "_initialDomRootAttributes", "_observers", "_ongoingChange", "_postFixersInProgress", "_renderingDisabled", "_hasChangedSinceTheLastRendering", "_renderer", "_writer", "addObserver", "_render", "isiOS", "relatedTarget", "_clearDomSelection", "markToSync", "viewRoot", "getRoot", "initialDomRootAttributes", "updateContenteditableAttribute", "isReadOnly", "observer", "detachDomRoot", "ObserverConstructor", "alignToTop", "forceScroll", "viewportOffset", "ancestorOffset", "originalArgs", "cloneDeep", "bottom", "right", "scrollViewportToShowTarget", "isRenderingInProgress", "callbackResult", "_disableRendering", "flag", "disableObservers", "enableObservers", "Node$1", "_index", "_startOffset", "attr", "_deep", "_setAttributesTo", "NodeList", "_nodes", "_offsetToNode", "maxOffset", "getNode", "getNodeAtOffset", "getNodeIndex", "getNodeStartOffset", "indexToOffset", "offsetToIndex", "nodeList", "nodesArray", "offsetsArray", "makeOffsetsArray", "spliceArray", "indexStart", "lastNode", "removedOffsetSum", "toJSON", "offsets", "fill", "fromJSON", "getChildAtOffset", "getChildStartOffset", "getNodeByPath", "relativePath", "parentName", "_removeNodes", "stickiness", "_visitedParent", "prevVisitedParent", "textNodeAtPosition", "getTextNodeAtPosition", "getNodeAfterPosition", "formatReturnValue", "offsetInTextNode", "getNodeBeforePosition", "newOffset", "getCommonPath", "cmp", "diffAt", "Math", "min", "isTouching", "commonLevel", "level", "checkTouchingBranch", "checkOnlyZeroes", "hasSameParentAs", "thisParentPath", "getParentPath", "posParentPath", "getTransformedByOperation", "operation", "_getTransformedByInsertOperation", "_getTransformedByMoveOperation", "_getTransformedBySplitOperation", "_getTransformedByMergeOperation", "_getTransformedByInsertion", "_getTransformedByMove", "sourcePosition", "movedRange", "isContained", "_getCombined", "splitPosition", "moveTargetPosition", "graveyardPosition", "_getTransformedByDeletion", "deletionPosition", "deletePosition", "transformed", "insertPosition", "isMoved", "combined", "graveyard", "checkOnlyMaxOffset", "idx", "startParentPath", "endParentPath", "containsItem", "shouldJoin", "posParent", "getTransformedByOperations", "operations", "j", "containsRange", "spread", "newPos", "moveRange", "differenceSet", "difference", "common", "transformedCommon", "newStart", "newEnd", "_createFromRanges", "ref", "refIndex", "Mapper", "_modelToViewMapping", "_viewToModelMapping", "_viewToModelLengthCallbacks", "_markerNameToElements", "_elementToMarkerNames", "_deferredBindingRemovals", "_unboundMarkerNames", "viewContainer", "modelPosition", "findPositionIn", "viewBlock", "findMappedViewAncestor", "modelParent", "modelOffset", "_toModelOffset", "ModelPosition", "modelElement", "toModelElement", "markerName", "defer", "unbindModelElement", "toViewElement", "elements", "names", "nameToElements", "elementToNames", "markerNames", "unbindViewElement", "toModelRange", "ModelRange", "toModelPosition", "toViewRange", "modelRange", "toViewPosition", "mapper", "isPhantom", "markerNameToElements", "boundElements", "getElementsWithSameId", "viewElementName", "lengthCallback", "viewOffset", "offsetToParentStart", "offsetInParent", "getModelLength", "len", "expectedOffset", "lastLength", "_moveViewPositionToTextNode", "ModelConsumable", "_consumable", "_textProxyRegistry", "_normalizeConsumableType", "_getSymbolForTextProxy", "itemConsumables", "verifyAllConsumed", "eventGroup", "consumables", "canConsume", "eventPrefix", "description", "symbol", "startMap", "endMap", "_addSymbolForTextProxy", "DowncastDispatcher", "conversionApi", "_conversionApi", "dispatcher", "_firedEventsMap", "differ", "markers", "_createConversionApi", "getRefreshedItems", "getMarkersToRemove", "_convertMarkerRemove", "changes", "_reduceChanges", "getChanges", "entry", "_convertInsert", "_convertReinsert", "_convertRemove", "_convertAttribute", "attributeOldValue", "attributeNewValue", "flushDeferredBindings", "flushUnboundMarkerNames", "markerRange", "getRange", "_convertMarkerAdd", "getMarkersToAdd", "consumable", "convert", "modelRoot", "markersAtSelection", "getMarkersAtPosition", "_addConsumablesForSelection", "marker", "shouldMarkerChangeBeConverted", "doNotAddConsumables", "_addConsumablesForInsert", "walkerValueToEventData", "_testAndFire", "oldValue", "newValue", "_addConsumablesForRange", "walkerValues", "reconversion", "eventName", "consume", "getEventName", "eventsFiredForConversion", "eventsFiredForItem", "refreshedItems", "Consumable", "convertItem", "convertChildren", "convertAttributes", "_testAndFireAddAttributes", "canReuseView", "reverse", "hasCustomHandling", "itemRange", "anyNewRange", "every", "oldRange", "_replaceAllRanges", "directChange", "_popRange", "getSelectedBlocks", "visited", "startBlock", "getParentBlock", "isStartBlockSelected", "block", "isUnvisitedTopBlock", "endBlock", "isEndBlockSelected", "containsEntireContent", "limitStartPosition", "limitEndPosition", "_checkRange", "_removeAllRanges", "isUnvisitedBlock", "model", "schema", "isBlock", "isTopBlockInRange", "hasParentLimit", "isLimit", "parentBlock", "findAncestorBlock", "isParentInRange", "LiveRange", "bindWithDocument", "fromRange", "isDocumentOperation", "transform", "boundariesChanged", "contentChanged", "doesOperationChangeRangeContent", "toRange", "storePrefix", "LiveSelection", "hasOwnRange", "isGravityOverridden", "updateMarkers", "_updateAttributes", "observeMarkers", "prefixOrName", "getStoredAttributes", "overrideGravity", "_restoreGravity", "uid", "restoreGravity", "_getStoreAttributeKey", "_isStoreAttributeKey", "_attributePriority", "_selectionRestorePosition", "_hasChangedRange", "_overriddenGravityRegister", "_observedMarkers", "_model", "_document", "_fixGraveyardSelection", "_validateSelectionRanges", "_updateMarker", "batch", "clearAttributesStoredInElement", "_getDefaultRange", "overrideUid", "liveRange", "_prepareRange", "_validateSelectionRange", "changed", "markerGroup", "selectionRange", "oldMarkers", "hasMarker", "contained", "clearAll", "newAttributes", "_getSurroundingAttributes", "oldAttributes", "newKey", "oldKey", "gotAdded", "realKey", "getTextAttributes", "getNearestSelectionRange", "isInline", "checkAttribute", "getAttributeProperties", "copyFromObject", "changeParent", "isNoLongerEmpty", "enqueueChange", "storedAttributes", "ConversionHelpers", "dispatchers", "_dispatchers", "conversionHelper", "DowncastHelpers", "elementToElement", "downcastElementToElement", "elementToStructure", "downcastElementToStructure", "attributeToElement", "downcastAttributeToElement", "attributeToAttribute", "downcastAttributeToAttribute", "markerToElement", "downcastMarkerToElement", "markerToHighlight", "downcastMarkerToHighlight", "markerToData", "downcastMarkerToData", "insertText", "viewWriter", "insertAttributesAndChildren", "modelEnd", "createViewElementFromHighlightDescriptor", "descriptor", "convertRangeSelection", "convertCollapsedSelection", "brokenPosition", "cleanSelection", "elementCreator", "oldViewElement", "newViewElement", "ModelSelection", "ModelDocumentSelection", "unwrap", "insertElement", "consumer", "defaultConsumer", "preflight", "reinsertOrConvertNodes", "insertStructure", "slotsMap", "createSlotFactory", "_clearSlotFactory", "validateSlotsChildren", "fillSlots", "insertUIElement", "isOpening", "viewStartElement", "viewEndElement", "bindElementToMarker", "removeUIElement", "unbindElementFromMarkerName", "insertMarkerData", "viewCreator", "viewMarkerData", "handleMarkerBoundary", "isStart", "elementAfter", "elementBefore", "insertMarkerAsAttribute", "insertMarkerAsElement", "createUIElement", "removeMarkerData", "viewData", "removeMarkerFromAttribute", "changeAttribute", "attributeCreator", "oldAttribute", "highlightText", "highlightDescriptor", "prepareDescriptor", "rangeAfterWrap", "highlightElement", "ModelElement", "addHighlightCallback", "removeHighlight", "viewHighlightElement", "removeHighlightCallback", "normalizeModelElementConfig", "normalizeToElementConfig", "createConsumer", "converterPriority", "createChangeReducer", "checkChild", "modelValue", "getFromAttributeCreator", "normalizeToAttributeConfig", "viewElementType", "modelData", "createViewElementFromDefinition", "viewElementDefinition", "ViewAttributeElement", "modelAttributeValue", "createChangeReducerCallback", "shouldReplace", "reducedChanges", "reconvertedElements", "changeIndex", "changePosition", "positionRelation", "events", "slot", "childrenInSlots", "flat", "uniqueChildrenInSlots", "toViewPositionMapping", "currentSlot", "currentSlotNodes", "off", "modelNodes", "modelChildNode", "reinsertNode", "modelNode", "viewChildNode", "autoParagraphEmptyRoots", "getRoots", "isParagraphable", "nodeOrType", "createContext", "wrapInParagraph", "paragraph", "createPositionAt", "UpcastHelpers", "upcastElementToElement", "elementToAttribute", "upcastElementToAttribute", "upcastAttributeToAttribute", "elementToMarker", "upcastElementToMarker", "dataToMarker", "upcastDataToMarker", "convertToModelFragment", "viewItem", "modelCursor", "convertText", "convertSelectionChange", "modelSelection", "converter", "prepareToElementConverter", "getViewElementNameFromConfig", "normalizeModelAttributeConfig", "prepareToAttributeConverter", "viewKey", "normalizeViewAttributeKeyValueConfig", "normalizeElementToMarkerModelConfig", "normalizedConfig", "converterStart", "normalizeDataToMarkerConfig", "converterEnd", "basePriority", "priorities", "low", "maxPriority", "highest", "priorityFactor", "upcastAttributeToMarker", "attrName", "addMarkerElements", "markerViewNames", "markerViewName", "viewConfig", "matcherResult", "getModelElement", "safeInsert", "updateConversionResult", "input", "Function", "normalized", "keyName", "viewAttributeKeyToCopy", "defaultModelValue", "onlyViewNameIsDefined", "modelKey", "attributeWasSet", "setAttributeOn", "configToTest", "modelAttribute", "elementCreatorFunction", "injectSelectionPostFixer", "selectionPostFixer", "correctedRange", "tryFixingRange", "mergeIntersectingRanges", "tryFixingCollapsedRange", "tryFixingNonCollapsedRage", "originalPosition", "nearestSelectionRange", "ancestorObject", "fixedPosition", "isTextAllowedOnStart", "isTextAllowedOnEnd", "startLimitElement", "getLimitElement", "endLimitElement", "checkSelectionOnNonLimitElements", "isStartBeforeSelectable", "isSelectable", "fixedStart", "isEndAfterSelectable", "fixedEnd", "isStartInLimit", "isEndInLimit", "bothInSameParent", "expandStart", "expandEnd", "findOutermostLimitAncestor", "startingNode", "isLimitNode", "startIsOnBlock", "endIsOnBlock", "rangesToMerge", "rangeIndexesToRemove", "currentRangeIndex", "currentRange", "previousRanges", "previousRangeIndex", "previousRange", "mergedRange", "getJoined", "nonIntersectingRanges", "_", "EditingController", "downcastDispatcher", "convertChanges", "convertSelection", "fixTargetRanges", "bindTo", "using", "reconvertMarker", "markerOrName", "currentMarker", "_refresh", "reconvertItem", "_refreshItem", "ViewConsumable", "elementConsumables", "ViewElementConsumables", "revert", "consumablesFromElement", "createFrom", "instance", "CONSUMABLE_TYPES", "_canConsumeName", "_add", "_test", "_consume", "_revert", "consumableName", "toConsume", "Schema", "_sourceDefinitions", "create", "_customChildChecks", "_customAttributeChecks", "_genericCheckSymbol", "_compiledDefinitions", "decorate", "SchemaContext", "getDefinition", "itemName", "definition", "_clearCache", "_compile", "getDefinitions", "isRegistered", "def", "isContent", "_checkContextMatch", "isAllowed", "_evaluateAttributeChecks", "allowAttributes", "positionOrBaseElement", "elementToMerge", "checkMerge", "checks", "properties", "_attributeProperties", "selectionOrRangeOrPosition", "rangeCommonAncestor", "firstPosition", "getValidRanges", "convertToMinimalFlatRanges", "_getValidRangesForRange", "backwardWalker", "forwardWalker", "limitElement", "combineWalkers", "removeDisallowedAttributeFromNode", "rangeInNode", "positionsInRange", "attributeProperties", "definitions", "sourceRules", "itemNames", "compileBaseItemRule", "propagateAllowIn", "propagateAllowChildren", "propagateDisallowIn", "propagateDisallowChildren", "resolveDisallows", "compileAllowContentOf", "compileAllowWhere", "compileAllowAttributesOf", "compileInheritPropertiesFrom", "compileDefinitions", "parentItem", "_evaluateChildChecks", "allowIn", "parentItemDefinition", "parentContext", "trimLast", "genericChecks", "childChecks", "check", "place", "firstBlock", "positionAfter", "_items", "mapContextItem", "ctx", "getItem", "getNames", "query", "sourceItemRules", "itemRule", "allowChildren", "disallowIn", "disallowChildren", "allowContentOf", "allowWhere", "disallowAttributes", "allowAttributesOf", "inheritTypesFrom", "copyTypes", "copyProperty", "resolveInheritAll", "childName", "childItem", "allowContentOfItemName", "baseItem", "allowWhereItemName", "finalDefinitions", "allowAttributeOfItemName", "inheritPropertiesOfItemName", "inheritFrom", "typeNames", "sourceItemRule", "singleValue", "inheritAllFrom", "ctxItem", "forward", "step", "getMinimalFlatRanges", "UpcastDispatcher", "_splitParts", "_cursorParents", "_modelCursor", "_emptyElementsToKeep", "store", "_convertItem", "positionOrElement", "_convertChildren", "_safeInsert", "_updateConversionResult", "splitToAllowedParent", "_splitToAllowedParent", "getSplitParts", "_getSplitParts", "keepEmptyElement", "_keepEmptyElement", "createContextTree", "documentFragment", "_removeEmptyElements", "extractMarkersFromModelFragment", "elementOrModelCursor", "nextModelCursor", "splitResult", "savedCursorParent", "allowedParent", "findAllowedParent", "stack", "treeWalkerValue", "originalPart", "splitPart", "_registerSplitPair", "cursorParent", "list", "anyRemoved", "modelItem", "markerElements", "markerElement", "currentPosition", "contextDefinition", "BasicHtmlWriter", "getHtml", "HtmlDataProcessor", "domParser", "htmlWriter", "toData", "toView", "_toDom", "useFillerType", "DataController", "upcastDispatcher", "ViewDocument", "htmlProcessor", "processor", "_viewWriter", "ViewDowncastWriter", "isUndoable", "_checkIfRootsExists", "ignoreWhitespaces", "stringify", "modelElementOrFragment", "viewDocumentFragment", "clearBindings", "_getMarkersRelativeToElement", "init", "version", "initialData", "main", "parse", "Promise", "resolve", "newData", "batchType", "removeSelectionAttribute", "toModel", "addStyleProcessorRules", "rootNames", "elementRange", "isMarkerCollapsed", "isMarkerAtElementBoundary", "updatedMarkerRange", "n1", "r1", "n2", "r2", "localeCompare", "Conversion", "downcastDispatchers", "upcastDispatchers", "_helpers", "_downcast", "_upcast", "_createConversionHelpers", "isDowncast", "alias", "isUpcast", "for", "_getAllUpcastDefinitions", "helpers", "upcastAlso", "_getUpcastDefinition", "upcastAlsoItem", "XmlDataProcessor", "namespaces", "nsp", "parsedDocument", "parserError", "querySelector", "documentElement", "Operation", "baseVersion", "_validate", "__className", "_insert", "normalizedNodes", "_normalizeNodes", "sum", "_splitNodeAtPosition", "_mergeNodesAtIndex", "_move", "_haveSameAttributes", "mergedNode", "offsetDiff", "firstPart", "secondPart", "nodeA", "nodeB", "iteratorA", "iteratorB", "MoveOperation", "affectedSelectable", "newTargetPosition", "getMovedRangeStart", "sourceElement", "targetElement", "sourceOffset", "targetOffset", "InsertOperation", "shouldReceiveAttributes", "gyPosition", "originalNodes", "SplitOperation", "MergeOperation", "splitElement", "getInsertionPosition", "mergedElement", "MarkerOperation", "affectsData", "_markers", "_set", "AttributeOperation", "NoOperation", "RenameOperation", "oldName", "RootAttributeOperation", "RootOperation", "isAdd", "createRoot", "_isAttached", "OperationFactory", "transformations", "setTransformation", "OperationA", "OperationB", "transformationFunction", "aGroup", "getTransformation", "noUpdateTransformation", "transformSets", "operationsA", "operationsB", "contextFactory", "ContextFactory", "useRelations", "forceWeakRemove", "setOriginalOperations", "originalOperations", "nextTransformIndex", "op", "nextBaseVersionA", "nextBaseVersionB", "originalOperationsACount", "originalOperationsBCount", "opA", "indexB", "opB", "newOpsA", "getContext", "newOpsB", "updateRelation", "newOpA", "handlePartialMarkerOperations", "padWithNoOps", "brokenOperationsACount", "brokenOperationsBCount", "updateBaseVersions", "_history", "_useRelations", "_forceWeakRemove", "_relations", "history", "takeFrom", "originalOperation", "_setRelation", "wasInLeftElement", "wasStartBeforeMergedElement", "wasEndBeforeMergedElement", "wasInRightElement", "aIsStrong", "aWasUndone", "_wasUndone", "bWasUndone", "abRelation", "_getRelation", "baRelation", "originalOp", "wasUndone", "isUndoneOperation", "origB", "undoneB", "getUndoneOperation", "origA", "relationsA", "relation", "markerOps", "r", "_getComplementaryAttributeOperations", "insertOperation", "insertValue", "_breakRangeByMoveOperation", "moveOp", "diffs", "aNewRange", "aToGraveyard", "bToGraveyard", "aIsWeak", "bIsWeak", "forceMove", "removedRange", "mergeSplittingElement", "insertBefore", "_moveTargetIntoMovedRange", "getReversed", "bTargetsToA", "_makeMoveOperationsFromRanges", "aTargetsToB", "aCompB", "shouldSpread", "rightRange", "movesGraveyardElement", "gyMoveSource", "splitNodesMoveSource", "aTarget", "gyMoveTarget", "gyMove", "splitNodesMoveTargetPath", "splitNodesMoveTarget", "splitNodesMove", "renamePath", "splitPath", "extraRename", "additionalSplit", "rangeToMove", "gyElementMoved", "newParentPosition", "newTargetPath", "splitAtTarget", "howManyRemoved", "aInGraveyard", "bInGraveyard", "newPositionPath", "LivePosition", "fromPosition", "oldPosition", "toPosition", "Batch", "isLocal", "isUndo", "isTyping", "addOperation", "Differ", "markerCollection", "_changesInElement", "_elementsSnapshots", "_elementChildrenSnapshots", "_elementState", "_changedMarkers", "_changedRoots", "_changeCount", "_cachedChanges", "_cachedChangesWithGraveyard", "_refreshedItems", "_markerCollection", "bufferOperation", "operationToBuffer", "_isInInsertedElement", "_markInsert", "_markAttribute", "sourceParentInserted", "targetParentInserted", "_markRemove", "_setElementState", "getMarkersIntersectingRange", "markerData", "bufferMarkerChange", "graveyardParent", "mergedIntoElement", "_isLoaded", "_bufferRootStateChange", "_bufferRootAttributeChange", "oldMarkerData", "newMarkerData", "buffered", "markerAdded", "markerRemoved", "markerChanged", "includeChangesInGraveyard", "diffSet", "childrenBefore", "childrenAfter", "_getChildrenSnapshots", "diffInstructions", "_generateDiffInstructionsFromChanges", "instruction", "_getDiffActionForNode", "childSnapshotBefore", "diffItem", "_getInsertDiff", "_getRemoveDiff", "beforeAttributes", "afterAttributes", "diffItems", "_getAttributesDiff", "changeCount", "prevIndex", "prevDiff", "thisDiff", "isConsecutiveTextRemove", "isConsecutiveTextAdd", "isConsecutiveAttributeChange", "v", "_changesInGraveyardFilter", "state", "_bufferRootLoad", "attrEntry", "changeItem", "_markChange", "_removeAllNestedChanges", "_makeSnapshots", "_getChangesForElement", "_handleChange", "currentStatePriority", "_statesPriority", "newStatePriority", "diffItemType", "childrenSnapshots", "snapshot", "inc", "nodesToHandle", "old", "incEnd", "oldEnd", "intersectionLength", "howManyAfter", "attributePart", "elementSnapshot", "elementSnapshotBefore", "before", "_getSingleNodeSnapshot", "snapshots", "oldChildrenLength", "oldChildrenHandled", "posInGy", "rangeInGy", "History", "_operations", "_undoPairs", "_undoneOperations", "_baseVersionToOperationIndex", "_version", "_gaps", "lastOperation", "historyVersion", "getOperations", "fromBaseVersion", "toBaseVersion", "firstOperation", "inclusiveTo", "gapFrom", "gapTo", "fromIndex", "toIndex", "getOperation", "operationIndex", "undoneOperation", "undoingOperation", "isUndoingOperation", "RootElement", "graveyardName", "_hasSelectionChangedFromTheLastChangeBlock", "removeMarker", "includeDetached", "_handleChangeBlock", "_hasDocumentChangedFromTheLastChangeBlock", "refresh", "hasDataChanges", "reset", "defaultRoot", "_getDefaultRoot", "createPositionFromPath", "nearestRange", "isValid", "validateTextNodePosition", "rangeBoundary", "isInsideSurrogatePair", "isInsideCombinedSymbol", "MarkerCollection", "Marker", "managedUsingOperations", "oldMarker", "hasChanged", "_attachLiveRange", "_managedUsingOperations", "_affectsData", "_destroyMarker", "getMarkersGroup", "prefix", "_detachLiveRange", "_liveRange", "stopDelegating", "DetachOperation", "Writer", "_assertWriterUsedCorrectly", "isSameTree", "applyOperation", "rangeRootPosition", "usingOperation", "updateMarker", "addMarker", "itemOrPositionOrOffset", "appendText", "appendElement", "itemOrRange", "setAttributeOnRange", "setAttributeOnItem", "val", "clearAttributes", "removeAttributesFromItem", "_addOperationForAffectedMarkers", "applyRemoveOperation", "_mergeDetached", "_merge", "renameOperation", "firstSplitElement", "firstCopyElement", "elementOrString", "shiftedRange", "applyMarkerOperation", "hasUsingOperationDefined", "affectsDataDefined", "updatedRange", "detachRoot", "rootOrName", "setSelectionAttribute", "keyOrObjectOrIterable", "_setSelectionAttribute", "keyOrIterableOfKeys", "_removeSelectionAttribute", "_overrideGravity", "restoreSelectionGravity", "storeKey", "_currentWriter", "isAffected", "affectedInLeftElement", "affectedInRightElement", "affectedAfterLeftElement", "affectedBeforeRightElement", "lastSplitPosition", "valueBefore", "valueAfter", "previousValue", "isRootChanged", "rootA", "rootB", "deleteContent", "selRange", "doNotResetEntireContent", "shouldEntireContentBeReplacedWithParagraph", "replaceEntireContentWithParagraph", "attributesForAutoparagraph", "doNotAutoparagraph", "getAttributesWithProperty", "getLivePositionsForSelectedBlocks", "leaveUnmerged", "mergeBranches", "removeDisallowedAttributes", "collapseSelectionAt", "shouldAutoparagraph", "insertParagraph", "ignoreMarkers", "modifySelection", "newEndPosition", "skippedRange", "checkShouldMerge", "startAncestor", "endAncestor", "getAncestorsJustBelowCommonAncestor", "mergeBranchesRight", "mergeBranchesLeft", "commonAncestor", "parentToRemove", "mergeRight", "rename", "setAttributes", "fromEntries", "isCrossingLimitElement", "positionA", "positionB", "isTextAllowed", "isParagraphAllowed", "leftPos", "rightPos", "rangeToCheck", "setAllowedAttributes", "getSelectedContent", "frag", "commonPath", "commonParent", "flatSubtreeRange", "cloneElement", "leftExcessRange", "rightExcessRange", "removeRangeContent", "parentsToCheck", "parentToCheck", "removeRange", "insertContent", "insertion", "Insertion", "fakeMarkerElements", "nodesToInsert", "markersPosition", "posA", "posB", "isAtBeginning", "handleNodes", "getSelectionRange", "selectionLiveRange", "markersData", "isStartBoundary", "elementPosition", "rangeOnInsertion", "getAffectedRange", "affectedRange", "_firstNode", "_lastNode", "_lastAutoParagraph", "_filterAttributesOf", "_affectedStart", "_affectedEnd", "_nodeToSelect", "canMergeWith", "_documentFragment", "_documentFragmentPosition", "_handleNode", "_insertPartialFragment", "_updateLastNodeFromAutoParagraph", "_mergeOnRight", "positionAfterLastNode", "positionAfterNode", "_setAffectedBoundaries", "_checkAndSplitToAllowedPosition", "_handleDisallowedNode", "_appendToFragment", "livePosition", "_mergeOnLeft", "_canMergeLeft", "mergePosLeft", "_canMergeRight", "mergePosRight", "allowedIn", "_getAllowedIn", "tempPos", "_insertAutoParagraph", "contextElement", "childNode", "insertObject", "object", "originalSelection", "insertionSelection", "findOptimalPosition", "findOptimalInsertionRange", "firstSelectedBlock", "attributesToCopy", "elementToInsert", "insertionPositionParent", "updateSelection", "paragraphAttributes", "nextElement", "canSetSelection", "wordBoundaryCharacters", "isForward", "unit", "treatEmojiAsSingleUnit", "getSearchRange", "tryExtendingTo", "setSelectionFocus", "getCorrectWordBreakPosition", "getCorrectPosition", "isInsideEmojiSequence", "isAtNodeBoundary", "isAtWordBoundary", "searchEnd", "offsetToCheck", "Model", "_pendingChanges", "methodName", "register", "addChildCheck", "canEditAt", "_runPendingChanges", "batchOrType", "_execute", "rest", "normalizeSelectable", "rangeOrElement", "intersectingMarker", "search", "createBatch", "createOperationFromJSON", "ret", "currentBatch", "callbackReturnValue", "ClickObserver", "MouseObserver", "UpcastWriter", "removeChildren", "oldElement", "insertChild", "valueOrElement", "HEX_COLOR_REGEXP", "RGB_COLOR_REGEXP", "RGBA_COLOR_REGEXP", "HSL_COLOR_REGEXP", "HSLA_COLOR_REGEXP", "CSS_SHORTHAND_VALUE_REGEXP", "COLOR_NAMES", "isColor", "string", "lineStyleValues", "isLineStyle", "lengthRegExp", "isLength", "PERCENTAGE_VALUE_REGEXP", "isPercentage", "repeatValues", "isRepeat", "positionValues", "isPosition", "attachmentValues", "isAttachment", "urlRegExp", "isURL", "getBoxSidesValues", "getShorthandValues", "getBoxSidesValueReducer", "styleShorthand", "reduced", "getBoxSidesShorthandValue", "out", "getPositionShorthandNormalizer", "shorthand", "matchAll", "addBackgroundRules", "setNormalizer", "getBackgroundNormalizer", "getBackgroundColorNormalizer", "setReducer", "getBackgroundReducer", "setStyleRelation", "background", "part", "attachment", "color", "addBorderRules", "getBorderNormalizer", "getBorderPositionNormalizer", "getBorderPropertyNormalizer", "getBorderPropertyPositionNormalizer", "setExtractor", "getBorderPositionExtractor", "getBorderPositionReducer", "getBorderReducer", "normalizeBorderShorthand", "side", "border", "toBorderPropertyShorthand", "which", "extractBorderPosition", "topStyles", "rightStyles", "bottomStyles", "leftStyles", "borderStyles", "borderStylesByType", "getReducedStyleValueForType", "reducedBorderStyle", "reduceBorderPosition", "reducedStyleTypes", "borderTypes", "borderValue", "addPaddingRules", "stylesProcessor", "setNormalizer", "getPositionShorthandNormalizer", "value", "path", "setReducer", "getBoxSidesValueReducer", "setStyleRelation", "ELEMENT_RANGE_START_TOKEN", "ELEMENT_RANGE_END_TOKEN", "TEXT_RANGE_START_TOKEN", "TEXT_RANGE_END_TOKEN", "allowedTypes", "ContainerElement", "AttributeElement", "EmptyElement", "UIElement", "RawElement", "domConverterStub", "setContentOf", "node", "html", "innerHTML", "getData", "view", "options", "View", "TypeError", "document", "withoutSelection", "rootName", "root", "getRoot", "stringifyOptions", "showType", "showPriority", "renderUIElements", "renderRawElements", "ignoreRoot", "domConverter", "_stringify", "selection", "stringify", "setData", "data", "change", "writer", "result", "_parse", "rootElement", "setSelection", "parse", "selectionOrPositionOrRange", "Position", "Range", "DocumentSelection", "viewStringify", "ViewStringify", "viewDocument", "ViewDocument", "StylesProcessor", "order", "rangeParser", "RangeParser", "sameSelectionCharacters", "processor", "XmlDataProcessor", "namespaces", "Object", "keys", "inlineObjectElements", "push", "toView", "_convertViewElements", "nodes", "_removeChildren", "childCount", "_appendChild", "ranges", "is", "getChild", "length", "backward", "lastRangeBackward", "parent", "_remove", "constructor", "_positions", "_getPositions", "_createRanges", "Error", "_sortRanges", "children", "getChildren", "child", "regexp", "RegExp", "text", "match", "offset", "brackets", "exec", "index", "bracket", "textOffset", "replace", "_data", "item", "position", "rangesOrder", "sortedRanges", "newPosition", "undefined", "range", "end", "showAttributeElementId", "getRanges", "_walkView", "chunk", "callback", "ignore", "_stringifyElementOpen", "render", "rawContentContainer", "createElement", "_stringifyElementRanges", "_stringifyElementClose", "_stringifyTextRanges", "element", "start", "collapsed", "isCollapsed", "split", "rangeStartToken", "rangeEndToken", "map", "letter", "join", "priority", "_stringifyElementPriority", "id", "_stringifyElementId", "type", "_stringifyElementType", "name", "filter", "i", "attributes", "_stringifyElementAttributes", "parts", "getAttributeKeys", "sort", "attribute", "attributeValue", "getClassNames", "getStyleNames", "style", "getStyle", "getAttribute", "rootNode", "convertedElement", "ViewDocumentFragment", "_convertElement", "viewElement", "info", "_convertElementNameAndInfo", "ElementConstructor", "newElement", "ViewElement", "_priority", "_id", "attributeKey", "_setAttribute", "_convertPriority", "hasAttribute", "_removeAttribute", "_convertType", "priorityString", "parseInt", "isNaN", "model", "Model", "convertMarkers", "markers", "modelDocumentFragment", "modelRoot", "parsedResult", "schema", "selectionAttributes", "context", "batchType", "enqueueChange", "writeToModel", "remove", "createRangeIn", "insert", "removeSelectionAttribute", "ModelPosition", "ModelRange", "isBackward", "setSelectionAttribute", "getAttributes", "mapper", "Mapper", "RootElement", "ModelDocumentFragment", "fragment", "createPositionBefore", "createPositionAfter", "ModelSelection", "viewRoot", "ViewRootEditableElement", "roots", "add", "downcastDispatcher", "DowncastDispatcher", "bindElements", "on", "insertText", "insertAttributesAndChildren", "evt", "conversionApi", "converter", "wrap", "modelAttributeValue", "createAttributeElement", "stringifyAttributeValue", "insertElement", "modelItem", "convertAttributes", "ViewContainerElement", "convertRangeSelection", "convertCollapsedSelection", "insertUIElement", "markerName", "isOpening", "createUIElement", "markersMap", "Map", "marker", "Array", "from", "a", "b", "set", "getRange", "_writer", "convert", "convertSelection", "substr", "destroy", "viewParse", "viewDocumentFragment", "viewSelection", "modelController", "upcastDispatcher", "UpcastDispatcher", "convertToModelFragment", "convertToModelText", "convertToModelElement", "viewRange", "toModelRange", "key", "toMap", "setAttribute", "childrenResult", "convertChildren", "viewItem", "modelCursor", "assign", "stop", "elementName", "checkChild", "parseAttributeValue", "modelRange", "_createOn", "viewText", "createText", "_createFromPositionAndShift", "offsetSize", "JSON", "e", "isPlainObject", "Watchdog", "constructor", "config", "crashes", "state", "Date", "now", "_crashNumberLimit", "crashNumberLimit", "_minimumNonErrorTimePeriod", "minimumNonErrorTimePeriod", "_boundErrorHandler", "evt", "error", "reason", "Error", "_handleError", "_listeners", "_restart", "_stopErrorHandling", "eventName", "callback", "push", "filter", "cb", "args", "callbacks", "apply", "window", "addEventListener", "removeEventListener", "_shouldReactToError", "message", "stack", "filename", "ErrorEvent", "undefined", "lineno", "colno", "date", "_now", "causesRestart", "_shouldRestart", "_fire", "is", "context", "_isErrorComingFromThisItem", "length", "lastErrorTime", "firstMeaningfulErrorTime", "averageNonErrorTimePeriod", "getSubNodes", "head", "excludedProperties", "Set", "nodes", "subNodes", "nodeIndex", "node", "has", "shouldNodeBeIncluded", "add", "Symbol", "iterator", "n", "err", "key", "type", "Object", "prototype", "toString", "call", "typeOfNode", "_watchdogExcluded", "EventTarget", "Event", "areConnectedThroughProperties", "target1", "target2", "excludedNodes", "isObject", "subNodes1", "subNodes2", "structure", "EditorWatchdog", "Editor", "watchdogConfig", "_editor", "_lifecyclePromise", "_initUsingData", "_editables", "_excludedProps", "_throttledSave", "throttle", "_save", "bind", "saveInterval", "_creator", "elementOrData", "create", "_destructor", "editor", "destroy", "_item", "setCreator", "creator", "setDestructor", "destructor", "Promise", "resolve", "then", "_destroy", "catch", "console", "existingRoots", "lazyRoots", "oldRootsAttributes", "_config", "rootsAttributes", "rootName", "rootData", "entries", "_data", "roots", "isLoaded", "updatedConfig", "extraPlugins", "_watchdogInitialData", "initialData", "EditorWatchdogInitPlugin", "isElement", "_elementOrData", "_startErrorHandling", "keys", "values", "_cloneEditorConfiguration", "model", "document", "on", "_lastDocumentVersion", "version", "_getData", "_getEditables", "finally", "cancel", "off", "_setExcludedProperties", "props", "root", "isAttached", "plugins", "commentsRepository", "get", "trackChanges", "data", "markers", "commentThreads", "JSON", "stringify", "suggestions", "forEach", "content", "Array", "from", "getChildren", "attributes", "getAttributes", "_isLoaded", "marker", "_affectsData", "name", "rangeJSON", "getRange", "toJSON", "usingOperation", "_managedUsingOperations", "affectsData", "getCommentThreads", "skipNotAttached", "getSuggestions", "editables", "getRootNames", "editable", "ui", "getEditableElement", "cloneDeepWith", "value", "stop", "enqueueChange", "isUndoable", "writer", "_restoreCollaborationData", "_restoreEditorData", "fire", "priority", "jsonNode", "element", "createElement", "children", "child", "_appendChild", "_createNode", "createText", "parsedNodes", "parse", "parsedAttributes", "rootElement", "getRoot", "setAttribute", "insert", "markerName", "markerOptions", "start", "end", "options", "startPosition", "createPositionFromPath", "path", "stickiness", "endPosition", "range", "createRange", "addMarker", "parsedCommentThreads", "parsedSuggestions", "commentThreadData", "channelId", "hasCommentThread", "threadId", "commentThread", "getCommentThread", "remove", "addCommentThread", "suggestionData", "trackChangesEditing", "hasSuggestion", "id", "suggestion", "getSuggestion", "addSuggestionData", "mainQueueId", "ContextWatchdog", "Context", "_watchdogs", "Map", "_context", "_contextProps", "_actionQueues", "ActionQueues", "_watchdogConfig", "contextConfig", "onEmpty", "enqueue", "_contextConfig", "_create", "getItem", "itemId", "watchdog", "_getWatchdog", "getItemState", "itemConfigurationOrItemConfigurations", "itemConfigurations", "toArray", "all", "map", "item", "set", "res", "rethrowRestartEventOnce", "sourceElementOrData", "itemIdOrItemIds", "itemIds", "delete", "_onEmptyCallbacks", "_queues", "_activeActions", "onEmptyCallback", "queueId", "action", "isMainAction", "awaitedActions", "queueWithAction", "nonErrorQueue", "elementOrArray", "isArray", "Plugin", "ObservableMixin", "constructor", "editor", "_disableStack", "Set", "set", "forceDisabled", "id", "add", "size", "on", "forceDisable", "priority", "isEnabled", "clearForceDisabled", "delete", "off", "stopListening", "isContextPlugin", "isOfficialPlugin", "isPremiumPlugin", "evt", "return", "stop", "Command", "undefined", "_affectsData", "_isEnabledBasedOnSelection", "decorate", "listenTo", "model", "document", "refresh", "affectsData", "selection", "selectionInGraveyard", "getFirstPosition", "root", "rootName", "canEditAtSelection", "canEditAt", "isReadOnly", "args", "MultiCommand", "_childCommandsDefinitions", "command", "_getFirstEnabledCommand", "execute", "options", "insertToPriorityArray", "_checkEnabled", "commandDefinition", "find", "PluginCollection", "EmitterMixin", "context", "availablePlugins", "contextPlugins", "_context", "_plugins", "Map", "_availablePlugins", "PluginConstructor", "pluginName", "_contextPlugins", "pluginInstance", "Symbol", "iterator", "entry", "get", "key", "plugin", "name", "CKEditorError", "has", "init", "plugins", "pluginsToRemove", "pluginsSubstitutions", "that", "findAvailablePluginConstructors", "validatePlugins", "pluginsToLoad", "filter", "isPluginRemoved", "pluginConstructors", "getPluginConstructors", "substitutePlugins", "pluginInstances", "loadPlugins", "initPlugins", "then", "isPluginConstructor", "some", "removedPlugin", "getPluginName", "processed", "forEach", "requires", "map", "reduce", "result", "parentPluginConstructor", "checkMissingPlugin", "checkContextPlugin", "checkRemovedPlugin", "missingPlugin", "requiredBy", "_add", "method", "promise", "bind", "Promise", "resolve", "pluginItem", "length", "pluginToReplace", "indexInPluginConstructors", "indexOf", "splice", "promises", "destroy", "push", "all", "plugin1", "plugin2", "Context", "config", "locale", "_contextOwner", "translations", "rest", "Config", "defaultConfig", "builtinPlugins", "define", "languageConfig", "Locale", "uiLanguage", "ui", "contentLanguage", "t", "editors", "Collection", "concat", "Array", "from", "isContextOwner", "_removeEditor", "remove", "names", "includes", "create", "ContextPlugin", "CommandCollection", "_commands", "commandName", "commandParams", "keys", "commands", "values", "EditingKeystrokeHandler", "KeystrokeHandler", "keystroke", "callback", "evtData", "cancel", "DEFAULT_CATEGORY_ID", "DEFAULT_GROUP_ID", "Accessibility", "keystrokeInfos", "_editor", "isMenuBarVisible", "addKeystrokeInfoCategory", "label", "description", "navigationKeystrokes", "mayRequireFn", "groups", "keystrokes", "addKeystrokeInfoGroup", "categoryId", "group", "category", "groupId", "addKeystrokeInfos", "Editor", "defaultTranslations", "language", "_addEditor", "_getEditorConfig", "_readOnlyLocks", "once", "state", "Model", "stylesProcessor", "StylesProcessor", "data", "DataController", "editing", "EditingController", "view", "to", "conversion", "Conversion", "downcastDispatcher", "upcastDispatcher", "addAlias", "accessibility", "value", "enableReadOnlyMode", "lockId", "fire", "disableReadOnlyMode", "setData", "getData", "removePlugins", "extraPlugins", "readyPromise", "err", "rethrowUnexpectedError", "focus", "Error", "EditorWatchdog", "ContextWatchdog", "attachToForm", "isFunction", "updateSourceElement", "sourceElement", "isTextArea", "form", "originalSubmit", "onSubmit", "submit", "apply", "addEventListener", "removeEventListener", "tagName", "toLowerCase", "ElementApiMixin", "base", "Mixin", "sourceElement", "updateSourceElement", "data", "CKEditorError", "shouldUpdateSourceElement", "config", "get", "isSourceElementTextArea", "HTMLTextAreaElement", "setDataInElement", "dataToSet", "Object", "prototype", "PendingActions", "ContextPlugin", "pluginName", "isOfficialPlugin", "set", "_actions", "Collection", "idProperty", "delegate", "to", "add", "message", "CKEditorError", "action", "ObservableMixin", "hasAny", "remove", "length", "first", "get", "Symbol", "iterator", "history", "icons", "bold", "cancel", "caption", "check", "cog", "colorPalette", "eraser", "image", "imageUpload", "imageAssetManager", "imageUrl", "lowVision", "textAlternative", "loupe", "previousArrow", "nextArrow", "importExport", "paragraph", "plus", "text", "alignBottom", "alignMiddle", "alignTop", "alignLeft", "alignCenter", "alignRight", "alignJustify", "objectLeft", "objectCenter", "objectRight", "objectFullWidth", "objectInline", "objectBlockLeft", "objectBlockRight", "objectSizeCustom", "objectSizeFull", "objectSizeLarge", "objectSizeSmall", "objectSizeMedium", "pencil", "pilcrow", "quote", "threeVerticalDots", "dragIndicator", "redo", "undo", "bulletedList", "numberedList", "todoList", "codeBlock", "browseFiles", "heading1", "heading2", "heading3", "heading4", "heading5", "heading6", "horizontalLine", "html", "indent", "outdent", "table", "FileReader", "ObservableMixin", "constructor", "total", "reader", "window", "_reader", "_data", "undefined", "set", "onprogress", "evt", "loaded", "error", "data", "read", "file", "size", "Promise", "resolve", "reject", "onload", "result", "onerror", "onabort", "readAsDataURL", "abort", "FileRepository", "Plugin", "loaders", "Collection", "_loadersMap", "Map", "_pendingAction", "pluginName", "isOfficialPlugin", "requires", "PendingActions", "on", "_updatePendingAction", "bind", "to", "uploaded", "getLoader", "fileOrPromise", "get", "createLoader", "createUploadAdapter", "logWarning", "loader", "FileLoader", "add", "then", "catch", "aggregatedUploaded", "aggregatedTotal", "uploadTotal", "destroyLoader", "fileOrPromiseOrLoader", "_destroy", "remove", "forEach", "value", "key", "delete", "pendingActions", "editor", "plugins", "length", "t", "getMessage", "parseInt", "uploadedPercent", "filePromise", "uploadAdapterCreator", "id", "uid", "_filePromiseWrapper", "_createFilePromiseWrapper", "_adapter", "promise", "status", "CKEditorError", "err", "upload", "uploadResponse", "isFulfilled", "rejecter", "wrapper", "SimpleUploadAdapter", "Plugin", "requires", "FileRepository", "pluginName", "isOfficialPlugin", "options", "editor", "config", "get", "uploadUrl", "logWarning", "plugins", "createUploadAdapter", "loader", "Adapter", "constructor", "xhr", "file", "then", "Promise", "resolve", "reject", "_initRequest", "_initListeners", "_sendRequest", "abort", "XMLHttpRequest", "open", "responseType", "genericErrorText", "name", "addEventListener", "response", "error", "message", "urls", "url", "default", "upload", "evt", "lengthComputable", "uploadTotal", "total", "uploaded", "loaded", "headers", "withCredentials", "headerName", "Object", "keys", "setRequestHeader", "data", "FormData", "append", "send", "parse", "m", "space", "names", "x", "i", "h", "s", "v", "a", "h", "s", "l", "h", "s", "v", "a", "b", "c", "d", "module", "r", "g", "b", "a", "first", "first", "cache", "html", "e", "root", "style", "i", "p", "root", "h", "root", "root", "h", "s", "v", "ViewCollection", "Collection", "constructor", "initialItems", "idProperty", "on", "evt", "view", "index", "_renderViewIntoCollectionParent", "element", "_parentElement", "remove", "map", "destroy", "setParent", "elementOrDocFragment", "events", "length", "isStringArray", "CKEditorError", "to", "dest", "evtName", "delegate", "stopDelegating", "isRendered", "render", "insertBefore", "children", "subject", "arr", "every", "a", "xhtmlNs", "Template", "EmitterMixin", "def", "ns", "Object", "assign", "normalize", "clone", "_isRendered", "_revertData", "node", "_renderNode", "intoFragment", "apply", "getEmptyRevertData", "isApplying", "revertData", "revert", "_revertTemplateFromNode", "getViews", "search", "child", "isView", "isTemplate", "bind", "observable", "emitter", "eventNameOrFunctionOrAttribute", "callback", "TemplateToBinding", "eventNameOrFunction", "attribute", "if", "valueIfTrue", "TemplateIfBinding", "extend", "template", "extendTemplate", "data", "isInvalid", "tag", "text", "_renderText", "_renderElement", "document", "createElementNS", "_renderAttributes", "_renderElementChildren", "_setUpListeners", "textContent", "createTextNode", "hasTemplateBinding", "_bindToObservable", "schema", "updater", "getTextUpdater", "join", "attributes", "attrName", "domAttrValue", "getAttribute", "attrValue", "attrNs", "isNamespaced", "valueToBind", "value", "shouldExtend", "unshift", "getAttributeUpdater", "_renderStyleAttribute", "val", "reduce", "prev", "next", "concat", "arrayValueReducer", "isFalsy", "setAttributeNS", "styles", "styleName", "styleValue", "getStyleUpdater", "style", "container", "createDocumentFragment", "childIndex", "isViewCollection", "appendChild", "isNode", "childRevertData", "push", "childNodes", "eventListeners", "key", "revertBindings", "schemaItem", "domEvtName", "domSelector", "split", "activateDomEventListener", "bindings", "syncValueSchemaValue", "filter", "item", "templateBinding", "activateAttributeListener", "binding", "revertBinding", "removeAttribute", "setAttribute", "i", "TemplateBinding", "getValue", "listenTo", "stopListening", "domEvt", "target", "matches", "fire", "Array", "isArray", "some", "getValueSchemaValue", "values", "set", "el", "removeAttributeNS", "cloneDeepWith", "normalizePlainTextDefinition", "normalizeTextDefinition", "normalizeListeners", "normalizeAttributes", "toArray", "arrayify", "listeners", "l", "obj", "cur", "extendObjectValueArray", "ext", "childDef", "View", "isObject", "DomEmitterMixin", "ObservableMixin", "locale", "t", "_viewCollections", "_unboundChildren", "createCollection", "collection", "decorate", "bindTemplate", "_bindTemplate", "views", "add", "registerChild", "isIterable", "deregisterChild", "setTemplate", "definition", "c", "clickOutsideHandler", "activator", "contextElements", "listenerOptions", "path", "composedPath", "contextElementsList", "contextElement", "contains", "includes", "CssTransitionDisablerMixin", "view", "Mixin", "disableCssTransitions", "_isCssTransitionsDisabled", "enableCssTransitions", "constructor", "args", "set", "initializeCssTransitionDisablerMixin", "extendTemplate", "attributes", "class", "bindTemplate", "if", "submitHandler", "listenTo", "element", "evt", "domEvt", "preventDefault", "fire", "useCapture", "addKeyboardHandlingForGrid", "keystrokeHandler", "focusTracker", "gridItems", "numberOfColumns", "uiLanguageDirection", "getNumberOfColumns", "getGridItemFocuser", "focusedElementIndex", "getLeftElementIndex", "length", "getRightElementIndex", "nextIndex", "Math", "floor", "getIndexToFocus", "focusedElement", "find", "item", "getIndex", "nextIndexToFocus", "get", "focus", "stopPropagation", "elementIndex", "collectionLength", "IconView", "View", "bind", "setTemplate", "tag", "ns", "value", "viewBox", "to", "render", "_updateXMLContent", "_colorFillPaths", "on", "content", "parsed", "DOMParser", "parseFromString", "trim", "svg", "querySelector", "getAttribute", "name", "Array", "from", "presentationalAttributeNames", "includes", "setAttribute", "firstChild", "removeChild", "childNodes", "appendChild", "fillColor", "querySelectorAll", "forEach", "path", "style", "fill", "ButtonLabelView", "undefined", "text", "id", "children", "ButtonView", "locale", "labelView", "_focusDelayed", "ariaLabelUid", "uid", "createCollection", "_setupLabelView", "iconView", "keystrokeView", "_createKeystrokeView", "_getTooltipString", "template", "role", "type", "tabindex", "click", "isEnabled", "isOn", "isToggleable", "isCheckableRole", "String", "env", "isSafari", "delay", "mousedown", "mouseup", "cancel", "icon", "add", "withKeystroke", "keystroke", "destroy", "getEnvKeystrokeText", "tooltip", "label", "Function", "FormHeaderView", "options", "FocusCycler", "EmitterMixin", "focusables", "actions", "methodName", "data", "keystrokeHandlerOptions", "focusFirst", "priority", "focusLast", "first", "isDomFocusable", "last", "filter", "slice", "next", "_getDomFocusableItem", "previous", "current", "index", "viewIndex", "focused", "_focus", "chain", "chainedFocusCycler", "getCurrentFocusedView", "oldCurrent", "focusNext", "stop", "focusPrevious", "unchain", "otherFocusCycler", "stopListening", "direction", "step", "focusableItem", "focusableItemCandidate", "isFocusable", "isVisible", "isViewWithFocusCycler", "focusCycler", "DraggableViewMixin", "DraggableMixin", "_onDragBound", "_onDrag", "_onDragEndBound", "_onDragEnd", "x", "y", "_attachListeners", "_onDragStart", "global", "document", "_isHandleElementPressed", "_attachDragListeners", "MouseEvent", "clientX", "clientY", "touches", "_lastDraggingCoordinates", "isDragging", "_detachDragListeners", "newX", "newY", "deltaX", "round", "deltaY", "dragHandleElement", "target", "HTMLElement", "contains", "DialogActionsView", "keystrokes", "KeystrokeHandler", "_focusTracker", "FocusTracker", "_focusables", "ViewCollection", "setButtons", "definitions", "definition", "button", "property", "onExecute", "onCreate", "_updateFocusCyclableItems", "v", "DialogContentView", "remove", "DialogViewPosition", "SCREEN_CENTER", "EDITOR_CENTER", "EDITOR_TOP_SIDE", "EDITOR_TOP_CENTER", "EDITOR_BOTTOM_CENTER", "EDITOR_ABOVE_CENTER", "EDITOR_BELOW_CENTER", "toPx", "toUnit", "DialogView", "getCurrentDomRoot", "getViewportOffset", "wasMoved", "t", "_getCurrentDomRoot", "_getViewportOffset", "decorate", "parts", "_focusCycler", "isModal", "top", "left", "visibility", "source", "moveBy", "window", "_isVisible", "updatePosition", "_isTransparent", "setTimeout", "headerView", "title", "hasCloseButton", "actionButtons", "closeButtonView", "_createCloseButton", "ariaLabel", "contentView", "addMany", "actionsView", "viewportRect", "_getViewportRect", "dialogRect", "_getDialogRect", "width", "right", "_moveTo", "_left", "_top", "moveTo", "parentNode", "configuredPosition", "position", "domRootRect", "_getVisibleDomRootRect", "defaultOffset", "leftCoordinate", "contentLanguageDirection", "_moveOffScreen", "height", "bottom", "visibleDomRootRect", "Rect", "getVisible", "getIntersection", "firstElementChild", "viewportOffset", "child", "push", "focusable", "buttonView", "icons", "Dialog", "Plugin", "editor", "_initShowHideListeners", "_initFocusToggler", "_initMultiRootIntegration", "isOpen", "accessibility", "addKeystrokeInfos", "categoryId", "mayRequireFn", "pluginName", "isOfficialPlugin", "_unlockBodyScroll", "_show", "onShow", "_visibleDialogPlugin", "_hide", "_onHide", "isFocused", "editing", "model", "changedRoots", "differ", "getChangedRoots", "changes", "state", "show", "dialogDefinition", "hide", "className", "onHide", "getDomRoot", "selection", "anchor", "root", "rootName", "ui", "body", "_lockBodyScroll", "setupParts", "reset", "documentElement", "classList", "ListItemButtonView", "_checkIconHolderView", "CheckIconHolderView", "hasCheckSpace", "_hasCheck", "_watchCheckIconHolderMount", "propertyName", "hasCheck", "_createCheckIconView", "_checkIconView", "_watchCheckIconMount", "has", "check", "MenuBarMenuListItemButtonView", "withText", "LabelView", "for", "AccessibilityHelpContentView", "helpLabel", "createElement", "_createCategories", "values", "categories", "map", "categoryDefinition", "elements", "groups", "groupDefinition", "_createGroup", "flat", "description", "splice", "definitionAndDescriptionElements", "sort", "a", "b", "localeCompare", "keystrokeDefinition", "_createGroupRow", "unshift", "dt", "dd", "normalizedKeystrokeDefinition", "normalizeKeystrokeDefinition", "keystrokeAlternativeHTMLs", "keystrokeAlternative", "keystrokeToEnvKbd", "join", "innerHTML", "isMac", "split", "part", "AccessibilityHelp", "requires", "componentFactory", "_createButton", "_toggleDialog", "_setupRootLabels", "ButtonClass", "dialog", "plugins", "accessibilityIcon", "editingView", "change", "writer", "roots", "addAriaLabelTextToRoot", "modelRoot", "viewRoot", "getRoot", "currentAriaLabel", "newAriaLabel", "segment", "keystrokeInfos", "BodyCollection", "initialItems", "bodyCollectionContainer", "_bodyCollectionContainer", "Template", "dir", "wrapper", "childElementCount", "SwitchButtonView", "toggleSwitchView", "_createToggleView", "FileDialogButtonView", "FileDialogViewMixin", "FileDialogListItemButtonView", "FileDialogView", "_fileInputView", "FileInputView", "delegate", "open", "accept", "multiple", "files", "CollapsibleView", "childViews", "_createButtonView", "hidden", "_collapsibleAriaLabelUid", "dropdownArrowIcon", "isCollapsed", "getLocalizedColorOptions", "localizedColorNames", "Black", "Grey", "White", "Red", "Orange", "Yellow", "Green", "Aquamarine", "Turquoise", "Blue", "Purple", "colorOption", "normalizeColorOptions", "normalizeSingleColorDefinition", "option", "color", "hasBorder", "styles", "ColorTileView", "checkIcon", "backgroundColor", "isMediaForcedColors", "ColorGridView", "colorDefinitions", "columns", "viewStyleAttribute", "gridTemplateColumns", "items", "colorTile", "selectedColor", "convertColor", "outputFormat", "colorObject", "parseColorString", "space", "canConvertParsedColor", "fromColorSpace", "toColorSpace", "convertedColorChannels", "hexValue", "formatColorOutput", "convertToHex", "registerCustomElement", "elementName", "customElements", "define", "format", "colorString", "startsWith", "parsedHex", "parse", "alpha", "parsedColor", "Object", "keys", "convert", "LabeledFieldView", "viewCreator", "viewUid", "statusUid", "fieldView", "_createLabelView", "statusView", "_createStatusView", "fieldWrapperChildren", "errorText", "infoText", "InputBase", "placeholder", "readonly", "input", "_updateIsEmpty", "_setDomElementValue", "select", "isEmpty", "isInputElementEmpty", "domElement", "InputView", "inputmode", "InputTextView", "InputNumberView", "min", "max", "DropdownPanelView", "View", "constructor", "locale", "bind", "bindTemplate", "set", "children", "createCollection", "setTemplate", "tag", "attributes", "class", "to", "value", "if", "tabindex", "on", "selectstart", "evt", "target", "tagName", "toLocaleLowerCase", "preventDefault", "length", "firstChild", "first", "focus", "logWarning", "childView", "dropdownPanel", "lastChild", "last", "focusLast", "DropdownView", "buttonView", "panelView", "undefined", "keystrokes", "KeystrokeHandler", "focusTracker", "FocusTracker", "id", "extendTemplate", "render", "add", "element", "listenTo", "isOpen", "name", "panelPosition", "optimalPanelPosition", "_getOptimalPosition", "fitInViewport", "positions", "_panelPositions", "position", "closeDropdown", "data", "cancel", "isEnabled", "south", "north", "southEast", "southWest", "northEast", "northWest", "southMiddleEast", "southMiddleWest", "northMiddleEast", "northMiddleWest", "defaultPanelPositions", "uiLanguageDirection", "buttonRect", "panelRect", "top", "bottom", "left", "width", "height", "getOptimalPosition", "DropdownButtonView", "ButtonView", "arrowView", "_createArrowView", "String", "delegate", "IconView", "content", "dropdownArrowIcon", "ListItemView", "View", "constructor", "locale", "bind", "bindTemplate", "set", "children", "createCollection", "setTemplate", "tag", "attributes", "class", "if", "value", "role", "first", "focus", "ListSeparatorView", "ListItemGroupView", "labelView", "LabelView", "nestedList", "ListView", "label", "isVisible", "to", "addMany", "ariaLabelledBy", "id", "focusTracker", "destroy", "keystrokes", "items", "firstListItem", "find", "item", "_listItemGroupToChangeListeners", "WeakMap", "focusables", "ViewCollection", "FocusTracker", "KeystrokeHandler", "_focusCycler", "FocusCycler", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "undefined", "render", "_registerFocusableItemsGroup", "_registerFocusableListItem", "on", "evt", "data", "removed", "_deregisterFocusableItemsGroup", "_deregisterFocusableListItem", "added", "Array", "from", "reverse", "index", "listenTo", "element", "focusFirst", "focusLast", "add", "remove", "_getOnGroupItemsChangeCallback", "groupView", "getIndex", "groupIndex", "forEach", "child", "childIndex", "registeredChildIndex", "groupItemsChangeCallback", "off", "get", "delete", "toPx", "toUnit", "POSITION_OFF_SCREEN", "top", "left", "name", "config", "withArrow", "BalloonPanelView", "View", "constructor", "locale", "bind", "bindTemplate", "set", "undefined", "_pinWhenIsVisibleCallback", "_resizeObserver", "content", "createCollection", "setTemplate", "tag", "attributes", "class", "to", "value", "if", "style", "children", "hide", "destroy", "isVisible", "attachTo", "options", "target", "getDomElement", "show", "defaultPositions", "positionOptions", "Object", "assign", "element", "positions", "southArrowNorth", "southArrowNorthMiddleWest", "southArrowNorthMiddleEast", "southArrowNorthWest", "southArrowNorthEast", "northArrowSouth", "northArrowSouthMiddleWest", "northArrowSouthMiddleEast", "northArrowSouthWest", "northArrowSouthEast", "viewportStickyNorth", "limiter", "global", "document", "body", "fitInViewport", "optimalPosition", "_getOptimalPosition", "parseInt", "position", "pin", "unpin", "_startPinning", "_stopPinning", "listenTo", "stopListening", "targetElement", "limiterElement", "evt", "domEvt", "scrollTarget", "isWithinScrollTarget", "contains", "isLimiterWithinScrollTarget", "useCapture", "window", "isText", "parentElement", "checkVisibility", "ResizeObserver", "generatePositions", "sideOffset", "arrowSideOffset", "heightOffset", "arrowHeightOffset", "stickyVerticalOffset", "northWestArrowSouthWest", "targetRect", "balloonRect", "getNorthTop", "northWestArrowSouthMiddleWest", "width", "northWestArrowSouth", "northWestArrowSouthMiddleEast", "northWestArrowSouthEast", "northEastArrowSouthWest", "right", "northEastArrowSouthMiddleWest", "northEastArrowSouth", "northEastArrowSouthMiddleEast", "northEastArrowSouthEast", "southWestArrowNorthWest", "getSouthTop", "southWestArrowNorthMiddleWest", "southWestArrowNorth", "southWestArrowNorthMiddleEast", "southWestArrowNorthEast", "southEastArrowNorthWest", "southEastArrowNorthMiddleWest", "southEastArrowNorth", "southEastArrowNorthMiddleEast", "southEastArrowNorthEast", "westArrowEast", "height", "eastArrowWest", "viewportRect", "limiterRect", "boundaryRect", "getIntersection", "bottom", "getOptimalPosition", "object", "isElement", "isRange", "commonAncestorContainer", "ToolbarSeparatorView", "View", "constructor", "locale", "setTemplate", "tag", "attributes", "class", "ToolbarLineBreakView", "preventDefault", "view", "bindTemplate", "to", "evt", "target", "element", "normalizeToolbarConfig", "config", "Array", "isArray", "items", "removeItems", "predefinedConfigOptions", "NESTED_TOOLBAR_ICONS", "alignLeft", "icons", "bold", "importExport", "paragraph", "plus", "text", "threeVerticalDots", "pilcrow", "dragIndicator", "ToolbarView", "options", "bind", "t", "set", "createCollection", "focusTracker", "FocusTracker", "keystrokes", "KeystrokeHandler", "undefined", "itemsView", "ItemsView", "children", "add", "focusables", "isRtl", "uiLanguageDirection", "_focusCycler", "FocusCycler", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "classes", "if", "shouldGroupWhenFull", "isFloating", "push", "role", "style", "maxWidth", "tabindex", "on", "mousedown", "_behavior", "DynamicGrouping", "StaticLayout", "render", "item", "remove", "listenTo", "destroy", "focusFirst", "focusLast", "itemsOrConfig", "factory", "addMany", "_buildItemsFromConfig", "normalizedRemoveItems", "itemsToAdd", "_cleanItemsConfiguration", "map", "isObject", "_createNestedToolbarDropdown", "create", "filter", "filteredItems", "idx", "indexOf", "logWarning", "has", "_cleanSeparatorsAndLineBreaks", "nonSeparatorPredicate", "count", "length", "firstCommandItemIndex", "findIndex", "lastCommandItemIndex", "slice", "reverse", "name", "isDuplicated", "definition", "componentFactory", "label", "icon", "tooltip", "withText", "dropdownView", "createDropdown", "buttonView", "addToolbarToDropdown", "toolbarView", "bindTo", "using", "isFocusable", "extendTemplate", "resizeObserver", "cachedPadding", "shouldUpdateGroupingOnNextResize", "viewChildren", "viewFocusables", "viewItemsView", "viewFocusTracker", "viewLocale", "ungroupedItems", "groupedItems", "groupedItemsDropdown", "_createGroupedItemsDropdown", "_updateFocusCyclableItems", "changeData", "index", "added", "from", "removedItem", "removed", "currentIndex", "addedItem", "_updateGrouping", "viewElement", "_enableGroupingOnResize", "_enableGroupingOnMaxWidthChange", "ownerDocument", "body", "contains", "isVisible", "initialGroupedItemsCount", "wereItemsGrouped", "_areItemsOverflowing", "_groupLastItem", "_ungroupFirstItem", "fire", "lastChildRect", "Rect", "lastChild", "toolbarRect", "computedStyle", "global", "window", "getComputedStyle", "paddingProperty", "Number", "parseInt", "right", "left", "previousWidth", "ResizeObserver", "entry", "contentRect", "width", "last", "first", "dropdown", "panelPosition", "tooltipPosition", "clear", "SplitButtonView", "actionButton", "actionView", "_createActionView", "arrowView", "_createArrowView", "value", "cancel", "focusedElement", "focus", "ButtonView", "delegate", "dropdownArrowIcon", "String", "ButtonClassOrInstance", "DropdownButtonView", "panelView", "DropdownPanelView", "DropdownView", "addDefaultBehaviors", "addToolbarToDropdown", "dropdownView", "buttonsOrCallback", "options", "extendTemplate", "attributes", "class", "isOpen", "addToolbarToOpenDropdown", "once", "priority", "enableActiveItemFocusOnDropdownOpen", "focusChildOnDropdownOpen", "toolbarView", "items", "find", "item", "isOn", "locale", "t", "ToolbarView", "buttons", "ariaLabel", "maxWidth", "isCompact", "isVertical", "ViewCollection", "bindTo", "using", "addMany", "panelView", "children", "add", "focusTracker", "delegate", "to", "addListToDropdown", "itemsOrCallback", "addListToOpenDropdown", "listView", "ListItemView", "first", "ListView", "role", "bindViewCollectionItemsToDefinitions", "childSelectorCallback", "on", "childToFocus", "focus", "logWarning", "view", "priorities", "low", "addDefaultBehaviors", "closeDropdownOnClickOutside", "closeDropdownOnExecute", "closeDropdownOnBlur", "focusDropdownContentsOnArrows", "focusDropdownButtonOnClose", "focusDropdownPanelOnOpen", "clickOutsideHandler", "emitter", "activator", "isRendered", "callback", "contextElements", "element", "getFocusTrackerTreeElements", "filter", "contains", "elements", "externalViews", "flatMap", "evt", "source", "SwitchButtonView", "name", "isFocused", "keystrokes", "set", "data", "cancel", "focusLast", "some", "global", "document", "activeElement", "buttonView", "listItems", "definitions", "listItemButtons", "reduce", "acc", "ListItemButtonView", "push", "hasAnyCheckboxOnList", "button", "isToggleable", "forEach", "hasCheckSpace", "def", "type", "ListSeparatorView", "groupView", "ListItemGroupView", "label", "model", "listItemView", "bind", "Object", "keys", "createLabeledInputText", "labeledFieldView", "viewUid", "statusUid", "inputView", "InputTextView", "id", "ariaDescribedById", "value", "errorText", "createLabeledInputNumber", "InputNumberView", "inputMode", "createLabeledDropdown", "labeledFieldView", "viewUid", "statusUid", "dropdownView", "createDropdown", "locale", "set", "id", "ariaDescribedById", "bind", "to", "waitingTime", "ColorPickerView", "View", "constructor", "config", "color", "_hexColor", "hexInputRow", "_createInputRow", "children", "createCollection", "hideInput", "add", "setTemplate", "tag", "attributes", "class", "tabindex", "_config", "_debounceColorPickerEvent", "debounce", "fire", "leading", "on", "evt", "propertyName", "newValue", "return", "convertColor", "format", "convertColorToCommonHexFormat", "document", "activeElement", "picker", "setAttribute", "render", "registerCustomElement", "HexBase", "global", "createElement", "_createSlidersView", "element", "insertBefore", "appendChild", "styleSheetForFocusedColorPicker", "textContent", "shadowRoot", "addEventListener", "event", "detail", "value", "env", "isGecko", "isiOS", "isSafari", "input", "get", "focus", "firstSlider", "slidersView", "first", "colorPickersChildren", "sliders", "filter", "item", "getAttribute", "map", "slider", "view", "SliderView", "forEach", "colorInput", "_createColorInput", "ColorPickerInputRowView", "labeledInput", "LabeledFieldView", "createLabeledInputText", "t", "label", "fieldView", "pickerColor", "isFocused", "startsWith", "substring", "inputValue", "maybeHexColor", "tryParseHexColor", "resetValidationStatus", "getParsedColor", "inputView", "errorText", "inputColor", "ret", "convertToHex", "length", "join", "toLowerCase", "HashView", "hashLessColor", "trim", "replace", "includes", "test", "DocumentColorCollection", "ObservableMixin", "Collection", "options", "index", "find", "hasColor", "ColorGridsFragmentView", "colors", "columns", "removeButtonLabel", "documentColorsLabel", "documentColorsCount", "colorPickerLabel", "focusTracker", "focusables", "bindTemplate", "items", "colorDefinitions", "documentColors", "_focusables", "_removeButtonLabel", "_colorPickerLabel", "_documentColorsLabel", "if", "removeColorButtonView", "_createRemoveColorButton", "model", "attributeName", "maxCount", "clear", "root", "getRoots", "range", "createRangeIn", "node", "getItems", "is", "hasAttribute", "_addColorToDocumentColors", "documentColorsGrid", "staticColorsGrid", "selectedColor", "_createStaticColorsGrid", "Template", "text", "_createDocumentColorsGrid", "_createColorPickerButton", "_addColorSelectorElementsToFocusTracker", "destroy", "colorPickerButtonView", "ButtonView", "withText", "icon", "icons", "colorPalette", "buttonView", "eraser", "source", "colorGrid", "ColorGridView", "data", "extendTemplate", "bindTo", "using", "colorObj", "colorTile", "ColorTileView", "hasBorder", "tooltip", "name", "val", "predefinedColor", "definition", "Object", "assign", "ColorPickerFragmentView", "keystrokes", "colorPickerViewConfig", "undefined", "_colorPickerViewConfig", "saveButtonView", "cancelButtonView", "_createActionButtons", "actionBarView", "_createActionBarView", "colorPickerView", "listenTo", "_addColorPickersElementsToFocusTracker", "_stopPropagationOnArrowsKeys", "_executeOnEnterPress", "_executeUponColorChange", "isVisible", "focusedElement", "isValid", "stopPropagation", "preventDefault", "actionBarRow", "check", "type", "cancel", "ColorSelectorView", "FocusTracker", "KeystrokeHandler", "ViewCollection", "_focusCycler", "FocusCycler", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "colorGridsFragmentView", "colorPickerFragmentView", "evtName", "_appendColorGridsFragment", "_appendColorPickerFragment", "_isColorPickerFragmentVisible", "_isColorGridsFragmentVisible", "focusFirst", "focusLast", "updateDocumentColors", "updateSelectedColors", "delegate", "showColorPickerFragment", "addColorPickerButton", "ComponentFactory", "editor", "_components", "Map", "names", "values", "originalName", "callback", "getNormalized", "create", "has", "CKEditorError", "String", "BALLOON_CLASS", "TooltipManager", "DomEmitterMixin", "_currentElementWithTooltip", "_currentTooltipPosition", "_mutationObserver", "_watchdogExcluded", "_editors", "_instance", "tooltipTextView", "balloonPanelView", "BalloonPanelView", "content", "createMutationObserver", "_updateTooltipPosition", "_pinTooltipDebounced", "_pinTooltip", "_unpinTooltipDebounced", "_unpinTooltip", "_onKeyDown", "useCapture", "_onEnterOrFocus", "_onLeaveOrBlur", "_onScroll", "editorBodyViewCollection", "ui", "body", "delete", "stopListening", "remove", "size", "getPositioningFunctions", "position", "defaultPositions", "defaultBalloonPositions", "s", "southArrowNorth", "southArrowNorthEast", "southArrowNorthWest", "n", "northArrowSouth", "e", "eastArrowWest", "w", "westArrowEast", "sw", "se", "domEvent", "key", "target", "elementWithTooltipAttribute", "getDescendantWithTooltip", "matches", "getTooltipData", "relatedTarget", "isElement", "balloonElement", "isEnteringBalloon", "contains", "isLeavingBalloon", "descendantWithTooltip", "relatedDescendantWithTooltip", "targetDomElement", "cssClass", "bodyViewCollection", "className", "pin", "positions", "attach", "priority", "unpin", "detach", "tooltipData", "generatePositions", "heightOffset", "sideOffset", "Set", "closest", "dataset", "ckeTooltipText", "ckeTooltipPosition", "ckeTooltipClass", "mutationObserver", "MutationObserver", "observe", "attributeFilter", "disconnect", "ICON_WIDTH", "ICON_HEIGHT", "NARROW_ROOT_HEIGHT_THRESHOLD", "NARROW_ROOT_WIDTH_THRESHOLD", "DEFAULT_LABEL", "PoweredBy", "_balloonView", "_lastFocusedEditableElement", "_showBalloonThrottled", "throttle", "_showBalloon", "_handleEditorReady", "balloon", "forceVisible", "verifyLicense", "_updateLastFocusedEditableElement", "_hideBalloon", "poweredByConfig", "getNormalizedConfig", "PoweredByView", "attachOptions", "getBalloonAttachOptions", "_createBalloonView", "editableEditorElements", "Array", "from", "getEditableElementsNames", "getEditableElement", "iconView", "IconView", "poweredByIcon", "isColorInherited", "style", "width", "height", "href", "dragstart", "focusedEditableElement", "positioningFunction", "side", "getLowerRightCornerPosition", "getLowerLeftCornerPosition", "getLowerCornerPosition", "rootRect", "balloonRect", "left", "horizontalOffset", "getBalloonLeft", "visibleEditableElementRect", "editableElementRect", "Rect", "balloonTop", "bottom", "verticalOffset", "balloonLeft", "newBalloonPositionRect", "clone", "moveTo", "getIntersection", "newBalloonPositionVisibleRect", "getVisible", "getArea", "top", "withArrow", "userConfig", "contentLanguageDirection", "AriaLiveAnnouncerPoliteness", "POLITE", "ASSERTIVE", "AriaLiveAnnouncer", "once", "politeness", "announce", "announcement", "AriaLiveAnnouncerView", "isUnsafeHTML", "politenessRegionView", "regionViews", "AriaLiveAnnouncerRegionView", "_pruneAnnouncementsInterval", "clearInterval", "_domConverter", "htmlProcessor", "domConverter", "setInterval", "_listElement", "firstChild", "messageListItem", "setContentOf", "innerText", "querySelector", "MenuBarMenuListItemView", "ListItemView", "parentMenuView", "NESTED_PANEL_HORIZONTAL_OFFSET", "MenuBarBehaviors", "toggleMenusAndFocusItemsOnHover", "menuBarView", "isFocusBorderEnabled", "isOpen", "menuView", "menus", "pathLeaf", "path", "isListItemContainingMenu", "isEnabled", "focusCycleMenusOnArrows", "isContentRTL", "uiLanguageDirection", "cycleTopLevelMenus", "currentMenuView", "step", "currentIndex", "getIndex", "isCurrentMenuViewOpen", "menusCount", "menuViewToOpen", "closeMenusWhenTheBarCloses", "closeMenuWhenAnotherOnTheSameLevelOpens", "closeOnClickOutside", "clickOutsideHandler", "emitter", "activator", "close", "contextElements", "child", "enableFocusHighlightOnInteraction", "isKeyPressed", "_", "MenuBarMenuBehaviors", "openAndFocusPanelOnArrowDownKey", "panelView", "openOnArrowRightKey", "keystroke", "openOnButtonClick", "toggleOnButtonClick", "openAndFocusOnEnterKeyPress", "closeOnArrowLeftKey", "closeOnEscKey", "closeOnParentClose", "MenuBarMenuViewPanelPositioningFunctions", "southEast", "buttonRect", "southWest", "panelRect", "northEast", "northWest", "eastSouth", "right", "eastNorth", "westSouth", "westNorth", "DefaultMenuBarItems", "menuId", "groups", "groupId", "normalizeMenuBarConfig", "configObject", "cloneDeep", "addItems", "removeItems", "isUsingDefaultConfig", "processMenuBarConfig", "normalizedConfig", "componentFactory", "extraItems", "configClone", "handleAdditions", "handleRemovals", "purgeUnavailableComponents", "purgeEmptyMenus", "localizeMenuLabels", "originalConfig", "itemsToBeRemoved", "successfullyRemovedItems", "push", "walkConfigMenus", "menuDefinition", "groupDefinition", "itemId", "getIdFromGroupItem", "itemName", "logWarning", "menuBarConfig", "successFullyAddedItems", "itemToAdd", "relation", "getRelationFromPosition", "relativeId", "getRelativeIdFromPosition", "isMenuBarMenuAddition", "unshift", "menu", "topLevelMenuDefinitionIndex", "findIndex", "splice", "wasAdded", "addMenuOrItemToGroup", "isMenuBarMenuGroupAddition", "group", "relativeGroupIndex", "addedItemConfig", "itemOrMenuToAdd", "groupItems", "relativeItemIndex", "groupItem", "isItemUnavailable", "parentMenuConfig", "componentName", "wasSubMenuPurged", "warnAboutEmptyMenu", "isMenuDefinition", "emptyMenuConfig", "localizedCategoryLabels", "string", "isArray", "topLevelMenuDefinition", "walk", "match", "EditorUI", "isReady", "_editableElementsMap", "_focusableToolbarDefinitions", "_extraMenuBarElements", "_lastFocusedForeignElement", "editingView", "editing", "tooltipManager", "poweredBy", "ariaLiveAnnouncer", "_readViewportOffsetFromConfig", "_bindBodyCollectionWithFocusTracker", "update", "_handleScrollToTheSelection", "_initFocusTracking", "domElement", "ckeditorInstance", "rootName", "setUpKeystrokeHandler", "getDomRoot", "removeEditableElement", "keys", "toolbarView", "isRendered", "extendMenuBar", "_editableElements", "console", "warn", "editorUI", "_initMenuBar", "menuBarViewElement", "normalizedMenuBarConfig", "fillFromConfig", "_saveLastFocusedForeignElement", "viewportOffsetConfig", "legacyOffsetConfig", "candidateDefinitions", "currentFocusedToolbarDefinition", "_getCurrentFocusedToolbarDefinition", "_getFocusableCandidateToolbarDefinitions", "i", "candidateDefinition", "shift", "_focusFocusableCandidateToolbar", "afterBlur", "focusedToolbarDef", "domRoots", "definitions", "toolbarDef", "beforeFocus", "sort", "defA", "defB", "getToolbarDefinitionWeight", "candidateToolbarDefinition", "configuredViewportOffset", "viewportOffset", "weight", "isContextual", "EditorUIView", "BodyCollection", "attachToDom", "detachFromDom", "BoxedEditorUIView", "main", "_voiceLabelView", "_createVoiceLabel", "role", "dir", "lang", "uiLanguage", "voiceLabel", "LabelView", "EditableUIView", "editableElement", "contentLanguage", "_editableElement", "_hasExternalElement", "_editingView", "template", "apply", "_updateIsFocusedClasses", "revert", "hasExternalElement", "isRenderingInProgress", "updateAfterRender", "change", "writer", "viewRoot", "getRoot", "addClass", "removeClass", "InlineEditableUIView", "_options", "getEditableAriaLabel", "editableName", "existingLabel", "Notification", "ContextPlugin", "pluginName", "isOfficialPlugin", "on", "evt", "data", "window", "alert", "message", "priority", "_showNotification", "type", "namespace", "title", "event", "fire", "Model", "ObservableMixin", "constructor", "attributes", "properties", "extend", "set", "toPx", "toUnit", "ContextualBalloon", "Plugin", "editor", "visibleStack", "_viewToStack", "Map", "_idToStack", "_view", "_rotatorView", "_fakePanelsView", "positionLimiter", "view", "editing", "viewDocument", "document", "editableElement", "selection", "domConverter", "mapViewToDom", "root", "decorate", "destroy", "_createPanelView", "hasView", "Array", "from", "keys", "includes", "add", "CKEditorError", "stackId", "has", "get", "_numberOfStacks", "size", "_visibleStack", "singleViewMode", "showStack", "stack", "_showView", "remove", "_singleViewMode", "visibleView", "_showNextStack", "hide", "hideView", "values", "delete", "_getStackId", "updatePosition", "position", "pin", "getPositionOptions", "pop", "limiter", "Object", "assign", "viewportOffsetConfig", "ui", "viewportOffset", "id", "BalloonPanelView", "locale", "body", "_createRotatorView", "_createFakePanelsView", "entry", "entries", "find", "stacks", "nextIndex", "indexOf", "length", "RotatorView", "t", "content", "bind", "to", "value", "isSingleViewMode", "numberOfStacks", "current", "buttonNextView", "focusTracker", "isFocused", "focus", "buttonPrevView", "_showPrevStack", "FakePanelsView", "number", "showPanels", "Math", "min", "listenTo", "balloonClassName", "withArrow", "class", "showView", "View", "bindTemplate", "FocusTracker", "_createButtonView", "icons", "previousArrow", "nextArrow", "createCollection", "setTemplate", "tag", "children", "text", "render", "element", "clear", "label", "icon", "ButtonView", "tooltip", "balloonPanelView", "_balloonPanelView", "style", "top", "left", "width", "height", "name", "next", "prev", "_addPanels", "_removePanels", "registerChild", "last", "deregisterChild", "numberOfPanels", "Rect", "StickyPanelView", "_contentPanelPlaceholder", "Template", "display", "isSticky", "_contentPanelRect", "contentPanelElement", "if", "getBoundingClientRect", "bottom", "marginLeft", "checkIfShouldBeSticky", "global", "useCapture", "limiterElement", "isActive", "_unstick", "limiterRect", "visibleLimiterRect", "getVisible", "windowRect", "viewportTopOffset", "getIntersection", "visibleLimiterTop", "limiterBottomOffset", "stickyBottomOffset", "max", "_stickToBottomOfLimiter", "_stickToTopOfAncestors", "topOffset", "_isStickyToTheBottomOfLimiter", "_stickyTopOffset", "_stickyBottomOffset", "_marginLeft", "scrollX", "toPx", "toUnit", "BalloonToolbar", "Plugin", "constructor", "editor", "_resizeObserver", "_balloonConfig", "normalizeToolbarConfig", "config", "get", "toolbarView", "_createToolbarView", "focusTracker", "FocusTracker", "_trackFocusableEditableElements", "add", "ui", "addToolbar", "beforeFocus", "show", "afterBlur", "hide", "isContextual", "_balloon", "plugins", "ContextualBalloon", "_fireSelectionChangeDebounced", "debounce", "fire", "decorate", "pluginName", "isOfficialPlugin", "requires", "selection", "model", "document", "listenTo", "evt", "name", "isFocused", "isToolbarVisible", "visibleView", "data", "directChange", "isCollapsed", "editing", "view", "shouldNotGroupWhenFull", "editableElement", "editable", "element", "ResizeObserver", "entry", "maxWidth", "contentRect", "width", "_updatePosition", "once", "fillFromConfig", "componentFactory", "t", "locale", "shouldGroupWhenFull", "ToolbarView", "isFloating", "ariaLabel", "render", "showForCollapsedSelection", "schema", "hasView", "selectionContainsOnlyMultipleSelectables", "Array", "from", "items", "every", "item", "isEnabled", "undefined", "position", "_getBalloonPositionData", "balloonClassName", "stopListening", "remove", "addObserver", "TrackEditableElements", "Observer", "observe", "domElement", "stopObserving", "viewDocument", "viewSelection", "isBackward", "target", "range", "getFirstRange", "getLastRange", "rangeRects", "Rect", "getDomRangeRects", "domConverter", "viewRangeToDom", "length", "pop", "positions", "_getBalloonPositions", "updatePosition", "destroy", "cancel", "isSafariIniOS", "env", "isSafari", "isiOS", "BalloonPanelView", "generatePositions", "heightOffset", "Math", "max", "arrowHeightOffset", "round", "global", "window", "visualViewport", "scale", "defaultPositions", "northWestArrowSouth", "northWestArrowSouthWest", "northWestArrowSouthEast", "northWestArrowSouthMiddleEast", "northWestArrowSouthMiddleWest", "southWestArrowNorth", "southWestArrowNorthWest", "southWestArrowNorthEast", "southWestArrowNorthMiddleWest", "southWestArrowNorthMiddleEast", "southEastArrowNorth", "southEastArrowNorthEast", "southEastArrowNorthWest", "southEastArrowNorthMiddleEast", "southEastArrowNorthMiddleWest", "northEastArrowSouth", "northEastArrowSouthEast", "northEastArrowSouthWest", "northEastArrowSouthMiddleEast", "northEastArrowSouthMiddleWest", "rangeCount", "getRanges", "getContainedElement", "isSelectable", "BlockButtonView", "ButtonView", "bind", "bindTemplate", "isVisible", "isToggleable", "set", "extendTemplate", "attributes", "class", "style", "top", "to", "val", "left", "BlockToolbar", "_blockToolbarConfig", "panelView", "_createPanelView", "buttonView", "_createButtonView", "clickOutsideHandler", "emitter", "contextElements", "activator", "callback", "_hidePanel", "editBlockText", "dragToMoveText", "editBlockLabel", "isDragDropBlockToolbarPluginLoaded", "has", "label", "dataset", "ckeTooltipClass", "_updateButton", "priority", "_repositionButtonOnScroll", "_showPanel", "on", "content", "body", "keystrokes", "iconFromConfig", "icon", "NESTED_TOOLBAR_ICONS", "dragIndicator", "withText", "_hideButton", "canEditAt", "modelTarget", "getSelectedBlocks", "domTarget", "mapViewToDom", "mapper", "toViewElement", "_setupToolbarResize", "_attachButtonToElement", "wasVisible", "_getSelectedEditableElement", "_getToolbarMaxWidth", "pin", "limiter", "focus", "selectedModelRootName", "root", "rootName", "getEditableElement", "focusEditable", "pendingAnimationFrame", "repositionOnScroll", "domEvt", "getAncestors", "includes", "requestAnimationFrame", "useCapture", "usePassive", "targetElement", "buttonElement", "contentStyles", "getComputedStyle", "editableRect", "contentPaddingTop", "parseInt", "paddingTop", "contentLineHeight", "lineHeight", "fontSize", "buttonRect", "positionLeft", "uiLanguageDirection", "right", "positionTop", "height", "moveTo", "absoluteButtonRect", "toAbsoluteRect", "_clipButtonToViewport", "scrollViewportRect", "getVisible", "setButtonClipping", "paths", "clipPath", "join", "markAsHidden", "isHidden", "pointerEvents", "bottom", "delta", "min", "isRTL", "offset", "MenuBarMenuButtonView", "ListItemButtonView", "role", "arrowView", "_createArrowView", "value", "String", "children", "IconView", "dropdownArrowIcon", "MenuBarMenuPanelView", "View", "createCollection", "setTemplate", "tag", "if", "tabindex", "selectstart", "tagName", "toLocaleLowerCase", "preventDefault", "direction", "first", "last", "MenuBarMenuView", "delegate", "KeystrokeHandler", "MenuBarMenuBehaviors", "closeOnEscKey", "_repositionPanelOnOpen", "parentMenuView", "_propagateArrowKeystrokeEvents", "openAndFocusPanelOnArrowDownKey", "toggleOnButtonClick", "openOnButtonClick", "openOnArrowRightKey", "closeOnArrowLeftKey", "openAndFocusOnEnterKeyPress", "closeOnParentClose", "isOpen", "optimalPanelPosition", "_getOptimalPosition", "fitInViewport", "_panelPositions", "southEast", "southWest", "northEast", "northWest", "westSouth", "eastSouth", "westNorth", "eastNorth", "MenuBarMenuViewPanelPositioningFunctions", "getOptimalPosition", "MenuBarMenuListView", "ListView", "_setItemsCheckSpace", "hasAnyToggleableItem", "some", "listButtonView", "pickListButtonMenuViewIfPresent", "forEach", "hasCheckSpace", "ListItemView", "map", "child", "isNestedMenuLikeView", "find", "MenuBarMenuListItemFileDialogButtonView", "FileDialogListItemButtonView", "withKeystroke", "tooltip", "EVENT_NAME_DELEGATES", "MenuBarView", "menus", "isFocusBorderEnabled", "_setupIsOpenUpdater", "extraItems", "processedConfig", "processMenuBarConfig", "normalizedConfig", "topLevelCategoryMenuViews", "menuDefinition", "_createMenu", "addMany", "MenuBarBehaviors", "toggleMenusAndFocusItemsOnHover", "closeMenusWhenTheBarCloses", "closeMenuWhenAnotherOnTheSameLevelOpens", "focusCycleMenusOnArrows", "closeOnClickOutside", "enableFocusHighlightOnInteraction", "topLevelCategoryMenuView", "menuView", "_attachBehaviors", "push", "registerMenu", "listView", "_createMenuItems", "menuGroupDefinition", "groups", "itemDefinition", "menuItemView", "MenuBarMenuListItemView", "isObject", "componentView", "_createMenuItemContentFromFactory", "componentName", "ListSeparatorView", "create", "MenuBarMenuListItemButtonView", "logWarning", "_registerMenuTree", "close", "menuBarItemsList", "filter", "nonSeparatorItems", "closeTimeout", "clearTimeout", "setTimeout", "ChangeBuffer", "constructor", "model", "limit", "_batch", "_size", "_isLocked", "_changeCallback", "evt", "batch", "isLocal", "isUndoable", "_reset", "_selectionChangeCallback", "document", "on", "selection", "createBatch", "isTyping", "size", "input", "changeCount", "isLocked", "off", "ignoreLock", "InsertTextCommand", "Command", "editor", "undoStepSize", "_buffer", "_isEnabledBasedOnSelection", "buffer", "destroy", "options", "doc", "text", "textInsertions", "length", "range", "createSelection", "canEditAt", "resultRange", "enqueueChange", "writer", "lock", "selectionAttributes", "Array", "from", "getAttributes", "deleteContent", "insertContent", "createText", "setSelection", "is", "unlock", "TYPING_INPUT_TYPES", "TYPING_INPUT_TYPES_ANDROID", "InsertTextObserver", "Observer", "view", "focusObserver", "getObserver", "FocusObserver", "typingInputTypes", "env", "isAndroid", "viewDocument", "data", "isEnabled", "targetRanges", "inputType", "domEvent", "includes", "flush", "eventInfo", "EventInfo", "fire", "DomEventData", "stop", "called", "priority", "observe", "stopObserving", "Input", "Plugin", "pluginName", "isOfficialPlugin", "editing", "mapper", "modelSelection", "_compositionQueue", "CompositionQueue", "addObserver", "insertTextCommand", "config", "get", "commands", "add", "listenTo", "isComposing", "preventDefault", "viewSelection", "modelRanges", "getRanges", "map", "viewRange", "toModelRange", "insertText", "selectedText", "getItems", "reduce", "rangeText", "node", "startsWith", "substring", "start", "getShiftedBy", "isCollapsed", "commandData", "push", "execute", "scrollToTheSelection", "keyCode", "deleteSelectionContent", "mutations", "viewElement", "findMappedViewAncestor", "modelElement", "toModelElement", "isComposedElement", "element", "flushComposedElements", "toViewElement", "type", "flushDebounced", "debounce", "_queue", "_compositionElements", "Set", "cancel", "clear", "shift", "commandLiveData", "selectionRanges", "LiveRange", "fromRange", "parent", "ranges", "liveRange", "detachLiveRange", "filter", "reason", "has", "result", "toRange", "detach", "root", "rootName", "viewNode", "DeleteCommand", "direction", "sequence", "doNotResetEntireContent", "modifySelection", "unit", "treatEmojiAsSingleUnit", "_shouldEntireContentBeReplacedWithParagraph", "_replaceEntireContentWithParagraph", "_shouldReplaceFirstBlockWithParagraph", "getFirstRange", "getMinimalFlatRanges", "forEach", "count", "getWalker", "singleCharacters", "ignoreElementEnd", "shallow", "limitElement", "schema", "getLimitElement", "limitElementIsEmpty", "containsEntireContent", "checkChild", "limitElementFirstChild", "getChild", "paragraph", "createElement", "remove", "createRangeIn", "insert", "position", "getFirstPosition", "name", "DELETE_CHARACTER", "DELETE_WORD", "DELETE_CODE_POINT", "DELETE_SELECTION", "DELETE_BACKWARD", "DELETE_FORWARD", "DELETE_EVENT_TYPES", "deleteContentBackward", "deleteWordBackward", "deleteHardLineBackward", "deleteSoftLineBackward", "deleteContentForward", "deleteWordForward", "deleteHardLineForward", "deleteSoftLineForward", "DeleteObserver", "deleteEventSpec", "deleteData", "selectionToRemove", "shouldUseTargetRanges", "BubblingEventInfo", "isBlink", "enableChromeWorkaround", "observer", "pressedKeyCode", "beforeInputReceived", "shouldFireDeleteEvent", "isDeleteKeyCode", "targetRange", "getDeleteDirection", "isMatchingBeforeInput", "shouldIgnoreBeforeInput", "keyCodes", "delete", "backspace", "walker", "nextPosition", "item", "offset", "isInsideSurrogatePair", "isInsideCombinedSymbol", "isInsideEmojiSequence", "Delete", "modelDocument", "_undoOnBackspace", "deleteForwardCommand", "commandName", "plugins", "context", "Typing", "requires", "getLastTextLine", "createPositionAfter", "createRange", "end", "TextWatcher", "ObservableMixin", "testCallback", "_hasMatch", "set", "_startListening", "stopListening", "hasMatch", "directChange", "_evaluateTextBeforeSelection", "isUndo", "suffix", "rangeBeforeSelection", "createPositionAt", "focus", "testResult", "eventData", "Object", "assign", "TwoStepCaretMovement", "_isNextGravityRestorationSkipped", "attributes", "_overrideUid", "locale", "shiftKey", "altKey", "ctrlKey", "arrowRightPressed", "arrowright", "arrowLeftPressed", "arrowleft", "contentDirection", "contentLanguageDirection", "isMovementHandled", "_handleForwardMovement", "_handleBackwardMovement", "_isGravityOverridden", "isBetweenDifferentAttributes", "_restoreGravity", "_enableClickingAfterNode", "_enableInsertContentSelectionAttributesFixer", "_handleDeleteContentAfterNode", "registerAttribute", "attribute", "isAtStart", "hasAnyAttribute", "preventCaretMovement", "clearSelectionAttributes", "_overrideGravity", "setSelectionAttributesFromTheNodeBefore", "isStepAfterAnyAttributeBoundary", "isAtEnd", "MouseObserver", "clicked", "isBackspace", "shouldPreserveAttributes", "change", "overrideSelectionGravity", "restoreSelectionGravity", "observedAttribute", "hasAttribute", "nodeBefore", "isInlineObject", "isObject", "isInline", "key", "value", "checkAttribute", "getAttributeProperties", "copyFromObject", "setSelectionAttribute", "removeSelectionAttribute", "positionBefore", "isStrict", "nodeAfter", "attrBefore", "getAttribute", "undefined", "attrAfter", "TRANSFORMATIONS", "copyright", "to", "registeredTrademark", "trademark", "oneHalf", "oneThird", "twoThirds", "oneForth", "threeQuarters", "lessThanOrEqual", "greaterThanOrEqual", "notEqual", "arrowLeft", "arrowRight", "horizontalEllipsis", "enDash", "emDash", "quotesPrimary", "buildQuotesRegExp", "quotesSecondary", "quotesPrimaryEnGb", "quotesSecondaryEnGb", "quotesPrimaryPl", "quotesSecondaryPl", "buildQuotesRegExp", "quoteCharacter", "RegExp", "findAttributeRange", "position", "attributeName", "value", "model", "createRange", "findAttributeRangeBound", "lookBack", "node", "textNode", "nodeBefore", "nodeAfter", "lastNode", "getAttribute", "previousSibling", "nextSibling", "createPositionAt", "inlineHighlight", "editor", "tagName", "className", "view", "editing", "highlightedElements", "Set", "document", "registerPostFixer", "writer", "selection", "changed", "hasAttribute", "modelRange", "getFirstPosition", "viewRange", "mapper", "toViewRange", "item", "getItems", "is", "hasClass", "addClass", "add", "conversion", "for", "dispatcher", "on", "removeHighlight", "priority", "change", "values", "removeClass", "delete", "AttributeCommand", "Command", "constructor", "editor", "attributeKey", "model", "doc", "document", "value", "_getValueFromFirstAllowedNode", "isEnabled", "schema", "checkAttributeInSelection", "selection", "options", "forceValue", "undefined", "change", "writer", "isCollapsed", "setSelectionAttribute", "removeSelectionAttribute", "ranges", "getValidRanges", "getRanges", "range", "setAttribute", "removeAttribute", "hasAttribute", "item", "getItems", "checkAttribute", "BOLD", "BoldEditing", "Plugin", "pluginName", "isOfficialPlugin", "t", "extend", "allowAttributes", "setAttributeProperties", "isFormatting", "copyOnEnter", "conversion", "attributeToElement", "view", "upcastAlso", "viewElement", "fontWeight", "getStyle", "Number", "name", "styles", "commands", "add", "keystrokes", "set", "accessibility", "addKeystrokeInfos", "label", "keystroke", "getButtonCreator", "commandName", "plugin", "icon", "ButtonClass", "command", "get", "locale", "isToggleable", "bind", "to", "MenuBarMenuListItemButtonView", "role", "tooltip", "listenTo", "execute", "editing", "focus", "BoldUI", "createButton", "icons", "bold", "ui", "componentFactory", "ButtonView", "Bold", "requires", "ITALIC", "ItalicEditing", "Plugin", "pluginName", "isOfficialPlugin", "editor", "t", "model", "schema", "extend", "allowAttributes", "setAttributeProperties", "isFormatting", "copyOnEnter", "conversion", "attributeToElement", "view", "upcastAlso", "styles", "commands", "add", "AttributeCommand", "keystrokes", "set", "accessibility", "addKeystrokeInfos", "label", "keystroke", "ItalicUI", "locale", "createButton", "getButtonCreator", "commandName", "plugin", "icon", "italicIcon", "ui", "componentFactory", "ButtonView", "MenuBarMenuListItemButtonView", "Italic", "requires", "getCopyOnEnterAttributes", "schema", "allAttributes", "attribute", "getAttributeProperties", "copyOnEnter", "EnterCommand", "Command", "editor", "model", "change", "writer", "enterBlock", "fire", "selection", "document", "isSelectionEmpty", "isCollapsed", "range", "getFirstRange", "startElement", "start", "parent", "endElement", "end", "isLimit", "deleteContent", "attributesToCopy", "getAttributes", "splitBlock", "setSelectionAttribute", "leaveUnmerged", "isAtStart", "isAtEnd", "isContainedWithinOneElement", "focus", "setSelection", "splitPos", "split", "nextSibling", "ENTER_EVENT_TYPES", "insertParagraph", "isSoft", "insertLineBreak", "EnterObserver", "Observer", "constructor", "view", "doc", "shiftPressed", "on", "evt", "data", "shiftKey", "isEnabled", "inputType", "env", "isSafari", "domEvent", "enterEventSpec", "event", "BubblingEventInfo", "targetRanges", "DomEventData", "stop", "called", "observe", "stopObserving", "Enter", "Plugin", "pluginName", "isOfficialPlugin", "init", "editing", "viewDocument", "t", "addObserver", "commands", "add", "listenTo", "isComposing", "preventDefault", "execute", "scrollToTheSelection", "priority", "accessibility", "addKeystrokeInfos", "keystrokes", "label", "keystroke", "ShiftEnterCommand", "softBreakAction", "rangeCount", "anchorPos", "anchor", "checkChild", "isInsideLimitElement", "insertBreak", "removeSelectionAttribute", "getAttributeKeys", "position", "breakLineElement", "createElement", "insertContent", "element", "is", "ShiftEnter", "conversion", "register", "allowWhere", "isInline", "for", "elementToElement", "modelElement", "createEmptyElement", "BlockQuoteCommand", "Command", "value", "_getValue", "isEnabled", "_checkEnabled", "options", "model", "editor", "schema", "selection", "document", "blocks", "Array", "from", "getSelectedBlocks", "forceValue", "undefined", "change", "writer", "_removeQuote", "filter", "findQuote", "blocksToQuote", "block", "checkCanBeQuoted", "_applyQuote", "firstBlock", "first", "getRangesOfBlockGroups", "reverse", "forEach", "groupRange", "start", "isAtStart", "end", "isAtEnd", "unwrap", "parent", "positionBefore", "createPositionBefore", "move", "split", "positionAfter", "createPositionAfter", "quotesToMerge", "quote", "createElement", "wrap", "push", "reduce", "currentQuote", "nextQuote", "nextSibling", "merge", "elementOrPosition", "name", "startPosition", "i", "ranges", "length", "nextBlock", "createRange", "isBQAllowed", "checkChild", "isBlockAllowedInBQ", "BlockQuoteEditing", "Plugin", "pluginName", "isOfficialPlugin", "requires", "Enter", "Delete", "commands", "add", "register", "inheritAllFrom", "conversion", "elementToElement", "view", "registerPostFixer", "changes", "differ", "getChanges", "entry", "type", "element", "position", "nodeAfter", "is", "isEmpty", "remove", "range", "createRangeIn", "child", "getItems", "viewDocument", "editing", "blockQuoteCommand", "get", "listenTo", "evt", "data", "isCollapsed", "positionParent", "getLastPosition", "execute", "scrollToTheSelection", "preventDefault", "stop", "context", "direction", "previousSibling", "BlockQuoteUI", "ui", "componentFactory", "buttonView", "_createButton", "ButtonView", "set", "tooltip", "MenuBarMenuListItemButtonView", "role", "ButtonClass", "locale", "command", "t", "label", "icon", "icons", "isToggleable", "bind", "to", "focus", "BlockQuote", "HighlightStack", "EmitterMixin", "_stack", "descriptor", "writer", "stack", "oldTop", "_insertDescriptor", "newTop", "compareDescriptors", "fire", "oldDescriptor", "newDescriptor", "id", "_removeDescriptor", "index", "findIndex", "item", "splice", "i", "shouldABeBeforeB", "a", "b", "priority", "classesToString", "classes", "Array", "isArray", "sort", "join", "WIDGET_CLASS_NAME", "WIDGET_SELECTED_CLASS_NAME", "isWidget", "node", "is", "getCustomProperty", "toWidget", "element", "options", "CKEditorError", "setAttribute", "addClass", "setCustomProperty", "getFillerOffset", "label", "setLabel", "hasSelectionHandle", "addSelectionHandle", "setHighlightHandling", "addHighlight", "toArray", "attributes", "key", "removeHighlight", "removeClass", "removeAttribute", "add", "remove", "on", "evt", "data", "addHighlightCallback", "removeHighlightCallback", "labelOrCreator", "widgetLabel", "push", "getLabel", "reduce", "prev", "current", "toWidgetEditable", "editable", "isReadOnly", "property", "findOptimalInsertionRange", "selection", "model", "selectedElement", "getSelectedElement", "typeAroundFakeCaretPosition", "getTypeAroundFakeCaretPosition", "createRange", "createPositionAt", "schema", "getFillerOffset", "addSelectionHandle", "widgetElement", "writer", "selectionHandle", "createUIElement", "class", "domDocument", "domElement", "toDomElement", "icon", "IconView", "set", "dragHandleIcon", "render", "appendChild", "element", "insert", "createPositionAt", "addClass", "calculateResizeHostAncestorWidth", "domResizeHost", "getElementComputedWidth", "width", "paddingLeft", "paddingRight", "ownerDocument", "defaultView", "getComputedStyle", "parseFloat", "domResizeHostParent", "parentElement", "parentWidth", "ancestorLevelLimit", "currentLevel", "checkedElement", "isNaN", "calculateResizeHostPercentageWidth", "resizeHostRect", "Rect", "TYPE_AROUND_SELECTION_ATTRIBUTE", "isTypeAroundWidget", "viewElement", "modelElement", "schema", "isWidget", "isInline", "getClosestTypeAroundDomButton", "closest", "getTypeAroundButtonPosition", "classList", "contains", "getClosestWidgetViewElement", "domConverter", "widgetDomElement", "mapDomToView", "getTypeAroundFakeCaretPosition", "selection", "getAttribute", "POSSIBLE_INSERTION_POSITIONS", "RETURN_ARROW_ICON_ELEMENT", "DOMParser", "parseFromString", "returnIcon", "firstChild", "PLUGIN_DISABLED_EDITING_ROOT_CLASS", "WidgetTypeAround", "Plugin", "_currentFakeCaretModelElement", "pluginName", "isOfficialPlugin", "requires", "Enter", "Delete", "editor", "editingView", "editing", "view", "on", "evt", "data", "isEnabled", "change", "root", "document", "roots", "removeClass", "model", "removeSelectionAttribute", "_enableTypeAroundUIInjection", "_enableInsertingParagraphsOnButtonClick", "_enableInsertingParagraphsOnEnterKeypress", "_enableInsertingParagraphsOnTypingKeystroke", "_enableTypeAroundFakeCaretActivationUsingKeyboardArrows", "_enableDeleteIntegration", "_enableInsertContentIntegration", "_enableInsertObjectIntegration", "_enableDeleteContentIntegration", "destroy", "widgetModelElement", "position", "attributesToCopy", "getAttributesWithProperty", "execute", "attributes", "focus", "scrollToTheSelection", "_listenToIfEnabled", "emitter", "event", "callback", "options", "listenTo", "args", "modelSelection", "typeAroundFakeCaretPosition", "selectedModelElement", "getSelectedElement", "_insertParagraph", "t", "locale", "buttonTitles", "before", "after", "downcastDispatcher", "conversionApi", "mapper", "toViewElement", "item", "injectUIIntoWidget", "widgetLabel", "getCustomProperty", "push", "priority", "domEventData", "_handleArrowKeyPress", "context", "directChange", "selectedViewElement", "map", "positionToWidgetCssClass", "ui", "focusTracker", "name", "isFocused", "keyCode", "isForward", "isForwardArrowKeyCode", "contentLanguageDirection", "toModelElement", "shouldStopAndPreventDefault", "_handleArrowKeyPressOnSelectedWidget", "isCollapsed", "_handleArrowKeyPressWhenSelectionNextToAWidget", "shiftKey", "_handleArrowKeyPressWhenNonCollapsedSelection", "preventDefault", "stop", "isLeavingWidget", "setSelectionAttribute", "widgetPlugin", "plugins", "get", "modelElementNextToSelection", "_getObjectElementNextToSelection", "viewElementNextToSelection", "_setSelectionOverElement", "selectedModelNode", "getLastPosition", "nodeBefore", "getFirstPosition", "nodeAfter", "selectedViewNode", "setSelection", "button", "domTarget", "buttonPosition", "widgetViewElement", "eventPhase", "wasHandled", "_insertParagraphAccordingToFakeCaretPosition", "isSoft", "viewDocument", "env", "isAndroid", "direction", "selectedModelWidget", "isFakeCaretBefore", "isDeleteForward", "shouldDeleteEntireWidget", "createSelection", "range", "getNearestSelectionRange", "probe", "start", "modifySelection", "isEqual", "deepestEmptyRangeAncestor", "getDeepestEmptyElementAncestor", "parent", "deleteContent", "doNotAutoparagraph", "documentSelection", "content", "selectable", "is", "selectedElement", "result", "insertContent", "findOptimalPosition", "viewWriter", "typeAroundWrapper", "wrapperDomElement", "injectButtons", "injectFakeCaret", "buttonTemplate", "Template", "tag", "title", "children", "importNode", "caretTemplate", "deepestEmptyAncestor", "ancestor", "getAncestors", "parentFirst", "childCount", "isLimit", "verticalNavigationHandler", "arrowUpPressed", "keyCodes", "arrowup", "arrowDownPressed", "arrowdown", "expandSelection", "selectionWillShrink", "findTextRangeFromSelection", "isSingleLineRange", "newPosition", "end", "newSelection", "anchor", "setFocus", "stopPropagation", "startPosition", "endPosition", "getNearestNonInlineLimit", "createRange", "lastRangePosition", "getNearestTextPosition", "firstRangePosition", "createRangeIn", "walkerValueType", "previousPosition", "type", "getWalker", "isBlock", "checkChild", "nextPosition", "modelRange", "isAtEnd", "viewRange", "toViewRange", "domRange", "viewRangeToDom", "rects", "getDomRangeRects", "boundaryVerticalPosition", "rect", "undefined", "Math", "round", "bottom", "top", "max", "isBackward", "Widget", "_previouslySelected", "Set", "consumable", "consume", "createRangeOn", "fake", "label", "getLabel", "_clearPreviouslySelectedWidgets", "viewSelection", "lastMarked", "getRanges", "value", "node", "isChild", "WIDGET_SELECTED_CLASS_NAME", "add", "addObserver", "MouseObserver", "_onMousedown", "_handleSelectionChangeOnArrowKeyPress", "_preventDefaultOnArrowKeyPress", "_handleDelete", "_selectFirstNestedEditable", "_selectAncestorWidget", "keystroke", "esc", "accessibility", "addKeystrokeInfoGroup", "id", "keystrokes", "eventInfo", "target", "domEvent", "detail", "_selectBlockContent", "editableOrWidgetElement", "findClosestEditableOrWidgetAncestor", "clickTargetFromPoint", "getElementFromMouseEvent", "findMappedViewAncestor", "findTextBlockAncestor", "nextTextBlock", "findNextTextBlock", "createPositionAfter", "objectElement", "getLocalizedArrowKeyCodeDirection", "isVerticalNavigation", "isObject", "newRange", "firstPosition", "lastPosition", "firstSelectedNode", "lastSelectedNode", "objectElementNextToSelection", "modelDocument", "canEditAt", "previousNode", "isEmpty", "nodeToRemove", "remove", "forward", "widget", "clear", "getFirstRange", "getItems", "positionParent", "positionParentElement", "findAncestor", "currentElement", "getRangeFromMouseEvent", "domRangeToView", "viewPosition", "viewNode", "isAtStart", "Array", "from", "includes", "includeSelf", "treeWalker", "TreeWalker", "WidgetToolbarRepository", "_toolbarDefinitions", "Map", "_balloon", "ContextualBalloon", "has", "balloonToolbar", "isWidgetSelected", "_updateToolbarsVisibility", "toolbarConfig", "values", "toolbarId", "ariaLabel", "items", "getRelatedElement", "balloonClassName", "length", "logWarning", "toolbarView", "ToolbarView", "CKEditorError", "toolbarDefinition", "itemsConfig", "initialized", "addToolbar", "isContextual", "beforeFocus", "relatedElement", "_showToolbar", "afterBlur", "_hideToolbar", "maxRelatedElementDepth", "deepestRelatedElement", "deepestToolbarDefinition", "definition", "_isToolbarInBalloon", "_isToolbarVisible", "relatedElementDepth", "stopListening", "repositionContextualBalloon", "fillFromConfig", "componentFactory", "getBalloonPositionData", "toolbar", "visibleView", "hasView", "balloon", "updatePosition", "defaultPositions", "BalloonPanelView", "mapViewToDom", "positions", "northArrowSouth", "northArrowSouthWest", "northArrowSouthEast", "southArrowNorth", "southArrowNorthWest", "southArrowNorthEast", "viewportStickyNorth", "ResizeState", "ObservableMixin", "constructor", "_options", "_referenceCoordinates", "originalWidth", "_originalWidth", "originalHeight", "_originalHeight", "originalWidthPercents", "_originalWidthPercents", "aspectRatio", "_aspectRatio", "domResizeHandle", "domHandleHost", "clientRect", "activeHandlePosition", "getHandlePosition", "getAbsoluteBoundaryPoint", "getOppositePosition", "height", "widthStyle", "style", "match", "update", "newSize", "proposedWidth", "proposedHeight", "proposedWidthPercents", "widthPercents", "proposedHandleHostWidth", "handleHostWidth", "proposedHandleHostHeight", "handleHostHeight", "resizerPosition", "elementRect", "positionParts", "split", "ret", "x", "right", "left", "y", "scrollX", "scrollY", "getResizerHandleClass", "domHandle", "resizerPositions", "parts", "replacements", "SizeView", "View", "bind", "bindTemplate", "setTemplate", "to", "display", "if", "visible", "text", "resizeState", "unit", "unbind", "_isVisible", "Resizer", "_viewResizerWrapper", "isSelected", "decorate", "state", "_cleanup", "_state", "that", "viewResizerWrapper", "_appendHandles", "_appendSizeUI", "isVisible", "hide", "show", "redraw", "begin", "_sizeView", "_bindToState", "_initialViewWidth", "getStyle", "_getHandleHost", "_getResizeHost", "updateSize", "_proposeNewSize", "newWidth", "setStyle", "domHandleHostRect", "domResizeHostRect", "newValue", "onCommit", "cancel", "handleHostRect", "domWrapper", "_domResizerWrapper", "existsInDom", "widgetWrapper", "handleHost", "resizerWrapper", "currentDimensions", "newDimensions", "isSameNode", "offsetWidth", "offsetHeight", "offsetLeft", "offsetTop", "compareArrays", "containsHandle", "isResizeHandle", "_dismiss", "currentCoordinates", "extractCoordinates", "isCentered", "enlargement", "endsWith", "abs", "dominant", "min", "getResizeHost", "getHandleHost", "currentPosition", "getResizerClass", "pageX", "pageY", "WidgetResize", "_resizers", "_observer", "_redrawSelectedResizerThrottled", "global", "window", "DomEmitterMixin", "_mouseDownListener", "_mouseMoveListener", "_mouseUpListener", "throttle", "redrawSelectedResizer", "resizer", "isAttached", "delete", "getResizerByViewElement", "select", "deselect", "selectedResizer", "attachTo", "attach", "widgetToolbarRepository", "forceDisabled", "clearForceDisabled", "_getResizerByHandle", "resizeHandle", "_activeResizer", "commit", "ClipboardObserver", "DomEventObserver", "constructor", "view", "domEventType", "viewDocument", "document", "listenTo", "handleInput", "priority", "type", "evt", "data", "preventDefault", "targetRanges", "dropRange", "eventInfo", "EventInfo", "fire", "dataTransfer", "method", "name", "target", "domEvent", "stop", "called", "stopPropagation", "onDomEvent", "nativeDataTransfer", "clipboardData", "cacheFiles", "evtData", "DataTransfer", "domRange", "getRangeFromMouseEvent", "domConverter", "domRangeToView", "plainTextToHtml", "text", "replace", "includes", "normalizeClipboardData", "fullMatch", "spaces", "length", "smallPaddingElements", "listElements", "viewToPlainText", "viewItem", "is", "hasAttribute", "getAttribute", "prev", "child", "getChildren", "newLinePadding", "element", "previous", "isEmpty", "getChild", "getCustomProperty", "ClipboardMarkersUtils", "Plugin", "_markersToCopy", "Map", "pluginName", "isOfficialPlugin", "markerName", "config", "set", "_copySelectedFragmentWithMarkers", "action", "selection", "getCopiedFragment", "writer", "model", "getSelectedContent", "editor", "change", "oldSelection", "setSelection", "sourceSelectionInsertedMarkers", "_insertFakeMarkersIntoSelection", "fragment", "fakeMarkersRangesInsideRange", "_removeFakeMarkersInsideElement", "elements", "Object", "entries", "createRangeIn", "remove", "markers", "clear", "range", "getPastedDocumentElement", "pasteMarkers", "_getPasteMarkersFromRangeMap", "sourceFragmentFakeMarkers", "_insertFakeMarkersElements", "transformedElement", "removedFakeMarkers", "values", "flat", "has", "addMarker", "usingOperation", "affectsData", "_pasteFragmentWithMarkers", "copyableMarker", "insertContent", "executor", "allowedActions", "copyPartiallySelected", "duplicateOnPaste", "before", "get", "delete", "_getMarkerClipboardConfig", "_hasMarkerConfiguration", "markerNamePrefix", "split", "copyableMarkers", "_getCopyableMarkersFromSelection", "selectionRanges", "Array", "from", "getRanges", "markersInRanges", "Set", "flatMap", "selectionRange", "getMarkersIntersectingRange", "isSelectionMarkerCopyable", "marker", "isCopyable", "_isMarkerCopyable", "markerRange", "getRange", "some", "containsRange", "filter", "map", "_getUniqueMarkerName", "copyMarkerConfig", "isInGraveyard", "root", "rootName", "mappedMarkers", "sortedMarkers", "start", "end", "position", "sort", "posA", "posB", "isBefore", "fakeMarker", "createElement", "push", "insert", "rootElement", "fakeMarkersElements", "_getAllFakeMarkersFromElement", "fakeMarkersRanges", "reduce", "acc", "markerElement", "createPositionBefore", "prevFakeMarker", "skipAssign", "mapValues", "Range", "createPositionFromPath", "createPositionAt", "foundFakeMarkers", "item", "prependFakeMarkers", "appendFakeMarkers", "hasMatchingStartMarker", "otherFakeMarker", "hasMatchingEndMarker", "unshift", "parts", "newId", "uid", "substring", "slice", "join", "ClipboardPipeline", "requires", "editing", "addObserver", "_setupPasteDrop", "_setupCopyCut", "clipboardMarkersUtils", "plugins", "enqueueChange", "isUndoable", "documentFragment", "content", "canEditAt", "contentData", "getData", "normalizeClipboardHtml", "htmlProcessor", "toView", "scrollToTheSelection", "dataController", "modelFragment", "toModel", "childCount", "resultRange", "modelDocument", "onCopyCut", "_fireOutputTransformationEvent", "setData", "toData", "deleteContent", "toPx", "toUnit", "LineView", "View", "bind", "bindTemplate", "isVisible", "left", "top", "width", "setTemplate", "tag", "attributes", "class", "if", "value", "style", "to", "DragDropTarget", "removeDropMarkerDelayed", "delay", "removeDropMarker", "_updateDropMarkerThrottled", "throttle", "targetRange", "_updateDropMarker", "_reconvertMarkerThrottled", "reconvertMarker", "_dropTargetLineView", "DomEmitterMixin", "_scrollables", "_setupDropMarker", "_domEmitter", "stopListening", "resizeObserver", "destroy", "cancel", "targetViewElement", "targetViewRanges", "clientX", "clientY", "blockMode", "draggedRange", "findDropTargetRange", "removeMarker", "ui", "body", "add", "conversion", "for", "markerToHighlight", "classes", "markerToElement", "schema", "checkChild", "_createDropTargetPosition", "isCollapsed", "_updateDropTargetLine", "isEqual", "updateMarker", "createUIElement", "domDocument", "domElement", "toDomElement", "append", "nodeBefore", "nodeAfter", "nodeParent", "parent", "viewElementBefore", "mapper", "toViewElement", "domElementBefore", "mapViewToDom", "viewElementAfter", "domElementAfter", "viewElementParent", "domElementParent", "domScrollableRect", "_getScrollableRect", "scrollX", "scrollY", "global", "window", "rectBefore", "Rect", "rectAfter", "rectParent", "excludeScrollbarsAndBorders", "above", "bottom", "below", "parentStyle", "getComputedStyle", "parseFloat", "paddingLeft", "right", "paddingRight", "leftClamped", "Math", "max", "rightClamped", "min", "viewElement", "domScrollable", "findScrollableElement", "usePassive", "ResizeObserver", "targetModelElement", "getClosestMappedModelElement", "modelElement", "targetViewPosition", "targetModelPosition", "toModelPosition", "canDropOnPosition", "getItems", "every", "createRange", "findDropTargetRangeForElement", "isInline", "isBlock", "childNodes", "node", "shouldIgnoreElement", "startIndex", "endIndex", "middleIndex", "floor", "side", "findElementSide", "float", "rect", "toModelElement", "viewPosition", "findMappedViewAncestor", "domNode", "parentElement", "overflow", "overflowY", "tagName", "DragDropBlockToolbar", "_isBlockDragging", "isReadOnly", "forceDisabled", "clearForceDisabled", "env", "isAndroid", "blockToolbar", "buttonView", "_handleBlockDragStart", "_handleBlockDragging", "_handleBlockDragEnd", "useCapture", "isEnabled", "setAttribute", "on", "blocks", "getSelectedBlocks", "createPositionAfter", "focus", "getObserver", "locale", "contentLanguageDirection", "elementFromPoint", "closest", "DragDrop", "_clearDraggableAttributesDelayed", "_clearDraggableAttributes", "_blockMode", "Widget", "_draggedRange", "_draggingUid", "_draggableElement", "MouseObserver", "_setupDragging", "_setupContentInsertionIntegration", "_setupClipboardInputIntegration", "_setupDraggableAttributeHandling", "_finalizeDragging", "detach", "_previewContainer", "dragDropTarget", "_prepareDraggedRange", "effectAllowed", "draggedSelection", "createSelection", "toRange", "clipboardPipeline", "domTarget", "_updatePreview", "isCanceled", "dropEffect", "updateDropMarker", "isGecko", "getFinalDropRange", "isMove", "getFinalDropEffect", "toViewRange", "ranges", "viewRange", "toModelRange", "isSuccess", "draggableElement", "findDraggableWidget", "isBlink", "selectedElement", "getSelectedElement", "isWidget", "editableElement", "removeAttribute", "moved", "widgetToolbarRepository", "undefined", "doNotAutoparagraph", "selectionParent", "getFirstPosition", "insertElement", "draggableWidget", "LiveRange", "fromRange", "createRangeOn", "getFirstRange", "blockRange", "getRangeIncludingFullySelectedParents", "touchesBlockEdges", "isTouching", "editable", "domEditable", "computedStyle", "appendChild", "firstElementChild", "removeChild", "domRect", "contains", "domEditablePaddingLeft", "preview", "className", "isiOS", "backgroundColor", "setContentOf", "setDragImage", "hasClass", "findAncestor", "ancestor", "firstElement", "lastElement", "getCommonAncestor", "startPosition", "endPosition", "isLimit", "parentRange", "touchesStart", "touchesEnd", "PastePlainText", "isUnformattedInlineContent", "textAttributes", "getAttributes", "key", "getAttributeProperties", "isFormatting", "attribute", "checkAttribute", "isObject", "attributeKeys", "getAttributeKeys", "find", "Clipboard", "t", "accessibility", "addKeystrokeInfos", "keystrokes", "label", "keystroke", "ClassicEditorUI", "EditorUI", "constructor", "editor", "view", "_toolbarConfig", "normalizeToolbarConfig", "config", "get", "_elementReplacer", "ElementReplacer", "listenTo", "editing", "_handleScrollToTheSelectionWithStickyPanel", "bind", "element", "init", "replacementElement", "editingView", "editable", "editingRoot", "document", "getRoot", "name", "rootName", "render", "editableElement", "setEditableElement", "to", "focusTracker", "attachDomRoot", "replace", "_initPlaceholder", "_initToolbar", "menuBarView", "_initMenuBar", "_initDialogPluginIntegration", "_initContextualBalloonIntegration", "fire", "destroy", "restore", "getDomRoot", "detachDomRoot", "stickyPanel", "limiterElement", "top", "toolbar", "fillFromConfig", "componentFactory", "addToolbar", "sourceElement", "placeholderText", "placeholder", "tagName", "toLowerCase", "getAttribute", "enablePlaceholder", "isDirectHost", "keepOnFocus", "plugins", "has", "contextualBalloon", "on", "evt", "position", "return", "isSticky", "stickyPanelHeight", "Rect", "height", "target", "limiter", "viewportOffsetConfig", "newTopViewportOffset", "priority", "updateBalloonPosition", "visibleView", "updatePosition", "ui", "data", "originalArgs", "viewportOffset", "scrollViewportOnPanelGettingSticky", "scrollToTheSelection", "setTimeout", "stopListening", "dialogPlugin", "dialogView", "wasMoved", "stickyPanelContentRect", "contentPanelElement", "bottom", "DialogView", "defaultOffset", "ClassicEditorUIView", "BoxedEditorUIView", "locale", "options", "StickyPanelView", "ToolbarView", "shouldGroupWhenFull", "shouldToolbarGroupWhenFull", "useMenuBar", "MenuBarView", "InlineEditableUIView", "undefined", "label", "content", "addMany", "add", "main", "ClassicEditor", "ElementApiMixin", "Editor", "sourceElementOrData", "isElement", "initialData", "CKEditorError", "define", "set", "getInitialData", "model", "createRoot", "menuBarConfig", "isVisible", "attachToForm", "updateSourceElement", "create", "Promise", "resolve", "initPlugins", "then", "getDataFromElement", "value", "_isElement", "SelectAllCommand", "Command", "constructor", "editor", "affectsData", "model", "selection", "document", "scopeElement", "schema", "getLimitElement", "containsEntireContent", "isSelectAllScope", "parent", "change", "writer", "setSelection", "element", "isLimit", "checkChild", "SELECT_ALL_KEYSTROKE", "parseKeystroke", "SelectAllEditing", "Plugin", "pluginName", "isOfficialPlugin", "t", "view", "editing", "viewDocument", "commands", "add", "listenTo", "eventInfo", "domEventData", "getCode", "execute", "preventDefault", "accessibility", "addKeystrokeInfos", "keystrokes", "label", "keystroke", "SelectAllUI", "ui", "componentFactory", "buttonView", "_createButton", "ButtonView", "set", "tooltip", "MenuBarMenuListItemButtonView", "ButtonClass", "locale", "command", "get", "icon", "selectAllIcon", "bind", "to", "focus", "SelectAll", "requires", "BaseCommand", "Command", "constructor", "editor", "_stack", "_createdBatches", "WeakSet", "refresh", "_isEnabledBasedOnSelection", "listenTo", "data", "evt", "options", "batchType", "isUndoable", "priority", "clearStack", "isEnabled", "length", "createdBatches", "addBatch", "batch", "docSelection", "model", "document", "selection", "ranges", "hasOwnRange", "Array", "from", "getRanges", "isBackward", "push", "operations", "selectionRanges", "transformedRangeGroups", "map", "range", "getTransformedByOperations", "allRanges", "flat", "rangeGroup", "transformed", "filter", "root", "graveyard", "isRangeContainedByAnyOtherRange", "normalizeRanges", "change", "writer", "setSelection", "backward", "batchToUndo", "undoingBatch", "add", "operationsToUndo", "slice", "operation", "isDocumentOperation", "reverse", "operationToUndo", "nextBaseVersion", "baseVersion", "historyOperations", "history", "getOperations", "transformedSets", "transformSets", "getReversed", "useRelations", "padWithNoOps", "forceWeakRemove", "reversedOperations", "operationsA", "affectedSelectable", "canEditAt", "NoOperation", "addOperation", "applyOperation", "setOperationAsUndone", "sort", "a", "b", "start", "isBefore", "i", "previousRange", "joinedRange", "getJoined", "splice", "some", "otherRange", "containsRange", "UndoCommand", "batchIndex", "findIndex", "item", "createBatch", "isUndo", "enqueueChange", "_undo", "_restoreSelection", "fire", "RedoCommand", "pop", "redoingBatch", "lastOperation", "UndoEditing", "Plugin", "_batchRegistry", "pluginName", "isOfficialPlugin", "t", "_undoCommand", "_redoCommand", "commands", "args", "isRedoBatch", "has", "isUndoBatch", "wasProcessed", "undoneBatch", "keystrokes", "set", "accessibility", "addKeystrokeInfos", "label", "keystroke", "UndoUI", "locale", "localizedUndoIcon", "uiLanguageDirection", "icons", "undo", "redo", "localizedRedoIcon", "_addButtonsToFactory", "name", "Icon", "ui", "componentFactory", "buttonView", "_createButton", "ButtonView", "tooltip", "MenuBarMenuListItemButtonView", "ButtonClass", "command", "get", "view", "icon", "bind", "to", "execute", "editing", "focus", "Undo", "requires", "Essentials", "Plugin", "requires", "AccessibilityHelp", "Clipboard", "Enter", "SelectAll", "ShiftEnter", "Typing", "Undo", "pluginName", "isOfficialPlugin", "ParagraphCommand", "Command", "editor", "_isEnabledBasedOnSelection", "model", "document", "block", "first", "selection", "getSelectedBlocks", "value", "is", "isEnabled", "checkCanBecomeParagraph", "schema", "options", "canEditAt", "change", "writer", "blocks", "rename", "checkChild", "parent", "isObject", "InsertParagraphCommand", "execute", "attributes", "position", "_findPositionToInsertParagraph", "paragraph", "createElement", "setAllowedAttributes", "insertContent", "setSelection", "allowedParent", "findAllowedParent", "positionParent", "isTextAllowed", "isEmpty", "isAtEnd", "createPositionAfter", "isAtStart", "createPositionBefore", "split", "Paragraph", "Plugin", "pluginName", "isOfficialPlugin", "commands", "add", "register", "inheritAllFrom", "conversion", "elementToElement", "view", "for", "viewElement", "paragraphLikeElements", "has", "name", "converterPriority", "Set", "ParagraphButtonUI", "requires", "t", "ui", "componentFactory", "locale", "ButtonView", "command", "get", "label", "icon", "icons", "tooltip", "isToggleable", "bind", "to", "on", "HeadingCommand", "Command", "constructor", "editor", "modelElements", "block", "first", "model", "document", "selection", "getSelectedBlocks", "value", "includes", "name", "isEnabled", "some", "heading", "checkCanBecomeHeading", "schema", "execute", "options", "modelElement", "change", "writer", "blocks", "Array", "from", "filter", "is", "rename", "checkChild", "parent", "isObject", "defaultModelElement", "HeadingEditing", "Plugin", "pluginName", "isOfficialPlugin", "config", "define", "title", "class", "view", "requires", "Paragraph", "get", "option", "register", "inheritAllFrom", "conversion", "elementToElement", "push", "_addDefaultH1Conversion", "commands", "add", "enterCommand", "listenTo", "evt", "data", "positionParent", "getFirstPosition", "isHeading", "childCount", "for", "converterPriority", "priorities", "low", "getLocalizedOptions", "t", "localizedTitles", "map", "HeadingUI", "defaultTitle", "accessibleLabel", "ui", "componentFactory", "locale", "titles", "itemDefinitions", "Collection", "headingCommand", "paragraphCommand", "def", "type", "ViewModel", "label", "role", "withText", "bind", "to", "set", "commandName", "commandValue", "dropdownView", "createDropdown", "addListToDropdown", "ariaLabel", "buttonView", "ariaLabelledBy", "undefined", "isOn", "tooltip", "extendTemplate", "attributes", "toMany", "areEnabled", "paragraph", "whichModel", "source", "editing", "focus", "menuView", "MenuBarMenuView", "listView", "MenuBarMenuListView", "panelView", "children", "listItemView", "MenuBarMenuListItemView", "MenuBarMenuListItemButtonView", "items", "isToggleable", "delegate", "on", "Heading", "defaultIcons", "heading1", "icons", "heading2", "heading3", "heading4", "heading5", "heading6", "HeadingButtonsUI", "item", "_createButton", "ButtonView", "command", "icon", "createInlineImageViewElement", "writer", "createContainerElement", "class", "createEmptyElement", "createBlockImageViewElement", "createSlot", "getImgViewElementMatcher", "editor", "matchImageType", "imageUtils", "plugins", "get", "areBothImagePluginsLoaded", "has", "element", "isInlineImageView", "getPositiveMatchPattern", "imageType", "getStyle", "findAncestor", "isBlockImageView", "pattern", "name", "hasAttribute", "attributes", "determineImageTypeForInsertionAtSelection", "schema", "selection", "firstBlock", "first", "getSelectedBlocks", "isObject", "isEmpty", "getSizeValueIfInPx", "size", "endsWith", "parseInt", "widthAndHeightStylesAreBothSet", "viewElement", "widthStyle", "heightStyle", "IMAGE_WIDGETS_CLASSES_MATCH_REGEXP", "ImageUtils", "Plugin", "DomEmitterMixin", "pluginName", "isOfficialPlugin", "isImage", "modelElement", "isInlineImage", "isBlockImage", "is", "hasClass", "selectable", "options", "model", "document", "determinedImageType", "determineImageTypeForInsertion", "Object", "fromEntries", "getAttributes", "attributeName", "checkAttribute", "change", "setImageSizes", "imageElement", "createElement", "insertObject", "setSelection", "findOptimalPosition", "undefined", "parent", "setImageNaturalSizeAttributes", "src", "getAttribute", "img", "global", "window", "Image", "_domEmitter", "listenTo", "enqueueChange", "batch", "setAttribute", "naturalWidth", "naturalHeight", "stopListening", "getClosestSelectedImageWidget", "selectionPosition", "getFirstPosition", "getSelectedElement", "isImageWidget", "getClosestSelectedImageElement", "selectedElement", "getImageWidgetFromImageView", "imageView", "classes", "isImageAllowedInParent", "isNotInsideImage", "label", "setCustomProperty", "labelCreator", "imgElement", "findViewImgElement", "altText", "toWidget", "getCustomProperty", "isWidget", "figureView", "editingView", "editing", "view", "item", "createRangeIn", "destroy", "getInsertImageParent", "checkChild", "focus", "getAncestors", "every", "ancestor", "insertionRange", "findOptimalInsertionRange", "start", "configImageInsertType", "config", "IMAGE_URL_REGEXP", "RegExp", "String", "source", "ImageTextAlternativeCommand", "Command", "editor", "imageUtils", "plugins", "get", "element", "getClosestSelectedImageElement", "model", "document", "selection", "isEnabled", "hasAttribute", "value", "getAttribute", "execute", "options", "imageElement", "change", "writer", "setAttribute", "newValue", "ImageTextAlternativeEditing", "Plugin", "requires", "ImageUtils", "pluginName", "isOfficialPlugin", "commands", "add", "TextAlternativeFormView", "View", "constructor", "locale", "t", "focusTracker", "FocusTracker", "keystrokes", "KeystrokeHandler", "labeledInput", "_createLabeledInputView", "saveButtonView", "_createButton", "icons", "check", "type", "cancelButtonView", "cancel", "_focusables", "ViewCollection", "_focusCycler", "FocusCycler", "focusables", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "setTemplate", "tag", "attributes", "class", "tabindex", "children", "render", "listenTo", "submitHandler", "view", "forEach", "v", "destroy", "label", "icon", "className", "eventName", "button", "ButtonView", "set", "tooltip", "extendTemplate", "delegate", "to", "LabeledFieldView", "createLabeledInputText", "repositionContextualBalloon", "balloon", "getClosestSelectedImageWidget", "editing", "position", "getBalloonPositionData", "updatePosition", "editingView", "defaultPositions", "BalloonPanelView", "target", "domConverter", "mapViewToDom", "positions", "northArrowSouth", "northArrowSouthWest", "northArrowSouthEast", "southArrowNorth", "southArrowNorthWest", "southArrowNorthEast", "viewportStickyNorth", "ImageTextAlternativeUI", "ContextualBalloon", "_form", "ui", "componentFactory", "command", "textAlternative", "bind", "_showForm", "viewDocument", "_balloon", "CssTransitionDisablerMixin", "fieldView", "_hideForm", "data", "_isVisible", "clickOutsideHandler", "emitter", "activator", "contextElements", "callback", "_createForm", "disableCssTransitions", "_isInBalloon", "select", "enableCssTransitions", "focusEditable", "isFocused", "focus", "remove", "visibleView", "hasView", "ImageTextAlternative", "upcastImageFigure", "converter", "evt", "conversionApi", "consumable", "test", "viewItem", "name", "classes", "viewImage", "findViewImgElement", "consume", "conversionResult", "convertItem", "modelCursor", "modelImage", "first", "modelRange", "getItems", "revert", "convertChildren", "updateConversionResult", "dispatcher", "on", "downcastSrcsetAttribute", "imageUtils", "imageType", "converter", "evt", "data", "conversionApi", "consumable", "consume", "item", "name", "writer", "element", "mapper", "toViewElement", "img", "findViewImgElement", "attributeNewValue", "removeAttribute", "setAttribute", "dispatcher", "on", "downcastImageAttribute", "imageUtils", "imageType", "attributeKey", "converter", "evt", "data", "conversionApi", "consumable", "consume", "item", "name", "viewWriter", "writer", "element", "mapper", "toViewElement", "img", "findViewImgElement", "setAttribute", "attributeNewValue", "dispatcher", "on", "ImageLoadObserver", "Observer", "observe", "domRoot", "listenTo", "event", "domEvent", "domElement", "target", "checkShouldIgnoreEventFromTarget", "tagName", "_fireEvents", "useCapture", "stopObserving", "stopListening", "isEnabled", "document", "fire", "InsertImageCommand", "Command", "constructor", "editor", "configImageInsertType", "config", "get", "plugins", "has", "logWarning", "isImageAllowed", "execute", "options", "sourceDefinitions", "toArray", "source", "selection", "model", "selectionAttributes", "Object", "fromEntries", "getAttributes", "forEach", "sourceDefinition", "index", "selectedElement", "getSelectedElement", "src", "isImage", "position", "createPositionAfter", "insertImage", "ReplaceImageSourceCommand", "decorate", "value", "getAttribute", "image", "change", "cleanupImage", "setImageNaturalSizeAttributes", "removeAttribute", "ImageEditing", "Plugin", "requires", "ImageUtils", "pluginName", "isOfficialPlugin", "conversion", "editing", "view", "addObserver", "for", "attributeToAttribute", "key", "insertImageCommand", "replaceImageSourceCommand", "commands", "add", "ImageSizeAttributes", "_registerSchema", "_registerConverters", "schema", "extend", "allowAttributes", "viewElementName", "styles", "width", "viewElement", "widthAndHeightStylesAreBothSet", "getSizeValueIfInPx", "getStyle", "height", "attachDowncastConverter", "modelAttributeName", "viewAttributeName", "setRatioForInlineImage", "hasAttribute", "isResized", "setStyle", "ImageTypeCommand", "modelElementName", "_modelElementName", "getClosestSelectedImageElement", "isInlineImage", "isBlockImage", "oldElement", "attributes", "uploadId", "setImageSizes", "markers", "Array", "from", "filter", "marker", "getRange", "containsItem", "newElement", "createSelection", "newElementRange", "createRangeOn", "markerRange", "range", "root", "rootName", "getJoined", "updateMarker", "ImagePlaceholder", "_setupSchema", "_setupConversion", "_setupLoadListener", "isRegistered", "test", "is", "addClass", "setCustomProperty", "removeClass", "removeStyle", "editingView", "imgViewElement", "domConverter", "mapDomToView", "getImageWidgetFromImageView", "modelElement", "toModelElement", "enqueueChange", "isUndoable", "ImageBlockEditing", "ClipboardPipeline", "register", "inheritAllFrom", "_setupClipboardIntegration", "t", "elementToStructure", "createBlockImageViewElement", "toImageWidget", "downcastSrcsetAttribute", "elementToElement", "getImgViewElementMatcher", "viewImage", "createElement", "undefined", "upcastImageFigure", "clipboardPipeline", "docFragmentChildren", "content", "getChildren", "modelRange", "every", "isInlineImageView", "targetRanges", "toModelRange", "getFirstRange", "determineImageTypeForInsertionAtSelection", "UpcastWriter", "blockViewImages", "map", "inlineViewImage", "class", "createDocumentFragment", "method", "createRangeIn", "getItems", "ImageInsertFormView", "View", "locale", "integrations", "focusTracker", "FocusTracker", "keystrokes", "KeystrokeHandler", "_focusables", "ViewCollection", "children", "createCollection", "_focusCycler", "FocusCycler", "focusables", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "CollapsibleView", "addMany", "setTemplate", "tag", "tabindex", "render", "submitHandler", "stopPropagation", "set", "destroy", "focusFirst", "ImageInsertUI", "_integrations", "Map", "define", "isImageSelected", "componentCreator", "_createToolbarComponent", "menuBarComponentCreator", "_createMenuBarComponent", "ui", "componentFactory", "observable", "buttonViewCreator", "formViewCreator", "menuBarButtonViewCreator", "requiresForm", "_prepareIntegrations", "length", "dropdownButton", "firstIntegration", "actionButton", "SplitButtonView", "tooltip", "bind", "to", "dropdownView", "createDropdown", "observables", "toMany", "some", "once", "integrationViews", "imageInsertFormView", "panelView", "resultView", "MenuBarMenuView", "listView", "MenuBarMenuListView", "buttonView", "icon", "icons", "label", "integration", "listItemView", "MenuBarMenuListItemView", "items", "result", "includes", "push", "ImageBlock", "Widget", "ImageTextAlternative", "ImageInlineEditing", "disallowIn", "createEmptyElement", "createInlineImageViewElement", "isBlockImageView", "inlineViewImages", "blockViewImage", "childCount", "attribute", "getChild", "ImageInline", "Image", "ImageCaptionUtils", "getCaptionFromImageModelElement", "imageModelElement", "node", "getCaptionFromModelSelection", "captionElement", "getFirstPosition", "findAncestor", "parent", "matchImageCaptionViewElement", "ToggleImageCaptionCommand", "imageCaptionUtils", "ancestorCaptionElement", "focusCaptionOnShow", "_hideImageCaption", "_showImageCaption", "imageCaptionEditing", "selectedImage", "savedCaption", "_getSavedCaption", "newCaptionElement", "append", "setSelection", "_saveCaption", "remove", "ImageCaptionEditing", "_savedCaptionsMap", "WeakMap", "allowIn", "allowContentOf", "isLimit", "_setupImageTypeCommandsIntegration", "_registerCaptionReconversion", "createContainerElement", "figcaptionElement", "createEditableElement", "placeholder", "enablePlaceholder", "keepOnFocus", "imageAlt", "toWidgetEditable", "imageTypeInlineCommand", "imageTypeBlockCommand", "handleImageTypeChange", "return", "oldCaptionElement", "savedOldElementCaption", "priority", "jsonObject", "Element", "fromJSON", "caption", "toJSON", "changes", "differ", "getChanges", "start", "nodeAfter", "reconvertItem", "ImageCaptionUI", "command", "ButtonView", "isToggleable", "modelCaptionElement", "scrollToTheSelection", "focus", "ImageCaption", "createImageTypeRegExp", "types", "regExpSafeNames", "type", "replace", "RegExp", "join", "fetchLocalImage", "Promise", "resolve", "reject", "imageSrc", "fetch", "then", "resource", "blob", "mimeType", "getImageMimeType", "ext", "filename", "file", "File", "catch", "err", "convertLocalImageOnCanvas", "isLocalImage", "match", "toLowerCase", "getBlobFromCanvas", "global", "addEventListener", "canvas", "ctx", "getContext", "drawImage", "toBlob", "ImageUploadUI", "_createToolbarButton", "_createMenuBarButton", "registerIntegration", "_createDropdownButton", "isOnly", "_createButton", "ButtonClass", "imageTypes", "imageTypesRegExp", "acceptedType", "allowMultipleFiles", "imageUpload", "files", "imagesToUpload", "imageInsertUI", "uploadImageCommand", "button", "FileDialogButtonView", "isAccessAllowed", "withText", "isOpen", "MenuBarMenuListItemFileDialogButtonView", "ImageUploadProgress", "modelImage", "fileRepository", "FileRepository", "status", "viewFigure", "_startAppearEffect", "_showPlaceholder", "loader", "loaders", "_hidePlaceholder", "_showProgressBar", "_displayLocalImage", "_showCompleteIcon", "_hideProgressBar", "_stopAppearEffect", "downcastDispatcher", "uploadStatusChange", "hasClass", "viewImg", "_getUIElement", "insert", "_createPlaceholder", "_removeUIElement", "progressBar", "_createProgressBar", "createPositionAt", "completeIcon", "createUIElement", "setTimeout", "imageFigure", "uniqueProperty", "child", "getCustomProperty", "UploadImageCommand", "_uploadImage", "createLoader", "id", "ImageUploadEditing", "upload", "_uploadImageElements", "Notification", "doc", "isHtmlIncluded", "dataTransfer", "images", "stop", "viewRange", "notification", "showWarning", "namespace", "fetchableImages", "promise", "imageElement", "fetchableImage", "preventDefault", "includeChangesInGraveyard", "reverse", "insertedImagesIds", "Set", "entry", "isInsertedInGraveyard", "getImagesFromChangeItem", "abort", "_readAndUpload", "urls", "default", "_parseAndSetSrcsetAttributeOnImage", "imageUploadElements", "read", "env", "isSafari", "domFigure", "mapViewToDom", "originalDisplay", "style", "display", "_ckHack", "offsetHeight", "ariaLiveAnnouncer", "announce", "clean", "error", "title", "delete", "destroyLoader", "maxWidth", "srcsetAttribute", "keys", "parseInt", "isNaN", "Math", "max", "srcset", "setAttributes", "getData", "ImageUpload", "ResizeImageCommand", "Command", "editor", "imageUtils", "plugins", "get", "element", "getClosestSelectedImageElement", "model", "document", "selection", "isEnabled", "hasAttribute", "value", "width", "getAttribute", "height", "execute", "options", "imageElement", "change", "writer", "setAttribute", "removeAttribute", "setImageNaturalSizeAttributes", "ImageResizeEditing", "Plugin", "requires", "ImageUtils", "pluginName", "isOfficialPlugin", "constructor", "config", "define", "resizeUnit", "resizeOptions", "name", "icon", "resizeImageCommand", "_registerConverters", "commands", "add", "_registerSchema", "has", "schema", "extend", "allowAttributes", "imageType", "conversion", "for", "dispatcher", "on", "evt", "data", "conversionApi", "consumable", "consume", "item", "viewWriter", "viewImg", "mapper", "toViewElement", "attributeNewValue", "setStyle", "addClass", "removeStyle", "removeClass", "attributeToAttribute", "key", "view", "modelAttributeValue", "target", "findViewImgElement", "styles", "viewElement", "widthAndHeightStylesAreBothSet", "getStyle", "RESIZE_ICONS", "small", "icons", "objectSizeSmall", "medium", "objectSizeMedium", "large", "objectSizeLarge", "custom", "objectSizeCustom", "original", "objectSizeFull", "ImageResizeButtons", "_resizeUnit", "command", "bind", "to", "option", "_registerImageResizeButton", "_registerImageResizeDropdown", "ui", "componentFactory", "locale", "button", "ButtonView", "labelText", "_getOptionLabelValue", "CKEditorError", "set", "label", "tooltip", "isToggleable", "isCustomImageResizeOption", "customResizeUI", "listenTo", "_showForm", "optionValueWithUnit", "getIsOnButtonCallback", "t", "originalSizeOption", "find", "componentCreator", "dropdownView", "createDropdown", "DropdownButtonView", "dropdownButton", "buttonView", "accessibleLabel", "commandValue", "withText", "class", "ariaLabel", "ariaLabelledBy", "undefined", "addListToDropdown", "_getResizeDropdownListItemDefinitions", "role", "source", "onClick", "commandName", "editing", "focus", "forTooltip", "itemDefinitions", "Collection", "optionsWithSerializedValues", "map", "valueWithUnits", "definition", "type", "ViewModel", "allDropdownValues", "getIsOnCustomButtonCallback", "objectCommandValue", "some", "dropdownValue", "RESIZABLE_IMAGES_CSS_SELECTOR", "RESIZED_IMAGE_CLASS", "ImageResizeHandles", "WidgetResize", "_setupResizerCreator", "editingView", "addObserver", "ImageLoadObserver", "domEvent", "matches", "domConverter", "imageView", "domToView", "widgetView", "getImageWidgetFromImageView", "resizer", "getResizerByViewElement", "redraw", "imageModel", "toModelElement", "attachTo", "unit", "modelElement", "getHandleHost", "domWidgetElement", "querySelector", "getResizeHost", "mapViewToDom", "isCentered", "imageStyle", "onCommit", "newValue", "hasClass", "tryParseDimensionWithUnit", "dimension", "rawValue", "trim", "match", "parsedValue", "Number", "parseFloat", "isNaN", "tryCastDimensionsToUnit", "parentDimensionPx", "targetUnit", "getSelectedImageEditorNodes", "imageModelElement", "imageViewElement", "imageDOMElement", "dom", "getSelectedImageWidthInUnits", "imageNodes", "parsedResizedWidth", "imageParentWidthPx", "calculateResizeHostAncestorWidth", "imageHolderDimension", "Rect", "ImageCustomResizeFormView", "View", "validators", "focusTracker", "FocusTracker", "keystrokes", "KeystrokeHandler", "labeledInput", "_createLabeledInputView", "saveButtonView", "_createButton", "check", "cancelButtonView", "cancel", "_focusables", "ViewCollection", "_validators", "_focusCycler", "FocusCycler", "focusables", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "setTemplate", "tag", "attributes", "tabindex", "children", "render", "submitHandler", "forEach", "v", "destroy", "className", "eventName", "extendTemplate", "delegate", "LabeledFieldView", "createLabeledInputNumber", "fieldView", "step", "resetFormStatus", "validator", "errorText", "rawSize", "parsedSize", "parsed", "sizeWithUnits", "getSelectedImagePossibleResizeRange", "minimumImageWidth", "window", "getComputedStyle", "minWidth", "lower", "Math", "max", "upper", "ImageCustomResizeUI", "ContextualBalloon", "_form", "_createForm", "_balloon", "CssTransitionDisablerMixin", "getFormValidators", "isValid", "_hideForm", "update", "clickOutsideHandler", "emitter", "activator", "_isVisible", "contextElements", "callback", "disableCssTransitions", "_isInBalloon", "position", "getBalloonPositionData", "currentParsedWidth", "initialInputValue", "toFixed", "possibleRange", "Object", "assign", "min", "ceil", "select", "enableCssTransitions", "focusEditable", "isFocused", "remove", "visibleView", "hasView", "form", "ImageResize", "ImageStyleCommand", "_defaultStyles", "imageBlock", "imageInline", "_styles", "Map", "style", "isDefault", "modelElementName", "modelElements", "requestedStyle", "setImageSizes", "shouldConvertImageType", "isBlockImage", "supportedTypes", "includes", "DEFAULT_OPTIONS", "inline", "title", "objectInline", "alignLeft", "objectLeft", "alignBlockLeft", "objectBlockLeft", "alignCenter", "objectCenter", "alignRight", "objectRight", "alignBlockRight", "objectBlockRight", "block", "side", "DEFAULT_ICONS", "full", "objectFullWidth", "left", "right", "center", "inlineLeft", "inlineRight", "DEFAULT_DROPDOWN_DEFINITIONS", "defaultItem", "items", "normalizeStyles", "configuredStyles", "arrangement", "normalizeDefinition", "filter", "isValidOption", "getDefaultStylesConfiguration", "isBlockPluginLoaded", "isInlinePluginLoaded", "getDefaultDropdownDefinitions", "pluginCollection", "extendStyle", "length", "warnInvalidStyle", "supportedElements", "elementName", "logWarning", "missingPlugins", "extendedStyle", "prop", "prototype", "hasOwnProperty", "call", "info", "modelToViewStyleAttribute", "newStyle", "getStyleDefinitionByName", "oldStyle", "attributeOldValue", "viewToModelStyleAttribute", "nonDefaultStyles", "modelRange", "viewItem", "modelImageElement", "first", "getItems", "checkAttribute", "classes", "ImageStyleEditing", "utils", "normalizedStyles", "_setupConversion", "_setupPostFixer", "modelToViewConverter", "viewToModelConverter", "downcastDispatcher", "upcastDispatcher", "priority", "stylesMap", "registerPostFixer", "changed", "differ", "getChanges", "attributeKey", "nodeAfter", "range", "start", "is", "childCount", "getChild", "isImage", "imageStyleDefinition", "ImageStyleUI", "localizedDefaultStylesTitles", "toolbarConfig", "imageStyleEditing", "definedStyles", "translateStyles", "styleConfig", "definedDropdowns", "isObject", "dropdownConfig", "_createDropdown", "factory", "defaultButton", "buttonViews", "itemName", "getUIComponentName", "buttonName", "create", "dropdown", "SplitButtonView", "splitButtonView", "splitButtonViewArrow", "arrowView", "addToolbarToDropdown", "enableActiveItemFocusOnDropdownOpen", "getDropdownButtonTitle", "unbind", "toMany", "areOn", "index", "findIndex", "identity", "isOn", "fire", "isOpen", "areEnabled", "buttonConfig", "_executeCommand", "titles", "dropdownTitle", "buttonTitle", "ImageStyle", "ImageToolbar", "WidgetToolbarRepository", "widgetToolbarRepository", "register", "normalizeDeclarativeConfig", "getRelatedElement", "getClosestSelectedImageWidget", "IndentEditing", "Plugin", "pluginName", "isOfficialPlugin", "editor", "commands", "add", "MultiCommand", "IndentUI", "locale", "t", "localizedIndentIcon", "uiLanguageDirection", "icons", "indent", "outdent", "localizedOutdentIcon", "_defineButton", "commandName", "label", "icon", "ui", "componentFactory", "buttonView", "_createButton", "ButtonView", "set", "tooltip", "MenuBarMenuListItemButtonView", "ButtonClass", "command", "get", "view", "bind", "to", "listenTo", "execute", "editing", "focus", "Indent", "requires", "AutomaticDecorators", "_definitions", "Set", "length", "size", "add", "item", "Array", "isArray", "forEach", "dispatcher", "on", "evt", "data", "conversionApi", "consumable", "test", "is", "schema", "isInline", "viewWriter", "writer", "viewSelection", "document", "selection", "viewElement", "createAttributeElement", "attributes", "priority", "classes", "addClass", "key", "styles", "setStyle", "setCustomProperty", "callback", "attributeNewValue", "wrap", "getFirstRange", "mapper", "toViewRange", "range", "unwrap", "viewFigure", "toViewElement", "linkInImage", "from", "getChildren", "find", "child", "toMap", "val", "setAttribute", "removeClass", "removeAttribute", "removeStyle", "ATTRIBUTE_WHITESPACES", "SAFE_URL_TEMPLATE", "EMAIL_REG_EXP", "PROTOCOL_REG_EXP", "DEFAULT_LINK_PROTOCOLS", "LINK_KEYSTROKE", "isLinkElement", "node", "getCustomProperty", "createLinkElement", "href", "linkElement", "ensureSafeUrl", "url", "allowedProtocols", "urlString", "String", "protocolsList", "join", "customSafeRegex", "RegExp", "replace", "isSafeUrl", "customRegexp", "normalizedUrl", "match", "getLocalizedDecorators", "t", "decorators", "localizedDecoratorsLabels", "decorator", "label", "normalizeDecorators", "retArray", "value", "Object", "entries", "assign", "id", "upperFirst", "push", "isLinkableElement", "element", "checkAttribute", "name", "isEmail", "addLinkProtocolIfApplicable", "link", "defaultProtocol", "protocol", "isProtocolNeeded", "linkHasProtocol", "openLink", "window", "open", "LinkCommand", "Command", "manualDecorators", "Collection", "automaticDecorators", "manualDecorator", "_getDecoratorStateFromModel", "model", "editor", "selectedElement", "getSelectedElement", "first", "getSelectedBlocks", "getAttribute", "isEnabled", "checkAttributeInSelection", "manualDecoratorIds", "truthyManualDecorators", "falsyManualDecorators", "change", "isCollapsed", "position", "getFirstPosition", "hasAttribute", "linkText", "extractTextFromSelection", "linkRange", "findAttributeRange", "_updateLinkContent", "setSelection", "createPositionAfter", "end", "nodeBefore", "getAttributes", "set", "positionAfter", "insertContent", "createText", "removeSelectionAttribute", "ranges", "getValidRanges", "getRanges", "allowedRanges", "createRangeOn", "rangesToUpdate", "slice", "_isRangeToUpdate", "createSelection", "decoratorName", "allowedRange", "containsRange", "text", "linkHref", "firstPosition", "textNode", "rangeItems", "getItems", "firstNode", "UnlinkCommand", "linkCommand", "commands", "get", "rangesToUnlink", "ManualDecorator", "ObservableMixin", "constructor", "defaultValue", "undefined", "HIGHLIGHT_CLASS", "DECORATOR_AUTOMATIC", "DECORATOR_MANUAL", "EXTERNAL_LINKS_REGEXP", "LinkEditing", "Plugin", "pluginName", "isOfficialPlugin", "requires", "TwoStepCaretMovement", "Input", "ClipboardPipeline", "config", "define", "allowCreatingEmptyLinks", "addTargetToExternalLinks", "extend", "allowAttributes", "conversion", "for", "attributeToElement", "view", "elementToAttribute", "linkDecorators", "_enableAutomaticDecorators", "filter", "mode", "_enableManualDecorators", "twoStepCaretMovementPlugin", "plugins", "registerAttribute", "inlineHighlight", "_enableLinkOpen", "_enableSelectionAttributesFixer", "_enableClipboardIntegration", "automaticDecoratorDefinitions", "command", "target", "rel", "getDispatcher", "manualDecoratorDefinitions", "decoratorDefinition", "manualDecoratorValue", "_createPattern", "editing", "viewDocument", "listenTo", "shouldOpen", "env", "isMac", "domEvent", "metaKey", "ctrlKey", "clickedElement", "domTarget", "tagName", "toLowerCase", "closest", "stop", "preventDefault", "context", "keyCode", "keyCodes", "enter", "altKey", "attributeKeys", "includes", "removeLinkAttributesFromSelection", "getLinkAttributesAllowedOnText", "createRangeIn", "content", "newLink", "linkAttributes", "attribute", "textAttributes", "getDefinition", "startsWith", "LinkFormView", "View", "locale", "validators", "focusTracker", "FocusTracker", "keystrokes", "KeystrokeHandler", "_focusables", "ViewCollection", "_validators", "urlInputView", "_createUrlInput", "saveButtonView", "_createButton", "icons", "check", "type", "cancelButtonView", "cancel", "_manualDecoratorSwitches", "_createManualDecoratorSwitches", "children", "_createFormChildren", "_focusCycler", "FocusCycler", "focusables", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "classList", "setTemplate", "tag", "class", "tabindex", "reduce", "accumulator", "switchButton", "isOn", "render", "submitHandler", "childViews", "v", "destroy", "focusFirst", "resetFormStatus", "validator", "errorText", "labeledInput", "LabeledFieldView", "createLabeledInputText", "fieldView", "inputMode", "icon", "className", "eventName", "button", "ButtonView", "tooltip", "extendTemplate", "delegate", "to", "switches", "createCollection", "SwitchButtonView", "withText", "bind", "toMany", "decoratorValue", "commandValue", "additionalButtonsView", "map", "trim", "LinkActionsView", "linkConfig", "_linkConfig", "previewButtonView", "_createPreviewButton", "unlinkButtonView", "unlinkIcon", "editButtonView", "pencil", "bindTemplate", "template", "eventListeners", "VISUAL_SELECTION_MARKER_NAME", "LinkUI", "actionsView", "formView", "ContextualBalloon", "addObserver", "ClickObserver", "_balloon", "_createToolbarLinkButton", "_enableBalloonActivators", "markerToHighlight", "markerToElement", "markerRange", "markerElement", "createUIElement", "accessibility", "addKeystrokeInfos", "keystroke", "_createActionsView", "_createFormView", "_enableUserBalloonInteractions", "unlinkCommand", "_addFormView", "execute", "_hideUI", "CssTransitionDisablerMixin", "getFormValidators", "isValid", "parsedUrl", "getDecoratorSwitchesState", "_closeFormView", "ui", "update", "componentFactory", "MenuBarMenuListItemButtonView", "role", "ButtonClass", "linkIcon", "isToggleable", "_showUI", "parentLink", "_getSelectedLinkElement", "keyEvtData", "_areActionsVisible", "isFocused", "focus", "_isUIVisible", "clickOutsideHandler", "emitter", "activator", "_isUIInPanel", "contextElements", "_createViews", "_areActionsInPanel", "_getBalloonPositionData", "_isFormInPanel", "disableCssTransitions", "visibleView", "select", "enableCssTransitions", "restoreManualDecoratorStates", "_removeFormView", "reset", "remove", "_hideFakeVisualSelection", "forceVisible", "_showFakeVisualSelection", "_addActionsView", "showStack", "_startUpdatingUI", "stopListening", "prevSelectedLink", "prevSelectionParent", "getSelectionParent", "selectedLink", "selectionParent", "updatePosition", "getAncestors", "reverse", "hasView", "markers", "has", "markerViewElements", "markerNameToElements", "newRange", "createRange", "createPositionBefore", "domConverter", "viewRangeToDom", "targetLink", "mapViewToDom", "isWidget", "findLinkElementAncestor", "getTrimmed", "startLink", "start", "endLink", "isEqual", "updateMarker", "isAtEnd", "startPosition", "getLastMatchingPosition", "isContent", "boundaries", "addMarker", "usingOperation", "affectsData", "removeMarker", "ancestor", "form", "MIN_LINK_LENGTH_WITH_SPACE_AT_END", "URL_REG_EXP", "URL_GROUP_IN_MATCH", "AutoLink", "Delete", "anchor", "parent", "_enableTypingHandling", "_enableEnterHandling", "_enableShiftEnterHandling", "_enablePasteLinking", "selectedRange", "selStart", "selEnd", "getLastPosition", "updatedSelection", "getJoined", "_expandLinkRange", "isBefore", "isAfter", "clipboardPipeline", "method", "rangeCount", "dataTransfer", "getData", "matches", "_selectEntireLinks", "watcher", "TextWatcher", "isSingleSpaceAtTheEnd", "getUrlAtTextEnd", "substr", "batch", "isTyping", "linkEnd", "getShiftedBy", "linkStart", "_applyAutoLink", "enterCommand", "previousSibling", "rangeToCheck", "_checkAndApplyAutoLinkOnRange", "shiftEnterCommand", "createPositionAt", "getLastTextLine", "fullUrl", "isLinkAllowedOnRange", "linkIsAlreadySet", "_persistAutoLink", "deletePlugin", "enqueueChange", "requestUndoOnBackspace", "exec", "nodeAfter", "Link", "ListWalker", "constructor", "startElement", "options", "_startElement", "_referenceIndent", "getAttribute", "_isForward", "direction", "_includeSelf", "includeSelf", "_sameAttributes", "toArray", "sameAttributes", "_sameIndent", "sameIndent", "_lowerIndent", "lowerIndent", "_higherIndent", "higherIndent", "first", "walker", "iterator", "Symbol", "nestedItems", "node", "iterateSiblingListBlocks", "_getStartNode", "indent", "push", "length", "some", "attr", "nextSibling", "previousSibling", "isForward", "previousNodesByIndent", "previous", "isListItemBlock", "previousNodeInList", "nodeIndent", "previousNodeIndent", "ListBlocksIterable", "listHead", "_listHead", "ListItemUid", "next", "uid", "is", "hasAttribute", "getAllListItemBlocks", "listItem", "getListItemBlocks", "items", "Array", "from", "reverse", "getNestedListBlocks", "getListItems", "backwardBlocks", "forwardBlocks", "isFirstBlockOfListItem", "listBlock", "isLastBlockOfListItem", "expandListBlocksToCompleteItems", "blocks", "withNested", "allBlocks", "Set", "block", "itemBlock", "add", "sortBlocks", "expandListBlocksToCompleteList", "splitListItemBefore", "writer", "id", "setAttribute", "mergeListItemBefore", "parentBlock", "attributes", "key", "value", "getAttributes", "startsWith", "setAttributes", "indentBlocks", "expand", "indentBy", "blockIndent", "removeListAttributes", "outdentBlocksWithMerge", "visited", "referenceIndent", "Math", "min", "map", "parentBlocks", "Map", "set", "has", "mergedBlocks", "mergeListItemIfNotLast", "get", "mergedBlock", "rename", "attributeKey", "getAttributeKeys", "removeAttribute", "isSingleListItem", "firstItemId", "item", "outdentFollowingItems", "lastBlock", "changedBlocks", "currentIndent", "Number", "POSITIVE_INFINITY", "newIndent", "filter", "root", "rootName", "sort", "a", "b", "index", "getSelectedBlockObject", "model", "selectedElement", "document", "selection", "getSelectedElement", "schema", "isObject", "isBlock", "canBecomeSimpleListItem", "checkChild", "parent", "isNumberedListType", "listType", "parentItemBlocks", "pop", "ListIndentCommand", "Command", "editor", "indentDirection", "_direction", "isEnabled", "_checkEnabled", "getSelectedListBlocks", "change", "previousItemBlock", "_fireAfterExecute", "fire", "firstBlock", "siblingItem", "getSelectedBlocks", "firstNonListBlockIndex", "findIndex", "ListCommand", "type", "_listWalkerOptions", "multiLevel", "undefined", "_getValue", "selectedBlockObject", "checkAttribute", "turnOff", "forceValue", "itemBlocks", "isCollapsed", "additionalAttributes", "listIndent", "listItemId", "ListMergeCommand", "execute", "shouldMergeOnBlocksContentLevel", "firstElement", "lastElement", "_getMergeSubjectElements", "firstIndent", "lastIndent", "lastElementId", "nestedLastElementBlocks", "sel", "createSelection", "createRange", "createPositionAt", "deleteContent", "doNotResetEntireContent", "lastElementAfterDelete", "getLastPosition", "positionParent", "getFirstPosition", "siblingNode", "lastPosition", "firstPosition", "isFirstBlock", "ListSplitCommand", "_getStartBlock", "doc", "ListUtils", "Plugin", "pluginName", "isOfficialPlugin", "isListView", "viewElement", "isListItemView", "getIndent", "createListElement", "getViewElementIdForListType", "createAttributeElement", "getViewElementNameForListType", "priority", "createListItemElement", "findAndAddListHeadToMap", "position", "itemToListHead", "previousNode", "nodeBefore", "nodeAfter", "fixListIndents", "listNodes", "maxIndent", "prevIndent", "fixBy", "applied", "itemIndent", "fixListItemIds", "seenIds", "listItemUpcastConverter", "evt", "data", "conversionApi", "modelRange", "getItems", "shallow", "viewItem", "firstItemListType", "keepEmptyElement", "reconvertItemsOnDataChange", "editing", "attributeNames", "listEditing", "changes", "differ", "getChanges", "itemsToRefresh", "changedItems", "entry", "name", "getShiftedBy", "range", "start", "includes", "attributeNewValue", "doesItemBlockRequiresRefresh", "values", "collectListItemsToRefresh", "reconvertItem", "stack", "Object", "fromEntries", "doesItemWrappingRequiresRefresh", "mapper", "toViewElement", "needsRefresh", "modelElement", "useBogus", "shouldUseBogusParagraph", "element", "isListItemElement", "isListElement", "eventName", "modelAttributes", "listItemDowncastConverter", "strategies", "dataPipeline", "consumer", "createAttributesConsumer", "consumable", "findMappedViewElement", "removeCustomMarkerElements", "unwrapListItemBlock", "viewRange", "insertCustomMarkerElements", "wrapListItemBlock", "listItemDowncastRemoveConverter", "elementName", "split", "viewStart", "toViewPosition", "modelEnd", "viewEnd", "isPhantom", "getTrimmed", "end", "bogusParagraphCreator", "createContainerElement", "class", "setCustomProperty", "createRangeOn", "toViewRange", "createModelToViewPositionMapper", "view", "modelPosition", "offset", "strategy", "scope", "canInjectMarkerIntoElement", "createRangeIn", "viewWalker", "getWalker", "positionAfterLastMarker", "toModelElement", "getCustomProperty", "createPositionAfter", "skip", "previousPosition", "isEqual", "viewPosition", "viewWriter", "unwrap", "markersToRemove", "collectMarkersToRemove", "createPositionBefore", "marker", "remove", "markerElement", "createElement", "insert", "createWrapperElement", "canWrapElement", "wrapper", "wrap", "attributeElement", "parentElement", "listItemIndent", "currentListItem", "listItemViewElement", "listViewElement", "attributeName", "setAttributeOnDowncast", "events", "every", "event", "test", "forEach", "consume", "LIST_BASE_ATTRIBUTES", "ListEditing", "_downcastStrategies", "config", "define", "requires", "Enter", "Delete", "ClipboardPipeline", "multiBlock", "plugins", "CKEditorError", "conflictPlugin", "register", "allowAttributes", "extend", "allowAttributesOf", "inheritAllFrom", "attribute", "setAttributeProperties", "copyOnReplace", "commands", "_setupDeleteIntegration", "_setupEnterIntegration", "_setupTabIntegration", "_setupClipboardIntegration", "_setupAccessibilityIntegration", "outdent", "registerChildCommand", "_setupModelPostFixing", "_setupConversion", "registerDowncastStrategy", "mergeBackwardCommand", "mergeForwardCommand", "listenTo", "isAtStart", "previousBlock", "preventDefault", "stop", "isAtEnd", "context", "enterCommand", "isEmpty", "isSoft", "isLastBlock", "splitCommand", "refresh", "listItemBlocks", "commandName", "shiftKey", "command", "stopPropagation", "getListAttributeNames", "conversion", "for", "elementToElement", "converterPriority", "dispatcher", "on", "modelToViewPositionMapper", "return", "registerPostFixer", "modelChangePostFixer", "clipboardPipeline", "createModelIndentPasteFixer", "allContentChildren", "content", "getChildren", "lastItem", "contentChildrenExceptLastItem", "slice", "method", "allChildren", "isSingleListItemSelected", "t", "accessibility", "addKeystrokeInfoGroup", "label", "keystrokes", "keystroke", "innerItem", "attributeOldValue", "selectable", "refItem", "refType", "refIndent", "firstElementIndent", "indentDiff", "max", "isListItem", "createUIComponents", "icon", "ui", "componentFactory", "buttonView", "_createButton", "ButtonView", "tooltip", "isToggleable", "MenuBarMenuListItemButtonView", "role", "ButtonClass", "locale", "bind", "to", "focus", "ListUI", "icons", "numberedList", "bulletedList", "List", "LIST_STYLE_TO_LIST_TYPE", "LIST_STYLE_TO_TYPE_ATTRIBUTE", "TYPE_ATTRIBUTE_TO_LIST_STYLE", "LIST_STYLE_TYPES", "listStyle", "typeAttribute", "listType", "escape", "html", "encode", "unescape", "_", "n", "e", "noopTest", "merge", "i", "count", "c", "l", "b", "result", "lexer", "text", "node", "options", "indent", "list", "t", "chars", "j", "k", "start", "mangle", "smartypants", "rules", "next", "Renderer", "quote", "Parser", "parser", "l2", "cell", "args", "tokenizer", "walkTokens", "parser", "Parser", "extend", "i", "count", "node", "options", "parent", "start", "index", "rule", "fn", "rules", "element", "isBlock", "isVoid", "text", "remove", "next", "root", "Parser", "e", "input", "Node", "m", "defaults", "process", "plugin", "escape", "parentNode", "self", "join", "s2", "indexOf", "rules", "node", "i", "parentNode", "n", "element", "index", "autolinkRegex", "RegExp", "source", "modelToViewUrlAttributeConverter", "registry", "options", "converter", "evt", "data", "conversionApi", "consumable", "consume", "item", "name", "url", "attributeNewValue", "viewWriter", "writer", "figure", "mapper", "toViewElement", "mediaContentElement", "getChildren", "find", "child", "getCustomProperty", "remove", "mediaViewElement", "getMediaViewElement", "insert", "createPositionAt", "dispatcher", "on", "toMediaWidget", "viewElement", "label", "setCustomProperty", "toWidget", "getSelectedMediaViewWidget", "selection", "getSelectedElement", "isMediaWidget", "isWidget", "createMediaFigureElement", "createContainerElement", "class", "createSlot", "getSelectedMediaModelWidget", "selectedElement", "is", "insertMedia", "model", "selectable", "findOptimalPosition", "change", "mediaElement", "createElement", "insertObject", "setSelection", "undefined", "MediaEmbedCommand", "Command", "editor", "document", "selectedMedia", "value", "getAttribute", "isEnabled", "isMediaSelected", "isAllowedInParent", "execute", "setAttribute", "insertionRange", "findOptimalInsertionRange", "parent", "start", "isEmpty", "schema", "isLimit", "checkChild", "element", "mediaPlaceholderIconViewBox", "MediaRegistry", "constructor", "locale", "config", "providers", "extraProviders", "removedProviders", "Set", "removeProviders", "providerDefinitions", "concat", "filter", "provider", "logWarning", "has", "hasMedia", "_getMedia", "getViewElement", "Media", "trim", "definition", "previewRenderer", "html", "pattern", "toArray", "subPattern", "match", "_getUrlMatches", "rawUrl", "replace", "_getValidUrl", "_locale", "_match", "_previewRenderer", "attributes", "renderForEditingView", "renderMediaPreview", "mediaHtml", "_getPreviewHtml", "createRawElement", "domElement", "domConverter", "setContentOf", "createEmptyElement", "elementName", "_getPlaceholderHtml", "icon", "IconView", "t", "content", "mediaPlaceholderIcon", "viewBox", "placeholder", "Template", "tag", "children", "target", "rel", "href", "render", "outerHTML", "MediaEmbedEditing", "Plugin", "define", "id", "time", "get", "pluginName", "isOfficialPlugin", "conversion", "commands", "add", "register", "inheritAllFrom", "allowAttributes", "for", "elementToStructure", "view", "modelElement", "elementToElement", "includes", "viewMedia", "viewItem", "classes", "modelRange", "modelCursor", "convertChildren", "first", "getItems", "revert", "URL_REGEXP", "AutoMediaEmbed", "_timeoutId", "_positionToInsert", "requires", "Clipboard", "Delete", "Undo", "modelDocument", "clipboardPipeline", "plugins", "listenTo", "firstRange", "getFirstRange", "leftLivePosition", "LivePosition", "fromPosition", "stickiness", "rightLivePosition", "end", "once", "_embedMediaBetweenPositions", "detach", "priority", "undoCommand", "global", "window", "clearTimeout", "leftPosition", "rightPosition", "mediaRegistry", "urlRange", "LiveRange", "walker", "getWalker", "ignoreElementEnd", "node", "mediaEmbedCommand", "setTimeout", "insertionPosition", "root", "rootName", "requestUndoOnBackspace", "MediaFormView", "View", "validators", "focusTracker", "FocusTracker", "keystrokes", "KeystrokeHandler", "set", "urlInputView", "_createUrlInput", "_validators", "setTemplate", "tabindex", "submitHandler", "destroy", "focus", "fieldView", "resetFormStatus", "validator", "errorText", "infoText", "_urlInputViewInfoDefault", "labeledInput", "LabeledFieldView", "createLabeledInputText", "inputField", "_urlInputViewInfoTip", "inputMode", "mediaURLInputValue", "MediaEmbedUI", "_formView", "Dialog", "ui", "componentFactory", "button", "_createDialogButton", "ButtonView", "tooltip", "MenuBarMenuListItemButtonView", "ButtonClass", "buttonView", "command", "dialogPlugin", "mediaIcon", "bind", "to", "hide", "_showDialog", "dialog", "CssTransitionDisablerMixin", "getFormValidators", "_handleSubmitForm", "show", "title", "isModal", "onShow", "select", "actionButtons", "withText", "onExecute", "isValid", "editing", "form", "length", "MediaEmbed", "Widget", "MediaEmbedToolbar", "WidgetToolbarRepository", "widgetToolbarRepository", "ariaLabel", "items", "getRelatedElement", "defaultHandledKeyCodes", "keyCodes", "arrowup", "arrowdown", "esc", "defaultCommitKeyCodes", "enter", "tab", "convertCssLengthToPx", "value", "numericValue", "parseFloat", "endsWith", "toPx", "isPx", "undefined", "toFixed", "replace", "transformListItemLikeElementsIntoLists", "documentFragment", "stylesString", "hasMultiLevelListPlugin", "childCount", "writer", "UpcastWriter", "document", "itemLikeElements", "findAllItemLikeElements", "length", "encounteredLists", "stack", "itemLikeElement", "indent", "isListContinuation", "originalListId", "id", "Math", "min", "listStyle", "detectListStyle", "listElement", "name", "type", "startIndex", "createNewEmptyList", "marginLeft", "setStyle", "parent", "element", "index", "getChildIndex", "insertChild", "parentListItems", "listItemElements", "appendChild", "listItem", "createElement", "push", "removeBulletElement", "removeStyle", "stackItem", "find", "listItems", "unwrapParagraphInListItem", "createRangeIn", "item", "is", "firstChild", "getChild", "unwrapElement", "range", "foundMargins", "Set", "getItems", "match", "getMarginLeftNormalized", "Array", "from", "getClassNames", "className", "startsWith", "hasStyle", "has", "itemData", "getListItemData", "order", "add", "clear", "currentItem", "previousSibling", "isList", "listLikeItem", "listStyleRegexp", "RegExp", "listStyleTypeRegex", "listStartIndexRegex", "legalStyleListRegex", "multiLevelNumberFormatTypeRegex", "legalStyleListMatch", "exec", "multiLevelNumberFormatMatch", "islegalStyleList", "listStyleMatch", "listStyleType", "listStyleTypeMatch", "trim", "bulletedStyle", "findBulletedListStyle", "listStartIndexMatch", "parseInt", "style", "mapListStyleDefinition", "isLegalStyleList", "hasAttribute", "getAttribute", "listMarkerElement", "findListMarkerNode", "listMarker", "_data", "childNode", "getChildren", "textNodeOrElement", "list", "setAttribute", "addClass", "getStyle", "idMatch", "orderMatch", "indentMatch", "bulletMatcher", "Matcher", "styles", "remove", "replaceImagesSourceWithBase64", "rtfData", "upcastWriter", "shapesIds", "findAllShapesIds", "removeAllImgElementsRepresentingShapes", "insertMissingImgs", "removeAllShapeElements", "images", "findAllImageElementsWithLocalSource", "replaceImagesFileSourceWithInlineRepresentation", "extractImageDataFromRtf", "_convertHexToBase64", "hexString", "btoa", "map", "char", "String", "fromCharCode", "join", "shapeElementsMatcher", "el", "prevSiblingName", "exceptionIds", "isElementAShape", "hasElementGfxdataAttribute", "isPreviousSiblingAShapeType", "isElementIdInExceptionsArray", "some", "includes", "imageElementsMatcher", "imgs", "shapes", "split", "every", "shape", "indexOf", "img", "shapeIds", "containsMatchingImg", "attrs", "src", "findSrc", "alt", "nodes", "node", "child", "regexPictureHeader", "regexPicture", "source", "result", "image", "imageType", "hex", "imageElements", "imagesHexSources", "i", "newSrc", "removeMSAttributes", "elementsToUnwrap", "removeClass", "styleName", "getStyleNames", "isEmpty", "itemParent", "childIndex", "msWordMatch1", "msWordMatch2", "MSWordNormalizer", "constructor", "isActive", "htmlString", "test", "execute", "data", "body", "_parsedData", "dataTransfer", "getData", "content", "removeBoldWrapper", "transformBlockBrsToParagraphs", "viewDocument", "ViewDocument", "stylesProcessor", "domConverter", "DomConverter", "renderingMode", "blockElements", "inlineObjectElements", "elementsToReplace", "nextSibling", "findSibling", "nextSiblingIsBlock", "isBlockViewElement", "previousSiblingIsBlock", "hasClass", "viewElement", "direction", "position", "createPositionAt", "getLastMatchingPosition", "nodeAfter", "nodeBefore", "googleDocsMatch", "GoogleDocsNormalizer", "removeXmlns", "removeAttribute", "removeGoogleSheetsTag", "removeInvalidTableWidth", "removeStyleBlock", "googleSheetsMatch", "GoogleSheetsNormalizer", "normalizeSpacing", "normalizeSafariSpaceSpans", "normalizeSpacerunSpans", "htmlDocument", "querySelectorAll", "forEach", "htmlElement", "innerTextLength", "innerText", "substr", "fullMatch", "spaces", "parseHtml", "domParser", "DOMParser", "normalizedHtml", "cleanContentAfterBody", "parseFromString", "bodyString", "innerHTML", "bodyView", "documentToView", "stylesObject", "extractStyles", "fragment", "createDocumentFragment", "childNodes", "domToView", "skipComments", "styleTags", "getElementsByTagName", "sheet", "cssRules", "bodyCloseTag", "htmlCloseTag", "bodyCloseIndex", "htmlCloseIndex", "substring", "PasteFromOffice", "Plugin", "pluginName", "isOfficialPlugin", "requires", "ClipboardPipeline", "editor", "clipboardPipeline", "plugins", "get", "editing", "view", "normalizers", "on", "evt", "_isTransformedWithPasteFromOffice", "codeBlock", "model", "selection", "getFirstPosition", "activeNormalizer", "normalizer", "priority", "REMOVE_FORMAT", "RemoveFormatUI", "Plugin", "pluginName", "isOfficialPlugin", "editor", "ui", "componentFactory", "add", "view", "_createButton", "ButtonView", "set", "tooltip", "MenuBarMenuListItemButtonView", "ButtonClass", "locale", "command", "commands", "get", "t", "label", "icon", "removeFormatIcon", "bind", "to", "listenTo", "execute", "editing", "focus", "RemoveFormatCommand", "Command", "model", "isEnabled", "first", "_getFormattingItems", "document", "selection", "schema", "change", "writer", "item", "is", "attributeName", "_getFormattingAttributes", "removeSelectionAttribute", "itemRange", "createRangeOn", "removeAttribute", "itemHasRemovableFormatting", "curRange", "getRanges", "getItems", "isBlock", "block", "getSelectedBlocks", "getAttributes", "attributeProperties", "getAttributeProperties", "isFormatting", "RemoveFormatEditing", "RemoveFormat", "requires", "upcastStyleToAttribute", "conversion", "options", "modelAttribute", "styleName", "viewElement", "defaultValue", "reduceBoxSides", "shouldUpcast", "for", "attributeToAttribute", "view", "name", "styles", "model", "key", "value", "normalized", "getNormalizedStyle", "reduceBoxSidesValue", "upcastBorderStyles", "viewElementName", "modelAttributes", "defaultBorder", "add", "dispatcher", "on", "evt", "data", "conversionApi", "modelRange", "stylesToConsume", "filter", "viewItem", "hasStyle", "length", "matcherPattern", "consumable", "test", "modelElement", "getItems", "shallow", "pop", "consume", "normalizedBorder", "style", "color", "width", "reducedBorder", "writer", "setAttribute", "downcastAttributeToStyle", "modelAttributeValue", "reduceBoxSidesValue", "style", "sides", "allSidesDefined", "every", "side", "topSideStyle", "top", "allSidesEqual", "updateNumericAttribute", "key", "value", "item", "writer", "defaultValue", "undefined", "setAttribute", "removeAttribute", "createEmptyTableCell", "insertPosition", "attributes", "tableCell", "createElement", "insertElement", "insert", "isHeadingColumnCell", "tableUtils", "table", "parent", "headingColumns", "parseInt", "getAttribute", "column", "getCellLocation", "enableProperty", "schema", "conversion", "options", "modelAttribute", "extend", "allowAttributes", "upcastStyleToAttribute", "viewElement", "downcastAttributeToStyle", "modelElement", "getSelectionAffectedTable", "selection", "selectedElement", "getSelectedElement", "is", "getFirstPosition", "findAncestor", "upcastTableFigure", "dispatcher", "on", "evt", "data", "conversionApi", "consumable", "test", "viewItem", "name", "classes", "viewTable", "getViewTableFromFigure", "consume", "conversionResult", "convertItem", "modelCursor", "modelTable", "first", "modelRange", "getItems", "revert", "convertChildren", "createPositionAt", "updateConversionResult", "upcastTable", "rows", "headingRows", "scanTable", "safeInsert", "forEach", "row", "isEmpty", "skipEmptyTableRow", "index", "stop", "priority", "ensureParagraphInTableCell", "elementName", "start", "nodeAfter", "childNodes", "Array", "from", "getChildren", "node", "paragraph", "move", "createRangeOn", "figureView", "figureChild", "headRows", "bodyRows", "firstTheadElement", "tableChild", "trs", "filter", "el", "tr", "length", "e", "push", "headingCols", "scanRowForHeadingColumns", "children", "child", "th", "colspan", "TableWalker", "constructor", "_jumpedToStartRow", "_table", "_startRow", "startRow", "_endRow", "endRow", "_startColumn", "startColumn", "_endColumn", "endColumn", "_includeAllSlots", "includeAllSlots", "_skipRows", "Set", "_row", "_rowIndex", "_column", "_cellIndex", "_spannedCells", "Map", "_nextCellAtColumn", "Symbol", "iterator", "_canJumpToStartRow", "_jumpToNonSpannedRowClosestToStartRow", "getChild", "_isOverEndRow", "done", "next", "_isOverEndColumn", "_advanceToNextRow", "outValue", "spanData", "_getSpanned", "_shouldSkipSlot", "_formatOutValue", "cell", "rowspan", "_recordSpans", "skipRow", "add", "anchorRow", "anchorColumn", "TableSlot", "rowIsMarkedAsSkipped", "has", "rowIsBeforeStartRow", "columnIsBeforeStartColumn", "columnIsAfterEndColumn", "rowMap", "get", "rowToUpdate", "columnToUpdate", "_markSpannedCell", "set", "rowSpans", "firstRowLength", "_getRowLength", "i", "rowIndex", "reduce", "cols", "tableWalker", "cellAnchorRow", "cellAnchorColumn", "isAnchor", "cellWidth", "cellHeight", "model", "root", "document", "downcastTable", "tableElement", "createContainerElement", "figureElement", "class", "createSlot", "element", "getRows", "positionOffset", "additionalSlots", "some", "asWidget", "toTableWidget", "downcastRow", "tableRow", "createEmptyElement", "downcastCell", "getChildIndex", "result", "tableSlot", "isHeading", "cellElementName", "toWidgetEditable", "createEditableElement", "convertParagraphInTableCell", "isSingleParagraphWithoutAttributes", "setCustomProperty", "isSingleParagraph", "childCount", "hasAnyAttribute", "toWidget", "hasSelectionHandle", "iteratorItem", "getAttributeKeys", "InsertTableCommand", "Command", "editor", "isEnabled", "isAllowedInParent", "plugins", "defaultRows", "config", "defaultColumns", "change", "createTable", "insertObject", "findOptimalPosition", "setSelection", "getNodeByPath", "positionParent", "validParent", "checkChild", "InsertRowCommand", "order", "isAnyCellSelected", "getSelectionAffectedTableCells", "insertAbove", "affectedTableCells", "rowIndexes", "getRowIndexes", "last", "insertRows", "at", "copyStructureFromAbove", "InsertColumnCommand", "insertBefore", "columnIndexes", "getColumnIndexes", "insertColumns", "columns", "SplitCellCommand", "direction", "selectedCells", "isHorizontal", "splitCellHorizontally", "splitCellVertically", "cropTableToDimensions", "sourceTable", "cropDimensions", "croppedTable", "cropHeight", "tableMap", "sourceRow", "sourceColumn", "rowInCroppedTable", "tableCellCopy", "cloneElement", "append", "trimTableCellIfNeeded", "addHeadingsToCroppedTable", "getVerticallyOverlappingCells", "overlapRow", "cells", "slotInfo", "cellEndRow", "splitHorizontally", "splitRow", "newRowspan", "newCellAttributes", "newCellRowSpan", "newCell", "columnIndex", "getPositionBefore", "getHorizontallyOverlappingCells", "overlapColumn", "cellsToSplit", "cellEndColumn", "splitVertically", "splitColumn", "newColspan", "newCellColSpan", "createPositionAfter", "cellRow", "cellColumn", "limitRow", "limitColumn", "trimmedSpan", "headingRowsInCrop", "headingColumnsInCrop", "removeEmptyColumns", "width", "getColumns", "columnsMap", "fill", "emptyColumns", "cellsCount", "emptyColumn", "removeColumns", "removeEmptyRows", "emptyRows", "tableRowCount", "emptyRow", "removeRows", "removeEmptyRowsColumns", "removedColumns", "adjustLastRowIndex", "dimensions", "lastRowMap", "firstColumn", "lastColumn", "lastRow", "everyCellHasSingleRowspan", "rowspanAdjustment", "adjustLastColumnIndex", "lastColumnMap", "firstRow", "everyCellHasSingleColspan", "colspanAdjustment", "MergeCellCommand", "cellToMerge", "_getMergeableCell", "doc", "getTableCellsContainingSelection", "isMergeNext", "cellToExpand", "cellToRemove", "removedTableCellRow", "mergeTableCells", "spanAttribute", "cellSpan", "cellToMergeSpan", "createRangeIn", "getHorizontalCell", "getVerticalCell", "span", "horizontalCell", "nextSibling", "previousSibling", "hasHeadingColumns", "cellOnLeft", "cellOnRight", "leftCellColumn", "rightCellColumn", "leftCellSpan", "isCellOnLeftInHeadingColumn", "isCellOnRightInHeadingColumn", "cellsAreTouching", "isMergeWithBodyCell", "isMergeWithHeadCell", "currentCellRowSpan", "rowOfCellToMerge", "currentCellData", "find", "mergeColumn", "cellToMergeData", "remove", "firstTableChild", "RemoveRowCommand", "firstCell", "lastRowIndex", "selectedRowIndexes", "areAllRowsSelected", "referenceCells", "removedRowIndexes", "columnIndexToFocus", "rowsToRemove", "cellToFocus", "getCellToFocus", "removedRowIndex", "columnToFocus", "Math", "min", "RemoveColumnCommand", "tableColumnCount", "lastCell", "getBoundaryCells", "removedColumnIndexes", "columnsToRemove", "reverse", "pop", "returnValue", "isBefore", "SetHeaderRowCommand", "isInTable", "_isInHeading", "forceValue", "headingRowsToSet", "currentHeadingRows", "overlappingCells", "SetHeaderColumnCommand", "headingColumnsToSet", "COLUMN_MIN_WIDTH_AS_PERCENTAGE", "COLUMN_MIN_WIDTH_IN_PIXELS", "COLUMN_WIDTH_PRECISION", "getChangedResizedTables", "affectedTables", "differ", "getChanges", "referencePosition", "type", "includes", "position", "range", "tableNode", "getColumnGroupElement", "getColumnMinWidthAsPercentage", "getTableWidthInPixels", "referenceElement", "getChildrenViewElement", "domReferenceElement", "editing", "view", "domConverter", "mapViewToDom", "getElementWidthInPixels", "viewFigure", "mapper", "toViewElement", "domElement", "styles", "global", "window", "getComputedStyle", "boxSizing", "parseFloat", "paddingLeft", "paddingRight", "borderLeftWidth", "borderRightWidth", "getColumnEdgesIndexes", "cellColumnIndex", "leftEdge", "rightEdge", "toPrecision", "multiplier", "pow", "number", "round", "clamp", "max", "createFilledArray", "sumArray", "array", "map", "Number", "isNaN", "normalizeColumnWidths", "columnWidths", "widths", "replace", "normalizedWidths", "calculateMissingColumnWidths", "totalWidth", "columnWidth", "isLastColumn", "numberOfUninitializedColumns", "totalWidthOfInitializedColumns", "widthForUninitializedColumn", "getDomCellOuterWidth", "domCell", "borderWidth", "updateColumnElements", "tableColumnGroup", "appendElement", "getTableColumnElements", "columnGroupElement", "getTableColumnsWidths", "translateColSpanAttribute", "tableColumnElements", "acc", "colSpan", "TableUtils", "Plugin", "pluginName", "isOfficialPlugin", "decorate", "createEmptyRows", "insertAt", "rowsToInsert", "isCopyStructure", "copyStructureFrom", "CKEditorError", "walkerEndRow", "tableIterator", "rowColSpansMap", "lastCellRow", "isOverlappingInsertedRow", "isReferenceRow", "cellIndex", "abs", "columnsToInsert", "tableColumns", "createCells", "rowCount", "indexesObject", "cellsToMove", "cellsToTrim", "getCellsToMoveAndTrimOnRemoveRow", "size", "rowAfterRemovedSection", "moveCellsToRow", "updateHeadingRows", "adjustHeadingColumns", "removedColumnIndex", "adjacentColumn", "removedColumnWidth", "adjacentColumnWidth", "numberOfCells", "newCellsSpan", "updatedSpan", "breakSpanEvenly", "newCellsAttributes", "cellsToInsert", "splitCellColumn", "cellsToUpdate", "isOnSameColumn", "spansOverColumn", "splitCellRow", "distanceFromLastCellSpan", "isAfterSplitCell", "rowspanToSet", "getSelectedTableCells", "sortRanges", "getRanges", "getContainedElement", "cellWithSelection", "tableCells", "indexes", "_getFirstLastIndexesObject", "entry", "isSelectionRectangular", "selectedTableCells", "_areCellInTheSameTableSection", "areaOfSelectedCells", "areaOfValidSelection", "getBiggestRectangleArea", "ranges", "sort", "compareRangeOrder", "allIndexesSorted", "indexA", "indexB", "_areIndexesInSameSection", "headingSectionSize", "firstCellIsInHeading", "lastCellIsInHeading", "tableCellToInsert", "floor", "headingsRemoved", "newRows", "lastRowOfCell", "isCellStickingOutFromRemovedRows", "rowspanInRemovedSection", "rowSpanToSet", "isCellOverlappingRemovedRows", "targetRowIndex", "tableRowMap", "previousCell", "cellToMove", "targetPosition", "rangeA", "rangeB", "posA", "posB", "rowsIndexes", "values", "MergeCellsCommand", "firstTableCell", "shift", "mergeWidth", "mergeHeight", "getMergeDimensions", "cellBeingMerged", "targetCell", "maxWidthOffset", "maxHeightOffset", "getMaxOffset", "firstCellRow", "firstCellColumn", "currentMaxOffset", "which", "dimensionValue", "SelectRowCommand", "affectsData", "rangesToSelect", "SelectColumnCommand", "startLocation", "endLocation", "cellInfo", "injectTableLayoutPostFixer", "registerPostFixer", "tableLayoutPostFixer", "changes", "wasFixed", "analyzedTables", "isTableAttributeEntry", "fixTableCellsRowspan", "fixTableRowsSizes", "findCellsToTrim", "childrenLengths", "getChildrenLengths", "entries", "splice", "rowsLengths", "tableSize", "isValid", "maxColumns", "prev", "current", "maxRows", "count", "isInHeader", "rowLimit", "lengths", "attributeKey", "injectTableCellParagraphPostFixer", "tableCellContentsPostFixer", "fixTable", "fixTableRow", "fixTableCellContent", "checkTableCellChange", "textNodes", "wrap", "tableHeadingsRefreshHandler", "isRowChange", "expectedElementName", "reconvertItem", "tableCellRefreshHandler", "cellsToCheck", "paragraphsToRefresh", "shouldRefresh", "TableEditing", "_additionalSlots", "requires", "register", "inheritAllFrom", "allowIn", "isLimit", "allowContentOf", "isSelectable", "for", "elementToStructure", "elementToElement", "converterPriority", "attributeToAttribute", "upcastCellSpan", "define", "commands", "listenTo", "registerAdditionalSlot", "slotHandler", "InsertTableView", "View", "locale", "bind", "bindTemplate", "items", "_createGridCollection", "keystrokes", "KeystrokeHandler", "focusTracker", "FocusTracker", "to", "setTemplate", "tag", "text", "mousedown", "preventDefault", "click", "fire", "domEvt", "target", "dataset", "focus", "focusedElement", "_highlightGridBoxes", "render", "addKeyboardHandlingForGrid", "keystrokeHandler", "gridItems", "numberOfColumns", "uiLanguageDirection", "boxView", "itemRow", "itemColumn", "isOn", "_createGridButton", "label", "button", "ButtonView", "extendTemplate", "boxes", "createCollection", "TableUI", "t", "contentLanguageDirection", "isContentLtr", "ui", "componentFactory", "command", "dropdownView", "createDropdown", "buttonView", "icon", "icons", "tooltip", "insertTableView", "panelView", "delegate", "execute", "menuView", "MenuBarMenuView", "event", "isOpen", "reset", "commandName", "bindIsOn", "_prepareDropdown", "tableColumnIcon", "tableRowIcon", "_prepareMergeSplitButtonDropdown", "tableMergeCellIcon", "_fillDropdownWithListOptions", "toMany", "areEnabled", "source", "SwitchButtonView", "SplitButtonView", "mergeCommandName", "mergeCommand", "itemDefinitions", "Collection", "option", "addListOption", "addListToDropdown", "ViewModel", "withText", "TableSelection", "args", "_handleDeleteContent", "_handleInsertTextEvent", "_defineSelectionConverter", "_enablePluginDisabling", "documentFragment", "createDocumentFragment", "adjustedLastRow", "adjustedLastColumn", "anchorCell", "cellsToSelect", "_getCellsToSelect", "backward", "focusCellRange", "anchorCellRange", "highlighted", "viewWriter", "clearHighlightedTableCells", "addClass", "lastViewCell", "previouslyHighlighted", "removeClass", "clear", "getNearestSelectionRange", "isBackward", "tableCellToSelect", "deleteContent", "createSelection", "rangeToSelect", "setTo", "viewRanges", "selectionMap", "walkerOptions", "flipVertically", "flipHorizontally", "flat", "TableClipboard", "ClipboardMarkersUtils", "ClipboardPipeline", "viewDocument", "_onCopyCut", "content", "selectable", "_onInsertContent", "tableSelection", "clipboardMarkersUtils", "canEditAt", "enqueueChange", "isUndoable", "_copySelectedFragmentWithMarkers", "getSelectionAsFragment", "dataTransfer", "toView", "method", "pastedTable", "getTableIfOnlyTableInContent", "_pasteMarkersIntoTransformedElement", "markers", "_replaceSelectedCells", "pastedDimensions", "height", "prepareTableForPasting", "selectionHeight", "selectionWidth", "selectedTable", "_replaceSelectedCellsWithPasted", "selectionRanges", "pastedWidth", "pastedHeight", "pastedTableLocationMap", "createLocationMap", "selectedTableMap", "pastedRow", "pastedColumn", "pastedCell", "cellToInsert", "newTableCell", "_replaceTableSlotCell", "areHeadingRowsIntersectingSelection", "areHeadingColumnsIntersectingSelection", "columnsLimit", "newCells", "doHorizontalSplit", "rowsLimit", "doVerticalSplit", "contentRange", "rangeBefore", "createRange", "createPositionBefore", "hasContent", "ignoreWhitespaces", "rangeAfter", "end", "shouldExpandSelection", "expandTableSize", "splitCellsToRectangularSelection", "expectedHeight", "expectedWidth", "tableWidth", "tableHeight", "limitColumns", "isAffectedBySelection", "limitRows", "limit", "endIndex", "isInsideSelection", "overlapsSelectionFromOutside", "TableKeyboard", "_onArrowKey", "context", "_handleTabOnSelectedTable", "_handleTab", "accessibility", "addKeystrokeInfoGroup", "id", "keystroke", "bubblingEventInfo", "domEventData", "stopPropagation", "isForward", "shiftKey", "getFocusCell", "currentRowIndex", "currentCellIndex", "isFirstCellInRow", "isLastCellInRow", "isLastRow", "nextRow", "previousRow", "eventInfo", "keyCode", "getLocalizedArrowKeyCodeDirection", "wasHandled", "_handleArrowKeys", "expandSelection", "focusCell", "_navigateFromCellInDirection", "isCollapsed", "containsEntireContent", "isObject", "_isSelectionAtCellEdge", "getLastPosition", "getLimitElement", "boundaryPosition", "isTouching", "probe", "modifySelection", "isEqual", "currentCellInfo", "isOutsideVertically", "isBeforeFirstCell", "isAfterLastCell", "cellToSelect", "getAnchorCell", "setCellSelection", "positionToSelect", "MouseEventsObserver", "DomEventObserver", "domEventType", "onDomEvent", "domEvent", "TableMouse", "addObserver", "_enableShiftClickSelection", "_enableMouseDragSelection", "blockSelectionChange", "_getModelTableCellFromDomEvent", "haveSameTableParent", "beganCellSelection", "ctrlKey", "altKey", "buttons", "newTargetCell", "viewTargetElement", "viewPosition", "modelPosition", "toModelPosition", "includeSelf", "cellA", "cellB", "Table", "Widget", "getSelectionAffectedTableWidget", "selection", "selectedTable", "getSelectedTableWidget", "getTableWidgetAncestor", "viewElement", "getSelectedElement", "isTableWidget", "selectionPosition", "getFirstPosition", "parent", "is", "getCustomProperty", "isWidget", "TableToolbar", "Plugin", "requires", "WidgetToolbarRepository", "pluginName", "isOfficialPlugin", "editor", "t", "widgetToolbarRepository", "plugins", "get", "tableContentToolbarItems", "config", "tableToolbarItems", "register", "ariaLabel", "items", "getRelatedElement", "ColorInputView", "View", "constructor", "locale", "options", "set", "focusTracker", "FocusTracker", "_focusables", "ViewCollection", "dropdownView", "_createDropdownView", "inputView", "_createInputTextView", "keystrokes", "KeystrokeHandler", "_stillTyping", "focusCycler", "FocusCycler", "focusables", "keystrokeHandler", "actions", "focusPrevious", "focusNext", "setTemplate", "tag", "attributes", "class", "children", "on", "evt", "name", "inputValue", "_setInputValue", "render", "buttonView", "forEach", "view", "add", "element", "listenTo", "focus", "direction", "focusLast", "focusFirst", "destroy", "bind", "bindTemplate", "colorSelector", "_createColorSelector", "dropdown", "createDropdown", "colorPreview", "style", "backgroundColor", "to", "if", "value", "extendTemplate", "label", "tooltip", "panelPosition", "uiLanguageDirection", "panelView", "isVisible", "updateSelectedColors", "showColorGridsFragment", "InputTextView", "blur", "mappedColor", "colorDefinitions", "find", "def", "color", "delegate", "defaultColor", "defaultColorValue", "removeColorButtonLabel", "ColorSelectorView", "colors", "columns", "removeButtonLabel", "colorPickerLabel", "colorPickerViewConfig", "colorPickerConfig", "hideInput", "appendUI", "data", "source", "isOpen", "fire", "backupColor", "colorGridsFragmentView", "colorPickerButtonView", "normalizedInputValue", "normalizeColor", "colorString", "replace", "isEmpty", "val", "getBorderStyleLabels", "none", "solid", "dotted", "dashed", "double", "groove", "ridge", "inset", "outset", "getLocalizedColorErrorText", "getLocalizedLengthErrorText", "colorFieldValidator", "trim", "toLowerCase", "isColor", "lengthFieldValidator", "isNumberString", "isLength", "isPercentage", "lineWidthFieldValidator", "getBorderStyleDefinitions", "defaultStyle", "itemDefinitions", "Collection", "styleLabels", "definition", "type", "model", "ViewModel", "_borderStyleValue", "role", "withText", "fillToolbar", "icons", "toolbar", "labels", "propertyName", "nameToValue", "defaultValue", "button", "ButtonView", "icon", "buttonValue", "valueToCompare", "defaultColors", "hasBorder", "getLabeledColorInputCreator", "labeledFieldView", "viewUid", "statusUid", "colorInputView", "colorConfigToColorGridDefinitions", "colorConfig", "id", "ariaDescribedById", "errorText", "parsedValue", "parseFloat", "Number", "isNaN", "String", "map", "item", "FormRowView", "createCollection", "child", "labelView", "_role", "_ariaLabelledBy", "TableCellPropertiesView", "borderStyle", "borderWidth", "borderColor", "padding", "width", "height", "horizontalAlignment", "verticalAlignment", "borderStyleDropdown", "borderWidthInput", "borderColorInput", "borderRowLabel", "_createBorderFields", "backgroundRowLabel", "backgroundInput", "_createBackgroundFields", "widthInput", "operatorLabel", "heightInput", "dimensionsLabel", "_createDimensionFields", "horizontalAlignmentToolbar", "verticalAlignmentToolbar", "alignmentLabel", "_createAlignmentFields", "paddingInput", "_createPaddingField", "saveButtonView", "cancelButtonView", "_createActionButtons", "_focusCycler", "FormHeaderView", "tabindex", "submitHandler", "chain", "fieldView", "defaultTableCellProperties", "defaultBorder", "colorInputCreator", "borderColors", "accessibleLabel", "LabelView", "text", "LabeledFieldView", "createLabeledDropdown", "ariaLabelledBy", "undefined", "isOn", "addListToDropdown", "createLabeledInputText", "isBorderStyleSet", "newValue", "oldValue", "backgroundColors", "ALIGNMENT_ICONS", "left", "alignLeft", "center", "alignCenter", "right", "alignRight", "justify", "alignJustify", "top", "alignTop", "middle", "alignMiddle", "bottom", "alignBottom", "ToolbarView", "isContentRTL", "contentLanguageDirection", "isCompact", "_horizontalAlignmentLabels", "_verticalAlignmentLabels", "fieldsThatShouldValidateToSave", "check", "toMany", "errorTexts", "every", "cancel", "BALLOON_POSITIONS", "BalloonPanelView", "defaultPositions", "northArrowSouth", "northArrowSouthWest", "northArrowSouthEast", "southArrowNorth", "southArrowNorthWest", "southArrowNorthEast", "viewportStickyNorth", "repositionContextualBalloon", "target", "balloon", "editing", "document", "position", "getBalloonCellPositionData", "getBalloonTablePositionData", "updatePosition", "modelTable", "getSelectionAffectedTable", "viewTable", "mapper", "toViewElement", "domConverter", "mapViewToDom", "positions", "rangeCount", "createBoundingRect", "getRanges", "modelTableCell", "getTableCellAtPosition", "viewTableCell", "isTableCellSelected", "nodeAfter", "findAncestor", "ranges", "rects", "Array", "from", "range", "start", "Rect", "getBoundingRect", "getSingleValue", "objectOrString", "isObject", "addDefaultUnitToNumericValue", "defaultUnit", "numericValue", "getNormalizedDefaultProperties", "normalizedConfig", "includeAlignmentProperty", "alignment", "includePaddingProperty", "includeVerticalAlignmentProperty", "includeHorizontalAlignmentProperty", "isRightToLeftContent", "getNormalizedDefaultCellProperties", "config", "options", "getNormalizedDefaultProperties", "borderStyle", "borderColor", "borderWidth", "ERROR_TEXT_TIMEOUT", "propertyToCommandMap", "height", "width", "padding", "backgroundColor", "horizontalAlignment", "verticalAlignment", "TableCellPropertiesUI", "Plugin", "constructor", "editor", "define", "borderColors", "defaultColors", "backgroundColors", "requires", "ContextualBalloon", "pluginName", "isOfficialPlugin", "t", "_defaultTableCellProperties", "get", "includeVerticalAlignmentProperty", "includeHorizontalAlignmentProperty", "includePaddingProperty", "isRightToLeftContent", "locale", "contentLanguageDirection", "_balloon", "plugins", "view", "_isReady", "ui", "componentFactory", "add", "ButtonView", "set", "label", "icon", "tableCellProperties", "tooltip", "listenTo", "_showView", "commands", "Object", "values", "map", "commandName", "bind", "toMany", "areEnabled", "some", "isCommandEnabled", "destroy", "borderColorsConfig", "normalizeColorOptions", "localizedBorderColors", "getLocalizedColorOptions", "backgroundColorsConfig", "localizedBackgroundColors", "hasColorPicker", "colorPicker", "TableCellPropertiesView", "defaultTableCellProperties", "colorPickerConfig", "render", "_hideView", "_undoStepBatch", "operations", "length", "execute", "keystrokes", "data", "cancel", "clickOutsideHandler", "emitter", "activator", "_isViewInBalloon", "contextElements", "element", "callback", "colorErrorText", "getLocalizedColorErrorText", "lengthErrorText", "getLocalizedLengthErrorText", "on", "_getPropertyChangeCallback", "_getValidatedPropertyChangeCallback", "viewField", "borderColorInput", "errorText", "validator", "colorFieldValidator", "borderWidthInput", "lineWidthFieldValidator", "paddingInput", "lengthFieldValidator", "widthInput", "heightInput", "backgroundInput", "borderStyleCommand", "entries", "property", "defaultValue", "value", "forEach", "_createPropertiesView", "_updateView", "_fillViewFormFromCommandValues", "position", "getBalloonCellPositionData", "model", "createBatch", "focus", "stopListening", "saveButtonView", "remove", "editing", "viewDocument", "document", "getTableWidgetAncestor", "selection", "_isViewVisible", "repositionContextualBalloon", "visibleView", "hasView", "evt", "propertyName", "newValue", "batch", "setErrorTextDebounced", "debounce", "TableCellPropertyCommand", "Command", "attributeName", "_defaultValue", "tableUtils", "selectedTableCells", "getSelectionAffectedTableCells", "isEnabled", "_getSingleValue", "tableCells", "valueToSet", "_getValueToSet", "enqueueChange", "writer", "tableCell", "setAttribute", "removeAttribute", "_getAttribute", "getAttribute", "firstCellValue", "everyCellHasAttribute", "every", "undefined", "TableCellWidthCommand", "addDefaultUnitToNumericValue", "TableCellWidthEditing", "TableEditing", "enableProperty", "schema", "conversion", "modelAttribute", "styleName", "TableCellPaddingCommand", "getSingleValue", "TableCellHeightCommand", "TableCellBackgroundColorCommand", "TableCellVerticalAlignmentCommand", "TableCellHorizontalAlignmentCommand", "TableCellBorderStyleCommand", "TableCellBorderColorCommand", "TableCellBorderWidthCommand", "VALIGN_VALUES_REG_EXP", "ALIGN_VALUES_REG_EXP", "TableCellPropertiesEditing", "addStyleProcessorRules", "addBorderRules", "enableBorderProperties", "color", "style", "addPaddingRules", "reduceBoxSides", "addBackgroundRules", "enableHorizontalAlignmentProperty", "enableVerticalAlignmentProperty", "defaultBorder", "modelAttributes", "extend", "allowAttributes", "upcastBorderStyles", "downcastAttributeToStyle", "modelElement", "for", "attributeToAttribute", "name", "key", "alignment", "styles", "viewElement", "align", "getStyle", "attributes", "valign", "TableCellProperties", "TableWidthsCommand", "Command", "isEnabled", "options", "model", "plugins", "editor", "table", "document", "selection", "getSelectedElement", "columnWidths", "tableWidth", "Array", "isArray", "split", "change", "writer", "setAttribute", "removeAttribute", "tableColumnGroup", "get", "getColumnGroupElement", "remove", "widths", "normalizeColumnWidths", "colGroupElement", "createElement", "forEach", "columnWidth", "appendElement", "append", "from", "getChildren", "column", "index", "upcastColgroupElement", "tableUtilsPlugin", "dispatcher", "on", "evt", "data", "conversionApi", "modelTable", "modelCursor", "findAncestor", "columnElements", "getTableColumnElements", "columnsCount", "getColumns", "translateColSpanAttribute", "length", "_", "includes", "updateColumnElements", "priority", "downcastTableResizedClass", "viewWriter", "item", "viewElement", "mapper", "toViewElement", "viewTable", "is", "find", "viewChild", "addClass", "removeClass", "TableColumnResizeEditing", "Plugin", "constructor", "_isResizingActive", "set", "_resizingData", "_domEmitter", "DomEmitterMixin", "_tableUtilsPlugin", "name", "value", "classAction", "editing", "view", "root", "roots", "getRoot", "rootName", "requires", "TableEditing", "TableUtils", "pluginName", "isOfficialPlugin", "_extendSchema", "_registerPostFixer", "_registerConverters", "_registerResizingListeners", "_registerResizerInserter", "columnResizePlugin", "tableEditing", "registerAdditionalSlot", "filter", "element", "positionOffset", "tableWidthsCommand", "commands", "add", "bind", "to", "isEditorReadOnly", "isPluginEnabled", "isTableWidthsCommandCommandEnabled", "stopListening", "destroy", "getTableColumnsWidths", "schema", "extend", "allowAttributes", "register", "allowIn", "isLimit", "registerPostFixer", "changed", "getChangedResizedTables", "columns", "normalizedWidths", "adjustColumnWidths", "isEqual", "plugin", "newTableColumnsCount", "columnsCountDelta", "map", "width", "Number", "replace", "cellSet", "getAffectedCells", "differ", "cell", "currentColumnsDelta", "hasMoreColumns", "currentColumnIndex", "getCellLocation", "columnMinWidthAsPercentage", "getColumnMinWidthAsPercentage", "columnWidthsToInsert", "createFilledArray", "splice", "removedColumnWidths", "Math", "abs", "sumArray", "Set", "getChanges", "type", "position", "nodeAfter", "getAncestors", "referenceNode", "nodeBefore", "conversion", "for", "attributeToAttribute", "key", "getStyle", "elementToElement", "styles", "viewColWidth", "endsWith", "editingView", "addObserver", "MouseEventsObserver", "_onMouseDownHandler", "listenTo", "global", "window", "throttle", "_onMouseMoveHandler", "_onMouseUpHandler", "eventInfo", "domEventData", "target", "hasClass", "_isResizingAllowed", "toModelElement", "canEditAt", "preventDefault", "stop", "columnWidthsInPx", "_calculateDomColumnWidths", "viewCol", "_insertColgroupElement", "_getResizingData", "_applyResizingAttributesToTable", "tableWalker", "TableWalker", "cellSlot", "viewCell", "domCell", "domConverter", "mapViewToDom", "domCellWidth", "getDomCellOuterWidth", "toPrecision", "colgroup", "createContainerElement", "i", "viewColElement", "createEmptyElement", "columnWidthInPc", "setStyle", "insert", "createPositionAt", "resizingData", "figureInitialPcWidth", "viewFigureWidth", "viewFigureParentWidth", "elements", "viewResizer", "mouseEventData", "columnPosition", "flags", "isRightEdge", "isTableCentered", "isLtrContent", "viewFigure", "viewLeftColumn", "viewRightColumn", "leftColumnWidth", "rightColumnWidth", "dxLowerBound", "COLUMN_MIN_WIDTH_IN_PIXELS", "dxUpperBound", "multiplier", "dx", "clamp", "clientX", "min", "max", "leftColumnWidthAsPercentage", "tableWidthAsPercentage", "rightColumnWidthAsPercentage", "viewColgroup", "viewColumns", "columnWidthsAttributeOld", "columnWidthsAttributeNew", "isColumnWidthsAttributeChanged", "tableWidthAttributeOld", "getAttribute", "tableWidthAttributeNew", "isTableWidthAttributeChanged", "execute", "shift", "removeStyle", "domEvent", "viewLeftCell", "modelLeftCell", "leftColumnIndex", "getColumnEdgesIndexes", "rightEdge", "lastColumnIndex", "hasAttribute", "locale", "contentLanguageDirection", "getChild", "undefined", "getElementWidthInPixels", "parent", "getTableWidthInPixels", "modelElement", "createUIElement", "class", "TableColumnResize", "TableCellWidthEditing", "n", "Image", "application", "map", "error", "element", "options", "_", "capitalize", "tokenize", "property", "index", "shift", "e", "node", "processor", "fetch", "set", "element", "match", "oldValue", "index", "_", "error", "capitalize", "_a", "constructor", "observer", "module", "Context", "extend", "a", "b", "application", "tokenize", "logger", "elements", "Scope", "c", "n", "k", "v", "resolve", "result", "constant", "e", "history", "query", "frame", "_a", "e", "_a", "frame", "e", "_a", "_e", "option", "Bss", "e", "import_bootstrap_bundle", "e", "e", "e", "i", "_a", "text", "import_bootstrap_bundle", "e", "import_bootstrap_bundle", "_a", "import_bootstrap_bundle", "_a", "a", "e", "e", "import_bootstrap_bundle", "import_bootstrap_bundle", "e", "e", "e", "e", "error", "import_bootstrap_bundle", "options", "e", "_a", "lookup", "keys", "count", "i", "html", "e", "i", "query", "version", "a", "c", "i", "s", "l", "u", "encode", "encodeURI", "b", "r2", "isValid", "v", "qs", "e", "_a", "debounce", "text", "import_bootstrap_bundle", "e", "delay", "i", "e", "e", "now", "map", "e", "observer", "import_bootstrap_bundle", "e", "input", "import_bootstrap_bundle", "e", "onLoad", "e", "blob", "e", "_a", "import_bootstrap_bundle", "plainTextToHtml", "text", "e", "o", "f", "_", "s", "c", "h", "$", "j", "w", "ce", "B", "y", "q", "k", "z", "x", "i", "n", "r", "t", "g", "I", "T", "v", "b", "p", "m", "O", "S", "P", "A", "D", "M", "L", "N", "a", "d", "l", "u", "C", "V", "F", "de_DE_default", "de_DE_default", "de_DE_default", "IconCross", "CharacterA", "MarkupEditor", "en_GB_default", "en_GB_default", "en_GB_default", "IconCross", "CharacterA", "MarkupEditor", "es_ES_default", "es_ES_default", "es_ES_default", "IconCross", "CharacterA", "MarkupEditor", "fr_FR_default", "fr_FR_default", "fr_FR_default", "IconCross", "CharacterA", "MarkupEditor", "it_IT_default", "it_IT_default", "it_IT_default", "IconCross", "CharacterA", "MarkupEditor", "nl_NL_default", "nl_NL_default", "nl_NL_default", "normalizeLocale", "de_DE_default", "MarkupEditor", "es_ES_default", "fr_FR_default", "it_IT_default", "nl_NL_default", "en_GB_default", "offset", "size", "i", "result", "onprogress", "options", "resolve", "blob", "isBrowser", "isString", "v", "element", "style", "h", "children", "width", "height", "isAndroid", "clone", "ctx", "isObject", "isFunction", "image", "fn", "e", "error", "canvasMemoryLimit", "colorSpace", "imageData", "post", "w", "a", "Direction", "scalar", "x", "y", "b", "l", "f", "s", "c", "p", "r", "format", "start", "n", "m", "t", "sizeMin", "index", "first", "last", "d", "j", "scale", "next", "h2", "isElement", "parent", "container", "isSafari", "createImage", "parse", "header", "isMac", "isPlainObject", "stringify", "x2", "g", "resizeImageData", "clamp", "input", "hasProp", "isArray", "isWindows", "timeout", "delay", "fontSize", "text", "node", "uid", "rules", "rule", "remoteRules", "styleSheets", "props", "shapeDeepCopy", "_", "y2", "bounds", "parser", "height", "x", "y", "width", "height", "element", "image", "resolve", "isFunction", "isString", "cache", "options", "onLoad", "container", "srcRect", "_a", "l", "i", "fn", "transform", "h", "a", "b", "identity", "k", "_", "props", "result", "keys", "now", "node", "root", "style", "text", "input", "html", "hash", "delay", "uid", "p", "t", "rule", "rules", "next", "setContext", "flush", "e", "c", "dispatch", "block", "detach", "config", "init", "d", "tick", "lookup", "list", "create_each_block", "o", "n", "insert", "update", "index", "instance", "create_fragment", "start", "set", "subscribe", "run", "isEqual", "defaultValue", "property", "r", "scalar", "clamp", "v", "clone", "isArray", "isObject", "copy", "hasProp", "w", "isRotatedSideways", "process", "error", "isString", "isElement", "hasProp", "bubble", "image", "getImage", "loadImage", "options", "resolve", "error", "processImage", "isSafari", "props", "element", "blob", "resolve", "limit", "r", "i", "B", "D", "A", "size", "version", "container", "format", "isSafari", "clamp", "video", "frame", "h", "width", "height", "image", "options", "fn", "onprogress", "scalar", "canvasMemoryLimit", "imageSize", "crop", "imageData", "dataset", "createStore", "isString", "isFunction", "src", "imageState", "h", "isObject", "options", "f", "x", "y", "z", "s", "c", "index", "l", "i", "w", "p", "a", "b", "c2", "j", "close", "first", "last", "width", "height", "v", "r", "t", "isBrowser", "clamp", "scale", "clarity", "gamma", "vignette", "drawPath", "drawRect", "drawEllipse", "options", "i", "x", "y", "r", "index", "l", "width", "height", "scalar", "h", "t", "a", "b", "fn", "keys", "result", "defaults", "set", "delay", "identity", "interpolate", "start", "now", "spring", "d", "isArray", "_", "k", "opts", "node", "element", "e", "map", "isURL", "resolve", "update", "isBrowser", "f", "dispatch", "SPRING_PROPS", "SPRING_PROPS_FRACTION", "isString", "image", "text", "fontSize", "texture", "backgroundColor", "hash", "p", "canvas", "usedTextures", "scale", "gamma", "vignette", "clamp", "v", "drawShapes", "isText", "gridSize", "$$props", "init", "list", "ctx", "root", "isSafari", "styles", "style", "isVisible", "props", "$opacityClamped", "setContext", "isMac", "html", "t2", "transform", "shift", "handleClick", "isFunction", "input", "value", "option", "g", "first", "Input", "Dropdown", "container", "preventDefault", "t3", "getValue", "pageOffset", "inputOffset", "inputSize", "Slider", "getLabel", "n", "s", "q", "w", "saturation", "brightness", "o", "label", "ColorPicker", "_a", "controls", "selectedIndex", "children", "textContent", "flush", "pointer", "c", "pointers", "diff", "space", "duration", "parentRect", "panelSize", "align", "justify", "isTextarea", "focus", "isAndroid", "proxy", "get", "cancel", "subscribe", "history", "file", "unshift", "push", "remove", "isPanning", "elastify", "utils", "locale", "trim", "confirm", "pluginComponents", "blob", "isElement", "imageFrame", "$utilRect", "$tabRect", "$toolRect", "$imageFrame", "$isInteracting", "$stagePadding", "$stagePadded", "$imageIsStatic", "$imageSize", "$imageRotation", "$stageRect", "$imageCropRect", "$imageStaticBounds", "$previewShouldUpscale", "$stageScalar", "$imageSelectionRect", "$imageSelectionZoom", "$imageSelectionRectScalar", "stageRect", "stageScalar", "$rootLineColor", "$rootBackgroundColor", "$imageOverlayMarkup", "$imageVisualLoadComplete", "$imagePreviewSource", "$rootRect", "$presentationScalar", "$imageFlipX", "$imageFlipY", "$imageSelectionScalar", "$imageSelectionPan", "env", "collection", "$activeImages", "pluginOptions", "utilsAvailable", "id", "util", "property", "$imageTransforms", "missingFeatures", "accept", "imageScrambler", "imageRedactionScalar", "imageBackgroundColor", "plugin", "isError", "errorCallback", "plugin", "history", "e", "index", "options", "isElement", "isNode", "isString", "node", "item", "v", "style", "result", "isBrowser", "options", "options", "_", "isObject", "props", "isString", "style", "v", "options", "defaultOptions", "options", "h", "isString", "isFunction", "hasProp", "e", "_", "input", "isObject", "isArray", "ctx", "width", "$$props", "init", "dispatch", "measurable", "t2", "root", "text", "value", "round", "increment", "r", "step", "clamp", "v", "position", "interactionRange", "result", "d", "i", "x", "y", "list", "Direction", "element", "transform", "t", "b", "l", "height", "w", "fill", "Dropdown", "map", "option", "filter", "label", "q", "a", "scalar", "index", "p", "interaction", "c", "history", "isCropMaxSize", "imageCropRect", "imageSize", "imageRotation", "isCropCentered", "env", "rangeInputElasticity", "locale", "$imageCropRange", "$imageCropRect", "set", "$imageSize", "$imageCropLimitToImage", "$imageCropMinSize", "$imageCropMaxSize", "$imageRotation", "z", "scale", "newCropRect", "$imageOutputSize", "$formattedCropPresetOptions", "name", "props", "flush", "scrollElasticity", "imageColorMatrix", "filterOptionsFlattened", "$tileRects", "$isActive", "$canvasSize", "imageTransforms", "style", "tile", "clone", "uid", "config", "getLabel", "store", "getValue", "N", "S", "points", "i2", "dir", "html", "isSafari", "confirm", "focus", "node", "children", "active", "snapThreshold", "gridSize", "gridRect", "collection", "update", "parentRect", "isText", "my", "interactionTarget", "d2", "j", "targetSnapLines", "beginImageOffset", "endImageOffset", "translation", "point", "f", "shape", "shapes", "activeMarkup", "fn", "start", "opacity", "disableSnapping", "fontSize", "offset", "contextZoom", "contextRotation", "_a", "cache", "utilRect", "first", "shapeProps", "activeControls", "styleKey", "component", "controls", "controlSet", "g", "isVisible", "hooks", "willRenderPresetToolbar", "shapePresets", "enableViewTool", "enableMoveTool", "markupDraft", "cursorStyle", "customCursor", "shapeUnderPointer", "isPanning", "x2", "y2", "shadow", "s", "frame", "frameStyles", "format", "activeField", "resizeMinSize", "resizeMaxSize", "$formattedResizeSizePresetOptionsFlattened", "$formattedResizeWidthPresetOptionsFlattened", "$formattedResizeHeightPresetOptionsFlattened", "IconCross", "CharacterA", "MarkupEditor", "isBrowser", "e", "subscribe", "resolve", "isBrowser", "o", "dispatch", "root", "isBrowser", "h", "element", "index", "e", "frame", "isOpaque", "$$props", "Modal", "options", "init", "flush", "parent", "subscribe", "start", "scalar", "options", "_a", "x", "y", "p", "x2", "y2", "style", "process", "v", "isString", "width", "height", "r", "_", "index", "hasProp", "res", "shape", "onprogress", "MarkupEditor", "options", "isFunction", "options", "utils", "FilePondPluginFileValidateSize", "FilePondPluginFileValidateType", "FilePondPluginFilePoster", "_a", "e", "error", "import_bootstrap_bundle", "import_bootstrap_bundle", "e", "e", "i", "_a", "host", "first", "_a", "host", "first", "e", "option", "e", "import_bootstrap_bundle", "e", "_a", "count", "symbols", "i", "s"]
}
